aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author(no author) <(no author)@138bc75d-0d04-0410-961f-82ee72b054a4>2004-10-06 23:29:25 +0000
committer(no author) <(no author)@138bc75d-0d04-0410-961f-82ee72b054a4>2004-10-06 23:29:25 +0000
commit23eec84c70340b31e0ebe2156dfb3e9184ea640b (patch)
treeb798af2f69ce5dbc62dd01ffaffed86373d0d78d
parentcfb805a092726fd6ecfe8451b684487064b6e73c (diff)
This commit was manufactured by cvs2svn to create taggcj-abi-2-premerge-20041007
'gcj-abi-2-premerge-20041007'. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/tags/gcj-abi-2-premerge-20041007@88649 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--ChangeLog119
-rw-r--r--ChangeLog.tree-ssa110
-rw-r--r--MAINTAINERS12
-rw-r--r--Makefile.def23
-rw-r--r--Makefile.in1079
-rw-r--r--Makefile.tpl69
-rw-r--r--boehm-gc/ChangeLog4
-rw-r--r--boehm-gc/mark.c8
-rw-r--r--config/ChangeLog6
-rw-r--r--config/acx.m438
-rwxr-xr-xconfigure375
-rw-r--r--configure.in136
-rw-r--r--contrib/ChangeLog11
-rw-r--r--contrib/ChangeLog.tree-ssa46
-rwxr-xr-xcontrib/filter_gcc_for_doxygen12
-rwxr-xr-xcontrib/filter_knr2ansi.pl45
-rwxr-xr-xcontrib/filter_params.pl14
-rwxr-xr-xcontrib/gcc_update2
-rw-r--r--contrib/regression/ChangeLog4
-rwxr-xr-xcontrib/regression/btest-gcc.sh1
-rw-r--r--contrib/tree-ssa.doxy932
-rwxr-xr-xdepcomp472
-rw-r--r--gcc/ChangeLog3219
-rw-r--r--gcc/ChangeLog.tree-ssa19338
-rw-r--r--gcc/Makefile.in277
-rw-r--r--gcc/ada/5qsystem.ads15
-rw-r--r--gcc/ada/ChangeLog1412
-rw-r--r--gcc/ada/ChangeLog.tree-ssa29
-rw-r--r--gcc/ada/Make-lang.in448
-rw-r--r--gcc/ada/Makefile.in1499
-rw-r--r--gcc/ada/Makefile.rtl1
-rw-r--r--gcc/ada/a-caldel-vms.adb99
-rw-r--r--gcc/ada/a-calend-mingw.adb394
-rw-r--r--gcc/ada/a-calend-vms.adb361
-rw-r--r--gcc/ada/a-calend-vms.ads121
-rw-r--r--gcc/ada/a-calend.adb69
-rw-r--r--gcc/ada/a-dirval-mingw.adb146
-rw-r--r--gcc/ada/a-dirval-vms.adb175
-rw-r--r--gcc/ada/a-except.adb21
-rw-r--r--gcc/ada/a-excpol-abort.adb58
-rw-r--r--gcc/ada/a-excpol-interix.adb66
-rw-r--r--gcc/ada/a-exexpr.adb15
-rw-r--r--gcc/ada/a-intnam-aix.ads201
-rw-r--r--gcc/ada/a-intnam-darwin.ads153
-rw-r--r--gcc/ada/a-intnam-dummy.ads48
-rw-r--r--gcc/ada/a-intnam-freebsd.ads136
-rw-r--r--gcc/ada/a-intnam-hpux.ads155
-rw-r--r--gcc/ada/a-intnam-interix.ads154
-rw-r--r--gcc/ada/a-intnam-irix.ads196
-rw-r--r--gcc/ada/a-intnam-linux.ads168
-rw-r--r--gcc/ada/a-intnam-lynxos.ads165
-rw-r--r--gcc/ada/a-intnam-mingw.ads67
-rw-r--r--gcc/ada/a-intnam-os2.ads43
-rw-r--r--gcc/ada/a-intnam-solaris.ads179
-rw-r--r--gcc/ada/a-intnam-tru64.ads151
-rw-r--r--gcc/ada/a-intnam-unixware.ads164
-rw-r--r--gcc/ada/a-intnam-vms.ads77
-rw-r--r--gcc/ada/a-intnam-vxworks.ads44
-rw-r--r--gcc/ada/a-numaux-libc-x86.ads108
-rw-r--r--gcc/ada/a-numaux-vxworks.ads110
-rw-r--r--gcc/ada/a-numaux-x86.adb592
-rw-r--r--gcc/ada/a-numaux-x86.ads84
-rw-r--r--gcc/ada/a-sytaco-vxworks.adb147
-rw-r--r--gcc/ada/a-sytaco-vxworks.ads68
-rw-r--r--gcc/ada/a-tags.adb32
-rw-r--r--gcc/ada/a-tags.ads4
-rw-r--r--gcc/ada/a-textio.adb6
-rw-r--r--gcc/ada/a-wtmoio.ads4
-rw-r--r--gcc/ada/ada-tree.def7
-rw-r--r--gcc/ada/ada-tree.h8
-rw-r--r--gcc/ada/adaint.c75
-rw-r--r--gcc/ada/adaint.h10
-rw-r--r--gcc/ada/ali.ads2
-rw-r--r--gcc/ada/atree.adb288
-rw-r--r--gcc/ada/checks.adb491
-rw-r--r--gcc/ada/clean.adb399
-rw-r--r--gcc/ada/config-lang.in5
-rw-r--r--gcc/ada/cstand.adb5
-rw-r--r--gcc/ada/decl.c47
-rw-r--r--gcc/ada/einfo.adb21
-rw-r--r--gcc/ada/einfo.ads49
-rw-r--r--gcc/ada/erroutc.adb8
-rw-r--r--gcc/ada/erroutc.ads10
-rw-r--r--gcc/ada/eval_fat.adb17
-rw-r--r--gcc/ada/eval_fat.ads4
-rw-r--r--gcc/ada/exp_aggr.adb14
-rw-r--r--gcc/ada/exp_attr.adb34
-rw-r--r--gcc/ada/exp_ch13.adb3
-rw-r--r--gcc/ada/exp_ch2.adb9
-rw-r--r--gcc/ada/exp_ch4.adb35
-rw-r--r--gcc/ada/exp_ch5.adb10
-rw-r--r--gcc/ada/exp_ch6.adb147
-rw-r--r--gcc/ada/exp_ch7.adb21
-rw-r--r--gcc/ada/exp_ch9.adb19
-rw-r--r--gcc/ada/exp_dbug.adb69
-rw-r--r--gcc/ada/exp_disp.adb26
-rw-r--r--gcc/ada/exp_dist.adb189
-rw-r--r--gcc/ada/exp_dist.ads7
-rw-r--r--gcc/ada/exp_fixd.adb14
-rw-r--r--gcc/ada/exp_intr.adb4
-rw-r--r--gcc/ada/exp_util.adb9
-rw-r--r--gcc/ada/exp_util.ads19
-rw-r--r--gcc/ada/frontend.adb7
-rw-r--r--gcc/ada/g-debpoo.adb127
-rw-r--r--gcc/ada/g-eacodu-vms.adb73
-rw-r--r--gcc/ada/g-expect-vms.adb1184
-rw-r--r--gcc/ada/g-os_lib.adb11
-rw-r--r--gcc/ada/g-os_lib.ads15
-rw-r--r--gcc/ada/g-regpat.adb22
-rw-r--r--gcc/ada/g-regpat.ads208
-rw-r--r--gcc/ada/g-soccon-aix.ads158
-rw-r--r--gcc/ada/g-soccon-freebsd.ads158
-rw-r--r--gcc/ada/g-soccon-hpux.ads158
-rw-r--r--gcc/ada/g-soccon-interix.ads158
-rw-r--r--gcc/ada/g-soccon-irix.ads158
-rw-r--r--gcc/ada/g-soccon-mingw.ads158
-rw-r--r--gcc/ada/g-soccon-solaris.ads158
-rw-r--r--gcc/ada/g-soccon-tru64.ads158
-rw-r--r--gcc/ada/g-soccon-unixware.ads158
-rw-r--r--gcc/ada/g-soccon-vms.adb158
-rw-r--r--gcc/ada/g-soccon-vxworks.ads158
-rw-r--r--gcc/ada/g-socthi-mingw.adb587
-rw-r--r--gcc/ada/g-socthi-mingw.ads433
-rw-r--r--gcc/ada/g-socthi-vms.adb551
-rw-r--r--gcc/ada/g-socthi-vms.ads445
-rw-r--r--gcc/ada/g-socthi-vxworks.adb624
-rw-r--r--gcc/ada/g-socthi-vxworks.ads446
-rw-r--r--gcc/ada/g-soliop-mingw.ads43
-rw-r--r--gcc/ada/g-soliop-solaris.ads43
-rw-r--r--gcc/ada/g-soliop-unixware.ads43
-rw-r--r--gcc/ada/g-trasym-vms.adb282
-rw-r--r--gcc/ada/get_targ.ads5
-rw-r--r--gcc/ada/gigi.h9
-rw-r--r--gcc/ada/gnat-style.texi10
-rw-r--r--gcc/ada/gnat_rm.texi134
-rw-r--r--gcc/ada/gnat_ugn.texi513
-rw-r--r--gcc/ada/gnatbind.adb5
-rw-r--r--gcc/ada/gnatcmd.adb9
-rw-r--r--gcc/ada/gnatlink.adb51
-rw-r--r--gcc/ada/gnatls.adb68
-rw-r--r--gcc/ada/gprmake.adb36
-rw-r--r--gcc/ada/i-c.ads18
-rw-r--r--gcc/ada/i-cpp-vms.adb346
-rw-r--r--gcc/ada/i-cstrea-vms.adb255
-rw-r--r--gcc/ada/impunit.adb2
-rw-r--r--gcc/ada/init.c90
-rw-r--r--gcc/ada/interfac-vms.ads194
-rw-r--r--gcc/ada/lang-specs.h9
-rw-r--r--gcc/ada/layout.adb6
-rw-r--r--gcc/ada/lib-load.adb39
-rw-r--r--gcc/ada/lib-writ.adb22
-rw-r--r--gcc/ada/lib-xref.adb25
-rw-r--r--gcc/ada/lib-xref.ads4
-rw-r--r--gcc/ada/lib.adb15
-rw-r--r--gcc/ada/lib.ads20
-rw-r--r--gcc/ada/link.c175
-rw-r--r--gcc/ada/make.adb1079
-rw-r--r--gcc/ada/make.ads7
-rw-r--r--gcc/ada/makegpr.adb3574
-rw-r--r--gcc/ada/makegpr.ads35
-rw-r--r--gcc/ada/makeusg.adb19
-rw-r--r--gcc/ada/makeutl.adb509
-rw-r--r--gcc/ada/makeutl.ads117
-rw-r--r--gcc/ada/mdll-utl.adb61
-rw-r--r--gcc/ada/misc.c38
-rw-r--r--gcc/ada/mlib-prj.adb29
-rw-r--r--gcc/ada/mlib-tgt-aix.adb391
-rw-r--r--gcc/ada/mlib-tgt-hpux.adb368
-rw-r--r--gcc/ada/mlib-tgt-irix.adb363
-rw-r--r--gcc/ada/mlib-tgt-linux.adb365
-rw-r--r--gcc/ada/mlib-tgt-mingw.adb347
-rw-r--r--gcc/ada/mlib-tgt-solaris.adb362
-rw-r--r--gcc/ada/mlib-tgt-tru64.adb380
-rw-r--r--gcc/ada/mlib-tgt-vms.adb703
-rw-r--r--gcc/ada/mlib-tgt-vxworks.adb317
-rw-r--r--gcc/ada/mlib-tgt.adb9
-rw-r--r--gcc/ada/mlib-tgt.ads5
-rw-r--r--gcc/ada/mlib-utl.adb8
-rw-r--r--gcc/ada/mlib.adb30
-rw-r--r--gcc/ada/mlib.ads7
-rw-r--r--gcc/ada/opt.ads23
-rw-r--r--gcc/ada/osint.adb21
-rw-r--r--gcc/ada/osint.ads18
-rw-r--r--gcc/ada/par-ch10.adb4
-rw-r--r--gcc/ada/par-ch3.adb287
-rw-r--r--gcc/ada/par-ch6.adb4
-rw-r--r--gcc/ada/par-prag.adb2
-rw-r--r--gcc/ada/par.adb14
-rw-r--r--gcc/ada/prj-attr.adb58
-rw-r--r--gcc/ada/prj-attr.ads15
-rw-r--r--gcc/ada/prj-com.ads1
-rw-r--r--gcc/ada/prj-dect.adb51
-rw-r--r--gcc/ada/prj-env.adb28
-rw-r--r--gcc/ada/prj-env.ads8
-rw-r--r--gcc/ada/prj-makr.adb211
-rw-r--r--gcc/ada/prj-nmsc.adb2653
-rw-r--r--gcc/ada/prj-nmsc.ads37
-rw-r--r--gcc/ada/prj-pars.adb12
-rw-r--r--gcc/ada/prj-pars.ads5
-rw-r--r--gcc/ada/prj-pp.adb13
-rw-r--r--gcc/ada/prj-proc.adb69
-rw-r--r--gcc/ada/prj-proc.ads6
-rw-r--r--gcc/ada/prj-strt.adb54
-rw-r--r--gcc/ada/prj-strt.ads5
-rw-r--r--gcc/ada/prj-tree.adb49
-rw-r--r--gcc/ada/prj-tree.ads13
-rw-r--r--gcc/ada/prj-util.adb55
-rw-r--r--gcc/ada/prj-util.ads35
-rw-r--r--gcc/ada/prj.adb37
-rw-r--r--gcc/ada/prj.ads124
-rw-r--r--gcc/ada/raise.c4
-rw-r--r--gcc/ada/restrict.adb6
-rw-r--r--gcc/ada/restrict.ads4
-rw-r--r--gcc/ada/rtsfind.adb106
-rw-r--r--gcc/ada/rtsfind.ads269
-rw-r--r--gcc/ada/s-addope.adb114
-rw-r--r--gcc/ada/s-addope.ads84
-rw-r--r--gcc/ada/s-asthan-vms.adb597
-rw-r--r--gcc/ada/s-auxdec.adb7
-rw-r--r--gcc/ada/s-auxdec.ads12
-rw-r--r--gcc/ada/s-carsi8.adb20
-rw-r--r--gcc/ada/s-carsi8.ads8
-rw-r--r--gcc/ada/s-carun8.adb20
-rw-r--r--gcc/ada/s-carun8.ads8
-rw-r--r--gcc/ada/s-casi16.adb23
-rw-r--r--gcc/ada/s-casi16.ads5
-rw-r--r--gcc/ada/s-casi32.adb17
-rw-r--r--gcc/ada/s-casi32.ads2
-rw-r--r--gcc/ada/s-casi64.adb21
-rw-r--r--gcc/ada/s-casi64.ads5
-rw-r--r--gcc/ada/s-caun16.adb23
-rw-r--r--gcc/ada/s-caun16.ads5
-rw-r--r--gcc/ada/s-caun32.adb17
-rw-r--r--gcc/ada/s-caun32.ads5
-rw-r--r--gcc/ada/s-caun64.adb21
-rw-r--r--gcc/ada/s-caun64.ads5
-rw-r--r--gcc/ada/s-finimp.adb5
-rw-r--r--gcc/ada/s-geveop.adb60
-rw-r--r--gcc/ada/s-gloloc-mingw.adb113
-rw-r--r--gcc/ada/s-inmaop-dummy.adb194
-rw-r--r--gcc/ada/s-inmaop-posix.adb359
-rw-r--r--gcc/ada/s-inmaop-vms.adb298
-rw-r--r--gcc/ada/s-inmaop.ads36
-rw-r--r--gcc/ada/s-interr-dummy.adb307
-rw-r--r--gcc/ada/s-interr-sigaction.adb682
-rw-r--r--gcc/ada/s-interr-vms.adb1176
-rw-r--r--gcc/ada/s-interr-vxworks.adb1146
-rw-r--r--gcc/ada/s-intman-dummy.adb49
-rw-r--r--gcc/ada/s-intman-irix-athread.adb184
-rw-r--r--gcc/ada/s-intman-irix.adb152
-rw-r--r--gcc/ada/s-intman-mingw.adb78
-rw-r--r--gcc/ada/s-intman-posix.adb285
-rw-r--r--gcc/ada/s-intman-solaris.adb263
-rw-r--r--gcc/ada/s-intman-vms.adb88
-rw-r--r--gcc/ada/s-intman-vms.ads142
-rw-r--r--gcc/ada/s-intman-vxworks.adb194
-rw-r--r--gcc/ada/s-intman-vxworks.ads123
-rw-r--r--gcc/ada/s-mastop-irix.adb444
-rw-r--r--gcc/ada/s-mastop-tru64.adb181
-rw-r--r--gcc/ada/s-mastop-vms.adb339
-rw-r--r--gcc/ada/s-mastop-x86.adb594
-rw-r--r--gcc/ada/s-memory-mingw.adb223
-rw-r--r--gcc/ada/s-osinte-aix-fsu.ads589
-rw-r--r--gcc/ada/s-osinte-aix.adb159
-rw-r--r--gcc/ada/s-osinte-aix.ads586
-rw-r--r--gcc/ada/s-osinte-darwin.adb163
-rw-r--r--gcc/ada/s-osinte-darwin.ads641
-rw-r--r--gcc/ada/s-osinte-dummy.ads53
-rw-r--r--gcc/ada/s-osinte-freebsd.adb108
-rw-r--r--gcc/ada/s-osinte-freebsd.ads644
-rw-r--r--gcc/ada/s-osinte-fsu.adb366
-rw-r--r--gcc/ada/s-osinte-hpux-dce.adb564
-rw-r--r--gcc/ada/s-osinte-hpux-dce.ads495
-rw-r--r--gcc/ada/s-osinte-hpux.ads556
-rw-r--r--gcc/ada/s-osinte-interix.ads574
-rw-r--r--gcc/ada/s-osinte-irix-athread.ads699
-rw-r--r--gcc/ada/s-osinte-irix.adb120
-rw-r--r--gcc/ada/s-osinte-irix.ads527
-rw-r--r--gcc/ada/s-osinte-linux-fsu.ads599
-rw-r--r--gcc/ada/s-osinte-linux-ia64.ads150
-rw-r--r--gcc/ada/s-osinte-linux.ads524
-rw-r--r--gcc/ada/s-osinte-lynxos-3.adb597
-rw-r--r--gcc/ada/s-osinte-lynxos-3.ads564
-rw-r--r--gcc/ada/s-osinte-lynxos.adb154
-rw-r--r--gcc/ada/s-osinte-lynxos.ads592
-rw-r--r--gcc/ada/s-osinte-mingw.ads451
-rw-r--r--gcc/ada/s-osinte-os2.adb120
-rw-r--r--gcc/ada/s-osinte-os2.ads125
-rw-r--r--gcc/ada/s-osinte-posix.adb132
-rw-r--r--gcc/ada/s-osinte-solaris-fsu.ads667
-rw-r--r--gcc/ada/s-osinte-solaris-posix.ads539
-rw-r--r--gcc/ada/s-osinte-solaris.adb100
-rw-r--r--gcc/ada/s-osinte-solaris.ads569
-rw-r--r--gcc/ada/s-osinte-tru64.adb135
-rw-r--r--gcc/ada/s-osinte-tru64.ads539
-rw-r--r--gcc/ada/s-osinte-unixware.adb182
-rw-r--r--gcc/ada/s-osinte-unixware.ads600
-rw-r--r--gcc/ada/s-osinte-vms.adb78
-rw-r--r--gcc/ada/s-osinte-vms.ads646
-rw-r--r--gcc/ada/s-osinte-vxworks.adb164
-rw-r--r--gcc/ada/s-osinte-vxworks.ads371
-rw-r--r--gcc/ada/s-osprim-mingw.adb286
-rw-r--r--gcc/ada/s-osprim-os2.adb172
-rw-r--r--gcc/ada/s-osprim-posix.adb159
-rw-r--r--gcc/ada/s-osprim-solaris.adb124
-rw-r--r--gcc/ada/s-osprim-unix.adb124
-rw-r--r--gcc/ada/s-osprim-vms.adb193
-rw-r--r--gcc/ada/s-osprim-vms.ads106
-rw-r--r--gcc/ada/s-osprim-vxworks.adb161
-rw-r--r--gcc/ada/s-parame-ae653.ads203
-rw-r--r--gcc/ada/s-parame-hpux.ads202
-rw-r--r--gcc/ada/s-parame-linux.adb73
-rw-r--r--gcc/ada/s-parame-os2.adb83
-rw-r--r--gcc/ada/s-parame-solaris.adb80
-rw-r--r--gcc/ada/s-parame-vms-restrict.ads203
-rw-r--r--gcc/ada/s-parame-vms.ads202
-rw-r--r--gcc/ada/s-parame-vxworks.ads203
-rw-r--r--gcc/ada/s-parint.adb27
-rw-r--r--gcc/ada/s-parint.ads22
-rw-r--r--gcc/ada/s-proinf-irix-athread.adb221
-rw-r--r--gcc/ada/s-proinf-irix-athread.ads96
-rw-r--r--gcc/ada/s-rident.ads23
-rw-r--r--gcc/ada/s-rpc.adb9
-rw-r--r--gcc/ada/s-stalib.ads2
-rw-r--r--gcc/ada/s-stchop-vxworks.adb255
-rw-r--r--gcc/ada/s-stoele.adb16
-rw-r--r--gcc/ada/s-stoele.ads8
-rw-r--r--gcc/ada/s-taprop-dummy.adb438
-rw-r--r--gcc/ada/s-taprop-hpux-dce.adb1061
-rw-r--r--gcc/ada/s-taprop-irix-athread.adb955
-rw-r--r--gcc/ada/s-taprop-irix.adb1139
-rw-r--r--gcc/ada/s-taprop-linux.adb1094
-rw-r--r--gcc/ada/s-taprop-lynxos.adb1184
-rw-r--r--gcc/ada/s-taprop-mingw.adb1106
-rw-r--r--gcc/ada/s-taprop-os2.adb1157
-rw-r--r--gcc/ada/s-taprop-posix.adb1212
-rw-r--r--gcc/ada/s-taprop-solaris.adb1815
-rw-r--r--gcc/ada/s-taprop-tru64.adb1136
-rw-r--r--gcc/ada/s-taprop-vms.adb1005
-rw-r--r--gcc/ada/s-taprop-vxworks.adb1144
-rw-r--r--gcc/ada/s-tasinf-irix-athread.adb312
-rw-r--r--gcc/ada/s-tasinf-irix-athread.ads274
-rw-r--r--gcc/ada/s-tasinf-irix.ads136
-rw-r--r--gcc/ada/s-tasinf-solaris.adb73
-rw-r--r--gcc/ada/s-tasinf-solaris.ads142
-rw-r--r--gcc/ada/s-tasinf-tru64.ads111
-rw-r--r--gcc/ada/s-taspri-dummy.ads55
-rw-r--r--gcc/ada/s-taspri-hpux-dce.ads89
-rw-r--r--gcc/ada/s-taspri-linux.ads96
-rw-r--r--gcc/ada/s-taspri-lynxos.ads97
-rw-r--r--gcc/ada/s-taspri-mingw.ads97
-rw-r--r--gcc/ada/s-taspri-os2.ads107
-rw-r--r--gcc/ada/s-taspri-posix.ads92
-rw-r--r--gcc/ada/s-taspri-solaris.ads130
-rw-r--r--gcc/ada/s-taspri-tru64.ads93
-rw-r--r--gcc/ada/s-taspri-vms.ads105
-rw-r--r--gcc/ada/s-taspri-vxworks.ads95
-rw-r--r--gcc/ada/s-tfsetr-default.adb313
-rw-r--r--gcc/ada/s-tfsetr-vxworks.adb107
-rw-r--r--gcc/ada/s-tpopde-vms.adb163
-rw-r--r--gcc/ada/s-tpopde-vms.ads54
-rw-r--r--gcc/ada/s-tpopsp-lynxos.adb113
-rw-r--r--gcc/ada/s-tpopsp-posix-foreign.adb108
-rw-r--r--gcc/ada/s-tpopsp-posix.adb80
-rw-r--r--gcc/ada/s-tpopsp-solaris.adb107
-rw-r--r--gcc/ada/s-tpopsp-vxworks.adb74
-rw-r--r--gcc/ada/s-traceb-hpux.adb600
-rw-r--r--gcc/ada/s-traceb-mastop.adb113
-rw-r--r--gcc/ada/s-traces-default.adb73
-rw-r--r--gcc/ada/s-traent-vms.adb68
-rw-r--r--gcc/ada/s-traent-vms.ads59
-rw-r--r--gcc/ada/s-trafor-default.adb113
-rw-r--r--gcc/ada/s-trafor-default.ads62
-rw-r--r--gcc/ada/s-tratas-default.adb367
-rw-r--r--gcc/ada/s-vaflop-vms.adb621
-rw-r--r--gcc/ada/s-vxwork-alpha.ads57
-rw-r--r--gcc/ada/s-vxwork-m68k.ads76
-rw-r--r--gcc/ada/s-vxwork-mips.ads57
-rw-r--r--gcc/ada/s-vxwork-ppc.ads57
-rw-r--r--gcc/ada/s-vxwork-sparcv9.ads62
-rw-r--r--gcc/ada/s-vxwork-xscale.ads54
-rw-r--r--gcc/ada/scn.adb26
-rw-r--r--gcc/ada/scng.adb12
-rw-r--r--gcc/ada/sem_aggr.adb12
-rw-r--r--gcc/ada/sem_attr.adb102
-rw-r--r--gcc/ada/sem_ch10.adb104
-rw-r--r--gcc/ada/sem_ch12.adb67
-rw-r--r--gcc/ada/sem_ch13.adb33
-rw-r--r--gcc/ada/sem_ch3.adb266
-rw-r--r--gcc/ada/sem_ch3.ads12
-rw-r--r--gcc/ada/sem_ch4.adb154
-rw-r--r--gcc/ada/sem_ch6.adb227
-rw-r--r--gcc/ada/sem_ch8.adb134
-rw-r--r--gcc/ada/sem_disp.adb39
-rw-r--r--gcc/ada/sem_dist.adb70
-rw-r--r--gcc/ada/sem_dist.ads6
-rw-r--r--gcc/ada/sem_elim.adb375
-rw-r--r--gcc/ada/sem_elim.ads4
-rw-r--r--gcc/ada/sem_eval.adb1
-rw-r--r--gcc/ada/sem_prag.adb184
-rw-r--r--gcc/ada/sem_prag.ads13
-rw-r--r--gcc/ada/sem_res.adb13
-rw-r--r--gcc/ada/sem_type.adb21
-rw-r--r--gcc/ada/sem_util.adb161
-rw-r--r--gcc/ada/sem_util.ads52
-rw-r--r--gcc/ada/sem_warn.adb3
-rw-r--r--gcc/ada/sinfo.adb16
-rw-r--r--gcc/ada/sinfo.ads14
-rw-r--r--gcc/ada/snames.adb19
-rw-r--r--gcc/ada/snames.ads1193
-rw-r--r--gcc/ada/sprint.adb41
-rw-r--r--gcc/ada/stand.ads5
-rw-r--r--gcc/ada/switch-c.adb2
-rw-r--r--gcc/ada/switch-m.adb33
-rw-r--r--gcc/ada/symbols-vms.adb743
-rw-r--r--gcc/ada/system-aix.ads150
-rw-r--r--gcc/ada/system-darwin-ppc.ads176
-rw-r--r--gcc/ada/system-freebsd-x86.ads150
-rw-r--r--gcc/ada/system-hpux.ads226
-rw-r--r--gcc/ada/system-interix.ads150
-rw-r--r--gcc/ada/system-irix-n32.ads153
-rw-r--r--gcc/ada/system-irix-o32.ads153
-rw-r--r--gcc/ada/system-linux-s390.ads150
-rw-r--r--gcc/ada/system-linux-s390x.ads150
-rw-r--r--gcc/ada/system-linux-x86.ads150
-rw-r--r--gcc/ada/system-linux-x86_64.ads150
-rw-r--r--gcc/ada/system-lynxos-ppc.ads150
-rw-r--r--gcc/ada/system-lynxos-x86.ads150
-rw-r--r--gcc/ada/system-mingw.ads208
-rw-r--r--gcc/ada/system-os2.ads150
-rw-r--r--gcc/ada/system-solaris-sparc.ads150
-rw-r--r--gcc/ada/system-solaris-sparcv9.ads150
-rw-r--r--gcc/ada/system-solaris-x86.ads150
-rw-r--r--gcc/ada/system-tru64.ads221
-rw-r--r--gcc/ada/system-unixware.ads150
-rw-r--r--gcc/ada/system-vms-zcx.ads236
-rw-r--r--gcc/ada/system-vms.ads236
-rw-r--r--gcc/ada/system-vxworks-alpha.ads158
-rw-r--r--gcc/ada/system-vxworks-m68k.ads158
-rw-r--r--gcc/ada/system-vxworks-mips.ads158
-rw-r--r--gcc/ada/system-vxworks-ppc.ads158
-rw-r--r--gcc/ada/system-vxworks-sparcv9.ads160
-rw-r--r--gcc/ada/system-vxworks-xscale.ads158
-rw-r--r--gcc/ada/targtyps.c12
-rw-r--r--gcc/ada/trans.c194
-rw-r--r--gcc/ada/types.ads5
-rw-r--r--gcc/ada/types.h17
-rw-r--r--gcc/ada/usage.adb6
-rw-r--r--gcc/ada/utils.c87
-rw-r--r--gcc/ada/utils2.c9
-rw-r--r--gcc/ada/vms_data.ads30
-rw-r--r--gcc/attribs.c21
-rw-r--r--gcc/basic-block.h124
-rw-r--r--gcc/bb-reorder.c26
-rw-r--r--gcc/bitmap.c8
-rw-r--r--gcc/builtin-attrs.def2
-rw-r--r--gcc/builtin-types.def10
-rw-r--r--gcc/builtins.c1931
-rw-r--r--gcc/builtins.def24
-rw-r--r--gcc/c-common.c637
-rw-r--r--gcc/c-common.def6
-rw-r--r--gcc/c-common.h101
-rw-r--r--gcc/c-convert.c3
-rw-r--r--gcc/c-decl.c272
-rw-r--r--gcc/c-dump.c4
-rw-r--r--gcc/c-format.c2
-rw-r--r--gcc/c-gimplify.c1102
-rw-r--r--gcc/c-incpath.c8
-rw-r--r--gcc/c-lang.c30
-rw-r--r--gcc/c-mudflap.c100
-rw-r--r--gcc/c-objc-common.c67
-rw-r--r--gcc/c-opts.c35
-rw-r--r--gcc/c-parse.in16
-rw-r--r--gcc/c-pragma.c8
-rw-r--r--gcc/c-pretty-print.c149
-rw-r--r--gcc/c-pretty-print.h5
-rw-r--r--gcc/c-semantics.c824
-rw-r--r--gcc/c-tree.h17
-rw-r--r--gcc/c-typeck.c121
-rw-r--r--gcc/c.opt10
-rw-r--r--gcc/calls.c509
-rw-r--r--gcc/cfg.c270
-rw-r--r--gcc/cfganal.c179
-rw-r--r--gcc/cfgbuild.c8
-rw-r--r--gcc/cfgcleanup.c30
-rw-r--r--gcc/cfghooks.c183
-rw-r--r--gcc/cfghooks.h49
-rw-r--r--gcc/cfglayout.c124
-rw-r--r--gcc/cfglayout.h18
-rw-r--r--gcc/cfgloop.c2
-rw-r--r--gcc/cfgloop.h1
-rw-r--r--gcc/cfgloopanal.c8
-rw-r--r--gcc/cfgloopmanip.c114
-rw-r--r--gcc/cfgrtl.c308
-rw-r--r--gcc/cgraph.c34
-rw-r--r--gcc/cgraph.h3
-rw-r--r--gcc/cgraphunit.c255
-rw-r--r--gcc/combine.c471
-rw-r--r--gcc/common.opt75
-rw-r--r--gcc/config.gcc59
-rw-r--r--gcc/config.in13
-rw-r--r--gcc/config/alpha/alpha.c13
-rw-r--r--gcc/config/alpha/alpha.md6
-rw-r--r--gcc/config/alpha/ev4.md2
-rw-r--r--gcc/config/alpha/ev5.md6
-rw-r--r--gcc/config/alpha/ev6.md2
-rw-r--r--gcc/config/alpha/freebsd.h1
-rw-r--r--gcc/config/alpha/linux.h8
-rw-r--r--gcc/config/alpha/osf.h8
-rw-r--r--gcc/config/alpha/xm-vms.h14
-rw-r--r--gcc/config/arm/arm-cores.def111
-rw-r--r--gcc/config/arm/arm-protos.h2
-rw-r--r--gcc/config/arm/arm.c491
-rw-r--r--gcc/config/arm/arm.h255
-rw-r--r--gcc/config/arm/arm.md22
-rw-r--r--gcc/config/arm/crti.asm4
-rw-r--r--gcc/config/arm/crtn.asm6
-rw-r--r--gcc/config/arm/freebsd.h1
-rw-r--r--gcc/config/arm/iwmmxt.md4
-rw-r--r--gcc/config/arm/lib1funcs.asm21
-rw-r--r--gcc/config/arm/linux-elf.h5
-rw-r--r--gcc/config/arm/t-xscale-coff12
-rw-r--r--gcc/config/arm/t-xscale-elf24
-rw-r--r--gcc/config/arm/vfp.md45
-rw-r--r--gcc/config/avr/avr.h3
-rw-r--r--gcc/config/c4x/c4x.c5
-rw-r--r--gcc/config/c4x/c4x.md4
-rw-r--r--gcc/config/cris/cris.c5
-rw-r--r--gcc/config/darwin-c.c27
-rw-r--r--gcc/config/darwin-crt2.c9
-rw-r--r--gcc/config/darwin.h15
-rw-r--r--gcc/config/darwin7.h28
-rw-r--r--gcc/config/fr30/fr30.h2
-rw-r--r--gcc/config/frv/frv-protos.h4
-rw-r--r--gcc/config/frv/frv.c63
-rw-r--r--gcc/config/frv/frv.h17
-rw-r--r--gcc/config/frv/frv.md171
-rw-r--r--gcc/config/h8300/h8300.c4
-rw-r--r--gcc/config/host-linux.c4
-rw-r--r--gcc/config/i386/cygming.h21
-rw-r--r--gcc/config/i386/gthr-win32.c28
-rw-r--r--gcc/config/i386/i386-protos.h3
-rw-r--r--gcc/config/i386/i386.c67
-rw-r--r--gcc/config/i386/i386.md972
-rw-r--r--gcc/config/i386/scodbx.h84
-rw-r--r--gcc/config/i386/winnt.c5
-rw-r--r--gcc/config/i386/xm-dgux.h4
-rw-r--r--gcc/config/i386/xm-sun.h21
-rw-r--r--gcc/config/i386/xm-sysv3.h3
-rw-r--r--gcc/config/ia64/crtbegin.asm1
-rw-r--r--gcc/config/ia64/crtend.asm6
-rw-r--r--gcc/config/ia64/freebsd.h1
-rw-r--r--gcc/config/ia64/hpux.h1
-rw-r--r--gcc/config/ia64/ia64.c16
-rw-r--r--gcc/config/ia64/ia64.h25
-rw-r--r--gcc/config/ia64/ia64.md32
-rw-r--r--gcc/config/ia64/ia64intrin.h64
-rw-r--r--gcc/config/ia64/itanium2.md4
-rw-r--r--gcc/config/ia64/t-ia642
-rw-r--r--gcc/config/ip2k/ip2k.c4
-rw-r--r--gcc/config/ip2k/ip2k.h3
-rw-r--r--gcc/config/linux.h7
-rw-r--r--gcc/config/m32r/little.h4
-rw-r--r--gcc/config/m32r/m32r.c2
-rw-r--r--gcc/config/m32r/m32r.h21
-rw-r--r--gcc/config/mips/4130.md136
-rw-r--r--gcc/config/mips/5500.md60
-rw-r--r--gcc/config/mips/7000.md4
-rw-r--r--gcc/config/mips/mips-protos.h7
-rw-r--r--gcc/config/mips/mips.c1582
-rw-r--r--gcc/config/mips/mips.h149
-rw-r--r--gcc/config/mips/mips.md1611
-rw-r--r--gcc/config/mips/sb1.md504
-rw-r--r--gcc/config/mips/sr71k.md2
-rw-r--r--gcc/config/mips/t-elf8
-rw-r--r--gcc/config/mips/t-vr10
-rw-r--r--gcc/config/mips/vr.h6
-rw-r--r--gcc/config/mips/vr4120-div.S75
-rw-r--r--gcc/config/mips/vxworks.h1
-rw-r--r--gcc/config/mips/windiss.h1
-rw-r--r--gcc/config/mmix/mmix.c1
-rw-r--r--gcc/config/pa/pa-hpux10.h4
-rw-r--r--gcc/config/pa/pa-hpux11.h4
-rw-r--r--gcc/config/pa/pa.c5
-rw-r--r--gcc/config/pa/pa.h4
-rw-r--r--gcc/config/pa/pa.md58
-rw-r--r--gcc/config/pa/pa64-hpux.h13
-rw-r--r--gcc/config/pa/pa64-regs.h10
-rw-r--r--gcc/config/rs6000/aix.h25
-rw-r--r--gcc/config/rs6000/altivec.h64
-rw-r--r--gcc/config/rs6000/altivec.md10
-rw-r--r--gcc/config/rs6000/linux.h5
-rw-r--r--gcc/config/rs6000/linux64.h5
-rw-r--r--gcc/config/rs6000/rs6000-protos.h6
-rw-r--r--gcc/config/rs6000/rs6000.c654
-rw-r--r--gcc/config/rs6000/rs6000.h108
-rw-r--r--gcc/config/rs6000/rs6000.md63
-rw-r--r--gcc/config/rs6000/spe.md71
-rw-r--r--gcc/config/rs6000/sysv4.h9
-rw-r--r--gcc/config/rs6000/t-rs600020
-rw-r--r--gcc/config/s390/s390-protos.h5
-rw-r--r--gcc/config/s390/s390.c418
-rw-r--r--gcc/config/s390/s390.h28
-rw-r--r--gcc/config/s390/s390.md372
-rw-r--r--gcc/config/s390/t-tpf2
-rw-r--r--gcc/config/sh/elf.h2
-rw-r--r--gcc/config/sh/linux.h5
-rw-r--r--gcc/config/sh/sh-protos.h3
-rw-r--r--gcc/config/sh/sh.c100
-rw-r--r--gcc/config/sh/sh.h1
-rw-r--r--gcc/config/sh/sh.md4
-rw-r--r--gcc/config/sparc/freebsd.h1
-rw-r--r--gcc/config/sparc/linux.h5
-rw-r--r--gcc/config/sparc/linux64.h9
-rw-r--r--gcc/config/sparc/sol2-bi.h7
-rw-r--r--gcc/config/sparc/sparc-protos.h1
-rw-r--r--gcc/config/sparc/sparc.c37
-rw-r--r--gcc/config/sparc/sparc.md26
-rw-r--r--gcc/config/t-linux2
-rw-r--r--gcc/config/v850/v850.c1
-rw-r--r--gcc/config/xtensa/xtensa.c11
-rw-r--r--gcc/config/xtensa/xtensa.h3
-rw-r--r--gcc/config/xtensa/xtensa.md6
-rwxr-xr-xgcc/configure335
-rw-r--r--gcc/configure.ac70
-rw-r--r--gcc/convert.c49
-rw-r--r--gcc/coverage.c65
-rw-r--r--gcc/coverage.h4
-rw-r--r--gcc/cp/ChangeLog99
-rw-r--r--gcc/cp/ChangeLog.tree-ssa566
-rw-r--r--gcc/cp/Make-lang.in14
-rw-r--r--gcc/cp/call.c26
-rw-r--r--gcc/cp/class.c130
-rw-r--r--gcc/cp/cp-gimplify.c236
-rw-r--r--gcc/cp/cp-lang.c125
-rw-r--r--gcc/cp/cp-mudflap.c108
-rw-r--r--gcc/cp/cp-tree.def9
-rw-r--r--gcc/cp/cp-tree.h38
-rw-r--r--gcc/cp/cvt.c5
-rw-r--r--gcc/cp/decl.c137
-rw-r--r--gcc/cp/decl2.c51
-rw-r--r--gcc/cp/error.c12
-rw-r--r--gcc/cp/except.c110
-rw-r--r--gcc/cp/expr.c18
-rw-r--r--gcc/cp/friend.c5
-rw-r--r--gcc/cp/init.c178
-rw-r--r--gcc/cp/name-lookup.c2
-rw-r--r--gcc/cp/name-lookup.h1
-rw-r--r--gcc/cp/optimize.c5
-rw-r--r--gcc/cp/parser.c35
-rw-r--r--gcc/cp/pt.c53
-rw-r--r--gcc/cp/rtti.c27
-rw-r--r--gcc/cp/semantics.c220
-rw-r--r--gcc/cp/tree.c131
-rw-r--r--gcc/cp/typeck.c75
-rw-r--r--gcc/cp/typeck2.c39
-rw-r--r--gcc/cpperror.c2
-rw-r--r--gcc/cppexp.c28
-rw-r--r--gcc/cppfiles.c24
-rw-r--r--gcc/cpphash.h13
-rw-r--r--gcc/cppinit.c6
-rw-r--r--gcc/cpplex.c28
-rw-r--r--gcc/cpplib.c14
-rw-r--r--gcc/cpplib.h3
-rw-r--r--gcc/cppmacro.c6
-rw-r--r--gcc/cpppch.c2
-rw-r--r--gcc/cpptrad.c7
-rw-r--r--gcc/cse.c56
-rw-r--r--gcc/cselib.c4
-rw-r--r--gcc/cselib.h1
-rw-r--r--gcc/dbxout.c3
-rw-r--r--gcc/defaults.h18
-rw-r--r--gcc/diagnostic.c6
-rw-r--r--gcc/diagnostic.h12
-rw-r--r--gcc/doc/c-tree.texi42
-rw-r--r--gcc/doc/cfg.texi614
-rw-r--r--gcc/doc/cpp.texi26
-rw-r--r--gcc/doc/cppopts.texi11
-rw-r--r--gcc/doc/extend.texi5
-rw-r--r--gcc/doc/gccint.texi4
-rw-r--r--gcc/doc/gty.texi2
-rw-r--r--gcc/doc/hostconfig.texi9
-rw-r--r--gcc/doc/install.texi121
-rw-r--r--gcc/doc/invoke.texi591
-rw-r--r--gcc/doc/md.texi5
-rw-r--r--gcc/doc/passes.texi1077
-rw-r--r--gcc/doc/rtl.texi3
-rw-r--r--gcc/doc/sourcebuild.texi14
-rw-r--r--gcc/doc/standards.texi5
-rw-r--r--gcc/doc/tm.texi30
-rw-r--r--gcc/doc/tree-ssa.texi1189
-rw-r--r--gcc/dojump.c88
-rw-r--r--gcc/dominance.c28
-rw-r--r--gcc/domwalk.c265
-rw-r--r--gcc/domwalk.h112
-rw-r--r--gcc/dwarf2out.c105
-rw-r--r--gcc/emit-rtl.c19
-rw-r--r--gcc/et-forest.c12
-rw-r--r--gcc/except.c560
-rw-r--r--gcc/except.h30
-rw-r--r--gcc/explow.c34
-rw-r--r--gcc/expmed.c25
-rw-r--r--gcc/expr.c754
-rw-r--r--gcc/expr.h17
-rw-r--r--gcc/f/ChangeLog11
-rw-r--r--gcc/f/ChangeLog.tree-ssa0
-rw-r--r--gcc/f/config-lang.in2
-rw-r--r--gcc/f/g77.texi3
-rw-r--r--gcc/final.c15
-rw-r--r--gcc/fixinc/Makefile.in5
-rw-r--r--gcc/fixinc/fixincl.x60
-rw-r--r--gcc/fixinc/inclhack.def17
-rw-r--r--gcc/fixinc/tests/base/sys/wait.h5
-rw-r--r--gcc/flags.h54
-rw-r--r--gcc/flow.c117
-rw-r--r--gcc/fold-const.c1029
-rw-r--r--gcc/fortran/.cvsignore1
-rw-r--r--gcc/fortran/CONTRIB33
-rw-r--r--gcc/fortran/ChangeLog3142
-rw-r--r--gcc/fortran/Make-lang.in300
-rw-r--r--gcc/fortran/NEWS7
-rw-r--r--gcc/fortran/README18
-rw-r--r--gcc/fortran/TODO56
-rw-r--r--gcc/fortran/arith.c2764
-rw-r--r--gcc/fortran/arith.h90
-rw-r--r--gcc/fortran/array.c1973
-rw-r--r--gcc/fortran/bbt.c201
-rw-r--r--gcc/fortran/check.c1866
-rw-r--r--gcc/fortran/config-lang.in22
-rw-r--r--gcc/fortran/convert.c124
-rw-r--r--gcc/fortran/data.c457
-rw-r--r--gcc/fortran/decl.c2649
-rw-r--r--gcc/fortran/dependency.c679
-rw-r--r--gcc/fortran/dependency.h30
-rw-r--r--gcc/fortran/dump-parse-tree.c1459
-rw-r--r--gcc/fortran/error.c751
-rw-r--r--gcc/fortran/expr.c1955
-rw-r--r--gcc/fortran/f95-lang.c839
-rw-r--r--gcc/fortran/gfortran.h1652
-rw-r--r--gcc/fortran/gfortran.texi800
-rw-r--r--gcc/fortran/gfortranspec.c549
-rw-r--r--gcc/fortran/interface.c1858
-rw-r--r--gcc/fortran/intrinsic.c2561
-rw-r--r--gcc/fortran/intrinsic.h315
-rw-r--r--gcc/fortran/invoke.texi656
-rw-r--r--gcc/fortran/io.c2409
-rw-r--r--gcc/fortran/iresolve.c1388
-rw-r--r--gcc/fortran/lang-specs.h35
-rw-r--r--gcc/fortran/lang.opt152
-rw-r--r--gcc/fortran/match.c3550
-rw-r--r--gcc/fortran/match.h164
-rw-r--r--gcc/fortran/matchexp.c776
-rw-r--r--gcc/fortran/mathbuiltins.def14
-rw-r--r--gcc/fortran/misc.c327
-rw-r--r--gcc/fortran/module.c3459
-rw-r--r--gcc/fortran/options.c321
-rw-r--r--gcc/fortran/parse.c2504
-rw-r--r--gcc/fortran/parse.h65
-rw-r--r--gcc/fortran/primary.c2214
-rw-r--r--gcc/fortran/resolve.c4435
-rw-r--r--gcc/fortran/scanner.c1073
-rw-r--r--gcc/fortran/simplify.c4009
-rw-r--r--gcc/fortran/st.c186
-rw-r--r--gcc/fortran/symbol.c2417
-rw-r--r--gcc/fortran/trans-array.c4158
-rw-r--r--gcc/fortran/trans-array.h117
-rw-r--r--gcc/fortran/trans-common.c756
-rw-r--r--gcc/fortran/trans-const.c375
-rw-r--r--gcc/fortran/trans-const.h59
-rw-r--r--gcc/fortran/trans-decl.c2139
-rw-r--r--gcc/fortran/trans-expr.c1830
-rw-r--r--gcc/fortran/trans-intrinsic.c3012
-rw-r--r--gcc/fortran/trans-io.c1157
-rw-r--r--gcc/fortran/trans-stmt.c3159
-rw-r--r--gcc/fortran/trans-stmt.h65
-rw-r--r--gcc/fortran/trans-types.c1485
-rw-r--r--gcc/fortran/trans-types.h143
-rw-r--r--gcc/fortran/trans.c662
-rw-r--r--gcc/fortran/trans.h534
-rw-r--r--gcc/function.c647
-rw-r--r--gcc/function.h90
-rw-r--r--gcc/gcc.c81
-rw-r--r--gcc/gcc.h4
-rw-r--r--gcc/gcov-io.h12
-rw-r--r--gcc/gcse.c1193
-rw-r--r--gcc/gdbinit.in18
-rw-r--r--gcc/genattrtab.c4
-rw-r--r--gcc/gengtype-lex.l2
-rw-r--r--gcc/gengtype-yacc.y9
-rw-r--r--gcc/gengtype.c3
-rw-r--r--gcc/genopinit.c8
-rw-r--r--gcc/genrecog.c3
-rw-r--r--gcc/ggc-zone.c31
-rw-r--r--gcc/gimple-low.c472
-rw-r--r--gcc/gimplify.c3754
-rw-r--r--gcc/gthr-win32.h40
-rw-r--r--gcc/haifa-sched.c4
-rw-r--r--gcc/ifcvt.c6
-rw-r--r--gcc/input.h3
-rw-r--r--gcc/integrate.c1867
-rw-r--r--gcc/integrate.h15
-rw-r--r--gcc/java/ChangeLog428
-rw-r--r--gcc/java/ChangeLog.tree-ssa360
-rw-r--r--gcc/java/Make-lang.in10
-rw-r--r--gcc/java/builtins.c14
-rw-r--r--gcc/java/check-init.c48
-rw-r--r--gcc/java/class.c347
-rw-r--r--gcc/java/constants.c42
-rw-r--r--gcc/java/decl.c805
-rw-r--r--gcc/java/except.c50
-rw-r--r--gcc/java/expr.c759
-rw-r--r--gcc/java/gcj.texi18
-rw-r--r--gcc/java/gjavah.c12
-rw-r--r--gcc/java/java-except.h6
-rw-r--r--gcc/java/java-gimplify.c320
-rw-r--r--gcc/java/java-tree.def9
-rw-r--r--gcc/java/java-tree.h103
-rw-r--r--gcc/java/jcf-parse.c132
-rw-r--r--gcc/java/jcf-write.c4
-rw-r--r--gcc/java/lang.c164
-rw-r--r--gcc/java/lang.opt3
-rw-r--r--gcc/java/parse.y298
-rw-r--r--gcc/java/resource.c9
-rw-r--r--gcc/java/typeck.c12
-rw-r--r--gcc/java/verify-glue.c434
-rw-r--r--gcc/java/verify-impl.c3336
-rw-r--r--gcc/java/verify.c109
-rw-r--r--gcc/java/verify.h155
-rw-r--r--gcc/jump.c361
-rw-r--r--gcc/langhooks-def.h30
-rw-r--r--gcc/langhooks.c35
-rw-r--r--gcc/langhooks.h35
-rw-r--r--gcc/libada-mk.in34
-rw-r--r--gcc/libgcov.c142
-rw-r--r--gcc/line-map.c30
-rw-r--r--gcc/line-map.h46
-rw-r--r--gcc/loop-doloop.c17
-rw-r--r--gcc/loop-unswitch.c2
-rw-r--r--gcc/objc/objc-act.c19
-rw-r--r--gcc/objc/objc-lang.c16
-rw-r--r--gcc/optabs.c14
-rw-r--r--gcc/optabs.h22
-rw-r--r--gcc/opts.c111
-rw-r--r--gcc/output.h5
-rw-r--r--gcc/params.def32
-rw-r--r--gcc/params.h4
-rw-r--r--gcc/passes.c290
-rw-r--r--gcc/predict.c509
-rw-r--r--gcc/predict.def4
-rw-r--r--gcc/predict.h9
-rw-r--r--gcc/pretty-print.c4
-rw-r--r--gcc/pretty-print.h1
-rw-r--r--gcc/print-rtl.c6
-rw-r--r--gcc/print-tree.c39
-rw-r--r--gcc/profile.c462
-rw-r--r--gcc/ra-debug.c15
-rw-r--r--gcc/ra-rewrite.c2
-rw-r--r--gcc/read-rtl.c24
-rw-r--r--gcc/recog.c6
-rw-r--r--gcc/reg-stack.c191
-rw-r--r--gcc/regs.h4
-rw-r--r--gcc/reload.c5
-rw-r--r--gcc/reload1.c44
-rw-r--r--gcc/reorg.c8
-rw-r--r--gcc/rtl-profile.c424
-rw-r--r--gcc/rtl.def5
-rw-r--r--gcc/rtl.h48
-rw-r--r--gcc/rtlanal.c60
-rw-r--r--gcc/sbitmap.c26
-rw-r--r--gcc/sbitmap.h1
-rw-r--r--gcc/sdbout.c4
-rw-r--r--gcc/simplify-rtx.c231
-rw-r--r--gcc/stmt.c815
-rw-r--r--gcc/stor-layout.c31
-rw-r--r--gcc/system.h3
-rw-r--r--gcc/target-def.h2
-rw-r--r--gcc/target.h3
-rw-r--r--gcc/testsuite/ChangeLog472
-rw-r--r--gcc/testsuite/ChangeLog.tree-ssa1204
-rwxr-xr-xgcc/testsuite/ada/acats/run_all.sh29
-rw-r--r--gcc/testsuite/ada/acats/support/impbit.adb6
-rw-r--r--gcc/testsuite/ada/acats/support/macro.dfs6
-rw-r--r--gcc/testsuite/g++.dg/README1
-rw-r--r--gcc/testsuite/g++.dg/charset/charset.exp2
-rw-r--r--gcc/testsuite/g++.dg/charset/extern3.cc11
-rw-r--r--gcc/testsuite/g++.dg/eh/cleanup3.C20
-rw-r--r--gcc/testsuite/g++.dg/eh/goto1.C34
-rw-r--r--gcc/testsuite/g++.dg/ext/altivec-8.C20
-rw-r--r--gcc/testsuite/g++.dg/ext/altivec-9.C13
-rw-r--r--gcc/testsuite/g++.dg/ext/asm3.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/complit3.C8
-rw-r--r--gcc/testsuite/g++.dg/ext/label3.C39
-rw-r--r--gcc/testsuite/g++.dg/ext/spe1.C9
-rw-r--r--gcc/testsuite/g++.dg/init/pmf1.C17
-rw-r--r--gcc/testsuite/g++.dg/lookup/java1.C2
-rw-r--r--gcc/testsuite/g++.dg/lookup/java2.C2
-rw-r--r--gcc/testsuite/g++.dg/opt/bool1.C25
-rw-r--r--gcc/testsuite/g++.dg/opt/cfg4.C45
-rw-r--r--gcc/testsuite/g++.dg/opt/crash1.C14
-rw-r--r--gcc/testsuite/g++.dg/opt/inline7.C7
-rw-r--r--gcc/testsuite/g++.dg/opt/nothrow1.C24
-rw-r--r--gcc/testsuite/g++.dg/opt/pr15054.C36
-rw-r--r--gcc/testsuite/g++.dg/opt/static4.C15
-rw-r--r--gcc/testsuite/g++.dg/other/pragma-re-2.C25
-rw-r--r--gcc/testsuite/g++.dg/other/vararg-1.C20
-rw-r--r--gcc/testsuite/g++.dg/parse/crash10.C2
-rw-r--r--gcc/testsuite/g++.dg/pch/externc-1.C2
-rw-r--r--gcc/testsuite/g++.dg/template/crash18.C13
-rw-r--r--gcc/testsuite/g++.dg/template/member5.C32
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/20040317-1.C38
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/nothrow-1.C19
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/tree-ssa.exp36
-rw-r--r--gcc/testsuite/g++.dg/warn/Wswitch-1.C14
-rw-r--r--gcc/testsuite/g++.dg/warn/Wswitch-2.C8
-rw-r--r--gcc/testsuite/g++.dg/warn/Wunused-5.C30
-rw-r--r--gcc/testsuite/g++.dg/warn/noeffect5.C8
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ext/arrnew2.C10
-rw-r--r--gcc/testsuite/g++.old-deja/g++.martin/new1.C16
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb42.C19
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb58.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb63.C2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20010518-1.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20030310-1.c13
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20030405-1.c78
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20030405-1.x3
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20030416-1.c16
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20030530-1.c23
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20030530-3.c16
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20030716-1.c7
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20030823-1.c18
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20030902-1.c37
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20030910-1.c11
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20030917-1.c18
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20031124-1.c8
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20031125-1.c36
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20031125-2.c20
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20031203-1.c22
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20031203-2.c6
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20031203-3.c7
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20040219-1.c1
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20040220-1.c16
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20040303-1.c16
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20040303-2.c23
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20040304-1.c61
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20040309-1.c20
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20040310-1.c10
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20040317-1.c4
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20040317-2.c25
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20040317-3.c11
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20040323-1.c11
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20040401-1.c6
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20040415-1.c5
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20040415-2.c7
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20040419-1.c3
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr14730.c16
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr15245.c21
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20000603-1.c11
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20020819-1.c22
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20021113-1.c17
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20030403-1.c16
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20030404-1.c23
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20030501-1.c17
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20030828-1.c18
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20030828-2.c28
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20030903-1.c21
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20030909-1.c35
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20030910-1.c13
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20030913-1.c26
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20031010-1.c34
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20031211-1.c13
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20031211-2.c19
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20040319-1.c17
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20040331-1.c8
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20040409-2.c12
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20040423-1.c30
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/930529-1.x23
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/divcmp-1.c356
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/divcmp-2.c92
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/divcmp-3.c97
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr15296.c73
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/simd-5.c59
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/va-arg-24.c96
-rw-r--r--gcc/testsuite/gcc.dg/20010516-1.c5
-rw-r--r--gcc/testsuite/gcc.dg/20030612-1.c32
-rw-r--r--gcc/testsuite/gcc.dg/20030805-1.c23
-rw-r--r--gcc/testsuite/gcc.dg/20040202-1.c8
-rw-r--r--gcc/testsuite/gcc.dg/20040206-1.c11
-rw-r--r--gcc/testsuite/gcc.dg/Wswitch-2.c8
-rw-r--r--gcc/testsuite/gcc.dg/Wswitch-default.c16
-rw-r--r--gcc/testsuite/gcc.dg/Wswitch-enum.c22
-rw-r--r--gcc/testsuite/gcc.dg/Wswitch.c8
-rw-r--r--gcc/testsuite/gcc.dg/altivec-1.c1
-rw-r--r--gcc/testsuite/gcc.dg/altivec-13.c20
-rw-r--r--gcc/testsuite/gcc.dg/altivec-3.c1
-rw-r--r--gcc/testsuite/gcc.dg/altivec-varargs-1.c1
-rw-r--r--gcc/testsuite/gcc.dg/asm-7.c4
-rw-r--r--gcc/testsuite/gcc.dg/builtins-33.c17
-rw-r--r--gcc/testsuite/gcc.dg/builtins-34.c22
-rw-r--r--gcc/testsuite/gcc.dg/builtins-37.c29
-rw-r--r--gcc/testsuite/gcc.dg/builtins-38.c48
-rw-r--r--gcc/testsuite/gcc.dg/builtins-39.c48
-rw-r--r--gcc/testsuite/gcc.dg/builtins-40.c47
-rw-r--r--gcc/testsuite/gcc.dg/charset/extern.c11
-rw-r--r--gcc/testsuite/gcc.dg/const-elim-1.c11
-rw-r--r--gcc/testsuite/gcc.dg/funcorder.c6
-rw-r--r--gcc/testsuite/gcc.dg/i386-387-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/i386-387-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/i386-387-5.c5
-rw-r--r--gcc/testsuite/gcc.dg/i386-387-6.c4
-rw-r--r--gcc/testsuite/gcc.dg/i386-387-7.c10
-rw-r--r--gcc/testsuite/gcc.dg/i386-387-8.c12
-rw-r--r--gcc/testsuite/gcc.dg/i386-ssetype-1.c3
-rw-r--r--gcc/testsuite/gcc.dg/i386-ssetype-3.c3
-rw-r--r--gcc/testsuite/gcc.dg/local1.c16
-rw-r--r--gcc/testsuite/gcc.dg/loop-3.c45
-rw-r--r--gcc/testsuite/gcc.dg/noncompile/920507-1.c3
-rw-r--r--gcc/testsuite/gcc.dg/noreturn-1.c11
-rw-r--r--gcc/testsuite/gcc.dg/noreturn-4.c4
-rw-r--r--gcc/testsuite/gcc.dg/noreturn-7.c10
-rw-r--r--gcc/testsuite/gcc.dg/pr14475.c8
-rw-r--r--gcc/testsuite/gcc.dg/return-type-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/return-type-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/rs6000-power2-1.c21
-rw-r--r--gcc/testsuite/gcc.dg/rs6000-power2-2.c22
-rw-r--r--gcc/testsuite/gcc.dg/sibcall-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/sibcall-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/sibcall-6.c2
-rw-r--r--gcc/testsuite/gcc.dg/tls/asm-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/torture/builtin-convert-2.c79
-rw-r--r--gcc/testsuite/gcc.dg/torture/builtin-convert-3.c56
-rw-r--r--gcc/testsuite/gcc.dg/torture/builtin-ctype-2.c23
-rw-r--r--gcc/testsuite/gcc.dg/torture/builtin-integral-1.c53
-rw-r--r--gcc/testsuite/gcc.dg/torture/builtin-rounding-1.c106
-rw-r--r--gcc/testsuite/gcc.dg/torture/mips-hilo-1.c75
-rw-r--r--gcc/testsuite/gcc.dg/torture/mips-hilo-2.c28
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030530-2.c26
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030611-1.c13
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030703-1.c21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030703-2.c41
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030708-1.c42
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030709-1.c15
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c53
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030709-3.c45
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030710-1.c53
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030711-1.c53
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030711-2.c67
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030711-3.c59
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c44
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030714-2.c39
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c47
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030729-1.c51
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030730-1.c23
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030730-2.c22
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030731-1.c65
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030731-2.c16
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030807-1.c46
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030807-10.c25
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030807-11.c19
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030807-2.c26
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030807-3.c27
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030807-5.c36
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030807-6.c44
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030807-7.c37
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030807-8.c52
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030807-9.c19
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030808-1.c39
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030814-1.c20
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030814-2.c21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030814-3.c22
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030814-4.c40
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030814-5.c40
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030814-6.c43
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030814-7.c40
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030815-1.c42
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030820-1.c24
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030820-2.c24
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030821-1.c23
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030824-1.c22
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030824-2.c22
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030825-1.c28
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030907-1.c26
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030907-2.c30
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030917-1.c20
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030917-2.c40
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030917-3.c24
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030918-1.c15
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030920-1.c112
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030922-1.c32
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030922-2.c22
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20031015-1.c16
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20031021-1.c20
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20031022-1.c27
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20031031-1.c17
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20031106-1.c20
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20031106-2.c27
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20031106-3.c21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20031106-4.c29
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20031106-5.c28
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20031106-6.c28
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20031113-1.c30
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20031216-1.c19
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040121-1.c27
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c36
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040209-1.c52
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040210-1.c32
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040211-1.c40
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040216-1.c18
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040302-1.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040305-1.c30
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040313-1.c16
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040319-1.c25
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040324-1.c31
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040326-1.c29
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040326-2.c63
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040408-1.c51
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040430-1.c25
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040513-1.c18
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040513-2.c24
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040514-1.c17
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040514-2.c15
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/asm-1.c16
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cfgcleanup-1.c18
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/copy-headers.c15
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/sra-1.c72
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/sra-2.c25
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/sra-3.c27
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-1.c74
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-10.c31
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-11.c41
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-2.c171
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-3.c134
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-7.c27
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-9.c54
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-1.c12
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-2.c16
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c29
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-ccp-1.c17
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-1.c16
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-1.c17
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-1.c19
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-2.c20
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/tailcall-1.c18
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/tailcall-2.c23
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-1.c11
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-2.c12
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-3.c15
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-4.c17
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-5.c72
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/tree-ssa.exp36
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/useless-1.c16
-rw-r--r--gcc/testsuite/gcc.dg/uninit-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/uninit-11.c42
-rw-r--r--gcc/testsuite/gcc.dg/uninit-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/uninit-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/uninit-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/uninit-5.c7
-rw-r--r--gcc/testsuite/gcc.dg/uninit-6.c4
-rw-r--r--gcc/testsuite/gcc.dg/uninit-8.c2
-rw-r--r--gcc/testsuite/gcc.dg/uninit-9.c2
-rw-r--r--gcc/testsuite/gcc.dg/uninit-H.c19
-rw-r--r--gcc/testsuite/gcc.dg/unused-6.c11
-rw-r--r--gcc/testsuite/gcc.dg/vmx/1b-01.c11
-rw-r--r--gcc/testsuite/gcc.dg/vmx/1b-02.c61
-rw-r--r--gcc/testsuite/gcc.dg/vmx/1b-03.c64
-rw-r--r--gcc/testsuite/gcc.dg/vmx/1b-04.c7
-rw-r--r--gcc/testsuite/gcc.dg/vmx/1b-05.c13
-rw-r--r--gcc/testsuite/gcc.dg/vmx/1b-06.c20
-rw-r--r--gcc/testsuite/gcc.dg/vmx/1b-07.c55
-rw-r--r--gcc/testsuite/gcc.dg/vmx/1c-01.c56
-rw-r--r--gcc/testsuite/gcc.dg/vmx/1c-02.c34
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3a-01.c16
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3a-01a.c17
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3a-01m.c17
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3a-03.c18
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3a-03m.c18
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3a-04.c18
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3a-04m.c18
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3a-05.c22
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3a-06.c15
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3a-06m.c15
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3a-07.c16
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3b-01.c18
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3b-02.c16
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3b-10.c21
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3b-13.c15
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3b-14.c29
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3b-15.c19
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3c-01.c86
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3c-01a.c1450
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3c-02.c17
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3c-03.c17
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3d-01.c171
-rw-r--r--gcc/testsuite/gcc.dg/vmx/4-01.c7
-rw-r--r--gcc/testsuite/gcc.dg/vmx/4-03.c7
-rw-r--r--gcc/testsuite/gcc.dg/vmx/5-01.c4
-rw-r--r--gcc/testsuite/gcc.dg/vmx/5-02.c4
-rw-r--r--gcc/testsuite/gcc.dg/vmx/5-03.c28
-rw-r--r--gcc/testsuite/gcc.dg/vmx/5-04.c10
-rw-r--r--gcc/testsuite/gcc.dg/vmx/5-05.c4
-rw-r--r--gcc/testsuite/gcc.dg/vmx/5-06.c4
-rw-r--r--gcc/testsuite/gcc.dg/vmx/5-07.c28
-rw-r--r--gcc/testsuite/gcc.dg/vmx/5-07t.c37
-rw-r--r--gcc/testsuite/gcc.dg/vmx/5-08.c10
-rw-r--r--gcc/testsuite/gcc.dg/vmx/5-10.c1352
-rw-r--r--gcc/testsuite/gcc.dg/vmx/5-11.c289
-rw-r--r--gcc/testsuite/gcc.dg/vmx/7-01.c36
-rw-r--r--gcc/testsuite/gcc.dg/vmx/7-01a.c36
-rw-r--r--gcc/testsuite/gcc.dg/vmx/7c-01.c11
-rw-r--r--gcc/testsuite/gcc.dg/vmx/7d-01.c19
-rw-r--r--gcc/testsuite/gcc.dg/vmx/7d-02.c21
-rw-r--r--gcc/testsuite/gcc.dg/vmx/8-01.c4
-rw-r--r--gcc/testsuite/gcc.dg/vmx/8-02.c299
-rw-r--r--gcc/testsuite/gcc.dg/vmx/8-02a.c17
-rw-r--r--gcc/testsuite/gcc.dg/vmx/brode-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/vmx/bug-1.c39
-rw-r--r--gcc/testsuite/gcc.dg/vmx/bug-2.c24
-rw-r--r--gcc/testsuite/gcc.dg/vmx/bug-3.c45
-rw-r--r--gcc/testsuite/gcc.dg/vmx/cw-bug-1.c12
-rw-r--r--gcc/testsuite/gcc.dg/vmx/cw-bug-2.c9
-rw-r--r--gcc/testsuite/gcc.dg/vmx/cw-bug-3.c5
-rw-r--r--gcc/testsuite/gcc.dg/vmx/dct.c176
-rw-r--r--gcc/testsuite/gcc.dg/vmx/debug-1.c26
-rw-r--r--gcc/testsuite/gcc.dg/vmx/debug-2.c42
-rw-r--r--gcc/testsuite/gcc.dg/vmx/debug-3.c75
-rw-r--r--gcc/testsuite/gcc.dg/vmx/debug-4.c78
-rw-r--r--gcc/testsuite/gcc.dg/vmx/dos-bug-1-gdb.c7
-rw-r--r--gcc/testsuite/gcc.dg/vmx/dos-bug-2-gdb.c7
-rw-r--r--gcc/testsuite/gcc.dg/vmx/eg-5.c27
-rw-r--r--gcc/testsuite/gcc.dg/vmx/fft.c99
-rw-r--r--gcc/testsuite/gcc.dg/vmx/gcc-bug-1.c20
-rw-r--r--gcc/testsuite/gcc.dg/vmx/gcc-bug-2.c19
-rw-r--r--gcc/testsuite/gcc.dg/vmx/gcc-bug-3.c26
-rw-r--r--gcc/testsuite/gcc.dg/vmx/gcc-bug-4.c5
-rw-r--r--gcc/testsuite/gcc.dg/vmx/gcc-bug-5.c26
-rw-r--r--gcc/testsuite/gcc.dg/vmx/gcc-bug-6.c30
-rw-r--r--gcc/testsuite/gcc.dg/vmx/gcc-bug-7.c35
-rw-r--r--gcc/testsuite/gcc.dg/vmx/gcc-bug-8.c13
-rw-r--r--gcc/testsuite/gcc.dg/vmx/gcc-bug-9.c5
-rw-r--r--gcc/testsuite/gcc.dg/vmx/gcc-bug-b.c23
-rw-r--r--gcc/testsuite/gcc.dg/vmx/gcc-bug-c.c25
-rw-r--r--gcc/testsuite/gcc.dg/vmx/gcc-bug-d.c14
-rw-r--r--gcc/testsuite/gcc.dg/vmx/gcc-bug-e.c44
-rw-r--r--gcc/testsuite/gcc.dg/vmx/gcc-bug-f.c125
-rw-r--r--gcc/testsuite/gcc.dg/vmx/gcc-bug-g.c119
-rw-r--r--gcc/testsuite/gcc.dg/vmx/gcc-bug-i.c42
-rw-r--r--gcc/testsuite/gcc.dg/vmx/harness.h30
-rw-r--r--gcc/testsuite/gcc.dg/vmx/ira1.c10
-rw-r--r--gcc/testsuite/gcc.dg/vmx/ira2.c23
-rw-r--r--gcc/testsuite/gcc.dg/vmx/ira2a.c9
-rw-r--r--gcc/testsuite/gcc.dg/vmx/ira2b.c17
-rw-r--r--gcc/testsuite/gcc.dg/vmx/ira2c.c11
-rw-r--r--gcc/testsuite/gcc.dg/vmx/mem.c9
-rw-r--r--gcc/testsuite/gcc.dg/vmx/newton-1.c67
-rw-r--r--gcc/testsuite/gcc.dg/vmx/ops.c3893
-rw-r--r--gcc/testsuite/gcc.dg/vmx/sn7153.c62
-rw-r--r--gcc/testsuite/gcc.dg/vmx/spill.c131
-rw-r--r--gcc/testsuite/gcc.dg/vmx/spill2.c155
-rw-r--r--gcc/testsuite/gcc.dg/vmx/spill3.c156
-rw-r--r--gcc/testsuite/gcc.dg/vmx/t.c43
-rw-r--r--gcc/testsuite/gcc.dg/vmx/varargs-1.c96
-rw-r--r--gcc/testsuite/gcc.dg/vmx/varargs-2.c78
-rw-r--r--gcc/testsuite/gcc.dg/vmx/varargs-3.c75
-rw-r--r--gcc/testsuite/gcc.dg/vmx/varargs-4.c299
-rw-r--r--gcc/testsuite/gcc.dg/vmx/varargs-5.c71
-rw-r--r--gcc/testsuite/gcc.dg/vmx/varargs-6.c35
-rw-r--r--gcc/testsuite/gcc.dg/vmx/varargs-7.c83
-rw-r--r--gcc/testsuite/gcc.dg/vmx/vmx.exp51
-rw-r--r--gcc/testsuite/gcc.dg/vmx/vprint-1.c266
-rw-r--r--gcc/testsuite/gcc.dg/vmx/vscan-1.c418
-rw-r--r--gcc/testsuite/gcc.dg/vmx/x-01.c25
-rw-r--r--gcc/testsuite/gcc.dg/vmx/x-02.c34
-rw-r--r--gcc/testsuite/gcc.dg/vmx/x-03.c124
-rw-r--r--gcc/testsuite/gcc.dg/vmx/x-04.c80
-rw-r--r--gcc/testsuite/gcc.dg/vmx/x-05.c82
-rw-r--r--gcc/testsuite/gcc.dg/vmx/yousufi-1.c15
-rw-r--r--gcc/testsuite/gcc.dg/vmx/zero-1.c13
-rw-r--r--gcc/testsuite/gcc.dg/vmx/zero.c100
-rw-r--r--gcc/testsuite/gcc.dg/vr-mult-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/vr-mult-2.c10
-rw-r--r--gcc/testsuite/gcc.dg/warn-1.c4
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/ChangeLog.g9599
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/actual.f9038
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/allocate.f9026
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/ambig.f9026
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/arrayio.f9012
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/bergervoet2.f905
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/compile.exp55
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/contained_1.f9015
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/contained_2.f9011
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/contained_3.f9012
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/contained_4.f9035
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/contained_5.f9010
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/convert.f9037
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/do_1.f9028
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/dummyfn.f9013
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/empty_interface_1.f904
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/emptyif.f9042
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/fnresvar.f905
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/gen_interf.f9019
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/implicit.f908
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/io_end.f909
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/module_common.f9010
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/module_expr.f9018
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/module_proc.f9014
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/module_result.f909
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/named_args.f906
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/noncontinuation_1.f3
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/parameter_1.f907
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/parameter_2.f9023
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/shape_reshape.f908
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/stoppause.f9010
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/strparm_1.f906
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/write.f905
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/a_edit_1.f9017
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/adjustr.f9046
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/allocate.f9038
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/alternate_return.f9018
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/args.f9022
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/arithmeticif.f9025
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/arrayarg.f90145
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/arrayarg2.f9021
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/arraysave.f9024
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/assumed_size.f9039
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/bounds.f9035
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/character_select_1.f9012
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/cmplx.f9045
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/common.f9053
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/common_size.f9010
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/constructor.f9029
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/contained.f9016
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/contained2.f9028
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/csqrt_1.f9078
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/data.f9072
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/data_2.f9017
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/dep_fails.f9050
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/der_init.f9032
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/der_init_2.f9015
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/der_io.f9067
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/der_point.f9045
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/der_type.f9045
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/direct_io.f9020
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/elemental.f9032
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/empty_format.f9014
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/emptyif.f9020
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/execute.exp59
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/f2_edit_1.f9010
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/forall.f9017
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/forall_1.f9061
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/forall_2.f9020
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/forall_3.f9036
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/forall_4.f9027
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/forall_5.f9028
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/forall_6.f9025
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/function_module_1.f9036
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/hollerith.f909
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/initializer.f9026
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/inquire_1.f908
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/inquire_2.f906
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/inquire_3.f9013
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/inquire_4.f9020
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/integer_select.f9071
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/integer_select_1.f9031
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/internal_write.f9011
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_abs.f9033
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_achar.f909
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_aint_anint.f9055
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_anyall.f9026
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_associated.f90137
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_associated_2.f9036
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_bitops.f9029
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_count.f9021
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_cshift.f9043
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_dim.f9020
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_dotprod.f9025
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_dprod.f9013
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_dummy.f9023
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_eoshift.f9060
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_fraction_exponent.f9084
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_index.f9015
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_integer.f9018
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_len.f9022
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_matmul.f9024
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_merge.f9015
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_minmax.f9037
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc.f9052
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc_2.f9022
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc_3.f9012
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc_4.f9013
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmval.f9028
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mod_ulo.f9064
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_nearest.f9071
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_pack.f9012
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_present.f9040
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_product.f9025
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_rrspacing.f9027
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_scale.f9027
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_set_exponent.f9091
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_shape.f9022
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_si_kind.f9035
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_sign.f9031
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_size.f9037
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_spacing.f9033
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_spread.f9010
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_sr_kind.f9061
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_sum.f9026
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_transpose.f9024
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_trim.f9023
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_unpack.f9017
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/list_read_1.f9053
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/logical_select_1.f9055
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/mainsub.f9017
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/math.f90100
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/module_interface.f9039
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/module_interface_2.f9029
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/mystery_proc.f9023
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/nestcons.f909
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/parameter_1.f9012
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/partparm.f9015
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/plusconst_1.f9015
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/power.f9043
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/procarg.f9029
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/ptr.f9020
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/random_init.f9011
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/read_eof.f905
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/retarray.f9045
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/retarray_2.f9020
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/scalarize.f9023
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/scalarize2.f9024
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/scalarize3.f908
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/slash_edit.f9014
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/spec_abs.f9012
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/specifics.f90133
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/st_function.f9087
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/stack_varsize.f9030
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/straret.f9018
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/strarray_1.f9013
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/strarray_2.f9014
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/strarray_3.f9050
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/strarray_4.f9039
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/strcmp.f9016
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/strcommon_1.f9028
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/string.f9015
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/strlen.f9034
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/strret.f9025
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/test_slice.f9017
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/unopened_unit_1.f9013
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/userop.f9067
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/where_1.f9041
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/where_2.f9022
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/where_3.f9021
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/where_4.f9013
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/where_5.f9013
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/where_6.f9023
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/write_logical.f9023
-rw-r--r--gcc/testsuite/lib/fortran-torture.exp344
-rw-r--r--gcc/testsuite/lib/gcc-dg.exp1
-rw-r--r--gcc/testsuite/lib/gfortran.exp233
-rw-r--r--gcc/testsuite/lib/scantree.exp243
-rw-r--r--gcc/testsuite/lib/target-supports.exp2
-rw-r--r--gcc/testsuite/objc.dg/image-info.m2
-rw-r--r--gcc/timevar.def33
-rw-r--r--gcc/toplev.c182
-rw-r--r--gcc/toplev.h2
-rw-r--r--gcc/tracer.c4
-rw-r--r--gcc/tree-alias-ander.c933
-rw-r--r--gcc/tree-alias-ander.h7
-rw-r--r--gcc/tree-alias-common.c1264
-rw-r--r--gcc/tree-alias-common.h99
-rw-r--r--gcc/tree-alias-type.c37
-rw-r--r--gcc/tree-alias-type.h41
-rw-r--r--gcc/tree-browser.c1045
-rw-r--r--gcc/tree-browser.def98
-rw-r--r--gcc/tree-cfg.c4594
-rw-r--r--gcc/tree-complex.c561
-rw-r--r--gcc/tree-dfa.c1165
-rw-r--r--gcc/tree-dump.c227
-rw-r--r--gcc/tree-dump.h6
-rw-r--r--gcc/tree-eh.c1756
-rw-r--r--gcc/tree-flow-inline.h604
-rw-r--r--gcc/tree-flow.h597
-rw-r--r--gcc/tree-gimple.c642
-rw-r--r--gcc/tree-gimple.h127
-rw-r--r--gcc/tree-inline.c1828
-rw-r--r--gcc/tree-inline.h3
-rw-r--r--gcc/tree-into-ssa.c1176
-rw-r--r--gcc/tree-iterator.c369
-rw-r--r--gcc/tree-iterator.h120
-rw-r--r--gcc/tree-mudflap.c1093
-rw-r--r--gcc/tree-mudflap.h41
-rw-r--r--gcc/tree-nested.c1383
-rw-r--r--gcc/tree-nomudflap.c127
-rw-r--r--gcc/tree-nrv.c217
-rw-r--r--gcc/tree-optimize.c558
-rw-r--r--gcc/tree-outof-ssa.c2173
-rw-r--r--gcc/tree-pass.h130
-rw-r--r--gcc/tree-phinodes.c524
-rw-r--r--gcc/tree-pretty-print.c2267
-rw-r--r--gcc/tree-profile.c188
-rw-r--r--gcc/tree-sra.c1182
-rw-r--r--gcc/tree-ssa-alias.c2118
-rw-r--r--gcc/tree-ssa-ccp.c2393
-rw-r--r--gcc/tree-ssa-copy.c355
-rw-r--r--gcc/tree-ssa-copyrename.c388
-rw-r--r--gcc/tree-ssa-dce.c913
-rw-r--r--gcc/tree-ssa-dom.c3144
-rw-r--r--gcc/tree-ssa-dse.c445
-rw-r--r--gcc/tree-ssa-forwprop.c526
-rw-r--r--gcc/tree-ssa-live.c1889
-rw-r--r--gcc/tree-ssa-live.h748
-rw-r--r--gcc/tree-ssa-loop.c365
-rw-r--r--gcc/tree-ssa-operands.c1318
-rw-r--r--gcc/tree-ssa-operands.h97
-rw-r--r--gcc/tree-ssa-phiopt.c346
-rw-r--r--gcc/tree-ssa-pre.c3390
-rw-r--r--gcc/tree-ssa.c1099
-rw-r--r--gcc/tree-ssanames.c184
-rw-r--r--gcc/tree-tailcall.c932
-rw-r--r--gcc/tree.c544
-rw-r--r--gcc/tree.def132
-rw-r--r--gcc/tree.h694
-rw-r--r--gcc/unroll.c4
-rw-r--r--gcc/unwind-sjlj.c17
-rw-r--r--gcc/value-prof.c94
-rw-r--r--gcc/value-prof.h52
-rw-r--r--gcc/var-tracking.c29
-rw-r--r--gcc/varasm.c55
-rw-r--r--gcc/varray.c25
-rw-r--r--gcc/varray.h28
-rw-r--r--gcc/version.c2
-rw-r--r--gcc/vmsdbgout.c42
-rw-r--r--include/ChangeLog49
-rw-r--r--include/demangle.h2
-rw-r--r--include/hashtab.h13
-rw-r--r--libada/ChangeLog51
-rw-r--r--libada/Makefile.in208
-rwxr-xr-xlibada/configure263
-rw-r--r--libada/configure.ac82
-rw-r--r--libbanshee/AUTHORS0
-rw-r--r--libbanshee/COPYING0
-rw-r--r--libbanshee/COPYRIGHT26
-rw-r--r--libbanshee/ChangeLog120
-rw-r--r--libbanshee/INSTALL0
-rw-r--r--libbanshee/Makefile.am41
-rw-r--r--libbanshee/Makefile.in554
-rw-r--r--libbanshee/NEWS0
-rw-r--r--libbanshee/README11
-rw-r--r--libbanshee/acinclude.m427
-rw-r--r--libbanshee/aclocal.m4928
-rw-r--r--libbanshee/config.h.in110
-rwxr-xr-xlibbanshee/configure5967
-rw-r--r--libbanshee/configure.in44
-rw-r--r--libbanshee/engine/ChangeLog14
-rw-r--r--libbanshee/engine/Makefile.am6
-rw-r--r--libbanshee/engine/Makefile.in405
-rw-r--r--libbanshee/engine/array.c96
-rw-r--r--libbanshee/engine/array.h76
-rw-r--r--libbanshee/engine/banshee.c67
-rw-r--r--libbanshee/engine/banshee.h105
-rw-r--r--libbanshee/engine/bool.h63
-rw-r--r--libbanshee/engine/bounds.c89
-rw-r--r--libbanshee/engine/bounds.h56
-rw-r--r--libbanshee/engine/buffer.c129
-rw-r--r--libbanshee/engine/buffer.h58
-rw-r--r--libbanshee/engine/compiler.h48
-rw-r--r--libbanshee/engine/dot.c362
-rw-r--r--libbanshee/engine/dot.h126
-rw-r--r--libbanshee/engine/flow-var.c181
-rw-r--r--libbanshee/engine/flow-var.h76
-rw-r--r--libbanshee/engine/flowrow-sort.c1107
-rw-r--r--libbanshee/engine/flowrow-sort.h133
-rw-r--r--libbanshee/engine/hash.c427
-rw-r--r--libbanshee/engine/hash.h140
-rw-r--r--libbanshee/engine/hashset.c217
-rw-r--r--libbanshee/engine/hashset.h50
-rw-r--r--libbanshee/engine/jcollection.c326
-rw-r--r--libbanshee/engine/jcollection.h63
-rw-r--r--libbanshee/engine/linkage.h44
-rw-r--r--libbanshee/engine/list.c438
-rw-r--r--libbanshee/engine/list.h216
-rw-r--r--libbanshee/engine/malloc.c5400
-rw-r--r--libbanshee/engine/nonspec.c852
-rw-r--r--libbanshee/engine/nonspec.h189
-rw-r--r--libbanshee/engine/setif-sort.c1141
-rw-r--r--libbanshee/engine/setif-sort.h134
-rw-r--r--libbanshee/engine/setif-var.c226
-rw-r--r--libbanshee/engine/setif-var.h72
-rw-r--r--libbanshee/engine/setst-sort.c907
-rw-r--r--libbanshee/engine/setst-sort.h121
-rw-r--r--libbanshee/engine/setst-var.c249
-rw-r--r--libbanshee/engine/setst-var.h77
-rw-r--r--libbanshee/engine/stamp.c120
-rw-r--r--libbanshee/engine/stamp.h57
-rw-r--r--libbanshee/engine/term-sort.c291
-rw-r--r--libbanshee/engine/term-sort.h101
-rw-r--r--libbanshee/engine/term-var.c133
-rw-r--r--libbanshee/engine/term-var.h60
-rw-r--r--libbanshee/engine/termhash.c262
-rw-r--r--libbanshee/engine/termhash.h48
-rw-r--r--libbanshee/engine/ufind.c177
-rw-r--r--libbanshee/engine/ufind.h178
-rw-r--r--libbanshee/engine/util.c201
-rw-r--r--libbanshee/engine/util.h108
-rw-r--r--libbanshee/libcompat/Makefile.am4
-rw-r--r--libbanshee/libcompat/Makefile.in365
-rw-r--r--libbanshee/libcompat/alloc.c133
-rw-r--r--libbanshee/libcompat/pages.c459
-rw-r--r--libbanshee/libcompat/profile.c521
-rw-r--r--libbanshee/libcompat/profile.h59
-rw-r--r--libbanshee/libcompat/radix-tree.c364
-rw-r--r--libbanshee/libcompat/radix-tree.h51
-rw-r--r--libbanshee/libcompat/regions.c387
-rw-r--r--libbanshee/libcompat/regions.h86
-rw-r--r--libbanshee/points-to/Makefile.am4
-rw-r--r--libbanshee/points-to/Makefile.in364
-rw-r--r--libbanshee/points-to/andersen_terms.c1363
-rw-r--r--libbanshee/points-to/andersen_terms.h100
-rw-r--r--libbanshee/points-to/andersen_terms.spec34
-rw-r--r--libbanshee/points-to/andersen_terms_st.spec34
-rw-r--r--libbanshee/stamp-h.in1
-rw-r--r--libffi/ChangeLog22
-rwxr-xr-xlibffi/configure1107
-rw-r--r--libffi/configure.ac2
-rw-r--r--libffi/src/powerpc/darwin.S6
-rw-r--r--libffi/src/powerpc/darwin_closure.S6
-rw-r--r--libffi/testsuite/libffi.call/cls_multi_schar.c2
-rw-r--r--libffi/testsuite/libffi.call/cls_multi_sshort.c2
-rw-r--r--libffi/testsuite/libffi.call/cls_multi_ushort.c2
-rw-r--r--libgfortran/AUTHORS2
-rw-r--r--libgfortran/COPYING504
-rw-r--r--libgfortran/ChangeLog769
-rw-r--r--libgfortran/INSTALL1
-rw-r--r--libgfortran/Makefile.am464
-rw-r--r--libgfortran/Makefile.in5479
-rw-r--r--libgfortran/NEWS1
-rw-r--r--libgfortran/README14
-rw-r--r--libgfortran/acinclude.m485
-rw-r--r--libgfortran/aclocal.m4958
-rw-r--r--libgfortran/config.h.in106
-rwxr-xr-xlibgfortran/configure8133
-rw-r--r--libgfortran/configure.in88
-rw-r--r--libgfortran/fmain.c22
-rw-r--r--libgfortran/generated/_abs_c4.f9029
-rw-r--r--libgfortran/generated/_abs_c8.f9029
-rw-r--r--libgfortran/generated/_abs_i4.f9029
-rw-r--r--libgfortran/generated/_abs_i8.f9029
-rw-r--r--libgfortran/generated/_abs_r4.f9029
-rw-r--r--libgfortran/generated/_abs_r8.f9029
-rw-r--r--libgfortran/generated/_acos_r4.f9029
-rw-r--r--libgfortran/generated/_acos_r8.f9029
-rw-r--r--libgfortran/generated/_aint_r4.f9029
-rw-r--r--libgfortran/generated/_aint_r8.f9029
-rw-r--r--libgfortran/generated/_anint_r4.f9029
-rw-r--r--libgfortran/generated/_anint_r8.f9029
-rw-r--r--libgfortran/generated/_asin_r4.f9029
-rw-r--r--libgfortran/generated/_asin_r8.f9029
-rw-r--r--libgfortran/generated/_atan2_r4.f9029
-rw-r--r--libgfortran/generated/_atan2_r8.f9029
-rw-r--r--libgfortran/generated/_atan_r4.f9029
-rw-r--r--libgfortran/generated/_atan_r8.f9029
-rw-r--r--libgfortran/generated/_conjg_c4.f9029
-rw-r--r--libgfortran/generated/_conjg_c8.f9029
-rw-r--r--libgfortran/generated/_cos_c4.f9029
-rw-r--r--libgfortran/generated/_cos_c8.f9029
-rw-r--r--libgfortran/generated/_cos_r4.f9029
-rw-r--r--libgfortran/generated/_cos_r8.f9029
-rw-r--r--libgfortran/generated/_cosh_r4.f9029
-rw-r--r--libgfortran/generated/_cosh_r8.f9029
-rw-r--r--libgfortran/generated/_dim_i4.f9029
-rw-r--r--libgfortran/generated/_dim_i8.f9029
-rw-r--r--libgfortran/generated/_dim_r4.f9029
-rw-r--r--libgfortran/generated/_dim_r8.f9029
-rw-r--r--libgfortran/generated/_exp_c4.f9029
-rw-r--r--libgfortran/generated/_exp_c8.f9029
-rw-r--r--libgfortran/generated/_exp_r4.f9029
-rw-r--r--libgfortran/generated/_exp_r8.f9029
-rw-r--r--libgfortran/generated/_log10_r4.f9029
-rw-r--r--libgfortran/generated/_log10_r8.f9029
-rw-r--r--libgfortran/generated/_log_c4.f9029
-rw-r--r--libgfortran/generated/_log_c8.f9029
-rw-r--r--libgfortran/generated/_log_r4.f9029
-rw-r--r--libgfortran/generated/_log_r8.f9029
-rw-r--r--libgfortran/generated/_mod_i4.f9029
-rw-r--r--libgfortran/generated/_mod_i8.f9029
-rw-r--r--libgfortran/generated/_mod_r4.f9029
-rw-r--r--libgfortran/generated/_mod_r8.f9029
-rw-r--r--libgfortran/generated/_sign_i4.f9029
-rw-r--r--libgfortran/generated/_sign_i8.f9029
-rw-r--r--libgfortran/generated/_sign_r4.f9029
-rw-r--r--libgfortran/generated/_sign_r8.f9029
-rw-r--r--libgfortran/generated/_sin_c4.f9029
-rw-r--r--libgfortran/generated/_sin_c8.f9029
-rw-r--r--libgfortran/generated/_sin_r4.f9029
-rw-r--r--libgfortran/generated/_sin_r8.f9029
-rw-r--r--libgfortran/generated/_sinh_r4.f9029
-rw-r--r--libgfortran/generated/_sinh_r8.f9029
-rw-r--r--libgfortran/generated/_sqrt_c4.f9029
-rw-r--r--libgfortran/generated/_sqrt_c8.f9029
-rw-r--r--libgfortran/generated/_sqrt_r4.f9029
-rw-r--r--libgfortran/generated/_sqrt_r8.f9029
-rw-r--r--libgfortran/generated/_tan_r4.f9029
-rw-r--r--libgfortran/generated/_tan_r8.f9029
-rw-r--r--libgfortran/generated/_tanh_r4.f9029
-rw-r--r--libgfortran/generated/_tanh_r8.f9029
-rw-r--r--libgfortran/generated/all_l4.c133
-rw-r--r--libgfortran/generated/all_l8.c133
-rw-r--r--libgfortran/generated/any_l4.c133
-rw-r--r--libgfortran/generated/any_l8.c133
-rw-r--r--libgfortran/generated/count_4_l4.c129
-rw-r--r--libgfortran/generated/count_4_l8.c129
-rw-r--r--libgfortran/generated/count_8_l4.c129
-rw-r--r--libgfortran/generated/count_8_l8.c129
-rw-r--r--libgfortran/generated/cshift1_4.c170
-rw-r--r--libgfortran/generated/cshift1_8.c170
-rw-r--r--libgfortran/generated/dotprod_c4.c67
-rw-r--r--libgfortran/generated/dotprod_c8.c67
-rw-r--r--libgfortran/generated/dotprod_i4.c64
-rw-r--r--libgfortran/generated/dotprod_i8.c64
-rw-r--r--libgfortran/generated/dotprod_l4.c74
-rw-r--r--libgfortran/generated/dotprod_l8.c74
-rw-r--r--libgfortran/generated/dotprod_r4.c64
-rw-r--r--libgfortran/generated/dotprod_r8.c64
-rw-r--r--libgfortran/generated/eoshift1_4.c178
-rw-r--r--libgfortran/generated/eoshift1_8.c178
-rw-r--r--libgfortran/generated/eoshift3_4.c193
-rw-r--r--libgfortran/generated/eoshift3_8.c193
-rw-r--r--libgfortran/generated/exp_c4.c139
-rw-r--r--libgfortran/generated/exp_c8.c139
-rw-r--r--libgfortran/generated/exponent_r4.c31
-rw-r--r--libgfortran/generated/exponent_r8.c31
-rw-r--r--libgfortran/generated/fraction_r4.c30
-rw-r--r--libgfortran/generated/fraction_r8.c30
-rw-r--r--libgfortran/generated/hyp_c4.c71
-rw-r--r--libgfortran/generated/hyp_c8.c71
-rw-r--r--libgfortran/generated/in_pack_i4.c115
-rw-r--r--libgfortran/generated/in_pack_i8.c115
-rw-r--r--libgfortran/generated/in_unpack_i4.c102
-rw-r--r--libgfortran/generated/in_unpack_i8.c102
-rw-r--r--libgfortran/generated/matmul_c4.c138
-rw-r--r--libgfortran/generated/matmul_c8.c138
-rw-r--r--libgfortran/generated/matmul_i4.c138
-rw-r--r--libgfortran/generated/matmul_i8.c138
-rw-r--r--libgfortran/generated/matmul_l4.c151
-rw-r--r--libgfortran/generated/matmul_l8.c151
-rw-r--r--libgfortran/generated/matmul_r4.c138
-rw-r--r--libgfortran/generated/matmul_r8.c138
-rw-r--r--libgfortran/generated/maxloc0_4_i4.c230
-rw-r--r--libgfortran/generated/maxloc0_4_i8.c230
-rw-r--r--libgfortran/generated/maxloc0_4_r4.c230
-rw-r--r--libgfortran/generated/maxloc0_4_r8.c230
-rw-r--r--libgfortran/generated/maxloc0_8_i4.c230
-rw-r--r--libgfortran/generated/maxloc0_8_i8.c230
-rw-r--r--libgfortran/generated/maxloc0_8_r4.c230
-rw-r--r--libgfortran/generated/maxloc0_8_r8.c230
-rw-r--r--libgfortran/generated/maxloc1_4_i4.c266
-rw-r--r--libgfortran/generated/maxloc1_4_i8.c266
-rw-r--r--libgfortran/generated/maxloc1_4_r4.c266
-rw-r--r--libgfortran/generated/maxloc1_4_r8.c266
-rw-r--r--libgfortran/generated/maxloc1_8_i4.c266
-rw-r--r--libgfortran/generated/maxloc1_8_i8.c266
-rw-r--r--libgfortran/generated/maxloc1_8_r4.c266
-rw-r--r--libgfortran/generated/maxloc1_8_r8.c266
-rw-r--r--libgfortran/generated/maxval_i4.c255
-rw-r--r--libgfortran/generated/maxval_i8.c255
-rw-r--r--libgfortran/generated/maxval_r4.c255
-rw-r--r--libgfortran/generated/maxval_r8.c255
-rw-r--r--libgfortran/generated/minloc0_4_i4.c230
-rw-r--r--libgfortran/generated/minloc0_4_i8.c230
-rw-r--r--libgfortran/generated/minloc0_4_r4.c230
-rw-r--r--libgfortran/generated/minloc0_4_r8.c230
-rw-r--r--libgfortran/generated/minloc0_8_i4.c230
-rw-r--r--libgfortran/generated/minloc0_8_i8.c230
-rw-r--r--libgfortran/generated/minloc0_8_r4.c230
-rw-r--r--libgfortran/generated/minloc0_8_r8.c230
-rw-r--r--libgfortran/generated/minloc1_4_i4.c266
-rw-r--r--libgfortran/generated/minloc1_4_i8.c266
-rw-r--r--libgfortran/generated/minloc1_4_r4.c266
-rw-r--r--libgfortran/generated/minloc1_4_r8.c266
-rw-r--r--libgfortran/generated/minloc1_8_i4.c266
-rw-r--r--libgfortran/generated/minloc1_8_i8.c266
-rw-r--r--libgfortran/generated/minloc1_8_r4.c266
-rw-r--r--libgfortran/generated/minloc1_8_r8.c266
-rw-r--r--libgfortran/generated/minval_i4.c255
-rw-r--r--libgfortran/generated/minval_i8.c255
-rw-r--r--libgfortran/generated/minval_r4.c255
-rw-r--r--libgfortran/generated/minval_r8.c255
-rw-r--r--libgfortran/generated/nearest_r4.c38
-rw-r--r--libgfortran/generated/nearest_r8.c38
-rw-r--r--libgfortran/generated/product_c4.c253
-rw-r--r--libgfortran/generated/product_c8.c253
-rw-r--r--libgfortran/generated/product_i4.c253
-rw-r--r--libgfortran/generated/product_i8.c253
-rw-r--r--libgfortran/generated/product_r4.c253
-rw-r--r--libgfortran/generated/product_r8.c253
-rw-r--r--libgfortran/generated/reshape_i4.c225
-rw-r--r--libgfortran/generated/reshape_i8.c225
-rw-r--r--libgfortran/generated/set_exponent_r4.c30
-rw-r--r--libgfortran/generated/set_exponent_r8.c30
-rw-r--r--libgfortran/generated/shape_i4.c43
-rw-r--r--libgfortran/generated/shape_i8.c43
-rw-r--r--libgfortran/generated/sum_c4.c252
-rw-r--r--libgfortran/generated/sum_c8.c252
-rw-r--r--libgfortran/generated/sum_i4.c252
-rw-r--r--libgfortran/generated/sum_i8.c252
-rw-r--r--libgfortran/generated/sum_r4.c252
-rw-r--r--libgfortran/generated/sum_r8.c252
-rw-r--r--libgfortran/generated/transpose_i4.c69
-rw-r--r--libgfortran/generated/transpose_i8.c69
-rw-r--r--libgfortran/generated/trig_c4.c71
-rw-r--r--libgfortran/generated/trig_c8.c71
-rw-r--r--libgfortran/intrinsics/abort.c31
-rw-r--r--libgfortran/intrinsics/associated.c50
-rw-r--r--libgfortran/intrinsics/cpu_time.c116
-rw-r--r--libgfortran/intrinsics/cshift0.c169
-rw-r--r--libgfortran/intrinsics/dprod_r8.f9027
-rw-r--r--libgfortran/intrinsics/eoshift0.c188
-rw-r--r--libgfortran/intrinsics/eoshift2.c204
-rw-r--r--libgfortran/intrinsics/ishftc.c64
-rw-r--r--libgfortran/intrinsics/pack_generic.c146
-rw-r--r--libgfortran/intrinsics/random.c361
-rw-r--r--libgfortran/intrinsics/reshape_generic.c231
-rw-r--r--libgfortran/intrinsics/reshape_packed.c46
-rw-r--r--libgfortran/intrinsics/selected_kind.f9090
-rw-r--r--libgfortran/intrinsics/size.c56
-rw-r--r--libgfortran/intrinsics/spread_generic.c118
-rw-r--r--libgfortran/intrinsics/string_intrinsics.c393
-rw-r--r--libgfortran/intrinsics/transpose_generic.c74
-rw-r--r--libgfortran/intrinsics/unpack_generic.c154
-rw-r--r--libgfortran/io/backspace.c160
-rw-r--r--libgfortran/io/close.c70
-rw-r--r--libgfortran/io/endfile.c46
-rw-r--r--libgfortran/io/format.c1285
-rw-r--r--libgfortran/io/inquire.c371
-rw-r--r--libgfortran/io/io.h653
-rw-r--r--libgfortran/io/list_read.c1531
-rw-r--r--libgfortran/io/lock.c84
-rw-r--r--libgfortran/io/open.c528
-rw-r--r--libgfortran/io/read.c793
-rw-r--r--libgfortran/io/rewind.c56
-rw-r--r--libgfortran/io/transfer.c1498
-rw-r--r--libgfortran/io/unit.c380
-rw-r--r--libgfortran/io/unix.c1432
-rw-r--r--libgfortran/io/write.c1129
-rw-r--r--libgfortran/libgfortran.h406
-rw-r--r--libgfortran/m4/all.m437
-rw-r--r--libgfortran/m4/any.m437
-rw-r--r--libgfortran/m4/cexp.m4140
-rw-r--r--libgfortran/m4/chyp.m472
-rw-r--r--libgfortran/m4/count.m433
-rw-r--r--libgfortran/m4/cshift1.m4175
-rw-r--r--libgfortran/m4/ctrig.m472
-rw-r--r--libgfortran/m4/dotprod.m471
-rw-r--r--libgfortran/m4/dotprodc.m474
-rw-r--r--libgfortran/m4/dotprodl.m479
-rw-r--r--libgfortran/m4/eoshift1.m4183
-rw-r--r--libgfortran/m4/eoshift3.m4198
-rw-r--r--libgfortran/m4/exponent.m432
-rw-r--r--libgfortran/m4/fraction.m431
-rw-r--r--libgfortran/m4/head.m421
-rw-r--r--libgfortran/m4/iforeach.m4196
-rw-r--r--libgfortran/m4/ifunction.m4256
-rw-r--r--libgfortran/m4/in_pack.m4122
-rw-r--r--libgfortran/m4/in_unpack.m4109
-rw-r--r--libgfortran/m4/iparm.m426
-rw-r--r--libgfortran/m4/matmul.m4145
-rw-r--r--libgfortran/m4/matmull.m4157
-rw-r--r--libgfortran/m4/maxloc0.m454
-rw-r--r--libgfortran/m4/maxloc1.m450
-rw-r--r--libgfortran/m4/maxval.m439
-rw-r--r--libgfortran/m4/minloc0.m454
-rw-r--r--libgfortran/m4/minloc1.m450
-rw-r--r--libgfortran/m4/minval.m439
-rw-r--r--libgfortran/m4/mtype.m45
-rw-r--r--libgfortran/m4/nearest.m439
-rw-r--r--libgfortran/m4/product.m437
-rw-r--r--libgfortran/m4/reshape.m4232
-rw-r--r--libgfortran/m4/set_exponent.m431
-rw-r--r--libgfortran/m4/shape.m448
-rw-r--r--libgfortran/m4/specific.m416
-rw-r--r--libgfortran/m4/specific2.m416
-rw-r--r--libgfortran/m4/sum.m436
-rw-r--r--libgfortran/m4/transpose.m475
-rw-r--r--libgfortran/m4/types.m44
-rw-r--r--libgfortran/runtime/environ.c678
-rw-r--r--libgfortran/runtime/error.c538
-rw-r--r--libgfortran/runtime/in_pack_generic.c123
-rw-r--r--libgfortran/runtime/in_unpack_generic.c120
-rw-r--r--libgfortran/runtime/main.c115
-rw-r--r--libgfortran/runtime/memory.c312
-rw-r--r--libgfortran/runtime/pause.c71
-rw-r--r--libgfortran/runtime/select.c125
-rw-r--r--libgfortran/runtime/stop.c56
-rw-r--r--libgfortran/runtime/string.c120
-rw-r--r--libiberty/ChangeLog34
-rw-r--r--libiberty/config.in3
-rwxr-xr-xlibiberty/configure170
-rw-r--r--libiberty/configure.ac36
-rw-r--r--libiberty/hashtab.c251
-rw-r--r--libiberty/mkstemps.c6
-rw-r--r--libiberty/strerror.c6
-rw-r--r--libjava/ChangeLog1934
-rw-r--r--libjava/Makefile.am54
-rw-r--r--libjava/Makefile.in111
-rw-r--r--libjava/boehm.cc152
-rw-r--r--libjava/defineclass.cc73
-rw-r--r--libjava/gcj/Makefile.in6
-rw-r--r--libjava/gcj/cni.h12
-rw-r--r--libjava/gcj/field.h13
-rw-r--r--libjava/gcj/javaprims.h16
-rw-r--r--libjava/gnu/classpath/ServiceFactory.java572
-rw-r--r--libjava/gnu/classpath/ServiceProviderLoadingAction.java149
-rw-r--r--libjava/gnu/gcj/natCore.cc3
-rw-r--r--libjava/gnu/gcj/runtime/SharedLibHelper.java87
-rw-r--r--libjava/gnu/gcj/runtime/natSharedLibLoader.cc7
-rw-r--r--libjava/gnu/gcj/util/Debug.java225
-rw-r--r--libjava/gnu/gcj/util/natDebug.cc118
-rw-r--r--libjava/gnu/java/awt/BitwiseXORComposite.java2
-rw-r--r--libjava/gnu/java/awt/Buffers.java41
-rw-r--r--libjava/gnu/java/awt/peer/ClasspathFontPeer.java35
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java199
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GtkFontPeer.java18
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GtkMenuItemPeer.java4
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GtkMenuPeer.java5
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GtkPanelPeer.java1
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java4
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GtkToolkit.java8
-rw-r--r--libjava/gnu/java/beans/BeanInfoEmbryo.java15
-rw-r--r--libjava/gnu/java/beans/info/ComponentBeanInfo.java5
-rw-r--r--libjava/gnu/java/io/Base64InputStream.java3
-rw-r--r--libjava/gnu/java/net/natPlainSocketImplPosix.cc2
-rw-r--r--libjava/gnu/java/nio/FileLockImpl.java16
-rw-r--r--libjava/gnu/java/nio/SocketChannelImpl.java13
-rw-r--r--libjava/gnu/java/nio/channels/FileChannelImpl.java139
-rw-r--r--libjava/gnu/java/nio/charset/UTF_16Decoder.java18
-rw-r--r--libjava/gnu/java/security/der/DERReader.java8
-rw-r--r--libjava/gnu/java/security/der/DERWriter.java9
-rw-r--r--libjava/gnu/java/security/provider/DSAKeyPairGenerator.java10
-rw-r--r--libjava/gnu/java/security/provider/DSAParameters.java1
-rw-r--r--libjava/gnu/java/text/AttributedFormatBuffer.java247
-rw-r--r--libjava/gnu/java/text/CharacterBreakIterator.java2
-rw-r--r--libjava/gnu/java/text/FormatBuffer.java136
-rw-r--r--libjava/gnu/java/text/FormatCharacterIterator.java534
-rw-r--r--libjava/gnu/java/text/LineBreakIterator.java1
-rw-r--r--libjava/gnu/java/text/SentenceBreakIterator.java1
-rw-r--r--libjava/gnu/java/text/StringFormatBuffer.java121
-rw-r--r--libjava/gnu/java/text/WordBreakIterator.java1
-rw-r--r--libjava/gnu/java/util/DoubleEnumeration.java1
-rw-r--r--libjava/gnu/java/util/prefs/NodeReader.java8
-rw-r--r--libjava/gnu/javax/rmi/CORBA/DelegateFactory.java32
-rw-r--r--libjava/include/Makefile.in6
-rw-r--r--libjava/include/execution.h140
-rw-r--r--libjava/include/java-interp.h50
-rw-r--r--libjava/include/jni.h22
-rw-r--r--libjava/include/jvm.h46
-rw-r--r--libjava/interpret.cc598
-rw-r--r--libjava/java/applet/Applet.java40
-rw-r--r--libjava/java/awt/AWTPermission.java2
-rw-r--r--libjava/java/awt/Color.java13
-rw-r--r--libjava/java/awt/ColorPaintContext.java114
-rw-r--r--libjava/java/awt/Component.java9
-rw-r--r--libjava/java/awt/ComponentOrientation.java8
-rw-r--r--libjava/java/awt/Dialog.java12
-rw-r--r--libjava/java/awt/FileDialog.java3
-rw-r--r--libjava/java/awt/Font.java39
-rw-r--r--libjava/java/awt/FontMetrics.java23
-rw-r--r--libjava/java/awt/Graphics.java4
-rw-r--r--libjava/java/awt/Menu.java7
-rw-r--r--libjava/java/awt/MenuItem.java5
-rw-r--r--libjava/java/awt/Polygon.java2
-rw-r--r--libjava/java/awt/PopupMenu.java4
-rw-r--r--libjava/java/awt/SystemColor.java6
-rw-r--r--libjava/java/awt/TextComponent.java7
-rw-r--r--libjava/java/awt/datatransfer/DataFlavor.java10
-rw-r--r--libjava/java/awt/event/MouseEvent.java6
-rw-r--r--libjava/java/awt/image/ColorModel.java8
-rw-r--r--libjava/java/awt/image/ComponentColorModel.java57
-rw-r--r--libjava/java/awt/image/ComponentSampleModel.java2
-rw-r--r--libjava/java/awt/image/DataBufferDouble.java174
-rw-r--r--libjava/java/awt/image/DataBufferFloat.java172
-rw-r--r--libjava/java/awt/image/DataBufferShort.java130
-rw-r--r--libjava/java/awt/image/PixelInterleavedSampleModel.java98
-rw-r--r--libjava/java/awt/image/Raster.java21
-rw-r--r--libjava/java/awt/image/SampleModel.java6
-rw-r--r--libjava/java/awt/image/SinglePixelPackedSampleModel.java158
-rw-r--r--libjava/java/awt/peer/MenuPeer.java1
-rw-r--r--libjava/java/beans/Introspector.java6
-rw-r--r--libjava/java/beans/PropertyEditor.java2
-rw-r--r--libjava/java/beans/PropertyEditorManager.java21
-rw-r--r--libjava/java/beans/beancontext/BeanContextServiceProvider.java8
-rw-r--r--libjava/java/io/BufferedReader.java11
-rw-r--r--libjava/java/io/BufferedWriter.java87
-rw-r--r--libjava/java/io/ByteArrayInputStream.java26
-rw-r--r--libjava/java/io/CharArrayWriter.java4
-rw-r--r--libjava/java/io/DataInput.java8
-rw-r--r--libjava/java/io/DataInputStream.java6
-rw-r--r--libjava/java/io/File.java65
-rw-r--r--libjava/java/io/FileDescriptor.java10
-rw-r--r--libjava/java/io/FileOutputStream.java22
-rw-r--r--libjava/java/io/FilePermission.java1
-rw-r--r--libjava/java/io/FilterInputStream.java18
-rw-r--r--libjava/java/io/InputStream.java4
-rw-r--r--libjava/java/io/InputStreamReader.java29
-rw-r--r--libjava/java/io/ObjectInputStream.java110
-rw-r--r--libjava/java/io/ObjectOutputStream.java70
-rw-r--r--libjava/java/io/ObjectStreamClass.java22
-rw-r--r--libjava/java/io/PipedInputStream.java2
-rw-r--r--libjava/java/io/PipedReader.java2
-rw-r--r--libjava/java/io/PushbackInputStream.java2
-rw-r--r--libjava/java/io/PushbackReader.java27
-rw-r--r--libjava/java/io/RandomAccessFile.java8
-rw-r--r--libjava/java/io/SerializablePermission.java4
-rw-r--r--libjava/java/io/StreamTokenizer.java56
-rw-r--r--libjava/java/io/StringWriter.java2
-rw-r--r--libjava/java/io/WriteAbortedException.java2
-rw-r--r--libjava/java/io/Writer.java6
-rw-r--r--libjava/java/io/natObjectInputStream.cc34
-rw-r--r--libjava/java/lang/Byte.java2
-rw-r--r--libjava/java/lang/CharSequence.java2
-rw-r--r--libjava/java/lang/Class.h93
-rw-r--r--libjava/java/lang/ClassLoader.java43
-rw-r--r--libjava/java/lang/Compiler.java15
-rw-r--r--libjava/java/lang/Double.java10
-rw-r--r--libjava/java/lang/Float.java11
-rw-r--r--libjava/java/lang/Integer.java8
-rw-r--r--libjava/java/lang/Long.java8
-rw-r--r--libjava/java/lang/Math.java2
-rw-r--r--libjava/java/lang/Number.java2
-rw-r--r--libjava/java/lang/Package.java5
-rw-r--r--libjava/java/lang/Runtime.java25
-rw-r--r--libjava/java/lang/RuntimePermission.java4
-rw-r--r--libjava/java/lang/SecurityManager.java50
-rw-r--r--libjava/java/lang/Short.java6
-rw-r--r--libjava/java/lang/StringBuffer.java2
-rw-r--r--libjava/java/lang/System.java89
-rw-r--r--libjava/java/lang/ThreadGroup.java12
-rw-r--r--libjava/java/lang/Throwable.java10
-rw-r--r--libjava/java/lang/VMClassLoader.java47
-rw-r--r--libjava/java/lang/VMCompiler.java259
-rw-r--r--libjava/java/lang/VMSecurityManager.java3
-rw-r--r--libjava/java/lang/natClass.cc1127
-rw-r--r--libjava/java/lang/natClassLoader.cc174
-rw-r--r--libjava/java/lang/natObject.cc2
-rw-r--r--libjava/java/lang/natString.cc38
-rw-r--r--libjava/java/lang/natSystem.cc13
-rw-r--r--libjava/java/lang/natVMClassLoader.cc114
-rw-r--r--libjava/java/lang/reflect/InvocationHandler.java43
-rw-r--r--libjava/java/lang/reflect/Proxy.java53
-rw-r--r--libjava/java/lang/reflect/natField.cc4
-rw-r--r--libjava/java/lang/reflect/natMethod.cc31
-rw-r--r--libjava/java/math/BigDecimal.java1
-rw-r--r--libjava/java/net/Authenticator.java92
-rw-r--r--libjava/java/net/BindException.java1
-rw-r--r--libjava/java/net/ConnectException.java2
-rw-r--r--libjava/java/net/ContentHandler.java39
-rw-r--r--libjava/java/net/ContentHandlerFactory.java11
-rw-r--r--libjava/java/net/DatagramPacket.java39
-rw-r--r--libjava/java/net/DatagramSocket.java266
-rw-r--r--libjava/java/net/DatagramSocketImpl.java55
-rw-r--r--libjava/java/net/DatagramSocketImplFactory.java7
-rw-r--r--libjava/java/net/FileNameMap.java7
-rw-r--r--libjava/java/net/HttpURLConnection.java169
-rw-r--r--libjava/java/net/Inet4Address.java139
-rw-r--r--libjava/java/net/Inet6Address.java168
-rw-r--r--libjava/java/net/InetAddress.java151
-rw-r--r--libjava/java/net/InetSocketAddress.java70
-rw-r--r--libjava/java/net/JarURLConnection.java51
-rw-r--r--libjava/java/net/MalformedURLException.java1
-rw-r--r--libjava/java/net/MulticastSocket.java125
-rw-r--r--libjava/java/net/NetPermission.java23
-rw-r--r--libjava/java/net/NetworkInterface.java146
-rw-r--r--libjava/java/net/NoRouteToHostException.java2
-rw-r--r--libjava/java/net/PasswordAuthentication.java15
-rw-r--r--libjava/java/net/PortUnreachableException.java2
-rw-r--r--libjava/java/net/ProtocolException.java1
-rw-r--r--libjava/java/net/ServerSocket.java239
-rw-r--r--libjava/java/net/Socket.java452
-rw-r--r--libjava/java/net/SocketAddress.java5
-rw-r--r--libjava/java/net/SocketException.java1
-rw-r--r--libjava/java/net/SocketImpl.java55
-rw-r--r--libjava/java/net/SocketImplFactory.java7
-rw-r--r--libjava/java/net/SocketOptions.java12
-rw-r--r--libjava/java/net/SocketPermission.java209
-rw-r--r--libjava/java/net/SocketTimeoutException.java1
-rw-r--r--libjava/java/net/URI.java317
-rw-r--r--libjava/java/net/URISyntaxException.java5
-rw-r--r--libjava/java/net/URL.java224
-rw-r--r--libjava/java/net/URLClassLoader.java304
-rw-r--r--libjava/java/net/URLConnection.java162
-rw-r--r--libjava/java/net/URLDecoder.java24
-rw-r--r--libjava/java/net/URLEncoder.java122
-rw-r--r--libjava/java/net/URLStreamHandler.java273
-rw-r--r--libjava/java/net/URLStreamHandlerFactory.java12
-rw-r--r--libjava/java/net/UnknownHostException.java1
-rw-r--r--libjava/java/net/UnknownServiceException.java1
-rw-r--r--libjava/java/nio/Buffer.java40
-rw-r--r--libjava/java/nio/ByteBuffer.java41
-rw-r--r--libjava/java/nio/ByteBufferImpl.java56
-rw-r--r--libjava/java/nio/CharBuffer.java43
-rw-r--r--libjava/java/nio/CharBufferImpl.java12
-rw-r--r--libjava/java/nio/DirectByteBufferImpl.java59
-rw-r--r--libjava/java/nio/DoubleBuffer.java43
-rw-r--r--libjava/java/nio/DoubleBufferImpl.java10
-rw-r--r--libjava/java/nio/DoubleViewBufferImpl.java2
-rw-r--r--libjava/java/nio/FloatBuffer.java43
-rw-r--r--libjava/java/nio/FloatBufferImpl.java10
-rw-r--r--libjava/java/nio/FloatViewBufferImpl.java2
-rw-r--r--libjava/java/nio/IntBuffer.java43
-rw-r--r--libjava/java/nio/IntBufferImpl.java10
-rw-r--r--libjava/java/nio/IntViewBufferImpl.java2
-rw-r--r--libjava/java/nio/LongBuffer.java43
-rw-r--r--libjava/java/nio/LongBufferImpl.java10
-rw-r--r--libjava/java/nio/LongViewBufferImpl.java2
-rw-r--r--libjava/java/nio/MappedByteBufferImpl.java54
-rw-r--r--libjava/java/nio/ShortBuffer.java43
-rw-r--r--libjava/java/nio/ShortBufferImpl.java10
-rw-r--r--libjava/java/nio/ShortViewBufferImpl.java2
-rw-r--r--libjava/java/nio/channels/AlreadyConnectedException.java2
-rw-r--r--libjava/java/nio/channels/AsynchronousCloseException.java3
-rw-r--r--libjava/java/nio/channels/ByteChannel.java6
-rw-r--r--libjava/java/nio/channels/CancelledKeyException.java3
-rw-r--r--libjava/java/nio/channels/Channel.java3
-rw-r--r--libjava/java/nio/channels/Channels.java37
-rw-r--r--libjava/java/nio/channels/ClosedByInterruptException.java3
-rw-r--r--libjava/java/nio/channels/ClosedChannelException.java3
-rw-r--r--libjava/java/nio/channels/ClosedSelectorException.java3
-rw-r--r--libjava/java/nio/channels/ConnectionPendingException.java3
-rw-r--r--libjava/java/nio/channels/DatagramChannel.java77
-rw-r--r--libjava/java/nio/channels/FileChannel.java83
-rw-r--r--libjava/java/nio/channels/FileLock.java38
-rw-r--r--libjava/java/nio/channels/FileLockInterruptionException.java3
-rw-r--r--libjava/java/nio/channels/GatheringByteChannel.java14
-rw-r--r--libjava/java/nio/channels/IllegalBlockingModeException.java3
-rw-r--r--libjava/java/nio/channels/IllegalSelectorException.java3
-rw-r--r--libjava/java/nio/channels/InterruptibleChannel.java3
-rw-r--r--libjava/java/nio/channels/NoConnectionPendingException.java3
-rw-r--r--libjava/java/nio/channels/NonReadableChannelException.java3
-rw-r--r--libjava/java/nio/channels/NonWritableChannelException.java3
-rw-r--r--libjava/java/nio/channels/NotYetBoundException.java3
-rw-r--r--libjava/java/nio/channels/NotYetConnectedException.java3
-rw-r--r--libjava/java/nio/channels/OverlappingFileLockException.java3
-rw-r--r--libjava/java/nio/channels/Pipe.java27
-rw-r--r--libjava/java/nio/channels/ReadableByteChannel.java11
-rw-r--r--libjava/java/nio/channels/ScatteringByteChannel.java12
-rw-r--r--libjava/java/nio/channels/SelectableChannel.java46
-rw-r--r--libjava/java/nio/channels/SelectionKey.java84
-rw-r--r--libjava/java/nio/channels/Selector.java57
-rw-r--r--libjava/java/nio/channels/ServerSocketChannel.java33
-rw-r--r--libjava/java/nio/channels/SocketChannel.java94
-rw-r--r--libjava/java/nio/channels/UnresolvedAddressException.java3
-rw-r--r--libjava/java/nio/channels/UnsupportedAddressTypeException.java3
-rw-r--r--libjava/java/nio/channels/WritableByteChannel.java8
-rw-r--r--libjava/java/nio/channels/spi/AbstractInterruptibleChannel.java38
-rw-r--r--libjava/java/nio/channels/spi/AbstractSelectableChannel.java126
-rw-r--r--libjava/java/nio/channels/spi/AbstractSelectionKey.java20
-rw-r--r--libjava/java/nio/channels/spi/AbstractSelector.java61
-rw-r--r--libjava/java/nio/channels/spi/SelectorProvider.java98
-rw-r--r--libjava/java/nio/charset/IllegalCharsetNameException.java6
-rw-r--r--libjava/java/nio/charset/MalformedInputException.java8
-rw-r--r--libjava/java/nio/charset/spi/CharsetProvider.java3
-rw-r--r--libjava/java/nio/natDirectByteBufferImpl.cc6
-rw-r--r--libjava/java/rmi/MarshalledObject.java5
-rw-r--r--libjava/java/rmi/Naming.java10
-rw-r--r--libjava/java/rmi/RemoteException.java2
-rw-r--r--libjava/java/rmi/activation/ActivationException.java2
-rw-r--r--libjava/java/rmi/server/ServerCloneException.java2
-rw-r--r--libjava/java/security/AccessController.java10
-rw-r--r--libjava/java/security/AlgorithmParameterGenerator.java2
-rw-r--r--libjava/java/security/AlgorithmParameters.java2
-rw-r--r--libjava/java/security/BasicPermission.java22
-rw-r--r--libjava/java/security/CodeSource.java23
-rw-r--r--libjava/java/security/Identity.java2
-rw-r--r--libjava/java/security/IdentityScope.java4
-rw-r--r--libjava/java/security/KeyPairGenerator.java69
-rw-r--r--libjava/java/security/KeyStore.java2
-rw-r--r--libjava/java/security/SecureRandom.java9
-rw-r--r--libjava/java/security/Security.java8
-rw-r--r--libjava/java/security/Signature.java30
-rw-r--r--libjava/java/security/SignatureSpi.java2
-rw-r--r--libjava/java/security/SignedObject.java2
-rw-r--r--libjava/java/security/UnresolvedPermission.java1
-rw-r--r--libjava/java/security/interfaces/DSAKeyPairGenerator.java4
-rw-r--r--libjava/java/security/interfaces/DSAPrivateKey.java4
-rw-r--r--libjava/java/security/interfaces/DSAPublicKey.java4
-rw-r--r--libjava/java/security/interfaces/RSAPrivateKey.java4
-rw-r--r--libjava/java/security/interfaces/RSAPublicKey.java4
-rw-r--r--libjava/java/security/spec/DSAParameterSpec.java4
-rw-r--r--libjava/java/security/spec/DSAPrivateKeySpec.java4
-rw-r--r--libjava/java/security/spec/DSAPublicKeySpec.java4
-rw-r--r--libjava/java/sql/Array.java8
-rw-r--r--libjava/java/sql/DatabaseMetaData.java360
-rw-r--r--libjava/java/sql/DriverManager.java4
-rw-r--r--libjava/java/sql/ResultSet.java14
-rw-r--r--libjava/java/text/AttributedCharacterIterator.java2
-rw-r--r--libjava/java/text/AttributedString.java32
-rw-r--r--libjava/java/text/AttributedStringIterator.java102
-rw-r--r--libjava/java/text/ChoiceFormat.java8
-rw-r--r--libjava/java/text/CollationElementIterator.java4
-rw-r--r--libjava/java/text/CollationKey.java8
-rw-r--r--libjava/java/text/Collator.java10
-rw-r--r--libjava/java/text/DateFormat.java6
-rw-r--r--libjava/java/text/DateFormatSymbols.java30
-rw-r--r--libjava/java/text/DecimalFormat.java370
-rw-r--r--libjava/java/text/DecimalFormatSymbols.java12
-rw-r--r--libjava/java/text/FieldPosition.java4
-rw-r--r--libjava/java/text/Format.java7
-rw-r--r--libjava/java/text/MessageFormat.java195
-rw-r--r--libjava/java/text/NumberFormat.java2
-rw-r--r--libjava/java/text/ParsePosition.java6
-rw-r--r--libjava/java/text/RuleBasedCollator.java28
-rw-r--r--libjava/java/text/SimpleDateFormat.java270
-rw-r--r--libjava/java/text/StringCharacterIterator.java8
-rw-r--r--libjava/java/util/ArrayList.java6
-rw-r--r--libjava/java/util/Arrays.java4
-rw-r--r--libjava/java/util/Calendar.java37
-rw-r--r--libjava/java/util/Collections.java2
-rw-r--r--libjava/java/util/Currency.java4
-rw-r--r--libjava/java/util/Date.java1
-rw-r--r--libjava/java/util/HashMap.java17
-rw-r--r--libjava/java/util/HashSet.java4
-rw-r--r--libjava/java/util/Hashtable.java4
-rw-r--r--libjava/java/util/LinkedList.java8
-rw-r--r--libjava/java/util/Map.java4
-rw-r--r--libjava/java/util/Properties.java19
-rw-r--r--libjava/java/util/PropertyPermission.java12
-rw-r--r--libjava/java/util/PropertyResourceBundle.java2
-rw-r--r--libjava/java/util/ResourceBundle.java28
-rw-r--r--libjava/java/util/SimpleTimeZone.java233
-rw-r--r--libjava/java/util/StringTokenizer.java4
-rw-r--r--libjava/java/util/TimeZone.java5
-rw-r--r--libjava/java/util/TreeMap.java8
-rw-r--r--libjava/java/util/TreeSet.java4
-rw-r--r--libjava/java/util/Vector.java4
-rw-r--r--libjava/java/util/WeakHashMap.java4
-rw-r--r--libjava/java/util/jar/Attributes.java27
-rw-r--r--libjava/java/util/jar/JarFile.java10
-rw-r--r--libjava/java/util/jar/JarInputStream.java4
-rw-r--r--libjava/java/util/jar/JarOutputStream.java4
-rw-r--r--libjava/java/util/jar/Manifest.java7
-rw-r--r--libjava/java/util/logging/ConsoleHandler.java2
-rw-r--r--libjava/java/util/logging/FileHandler.java4
-rw-r--r--libjava/java/util/logging/Formatter.java4
-rw-r--r--libjava/java/util/logging/Handler.java3
-rw-r--r--libjava/java/util/logging/Level.java2
-rw-r--r--libjava/java/util/logging/LogManager.java10
-rw-r--r--libjava/java/util/logging/Logger.java6
-rw-r--r--libjava/java/util/logging/MemoryHandler.java11
-rw-r--r--libjava/java/util/logging/SimpleFormatter.java4
-rw-r--r--libjava/java/util/logging/SocketHandler.java2
-rw-r--r--libjava/java/util/logging/XMLFormatter.java5
-rw-r--r--libjava/java/util/prefs/AbstractPreferences.java7
-rw-r--r--libjava/java/util/prefs/BackingStoreException.java4
-rw-r--r--libjava/java/util/prefs/InvalidPreferencesFormatException.java4
-rw-r--r--libjava/java/util/prefs/Preferences.java7
-rw-r--r--libjava/java/util/regex/Matcher.java1
-rw-r--r--libjava/java/util/regex/Pattern.java8
-rw-r--r--libjava/java/util/zip/ZipEntry.java12
-rw-r--r--libjava/javax/accessibility/AccessibleText.java5
-rw-r--r--libjava/javax/imageio/ImageReader.java46
-rw-r--r--libjava/javax/imageio/ImageTranscoder.java46
-rw-r--r--libjava/javax/imageio/ImageWriter.java47
-rw-r--r--libjava/javax/imageio/package.html46
-rw-r--r--libjava/javax/imageio/spi/IIOServiceProvider.java163
-rw-r--r--libjava/javax/imageio/spi/ImageInputStreamSpi.java144
-rw-r--r--libjava/javax/imageio/spi/ImageOutputStreamSpi.java143
-rw-r--r--libjava/javax/imageio/spi/ImageReaderWriterSpi.java425
-rw-r--r--libjava/javax/imageio/spi/ImageTranscoderSpi.java84
-rw-r--r--libjava/javax/imageio/spi/RegisterableService.java83
-rw-r--r--libjava/javax/imageio/spi/ServiceRegistry.java948
-rw-r--r--libjava/javax/imageio/spi/package.html46
-rw-r--r--libjava/javax/imageio/stream/IIOByteBuffer.java94
-rw-r--r--libjava/javax/imageio/stream/ImageInputStream.java651
-rw-r--r--libjava/javax/imageio/stream/ImageOutputStream.java58
-rw-r--r--libjava/javax/imageio/stream/package.html46
-rw-r--r--libjava/javax/naming/AuthenticationException.java3
-rw-r--r--libjava/javax/naming/AuthenticationNotSupportedException.java3
-rw-r--r--libjava/javax/naming/CannotProceedException.java3
-rw-r--r--libjava/javax/naming/CommunicationException.java3
-rw-r--r--libjava/javax/naming/CompoundName.java6
-rw-r--r--libjava/javax/naming/ConfigurationException.java3
-rw-r--r--libjava/javax/naming/ContextNotEmptyException.java3
-rw-r--r--libjava/javax/naming/InitialContext.java5
-rw-r--r--libjava/javax/naming/InsufficientResourcesException.java3
-rw-r--r--libjava/javax/naming/InterruptedNamingException.java3
-rw-r--r--libjava/javax/naming/LimitExceededException.java3
-rw-r--r--libjava/javax/naming/LinkException.java3
-rw-r--r--libjava/javax/naming/LinkLoopException.java3
-rw-r--r--libjava/javax/naming/LinkRef.java3
-rw-r--r--libjava/javax/naming/MalformedLinkException.java3
-rw-r--r--libjava/javax/naming/Name.java4
-rw-r--r--libjava/javax/naming/NameAlreadyBoundException.java3
-rw-r--r--libjava/javax/naming/NameNotFoundException.java3
-rw-r--r--libjava/javax/naming/NamingException.java4
-rw-r--r--libjava/javax/naming/NamingSecurityException.java3
-rw-r--r--libjava/javax/naming/NoInitialContextException.java3
-rw-r--r--libjava/javax/naming/NoPermissionException.java3
-rw-r--r--libjava/javax/naming/NotContextException.java3
-rw-r--r--libjava/javax/naming/PartialResultException.java3
-rw-r--r--libjava/javax/naming/ReferralException.java3
-rw-r--r--libjava/javax/naming/ServiceUnavailableException.java3
-rw-r--r--libjava/javax/naming/SizeLimitExceededException.java3
-rw-r--r--libjava/javax/naming/TimeLimitExceededException.java3
-rw-r--r--libjava/javax/naming/directory/Attribute.java5
-rw-r--r--libjava/javax/naming/directory/Attributes.java5
-rw-r--r--libjava/javax/naming/directory/SearchControls.java4
-rw-r--r--libjava/javax/naming/directory/SearchResult.java3
-rw-r--r--libjava/javax/naming/event/NamingExceptionEvent.java5
-rw-r--r--libjava/javax/naming/spi/DirStateFactory.java2
-rw-r--r--libjava/javax/naming/spi/ResolveResult.java6
-rw-r--r--libjava/javax/print/attribute/EnumSyntax.java2
-rw-r--r--libjava/javax/print/attribute/HashAttributeSet.java2
-rw-r--r--libjava/javax/print/attribute/ResolutionSyntax.java4
-rw-r--r--libjava/javax/print/attribute/SetOfIntegerSyntax.java4
-rw-r--r--libjava/javax/print/attribute/TextSyntax.java20
-rw-r--r--libjava/javax/rmi/CORBA/PortableRemoteObjectDelegate.java6
-rw-r--r--libjava/javax/rmi/CORBA/Stub.java10
-rw-r--r--libjava/javax/rmi/CORBA/Util.java14
-rw-r--r--libjava/javax/rmi/CORBA/UtilDelegate.java3
-rw-r--r--libjava/javax/rmi/CORBA/ValueHandler.java6
-rw-r--r--libjava/javax/rmi/PortableRemoteObject.java11
-rw-r--r--libjava/javax/security/auth/x500/X500Principal.java11
-rw-r--r--libjava/javax/swing/AbstractButton.java10
-rw-r--r--libjava/javax/swing/ActionMap.java1
-rw-r--r--libjava/javax/swing/DefaultBoundedRangeModel.java2
-rw-r--r--libjava/javax/swing/DefaultButtonModel.java6
-rw-r--r--libjava/javax/swing/DefaultListModel.java5
-rw-r--r--libjava/javax/swing/DefaultSingleSelectionModel.java2
-rw-r--r--libjava/javax/swing/ImageIcon.java12
-rw-r--r--libjava/javax/swing/JCheckBoxMenuItem.java323
-rw-r--r--libjava/javax/swing/JComboBox.java5
-rw-r--r--libjava/javax/swing/JComponent.java11
-rw-r--r--libjava/javax/swing/JDialog.java60
-rw-r--r--libjava/javax/swing/JFrame.java45
-rw-r--r--libjava/javax/swing/JInternalFrame.java5
-rw-r--r--libjava/javax/swing/JLabel.java2
-rw-r--r--libjava/javax/swing/JLayeredPane.java3
-rw-r--r--libjava/javax/swing/JList.java2
-rw-r--r--libjava/javax/swing/JMenuBar.java6
-rw-r--r--libjava/javax/swing/JMenuItem.java672
-rw-r--r--libjava/javax/swing/JOptionPane.java4
-rw-r--r--libjava/javax/swing/JProgressBar.java17
-rw-r--r--libjava/javax/swing/JRadioButtonMenuItem.java284
-rw-r--r--libjava/javax/swing/JRootPane.java6
-rw-r--r--libjava/javax/swing/JScrollBar.java28
-rw-r--r--libjava/javax/swing/JScrollPane.java5
-rw-r--r--libjava/javax/swing/JSeparator.java2
-rw-r--r--libjava/javax/swing/JSlider.java24
-rw-r--r--libjava/javax/swing/JTabbedPane.java1458
-rw-r--r--libjava/javax/swing/JTable.java12
-rw-r--r--libjava/javax/swing/JTextField.java5
-rw-r--r--libjava/javax/swing/JToggleButton.java4
-rw-r--r--libjava/javax/swing/JToolBar.java4
-rw-r--r--libjava/javax/swing/JToolTip.java3
-rw-r--r--libjava/javax/swing/JTree.java17
-rw-r--r--libjava/javax/swing/JViewport.java9
-rw-r--r--libjava/javax/swing/JWindow.java4
-rw-r--r--libjava/javax/swing/KeyStroke.java3
-rw-r--r--libjava/javax/swing/ListModel.java2
-rw-r--r--libjava/javax/swing/LookAndFeel.java3
-rw-r--r--libjava/javax/swing/Popup.java4
-rw-r--r--libjava/javax/swing/SwingUtilities.java8
-rw-r--r--libjava/javax/swing/Timer.java4
-rw-r--r--libjava/javax/swing/ToolTipManager.java1
-rw-r--r--libjava/javax/swing/UIDefaults.java11
-rw-r--r--libjava/javax/swing/border/TitledBorder.java4
-rw-r--r--libjava/javax/swing/filechooser/FileSystemView.java3
-rw-r--r--libjava/javax/swing/plaf/BorderUIResource.java24
-rw-r--r--libjava/javax/swing/plaf/ComponentUI.java34
-rw-r--r--libjava/javax/swing/plaf/basic/BasicArrowButton.java363
-rw-r--r--libjava/javax/swing/plaf/basic/BasicButtonListener.java5
-rw-r--r--libjava/javax/swing/plaf/basic/BasicButtonUI.java11
-rw-r--r--libjava/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java75
-rw-r--r--libjava/javax/swing/plaf/basic/BasicGraphicsUtils.java2
-rw-r--r--libjava/javax/swing/plaf/basic/BasicIconFactory.java4
-rw-r--r--libjava/javax/swing/plaf/basic/BasicLabelUI.java2
-rw-r--r--libjava/javax/swing/plaf/basic/BasicLookAndFeel.java12
-rw-r--r--libjava/javax/swing/plaf/basic/BasicMenuItemUI.java632
-rw-r--r--libjava/javax/swing/plaf/basic/BasicProgressBarUI.java4
-rw-r--r--libjava/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java76
-rw-r--r--libjava/javax/swing/plaf/basic/BasicRootPaneUI.java8
-rw-r--r--libjava/javax/swing/plaf/basic/BasicScrollBarUI.java3
-rw-r--r--libjava/javax/swing/plaf/basic/BasicScrollPaneUI.java2
-rw-r--r--libjava/javax/swing/plaf/basic/BasicSliderUI.java7
-rw-r--r--libjava/javax/swing/plaf/basic/BasicTabbedPaneUI.java3000
-rw-r--r--libjava/javax/swing/plaf/basic/BasicToggleButtonUI.java4
-rw-r--r--libjava/javax/swing/plaf/basic/BasicViewportUI.java27
-rw-r--r--libjava/javax/swing/table/DefaultTableCellRenderer.java3
-rw-r--r--libjava/javax/swing/table/JTableHeader.java21
-rw-r--r--libjava/javax/swing/table/TableColumn.java5
-rw-r--r--libjava/javax/swing/text/AbstractDocument.java2
-rw-r--r--libjava/javax/swing/text/DefaultCaret.java6
-rw-r--r--libjava/javax/swing/text/StyledEditorKit.java5
-rw-r--r--libjava/javax/swing/tree/DefaultTreeCellEditor.java4
-rw-r--r--libjava/javax/swing/undo/CompoundEdit.java19
-rw-r--r--libjava/javax/swing/undo/StateEdit.java60
-rw-r--r--libjava/jni.cc11
-rw-r--r--libjava/jni/classpath/jcl.c10
-rw-r--r--libjava/jni/classpath/jnilink.c4
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c40
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c75
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c2
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c37
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c3
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c82
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c21
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c7
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.c59
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c4
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c2
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c28
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c23
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.c64
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c6
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextComponentPeer.c32
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c22
-rw-r--r--libjava/jni/gtk-peer/gthread-jni.c56
-rw-r--r--libjava/libltdl/ChangeLog6
-rw-r--r--libjava/libltdl/acinclude.m42
-rw-r--r--libjava/libltdl/aclocal.m42
-rwxr-xr-xlibjava/libltdl/configure2
-rw-r--r--libjava/link.cc1654
-rw-r--r--libjava/mauve-libgcj7
-rw-r--r--libjava/prims.cc74
-rw-r--r--libjava/resolve.cc1125
-rw-r--r--libjava/testsuite/Makefile.in4
-rw-r--r--libjava/testsuite/lib/libjava.exp28
-rw-r--r--libjava/testsuite/libjava.compile/compile.exp4
-rw-r--r--libjava/testsuite/libjava.jacks/jacks.exp7
-rw-r--r--libjava/testsuite/libjava.jacks/jacks.xfail1305
-rw-r--r--libjava/testsuite/libjava.jar/jar.exp2
-rw-r--r--libjava/testsuite/libjava.jni/PR15133.c9
-rw-r--r--libjava/testsuite/libjava.jni/PR15133.java14
-rw-r--r--libjava/testsuite/libjava.jni/PR15133.out1
-rw-r--r--libjava/testsuite/libjava.jni/jni.exp45
-rw-r--r--libjava/testsuite/libjava.jni/pr11951.java4
-rw-r--r--libjava/testsuite/libjava.lang/InvokeInterface.java55
-rw-r--r--libjava/testsuite/libjava.lang/InvokeInterface.out6
-rw-r--r--libjava/testsuite/libjava.lang/MathBuiltin.java25
-rw-r--r--libjava/testsuite/libjava.mauve/xfails1
-rw-r--r--libjava/verify.cc2
-rw-r--r--libmudflap/ChangeLog957
-rw-r--r--libmudflap/Makefile.am388
-rw-r--r--libmudflap/Makefile.in918
-rw-r--r--libmudflap/acinclude.m4928
-rw-r--r--libmudflap/aclocal.m41066
-rw-r--r--libmudflap/config.h.in62
-rwxr-xr-xlibmudflap/configure3218
-rw-r--r--libmudflap/configure.in137
-rw-r--r--libmudflap/mf-heuristics.c174
-rw-r--r--libmudflap/mf-hooks1.c478
-rw-r--r--libmudflap/mf-hooks2.c1767
-rw-r--r--libmudflap/mf-hooks3.c573
-rw-r--r--libmudflap/mf-impl.h389
-rw-r--r--libmudflap/mf-runtime.c2431
-rw-r--r--libmudflap/mf-runtime.h.in191
-rw-r--r--libmudflap/stamp-h.in0
-rw-r--r--libmudflap/testsuite/Makefile.am18
-rw-r--r--libmudflap/testsuite/Makefile.in249
-rw-r--r--libmudflap/testsuite/config/default.exp2
-rw-r--r--libmudflap/testsuite/lib/libmudflap.exp237
-rw-r--r--libmudflap/testsuite/lib/mfdg.exp377
-rw-r--r--libmudflap/testsuite/libmudflap.c++/c++frags.exp16
-rw-r--r--libmudflap/testsuite/libmudflap.c++/fail24-frag.cxx16
-rw-r--r--libmudflap/testsuite/libmudflap.c++/pass27-frag.cxx12
-rw-r--r--libmudflap/testsuite/libmudflap.c++/pass28-frag.cxx20
-rw-r--r--libmudflap/testsuite/libmudflap.c++/pass31-frag.cxx12
-rw-r--r--libmudflap/testsuite/libmudflap.c++/pass41-frag.cxx10
-rw-r--r--libmudflap/testsuite/libmudflap.c/cfrags.exp15
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail1-frag.c13
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail10-frag.c16
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail11-frag.c19
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail12-frag.c19
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail13-frag.c26
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail14-frag.c29
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail15-frag.c27
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail16-frag.c26
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail17-frag.c18
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail18-frag.c16
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail19-frag.c18
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail2-frag.c13
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail20-frag.c13
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail21-frag.c18
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail22-frag.c17
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail23-frag.c16
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail25-frag.c18
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail26-frag.c24
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail27-frag.c24
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail28-frag.c18
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail29-frag.c17
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail3-frag.c13
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail30-frag.c18
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail31-frag.c22
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail4-frag.c13
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail5-frag.c14
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail6-frag.c17
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail7-frag.c17
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail8-frag.c19
-rw-r--r--libmudflap/testsuite/libmudflap.c/fail9-frag.c21
-rw-r--r--libmudflap/testsuite/libmudflap.c/hook-allocstuff.c16
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass-stratcliff.c319
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass1-frag.c9
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass10-frag.c12
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass11-frag.c15
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass12-frag.c15
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass13-frag.c17
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass14-frag.c20
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass15-frag.c23
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass16-frag.c22
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass17-frag.c9
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass18-frag.c27
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass19-frag.c11
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass2-frag.c9
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass20-frag.c13
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass21-frag.c15
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass22-frag.c23
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass23-frag.c29
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass24-frag.c18
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass25-frag.c15
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass26-frag.c52
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass29-frag.c15
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass3-frag.c9
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass30-frag.c12
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass32-frag.c18
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass33-frag.c17
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass34-frag.c18
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass35-frag.c14
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass36-frag.c15
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass38-frag.c9
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass4-frag.c9
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass42-frag.c17
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass43-frag.c11
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass44-frag.c14
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass45-frag.c31
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass46-frag.c18
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass5-frag.c11
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass6-frag.c14
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass7-frag.c13
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass8-frag.c16
-rw-r--r--libmudflap/testsuite/libmudflap.c/pass9-frag.c16
-rw-r--r--libmudflap/testsuite/libmudflap.cth/cthfrags.exp23
-rw-r--r--libmudflap/testsuite/libmudflap.cth/pass37-frag.c58
-rw-r--r--libmudflap/testsuite/libmudflap.cth/pass39-frag.c57
-rw-r--r--libmudflap/testsuite/libmudflap.cth/pass40-frag.c59
-rw-r--r--libobjc/ChangeLog21
-rw-r--r--libobjc/Makefile.in2
-rw-r--r--libobjc/archive.c4
-rwxr-xr-xlibobjc/configure97
-rw-r--r--libobjc/configure.ac14
-rw-r--r--libstdc++-v3/ChangeLog454
-rw-r--r--libstdc++-v3/Makefile.in2
-rw-r--r--libstdc++-v3/acconfig.h3
-rw-r--r--libstdc++-v3/acinclude.m42
-rw-r--r--libstdc++-v3/config.h.in3
-rw-r--r--libstdc++-v3/config/linker-map.gnu13
-rw-r--r--libstdc++-v3/config/locale/generic/monetary_members.cc14
-rw-r--r--libstdc++-v3/config/locale/generic/numeric_members.cc21
-rw-r--r--libstdc++-v3/config/locale/gnu/ctype_members.cc12
-rw-r--r--libstdc++-v3/config/locale/gnu/monetary_members.cc14
-rw-r--r--libstdc++-v3/config/locale/gnu/numeric_members.cc35
-rwxr-xr-xlibstdc++-v3/configure345
-rw-r--r--libstdc++-v3/crossconfig.m448
-rw-r--r--libstdc++-v3/docs/html/17_intro/TODO14
-rw-r--r--libstdc++-v3/docs/html/abi.html880
-rw-r--r--libstdc++-v3/docs/html/configopts.html2
-rw-r--r--libstdc++-v3/docs/html/documentation.html2
-rw-r--r--libstdc++-v3/docs/html/faq/index.html21
-rw-r--r--libstdc++-v3/include/backward/iterator.h29
-rw-r--r--libstdc++-v3/include/bits/basic_string.h10
-rw-r--r--libstdc++-v3/include/bits/basic_string.tcc8
-rw-r--r--libstdc++-v3/include/bits/boost_concept_check.h26
-rw-r--r--libstdc++-v3/include/bits/c++config27
-rw-r--r--libstdc++-v3/include/bits/deque.tcc85
-rw-r--r--libstdc++-v3/include/bits/fstream.tcc2
-rw-r--r--libstdc++-v3/include/bits/istream.tcc84
-rw-r--r--libstdc++-v3/include/bits/list.tcc4
-rw-r--r--libstdc++-v3/include/bits/locale_classes.h27
-rw-r--r--libstdc++-v3/include/bits/locale_facets.h10
-rw-r--r--libstdc++-v3/include/bits/stl_bvector.h207
-rw-r--r--libstdc++-v3/include/bits/stl_deque.h43
-rw-r--r--libstdc++-v3/include/bits/stl_list.h14
-rw-r--r--libstdc++-v3/include/bits/stl_map.h4
-rw-r--r--libstdc++-v3/include/bits/stl_multimap.h4
-rw-r--r--libstdc++-v3/include/bits/stl_multiset.h4
-rw-r--r--libstdc++-v3/include/bits/stl_pair.h36
-rw-r--r--libstdc++-v3/include/bits/stl_set.h4
-rw-r--r--libstdc++-v3/include/bits/stl_threads.h19
-rw-r--r--libstdc++-v3/include/bits/stl_tree.h10
-rw-r--r--libstdc++-v3/include/bits/stl_vector.h164
-rw-r--r--libstdc++-v3/include/bits/vector.tcc543
-rw-r--r--libstdc++-v3/include/debug/bitset7
-rw-r--r--libstdc++-v3/include/debug/deque8
-rw-r--r--libstdc++-v3/include/debug/formatter.h4
-rw-r--r--libstdc++-v3/include/debug/list8
-rw-r--r--libstdc++-v3/include/debug/map.h6
-rw-r--r--libstdc++-v3/include/debug/multimap.h6
-rw-r--r--libstdc++-v3/include/debug/multiset.h6
-rw-r--r--libstdc++-v3/include/debug/safe_iterator.h5
-rw-r--r--libstdc++-v3/include/debug/safe_iterator.tcc10
-rw-r--r--libstdc++-v3/include/debug/safe_sequence.h15
-rw-r--r--libstdc++-v3/include/debug/set.h6
-rw-r--r--libstdc++-v3/include/debug/vector6
-rw-r--r--libstdc++-v3/include/std/std_bitset.h11
-rw-r--r--libstdc++-v3/libsupc++/tinfo.h28
-rw-r--r--libstdc++-v3/linkage.m45
-rw-r--r--libstdc++-v3/po/string_literals.cc9
-rw-r--r--libstdc++-v3/src/Makefile.am1
-rw-r--r--libstdc++-v3/src/Makefile.in13
-rw-r--r--libstdc++-v3/src/debug.cc12
-rw-r--r--libstdc++-v3/src/debug_list.cc34
-rw-r--r--libstdc++-v3/src/list.cc6
-rw-r--r--libstdc++-v3/src/locale.cc66
-rw-r--r--libstdc++-v3/src/locale_init.cc18
-rw-r--r--libstdc++-v3/src/localename.cc56
-rw-r--r--libstdc++-v3/testsuite/18_support/new_delete_placement.cc4
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/capacity/1.cc4
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/1.cc4
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/1.cc4
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char/10.cc80
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/10.cc80
-rw-r--r--libstdc++-v3/testsuite/21_strings/char_traits/requirements/char/1.cc3
-rw-r--r--libstdc++-v3/testsuite/21_strings/char_traits/requirements/short/1.cc4
-rw-r--r--libstdc++-v3/testsuite/21_strings/char_traits/requirements/wchar_t/1.cc3
-rw-r--r--libstdc++-v3/testsuite/23_containers/bitset/ext/15361.cc40
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/bool/clear_allocator.cc88
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_filebuf/2.cc5
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-4.cc3
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/14975-1.cc67
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/13582-3.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/14975-2.cc83
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_fstream/2.cc5
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_ifstream/2.cc5
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_ios/2.cc5
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_iostream/2.cc5
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_istream/2.cc6
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_istream/extractors_character/char/9555-ic.cc5
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_istream/getline/char/4.cc108
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_istream/getline/char/5.cc81
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_istream/seekg/char/exceptions_badbit_throw.cc4
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_istringstream/2.cc5
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_istringstream/str/char/1.cc4
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_ofstream/2.cc5
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_ostream/2.cc6
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/char/exceptions_badbit_throw.cc4
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/char/exceptions_failbit_throw.cc4
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_ostream/seekp/char/exceptions_badbit_throw.cc6
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_ostringstream/2.cc5
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_streambuf/2.cc5
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringbuf/1.cc9
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringbuf/2.cc7
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringbuf/4.cc5
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringstream/2.cc7
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringstream/str/char/1.cc4
-rw-r--r--libstdc++-v3/testsuite/27_io/fpos/1.cc7
-rw-r--r--libstdc++-v3/testsuite/27_io/fpos/14320-3.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/fpos/14775.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/ios_base/storage/2.cc12
-rw-r--r--libstdc++-v3/testsuite/27_io/types/2.cc4
-rw-r--r--libstdc++-v3/testsuite/Makefile.am26
-rw-r--r--libstdc++-v3/testsuite/Makefile.in20
-rw-r--r--libstdc++-v3/testsuite/abi_check.cc489
-rw-r--r--libstdc++-v3/testsuite/ext/stdio_filebuf/char/1.cc12
-rw-r--r--libstdc++-v3/testsuite/ext/stdio_sync_filebuf/wchar_t/12077.cc2
-rw-r--r--libstdc++-v3/testsuite/lib/libstdc++.exp14
-rw-r--r--libstdc++-v3/testsuite/testsuite_abi.cc462
-rw-r--r--libstdc++-v3/testsuite/testsuite_abi.h129
-rw-r--r--libstdc++-v3/testsuite/testsuite_hooks.cc6
-rw-r--r--libtool.m44
-rw-r--r--ltcf-c.sh6
-rw-r--r--ltcf-cxx.sh6
-rw-r--r--ltcf-gcj.sh6
-rwxr-xr-xltconfig11
-rw-r--r--maintainer-scripts/ChangeLog40
-rw-r--r--maintainer-scripts/crontab10
-rwxr-xr-xmaintainer-scripts/gcc_release14
-rw-r--r--maintainer-scripts/snapshot-README2
-rw-r--r--maintainer-scripts/snapshot-index.html4
-rwxr-xr-xmaintainer-scripts/update_version2
-rwxr-xr-xmaintainer-scripts/update_web_docs14
2676 files changed, 426322 insertions, 34194 deletions
diff --git a/ChangeLog b/ChangeLog
index 30c49ab1108..37ef3ffa26a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,122 @@
+2004-05-13 Tobias Schlüter <tobi@gcc.gnu.org>
+
+ * MAINTAINERS (Write After Approval): Add myself.
+
+2004-05-13 Diego Novillo <dnovillo@redhat.com>
+
+ Merge from tree-ssa-20020619-branch.
+
+ * Makefile.def: Add libbanshee, libmudflap and libgfortran.
+ * Makefile.tpl (BUILD_CONFIGDIRS): Add libbanshee.
+ (HOST_GMPLIBS): Define.
+ (HOST_GMPINC): Define.
+ (TARGET_LIB_PATH): Add libmudflap.
+ (GFORTRAN_FOR_TARGET): Define.
+ (configure-build*): Export GFORTRAN.
+ (configure-gcc): Export GMPLIBS and GMPINC.
+ (all-gcc): Add maybe-all-libbanshee.
+ (configure-target-libgfortran): Define.
+ * Makefile.in: Regenerate.
+ * configure.in (host_libs): Add libbanshee.
+ (target_libraries): Add target-libmudflap and target-libgfortran.
+ Add --with-libbanshee.
+ Handle --disable-libmudflap.
+ (*-*-freebsd*): Use with_gmp.
+ Add $(libgcj) to noconfigdirs.
+ * configure: Regenerate.
+ * depcomp: New file.
+ * MAINTAINERS: Add tree-ssa maintainers.
+
+2004-05-04 Vladimir Makarov <vmakarov@redhat.com>
+
+ * MAINTAINERS (Various Maintainers): Add myself.
+
+2004-04-30 Brian Ford <ford@vss.fsi.com>
+
+ * MAINTAINERS (Write After Approval): Add myself.
+
+2004-04-29 Uros Bizjak <uros@kss-loka.si>
+
+ * MAINTAINERS (Write After Approval): Add myself.
+
+2004-04-28 Paolo Bonzini <bonzini@gnu.org>
+
+ * config/acx.m4: Fix fastcompare support for new-bootstrap.
+ * configure: Regenerate.
+
+2004-04-27 Paolo Bonzini <bonzini@gnu.org>
+
+ Revert:
+ 2004-04-26 Paolo Bonzini <bonzini@gnu.org>
+
+ * Makefile.def (flags_to_pass): Remove *dir variables that
+ are passed to the modules via TOPLEVEL_CONFIGURE_ARGUMENTS,
+ as well as prefix and exec_prefix.
+ * Makefile.in: Regenerate.
+
+2004-04-26 Robert Millan <robertmh@gnu.org>
+
+ Add patches from libtool CVS.
+ * libtool.m4: Add kfreebsd*-gnu and knetbsd*-gnu.
+ * ltconfig: Likewise.
+ * ltcf-c.sh: Likewise.
+ * ltcf-cxx.sh: Likewise.
+ * ltcf-gcj.sh: Likewise.
+
+2004-04-26 Paolo Bonzini <bonzini@gnu.org>
+
+ * Makefile.def (host_modules): Mark with the bootstrap
+ flag packages on which gcc depends.
+ * Makefile.tpl (all-bootstrap): Use it.
+ * Makefile.in: Regenerate.
+
+2004-04-26 Paolo Bonzini <bonzini@gnu.org>
+
+ * Makefile.def (flags_to_pass): Remove *dir variables that
+ are passed to the modules via TOPLEVEL_CONFIGURE_ARGUMENTS,
+ as well as prefix and exec_prefix.
+ * Makefile.in: Regenerate.
+
+2004-04-26 Paolo Bonzini <bonzini@gnu.org>
+
+ * configure.in: Invoke ACX_PROG_CMP_IGNORE_INITIAL.
+ * configure: Regenerate.
+ * config/acx.m4: Mutuate ACX_PROG_CMP_IGNORE_INITIAL from gcc.
+ * gcc/Makefile.tpl (compare): Use the result of the test.
+ * gcc/Makefile.in: Regenerate.
+
+2004-04-23 Paolo Bonzini <bonzini@gnu.org>
+
+ * Makefile.tpl (all-stage1-gcc, all-stage2-gcc, all-stage3-gcc):
+ Always relocate gcc and prev-gcc to the original names, even
+ if the build fails.
+ (new-cleanstrap, new-restage1, new-restage2, new-restage3):
+ New targets.
+
+2004-04-23 Laurent GUERBY <laurent@guerby.net>
+
+ * MAINTAINERS: Update my email address.
+
+2004-04-19 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure.in (mips*-*-irix5*): Enable ld.
+ * configure: Regenerate.
+
+2004-04-16 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure: Regenerate.
+
+2004-04-15 James E Wilson <wilson@specifixinc.com>
+
+ * Makefile.tpl (configure-[+module+], configure-gcc,
+ configure-stage1-gcc, configure-stage2-gcc, configure-stage3-gcc):
+ Set and export LDFLAGS.
+ * Makefile.in: Regenerate.
+
+2004-04-12 Michael Chastain <mec.gnu@mindspring.com>
+
+ * MAINTAINERS: Add myself to write-after-approval.
+
2004-04-09 Nathanael Nerode <neroden@gcc.gnu.org>
PR bootstrap/14871
diff --git a/ChangeLog.tree-ssa b/ChangeLog.tree-ssa
new file mode 100644
index 00000000000..9ada8f03e7f
--- /dev/null
+++ b/ChangeLog.tree-ssa
@@ -0,0 +1,110 @@
+2004-05-03 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * configure.in (GMP checking): s/save_CFLAGS/saved_CFLAGS.
+ * configure: Regenerate.
+
+2004-04-22 Loren J. Rittle <ljrittle@acm.org>
+
+ * configure.in (*-*-freebsd*): Use with_gmp to "Avoid crusty gmp.h."
+ * configure: Rebuilt (with autoconf version 2.13).
+
+2004-04-17 Paul Brook <paul@codesourcery.com>
+
+ * Makefile.tmp (EXTRA_HOST_FLAGS): Remove GMPLIBS and GMPINC.
+ (configure-gcc): Set GMPLIBS and GMPINC.
+ * Makefile.in: Regenerate.
+
+2004-04-14 Paul Brook <paul@codesourcery.com>
+
+ * Makefile.tmp (HOST_GMPLIBS, HOST_GMPINC): New variables.
+ (EXTRA_HOST_FLAGS): Pass them.
+ * configure.in: Add check for GMP. Disable languages if not found.
+ * Makefile.in, configure: Regenrate.
+
+2004-03-29 Diego Novillo <dnovillo@redhat.com>
+
+ * configure.in: Set with_libbansshee to yes by default.
+ * configure: Regenerate.
+
+2004-03-28 Diego Novillo <dnovillo@redhat.com>
+
+ * configure.in: Fix handling of --without-libbanshee.
+ * configure: Regenerate.
+
+2004-03-26 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in: Add support for --without-libbanshee.
+ * configure: Regenerated.
+
+2004-02-17 Brian Booth <bbooth@redhat.com>
+
+ * MAINTAINERS.tree-ssa: Add self to write after approval.
+
+2004-02-13 Loren J. Rittle <ljrittle@acm.org>
+
+ * configure.in (*-*-freebsd*): Avoid crusty gmp.h.
+ (alpha*-*-*freebsd*, i[[3456789]]86-*-*freebsd*): Merge into above.
+ * configure: Rebuilt (with autoconf version 2.13).
+
+2003-10-22 Frank Ch. Eigler <fche@redhat.com>
+
+ * configure.in: Add support for "--disable-libmudflap" option.
+ * configure: Regenerated.
+
+2003-09-22 Diego Novillo <dnovillo@redhat.com>
+
+ * MAINTAINERS.tree-ssa: Add Andrew MacLeod as global maintainer for
+ the branch.
+
+2003-08-23 Paul Brook <paul@nowt.org>
+
+ * Makefile.in: Regenerate.
+
+2003-07-26 Paul Brook <paul@nowt.org>
+
+ * Makefile.def: Add libgfortran and GFORTRAN_FOR_TARGET.
+ * Makefile.tmp: Ditto.
+ * configure.in: Ditto.
+ * depcomp: New file.
+ * maintainer-scripts/gcc_release: Add gcc-fortran.
+ * maintainer-scripts/snapshot-README: Ditto.
+ * maintainer-scripts/snapshot-index.html: Ditto.
+ * libgfortran: New target library.
+
+2003-06-05 Frank Ch. Eigler <fche@redhat.com>
+
+ * Makefile.in: Regenerated to activate libmudflap builds.
+
+2003-04-25 Diego Novillo <dnovillo@redhat.com>
+
+ * MAINTAINERS.tree-ssa: New file.
+
+2003-01-29 Daniel Berlin <dberlin@dberlin.org>
+
+ * configure.in: Use ac_configure_args for libbanshee option
+ * configure: regen.
+
+2002-11-27 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.tpl (all-gcc, all-bootstrap): Add dependency on
+ all-libbanshee.
+ * Makefile.in: Regenerate.
+
+2002-11-25 Daniel Berlin <dberlin@dberlin.org>
+
+ * Makefile.def: Diego already did the libmudflap moving in a merge,
+ so remove the extra i added.
+ * Makefile.in: Regenerate.
+
+2002-11-24 Daniel Berlin <dberlin@dberlin.org>
+
+ * configure.in: Add libbanshee related stuff.
+ * Makefile.in: Regenerate from Makefile.def.
+ * Makefile.def: Move libmudflap stuff to here, where it belongs.
+ Add libbanshee stuff.
+ * Makefile.tpl: Add libbanshee stuff.
+
+2002-08-12 Frank Ch. Eigler <fche@redhat.com>
+
+ * Makefile.in (target-libmudflap): Add libmudflap-related targets.
+ * configure.in (target_libs): Ditto.
diff --git a/MAINTAINERS b/MAINTAINERS
index 91affa75a07..8c42742df4e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -129,6 +129,7 @@ loop discovery Michael Hayes m.hayes@elec.canterbury.ac.nz
scheduler (+ haifa) Jim Wilson wilson@specifixinc.com
scheduler (+ haifa) Michael Meissner gnu@the-meissners.org
scheduler (+ haifa) Jeff Law law@redhat.com
+scheduler (+ haifa) Vladimir Makarov vmakarov@redhat.com
reorg Jeff Law law@redhat.com
caller-save.c Jeff Law law@redhat.com
callgraph Jan Hubicka jh@suse.cz
@@ -169,6 +170,11 @@ gcov Nathan Sidwell nathan@codesourcery.com
option handling Neil Booth neil@daikokuya.co.uk
libffi testsuite Andreas Tobler andreast@gcc.gnu.org
middle-end Roger Sayle roger@eyesopen.com
+tree-ssa Diego Novillo dnovillo@redhat.com
+tree-ssa Andrew MacLeod amacleod@redhat.com
+PRE, points-to Daniel Berlin dberlin@dberlin.org
+mudflap Frank Ch. Eigler fche@redhat.com
+tree browser/unparser Sebastian Pop s.pop@laposte.net
Note individuals who maintain parts of the compiler need approval to check
in changes outside of the parts of the compiler they maintain.
@@ -183,6 +189,7 @@ Wolfgang Bangerth bangerth@dealii.org
Daniel Berlin dan@dberlin.org
David Billinghurst David.Billinghurst@riotinto.com
Laurynas Biveinis laurynas.biveinis@mif.vu.lt
+Uros Bizjak uros@kss-loka.si
Eric Blake ericb@gcc.gnu.org
Jim Blandy jimb@redhat.com
Phil Blundell pb@futuretv.com
@@ -194,6 +201,7 @@ Joel Brobecker brobecker@gnat.com
Kevin Buettner kevinb@redhat.com
Andrew Cagney cagney@redhat.com
Steve Chamberlain sac@transmeta.com
+Michael Chastain mec.gnu@mindspring.com
Chandra Chavva cchavva@redhat.com
William Cohen wcohen@redhat.com
R. Kelley Cook kcook@gcc.gnu.org
@@ -209,10 +217,11 @@ Mohan Embar gnustuff@thisiscool.com
Marc Espie espie@cvs.openbsd.org
Ansgar Esztermann ansgar@thphy.uni-duesseldorf.de
Doug Evans dje@transmeta.com
+Brian Ford ford@vss.fsi.com
Kaveh Ghazi ghazi@caip.rutgers.edu
Matthew Gingell gingell@gnat.com
Anthony Green green@redhat.com
-Laurent Guerby guerby@acm.org
+Laurent Guerby laurent@guerby.net
Olivier Hainque hainque@act-europe.fr
Stuart Hastings stuart@apple.com
Matthew Hiller hiller@redhat.com
@@ -271,6 +280,7 @@ Gavin Romig-Koch gavin@redhat.com
Ira Ruben ira@apple.com
Douglas Rupp rupp@gnat.com
Alex Samuel samuel@codesourcery.com
+Tobias Schlüter tobias.schlueter@physik.uni-muenchen.de
Andreas Schwab schwab@suse.de
Svein Seldal svein.seldal@solidas.com
Franz Sirl franz.sirl-kernel@lauterbach.com
diff --git a/Makefile.def b/Makefile.def
index 5a68098157b..5f293680ae2 100644
--- a/Makefile.def
+++ b/Makefile.def
@@ -25,6 +25,7 @@ AutoGen definitions Makefile.tpl;
// that recursive target in its Makefile.
build_modules= { module= libiberty; };
+build_modules= { module= libbanshee; };
host_modules= { module= ash; };
host_modules= { module= autoconf; };
@@ -32,9 +33,9 @@ host_modules= { module= automake; };
host_modules= { module= bash; };
host_modules= { module= bfd; };
host_modules= { module= opcodes; };
-host_modules= { module= binutils; };
-host_modules= { module= bison; no_check_cross= true; };
-host_modules= { module= byacc; no_check_cross= true; };
+host_modules= { module= binutils; bootstrap=true; };
+host_modules= { module= bison; no_check_cross= true; bootstrap=true; };
+host_modules= { module= byacc; no_check_cross= true; bootstrap=true; };
host_modules= { module= bzip2; };
host_modules= { module= dejagnu; };
host_modules= { module= diff; };
@@ -45,7 +46,7 @@ host_modules= { module= fileutils; };
host_modules= { module= findutils; };
host_modules= { module= find; };
host_modules= { module= flex; no_check_cross= true; };
-host_modules= { module= gas; };
+host_modules= { module= gas; bootstrap=true; };
host_modules= { module= gawk; };
host_modules= { module= gettext; };
host_modules= { module= gnuserv; };
@@ -53,13 +54,14 @@ host_modules= { module= gprof; };
host_modules= { module= gzip; };
host_modules= { module= hello; };
host_modules= { module= indent; };
-host_modules= { module= intl; };
+host_modules= { module= intl; bootstrap=true; };
host_modules= { module= tcl;
missing=mostlyclean; };
host_modules= { module= itcl; };
-host_modules= { module= ld; };
+host_modules= { module= ld; bootstrap=true; };
host_modules= { module= libgui; };
-host_modules= { module= libiberty; };
+host_modules= { module= libbanshee; bootstrap=true; no_install=true; };
+host_modules= { module= libiberty; bootstrap=true; };
host_modules= { module= libtool; };
host_modules= { module= m4; };
host_modules= { module= make; };
@@ -77,13 +79,13 @@ host_modules= { module= shellutils; };
host_modules= { module= sid; };
host_modules= { module= sim; };
host_modules= { module= tar; };
-host_modules= { module= texinfo; no_install= true; };
+host_modules= { module= texinfo; no_install= true; bootstrap=true; };
host_modules= { module= textutils; };
host_modules= { module= time; };
host_modules= { module= uudecode; };
host_modules= { module= wdiff; };
host_modules= { module= zip; no_check_cross=true; };
-host_modules= { module= zlib; no_install=true; no_check=true; };
+host_modules= { module= zlib; no_install=true; no_check=true; bootstrap=true; };
host_modules= { module= gdb; with_x=true; };
host_modules= { module= expect; with_x=true; };
host_modules= { module= guile; with_x=true; };
@@ -97,8 +99,10 @@ host_modules= { module= libtermcap; no_check=true;
host_modules= { module= utils; no_check=true; };
target_modules = { module= libstdc++-v3; raw_cxx=true; };
+target_modules = { module= libmudflap; };
target_modules = { module= newlib; };
target_modules = { module= libf2c; };
+target_modules = { module= libgfortran; };
target_modules = { module= libobjc; };
target_modules = { module= libtermcap; no_check=true; stage=true;
missing=mostlyclean;
@@ -202,6 +206,7 @@ flags_to_pass = { flag= CXX_FOR_TARGET ; };
flags_to_pass = { flag= CXXFLAGS_FOR_TARGET ; };
flags_to_pass = { flag= DLLTOOL_FOR_TARGET ; };
flags_to_pass = { flag= GCJ_FOR_TARGET ; };
+flags_to_pass = { flag= GFORTRAN_FOR_TARGET ; };
flags_to_pass = { flag= LD_FOR_TARGET ; };
flags_to_pass = { flag= LIBCFLAGS_FOR_TARGET ; };
flags_to_pass = { flag= LIBCXXFLAGS_FOR_TARGET ; };
diff --git a/Makefile.in b/Makefile.in
index bf7bc3e0685..ff065ac1ce6 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -102,7 +102,7 @@ REALLY_SET_LIB_PATH = \
$(RPATH_ENVVAR)=`echo "$(HOST_LIB_PATH):$(TARGET_LIB_PATH):$$$(RPATH_ENVVAR)" | sed 's,::*,:,g;s,^:*,,;s,:*$$,,'`; export $(RPATH_ENVVAR);
# This is the list of directories to be built for the build system.
-BUILD_CONFIGDIRS = libiberty
+BUILD_CONFIGDIRS = libiberty libbanshee
# Build programs are put under this directory.
BUILD_SUBDIR = @build_subdir@
# This is set by the configure script to the arguments to use when configuring
@@ -124,6 +124,10 @@ TARGET_SUBDIR = @target_subdir@
# directories built for the target.
TARGET_CONFIGARGS = @target_configargs@
+# Where to find GMP
+HOST_GMPLIBS = @gmplibs@
+HOST_GMPINC = @gmpinc@
+
# ----------------------------------------------
# Programs producing files for the BUILD machine
# ----------------------------------------------
@@ -241,7 +245,7 @@ PICFLAG =
# This is the list of directories that may be needed in RPATH_ENVVAR
# so that prorgams built for the target machine work.
-TARGET_LIB_PATH = $$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs:
+TARGET_LIB_PATH = $$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs:$$r/$(TARGET_SUBDIR)/libmudflap/.libs
FLAGS_FOR_TARGET = @FLAGS_FOR_TARGET@
@@ -308,6 +312,7 @@ USUAL_DLLTOOL_FOR_TARGET = ` \
fi`
GCJ_FOR_TARGET = @GCJ_FOR_TARGET@
+GFORTRAN_FOR_TARGET = @GFORTRAN_FOR_TARGET@
LD_FOR_TARGET=@LD_FOR_TARGET@
CONFIGURED_LD_FOR_TARGET=@CONFIGURED_LD_FOR_TARGET@
@@ -446,6 +451,7 @@ BASE_FLAGS_TO_PASS = \
"CXXFLAGS_FOR_TARGET=$(CXXFLAGS_FOR_TARGET)" \
"DLLTOOL_FOR_TARGET=$(DLLTOOL_FOR_TARGET)" \
"GCJ_FOR_TARGET=$(GCJ_FOR_TARGET)" \
+ "GFORTRAN_FOR_TARGET=$(GFORTRAN_FOR_TARGET)" \
"LD_FOR_TARGET=$(LD_FOR_TARGET)" \
"LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
"LIBCXXFLAGS_FOR_TARGET=$(LIBCXXFLAGS_FOR_TARGET)" \
@@ -568,6 +574,7 @@ configure-host: maybe-configure-gcc \
maybe-configure-itcl \
maybe-configure-ld \
maybe-configure-libgui \
+ maybe-configure-libbanshee \
maybe-configure-libiberty \
maybe-configure-libtool \
maybe-configure-m4 \
@@ -603,8 +610,10 @@ configure-host: maybe-configure-gcc \
.PHONY: configure-target
configure-target: \
maybe-configure-target-libstdc++-v3 \
+ maybe-configure-target-libmudflap \
maybe-configure-target-newlib \
maybe-configure-target-libf2c \
+ maybe-configure-target-libgfortran \
maybe-configure-target-libobjc \
maybe-configure-target-libtermcap \
maybe-configure-target-winsup \
@@ -658,6 +667,7 @@ all-host: maybe-all-gcc \
maybe-all-itcl \
maybe-all-ld \
maybe-all-libgui \
+ maybe-all-libbanshee \
maybe-all-libiberty \
maybe-all-libtool \
maybe-all-m4 \
@@ -693,8 +703,10 @@ all-host: maybe-all-gcc \
.PHONY: all-target
all-target: \
maybe-all-target-libstdc++-v3 \
+ maybe-all-target-libmudflap \
maybe-all-target-newlib \
maybe-all-target-libf2c \
+ maybe-all-target-libgfortran \
maybe-all-target-libobjc \
maybe-all-target-libtermcap \
maybe-all-target-winsup \
@@ -752,6 +764,7 @@ info-host: maybe-info-gcc \
maybe-info-itcl \
maybe-info-ld \
maybe-info-libgui \
+ maybe-info-libbanshee \
maybe-info-libiberty \
maybe-info-libtool \
maybe-info-m4 \
@@ -788,8 +801,10 @@ info-host: maybe-info-gcc \
.PHONY: info-target
info-target: \
maybe-info-target-libstdc++-v3 \
+ maybe-info-target-libmudflap \
maybe-info-target-newlib \
maybe-info-target-libf2c \
+ maybe-info-target-libgfortran \
maybe-info-target-libobjc \
maybe-info-target-libtermcap \
maybe-info-target-winsup \
@@ -842,6 +857,7 @@ dvi-host: maybe-dvi-gcc \
maybe-dvi-itcl \
maybe-dvi-ld \
maybe-dvi-libgui \
+ maybe-dvi-libbanshee \
maybe-dvi-libiberty \
maybe-dvi-libtool \
maybe-dvi-m4 \
@@ -878,8 +894,10 @@ dvi-host: maybe-dvi-gcc \
.PHONY: dvi-target
dvi-target: \
maybe-dvi-target-libstdc++-v3 \
+ maybe-dvi-target-libmudflap \
maybe-dvi-target-newlib \
maybe-dvi-target-libf2c \
+ maybe-dvi-target-libgfortran \
maybe-dvi-target-libobjc \
maybe-dvi-target-libtermcap \
maybe-dvi-target-winsup \
@@ -932,6 +950,7 @@ TAGS-host: maybe-TAGS-gcc \
maybe-TAGS-itcl \
maybe-TAGS-ld \
maybe-TAGS-libgui \
+ maybe-TAGS-libbanshee \
maybe-TAGS-libiberty \
maybe-TAGS-libtool \
maybe-TAGS-m4 \
@@ -968,8 +987,10 @@ TAGS-host: maybe-TAGS-gcc \
.PHONY: TAGS-target
TAGS-target: \
maybe-TAGS-target-libstdc++-v3 \
+ maybe-TAGS-target-libmudflap \
maybe-TAGS-target-newlib \
maybe-TAGS-target-libf2c \
+ maybe-TAGS-target-libgfortran \
maybe-TAGS-target-libobjc \
maybe-TAGS-target-libtermcap \
maybe-TAGS-target-winsup \
@@ -1022,6 +1043,7 @@ install-info-host: maybe-install-info-gcc \
maybe-install-info-itcl \
maybe-install-info-ld \
maybe-install-info-libgui \
+ maybe-install-info-libbanshee \
maybe-install-info-libiberty \
maybe-install-info-libtool \
maybe-install-info-m4 \
@@ -1058,8 +1080,10 @@ install-info-host: maybe-install-info-gcc \
.PHONY: install-info-target
install-info-target: \
maybe-install-info-target-libstdc++-v3 \
+ maybe-install-info-target-libmudflap \
maybe-install-info-target-newlib \
maybe-install-info-target-libf2c \
+ maybe-install-info-target-libgfortran \
maybe-install-info-target-libobjc \
maybe-install-info-target-libtermcap \
maybe-install-info-target-winsup \
@@ -1112,6 +1136,7 @@ installcheck-host: maybe-installcheck-gcc \
maybe-installcheck-itcl \
maybe-installcheck-ld \
maybe-installcheck-libgui \
+ maybe-installcheck-libbanshee \
maybe-installcheck-libiberty \
maybe-installcheck-libtool \
maybe-installcheck-m4 \
@@ -1148,8 +1173,10 @@ installcheck-host: maybe-installcheck-gcc \
.PHONY: installcheck-target
installcheck-target: \
maybe-installcheck-target-libstdc++-v3 \
+ maybe-installcheck-target-libmudflap \
maybe-installcheck-target-newlib \
maybe-installcheck-target-libf2c \
+ maybe-installcheck-target-libgfortran \
maybe-installcheck-target-libobjc \
maybe-installcheck-target-libtermcap \
maybe-installcheck-target-winsup \
@@ -1202,6 +1229,7 @@ mostlyclean-host: maybe-mostlyclean-gcc \
maybe-mostlyclean-itcl \
maybe-mostlyclean-ld \
maybe-mostlyclean-libgui \
+ maybe-mostlyclean-libbanshee \
maybe-mostlyclean-libiberty \
maybe-mostlyclean-libtool \
maybe-mostlyclean-m4 \
@@ -1238,8 +1266,10 @@ mostlyclean-host: maybe-mostlyclean-gcc \
.PHONY: mostlyclean-target
mostlyclean-target: \
maybe-mostlyclean-target-libstdc++-v3 \
+ maybe-mostlyclean-target-libmudflap \
maybe-mostlyclean-target-newlib \
maybe-mostlyclean-target-libf2c \
+ maybe-mostlyclean-target-libgfortran \
maybe-mostlyclean-target-libobjc \
maybe-mostlyclean-target-libtermcap \
maybe-mostlyclean-target-winsup \
@@ -1292,6 +1322,7 @@ clean-host: maybe-clean-gcc \
maybe-clean-itcl \
maybe-clean-ld \
maybe-clean-libgui \
+ maybe-clean-libbanshee \
maybe-clean-libiberty \
maybe-clean-libtool \
maybe-clean-m4 \
@@ -1328,8 +1359,10 @@ clean-host: maybe-clean-gcc \
.PHONY: clean-target
clean-target: \
maybe-clean-target-libstdc++-v3 \
+ maybe-clean-target-libmudflap \
maybe-clean-target-newlib \
maybe-clean-target-libf2c \
+ maybe-clean-target-libgfortran \
maybe-clean-target-libobjc \
maybe-clean-target-libtermcap \
maybe-clean-target-winsup \
@@ -1382,6 +1415,7 @@ distclean-host: maybe-distclean-gcc \
maybe-distclean-itcl \
maybe-distclean-ld \
maybe-distclean-libgui \
+ maybe-distclean-libbanshee \
maybe-distclean-libiberty \
maybe-distclean-libtool \
maybe-distclean-m4 \
@@ -1418,8 +1452,10 @@ distclean-host: maybe-distclean-gcc \
.PHONY: distclean-target
distclean-target: \
maybe-distclean-target-libstdc++-v3 \
+ maybe-distclean-target-libmudflap \
maybe-distclean-target-newlib \
maybe-distclean-target-libf2c \
+ maybe-distclean-target-libgfortran \
maybe-distclean-target-libobjc \
maybe-distclean-target-libtermcap \
maybe-distclean-target-winsup \
@@ -1472,6 +1508,7 @@ maintainer-clean-host: maybe-maintainer-clean-gcc \
maybe-maintainer-clean-itcl \
maybe-maintainer-clean-ld \
maybe-maintainer-clean-libgui \
+ maybe-maintainer-clean-libbanshee \
maybe-maintainer-clean-libiberty \
maybe-maintainer-clean-libtool \
maybe-maintainer-clean-m4 \
@@ -1508,8 +1545,10 @@ maintainer-clean-host: maybe-maintainer-clean-gcc \
.PHONY: maintainer-clean-target
maintainer-clean-target: \
maybe-maintainer-clean-target-libstdc++-v3 \
+ maybe-maintainer-clean-target-libmudflap \
maybe-maintainer-clean-target-newlib \
maybe-maintainer-clean-target-libf2c \
+ maybe-maintainer-clean-target-libgfortran \
maybe-maintainer-clean-target-libobjc \
maybe-maintainer-clean-target-libtermcap \
maybe-maintainer-clean-target-winsup \
@@ -1619,6 +1658,7 @@ do-check: maybe-check-gcc \
maybe-check-itcl \
maybe-check-ld \
maybe-check-libgui \
+ maybe-check-libbanshee \
maybe-check-libiberty \
maybe-check-libtool \
maybe-check-m4 \
@@ -1652,8 +1692,10 @@ do-check: maybe-check-gcc \
maybe-check-libtermcap \
maybe-check-utils \
maybe-check-target-libstdc++-v3 \
+ maybe-check-target-libmudflap \
maybe-check-target-newlib \
maybe-check-target-libf2c \
+ maybe-check-target-libgfortran \
maybe-check-target-libobjc \
maybe-check-target-libtermcap \
maybe-check-target-winsup \
@@ -1729,6 +1771,7 @@ install-host-nogcc: \
maybe-install-itcl \
maybe-install-ld \
maybe-install-libgui \
+ maybe-install-libbanshee \
maybe-install-libiberty \
maybe-install-libtool \
maybe-install-m4 \
@@ -1796,6 +1839,7 @@ install-host: maybe-install-gcc \
maybe-install-itcl \
maybe-install-ld \
maybe-install-libgui \
+ maybe-install-libbanshee \
maybe-install-libiberty \
maybe-install-libtool \
maybe-install-m4 \
@@ -1832,8 +1876,10 @@ install-host: maybe-install-gcc \
.PHONY: install-target
install-target: \
maybe-install-target-libstdc++-v3 \
+ maybe-install-target-libmudflap \
maybe-install-target-newlib \
maybe-install-target-libf2c \
+ maybe-install-target-libgfortran \
maybe-install-target-libobjc \
maybe-install-target-libtermcap \
maybe-install-target-winsup \
@@ -1918,6 +1964,7 @@ configure-build-libiberty:
CXX="$(CXX_FOR_BUILD)"; export CXX; \
CXXFLAGS="$(CXXFLAGS_FOR_BUILD)"; export CXXFLAGS; \
GCJ="$(GCJ_FOR_BUILD)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_BUILD)"; export GFORTRAN; \
DLLTOOL="$(DLLTOOL_FOR_BUILD)"; export DLLTOOL; \
LD="$(LD_FOR_BUILD)"; export LD; \
LDFLAGS="$(LDFLAGS_FOR_BUILD)"; export LDFLAGS; \
@@ -1972,6 +2019,76 @@ all-build-libiberty: configure-build-libiberty
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
(cd $(BUILD_SUBDIR)/libiberty && $(MAKE) all)
+.PHONY: configure-build-libbanshee maybe-configure-build-libbanshee
+maybe-configure-build-libbanshee:
+configure-build-libbanshee:
+ @test ! -f $(BUILD_SUBDIR)/libbanshee/Makefile || exit 0; \
+ $(SHELL) $(srcdir)/mkinstalldirs $(BUILD_SUBDIR)/libbanshee ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ AR="$(AR_FOR_BUILD)"; export AR; \
+ AS="$(AS_FOR_BUILD)"; export AS; \
+ CC="$(CC_FOR_BUILD)"; export CC; \
+ CFLAGS="$(CFLAGS_FOR_BUILD)"; export CFLAGS; \
+ CONFIG_SHELL="$(SHELL)"; export CONFIG_SHELL; \
+ CXX="$(CXX_FOR_BUILD)"; export CXX; \
+ CXXFLAGS="$(CXXFLAGS_FOR_BUILD)"; export CXXFLAGS; \
+ GCJ="$(GCJ_FOR_BUILD)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_BUILD)"; export GFORTRAN; \
+ DLLTOOL="$(DLLTOOL_FOR_BUILD)"; export DLLTOOL; \
+ LD="$(LD_FOR_BUILD)"; export LD; \
+ LDFLAGS="$(LDFLAGS_FOR_BUILD)"; export LDFLAGS; \
+ NM="$(NM_FOR_BUILD)"; export NM; \
+ RANLIB="$(RANLIB_FOR_BUILD)"; export RANLIB; \
+ WINDRES="$(WINDRES_FOR_BUILD)"; export WINDRES; \
+ echo Configuring in $(BUILD_SUBDIR)/libbanshee; \
+ cd "$(BUILD_SUBDIR)/libbanshee" || exit 1; \
+ case $(srcdir) in \
+ /* | [A-Za-z]:[\\/]*) \
+ topdir=$(srcdir) ;; \
+ *) \
+ case "$(BUILD_SUBDIR)" in \
+ .) topdir="../$(srcdir)" ;; \
+ *) topdir="../../$(srcdir)" ;; \
+ esac ;; \
+ esac; \
+ if [ "$(srcdir)" = "." ] ; then \
+ if [ "$(BUILD_SUBDIR)" != "." ] ; then \
+ if $(SHELL) $$s/symlink-tree $${topdir}/libbanshee "no-such-file" ; then \
+ if [ -f Makefile ]; then \
+ if $(MAKE) distclean; then \
+ true; \
+ else \
+ exit 1; \
+ fi; \
+ else \
+ true; \
+ fi; \
+ else \
+ exit 1; \
+ fi; \
+ else \
+ true; \
+ fi; \
+ srcdiroption="--srcdir=."; \
+ libsrcdir="."; \
+ else \
+ srcdiroption="--srcdir=$${topdir}/libbanshee"; \
+ libsrcdir="$$s/libbanshee"; \
+ fi; \
+ rm -f no-such-file || : ; \
+ CONFIG_SITE=no-such-file $(SHELL) $${libsrcdir}/configure \
+ $(BUILD_CONFIGARGS) $${srcdiroption} \
+ --with-build-subdir="$(BUILD_SUBDIR)" \
+ || exit 1
+
+.PHONY: all-build-libbanshee maybe-all-build-libbanshee
+maybe-all-build-libbanshee:
+all-build-libbanshee: configure-build-libbanshee
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ (cd $(BUILD_SUBDIR)/libbanshee && $(MAKE) all)
+
# --------------------------------------
# Modules which run on the host machine
@@ -1994,6 +2111,7 @@ configure-ash:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -2259,6 +2377,7 @@ configure-autoconf:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -2524,6 +2643,7 @@ configure-automake:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -2789,6 +2909,7 @@ configure-bash:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -3054,6 +3175,7 @@ configure-bfd:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -3319,6 +3441,7 @@ configure-opcodes:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -3584,6 +3707,7 @@ configure-binutils:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -3849,6 +3973,7 @@ configure-bison:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -4117,6 +4242,7 @@ configure-byacc:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -4385,6 +4511,7 @@ configure-bzip2:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -4650,6 +4777,7 @@ configure-dejagnu:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -4915,6 +5043,7 @@ configure-diff:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -5180,6 +5309,7 @@ configure-dosutils:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -5441,6 +5571,7 @@ configure-etc:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -5706,6 +5837,7 @@ configure-fastjar:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -5974,6 +6106,7 @@ configure-fileutils:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -6239,6 +6372,7 @@ configure-findutils:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -6504,6 +6638,7 @@ configure-find:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -6769,6 +6904,7 @@ configure-flex:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -7037,6 +7173,7 @@ configure-gas:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -7302,6 +7439,7 @@ configure-gawk:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -7567,6 +7705,7 @@ configure-gettext:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -7832,6 +7971,7 @@ configure-gnuserv:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -8097,6 +8237,7 @@ configure-gprof:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -8362,6 +8503,7 @@ configure-gzip:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -8627,6 +8769,7 @@ configure-hello:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -8892,6 +9035,7 @@ configure-indent:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -9157,6 +9301,7 @@ configure-intl:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -9422,6 +9567,7 @@ configure-tcl:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -9673,6 +9819,7 @@ configure-itcl:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -9938,6 +10085,7 @@ configure-ld:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -10203,6 +10351,7 @@ configure-libgui:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -10451,6 +10600,268 @@ maintainer-clean-libgui:
+.PHONY: configure-libbanshee maybe-configure-libbanshee
+maybe-configure-libbanshee:
+configure-libbanshee:
+ @test ! -f libbanshee/Makefile || exit 0; \
+ [ -d libbanshee ] || mkdir libbanshee; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ CC="$(CC)"; export CC; \
+ CFLAGS="$(CFLAGS)"; export CFLAGS; \
+ CONFIG_SHELL="$(SHELL)"; export CONFIG_SHELL; \
+ CXX="$(CXX)"; export CXX; \
+ CXXFLAGS="$(CXXFLAGS)"; export CXXFLAGS; \
+ AR="$(AR)"; export AR; \
+ AS="$(AS)"; export AS; \
+ CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
+ DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
+ LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
+ NM="$(NM)"; export NM; \
+ RANLIB="$(RANLIB)"; export RANLIB; \
+ WINDRES="$(WINDRES)"; export WINDRES; \
+ OBJCOPY="$(OBJCOPY)"; export OBJCOPY; \
+ OBJDUMP="$(OBJDUMP)"; export OBJDUMP; \
+ echo Configuring in libbanshee; \
+ cd libbanshee || exit 1; \
+ case $(srcdir) in \
+ \.) \
+ srcdiroption="--srcdir=."; \
+ libsrcdir=".";; \
+ /* | [A-Za-z]:[\\/]*) \
+ srcdiroption="--srcdir=$(srcdir)/libbanshee"; \
+ libsrcdir="$$s/libbanshee";; \
+ *) \
+ srcdiroption="--srcdir=../$(srcdir)/libbanshee"; \
+ libsrcdir="$$s/libbanshee";; \
+ esac; \
+ $(SHELL) $${libsrcdir}/configure \
+ $(HOST_CONFIGARGS) $${srcdiroption} \
+ || exit 1
+
+.PHONY: all-libbanshee maybe-all-libbanshee
+maybe-all-libbanshee:
+all-libbanshee: configure-libbanshee
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ (cd libbanshee && $(MAKE) $(FLAGS_TO_PASS) all)
+
+.PHONY: check-libbanshee maybe-check-libbanshee
+maybe-check-libbanshee:
+
+check-libbanshee:
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ (cd libbanshee && $(MAKE) $(FLAGS_TO_PASS) check)
+
+
+.PHONY: install-libbanshee maybe-install-libbanshee
+maybe-install-libbanshee:
+
+install-libbanshee:
+
+
+# Other targets (info, dvi, etc.)
+
+.PHONY: maybe-info-libbanshee info-libbanshee
+maybe-info-libbanshee:
+
+info-libbanshee: \
+ configure-libbanshee
+ @[ -f ./libbanshee/Makefile ] || exit 0; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ for flag in $(EXTRA_HOST_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ echo "Doing info in libbanshee" ; \
+ (cd libbanshee && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ info) \
+ || exit 1
+
+
+.PHONY: maybe-dvi-libbanshee dvi-libbanshee
+maybe-dvi-libbanshee:
+
+dvi-libbanshee: \
+ configure-libbanshee
+ @[ -f ./libbanshee/Makefile ] || exit 0; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ for flag in $(EXTRA_HOST_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ echo "Doing dvi in libbanshee" ; \
+ (cd libbanshee && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ dvi) \
+ || exit 1
+
+
+.PHONY: maybe-TAGS-libbanshee TAGS-libbanshee
+maybe-TAGS-libbanshee:
+
+TAGS-libbanshee: \
+ configure-libbanshee
+ @[ -f ./libbanshee/Makefile ] || exit 0; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ for flag in $(EXTRA_HOST_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ echo "Doing TAGS in libbanshee" ; \
+ (cd libbanshee && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ TAGS) \
+ || exit 1
+
+
+.PHONY: maybe-install-info-libbanshee install-info-libbanshee
+maybe-install-info-libbanshee:
+
+install-info-libbanshee: \
+ configure-libbanshee \
+ info-libbanshee
+ @[ -f ./libbanshee/Makefile ] || exit 0; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ for flag in $(EXTRA_HOST_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ echo "Doing install-info in libbanshee" ; \
+ (cd libbanshee && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ install-info) \
+ || exit 1
+
+
+.PHONY: maybe-installcheck-libbanshee installcheck-libbanshee
+maybe-installcheck-libbanshee:
+
+installcheck-libbanshee: \
+ configure-libbanshee
+ @[ -f ./libbanshee/Makefile ] || exit 0; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ for flag in $(EXTRA_HOST_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ echo "Doing installcheck in libbanshee" ; \
+ (cd libbanshee && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ installcheck) \
+ || exit 1
+
+
+.PHONY: maybe-mostlyclean-libbanshee mostlyclean-libbanshee
+maybe-mostlyclean-libbanshee:
+
+mostlyclean-libbanshee:
+ @[ -f ./libbanshee/Makefile ] || exit 0; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ for flag in $(EXTRA_HOST_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ echo "Doing mostlyclean in libbanshee" ; \
+ (cd libbanshee && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ mostlyclean) \
+ || exit 1
+
+
+.PHONY: maybe-clean-libbanshee clean-libbanshee
+maybe-clean-libbanshee:
+
+clean-libbanshee:
+ @[ -f ./libbanshee/Makefile ] || exit 0; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ for flag in $(EXTRA_HOST_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ echo "Doing clean in libbanshee" ; \
+ (cd libbanshee && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ clean) \
+ || exit 1
+
+
+.PHONY: maybe-distclean-libbanshee distclean-libbanshee
+maybe-distclean-libbanshee:
+
+distclean-libbanshee:
+ @[ -f ./libbanshee/Makefile ] || exit 0; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ for flag in $(EXTRA_HOST_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ echo "Doing distclean in libbanshee" ; \
+ (cd libbanshee && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ distclean) \
+ || exit 1
+
+
+.PHONY: maybe-maintainer-clean-libbanshee maintainer-clean-libbanshee
+maybe-maintainer-clean-libbanshee:
+
+maintainer-clean-libbanshee:
+ @[ -f ./libbanshee/Makefile ] || exit 0; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ for flag in $(EXTRA_HOST_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ echo "Doing maintainer-clean in libbanshee" ; \
+ (cd libbanshee && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ maintainer-clean) \
+ || exit 1
+
+
+
.PHONY: configure-libiberty maybe-configure-libiberty
maybe-configure-libiberty:
configure-libiberty:
@@ -10468,6 +10879,7 @@ configure-libiberty:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -10733,6 +11145,7 @@ configure-libtool:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -10998,6 +11411,7 @@ configure-m4:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -11263,6 +11677,7 @@ configure-make:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -11528,6 +11943,7 @@ configure-mmalloc:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -11789,6 +12205,7 @@ configure-patch:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -12054,6 +12471,7 @@ configure-perl:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -12319,6 +12737,7 @@ configure-prms:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -12584,6 +13003,7 @@ configure-rcs:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -12849,6 +13269,7 @@ configure-readline:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -13114,6 +13535,7 @@ configure-release:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -13371,6 +13793,7 @@ configure-recode:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -13636,6 +14059,7 @@ configure-sed:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -13901,6 +14325,7 @@ configure-send-pr:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -14166,6 +14591,7 @@ configure-shellutils:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -14431,6 +14857,7 @@ configure-sid:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -14696,6 +15123,7 @@ configure-sim:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -14961,6 +15389,7 @@ configure-tar:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -15226,6 +15655,7 @@ configure-texinfo:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -15487,6 +15917,7 @@ configure-textutils:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -15752,6 +16183,7 @@ configure-time:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -16017,6 +16449,7 @@ configure-uudecode:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -16282,6 +16715,7 @@ configure-wdiff:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -16547,6 +16981,7 @@ configure-zip:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -16815,6 +17250,7 @@ configure-zlib:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -17072,6 +17508,7 @@ configure-gdb:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -17337,6 +17774,7 @@ configure-expect:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -17602,6 +18040,7 @@ configure-guile:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -17867,6 +18306,7 @@ configure-tk:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -18132,6 +18572,7 @@ configure-tix:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -18397,6 +18838,7 @@ configure-libtermcap:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -18602,6 +19044,7 @@ configure-utils:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -18876,6 +19319,7 @@ configure-target-libstdc++-v3: $(TARGET_SUBDIR)/libstdc++-v3/multilib.out
CXX="$(RAW_CXX_FOR_TARGET)"; export CXX; \
CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
GCJ="$(GCJ_FOR_TARGET)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_TARGET)"; export GFORTRAN; \
DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
LD="$(LD_FOR_TARGET)"; export LD; \
LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
@@ -19130,6 +19574,285 @@ maintainer-clean-target-libstdc++-v3:
+.PHONY: configure-target-libmudflap maybe-configure-target-libmudflap
+maybe-configure-target-libmudflap:
+
+# There's only one multilib.out. Cleverer subdirs shouldn't need it copied.
+$(TARGET_SUBDIR)/libmudflap/multilib.out: multilib.out
+ $(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libmudflap ; \
+ rm -f $(TARGET_SUBDIR)/libmudflap/Makefile || : ; \
+ cp multilib.out $(TARGET_SUBDIR)/libmudflap/multilib.out
+
+configure-target-libmudflap: $(TARGET_SUBDIR)/libmudflap/multilib.out
+ @test ! -f $(TARGET_SUBDIR)/libmudflap/Makefile || exit 0; \
+ $(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libmudflap ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ AR="$(AR_FOR_TARGET)"; export AR; \
+ AS="$(AS_FOR_TARGET)"; export AS; \
+ CC="$(CC_FOR_TARGET)"; export CC; \
+ CFLAGS="$(CFLAGS_FOR_TARGET)"; export CFLAGS; \
+ CONFIG_SHELL="$(SHELL)"; export CONFIG_SHELL; \
+ CPPFLAGS="$(CFLAGS_FOR_TARGET)"; export CPPFLAGS; \
+ CXX="$(CXX_FOR_TARGET)"; export CXX; \
+ CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
+ GCJ="$(GCJ_FOR_TARGET)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_TARGET)"; export GFORTRAN; \
+ DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
+ LD="$(LD_FOR_TARGET)"; export LD; \
+ LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
+ NM="$(NM_FOR_TARGET)"; export NM; \
+ RANLIB="$(RANLIB_FOR_TARGET)"; export RANLIB; \
+ WINDRES="$(WINDRES_FOR_TARGET)"; export WINDRES; \
+ echo Configuring in $(TARGET_SUBDIR)/libmudflap; \
+ cd "$(TARGET_SUBDIR)/libmudflap" || exit 1; \
+ case $(srcdir) in \
+ /* | [A-Za-z]:[\\/]*) \
+ topdir=$(srcdir) ;; \
+ *) \
+ case "$(TARGET_SUBDIR)" in \
+ .) topdir="../$(srcdir)" ;; \
+ *) topdir="../../$(srcdir)" ;; \
+ esac ;; \
+ esac; \
+ srcdiroption="--srcdir=$${topdir}/libmudflap"; \
+ libsrcdir="$$s/libmudflap"; \
+ rm -f no-such-file || : ; \
+ CONFIG_SITE=no-such-file $(SHELL) $${libsrcdir}/configure \
+ $(TARGET_CONFIGARGS) $${srcdiroption} \
+ --with-target-subdir="$(TARGET_SUBDIR)" \
+ || exit 1
+
+.PHONY: all-target-libmudflap maybe-all-target-libmudflap
+maybe-all-target-libmudflap:
+all-target-libmudflap: configure-target-libmudflap
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ (cd $(TARGET_SUBDIR)/libmudflap && \
+ $(MAKE) $(TARGET_FLAGS_TO_PASS) all)
+
+.PHONY: check-target-libmudflap maybe-check-target-libmudflap
+maybe-check-target-libmudflap:
+
+check-target-libmudflap:
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ (cd $(TARGET_SUBDIR)/libmudflap && \
+ $(MAKE) $(TARGET_FLAGS_TO_PASS) check)
+
+
+.PHONY: install-target-libmudflap maybe-install-target-libmudflap
+maybe-install-target-libmudflap:
+
+install-target-libmudflap: installdirs
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ (cd $(TARGET_SUBDIR)/libmudflap && \
+ $(MAKE) $(TARGET_FLAGS_TO_PASS) install)
+
+
+# Other targets (info, dvi, etc.)
+
+.PHONY: maybe-info-target-libmudflap info-target-libmudflap
+maybe-info-target-libmudflap:
+
+info-target-libmudflap: \
+ configure-target-libmudflap
+ @[ -f $(TARGET_SUBDIR)/libmudflap/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ echo "Doing info in $(TARGET_SUBDIR)/libmudflap" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libmudflap && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ info) \
+ || exit 1
+
+
+.PHONY: maybe-dvi-target-libmudflap dvi-target-libmudflap
+maybe-dvi-target-libmudflap:
+
+dvi-target-libmudflap: \
+ configure-target-libmudflap
+ @[ -f $(TARGET_SUBDIR)/libmudflap/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ echo "Doing dvi in $(TARGET_SUBDIR)/libmudflap" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libmudflap && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ dvi) \
+ || exit 1
+
+
+.PHONY: maybe-TAGS-target-libmudflap TAGS-target-libmudflap
+maybe-TAGS-target-libmudflap:
+
+TAGS-target-libmudflap: \
+ configure-target-libmudflap
+ @[ -f $(TARGET_SUBDIR)/libmudflap/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ echo "Doing TAGS in $(TARGET_SUBDIR)/libmudflap" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libmudflap && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ TAGS) \
+ || exit 1
+
+
+.PHONY: maybe-install-info-target-libmudflap install-info-target-libmudflap
+maybe-install-info-target-libmudflap:
+
+install-info-target-libmudflap: \
+ configure-target-libmudflap \
+ info-target-libmudflap
+ @[ -f $(TARGET_SUBDIR)/libmudflap/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ echo "Doing install-info in $(TARGET_SUBDIR)/libmudflap" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libmudflap && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ install-info) \
+ || exit 1
+
+
+.PHONY: maybe-installcheck-target-libmudflap installcheck-target-libmudflap
+maybe-installcheck-target-libmudflap:
+
+installcheck-target-libmudflap: \
+ configure-target-libmudflap
+ @[ -f $(TARGET_SUBDIR)/libmudflap/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ echo "Doing installcheck in $(TARGET_SUBDIR)/libmudflap" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libmudflap && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ installcheck) \
+ || exit 1
+
+
+.PHONY: maybe-mostlyclean-target-libmudflap mostlyclean-target-libmudflap
+maybe-mostlyclean-target-libmudflap:
+
+mostlyclean-target-libmudflap:
+ @[ -f $(TARGET_SUBDIR)/libmudflap/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ echo "Doing mostlyclean in $(TARGET_SUBDIR)/libmudflap" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libmudflap && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ mostlyclean) \
+ || exit 1
+
+
+.PHONY: maybe-clean-target-libmudflap clean-target-libmudflap
+maybe-clean-target-libmudflap:
+
+clean-target-libmudflap:
+ @[ -f $(TARGET_SUBDIR)/libmudflap/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ echo "Doing clean in $(TARGET_SUBDIR)/libmudflap" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libmudflap && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ clean) \
+ || exit 1
+
+
+.PHONY: maybe-distclean-target-libmudflap distclean-target-libmudflap
+maybe-distclean-target-libmudflap:
+
+distclean-target-libmudflap:
+ @[ -f $(TARGET_SUBDIR)/libmudflap/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ echo "Doing distclean in $(TARGET_SUBDIR)/libmudflap" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libmudflap && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ distclean) \
+ || exit 1
+
+
+.PHONY: maybe-maintainer-clean-target-libmudflap maintainer-clean-target-libmudflap
+maybe-maintainer-clean-target-libmudflap:
+
+maintainer-clean-target-libmudflap:
+ @[ -f $(TARGET_SUBDIR)/libmudflap/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ echo "Doing maintainer-clean in $(TARGET_SUBDIR)/libmudflap" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libmudflap && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ maintainer-clean) \
+ || exit 1
+
+
+
.PHONY: configure-target-newlib maybe-configure-target-newlib
maybe-configure-target-newlib:
@@ -19154,6 +19877,7 @@ configure-target-newlib: $(TARGET_SUBDIR)/newlib/multilib.out
CXX="$(CXX_FOR_TARGET)"; export CXX; \
CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
GCJ="$(GCJ_FOR_TARGET)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_TARGET)"; export GFORTRAN; \
DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
LD="$(LD_FOR_TARGET)"; export LD; \
LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
@@ -19432,6 +20156,7 @@ configure-target-libf2c: $(TARGET_SUBDIR)/libf2c/multilib.out
CXX="$(CXX_FOR_TARGET)"; export CXX; \
CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
GCJ="$(GCJ_FOR_TARGET)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_TARGET)"; export GFORTRAN; \
DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
LD="$(LD_FOR_TARGET)"; export LD; \
LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
@@ -19686,6 +20411,285 @@ maintainer-clean-target-libf2c:
+.PHONY: configure-target-libgfortran maybe-configure-target-libgfortran
+maybe-configure-target-libgfortran:
+
+# There's only one multilib.out. Cleverer subdirs shouldn't need it copied.
+$(TARGET_SUBDIR)/libgfortran/multilib.out: multilib.out
+ $(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libgfortran ; \
+ rm -f $(TARGET_SUBDIR)/libgfortran/Makefile || : ; \
+ cp multilib.out $(TARGET_SUBDIR)/libgfortran/multilib.out
+
+configure-target-libgfortran: $(TARGET_SUBDIR)/libgfortran/multilib.out
+ @test ! -f $(TARGET_SUBDIR)/libgfortran/Makefile || exit 0; \
+ $(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libgfortran ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ AR="$(AR_FOR_TARGET)"; export AR; \
+ AS="$(AS_FOR_TARGET)"; export AS; \
+ CC="$(CC_FOR_TARGET)"; export CC; \
+ CFLAGS="$(CFLAGS_FOR_TARGET)"; export CFLAGS; \
+ CONFIG_SHELL="$(SHELL)"; export CONFIG_SHELL; \
+ CPPFLAGS="$(CFLAGS_FOR_TARGET)"; export CPPFLAGS; \
+ CXX="$(CXX_FOR_TARGET)"; export CXX; \
+ CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
+ GCJ="$(GCJ_FOR_TARGET)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_TARGET)"; export GFORTRAN; \
+ DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
+ LD="$(LD_FOR_TARGET)"; export LD; \
+ LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
+ NM="$(NM_FOR_TARGET)"; export NM; \
+ RANLIB="$(RANLIB_FOR_TARGET)"; export RANLIB; \
+ WINDRES="$(WINDRES_FOR_TARGET)"; export WINDRES; \
+ echo Configuring in $(TARGET_SUBDIR)/libgfortran; \
+ cd "$(TARGET_SUBDIR)/libgfortran" || exit 1; \
+ case $(srcdir) in \
+ /* | [A-Za-z]:[\\/]*) \
+ topdir=$(srcdir) ;; \
+ *) \
+ case "$(TARGET_SUBDIR)" in \
+ .) topdir="../$(srcdir)" ;; \
+ *) topdir="../../$(srcdir)" ;; \
+ esac ;; \
+ esac; \
+ srcdiroption="--srcdir=$${topdir}/libgfortran"; \
+ libsrcdir="$$s/libgfortran"; \
+ rm -f no-such-file || : ; \
+ CONFIG_SITE=no-such-file $(SHELL) $${libsrcdir}/configure \
+ $(TARGET_CONFIGARGS) $${srcdiroption} \
+ --with-target-subdir="$(TARGET_SUBDIR)" \
+ || exit 1
+
+.PHONY: all-target-libgfortran maybe-all-target-libgfortran
+maybe-all-target-libgfortran:
+all-target-libgfortran: configure-target-libgfortran
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ (cd $(TARGET_SUBDIR)/libgfortran && \
+ $(MAKE) $(TARGET_FLAGS_TO_PASS) all)
+
+.PHONY: check-target-libgfortran maybe-check-target-libgfortran
+maybe-check-target-libgfortran:
+
+check-target-libgfortran:
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ (cd $(TARGET_SUBDIR)/libgfortran && \
+ $(MAKE) $(TARGET_FLAGS_TO_PASS) check)
+
+
+.PHONY: install-target-libgfortran maybe-install-target-libgfortran
+maybe-install-target-libgfortran:
+
+install-target-libgfortran: installdirs
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ (cd $(TARGET_SUBDIR)/libgfortran && \
+ $(MAKE) $(TARGET_FLAGS_TO_PASS) install)
+
+
+# Other targets (info, dvi, etc.)
+
+.PHONY: maybe-info-target-libgfortran info-target-libgfortran
+maybe-info-target-libgfortran:
+
+info-target-libgfortran: \
+ configure-target-libgfortran
+ @[ -f $(TARGET_SUBDIR)/libgfortran/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ echo "Doing info in $(TARGET_SUBDIR)/libgfortran" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libgfortran && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ info) \
+ || exit 1
+
+
+.PHONY: maybe-dvi-target-libgfortran dvi-target-libgfortran
+maybe-dvi-target-libgfortran:
+
+dvi-target-libgfortran: \
+ configure-target-libgfortran
+ @[ -f $(TARGET_SUBDIR)/libgfortran/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ echo "Doing dvi in $(TARGET_SUBDIR)/libgfortran" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libgfortran && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ dvi) \
+ || exit 1
+
+
+.PHONY: maybe-TAGS-target-libgfortran TAGS-target-libgfortran
+maybe-TAGS-target-libgfortran:
+
+TAGS-target-libgfortran: \
+ configure-target-libgfortran
+ @[ -f $(TARGET_SUBDIR)/libgfortran/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ echo "Doing TAGS in $(TARGET_SUBDIR)/libgfortran" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libgfortran && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ TAGS) \
+ || exit 1
+
+
+.PHONY: maybe-install-info-target-libgfortran install-info-target-libgfortran
+maybe-install-info-target-libgfortran:
+
+install-info-target-libgfortran: \
+ configure-target-libgfortran \
+ info-target-libgfortran
+ @[ -f $(TARGET_SUBDIR)/libgfortran/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ echo "Doing install-info in $(TARGET_SUBDIR)/libgfortran" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libgfortran && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ install-info) \
+ || exit 1
+
+
+.PHONY: maybe-installcheck-target-libgfortran installcheck-target-libgfortran
+maybe-installcheck-target-libgfortran:
+
+installcheck-target-libgfortran: \
+ configure-target-libgfortran
+ @[ -f $(TARGET_SUBDIR)/libgfortran/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ echo "Doing installcheck in $(TARGET_SUBDIR)/libgfortran" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libgfortran && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ installcheck) \
+ || exit 1
+
+
+.PHONY: maybe-mostlyclean-target-libgfortran mostlyclean-target-libgfortran
+maybe-mostlyclean-target-libgfortran:
+
+mostlyclean-target-libgfortran:
+ @[ -f $(TARGET_SUBDIR)/libgfortran/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ echo "Doing mostlyclean in $(TARGET_SUBDIR)/libgfortran" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libgfortran && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ mostlyclean) \
+ || exit 1
+
+
+.PHONY: maybe-clean-target-libgfortran clean-target-libgfortran
+maybe-clean-target-libgfortran:
+
+clean-target-libgfortran:
+ @[ -f $(TARGET_SUBDIR)/libgfortran/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ echo "Doing clean in $(TARGET_SUBDIR)/libgfortran" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libgfortran && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ clean) \
+ || exit 1
+
+
+.PHONY: maybe-distclean-target-libgfortran distclean-target-libgfortran
+maybe-distclean-target-libgfortran:
+
+distclean-target-libgfortran:
+ @[ -f $(TARGET_SUBDIR)/libgfortran/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ echo "Doing distclean in $(TARGET_SUBDIR)/libgfortran" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libgfortran && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ distclean) \
+ || exit 1
+
+
+.PHONY: maybe-maintainer-clean-target-libgfortran maintainer-clean-target-libgfortran
+maybe-maintainer-clean-target-libgfortran:
+
+maintainer-clean-target-libgfortran:
+ @[ -f $(TARGET_SUBDIR)/libgfortran/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(SET_LIB_PATH) \
+ echo "Doing maintainer-clean in $(TARGET_SUBDIR)/libgfortran" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libgfortran && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+ maintainer-clean) \
+ || exit 1
+
+
+
.PHONY: configure-target-libobjc maybe-configure-target-libobjc
maybe-configure-target-libobjc:
@@ -19710,6 +20714,7 @@ configure-target-libobjc: $(TARGET_SUBDIR)/libobjc/multilib.out
CXX="$(CXX_FOR_TARGET)"; export CXX; \
CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
GCJ="$(GCJ_FOR_TARGET)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_TARGET)"; export GFORTRAN; \
DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
LD="$(LD_FOR_TARGET)"; export LD; \
LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
@@ -19988,6 +20993,7 @@ configure-target-libtermcap: $(TARGET_SUBDIR)/libtermcap/multilib.out
CXX="$(CXX_FOR_TARGET)"; export CXX; \
CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
GCJ="$(GCJ_FOR_TARGET)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_TARGET)"; export GFORTRAN; \
DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
LD="$(LD_FOR_TARGET)"; export LD; \
LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
@@ -20228,6 +21234,7 @@ configure-target-winsup: $(TARGET_SUBDIR)/winsup/multilib.out
CXX="$(CXX_FOR_TARGET)"; export CXX; \
CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
GCJ="$(GCJ_FOR_TARGET)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_TARGET)"; export GFORTRAN; \
DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
LD="$(LD_FOR_TARGET)"; export LD; \
LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
@@ -20506,6 +21513,7 @@ configure-target-libgloss: $(TARGET_SUBDIR)/libgloss/multilib.out
CXX="$(CXX_FOR_TARGET)"; export CXX; \
CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
GCJ="$(GCJ_FOR_TARGET)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_TARGET)"; export GFORTRAN; \
DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
LD="$(LD_FOR_TARGET)"; export LD; \
LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
@@ -20780,6 +21788,7 @@ configure-target-libiberty: $(TARGET_SUBDIR)/libiberty/multilib.out
CXX="$(CXX_FOR_TARGET)"; export CXX; \
CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
GCJ="$(GCJ_FOR_TARGET)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_TARGET)"; export GFORTRAN; \
DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
LD="$(LD_FOR_TARGET)"; export LD; \
LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
@@ -21058,6 +22067,7 @@ configure-target-gperf: $(TARGET_SUBDIR)/gperf/multilib.out
CXX="$(CXX_FOR_TARGET)"; export CXX; \
CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
GCJ="$(GCJ_FOR_TARGET)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_TARGET)"; export GFORTRAN; \
DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
LD="$(LD_FOR_TARGET)"; export LD; \
LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
@@ -21336,6 +22346,7 @@ configure-target-examples: $(TARGET_SUBDIR)/examples/multilib.out
CXX="$(CXX_FOR_TARGET)"; export CXX; \
CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
GCJ="$(GCJ_FOR_TARGET)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_TARGET)"; export GFORTRAN; \
DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
LD="$(LD_FOR_TARGET)"; export LD; \
LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
@@ -21606,6 +22617,7 @@ configure-target-libffi: $(TARGET_SUBDIR)/libffi/multilib.out
CXX="$(CXX_FOR_TARGET)"; export CXX; \
CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
GCJ="$(GCJ_FOR_TARGET)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_TARGET)"; export GFORTRAN; \
DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
LD="$(LD_FOR_TARGET)"; export LD; \
LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
@@ -21885,6 +22897,7 @@ configure-target-libjava: $(TARGET_SUBDIR)/libjava/multilib.out
CXX="$(RAW_CXX_FOR_TARGET)"; export CXX; \
CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
GCJ="$(GCJ_FOR_TARGET)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_TARGET)"; export GFORTRAN; \
DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
LD="$(LD_FOR_TARGET)"; export LD; \
LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
@@ -22163,6 +23176,7 @@ configure-target-zlib: $(TARGET_SUBDIR)/zlib/multilib.out
CXX="$(CXX_FOR_TARGET)"; export CXX; \
CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
GCJ="$(GCJ_FOR_TARGET)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_TARGET)"; export GFORTRAN; \
DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
LD="$(LD_FOR_TARGET)"; export LD; \
LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
@@ -22463,6 +23477,7 @@ configure-target-boehm-gc: $(TARGET_SUBDIR)/boehm-gc/multilib.out
CXX="$(CXX_FOR_TARGET)"; export CXX; \
CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
GCJ="$(GCJ_FOR_TARGET)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_TARGET)"; export GFORTRAN; \
DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
LD="$(LD_FOR_TARGET)"; export LD; \
LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
@@ -22741,6 +23756,7 @@ configure-target-qthreads: $(TARGET_SUBDIR)/qthreads/multilib.out
CXX="$(CXX_FOR_TARGET)"; export CXX; \
CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
GCJ="$(GCJ_FOR_TARGET)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_TARGET)"; export GFORTRAN; \
DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
LD="$(LD_FOR_TARGET)"; export LD; \
LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
@@ -23019,6 +24035,7 @@ configure-target-rda: $(TARGET_SUBDIR)/rda/multilib.out
CXX="$(CXX_FOR_TARGET)"; export CXX; \
CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
GCJ="$(GCJ_FOR_TARGET)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_TARGET)"; export GFORTRAN; \
DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
LD="$(LD_FOR_TARGET)"; export LD; \
LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
@@ -23297,6 +24314,7 @@ configure-target-libada: $(TARGET_SUBDIR)/libada/multilib.out
CXX="$(CXX_FOR_TARGET)"; export CXX; \
CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
GCJ="$(GCJ_FOR_TARGET)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_TARGET)"; export GFORTRAN; \
DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
LD="$(LD_FOR_TARGET)"; export LD; \
LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
@@ -23585,11 +24603,14 @@ configure-gcc:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
OBJCOPY="$(OBJCOPY)"; export OBJCOPY; \
OBJDUMP="$(OBJDUMP)"; export OBJDUMP; \
+ GMPLIBS="$(HOST_GMPLIBS)"; export GMPLIBS; \
+ GMPINC="$(HOST_GMPINC)"; export GMPINC; \
echo Configuring in gcc; \
cd gcc || exit 1; \
case $(srcdir) in \
@@ -24007,6 +25028,7 @@ configure-stage1-gcc:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -24046,11 +25068,11 @@ all-stage1-gcc: configure-stage1-gcc prebootstrap
mv stage1-gcc gcc ; \
cd gcc && \
$(MAKE) $(GCC_FLAGS_TO_PASS) \
- CFLAGS="$(STAGE1_CFLAGS)" \
- || exit 1 ; \
+ CFLAGS="$(STAGE1_CFLAGS)" && $(STAMP) ../all-stage1-gcc ; \
+ result=$$? ; \
cd .. ; \
mv gcc stage1-gcc ; \
- $(STAMP) all-stage1-gcc
+ exit $$result
# TODO: Deal with STAGE_PREFIX (which is only for ada, incidentally)
# Possibly pass --enable-werror-always (depending on --enable-werror);
@@ -24077,6 +25099,7 @@ configure-stage2-gcc: all-stage1-gcc
AS="$(AS)"; export AS; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -24121,11 +25144,12 @@ all-stage2-gcc: all-stage1-gcc configure-stage2-gcc
CC="$(STAGE_CC_WRAPPER) $$r/prev-gcc/xgcc$(exeext) -B$$r/prev-gcc/ -B$(build_tooldir)/bin/" \
CC_FOR_BUILD="$(STAGE_CC_WRAPPER) $$r/prev-gcc/xgcc$(exeext) -B$$r/prev-gcc/ -B$(build_tooldir)/bin/" \
STAGE_PREFIX=$$r/prev-gcc/ \
- $(POSTSTAGE1_FLAGS_TO_PASS) || exit 1 ; \
+ $(POSTSTAGE1_FLAGS_TO_PASS) && $(STAMP) ../all-stage2-gcc ; \
+ result=$$? ; \
cd .. ; \
mv prev-gcc stage1-gcc ; \
mv gcc stage2-gcc ; \
- $(STAMP) all-stage2-gcc
+ exit $$result
configure-stage3-gcc: all-stage2-gcc
echo configure-stage3-gcc > stage_last ; \
@@ -24149,6 +25173,7 @@ configure-stage3-gcc: all-stage2-gcc
AS="$(AS)"; export AS; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -24187,11 +25212,12 @@ all-stage3-gcc: all-stage2-gcc configure-stage3-gcc
CC="$(STAGE_CC_WRAPPER) $$r/prev-gcc/xgcc$(exeext) -B$$r/prev-gcc/ -B$(build_tooldir)/bin/" \
CC_FOR_BUILD="$(STAGE_CC_WRAPPER) $$r/prev-gcc/xgcc$(exeext) -B$$r/prev-gcc/ -B$(build_tooldir)/bin/" \
STAGE_PREFIX=$$r/prev-gcc/ \
- $(POSTSTAGE1_FLAGS_TO_PASS) || exit 1 ; \
+ $(POSTSTAGE1_FLAGS_TO_PASS) && $(STAMP) ../all-stage3-gcc \
+ result=$$? ; \
cd .. ; \
mv prev-gcc stage2-gcc ; \
mv gcc stage3-gcc ; \
- $(STAMP) all-stage3-gcc
+ exit $$result
# We only want to compare .o files, so set this!
objext = .o
@@ -24204,8 +25230,8 @@ compare: all-stage3-gcc
files=`find . -name "*$(objext)" -print` ; \
cd .. ; \
for file in $${files} ; do \
- cmp --ignore-initial=16 $$r/stage2-gcc/$$file $$r/stage3-gcc/$$file \
- > /dev/null 2>&1; \
+ f1=$$r/stage2-gcc/$$file; f2=$$r/stage3-gcc/$$file; \
+ @do_compare@ > /dev/null 2>&1; \
test $$? -eq 1 && echo $$file differs >> .bad_compare || true; \
done ; \
if [ -f .bad_compare ]; then \
@@ -24226,6 +25252,30 @@ new-bootstrap: compare
$(MAKE) all ; \
mv gcc stage3-gcc
+new-cleanstrap:
+ rm -rf configure-stage1-gcc all-stage1-gcc stage1-gcc \
+ configure-stage2-gcc all-stage2-gcc stage2-gcc \
+ configure-stage3-gcc all-stage3-gcc stage3-gcc \
+ compare
+ $(MAKE) new-bootstrap
+
+new-restage1:
+ rm -rf all-stage1-gcc \
+ configure-stage2-gcc all-stage2-gcc stage2-gcc \
+ configure-stage3-gcc all-stage3-gcc stage3-gcc \
+ compare
+ $(MAKE) all-stage1-gcc
+
+new-restage2: all-stage1-gcc
+ rm -rf all-stage2-gcc \
+ configure-stage3-gcc all-stage3-gcc stage3-gcc \
+ compare
+ $(MAKE) all-stage2-gcc
+
+new-restage3: all-stage2-gcc
+ rm -rf all-stage3-gcc compare
+ $(MAKE) compare
+
# --------------------------------------
# Dependencies between different modules
# --------------------------------------
@@ -24241,11 +25291,11 @@ new-bootstrap: compare
# GCC needs to identify certain tools.
# GCC also needs the information exported by the intl configure script.
configure-gcc: maybe-configure-intl maybe-configure-binutils maybe-configure-gas maybe-configure-ld maybe-configure-bison maybe-configure-flex
-all-gcc: maybe-all-libiberty maybe-all-intl maybe-all-bison maybe-all-byacc maybe-all-binutils maybe-all-gas maybe-all-ld maybe-all-zlib
+all-gcc: maybe-all-libiberty maybe-all-intl maybe-all-bison maybe-all-byacc maybe-all-binutils maybe-all-gas maybe-all-ld maybe-all-zlib maybe-all-libbanshee
# This is a slightly kludgy method of getting dependencies on
# all-build-libiberty correct; it would be better to build it every time.
-all-gcc: maybe-all-build-libiberty
-all-bootstrap: maybe-all-libiberty maybe-all-intl maybe-all-texinfo maybe-all-bison maybe-all-byacc maybe-all-binutils maybe-all-gas maybe-all-ld maybe-all-zlib
+all-gcc: maybe-all-build-libiberty maybe-all-libbanshee
+all-bootstrap: maybe-all-binutils maybe-all-bison maybe-all-byacc maybe-all-gas maybe-all-intl maybe-all-ld maybe-all-libbanshee maybe-all-libiberty maybe-all-texinfo maybe-all-zlib
# Host modules specific to gdb.
# GDB needs to know that the simulator is being built.
@@ -24320,6 +25370,7 @@ all-target-fastjar: maybe-all-target-zlib maybe-all-target-libiberty
configure-target-libada: $(ALL_GCC_C)
configure-target-libf2c: $(ALL_GCC_C)
all-target-libf2c: maybe-all-target-libiberty
+configure-target-libgfortran: $(ALL_GCC_C)
configure-target-libffi: $(ALL_GCC_C)
configure-target-libjava: $(ALL_GCC_C) maybe-configure-target-zlib maybe-configure-target-boehm-gc maybe-configure-target-qthreads maybe-configure-target-libffi
all-target-libjava: maybe-all-fastjar maybe-all-target-zlib maybe-all-target-boehm-gc maybe-all-target-qthreads maybe-all-target-libffi
diff --git a/Makefile.tpl b/Makefile.tpl
index e52f7096bdf..a8515bd6d56 100644
--- a/Makefile.tpl
+++ b/Makefile.tpl
@@ -105,7 +105,7 @@ REALLY_SET_LIB_PATH = \
$(RPATH_ENVVAR)=`echo "$(HOST_LIB_PATH):$(TARGET_LIB_PATH):$$$(RPATH_ENVVAR)" | sed 's,::*,:,g;s,^:*,,;s,:*$$,,'`; export $(RPATH_ENVVAR);
# This is the list of directories to be built for the build system.
-BUILD_CONFIGDIRS = libiberty
+BUILD_CONFIGDIRS = libiberty libbanshee
# Build programs are put under this directory.
BUILD_SUBDIR = @build_subdir@
# This is set by the configure script to the arguments to use when configuring
@@ -127,6 +127,10 @@ TARGET_SUBDIR = @target_subdir@
# directories built for the target.
TARGET_CONFIGARGS = @target_configargs@
+# Where to find GMP
+HOST_GMPLIBS = @gmplibs@
+HOST_GMPINC = @gmpinc@
+
# ----------------------------------------------
# Programs producing files for the BUILD machine
# ----------------------------------------------
@@ -244,7 +248,7 @@ PICFLAG =
# This is the list of directories that may be needed in RPATH_ENVVAR
# so that prorgams built for the target machine work.
-TARGET_LIB_PATH = $$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs:
+TARGET_LIB_PATH = $$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs:$$r/$(TARGET_SUBDIR)/libmudflap/.libs
FLAGS_FOR_TARGET = @FLAGS_FOR_TARGET@
@@ -311,6 +315,7 @@ USUAL_DLLTOOL_FOR_TARGET = ` \
fi`
GCJ_FOR_TARGET = @GCJ_FOR_TARGET@
+GFORTRAN_FOR_TARGET = @GFORTRAN_FOR_TARGET@
LD_FOR_TARGET=@LD_FOR_TARGET@
CONFIGURED_LD_FOR_TARGET=@CONFIGURED_LD_FOR_TARGET@
@@ -705,6 +710,7 @@ configure-build-[+module+]:
CXX="$(CXX_FOR_BUILD)"; export CXX; \
CXXFLAGS="$(CXXFLAGS_FOR_BUILD)"; export CXXFLAGS; \
GCJ="$(GCJ_FOR_BUILD)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_BUILD)"; export GFORTRAN; \
DLLTOOL="$(DLLTOOL_FOR_BUILD)"; export DLLTOOL; \
LD="$(LD_FOR_BUILD)"; export LD; \
LDFLAGS="$(LDFLAGS_FOR_BUILD)"; export LDFLAGS; \
@@ -781,6 +787,7 @@ configure-[+module+]:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -920,6 +927,7 @@ ELSE normal_cxx +]
ENDIF raw_cxx +]
CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
GCJ="$(GCJ_FOR_TARGET)"; export GCJ; \
+ GFORTRAN="$(GFORTRAN_FOR_TARGET)"; export GFORTRAN; \
DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
LD="$(LD_FOR_TARGET)"; export LD; \
LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
@@ -1076,11 +1084,14 @@ configure-gcc:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
OBJCOPY="$(OBJCOPY)"; export OBJCOPY; \
OBJDUMP="$(OBJDUMP)"; export OBJDUMP; \
+ GMPLIBS="$(HOST_GMPLIBS)"; export GMPLIBS; \
+ GMPINC="$(HOST_GMPINC)"; export GMPINC; \
echo Configuring in gcc; \
cd gcc || exit 1; \
case $(srcdir) in \
@@ -1335,6 +1346,7 @@ configure-stage1-gcc:
CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -1374,11 +1386,11 @@ all-stage1-gcc: configure-stage1-gcc prebootstrap
mv stage1-gcc gcc ; \
cd gcc && \
$(MAKE) $(GCC_FLAGS_TO_PASS) \
- CFLAGS="$(STAGE1_CFLAGS)" \
- || exit 1 ; \
+ CFLAGS="$(STAGE1_CFLAGS)" && $(STAMP) ../all-stage1-gcc ; \
+ result=$$? ; \
cd .. ; \
mv gcc stage1-gcc ; \
- $(STAMP) all-stage1-gcc
+ exit $$result
# TODO: Deal with STAGE_PREFIX (which is only for ada, incidentally)
# Possibly pass --enable-werror-always (depending on --enable-werror);
@@ -1405,6 +1417,7 @@ configure-stage2-gcc: all-stage1-gcc
AS="$(AS)"; export AS; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -1449,11 +1462,12 @@ all-stage2-gcc: all-stage1-gcc configure-stage2-gcc
CC="$(STAGE_CC_WRAPPER) $$r/prev-gcc/xgcc$(exeext) -B$$r/prev-gcc/ -B$(build_tooldir)/bin/" \
CC_FOR_BUILD="$(STAGE_CC_WRAPPER) $$r/prev-gcc/xgcc$(exeext) -B$$r/prev-gcc/ -B$(build_tooldir)/bin/" \
STAGE_PREFIX=$$r/prev-gcc/ \
- $(POSTSTAGE1_FLAGS_TO_PASS) || exit 1 ; \
+ $(POSTSTAGE1_FLAGS_TO_PASS) && $(STAMP) ../all-stage2-gcc ; \
+ result=$$? ; \
cd .. ; \
mv prev-gcc stage1-gcc ; \
mv gcc stage2-gcc ; \
- $(STAMP) all-stage2-gcc
+ exit $$result
configure-stage3-gcc: all-stage2-gcc
echo configure-stage3-gcc > stage_last ; \
@@ -1477,6 +1491,7 @@ configure-stage3-gcc: all-stage2-gcc
AS="$(AS)"; export AS; \
DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
LD="$(LD)"; export LD; \
+ LDFLAGS="$(LDFLAGS)"; export LDFLAGS; \
NM="$(NM)"; export NM; \
RANLIB="$(RANLIB)"; export RANLIB; \
WINDRES="$(WINDRES)"; export WINDRES; \
@@ -1515,11 +1530,12 @@ all-stage3-gcc: all-stage2-gcc configure-stage3-gcc
CC="$(STAGE_CC_WRAPPER) $$r/prev-gcc/xgcc$(exeext) -B$$r/prev-gcc/ -B$(build_tooldir)/bin/" \
CC_FOR_BUILD="$(STAGE_CC_WRAPPER) $$r/prev-gcc/xgcc$(exeext) -B$$r/prev-gcc/ -B$(build_tooldir)/bin/" \
STAGE_PREFIX=$$r/prev-gcc/ \
- $(POSTSTAGE1_FLAGS_TO_PASS) || exit 1 ; \
+ $(POSTSTAGE1_FLAGS_TO_PASS) && $(STAMP) ../all-stage3-gcc \
+ result=$$? ; \
cd .. ; \
mv prev-gcc stage2-gcc ; \
mv gcc stage3-gcc ; \
- $(STAMP) all-stage3-gcc
+ exit $$result
# We only want to compare .o files, so set this!
objext = .o
@@ -1532,8 +1548,8 @@ compare: all-stage3-gcc
files=`find . -name "*$(objext)" -print` ; \
cd .. ; \
for file in $${files} ; do \
- cmp --ignore-initial=16 $$r/stage2-gcc/$$file $$r/stage3-gcc/$$file \
- > /dev/null 2>&1; \
+ f1=$$r/stage2-gcc/$$file; f2=$$r/stage3-gcc/$$file; \
+ @do_compare@ > /dev/null 2>&1; \
test $$? -eq 1 && echo $$file differs >> .bad_compare || true; \
done ; \
if [ -f .bad_compare ]; then \
@@ -1554,6 +1570,30 @@ new-bootstrap: compare
$(MAKE) all ; \
mv gcc stage3-gcc
+new-cleanstrap:
+ rm -rf configure-stage1-gcc all-stage1-gcc stage1-gcc \
+ configure-stage2-gcc all-stage2-gcc stage2-gcc \
+ configure-stage3-gcc all-stage3-gcc stage3-gcc \
+ compare
+ $(MAKE) new-bootstrap
+
+new-restage1:
+ rm -rf all-stage1-gcc \
+ configure-stage2-gcc all-stage2-gcc stage2-gcc \
+ configure-stage3-gcc all-stage3-gcc stage3-gcc \
+ compare
+ $(MAKE) all-stage1-gcc
+
+new-restage2: all-stage1-gcc
+ rm -rf all-stage2-gcc \
+ configure-stage3-gcc all-stage3-gcc stage3-gcc \
+ compare
+ $(MAKE) all-stage2-gcc
+
+new-restage3: all-stage2-gcc
+ rm -rf all-stage3-gcc compare
+ $(MAKE) compare
+
# --------------------------------------
# Dependencies between different modules
# --------------------------------------
@@ -1569,11 +1609,11 @@ new-bootstrap: compare
# GCC needs to identify certain tools.
# GCC also needs the information exported by the intl configure script.
configure-gcc: maybe-configure-intl maybe-configure-binutils maybe-configure-gas maybe-configure-ld maybe-configure-bison maybe-configure-flex
-all-gcc: maybe-all-libiberty maybe-all-intl maybe-all-bison maybe-all-byacc maybe-all-binutils maybe-all-gas maybe-all-ld maybe-all-zlib
+all-gcc: maybe-all-libiberty maybe-all-intl maybe-all-bison maybe-all-byacc maybe-all-binutils maybe-all-gas maybe-all-ld maybe-all-zlib maybe-all-libbanshee
# This is a slightly kludgy method of getting dependencies on
# all-build-libiberty correct; it would be better to build it every time.
-all-gcc: maybe-all-build-libiberty
-all-bootstrap: maybe-all-libiberty maybe-all-intl maybe-all-texinfo maybe-all-bison maybe-all-byacc maybe-all-binutils maybe-all-gas maybe-all-ld maybe-all-zlib
+all-gcc: maybe-all-build-libiberty maybe-all-libbanshee
+all-bootstrap: [+ FOR host_modules +][+ IF bootstrap +]maybe-all-[+module+] [+ ENDIF bootstrap +][+ ENDFOR host_modules +]
# Host modules specific to gdb.
# GDB needs to know that the simulator is being built.
@@ -1648,6 +1688,7 @@ all-target-fastjar: maybe-all-target-zlib maybe-all-target-libiberty
configure-target-libada: $(ALL_GCC_C)
configure-target-libf2c: $(ALL_GCC_C)
all-target-libf2c: maybe-all-target-libiberty
+configure-target-libgfortran: $(ALL_GCC_C)
configure-target-libffi: $(ALL_GCC_C)
configure-target-libjava: $(ALL_GCC_C) maybe-configure-target-zlib maybe-configure-target-boehm-gc maybe-configure-target-qthreads maybe-configure-target-libffi
all-target-libjava: maybe-all-fastjar maybe-all-target-zlib maybe-all-target-boehm-gc maybe-all-target-qthreads maybe-all-target-libffi
diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog
index 182fef1cab3..8195dd2dbc3 100644
--- a/boehm-gc/ChangeLog
+++ b/boehm-gc/ChangeLog
@@ -1,3 +1,7 @@
+2004-04-25 Andreas Jaeger <aj@suse.de>
+
+ * mark.c (GC_mark_from): Use pointer as prefetch argument.
+
2004-04-06 H.J. Lu <hongjiu.lu@intel.com>
* include/private/gcconfig.h (PREFETCH): Use __builtin_prefetch
diff --git a/boehm-gc/mark.c b/boehm-gc/mark.c
index ca947290291..fffd62ac90c 100644
--- a/boehm-gc/mark.c
+++ b/boehm-gc/mark.c
@@ -684,7 +684,7 @@ mse * mark_stack_limit;
current = *current_p;
FIXUP_POINTER(current);
if ((ptr_t)current >= least_ha && (ptr_t)current < greatest_ha) {
- PREFETCH(current);
+ PREFETCH((ptr_t)current);
HC_PUSH_CONTENTS((ptr_t)current, mark_stack_top,
mark_stack_limit, current_p, exit1);
}
@@ -760,7 +760,7 @@ mse * mark_stack_limit;
FIXUP_POINTER(deferred);
limit = (word *)((char *)limit - ALIGNMENT);
if ((ptr_t)deferred >= least_ha && (ptr_t)deferred < greatest_ha) {
- PREFETCH(deferred);
+ PREFETCH((ptr_t)deferred);
break;
}
if (current_p > limit) goto next_object;
@@ -770,7 +770,7 @@ mse * mark_stack_limit;
FIXUP_POINTER(deferred);
limit = (word *)((char *)limit - ALIGNMENT);
if ((ptr_t)deferred >= least_ha && (ptr_t)deferred < greatest_ha) {
- PREFETCH(deferred);
+ PREFETCH((ptr_t)deferred);
break;
}
if (current_p > limit) goto next_object;
@@ -787,7 +787,7 @@ mse * mark_stack_limit;
if ((ptr_t)current >= least_ha && (ptr_t)current < greatest_ha) {
/* Prefetch the contents of the object we just pushed. It's */
/* likely we will need them soon. */
- PREFETCH(current);
+ PREFETCH((ptr_t)current);
HC_PUSH_CONTENTS((ptr_t)current, mark_stack_top,
mark_stack_limit, current_p, exit2);
}
diff --git a/config/ChangeLog b/config/ChangeLog
index 7a970b70993..fe845783b5c 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,9 @@
+2004-04-16 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * acx.m4 (ACX_PROG_GNAT): Check if ${CC} produces object file for
+ Ada compilation.
+ Fix acx_cv_cc_gcc_supports_ada spelling.
+
2004-03-08 Paolo Bonzini <bonzini@gnu.org>
PR ada/14131
diff --git a/config/acx.m4 b/config/acx.m4
index ab7f98a216c..3652836bb8d 100644
--- a/config/acx.m4
+++ b/config/acx.m4
@@ -177,16 +177,50 @@ acx_cv_cc_gcc_supports_ada=no
# has not been installed. This is fixed in 2.95.4, 3.0.2, and 3.1.
# Therefore we must check for the error message as well as an
# unsuccessful exit.
+# Other compilers, like HP Tru64 UNIX cc, exit successfully when
+# given a .adb file, but produce no object file. So we must check
+# if an object file was really produced to guard against this.
errors=`(${CC} -c conftest.adb) 2>&1 || echo failure`
-if test x"$errors" = x; then
+if test x"$errors" = x && test -f conftest.$ac_objext; then
acx_cv_cc_gcc_supports_ada=yes
break
fi
rm -f conftest.*])
-if test x$GNATBIND != xno && test x$acx_cv_gcc_supports_ada != xno; then
+if test x$GNATBIND != xno && test x$acx_cv_cc_gcc_supports_ada != xno; then
have_gnat=yes
else
have_gnat=no
fi
])
+
+dnl 'make compare' can be significantly faster, if cmp itself can
+dnl skip bytes instead of using tail. The test being performed is
+dnl "if cmp --ignore-initial=2 t1 t2 && ! cmp --ignore-initial=1 t1 t2"
+dnl but we need to sink errors and handle broken shells. We also test
+dnl for the parameter format "cmp file1 file2 skip1 skip2" which is
+dnl accepted by cmp on some systems.
+AC_DEFUN([ACX_PROG_CMP_IGNORE_INITIAL],
+[AC_CACHE_CHECK([how to compare bootstrapped objects], gcc_cv_prog_cmp_skip,
+[ echo abfoo >t1
+ echo cdfoo >t2
+ gcc_cv_prog_cmp_skip='tail +16c $$f1 > tmp-foo1; tail +16c $$f2 > tmp-foo2; cmp tmp-foo1 tmp-foo2'
+ if cmp t1 t2 2 2 > /dev/null 2>&1; then
+ if cmp t1 t2 1 1 > /dev/null 2>&1; then
+ :
+ else
+ gcc_cv_prog_cmp_skip='cmp $$f1 $$f2 16 16'
+ fi
+ fi
+ if cmp --ignore-initial=2 t1 t2 > /dev/null 2>&1; then
+ if cmp --ignore-initial=1 t1 t2 > /dev/null 2>&1; then
+ :
+ else
+ gcc_cv_prog_cmp_skip='cmp --ignore-initial=16 $$f1 $$f2'
+ fi
+ fi
+ rm t1 t2
+])
+do_compare="$gcc_cv_prog_cmp_skip"
+AC_SUBST(do_compare)
+])
diff --git a/configure b/configure
index f8c5cfeb03b..fd4f900547f 100755
--- a/configure
+++ b/configure
@@ -12,8 +12,14 @@ ac_help=
ac_default_prefix=/usr/local
# Any additions from configure.in:
ac_help="$ac_help
+ --without-libbanshee Don't build with libbanshee"
+ac_help="$ac_help
--enable-libada Builds libada directory"
ac_help="$ac_help
+ --with-gmp-dir=PATH Specify source directory for GMP library"
+ac_help="$ac_help
+ --with-gmp=PATH Specify directory for installed GMP library"
+ac_help="$ac_help
--enable-serial-[{host,target,build}-]configure
Force sequential configuration of
sub-packages for the host, target or build
@@ -581,7 +587,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
fi
echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:585: checking host system type" >&5
+echo "configure:591: checking host system type" >&5
host_alias=$host
case "$host_alias" in
@@ -602,7 +608,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$host" 1>&6
echo $ac_n "checking target system type""... $ac_c" 1>&6
-echo "configure:606: checking target system type" >&5
+echo "configure:612: checking target system type" >&5
target_alias=$target
case "$target_alias" in
@@ -620,7 +626,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$target" 1>&6
echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:624: checking build system type" >&5
+echo "configure:630: checking build system type" >&5
build_alias=$build
case "$build_alias" in
@@ -675,7 +681,7 @@ test "$program_transform_name" = "" && program_transform_name="s,x,x,"
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:679: checking for a BSD compatible install" >&5
+echo "configure:685: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -780,6 +786,8 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
### we might need to use some other shell than /bin/sh for running subshells
### If we are on Windows, search for the shell. This will permit people
### to not have /bin/sh, but to be able to see /SOME/PATH/sh configure
@@ -878,7 +886,7 @@ fi
# these libraries are used by various programs built for the host environment
#
-host_libs="intl mmalloc libiberty opcodes bfd readline tcl tk itcl tix libgui zlib"
+host_libs="intl mmalloc libiberty opcodes bfd readline tcl tk itcl tix libgui zlib libbanshee"
# these tools are built for the host environment
# Note, the powerpc-eabi build depends on sim occurring before gdb in order to
@@ -901,7 +909,9 @@ target_libraries="target-libiberty \
target-libgloss \
target-newlib \
target-libstdc++-v3 \
+ target-libmudflap \
target-libf2c \
+ target-libgfortran \
${libgcj} \
target-libobjc \
target-libada"
@@ -1080,6 +1090,22 @@ case "${host}" in
;;
esac
+# Check whether --with-libbanshee or --without-libbanshee was given.
+if test "${with_libbanshee+set}" = set; then
+ withval="$with_libbanshee"
+ :
+fi
+
+case ${with_libbanshee} in
+ no)
+ noconfigdirs="$noconfigdirs libbanshee" ;;
+ yes|"")
+ with_libbanshee=yes
+ ;;
+ *)
+ { echo "configure: error: --with-libbanshee can only be empty, "yes" or "no" (empty defaults to "yes"." 1>&2; exit 1; }
+esac
+
# Check whether --enable-libada or --disable-libada was given.
if test "${enable_libada+set}" = set; then
enableval="$enable_libada"
@@ -1108,6 +1134,18 @@ no)
;;
esac
+
+# Allow --disable-libmudflap to exclude target-libmudflap
+case $enable_libmudflap in
+yes | "")
+ # By default it's enabled
+ ;;
+no)
+ noconfigdirs="$noconfigdirs target-libmudflap"
+ ;;
+esac
+
+
case "${target}" in
*-*-chorusos)
noconfigdirs="$noconfigdirs target-newlib target-libgloss ${libgcj}"
@@ -1123,6 +1161,22 @@ case "${target}" in
*-*-freebsd[12] | *-*-freebsd[12].* | *-*-freebsd*aout*)
noconfigdirs="$noconfigdirs target-newlib target-libgloss ${libgcj}"
;;
+ *-*-freebsd* | *-*-kfreebsd*-gnu)
+ noconfigdirs="$noconfigdirs target-newlib target-libgloss"
+ if test "x$with_gmp" = x && test "x$with_gmp_dir" = x \
+ && test -f /usr/local/include/gmp.h; then
+ with_gmp=/usr/local
+ fi
+
+ # Skip some stuff that's unsupported on some FreeBSD configurations.
+ case "${target}" in
+ i*86-*-*) ;;
+ alpha*-*-*) ;;
+ *)
+ noconfigdirs="$noconfigdirs ${libgcj}"
+ ;;
+ esac
+ ;;
*-*-kaos*)
# Remove unsupported stuff on all kaOS configurations.
skipdirs="target-libiberty ${libgcj} target-libstdc++-v3 target-libf2c target-librx"
@@ -1174,9 +1228,6 @@ case "${target}" in
# newlib is not 64 bit ready
noconfigdirs="$noconfigdirs target-newlib target-libgloss"
;;
- alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu)
- noconfigdirs="$noconfigdirs target-newlib target-libgloss"
- ;;
alpha*-*-*)
# newlib is not 64 bit ready
noconfigdirs="$noconfigdirs target-newlib target-libgloss ${libgcj}"
@@ -1295,9 +1346,6 @@ case "${target}" in
i[3456789]86-*-coff | i[3456789]86-*-elf)
noconfigdirs="$noconfigdirs ${libgcj}"
;;
- i[3456789]86-*-freebsd* | i[3456789]86-*-kfreebsd*-gnu)
- noconfigdirs="$noconfigdirs target-newlib target-libgloss"
- ;;
i[3456789]86-*-linux*)
# The GCC port for glibc1 has no MD_FALLBACK_FRAME_STATE_FOR, so let's
# not build java stuff by default.
@@ -1420,8 +1468,7 @@ case "${target}" in
noconfigdirs="$noconfigdirs ld binutils gprof target-libgloss ${libgcj}"
;;
mips*-*-irix5*)
- # The GNU linker does not support shared libraries.
- noconfigdirs="$noconfigdirs ld gprof target-libgloss ${libgcj}"
+ noconfigdirs="$noconfigdirs gprof target-libgloss ${libgcj}"
;;
mips*-*-irix6*)
# Linking libjava exceeds command-line length limits on at least
@@ -1854,7 +1901,7 @@ fi
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1858: checking for $ac_word" >&5
+echo "configure:1905: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1884,7 +1931,7 @@ if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1888: checking for $ac_word" >&5
+echo "configure:1935: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1935,7 +1982,7 @@ fi
# Extract the first word of "cl", so it can be a program name with args.
set dummy cl; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1939: checking for $ac_word" >&5
+echo "configure:1986: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1967,7 +2014,7 @@ fi
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1971: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:2018: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -1978,12 +2025,12 @@ cross_compiling=$ac_cv_prog_cc_cross
cat > conftest.$ac_ext << EOF
-#line 1982 "configure"
+#line 2029 "configure"
#include "confdefs.h"
main(){return(0);}
EOF
-if { (eval echo configure:1987: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2034: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
ac_cv_prog_cc_works=yes
# If we can't run a trivial program, we are probably using a cross compiler.
if (./conftest; exit) 2>/dev/null; then
@@ -2009,12 +2056,12 @@ if test $ac_cv_prog_cc_works = no; then
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:2013: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:2060: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
cross_compiling=$ac_cv_prog_cc_cross
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:2018: checking whether we are using GNU C" >&5
+echo "configure:2065: checking whether we are using GNU C" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2023,7 +2070,7 @@ else
yes;
#endif
EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2027: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2074: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes
else
ac_cv_prog_gcc=no
@@ -2042,7 +2089,7 @@ ac_test_CFLAGS="${CFLAGS+set}"
ac_save_CFLAGS="$CFLAGS"
CFLAGS=
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:2046: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:2093: checking whether ${CC-cc} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2078,7 +2125,7 @@ fi
# Extract the first word of "${ac_tool_prefix}gnatbind", so it can be a program name with args.
set dummy ${ac_tool_prefix}gnatbind; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2082: checking for $ac_word" >&5
+echo "configure:2129: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_GNATBIND'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2110,7 +2157,7 @@ if test -n "$ac_tool_prefix"; then
# Extract the first word of "gnatbind", so it can be a program name with args.
set dummy gnatbind; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2114: checking for $ac_word" >&5
+echo "configure:2161: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_GNATBIND'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2143,7 +2190,7 @@ fi
fi
echo $ac_n "checking whether compiler driver understands Ada""... $ac_c" 1>&6
-echo "configure:2147: checking whether compiler driver understands Ada" >&5
+echo "configure:2194: checking whether compiler driver understands Ada" >&5
if eval "test \"`echo '$''{'acx_cv_cc_gcc_supports_ada'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2156,8 +2203,11 @@ acx_cv_cc_gcc_supports_ada=no
# has not been installed. This is fixed in 2.95.4, 3.0.2, and 3.1.
# Therefore we must check for the error message as well as an
# unsuccessful exit.
+# Other compilers, like HP Tru64 UNIX cc, exit successfully when
+# given a .adb file, but produce no object file. So we must check
+# if an object file was really produced to guard against this.
errors=`(${CC} -c conftest.adb) 2>&1 || echo failure`
-if test x"$errors" = x; then
+if test x"$errors" = x && test -f conftest.$ac_objext; then
acx_cv_cc_gcc_supports_ada=yes
break
fi
@@ -2166,12 +2216,140 @@ fi
echo "$ac_t""$acx_cv_cc_gcc_supports_ada" 1>&6
-if test x$GNATBIND != xno && test x$acx_cv_gcc_supports_ada != xno; then
+if test x$GNATBIND != xno && test x$acx_cv_cc_gcc_supports_ada != xno; then
have_gnat=yes
else
have_gnat=no
fi
+echo $ac_n "checking how to compare bootstrapped objects""... $ac_c" 1>&6
+echo "configure:2227: checking how to compare bootstrapped objects" >&5
+if eval "test \"`echo '$''{'gcc_cv_prog_cmp_skip'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo abfoo >t1
+ echo cdfoo >t2
+ gcc_cv_prog_cmp_skip='tail +16c $$f1 > tmp-foo1; tail +16c $$f2 > tmp-foo2; cmp tmp-foo1 tmp-foo2'
+ if cmp t1 t2 2 2 > /dev/null 2>&1; then
+ if cmp t1 t2 1 1 > /dev/null 2>&1; then
+ :
+ else
+ gcc_cv_prog_cmp_skip='cmp $$f1 $$f2 16 16'
+ fi
+ fi
+ if cmp --ignore-initial=2 t1 t2 > /dev/null 2>&1; then
+ if cmp --ignore-initial=1 t1 t2 > /dev/null 2>&1; then
+ :
+ else
+ gcc_cv_prog_cmp_skip='cmp --ignore-initial=16 $$f1 $$f2'
+ fi
+ fi
+ rm t1 t2
+
+fi
+
+echo "$ac_t""$gcc_cv_prog_cmp_skip" 1>&6
+do_compare="$gcc_cv_prog_cmp_skip"
+
+
+
+# Check for GMP
+gmplibs=
+gmpinc=
+have_gmp=yes
+# Specify a location for gmp
+# Check whether --with-gmp-dir or --without-gmp-dir was given.
+if test "${with_gmp_dir+set}" = set; then
+ withval="$with_gmp_dir"
+ :
+fi
+
+
+if test "x$with_gmp_dir" != x && test -f "$with_gmp_dir/gmp.h"; then
+ gmpinc="-I$with_gmp_dir"
+ if test -f "$with_gmp_dir/.libs/libgmp.a"; then
+ gmplibs="$with_gmp_dir/.libs/libgmp.a"
+ elif test -f "$with_gmp_dir/_libs/libgmp.a"; then
+ gmplibs="$with_gmp_dir/_libs/libgmp.a"
+ fi
+ # One of the later tests will catch the error if neither library is present.
+fi
+
+# Check whether --with-gmp or --without-gmp was given.
+if test "${with_gmp+set}" = set; then
+ withval="$with_gmp"
+ :
+fi
+
+
+if test "x$with_gmp" != x && test -d "$with_gmp"; then
+ gmplibs="-L$with_gmp/lib -lgmp"
+ gmpinc="-I$with_gmp/include"
+fi
+
+# Use system gmp if nothing else specified
+if test "x$gmplibs" = x; then
+ gmplibs="-lgmp"
+fi
+
+saved_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $gmpinc"
+# Check GMP actually works
+echo $ac_n "checking for correct version of gmp.h""... $ac_c" 1>&6
+echo "configure:2300: checking for correct version of gmp.h" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2302 "configure"
+#include "confdefs.h"
+#include "gmp.h"
+int main() {
+
+#if __GNU_MP_VERSION < 3
+choke me
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2313: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ echo "$ac_t""yes" 1>&6
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ echo "$ac_t""no" 1>&6; have_gmp=no
+fi
+rm -f conftest*
+
+if test x"$have_gmp" = xyes; then
+ echo $ac_n "checking for mpf_init in -lgmp""... $ac_c" 1>&6
+echo "configure:2326: checking for mpf_init in -lgmp" >&5
+
+ saved_LIBS="$LIBS"
+ LIBS="$LIBS $gmplibs"
+ cat > conftest.$ac_ext <<EOF
+#line 2331 "configure"
+#include "confdefs.h"
+#include <gmp.h>
+int main() {
+mpf_t n; mpf_init(n);
+; return 0; }
+EOF
+if { (eval echo configure:2338: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ echo "$ac_t""yes" 1>&6
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ echo "$ac_t""no" 1>&6; have_gmp=no
+fi
+rm -f conftest*
+ LIBS="$saved_LIBS"
+ CFLAGS="$saved_CFLAGS"
+fi
+
+
+
# By default, C is the only stage 1 language.
stage1_languages=c
@@ -2245,6 +2423,7 @@ if test -d ${srcdir}/gcc; then
lang_dirs=
boot_language=
build_by_default=
+ need_gmp=
. ${lang_frag}
# This is quite sensitive to the ordering of the case statement arms.
case ,${enable_languages},:${language}:${have_gnat}:${build_by_default} in
@@ -2273,7 +2452,13 @@ if test -d ${srcdir}/gcc; then
add_this_lang=no
;;
esac
- case $add_this_lang in
+
+ # Disable language that need GMP if it isn't available.
+ if test x"$need_gmp" = xyes && test x"$have_gmp" = xno; then
+ add_this_lang=no
+ fi
+
+ case $add_this_lang in
no)
# Remove language-dependent dirs.
eval noconfigdirs='"$noconfigdirs "'\"$target_libs $lang_dirs\"
@@ -2574,6 +2759,9 @@ if test x${with_newlib} != xno && echo " ${target_configdirs} " | grep " target-
extra_host_args="$extra_host_args --with-newlib"
fi
+if test x${with_libbanshee} = xyes && echo " ${configdirs} " | grep " libbanshee " >/dev/null 2>&1; then
+ extra_host_args="$extra_host_args --with-libbanshee"
+fi
# Default to using --with-stabs for certain targets.
if test x${with_stabs} = x ; then
@@ -2608,7 +2796,7 @@ do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2612: checking for $ac_word" >&5
+echo "configure:2800: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_DEFAULT_YACC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2643,7 +2831,7 @@ do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2647: checking for $ac_word" >&5
+echo "configure:2835: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_DEFAULT_M4'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2678,7 +2866,7 @@ do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2682: checking for $ac_word" >&5
+echo "configure:2870: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_DEFAULT_LEX'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3141,6 +3329,20 @@ else
fi
GCJ_FOR_TARGET=$GCJ_FOR_TARGET' $(FLAGS_FOR_TARGET)'
+if test "x${GFORTRAN_FOR_TARGET+set}" = xset; then
+ :
+elif test -d ${srcdir}/gcc; then
+ GFORTRAN_FOR_TARGET='$$r/gcc/gfortran -B$$r/gcc/'
+elif test "$host" = "$target"; then
+ GFORTRAN_FOR_TARGET='gfortran'
+else
+ GFORTRAN_FOR_TARGET=`echo gfortran | sed -e 's/x/x/' ${program_transform_name}`
+fi
+case $GFORTRAN_FOR_TARGET in
+*' $(FLAGS_FOR_TARGET)') ;;
+*) GFORTRAN_FOR_TARGET=$GFORTRAN_FOR_TARGET' $(FLAGS_FOR_TARGET)' ;;
+esac
+
# Don't use libstdc++-v3's flags to configure/build itself.
libstdcxx_flags='`test ! -f $$r/$(TARGET_SUBDIR)/libstdc++-v3/scripts/testsuite_flags || $(SHELL) $$r/$(TARGET_SUBDIR)/libstdc++-v3/scripts/testsuite_flags --build-includes` -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs'
raw_libstdcxx_flags='-L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs'
@@ -3182,6 +3384,7 @@ qqRAW_CXX_FOR_TARGET=`echo "$qRAW_CXX_FOR_TARGET" | sed -e 's,[$][$],$$$$,g'`
# Wrap CC_FOR_TARGET and friends, for certain types of builds.
CC_FOR_TARGET="\$(STAGE_CC_WRAPPER) ${CC_FOR_TARGET}"
GCJ_FOR_TARGET="\$(STAGE_CC_WRAPPER) ${GCJ_FOR_TARGET}"
+GFORTRAN_FOR_TARGET="\$(STAGE_CC_WRAPPER) ${GFORTRAN_FOR_TARGET}"
CXX_FOR_TARGET="\$(STAGE_CC_WRAPPER) ${qCXX_FOR_TARGET}"
RAW_CXX_FOR_TARGET="\$(STAGE_CC_WRAPPER) ${qRAW_CXX_FOR_TARGET}"
CXX_FOR_TARGET_FOR_RECURSIVE_MAKE="\$(STAGE_CC_WRAPPER) ${qqCXX_FOR_TARGET}"
@@ -3241,7 +3444,7 @@ test -n "$target_alias" && ncn_target_tool_prefix=$target_alias-
# Extract the first word of "${ncn_tool_prefix}ar", so it can be a program name with args.
set dummy ${ncn_tool_prefix}ar; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3245: checking for $ac_word" >&5
+echo "configure:3448: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3274,7 +3477,7 @@ if test -z "$ac_cv_prog_AR" ; then
# Extract the first word of "ar", so it can be a program name with args.
set dummy ar; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3278: checking for $ac_word" >&5
+echo "configure:3481: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_AR'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3313,7 +3516,7 @@ fi
# Extract the first word of "${ncn_tool_prefix}as", so it can be a program name with args.
set dummy ${ncn_tool_prefix}as; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3317: checking for $ac_word" >&5
+echo "configure:3520: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3346,7 +3549,7 @@ if test -z "$ac_cv_prog_AS" ; then
# Extract the first word of "as", so it can be a program name with args.
set dummy as; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3350: checking for $ac_word" >&5
+echo "configure:3553: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_AS'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3385,7 +3588,7 @@ fi
# Extract the first word of "${ncn_tool_prefix}dlltool", so it can be a program name with args.
set dummy ${ncn_tool_prefix}dlltool; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3389: checking for $ac_word" >&5
+echo "configure:3592: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3418,7 +3621,7 @@ if test -z "$ac_cv_prog_DLLTOOL" ; then
# Extract the first word of "dlltool", so it can be a program name with args.
set dummy dlltool; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3422: checking for $ac_word" >&5
+echo "configure:3625: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_DLLTOOL'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3457,7 +3660,7 @@ fi
# Extract the first word of "${ncn_tool_prefix}ld", so it can be a program name with args.
set dummy ${ncn_tool_prefix}ld; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3461: checking for $ac_word" >&5
+echo "configure:3664: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3490,7 +3693,7 @@ if test -z "$ac_cv_prog_LD" ; then
# Extract the first word of "ld", so it can be a program name with args.
set dummy ld; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3494: checking for $ac_word" >&5
+echo "configure:3697: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_LD'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3529,7 +3732,7 @@ fi
# Extract the first word of "${ncn_tool_prefix}nm", so it can be a program name with args.
set dummy ${ncn_tool_prefix}nm; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3533: checking for $ac_word" >&5
+echo "configure:3736: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_NM'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3562,7 +3765,7 @@ if test -z "$ac_cv_prog_NM" ; then
# Extract the first word of "nm", so it can be a program name with args.
set dummy nm; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3566: checking for $ac_word" >&5
+echo "configure:3769: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_NM'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3601,7 +3804,7 @@ fi
# Extract the first word of "${ncn_tool_prefix}ranlib", so it can be a program name with args.
set dummy ${ncn_tool_prefix}ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3605: checking for $ac_word" >&5
+echo "configure:3808: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3634,7 +3837,7 @@ if test -z "$ac_cv_prog_RANLIB" ; then
# Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3638: checking for $ac_word" >&5
+echo "configure:3841: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3673,7 +3876,7 @@ fi
# Extract the first word of "${ncn_tool_prefix}windres", so it can be a program name with args.
set dummy ${ncn_tool_prefix}windres; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3677: checking for $ac_word" >&5
+echo "configure:3880: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_WINDRES'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3706,7 +3909,7 @@ if test -z "$ac_cv_prog_WINDRES" ; then
# Extract the first word of "windres", so it can be a program name with args.
set dummy windres; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3710: checking for $ac_word" >&5
+echo "configure:3913: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_WINDRES'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3745,7 +3948,7 @@ fi
# Extract the first word of "${ncn_tool_prefix}objcopy", so it can be a program name with args.
set dummy ${ncn_tool_prefix}objcopy; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3749: checking for $ac_word" >&5
+echo "configure:3952: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_OBJCOPY'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3778,7 +3981,7 @@ if test -z "$ac_cv_prog_OBJCOPY" ; then
# Extract the first word of "objcopy", so it can be a program name with args.
set dummy objcopy; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3782: checking for $ac_word" >&5
+echo "configure:3985: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_OBJCOPY'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3817,7 +4020,7 @@ fi
# Extract the first word of "${ncn_tool_prefix}objdump", so it can be a program name with args.
set dummy ${ncn_tool_prefix}objdump; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3821: checking for $ac_word" >&5
+echo "configure:4024: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_OBJDUMP'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3850,7 +4053,7 @@ if test -z "$ac_cv_prog_OBJDUMP" ; then
# Extract the first word of "objdump", so it can be a program name with args.
set dummy objdump; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3854: checking for $ac_word" >&5
+echo "configure:4057: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_OBJDUMP'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3899,7 +4102,7 @@ fi
# Extract the first word of "${ncn_target_tool_prefix}ar", so it can be a program name with args.
set dummy ${ncn_target_tool_prefix}ar; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3903: checking for $ac_word" >&5
+echo "configure:4106: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CONFIGURED_AR_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3932,7 +4135,7 @@ if test -z "$ac_cv_prog_CONFIGURED_AR_FOR_TARGET" ; then
# Extract the first word of "ar", so it can be a program name with args.
set dummy ar; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3936: checking for $ac_word" >&5
+echo "configure:4139: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_CONFIGURED_AR_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3971,7 +4174,7 @@ fi
# Extract the first word of "${ncn_target_tool_prefix}as", so it can be a program name with args.
set dummy ${ncn_target_tool_prefix}as; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3975: checking for $ac_word" >&5
+echo "configure:4178: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CONFIGURED_AS_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4004,7 +4207,7 @@ if test -z "$ac_cv_prog_CONFIGURED_AS_FOR_TARGET" ; then
# Extract the first word of "as", so it can be a program name with args.
set dummy as; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4008: checking for $ac_word" >&5
+echo "configure:4211: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_CONFIGURED_AS_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4043,7 +4246,7 @@ fi
# Extract the first word of "${ncn_target_tool_prefix}dlltool", so it can be a program name with args.
set dummy ${ncn_target_tool_prefix}dlltool; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4047: checking for $ac_word" >&5
+echo "configure:4250: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CONFIGURED_DLLTOOL_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4076,7 +4279,7 @@ if test -z "$ac_cv_prog_CONFIGURED_DLLTOOL_FOR_TARGET" ; then
# Extract the first word of "dlltool", so it can be a program name with args.
set dummy dlltool; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4080: checking for $ac_word" >&5
+echo "configure:4283: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_CONFIGURED_DLLTOOL_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4115,7 +4318,7 @@ fi
# Extract the first word of "${ncn_target_tool_prefix}ld", so it can be a program name with args.
set dummy ${ncn_target_tool_prefix}ld; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4119: checking for $ac_word" >&5
+echo "configure:4322: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CONFIGURED_LD_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4148,7 +4351,7 @@ if test -z "$ac_cv_prog_CONFIGURED_LD_FOR_TARGET" ; then
# Extract the first word of "ld", so it can be a program name with args.
set dummy ld; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4152: checking for $ac_word" >&5
+echo "configure:4355: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_CONFIGURED_LD_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4187,7 +4390,7 @@ fi
# Extract the first word of "${ncn_target_tool_prefix}nm", so it can be a program name with args.
set dummy ${ncn_target_tool_prefix}nm; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4191: checking for $ac_word" >&5
+echo "configure:4394: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CONFIGURED_NM_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4220,7 +4423,7 @@ if test -z "$ac_cv_prog_CONFIGURED_NM_FOR_TARGET" ; then
# Extract the first word of "nm", so it can be a program name with args.
set dummy nm; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4224: checking for $ac_word" >&5
+echo "configure:4427: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_CONFIGURED_NM_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4259,7 +4462,7 @@ fi
# Extract the first word of "${ncn_target_tool_prefix}ranlib", so it can be a program name with args.
set dummy ${ncn_target_tool_prefix}ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4263: checking for $ac_word" >&5
+echo "configure:4466: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CONFIGURED_RANLIB_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4292,7 +4495,7 @@ if test -z "$ac_cv_prog_CONFIGURED_RANLIB_FOR_TARGET" ; then
# Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4296: checking for $ac_word" >&5
+echo "configure:4499: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_CONFIGURED_RANLIB_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4331,7 +4534,7 @@ fi
# Extract the first word of "${ncn_target_tool_prefix}windres", so it can be a program name with args.
set dummy ${ncn_target_tool_prefix}windres; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4335: checking for $ac_word" >&5
+echo "configure:4538: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CONFIGURED_WINDRES_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4364,7 +4567,7 @@ if test -z "$ac_cv_prog_CONFIGURED_WINDRES_FOR_TARGET" ; then
# Extract the first word of "windres", so it can be a program name with args.
set dummy windres; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4368: checking for $ac_word" >&5
+echo "configure:4571: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_CONFIGURED_WINDRES_FOR_TARGET'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4409,6 +4612,7 @@ fi
+
# Fix up target tools.
if test "x${build}" = "x${host}" ; then
# In this case, the newly built tools can and should be used,
@@ -4448,7 +4652,7 @@ RANLIB_FOR_TARGET=${RANLIB_FOR_TARGET}${extra_ranlibflags_for_target}
NM_FOR_TARGET=${NM_FOR_TARGET}${extra_nmflags_for_target}
echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
-echo "configure:4452: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo "configure:4656: checking whether to enable maintainer-specific portions of Makefiles" >&5
# Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
if test "${enable_maintainer_mode+set}" = set; then
enableval="$enable_maintainer_mode"
@@ -4573,15 +4777,34 @@ trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
# Transform confdefs.h into DEFS.
# Protect against shell expansion while executing Makefile rules.
# Protect against Makefile macro expansion.
-cat > conftest.defs <<\EOF
-s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
-s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
-s%\[%\\&%g
-s%\]%\\&%g
-s%\$%$$%g
-EOF
-DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
-rm -f conftest.defs
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then we branch to the quote section. Otherwise,
+# look for a macro that doesn't take arguments.
+cat >confdef2opt.sed <<\_ACEOF
+t clear
+: clear
+s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g
+t quote
+s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g
+t quote
+d
+: quote
+s,[ `~#$^&*(){}\\|;'"<>?],\\&,g
+s,\[,\\&,g
+s,\],\\&,g
+s,\$,$$,g
+p
+_ACEOF
+# We use echo to avoid assuming a particular line-breaking character.
+# The extra dot is to prevent the shell from consuming trailing
+# line-breaks from the sub-command output. A line-break within
+# single-quotes doesn't work because, if this script is created in a
+# platform that uses two characters for line-breaks (e.g., DOS), tr
+# would break.
+ac_LF_and_DOT=`echo; echo .`
+DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
+rm -f confdef2opt.sed
# Without the "./", some shells look in PATH for config.status.
@@ -4676,6 +4899,9 @@ s%@host_subdir@%$host_subdir%g
s%@target_subdir@%$target_subdir%g
s%@CC@%$CC%g
s%@GNATBIND@%$GNATBIND%g
+s%@do_compare@%$do_compare%g
+s%@gmplibs@%$gmplibs%g
+s%@gmpinc@%$gmpinc%g
s%@stage1_languages@%$stage1_languages%g
s%@DEFAULT_YACC@%$DEFAULT_YACC%g
s%@DEFAULT_M4@%$DEFAULT_M4%g
@@ -4754,6 +4980,7 @@ s%@GCC_FOR_TARGET@%$GCC_FOR_TARGET%g
s%@FLAGS_FOR_TARGET@%$FLAGS_FOR_TARGET%g
s%@CC_FOR_TARGET@%$CC_FOR_TARGET%g
s%@GCJ_FOR_TARGET@%$GCJ_FOR_TARGET%g
+s%@GFORTRAN_FOR_TARGET@%$GFORTRAN_FOR_TARGET%g
s%@CXX_FOR_TARGET@%$CXX_FOR_TARGET%g
s%@RAW_CXX_FOR_TARGET@%$RAW_CXX_FOR_TARGET%g
s%@CXX_FOR_TARGET_FOR_RECURSIVE_MAKE@%$CXX_FOR_TARGET_FOR_RECURSIVE_MAKE%g
diff --git a/configure.in b/configure.in
index 7c8cabcf814..a3e1f863445 100644
--- a/configure.in
+++ b/configure.in
@@ -126,7 +126,7 @@ fi
# these libraries are used by various programs built for the host environment
#
-host_libs="intl mmalloc libiberty opcodes bfd readline tcl tk itcl tix libgui zlib"
+host_libs="intl mmalloc libiberty opcodes bfd readline tcl tk itcl tix libgui zlib libbanshee"
# these tools are built for the host environment
# Note, the powerpc-eabi build depends on sim occurring before gdb in order to
@@ -149,7 +149,9 @@ target_libraries="target-libiberty \
target-libgloss \
target-newlib \
target-libstdc++-v3 \
+ target-libmudflap \
target-libf2c \
+ target-libgfortran \
${libgcj} \
target-libobjc \
target-libada"
@@ -307,6 +309,18 @@ case "${host}" in
;;
esac
+AC_ARG_WITH(libbanshee,
+[ --without-libbanshee Don't build with libbanshee])
+case ${with_libbanshee} in
+ no)
+ noconfigdirs="$noconfigdirs libbanshee" ;;
+ yes|"")
+ with_libbanshee=yes
+ ;;
+ *)
+ AC_MSG_ERROR([--with-libbanshee can only be empty, "yes" or "no" (empty defaults to "yes".])
+esac
+
AC_ARG_ENABLE(libada,
[ --enable-libada Builds libada directory],
ENABLE_LIBADA=$enableval,
@@ -331,6 +345,18 @@ no)
;;
esac
+
+# Allow --disable-libmudflap to exclude target-libmudflap
+case $enable_libmudflap in
+yes | "")
+ # By default it's enabled
+ ;;
+no)
+ noconfigdirs="$noconfigdirs target-libmudflap"
+ ;;
+esac
+
+
case "${target}" in
*-*-chorusos)
noconfigdirs="$noconfigdirs target-newlib target-libgloss ${libgcj}"
@@ -346,6 +372,22 @@ case "${target}" in
*-*-freebsd[[12]] | *-*-freebsd[[12]].* | *-*-freebsd*aout*)
noconfigdirs="$noconfigdirs target-newlib target-libgloss ${libgcj}"
;;
+ *-*-freebsd* | *-*-kfreebsd*-gnu)
+ noconfigdirs="$noconfigdirs target-newlib target-libgloss"
+ if test "x$with_gmp" = x && test "x$with_gmp_dir" = x \
+ && test -f /usr/local/include/gmp.h; then
+ with_gmp=/usr/local
+ fi
+
+ # Skip some stuff that's unsupported on some FreeBSD configurations.
+ case "${target}" in
+ i*86-*-*) ;;
+ alpha*-*-*) ;;
+ *)
+ noconfigdirs="$noconfigdirs ${libgcj}"
+ ;;
+ esac
+ ;;
*-*-kaos*)
# Remove unsupported stuff on all kaOS configurations.
skipdirs="target-libiberty ${libgcj} target-libstdc++-v3 target-libf2c target-librx"
@@ -397,9 +439,6 @@ case "${target}" in
# newlib is not 64 bit ready
noconfigdirs="$noconfigdirs target-newlib target-libgloss"
;;
- alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu)
- noconfigdirs="$noconfigdirs target-newlib target-libgloss"
- ;;
alpha*-*-*)
# newlib is not 64 bit ready
noconfigdirs="$noconfigdirs target-newlib target-libgloss ${libgcj}"
@@ -518,9 +557,6 @@ case "${target}" in
i[[3456789]]86-*-coff | i[[3456789]]86-*-elf)
noconfigdirs="$noconfigdirs ${libgcj}"
;;
- i[[3456789]]86-*-freebsd* | i[[3456789]]86-*-kfreebsd*-gnu)
- noconfigdirs="$noconfigdirs target-newlib target-libgloss"
- ;;
i[[3456789]]86-*-linux*)
# The GCC port for glibc1 has no MD_FALLBACK_FRAME_STATE_FOR, so let's
# not build java stuff by default.
@@ -643,8 +679,7 @@ case "${target}" in
noconfigdirs="$noconfigdirs ld binutils gprof target-libgloss ${libgcj}"
;;
mips*-*-irix5*)
- # The GNU linker does not support shared libraries.
- noconfigdirs="$noconfigdirs ld gprof target-libgloss ${libgcj}"
+ noconfigdirs="$noconfigdirs gprof target-libgloss ${libgcj}"
;;
mips*-*-irix6*)
# Linking libjava exceeds command-line length limits on at least
@@ -1069,6 +1104,61 @@ EOF
fi
ACX_PROG_GNAT
+ACX_PROG_CMP_IGNORE_INITIAL
+
+# Check for GMP
+gmplibs=
+gmpinc=
+have_gmp=yes
+# Specify a location for gmp
+AC_ARG_WITH(gmp-dir, [ --with-gmp-dir=PATH Specify source directory for GMP library])
+
+if test "x$with_gmp_dir" != x && test -f "$with_gmp_dir/gmp.h"; then
+ gmpinc="-I$with_gmp_dir"
+ if test -f "$with_gmp_dir/.libs/libgmp.a"; then
+ gmplibs="$with_gmp_dir/.libs/libgmp.a"
+ elif test -f "$with_gmp_dir/_libs/libgmp.a"; then
+ gmplibs="$with_gmp_dir/_libs/libgmp.a"
+ fi
+ # One of the later tests will catch the error if neither library is present.
+fi
+
+AC_ARG_WITH(gmp, [ --with-gmp=PATH Specify directory for installed GMP library])
+
+if test "x$with_gmp" != x && test -d "$with_gmp"; then
+ gmplibs="-L$with_gmp/lib -lgmp"
+ gmpinc="-I$with_gmp/include"
+fi
+
+# Use system gmp if nothing else specified
+if test "x$gmplibs" = x; then
+ gmplibs="-lgmp"
+fi
+
+saved_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $gmpinc"
+# Check GMP actually works
+AC_MSG_CHECKING([for correct version of gmp.h])
+AC_TRY_COMPILE([#include "gmp.h"],[
+#if __GNU_MP_VERSION < 3
+choke me
+#endif
+], [AC_MSG_RESULT([yes])],
+ [AC_MSG_RESULT([no]); have_gmp=no])
+
+if test x"$have_gmp" = xyes; then
+ AC_MSG_CHECKING([for mpf_init in -lgmp])
+
+ saved_LIBS="$LIBS"
+ LIBS="$LIBS $gmplibs"
+ AC_TRY_LINK([#include <gmp.h>], [mpf_t n; mpf_init(n);],
+ [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no]); have_gmp=no])
+ LIBS="$saved_LIBS"
+ CFLAGS="$saved_CFLAGS"
+fi
+
+AC_SUBST(gmplibs)
+AC_SUBST(gmpinc)
# By default, C is the only stage 1 language.
stage1_languages=c
@@ -1142,6 +1232,7 @@ if test -d ${srcdir}/gcc; then
lang_dirs=
boot_language=
build_by_default=
+ need_gmp=
. ${lang_frag}
# This is quite sensitive to the ordering of the case statement arms.
case ,${enable_languages},:${language}:${have_gnat}:${build_by_default} in
@@ -1170,7 +1261,13 @@ if test -d ${srcdir}/gcc; then
add_this_lang=no
;;
esac
- case $add_this_lang in
+
+ # Disable language that need GMP if it isn't available.
+ if test x"$need_gmp" = xyes && test x"$have_gmp" = xno; then
+ add_this_lang=no
+ fi
+
+ case $add_this_lang in
no)
# Remove language-dependent dirs.
eval noconfigdirs='"$noconfigdirs "'\"$target_libs $lang_dirs\"
@@ -1471,6 +1568,9 @@ if test x${with_newlib} != xno && echo " ${target_configdirs} " | grep " target-
extra_host_args="$extra_host_args --with-newlib"
fi
+if test x${with_libbanshee} = xyes && echo " ${configdirs} " | grep " libbanshee " >/dev/null 2>&1; then
+ extra_host_args="$extra_host_args --with-libbanshee"
+fi
# Default to using --with-stabs for certain targets.
if test x${with_stabs} = x ; then
@@ -1935,6 +2035,20 @@ else
fi
GCJ_FOR_TARGET=$GCJ_FOR_TARGET' $(FLAGS_FOR_TARGET)'
+if test "x${GFORTRAN_FOR_TARGET+set}" = xset; then
+ :
+elif test -d ${srcdir}/gcc; then
+ GFORTRAN_FOR_TARGET='$$r/gcc/gfortran -B$$r/gcc/'
+elif test "$host" = "$target"; then
+ GFORTRAN_FOR_TARGET='gfortran'
+else
+ GFORTRAN_FOR_TARGET=`echo gfortran | sed -e 's/x/x/' ${program_transform_name}`
+fi
+case $GFORTRAN_FOR_TARGET in
+*' $(FLAGS_FOR_TARGET)') ;;
+*) GFORTRAN_FOR_TARGET=$GFORTRAN_FOR_TARGET' $(FLAGS_FOR_TARGET)' ;;
+esac
+
# Don't use libstdc++-v3's flags to configure/build itself.
libstdcxx_flags='`test ! -f $$r/$(TARGET_SUBDIR)/libstdc++-v3/scripts/testsuite_flags || $(SHELL) $$r/$(TARGET_SUBDIR)/libstdc++-v3/scripts/testsuite_flags --build-includes` -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs'
raw_libstdcxx_flags='-L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs'
@@ -1976,6 +2090,7 @@ qqRAW_CXX_FOR_TARGET=`echo "$qRAW_CXX_FOR_TARGET" | sed -e 's,[[$]][[$]],$$$$,g'
# Wrap CC_FOR_TARGET and friends, for certain types of builds.
CC_FOR_TARGET="\$(STAGE_CC_WRAPPER) ${CC_FOR_TARGET}"
GCJ_FOR_TARGET="\$(STAGE_CC_WRAPPER) ${GCJ_FOR_TARGET}"
+GFORTRAN_FOR_TARGET="\$(STAGE_CC_WRAPPER) ${GFORTRAN_FOR_TARGET}"
CXX_FOR_TARGET="\$(STAGE_CC_WRAPPER) ${qCXX_FOR_TARGET}"
RAW_CXX_FOR_TARGET="\$(STAGE_CC_WRAPPER) ${qRAW_CXX_FOR_TARGET}"
CXX_FOR_TARGET_FOR_RECURSIVE_MAKE="\$(STAGE_CC_WRAPPER) ${qqCXX_FOR_TARGET}"
@@ -2057,6 +2172,7 @@ AC_SUBST(GCC_FOR_TARGET)
AC_SUBST(FLAGS_FOR_TARGET)
AC_SUBST(CC_FOR_TARGET)
AC_SUBST(GCJ_FOR_TARGET)
+AC_SUBST(GFORTRAN_FOR_TARGET)
AC_SUBST(CXX_FOR_TARGET)
AC_SUBST(RAW_CXX_FOR_TARGET)
AC_SUBST(CXX_FOR_TARGET_FOR_RECURSIVE_MAKE)
diff --git a/contrib/ChangeLog b/contrib/ChangeLog
index edc077af2e9..6451d6f0e90 100644
--- a/contrib/ChangeLog
+++ b/contrib/ChangeLog
@@ -1,3 +1,14 @@
+2004-05-13 Diego Novillo <dnovillo@redhat.com>
+
+ Merge from tree-ssa-20020619-branch.
+
+ * filter_gcc_for_doxygen: New file.
+ * filter_knr2ansi.pl: New file.
+ * filter_params.pl: New file.
+ * tree-ssa.doxy: New file.
+ * contrib/gcc_update (files_and_dependencies): Handle
+ libbanshee and libmudflap.
+
2004-04-12 Kelley Cook <kcook@gcc.gnu.org>
Andreas Jaeger <aj@suse.de>
diff --git a/contrib/ChangeLog.tree-ssa b/contrib/ChangeLog.tree-ssa
new file mode 100644
index 00000000000..2c1165f79b2
--- /dev/null
+++ b/contrib/ChangeLog.tree-ssa
@@ -0,0 +1,46 @@
+2004-03-25 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc_update (files_and_dependencies): Add libbanshee and
+ libmudflap dependencies.
+
+2003-11-27 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa.doxy (FILE_PATTERNS): Update.
+
+2003-11-21 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa.doxy: Do not generate latex output.
+
+2003-07-21 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa.doxy: Include tree* files
+
+2003-07-15 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa.doxy: Add tree-must-alias.c.
+
+2003-01-28 Diego Novillo <dnovillo@redhat.com>
+
+ * filter_params.pl: Surround comments in @verbatim/@endverbatim.
+
+2003-01-19 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa.doxy (OUTPUT_DIRECTORY, INPUT_FILTER): Replace
+ hardwired values for with replaceable strings.
+
+2003-01-18 Diego Novillo <dnovillo@redhat.com>
+
+ * filter_params.pl: Change most comments to start with /**.
+
+2002-12-23 Steven Bosscher <Steven.Bosscher@usafa.af.mil>
+
+ * filter_params.pl: Filter ATTRIBUTE_UNUSED.
+
+2002-12-12 Daniel Berlin <dberlin@dberlin.org>
+ Steven Bosscher <Steven.Bosscher@usafa.af.mil>
+ Diego Novillo <dnovillo@redhat.com>
+
+ * filter_gcc_for_doxygen: New file.
+ * filter_knr2ansi.pl: New file.
+ * filter_params.pl: New file.
+ * tree-ssa.doxy: New file.
diff --git a/contrib/filter_gcc_for_doxygen b/contrib/filter_gcc_for_doxygen
new file mode 100755
index 00000000000..3787eebbf0e
--- /dev/null
+++ b/contrib/filter_gcc_for_doxygen
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# This filters GCC source before Doxygen can get confused by it;
+# this script is listed in the doxyfile. The output is not very
+# pretty, but at least we get output that Doxygen can understand.
+#
+# $1 is a source file of some kind. The source we wish doxygen to
+# process is put on stdout.
+
+dir=`dirname $0`
+perl $dir/filter_params.pl < $1 | perl $dir/filter_knr2ansi.pl
+exit 0
diff --git a/contrib/filter_knr2ansi.pl b/contrib/filter_knr2ansi.pl
new file mode 100755
index 00000000000..c05e8d2ed20
--- /dev/null
+++ b/contrib/filter_knr2ansi.pl
@@ -0,0 +1,45 @@
+#!/usr/bin/perl
+#
+# Goes thourgh the input line by line to find K&R style function
+# declarations, and replaces them with ANSI style declarations.
+#
+@blah = <>;
+
+for ($i = 0; $i < @blah; $i++)
+{
+ if ($blah[$i] =~ /^([a-zA-Z_0-9]+)\s*\([^)]+\)\s*$/)
+ {
+ $name = $1;
+ $funci = $i;
+ $blah[$funci]="$name (";
+ $i++;
+ $lastline = $i;
+ while ($lastline < @blah && $blah[$lastline] !~ /^{/)
+ {
+ $lastline++;
+ }
+ $lastline--;
+ while ($i < @blah && $blah[$i] !~ /^{/)
+ {
+ $arg = $blah[$i];
+ if ($i != $lastline)
+ {
+ $arg =~ s/;/,/g;
+ }
+ else
+ {
+ $arg =~ s/;//g;
+ }
+ $blah[$i] = "";
+ $blah[$funci] = "$blah[$funci]" . "$arg";
+ $i++;
+ }
+ $blah[$funci] = "$blah[$funci]" . ")\n";
+ }
+}
+
+for ($i = 0; $i < @blah; $i++)
+{
+ print $blah[$i];
+}
+
diff --git a/contrib/filter_params.pl b/contrib/filter_params.pl
new file mode 100755
index 00000000000..05861e376fe
--- /dev/null
+++ b/contrib/filter_params.pl
@@ -0,0 +1,14 @@
+#!/usr/bin/perl
+
+# Filters out some of the #defines used thourghout the GCC sources:
+# - GTY(()) marks declarations for gengtype.c
+# - PARAMS(()) is used for K&R compatibility. See ansidecl.h.
+
+while (<>) {
+ s/^\/\* /\/\*\* \@verbatim /;
+ s/\*\// \@endverbatim \*\//;
+ s/GTY[ \t]*\(\(.*\)\)//g;
+ s/[ \t]ATTRIBUTE_UNUSED//g;
+ s/PARAMS[ \t]*\(\((.*?)\)\)/\($1\)/sg;
+ print;
+}
diff --git a/contrib/gcc_update b/contrib/gcc_update
index 9c4f40c44a7..dda18afd5a4 100755
--- a/contrib/gcc_update
+++ b/contrib/gcc_update
@@ -80,6 +80,8 @@ libf2c/libI77/stamp-h.in: libf2c/libI77/configure.in
libf2c/libI77/config.h.in: libf2c/libI77/configure.in libf2c/libI77/stamp-h.in
libf2c/libU77/configure: libf2c/libU77/configure.in
libf2c/libU77/stamp-h.in: libf2c/libU77/configure.in libf2c/libU77/acconfig.h
+libbanshee/configure: libbanshee/configure.in
+libmudflap/configure: libmudflap/configure.in
libobjc/configure: libobjc/configure.ac
zlib/aclocal.m4: zlib/configure.ac zlib/acinclude.m4
zlib/Makefile.in: zlib/Makefile.am zlib/configure.ac zlib/aclocal.m4
diff --git a/contrib/regression/ChangeLog b/contrib/regression/ChangeLog
index 09c920aa8e2..74f9d5f4e95 100644
--- a/contrib/regression/ChangeLog
+++ b/contrib/regression/ChangeLog
@@ -1,3 +1,7 @@
+2004-05-13 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * btest-gcc.sh: Remove g77.sum from TESTLOGS.
+
2003-09-18 Andreas Tobler <a.tobler@schweiz.ch>
* btest-gcc.sh: Add make check-target-libffi.
diff --git a/contrib/regression/btest-gcc.sh b/contrib/regression/btest-gcc.sh
index 4978c49e083..c8cb8fc2e0b 100755
--- a/contrib/regression/btest-gcc.sh
+++ b/contrib/regression/btest-gcc.sh
@@ -98,7 +98,6 @@ H_REAL_TARGET=`$SOURCE/config.sub $H_TARGET || exit 1`
# look at.
TESTLOGS="gcc/testsuite/gcc.sum
gcc/testsuite/g++.sum
-gcc/testsuite/g77.sum
gcc/testsuite/objc.sum"
# $H_TARGET/libstdc++-v3/testsuite/libstdc++-v3.sum
# $H_TARGET/libjava/testsuite/libjava.sum
diff --git a/contrib/tree-ssa.doxy b/contrib/tree-ssa.doxy
new file mode 100644
index 00000000000..68d8f205ef1
--- /dev/null
+++ b/contrib/tree-ssa.doxy
@@ -0,0 +1,932 @@
+# Doxyfile 1.2.18
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+
+#-----------------------------------------------------------------------------
+# NOTE: YOU MUST EDIT THE FOLLOWING HARDWIRED PATHS BEFORE USING THIS FILE.
+#-----------------------------------------------------------------------------
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = @OUTPUT_DIRECTORY@
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+
+INPUT_FILTER = @INPUT_FILTER@
+
+#-----------------------------------------------------------------------------
+
+
+
+
+#---------------------------------------------------------------------------
+# General configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = "Tree SSA"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER =
+
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Brazilian, Chinese, Croatian, Czech, Danish, Dutch, Finnish, French,
+# German, Greek, Hungarian, Italian, Japanese, Korean, Norwegian, Polish,
+# Portuguese, Romanian, Russian, Slovak, Slovene, Spanish and Swedish.
+
+OUTPUT_LANGUAGE = English
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these class will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = YES
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited
+# members of a class in the documentation of that class as if those members were
+# ordinary class members. Constructors, destructors and assignment operators of
+# the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. It is allowed to use relative paths in the argument list.
+
+STRIP_FROM_PATH =
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower case letters. If set to YES upper case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# users are adviced to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explict @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# reimplements.
+
+INHERIT_DOCS = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consist of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C.
+# For instance some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = .
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp
+# *.h++ *.idl *.odl
+
+FILE_PATTERNS = tree* *mudflap* c-simplify.c gimpl* domwalk*
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories
+# that are symbolic links (a Unix filesystem feature) are excluded from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+
+EXCLUDE_PATTERNS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse.
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+
+SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the Html help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript and frames is required (for instance Mozilla, Netscape 4.0+,
+# or Internet explorer 4.0+). Note that for large projects the tree generation
+# can take a very long time. In such cases it is better to disable this feature.
+# Windows users are probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = letter
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimised for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assigments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_XML = NO
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line and do not end with a semicolon. Such function macros are typically
+# used for boiler-plate code, and will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tagfiles.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or
+# super classes. Setting the tag to NO turns the diagrams off. Note that this
+# option is superceded by the HAVE_DOT option below. This is only a fallback. It is
+# recommended to install and use dot, since it yield more powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = YES
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are gif, jpg, and png
+# If left blank gif will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_WIDTH = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT = 1024
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermedate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
+
+# The CGI_NAME tag should be the name of the CGI script that
+# starts the search engine (doxysearch) with the correct parameters.
+# A script with this name will be generated by doxygen.
+
+CGI_NAME = search.cgi
+
+# The CGI_URL tag should be the absolute URL to the directory where the
+# cgi binaries are located. See the documentation of your http daemon for
+# details.
+
+CGI_URL =
+
+# The DOC_URL tag should be the absolute URL to the directory where the
+# documentation is located. If left blank the absolute path to the
+# documentation, with file:// prepended to it, will be used.
+
+DOC_URL =
+
+# The DOC_ABSPATH tag should be the absolute path to the directory where the
+# documentation is located. If left blank the directory on the local machine
+# will be used.
+
+DOC_ABSPATH =
+
+# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
+# is installed.
+
+BIN_ABSPATH = /usr/local/bin/
+
+# The EXT_DOC_PATHS tag can be used to specify one or more paths to
+# documentation generated for other projects. This allows doxysearch to search
+# the documentation for these projects as well.
+
+EXT_DOC_PATHS =
diff --git a/depcomp b/depcomp
new file mode 100755
index 00000000000..aea3d00785d
--- /dev/null
+++ b/depcomp
@@ -0,0 +1,472 @@
+#! /bin/sh
+
+# depcomp - compile a program generating dependencies as side-effects
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+# `libtool' can also be set to `yes' or `no'.
+
+if test -z "$depfile"; then
+ base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'`
+ dir=`echo "$object" | sed 's,/.*$,/,'`
+ if test "$dir" = "$object"; then
+ dir=
+ fi
+ # FIXME: should be _deps on DOS.
+ depfile="$dir.deps/$base"
+fi
+
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+ "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+ tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'. On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like `#:fec' to the end of the
+ # dependency line.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+ tr '
+' ' ' >> $depfile
+ echo >> $depfile
+
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> $depfile
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. This file always lives in the current directory.
+ # Also, the AIX compiler puts `$object:' at the start of each line;
+ # $object doesn't have directory information.
+ stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'`
+ tmpdepfile="$stripped.u"
+ outname="$stripped.o"
+ if test "$libtool" = yes; then
+ "$@" -Wc,-M
+ else
+ "$@" -M
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+
+ if test -f "$tmpdepfile"; then
+ # Each line is of the form `foo.o: dependent.h'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+ sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+icc)
+ # Intel's C compiler understands `-MD -MF file'. However on
+ # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+ # ICC 7.0 will fill foo.d with something like
+ # foo.o: sub/foo.c
+ # foo.o: sub/foo.h
+ # which is wrong. We want:
+ # sub/foo.o: sub/foo.c
+ # sub/foo.o: sub/foo.h
+ # sub/foo.c:
+ # sub/foo.h:
+ # ICC 7.1 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using \ :
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form `foo.o: dependent.h',
+ # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+ sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+tru64)
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in `foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+ if test "$libtool" = yes; then
+ tmpdepfile1="$dir.libs/$base.lo.d"
+ tmpdepfile2="$dir.libs/$base.d"
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1="$dir$base.o.d"
+ tmpdepfile2="$dir$base.d"
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2"
+ exit $stat
+ fi
+
+ if test -f "$tmpdepfile1"; then
+ tmpdepfile="$tmpdepfile1"
+ else
+ tmpdepfile="$tmpdepfile2"
+ fi
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a space and a tab in the [].
+ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the proprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ test -z "$dashmflag" && dashmflag=-M
+ # Require at least two characters before searching for `:'
+ # in the target name. This is to cope with DOS-style filenames:
+ # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+ "$@" $dashmflag |
+ sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ "$@" || exit $?
+ # Remove any Libtool call
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no
+ for arg in "$@"; do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ # Strip any option that makedepend may not understand. Remove
+ # the object too, otherwise makedepend will parse it as a source file.
+ -*|$object)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift ;;
+ esac
+ done
+ obj_suffix="`echo $object | sed 's/^.*\././'`"
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the proprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ "$@" -E |
+ sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+ sed '$ s: \\$::' > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the proprocessed file to stdout, regardless of -o,
+ # because we must use -o when running libtool.
+ "$@" || exit $?
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
+ echo " " >> "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 10ef23ca276..a925eb59660 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,3218 @@
+2004-04-20 Bryce McKinlay <mckinlay@redhat.com>
+
+ * version.c (version_string): Update for gcj-abi-2-dev-branch.
+
+2004-05-14 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (simplify_rhs_and_lookup_avail_expr): Reorganize
+ so that it picks up more opportunities to eliminate ABS expressions
+ or turn them into negations.
+
+2004-05-14 Steven Bosscher <stevenb@suse.de>
+
+ * passes.c (rest_of_handle_null_pointer): Remove.
+ (rest_of_handle_cse): Don't call rest_of_handle_null_pointer.
+ (rest_of_compilation): Likewise.
+ * rtl.h (delete_null_pointer_checks): Remove prototype.
+ * gcse.c (rd_kill, rd_gen, reaching_defs, rd_out, ae_in, ae_out):
+ Remove declarations.
+ (get_bitmap_width, alloc_rd_mem, free_rd_mem, handle_rd_kill_set,
+ compute_kill_rd, compute_rd, alloc_avail_expr_mem,
+ free_avail_expr_mem, compute_ae_gen, expr_killed_p, compute_ae_kill,
+ expr_reaches_here_p, computing_insn, def_reaches_here_p,
+ can_disregard_other_sets, handle_avail_expr, classic_gcse,
+ one_classic_gcse_pass, invalidate_nonnull_info,
+ delete_null_pointer_checks_1, delete_null_pointer_checks,
+ expr_reached_here_p_work): Remove.
+ (gcse_main): Do not perform classic GCSE when optimizing for size.
+ (alloc_pre_mem, free_pre_mem): Don't touch ae_in and ae_out, they
+ are never used.
+
+2004-05-14 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR optimization/14466
+ * tree-complex.c (make_temp): Remove.
+ (gimplify_val): Replace make_temp with make_rename_temp
+ and add NULL as the second argument.
+ (expand_complex_div_wide): Likewise.
+ * tree-dfa.c (make_rename_temp): New function.
+ * tree-flow.h (make_rename_temp): Declare.
+ * tree-sra.c (make_temp): Remove.
+ (lookup_scalar): Replace make_temp with make_rename_temp.
+ (create_scalar_copies): Likewise.
+ * tree-ssa-phiopt.c (conditional_replacement): When we
+ get non gimple create a temporary variable to hold the
+ casted expression.
+
+2004-05-14 Paul Brook <paul@codesourcery.com>
+
+ * stor-layout.c (update_alignment_for_field): Use
+ targetm.align_anon_bitfield.
+ * target-def.h (TARGET_ALIGN_ANON_BITFIELD): Define.
+ (TARGET_INITIALIZER): Use it.
+ * target.h (struct gcc_target): Add align_anon_bitfield.
+ * config/arm/arm.c (arm_align_anon_bitfield): New function.
+ (TARGET_ALIGN_ANON_BITFIELD): Define.
+ * doc/tm.texi: Document TARGET_ALIGN_ANON_BITFIELD.
+
+2004-05-13 Zack Weinberg <zack@codesourcery.com>
+
+ * tree.def (documentation): Remove mention of class 'b'.
+ (BLOCK): Now in class 'x'.
+ * c-common.c (verify_tree): Remove case 'b'.
+ * c-typeck.c (same_translation_unit_p): Change 'b' to 'x'.
+ * calls.c (calls_function_1): Control cannot get past the switch
+ when exp is a BLOCK.
+ * print-tree.c (print_node): Move code for class 'b' to the class
+ 'c'/'x' switch, as case BLOCK.
+ * tree.c (tree_size, make_node_stat, tree_node_structure): Likewise.
+ (unsafe_for_reeval, substitute_placeholder_in_expr)
+ (stabilize_reference_1): Remove case 'b'.
+ * tree-browser.c (browse_tree): Change all tests for TREE_CODE_CLASS
+ of something being 'b' to tests for TREE_CODE of something being
+ BLOCK.
+ * tree-ssa-operands.c (get_expr_operands): Likewise.
+
+2004-05-13 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-gimple.c: Rename from tree-simple.c.
+ * tree-gimple.h: Rename from tree-simple.h.
+ * c-gimplify.c: Rename from c-simplify.c
+ * Makefile.in, c-decl.c, gimple-low.c, gimplify.c,
+ langhooks.c, tree-alias-ander.c, tree-alias-common.c,
+ tree-complex.c, tree-dfa.c, tree-flow.h, tree-inline.c,
+ tree-into-ssa.c, tree-iterator.c, tree-mudflap.c,
+ tree-nested.c, tree-nomudflap.c, tree-outof-ssa.c, tree-sra.c,
+ tree-ssa-alias.c, tree-ssa-ccp.c, tree-ssa-copyrename.c,
+ tree-ssa-dce.c, tree-ssa-live.c, tree-ssa-pre.c, tree-ssa.c:
+ Update.
+
+2004-05-14 Ranjit Mathew <rmathew@hotmail.com>
+
+ * doc/sourcebuild.texi: Mention libbanshee and libmudflap.
+
+2004-05-13 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * tree-ssa.c (delete_tree_ssa): XFREE
+ bitmaps allocated with BITMAP_XMALLOC.
+
+ * tree-ssa-pre.c (execute_pre): Free ephi_use_pool and
+ idfs_cache at the end of the function.
+
+ * tree-ssa-live.c (calculate_live_on_entry): Free saw_def
+ at the end of the function.
+
+ * tree-ssa-dce.c (perform_tree_ssa_dce): Free
+ el at the end of the function.
+
+ * tree-into-ssa.c (insert_phi_nodes_for): XFREE
+ bitmaps allocated with BITMAP_XMALLOC.
+
+ * loop-unswitch.c (unswitch_single_loop): Free bbs at
+ the end.
+
+ * final.c (shorten_branches): Free uid_shuid before
+ reallocating it.
+
+ * bb-reoder.c (connect_traces): Free cold_traces at the end.
+
+2004-05-13 Jeff Law <law@redhat.com>
+
+ * tree-ssa-live.c (calculate_live_on_entry): Ignore virtual
+ variables. Simplify slightly by using USE_OP/DEF_OP instead
+ of USE_OP_PTR/DEF_OP_PTR and dereferencing the result.
+
+ * tree-into-ssa.c (compute_global_livein): Use EXECUTE_IF_SET_IN_BITMAP
+ rather than iterating through the blocks testing each bit in
+ livein to initialize the worklist.
+ (mark_def_sites): Remove useless checks of KILLS for virtual
+ operands.
+
+ * tree-ssa-forwprop.c (record_single_argument_cond_exprs): Accept
+ new parameters for the statement and variable worklist as well
+ as a bitmap of interesting SSA_NAMEs. Walk over the statement
+ worklist recording interesting variables in the variable worklist
+ and bitmap. Handle casts between integral and boolean types.
+ (substitute_single_use_vars): Accept new parameters for the statement
+ and variable worklist. When a substitution is made add a new
+ entry to the statement worklist. Handle casts between integral
+ and boolean types.
+ (tree_ssa_forward_propagate_single_use_vars): Rework to pass
+ worklists to children. Iterate until the statement worklist
+ is empty.
+
+2004-05-13 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * tree-outof-ssa.c (rewrite_vars_out_of_ssa): Free map at
+ the end of the block.
+
+ * tree-into-ssa.c (def_blocks_free): XFREE bitmaps allocated
+ with BITMAP_XMALLOC.
+
+ * tree-ssa-alias.c (delete_alias_info): XFREE bitmaps allocated
+ with BITMAP_XMALLOC.
+
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize):
+ Free nonzero_vars at the end of the function.
+
+ * convert.c (convert_to_integer): Make a CONVERT_EXPR when there is a
+ need to generate code instead of a NOP_EXPR.
+
+2004-05-13 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * gcc.c (default_compilers): Fill out initializers for new Fortran
+ entries.
+
+2004-05-13 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.h (PCC_BITFIELD_TYPE_MATTERS): Define.
+
+2004-05-13 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.c (arm_default_short_enums): New function.
+ (TARGET_DEFAULT_SHORT_ENUMS): Define.
+
+2004-05-13 Diego Novillo <dnovillo@redhat.com>
+
+ Merge from tree-ssa-20020619-branch.
+
+ * Makefile.in (reload1.o-warn): Add.
+ (tree-alias-ander.o-warn): Add.
+ (GMPLIBS): Define.
+ (GMPINC): Define.
+ (BANSHEELIB): Define.
+ (BANSHEEINC): Define.
+ (TREE_DUMP_H): Define.
+ (TREE_SIMPLE_H): Define.
+ (TREE_FLOW_H): Define.
+ (LIBDEPS): Add BANSHEELIB.
+ (INCLUDES): Add BANSHEEINC and GMPINC.
+ (C_AND_OBJC_OBJS): Add c-simplify.o, tree-mudflap.o,
+ c-mudflap.o and c-pretty-print.o.
+ (C_OBJS): Remove c-pretty-print.o.
+ (OBJS-common): Remove sibcall.o.
+ Add tree-cfg.o, tree-dfa.o, tree-eh.o,
+ tree-ssa.o, tree-optimize.o, tree-simple.o,
+ tree-alias-type.o, gimplify.o, tree-pretty-print.o,
+ tree-into-ssa.o, tree-outof-ssa.o, tree-alias-common.o,
+ tree-ssa-ccp.o, @ANDER@, tree-ssa-dce.o, tree-ssa-copy.o,
+ tree-nrv.o, tree-ssa-copyrename.o, tree-ssa-pre.o,
+ tree-ssa-live.o, tree-ssa-operands.o, tree-ssa-alias.o,
+ tree-ssa-phiopt.o, tree-ssa-forwprop.o, tree-nested.o,
+ tree-ssa-dse.o, tree-ssa-dom.o, domwalk.o,
+ tree-tailcall.o, gimple-low.o, tree-iterator.o,
+ tree-phinodes.o, tree-ssanames.o, tree-sra.o,
+ tree-complex.o, tree-ssa-loop.o, rtl-profile.o and
+ tree-profile.o.
+ (OBJC-archive): Add tree-nomudflap.o.
+ (cc1): Add dependency on @TREEBROWSER@.
+ (c-decl.o): Add dependency on TREE_DUMP_H.
+ (c-dump.o): Likewise.
+ (c-common.o): Add dependency on tree-iterator.h
+ (c-pretty-print.o): Add dependency on DIAGNOSTIC_H.
+ (gtype-desc.o): Add dependency on TREE_FLOW_H.
+ (tree.o): Add dependency on tree-iterator.h,
+ BASIC_BLOCK_H and TREE_FLOW_H.
+ (tree-dump.o): Depend on TREE_DUMP_H instead of tree-dump.h.
+ (langhooks.o): Add dependency on TREE_SIMPLE_H.
+ (tree-alias-type.o, tree-alias-ander.o,
+ tree-alias-common.o, tree-ssa.o, tree-into-ssa.o,
+ tree-outof-ssa.o, tree-ssa-dse.o, tree-ssa-forwprop.o,
+ tree-ssa-phiopt.o, tree-nrv.o, tree-ssa-copy.o,
+ tree-ssa-dom.o, tree-ssanames.o, tree-phinodes.o,
+ domwalk.o, tree-ssa-live.o, tree-ssa-copyrename.o,
+ tree-ssa-pre.o, tree-cfg.o, tree-tailcall.o,
+ tree-nested.o, tree-iterator.o, tree-dfa.o,
+ tree-ssa-operands.o, tree-eh.o, tree-ssa-loop.o,
+ tree-ssa-alias.o, tree-optimize.o, c-simplify.o,
+ gimplify.o, gimple-low.o, tree-browser.o, tree-simple.o,
+ tree-mudflap.o, c-mudflap.o, tree-nomudflap.o,
+ tree-pretty-print.o, tree-ssa-dce.o, tree-ssa-ccp.o,
+ tree-sra.o, tree-complex.o, tree-profile.o,
+ rtl-profile.o): New rules.
+ (function.o): Add dependency on basic-block.h
+ (expr.o): Add dependency on tree-iterator.h.
+ (sibcall.o): Remove.
+ (profile.o): Depend on TREE_FLOW_H instead of TREE_H.
+ (cfg.o): Add dependency on TIMEVAR_H.
+ (cfghooks.o): Add dependency on TREE_FLOW_H.
+ (reg-stack.o): Add dependency on basic-block.h.
+ (GTFILES): Add hwint.h, tree-mudflaph.c, tree-flow.h,
+ c-objc-common.c, c-common.c, c-parse.in, tree-ssanames.c,
+ tree-eh.c, tree-phinodes.c, tree-cfg.c, tree-dfa.c,
+ tree-ssa-ccp.c, tree-iterator.c, gimplify.c,
+ tree-alias-type.h, tree-alias-common.h,
+ tree-alias-type.c, tree-alias-common.c,
+ tree-ssa-operands.h, tree-ssa-operands.c, tree-profile.c,
+ rtl-profile.c and tree-nested.c.
+ (gt-tree-alias-common.h, gt-tree-mudflap.h,
+ gt-tree-ssa-ccp.h, gt-tree-eh.h, gt-tree-ssanames.h,
+ gt-tree-iterator.h, gt-gimplify.h, gt-tree-phinodes.h,
+ gt-tree-cfg.h, gt-tree-nested.h): New rules.
+ (TEXI_GCCINT_FILES): Add cfg.texi and tree-ssa.texi.
+ * basic-block.h: Include predict.h
+ (struct edge_def): Add GTY marker.
+ Change field 'insns' to be a union of tree and rtx.
+ (EDGE_TRUE_VALUE): Define.
+ (EDGE_FALSE_VALUE): Define.
+ (EDGE_EXECUTABLE): Define.
+ (struct bb_ann_d): Forward declare.
+ (struct basic_block_def): Add GTY marker.
+ Remove fields head_tree and end_tree.
+ Add fields stmt_list, rbi and tree_annotations.
+ (struct reorder_block_def): Define.
+ (basic_block_info): Add GTY marker.
+ (ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR): Change to global
+ variables instead of macros.
+ (flow_call_edges_add): Remove declaration.
+ (make_eh_edge): Remove declaration.
+ (brief_dump_cfg, find_edge, tree_predicted_by_p,
+ rtl_predicted_by_p, tree_predict_edge, rtl_predict_edge,
+ predict_edge_def, rtl_make_eh_edge, find_basic_blocks,
+ cleanup_cfg, delete_unreachable_blocks, merge_seq_blocks,
+ alloc_rbi_pool, initialize_bb_rbi, free_rbi_pool): Declare.
+ (try_redirect_by_replacing_jump): Modfiy return type to
+ edge instead of bool.
+ * bb-reorder.c (copy_bb): Call duplicate_block
+ instead of cfg_layout_duplicate_bb.
+ (copy_bb_p): Call can_duplicate_block_p instead of
+ cfg_layout_can_duplicate_bb_p.
+ * bitmap.c (bitmap_first_set_bit): Abort if word
+ wasn't found.
+ (bitmap_last_set_bit): Likewise.
+ * builtin-types.def (DEF_FUNCTION_TYPE_2): Add
+ (DEF_FUNCTION_TYPE_3): Add.
+ * builtins.c (c_strlen): Make extern.
+ (builtin_save_expr): New.
+ (expand_builtin_nonlocal_goto): New.
+ (expand_builtin_constant_p): Remove.
+ (expand_builtin_mathfn): Call builtin_save_expr instead
+ of save_expr.
+ (expand_builtin_mathfn_2): Likewise.
+ (expand_builtin_strcmp): Likewise.
+ (expand_builtin_strncmp): Likewise.
+ (expand_builtin_strcat): Likewise.
+ (fold_builtin_cabs): Likewise.
+ (expand_builtin_alloca): Don't trigger if -fmudflap is
+ given.
+ (build_string_literal): Set TREE_INVARIANT on new node.
+ (expand_builtin_profile_fun): New.
+ (round_trampoline_addr): New.
+ (expand_builtin_init_trampoline): New.
+ (expand_builtin_adjust_trampoline): New.
+ (expand_builtin) <BUILT_IN_NEXT_ARG>: Call simplify_builtin_next_arg.
+ <BUILT_IN_CONSTANT_P>: Return const0_rtx;
+ <BUILT_IN_STACK_ALLOC, BUILT_IN_STACK_SAVE,
+ BUILT_IN_STACK_RESTORE, BUILT_IN_NONLOCAL_GOTO,
+ BUILT_IN_PROFILE_FUNC_ENTER, BUILT_IN_PROFILE_FUNC_EXIT,
+ BUILT_IN_INIT_TRAMPOLINE, BUILT_IN_ADJUST_TRAMPOLINE>:
+ Handle.
+ (fold_builtin_expect): New.
+ (fold_builtin_isascii): Don't return non-constant results
+ in GIMPLE form.
+ (fold_builtin_isdigit): Likewise.
+ (fold_builtin_1): New.
+ (fold_builtin): Call it.
+ (build_function_call_expr): Update call to build a new
+ CALL_EXPR.
+ (purge_builtin_constant_p): Remove.
+ (simplify_builtin, simplify_builtin_memcmp,
+ simplify_builtin_strcmp, simplify_builtin_strncmp,
+ simplify_builtin_strpbrk, simplify_builtin_strstr,
+ simplify_builtin_strchr, simplify_builtin_strrchr,
+ simplify_builtin_strcat, simplify_builtin_strncat,
+ simplify_builtin_strspn, simplify_builtin_strcspn,
+ simplify_builtin_next_arg, simplify_builtin_va_start,
+ simplify_builtin_sprintf): New.
+ * builtins.def (BUILT_IN_STACK_ALLOC,
+ BUILT_IN_STACK_SAVE, BUILT_IN_STACK_RESTORE,
+ BUILT_IN_INIT_TRAMPOLINE, BUILT_IN_ADJUST_TRAMPOLINE,
+ BUILT_IN_NONLOCAL_GOTO, BUILT_IN_PROFILE_FUNC_ENTER,
+ BUILT_IN_PROFILE_FUNC_EXIT): Define.
+ * c-common.c: Include tree-iterator.h and hashtab.h.
+ (lang_statement_code_p): Declare.
+ (lang_gimplify_stmt): Declare.
+ (fix_string_type): Set TREE_INVARIANT for value.
+ (pointer_int_sum): Rely on build to set TREE_CONSTANT.
+ (c_type_hash): New.
+ (c_common_get_alias_set): Handle multiple type nodes
+ referring to "the same" type, currently for C90 only.
+ (c_add_case_label): Use create_artificial_label.
+ (finish_label_address_expr): Don't set TREE_CONSTANT on
+ result.
+ (c_expand_expr): Don't handle STMT_EXPR.
+ (handle_alias_attribute): Marke aliased variables to be
+ TREE_STATIC.
+ (handle_nonnull_attribute): Initialize arg_num.
+ (check_function_nonnull): Likewise.
+ (c_walk_subtrees): New.
+ (c_estimate_num_insns_1): Don't handle
+ EXPR_WITH_FILE_LOCATION nor FILE_STMT.
+ (c_decl_uninit_1): Remove.
+ (c_decl_uninit): Remove.
+ (c_warn_unused_result): New.
+ * c-common.def (ASM_STMT): Change number of operands
+ to 4.
+ (FILE_STMT): Remove.
+ * c-common.h (lang_expand_stmt, lang_expand_decl_stmt):
+ Remove.
+ (lang_gimplify_stmt): Add.
+ (expand_stmt): Remove.
+ (ASM_CV_QUAL, ASM_STRING, ASM_OUTPUTS, ASM_INPUTS,
+ ASM_CLOBBERS, STMT_EXPR_WARN_UNUSED_RESULT,
+ ASM_VOLATILE_P, FILE_STMT_FILENAME_NODE,
+ FILE_STMT_FILENAME, STMT_LINENO, STMT_LINENO_FOR_FN_P,
+ ASM_INPUT_P, DECL_C_HARD_REGISTER): Remove.
+ (genrtl_do_pushlevel, genrtl_goto_stmt, genrtl_expr_stmt,
+ genrtl_expr_stmt_value, genrtl_decl_stmt, genrtl_if_stmt,
+ genrtl_while_stmt, genrtl_do_stmt, genrtl_return_stmt,
+ genrtl_for_stmt, genrtl_break_stmt, genrtl_continue_stmt,
+ genrtl_scope_stmt, genrtl_switch_stmt, genrtl_case_label,
+ genrtl_compound_stmt, genrtl_asm_stmt,
+ genrtl_cleanup_stmt, c_decl_uninit): Remove.
+ (c_do_switch_warnings, c_gimplify_expr, c_walk_subtrees,
+ c_tree_chain_matters_p, c_warn_unused_result,
+ c_genericize, c_gimplify_stmt, stmt_expr_last_stmt):
+ Declare.
+ * c-convert.c (convert): Make convert work when
+ converting to compatible types across translation unit.
+ * c-decl.c: Include langhooks.h, tree-mudflap.h,
+ tree-simple.h, diagnostic.h and tree-dump.h
+ (merge_decls): Initialize oldtype to NULL.
+ (finish_decl): Use DECL_HARD_REGISTER instead of
+ DECL_C_HARD_REGISTER.
+ (check_bitfield_type_and_width): Check for null
+ lang_type_specific when check the precision of an enum.
+ (grokdeclarator): Immediately layout an ARRAY_TYPE used
+ in a pointer-to-array declarator.
+ (finish_struct): Clear allocated struct lang_type.
+ (finish_enum): Set enum_min and enum_max. Set
+ TYPE_MIN/MAX_VALUE to the limits of the compatible type,
+ not to the enumerators.
+ (set_decl_nonlocal): New.
+ (store_parm_decls): Use it via walk_tree.
+ (c_finalize): New.
+ (finish_function): When !targetm.have_ctors_dtors,
+ record static constructors and destructors here...
+ (c_expand_body_1): ... not here.
+ (c_expand_decl): Rename from c_expand_decl_stmt.
+ Handle all C-specific expansion semantics.
+ * c-dump.c (dump_stmt): Use EXPR_LOCUS instead of
+ STMT_LINENO.
+ * c-format.c (handle_format_arg_attribute): Initialize
+ format_num.
+ * c-lang.c: Include tree-inline.h
+ (LANG_HOOKS_EXPAND_DECL,
+ LANG_HOOKS_FUNCTION_MISSING_NORETURN_OK_P,
+ LANG_HOOKS_TREE_INLINING_WALK_SUBTREES,
+ LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P,
+ LANG_HOOKS_GIMPLIFY_EXPR, LANG_HOOKS_TYPES_COMPATIBLE_P): Define.
+ (LANG_HOOKS_DECL_UNINIT, LANG_HOOKS_RTL_EXPAND_STMT,
+ LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS): Remove.
+ (c_types_compatible_p): New.
+ * c-mudflap.c: New file.
+ * c-objc-common.c: Include tree-mudflap.h
+ (start_cdtor, finish_cdtor): Collapse
+ together into
+ (build_cdtor): ...here. Update to construct a complete tree
+ for the function. No need to call push_scope, pop_scope, or
+ clear_last_expr, or set current_function_cannot_inline.
+ (c_missing_noreturn_ok_p): Change prototype to return
+ bool.
+ (c_objc_common_init): Don't set lang_missing_noreturn_ok_p.
+ * c-opts.c (c_common_handle_option): Move handling of -fdump- to
+ opts.c.
+ (c_common_post_options): Don't ever use rtl inlining.
+ * c-parse.in: Use EXPR_LOCUS instead of STMT_LINENO.
+ * c-pragma.c (handle_pragma_redefine_extname): Define
+ always.
+ (init_pragma): Activate #pragma redefine_extname for mudflap.
+ * c-pretty-print.c (pp_c_statement): Remove FILE_STMT.
+ (pp_c_initializer): Accept any type CONSTRUCTOR.
+ (pp_c_initializer_list): Fix code expectations for VECTOR_TYPE and
+ COMPLEX_TYPE.
+ (decl_name_str): New local function.
+ (pp_c_direct_declarator): Call it.
+ (pp_c_primary_expression): Call it.
+ (pp_c_id_expression): Call it.
+ (pp_c_statement): Call it.
+ (print_c_tree): Create new pp object.
+ * c-pretty-print.h (pp_c_tree_decl_identifier,
+ print_c_tree): Declare.
+ * c-semantics.c: Include langhooks.h
+ (lang_expand_stmt, lang_expand_decl_stmt,
+ find_reachable_label_1, find_reachable_label,
+ expand_unreachable_if_stmt, expand_unreachable_stmt,
+ genrtl_do_stmt_1): Remove.
+ (begin_stmt_tree): Don't check for changed filename.
+ Call annotate_with_locus.
+ (finish_stmt_tree): Don't set line for end of function.
+ (build_stmt): Don't check type nodes for
+ side effects.
+ (build_stmt): Set TREE_SIDE_EFFECTS.
+ Set EXPR_LOCUS instead of STMT_LINENO.
+ (lang_expand_stmt, lang_expand_decl_stmt,
+ expand_cond, genrtl_do_pushlevel, genrtl_goto_stmt, genrtl_expr_stmt,
+ genrtl_expr_stmt_value, genrtl_decl_stmt, genrtl_if_stmt,
+ genrtl_while_stmt, genrtl_do_stmt_1, genrtl_do_stmt,
+ genrtl_return_stmt, genrtl_for_stmt, genrtl_break_stmt,
+ genrtl_continue_stmt, genrtl_scope_stmt, genrtl_switch_stmt,
+ genrtl_case_label, genrtl_compound_stmt, genrtl_asm_stmt,
+ genrtl_cleanup_stmt, expand_stmt, find_reachable_label,
+ find_reachable_label_1, expand_unreachable_if_stmt,
+ expand_unreachable_stmt): Remove.
+ (prep_stmt): Use EXPR_LOCUS instead of STMT_LINENO.
+ * c-simplify.c: New file.
+ * c-tree.h (C_LANG_TREE_NODE_CHAIN_NEXT): Define.
+ (struct lang_type): Add fields enum_min and enum_max.
+ (c_expand_decl_stmt, c_missing_noreturn_ok_p): Remove.
+ (c_expand_decl, c_missing_noreturn_ok_p,
+ c_types_compatible_p): Declare.
+ * c-typeck.c (tagged_types_tu_compatible_p): Allow for
+ compiler-generated TYPE_DECLs without a DECL_ORIGINAL_TYPE.
+ (default_function_array_conversion): Rely on build to
+ set TREE_CONSTANT.
+ (parser_build_binary_op, pointer_diff): Likewise.
+ (build_unary_op, build_binary_op): Likewise.
+ (build_array_ref):
+ (build_external_ref): Set TREE_INVARIANT.
+ (build_c_cast, pop_init_level): Likewise.
+ (process_init_element): Use ASM_VOLATILE_P.
+ (build_asm_expr): Adapt to GENERIC/GIMPLE syntax.
+ (c_finish_case): Call c_do_switch_warnings.
+ * c.opt (fdump-): Remove.
+ * calls.c (try_to_integrate): Remove.
+ (prepare_call_address): Replace fndecl arg with a
+ precomputed static chain value.
+ (emit_call_1): New argument for full call expr.
+ (flags_from_decl_or_type): Call special_function_p.
+ (initialize_argument_information): Add argument
+ may_tailcall.
+ (purge_reg_equiv_notes): New.
+ (expand_call): Do not try to expand calls inline.
+ (fixup_tail_calls): New.
+ * cfg.c: Include timevar.h and ggc.h.
+ (bb_pool, edge_pool): Remove.
+ (ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR): Declare.
+ (entry_exit_blocks): Remove.
+ (rbi_pool): Declare.
+ (init_flow): Do not create pools.
+ Allocate entry/exit block.
+ (free_edge, alloc_block, expunge_block, unchecked_make_edge): Use GGC.
+ (alloc_rbi_pool, free_rbi_pool, initialize_bb_rbi): New.
+ (unlink_block): Clear b->prev_bb and b->next_bb.
+ (compact_blocks): Clear all slots of BASIC_BLOCK array.
+ (dump_flow_info): Work on trees too.
+ (dump_cfg_bb_info): New.
+ (brief_dump_cfg): New.
+ * cfganal.c (need_fake_edge_p, flow_call_edges_add): Remove.
+ (find_edge): New.
+ * cfgbuild.c (rtl_make_eh_edge): Rename from
+ make_eh_edge. Update all users.
+ (find_basic_blocks): Don't call VARRAY_FREE on
+ basic_block_info.
+ * cfgcleanup.c (outgoing_edges_match): Initialize newpos1
+ and newpos2.
+ (delete_unreachable_blocks): Return changed status.
+ (merge_seq_blocks): New.
+ * cfghooks.c: Include tree-flow.h
+ (tree_register_cfg_hooks, ir_type): New.
+ (redirect_edge_and_branch): Change return type to edge.
+ (predict_edge, predicted_by_p, can_duplicate_block_p,
+ duplicate_block, block_ends_with_call_p,
+ block_ends_with_condjump_p, flow_call_edges_add): New.
+ * cfghooks.h (redirect_edge_and_branch): Change return
+ type to edge.
+ (predict_edge, predicted_by_p, can_duplicate_block_p,
+ duplicate_block, block_ends_with_call_p,
+ block_ends_with_condjump_p, flow_call_edges_add): Declare.
+ (redirect_edge_and_branch): Change return type to edge.
+ (struct cfg_hooks): Add fields block_ends_with_call_p,
+ block_ends_with_condjump_p, flow_call_edges_add,
+ predict_edge, predicted_by_p, can_duplicate_block_p and
+ duplicate_block.
+ (tree_cfg_hooks, ir_type, tree_register_cfg_hooks): Declare.
+ * cfglayout.c (cfg_layout_pool, cfg_layout_initialize_rbi): Removed.
+ (fixup_reorder_chain): Use initialize_bb_rbi.
+ (cfg_layout_can_duplicate_bb_p, cfg_layout_duplicate_bb): Hookized.
+ (cfg_layout_initialize): Use cfg.c rbi pool manipulation functions.
+ (can_copy_bbs_p, copy_bbs): Use cfghooks for bb duplication.
+ (insn_locators_initialize): Use new info about blocks.
+ * cfglayout.h (typedef struct reorder_block_def): Moved to
+ basic_block.h.
+ (cfg_layout_can_duplicate_bb_p, cfg_layout_duplicate_bb): Declaration
+ removed.
+ * cfgloop.c: Include tree.h and tree-flow.h.
+ * cfgloop.h (create_loop_notes): Declare.
+ * cfgloopmanip.c (create_loop_notes): New.
+ * cfgrtl.c (cfg_layout_create_basic_block): Use initialize_bb_rbi.
+ (rtl_cfg_hooks, cfg_layout_rtl_cfg_hook): Fill in can_duplicate_block_p
+ and duplicate_block fields.
+ (create_basic_block_structure): Don't look at
+ RTX_INTEGRATED_P.
+ (rtl_block_ends_with_call_p): New.
+ (rtl_block_ends_with_condjump_p): New.
+ (need_fake_edge_p): Moved from cfganal.c.
+ (rtl_flow_call_edges_add): Moved from cfganal.c (flow_call_edges_add).
+ (rtl_cfg_hooks): Add rtl_block_ends_with_call_p,
+ rtl_block_ends_with_condjump_p, rtl_flow_call_edges_add.
+ (cfg_layout_rtl_cfg_hooks): Ditto.
+ * cgraph.c (cgraph_mark_reachable_node): Don't force nested
+ functions to be reachable.
+ * cgraphunit.c (decide_is_function_needed):
+ * cgraphunit.c (decide_is_function_needed): Nested functions of extern
+ inline functions don't need to be output.
+ (cgraph_assemble_pending_functions): Don't do anything
+ special for nested functions.
+ (cgraph_mark_functions_to_output): Likewise.
+ (cgraph_finalize_function): Don't zap DECL_STRUCT_FUNCTION.
+ (cgraph_analyze_function): Use estimate_num_insns.
+ (cgraph_mark_functions_to_output): Likewise.
+ (cgraph_estimate_growth, cgraph_clone_inlined_nodes): Likewise.
+ (cgraph_expand_function): Allow functions to not be
+ emitted.
+ (cgraph_remove_unreachable_nodes):
+ (cgraph_recursive_inlining_p): Simplify.
+ (lookup_recursive_calls,
+ cgraph_decide_recursive_inlining): New.
+ (cgraph_decide_inlining_*): Update calls of
+ cgraph_mark_inline.
+ * combine.c (get_pos_from_mask): Always set *plen.
+ * common.opt (fdump-, fmudflap, fmudflapth, fmudflapir,
+ ftree-based-profiling, ftree-ccp, ftree-ch,
+ ftree-combine-temps, ftree-copyrename, ftree-dce,
+ ftree-dominator-opts, ftree-dse, ftree-loop-optimize,
+ ftree-points-to, ftree-pre, ftree-sra, ftree-ter,
+ ftree-lrs): Add.
+ * config.in (HAVE_LD_PIE, HAVE_BANSHEE, PREFIX_INCLUDE_DIR):
+ Undefine.
+ * configure.ac: Add --enable-tree-browser option.
+ Add --with-libbanshee option.
+ Add GMPLIBS and GMPINC.
+ * configure: Regenerate.
+ * coverage.c (tree_ctr_tables): New.
+ (coverage_counter_alloc): Use it.
+ (build_ctr_info_value): Ditto.
+ (coverage_counter_ref): Ditto. Rename to rtl_coverage_counter_ref.
+ (tree_coverage_counter_ref): New.
+ * coverage.h (coverage_counter_ref): Remove declaration.
+ (rtl_coverage_counter_ref): Declare.
+ (tree_coverage_counter_ref): Declare.
+ * cppexp.c (append_digit): Rearrange unsignedp/overflow setting.
+ (eval_token, num_binary_op, num_part_mul, num_div_op): Likewise.
+ * cse.c (fold_rtx): Do not handle CONSTANT_P_RTX.
+ (struct cse_basic_block_data): Rename enum values to not
+ conflict with profile.h; update all uses.
+ * dbxout.c (dbxout_symbol_location): Don't mention integrate.c
+ in comments.
+ * defaults.h (TRAMPOLINE_ALIGNMENT): Move from function.c.
+ * diagnostic.h (debug_output_buffer, dump_generic_node,
+ print_generic_stmt, print_generic_stmt_indented,
+ print_generic_expr, print_generic_decl,
+ debug_generic_expr, debug_generic_stmt, debug_c_tree):
+ Declare.
+ * dominance.c: Cache immediate dominators.
+ * domwalk.c: New file.
+ * domwalk.h: New file.
+ * dwarf2out.c (is_fortran): Support DW_LANG_Fortran95.
+ (gen_subprogram_die): Generate a DIE for a named
+ return value.
+ (loc_descriptor_from_tree): Treat RESULT_DECL like VAR_DECL.
+ (add_location_or_const_value_attribute): Likewise.
+ (add_bound_info): Likewise.
+ (gen_decl_die): Likewise.
+ * emit-rtl.c (maybe_set_first_label_num): New.
+ (copy_most_rtx): Don't copy the integrated flag.
+ Copy the new return_val flag.
+ * et-forest.c (MAX_NODES): Define.
+ (record_path_before_1): Abort if len is greater than
+ MAX_NODES.
+ * except.c (gen_eh_region, gen_eh_region_cleanup, gen_eh_region_try,
+ gen_eh_region_catch, gen_eh_region_allowed,
+ gen_eh_region_must_not_throw, get_eh_region_number,
+ get_eh_region_may_contain_throw, get_eh_region_tree_label,
+ set_eh_region_tree_label, expand_resx_expr): New.
+ (expand_eh_region_start, expand_start_catch): Use them.
+ (expand_end_catch): Tidy.
+ (note_eh_region_may_contain_throw): Take region argument.
+ (note_current_region_may_contain_throw): New.
+ (get_exception_filter): Export.
+ (collect_eh_region_array): Export.
+ (remove_unreachable_regions): Check ERT_TRY based on reachability
+ of catches, not reachability of continue_label. Never remove
+ ERT_MUST_NOT_THROW regions.
+ (collect_rtl_labels_from_trees): New.
+ (convert_from_eh_region_ranges): Use it.
+ (connect_post_landing_pads): Handle dying cleanups.
+ (struct reachable_info): Add callback data.
+ (add_reachable_handler): Invoke the callback.
+ (foreach_reachable_handler): New.
+ (reachable_handlers): Use it.
+ (arh_to_landing_pad, arh_to_label): New.
+ (can_throw_internal_1): Split out from can_throw_internal.
+ (can_throw_external_1): Similarly.
+ * except.h: Update.
+ * explow.c (emit_stack_save): Remove savearea mode check.
+ (update_nonlocal_goto_save_area): New.
+ (allocate_dynamic_stack_space): Use it.
+ (probe_stack_range): Never emit loop notes.
+ * expmed.c (extract_fixed_bit_field): Always propagate the
+ target for the shift if it is a REG.
+ * expr.c: Include tree-iterator.h
+ (is_zeros_p): Remove.
+ (categorize_ctor_elements_1, categorize_ctor_elements): New.
+ (count_type_elements): New.
+ (mostly_zeros_p): Use them.
+ (expr_wfl_stack): Remove.
+ (convert_move): Do nothing if to and from are the same.
+ (emit_block_move_via_loop): Don't emit LOOP notes.
+ (emit_move_insn): Don't handle CONSTANT_P_RTX.
+ (emit_move_insn_1): Don't generate inline warnings.
+ (expand_vars, expand_var): Split from ...
+ (expand_expr_1): ... here.
+ (expand_expr_real, expand_expr_real_1): Use new macros
+ EXPR_LOCATION and EXPR_HAS_LOCATION.
+ * expr.h (simplify_builtin_fputs,
+ simplify_builtin_strcpy, simplify_builtin_strncpy,
+ expand_var, fixup_tail_calls,
+ update_nonlocal_goto_save_area): Declare.
+ (lookup_static_chain, expand_inline_function,
+ mark_seen_cases): Remove.
+ (prepare_call_address): Change type of 2nd argument to
+ rtx.
+ * final.c (profile_function): Update static chain test.
+ (final): Don't look at RTX_INTEGRATED_P.
+ * flags.h (flag_mudflap, flag_mudflap_threads,
+ flag_mudflap_ignore_reads, flag_tree_pre, flag_tree_ccp,
+ flag_tree_dce, flag_tree_combine_temps,
+ flag_tree_live_range_split, flag_tree_dom, flag_tree_ch,
+ flag_tree_dse, flag_tree_sra, flag_tree_copyrename,
+ flag_tree_points_to): Declare.
+ (enum pta_type): Declare.
+ * flow.c (lang_missing_noreturn_ok_p): Remove.
+ (check_function_return_warnings): Remove.
+ (update_life_info): Update comments.
+ (free_basic_block_vars): Don't call VARRAY_FREE for
+ basic_block_info.
+ (regno_uninitialized): Remove.
+ * fold-const.c (int_const_binop): Make extern.
+ (non_lvalue): Rely on build to set TREE_CONSTANT.
+ (operand_equal_p): Replace only_const argument with
+ flags. Allow pure functions if OEP_PURE_SAME.
+ (fold): Use OEP_ONLY_CONST.
+ (invert_truthvalue) <NOP_EXPR> Break if argument is of
+ boolean type.
+ (fold_relational_hi_lo,
+ nondestructive_fold_binary_to_constant,
+ nondestructive_fold_unary_to_constant,
+ fold_read_from_constant_string): New.
+ * function.c (struct function): Remove calls_constant_p.
+ (current_function_calls_constant_p): Remove.
+ (inline_function_decl): Remove.
+ (put_var_into_stack): Don't use it.
+ (fix_lexical_addr): Likewise.
+ (inline_function_decl): Remove extern declaration.
+ (TRAMPOLINE_ALIGNMENT): Move to defaults.h.
+ (trampolines_created): Move to varasm.c.
+ (free_after_compilation): Update for removed fields.
+ (allocate_struct_function): Likewise.
+ (delete_handlers, lookup_static_chain): Remove.
+ (fix_lexical_addr): Don't consider non-local variable refs.
+ (trampoline_address): Remove.
+ (round_trampoline_addr): Move to builtins.c.
+ (adjust_trampoline_addr): Remove.
+ (expand_function_start): Update for changes to static chain
+ and nonlocal goto handling.
+ (initial_trampoline): Move to varasm.c.
+ (expand_function_end): Don't build trampolines or kill
+ unreferenced nonlocal goto labels.
+ (free_after_compilation): Don't set it.
+ (expand_function_end): Likewise.
+ (setjmp_vars_warning): Rename from
+ uninitialized_vars_warning, remove uninitialized vars warning.
+ (uninitialized_vars_warning): Remove old comment
+ and check for DECL_INITIAL, replace with a check of TREE_NO_WARNING
+ and do not call the langhook.
+ (expand_function_start, expand_function_end): Don't do
+ function instrumentation here.
+ (clear_block_marks): Rename from reorder_blocks_0, export.
+ (blocks_nreverse): Export.
+ (uninitialized_vars_warning): Use DECL_RTL_SET_P to test for presence
+ of rtl.
+ (reset_block_changes, record_block_change, finalize_block_changes,
+ check_block_change, free_block_changes): New functions.
+ (assign_parms): Setting of current_function_stdarg
+ moved ...
+ (allocate_struct_function): ... here.
+ * function.h (struct function): Remove x_nonlocal_labels,
+ x_nonlocal_goto_handler_slots, x_nonlocal_goto_stack_level,
+ x_context_display, x_trampoline_list, needs_context.
+ Add static_chain_decl, nonlocal_goto_save_area.
+ (struct function): Remove x_clobber_return_insn.
+ Add tail_call_emit field, last_label_uid,
+ unexpanded_var_list, dont_emit_block_notes,
+ ib_boundaries_block, function_end_locus and saved_tree/saved_args.
+ (clear_block_marks): Declare.
+ * gcc.c (MFWRAP_SPEC, MFLIB_SPEC): Add -fmudflapth support.
+ (mfwrap_spec, mflib_spec): Declare.
+ (cpp_unique_options, cc1_options): Ditto.
+ (default_compilers): Add .F and .f90.
+ (static_specs): Add mfwrap and mflib.
+ * gcse.c (want_to_gcse_p, gcse_constant_p): Don't handle
+ CONSTANT_RTX_P.
+ (reg_used_on_edge, reg_killed_on_edge, bypass_block):
+ Update to match insns field in struct edge_def.
+ * gdbinit.in (pgs, pge): Define.
+ * genattrtab.c (ATTR_PERMANENT_P): Use the return_val flag
+ instead of the integrated flag.
+ * gengtype-lex.l (IWOrD): Add HOST_WIDEST_INT
+ * gengtype-yacc.y (bitfieldlen): Add empty action.
+ (struct_fields): Accept unnamed bitfields.
+ (bitfieldlen): Split from ...
+ (bitfieldopt): ... here.
+ * gengtype.c (ifiles): Add tree-alias-type.h and
+ tree-flow.h.
+ * genrecog.c (validate_pattern): Do not handle
+ CONSTANT_P_RTX.
+ * gimple-low.c: New file.
+ * gimplify.c: New file.
+ * haifa-sched.c (priority): Do not handle CONSTANT_P_RTX.
+ (restore_line_notes): Do not set RTX_INTEGRATED_P.
+ * ifcvt.c (dead_or_predicable): Initialize local variable
+ 'earliest'.
+ * input.h (expr_wfl_stack): Remove.
+ * integrate.c (INTEGRATE_THRESHOLD): Remove.
+ (setup_initial_hard_reg_value_integration): Likewise.
+ (initialize_for_inline): Likewise.
+ (note_modified_parmregs): Likewise.
+ (integrate_parm_decls): Likewise.
+ (process_reg_param): Likewise.
+ (save_parm_insns): Likewise.
+ (copy_insn_list): Likewise.
+ (copy_insn_notes): Likewise.
+ (compare_blocks): Likewise.
+ (find_block): Likewise.
+ (inlining): Likewise.
+ (function_cannot_inline_p): Likewise.
+ (parmdecl_map): Likewise.
+ (in_nonparam_insns): Likewise.
+ (save_for_inline): Likewise.
+ (FIXED_BASE_PLUS): Likewise.
+ (expand_inline_function): Likewise.
+ (copy_rtx_and_substitute): Don't look at map->integrating,
+ map->inline_target, and inlining, since we are never copying
+ for integrating.
+ Don't abort on RTX_INTEGRATED_P.
+ (old_fun): Remove.
+ (output_inline_function): Remove.
+ * integrate.h (struct inline_map): Remove fields integrating,
+ block_map, leaf_reg_map, inline_target, and local_return_label.
+ * jump.c (next_nonnote_insn_in_loop, duplicate_loop_exit_test,
+ copy_loop_headers, never_reached_warning): Removed.
+ (any_uncondjump_p): Reject nonlocal goto.
+ * langhooks-def.h (lhd_types_compatible_p,
+ lhd_expand_decl, lhd_gimplify_expr): Declare.
+ (LANG_HOOKS_EXPAND_DECL, LANG_HOOKS_TYPES_COMPATIBLE_P,
+ LANG_HOOKS_FUNCTION_MISSING_NORETURN_OK_P,
+ LANG_HOOKS_FUNCTION_LEAVE_NESTED,
+ LANG_HOOKS_FUNCTION_MISSING_NORETURN_OK_P,
+ LANG_HOOKS_GIMPLIFY_EXPR,
+ LANG_HOOKS_GIMPLE_BEFORE_INLINING,
+ LANG_HOOKS_EXPAND_DECL, LANG_HOOKS_TYPES_COMPATIBLE_P,
+ LANG_HOOKS_GIMPLIFY_EXPR,
+ LANG_HOOKS_GIMPLE_BEFORE_INLINING): Define.
+ (LANG_HOOKS_DECL_UNINIT, LANG_HOOKS_RTL_EXPAND_START,
+ LANG_HOOKS_RTL_EXPAND_STMT, LANG_HOOKS_RTL_EXPAND_END,
+ LANG_HOOKS_FUNCTION_LEAVE_NESTED,
+ LANG_HOOKS_RTL_EXPAND_INITIALIZER,
+ LANG_HOOKS_DECL_UNINIT,
+ LANG_HOOKS_RTL_EXPAND_INITIALIZER): Remove.
+ * langhooks.c: Include tree-simple.h.
+ (lhd_expand_decl): New.
+ (lhd_types_compatible_p): New.
+ (lhd_decl_uninit): Remove.
+ (lhd_gimplify_expr): New.
+ * langhooks.h (struct lang_hooks_for_rtl_expansion):
+ Remove.
+ (struct lang_hooks_for_functions): Add field
+ missing_noreturn_ok_p.
+ (struct lang_hooks): Add field expand_decl,
+ types_compatible_p, gimplify_expr and
+ gimple_before_inlining.
+ Remove fields decl_uninit and rtl_expand
+ * opts.c (decode_options): Set flag_tree_ccp,
+ flag_tree_dce, flag_tree_dom, flag_tree_dse,
+ flag_tree_pre, flag_tree_ter,
+ flag_tree_live_range_split, flag_tree_sra,
+ flag_tree_copyrename and flag_tree_ch at -O1 and higher.
+ (common_handle_option): Handle OPT_fdump_, OPT_fmudflap,
+ OPT_fmudflapth, OPT_fmudflapir,
+ OPT_ftree_based_profiling, OPT_ftree_ccp, OPT_ftree_dce,
+ OPT_ftree_combine_temps, OPT_ftree_ter, OPT_ftree_lrs,
+ OPT_ftree_dominator_opts, OPT_ftree_copyrename,
+ OPT_ftree_ch, OPT_ftree_dse, OPT_ftree_sra,
+ OPT_ftree_points_to_ and OPT_ftree_pre.
+ * output.h (regno_uninitialized, find_basic_blocks,
+ cleanup_cfg, delete_unreachable_blocks,
+ check_function_return_warnings): Remove.
+ * params.def (PARAM_MAX_INLINE_INSNS_RECURSIVE,
+ PARAM_MAX_INLINE_INSNS_RECURSIVE_AUTO,
+ PARAM_MAX_INLINE_RECURSIVE_DEPTH,
+ PARAM_MAX_INLINE_RECURSIVE_DEPTH_AUTO,
+ PARAM_GLOBAL_VAR_THRESHOLD, PARAM_MAX_ALIASED_VOPS):
+ * params.h (GLOBAL_VAR_THRESHOLD, MAX_ALIASED_VOPS):
+ Define.
+ * passes.c (rest_of_decl_compilation):
+ (rest_of_handle_sibling_calls): Remove.
+ (rest_of_handle_inlining): Remove.
+ (rest_of_handle_gcse): Do not run
+ purge_builtin_constant_p.
+ (rest_of_compilation): Update.
+ Do not call copy_loop_headers.
+ Do rtl-based profiling only when
+ !flag_tree_based_profiling. Register rtl-based profiling
+ hooks.
+ * predict.c: Include tree-flow.h, ggc.h, tree-dump.h
+ (predicted_by_p): Rename to ...
+ (rtl_predicted_by_p): .. this one; make global
+ (tree_predicted_by_p): New.
+ (dump_prediction): Add FILE argument.
+ (predict_edge): Rename to ...
+ (rtl_predict_edge): .. this one.
+ (tree_predict_edge): New.
+ (combine_predictions_for_insn): Update calls of predict_edge.
+ (predict_loops): Break out from ...
+ (estimate_probability): ... here; update comments; move updating
+ of unknown probabilities from ...
+ (estimate_bb_frequencies): ... here.
+ (combine_predictions_for_bb): New.
+ (tree_predict_by_opcode): New.
+ (tree_estimate_probability): New.
+ * predict.def (PRED_TREE_POINTER, PRED_TREE_OPCODE_POSITIVE,
+ PRED_TREE_OPCODE_NONEQUAL, PRED_TREE_FPOPCODE): New predictors.
+ * predict.h: Add include guard.
+ (predict_edge, predict_edge_def): Move prototypes to basic_block.h
+ * pretty-print.c (pp_write_text_to_stream): Make extern.
+ * pretty-print.h (pp_write_text_to_stream): Declare.
+ * print-rtl.c (print_rtx): Don't print the integrated flag.
+ Print the return_val flag.
+ * print-tree.c: Use TREE_FILENAME and TREE_LINENO instead
+ of DECL_SOURCE_FILE and DECL_SOURCE_LINE respectively.
+ Remove support for EXPR_WITH_FILE_LOCATION nodes.
+ (print_node): Print TREE_INVARIANT and TREE_VISITED.
+ * profile.c: Include cfghooks.h, tree-flow.h.
+ (profile_hooks): New.
+ (profile_dump_file): New.
+ (instrument_edges): Use hooks instead of RTL-specific code.
+ (instrument_values): Ditto.
+ (get_exec_counts): Ditto.
+ (compute_branch_probabilities): Ditto.
+ (compute_value_histograms): Ditto.
+ (branch_prob): Ditto.
+ (find_spanning_tree): Ditto.
+ (end_branch_prob): Ditto.
+ (gen_edge_profiler): Move to rtl-profile.c (rtl_gen_edge_profiler).
+ (gen_interval_profiler): Ditto (rtl_gen_interval_profiler).
+ (gen_pow2_profiler): Ditto (rtl_gen_pow2_profiler).
+ (gen_one_value_profiler): Ditto (rtl_gen_one_value_profiler).
+ (tree_register_profile_hooks): New.
+ (rtl_register_profile_hooks): New.
+ * ra-rewrite.c (rewrite_program): Clear variable info.
+ * recog.c (immediate_operand): Do not handle CONSTANT_P_RTX.
+ * regs.h: Add include guards.
+ * reload.c (decompose): Clear val using memset.
+ * rtl.def (CONSTANT_P_RTX): Remove.
+ * rtl.h (CONSTANT_P): Do not handle CONSTANT_P_RTX.
+ (copy_loop_headers): Remove.
+ (struct rtx_def): Replace the integrated flag with the
+ return_val flag.
+ (maybe_set_first_label_num): Declare.
+ (init_branch_prob): Move declaration to value-prof.h.
+ (end_branch_prob): Ditto.
+ (branch_prob): Ditto.
+ (never_reached_warning): Don't declare it.
+ * rtlanal.c (get_related_value): Initialize get_jump_table_offset
+ (hoist_insn_to_edge): Update to match field insns in
+ struct edge_def.
+ * sbitmap.c (sbitmap_realloc): New.
+ * sbitmap.h (sbitmap_realloc): Declare.
+ * sibcall.c: Remove file.
+ * simplify-rtx.c (simplify_rtx): Do not handle
+ CONSTANT_P_RTX.
+ * stmt.c (parse_output_constraint): Don't warn for read-write
+ memory operand.
+ (tail_recursion_args): Use types_compatible_p langhook.
+ (force_label_rtx): Don't look at inline_function_decl.
+ (label_rtx): Set LABEL_PRESERVE_P appropriately.
+ (expand_label): Handle DECL_NONLOCAL and FORCED_LABEL.
+ (declare_nonlocal_label): Remove.
+ (expand_goto): Don't handle nonlocal gotos.
+ (expand_nl_handler_label): Remove.
+ (expand_nl_goto_receivers): Remove.
+ (expand_end_bindings): Don't expand_nl_goto_receivers. Use
+ update_nonlocal_goto_save_area.
+ (expand_expr_stmt_value): Check TREE_NO_WARNING.
+ (warn_if_unused_value): Likewise.
+ (expand_start_loop, expand_loop_continue_here,
+ expand_end_loop): Don't create loop notes.
+ (all_cases_count, BITARRAY_TEST, BITARRAY_SET,
+ mark_seen_cases, check_for_full_enumeration_handling): Remove.
+ (expand_end_case_type): Don't do warn_switch handling.
+ (pushcase, pushcase_range) Update add_case_node calls.
+ (add_case_node): Add dont_expand_label argument.
+ (same_case_target_p): Don't search rtl.
+ (expand_start_bindings_and_block, expand_end_bindings):
+ Don't emit block notes when dont_emit_block_notes.
+ (using_eh_for_cleanups_p): Export.
+ (expand_return): Allow any typed rhs.
+ (expand_stack_alloc): New.
+ (expand_stack_save, expand_stack_restore): New.
+ (containing_blocks_have_cleanups_or_stack_level): New
+ function.
+ (asm_op_is_mem_input): New fn.
+ (expand_asm_expr): New fn.
+ (warn_if_unused_value): Check operand 0 of SAVE_EXPR
+ nodes.
+ * stor-layout.c (layout_type): Just return if type is
+ error_mark_node.
+ (update_alignment_for_field): Export.
+ (variable_size): We don't care about global_bindings_p if
+ the frontend doesn't want a list of the expressions.
+ * system.h: Poison INTEGRATE_THRESHOLD.
+ * timevar.def (TV_TREE_GIMPLIFY, TV_TREE_EH, TV_TREE_CFG,
+ TV_TREE_CLEANUP_CFG, TV_TREE_PTA, TV_TREE_MAY_ALIAS,
+ TV_TREE_INSERT_PHI_NODES, TV_TREE_SSA_REWRITE_BLOCKS,
+ TV_TREE_SSA_OTHER, TV_TREE_OPS,
+ TV_TREE_SSA_DOMINATOR_OPTS, TV_TREE_SRA, TV_TREE_CCP,
+ TV_TREE_SPLIT_EDGES, TV_TREE_PRE, TV_TREE_PHIOPT,
+ TV_TREE_FORWPROP, TV_TREE_DCE, TV_TREE_CD_DCE,
+ TV_TREE_DSE, TV_TREE_LOOP, TV_TREE_CH,
+ TV_TREE_SSA_TO_NORMAL, TV_TREE_SSA_TO_NORMAL,
+ TV_TREE_NRV, TV_TREE_COPY_RENAME, TV_TREE_SSA_VERIFY,
+ TV_TREE_STMT_VERIFY, TV_DOM_FRONTIERS,
+ TV_CONTROL_DEPENDENCES): Define.
+ * toplev.c: Include tree-alias-common.h
+ (current_file_decl, flag_mudflap, flag_mudflap_threads,
+ flag_mudflap_ignore_reads, flag_tree_based_profiling,
+ flag_tree_gvn, flag_tree_points_to, flag_tree_ccp,
+ flag_tree_dce, flag_tree_ch, flag_tree_sra,
+ flag_tree_combine_temps, flag_tree_ter,
+ flag_tree_live_range_split, flag_tree_dom,
+ flag_tree_copyrename, flag_tree_dse): Declare.
+ (f_options): Add tree-based-profiling, tree-gvn,
+ tree-pre, tree-ccp, tree-dce,
+ tree-dominator-opts, tree-copyrename, tree-dse,
+ tree-combine-temps, tree-ter, tree-lrs and tree-ch.
+ (wrapup_global_declarations): Don't output nested inlined functions.
+ (general_init): Call init_tree_optimization_passes.
+ (process_options): Sorry for -ftree-based-profiling plus
+ -ftest-coverage or -fprofile-values.
+ * toplev.h (init_tree_optimization_passes,
+ flag_tree_based_profiling): Declare.
+ * tracer.c (tail_duplicate): Use cfghooks for bb duplication.
+ * tree-alias-ander.c: New file.
+ * tree-alias-ander.h: New file.
+ * tree-alias-common.c: New file.
+ * tree-alias-common.h: New file.
+ * tree-alias-type.c: New file.
+ * tree-alias-type.h: New file.
+ * tree-browser.c: New file.
+ * tree-browser.def: New file.
+ * tree-cfg.c: New file.
+ * tree-complex.c: New file.
+ * tree-dfa.c: New file.
+ * tree-dump.c (dump_enable_all): New.
+ (dequeue_and_dump): Do not handle EXPR_WITH_FILE_LOCATION.
+ (dump_node): Remove const from field suffix and swtch.
+ (dump_files): Add null entry, .generic, .nested, .vcg,
+ .xml and a match-all entry.
+ (extra_dump_files, extra_dump_files_in_use,
+ extra_dump_files_alloced): Declare
+ (dump_option_value_info): Add raw, details, stats,
+ blocks, vops, lineno, uid and all.
+ (dump_register): New.
+ (get_dump_file_info): New.
+ (dump_begin): Call it.
+ Do nothing for TDI_none.
+ (dump_begin): Include phase number in dump filename.
+ (dump_enable_all): New.
+ (dump_switch_p_1): Split out from dump_switch_p.
+ (dump_switch_p): Handle extra_dump_files.
+ Start our scan at TDI_none + 1.
+ If -fdump-tree-all was given, call dump_enable_all.
+ * tree-dump.h: Include splay-tree.h.
+ (dump_function, dump_function_to_file, dump_register):
+ Declare.
+ * tree-eh.c: New file.
+ * tree-flow-inline.h: New file.
+ * tree-flow.h: New file.
+ * tree-inline.c: Re-write to handle inlining on GIMPLE.
+ * tree-inline.h (walk_tree,
+ walk_tree_without_duplicates): Move to tree.h.
+ (estimate_num_insns): Declare.
+ * tree-into-ssa.c: New file.
+ * tree-iterator.c: New file.
+ * tree-iterator.h: New file.
+ * tree-mudflap.c: New file.
+ * tree-mudflap.h: New file.
+ * tree-nested.c: New file.
+ * tree-nomudflap.c: New file.
+ * tree-nrv.c: New file.
+ * tree-optimize.c (dump_flags, vars_to_rename,
+ in_gimple_form, all_passes, pass_gimple,
+ pass_rebuild_bind, pass_all_optimizations, pass_del_cfg): Declare.
+ (execute_gimple, execute_rebuild_bind,
+ gate_all_optimizations, execute_del_cfg,
+ register_one_dump_file, register_dump_files, dup_pass_1,
+ init_tree_optimization_passes, execute_todo,
+ execute_one_pass, execute_pass_list): New.
+ (clear_decl_rtl): Remove.
+ (tree_rest_of_compilation): Update to use tree
+ optimizers.
+ * tree-outof-ssa.c: New file.
+ * tree-pass.h: New file.
+ * tree-phinodes.c: New file.
+ * tree-pretty-print.c: New file.
+ * tree-profile.c: New file.
+ * tree-simple.c: New file.
+ * tree-simple.h: New file.
+ * tree-sra.c: New file.
+ * tree-ssa-alias.c: New file.
+ * tree-ssa-ccp.c: New file.
+ * tree-ssa-copy.c: New file.
+ * tree-ssa-copyrename.c: New file.
+ * tree-ssa-dce.c: New file.
+ * tree-ssa-dom.c: New file.
+ * tree-ssa-dse.c: New file.
+ * tree-ssa-forwprop.c: New file.
+ * tree-ssa-live.c: New file.
+ * tree-ssa-live.h: New file.
+ * tree-ssa-loop.c: New file.
+ * tree-ssa-operands.c: New file.
+ * tree-ssa-operands.h: New file.
+ * tree-ssa-phiopt.c: New file.
+ * tree-ssa-pre.c: New file.
+ * tree-ssa.c: New file.
+ * tree-ssanames.c: New file.
+ * tree-tailcall.c: New file.
+ * tree.c: Include tree-iterator.h, basic-block.h and
+ tree-flow.h.
+ (tree_node_kind): Add phi_nodes and ssa names.
+ (tree_size): Handle PHI_NODE, EPHI_NODE, SSA_NAME,
+ EUSE_NODE, EKILL_NODE, EEXIT_NODE and STATEMENT_LIST.
+ (make_node_stat): Handle PHI_NODE and SSA_NAME.
+ <'c'> Set TREE_INVARIANT.
+ (copy_node_stat): Abort if trying to copy a
+ STATEMENT_LIST.
+ Clear TREE_VISITED.
+ Clear annotation field.
+ (build_constructor): Copy TREE_INVARIANT from vals.
+ Don't clear TREE_CONSTANT.
+ (expr_first, expr_last, expr_length): Remove.
+ (staticp): Pass unknown component references to the language.
+ (save_expr): Check TREE_INVARIANT instead of TREE_CONSTANT.
+ (skip_simple_arithmetic): Likewise.
+ (stabilize_reference_1): Likewise.
+ (tree_node_structure): Handle PHI_NODE, EPHI_NODE,
+ EUSE_NODE, EKILL_NODE, EEXIT_NODE, SSA_NAME and
+ STATEMENT_LIST.
+ (lhd_unsave_expr_now): Remove.
+ (unsafe_for_reeval): Handle LABEL_EXPR and BIND_EXPR.
+ (recompute_tree_invarant_for_addr_expr): New.
+ (build1_stat): Clear EXPR_LOCUS and TREE_BLOCK.
+ Call recompute_tree_invarant_for_addr_expr.
+ Set TREE_INVARIANT accordingly.
+ (build2_stat): Don't handle CALL_EXPR.
+ (build3_stat): Don't call build2_stat for CALL_EXPRs.
+ (build_expr_wfl): Remove.
+ (annotate_with_file_line, annotate_with_locus): New.
+ (simple_cst_equal): Call simple_cst_list_equal to compare
+ CONSTRUCTOR_ELTS pointers.
+ (iterative_hash_expr): Don't hash types associated
+ with conversions. Instead hash on the signedness of the
+ toplevel object and the operand of the conversion.
+ (dump_tree_statistics): Call ssanames_print_statistics
+ and phinodes_print_statistics.
+ (ephi_node_elt_check_failed, phi_node_elt_check_failed,
+ add_var_to_bind_expr, build_empty_stmt, is_essa_node,
+ needs_to_live_in_memory): New.
+ (initializer_zerop): Handle VECTOR_CST. Don't check
+ AGGREGATE_TYPE_P for CONSTRUCTOR.
+ * tree.def (FILTER_EXPR, CASE_LABEL_EXPR, RESX_EXPR,
+ SSA_NAME, EUSE_NODE, EKILL_NODE, EPHI_NODE, EEXIT_NODE,
+ PHI_NODE, CATCH_EXPR, EH_FILTER_EXPR, STATEMENT_LIST): Define.
+ (GOTO_SUBROUTINE_EXPR): Change type to 's'.
+ (CALL_EXPR): Add another operand.
+ (EXPR_WITH_FILE_LOCATION): Remove.
+ (SWITCH_EXPR): Add another operand.
+ * tree.h: Update various comments.
+ (union tree_ann_d): Forward declare.
+ (struct tree_common): Add fields nowarning_flag,
+ invariant_flag and visited.
+ (EREF_NODE_CHECK, EPHI_NODE_ELT_CHECK,
+ PHI_NODE_ELT_CHECK, EREF_NODE_CHECK, PHI_NODE_ELT_CHECK,
+ EPHI_NODE_ELT_CHECK, TREE_BLOCK,
+ STRIP_USELESS_TYPE_CONVERSION, CALL_EXPR_TAILCALL,
+ TREE_NO_WARNING, FORCED_LABEL, TREE_INVARIANT,
+ IS_EMPTY_STMT, EXPR_LOCUS, SET_EXPR_LOCUS, EXPR_FILENAME,
+ EXPR_LINENO, EXPR_LOCATION, EXPR_HAS_LOCATION,
+ EXIT_EXPR_COND, SWITCH_COND, SWITCH_BODY, SWITCH_LABELS,
+ CASE_LOW, CASE_HIGH, CASE_LABEL, BIND_EXPR_VARS,
+ BIND_EXPR_BODY, BIND_EXPR_BLOCK, GOTO_DESTINATION,
+ ASM_STRING, ASM_OUTPUTS, ASM_INPUTS, ASM_CLOBBERS,
+ ASM_INPUT_P, ASM_VOLATILE_P, COND_EXPR_COND,
+ COND_EXPR_THEN, COND_EXPR_ELSE, LABEL_EXPR_LABEL,
+ CATCH_TYPES, CATCH_BODY, EH_FILTER_TYPES,
+ EH_FILTER_FAILURE, EH_FILTER_MUST_NOT_THROW,
+ SSA_NAME_VAR, SSA_NAME_DEF_STMT, SSA_NAME_VERSION,
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI, SSA_NAME_IN_FREE_LIST,
+ PHI_RESULT, PHI_REWRITTEN, PHI_NUM_ARGS,
+ PHI_ARG_CAPACITY, PHI_ARG_ELT, PHI_ARG_EDGE, PHI_ARG_DEF,
+ EREF_PROCESSED, EREF_ID, EREF_NAME, EREF_STMT,
+ EREF_RELOAD, EREF_SAVE, EREF_CLASS, EREF_INJURED,
+ EREF_TEMP, EUSE_DEF, EUSE_PHIOP, EUSE_INSERTED,
+ EUSE_LVAL, EPHI_NUM_ARGS, EPHI_ARG_CAPACITY,
+ EPHI_ARG_ELT, EPHI_ARG_EDGE, EPHI_ARG_PRED, EPHI_ARG_DEF,
+ EPHI_ARG_INJURED, EPHI_ARG_DELAYED_RENAME,
+ EPHI_ARG_HAS_REAL_USE, EPHI_ARG_STOPS,
+ EPHI_ARG_PROCESSED2, EPHI_IDENTITY, EPHI_IDENT_INJURED,
+ EPHI_REP_OCCUR_KNOWN, EPHI_IDENTICAL_TO, EPHI_DOWNSAFE,
+ EPHI_CANT_BE_AVAIL, EPHI_DEAD, EPHI_USES, EPHI_STOPS,
+ TREE_VISITED, SSA_VAR_P, DECL_NUM_STMTS,
+ DECL_HARD_REGISTER, DECL_PTA_ALIASVAR, LABEL_DECL_UID,
+ DECL_NEEDS_TO_LIVE_IN_MEMORY_INTERNAL,
+ STATEMENT_LIST_HEAD, STATEMENT_LIST_TAIL, TDF_RAW,
+ TDF_DETAILS, TDF_STATS, TDF_BLOCKS, TDF_VOPS, TDF_LINENO,
+ TDF_UID,): Define.
+ (TREE_NO_UNUSED_WARNING, EXPR_WFL_EMIT_LINE_NOTE,
+ EXPR_WFL_NODE, EXPR_WFL_FILENAME_NODE, EXPR_WFL_FILENAME,
+ EXPR_WFL_LINECOL, EXPR_WFL_LINENO, EXPR_WFL_COLNO,
+ EXPR_WFL_SET_LINECOL): Remove.
+ (phi_node_elt_check_failed, ephi_node_elt_check_failed,
+ make_phi_node, init_phinodes, fini_phinodes,
+ release_phi_node, phinodes_print_statistics,
+ init_ssanames, fini_ssanames, make_ssa_name,
+ release_ssa_name, ssanames_print_statistics,
+ annotate_with_file_line, build_empty_stmt,
+ annotate_with_locus, expr_only, categorize_ctor_elements,
+ count_type_elements, add_var_to_bind_expr, is_essa_node,
+ expand_stack_alloc, expand_stack_save,
+ expand_stack_restore, add_case_node, operand_equal_p,
+ nondestructive_fold_unary_to_constant,
+ nondestructive_fold_binary_to_constant,
+ fold_read_from_constant_string, int_const_binop,
+ strip_float_extensions, simplify_builtin, c_strlen,
+ recompute_tree_invarant_for_addr_expr,
+ needs_to_live_in_memory, make_vector,
+ setjmp_vars_warning, update_alignment_for_field,
+ expand_asm_expr, asm_op_is_mem_input,
+ containing_blocks_have_cleanups_or_stack_level,
+ create_artificial_label, gimplify_function_tree,
+ get_name, unshare_expr, walk_tree,
+ walk_tree_without_duplicates, in_gimple_form): Declare.
+ (struct tree_exp): Add fields locus and block.
+ (struct tree_ssa_name, struct edge_def, struct
+ tree_phi_node, struct tree_eref_common, struct
+ tree_euse_node, struct ephi_arg_d, struct tree_ephi_node,
+ union alias_var_def, struct tree_statement_list_node,
+ struct tree_statement_list, enum operand_equal_flag): Declare.
+ (enum tree_node_structure_enum): Add TS_SSA_NAME,
+ TS_PHI_NODE, TS_EPHI_NODE, TS_EUSE_NODE, TS_EREF_NODE,
+ TS_STATEMENT_LIST.
+ (union tree_node): Add fields ssa_name, phi, eref, ephi,
+ euse and stmt_list.
+ (function_cannot_inline_p, uninitialized_vars_warning,
+ save_for_inline, output_inline_function, all_cases_count,
+ check_for_full_enumeration_handling,
+ declare_nonlocal_label): Remove.
+ (enum tree_dump_index): Add TDI_none, TDI_tu,
+ TDI_generic, TDI_nested, TDI_vcg, TDI_xml.
+ * unroll.c (unroll_loop): Don't clear map->inline_target.
+ * unwind-sjlj.c (uw_install_context): Make a proper static inline
+ function.
+ * value-prof.c (value_prof_hooks): New.
+ (find_values_to_profile): Rename to rtl_find_values_to_profile.
+ Move rtl-specific bits in from branch_prob.
+ (value_profile_transformations): Rename to
+ rtl_value_profile_transformations.
+ (struct value_prof_hooks): New.
+ (rtl_value_prof_hooks): New.
+ (rtl_register_value_prof_hooks): New.
+ (tree_find_values_to_profile): New stub.
+ (tree_value_profile_transformations): New stub.
+ (tree_value_prof_hooks): New stub.
+ (tree_register_value_prof_hooks): New stub.
+ (find_values_to_profile): New.
+ (value_profile_transformations): New.
+ * value-prof.h: Add multiple inclusion guard.
+ (struct histogram_value): Change rtx fields to void *.
+ (rtl_register_value_prof_hooks): New declaration.
+ (tree_register_value_prof_hooks): New declaration.
+ (find_values_to_profile): New declaration.
+ (free_profiled_values): New declaration.
+ (value_profile_transformations): New declaration.
+ (struct profile_hooks): New declaration.
+ (init_branch_prob): Declaration moved from rtl.h.
+ (branch_prob): Declaration moved from rtl.h.
+ (end_branch_prob): Declaration mooved from rtl.h.
+ (tree_register_profile_hooks): New declaration.
+ (rtl_register_profile_hooks): New declaration.
+ (tree_profile_hooks): New declaration.
+ (rtl_profile_hooks): New declaration.
+ * varasm.c: Include tree-mudflap.h.
+ (TRAMPOLINE_ALIGNMENT): Remove.
+ (make_decl_rtl): Call mudflap_enqueue_decl.
+ (assemble_static_space):
+ (assemble_trampoline_template): Set and return
+ TRAMPOLINE_ALIGNMENT.
+ * varray.c (element): Add GENERIC_PTR_NOGC entry.
+ Add entry for 'tree *'.
+ Add entry for struct edge_def *.
+ (varray_copy): New.
+ * varray.h (enum varray_data_enum): Add
+ VARRAY_DATA_GENERIC_NOGC, VARRAY_DATA_EDGE and
+ VARRAY_DATA_TREE_PTR.
+ (union varray_data_tag): Corresponding changes.
+ (VARRAY_GENERIC_PTR_NOGC_INIT, VARRAY_EDGE_INIT,
+ VARRAY_TREE_PTR_INIT, VARRAY_GENERIC_PTR_NOGC,
+ VARRAY_EDGE, VARRAY_TREE_PTR,
+ VARRAY_PUSH_GENERIC_PTR_NOGC, VARRAY_PUSH_EDGE,
+ VARRAY_PUSH_TREE_PTR, VARRAY_TOP_GENERIC_PTR_NOGC,
+ VARRAY_TOP_EDGE, VARRAY_TOP_TREE_PTR): Define.
+
+ * config/*/*: Various updates for changed macros, tree
+ codes, etc. Check ChangeLog.tree-ssa.
+
+ * doc/cfg.texi: New file.
+ * doc/tree-ssa.texi: New file.
+ * doc/c-tree.texi: Document new codes.
+ * doc/gccint.texi: Include new files.
+ * doc/install.texi: Document new features.
+ * doc/invoke.texi: Document new switches.
+ * doc/passes.texi: Document new passes.
+ * doc/rtl.texi: Update changed RTL codes.
+ * doc/sourcebuild.texi: Update build instructions.
+ * doc/standards.texi: Document Fortran changes.
+ * doc/tm.texi: Update.
+
+2004-05-12 Paolo Bonzini <bonzini@gnu.org>
+
+ Replace several arrays with a struct of arrays.
+ * combine.c (struct reg_stat): New.
+ (init_reg_last_arrays): Renamed to...
+ (init_reg_last): ...this. Callers adjusted.
+ (reg_stat): New.
+ (combine_instructions): Allocate it and use it.
+ (reg_last_death, reg_last_set, reg_last_set_value,
+ reg_last_set_label, reg_last_set_table_tick,
+ reg_last_set_invalid, reg_nonzero_bits, reg_sign_bit_copies,
+ reg_last_set_mode, reg_last_set_nonzero_bits,
+ reg_last_set_sign_bit_copies): Replace throughout
+ with items of reg_stat.
+
+2004-05-11 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ PR optimization/15100
+ * combine.c (distribute_notes): Don't create a dangling
+ REG_LIBCALL/REG_RETVAL note.
+
+2004-05-11 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.md (spe_evneg): Rename to negv2si2.
+
+ * config/rs6000/rs6000.c (bdesc_1arg): Change spe_evneg to
+ negv2si2.
+
+2004-05-11 Aldy Hernandez <aldyh@redhat.com>
+
+ * doc/md.texi (Standard Names): Fix typo in vec_init description.
+
+2004-05-11 Geoffrey Keating <geoffk@apple.com>
+
+ * doc/gty.texi (GTY Options): Clarify example.
+
+2004-05-11 Fariborz Jahanian <fjahanian@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_handle_altivec_attribute):
+ Add const qualifier to altivec vector type if one is needed.
+
+2004-05-11 Paul Brook <paul@codesourcery.com>
+
+ * flags.h (flag_short_enums): Update comment.
+ * opts.c (decode_options): Set flag_short_enums to 2.
+ * toplev.c (flag_short_enums): Update comment.
+ (process_options): Call default_short_enums target hook.
+
+2004-05-11 Andrew Pinski <pinskia@gcc.gnu.org>
+
+ PR target/14063
+ * config/rs6000/altivec.md (altivec_dssall):
+ Change to unspec_volatile.
+ (altivec_dss): Likewise.
+
+2004-05-10 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/altivec.md ("one_cmplv16qi2"): Change vnot to
+ vnor.
+ ("one_cmplv8hi2"): Same.
+ ("one_cmplv4si2"): Same.
+
+2004-05-10 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ PR target/15130
+ * config/sh/sh-protos.h (sh_expand_epilogue): Change prototype.
+ * config/sh/sh.c (output_stack_adjust): Take the sibcall epilogue
+ into account. Compute the correct number of general registers
+ for the return value. Generate a special push/pop sequence when
+ failing to get a temporary register for non SHmedia epilogue.
+ (sh_expand_epilogue): Add an argument to show whether it's for
+ sibcall or not. Set the 3rd argument of output_stack_adjust to
+ -1 if needed.
+ (sh_need_epilogue): Call sh_expand_epilogue with 0.
+ * config/sh/sh.md (sibcall_epilogue): Call sh_expand_epilogue
+ with 1.
+ (epilogue): Call sh_expand_epilogue with 0.
+
+2004-05-10 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * gcse.c (eliminate_partially_redundant_loads): Instead of returning early,
+ goto a cleanup label. After the cleanup, free the allocated memory.
+
+2004-05-10 Ziemowit Laski <zlaski@apple.com>
+
+ * config/rs6000/altivec.h (vec_sld): Add overloads for
+ argument/return types of 'vector bool int', 'vector bool short'
+ and 'vector bool char'.
+
+2004-05-10 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (store_parm_decls_newstyle): Correct test for a
+ nested function.
+
+2004-05-10 Richard Sandiford <rsandifo@redhat.com>
+
+ * read-rtl.c (read_rtx): Allow 's' and 'T' strings to be omitted,
+ treating missing ones as "".
+ * config/mips/mips.md: Remove constraints from match_operands and
+ match_scratches if they appear in define_expands (except reload*),
+ define_peephole2s, define_splits or attribute specifications.
+ * config/mips/7000.md, config/mips/sb1.md: Remove match_operand
+ constraint strings.
+
+2004-05-10 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c (function_arg_boundary): Always align
+ AltiVec vectors.
+ (function_arg_advance): Pass TARGET_32BIT -mabi=no-altivec AltiVec
+ vectors by refererence. Align the same for TARGET_64BIT to a 16
+ byte boundary. Remove useless code. Add function comment.
+ (function_arg): Similarly. Move gpr rs6000_mixed_function_arg
+ call to where it belongs.
+ (function_arg_partial_nregs): Return true for all TARGET_32BIT
+ -mabi=no-altivec AltiVec vectors. Fix debug output.
+ (rs6000_va_arg): Adjust for AltiVec change.
+
+2004-05-10 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.c (arm_promote_prototypes): Use TARGET_AAPCS_BASED.
+ * config/arm/arm.h (TARGET_AAPCS_BASED): Define.
+ (TARGET_DOUBLEWORD_ALIGN): Use it.
+ (WCHAR_TYPE): Define.
+ (WCHAR_SIZE_TYPE): Define.
+ (SIZE_TYPE): Define.
+
+2004-05-10 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c (function_arg_boundary): Align for ABI_V4
+ when size is 8 bytes.
+ (function_arg_advance): Account for stack space used by AltiVec
+ args when -mabi=altivec. Simplify alignment calculations. For
+ ABI_V4, pass AltiVec vectors by reference when -mabi=no-altivec.
+ (function_arg): Similarly.
+ (function_arg_pass_by_reference): True for ABI_V4 AltiVec when
+ not AltiVec ABI.
+ (rs6000_va_arg): Correct fp arg test. Adjust for AltiVec change.
+ Correct alignment, and align before testing reg count. Remove
+ TREE_THIS_VOLATILE from reg. Don't emit unused labels.
+ (rs6000_complex_function_value): Check TARGET_HARD_FLOAT and
+ TARGET_FPRS here..
+ (rs6000_function_value): .. not here before call.
+
+2004-05-09 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.md ("tstsflt_gpr"): Fix typo in unspec.
+
+2004-05-09 Zack Weinberg <zack@codesourcery.com>
+
+ PR 15007
+ * c-decl.c (current_file_decl): Rename to all_translation_units,
+ adjust comment.
+ (pop_scope): If popping file_scope, construct a
+ TRANSLATION_UNIT_DECL and make it the context of all the
+ symbols in the scope.
+ (push_file_scope): Don't construct a TRANSLATION_UNIT_DECL here.
+ (pushdecl): Clarify comment. Do not set DECL_CONTEXT of
+ anything to current_file_decl.
+ (pushdecl_top_level): Likewise.
+ (store_parm_decls_newstyle): Adjust check for nested function.
+ (c_write_global_declarations): Update for renamed variable.
+
+2004-05-09 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000-protos.h
+ (rs6000_conditional_register_usage): Protoize.
+
+ * config/rs6000/rs6000.c (rs6000_conditional_register_usage): New.
+
+ * config/rs6000/rs6000.h (CONDITIONAL_REGISTER_USAGE): Call
+ function.
+
+2004-05-08 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold_div_compare): New function to optimize X/C1 op C2
+ where op is a comparison operator and C1 and C2 are integer constants
+ into a range check.
+ (fold): Call fold_div_compare.
+
+2004-05-08 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * doc/install.texi (sparc-sun-solaris2*): Document bootstrap
+ problems with earlier versions of the GNU compiler.
+
+2004-05-07 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000-protos.h (rs6000_hard_regno_mode_ok_p):
+ Declare.
+
+ * config/rs6000/rs6000.c (rs6000_hard_regno_mode_ok_p): New.
+ (rs6000_hard_regno_mode_ok): New.
+ (rs6000_init_hard_regno_mode_ok): New.
+ (rs6000_override_options): Call rs6000_init_hard_regno_mode_ok.
+
+ * config/rs6000/rs6000.h (HARD_REGNO_NREGS): Use precomputed
+ result.
+
+2004-05-07 Ziemowit Laski <zlaski@apple.com>
+
+ * config/rs6000/altivec.h (vector, pixel, bool): Do not
+ define as macros #ifdef __APPLE_ALTIVEC__.
+
+2004-05-07 Fariborz Jahanian <fjahanian@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_mixed_function_arg):
+ Generate appropriate parallels for vector arguments
+ passed to vararg functions. (function_arg): make the call
+ to rs6000_mixed_function_arg for vector args as needed.
+
+2004-05-07 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_va_arg): Fix calculation of osize for
+ EABI_FLOAT_VARARGS_P.
+
+2004-05-07 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (ISA_HAS_BRANCHLIKELY): Remove TARGET_MIPS5500.
+ * config/mips/mips.c (override_options): Disable branch likely
+ instructions if TUNE_MIPS5500.
+
+2004-05-07 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (override_options): Allow the hi and lo registers
+ to store any integral mode, not just MODE_INTs.
+
+2004-05-07 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.c (arm_promote_prototypes): Use TARGET_AAPCS_BASED.
+ * config/arm/arm.h (TARGET_AAPCS_BASED): Define.
+ (TARGET_DOUBLEWORD_ALIGN): Use it.
+ (WCHAR_TYPE): Define.
+ (WCHAR_SIZE_TYPE): Define.
+ (SIZE_TYPE): Define.
+
+2004-05-07 Uros Bizjak <uros@kss-loka.si>
+
+ * config/i386/i386.c (ix86_emit_fp_unordered_jump): Use
+ testb $4, %ah insn instead of sahf insn if !TARGET_USE_SAHF.
+
+2004-05-07 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * loop-doloop.c (doloop_valid_p): Make sure that body
+ gets freed.
+
+2004-05-07 Eric Botcazou <ebotcazou@act-europe.fr>
+
+ * config/sparc/sparc-protos.h (sparc_skip_caller_unimp): New
+ declaration.
+ * config/sparc/sparc.c (SKIP_CALLERS_UNIMP_P): Delete.
+ (sparc_skip_caller_unimp): New global variable.
+ (sparc_function_epilogue): Set 'sparc_skip_caller_unimp'.
+ Use it instead of SKIP_CALLERS_UNIMP_P.
+ * config/sparc/sparc.md (call expander): Add sanity check.
+ (call_address_struct_value_sp32): Re-sync with expander.
+ (call_symbolic_struct_value_sp32): Likewise.
+ (return peepholes): Use 'sparc_skip_caller_unimp' instead
+ of custom predicate.
+
+2004-05-07 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR c++/14962
+ * c-pragma.c (handle_pragma_redefine_extname): Only change
+ the assembler name of FUNCTION_DECLs and VAR_DECLs.
+
+2004-05-07 Uros Bizjak <uros@kss-loka.si>
+
+ * optabs.h (enum optab_index): Add new OTI_log1p.
+ (log1p_optab): Define corresponding macro.
+ * optabs.c (init_optabs): Initialize log1p_optab.
+ * genopinit.c (optabs): Implement log1p_optab using log1p?f2
+ patterns.
+ * builtins.c (expand_builtin_mathfn): Handle BUILT_IN_LOG1P{,F,L}
+ using log1p_optab.
+ (expand_builtin): Expand BUILT_IN_LOG1P{,F,L} using
+ expand_builtin_mathfn if flag_unsafe_math_optimizations is set.
+
+ * reg-stack.c (subst_stack_regs_pat): Handle UNSPEC_FYL2XP1.
+
+ * config/i386/i386.c (ix86_emit_i387_log1p): New function.
+ * config/i386/i386-protos.h (ix86_emit_i387_log1p):
+ Prototype here.
+ * config/i386/i386.md (UNSPEC_FYL2XP1): New unspec to represent
+ x87's fyl2xp1 instruction.
+ (*fyl2x_xf3): Rename insn definition to fyl2x_xf3.
+ (fyl2xp1_xf3): New pattern to implement fyl2xp1 x87 instruction.
+ (log1psf2, log1pdf2, log1pxf2): New expanders to implement log1pf,
+ log1p and log1pl built-ins as inline x87 intrinsics.
+
+2004-05-07 Loren James Rittle <ljrittle@acm.org>
+
+ * config/alpha/freebsd.h (SUBTARGET_EXTRA_SPECS): Proper redefinition.
+ * config/arm/freebsd.h: Likewise.
+ * config/ia64/freebsd.h: Likewise.
+ * config/sparc/freebsd.h: Likewise.
+
+2004-05-07 Hans-Peter Nilsson <hp@axis.com>
+
+ PR optimization/15296
+ * reorg.c (fill_simple_delay_slots): Use next_real_insn when
+ getting last consecutive label at a branch.
+ (relax_delay_slots): Similar, near top of loop.
+
+2004-05-06 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR target/15202
+ * pa.md (movdi, movsi, movhi, movqi): Support move from shift amount
+ register to general register.
+
+2004-05-07 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.h (STACK_BOUNDARY): Use 128 bit for either
+ TARGET_ALTIVEC or TARGET_ALTIVEC_ABI.
+ * config/rs6000/sysv4.h (ABI_STACK_BOUNDARY): Likewise.
+ (STACK_BOUNDARY): Delete.
+
+2004-05-06 Stuart Hastings <stuart@apple.com>
+
+ * gcc/doc/invoke.texi: Restore -fgcse-after-reload doc from 1.421,
+ mistakenly clobbered by 1.423.
+
+2004-05-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * doc/invoke.texi: Document -mvr4130-align.
+ * config/mips/mips.h (MASK_VR4130_ALIGN, TARGET_VR4130_ALIGN)
+ (TUNE_MIPS4120, TUNE_MIPS4130): New macros.
+ (TUNE_MACC_CHAINS): Include TUNE_MIPS4120 and TUNE_MIPS4130.
+ (TARGET_SWITCHES): Add -mvr4130-align and -mno-vr4130-align.
+ * config/mips/mips.md: Include sched-int.h.
+ (USEFUL_INSN_P, SEQ_BEGIN, SEQ_END, FOR_EACH_SUBINSN): New macros.
+ (mips_rtx_costs): Set integer multiplication costs for TUNE_MIPS4130.
+ (override_options): Enable -mvr4130-align at -O3 and above.
+ (mips_sim_insn): New variable.
+ (mips_sim): New structure.
+ (mips_sim_reset, mips_sim_init, mips_sim_next_cycle, mips_sim_wait_reg)
+ (mips_sim_wait_regs_2, mips_sim_wait_regs_1, mips_sim_wait_regs)
+ (mips_sim_wait_units, mips_sim_wait_insn, mips_sim_record_set)
+ (mips_sim_issue_insn, mips_sim_issue_nop, mips_sim_finish_insn)
+ (vr4130_avoid_branch_rt_conflict, vr4130_align_insns): New functions.
+ (mips_reorg): Call vr4130_align_insns.
+ (vr4130_last_insn): New variable.
+ (vr4130_true_reg_dependence_p_1, vr4130_true_reg_dependence_p)
+ (vr4130_swap_insns_p, vr4130_reorder): New functions.
+ (mips_sched_reorder, mips_variable_issue): Hook in vr4130 code.
+ (mips_issue_rate): Return 2 for PROCESSOR_R4130.
+ (mips_use_dfa_pipeline_interface): Return true for the same.
+ * config/mips/4130.md: New file.
+ * config/mips/mips.md: Include it. Add a peephole2 to convert
+ "mult;mflo" into "mtlo;macc".
+ (*macc, *umul_acc_di, *smul_acc_di): Use $1 rather than $0 as the
+ target of maccs.
+ (*msac_using_macc): New pattern.
+
+2004-05-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/5500.md (ir_vr55_store): Set latency to 0.
+ (ir_vr55_hilo): Split into...
+ (ir_vr55_mfhilo, ir_vr55_mthilo): ...these new reservations.
+ (ir_vr55_imul_si, ir_vr55_imadd): Change latency to 5.
+ (ir_vr55_imul_di): Change latency to 9. Reserve vr55_mac for 4 cycles.
+ Add various multiplication bypasses.
+ * config/mips/mips.c (mips_rtx_costs): Adjust VR5500 costs for integer
+ multiplication.
+
+2004-05-06 Uros Bizjak <uros@kss-loka.si>
+
+ * config/i386/i386.md (*fscalexf4): Correct insn "mode"
+ attribute to "XF".
+
+2004-05-05 Uros Bizjak <uros@kss-loka.si>
+
+ * optabs.h (enum optab_index): Add new OTI_fmod and OTI_drem.
+ (fmod_optab, drem_optab): Define corresponding macros.
+ * optabs.c (init_optabs): Initialize fmod_optab and drem_optab.
+ * genopinit.c (optabs): Implement fmod_optab and drem_optab
+ using fmod?f3 and drem?f3 patterns.
+ * builtins.c (expand_builtin_mathfn_2): Handle BUILT_IN_FMOD{,F,L}
+ using fmod_optab and BUILT_IN_DREM{,F,L} using drem_optab.
+ (expand_builtin): Expand BUILT_IN_FMOD{,F,L} and
+ BUILT_IN_DREM{,F,L} using expand_builtin_mathfn_2 if
+ flag_unsafe_math_optimizations is set.
+
+ * reg-stack.c (subst_stack_regs_pat): Handle UNSPEC_FPREM_F,
+ UNSPEC_FPREM_U, UNSPEC_FPREM1_F and UNSPEC_FPREM1_U.
+
+ * config/i386/i386.c (ix86_emit_fp_unordered_jump): New function.
+ * config/i386/i386-protos.h (ix86_emit_fp_unordered_jump):
+ Prototype here.
+ * config/i386/i386.md (UNSPEC_FPREM_F, UNSPEC_FPREM_U,
+ UNSPEC_FPREM1_F, UNSPEC_FPREM1_U): New unspecs to represent x87's
+ fprem and fprem1 instructions.
+ (*x86_fnstsw_1): Change input parameter to (reg:CCFP 18).
+ Rename insn definition to x86_fnstsw_1.
+ (fpremxf4, fprem1xf4): New patterns to implement fprem and fprem1
+ x87 instructions.
+ (fmodsf3, fmoddf3, fmodxf3): New expanders to implement fmodf, fmod
+ and fmodl built-ins as inline x87 intrinsics.
+ (dremsf3, dremdf3, dremxf3): New expanders to implement dremf, drem
+ and dreml built-ins as inline x87 intrinsics.
+
+2004-05-05 Roger Sayle <roger@eyesopen.com>
+
+ * reload1.c (inherit_piecemeal_p): Mark parameters potentially unused.
+
+2004-05-05 Ian Lance Taylor <ian@wasabisystems.com>
+
+ PR driver/9822
+ * doc/invoke.texi (Spec Files): Remove documentation of %c.
+
+2004-05-05 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.md: Update the msub define_split for new mflo/mfhi
+ representation.
+
+2004-05-06 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm-protots.h (vfp_mem_operand): Rename ...
+ (arm_coproc_mem_operand): ... To this.
+ * config/arm/arm.c (arm_legitimate_address_p): Allow ldrd modes.
+ (arm_legitimate_index_p): Ditto.
+ (vfp_mem_operand): Rename ...
+ (arm_coproc_mem_operand): ... To this. Handle writeback modes.
+ (vfp_secondary_reload_class): Use it.
+ (output_move_double): Use doubleword load/store instructions.
+ (arm_hard_regno_mode_ok): Only allow even reg pairs for ldrd.
+ * config/arm/arm.h (TARGET_LDRD): Define.
+ (EXTRA_CONSTRAINT_STR_ARM): Add 'Uy'.
+ * config/gcc/arm/arm.md (arm_movdi): Allow all valid memory operands.
+ New splitter for invalid doubleword loads.
+ * config/arm/iwmmxt.md (iwmmxt_arm_movdi): Use Uy constraint.
+ * config/arm/vfp.md (arm_movdi_vfp): Allow all valid memory operands.
+ * doc/md.texi: Document Uy constraint.
+
+2004-05-05 Jan Hubicka <jh@suse.cz>
+
+ PR opt/14980
+ * cgraphunit.c (cgraph_remove_unreachable_nodes): Deal properly with
+ inline clones.
+
+2004-05-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/15290
+ * config/i386/i386.c (ix86_split_to_parts): Use real_to_target
+ instead of REAL_VALUE_TO_TARGET_LONG_DOUBLE.
+
+2004-05-05 Mike Stump <mrs@apple.com>
+
+ * config/darwin-c.c (add_framework): Copy the directory name as it
+ can be freed later. Also, ensure we always allocate enough room
+ for the cached framework information.
+ (find_subframework_header): Keep track of the directory where the
+ subframework header was found.
+ (framework_construct_pathname): Speed up by not trying to re-add a
+ framework.
+ * cppfiles.c (search_path_exhausted): Arrange for the missing
+ header callback to be able to set the directory where the header
+ was found.
+ (cpp_get_dir): Add.
+ * cpplib.h (missing_header_cb): Add a parameter.
+ (cpp_get_dir): Add.
+
+2004-05-03 Mike Stump <mrs@apple.com>
+
+ * doc/invoke.texi (Directory Options): Document -iquote.
+ * doc/cpp.texi: Likewise.
+ * doc/cppopts.texi: Likewise.
+ * c-opts.c (c_common_missing_argument): Add -iquote processing.
+ (c_common_handle_option): Likewise.
+ * c.opt (iquote): Add.
+ * gcc.h (DEFAULT_WORD_SWITCH_TAKES_ARG): Add -iquote.
+ * c-incpath.c (merge_include_chains): Update comment to use -iquote.
+
+ * c-opts.c (case OPT_I): Deprecate -I- support.
+ * doc/invoke.texi: Likewise.
+ * doc/cpp.texi: Likewise.
+ * doc/cppopts.texi: Likewise.
+
+2004-05-05 Steven Bosscher <stevenb@suse.de>
+
+ * basic-block.h (free_basic_block_vars): Update prototype.
+ * flow.c (free_basic_block_vars): Remove the keep_head_end_p
+ argument.
+ (life_analysis): Update call.
+ * ifcvt.c (if_convert): Likewise.
+ * sibcall.c (optimize_sibling_and_tail_recursive_call): Likewise.
+ * passes.c (rest_of_handle_final): Likewise.
+ (rest_of_compilation): Likewise.
+ * config/sh/sh.c (sh_output_mi_thunk): Likewise.
+
+ * emit-rtl.c (next_real_insn): Use INSN_P.
+ (prev_real_insn): Likewise.
+
+2004-05-05 Eric Christopher <echristo@redhat.com>
+
+ * config/mips/mips.md: Update the madd define_split for new mflo/mfhi
+ representation.
+
+2004-05-05 Paolo Bonzini <bonzini@gnu.org>
+
+ * config/rs6000/rs6000.c (build_opaque_vector_type):
+ New function.
+ (rs6000_init_builtins): Use it.
+
+2004-05-04 Bernard Giroud <bgiroud2@free.fr>
+
+ * gcc/gcc/vmsdbgout.c (vms_func_node, vms_func_ref): New.
+ (func_table): Change type from char ** to vms_func_ref.
+ (write_rtnbeg): Update to reflect func_table change. Use
+ fde->funcdef_number instead of rtnnum in output.
+ (write_rtnend, vmxdbgout_begin_function, vmsdbgout_init): Likewise.
+
+2004-05-04 Paolo Bonzini <bonzini@gnu.org>
+ Richard Henderson <rth@redhat.com>
+
+ PR target/14899
+
+ * c-common.c (vector_types_convertible_p): New function.
+ * c-typeck.c (comptypes): Recurse on vector types.
+ (convert_for_assignment): Use vector_types_convertible_p.
+ (digest_init): Use vector_types_convertible_p to check
+ validness of constant vector initializers; otherwise treat
+ them as scalars.
+ * tree.c (make_or_reuse_type): New.
+ (build_common_tree_nodes): Use it.
+ * cp/call.c (standard_conversion): Likewise.
+ * cp/typeck.c (comptypes): Recurse on vector types.
+ (convert_for_assignment): Use vector_types_convertible_p.
+
+2004-05-04 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.c (override_options): Default to no
+ generation of branch-likely operations when tuning for
+ CPUs where they tend to have a negative performance impact
+ (e.g., SB-1).
+
+2004-05-04 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * expr.c (store_constructor_field): Don't call store_constructor
+ if bitsize is not a multiple of a byte.
+
+2004-05-04 Richard Sandiford <rsandifo@redhat.com>
+
+ * reload1.c (inherit_piecemeal_p): New function.
+ (emit_reload_insns): When reloading a group of hard registers, use
+ inherit_piecemeal_p to decide whether the values of individual hard
+ registers can be inherited.
+
+2004-05-04 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/ia64/t-ia64 (LIB2ADDEH): Remove gthr-gnat.c.
+ * config/s390/t-tpf (LIB2ADDEHDEP): Likewise.
+ * config/t-linux (LIB2ADDEHDEP): Likewise.
+
+2004-05-04 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/crti.asm: Push an even number of registers.
+ * config/arm/crtn.asm: And restore them. Load via sp.
+
+2004-05-04 Paolo Bonzini <bonzini@gnu.org>
+
+ * ggc-zone.c (ggc_alloc_zone_1): Add MEM_STAT_DECL parameter.
+ Collect overhead information.
+ (ggc_alloc_stat): New name of ggc_alloc. Add MEM_STAT_DECL
+ parameter and pass it through.
+ (ggc_alloc_typed_stat): New name of ggc_alloc_typed. Add
+ MEM_STAT_DECL parameter and pass it through.
+ (ggc_alloc_zone_stat): New name of ggc_alloc_zone. Add
+ MEM_STAT_DECL parameter and pass it through.
+
+2004-05-03 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000-protos.h: Protoize rs6000_hard_regno_nregs.
+
+ * config/rs6000/rs6000.c (rs6000_hard_regno_nregs): New.
+
+ * config/rs6000/rs6000.h (HARD_REGNO_NREGS): Call
+ rs6000_hard_regno_nregs.
+
+2004-05-03 Eric Christopher <echristo@redhat.com>
+
+ * config/s390/s390.c (s390_emit_prologue): Call unspec tpf
+ prologue insn instead of setting up call.
+ (s390_emit_epilogue): Ditto.
+ * config/s390/s390.md (prologue_tpf, epilogue_tpf): New patterns.
+ (define_constants): Add numbers for above patterns.
+
+2004-05-03 Eric Christopher <echristo@redhat.com>
+
+ * config/s390/s390.h (CONDITIONAL_REGISTER_USAGE): Move body...
+ * config/s390/s390.c (s390_conditional_register_usage): ...here.
+ * config/s390/s390-protos.h: Prototype.
+
+2004-05-03 Joe Buck <jbuck@welsh-buck.org>
+
+ * cppfiles.c (pchf_adder): Eliminate use of |= in d->have_once_only
+ assignment.
+
+2004-05-03 Eric Christopher <echristo@redhat.com>
+
+ * config/mips/mips.md: Fix branch length attribute definition.
+
+2004-05-03 Aldy Hernandez <aldyh@redhat.com>
+
+ * config.gcc: Remove --enable-altivec support.
+
+ * config/rs6000/altivec-defs.h: Remove.
+
+2004-05-03 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * fixinc/inclhack.def (svr4_profil): Don't apply on IRIX 5/6.
+ * fixinc/fixincl.x: Regenerate.
+
+2004-05-03 Uros Bizjak <uros@kss-loka.si>
+
+ * config/i386/i386.md (*fyl2x_sfxf3, *fyl2x_dfxf3): Remove insn
+ definition.
+ (log?f2, log10?f2, log2?f2): Reimplement expanders with
+ float_truncate insn.
+ (*fxtractsf3, *fxtractdf3): Remove insn definition.
+ (logb?f2): Reimplement expanders with float_truncate insn.
+
+2004-05-03 Graham Stott <graham.stott@btinternet.com>
+
+ PR 14718
+ * dwarf2out.c (dwarf2out_imported_module_or_decl): Use
+ force_type_die for CONST_DECL.
+
+2004-05-03 Eric Botcazou <ebotcazou@libertysurf.fr>
+ Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config.gcc (sparc64-*-solaris2*, sparcv9-*-solaris2*): Add
+ tm-dwarf2.h to tm_file.
+ (sparc-*-solaris2*): Add tm-dwarf2.h to tm_file for Solaris 7+.
+ * config/sparc/sol2-bi.h (PREFERRED_DEBUGGING_TYPE): Delete.
+ (ASM_DEBUG_SPEC): Delete.
+
+2004-05-03 Uros Bizjak <uros@kss-loka.si>
+
+ * optabs.h (enum optab_index): Add new OTI_expm1.
+ (expm1_optab): Define corresponding macro.
+ * optabs.c (init_optabs): Initialize expm1_optab.
+ * genopinit.c (optabs): Implement expm1_optab using expm1?f2
+ patterns.
+ * builtins.c (expand_builtin_mathfn): Handle BUILT_IN_EXPM1{,F,L}
+ using expm1_optab.
+ (expand_builtin): Expand BUILT_IN_EXPM1{,F,L} using
+ expand_builtin_mathfn if flag_unsafe_math_optimizations is set.
+
+ * config/i386/i386.md (expm1df2, expm1sf2, expm1xf2): New expanders
+ to implement expm1, expm1f and expm1l built-ins as inline x87
+ intrinsics.
+
+2004-05-02 Alexandre Oliva <aoliva@redhat.com>
+
+ 2003-11-19 Richard Sandiford <rsandifo@redhat.com>
+ * config/frv/frv.md (*return_true, *return_false): New patterns.
+
+2004-05-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * rtl.h (PHI_NODE_P): Remove.
+
+2004-05-02 Eric Botcazou <ebotcazou@act-europe.fr>
+
+ PR middle-end/14988
+ * function.c (assign_stack_local_1): Use BITS_PER_UNIT alignment
+ when passed -2 as 'align'.
+ (put_var_into_stack): Use 'bool' as the type for the three local
+ predicates. Adjust calls to put_reg_into_stack.
+ When passed a CONCAT, instruct put_reg_into_stack to use
+ a consecutive stack slot for the second part.
+ (put_reg_into_stack): Remove 'promoted_mode' parameter, add
+ 'consecutive_p' parameter. Turn the three predicates into 'bool'
+ parameters. Retrieve the register mode from 'reg'.
+ When consecutive_p is true, instruct assign_stack_local_1 to use
+ BITS_PER_UNIT alignment.
+ (put_addressof_into_stack): Use 'bool' as the type for the two
+ local predicates. Adjust call to put_reg_into_stack.
+
+2004-05-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * fold-const.c (fold_convert_const, fold): Add missing
+ FIX_ROUND_EXPR case.
+
+2004-05-02 Alexandre Oliva <aoliva@redhat.com>
+
+ * configure.ac (FLEX, BISON): Only use tools from the build tree
+ if build equals host.
+ * configure: Rebuilt.
+
+ * config/frv/frv-protos.h (frv_expand_epilogue,
+ frv_expand_fdpic_call): Add bool argument.
+ * config/frv/frv.c (frv_function_ok_for_sibcall): New.
+ (TARGET_FUNCTION_OK_FOR_SIBCALL): Define to it.
+ (frv_expand_epilogue): Use new argument to decide whether to emit
+ return instruction or copy the return address to LR.
+ (frv_expand_fdpic_call): Inline PLT entry when emitting direct
+ sibcalls.
+ (sibcall_operand): New.
+ * config/frv/frv.h (PREDICATE_CODES): call_operand doesn't match
+ PLUS nor LABEL_REF. Add sibcall_operand.
+ * config/frv/frv.md (call, call_value): Pass false to
+ frv_expand_fdpic_call.
+ (call_fdpicdi, call_value_fdpicdi): Insert %i0 in calll.
+ (sibcall, sibcall_internal, sibcall_fdpicdi, sibcall_value,
+ sibcall_value_internal, sibcall_value_fdpicdi): New.
+ (return_unsigned_true, return_unsigned_false): New.
+ (epilogue): Adjust call to frv_expand_epilogue.
+ (sibcall_epilogue): New.
+
+ * config/frv/frv.h (ASM_SPEC): Pass -mno-fdpic as -mnopic.
+ (CPP_SPEC, CPP_SIMPLE_SPEC): Undefine __FRV_ACC__ and __FRV_FPR__
+ before redefining them.
+
+2004-05-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (fold_fixed_mathfn): New function.
+ (fold_builtin_lround, fold_builtin): Use it.
+
+2004-05-01 Jakub Jelinek <jakub@redhat.com>
+
+ * config/sparc/linux64.h (TARGET_DEFAULT): Make 64-bit by default
+ also for TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc3.
+
+2004-05-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/cris/cris.h: Revert my "fix comment typos" patch.
+
+2004-05-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (TUNE_MACC_CHAINS): Fix comment.
+
+2004-05-01 Falk Hueffner <falk@debian.org>
+
+ * config/alpha/alpha.md (builtin_insbl, builtin_inswl,
+ builtin_insll): Disallow 0 as first input operand.
+
+2004-05-01 Falk Hueffner <falk@debian.org>
+
+ * config/alpha/alpha.c (alpha_rtx_costs): Fix shiftadd costs.
+
+2004-05-01 Ulrich Weigand <uweigand@de.ibm.com>
+
+ PR middle-end/15054
+ * expr.c (expand_expr_real): Do not call preserve_temp_slots
+ on a TARGET_EXPR temp.
+ * function.c (assign_stack_temp_for_type): Set 'keep' flag for
+ TARGET_EXPR temp slots.
+
+2004-05-01 Paolo Bonzini <bonzini@gnu.org>
+
+ * simplify-rtx.c (simplify_ternary_operation): When
+ converting an IF_THEN_ELSE to a relational op, return
+ correct mode.
+
+2004-04-30 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (fold_builtin_round): Fix comment typo.
+ (fold_builtin_lround): New function.
+ (fold_builtin): Use it.
+
+2004-04-20 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR target/11608
+ * config/sh/elf.h (DBX_OUTPUT_MAIN_SOURCE_FILE_END): Update and make it
+ more like the one in config/dbxelf.h.
+
+2004-04-30 Zack Weinberg <zack@codesourcery.com>
+
+ * tree.h (SET_ARRAY_OR_VECTOR_CHECK): Rename to SET_OR_ARRAY_CHECK
+ and adjust definition accordingly.
+ (TYPE_DOMAIN): Allow only SET_TYPE and ARRAY_TYPE.
+ (TYPE_DEBUG_REPRESENTATION_TYPE): Allow only VECTOR_TYPE.
+ * expr.c (store_constructor): Do not access TYPE_DOMAIN of a
+ VECTOR_TYPE.
+
+2004-04-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/14587
+ * config/i386/winnt.c (associated_type): Look for attributes on
+ the TYPE_MAIN_VARIANT of *this.
+ * attribs.c (decl_attributes): If ATTR_FLAG_TYPE_IN_PLACE, also
+ apply the attributes to the variants.
+
+2004-04-30 Paul Brook <paul@codesourcery.com>
+
+ * config.gcc: Simplify arm --with-{cpu,tune} test.
+ * config/arm/arm-cores.def: Document whitespace restrictions.
+
+2004-04-30 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ PR other/1963
+ * config/alpha/osf.h (SWITCHES_NEED_SPACES): Define.
+
+2004-04-30 Brian Ford <ford@vss.fsi.com>
+ DJ Delorie <dj@redhat.com>
+
+ * config/i386/cygming.h [HAVE_GAS_PE_SECREL32_RELOC]
+ (DWARF2_DEBUGGING_INFO): Define to enable.
+ (DBX_REGISTER_NUMBER): Define to use the svr4 register map for
+ DWARF2.
+ * configure.ac (Target-specific assembler checks)
+ <i[34567]86-*-[cygwin*|pe|mingw32*]>: New test for .secrel32
+ relocs.
+ * configure: Regenerate.
+ * config.in: Likewise.
+
+ * config/i386/cygming.h [HAVE_GAS_PE_SECREL32_RELOC]
+ (ASM_OUPUT_DWARF_OFFSET): Define.
+
+2004-04-29 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * config/s390/s390-protos.h (s390_emit_epilogue): Parameter added.
+ (s390_emit_call): New function prototype added.
+ (s390_tls_get_offset): Function removed.
+ * config/s390/s390.c (s390_function_ok_for_sibcall,
+ s390_call_saved_register_used_p): New functions.
+ (TARGET_FUNCTION_OK_FOR_SIBCALL): Definition of target macro added.
+ (s390_tls_get_offset): Function merged into s390_emit_tls_call_insn.
+ (s390_emit_tls_call_insn): New function.
+ (legitimize_tls_address): Call s390_emit_tls_call_insn instead of
+ emit_call_insn.
+ (s390_emit_prologue): Use s390_emit_call instead of emit_call_insn.
+ (s390_emit_epilogue): Like s390_emit_prologue. Parameter for sibcalls
+ added.
+ * config/s390/s390.h (SIBCALL_REGNUM): New macro representing the
+ register number used to hold the target address for sibcalls.
+ * config/s390/s390.md ("sibcall", "sibcall_value", "sibcall_epilogue"):
+ New expanders.
+ ("*sibcall_br", "*sibcall_brc", "*sibcall_brcl", "*sibcall_value_br",
+ "*sibcall_value_brc", "*sibcall_value_brcl"): New insns.
+ ("call_exp", "call_value_exp", "call_value_tls", "call_value_tls_exp"):
+ Expanders removed.
+ ("call", "call_value"): Call s390_emit_call to emit the call patterns.
+ ("*bras", "*brasl", "*bras_r", "*brasl_r", "*bras_tls", "*brasl_tls",
+ "*basr", "*basr_r", "*basr_tls"): Added constraint: !SIBLING_CALL_P.
+ ("epilogue"): Changed the call to s390_emit_epilogue to use the
+ new parameter.
+
+2004-04-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * bb-reorder.c, c-opts.c, cfglayout.c, cgraph.c, cgraphunit.c,
+ cppfiles.c, fold-const.c, ggc-zone.c, loop-doloop.c, optabs.c,
+ reg-stack.c, varasm.c, config/alpha/ev4.md,
+ config/alpha/ev5.md, config/alpha/ev6.md, config/arm/arm.c,
+ config/c4x/c4x.c, config/c4x/c4x.md, config/cris/cris.c,
+ config/cris/cris.h, config/fr30/fr30.h, config/frv/frv.c,
+ config/frv/frv.h, config/frv/frv.md, config/h8300/h8300.c,
+ config/i386/i386.c, config/i386/i386.md, config/i386/winnt.c,
+ config/ia64/itanium2.md, config/ip2k/ip2k.c,
+ config/mips/mips.c, config/mips/mips.h, config/mips/sr71k.md,
+ config/pa/pa.c, config/s390/s390.c, config/sh/sh.c: Fix
+ comment typos.
+
+2004-04-30 Paul Brook <paul@codesourcery.com>
+
+ * config.gcc: Default ep9312 to hard-float.
+ * config/arm/arm-cores.def: Add ARCH field.
+ * config/arm/arm.c (FL_FOR_ARCH*): Define.
+ (arm_arch_cirrus): New variable.
+ (all_cores): Set and use arch.
+ (all_architectures): Ditto.
+ (arm_arch_name): New variable.
+ (arm_override_options): Set it. Use [SUB]TARGET_CPU_DEFAULT.
+ Set and use arm_arch_cirrus.
+ * config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Set arch defines.
+ (enum processor_type): Update ARM_CORE define.
+ (enum target_cpus): Add. Replaces TARGET_CPU_* defines.
+ (CPP_SPEC): Remove %(cpp_cpu_arch).
+ (CPP_ARCH_DEFAULT_SPEC): Remove.
+ (CPP_CPU_ARCH_SPEC): Remove.
+ (EXTRA_SPECS): Don't use CPP_*ARCH*_SPEC.
+ (FPUTYPE_DEFAULT): Don't define here.
+
+2004-04-30 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * flow.c (propagate_one_insn): Call mark_set_regs for stack pointer
+ updates too.
+
+2004-04-30 Paul Brook <paul@codesourcery.com>
+
+ * arm.c (arm_needs_doubleword_align): Use mode alignment.
+
+2004-04-30 Paolo Bonzini <bonzini@gnu.org>
+
+ * config/altivec/altivec.h [__cplusplus] (vec_subsubs): Rename to
+ vec_sububs.
+ [__cplusplus] (vec_subsuhs): Rename to vec_subuhs, without
+ duplicates.
+
+2004-04-30 Uros Bizjak <uros@kss-loka.si>
+
+ * config/i386/i386.md (atansf2, atandf2, atanxf2): Move near
+ atan2?f3 expanders.
+
+2004-04-29 Nick Clifton <nickc@redhat.com>
+
+ Bug 14093
+ * config/sh/sh-protos.h (sh_promote_prototypes): Declare.
+ * config/sh/sh.c (sh_promote_prototypes): Remove declaration.
+ Delete static from definition.
+ * config/sh/sh.h (FUNCTION_VALUE): Add sh_promote_prototypes call.
+
+2004-04-30 Uros Bizjak <uros@kss-loka.si>
+
+ * reg-stack.c (subst_stack_regs_pat): <UNSPEC_SIN, UNSPEC_COS,
+ UNSPEC_FRNDINT, UNSPEC_F2XM1>: abort() if src1 dies.
+ <UNSPEC_SINCOS_COS, UNSPEC_TAN_ONE, UNSPEC_XTRACT_FRACT>: Same.
+ <UNSPEC_SINCOS_SIN, UNSPEC_TAN_TAN, UNSPEC_XTRACT_EXP>: Same.
+
+2004-04-29 Richard Guenther <richard.guenther@uni-tuebingen.de>
+
+ * commom.opt (Wfatal-errors): Add it.
+ * diagnostic.c (flag_fatal_errors): Define it.
+ (diagnostic_action_after_output): Check for flag_fatal_errors.
+ * flags.h (flag_fatal_errors): Declare it.
+ * opts.c (common_handle_option): Add OPT_Wfatal_errors.
+ * doc/invoke.texi (Warning Options): Document -Wfatal-errors.
+
+2004-04-30 Josef Zlomek <zlomekj@suse.cz>
+
+ * gcse.c (remove_reachable_equiv_notes): Delete notes also in
+ blocks which have kill flag set.
+
+2004-04-29 Ben Elliston <bje@au.ibm.com>
+
+ * configure.ac (--with-as): Abort if user-supplied assembler
+ cannot be executed.
+ (--with-ld): Likewise for the linker.
+ * configure: Regenerate.
+
+2004-04-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * convert.c (convert_to_integer): Ensure `long_integer_type_node'
+ isn't NULL before using it.
+
+2004-04-29 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/15189
+ * config/mips/mips.md (load_df_low): Use default length.
+ (load_df_high, store_df_high): Likewise.
+
+2004-04-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/mips/mips.md, config/mips/sb1.md,
+ config/rs6000/rs6000.c: Fix comment typos.
+
+2004-04-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * builtins.c, cgraph.c, cgraphunit.c, final.c, fold-const.c:
+ Fix comment typos.
+
+2004-04-29 Douglas B Rupp <rupp@gnat.com>
+
+ * gcc.c (DELETE_IF_ORDINARY): New macro default definition.
+ (delete_if_ordinary): Use above macro.
+ * config/alpha/xm-vms.h (DELETE_IF_ORDINARY): New macro VMS definition.
+ Update copyright.
+ * doc/hostconfig.texi (DELETE_IF_ORDINARY): Document new macro.
+
+2004-04-29 Richard Earnshaw <rearnsha@arm.com>
+
+ * c-decl.c (get_parm_info): Use the correct tag keywords when
+ warning about type declarations in prototypes.
+
+2004-04-29 Paul Brook <paul@codesourcery.com>
+
+ * config.gcc: Pull list of cores from arm-cores.def.
+
+2004-04-29 Paolo Bonzini <bonzini@gnu.org>
+
+ * combine.c (combine_simplify_rtx): Adjust call to use
+ simplify_relational_operation. Do not use SELECT_CC_MODE
+ when a comparison already has a MODE_CC mode.
+
+2004-04-29 Paolo Bonzini <bonzini@gnu.org>
+
+ (simplify_set): simplify_relational_operation may now
+ return another relational expression.
+ * cse.c (fold_rtx): simplify_relational_operation now
+ takes of computing the comparison mode.
+ * dojump.c (compare_from_rtx): Use simplify_relational_operation,
+ remove dead code.
+ (do_compare_rtx_and_jump): Likewise.
+ * integrate.c (subst_constants): simplify_relational_operation
+ may now return another relational expression.
+ * simplify-rtx.c (simplify_gen_relational): Move most code to
+ the new simplify_relational_operation and
+ simplify_relational_operation_1 functions.
+ (simplify_relational_operation): Rewritten.
+ (simplify_relational_operation_1): New function.
+ (simplify_ternary_operation): simplify_relational_operation
+ may now return another relational expression.
+ (simplify_rtx): Remove unnecessary temp variable.
+
+2004-04-29 Uros Bizjak <uros@kss-loka.si>
+
+ * reg-stack.c (swap_to_top): New function.
+ (subst_stack_regs_pat): UNSPEC_FPATAN, UNSPEC_FYL2X: Use
+ swap_to_top().
+ (subst_stack_regs_pat): UNSPEC_FSCALE: Remove.
+ (subst_stack_regs_pat): Handle UNSPEC_FSCALE_FRACT and
+ UNSPEC_FSCALE_EXP.
+
+ * config/i386/i386.md (UNSPEC_FSCALE): Remove.
+ (*fscale_sfxf3, *fscale_dfxf3, *fscale_xf3): Remove insn pattern.
+ (UNSPEC_FSCALE_FRACT, UNSPEC_FSCALE_EXP): New unspecs to represent
+ x87's fscale insn.
+ (*fscalexf4: Define new insn pattern to implement x87 fscale insn.
+ (exp?f2, exp10?f2, exp2?f2): Use *fscalexf4 and float_truncate
+ patterns.
+
+2004-04-28 Serge Belyshev <1319@bot.ru>
+
+ PR 14944
+ * coverage.c (read_counts_file): Fix usage of warning () call.
+ * pretty-print.c (pp_base_format_text): Fix typo in the comment.
+
+2004-04-28 Ben Elliston <bje@au.ibm.com>
+
+ * doc/invoke.texi (Objective-C Dialect Options): Don't prefix
+ options with "-" in the option index.
+ (SPARC Options): Likewise.
+ (M32R/D Options): Likewise.
+
+2004-04-28 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * convert.c (convert_to_integer): Convert (long)round -> lround,
+ etc.
+
+2004-04-28 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/rs6000/rs6000.c (registers_ok_for_quad_peep):
+ Return false if we do not have fp register.
+ (addrs_ok_for_quad_peep): Rename to ...
+ (mems_ok_for_quad_peep): this.
+ Add check for volatile memory.
+ * config/rs6000/rs6000-protos.h (addrs_ok_for_quad_peep):
+ Rename to ...
+ (mems_ok_for_quad_peep): this.
+ * config/rs6000/rs6000.md: Change peephole's for lfq/stq
+ to peephole2's.
+ (lfq_power2): New instruction.
+ (stfq_power2): Likewise.
+
+2004-04-28 Jan Hubicka <jh@suse.cz>
+
+ PR c/15004
+ * function.c (do_warn_unused_parameter): Break out form ...
+ (expand_function_end): ... here; warn only when not using cgraphunit.
+ * function.h (do_warn_unused_parameter): Declare.
+ * cgraphunit.c: Include function.h.
+ (cgraph_finalize_function): Do unused parameter warning.
+ * Makefile.in (cgraphunit.o): Depend on function.h
+
+2004-04-28 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * Makefile.in ($(DESTDIR)$(infodir)/%.info): Don't condition
+ calling install-info on $(DESTDIR)$(infodir)/dir already being
+ present.
+
+2004-04-28 Paul Brook <paul@codesourcery.com>
+
+ * dwarf2out.c (mem_loc_descriptor): Handle shifts.
+
+2004-04-28 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * gcse.c (find_moveable_store): Do not accept store insns with
+ REG_EH_REGION note.
+
+2004-04-28 Paul Brook <paul@codesourcery.com>
+
+ * calls.c (precompute_arguments): Remove PROMOTE_FOR_CALL_ONLY.
+ * function.c (assign_temp): Ditto.
+ * system.h (PROMOTE_FOR_CALL_ONLY): Poison.
+
+2004-04-28 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/lib1funcs.asm: Recognize armv5tej and armv6.
+
+2004-04-28 Josef Zlomek <zlomekj@suse.cz>
+
+ * var-tracking.c (variable_different_p): Add a parameter
+ compare_current_location, compare current location of variable parts
+ if it is true.
+ (dataflow_set_different_1): Pass compare_current_location == false.
+ (dataflow_set_different_2): Pass compare_current_location == false.
+ (emit_notes_for_differences_1): Pass compare_current_location == true.
+
+2004-04-28 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("casesi"): Mark jump table access as
+ non-trapping and unchanging.
+
+2004-04-27 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR debug/14829
+ * dwarf2out.c (reg_number): Rename to dbx_reg_number. Adjust all
+ callers.
+ (multiple_reg_loc_descriptor, reg_loc_descriptor): Use gcc register
+ number for indexing hard_regno_nregs array.
+
+2004-04-27 Geoffrey Keating <geoffk@apple.com>
+
+ * config/darwin.h (STARTFILE_SPEC): Use %s to find crt2.o.
+ * config/darwin-crt2.c: Only have contents on __ppc__.
+
+2004-04-27 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.c (call_insn_operand): Check
+ SYMBOL_REF_EXTERNAL_P in addition to SYMBOL_REF_LOCAL_P.
+ * config/xtensa/xtensa.h (LEGITIMATE_PIC_OPERAND): Likewise.
+ * config/xtensa/xtensa.md (call, call_value): Likewise.
+
+2004-04-27 Wu Yongwei <adah@sh163.net>
+
+ * gthr-win32.h (__gthread_mutex_t): Change typedef to new structure.
+ (__GTHREAD_MUTEX_INIT_DEFAULT): Adjust.
+ (__gthread_mutex_init_function): Replace CreateMutex with
+ initialization of custom mutex using CreateSemaphore.
+ (__gthread_mutex_lock): Use InterlockedIncrement.
+ (__gthread_mutex_trylock): Use InterlockedCompareExchange.
+ (__gthread_mutex_unlock): Use InterlockedDecrement and
+ ReleaseSemaphore to unlock
+ * config/i386/gthr-win32.c (__gthread_mutex_init_function,
+ __gthread_mutex_lock, __gthread_mutex_trylock,
+ __gthread_mutex_unlock): Adjust to match inline versions in
+ gthr-win32.h.
+
+2004-04-27 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.c (arm_promote_prototypes): New function.
+ (TARGET_PROMOTE_PROTOTYPES): Use it.
+
+2004-04-27 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.c (arm_expand_epilogue): Count blocks of 4 regs.
+
+2004-04-26 Bernard Giroud <bgiroud@free.fr>
+
+ * config/alpha.c (alpha_end_function): For OpenVMS gas,
+ correctly output .pdesc directive before .end.
+
+2004-04-26 James E Wilson <wilson@specifixinc.com>
+
+ Bug 14927
+ * config/ia64/ia64.md (movxf): New local op0. Handle case where
+ operands[0] is a SUBREG. Handle case where operands[1] is a GR reg.
+
+2004-04-26 Zack Weinberg <zack@codesourcery.com>
+
+ * config/ia64/hpux.h: Predefine __STDCPP__ when compiling C++.
+ * config/pa/pa-hpux10.h: Likewise.
+ * config/pa/pa-hpux11.h: Likewise.
+
+2004-04-26 Geoffrey Keating <geoffk@apple.com>
+
+ * doc/invoke.texi (Overall Options): Document default for -o
+ for PCH files.
+
+2004-04-26 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * builtins.c (expand_builtin_update_setjmp_buf): New function.
+ (expand_builtin, case BUILT_IN_UPDATE_SETJMP_BUF): New case.
+ * builtins.def (BUILT_IN_UPDATE_SETJMP_BUF): New code.
+
+2004-04-26 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.c (arm_legitimate_index_p): Correct iwmmxt offsets.
+
+2004-04-26 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.c (arm_legitimate_index_p): Correct maverick offsets.
+
+2004-04-25 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold): Prefer fold_convert (negate_expr (...)) to
+ fold (build1 (NEGATE_EXPR, ...)). Optimize X / -1 as -X and
+ X % -1 as 0.
+
+2004-04-26 Hans-Peter Nilsson <hp@bitrange.com>
+
+ PR bootstrap/15141
+ * except.c (connect_post_landing_pads): Delete insns after the
+ barrier when generating a unwind_resume_libfunc call.
+
+2004-04-25 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ PR/c++ 15119
+ * tree.c (substitute_placeholder_in_expr, case 4): New case,
+ for TARGET_EXPR.
+
+2004-04-25 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * gcov-io.h (__gcov_fork, __gcov_execl, __gcov_execlp, __gcov_execle,
+ __gcov_execv, __gcov_execvp, __gcov_execve): Do not declare when
+ inhibit_libc is defined.
+
+2004-04-25 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_linked_macc_p): Declare.
+ * config/mips/mips.h (TUNE_MACC_CHAINS): New macro.
+ * config/mips/mips.c (TARGET_SCHED_REORDER): Define.
+ (TARGET_SCHED_VARIABLE_ISSUE): Define.
+ (mips_adjust_cost): Move later in file, next to other sched hooks.
+ (mips_macc_chains_last_hilo): New variable.
+ (mips_linked_madd_p, mips_macc_chains_record, mips_macc_chains_reorder)
+ (mips_promote_ready, mips_sched_reorder, mips_variable_issue): New.
+ * config/mips/mips.md (may_clobber_hilo): New attribute.
+
+2004-04-24 Roger Sayle <roger@eyesopen.com>
+ Bruce Korb <bkorb@gnu.org>
+
+ * fixinc/inclhack.def (aix_syswait_2): New fix.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/tests/base/sys/wait.h: Update for new test.
+
+2004-04-24 Alan Modra <amodra@bigpond.net.au>
+
+ PR target/14960
+ * config/rs6000/rs6000.c (rs6000_stack_info): Rename total_raw_size
+ to non_fixed_size, and leave out fixed_size from the sum.
+ (generate_set_vrsave): Correct clobbers.
+ (rs6000_emit_epilogue): Test TARGET_ALTIVEC with TARGET_ALTIVEC_SAVE.
+ (rs6000_function_value): Test TARGET_ALTIVEC and TARGET_ALTIVEC_ABI.
+ (rs6000_libcall_value): Likewise.
+ * config/rs6000/rs6000.h (FUNCTION_VALUE_REGNO_P): Likewise.
+ (FUNCTION_ARG_REGNO_P): Likewise.
+
+2004-04-24 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * expmed.c (expand_mult_highpart_adjust): Do not assume OP1
+ is a CONST_INT.
+ (expand_mult_highpart_optab): Call expand_mult_highpart_adjust
+ with NARROW_OP1 instead of OP1.
+
+2004-04-24 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/host-linux.c (TRY_EMPTY_VM_SPACE): Define for __s390__
+ and __s390x__ hosts.
+
+2004-03-23 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * Makefile.in (LIBGCOV): Add _gcov_fork, _gcov_execl, _gcov_execlp,
+ _gcov_execle, _gcov_execv, _gcov_execvp, _gcov_execve.
+ * builtin-types.def (BT_PID, BT_PTR_CONST_STRING, BT_FN_PID,
+ BT_FN_INT_CONST_STRING_PTR_CONST_STRING,
+ BT_FN_INT_CONST_STRING_PTR_CONST_STRING_PTR_CONST_STRING): New.
+ * builtins.c (expand_builtin_fork_or_exec): New.
+ (expand_builtin): Call it.
+ * builtins.def (BUILT_IN_EXECL, BUILT_IN_EXECLP,BUILT_IN_EXECLE,
+ BUILT_IN_EXECV, BUILT_IN_EXECVP, BUILT_IN_EXECVE, BUILT_IN_FORK): New.
+ * c-common.c (PID_TYPE): New macro.
+ (c_common_nodes_and_builtins): Initialize pid_type_node.
+ * calls.c (special_function_p): Do not handle fork and exec.
+ (expand_call): Do not handle ECF_FORK_OR_EXEC.
+ * gcov-io.h (__gcov_fork, __gcov_execl, __gcov_execlp, __gcov_execle,
+ __gcov_execv, __gcov_execvp, __gcov_execve): Declare.
+ * libgcov.c (__gcov_fork, __gcov_execl, __gcov_execlp, __gcov_execle,
+ __gcov_execv, __gcov_execvp, __gcov_execve): New.
+ * tree.h (enum tree_index): Add TI_PID_TYPE.
+ (pid_type_node): New macro.
+ (ECF_FORK_OR_EXEC): Removed.
+
+2004-04-23 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/13985
+ * cfgloopmanip.c (fix_loop_placements): New prototype.
+ Call fix_bb_placements on the preheader of loops that have
+ been reparented.
+ (remove_path): Adjust call to fix_loop_placements.
+
+2004-04-23 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/darwin7.h: New file.
+ * config.gcc (*-*-darwin*): Add darwin7.h if the
+ version is greater than 6.
+ * config/darwin.h (TARGET_C99_FUNCTIONS): Define.
+ (MATH_LIBRARY): Wrap in ifdefs.
+
+2004-04-23 Daniel Jacobowitz <drow@mvista.com>
+
+ * config/arm/arm.c (arm_output_epilogue): Reverse the order of
+ loading iWMMXt registers with a frame pointer. Use post-increment
+ without a frame pointer.
+ (arm_expand_prologue): Reverse the order of saving iWMMXt registers.
+
+2004-04-23 Paolo Bonzini <bonzini@gnu.org>
+
+ * doc/invoke.texi (Optimize Options): Refer to "unit-at-a-time
+ mode" rather than "-funit-at-a-time" since -O2 enables it
+ without requiring -f* options. Refer to -fprofile-generate and
+ -fprofile-use correctly. Move -funit-at-a-time among options
+ enabled by -O. Add information about unit-at-a-time caveats.
+
+2004-04-22 Per Bothner <per@bothner.com>
+
+ * line-map.h (struct line_maps): New field highest_line.
+ (linemap_position_for_column): Make non-inline function.
+ (LINEMAP_POSITION_FOR_COLUMN): New macro.
+ * line-map.c (linemap_init): Clear highest_line field.
+ (linemap_add): Set highest_line field.
+ (linemap_line_start): Minor optimization - use highest_line field.
+ Reduce maximum column hint to 10000. Update highest_line field.
+ (linemap_position_for_column): Moved from line-map.h. Optimize a bit.
+ * cpphash.h (struct cpp_reader): Remove line field - instead use
+ line_table->highest_line.
+ (saved_line): Remove unused field.
+ (CPP_INCREMENT_FILE): Don't do linemap_lookup - just use newest map.
+ Use line_table's highest_line field instead of cpp_reader's line.
+ * cpplib.c (start_directive): Likewise use highest_line field.
+ (do_line, do_linemarker): Likewise just use newest map.
+ (_cpp_do_file_change): Don't need to set cpp_reader's line field.
+ * cpperror.c (cpp_error): Likewise use highest_line field.
+ * cppfiles.c (open_file_failed: Likewise.
+ (cpp_make_system_header): Likewise use newest map and highest_line.
+ * cppinit.c (cpp_create_reader): Don't initialize removed field.
+ * cpplex.c (_cpp_process_line_notes, _cpp_skip_block_comment,
+ skip_line_comment, skip_whitespace, _cpp_get_fresh_line,
+ _cpp_lex_direct): Likewise use highest_line.
+ (_cpp_lex_direct): Use new LINEMAP_POSITION_FOR_COLUMN macro.
+ * cppmacro.c (_cpp_builtin_macro_text): Likewise use highest_line,
+ and use newest map.
+ * cpppch.c (cpp_read_state): Don't save+restore cpp_reader's line.
+ * cpptrad.c (_cpp_overlay_buffer): Don't save cpp_reader's line.
+ (copy_comment, _cpp_scan_out_logical_line): Likewise use highest_line.
+
+2004-04-23 Alan Modra <amodra@bigpond.net.au>
+
+ PR bootstrap/14992
+ * gcc.c (init_gcc_specs): Test USE_LD_AS_NEEDED, not HAVE_LD_AS_NEEDED.
+ * config/linux.h (USE_LD_AS_NEEDED): Define.
+ * gcc/config/alpha/linux.h (USE_LD_AS_NEEDED): Define.
+ * gcc/config/arm/linux-elf.h (USE_LD_AS_NEEDED): Define.
+ * gcc/config/rs6000/linux.h (USE_LD_AS_NEEDED): Define.
+ * gcc/config/rs6000/linux64.h (USE_LD_AS_NEEDED): Define.
+ * gcc/config/sh/linux.h (USE_LD_AS_NEEDED): Define.
+ * gcc/config/sparc/linux.h (USE_LD_AS_NEEDED): Define.
+ * gcc/config/sparc/linux64.h (USE_LD_AS_NEEDED): Define.
+
+2004-04-22 Per Bothner <per@bothner.com>
+
+ * cppinit.c (cpp_read_main_file): Return NULL rather than false.
+ Fixes PR preprocessor/15067.
+
+2004-04-23 Andreas Schwab <schwab@suse.de>
+
+ * config/ia64/ia64intrin.h: Add intermediate cast to void * to
+ avoid aliasing warning.
+
+2004-04-22 Jan Hubicka <jh@suse.cz>
+ Mostafa Hagog <mustafa@il.ibm.com>
+
+ * cfgloopmanip.c (scale_bbs_frequencies): Use RDIV macro
+ * cfgloopanal.c (expected_loop_iterations): Change the return value
+
+2004-04-22 Jakub Jelinek <jakub@redhat.com>
+
+ * cselib.h (struct elt_loc_list): Remove canon_loc field.
+ * cselib.c (new_elt_loc_list): Remove canon_loc initialization.
+ (cselib_invalidate_mem): Remove all canon_loc and canon_x
+ traces.
+
+2004-04-22 Josef Zlomek <zlomekj@suse.cz>
+
+ Revert
+ 2004-04-20 Josef Zlomek <zlomekj@suse.cz>
+
+ * var-tracking.c (variable_part_different_p): Variable parts
+ differ when the most recent locations differ.
+
+2004-04-22 Richard Sandiford <rsandifo@redhat.com>
+
+ * doc/invoke.texi: Remove the MIPS -membedded-pic option.
+ * config/mips/mips-protos.h (embedded_pic_fnaddr_reg): Delete.
+ (embedded_pic_offset): Delete.
+ * config/mips/mips.h (MASK_EMBEDDED_PIC): Delete. Shuffle other
+ MASK_* constants.
+ (TARGET_EMBEDDED_PIC): Delete.
+ (TARGET_SWITCHES): Remove -m{no-,}embedded-pic.
+ (ASM_SPEC): Remove -membedded-pic.
+ (ASM_OUTPUT_ADDR_DIFF_ELT): Remove embedded-pic handling.
+ (ASM_OUTPUT_CASE_LABEL): Likewise.
+ * config/mips/vxworks.h (ASM_SPEC): Remove -membedded-pic.
+ * config/mips/windiss.h (ASM_SPEC): Likewise.
+ * config/mips/mips.c (struct machine_function): Remove
+ embedded_pic_fnaddr_rtx.
+ (TARGET_ENCODE_SECTION_INFO): Remove override.
+ (embedded_pic_fnaddr_reg, embedded_pic_offset): Delete.
+ (override_options): Remove -membedded-pic handling.
+ (print_operand): Remove handling of '%S'.
+ (mips_select_section: Remove -membedded-pic handling.
+ (mips_encode_section_info): Delete.
+ (mips_output_conditional_branch): Remove mention of -membedded-pic.
+ * config/mips/mips.md (define_attr length, movsi, movdi, jump): Remove
+ -membedded-pic handling.
+ (casesi, casesi_internal, casesi_internal_di, get_fnaddr): Delete.
+
+2004-04-22 Alan Modra <amodra@bigpond.net.au>
+
+ * var-tracking.c (frame_base_decl): Remove useless GTY.
+
+2004-04-21 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_override_options): Error when
+ user wants altivec and e500 instructions.
+
+2004-04-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/14813
+ * config/ia64/crtend.asm: Move pointer to __do_global_ctors_aux
+ in .init_array section to ...
+ * config/ia64/crtbegin.asm: Here.
+
+ * config/ia64/crtend.asm: Mark __do_global_ctors_aux global
+ and hidden if HAVE_INITFINI_ARRAY is defined.
+
+2004-04-21 James E Wilson <wilson@specifixinc.com>
+
+ * config/mips/mips-protos.h (fp_register_operand, lo_operand): Declare.
+ * config/mips/mips.c (mips_multipass_dfa_lookahead): Declare.
+ (TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD): New.
+ (fp_register_operand, lo_operand): New.
+ (mips_rtx_costs): Add TUNE_SB1 support.
+ (mips_issue_rate): Add comment. Add PROCESSOR_SB1 support.
+ (mips_use_dfa_pipeline_interface): Add PROCESSOR_SB1 support.
+ (mips_multipass_dfa_lookahead): New.
+ * config/mips/mips.h (MASK_FP_EXCEPTIONS, TARGET_FP_EXCEPTIONS,
+ TUNE_SB1): New.
+ (TARGET_SWITCHES): Add -mfp-exceptions support.
+ (TARGET_FP_EXCEPTIONS_DEFAULT): New.
+ (BRANCH_COST): Fix whitespace.
+ * config/mips/mips.md: Include sb1.md.
+ * config/mips/sb1.md: New file.
+ * doc/invoke.texi: Document -mfp-exceptions.
+
+ * Makefile.in (fixinc.sh): Don't set or export WARN_CFLAGS. Fix
+ comment.
+ * fixinc/Makefile.in (FL_LIST): Don't mention WARN_CFLAGS.
+ (fixincl.o-warn): Delete.
+
+2004-04-21 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/rs6000/rs6000 (print_operand) ['z']:
+ Change ifdef of TARGET_MACHO to if TARGET_MACHO.
+
+2004-04-21 Daniel Jacobowitz <drow@mvista.com>
+
+ * config.gcc: Support --with-arch=iwmmxt for ARM.
+
+2004-04-21 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * expmed.c (expand_mult_highpart_optab): Use narrower version of OP1
+ in two more places; remove unneeded force_reg
+
+2004-04-21 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/rs6000/rs6000.c (symbol_ref_operand): Remove hack
+ for TARGET_MACHO.
+ (print_operand): For TARGET_MACHO check to see if we need a stub
+ and output one if we need it.
+
+ PR debug/15033
+ * dwarf2out.c (rtl_for_decl_location): Check for NULL
+ rtl.
+
+2004-04-20 James E Wilson <wilson@specifixinc.com>
+
+ * config/ia64/ia64.md (call_value_nogp): Add constraints for op0.
+ (vall_value_gp): Likewise.
+
+2004-04-20 DJ Delorie <dj@redhat.com>
+
+ * dwarf2out.c (rtl_for_decl_location): Adjust rtl for byte
+ variables stored in word registers, then in memory.
+
+2004-04-20 Eric Christopher <echristo@redhat.com>
+
+ * cp/parser.c (cp_parser_declaration): Move translate
+ up before tokens are lexed.
+
+2004-04-20 Uros Bizjak <uros@kss-loka.si>
+
+ * optabs.h (enum optab_index): Add new OTI_asin and OTI_acos.
+ (asin_optab, acos_optab): Define corresponding macros.
+ * optabs.c (init_optabs): Initialize asin_optab and acos_optab.
+ * genopinit.c (optabs): Implement asin_optab and acos_optab
+ using asin?f2 and acos?f2 patterns.
+ * builtins.c (expand_builtin_mathfn): Handle BUILT_IN_ASIN{,F,L}
+ using asin_optab, and BUILT_IN_ACOS{,F,L} using acos_optab.
+ (expand_builtin): Expand BUILT_IN_ASIN{,F,L} and BUILT_IN_ACOS{,F,L}
+ using expand_builtin_mathfn if flag_unsafe_math_optimizations is set.
+
+ * config/i386/i386.md (asindf2, asinsf2, asinxf2, acosdf2,
+ acossf2, acosxf2): New expanders to implement asin, asinf, asinl,
+ acos, acosf and acosl built-ins as inline x87 intrinsics.
+
+2004-04-20 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.c (arm_legitimate_address_p): Use rtx_equal_p.
+
+2004-04-20 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.c (arm_expand_prologue): Fix size calculation.
+
+2004-04-20 Paolo Bonzini <bonzini@gnu.org>
+
+ Revert part of 2004-04-17 change that moved -frename-registers
+ to -O1. -frename-registers is buggy.
+
+ * toplev.c (flag_rename_registers): Initialize to 0.
+ * doc/invoke.texi (Optimize options): Move -frename-registers
+ to "Not triggered by any -O level" section. Adjust commentary
+ accordingly.
+
+2004-04-20 Anil Paranjpe <anilp1@kpitcummins.com>
+
+ * toplev.c (compile_file): Move targetm.asm_out.file_end call to end.
+
+2004-04-20 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_legitimize_move): Generate special patterns
+ for mflo and mfhi instructions.
+ (mips_output_move): Remove mflo and mfhi handling.
+ * config/mips/mips.md (UNSPEC_MFHILO): New unspec.
+ (*mulsidi3_64bit): Update for new mfhi/mflo representation.
+ Likewise various define_peephole2s.
+ (*movdi_32bit, *movdi_64bit, *movsi_internal): Merge x<-J and x<-d
+ alternatives.
+ (*movdi_64bit, *movdi_64bit_mips16, *mov[shq]i_internal)
+ (*mov[shq]i_mips16): Remove mflo and mfhi alternatives.
+ (mfhilo_di, mfhilo_si): New patterns.
+
+2004-04-20 Josef Zlomek <zlomekj@suse.cz>
+
+ * function.c (assign_parms): Force
+ MEM_EXPR (DECL_INCOMING_RTL (parm)) == parm.
+
+2004-04-20 Josef Zlomek <zlomekj@suse.cz>
+
+ * var-tracking.c (variable_part_different_p): Variable parts differ
+ when the most recent locations differ.
+
+2004-04-19 James E Wilson <wilson@specifixinc.com>
+
+ * rtl.h (reg_set_last): Delete declaration.
+ * rtlanal.c (reg_set_last): Delete.
+
+2004-04-19 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold_convert): Make function extern/public.
+ * tree.h (fold_convert): Prototype here.
+ * builtins.c (expand_builtin_strstr, expand_builtin_strchr,
+ expand_builtin_strrchr, expand_builtin_strpbrk,
+ expand_builtin_mempcpy, expand_builtin_bcopy,
+ expand_builtin_bzero, expand_builtin_memcmp,
+ expand_builtin_strcmp, expand_builtin_strncmp,
+ stabilize_va_list, expand_builtin_sprintf,
+ fold_trunc_transparent_mathfn, fold_builtin_logarithm,
+ fold_builtin_exponent, fold_builtin_mempcpy,
+ fold_builtin_strcpy, fold_builtin_strcmp, fold_builtin_strncmp,
+ fold_builtin_signbit, fold_builtin_isdigit, fold_builtin): Prefer
+ fold_convert to "convert" or "fold (build1 (NOP_EXPR, ...))".
+
+2004-04-19 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.md (UNSPEC_MV_CR_GT): New constant.
+ (move_from_CR_gt_bit): New.
+ (cceq_ior_compare): Name previously unnamed pattern. Disable for
+ E500.
+ (cceq_rev_compare): Name previously unnamed pattern. Allow for
+ E500.
+
+ * config/rs6000/spe.md (cmpsfeq_gpr): Rewrite as unspec.
+ (tstsfeq_gpr): Same.
+ (cmpsfgt_gpr): Same.
+ (tstsfgt_gpr): Same.
+ (cmpsflt_gpr): Same.
+ (tstsflt_gpr): Same.
+ (e500_cceq_ior_compare): New.
+ (e500_flip_gt_bit): New.
+
+ * config/rs6000/rs6000.c (ccr_bit): Remove E500 specific code.
+ (print_operand): Add 'c' and 'D'.
+ (rs6000_generate_compare): Rewrite to generate correct rtl.
+ (rs6000_emit_sCOND): Handle E500.
+ (output_cbranch): Adjust for changes in rs6000_generate_compare.
+ (output_e500_flip_gt_bit): New.
+
+ * config/rs6000/rs6000-protos.h (output_e500_flip_gt_bit):
+ Protoize.
+
+2004-04-19 Eric Christopher <echristo@redhat.com>
+
+ * config/mips/mips.h (DWARF2_ADDR_SIZE): New.
+
+2004-04-19 David Edelsohn <edelsohn@gnu.org>
+
+ * doc/install.texi (*-ibm-aix*): Add AIX 5.1 assembler and archiver
+ fix information.
+
+2004-04-19 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * doc/install.texi (Specific, mips-sgi-irix5): Fix IRIX 5.3 IDO
+ download URL.
+
+2004-04-19 Daniel Jacobowitz <drow@mvista.com>
+
+ * stor-layout.c (layout_decl): Check DECL_PACKED before calling
+ ADJUST_FIELD_ALIGN. Check maximum_field_alignment after.
+
+2004-04-19 Andrew PInski <pinskia@physics.uc.edu>
+
+ * builtins.c (fold_builtin_cabs): Remove fndecl parameter.
+ (fold_builtin): Update caller to match.
+
+ PR bootstrap/15009
+ * bb-reorder.c (fix_up_fall_thru_edges): Init cond_jump.
+
+ PR bootstrap/14999
+ * builtins.c (fold_builtin_cabs): Mark fndecl as unused.
+
+2004-04-19 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * varasm.c (compare_constant, case VIEW_CONVERT_EXPR): Add case.
+
+ * expmed.c (expand_mult_highpart_adjust): Make OP1 valid for MODE.
+ (expand_mult_highpart_optab): Likewise.
+ (expand_mult_highpart): Make OP1 valid for WIDER_MODE, not MODE.
+
+2004-04-19 Paul Brook <paul@codesourcery.com>
+
+ * config/arm/arm.md (fixuns_truncsfsi2, fixuns_truncdfsi2,
+ floatunssisf2, floatunssidf2): New patterns.
+
+2004-04-18 Mark Mitchell <mark@codesourcery.com>
+
+ PR other/14918
+ * doc/invoke.texi (-fprofile-generate): Document requirement to
+ use -fprofile-generate when linking.
+
+ * doc/extend.texi (Strong Using): Warn users against using this
+ feature.
+
+2004-04-18 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (m16_usym8_4, m16_usym5_4): Delete.
+ * config/mips/mips.h (mips_entry, mips_string_length): Delete.
+ (CONSTANT_POOL_BEFORE_FUNCTION, ASM_OUTPUT_POOL_EPILOGUE): Undefine.
+ * config/mips/mips.c (struct mips16_constant): Renamed from struct
+ constant. Propogate change throughout file.
+ (struct machine_function): Remove insns_len.
+ (mips_string_length, mips16_strings, string_constants): Delete.
+ (mips_classify_symbol): Return SYMBOL_CONSTANT_POOL for LABEL_REFs
+ when generating mips16 code. Remove special mips16 treatment of
+ string constants.
+ (mips_symbolic_constant_p): Allow mips16 constant pool accesses
+ to have the form LABEL+CONSTANT.
+ (mips_symbolic_address_p): Fix comment.
+ (m16_usym8_4, m16_usym5_4): Delete.
+ (mips_output_function_epilogue): Remove mips16 string handling.
+ (mips_output_mi_thunk): Call mips16_lay_out_constants.
+ (mips_select_section, mips_encode_section_info): Remove mips16
+ string handling.
+ (struct mips16_constant_pool): New.
+ (add_constant): Take a mips16_constant_pool structure. Keep pool
+ sorted into order of ascending mode size. Keep track of the highest
+ possible start address, taking padding and the masking of the base PC
+ value into account.
+ (dump_constants_1): New function, split out from dump_constants.
+ Handle vector constants. Use gen_consttable_{int,float} rather than
+ separate functions for each mode.
+ (dump_constants): Simplify. Use GET_MODE_ALIGNMENT. Use gen_align
+ rather than separate functions for each alignment.
+ (mips_find_symbol): Delete.
+ (mips16_insn_length): New function, split out from
+ mips16_lay_out_constants.
+ (mips16_rewrite_pool_refs): New function.
+ (mips16_lay_out_constants): Rework. Remove string handling.
+ Always create an inline constant pool.
+ * config/mips/mips.md (UNSPEC_CONSTTABLE_INT, UNSPEC_CONSTTABLE_FLOAT)
+ (UNSPEC_ALIGN): New constants.
+ (UNSPEC_CONSTTABLE_[QHSD]I, UNSPEC_CONSTTABLE_[SD]F): Delete.
+ (UNSPEC_ALIGN_[248]): Delete.
+ (consttable_int, consttable_float, align): New patterns.
+ (consttable_[qhsd]i, consttable_[sd]f, align_[248]): Delete.
+
+2004-04-17 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/altivec.h (vec_any_numeric): Correct typo in
+ __unn_args_eq.
+
+2004-04-17 Alan Modra <amodra@bigpond.net.au>
+
+ PR target/14715
+ * config/rs6000/rs6000.c (rs6000_stack_info): Make parm_size agree
+ with STARTING_FRAME_OFFSET.
+
+2004-04-17 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (PREDICATE_CODES): Add macc_msac_operand.
+ * config/mips/mips.c (macc_msac_operand): New function.
+ * config/mips/mips.md (*msac): Move after *macc.
+ (*msac2): New. Generalize macc-related peepholes so that they apply
+ to msac too.
+
+2004-04-17 Paolo Bonzini <bonzini@gnu.org>
+
+ * opts.c (decode_options): Do not enable flag_rename_registers
+ and flag_web at -O3.
+ * toplev.c (flag_rename_registers): Initialize
+ flag_rename_registers and flag_web to
+ AUTODETECT_FLAG_VAR_TRACKING.
+ (default_debug_hooks): New global.
+ (process_options): Initialize default_debug_hooks. Warn if
+ -fvar-tracking specified but not supported by the current
+ debug format. Do not run var tracking at -O0 or if not
+ supported by the current debug format, even if
+ -fvar-tracking was given. If -fno-rename-registers
+ is not specified, always run register renaming if var
+ tracking is supported by the default debugging information
+ format for the target, and we are at -O1 or higher; similarly
+ for -fweb, but only at -O2 or higher.
+ * doc/invoke.texi (Optimize Options): Document this.
+
+2004-04-17 Richard Sandiford <rsandifo@redhat.com>
+
+ * configure.ac (gcc_cv_ld_as_needed): Use AC_CACHE_CHECK.
+ * configure: Regenerate.
+
+2004-04-17 Richard Sandiford <rsandifo@redhat.com>
+
+ * gcc.c (used_arg): Check whether an option has been removed.
+
+2004-04-17 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config.gcc (i[34567]86-*-solaris2*): Default to DWARF-2
+ debugging on Solaris 7 and up.
+
+2004-04-16 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * doc/install.texi (Specific, mips-sgi-irix5): Reflect working
+ IRIX 5 port.
+ Remove -save-temps workaround, handled automatically.
+ Require GNU binutils 2.15 for debugging.
+ Remove SGI make warnings since GNU make is now required.
+ (Specific, mips-sgi-irix6): Some markup fixes.
+ Describe MIPSpro C problems and workarounds.
+ Mention working O32 ABI support.
+ Recommend GNU as 2.15 for O32 with debugging.
+ Remove description of fixed structure pass/return bug.
+
+2004-04-16 DJ Delorie <dj@redhat.com>
+
+ * sdbout.c (sdbout_one_type): Use TYPE_VALUES for enums, not
+ TYPE_FIELDS.
+ (sdbout_finish): Don't free deferred_global_decls; it's GC'd.
+
+2004-04-16 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.md: Remove unnecessary declarations for asm_out_file.
+
+ * pa64-regs.h (DBX_REGISTER_NUMBER): Simplify and correct mapping of
+ SAR register. Fix comment.
+ (ADDITIONAL_REGISTER_NAMES): Correct register number of SAR register
+ (%cr11).
+
+ * pa64-hpux.h (LIB_SPEC): Fix library specification used with GNU ld.
+
+2004-04-16 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/arm.c (arm_override_options): Revert previous patch.
+ * config/arm/t-xscale-elf: Disable iwmmxt multilibs until they can
+ be safely built.
+
+2004-04-16 Kazuhiro Inaoka <inaoka dot kazuhiro at renesas dot com>
+
+ * config/m32r/m32r.h (BIG_ENDIAN_BIT): Deleted to fix endian
+ bug.
+ (TARGET_LITTLE_ENDIAN, TARGET_BIG_ENDIAN,
+ TARGET_DEFAULT): Changed. Ditto.
+ (LITTLE_ENDIAN_BIT, TARGET_CPU_DEFAULT,
+ TARGET_ENDIAN_DEFAULT): Added. Ditto.
+ * config/m32r/little.h (TARGET_LITTLE_ENDIAN): Deleted.
+ (TARGET_ENDIAN_DEFAULT): Added.
+
+2004-04-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.def (BUILT_IN_ISDIGIT, BUILT_IN_ISXDIGIT): Mark with
+ ATTR_CONST_NOTHROW_LIST.
+
+2004-04-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ PR/middle-end 14915
+ * builtins.c (expand_builtin_signbit): Test BYTES_BIG_ENDIAN, not
+ BITS_BIG_ENDIAN.
+
+2004-04-15 Pat Haugen <pthaugen@us.ibm.com>
+
+ * ra-debug.c (ra_print_rtx): Add break's to case legs.
+
+2004-04-14 James E Wilson <wilson@specifixinc.com>
+
+ * Makefile.in (fixinc.sh): Set WARN_CFLAGS to empty string.
+
+2004-04-14 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * libada-mk.in: New file.
+ * configure.ac: Create libada-mk from libada-mk.in.
+ * configure: Regenerate.
+
+2004-04-14 Uros Bizjak <uros@kss-loka.si>
+
+ * optabs.h (enum optab_index): Add new OTI_logb and OTI_ilogb.
+ (logb_optab, ilogb_optab): Define corresponding macros.
+ * optabs.c (init_optabs): Initialize logb_optab and ilogb_optab.
+ * genopinit.c (optabs): Implement logb_optab and ilogb_optab
+ using logb?f2 and ilogb?i2 patterns.
+ * builtins.c (expand_builtin_mathfn): Handle BUILT_IN_LOGB{,F,L}
+ using logb_optab, and BUILT_IN_ILOGB{,F,L} using ilogb_optab.
+ (expand_builtin): Expand BUILT_IN_LOGB{,F,L} and BUILT_IN_ILOGB{,F,L}
+ using expand_builtin_mathfn if flag_unsafe_math_optimizations is set.
+
+ * reg-stack.c (subst_stack_regs_pat): Handle UNSPEC_XTRACT_FRACT
+ and UNSPEC_XTRACT_EXP.
+
+ * config/i386/i386.md (*fxtractdf3, *fxtractsf3, *fxtractxf3): New
+ patterns to implement fxtract x87 instruction.
+ (logbdf2, logbsf2, logbxf2, ilogbsi2): New expanders to implement
+ logb, logbf, logbl, ilogb, ilogbf and ilogbl built-ins as inline x87
+ intrinsics.
+ (UNSPEC_XTRACT_FRACT, UNSPEC_XTRACT_EXP): New unspecs to represent
+ x87's fxtract insn.
+
+2004-04-14 Eric Christopher <echristo@redhat.com>
+
+ * config/mips/t-elf: Enable multilibs by default.
+
+2004-04-14 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * bb-reorder.c (fix_crossing_conditional_branches): Adjust the
+ previous fix to check HAVE_return at runtime too.
+
+2004-04-14 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/arm.c (arm_override_options): If the user has not
+ specified an ABI, then default to AAPCS for the iWMMXt processor.
+ * config/arm/t-xscale-elf: Remove redundant multilib specifications.
+ * config/arm/t-xscale-coff: Likewise.
+
+2004-04-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (fold_builtin_isdigit): New.
+ (fold_builtin): Handle BUILT_IN_ISDIGIT.
+ * defaults.h: Add TARGET_DIGIT0 and sort.
+ * doc/tm.texi: Add TARGET_BS and TARGET_DIGIT0.
+
+2004-04-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (fold_builtin_cabs, fold_builtin): Use
+ `mathfn_built_in' to determine the new builtin.
+ * fold-const.c (fold): Likewise.
+
+2004-04-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * doc/invoke.texi: Rename MIPS's -mfix-vr4122-bugs to -mfix-vr4120.
+ * config/mips/mips.h (MASK_FIX_VR4120): Renamed from MASK_FIX_VR4122.
+ (TARGET_FIX_VR4120): Likewise TARGET_FIX_VR4122.
+ (TARGET_SWITCHES): Replace -mfix-vr4122-bugs with -mfix-vr4120.
+ (ASM_SPEC): Update accordingly.
+ * config/mips/mips.c: Update after above renaming.
+ * config/mips/mips.md, config/mips/t-vr, config/mips/vr.h: Likewise.
+ * config/mips/vr4120-div.S: Renamed from vr4122-div.S.
+
+2004-04-13 James E Wilson <wilson@specifixinc.com>
+
+ * c-opt.c (c_common_post_options): If this_input_filename is NULL,
+ increment errorcount and return false instead of true.
+
+2004-04-13 Uros Bizjak <uros@kss-loka.si>:
+
+ * optabs.c (expand_twoval_unop): Reorder function arguments.
+ * builtins.c (expand_builtin_mathfn_3): Update calls to
+ expand_twoval_unop.
+
+ * reg-stack.c (subst_stack_regs_pat): Handle UNSPEC_TAN_ONE
+ and UNSPEC_TAN_TAN. Add missing comment.
+
+ * config/i386/i386.md (*tandf3_1, *tansf3_1, *tanxf3_1): New
+ patterns to implement fptan x87 instruction.
+ (tandf2, tansf2, tanxf2): New expanders to implement tan, tanf
+ and tanl built-ins as inline x87 intrinsics. Define corresponding
+ peephole2 optimizers for 'fptan; fstp %st(0); fld1' sequence.
+ (UNSPEC_TAN_ONE, UNSPEC_TAN_TAN): New unspecs to represent
+ x87's fptan insn.
+
+2004-03-13 Richard Henderson <rth@redhat.com>
+
+ * bb-reorder.c (fix_crossing_unconditional_branches): Use Pmode
+ for LABEL_REFs.
+
+ * defaults.h (HOT_TEXT_SECTION_NAME): Add leading dot.
+ (UNLIKELY_EXECUTED_TEXT_SECTION_NAME): Likewise.
+ * doc/invoke.texi: Update to match.
+
+ * varasm.c (unlikely_text_section): Use assemble_align instead of
+ ASM_OUTPUT_ALIGN. Use it in the correct place with an approximately
+ correct alignment argument.
+
+2004-04-13 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * reload1.c (emit_reload_insns): Set reg_has_output_reload to one
+ after setting reg_last_reload_reg for optional output reloads.
+
+2004-04-12 Fariborz Jahanian <fjahanian@apple.com>
+
+ * config/rs6000/altivec.h (vec_mergeh, vec_mergel):
+ Definition of these two macros are corrected by adding
+ matchine right paren.
+
2004-04-12 Jonathan Larmour <jifl@eCosCentric.com>
* fix-header.c: kill(), putenv() and tzset() are POSIX not ANSI.
@@ -465,8 +3680,8 @@
(sindf2, sinsf2, sinxf2): Rename to *sindf2, *sinsf2, *sinxf2.
(cosdf2, cossf2, cosxf2): Rename to *cosdf2, *cossf2, *cosxf2.
- (UNSPEC_SINCOS_SIN, UNPEC_SINCOS_COS): New unspecs to represent
- x87's unspec insn.
+ (UNSPEC_SINCOS_SIN, UNSPEC_SINCOS_COS): New unspecs to represent
+ x87's fsincos insn.
2004-04-06 Devang Patel <dpatel@apple.com>
diff --git a/gcc/ChangeLog.tree-ssa b/gcc/ChangeLog.tree-ssa
new file mode 100644
index 00000000000..cf077aa1e36
--- /dev/null
+++ b/gcc/ChangeLog.tree-ssa
@@ -0,0 +1,19338 @@
+2004-05-11 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (delete_tree_cfg): Update call to
+ free_basic_block_vars.
+
+2004-05-10 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa-live.h: Fix typo in #include guard.
+
+2004-05-08 Jeff Sturm <jsturm@one-point.com>
+
+ * tree-eh.c (lower_catch): Lower catch body in context of
+ catch_region.
+
+2004-05-07 Richard Henderson <rth@redhat.com>
+
+ * tree-eh.c (tree_could_trap_p): Use get_base_address on references.
+
+2004-05-07 Diego Novillo <dnovillo@redhat.com>
+
+ * doc/invoke.texi: Remove documentation for -ftree-copyprop.
+ Update documentation for -ftree-pre.
+
+2004-05-06 Richard Henderson <rth@redhat.com>
+
+ * stmt.c (parse_output_constraint): Don't warn for read-write
+ memory operand.
+ * gimplify.c (gimplify_asm_expr): Force in-out memory operands
+ to minimal lvalues, then expand to non-matching constraints.
+
+2004-05-06 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (finish_function): When !targetm.have_ctors_dtors,
+ record static constructors and destructors here...
+ (c_expand_body_1): ... not here.
+ * c-objc-common.c (start_cdtor, finish_cdtor): Collapse
+ together into
+ (build_cdtor): ...here. Update to construct a complete tree
+ for the function. No need to call push_scope, pop_scope, or
+ clear_last_expr, or set current_function_cannot_inline.
+ (c_objc_common_finish_file): Just call build_cdtor for static
+ ctors/dtors, then clear the variables. Do this before calling
+ cgraph_finalize_compilation_unit and cgraph_optimize.
+
+2004-05-06 Richard Henderson <rth@redhat.com>
+
+ * fold-const.c (fold): Don't build COND_EXPR from comparisons for
+ boolean and integer result types. Handle X ^ X for TRUTH_XOR_EXPR.
+
+2004-05-05 Richard Henderson <rth@redhat.com>
+
+ * tree-nested.c (create_tmp_var_for): Disallow variable sized types.
+ (convert_nonlocal_reference): Set val_only false for the base of a
+ component or array reference.
+ (convert_local_reference): Likewise.
+
+2004-05-05 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (create_tmp_var): Disallow variable sized objects.
+ (gimplify_modify_expr): Don't memcpy for VA_ARG_EXPR.
+
+2004-05-05 Richard Henderson <rth@redhat.com>
+
+ * fold-const.c (operand_equal_p): Replace only_const argument with
+ flags. Allow pure functions if OEP_PURE_SAME.
+ (fold, nondestructive_fold_binary_to_constant): Use OEP_ONLY_CONST.
+ * tree-cfg.c (phi_alternatives_equal): Fix operand_equal_p flag type.
+ * tree-ssa-dom.c (avail_expr_eq): Use OEP_PURE_SAME.
+ * tree.h (enum operand_equal_flag): New.
+ (operand_equal_p): Update argument list.
+
+2004-05-05 Richard Henderson <rth@redhat.com>
+
+ * tree-ssa-operands.c (get_call_flags): Remove.
+ (get_expr_operands): Use call_expr_flags.
+ * tree-alias-common.c (call_may_clobber): Likewise.
+ (call_may_return): Likewise.
+
+2004-04-05 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c/15062
+ * c-typeck.c (build_asm_expr): Mark the output operands
+ to an asm addressable, if necessary.
+
+2004-05-05 Steven Bosscher <stevenb@suse.de>
+
+ * Makefile.in (GTFILES): Remove duplicate basic-block.h.
+
+2004-05-04 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (build_addr_expr_with_type): Set TREE_ADDRESSABLE.
+ (gimplify_modify_expr): Turn variable-width assignment into memcpy.
+ * tree-nested.c (convert_local_reference): Set val_only after default.
+
+2004-05-04 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (tree_cfg2vcg): Rename from tree_cfg2dot. Update all
+ users.
+ Emit flowgraph using VCG syntax.
+ * tree-dump.c (dump_files): Rename -fdump-tree-dot to
+ -fdump-tree-vcg.
+ * tree.h (enum tree_dump_index): Rename TDI_dot to TDI_vcg.
+ * doc/invoke.texi: Update documentation to describe
+ -fdump-tree-vcg.
+
+2004-05-03 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * objc/objc-act.c (build_objc_string_object):
+ Add the fields to the purpose of the list for
+ the constructor.
+
+2004-05-03 Richard Henderson <rth@redhat.com>
+
+ * c-simplify.c (gimplify_if_stmt): Loop for else-if.
+
+2004-05-03 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR optimization/15245
+ * tree-ssa-phiopt.c (conditional_replacement): Use fold_convert
+ instead of convert.
+
+2004-05-03 Diego Novillo <dnovillo@redhat.com>
+
+ * gimplify.c (gimplify_compound_lval): Gimplify non-constant
+ array indices into a temporary variable.
+
+2004-04-30 Richard Henderson <rth@redhat.com>
+
+ * builtins.c (validate_arglist): Don't reject side effects.
+ (simplify_builtin_strcpy): Do reject side effects in length.
+
+2004-04-30 Jeff Law <law@redhat.com>
+
+ * tree-outof-ssa.c (eliminate_build): Move code which verifies
+ that all of a PHI's arguments do not have a partition if the
+ result does not have a partition from here to...
+ (rewrite_trees): Here.
+
+2004-04-24 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-cfg.c (factored_computed_goto_label,
+ factored_computed_goto): Removed.
+ (disband_implicit_edges): Unfactor computed gotos without
+ using them.
+
+2004-04-23 Per Bothner <per@bothner.com>
+
+ * expr.c (expr_wfl_stack): Remove unused global.
+
+ Pre-patches for future source_location / location_t merge.
+ * tree.h (EXPR_LOCATION, EXPR_HAS_LOCATION): New macros.
+ * expr.c (expand_expr_real, expand_expr_real_1): Use new macros.
+ * gimple-low.c (lower_stmt): Likewise.
+ * gimplify.c (annotate_all_with_locus): Likewise.
+ * print-tree.c (print_node): Likewise.
+ * tree-inline.c (expand_call_inline): Likewise.
+ * tree-pretty-print.c (tree-pretty-print.c): Likewise.
+ * tree-sra.c (scalarize_structure_assignment, emit_scalar_copies,
+ scalarize_call_expr): Likewise.
+ * tree-ssa-pre.c (code_motion): Likewise.
+
+2004-04-23 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * c-simplify.c (gimplify_decl_stmt) [TYPE_DECL]:
+ Do not check the type.
+
+2004-04-22 Jeff Law <law@redhat.com>
+
+ * tree-into-ssa.c (rewrite_initialize_block_local_data): Mark all
+ arguments as potentially unused. Do not bother to VARRAY_CLEAR
+ the block_defs. Instead abort if we are presented with a block
+ which has a nonempty block_defs. Wrap entire thing inside
+ #ifdef ENABLE_CHECKING.
+ * tree-ssa-dom.c (dom_opt_initialize_block_local_data): Similarly
+
+ * tree-ssa-dom.c (redirect_edges_and_update_ssa_graph): Do not mark
+ arguments to bypassed PHIs as needing to be rewritten.
+
+2004-04-21 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/14978
+ * tree-nested.c (convert_nonlocal_reference): Set val_only when
+ processing any otherwise unhandled expression.
+
+2004-04-21 Jeff Law <law@redhat.com>
+
+ * tree-ssa-copy.c (cprop_operand): Break out of cprop_into_stmt.
+ (cprop_into_stmt): Use cprop_operand. Rearrange slightly to avoid
+ switch statement inside a loop.
+
+ * tree-flow.h (var_ann_d): Add "current_def" field.
+ (register_new_def): Lose last argument (currdefs table).
+ * tree-into-ssa.c (currdefs): Remove.
+ (rewrite_into_ssa): Initialize current_def field on each variable's
+ annotation. Remove initialization/clearing of currdefs.
+ (set_value_for, get_value_for): Kill.
+ (rewrite_initialize_block): Update call to register_new_def.
+ (rewrite_stmt): Similarly.
+ (rewrite_finalize_block): Get/set a _DECL node's current
+ definition from its annotation.
+ (get_reaching_def): Similarly.
+ (register_new_def): Similarly. Lose last argument.
+ * tree-ssa-dom.c (currdefs): Remove.
+ (get_value_for, set_value_for): Simplify.
+ (tree_ssa_dominator_optimize): Initialize current_def on each
+ variable's annotation. Remove initialization/clearing of currdefs.
+ (thread_across_edge): Lose unnecessary argument to register_new_def.
+ (record_equivalences_from_phis): Likewise.
+ (register_definitions_for_stmt): Likewise.
+ (restore_currdefs_to_original_value): Get/set a _DECL node's current
+ definition from its annotation. Lose unnecessary "table" argument.
+ (dom_opt_finalize_block): Corresponding changes.
+
+ * tree-dfa.c (free_df_for_stmt): Release memory back to the GC
+ system immediately.
+
+2004-04-21 Ben Elliston <bje@au.ibm.com>
+
+ PR middle-end/14730
+ * expr.c (expand_expr_real_1) <SWITCH_EXPR>: Discard out of bounds
+ case label values and ranges. Saturate case range values that
+ exceed the minimum or maximum permitted value for the controlling
+ expression type to TYPE_MIN_VALUE or TYPE_MAX_VALUE.
+
+2004-04-20 Jeff Law <law@redhat.com>
+
+ * tree-into-ssa.c (register_new_def): Avoid pushing useless
+ information onto the block local definition stack.
+
+ * tree-into-ssa.c (register_new_def): If there is no current
+ reaching definition for SSA_NAME_VAR (DEF), then just push
+ SSA_NAME_VAR (DEF) onto the stack.
+ (rewrite_finalize_block): If we pop a _DECL node from the stack,
+ then the _DECL node has no current reaching definition.
+ * tree-ssa-dom.c (restore_currdefs_to_original_value): Similarly.
+
+2004-04-19 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c: Reinstate all changes from 2004-04-12.
+ (lookup_avail_expr): Do not access a hash table object after
+ it has been freed.
+
+2004-04-19 Daniel Berlin <dberlin@dberlin.org>
+
+ * doc/passes.texi: Add blurb about PRE.
+
+2004-04-19 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * tree-ssa-phiopt.c (conditional_replacement):
+ Catch some more non-gimple.
+
+2004-04-19 Jan Hubicka <jh@suse.cz>
+
+ * predict.c (combine_predictions_for_bb): Fix pasto.
+
+2004-04-18 Jan Hubicka <jh@suse.cz>
+
+ * tree-inline.c (estimate_num_insn_1): Deal properly with
+ builtin_constant_p and builtin_expect.
+
+2004-04-17 Andrew MacLeod <amacleod@redhat.com>
+
+ * doc/invoke.texi (tree-ter, tree-lrs): Document options.
+
+2004-04-17 Paul Brook <paul@codesourcery.com>
+
+ * Makefile.in: Set GMPLIBS and GMPINC.
+ * configure.ac: Add GMPLIBS and GMPINC.
+ * configure: Regenerate.
+
+2004-04-16 Andrew MacLeod <amacleod@redhat.com>
+
+ * common.opt (ftree-lrs): New common option.
+ * flags.h (flag_tree_live_range_split): New flag.
+ * opts.c (decode_options): Turn on LRS by default.
+ (common_handle_option): Set LRS flag to specified value.
+ * toplev.c (flag_tree_live_range_split): Initialize.
+ (lang_independent_options f_): Add tree-lrs.
+ * tree-outof-ssa.c (rewrite_out_of_ssa): Use LRS flag.
+ * tree-ssa-copyrename.c (copy_rename_partition_coalesce): Don't coalesce
+ variables if one is a hardware register. Coalesce inlined user vars.
+ (rename_ssa_copies): Scan blocks first, then PHI nodes.
+
+2004-04-15 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * builtins.c (fold_builtin_isascii): Do not return non-gimple
+ code when we are in gimple form.
+ (fold_builtin_isdigit): Do not return non-gimple
+ code when we are in gimple form.
+
+ * c-simplify.c (gimplify_decl_stmt): Handle TYPE_DECL.
+
+2004-04-14 Paul Brook <paul@codesourcery.com>
+
+ * Makefile.in (GMPLIBS, GMPINC): Don't set.
+ * configure.ac: Remove checks for GMP.
+ * configure: Regenerate.
+
+2004-04-13 Diego Novillo <dnovillo@redhat.com>
+
+ * fold-const.c, tree-ssa-ccp.c, tree-ssa-dom.c,
+ tree-ssa.c, tree.c: Replace all uses of TREE_UNSIGNED with
+ TYPE_UNSIGNED or DECL_UNSIGNED.
+
+ * c-semantics.c (build_stmt): Don't check type nodes for
+ side effects.
+
+2004-04-13 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c: Revert all changes from 2004-04-12.
+
+2004-04-12 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (struct expr_hash_elt): Add new field for hash value.
+ (initialize_hash_element): New LHS argument. Callers changed.
+ Initialize the hash value field.
+ (remove_local_expressions_from_table): Use htab_remove_elt_with_hash.
+ (update_rhs_and_lookup_avail_expr): Similary.
+ (lookup_avail_expr): Use htab_find_slot_with_hash. Simplify slightly
+ and pass LHS to initialize_hash_element.
+ (record_cond): Also use htab_find_slot_with_hash. Initialize the
+ hash table entry with initialize_hash_element.
+ (avail_expr_eq): Use the saved hash value rather than calling into
+ the hash functions again.
+
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize): Slightly rearrange
+ code to clear tables before each iteration to be clearer.
+
+ * tree-ssa-dom.c (redirect_edges_and_update_ssa_graph): Use
+ DEF_OPS and VDEF_OPS instead of STMT_DEF_OPS and STMT_VDEF_OPS.
+
+2004-04-12 Diego Novillo <dnovillo@redhat.com>
+
+ * flags.h (flag_tree_loop): Remove. Update all users.
+ * opts.c (common_handle_option) <OPT_ftree_loop_optimize>: Remove.
+ * toplev.c (f_options): Remove -ftree-loop-optimize.
+ * tree-optimize.c (init_tree_optimization_passes): Don't
+ schedule pass_loop.
+ * tree-ssa-loop.c (tree_ssa_loop_opt): Remove.
+ (gate_loop): Remove.
+ * doc/invoke.texi: Remove documentation for -ftree-loop-optimize.
+
+2004-04-12 Diego Novillo <dnovillo@redhat.com>
+
+ * c-lang.c (LANG_HOOKS_RTL_EXPAND_STMT): Remove.
+ * c-semantics.c (expand_stmt_toplev): Remove.
+ * langhooks-def.h (LANG_HOOKS_RTL_EXPAND_INITIALIZER): Remove.
+ (LANG_HOOKS_RTL_EXPAND_START): Remove.
+ (LANG_HOOKS_RTL_EXPAND_STMT): Remove.
+ (LANG_HOOKS_RTL_EXPAND_END): Remove.
+ * langhooks.h (struct lang_hooks_for_rtl_expansion): Remove.
+ (struct lang_hooks): Update.
+ * tree-optimize.c (tree_rest_of_compilation): Don't call
+ lang_hooks.rtl_expand.start nor lang_hooks.rtl_expand.end.
+ Call expand_expr_stmt_value instead of
+ lang_hooks.rtl_expand.stmt.
+ * objc/objc-lang.c (LANG_HOOKS_RTL_EXPAND_STMT): Remove.
+
+
+2004-04-12 Richard Henderson <rth@redhat.com>
+
+ * c-common.c (c_do_switch_warnings): Use EXPR_LOCUS instead
+ of STMT_LINENO.
+ (c_walk_subtrees): Likewise.
+ (c_estimate_num_insns_1): Remove FILE_STMT.
+ * c-common.def (FILE_STMT): Remove.
+ * c-common.h (FILE_STMT_FILENAME_NODE): Remove.
+ (FILE_STMT_FILENAME, STMT_LINENO, STMT_LINENO_FOR_FN_P): Remove.
+ (c_common_stmt_codes): Remove FILE_STMT.
+ * c-dump.c (dump_stmt): Use EXPR_LOCUS instead of STMT_LINENO.
+ * c-parse.in (lineno_stmt, lineno_label): Likewise.
+ * c-pretty-print.c (pp_c_statement): Remove FILE_STMT.
+ * c-semantics.c (add_stmt): Don't emit FILE_STMT. Do set
+ EXPR_LOCUS if not yet set.
+ (finish_stmt_tree): Don't set line for end of function.
+ (build_stmt): Set EXPR_LOCUS instead of STMT_LINENO.
+ (prep_stmt): Use EXPR_LOCUS instead of STMT_LINENO.
+ * c-simplify.c (c_gimplify_stmt): Remove FILE_STMT.
+ (gimplify_block): Save and restore entire locus.
+ (stmt_expr_last_stmt): Use EXPR_LOCUS instead of STMT_LINENO.
+ * doc/c-tree.texi (FILE_STMT, FILE_STMT_FILENAME, STMT_LINENO): Remove.
+
+2004-04-12 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (true_exprs, false_exprs): Kill.
+ (struct expr_hash_elt): New structure for the expression hash table.
+ (struct dom_walk_block_data): Kill block local true_exprs and
+ false_exprs.
+ (get_eq_expr_value): One less local varray argument. Fix prototype.
+ Use record_cond rather than record_cond_is_{true,false}.
+ (true_false_expr_hash, true_false_expr_eq): Kill.
+ (record_cond_is_true, record_cond_is_false): Collapse into ...
+ (record_cond): New function.
+ (tree_ssa_dominator_optimize): Kill references to true_exprs and
+ false_exprs. Use "free" as the free function for the avail_exprs
+ hash table.
+ (dom_opt_initialize_block_local_data): No longer initialize
+ block local true/false expressions.
+ (initialize_hash_element): New function.
+ (remove_local_expressions_from_table): Use initialize_hash_element.
+ (update_rhs_and_lookup_avail_expr): Similarly.
+ (dom_opt_finalize_block): Record true/false expressions into the
+ main avail_expr hash table. Unwind main hash table appropriately.
+ Use record_cond rather than record_cond_is_{true,false}.
+ (record_equivalences_from_incoming_edge): Pass block local avail_exprs
+ varray instead of block local true/false varrays to get_eq_expr_value.
+ (dump_dominator_optimization_stats): Update to reflect that the
+ true/false expression hash tables are gone.
+ (lookup_avail_expr): Simplify slightly now that we only have one
+ expression hash table.
+ (avail_expr_hash, avail_expr_eq): Generalize slightly to handle new
+ hash table entry structure and having true/false expression information
+ in the available expression hash table.
+
+2004-04-09 Jeff Law <law@redhat.com>
+
+ * tree-ssa_dom.c (register_definitions_for_stmt): Accept a statement
+ annotation rather than the statement itself. Callers changed.
+ Use [V]DEF_OPS rather than STMT_[V]DEF_OPS.
+ * tree-ssa-operands.c (get_stmt_operands): Slightly reorganize to
+ avoid unnecessary calls to stmt_ann.
+ * tree-ssa-pre.c (expr_phi_insertion): Get the statement's annotation
+ and use [V]USE_OPS rather than STMT_[V]USE_OPS.
+ (same_e_version_phi_result): Similarly
+ (process_left_occs_and_kills): Similarly for [V]DEF_OPS and
+ STMT_[V]DEF_OPS.
+ * tree-ssa.c (replace_immediate_uses): Similarly.
+ (verify_ssa): Similarly. Also verify that VDEF_OPs uses are dominated
+ by their sets.
+
+ * tree-into-ssa.c (insert_phi_nodes_for): Use passed in worklist
+ varray instead of allocated one for every variable we rewrite into
+ SSA form.
+ (insert_phi_nodes_1): Pass worklist varray from caller to
+ insert_phi_nodes_for.
+ (insert_phi_nodes): Allocate a worklist for insert_phi_nodes_for
+ and pass it to insert_phi_nodes_1.
+
+2004-04-08 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (nonzero_vars): Turn it into a bitmap.
+ (tree_ssa_dominator_optimize): Update initialization, clearing and
+ freeing of nonzero_vars.
+ (restore_nonzero_vars_to_original_value): New function.
+ (dom_opt_finalize_block): Use it.
+ (record_var_is_nonzero): Only record the variable into the block
+ local nonzero vars array if it did not already have a nonzero property.
+ (lookup_avail_expr): Lookup the nonzero property of an SSA_NAME with
+ a bitmap test.
+
+ * fold-const.c (fold): Remove attempt to share code which
+ simplifies tests against the highest/lowest value of a
+ range between the main folder and the nondestructive folder.
+
+2004-04-08 Brian Booth <bbooth@redhat.com>
+ Diego Novillo <dnovillo@redhat.com>
+
+ * tree-into-ssa.c (invalidate_name_tags): New function.
+ Mark aliases of invalidated name tags for renaming.
+ (rewrite_into_ssa): Call invalidate_name_tags.
+
+2004-04-07 Diego Novillo <dnovillo@redhat.com>
+
+ * gimplify.c (gimplify_call_expr): Remove argument POST_P.
+ Update all callers.
+ Don't use POST_P when gimplifying the call expression.
+
+2004-04-07 Diego Novillo <dnovillo@redhat.com>
+
+ * doc/tree-ssa.texi: Add documentation for the dominator
+ walker.
+
+2004-04-07 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-outof-ssa.c: Update comments and reformat for legibility.
+ * tree-ssa-copyrename.c: Update comments and reformat for legibility.
+ * tree-ssa-live.c: Update comments and reformat for legibility.
+ * tree-ssa-live.h: Update comments and reformat for legibility.
+
+2004-04-07 Diego Novillo <dnovillo@redhat.com>
+
+ * gimplify.c (gimplify_call_expr): Don't use POST_P when
+ gimplifying CALL_EXPR arguments.
+
+2004-04-06 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c: Update comments and reformat for legibility.
+ (find_vars_r): Remove special casing of MODIFY_EXPR and
+ simplify logic.
+ (compute_reached_uses, compute_reaching_defs, remove_decl,
+ find_decl_location): Remove.
+ (discover_nonconstat_array_refs_r,
+ discover_nonconstant_array_refs): Move ...
+ * tree-outof-ssa.c: ... here.
+
+2004-04-05 Richard Henderson <rth@redhat.com>
+
+ * tree-simple.c (is_gimple_min_invariant): Disallow &a+i.
+ * tree-ssa-ccp.c (maybe_fold_stmt_addition): Rename from
+ maybe_fold_stmt_plus. Handle MINUS_EXPR.
+ (fold_stmt_r): Pass MINUS_EXPR to it.
+
+2004-04-05 Ben Elliston <bje@au.ibm.com>
+
+ * Makefile.in (OBJS-common): Remove tree-browser.o.
+ (cc1): Depend on @TREEBROWSER@ and include in list of objects.
+ * configure.ac: Add --enable-tree-browser option.
+ * configure: Rebuild.
+
+2004-04-05 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * tree-ssa-ccp.c (fold_stmt_r): Fix whitespace formatting.
+ (set_rhs): Likewise.
+
+2004-04-03 Paolo Bonzini <bonzini@gnu.org>
+ Diego Novillo <dnovillo@redhat.com>
+
+ * tree-alias-common.c (find_func_aliases): Support
+ assigning to BIT_FIELD_REFs.
+ * tree-cfg.c (verify_expr): Don't allow assign to
+ a register with BIT_FIELD_REF.
+ * tree-dfa.c (get_virtual_var): Add consistency check on
+ the shape of expected VARs.
+ (discover_nonconstant_array_refs_r): Go through BIT_FIELD_REFs.
+ * tree-simple.c: Document that BIT_FIELD_REFs are valid lvalues.
+ * tree-ssa.c (set_is_used): Go through BIT_FIELD_REFs.
+ * tree-ssa-operands.c (get_expr_operands): Mark VA_ARG_EXPR
+ nodes as making volatile references.
+
+2004-04-02 Fariborz Jahanian <fjahanian@apple.com>
+
+ * c-convert.c (convert): Make convert work when converting
+ to compatible types across translation unit.
+
+2004-04-02 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * Makefile.in (stage2_build): Remove support for
+ rebuilding libbanshee.
+ * configure.ac: Remove support for rebuilding
+ libbanshee.
+ * config.gcc (powerpc-*-darwin*): Do not rebuild
+ libbanshee.
+
+2004-04-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * tree-ssa-forwprop.c: Add a comment about forward propagation
+ of TRUTH_NOT_EXPR.
+
+2004-04-01 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-optimize.c (tree_rest_of_compilation): Fix typo in
+ setting of in_gimple_form.
+
+2004-04-01 Jeff Law <law@redhat.com>
+
+ * fold-const.c (fold_relational_hi_lo): Do not return non-gimple
+ code when we are in gimple form.
+ * tree-optimize.c (tree_rest_of_compilation): Note when we are in
+ gimple form.
+ * tree-ssa-ccp.c (ccp_fold): Tighten tests on return value from
+ nondestructive_fold_{unary,binary}_to_constant.
+ * tree.h (in_gimple_form): Declare.
+
+ * tree-ssa.c (ssa_remove_edge): Correct looping structure.
+ (ssa_redirect_edge): Similarly
+
+2004-03-30 Brian Booth <bbooth@redhat.com>
+
+ * tree-pretty-print.c (dump_vops): Add flags argument and
+ propagate it to dump_generic_node calls.
+ (dump_generic_node): Update dump_vops call.
+
+2004-03-29 Diego Novillo <dnovillo@redhat.com>
+
+ * configure.ac: Emit confirmation messages for libbanshee.
+ * configure: Regenerate.
+
+2004-03-29 Jan Hubicka <jh@suse.cz>
+
+ PR 14756
+ * cgraphunit.c (cgraph_decide_inlining): Rewrite handling of
+ always_inline functions.
+
+2004-03-28 Jan Hubicka <jh@suse.cz>
+
+ * tree-inline.c (expand_call_inline): Remove fixme introduced by
+ nested function patch.
+
+2004-03-26 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa-operands.c (get_stmt_operands): Remove always-true
+ predicate.
+
+ * tree-ssa-alias.c (maybe_create_global_var): Create
+ .GLOBAL_VAR if there are no call-clobbered variables.
+ * tree-ssa-operands.c (get_stmt_operands): Add call-clobbering
+ VDEFs for asm ("":::"memory") if there are call-clobbered
+ variables or if .GLOBAL_VAR has been created.
+
+
+2004-03-26 Diego Novillo <dnovillo@redhat.com>
+
+ * passes.c (rest_of_compilation): Re-enable .01.rtl
+ dumps.
+
+2004-03-25 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-pretty-print.c (dump_generic_node) <WITH_RECORD_EXPR>: Remove.
+ * tree-inline.c (estimate_num_insns_1) <WITH_RECORD_EXPR>: Remove.
+ * fold-const.c (fold_relational_hi_lo): Change type of argument
+ 'type_p' to const tree and rename it to 'type'. Update
+ all callers.
+
+2004-03-25 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (C_AND_OBJC_OBJS): Remove c-call-graph.o
+ (c-call-graph.o): Remove.
+ * c-call-graph.c: Remove.
+ * c-tree.h (print_call_graph): Remove.
+ (debug_call_graph): Remove.
+ * tree-cfg.c: Update/add comments everywhere.
+ (pre_insert_on_edge): Rename from bsi_insert_on_edge_immediate.
+ * tree-flow.h (build_tree_cfg): Make static.
+ (tree_cfg2dot): Likewise.
+ (verify_stmt): Likewise.
+ * tree-ssa-pre.c (insert_one_operand): Call pre_insert_on_edge.
+
+2004-03-25 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa-alias.c (struct alias_info): Change type of field
+ 'num_references' to varray_type. Update all users.
+
+2004-03-24 Jeff Law <law@redhat.com>
+
+ * c-mudflap (mflang_flush_calls): Use push_scope/pop_scope instead
+ of pushlevel and poplevel.
+
+2004-03-23 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/14694
+ * c-common.c (handle_alias_attribute): Mark aliased variables
+ to be TREE_STATIC.
+
+2004-03-23 Jeff Law <law@redhat.com>
+
+ * tree-into-ssa.c (register_new_def): Lose unnecessary VAR argument,
+ instead derive VAR from DEF argument.
+ (rewrite_initialize_block, rewrite_stmt, rewrite_operand): Corresponding
+ changes.
+ * tree-ssa-dom.c (register_definitions_for_stmt): Corresponding changes.
+ (record_equivalences_from_phis): Likewise.
+ (restore_currdefs_to_original_value): New, extracted from ...
+ (dom_opt_finalize_block): Use restore_currdefs_to_original_value.
+ Restore currdefs after threading across a true edge.
+ (thread_across_edge): Register new defintions when we walk through
+ a PHI node or real statement.
+ * tree-flow.h (register_new_def): Updated.
+
+2004-03-23 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-ssa-dce.c (find_obviously_necessary_stmts,
+ perform_tree_ssa_dce): Do not remove loops.
+
+2004-03-19 Diego Novillo <dnovillo@redhat.com>
+
+ PR optimization/14643
+ * tree-ssa-alias.c (group_aliases_into): Don't add a variable
+ to its own may-alias set.
+ (create_alias_map_for): New.
+ (setup_pointers_and_addressables): Call it.
+ Fix allocation of AI->ADDRESSABLE_VARS and AI->POINTERS.
+ If there are no addressable variables and more than one
+ dereferenced pointers, add type tags to the ADDRESSABLE_VARS
+ array.
+ (get_tmt_for): Add comment about using alias set equality when
+ checking for existing tags.
+
+2004-03-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * fold-const.c (fold_relational_const): Remove dead code.
+
+2004-03-19 Dale Johannesen <dalej@apple.com>
+
+ * tree-ssa-dse.c (dse_optimize_stmt): Redirect uses feeding into
+ a deleted store correctly.
+
+2004-03-19 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (simplify_rhs_and_lookup_avail_expr): Fix typo.
+ Eliminate unnecessary test of VAL.
+
+ * tree-dfa.c (find_hidden_use_vars): Also look inside the
+ PENDING_SIZES list for hidden uses.
+ * tree-optimize.c (tree_rest_of_compilation): Expand used variables
+ before setting up parameters.
+ * tree-ssa-copyrename.c (rename_ssa_copies): Do nothing for copies
+ where the LHS has a hidden use.
+
+2004-03-18 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (TREE_FLOW_H): Reformat.
+ (OBJS-common): Add tree-into-ssa.o and tree-outof-ssa.o.
+ (tree-ssa.o): Remove dependency on domwalk.h and tree-ssa-live.h
+ (tree-into-ssa.o): New.
+ (tree-outof-ssa.o): New.
+ (GTFILES): Remove tree-ssa.c.
+ (gt-tree-ssa.h): Remove.
+ * tree-into-ssa.c: New file.
+ Move all the functions used to rename into SSA from tree-ssa.c.
+ Update/add comments.
+ Remove unused variables and structures.
+ Don't use GGC for memory allocation.
+ * tree-outof-ssa.c: New file.
+ Move all the functions used to rename out of SSA from
+ tree-ssa.c.
+ Update/add comments.
+ * tree-ssa-alias.c (compute_points_to_and_addr_escape): Add
+ bibliographic reference.
+
+2004-03-18 Jeff Law <law@redhat.com>
+
+ * Makefile.in (tree-tailcall.o): Depend on langhooks.h.
+ * tree-tailcall.c: Include langhooks.h.
+ (find_tail_calls): Use types_compatible_p langhook instead of
+ equality test of TYPE_MAIN_VARIANT.
+
+ * tree-nested.c (get_chain_decl): Mark the chain decl with
+ TREE_NO_WARNING.
+
+2004-03-18 Devang Patel <dpatel@apple.com>
+
+ * tree-ssa-live.c (new_tree_live_info): Set num_blocks to
+ last_basic_block instead of n_basic_blocks.
+ (calculate_live_on_entry): Use last_basic_block instead of
+ n_basic_blocks.
+ (calculate_live_on_exit): Same.
+
+2004-03-17 Jeff Law <law@redhat.com>
+
+ * tree-tailcall.c (find_tail_calls): Tighten test for tail recursion.
+
+2004-03-17 Diego Novillo <dnovillo@redhat.com>
+
+ PR optimization/14511
+ * tree-ssa-alias.c (compute_flow_insensitive_aliasing): Do not
+ ignore read-only variables.
+ (may_alias_p): Fix pointer-to-var calculation when 'var' is an
+ array.
+
+2004-03-17 Jan Hubicka <jh@suse.cz>
+
+ * tree-ssa.c (rewrite_into_ssa, compute_global_livein): Fix.
+
+2004-03-17 Paolo Bonzini <bonzini@gnu.org>
+
+ * builtins.c (expand_builtin_constant_p,
+ purge_builtin_constant_p): Remove.
+ (expand_builtin): Expand __builtin_constant_p to zero.
+ * function.c (struct function): Remove calls_constant_p.
+ (current_function_calls_constant_p): Remove.
+ * passes.c (rest_of_handle_gcse): Do not run
+ purge_builtin_constant_p.
+ * rtl.def (CONSTANT_P_RTX): Die die die.
+
+ * cse.c (fold_rtx): Do not handle CONSTANT_P_RTX.
+ * expr.c (emit_move_insn): Likewise.
+ * gcse.c (want_to_gcse_p, gcse_constant_p): Likewise.
+ * genrecog.c (validate_pattern): Likewise.
+ * recog.c (immediate_operand): Likewise.
+ * rtl.h (CONSTANT_P): Likewise.
+ * simplify-rtx.c (simplify_rtx): Likewise.
+ * config/alpha/alpha.c (input_operand): Likewise.
+ * config/arm/arm.c (THUMB_LEGITIMATE_CONSTANT_P): Likewise.
+ * config/c4x/c4x.c (const_operand): Likewise.
+ * config/cris/cris.c (cris_gotless_symbol,
+ cris_got_symbol): Likewise.
+ * config/frv/frv.h (LEGITIMATE_PIC_OPERAND_P): Likewise.
+ * config/ia64/ia64.c (gr_reg_or_5bit_operand,
+ gr_reg_or_6bit_operand, gr_reg_or_8bit_operand,
+ gr_reg_or_8bit_adjusted_operand,
+ gr_reg_or_8bit_and_adjusted_operand,
+ gr_reg_or_14bit_operand, gr_reg_or_22bit_operand,
+ shift_count_operand, shift_32bit_count_operand): Likewise.
+ * config/m32r/m32r.c (move_src_operand): Likewise.
+ * config/mips/mips.c (mips_const_insns): Likewise.
+ * config/mmix/mmix.c (mmix_constant_address_p): Likewise.
+ * config/pa/pa.c (move_src_operand): Likewise.
+ * config/rs6000/rs6000.c (input_operand): Likewise.
+ * config/sparc/sparc.c (input_operand): Likewise.
+ * config/v850/v850.c (movsi_source_operand): Likewise.
+ * config/xtensa/xtensa.c (move_operand,
+ xtensa_emit_move_sequence): Likewise.
+ * config/ia64/ia64.h (PREDICATE_CODES): Do not mention CONSTANT_P_RTX.
+ * config/pa/pa.h (PREDICATE_CODES): Likewise.
+
+2004-03-16 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dump.c (struct dump_option_value_info): Add TDF_UID.
+ * tree.h (TDF_UID): Define.
+ * doc/invoke.texi: Document -ftree-dump-...-uid.
+ * tree-pretty-print.c (debug_generic_expr): Add TDF_UID.
+ (debug_generic_stmt): Likewise.
+ (dump_decl_name): New function.
+ (dump_generic_node): Call it.
+ (print_declaration): Add new argument 'flags'. Update all users.
+ (print_struct_decl): Likewise.
+ * tree-alias-ander.c, tree-cfg.c, tree-dfa.c, tree-mudflap.c,
+ tree-nrv.c, tree-sra.c, tree-ssa-alias.c, tree-ssa-ccp.c,
+ tree-ssa-copy.c, tree-ssa-dom.c, tree-ssa-dse.c,
+ tree-ssa-forwprop.c, tree-ssa-operands.c, tree-ssa-pre.c,
+ tree-ssa.c, tree-tail-call.c: Call print_generic_* with
+ 'dump_flags'.
+
+2004-03-16 Dale Johannesen <dalej@apple.com>
+
+ * Makefile.in (tree-ssa-phiopt.o): add langhooks.h dependency.
+ (tree-nrv.o): Ditto.
+ (tree-ssa-copy.o): Ditto.
+ (tree-ssa-dom.o): Ditto.
+ (tree-ssa-ccp.o): Ditto.
+ * c-common.c: Add #include hashtab.h.
+ (c_type_hash): New.
+ (c_common_get_alias_set): Handle multiple type nodes referring
+ to "the same" type, currently for C90 only.
+ * c-decl.c (current_file_decl): Move to toplev.c.
+ * c-lang.c (LANG_HOOKS_TYPES_COMPATIBLE_P): Define to
+ c_types_compatible_p.
+ (c_types_compatible_p): New.
+ * c-tree.h (c_types_compatible_p): New declaration.
+ * c-typeck.c (tagged_types_tu_compatible_p): Allow for
+ compiler-generated TYPE_DECLs without a DECL_ORIGINAL_TYPE.
+ * gimplify.c (canonicalize_addr_expr): Use types_compatible_p langhook.
+ (cpt_same_type): Ditto.
+ * langhooks-def.h (lhd_types_compatible_p): New declaration.
+ LANG_HOOKS_TYPES_COMPATIBLE_P: New.
+ * langhooks.c (lhd_types_compatible_p): New.
+ * langhooks.h (struct lang_hooks): Add types_compatible_p.
+ * stmt.c (tail_recursion_args): Use types_compatible_p langhook.
+ * toplev.c (current_file_decl): New, moved from c-decl.c.
+ * tree-nrv.c: Include langhooks.h.
+ (tree_nrv): Use types_compatible_p langhook.
+ * tree-ssa-ccp.c: Include langhooks.h.
+ (maybe_fold_offset_to_array_ref): Use types_compatible_p langhook.
+ (maybe_fold_offset_to_component_ref): Ditto (2 places).
+ (fold_stmt_r): Make sure rhs of COMPONENT_REF is in lhs type.
+ * tree-ssa-copy.c: Include langhooks.h.
+ (cprop_into_stmt): Use types_compatible_p langhook.
+ * tree-ssa-dom.c: Include langhooks.h.
+ (avail_expr_p): Use types_compatible_p langhook.
+ * tree-ssa-phiopt.c: Include langhooks.h.
+ (conditional_replacement): Use types_compatible_p langhook.
+ * tree-ssa.c (tree_ssa_useless_type_conversion_1): Use
+ types_compatible_p langhook.
+ * tree.h (current_file_decl): New declaration.
+
+2004-03-16 Dale Johannesen <dalej@apple.com>
+
+ PR optimization/14498
+ * gimplify.c (copy_if_shared_r): Mark VA_ARGS_EXPRs as volatile.
+ (mark_decls_volatile_r): Moved higher in file (unchanged).
+
+2004-03-16 Daniel Berlin <dberlin@dberlin.org>
+
+ PR optimization/14562
+ * tree-ssa-pre.c (generate_expr_as_of_bb): Don't use names_match_p.
+ (generate_vops_as_of_bb): Ditto.
+
+2004-03-12 Diego Novillo <dnovillo@redhat.com>
+
+ PR optimization/14553
+ * tree-ssa.c (replace_immediate_uses): Call propagate_value to
+ update operands.
+
+2004-03-12 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-alias-common.c (create_alias_vars): Add #if
+ HAVE_BANSHEE around test for PTA_ANDERSEN.
+
+2004-03-11 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (struct walk_state): Remove fields 'is_store' and
+ 'is_indirect_ref'. Update all users.
+ * tree-flow.h (struct var_ann_d): Remove fields 'is_stored',
+ 'is_dereferenced_store' and 'is_dereferenced_load'. Update
+ all users.
+ * tree-simple.c (get_base_address): Handle BIT_FIELD_REF.
+ * tree-ssa-alias.c (struct alias_info): Add fields
+ 'written_vars', 'dereferenced_ptrs_store' and
+ 'dereferenced_ptrs_load'.
+ (init_alias_info): Initialize them.
+ (delete_alias_info): Free them.
+ (find_ptr_dereference): New.
+ (ptr_is_dereferenced_by): Call it.
+ Add new argument 'is_store'. Set to true if the
+ expression is an indirect store operation.
+ (compute_points_to_and_addr_escape): If the statement
+ makes a store, load or write operation, update the
+ corresponding bitmap.
+ (compute_flow_insensitive_aliasing): Test the
+ 'written_vars' bitmap to determine if alias sets should
+ be computed.
+ (setup_pointers_and_addressables): Always assume that
+ volatile pointers and hidden pointers have been used in a
+ memory store operation.
+ * tree-ssa-operands.c (add_stmt_operand): Do add an
+ operand for may-aliased variables before computing
+ aliases.
+
+2004-03-11 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-optimize.c (init_tree_optimization_passes): Move
+ pass_tail_recursion and pass_ch after pass_may_alias.
+ * tree-ssa-loop.c (mark_defs_for_rewrite): Mark type tags
+ for rewriting.
+ * tree-ssa.c (mark_def_sites): Process the operand of a
+ VDEF before the result.
+
+2004-03-11 Richard Henderson <rth@redhat.com>
+
+ PR 14204
+ * tree-ssa.c (warn_uninit): Don't warn for hard register variables.
+
+2004-03-10 Richard Henderson <rth@redhat.com>
+
+ * tree-simple.c (get_base_var, get_base_decl): Remove.
+ * tree-simple.h: Likewise.
+ * tree-dfa.c (discover_nonconstant_array_refs_r): Use get_base_address.
+ * tree-ssa-alias.c (ptr_is_dereferenced_by): Likewise.
+ (add_pointed_to_var, is_escape_site): Likewise.
+ * tree-ssa-ccp.c (get_default_value): Expect only SSA_NAME and DECLs.
+ * tree-ssa-operands.c (add_stmt_operand): Likewise.
+ (note_addressable): Use get_base_address.
+ * tree-ssa-dce.c (need_to_preserve_store): Expect only SSA_NAME.
+ * tree-ssa.c (set_is_used): Inline get_base_decl.
+
+2004-03-10 Richard Henderson <rth@redhat.com>
+
+ * tree-nested.c (convert_nonlocal_reference): Clear TREE_INVARIANT
+ on modified ADDR_EXPRs.
+
+2004-03-10 Andrew Pinski <apinski@apple.com
+
+ PR c/14475
+ * c-decl.c (check_bitfield_type_and_width): Check for null
+ lang_type_specific when check the precision of an enum.
+
+2004-03-09 Andrew Pinski <apinski@apple.com>
+
+ * Makefile.in (tree-ssa-forwprop.o): Fix the dependences.
+
+2004-03-09 Jeff Law <law@redhat.com>
+
+ * tree-flow-inline.h (may_propagate_copy): Do not allow propagation of
+ a constant for a virtual operand.
+
+2004-03-08 Richard Henderson <rth@redhat.com>
+
+ * calls.c (initialize_argument_information): Add
+ parameter may_tail_call. Set to false for invisible
+ pass-by-reference arguments that require stack
+ allocation.
+ Update all users.
+
+2004-03-07 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c: (get_eq_expr_value): Fix typo when comparing a
+ boolean against a constant.
+ * tree-ssa-forwprop.c (record_single_argument_cond_exprs): Do not
+ record the same SSA_NAME more than once. Only record the SSA_NAME
+ tested, not the COND_EXPR.
+ (substitute_single_use_vars): Substitute booleans which are
+ set from a TRUTH_NOT_EXPR even if they have more than one use site.
+
+2004-03-05 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dce.c (remove_dead_stmt): Clear PENDING_STMT after
+ redirect_edge_and_branch call.
+
+ * tree-ssa-forwprop.c (record_single_argument_cond_exprs): Also
+ record COND_EXPRs with single use vars defined by SSA_NAME + CONST
+ expressions.
+ (substitute_single_use_vars): Corresponding changes to rewrite
+ COND_EXPRs using single use vars defined by SSA_NAME + CONST
+ expressions.
+
+2004-03-05 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_expand_movstr): Do not use
+ expand_exit_loop_top_cond, manually copy loop header.
+ (s390_expand_clrstr): Likewise.
+ (s390_expand_cmpmem): Likewise.
+
+2004-03-04 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa-alias.c (compute_flow_sensitive_aliasing): If
+ a name tag has been marked call-clobbered, also mark the
+ corresponding type tag.
+
+2004-03-04 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-ssa-loop-live.c (coalesce_tpa_members): Update the root
+ variable of the partition.
+
+2004-03-04 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dce.c (remove_dead_stmt): Redirect an existing edge
+ rather than deleting the old ones and creating a new one when
+ removing a dead conditional.
+
+ * fold-const.c (fold): When rebuilding the expression after a
+ call to fold_relational_hi_lo, make sure to convert the type of
+ the second argument to the type of the first.
+
+2004-03-04 Diego Novillo <dnovillo@redhat.com>
+
+ * cgraphunit.c (cgraph_optimize): Do not do memory release
+ check if there have been errors.
+
+2004-03-03 Jeff Law <law@redhat.com>
+
+ * tree-ssa-phiopt.c (conditional_replacement): Clear EDGE_TRUE_VALUE
+ and EDGE_FALSE_VALUE on the remaining edge after eliminating a PHI.
+
+2004-03-03 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-ssa-copyrename.c (gate_copyrename): Really check it in.
+ * tree-ssa.c (create_temp): Use DECL_ARTIFICIAL from original decl.
+
+2004-03-02 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-tailcall.c (struct tailcall): Remove return_block and return_bsi
+ fields, add m and a fields.
+ (m_acc, a_acc): New.
+ (find_tail_calls): Find tail calls on whose results simple operations
+ are performed.
+ (independent_on_stmt_p, process_assignment,
+ propagate_through_phis, adjust_accumulator_values,
+ adjust_return_value): New.
+ (eliminate_tail_call): Update the accumulators if needed.
+ (optimize_tail_call): Do not create phis.
+ (tree_optimize_tail_calls): Create phis and accumulators as needed.
+ Adjust return values.
+
+2004-03-02 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa-operands.c (get_expr_operands): Mark CALL_EXPRs
+ with has_volatile_ops if aliases haven't been computed yet.
+ (add_stmt_operand): Use 'true' instead of '1'.
+
+2004-03-02 Diego Novillo <dnovillo@redhat.com>
+
+ PR optimization/14266
+ * tree-ssa-alias.c (create_global_var): Mark GLOBAL_VAR for
+ renaming.
+
+2004-03-01 Richard Henderson <rth@redhat.com>
+
+ * tree.c (associative_tree_code): Remove MINUS_EXPR, LSHIFT_EXPR,
+ RSHIFT_EXPR.
+ * tree-ssa-dom.c (simplify_rhs_and_lookup_avail_expr): Use
+ is_gimple_min_invariant and is_gimple_var. Handle minus_expr
+ specially.
+
+2004-03-01 Richard Henderson <rth@redhat.com>
+
+ * cfgbuild.c (rtl_make_eh_edge): Rename from make_eh_edge.
+ * basic-block.h, except.c: Update decl and uses.
+
+2004-03-01 Frank Ch. Eigler <fche@redhat.com>
+
+ * doc/passes.texi: Add information about mudflap.
+
+2004-03-01 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR middle-end/13066
+ * fold-const (fold): Call fold_convert when building
+ a TRUTH_*_EXPR tree.
+
+2004-03-01 Andrew MacLeod <amacleod@redhat.com>
+
+ * common.opt : Add tree-copyrename option. Remove duplicate tree-sra.
+ * flags.h (flag_tree_copyrename): Declare.
+ * opts.c (decode_options): Turn copyrename on by default at -O.
+ (common_handle_option): Handle -ftree-copyrename.
+ * toplev.c (flag_tree_copyrename): Declare.
+ * tree-ssa-copyrename.c (gate_copyrename): New. Check flag.
+ (pass_rename_ssa_copies): Initialize with gated routine.
+ (lang_independent_options f_): Add tree-copyrename.
+ * doc/invoke.texi: Add -fdump-tree-copyrename and -ftree-copyrename.
+ * doc/passes.texi: Add blurb for copy renaming.
+
+2004-03-01 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (true_false_expr_hash): Update comments slightly.
+ (true_false_expr_eq): Update comments slightly. Avoid using
+ operand_equal_p, instead check the code and operands directly.
+
+2004-03-01 Andrew MacLeod <amacleod@redhat.com>
+
+ * Makefile.in (tree-ssa-copyrename.o): New object.
+ * timevar.def (TV_TREE_COPY_RENAME): New time variable.
+ * tree-optimize.c (init_tree_optimization_passes): Add copy rename
+ pass.
+ * tree-pass.h (pass_rename_ssa_copies): New pass structure.
+ * tree-sra.c (lookup_scalar): Copy DECL_ARITIFICIAL flag from base.
+ * tree-ssa-copyrename.c : New file.
+ (copy_rename_partition_coalesce): Coalesce partitions for renaming.
+ (rename_ssa_copies): Find renamable copies.
+ (pass_rename_ssa_copies): Initialize.
+ * tree-ssa-live.c (register_ssa_partition): Move to tree-ssa-live.h.
+ * tree-ssa-live.h (register_ssa_partition): Moved from tree-ssa-live.c.
+
+2004-02-29 David Edelsohn <edelsohn@gnu.org>
+
+ * doloop.c (doloop_optimize): Increment n_iterations if loop->top
+ present.
+
+2004-02-29 Diego Novillo <dnovillo@redhat.com>
+
+ * gimple-low.c (pass_remove_useless_vars): Add TODO_dump_func.
+
+2004-02-27 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/14310
+ * explow.c (emit_stack_save): Remove savearea mode check.
+
+2004-02-27 Richard Henderson <rth@redhat.com>
+
+ * builtins.c (simplify_builtin_strcmp): Don't export. Remove
+ length parameters. Remove conversion to memcmp.
+ (simplify_builtin_strncmp): Likewise.
+ * expr.h: Don't declare them.
+ * tree-ssa-ccp.c (ccp_fold_builtin): Don't call them.
+
+2004-02-27 Dale Johannesen <dalej@apple.com>
+
+ * tree-cfg.c (cleanup_control_expr_graph): Prevent edge
+ probability from overflowing due to roundoff errors.
+
+2004-02-27 Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (verify_expr): Do not walk down into types.
+ Expand checking to verify that unary/binary operators have
+ gimple operands.
+ * tree-ssa-ccp.c (ccp_fold_builtin, case BUILT_IN_STRLEN): Do not
+ create non-gimple code. Similarly for BUILTIN_IN_STRCPY and
+ BUILT_IN_STRNCPY.
+ * tree-ssa-phiopt.c (conditional_replacement): Do not create
+ non-gimple code.
+ * tree-ssa-dom.c (simplify_rhs_and_lookup_avail_expr): Likewise.
+
+ * tree-simple.c (is_gimple_min_invariant): Subtraction of a
+ constant from a constant pointer is a gimple invariant as well.
+ * tree-ssa-operands.c (get_expr_operands): Handle subtraction
+ of a constant from a constant pointer too.
+
+ * fold-const.c (fold): Tighten test for optimizing an equality
+ comparison of the address of two variables.
+
+ * tree-inline.c (setup_one_parameter): Improve test for when we
+ need to gimplify the initialization statements.
+
+2004-02-27 Diego Novillo <dnovillo@redhat.com>
+
+ PR optimization/14312
+ * tree-pretty-print.c (dump_generic_node): Mark tail calls.
+ * tree-ssa-alias.c (compute_may_aliases): Restore call to
+ dump_referenced_vars.
+ (compute_points_to_and_addr_escape): If the address of a
+ variable V is stored into a non-pointer variable, mark V as
+ call-clobbered.
+ * tree-tailcall.c (suitable_for_tail_opt_p): Check for
+ call-clobbered instead of TREE_ADDRESSABLE.
+ Ignore memory tags.
+ (optimize_tail_call): Add newline to dump output.
+
+2004-02-27 Diego Novillo <dnovillo@redhat.com>
+
+ PR optimization/13347
+ * tree-sra.c (scalarize_structure_assignment): Use STRIP_NOPS
+ instead of STRIP_USELESS_TYPE_CONVERSION to remove type casts
+ from RHS of the assignment.
+
+ * tree-ssa.c (tree_ssa_useless_type_conversion_1): Reformat
+ and rephrase comments.
+ * tree.h (STRIP_USELESS_TYPE_CONVERSION): Reformat comment.
+
+2004-02-26 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-cfg.c (tree_redirect_edge_and_branch_1): Allow to redirect
+ RETURN_EXPR branches.
+
+2004-02-26 Jeff Law <law@redhat.com>
+
+ * tree-nrv.c (tree_nrv): Only perform NRV optimization when the
+ return value lives in memory.
+
+ * tree-ssa-dom.c (simplify_rhs_and_lookup_avail_expr): If an
+ operand is unsigned, then we can eliminate more ABS expressions
+ and turned div/mod expression into shift/and expressions.
+
+ * fold-const.c (fold): An equality comparison of the address of
+ two non-weak variables has known compile-time result.
+
+2004-02-26 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * tree-ssa-phiopt.c (conditional_replacement):
+ s/tree_dump_flags/dump_flags/.
+
+ * tree-ssa-phiopt.c (tree_ssa_phiopt): Split into ...
+ (conditional_replacement): Here.
+
+2004-02-26 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-ssa.c (find_replaceable_in_bb): Don't repalce expressions in
+ volatile statements.
+
+2004-02-25 Richard Henderson <rth@redhat.com>
+
+ PR opt/14288
+ * gimplify.c (gimple_push_cleanup): Add VAR argument. Set
+ TREE_NO_WARNING if in a conditional context.
+ (gimplify_target_expr): Pass new argument.
+ * tree-sra.c (lookup_scalar): Copy TREE_NO_WARNING to replacement.
+
+2004-02-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/invoke.texi: Replace -fdump-tree-all-ssa with
+ -fdump-tree-all.
+
+2004-02-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR target/14285
+ * config/arm/arm.c (arm_compute_func_type): Replace
+ "current_function_needs_context" with "cfun->static_chain_decl
+ != NULL".
+ (arm_compute_initial_elimination_offset): Likewise.
+ * config/h8300/h8300.c (h8300_emit_stack_adjustment):
+ Likewise.
+ * config/sh/sh.c (output_stack_adjust): Likewise.
+ (sh5_schedule_saves): Likewise.
+ * config/xtensa/xtensa.c (compute_frame_size): Likewise.
+
+2004-02-24 Richard Henderson <rth@redhat.com>
+
+ * c-simplify.c (c_genericize): s/dump_flags/local_dump_flags/.
+ * predict.c, tree-alias-ander.c, tree-cfg.c, tree-nrv.c,
+ tree-optimize.c, tree-pass.h, tree-sra.c, tree-ssa-alias.c,
+ tree-ssa-ccp.c, tree-ssa-copy.c, tree-ssa-dce.c, tree-ssa-dom.c,
+ tree-ssa-dse.c, tree-ssa-forwprop.c, tree-ssa-loop.c,
+ tree-ssa-phiopt.c, tree-ssa-pre.c, tree-ssa.c, tree-tailcall.c:
+ s/tree_dump_flags/dump_flags/.
+
+2004-02-24 Richard Henderson <rth@redhat.com>
+
+ * predict.c, tree-alias-ander.c, tree-cfg.c, tree-mudflap.c,
+ tree-nrv.c, tree-optimize.c, tree-pass.h, tree-profile.c, tree-sra.c,
+ tree-ssa-alias.c, tree-ssa-ccp.c, tree-ssa-copy.c, tree-ssa-dce.c,
+ tree-ssa-dom.c, tree-ssa-dse.c, tree-ssa-forwprop.c, tree-ssa-loop.c,
+ tree-ssa-operands.c, tree-ssa-phiopt.c, tree-ssa-pre.c, tree-ssa.c,
+ tree-tailcall.c: s/tree_dump_file/dump_file/g.
+
+2004-02-24 Diego Novillo <dnovillo@redhat.com>
+
+ * doc/tree-ssa.texi: Fix formatting mark ups.
+
+2004-02-24 Jeff Law <law@redhat.com>
+
+ * gimple-low.c (remove_useless_vars): Now static.
+ (pass_remove_useless_vars): New.
+ * tree-flow.h (remove_useless_vars): Remove prototype.
+ * tree-nrv.c (struct nrv_data): Remove visited hashtable.
+ (finalize_nrv_r): Do not descend into types. No need to update
+ the visited hashtable.
+ (tree_nrv): No need to allocate/free the visited hashtable.
+ Clear the used flag on the variable's annotation.
+ * tree-optimize.c (init_tree_optimizatio_passes): Link in
+ pass_remove_useless_vars.
+ * tree-pass.h (pass_remove_useless_vars): Declare.
+ * tree-ssa.c (rewrite_out_of_ssa): Do not remove useless vars here.
+
+ * Makefile.in (OBJS-common): Add tree-nrv.o.
+ (tree-nrv.o): Add dependencies.
+ * timevar.def (TV_TREE_NRV): New timevar.
+ * tree-nrv.c: New file implementing NRV on generic trees.
+ * tree-optimize.c (init_tree_optimization_passes): Link in
+ tree_nrv optimization pass.
+ * tree-pass.h (tree_nrv): Declare.
+ * doc/invoke.texi: Add -fdump-tree-nrv documentation.
+
+2004-02-24 Sebastian Pop <sebastian.pop@cri.ensmp.fr>
+
+ * tree-flow.h (walk_use_def_chains_fn): Return a boolean.
+ True for stopping the use-def walk, false otherwise.
+ * tree-ssa-alias.c (collect_points_to_info_r): Same.
+ Always return false, and never stopping the def-use walk as before.
+ * tree-ssa.c (walk_use_def_chains_1): Stop when the result of the
+ callback function is true.
+ * doc/tree-ssa.texi: Document the behavior of the callback
+ function for walk_use_def_chains.
+
+2004-02-24 Richard Henderson <rth@redhat.com>
+
+ * doc/passes.texi: Rewrite.
+
+2004-02-23 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (TEXI_GCCINT_FILES): Add cfg.texi and tree-ssa.texi
+ * tree-ssa-alias.c (compute_may_aliases): Update documentation.
+ * doc/gccint.texi: Add node for Tree SSA documentation.
+ Include tree-ssa.texi.
+ * doc/tree-ssa.texi: New file.
+
+2004-02-23 Dale Johannesen <dalej@apple.com>
+
+ * config/rs6000/rs6000.md: Roll in changes from mainline:
+ (movdf_softfloat64): Add POWER form of nop.
+ (movsf_hardfloat): Ditto, and accept CTR-to-CTR copy.
+ (movdf_hardfloat64): Ditto.
+
+2004-02-23 Jeff Law <law@redhat.com>
+
+ * ggc-page.c (struct page_entry): New field PREV.
+ (ggc_alloc): Update PREV field appropriately.
+ (sweep_pages): Likewise.
+ (ggc_free): Likewise. Use PREV field rather than loop to
+ improve ggc_free performance.
+
+ * Makefile.in (OBJC-common): Add tree-ssa-copy.o.
+ (tree-ssa-copy.o): Add dependencies.
+ * tree-flow.h (propagate_value, replace_exp): Prototype.
+ (cprop_into_stmt, cprop_into_successor_phis): Likewise.
+ * tree-ssa-copy.c: New file, most functions copied from tree-ssa-dom.c
+ (cprop_into_stmt): Handle pointer & reference types better.
+ * tree-ssa-dom.c (opt_stats_d): Kill uninteresting stats.
+ (dump_dominator_optimization_stats): Corresponding changes.
+ (cprop_into_stmt): Moved into tree-ssa-copy.c.
+ (propagate_value): Likewise.
+ (cprop_into_phis): Simplify using code fromi tree-ssa-copy.c.
+ (optimize_stmt): Pass additional argument to cprop_into_stmt.
+ * tree-ssa-pre.c (generate_expr_as_of_bb): Use replace_exp.
+ (generate_vops_as_of_bb): Similarly.
+
+2004-02-21 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (decide_is_function_needed): Nested functions of extern
+ inline functions don't need to be output.
+ (expand_function): Re-enable sanity check.
+
+2004-02-21 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-ssa-loop.c (do_while_loop_p): New function.
+ (copy_loop_headers): Do not peel do-while loops.
+
+2004-02-21 Jan Hubicka <jh@suse.cz>
+
+ * tree-cfg.c (cleanup_control_expr_graph): Update profile.
+
+ * tree-cfg.c (disband_implicit_edges): Set fallthru edges correctly.
+
+ * cfg.c (dump_flow_info): Work on trees too.
+
+ * tree-pretty-print.c (dump_generic_bb_stuff): Do not touch bb
+ annotations when not allocated.
+
+2004-02-21 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (cprop_into_stmt): Look at the type's main variant
+ to determine if the two operands of a copy have equivalent types.
+
+2004-02-20 Jeff Law <law@redhat.com>
+
+ * tree-flow-inline.h (may_propagate_copy): Do not perform ABNORMAL_PHI
+ and DECL_HARD_REGISTER tests on virtual operands.
+ * tree-flow.h (propagate_copy): Kill prototype.
+ (propagate_value): New prototype.
+ * tree-ssa-dom.c (propagate_copy): Now static.
+ (propagate_value): No longer static.
+
+2004-02-20 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/14218
+ * c-simplify.c (mark_labels_r): Move to ...
+ * gimplify.c (force_labels_r): ... here, and rename.
+ (gimplify_init_constructor): Invoke it.
+ * tree-simple.h (force_labels_r): Declare.
+
+2004-02-20 Richard Henderson <rth@redhat.com>
+
+ PR opt/14194
+ * tree-ssa-ccp.c (substitute_and_fold): Also mark new vars
+ if fold_stmt was successful.
+
+2004-02-20 Diego Novillo <dnovillo@redhat.com>
+
+ * doc/invoke.texi: Add documentation for parameters
+ global-var-threshold and max-aliased-vops.
+ * params.def (PARAM_GLOBAL_VAR_THRESHOLD): Reformat help message.
+ (PARAM_MAX_ALIASED_VOPS): Rename from PARAM_MAX_ALIAS_SET_SIZE.
+ * params.h (MAX_ALIASED_VOPS): Rename from MAX_ALIAS_SET_SIZE.
+ Update all users.
+ * tree-ssa-alias.c (struct alias_map_d): Document fields.
+ Add fields total_alias_vops, grouped_p and may_aliases.
+ (struct alias_info): Change fields addressable_vars and
+ pointers to malloc'd arrays. Update all users.
+ Add fields num_references and total_alias_vops.
+ (compute_may_aliases): Add more comments.
+ (init_alias_info): Initialize new fields in struct alias_info.
+ (delete_alias_info): Corresponding changes.
+ (compute_points_to_and_addr_escape): Count references to
+ potentially aliased variables and pointer dereferences.
+ (compute_flow_insensitive_aliasing): Remove old grouping
+ heuristic.
+ Count the number of virtual operands induced by all the alias
+ sets created and call group_aliases if the number exceeds the
+ threshold set by --param max-aliased-vops.
+ (total_alias_vops_cmp): New.
+ (group_aliases_into): New.
+ (group_aliases): New.
+ * tree-ssa-operands.c (get_expr_operands): Change dump file
+ message when no flow-sensitive alias information is available.
+ (add_stmt_operand): Reformat comment.
+ * tree-ssa.c (init_tree_ssa): Don't call bitmap_clear.
+
+ * tree-simple.c (get_base_decl): Fix typo in comment.
+
+ * tree-pretty-print.c (print_call_name): Handle matrices of
+ function pointers.
+
+2004-02-20 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * Makefile.in (tree-ssa-loop.o): Add tree-inline.h dependency.
+ * basic-block.h (struct reorder_block_def): Moved from cfglayout.h.
+ (alloc_rbi_pool, initialize_bb_rbi, free_rbi_pool): New.
+ * bb-reorder.c (copy_bb): Use cfghooks for bb duplication.
+ * cfg.c (rbi_pool): New variable.
+ (alloc_rbi_pool, free_rbi_pool, initialize_bb_rbi): New functions.
+ * cfghooks.c (can_duplicate_block_p, duplicate_block): New functions.
+ * cfghooks.h (struct cfg_hooks): Add can_duplicate_block_p and
+ duplicate_block hooks.
+ (can_duplicate_block_p, duplicate_block): Declare.
+ * cfglayout.c (cfg_layout_pool, cfg_layout_initialize_rbi): Removed.
+ (fixup_reorder_chain): Use initialize_bb_rbi.
+ (cfg_layout_can_duplicate_bb_p, cfg_layout_duplicate_bb): Hookized.
+ (cfg_layout_initialize): Use cfg.c rbi pool manipulation functions.
+ (can_copy_bbs_p, copy_bbs): Use cfghooks for bb duplication.
+ * cfglayout.h (typedef struct reorder_block_def): Moved to
+ basic_block.h.
+ (cfg_layout_can_duplicate_bb_p, cfg_layout_duplicate_bb): Declaration
+ removed.
+ * cfgrtl.c (cfg_layout_create_basic_block): Use initialize_bb_rbi.
+ (rtl_cfg_hooks, cfg_layout_rtl_cfg_hook): Fill in can_duplicate_block_p
+ and duplicate_block fields.
+ * common.opt (ftree-ch): Add.
+ * flags.h (flag_tree_ch): Declare.
+ * jump.c (next_nonnote_insn_in_loop, duplicate_loop_exit_test,
+ copy_loop_headers): Removed.
+ * loop-unswitch.c (unswitch_loop): Use cfghooks for bb duplication.
+ * opts.c (decode_options): Enable flag_tree_ch at -O1.
+ (common_handle_option): Handle -ftree_ch.
+ * rtl.h (copy_loop_headers): Declaration removed.
+ * timevar.def (TV_TREE_CH): New.
+ * toplev.c (flag_tree_ch): New.
+ (rest_of_compilation): Do not call copy_loop_headers.
+ * tracer.c (tail_duplicate): Use cfghooks for bb duplication.
+ * tree-cfg.c (build_tree_cfg): Call alloc_rbi_pool.
+ (create_bb): Call initialize_bb_rbi.
+ (delete_tree_cfg): Call free_rbi_pool.
+ (tree_duplicate_bb): Hookize.
+ (tree_can_duplicate_bb_p): New.
+ (tree_cfg_hooks): Fill in can_duplicate_block_p and duplicate_block
+ fields.
+ * tree-flow.h (tree_duplicate_bb): Declaration removed.
+ * tree-optimize.c (init_tree_optimization_passes): Add pass_ch.
+ * tree-pass.h (pass_ch): Declare.
+ * tree-ssa-loop.c: Include tree-inline.h.
+ (call_expr_p, should_duplicate_loop_header_p, mark_defs_for_rewrite,
+ duplicate_blocks, copy_loop_headers, gate_ch): New functions.
+ (pass_ch): New.
+ * doc/invoke.texi (-fdump-tree-ch, -ftree-ch): Document.
+
+2004-02-19 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/aix.h (MFWRAP_SPEC): Define.
+ (MFLIB_SPEC): Define.
+
+2004-02-19 Jeff Law <law@redhat.com>
+
+ * tree-ssa-phiopt.c (tree_ssa_phiopt): TRUTH_NOT_EXPR is valid
+ gimple code.
+
+2004-02-19 Steven Bosscher <stevenb@suse.de>
+
+ * tree-cfg.c (cleanup_dead_labels): New function to remove
+ redundant labels.
+
+ Remove the RTL inliner.
+ * calls.c (try_to_integrate): Remove.
+ (expand_call): Do not try to expand calls inline.
+ * dbxout.c (dbxout_symbol_location): Don't mention integrate.c
+ in comments.
+ * expmed.c (extract_fixed_bit_field): Always propagate the
+ target for the shift if it is a REG.
+ * expr.c (emit_move_insn_1): Don't generate inline warnings.
+ (expand_expr_real_1): Don't look at inline_function_decl.
+ Don't output inlined functions here.
+ * expr.h (expand_inline_function): Remove prototype.
+ * emit-rtl.c (copy_most_rtx): Don't copy the integrated flag.
+ Copy the new return_val flag.
+ * final.c (final): Don't look at RTX_INTEGRATED_P.
+ * cfgrtl.c (create_basic_block_structure): Likewise.
+ * haifa-sched.c (priority): Likewise.
+ (restore_line_notes): Likewise.
+ * function.c (inline_function_decl): Remove.
+ (put_var_into_stack): Don't use it.
+ (fix_lexical_addr): Likewise.
+ * function.c (inline_function_decl): Remove extern declaration.
+ * genattrtab.c (ATTR_PERMANENT_P): Use the return_val flag
+ instead of the integrated flag.
+ * integrate.c (INTEGRATE_THRESHOLD): Remove.
+ (setup_initial_hard_reg_value_integration): Likewise.
+ (initialize_for_inline): Likewise.
+ (note_modified_parmregs): Likewise.
+ (integrate_parm_decls): Likewise.
+ (process_reg_param): Likewise.
+ (save_parm_insns): Likewise.
+ (copy_insn_list): Likewise.
+ (copy_insn_notes): Likewise.
+ (compare_blocks): Likewise.
+ (find_block): Likewise.
+ (inlining): Likewise.
+ (function_cannot_inline_p): Likewise.
+ (parmdecl_map): Likewise.
+ (in_nonparam_insns): Likewise.
+ (save_for_inline): Likewise.
+ (FIXED_BASE_PLUS): Likewise.
+ (expand_inline_function): Likewise.
+ (copy_rtx_and_substitute): Don't look at map->integrating,
+ map->inline_target, and inlining, since we are never copying
+ for integrating.
+ Don't abort on RTX_INTEGRATED_P.
+ (old_fun): Remove.
+ (output_inline_function): Remove.
+ * integrate.h (struct inline_map): Remove fields integrating,
+ block_map, leaf_reg_map, inline_target, and local_return_label.
+ * print-rtl.c (print_rtx): Don't print the integrated flag.
+ Print the return_val flag.
+ * rtl.h (struct rtx_def): Replace the integrated flag with the
+ return_val flag.
+ (RTX_INTEGRATED_P): Remove.
+ (notice_rtl_inlining_of_deferred_constant): Remove prototype.
+ * stmt.c (force_label_rtx): Don't look at inline_function_decl.
+ * toplev.c (rest_of_handle_inlining): Remove.
+ (rest_of_compilation): Don't call it, and never jump to exit.
+ Call convert_from_eh_region_ranges.
+ (wrapup_global_declarations): Don't output nested inlined functions.
+ * tree.h (function_cannot_inline_p): Remove prototype.
+ (save_for_inline): Ditto.
+ (output_inline_function): Ditto.
+ * unroll.c (unroll_loop): Don't clear map->inline_target.
+ * varasm.c (notice_rtl_inlining_of_deferred_constant): Remove.
+
+ * system.h: Poison INTEGRATE_THRESHOLD.
+ * config/avr/avr.h: Remove define.
+ * config/ip2k/ip2k.h: Likewise.
+
+ * unwind-sjlj.c (uw_install_context): Make a proper static inline
+ function.
+
+ * doc/rtl.texi: Remove references to the integrated flag.
+ * doc/tm.texi: Remove documentation of INTEGRATE_THRESHOLD.
+
+2004-02-17 Andrew Macleod <amacleod@redhat.com>
+
+ * tree-ssa-live.c (coalesce_tpa_members): Don't coalesce partitions
+ which are not in the same TPA group.
+ * tree-ssa.c (rewrite_out_of_ssa): Coalesce via list first.
+
+2004-02-17 Brian Booth <bbooth@redhat.com>
+
+ * tree-ssa-ccp.c (substitute_and_fold): Update stmt after
+ calling fold_stmt.
+
+2004-02-16 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/rs6000/rs6000.c (output_function_profiler): Check
+ cfun->static_chain_decl instead of current_function_needs_context.
+
+2004-02-16 Jeff Law <law@redhat.com>
+
+ * tree-ssa.dse.c (dse_optimize_stmt): Dump info when we delete
+ stores.
+
+ * tree-ssa-dse.c: Update comments.
+
+ * Makefile.in (OBJS-common): Add tree-ssa-dse.o
+ (tree-ssa-dse.o): Add dependencies.
+ * common.opt (ftree-dse): New option.
+ * flags.h (flag_tree_dse): New.
+ (flag_tree_dom): Fix comments.
+ * opts.c (decode_options): Turn on flag_tree_dse.
+ (common_handle_option): Handle OPT_ftree_dse.
+ * timevar.def (TV_TREE_PHIOPT): Update text.
+ (TV_TREE_DSE): New timevar.
+ * toplev.c (flag_tree_dse): New.
+ (flag_tree_dom): Fix comments.
+ (lang_independent_options): Add -ftree-dse.
+ * tree-dfa.c (redirect_immediate_use): New function.
+ (redirect_immediate_uses): New function.
+ * tree-flow.h (stmt_ann_d): Add UID field.
+ (redirect_immediate_uses): Declare.
+ * tree-optimize.c (init_tree_optimization_passes): Link in DSE pass.
+ * tree-pass.h (pass_dse): Declare.
+ * tree-ssa-dse.c: New file implementing DSE.
+ * doc/invoke.texi: Document new option.
+
+2004-02-16 Richard Henderson <rth@redhat.com>
+
+ * tree-nested.c: New file.
+ * Makefile.in (OBJS-common, GTFILES, tree-nested.o): Add it.
+ * builtin-types.def (BT_FN_VOID_PTR_PTR, BT_FN_VOID_PTR_PTR_PTR): New.
+ * builtins.c (expand_builtin_nonlocal_goto): New.
+ (expand_builtin_apply): Fix prepare_call_address args.
+ (round_trampoline_addr): Move from function.c.
+ (expand_builtin_init_trampoline): New.
+ (expand_builtin_adjust_trampoline): New.
+ (expand_builtin): Invoke them.
+ (build_function_call_expr): Add CALL_EXPR chain operand.
+ * builtins.def (BUILT_IN_INIT_TRAMPOLINE,
+ BUILT_IN_ADJUST_TRAMPOLINE, BUILT_IN_NONLOCAL_GOTO): New.
+ * c-decl.c (finish_function): Call lower_nested_functions.
+ (c_expand_decl): Don't declare_nonlocal_label.
+ * calls.c (prepare_call_address): Replace fndecl arg with a
+ precomputed static chain value.
+ (expand_call): Precompute the static chain value. Use
+ update_nonlocal_goto_save_area.
+ * cgraph.c (cgraph_mark_reachable_node): Don't force nested
+ functions to be reachable.
+ (cgraph_clone_node): Don't abort cloning functions containing
+ nested functions.
+ * cgraphunit.c (cgraph_assemble_pending_functions): Don't do
+ anything special for nested functions.
+ (cgraph_mark_functions_to_output): Likewise.
+ (cgraph_estimate_growth, cgraph_clone_inlined_nodes): Likewise.
+ (cgraph_optimize): Likewise.
+ (cgraph_finalize_function): Don't zap DECL_SAVED_INSNS.
+ (cgraph_expand_function): Allow functions to not be emitted.
+ * defaults.h (TRAMPOLINE_ALIGNMENT): Move from function.c.
+ * dwarf2out.c (gen_subprogram_die): Generate DW_AT_static_link.
+ * emit-rtl.c (maybe_set_first_label_num): New.
+ * explow.c (update_nonlocal_goto_save_area): New.
+ (allocate_dynamic_stack_space): Use it.
+ * expr.c (expand_expr_real_1) <LABEL_DECL>: Don't force_label_rtx.
+ <COND_EXPR>: Ignore the possibility of non-local labels.
+ <ADDR_EXPR>: Don't do trampoline_address.
+ * expr.h (lookup_static_chain): Remove.
+ (prepare_call_address): Update 2nd arg.
+ (update_nonlocal_goto_save_area): Declare.
+ * final.c (profile_function): Update static chain test.
+ * function.c (TRAMPOLINE_ALIGNMENT): Move to defaults.h.
+ (trampolines_created): Move to varasm.c.
+ (free_after_compilation): Update for removed fields.
+ (allocate_struct_function): Likewise.
+ (delete_handlers, lookup_static_chain): Remove.
+ (fix_lexical_addr): Don't consider non-local variable refs.
+ (trampoline_address): Remove.
+ (round_trampoline_addr): Move to builtins.c.
+ (adjust_trampoline_addr): Remove.
+ (expand_function_start): Update for changes to static chain
+ and nonlocal goto handling.
+ (initial_trampoline): Move to varasm.c.
+ (expand_function_end): Don't build trampolines or kill
+ unreferenced nonlocal goto labels.
+ * function.h (struct function): Remove x_nonlocal_labels,
+ x_nonlocal_goto_handler_slots, x_nonlocal_goto_stack_level,
+ x_context_display, x_trampoline_list, needs_context.
+ Add static_chain_decl, nonlocal_goto_save_area.
+ * gimple-low.c (record_vars): Don't record functions.
+ * gimplify.c (declare_tmp_vars): Export.
+ (create_artificial_label): Set type.
+ (gimplify_expr): Don't consider nonlocal gotos.
+ * integrate.c (expand_inline_function): Kill lookup_static_chain ref.
+ * jump.c (any_uncondjump_p): Reject nonlocal goto.
+ * rtl.h (maybe_set_first_label_num): Declare.
+ * stmt.c (label_rtx): Set LABEL_PRESERVE_P appropriately.
+ (expand_label): Handle DECL_NONLOCAL and FORCED_LABEL.
+ (declare_nonlocal_label): Remove.
+ (expand_goto): Don't handle nonlocal gotos.
+ (expand_nl_handler_label): Remove.
+ (expand_nl_goto_receivers): Remove.
+ (expand_end_bindings): Don't expand_nl_goto_receivers. Use
+ update_nonlocal_goto_save_area.
+ * tree-cfg.c (make_edges): Handle abnormal edges out of block
+ falling through to EXIT.
+ (make_ctrl_stmt_edges): Don't check GOTO_EXPR for nonlocal goto.
+ Handle computed goto with no destinations.
+ (tree_can_merge_blocks_p): Don't merge blocks with nonlocal labels.
+ (remove_useless_stmts_label, stmt_starts_bb_p): Likewise.
+ (tree_forwarder_block_p): Likewise.
+ (nonlocal_goto_p): Remove.
+ (tree_verify_flow_info): Update to match.
+ * tree-dump.c (dump_files): Add tree-nested.
+ * tree-flow.h (nonlocal_goto_p): Remove.
+ * tree-inline.c (setup_one_parameter): Split out from ...
+ (initialize_inlined_parameters): ... here. Handle static chain.
+ (inline_forbidden_p_1): Update nonlocal goto check.
+ (expand_call_inline): Disable mysterious cgraph abort.
+ * tree-optimize.c (tree_rest_of_compilation): Save DECL_SAVED_INSNS.
+ * tree-pretty-print.c (dump_generic_node): Print static chain
+ and nonlocal label.
+ * tree-simple.h (declare_tmp_vars): Declare.
+ (lower_nested_functions): Declare.
+ * tree-ssa-dom.c (propagate_value): Avoid sharing problems.
+ * tree-ssa-operands.c (get_expr_operands): Walk static chain
+ field of call_expr.
+ * tree.def (CALL_EXPR): Add static chain operand.
+ * tree.h (NONLOCAL_LABEL): Remove.
+ (TDI_nested): New.
+ * varasm.c (TRAMPOLINE_ALIGNMENT): Remove.
+ (initial_trampoline): Move from function.c.
+ (assemble_trampoline_template): Set and return it.
+ (trampolines_created): Move from function.c.
+
+2004-02-16 Steven Bosscher <stevenb@suse.de>
+
+ * tree-flow.h (cleanup_control_expr_graph): Don't declare here.
+ * tree-cfg.c (cleanup_control_expr_graph): Make static.
+ (find_edge_taken_cond_expr): Return an edge if the true and false
+ edges of a branch lead to the same basic block.
+
+2004-02-13 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-phinodes.c (resize_phi_node): Do not use ggc_realloc to
+ allocate a new PHI node.
+
+2004-02-12 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-flow.h (kill_redundant_phi_nodes): Remove declaration.
+ * tree-optimize.c (init_tree_optimization_passes): Add
+ pass_redundant_phi after DOM and CCP.
+ (execute_todo): Do not call kill_redundant_phi_nodes.
+ * tree-pass.h (TODO_redundant_phi): Remove.
+ Update all users.
+ Adjust values for all the other TODO_* entries.
+ (pass_redundant_phi): Declare.
+ * tree-ssa.c (replace_immediate_uses): Call mark_new_vars_to_rename
+ if a pointer was replaced.
+ (kill_redundant_phi_nodes): Make static.
+ (pass_redundant_phi): Define.
+
+2004-02-12 Dale Johannesen <dalej@apple.com>
+
+ * Makefile.in (OBJS-common): Add rtl-profile.o, tree-profile.o.
+ (profile.o): Add tree-flow.h dependency.
+ (rtl-profile.o): New rule.
+ (tree-profile.o): New rule.
+ (GTFILES): Add tree-profile.c, rtl-profile.c.
+ * basic-block.h (flow_call_edges_add): Remove.
+ * cfganal.c (need_fake_edge_p): Move to cfgrtl.c.
+ (flow_call_edges_add): Move to cfgrtl.c.
+ * cfghooks.c: (block_ends_with_call_p): New.
+ (block_ends_with_condjump_p): New.
+ (flow_call_edges_add): New.
+ * cfghooks.h: (struct cfg_hooks): add block_ends_with_call_p,
+ block_ends_with_condjump_p, flow_call_edges_add.
+ (block_ends_with_call_p): New declaration.
+ (block_ends_with_condjump_p): New declaration.
+ (flow_call_edges_add): New declaration.
+ * cfgrtl.c (rtl_block_ends_with_call_p): New.
+ (rtl_block_ends_with_condjump_p): New.
+ (need_fake_edge_p): Moved from cfganal.c.
+ (rtl_flow_call_edges_add): Moved from cfganal.c (flow_call_edges_add).
+ (rtl_cfg_hooks): Add rtl_block_ends_with_call_p,
+ rtl_block_ends_with_condjump_p, rtl_flow_call_edges_add.
+ (cfg_layout_rtl_cfg_hooks): Ditto.
+ * common.opt (ftree-based-profiling): New.
+ * coverage.c (tree_ctr_tables): New.
+ (coverage_counter_alloc): Use it.
+ (build_ctr_info_value): Ditto.
+ (coverage_counter_ref): Ditto. Rename to rtl_coverage_counter_ref.
+ (tree_coverage_counter_ref): New.
+ * coverage.h (coverage_counter_ref): Remove declaration.
+ (rtl_coverage_counter_ref): New declaration.
+ (tree_coverage_counter_ref): New declaration.
+ * opts.c (OPT_ftree_based_profiling): New.
+ * profile.c: Include cfghooks.h, tree-flow.h.
+ (profile_hooks): New.
+ (profile_dump_file): New.
+ (instrument_edges): Use hooks instead of RTL-specific code.
+ (instrument_values): Ditto.
+ (get_exec_counts): Ditto.
+ (compute_branch_probabilities): Ditto.
+ (compute_value_histograms): Ditto.
+ (branch_prob): Ditto.
+ (find_spanning_tree): Ditto.
+ (end_branch_prob): Ditto.
+ (gen_edge_profiler): Move to rtl-profile.c (rtl_gen_edge_profiler).
+ (gen_interval_profiler): Ditto (rtl_gen_interval_profiler).
+ (gen_pow2_profiler): Ditto (rtl_gen_pow2_profiler).
+ (gen_one_value_profiler): Ditto (rtl_gen_one_value_profiler).
+ (tree_register_profile_hooks): New.
+ (rtl_register_profile_hooks): New.
+ * rtl-profile.c: New file.
+ * rtl.h (init_branch_prob): Move declaration to value-prof.h.
+ (end_branch_prob): Ditto.
+ (branch_prob): Ditto.
+ * toplev.c (flag_tree_based_profiling): New.
+ (f_options): Add -ftree-based-profiling.
+ (compile_file): Register rtl-based CFG and profiling hooks.
+ (rest_of_compilation): Do rtl-based profiling only when
+ !flag_tree_based_profiling. Register rtl-based profiling hooks.
+ (process_options): Sorry for -ftree-based-profiling plus
+ -ftest-coverage or -fprofile-values.
+ * toplev.h (flag_tree_based_profiling): New.
+ * tree-cfg.c (tree_block_ends_with_call_p): New.
+ (tree_block_ends_with_condjump_p): New.
+ (need_fake_edge_p): New.
+ (tree_flow_call_edges_add): New (largely from flow_call_edges_add
+ in cfganal.c).
+ (tree_cfg_hooks): Add tree_block_ends_with_call_p,
+ tree_block_ends_with_condjump_p, tree_flow_call_edges_add.
+ * tree-optimize.c (init_tree_optimization_passes):
+ Add pass_tree_profile.
+ * tree-pass.h: Ditto.
+ * tree-profile.c: New file.
+ * value-prof.c (value_prof_hooks): New.
+ (find_values_to_profile): Rename to rtl_find_values_to_profile.
+ Move rtl-specific bits in from branch_prob.
+ (value_profile_transformations): Rename to
+ rtl_value_profile_transformations.
+ (struct value_prof_hooks): New.
+ (rtl_value_prof_hooks): New.
+ (rtl_register_value_prof_hooks): New.
+ (tree_find_values_to_profile): New stub.
+ (tree_value_profile_transformations): New stub.
+ (tree_value_prof_hooks): New stub.
+ (tree_register_value_prof_hooks): New stub.
+ (find_values_to_profile): New.
+ (value_profile_transformations): New.
+ * value-prof.h: Add multiple inclusion guard.
+ (struct histogram_value): Change rtx fields to void *.
+ (rtl_register_value_prof_hooks): New declaration.
+ (tree_register_value_prof_hooks): New declaration.
+ (find_values_to_profile): New declaration.
+ (free_profiled_values): New declaration.
+ (value_profile_transformations): New declaration.
+ (struct profile_hooks): New declaration.
+ (init_branch_prob): Declaration moved from rtl.h.
+ (branch_prob): Declaration moved from rtl.h.
+ (end_branch_prob): Declaration mooved from rtl.h.
+ (tree_register_profile_hooks): New declaration.
+ (rtl_register_profile_hooks): New declaration.
+ (tree_profile_hooks): New declaration.
+ (rtl_profile_hooks): New declaration.
+ * doc/invoke.texi: Document -ftree-based-profiling.
+
+2004-02-12 Jeff Law <law@redhat.com>
+
+ * domwalk.c (walk_dominator_tree): Move statement walking from
+ clients into here. Walk statements in forward or backward order
+ as requested by the client. Walk either the dominator tree or
+ the post-dominator tree as requested by the client.
+ * domwalk.h (dom_walk_data): Add two fields to control direction of
+ statement walk and dominator vs post-dominator tree walk. Add
+ BSI argument to the per-statement callbacks.
+ * tree-ssa-dom.c (optimize_stmt): Update prototype so that it can
+ be directly used as a callback for the dominator tree walker.
+ Update stmts_to_rescan here.
+ (tree_ssa_dominator_optimize): Initialize new fields in the dominator
+ walker structure. Use optimize_stmt instead of dom_opt_walk_stmts
+ for statement callback.
+ (dom_opt_walk_stmts): Kill. No longer used.
+ * tree-ssa.c (mark_def_sites): Update prototype so that it can be
+ called as the per-statement callback. No longer walk statements here.
+ (mark_def_sites_initialize_block): New.
+ (rewrite_stmt): Update prototype so that it can be called as the
+ per-statement callback.
+ (rewrite_walk_stmts): Kill. No longer used.
+ (rewrite_into_ssa): Initialize new fields in the dominator walker
+ structure. Use rewrite_stmt instead of rewrite_walk_stmts. Add
+ mark_def_sites_initialize_block callback.
+
+2004-02-12 Steven Bosscher <stevenb@suse.de>
+
+ * doc/cfg.texi: New file.
+ * doc/ggcint.texi: Include it. Add a new chapter.
+
+2004-02-11 Jeff Law <law@redhat.com>
+
+ * Makefile.in (OBJS-common): Add tree-ssa-forwprop.o
+ (tree-ssa-forwprop.o): Add dependencies.
+ * timevar.def (TV_TREE_FORWPROP): New timevar.
+ * tree-optimize.c (init_tree_optimization_passes): Link in
+ the forward propagation pass.
+ * tree-pass.h (pass_forwprop): Declare.
+ * tree-ssa-forwprop.c: New file with forward propagation pass.
+ * doc/invoke.texi: Document dump for forward propagation pass.
+
+2004-02-11 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-ssa.c (rewrite_out_of_ssa): Don't use coalesce list until new
+ bug resolved.
+
+2004-02-11 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-ssa-live.c (compare_pairs): New. Coalesce list cost function.
+ (sort_coalesce_list): Use qsort() to sort list by cost.
+ (coalesce_tpa_members): Use correct partition representatives. Add more
+ debug information. Allow coalesce by list, root_var, or both.
+ (tpa_dump): Show partition index.
+ * tree-ssa-live.h (SSANORM_COALESCE_PARTITIONS): New flag.
+ (SSANORM_USE_COALESCE_LIST): New flag.
+ * tree-ssa.c (create_temp): Don't mark as used when created.
+ (coalesce_ssa_name): Create coalesce list if requested. Add more
+ debug output.
+ (assign_vars): Add additional debug info.
+ (remove_ssa_form): Perform TER after assign_vars().
+ (rewrite_vars_out_of_ssa): Pass coalesce partitions flag to
+ remove_ssa_form.
+ (rewrite_out_of_ssa): Add coalesce list flag to remove_ssa_form call.
+
+2004-02-10 Jeff Law <law@redhat.com>
+
+ * Makefile.in (OBJS-common): Add tree-ssa-phiopt.o
+ (tree-ssa-phiopt.o): Add dependencies.
+ * timevar.def (TV_TREE_PHIOPT): New timevar.
+ * tree-cfg.c (extract_true_false_edges_from_block): Moved here from
+ tree-ssa-dom.c.
+ (tree_verify_flow_info): Use extract_true_false_edges_from_block.
+ * tree-flow.h (extract_true_false_edges_from_block): Declare.
+ * tree-ssa-dom.c (extract_true_false_edges_from_block): Moved into
+ tree-cfg.c.
+ (get_eq_expr_value): Improve type check.
+ * tree-optimize.c (init_tree_optimization_passes): Link in
+ phiopt pass.
+ * tree-pass.h (pass_phiopt): Declare.
+ * tree-ssa-phiopt.c: New file with PHI node optimization pass.
+ * doc/invoke.texi: Document dump for PHI node optimization.
+
+2004-02-10 Richard Henderson <rth@redhat.com>
+
+ * tree-sra.c (lookup_scalar): Handle unnamed fields.
+
+2004-02-10 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (OBJS-common): Add tree-ssa-alias.o.
+ (tree-ssa-alias.o): New rule.
+ (tree-ssa-operands.o): Add dependency on $(TIMEVAR_H) and tree-pass.h
+ (gt-tree-dfa.h): Remove.
+ * timevar.def (TV_TREE_OPS): Rename from unused entry TV_TREE_DFA.
+ * tree-ssa-alias.c: New file.
+ * tree-dfa.c (struct alias_stats_d, alias_stats, dump_alias_stats,
+ may_alias_p, add_may_alias, global_var, aliases_computed_p,
+ compute_may_aliases): Move to tree-ssa-alias.c.
+ (struct walk_state): Remove fields 'is_asm_expr' and 'num_calls'.
+ Update all users.
+ (compute_alias_sets, create_memory_tags, may_access_global_mem_p,
+ get_memory_tag_for, promote_call_clobbered_vars,
+ find_addressable_vars): Remove.
+ (call_clobbered_vars): Move to tree-ssa-alias.c and convert to
+ bitmap.
+ (find_referenced_vars): Move logic to create .GLOBAL_VAR to
+ tree-ssa-alias.c.
+ (create_ssa_name_ann): New.
+ (dump_variable): Rearrange.
+ (dump_dfa_stats): Do not show the number of call clobbered
+ variables.
+ (find_vars_r): Do not try to determine if an assignment my access
+ global memory.
+ (add_referenced_var): Remove hacks to establish global memory
+ dependencies.
+ If the variable needs to live in memory mark it call-clobbered.
+ * tree-flow-inline.h (ssa_name_ann): New.
+ (get_ssa_name_ann): New.
+ (set_may_alias_global_mem): Remove.
+ (may_alias_global_mem_p): Remove.
+ (set_may_point_to_global_mem): Remove.
+ (may_point_to_global_mem_p): Remove.
+ (is_call_clobbered): New
+ (mark_call_clobbered): New
+ (mark_non_addressable): New
+ * tree-flow.h (enum tree_ann_type): Add SSA_NAME_ANN.
+ (enum mem_tag_kind): Declare.
+ (struct var_ann_d): Remove fields 'is_call_clobbered',
+ 'may_alias_global_mem' and 'may_point_to_global_mem'.
+ Replace bitfield 'mem_tag' with enum bitfield 'mem_tag_kind'.
+ Rename field 'mem_tag' to 'type_mem_tag'.
+ (struct stmt_ann_d): Change type of field 'addresses_taken' to a
+ bitmap. Update all users.
+ (struct ssa_name_ann_d): Declare.
+ (union tree_ann_d): Add field 'ssa_name'.
+ (ssa_name_ann_t): New type.
+ (struct bb_ann_d): Add field 'has_escape_site'.
+ (num_call_clobbered_vars): Remove.
+ (call_clobbered_var): Remove.
+ (call_clobbered_vars): Change to bitmap.
+ (dump_points_to_info): Declare.
+ (debug_points_to_info): Declare.
+ (walk_use_def_chains_fn): New type.
+ (walk_use_def_chains): Declare.
+ (is_call_clobbered): Declare.
+ (mark_call_clobbered): Declare.
+ * tree-simple.c (needs_to_live_in_memory): Move to tree.c.
+ (is_gimple_non_addressable): Update comment.
+ (is_gimple_call_clobbered): Remove.
+ (get_call_expr_in): New.
+ (get_base_var): Rename from get_base_symbol. Update all callers.
+ Don't strip SSA_NAME wrappers.
+ (get_base_decl): New.
+ (get_base_address): New.
+ * tree-simple.h (is_gimple_call_clobbered): Remove.
+ (needs_to_live_in_memory): Remove.
+ (get_base_decl): Declare.
+ (get_base_var): Declare.
+ (get_base_address): Declare.
+ * tree-ssa-dce.c (need_to_preserve_store): Reduce to calling
+ needs_to_live_in_memory.
+ * tree-ssa-operands.c: Include tree-pass.h and timevar.h
+ (get_stmt_operands): Push/pop TV_TREE_OPS time var.
+ Call mark_call_clobbered for asms that store to memory.
+ (get_expr_operands): When adding operands for INDIRECT_REF
+ expressions, use flow-sensitive aliasing, if available.
+ Assume that malloc-like function calls won't clobber.
+ (add_call_clobber_ops):
+ (add_call_read_ops):
+ * tree-ssa.c (rewrite_into_ssa): If any variable in vars_to_rename
+ is a pointer, invalidate all name memory tags.
+ (create_temp): Call is_call_clobbered and mark_call_clobbered.
+ (walk_use_def_chains_1): New.
+ (walk_use_def_chains): New.
+
+ * tree.c (needs_to_live_in_memory): New.
+ * tree.h (DECL_NEEDS_TO_LIVE_IN_MEMORY_INTERNAL): Define.
+ (struct tree_decl): Add bitfield 'needs_to_live_in_memory'.
+ Update unused bits comment.
+ (needs_to_live_in_memory): Declare.
+
+ * tree-simple.h (get_call_expr_in): Declare.
+ * tree-sra.c (scalarize_stmt): Call get_call_expr_in when handling
+ function calls.
+ * tree-ssa-ccp.c (likely_value): Likewise.
+
+ * params.def (PARAM_MAX_CLOBBERED_VARS_GLOBAL_VAR): Remove.
+ (PARAM_MAX_CALLS_GLOBAL_VAR): Remove.
+ (PARAM_GLOBAL_VAR_THRESHOLD): Define.
+ (PARAM_MAX_ALIAS_SET_SIZE): Define.
+ Update all users.
+ * params.h (MAX_CALLS_FOR_GLOBAL_VAR): Remove.
+ (MAX_CLOBBERED_VARS_FOR_GLOBAL_VAR): Remove.
+ (GLOBAL_VAR_THRESHOLD): Define.
+ (MAX_ALIAS_SET_SIZE): Define.
+
+2004-02-09 Richard Henderson <rth@redhat.com>
+
+ * langhooks.h (lang_hooks_for_functions): Add missing_noreturn_ok_p.
+ * langhooks-def.h, c-lang.c, objc/objc-lang.c
+ (LANG_HOOKS_FUNCTION_MISSING_NORETURN_OK_P): New.
+ * c-objc-common.c (c_missing_noreturn_ok_p): Return bool.
+ (c_objc_common_init): Don't set lang_missing_noreturn_ok_p.
+ * c-tree.h (c_missing_noreturn_ok_p): Update decl.
+ * flow.c (lang_missing_noreturn_ok_p): Remove.
+
+ * flow.c (check_function_return_warnings): Move to tree-cfg.c.
+ * toplev.c (rest_of_compilation): Don't call it.
+ * tree-cfg.c (execute_warn_function_return): Move from flow.c,
+ rename, update for tree vs rtl.
+ (pass_warn_function_return): New.
+ * tree-pass.h (pass_warn_function_return): Declare it.
+ * tree-optimize.c (init_tree_optimization_passes): Run it.
+
+ * function.h (struct function): Remove x_clobber_return_insn.
+ * function.c (free_after_compilation): Don't set it.
+ (expand_function_end): Likewise.
+
+2004-02-09 Richard Henderson <rth@redhat.com>
+
+ Revert:
+ 2004-02-06 Richard Henderson <rth@redhat.com>
+ * tree-ssa-dom.c (record_equivalences_from_phis): Use
+ record_const_or_copy.
+ (record_equivalences_from_stmt): Likewise. Replace
+ block_avail_exprs_p and block_nonzero_vars_p args with bd.
+
+2004-02-09 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (get_eq_expr_value): Improve handling of boolean
+ conditions.
+
+ * domwalk.c (walk_dominator_tree): Completely lose PARENT argument.
+ Callers updated. No longer pass PARENT to callbacks.
+ * domwalk.h (struct dom_walk_data): Corresponding changes.
+ * tree-ssa-dom.c: Likewise.
+ * tree-ssa.c: Likewise.
+
+ * domwalk.c (walk_dominator_tree): Change last argument to be the
+ parent block in the dominator tree rather than the last statement
+ in the parent block in the dominator tree. Similarly in all the
+ callbacks.
+ * domwalk.h (struct dom_walk_data): Update callback prototypes.
+ * tree-ssa-dom.c: Corresponding changes.
+ * tree-ssa.c: Likewise.
+
+ * tree-ssa-dom.c (redirect_edges_and_update_ssa_graph): Break out
+ of tree_ssa_dominator_optimize. If the out-of-ssa pass creates
+ new variables, then invalidate some requested jump threads.
+
+2004-02-08 Richard Henderson <rth@redhat.com>
+
+ * flow.c (regno_uninitialized): Remove.
+ * output.h (regno_uninitialized): Remove.
+ * function.c (setjmp_vars_warning): Rename from
+ uninitialized_vars_warning, remove uninitialized vars warning.
+ * toplev.c (rest_of_handle_life): Update to match.
+ * tree.h (setjmp_vars_warning): Likewise.
+
+ * tree-sra.c (lookup_scalar): Set DECL_NAME to something descriptive.
+
+ * tree-ssa.c (warn_uninit): New.
+ (warn_uninitialized_var, warn_uninitialized_phi): New.
+ (execute_early_warn_uninitialized): New.
+ (execute_late_warn_uninitialized): New.
+ (gate_warn_uninitialized): New.
+ (pass_early_warn_uninitialized): New.
+ (pass_late_warn_uninitialized): New.
+ * tree-pass.h (pass_early_warn_uninitialized): New.
+ (pass_late_warn_uninitialized): New.
+ * tree-optimize.c (init_tree_optimization_passes): Add them.
+
+2004-02-08 Richard Henderson <rth@redhat.com>
+
+ * cppexp.c (append_digit): Rearrange unsignedp/overflow setting.
+ (eval_token, num_binary_op, num_part_mul, num_div_op): Likewise.
+ * ra-rewrite.c (rewrite_program2): Zero info.
+ * reload.c (decompose): Zero val.
+ * tree-ssa-ccp.c (visit_phi_node): Zero phi_val.const_val.
+
+2004-02-07 Jan Hubicka <jh@suse.cz>
+
+ * tree-inline.c (save_body): Clone the parm decl correctly.
+
+ * cgraph.c: Add introductionary comment.
+ (cgraph_remove_node): Release DECL_SAVED_INSNS too.
+ * cgraphunit.c: Likewise.
+ (cgraph_finalize_function): Release DECL_SAVED_INSNS of external function.
+ (decl_expand_function): Release DECL_SAVED_INSNS/body/tree.
+ (cgraph_remove_unreachable_nodes): Likewise; guard cgraph verification.
+
+2004-02-06 Richard Henderson <rth@redhat.com>
+
+ * common.opt (fdisable-tree-ssa): Remove.
+ * flags.h (flag_disable_tree_ssa): Remove.
+ * toplev.c (flag_disable_tree_ssa): Remove.
+ (f_options): Don't set it.
+ * opts.c (common_handle_option): Likewise.
+ * doc/invoke.texi (fdisable-tree-ssa): Remove.
+
+2004-02-06 Richard Henderson <rth@redhat.com>
+
+ * tree-ssa-dom.c (record_equivalences_from_phis): Use
+ record_const_or_copy.
+ (record_equivalences_from_stmt): Likewise. Replace
+ block_avail_exprs_p and block_nonzero_vars_p args with bd.
+
+2004-02-06 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR middle-end/13127
+ * tree-inline.c (declare_return_variable): Set the no warning bit
+ on the variable created for the return value.
+
+2004-02-06 Richard Henderson <rth@redhat.com>
+
+ * tree-pretty-print.c (dump_generic_node): Render NON_LVALUE_EXPR.
+
+ * tree-ssa-dom.c (local_fold): New.
+ (thread_across_edge, simplify_rhs_and_lookup_avail_expr,
+ find_equivalent_equality_comparison): Use it.
+
+2004-02-06 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c/13863
+ * c-common.c (c_decl_uninit_1): Remove.
+ (c_decl_uninit): Remove.
+ * c-common.h (c_decl_uninit): Remove prototype.
+ * c-lang.c (LANG_HOOKS_DECL_UNINIT): Delete.
+ * objc/objc-lang.c (LANG_HOOKS_DECL_UNINIT): Delete.
+ * c-simplify.c (gimplify_decl_stmt): Set TREE_NO_WARNING
+ on the decl where the initial is itself.
+ * function.c (uninitialized_vars_warning): Remove old comment
+ and check for DECL_INITIAL, replace with a check of TREE_NO_WARNING
+ and do not call the langhook.
+ * langhooks-def.h (LANG_HOOKS_DECL_UNINIT): Remove.
+ (LANG_HOOKS_INITIALIZER): Remove usage of LANG_HOOKS_DECL_UNINIT.
+ * langhooks.c (lhd_decl_uninit): Remove.
+ * langhooks.h (lhd_decl_uninit): Remove prototype.
+
+2004-02-05 Richard Henderson <rth@redhat.com>
+
+ * tree-ssa-dom.c (record_const_or_copy_1): New.
+ (record_const_or_copy): New.
+ (thread_across_edge): Use it.
+ (dom_opt_finalize_block): Likewise. Tidy.
+ (record_equality): Split out from ...
+ (record_equivalences_from_incoming_edge): ... here.
+
+2004-02-05 Richard Henderson <rth@redhat.com>
+
+ * tree-ssa-dom.c (simplify_rhs_and_lookup_avail_expr): Allow
+ mixing PLUS and MINUS when folding operations.
+
+2004-02-05 Andrew Macleod <amacleod@redhat.com>
+
+ * tree-pretty-print.c (dump_bb_header): Allow TDF_SLIM printing.
+ (dump_bb_end): Allow TDF_SLIM printing.
+ (dump_generic_bb_buff): Add flags parameter to dump_bb_end.
+
+2004-02-05 Jan Hubicka <jh@suse.cz>
+
+ * alias.c (find_base_term, get_addr): Do not dereference NULL
+ pointer when all VALUE's locations has been invalidated.
+ (rtx_equal_for_memref_p): Simplify checking of VALUEs.
+
+2004-02-04 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-ander.c (andersen_init): Reorder/Redo code so that we
+ actually free the memory in intraprocedural mode.
+ (andersen_cleanup): Ditto.
+
+2004-02-04 Richard Henderson <rth@redhat.com>
+
+ * tree-ssa-ccp.c (get_value, visit_phi_node,
+ visit_assignment, dump_lattice_value): Tidy.
+ (evaluate_stmt): Don't do debug dump here.
+ (def_to_undefined): Merge into set_lattice_value.
+ (def_to_varying): Likewise, but retain as a wrapper.
+ (set_lattice_value): Tidy. Emit correct debug info.
+ (replace_uses_in): Remove strlen hacks.
+ (execute_fold_all_builtins): Fix DECL_BUILT_IN comparison.
+ Force folding of BUILT_IN_CONSTANT_P.
+
+2004-02-04 Richard Henderson <rth@redhat.com>
+
+ * builtins.c (fold_builtin_expect): New.
+ (fold_builtin_1): Call it.
+
+2004-02-04 Jeff Law <law@redhat.com>
+
+ * jump.c (duplicate_loop_exit_test): Allow copying of the loop
+ exit test even if we do not find the LOOP_END note.
+
+ * domwalk.c: Update comments.
+
+2004-02-04 Brian Booth <bbooth@redhat.com>
+
+ PR opt/13755
+ * tree-dfa.c (compute_alias_sets): set rename flag for variables
+ aliased by GLOBAL_VAR.
+
+2004-02-04 Richard Henderson <rth@redhat.com>
+
+ * tree-ssa-dom.c (simplify_switch_and_lookup_avail_expr): New.
+ (eliminate_redundant_computations): Call it.
+
+2004-02-03 Richard Henderson <rth@redhat.com>
+
+ PR opt/13869
+ * tree-cfg.c (cfg_remove_useless_stmts_bb): Correct handling of
+ boolean variables in COND_EXPR_COND.
+
+2004-02-03 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/13325
+ * builtins.c (fold_builtin_1): Rename from fold_builtin.
+ (fold_builtin): New.
+ * c-simplify.c (gimplify_expr_stmt): Check TREE_NO_WARNING.
+ * stmt.c (expand_expr_stmt_value): Likewise.
+ * tree.h (struct tree_common): Add nowarning_flag.
+ (TREE_NO_WARNING): New.
+ (TREE_NO_UNUSED_WARNING): Remove.
+ * c-typeck.c (build_unary_op): Use TREE_NO_WARNING instead.
+ * stmt.c (warn_if_unused_value): Likewise.
+
+2004-02-03 Steven Bosscher <stevenb@suse.de>
+
+ * tree-ssa-dce.c: Partial rewrite. The old DCE is now called
+ `conservative'. The more aggressive algorithm uses control
+ dependence and is called `aggressive' or cd-dce.
+ * timevar.def (TV_TREE_DCE): Rename.
+ (TV_TREE_CD_DCE, TV_CONTROL_DEPENDENCES): New timevars.
+ * tree-pass.h: Declare extern pass_cd_dce.
+ * tree-optimize.c (init_tree_optimization_passes): Replace
+ the final DCE pass with a CD-DCE pass.
+
+2004-02-01 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_mark_inline_edge): Fix insertion to
+ cgraph_inline_hash.
+
+2004-01-30 Frank Ch. Eigler <fche@redhat.com>
+
+ * common.opt: Add support for -fmudflapth, -fmudflapir.
+ * invoke.texi: Document them.
+ * opts.c: Ditto.
+ * flags.h: Add new flags flag_mudflap_threads, _ignore_reads.
+ * toplev.c: Initialize new flags. Remove redundant code from
+ lang_independent_options[].
+ * tree-mudflap.c (*): Support new flag_mudflap_threads encoding.
+ (mf_xform_derefs_1): Support flag_mudflap_ignore_reads option.
+ * c-mudflap.c (mflang_flush_calls): Mark static ctor TREE_USED.
+
+2004-01-30 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * gengtype-yacc.y (bitfieldlen): Add empty action.
+
+2004-01-30 Diego Novillo <dnovillo@redhat.com>
+
+ * configure.ac: Move configuration for libbanshee and
+ libgmp from configure.in.
+
+2004-01-30 Richard Henderson <rth@redhat.com>
+
+ PR opt/13524
+ * gengtype-yacc.y (struct_fields): Accept unnamed bitfields.
+ (bitfieldlen): Split from ...
+ (bitfieldopt): ... here.
+ * gimplify.c (mark_not_gimple): Remove.
+ (gimplify_call_expr): Don't ignore BUILT_IN_MD.
+ * tree-dfa.c (struct walk_state): Remove is_not_gimple.
+ (find_referenced_vars): Don't look for TREE_NOT_GIMPLE.
+ (find_vars_r, add_referenced_var): Likewise.
+ * tree-ssa-operands.c (get_stmt_operands, get_expr_operands): Likewise.
+ * tree-simple.h (mark_not_gimple): Remove.
+ * tree.h (struct tree_common): Remove not_gimple_flag.
+ (TREE_NOT_GIMPLE): Remove.
+
+2004-01-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/13865
+ * c-simplify.c (gimplify_for_stmt): Reorganize to fix cleanups.
+
+2004-01-29 Richard Henderson <rth@redhat.com>
+
+ PR c++/13543
+ * tree-inline.c (initialize_inlined_parameters): Register the
+ substitute reference also.
+
+2004-01-29 Richard Henderson <rth@redhat.com>
+
+ * tree-inline.c (gimple_expand_calls_inline): Look inside
+ RETURN_EXPR.
+
+ * tree-pretty-print.c (dump_generic_node): If TDF_DETAILS, dump
+ both name and uid.
+
+2004-01-29 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfg.c (unlink_block): Reset prev_bb and next_bb.
+
+2004-01-29 Jeff Law <law@redhat.com>
+ Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-ssa-live.h (tpa_next_partition): Correctly handle compressed
+ elements.
+ * tree-ssa.c (coalesce_ssa_name): New argument, flags. Callers
+ updated. Test SSANORM_COMBINE_TEMPS in flags rather than
+ flag_tree_combine_temps.
+ (coalesce_vars): Either operand of a copy might not have a
+ partition when rewriting a subset of the variables out of SSA form.
+ (rewrite_vars_out_of_ssa): Honor -ftree-combine-temps by passing
+ in SSANORM_COMBINE_TEMPS in flags argument to remove_sas_form..
+
+2004-01-29 Dale Johannesen <dalej@apple.com>
+
+ * Makefile.in (OBJS-common): Move tree-nomudflap.o...
+ (OBJS-archive): ...to here, and remove duplicate tree-optimize.o.
+
+2004-01-28 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/13898
+ * gimplify.c (gimplify_init_constructor): Invoke
+ lhd_set_decl_assembler_name on the now-static variable.
+
+2004-01-28 Richard Henderson <rth@redhat.com>
+
+ PR opt/13798
+ * expr.c (is_zeros_p): Remove. Change all callers to use
+ initializer_zerop.
+ (categorize_ctor_elements_1, categorize_ctor_elements): New.
+ (count_type_elements): New.
+ (mostly_zeros_p): Use them.
+ * gimplify.c (tmp_var_id_num): Split out from create_tmp_var_raw.
+ (create_tmp_var_name): Likewise.
+ (gimplify_init_constructor): Drop constructors to readonly memory
+ as indicated by categorize_ctor_elements and can_move_by_pieces.
+ * tree.c (initializer_zerop): Handle VECTOR_CST. Don't check
+ AGGREGATE_TYPE_P for CONSTRUCTOR.
+ * tree.h (categorize_ctor_elements): Declare.
+ (count_type_elements): Declare.
+ * Makefile.in (gimplify.o): Update dependencies.
+ (GTFILES): Add gimplify.c.
+
+2004-01-27 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mx_register_decls): Support VLAs.
+ (mf_xform_derefs_1): Disable checking shortcut for VLAs.
+ * c-simplify.c (gimplify_decl_stmt): Add mudflap xref comment.
+ * gimplify.c (gimplify_bind_expr): Ditto.
+
+2004-01-27 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c: Add more comments describing SSAPRE and
+ the various functions.
+ (generate_expr_as_of_bb): Use PRED, a basic block argument, instead of
+ j, the index of that bb.
+ (generate_vops_as_of_bb): Ditto.
+ (insert_occ_in_preorder_dt_order): Rename to
+ create_and_insert_occ_in_preorder_dt_order.
+
+2004-01-27 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (rename_1): Add some more comments.
+
+2004-01-25 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c/13748
+ * c-decl.c (finish_function): Do not pass
+ the function on to optimizers if there was an error.
+
+2004-01-23 Richard Henderson <rth@redhat.com>
+
+ PR opt/12941
+ * combine.c (SHIFT_COUNT_TRUNCATED): Provide default value.
+ (simplify_comparison): Don't simplify (eq (zero_extract c 1 r) 0)
+ if SHIFT_COUNT_TRUNCATED is set.
+
+2004-01-21 Richard Henderson <rth@redhat.com>
+
+ PR c/11267
+ * c-decl.c (c_finalize): New.
+ (finish_function): Use it. Genericize and finalize only non-nested
+ functions. Register nested functions with cgraph.
+ * c-simplify.c: Include cgraph.h.
+ (c_genericize): Genericize nested functions.
+ * gimplify.c (gimplify_expr): Use DECL_SAVED_INSNS to access
+ the struct function for the context.
+ * Makefile.in (c-simplify.o): Update dependencies.
+
+2004-01-21 Steven Bosscher <stevenb@suse.de>
+
+ PR opt/13767
+ * tree-cfg.c (simple_goto_p): Remove NONLOCAL_LABEL check.
+
+2004-01-21 Dale Johannesen <dalej@apple.com>
+
+ * tree-dfa.c: Fix comment.
+
+2004-01-21 Richard Henderson <rth@redhat.com>
+
+ PR opt/13681
+ * tree-ssa-operands.c (get_expr_operands): Handle (&x + c).
+
+ * tree-ssa-ccp.c (maybe_fold_offset_to_component_ref): Handle
+ flexible array members and lookalikes.
+
+2004-01-21 Dale Johannesen <dalej@apple.com>
+
+ * tree-ssa-dom.c (cprop_into_stmt): Add convert call
+ to prevent type mismatches.
+
+2004-01-21 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (load_modified_phi_result): PARM_DECL is okay
+ to not have a defbb.
+ (rename_1): Add a comment.
+
+2004-01-21 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (find_equivalent_equality_comparison): Treat
+ CONVERT_EXPRs just like NOP_EXPRs.
+ (record_equivalences_from_stmt): Similarly.
+ (thread_across_edge): Fix formatting goof.
+
+ * tree-ssa-dom.c (thread_across_edge): Remove bogus restriction
+ which prevents threading around to the top of a loop.
+
+ * tree-ssa-dom.c (thread_across_edge): Handle SWITCH_EXPRs in the
+ target block in addition to COND_EXPRs.
+
+ * tree-ssa-dom.c (thread_across_edge): Create equivalences for
+ PHIs before looking at the statements in the destination
+ block.
+
+2004-01-20 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold_convert): Rename to fold_convert_const.
+ (fold_convert_const): Change arguments to take a tree_code,
+ a type and the operand/expression to be converted. Return
+ NULL_TREE if no simplification is possible. Add support for
+ FIX_CEIL_EXPR and FIX_FLOOR_EXPR in addition to FIX_TRUNC_EXPR.
+ (fold): Handle FIX_CEIL_EXPR and FIX_FLOOR_EXPR.
+ Adjust call to fold_convert to match new fold_convert_const.
+ Avoid modifying the tree passed to fold in-place.
+ (nondestructive_fold_unary_to_constant): Likewise, simplify
+ call to fold_convert to match new fold_convert_const.
+
+2004-01-20 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-ander.c (andersen_op_assign): Update
+ prototype. Make this handle &x in the operands using
+ the addrargs parameter.
+ (andersen_init): Turn off ip_partial until variables
+ aliasing variables in other functions is resolved.
+ (andersen_add_var): Use newly renamed alias_var_new_with_aterm.
+ Fix comment.
+ (andersen_add_var_same): Ditto.
+ (andersen_function_call): Use ip_partial, not flag_unit_at_a_time.
+ * tree-alias-common.c (get_values_from_constructor): Add bitmap
+ and int * arguments. Used to mark operands that we are taking
+ address of.
+ (get_alias_var_decl): We should never see FIELD_DECL's right now.
+ (intra_function_call): Reverse ordering for slightly faster
+ projection merging.
+ (find_op_of_decl): New function.
+ (find_func_aliases): Use it.
+ Comment x = foo.y case.
+ Move get_alias_var_decl of arguments so we only call it if
+ necessary.
+ Handle address of arguments in operations.
+ (create_fun_alias_var): tvar->var.
+ Set context of fakeargs.
+ Set context of fakedecls.
+ Set DECL_PTA_ALIASVAR of RETURN_DECL's.
+ (create_fun_alias_var_ptf): tvar->var.
+ Set context of fakedecls.
+ (create_alias_vars): Only create alias vars for globals
+ with DECL_INITIAL's.
+ * tree-alias-common.h (struct tree_alias_ops):
+ Update op_assign arguments.
+ (may_alias): Fix comment.
+ (same_points_to_set): Ditto.
+ (empty_points_to_set): Ditto.
+ * tree-alias-type.h: Rename alias_tvar_new_with_aterm
+ -> alias_var_new_with_aterm.
+ * tree-alias-type.c: Ditto.
+
+2004-01-20 Richard Henderson <rth@redhat.com>
+
+ * tree-sra.c (get_scalar_for_field): Validate field.
+ (create_scalar_copies): Iterate over rhs fields too.
+
+2004-01-19 Dale Johannesen <dalej@apple.com>
+
+ * params.def: Add PARAM_MAX_CALLS_GLOBAL_VAR and
+ PARAM_MAX_CLOBBERED_VARS_GLOBAL_VAR.
+ params.h: Ditto.
+ tree-dfa.c: Use them.
+ doc/invoke.texi: Document them.
+
+2004-01-19 Jeff Law <law@redhat.com>
+
+ * tree-ssa.c (insert_phi_nodes_for): Always use fully pruned
+ SSA form.
+
+ * tree-flow.h: Update copyright dates.
+ (register_new_def): Declare.
+ * tree-ssa-dom.c: Update copyright dates.
+ Add tracking of current definition of each program variable just
+ like we do when rewriting into SSA form.
+ (get_value_for, set_value_for): Handle either an SSA_NAME or
+ regular variable.
+ (tree_ssa_dominator_optimize): Initialize and update CURRDEFS.
+ If we thread through a block with real statements, the destination
+ of those statements must be rewritten too.
+ (thread_across_edge): Skip nop statements at the start of a
+ block.
+ (dom_opt_initialize_block_local_data): Clear block_defs
+ appropriately.
+ (record_equivalences_from_phis): Accept walk_data structure.
+ Call register_new_def appropriately.
+ (optimize_stmt): Call register_new_defs_for_stmt.
+ (dom_opt_finalize_block): Restore CURRDEFS appropriately.
+ (register_new_definitions_for_stmt): New.
+ * tree-ssa.c: Update copyright dates.
+ (register_new_def): No longer static. Accept additional argument
+ for the table to hold the new definition. Callers updated.
+
+ * gimplify.c: Update copyright dates.
+ * tree-cfg.c: Likewise.
+ * tree.h: Likewise.
+
+ * tree-iterator.c, tree-iterator.c: Use GCC rather than GNU CC.
+ * tree-ssa-pre.c, tree-ssa-live.h: Likewise.
+
+2004-01-19 Daniel Berlin <dberlin@dberlin.org>
+
+ * timevar.def (TV_TREE_SPLIT_EDGES): New timevar.
+ * tree-ssa-pre.c (split_critical_edges): Move from here
+ (pass_pre): Add PROP_no_crit_edges as required.
+ * tree-cfg.c (split_critical_edges): to here.
+ (pass_split_crit_edges): New pass.
+ * tree-optimize.c (tree_optimization_passes): Add NEXT_PASS
+ (split_crit_edges).
+ * tree-pass.h: Add PROP_no_crit_edges.
+ (pass_split_crit_edges): Declared.
+
+2004-01-19 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mf_build_check_statement_for): Tolerate
+ incoming locus NULL pointer.
+
+2004-01-18 Richard Henderson <rth@redhat.com>
+
+ * builtins.c (simplify_builtin_strcpy): Export. Take strlen argument.
+ (simplify_builtin_strncpy, simplify_builtin_strcmp): Similarly.
+ (simplify_builtin_strncmp): Similarly.
+ (simplify_builtin): Update to match.
+ * expr.h (simplify_builtin_strcmp, simplify_builtin_strncmp,
+ simplify_builtin_strcpy, simplify_builtin_strncpy): Declare.
+ * tree-pass.h (pass_fold_builtins): New.
+ * tree-optimize.c (init_tree_optimization_passes): Add it.
+ * tree-ssa-ccp.c (ccp_fold_builtin): Handle BUILT_IN_STRCPY,
+ BUILT_IN_STRNCPY, BUILT_IN_STRCMP, BUILT_IN_STRNCMP.
+ (get_strlen): Don't cast to size_t.
+ (execute_fold_all_builtins, pass_fold_builtins): New.
+
+2004-01-19 Jan Hubicka <jh@suse.cz>
+
+ PR opt/13729
+ * cgraphunit.c (cgraph_finalize_compilation_unit): Fix memory leak.
+ (cgraph_remove_unreachable_nodes): Do not mix analyzed and
+ DECL_SAVED_TREE flags.
+
+2004-01-18 Richard Henderson <rth@redhat.com>
+
+ * tree-sra.c (REALPART_INDEX, IMAGPART_INDEX): Remove.
+ (sra_candidates, needs_copy_in): Use a bitmap. Update all users.
+ (struct sra_elt, sra_elt_hash, sra_elt_eq): New.
+ (sra_map_size): Remove.
+ (sra_map): Use a htab_t.
+ (lookup_scalar): Update to match.
+ (get_scalar_for_field, get_scalar_for_complex_part): Likewise.
+ (scalarize_structure_assignment): Use annotate_all_with_locus.
+ (csc_build_component_ref): Remove index argument.
+ (csc_build_complex_part): Take tree_code, not index.
+ (create_scalar_copies): Don't collect indicies.
+ (emit_scalar_copies): New.
+ (scalarize_modify_expr, scalarize_tree_list): Use it.
+ (scalarize_return_expr): Likewise.
+ (scalarize_structures): Simplify needs_copy_in iteration.
+ (scalarize_call_expr): Use annotate_all_with_locus.
+ (dump_sra_map_trav): Split from ...
+ (dump_sra_map): ... here. Update for hash table.
+ (tree_sra): Update for new datastructures.
+
+2004-01-18 Richard Henderson <rth@redhat.com>
+
+ * tree-cfg.c (dump_function_to_file): Move ";; Function" header ...
+ * tree-optimize.c (execute_one_pass): ... here.
+
+2004-01-17 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-common.c: s@_typevar@_var@g, s@_TVAR@_VAR@g,
+ s@_TYPEVAR@_VAR@g
+ * tree-alias-common.h: Ditto
+ * tree.h: Ditto
+ * tree-alias-ander.c: Ditto
+ * tree-alias-type.c: Ditto
+ * tree-alias-type.h: Ditto
+
+2004-01-17 Richard Henderson <rth@redhat.com>
+
+ * tree-complex.c (gimplify_val): Copy TREE_BLOCK.
+
+ * tree-complex.c (gimplify_val): New.
+ (extract_component, do_binop, do_unop): Use it.
+
+2004-01-17 Richard Henderson <rth@redhat.com>
+
+ * tree-complex.c (expand_complex_operations_1): Fix RETURN_EXPR
+ thinko in last change.
+
+2004-01-18 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfghooks.c (split_block): Don't redirect edges.
+ * cfgrtl.c (rtl_split_block): Do it here.
+ * tree-cfg.c (tree_split_block): Ditto.
+
+2004-01-17 Richard Henderson <rth@redhat.com>
+
+ * tree-cfg.c (verify_expr): Tidy. Check COND_EXPR for boolean
+ condition.
+
+2004-01-17 Jan Hubicka <jh@suse.cz>
+
+ PR optimization/11761
+ * Makefile.in: Remove tree-simple.c from GTYized files.
+ * tree-dfa.c (find_addressable_vars): Parse nontrivial ADDR_EXPRs.
+ (discover_nonconstant_array_refs_r): New static function.
+ (discover_nonconstant_array_refs): New global function.
+ * tree-flow.h (discover_nonconstant_array_refs): Declare.
+ * tree-simple.c (types_checked, types_in_memory): Kill.
+ (struct_needs_to_live_in_memory): Kill.
+ (needs_to_live_in_memory): aggregates are safe.
+ * tree-ssa.c (rewrite_out_of_ssa): Call the new function.
+
+2004-01-17 Richard Henderson <rth@redhat.com>
+
+ PR opt/13718
+ * tree-complex.c (expand_complex_comparison): Handle COND_EXPR.
+ (expand_complex_operations_1): Likewise.
+
+2004-01-17 Richard Henderson <rth@redhat.com>
+
+ * tree-sra.c (scalarize_tree_list): Take bitmap argument to
+ avoid emitting duplicates. Update all callers.
+
+2004-01-17 Richard Henderson <rth@redhat.com>
+
+ PR opt/13718
+ * tree-complex.c (expand_complex_comparison): New.
+ (expand_complex_operations_1): Handle EQ_EXPR and NE_EXPR.
+
+2004-01-16 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-common.c (get_alias_var): Handle BIT_FIELD_REF.
+ (find_func_aliases): Ditto.
+ Update for fact that basic component_refs are no longer
+ is_gimple_variable.
+ (create_fun_alias_var): Set DECL_CONTEXT on our faked declarations.
+ (pass_del_pta): PTA dumps info on delete, so it needs a name.
+
+2004-01-16 Steven Bosscher <stevenb@suse.de>
+
+ * tree-optimize.c (init_tree_optimization_passes): Run DCE
+ before the first dominator optimization pass.
+
+2004-01-15 Brian Booth <bbooth@redhat.com>
+ Richard Henderson <rth@redhat.com>
+
+ * tree-sra.c (REALPART_INDEX, IMAGPART_INDEX): New.
+ (sra_map_size): New.
+ (make_temp): New.
+ (mark_all_vdefs): New.
+ (is_sra_candidate_decl): New.
+ (is_sra_candidate_ref): New.
+ (lookup_scalar): Use sra_map_size, make_temp.
+ (get_scalar_for_field): Rename from get_scalar_for.
+ (get_scalar_for_complex_part): New.
+ (can_be_scalarized_p): Handle COMPLEX_TYPE.
+ (scalarize_component_ref): Handle REAL/IMAGPART_EXPR.
+ (scalarize_structure_assignment): Tidy.
+ (find_candidates_for_sra): Handle COMPLEX_TYPE, return bool.
+ (csc_assign, csc_build_component_ref): Split out from ...
+ (create_scalar_copies): ... here. Handle COMPLEX_TYPE.
+ (csc_build_complex_part): New.
+ (scalarize_modify_expr): Use is_sra_candidate_foo.
+ (scalarize_tree_list): Likewise.
+ (scalarize_return_expr): Likewise.
+ (dump_sra_map): Split out from ...
+ (tree_sra): ... here. Tidy.
+
+2004-01-15 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mf_xform_derefs): Accept void return statements.
+
+2004-01-15 Andrew MacLeod <amacleod@redhat.com>
+ Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (remove_local_expressions_from_table): New function
+ extracted from dom_opt_finalize_block.
+ (restore_vars_to_originalvalue): Likewise.
+ (extract_true_false_edges_from_block): Likewise.
+ (thread_across_edge): Handle if (cond) too.
+ (dom_opt_finalize_block): Use new functions. Handle if (cond).
+
+ * tree-ssa-dom.c (thread_across_edge): Accept dom_walk argument.
+ Record temporary equivalences created by PHIs and temporarily
+ const/copy propagate into conditionals.
+ (dom_opt_finalize_block): Thread across an edge to a dominated block
+ if the dominated block has PHIs. Remove temporary equivalenecs
+ created by PHIs in thread_across_edge. Update code to restore the
+ various hash tables to use the actual varray rather than a local
+ copy of the varray.
+ (simplify_rhs_and_lookup_avail_expr): Set the condition's code
+ before settings its operands.
+
+ * tree-ssa.c (create_temp): Use add_referenced_var rather than
+ an incomplete inline of its behavior. Also make sure to
+ set is_dereferenced_{load,store}, is_call_clobbered and is_stored.
+
+ * tree-ssa-live.c (build_tree_conflict_graph): Correctly handle
+ case where the result of a PHI is unused.
+
+2004-01-15 Diego Novillo <dnovillo@redhat.com>
+
+ * cfghooks.c (predicted_by_p): Add missing return.
+
+2004-01-15 Richard Henderson <rth@redhat.com>
+
+ * tree-ssa-dom.c (optimize_stmt): Dump new statement if
+ folding succeeded.
+
+2004-01-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * tree-cfg.c: Fix comment typos.
+ * tree-eh.c: Likewise.
+ * tree-inline.c: Likewise.
+ * tree-optimize.c: Likewise.
+ * tree-ssa.c: Likewise.
+ * tree-ssa-dom.c: Likewise.
+ * tree-ssa-operands.c: Likewise.
+ * tree-ssa-pre.c: Likewise.
+ * tree-tailcall.c: Likewise.
+
+2004-01-14 Jan Hubicka <jh@suse.cz>
+
+ * basic-block.h: Include predict.h
+ (tree_predicted_by_p, rtl_predicted_by_p, rtl_predict_edge,
+ predict_edge_def): Declare.
+ * cfghooks.h (cfg_hooks): add predict_edge and predicted_by_p
+ (predict_edge, predicted_by_p): Declare.
+ * cfghooks.c (predict_edge, predicted_by_p): Declare.
+ * cfgrtl (rtl_cfg_hooks, cfg_layout_rtl_cfg_hook): Add new hooks.
+ * cse.c (struct cse_basic_block_data): Rename enum values to not
+ conflict with profile.h; update all uses.
+ * predict.c: Include tree-flow.h, ggc.h, tree-dump.h
+ (predicted_by_p): Rename to ...
+ (rtl_predicted_by_p): .. this one; make global
+ (tree_predicted_by_p): New.
+ (dump_prediction): Add FILE argument.
+ (predict_edge): Rename to ...
+ (rtl_predict_edge): .. this one.
+ (tree_predict_edge): New.
+ (combine_predictions_for_insn): Update calls of predict_edge.
+ (predict_loops): Break out from ...
+ (estimate_probability): ... here; update comments; move updating
+ of unknown probabilities from ...
+ (estimate_bb_frequencies): ... here.
+ (combine_predictions_for_bb): New.
+ (tree_predict_by_opcode): New.
+ (tree_estimate_probability): New.
+ * predict.def (PRED_TREE_POINTER, PRED_TREE_OPCODE_POSITIVE,
+ PRED_TREE_OPCODE_NONEQUAL, PRED_TREE_FPOPCODE): New predictors.
+ * predict.h: Add include guard.
+ (predict_edge, predict_edge_def): Move prototypes to basic_block.h
+ * tree-cfg.c (tree_cfg_hooks): Add prediction hooks.
+ * tree-dump.c (dump_files): Add profile.
+ * tree-flow.h (struct edge_prediction): New structure.
+ (struct bb_ann_d): Add field predictions.
+ (tree_estimate_probability): Declare.
+ * tree-optimize.c (optimize_function_tree): Call tree_estimate_probability.
+ * tree.h (tree_dump_index): Add TDI_profile.
+ * tree-pass.h (pass_profile): Declare.
+
+2004-01-14 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * basic-block.h (find_basic_blocks, cleanup_cfg,
+ delete_unreachable_blocks, merge_seq_blocks): Declare.
+ * cfgcleanup.c (merge_seq_blocks): New.
+ * output.h (find_basic_blocks, cleanup_cfg, delete_unreachable_blocks):
+ Declarations moved to basic-block.h.
+ * tree-cfg.c (tree_merge_blocks, tree_can_merge_blocks_p): New.
+ (cleanup_tree_cfg): Call merge_seq_blocks.
+ (tree_cfg_hooks): Add tree_can_merge_blocks_p and tree_merge_blocks.
+
+2004-01-14 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-cfg.c (tree_make_forwarder_block): Fix.
+
+2004-01-14 Richard Henderson <rth@redhat.com>
+
+ * tree-complex.c: New file.
+ * Makefile.in (OBJS-common): Add it.
+ * tree-pass.h (pass_lower_complex): New.
+ * tree-optimize.c (init_tree_optimization_passes): Add it.
+
+2004-01-14 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * Makefile.in (tree-ssa-loop.o): Add cfgloop.h dependency.
+ (cfghooks.o): Add TIMEVAR_H and toplev.h dependency.
+ * basic-block.h (struct edge_def): Use ir_type instead testing of
+ cfg_hooks directly.
+ (tidy_fallthru_edge, tidy_fallthru_edges, dump_bb, verify_flow_info):
+ Declaration removed.
+ * cfg.c (verify_flow_info, dump_bb): Moved to cfghooks.c.
+ * cfgcleanup.c (try_simplify_condjump): Changed due to change of
+ tidy_fallthru_edge.
+ * cfghooks.c: Include timevar.h and toplev.h.
+ (cfg_hooks): Made static.
+ (tree_register_cfg_hooks, ir_type): New.
+ (verify_flow_info, dump_bb): Moved from cfg.c.
+ (redirect_edge_and_branch, redirect_edge_and_branch_force,
+ split_block, split_block_after_labels, move_block_after,
+ delete_basic_block, split_edge, create_basic_block,
+ create_empty_bb, can_merge_blocks_p, merge_blocks,
+ make_forwarder_block, tidy_fallthru_edge, tidy_fallthru_edges): New.
+ * cfghooks.h (struct cfg_hooks): Modified.
+ (redirect_edge_and_branch, redirect_edge_and_branch_force, split_block,
+ delete_basic_block, split_edge, create_basic_block, can_merge_blocks_p,
+ merge_blocks, make_forwarder_block): Changed into functions.
+ (loop_optimizer_init, loop_optimizer_finalize): Removed.
+ (HEADER_BLOCK, LATCH_EDGE): Moved into cfgloop.c.
+ (tidy_fallthru_edge, tidy_fallthru_edges, create_empty_bb,
+ verify_flow_info, dump_bb, ir_type): Declare.
+ (cfg_layout_rtl_cfg_hooks): Declare.
+ * cfglayout.c (copy_bbs): Don't call add_to_dominance_info.
+ * cfgloop.c (HEADER_BLOCK, LATCH_EDGE): Moved from cfghooks.h.
+ (update_latch_info, mfb_keep_just, mfb_keep_nonlatch): New functions.
+ (canonicalize_loop_headers): Use new semantics of make_forwarder_block.
+ * cfgloop.h (rtl_loop_optimizer_init, rtl_loop_optimizer_finalize):
+ Removed.
+ (loop_optimizer_init, loop_optimizer_finalize): Declare.
+ * cfgloopmanip.c (split_loop_bb): Don't update dominators.
+ (remove_bbs): Don't call remove_bbs.
+ (create_preheader): Use make_forwarder_block.
+ (mfb_keep_just, mfb_update_loops): New static functions.
+ * cfgrtl.c (cfg_layout_split_block, rtl_split_block,
+ rtl_make_forwarder_block, rtl_create_basic_block,
+ rtl_delete_block, rtl_split_block, rtl_merge_blocks,
+ tidy_fallthru_edge, rtl_split_edge, cfg_layout_merge_blocks,
+ cfg_layout_split_edge): Parts not specific to rtl moved to cfghooks.c
+ (tidy_fallthru_edges): Moved to cfghooks.c.
+ (rtl_move_block_after): New.
+ (redirect_edge_with_latch_update, update_cfg_after_block_merging):
+ Removed.
+ (rtl_cfg_hooks, cfg_layout_rtl_cfg_hooks): Modified.
+ * ifcvt.c (merge_if_block, find_cond_trap, find_if_case_1,
+ find_if_case_2): Don't update dominators.
+ * loop-init.c (rtl_loop_optimizer_init, rtl_loop_optimizer_finalize):
+ Replaced by rtl_loop_optimizer_init and rtl_loop_optimizer_finalize.
+ * loop-unswitch.c (unswitch_loop): Don't call add_to_dominance_info.
+ * toplev.c (rest_of_handle_loop2): Enter cfglayout mode here.
+ * tree-cfg.c (create_bb): Modified to suit create_basic_block hook.
+ (tree_redirect_edge_and_branch_1): Merged into
+ tree_redirect_edge_and_branch.
+ (create_blocks_annotations): Removed.
+ (tree_loop_optimizer_init, tree_loop_optimizer_finalize): Removed.
+ (tree_make_forwarder_block, remove_bb, tree_split_edge,
+ tree_redirect_edge_and_branch, tree_split_block,
+ tree_move_block_after): Partially moved to cfghooks.c.
+ (tree_duplicate_bb): New.
+ (PENDING_STMT): Moved to tree-flow.h.
+ (tree_register_cfg_hooks): Moved to cfghooks.c.
+ (build_tree_cfg): Don't call create_blocks_annotations.
+ (factor_computed_gotos, make_blocks): Use create_empty_bb.
+ (cleanup_tree_cfg): Use delete_unreachable_blocks.
+ (remove_unreachable_blocks, insert_bb_before): Removed.
+ (remove_phi_nodes_and_edges_for_unreachable_block): Modified.
+ (tree_find_edge_insert_loc, thread_jumps): Use cfg hooks.
+ (bsi_commit_edge_inserts): Update_annotations argument removed.
+ (tree_cfg_hooks): Modified.
+ * tree-flow.h (PENDING_STMT): Moved from tree-cfg.c.
+ (insert_bb_before, remove_unreachable_blocks,
+ remove_phi_nodes_and_edges_for_unreachable_block, tree_split_edge):
+ Declaration removed.
+ (bsi_commit_edge_inserts): Declaration changed.
+ (tree_duplicate_bb): Declare.
+ * tree-sra.c (scalarize_structures): Changed due to
+ bsi_commit_edge_inserts change.
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize): Use
+ delete_unreachable_blocks.
+ * tree-ssa-loop.c: Include cfgloop.h.
+ * tree-ssa-pre.c (split_critical_edges, tree_perform_ssapre): Use cfg
+ hooks.
+ * tree-ssa.c (rewrite_trees, rewrite_vars_out_of_ssa): Changed due to
+ bsi_commit_edge_inserts change.
+ (ssa_redirect_edge): Record the phi arguments on the redirected edge.
+ * tree-tailcall.c (eliminate_tail_call): Clean stored phi arguments.
+
+2004-01-13 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (gimplify_lhs_complex_part_expr): Remove.
+ (gimplify_modify_expr): Don't call it.
+
+ * tree-alias-common.c (HAVE_BANSHEE): Make sure it's defined.
+ (pass_build_pta): Set name.
+
+2004-01-13 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-tailcall.c (eliminate_tail_call): Add phi nodes for the call
+ vdefs.
+ (find_tail_calls): Ignore returns with virtual operands.
+
+2004-01-12 Richard Henderson <rth@redhat.com>
+
+ * tree-pass.h: New file.
+ * gimple-low.c: Include tree-pass.h.
+ (lower_function_body): Make static, take no arguments. Set
+ dont_emit_block_notes and call reset_block_changes here.
+ (pass_lower_cf): New.
+ * toplev.c (general_init): Call init_tree_optimization_passes.
+ * toplev.h (init_tree_optimization_passes): Declare.
+ * tree-alias-ander.c: Include tree-pass.h.
+ (tree_dump_file, tree_dump_flags): Remove.
+ (andersen_init): Don't dump_begin.
+ (andersen_cleanup): Don't dump_end.
+ * tree-alias-common.c: Include tree-pass.h, timevar.h.
+ (currptadecl): Remove.
+ (create_alias_vars): Make static, take no args. Tidy ifdefs.
+ (delete_alias_vars): Likewise. Protect vs PTA_ANDERSEN.
+ (pass_build_pta, pass_del_pta): New.
+ * tree-alias-common.h (create_alias_vars): Delete decl.
+ (delete_alias_vars): Likewise.
+ * tree-cfg.c: Include tree-pass.h.
+ (tree_dump_file, tree_dump_flags): Remove.
+ (build_tree_cfg): Don't timevar, do init_flow. Ensure one bb.
+ Don't dump the function here.
+ (execute_build_cfg, pass_build_cfg): New.
+ (remove_useless_stmts): Make static, take no arguments.
+ (pass_remove_useless_stmts): New.
+ (remove_bb): Don't open the dump file.
+ * tree-dfa.c: Include tree-pass.h.
+ (tree_dump_file, tree_dump_flags): Remove.
+ (find_referenced_vars): Make static, take no args. Do init_tree_ssa.
+ (compute_may_aliases): Similarly. Don't timevar or open dump file.
+ Don't delete_alias_vars here.
+ (pass_referenced_vars, pass_may_alias): New.
+ * tree-dump.c (dump_files): Remove optimization dumps.
+ (extra_dump_files, extra_dump_files_in_use): New.
+ (extra_dump_files_alloced): New.
+ (dump_register): New.
+ (get_dump_file_info): New.
+ (dump_begin, dump_enabled_p, dump_flag_name): Use it.
+ (dump_enable_all): Handle extra_dump_files.
+ (dump_switch_p_1): Split out from dump_switch_p.
+ (dump_switch_p): Handle extra_dump_files.
+ * tree-dump.h (dump_register): Declare.
+ * tree-eh.c: Include tree-pass.h
+ (lower_eh_constructs): Make static, take no args. Don't timevar,
+ don't dump function.
+ (pass_lower_eh): New.
+ * tree-flow.h (remove_useless_stmts, find_referenced_vars,
+ compute_may_aliases, lower_function_body, rewrite_out_of_ssa,
+ tree_ssa_ccp, tree_ssa_dominator_optimize, tree_ssa_dce,
+ tree_ssa_loop_opt, lower_eh_constructs, tree_sra): Remove.
+ (rewrite_into_ssa): Update decl.
+ * tree-mudflap.c: Include tree-pass.h.
+ (mudflap_function_decls): Make static, take no args, don't process
+ functions with mf_marked_p.
+ (mudflap_function_ops): Likewise.
+ (gate_mudflap, pass_mudflap_1, pass_mudflap_2): New.
+ (mudflap_enqueue_decl): Don't open dump file.
+ (mudflap_enqueue_constant): Likewise.
+ * tree-nomudflap.c: Include tree-pass.h.
+ (mudflap_c_function_decls, mudflap_c_function_ops): Remove.
+ (pass_mudflap_1, pass_mudflap_2): New.
+ * tree-optimize.c: Include tree-pass.h.
+ (optimize_function_tree): Remove.
+ (tree_dump_file, tree_dump_flags, vars_to_rename): New.
+ (all_passes): New.
+ (execute_gimple, pass_gimple): New.
+ (execute_rebuild_bind, pass_rebuild_bind): New.
+ (gate_all_optimizations, pass_all_optimizations): New.
+ (execute_del_cfg, pass_del_cfg): New.
+ (register_one_dump_file, register_dump_files): New.
+ (dup_pass_1, init_tree_optimization_passes): New.
+ (current_properties, last_verified): New.
+ (execute_todo, execute_one_pass, execute_pass_list): New.
+ (tree_rest_of_compilation): Remove -O0 passes.
+ * tree-sra.c: Include tree-pass.h, flags.h.
+ (tree_dump_file, tree_dump_flags, vars_to_rename): Remove.
+ (tree_sra): Make static, take no args. Don't timevar or dump file.
+ (gate_sra, pass_sra): New.
+ * tree-ssa-ccp.c: Include tree-pass.h, flags.h.
+ (tree_dump_file, tree_dump_flags): New.
+ (tree_ssa_ccp): Make static, take no args. Don't timevar or dump file.
+ (gate_ccp, pass_ccp): New.
+ (substitute_and_fold): Take no args.
+ * tree-ssa-dce.c: Include tree-pass.h, flags.h.
+ (tree_dump_file, tree_dump_flags): New.
+ (tree_ssa_dce): Make static, take no args. Don't open dump file.
+ (gate_dce, pass_dce): New.
+ * tree-ssa-dom.c: Include tree-pass.h, flags.h.
+ (tree_dump_file, tree_dump_flags, vars_to_rename): Remove.
+ (tree_ssa_dominator_optimize): Make static, take no args, don't
+ timevar, don't dump file.
+ (gate_dominator, pass_dominator): New.
+ * tree-ssa-loop.c: Include tree-pass.h, flags.h.
+ (tree_dump_file, tree_dump_flags): Remove.
+ (tree_ssa_loop_opt): Make static, take no args, don't open dump file.
+ (gate_loop, pass_loop): New.
+ * tree-ssa-pre.c: Include tree-pass.h, flags.h.
+ (tree_dump_file, tree_dump_flags): Remove.
+ (execute_pre): Rename from tree_perform_ssapre, make static,
+ take no args, don't timevar, don't open dump file, don't allocate
+ vars_to_rename.
+ (gate_pre, pass_pre): New.
+ * tree-ssa.c: Include tree-pass.h.
+ (tree_dump_file, tree_dump_flags, vars_to_rename): Remove.
+ (rewrite_into_ssa): Take no arguments, don't open dump file.
+ (rewrite_out_of_ssa): Make static, take no args, don't timevar,
+ don't open dump file. Disable TER if mudflap.
+ (pass_build_ssa, pass_del_ssa): New.
+ * tree-tailcall.c: Include tree-pass.h, flags.h.
+ (tree_dump_file, tree_dump_flags): Remove.
+ (tree_optimize_tail_calls_1): Rename from tree_optimize_tail_calls.
+ Make static, take only opt_tailcalls, don't dump file.
+ (execute_tail_recursion, gate_tail_calls, execute_tail_calls): New.
+ (pass_tail_recursion, pass_tail_calls): New.
+ * tree.h (enum tree_dump_index): Remove optimization dumps.
+ * Makefile.in (tree-alias-ander.o, tree-alias-common.o, tree-ssa.o,
+ tree-ssa-dom.o, tree-ssa-pre.o, tree-cfg.o, tree-tailcall.o,
+ tree-dfa.o, tree-eh.o, tree-ssa-loop.o, tree-optimize.o, gimple-low.o,
+ tree-mudflap.o, tree-ssa-dce.o, tree-ssa-ccp.o, tree-sra.o: Update
+ dependencies.
+
+2004-01-12 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mf_xform_derefs): Restore instrumentation of
+ RETURN_EXPRs.
+
+2004-01-11 Jan Hubicka <jh@suse.cz>
+
+ * tree-cfg.c (remove_usless_stmts_cond): Fold statement.
+ (remove_useless_stmts_1): Fold trees we know how to fold.
+
+2004-01-09 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (gimplify_constructor): Merge into ...
+ (gimplify_init_constructor): ... here. Handle COMPLEX_TYPE and
+ VECTOR_TYPE.
+ (gimplify_lhs_complex_part_expr): New.
+ (gimplify_modify_expr): Call it.
+ * tree-simple.c (is_gimple_rhs): Accept COMPLEX_EXPR.
+ * c-pretty-print.c (pp_c_initializer): Accept any type CONSTRUCTOR.
+ (pp_c_initializer_list): Fix code expectations for VECTOR_TYPE and
+ COMPLEX_TYPE.
+
+2004-01-09 Steven Bosscher <stevenb@suse.de>
+
+ PR optimization/13599
+ * tree-cfg.c (remove_useless_stmts_cond): Clear last-goto
+ before returning.
+
+2004-01-09 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (gimplify_asm_expr): Fix ordering of ASM_INPUTS.
+
+2004-01-09 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.h (cgraph_clone_inlined_nodes): Declare.
+ * cgraphunit.c (cgrpah_clone_inlined_nodes): Make global.
+ (cgraph_mark_inline_edge): Sanity check that size is positive.
+ (cgraph_decide_inlining): Fix typo.
+ * tree-optimize.c (tree_rest_of_compilation): Fix node duplication
+ code.
+
+2004-01-09 Jan Hubicka <jh@suse.cz>
+
+ * tree-inline.c (estimate_num_insns_1): Fix.
+
+2004-01-09 Richard Henderson <rth@redhat.com>
+
+ * tree-alias-ander.c, tree-cfg.c, tree-dfa.c, tree-mudflap.c,
+ tree-sra.c, tree-ssa-ccp.c, tree-ssa-dce.c, tree-ssa-dom.c,
+ tree-ssa-loop.c, tree-ssa-pre.c, tree-ssa.c, tree-tailcall.c: Rename
+ dump_file and dump_flags to tree_dump_file/flags.
+
+2004-01-08 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mf_build_string): Properly mf_mark string.
+ (mf_varname_tree): Remove redundant marking.
+ * tree-optimize.c (tree_rest_of_compilation): Skip mudflap processing
+ of mf_marked functions.
+ * c-mudflap.c (mflang_flush_calls): mf_mark synthetic function.
+
+2004-01-07 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (OBJS-common): Remove tree-must-alias.o
+ (tree-must-alias.o): Remove.
+ * common.opt (ftree-must-alias): Remove.
+ * flags.h (flag_tree_must_alias): Remove. Update all users.
+ * timevar.def (TV_TREE_MUST_ALIAS): Remove.
+ * toplev.c (f_options): Remove entry for -ftree-must-alias.
+ * tree-alias-common.c (local_alias_vars): Add GTY marker.
+ (local_alias_varnums): Likewise.
+ * tree-dfa.c (aliases_computed_p): Declare.
+ (dump_variable): Show variable UID and dereferenced bits.
+ (compute_may_aliases): Add arguments 'vars_to_rename' and 'phase'.
+ Do not call create_alias_vars.
+ Call promote_call_clobbered_vars
+ Do debugging dumps.
+ Set 'aliases_computed_p' to true before returning.
+ (create_memory_tags): Call may_be_aliased.
+ Mark new memory tags for renaming.
+ (compute_alias_sets): Don't do debugging dumps.
+ (find_variable_in): Move from tree-must-alias.c
+ (remove_element_from): Likewise.
+ (find_addressable_vars): Likewise
+ (promote_call_clobbered_vars): New.
+ (get_memory_tag_for): Mark the tag volatile if the pointed-to type
+ is volatile.
+ * tree-dump.c (dump_files): Remove entry for tree-mustalias.
+ Add entries for tree-ssa7, tree-dom3 and tree-dce3.
+ * tree-flow-inline.h (may_be_aliased): New.
+ * tree-flow.h (may_be_aliased): Declare.
+ (aliases_computed_p): Declare.
+ (tree_compute_must_alias): Remove.
+ * tree-must-alias.c: Remove.
+ * tree-optimize.c: Include tree-alias-common.h.
+ (optimize_function_tree): Call create_alias_vars before going into
+ SSA form.
+ Do not compute aliases until after the first DOM and DCE passes.
+ Run DOM and DCE once more after computing may-aliases.
+ * tree-ssa-dom.c (propagate_copy): Merge the dereferenced bit flags
+ when copy propagating pointers.
+ * tree-ssa-operands.c (get_stmt_operands): Assume that the
+ statement has no volatile operands.
+ (get_expr_operands): When processing an INDIRECT_REF expressions,
+ mark the statement as having volatile operands if aliases have not
+ been computed.
+ (add_stmt_operand): If the variable may be aliased and aliasing has
+ not been computed yet, mark the statement as having volatile
+ operands.
+ * tree-ssa.c (init_tree_ssa): Set aliases_computed_p to false.
+ (delete_tree_ssa): Likewise.
+ * tree.h (tree_dump_index): Remove TDI_mustalias.
+ Add TDI_dom_3, TDI_ssa_7 and TDI_dce_3.
+ * doc/invoke.texi: Remove must-alias documentation.
+
+2004-01-07 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dce.c (find_useful_stmts): Do not consider PHIs for
+ virtual operands inherently necessary.
+
+2004-01-07 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-dfa.c (free_df_for_stmt, free_df): New functions.
+ (compute_immediate_uses_for_stmt): Record uses in VDEFs.
+ * tree-flow.h (free_df, kill_redundant_phi_nodes): Declare.
+ * tree-optimize.c (optimize_function_tree): Call
+ kill_redundant_phi_nodes.
+ * tree-ssa-ccp.c (finalize): Call free_df.
+ * tree-ssa.c (replace_immediate_uses, raise_value,
+ kill_redundant_phi_nodes): New functions.
+
+2004-01-06 Jeff Law <law@redhat.com>
+
+ * tree.h (FUNCTION_RECEIVES_NONLOCAL_GOTO): Kill.
+ * tree-cfg.c (make_exit_edges, is_ctrl_altering_stmt): Use
+ current_function_has_nonlocal_label instead of
+ FUNCTION_RECEIVES_NONLOCAL_GOTO.
+ * gimplify.c (gimplify_expr): Set has_nonlocal_label in the
+ appropriate function's struct function rather than setting
+ a bit in the FUNCTION_DECL.
+
+2004-01-06 Jan Hubicka <jh@suse.cz>
+
+ * expr.c (string_constant): Recognize array_ref.
+
+2004-01-06 Richard Henderson <rth@redhat.com>
+
+ * builtins.c (builtin_save_expr): New.
+ (expand_builtin_mathfn, expand_builtin_mathfn_2,
+ expand_builtin_strcmp, expand_builtin_strncmp,
+ expand_builtin_strcat, fold_builtin_cabs): Use it.
+
+2004-01-06 Jan Hubicka <jh@suse.cz>
+
+ * fold-const.c (fold): Do not rebuild comparison when nothing
+ changed.
+
+2004-01-05 Jan Hubicka <jh@suse.cz>
+
+ * tree-ssa-ccp.c (ccp_fold_builtin): Return early for builtins
+ taking no arugment.
+
+2004-01-05 Steven Bosscher <steven@gcc.gnu.org>
+
+ * tree-ssa-dce.c: Clean up whitespace.
+
+ * tree-cfg.c (tree_verify_flow_info): Fix complaint about
+ missing or wrong labels in the targets of a conditional branch.
+
+2004-01-05 Richard Henderson <rth@redhat.com>
+
+ * tree-ssa-dom.c (record_equivalences_from_incoming_edge): Check
+ for signed zeros before recording value.
+ * Makefile.in (tree-ssa-dom.o): Depend on real.h.
+
+2004-01-05 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (cprop_into_stmt): Remove hack which prevented
+ copy propagation into statements with virtual operands, but no
+ real operands.
+
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize): Correctly handle
+ the case where an edge we wish to redirect is split by the out of SSA
+ code.
+
+2004-01-05 Richard Henderson <rth@redhat.com>
+
+ * c-tree.h (struct lang_type): Add enum_min, enum_max.
+ * c-decl.c (finish_enum): Set them. Set TYPE_MIN/MAX_VALUE to
+ the limits of the compatible type, not to the enumerators.
+ (check_bitfield_type_and_width): Use them.
+ (finish_struct): Clear allocated struct lang_type.
+ * gimplify.c (gimplify_switch_expr): Remove special handling of
+ outer cast in a switch.
+ * tree-ssa-dom.c (record_equivalences_from_incoming_edge): Likewise.
+
+2004-01-05 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (added_phis): Removed.
+ Remove gt-tree-ssa-pre.h.
+ (process_left_occs_and_kills): ASM_EXPR's block load pre.
+
+ * Makefile.in (GTFILES): Don't process tree-ssa-pre.c.
+ gt-tree-ssa-pre.h isn't a gtfile anymore.
+
+2004-01-05 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config.gcc (powerpc-*-darwin*): Make libbanshee rebuild
+ on PPC darwin.
+
+2004-01-05 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (gimplify_expr): Move check for error_mark inside
+ the main loop.
+
+2004-01-04 Jan Hubicka <jh@suse.cz>
+
+ * Makefile.in (cgraph.o, cgraphunit.o): Add intl.h dependency.
+ * cgraph.c (create_edge, dump_cgraph): Update to use inline_failed
+ * cgraph.h (cgraph_edge): Replace inline_call by inline_failed
+ (cgraph_inline_p): Add extra argument reason.
+ * cgraphunit.c: Minor formating fixes.
+ cgraph_first_inlined_callee): New functions.
+ (record_call_1): Record builtins too.
+ (cgraph_analyze_function): Update inline_failed messages.
+ (cgraph_mark_functions_to_output, cgraph_expand_function, cgraph_inlined_into,
+ cgraph_inlined_callees, cgraph_estimate_growth): Update to use inline_failed.
+ (cgraph_check_inline_limits): Likewise; Add argument reason.
+ (cgraph_set_inline_failed): New static function.
+ (cgraph_decide_inlining_of_small_function, cgraph_decide_inlining): Set
+ reasons.
+ (cgraph_inline_p): Add new argument reason.
+ * tree-inline.c (expand_call_inline): Update warning.
+
+2004-01-04 Andreas Jaeger <aj@suse.de>
+
+ * common.opt: Re-order some options in ASCII collating orders.
+
+2004-01-03 Richard Henderson <rth@redhat.com>
+
+ * toplev.c (rest_of_compilation): Fixup merge error wrt
+ check_function_return_warnings.
+
+ * tree.h (FUNCTION_RECEIVES_NONLOCAL_GOTO): Use unsigned_flag.
+
+2004-01-02 Jan Hubicka <jh@suse.cz>
+
+ * c-decl.c (duplicate_decls): Output DIE of extern inline function
+ only when it can be inlined.
+ * c-objc-common.c (c_disregard_inline_limits): When not inlining
+ extern inline functions do not disregard.
+ * cgraphunit.c (cgraph_analyze_function): When not inlining do not set
+ inline.
+ (cgraph_decide_inlining): Limit work done when not inlining.
+ (cgrpah_decide_inlining_incrementally): Likewise.
+ * tree-optimize.c (tree_rest_of_compilation): Do not call
+ optimize_inline_calls
+ when there is nothing to inline.
+
+2004-01-01 Richard Henderson <rth@redhat.com>
+
+ * c-common.c (c_expand_expr): Don't handle STMT_EXPR.
+ * c-objc-common.c (c_objc_common_finish_file): Use expand_expr.
+ * c-semantics.c (lang_expand_stmt, lang_expand_decl_stmt,
+ expand_cond, genrtl_do_pushlevel, genrtl_goto_stmt, genrtl_expr_stmt,
+ genrtl_expr_stmt_value, genrtl_decl_stmt, genrtl_if_stmt,
+ genrtl_while_stmt, genrtl_do_stmt_1, genrtl_do_stmt,
+ genrtl_return_stmt, genrtl_for_stmt, genrtl_break_stmt,
+ genrtl_continue_stmt, genrtl_scope_stmt, genrtl_switch_stmt,
+ genrtl_case_label, genrtl_compound_stmt, genrtl_asm_stmt,
+ genrtl_cleanup_stmt, expand_stmt, find_reachable_label,
+ find_reachable_label_1, expand_unreachable_if_stmt,
+ expand_unreachable_stmt): Remove.
+ * c-common.h: Update.
+
+2003-12-31 Richard Henderson <rth@redhat.com>
+
+ * c-mudflap.c (mflang_register_call): Remove.
+ (mflang_flush_calls): Use start_function/finish_function.
+ * tree-mudflap.c (mf_init_extern_trees): Tidy.
+ (mf_decl_cache_locals): Fix chaining for empty body.
+ (deferred_static_decl_labels): Remove.
+ (deferred_static_decls_init): Remove.
+ (mudflap_register_call): New.
+ (mudflap_enqueue_decl): Use it. Remove label argument.
+ (mudflap_enqueue_constant): Likewise.
+ (mudflap_finish_file): Update to match.
+ * tree-mudflap.h (mudflap_enqueue_decl): Remove label argument.
+ (mudflap_enqueue_constant): Likewise.
+ (mflang_register_call): Remove.
+ * tree-nomudflap.c (mudflap_enqueue_decl): Remove label argument.
+ (mudflap_enqueue_constant): Likewise.
+ * tree-optimize.c (tree_ssa_finish): Don't create NULL bodies.
+ * varasm.c (make_decl_rtl): Update mudflap_enqueue_decl call.
+ (output_constant_def_contents): Similarly for mudflap_enqueue_constant.
+
+2003-12-26 Sebastian Pop <s.pop@laposte.net>
+
+ * tree-cfg.c (print_loop, print_pred_bbs, print_succ_bbs,
+ debug_loop_ir, print_loop_ir): New.
+ * tree-flow.h (debug_loop_ir, print_loop_ir): Declare.
+
+2003-12-23 Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (tree_find_edge_insert_loc): Do not use the target
+ block as an insertion location if the target block has PHI nodes.
+
+2003-12-23 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_mark_inline): Accept argument edge; return
+ next edge not redirected.
+ (cgraph_recursive_inlining_p): Simplify.
+ (cgraph_decide_inlining*): Update calls of cgraph_mark_inline.
+
+2003-12-22 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * tree-alias-common.c (find_func_aliases): Do not call
+ intra_function_call for languages assuring no aliasing between
+ arguments (by themselves) and and global memory.
+
+2003-12-21 Jan Hubicka <jh@suse.cz>
+
+ * tree-ssa-ccp.c (fold_stmt): Return when there is no RHS
+ (get_rhs): Return for RETURN_EXPR with no operand.
+
+2003-12-21 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-cfg.c (tree_make_forwarder_block): Use split_block.
+ (tree_split_block): New.
+ (tree_cfg_hooks): Add tree_split_block.
+ (tree_loop_optimizer_init): Enable force_single_succ_latches.
+ * cfgloopmanip.c (loop_split_edge_with): Don't update dominators.
+ * cfgrtl.c (rtl_split_edge, cfg_layout_split_edge): Update dominators.
+
+2003-12-19 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-dfa.c (alias_stats_d): New structure.
+ (alias_stats): New variable.
+ (create_memory_tags): Zero out alias_stats.
+ (dump_alias_stats): New function.
+ (compute_alias_sets): Call it if TDF_STATS is set.
+ (may_alias_p): Collect the various statistics.
+
+2003-12-19 Diego Novillo <dnovillo@redhat.com>
+
+ * gimple-low.c (expand_var_p): Always expand volatiles.
+ * tree-dfa.c (find_referenced_vars): Move up in the file.
+ (create_memory_tags): New local function.
+ (compute_may_aliases): Call it.
+ (add_referenced_var): Move code to create memory tags and create
+ aliasing arrays to create_memory_tags.
+ (get_memory_tag_for): Don't mark memory tags volatile. Mark them
+ addressable.
+ * tree-flow.h (var_ann_d): Add bitfields is_dereferenced_store and
+ is_dereferenced_load.
+ (add_call_clobbered_var): Remove.
+ * tree-ssa-operands.c (check_optype_freelist): Mark arguments
+ unused.
+ (add_optype_freelist): Likewise.
+ (add_stmt_operand): Don't add operands for volatile variables.
+
+2003-12-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * dominance.c: Fix comment typos.
+ * et-forest.c: Likewise.
+ * et-forest.h: Likewise.
+ * tree-cfg.c: Likewise.
+ * tree-eh.c: Likewise.
+ * tree-mudflap.c: Likewise.
+ * tree-optimize.c: Likewise.
+ * tree-pretty-print.c: Likewise.
+ * tree-ssa-ccp.c: Likewise.
+ * tree-ssa-dom.c: Likewise.
+ * tree-ssa.c: Likewise.
+ * tree-tailcall.c: Likewise.
+ * tree.def: Likewise.
+ * tree.h: Likewise.
+
+2003-12-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/12453
+ * c-simplify.c (stmt_expr_last_stmt): Split out from...
+ (gimplify_stmt_expr): Here.
+ * c-common.h: Declare it.
+
+2003-12-18 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * et-forest.h (et_forest_create, et_forest_delete,
+ et_forest_add_node, et_forest_add_edge, et_forest_remove_node,
+ et_forest_remove_edge, et_forest_parent,
+ et_forest_common_ancestor, et_forest_node_value,
+ et_forest_enumerate_sons): Declarations removed.
+ (struct et_node): New.
+ (et_new_tree, et_free_tree, et_set_father, et_split, et_nca,
+ et_below): Declare.
+ * et-forest.c (struct et_forest_occurrence, struct et_forest,
+ struct et_forest_node): Removed.
+ (et_forest_create, et_forest_delete,
+ et_forest_add_node, et_forest_add_edge, et_forest_remove_node,
+ et_forest_remove_edge, et_forest_parent,
+ et_forest_common_ancestor, et_forest_node_value,
+ et_forest_enumerate_sons, splay, remove_all_occurrences,
+ find_leftmost_node, find_rightmost_node, calculate_value): Removed.
+ (struct et_occ): New.
+ (et_nodes, et_occurences): New.
+ (set_depth, set_depth_add, set_prev, set_next, et_recomp_min,
+ et_check_occ_sanity, et_check_sanity, et_check_tree_sanity,
+ record_path_before_1, record_path_before, check_path_after_1,
+ check_path_after, et_splay, et_new_occ, et_new_tree,
+ et_free_tree, et_set_father, et_split, et_nca, et_below): New.
+ * basic-block.h (struct basic_block_def): New field dom.
+ (struct dominance_info): Type removed.
+ (calculate_dominance_info, free_dominance_info,
+ nearest_common_dominator, set_immediate_dominator,
+ get_immediate_dominator, dominated_by_p, get_dominated_by,
+ add_to_dominance_info, delete_from_dominance_info,
+ recount_dominator, redirect_immediate_dominators,
+ iterate_fix_dominators, verify_dominators): Declarations
+ changed.
+ (enum dom_state): New.
+ (dom_computed): New variable.
+ (first_dom_son, next_dom_son): Declare.
+ * dominance.c (struct dominance_info): Removed.
+ (BB_NODE, SET_BB_NODE): Removed.
+ (calculate_dominance_info, free_dominance_info,
+ nearest_common_dominator, set_immediate_dominator,
+ get_immediate_dominator, dominated_by_p, get_dominated_by,
+ add_to_dominance_info, delete_from_dominance_info,
+ recount_dominator, redirect_immediate_dominators,
+ iterate_fix_dominators, verify_dominators,
+ debug_dominance_info): Work over new datastructure. Access
+ dominance datastructures through CFG.
+ (assign_dfs_numbers, compute_dom_fast_query, first_dom_son,
+ next_dom_son): New.
+ * tree-cfg.c (pdom_info): Variable removed.
+ (create_bb): Add the block to the dominance information.
+ (cleanup_tree_cfg): Let updating of the dominance on the
+ individual passes.
+ (remove_bb): Don't handle pdom.
+ (cleanup_control_expr_graph, tree_make_forwarder_block,
+ thread_jumps): Invalidate the dominators.
+ (tree_split_edge): Update the dominators.
+ (compute_dominance_frontiers_1, compute_dominance_frontiers,
+ tree_verify_flow_info, tree_loop_optimizer_init): Use the new
+ interface to dominators.
+ * domwalk.c (walk_dominator_tree): Do not use dom_children.
+ * tree-flow-inline.h (add_dom_child, remove_dom_child,
+ clear_dom_children, dom_children): Removed.
+ * tree-flow.h (struct bb_ann_d): Dom_children field removed.
+ (add_dom_child, dom_children, build_dominator_tree): Declaration
+ removed.
+ (compute_dominance_frontiers): Declaration changed.
+ * tree-optimize.c (optimize_function_tree): Free dominance
+ information in the end.
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize,
+ dom_opt_finalize_block): Do not use dom_children.
+ * tree-ssa-pre.c (fast_a_dominates_b, build_dfs_id_array_1,
+ build_dfs_id_array): Removed.
+ (pre_idom, dfs_id, dfs_id_last): Variables removed.
+ (build_dfn_array): Do not use dom_children.
+ (eref_compare, load_modified_phi_result, rename_1, reaching_def,
+ finalize_1, collect_expressions, tree_perform_ssapre): Use the
+ new interface to the dominance information.
+ * tree-ssa.c (struct mark_def_sites_global_data): Idom field
+ removed.
+ (set_livein_block, verify_use, verify_phi_args,
+ rewrite_into_ssa, mark_def_sites, verify_ssa): Use the new
+ interface to the dominance information.
+ (build_dominator_tree): Removed.
+ * tree-tailcall.c (tree_optimize_tail_calls): Invalidate
+ dominance information.
+ * bt-load.c (dom): Variable removed.
+ (augment_live_range, combine_btr_defs, migrate_btr_def,
+ migrate_btr_defs, branch_target_load_optimize): Updated for the
+ new interface for dominance information.
+ * cfglayout.c (copy_bbs): Removed loops argument. Updated for
+ the new interface for dominance information.
+ * cfglayout.h (copy_bbs): Declaration changed.
+ * cfgloop.c (flow_loop_pre_header_find, flow_loops_cfg_dump,
+ flow_loop_scan, canonicalize_loop_headers, flow_loops_find): Updated
+ for the new interface for dominance information.
+ (flow_loop_scan): Loops argument removed.
+ (flow_loops_free): Don't release dominators.
+ * cfgloop.h (struct cfg): Dom field removed.
+ (flow_loop_scan, loop_split_edge_with, simple_loop_p,
+ just_once_each_iteration_p, split_loop_bb): Declaration changed.
+ * cfgloopanal.c (simple_loop_exit_p, simple_increment,
+ just_once_each_iteration_p, simple_loop_p): Remove loops argument.
+ Updated for the new interface for dominance information.
+ * cfgloopmanip.c (remove_bbs, find_path, create_preheader,
+ split_loop_bb, loopify, duplicate_loop_to_header_edge,
+ force_single_succ_latches, loop_split_edge_with): Ditto.
+ (create_loop_notes): Free the dominators.
+ * gcse.c (dominators): Variable removed.
+ (free_code_hoist_mem, compute_code_hoist_data, hoist_code):
+ Updated for the new interface for dominance information.
+ * ifcvt.c (post_dominators): Variable removed.
+ (mark_loop_exit_edges, merge_if_block, find_if_header,
+ find_cond_trap, find_if_case_1, find_if_case_2, if_convert):
+ Updated for the new interface for dominance information.
+ * loop-init.c (rtl_loop_optimizer_init,
+ rtl_loop_optimizer_finalize): Ditto.
+ * loop-unroll.c (decide_peel_simple, decide_peel_once_rolling,
+ decide_peel_completely, decide_unroll_stupid,
+ decide_unroll_constant_iterations,
+ decide_unroll_runtime_iterations): Loops argument removed.
+ Updated for the new interface for dominance information.
+ (unroll_and_peel_loops, peel_loops_completely,
+ unroll_loop_runtime_iterations): Updated for the new interface for
+ dominance information.
+ * loop-unswitch.c (may_unswitch_on_p, unswitch_loops,
+ unswitch_single_loop, unswitch_loop): Updated for the new
+ interface for dominance information.
+ * predict.c (process_note_predictions, process_note_prediction,
+ estimate_probability, note_prediction_to_br_prob): Ditto.
+ * sched-rgn.c (find_rgns, init_regions): Ditto.
+ * toplev.c (rest_of_handle_branch_prob): Free the dominators.
+
+2003-12-18 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (edges_to_redirect, redirection_targets): Merged
+ into a single varray "redirection_edges".
+ (tree_ssa_dominator_optimize): Twiddle initialization, finalization
+ and accessors to redirection information based on combining varrays.
+ Get the threading destination from the saved edge rather than from a
+ saved block. Mark variables appearing in PHIs at the jump thread
+ destination to be taken out of SSA form.
+ (thread_across_edge): Save the edge into the destination block
+ rather than the destination block itself. Twiddle based on
+ combining varrays of jump threading information.
+ * tree-flow.h (tree_block_forwards_to): Returns an edge rather than
+ a block.
+ * tree-cfg.c (tree_block_forwards_to): Return the edge leading to
+ the target block rather than the target block itself.
+
+2003-12-18 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-dfa.c (get_memory_tag_for): Don't put things with different
+ points-to sets in the same memory tag.
+
+2003-12-18 Jan Hubicka <jh@suse.cz>
+
+ * c-common.c (handle_nonnull_attribute, check_function_nonnull):
+ Initialize arg_num.
+ * c-format.c (handle_format_attribute): Initialize format_num.
+ * rtlanal.c (get_related_value): Initialize get_jump_table_offset
+
+2003-12-18 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * stmt.c (expand_start_loop, expand_loop_continue_here,
+ expand_end_loop): Don't create loop notes.
+
+2003-12-18 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+ Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (tree_node_shared_p): Explicitly allow sharing of
+ CST nodes.
+ * tree-simple.c (is_gimple_rhs): Allow CST nodes.
+ (is_gimple_min_invariant): Reject constants with TREE_OVERFLOW set.
+ * tree-ssa-ccp (visit_assignment): Test is_gimple_min_invariant
+ after munging bitfields.
+ * tree-ssa-dom.c (record_equivalences_from_stmt): Similarly.
+
+2003-12-17 Jan Hubicka <jh@suse.cz>
+
+ Based on patch by Dale Johannesen
+ * expr.c (MOVE_RATIO, CLEAR_RATIO): Move to ...
+ * expr.h (MOVE_RATIO, CLEAR_RATIO): ... here
+
+2003-12-17 Jan Hubicka <jh@suse.cz>
+
+ * Makefile.in (sibcall.o): Kill.
+ (tree-tailcall.o): Add except.h dependency
+ * sibcall.c: Kill.
+ (purge_reg_equiv_notes, purge_mem_unchanging_flag): Move to ...
+ * calls.c (purge_reg_equiv_notes, purge_mem_unchanging_flag) ... here.
+ (expand_call): Do not produce placeholders; do not deal with tail
+ recursion; set tail_call_emit.
+ (fixup_tail_calls): New.
+ * expr.h (fixup_tail_calls): Declare.
+ * toplev.c (rest_of_handle_sibling_calls): Kill.
+ (rest_of_compialtion): Do not use rest_of_handle_sibling_calls;
+ call fixup_tail_calls.
+ * tree-dump.c (dump_files): Add tail2
+ * tree-flow.h (tree_optimize_tail_calls): Update prototype.
+ * tree-optimize.c (optimize_function_tree): Do tail optimization twice.
+ * tree-tailcall.c: Inlucde except.h
+ (suitable_for_tail_call_opt_p): New.
+ (optimize_tail_call): Add opt_tailcalls argument; optimize tailcalls.
+ (tree_optimize_tail_calls): Add opt_tailcalls/pass arguments.
+ * tree.h (CALL_EXPR_TAILCALL): New.
+ (tree_dump_index): Add tail2
+ * function.h (struct function): Add tail_call_emit field.
+
+2003-12-17 Jan Hubicka <jh@suse.cz>
+
+ * tree-inline.c (estimate_num_insns_1): Check that all nodes are
+ known; add missing nodes; fix MODIFY_EXPR
+
+2003-12-16 Jason Merrill <jason@redhat.com>
+
+ PR middle-end/12920
+ * stor-layout.c (layout_type): Just return if type is
+ error_mark_node.
+ * c-decl.c (grokdeclarator): Immediately layout an
+ ARRAY_TYPE used in a pointer-to-array declarator.
+
+2003-12-16 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (may_alias_p): If VAR and PTR are pointers with the
+ same alias set, return false.
+ (get_memory_tag_for): Group based on alias set classes, not on
+ conflicting alias sets.
+ * tree-must-alias.c (promote_var): Don't bring aliases over when
+ all the may-aliases of a non-promotable variable are promoted.
+
+2003-12-16 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-flow-inline.h (free_vuse, free_vdefs): Moved to
+ tree-ssa-operands.c
+ (get_def_ops, get_use_ops, get_vdef_ops, get_vuse_ops): Use the new
+ more direct structure pointer.
+ (get_use_op_ptr, get_def_op_ptr): Cast is no longer necessary.
+ * tree-flow.h (struct stmt_ann_d): Replace operands and voperands
+ pointers with pointers directly to the operand types.
+ * tree-ssa-dom.c (cprop_into_stmt): Use new stmt based interface to
+ free virtual operands. Check virtual bases of both VUSE and VDEF.
+ * tree-ssa-operands.c (struct voperands_d): Declare here, used only
+ for previous_vops during stmt operand construction.
+ (struct vecmanage_d, vecmanage_add_segmen, vecmanage_add_special,
+ vecmanage_init, vecmanage_tree_ptr_init, vecmanage_fini, check_free,
+ vecmanage_new_vector, vecmanage_new_tree_ptr_vector,
+ vecmanage_free_vector): Remove.
+ (allocate_ssa_op_vec, free_ssa_op_vec, allocate_ssa_virtual_op_vec,
+ allocate_operands_t, allocate_voperands_t): Remove.
+ (finalize_new_ssa_operands, inalize_new_ssa_virtual_operand): Remove.
+ (struct freelist_d): New. List of free operand structures.
+ (check_optype_freelist): New. Choose memory from freelist, if available.
+ (add_optype_freelist): New. Add structure to freelist, if appropriate.
+ (allocate_def_optype): New. Allocate a def operand list from GC.
+ (allocate_use_optype): New. Allocate a useoperand list from GC.
+ (allocate_vdef_optype): New. Allocate a vdef operand list from GC.
+ (allocate_vuse_optype): New. Allocate a vuse operand list from GC.
+ (free_uses, free_defs, free_vuses, free_vdefs): Use GC and the freelist.
+ (remove_vuses, remove_vdefs): New. External interface to remove virtual
+ operands.
+ (init_ssa_operands, fini_ssa_operands): Ensure the free list is empty.
+ (finalize_ssa_defs, finalize_ssa_use, finalize_ssa_vdefs,
+ finalize_ssa_vuses): Use new direct pointers from the stmt annotation.
+ (append_vdef, append_vuse): No need to hack prev_vops pointer now.
+ (get_stmt_operands): use new freeing interface, keep previous vops in
+ their own local structure for now, passing its address around.
+ * tree-ssa-operands.h (struct def_optype_d, struct use_optype_d,
+ struct vdef_optype_d, struct vuse_optype_d): Implement as a single
+ dynamically allocated structure.
+ (struct operands_d, struct operands_d): Remove.
+ * tree-ssa-pre.c (subst_phis): Remove virtual operands using new funcs.
+
+2003-12-16 Jan Hubicka <jh@suse.cz>
+
+ * tree-cfg.c (verify_addr_expr): Rename to ....
+ (verify_expr): ... this one; check that no SSA names are on
+ freelist.
+ (verify_stmt, verify_stmts): Update calls of verify_addr_expr.
+
+ Revert until initializers are made language independent:
+ * cgraphunit.c (record_call_1): Do not call analyze_expr hook
+ * langhooks-def.h (LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR): Kill.
+ (LANG_HOOKS_CALLGRAPH_INITIALIZER): Update.
+ * longhooks.h (lang_hooks_for_callgraph): Kill analyze_expr.
+
+2003-12-16 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-pretty-print.c (dump_bb_header): Show block number when
+ there is no label.
+ (pp_cfg_jump): Show labels in addition to block numbers.
+ (dump_generic_bb_buff): Always call dump_bb_header.
+
+2003-12-16 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_remove_unreachable_nodes): Fix typo;
+ improve comments; cleanup linked list mantenance.
+
+2003-12-15 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-sra.c (can_be_scalarized_p): Reject volatile variables.
+
+ * sibcall.c (skip_copy_to_return_value): Initialize 'hardret' and
+ 'softret'.
+
+2003-12-16 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_remove_node): Ignore DECL_EXTERNAL clones.
+ * cgraphunit.c (verify_cgraph_node): Do not insist on unemmited extern
+ inline functions to be valid.
+ (cgraph_finalize_compilation_unit): Fix ordering.
+ (cgraph_mark_functions_to_output): Do not insist on DECL_EXTERNAL
+ nodes to be reclaimed.
+ (cgraph_remove_unreachable_nodes): New function.
+ (cgraph_decide_inlining): use it.
+
+2003-12-15 Andrew MacLeod <amacleod@redhat.com>
+
+ * Makefile.in (TREE_FLOW_H): Add dependence on tree-ssa-operands.h
+ (OBJS-common): Add tree-ssa-operands.o
+ (tree-ssa-operands.o): Add dependencies.
+ (GTFILES): Add tree-ssa-operands.[ch].
+ * tree-dfa.c (get_stmt_operands, get_expr_operands, add_stmt_operand,
+ note_addressable, add_def, add_use, add_vde, add_vuse,
+ add_call_clobber_ops, add_call_read_ops): Moved to tree-ssa-operands.c.
+ (compute_immediate_uses_for_stmt): Use new optypes interface.
+ (cleanup_operand_arrays): Delete.
+ (collect_dfa_stats_r): Use new optypes interface.
+ (get_call_flags): Moved to tree-ssa-operands.c.
+ (vdefs_disappeared_p, mark_new_vars_to_rename): Use optypes interface.
+ * tree-flow-inline.h (def_ops, use_ops, vdef_ops, vuse_ops): Use new
+ optypes.
+ (free_vuses): New. Clear and release vuses.
+ (free_vdefs): New. Clear and release vdefs.
+ (get_use_ops_ptr): New. Get address of a use op.
+ (get_def_ops_ptr): New. Get address of a use op.
+ (get_vdef_result_ptr): New. Get address of a use op.
+ (get_vdef_op_ptr): New. Get address of a use op.
+ (get_vuse_op_ptr): New. Get address of a use op.
+ (start_ssa_stmt_operands): New. Entry point to start processing stmt
+ operands.
+ * tree-flow.h (struct operands_d, struct voperands_d): Move to
+ tree-ssa-operands.h
+ (struct stmt_ann_d): Add GTY markers to operands.
+ * tree-pretty-print.c (dump_vops): Use optypes interface.
+ * tree-sra.c (create_scalar_copies): Use optypes interface.
+ (scalarize_structures, scalarize_modify_exp): Use optypes interface.
+ * tree-ssa-ccp.c (visit_stmt, ccp_fold, initialize, replace_uses_in,
+ likely_value, set_rhs): Use optypes interface.
+ * tree-ssa-dce.c (find_useful_stmts, stmt_useful_p, process_worklist):
+ Use optypes interface.
+ * tree-ssa-dom.c (thread_across_edge, thread_jumps_walk_stmts): Use
+ optypes interface.
+ (cprop_into_stmt): Rewrite using new interface.
+ (eliminate_redundant_computations, record_equivalences_from_stmt,
+ optimize_stmt, avail_expr_hash, avail_expr_eq): Use optypes interface.
+ * tree-ssa-live.c (create_ssa_var_map, calculate_live_on_entry,
+ build_tree_conflict_graph,register_ssa_partitions_for_vars): Use
+ optypes interface.
+ * tree-ssa-pre.c (names_match_p, maybe_find_rhs_use_for_var,
+ expr_phi_insertion, same_e_version_real_occ_real_occ, opnum_of_phi,
+ generate_expr_as_of_bb, generate_vops_as_of_bb, subst_phis,
+ load_modified_real_occ_real_occ, same_e_version_phi_result, can_insert,
+ get_default_def, reaching_def, process_left_occs_and_kills,
+ collect_expressions): Use optypes interface.
+ * tree-ssa.c (mark_def_sites, check_replaceable, find_replaceable_in_bb,
+ dump_replaceable_exprs, rewrite_trees, verify_ssa, rewrite_stmt): Use
+ optypes interface.
+ (init_tree_ssa): Initialize new operand data structures.
+ (delete_tree_ssa): Free new operand structures.
+ * tree.h (VDEF_RESULT, VDEF_OP, NUM_VDEFS): Move to tree-ssa-operands.h.
+
+ * tree-ssa-operands.h: New file.
+ (struct def_optype_d): New. Structure for stmt defs.
+ (struct use_optype_d): New. Structure for stmt uses.
+ (struct vdef_optype_d): New. Structure for stmt vdefs.
+ (struct vuse_optype_d): New. Structure for stmt vuses.
+ (USE_OPS, STMT_USE_OPS, NUM_USES, USE_OP_PTR, USE_OP): Macros to
+ access stmt uses.
+ (DEF_OPS, STMT_DEF_OPS, NUM_DEFS, DEF_OP_PTR, DEF_OP): Macros to
+ access stmt defs.
+ (VDEF_OPS, STMT_VDEF_OPS, NUM_VDEFS, VDEF_RESULT_PTR, VDEF_RESULT,
+ VDEF_OP_PTR, VDEF_OP): Macros to access stmt vdefs.
+ (VUSE_OPS, STMT_VUSE_OPS, NUM_VUSES, VUSE_OP_PTR, VUSE_OP): Macros to
+ access stmt vuses.
+ (struct operands_d, struct voperands_d): moved from tree-dfa.c.
+ * tree-ssa-operands.c: New file.
+ (build_defs, build_uses, build_vdefs, build_vuses): New static varrays.
+ (struct vecmanage_d): New. Struct to manage non-GC vectors.
+ (vecmanage_add_segment): New. Add a new segment to a vector manager.
+ (vecmanage_add_special): New. Add a large vector to the special list.
+ (vecmanage_init): Initialize a vector manager.
+ (vecmanage_tree_ptr_init): New. Initialize a vector manager for tree *.
+ (vecmanage_fini): New. Release vector manager memory.
+ (check_free): New. Look for free memory in the vector maanger.
+ (vecmanage_new_vector): New. Allocate a vector.
+ (vecmanage_new_tree_ptr_vector): New. Allocate a vector of 'tree *'.
+ (vecmanage_free_vector): New. Free a vector.
+ (free_ssa_op_vec): New. Free an ssa operand's memory.
+ (allocate_ssa_op_vec): New. Allocate a vector for use/defs.
+ (allocate_ssa_virtual_op_vec): New. Allocate a vector for vuse/vdefs.
+ (allocate_operands_t): New. Allocate an operand structure.
+ (allocate_voperands_t): New. Allocate a virtual operand structure.
+ (free_uses): New. Clear and release uses.
+ (free_defs): New. Clear and release defs.
+ (init_ssa_operands): New. Initialize ssa operand management.
+ (fini_ssa_operands): New. Cleanup ssa operand management.
+ (finalize_new_ssa_operands): New. Commit current operands.
+ (finalize_new_ssa_virtual_operands): New. Commit current virtual ops.
+ (finalize_ssa_defs): New. Commit and verify stmt definitions.
+ (finalize_ssa_uses): New. Commit and verify stmt uses.
+ (finalize_ssa_vdefs): New. Commit and verify stmt virtual definitions.
+ (finalize_ssa_vuses): New. Commit and verify stmt virtual uses.
+ (finalize_ssa_stmt_operands): New. Commit all stmt operands.
+ (verify_start_operands): New. Verify build mechanism is ready for a new
+ stmt.
+ (append_def): Renamed from add_def, and moved from tree-dfa.c.
+ (append_use): Renamed from add_def, and moved from tree-dfa.c.
+ (append_vdef): Renamed from add_def, and moved from tree-dfa.c.
+ (append_vuse): Renamed from add_def, and moved from tree-dfa.c.
+ (add_vuse): New. Entry point to add a vuse to a stmt.
+ (get_call_flags): Moved from tree-dfa.c
+ (get_stmt_operands, get_expr_operands, add_stmt_operand): Moved from
+ tree-dfa.c, and use new optype interface.
+ (note_addressabe, add_call_clobber_ops, add_call_read_ops): Moved from
+ tree-dfa.c
+
+2003-12-15 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-optimize.c (optimize_function_tree): Call BITMAP_XFREE.
+
+2003-12-15 Diego Novillo <dnovillo@redhat.com>
+
+ PR optimization/12747
+
+ * tree-cfg.c (verify_addr_expr): Simplify predicates.
+ * tree-must-alias.c (addresses_needed): Declare as file local.
+ (can_be_promoted): New.
+ (tree_compute_must_alias): Call it.
+ Remove promoted variables from call_clobbered_vars.
+ (find_addressable_vars): Update comment.
+ Remove argument. Update callers.
+ (promote_var): Always clear TREE_ADDRESSABLE.
+ Don't remove promoted variables from call_clobbered_vars.
+ If the promoted variable is in the may-alias set of a
+ non-promotable variable, copy its alias set into the alias set of
+ the non-promotable variable.
+ (find_variable_in): Update comment.
+ * tree-sra.c (can_be_scalarized_p): Reject structures with
+ __complex__ fields in them.
+
+2003-12-15 Diego Novillo <dnovillo@redhat.com>
+ Jason Merrill <jason@redhat.com>
+
+ PR optimization/12747
+
+ * Makefile.in (tree-simple.o): Add dependency on bitmap.h and
+ $(GGC_H).
+ (GTFILES): Add tree-simple.c.
+ * tree-simple.c: Include ggc.h and bitmap.h.
+ (is_gimple_non_addressable_1): Remove. Update all callers.
+ (types_checked): New local variable.
+ (types_in_memory): New local variable.
+ (struct_needs_to_live_in_memory): New.
+ (needs_to_live_in_memory): New.
+ (is_gimple_reg): Call it.
+ (is_gimple_non_addressable): Call it.
+ (is_gimple_call_clobbered): Call it.
+ * tree-simple.h (needs_to_live_in_memory): Declare.
+
+2003-12-14 Andreas Jaeger <aj@suse.de>
+
+ * config/rs6000/rs6000.c (rs6000_output_function_epilogue): Handle
+ GNU F95.
+
+2003-12-14 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_expand_function): Release function body when no
+ longer needed.
+ (lookup_recursive_calls): New function.
+ (cgraph_decide_recursive_inlining): Likewise.
+ (cgraph_decide_inlining_of_small_functions): Do recursive inlining.
+ * tree-inline.c: Include function.h
+ (copy_body): Choose saved body for recursive inlining.
+ (initialize_inlined_parameters): Likewise.
+ (expand_call_inline): Do not verify nodes when recursivly inlining,
+ insert ret_label into decl map.
+ * params.def (PARAM_MAX_INLINE_INSNS_RECURSIVE,
+ PARAM_MAX_INLINE_INSNS_RECURSIVE_AUTO,
+ PARAM_MAX_INLINE_RECURSIVE_DEPTH,
+ PARAM_MAX_INLINE_RECURSIVE_DEPTH_AUTO): New argument.
+ * invoke.texi (max-inline-insns-recursive, max-inline-recursive-depth):
+ Document.
+ * Makefile.in (tree-inline.o): Include function.h.
+
+2003-12-14 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (record_call_1): Do not call analyze_expr hook
+ * langhooks-def.h (LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR): Kill.
+ (LANG_HOOKS_CALLGRAPH_INITIALIZER): Update.
+ * longhooks.h (lang_hooks_for_callgraph): Kill analyze_expr.
+
+2003-12-13 Jan Hubicka <jh@suse.cz>
+
+ * timevar.def (TV_TREE_STMT_VERIFY, TV_CFG_VERIFY, TV_CGRAPH_VERIFY):
+ New timers.
+ * tree-cfg.c (verify_stmts): Push/pop timevar.
+ * cfg.c: Include timevar.h
+ (verify_flow_info): Push/pop timevar.
+ * Makefile.in (cfg.o): Add dependnecy on TIMEVARS
+
+ * cgraph.c (cgraph_create_edge): Sanity check for duplicates;
+ initialize aux.
+ (cgraph_remove_node): Decrease cgraph_n_nodes; do not clear
+ DECL_SAVED_TREE when dumping.
+ (cgraph_dump_node): Break out from ...; print more information.
+ (cgraph_dump): ... here.
+ * cgraph.h (cgraph_node): Add aux field.
+ (dump_cgraph_node, verify_cgraph, verify_cgraph_node): Declare.
+ (cgraph_mark_inline_edge): Declare
+ * cgraphunit.c (error_found): New static variable.
+ (verify_cgraph_node_1): New static function.
+ (verify_cgraph_node, verify_cgraph): New global function.
+ (cgraph_expand_function): More sanity checks.
+ (cgraph_clone_inline_nodes): Destructivly clone DECL_EXTERNAL nodes.
+ (cgraph_mark_inline_edge): Make global.
+ (cgraph_decide_inlining): Remove extern inline functions never inlined.
+ (cgraph_decide_inlining_incrementally): Verify that function body is
+ still present.
+ (expand_all_functions): Verify that all nodes are reachable.
+ (cgraph_optimize): Verify cgraph and memory management.
+ * tree-inline.c (copy_body_r): All edges must be present.
+ (expand_call_inline): Sanity check newly created edges and nodes
+ being inlined.
+ (optimize_inline_calls): Sanity check that we've inlined everything.
+ * tree-optimize.c (tree_rest_of_compilation): Clone functions inlined
+ into cloned node.
+
+2003-12-13 Jan Hubicka <jh@suse.cz>
+
+ * tree-flow.h (tree_ssa_useless_type_conversion_1): Declare.
+ * tree-flow.c (tree_ssa_useless_type_conversion_1): Break out from
+ from...; allow complex types whose subtypes match.
+ (tree_ssa_useless_type_conversion): ... here.
+
+2003-12-12 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (optimize_stmt): Don't call cleanup_control_expr
+ here. Instead just note that we need to cleanup the cfg (which
+ will DTRT).
+
+ * timevar.def (TV_TREE_SSA_THREAD_JUMPS): Kill.
+ * tree-dump.c (dump_files): Kill .thread dump.
+ * tree.h (TDI_thread_jumps): Kill.
+ * tree-flow.h (tree_ssa_dominator_thread_jumps): Kill prototype.
+ * tree-optimize.c (optimize_function_tree): Kill call to
+ tree_ssa_dominator_thread_jumps.
+ * tree-ssa-dom.c (thread_through_phis): Kill. We no longer need
+ to restrict threading through PHIs.
+ (tree_ssa_dominator_thread_jumps): Kill.
+ (tree_ssa_domiantor_optimize_1): Fold back into
+ tree_ssa_dominator_optimize.
+ (tree_ssa_dominator_optimize): Mark back edges in the flow graph.
+ Kill code which conditionalized the walk_tree callbacks based
+ on thread_through_phis. When threading jumps, reorganize code
+ so that we can take the affected variables out of SSA form.
+ Mark new variables created by out-of-ssa code as needing to be
+ rewritten.
+ (thread_across_edge): Always allow threading through phis.
+ (thread_jumps_walk_stmts): Kill.
+
+ * tree-ssa.c (create_temp): When we create a new temporary, make
+ sure to put it into referenced_vars, give it an ID number and
+ a suitable mem_tag.
+ (eliminate_build): If we encounter a PHI argument which is an
+ SSA_VAR we are not rewriting out of SSA form, then just treat
+ it like a constant.
+ (rewrite_vars_out_of_ssa): New function.
+ * tree-flow.h (rewrite_vars_out_of_ssa): Prototype.
+ * tree-ssa-live.c (register_ssa_partitions_for_vars): New function.
+ * tree-ssa-live.h (register_ssa_partitions_for_vars): Prototype.
+
+2003-12-12 Jan Hubicka <jh@suse.cz>
+
+ * tree-inline.c (remap_decl): Avoid invalid sharing.
+ * cp-tree.h (optimize_function): Kill.
+ * optimize.c (optimize_function): Kill.
+ * semantics.c (expand_body): Do not call optimize_function.
+
+2003-12-12 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_optimize): Do not decide inlining when not
+ inlining
+
+2003-12-11 Jan Hubicka <jh@suse.cz>
+
+ * tree-inline.c (initialize_inlined_parameters): Disable
+ constant propagation for non-gimple-min-invariant when
+ preserving gimple form.
+
+2003-12-11 Jeff Law <law@redhat.com>
+
+ * tree-ssa-ccp.c (widen_bitfield): Clear out unwanted high bits
+ even if the field's type is unsigned.
+ * tree-ssa-dom.c (record_equivalences_from_stmt): When creating
+ equivalences from stores, be more careful about non-constant
+ stores to bitfields.
+
+2003-12-11 Diego Novillo <dnovillo@redhat.com>
+
+ * opts.c (decode_options): Do not enable the tree loop optimizer by
+ default.
+ * tree-ssa-loop.c (tree_ssa_loop_opt): Remove ENABLE_CHECKING
+ guards.
+
+2003-12-10 Richard Henderson <rth@redhat.com>
+
+ * builtins.c (expand_builtin_profile_func): New.
+ (expand_builtin): Use it.
+ * builtins.def (BUILT_IN_PROFILE_FUNC_ENTER): New.
+ (BUILT_IN_PROFILE_FUNC_EXIT): New.
+ * function.c (expand_function_start, expand_function_end): Don't
+ do function instrumentation here.
+ * gimplify.c (gimplify_function_tree): Do it here.
+
+ * c-opts.c (c_common_post_options): Don't ever use rtl inlining.
+
+2003-12-10 Diego Novillo <dnovillo@redhat.com>
+
+ * ifcvt.c (dead_or_predicable): Initialize local variable
+ 'earliest'.
+ * tree-cfg.c (verify_stmt): Fix typo.
+ * tree-ssa-dom.c (propagate_value): New local function.
+ (cprop_into_stmt): Call it.
+ (cprop_into_phis): Call it.
+ (eliminate_redundant_computations): Call it.
+
+2003-12-10 Dale Johannesen <dalej@apple.com>
+
+ * tree-dfa.c (compute_alias_sets): Don't try to make
+ GLOBAL_VAR alias itself.
+
+2003-12-08 Steven Bosscher <stevenb@suse.de>
+
+ * tree-must-alias.c (tree_compute_must_alias): Use
+ num_call_clobbered_vars and call_clobbered_var() instead of
+ poking in the call_clobbered_vars varray directly.
+
+2003-12-11 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_function_possibly_inlined_p): Fix syntax error on
+ gcc-2.95.
+
+2003-12-10 Diego Novillo <dnovillo@redhat.com>
+
+ Revert
+
+ 2003-12-07 Richard Henderson <rth@redhat.com>
+
+ * c-common.c (c_address_looks_like_offsetof): New.
+ * c-common.h (c_address_looks_like_offsetof): Declare.
+ * c-typeck.c (build_unary_op) <ADDR_EXPR>: Use it. Don't lower
+ address references not destined for offsetof.
+ (c_expand_return): Only look inside ARRAY_REF and COMPONENT_REF
+ when looking for returning address of local variable.
+ * expr.c (expand_expr_1): Don't dereference size
+ of unbounded arrays.
+ * gimplify.c (gimplify_addr_expr): Only fold
+ address of variable size array elements.
+ * tree-simple.c (is_gimple_min_invariant): Also check
+ is_gimple_variable before disallowing offset address for type.
+ * tree-ssa-ccp.c (maybe_fold_offset_to_aggregate_ref): New.
+ (maybe_fold_offset_to_component_ref): Use it.
+ (maybe_fold_stmt_indirect, maybe_fold_stmt_plus): Likewise.
+ (maybe_fold_offset_to_array_ref): Likewise.
+ Don't fail for division remainder non-zero.
+ * varasm.c (initializer_constant_valid_p) <ADDR_EXPR>: Use
+ handled_component_p and look inside references.
+ <MINUS_EXPR>: Always look past widening casts.
+
+2003-12-09 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_inline_hash): New global variable.
+ (cgraph_create_node): Break out of ....
+ (cgraph_node): ... this one.
+ (cgraph_redirect_edge_callee): New function.
+ (cgraph_remove_node): Aggressively elliminate dead nodes;
+ remove node out of clone list.
+ (dump_cgraph): Dump inlined_to field; dump uid numbers.
+ (cgraph_clone_edge): Return edge created.
+ (cgraph_clone_node): New.
+ (cgraph_function_possibly_inlined_p): Re-implement using hashtable.
+ * cgraph.h: Include hashtab.h
+ (struct cgraph_global_info): Kill inline_once, will be output and
+ cloned_times fields. Add inlined_to field.
+ (cgraph_node): Add next_clone.
+ (cgraph_inline_hash): Declare.
+ (cgraph_clone_edge): Update prototype.
+ (cgraph_clone_node, cgraph_redirect_callee): Declare.
+ * cgraphunit.c (cgraph_optimize_function): Kill.
+ (cgraph_assemble_function): Kill next_needed to avoid GGC corruption.
+ (cgraph_analyze_function): Do not intialize cloned_times and
+ will_be_output.
+ (cgraph_finalize_compilation_unit): Clear next_needed.
+ (cgraph_optimize_function): Kill.
+ (cgraph_expand_function): Do not use cgraph_optimize_function.
+ (cgraph_estimate_growth, cgraph_mark_inline,
+ cgraph_check_inline_limits, cgraph_recursive_inlining_p,
+ cgraph_preserve_function_body_p): Update for explicit clones.
+ (INLINED_TIMES, SET_INLINED_TIMES, cgraph_inlined_into,
+ cgraph_inlined_callees, struct cgraph_inline_context,
+ cgraph_create_inline_context, cgraph_free_inline_context,
+ cgraph_inline_context_set_caller, cgraph_inline_context_clear_caller,
+ cgraph_inline_context_set_callee, cgraph_inline_context_clear_callee,
+ update_callee_keys): Kill.
+ (cgraph_clone_inlined_nodes, cgraph_mark_inline_edge): New.
+ (cgraph_decide_inlining_of_small_functions, (cgraph_decide_inlining,
+ cgraph_decide_inlining_incrementally): Simplify.
+ * tree-inline.c (typedef struct_inline_data): New field saving_p.
+ (copy_body_r): Update all clones.
+ (expand_call_inline): Remove inlined cgraph node.
+ (save_body): Inicialize id.node and id.saving_p.
+ * tree-optimize.c (tree_rest_of_compilation): Maintain clone up-to-date
+ in no-unit-at-a-time mode.
+
+2003-12-08 Steven Bosscher <stevenb@suse.de>
+
+ * tree-optimize.c (optimize_function_tree): Move verify_ssa calls
+ into conditionals.
+
+2003-12-08 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-ander.c (andersen_same_points_to_set): Fix memory leak.
+
+2003-12-08 Jeff Law <law@redhat.com>
+
+ * tree-ssa-live.c (register_ssa_partition): Kill legacy code which
+ recursively called register_ssa_partition on PHI arguments when
+ SSA_VAR was defined by a PHI_NODE.
+
+2003-12-08 Jan Hubicka <jh@suse.cz>
+
+ * tree-dump.c (dump_files): Fix ordering of tail call pass.
+ * tree.h (tree_dump_index): Likewise.
+
+2003-12-08 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * Makefile.in (tree-cfg.o): Add gt-tree-cfg.h dependency.
+ (GTFILES): Add tree-cfg.c.
+ * tree-cfg.c: Include gt-tree-cfg.h.
+ (factored_computed_goto_label, factored_computed_goto):
+ Mark gc roots.
+
+2003-12-08 Steven Bosscher <stevenb@suse.de>
+ Jan Hubicka <jh@suse.de>
+
+ * gengtype-lex.l (IWOrD): Add HOST_WIDEST_INT
+ * Makefile.in (function.o, reg-stack.o): Add missing dependency on
+ basic-block.h.
+ (GTFILES): Add basic-block.h and hwint.h.
+ * basic-block.h (struct edge_def): Add GTY markers, make garbage
+ collectable. Make `insns' field GC safe depending on the setting
+ of cfg_hooks.
+ (struct basic_block_def): Add GTY markers, make garbage collectable.
+ (tree_bb_root, tree_phi_root): Kill extern decls.
+ (ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR): Change from macro to variable
+ (entry_exit_blocks): Kill.
+ * cfg.c: Include ggc.h
+ (bb_pool, edge_pool, entry_exit_blocks): Kill.
+ (ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR): Define.
+ (init_flow): Do not create ppols; allocate entry/exit block.
+ (free_edge, alloc_block, expunge_block, unchecked_make_edge): Use GGC.
+ (compact_blocks): Don't update tree_bb_root and tree_phi_root.
+ * cfgrtl.c (rtl_merge_blocks): Clear head pointer.
+ * regs.h: Protect against multiple inclusion.
+ * tree-cfg.c (obstack_tree_ann_obstack, first_block_tree_and_obj,
+ tree_bb_root): Kill.
+ (build_tree_cfg, create_bb, remove_bb, delete_tree_cfg): Don't
+ touch tree_bb_root and tree_phi_root.
+ (create_block_annotations): Do not initialize obstack.
+ (free_block_annotations): Do not free obstack.
+ (create_block_annotation): Use GGC.
+ * tree-dfa.c (tree_phi_root): Kill.
+ * tree-flow.h (bb_ann, bb_ann_d): Declare. Add `phi_nodes' field.
+ * tree-phinodes.c (create_phi_node, add_phi_arg, remove_phi_node,
+ remove_all_phi_nodes_for): Use `phi_nodes' field in the bb
+ annotation instead of tree_phi_root.
+ * tree-flow-inline.h (phi_nodes, set_phi_nodes): Likewise.
+ (add_dom_child, clear_dom_children): Use GGC.
+ * tree-ssa-pre.c (code_motion): Use `phi_nodes' field in the bb
+ annotation instead of tree_phi_root.
+ * varray.h (union varray_data): Make basic_block_def and edge_def
+ varrays garbage collectable.
+
+2003-12-07 Richard Henderson <rth@redhat.com>
+
+ * c-common.c (c_address_looks_like_offsetof): New.
+ * c-common.h (c_address_looks_like_offsetof): Declare.
+ * c-typeck.c (build_unary_op) <ADDR_EXPR>: Use it. Don't lower
+ address references not destined for offsetof.
+ (c_expand_return): Only look inside ARRAY_REF and COMPONENT_REF
+ when looking for returning address of local variable.
+ * expr.c (expand_expr_1): Don't dereference size of unbounded arrays.
+ * gimplify.c (gimplify_addr_expr): Only fold address of variable size
+ array elements.
+ * tree-simple.c (is_gimple_min_invariant): Also check
+ is_gimple_variable before disallowing offset address for type.
+ * tree-ssa-ccp.c (maybe_fold_offset_to_aggregate_ref): New.
+ (maybe_fold_offset_to_component_ref): Use it.
+ (maybe_fold_stmt_indirect, maybe_fold_stmt_plus): Likewise.
+ (maybe_fold_offset_to_array_ref): Likewise. Don't fail for division
+ remainder non-zero.
+ * varasm.c (initializer_constant_valid_p) <ADDR_EXPR>: Use
+ handled_component_p and look inside references.
+ <MINUS_EXPR>: Always look past widening casts.
+
+2003-12-07 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-cfg.c (compute_dominance_frontiers): Don't assume that
+ the first block has index 0.
+
+2003-12-07 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (create_edge): Rename to ...
+ (cgraph_create_edge): ... this one; accept call_expr as operand.
+ (cgraph_edge): New function
+ (cgraph_remove_edge): Use edge as argument
+ (cgraph_record_call, cgraph_remove_call): Kill.
+ (clone_cgraphedge): New function.
+ * cgraph.h (cgraph_edge): Add call_expr argument; add chain_next.
+ (cgraph_record_call, cgraph_remove_call): Kill prototype.
+ (cgraph_remove_call, cgraph_inline_p): Update prototype.
+ (cgraph_clone_edge): Declare.
+ * cgraphunit.c (cgraph_finalize_function): Update use of
+ cgraph_remove_edge
+ (record_call_1): Use cgraph_create_edge; record builtins too.
+ (cgraph_create_edges): Accept node instead of decl.
+ (cgraph_analyze_function): Update use cgraph_create_edges.
+ (cgraph_inline_p): Accept edge.
+ * tree-inline.c (inline_data): Replace decl and current_decl
+ by node and current_node.
+ (copy_body_r): Clone edges.
+ (expand_call_inline): Do not create inlined edges.
+ (optimize_inline_call): Set id->current_node, id->node.
+ * tree-optimize.c (tree_rest_of_compilation): Update cgraph edges after
+ compiling.
+
+2003-12-07 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa-loop.c (dump_file, dump_flags): Only declare with
+ checking enabled.
+ (tree_ssa_loop_opt): Mark arguments with ATTRIBUTE_UNUSED.
+
+2003-12-07 Richard Henderson <rth@redhat.com>
+
+ * function.h (struct function): Add last_label_uid.
+ * tree-cfg.c (set_bb_for_stmt): Use it.
+ (delete_tree_cfg): Clear label_to_block_map.
+
+ * gimple-low.c (lower_stmt_body): Export.
+ (lower_stmt): Allow data to be null.
+ * gimplify.c (declare_tmp_vars): Make static.
+ (push_gimplify_context): Export.
+ (pop_gimplify_context): Export. Put the temps somewhere.
+ (gimplify_body): Don't declare_tmp_vars here.
+ * tree-flow.h, tree-simple.h: Update for new decls.
+
+ * tree-mudflap.c (mf_build_string): New.
+ (mudflap_c_function_decls): Push and pop gimplify context, don't
+ gimplify here. Dump pass 1.
+ (mudflap_c_function_ops): Similarly.
+ (mf_decl_cache_locals): Gimplify eveything as we go along.
+ (mf_build_check_statement_for): Likewise.
+ (mf_mostly_copy_tree_r): Remove.
+ (mf_varname_tree): Use mf_build_string.
+ (mf_file_function_line_tree): Rewrite.
+ (mf_offset_expr_of_array_ref): Remove.
+ (mx_xfn_indirect_ref): Remove.
+ (mf_xform_derefs_1): New.
+ (mf_xform_derefs): Rewrite to expect gimple.
+ (mx_register_decls): Use build_function_call_expr.
+ (mudflap_enqueue_constant): Use mf_build_string.
+ * tree-optimize.c (tree_rest_of_compilation): Reorder mudflap bits.
+ * tree-dump.c (dump_files): Split mudflap to parts 1 and 2.
+ * tree.h (enum tree_dump_index): Likewise.
+
+2003-12-06 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-ssa-loop.c: New.
+ * Makefile.in (tree-ssa-loop.o): New.
+ * common.opt (ftree-loop-optimize): Add.
+ * flags.h (flag_tree_loop): Declare.
+ * opts.c (decode_options): Enable flag_tree_loop at -O1.
+ (common_handle_option): Handle OPT_ftree_loop_optimize.
+ * timevar.def (TV_TREE_LOOP): New.
+ * toplev.c (flag_tree_loop): New.
+ (f_options): Add -ftree-loop-optimize.
+ * tree-cfg.c (build_tree_cfg): Remove disabled loop optimizer
+ initialization.
+ (tree_make_forwarder_block): Update phi nodes.
+ (tree_loop_optimizer_init): Don't call force_single_succ_latches.
+ (tree_try_redirect_by_replacing_jump): Comment fix.
+ * tree-dump.c (dump_files): Add .loop dump.
+ * tree-flow.h (tree_ssa_loop_opt, set_phi_nodes): Declare.
+ * tree-optimize.c (optimize_function_tree): Call tree_ssa_loop_opt.
+ * tree.h (enum tree_dump_index): Add TDI_loop.
+ * tree-flow-inline.h (set_phi_nodes): New.
+ * doc/invoke.texi (-fdump-tree-loop, -ftree-loop-optimize): Document.
+
+2003-12-05 Jeff Law <law@redhat.com>
+
+ * tree-dfa.c (mark_new_vars_to_rename): Change VARS_TO_RENAME to be
+ a "bitmap" instead of an "sbitmap". Callers updated.
+ * tree-must-alias.c (promote_var): Likewise.
+ (tree_compute_must_alias): Likewise.
+ * tree-phinodes.c (remove_all_phi_nodes_for): Likewise.
+ * tree-ssa-dom.c (tree_ssa_dominator_thread_jumps): Likewise.
+ (tree_ssa_dominator_optimize): Likewise.
+ (tree_ssa_dominator_optimize_1): Likewise.
+ * tree-ssa-pre.c (pre_expression): Likewise.
+ (tree_perform_ssapre): Likewise.
+ * tree-ssa.c (rewrite_into_ssa): Likewise.
+ (insert_phi_nodes): If VARS_TO_RENAME is zero, then examine
+ each node to determine if we need to insert a PHI.
+ (prepare_operand_for_rename): If VARS_TO_RENAME is zero, then
+ assume the operand needs renaming.
+ * tree-ssa-ccp.c (substitute_and_fold): Change VARS_TO_RENAME to
+ be a "bitmap" instead of an "sbitmap". Callers updated.
+ (tree_ssa_ccp): Likewise. Also make sure timevar_pop encloses
+ entire function.
+ (scalarize_modify_expr): Likewise.
+ * tree-sra.c (create_scalar_copies): Change VARS_TO_RENAME to
+ be a "bitmap" instead of an "sbitmap". Callers updated.
+ (tree_sra): Likewise.
+ * tree-optimize.c (optimize_function_tree): Make VARS_TO_RENAME
+ be a "bitmap" instead of an "sbitmap".
+ * tree-flow.h: Update various prototypes.
+
+2003-12-05 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-cfg.c (remove_useless_stmts_goto, remove_useless_stmts): Move
+ handling of factored_computed_goto ...
+ (disband_implicit_edges): ... here.
+
+2003-12-05 Jan Hubicka <jh@suse.cz>
+
+ * tree-eh.c (tree_could_trap_p): Fix warning.
+ * expr.c (expand_expr): Fix warning on uninitialized last.
+
+2003-12-04 Jeff Law <law@redhat.com>
+
+ * tree-ssa.c (rewrite_trees): Do not unconditionally overwrite
+ variables set by statements. Let replace_variable do any
+ required rewriting.
+
+2003-12-04 Richard Henderson <rth@redhat.com>
+
+ * c-parse.in (primary): Use annotate_with_locus instead of
+ STMT_LINENO for STMT_EXPR.
+ * c-simplify.c (gimplify_stmt_expr): Likewise.
+
+2003-12-04 Jan Hubicka <jh@suse.cz>
+
+ * tree-dump.c (dump_files): Reorder tailcall and mustalias
+ * tree.h (tree_dump_index): Likewise.
+ * tree-optimize.c (optimize_function_tree): Do tail call after mustalias.
+
+2003-12-04 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (opf_none, opf_is_def, opf_no_vops): Change to #define.
+
+2003-12-04 Canqun Yang <canqun@nudt.edu.cn>
+
+ * stor-layout.c (update_alignment_for_field): Export.
+ * tree.h (update_alignment_for_field): Declare.
+
+2003-12-03 Andrew Haley <aph@redhat.com>
+
+ * tree-eh.c (tree_could_trap_p): Add division instructions.
+ * expr.c (expand_expr): Check the EH region of an expression and
+ mark all the insns that result from its expansion with the
+ appropriate REG_EH_REGION.
+
+2003-12-03 Jan Hubicka <jh@suse.cz>
+
+ * tree-cfg.c (verify_addr_expr, verify_stmt, tree_node_shared_p,
+ verify_stmts): New functions.
+ (verify_flow_info): Remove PHI checking code.
+ * tree-flow.h (verify_stmt, verify_stmts): Declare.
+ * tree-inline.h (walk_tree, walk_tree_without_duplicates): Move
+ prototypes ...
+ * tree.h (walk_tree, walk_tree_without_duplicates): ... here.
+
+2003-12-03 Jan Hubicka <jh@suse.cz>
+ Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa.c (verify_def, verify_use, verify_phi_args): New static
+ functions.
+ (verify_ssa): New global function.
+ * tree-flow.h (verify_ssa): Declare.
+ * tree-optimize.c (optimize_function_tree): Call it.
+
+2003-12-03 Diego Novillo <dnovillo@redhat.com>
+
+ * timevar.def (TV_TREE_SSA_VERIFY): New timer.
+ * tree-sra.c (create_scalar_copies): Always mark the previous
+ variables on the LHS for renaming.
+ Do not emit unnecessary assignments from VA_ARG_EXPRs.
+ (scalarize_modify_expr): Similarly, when scalarizing the LHS of a
+ COMPONENT_REF assignment.
+ * tree-must-alias.c (tree_compute_must_alias): Do not promote
+ variables with hidden uses.
+ * tree-ssa-ccp.c (set_rhs): When replacing the whole statement, reset
+ SSA_NAME_DEF_STMT for all the SSA_NAMEs in vdef and def
+ operands.
+
+2003-12-03 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+ Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (opf_no_vops): New.
+ (add_stmt_operand): Don't create virtual operands when opf_no_vops
+ is passed in flags.
+ (get_expr_operands): Set opf_no_vops flag before diving into the
+ operand of an ADDR_EXPR node.
+
+2003-12-03 Richard Henderson <rth@redhat.com>
+
+ * tree-simple.c (is_gimple_min_invariant): Disallow offset of
+ address of a scalar.
+
+ * c-parse.in (primary): Set STMT_LINENO on STMT_EXPR.
+ * c-simplify.c (gimplify_stmt_expr): Be prepared for last_stmt
+ to be null.
+
+2003-12-03 Daniel Berlin <dberlin@dberlin.org>
+
+ Fix PR 13177
+ * tree-ssa-pre.c (code_motion): Do phi nodes last, and rearrange
+ how we decide what temporary to choose so that we get it right.
+
+2003-12-03 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-dfa.c (get_expr_operands): Don't record VUSEs for invariant
+ adresses.
+
+2003-12-03 Brian Booth <bbooth@redhat.com>
+
+ * tree-pretty-print.c (dump_phi_nodes): Removed superfluous ampersand.
+
+2003-12-03 Jeff Law <law@redhat.com>
+
+ * ggc-page.c: Resync with mainline sources. Remove tree-ssa
+ specific hack which disabled special GC pagesizes for 2 operand
+ tree expressions.
+
+ * tree-ssa.c (mark_def_sites): Call prepare_operand_for_rename
+ on the VDEF_RESULT as well, providing a dummy uid argument.
+
+ * tree-phinodes.c: Include rtl.h for ceil_log2.
+ (ideal_phi_node_len): New function.
+ (resize_phi_node): Make static.
+ (make_phi_node): Use ideal_phi_node_len.
+ (add_phi_arg): Likewise.
+ * tree.h (resize_phi_node): Remove prototype.
+ * Makefile.in (tree-phinodes.o): Depend on $(RTL_H).
+
+2003-12-03 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-cfg.c: (make_edges): Eliminate fallthru to exit.
+ (make_ctrl_stmt_edges): Nonlocal goto handling moved to
+ make_goto_expr_edges.
+ (make_goto_expr_edges): Remove simple gotos.
+ (cfg_remove_useless_stmts_bb): Goto removal cancelled.
+ (cleanup_cond_expr_graph, cleanup_switch_expr_graph):
+ Replaced by ...
+ (cleanup_control_expr_graph): New.
+ (cleanup_control_flow): Use it.
+ (disband_implicit_edges): New.
+ (tree_find_edge_insert_loc): Never insert before a control statement.
+ (tree_split_edge, thread_jumps, tree_try_redirect_by_replacing_jump,
+ tree_redirect_edge_and_branch): Work over no-gotos form.
+ (tree_verify_flow_info): Check no-gotos form invariants.
+ * tree-pretty-print.c (pp_cfg_jump, dump_implicit_edges): New.
+ (dump_generic_bb_buff): Call dump_implicit_edges.
+ * tree-flow.h (cleanup_cond_expr_graph, cleanup_switch_expr_graph):
+ Declaration removed.
+ (cleanup_control_expr_graph, delete_tree_ssa, disband_implicit_edges):
+ Declare.
+ * tree-optimize.c (tree_ssa_finish): New.
+ (optimize_function_tree): Call it.
+ * tree-ssa-dom.c (thread_jumps_walk_stmts, optimize_stmt): Use
+ cleanup_control_expr_graph.
+ * tree-ssa.c (delete_tree_ssa): Export, work even if there are no
+ referenced_vars.
+ (rewrite_out_of_ssa): Don't call it.
+
+2003-12-03 Jan Hubicka <jh@suse.cz>
+
+ * tree-ssa.dom.c (tree_ssa_domionator_thread_jumps): Mark back edges.
+ (thread_across_edge): Do not thread across loop headers.
+
+ * Makefile.in (tree-optimize.o): Depend on cgraph.h
+ * cgraph.h (cgraph_preserve_function_body_p): Declare.
+ * cgraphunit.c (cgraph_preserve_function_body_p): New function.
+ * tree-optimize.c: Include cgraph.h
+ (clear_decl_rtl): Kill.
+ (tree_rest_of_compilation): Use cgraph_preserve_function_body_p;
+ do not clear DECL_RTL; do final ggc in the pushed context for nested
+ functions;
+
+2003-12-02 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (optimize_stmt): Accept and pass down dominator
+ walker structure instead of individual varrays. Callers updated.
+ (eliminate_redundant_computations): Likewise.
+ (simplify_rhs_and_lookup_avail_expr): Likewise. Cache and update
+ a dummy COND_EXPR when querying the hash tables when transforming
+ DIV/MOD into RSHIFT/BIT_AND or ABS_EXPR into NEG_EXPR.
+ (dom_opt_walk_stmts): Don't reload the block data pointer each
+ iteration of the loop. Load it once outside the loop.
+
+ * tree-dfa.c (cleanup_operand_arrays): Avoid creating a new
+ varray for the vuse operands.
+
+ * tree-ssa-dom.c (extract_range_from_cond): Use int_const_binop to
+ avoid creating useless tree nodes.
+
+ * tree-phinodes.c (add_phi_arg): If we receive a new node from
+ resize_phi_node, then release the old node and update the PHI
+ chain.
+
+2003-12-02 Brian Booth <bbooth@redhat.com>
+
+ * tree-pretty-print.c (dump_phi_nodes): Added code to always show phi
+ nodes of regular gimple scalars.
+ (dump_generic_bb_buff): Removed condition upon which to show phi nodes.
+
+2003-12-02 Jan Hubicka <jh@suse.cz>
+
+ * tree-optimize.c (optimize_function_tree): Invoke ggc_collect in
+ between optimization passes.
+
+2003-12-02 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-sra.c (can_be_scalarized_p): Print details about why something
+ could not be scalarized to the dump file.
+
+2003-12-01 Jeff Law <law@redhat.com>
+
+ * Makefile.in (OBJS-common): Add tree-phinodes.o.
+ (tree-phinodes.o): Add dependencies.
+ (GTFILES): Add tree-phinodes.c.
+ * tree-phinodes.c: New file.
+ * tree-dfa.c (create_phi_node): Moved to tree-phinodes.o.
+ (add_phi_arg, remove_phi_arg, remove_phi_arg_num): Similarly.
+ (remove_phi_node, remove_all_phi_nodes_for): Similarly.
+ * tree-ssa.c (init_tree_ssa): Initialize PHI node management.
+ (delete_tree_ssa): Finalize PHI node management.
+ * tree.c (dump_tree_statistics): Dump PHI node stats.
+ (make_phi_node, resize_phi_node): Moved to tree-phinodes.o.
+ * tree.h (init_phinodes): Prototype.
+ (fini_phinodes, release_phi_node): Likewise.
+ (phinodes_print_statistics): Likewise.
+
+2003-12-01 Richard Henderson <rth@redhat.com>
+
+ * tree-dfa.c (get_expr_operands): Don't handle PLUS_EXPR inside
+ INDIRECT_REF.
+ * tree-ssa-ccp.c (maybe_fold_offset_to_array_ref): Use int_const_binop.
+ (maybe_fold_offset_to_component_ref): Likewise.
+ (maybe_fold_stmt_indirect): Likewise.
+ (maybe_fold_stmt_plus): Expand ARRAY_REF when seen with addend.
+ * fold-const.c (int_const_binop): Export.
+ * tree.h (int_const_binop): Declare.
+
+2003-12-01 Jan Hubicka <jh@suse.cz>
+
+ * basic-block.h (tree_phi_root): New variable.
+ * cfg.c: Include tree-flow.h.
+ (compact_blocks): Compact tree_phi_root
+ * tree-cfg.c (build_tree_cfg): Initialize tree_phi_root.
+ (create_bb, remove_bb, delete_tree_cfg): Update tree_phi_root.
+ * tree-dfa.c (tree_phi_root): Declare.
+ (create_phi_node, add_phi_arg, remove_phi_node,
+ remove_all_phi_nodes_for): Always use accessor functions for
+ getting, varray for setting phis.
+ * tree-ssa-pre.c (code_motion): Likewsie.
+ * tree-flow-inline.h (phi_nodes): Use varray.
+ * tree-flow.h (bb_ann_d): Remove phi_nodes.
+
+ * tree-ssanames.c (free_ssanames): Do not use deleteable GTY flag.
+
+2003-11-30 Jan Hubicka <jh@suse.cz>
+
+ * tree-optimize.c (tree_rest_of_compilation): Move ggc_collect call to
+ the end of function; keep clearing of DECL_SAVED_TREE to the cgraph
+ code.
+
+2003-11-30 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_inline_context): New structure.
+ (cgrpah_mark_inline, cgraph_check_inline_limits): Use context
+ instead of passing all arguments by hand.
+ (cgraph_create_inline_context, cgraph_free_inline_context,
+ cgraph_inline_context_set_caller, cgraph_inline_context_clear_caller,
+ cgraph_inline_context_set_callee, cgrpah_inline_context_clear_callee,
+ cgraph_recursive_inlining_p): New static function.
+ (cgraph_decide_inline*): Reorganize to use context.
+
+2003-11-30 Paul Brook <paul@nowt.org>
+
+ * Makefile.in (GTFILES): Remove stray '\'.
+
+2003-11-30 Daniel Berlin <dberlin@dberlin.org>
+
+ * c-config-lang.in: Move tree-alias-* from here
+ * Makefile.in (GTFILES): To here.
+ * tree-alias-ander.c: Include bitmap.h
+ (andersen_function_call): Updated to take address of variables
+ in an ADDR_EXPR in a CALL_EXPR.
+ * tree-alias-common.h (struct tree_alias_ops): Update arguments to
+ function_call.
+ * tree-alias-type.h (struct alias_typevar_common): Add varnum.
+ * tree-alias-common.c: Include bitmap.h, and function.h.
+ s/global_var/pta_global_var/g.
+ (addrargs): New static variable.
+ (pta_global_var): Ditto.
+ (find_func_decls): Remove.
+ (find_func_aliases): Take one argument, update all callers.
+ Handle (cast) [addr-expr] [var].
+ Handle COMPONENT_REF of an INDIRECT_REF.
+ Pass info about ADDR_EXPR arguments to function_call function.
+ (deal_with_call_aliasing): New function.
+ (call_may_return): New function.
+ (get_alias_var_decl): Call find_func_aliases on the DECL_INITIAL
+ of a global var.
+ Use ALIAS_TVAR_VARNUM, instead of VARRAY_ACTIVE_SIZE (alias_vars) - 1.
+ (get_alias_var): Handle REALPART_EXPR and IMAGPART_EXPR.
+ Return NULL in default case.
+ (intra_function_call): Remove wrong code.
+ (create_fun_alias_var): Use simple_assign, not addr_assign.
+ Set up ALIAS_TVAR_VARNUM when creating an alias var.
+ (create_fun_alis_var_ptf): Ditto on ALIAS_TVAR_VARNUM.
+ (create_alias_var): Ditto.
+ (create_alias_vars): Build pta_global_var here.
+ Walk unexpanded_var_list.
+ Walk the statements in basic blocks.
+ (delete_alias_vars): Correct ip_partial case.
+ Free addrargs.
+ (init_alias_vars): Create addrargs.
+
+2003-11-29 Jan Hubicka <jh@suse.cz>
+
+ * Makefile.in (tree-ssanames.o): Depend on gt-tree-ssanames.h.
+ (tree-eh.o): Depend on gt-tree-eh.h.
+ (gr-tree-ssanames.h, gt-tree-eh.h): New targets.
+ (GTFILES): Add tree-ssanames.c, tree-eh.c
+ * tree-eh.c: Include ggc.h and gt-tree-eh.h
+ (lower_eh_constructs): Allecate throw_stmt_table in ggc.
+ * tree-ssanames.c: Include ggc.h and gt-tree-ssanames.h
+
+ * function.h (struct function): Add saved_tree/saved_args.
+ * toplev.c (rest_of_compilation): Move code to clear cfun and
+ DECL_SAVED_INSNS and call to ggc_collect to ...
+ * tree-optimize.c (tree_rest_of_compilation): ... this function. Use
+ cfun to save/restore function body.
+
+2003-11-28 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (create_tmp_var_raw): Split out from create_tmp_var.
+ (create_tmp_var): Use it.
+ (create_tmp_alias_var): Remove.
+ * tree-alias-common.c, tree-dfa.c: Use create_tmp_var_raw instead.
+ * tree-simple.h: Update decls.
+
+2003-11-28 Richard Henderson <rth@redhat.com>
+
+ * gimple-low.c (lower_function_body): Call lower_bind_expr
+ to handle the outermost BIND_EXPR.
+
+2003-11-28 Jan Hubicka <jh@suse.cz>
+
+ * tree-ssa.c (remove_annotations_r): Kill.
+ (delete_tree_ssa): Remove annotations using statement walk;
+ kill argument fndecl.
+ (rewrite_out_of_ssa): Update call.
+
+2003-11-27 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-ssa-live.c (register_ssa_partition): Abort if a virtual SSA
+ version is registered.
+ (create_ssa_var_map): Always process PHI nodes.
+ * tree-ssa.c (Eliminate_virtual_phis): Rename from
+ eliminate_extraneous_phis, and look specifically for virtuals.
+ (rewrite_out_of_ssa): Eliminate virtual PHI nodes before building
+ partitions.
+
+2003-11-27 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-ssa-ccp.c (get_strlen): Mark the visited variables.
+ (ccp_fold_builtin): Changed due to changed calling convention of
+ get_strlen.
+
+2003-11-26 Diego Novillo <dnovillo@redhat.com>
+
+ Revert
+
+ 2003-11-25 Jeff law <law@redhat.com>
+
+ * Makefile.in (OBJS-common): Add tree-phinodes.o.
+ (tree-phinodes.o): Add dependencies.
+ * tree-phinodes.c: New file.
+ * tree-dfa.c (create_phi_node): Moved to tree-phinodes.o.
+ (add_phi_arg, remove_phi_arg, remove_phi_arg_num): Similarly.
+ (remove_phi_node, remove_all_phi_nodes_for): Similarly.
+ * tree-ssa.c (init_tree_ssa): Initialize PHI node management.
+ (delete_tree_ssa): Finalize PHI node management.
+ * tree.c (dump_tree_statistics): Dump PHI node stats.
+ (make_phi_node, resize_phi_node): Moved to tree-phinodes.o.
+ * tree.h (init_phinodes): Prototype.
+ (fini_phinodes, release_phi_node): Likewise.
+ (phinodes_print_statistics): Likewise.
+
+2003-11-25 Jan Hubicka <jh@suse.cz>
+
+ * tree-mustalias.c (promote_var): Do not clear
+ may_point_to_global_mem.
+
+2003-11-25 Jeff law <law@redhat.com>
+
+ * domwalk.c (walk_dominator_tree): Indicate to the block local
+ data initializer if the block local data is new or recycled.
+ * domwalk.h (struct dom_walk_data): Corresponding changes.
+ * tree-ssa-dom.c (dom_opt_initialize_block_local_data): Accept and use
+ "recycled" argument. For recycled structures, only clear varrays
+ that have been initialized. For new blocks, do not initialize
+ varrays here.
+ (dom_opt_finalize_block): When threading across edges, if the
+ true/false varrays have not been initialized, then the limit is zero.
+ Only clear block local varrays that have been initialized.
+ (record_equivalences_from_incoming_edge): If necessary, initialize
+ block local const_and_copies.
+ (dom_opt_walk_stmts): If necessary, initialize block local
+ stmts_to_rescan.
+ (record_var_is_nonzero): If necessary, initialize block local
+ nonzero_vars.
+ (record_cond_is_true): If necessary, initialize block local
+ true_exprs.
+ (record_cond_is_false): If necessary, initialize block local
+ false_exprs.
+ (lookup_avail_expr): If necessary, initialize block local
+ avail_exprs.
+ (record_range): If necessary, initialize block local vrp_varaibles.
+ * tree-ssa.c
+ * tree-ssa.c (rewrite_initialize_block_local_data): Accept and use
+ "recycled" argument. For recycled structures, only clear varrays
+ that have been initialized. For new blocks, do not initialize
+ varrays here.
+ (rewrite_finalize_block): Only clear block local varrays that have
+ been initialized.
+ (register_new_def): If necessary, initialize block local defs.
+
+ * tree-ssa-dom.c (get_eq_expr_value): Return a struct rather than
+ a tree node.
+ (record_equivalences_from_incoming_edge): Corresponding changes.
+ (find_equivalent_equality_comparison): Use tree_int_cst_XXX rather
+ then building and folding nodes.
+ (simplify_cond_and_lookup_avail_expr): Likewise.
+
+ * Makefile.in (OBJS-common): Add tree-phinodes.o.
+ (tree-phinodes.o): Add dependencies.
+ * tree-phinodes.c: New file.
+ * tree-dfa.c (create_phi_node): Moved to tree-phinodes.o.
+ (add_phi_arg, remove_phi_arg, remove_phi_arg_num): Similarly.
+ (remove_phi_node, remove_all_phi_nodes_for): Similarly.
+ * tree-ssa.c (init_tree_ssa): Initialize PHI node management.
+ (delete_tree_ssa): Finalize PHI node management.
+ * tree.c (dump_tree_statistics): Dump PHI node stats.
+ (make_phi_node, resize_phi_node): Moved to tree-phinodes.o.
+ * tree.h (init_phinodes): Prototype.
+ (fini_phinodes, release_phi_node): Likewise.
+ (phinodes_print_statistics): Likewise.
+
+2003-11-25 Jan Hubicka <jh@suse.cz>
+
+ * tree-inline.c (save_body): New body
+ * tree-inline.h (save_body): Declare.
+ * tree-optimize.c (tree_rest_of_compilation): Save function tree
+ properly.
+
+2003-11-24 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (canonicalize_addr_expr): New.
+ (gimplify_conversion): Use it. Canonicalize after nop cast removal.
+ * tree-simple.c (is_gimple_min_invariant): Remove STRING_CST cast
+ special case.
+
+2003-11-24 Jeff Law <law@redhat.com>
+
+ * flow.c (count_or_remove_death_notes_bb): New. Extracted from
+ count_or_remove_death_notes.
+ (count_or_remove_death_notes): Use EXECUTE_IF_SET_IN_SBITMAP.
+
+2003-11-24 Richard Henderson <rth@redhat.com>
+
+ PR 13174, PR 13143
+ * gimplify.c (cpt_same_type): Allow different ARRAY_TYPEs with
+ the same base type.
+
+2003-11-24 Daniel Berlin <dberlin@dberlin.org>
+
+ Fix PR/13163
+ * tree-ssa-pre.c (append_eref_to_block): Delete.
+ (insert_euse_in_preorder_dt_order_1): Ditto.
+ (insert_one_operand): Take an extra argument, because
+ avdefs may need to be changed.
+ (clear_all_eref_arrays): Use FOR_ALL_BB.
+ (insert_occ_in_preorder_dt_order): Stop appending to bb eref arrays.
+ Use FOR_ALL_BB.
+ (insert_euse_in_preorder_dt_order): Rewrite to just build a new varray
+ with only the EPHI's and EUSE's, and then sort it.
+ (pre_expression): Don't use bb based erefs array when printing
+ expressions.
+ (split_critical_edges): Just use FOR_ALL_BB.
+ (tree_perform_ssapre): Pre-split entry block successor edge if the
+ successor block has multiple preds.
+
+ * tree-flow.h (struct bb_ann_d): Remove erefs varray.
+
+2003-11-24 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-cfg.c (cleanup_tree_cfg): FOR_EACH_BB -> FOR_ALL_BB when
+ clearing dom children, because the entry block has dom_children
+ too.
+ * tree-ssa.c (build_dominator_tree): Ditto.
+
+2003-11-24 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (compute_dominance_frontiers_1,
+ compute_dominance_frontiers): Move from ssa.c.
+ * tree-flow.h (compute_dominance_frontiers): Declare.
+ * Makefile.in (tree-ssa.o, tree-ssa-live.o, tree-ssa-pre.o,
+ tree-optimize.o): Don't depend on ssa.h.
+ * tree-ssa.c: Don't include ssa.h.
+ * tree-ssa-live.c: Likewise.
+ * tree-ssa-pre.c: Likewise.
+ * tree-optimize.c: Likewise.
+
+2003-11-24 Jan Hubicka <jh@suse.cz>
+
+ * fold-const.c (fold): Do not return early when
+ optimizing COMPONENT_REF and constant.
+
+2003-11-24 Richard Henderson <rth@redhat.com>
+
+ * objc/objc-act.c (build_protocol_expr): Use convert instead of
+ smashing TREE_TYPE.
+
+2003-11-23 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-ssa-live.h (SSANORM_PERFORM_TER, SSANORM_COMBINE_TEMPS,
+ SSANORM_REMOVE_ALL_PHIS): New flag macros.
+ * tree-ssa.c (replace_variable): Return true if var was rewritten.
+ (eliminate_extraneous_phis): Dump var map to file if checking triggers
+ an abort.
+ (rewrite_trees): Set modified_stmt if stmt was changed.
+ (remove_ssa_form): Move more of rewrite_out_of_ssa to make it serve
+ all the same functions based on new flags in tree-ssa-live.h.
+ (rewrite_out_of_ssa): Call remove_ssa_form.
+
+2003-11-23 Jan Hubicka <jh@suse.cz>
+
+ * tree-cfg.c (tree_verify_flow_info): Check that ENTRY/EXIT block
+ has no instructions associated with it.
+
+2003-11-22 Jeff Law <law@redhat.com>
+
+ * tree-ssa-names.c (release_ssa_name): Use SSA_NAME_IN_FREE_LIST
+ instead of checking SSA_NAME_DEF_STMT being null.
+ * tree.h (SSA_NAME_DEF_STMT): Use chain field rather than the
+ def_stmt field.
+ (SSA_NAME_OCCURS_IN_ABNORMAL_PHI): Use existing flag from tree_common.
+ (SSA_NAME_IN_FREE_LIST): Define.
+ (struct tree_ssa_name): Kill DEF_STMT and OCCURS_IN_ABNORMAL_PHI fields.
+
+2003-11-22 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-pretty-print.c (dump_generic_node): Remove superfluous ';'.
+
+2003-11-22 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (simple-break-elim.o): Remove.
+ (simple-goto-elim.o): Remove.
+ (tree-dchain.o): Remove.
+ * simple-break-elim.c: Remove.
+ * simple-goto-elim.c: Remove.
+ * tree-dchain.c: Remove.
+ * tree-dchain.h: Remove.
+
+2003-11-22 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (build_dfs_id_array_1): > should be >=
+ (build_dfn_array): Ditto.
+
+2003-11-21 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree-dfa.o): Add dependency on $(TREE_DUMP_H)
+ * tree-dfa.c: Include tree-dump.h
+ (compute_alias_sets): Call dump_function_to_file.
+ (may_access_global_mem_p): Check if the base address of _REF nodes
+ may point to global memory.
+
+ * cfgcleanup.c (try_crossjump_to_edge): Initialize newpos1 and
+ newpos2.
+
+2003-11-21 Jeff Law <law@redhat.com>
+
+ Revert:
+
+ 2003-11-21 Jan Hubicka <jh@suse.cz>
+
+ * tree-dfa.c (get_expr_operands): Fix handling of CALL_EXPR.
+ * tree-must-alias.c (tree_compute_must_alias): promote pointers.
+ (find_addressable_vars): Deal with complex constant
+ expressions; do not clear may_point_to_global_mem.
+
+2003-11-21 Jeff Law <law@redhat.com>
+
+ * Makefile.in (domwalk.o): Depend on $(GGC_H).
+ * domwalk.c: Include ggc.h.
+ (walk_dominator_tree): Manage allocation/deallocation and
+ pushing/popping of the toplevel block data pointer here.
+ Use callback to initialize the block local data.
+ (init_walk_dominator_tree): New function.
+ (fini_walk_dominator_tree): Likewise.
+ * domwalk.h (struct dom_walk_data): Add callback to initialize
+ block local data. Add field for sizeof block local data.
+ Add "private" field free_block_data.
+ (init_dominator_tree, fini_dominator_tree): Prototype.
+ * tree-ssa-dom.c (dom_opt_initialize_local_data): New function.
+ (tree_ssa_dominator_optimize_1): Initialize new fields in the
+ dominator walker structure. Initialize and finalize the dominator
+ walker. Slightly reorder code to make it more readable..
+ (dom_opt_initialize_block): No longer deal with allocation and
+ initialization of block local data.
+ (dom_opt_finalize_block): Similarly for deallocation of block
+ local data.
+ * tree-ssa.c (rewrite_block_data): New structure.
+ (rewrite_initialize_block_local_data): New function.
+ (rewrite_initialize_block): No longer deal with allocation and
+ initialization of block local data.
+ (rewrite_into_ssa): Initialize new fields in the dominator walker
+ structure. Initialize and finalize the dominator walker.
+ (rewrite_initialize_block): No longer deal with allocation and
+ initialization of block local data.
+ (rewrite_optimize_stmts): Deal with changes in the dominator
+ walker structure.
+ (rewrite_finalize_block): No longer with deallocation of block
+ local data.
+
+ * tree-dfa.c (add_vdef, cleanup_voperand_arrays): Use NUM_VDEFS.
+ (mark_new_vars_to_rename, collect_dfa_status_r): Likewise.
+ * tree-pretty-print.c (dump_vops): Likewise.
+ * tree-sra.c (create_scalar_copies): Likewise.
+ * tree-ssa-dce.c (stmt_useful_p, process_worklist): Likewise.
+ * tree-ssa-live.c (create_ssa_var_map): Likewise.
+ (calculate_live_on_entry): Likewise.
+ * tree-ssa-pre.c (process_left_occs_and_kills): Likewise.
+ * tree-ssa.c (mark_def_sites, rewrite_stmt): Likewise.
+ * tree.h (NUM_VDEFS): Define.
+ * tree-ssa-ccp.c (visit_stmt): Use NUM_VDEFS. Fix thinko in last
+ change.
+ (initialize): Use NUM_VDEFS.
+
+ * tree-dfa.c (add_vdef): Revamp to handle new method for
+ recording vdefs.
+ (cleanup_operand_arrays): Similarly.
+ * tree-sra.c (create_scalar_copies): Similarly.
+ * tree-ssa-ccp.c (visit_stmt, initialize): Similarly.
+ * tree-ssa-dce.c (stmt_useful_p, process_worklist): Similarly.
+ * tree-ssa-dom.c (cprop_into_stmt): Similarly.
+ (record_equivalences_from_stmt): Similarly.
+ * tree-ssa-live.c (create_ssa_var_map): Similarly.
+ (calculate_live_on_entry): Similarly.
+ * tree-ssa.c (mark_def_sites, rewrite_stmt): Similarly.
+ * tree-ssa-pre.c (process_left_occr_and_kills): Similarly.
+ * tree-inline.c (estimate_num_insns_1): Kill VDEF_EXPR.
+ * tree-pretty-print.c (dump_generic_node) Kill VDEF_EXPR.
+ (dump_vops): Dump VDEFs here.
+ * tree.c (build_vdef_expr): Kill.
+ * tree.h (build_vdef_expr): Kill prototype.
+ (VDEF_RESULT, VDEF_OP): Revamp to handle new method for recording
+ vdefs.
+ * tree.def (VDEF_EXPR): Kill.
+
+ * tree-cfg.c (cfg_remove_useless_stmts): Set both VAR and VAL to
+ NULL anytime one of them is determined to be invalid.
+
+2003-11-21 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-ssa-live.c (compact_var_map): Fix typo. Clear correct field.
+ (calculate_live_on_entry): Remove unneeded stmt.
+ * tree-ssa-live.h (version_to_var): New. Return variable associated
+ with a specific SSA version.
+ * tree-ssa.c (eliminate_build): Add check that ignored results don't
+ have important arguments. Allow ignored results.
+ (coalesce_abnormal_edges): Allow non-relevant results to be ignored.
+ (eliminate_extraneous_phis): Allow non-relevant results. Check that
+ no important arguments are being missed.
+ (coalesce_vars): Non-partition variables are allowed now, just ignored.
+ (rewrite_trees): New. Split out from rewrite_out_of_ssa. Perform tree
+ rewriting step.
+ (remove_ssa_form): New. Allow rewriting of just specified variables.
+ (rewrite_out_of_ssa): Use rewrite_trees and reorganize slightly to
+ accommodate typechecking in eliminate_extraneous_phis.
+
+2003-11-21 Jan Hubicka <jh@suse.cz>
+
+ * tree-dfa.c (get_expr_operands): Fix handling of CALL_EXPR.
+ * tree-must-alias.c (tree_compute_must_alias): promote pointers.
+ (find_addressable_vars): Deal with complex constant expressions;
+ do not clear may_point_to_global_mem.
+
+2003-11-21 Jan Hubicka <jh@suse.cz>
+
+ * parser.c (cp_parser_postfix_expression): Initialize 's' to
+ NULL_TREE.
+
+2003-11-20 Richard Henderson <rth@redhat.com>
+
+ * Makefile.in (bitmap.o-warn, caller-save.o-warn, combine.o-warn,
+ cgraphunit.o-warn, c-semantics.o-warn, emit-rtl.o-warn, expr.o-warn,
+ fold-const.o-warn, genattrtab.o-warn, regmove.o-warn, tree.o-warn,
+ varasm.o-warn, f/expr.o-warn, profile.o-warn): Remove.
+ * bitmap.c (bitmap_first_set_bit): Abort if no non-zero word found.
+ (bitmap_last_set_bit): Likewise.
+ * combine.c (get_pos_from_mask): Always set *plen.
+
+2003-11-20 Richard Henderson <rth@redhat.com>
+
+ * tree-dfa.c (get_expr_operands): Remove handling of PLUS_EXPR
+ inside INDIRECT_REF.
+
+2003-11-20 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-nomudflap.c (nogo): Fix prototype.
+
+2003-11-20 Richard Henderson <rth@redhat.com>
+
+ * except.c (output_function_exception_table): Strip nops.
+ * gimplify.c (gimplify_addr_expr): Kill missing cast workaround.
+ (cpt_same_type, check_pointer_types_r): New.
+ (gimplify_body): Call it.
+ * tree-inline.c (insert_decl_map): New.
+ (remap_decl, remap_type, remap_block, copy_body_r,
+ initialize_inlined_parameters, declare_return_variable,
+ remap_save_expr, mark_local_for_remap_r): Use it.
+
+2003-11-20 Frank Ch. Eigler <fche@redhat.com>
+
+ libstdc++/11696
+ * c-pragma.c (handle_pragma_redefine_extname): Define always.
+ (init_pragma): Activate #pragma redefine_extname for mudflap.
+
+ * tree-inline.c (copy_tree_r): Propagate mf_marked-ness.
+ * tree-mudflap.c (mudflap_c_function): Break into new
+ _decls and _ops functions.
+ (mudflap_c_function_decls): Avoid unnecessary tree copying.
+ (mudflap_c_function_ops): Ditto. Gimplify explicitly only for
+ tree dumping.
+ * tree-nomudflap.c: Add new stub functions. Simplify error
+ message emission throughout.
+ * tree-mudflap.h: Corresponding changes.
+ * tree-optimize.c (tree_rest_of_compilation): Call the _decl
+ instrumentation before gimplification and ssa optimizations;
+ call the _ops instrumentation after ssa optimizations.
+
+2003-11-20 Diego Novillo <dnovillo@redhat.com>
+
+ Initial fix for PR optimization/12747
+
+ * Makefile.in (OBJS): Add tree-sra.o
+ * common.opt (ftree-sra): Add.
+ * flags.h (flag_tree_sra): Declare.
+ * gimplify.c (gimplify_addr_expr): Set TREE_INVARIANT
+ when producing and address expression for a DECL node.
+ * opts.c (decode_options): Enable SRA at -O1.
+ (common_handle_option): Handle -ftree-sra.
+ * timevar.def (TV_TREE_SRA): New timer.
+ * toplev.c (flag_tree_sra): Define.
+ * tree-cfg.c (stmt_ends_bb_p): Declare extern.
+ (bsi_replace): Add boolean argument to specify whether to
+ preserve EH region information. Update all callers.
+ (bsi_commit_edge_inserts): Also check the edge from ENTRY_BLOCK_PTR
+ to basic block 0.
+ Move loop body ...
+ (bsi_commit_edge_inserts_1): ... here.
+ * tree-dump.c: Add dump for SRA pass.
+ * tree.h (enum tree_dump_index): Modify accordingly.
+ (STRIP_USELESS_TYPE_CONVERSION): Define. Update all callers to
+ tree_ssa_useless_type_conversion.
+ * tree-eh.c (add_stmt_to_eh_region): New function.
+ * tree-flow.h (stmt_ends_bb_p): Declare.
+ (add_stmt_to_eh_region): Declare.
+ (tree_sra): Declare.
+ (enum bsi_iterator_update): Mirror entries in
+ enum tsi_iterator_update.
+ * tree-optimize.c (optimize_function_tree): Call SRA pass
+ after must-alias.
+ * tree-sra.c: New file.
+ * doc/invoke.texi: Document -ftree-sra and -fdump-tree-sra.
+
+2003-11-20 Andrew Macleod <amacleod@redhat.com>
+
+ * tree-ssa.c (check_replaceable): Return false if the LHS is a
+ DECL_HARD_REGISTER.
+
+2003-11-20 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa-ccp.c (set_rhs): Replace with an empty statement when
+ the replacement has no side effects.
+
+2003-11-20 Jeff Law <law@redhat.com>
+
+ * Makefile.in (OBJS-common): Kill tree-ssa-copyprop.o.
+ (tree-ssa-copyprop.o): Kill dependencies clause.
+ * common.opt (tree-copyprop): Kill option.
+ * flags.h (flag_tree_copyprop): Kill.
+ * opts.c (decode_options): Don't set flag_tree_copyprop.
+ (common_handle_option): Kill handling of -ftree-copyprop.
+ * timevar.def (TV_TREE_COPYPROP): Kill.
+ * toplev.c (flag_tree_copyprop): Kill.
+ (lang_independent_options): Kill -ftree-copyprop.
+ * tree-dump.c (dump_files): Kill .copyprop dump.
+ * tree-flow.h (tree_ssa_copyprop): Kill prototype.
+ (propagate_copy): Move prototype.
+ * tree-optimize.c (optimize_function_tree): Kill -ftree-copyprop stuff.
+ * tree.h (tree_dump_index): Kill TDI_copyprop.
+ * tree-ssa-copyprop.c: Kill.
+ * tree-ssa-dom.c (propagate_copy): Moved here from tree-ssa-copyprop.c.
+
+ * tree-ssanames.c (free_ssanames): No longer a varray.
+ (init_ssanames, make_ssa_name, release_ssa_name): Corresponding changes.
+
+2003-11-20 Steven Bosscher <stevenb@suse.de>
+
+ * tree-ssanames.c (ssanames_print_statistics): Use ISO function
+ declaration. Print unsigned ints, not usinged longs.
+
+2003-11-18 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (rename_1): This should be static.
+ (append_eref_to_block): Don't gc allocate.
+ (clear_all_eref_arrays): Free the array rather than
+ clear them.
+ (rename_1): Ditto on both counts.
+ (free_expr_info): Free the arrays.
+ (collect_expressions): Don't gc allocate the arrays.
+
+2003-11-18 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (insert_one_operand): Handle self-referential
+ ephi's properly.
+
+2003-11-19 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (true_exprs, false_exprs): New hash tables.
+ (nonzero_vars): New varray.
+ (dom_walk_block_data): Add true_exprs, false_exprs and nonzero_vars.
+ (get_value_for, set_value_for): Accept additional argument indicating
+ which table to use. Callers updated.
+ (tree_ssa_dominator_optimize_1): Initialize and wipe our new hash
+ tables and varray appropriately.
+ (dom_opt_initialize_block): Initialize new block local varrays for
+ true expressions, false expressions and nonzero vars. Update call
+ to record_equivalences_from_incoming_edge.
+ (dom_opt_finalize_block): Put equivalences from taken edges
+ into the true_exprs and false_exprs hash tables. Restore global
+ state for true_exprs, false_exprs and nonzero_vars too.
+ (record_equivalences_from_incoming_edge): Accept dom_walk structure
+ instead of a gazillion varrays. Pass down block local
+ true_exprs, false_exprs and nonzero_vars varrays to various children.
+ (optimize_stmt): Accept block local nonzero_vars argument. Pass
+ new varrays down to record_equivalences_from_stmt.
+ (thread_jumps_walk_stmt): Pass new varrays down to
+ record_equivalences_from_stmt.
+ (dom_opt_walk_stmt): Pass new varrays down to optimize_stmt.
+ (dump_dominator_optimizer_statistics): Dump new hash tables.
+ (record_cond_is_true, record_cond_is_false): Record info into
+ the true/false hash tables/varrays instead of the main expression
+ varrays. Don't create useless tree nodes.
+ (record_var_is_nonzero): New function.
+ (record_equivalences_from_stmt): Don't generate useless tree nodes.
+ (lookup_avail_expr): Consult nonzero_vars and the true/false
+ expression tables as well.
+ (get_eq_expr_value): Record local true/false expressions in the
+ local true/false varrays rather than the main local expression
+ varray.
+ (true_false_expr_hash, true_false_expr_eq): New functions.
+
+ * Makefile.in (OBJS-sommon): Add tree-ssanames.o.
+ (tree-ssanames.o): Add dependencies.
+ * tree-dfa.c (remove_phi_node): Release SSA_NAME expression when
+ we remove the PHI node.
+ (remove_all_phi_nodes_for): Similarly.
+ * tree-ssa.c (prepare_operand_for_rename): Similarly when we
+ strip away an SSA_NAME expression from an operand.
+ (init_tree_ssa): Call the SSA_NAME initializer.
+ (delete_tree_ssa): Call the SSA_NAME finalizer.
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize_1): Clear the
+ const_and_copies and vrp_data virtual arrays.
+ * tree-ssanames.c: New file for management of SSA_NAME expressions.
+ * tree.h: Prototypes for functions exported by tree-ssanames.c.
+ * tree-flow.h, tree-ssa-ccp.c, tree-ssa-dce.c: Use highest_ssa_version
+ rather than next_ssa_version.
+ * tree-ssa-dom.c, tree-ssa-live.c, tree-ssa.c: Similarly.
+ * tree.c (dump_tree_statistics): Call into tree-ssaname statistics
+ dumper too.
+ (make_ssa_name): Kill. Now in tree-ssanames.c
+
+2003-11-18 Richard Henderson <rth@redhat.com>
+
+ * tree.c (recompute_tree_invarant_for_addr_expr): Split out from ...
+ (build1): ... here.
+ * tree.h: Declare it.
+ * gimplify.c (gimplify_addr_expr): Use it.
+ * tree-ssa-ccp.c (maybe_fold_offset_to_array_ref): Split out
+ from fold_indirect_refs_r.
+ (maybe_fold_stmt_indirect): Likewise.
+ (maybe_fold_offset_to_component_ref): New.
+ (maybe_fold_stmt_plus): New.
+ (fold_stmt_r): Rename from fold_indirect_refs_r.
+ (fold_stmt): Strip more useless type conversions.
+
+2003-11-18 Richard Henderson <rth@redhat.com>
+
+ * tree-cfg.c (dump_function_to_file): Mind when cfun is null.
+
+2003-11-18 Diego Novillo <dnovillo@redhat.com>
+
+ Revert
+
+ 2003-11-18 Jan Hubicka <jh@suse.cz>
+
+ * tree-cfg.c (cfg_remove_useless_stmts_bb): Avoid crash.
+ * tree-dfa.c (get_expr_operands): Fix handling of CALL_EXPR.
+
+ 2003-11-18 Jan Hubicka <jh@suse.cz>
+
+ * Makefile.in (sibcall.o): Kill.
+ (tree-tailcall.o): Add except.h dependency
+ * sibcall.c: Kill.
+ (purge_reg_equiv_notes, purge_mem_unchanging_flag): Move to ...
+ * calls.c (purge_reg_equiv_notes,
+ purge_mem_unchanging_flag) ... here.
+ (expand_call): Do not produce placeholders; do
+ not deal with tail recursion; update
+ equivalencies after sibcall production.
+ * toplev.c (rest_of_handle_sibling_calls): Kill.
+ (rest_of_compialtion): Do not use rest_of_handle_sibling_calls.
+ * tree-dump.c (dump_files): Add tail2
+ * tree-flow.h (tree_optimize_tail_calls): Update prototype.
+ * tree-optimize.c (optimize_function_tree): Do
+ tail optimization twice.
+ * tree-tailcall.c: Inlucde except.h
+ (suitable_for_tail_call_opt_p): New.
+ (optimize_tail_call): Add opt_tailcalls argument;
+ optimize tailcalls.
+ (tree_optimize_tail_calls): Add opt_tailcalls/pass arguments.
+ * tree.h (CALL_EXPR_TAILCALL): New.
+ (tree_dump_index): Add tail2
+
+2003-11-18 Jan Hubicka <jh@suse.cz>
+
+ * tree-cfg.c (cfg_remove_useless_stmts_bb): Avoid crash.
+ * tree-dfa.c (get_expr_operands): Fix handling of CALL_EXPR.
+
+2003-11-18 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-optimize.c (optimize_function_tree): Disable tail
+ call optimizations.
+
+2003-11-18 Jan Hubicka <jh@suse.cz>
+
+ * Makefile.in (sibcall.o): Kill.
+ (tree-tailcall.o): Add except.h dependency
+ * sibcall.c: Kill.
+ (purge_reg_equiv_notes, purge_mem_unchanging_flag): Move to ...
+ * calls.c (purge_reg_equiv_notes, purge_mem_unchanging_flag) ... here.
+ (expand_call): Do not produce placeholders; do not deal with tail
+ recursion; update equivalencies after sibcall production.
+ * toplev.c (rest_of_handle_sibling_calls): Kill.
+ (rest_of_compialtion): Do not use rest_of_handle_sibling_calls.
+ * tree-dump.c (dump_files): Add tail2
+ * tree-flow.h (tree_optimize_tail_calls): Update prototype.
+ * tree-optimize.c (optimize_function_tree): Do tail optimization twice.
+ * tree-tailcall.c: Inlucde except.h
+ (suitable_for_tail_call_opt_p): New.
+ (optimize_tail_call): Add opt_tailcalls argument; optimize tailcalls.
+ (tree_optimize_tail_calls): Add opt_tailcalls/pass arguments.
+ * tree.h (CALL_EXPR_TAILCALL): New.
+ (tree_dump_index): Add tail2
+
+2003-11-18 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (thread_across_edge): Lose block_avail_exprs argument.
+ Callers updated. Pass NULL for block_avail_exprs in call to
+ lookup_avail_expr. Record both the condition and the inverted
+ condition when threading across an edge.
+
+2003-11-18 Richard Henderson <rth@redhat.com>
+
+ * tree-ssa.c (tree_ssa_useless_type_conversion): Use TYPE_MAIN_VARIANT
+ when compariing pointer types too.
+
+2003-11-18 Jan Hubicka <jh@suse.cz>
+
+ * tree-dump.c (dump_files): Reorder tail calls.
+ * tree-optimize.c (optimize_function_tree): Likewise
+ * tree-tailcall.c (optimize_tail_call, eliminate_tail_call): Remove
+ variable tmpvars; update SSA.
+ (suitable_for_tail_opt_p): Do not give up because of static variables.
+ (find_tail_calls): Track return values in SSA graph.
+ * tree.c (make-phi_node): Do not create new SSA name when operand
+ already is.
+ * tree.h (enum tree_dump_index): Reorder tail call.
+
+2003-11-17 Diego Novillo <dnovillo@redhat.com>
+
+ * gimplify.c (gimplify_call_expr): Change gimple_test_f argument to
+ return bool type.
+ (mark_decls_volatile_r): New local function.
+ (gimplify_expr): Make gimple_test_f return bool type.
+ Call mark_decls_volatile_r when gimplifying VA_ARG_EXPR.
+ * tree-dfa.c (struct walk_state): Remove field is_va_arg_expr.
+ Update all callers.
+ (opf_force_vop): Remove. Update all users.
+ (add_stmt_operand): Re-structure to add real operands only for
+ GIMPLE register variables.
+ (find_vars_r): Don't handle VA_ARG_EXPR nodes.
+ (add_referenced_var): Also assign a UID to variables with hidden
+ uses.
+ Call is_gimple_call_clobbered to determine if a variable is call
+ clobbered.
+ (get_memory_tag_for): Mark memory tags volatile and static.
+ * tree-flow.h (struct var_ann_d): Remove field is_in_va_arg_expr.
+ Update all users.
+ * tree-simple.c (is_gimple_*): Change return type to bool. Update
+ all users.
+ (is_gimple_reg_type): Return true only for non aggregate types.
+ (is_gimple_non_addressable_1): New local function.
+ (is_gimple_reg): Call it.
+ (is_gimple_non_addressable): New function.
+ (is_gimple_call_clobbered): New function.
+ * tree-simple.h (is_gimple_*): Change return type to bool.
+
+2003-11-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/11266
+ * gimplify.c (gimple_add_tmp_var): Also make sure
+ seen_in_bind_expr isn't set.
+ (mostly_copy_tree_r): Don't copy a TARGET_EXPR.
+ (gimplify_target_expr): Only expand a TARGET_EXPR the first time
+ we see it.
+
+2003-11-17 Richard Henderson <rth@redhat.com>
+
+ * tree-pretty-print.c (dump_generic_node): Use %u not %x for
+ printing DECL_UID.
+
+2003-11-16 Richard Henderson <rth@redhat.com>
+
+ * c-common.c (c_add_case_label): Use create_artificial_label.
+ * tree-simple.h (create_artificial_label): Move decl ...
+ * tree.h: ... here.
+
+2003-11-16 Richard Henderson <rth@redhat.com>
+
+ PR c++/12770
+ * gimple-low.c (lower_stmt_body): Take a tree, not a tree*.
+ (lower_stmt): Handle EH nodes.
+ (lower_bind_expr): Remove fixme.
+ (block_may_fallthru): Move from tree-eh.c. Handle COND_EXPR,
+ BIND_EXPR, and TRY_FINALLY_EXPR.
+ (lower_cond_expr): Use it.
+ * tree-eh.c (collect_finally_tree): Ignore COND_EXPR and BIND_EXPR.
+ (replace_goto_queue_cond_clause): New.
+ (replace_goto_queue_1): Use it. Split out statement_list handling.
+ (replace_goto_queue_stmt_list): New.
+ (-block_may_fallthru): Move to gimple-low.c.
+ (lower_eh_constructs_1): Ignore BIND_EXPR.
+ * tree-flow.h (block_may_fallthru): Declare.
+
+ * tree-dump.c (dump_files): Exchange .eh and .lower passes.
+ * tree-optimize.c (tree_rest_of_compilation): Likewise.
+ * tree.h (enum tree_dump_index): Likewise.
+
+2003-11-16 Jason Merrill <jason@redhat.com>
+
+ * gimplify.c (mostly_copy_tree_r): Don't walk into a BLOCK.
+
+ * tree-inline.c (walk_tree): Don't walk into the BIND_EXPR_VARS
+ of a BIND_EXPR.
+ * c-common.c (c_walk_subtrees): Don't walk into the decl of a
+ DECL_STMT.
+
+ PR optimization/11269
+ * dwarf2out.c (gen_subprogram_die): Generate a DIE for a named
+ return value.
+ (loc_descriptor_from_tree): Treat RESULT_DECL like VAR_DECL.
+ (add_location_or_const_value_attribute): Likewise.
+ (add_bound_info): Likewise.
+ (gen_decl_die): Likewise.
+
+2003-11-16 Jason Merrill <jason@redhat.com>
+
+ * c-pretty-print.c (debug_c_tree): Restore removed fn.
+ * diagnostic.h: Declare it.
+
+ * tree-pretty-print.c (dump_generic_node): Use DECL_UID when
+ dumping anonymous decls.
+
+2003-11-16 Richard Henderson <rth@redhat.com>
+
+ * tree-cfg.c (last_and_only_stmt): New.
+ * tree-flow.h (last_and_only_stmt): Declare.
+ * tree-ssa-dom.c (thread_across_edge): Use it.
+
+ * tree-cfg.c (tree_block_forwards_to): Don't check for empty stmts.
+ (tree_forwarder_block_p): Likewise.
+ * tree-dfa.c (get_stmt_operands): Likewise.
+ * tree-ssa-ccp.c (set_rhs): Likewise.
+ * tree-ssa-dom.c (optimize_stmt): Likewise.
+ * tree-ssa.c (rewrite_stmt): Likewise.
+
+2003-11-16 Richard Henderson <rth@redhat.com>
+
+ * tree.h (LABEL_DECL_UID): Rename from LABEL_DECL_INDEX.
+ * tree-flow.h (bsi_remove): Declare.
+ * tree-flow-inline.h (bsi_remove): Move ...
+ * tree-cfg.c (set_bb_for_stmt): Don't re-set LABEL_DECL_UID.
+ Verify that a label isn't already in a block before adding it.
+ (bsi_remove): Move from tree-flow-inline.h, clear bb.
+ * tree-pretty-print.c (dump_generic_node): Use LABEL_DECL_UID if set.
+
+2003-11-15 Richard Henderson <rth@redhat.com>
+
+ * function.c (clear_block_marks): Rename from reorder_blocks_0, export.
+ * function.h (clear_block_marks): Declare.
+ * gimple-low.c (lower_function_body): Use it.
+ (lower_bind_expr): Ensure we don't link blocks into the tree twice.
+ * gimplify.c (gimplify_body): Keep old bind_expr at top level if
+ possible.
+
+2003-11-14 Richard Henderson <rth@redhat.com>
+
+ * tree-ssa-pre.c (split_critical_edges): Reimplement. Call
+ tree_split_edge directly.
+
+2003-11-14 Jason Merrill <jason@redhat.com>
+
+ * tree-eh.c (do_return_redirection): Assign directly to the
+ RESULT_DECL of a function which returns in memory.
+
+2003-11-14 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (pre_stats): Add ephis_current member.
+ (create_ephi_node): Use xmalloc, not ggc_alloc_tree.
+ (clear_all_eref_arrays): Free the ephis here.
+ (expr_phi_insertion): Don't append the ephis to the erefs array.
+ (insert_occ_in_preorder_dt_order): Move building/freeing of dfn
+ array so that it only occurs once per function..
+ (rename_1): Ditto on the dfs_id array.
+ (ephi_use_pool): New alloc pool.
+ (add_ephi_use): Pool allocate these things, rather than
+ ggc_alloc'ing them.
+ (insert_euse_in_preorder_dt_order_1): Use ephi_at_block to put the
+ ephi in the list.
+ (pre_expression): Don't PRE when we only have 1 occurrence.
+ (expr_lexically_eq): Make inline.
+ (names_match_p): Move closer to first use.
+ (tree_perform_ssapre): Alloc and free the ephi_use_pool.
+ Make stat printing per-expression.
+ Add checking that we freed all ephis.
+
+2003-11-14 Andrew MacLeod <amacleod@redhat.com>
+
+ * common.opt (ftree-ter): Document new option.
+ * flags.h (flag_tree_ter): Add new flag.
+ * fold-const.c (invert_truthvalue): Don't ignore cast to BOOLEAN_TYPE.
+ * opts.c (decode_options): Option -ftree-ter defaults to on.
+ (common_handle_option): Add processing for flag_tree_ter.
+ * toplev.c (flag_tree_ter): Initialize to 0.
+ (lang_independent_options f_): Add -ftree-ter flag.
+ * tree-ssa-live.c (init_var_map): Initialize ref_count to 0.
+ (delete_var_map): Free ref count if allocated.
+ (register_ssa_partition): Add "is_use" parameter for reference counting.
+ (create_ssa_var_map): Add flag and code for calculating ref counts.
+ * tree-ssa-live.h (struct _var_map): Add ref_count field.
+ (SSA_VAR_MAP_REF_COUNT): Define flag.
+ (version_ref_count): Function to retreive ref_count.
+ * tree-ssa.c (replace_variable): If an expression vector is passed in,
+ use replacement expression instead of mapped variable when available.
+ (struct value_expr_d): New structure for value lists.
+ (struct temp_expr_table_d): Structure used to build an expression
+ replacement table.
+ (new_temp_expr_table): New. Create a new TER (Temporary Expression
+ Replacement) table.
+ (free_temp_expr_table): New. Free a TER table.
+ (new_value_expr): New. Allocate a value list element.
+ (free_value_expr): New. Free a value list element.
+ (find_value_in_list): New. Find a value in a list.
+ (add_value_to_list): New. Add a value to a list if not already present.
+ (remove_value_from_list): New. Remove a value from a list.
+ (add_dependance): New. Add a dependency to an expression.
+ (check_replaceable): New. Check if a stmt is a candidate for TER. Add
+ to active list and create dependancies if so.
+ (finish_expr): New. Remove an expression from TER consideration.
+ (mark_replaceable): New. Finish a TER expression as a valid replacement.
+ (kill_expr): New. Finish dependent TER expressions as not replaceable.
+ (kill_virtual_exprs): New. Finish any TER expressions dependent on a
+ virtual operand as not replaceable.
+ (find_replaceable_in_bb): New. Process a basic block for TER expression.
+ (find_replaceable_exprs): New. Entry point for TER expression finder.
+ (dump_replaceable_exprs): New. output list of replaceable expressions.
+ (rewrite_out_of_ssa): Build TER table if requested, and use it.
+
+2003-11-14 Andreas Jaeger <aj@suse.de>
+
+ * c-semantics.c (find_reachable_label): Use C90 function
+ declaration.
+
+2003-11-14 Jason Merrill <jason@redhat.com>
+
+ PR middle-end/12526
+ * tree-cfg.c (call_expr_flags): Move to calls.c.
+ * tree-flow.h: Move prototype to tree.h.
+
+ PR c++/13033
+ * c-simplify.c (gimplify_c_loop): Wrap the increment in a
+ CLEANUP_POINT_EXPR.
+
+ * tree-dfa.c (get_stmt_operands) <ASM_EXPR>: A memory clobber
+ clobbers all call-clobbered variables. Clobber clobber.
+
+ * gimplify.c (canonicalize_component_ref): Remove redundant call
+ to recalculate_side_effects.
+
+2003-11-14 Richard Henderson <rth@redhat.com>
+
+ PR c++/12751
+ * tree-eh.c (struct leh_tf_state): Add outer.
+ (lower_try_finally, lower_cleanup): Set it.
+ (lower_try_finally_fallthru_label): New.
+ (honor_protect_cleanup_actions): Use it.
+ (lower_try_finally_copy, lower_try_finally_switch): Likewise.
+
+ * tree-eh.c (collect_finally_tree): Complete manual tailrecurse
+ transformation.
+
+2003-11-14 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (voidify_wrapper_expr): Don't clobber TREE_TYPE of
+ statements in a STATEMENT_LIST. Be prepared for an empty list.
+
+2003-11-14 Steven Bosscher <stevenb@suse.de>
+
+ * jump.c (never_reached_warning): Remove function.
+ * rtl.h (never_reached_warning): Don't declare it.
+ * cfgrtl.c (never_reached_warning): Don't call it.
+ * cse.c (never_reached_warning): Ditto.
+
+2003-11-13 Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (bsi_replace): Restore accidentally removed code.
+
+ * tree-cfg.c (cfg_remove_useless_stmts_bb): Also detect useless
+ var->var copies created by the out-of-ssa translation.
+
+2003-11-13 Steven Bosscher <stevenb@suse.de>
+
+ PR middle-end/11514
+ * tree-inline.c (walk_tree): Handle PLACEHOLDER_EXPR.
+
+2003-11-13 Richard Henderson <rth@redhat.com>
+
+ * tree-cfg.c (cfg_remove_useless_stmts_bb): Initialize stmt.
+
+2003-11-13 Jan Hubicka <jh@suse.cz>
+
+ * calls.c (special_function_p): Do not check for ECF_MALLOC.
+ (flags_from_decl_or_type): Use special_function_p.
+ (expand_call): Remove call to special_function_p.
+ * tree-cfg.c (notice_special_calls, clear_special_calls): New functions.
+ (remove_useless_stmts): Use clear_special_calls.
+ (remove_useless_stmts_1): Use notice_special_calls.
+ * tree-flow.h (notice_special_calls, clear_special_calls): New functions.
+ * tree-ssa-dce.c (remove_dead_stmts): Use clear_special_calls and
+ notice_special_calls..
+
+ * gimplify.c (gimplify_expr): Check labels.
+
+ * tree-cfg.c (tree_verify_flow_info): Check labels.
+
+ * tree-cfg.c (make_exit_edges): Do not create edges for const
+ functions.
+ (update_call_expr_flags): Fix.
+
+2003-11-12 Diego Novillo <dnovillo@redhat.com>
+
+ (declare_inlined_vars): New local function.
+ (initialize_inlined_parameters): Call it.
+ (expand_call_inline): Call it.
+
+2003-11-13 Steven Bosscher <stevenb@suse.de>
+
+ PR optimization/12640
+ * tree-ssa-ccp.c (get_strlen): Don't follow the UD chain
+ of a PHI argument if the DEF stmt for the argument is
+ the PHI itself.
+
+2003-11-12 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+ Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (cfg_remove_useless_stmts): New function.
+ (cfg_remove_useless_stmts_bb): Likewise.
+ * tree-flow.h (cfg_remove_useless_stmts): Prototype.
+ * tree-ssa.c (rewrite_out_of_ssa): Use cfg_remove_useless_stmts
+ instead of remove_useless_stmts.
+
+2003-11-12 Richard Henderson <rth@redhat.com>
+
+ * Makefile.in (OBJS-common): Add tree-iterator.o.
+ (expr.o): Depend on tree-iterator.h.
+ (GTFILES): Add tree-iterator.c.
+ * basic-block.h (struct basic_block_def): Replace head_tree_p
+ and end_tree_p with stmt_list.
+ (tree_bb_root): New.
+ (create_bb): Don't declare.
+ * c-common.c (c_warn_unused_result): Handle STATEMENT_LIST.
+ * c-simplify.c (c_gimplify_stmt): Don't rationalize_compound_expr.
+ * cfg.c (entry_exit_blocks): Adjust for member changes.
+ (compact_blocks): Manage tree_bb_root.
+ * expr.c (expand_expr_1): Handle STATEMENT_LIST.
+ * gimple-low.c: Update for tree_stmt_iterator changes.
+ (lower_cond_expr): Use expr_only. Notice empty conditionals.
+ * gimplify.c (append_to_statement_list_1): Create and
+ manage statement_list nodes.
+ (foreach_stmt): Remove.
+ (wfl_locus): Remove.
+ (annotate_all_with_locus_1): Merge into...
+ (annotate_all_with_locus): ... here. Iterate over the
+ statement list directly.
+ (voidify_wrapper_expr): Handle STATEMENT_LIST.
+ (gimplify_return_expr): Likewise.
+ (gimplify_loop_expr): Likewise.
+ (shortcut_cond_r, shortcut_cond_expr): Likewise.
+ (gimplify_cleanup_point_expr): Likewise.
+ (gimple_build_eh_filter): Create statement list bodies.
+ (gimplify_bind_expr): Likewise.
+ (gimplify_switch_expr): Likewise.
+ (gimplify_cond_expr): Likewise.
+ (gimplify_compound_expr): Handle void expressions as well.
+ (gimplify_statement_list): New.
+ (gimple_push_cleanup): Gimplify the WITH_CLEANUP_EXPR operand.
+ (gimplify_stmt): Ensure non-null result.
+ (gimplify_to_stmt_list): New.
+ (gimplify_expr): Use gimplify_compound_expr, gimplify_statement_list,
+ gimplify_to_stmt_list as appropriate.
+ (gimplify_body): Fix creation of outer BIND_EXPR.
+ * tree-cfg.c (tree_bb_root): New.
+ (build_tree_cfg): Initialize it. Update for make_blocks changes.
+ (factor_computed_gotos): Use create_bb directly.
+ (make_blocks): Rewrite to use statement lists.
+ (append_stmt_to_bb, prepend_stmt_to_bb): Remove.
+ (create_bb): Make static. Add stmt_list argument. Don't allow
+ null after argument. Set tree_bb_root.
+ (make_edges): ENTRY block successor is FALLTHRU.
+ (remove_useless_stmts_warn_notreached): Handle STATEMENT_LIST.
+ (struct rus_data): Add last_goto.
+ (remove_useless_stmts_cond): Clear it. Zap empty conditionals.
+ Use expr_only for simple statment elimination.
+ (remove_useless_stmts_tf): Clear last_goto. Use TREE_SIDE_EFFECTS
+ instead of IS_EMPTY_STMT. Use append_to_statement_list instead of
+ munging to COMPOUND_EXPR.
+ (remove_useless_stmts_tc): Clear last_goto. Use TREE_SIDE_EFFECTS.
+ (remove_useless_stmts_goto): Set last_goto.
+ (remove_useless_stmts_label): New. Kill goto-next-label.
+ (remove_useless_stmts_1): Reorg to handle STATEMENT_LIST.
+ (remove_bb): Simplify block removal.
+ (remove_bsi_from_block): Kill.
+ (tree_block_forwards_to): Tidy bsi loops. Do not create
+ block label here.
+ (tree_cfg2dot): Update for bb->stmt_list.
+ (delete_tree_cfg): Clear tree_bb_root.
+ (set_bb_for_stmt): Handle STATEMENT_LISTs.
+ (bsi_insert_before, bsi_insert_after): Re-implement on TSIs.
+ (bsi_move_after, bsi_move_before, bsi_move_to_bb_end): Likewise.
+ (bsi_replace): Likewise.
+ (tree_find_edge_insert_loc): New, split from ...
+ (bsi_insert_on_edge_immediate): ... here.
+ (bsi_commit_edge_inserts): Use it. Add all stmts at once.
+ (bsi_insert_on_edge): Use statement lists.
+ (tree_split_edge): Position new block correctly. Deal with
+ fallthrough to EXIT.
+ (tree_verify_flow_info): Do not check block order vs statement chain.
+ (tree_make_forwarder_block): Update create_bb call, fix edge flags.
+ (thread_jumps): Call tree_redirect_edge_and_branch directly.
+ (tree_block_label): Don't return a NONLOCAL_LABEL.
+ (tree_redirect_edge_and_branch_1): Rename from s/_1//. Take an
+ argument to use ssa_redirect_edge or redirect_edge_succ. Use
+ tree_split_edge instead of bsi_insert_on_edge_immediate.
+ (tree_redirect_edge_and_branch): New.
+ (remove_stmt, first_exec_stmt, bsi_init, bsi_next_in_bb): Kill.
+ (bsi_start, bsi_last, bsi_prev, bsi_from_tsi): Kill.
+ (bsi_update_from_tsi, bsi_link_after): Kill.
+ * tree-eh.c (collect_finally_tree): Handle STATEMENT_LIST.
+ (replace_goto_queue_1): Likewise.
+ (replace_goto_queue): Don't use walk_tree.
+ (do_return_redirection): Create statement lists.
+ (do_goto_redirection): Likewise.
+ (block_may_fallthru_last): Fold into...
+ (block_may_fallthru): ... here.
+ (frob_into_branch_around): Use append_to_statement_list.
+ (honor_protect_cleanup_actions): Likewise.
+ (lower_try_finally_nofallthru): Likewise.
+ (lower_try_finally_onedest): Likewise.
+ (lower_try_finally_copy): Likewise.
+ (lower_try_finally_switch): Likewise.
+ (lower_try_finally): Likewise.
+ (lower_catch): Likewise.
+ (lower_eh_filter): Likewise.
+ (lower_eh_constructs_1): Handle STATEMENT_LIST.
+ * tree-flow-inline.h (BSI_NUM_ELEMENTS, bsi_list_p): Remove.
+ (new_bsi_list, empty_bsi_stack, FOR_EACH_BSI_IN_REVERSE): Remove.
+ (FOR_EACH_STMT_IN_REVERSE): Remove.
+ (bsi_start, bsi_last, bsi_end_p): Re-implement based on TSIs.
+ (bsi_next, bsi_prev, bsi_stmt, bsi_stmt_ptr, bsi_remove): Likewise.
+ * tree-flow.h (block_stmt_iterator): Likewise.
+ * tree-inline.c (copy_statement_list): New.
+ (copy_body_r): Use it, and append_to_statement_list.
+ (initialize_inlined_parameters): Use append_to_statement_list.
+ (expand_call_inline): Likewise.
+ (gimple_expand_calls_inline): New.
+ (expand_calls_inline): Use it.
+ (walk_tree, unsave_r): Handle STATEMENT_LIST.
+ (add_stmt_to_compound): Remove.
+ * tree-iterator.c: New file.
+ * tree-iterator.h: Re-implement based on STATEMENT_LIST.
+ * tree-mudflap.c (mf_decl_cache_locals): Don't
+ rationalize_compound_expr.
+ * tree-optimize.c (optimize_function_tree): Make static.
+ Rechain statements from blocks before deleting the cfg.
+ * tree-pretty-print.c (dump_generic_node): Handle STATEMENT_LIST,
+ update for change in tree_stmt_iterator wrt COMPOUND_EXPR.
+ (dump_generic_node): Dump lowered COND_EXPR on a single line.
+ * tree-simple.c (is_gimple_stmt): Handle STATEMENT_LIST.
+ * tree-simple.h (foreach_stmt_fn, foreach_stmt): Remove.
+ (gimplify_to_stmt_list): Declare.
+ (alloc_stmt_list, free_stmt_list): Declare.
+ * tree-ssa-dce.c (should_remove_dead_stmt): Rename from
+ remove_dead_stmt; return bool if statement should be removed.
+ (remove_dead_stmts): Update to match.
+ * tree-ssa-live.c (build_tree_conflict_graph): Don't use
+ FOR_EACH_STMT_IN_REVERSE.
+ * tree-ssa-pre.c (reaching_def): Tidy BSI usage.
+ (insert_one_operand, collect_expressions): Likewise.
+ * tree.c (tree_size): Handle STATEMENT_LIST.
+ (copy_node): Abort on STATEMENT_LIST.
+ (expr_first, expr_last): Move to tree-iterator.c.
+ (expr_length): Remove.
+ (tree_node_structure): Handle STATEMENT_LIST.
+ (tsi_link_before, tsi_link_after, tsi_delink): Move to tree-iterator.c.
+ (tsi_link_chain_before, tsi_link_chain_after): Merge into non-chain.
+ (tsi_new_stmt_list, tsi_stmt_list_head, body_is_empty): Kill.
+ * tree.def (STATEMENT_LIST): New.
+ * tree.h (STATEMENT_LIST_HEAD, STATEMENT_LIST_TAIL): New.
+ (struct tree_statement_list_node): New.
+ (struct tree_statement_list): New.
+ (enum tree_node_structure_enum): Add TS_STATEMENT_LIST.
+ (union tree_node): Add stmt_list.
+ (expr_length): Remove.
+ (expr_only): New.
+ (add_to_compound_expr, body_is_empty): Remove.
+ (optimize_function_tree): Remove.
+
+2003-11-12 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-flow.h (remove_useless_vars): Declare.
+ (expand_var_p): Declaration removed.
+ * tree-ssa.c (rewrite_out_of_ssa): Call remove_useless_vars.
+ * tree-cfg.c (dump_function_to_file): Update dumping of variables.
+ * gimple-low.c (expand_var_p): Made static.
+ (remove_useless_vars): New.
+ (expand_used_vars): Expand all variables in the
+ cfun->unexpanded_var_list.
+
+2003-11-11 Richard Henderson <rth@redhat.com>
+
+ * c-common.c (c_gimplify_stmt): Fix botched removal of
+ rationalize_compound_expr calls.
+
+ * c-semantics.c (build_stmt): Set TREE_SIDE_EFFECTS.
+ * c-simplify.c (c_gimplify_stmt): Return a gimplify_status;
+ mind the status from subroutines to avoid re-gimplification.
+ (c_build_bind_expr): Do not call gimplify_stmt.
+ (gimplify_c_loop): Don't create a loop_expr; fully gimplify.
+ (gimplify_block, gimplify_cleanup, gimplify_expr_stmt,
+ gimplify_for_stmt, gimplify_while_stmt, gimplify_do_stmt,
+ gimplify_if_stmt, gimplify_switch_stmt, gimplify_return_stmt,
+ gimplify_decl_stmt, gimplify_compound_literal_expr,
+ gimplify_stmt_expr): Return a gimplify_status. In most cases,
+ don't do local gimplification of sub-structures.
+ (gimplify_decl_stmt): Use append_to_compound_expr when we care
+ about the result value.
+ (gimplify_stmt_expr): Use append_to_statement_list_force and
+ re-gimplify so that voidify_wrapper_expr can work.
+ (finish_bc_block): Don't append to a non-list.
+ (c_gimplify_expr): Pass back the gimplify_status of subroutines.
+ * c-common.h (c_gimplify_stmt): Update decl.
+ * gimplify.c (append_to_statement_list_1): Make sure list_p is
+ never null after call.
+ (append_to_compound_expr): New.
+ * tree-simple.h (append_to_compound_expr): Declare.
+
+2003-11-11 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (gimplify_addr_expr): Clear, not copy, TREE_SIDE_EFFECTS.
+
+2003-11-11 Richard Henderson <rth@redhat.com>
+
+ PR c/13014
+ * c-simplify.c (gimplify_if_stmt): Remove short circuit.
+ * tree-cfg.c (struct rus_data): Add has_label.
+ (remove_useless_stmts_warn_notreached): New.
+ (remove_useless_stmts_cond): Warn for deleted conditionals.
+ (remove_useless_stmts_tc): Warn for deleted catches.
+ (remove_useless_stmts_1): Set has_label.
+
+2003-11-11 Jan Hubicka <jh@suse.cz>
+
+ * gimplify.c (gimplify_call_expr): Unset side effects for
+ pure functions too.
+ * tree-cfg.c (update-call_expr_flags): New function.
+ (remove_useless_stmts_and_vars_1): Use it.
+ (is_ctrl_altering_stmt): Pure/const calls never alter the CFG.
+ * tree-ssa-dce.c (stmt_useful_p): Check side effects flag
+ on call exprs.
+
+2003-11-11 Jan Hubicka <jh@suse.cz>
+
+ * tree-cfg.c (has_label_p): New function.
+ (tree_verify_flow_info): New checks.
+ * tree-optimize.c (optimize_function_tree): Call verify_flow_info
+ before de-SSA.
+
+2003-11-11 Richard Henderson <rth@redhat.com>
+
+ * tree-cfg.c (struct rus_data): Rename from rusv_data.
+ Remove remove_unused_vars.
+ (remove_useless_stmts*): Rename from remove_useless_stmts_and_vars*.
+ (remove_useless_stmts_bind): Do not remove dead variables.
+ (remove_useless_stmts): Kill remove_unused_vars argument.
+ * tree-flow.h (remove_useless_stmts): Update.
+ * tree-optimize.c (tree_rest_of_compilation): Update call.
+ * tree-ssa.c (rewrite_out_of_ssa): Likewise.
+
+2003-11-11 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+ Diego Novillo <dnovillo@redhat.com>
+
+ * basic-block.h (brief_dump_cfg): Declare.
+ * cfg.c (dump_cfg_bb_info, brief_dump_cfg): New.
+ * diagnostic.h (dump_generic_node): Declaration changed.
+ (print_generic_stmt_indented): Declare.
+ * gimple-low.c (expand_var_p): New.
+ (expand_used_vars): Use it.
+ * tree-cfg.c (struct cfg_stats_d): Remove num_failed_bind_expr_merges
+ field.
+ (remove_bb): Only dump whole block with TDF_DETAILS.
+ (tree_dump_bb): Use dump_generic_bb.
+ (dump_tree_cfg): Use brief_dump_cfg and dump_function_to_file.
+ (dump_cfg_function_to_file): Merged into dump_function_to_file,
+ removed.
+ (dump_cfg_stats): Do not dump cfg_stats.num_failed_bind_expr_merges.
+ (dump_function_to_file): Moved from tree-dump.c, merged with
+ dump_cfg_function_to_file.
+ * tree-dump.c (dump_function_to_file): Removed.
+ * tree-flow.h (dump_cfg_function_to_file): Declaration removed.
+ (dump_generic_bb, expand_var_p): Declare.
+ * tree-must-alias.c (tree_compute_must_alias): Replace
+ dump_cfg_function_to_file by dump_function_to_file.
+ * tree-ssa-ccp.c (tree_ssa_ccp): Ditto.
+ * tree-ssa-copyprop.c (tree_ssa_copyprop): Ditto.
+ * tree-ssa-dce.c (tree_ssa_dce): Ditto.
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize_1): Ditto.
+ * tree-ssa-pre.c (tree_perform_ssapre): Ditto.
+ * tree-ssa.c (rewrite_into_ssa, rewrite_out_of_ssa): Ditto.
+ * tree-tailcall.c (tree_optimize_tail_calls): Ditto.
+ * tree-pretty-print.c (print_declaration, print_generic_decl): Don't
+ use flags argument, change spacing.
+ (dump_block_info): Removed.
+ (dump_generic_bb_buff, dump_generic_bb, print_generic_stmt_indented,
+ dump_bb_header, dump_bb_end, dump_phi_nodes): New functions.
+ (dump_vops): Change spacing, don't dump phi nodes.
+ (do_niy, print_generic_stmt, print_generic_expr, print_declaration,
+ print_struct_decl, print_call_name): Add argument to
+ the dump_generic_node calls.
+ (last_bb): Removed.
+ (dump_generic_node): Print semicolons at end of statements correctly.
+ Don't print bb related stuff.
+ (maybe_init_pretty_print): Don't initialize last_bb.
+ * tree-ssa.c (rewrite_out_of_ssa): Do not allow virtual operands to
+ be shown in the .optimized dump.
+
+2003-11-11 Daniel Berlin <dberlin@dberlin.org>
+
+ PR optimization/12936
+ * tree-ssa-pre.c (expr_phi_insertion): Remove unused code that was
+ causing ICE's for VA_ARG_EXPR.
+
+2003-11-10 Richard Henderson <rth@redhat.com>
+
+ * gimple-low.c (lower_function_body): Lower bind_expr in place.
+ (lower_stmt): Only incr for stmts we're skipping.
+ (lower_cond_expr): Detect empty if.
+
+2003-11-10 Steven Bosscher <stevenb@suse.de>
+
+ * toplev.c (rest_of_decl_compilation): Use the location of the
+ declaration for error messages.
+
+2003-11-10 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (add_stmt_to_compound, add_tree): Remove.
+ (append_to_statement_list_1, append_to_statement_list): New.
+ (append_to_statement_list_force): New.
+ (gimplify_loop_expr): Take pre_p.
+ (gimplify_expr): Provide it.
+ * tree-simple.h: Update.
+
+ * c-simplify.c: Replace add_tree with append_to_statement_list.
+ * gimplify.c, tree-mudflap.c: Likewise.
+
+2003-11-10 Richard Henderson <rth@redhat.com>
+
+ * c-common.c (c_warn_unused_result): Restructure to use iterator
+ on COMPOUND_EXPR only.
+
+2003-11-09 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-cfg.c (tree_verify_flow_info): Fix checking of order of basic
+ blocks over code.
+
+2003-11-09 Richard Henderson <rth@redhat.com>
+
+ * basic-block.h (struct edge_def): Turn insns into a union.
+ * cfgrtl.c (insert_insn_on_edge): Update to match.
+ (commit_one_edge_insertion, commit_edge_insertions): Likewise.
+ (commit_edge_insertions_watch_calls): Likewise.
+ * gcse.c (reg_killed_on_edge, bypass_block): Likewise.
+ * profile.c (instrument_edges): Likewise.
+ * rtlanal.c (hoist_insn_to_edge): Likewise.
+ * tree-cfg.c (PENDING_STMT): Likewise.
+ (SET_PENDING_STMT): Remove.
+ (bsi_commit_edge_inserts): Update to match.
+
+2003-11-08 Jan Hubicka <jh@suse.cz>
+
+ * fold.c (nondestructive_fold_binary_to_constant): Fix typo.
+ * fold-const.c (fold_relational_const): Check for side effects.
+
+2003-11-07 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * basic-block.h (create_bb): Declaration changed.
+ * tree-cfg.c (create_bb): Enable creating a block on specified place.
+ (make_blocks, tree_split_edge, tree_make_forwarder_block): Use it.
+ (tree_verify_flow_info): Check bbs are in the correct order.
+
+ * tree-cfg.c (find_unreachable_blocks): Remove now incorrect comments.
+
+ * tree-ssa.c (rewrite_out_of_ssa): Don't remove annotations from
+ statements before the final dump.
+
+2003-11-07 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-tailcall.c (struct tailcall): New.
+ (bb_optimize_tail_calls, find_tail_call_p): Removed.
+ (eliminate_tail_call): Get the tailcall from the struct tailcall.
+ (optimize_tail_call, find_tail_calls): New.
+ (tree_optimize_tail_calls): Use them.
+
+2003-11-07 Jan Hubicka <jh@suse.cz>
+
+ * gimple-low.c (simple_goto_p): Move to...
+ * tree-cfg.c: (simple_goto_p): ... here;
+ (nonlocal_goto_p): New.
+ (is_computed_goto): Rename to ...
+ (computed_goto_p): ... this; make global.
+ (factor_computed_gotos, make_blocks): Update calls.
+ (make_ctrl_stmt_edges): Add edge for nonlocal labels; use new functions.
+ * tree-flow.h (is_coputed_goto): Kill.
+ (nonlocal_goto_p, simple_goto_p, computed_goto_p): Declare.
+ * tree-ssa-ccp (visit_stmt): Update.
+
+2003-11-07 Jan Hubicka <jh@suse.cz>
+
+ * fold-const.c (tree_expr_nonzero_p): Fix typo.
+
+ * fold-const.c (tree_expr_nonzero_p): New function.
+ (fold_relational_const): Use it.
+ (nondestructive_fold_binary_to_constant): Allow casts in address
+ expressions.
+
+2003-11-06 Jan Hubicka <jh@suse.cz>
+
+ * tree-cfg.c (tree_block_label): Cleanup.
+
+2003-11-06 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (fast_a_dominates_b): New function.
+ (build_dfs_id_array_1): Ditto.
+ (build_dfs_id_array): Ditto.
+ (load_modified_phi_result): Use fast_a_dominates_b.
+ (rename_1): Ditto.
+ Also use build_dfs_id_array, and remove some duplicate ephi_at_block
+ calls.
+ (insert_occ_in_preorder_dt_order): Remove some duplicate ephi_at_block
+ calls.
+ (pre_expression): Ditto.
+ Also free dfs_id arrays here.
+ (collect_expressions): Remove duplicate bsi_stmt calls.
+
+2003-11-06 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (count_stmts_in_bb): Removed.
+ (set_var_phis): Only call bb_for_stmt once.
+ (insert_one_operand): Remove endtree, endtreep, a lot of special handling
+ no longer needed. Remove insert_done.
+ (collect_expressions): Enable INDIRECT_REF and SSA_NAME handling.
+
+2003-11-06 Steven Bosscher <stevenb@suse.de>
+
+ * tree-cfg.c (STRIP_CONTAINERS): Remove.
+
+2003-11-06 Jan Hubicka <jh@suse.cz>
+
+ * tree-cfg.c (cleanup_cond_expr_graph): Clean edge flags.
+
+2003-11-06 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-dump.c (dump_options): Remove TDF_LINENO from all setting.
+
+2003-11-06 Jan Hubicka <jh@suse.cz>
+
+ * builtins.c (expand_builtin_strstr, expand_builtin_strchr,
+ expand_builtin_strrchr, expand_builtin_strpbrk,
+ simplify_builtin_strstr, simplify_builtin_strrchr,
+ simplify_builtin_strpbrk): Add missing casts.
+
+2003-11-05 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * diagnostic.h (print_generic_decl): Declare.
+ * tree-cfg.c (dump_cfg_function_to_file): Dump variables in
+ unexpanded_var_list.
+ * tree-pretty-print.c (print_generic_decl): New function.
+
+2003-11-05 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * Makefile.in (gimplify.o): Add function.h dependency.
+ * c-call-graph.c (construct_call_graph): Modify build_tree_cfg call.
+ * gimple-low.c (record_vars): Export.
+ (lower_function_body): Remove the topmost BIND_EXPR.
+ * gimplify.c: Include function.h.
+ (gimple_add_tmp_var): Record temporaries in the
+ cfun->unexpanded_vars_list if available.
+ * tree-cfg.c (build_tree_cfg): Work without the topmost BIND_EXPR.
+ (dump_cfg_function_to_file): New.
+ (dump_tree_cfg): Use dump_cfg_function_to_file.
+ * tree-dump.c (dump_function_to_file): Work without the topmost
+ BIND_EXPR.
+ * tree-flow.h (build_tree_cfg): Declaration changed.
+ (dump_cfg_function_to_file, record_vars): Declare.
+ * tree-optimize.c (optimize_function_tree, tree_rest_of_compilation):
+ Work without the topmost BIND_EXPR.
+ * tree-must-alias.c (tree_compute_must_alias): Use
+ dump_cfg_function_to_file.
+ * tree-ssa-ccp.c (tree_ssa_ccp): Ditto.
+ * tree-ssa-copyprop.c (tree_ssa_copyprop): Ditto.
+ * tree-ssa-dce.c (tree_ssa_dce): Ditto.
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize_1): Ditto.
+ * tree-ssa-pre.c (tree_perform_ssapre): Ditto.
+ * tree-ssa.c (rewrite_into_ssa, rewrite_out_of_ssa): Ditto.
+ * tree-tailcall.c (tree_optimize_tail_calls): Ditto.
+ * tree.h (optimize_function_tree): Declaration changed.
+
+2003-11-03 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (handle_bb_creation): Removed.
+ (redo_dominators): Removed.
+ (insert_one_operand): Remove code to handle bb creation, since all
+ critical edges are now pre-split.
+ (finalize_2): Remove redo_dominators related code.
+ (pre_expression): Return 1 if we exited early because nothing happened.
+ (split_critical_edges): Do fake variable assignments instead, because
+ it works. return true if we actually split an edge.
+ (tree_perform_ssapre): Remove redo_dominators code.
+
+2003-11-03 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * function.h (struct function): New field unexpanded_var_list.
+ * gimple-low.c (unexpanded_var_list): Removed.
+ (record_vars, expand_used_vars): Use cfun->unexpanded_var_list.
+ * tree-flow.h (unexpanded_var_list): Declaration removed.
+
+ * gimplify.c (should_carry_locus_p): New.
+ (annotate_all_with_locus_1): Use it. Do not annotate empty
+ statements.
+
+2003-11-03 Jan Hubicka <jh@suse.cz>
+
+ * tree-cfg.c (tree_try_redirect_by_replacing_jump): Do not use
+ succesor_block.
+
+2003-11-03 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-pretty-print.c (dump_block_info): Add flags parameter.
+ Only show line number when asked to.
+ (dump_generic_node): Pass flags to dump_block_info.
+
+2003-11-03 Jan Hubicka <jh@suse.cz>
+
+ * cfghooks.h (redirect_edge_and_branch hook): Make it return edge.
+ * cfgrtl.c (cfg_layout_redirect_edge_and_branch,
+ rtl_redirect_edge_and_branch, try_redirect_by_replacing_jump):
+ Update to new interface.
+ * tree-cfg.c (tree_cfg_hooks): Move to end of file; set
+ redirect_edge_and_branch and redirect_edge_and_branch_force.
+ (thread_jumps): Use redirect_edge_and_branch.
+ (tree_block_label): new; break out of thread_edge.
+ (tree_try_redirect_by_replacing_jump): New.
+ (thread_edge): Rename to tree_redirect_edge_and_branch; deal sanely
+ with unusual edges; preserve profile.
+ (tree_redirect_edge_and_branch_force): New.
+ * tree-flow.h (ssa_redirect_edge): Declare.
+ * tree-ssa.dom.c (tree_ssa_dominator_optimize): Use redirect_edge_and_branch.
+ * tree-ssa.c (ssa_redirect_edge): New.
+
+2003-11-03 Jeff Law <law@redhat.com>
+
+ * domwalk.h (struct dom_walk_data): New field "global_data".
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize_1): Initialize new
+ "global_data" field.
+ * tree-flow.h (enum need_phi_state): New enumeration.
+ (var_ann_d): Add bitfield for need_phi_state.
+ * tree-ssa.c (mark_def_sites_global_data): New structure to hold
+ global data for mark_def_sites dominator walk.
+ (mark_def_sites): Revamp to be called via the dominator walker.
+ (set_def_block): Update need_phi_state for the variable as needed.
+ (set_livein_block): Similarly.
+ (rewrite_into_ssa): Use dominator walker to call mark_def_sites.
+ Delay freeing dominance info. Kill "globals" bitmap.
+ (insert_phi_nodes): No longer need "globals" bitmap. Use
+ need_phi_state in variable's annotation to determine if a PHI
+ may be needed.
+
+ * tree-ssa-dom.c (dom_opt_finalize_block): Try to thread across the
+ edges leaving COND_EXPR nodes which are leafs in the dominator
+ tree.
+ (record_equivalences_from_incoming_edge): Do not set EQ_EXPR_VALUE
+ unless the block's single predecessor contains parent_block_last_stmt.
+
+2003-11-03 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-dump.c (dump_options): Add TDF_LINENO.
+ * tree-pretty-print.c (dump_generic_node): Print line number for
+ statements if asked to.
+ * tree.h (TDF_LINENO): New.
+ * doc/invoke.texi (lineno): Document.
+
+2003-11-03 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * expr.c (expand_vars, expand_var): Split of ...
+ (expand_expr_1): ... here.
+ * expr.h (expand_var): Declare.
+ * gimple-low.c (lower_function_body, lower_stmt, lower_bind_expr):
+ Eliminate BIND_EXPRs.
+ (expand_used_vars): New.
+ * tree-alias-common.c (create_alias_vars): Walk variables in blocks.
+ * tree-cfg.c (make_bind_expr_blocks): Removed.
+ (make_blocks, build_tree_cfg, factor_computed_gotos): Don't handle
+ BIND_EXPRs.
+ (assign_vars_to_scope, successor_block, NEXT_BLOCK_LINK): Removed.
+ (make_edges, make_exit_edges): Don't use successor_block.
+ (remove_useless_stmts_and_vars_goto): Don't expect NEXT_BLOCK_LINK
+ to be set.
+ (bsi_init, bsi_next_in_bb, bsi_from_tsi): Don't handle BIND_EXPRs.
+ (replace_stmt): Don't create BIND_EXPRs.
+ * tree-flow.h (struct var_ann_d): Removed field scope.
+ (struct stmt_ann_d): Removed fields scope and scope_level.
+ (propagate_copy): Declaration changed.
+ (fixup_var_scope): Removed.
+ * tree-must-alias.c (tree_compute_must_alias): Consider DECL_NONLOCAL
+ vars call clobbered.
+ * tree-optimize.c (tree_rest_of_compilation): Call expand_used_vars.
+ * tree-ssa-copyprop.c (move_var_to_scope, fixup_var_scope): Removed.
+ (copyprop_stmt): Call to propagate_copy changed.
+ (propagate_copy): Don't update scope.
+ * tree-ssa-dom.c (cprop_into_stmt): Call to propagate_copy changed.
+ (eliminate_redundant_computations): Don't call fixup_var_scope.
+ * tree-ssa.c (insert_copy_on_edge): Don't update scope.
+
+2003-11-02 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-inline.c (walk_tree): Tail recursion optimized for
+ COMPOUND_EXPRs.
+ * tree-eh.c (collect_finally_tree): Ditto.
+
+2003-11-02 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-optimize.c (optimize_function_tree): Removed duplicate call of
+ lower_function_body. Moved call of reset_block_changes ...
+ (tree_rest_of_compilation) ... here. Reset the scope to top before
+ expanding function end.
+
+2003-11-01 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * basic-block.h (BB_CONTROL_STRUCTURE): Removed.
+ * tree-cfg.c (struct cfg_stats_d): Field num_merged_cases removed.
+ (make_blocks, make_bind_expr_blocks, append_stmt_to_bb, bsi_link_after,
+ build_tree_cfg, factor_computed_gotos, prepend_stmt_to_bb,
+ remove_stmt, replace_stmt): Don't set parent.
+ (set_parent_stmt, add_stmt_to_bb, find_contained_blocks,
+ blocks_unreachable_p, remove_blocks, remove_unreachable_block,
+ move_outgoing_edges, merge_tree_blocks, remap_stmts): Removed.
+ (REMOVE_ALL_STMTS, REMOVE_NO_STMTS, REMOVE_NON_CONTROL_STRUCTS,
+ REMOVE_CONTROL_STRUCTS): Removed.
+ (remove_bb): Code to handle control structures removed.
+ (tree_block_forwards_to): Don't stop due to CASE_LABEL_EXPRs.
+ (tree_dump_bb): Don't print parent. Print only BIND_EXPRs in slim
+ form.
+ (dump_tree_cfg): Don't count merged case labels.
+ (is_ctrl_structure): Removed.
+ (stmt_starts_bb_p): Don't handle CASE_LABEL_EXPRs.
+ (tree_verify_flow_info): Don't check BB_CONTROL_STRUCTURE.
+ * tree-flow-inline.h (parent_block, parent_stmt): Removed.
+ * tree-flow.h (struct stmt_ann_d): Remove parent_stmt field.
+ (parent_stmt, parent_block, is_ctrl_structure): Declarations removed.
+ * tree-pretty-print.c (dump_generic_node): Don't handle lowered
+ COND_EXPRs specially.
+ * tree-ssa-ccp.c (visit_stmt): Don't check is_ctrl_structure.
+
+2003-10-31 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (record_equivalences_from_stmt): Restore lost code
+ to create equivalences from BIT_IOR_EXPR.
+
+ * tree-ssa-dom.c (thread_jumps_walk_stmts): Go ahead and optimize
+ a COND_EXPR with a compile-time constant condition.
+
+2003-10-31 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-optimize.c (optimize_function_tree): Fix comment
+ describing SSA pass after DOM2.
+
+2003-10-31 Diego Novillo <dnovillo@redhat.com>
+
+ Fix PR optimization/12825
+ * tree-optimize.c (optimize_function_tree): Run SSA renamer after
+ second DOM pass.
+
+2003-10-30 Richard Henderson <rth@redhat.com>
+
+ * c-common.c (match_case_to_enum_1, match_case_to_enum): New.
+ (c_do_switch_warnings): New.
+ * c-common.h (c_do_switch_warnings): Declare.
+ * c-typeck.c (c_finish_case): Call it.
+ * stmt.c (all_cases_count, BITARRAY_TEST, BITARRAY_SET,
+ mark_seen_cases, check_for_full_enumeration_handling): Remove.
+ (expand_end_case_type): Don't do warn_switch handling.
+ * expr.h, tree.h: Remove dead decls.
+
+ * c-simplify.c (gimplify_switch_stmt): Force switch body non-null.
+
+2003-10-30 Richard Henderson <rth@redhat.com>
+
+ * tree-cfg.c (thread_jumps): Allow SWITCH_EXPR.
+ (thread_edge): Handle it. Tidy surrounding code.
+
+2003-10-30 Richard Henderson <rth@redhat.com>
+
+ * domwalk.c (walk_dominator_tree): Pass any final is_ctrl_stmt
+ down the recursive walk.
+
+2003-10-30 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (thread_across_edge): Renamed from
+ thread_through_successor. Revamp to thread the destination of an edge
+ rather than the successors of a block.
+ (dom_opt_finalize_block): Corresponding changes. Do not bother calling
+ thread_across_edge unless we are at a leaf in the dominator tree.
+
+ * tree-cfg.c (thread_jumps): Now returns a bool. Move some tests into
+ tree_forwarder_block_p. Improve comments.
+ (cleanup_control_flow): Now returns a bool indicating if anything was
+ changed.
+ (thread_unconditional_jumps): Kill.
+ (cleanup_tree_cfg): Repeat cascading cleanups until nothing changes.
+ (tree_forwarder_block_p): Check forwardable bit in the block's
+ annotation to avoid useless work. Mark blocks as not forwardable as
+ appropriate. Verify destination is not the exit block here. Do not
+ consider successors of the entry block as forwarders. Ignore empty
+ statements when walking through the block's statements. Verify target
+ block is not the start of a case label and that we can safely insert
+ a label at the target block.
+
+2003-10-29 Richard Henderson <rth@redhat.com>
+
+ * c-common.c (c_warn_unused_result): Remove lowered containers.
+ * c-semantics.c (genrtl_case_label): Update add_case_node call.
+ * c-simplify.c (gimplify_switch_stmt): Build SWITCH_EXPR and
+ gimplify it simultaneously with the body.
+ * expr.c (expand_expr_1): Handle SWITCH_BODY clear and
+ SWITCH_LABELS set. Update add_case_node calls.
+ * gimple-low.c (lower_stmt): Don't do anything for SWITCH_EXPR.
+ (lower_switch_expr, lower_case_label_expr): Remove.
+ * gimplify.c (gimplify_switch_expr): Zap SWITCH_BODY after
+ gimplification. Force default entry for SWITCH_LABELS.
+ (gimplify_case_label_expr): Rename from gimple_add_case_label.
+ Assert switch in scope; lower to LABEL_EXPR.
+ * stmt.c (pushcase, pushcase_range) Update add_case_node calls.
+ (add_case_node): Add dont_expand_label argument.
+ (same_case_target_p): Don't search rtl.
+ * tree-cfg.c (enum find_location_action): Remove.
+ (make_switch_expr_blocks): Remove.
+ (make_blocks): Update.
+ (make_case_label_edges): Remove.
+ (make_edges): Update.
+ (find_contained_blocks): Remove lowered containers.
+ (make_switch_expr_edges): New.
+ (make_ctrl_stmt_edges): Call it.
+ (make_cond_expr_edges): Use label_to_block.
+ (remove_useless_stmts_and_vars_1): Don't go into SWITCH_BODY.
+ (remove_unreachable_block): Remove SWITCH_EXPR special case.
+ (cleanup_cond_expr_graph): Tidy.
+ (cleanup_switch_expr_graph): Rewrite.
+ (disconnect_unreachable_case_labels): Remove.
+ (find_taken_edge_cond_expr): Use integer_zerop/integer_nonzerop.
+ (find_taken_edge_switch_expr): Rewrite.
+ (value_matches_some_label): Remove.
+ (find_case_label_for_value): New.
+ (is_ctrl_structure): Remove lowered containers.
+ (is_ctrl_stmt): Add SWITCH_EXPR.
+ (switch_parent): Remove.
+ (handle_switch_fallthru): Remove.
+ (handle_switch_split): Remove.
+ (find_insert_location): Merge into ...
+ (bsi_insert_on_edge_immediate): ... here. Simplify.
+ (tree_split_edge): Don't set EDGE_FALLTHRU.
+ * tree-eh.c (collect_finally_tree): Remove lowered containers.
+ (replace_goto_queue_1, block_may_fallthru_last): Likewise.
+ (lower_eh_constructs_1): Likewise.
+ (verify_norecord_switch_expr): New.
+ (lower_try_finally_switch): Generate lowered switches.
+ * tree-inline.c (expand_calls_inline): Don't search null SWITCH_BODY.
+ * tree-pretty-print.c (dump_generic_node): Do something sensible
+ with lowered switch_expr.
+ * tree-ssa-dom.c (record_equivalences_from_incoming_edge): Update
+ for lowered switch_expr.
+ * tree.def (SWITCH_EXPR): Update docs.
+ * tree.h (add_case_node): Update decl.
+
+2003-10-29 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (n_phi_preds): New variable.
+ (generate_vops_as_of_bb): New function
+ (generate_expr_as_of_bb): Remove unused first argument. Update all
+ callers.
+ (subst_phis): Add boundary check for the phi_pred_cache array.
+ (same_e_version_phi_result): Once modified, no point in continuing
+ the loop.
+ (finalize_2): ESSA Minimization can crash if we ended up with new
+ BB's
+
+2003-10-29 Richard Henderson <rth@redhat.com>
+
+ * tree-eh.c (do_return_redirection): Don't move copy to RESULT_DECL
+ outside the RETURN_EXPR. Introduce a new temporary as needed.
+
+2003-10-26 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (keep_function_tree_in_gimple_form): Remove.
+ (gimplify_function_tree): Return void. Remove hack for
+ language not supporting gimple.
+ * tree.h: Update decls.
+ * langhooks-def.h (LANG_HOOKS_GIMPLE_BEFORE_INLINING): New.
+ * langhooks.h (struct lang_hooks): Add gimple_before_inlining.
+ * tree-inline.c (copy_body_r): Check that instead of
+ keep_function_tree_in_gimple_form.
+ (initialize_inlined_parameters): Likewise.
+ (expand_call_inline, expand_calls_inline): Likewise.
+
+ * explow.c (probe_stack_range): Never emit loop notes.
+ * expr.c (emit_block_move_via_loop): Likewise.
+ * toplev.c (rest_of_compilation): Always synthesize loop notes.
+
+2003-10-26 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * Makefile.in (gimple-low.o): Add function.h dependency.
+ * gimple-low.c (struct lower_data): New field block.
+ (lower_function_body, lower_stmt, lower_bind_expr): Record
+ the block at statements.
+ * cfglayout.c (insn_locators_initialize): Use new info about
+ blocks.
+ * expr.c (expand_expr): Record block changes.
+ * function.c (blocks_nreverse): Export.
+ (uninitialized_vars_warning): Use DECL_RTL_SET_P to test for presence
+ of rtl.
+ (reset_block_changes, record_block_change, finalize_block_changes,
+ check_block_change, free_block_changes): New functions.
+ * function.h (struct function): New bitfield dont_emit_block_notes.
+ New field ib_boundaries_block.
+ (blocks_nreverse, reset_block_changes, record_block_change,
+ finalize_block_changes, check_block_change, free_block_changes):
+ Declare.
+ * sibcall.c (optimize_sibling_and_tail_recursive_call): Don't call
+ reorder_blocks when dont_emit_block_notes.
+ * stmt.c (expand_start_bindings_and_block, expand_end_bindings):
+ Don't emit block notes when dont_emit_block_notes.
+ * toplev.c (rest_of_compilation): Don't call reorder_blocks when
+ dont_emit_block_notes.
+ * tree.c (build1): Initialize TREE_BLOCK field.
+ * tree-flow.h (lower_function_body): Declare.
+ * tree-optimize.c: Include function.h.
+ (optimize_function_tree): Call lower_function_body.
+ * tree.h (struct tree_exp): Add block field.
+ (TREE_BLOCK): New macro.
+
+2003-10-26 Richard Henderson <rth@redhat.com>
+
+ * tree.h (tree_dump_index): Add TDI_lower.
+ * tree-dump.c (dump_files): Add .lower entry.
+ * tree-optimize.c (optimize_function_tree): Move lower_function_body,
+ (tree_rest_of_compilation): here. Tidy .useless dump.
+
+2003-10-25 Jan Hubicka <jh@suse.cz>
+
+ * c-common.c (c_estimate_num_insns_1): Kill.
+ (c_estimate_num_insns): Kill.
+ * c-common.h (c_estimate_num_insns): Kill.
+ * c-lang.c (LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS): Kill.
+ * cp-lang.c (LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS): Kill.
+ * objc-lang.c (LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS): Kill.
+ * java/lang.c (LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS): Kill.
+ (java_estimate_num_insns_1, java_estimate_num_insns): Kill.
+ * cgraphunit (cgraph_analyze_function): Use estimate_num_insns.
+ * tree-eh.c (decide_copy_try_finally): Likewise.
+ * tree-inline.c (limits_allow_inilining, optimize_inline_calls): Likewise.
+ (estimate_num_insns_1, estimate_num_insns): New functions.
+ * langhooks-def.h (LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS): Kill.
+ * langhooks.h (estimate_num_inssn): Kill.
+ * tree-inline.h (estimate_num_insns): Declare.
+
+2003-10-25 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * gimple-low.c: New.
+ * Makefile.in (gimple-low.o): Add.
+ * domwalk.c (walk_dominator_tree): Consider COND_EXPR a control
+ structure.
+ * tree-cfg.c (make_cond_expr_blocks, linearize_control_structures,
+ linearize_cond_expr): Removed.
+ (thread_jumps, tree_forwarder_block_p): New.
+ (merge_tree_blocks): Unused now.
+ (phi_alternatives_equal): Modified for use in jump threading.
+ (enum find_location_action): Remove EDGE_INSERT_LOCATION_NEW_ELSE.
+ (make_blocks): Don't call make_cond_expr_blocks.
+ (set_parent_stmt): Ensure we don't set COND_EXPR as a parent
+ statement.
+ (find_contained_blocks): Remove COND_EXPR alternative.
+ (make_cond_expr_edges): Handle lowered gotos.
+ (cleanup_tree_cfg): Don't call linearize_control_structures,
+ call thread_jumps and verify_flow_info and rerun cleanup_control_flow.
+ (remove_unreachable_block): Remove handling of structured COND_EXPRs.
+ (remove_bb): Fix warning for removed goto exprs.
+ (cleanup_control_flow, cleanup_cond_expr_graph,
+ cleanup_switch_expr_graph, find_taken_edge_cond_expr,
+ bsi_insert_before, find_insert_location, bsi_insert_on_edge_immediate):
+ Handle lowered COND_EXPRs.
+ (is_ctrl_structure): Remove COND_EXPR.
+ (is_ctrl_stmt): Add COND_EXPR.
+ (tree_verify_flow_info): Check validity of COND_EXPRs.
+ (thread_edge): Moved from tree-ssa-dom.c.
+ * tree-flow.h (cleanup_cond_expr_graph, cleanup_switch_expr_graph):
+ Declaration changed.
+ (thread_edge, lower_function_body): Declare.
+ * tree-optimize.c (optimize_function_tree): Call lower_function_body.
+ * tree-pretty-print.c (dump_generic_node): Dump lowered cond_exprs in
+ full.
+ * tree-ssa-copyprop.c (fixup_var_scope): Handle non-SSA_NAMEs.
+ * tree-ssa-dce.c (stmt_useful_p, process_worklist): Cleaned up when
+ COND_EXPRs are lowered.
+ * tree-ssa-dom.c (thread_edge): Moved to tree-cfg.c.
+ (tree_ssa_dominator_optimize_1): Dumps and setting of vars_to_rename
+ moved from thread_edge.
+ (optimize_stmt): Pass block iterator to cleanup_cond_expr_graph and
+ cleanup_switch_expr_graph.
+ * tree-ssa.c (insert_copy_on_edge): Fixup scope for emitted variables.
+
+ * dominance.c (BB_NODE): Use VARRAY_GENERIC_PTR_NOGC.
+ (calculate_dominance_info): Use VARRAY_GENERIC_PTR_NOGC_INIT.
+ * varray.c (element): Add GENERIC_PTR_NOGC entry.
+ * varray.h (enum varray_data_enum): Add VARRAY_DATA_GENERIC_NOGC.
+ (union varray_data_tag): Add generic_nogc.
+ (VARRAY_GENERIC_PTR_NOGC_INIT, VARRAY_GENERIC_PTR_NOGC,
+ VARRAY_PUSH_GENERIC_PTR_NOGC, VARRAY_TOP_GENERIC_PTR_NOGC): New.
+
+2003-10-25 Jan Hubicka <jh@suse.cz>
+
+ * cppcharset.c (one_utf8_to_utf32): Initialize 's' to silence warning.
+
+2003-10-25 Jan Hubicka <jh@suse.cz>
+
+ * fold-const.c (nondestructive_fold_binary_to_constant): Realize that
+ (plus (address) (const_int)) is a constant.
+
+2003-10-25 Jan Hubicka <jh@suse.cz>
+
+ * opts.c (decode_options): Uncomment unit-at-a-time setting
+ * params.def: Syncrhonize with manline.
+ * tree-inline.c (initialize_inlined_parameters): Set variable as
+ gimplified.
+
+2003-10-24 Steven Bosscher <steven@gcc.gnu.org>
+
+ * gimplify.c (create_artificial_label): New function.
+ (build_and_jump): Use it.
+ * c-simplify.c (c_gimplify_stmt): Likewise.
+ (gimplify_condition): Likewise.
+ * tree-cfg.c (factor_computed_gotos, tree_block_forwards_to,
+ handle_switch_fallthru, handle_switch_split): Likewise.
+ * tree-ssa-dom.c (thread_edge): Likewise.
+ * tree-ssa-pre.c (split_critical_edges): Likewise.
+ * tree-tailcall.c (eliminate_tail_call): Likewise.
+ * tree-eh.c (frob_into_branch_around,
+ honor_protect_cleanup_actions, lower_try_finally_nofallthru,
+ lower_try_finally_onedest, lower_try_finally_copy,
+ lower_try_finally_switch, lower_catch, lower_eh_filter,
+ lower_cleanup): Likewise.
+ (make_label): Remove.
+ * tree-simple.h (create_artificial_label): Add prototype.
+ * tree-inline.c (expand_call_inline): Make return label for
+ inlined function artificial.
+
+2003-10-23 Jeff Law <law@redhat.com>
+
+ * timevar.def (TV_TREE_SSA_THREAD_JUMPS): New timevar.
+ * tree-dump.c (dump_files): Add dump file for jump threading.
+ * tree.h (TDI_thread_jumps): New enum member.
+ * tree-cfg.c (tree_block_forwards_to): No longer static.
+ * tree-flow.h (tree_block_forwards_to): Prototype.
+ (tree_ssa_dominator_thread_jumps): Likewise.
+ * tree-optimize.c (optimize_function_tree): Call jump threader.
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize_1): New function.
+ Common code for redundancy elimination and jump threading on
+ the dominator tree. Slightly different callback initialization
+ for redundancy elimination and jump threading. Initialize
+ block forwardable attribute.
+ (tree_ssa_dominator_optimize): Call tree_ssa_dominator_optimize_1.
+ (tree_ssa_dominator_thread_jumps): New function.
+ (thread_edge): Mark results of PHI nodes as needing rewriting if
+ we have threaded through a block with PHI nodes.
+ (thread_through_successor): If thread_through_phis is nonzero,
+ then allow jump threading through blocks with PHI nodes. If the
+ target block is a forwarder block, then forward the jump.
+ (thread_jumps_walk_stmts): Statement walker for dominator thread
+ jumping.
+
+ * tree-ssa-dom.c (record_equivalence_from_incoming_edge): Fix
+ comment typo.
+
+2003-10-23 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (gimplify_*): Return gimplify_status.
+ (gimple_add_tmp_var): Set seen_in_bind_expr.
+ (gimplify_bind_expr): Likewise. Kill if 0 code.
+ (gimplify_return_expr): Cope with error marks.
+ (gimple_push_cleanup): Do nothing if errors seen.
+ (gimplify_expr): Cope with error marks. Use gimplify_status to
+ decide when to exit the main loop. Zap statements with errors.
+ (gimplify_body): Return void.
+ (keep_function_tree_in_gimple_form): Don't exit on errors.
+ (gimplify_function_tree): Return bool. Don't exit on errors.
+ * langhooks.c (lhd_gimplify_expr): Return GS_UNHANDLED.
+ * langhooks.h (struct lang_hooks): Update docs for gimplify_expr.
+ * tree-optimize.c (optimize_function_tree): Don't exit on errors.
+ Move delete_tree_cfg call outside optimization clause.
+ (tree_rest_of_compilation): Don't exit on errors.
+ * tree-simple.h (enum gimplify_status): New.
+ (gimplify_expr, gimplify_stmt, gimplify_body): Update.
+ * tree-ssa.c (rewrite_out_of_ssa): Move delete_tree_cfg call to
+ optimize_function_tree.
+ * tree.h (struct tree_decl): Add seen_in_bind_expr.
+ (gimplify_function_tree): Update.
+ * c-common.c (c_add_case_label): Unify three error exit paths.
+ Create a normal label, not a case label to suppress unreachable
+ code warning.
+ * c-simplify.c (c_build_bind_expr): Don't create an empty bind
+ body. Pass entire bind_expr to gimplify_stmt.
+ (gimplify_block): Don't abort on mismatches if errors seen.
+ (gimplify_expr_stmt): Cope with error marks.
+ (gimplify_decl_stmt): Likewise.
+ (c_gimplify_expr): Return gimplify_status.
+
+2003-10-22 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-pretty-print.c (dump_generic_node): Kill off ELEFT_NODE.
+ Print out status of new EUSE_LVAL flag.
+
+ * tree-ssa-pre.c: #include alloc-pool.h
+ (append_eref_to_block): Inline.
+ (names_match_p): Ditto.
+ (pre_expression): Take sbitmap of variables to rename so we can
+ mark our new variable if necessary.
+ (insert_occ_in_preorder): Completely redo to be an O(n log n)
+ algorithm worst case, instead O(n^2) all the time.
+ (build_dfn_array): New function.
+ (eref_compare): Ditto.
+ (preorder_count): Remove no-longer used variable.
+ (pre_stats): Add new stats about memory use.
+ (struct expr_info): add loadpre_cand member.
+ (euse_node_pool): New alloc-pool
+ (eref_node_pool): Ditto
+ (create_expr_ref): Use them.
+ (expr_phi_insertion): Insert on PHI's of VUSES for loadpre cands.
+ Not all expressions have uses (left occurrences don't).
+ (load_modified_real_occ_real_occ): Return false, not abort.
+ (process_delayed_rename): Remove useless fibheap, do proper LVAL
+ handling.
+ (insert_euse_in_preorder_dt_order_1): No more ELEFT_NODE's.
+ (finalize_1): Ditto.
+ (set_save): Ditto.
+ (really_available_def): New function.
+ (finalize_2): Use really_available_def, not EUSE_SAVE, during EPHI
+ minimization.
+ (names_match_p): Handle INDIRECT_REF properly.
+ (call_modifies_slot): Removed.
+ (add_call_to_ei): Removed.
+ (process_left_occs_and_kills): Fix.
+ (pre_expression): Zero out counts.
+ (collect_expressions): Split out from tree_perform_ssapre. Do this
+ in domtree order.
+ (tree_perform_ssapre): Create and free alloc-pools.
+ Rename new variables that need to be renamed.
+
+ * tree.c (tree_size): Remove ELEFT_NODE.
+ (tree_node_size): Ditto.
+ (is_essa_node): Ditto.
+
+ * tree.def (ELEFT_NODE): Gone.
+
+ * tree.h (EREF_NODE_CHECK): No more ELEFT_NODE.
+ (struct tree_eref_common): Add ID flag.
+ (struct tree_euse_node): Add lval flag.
+ (EREF_ID): New macro.
+ (EUSE_LVAL): New macro.
+
+2003-10-22 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-flow-inline.h (add_dom_child): XMALLOC, not GGC_ALLOC,
+ the bitmap.
+ (clear_dom_children): XFREE the bitmap.
+
+2003-10-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-ssa-live.c (new_tree_live_info, (delete_tree_live_info,
+ live_worklist, set_if_valid, add_livein_if_notdef,
+ calculate_live_on_entry, calculate_live_on_exit,
+ add_conflicts_if_valid, dump_live_info): Use bitmap instead of sbitmap.
+ (build_tree_conflict_graph): Use bitmap, Change mechanism for
+ adding conflicts between live-on-entry partitions.
+ * tree-ssa-live.h (struct tree_live_info_d): Switch to bitmaps.
+ (partition_is_global, live_entry_blocks, live_on_exit,
+ live_merge_and_clear, make_live_on_entry): Switch to bitmaps.
+ * tree-ssa.c (struct _elim_graph): Remove bitmaps, use varrays.
+ (new_elim_graph, clear_elim_graph, delete_elim_graph): Switch from
+ old bitmap implementation.
+ (elim_graph_size): New. Number of elements in elimination graph.
+ (elim_graph_add_node): New. Add an element to the elim-graph.
+ (elim_graph_add_edge): New. Add an edge to the elim-graph.
+ (elim_graph_remove_succ_edge): New. Remove an edge for which a node
+ has a successor.
+ (FOR_EACH_ELIM_GRAPH_SUCC): Find all successor nodes.
+ (FOR_EACH_ELIM_GRAPH_PRED): Find all predeccesor nodes.
+ (eliminate_name, eliminate_build, elim_forward,
+ elim_unvisited_predecessor, elim_backward, elim_create, eliminate_phi):
+ Use new elim-graph routines.
+ (rewrite_out_of_ssa): Enable single-definition compaction when not
+ combining temporaries.
+
+2003-10-21 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c: Sort functions into use order, and all gimplification
+ functions to the end.
+
+2003-10-22 Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (thread_unconditional_jumps): New function.
+ (tree_block_forwards_to): Likewise.
+ (cleanup_tree_cfg): Call thread_unconditional_jumps.
+ * tree-flow.h (bb_ann_t): Add forwardable status bit.
+
+ * tree-dump.c (dump_files): Add entry for TDI_none.
+ (dump_begin): Do nothing for TDI_none.
+ (dump_enable_all, dump_switch_p): Start our scan at TDI_none + 1.
+ * tree.h (tree_dump_index): Add.
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize): If we have altered the
+ CFG and we have variables to [re]rename, go ahead and rename them before
+ starting the next iteration of the dominator optimizer.
+
+2003-10-21 Jason Merrill <jason@redhat.com>
+
+ * gimplify.c (gimplify_modify_expr): Require a regvar on either
+ the lhs or rhs if we're dealing with a renameable type.
+ (canonicalize_component_ref): New fn.
+ (gimplify_compound_lval): Use it.
+ (gimplify_conversion): Use it.
+ (gimplify_expr): Lose redundant STRIP_MAIN_TYPE_NOPS.
+ Discard conversions in void context.
+
+2003-10-21 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (pre_expression): Free and allocate the
+ ephi_pindex_htab and phi_pred_cache in this function only.
+ (phi_pred_cache): New array to store cached phi preds, to avoid
+ recomputation and unnecessary copying.
+ (subst_phis): Use it.
+ (added_phis): array of added phis that is marked for GC.
+
+ * Makefile.in: Add tree-ssa-pre.c to the gtype files, and
+ gt-tree-ssa-pre.h to the list of generated files.
+
+2003-10-21 Jason Merrill <jason@redhat.com>
+
+ PR optimization/12661
+ * tree-dfa.c (get_expr_operands): Handle TRUTH_NOT_EXPR.
+ * tree-simple.c (is_gimple_rhs): Allow TRUTH_NOT_EXPR.
+ * gimplify.c (gimplify_expr) <TRUTH_NOT_EXPR>: Don't rewrite to an
+ EQ_EXPR.
+
+2003-10-21 Jan Hubicka <jh@suse.cz>
+
+ * haifa-sched.c (choose_ready): Initialize index.
+ * tree-tailcall.c (bb_optimize_tail_calls): Initialize has_return.
+ * f/lex.c (ffelex_cfelex_): Initialize d.
+
+2003-10-20 Diego Novillo <dnovillo@redhat.com>
+
+ Fix PR optimization/12688
+ * tree-dfa.c (get_stmt_operands): Don't return early when dealing
+ with an empty statement.
+ * tree-ssa-ccp.c (set_rhs): If the expression has no side effects,
+ replace the statement with an empty statement.
+
+2003-10-20 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-ssa-dce.c (processed): Change to an sbitmap.
+ (mark_necessary): Test bits in 'processed'.
+ (tree_ssa_dce): Initialize/free processed as an sbitmap.
+
+2003-10-20 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (bsi_prev): Also copy the context from the previous
+ iterator.
+
+2003-10-18 Richard Henderson <rth@redhat.com>
+
+ * builtins.c (simplify_builtin): Handle BUILT_IN_CONSTANT_P.
+
+2003-10-18 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-tailcall.c: New.
+ * Makefile.in (tree-tailcall.o): Add.
+ * function.c (assign_parms): Setting of current_function_stdarg
+ moved ...
+ (allocate_struct_function): ... here.
+ * tree-dump.c (dump_files): Add .tail dump.
+ * tree-flow.h (tree_optimize_tail_calls): Declare.
+ * tree-optimize.c (optimize_function_tree): Call
+ tree_optimize_tail_calls.
+ * tree.h (enum tree_dump_index): Add TDI_tail.
+
+2003-10-18 Jan Hubicka <jh@suse.cz>
+
+ * tree-ssa-copyprop.c (move_var_to_scope): Do not clear abstract
+ origin for static variables.
+
+2003-10-18 Jan Hubicka <jh@suse.cz>
+
+ * integrate.c (copy_decl_for_inlinig): Fix copying of copies.
+
+2003-10-18 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_analyze_function): Fix call of estimate_num_insns.
+
+2003-10-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog.tree-ssa: Fix typos.
+ * tree-alias-common.c: Fix comment typos.
+ * tree-cfg.c: Likewise.
+ * tree-dfa.c: Likewise.
+ * tree-eh.c: Likewise.
+ * tree-flow.h: Likewise.
+ * tree-iterator.h: Likewise.
+ * tree-mudflap.c: Likewise.
+ * tree-ssa-ccp.c: Likewise.
+ * tree-ssa-dce.c: Likewise.
+ * tree-ssa-dom.c: Likewise.
+ * tree-ssa-live.c: Likewise.
+ * tree-ssa-live.h: Likewise.
+ * tree-ssa-pre.c: Likewise.
+ * tree-ssa.c: Likewise.
+
+2003-10-17 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-ssa-dce.c (processed): New Global vector.
+ (mark_necessary): Check if SSA_NAME has already been processed first.
+ (find_useful_stmts, process_worklist): Change call to mark_necessary().
+ (tree_ssa_dce): Initialize and free processed vector.
+ * tree-cfg.c (handle_switch_fallthru): A new basic block can result
+ from splitting edges of nested switch stmts.
+ (handle_switch_split): If a new block is created, restart the loop for
+ inserting GOTO's to handle the new block.
+
+2003-10-17 Jan Hubicka <jh@suse.cz>
+
+ * tree-cfg.c (remove_useless_stmts_and_vars_bind): Fix handling of
+ static variables.
+
+2003-10-16 Richard Henderson <rth@redhat.com>
+
+ * common.opt (fdisable-gimple): Remove.
+ * flags.h (flag_disable_gimple): Remove.
+ * toplev.c (flag_disable_gimple): Remove.
+ (process_options): Don't check it.
+ (lang_independent_options): Don't set it.
+ * opts.c (common_handle_option): Likewise.
+ * gimplify.c (keep_function_tree_in_gimple_form): Don't check it.
+ * c-semantics.c (expand_stmt_toplev): Likewise.
+ * tree-optimize.c (tree_rest_of_compilation): Likewise.
+ * doc/invoke.texi: Don't document it.
+
+2003-10-16 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c: Merge from mainline.
+ * tree.c (associate_tree_code, commutative_tree_code): Use a
+ switch statement instead of a sequence of comparisons.
+
+2003-10-16 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (maybe_protect_cleanup): Remove.
+ * tree-simple.h (maybe_protect_cleanup): Remove.
+ * c-simplify.c (gimplify_cleanup): Don't call it.
+
+2003-10-16 Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (found_computed_goto): New global for computed goto
+ factoring/unfactoring.
+ (factored_computed_goto_label, factored_computed_goto): Likewise.
+ (factor_computed_gotos): New function.
+ (build_tree_cfg): Use it.
+ (make_blocks): Record whether or not we find a computed goto.
+ (remove_useless_stmts_and_vars): Un-factor computed gotos.
+ (remove_useless_stmts_and_vars): Reset factored_computed_goto_label
+ and factored_computed_goto.
+
+ * tree-ssa-dom.c (get_value_for, set_value_for): Move to the start
+ of the file. Delete pointless sanity checking.
+
+ * tree-ssa.c (currdefs): Now a varray instead of a hash table.
+ (get_value_for, set_value_for): Corresponding changes. Move to
+ the start of the file and delete pointless sanity checking.
+ (rewrite_into_ssa, dump_tree_ssa_stats): Corresponding changes.
+ (var_value_hash, var_value_eq): Kill.
+
+ * tree-ssa.c (rewrite_add_phi_arguments): Once we encounter a
+ rewritten PHI break the inner loop.
+
+ * tree-ssa.c (insert_phi_nodes_for): Use EXECUTE_IF_AND_COMPL_IN_BITMAP.
+
+ * tree-dfa.c (create_phi_node): Clear PHI_REWRITTEN on all new PHIs
+ (remove_all_phi_nodes_for): Set PHI_REWRITTEN on any PHIs which are
+ not removed.
+ * tree-ssa.c (rewrite_add_phi_arguments): Check the PHI node itself
+ to see if it has already been rewritten.
+ * tree.h (PHI_REWRITTEN): New accessor macro.
+ (struct phi_node): New field rewritten.
+
+ * tree-flow.h (struct bb_ann_d): New field num_preds.
+ * tree-dfa.c (create_phi_node): Get the number of predecessors from
+ the block's annotation.
+ * tree-ssa.c (rewrite_into_ssa): Compute number of preds for each
+ block and store it into the block's annotation.
+ (insert_phi_nodes_for): Get the number of preds for each block
+ from the block's annotation.
+
+ * tree-ssa.c: Remove parallel lifetime analysis code from April 2003.
+ (def_blocks_d): Remove PHI_INSERTION_POINTS field.
+ (compute_global_livein): Accept livein/def bitmaps to use for
+ life analyis rather than a varray of variables. Callers updated.
+ Rewritten to compute life information for one variable at a
+ time instead of several variables at once.
+ (insert_phis_for_deferred_variables): Remove.
+ (insert_phi_nodes_for): Lose varray argument. Callers updated.
+ No longer mess with deferring PHI insertions for variables.
+ (insert_phi_nodes): No longer need to deal with deferred variables.
+ Kill everything related to them.
+
+2003-10-15 Jeff Law <law@redhat.com>
+
+ * domwalk.c, domwalk.h: New files.
+ * Makefile.in (OBJS-common): Add domwalk.c.
+ (tree-ssa-dom.o): Add dependency on $(BASIC_BLOCK_H) and domwalk.h.
+ (tree-ssa.o): Add dependency on domwalk.h.
+ (domwalk.o): Add dependencies.
+ * tree-ssa-dom.c: Include domwalk.h.
+ (cfg_altered, vars_to_rename): Now globals.
+ (dom_walk_block_data): New structure for block data used by dominator
+ walker.
+ (optimize_block, record_equivalences_from_block_entry): Kill.
+ (optimize_stmt): Lose "cfg_altered" argument. Update callers.
+ Initialize may_have_exposed_new_symbols.
+ (get_value_for, set_value_for): Lose "table" argument. Update
+ callers. Use const_and_copies table directly.
+ (lookup_avail_expr): Lose "const_and_copies" argument. Callers
+ updated.
+ (get_eq_expr_value): Similarly. Also accept a pointer to the
+ vrp_variables. Callers updated.
+ (update_rhs_and_lookup_avail_expr): Similarly.
+ (record_cond_is_true, record_cond_is_false): Similarly.
+ (simplify_rhs_and_lookup_avail_expr): Similarly.
+ (simplify_cond_and_lookup_avail_expr): Similarly.
+ (record_equivalences_from_phis): Similarly.
+ (record_equivalences_from_incoming_edge): Similarly. Also accept
+ a pointer to the block const_and_copies table and vrp_variables.
+ Callers updated.
+ (eliminate_redundant_computations): Similarly
+ (record_equivalences_from_stmt, thread_through_successor): Similarly.
+ (dom_opt_initialize_block): New function. Perform block local
+ initialization for the dominator optimizer.
+ (dom_opt_finalize_block): Renamed from finalize_block. Get
+ block local varrays from walk_data. Pop entry off block local
+ data stack when complete.
+ (dom_opt_walk_stmts): New function.
+ (cprop_into_phis): Get block local varrays from walk_data.
+ (record_range): Get vrp varray by reference than by value.
+ (tree_ssa_dominator_optimize): Store incoming "vars" variable into
+ global "vars_to_rename". Initialize walk_data. Use
+ walk_dominator_tree.
+ (cprop_into_stmt): Initialize may_have_exposed_new_symbols.
+ * tree-ssa.c: Include domwalk.h
+ (rewrite_finalize_block, rewrite_initialize_block): New functions
+ extracted from rewrite_block.
+ (rewrite_walk_stmts, rewrite_add_phi_arguments): Similarly.
+ (rewrite_block): Kill.
+ (rewrite_into_ssa): Initialize walk_data. Use walk_dominator_tree.
+
+2003-10-14 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (gimplify_expr): Return bool. Bail gracefully if
+ fb_mayfail is set.
+ (gimplify_asm_expr): Take pointer-to-expr. Allow gimplify_expr
+ to fail for lvalues, and issue appropriate error messages. Zap
+ the entire asm statement on failure.
+ * tree-simple.h (enum fallback_t): Add fb_mayfail.
+
+2003-10-14 Richard Henderson <rth@redhat.com>
+
+ * c-tree.h (C_LANG_TREE_NODE_CHAIN_NEXT): New.
+ (union lang_tree_node): Use it for chain_next annotation.
+
+2003-10-14 Richard Henderson <rth@redhat.com>
+
+ * c-common.c: Include tree-iterator.h.
+ (c_expand_expr): Kill warn_unused_result checks.
+ (c_warn_unused_result): New.
+ * c-common.h (STMT_EXPR_WARN_UNUSED_RESULT): Remove.
+ (c_warn_unused_result): Declare.
+ * c-decl.c (finish_function): Always gimplify. Call
+ c_warn_unused_result.
+ * calls.c (expand_call): Kill warn_unused_result checks.
+ * Makefile.in (c-common.o): Update.
+
+2003-10-15 Steven Bosscher <steven@gcc.gnu.org>
+
+ * cfghooks.c (dump_bb): Take extra `int indent' argument.
+ * cfg.c (dump_bb): Take extra argument to match cfg hook.
+ Write out all information about bb that is shared between the tree
+ and rtl representations.
+ * basic-block.c (dump_bb): Adjust prototype.
+ * cfgrtl.c (rtl_dump_bb): Update prototype to match cfg hook.
+ Use indent.
+ * flow.c (verify_wide_reg, verify_local_live_at_start):
+ Fixup dump_bb calls.
+ * tree-cfg.c (dump_tree_bb): Rename to tree_dump_bb. Remove unused
+ `prefix' argument. Put in tree_cfg_hooks as cfg hook for dump_bb.
+ (remove_bb, debug_tree_bb, dump_tree_cfg): Call dump_bb.
+ * tree-ssa (dump_tree_ssa): Likewise.
+ * tree-flow.h (dump_tree_bb): Replace with new tree_dump_bb
+ prototype.
+ * tree-pretty-print (dump_block_info): Match case of BLOCK, SUCC,
+ PRED with dump_bb.
+
+2003-10-14 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-ander.c (throwaway_global): Delete.
+ (andersen_same_ponts_to_set): We handle all globals individually
+ now.
+ * tree-alias-common.c: Remove doxygen markers.
+ (get_alias_var_decl): Always create an alias var for globals now.
+ Assign the global alias vars to GLOBAL_VAR, too.
+ (intra_function_call): Fix logic, do a bit of pre-filtering to
+ avoid useless global aliasing.
+ (get_values_from_constructor): It's the same for field based and
+ not field based.
+ (create_alias_vars): Remove special global var handling.
+ (same_points_to_set): Ditto.
+ (ptr_may_alias_var): Ditto.
+
+2003-10-14 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (cprop_into_phis): Avoid doing useless work if the
+ edge we care about is abnormal.
+ * tree-ssa-copyprop (cprop_phi): Avoid doing useless work if the
+ destination of the PHI node occurs in an abnormal PHI.
+
+ * tree-ssa-dom.c (record_equivalences_from_stmt): Renamed from
+ record_equivalances. Caller updated.
+ (record_equivalences_from_phis): New function extracted from
+ optimize_block.
+ (record_equivalences_from_incoming_edge): Likewise.
+ (record_equivalances_from_block_entry): Likewise.
+ (cprop_into_phis): Likewise.
+ (optimize_stmt): Lots of code moved into new functions. Call
+ record_equivlances_from_block_entry.
+
+ * tree-ssa-dom.c (optimize_block): Simplify interface slightly.
+ Use finalize_block. Extract edge_flags from our block's
+ incoming edge as necessary. Simplify recursive call.
+ (thread_through_successor): Extracted from optimize_block.
+ (finalize_block): Similarly.
+
+ * tree-ssa-dom.c (eliminate_redundant_computations): New function
+ extracted from optimize_stmt.
+ (record_equivalences): Similarly.
+ (optimize_stmt): Use eliminate_redundant_computations and
+ record_equivalences. If fold_stmt changes stmt, then make sure
+ to get a new annotation as well.
+
+ * tree-cfg.c (cleanup_control_flow): Pass last statement down to
+ cleanup_cond_expr_graph and cleanup_switch_expr_graph.
+ (cleanup_cond_expr_graph): Accept statement from caller and
+ use it. Return nonzero if the predicate was constant. No longer
+ static.
+ (cleanup_switch_expr_graph): Similarly.
+ (disconnect_unreachable_case_labels): Similarly, except that it
+ is still static.
+ * tree-flow.h (cleanup_cond_expr_graph): Prototype.
+ (cleanup_switch_expr_graph): Similarly.
+ * tree-ssa-dom.c (optimize_stmt): Also optimize the condition
+ in a SWITCH_EXPR. Use COND_EXPR_COND and SWITCH_COND to get
+ conditions instead of relying upon known operand positions.
+ Use cleanup_cond_expr_graph and cleanup_switch_expr_graph rather
+ than open coding equivalents.
+ (lookup_avail_expr): Handle SWITCH_EXPRs. Use COND_EXPR_COND and
+ SWITCH_COND to get conditions instead of relying upon known
+ operand positions.
+ (avail_expr_hash, avail_expr_eq): Similarly.
+
+2003-10-14 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (gimplify_body): Save and restore input_location;
+ initialize input_location to DECL_SOURCE_LOCATION.
+ (gimplify_expr): Always save and restore input_location.
+
+2003-10-14 Richard Henderson <rth@redhat.com>
+
+ * expr.c (expand_expr): Break out EXPR_LOCUS code from ...
+ (expand_expr_1): ... here, renamed from expand_expr.
+
+2003-10-13 Richard Henderson <rth@redhat.com>
+
+ * c-simplify.c (c_gimplify_stmt): Upreate on location_t and not
+ fine and line individually.
+ (gimplify_c_loop, gimplify_switch_stmt): Likewise.
+ * gimplify.c (wfl_locus): Merge wfl_filename+wfl_lineno.
+ (annotate_all_with_locus_1): Rename from annotate_stmt_with_file_line.
+ (annotate_all_with_locus): Replace annotate_all_with_file_line;
+ update all callers.
+ * tree-simple.h: Update.
+ * tree.c, tree.h (annotate_with_locus): New.
+
+2003-10-13 Steven Bosscher <steven@gcc.gnu.org>
+
+ * tree-flow-inline.h (def_ops): Take a stmt_ann_t as argument
+ instead of a tree.
+ (use_ops): Likewise.
+ (vdef_ops): Likewise.
+ (vuse_ops): Likewise.
+ * tree-flow.h: Update prototypes.
+ * tree-cfg.c (remove_stmt): Load the statement annotation.
+ Adjust *_ops calls.
+ * tree-dfa.c (compute_immediate_uses_for_stmt,
+ mark_new_vars_to_rename): Likewise.
+ * tree-pretty-print.c (dump_vops): Likewise.
+ * tree-ssa-ccp.c (tree_ssa_ccp): Likewise. Also remove now
+ superfluous stmt_ann() calls.
+ (visit_stmt, cpp_fold, add_var_to_ssa_edges_worklist,
+ initialize, replace_uses_in, likely_value): Likewise.
+ * tree-ssa-copyprop.c (copyprop_stmt): Likewise.
+ * tree-ssa-dce.c (stmt_useful_p, process_worklist): Likewise.
+ * tree-ssa-dom.c (cprop_into_stmt, optimize_stmt,
+ avail_expr_hash, avail_expr_eq):
+ Likewise.
+ * tree-ssa-live.c (create_ssa_var_map, calculate_live_on_entry,
+ build_tree_conflict_graph): Likewise.
+ * tree-ssa-pre.c (maybe_find_rhs_use_for_var,
+ expr_phi_insertion, same_e_version_real_occ_real_occ,
+ generate_expr_as_of_bb, bool load_modified_real_occ_real_occ,
+ bool same_e_version_phi_result, get_default_def,reaching_def,
+ tree_perform_ssapre): Likewise.
+ * tree-ssa.c (mark_def_sites, rewrite_out_of_ssa, rewrite_stmt):
+ Likewise.
+
+2003-10-12 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (gimplify_array_ref_to_plus): Be prepared for
+ null TYPE_DOMAIN or TYPE_MIN_VALUE for the array.
+ * tree-ssa-ccp.c (fold_indirect_refs_r): Likewise.
+
+2003-10-12 Richard Henderson <rth@redhat.com>
+
+ * tree.h (struct tree_common): Rename unused_1 to invariant_flag.
+ (TREE_INVARIANT): New.
+ * builtins.c (build_string_literal): Set TREE_INVARIANT.
+ * c-common.c (fix_string_type): Likewise.
+ * c-typeck.c (build_external_ref): Likewise.
+ (build_c_cast, pop_init_level): Likewise.
+ * fold-const.c (fold_convert, fold): Likewise.
+ * tree.c (make_node, build_constructor): Likewise.
+ (build, build1): Likewise.
+ (staticp): Pass unknown component references to the language.
+ (save_expr): Check TREE_INVARIANT instead of TREE_CONSTANT.
+ (skip_simple_arithmetic): Likewise.
+ (stabilize_reference_1): Likewise.
+ * print-tree.c (print_node): Print TREE_INVARIANT.
+
+ * c-common.c (pointer_int_sum): Rely on build to set TREE_CONSTANT.
+ (finish_label_address_expr): Likewise.
+ * c-typeck.c (default_function_array_conversion): Likewise.
+ (parser_build_binary_op, pointer_diff): Likewise.
+ (build_unary_op, build_binary_op): Likewise.
+ * fold-const.c (non_lvalue): Likewise.
+
+ * tree-pretty-print.c (dump_generic_node): Handle VIEW_CONVERT_EXPR.
+
+2003-10-12 Richard Henderson <rth@redhat.com>
+ Diego Novillo <dnovillo@redhat.com>
+
+ * gimplify.c (gimplify_array_ref_to_plus): Subtract the array
+ domain minimum index.
+ (gimplify_addr_expr): Expand ARRAY_REFs. Cope with Fortran
+ missing cast wierdnesses.
+ * tree-dfa.c (get_expr_operands): Handle (&v + c); abort on
+ other address invariants that should have been folded.
+ (vdefs_disappeared_p): New.
+ (mark_new_vars_to_rename): Use it. Move from ...
+ * tree-ssa-dom.c: ... here.
+ * tree-flow-inline.h (is_unchanging_value): Remove; use
+ is_gimple_min_invariant everywhere instead.
+ (phi_ssa_name_p): New.
+ * tree-must-alias.c (find_addressable_vars): Process PHIs.
+ * tree-simple.c (is_gimple_min_invariant): Rename from
+ is_gimple_const; allow non-static variable addresses; update callers.
+ (is_gimple_val): Remove ADDR_EXPR checks.
+ * tree-simple.h: Update.
+ * tree-ssa-ccp.c (replace_uses_in): Add replaced_address argument.
+ (substitute_and_fold): Use that to mark_new_vars_to_rename.
+ (fold_indirect_refs_r): New.
+ (fold_stmt): Use it.
+ * tree-ssa-copyprop.c (copyprop_stmt): Call fold_stmt.
+ * tree-ssa-dce.c (NECESSARY): Use asm_written_flag.
+ (mark_necessary): Reject DECLs.
+ * tree-ssa-live.c (register_ssa_partition): Use phi_ssa_name_p.
+ * tree-ssa-pre.c (generate_expr_as_of_bb): Call fold_stmt if we
+ replaced with constants.
+ * tree-ssa.c (insert_copy_on_edge): Unwrap ADDR_EXPRs to set_is_used.
+ (eliminate_build, coalesce_abnormal_edges, coalesce_vars): Use
+ phi_ssa_name_p.
+
+2003-10-09 Frank Ch. Eigler <fche@redhat.com>
+
+ java/12211
+ * gimplify.c (gimplify_save_expr): Tolerate void-typed saved
+ expressions.
+
+2003-10-09 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (add_call_clobber_ops): If a variable is read-only,
+ add a VUSE operand instead of VDEF.
+
+2003-10-08 Jason Merrill <jason@redhat.com>
+
+ PR optimization/12525
+ * tree-dfa.c (note_addressable): New fn, split out from...
+ (add_stmt_operands): Here.
+ (get_stmt_operands) <ASM_EXPR>: Call it for mem ops.
+ * gimplify.c (gimplify_asm_expr): Call parse_input_constraint
+ directly. It's only a mem op if allows_mem is set.
+
+2003-10-08 Diego Novillo <dnovillo@redhat.com>
+
+ PR/12187
+ * tree-dfa.c (add_stmt_operand): Test against current_function_decl
+ when checking for global variables.
+ (may_access_global_mem_p): Likewise.
+ (add_referenced_var): Likewise.
+ Consider DECL_NONLOCAL variables call clobbered and used.
+ (find_hidden_use_vars): Do not test for DECL_NONLOCAL variables.
+ * tree-optimize.c (tree_rest_of_compilation): Test against
+ current_function_decl when checking for global variables.
+ * tree-ssa-ccp.c (get_default_value): Likewise.
+ * tree-ssa-dce.c (need_to_preserve_store): Likewise.
+
+2003-10-07 Jason Merrill <jason@redhat.com>
+
+ PR optimization/12525
+ * gimplify.c (gimplify_asm_expr): If the constraint doesn't allow
+ a register, call mark_addressable. Split an in/out operand that
+ does allow a register into separate input and output operands.
+
+2003-10-06 Richard Henderson <rth@redhat.com>
+
+ * fold-const.c (fold): Fold (T1)((T2)X op Y) into (T1)X op Y,
+ for suitable values of T1 & T2.
+
+2003-10-06 Andrew Macleod <amacleod@redhat.com>
+
+ * tree-dfa.c (compute_immediate_uses): Add optional callback.
+ (compute_immediate_uses_for_phi): Remove unused parameter. Add optional
+ callback to determine if usage info should be calculated for variable.
+ (compute_immediate_uses_for_stmt): Add optional callback to determine
+ if usage info should be calculated for variable.
+ * tree-flow.h (compute_immediate_uses): Update prototype.
+ * tree-ssa-ccp.c (need_imm_uses_for): New. Callback function passed to
+ compute_immediate_uses.
+ (initialize): Calculate defaults initially, then build reduced
+ immediate use information.
+ (get_default_value): Non empty stmt's which are not a PHI_NODE or
+ a MODIFY_EXPR default to VARYING.
+
+2003-10-06 Andrew Macleod <amacleod@redhat.com>
+
+ * tree-cfg.c (tree_split_edge): Mark edge as FALLTHRU when splitting.
+
+2003-10-03 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-ssa.c (rewrite_block): Test vars_to_rename instead of
+ PHI_ARG_CAPACITY.
+ * tree-dfa.c (remove_phi_arg_num): Don't update
+ PHI_ARG_CAPACITY.
+
+2003-10-01 Richard Henderson <rth@redhat.com>
+
+ * c-decl.c (set_decl_nonlocal): New.
+ (store_parm_decls): Use it via walk_tree.
+
+2003-10-01 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (cprop_into_stmt): New function extracted from
+ optimize_stmt.
+ (optimize_stmt): Use cprop_into_stmt.
+
+2003-09-30 Richard Henderson <rth@redhat.com>
+
+ * function.h (struct function): Add function_end_locus.
+ * c-decl.c (finish_function): Set it.
+ * tree-optimize.c (tree_rest_of_compilation): Set input_location
+ to function_end_locus before expand_function_end.
+
+ * tree-optimize.c (optimize_function_tree): Move calls to
+ remove_useless_stmts_and_vars and lower_eh_constructs ...
+ (tree_rest_of_compilation): ... here.
+
+ * c-simplify.c (gimplify_expr_stmt): Don't warn for any statement
+ with void result type.
+
+2003-09-30 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (simplify_cond_and_lookup_avail_expr): Fix thinko
+ in test for swapping ranges.
+
+ * tree-ssa-dom.c (record_range): New function.
+ (extract_range_from_cond): Likewise.
+ (tree_ssa_dominator_optimize): Initialize the vrp_data varray.
+ (optimize_block): Initialize the vrp_variables varray. Wipe
+ appropriate entries from the VRP varrays when done processing a block.
+ (get_eq_expr_value): Accept new argument "bb". Call record_range
+ appropriately. Refactor code to avoid useless work.
+ (simplify_cond_and_lookup_avail_expr): Use value range records to
+ simplify conditions.
+ (simplify_rhs_and_lookup_avail_expr): When simplifying ABS_EXPR,
+ DIV_EXPR and MOD_EXPR, use simplify_cond_and_lookup_avail_expr
+ to determine the range of the given variable.
+
+ * tree-ssa-dom.c (find_equivalent_equality_comparison): Do not
+ look through a typecast which narrows a value.
+
+2003-09-30 Paul Brook <paul@nowt.org>
+
+ * Makefile.in: Add rules for check-gfortran.
+
+2003-09-29 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (gimplify_cond_expr): Fix both arms dead return value.
+
+2003-09-29 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (simplify_cond_and_lookup_avail_expr): New function.
+ (find_equivalent_equality_comparison): Likewise.
+ (optimize_block): Remove code to build a == c equivalence after
+ seeing a == b and b == c. Remove code to walk backwards
+ though typecasts to record equivalences and move relevant parts
+ into find_equivalent_equality_comparison.
+ (optimize_stmt): Call simplify_cond_and_lookup_avail_expr.
+
+2003-09-28 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (gimplify_call_expr): Annotate all call_exprs.
+ * tree-inline.c (expand_call_inline): Set input_location based
+ on EXPR_LOCUS; save and restore input_location around that.
+ (walk_tree): Do not set input_location.
+
+2003-09-27 Graham Stott <graham.stott@btinternet.com>
+
+ * expr.c (expand_expr)[CATCH_EXPR]: Fix bogus return value.
+
+2003-09-26 Andrew MacLeod <amacloeod@redhat.com>
+
+ * tree-ssa-dom.c (struct var_value_d): Remove.
+ (const_and_copies): Change to a varray_type.
+ (tree_ssa_dominator_optimize): Initialize const_and_copies as a varray.
+ (optimize_block): Simply set the value in const_and_copies.
+ (dump_dominator_optimization_stats): No hash stats for const_and_copies.
+ (record_cond_is_true, record_cond_is_false,
+ simplify_rhs_and_lookup_avail_expr, update_rhs_and_lookup_avail_expr):
+ Parameter const_and_copies is now a varray_type.
+ (var_value_hash, var_value_eq): Remove.
+ (get_value_for, set_value_for): Access varray elements.
+ (get_eq_expr_value): Parameter const_and_copies is now a varray_type.
+
+ * tree-cfg.c (handle_switch_split): Update container of previous stmt.
+
+2003-09-25 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (split_critical_edges): New function, temporarily
+ disabled until some edge splitting/insertion problems are fixed.
+ (opnum_of_ephi): Take an edge argument, constify. Use hash table lookup.
+ Update all callers.
+ (ephi_pindex_eq): New function.
+ (ephi_pindex_hash): New function.
+ (ephi_pindex_htab): New variable.
+ (add_ephi_pred): Update hash table.
+ (expr_phi_insertion): Don't free the bitmap returned by compute_idfs
+ anymore.
+ (idfs_cache): New variable.
+ (compute_idfs): Rewrite to use cache as much as possible, and not
+ recompute when we can avoid it.
+
+2003-09-25 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-ander.c: Fixup comment spacing.
+ (andersen_op_assign): Handle >2 operands case.
+
+2003-09-24 Steven Bosscher <steven@gcc.gnu.org>
+
+ * tree-dfa.c (compute_immediate_uses_for): Split up in two
+ separate functions, one for PHIs and one for normal statements.
+ (compute_immediate_uses_for_phi): New.
+ (compute_immediate_uses_for_stmt): New.
+
+2003-09-25 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (optimize_block): When EQ_EXPR_VALUE has the
+ form DEST = SRC where both DEST and SRC are SSA_NAMEs also
+ record SRC = DEST into the const and copies table.
+
+ * tree-ssa-dom.c (optimize_block): Change tests which checked
+ for SSA_VAR_P to only allow SSA_NAMEs.
+ (get_value_for, set_value_for): Likewise.
+ (lookup_avail_expr, get_eq_expr_value): Likewise.
+
+2003-09-25 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-ssa-dce.c (pdom_info, needed_stmts): Remove.
+ (NECESSARY): Define.
+ (necessary_p): Check bit instead of hash table lookup.
+ (clear_necessary): New. Clear necessary bit.
+ (mark_necessary): Use bit instead of hash table. No control lookup.
+ (mark_tree_necessary): Remove.
+ (find_useful_stmts): Clear necessary bit before checking it.
+ (stmt_useful_p): Remove GOTO_EXPR case. Check arms of COND_EXPR for
+ GOTO. All other control flow stmts are necessary.
+ (process_worklist): Dont look for control parents.
+ (remove_dead_stmts): No dominattor info is necessary.
+ (remove_dead_stmt): Don't need BB any more. Remove COND_EXPR by changing
+ the condition to 'if (0)'. Abort on other control flow.
+ (tree_ssa_dce): No longer need the hash table.
+ (remove_conditional): Remove.
+
+2003-09-25 Andreas Schwab <schwab@suse.de>
+
+ * tree-flow.h: Declare next_ssa_version.
+ * tree-ssa-ccp.c: Remove conflicting declaration.
+ * tree-ssa-live.c: Likewise.
+ * tree.c (make_ssa_name): Likewise.
+
+2003-09-24 Jason Merrill <jason@redhat.com>
+
+ * tree.h (DECL_SOURCE_LOCATION): Resurrect.
+ (DECL_SOURCE_FILE, DECL_SOURCE_LINE): Likewise.
+ (EXPR_LOCUS): Renamed from TREE_LOCUS. Null for non-exprs.
+ (SET_EXPR_LOCUS): New macro.
+ (EXPR_FILENAME): Renamed from TREE_FILENAME.
+ (EXPR_LINENO): Renamed from TREE_LINENO.
+ (struct tree_common): Remove locus field.
+ (struct tree_decl): Re-add locus field.
+ (struct tree_expr): Add locus field.
+ * c-aux-info.c, c-decl.c, coverage.c, c-parse.in, dbxout.c,
+ diagnostic.c, dwarf2out.c, expr.c, function.c, gimplify.c,
+ integrate.c, print-tree.c, stmt.c, tree.c, tree-cfg.c,
+ tree-dump.c, tree-flow-inline.h, config/alpha/alpha.c,
+ config/mips/mips.c: Adjust.
+
+2003-09-24 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-ssa-ccp.c (enum latticevalue): Add UNINITIALIZED.
+ (const_values, struct value_map_d): Remove hash table structures.
+ (value_vector): New array of values.
+ (get_value): Use value_vector instead of hash table. Mark inline.
+ (visit_phi_node): Ignore arguments if the PHI result is already VARYING.
+ (initialize): Initialize value vector instead of hash table.
+ (finalize): Free value vector instead of hash table.
+ (add_var_to_ssa_edges_worklist): Don't add to worklist if
+ DONT_SIMULATE_AGAIN flag is set.
+ (value_map_hash, value_map_eq): Delete.
+
+2003-09-24 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (optimize_block): Create infrastructure for
+ tracking const_and_copies equivalences which disappear when
+ we leave the current block. Use it for equivalences created
+ by EQ_EXPR_VALUE. Follow use-def chains for EQ_EXPR_VALUE
+ equivalences and see if certain NOP_EXPRs can be ignored
+ to create a block-local equivalence for const_and_copies.
+ (optimize_stmt): Do not get confused by a cast of the return
+ value from alloca or the address of a non-weak decl.
+
+ * fold-const.c (fold_read_from_constant_string): New function.
+ * tree.h (fold_read_from_constant_string): Prototype.
+ * expr.c (expand_expr, case INDIRECT_REF): Use it.
+ (expand_expr, case ARRAY_REF): Likewise. Put checking code
+ inside an ENABLE_CHECKING.
+ * tree-ssa-ccp.c (fold_stmt): Use fold_read_from_constant_string.
+ * tree-ssa-dom.c (simplify_rhs_and_lookup_avail_expr): Likewise.
+
+2003-09-23 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (optimize_block): Ignore "useless" type
+ conversions in SWITCH_COND when creating equivalenecs at
+ case labels.
+
+2003-09-22 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (optimize_stmt): Addresses of non-weak symbols
+ as well as dynamically allocated stack space are always nonzero.
+
+ * tree-cfg.c (handle_switch_split): Properly mark the fallthru
+ edge from SRC to DEST with EDGE_FALLTHRU.
+
+2003-09-22 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-flow.h (struct bb_ann_d): Add erefs array.
+ * tree-ssa-pre.c (handle_bb_creation): Remove ei parameter.
+ Update caller.
+ (struct expr_info): Remove erefs array.
+ (append_eref_to_block): New function.
+ (clear_all_eref_arrays): Ditto.
+ (expr_phi_insertion): Use append_eref_to_block.
+ (insert_occ_in_preorder_dt_order_1): Ditto.
+ (subst_phis): Only copy expression, not the containing EUSE/EPHI.
+ Update all callers to reflect this.
+ (compute_will_be_avail): Update for per-block eref array.
+ (handle_bb_creation): Ditto.
+ (pre_expression): Ditto.
+ (tree_perform_ssapre): Clear eref arrays when done with expression.
+
+2003-09-22 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (dump_tree_bb): Remove superlfuous newlines.
+
+2003-09-21 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (compute_alias_sets): Use TDI_alias instead of
+ TDI_ssa.
+ * tree-dump.c (dump_files): Add enties for TDI_alias, TDI_ssa1,
+ TDI_dom1, TDI_ssa2, TDI_dce1, TDI_ssa3, TDI_dom2, TDI_ssa4,
+ TDI_ssa5 and TDI_dce2.
+ Remove entries for TDI_ssa, TDI_dom and TDI_dce.
+ * tree.h (enum tree_dump_index): Similarly.
+ (TDF_ALIAS): Remove.
+ (TDF_VOPS): Change value.
+ * doc/invoke.texi (-fdump-tree-alias): Document.
+ * tree-flow.h (tree_warn_uninitialized): Remove unused variable.
+ (rewrite_into_ssa): Add enum tree_dump_index argument. Update all
+ callers.
+ (rewrite_out_of_ssa): Likewise.
+ (tree_perform_ssa_pre): Likewise.
+ (tree_ssa_dominator_optimize): Likewise.
+ (tree_ssa_dce): Likewise.
+ (tree_ssa_copyprop): Likewise.
+ (tree_ssa_ccp): Likewise.
+ Add sbitmap argument.
+ (tree_compute_must_alias): Likewise.
+ (mark_new_vars_to_rename): Declare.
+ * tree-must-alias.c (tree_compute_must_alias): Do not call
+ rewrite_into_ssa.
+ Remove local vars_to_rename. Use new argument instead.
+ * tree-optimize.c (optimize_function_tree): Re-write optimization
+ ordering to support passes that need the SSA form updated.
+ Call tree_ssa_dominator_optimize.
+ Re-arrange optimization ordering.
+ * tree-ssa-ccp.c (substitute_and_fold): Take new argument
+ vars_to_rename.
+ Call mark_new_vars_to_rename.
+ (visit_phi_node): Move variable 'val' into the right scope.
+ (initialize): Move call dump_begin ...
+ (tree_ssa_ccp): ... here.
+ * tree-ssa-dom.c (mark_new_vars_to_rename): Declare extern.
+ Make sure that variables in virtual operands aren't marked
+ unnecessarily.
+ * tree-ssa.c (rewrite_into_ssa): Do not call
+ tree_ssa_dominator_optimize.
+
+2003-09-21 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa-dce.c (dom_info): Remove unused variable.
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize): If the CFG has been
+ altered, call cleanup_tree_cfg.
+ Call cleanup_tree_cfg before returning.
+ * tree-ssa-pre.c (tree_perform_ssapre): Call get_stmt_operands
+ before processing the statement.
+ * tree-ssa-dom.c (thread_edge): Remove attribute EDGE_FALLTHRU from
+ edge.
+
+2003-09-21 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (simplify_rhs_and_lookup_avail_expr): Break out of
+ optimize_stmt. Follow the def-use chains back for certain expressions
+ to see if we can simplify the RHS of the current expression based
+ on earlier expressions.
+
+ * tree-ssa-dom.c (optimize_block): Rework code to propagate values
+ into PHI nodes to be more efficient.
+
+2003-09-20 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-flow.h (struct dataflow_d): Remove reaching fields, add 2 element
+ vector of trees.
+ * tree-flow-inline.h (immediate_uses): Rename to get_immediate_uses,
+ return a dataflow object.
+ (reaching_defs): Remove until needed.
+ (num_immediate_uses): New. Return number of immediate uses.
+ (immediate_use): New. Return a specified immediate use.
+ * tree-dfa.c (add_immediate_use): Use new fields.
+ (dump_immediate_uses_for): Use new interface.
+ (create_phi_node): Chain to start of list.
+ * tree-ssa-ccp.c (add_var_to_ssa_edges_worklist): Use new interface.
+ * tree-ssa.c (compute_global_livein): Loop interchange.
+
+2003-09-18 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (optimize_stmt): Allow optimizing the RHS of a
+ MODIFY_EXPR even if we can't record any equivalences created by
+ the MODIFY_EXPR. Move code to simplify ABS_EXPR, TRUNC_DIV_EXPR
+ and TRUNC_MOD_EXPR to an earlier position.
+
+2003-09-19 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-ssa-ccp.c (cfg_edges): Rename to cfg_blocks.
+ (cfg_blocks_num, cfg_blocks_head, cfg_blocks_tail): New. Queue markers.
+ (bb_in_list): New. Vector indicating if a BB is in the cfg_blocks list.
+ (tree_ssa_ccp): Use new routines.
+ (add_control_edge): Add to cfg_blocks list.
+ (initialize): Initialize new variables.
+ (finalize): Free allocations.
+ (cfg_blocks_empty): New. Is cfg_blocks queue list.
+ (cfg_blocks_add): New. Add a basic block to cfg_blocks list.
+ (cfg_blocks_pop): New. Get a a basic_block form the list.
+
+2003-09-18 Richard Henderson <rth@redhat.com>
+
+ * tree-cfg.c (struct rusv_data): Add may_throw, may_branch.
+ (remove_useless_stmts_and_vars_1): Set them.
+ (remove_useless_stmts_and_vars_goto): Likewise.
+ (remove_useless_stmts_and_vars_tf): Transform to compound_expr
+ if only fallthrough.
+ (remove_useless_stmts_and_vars_tc): Kill region if nothrow.
+ Detect catch regions that don't propagate exceptions.
+ (remove_useless_stmts_and_vars): Zero entire data struct.
+
+2003-09-18 Richard Henderson <rth@redhat.com>
+
+ * tree-eh.c (lower_try_finally_dup_block): New.
+ (honor_protect_cleanup_actions, lower_try_finally_copy): Use it.
+
+2003-09-18 Richard Henderson <rth@redhat.com>
+
+ * tree-cfg (remove_useless_stmts_and_vars_cond,
+ remove_useless_stmts_and_vars_tf,
+ remove_useless_stmts_and_vars_tc,
+ remove_useless_stmts_and_vars_bind,
+ remove_useless_stmts_and_vars_goto): Break out of ...
+ (remove_useless_stmts_and_vars_1): ... here. Rename to _1;
+ take and use struct rusv_data.
+ (remove_useless_stmts_and_vars): New. Loop until no change.
+ * tree-flow.h (remove_useless_stmts_and_vars): Update decl.
+ * tree-ssa.c (rewrite_out_of_ssa): Don't loop here.
+
+2003-09-18 Richard Henderson <rth@redhat.com>
+
+ * tree-pretty-print.c (dump_generic_node): Don't double indent asms.
+
+2003-09-18 Richard Henderson <rth@redhat.com>
+
+ * tree-eh.c: Include langhooks.h, remove errors.h.
+ (decide_copy_try_finally): Use estimate_num_insns to choose
+ between copy and switch implementations.
+
+ * c-common.c (c_estimate_num_insns): Take an expr, not a decl.
+ * tree-inline.c (limits_allow_inlining): Pass it the body of the decl.
+
+2003-09-18 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (lookup_avail_expr): New argument which indicates
+ if the expression should be entered into the hash table. All
+ callers updated.
+ (update_rhs_and_lookup_avail_expr): New function factored out
+ of optimize_stmt.
+
+ * tree.h (commutative_tree_code, associative_tree_code): Declare
+ * tree.c (commutative_tree_code, associative_tree_code): New
+ functions.
+ (iterative_hash_expr): Use commutative_tree_code.
+ * fold-const.c (operand_equal_p): Use commutative_tree_code
+ rather than inlining the communitivy check.
+ (fold, nondestructive_fold_binary_to_constant): Similarly.
+
+2003-09-18 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree-eh.o): Add dependency on errors.h
+ * tree-eh.c: Include errors.h
+
+2003-09-17 Richard Henderson <rth@redhat.com>
+
+ * tree-cfg.c (remove_useless_stmts_and_vars): Revert last change.
+ * tree-flow.h, tree-ssa.c: Likewise.
+
+2003-09-17 Richard Henderson <rth@redhat.com>
+
+ * tree-eh.c (decide_copy_try_finally): Remove forgotten debug code.
+
+2003-09-17 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (pick_ssa_name): New function.
+ (code_motion): Use it.
+
+2003-09-17 Richard Henderson <rth@redhat.com>
+
+ * tree-eh.c: New file.
+ * Makefile.in (OBJS-common): Add it.
+ (tree-eh.o): New.
+ * calls.c (emit_call_1): New argument for full call expr.
+ Check with lookup_stmt_eh_region to set REG_EH_REGION.
+ (expand_call): Likewise for tail-calls.
+ * except.c (struct eh_region): Add tree_label.
+ (gen_eh_region, gen_eh_region_cleanup, gen_eh_region_try,
+ gen_eh_region_catch, gen_eh_region_allowed,
+ gen_eh_region_must_not_throw, get_eh_region_number,
+ get_eh_region_may_contain_throw, get_eh_region_tree_label,
+ set_eh_region_tree_label, expand_resx_expr): New.
+ (expand_eh_region_start, expand_start_catch): Use them.
+ (expand_end_catch): Tidy.
+ (note_eh_region_may_contain_throw): Take region argument.
+ (note_current_region_may_contain_throw): New.
+ (get_exception_filter): Export.
+ (collect_eh_region_array): Export.
+ (remove_unreachable_regions): Check ERT_TRY based on reachability
+ of catches, not reachability of continue_label. Never remove
+ ERT_MUST_NOT_THROW regions.
+ (collect_rtl_labels_from_trees): New.
+ (convert_from_eh_region_ranges): Use it.
+ (connect_post_landing_pads): Handle dying cleanups.
+ (struct reachable_info): Add callback data.
+ (add_reachable_handler): Invoke the callback.
+ (foreach_reachable_handler): New.
+ (reachable_handlers): Use it.
+ (arh_to_landing_pad, arh_to_label): New.
+ (can_throw_internal_1): Split out from can_throw_internal.
+ (can_throw_external_1): Similarly.
+ * except.h: Update.
+ * expr.c (expand_expr): Handle RESX_EXPR, FILTER_EXPR.
+ * gimplify.c (gimplify_modify_expr): Use tree_could_trap_p.
+ * stmt.c (using_eh_for_cleanups_p): Export.
+ (expand_return): Allow any typed rhs.
+ * timevar.def (TV_TREE_EH): New.
+ * tree-cfg.c (eh_stack): Kill.
+ (build_tree_cfg): Don't set it. Kill code to handle EH.
+ (could_trap_p): Move to tree-eh.c as tree_could_trap_p.
+ (get_eh_region_type, make_try_expr_blocks, make_catch_expr_blocks,
+ make_eh_filter_expr_blocks, try_finallys): Kill.
+ (make_edges): Kill code to handle EH.
+ (make_ctrl_stmt_edges): Kill TRY_FINALLY_EXPR, CATCH_EXPR,
+ EH_FILTER_EXPR. Handle RESX_EXPR.
+ (make_call_expr_edges): Kill.
+ (make_exit_edges): Use make_eh_edges.
+ (label_to_block): New.
+ (make_goto_expr_edges): Use it.
+ (is_ctrl_stmt): Add RESX_EXPR.
+ (is_ctrl_altering_stmt): Restructure. Use tree_can_throw_internal.
+ (last_exec_block, compute_reachable_eh): Kill.
+ * tree-dfa.c (get_stmt_operands): Add RESX_EXPR.
+ (get_expr_operands): Add FILTER_EXPR.
+ * tree-dump.c (dump_files): Add tree-eh.
+ * tree-flow.h (struct stmt_ann_d): Kill reachable_exception_handlers.
+ (label_to_block, lower_eh_constructs, make_eh_edges,
+ tree_could_trap_p, tree_could_throw_p, tree_can_throw_internal,
+ tree_can_throw_external): Declare.
+ * tree-optimize.c (optimize_function_tree): Call lower_eh_constructs.
+ (tree_rest_of_compilation): Save tree for inlining.
+ * tree-pretty-print.c (dump_generic_node): Handle FILTER_EXPR,
+ RESX_EXPR.
+ * tree-simple.c (is_gimple_stmt): Add RESX_EXPR.
+ (is_gimple_val): Add FILTER_EXPR.
+ * tree-ssa-dce.c (stmt_useful_p): Restructure. Add lhs of
+ EXC_PTR_EXPR or FILTER_EXPR.
+ * tree.def (FILTER_EXPR, RESX_EXPR): New.
+ * tree.h (enum tree_dump_index): Add TDI_eh.
+
+2003-09-17 Richard Henderson <rth@redhat.com>
+
+ * tree.c (tsi_link_before): Remove unnecessary parens.
+ (tsi_link_chain_before, tsi_delink): Likewise.
+ (tsi_link_after): Accept the case if the iterator points
+ to a NULL node; treat it as an empty list.
+ (tsi_link_chain_after): Likewise. Update iterator properly
+ for TSI_CHAIN_END.
+
+2003-09-17 Richard Henderson <rth@redhat.com>
+
+ * tree-inline.c (debug_find_tree_1, debug_find_tree): New.
+
+2003-09-17 Richard Henderson <rth@redhat.com>
+
+ * tree-cfg.c (struct rusv_data): New.
+ (remove_useless_stmts_and_vars_1): Rename from
+ remove_useless_stmts_and_vars. Use rusv_data. Handle goto-next
+ via remembering the last goto seen, and zapping it when appropriate.
+ (remove_useless_stmts_and_vars): New. Loop until done.
+ * tree-flow.h (remove_useless_stmts_and_vars): Update decl.
+ * tree-optimize.c (optimize_function_tree): Don't cache fnbody.
+ Dump data after remove_useless_stmts_and_vars.
+ * tree-ssa.c (rewrite_out_of_ssa): Kill loop around
+ remove_useless_stmts_and_vars.
+ * tree-dump.c (dump_files): Add .useless.
+ * tree.h (enum tree_dump_index): Add TDI_useless.
+
+2003-09-17 Diego Novillo <dnovillo@redhat.com>
+
+ * pretty-print.c (pp_write_text_to_stream): Export.
+ * pretty-print.h (pp_write_text_to_stream): Declare.
+ * tree-pretty-print.c (print_generic_stmt): Flush to file.
+ (dump_generic_node): Call pp_write_text_to_stream.
+ (maybe_init_pretty_print): Take file argument; associate the
+ stream with the buffer.
+
+2003-09-17 Jeff Law <law@redhat.com>
+
+ * tree-ssa-ccp.c (ccp_fold): If the return value has the wrong
+ type, try to convert it to the proper type rather than failing.
+
+ * tree-ssa-dom.c (optimize_stmt): Note that the statement is
+ modified, even if we just change the virtual operands. If
+ the statement was modified by const/copy propagation, then
+ set may_have_exposed_new_symbols.
+
+2003-09-17 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (find_vars_r): Do not consider 'void *' pointers as
+ dereferenced when scanning function call arguments.
+ * tree-flow-inline.h (may_propagate_copy): Block propagation of
+ pointers when they have different memory tags.
+ * tree-ssa-copyprop.c (propagate_copy): When copy propagating
+ pointers, abort if the two pointers don't have identical memory
+ tags.
+
+2003-09-16 Jeff Law <law@redhat.com>
+
+ * tree-ssa-ccp.c (visit_stmt): Do not set DONT_SIMULATE_AGAIN
+ just because a statement as virtual definitions.
+ (likely_value): A CALL_EXPR is assumed to return a VARYING
+ result, regardless of its operands.
+
+2003-09-15 Jason Merrill <jason@redhat.com>
+
+ * tree-simple.c (is_gimple_val): Allow addresses of all decls.
+ (is_gimple_const): Allow addresses of all non-weak statics.
+ * tree-ssa-ccp.c (fold_stmt): Return bool.
+ * tree-flow.h: Adjust prototype.
+ * tree-ssa-dom.c (optimize_stmt): If folding changed stuff, we
+ need to recalculate the vops.
+
+2003-09-13 Diego Novillo <dnovillo@redhat.com>
+
+ Fix PR optimization/12268
+ * tree-dfa.c (add_referenced_var): Call-clobbered pointers may
+ point to global memory.
+
+2003-09-13 Jason Merrill <jason@redhat.com>
+
+ * c-common.c (c_apply_type_quals_to_decl): Unset TREE_READONLY for
+ types with constructors.
+ Remove superfluous references to TREE_TYPE (decl).
+
+2003-09-13 Diego Novillo <dnovillo@redhat.com>
+
+ * opts.c (decode_options): Enable must-alias optimization by default.
+ * tree-dfa.c (get_expr_operands): Always call add_stmt_operand when
+ dealing with ADDR_EXPR nodes.
+ (add_stmt_operand): If the variable has an alias set
+ of size zero, abort.
+ Call get_base_symbol() to retrieve the variable from an ADDR_EXPR
+ node.
+ (compute_alias_sets): Deep copy the aliases array when triggering
+ the alias grouping heuristic.
+ Don't group aliases if -ftree-must-alias is given.
+ * tree-must-alias.c (tree_compute_must_alias): Call
+ dump_referenced_vars when doing detailed dumps.
+ Rename promoted_vars to vars_to_rename. Update all users.
+ (find_addressable_vars): Always mark statements modified.
+ (promote_var): Also mark aliases of promoted variable to be
+ renamed.
+ Call find_variable_in and remove_element_from to update varrays for
+ call-clobbered variables and alias sets.
+ (find_variable_in): New local function.
+ (remove_element_from): New local function.
+ * varray.c (varray_copy): New function.
+ * varray.h (varray_copy): Declare.
+
+2003-09-13 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-flow-inline.h (is_optimizable_addr_expr): Remove. Update
+ all users.
+ * tree-ssa-dom.c (optimize_stmt): Do not propagate SSA names from
+ redundant expressions across abnormal edges.
+
+2003-09-13 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-cfg.c (remove_unreachable_blocks): Clean up.
+ (debug_tree_bb_n): New.
+ (is_ctrl_structure): Remove LOOP_EXPR.
+ * tree-flow.h (debug_tree_bb_n): Declare.
+
+2003-09-12 Andrew Macleod <amacleod@redhat.com>
+
+ * tree-ssa-live.c (calculate_live_on_entry): Use default_def to add
+ addition checks to live on entry calculations.
+ * tree-ssa.c (print_exprs_edge): New debug output function.
+ (coalesce_abnormal_edges): Add basic block information to output.
+ (coalesce_ssa_name): Use default_def instead of trying to compute live
+ on entry variables.
+
+2003-09-12 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-optimize.c (tree_rest_of_compilation): Set TREE_ASM_WRITTEN
+ for functions that have errors.
+
+2003-09-12 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa-pre.c (graph_dump_file, graph_dump_flags): Remove
+ unused variables.
+
+2003-09-11 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (reset_down_safe): Make test less conservative.
+ (cba_search_start_from): Start from abnormal edge arguments, too.
+ (cba_search_continue_from_to): Ditto here.
+
+2003-09-11 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c: s/#if ENABLE_CHECKING/#ifdef ENABLE_CHECKING/g.
+ Add more comments to DFS searching functions.
+ (cba_search_reach_from_to): Remove empty function.
+ (code_motion): Remove #if 0'd code.
+ (pre_expression): Ditto.
+ * tree.h (tree_dump_index): Remove TDI_predot.
+ * tree-dump.c (dump_files): Ditto.
+
+2003-09-11 Jason Merrill <jason@redhat.com>
+
+ Make EDGE_FALLTHRU meaningful for tree-cfg.
+ * tree-cfg.c (make_edges): Set EDGE_FALLTHRU on fallthrough edge.
+ (make_exit_edges): Likewise.
+ (make_ctrl_stmt_edges): Don't set EDGE_FALLTHRU on edges into a
+ control structure.
+ (handle_switch_fallthru): Clear EDGE_FALLTHRU after inserting a goto.
+ (find_insert_location): Only insert after a CALL_EXPR or MODIFY_EXPR.
+ (bsi_insert_on_edge_immediate): Count outgoing abnormal edges.
+ Insert before all control stmts.
+ (bsi_link_after): Handle a block with nops after the last stmt.
+
+ Rename some things to clarify difference between "control structures"
+ (i.e. COND_EXPR) and "control statements" (also GOTO_EXPR).
+ * basic-block.h (BB_CONTROL_STRUCTURE): Rename from BB_CONTROL_EXPR.
+ * tree-cfg.c (REMOVE_NON_CONTROL_STRUCTS): Rename from
+ REMOVE_NON_CONTROL_STMTS.
+ (REMOVE_CONTROL_STRUCTS): Rename from REMOVE_CONTROL_STMTS.
+ (make_ctrl_stmt_edges): Move GOTO_EXPR/RETURN_EXPR handling here...
+ (make_exit_edges): ...from here.
+ (is_ctrl_altering_stmt): Don't accept GOTO_EXPR/RETURN_EXPR.
+ (is_ctrl_structure): Renamed from old is_ctrl_stmt.
+ (is_ctrl_stmt): New fn.
+ (bsi_move_to_bb_end): Use it.
+ (stmt_starts_bb_p): Use is_ctrl_stmt and is_ctrl_altering_stmt.
+ * tree-flow.h: Add prototype.
+ * tree-ssa-ccp.c, tree-ssa-dom.c: Update for name changes.
+
+2003-09-10 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (ephi_has_bottom): Remove dead function.
+ (ephi_has_unsafe_arg): New function.
+ (compute_down_safety): Use it.
+ (reset_down_safe): Continue search on abnormal edges, too.
+
+2003-09-10 Jason Merrill <jason@redhat.com>
+
+ * gimplify.c (gimplify_asm_expr): Add post_p parm.
+ (get_initialized_tmp_var): Add post_p parm.
+ (internal_get_tmp_var): Likewise.
+ (gimplify_expr, get_formal_tmp_var): Pass it.
+ * c-simplify.c (gimplify_decl_stmt): Pass it.
+ * tree-simple.h: Adjust prototype.
+
+ * tree-cfg.c (make_call_expr_edges): Break out from...
+ (make_exit_edges): ...here. Check TREE_NOTHROW.
+ (is_ctrl_altering_stmt): Check TREE_NOTHROW.
+
+2003-09-10 Paul Brook <paul@nowt.org>
+
+ * gimplify.c (gimplify_compound_lval): Treat REALPART_EXPR and
+ IMAGPART_EXPR the same as COMPONENT_REF.
+ * tree-simple.c (is_gimple_addr_expr_arg): Ditto.
+ (is_gimple_lvalue): Remove REALPART_EXPR and IMAGPART_EXPR.
+
+2003-09-10 Diego Novillo <dnovillo@redhat.com>
+
+ * c-pretty-print.c (decl_name_str): New local function.
+ (pp_c_direct_declarator): Call it.
+ (pp_c_primary_expression): Call it.
+ (pp_c_id_expression): Call it.
+ (pp_c_statement): Call it.
+
+2003-09-10 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-pretty-print.c (dump_generic_node): Change string used to
+ display _DECL nodes with no DECL_NAME.
+
+2003-09-10 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (add_referenced_var): Handle cases when argument
+ walk_state is NULL.
+ (add_referenced_tmp_var): New function.
+ * tree-flow.h (add_referenced_tmp_var): Declare it.
+ * tree-ssa-pre.c (pre_expression): Call it.
+ * tree-ssa-live.c (create_ssa_var_map): Add checking for variables
+ being in real and virtual operands.
+
+2003-09-01 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+ Jeff Law <law@redhat.com>
+
+ * tree-flow.h (remove_unreachable_blocks): Declare.
+ * tree-cfg.c (remove_unreachable_blocks): Export. Return true
+ if blocks were removed.
+ * tree-ssa-dom.c (optimize_block, optimize_stmt): Record whether
+ the cfg has changed. Schedule jump threading. If a block
+ has more than one pred, then do not record equivalences created
+ by a controlling COND_EXPR.
+ (edges_to_redirect, redirection_targets): New variables.
+ (thread_edge): Split out of optimize_block.
+ (tree_ssa_dominator_optimize); Remove unreachable blocks and
+ recompute dominator tree when the cfg changes.
+
+2003-09-07 Steven Bosscher <steven@gcc.gnu.org>
+
+ * c-tree.h: Don't declare c_genericize, it's already
+ declared in c-common.h.
+
+2003-09-07 Steven Bosscher <steven@gcc.gnu.org>
+
+ Fix PR optimization/12198
+ * tree-cfg.c (value_matches_some_label): Handle integer
+ case ranges.
+
+2003-09-06 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-iterator.h (tsi_iterator_update): Added TSI_CHAIN_START,
+ TSI_CHAIN_END, TSI_CONTINUE_LINKING and comments.
+ (tsi_link_chain_before, tsi_link_chain_after): Declare.
+ * tree.c (tsi_link_chain_before, tsi_link_chain_after): New.
+ (tsi_link_before, tsi_link_after): Handle new TSI_...
+ positions.
+
+2003-09-06 Diego Novillo <dnovillo@redhat.com>
+
+ * varray.c (element): Add entry for 'tree *'.
+ * varray.h (enum varray_data_enum): Add VARRAY_DATA_TREE_PTR.
+ (union varray_data_tag): Add entry for 'tree *'.
+ (VARRAY_TREE_PTR_INIT): Define.
+ (VARRAY_TREE_PTR): Define.
+ (VARRAY_PUSH_TREE_PTR): Define.
+ (VARRAY_TOP_TREE_PTR): Define.
+ * tree-cfg.c: Replace uses of VARRAY_GENERIC_PTR with
+ VARRAY_TREE_PTR when accessing operand arrays.
+ * tree-ssa-ccp.c: Likewise.
+ * tree-ssa-copyprop.c: Likewise.
+ * tree-ssa-dce.c: Likewise.
+ * tree-ssa-dom.c: Likewise.
+ * tree-ssa-live.c: Likewise.
+ * tree-ssa-pre.c: Likewise.
+ * tree-dfa.c: Likewise.
+ * tree-ssa.c: Likewise.
+ * tree-flow.h (struct operands_d): Remove 'skip' GC markers from
+ all fields.
+ (struct dataflow_d): Likewise.
+
+2003-09-05 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (find_referenced_vars): Re-enable .GLOBAL_VAR
+ optimization.
+
+2003-09-05 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree.h (tree_eref_common): Make stmt a tree, not a tree *.
+ * tree-ssa-pre.c: Transform all tree *'s to tree.
+
+2003-09-05 Paul Brook <paul@nowt.org>
+
+ * tree.h (enum tree_index): Delete TI_SIGNED_SIZE_TYPE here.
+ (signed_size_type_node): No longer a member of global_trees.
+ * c-common.h (enum c_tree_index): New member CTI_SIGNED_SIZE_TYPE.
+ (signed_size_type_node): Moved, now a member of c_global_trees.
+
+2003-09-05 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (find_referenced_vars): Temporarily disable
+ .GLOBAL_VAR optimization.
+
+2003-09-04 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-common.c: Add overview.
+ * tree-alias-ander.c: Add overview and more specific comments on what
+ each function does.
+
+2003-09-04 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-optimize.c (tree_rest_of_compilation): Return if errorcount
+ or sorrycount are non-zero.
+
+2003-09-04 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (cleanup_tree_cfg): Traverse basic blocks
+ with FOR_EACH_BB.
+ (remove_useless_stmts_and_vars): Likewise.
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize): Likewise.
+ * tree-ssa.c (rewrite_into_ssa): Likewise.
+ * tree-dfa.c (remove_all_phi_nodes_for): Make sure that the new
+ list of PHI nodes is NULL-terminated.
+ Add sanity checks to make sure all the PHI nodes for variables to
+ rename are gone.
+
+2003-09-04 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (struct walk_state): Add field 'num_calls'.
+ (add_call_clobber_ops): New local function.
+ (add_call_read_ops): New local function.
+ (get_expr_operands): Call them.
+ (add_stmt_operand): Call-clobbered variables are always added to
+ virtual operands.
+ (find_referenced_vars): If the number of call-clobbered variables
+ and number of call sites is larger than a certain threshold, group
+ all call-clobbered variables under .GLOBAL_VAR.
+ (find_vars_r): Count the number of call sites.
+ Don't add .GLOBAL_VAR to the list of referenced variables.
+ (add_referenced_var): If the addressable variable is an array,
+ register alias set of the type of the elements, not the type of the
+ array.
+ * tree-ssa-dom.c (mark_new_vars_to_rename): Rename from
+ find_new_vars_to_rename. Update all users.
+ Before scanning the statement for new operands, mark the existing
+ virtual operands to be renamed again.
+ (optimize_stmt): Also check for newly exposed variables when doing
+ redundancy elimination.
+ * tree-ssa.c (rewrite_into_ssa): Don't abort when rename_count is
+ greater than 2. Simply stop trying at 3.
+ (prepare_operand_for_rename): New function.
+ (mark_def_sites): Call it.
+ (rewrite_stmt): Don't check if the operand is an SSA_NAME before
+ calling rewrite_operand.
+ (rewrite_operand): Don't abort if the operand was already an
+ SSA_NAME. Ignore it.
+
+2003-09-03 Richard Henderson <rth@redhat.com>
+
+ * tree-optimize.c (set_save_expr_context, clear_decl_rtl,
+ tree_rest_of_compilation): Merge from mainline new file.
+ * Makefile.in (tree-optimize.o): Update.
+ * c-semantics.c (expand_stmt_toplev): New.
+ * c-common.h (expand_stmt_toplev): Declare.
+ * c-lang.c, objc/objc-lang.c (LANG_HOOKS_RTL_EXPAND_STMT): Use it.
+
+2003-09-03 Richard Henderson <rth@redhat.com>
+
+ * gimplify.c (gimplify_switch_expr): Leave the outermost cast
+ as part of the switch condition.
+
+2003-09-02 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree.o): Add dependency on $(BASIC_BLOCK_H) and
+ $(TREE_FLOW_H)
+ * tree.c: Include basic-block.h and tree-flow.h
+ (tsi_link_after): Adjust basic block tree pointers when inserting a
+ new COMPOUND_EXPR.
+
+2003-09-02 Richard Henderson <rth@redhat.com>
+
+ * c-decl.c (finish_function): Fix misapplied patch. Don't
+ free_after_parsing or free_after_compilation. For real this time.
+
+2003-09-01 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (finalize_1): Remove unnecessary call to
+ insert_euse_in_preorder_dt_order.
+ (code_motion): Ditto.
+ (pre_expression): Ditto.
+
+2003-09-01 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+ Jeff Law <law@redhat.com>
+
+ * basic-block.h (BB_LOOP_CONTROL_EXPR): Remove.
+ * c-simplify.c (gimplify_c_loop): Create loops in a better shape.
+ * cfgloop.h (create_loop_notes): Declare.
+ * cfgloopmanip.c (create_loop_notes): New.
+ * explow.c (probe_stack_range): Don't produce loop notes when we
+ recreate them.
+ * expr.c (emit_block_move_via_loop): Ditto.
+ * gimplify.c (build_and_jump): Export.
+ (gimplify_loop_expr): Don't produce LOOP_EXPRs.
+ * toplev.c (rest_of_compilation): Recreate loop notes if needed.
+ * tree-cfg.c (make_loop_expr_edges, make_loop_expr_blocks): Removed.
+ (find_contained_blocks, make_ctrl_stmt_edges,
+ remove_useless_stmts_and_vars, stmt_ends_bb_p, bsi_insert_before,
+ find_insert_location, bsi_insert_on_edge_immediate,
+ merge_tree_blocks): Remove handling of LOOP_EXPRs.
+ (remove_stmt): Remove handling of BB_LOOP_CONTROL_EXPR.
+ (find_taken_edge): Remove comment on LOOP_EXPRs.
+ (dump_tree_bb): Don't dump loop-related information.
+ (is_loop_stmt, is_latch_block_for): Removed.
+ (find_insert_location): Handle TRY_CATCH and TRY_FINALLY.
+ * tree-flow.h (is_loop_stmt, loop_body, set_loop_body,
+ is_latch_block_for): Removed.
+ * tree-dfa.c (get_stmt_operands): Don't handle LOOP_EXPRs.
+ * tree-simple.c (is_gimple_stmt): Remove handling of LOOP_EXPRs.
+ * tree-simple.h: Remove LOOP_EXPRs from gimple grammar comment.
+ (build_and_jump): Declare.
+ * tree-ssa.c (remove_annotations_r): Don't handle LOOP_EXPRs.
+
+2003-08-29 Daniel Berlin <dberlin@dberlin.org>
+
+ * opts.c (decode_options): Turn on SSAPRE by default.
+
+2003-08-29 Jason Merrill <jason@redhat.com>
+
+ * builtins.c (simplify_builtin): Make sure that the replacement
+ has the same type as the original expression.
+ (simplify_builtin_strpbrk): Fix type of COMPOUND_EXPR.
+ (simplify_builtin_strncpy, simplify_builtin_memcmp): Likewise.
+ (simplify_builtin_strncmp, simplify_builtin_strncat): Likewise.
+ (simplify_builtin_strspn, simplify_builtin_strcspn): Likewise.
+ (simplify_builtin_fputs, simplify_builtin_sprintf): Likewise.
+
+2003-08-28 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * builtins.c (expand_builtin): Expand BUILT_IN_STACK_SAVE and
+ BUILT_IN_STACK_RESTORE.
+ * builtins.def (BUILT_IN_STACK_SAVE, BUILT_IN_STACK_RESTORE): New.
+ * gimplify.c (build_stack_save_restore): New functions.
+ (struct gimplify_ctx): New field save_stack.
+ (gimplify_bind_expr, gimplify_call_expr): Arrange save of stack on
+ BIND_EXPR entry and restore on exits.
+ * stmt.c (expand_stack_alloc): Saving of stack removed.
+ (expand_stack_save, expand_stack_restore): New.
+ * tree.h (expand_stack_save, expand_stack_restore): Declare.
+
+2003-08-28 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (add_vdef): Check for duplicate voperands first.
+ Handle SSA_NAME in voperands.
+ (add_vuse): Likewise.
+
+2003-08-27 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-flow.h (var_ann_d): Convert is_in_va_arg_expr into a
+ bitfield.
+
+2003-08-27 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c: Update comments to reflect reality.
+ (insert_one_operand): Remove #if'0d code.
+
+2003-08-27 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * gcov.c (typedef struct arc_info): New field cs_count.
+ (accumulate_line_counts): Find cycles correctly.
+
+2003-08-27 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (compute_du_info): Move #if ENABLE_CHECKING up one
+ line.
+
+2003-08-27 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree.h (struct ephi_arg_d): New structure.
+ (struct eref_common): Remove non-used members, move some members
+ elsewhere.
+ (struct ephi_node): Ditto.
+
+ * tree-optimize.c (optimize_function_tree): Move PRE before DCE.
+
+ * tree.c (tree_size): use sizeof (struct ephi_arg_d) for ephi's.
+
+ * tree-pretty-print.c (dump_generic_node): Re-teach to pretty
+ print euses/ephis/etc given new structures, members, and
+ relationships.
+
+ * tree-ssa-pre.c (fixup_domchildren): Removed.
+ (a_dom_b): Ditto.
+ (calculate_preorder): Ditto.
+ (defs_match_p): Ditto.
+ (defs_y_dom_x): Ditto.
+ (compute_can_be_avail): Ditto.
+ (reset_can_be_avail): Ditto.
+ (reset_later): Ditto.
+ (compute_later): Ditto.
+ (repair_*): Ditto.
+ (set_replacement): Ditto.
+ (remove_ephi): Ditto.
+ (set_expruse_def): Ditto.
+ (occ_compare): Ditto.
+ (defs_hash_expr): Ditto.
+ (compute_dt_preorder): Ditto
+ (search_dt_preorder): Ditto.
+ (ephi_operand_for_pred): Ditto.
+ (injured_ephi_operand): Ditto.
+ (compute_stops): New function.
+ (occ_identical_to): Ditto.
+ (require_phi): Ditto.
+ (do_ephi_df_search_1): Ditto.
+ (do_ephi_df_search): Ditto.
+ (any_operand_injured): Ditto.
+ (compute_du_info): Ditto.
+ (add_ephi_use): Ditto.
+ (insert_one_operand): Ditto.
+ (add_ephi_pred): Ditto.
+ (created_phi_preds): New bitmap.
+ (dfn) Removed static variable.
+ (idom_of_ephi): Ditto.
+ (avdefs): Move into expr_info).
+ (struct ephi_use_entry): New structure for EPHI uses.
+ (struct ephi_df_search): New structure for depth first searchs.
+ (cant_be_avail_search): Implementation of structure for
+ cant_be_avail search.
+ (stops_search): Ditto for stops.
+ (replacing_search): Ditto for replacing_search.
+ (do_proper_save): Arguments changed, callers updated.
+ (create_ephi_node): Use sizeof (struct ephi_arg_d).
+ (ephi_has_bottom): Rewrite for updated ephi-pred handling.
+ (ephi_will_be_avail): Rewrite in terms of CANT_BE_AVAIL and STOPS.
+ (expr_phi_insertion): Remove dead code.
+ Update for new flags.
+ (insert_occ_in_preorder_dt_order_1): Only insert one ephi-pred per
+ block.
+ Fix exit occurence handling.
+ (rename_1): Remove occs stuff.
+ Update for new ephi-pred handling.
+ (reset_down_safe): Update for new ephi-pred handling.
+ (compute_down_safe): Ditto.
+ (can_insert): Ditto.
+ (insert_one_operand): Split out from finalize_1.
+ (finalize_1): Update for new ephi-pred handling.
+ Only insert non-pointless, will-be-avail phis, rather than *all*
+ ephis.
+ (get_temp): New function. Hand us the right temporary for a given
+ EPHI/EUSE.
+ (code_motion): Use EREF_TEMP again, now that we can do it
+ properly.
+
+2003-08-26 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * builtins.c (expand_builtin): Handle STACK_ALLOC.
+ * builtins.def (BUILT_IN_STACK_ALLOC): New.
+ * c-simplify.c (gimplify_decl_stmt, c_gimplify_stmt,
+ gimplify_compound_literal_expr): Arrange explicit stack allocation.
+ * expr.c (expand_expr): Handle deferred variables.
+ * stmt.c (expand_stack_alloc): New.
+ * tree-simple.c (is_gimple_val): Prevent ADDR_EXPRs of vla's from
+ being reduced.
+ * tree.h (expand_stack_alloc): Declare.
+
+2003-08-26 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-ssa.c (build_dominator_tree): Use FOR_EACH_BB.
+
+2003-08-26 Jason Merrill <jason@redhat.com>
+
+ * tree-simple.c (is_gimple_val): Also disallow memory vars.
+
+2003-08-25 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * integrate.c (copy_decl_for_inlining): Reset DECL_TOO_LATE.
+
+2003-08-25 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-ssa-dom.c (optimize_block): Handle empty source block.
+
+ * tree-ssa-dom.c (optimize_block): Handle case when dominance
+ tree children have also other sucessors. Add dump to jump
+ threading.
+
+2003-08-25 Jason Merrill <jason@redhat.com>
+
+ * c-simplify.c (mark_labels_r): New fn.
+ (gimplify_decl_stmt): Use it to mark labels in static initializers.
+ * tree-simple.c (is_gimple_initializer): Remove.
+ (is_gimple_reg_type): New fn.
+ (is_gimple_reg): Use it. Handle SSA_NAMEs properly.
+ * tree-simple.h: Adjust.
+ * gimplify.c (gimplify_expr) <CONSTRUCTOR>: Do nothing here.
+
+ * gimplify.c (create_tmp_var): Set DECL_IGNORED_P.
+
+ * tree-inline.c (initialize_inlined_parameters): Improve error
+ recovery.
+
+ * gimplify.c (gimplify_boolean_expr): Just replace with a COND_EXPR.
+
+2003-08-25 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (get_expr_operands): Don't create shared operands when
+ folding *&VAR expressions.
+
+2003-08-24 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-flow.h (struct var_ann_d): Add field default_def.
+ (widen_bitfield): Declare.
+ (set_default_def): Declare.
+ (default_def): Declare.
+ * tree-flow-inline.h (set_default_def): New inline function.
+ (default_def): New inline function.
+ * tree-dfa.c (dump_variable): Display default_def, if set.
+ * tree-simple.c (is_gimple_reg): Check for DECL_P before checking
+ for DECL_EXTERNAL.
+ * tree-ssa-dom.c (add_expr_propagated_p): Remove. Update all
+ users.
+ (find_new_vars_to_rename): New local function.
+ (tree_ssa_dominator_optimize): Add new argument vars_to_rename.
+ Change return type to void. Update all users.
+ (optimize_block): Add new argument vars_to_rename. Update all
+ users.
+ If the call to optimize_stmt returns true, add the statement to the
+ list of statements to re-scan for operands.
+ After optimizing the block and its dominator children, call
+ find_new_vars_to_rename for every statement that may have had new
+ symbols exposed.
+ (optimize_stmt): Change return type to bool. Return true if the
+ statement may have had new symbols exposed by optimization.
+ Add a sanity check for the value returned by lookup_avail_expr.
+ Create equivalences for more memory stores, not just the ones done
+ via INDIRECT_REF expressions.
+ Call widen_bitfield when optimizing stores to bitfields.
+ (lookup_avail_expr): Reformat comment.
+ * tree-ssa.c (rewrite_into_ssa): Remove local variable
+ addr_expr_propagated_p.
+ Clear out vars_to_rename before running dominator optimizations.
+ (check_for_new_variables): Remove.
+ (rewrite_stmt): Always register new definitions and virtual
+ definitions.
+ (register_new_def): Update comment.
+ (get_reaching_def): Update the default_def field for the variable
+ if it didn't have a reaching definition.
+ * tree-ssa-ccp.c (widen_bitfield): Declare it extern.
+
+2003-08-23 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-cfg.c (bsi_next_in_bb): Work correctly when the block ends
+ with start of BIND_EXPR.
+
+2003-08-23 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-ander.c (andersen_op_assign): Fix to join the operands,
+ the assign to the lhs.
+
+2003-08-23 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-common.c (get_alias_var): Remove REFERENCE_EXPR.
+ (find_func_aliases): Fix some not quite right predicates, add ARRAY_REF
+ handling.
+
+2003-08-22 Jeff Law <law@redhat.com>
+
+ * tree-dfa.c (compute_alias_sets): A memory tag used for stores can
+ not conflict with objects marked TREE_READONLY.
+
+ * tree-ssa-ccp.c (fold_stmt): Optimize reads from constant strings.
+
+2003-08-22 Jason Merrill <jason@redhat.com>
+
+ * tree-simple.c: Total overhaul to only check forms and remove
+ unnecessary predicates.
+ (is_gimple_const): Accept function addresses here.
+ Don't accept LABEL_DECL or RESULT_DECL.
+ (is_gimple_val): Accept EXC_PTR_EXPR here.
+ (is_gimple_lvalue): Rename from is_gimple_modify_expr_lhs.
+ Accept BIT_FIELD_REF, REALPART_EXPR and IMAGPART_EXPR here.
+ (is_gimple_addr_expr_arg): Replace with former is_gimple_varname.
+ (is_gimple_constructor_elt): Just check for CONSTRUCTOR.
+ (is_gimple_initializer): Just hand off to is_gimple_rhs.
+ (is_gimple_rhs): Recognize most expressions here.
+ (is_gimple_variable): New fn.
+ (is_gimple_id): Use it. Now static.
+ (is_gimple_reg): New fn.
+ (is_gimple_cast): Replace with former is_gimple_cast_op.
+ (is_gimple_constructor, is_gimple_expr): Remove.
+ (is_gimple_modify_expr, is_gimple_relop): Remove.
+ (is_gimple_binary_expr, is_gimple_unary_expr): Remove.
+ (is_gimple_call_expr, is_gimple_arglist): Remove.
+ (is_gimple_compound_lval, is_gimple_arrayref): Remove.
+ (is_gimple_compref, is_gimple_exprseq): Remove.
+ (is_gimplifiable_builtin): Remove.
+ * tree-simple.h: Adjust.
+ * gimplify.c (gimplify_conversion): Break out from gimplify_expr.
+ (gimplify_expr): Use is_gimple_reg predicate to force a temp.
+ <COMPONENT_REF>: Use gimplify_compound_lval.
+ <REALPART_EXPR, IMAGPART_EXPR>: Likewise.
+ <INDIRECT_REF>: Use is_gimple_reg predicate.
+ <MIN_EXPR, MAX_EXPR>: Use new gimplify_minimax_expr.
+ <TREE_LIST>: Reject.
+ (gimplify_tree_list, gimplify_component_ref): Remove.
+ (gimplify_compound_lval): Include REALPART_EXPR and IMAGPART_EXPR.
+ (gimplify_component_ref): Remove.
+ (gimplify_call_expr): Handle non-gimplifiable builtins and walking
+ the argument list here.
+ (gimplify_tree_list): Remove.
+ (gimplify_addr_expr): Use fb_either.
+ * tree-simple.h: Adjust.
+ * tree-alias-common.c (find_func_aliases): Update use of predicates.
+
+2003-08-21 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * tree-ssa.c (tree_ssa_useless_type_conversion): Check also the
+ precision of the type to make sure they are really useless type
+ conversions.
+
+2003-08-21 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dump.c (dequeue_and_dump): Handle 'r' and 's' code classes.
+
+2003-08-21 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * c-pretty-print.c (print_c_tree): Create new pp object.
+
+2003-08-21 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize): Don't free hash tables
+ before statistics are made from them.
+ * tree-ssa.c (rewrite_into_ssa): Ditto.
+
+2003-08-21 Jason Merrill <jason@redhat.com>
+
+ * tree-inline.c (copy_body_r): Don't convert when stripping &*.
+ Fix thinko in stripping *&.
+
+2003-08-21 Diego Novillo <dnovillo@redhat.com>
+ Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-cfg.c (stmt_starts_bb_p): Nonlocal and computed GOTO targets
+ always start a new block.
+
+2003-08-20 Jason Merrill <jason@redhat.com>
+
+ * tree-pretty-print.c (dump_generic_node): Just print "<retval>"
+ for the RESULT_DECL.
+
+ * c-simplify.c (make_type_writable, mostly_copy_tree_r): Remove.
+ (deep_copy_list, deep_copy_node): Remove.
+
+ * expr.c (expand_expr): Don't check for 'r' or 's' if we're
+ checking IS_EXPR_CODE_CLASS.
+ * tree-dfa.c (may_access_global_mem_p): Likewise.
+ * tree-browser.c (browse_tree): Likewise.
+ * tree-ssa-pre.c (defs_hash_expr): Likewise.
+ * gimplify.c (gimplify_expr): Likewise.
+ (internal_get_tmp_var): Only copy TREE_LOCUS from an expr.
+ (mostly_copy_tree_r): Ignore decls here.
+
+2003-08-20 Diego Novillo <dnovillo@redhat.com>
+
+ * c-pretty-print.c: Discard. Replace with same file from
+ mainline. Update all users.
+ (print_c_tree): New function.
+ * c-pretty-print.h (print_c_tree): Declare.
+ * tree-pretty-print.c: Update to use new pp_* primitives.
+ * c-simplify.c: Include c-pretty-print.h.
+ * Makefile.in (c-simplify.o): Add dependency on $(C_PRETTY_PRINT_H).
+
+2003-08-20 Roger Sayle <roger@eyesopen.com>
+
+ * c-common.h (enum c_tree_index): Delete CTI_SIGNED_SIZE_TYPE.
+ (signed_size_type_node): No longer a member of c_global_trees.
+ * tree.h (enum tree_index): New member TI_SIGNED_SIZE_TYPE here.
+ (signed_size_type_node): Moved, now a member of global_trees.
+
+2003-08-20 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-ssa-dom.c (optimize_block): Thread jump into empty
+ block correctly.
+
+ * tree-cfg.c (linearize_cond_expr): Don't merge blocks if the
+ later has other predecessors.
+
+2003-08-19 Jason Merrill <jason@redhat.com>
+
+ * c-typeck.c (build_array_ref): Also build ARRAY_REFs from
+ INDIRECT_REFs of ARRAY_TYPE.
+
+ * tree-ssa.c (tree_ssa_useless_type_conversion): Also strip
+ conversions between pointer and reference types.
+
+ * tree-dfa.c (get_stmt_operands): Just mark non-GIMPLE statements
+ as unmodified.
+ (find_referenced_vars): So we don't need to mark them here.
+
+ * tree-inline.c (inline_data): Add retvar field.
+ (declare_return_variable): Set it.
+ (remap_decls): Use it.
+ (expand_call_inline): Tweak.
+
+2003-08-19 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfg.c (dump_edge_info): Add name for EDGE_LOOP_EXIT flag.
+
+2003-08-19 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-flow.h (struct var_ann_d): New field scope.
+ (struct stmt_ann_d): New field scope.
+ (propagate_copy): Declaration changed.
+ (fixup_var_scope): Declare.
+ * tree-cfg.c (make_blocks, make_cond_expr_blocks,
+ make_catch_expr_blocks, make_eh_filter_expr_blocks,
+ make_try_expr_blocks, make_loop_expr_blocks, make_switch_expr_blocks,
+ make_bind_expr_blocks, build_tree_cfg): Assign variables and statements
+ to scopes.
+ (assign_vars_to_scope): New.
+ * tree-ssa-copyprop.c (move_var_to_scope): New.
+ (copyprop_stmt): Pass scope of statement to propagate_copy.
+ (propagate_copy): Assign variable to the right bind_expr.
+ (fixup_var_scope): New.
+ * tree-ssa-dom.c (optimize_stmt): Pass scope of statement to
+ propagate_copy.
+
+2003-08-19 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-cfg (bsi_move_after): New function.
+ (bsi_move_before): New function.
+ (bsi_move_to_bb_end): New function.
+ * tree-flow.h: Prototype new functions.
+
+2003-08-18 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-ander.c: Remove doxygen markers.
+ (eq_to_var): remove.
+ (simple_cmp): Add.
+ (throwaway_global): Add.
+ (andersen_same_points_to_set): Handle ignoring global var aliasing the
+ right way here.
+ (andersen_may_alias): Use list_member to avoid stupid hack.
+ * tree-alias-common.c: Remove hacks for disabling global var aliasing.
+
+2003-08-17 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree.c (resize_phi_node): Initialize new entries.
+
+2003-08-17 Jeff Law <law@redhat.com>
+
+ * tree-pretty-print.c (last_bb): Actually record the basic block,
+ not just its index.
+ (maybe_init_pretty_print): Corresponding changes.
+ (dump_generic_node, dump_vops): Test the actual block pointers, not
+ their indices.
+
+ * tree-ssa-dom.c (optimize_block): Use equivalences from the
+ dominator tree walk to thread through conditional jumps at leafs in
+ the dominator tree.
+
+ * tree-cfg.c (blocks_unreachable_p, remove_blocks): Use a bitmap
+ rather than a varray.
+ (REMOVE_ALL_STMTS, REMOVE_NO_STMTS): New defines for remove_bb.
+ (REMOVE_NON_CONTROL_STMTS, REMOVE_CONTROL_STMTS): Likewise.
+ (remove_unreachable_block): Use find_contained_blocks rather
+ than find_subblocks. If we have a COND_EXPR or SWITCH_EXPR which
+ is unreachable, but which has reachable children clear out the
+ condition and request all non-control statements be removed
+ from the block.
+ (remove_bb): Allow better control over what (if any) statements
+ are removed. All callers updated.
+ (find_subblocks): Remove.
+ (find_contained_blocks): Handle statements with no associated
+ basic block.
+
+2003-08-15 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * objc/objc-lang.c (LANG_HOOKS_GIMPLIFY_EXPR): Define
+ as the c gimplifier.
+
+2003-08-15 Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (cleanup_tree_cfg): Wipe out the dominator tree
+ if the number of basic blocks changes as a result of cfg cleanups.
+ * tree-flow.h (build_dominator_tree): Prototype.
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize): Build the dominator
+ tree if it is not already available.
+ * tree-ssa.c (build_dominator_tree): New function.
+ (rewrite_into_ssa): Use it.
+
+ * gimplify.c (gimplify_expr, cases NOP_EXPR, CONVERT_EXPR): If a
+ COMPONENT_REF is wrapped with a NOP_EXPR, then force the type of
+ the COMPONENT_REF to match the accessed field. Strip away
+ unnecessary type conversions and handle the case where all type
+ conversions were removed.
+ (case ARRAY_REF, COMPONENT_REF): Indicate to gimplify_array_ref
+ and gimplify_component_ref if we want an lvalue or not.
+ (gimplify_array_ref, gimplify_component_ref): Pass new argument
+ WANT_LVALUE through to gimplify_compound_lval.
+ (gimplify_compound_lval): If we do not want an lvalue and the
+ toplevel COMPONENT_REF's type does not match its field's type,
+ then wrap the COMPONENT_REF in a NOP_EXPR and force the
+ COMPONENT_REF's type to match its field's type.
+ (gimplify_modify_expr): If the RHS is a CALL_EXPR and the LHS
+ is not a gimple temporary, then force the RHS through a gimple
+ temporary, even if the call can not throw.
+ (create_tmp_var): Make sure not to lose the type's attributes
+ for the new variable.
+ * tree-ssa.c (tree_ssa_useless_type_conversion): New function.
+ * tree-flow.h (tree_ssa_useless_type_conversion): Prototype.
+ * tree-ssa-dom.c (optimize_stmt): Use tree_ssa_useless_type_conversion.
+
+ * tree-cfg.c (remove_useless_stmts_and_vars): Catch more
+ useless statements created during the out-of-ssa pass.
+
+2003-08-14 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (optimize_block): Record equivalences created by
+ SWITCH_EXPRs.
+
+ * tree-ssa-dom.c (optimize_stmt): Allow optimizing the RHS of
+ a RETURN_EXPR which contains an optimizable MODIFY_EXPR.
+ (lookup_avail_expr): Corresponding changes.
+ (avail_expr_hash, avail_expr_eq): Likewise.
+
+ * tree-ssa-dom.c (optimize_stmt): Fix typo which prevented
+ stores with more than one VDEF from creating useful equivalences.
+
+ * tree-dfa.c (get_expr_operands): Do not special case *0;
+
+ * fold-const.c (fold, case INDIRECT_REF): Revert last change.
+
+2003-08-14 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (bsi_insert_on_edge_immediate): Only update the
+ container for the head tree of the next block if the new statement
+ needs to be linked to it.
+
+2003-08-13 Jeff Law <law@redhat.com>
+
+ * fold-const.c (fold, case INDIRECT_REF): Optimize reads from
+ constant strings.
+
+ * tree-cfg.c (remove_useless_stmts_and_vars): For a COND_EXPR
+ where the condition is a variable and the ELSE clause merely
+ sets that variable to zero, remove the ELSE clause.
+
+ * tree-ssa-dom.c (optimize_stmt): Do not check the type of the
+ value returned by lookup_avail_expr.
+
+2003-08-13 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-cfg.c (remove_stmt): Add new argument saying whether to remove
+ annotations and invalidate defs. Update all callers
+ (remove_bsi_from_block): Moved from bsi_remove, argument added.
+ (bsi_remove): Made into wrapper for remove_bsi_from_block.
+
+2003-08-13 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * tree-ssa-dom.c (optimize_stmt): Call get_stmt_operands.
+
+2003-08-12 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (optimize_stmt): Record equivalences created
+ by memory stores.
+
+2003-08-12 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (find_insert_location): Handle other control
+ statements that may be at the end of the block.
+
+2003-08-12 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * Makefile.in (tree-pretty-print.o): Add tree-iterator.h dependency.
+ * tree-pretty-print.c: Include tree-iterator.h.
+ (dump_generic_node): Avoid recursing into COMPOUND_EXPRs.
+
+2003-08-12 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (optimize_stmt): Optimize ABS_EXPR when we know
+ the sign of the source operand.
+
+ * tree-ssa-dom.c (optimize_stmt): Rewrite TRUNC_DIV_EXPR and
+ TRUNC_MOD_EXPR even if the LHS is not an SSA variable. Do not
+ enter the new expression in the hash tables if !may_optimize_p.
+ Also try GE_EXPR to see if this transformation is safe.
+
+ * tree-ssa-dom.c (optimize_stmt): Fix typo in last change which
+ prevented recording equivalences created by IOR_EXPR.
+
+ * tree-ssa-dom.c (optimize_stmt): Record that the destination of
+ a MODIFY_EXPR nonzero if the RHS contains an IOR with a nonzero
+ constant. Turn DIV/MOD by a power of 2 into SHIFT/AND if we know
+ dividend is positive.
+
+2003-08-11 Jeff Law <law@redhat.com>
+
+ * fold-const.c (fold, cases NE_EXPR and EQ_EXPR): Fold equality
+ comparisons of non-weak symbol addresses against zero.
+
+ * tree-ssa-ccp.c (fold_stmt): Strip unnecessary NOP_EXPRs from
+ the folded result.
+
+ * gimplify.c (gimplify_expr, case INDIRECT_REF): Copy the base
+ object into a temporary if it's in static memory or is addressable.
+
+2003-08-11 Steven Bosscher <steven@gcc.gnu.org>
+
+ * tree-alias-common.h (struct tree_alias_ops): Add a semicolon, fix
+ bootstrap.
+
+2003-08-10 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-dfa.c (compute_may_aliases): Move points-to initialization from
+ here.
+ (find_referenced_vars): To here.
+ (get_memory_tag_for): Use new same_points_to_set function.
+
+ * tree-alias-common.h (struct tree_alias_ops): Remove doxygen markers.
+ Add same_points_to_set function to struct.
+ (same_points_to_set): New function.
+
+ * tree-alias-common.c (we_created_global_var): A bit of magic to ignore
+ global var aliasing when we didn't create global var. This will go
+ away soon
+ (same_points_to_set): New function.
+
+ * tree-alias-andersen.c (struct andersen_alias_ops): Add
+ andersen_same_points_to_set.
+ (andersen_same_points_to_set): New function. Return true if the two
+ variables have the same points-to set.
+
+ * opts.c (common_handle_option): Add "none" as a points-to option.
+
+2003-08-10 Paul Brook <paul@nowt.org>
+
+ * doc/install.texi: Mention --enable-languages=f95.
+
+2003-08-09 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-pretty-print.c (dump_vops): check bb->tree_annotations, not
+ bb->aux.
+
+2003-08-08 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-cfg.c (bsi_insert_on_edge_immediate): If there's only
+ one statement in the block, and it's an empty statement, replace it.
+
+2003-08-08 Jason Merrill <jason@redhat.com>
+
+ * c-decl.c (c_expand_body_1): Restore support for
+ !keep_function_tree_in_gimple_form.
+ (finish_function, c_expand_deferred_function): Do TDI_inlined dump.
+
+ * gimplify.c (voidify_wrapper_expr): Set TREE_SIDE_EFFECTS on the
+ wrapper if we insert a MODIFY_EXPR.
+
+2003-08-07 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (GTFILES): Add tree-ssa.c, tree-dfa.c and
+ tree-ssa-ccp.c.
+ (gt-tree-ssa.h, gt-tree-dfa.h, gt-tree-ssa-ccp.h): Depend on
+ s-gtype.
+ * tree-dfa.c (struct clobber_data_d): Remove. Update all users.
+ (struct alias_map_d): Mark for garbage collection.
+ (struct walk_state): Add fields 'is_not_gimple' and
+ 'is_va_arg_expr'.
+ (clobber_vars_r): Remove. Update all users.
+ (get_stmt_operands): Abort if attempting to get operands from a
+ non-GIMPLE statement.
+ (get_expr_operands): Likewise.
+ Do not force a virtual operand when scanning VA_ARG_EXPR.
+ (add_stmt_operand): If the variable has hidden uses, mark the
+ statement as having volatile operands and return.
+ If the variable occurs inside a VA_ARG_EXPR, add it as a virtual
+ operand.
+ (add_immediate_use): Call VARRAY_TREE_INIT instead of
+ VARRAY_GENERIC_PTR_INIT.
+ (dump_variable): Check is_in_va_arg_expr flag.
+ (compute_may_aliases): Move code to find variables ...
+ (find_referenced_vars): ... here.
+ (find_vars_r): Abort if we find a non-GIMPLE expression
+ unexpectedly.
+ Mark variables found inside a VA_ARG_EXPR.
+ Do not scan arguments for non-GIMPLE CALL_EXPRs.
+ Remove local variable saved_is_store.
+ Reformat some code for readability.
+ (add_referenced_var): If the variable is already marked as having
+ hidden uses, ignore it.
+ If the variable is found inside a non-GIMPLE expression, mark it.
+ If the variable is found inside a VA_ARG_EXPR, mark it.
+
+ * tree-flow.h (struct var_ann_d): Add field is_in_va_arg_expr.
+ (find_referenced_vars): Declare.
+ * tree-optimize.c (optimize_function_tree): Call
+ find_referenced_vars before computing may aliases.
+
+ * tree-ssa-dce.c (need_to_preserve_store): Do not check if the
+ variable has hidden uses.
+ * tree-ssa-live.c (type_var_init): Likewise.
+
+ * tree-ssa-ccp.c (ssa_edges): Mark for garbage collection.
+ (tree_ssa_ccp): Use VARRAY_.*_EDGE calls to manipulate the varray
+ of CFG edges.
+ (add_control_edge): Likewise.
+ (initialize): Likewise.
+ * tree-ssa.c (struct def_blocks_d): Mark for garbage collection.
+ (struct var_value_d): Likewise.
+ (def_blocks_free): Remove. Update all users.
+ (rewrite_into_ssa): Do not specify free function when creating
+ def_blocks and currdefs.
+ Call sbitmap_free instead of free.
+ (mark_def_sites): Call sbitmap_free instead of free.
+ (set_def_block): Use GC allocation.
+ (set_livein_block): Likewise.
+ (insert_phi_nodes): Adjust name of varray def_maps when creating it.
+ (insert_phis_for_deferred_variables): Remove call to BITMAP_XFREE.
+ (insert_phi_nodes_for): Use GC allocation for phi_insertion_points.
+ (init_tree_ssa): Remove typecast in call to memset.
+ (set_value_for): Use GC allocation.
+ (get_def_blocks_for): Remove typecast in call to htab_find.
+ * varray.c (element): Add entry for struct edge_def *.
+ * varray.h (enum varray_data_enum): Add VARRAY_DATA_EDGE.
+ (union varray_data_tag): Add field of type struct edge_def *.
+ (VARRAY_EDGE_INIT): Define.
+ (VARRAY_EDGE): Define.
+ (VARRAY_PUSH_EDGE): Define.
+ (VARRAY_TOP_EDGE): Define.
+
+2003-08-06 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (handle_switch_fallthru): Do not abort when the last
+ statement of the case block needs to be the last statement of the
+ block.
+ (find_insert_location): Fix typo.
+
+2003-08-06 Steven Bosscher <steven@gcc.gnu.org>
+
+ * tree-dfa.c (remove_phi_arg): When the PHI no longer has
+ arguments, don't remove it here, but do so...
+ (remove_phi_arg_num): ...from here.
+
+2003-08-05 Jason Merrill <jason@redhat.com>
+
+ * gimplify.c (gimplify_cond_expr): Gimplify shortcut expansion in
+ a conditional context.
+
+ * tree-cfg.c (make_catch_expr_blocks): Don't change next_block_link.
+ (make_eh_filter_expr_blocks): Likewise.
+
+ * tree-dfa.c (add_referenced_var): Static locals are call
+ clobbered.
+
+2003-08-05 Steven Bosscher <steven@gcc.gnu.org>
+
+ * tree-dfa.c (add_phi_arg): Allow PHI capacity to grow.
+ * tree-flow.h (add_phi_arg): Adjust prototype.
+ * tree-ssa-pre.c (code_motion): Adjust call.
+ * tree-ssa.c (rewrite_block): Likewise.
+ * tree.c (resize_phi_node): New function.
+ * tree.h (resize_phi_node): Add prototype.
+
+2003-08-05 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (optimize_block): Be more aggressive about
+ creating equivalences from PHI nodes.
+
+ * tree-ssa-dom.c (optimize_stmt): Strip away certain NOP_EXPRs
+ before determining if we have an equivalence to enter into
+ the const_and_copies table.
+
+ * tree-ssa-dce.c (remove_dead_stmts): Iterate backwards through the
+ basic blocks removing dead statements. Within each block iterate
+ backwards through the statements removing those which are dead.
+
+ * tree-ssa-optimize.c (optimize_function_tree): Call
+ remove_useless_stmts_and_vars before building the flow graph.
+ * tree-cfg.c (remove_useless_stmts_and_vars): Rename argument from
+ first_iteration to remove_unused_vars.
+
+ * tree-cfg.c (remove_unreachable_blocks): Remove blocks in reverse
+ order.
+ (remove_bb): Remove unwanted call to bsi_next.
+ (bsi_remove): Refine code which removes useless COMPOUND_EXPRs to allow
+ removal if one of the arms is not associated with a basic block.
+ (remove_stmt): Improve check for testing when a basic block head/end
+ pointer needs to be updated when removing a COMPOUND_EXPR.
+
+ * tree-cfg.c (phi_alternatives_equal): New function.
+ (linearize_cond_expr): Allow linearization if the PHI nodes at the
+ target have equivalent arguments for the incoming edges from the THEN
+ and ELSE clauses.
+
+ * tree-ssa-dce.c (mark_tree_necessary): Empty statements may be
+ necessary.
+ (process_worklist): Handle any incoming abnormal edges the first
+ time a statement in each block becomes executable.
+
+ * tree-ssa-ccp.c (substitute_and_fold): Substitute known
+ constants into PHI nodes.
+
+2003-08-04 Sebastian Pop <s.pop@laposte.net>
+
+ * basic-block.h: Declare bb_ann_d.
+ (basic_block_def): Add a field tree_annotations.
+ * cfg.c (entry_exit_blocks): Initialize tree_annotations to NULL.
+ * cfghooks.c: Remove the definition of cfg_level.
+ (rtl_register_cfg_hooks): Remove the initiallization of cfg_level.
+ * cfghooks.h (cfg_hooks): Add cfgh_loop_optimizer_init, and
+ cfgh_loop_optimizer_finalize.
+ (loop_optimizer_init, loop_optimizer_finalize): New macros.
+ (cfg_level): Remove.
+ * cfgloop.h (loop_optimizer_init, loop_optimizer_finalize): Rename
+ to rtl_loop_optimizer_init and rtl_loop_optimizer_finalize.
+ * cfgrtl.c (rtl_loop_optimizer_init, rtl_loop_optimizer_finalize):
+ Declare, and register them in rtl_cfg_hooks and cfg_layout_rtl_cfg_hook.
+ * loop-init.c (loop_optimizer_init, loop_optimizer_finalize): Rename
+ to rtl_loop_optimizer_init and rtl_loop_optimizer_finalize. Remove
+ the checks to cfg_level.
+ * tree-cfg.c (block_tree_ann_obstack, first_block_tree_ann_obj): New.
+ (create_blocks_annotations, create_block_annotation,
+ free_blocks_annotations, clear_blocks_annotations): New functions.
+ (tree_loop_optimizer_init, tree_loop_optimizer_finalize): New
+ functions. Register them in tree_cfg_hooks.
+ (build_tree_cfg, dump_tree_bb, delete_tree_cfg, tree_split_edge): Use
+ create_blocks_annotations instead of alloc_aux_for_blocks,
+ create_block_annotation instead of alloc_aux_for_block,
+ .tree_annotations instead of .aux,
+ free_blocks_annotations instead of free_aux_for_blocks.
+ (tree_register_cfg_hooks): Remove initialization of cfg_level.
+ * tree-flow-inline.h (bb_ann): Use .tree_annotations.
+ * tree-flow.h: Update comment.
+
+2003-08-04 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * Makefile.in (c-pretty-print.o): Add TREE_H and C_TREE_H dependencies.
+
+2003-08-01 Paul Brook <paul@nowt.org>
+
+ * Makefile.in (GMPINC): Set and use.
+ (GMPLIBS): Set it.
+ * configure.in: Add test and switches for the GMP library.
+ (all_need_gmp): Set from config-lang.in.
+ * sourcebuild.texi: Document need_gmp.
+ * configure: regen
+
+2003-08-01 Steven Bosscher <steven@gcc.gnu.org>
+
+ * tree-inline.c (expand_calls_inline): Fix comments.
+
+2003-07-31 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree-ssa-ccp.o): Depend on $(EXPR_H).
+ * builtins.c (c_strlen): Remove static declaration.
+ (simplify_builtin_fputs): Remove static declaration.
+ (simplify_builtin_sprintf): New local function.
+ (expand_builtin_sprintf): Remove by surrounding with #if 0.
+ (expand_builtin): Add BUILT_IN_SPRINTF to the list of built-ins
+ handed over to simplify_builtin.
+ (validate_arglist): Do not allow arguments with TREE_SIDE_EFFECTS.
+ (simplify_builtin_fputs): Add new argument KNOWN_LEN. If it's set,
+ use it instead of trying to compute the length of the string.
+ Update all callers.
+ * expr.h (simplify_builtin_fputs): Declare.
+ * tree-flow.h (fold_stmt): Change argument type to tree *. Update
+ all users.
+ * tree-ssa-ccp.c: Include expr.h.
+ (replace_uses_in): If the statement makes a call to some selected
+ built-ins, mark it for folding.
+ (get_strlen): New local function.
+ (ccp_fold_builtin): New local function.
+ (fold_stmt): Call it.
+ (set_rhs): Fix if-else-if chaining. Handle cases where the whole
+ statement needs to be replaced.
+ * tree.h (c_strlen): Declare.
+
+2003-07-31 Diego Novillo <dnovillo@redhat.com>
+
+ Fix PR optimization/11373
+ * tree-ssa-dce.c (stmt_useful_p): Get statement operands before
+ checking for volatile operands.
+ * tree-dfa.c (get_expr_operands): If a constant is dereferenced as a
+ pointer, mark the statement as having volatile operands.
+ (may_access_global_mem_p): If a non-NULL constant is used as a
+ pointer, consider it as pointing to global memory.
+ * tree-ssa-dom.c (optimize_stmt): Set addr_expr_propagated_p when
+ propagating pointers that are integer constants.
+
+2003-07-31 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-dfa.c (add_stmt_operand): Don't treat complex types as scalars.
+ * tree-ssa-live.c (var_union): Change comment.
+ (coalesce_tpa_members): Don't proceed if var_union fails.
+ * tree-ssa.c (insert_copy_on_edge): Change comment.
+ (coalesce_abnormal_edges): Handle var_union failing.
+ (coalesce_vars): Skip constant PHI arguments.
+
+2003-07-30 Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (bsi_remove): Don't remove a COMPOUND_EXPR with empty
+ arms if the arms are in different basic blocks.
+
+ * tree-ssa-dom.c (record_cond_is_false): New function.
+ (record_cond_is_true): Similarly.
+ (get_eq_expr_value): Use record_cond_expr_is_{true,false}.
+ (optimize_stmt): Fix minor formatting issue. If we encounter an
+ INDIRECT_REF, record that the dereferenced pointer can not be
+ null.
+
+2003-07-30 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-dump.c (dump_option_value_in): "all" is now everything but
+ TDF_RAW and TDF_SLIM.
+
+2003-07-30 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-simple.c (is_gimple_const): Accept CONST + CONST expressions
+ as GIMPLE constants.
+
+2003-07-30 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c: #include real.h
+ (defs_match_p): Change arguments to something normal now that we use
+ the new renaming algorithm. Update all callers.
+ Use defs_hash_expr.
+ (defs_y_dom_x): Ditto.
+ (defs_hash_expr): New. Based on iterative_hash_expr.
+ (generate_exr_as_of_bb): If there aren't any uses, return.
+ (subst_phis): Call modify_stmt on the actually modified statement. :)
+ (get_default_def): Only walk SSA_NAME arguments in PHI's.
+
+2003-07-30 Jason Merrill <jason@redhat.com>
+
+ Don't modify code that is already GIMPLE.
+ * gimplify.c (gimplify_expr): Don't return early if the predicate
+ matches.
+ Use a variable temp if the caller wants an lvalue.
+ Don't call gimplify_constructor if we're on the rhs of a MODIFY_EXPR.
+ (add_tree, add_stmt_to_compound): Do add an empty stmt if we
+ previously had nothing at all.
+ (gimplify_return_expr): Don't mess with iterators if it was already
+ gimple.
+ (gimplify_cond_expr): Remove a COND_EXPR with two empty arms.
+ (gimplify_call_expr): Try to simplify a builtin again after
+ gimplifying the args.
+ (internal_get_tmp_var): Gimplify the new MODIFY_EXPR.
+ (gimplify_expr, gimple_push_cleanup): Use boolean_false_node.
+ (gimplify_init_constructor): New fn, broken out from...
+ (gimplify_modify_expr): ...here. Be smarter about zero-initialization.
+ * tree-simple.c (is_gimple_rhs): Accept any CONSTRUCTOR.
+ * tree-simple.h: Adjust add_tree prototype.
+
+2003-07-29 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-common.c (create_alias_vars): If we created global_var,
+ delete it when we are done.
+ (ptr_may_alias_var): Handle case that global_var is now NULL_TREE.
+
+2003-07-29 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (optimize_stmt): Propagate copies into VUSEs and
+ the RHS of VDEFs.
+
+2003-07-29 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-ssa.c (insert_copy_on_edge): Only set used bit on DECL nodes.
+
+2003-07-29 Andrew MacLeod <amacleod@redhat.com>
+
+ * common.opt (ftree-combine-temps): Add new option.
+ * flags.h (flag_tree_combine_temps): New flag.
+ * opts.c (decode_options): Initialize flag_tree_combine_temps.
+ (common_handle_option): Handle new flag.
+ * toplev.c (flag_tree_combine_temps): Declare.
+ (lang_independent_options f): Add tree-combine-temp.
+ * tree-ssa-live.c (var_union): When combining 2 root variables, choose
+ the user variable over a temporary as the new variable.
+ (compact_var_map): Use renamed root_var routines.
+ (calculate_live_on_exit): Reformatting.
+ (tpa_init): Initialize a tpa object.
+ (tpa_remove_partition): Remove a partition from a tpa list.
+ (tpa_delete): Delete a tpa object.
+ (tpa_compact): Hide single elemenet lists.
+ (root_var_init): Split common part into tpa_init and rename.
+ (remove_root_var_partition, delete_root_va, dump_root_var): Delete.
+ (type_var_init): New. Initialize a type_var object.
+ (create_coalesce_list): New. Create a coalesce_list object.
+ (delete_coalesce_list): New. Free a coalesce list's memory.
+ (find_partition_pair): New. Find a coalesce pair in a coalesce list.
+ (add_coalesce): New. Add a coalesce between 2 partitions.
+ (sort_coalesce_list): New. Sort coalesce pairs by importance.
+ (pop_best_coalesce): New. Get best remaining pair to coalesce.
+ (add_conflicts_if_valid): Move from tree-ssa.c.
+ (build_tree_conflict_graph): Move from coalesce_ssa_name in tree-ssa.c.
+ Genericize to use tpa_p instead of root_var object. Don't add
+ interferences between copies. Update coalesce list.
+ (coalesce_tpa_members): Move from coalesce_ssa_name in tree-ssa.c. Use
+ tpa_p instead of root_var. Use coalesce list if provided.
+ (dump_coalesce_list): New. Show debug info for a coalesce list.
+ (tpa_dump): Rename from dump_root_var and genericize to use tpa_p.
+ * tree-ssa-live.h (root_var_p): Rename structure type to tpa_p
+ (tpa_num_trees, tpa_tree, tpa_first_partition, tpa_next_partition,
+ tpa_find_tree): New. Generic versions of existing root_var routines.
+ (tpa_decompact): New. Include single version lists.
+ (root_var_p): Declare as type tpa_p.
+ (root_var_num, root_var, root_var_first_partition,
+ root_var_next_partition, root_var_dump, root_var_delete,
+ root_var_remove_partition, root_var_find , root_var_compac,
+ root_var_decompac): Rename and call generic versions.
+ (type_var_p): New. Use tpa_p structure for a type based association.
+ (type_var_num, type_var, type_var_first_partition,
+ type_var_next_partition, type_var_dump, type_var_delete,
+ type_var_remove_partition, type_var_find, type_var_compact,
+ type_var_decompact): New. Call generic versions of the routine.
+ (struct partition_pair_d): New. Represent a desired coalesce.
+ (struct coalesce_list_d): New. Organize lists of desired coalesces.
+ (NO_BEST_COALESCE): Define value.
+ * tree-ssa.c (set_if_valid): Remove.
+ (insert_copy_on_edge): Set variable as used when inserting a copy.
+ (add_conflicts_if_valid): Remove. Move to tree-ssa-live.c.
+ (print_exprs): New. Routine for commonly used output format.
+ (coalesce_abnormal_edges): New. Split from coalece_ssa_name. Force
+ partition coalesces across abnormal edges.
+ (coalesce_ssa_name): Split out build_tree_conflict_graph,
+ coalesce_abnormal_edges, and coalesce_tpa_members. Return live
+ range info if required. Use renamed root_var routines.
+ (assign_vars): Use renamed root_var routines.
+ (replace_variable): Mark as inline.
+ (coalesce_vars): Coalesce variable memory storage.
+ (rewrite_out_of_ssa): Don't compact varmap anymore. Free live range
+ info if required. Call coalesce_vars if combining temps.
+
+2003-07-29 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-cfg.c (handle_switch_fallthru): Use bsi_link_after if stmt is
+ in a basic block.
+
+2003-07-28 Diego Novillo <dnovillo@redhat.com>
+
+ * opts.c (decode_options): Disable must-alias optimization.
+
+2003-07-28 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-ssa.c (struct _elim_graph): Add varray for constant copies.
+ (new_elim_graph): Initialize constant copy array..
+ (eliminate_build): Push constant copies onto stack instead of emitting.
+ (eliminate_phi): Emit any pending constant copies.
+
+2003-07-28 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (optimize_block): If a PHI has a single argument
+ that is a constant, then that creates a useful equivalence.
+ Propagate constant values into PHI nodes.
+
+ * tree-flow-inline.h (may_propagate_copy): Allow RHS to be a
+ constant.
+
+ * tree-dfa.c (compute_immediate_uses_for): Do not assume that
+ PHI arguments are SSA_NAMEs.
+ * tree-ssa-dce.c (process_worklist): Likewise.
+ * tree-ssa-copyprop.c (copyprop_phi): Likewise. Use may_propagate_copy.
+ * tree-ssa-ccp.c (visit_phi_node): Do not assume that PHI arguments
+ are SSA_NAMEs. Create a suitable value if a PHI argument is a
+ constant.
+
+ * tree-cfg.c (move_outgoing_edges): Correctly handle case where
+ an edge already exists from BB1 to BB2's successor.
+
+2003-07-27 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree.h (EREF_TEMP): Rename to EPHI_TEMP.
+ (tree_eref_common): Move temp to tree_ephi_node.
+ * tree-ssa-pre.c: Remove #if 0'd code.
+ Use EPHI_TEMP rather than EREF_TEMP, remove EREF_TEMP on EUSE nodes.
+ (finalize_1): Handle empty blocks properly.
+
+2003-07-27 Andreas Jaeger <aj@suse.de>
+
+ * tree.c: Convert remaining K&R prototypes to ISO C90.
+ * tree-dump.c: Likewise.
+ * tree-inline.c: Likewise.
+ * stmt.c (expand_asm_expr): Likewise.
+
+ * diagnostic.h: Remove PARAMS.
+
+2003-07-26 Paul Brook <paul@nowt.org>
+
+ * Makefile.in: Rename check-g95 to check-gfortran.
+ * gcc.c (default_compilers): Add entries for .f90 and .f95.
+ * doc/frontends.texi: Document new F95 front end.
+ * doc/install.texi: Ditto.
+ * doc/invoke.texi: Ditto.
+ * doc/sourcebuild.texi: Ditto.
+ * fortran: New front end.
+
+2003-07-25 Jeff law <law@redhat.com>
+
+ * tree-ssa-dom.c (optimize_block): Use may_propagate_copy.
+
+2003-07-25 Diego Novillo <dnovillo@redhat.com>
+
+ * opts.c (decode_options): Re-enable must-alias optimizations.
+
+2003-07-25 Daniel Berlin <dberlin@dberlin.org>
+
+ * configure.in: Update BANSHEEREBUILD for PWD change.
+ * configure: regen
+
+2003-07-25 Andreas Jaeger <aj@suse.de>
+
+ * c-call-graph.c: Convert to ISO C90.
+ * c-common.c: Likewise.
+ * c-mudflap.c: Likewise.
+ * c-pretty-print.c: Likewise.
+ * cfganal.c (find_edge): Likewise.
+ * dependence.c: Likewise.
+ * diagnostic.c (debug_output_buffer): Likewise.
+ * except.c (expand_eh_handler): Likewise.
+ * fold-const.c: Likewise.
+ * langhooks.c: Likewise.
+ * tree-cfg.c (last_exec_block): Likewise.
+ * tree-ssa-pre.c: Likewise.
+ * builtins.c: Likewise.
+
+ * tree.h: Remove remaining PARAMS.
+ * c-common.h: Likewise.
+ * c-pretty-print.h: Likewise
+ * c-tree.h: Likewise.
+ * except.h: Likewise.
+ * langhooks-def.h: Likewise.
+ * langhooks.h: Likewise.
+
+2003-07-24 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (cleanup_operand_arrays): New local function. Remove
+ superfluous VUSE operands.
+ (get_stmt_operands): Call it.
+
+2003-07-24 Jason Merrill <jason@redhat.com>
+
+ * gimplify.c (gimple_boolify): New fn.
+ (gimplify_expr) <TRUTH_NOT_EXPR>: Boolify arg.
+ (gimplify_cond_expr): Boolify condition.
+ (gimplify_boolean_expr): Boolify args.
+ (gimple_push_cleanup): Make flag boolean.
+
+ * tree-simple.c (is_gimple_relop): TRUTH_{AND,OR,XOR}_EXPR
+ are not comparisons.
+ (is_gimple_binary_expr): They are binary ops.
+
+ * tree-mudflap.c (mf_build_check_statement_for): Use TRUTH_OR_EXPR
+ rather than BIT_IOR_EXPR.
+
+2003-07-23 Jason Merrill <jason@redhat.com>
+ Diego Novillo <dnovillo@redhat.com>
+
+ * c-common.h (DECL_C_HARD_REGISTER): Replace ...
+ * tree.h (DECL_HARD_REGISTER): ... with this. Update all users.
+
+2003-07-23 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-flow-inline.h (may_propagate_copy): New function.
+ * tree-flow.h (may_propagate_copy): Declare.
+ * tree-ssa-copyprop.c (copyprop_stmt): Call it.
+ (get_original): Likewise.
+ * tree-ssa-dom.c (optimize_stmt): Likewise.
+
+2003-07-23 Frank Ch. Eigler <fche@redhat.com>
+
+ * gcc.c (MFWRAP_SPEC): Also wrap pthread_join and pthread_exit.
+
+2003-07-23 Steven Bosscher <steven@gcc.gnu.org>
+
+ * tree-flow-inline.h (remove_dom_child): New function.
+ (clear_dom_children): New function.
+ * tree-cfg.c (bsi_insert_on_edge_immediate): Do not clear
+ the annotation for the new bb, it is already memset to zero
+ in alloc_aux_for_block().
+ (move_outgoing_edges): Use dom_children() instead of looking
+ at the dom_children field in the basic block annotation.
+ * tree-ssa.c (rewrite_into_ssa): Use clear_dom_children().
+
+ * tree-cfg.c (dump_tree_cfg): Dump to `file', not `dump_file'.
+
+2003-07-23 Diego Novillo <dnovillo@redhat.com>
+
+ * tree.h (DECL_ESTIMATED_INSNS): Move from c-common.h.
+
+2003-07-23 Steven Bosscher <steven@gcc.gnu.org>
+
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize): Make
+ found_unreachable a bool. Create/delete hash tables for
+ copies and available exprs outside the main loop. Use
+ htab_clean to wipe them after each iteration.
+
+2003-07-22 Diego Novillo <dnovillo@redhat.com>
+
+ * opts.c (decode_options): Add temporary test for environment
+ variable TREE_SSA_DO_PRE.
+ Do not disable dominator optimizations when PRE is enabled.
+
+2003-07-22 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (finalize_1): Change to not use bsi_last.
+
+2003-07-22 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-cfg.c (remove_stmt): Revert 07-15 change. Turns out the bug is in
+ the reverse iterator.
+
+2003-07-22 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa-ccp.c (visit_phi_node): Assume default value of CONSTANT
+ if the PHI value was already constant.
+
+2003-07-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * c-pretty-print.c (print_call_name): Handle COND_EXPR correctly.
+ * tree-pretty-print.c (print_call_name): Handle COND_EXPR correctly and
+ handle SSA_NAME.
+ * tree-dfa.c (add_phi_arg, remove_phi_arg_num): Remove references to
+ SSA_NAME_HAS_REAL_REFS.
+ * tree-ssa-ccp.c (visit_phi_node): Remove SSA_NAME_HAS_REAL_REFS.
+ * tree-ssa-copyprop.c (copyprop_phi): Remove SSA_NAME_HAS_REAL_REFS.
+ * tree-ssa-live.c (register_ssa_partition): Register the PHI and it's
+ arguments if this variable is defined by a PHI.
+ (create_ssa_var_map): Only register real uses and defs, and virtual
+ operands of ASM_EXPR's. Remove SSA_NAME_HAS_REAL_REFS. Don't set
+ used flag on variables here.
+ (calculate_live_on_entry): Ignore constants in PHI arguments.
+ (calculate_live_on_exit): Ignore constants in PHI arguments.
+ (dump_live_info): New. Dump live range information.
+ * tree-ssa-live.h (dump_live_info): New prototype and flags.
+ * tree-ssa-pre.c (create_expr_ref, finalize_1, repair_use_injury,
+ code_motion): Remove SSA_NAME_HAS_REAL_REFS.
+ * tree-ssa.c (rewrite_operand, register_new_def): Remove real_ref
+ parameter and SSA_NAME_HAS_REAL_REFS.
+ (rewrite_block): Remove real_ref parameter from register_new_def call.
+ (eliminate_build): Remove SSA_NAME_HAS_REAL_REFS. Insert copy if PHI
+ argument is a constant. Handle irregular PHI argument ordering.
+ (elim_create): Remove dead code to count PHI nodes.
+ (assign_vars): Set used flag on variables when assigned.
+ (replace_variable): Eliminate dead code.
+ (coalesce_ssa_name): Remove SSA_NAME_HAS_REAL_REFS. Print error for
+ constant argument across an abnormal edge.
+ (eliminate_extraneous_phis): New. Remove PHI nodes which are not in
+ the partition.
+ (rewrite_out_of_ssa): Call eliminate_extraneous_phis.
+ (rewrite_stmt): Remove real_ref parameter from rewrite_operand and
+ register_new_def.
+ * tree.h (SSA_NAME_HAS_REAL_REFS): Remove.
+ (struct tree_ssa_name): Remove 'has_real_refs' field.
+
+2003-07-22 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (factor_through_injuries): Take new argument specifying
+ whether use was injured or not (needed for SR). Update all callers.
+ (maybe_find_rhs_use_for_var): Take new argument specifying which
+ operand to start search with. Update all callers.
+ (phi_opnd_from_res): #if 0 out.
+ (rename_2): Ditto.
+ (rename_1): Ditto.
+ (defs_match_p): Take new arguments specifying which defs were injured.
+ Update all callers.
+ (defs_y_dom_x): Ditto.
+ (generate_expr_as_of_bb): Fix small memory overwrite.
+ (process_delayed_rename): Propagate injured flag around.
+ (new_rename_1): Ditto.
+ (finalize_1): Get correct variable names for newly created statement if
+ necessary due to PHI.
+ (repair_use_injury): Note the repair in the stats. Insert repair
+ in right place.
+ (repair_euse_injury): Fix handling of PHI_NODE.
+ (code_motion): Fix algorithm so it can handle using reaching_def all the
+ time (needed for SR).
+ Use reaching_def rather than EREF_TEMP.
+
+2003-07-21 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (get_stmt_operands): Remove FIXME note
+ regarding virtual operands for ASM_EXPRs.
+
+2003-07-21 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (add_def): Renamed from set_def. Update all users.
+ (get_stmt_operands): Don't force ASM_EXPR operands to be virtual.
+ (add_stmt_operand): Allow non-assignments to create new defs.
+ * tree-dump.c (dump_function): Move header dump...
+ (dump_function_to_file): ... here.
+ * tree-flow-inline.h (def_ops): Renamed from def_op. Return a
+ varray with all the definitions made by the statement.
+ Update all users.
+ * tree-flow.h (struct operands_d): Rename field 'def_op' to
+ 'def_ops'. Convert it into a varray.
+ * tree-must-alias.c (tree_compute_must_alias): Call
+ dump_function_to_file instead of dump_function.
+ * tree-ssa-ccp.c (tree_ssa_ccp): Likewise.
+ (visit_stmt): Only visit statements that make new definitions using
+ MODIFY_EXPR.
+ Definitions coming from other statements are considered VARYING.
+ * tree-ssa-copyprop.c (tree_ssa_copyprop): Call
+ dump_function_to_file instead of dump_function.
+ * tree-ssa-dce.c (tree_ssa_dce): Likewise.
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize): Likewise.
+ (optimize_stmt): Don't abort if a statement makes more than one
+ definition.
+ Check for MODIFY_EXPR statements directly, instead of relying on
+ the the presence of a single definition.
+ * tree-ssa-pre.c (tree_perform_ssapre): Call dump_function_to_file
+ instead of dump_function.
+ * tree-ssa.c (rewrite_into_ssa): Likewise.
+ Dump the function before dominator optimizations if TDF_DETAILS is
+ set.
+ (rewrite_stmt): Don't abort if the statement makes more than one
+ definition.
+
+2003-07-21 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize): If we made any
+ blocks unreachable, repeat the dominator optimizations.
+ (optimize_block): Enter PHIs with a single source argument into
+ the const_and_copies table. When propagating into a PHI node,
+ break the loop over the PHI arguments when a propagation is performed.
+ If the PHI agument is not an SSA_VAR, then no propagation is possible.
+ (optimize_stmt): If an operand is not an SSA_VAR, then no propagation
+ is possible/needed.
+
+2003-07-21 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree-ssa-dom.o): Add dependency on $(TREE_DUMP_H).
+ * fold-const.c (fold): Remove unusued local variable 'invert'.
+ * tree-dump.c (dump_files): Add entry for -fdump-tree-dom.
+ * tree-flow.h (tree_ssa_dominator_optimize): Change declaration to
+ accept a function decl.
+ * tree-ssa-dom.c: Include timevar.h and tree-dump.h.
+ (tree_ssa_dominator_optimize): Change to receive the function decl
+ for the function to optimize. Update callers.
+ Use own dump file instead of dumping on the .ssa dump file.
+ Dump function at the end.
+ Push and pop TV_TREE_SSA_DOMINATOR_OPTS.
+ * tree-ssa.c (rewrite_into_ssa): Restore check for number of times
+ that the rename loop has been executed. Abort if the loop executes
+ more than twice.
+ * tree.h (enum tree_dump_index): Add TDI_dom.
+ * doc/invoke.texi: Document -fdump-tree-dom.
+
+2003-07-21 Steven Bosscher <steven@gcc.gnu.org>
+ Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (install-po): Check if $CATALOGS is empty to avoid
+ buggy shells.
+ * basic-block.h (rtl_verify_flow_info): Remove.
+ (tree_verify_flow_info): Remove.
+ (verify_flow_info): Declare.
+ * builtins.c: Rearrange to simplify merges. Add #if 0 around
+ expand_ functions that are not used in the branch and move new code
+ to the end of the file.
+ * c-opts.c (c_common_handle_option): Move handling of -fdump- to
+ opts.c.
+ * cfgloopmanip.c (loop_split_edge_with_NULL): Remove. Update all
+ users.
+ * common.opt: Add all the tree-ssa switches.
+ * opts.c: Handle them.
+ * flags.h (flag_tree_cp): Remove unused variable.
+ (enum pta_type): Move from tree-must-alias.h
+ (flag_tree_points_to): Likewise.
+ * toplev.c (flag_tree_cp): Remove unused variable.
+ * tree-cfg.c: Move cfg_hooks structures and functions for
+ trees from cfghooks.c.
+ * tree-mudflap.c (mudflap_enqueue_decl): Don't use %D to
+ avoid warning about format specifiers.
+
+2003-07-21 Diego Novillo <dnovillo@redhat.com>
+
+ * gimplify.c (gimplify_function_tree): Move gimplification of the
+ function body ...
+ (gimplify_body): ... here.
+ * tree-simple.h (gimplify_body): Declare.
+ * tree-inline.c (initialize_inlined_parameters): If the
+ emitted assignment is not in GIMPLE form, gimplify the
+ body of assignments emitted.
+
+2003-07-17 Jeff Law <law@redhat.com>
+
+ * tree-dfa.c (remove_phi_arg): Update PHI_ARG_CAPACITY.
+
+ * tree-ssa.c (mark_def_sites): Do not build the dominator tree here.
+ (rewrite_into_ssa): Do not depend on mark_def_sites to build the
+ dominator tree. Move computation of dominance frontiers out
+ of main loop (even though it was only done once). Free immediate
+ dominator information as soon as we're done with it.
+
+ * tree-flow.h (remove_phi_nodes_and_edges_for_unreachable_block):
+ Prototype.
+ * tree-cfg.c (remove_phi_nodes_and_edges_for_unreachable_block): New
+ function extracted from remove_bb.
+ (remove_bb): Call remove_phi_nodes_and_edges_for_unreachable_block.
+
+ * tree-ssa-dom.c (optimize_block): Propagate values into PHI nodes.
+ Do not optimize a block which has become unreachable.
+ If a COND_EXPR has a compile-time constant condition, then remove
+ outgoing from the COND_EXPR which can not execute.
+
+2003-07-16 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mx_xfn_indirect_ref): Correct source locations
+ for tracked expressions by ignoring incidental decl source loci.
+
+2003-07-16 Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (remove_bb): Remove statements in reverse order.
+ Simplify code to issue warnings for unreachable code.
+
+ * tree-ssa-dom.c (get_eq_expr_value): Also enter expressions
+ into the available expression hash table. Callers changed to
+ pass in the block_avail_exprs varray and const_and_copies hash
+ table.
+ (optimize_stmt): Allow optimization of the condition in
+ a COND_EXPR statement.
+ (lookup_avail_expr): For COND_EXPRs, just see if their condition
+ has been recorded into the hash table, do not enter them into
+ the hash table. Only do a lookup of the result in the
+ const_and_copies table if it is an SSA_VAR.
+ (avail_expr_hash): Handle COND_EXPRs, specifically we only care
+ about their condition and virtual operands.
+ (avail_expr_eq): Likewise. If one statement has virtual operands
+ and the other does not, then the expressions are not equal.
+
+ * tree-ssa.c (rewrite_into_ssa): If we have done dominator
+ optimizations, then call cleanup_tree_cfg after rewriting is
+ complete.
+ * tree-ssa-dom.c (optimize_block): Get eq_expr_value for the
+ current block rather than having it passed in by the caller.
+ Propagate eq_expr_value into the false arm of a COND_EXPR.
+ (get_eq_expr_value): Return equivalences for the false
+ arm of a COND_EXPR if requested.
+
+2003-07-16 Daniel Berlin <dberlin@dberlin.org>
+
+ * c-decl.c (store_parm_decls): Also strip NON_LVALUE_EXPRs and
+ CONVERT_EXPRs when setting DECL_NONLOCAL.
+
+2003-07-15 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-cfg.c (remove_stmt): Update bb->end_tree_p properly when
+ stmt_p is the end of the bb.
+
+2003-07-15 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (optimize_stmt): Consider two types equivalent if
+ their TYPE_MAIN_VARIANT is equivalent.
+ (avail_expr_eq): Likewise.
+
+ * Makefile.in (OBJS): Add tree-ssa-dom.o
+ (tree-ssa-dom.o): Add dependencies.
+ (ssa.o, cfghooks.o): Use $(TREE_FLOW_H), not tree-flow.h.
+ * timevar.def: Add new timevar for dominator optimizer. Reorder
+ slightly.
+ * tree-dfa.c (add_stmt_operand): Do not consider references to
+ static storage as volatile operands.
+ (add_referenced_var): Static storage items reference global memory.
+ * tree-ssa.c: Simplify by moving everything specific to the
+ dominator optimizer into tree-ssa-dom.c. Call into the dominator
+ optimizer after rewriting all the basic blocks.
+ * tree-ssa-dom.c: New file. Mostly extracted from tree-ssa.c
+ * tree-flow.h (tree_ssa_dominator_optimize): Prototype.
+ (dump_dominator_optimization_stats): Likewise.
+ (debug_dominator_optimization_stats): Likewise.
+
+2003-07-15 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (add_stmt_operand): Move volatile handling...
+ (find_vars_r): ... here.
+ Mark when the walker is inside an ASM_EXPR.
+ (struct walk_state): Add field 'is_asm_expr'.
+ Change flag fields to bitfields.
+ (add_referenced_var): If the variable is a pointer being stored by
+ an ASM_EXPR, mark it as a global memory pointer.
+ * tree-flow-inline.h (is_optimizable_addr_expr): New function.
+ * tree-flow.h (is_optimizable_addr_expr): Declare it.
+ * tree-ssa.c (rewrite_and_optimize_stmt): Use it.
+ (lookup_avail_expr): Likewise.
+ (get_eq_expr_value): Likewise.
+ (avail_expr_eq): Return 'true' when comparing a statement against
+ itself.
+ * tree-ssa-dce.c (need_to_preserve_store): Move volatile checking...
+ (stmt_useful_p): ...here.
+
+2003-07-15 Andreas Jaeger <aj@suse.de>
+
+ * c-simplify.c: Convert prototypes to ISO C90.
+ * gimplify.c: Likewise.
+ * simple-break-elim.c: Likewise.
+ * simple-goto-elim.c: Likewise.
+
+ * tree-alias-ander.c: Convert prototypes to ISO C90.
+ * tree-alias-common.c: Likewise.
+ * tree-alias-type.c: Likewise.
+ * tree-browser.c: Likewise.
+ * tree-dchain.c: Likewise.
+ * tree-mudflap.c: Likewise.
+ * tree-nomudflap.c: Likewise.
+ * tree-optimize.c: Likewise.
+ * tree-pretty-print.c: Likewise.
+ * tree-simple.c: Likewise.
+
+ * tree-alias-common.h: Convert prototypes to ISO C90, remove extra
+ whitespace.
+ * tree-alias-type.h: Convert prototypes to ISO C90.
+ * tree-dchain.h: Likewise.
+ * tree-flow-inline.h: Likewise.
+ * tree-flow.h: Likewise.
+ * tree-iterator.h: Likewise.
+ * tree-mudflap.h: Likewise.
+ * tree-simple.h: Likewise.
+
+2003-07-14 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (tree_perform_ssapre): Fix dom_children after DCE
+ breaks them.
+
+2003-07-14 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (add_vdef): Initialize variable 'vdef'.
+ (add_vuse): Initialize variable 'vuse'.
+
+2003-07-14 Diego Novillo <dnovillo@redhat.com>
+
+ Must alias analysis. Allow the SSA rename pass to be done on a set
+ of variables.
+
+ * Makefile.in (OBJS): Add tree-must-alias.o.
+ * flags.h (flag_tree_must_alias): Declare.
+ * timevar.def (TV_TREE_MUST_ALIAS): Define.
+ * toplev.c (flag_tree_must_alias): Declare.
+ (f_options): Add entry for -ftree-must-alias.
+ (parse_options_and_default_flags): Enable must-alias analysis at -O1.
+
+ * tree-cfg.c (remove_useless_stmts_and_vars): Do not remove
+ addressable variables.
+
+ * tree-dfa.c (dump_file, dump_flags): New local variables to
+ replace tree_ssa_dump_file and tree_ssa_dump_flags. Update every
+ user.
+ (get_stmt_operands): Clear the array of virtual operands before
+ scanning the statement.
+ (get_expr_operands): Do not add an operand for ADDR_EXPR if the
+ expression takes the address of a VAR_DECL or a PARM_DECL. Instead
+ add the variable to the list of variables whose address has been
+ taken by the statement.
+ Allow INDIRECT_REF expressions of the form *&VAR. Convert them
+ into an operand for VAR.
+ When processing function calls, add a VUSE for .GLOBAL_VAR if the
+ function is pure but not const.
+ (add_stmt_operand): If the operand is an ADDR_EXPR, add the
+ variable to the list of variables whose address has been taken by
+ the statement.
+ (add_vdef): If the statement had virtual definitions, try to find
+ an existing VDEF for the variable, to preserve SSA information. If
+ none is found, create a new one.
+ (add_vuse): Likewise.
+ (remove_all_phi_nodes_for): New function.
+ (get_call_flags): New function to replace call_may_clobber. Update
+ all callers.
+
+ * tree-dump.c (dump_files): Add entry for -fdump-tree-mustalias.
+ * tree-flow-inline.h (addresses_taken): New function.
+ (is_unchanging_value): New function.
+
+ * tree-flow.h (addresses_taken): Declare.
+ (remove_all_phi_nodes): Declare.
+ (init_tree_ssa): Declare.
+ (propagate_copy): Declare.
+ (is_unchanging_value): Declare.
+ (tree_compute_must_alias): Declare.
+
+ * tree-inline.c (copy_body_r): Fold instances of *&VAR.
+
+ * tree-must-alias.c: New file.
+
+ * tree-optimize.c (optimize_function_tree): Call init_tree_ssa and
+ compute_may_aliases before calling rewrite_into_ssa.
+ After the SSA pass, run dead code elimination and compute
+ must-aliases.
+
+ * tree-simple.c (is_gimple_call_expr): Add comment that
+ is_gimple_* predicates should not have side effects.
+
+ * tree-ssa-ccp.c: Replace calls to really_constant_p with
+ is_unchanging_value everywhere.
+ (fold_stmt): Don't fold if the RHS is already a constant.
+
+ * tree-ssa-copyprop.c (copyprop_stmt): Remove unnecessary
+ variable 'vuse'.
+ Call propagate_copy to replace the operand with its new value.
+ (copyprop_phi): Remove unnecessary variable 'vuse'.
+ (get_original): Remove unused parameter 'vuse_p'.
+ (propagate_copy): New function.
+
+ * tree-ssa-dce.c (need_to_preserve_store): Update comments.
+
+ * tree-ssa.c (dump_file, dump_flags): New local variables to
+ replace globals tree_ssa_dump_file and tree_ssa_dump_flags. Update
+ all users.
+ (addr_expr_propagated_p): New local variable.
+ (vars_to_rename): New local variable.
+ (check_for_new_variables): New local function.
+ (rewrite_into_ssa): Add new argument VARS which is a bitmap
+ representing all the variables that should be renamed into SSA. If
+ VARS is NULL, all the variables in the program are renamed.
+ Don't call init_tree_ssa nor compute_may_aliases.
+ Initialize all the local hash tables and bitmaps.
+ Add support for repeating the SSA rename process more than once.
+ If the dominator optimizations produced new symbols, repeat the
+ process.
+ (mark_def_sites): Ignore operands that are in SSA form already.
+ (insert_phi_nodes): Only add PHI nodes for variables in the
+ VARS_TO_RENAME bitmap.
+ (rewrite_block): Ignore PHI nodes that have been renamed already.
+ (rewrite_and_optimize_stmt): Ignore operands that are already in
+ SSA form.
+ When propagating ADDR_EXPR set addr_expr_propagated_p to 'true'.
+ Call propagate_copy when doing copy propagation.
+ Call is_unchanging_value to decide if the RHS of an assignment is a
+ constant.
+ (rewrite_stmt): Ignore operands that are already in SSA form.
+ (init_tree_ssa): Make external.
+ Move initialization of local hash tables and bitmaps to
+ rewrite_into_ssa.
+ (remove_annotations_r): Don't special case MODIFY_EXPR nodes.
+ (lookup_avail_expr): Call is_unchanging_value.
+ (get_eq_expr_value): Likewise.
+
+ * tree.h (enum tree_dump_index): Add TDI_must_alias.
+
+ * cp/optimize.c (optimize_function): Don't call the tree optimizers
+ if -fdisable-tree-ssa is given.
+
+ * doc/invoke.texi: Add documentation for -ftree-must-alias.
+
+2003-07-07 Jeff Law <law@redhat.com>
+
+ * fold-const.c (nondestructive_fold_unary_to_constant: For BIT_NOT_EXPR
+ make sure OP0 is a suitable constant before trying to fold it.
+
+ * tree-cfg.c (handle_switch_fallthru): Set DECL_CONTEXT for
+ newly created labels.
+
+ * tree-cfg.c (move_outgoing_edges): New function.
+ (merge_tree_blocks): Use it.
+ (remove_bb): Remove the block from the pdom_info structures
+ as well if they exist.
+ (linearize_cond_expr): Move important edges from the then and
+ else arms to BB as appropriately
+
+ * tree-cfg.c (remove_stmt): When removing a COMPOUND_EXPR, make
+ sure that any basic block pointers to the arms of the COMPOUND_EXPR
+ are updated.
+
+ * tree-cfg.c (make_goto_expr_edges): Computed gotos create
+ abnormal edges.
+
+2003-07-05 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (defs_match_p): Check for copies of the same version.
+
+2003-07-03 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-nomudflap.c (mf_marked_p, mf_mark): New dummy functions.
+
+2003-07-03 Jeff Law <law@redhat.com>
+
+ * tree-ssa.c (lookup_avail_expr): Accept new argument containing the
+ const_and_copies table. All callers changed. If we find the
+ given expression in the availe expression hash table, then lookup
+ the LHS of the hash table's entry in the const_and_copies_table.
+ Do record type casts into the available expression table.
+
+ * tree-nomudflap.c (mf_marked_p): Mark arguments as being unused.
+ (mf_mark): Likewise.
+
+ * c-decl.c (store_parm_decls): Strip away NOP_EXPRs when looking
+ for hidden use variables.
+
+2003-07-02 Frank Ch. Eigler <fche@redhat.com>
+
+ * varasm.c (build_constant_desc): Propagate mudflap marked-ness
+ across constant copying.
+
+2003-07-02 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (tree_perform_ssapre): Don't optimize things with
+ volatile ops or making aliased loads right now.
+ (create_expr_ref): Mark the phi result of the new phi as having
+ real refs.
+ (finalize_1): Mark the new temp as having real refs.
+ (repair_use_injury): Ditto.
+ (code_motion): Ditto.
+
+2003-07-01 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree.h (struct tree_eref_common): Add injured flag.
+ Add EREF_INJURED macro.
+
+2003-07-01 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-flow-inline.h (stmt_ann): We have stmt_ann on E*_NODE's as well,
+ so use is_essa_node as well.
+ * tree-dfa.c (create_stmt_ann): Ditto.
+ * tree.h (is_essa_node): Declare.
+ * tree.c (is_essa_node): Define.
+
+2003-07-01 Jason Merrill <jason@redhat.com>
+
+ * tree-cfg.c (prepend_stmt_to_bb): New fn.
+ (bsi_insert_after): Add to the beginning of an empty block.
+
+2003-07-01 Jeff Law <law@redhat.com>
+
+ * expr.c (expand_expr, case COND_EXPR): Correctly (?) handle
+ cases where a containing block has a stack level. Handle
+ cases where one arm is a GOTO_EXPR and the other arm has
+ side effects.
+
+ * stmt.c (containing_blocks_have_cleanups_or_stack_level): New
+ function.
+ (any_pending_cleanups): Further simplification.
+ * tree.h (containing_blocks_have_cleanups_or_stack_level): Prototype.
+
+2003-06-30 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-flow.h (struct tree_ann_common_d): Remove 'stmt' field.
+ Update all users.
+ (struct var_ann_d): Remove field 'has_real_refs'. Update all callers
+ with calls to SSA_NAME_HAS_REAL_REFS.
+ Remove field 'occurs_in_abnormal_phi'. Update all callers with
+ calls to SSA_NAME_OCCURS_IN_ABNORMAL_PHI.
+ * tree-flow-inline.h (var_ann): Only accept _DECL nodes.
+ (stmt_ann): Only accept GIMPLE statements.
+ (tree_stmt): Remove. Update all users.
+
+ * tree-cfg.c (linearize_cond_expr): Handle cases where BB doesn't
+ have a postdominator.
+ (find_contained_blocks): Do not look inside COND_EXPR_COND nor
+ SWITCH_COND expressions.
+
+ * tree-dfa.c (get_stmt_operands): Force virtual operands on
+ ASM_EXPRs.
+ (get_expr_operands): Handle SSA names when adding operands for
+ memory tags.
+ (add_stmt_operand): Handle SSA names.
+ Move checks for volatile operands earlier in the code.
+ (add_vdef): Re-format for readability.
+ (create_var_ann): Only allow _DECL nodes.
+ (create_stmt_ann): Only allow GIMPLE statements.
+ (dump_variable): Handle SSA names.
+ (dump_may_aliases_for): Likewise.
+ (may_access_global_mem_p): Handle SSA names.
+ (remove_phi_arg): If the argument removed was the last one with
+ real references, update the LHS of the PHI node.
+ (add_phi_arg): If the argument added has real references, propagate
+ the attribute into the LHS of the PHI node.
+
+ * tree-pretty-print.c (dump_generic_node): Only retrieve basic
+ block information from GIMPLE statements.
+ Always output the THEN and ELSE clauses of COND_EXPR nodes.
+
+ * tree-simple.c (is_gimple_stmt): Accept PHI_NODEs.
+ (is_gimple_id): Accept SSA_NAMEs.
+
+ * tree-ssa-copyprop.c (copyprop_phi): If an argument is used as a
+ real operand, propagate the attribute into the LHS of the PHI.
+
+ * tree-ssa-live.c (create_ssa_var_map): Don't set 'used' flag on
+ both the operand and the result of VDEFs.
+ Only register PHI results and arguments that have been used as real
+ operands.
+ (calculate_live_on_entry): Fix formatting in debugging message.
+
+ * tree-ssa.c (register_new_def): Add new argument
+ 'is_real_operand'. If it's set, set SSA_NAME_HAS_REAL_REFS for the
+ new name. Update all callers.
+ (rewrite_operand): Add new argument 'is_real_operand'. If it's
+ set, set SSA_NAME_HAS_REAL_REFS to the operand.
+ (eliminate_build): Ignore PHI arguments and PHI results that have
+ not been used in real operands.
+ (rewrite_vdefs): Remove. Update all users.
+ (set_is_used): Don't handle SSA names.
+ (coalesce_ssa_name): Ignore PHI arguments that have not had real
+ references in the program.
+
+ * tree.c (make_ssa_name): Update documentation.
+ * tree.h (IS_EMPTY_STMT): Call integer_zerop instead of comparing
+ against size_zero_node.
+ (SSA_NAME_HAS_REAL_REFS): Define.
+ (SSA_NAME_OCCURS_IN_ABNORMAL_PHI): Define.
+ (struct tree_ssa_name): Add bitfields 'has_real_refs' and
+ 'occurs_in_abnormal_phi'.
+
+2003-06-30 Jeff Law <law@redhat.com>
+
+ * c-simplify.c (gimplify_c_loop): Don't return a LOOP_EXPR for
+ a do ... while (0) loop.
+
+ * expr.c (expand_expr, case COND_EXPR): Be smarter about expanding
+ a COND_EXPR with only one useful arm, which happens to be a GOTO_EXPR.
+
+ * tree-cfg.c (remove_useless_stmts_and_vars): Don't remove user
+ variables unless we're at -O2 or higher.
+
+2003-06-30 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (expr_phi_insertion): Stop optimizing the expression
+ if we have > some very large number of ephi operands, as it will
+ take an ungodly amount of memory and time.
+ (pre_expression): Push/pop gc context so we can do gc collection
+ in between expressions.
+ Throw away expression info right after done optimizing it.
+
+2003-06-30 Jason Merrill <jason@redhat.com>
+
+ * gimplify.c (gimplify_call_expr): Check PUSH_ARGS_REVERSED.
+
+ * gimplify.c (gimplify_modify_expr): Also force a call with a
+ possible nonlocal goto into a temporary.
+ (gimplify_return_expr): Don't duplicate the MODIFY_EXPR.
+ * tree-iterator.h (tsi_one_before_end_p): New fn.
+
+2003-06-29 Jeff Sturm <jsturm@one-point.com>
+
+ * fold-const.c (fold): Don't save_expr unless TREE_SIDE_EFFECTS.
+
+2003-06-26 Diego Novillo <dnovillo@redhat.com>
+
+ * c-simplify.c (gimplify_stmt_expr): Handle statement-expressions
+ that don't end in a non-void expression. Emit a warning in that
+ case.
+
+2003-06-26 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (fixup_domchildren): Rename from
+ compute_domchildren, change to not use our own array.
+ (domchildren): Remove variable.
+ (insert_occ_in_preorder_dt_order_1): Use dom_children now.
+ (insert_euse_in_preorder_dt_order_1): Ditto.
+ (search_dt_preorder): Ditto.
+ (handle_bb_creation): Fix to work properly.
+ (tree_perform_ssapre): Remove remnants of domchildren.
+ Redo dominator info if we have to due to a new block.
+
+2003-06-26 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-cfg.c (handle_switch_split): Use a tree iterator to find the
+ real split point rather than a block iterator.
+
+2003-06-26 Jason Merrill <jason@redhat.com>
+
+ * tree-simple.c (is_gimple_stmt): Complete.
+
+2003-06-24 Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (remove_useless_stmts_and_vars): On the first
+ iteration, remove unused variables from BIND_EXPRs.
+ * tree-flow.h (var_ann_d): Add new field USED.
+ (set_is_used): Prototype.
+ (remove_useless_stmts_and_vars): Update prototype.
+ * tree-ssa-live.c (create_ssa_var_map): Note which variables
+ are used so that we can delete those which are not used.
+ * tree-ssa.c (create_temp): Mark the new temporary as being used.
+ (rewrite_out_of_ssa): Note if the call to remove_useless_stmts_and_vars
+ is the first iteration or not.
+ (set_is_used): New function.
+
+ * c-decl.c (store_parm_decls): Variables and parameters on the
+ pending_sizes chain have nonlocal uses.
+
+2003-06-25 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c: Convert to ISO C.
+ (handle_bb_creation): New function.
+ (ephi_will_be_avail): Remove dead code.
+ (finalize_1): Use handle_bb_creation, start to fix edge insertion
+ related fun.
+ (maybe_find_rhs_use_for_var): Stop using tree_stmt.
+ (code_motion): Always get the temporary from the right place.
+
+2003-06-24 Jason Merrill <jason@redhat.com>
+
+ * gimplify.c (gimplify_self_mod_expr): Add want_value parm.
+ For postfix ops, make sure it returns an rvalue.
+ (gimplify_expr): Copy a volatile reference into a temp.
+ (create_tmp_var): Require a complete type.
+ (create_tmp_alias_var): Use TYPE_VOLATILE on types.
+ * tree-simple.c (is_gimple_stmt): Flesh out a bit.
+ (is_gimple_val): Don't allow volatiles.
+
+ * c-simplify.c (gimplify_expr_stmt): Don't insert a null pointer.
+
+ * gimplify.c (gimplify_return_expr): Search through the gimple
+ form for the interesting MODIFY_EXPR.
+ (gimplify_modify_expr): Don't suppress posteffects if want_value.
+
+2003-06-24 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (struct dfa_stats_d): Remove obsolete fields
+ num_tree_refs and size_tree_refs. Update all users.
+ (dump_dfa_stats): Also dump information about VUSE and VDEF
+ operands.
+ * tree-ssa.c (rewrite_vdefs): Dump information about VDEF operators
+ promoted to real copies if -fdump-tree-optimized-details is given.
+
+2003-06-23 Jeff Law <law@redhat.com>
+
+ * tree-ssa.c (avail_expr_eq): Verify types are the same before
+ handing expressions to operand_equal_p.
+
+ * tree-cfg.c (make_edges): Remove fake edges before building
+ extra edges for TRY_FINALLY_EXPRs. Delete unnecessary edges
+ leaving the TRY block in a TRY_FINALLY_EXPR.
+ (find_contained_blocks): Don't consider statements in the CATCH
+ clause of a TRY_CATCH_EXPR when noting the last statement in
+ the block.
+ * tree-dfa.c (remove_phi_arg): If we removed the last PHI argument,
+ then remove the entire PHI node.
+ * tree-ssa-dce.c (stmt_useful_p): Consider the other EH related
+ nodes useful as well (TRY_FINALLY_EXPR, TRY_CATCH_EXPR, and
+ EH_FILTER_EXPR).
+
+ * tree-cfg.c (remove_useless_stmts_and_vars): If the body of a
+ TRY_CATCH_EXPR is empty, then the entire TRY_CATCH_EXPR can
+ be safely removed.
+
+ * tree-cfg.c (find_contained_blocks): Renamed from
+ find_contained_blocks_and_edge_targets. Remove targets
+ bitmap argument and no longer record targets of edges.
+ All callers changed.
+ (make_edges): No longer need TRY_TARGETS bitmap. Kill it.
+ Simplify code which creates additional edges out of the TRY
+ block and the FINALLY block in a TRY_FINALLY_EXPR.
+
+2003-06-23 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-alias-common.c (ptr_may_alias_var): Don't handle memory
+ tags.
+ * tree-dfa.c (struct alias_set_d): Remove. Update all users.
+ (alias_sets): Remove. Update all users.
+ (struct walk_state): Remove field aliased_objects_found.
+ (struct alias_map_d): New.
+ (addressable_vars): New local variable.
+ (pointers): New local variable.
+ (add_stmt_operand): Do not force aliased variables to be in virtual
+ operands.
+ (register_alias_set): Remove. Update all users.
+ (find_alias_for): Remove. Update all users.
+ (get_memory_tag_for): New local function.
+ (num_referenced_vars): Remove.
+ (num_aliased_objects): Remove. Update all users.
+ (aliased_objects): Remove. Update all users.
+ (aliased_objects_alias_set): Remove. Update all users.
+ (num_call_clobbered_vars): Remove. Update all users.
+ (dump_variable): Move code to dump aliases ...
+ (dump_may_aliases_for): ... here.
+ (debug_may_aliases_for): New function.
+ (compute_may_aliases): Initialize 'addressable_vars' and 'pointers'
+ arrays.
+ (compute_alias_sets): Re-implement matching pointers with
+ addressable variables. Limit the size of may-alias sets.
+ (may_alias_p): Re-implement to compare pointers against variables,
+ instead of memory tags.
+ (dump_alias_info): Re-implement to display pointers and addresable
+ variables arrays.
+ (add_referenced_var): Collect addressable variables and pointers.
+ Share memory tags among pointers that may alias each other.
+ * tree-flow.h (num_referenced_vars): Change to macro.
+ (referenced_var): Likewise.
+ (num_call_clobbered_vars): Likewise.
+ (call_clobbered_var): Likewise.
+ (dump_may_aliases_for): Declare.
+ (debug_may_aliases_for): Declare.
+ * tree-ssa.c (rewrite_vdefs): New local function.
+ (rewrite_out_of_ssa): Call it.
+
+2003-06-23 Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (make_edges): Walk TRY_FINALLYs inner to outer and
+ simplify creation of special edges related to the TRY_FINALLY_EXPR.
+
+ * tree-cfg.c (remove_useless_stmts_and_vars): More aggressively
+ remove TRY_CATCH_EXPRs and TRY_FINALLY_EXPRs.
+
+ * tree-cfg.c (make_edges): Remove fake edges.
+ (make_exit_edges): Mark edges from nonreturning functions to the
+ exit block as being fake edges.
+
+ * gimplify.c (gimplify_modify_expr): Don't create a new MODIFY_EXPR,
+ reuse the existing one.
+
+2003-06-23 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-cfg.c (find_insert_location): Default case should insert after
+ the last stmt in the block.
+
+2003-06-22 Jeff Sturm <jsturm@one-point.com>
+
+ * Makefile.in (old-tree-inline.o): Remove rule.
+ * old-tree-inline.c: Remove.
+
+2003-06-19 Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (make_ctrl_stmt_edges): Do not create bogus edges
+ to the successor block of TRY_CATCH_EXPR, TRY_FINALLY_EXPR,
+ CATCH_EXPR or EH_FILTER_EXPR nodes.
+
+ * gimplify.c (gimplify_modify_expr): If the RHS of an MODIFY_EXPR
+ might throw, then make sure its result goes into a temporary.
+
+ * tree-cfg.c (handle_switch_split): Handle case where target
+ block has only one statement (the case label itself).
+
+2003-06-19 Diego Novillo <dnovillo@redhat.com>
+
+ * doc/invoke.texi: Add documentation for -ftree-dominator-opts
+ that was missing from an earlier patch.
+
+2003-06-19 Jeff Sturm <jsturm@one-point.com>
+
+ * gimplify.c (gimplify_expr): Handle LABELED_BLOCK_EXPR
+ and EXIT_BLOCK_EXPR.
+ (gimplify_labeled_block_expr): New function.
+ (gimplify_exit_block_expr): New function.
+
+2003-06-18 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-cfg.c (EDGE_INSERT_LOCATION_BSI_AFTER): New location code.
+ (cleanup_switch_expr_graph): Find default case correctly.
+ (bsi_insert_after): Get BB from stmt when its avialble.
+ (bsi_insert_before): Get BB from stmt when its avialble.
+ (handle_switch_fallthru): New. Handle edge from switch to the fallthru.
+ (handle_switch_split): Re-implement using new scheme.
+ (find_insert_location): Use handle_switch_fallthru ().
+ (bsi_insert_on_edge_immediate): Handle EDGE_INSERT_LOCATION_BSI_AFTER.
+ * tree-iterator.h (tsi_last): New. Find last stmt in a chain.
+
+2003-06-17 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-common.c (find_func_aliases): Guard cast op
+ properly.
+ (ptr_may_alias_var): Small optimization to avoid calling
+ decl_function_context so often.
+ * tree-alias-ander.c (ander_simple_assign): Ignore if lhs == rhs.
+
+2003-06-17 Steven Bosscher <steven@gcc.gnu.org>
+
+ * timevar.def (TV_TREE_BUILD_FUD_CHAINS): Remove.
+
+2003-06-16 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa-ccp.c (DONT_SIMULATE_AGAIN): Define.
+ (visit_phi_node): Don't do anything if the PHI node doesn't need to
+ be simulated.
+ If the PHI variable does not have real references, consider it
+ VARYING.
+ If the PHI node has a lattice value of VARYING, set
+ DONT_SIMULATE_AGAIN.
+ (visit_stmt): Don't do anything if the statement doesn't need to be
+ simulated.
+ Only visit conditional branches COND_EXPR and SWITCH_EXPR.
+ If the statement doesn't produce a result mark it with
+ DONT_SIMULATE_AGAIN.
+ (visit_assignment): Remove unnecessary def_op() check.
+ If the value is VARYING, mark the statement with
+ DONT_SIMULATE_AGAIN.
+ (visit_cond_stmt): Remove unnecessary is_ctrl_stmt() check.
+ If the predicate is VARYING, mark the statement with
+ DONT_SIMULATE_AGAIN.
+ (initialize): Clear DONT_SIMULATE_AGAIN flag for every statement
+ and PHI node.
+ (likely_value): Get statement operands after checking if it makes
+ aliased loads or has volatile operands.
+
+2003-06-16 Jeff Law <law@redhat.com>
+ Jason Merrill <jason@redhat.com>
+
+ * except.c (enum eh_region_type): Don't declare the enumeration
+ members here. Instead do it in except.h.
+ (expand_eh_hander): Use expr_first instead of open-coding it.
+ * except.h (enum eh_region_type): Define the enumeration memebers
+ here.
+ * tree-cfg.c (last_exec_block): Break out from make_edges.
+ (could_trap_p): No longer static.
+ (get_eh_region_type): New function.
+ (make_try_expr_blocks): Keep the whole TRY_CATCH_EXPR or
+ TRY_FINALLY_EXPR instead of just the handler part in the
+ EH_STACK varray. For a cleanup, record which cleanup higher
+ in the EH_STACK it can reach.
+ (make_edges): Use last_exec_block.
+ (make_ctrl_stmt_edges): Thread cleanups as needed.
+ (compute_reachable_eh): Use get_eh_region_type. Properly
+ track when we can skip cleanups. Skip cleanups when possible.
+ * tree-flow.h (could_trap_p): Prototype.
+
+2003-06-16 Andrew Macleod <amacleod@redhat.com>
+
+ * tree-cfg.c (find_insert_location): Check for control_altering stmts,
+ and abort if its an unrecognized BB ending stmt.
+ (bsi_commit_first_edge_insert): Rename to bsi_insert_on_edge_immediate,
+ externalize, and change the interface to an on-demand inserter.
+ (bsi_commit_edge_inserts): Call bsi_insert_on_edge_immediate().
+ * tree-flow.h (bsi_insert_on_edge_immediate): Prototype.
+ * tree-pretty-print.c (dump_block_info): Add 'ab' for abnormal edges.
+ * tree-ssa-dce.c (process_worklist): Use sparse bitmaps.
+ * tree-ssa-live.c (calculate_live_on_entry): Abort if ssa_name has a
+ definition, but is also live on entry.
+ * tree-ssa.c (coalesce_ssa_name): Call abort() instead of error(), and
+ provide more detailed info.
+ (rewrite_out_of_ssa): Provide CFG dumps before and after rewritting.
+
+2003-06-16 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mf_mark): Use GC-compatible htab_create_ggc.
+
+2003-06-15 Jeff Law <law@redhat.com>
+
+ * tree-ssa-ccp.c (visit_phi_node): If the PHI is already known
+ to be varying, don't recompute its value.
+
+2003-06-14 Jeff Law <law@redhat.com>
+ Jason Merrill <jason@redhat.com>
+
+ * tree-cfg.c (make_blocks): Do not return early if presented
+ with an empty statement.
+ (make_ctrl_stmt_edges): Do not try to optimize an empty TRY
+ block in a TRY_FINALLY_EXPR. Simplify TRY_FINALLY_EXPR,
+ TRY_CATCH_EXPR, CATCH_EXPR, and EH_FILTER_EXPR now that empty
+ statements are no longer shared.
+
+2003-06-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * tree-ssa-pre.c: Fix a comment typo.
+
+2003-06-13 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (get_stmt_operands): Abort if the statement is a
+ variable.
+ (create_var_ann): Abort if the variable is not a _DECL node.
+
+2003-06-13 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mudflap_c_function): Change calling conventions so
+ as to return the instrumented function body rather than changing the
+ given fndecl in place. Gimplify at the very end, for cosmetic
+ reasons.
+ * tree-mudflap.h, tree-nomudflap.c: Corresponding changes.
+ * c-decl.c (c_expand_body_1): Call mudflap_c_function just before
+ rtl expansion of function body; don't interfere with inlining.
+
+2003-06-13 Diego Novillo <dnovillo@redhat.com>
+
+ * c-simplify.c: Fix typo in previous change.
+
+2003-06-13 Diego Novillo <dnovillo@redhat.com>
+
+ * c-common.c, c-common.h, c-decl.c, c-lang.c, c-simplify.c,
+ flags.h, gimplify.c, langhooks-def.h, langhooks.c, langhooks.h,
+ simple-break-elim.c, simple-goto-elim.c, toplev.c,
+ tree-alias-common.c, tree-cfg.c, tree-dfa.c, tree-dump.c,
+ tree-inline.c, tree-mudflap.c, tree-simple.c, tree-simple.h,
+ tree-ssa-ccp.c, tree-ssa-pre.c, tree-ssa.c, tree.h, doc/invoke.texi:
+ Rename SIMPLE to GIMPLE everywhere.
+
+2003-06-13 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-cfg.c (bsi_commit_first_edge_insert): Only consider non-abnormal
+ edges when determining whether an edge needs to be split.
+
+ * tree-ssa-dce.c (process_worklist): When checking for GOTO and
+ COND_EXPR's that are necessary, check each BB's predecessors only once.
+
+2003-06-12 Jeff Law <law@redhat.com>
+
+ * tree-ssa.c (avail_expr_eq): Add some checking code to
+ detect when equal expressions have different hash values.
+
+ * tree.c (iterative_hash_expr): Don't hash types associated
+ with conversions. Instead hash on the signedness of the
+ toplevel object and the operand of the conversion.
+
+ * Makefile.in (gimplify.o): Depend on $(RTL_H). Ugh.
+ * gimplify.c: Include "rtl.h".
+ (simplify_call_expr): Use call_expr_flags and check for ECF_CONST
+ rather than checking bits in the tree node directly.
+
+ * fold-const.c (operand_equal_p): CALL_EXPRs with side effects
+ are never equal.
+
+2003-06-11 Frank Ch. Eigler <fche@redhat.com>
+
+ * gcc.c (MFWRAP_SPEC): Always wrap main().
+ * tree-mudflap.c (mudflap_enqueue_decl): Mark enqueued decls
+ to prevent their repeated processing.
+
+2003-06-11 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c: add graph_dump_file, graph_dump_flags.
+ (finalize_1): Modify to use temporary in expr_info structure,
+ remove temporary from arguments.
+ Use bsi_insert_on_edge for ephi insertions.
+ Set EREF_TEMP on inserted euses.
+ (repair_phi_injury): Note (to dump file) injuries we have
+ repaired already.
+ (repair_use_injury): Ditto.
+ (repair_euse_injury): Ditto.
+ (count_stmts_in_bb): Count both forwards and backwards, and make
+ sure the numbers agree. This makes sure both the head and end are
+ updated properly.
+ (code_motion): Use the EREF_TEMP, rather than calculating the
+ reaching def, when possible, because it's faster.
+ Add the phi we created when we insert the ephi. We should always
+ be able to get the reaching def of the ephi from EREF_TEMP (since
+ the args should have already been inserted, or in the case of
+ phi's, have a phi already allocated), so abort if we can't.
+ (create_expr_ref): Take expr_info parameter. Make a phi for the
+ ephi's, but don't add to the bb yet. Update all callers.
+ (get_default_def): New function.
+ (get_reaching_def): Use it to find the default def when we hit the
+ top of the dom tree.
+ (struct expr_info): Add temp.
+ (new_rename_1): Dump out occurrences after rename 1, but before
+ rename 2.
+ (requires_edge_placement): Now that we can insert on edges, we
+ shouldn't need this, so make it always return false.
+ Will remove unless something bad comes up.
+ (pre_expression): Start working on dumping the redundancy graph.
+
+ * tree.h (struct treeeref_common): Add the temp member.
+ Add EREF_TEMP macro.
+ (tree_dump_index): Reorder to match actual optimization order.
+ Add TDI_predot.
+
+ * tree-dump.c: Ditto.
+
+2003-06-11 Jeff Law <law@redhat.com>
+
+ * gimplify.c (simplify_call_expr): Clear TREE_SIDE_EFFECTS for
+ calls to "const" functions.
+
+ * tree-inline.c (expand_call_inline): Recalculate TREE_SIDE_EFFECTS
+ properly when inlining gimplified functions.
+
+ * fold-const.c (operand_equal_p): Handle CALL_EXPRs.
+
+ * tree-cfg.c (first_exec_block): Kill.
+ (make_edges): Use bb_for_stmt rather than first_exec_block.
+ (make_ctrl_stmt_edges, make_exit_edges): Likewise.
+ (make_loop_expr_edges, make_cond_expr_edges): Likewise.
+ (successor_block): Don't skip empty statements.
+
+ * tree-ssa.c (rewrite_and_optimize_stmt): Do not special case
+ CALL_EXPRs they're caught by the TREE_SIDE_EFFECTS test.
+
+ * tree-ssa.c (rewrite_and_optimize_stmt): Improve/correct setting of
+ may_optimize_p. Simplify later code knowing may_optimize_p is
+ correctly set.
+ (avail_expr_hash): Do not use iterative_hash_object or deal with
+ SSA names for real operands. Instead use iterative_hash_expr
+ which handles both.
+ (avail_expr_eq): Use operand_equal_p to test for equality.
+
+2003-06-11 Steven Bosscher <steven@gcc.gnu.org>
+
+ * tree-flow.h, tree-ssa-ccp.c, tree-ssa-copyprop.c,
+ tree-ssa-dce.c, tree-ssa-live.c, tree-ssa-live.h:
+ Convert function prototypes to ISO C.
+
+2003-06-10 Jeff Law <law@redhat.com>
+
+ * toplev.c (parse_options_and_default_flags): Fix typo in last change.
+
+ * gimplify.c (simplify_expr, case BIT_FIELD_REF): Make sure
+ to call recalculate_side_effects after gimplifying the
+ operands.
+
+2003-06-10 Diego Novillo <dnovillo@redhat.com>
+
+ * toplev.c (flag_tree_dom): New variable.
+ (f_options): Add new entry for -ftree-dominator-opts.
+ (parse_options_and_default_flags): Enable flag_tree_dom for
+ -O1 and higher. At -O2 and higher, disable flag_tree_dom is
+ SSA-PRE is also specified.
+ * flags.h (flag_tree_dom): Declare.
+ * doc/invoke.texi: Document -ftree-dominator-opts.
+ * tree-ssa.c (rewrite_block): Disable tracking of available
+ expressions when not doing dominator optimizations.
+ Call rewrite_stmt when not doing dominator optimizations.
+ Otherwise, call rewrite_and_optimize_stmt.
+ (rewrite_stmt): Don't optimize the statement. Just rename.
+ (rewrite_and_optimize_stmt): Optimize the statement while rewriting
+ its operands.
+ (lookup_avail_expr): Update comments.
+
+2003-06-10 Andrew Haley <aph@redhat.com>
+
+ * c-simplify.c (c_simplify_stmt): case ASM_STMT: Ensure qualifiers
+ come from input statement.
+
+2003-06-09 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-cfg.c (handle_switch_split): Update PHI nodes when splitting.
+ (tree_split_edge): Update PHI nodes in destination block.
+
+2003-06-09 Steven Bosscher <steven@gcc.gnu.org>
+
+ * basic-block.h, tree-dfa.c, tree-ssa.c, tree-cfg.c,
+ tree-flow.h: Convert function prototypes to ISO C.
+
+2003-06-09 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-cfg.c (bsi_commit_edge_inserts): Fix computation of
+ new_blocks.
+
+2003-06-08 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (handle_switch_split): Don't allocate basic block
+ annotations more than once.
+ (bsi_commit_first_edge_insert): Likewise.
+
+2003-06-07 Jeff Sturm <jsturm@one-point.com>
+
+ * tree-cfg.c (could_trap_p): New function.
+ (stmt_ends_bb_p): Handle flag_non_call_exceptions.
+ (make_exit_edges): Handle flag_non_call_exceptions.
+ (is_ctrl_altering_stmt): Handle flag_non_call_exceptions.
+ * tree-inline.c (walk_tree): Add case for CHAR_TYPE.
+ * tree-ssa-dce.c (stmt_useful_p): Keep all CATCH_EXPRs.
+
+2003-06-05 Jason Merrill <jason@redhat.com>
+
+ * stmt.c (asm_op_is_mem_input): New fn.
+ * tree.h: Declare it.
+ * gimplify.c (simplify_asm_expr): Call resolve_asm_operand_names.
+ Use is_simple_modify_expr_lhs for mem input ops.
+
+2003-06-05 Frank Ch. Eigler <fche@redhat.com>
+
+ * c-mudflap.c (mflang_register_call): Give the synthetic decl
+ undefined (not zero) size.
+
+2003-06-05 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mx_flag): Remove. Update callers to use mf_mark.
+ (TREE_MUDFLAPPED_P): Remove. Update callers to use mf_marked_p.
+ (mf_mark, mf_marked_p): Replacement functions to replace old node
+ marking based on tree flag-bits.
+ (mf_mostly_copy_tree_r): Preserve markedness across copies.
+ * tree-mudflap.h: Add new decls
+ * c-mudflap.c (mx_flag): Remove. Update callers to use mf_mark.
+
+2003-06-04 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (add_stmt_operand): Always consider non-scalar types
+ virtual operands.
+
+2003-06-04 Andrew MacLeod <amacleod@redhat.com>
+
+ * toplev.c (parse_options_and_default_flags): Turn tree_copyprop on by
+ default.
+ * tree-cfg.c (linearize_control_structures, linearize_cond_expr,
+ replace_stmt, merge_tree_blocks, remap_stmts): Fix PROTOS.
+ (find_insert_location): Add additional basic block parameter. Handle
+ switch stmts.
+ (handle_switch_split): New. Split edges to switch labels.
+ (bsi_commit_first_edge_insert): Add extra parameter to
+ find_insert_location call. Fix split block chaining in THEN & ELSE.
+ * tree-ssa-live.c (calculate_live_on_entry): Process all PHI def's
+ after all the arguments have been processed.
+ * tree-ssa.c (struct ssa_stats_d, struct loops *loops, var_is_live,
+ rewrite_into_ssa): Remove old UNSSA code.
+ (rewrite_block): Remove stmt is rewrite_stmt returns 1.
+ (assign_vars): Remove abort and enable overlapping live ranges.
+ (replace_variable): New. Replace SSA name with the partition variable.
+ (rewrite_out_of_ssa): Use replace_variable().
+ (dump_tree_ssa_stats): Remove old UNSSA code.
+ (rewrite_stmt): Return 1 if stmt should be deleted. Remove old
+ UNSSA code.
+
+2003-06-03 Diego Novillo <dnovillo@redhat.com>
+
+ * gimplify.c (simplify_call_expr): Move code to mark MD builtins
+ non-simplifiable...
+ * tree-simple.c (is_simple_call_expr): ... here.
+
+2003-06-03 Diego Novillo <dnovillo@redhat.com>
+
+ * c-parse.in: Fix botched merge.
+
+2003-06-03 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-mudflap.c (MARK_TREE_MUDFLAPPED, TREE_MUDFLAPPED):
+ Use TREE_VISITED instead of TREE_BOUNDED.
+ * c-mudflap.c (TREE_MUDFLAPPED): Likewise.
+ * tree-pretty-print.c (dump_generic_node): Remove
+ references to TYPE_QUAL_BOUNDED.
+
+2003-06-03 Jason Merrill <jason@redhat.com>
+
+ * gimplify.c (simplify_cond_expr): Call truthvalue_conversion
+ before invert_truthvalue.
+
+2003-06-02 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-dfa.c (compute_may_aliases): Call delete_alias_vars whenever we
+ call create_alias_vars.
+
+ * tree-alias-common (ptr_may_alias_var): Cleanup determination of
+ global vars and whatnot.
+
+2003-06-02 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree-ssa.o, tree-cfg.o): Add dependency on cfgloop.h
+ (tree-optimize.o): Remove dependency on cfgloop.h.
+ * basic-block.h (struct basic_block_def): Fix documentation for
+ field 'loop_father'.
+ * tree-dfa.c (add_referenced_var): Fix type of element
+ pushed into aliased_objects_alias_set.
+ * tree-optimize.c: Don't include cfgloop.h
+ (optimize_function_tree): Move code to initialize loop optimizer...
+ * tree-cfg.c (build_tree_cfg): ... here.
+ * tree-ssa.c: Include cfgloop.h.
+ (loops): New file local variable.
+ (rewrite_into_ssa): Initialize/finalize loop optimizer.
+ (rewrite_stmt): Call var_is_live when processing redundant
+ assignments to the same LHS.
+ (var_is_live): Add heuristic to discover overlapping definitions in
+ loops that do not have PHI nodes for VAR at the loop header.
+
+2003-06-02 Jason Merrill <jason@redhat.com>
+
+ * gimplify.c (simplify_expr): Only allow a cast from a 'val'.
+ * tree-simple.c (is_simple_cast): Likewise.
+
+2003-06-02 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-cfg.c (bsi_insert_before): Update end of block pointer if we
+ inserted before the last stmt in a block. (The container changed).
+ * tree-ssa.c (elim_backward): Inserting copy should be within
+ conditional check.
+ (elim_create): Only select one bit instead of the all.
+
+2003-06-01 Jason Merrill <jason@redhat.com>
+
+ * Makefile.in: Remove lots of -Wno-error targets.
+
+ * tree-simple.c (recalculate_side_effects): Check TREE_THIS_VOLATILE.
+
+ * gimplify.c (simplify_compound_lval): Call
+ recalculate_side_effects on each of the subexpressions.
+
+ * expr.c (expand_expr) <COND_EXPR>: Use the if-statement code if
+ it's void.
+
+2003-06-01 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-common.c: Remove setting of DECL_CONTEXT in temp vars,
+ it's done in create_tmp_alias_var for us.
+ (ptr_may_alias_var): Check if the variables are memory tags, and get
+ the associated pointers if they are.
+
+2003-05-30 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mudflap_c_function, enqueue_constant, enqueue_decl):
+ Rework dumping logic.
+
+2003-05-27 Jason Merrill <jason@redhat.com>
+
+ * tree-ssa.c (avail_expr_hash): Simplify by using iterative_hash_expr
+ in more places.
+ * tree.c (iterative_hash_expr): Handle SSA_NAME.
+
+2003-05-29 Jeff Law <law@redhat.com>
+
+ * tree-ssa.c (rewrite_stmt): Detect and remove redundant
+ memory loads.
+ (avail_expr_hash): Use iterative_hash_expr, not iterative_hash_object
+ as needed.
+
+2003-05-27 Jason Merrill <jason@redhat.com>
+
+ * gimplify.c (shortcut_cond_expr): Avoid jumps to jumps.
+
+2003-05-26 Jason Merrill <jason@redhat.com>
+
+ * c-simplify.c (simplify_switch_stmt): A SWITCH_EXPR also gets the
+ source location of its first line.
+
+2003-05-24 Diego Novillo <dnovillo@redhat.com>
+
+ Do not consider INDIRECT_REF nodes to be variables.
+
+ * gimplify.c (create_tmp_alias_var): Allow temporaries of
+ ARRAY_TYPE to be created.
+ Create new temporaries with function scope.
+ Don't call build_type_variant.
+ Mark the temporary volatile if its type is volatile.
+
+ * tree-dfa.c: Change every function that received a variable and
+ its base symbol to just receive the variable. Update all callers.
+ (struct alias_set_d): Remove field 'tag_sym'.
+ Add documentation for fields.
+ (struct walk_state): Add field 'is_indirect_ref'.
+ Add documentation for fields.
+ (opf_ignore_bp): Remove. Update all users.
+ (aliased_objects_base): Remove. Update all users.
+ (get_stmt_operands): If the statement had virtual operands, do not
+ scan them again.
+ (get_expr_operands): Handle INDIRECT_REF nodes by adding an operand
+ for the memory tag represented and a use for the base pointer.
+ Don't add VUSE operands for pointer arguments to functions.
+ Force a virtual operand when processing ADDR_EXPR nodes.
+ (add_stmt_operand): If the variable is an alias tag, always add it
+ as a virtual operand.
+ Remove code to handle INDIRECT_REF nodes.
+ Move code to determine if a pointer may point to global memory to
+ find_vars_r.
+ Set has_volatile_ops flag in the statement when adding operands for
+ globals and local statics.
+ If the variable is an alias tag, mark the statement as making
+ aliased loads or stores.
+ (set_def): Mark the variable as having real references.
+ (add_use): Likewise.
+ (add_vdef): Remove code to re-add previous virtual operands.
+ If PREV_VOPS is set, don't add a new virtual operand.
+ (add_vuse): Likewise.
+ (dump_variable): Show annotation bitfields 'mem_tag',
+ 'occurs_in_abnormal_phi', 'is_alias_tag' and 'is_stored'.
+ (compute_may_aliases): Initialize walk_state.is_indirect_ref to 0.
+ (compute_alias_sets): Don't remove alias sets with exactly one
+ entry.
+ (register_alias_set): Re-implement to support memory tags instead
+ of INDIRECT_REF nodes. Document algorithm.
+ (find_alias_for): Likewise.
+ (may_alias_p): Likewise.
+ (add_may_alias): Likewise.
+ (find_vars_r): If a pointer assignment is found and the RHS of the
+ assignment may access global memory, mark the pointer as pointing
+ to global memory.
+ Handle INDIRECT_REF nodes by marking the base pointer as
+ dereferenced.
+ Do not share INDIRECT_REF nodes.
+ (add_referenced_var): Don't handle INDIRECT_REF nodes.
+ If called from a store operation, mark the variable as stored.
+ By default mark the variable as not having real references.
+ When processing a pointer that has been dereferenced, create a
+ memory tag for the pointer.
+ (add_indirect_ref_var): Remove. Update all callers.
+ (get_virtual_var): Don't handle INDIRECT_REF nodes.
+ (find_hidden_use_vars_r):
+
+ * tree-flow-inline.h (get_var_ann): New function. Change all
+ functions that called var_ann and create_var_ann to call
+ get_var_ann.
+ (get_stmt_ann): Likewise.
+ (set_indirect_ref): Remove. Update all callers.
+ (indirect_ref): Remove. Update all callers.
+ (create_indirect_ref): Remove. Update all callers.
+
+ * tree-flow.h (struct var_ann_d): Remove fields 'is_loaded',
+ 'unused' and 'indirect_ref'.
+ Add fields 'mem_tag', 'is_mem_tag', 'is_alias_tag' and
+ 'has_real_refs'.
+ (get_var_ann, get_stmt_ann): Declare.
+ (create_indirect_ref, set_indirect_ref, indirect_ref): Remove.
+
+ * tree-pretty-print.c (dump_generic_node): Don't handle
+ INDIRECT_REF nodes inside SSA_NAME nodes.
+
+ * tree-simple.c (get_base_symbol): Don't handle INDIRECT_REF nodes.
+ (is_simple_unary_expr): Don't call STRIP_NOPS.
+
+ * tree-ssa-copyprop.c (get_original): Don't handle INDIRECT_REF
+ nodes. Allow pointers to be copy propagated.
+
+ * tree-ssa-dce.c (need_to_preserve_store): Don't handle
+ INDIRECT_REF nodes.
+
+ * tree-ssa-live.c (create_ssa_var_map): Only process variables that
+ have real references.
+
+ * tree-ssa.c: Update documentation regarding INDIRECT_REF nodes.
+ (update_indirect_ref_vuses): Remove. Update all users.
+ (update_pointer_vuses): Remove. Update all users.
+ (MAY_COPYPROP_P): Remove. Update all users.
+ (create_temp): Don't handle INDIRECT_REF nodes.
+ (coalesce_ssa_name): Ignore variables that have no real references.
+ (rewrite_stmt): Mark the statement modified if a new copy or
+ constant was propagated into it.
+ Don't special-case pointers.
+ (rewrite_operand): Don't handle INDIRECT_REF nodes.
+ * tree.h (SSA_VAR_P): Remove. Update all users.
+ (SSA_DECL_P): Rename to SSA_VAR_P.
+
+2003-05-22 Jeff Law <law@redhat.com>
+
+ * gimplify.c (simplify_expr): Avoid gimplifying expressions which
+ are already in gimple form.
+ * tree-simple.c (is_simple_constructor): No longer treat TREE_STATIC
+ constructors specially.
+ (is_simple_addr_expr_arg): If we're taking the address of a label
+ for the first time, then the ADDR_EXPR is not in gimple form.
+
+2003-05-22 Jason Merrill <jason@redhat.com>
+
+ * tree-cfg.c (compute_reachable_eh): Don't skip cleanups.
+
+ * tree-dfa.c (add_referenced_var): Read-only INDIRECT_REFs can
+ also be clobbered by function calls.
+
+2003-05-22 Jeff Law <law@redhat.com>
+
+ * expr.c (convert_move): Avoid making silly copies.
+ (expand_expr, case BIND_EXPR): Correctly determine when the
+ result of the BIND_EXPR will not be used.
+
+2003-05-21 Jason Merrill <jason@redhat.com>
+
+ * tree-cfg.c (compute_reachable_eh): Handle multiple CATCH_EXPRs.
+
+ * builtins.c (simplify_builtin_next_arg): Split out from...
+ (expand_builtin_next_arg): ...here.
+ (simplify_builtin_va_start): Split out from...
+ (expand_builtin_va_start): ...here.
+ (simplify_builtin): Call it.
+ * gimplify.c (simplify_call_expr): If simplify_builtin worked,
+ just return.
+
+2003-05-20 Jason Merrill <jason@redhat.com>
+
+ * gimplify.c (shortcut_cond_expr, shortcut_cond_r): Rewrite.
+ (simplify_cond_expr): Also invert ifs with no 'then'.
+ (build_and_jump): New fn, split out from...
+ (gimplify_exit_expr): ...here. Don't bother gimplifying the
+ condition.
+
+ * gimplify.c (simplify_save_expr): Add post-effects to the
+ postqueue.
+
+ * gimplify.c (mostly_copy_tree_r): Don't unshare constants.
+
+2003-05-20 Jeff Law <law@redhat.com>
+
+ * expr.c (expand_expr, case COND_EXPR): Avoid useless RTL generation
+ when the THEN or ELSE arm is empty.
+
+ * tree-cfg.c (make_loop_expr_blocks): Do not accept next_block_link
+ as an argument, make it a local variable. Callers changed.
+
+ * tree-cfg.c (remove_useless_stmts_and_empty_vars): Eliminate
+ GOTO_EXPRs which jump to the next statement occuring in an
+ outer control/block structure nest.
+
+2003-05-20 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa-ccp.c (set_rhs): Fix typo in handling of
+ RETURN_EXPR nodes.
+
+2003-05-19 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-common.c (alias_get_name): Handle unnamed variables once
+ and for all.
+
+2003-05-19 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dce.c (remove_conditional): If the conditional's block
+ has no post dominator in the CFG, then wire it to the exit node.
+ Avoid unnecessary check of bb->succ.
+
+2003-05-17 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-pretty-print.c (MASK_POINTER): Parameter is P, not node.
+
+2003-05-17 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-common.c (get_alias_var): Handle REFERENCE_EXPR.
+ (find_func_aliases): Ditto.
+ (get_alias_var): Use POINTER_TYPE_P.
+
+2003-05-16 Frank Ch. Eigler <fche@redhat.com>
+
+ * gcc.c (cc1_options): Correct "-fmudflapth" handling.
+ * tree-mudflap.c (mudflap_c_function, mf_build_check_statement_for):
+ Use locally cached mask/shift values only in single-threaded mode.
+
+2003-05-16 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-common.c (ptr_may_alias_var): Fix DECL_CONTEXT
+ checking.
+
+2003-05-16 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-flow.h (ssa_make_edge): Remove prototype.
+ * tree-ssa-dce.c (remove_dead_stmt): Change comment about removing
+ conditionals.
+ (remove_conditional): Don't update PHI nodes or call ssa_make_edge.
+ * tree-ssa.c (ssa_make_edge): Remove.
+
+2003-05-16 Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (remove_useless_stmts_and_vars): Handle case where
+ both arms of an if-then-else simply jump to the same location.
+
+ * tree-ssa-ccp.c (get_rhs): Correctly handle MODIFY_EXPR embedded in
+ a RETURN_EXPR.
+ (set_rhs): Likewise.
+
+2003-05-15 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * Makefile.in (regmove.o-warn): Change to -Wno-error.
+
+2003-05-15 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-cfg.c (enum find_location_action): Enum for find_insert_location.
+ (bsi_insert_before): Handle insert at start of a BB and update pointers
+ from parents if appropriate.
+ (find_insert_location): Handle COND_EXPR properly. Return
+ an enum type indicating what action to take on the returned value.
+ (bsi_commit_first_edge_insert): Use new returned action.
+
+2003-05-15 Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (make_edges): Factor out loop invariants from
+ code to insert edges from the TRY to the FINALLY block.
+ Avoid creating unnecessary edges from the end of the
+ FINALLY block back to the start of the FINALLY block.
+
+2003-05-15 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa.c (rewrite_out_of_ssa): Undo previous patch.
+
+2003-05-15 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa.c (rewrite_out_of_ssa): Don't dump the optimized
+ function after the SSA->normal pass.
+
+2003-05-14 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * Makefile.in: Add additional -Wno-error targets for Alpha.
+
+2003-05-13 Jason Merrill <jason@redhat.com>
+
+ * gdbinit.in (pgs, pge): New macros.
+
+ Implement expression temporary optimization.
+ * gimplify.c (gimplify_ctx): Add temp_htab field.
+ (push_gimplify_context): Initialize it.
+ (pop_gimplify_context): Destroy it.
+ (simplify_expr): If there's no internal postqueue, generate an
+ expression temporary.
+ (gimple_tree_hash, gimple_tree_eq): New fns.
+ (create_tmp_from_val, lookup_tmp_var): New fns.
+ (get_formal_tmp_var): New fn.
+ (internal_get_tmp_var): New fn.
+ (get_initialized_tmp_var): Use it.
+ * tree-simple.h: Declare it.
+
+ * gimplify.c (simplify_cond_expr): Reorganize.
+ (shortcut_cond_expr, shortcut_cond_r): New fns.
+ (build_and_jump): New fn.
+ (gimplify_exit_expr): Use it.
+
+ * gimplify.c (simplify_expr): Do better at stripping unnecessary
+ NOPs. Tidy GOTO_EXPR handling. Don't allow NON_LVALUE_EXPR.
+ * tree-simple.c (is_simple_modify_expr): Don't allow NON_LVALUE_EXPR.
+ (is_simple_binary_expr, is_simple_condexpr): Likewise.
+ (is_simple_unary_expr, is_simple_compound_lval): Likewise.
+ (is_simple_id): Likewise.
+
+ * tree-ssa.c (rewrite_stmt): Discard redundant assignments.
+ (avail_expr_eq): Don't test ops1 == ops2.
+ (avail_expr_hash): Use iterative_hash_object.
+
+2003-05-13 Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (cleanup_tree_cfg): Update comments. Set repeat
+ anytime we remove a control structure.
+
+ * tree-flow.h (struct var_ann_d): New field occurs_in_abnormal_phi.
+ * tree-ssa.c (MAY_COPYPROP_P): Do not allow copy propagations
+ if either argument occurs in an abnormal phi.
+ * tree-dfa.c (add_phi_arg): Set occurs_in_abrnomal_phi as needed.
+ * tree-ssa-copyprop.c (copyprop_stmt): Do not allow copy
+ propagations if either argument occurs in an abnormal phi.
+ (copyprop_phi): Likewise.
+
+2003-05-12 Diego Novillo <dnovillo@redhat.com>
+
+ * c-common.h (STATEMENT_CODE_P): Use size_t cast instead
+ of int.
+ (INIT_STATEMENT_CODES): Change type of local variable i to
+ size_t.
+
+2003-05-12 Diego Novillo <dnovillo@redhat.com>
+
+ * c-pretty-print.c (dump_c_node): Call CONSTRUCTOR_ELTS
+ to access the operand of a CONSTRUCTOR node.
+ * tree-pretty-print.c (dump_generic_node): Likewise.
+
+2003-05-11 Diego Novillo <dnovillo@redhat.com>
+
+ * c-simplify.c (simplify_if_stmt): Replace calls to
+ warning_with_file_and_line with warning.
+
+2003-05-12 Frank Ch. Eigler <fche@redhat.com>
+
+ * toplev.c (lang_independent_options): Add "-fmudflapth".
+ * flags.h (flag_mudflap): Document meaning of >1 value.
+ * gcc.c (MFWRAP_SPEC, MFLIB_SPEC): Add -fmudflapth support.
+ (cpp_unique_options, cc1_options): Ditto.
+
+2003-05-10 Sebastian Pop <s.pop@laposte.net>
+
+ * gimplify.c (simplify_expr): Replace CONST_DECL with its DECL_INITIAL.
+
+2003-05-09 Sebastian Pop <s.pop@laposte.net>
+
+ * tree-optimize.c (optimize_function_tree): Clarify the use of the
+ loop analyzer.
+
+2003-05-09 Jeff Law <law@redhat.com>
+
+ * c-simplify.c (simplify_cleanup): Remove code which optimizes
+ TRY_FINALLY and TRY_CATCH. It doesn't trigger.
+
+ * tree-cfg.c (remove_useless_stmts_and_vars): Optimize away
+ TRY_CATCH and TRY_FINALLY blocks when possible.
+
+2003-05-09 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-pretty-print.c (dump_generic_node): CONSTRUCTOR
+ nodes have only one operand now.
+
+2003-05-08 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-cfg.c (pdom_info): New file level static.
+ (cleanup_tree_cfg): Free dominance info, if it was used.
+ (bsi_replace): New. Replace a stmt with a new one.
+ (linearize_cond_expr): Use post dominator info to determine is a
+ conditional can be safely removed.
+ (find_insert_location): New. Determine where to insert a new stmt that
+ is placed on a split edge.
+ (bsi_commit_first_edge_insert): Use find_insert_location to determine
+ where to link a stmt when splitting an edge.
+ (merge_tree_blocks): When deleting a basic block, remove it from the
+ dominance structure if it exists.
+ * tree-dfa.c (add_stmt_operand): Don't rename local statics. Treat
+ them just like globals.
+ * tree-flow.h (struct var_ann_d): Add root_var_processed bit and
+ root_index fields.
+ * tree-ssa-dce.c (process_worklist): Mark conditions feeding PHI's as
+ necessary as well.
+ (remove_dead_phis): Add missing debug information.
+ * tree-ssa-live.c (var_union): Handle combining partitions when one
+ has a root_variable as a representative.
+ (compact_var_map): Add comments and use flags.
+ (init_root_var): Use new root_var fields in struct var_ann_d.
+ (dump_root_var): Send output to specified file, not stderr.
+ (dump_var_map): Remove dump_flag parameter & some grotesque debug info.
+ * tree-ssa-live.h (VAR_ANN_ROOT_INDEX): Define.
+ (VARMAP_NORMAL, VARMAP_NO_SINGLE_DEFS): Define flags for compact_var_map.
+ (var_to_partition_to_var): Return NULL if not in a partition.
+ (find_root_var): Use VAR_ANN_ROOT_INDEX.
+ * tree-ssa.c (insert_copy_on_edge): Add listing info.
+ (coalesce_ssa_name): Coalesce live-on-entry variables to their root.
+ Coalesce partitions across abnormal edges.
+ (assign_vars): Remove redundant initialization code. Handle root_vars
+ which have already been coalesced to a partition.
+ (rewrite_out_of_ssa): Add debug info & remove PHI nodes when processed.
+ (rewrite_stmt): Don't redefine redundant expressions.
+
+2003-05-08 Jeff Law <law@redhat.com>
+
+ * c-simplify.c (simplify_expr_stmt): Make sure to
+ simplify the body of the EXPR_STMT.
+
+ * tree-dfa.c (remove_decl): Accept new argument for the block
+ to start the search.
+ * tree-flow.h (remove_decl): Update prototype.
+ * tree-cfg.c (remove_stmt): Pass the toplevel block to
+ remove_decl.
+
+ * tree-dfa.c (find_hidden_use_vars): No longer returns a value.
+ Callers and prototype updated. No longer need to look for
+ nested functions, instead just mark any variables and
+ parameters with DECL_NONLOCAL set as having hidden uses.
+
+2003-05-08 Diego Novillo <dnovillo@redhat.com>
+
+ * version.c (version_string): Change format to show daily
+ datestamp and merged date.
+
+2003-05-07 Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (remove_useless_stmts_and_vars): Do not remove
+ the toplevel BIND_EXPR for an inlined function.
+
+ * tree-dfa.c (find_hidden_use_vars): Look at the size of
+ VAR_DECLs, not the size of ARRAY_TYPES. Also make sure
+ to reset *inside_vla to its original value when done
+ processing any particular VAR_DECL.
+
+2003-05-06 Diego Novillo <dnovillo@redhat.com>
+
+ * c-simplify.c (simplify_if_stmt): Warn if
+ -Wunreachable-code is given and the conditional is always
+ true or always false.
+
+ * expr.c (expand_expr): Don't try to expand FUNCTION_DECL
+ nodes when processing BIND_EXPR_VARS.
+
+ * varasm.c (output_constant_def_contents): Re-use the
+ label when emitting a label for mudflap.
+
+ Disable the following patch:
+
+ 2003-04-30 Steven Bosscher <steven@gcc.gnu.org>
+
+ * ggc-page.c (TREE_EXP_SIZE): Define.
+ (extra_order_size_table): New entry for expr trees with
+ two operands.
+
+2003-05-06 Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (make_exit_edges): Fix handling of blocks which
+ end with calls.
+
+ * tree-cfg.c (remove_useless_stmts_and_vars): Remove GOTO_EXPRs
+ to the immediately following tree node.
+
+ * tree-cfg.c (make_goto_expr_edges): Fix typo in comment.
+ (remove_useless_stmts_and_vars): New function.
+ * tree-flow.h (remove_useless_stmts_and_vars): Prototype.
+ * tree-ssa.c (rewrite_out_of_ssa): After returning to normal
+ form, call remove_useless_stmts_and_vars.
+
+2003-05-02 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-common.c (alias_get_name): Given unnamed result decls
+ a name.
+ (create_fun_alias_var): Use DECL_RESULT if available.
+
+2003-05-02 Jeff Law <law@redhat.com>
+
+ * tree-inline.c (expand_call_inline): Avoid creating naked
+ _DECL nodes for inlined functions which had NRV optimizations
+ applied.
+
+2003-05-02 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (build_tree_cfg): Update comment.
+ (make_blocks): Don't skip over empty statements.
+ Move exception handling code ...
+ (compute_reachable_eh): ... here.
+ (set_parent_stmt): Don't skip over empty statements.
+ (bsi_remove): Don't return early on empty statements.
+ Don't call STRIP_NOPS.
+ (remove_stmt): Don't call STRIP_NOPS.
+ Always compute the block holding the statement.
+ After replacing the statement with an empty statement, add the
+ empty statement to the block.
+ (successor_block): Don't call STRIP_NOPS.
+ (first_exec_stmt): Likewise.
+ (first_exec_block): Don't return early for empty statements.
+ (first_stmt): Don't test for NULL blocks.
+ Reformat to improve legibility.
+ (bsi_next_in_bb): Don't call STRIP_NOPS.
+ Reformat to improve legibility.
+ (set_bb_for_stmt): Don't ignore empty statements.
+
+ * tree-dfa.c (get_stmt_operands): Don't call STRIP_NOPS.
+ (create_stmt_ann): Don't abort on emtpy statements.
+ Don't call STRIP_NOPS.
+ (copy_stmt): Remove unused function.
+ * tree-flow.h (copy_stmt): Remove prototype.
+
+ * tree-flow-inline.h: Don't call STRIP_NOPS.
+ Remove local variable 't'.
+ (bsi_stmt): Don't return NULL_TREE for empty statements.
+ Ignore error_mark_node.
+
+ * tree-iterator.h (tsi_next): Don't call STRIP_NOPS.
+ (tsi_stmt_ptr): Likewise.
+ (tsi_stmt): Likewise.
+ Don't return NULL_TREE for empty statements.
+
+ * tree-pretty-print.c (dump_generic_node): Don't ignore empty
+ statements.
+
+ * tree-ssa-ccp.c (fold_stmt): Don't call STRIP_NOPS.
+ * tree-ssa-dce.c (find_useful_stmts): Likewise.
+ (remove_dead_stmt): Likewise.
+ * tree-ssa.c (mark_def_sites): Likewise.
+ (rewrite_out_of_ssa): Likewise.
+ (rewrite_stmt): Likewise.
+
+ * tree.c (make_ssa_name): Don't ignore empty statements.
+ (body_is_empty): Fix comment.
+
+2003-05-01 Jeff Law <law@redhat.com>
+
+ * tree-dfa.c (find_hidden_use_vars): Renamed from find_vla_decls.
+ Now returns a value indicating if nested function was found.
+ When nested functions are found, mark suitable variables as
+ having hidden uses.
+ (find_hidden_use_vars_r): Renamed from find_vla_decls_r.
+ (compute_may_alias): Corresponding changes. Handle
+ multiple BLOCKs at the toplevel of a function.
+
+2003-04-30 Diego Novillo <dnovillo@redhat.com>
+
+ * tree.c (build_empty_stmt): New function.
+ * tree.h (IS_EMPTY_STMT): Define.
+ (TI_EMPTY_STMT): Remove.
+ (empty_stmt_node): Remove.
+ Replace 'X = empty_stmt_node' with 'X = build_empty_stmt ()',
+ and 'X == empty_stmt_node' with 'IS_EMPTY_STMT (X)' everywhere.
+ (build_empty_stmt): Declare.
+
+ * cp/cp-simplify.c (cp_simplify_stmt): Use IS_EMPTY_STMT.
+
+ * java/java-tree.h (build_java_empty_stmt): Declare.
+ * java/expr.c (build_java_empty_stmt): New function.
+ * java/decl.c (java_init_decl_processing): Don't build empty_stmt_node.
+ Replace 'X = empty_stmt_node' with 'X = build_java_empty_stmt ()',
+ and 'X == empty_stmt_node' with 'IS_EMPTY_STMT (X)' everwhere.
+
+2003-04-30 Jeff Law <law@redhat.com>
+
+ * tree-dfa.c (get_expr_operands): Do not ignore operands of an
+ an ADDR_EXPR if it is a PARM_DECL or VAR_DECL.
+
+ * tree-dfa.c (get_expr_operands): Look inside operands in
+ a TREE_LIST.
+
+2003-04-29 Diego Novillo <dnovillo@redhat.com>
+
+ * builtins.def (BUILTIN_CONSTANT_P): Mark as constant.
+
+ * tree-dfa.c (get_expr_operands): Do not add VDEF operands for
+ dereferenced pointers at call sites.
+ * tree-ssa.c (assign_vars): Abort if we couldn't coalesce all the
+ versions together.
+
+2003-04-29 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-cfg.c (bsi_start): If there are no stmts in a block, use the
+ context pointer to represent the basic block.
+ (bsi_insert_after): Handle inserting into empty blocks better.
+ (bsi_insert_before): Call bsi_insert_after to handle empty blocks.
+ * tree-ssa.c (elim_create): Clear bitmap after its been processed
+ instead of during loop.
+
+2003-04-27 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree-mudflap.o): Add dependency on $(TREE_DUMP_H).
+ * c-decl.c (c_expand_body_1): Don't call simplify_function_tree
+ after mudflap_c_function.
+ Move mudflap instrumentation after SSA optimizers.
+ * tree-dump.c (dump_files): Add entry for -fdump-tree-mudflap.
+ * tree.h (enum tree_dump_index): Add TDI_mudflap.
+ * doc/invoke.texi: Document -fdump-tree-mudflap.
+ * tree-mudflap.c: Include tree-dump.h.
+ (dump_file): New local variable.
+ (dump_flags): New local variable.
+ (mudflap_c_function): Call dump_begin, dump_end and dump_function.
+ (mf_decl_cache_locals): Set DECL_CONTEXT for __mf_lookup_shift_l
+ and __mf_lookup_mask_l to current_function_decl.
+ (mf_offset_expr_of_array_ref): Likewise for __mf_index_X.
+ (mf_build_check_statement_for): Re-implement to emit a proper
+ STMT_EXPR.
+ (mx_xfn_indirect_ref): Emit detailed debugging info if
+ -fdump-tree-mudflap-details is given.
+ (mudflap_enqueue_decl): Likewise
+ * tree-optimize.c (optimize_function_tree): Don't check for
+ -fmudflap.
+
+2003-04-26 Diego Novillo <dnovillo@redhat.com>
+
+ * c-simplify.c (build_bc_goto): If the target label couldn't be
+ found, emit an error message.
+
+2003-04-25 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-ssa-live.c (compact_var_map): Add parameter to exclude variables
+ with a single SSA version.
+ (init_root_var): Allow that a var_map might not be compacted yet.
+ * tree-ssa-live.h (compact_var_map): Change Prototype.
+ * tree-ssa.c (rewrite_out_of_ssa): When coalescing, don't include single
+ reference variables during the compaction.
+
+2003-04-25 Jeff Law <law@redhat.com>
+
+ * tree-optimize.c (optimize_function_tree): Simplify slightly.
+
+2003-04-25 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-ssa.c (struct _elim_graph): Change type of fields
+ 'pred' and 'succ' to be bitmaps instead of sbitmaps.
+ Update all uses.
+
+2003-04-25 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (linearize_cond_expr): Reformat.
+ * tree-dfa.c (get_expr_operands): Check for read-only
+ status the dereferenced argument pointer, not the pointer
+ itself.
+ (add_stmt_operand): Always consider global variables as
+ virtual operands.
+
+2003-04-24 Jason Merrill <jason@redhat.com>
+
+ * gimplify.c (simplify_cond_expr): Avoid redundant gimplification.
+
+ Add TREE_VEC of case labels to the SWITCH_EXPR during gimplification.
+ * tree.def (CASE_LABEL_EXPR): Add an operand for the LABEL_DECL.
+ * tree.h (SWITCH_LABELS, CASE_LABEL): New macros.
+ * c-simplify.c (c_simplify_stmt) <CASE_LABEL>: Create LABEL_DECL here.
+ * expr.c (expand_expr) <CASE_LABEL_EXPR>: Not here.
+ * gimplify.c (gimplify_ctx): Add case_labels field.
+ (gimplify_switch_expr, gimple_add_case_label): New fns.
+ (simplify_expr): Use them.
+
+2003-04-24 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-flow.h (processed_out_of_ssa): Rename to out_of_ssa_tag.
+ * tree-ssa-live.c (register_ssa_partition): Add variable to partition.
+ (change_partition_var): Use out_of_ssa_tag.
+ (create_ssa_var_map): Add all uses, defs and PHI elements to partition.
+ (new_tree_live_info): Create a live range info structure.
+ (delete_tree_live_info): Free storage.
+ (live_worklist): Fill in the live range info for a variable for the
+ blocks between the def and all the blocks containing uses.
+ (set_if_valid): Set partition bit if variable is in a partition.
+ (add_livein_if_notdef): Set live on entry bit for a var's partition
+ if a definition has not been seen.
+ (calculate_live_on_entry): Create partition live on entry bitmaps for
+ all basic blocks .
+ (calculate_live_on_exit): Calculate live on exit information for each
+ basic block.
+ (init_root_var): Initialize and fill in a root_var structure.
+ (remove_root_var_partition): remove a partition from a root_var list.
+ (delete_root_var): Free storage.
+ (dump_root_var): Display root_var summary.
+ (dump_var_map): Show extra info for ssa name versions.
+ * tree-ssa-live.h (NO_PARTITION): Define.
+ (register_ssa_partition): Remove.
+ (partition_to_var): Use partition_find after decompressing.
+ (var_to_partition): Return NO_PARTITION if var is not in a partition.
+ (struct tree_live_info_d): Define live range info structure.
+ (partition_is_global): Return 1 if used outside a basic block.
+ (live_entry_blocks): Return bitmap over blocks that partition is live
+ on entry to.
+ (live_on_exit): Return bitmap of partitions live on exit from a block.
+ (struct root_var_d): Define a root_var structure.
+ (ROOT_VAR_NONE): Define.
+ (num_root_vars): Number of variables in root_var object.
+ (root_var): Return variable for a root_var index.
+ (first_root_var_partition): Return first partition for a root_var.
+ (next_root_var_partition): Get next partition for a root_var.
+ (find_root_var): Find root_var index for a specific partition.
+ * tree-ssa.c (eliminate_extraneous_phis): Remove.
+ (set_if_valid): Set partition bit if variable is in a partition.
+ (add_conflicts_if_valid): Add conflict between variable and all
+ related partitions set in a bitvector.
+ (coalesce_ssa_name): Create a conflict graph and coalesce all
+ partitions which don't conflict and are related by the same root_var.
+ (assign_vars): Use a root_var object, and assign different real
+ variables to all partitions.
+ (rewrite_out_of_ssa): Call compact_var_map() once, and don't call
+ eliminate_extraneous_phis.
+
+2003-04-23 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-flow.h (create_global_var): Add prototype.
+
+ * tree-dfa.c (create_global_var): Externalize.
+
+ * tree-alias-common.c: Set DECL_CONTEXT on our temp alias vars.
+ (call_may_clobber): Make a copy of this function, since our version
+ will be slightly different soon.
+ (create_alias_vars): We need global_var, so create it if necessary.
+
+2003-04-23 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (do_proper_save): Remove old code, since the new
+ insertion code works okay.
+ (pre_expression): Use new_rename_1, it removes a *lot* of useless
+ saves.
+
+2003-04-23 Jeff Law <law@redhat.com>
+
+ * gimplify.c (simplify_target_expr): Make sure to simplify
+ the cleanup too.
+
+ * tree-ssa.c (struct def_blocks_d): Add new field phi_insertion_points.
+ (compute_global_livein): Accept varray rather than bitmaps. Callers
+ updated. Rewrite to compute global life information for all the
+ objects in the varray in parallel.
+ (insert_phis_for_deferred_variables): New function.
+ (insert_phi_nodes_for): New argument DEF_MAPs. When an object
+ crosses the threshold for using fully pruned PHI insertions,
+ push it on the def_maps varray for deferred processing.
+ (insert_phi_nodes): Initialize def_maps. Pass it to
+ insert_phi_nodes_for. Drain the def_maps varray as it grows.
+ Also drain any residual objects in def_maps. Zero def_maps
+ when complete.
+
+2003-04-21 Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (find_contained_blocks_and_edge_targets): New function.
+ (try_finallys): New varray used during edge creation.
+ (make_edges): Initialize try_finallys varray. After creating
+ all the "normal" edges, go back and create the special edges
+ for the try-finally blocks.
+ (make_ctrl_stmt_edges): Create edges for the EH nodes. Also
+ make sure to build the try-finally stack.
+ (make_exit_edges): Create edges from calls which may throw
+ to any directly reachable exception handlers.
+ (is_ctrl_altering_stmt): Statements which may throw alter
+ flow control.
+
+ * tree-cfg.c: Include except.h.
+ (eh_stack): New file-scoped varray.
+ (build_tree_cfg): Initialize eh_stack.
+ (make_catch_expr_blocks): New function.
+ (make_try_expr_blocks, make_eh_filter_expr_blocks): Likewise.
+ (make_blocks): Call new functions as needed. When ending a block
+ due to a statement that may throw, compute the reachable exception
+ handlers and store it in the statement's annotation.
+ (is_ctrl_stmt): Handle EH nodes.
+ (stmt_ends_bb_p): Likewise.
+ * tree-flow.h (stmt_ann_d): Add new field reachable_exception_handlers.
+
+ * except.c (check_handled): No longer static.
+ * except.h (check_handled): Prototype.
+
+ * c-simplify.c (c_build_bind_expr): Revert change from earlier today.
+
+ * c-common.h (find_reachable_label): Prototype.
+ * c-semantics.c (find_reachable_label): No longer static.
+ * c-simplify.c (c_build_bind_expr): Avoid creating unnecessary
+ BIND_EXPRs.
+ (simplify_cleanup): Avoid creating unnecessary TRY_CATCH_EXPRs
+ or TRY_FINALLY_EXPRs.
+ (simplify_if_stmt): If the condition is constant and the
+ unexecuted arm has no reachable code, then just emit
+ the executed arm.
+
+2003-04-18 Sebastian Pop <s.pop@laposte.net>
+
+ * cfghooks.h, cfghooks.c: New files.
+ * Makefile.in (BASIC_BLOCK_H): Depends on cfghooks.h.
+ (OBJS): Add cfghooks.o.
+ (tree-optimize.o): Depends on cfgloop.h.
+ (cfghooks.o): New rule.
+ * basic-block.h (split_edge): Rename to rtl_split_edge.
+ (tree_split_edge): Declare.
+ (create_bb): Declare extern here.
+ (verify_flow_info): Rename to rtl_verify_flow_info.
+ (tree_verify_flow_info): Declare.
+ (cfghooks.h): Included here.
+ * cfgloop.c (tree.h, tree-flow.h): Included.
+ (make_forwarder_block): Renamed to rtl_make_forwarder_block.
+ (tree_make_forwarder_block): New static function.
+ (blocks_headers): Declared static.
+ (HEADER_BLOCK): Use blocks_headers instead of bb's .aux field.
+ (redirect_edge_with_latch_update, make_forwarder_block,
+ canonicalize_loop_headers): Don't allocate .aux, but makes grow
+ the blocks_headers array.
+ (canonicalize_loop_headers): Register tree_make_forwarder_block
+ into the tree_cfg_hooks and rtl_make_forwarder_block into the
+ rtl_cfg_hooks structure.
+ (canonicalize_loop_headers): Initialize/free the blocks_headers
+ array rather than the bb's .aux field.
+ * cfgloopmanip.c (loop_split_edge_with_NULL): New static function.
+ (remove_path, force_single_succ_latches):
+ Call loop_split_edge_with_NULL instead of loop_split_edge_with.
+ * cfgrtl.c (split_block): Update the comment.
+ (split_edge): Renamed rtl_split_edge.
+ (verify_flow_info): Renamed rtl_verify_flow_info.
+ * loop-init.c (loop_optimizer_init, loop_optimizer_finalize):
+ Execute code following the value of cfg_level.
+ * toplev.c (rest_of_compilation): Call rtl_register_cfg_hooks.
+ * tree-cfg.c (create_bb): Declared extern.
+ (build_tree_cfg): Call tree_register_cfg_hooks.
+ (make_edges, make_exit_edges): Remove the use of EDGE_FALLTHRU.
+ (bsi_commit_first_edge_insert): Use split_edge.
+ (tree_split_edge, tree_verify_flow_info): New functions.
+ * tree-optimize.c (cfgloop.h): Included.
+ (optimize_function_tree): Add #if 0'ed calls to
+ loop_optimizer_init and loop_optimizer_finalize.
+
+2003-04-16 Jeff Law <law@redhat.com>
+
+ * Makefile.in (tree-ssa.o): Depend on langhooks.h.
+ (tree-dfa.o, tree-cfg.o): Likewise.
+ * tree-cfg.c: Include langhooks.h
+ (dump_tree_cfg): Revamp how we get the current function's name
+ to not rely on current_function_name (and implicitly cfun).
+ (dump_cfg_stats, tree_cfg2dot): Likewise.
+ * tree-dfa.c: Include langhooks.h
+ (dump_immediate_uses): Revamp how we get the current function's name
+ to not rely on current_function_name (and implicitly cfun).
+ (dump_dfa_stats, dump_alias_info): Likewise.
+ * tree-ssa.c: Include langhooks.h
+ (dump_tree_ssa): Revamp how we get the current function's name
+ to not rely on current_function_name (and implicitly cfun).
+
+ * tree-cfg.c (make_loop_expr_blocks): When determining the value for
+ NEXT_BLOCK_LINK, correctly handle empty statement nodes at the
+ end of the tree.
+ (make_cond_expr_blocks, make_switch_expr_blocks): Likewise.
+ (make_bind_expr_blocks): Likewise.
+
+ * gimplify.c (keep_function_tree_in_gimple_form): Move check of
+ flag_disable_simple here. Include flags.h.
+ * Makefile.in (gimplify.o): Depends on flags.h
+ * c-decl.c (c_expand_body_1): No longer check flag_disable_simple.
+ * tree-inline.c (copy_body_r): Avoid creating non-gimple code
+ when inlining a function where the RESULT_DECL's initialization
+ is not on the RETURN_EXPR.
+
+2003-04-15 Jeff Law <law@redhat.com>
+
+ * tree-flow.h (struct var_ann_d): Renamed is_vla_decl field to
+ has_hidden_use.
+ (has_hidden_use, set_has_hidden_use): Renamed from is_vla_decl
+ and set_vla_decl.
+ * tree-flow-inline.h (has_hidden_use): Renamed from is_vla_decl.
+ Updated to use "has_hidden_use" instead of "is_vla_decl" field.
+ (set_has_hidden_use): Renamed from set_vla_decl.
+ Updated to use "has_hidden_use" instead of "is_vla_decl" field.
+ * tree-dfa.c (dump_variable): Corresponding changes.
+ (find_vla_decls_r): Likewise.
+ * c-simplify.c (simplify_decl_stmt): Likewise.
+ * tree-ssa-dce.c: Likewise.
+
+2003-04-09 Jeff Law <law@redhat.com>
+
+ * tree-dfa.c (struct alias_set_d, field tag_sym_set): Remove
+ unused field.
+ (register_alias_set): Rework to avoid incorrect coalescing of
+ entries. Fix memory leak. No longer set field tag_sym_set.
+ (get_expr_operands): ADDR_EXPR expressions may have interesting
+ operands in some cases.
+
+2003-04-09 Diego Novillo <dnovillo@redhat.com>
+
+ * gimplify.c (simplify_expr): Handle VECTOR_CST nodes.
+ * tree-cfg.c (make_blocks): Ignore empty statement containers.
+ Create a basic block before processing containers that only have
+ empty statements.
+ (make_loop_expr_blocks): Use the container instead of the statement
+ when setting NEXT_BLOCK_LINK.
+ (make_cond_expr_blocks): Likewise.
+ (make_switch_expr_blocks): Likewise.
+ (make_bind_expr_blocks): Likewise.
+ (successor_block): If the last statement of the block is the empty
+ statement, use its container to get NEXT_BLOCK_LINK.
+ (stmt_starts_bb_p): Return false if the statement is NULL.
+ * tree-pretty-print.c (dump_generic_node): Handle VECTOR_CST nodes.
+ * tree-simple.c (is_simple_const): Accept VECTOR_CST as constants.
+ * objc/objc-lang.c (LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P):
+ Define.
+
+2003-04-06 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (remove_bb): Call ssa_remove_edge.
+ (cleanup_cond_expr_graph): Likewise.
+ (cleanup_switch_expr_graph): Likewise.
+ (disconnect_unreachable_case_labels): Likewise.
+ (merge_tree_blocks): Likewise.
+ Update PHI nodes at BB2's successor.
+ (dump_tree_bb): Show PHI nodes in the block.
+ * tree-dfa.c (add_phi_arg): Update comment.
+ (remove_phi_arg_num): New function.
+ (remove_phi_arg): Call it.
+ Move from tree-ssa.c.
+ (remove_phi_node): Move from tree-ssa.c.
+ * tree-flow.h (ssa_make_edge): Declare.
+ (ssa_remove_edge): Declare.
+ * tree-pretty-print.c (dump_generic_node): Show block where PHI
+ arguments are coming from.
+ * tree-ssa-dce.c (pdom_info): New local variable.
+ (remove_dead_stmts): Initialize it and free it at the end.
+ (remove_conditional): New function.
+ (remove_dead_stmt): Call it.
+ * tree-ssa.c (eliminate_phi): If the edge index is -1, abort
+ compilation.
+ (ssa_remove_edge): New function.
+ (ssa_make_edge): New function.
+
+2003-04-06 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-cfg.c (push_bsi): New. Push a block_stmt_iterator onto a stack.
+ (pop_bsi): New. Pop a block_stmt_iterator off a stack.
+ * tree-flow-inline.h (struct bsi_list_d): Block iterator stack struct.
+ (new_bsi_list): Start a new bsi stack.
+ (empty_bsi_stack): Is stack empty.
+ (FOR_EACH_BSI_IN_REVERSE): Macro for processing bsi's in reverse.
+ (FOR_EACH_STMT_IN_REVERSE): Macro for processing stmt's in reverse.
+
+2003-04-06 Andreas Jaeger <aj@suse.de>
+
+ * treelang/treetree.c (tree_code_create_function_initial): Replace
+ calls to non-existent function annotate_with_file_line_column with
+ calls to annotate_with_file_line.
+ (tree_code_create_variable): Likewise.
+
+2003-04-05 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (get_expr_operands): Do not clobber readonly operands
+ in CALL_EXPRs.
+ (find_vars_r): Likewise.
+ (add_indirect_ref_var): When creating new INDIRECT_REF variables,
+ copy the readonly attribute from the variable's type.
+
+2003-04-05 Diego Novillo <dnovillo@redhat.com>
+
+ * tree.c (copy_node): Never copy tree annotations.
+
+2003-04-05 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa-ccp.c (visit_cond_stmt): Don't short circuit evaluation
+ of UNDEFINED conditional expressions.
+
+2003-04-04 Andrew MacLeod <amacleod@redhat.com>
+
+ * Makefile.in : Add tree-ssa-live.c and tree-ssa-live.h files.
+ * tree-ssa.c (struct _var_map, create_var_map, delete_var_map,
+ var_from_partition, get_var_partition, mapped_var_from_ref,
+ compact_var_map, dump_tree_partition, set_partition_for_var,
+ set_var_mapping, create_var_partition): Remove.
+ (create_temp): Allow temps to be created from SSA_NAME vars as well.
+ (eliminate_name, eliminate_build, elim_backward, elim_create,
+ eliminate_phi): Use new var map interface.
+ (coalesce_ssa_name): New. Coalesce ssa_name ranges together.
+ (assign_vars): Assign real variables to ssa_name partitions.
+ (rewrite_out_of_ssa): Use new varmap partition and routines.
+ * tree-ssa-live.h: New file
+ (var_map): Structure for variable map.
+ (num_var_partitions): Number of partitions.
+ (partition_to_var): Return variable for partition.
+ (var_to_partition): Return partition variable is in.
+ (var_to_partition_to_var): Return variable representing partition
+ another variable is in.
+ (register_ssa_partition): Initialize a partition element as used.
+ * tree-ssa-live.c: New file.
+ (init_var_map): Initialize a var_map.
+ (delete_var_map): Free storage for a var_map.
+ (var_union): Combine 2 partitions.
+ (compact_var_map): Reduce the number of partitions in a var_map.
+ (change_partition_var): Assign a specific var to a partition.
+ (create_ssa_var_map): Initialize a var_map with referenced variables.
+ (dump_var_map): Debug output for a var_map.
+
+2003-04-03 Diego Novillo <dnovillo@redhat.com>
+
+ * fold-const.c (fold_relational_hi_lo): Add missing comparison when
+ folding comparisons to signed_max+1.
+
+2003-04-02 Jason Merrill <jason@redhat.com>
+ Diego Novillo <dnovillo@redhat.com>
+
+ * tree-inline.c (initialize_inlined_parameters): Cast argument
+ types appropriately when emitting initialization assignments.
+
+2003-04-01 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-cfg.c (PENDING_STMT, SET_PENDING_STMT): New Macros.
+ (bsi_insert_on_edge): Rename to bsi_commit_first_edge_insert. Add an
+ empty annotation record to the new basic_block.
+ (bsi_commit_edge_inserts): New. Commit all pending edge inserts.
+ (bsi_insert_on_edge): New. Add stmt to edge's pending insert list.
+ * tree-flow-inline.h (phi_arg_from_edge): Return PHI index for an edge.
+ (phi_element_for_edge): Return PHI element for an edge.
+ * tree-flow.h (struct var_ann_d): Add auxiallary field and new
+ bit 'processed_out_of_ssa'.
+ * tree-ssa.c (_var_map): Structure for variable parition map.
+ (struct _elim_graph): Elimination graph for out-of-ssa pass.
+ (create_var_map): Create a new var_map.
+ (delete_var_map): Delete a var_map.
+ (var_from_parition): Return var for a specified partition.
+ (get_var_partition): Return partition a var belongs to.
+ (mapped_var_from_ref): Get root var for a var's partition.
+ (compact_var_map): Re-map the partitions to make the list dense.
+ (dump_var_parition): Print var_map.
+ (set_partition_for_var): Associate a real var with a partition.
+ (set_var_mapping): Associate an SSA version var with a real var.
+ (create_var_partition): Create a partition for processing.
+ (create_temp): Create a new temp variable for a partition.
+ (insert_copy_on_edge): Insert a copy between variables on an edge.
+ (new_elim_graph): Create a new elimination graph.
+ (clear_elim_graph): clear an elimination graph.
+ (delete_elim_graph): Delete an elimination graph.
+ (eliminate_name, eliminate_build, elim_forward,
+ elim_unvisited_predecessor, elim_backward, elim_create,
+ eliminate_phi): Routines to implement Morgans PHI elimination algorithm.
+ (eliminate_extraneous_phis): Eliminate PHI nodes which will never
+ generate code.
+ (rewrite_out_of_ssa): Use partitions and PHI elimination algorithm.
+
+2003-04-01 Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (make_blocks): Make sure the BIND_EXPR's subgraph
+ actually ended in a statement before seeing of the statement should
+ end a basic block.
+
+ * tree-cfg.c (dump_tree_cfg): Avoid crashing when cfun is NULL.
+ (tree_cfg2dot): Likewise.
+ * tree-dfa.c (dump_immediate_uses): Likewise.
+ * tree-pretty-print.c (dump_generic_node): Dump the EH_FILTER_FAILURE
+ nodes attached to an EH_FILTER_EXPR.
+
+ * tree-dfa.c (get_stmt_operands): Add cases for TRY_FINALLY_EXPR,
+ TRY_CATCH_EXPR, CATCH_EXPR and EH_FILTER_EXPR.
+ (get_expr_operands): Add case for EXC_PTR_EXPR.
+
+ * tree-dfa.c (compute_may_aliases): Accept FNDECL as an argument.
+ Use FNDECL instead of relying on CURRENT_FUNCTION_DECL.
+ * tree-flow.h (compute_may_aliases): Update prototype.
+ * tree-ssa.c (rewrite_into_ssa): Corresponding changes.
+
+ * tree-inline.c (expand_calls_inline): Correctly handle EH_FILTER_EXPR.
+
+2003-03-31 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (STRICT_WARN, STRICT2_WARN): Remove -Wtraditional.
+ * timevar.def (TV_TREE_CLEANUP_CFG): Define.
+ * tree-cfg.c (set_parent_stmt): Add documentation.
+ (replace_stmt): New function.
+ (merge_tree_blocks): New function.
+ (remap_stmts): New function.
+ (linearize_cond_expr): New function.
+ (linearize_control_structures): New function.
+ (cleanup_tree_cfg): Call it.
+ Use new timevar TV_TREE_CLEANUP_CFG.
+ (remove_bb): Update debugging message.
+ Make sure that bb->head_tree_p and bb->end_tree_p exist before
+ resetting their basic blocks.
+ (remove_stmt): When removing a control flow expression, update
+ basic block flags.
+ (cleanup_control_flow): Make sure that the block contains
+ statements.
+ (last_stmt): Reformat for readability.
+ (last_stmt_ptr): Return NULL if the block has no statements.
+ * tree-flow-inline.h (parent_block): Check that the block is not
+ empty.
+ * tree-flow.h (bb_empty_p): Remove.
+ * tree-inline.c (copy_tree_r): Do not copy empty_stmt_node.
+ * tree-ssa-dce.c (tree_ssa_dce): Call cleanup_tree_cfg.
+ * tree.c (body_is_empty): New function.
+ * tree.h (body_is_empty): Declare.
+
+2003-03-31 Jeff Law <law@redhat.com>
+
+ * tree-ssa-ccp.c (simulate_block): Add abnormal edges out of a
+ block to the edge worklist after simulating a block for the
+ first time. If the block has a single outgoing normal edge,
+ add that edge to the worklist after simulating the block for
+ the first time.
+
+2003-03-31 Frank Ch. Eigler <fche@redhat.com>
+
+ * gcc.c (MFLIB_SPEC): Remove -ld.
+ (MFWRAP_SPEC): Remove dlopen wrapping.
+
+2003-03-28 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa.c (rewrite_block): Add new argument 'eq_expr_value'.
+ Update all users.
+ If 'eq_expr_value' is given, use it to register a new
+ value for the variable given on the LHS.
+ If the block ends in a conditional expression of the form 'X == Y',
+ propagate 'X = Y' into the THEN_CLAUSE.
+ (MAY_COPYPROP_P): Define.
+ (rewrite_stmt): Call it.
+ (register_new_def): Fix comment.
+ (get_eq_expr_value): New function.
+
+2003-03-28 Diego Novillo <dnovillo@redhat.com>
+
+ * basic-block.h (BB_COMPOUND_ENTRY): Remove. Update all users
+ everywhere.
+ * tree-cfg.c: Minor fixes to various comments.
+ * tree-optimize.c (optimize_function_tree): Dump optimized function
+ after SSA->normal conversion.
+
+2003-03-26 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c: Implement open64 renaming algorithm.
+ (subst_phis): New function.
+ (generate_expr_as_of_bb): Ditto.
+ (new_rename_1): Ditto.
+ (process_delayed_rename): Ditto.
+ (do_proper_save): Use bsi_* functions for insertion, don't remove
+ old code quite yet, haven't fully tested.
+ Also add argument that says whether to insert before use or after use.
+ (defs_y_dom_x): Factor through injuries properly.
+ (defs_match_p): Ditto.
+ (phi_opnd_from_res): Attempt to fix, and remove useless argument.
+ (reset_can_be_avail): Fix broken condition that would cause infinite
+ loop.
+ (update_old_new): #if 0 updating of bb heads.
+ (finalize_1): We occasionally get 5 + a rather than a + 5, so we
+ need to make sure 5 is a DECL before trying to get a reaching def.
+ (repair_use_injury): If we couldn't find a reaching def, we don't need
+ to repair it.
+ (assign_new_class): Only push to stack2 if it exists (so we can
+ share this function in both rename implementations).
+ (create_ephi_node): Add argument that says whether to add ephi
+ to block or not (we create them sometimes for validation only).
+ (tree_perform_ssapre): Skip expressions without any uses.
+
+ * tree.h: Add EREF_DELAYED_RENAME.
+ (struct tree_eref_common): Add delayed_rename bit.
+
+2003-03-25 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-simple.c: Use tree codes to document grammar for relational
+ operators &&, || and ^.
+
+2003-03-25 Diego Novillo <dnovillo@redhat.com>
+
+ * cfg.c (dump_edge_info): Add labels for EDGE_TRUE_VALUE,
+ EDGE_FALSE_VALUE and EDGE_EXECUTABLE.
+ * tree-cfg.c (dump_tree_bb): Change formatting. Show all
+ statements in the block.
+ * tree-simple.c: Update documentation for GIMPLE conditional
+ expressions.
+
+2003-03-24 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (get_expr_operands): If there are no call clobbered
+ variables, don't create a VDEF for GLOBAL_VAR at clobbering
+ CALL_EXPRS.
+ * tree-flow.h (fold_stmt): Declare.
+ * tree-ssa-ccp.c (fold_stmt): Change to extern declaration.
+ * tree-ssa.c (rewrite_stmt): Call it.
+
+2003-03-22 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (gtype-desc.o): Add dependency on $(TREE_FLOW_H).
+
+ * tree-dfa.c (struct alias_set_d): Add field 'num_elements'.
+ (struct walk_state): Move declaration earlier in the file.
+ (create_global_var): New local function.
+ (num_referenced_vars, num_aliased_objects): Change type to
+ 'size_t'. Update all users.
+ (aliased_objects, aliased_objects_base, aliased_objects_aliase_set):
+ Mark for garbage collection.
+ (num_call_clobbered_vars, call_clobbered_vars): New global
+ variable.
+ (get_expr_operands): For CALL_EXPRs, add a VUSE or VDEF reference
+ for every pointer argument. If the call may clobber, add a VDEF,
+ otherwise add a VUSE.
+ If the call may clobber, add VDEF for GLOBAL_VAR.
+ (dump_variable): Show whether the variable is call clobbered.
+ (dump_dfa_stats): Show call clobbered variables.
+ (compute_may_aliases): Minor formatting changes.
+ (compute_alias_sets): If the function makes clobbering calls, add
+ GLOBAL_VAR as an alias to every call-clobbered variable.
+ Remove alias sets that have exactly one element.
+ (register_alias_set): Set 'num_elements' to zero for every newly
+ created alias set.
+ (find_alias_for): Don't make a second call to add_may_alias to make
+ alias tags alias themselves. It's redundant.
+ Increment 'num_elements' when adding a new alias to an alias set.
+ (may_alias_p): Don't handle GLOBAL_VAR.
+ Check for structure aliasing when either PTR or VAR are a
+ structure. Don't do it only when both are structures.
+ (dump_alias_info): Show all aliases of each variable.
+ (find_vars_r): When processing a CALL_EXPR node, set
+ walk_state->is_store if the function may clobber and create a
+ reference to GLOBAL_VAR.
+ (add_indirect_ref_var): Change type of second argument from 'void *'
+ to 'struct walk_state *'. Update all users.
+ (add_referenced_var): Likewise. If a potentially aliased variabe
+ is not declared 'const', add it to the list of call clobbered
+ variables.
+
+ * tree-flow.h (struct var_ann_d): Add field 'is_call_clobbered'.
+ Change type of field 'uid' to size_t. Update all users.
+ (stmt_ann_d): Add field 'makes_clobbering_call'.
+ (next_tree_ref_id): Remove unused variable.
+ (call_clobbered_vars): Declare.
+ (num_call_clobbered_vars): Declare.
+ (call_clobbered_var): New inline function.
+
+ * tree-ssa-ccp.c (visit_phi_node): If the LHS of a PHI node is
+ volatile, mark the PHI node VARYING without checking its arguments.
+ (visit_assignment): Likewise.
+ (set_value): Remove. Update all users.
+ (likely_value): If the statement makes aliased loads or has
+ volatile operands, consider it VARYING.
+ (get_default_value): If a variable is volatile, consider it
+ VARYING.
+
+ * tree-ssa.c (init_tree_ssa): Initialize num_call_clobbered_vars
+ and call_clobbered_vars.
+ Do not create GLOBAL_VAR. Set it to NULL_TREE.
+ Increase initial size for various hash tables.
+ (delete_tree_ssa): Reset num_call_clobbered_vars and
+ call_clobbered_vars.
+ (get_reaching_def): Rename from currdef_for. Update all users.
+ Always create default definitions for variables that need them.
+ Callers that use to call currdef_for with the second argument set
+ to false now call get_value_for.
+ (htab_statistics): New function.
+ (dump_tree_ssa): Call it.
+ (avail_expr_eq): Also compare VUSE operands.
+
+2003-03-21 Jeff Law <law@redhat.com>
+
+ * tree-dfa.c: Revert vla changes from yesterday.
+ (find_vla_decls_r): Do not look inside TYPE_DECLs.
+
+2003-03-20 Jeff Law <law@redhat.com>
+
+ * gimplify.c (simplify_return_expr): Tighten condition for
+ converting the RHS of a MODIFY_EXPR in a RETURN_EXPR to a
+ simple_val. Allow returning a RESULT_DECL directly.
+ * tree-dfa.c (get_expr_operands): A RESULT_DECL can have
+ interesting operands.
+ (clobber_vars_r): Handle RESULT_DECLs.
+ (compute_may_aliases): Initialize and free vla_htab.
+ (find_vla_decls): Pass vla_htab to walk_tree.
+ (find_vla_decls_r): Likewise.
+ * tree.h (SSA_DECL_P): Accept RESULT_DECLs.
+
+2003-03-19 Jeff Law <law@redhat.com>
+
+ * gimplify.c (simplify_return_expr): Only allow simple values
+ on the RHS of a MODIFY_EXPR appearing in a RETURN_EXPR.
+ * tree-cfg.c (make_exit_edges): We no longer need to look for
+ CALL_EXPRs on the RHS of a MODIFY_EXPR inside RETURN_EXPRs.
+
+2003-03-18 Andrew Macleod <amacleod@redhat.com>
+
+ * tree-cfg.c (make_blocks): Use append_stmt_to_bb. Check for NULL
+ tsi_stmt when deciding whether to start a new block.
+ (add_stmt_to_bb): Don't update the basic block end pointer.
+ (append_stmt_to_bb): New. Add stmt and update the BB end pointer.
+ (first_stmt): Use only 1 return.
+ (last_stmt): Modified to use bsi_last().
+ (last_stmt_ptr): Modified to use bsi_last().
+ (bsi_last): New. Return an iterator to the last stmt in a block.
+ (bsi_from_tsi): Fix bug which wouldn't set the context properly when
+ within a nested BIND_EXPR.
+ (bsi_update_from_tsi): Insert helper which is more efficient than
+ bsi_from_tsi().
+ (bsi_link_after): link in a new stmt and update the basic block
+ data structures.
+ (bsi_insert_after): Insert a new stmt into a block.
+ (bsi_insert_before): Insert a new stmt into a block.
+ (bsi_insert_on_edge): Insert a new stmt on an edge.
+ * tree-flow-inline.h (is_label_stmt): Return true if stmt can be a
+ target of a control transfer.
+ * tree-flow.h (is_label_stmt, bsi_last): New prototypes.
+
+2003-03-12 Jeff Law <law@redhat.com>
+
+ * c-simplify.c (simplify_switch_stmt): Save the type of the original
+ condition in TREE_TYPE (SWITCH_EXPR (...)). Annotate the SWITCH_EXPR
+ with file/line information.
+ * expr.c (expand_expr, case SWITCH_EXPR): Use expand_end_case_type.
+ * tree.def (SWITCH_EXPR): Document meaning of TREE_TYPE field of
+ the SWITCH_EXPR.
+
+ * c-simplify.c (simplify_block): Set the current line number to
+ the line associated with the end of the block.
+
+ * c-decl.c (finish_function): No longer save/restore the
+ current filename or linenumber around simplification. Instead
+ save/restore it around inlining.
+ (c_expand_body_1): Save/restore current filename and linenumber
+ around expansion of trees into RTL.
+ * gimplify.c (simplify_function_tree): Make the current file/line
+ number match the non-gimple code at the end of a function.
+
+ * tree-cfg.c: Include toplev.h.
+ (remove_bb): Warn about unreachable code.
+
+ * cfgrtl.c (verify_flow_info): Ignore EDGE_EXECUTABLE, it's for
+ the CCP optimizer only.
+
+ * ssa.c (convert_to_ssa): Use last_basic_block, not n_basic_blocks.
+
+2003-03-11 Jeff Law <law@redhat.com>
+
+ * builtins.c: Fix minor comment typo.
+ (expand_builtin_strcmp, expand_builtin_strncmp): Remove.
+ (expand_builtin_strcat, expand_builtin_strncat): Likewise.
+ (expand_builtin_strspn, expand_builtin_strcspn): Likewise.
+ (expand_builtin_strcopy, expand_builtin_strstr): Likewise.
+ (expand_builtin_strpbrk, expand_builtin_strchr): Likewise.
+ (expand_builtin_strrchr, expand_builtin_fputs): Likewise.
+ (simplify_builtin_memcmp, simplify_builtin_strcmp): New functions.
+ (simplify_builtin_strpbrk, simplify_builtin_strstr): Likewise
+ (simplify_builtin_strchr, simplify_builtin_strrchr): Likewise
+ (simplify_builtin_strcpy, simplify_builtin_strncpy): Likewise
+ (simplify_builtin_strncmp, simplify_builtin_strcat): Likewise
+ (simplify_builtin_strncat, simplify_builtin_strspn): Likewise
+ (simplify_builtin_strcspn, simplify_builtin_fputs): Likewise
+ (expand_builtin_memcmp): Use simplify_builtin_memcmp.
+ (simplify_builtin): New function
+ (expand_builtin): Use simpify_builtin to collapse several common
+ cases together.
+ * gimplify.c (simplify_call_expr): Accept new argument. All
+ callers updated. Call simplify_builtin to try and simplify builtin
+ function calls before we simplify their arguments.
+ * tree.h (simplify_builtin): Prototype.
+
+2003-03-11 Jeff Law <law@redhat.com>
+
+ * timevar.def (TV_TREE_SSA_TO_NORMAL): New timevar.
+ * tree-cfg.c (remove_stmt): Also remove special annotations
+ on RHS of MODIFY_EXPR statements.
+ * tree-dfa.c (create_stmt_ann): Update comments. Fix formatting.
+ (compute_may_aliases): Make sure timevar encloses entire routine.
+ * tree-ssa.c (rewrite_out_of_ssa): Enclose with a timevar.
+ (remove_annotations_r): Avoid walking into subtrees of anything
+ except container nodes. Remove the special annotation on the
+ RHS of MODIFY_EXPRs.
+
+2003-03-10 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mx_xfn_indirect_ref): Allow unfolded "& ptr->field"
+ constructs to pass uninstrumented. Remove TREE_ADDRESSABLE settings.
+ Keep array accesses to non-ADDRESSABLE objects uninstrumented. Update
+ __MF_TYPE_* constants for __mf_register calls.
+
+2003-03-10 Jeff Law <law@redhat.com>
+
+ * c-decl.c (c_expand_body_1): Update comments relating to
+ re-simplification after mudflap instrumentation. Avoid
+ unnecessary simplification of the function tree.
+ * gimplify.c (keep_function_tree_in_gimple_form): New function.
+ * tree-inline.c: Include tree-iterator.h and tree-simple.h
+ (struct inline_data): Add new TSI field.
+ (copy_body_r): Keep tree in gimple form when transforming a
+ RETURN_EXPR into a MODIFY_EXPR and GOTO_EXPR.
+ (initialize_inlined_parameters): Use MODIFY_EXPR, not INIT_EXPR
+ for initialization of inlined parameters.
+ (expand_call_inline): Save and restore the TSI around the
+ call to expand_calls_inline. Keep the tree in gimple form
+ when replacing a CALL_EXPR with a BIND_EXPR for the inlined
+ body.
+ (expand_calls_inline): Revamp to provide the current TSI to
+ expand_call_inline when we're working with gimple form.
+ * Makefile.in (tree-inline.o): Update dependencies.
+ * tree.h (keep_function_tree_in_gimple_form): Prototype.
+
+2003-03-10 Andrew MacLeod <amacleod@redhat.com>
+
+ * Makefile.in (tree.o): Add tree-iterator.h dependancy.
+ * sbitmap.c (sbitmap_realloc): Grow a sbitmap structure.
+ * sbitmap.h (sbitmap_realloc): New Prototype.
+ * tree-cfg.c (remove_bb): Use new format for bsi_remove.
+ (bsi_remove): Update iterator to refer to the next stmt.
+ (bsi_prev): Implement previous stmt routine.
+ (bsi_from_tsi): Create a block iterator from a tree iterator.
+ * tree-flow-inline.h (bsi_prev): Remove.
+ (tsi_from_bsi): Create a tree iterator from a block iterator.
+ * tree-flow.h (bsi_prev,bsi_remove): Update prototypes.
+ (bsi_from_tsi, tsi_from_bsi, bsi_insert_*): New prototypes.
+ (bsi_iterator_update): New enum type.
+ * tree-iterator.h (tree_stmt_anchor, tsi_iterator_update): New type.
+ (tsi_link_before, tsi_link_after, tsi_delink, tsi_new_stmt_list,
+ tsi_stmt_list_head): New prototypes.
+ * tree-ssa-dce.c (remove_dead_stmts): Update removal loop to allow
+ that remove_dead_stmt update's the iterator.
+ (remove_dead_stmt): Use a pointer to the iterator since bsi_remove
+ requires it.
+ * tree.c (tsi_link_before): New function to link a stmt before an
+ iterator.
+ (tsi_link_after): New function links stmt after an iterator.
+ (tsi_delink): Removes a stmt from a list.
+ (tsi_new_stmt_list): New function to begin a new stmt list.
+ (tsi_stmt_list_head): New function to get the first stmt in a list.
+
+2003-03-07 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (remove_stmt): Don't assume that the statement is in
+ SSA form.
+
+ * tree-flow.h (dump_tree_ssa_stats): Declare.
+ (debug_tree_ssa_stats): Declare.
+ (stmt_ann_d): Add new statement flags 'makes_aliased_loads',
+ 'makes_aliased_stores', and 'has_volatile_ops'.
+ * tree-dfa.c (add_stmt_operand): Set new statement flags accordingly.
+
+ * tree-pretty-print.c (dump_generic_node): Various cosmetic changes
+ to the rendering of some expressions.
+
+ * tree-ssa.c (struct var_value_d): Rename from struct currdef_d.
+ Rename field 'currdef' to 'value'. Update all users.
+ (avail_exprs): New local hash table.
+ (const_and_copies): New local hash table.
+ (struct ssa_stats_d): Declare.
+ (ssa_stats): New local variable.
+ (rewrite_into_ssa): Deallocate avail_exprs and const_and_copies
+ after renaming.
+ Call dump_tree_ssa_stats() if -fdump-tree-ssa-stats is given.
+ (rewrite_block): Document the renaming process.
+ Add new local stack block_avail_exprs to keep track of expressions
+ made available in this block and its children.
+ (rewrite_stmts): Move body inside rewrite_block.
+ (dump_tree_ssa_stats): New function.
+ (debug_tree_ssa_stats): New function.
+ (get_def_blocks): New function.
+ (insert_phi_nodes_for): Call it.
+ (rewrite_stmt): Add support for keeping track of copies, constants
+ and globally redundant expressions.
+ (rewrite_operand): If a pointer has been copy propagated into
+ another one, rewrite INDIRECT_REF nodes of the original pointer to
+ refer to the new one.
+ (register_new_def): Add new argument 'var' indicating which
+ variable is this new definition for. Update all users.
+ (update_indirect_ref_vuses): New function.
+ (update_pointer_vuses): New function.
+ (init_tree_ssa): Set variable 'ssa_stats' to zero.
+ Allocate memory for 'avail_exprs' and 'const_and_copies'.
+ (currdef_for): Don't mark inline.
+ Call get_value_for and set_value_for.
+ (set_currdef_for): Remove. Update all users.
+ (var_value_hash): Rename from currdef_hash. Update all users.
+ (var_value_eq): Rename from currdef_eq. Update all users.
+ (get_value_for): New function.
+ (set_value_for): New function.
+ (lookup_avail_expr): New function.
+ (avail_expr_hash): New function.
+ (avail_expr_eq): New function.
+ (get_def_blocks_for): New function.
+ (var_is_live): New function.
+
+2003-03-06 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa-ccp.c (likely_value): Don't assume CONSTANT if the
+ statement has virtual uses.
+
+2003-03-05 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (opf_none, opf_is_def, opf_force_vop, opf_ignore_bp):
+ New flags to alter the behavior of add_stmt_operand.
+ (get_expr_operands): Change operand IS_DEF with FLAGS. Update all
+ users.
+ When adding a VUSE for pointer dereferences in function arguments,
+ don't add a superfluous VUSE for the base pointer.
+ (add_stmt_operand): Remove operands IS_DEF and FORCE_VOP. Add
+ operand FLAGS. Update all users.
+
+2003-03-05 Jason Merrill <jason@redhat.com>
+
+ * c-pretty-print.c (do_niy): Only print operands of expressions.
+ * tree-pretty-print.c: Likewise.
+
+ * c-simplify.c (simplify_decl_stmt): Only simplify DECL_SIZE_UNIT.
+ * gimplify.c (simplify_array_ref_to_plus): New fn.
+ (simplify_array_ref): Use it.
+ (build_addr_expr_with_type): Split out from build_addr_expr.
+ (simplify_compound_lval): Break out an ARRAY_REF with non-constant
+ element size.
+
+2003-03-05 Frank Ch. Eigler <fche@redhat.com>
+
+ * gcc.c (MFWRAP_SPEC): Remove most --wrap entries.
+
+2003-03-03 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (is_strred_cand): Temporarily disable strength
+ reduction while working on bootstrapping.
+ (requires_edge_placement): Reenable for now, until an insertion
+ infrastructure exists that can handle critical edges.
+ (count_stmts_in_bb): New function, used for verifying we do
+ insertions properly.
+ (update_old_new): Fix up bb heads as well.
+ (do_proper_save): Handle single statement bb properly.
+ Handle BB's contained in BIND_EXPRS.
+ (code_motion): Count number of statements in bb before and after
+ to make sure we don't screw up boundaries.
+ (finalize_1): Ditto.
+ (rename_2): Fix subtle rename bug.
+ (phi_opnd_from_res): Do this the right way, by cloning the
+ occurrence and modifying it, as every other PRE implementation
+ does.
+ (tree_perform_ssapre): Handle comparisons too (unary exprs
+ currently disabled till load PRE is reimplemented).
+ (reset_can_be_avail): Fix can_be_avail test.
+
+2003-03-01 Diego Novillo <dnovillo@redhat.com>
+
+ * doc/invoke.texi: Fix typo.
+
+2003-02-28 Aldy Hernandez <aldyh@redhat.com>
+ Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (OBJS): Add tree-ssa-copyprop.o.
+ (tree-ssa-copyprop.o): New rule.
+ (tree-ssa-ccp.o): Add dependency on $(TREE_SIMPLE_H).
+
+ * timevar.def (TV_TREE_COPYPROP): New timevar.
+ * flags.h (flag_tree_copyprop): Declare.
+ * toplev.c (flag_tree_copyprop): Define.
+ (f_options): Add -ftree-copyprop.
+ * tree.h (tree_dump_index): Add TDI_copyprop.
+ * tree-dump.c (dump_files): Add entry for -fdump-tree-copyprop.
+ * doc/invoke.texi: Document -ftree-copyprop and -fdump-tree-copyprop.
+
+ * tree-ssa-copyprop.c: New file.
+ * tree-flow.h (tree_ssa_copyprop): Declare.
+ * tree-optimize.c (optimize_function_tree): Call it.
+ * tree-dfa.c (add_vuse): Make extern. Update all users.
+
+ * tree-ssa.c (mark_def_sites): VUSEs are stored in a varray of trees.
+
+2003-02-28 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mudflap_enqueue_decl): Ignore extern artificial
+ variable declarations.
+
+2003-02-27 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (get_stmt_operands): INIT_EXPR nodes cannot
+ appear in GIMPLE form. Don't handle them.
+ (get_expr_operands): Likewise.
+ (find_vars_r): Likewise.
+ * tree-ssa-ccp.c (get_rhs): Likewise.
+ (set_rhs): Likewise.
+ * tree-ssa-pre.c (tree_perform_ssapre): Likewise.
+
+2003-02-27 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa-ccp.c (ccp_fold): Fold builtins by replacing and
+ restoring their arguments.
+
+2003-02-27 Jeff Law <law@redhat.com>
+
+ * tree-dfa.c (find_vars_r): Clear *walk_subtrees appropriately
+ to avoid useless walking of subtrees.
+
+ * fold-const.c (nondestructive_fold_binary_to_constant): Renamed
+ from nondestructive_fold_binary. Update comments slightly.
+ (nondestructive_fold_unary_to_constant): Similarly.
+ (fold_relational_hi_lo): Corresponding changes.
+ * tree-ssa-ccp.c (ccp_fold): Corresponding changes.
+ * tree.h: Corresponding changes.
+
+2003-02-26 Jeff Law <law@redhat.com>
+
+ * tree-ssa-ccp.c (ccp_fold): Also handle folding of calls to
+ builtin functions.
+
+ * fold-const.c (nondestructive_fold_binary): Handle truth ops
+ when both arguments are constant (duh!). Handle CONJ_EXPR.
+
+2003-02-26 Daniel Berlin <dberlin@dberlin.org>
+
+ * flags.h: Remove flag_ip.
+ * toplev.c: Ditto.
+ * tree-alias-ander.c: s/flag_ip/flag_unit_at_a_time/g.
+ (andersen_cleanup): Set region to null when done.
+ (andersen_function_call): Check DECL_PTA_TYPEVAR, not
+ DECL_SAVED_TREE.
+ * tree-alias-common.c: s/SSA_DECL_P/DECL_P/g.
+ (get_alias_var_decl): Remove dead code, fix bug in what is a
+ local alias var.
+ (find_func_aliases): Use get_alias_var, not create_fun_alias_var.
+ (create_fun_alias_var): Fix to use DECL_PTA_TYPEVAR.
+ Use get_alias_var rather than create_alias_var.
+ (create_fun_alias_var_ptf): Ditto.
+ (create_alias_vars): Ditto.
+ * tree-dfa.c (compute_may_aliases): Fix check for
+ create_alias_vars.
+ Move deletion of alias vars back to here, from tree-ssa.c
+ * tree-ssa.c (delete_tree_ssa): Remove delete_alias_vars call.
+
+2003-02-25 Jeff Law <law@redhat.com>
+ Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa-ccp.c (likely_value): If the statement has no
+ use operands, then return CONSTANT.
+
+ * fold-const.c (nondestructive_fold_binary): Handle TRUTH_AND_EXPR
+ and TRUTH_OR_EXPR. Placeholder for TRUTH_XOR_EXPR.
+ * tree-ssa-ccp.c (ccp_fold): Handle TRUTH_{AND,OR,XOR}_EXPR.
+ (def_to_undefined): Re-enable VARYING->UNDEFINED state transition
+ sanity check.
+
+ * tree-ssa-ccp.c (likely_value): Renamed from may_fold_p. Now
+ returns a latticevalue indicating the likely value for the
+ the RHS of the statement.
+ (evaluate_stmt): Update to use likely_value instead of may_fold_p.
+ Statements with UNDEFINED operands produce an UNDEFINED result.
+ (set_lattice_value): Reenable VARYING->CONSTANT sanity check.
+
+2003-02-25 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-cfg.c (bsi_init): Handle BIND_EXPR nodes inside a basic block.
+ (bsi_next_in_bb): Likewise.
+
+2003-02-25 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (parent_array): Remove. Update all users.
+ (struct cfg_stats_d): Add field 'num_failed_bind_expr_merges'.
+ (NEXT_BLOCK_LINK): Define.
+ (build_tree_cfg): Call alloc_aux_for_blocks instead of
+ create_block_annotations.
+ (make_blocks): Rewrite to support basic blocks that can span whole
+ BIND_EXPR bodies and put control statements at the end of blocks.
+ Add arguments 'next_block_link' and 'bb'. Replace 'parent_block'
+ with 'parent_stmt'. Update all users.
+ (make_loop_expr_blocks): Replace argument 'parent_block' with 'entry'.
+ Add argument 'next_block_link'. Update all users.
+ Don't create an empty latch block.
+ (make_cond_expr_blocks): Add argument 'next_block_link'. Update
+ all users.
+ (make_switch_expr_blocks): Likewise.
+ (make_bind_expr_blocks): Replace 'parent_block' with 'parent_stmt'.
+ Add argument 'next_block_link' and 'entry'.
+ Don't create a new block for the BIND_EXPR node. Extend the
+ existing block.
+ (add_stmt_to_bb): New function.
+ (create_bb): Remove argument 'parent_block'. Update all users.
+ (create_block_annotations): Remove. Update all users.
+ (make_edges): Don't handle BIND_EXPR nodes.
+ (make_ctrl_stmt_edges): Don't create an extra edge to the body of
+ the switch.
+ (make_loop_expr_edges): Only create an edge to the body of the
+ loop.
+ (remove_unreachable_block): Add more documentation for the special
+ case where a control statement entry is unreachable but its body
+ isn't.
+ Remove the basic block annotation from the head and end containers
+ in the block.
+ (disconnect_unreachable_case_labels): Don't keep the edge that goes
+ to the BIND_EXPR at the start of the switch body.
+ (dump_tree_bb): Call is_latch_block_for.
+ (dump_cfg_stats): Show stats about basic blocks that could not span
+ beyond the end of a BIND_EXPR body.
+ (successor_block): Use NEXT_BLOCK_LINK if the block is the last
+ inside a control structure.
+ (is_ctrl_stmt): Update documentation.
+ (stmt_starts_bb_p): Add new argument 'prev_t'. Update all users.
+ Only labels may start a new basic block.
+ (stmt_ends_bb_p): Add LOOP_EXPR, TRY_FINALLY_EXPR and
+ TRY_CATCH_EXPR to the list.
+ (latch_block): Remove.
+ (is_latch_block_for): New function.
+ (set_bb_for_stmt): Reformat some code.
+
+ * tree-flow-inline.h (set_parent_block): Remove. Update all users.
+ (parent_stmt): New function.
+ (parent_block): Call it.
+
+ * tree-flow.h (struct stmt_ann_d): Add field 'parent_stmt'.
+ (struct bb_ann_d): Remove block parent_block.
+
+ * tree-pretty-print.c (dump_generic_node): Don't handle empty latch
+ nodes.
+
+ * tree-ssa-ccp.c (def_to_undefined): Temporarily disable check for
+ VARYING->UNDEFINED transitions.
+ (set_lattice_value): Likewise for VARYING->CONSTANT transitions.
+
+ * tree-ssa-dce.c (mark_necessary): Use parent_stmt() to traverse
+ all the control statements that contain the current
+ statement.
+ (makr_control_parent_necessary): Remove. Update all users.
+ (stmt_useful_p): Add BIND_EXPR to the list of useful
+ statements.
+ (process_worklist): Check that the statement is
+ associated to a basic block.
+ (remove_dead_stmt): Don't assume that the block has a
+ postdominator.
+
+2002-02-20 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-ander.c: Store cached ptsets in the typevar, not
+ a seperate hash table.
+ (ptset_map): Removed;
+ (ptset_map_eq): Ditto.
+ (ptset_map_hash): Ditto.
+ (andersen_init): Remove ptset_map.
+ (andersen_cleanup): Ditto.
+ (andersen_add_var): Ditto.
+ (andersen_add_var_asm): Ditto.
+ (andersen_may_alias): Ditto.
+ * tree-alias-common.c: Store typevars for DECL nodes in the tree_decl
+ structure.
+ (get_alias_var_decl): Use DECL_PTA_TYPEVAR for DECL's.
+ (create_alias_var): Ditto.
+ (find_func_aliases): CONST functions don't affect aliasing either.
+ (ptr_may_alias_var): Don't call get_base_symbol.
+ Remove decl_function_context, use DECL_CONTEXT instead.
+ For DECL's, use DECL_PTA_TYPEVAR.
+ * tree-alias-type.c (struct alias_typevar_aterm): Add ptset member.
+ (ALIAS_TVAR_PTSET): New macro.
+ * tree.h (DECL_PTA_TYPEVAR): New macro.
+ (struct tree_decl): Add typevar member.
+
+2003-02-20 Jeff Law <law@redhat.com>
+
+ * c-simplify.c (simplify_decl_stmt): Call set_vla_decl on the
+ temporary holding the size and unit size for a VLA. Minor
+ formatting fixes.
+
+ * ssa.c: Revert caching of immediate dominators change made on
+ Jan 28, 2003.
+
+ * tree-dfa.c: Fix comment.
+
+2003-02-20 Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (remove_bb): Update PHI nodes as edges are removed.
+ (cleanup_cond_expr_graph): Likewise.
+ (cleanup_switch_expr_graph): Likewise.
+ (disconnect_unreachable_case_labels): Likewise.
+
+ * tree-ssa-dce.c (mark_control_parent_necessary): Be much more
+ selective about what statements in the control parents are marked
+ as necessary.
+
+ * tree-dfa.c (INDIRECT_REFs and ADDRESSABLE_VARs varrays): Replace
+ with a single ALIASED_OBJECTs set of varrays.
+ (dump_dfa_stats): Corresponding changes.
+ (compute_may_aliases, dump_alias_info): Likewise.
+ (compute_alias_sets): Likesise. Update comments. Register
+ alias sets for all potentially aliased objects which are stored.
+ Check each potentially aliased object with the registered alias
+ sets.
+ (register_alias_set): If DEREF aliases a single registered _DECL,
+ then replace the _DECL's entry with DEREF.
+ (find_alias_for): Update comments. Do not stop the search when
+ an alias is found. There may be multiple entries with conflicting
+ alias sets.
+ (struct walk_state): New structure for statement walker callbacks.
+ (find_vars_r): Add logic to track loads and stores of potentially
+ aliased objects separately. Various changes related to
+ using a single set of varrays for all aliased objects.
+ (add_referenced_var): Record in the var's annotation if the
+ var is read or written. Various changes related to using a
+ single set of varrays for all the aliased objects.
+ (add_stmt_operand): Only set may_point_to_global_mem for INDIRECT_REFs.
+ * tree-flow.h (struct var_ann_d): Add new fields indicating if
+ the var is loaded or stored. Explicitly note unused bitfield
+ entries.
+
+2003-02-19 Jeff Law <law@redhat.com>
+
+ * fold-const.c (fold_negate_const): New function. Broken out of
+ the generic fold code.
+ (fold_abs_const, fold_relational_const): Likewise.
+ (fold_relational_hi_lo): Likewise.
+ (nondestructive_fold_unary, nondestructive_fold_binary): Likewise.
+ (fold): Use fold_negate_const, fold_abs_const, fold_relational_const,
+ and fold_relational_hi_lo.
+ * tree.h (nondestructive_fold_unary): Declare.
+ (nondestructive_fold_binary): Declare.
+ * tree-ssa-ccp.c (ccp_fold): New function.
+ (add_control_edge): Fix trivial formatting bug.
+ (evaluate_stmt): Rework to use ccp_fold instead of copying
+ statements.
+
+2003-02-18 Jeff Law <law@redhat.com>
+
+ * tree-ssa-ccp.c (visit_assignment): For simple copies, copy the
+ lattice values.
+ (defs_to_undefined): Add missing abort.
+ (replace_uses_in): Do not do a replacement if it would create
+ non GIMPLE trees.
+
+2002-02-14 Jeff Law <law@redhat.com>
+
+ * tree-ssa-ccp.c (def_to_undefined): Improve sanity checking code
+ so that it can detect invalid VARYING->UNDEFINED transitions.
+ (set_lattice_value): Improve sanity checking code so that it
+ does not trip on valid VARYING->CONSTANT transitions.
+
+ * tree-flow.h (struct stmt_ann_d): Add new field in_ccp_worklist.
+ * tree-ssa-ccp.c (simulate_stmt): Renamed from simulate_def_use_edges.
+ (add_var_to_ssa_edges_worklist): New function. Only add statements
+ to the ssa_edges worklist if they are not already on the worklist.
+ (def_to_undefined, def_to_varying, set_lattice_value)
+ (tree_ssa_ccp): Only reevaluate the statement if in_ccp_worklist
+ is set for the element popped off the ssa_edges worklist.
+ (simulate_statement): Simplify now that ssa_edges is a worklist
+ of statements to reevaluate rather than a worklist of defs
+ that need their immediate uses reevaluated.
+ (visit_stmt): Clear in_ccp_worklist.
+
+ * tree-ssa-ccp.c (def_to_undefined): Directly store the new
+ lattice values rather than call set_value.
+ (def_to_varying): Likewise.
+ (set_lattice_value): Likewise.
+
+ * tree-ssa-ccp.c (def_to_undefined): Add some state transition
+ sanity checking. Avoid calling set_value if nothing changed.
+ (def_to_varying): Avoid calling set_value if nothing changed.
+ (set_lattice_value): Add some state transition sanity checking
+ for transitions into the CONSTANT state. If the object's
+ "constant" value has changed to a new constant value, then the
+ object has a VARYING value.
+
+ * tree-ssa-ccp.c (tree_ssa_ccp): Work through the entire
+ ssa_edges worklist each iteration through the main loop.
+
+2002-02-13 Jeff Law <law@redhat.com>
+
+ * tree-ssa-ccp.c: Fix comment formatting glitches.
+
+ * tree-ssa-ccp.c (may_fold_p): New function. Returns nonzero if
+ the given statement may fold after replacement of operands with
+ constants.
+ (evaluate_stmt): Only create a copy of the statement if there is
+ a reasonable chance the statement will fold.
+
+2002-02-13 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (OBJS): Add tree-ssa-pre.o.
+
+2003-02-13 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-dfa.c (create_stmt_ann): Do stmt part of common annotation.
+ * tree-flow-inline.h (tree_stmt): Return statement tree is part of.
+ * tree-flow.h (struct bb_ann_d): Add ephi_nodes.
+ * tree-optimize.c (optimize_tree): Activate SSAPRE again.
+ * tree-pretty-print.c (debug_generic_expr): New function.
+ (debug_generic_stmt): Ditto.
+ (dump_generic_node): Pretty print EUSE's, EREF's, and EPHI's.
+
+ * tree-ssa-pre.c: Rewrite almost entirely. Now performs more
+ strength reduction, EPHI minimization, and keeps SSA up to date.
+ * tree.c (tree_size): Handle EUSE, EPHI, EREF nodes.
+ (tree_node_structure): Ditto.
+ (ephi_node_elt_check_failed): New function.
+ * tree.def: Add EUSE_NODE, ELEFT_NODE, EKILL_NODE, EPHI_NODE,
+ EEXIT_NODE.
+ * tree.h (EREF_NODE_CHECK): New.
+ (EPHI_NODE_ELT_CHECK): New.
+ (struct tree_eref_common): New.
+ (struct tree_euse_node): New.
+ (struct tree_ephi_node): New.
+ (union tree_node): Add euse, eref, ephi members.
+ (enum tree_node_structure): Add TS_EPHI_NODE, TS_EUSE_NODE,
+ TS_EREF_NODE.
+
+2003-02-13 Daniel Berlin <dberlin@dberlin.org>
+ Andreas Jaeger <aj@suse.de>
+
+ * tree-flow.h: Add some garbage collector marks.
+
+2003-02-12 Jeff Law <law@redhat.com>
+
+ * Makefile.in (ssa.o): Depends on $(TREE_H) and tree-flow.h
+ * ssa.c: Include tree.h and tree-flow.h.
+ (compute_dominance_frontiers_1): Use the sparse bitmap
+ of dominator children from the basic block's annotation
+ if it's available. Otherwise build the sparse bitmap
+ using the result of get_dominated_by.
+ * tree-ssa.c (rewrite_into_ssa): Reorder things slightly so
+ that we can use the cached dominator children computed
+ by mark_def_sites in compute_dominance_frontiers.
+
+2003-02-12 Andreas Jaeger <aj@suse.de>
+
+ * tree-dfa.c (dump_alias_info): Cast variable of size_t properly.
+
+2003-02-12 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-dfa.c (find_may_aliases_for): Remove
+ (compute_may_aliases): Always call compute_alias_sets.
+
+2003-02-10 Jeff Law <law@redhat.com>
+
+ * ssa.c (compute_dominance_frontiers_1): Use a sparse bitmap
+ for the frontiers.
+ (compute_dominance_frontiers): Corresponding changes.
+ (convert_to_ssa): Similarly. Convert the sparse bitmap to
+ a simple bitmap to avoid lots of collateral damage.
+ * ssa.h (compute_dominance_frontiers): Update prototype.
+ * tree-ssa.c (added, in_work): Kill, no longer needed.
+ (struct def_blocks_d): Add new bitmap (livein_blocks).
+ (rewrite_into_ssa): Make dominance frontiers be a sparse
+ bitmap instead of a simple bitmap. Rename the "nonlocals"
+ simple bitmap to "globals". Pass it into mark_def_sites.
+ (compute_global_livein): New function.
+ (mark_def_sites): Also keep track of variables which are
+ used before they are set. Allow caller to allocate and
+ pass in a simple bitmap for global variables. Process
+ items defined in the statement last.
+ (set_def_block): Also allocate bitmap for globals.
+ (set_livein_block): New function.
+ (def_blocks_free): Free def_blocks correctly. Also free
+ livein_blocks.
+ (debug_def_blocks_r): Also dump the livein_blocks.
+ (insert_phi_nodes): Simplify now that we don't need the
+ added and in_work varrays. Accept DFS as a sparse bitmap
+ instead of a simple bitmap.
+ (insert_phi_nodes_for): Rework significantly. Pre-compute all
+ the insertion points for semi-pruned form. While computing those
+ insertion points keep track of how many phi vector entries
+ would be needed at those insertion points. When the number of
+ entries gets large (32), compute global life information and
+ use that to further pruned the number of PHI insertion points
+ necessary.
+
+2003-02-09 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (find_vars_r): Assume that the RHS of an INDIRECT_REF,
+ that is also an SSA variable, is a VAR_DECL.
+ (get_virtual_var): Handle INDIRECT_REF nodes that are not valid SSA
+ variables.
+
+ * tree-ssa-dce.c (stmt_useful_p): Revert kludge in previous commit.
+ VA_ARG_EXPR nodes are not inherently live.
+
+ * tree-ssa.c (mark_def_sites): Don't process the LHS of assignments
+ twice.
+ The operand of a virtual definition constitutes a use of the
+ variable which should be considered a non-local if it had not been
+ killed inside the block.
+
+ * tree.h (SSA_VAR_P): Only return true for INDIRECT_REFs if their
+ operand is a _DECL node.
+
+2003-02-09 Diego Novillo <dnovillo@redhat.com>
+
+ * config/rs6000/t-rs6000 (simplify-rtx.o): Compile with -Wno-error.
+
+2003-02-08 Diego Novillo <dnovillo@redhat.com>
+
+ * toplev.c (parse_options_and_default_flags): Enable SSA DCE by
+ default.
+
+ * tree-dfa.c (get_expr_operands): Recurse into LHS of an ARRAY_REF
+ when it's not a regular variable. Always recurse into the RHS.
+ (add_stmt_operand): Set may_point_to_global_mem for pointers that
+ are assigned expressions that may reference global memory. Also
+ set its dereference variable to be an alias of global memory.
+ (dump_variable): Show may_point_to_global_mem flag.
+ (compute_alias_sets): Also dump all referenced variables when
+ dumping alias information.
+ (add_may_alias): Check for global memory aliasing.
+ (may_access_global_mem_p): Rename from may_access_global_mem.
+ Return true if the expression is a variable that may point to or
+ alias global memory.
+ (add_referenced_var): Pointer arguments and global pointers may
+ point to global memory.
+ (set_may_alias_global_mem): Move ...
+ * tree-flow-inline.h (set_may_alias_global_mem): ... here.
+ (set_may_point_to_global_mem): New function.
+ (may_point_to_global_mem_p): New function.
+
+ * tree-ssa-dce.c (stmt_useful_p): VA_ARG_EXPRs are inherently live.
+ * tree-ssa.c (rewrite_into_ssa): Don't call dump_referenced_vars.
+
+2003-02-06 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (struct alias_tags, alias_tags, num_alias_tags):
+ Remove. Update all users.
+ (struct alias_set_d): New.
+ (alias_sets): New file local variable.
+ (compute_alias_sets): New function.
+ (compute_may_aliases): Call it when not doing points-to analysis.
+ (register_alias_set): New function.
+ (find_alias_for): New function.
+ (may_alias_p): Declare static.
+ Don't assume that VAR may not be aliased if it's a non-addressable
+ _DECL.
+ If VAR and PTR are aggregate types, check if they can have a field
+ that points to the other one.
+ (find_may_aliases_for): Move handling of global memory aliasing ...
+ (add_may_alias): ... here.
+ Also accept the base symbols for the variable and its alias.
+ (register_new_alias): Remove. Update all users.
+ (find_alias_tag): Remove. Update all users.
+ (find_vars_r): Update VAR after re-writing *TP when sharing
+ INDIRECT_REF nodes.
+ * tree-flow.h (may_alias_p): Remove declaration.
+
+ * tree-ssa.c (rewrite_into_ssa): Include referenced variables in
+ default debug dumps.
+
+ Support for VLAs.
+
+ * tree-dfa.c (find_vla_decls): New function.
+ (compute_may_aliases): Call it.
+ (find_vla_decls_r): New function.
+ (dump_variable): Show whether the variable is used in a VLA
+ declaration.
+ * tree-flow-inline.h (is_vla_decl): New function.
+ (set_vla_decl): New function.
+ * tree-flow.h (struct var_ann_d): Add bitfield 'is_vla_decl'.
+ * tree-ssa-dce.c (need_to_preserve_store): Return true if SYM is
+ used inside a VLA declaration.
+
+2003-02-05 Andrew MacLeod <amacleod@redhat.com>
+
+ * Makefile.in : Include new file tree-iterator.h in tree-simple.h
+ * gimplify.c (simplify_cleanup_point_expr): Use tsi_ rather than gsi_.
+ * tree-cfg.c (make_blocks, remove_bb): Use tsi_ not gsi_ routines.
+ (bsi_remove): Renamed from gsi_remove, use bsi_ routines.
+ (successor_block, first_exec_stmt): Use tsi_ not gsi_ routines.
+ (first_stmt, last_stmt, last_stmt_ptr): Use bsi_ not gsi_ routines.
+ (bsi_init): Split out from bsi_start.
+ (bsi_start): Renamed from gsi_start_bb, use bsi_ routines.
+ (bsi_next_in_bb): Moved from tree-flow-inline.h and renamed from
+ gsi_step_in_bb. Also verify BB of new stmt.
+ * tree-dfa.c (compute_immediate_uses, dump_immediate_uses,
+ collect_dfa_stats, compute_may_aliases): Use block_stmt_iterator.
+ * tree-flow-inline.h (gsi_step_in_bb): Moved to tree-cfg.c
+ (bsi_end_p): Renamed from gsi_end_bb_p.
+ (bsi_next): renamed from gsi_step_bb
+ (bsi_prev): New function.
+ (bsi_stmt_ptr): Block version of gsi_stmt_ptr.
+ (bsi_stmt): Block version of gsi_stmt.
+ (bsi_container): Block version of gsi_container.
+ * tree-flow.h (block_stmt_iterator): New iterator type.
+ * tree-iterator.h: New include file for tree_iterator.
+ * tree-simple.h : Include tree-iterator.h
+ (gimple_stmt_iterator, gsi_start, gsi_end_p, gsi_stmt_ptr,
+ gsi_stmt, gsi_container): Move to tree-iterator.h and rename to tsi_.
+ (gsi_step): Move to tree-iterator.h and renamed to tsi_next.
+ * tree-ssa-ccp.c (simulate_block, substitute_and_fold): Use block
+ iterators instead of gimple_stmt_iterator.
+ * tree-ssa-dce.c (mark_control_parent_necessary, find_useful_stmts,
+ remove_dead_stmts, remove_dead_stmt): Use block_stmt_iterator.
+ * tree-ssa.c (mark_def_sites, rewrite_out_of_ssa, rewrite_stmts): Use
+ block_stmt_iterator.
+
+2003-02-04 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-common.c (get_alias_var_decl): If it's a global var,
+ make sure it doesn't get added to local_alias_vars.
+ (get_name): Return the right name for FUNCTION_DECL's.
+
+2003-02-04 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (add_stmt_operand): Do not add a VUSE for a pointer
+ when clobbering its associated INDIRECT_REF variable.
+
+2003-02-04 Diego Novillo <dnovillo@redhat.com>
+
+ * config/rs6000/t-rs6000 (jump.o, regmove.o, c-typeck.o, cfgrtl.o,
+ combine.o, fold-const.o, ifcvt.o, reload1.o, rtlanal.o,
+ cp/decl2.o, cp/pt.o, f/where.o, java/expr.o, objc/objc-act.o,
+ rs6000.o, insn-emit.o): Compile with -Wno-error.
+
+2003-02-03 Diego Novillo <dnovillo@redhat.com>
+ Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (make_blocks): Don't always start a new block with
+ COND_EXPR and SWITCH_EXPR statements.
+ Call stmt_ends_bb_p to determine if the current statement should be
+ the last in the block.
+ (make_cond_expr_blocks): Second argument is now the entry block
+ to the conditional.
+ (make_switch_expr_blocks): Second argument is now the entry block
+ to the switch.
+ (make_edges, make_ctrl_stmt_edges, make_loop_expr_edges,
+ cleanup_control_flow, cleanup_cond_expr_graph,
+ cleanup_switch_expr_graph, disconnect_unreachable_case_labels,
+ find_taken_edge, successor_block, latch_block, is_latch_block,
+ switch_parent): Work with the last statement of the block, not the
+ first.
+ (is_ctrl_altering_stmt): Pre-compute the code of the statement.
+ (stmt_starts_bb_p): Declare file local.
+ Don't call is_ctrl_stmt. Check if T is a LOOP_EXPR instead.
+ (stmt_ends_bb_p): New function.
+
+ * tree-flow.h (stmt_starts_bb_p): Remove declaration.
+
+2003-02-03 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (find_vars_r): Share INDIRECT_REF nodes whose operand
+ is a VAR_DECL.
+ (add_referenced_var): Add additional argument 'sym'. Update all users.
+ Don't call get_base_symbol.
+ (add_indirect_ref_var): Rename argument 'var' to 'ptr'.
+ (htab_hash_var): Remove. Update all users to use htab_hash_pointer.
+ (htab_var_eq): Remove. Update all users to use htab_eq_pointer.
+
+ * tree-flow-inline.h (var_ann): Don't retrieve the annotation of
+ the base pointer for INDIRECT_REF variables.
+ (is_aliased): Remove. Update all users.
+ (is_dereferenced): Remove. Update all users.
+ (same_var_p): Remove. Update all users to use pointer equality.
+
+ * tree-simple.c (get_base_symbol): Convert tail recursion into
+ iteration.
+
+ * tree-ssa.c (rewrite_out_of_ssa): Add FIXME note about overlapping
+ live ranges for different versions of the same variable.
+
+2003-02-03 Jeff Law <law@redhat.com>
+
+ * tree-dfa.c (add_referenced_var): Annotate each item in the
+ REFERENCED_VARS varray with a unique id.
+ * tree-flow.h (struct var_ann_d): Add new uid field.
+ * tree-ssa.c (mark_def_sites): Compute the set of variables
+ live across basic blocks and return them in an sbitmap.
+ (insert_phi_nodes): Use the set of nonlocal variables computed
+ by mark_def_sites to reduce the number of PHI nodes inserted.
+ (rewrite_into_ssa): Updated to deal with changes in
+ insert_phi_nodes and mark_def_sites. Free the sbitmap returned
+ by mark_def_sites.
+
+2003-02-03 Diego Novillo <dnovillo@redhat.com>
+
+ * c-common.h (GOTO_DESTINATION): Remove. Fix botched
+ merge.
+
+2003-02-03 Diego Novillo <dnovillo@redhat.com>
+
+ Fix warnings to allow bootstrapping with -Werror.
+
+ * Makefile.in (c-semantics.o-warn): Add -Wno-error.
+ (emit-rtl.o-warn): Likewise.
+ (profile.o-warn): Likewise.
+ (tree.o-warn): Likewise.
+ (OBJS): Remove simple-break-elim.o and simple-goto-elim.o.
+ * c-pretty-print.c (print_function_decl): Remove unused function.
+ * bitmap.c (bitmap_last_set_bit): Initialize variable 'word'.
+ * c-typeck.c (build_binary_op): Initialize variable 'type'.
+ * combine.c (combine_simplify_rtx): Initialize variable 'reversed'.
+ (make_compound_operation): Initialize variable 'i'.
+ * dwarf2out.c (dwarf2out_finish): Initialize variable 'context'.
+ * expr.c (store_constructor): Initialize variables 'lo', 'hi',
+ 'startb' and 'endb'.
+ (expand_expr): Initialize variable 'op0'.
+ * fold-const.c (fold): Initialize variable 'tem'.
+ * profile.c (branch_prob): Initialize variable 'prev_file_name'.
+ * reload.c (find_equiv_reg): Initialize variables 'valtry and
+ 'valueno'.
+ * rtlanal.c (get_jump_table_offset): Initialize variable 'set'.
+ * ssa-ccp.c (ssa_const_prop): Fix sign mismatch warning.
+ * varasm.c (output_constant_def): Initialize variable 'defstr'.
+ * gimplify.c (simplify_expr): Initialize variables
+ 'saved_input_filename' and 'saved_lineno'.
+ (simplify_compound_lval): Initialize variable 'code'.
+ * tree-alias-ander.c (pta_bottom): De-ansify.
+ (andersen_cleanup): Remove unused variables.
+ (andersen_heap_assign): Mark argument lhs ATTRIBUTE_UNUSED.
+ (pta_bottom): Remove unused function.
+ (pta_get_ptsize): Remove unused function.
+
+2003-02-02 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (get_expr_operands): Add a VUSE for the dereference of
+ every pointer passed in a function call.
+ Move code to add an operand for the base pointer of an
+ INDIRECT_REF ...
+ (add_stmt_operand): ... here.
+ Add a VUSE for the base pointer of every INDIRECT_REF variable.
+ (find_may_aliases_for): Fix starting index for the loop that scans
+ INDIRECT_REFs for aliasing.
+ Factor code that marks two variables aliased into
+ register_new_alias.
+ (register_new_alias): New function.
+ (may_alias_p): Handle aliasing of structure fields.
+ (add_may_alias): Fix documentation.
+ (find_vars_r): Factor code that adds a new referenced variable into
+ add_referenced_var.
+ (add_referenced_var): New function.
+ (add_indirect_ref_var): New function.
+ (get_virtual_var): Handle variables wrapped in SSA_NAMEs.
+ (set_may_alias_global_mem): Move from ...
+ * tree-flow-inline.h: ... here.
+
+ * tree-ssa-dce.c (need_to_preserve_store): CALL_EXPRs are
+ implicitly live. VA_ARG_EXPRs are not.
+ (stmt_useful_p):
+
+ * tree.h (SSA_NAME_VAR): Rename from SSA_NAME_DECL. Update all
+ users.
+ (struct tree_ssa_name): Rename field 'decl' to 'var'. Update all
+ users.
+ (SSA_DECL_P): Accept only VAR_DECLs and PARM_DECLs possibly wrapped
+ inside an SSA_NAME node.
+ (SSA_VAR_P): Also accept SSA_NAME nodes.
+
+2003-02-01 Daniel Berlin <dberlin@dberlin.org>
+
+ * Makefile.in (tree-ssa-pre2.o): Remove accidental addition.
+
+2003-01-31 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (find_taken_edge_cond_expr): New function.
+ (find_taken_edge_switch_expr): New function.
+ (value_matches_some_label): New function.
+ (find_taken_edge): Re-structure to use the three new functions.
+
+2003-01-30 Jason Merrill <jason@redhat.com>
+
+ * gimplify.c (simplify_function_tree): Set TREE_SIDE_EFFECTS on
+ the BIND_EXPR wrapper.
+
+2003-01-30 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (call_may_clobber): New function.
+ (get_expr_operands): Call it.
+ (find_vars_r): Call it.
+
+2003-01-30 Jeff Law <law@redhat.com>
+
+ * tree-dfa.c (struct alias_tags): New. Collector for key information
+ regarding alias tags.
+ (indirect_refs_base, indirect_refs_alias_set): New varrays.
+ (addressable_vars_base, addressable_vars_alias_set): Likewise.
+ (compute_may_aliases): Initialize and finalize the new varrays.
+ Update allocation of alias tags information.
+ (find_may_aliases_for): Extract base symbols and alias set
+ information for V1 and V2 from the virtual arrays and store
+ them into local variables. Pass them as necessary to
+ may_alias_p, may_access_global_mem, find_alias_tag. Add base
+ symbol and alias set when creating a new alias tag.
+ (find_vars_r): Fill in new varrays as needed.
+ (may_alias_p): Add new arguments for base and alias set of the
+ two origianl incoming arguments. No longer call get_base_symbol
+ or get_alias_set.
+ (find_alias_tag, may_access_global_mem): Similarly.
+ (add_stmt_operand): Update to pass additional argument to
+ may_access_global_mem.
+ (dump_alias_info): Update to deal with new alias tag structure.
+ * tree-flow.h (may_alias_p): Update prototype with new arguments.
+ * tree-ssa-pre.c (process_left_occs_and_kills): Update to pass
+ new arguments to may_alias_p.
+
+2003-01-30 Daniel Berlin <dberlin@dberlin.org>
+
+ Remove all traces of steensgaard's algorithm.
+ * tree-alias-steen.c: Removed.
+ * tree-alias-steen.h: Ditto.
+ * tree-alias-ecr.c: Ditto.
+ * tree-alias-ecr.h: Ditto.
+ * disjoint-set.c: Ditto.
+ * disjoint-set.h: Ditto.
+ * Makefile.in: Remove removed files.
+ * c-config-lang.in: Ditto.
+ * gengtype.c: Ditto.
+ * tree-alias-common.c: Don't use steen_alias_ops anymore.
+ * toplev.c: Remove help text and steen option.
+ * tree-alias-common.h: Remove PTA_STEEN.
+ * tree-alias-type.c: Remove all steensgaard related types and
+ functions.
+ * tree-alias-type.h: Ditto.
+
+2003-01-30 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (struct cfg_stats_d): New.
+ (cfg_stats): New file local.
+ (build_tree_cfg): Start TV_TREE_CFG timer before allocating memory.
+ Initialize cfg_stats.
+ (make_blocks): Count coalesced label blocks.
+ (dump_tree_cfg): Call dump_cfg_stats if TDF_STATS is enabled.
+ (dump_cfg_stats): New.
+ (debug_cfg_stats): New.
+
+ * tree-dfa.c (SCALE, LABEL, PERCENT): Move ...
+ * tree-flow.h: ... here
+
+2003-01-29 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (make_blocks): Do not start a new block if the
+ previous statement and the current statement are labels of the same
+ kind.
+
+2003-01-29 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (parent_array): Make file local.
+ (label_to_block_map): New file local variable.
+ (build_tree_cfg): Initialize label_to_block_map.
+ (make_edges): Don't pre-scan all the blocks looking for blocks with
+ labels.
+ (make_exit_edges): Remove argument label_to_block_map. Update all
+ callers.
+ (make_goto_expr_edges): Likewise.
+ (dump_tree_bb): Check that the block has a valid annotation.
+ (set_bb_for_stmt): If the statement is a label, add the label to
+ the label_to_block_map.
+
+ * tree-pretty-print.c (dump_vops): Check that the block has a valid
+ annotation.
+
+2003-01-29 Jeff Law <law@redhat.com>
+
+ * tree-dfa.c (find_may_aliases_for): Just accept the index of
+ the current indirect_ref. Caller updated.
+ (num_indirect_refs, num_addressable_vars): New variables.
+ (indirect_refs, addressable_vars): New varrays.
+ (dump_dfa_status): Dump info on the indirect refs and
+ addressable vars.
+ (dump_alias_info): Similarly.
+ (compute_may_aliases): Initialize and finalize the new virtual
+ arrays and hash tables for indirect refs and addressable vars.
+ Include setup/teardown in the cost for alias analysis.
+ (find_may_aliases_for): Split main loop into two. The first
+ walks over the indirect refs and takes advantage of the
+ symmetric properties of the aliasing relationship to avoid
+ useless work. The second loop iterates over the addressable
+ variables.
+ (find_vars_r): Rework to build all three arrays we need.
+
+2003-01-29 Andreas Jaeger <aj@suse.de>
+
+ * tree-alias-common.c (find_func_aliases): Remove unused variable.
+ (display_points_to_set_helper): #if 0 function to avoid warning
+ about unused function.
+
+ * tree-alias-ecr.c (ECR_new): Remove ISO C style function
+ definition.
+ * disjoint-set.c (disjoint_set_new): Likewise.
+
+2003-01-29 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mx_xfn_indirect_ref): Use a stack of flags for
+ tracking pointer dereference reads vs writes.
+ (mf_build_check_statement_for): Pass access-type value to __mf_check.
+ * c-mudflap.c (mflang_register_call): Adapt to mf-runtime.h API change.
+
+2003-01-29 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (ssa.o): Add dependency on $(TIMEVAR_H).
+ * timevar.def (TV_DOM_FRONTIERS): Define.
+ * ssa.c (compute_dominance_frontiers): Use.
+
+2003-01-29 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa-dce.c (remove_dead_stmt): Fix uninitialized use
+ warning.
+
+2003-01-28 Diego Novillo <dnovillo@redhat.com>
+
+ * timevar.def (TV_TREE_SSA_REWRITE_BLOCKS): Adjust legend.
+ * tree-ssa.c (rewrite_into_ssa): Use TV_TREE_SSA_REWRITE_BLOCKS.
+ (mark_def_sites): Add comment.
+
+2003-01-28 Jeff Law <law@redhat.com>
+
+ * ssa.c (compute_dominance_frontiers_1): Use get_dominated_by
+ to avoid useless walks over all the basic blocks. Use cache
+ of immediate dominators to avoid silly calls to get_immediate_dominator.
+ Do not clear elements of the frontiers bitmap.
+ (compute_dominance_frontiers): Compute cache of immediate
+ dominators and pass it to compute_dominance_frontiers_1. Clear
+ the entire vector of frontiers bitmaps.
+
+ * timevar.def (TV_TREE_SSA_REWRITE_BLOCKS): Renamed from
+ TV_TREE_BUILD_SSA.
+ (TV_TREE_SSA_OTHER): New timevar.
+ * tree-ssa.c (rewrite_into_ssa): Updated. Use new TV_TREE_SSA_OTHER
+ timevar.
+
+ * tree.h (LABEL_DECL_INDEX): Define for use by CFG builder.
+ * tree-cfg.c (make_exit_edges): Accept and pass though label to
+ block mapping array.
+ (make_goto_expr_edges): For simple gotos, lookup the destination
+ in the label to block mapping array. Zap old slow code to
+ handle simple gotos.
+ (make_edges): Build the label to block mapping array.
+
+ * tree.h (PHI_NODE_ELT_CHECK): Provide version when ENABLE_CHECKING
+ is not defined.
+
+2003-01-28 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-flow-inline.h (parent_block, set_parent_block, phi_nodes):
+ Assume that blocks always have valid annotations.
+ (add_dom_child): New function.
+ (dominator_children): New function.
+
+ * tree-flow.h (struct bb_ann_d): Add field 'dom_children'.
+
+ * tree-ssa.c (mark_def_sites): Add parameter 'idom'.
+ Add each block BB to the set of dominator children of BB's
+ immediate dominator.
+ (rewrite_block): Remove 'idom' parameter.
+ Recurse into blocks set in the dominator children bitmap.
+
+2003-01-28 Diego Novillo <dnovillo@redhat.com>
+
+ * flags.h (flag_disable_tree_ssa): New flag.
+ * c-decl.c (c_expand_body): Use it.
+ * toplev.c: Declare it.
+ (f_options): Add help text for -fdisable-tree-ssa.
+ * doc/invoke.texi: Add documentation for -fdisable-tree-ssa.
+
+2003-01-28 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (TREE_FLOW_H): Add dependency on $(HASHTAB_H)
+ (OBJS): Temporarily remove tree-ssa-pre.o.
+ (tree-ssa.o, c-decl.o): Add dependency on $(TREE_DUMP_H).
+
+ * c-decl.c: Include tree-dump.h
+
+ * c-pretty-print.c (dump_c_node): Fix rendering of GOTO_STMTs to
+ computed locations.
+ (op_prio): Don't abort on unknown operators.
+
+ * c-simplify.c (mostly_copy_tree_r): Don't copy statement
+ annotations.
+
+ * gimplify.c (simplify_addr_expr): Mark the RHS of the simplified
+ ADDR_EXPR addressable.
+ (mostly_copy_tree_r): Don't copy statement annotations.
+
+ * old-tree-inline.c (walk_tree): Handle SSA_NAME nodes.
+
+ * timevar.def (TV_TREE_RDEFS): Remove.
+ (TV_TREE_BUILD_SSA): Define.
+ (TV_TREE_DFA): Define.
+
+ * tree-cfg.c: Update copyright notices.
+ Remove doxygen markers everywhere.
+ (remove_unreachable_block): New local function
+ (remove_unreachable_blocks): Call it.
+ (remove_bb): Rename from remove_tree_bb. Update all callers.
+ (validate_loops): Remove unused function.
+ (block_invalidates_loop): Remove unused function.
+ (remove_stmt): Invalidate the defining statement of all the
+ definitions made by the statement.
+ Remove the annotation before replacing the statement with
+ empty_stmt_node.
+
+ * tree-dfa.c: Update copyright notices.
+ Remove doxygen markers everywhere.
+ (struct clobber_data_d): Remove existing fields. Add fields 'stmt'
+ and 'prev_vops'. Update all users.
+ (alias_tags): Rename from alias_leaders.
+ (num_alias_tags): Rename from num_alias_leaders.
+ (struct dfa_stats_d): Declare.
+ (struct dfa_counts_d): Remove. Update all users.
+ (TRM_*): Remove. Update all users.
+ (find_tree_refs): Remove. Update all users.
+ (get_stmt_operands): Rename from find_refs_in_stmt. Update all users.
+ (get_expr_operands): Rename from find_refs_in_expr. Update all users.
+ (add_stmt_operand): New function.
+ (set_def): New function.
+ (add_use): New function.
+ (add_vdef): New function.
+ (add_vuse): New function.
+ (create_phi_node): New function.
+ (copy_stmt): New function.
+ (compute_immediate_uses): New function.
+ (compute_immediate_uses_for): New function.
+ (compute_reached_uses): New function.
+ (compute_reaching_defs): New function.
+ (add_immediate_use): New function.
+ (create_var_ann): New function.
+ (create_stmt_ann): New function.
+ (dump_immediate_uses): New function.
+ (debug_immediate_uses): New function.
+ (dump_immediate_uses_for): New function.
+ (debug_immediate_uses_for): New function.
+ (create_ref_list, empty_ref_list, add_ref_to_list_begin,
+ add_ref_to_list_end, add_list_to_list_begin, add_list_to_list_end,
+ find_list_node, rli_start, rli_start_last, rli_start_at,
+ rli_delete, add_ref_to_list_after, tree_ref_size, create_ref,
+ add_ephi_arg, add_referenced_var, replace_ref_with,
+ try_replace_ref_with, replace_ref_r, replace_ref_stmt_with,
+ remove_ref, remove_def, reset_def_def_links, replace_phi_arg_with,
+ create_tree_ann, function_may_recurse_p, dump_ref, debug_ref,
+ dump_ref_list, dump_ref_array, debug_ref_list, debug_ref_array,
+ dump_phi_args, dump_if_different, count_tree_refs, ref_type_name,
+ ref_defines, is_killing_def, tree_ref_structure, output_ref):
+ Remove. Update all users.
+ (dump_referenced_vars): Remove parameter 'details'. Update all
+ users.
+ (dump_variable): Don't abort if the variable is nil. Display all
+ the aliases for the variable.
+ (dump_dfa_stats): Handle new counters.
+ (collect_dfa_stats): Likewise.
+ (collect_dfa_stats_r): Likewise.
+ (find_vars_r): New function.
+ (compute_may_aliases): Call it via walk_tree before computing aliases.
+ Only use alias tags if -ftree-points-to is not given.
+ Call add_may_alias.
+ (find_may_aliases_for): Only use alias tags if -ftree-points-to is
+ not given.
+ (add_may_alias): New function.
+ (find_alias_tag): Rename from find_alias_leader.
+ (dump_alias_info): New function.
+ (debug_alias_info): New function.
+ (htab_hash_var): New function.
+ (htab_var_eq): New function.
+ (get_virtual_var): New function.
+
+ * tree-dump.c (struct dump_option_value_info): Rename -block to
+ -blocks. Add new option -vops.
+ (dump_function): Don't display which pass enabled the dump.
+
+ * tree-flow-inline.h: Update copyright notices.
+ (var_ann): New function.
+ (stmt_ann): New function.
+ (ann_type): New function.
+ (bb_ann): Rename from bb_annotation.
+ (may_aliases): New function.
+ (set_may_alias_global_mem): New function.
+ (may_alias_global_mem_p): New function.
+ (set_indirect_ref): New function.
+ (indirect_ref): New function.
+ (is_dereferenced): New function.
+ (modify_stmt): New function.
+ (unmodify_stmt): New function.
+ (stmt_modified_p): New function.
+ (def_op): New function.
+ (use_ops): New function.
+ (vdef_ops): New function.
+ (vuse_ops): New function.
+ (immediate_uses): New function.
+ (reaching_defs): New function.
+ (phi_nodes): New function.
+ (same_var_p): New function.
+ (gsi_step_in_bb): Re-implement. Check if the iterator stepped out
+ of the block by calling bb_for_stmt.
+ (gsi_end_bb_p): Rename from gsi_end_bb. Update all users.
+ Call gsi_stmt to determine if the iterator has reached the end of
+ the block.
+ (ref_id, ref_type, ref_bb, ref_stmt, ref_var, imm_uses,
+ reached_uses, imm_reaching_def, set_imm_reaching_def,
+ set_phi_arg_def, phi_arg_def, set_phi_arg_edge, phi_arg_edge,
+ reaching_defs, phi_args, num_phi_args, phi_arg, set_phi_arg,
+ tree_annotation, tree_refs, add_tree_ref, remove_tree_ref,
+ alias_leader, set_alias_leader, set_tree_flag, clear_tree_flag,
+ reset_tree_flags, tree_flags, indirect_var, set_indirect_var,
+ bb_refs, remove_bb_ref, set_exprref_class, exprref_class,
+ set_exprref_inserted, exprref_inserted, set_exprref_save,
+ exprref_save, set_exprref_reload, exprref_reload,
+ set_exprref_processed, set_exprref_processed2, exprref_processed2i,
+ exprref_uses, set_exprref_uses, set_expruse_def, expruse_def,
+ set_expruse_phiop, expruse_phiop, set_expruse_phi, expruse_phi,
+ set_expruse_has_real_use, expruse_has_real_use,
+ set_exprphi_phi_args, exprphi_phi_args, num_ephi_args, ephi_arg,
+ set_ephi_arg, set_exprphi_downsafe, exprphi_downsafe,
+ set_exprphi_canbeavail, exprphi_canbeavail, set_exprphi_later,
+ exprphi_later, set_exprphi_extraneous, exprphi_extraneous,
+ exprphi_willbeavail, is_assignment_stmt, is_may_ref, is_may_def,
+ is_may_use, is_partial_ref, is_partial_use, is_volatile_ref,
+ is_volatile_def, is_volatile_use, is_clobbering_def,
+ is_relocating_def, is_addressof_use, is_pure_use, is_pure_def,
+ rli_after_end, rli_step, rli_step_rev, rli_ref, get_last_ref,
+ get_first_ref, ref_list_is_empty): Remove. Update all users.
+
+ * tree-flow.h: Update copyright notices.
+ Remove doxygen markers.
+ Include hashtab.h.
+ (enum tree_ann_type): New.
+ (struct tree_ann_common_d): New.
+ (struct var_ann_d): New.
+ (struct operands_d): New.
+ (struct voperands_d): New.
+ (operands_t): New type.
+ (voperands_t): New type.
+ (struct dataflow_d): New.
+ (dataflow_t): New type.
+ (struct stmt_ann_d): New.
+ (tree_ann): New type.
+ (var_ann_t): New type.
+ (stmt_ann_t): New type.
+ (bb_ann_t): Rename from bb_ann.
+ (enum tree_ref_type, TRM_*, struct ref_list_node, struct
+ ref_list_priv, ref_list, struct tree_ref_common, struct var_ref_d,
+ struct var_def_d, struct var_phi_d, struct var_use_d, struct
+ phi_node_arg_d, phi_node_arg, struct expr_ref_common, struct
+ expr_phi_d, struct expr_use_d, enum tree_ref_structure_enum, union
+ tree_ref_d, tree_ref, struct tree_ann_d, tree_ann, enum tree_flags,
+ struct dfa_counts_d, ref_list_iterator): Remove. Update all users.
+ (TDFA_USE_OPS): Define.
+ (TDFA_USE_VOPS): Define.
+
+ * tree-inline.c (walk_tree): Handle SSA_NAME nodes.
+
+ * tree-optimize.c: Update copyright notices.
+ Remove doxygen markers.
+ (optimize_function_tree): Temporarily disable call to
+ tree_perform_ssapre.
+ Remove #if0 code.
+
+ * tree-pretty-print.c (MASK_POINTER): Define.
+ (dump_vops): New function.
+ (dump_generic_node): Shorten made-up names for unnamed objects.
+ Hanlde PHI_NODE, VDEF_EXPR and SSA_NAME nodes.
+ Keep track of basic block transitions.
+ Call dump_vops if -vops dump option is given.
+ (op_prio): Don't abort if the operand is nil.
+ (dump_block_info): Don't keep track of basic block transitions.
+
+ * tree-simple.c: Update copyright notices.
+ (get_base_symbol): Call STRIP_NOPS.
+ Handle SSA_NAME nodes.
+
+ * tree-simple.h: Update copyright notices.
+ (gsi_end_p): Rename from gsi_end. Update all callers.
+
+ * tree-ssa-ccp.c: Update copyright notices.
+ Update code to use the new SSA infrastructure.
+ (const_values): New hash table to keep track of constants.
+ (struct value_map_d): New.
+ (cfg_edges): Rename from edges. Update all users.
+ (set_value): New function.
+ (get_value): New function.
+ (get_default_value): New function.
+ (value_map_hash): New function.
+ (value_map_eq): New function.
+
+ * tree-ssa-dce.c: Update copyright notice.
+ Update code to use new SSA infrastructure. Factor some code into
+ new functions.
+ (dom_info): Declare with file scope.
+ (struct stmt_stats): Add fields 'total_phis' and 'removed_phis'.
+ (needed_stmts): New hash table to keep track of needed statements.
+ (stmt_useful_p): New function.
+ (find_useful_stmts): Call it.
+ (remove_dead_stmt, remove_dead_phis): New functions.
+ (remove_dead_stmts): Call them.
+ (need_to_preserve_store): Preserve stores to volatile variables.
+ (tree_ssa_dce): Rename from tree_ssa_eliminate_dead_code. Update
+ all users.
+
+ * tree-ssa.c: Update copyright notice.
+ Change basic algorithm to rewrite the function into SSA form
+ instead of building factored use-def chains.
+ Include hashtab.h and tree-dump.h
+ (next_ssa_version): New global variable.
+ (def_blocks): New file local variable.
+ (struct def_blocks_d): New.
+ (currdefs): New file local variable.
+ (struct currdef_d): New.
+ (rewrite_into_ssa): Rename from build_tree_ssa. Update all users.
+ Call compute_may_aliases, mark_def_sites and rewrite_block.
+ (rewrite_block): Rename from search_fud_chains. Call
+ rewrite_stmts.
+ (mark_def_sites): New function.
+ (set_def_block): New function.
+ (rewrite_stmts): New function.
+ (rewrite_stmt): New function.
+ (rewrite_operand): New function.
+ (rewrite_out_of_ssa): New function.
+ (remove_phi_node): New function.
+ (register_new_def): New function.
+ (def_blocks_free): New function.
+ (def_blocks_hash): New function.
+ (def_blocks_eq): New function.
+ (currdef_hash): New function.
+ (currdef_eq): New function.
+ (debug_def_blocks): New function.
+ (debug_def_blocks_r): New function.
+ (build_fud_chains, compute_reaching_defs, follow_chain,
+ dump_reaching_defs, debug_reaching_defs, set_ssa_links): Remove.
+ (remove_phi_arg): Rename from tree_ssa_remove_phi_alternative.
+ Update all users.
+ (init_tree_ssa): Set next_ssa_version to 1.
+ Create hash tables def_blocks and currdefs.
+ (delete_tree_ssa): Accept a FUNCTION_DECL tree as argument. Update
+ all users.
+ (currdef_for): Add new parameter 'create_default'. If nonzero,
+ create a new SSA name if none is found for the variable.
+ (set_currdef_for): Search in the currdefs hash table.
+
+ * tree.c (tree_node_kind): Add new values phi_kind and
+ ssa_name_kind.
+ (tree_node_kind_names): Likewise.
+ (tree_size): Handle PHI_NODE and SSA_NAME nodes.
+ (make_node): Likewise.
+ (tree_node_structure): Likewise.
+ (phi_node_elt_check_failed): New function.
+ (make_phi_node): New function.
+ (make_ssa_name): New function.
+ (build_vdef_expr): New function.
+
+ * tree.def (SSA_NAME): New code.
+ (VDEF_EXPR): New code.
+ (PHI_NODE): New code.
+
+ * tree.h (union tree_ann_d): Forward declare.
+ (struct tree_common): Change type of field 'ann'.
+ (PHI_NODE_ELT_CHECK): Define.
+ (phi_node_elt_check_failed): Declare.
+ (VDEF_RESULT): Define.
+ (VDEF_OP): Define.
+ (SSA_NAME_DECL): Define.
+ (SSA_NAME_DEF_STMT): Define.
+ (SSA_NAME_VERSION): Define.
+ (struct tree_ssa_name): New.
+ (PHI_RESULT): Define.
+ (PHI_NUM_ARGS): Define.
+ (PHI_ARG_CAPACITY): Define.
+ (PHI_ARG_ELT): Define.
+ (PHI_ARG_EDGE): Define.
+ (PHI_ARG_DEF): Define.
+ (struct phi_arg_d): New.
+ (struct tree_phi_node): New.
+ (SSA_DECL_P): Define.
+ (SSA_VAR_P): Define.
+ (enum tree_node_structure_enum): Add values TS_SSA_NAME and
+ TS_PHI_NODE.
+ (union tree_node): Add fields 'ssa_name' and 'phi'.
+ (make_phi_node): Declare.
+ (make_ssa_name): Declare.
+ (build_vdef_expr): Declare.
+ (TDF_BLOCKS): Rename from TDF_BLOCK.
+ (TDF_VOPS): Define.
+
+ * doc/invoke.texi: Document new tree dump option -vops. Update
+ documentation for switch -blocks.
+
+2003-01-27 Jeff Law <law@redhat.com>
+
+ * gimplify.c (simplify_return_expr): Correctly handle return
+ expressions with side effects in functions returning void.
+
+ * tree-ssa-ccp.c (widen_bitfield): Do not try to widen anything
+ except constant integers.
+
+2003-01-26 Jeff Law <law@redhat.com>
+
+ * c-simplify.c (simplify_decl_stmt): Fix comment typo.
+ Use correct predicate when "simplifying" a static initializer.
+
+2003-01-26 Andreas Jaeger <aj@suse.de>
+
+ * Makefile.in (gt-dependence.h): New rule.
+
+2003-01-23 Jeff Law <law@redhat.com>
+
+ * c-simplify.c (simplify_decl_stmt): Arrange to examine initializers
+ for static variables.
+ * gimplify.c (simplify_constructor): Kill initial is_simple_constructor
+ check.
+ (simplify_modify_expr): Get the type from the destination rather than
+ the toplevel expression. Handle case where type is ARRAY_TYPE. Ignore
+ TREE_STATIC for the RHS.
+
+2003-01-24 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mf_varname_tree): Check for non-NULL DECL_NAME
+ before trying to cplus_demangle it.
+
+2003-01-23 Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (make_exit_edges): Fix thinkos.
+
+2003-01-22 Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (make_goto_expr_edges): Check the underlying
+ LABEL_DECL, not the LABEL_EXPR for FORCED_LABEL and NONLOCAL_LABEL.
+
+ * gimplify.c (simplify_expr, case GOTO_EXPR): Identify and mark
+ labels which are targets of nonlocal gotos and mark functions which
+ have labels which are targets of nonlocal gotos.
+ (simplify_expr, case LABEL_DECL): New case. Mark labels which
+ have their address taken.
+ * tree-cfg.c (is_nonlocal_label_block): Remove. All callers
+ updated.
+ (make_exit_edges, case GOTO_EXPR): Handle computed gotos sanely.
+ (make_exit_edges, case CALL_EXPR): Handle abnormal edges from
+ nonlocal gotos at call sites.
+ (make_exit_edges, case RETURN_EXPR): Likewise.
+ (make_exit_edges, case MODIFY_EXPR): New case to handle abnormal
+ edges from nonlocal gotos as call sites.
+ (make_goto_expr_edges): Handle computed gotos and nonlocal gotos.
+ (is_ctrl_altering_stmt): Handle abnormal edges in CALL_EXPRs
+ functions which receive nonlocal gotos. Similarly for CALL_EXPRs
+ which occur on the RHS of a MODIFY_EXPR.
+ * tree.h (FORCED_LABEL, NONLOCAL_LABEL): New defines.
+ (FUNCTION_RECEIVES_NONLOCAL_GOTO): Likewise.
+
+2003-01-22 Frank Ch. Eigler <fche@redhat.com>
+
+ * doc/invoke.texi: Provide some information about -fmudflap.
+
+ * tree-mudflap.c (mf_varname_tree): Conditionally invoke the C++
+ demangler in libiberty. Reduce function printing verbosity.
+ (mf_file_function_line_tree): Reduce function printing verbosity.
+ (mudflap_enqueue_decl): Use COMPLETE_TYPE_P to avoid trying to
+ register (get size of) void-typed objects.
+
+2003-01-21 Jose Renau <renau@uiuc.edu>
+
+ * tree-flow-inline.h (get_lineno): Return -1 for nodes without
+ locus information.
+ (get_filename): Return "???" for nodes without locus information.
+
+2003-01-21 Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (cleanup_switch_expr_graph): Wrap declaration of
+ switch_expr with ENABLE_CHECKING block.
+
+ * c-simplify.c (is_last_stmt_of_scope): Wrap definition and
+ declaration inside and ENABLE_CHECKING block.
+
+2003-01-20 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mx_xfn_indirect_ref): Use new TREE_LOCUS field
+ as a predicate for finding TREE_FILENAME etc.
+
+2003-01-16 Daniel Berlin <dan@dberlin.org>
+
+ * Remove dead PRE code.
+ * tree-ssa-pre.c (tree_perform_ssapre): Collect left occurrences and
+ kills *after* finishing collecting all expressions.
+
+2003-01-15 Jeff Law <law@redhat.com>
+
+ * Death to WFL nodes.
+ * c-aux-info.c: Replace DECL_SOURCE_FILE and DECL_SOURCE_LINE with
+ TREE_FILENAME and TREE_LINENO respectively when retrieving file
+ and line information. Use TREE_LOCUS to copy existing information
+ from one node to another. Use annotate_with_file_line to add or
+ replace location information on a node. Remove support for
+ EXPR_WITH_FILE_LOCATION nodes. Remove STRIP_WFL statements.
+ * c-common.c, c-parse.in, c-pretty-print.c, dbxout.c: Likewise.
+ * diagnostic.c, dwarf2out.c, dwarfout.c: Likewise.
+ * except.c, integrate.c, stmt.c, tree-alias-common.c: Likewise.
+ * tree-cfg.c, tree-dfa.c, tree-dump.c, tree-flow-inline.h: Likewise.
+ * tree-mudflap.c, tree-pretty-print.c, tree-simple.c: Likewise.
+ * tree-ssa-ccp.c, tree-ssa-dce.c, tree-ssa-pre.c: Likewise.
+ * varasm.c, xcoffout.c: Likewise.
+ * config/alpha/alpha.c: Likewise.
+ * config/mips/mips.c: Likewise.
+ * c-decl.c: Likewise.
+ (duplicate_decls): Also copy TREE_LOCUS from olddecl to newdecl.
+ (finish_function): Save and restore the current filename and
+ linenumber around genericizing of the function tree.
+ * c-simplify.c (c_simplify_stmt): Use annotate_all_with_file_line
+ instead of wrap_all_with_wfl. Remove STRIP_WFL statements.
+ * expr.c (expand_expr): Emit line number notes for expressions
+ with attached file/line information. Remove EXPR_WITH_FILE_LOCATION
+ support.
+ * gimplify.c: Kill STRIP_WFL statements. Remove EXPR_WITH_FILE_LOCATION
+ support.
+ (simplify_expr_wfl): Kill.
+ (annotate_stmt_with_file_line): Renamed from wrap_with_wfl.
+ (annotate_all_with_file_line): Renamed from wrap_all_with_wfl.
+ (simplify_expr): Save and restore the current file/line around
+ simplification of the given expression. Add annotation to more
+ nodes created during simplification.
+ (simplify_self_mod_expr): Add file/line location to nodes we create.
+ (get_initialized_tmp_var): Similarly.
+ * old-tree-inline.c (expand_call_inline): Use annotate_with_file_line
+ to add file/line information to nodes instead of wrapping them
+ with EXPR_WITH_FILE_LOCATION nodes.
+ * print-tree.c: Use TREE_FILENAME and TREE_LINENO instead of
+ DECL_SOURCE_FILE and DECL_SOURCE_LINE respectively. Remove
+ support for EXPR_WITH_FILE_LOCATION nodes.
+ (print_node): Dump any file/line information that is attached to
+ the given node.
+ * tree-inline.c (walk_tree): Set lineno appropriately.
+ * tree-simple.h (annotate_all_with_file_line): Renamed from
+ wrap_all_with_wfl. Remove STRIP_WFL statements.
+ * tree.c (build_expr_wfl): Kill.
+ (make_node): Use annotate_with_file_line.
+ (annotate_with_file_line): New function.
+ * tree.def: Remove EXPR_WITH_FILE_LOCATION.
+ * tree.h (tree_common): Add locus field. Remove references to
+ EXPR_WITH_FILE_LOCATION.
+ (tree_decl): Remove locus field.
+ (STRIP_WFL, EXPR_WFL_*): Kill.
+ (DECL_SOURCE_LOCATION, DECL_SOURCE_FILE, DECL_SOURCE_LINE): Kill.
+ (TREE_LOCUS, TREE_FILENAME, TREE_LINENO): new.
+ (annotate_with_file_line): Renamed from build_expr_wfl.
+
+ * objc/objc-act.c: Use TREE_FILENAME and TREE_LINENO to
+ extract file/line information from tree nodes.
+
+2003-01-14 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mx_xfn_indirect_ref): Handle ARRAY_REF of
+ a COMPONENT_REF specially to avoid unnecessary checks.
+
+2003-01-13 Frank Ch. Eigler <fche@redhat.com>
+
+ Front-end generalization.
+ * Makefile.in (C_AND_OBJC_OBJS): Add c-mudflap.o and dependencies.
+ * tree-mudflap.c: Don't include "c-tree.h" any more.
+ (mf_init_extern_trees): Divert to mflang_lookup_decl().
+ (mf_enqueue_register_call, mf_flush_enqueued_calls): Move and rename
+ these functions.
+ * tree-mudflap.h: Declare new mflang_* routines.
+ * c-mudflap.c: New file with C front-end mflang_* routines.
+ * tree-nomudflap.c (*): Call internal_error instead of abort.
+
+2003-01-07 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * Makefile.in (check-g95): New test target.
+ (check-f95): Alias for check-g95.
+
+2003-01-07 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dump.c (dump_function_to_file): New function.
+ (dump_function): Call it.
+ Convert argument declaration to K&R format.
+ * tree-dump.h: Include splay-tree.h.
+ (dump_function_to_file): Declare.
+
+ * tree-optimize.c (optimize_function_tree): Remove unused variables
+ dump_file and dump_flags.
+ (dump_current_function): Remove. Update all users by calling
+ dump_function instead.
+ * tree.h (dump_current_function): Remove declaration.
+
+ * Makefile.in (TREE_DUMP_H): Define.
+ Update targets depending on tree-dump.h to depend on $(TREE_DUMP_H).
+ (tree-ssa-cp.o): Remove unused target.
+ (tree-cfg.o): Add dependency on $(TREE_DUMP_H).
+ (tree-optimize.o): Likewise.
+ (tree-ssa-dce.o): Likewise.
+ (tree-ssa-ccp.o): Likewise.
+ (tree-ssa-pre.o): Likewise.
+
+2003-01-02 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (rename_2): Fix a false matching condition.
+ This is actually fallout from is_default_def change.
+
+2003-01-02 Jason Merrill <jason@redhat.com>
+
+ * c-simplify.c (c_genericize): Dump more info about the function.
+ Use dump_function.
+ * tree-dump.c (dump_function): Move from cp/optimize.c.
+ * tree-dump.h: Declare it.
+
+ * gimplify.c (mostly_copy_tree_r): Remove unnecessary cases.
+ (unshare_expr): New fn.
+ * tree-inline.c (mark_local_for_remap_r, unsave_r): New fns, adapted
+ from C++ versions.
+ (lhd_unsave_expr_now): Likewise.
+ * tree.c (unsave_expr_now): Remove.
+ (unsafe_for_reeval): Labels and BIND_EXPRs are only somewhat unsafe.
+
+ * gimplify.c (simplify_function_tree): Add an outer BIND_EXPR if
+ needed.
+ (voidify_wrapper_expr): Not static. Abort if we try to voidify an
+ expression with TREE_ADDRESSABLE type. Be clever with INDIRECT_REFs.
+ (foreach_stmt): Avoid redundant work.
+ (create_tmp_var): Abort if we try to create a temp of ADDRESSABLE type.
+ (simplify_expr): Simplify VTABLE_REF.
+ * c-simplify.c (simplify_decl_stmt): Ignore DECL_EXTERNAL decls.
+ (simplify_stmt_expr): Fix thinko.
+ (simplify_block): Don't ignore partial scopes.
+ (simplify_condition): New fn.
+ (simplify_c_loop, simplify_if_stmt, simplify_switch_stmt): Call it.
+ * expr.c (expand_expr) [BIND_EXPR]: Handle statics better.
+ * tree-inline.c (remap_decl): Remap all decls.
+ (declare_return_variable): Be clever with INDIRECT_REFs.
+ (expand_call_inline): If we have an explicit return slot, the inlined
+ body is void.
+ (walk_tree): Fix type handling.
+ (copy_tree_r): Don't walk into decls.
+ * tree-simple.c (is_simple_unary_expr): Handle VTABLE_REF.
+ (is_simple_id): Allow RESULT_DECL.
+ * tree-simple.h (gsi_stmt): Strip WFLs and NOPs.
+
+ * gimplify.c (simplify_cond_expr): Handle void arms. Add target parm.
+ (simplify_modify_expr): Pass it. Add special handling for COND_EXPR
+ and CONSTRUCTOR (from Daniel Berlin). Add want_value parm.
+ (simplify_expr): Pass new args. Loop sooner if language-specific
+ simplification happened.
+ (simplify_return_expr): Pass the whole MODIFY_EXPR to simplify_expr.
+ (simplify_target_expr): Simplify.
+
+ * tree.def (CATCH_EXPR, EH_FILTER_EXPR): New tree codes.
+ * except.c (expand_eh_handler): New fn.
+ (expand_eh_region_end_allowed): If no types are allowed, hand off to
+ expand_eh_region_end_must_not_throw.
+ * except.h: Declare expand_eh_handler.
+ * expr.c (expand_expr) [TRY_CATCH_EXPR]: Use it.
+ [CATCH_EXPR, EH_FILTER_EXPR]: New cases.
+ * gimplify.c (simplify_expr) [EXC_PTR_EXPR, CATCH_EXPR,
+ EH_FILTER_EXPR]: New cases.
+ (gimple_build_eh_filter): New fn.
+ (maybe_protect_cleanup): New fn.
+ (gimple_push_cleanup): Call it.
+ (simplify_cleanup_point_expr): Fix thinko.
+ * c-simplify.c (simplify_cleanup): Call it.
+ * tree-simple.h: Declare it.
+ * Makefile.in (gimplify.o): Depend on except.h.
+ * tree.h (CATCH_TYPES, CATCH_BODY): New macros.
+ (EH_FILTER_TYPES, EH_FILTER_FAILURE): New macros.
+ * tree-simple.c (is_simple_id): Allow EXC_PTR_EXPR.
+ * c-pretty-print.c (dump_c_node) [CLEANUP_POINT_EXPR]: Support.
+ * tree-pretty-print.c (dump_generic_node): Likewise.
+ [CATCH_EXPR, EH_FILTER_EXPR, EXC_PTR_EXPR]: Support.
+
+ * c-pretty-print.c (NIY): Print operands.
+ (dump_c_tree): Don't look at TREE_CHAIN if it doesn't matter.
+ (dump_c_node) [ARRAY_TYPE]: Handle non-constant array bounds.
+ [CALL_EXPR]: Pass spc down.
+ [VTABLE_REF]: Support.
+ (op_prio) [TARGET_EXPR]: Support.
+ (print_call_name): Handle function pointers.
+ * tree-pretty-print.c: Likewise.
+
+2002-12-31 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * gimplify.c (create_tmp_var_noc): Remove unused function.
+ * tree-simple.h: Kill prototype.
+
+2002-12-30 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-flow.h (tree_find_loops): Remove unused declaration.
+
+2002-12-29 Daniel Berlin <dberlin@dberlin.org>
+
+ * toplev.c: Add flag_ip, enable by default at -O4+ (This is not
+ set in stone, and thus, not documented).
+ (decode_f_option): Add warning if andersen's PTA is selected but
+ not compiled in.
+
+ * flags.h: Add flag_ip.
+
+ * tree-alias-ander.c: Fix todo.
+ (andersen_function_call): Return 1 if we don't need to process
+ the function.
+ (ptset_map): New map, cache points-to sets.
+ (andersen_op): We can do IP on all statics without help.
+ (andersen_init): Only init once if we are doing ip analysis.
+ (andersen_cleanup): Don't cleanup if we need the info for ip.
+ (andersen_add_var): Clear points-to set if it exists already.
+ (andersen_add_var_same): Ditto.
+ (andersen_function_call): We can do interprocedural analysis on
+ statics.
+ (andersen_may_alias): Cache points-to sets.
+
+ * c-decl.c (c_expand_body): Don't throw away tree if flag_ip is
+ on, even if they are uninlinable, they may be wanted for ip
+ optimizations.
+
+ * tree-alias-common.c (get_values_from_constructor): New
+ function to collect alias_typevars from constructors.
+ (alias_annot): Fix where the GTY is so gengtype picks it up.
+ (intra_function_call): Ignore non-pointers for global var
+ assignment. What arguments point to can now point to a global var
+ as well.
+ (find_func_aliases): We need to handle decl's with initials as
+ well.
+ Only call intra_function_call if we have to.
+ Handle constructors.
+ (create_fun_alias_var): Incoming pointer arguments could be
+ pointing to a global var, unless this is a static function and we
+ are doing interprocedural analysis.
+ (create_alias_vars): Take an fndecl argument, and use it.
+ (init_alias_vars): Handle ip_partial as well.
+ (ptr_may_alias_var): Simplify, fix.
+
+ * tree-alias-common.h (tree_alias_ops): function_call now returns
+ an int, and we have an extra member named ip_partial.
+
+ * tree-alias-steen.c (steen_ops): We can't do ip_partial.
+ (steen_function_call): Update definition and return 1.
+
+ * tree-dfa.c (compute_may_aliases): Call create_alias_vars with
+ current_function_decl.
+
+ * tree-flow.h (create_alias_vars): Remove proto from here, it's
+ in tree-alias-common.h.
+ (tree_perform_ssapre): Take a tree, like the other optimizers.
+
+ * tree-optimize.c (optimize_function_tree): Call
+ tree_perform_ssapre with a tree.
+
+ * tree-ssa-pre.c: Remove dead, #if 0'd code.
+ (tree_perform_ssapre): Use passed in tree.
+
+2002-12-23 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mf_decl_cache_locals, mf_decl_clear_locals): New
+ functions.
+ (mudflap_c_function): Call them before/after basic transforms.
+ (mf_cache_shift_decl_l, ..._mask_l): New variables to track local
+ VAR_DECL shadows of cache parameters.
+ (mf_build_check_statement_for): Use and update them.
+
+2002-12-23 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mx_register_decls): Trust incoming TREE_ADDRESSABLE
+ instead of own timetaking analysis.
+ (mf_find_addrof, mx_xfn_find_addrof): Removed functions.
+
+2002-12-23 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * tree-dfa.c: Add doxygen markers in comments.
+
+2002-12-22 Diego Novillo <dnovillo@redhat.com>
+
+ * gimplify.c: Undo the following change:
+ 2002-12-11 Diego Novillo <dnovillo@redhat.com>
+ * gimplify.c (simplify_return_expr): return statements should
+ only have a GIMPLE value as argument.
+
+ * tree-simple.c: Fix grammar for return statements.
+
+2002-12-20 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mf_init_extern_trees): Rewrite last change
+ without using statement-expressions.
+
+2002-12-19 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (build_tree_cfg): Make sure that TV_TREE_CFG
+ is popped properly.
+
+2002-12-19 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mf_init_extern_trees): Abort gracefully if
+ <mf-runtime.h> was not included.
+ (*): Correct some minor compiler warnings elsewhere.
+
+2002-12-18 Diego Novillo <dnovillo@redhat.com>
+
+ * configure: Regenerate with autoconf 2.13.
+
+2002-12-17 Ben Elliston <bje@redhat.com>
+
+ * tree-optimize.c (optimize_function_tree): Temporarily
+ disable SSA optimizations if -fmudflap is present.
+
+2002-12-16 Ben Elliston <bje@redhat.com>
+
+ * tree-mudflap.c (mx_flag): Assert that the tree node is valid.
+
+2002-12-14 Jason Merrill <jason@redhat.com>
+
+ * tree-dump.c (dump_files): Add .generic. Move .inlined after it.
+ * tree.h (tree_dump_index): Likewise.
+ * c-simplify.c (c_genericize): Emit original and generic dumps here.
+ * c-decl.c (c_expand_body): Not here.
+
+2002-12-13 Ben Elliston <bje@redhat.com>
+
+ * tree-dfa.c (find_refs_in_expr): Terminate comment.
+
+2002-12-12 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * tree-cfg.c: Update doxygen documentation.
+ * tree-dfa.c: Add doxygen documentation.
+
+2002-12-11 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * tree-cfg.c: Add doxygen markers in comments.
+ * tree-optimize.c: Likewise.
+ * tree-ssa.c: Likewise.
+
+2002-12-11 Diego Novillo <dnovillo@redhat.com>
+
+ * gimplify.c (simplify_return_expr): return statements should only
+ have a GIMPLE value as argument.
+ * tree-cfg.c (call_expr_flags): New function.
+ (is_ctrl_altering_stmt): Call it.
+ * tree-flow.h (extern): Declare it.
+
+2002-12-06 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (make_goto_expr_edges): Temporary hack to prevent
+ removing blocks with nonlocal labels.
+ (is_nonlocal_label_block): Return true if DECL_NONLOCAL is set for
+ the label.
+
+ * tree-dfa.c (alias_leaders): New local array.
+ (num_alias_leaders): New local variable.
+ (find_alias_leader): New local function.
+ (may_access_global_mem): New local function.
+ (find_may_aliases_for): Call them.
+ (compute_may_aliases): Allocate and deallocate alias_leaders.
+ Show alias information if -fdump-tree-...-alias flag is given.
+ (may_alias_p): Return true if both variables are the same.
+ (find_refs_in_expr): Strip WFL and NOPs from the parent statement.
+ If a pointer relocation is due to a function call, assignment from
+ a global or a function argument, mark the pointer as a may-alias
+ for global storage.
+ (dump_referenced_vars): Reformat output.
+ (dump_variable): Likewise.
+
+ * tree-dump.c (dump_option_value_info): Add entry for TDF_ALIAS.
+ * tree.h (TDF_ALIAS): Define.
+ * doc/invoke.texi: Document new flag.
+
+ * tree-flow-inline.h (may_alias_global_mem_p): New function.
+ * tree-flow.h (enum tree_flags): Add value TF_MAY_ALIAS_GLOBAL_MEM.
+ (may_alias_global_mem_p): Declare.
+
+ * tree-simple.c (get_base_symbol): Return NULL_TREE, not NULL.
+ * tree-ssa-ccp.c (tree_ssa_ccp): Remove unused variable.
+ * tree-ssa-dce.c (need_to_preserve_store): Call
+ decl_function_context instead of DECL_CONTEXT.
+ If the symbol may alias global memory, return nonzero.
+
+ * tree-ssa.c (dump_reaching_defs): Reformat output.
+ (set_currdef_for): Walk the alias leader chain, setting CURRDEF for
+ all the alias sets that may be affected by the definition.
+
+2002-12-06 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-dfa.c (may_alias_p): Fix global variables and points-to.
+
+2002-12-03 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa.c (delete_tree_ssa): Move call to delete_alias_vars
+ above resetting num_referenced_vars.
+
+2002-12-03 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in: Add dependencies on $(TM_H) and coretypes.h for the
+ files mentioned below.
+ * old-tree-inline.c: Include tm.h and coretypes.h.
+ * c-pretty-print.c: Likewise.
+ * disjoint-set.c: Likewise.
+ * tree-alias-ecr.c: Likewise.
+ * tree-alias-type.c: Likewise.
+ * tree-alias-ander.c: Likewise.
+ * tree-alias-steen.c: Likewise.
+ * tree-alias-common.c: Likewise.
+ * tree-ssa.c: Likewise.
+ * tree-ssa-pre.c: Likewise.
+ * tree-cfg.c: Likewise.
+ * tree-dfa.c: Likewise.
+ * tree-optimize.c: Likewise.
+ * c-simplify.c: Likewise.
+ * gimplify.c: Likewise.
+ * tree-browser.c: Likewise.
+ * simple-break-elim.c: Likewise.
+ * simple-goto-elim.c: Likewise.
+ * tree-dchain.c: Likewise.
+ * c-call-graph.c: Likewise.
+ * tree-simple.c: Likewise.
+ * tree-nomudflap.c: Likewise.
+ * tree-pretty-print.c: Likewise.
+ * tree-ssa-dce.c: Likewise.
+ * tree-ssa-ccp.c: Likewise.
+ * dependence.c: Likewise.
+ * tree-mudflap.c: Likewise
+ (mx_xfn_indirect_ref): Use size_type_node instead of c_size_type_node.
+
+2002-12-03 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c: Undo this change that causes bootstrap
+ failures:
+
+ 2002-12-02 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (may_alias_p): Artificial variables
+ can also be aliased.
+
+2002-12-03 Andreas Jaeger <aj@suse.de>
+
+ * tree-simple.c (right_assocify_expr): Remove unused variable.
+
+2002-12-02 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimplify.c (simplify_cleanup_point_expr): gsi_stmt can return NULL,
+ use gsi_end.
+ * tree-cfg.c (make_blocks): Use gsi_end, gsi_stmt can return NULL. Set
+ basic_block for empty_stmt_node containers.
+ (make_edges): Stmt's can be NULL.
+ (make_ctrl_stmt_edges, make_exit_edges, make_loop_expr_edges,
+ make_cond_expr_edges, make_goto_expr_edges, is_nonlocal_label_block,
+ block_invalidates_loop, cleanup_control_flow, cleanup_cond_expr_graph,
+ cleanup_switch_expr_graph, disconnect_unreachable_case_labels,
+ find_taken_edge, tree_cfg2dot, successor_block, is_latch_block,
+ switch_parent, first_stmt, last_stmt): Check for first_stmt() or
+ last_stmt() returning NULL.
+ (remove_tree_bb, first_exec_stmt): Use gsi_end.
+ (last_stmt_ptr): Iterate to find last execuatbel stmt_ptr in a block.
+ (gsi_start_bb): Return first non-empty stmt, if there is one.
+ (set_bb_for_stmt): Don't decend into an empty_stmt_node.
+ * tree-dfa.c (find_tree_refs): Use gsi_end.
+ (collect_dfa_stats): Use gsi_end_bb.
+ * tree-flow-inline.h (gsi_step_bb): split.
+ (gsi_step_in_bb): gsi_step with explicit bb specified. Never return
+ empty_stmt_node.
+ (gsi_start_bb): Move to tree-cfg.c.
+ (gsi_end_bb): New. Have we reached the end of a basic block.
+ * tree-flow.h (gsi_start_bb): Make external.
+ (gsi_end_bb, gsi_step_in_bb): New prototypes.
+ * tree-simple.h (gsi_end): renamed from gsi_after_end.
+ (gsi_stmt): Return NULL if stmt is an empty_stmt_node or error mark.
+ * tree-ssa-ccp.c (simulate_block, substitute_and_fold): Use gsi_end.
+ * tree-ssa-dce.c (mark_control_parent_necessary, find_useful_stmts,
+ remove_dead_stmts): Use gsi_end_bb.
+ (process_worklist): Check for NULL last_stmt.
+ * tree-ssa-pre.c (finalize_1): Use gsi_end_bb, gsi_stmt can be NULL.
+
+2002-12-02 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (dump_ref): Display '<nil>' for NULL references.
+ (dump_phi_args): Handle NULL arguments.
+ (may_alias_p): Artificial variables can also be aliased.
+
+2002-12-02 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (okay_injuring_def): inj could be null.
+ (get_operand): Use instead of special casing INDIRECT_REF and
+ COMPONENT_REF everywhere.
+ (names_match_p): Fix.
+ (defs_match_p): Ignore partial uses.
+ (rename_2): Fix non-matching condition.
+ (update_old_new): Update the kills and lefts arrays.
+ (finalize_1): Set the bb for the new statement.
+ (update_ssa_for_new_use): Ditto.
+ (code_motion): Ditto.
+ (call_modifies_slot): Handle function pointers (where we end up
+ with a _DECL as our argument).
+ (pre_part_1_trav): Update the kills and lefts arrays.
+ Just use TREE_TYPE (ei->expr) for type of expression.
+ (add_left_occ): New helper function.
+ (process_left_occs_and_kills): Add other cases we need to handle.
+ (tree_perform_ssapre): Add new processed array, since for left
+ occurrences and kills, we need to process *all* statements, not
+ just ones we might consider candiates for PRE.
+
+2002-12-02 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (find_refs_in_expr): Look for references in
+ VA_ARG_EXPR nodes.
+
+2002-12-01 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-optimize.c (optimize_function_tree): Undo
+ inadvertent change in previous commit.
+
+2002-12-01 Diego Novillo <dnovillo@redhat.com>
+
+ * fold-const.c (operand_equal_p): Check for NULL TREE_TYPEs.
+
+ * tree-cfg.c (remove_stmt): Call remove_ref.
+ (disconnect_unreachable_case_labels): Do not disconnect the edge
+ going to the block holding the BIND_EXPR node for the switch()
+ body.
+ (dump_tree_cfg): Call dump_current_function.
+
+ * Makefile.in (tree-dfa.o): Depend on convert.h.
+ * tree-dfa.c: Include convert.h.
+ (remove_def): New local function.
+ (reset_def_def_links): New local function.
+ (replace_phi_arg_with): New local function.
+ (replace_ref_with): New function.
+ (try_replace_ref_with): Rename from replace_ref_in.
+ Also look for V_USE references on the LHS of assignments.
+ When replacing the callee of a CALL_EXPR, make sure that the type
+ of the new callee is compatible with the old one.
+ (replace_ref_r): Call operand_equal_p.
+ (remove_ref): New function.
+ (same_var_p): New function.
+ (dump_referenced_vars): Add new flag DETAILS. Update all users.
+ (debug_referenced_vars): Likewise.
+
+ * tree-ssa.c (dump_reaching_defs): Change output format.
+ (set_ssa_links): Don't set def-def links for PHI nodes.
+
+ * tree-ssa-ccp.c (replace_uses_in): Add new argument COMMIT.
+ Update all users.
+
+ * tree-optimize.c (dump_current_function): New function.
+ (optimize_function_tree): Call it.
+ * tree.h (dump_current_function): Declare.
+ * c-decl.c (c_expand_body): Call dump_current_function.
+ * tree-ssa-dce.c (tree_ssa_eliminate_dead_code): Likewise.
+ * tree-ssa-pre.c (tree_perform_ssapre): Likewise.
+ * tree-ssa.c (build_tree_ssa): Likewise.
+ * tree-ssa-ccp.c (tree_ssa_ccp): Likewise.
+ Dump variables and reaching definitions if TDF_DETAILS is set.
+
+ * tree-pretty-print.c (print_call_name): Call dump_generic_node for
+ NOP_EXPR operands.
+
+ * tree-ssa-pre.c: Don't include c-common.h nor c-tree.h
+ Replace calls to build_modify_expr with build everywhere.
+ Replace calls to deep_copy_node with copy_node_r everywhere.
+
+2002-11-29 Andreas Jaeger <aj@suse.de>
+
+ * c-call-graph.c (construct_call_graph): Fix format.
+
+ * tree-alias-ander.c: Declare print_out_result.
+
+ * tree-ssa-pre.c: Declare is_on_lhs and call_modifies_slot.
+
+ * tree.h: Declare expand_asm_expr and add_var_to_bind_expr.
+
+ * tree-inline.c: Declare remap_decls.
+
+2002-11-28 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-common.h: Start adding doxygen docs.
+
+ * tree-alias-common.c: Ditto
+
+2002-11-28 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-ander.c: Convert debug defines and ifdefs into
+ dump_file use.
+
+ * tree.h: Add TDI_pta.
+
+ * tree-dump.c: Add dump-tree-pta and TDI_pta.
+
+2002-11-28 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree-ssa-pre.o, tree-cfg.o, gimplify.o, tree-ssa-dce.o,
+ tree-ssa-ccp.o): Add dependency on $(TIMEVAR_H).
+ * timevar.def (TV_TREE_GIMPLIFY, TV_TREE_MAY_ALIAS,
+ TV_TREE_INSERT_PHI_NODES, TV_TREE_BUILD_FUD_CHAINS, TV_TREE_RDEFS):
+ New timers.
+ (TV_TREE_SSA): Remove.
+ (TV_INTEGRATION, TV_EXPAND): Switch order.
+ * c-decl.c (c_expand_body): Pop TV_EXPAND before running the tree
+ optimizers.
+ * gimplify.c (simplify_function_tree): Push/pop TV_TREE_GIMPLIFY.
+ * tree-cfg.c (build_tree_cfg): Push/pop TV_TREE_CFG.
+ * tree-dfa.c (compute_may_aliases): Push/pop TV_TREE_MAY_ALIAS.
+ * tree-ssa-ccp.c (tree_ssa_ccp): Push/pop TV_TREE_CCP.
+ * tree-ssa-dce.c (tree_ssa_eliminate_dead_code): Push/pop
+ TV_TREE_DCE.
+ Call compute_reaching_defs.
+ Remove debugging dumps before DCE.
+ * tree-ssa-pre.c (tree_perform_ssapre): Push/pop TV_TREE_PRE.
+ * tree-ssa.c (build_tree_ssa): Don't call compute_reaching_defs.
+ Don't call dump_reaching_defs.
+ (insert_phi_nodes): Push/pop TV_TREE_INSERT_PHI_NODES.
+ (build_fud_chains): Push/pop TV_TREE_BUILD_FUD_CHAINS.
+ (compute_reaching_defs): Push/pop TV_TREE_RDEFS.
+ Call dump_reaching_defs.
+ * tree-optimize.c (optimize_function_tree): Remove calls to
+ timevar_push and timevar_pop.
+
+2002-11-28 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree-ssa.o): Add dependency on $(TIMEVAR_H) and
+ tree-alias-common.h.
+ (tree-dfa.o): Likewise.
+ (tree-optimize.o): Add dependency on $(TIMEVAR_H).
+ * tree-dfa.c (compute_may_aliases): Move call to delete_alias_vars
+ * tree-ssa.c (delete_tree_ssa): ... here.
+
+2002-11-27 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (add_may_alias): Remove. Update all users.
+ (get_alias_index): Remove. Update all users.
+ (dfa_stats_d): Remove fields num_may_alias, max_num_may_alias,
+ num_alias_imm_rdefs and max_num_alias_imm_rdefs. Update all users.
+ (may_alias_p): Make extern. Move declaration to tree-flow.h.
+ (TRM_DEFAULT): Remove. Update all users. Update values of the
+ other TRM_* constants.
+ (create_ref): Don't initialize the PHI argument array with the
+ number of incoming edges.
+ (collect_dfa_stats): Do not traverse the function body with
+ walk_tree.
+ Free temporary hash table before returning.
+ (compute_may_aliases): Update comment.
+ (may_alias_p): Switch arguments if the first argument is not an
+ INDIRECT_PTR or the artificial global_var.
+ (find_may_aliases_for): If a pointer aliases a variable, set the
+ pointer to be the alias leader for the variable.
+ (ref_defines): Call may_alias_p.
+ (is_killing_def): Return false if the reaching definition is NULL.
+ Don't check for volatile definitions.
+ Change second argument to be a tree. Update all users.
+
+ * tree-flow-inline.h (alias_imm_reaching_def): Remove. Update all
+ users.
+ (may_alias): Remove. Update all users.
+ (set_imm_reaching_def): Check for circularity.
+ (alias_leader): New function.
+ (set_alias_leader): New function.
+ (is_aliased): New function.
+ (is_default_def): Remove. Update all users.
+
+ * tree-flow.h (struct var_ref_d): Remove field alias_imm_rdefs.
+ Update all users.
+ (struct var_def_d): Remove field m_default. Update all users.
+ (struct tree_ann_d): Remove field may_aliases. Update all users.
+ Add field alias_leader.
+ (struct dfa_counts_d): Remove fields num_may_alias and
+ num_may_alias_imm_rdefs. Update all users.
+
+ * tree-ssa.c: Update documentation on may-alias processing.
+ (set_ssa_links): Remove third argument. Update all users.
+ (set_alias_imm_reaching_def): Remove. Update all users.
+ (create_default_def): Likewise.
+ (analyze_rdefs): Likewise.
+ (currdef_for): Move from tree-flow-inline.h
+ (set_currdef_for): Likewise.
+ (compute_reaching_defs): Rename from compute_tree_rdefs. Update
+ all users.
+ (follow_chain): Call is_killing_def instead of is_partial_def.
+ (tree_ssa_remove_phi_alternative): Remove unused variable ref.
+ (set_ssa_links): When processing V_USE references, make sure that
+ CURRDEF is a definition for the variable or one of its aliases.
+
+2002-11-26 Sebastian Pop <s.pop@laposte.net>
+
+ * Makefile.in (OBJS): Add tree-browser.o.
+ (tree-browser.o): New dependency.
+ * tree-browser.c: New file.
+ * tree-browser.def: New file.
+
+2002-11-26 Jason Merrill <jason@redhat.com>
+
+ Gimplify C++ cleanups.
+ * gimplify.c (voidify_wrapper_expr): Split out from...
+ (simplify_bind_expr): ...here.
+ (simplify_cleanup_point_expr): New fn.
+ (simplify_target_expr): New fn.
+ (gimple_conditional_context): New fn.
+ (gimple_push_condition, gimple_pop_condition): New fns.
+ (simplify_expr) [TRY_CATCH_EXPR]: Handle like TRY_FINALLY_EXPR.
+ * c-simplify.c (simplify_cleanup): New fn.
+ (c_simplify_stmt): Call it and lang_simplify_stmt.
+ (simplify_expr_stmt): Wrap the expr in a CLEANUP_POINT_EXPR.
+ (simplify_return_stmt, simplify_decl_stmt): Likewise.
+ (simplify_stmt_expr): Handle the STMT_EXPR_NO_SCOPE case.
+ (is_last_stmt_of_scope): Likewise.
+ * c-common.h: Declare c_genericize, c_simplify_stmt and
+ lang_simplify_stmt.
+ * c-common.c (lang_simplify_stmt): Define.
+
+ Gimplify EXIT_EXPRs.
+ * gimplify.c (gimplify_loop_expr, gimplify_exit_expr): New fns.
+ (simplify_expr): Call them.
+ * expr.c (expand_expr) [LOOP_EXPR]: Pass 1 again for exit_flag.
+
+ * tree-simple.c (right_assocify_expr): Also set TREE_SIDE_EFFECTS.
+
+ * gimplify.c (simplify_expr): Call STRIP_TYPE_NOPS.
+ [REALPART_EXPR]: Don't just return.
+
+ * tree-pretty-print.c (dump_c_node): Handle REFERENCE_TYPE.
+ * c-pretty-print.c (dump_c_node): Likewise. Handle null FOR_INIT_STMT.
+
+2002-11-25 Daniel Berlin <dberlin@dberlin.org>
+
+ * config.gcc: Try committing the correct version.
+ * tree-alias-ander.c (andersen_may_alias): Add "!= NULL" to make
+ return a bool.
+
+2002-11-24 Daniel Berlin <dberlin@dberlin.org>
+
+ * configure.in: Add --with-libbanshee, passed to us by toplevel if
+ libbanshee was configured. Substitute appropriate definitions for
+ Makefile (IE disabling tree-alias-ander building) if it wasn't.
+ * config.in: Regenerated.
+ * config.gcc: Rebuild libbanshee with stage1 on darwin to work
+ around system compiler problem.
+ * configure: Regenerated.
+ * Makefile.in: Add banshee stuff.
+ * tree-alias-ander.c: New file.
+ * tree-alias-ander.h: New file.
+ * tree-alias-common.c (get_alias_var): Fix field based stuff.
+ (find_func_aliases): Don't walk subtrees if we processed the tree.
+ (ptr_may_alias_var): Fix both field-based and non-field-based lookup.
+
+2002-11-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-ssa-dce.c (mark_necessary): Split out mark_tree_necessary. Don't
+ mark if tree is already marked.
+ (mark_tree_necessary): New. Mark tree without processing control parent.
+ (mark_control_parent_necessary): Remove recursion, mark trees directly.
+ (need_to_preserve_store): Can expression/symbol affect external values.
+ (tree_ssa_eliminate_dead_code): Split.
+ (find_useful_stmts): Find initial set of needed statements.
+ (process_worklist): Find statements which calculate needed statements.
+ (remove_dead_stmts): Delete statements which are dead.
+
+2002-11-16 Jason Merrill <jason@redhat.com>
+
+ Improve tree dumps.
+ * c-pretty-print.c, tree-pretty-print.c (dump_c_node): Handle
+ integers larger than a host word.
+ (op_prio): Handle INIT_EXPR.
+ * gimplify.c (simplify_bind_expr): Set TREE_SIDE_EFFECTS and type
+ of void_type_node on the COMPOUND_EXPRs as we walk.
+ * tree-simple.c (right_assocify_expr): Propagate the type from cur
+ rather than rhs.
+
+ * c-decl.c (finish_function): Call c_genericize instead of
+ simplify_function_tree.
+ * c-simplify.c (c_genericize): New function.
+ (simplify_stmt_expr): Just genericize.
+ (simplify_compound_literal_expr): Likewise.
+ (c_build_bind_expr): Don't build a block for an artificial decl.
+ (simplify_decl_stmt): Add the variable to the temps list iff it's
+ artificial.
+ (c_simplify_expr): Don't call push/pop_context.
+ * c-decl.c (build_compound_literal): Set DECL_ARTIFICIAL.
+ * c-tree.h: Declare c_genericize.
+
+ * c-simplify.c (tree_build_scope): Remove.
+
+ Remove INIT_EXPR from GIMPLE.
+ * c-simplify.c (simplify_decl_stmt): Use MODIFY_EXPR.
+ * gimplify.c (simplify_bind_expr): Likewise.
+ (simplify_modify_expr): Convert INIT_EXPR to MODIFY_EXPR.
+
+ * c-simplify.c (create_tmp_var_1): Drop; change all users to call
+ create_tmp_var.
+ (gimple_add_tmp_var): Now adds to the external temps list if
+ available, or directly to the function otherwise.
+
+ Avoid gratuitous unused warnings.
+ * c-simplify.c (simplify_expr_stmt): Check TREE_SIDE_EFFECTS
+ directly. Also check for explicit conversions to void.
+ (expr_has_effect): Remove.
+
+ * Makefile.in (OBJS): Remove tree-dchain.o.
+
+ * stor-layout.c (variable_size): We don't care about
+ global_bindings_p if the frontend doesn't want a list of the
+ expressions.
+
+2002-11-13 Diego Novillo <dnovillo@redhat.com>
+
+ * toplev.c (parse_options_and_default_flags): Enable SSA-CCP by
+ default with optimization >= 1.
+ * tree-dfa.c (find_refs_in_expr): Clobber '*.GLOBAL_VAR', not
+ 'GLOBAL_VAR'.
+ (collect_dfa_stats): Collect statistics on '*.GLOBAL_VAR'.
+ (compute_may_aliases): Make sure that variable is an INDIRECT_REF.
+ (may_alias_p): GLOBAL_VAR should alias INDIRECT_REFs.
+ Only check addressability on VAR_DECLs.
+ (find_may_aliases_for): Make sure argument is an INDIRECT_REF.
+ * tree-flow-inline.h (indirect_var): Call DECL_P.
+ (set_indirect_var): Call DECL_P.
+ Create annotation if it doesn't exist.
+ (create_indirect_ref): Move from tree-dfa.c.
+ * tree-flow.h (create_indirect_ref): Declare.
+ * tree-ssa-ccp.c (visit_phi_node): Avoid debugging dump from
+ accessing uninitialized data.
+ * tree-ssa.c (init_tree_ssa): Create an INDIRECT_REF node for
+ .GLOBAL_VAR.
+
+2002-11-12 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (delete_tree_cfg): Call free_aux_for_blocks.
+ Call free_basic_block_vars.
+
+ * gimplify.c (simplify_expr): VA_ARG_EXPR nodes are in GIMPLE form
+ already.
+ Gimplify BIT_FIELD_REF nodes.
+ (simplify_call_expr): Update comment.
+ * tree-dfa.c (find_refs_in_expr): VA_ARG_EXPR nodes make no
+ data references.
+ Handle BIT_FIELD_REF nodes.
+ * tree-pretty-print.c (op_prio): Don't write an error message if
+ the operand is not recognized.
+ * tree-simple.c (is_simple_unary_expr): Handle BIT_FIELD_REFs.
+ (is_simplifiable_builtin): Only return false for MD builtins.
+
+2002-11-08 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (cleanup_switch_expr_graph): Handle edges going to
+ EXIT_BLOCK_PTR.
+ (first_stmt): Return NULL for ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR and
+ INVALID_BLOCK.
+ * tree-dfa.c (find_refs_in_expr): Call mark_not_simple.
+
+2002-11-07 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree-ssa.o, tree-cfg.o, tree-dfa.o): Add dependency
+ on function.h
+ * tree-cfg.c: Include function.h.
+ (build_tree_cfg): Set dump_file to NULL after closing the file.
+ (remove_tree_bb): Don't dump warnings about statements being
+ removed.
+ (dump_tree_cfg): Use current_function_name.
+ Check that the flowgraph is not empty before dumping the function
+ body.
+ (tree_cfg2dot): Use current_function_name.
+ * tree-dfa.c: Include function.h
+ (dump_dfa_stats): Use current_function_name.
+ * tree-optimize.c (optimize_function_tree): Set dump_file to NULL
+ after closing the file.
+ * tree-pretty-print.c (dump_generic_node): Make sure that the
+ flowgraph exists before displaying block boundaries.
+ * tree-ssa-ccp.c (tree_ssa_ccp): Set dump_file to NULL after
+ closing the file.
+ * tree-ssa.c: Include function.h.
+ (build_tree_ssa): Set tree_ssa_dump_file to NULL after closing the
+ file.
+ (dump_reaching_defs): Use current_function_name.
+ (dump_tree_ssa): Likewise.
+
+2002-11-07 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (successor_block): Return EXIT_BLOCK_PTR if no
+ successor can be found while walking the nesting chain.
+
+2002-11-07 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c: Fix some formatting in code and comments.
+ (set_bb_for_stmt): Move from tree-flow-inline.h
+ * tree-dfa.c: Fix some formatting in code and comments.
+ * tree-flow-inline.h: Likewise.
+ * tree-flow.h: Likewise.
+ * tree-ssa.c: Likewise.
+
+2002-11-06 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree-ssa-ccp.o): Add dependency on tree-inline.h
+ * tree-cfg.c (find_taken_edge): New function.
+ (cleanup_cond_expr_graph): Call it.
+ (disconnect_unreachable_case_labels): Call it.
+
+ * tree-dfa.c (struct clobber_data_d): Remove field
+ parent_expr_p. Update all users.
+ (find_refs_in_expr): Remove argument parent_expr_p. Update all users.
+ (create_ref): Remove arguments parent_expr_p and operand_p. Update
+ all users.
+ (replace_ref_in): Rename from replace_ref_operand_with. Update all
+ users. Find the operand in the statement and replace it with a new
+ operand.
+ (replace_ref_r): New local function.
+ (is_killing_def): Also handle V_PHI references.
+ (output_ref): Move from tree-flow-inline.h
+
+ * tree-flow-inline.h (ref_expr): Remove. Update all users.
+ (restore_ref_operand): Remove. Update all users.
+ (set_output_ref): Remove. Update all users.
+ (is_assignment_stmt): New function.
+ (is_may_def, is_may_use, is_partial_def, is_partial_use,
+ is_volatile_def, is_volatile_use, is_default_def,
+ is_clobbering_def, is_initializing_def, is_relocating_def,
+ is_addressof_use, is_pure_use): Check reference type first.
+ (is_pure_def): New function.
+
+ * tree-flow.h (struct tree_ref_common): Remove fields expr_p,
+ operand_p and orig_operand. Update all users.
+ (struct tree_ann_d): Remove field output_ref. Update all users.
+
+ * tree-ssa-ccp.c: Include tree-inline.h.
+ (simulate_block): Simulate every statement in the block, not its
+ references
+ (simulate_def_use_chains): Simulate statements containing uses
+ reached by the definition.
+ (substitute_and_fold): Traverse statements, not references.
+ Call fold_stmt.
+ (visit_phi_node): If PHI node is marked volatile, assume varying.
+ (visit_stmt): Rename from visit_expression_for. Work on a
+ statement, not a reference.
+ (visit_assignment): Rename from visit_assignment_for. Work on a
+ statement, not a reference.
+ (visit_cond_stmt): Rename from visit_condexpr_for. Work on a
+ statement, not a reference.
+ (evaluate_stmt): Rename from evaluate_expr. Work on a statement,
+ not a reference.
+ (initialize): Initialize special definitions to varying.
+ (replace_uses_in): Work on a statement, not an expression.
+ (fold_stmt): Rename from ccp_fold. Work on a statement, not an
+ expression.
+ (get_rhs): New local function.
+ (set_rhs): New local function.
+
+2002-11-06 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-flow.h: Prototype set_bb_for_stmt, last_stmt_ptr,
+ add_ephi_arg, num_ephi_args, set_ephi_arg, ephi_arg.
+ (enum tree_ref_type): Add E_LEFT, E_KILL, E_EXIT.
+
+ * tree-cfg.c (set_bb_for_stmt): Move to tree-flow-inline.h.
+ (last_stmt_ptr): New function, gives pointer to last statement in
+ bb.
+
+ * tree-flow-inline.h: Add exprref_processed, exprref_processed2,
+ expruse_phi, num_ephi_args, set_ephi_arg, ephi_arg, add_ephi_arg.
+
+ * tree-dfa.c (tree_ref_structure): Handle E_{LEFT,KILL,EXIT}.
+ (ref_type_name): Ditto.
+ (tree_ref_size): Ditto.
+ (dump_ref): E_PHI's phi_args is now a varray of phi_arg structs.
+ (add_ephi_arg): New function.
+ (remove_ref_from_list): Fix crash when node not found.
+ (compute_may_aliases): Add timing for points-to analysis.
+
+ * timevar.def: Add TV_TREE_PTA.
+
+ * tree-ssa-pre.c: Start of massive cleanup and rewriting (in
+ preparation for load/store PRE). No more uses of ref_expr, proper
+ call handling. Started removing unnecessary structures and lists,
+ started removing redundant and inefficient operations (IE O(n^2)
+ loops to process all phi operands, etc). Basic load PRE implemented.
+ Code may look ugly due to large pieces commented out waiting for DFA
+ updating of refs to redo.
+
+2002-11-05 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (create_block_annotations): New local function.
+ (create_bb_ann): Remove. Update all users.
+ (parent_array): New local variable.
+ (build_tree_cfg): Initialize it.
+ Call create_block_annotations.
+ (create_bb): Call alloc_block instead of ggc_alloc to allocate
+ memory for basic blocks.
+ Don't call set_parent_block.
+ Grow array parent_array.
+ (dump_tree_cfg): Change meaning of second argument. Make it accept
+ any of the TDF_* flags defined in tree.h.
+ (delete_tree_cfg): Call free_aux_for_blocks.
+ Free array parent_array.
+ * tree-flow-inline.h (get_filename): New function.
+ (is_exec_stmt): return false if T is error_mark_node.
+ * tree-flow.h (struct var_ref_d): Mark alias_imm_rdefs field for
+ garbage collection.
+ (get_filename): Declare.
+ (struct bb_ann_d): Rename from bb_ann_def.
+ Remove garbage collection markers.
+ (referenced_vars): Mark for garbage collection.
+ (global_var): Likewise.
+ (create_bb_ann): Remove.
+ * tree-optimize.c (optimize_function_tree): Remove CFG and SSA
+ after debugging dumps.
+
+ * diagnostic.h (print_generic_stmt): Rename from print_generic_tree.
+ Update all users.
+ (print_generic_expr): Rename from print_generic_node. Update all
+ users.
+ (PPF_BRIEF): Remove. Update all users.
+ (PPF_BLOCK): Remove. Update all users.
+ (PPF_LINENO): Remove. Update all users.
+ (PPF_IS_STMT): Remove. Update all users.
+ * flags.h (flag_dump_tree_all_ssa): Remove. Update all users.
+ * toplev.c (f_options): Remove entry for -fdump-tree-all-ssa.
+ Update all users.
+ * tree-dump.c (dump_enable_all): Rename from dump_enable_all_ssa.
+ Update all users.
+ (dump_files): Add entry for -fdump-tree-all.
+ (dump_option_value_info): Remove entries for TDF_REFS and
+ TDF_RDEFS.
+ Add entry for TDF_BLOCK.
+ (dump_switch_p): If -fdump-tree-all was given, call dump_enable_all.
+ * tree-pretty-print.c (PPF_BRIEF): Remove. Update all users.
+ (PPF_BLOCK): Remove. Update all users.
+ (PPF_LINENO): Remove. Update all users.
+ (PPF_IS_STMT): Remove. Update all users.
+ (dumping_stmts): New local variable.
+ (print_generic_stmt): Rename from print_generic_tree. Update all
+ users.
+ Set dumping_stmts to true.
+ (print_generic_expr): Rename from print_generic_node. Update all
+ users.
+ Set dumping_stmts to false.
+ (maybe_init_pretty_print): Set last_bb to -1.
+ (dump_block_info): If available, dump file and line number
+ information for the first statement in the basic block.
+ * tree-ssa.c (build_tree_ssa): Dump referenced variables and
+ reaching definition information if -details is given.
+ * tree.h (enum tree_dump_index): Rename TDI_all to TDI_tu. Update
+ all users.
+ Add new index TDI_all.
+ (TDF_DETAILS): Change value.
+ (TDF_REFS): Remove. Update all users.
+ (TDF_RDEFS): Remove. Update all users.
+ (TDF_BLOCK): Define.
+ * doc/invoke.texi: Update documentation for -fdump-tree-... flags.
+
+2002-11-05 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mudflap_enqueue_decl, _constant): Use
+ size_in_bytes, not c_size_in_bytes.
+ (mf_init_extern_trees): Import uintptr_t typedef node from
+ mf-runtime.h.
+
+2002-11-01 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (remove_tree_bb): Add new argument remove_stmts.
+ Update all callers.
+ (make_ctrl_stmt_edges): Add an edge to the body of a SWITCH_EXPR.
+ (make_cond_expr_edges): Don't try to linearize the if() subgraph.
+ (make_case_label_edges): Don't remove the fallthru edge from the
+ entry block to the switch() subgraph.
+ (cleanup_tree_cfg): Call cleanup_control_flow.
+ (remove_unreachable_blocks): Remove blocks of compound structures
+ before removing the entry block.
+ (remove_blocks): New local function.
+ (blocks_unreachable_p): New local function.
+ (is_nonlocal_label_block): New local function.
+ (find_subblocks): New local function.
+ (is_parent): New local function.
+ (gsi_remove): New function.
+ (remove_stmt): New local function.
+ (cleanup_control_flow): New local function.
+ (cleanup_cond_expr_graph): New local function.
+ (cleanup_switch_expr_graph): New local function.
+ (disconnect_unreachable_case_labels): New local function.
+
+ * tree-dfa.c (remove_decl): New function.
+ (find_decl_location): New function.
+
+ * tree-flow.h (gsi_remove): Declare.
+ (remove_decl): Declare.
+ (find_decl_location): Declare.
+
+ * tree-ssa-ccp.c (optimize_unexecutable_edges): Remove. Update all
+ users.
+ (ssa_ccp_df_delete_unreachable_insns): Remove. Update all users.
+ (tree_ssa_ccp): Call print_generic_tree with PPF_BLOCK.
+
+2002-10-31 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (create_indirect_ref): New local function.
+ (find_refs_in_expr): Call it.
+ (create_ref): Check E_* reference types with == instead of &.
+ (dump_ref): Likewise.
+ (count_tree_refs): Likewise.
+ * tree-ssa.c (set_ssa_links): Update documentation comment for
+ save_chain.
+
+2002-10-31 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (remove_tree_bb): Don't walk beyond the end of the
+ basic block.
+
+2002-10-26 Daniel Berlin <dberlin@dberlin.org>
+
+ * flags.h: Remove flag_tree_points_to from here.
+ * toplev.c: Include tree-alias-common.h.
+ (flag_tree_points_to): Now of type enum pta_type, rather than
+ int.
+ (lang_independent_options): Remove flag_tree_points_to.
+ (display_help): Display help for tree-points-to here.
+ (decode_f_option): Allow selecting of points-to algorithm.
+ * tree-alias-common.c (varmap): Removed.
+ (alias_annot): Changed to a hash table. Update all functions
+ appropriately.
+ (FIELD_BASED): New macro, switches between field-based analysis,
+ and field-independent analysis (field-based isn't quite done yet).
+ (alias_annot_entry): New, used in hash table.
+ (annot_eq): New function.
+ (annot_hash): New function.
+ (find_func_aliases): Handle casts, fix indendation.
+ (splaycount): Removed.
+ (splay_tree_count): Removed.
+ (display_points_to_set): Removed.
+ (splay_tree_size): Removed.
+ (alias_get_name): New function.
+ (ptr_may_alias_var): Globals are a bit funky to handle.
+ * tree-alias-steen.c: Use alias_get_name, rather than
+ print_generic_node.
+ (steen_simple_assign): Handle assignment of PTF's.
+ (test_assign): Remove.
+ * tree-alias-common.h (enum pta_type): New.
+ (alias_get_name): New.
+ (flag_tree_points_to): New.
+
+2002-10-26 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (cleanup_tree_cfg): Uncomment call to
+ compact_blocks.
+
+2002-10-26 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree-pretty-print.o): Depend on $(TREE_FLOW_H)
+ * basic-block.h (BB_COMPOUND_ENTRY): Rename from BB_CONTROL_ENTRY.
+ * diagnostic.h (dump_generic_tree): Remove extern declaration.
+ (print_generic_node_brief): Remove. Update all users.
+ (PPF_BRIEF): Declare.
+ (PPF_BLOCK): Declare.
+ (PPF_LINENO): Declare.
+ (PPF_IS_STMT): Declare.
+ * tree-pretty-print.c (PPF_BRIEF): New constant.
+ (PPF_BLOCK): New constant.
+ (PPF_LINENO): New constant.
+ (PPF_IS_STMT): New constant.
+ (dump_block_info): New local function.
+ (last_bb): New local variable.
+ (dump_generic_tree): Remove unused function.
+ (print_generic_tree): Add third argument 'flags'. Update all
+ users.
+ (print_generic_node_brief): Remove. Update all users.
+ (print_generic_node): Add third argument 'flags'. Update all
+ users.
+ (dump_generic_node): Add third argument 'flags'. Update all users.
+ If PPF_BLOCK is set, display basic block information at basic block
+ boundaries.
+ If PPF_IS_STMT is set, change the way COMPOUND_EXPR nodes are
+ rendered.
+ If PPF_BRIEF is set, don't show the bodies of control statements.
+ (print_declaration):
+
+ * toplev.c (process_options): Update comment for -fdisable-simple.
+
+ * tree-cfg.c (remove_tree_bb): Rename from tree_delete_bb.
+ (latch_block): Move declaration to tree-flow.h. Declare extern.
+ (make_blocks): Start a new block after finding a control flow
+ altering statement.
+ (make_loop_expr_blocks): Set the loop entry block to be the parent
+ block for the loop latch block.
+ (cleanup_tree_cfg): Rename from tree_cleanup_cfg.
+ Call compact_blocks.
+ (remove_tree_bb): Rename from tree_delete_bb. Update all users.
+ (dump_tree_bb): Rename from dump_tree_bb. Update all users.
+ Dump information about loop latch blocks.
+ (debug_tree_bb): Rename from tree_debug_bb. Update all users.
+ (debug_tree_cfg): Rename from tree_debug_cfg. Update all users.
+ (dump_tree_cfg): Rename from tree_dump_cfg. Update all users.
+ By default, dump the function with markers for basic block
+ boundaries.
+ (successor_block): If we can't find a successor following the
+ parent chain, return the next block in the linked list of blocks.
+ Update documentation comments.
+ (stmt_starts_bb_p): Don't let RETURN_EXPR start a new block.
+ (is_latch_block): New function.
+ (first_exec_stmt): Don't treat BIND_EXPR nodes as a special case.
+ (first_stmt): Return NULL_TREE if the block does not exist.
+ (last_stmt): Likewise.
+
+ * tree-dfa.c (find_tree_refs): Rename from tree_find_refs. Update
+ all users.
+ (find_refs_in_stmt): Handle BIND_EXPR nodes.
+ (rli_start): Move from tree-flow-inline.h
+ (rli_start_last): Likewise.
+ (rli_start_at): Likewise.
+ (rli_delete): Likewise.
+
+ * tree-flow-inline.h (gsi_start_bb): Handle NULL blocks.
+ (ref_list_is_empty): New function.
+ * tree-flow.h (rli_start): Change declaration to extern.
+ (rli_start_last): Likewise.
+ (rli_start_at): Likewise.
+ (rli_delete): Declare.
+ (latch_block): Declare.
+ (is_latch_block): Declare.
+ (get_last_ref): Change to inline declaration.
+ (get_first_ref): Likewise.
+ (ref_list_empty): Declare.
+
+ * tree-optimize.c (delete_tree_ssa): Remove declaration.
+
+ * tree-ssa-dce.c (mark_control_parent_necessary): Call gsi_step_bb
+ instead of gsi_step.
+ (tree_ssa_eliminate_dead_code): Likewise.
+
+ * tree-ssa.c (compute_tree_rdefs): Rename from compute_tree_rdefs.
+ Update all users.
+
+2002-10-22 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (struct dfa_stats_d): Add field size_tree_refs.
+ (tree_ref_size): New function.
+ (create_ref): Call it.
+ (dump_dfa_stats): Get total size from dfa_stats.size_tree_refs.
+ (count_tree_refs): Call tree_ref_size.
+ * tree-flow-inline.h (get_last_ref): New function.
+ (get_first_ref): New function.
+ * tree-flow.h (struct var_ref_d): Rename from var_ref.
+ (struct var_def_d): Rename from var_def.
+ (struct var_phi_d): Rename from var_phi.
+ (struct var_use_d): Rename from var_use.
+ (struct expr_phi_d): Rename from expr_phi.
+ (struct expr_use_d): Rename from expr_use.
+ * tree-ssa-ccp.c (tree_ssa_ccp): Call get_last_ref.
+
+2002-10-21 Daniel Berlin <dberlin@dberlin.org>
+
+ * timevar.def: Add TV_TREE_{PRE,CCP,DCE,CFG,SSA}} timevars.
+
+ * tree-optimize.c (optimize_function_tree): Push and pop timevars
+ for the tree optimizers.
+
+2002-10-21 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (OBJS): Move tree-mudflap.o ...
+ (C_AND_OBJC_OBJS): ... here.
+
+2002-10-21 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-flow-inline.h (rli_start): New function.
+ (rli_start_rev): New function.
+ (rli_start_at): New function.
+ (rli_after_end): New function.
+ (rli_step): New function.
+ (rli_step_rev): New function.
+ (rli_ref): New function.
+ * tree-flow.h (struct ref_list_iterator): Declare.
+ (FOR_REF_BETWEEN, FOR_EACH_REF, FOR_EACH_REF_REV): Replace with new
+ rli_* iterator functions. Update all users.
+
+2002-10-21 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-cfg.c (make_blocks): Ignore TRY_FINALLY_EXPR and
+ TRY_CATCH_EXPR.
+ * tree-mudflap.c (mx_register_decls): Ignore local decls
+ of extern variables of unknown size.
+
+2002-10-20 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (repair_injury): DTRT, rather than abort.
+
+ * tree-dfa.c (ref_type_name): E_* don't have these modifier
+ fields, but may have the same bits set, so don't print the
+ modifiers on them.
+
+ * gimplify.c (create_tmp_var): New function, wraps calls to
+ create_tmp_var_1 with pushing/popping of right context.
+ All internal gimplify.c now use create_tmp_var_1.
+ (create_tmp_var_noc): New function, create the var without
+ pushing/popping, and without exposing internals of create_tmp_var_1.
+ Only one use of this.
+
+ * tree-simple.h (create_tmp_var_noc): New prototype.
+
+ * c-simplify.c (simplify_stmt_expr): create_tmp_var changed to
+ create_tmp_var_noc.
+
+ * tree-ssa-pre.c: Add WAITING_FOR_DFA_UPDATE around code waiting for DFA
+ functions to keep refs up to date.
+ (add_call_to_ei): occurs and occurstmts is now an
+ array of tree pointers, not trees. Update approriately.
+ (insert_occ_in_preorder_dt_order_1): Ditto.
+ (tree_perform_ssapre): Ditto.
+ (find_use_for_var): Removed function.
+ (orig_expr_map): Removed global, removed uses.
+ (struct ei): Added injfixups member.
+ (is_strred_cand): STRIP_WFL the expression.
+ (calculate_increment): Ditto.
+ (is_injuring_def): Ditto.
+ (defs_y_dom_x): Ditto. Also account for fact that y is now a full
+ expression, not just an RHS.
+ (defs_match_p): Ditto (t2 is no longer just an RHS).
+ (finalize_1): Do insertion by replacement.
+ (repair_injury): Clean up, do insertion by replacement.
+ (find_reaching_def_of_var): Do backwards search in a cleaner way.
+ (update_ssa_for_new_use): Change how we do replacement.
+ (code_motion): Insertion by replacement. Print EXPR_WFL_LINENO, not
+ STMT_LINENO.
+ (pre_part_1_trav): Just create_tmp_var will now suffice.
+
+2002-10-18 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (find_refs_in_expr): Change type of second argument to
+ enum tree_ref_type. Add third argument ref_mod. Update all users.
+ (create_ref): Add third argument ref_mod. Decode bitmask to set
+ the individual bitfields in the new reference.
+ * tree-flow-inline.h (is_may_ref): New function.
+ (is_may_def): New function.
+ (is_may_use): New function.
+ (is_partial_ref): New function.
+ (is_partial_def): New function.
+ (is_partial_use): New function.
+ (is_volatile_ref): New function.
+ (is_volatile_def): New function.
+ (is_volatile_use): New function.
+ (is_default_def): New function.
+ (is_clobbering_def): New function.
+ (is_initializing_def): New function.
+ (is_relocating_def): New function.
+ (is_addressof_use): New function.
+ (is_pure_use): New function.
+ * tree-flow.h (V_DEF, V_USE, V_PHI, E_PHI, E_USE, E_KILL): Redefine
+ inside enum tree_ref_type. Update all users.
+ (enum tree_ref_type): Define.
+ (TRM_DEFAULT, TRM_CLOBBER, TRM_MAY, TRM_PARTIAL, TRM_INITIAL,
+ TRM_VOLATILE, TRM_RELOCATE): Rename from M_*. Update all users.
+ (struct tree_ref_common): Change type of field 'type' to enum
+ tree_ref_type. Update all users.
+ (struct var_ref): Add bitfields 'm_may', 'm_partial' and 'm_volatile'.
+ (struct var_def): Add bitfield 'm_default', 'm_clobber', 'm_initial'
+ and 'm_relocate'.
+ (struct var_use): Add bitfield 'm_addressof'.
+ (ref_type): Change return type to enum tree_ref_type. Update all
+ users.
+ (create_ref): Add new argument ref_mod. Update all users.
+ (function_may_recurse_p): Change return type to bool. Update all
+ users.
+ (ref_type_name): Change argument type to tree_ref. Update all
+ users.
+ (validate_ref_type): Remove.
+
+2002-10-18 Diego Novillo <dnovillo@redhat.com>
+
+ * cp/Make-lang.in (CXX_C_OBJS): Remove tree-cfg.o, tree-dfa.o,
+ tree-optimize.o, tree-ssa.o, tree-ssa-pre.o, gimplify.o, tree-simple.o,
+ tree-alias-steen.o, tree-alias-ecr.o, tree-alias-type.o,
+ disjoint-set.o, tree-ssa-ccp.o, tree-dchain.o, tree-alias-common.o,
+ and tree-ssa-dce.o.
+
+2002-10-17 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (TREE_FLOW_H): Add bitmap.h, basic-block.h,
+ hard-reg-set.h and tree-simple.h. Update all users.
+ (C_AND_OBJC_OBJS): Move tree-cfg.o, tree-dfa.o,
+ tree-ssa.o, tree-optimize.o, c-simplify.o, c-call-graph.o,
+ tree-simple.o, simple-break-elim.o, simple-goto-elim.o, tree-dchain.o,
+ tree-ssa-pre.o, tree-alias-type.o, tree-mudflap.o, gimplify.o,
+ tree-alias-ecr.o, tree-alias-common.o, tree-alias-steen.o,
+ disjoint-set.o, tree-ssa-ccp.o and tree-ssa-dce.o ...
+ (OBJS): ... here.
+ (gimplify.o): Add dependency on $(TREE_FLOW_H).
+ (tree-pretty-print.o): New rule.
+ (GTFILES): Add tree-flow.h
+ * c-config-lang.in (gtfiles): Remove tree-flow.h
+ * c-simplify.c (copy_if_shared_r, unmark_visited_r,
+ unshare_all_trees, mark_not_simple): Move ...
+ * gimplify.c: ... here.
+ Include tree-flow.h
+ * tree-flow.h: Include hard-reg-set.h.
+
+ * c-common.h (print_c_tree, print_c_node, print_c_node_brief,
+ debug_c_tree, debug_c_node, debug_c_node_brief): Move declarations
+ from diagnostic.h.
+ * c-call-graph.c (construct_call_graph): Call get_name.
+ (print_callee): Likewise.
+ * c-pretty-print.c (print_declaration): Declare static.
+ (print_function_decl): Likewise.
+ (print_struct_decl): Likewise.
+ (dump_c_tree): Likewise.
+ (dump_c_node): Likewise.
+ * diagnostic.h (dump_generic_tree, dump_generic_node,
+ print_generic_tree, print_generic_node, print_generic_node_brief):
+ Declare.
+ * tree-pretty-print.c: New file.
+ * c-decl.c: Replace calls to print_c_node with print_generic_node.
+ * tree-alias-common.c: Likewise.
+ * tree-alias-steen.c: Likewise.
+ * tree-cfg.c: Likewise.
+ * tree-dfa.c: Likewise.
+ * tree-mudflap.c: Likewise.
+ * tree-optimize.c: Likewise.
+ * tree-ssa-ccp.c: Likewise.
+ * tree-ssa-pre.c: Likewise.
+ * tree-ssa-dce.c: Likewise.
+ Don't include c-common.h nor c-tree.h
+ (tree_ssa_eliminate_dead_code): Don't call COMPOUND_BODY.
+ Replace ASM_STMT with ASM_EXPR. Don't check for EXPR_STMT.
+
+2002-10-17 Daniel Berlin <dberlin@dberlin.org>
+ Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (remove_bb_ann): Remove. Update all users.
+ (delete_tree_cfg): Set bb->aux to NULL in all basic blocks.
+ * tree-dfa.c: Remove extern declaration for tree_find_refs.
+ (create_ref_list): Allocate new list with ggc_alloc.
+ (empty_ref_list): Just set first and last element to NULL.
+ (delete_ref_list): Remove. Update all users.
+ (remove_ref_from_list): Don't call free.
+ (add_ref_to_list_begin): Allocate new node with ggc_alloc.
+ (add_ref_to_list_end): Likewise.
+ (add_ref_to_list_after): Likewise.
+ (create_ref): Call BITMAP_GGC_ALLOC.
+ (remove_tree_ann): Remove. Update all users.
+ (tree_ref_structure): New function.
+ * tree-flow.h (edge, basic_block): Forward declare if necessary.
+ (struct ref_list_node): Mark for garbage collection.
+ (struct ref_list_priv): Likewise.
+ (struct tree_ref_common): Likewise.
+ (struct var_ref): Likewise.
+ (struct var_def): Likewise.
+ (struct var_phi): Likewise.
+ (struct var_use): Likewise.
+ (struct phi_node_arg_d): Likewise.
+ (struct expr_ref_common): Likewise.
+ (struct expr_phi): Likewise.
+ (struct expr_use): Likewise.
+ (union tree_ref_d): Likewise.
+ (struct tree_ann_d): Likewise.
+ (struct bb_ann_def): Likewise.
+ (referenced_vars): Likewise.
+ (global_var): Likewise.
+ (enum tree_ref_structure_enum): New.
+ (call_sites): Remove unused function.
+ * tree-inline.c (copy_tree_r): Copy the 'ann' field from tree_common.
+ * old-tree-inline.c (copy_tree_r): Likewise.
+ * tree-ssa.c (added): Mark for garbage collection.
+ (in_work): Likewise.
+ (work_stack): Likewise.
+ (delete_tree_ssa): Set global_var to NULL_TREE.
+ * tree.h (struct tree_ann_d): Forward declare.
+ (struct tree_common): Rename field 'aux' to 'ann'. Update all
+ users. Don't mark it 'skip' for garbage collection.
+
+2002-10-16 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-dfa.c (compute_may_aliases): Call create/delete_alias_vars
+ if flag_tree_points_to is on.
+ (may_alias_p): Use points-to info if user asked us to generate it.
+
+ * tree-optimize.c (optimize_function_tree): Don't call
+ create_alias_vars here.
+
+2002-10-16 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (make_cond_expr_edges): If the conditional has known
+ value, only make the edge to the corresponding branch.
+ (tree_delete_bb): Write a warning to the dump file when removing
+ blocks with executable statements.
+ (first_exec_stmt): Skip over empty BIND_EXPR blocks.
+
+ * tree-dfa.c (find_refs_in_expr): Don't look for references in non
+ GIMPLE statements.
+ (remove_tree_ann): Clear the annotation with memset.
+ (collect_dfa_stats_r): Don't call tree_annotation.
+ (find_may_aliases_for): Avoid adding the same alias more than once.
+ (may_alias_p): Fix comment grammar.
+
+ * tree-flow-inline.h (is_exec_stmt): New function.
+ * tree-flow.h (FOR_EACH_REF): Guard against NULL lists.
+ (FOR_EACH_REF_REV): Likewise.
+ (is_exec_stmt): Declare.
+
+ * tree-ssa-ccp.c (visit_phi_node): Reformat debug dumping output.
+ (visit_expression_for): Move check for clobbering definitions
+ before check for NULL expressions.
+ (visit_condexpr_for): Reformat debug dumping output.
+ (set_lattice_value): Remove stale comments.
+ (replace_uses_in): Don't clear TF_FOLDED flag from expression.
+
+ * tree-ssa.c (add_phi_node): If possible, associate the PHI node to
+ a statement.
+ (create_default_def): Create initial declarations for static
+ variables with DECL_INITIAL set.
+ (delete_tree_ssa): Remove annotations from variables.
+
+2002-10-16 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-type.c (alias_tvar_new_with_aterm): New function.
+ Update all allocations to allocate right type, rather than the union.
+ Update to use macros to access members of alias_typevar.
+
+ * tree-alias-type.h: Split alias_typevar into a common, an ECR, and
+ an aterm, update all users.
+ Add macros to access members of union.
+
+ * tree-alias-common.c (create_alias_var): Handle function_decl's
+ properly (needed for proper handling of function pointers).
+ Updates for macros to access typevars.
+ Fix some indentation.
+
+ * tree-alias-steen.c: Updates for macros to access typevars.
+
+2002-10-16 Frank Ch. Eigler <fche@redhat.com>
+
+ * c-decl.c (c_expand_body): Enable mudflap, only for gimple.
+ * c-pretty-print.c (dump_c_node): Render try/catch/finally exprs.
+ (op_prio): Accept BIND_EXPRs.
+ * gcc.c (cpp_unique_options): Make -fmudflap -include mf-runtime.h.
+ * toplev.c (process_options): Complain on -fmudflap -fdisable-simple.
+ * tree-mudflap.c (*): Reorganize for generic/gimple operation.
+ (mf_init_extern_trees): Extract decl nodes from -include'd file.
+ (mf_external_ref, mf_decl_extern_trees): Removed; updated callers.
+ (mf_offset_expr_of_array_ref): Don't bother store index type as
+ TREE_PURPOSE.
+ (mf_build_check_statement_for): Use GIMPLE tree types and builders.
+ (mx_register_decls): New function, replacing mx_register_decl.
+ (mx_xfn_xform_decls): Support only GIMPLE input tree types.
+ (mf_flush_enqueued_calls): Clean up enqueued call statements.
+
+2002-10-14 Diego Novillo <dnovillo@redhat.com>
+
+ * toplev.c (parse_options_and_default_flags): Undo local
+ hack that slipped in the previous commit.
+
+2002-10-14 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (c-decl.o): Add dependency on diagnostic.h.
+ * c-decl.c: Include diagnostic.h
+ (c_expand_body): Call get_name.
+
+ * basic-block.h (struct basic_block_def): Rename head_tree to
+ head_tree_p and end_tree to end_tree_p. Change type to tree *.
+ Update all users.
+ (BLOCK_HEAD_TREE): Remove. Update all users.
+ (BLOCK_END_TREE): Remove. Update all users.
+ * tree-cfg.c (build_tree_cfg): Return if function body is empty.
+ (make_blocks): Change first argument to tree *. Update all users.
+ (make_bind_expr_blocks): Likewise.
+ (make_loop_expr_blocks): Likewise.
+ (make_cond_expr_blocks): Likewise.
+ (make_switch_expr_blocks): Likewise.
+ (create_bb): Likewise.
+ (first_exec_block): Likewise.
+ (first_exec_stmt): Likewise.
+ (tree_delete_bb): Use a gimple statement iterator to unmap
+ statements.
+ (insert_stmt_before): Remove empty function.
+ (replace_expr_in_tree): Remove. Update all users.
+ (find_expr_in_tree_helper): Likewise.
+ (find_expr_in_tree): Likewise.
+ (first_stmt): Call STRIP_NOPS.
+ (last_stmt): Call STRIP_NOPS.
+
+ * tree-dfa.c (struct clobber_data_d): Rename parent_stmt to
+ parent_stmt_p and parent_expr to parent_expr_p. Change types to
+ tree *. Update all users.
+ (find_refs_in_stmt): Change first argument type to tree *. Update
+ all users.
+ (find_refs_in_expr): Chnage arguments parent_stmt and parent_expr
+ to tree *. Update all users.
+ (create_ref): Don't add the same reference twice on the same list
+ when parent_stmt and parent_expr are the same node.
+ Don't set output_ref when the parent statement is not in GIMPLE
+ form.
+ (replace_ref_operand_with): Move from tree-flow-inline.h
+ (replace_ref_expr_with): New function.
+ (replace_ref_stmt_with): New function.
+ (create_tree_ann): Abort if trying to annotate certain nodes.
+ Don't create an empty ref list.
+ In the presence of WFL or NOPS wrappers, add the annotation to the
+ inner node.
+ (dump_ref): Don't call tree_annotation to access the tree
+ annotation.
+
+ * tree-flow.h (struct tree_ref_common): Rename field stmt to stmt_p
+ and field expr to expr_p. Change types to tree *. Update all
+ users.
+ (replace_ref_expr_with): Declare.
+ (replace_ref_stmt_with): Declare.
+ (insert_stmt_before, insert_stmt_after, replace_expr_in_tree,
+ find_expr_in_tree): Remove.
+ * tree-flow-inline.h (ref_expr): Return NULL_TREE if expr_p is
+ NULL.
+ (ref_stmt): Return NULL_TREE if stmt_p is NULL.
+ (tree_annotation): Call STRIP_WFL and STRIP_NOPS before returning
+ the annotation.
+ (add_tree_ref): Remove consistency checks. Create an empty list
+ the first time.
+ (get_lineno): Return -1 on NULL_TREE.
+ (set_output_ref): Remove consistency.
+ (set_tree_flag): Likewise.
+ (clear_tree_flag): Likewise.
+ (reset_tree_flags): Likewise.
+ * tree-simple.h (gimple_stmt_iterator): Rename ptr to tp. Change
+ type to tree *. Update all users.
+ (gsi_start): Change argument type to tree *. Update all users.
+ (gsi_stmt_ptr): New function.
+ (gsi_container): New function.
+
+ * tree-optimize.c (optimize_function_tree): Don't test fnbody for
+ NULL.
+ Re-enable optimizers.
+ * tree-ssa-ccp.c: Update documentation comments.
+ Don't include c-common.h and c-tree.h.
+ (tree_ssa_ccp): Don't call COMPOUND_BODY.
+ (ccp_fold): New private function.
+ (substitute_and_fold): Call it.
+ Call replace_ref_expr_with.
+ Set TF_FOLDED flag on the statement, not the expression.
+ (visit_assignment_for): Call STRIP_NOPS and STRIP_WFL.
+ (evaluate_expr): Call ccp_fold. Only use the RHS of the simplified
+ value in the case of MODIFY_EXPR or INIT_EXPR.
+ (restore_expr):
+ * tree-ssa-dce.c (mark_control_parent_necessary): Use a gimple
+ iterator.
+ (tree_ssa_eliminate_dead_code): Likewise.
+ * tree-ssa-pre.c: Disable and add warning comments for out-of-date
+ calls to create_ref, find_refs_in_stmt and replace_expr_in_tree.
+
+2002-10-12 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-type.h (alias_typevar_def): Add struct aterm
+ as a temporary hack for andersen's analysis.
+ * tree-alias-common.c (current_alias_ops): New, use it
+ instead of referring to steen_alias_ops everywhere.
+ (get_alias_var): Use STRIP_WFL.
+ (find_func_aliases): Ditto.
+ (create_alias_vars): Call init function, move deletion to
+ delete_alias_vars.
+ (delete_alias_vars): New function, move deletion code to here.
+ (get_virtual_var): Removed.
+ (ptr_may_alias_var): New function.
+ * tree-alias-common.h (struct tree_alias_ops): Add may_alias
+ function.
+ * tree-alias-steen.c (steen_may_alias): New function.
+
+2002-10-10 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
+
+ * diagnostic.h (dump_c_tree, dump_c_node,
+ print_declaration, print_function_decl,
+ print_struct_decl): Fix argument types.
+
+2002-10-10 Diego Novillo <dnovillo@redhat.com>
+
+ * tree.h (struct tree_common): Rename field unused_0 to
+ not_gimple_flag.
+ (TREE_NOT_GIMPLE): Define.
+ * c-simplify.c (mark_not_simple_r): Remove. Update all users.
+ (mark_not_simple): Set TREE_NOT_GIMPLE.
+ * gimplify.c (simplify_call_expr): Enable call to mark_not_simple.
+ * tree-flow.h (TF_NOT_SIMPLE): Remove. Update all users.
+
+ * tree-cfg.c (build_tree_cfg): Rename from tree_find_basic_blocks.
+ Update all users.
+ Find the first executable statement before starting basic block 0.
+ (make_blocks): Do not accept TRY_FINALLY_EXPR and TRY_CATCH_EXPR
+ nodes.
+ (make_edges): Always create an edge from entry to basic block 0.
+ (delete_tree_cfg): Rename from delete_cfg. Update all uses.
+ (first_exec_stmt): Return the container for the first statement,
+ not the statement itself.
+
+ * tree-dfa.c (tree_find_refs): Re-implement using a GIMPLE
+ iterator.
+ (find_refs_in_stmt): Handle GIMPLE statements.
+ (find_refs_in_expr): Call flags_from_decl_or_type when handling
+ CALL_EXPR expressions.
+ (create_ref): Call DECL_P.
+ (remove_tree_ann): Call tree_annotation.
+
+ * tree-flow-inline.h (gsi_step_bb): Stop if statement is not inside
+ a basic block.
+
+ * tree-flow.h (build_tree_cfg): Rename from tree_find_basic_blocks.
+ Update all users.
+ (delete_tree_cfg): Rename from delete_cfg.
+ (tree_find_refs): Declare.
+ (build_tree_ssa): Rename from tree_build_ssa.
+ (is_upward_exposed): Remove unused function.
+ * tree-optimize.c (delete_tree_ssa): Remove declaration.
+ (optimize_function_tree): Re-enable SSA builder.
+ * tree-simple.h (gsi_container): New function.
+
+ * Makefile.in (tree-ssa.o): Remove dependencies on c-common.h and
+ c-tree.h.
+ * tree-ssa.c: Don't include c-common.h nor c-tree.h.
+ (tree_find_refs): Remove declaration.
+ (remove_annotations_r): New local function.
+ (build_tree_ssa): Rename from tree_build_ssa. Update all users.
+ (analyze_rdefs): Don't call prep_stmt.
+ (is_upward_exposed): Remove unused function.
+ (add_phi_node): Don't associate the PHI node to a statement.
+ (delete_tree_ssa): Receive the function body as argument.
+ Walk the function body removing annotations from every tree.
+
+2002-10-10 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * tree-ssa-dce (tree_ssa_eliminate_dead_code): Initialize prev to
+ NULL_TREE.
+ Don't close dump_file until end of function.
+ Dump the the tree after DCE for -fdump-tree-dce.
+
+2002-10-08 Richard Henderson <rth@redhat.com>
+ Jason Merrill <jason@redhat.com>
+ Diego Novillo <dnovillo@redhat.com>
+
+ * tree-simple.h (gimple_stmt_iterator): New type.
+ (gsi_start): New function.
+ (gsi_after_end): New function.
+ (gsi_step): New function.
+ (gsi_stmt): New function.
+
+2002-10-08 Diego Novillo <dnovillo@redhat.com>
+
+ * calls.c (flags_from_decl_or_type): Make extern.
+ (ECF_*): Move ...
+ * rtl.h (ECF_*): ... here.
+ (flags_from_decl_or_type): Declare.
+
+ * tree.h (COND_EXPR_COND): Define.
+ (COND_EXPR_THEN): Define.
+ (COND_EXPR_ELSE): Define.
+ (LABEL_EXPR_LABEL): Define.
+ (optimize_function_tree): Declare.
+
+2002-10-08 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (TREE_FLOW_H): Define.
+ (c-decl.o): Remove dependency on tree-optimize.h.
+ (tree-alias-steen.o, tree-alias-common.o, tree-ssa.o, tree-ssa-pre.o,
+ tree-cfg.o, tree-dfa.o, tree-optimize.o, c-simplify.o, c-call-graph.o,
+ tree-ssa-dce.o, tree-ssa-ccp.o): Depend on $(TREE_FLOW_H).
+ (tree-cfg.o): Remove dependencies on c-tree.h and c-common.h.
+ * c-call-graph.c (construct_call_graph): Disable calls to removed
+ functions.
+ * c-decl.c: Don't include tree-optimize.h.
+ (c_expand_body): Enable calls to optimize_function_tree.
+
+ * c-pretty-print.c (dump_c_node): Fix printf warnings.
+ Only dump the first node of a COMPOUND_EXPR when brief_dump is set.
+ Use COND_EXPR_COND, COND_EXPR_THEN and COND_EXPR_ELSE accessors.
+ Only dump the opening brace of a BIND_EXPR when brief_dump is set.
+
+ * tree-cfg.c: Don't include tree-optimize.h, c-common.h and c-tree.h.
+ (binding_stack, make_for_stmt_blocks, make_if_stmt_blocks,
+ make_while_stmt_blocks, make_switch_stmt_blocks,
+ make_do_stmt_blocks, create_maximal_bb, make_for_stmt_edges,
+ make_while_stmt_edges, make_do_stmt_edges, make_if_stmt_edges,
+ make_break_stmt_edges, make_continue_stmt_edges, create_loop_hdr,
+ insert_before_ctrl_stmt, insert_before_normal_stmt,
+ insert_after_ctrl_stmt, insert_after_normal_stmt,
+ insert_after_loop_body, tree_split_bb, stmt_ends_bb_p): Remove.
+ Update all users.
+ (STRIP_CONTAINERS): Define.
+ (make_bind_expr_blocks): New local function.
+ (make_cond_expr_blocks): New local function.
+ (make_loop_expr_blocks): New local function.
+ (make_switch_expr_blocks): New local function.
+ (make_loop_expr_edges): New local function.
+ (make_cond_expr_edges): New local function.
+ (make_case_label_edges): New local function.
+ (first_exec_block): New local function.
+ (make_goto_expr_edges): Rename from make_goto_stmt_edges.
+ (make_blocks): Remove arguments COMPOUND_STMT and PREV_CHAIN_P.
+ Use gimple_stmt_iterator to iterate over the statements in the
+ function. Create maximal basic blocks during traversal.
+ (create_bb): Remove arguments end, prev_chain_p and binding_scope.
+ Rename control_parent to parent_block.
+ (set_bb_for_stmt): Move from tree-flow.h.
+ (make_edges): Don't assume that basic block 0 contains executable
+ statements.
+ Handle BIND_EXPR nodes.
+ (make_ctrl_stmt_edges): Handle LOOP_EXPR, COND_EXPR and
+ SWITCH_EXPR.
+ (make_exit_edges): Handle GOTO_EXPR, CALL_EXPR and RETURN_EXPR.
+ (tree_delete_bb): Call first_stmt and last_stmt.
+ (block_invalidates_loop): Call last_stmt.
+ (replace_expr_in_tree): Don't dump line number information.
+ (find_expr_in_tree_helper): Don't call statement_code_p.
+ (tree_dump_bb): Call get_lineno.
+ (tree_cfg2dot): Ditto.
+ (successor_block): Use a gimple_stmt_iterator to find the first
+ executable block after the current one.
+ (is_ctrl_stmt): Handle COND_EXPR, LOOP_EXPR and SWITCH_EXPR.
+ (is_ctrl_altering_stmt): Call flags_from_decl_or_type to discover
+ non-return functions.
+ (is_loop_stmt): Handle LOOP_EXPR.
+ (is_computed_goto): Handle GOTO_EXPR.
+ (stmt_starts_bb_p): Handle CASE_LABEL_EXPR, LABEL_EXPR, RETURN_EXPR
+ and BIND_EXPR.
+ (first_exec_stmt): Use a gimple_stmt_iterator to traverse the
+ statements.
+ (first_stmt): New function.
+ (last_stmt): New function.
+
+ * tree-dfa.c: Don't include c-common.h, c-tree.h and
+ tree-optimize.h. Include diagnostic.h.
+ (tree_find_refs): Disable.
+ (find_refs_in_stmt): Disable.
+ (find_refs_in_expr): Don't call prep_stmt.
+ (tree_ann): Don't annotate empty_stmt_node.
+ (find_declaration): Remove. Update all users.
+ (dump_ref): Call get_lineno.
+ (is_visible_to): Always return true.
+
+ * tree-flow.h: Include tree-flow-inline.h, basic-block.h and
+ tree-simple.h.
+ (tree_ann_d): Remove compound_parent field.
+ (set_bb_for_stmt): Declare extern.
+ (compound_parent, set_compound_parent, struct for_header_blocks,
+ union header_blocks, prev_chain_p, set_prev_chain_p, binding_scope,
+ set_binding_scope, loop_hdr, for_init_bb, set_for_init_bb,
+ for_cond_bb, set_for_cond_bb, for_expr_bb, set_for_expr_bb,
+ end_while_bb, set_end_while_bb, do_cond_bb, set_cond_bb,
+ stmt_ends_bb_p, loop_parent, latch_block, switch_parent,
+ first_exec_stmt, last_exec_stmt, is_exec_stmt,
+ is_statement_expression, first_non_decl_stmt, first_decl_stmt,
+ first_non_label_in_bb, tree_split_bb, find_declaration): Remove.
+ Update all users.
+ (get_lineno): New function.
+ (struct bb_ann_def): Rename field parent to parent_block. Update
+ all users.
+ Remove fields prev_chain_p, loop_hdr and binding_scope. Update all
+ users.
+ (parent_block): Rename from bb_parent.
+ (set_parent_block): Rename from set_bb_parent.
+ (prev_chain_p): Remove
+ (bb_empty_p): Return true if block only contains empty_stmt_node.
+ (gsi_step_bb): New function.
+ (gsi_start_bb): New function.
+ (gsi_insert_before, gsi_insert_after, gsi_delete, gsi_replace):
+ Declare.
+ (insert_stmt_before): Rename from insert_stmt_tree_before.
+ (insert_stmt_after): Rename from insert_stmt_tree_after.
+ (first_stmt): Declare.
+ (last_stmt): Declare.
+ (tree_perform_ssapre, tree_ssa_ccp,
+ tree_ssa_eliminate_dead_code): Move declaration from tree-optimize.h.
+ * tree-flow-inline.h: New file for all the inline functions
+ declared in tree-flow.h
+
+ * tree-optimize.c: Don't include tree-optimize.h, c-common.h and
+ c-tree.h.
+ (optimize_function_tree): Disable call to double_chain_stmts.
+ Call init_flow.
+ Call tree_find_basic_blocks.
+ Disable calls to tree_build_ssa and optimizers.
+ (build_tree_ssa): Remove. Update all users.
+ * tree-optimize.h: Remove.
+ * tree-ssa-ccp.c: Don't include tree-optimize.h
+ * tree-ssa-dce.c: Don't include tree-optimize.h.
+ Include diagnostic.h
+ * tree-ssa-pre.c: Don't include tree-optimize.h.
+ (requires_edge_placement): Disable unused function.
+ (set_need_repair): Disable unused function.
+ (finalize_1): Disable calls to insert_stmt_tree_before and
+ insert_stmt_tree_after.
+ (repair_injury): Ditto.
+ (code_motion): Ditto.
+ * tree-ssa.c: Don't include tree-optimize.h.
+ (insert_phi_nodes_for): Remove unused variable.
+ (add_phi_node): Don't call statement_code_p.
+ * cp/optimize.c: Don't include tree-optimize.h
+ * tree-alias-common.c: Don't include tree-optimize.h.
+ (find_func_decls): Disable.
+ (display_points_to_set): Disable.
+ * tree-alias-steen.c: Don't include tree-optimize.h.
+
+2002-10-04 Jason Merrill <jason@redhat.com>
+
+ * gimplify.c (declare_tmp_vars): Don't add temps to block vars.
+ * tree-inline.c (remap_decls): Split out from remap_block.
+ (copy_bind_expr): Remap BIND_EXPR_VARS separately from block vars.
+
+ * c-simplify.c (simplify_expr_stmt): Call set_file_and_line_for_stmt.
+
+ * gimplify.c: New file.
+ (push_gimplify_context, pop_gimplify_context): New fns.
+ (gimple_push_bind_expr, gimple_pop_bind_expr): New fns.
+ (simplify_bind_expr): Use them.
+ (gimple_current_bind_expr, gimple_add_tmp_var): New fn.
+ (foreach_stmt): Recurse if necessary.
+ (various): Use generic interfaces instead of c-specific ones.
+ * c-simplify.c: Move language-independent code to gimplify.c.
+ (simplify_c_loop): Use add_tree instead of add_stmt_to_compound.
+ (various): Use new *_bind_expr interfaces.
+ * Makefile.in (C_AND_OBJC_OBJS): Add gimplify.o.
+ (gimplify.o): New rule.
+
+ * c-decl.c (c_expand_body): Dump trees here.
+ * c-simplify.c (simplify_function_body): Not here.
+
+2002-10-03 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mf_offset_expr_of_array_ref): Don't emit
+ intermediate variables for constant index values.
+ (mx_xfn_indirect_ref): For constant valid index values and
+ known valid array sizes, omit bounds checks.
+
+2002-10-03 Jason Merrill <jason@ariel.home>
+
+ * c-simplify.c (simplify_bind_expr): Don't clear TREE_SIDE_EFFECTS
+ if we have a block.
+
+ * c-simplify.c (simplify_expr) [TRY_FINALLY_EXPR]: New case.
+
+ * tree-inline.c (copy_body_r) [RETURN_EXPR]: Don't make an extra
+ copy of the MODIFY_EXPR. Mark the return label used.
+ (expand_call_inline): Don't push/pop_srcloc. Only emit the return
+ label if it was used.
+
+ * tree-simple.c (right_assocify_expr): Split out from
+ rationalize_compound_expr. Don't move non-matching op0's.
+ * tree-simple.h: Declare it.
+ * c-simplify.c (simplify_boolean_expr): Call it.
+ (simplify_cond_expr): Reorganize. Optimize if (a&&b).
+
+ * c-simplify.c (wrap_with_wfl): Drop special loop handling.
+ (simplify_c_loop): Wrap loop contents in wfls.
+
+ * c-simplify.c (STRIP_WFL): Move...
+ * tree.h: ...here.
+
+ * c-common.c (c_walk_subtrees): Don't walk TREE_CHAIN.
+ * tree-inline.c (walk_tree): Call langhook walk_subtrees first.
+ For expressions, walk TREE_CHAIN if it matters.
+
+2002-10-01 Frank Ch. Eigler <fche@redhat.com>
+
+ * builtins.c (expand_builtin_alloca): Disable if -fmudflap.
+ * tree-mudflap.c (mudflap_enqueue_decl): Tweak logic to include
+ more globals.
+ (mx_xfn_indirect_ref): Handle bitfield COMPONENT_REFs; instrument
+ BIT_FIELD_REF/INDIRECT_REFs.
+
+2002-10-01 Jason Merrill <jason@redhat.com>
+
+ * c-decl.c (poplevel): Only add undeclared labels to the toplevel
+ block.
+ * c-parse.in (label_decl): Push the declared label.
+
+ * c-decl.c (c_expand_body): If we've been simplified, use
+ expand_expr_stmt_value instead.
+
+ * c-decl.c (c_expand_decl): Rename from c_expand_decl_stmt.
+ Handle all C-specific expansion semantics.
+ * c-tree.h: Change prototype.
+ * langhooks.h (struct lang_hooks): Add expand_decl hook.
+ * langhooks.c (lhd_expand_decl): Default version.
+ * langhooks-def.h (LANG_HOOKS_EXPAND_DECL): Provide default.
+ * c-lang.c (LANG_HOOKS_EXPAND_DECL): Define.
+ * c-semantics.c (lang_expand_decl_stmt): Remove.
+ (genrtl_decl_stmt): Use lang_hooks.expand_decl.
+ * Makefile.in (c-semantics.o): Depend on langhooks.h.
+ * c-objc-common.c (c_objc_common_init): Don't set
+ lang_expand_decl_stmt.
+
+ * c-common.def (ASM_STMT): Only 4 operands.
+ * c-common.h (ASM_CV_QUAL): Remove.
+ (genrtl_asm_stmt): Adjust prototype.
+ * c-typeck.c (build_asm_stmt): Adjust.
+ * c-semantics.c (genrtl_asm_stmt): Change cv_qualifier parm to
+ volatile_p.
+ (expand_stmt): Adjust.
+
+ * c-common.h (SWITCH_COND, SWITCH_BODY, CASE_LOW, CASE_HIGH,
+ CASE_LABEL_DECL, GOTO_DESTINATION, ASM_STRING, ASM_OUTPUTS,
+ ASM_INPUTS, ASM_CLOBBERS, ASM_VOLATILE_P, ASM_INPUT_P): Move to tree.h.
+
+ * c-pretty-print.c (newline_and_indent): New fn.
+ (dump_c_tree, dump_c_node): Make spc a plain int.
+ (dump_c_node): Use output_add_identifier.
+ Reorganize for bnw-simple; indent in the enclosing node rather
+ than the subexpression.
+ [FUNCTION_DECL]: Just print the name for now.
+ [COMPOUND_EXPR, COND_EXPR]: Handle use as statements.
+ [BIND_EXPR, GOTO_EXPR, EXIT_EXPR, LOOP_EXPR, LABELED_BLOCK_EXPR,
+ EXIT_BLOCK_EXPR, RETURN_EXPR, SWITCH_EXPR, ASM_EXPR,
+ CASE_LABEL_EXPR]: Implement.
+ (print_declaration): Print 'static'.
+ * c-tree.h: Move c-pretty-print decls to diagnostic.h.
+
+ * expr.c (store_field): Don't always pass want_value==0 to store_expr.
+
+ * expr.c (expand_expr) [EXIT_EXPR]: Handle EXIT_EXPR_IS_LOOP_COND.
+
+ * expr.c (expand_expr) [LOOP_EXPR]: Pass exit_flag==0 to
+ exand_start_loop.
+ [BIND_EXPR]: Adjust for functions-as-trees mode.
+ [COMPOUND_EXPR]: Avoid recursion if possible.
+ [SWITCH_EXPR, LABEL_EXPR]: Move handling from java/expr.c.
+ [CASE_LABEL_EXPR, ASM_EXPR]: New handling.
+
+ * tree.h (struct tree_common): Add visited flag.
+ (TREE_VISITED): New macro.
+ * tree.c (copy_node): Clear TREE_VISITED.
+ * print-tree.c (print_node): Print visted.
+
+ * stmt.c (expand_asm_expr): New fn.
+
+ * tree.c (build1): Always set TREE_SIDE_EFFECTS for 's' codes.
+
+ * tree.h (enum tree_index): Add TI_EMPTY_STMT.
+ (empty_stmt_node): New macro.
+ * tree.c (build_common_tree_nodes_2): Initialize it.
+
+ * tree.def: Change some codes from 'e' to 's'.
+ (CASE_LABEL_EXPR, ASM_EXPR): New codes.
+
+ * tree.def (SWITCH_EXPR): Now has three operands.
+
+ * tree-inline.c: Retarget to generic trees. FIXME FIXME.
+ * old-tree-inline.c: Old C/Java-specific inliner.
+ * Makefile.in (old-tree-inline.o): New rule.
+ * c-common.c (c_walk_subtrees): New fn.
+ (c_tree_chain_matters_p): New fn.
+ * c-lang.c: Use them for LANG_HOOKS_TREE_INLINING_WALK_SUBTREES
+ and LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P.
+ * c-common.h: Declare them.
+ (DECL_NUM_STMTS): Move to tree.h.
+ * c-decl.c (finish_function): Simplify the function trees.
+ * c-objc-common.c (inline_forbidden_p): Look inside BIND_EXPRs
+ for nested functions. Don't inline a function with _STMT trees.
+
+ * basic-block.h: Include hard-reg-set.h.
+
+ * c-decl.c (start_function): Don't call make_decl_rtl.
+ (c_expand_body): Call it here instead.
+
+ * Makefile.in (explow.o): Depend on langhooks.h.
+
+ * unroll.c (copy_loop_body): Don't copy NOTE_INSN_DELETED_LABELs
+ between copy_notes_from and loop_end, either.
+
+2002-09-30 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (repair_injury): Start work on updating SSA
+ representation for strength reduction injuries.
+ Print a new line after outputting tree node in debug statements.
+ Fix strength reduction of a candidate with two variables (IE a *
+ c).
+ Put the repair after the injuring statement, not at the end of the
+ block.
+ Break the RHS use lookup if it's defined by a phi.
+ (calculate_increment): Ditto on node printing.
+ (code_motion): Ditto on updating SSA rep for strength reduction
+ injuries.
+ (find_rhs_use_for_var): Rewrite to use maybe_find_rhs_use_for_var.
+ (maybe_find_rhs_use_for_var): Rename from find_rhs_use_for_var,
+ don't abort, return NULL.
+ (set_var_phis): Simplify break condition.
+ Make sure RHS *has* a use before we go and get it.
+ (rename2): Ditto on RHS checking.
+ When looking up injuring defs, break on phis.
+ (phi_opnd_from_res): Ditto.
+ (defs_y_dom_x): Ditto.
+ (TODO List): Add new TODO to fix the remapping crud.
+
+2002-09-27 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (tree_perform_ssapre): Move insertion into
+ splay tree inside the is_simple_modify_expr block, to prevent
+ tree check failure.
+
+2002-09-26 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (update_phis_in_list): New function.
+ (update_ssa_for_new_use): New function.
+ (code_motion): Start working on code to update SSA representation.
+ (find_reaching_def_of_var): New function.
+
+2002-09-25 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * Makefile.in (tree): Add dependency on c-tree.h
+ * tree-optimize.c: Include c-tree.h
+ (optimize_function_tree): React to -fdump-tree-optimized.
+
+2002-09-25 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-dfa.c (add_list_to_ref_list_end): New function.
+ (add_list_to_ref_list_begin): Ditto.
+ (find_list_node): Handle searching in empty lists.
+ (find_refs_in_stmt): De-staticify.
+
+ * tree-flow.h (add_list_to_ref_list_end): New declaration.
+ (add_list_to_ref_list_begin): Ditto.
+ (find_refs_in_stmt): Add prototype.
+
+2002-09-25 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree-dfa.o): Depend on flags.h
+ * tree-cfg.c (tree_dump_cfg): Alter output format slightly.
+ (block_invalidates_loop): Look for clobbering definitions of
+ GLOBAL_VARIABLE.
+ * tree-simple.c (get_base_symbol): Handle EXPR_WITH_FILE_LOCATION
+ nodes.
+ * tree-optimize.c (init_tree_flow): Remove. Update all users.
+ (build_tree_ssa): Don't call tree_find_refs.
+ Don't call tree_compute_rdefs.
+
+ * tree-dfa.c: Include flags.h
+ (dump_file): Remove.
+ (dump_flags): Remove.
+ (pointer_refs): Remove.
+ (struct dfa_stats_d): Add fields max_num_phi_args, num_may_alias,
+ max_num_may_alias, num_alias_imm_rdefs and max_num_alias_imm_rdefs.
+ Remove field num_fcalls.
+ (dfa_counts): Declare.
+ (tree_find_refs): Declare.
+ (tree_ssa_dump_file): Declare.
+ (tree_ssa_dump_flags): Declare.
+ (dump_if_different): New function.
+ (add_default_defs): Remove. Update all users.
+ (add_call_site_clobbers): Remove. Update all users.
+ (add_ptr_may_refs): Remove. Update all users.
+ (compute_may_aliases): New function.
+ (find_may_aliases_for): New function.
+ (add_may_alias): New function.
+ (may_alias_p): New function.
+ (is_visible_to): New function.
+ (get_alias_index): New function.
+ (call_sites): Remove. Update all users.
+ (global_var): Declare.
+ (E_FCALL): Remove. Adjust other constants.
+ (M_INDIRECT): Remove. Update all users.
+ (M_RELOCATE): Declare.
+ (tree_find_refs): Move debugging dumps to tree_build_ssa.
+ Move initialization code to init_tree_ssa.
+ Call compute_may_aliases.
+ (find_refs_in_expr): For INDIRECT_REF nodes create a reference to
+ the canonical INDIRECT_REF node associated with the pointer symbol.
+ Given a pointer p, clobber the canonical INDIRECT_REF of p after
+ creating a V_DEF for p.
+ For CALL_EXPR nodes, if the called function is not pure nor
+ const, create a use and a clobbering definition to GLOBAL_VAR.
+ (create_ref): Allow INDIRECT_REF variables.
+ (add_phi_arg): Keep track of number of PHI arguments created.
+ (function_may_recurse_p): Look for clobbering definitions to
+ GLOBAL_VAR.
+ (get_fcalls): Remove unused function.
+ (is_pure_fcall): Remove unused function.
+ (fcall_takes_ref_args): Remove unused function.
+ (find_declaration): Stop iterating at ENTRY_BLOCK_PTR.
+ (debug_variable): New function.
+ (dump_variable): New function.
+ (dump_referenced_vars): Call it.
+ (dump_phi_args): Don't dump NULL arguments.
+ (PERCENT): Define.
+ (dump_dfa_stats): Re-format output.
+ Add new counters.
+ Call dump_if_different.
+ (collect_dfa_stats): Also recurse into GLOBAL_VAR.
+ (collect_dfa_stats_r): Collect may-alias information.
+ (count_tree_refs): Collect information about def-def links for
+ aliases.
+ Keep track of maximum values for number of PHI arguments, aliases
+ and def-def links.
+ (ref_type_name): Handle M_RELOCATE.
+ (validate_ref_type): Ditto.
+
+ * tree-ssa.c: Add more documentation.
+ (tree_ssa_dump_file): Rename from dump_file. Declare extern.
+ (tree_ssa_dump_flags): Rename from dump_flags. Declare extern.
+ (added): New local varray.
+ (in_work): New local varray.
+ (work_stack): New local varray.
+ (dfa_counts): Declare.
+ (insert_phi_nodes_for): New local function.
+ (add_phi_node): New local function.
+ (set_ssa_links): New local function.
+ (set_alias_imm_reaching_def): New local function.
+ (create_default_def): New local function.
+ (init_tree_ssa): New local function.
+ (tree_find_refs): Relocate declaration from tree-flow.h
+ (tree_build_ssa): Call init_tree_ssa.
+ Call tree_find_refs.
+ Process all SSA-related dump options.
+ (insert_phi_nodes): Rename from insert_phi_terms. Update all
+ users.
+ Call insert_phi_nodes_for.
+ (build_fud_chains): Add more documentation.
+ Initialize save_chain to 0.
+ (search_fud_chains): Add more documentation.
+ Call set_ssa_links.
+ Call create_default_def.
+ (tree_compute_rdefs): Initialize array marked to 0.
+ (follow_chain): Follow def-def chains for non-killing definitions
+ for aliases.
+ (dump_reaching_defs): Call dump_variable.
+
+ * tree-flow.h (E_FCALL): Remove. Update all users.
+ (M_INDIRECT): Remove. Update all users.
+ (M_RELOCATE): Declare.
+ (struct var_ref): Add field alias_imm_rdefs.
+ (alias_imm_reaching_def): New inline function.
+ (struct tree_ann_d): Add field indirect_var.
+ Add field may_aliases.
+ (enum tree_flags): Relocate.
+ (indirect_var): New inline function.
+ (set_indirect_var): New inline function.
+ (may_alias): New inline function.
+ (num_may_alias): New inline function.
+ (struct dfa_counts_d): Declare.
+ (global_var): Declare.
+ (FCALL_NON_PURE, FCALL_PURE, FCALL_BUILT_IN): Remove.
+ (tree_find_refs): Move to tree-ssa.c.
+ (dump_variable): Declare.
+ (debug_variable): Declare.
+ (get_fcalls): Remove.
+ (is_pure_fcall): Remove.
+ (fcall_takes_ref_args): Remove.
+ (ref_defines): Declare.
+ (is_killing_def): Declare.
+ (get_alias_index): Declare.
+ (delete_tree_ssa): Rename from delete_ssa. Update all users.
+ (set_currdef_for): Allow INDIRECT_REF nodes.
+ (bb_annotation): Don't create a new one if the block didn't have an
+ annotation already.
+
+ * tree-ssa-ccp.c (substitute_and_fold): Rename from
+ ssa_ccp_substitute_constants. Update all users.
+ Call replace_uses_in.
+ (replace_uses_in): New local function.
+ (evaluate_expr): Call it.
+ (initialize): Call get_base_symbol.
+
+ * tree-ssa-dce.c (tree_ssa_eliminate_dead_code): Don't handle
+ E_FCALL.
+
+2002-09-22 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree-dfa.o): Depend on hashtab.h.
+ * c-simplify.c (get_name): Declare extern.
+ * tree-cfg.c (tree_dump_cfg): Call it.
+ (tree_cfg2dot): Call it.
+ * tree-ssa-ccp.c (tree_ssa_ccp): Call get_name.
+ * tree-ssa-dce.c (tree_ssa_eliminate_dead_code): Call get_name.
+ * tree-ssa-pre.c (tree_perform_ssapre): Call get_name.
+ * tree-ssa.c (analyze_rdefs): Call get_name.
+ (dump_reaching_defs): Call get_name.
+ (dump_tree_ssa): Call get_name.
+ * tree.h (get_name): Declare.
+
+ * tree-dfa.c: Include "hashtab.h"
+ (struct dfa_stats_d): New.
+ (collect_dfa_stats): New local function.
+ (collect_dfa_stats_r): New local function.
+ (count_tree_refs): New local function.
+ (count_ref_list_nodes): New local function.
+ (tree_find_refs): Call dump_begin on entry to the function.
+ (dump_referenced_vars): Call get_name.
+ (SCALE): Declare.
+ (LABEL): Declare.
+ (dump_dfa_stats): New function.
+ (debug_dfa_stats): New function.
+ * tree-dump.c (struct dump_option_value_info): Add entry for TDF_STATS.
+ * tree-flow.h (has_annotation): Remove. Update all users.
+ (dump_dfa_stats): Declare.
+ (debug_dfa_stats): Declare.
+ (tree_annotation): Don't create one if the tree doesn't have one
+ already. Update all users to new semantics.
+ * tree-ssa-dce.c (print_stats): Dump if dump_flags has TDF_STATS bit
+ set.
+ * tree-ssa.c (tree_build_ssa): Open dump file on entry.
+ Call dump_dfa_stats if dump_flags has TDF_STATS bit set.
+ Call dump_tree_ssa if dump_flags has TDF_DETAILS bit set.
+ * tree.h (TDF_STATS): Define.
+ * doc/invoke.texi: Document 'stats' flag for -fdump-tree.
+
+ * tree-dfa.c (next_tree_ref_id): Change type to unsigned long.
+ Update all users.
+ tree-flow.h (tree_ref_common): Change type of field 'id' to
+ unsigned long. Update all users.
+ (ref_id): Change return type to unsigned long. Update all users.
+
+2002-09-21 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (struct expr_info): Add repaired member.
+ (repair_injury): Track which injuries we repaired, so we don't
+ repair them > 1 time.
+
+2002-09-20 Diego Novillo <dnovillo@redhat.com>
+
+ * c-pretty-print.c (dump_c_node): Fix call to REAL_VALUE_TO_DECIMAL.
+
+2002-09-20 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (find_refs_in_stmt): Fix botched call to
+ clobber_vars_r with CLEANUP_STMT nodes.
+
+2002-09-20 Diego Novillo <dnovillo@redhat.com>
+
+ * toplev.c (flag_tree_ssa): Remove. Update all users.
+
+2002-09-20 Frank Ch. Eigler <fche@redhat.com>
+
+ * gcc.c (cc1_options): Make -fmudflap imply -fno-merge-constants.
+ * varasm.c (categorize_decl_for_section): Likewise, for strings.
+ * tree-mudflap.c (mudflap_enqueue_decl): Don't be interested
+ in !TREE_USED decls. Fix minor type warning.
+ (mf_offset_expr_of_array_ref): Create explicit temporary variables
+ for array index expressions instead of SAVE_EXPRs. Update callers.
+ (mf_build_check_statement_for): Insert temp variables.
+ (mx_xfn_indirect_ref): Correct recursion-protection checking
+ sequence. Tweak array check-base calculation back to "&array[0]".
+ (*): Use build_function_type_list instead of build_function_type.
+ (mx_external_ref): Remove unused parameter. Update callers.
+
+2002-09-19 Diego Novillo <dnovillo@redhat.com>
+
+ * c-decl.c (c_expand_body): Invoke tree optimizers with -O1 and
+ above.
+ * flags.h (flag_tree_ssa): Remove.
+ * tree-cfg.c (find_expr_in_tree_helper): Change last argument type
+ to int.
+ * tree-dfa.c (create_ref): Ditto.
+ * tree-flow.h (num_referenced_vars): Change type to unsigned long.
+ * doc/invoke.texi (-ftree-ssa): Remove.
+ (-fdump-tree-{pre,ccp,dce}): Add to the summary section.
+ (-fdump-tree-xxx-details): Update documentation.
+ (-fdump-tree-ccp): Document.
+ (-fdump-tree-simple): Move elsewhere.
+
+2002-09-19 Richard Henderson <rth@redhat.com>
+
+ * function.c (insns_for_mem_hash): Cast to size_t first.
+ * tree-dfa.c (num_referenced_vars): Unsigned long, not size_t.
+ (dump_referenced_vars): Use %lu for it.
+ (dump_ref): Use HOST_WIDE_INT_PRINT_DEC.
+ * tree-nomudflap.c (mudflap_c_function): Use ATTRIBUTE_UNUSED.
+ (mudflap_enqueue_decl, mudflap_enqueue_constant): Likewise.
+ * tree-ssa-pre.c (compute_idfs): Cast to size_t first.
+
+ * tree-optimize.c (optimize_function_tree): Fix missed renamings.
+ * tree-ssa-pre.c (tree_perform_ssapre): Likewise.
+
+2002-09-19 Jeff Law <law@redhat.com>
+
+ * tree-dfa.c (find_refs_in_stmt): Search for references in the call
+ address of a CALL_EXPR.
+
+2002-09-19 Daniel Berlin <dberlin@dberlin.org>
+
+ * toplev.c: tree-ssa-* -> tree-*.
+
+ * doc/invoke.texi: Ditto.
+
+2002-09-19 Daniel Berlin <dberlin@dberlin.org>
+
+ * flags.h: flag_tree_ssa_* -> flag_tree_*.
+
+ * toplev.c: Ditto.
+
+ * tree-optimize.c: Ditto.
+
+ * tree-dump.c: dump-tree-ssa-* -> dump-tree-*.
+ TDI_ssa_* -> TDI_*.
+
+ * tree.h: Ditto
+
+ * tree-ssa-dce.c (tree_ssa_eliminate_dead_code): Fix dump handling.
+
+2002-09-18 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-dump.c (dump_files): Use dump-tree-ssa-??? for the option names
+ and "ssa-???" for the dump files.
+
+ * tree.h: TDI_ccp and TDI_dce -> TDI_ssa_ccp and TDI_ssa_dce.
+
+ * tree-ssa-ccp.c: TDI_ccp->TDI_ssa_ccp.
+
+2002-09-18 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-dump.c: Fix order of dump files
+
+2002-09-17 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c: Remove a lot of finding refs in statements junk.
+ Start on strength reduction.
+ Only generate simple statements.
+ Remove EXPR* macros in favor of inline functions.
+ Update comparisons and sets to 1 and 0 to true and false where
+ approriate.
+ (toplevel): Add DEBUGGING_STRRED define (temporary, for
+ implementation debugging, *not* useful as a dump option).
+ Add TODO notes.
+ Add global avdefs, orig_expr_map, need_repair_map,
+ strred_candidate.
+ (set_var_phis): Add struct expr_info * argument.
+ Update to handle injuring definitions.
+ (defs_y_dom_x): Ditto.
+ (phi_opnd_from_res): Ditto.
+ (phi_for_operand): Remove extra \.
+ (find_tree_ref_for_var): Renamed to find_use_for_var. Update all
+ callers.
+ Use orig_expr_map to lookup original expression, remove statement
+ searching gunk.
+ (find_rhs_use_for_var): New function.
+ (is_strred_cand): New function.
+ (is_injuring_def): New function.
+ (calculate_increment): New function.
+ (repair_injury): New function.
+ (set_need_repair): New function.
+ (struct expr_info): Add strred_cand member.
+ (rename_2): Update to handle injuring definitions.
+ (expr_phi_insertion): Ditto.
+ (code_motion): Update to repair injuries.
+ Only insert SIMPLE statements.
+ Free avdefs here now.
+ (finalize_1): Don't free avdefs anymore here.
+ (tree_perform_ssapre): Record original expresion for
+ find_use_for_var's benefit.
+ Determine strength reduction candidates.
+
+ * tree-flow.h: Remove EXPR* macros in favor of inline functions.
+ Remove E_INJ.
+
+ * tree-dfa.c: Change EXPR* macros to the new functions.
+ Remove E_INJ.
+
+2002-09-18 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (M_ADDRESSOF): Define.
+ (find_refs_in_expr): Create addressof-use references for ADDR_EXPR
+ nodes.
+ Don't create references for FUNCTION_DECL nodes.
+ (ref_type_name): Handle M_ADDRESSOF.
+ (validate_ref_type): Ditto.
+ (clobber_vars_r): Don't clobber FUNCTION_DECL nodes.
+ * tree-flow.h (M_ADDRESSOF): Declare.
+
+2002-09-17 Diego Novillo <dnovillo@redhat.com>
+
+ * doc/invoke.texi: Document -ftree-ssa-dce and -fdump-tree-dce.
+ * cp/Make-lang.in (CXX_C_OBJS): Add tree-ssa-dce.o.
+
+2002-09-17 Ben Elliston <bje@redhat.com>
+
+ * Makefile.in (C_AND_OBJC_OBJS): Add tree-ssa-dce.o.
+ tree-ssa-dce.o): New target.
+ * tree-ssa-dce.c: New file.
+ * flags.h (flag_tree_ssa_dce): Declare flag.
+ * tree.h (tree_dump_index): Add TDI_dce.
+ * toplev.c (flag_tree_ssa_dce): New flag.
+ (f_options): Add "dump-tree-all-ssa" option.
+ * tree-flow.h (enum tree_flags): Add TF_NECESSARY.
+ * tree-dump.c (dump_files): Add dump-tree-dce option.
+ (dump_enable_all_ssa): Enable it when dumping all.
+ * tree-optimize.h (tree_ssa_eliminate_dead_code): Declare.
+ * tree-optimize.c (optimize_function_tree): Invoke the
+ optimisation pass if flag_tree_ssa_dce is set.
+
+2002-09-17 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree-ssa.o): Add dependency on c-tree.h
+ * c-simplify.c (mark_not_simple_r): Don't mark IDENTIFIER_NODEs.
+ * tree-dfa.c (function_may_recurse_p): Fix comment.
+ (dump_ref): Don't dump immediate uses for PHI nodes more than once.
+ (dump_referenced_vars): Unparse the name of the variable.
+ * tree-flow.h (dump_tree_ssa): Declare.
+ (debug_tree_ssa): Declare.
+ (replace_ref_operand_with): Check if OPERAND_P is NULL.
+ (restore_ref_operand): Ditto.
+ (tree_annotation): Check that constants, types and IDENTIFIER_NODEs
+ are not being annotated.
+ * tree-ssa.c: Include c-tree.h.
+ (dump_reaching_defs): Unparse the variable name.
+ (dump_tree_ssa): New function.
+ (tree_build_ssa): Call it.
+ (debug_tree_ssa): New function.
+
+2002-09-14 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * dwarf2out.c (is_fortran): Return true for
+ DW_LANG_Fortran95.
+ (gen_compile_unit_die): Return DW_LANG_Fortran95 if
+ language is "GNU F95".
+
+2002-09-13 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-dump.c (dump_switch_p): Get longest match, not first one.
+
+ * tree.h: Put TDI_* back in order, now that we do longest match
+ matching.
+
+2002-09-13 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (add_call_site_clobbers): Call decl_function_context
+ instead of DECL_CONTEXT.
+ * tree-ssa-ccp.c (initialize): Ditto.
+ * tree-ssa.c (analyze_rdefs): Ditto.
+
+2002-09-11 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (find_refs_in_stmt): Call clobber_vars_r to clobber
+ CLEANUP_STMT nodes.
+ (create_ref): Only add _DECL nodes to the list of referenced
+ variables.
+ (clobber_vars_r): Create a may-use reference prior to clobbering
+ the variable.
+ (add_call_site_clobbers): Ditto.
+ (add_ptr_may_refs): Move call to find_list_node where it's actually
+ needed.
+ * tree-flow.h: Update documentation on M_CLOBBER.
+
+2002-09-10 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (defs_match_p): Fix typo ( | -> || ).
+
+2002-09-10 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (V_PHI_ARG): Remove. Adjust related constants.
+ Update all users.
+ (add_ref_to_list_after): Don't allocate memory for the
+ node when adding to the beginning or the end of the list.
+ (add_phi_arg): Don't call create_ref to add a new argument.
+ (debug_phi_args): New function.
+ (dump_phi_args): New function.
+ (dump_ref): Call it.
+ (dump_referenced_vars): Use 'file' instead of 'dump_file'.
+
+ * tree-flow.h (V_PHI_ARG): Remove. Update all users.
+ (struct var_ref): Move fields used in distinct
+ reference types to other structures. Update all users.
+ (struct var_def): New.
+ (struct var_phi): New.
+ (struct var_use): New.
+ (union tree_ref_d): Add members vdef, vphi, vuse and vphi_arg.
+ Update all users.
+ (save_chain): Remove. Update all users.
+ (set_save_chain): Remove. Update all users.
+ (marked_with): Remove. Update all users.
+ (mark_def_with): Remove. Update all users.
+ (dump_reaching_defs): Declare.
+ (debug_reaching_defs): Declare.
+
+ (struct phi_node_arg_d): New structure.
+ (phi_node_arg): New type.
+ (phi_arg): Change return type to phi_node_arg.
+ (imm_reaching_def_edge): Rename to phi_arg_edge.
+ (set_imm_reaching_def_edge): Rename to set_phi_arg_edge.
+ (phi_arg_def): New inline function.
+ (set_phi_arg_def): New inline function.
+ (debug_phi_args): Declare.
+ (dump_phi_args): Declare.
+
+ * tree-ssa-ccp.c: Use new phi_node_arg type when examining PHI node
+ arguments.
+
+ * tree-ssa-pre.c: Ditto.
+
+ * tree-ssa.c (save_chain): New local variable.
+ (build_fud_chains, search_fud_chains): Use it.
+ (marked): New local variable.
+ (tree_compute_rdefs, follow_chain): Use it.
+ (dump_reaching_defs): New function.
+ (debug_reaching_defs): New function.
+
+2002-09-09 Daniel Berlin <dberlin@dberlin.org>
+
+ * Makefile.in (tree-alias-steen.o): Remove gt-tree-alias-steen.h
+ (tree-alias-common.o): Add dependency on c-common.h
+
+ * tree-ssa-pre.c: Fix PRE now that V_USE's expr's are the entire
+ assignment, rather than just the right hand side.
+ Stop generating our own call clobbers
+
+ * tree-dfa.c (create_ref): Make sure var is not null before checking
+ TREE_THIS_VOLATILE.
+
+ * tree.h: Reorder TDI_* so ssapre comes before ssa.
+
+ * tree-dump.c: dump-tree-ssapre has to come before dump-tree-ssa
+ in the table, or else it'll never match.
+
+2002-09-09 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mf_offset_expr_of_array_ref): Fold constants along
+ the way.
+ (mf_build_check_statement_for): Ditto. Flag new COMPONENT_REFs.
+ (mx_xfn_indirect_ref): Instrument COMPONENT_REFs specially. Tweak
+ ARRAY_REF instrumentation to reduce need of copying and recursion.
+
+2002-09-09 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa.c (analyze_rdefs): Disable uninitialized variable warnings.
+
+2002-09-09 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree-ssa.o): Add dependency on tree-simple.h.
+ (tree-dfa.o): Add dependency on tree-simple.h and tree-inline.h.
+ (tree-alias-steen.o): Add dependency on c-common.h.
+ (tree-optimize.o): Add dependency on c-common.h.
+
+ * c-simplify.c (deep_copy_node): Call walk_tree with mostly_copy_tree_r.
+ (mostly_copy_tree_r): Also copy flags from original tree.
+ (mark_not_simple_r): Call set_tree_flag.
+
+ * tree-alias-steen.c: Include c-common.h.
+
+ * tree-cfg.c (map_stmt_to_bb): Remove.
+ (block_invalidates_loop): Change return type to bool.
+ (create_loop_hdr): New function.
+ (create_bb): Call it.
+ (create_bb_ann): Return newly created annotation object.
+ (remove_bb_ann): Nullify loop_hdr annotation, if there is one.
+ (tree_delete_bb): Only remove basic block annotation from
+ executables statements.
+ (is_computed_goto): New function.
+
+ * tree-dfa.c (pointer_refs): New file local variable.
+ (call_sites): New global variable.
+ (V_DEF, V_USE, V_PHI, V_PHI_ARG, E_FCALL, E_PHI, E_USE, E_KILL,
+ E_INJ): New global constants.
+ (M_DEFAULT, M_CLOBBER, M_MAY, M_PARTIAL, M_INITIAL, M_INDIRECT,
+ M_VOLATILE): New global constants.
+ (num_referenced_vars): New global variable.
+ (referenced_vars): Rename from referenced_symbols. Update all
+ users.
+ (clobber_vars_r): New function.
+ (add_default_defs): New function.
+ (add_call_site_clobbers): New function.
+ (add_ptr_may_refs): New function.
+ (add_phi_arg): New function.
+ (find_list_node): New function.
+ (remove_ref_from_list): Call it.
+ (add_ref_to_list_after): New function.
+ (is_pure_fcall): New function.
+ (fcall_takes_ref_args): New function.
+ (dump_referenced_vars): New function.
+ (debug_referenced_vars): New function.
+ (ref_type_name): New function.
+ (validate_ref_type): New function.
+ (debug_phi_args): Remove.
+ (dump_phi_args): Remove.
+ (add_referenced_var): Rename from add_ref_symbol. Update all
+ users.
+ (dump_ref): Rename from dump_varref. Update all users.
+ (debug_ref): Rename from debug_varref. Update all users.
+ (dump_ref_list): Rename from dump_varref_list. Update all users.
+ (dump_ref_array): Rename from dump_varref_array. Update all users.
+ (next_tree_ref_id): Rename from next_varref_id. Update all users.
+
+ (tree_find_refs): Rename from tree_find_varrefs. Update all users.
+ Call add_default_defs.
+ Call add_call_site_clobbers.
+ Call add_ptr_may_refs.
+ Call dump_referenced_vars.
+ Create and destroy pointer_refs list.
+
+ (find_refs_in_stmt): Set reference type to clobbering definition
+ for the ASM_OUTPUTS and ASM_CLOBBERS expressions of an ASM_STMT.
+ Set reference type to initial definition for the DECL_INITIAL node
+ of a DECL_STMT.
+ Clobber everything in CLEANUP_STMT nodes.
+
+ (find_refs_in_expr): Re-write.
+ Recursively clobber every VAR_DECL contained in non SIMPLE nodes.
+ Mark indirect pointer references with M_INDIRECT flag.
+ Add pointer references to pointer_refs list.
+ Glob references to arrays and structures.
+ Add function call expressions to call_sites list.
+
+ (empty_ref_list): Do nothing if the list is empty already.
+ (delete_ref_list): Ditto.
+ (create_ref): Add new argument ADD_TO_BB.
+ Set M_VOLATILE modifier if this is a reference to a volatile
+ variable.
+ Count number of incoming edges for V_PHI references before
+ initializing the V_PHI_ARG array.
+ Only add reference to basic block if ADD_TO_BB is true.
+ Set output reference for the parent expression for V_DEF
+ references.
+ (remove_tree_ann): Do nothing if the tree didn't have an
+ annotation.
+
+ * tree-flow.h (enum treeref_type): Remove. Update all users.
+ (union varref_def): Ditto.
+ (tree_ref): Rename from varref. Update all users.
+ (V_DEF): Declare.
+ (V_USE): Declare.
+ (V_PHI): Declare.
+ (V_PHI_ARG): Declare.
+ (E_FCALL): Declare.
+ (E_PHI): Declare.
+ (E_USE): Declare.
+ (E_KILL): Declare.
+ (E_INJ): Declare.
+ (M_DEFAULT): Declare.
+ (M_CLOBBER): Declare.
+ (M_MAY): Declare.
+ (M_PARTIAL): Declare.
+ (M_INITIAL): Declare.
+ (M_INDIRECT): Declare.
+ (M_VOLATILE): Declare.
+ (struct tree_ref_common): Rename from treeref_common. Update all
+ users.
+ Change type of field 'type' to HOST_WIDE_INT.
+ Rename field 'sym' to 'var'.
+ (struct var_ref): Rename from varref. Update all users.
+ Join the structures varuse
+ and vardef into a single structure.
+ (struct expr_ref_common): Rename from exprref_common. Update all
+ users.
+ (struct expr_use): Rename from expruse. Update all users.
+ (struct expr_phi): Rename from exprphi. Update all users.
+ (union tree_ref_d): Rename from varref_def. Update all users.
+ (EXPRPHI_PHI_ARGS): Rename from EXPRPHI_PHI_CHAIN. Update all
+ users.
+ (struct tree_ann_d): Rename field 'compound_stmt' to
+ 'compound_parent'.
+ Add field 'output_ref'.
+ (enum tree_flags): New enum.
+ (TF_REFERENCED): New flag.
+ (phi_arg): Remove.
+ (get_num_phi_args): Remove.
+ (get_phi_arg): Remove.
+
+ (struct vardef): Remove. Update all users.
+ (VARDEF_IMM_USES): Ditto.
+ (VARDEF_SAVE_CHAIN): Ditto.
+ (VARDEF_RUSES): Ditto.
+ (VARDEF_MARKED): Ditto.
+ (VARDEF_PHI_ARGS): Ditto.
+ (struct varuse): Ditto.
+ (VARUSE_IMM_RDEF): Ditto.
+ (VARUSE_RDEFS): Ditto.
+ (VARREF_ID): Ditto.
+ (VARREF_TYPE): Ditto.
+ (VARREF_BB): Ditto.
+ (VARREF_EXPR): Ditto.
+ (VARREF_OPERAND_P): Ditto.
+ (VARREF_STMT): Ditto.
+ (VARREF_SYM): Ditto.
+ (IS_DEFAULT_DEF): Ditto.
+ (IS_ARTIFICIAL_REF): Ditto.
+ (TREE_ANN): Ditto.
+ (BB_FOR_STMT): Ditto.
+ (TREE_CURRDEF): Ditto.
+ (TREE_REFS): Ditto.
+ (TREE_COMPOUND_STMT): Ditto.
+ (TREE_FLAGS): Ditto.
+ (BB_ANN): Ditto.
+ (BB_PARENT): Ditto.
+ (BB_REFS): Ditto.
+ (BB_PREV_CHAIN_P): Ditto.
+ (BB_BINDING_SCOPE): Ditto.
+ (BB_LOOP_HDR): Ditto.
+ (FOR_INIT_STMT_BB): Ditto.
+ (FOR_COND_BB): Ditto.
+ (FOR_EXPR_BB): Ditto.
+ (END_WHILE_BB): Ditto.
+ (DO_COND_BB): Ditto.
+ (BB_EMPTY_P): Ditto.
+
+ (ref_type): New inline function.
+ (ref_var): New inline function.
+ (ref_stmt): New inline function.
+ (ref_expr): New inline function.
+ (ref_bb): New inline function.
+ (ref_id): New inline function.
+ (replace_ref_operand_with): New inline function.
+ (restore_ref_operand): New inline function.
+ (imm_uses): New inline function.
+ (save_chain): New inline function.
+ (set_save_chain): New inline function.
+ (reached_uses): New inline function.
+ (marked_with): New inline function.
+ (mark_def_with): New inline function.
+ (phi_args): New inline function.
+ (num_phi_args): New inline function.
+ (phi_arg): New inline function.
+ (imm_reaching_def): New inline function.
+ (set_imm_reaching_def): New inline function.
+ (imm_reaching_def_edge): New inline function.
+ (set_imm_reaching_def_edge): New inline function.
+ (reaching_defs): New inline function.
+ (tree_annotation): New inline function.
+ (has_annotation): New inline function.
+ (bb_for_stmt): New inline function.
+ (set_bb_for_stmt): New inline function.
+ (currdef_for): New inline function.
+ (set_currdef_for): New inline function.
+ (tree_refs): New inline function.
+ (add_tree_ref): New inline function.
+ (remove_tree_ref): New inline function.
+ (compound_parent): New inline function.
+ (set_compound_parent): New inline function.
+ (set_tree_flag): New inline function.
+ (clear_tree_flag): New inline function.
+ (tree_flags): New inline function.
+ (reset_tree_flags): New inline function.
+ (output_ref): New inline function.
+ (set_output_ref): New inline function.
+ (bb_annotation): New inline function.
+ (bb_parent): New inline function.
+ (set_bb_parent): New inline function.
+ (bb_refs): New inline function.
+ (remove_bb_ref): New inline function.
+ (prev_chain_p): New inline function.
+ (set_prev_chain_p): New inline function.
+ (binding_scope): New inline function.
+ (set_binding_scope): New inline function.
+ (header_blocks): New inline function.
+ (for_init_bb): New inline function.
+ (set_for_init_bb): New inline function.
+ (for_cond_bb): New inline function.
+ (set_for_cond_bb): New inline function.
+ (for_expr_bb): New inline function.
+ (set_for_expr_bb): New inline function.
+ (end_while_bb): New inline function.
+ (set_end_while_bb): New inline function.
+ (do_cond_bb): New inline function.
+ (set_do_cond_bb): New inline function.
+ (bb_empty_p): New inline function.
+
+ (referenced_vars): Rename from referenced_symbols. Update all
+ users.
+ (num_referenced_vars): Declare.
+ (NREF_SYMBOLS): Remove. Update all users.
+ (REF_SYMBOL): Ditto.
+ (ADD_REF_SYMBOL): Ditto.
+ (referenced_var): New inline function.
+ (call_sites): Declare.
+ (next_tree_ref_id): Rename from next_varref_id. Update all users.
+ (is_computed_goto): Declare.
+ (is_pure_fcall): Declare.
+ (fcall_takes_ref_args): Declare.
+ (add_ref_to_list_after): Declare.
+ (find_list_node): Declare.
+ (ref_type_name): Declare.
+ (validate_ref_type): Declare.
+
+ * tree-optimize.c: Include c-common.h.
+ (optimize_function_tree): Store DECL_SAVED_TREE in a local
+ variable.
+
+ * tree-ssa-ccp.c (cp_lattice_meet): New function.
+ (visit_phi_node): Call it.
+ (add_outgoing_control_edges): New function.
+ (visit_expression_for): Call it.
+ Don't handle static initializers.
+ Handle computed gotos.
+ (add_control_edge): New function.
+ (visit_condexpr_for, simulate_block, add_outgoing_control_edges): Call
+ it.
+ (simulate_def_use_chains): Only look at unmodified V_USE references.
+ (ssa_ccp_substitute_constants): Ditto.
+ (evaluate_expr): Ditto.
+ (initialize): Set initial value for incoming parameters and globals
+ to VARYING.
+ Set initial value for initialized static variables to VARYING,
+ unless the variable is read-only.
+ (set_lattice_value): Don't special case globals, volatiles and
+ variables with their address taken.
+
+ * tree-ssa.c: Include tree-simple.h.
+ (tree_build_ssa): Don't add default definitions.
+ (insert_phi_terms): Add new PHI nodes at the beginning of the list
+ of references for the basic block.
+ (search_fud_chains): Add def-def chains for non-killing
+ definitions.
+ (delete_ssa): Remove list call_sites.
+ Set num_referenced_vars to 0.
+ Set referenced_vars to NULL.
+ (follow_chain): Follow def-def chains for non-killing definitions.
+ (is_upward_exposed): Change return type to bool.
+ (add_phi_arg): Remove.
+
+2002-09-06 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (deferred_static_decl*): Correct GTY markup.
+ (mudflap_enqueue_decl): Correct iteration bounds.
+ (mf_init_extern_trees): Add more constness to mf_cache_structptr_type.
+ (mf_offset_expr_of_array_ref): Remove excess mx_flagging. save_expr
+ array subscripts.
+ (mf_build_check_statement_for): Reorganize to take explicit
+ check-base/size arguments, in addition to value argument. save_expr
+ array subscripts. Copy value/base/size subtrees.
+ (mx_xfn_indirect_ref): Support marking of subtrees for nontraversal.
+ Track source line numbers more aggressively. For arrays, check bounds
+ from base through indexed element, not just the indexed element.
+ Use nontraversal flagging to eliminate some excess instrumentation.
+ (mf_xform_derefs): Support nontraversal by a hash table.
+ (*): Remove "{{{"/"}}}" folding marks.
+
+2002-09-02 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-common.[ch]: New files.
+ * tree-alias-steen.[ch]: Split out common stuff into
+ tree-alias-common.[ch].
+ * c-config-lang.in: Modify to use tree-alias-common.[ch] instead of
+ tree-alias-steen, since this is where the GTY'd stuff is now.
+ * Makefile.in: Add dependencies for tree-alias-common.[ch].
+
+2002-09-03 Diego Novillo <dnovillo@redhat.com>
+
+ * c-simplify.c (simplify_goto_stmt): New function.
+ (simplify_stmt): Call it.
+ * tree-simple.c: Document grammar for GOTO_STMT nodes.
+ (rationalize_compound_expr): Wrap it with #if 0/#endif.
+ (get_base_symbol): Minor comment fixup.
+
+2002-09-03 Frank Ch. Eigler <fche@redhat.com>
+
+ * gcc.c (MFWRAP_SPEC): Add --wrap=alloca.
+
+2002-09-01 Diego Novillo <dnovillo@redhat.com>
+
+ * c-simplify.c (simplify_stmt): Mark CLEANUP_STMTs and ASM_STMTs
+ not SIMPLE.
+ (simplify_for_stmt): Do not allow expression sequences in
+ FOR_INIT_STMT and FOR_EXPR nodes.
+ * tree-simple.c: Document difference with original SIMPLE grammar.
+
+2002-08-31 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mf_build_check_statement_for): Tolerate dereference
+ of void pointers.
+ (mx_register_decl): Correct typo in below patch.
+
+2002-08-30 Graydon Hoare <graydon@redhat.com>
+
+ * tree-mudflap.c (mx_register_decl): Mark declarations as
+ TREE_ADDRESSABLE when mudflap decides to register them.
+
+2002-08-29 Graydon Hoare <graydon@redhat.com>
+
+ * tree-mudflap.c (mx_xfn_indirect_ref): Rewrite array references as
+ pointer dereferences.
+ (struct mf_xform_decls_data): New member: param_decls.
+ (mx_register_decl): New function.
+ (mx_xfn_xform_decls): Factor code out into mx_register_decl.
+ Register live parameters with mudflap.
+ (mx_xfn_find_addrof): Notice references to fields of structures
+ and function parameters.
+
+2002-08-29 Frank Ch. Eigler <fche@redhat.com>
+
+ * c-pretty-print.c (dump_c_tree): Detect loops in statement chains
+ using a hash table to track visited status.
+ * Makefile.in: Add hashtab.h dependency.
+
+2002-08-28 Frank Ch. Eigler <fche@redhat.com>
+
+ * tree-mudflap.c (mudflap_enqueue_constant): Register non-string
+ constants also.
+ (mf_build_check_statement_for): Include pushlevel/pushdecl/poplevel
+ for local variables.
+
+2002-08-27 Frank Ch. Eigler <fche@redhat.com>
+
+ Better static registration:
+ * varasm.c (make_decl_rtl): Handle DECL_RTL_SET_P case for
+ mudflap static registration.
+ * tree-mudflap.c (mudflap_enqueue_decl): Rewrite to handle
+ deferred statics.
+ (mudflap_finish_file): Call above fn back for deferred statics.
+
+ Cleanup:
+ * tree-mudflap.c (mf_varname_tree, mf_file_function_line_tree):
+ Reorganize output_buffer reuse mechanism.
+ (mf_build_check_statement_for): Set TREE_SIDE_EFFECTS.
+ (mx_xfn_indirect_ref): Correct file/line collection tests.
+
+ Dynamic linking support:
+ * gcc.c (MFWRAP_SPEC): Make conditional on -static. Add the
+ newer wrapped functions dlopen/mmap/munmap.
+ (MFLIB_SPEC): Be sensitive to -static. Partial support for
+ dynamic linking.
+
+2002-08-26 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree-ssa.o): Add dependency on ggc.h
+ (c-simplify.o): Add dependency on langhooks-def.h
+ * c-simplify.c: Include langhooks-def.h
+ (simplify_function_tree): Do nothing if the front end does not
+ support simplification.
+
+ * tree-flow.h (struct vardef): Remove fields 'phi_chain' and
+ 'phi_chain_bb'.
+ Add field 'phi_args'.
+ (VARDEF_PHI_CHAIN): Remove. Update all users.
+ (VARDEF_PHI_CHAIN_BB): Remove. Update all users.
+ (VARDEF_PHI_ARGS): Define.
+ (struct varuse): Rename field 'chain' to 'imm_rdef'. Update all
+ users.
+ (VARUSE_IMM_RDEF): Rename from VARUSE_CHAIN. Update all users.
+ (phi_arg): New structure.
+ (get_num_phi_args): New function.
+ (get_phi_arg): New function.
+ (set_phi_arg): New function.
+ (add_phi_arg): New function.
+ (debug_phi_args): Declare.
+ (dump_phi_args): Declare.
+ * tree-dfa.c (create_ref): Remove initialization of
+ VARDEF_PHI_CHAIN and VARDEF_PHI_CHAIN_BB.
+ Initialize array VARDEF_PHI_ARGS.
+ (dump_varref): Call dump_phi_args.
+ (dump_phi_args): New function.
+ (debug_phi_args): New function.
+ * tree-ssa-ccp.c (PHI_PARMS): Remove.
+ (EIE): Remove.
+ (visit_phi_node): Get the argument's edge directly from the
+ argument instead of calling find_edge.
+ (initialize): Cast call to NUM_EDGES to unsigned.
+ * tree-ssa-pre.c: Update uses of VARDEF_PHI_CHAIN,
+ VARDEF_PHI_CHAIN_BB and VARUSE_CHAIN everywhere.
+ * tree-ssa.c: Ditto.
+ Include ggc.h.
+ (search_fud_chains): Call add_phi_arg to add arguments to each PHI
+ node.
+ (tree_ssa_remove_phi_alternative): Call set_phi_arg to switch the
+ last element with the element being removed.
+
+2002-08-26 Diego Novillo <dnovillo@redhat.com>
+
+ * c-simplify.c (mostly_copy_tree_r): Unshare STMT_EXPR
+ nodes.
+
+2002-08-25 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (find_refs_in_stmt): Replace calls to
+ RETURN_EXPR with RETURN_STMT_EXPR.
+ * c-simplify.c (simplify_return_stmt): Ditto.
+ (deep_copy_node): Ditto.
+ * c-pretty-print.c (dump_c_node): Ditto.
+
+2002-08-24 Diego Novillo <dnovillo@redhat.com>
+
+ * c-pretty-print.c: Add `break' after calls to NIY in
+ switch statements.
+
+2002-08-23 Jeffrey A Law (law@redhat.com)
+
+ * tree-ssa-ccp.c (tree_ssa_ccp): Remove #if 0 that accidentally
+ got checked in. Cleanup the cfg to remove unreachable blocks
+ discovered by CCP.
+
+ * basic-block.h (EDGE_EXECUTABLE): New edge flag.
+
+ * cfganal.c (find_edge): New function.
+
+ * ssa-ccp.c: Convert to use EDGE_EXECUTABLE bit in the
+ edge flags rather than a bitmap. Convert edge worklist
+ into a varray. Avoids expensive find_index_edge calls.
+ * tree-ssa-ccp.c: Likewise.
+
+ * tree-flow.h (tree_ssa_remove_phi_alternative): Declare.
+ * tree-ssa.c (tree_ssa_remove_phi_alternative): New function.
+ * tree-ssa-ccp.c (optimize_unexecutable_edges): Remove
+ PHI alternatives for unexecutable edges. Also remove
+ unexecutable edges from the CFG.
+
+2002-08-22 Jeffrey A Law (law@redhat.com)
+
+ * Makefile.in (tree-optimize.o): Depend on tree-dchain.o
+ * tree-optimize.c: Include tree-dchain.h.
+ (optimize_function_tree): Unconditionally build and tear down
+ the backpointers for the statement chain.
+
+2002-08-22 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (find_refs_in_stmt): Look for VARUSE references in
+ initialization expressions.
+ (find_refs_in_expr): Reformat.
+ (remove_ref_from_list): Optimize for the common case of removing
+ the head or the tail of the list.
+ (add_ref_to_list_end): Reformat comment.
+ (create_ref): Store the reference to LHS of assignment expressions.
+ (dump_varref): Also dump immediate uses of PHI nodes.
+ * tree-flow.h (IS_GHOST_DEF): Rename to IS_DEFAULT_DEF. Update all
+ callers everywhere.
+ (struct tree_ann_def): Update comments for field 'currdef'.
+ * tree-ssa-ccp.c (ssa_edges): Change type to ref_list.
+ (SSA_NAME): Remove.
+ (initialize): New function
+ (finalize): New function.
+ (visit_expression): Rename to visit_expression_for. Update all
+ callers.
+ (visit_condexpr_for): New function.
+ (visit_assignment): Rename to visit_assignment_for. Update all
+ callers.
+ (examine_flow_edges): Rename to simulate_block. Update all
+ callers.
+ (follow_def_use_chains): Rename to simulate_def_use_chains. Update
+ all callers.
+ (evaluate_expr_for): Rename to evaluate_expr. Change argument to
+ 'tree'.
+ (set_lattice_value): New function.
+ (tree_ssa_ccp): Change main loop to visit flow_edges and ssa_edges
+ alternately.
+ (visit_phi_node): Do not set the lattice value to UNDEFINED when we
+ find a non-executable edge.
+ (visit_expression_for): Default definitions for PARM_DECLs are
+ assigned a VARYING value.
+ Default definitions for any other local variables are assigned an
+ UNDEFINED value.
+ Clobber VARDEFs that are not the LHS of an assignment.
+ Clobber VARDEFs that initialize non-const static variables.
+ * tree-ssa.c (search_fud_chains): Set up def-use edges for PHI
+ nodes and regular definitions.
+
+ * tree.c (simple_cst_equal): Call simple_cst_list_equal to compare
+ CONSTRUCTOR_ELTS pointers.
+
+2002-08-22 Diego Novillo <dnovillo@redhat.com>
+
+ * c-pretty-print.c (buffer): New file local variable.
+ (initialized): New file local variable.
+ (print_c_tree): Don't call init_output_buffer. Call
+ maybe_init_pretty_print.
+ (print_c_node): Ditto.
+ (print_c_node_brief): Ditto.
+ (maybe_init_pretty_print): New function.
+ * tree-mudflap.c (mf_varname_tree): Only call init_output_buffer
+ once. Call output_clear_message_text before returning.
+
+2002-08-21 Frank Ch. Eigler <fche@redhat.com>
+
+ Support source-file/line coordinates in check/violation messages.
+ * tree-mudflap.c (mf_init_extern_trees): Add new "location" formal
+ arg to __mf_check.
+ (mf_file_function_line_tree): New function to build an actual location
+ string.
+ (build_check_statement_for): Call it / pass it.
+ (mx_xfn_indirect_ref): Track source file/line location via
+ STMT_LINENO, FILE_STMT, EXPR_WITH_FILE_LOCATION traversal memos.
+
+2002-08-21 Daniel Berlin <dberlin@dberlin.org>
+
+ * dominance.c: Cache immediate dominators.
+
+2002-08-20 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-steen.h (struct tree_alias_ops): Add flag for
+ interprocedural.
+
+ * tree-alias-steen.c (steen_alias_ops): Set interprocedural to 0
+ for now.
+ (intra_function_call): New function to handle intraprocedural calling.
+ (finc_func_aliases): Use it.
+ Handle *x = *y, *x = &y, and *x = (cast) y.
+ (display_points_to_set_helper): New function, split from ...
+ (display_points_to_set): Here.
+ (create_alias_vars): Try to print all alias vars we find in the
+ alias_vars array, rather than just those that are linked directly to
+ trees.
+ Clear arrays when we finish if we aren't interprocedural.
+
+2002-08-20 Frank Ch. Eigler <fche@redhat.com>
+
+ static object registration support:
+ * tree-mudflap.c (mudflap_enqueue_decl, mudflap_enqueue_constant):
+ Replace stubs with real code.
+ (mf_enqueue_register_call): New function to generate asm-object
+ call to __mf_register.
+ (mf_flush_enqueued_calls): New function to emit global ctor function
+ with enqueued __mf_register calls.
+ (mf_varname_tree): Tolerate being called from non-function context.
+ * c-objc-common.c: #include <tree-mudflap.h>.
+
+ gengtypes support for mudflap:
+ * Makefile.in (GTFILES): Include tree-mudflap.c.
+ (gt-tree-mudflap.h): New target.
+ * tree-mudflap.c: Annotate global tree nodes with GTY(()).
+ * tree-nomudflap.c: Add dummy ggc root table.
+
+2002-08-19 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (find_refs_in_expr): If the current sub-expression is
+ not SIMPLE, mark its parent.
+ (create_ref): If the parent expression is not SIMPLE, create
+ VARDEFs regardless of the original reference type.
+
+ * tree-ssa-ccp.c (widen_bitfield): New function.
+ (evaluate_expr_for): Call it.
+
+2002-08-18 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa-ccp.c (evaluate_expr_for): Fix thinko in
+ 2002-08-17 patch.
+
+2002-08-17 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa-ccp.c (evaluate_expr_for): keep VARREF_SYM in a local
+ variable.
+
+2002-08-16 Diego Novillo <dnovillo@redhat.com>
+
+ * basic-block.h (BB_CONTROL_EXPR): Update value.
+ (BB_LOOP_CONTROL_EXPR): Define.
+ (BB_CONTROL_ENTRY): Update value.
+ * tree-cfg.c (make_for_stmt_blocks): Flag header blocks withh
+ BB_LOOP_CONTROL_EXPR.
+ (make_while_stmt_blocks): Ditto.
+ (make_do_stmt_blocks): Ditto.
+ (tree_delete_bb): Update annotations in the loop entry block when
+ removing one of the loop expression blocks.
+
+ * tree-dfa.c (tree_find_varrefs): Disregard empty blocks.
+ (find_refs_in_stmt): Handle all the loop expression blocks in
+ FOR_STMT and DO_STMT nodes.
+ (find_refs_in_expr): Change first argument to tree *. Update all
+ callers.
+ Force all references to be definitions when the expression is not
+ in SIMPLE form.
+ Also create references for compound variables and array references.
+ Not just their individual components.
+ Always use the original parent expression when making recursive
+ calls.
+ (create_ref): Add new argument operand_p. Update all callers.
+ (remove_tree_ann): New function.
+ (dump_varref): Don't assume that the referenced symbol is a _DECL
+ node.
+ * tree-flow.h (treeref_common): Add field operand_p.
+ (VARREF_OPERAND_P): Define.
+ (BB_EMPTY_P): Define.
+ (remove_tree_ann): Declare.
+ (create_ref): Add new argument operand_p.
+ * tree-simple.c (get_base_symbol): New function.
+ * tree-simple.h (get_base_symbol): Declare.
+ * tree-ssa-ccp.c (visit_assignment): Call it.
+ (ssa_ccp_substitute_constants): Use VARREF_OPERAND_P to replace
+ values into the expression.
+ (evaluate_expr_for): Ditto.
+ Do not try to evaluate the expression if the reference is not of
+ the same type as the expression.
+ After evaluation, restore the expression to its original form.
+ * tree-ssa-pre.c (insert_occ_in_preorder_dt_order_): Update calls
+ to create_ref.
+ (finalize_): Ditto.
+ (expr_phi_insertion): Ditto.
+ * tree-ssa.c (tree_build_ssa): Ditto.
+ (insert_phi_terms): Ditto.
+ (delete_ssa): Call remove_tree_ann.
+
+2002-08-15 Diego Novillo <dnovillo@redhat.com>
+
+ * c-pretty-print.c: Move extern definitions to diagnostic.h.
+ (print_c_node_brief): New function.
+ (debug_c_node_brief): New function.
+ (debug_c_node): Add option for showing brief versions of statement
+ nodes. Update all callers.
+ (print_declaration): Ditto.
+ * c-simplify.c (simplify_function_tree): Add newline to debug
+ output.
+ * c-tree.h (print_c_node_brief): Declare.
+ (debug_c_node_brief): Declare.
+ * tree-cfg.c: Call print_c_node_brief in debugging otuput.
+ * tree-mudflap.c (dump_c_node): Remove extern declaration.
+ (mf_varname_tree): Update call to dump_c_node.
+
+2002-08-15 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-cfg.c (find_expr_in_tree_helper): Renamed from find_expr_in_tree.
+ (find_expr_in_tree): Redone.
+
+2002-08-15 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-cfg.c (insert_before_ctrl_stmt): Fix insertion for various
+ parts of for loop.
+
+ * tree-ssa-pre.c (finalize_1): Set EXPR_STMT type to type of
+ expression in it.
+
+2002-08-14 Frank Ch. Eigler <fche@redhat.com>
+
+ * gcc.c (LINK_COMMAND_SPEC): Tweak placement of %(mflib).
+
+2002-08-14 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-simple.h (is_simple_decl_stmt): Declare.
+
+2002-08-13 Frank Ch. Eigler <fche@redhat.com>
+
+ * gcc.c (MFWRAP_SPEC, MFLIB_SPEC): New macros, splitting MFLIB_SPEC.
+ (mfwrap_spec, mflib_spec): Define corresponding vars.
+ (static_specs): Define correponding spec aliases.
+ (LINK_COMMAND_SPEC): Include -fmudflap refs to new spec aliases.
+ (cpp_unique_options): Move -fmudflap MFCPP_SPEC clause here.
+ (cc1_options): Move -fmudflap MFCC1_SPEC clause here.
+ (MFCC1_SPEC, MFCPP_SPEC, MFLIB_SPEC): Remove macros and uses.
+
+2002-08-13 Graydon Hoare <graydon@redhat.com>
+
+ * tree-mudflap.c (mf_build_check_statement_for): Factor code out of
+ mx_xfn_indirect_ref for use in ARRAY_REF case.
+ (mf_build_check_statement_for): Check size of underlying object
+ rather than size of pointer.
+ (mx_xfn_indirect_ref): Check ARRAY_REF expressions.
+ (mf_offset_expr_of_array_ref): New function to calculate array ref
+ offsets.
+
+2002-08-13 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-simple.c (is_simple_condexpr): Update comment.
+ * tree-ssa-ccp.c (ssa_ccp_substitute_constants): Add debugging code.
+
+2002-08-12 Jason Merrill <jason@redhat.com>
+
+ * c-typeck.c (build_component_ref): Don't add a NON_LVALUE_EXPR
+ in C99 mode.
+
+ * c-simplify.c (simplify_expr): Always simplify. Loop if *expr_p
+ changed.
+ (simplify_addr_expr): Just replace *expr_p if we have a '&*'.
+ * tree-simple.c (is_simplifiable_builtin): Add more tree codes.
+
+2002-08-11 Diego Novillo <dnovillo@redhat.com>
+
+ * c-simplify.c: Fix typo. Substitute CHECKING with ENABLE_CHECKING.
+ * tree-cfg.c: Ditto.
+ * tree-dfa.c: Ditto.
+ * tree-ssa-ccp.c: Ditto.
+ * tree-ssa.c: Ditto.
+
+2002-08-11 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (find_refs_in_expr): Use the given ref_type for some unary
+ expressions.
+ (create_ref): Insert ghost definitions at the beginning of the
+ basic block.
+ (find_expr_in_tree): Ignore IDENTIFIER_NODE.
+ * tree-flow.h (treeref_common): Move the id field to the end of the
+ structure.
+ (IS_GHOST_DEF): Redefine to return non zero for definitions
+ without an associated expression in basic block 0.
+ * tree-ssa-ccp.c (tree_ssa_ccp): Use last_basic_block to allocate
+ executable_blocks.
+ (visit_expression): Set the lattice value for ghost definitions to
+ VARYING.
+ (examine_flow_edges): Update comments.
+ * tree-ssa.c (tree_build_ssa): Create ghost definitions in basic
+ block 0.
+ (insert_phi_terms): Don't ignore ghost definitions.
+
+ * c-simplify.c (simplify_function_tree): Return 0 if the function's
+ body is not a COMPOUND_STMT.
+ Return 0 if simplification failed.
+ (simplify_expr): Change to return int. Return non zero if
+ simplification was successful.
+ (c_simplify_expr): Add default case to avoid compile time warnings.
+ (create_tmp_alias_var): Reformat comment.
+ * tree-simple.h (simplify_expr): Change return type to int.
+
+ * c-simplify.c: Guard consistency checks with #if defined CHECKING
+ everywhere.
+ * tree-cfg.c: Ditto.
+ * tree-dfa.c: Ditto.
+ * tree-ssa-ccp.c: Ditto.
+ * tree-ssa.c: Ditto.
+
+ * c-simplify.c: Include hard-reg-set.h, basic-block.h and
+ tree-flow.h.
+ (mark_not_simple_r): New function.
+ (simplify_expr): Temporarily mark VA_ARG_EXPR and BIT_FIELD_REF
+ trees as not simplifiable.
+ (simplify_call_expr): If the builtin cannot be simplified, flag it.
+ * Makefile.in (c-simplify.o): Update dependencies.
+ * tree-dfa.c (create_ref): Variable references inside
+ non-simplifiable expressions are always considered definitions.
+ * tree-flow.h (TF_NOT_SIMPLE): New flag.
+ * tree-simple.c (is_simplifiable_builtin): Update comments.
+
+ * c-pretty-print.c (dump_c_node): Unparse anonymous structures and
+ unions.
+ Change rendering for SAVE_EXPR and BIT_FIELD_REF.
+
+ * Makefile.in (tree-mudflap.o, tree-nomudflap.o): Add.
+
+2002-08-11 Frank Ch. Eigler <fche@redhat.com>
+
+ Prototype -fmudflap support.
+ * Makefile.in (C_AND_OBJC_OBJS): Add tree-mudflap.o.
+ (OBJS): Add tree-nomudflap.o.
+ * flags.h (flag_mudflap): New flag.
+ * toplev.c: Map "-fmudflap" to that flag.
+ * c-decl.c (c_expand_body): Call mudflap_c_function if flag_mudflap.
+ * c-objc-common.c (c_objc_common_finish_file): Add mudflap hook.
+ * varasm.c (make_decl_rtl): Add mudflap hook.
+ (output_constant_def_contents): Ditto.
+ * tree-mudflap.c: New file: implement mudflap instrumentation.
+ * tree-nomudflap.c: New file: stub functions for non-C frontends.
+ * tree-mudflap.h: New file: define exported functions.
+ * gcc.c (MFLIB_SPEC, MFCC1_SPEC, MFCPP_SPEC): Add general
+ -fmudflap spec mappings.
+ * c-simplify.c (simplify_stmt): Stub: handle CLEANUP_STMT nodes.
+ * tree-dfa.c (find_refs_in_stmt): Ditto.
+ * c-pretty-print.c (dump_c_node): Ditto.
+ (print_declaration): Handle "extern" decls. Handle arrays with
+ indefinite sizes.
+ * tree-simple.h (is_simple_stmt, is_simple_compstmt): Remove decls.
+
+2002-08-11 Jason Merrill <jason@redhat.com>
+
+ * c-simplify.c (simplify_self_mod_expr): Unshare the lhs before
+ using it again.
+ (simplify_compound_lval): Don't unshare.
+
+ * c-simplify.c (c_simplify_expr): Check statement_code_p.
+
+ * c-simplify.c (maybe_fixup_loop_cond): Move to cp/cp-simplify.c.
+ (simplify_for_stmt): Don't call it.
+ (simplify_while_stmt): Don't call it.
+
+2002-08-11 Diego Novillo <dnovillo@redhat.com>
+
+ * c-simplify.c (simplify_compound_lval): Use mostly_copy_tree_r.
+
+2002-08-09 Jason Merrill <jason@redhat.com>
+
+ * langhooks-def.h: Replace the simplify_function_tree hook
+ with a simplify_expr hook.
+ * langhooks.h: Likewise.
+ * langhooks.c: Replace lhd_simplify_function_tree with
+ lhd_simplify_expr.
+ * c-lang.c (LANG_HOOKS_SIMPLIFY_FUNCTION_TREE): Don't define.
+ (LANG_HOOKS_SIMPLIFY_EXPR): Define.
+ * c-decl.c (c_expand_body): De-hook simplify_function_tree.
+ * c-common.h: Declare c_simplify_expr.
+ * c-simplify.c (simplify_function_tree): Rename from
+ c_simplify_function_tree. Call simplify_expr instead of
+ simplify_stmt.
+ (c_simplify_expr): Split out from...
+ (simplify_expr): ...here. No longer static. Call langhook.
+ (is_simple_decl_stmt): Move here from tree-simple.c.
+ * tree-simple.c: Don't include c-tree.h.
+ (is_simple_stmt, is_simple_compstmt): Remove.
+ (is_simple_decl_stmt): Move to c-simplify.c.
+ * tree.h: Declare simplify_function_tree.
+ * tree-simple.h: Declare simplify_expr, add_tree.
+
+ * tree-simple.c (rationalize_compound_expr): New fn.
+
+2002-08-07 Diego Novillo <dnovillo@redhat.com>
+
+ * basic-block.h (EDGE_TRUE_VALUE): Define.
+ (EDGE_FALSE_VALUE): Define.
+ * tree-cfg.c: Include c-tree.h.
+ (make_for_stmt_edges): Call simple_cst_equal to determine infinite
+ and zero iteration loops.
+ Set EDGE_TRUE_VALUE and EDGE_FALSE_VALUE to edges coming out of
+ predicate block.
+ (make_while_stmt_edges): Ditto.
+ (make_do_stmt_edges): Ditto.
+ (make_if_stmt_edges): Set EDGE_TRUE_VALUE and EDGE_FALSE_VALUE to
+ edges coming out of predicate block.
+
+ * c-simplify.c (simplify_compound_lval): Unshare the compound
+ reference before simplification.
+
+ * tree-cfg.c (insert_before_ctrl_stmt): Call print_c_node instead of
+ print_node_brief.
+ (insert_before_normal_stmt): Ditto.
+ (insert_after_ctrl_stmt): Ditto.
+ (insert_after_normal_stmt): Ditto.
+ (insert_after_loop_body): Ditto.
+ (replace_expr_in_tree): Ditto.
+ (tree_dump_bb): Ditto.
+
+ * tree-dfa.c: Include c-tree.h
+ (next_varref_id): New global variable.
+ (tree_find_varrefs): Initialize it to 0.
+ (create_ref): Increment it after creating a new reference. Store
+ it in ref.common.id.
+ Add the new reference to the list of references for the containing
+ expression.
+ (dump_varref): Show the reference ID.
+ * tree-flow.h (treeref_common): Add field 'id'.
+ (VARREF_ID): Define.
+
+ * tree-dump.c (dump_files): Re-order dump files.
+ * tree.h (tree_dump_index): Ditto.
+
+ * tree-optimize.c (optimize_function_tree): Remove blank lines.
+
+ * tree-simple.c: Remove unary operator '!' from grammar.
+
+ * tree-flow.h (tree_ann_def): Add field 'flags'.
+ (TF_FOLD): Define.
+ (TREE_ANN): Re-define into an lvalue.
+ (BB_FOR_STMT): Ditto.
+ (TREE_CURRDEF): Ditto.
+ (next_varref_id): Declare.
+ * tree-ssa-ccp.c: Include tree-simple.h
+ (ssa_edges): Convert sbitmap into varray_type. Update all uses.
+ (decl_map): Remove.
+ (SSA_NAME): Use VARREF_ID instead of DECL_UID.
+ (visit_assignment): New function.
+ (evaluate_expr_for): New function.
+ (dump_lattice_value): New function.
+ (tree_ssa_ccp): Add debugging dumps.
+ Remove #if 0 code everywhere.
+ (visit_phi_node): Add debugging dumps.
+ Also visit PHI arguments.
+ Remove basic block argument
+ (visit_expression): Re-implement.
+ (examine_flow_edges): Add debugging dumps.
+ (ssa_ccp_substitute_constants): Add debugging dumps.
+ Update comments.
+ Mark and fold expressions with substituted constants.
+ * tree-ssa.c (search_fud_chains): Don't check if BB_REFS(bb) is
+ empty before iterating.
+ Add comment explaining how we chain PHI node arguments to their
+ originating basic block.
+
+ * Makefile.in (tree-cfg.o, tree-dfa.o, tree-ssa-ccp.o): Update
+ dependencies.
+
+2002-07-29 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (tree_perform_ssapre): Ben forgot to add a
+ dump_begin call when he removed the before dump.
+
+2002-07-24 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-ecr.c (ECR_new_with_type): Use correct number in mapping.
+
+2002-07-23 Daniel Berlin <dberlin@dberlin.org>
+
+ * c-simplify.c (simplify_for_stmt): Deep copy the result of the
+ tail_expression, so it's unshared.
+
+2002-07-23 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-flow.h: Add prototype for create_alias_vars.
+
+ * tree-alias-steen.c (display_points_to_set): New function.
+ (init_alias_vars): Display points to sets when we are done.
+
+ * disjoint-set.h (disjoint_set_def): ptr_alias to ECR_def so that
+ we mark parent properly.
+
+2002-07-24 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (GTFILES): Move tree-alias-type.[ch],
+ tree-alias-ecr.[ch], tree-alias-steen.[ch] from ...
+ * c-config-lang.in (gtfiles): ... here.
+
+ * tree-simple.c (is_simplifiable_builtin): Replace
+ BUILT_IN_VARARGS_START with BUILT_IN_VA_START.
+
+2002-07-23 Andreas Jaeger <aj@suse.de>
+
+ * tree-ssa-pre.c (hash_expr_tree): Remove.
+
+ * c-call-graph.c (write_dtd): Remove.
+
+ * tree-ssa.c (delete_refs): Remove.
+
+2002-07-23 Andreas Jaeger <aj@suse.de>
+
+ * gengtype.c (open_base_files): Add tree.h.
+
+ * tree-alias-type.h: Remove inclusion of tree.h.
+
+ * tree-alias-steen.c: Include tree.h.
+ Add prototype for create_fun_alias_var_ptf.
+
+ * tree-alias-ecr.c: Add prototype for ECR_add_pending.
+
+ * tree-ssa-pre.c (calculate_preorder): Remove unused variables.
+
+ * tree-simple.c: Include expr.h and rtl.h for prototypes.
+
+ * tree-optimize.c: Include tree-alias-steen.h for prototypes.
+
+ * Makefile.in (tree-optimize.o): Add tree-alias-steen.h.
+ (tree-simple.o): Add expr.h and rtl.h.
+ (tree-alias-steen.o): Add tree.h.
+
+ * diagnostic.h: Add declaration of debug_output_buffer.
+
+ * c-call-graph.c (construct_call_graph): Make static to follow
+ declaration.
+ (construct_call_graph): Use #if 0 instead of C++ comments to
+ disable code.
+
+2002-07-20 Andreas Jaeger <aj@suse.de>
+
+ * doc/invoke.texi (Option Summary): Fix syntax.
+
+2002-07-19 Jason Merrill <jason@redhat.com>
+
+ * c-simplify.c (simplify_return_stmt): Do simplify a returned
+ expression in a void function.
+
+ * c-simplify.c (simplify_stmt_expr): Handle C++ return semantics.
+
+2002-07-19 Jason Merrill <jason@redhat.com>
+
+ * c-pretty-print.c (dump_c_node) [TARGET_EXPR]: Handle.
+ [COND_EXPR]: Print a returned expression in a void function.
+
+2002-07-19 Ben Elliston <bje@redhat.com>
+
+ * tree-ssa-pre.c (tree_perform_ssapre): Don't dump the original
+ tree before applying this optimisation.
+
+ * flags.h (flag_dump_tree_all_ssa): New flag.
+ * toplev.c (flag_dump_tree_all_ssa): New flag.
+ (f_options): Add "dump-tree-all-ssa" option.
+ (process_options): Process flag_dump_tree_all_ssa.
+ * tree.h (dump_enable_all_ssa): Declare.
+ * tree-dump.c (dump_enable_all_ssa): New function.
+ * doc/invoke.texi (Option Summary): Add -fdump-tree-all-ssa and
+ -fdump-tree-ssapre options.
+ (Debugging Options): Describe in more detail.
+ * c-simplify.c (c_simplify_function_tree): Dump the original tree
+ only if a TDI_original dump is requested, rather than TDI_simple.
+
+ * tree-dump.c (dump_begin): Include phase number in dump filename.
+
+2002-07-18 Ben Elliston <bje@redhat.com>
+
+ * tree-dump.c (dump_files): Rename "unparse" to "raw".
+ * tree.h (TDF_UNPARSE): Rename from this ..
+ (TDF_RAW): .. to this.
+ * tree-ssa-pre.c (tree_perform_ssapre): Use TDF_RAW and invert the
+ logical sense of this flag.
+ * tree-ssa-ccp.c (tree_ssa_ccp): Likewise.
+ * c-simplify.c (c_simplify_function_tree): Likewise.
+
+2002-07-18 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (calculate_preorder): New function.
+ (tree_perform_ssapre): Use it, rather than
+ flow_compute_preorder_tranversal, which seems to not do
+ what we want.
+
+2002-07-18 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-type.c: Move gt-tree-alias-type include to end of file.
+
+ * tree-alias-steen.c: Move gt-tree-alias-steen include to end of file.
+
+2002-07-18 Daniel Berlin <dberlin@dberlin.org>
+
+ * gengtype.c (get_base_file_bitmap): Mark tree-alias-* and
+ disjoint-set* as c/c++/objc files only.
+
+ * Makefile.in (gt-tree-alias-type.h): Add.
+ (tree-alias-type.o): Add dependency on gt-tree-alias-type.h.
+
+ * tree-alias-type.c: Include gt-tree-alias-type.h.
+ (alias_bottom): Add a GTY marked version of alias_bottom here.
+
+ * tree-alias-type.h: Remove the GTY marker from alias_bottom.
+
+2002-07-17 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-ecr.c (ECR_union_pending_sets): Only clear bitmap if
+ it's not NULL.
+
+2002-07-16 Jason Merrill <jason@redhat.com>
+
+ * c-simplify.c (add_tree): Build an EXPR_STMT immediately.
+ (convert_to_stmt_chain): Remove.
+ (simplify_stmt, simplify_for_stmt, simplify_while_stmt,
+ simplify_do_stmt, simplify_expr_wfl, tail_expression): Adjust.
+
+2002-07-17 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-alias-ecr.c: New file. Equivalence Class Representation.
+
+ * tree-alias-steen.c: New file. Steengaard Alias Analysis.
+
+ * disjoint-set.c: New file. Disjoint set data structure.
+
+ * tree-alias-type.c: New file. Alias types.
+
+ * c-simplify.c (create_tmp_alias_var): New function, like
+ create_tmp_var, but doesn't add it to the current binding.
+
+ * tree-simple.h: Prototype for create_tmp_alias_var.
+
+ * tree-optimize.c (build_tree_ssa): Create alias variables, if
+ requested.
+
+ * flags.h: Add flag_tree_points_to.
+
+ * toplev.c: Ditto.
+
+ * gengtype.c (open_base_files): Add disjoint-set.h,
+ tree-alias-ecr.h, tree-alias-type.h, tree-flow.h.
+
+ * Makefile.in (C_AND_OBJC_OBJS): Add disjoint-set.o,
+ tree-alias-ecr.o, tree-alias-type.o, tree-alias-steen.o.
+ (tree-alias-steen.o): Add dependencies.
+ (tree-alias-ecr.o): Ditto.
+ (tree-alias-type.o): Ditto.
+ (disjoint-set.o): Ditto.
+
+2002-07-10 Daniel Berlin <dberlin@dberlin.org>
+ Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (C_AND_OBJC_OBJS): Add tree-ssa-ccp.o
+ * flags.h (flag_tree_ssa_ccp): Declare.
+ * fold-const.c (eval_subst): Make extern.
+ * toplev.c (flag_tree_ssa_ccp): Define.
+ (f_options): Document -ftree-ssa-ccp.
+ * tree-dump.c (dump_files): Add -fdump-tree-ccp.
+ * tree-flow.h (tree_perform_ssapre): Move declaration ...
+ * tree-optimize.h: ... here.
+ (tree_ssa_ccp): Declare.
+ * tree-optimize.c (optimize_function_tree): Call tree_ssa_ccp.
+ * tree-ssa-ccp.c: New file.
+ * tree.c (next_decl_uid): Remove static declaration.
+ * tree.h (next_decl_uid): Declare.
+ (tree_dump_index): Add TDI_ccp.
+ * cp/Make-lang.in (CXX_C_OBJS): Add tree-ssa-ccp.o.
+ * doc/invoke.texi: Document -ftree-ssa-pre and -ftree-ssa-ccp.
+
+2002-07-09 Daniel Berlin <dberlin@dberlin.org>
+
+ s/varrays of refs/ref_list of refs/g
+
+ * tree-flow.h: Add ref_list structure.
+ Add prototypes for ref_list functions.
+ (FOR_EACH_REF, FOR_EACH_REF_REV): New macros to iterate through
+ ref lists.
+ * tree-cfg.c, tree-ssa.c, tree-ssa-pre.c: Update all uses.
+
+ * tree-dfa.c (create_ref_list): New function.
+ (delete_ref_list): Ditto.
+ (empty_ref_list): Ditto.
+ (add_ref_to_list_end): Ditto.
+ (add_ref_to_list_begin): Ditto.
+ (remove_ref_from_list): Ditto.
+
+2002-07-04 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-simple.c (is_simplifiable_builtin): Don't simplify target
+ builtins.
+
+2002-07-03 Diego Novillo <dnovillo@redhat.com>
+
+ * c-simplify.c (simplify_decl_stmt): Unshare the
+ initializer nodes before simplification.
+
+2002-06-29 Aldy Hernandez <aldyh@quesejoda.com>
+ Diego Novillo <dnovillo@redhat.com>
+
+ * c-simplify.c (simplify_call_expr): Do not bail on all builtins.
+ (is_simple_call_expr): Same.
+ (simplify_addr_expr): New function.
+ (simplify_expr): Call it.
+
+ * tree-simple.c (is_simplifiable_builtin): New.
+ (is_simple_compound_lval): Do not bail on INDIRECT_REF.
+
+ * tree-simple.h: New prototype for is_simplifiable_builtin.
+
+2002-06-26 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa.c (tree_build_ssa): Call free_dominance_info, not
+ free, on idom.
+
+ * tree-ssa-pre.c (compute_domchildren): Update to use new
+ dominance_info structure, rather than idom array.
+ (tree_perform_ssapre): Don't forget to free the dominance info.
+
+ s/VARRAY_FREE/VARRAY_CLEAR/g now that VARRAY's are ggc allocated.
+
+2002-06-24 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-ssa.c (build_fud_chains): Use dominance_info instead of int *.
+ (search_fud_chains): Ditto.
+ Call get_immediate_dominator.
+ * tree-ssa-pre.c (a_dom_b): Call dominated_by_p.
+ (pre_idom): Change type to dominance_info. Update all uses.
+ (pre_doms): Remove. Update all uses.
+
+2002-06-20 Jason Merrill <jason@redhat.com>
+
+ Simplify DECL_STMT, CONSTRUCTOR and COMPOUND_LITERAL_EXPR.
+ * tree-simple.c (is_simple_decl_stmt): New fn.
+ (is_simple_constructor, is_simple_constructor_elt): New fns.
+ (is_simple_stmt, is_simple_unary_expr): Use them.
+ (is_simple_modify_expr): Accept an INIT_EXPR.
+ (is_simple_id): Don't allow a COMPOUND_LITERAL_EXPR.
+ (is_simple_unary_expr): Here either.
+ * c-simplify.c (simplify_decl_stmt, simplify_constructor): New fns.
+ (simplify_compound_literal_expr): New fn.
+ (simplify_stmt, simplify_expr): Use them.
+ (get_initialized_tmp_var): Use an INIT_EXPR.
+ (simplify_modify_expr): Accept an INIT_EXPR.
+ (simplify_for_stmt): Call simplify_decl_stmt.
+ (get_name): Don't crash if the decl is anonymous.
+ (tail_expression): New fn.
+ * tree-simple.h: Declare new fns.
+ * c-pretty-print.c (dump_c_node) [INIT_EXPR]: Print like MODIFY_EXPR.
+ (dump_c_node, op_prio): Handle COMPOUND_LITERAL_EXPR.
+ * c-simplify.c (simplify_expr_wfl): Only wrap pre and post stuff
+ that came from our subexpression.
+ (simplify_stmt): Restore stmts_are_full_exprs_p.
+
+ * c-simplify.c (simplify_expr_wfl): Bracket substatements with
+ FILE_STMTs rather than wrapping them in EXPR_WITH_FILE_LOCATION.
+ (simplify_stmt): Update lineno and input_filename from stmts.
+ (simplify_expr et al): Don't copy lineno between stmts. Don't pass
+ enclosing stmt down.
+ (update_line_number): Remove.
+
+ * c-simplify.c (simplify_expr_stmt): Don't check
+ is_last_stmt_of_scope.
+ (simplify_stmt_expr): Check it here. Set *expr_p to void_zero_node
+ instead of NULL_TREE.
+ (expr_has_effect): No need to deal with NULL exprs now.
+ (simplify_expr_wfl): Likewise.
+
+2002-06-18 Diego Novillo <dnovillo@redhat.com>
+
+ * c-simplify.c (strip_off_ending): Rename to remove_suffix.
+ Update callers.
+ (is_last_stmt_of_scope): New function.
+ (simplify_expr_stmt): Call it.
+ (stmt_has_effect): Ditto.
+ (c_simplify_function_tree): Update comment.
+
+2002-06-18 Jason Merrill <jason@redhat.com>
+
+ * c-simplify.c (maybe_fixup_loop_cond): New fn for C++ conditions.
+ (simplify_for_stmt, simplify_while_stmt): Use it.
+
+ * c-pretty-print.c (dump_c_node) [COMPONENT_REF]: Print "->" if
+ appropriate.
+
+2002-06-19 Jason Merrill <jason@redhat.com>
+
+ * c-simplify.c (simplify_stmt_expr): New fn.
+ (simplify_expr): Call it.
+ (stmt_expr_level): Remove.
+ (stmt_has_effect, c_simplify_function_tree): Remove refs.
+ (expr_has_effect): Deal with null expression.
+ (simplify_expr_wfl): If the subexpression is simplified away, drop
+ this one, too. Don't wrap statements.
+ * tree-simple.c (is_simple_unary_expr): Don't allow a STMT_EXPR.
+ * tree-inline.c (copy_tree_r): Clear the aux field in the copies.
+
+2002-06-17 Frank Ch. Eigler <fche@redhat.com>
+
+ * c-pretty-print.c (dump_c_node): Print pointer-type
+ integer constants as raw numbers with a "B" (bytes) suffix.
+
+2002-06-17 Jason Merrill <jason@redhat.com>
+
+ * c-simplify.c (simplify_stmt): Take a tree *.
+ (various): Adjust.
+
+2002-06-16 Daniel Berlin <dberlin@dberlin.org>
+
+ * c-simplify.c (get_name): New function.
+ (get_initialized_tmp_var): Use it to try to get a prefix for
+ create_tmp_var from the value we are initializing to.
+ (simplify_cond_expr): Add prefix for create_tmp_var.
+ (create_tmp_var): Add prefix argument.
+
+ * tree-simple.h: Change create_tmp_var prototype to match.
+
+ * tree-ssa-pre.c: Change create_tmp_var call.
+
+2002-06-15 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (c-decl.o): Add dependency on langhooks.h
+ (c-simplify.o): Add dependency on flags.h, langhooks.h, toplev.h
+ and rtl.h.
+ * c-decl.c: Include langhooks.h.
+ (c_expand_body): Simplify the function. If it succeeds and
+ -ftree-ssa is enabled, call optimize_function_tree.
+ * c-simplify.c: Include flags.h, rtl.h and toplev.h.
+ (simplify_expr_stmt): New function.
+ (simplify_stmt): Call it.
+ * tree-optimize.c: Don't include langhooks.h.
+ (optimize_function_tree): Don't call lang_hooks.simplify_function_tree.
+
+ * c-decl.c (c_expand_body): Do not simplify nor optimize the
+ function if -fdisable-simple is given.
+ * c-simplify.c (simplify_expr): Use is_simple_addr_expr_arg when
+ simplifying ADDR_EXPR nodes.
+ * flags.h (flag_disable_simple): Declare.
+ * toplev.c (flag_disable_simple): Define.
+ (f_options): Document -fdisable-simple.
+ (process_options): Warn if -fdisable-simple is used with
+ optimization enabled.
+ * tree-simple.c (is_simple_addr_expr_arg): New function.
+ (is_simple_unary_expr): Call it.
+ * tree-simple.h (is_simple_addr_expr_arg): Declare.
+ * doc/invoke.texi: Document -fdisable-simple.
+
+ * c-pretty-print.c (dump_c_node): Handle DECL_STMT nodes inside
+ FOR_INIT_STMT.
+ * c-simplify.c (c_simplify_function_tree): Don't do anything if the
+ program had errors.
+ (simplify_stmt): Skip DECL_STMTs.
+ (simplify_for_stmt): Handle DECL_STMT nodes inside FOR_INIT_STMT.
+ (simplify_save_expr): New function.
+ (simplify_expr): Call it.
+ (tree_last_decl): Handle cases where DECL_STMTs are found before
+ the body of the function.
+ * tree-simple.c (is_simple_stmt): Handle DECL_STMT nodes inside
+ FOR_INIT_STMT.
+ (is_simple_compound_lval): Handle nodes wrapped in NON_LVALUE_EXPR.
+
+2002-06-14 Frank Ch. Eigler <fche@redhat.com>
+
+ * c-pretty-print.c (dump_c_node): Print more type qualifiers,
+ especially for pointers.
+
+2002-06-11 Diego Novillo <dnovillo@redhat.com>
+
+ * c-simplify.c: Remove folding markers.
+ (insert_before_first): Remove unused function.
+ * tree-cfg.c: Remove folding markers.
+ * tree-dfa.c: Ditto.
+ * tree-flow.h: Ditto.
+ * tree-optimize.c: Ditto.
+ * tree-optimize.h: Ditto.
+ * tree-simple.c: Ditto.
+ * tree-ssa.c: Ditto.
+
+2002-06-11 Jason Merrill <jason@redhat.com>
+
+ * c-simplify.c (add_tree): Don't deep-copy expressions.
+ (simplify_for_stmt): Only deep-copy pre_cond_s the first time.
+ Don't deep copy expr_chain.
+
+2002-06-10 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (remove_bb_ann): Don't call VARRAY_FREE.
+ * tree-dfa.c (create_ref): Use sizeof (ref) instead of
+ refs->element_size.
+ * tree.h (struct tree_common): Skip field 'aux' from GC type
+ information.
+ * tree-optimize.c (optimize_function_tree): Don't call
+ VARRAY_REF.
+ * tree-ssa.c (insert_phi_terms): Ditto.
+ (delete_refs): Ditto.
+ * c-simplify.c (simplify_array_ref): Ditto.
+ * simple-break-elim.c: Disable whole file.
+ * simple-goto-elim.c: Disable whole file.
+
+2002-06-10 Jason Merrill <jason@redhat.com>
+
+ * c-simplify.c (simplify_switch_stmt): Let simplify_expr handle
+ post-effects. Reorder.
+ (simplify_if_stmt): Likewise. Don't build redundant comparison.
+ (simplify_do_stmt, simplify_while_stmt): Likewise.
+ (simplify_for_stmt): Likewise. Remove POST_P parm.
+ (simplify_stmt): Adjust.
+ (insert_before_first): #if 0, no longer used.
+
+ * c-pretty-print.c (dump_c_node): Print FIX_TRUNC_EXPR, FLOAT_EXPR
+ et al as casts. Add parens as needed.
+
+ * tree-simple.c (is_union_based_ref): New fn.
+ (is_simple_min_lval): Use it. Rename from is_simple_arraybase.
+ (is_simple_arrayref): Adjust. Use loop instead of recursion.
+ (is_simple_compref): Likewise.
+ (is_simple_compref_lhs): Remove.
+ * tree-simple.h: Adjust.
+ * c-simplify.c (simplify_array_ref): Adjust.
+ (simplify_component_ref): Adjust.
+
+ * c-simplify.c (simplify_expr_common): Tweak ordering.
+ (get_initialized_tmp_var): Let simplify_expr handle post-effects.
+ * tree-simple.c (is_simple_stmt): Accept an rhs for a return expr.
+
+ * c-simplify.c (simplify_boolean_expr): Avoid redundant tests.
+ Give the temp the appropriate type for a boolean value, and
+ reconvert at the end.
+
+ * c-simplify.c (simplify_self_mod_expr): Don't duplicate side-effects.
+
+ * c-simplify.c (simplify_return_stmt): Accept a SIMPLE rhs.
+ Just hand off to simplify_expr.
+
+ * c-simplify.c (get_initialized_tmp_var): New fn.
+ (simplify_expr_common): Use it. Handle post-effects internally if
+ POST_P is NULL.
+ (is_simple_tmp_var): Rename from simple_tmp_var_p.
+ * tree-simple.h: Adjust.
+
+2002-06-09 Diego Novillo <dnovillo@redhat.com>
+
+ * c-simplify.c (simplify_return_stmt): Update folding markers.
+ (build_addr_expr): Ditto.
+ * langhooks.h (struct langhooks): Document simplify_function_tree
+ hook.
+
+2002-06-09 Jason Merrill <jason@redhat.com>
+
+ * c-simplify.c (simplify_expr_common): Handle creating both lvalue
+ and rvalue temps. Add new parameter to specify which.
+ (simplify_expr): Now just a wrapper.
+ (simplify_lvalue_expr): Likewise.
+ (simplify_expr_either): New wrapper.
+ (simplify_component_ref): Use it instead of simplify_lvalue_expr.
+
+ * c-pretty-print.c (debug_c_tree): Add a trailing newline.
+ (debug_c_node): Likewise.
+ * gdbinit.in (pct): New macro, calls debug_c_tree.
+
+2002-06-08 Jason Merrill <jason@redhat.com>
+
+ * tree-simple.c (is_simple_unary_expr): Only allow the address of
+ a varname.
+ (is_simple_id): Allow STRING_CST.
+ * c-simplify.c (simplify_expr_common): Split out from simplify_expr.
+ Do simplify ADDR_EXPR.
+ (simplify_lvalue_expr): Use it and build_addr_expr. Take
+ simple_test_f.
+ (simplify_modify_expr): Adjust.
+ (build_addr_expr): New fn.
+ (simplify_array_ref): Use simplify_lvalue_expr.
+ (simplify_component_ref): Likewise.
+
+ * tree-simple.c (is_simple_rhs): Remove condexpr rule.
+ (is_simple_compref_lhs): Remove &ID.idlist rule.
+ (is_simple_relop): New fn.
+ (is_simple_binary_expr, is_simple_condexpr): Use it.
+ * tree-simple.h: Declare it.
+
+ * c-simplify.c (create_tmp_var): Refuse to create an array temp.
+ (simple_tmp_var_p): New fn.
+ (simplify_lvalue_expr): Use it; make sure we don't return a temp.
+ * tree-simple.h: Declare it.
+
+ * c-pretty-print.c (dump_c_node) [ARRAY_REF]: Wrap array in parens
+ as needed.
+ [COMPONENT_REF]: Likewise.
+ [POINTER_TYPE]: Fix pointer-to-function handling.
+ [ARRAY_TYPE]: Don't try to print an unknown dimension.
+
+ * tree-simple.c (is_simple_arraybase): New function.
+ (is_simple_arrayref): Use it to check the array base again.
+ * tree-simple.h: Add declaration.
+ * c-simplify.c (simplify_array_ref): Do simplify the base.
+ * expr.c (expand_expr): First make sure the type has a size.
+
+2002-06-07 Jason Merrill <jason@redhat.com>
+
+ * cppexp.c (num_equality_op): Use a temporary variable to work
+ around gcc 3.0.4 bug.
+
+2002-06-05 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (BOOT_CFLAGS): Remove -ftree-ssa.
+ * c-decl.c (c_expand_body): Call optimize_function_tree if tree SSA
+ is enabled.
+ * c-lang.c (LANG_HOOKS_SIMPLIFY_FUNCTION_TREE): Define.
+ * c-simplify.c (simplify_tree): Rename to c_simplify_function_tree.
+ Update all callers.
+ Dump function body before and after simplification if
+ -fdump-tree-simple is used.
+ (simplify_expr): Document FIXME for simplification of BIT_FIELD_REF
+ nodes.
+ * c-tree.h (simplify_tree): Rename to c_simplify_function_tree.
+ * langhooks-def.h (LANG_HOOKS_SIMPLIFY_FUNCTION_TREE): Define
+ (LANGHOOKS_INITIALIZER): Add LANG_HOOKS_SIMPLIFY_FUNCTION_TREE.
+ (lhd_simplify_function_tree): Declare.
+ * langhooks.c (lhd_simplify_function_tree): New function.
+ * langhooks.h (lang_hooks): Add simplify_function_tree function
+ pointer.
+ * toplev.c (parse_options_and_default_flags): Set flag_tree_ssa to
+ 1 at optimization levels >= 1.
+ Revert to default warning when -Wuninitialized is used without -O.
+ * tree-cfg.c (tree_find_basic_blocks): Rename argument 't' to
+ 'fnbody'.
+ * tree-optimize.c: Include langhooks.h.
+ (optimize_tree): Rename to optimize_function_tree. Update all
+ users.
+ Rename argument 't' to 'fndecl'.
+ Call simplify langhook before building SSA.
+ (build_tree_ssa): Rename argument 't' to 'fndecl'.
+ Adjust call to tree_find_basic_blocks to pass body of the function.
+ * tree-optimize.h (optimize_tree): Rename to
+ optimize_function_tree.
+ * tree-simple.c (is_simple_unary_expr): Document FIXME on
+ BIT_FIELD_REF nodes.
+ * tree-ssa.c: Add whitespace.
+ * testsuite/lib/c-torture.exp: Remove -ftree-ssa flag.
+
+2002-06-03 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-cfg.c (insert_before_*): For insertion into FOR_INIT's, if
+ we have an expression statement, transform into a compound
+ expression.
+ Pick the right place to insert a statement by iterating until we
+ have a first_exec_stmt (first_non_decl_stmt) that is really the
+ first executable non decl statement.
+ (insert_after_*): Ditto.
+
+2002-06-03 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c: Update BB stuff to new basic block structure.
+ Add some comments throughout (more coming, particularly describing
+ the algorithm, rather than the implementation).
+ (free_expr_info): Free refs as well.
+ (defs_y_dom_x): Handle unary expressions as well.
+ (insert_euse_in_preorder_dt_order_1): Use block of ref, not block
+ of statement.
+ Don't insert exit blocks if we hit them before hitting an
+ occurrence (it's pointless).
+ (rename_2): Return set of phi operands we touched, don't forget to
+ free VARRAY's we allocated.
+ (rename_1): Correct downsafety computation. Now get exact same
+ results as Open64.
+ Correct setting of has_real_use.
+ (finalize_1): Fix up insertion.
+ (code_motion): Fix up insertion.
+
+ * tree-dfa.c (dump_varref): Improve dumping of expression
+ references.
+
+2002-06-03 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (delete_bb): Rename to tree_delete_bb. Update callers.
+ (tree_find_basic_blocks): Initializer last_basic_block.
+ (create_bb): Update last_basic_block after creating a new block.
+ (tree_cleanup_cfg): Delete unreachable blocks by traversing the
+ linked list, not the array. Update comments.
+ (delete_bb): Update comments.
+ (tree_dump_cfg): Also show last_basic_block.
+ * tree-ssa.c (tree_build_ssa): Use last_basic_block instead of
+ n_basic_blocks to allocate dominator arrays.
+ (insert_phi_terms): Ditto.
+ (search_fud_chains): User FOR_EACH_BB to look for dominator
+ children.
+
+2002-05-29 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (tree_find_basic_blocks): Set next_bb and prev_bb for
+ ENTRY_BLOCK_PTR and EXIT_BLOCK_PTR.
+ (create_bb): Set flag BB_NEW for every newly created block.
+ Call link_block to add the new block to the linked list.
+ (tree_split_bb): Traverse basic blocks using FOR_EACH_BB.
+ (make_goto_stmt_edges): Ditto.
+ (remove_unreachable_blocks): Add reminder comment to stop
+ compacting the basic block array every time a block is deleted.
+ (delete_cfg): Traverse basic blocks using FOR_EACH_BB.
+ (tree_dump_bb): Ditto.
+ (tree_dump_cfg): Ditto.
+ (tree_cfg2dot): Ditto.
+ * tree-dfa.c (tree_find_varrefs): Ditto.
+ (create_tree_ann): Ditto.
+ (get_fcalls): Ditto.
+ (find_declaration): Ditto.
+ * tree-ssa.c (tree_build_ssa): Ditto.
+
+2002-05-28 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in: Add -ftree-ssa to BOOT_CFLAGS.
+
+2002-05-27 Diego Novillo <dnovillo@redhat.com>
+
+ * c-decl.c (c_expand_body): Close dump file before simplifying the
+ function.
+ * c-pretty-print.c (dump_c_node): Handle COMPLEX_CST,
+ BIT_FIELD_REF, COMPLEX_EXPR, CONJ_EXPR, REALPART_EXPR,
+ IMAGPART_EXPR and VA_ARG_EXPR nodes.
+ Display all type casts, not just pointer casts.
+ (op_prio): Handle LROTATE_EXPR, RROTATE_EXPR, REALPART_EXPR and
+ IMAGPART_EXPR.
+ * c-simplify.c: Include "tree-inline.h"
+ (dump_file): New local variable.
+ (dump_flags): New local variable.
+ (stmt_expr_level): New local variable.
+ (simplify_tree): Open and close dump file if
+ -fdump-tree-simple-details is given.
+ Initialize stmt_expr_level.
+ (simplify_stmt): Dump statement before and after simplification if
+ -fdump-tree-simple-detail is given.
+ Unshare the expression of an EXPR_STMT before simplifying it.
+ Call simplify_return_stmt to handle RETURN_STMT nodes.
+ Do not simplify DECL_STMT nodes.
+ Call stmt_has_effect before re-chaining side effects.
+ (simplify_for_stmt): Do not return the simplified statement.
+ Update all callers.
+ Simplify FOR_BODY after the headers.
+ Unshare loop header expressions before simplification.
+ (simplify_while_stmt): Do not return the simplified statement.
+ Update all callers.
+ Simplify WHILE_BODY after the headers.
+ Unshare the loop header expression before simplification.
+ (simplify_do_stmt): Do not return the simplified statement. Update
+ all callers.
+ Unshare the loop header expression before simplification.
+ (simplify_if_stmt): Do not return the simplified statement. Update
+ all callers.
+ Simplify the condition expression before the clauses.
+ Unshare the condition expression before simplification.
+ (simplify_switch_stmt): Do not return the simplified statement.
+ Update all callers.
+ Simplify the switch expression before the body.
+ Unshare the switch expression before simplification.
+ (simplify_decl_stmt): Remove.
+ (simplify_expr): Remove argument 'needs_lvalue'.
+ Add argument 'stmt'.
+ Replace first argument 'expr' with a pointer to the
+ expression 'expr_p'.
+ Do not return the simplified expression.
+ Update all callers and uses.
+ Handle TRUTH_NOT_EXPR nodes. Simplify SAVE_EXPR nodes into a
+ SIMPLE id and remove the SAVE_EXPR node.
+ Do not simplify BIT_FIELD_REF nodes.
+ Remove code that tried to create new lvalues.
+ (simplify_array_ref): Replace first argument 'expr' with a pointer
+ to the expression 'expr_p'.
+ Do not return the simplified expression.
+ Add argument 'stmt'.
+ Update all callers and uses.
+ (simplify_self_mod_expr): Replace first argument 'expr' with a
+ pointer to the expression 'expr_p'.
+ Do not return the simplified expression.
+ Add argument 'stmt'.
+ Update all callers and uses.
+ Call simplify_lvalue_expr to simplify a copy of the LHS into an
+ lvalue for the new assignment.
+ Simplify the new binary expression.
+ (simplify_component_ref): Replace first argument 'expr' with a
+ pointer to the expression 'expr_p'.
+ Do not return the simplified expression.
+ Add argument 'stmt'.
+ Update all callers and uses.
+ (simplify_call_expr): Ditto.
+ (simplify_tree_list): Ditto.
+ (simplify_cond_expr): Ditto.
+ Build a replacement IF_STMT and call simplify_if_stmt() to process
+ it. Set the line number of the new statement from the statement
+ containing the original expression.
+ (simplify_modify_expr): Replace first argument 'expr' with a
+ pointer to the expression 'expr_p'.
+ Do not return the simplified expression.
+ Add argument 'stmt'.
+ Update all callers.
+ Call simplify_lvalue_expr to simplify the LHS of the assignment.
+ (simplify_boolean_expr): Replace first argument 'expr' with a
+ pointer to the expression 'expr_p'.
+ Do not return the simplified expression.
+ Add argument 'stmt'.
+ Update all callers.
+ Build a new IF_STMT and simplify it all at once by calling
+ simplify_if_stmt.
+ (simplify_compound_expr): Replace first argument 'expr' with a
+ pointer to the expression 'expr_p'.
+ Do not return the simplified expression.
+ Add argument 'stmt'.
+ Update all callers.
+ (simplify_expr_wfl): Ditto.
+ (simplify_lvalue_expr): New function.
+ (add_tree): Create a copy of each expression before adding it to
+ the list.
+ (deep_copy_node): Call copy_tree_r to copy expression nodes.
+ (stmt_has_effect): Return nonzero if the statement may be the last
+ statement of a statement expression body.
+ (mostly_copy_tree_r): New function.
+ * tree-dump.c (dump_options): Add 'details'.
+ * tree-simple.c: Update documentation about ADDRESSOF expressions.
+ (is_simple_stmt): Test for SIMPLE values when checking return
+ statements.
+ Accept all DECL_STMT nodes.
+ (is_simple_compstmt): Return nonzero if T is NULL. Do not test
+ DECL_STMT nodes
+ (is_simple_expr): Return nonzero if T is NULL.
+ (is_simple_rhs): Ditto.
+ (is_simple_modify_expr): Ditto.
+ (is_simple_modify_expr_lhs): Ditto.
+ (is_simple_binary_expr): Ditto.
+ (is_simple_cond_expr): Ditto.
+ (is_simple_unary_expr): Call STRIP_NOPS before testing T.
+ Always accept ADDR_EXPR nodes.
+ Always accept BIT_FIELD_REF nodes.
+ (is_simple_call_expr): Return nonzero if T is NULL.
+ (is_simple_const): Ditto.
+ (is_simple_val): Ditto.
+ (is_simple_compref): Ditto.
+ (is_simple_compref_lhs): Ditto.
+ (is_simple_cast): Ditto.
+ (is_simple_cast_op): Ditto.
+ (is_simple_id): Return nonzero if T is NULL. Allow identifiers
+ wrapped inside NON_LVALUE_EXPR and EXPR_WITH_FILE_LOCATION nodes.
+ Allow real and imaginary parts of a complex variable.
+ Allow compound literals.
+ (is_simple_arrayref): Allow arrays of complex types.
+ * tree.h (TDF_DETAILS): Define.
+ * cp/pt.c (tsubst_template_parms): Check that 'parms' is non-NULL
+ before calling TMPL_PARMS_DEPTH.
+ * doc/invoke.texi: Document -fdump-tree-simple-details.
+
+2002-05-10 Daniel Berlin <dberlin@dberlin.org>
+
+ * c-pretty-print.c (dump_c_node): Print "<unnamed whatever>" for
+ types, variables, etc that have no name, rather than printing
+ nothing.
+ Handle PMF's properly.
+ Print out structure initializers in a somewhat sensible way.
+ Print SAVE_EXPR () around SAVE_EXPRs.
+ (print_call_name): Handle EXPR_WITH_FILE_LOCATION.
+
+2002-05-09 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-dfa.c (dump_varref): Tree inlining generates variables with
+ no name. Don't crash on dumping varref's of them.
+
+ * tree-inline.c (expand_call_inline): Generate a proper STMT_EXPR
+ (it was missing COMPOUND_STMT).
+
+2002-05-08 Daniel Berlin <dberlin@dberlin.org>
+
+ s/varref_type/treeref_type/g
+ s/create_varref/create_ref/g
+
+ * tree-flow.h: Add EXPRPHI, EXPRUSE, EXPRKILL, EXPRINJ.
+ Add structures and macros for each.
+ Add tree_perform_ssapre prototype.
+
+ * Makefile.in (C_AND_OBJC_OBJS): Add tree-ssa-pre.o
+ (tree-ssa-pre.o): Add dependencies for tree-ssa-pre.o
+
+ * cp/Make-lang.in: Add tree-ssa-pre.o
+
+ * flags.h: Add flag_tree_ssa_pre.
+
+ * tree-ssa-pre.c: New file, SSA-PRE.
+
+ * toplev.c: Add flag_tree_ssa_pre.
+ (lang_independent_options): Add tree-ssa-pre.
+
+ * tree-dump.c (dump_files): Add ssapre dump.
+
+ * tree-optimize.c (optimize_tree): Do SSAPRE if requested.
+
+ * tree.h (dump_index): Add TDI_ssa_pre.
+
+ * tree-dfa.c (create_ref): Add support for creating the EXPR*'s refs.
+ (dump_varref): Add support for dumping EXPR* refs.
+
+ * tree-ssa.c (search_fud_chains): Add BB to VARDEF_PHI_CHAIN_BB.
+
+2002-05-07 Diego Novillo <dnovillo@redhat.com>
+
+ * c-pretty-print.c (op_prio): Handle ABS_EXPR.
+ Don't abort when the operand is not recognized.
+ (op_symbol): Don't abort when the operand is not recognized.
+ * c-simplify.c (simplify_expr): Remove 'const' qualifier from first
+ argument.
+ Do not copy incoming expression.
+ Exclude handling of MODIFY_EXPR, INIT_EXPR, SAVE_EXPR and binary
+ expression nodes.
+ (simplify_array_ref): Remove 'const' qualifier from first argument.
+ Do not copy the incoming expression.
+ (simplify_self_mod_expr): Ditto.
+ Do not simplify the first operand twice.
+ (simplify_component_ref): Remove 'const' qualifier from first
+ argument. Do not copy the incoming expression.
+ (simplify_call_expr): Ditto.
+ (simplify_tree_list): Ditto.
+ (simplify_cond_expr): Ditto.
+ (simplify_modify_expr): Ditto.
+ (simplify_boolean_expr): Ditto.
+ (simplify_compound_expr): Ditto.
+ (simplify_save_expr): Ditto.
+ (simplify_expr_wfl): Ditto.
+ (tree_build_scope): Re-write. Do nothing if block already contains
+ a scope. Use chainon to chain the body with the scope closing
+ node.
+ (deep_copy_node): Do not check for NULL nodes. Do not deep copy
+ declarations, types and constants.
+
+2002-05-06 Daniel Berlin <dberlin@dberlin.org>
+
+ * c-simplify.c (deep_copy_node): Don't copy DECL_STMT_DECL's.
+
+2002-05-06 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-simple.c (is_simple_compstmt): Don't post-initialize
+ statics or aggregate initializers.
+
+ * c-simplify.c (simplify_decl_stmt): Ditto.
+
+2002-05-06 Sebastian Pop <s.pop@laposte.net>
+
+ * Makefile.in (simple-break-elim.o, simple-goto-elim.o, tree-dchain.o):
+ Added.
+ * c-decl.c: Include tree-dchain.h
+ (c_expand_body): Add entry point to the goto, break elimination
+ after the simplification pass.
+ * simple-break-elim.c: New file.
+ * simple-goto-elim.c: New file.
+ * tree-dchain.h: New file.
+ * tree-dchain.c: New file.
+
+2002-05-02 Diego Novillo <dnovillo@redhat.com>
+
+ * c-simplify.c (simplify_expr): Constify first argument.
+ Always work on a copy of the input expression.
+ Do not simplify COMPOUND_LITERAL_EXPR nor CONSTRUCTOR nodes.
+ (simplify_array_ref): Constify first argument. Always work on a
+ copy of the input expression.
+ (simplify_self_mod_expr): Ditto.
+ (simplify_component_ref): Ditto.
+ (simplify_call_expr): Ditto.
+ (simplify_tree_list): Ditto.
+ (simplify_cond_expr): Ditto.
+ When building the THEN_CLAUSE and ELSE_CLAUSE for the new IF_STMT,
+ create a scope for them and simplify the scope, not the expression.
+ (simplify_modify_expr): Constify first argument. Always work on a
+ copy of the input expression.
+ (simplify_boolean_expr): Ditto.
+ (simplify_compound_expr): Ditto.
+ (simplify_save_expr): Ditto.
+ (simplify_expr_wfl): Ditto.
+ * tree-cfg.c (tree_find_basic_blocks): Update comments for
+ -fdump-tree-dot.
+ (tree_dump_cfg): Ditto.
+ * tree-dump.c (dump_files): Rename -fdump-tree-graphviz to
+ -fdump-tree-dot.
+ * tree-simple.c (is_simple_unary_expr): Do not handle &CONST
+ expressions.
+ Handle COMPOUND_LITERAL_EXPR and CONSTRUCTOR nodes.
+ (is_simple_const): Strip NOPS and handle &CONST expressions.
+ * tree.h (enum tree_dump_index): Remove references to GraphViz.
+ * doc/invoke.texi: Update documentation for -fdump-tree-dot.
+
+2002-05-02 Sebastian Pop <s.pop@laposte.net>
+
+ * c-pretty-print.c (dump_c_node): Don't print declarations
+ from the SCOPE_STMT_BLOCK, use the DECL_STMT instead.
+
+2002-04-30 Diego Novillo <dnovillo@redhat.com>
+
+ * c-pretty-print.c (NIY): Display an error string instead of aborting.
+ (op_prio): Add support for COMPOUND_EXPR, TRUTH_XOR_EXPR, MIN_EXPR,
+ MAX_EXPR and NON_LVALUE_EXPR.
+ For EXPR_WITH_FILE_LOCATION nodes, return the priority of
+ the internal node.
+ (op_symbol): Add support for TRUTH_XOR_EXPR.
+ * c-simplify.c (simplify_stmt): Only remove null statements that
+ have been nullified by simplification.
+ Call debug_tree() dump unhandled tree nodes.
+ (simplify_for_stmt): Always deep-copy PRE_COND_S before adding it
+ to PRE_P.
+ (simplify_expr): When simplifying a MODIFY_EXPR node into an
+ rvalue, return operand 0.
+ Handle VA_ARG_EXPR, BIT_FIELD_REF and NON_LVALUE_EXPR nodes.
+ Treat TRUTH_AND_EXPR, TRUTH_OR_EXPR and TRUTH_XOR_EXPR nodes as
+ regular binary expressions.
+ Call debug_tree() to dump an unhandled expression.
+ (simplify_array_ref): Do not simplify the base of an array.
+ (simplify_call_expr): Do not simplify calls to builtins.
+ (simplify_cond_expr): Handle conditional expressions of type void.
+ (simplify_boolean_expr): Return 'T != 0' instead of 'T'.
+ (simplify_save_expr): Do not wrap statement trees inside SAVE_EXPR
+ nodes.
+ (tree_last_decl): Ignore FILE_STMT nodes preceding a SCOPE_STMT.
+ * tree-simple.c: Update grammar to accept any valid C array as the
+ array base.
+ (is_simple_compstmt): Accept DECL_INITIAL expressions for read-only
+ variables.
+ (is_simple_expr): Do not abort if the incoming tree is NULL.
+ (is_simple_modify_expr): Allow SAVE_EXPR, EXPR_WITH_FILE_LOCATION
+ and NON_LVALUE_EXPR wrappers.
+ (is_simple_binary_expr): Ditto.
+ (is_simple_condexpr): Ditto.
+ Accept TRUTH_AND_EXPR, TRUTH_OR_EXPR and TRUTH_XOR_EXPR.
+ (is_simple_unary_expr): Do not abort it the incoming tree is NULL.
+ Allow SAVE_EXPR, EXPR_WITH_FILE_LOCATION and NON_LVALUE_EXPR
+ wrappers.
+ Handle BIT_FIELD_REF and VA_ARG_EXPR nodes.
+ (is_simple_call_expr): Always return 1 for builtin calls.
+ (is_simple_arrayref): Do not check the array base.
+
+2002-04-30 Daniel Berlin <dberlin@dberlin.org>
+
+ * c-simplify.c (simplify_call_expr): Don't try to simplify
+ call_expr arglist if it's not there.
+
+2002-04-27 Diego Novillo <dnovillo@redhat.com>
+
+ * c-decl.c (c_expand_body): Call simplify_tree to simplify a
+ FUNCTION_DECL node.
+ * c-simplify.c (simplify_tree): New function.
+ (simplify_stmt): Remove variable 'new_vars'. Update all called
+ functions.
+ Remove argument 'scope'. Update all callers.
+ Do not keep track of new scope statements as they are entered.
+ Do not call declare_tmp_vars().
+ (simplify_for_stmt): Remove argument new_vars_p. Update all callers.
+ (simplify_while_stmt): Ditto.
+ (simplify_do_stmt): Ditto.
+ (simplify_if_stmt): Ditto.
+ (simplify_switch_stmt): Ditto.
+ (simplify_decl_stmt): Reformat comments.
+ (simplify_expr): Remove argument new_vars_p. Update all callers.
+ Call simplify_save_expr() to simplify SAVE_EXPR nodes.
+ Call simplify_expr_wfl() to simplify EXPR_WITH_FILE_LOCATION nodes.
+ Do not call is_unop() and is_binop() when checking for unary and
+ binary operators.
+ Do not return early after simplify statement-expressions.
+ Do not call add_modify_stmt() to create assignment expressions.
+ (simplify_array_ref): Remove argument new_vars_p. Update all callers.
+ (simplify_self_mod_expr): Ditto.
+ (simplify_component_ref): Ditto.
+ (simplify_call_expr): Ditto.
+ (simplify_tree_list): Ditto.
+ (simplify_cond_expr): Ditto.
+ (simplify_modify_expr): Ditto.
+ (simplify_boolean_expr): Ditto.
+ (simplify_compound_expr): Ditto.
+ (simplify_save_expr): New function.
+ (simplify_expr_wfl): New function.
+ (tree_build_scope): Reformat.
+ (add_tree): Call stmt_has_effect() and expr_has_effect() to decide
+ whether or not to add a new tree to the list.
+ (add_modify_stmt): Remove.
+ (create_tmp_var): Remove 'new_vars_p' argument.
+ Call pushdecl() to insert the newly created variable in the current
+ binding scope.
+ (declare_tmp_vars): Do not create a BLOCK_VARS for the scope.
+ (is_binop): Remove.
+ (is_unop): Remove.
+ (expr_has_effect): New function.
+ * c-tree.h (simplify_tree): Remove second argument.
+ * stmt.c (warn_if_unused_value): Check operand 0 of SAVE_EXPR
+ nodes.
+ * tree-dfa.c (find_refs_in_expr): Call find_refs_in_expr() to look
+ inside an EXPR_WITH_FILE_LOCATION node.
+ * tree-simple.c (is_simple_stmt): Add a case for SCOPE_STMT nodes.
+ (is_simple_compstmt): Assume that T is the first tree in the
+ compound statement's body.
+ Stop when a scope ending SCOPE_STMT node is found.
+ (is_simple_binary_expr): Don't call is_simple_binop().
+ (is_simple_condexpr): Don't call is_simple_relop().
+ (is_simple_binop): Remove.
+ (is_simple_relop): Remove.
+ (is_simple_unary_expr): Accept any operator with tree code class
+ '1' followed by a simple value.
+ Accept simple unary expressions wrapped inside SAVE_EXPR,
+ EXPR_WITH_FILE_LOCATION and NON_LVALUE_EXPR nodes.
+ (is_simple_id): Accept simple identifiers wrapped inside SAVE_EXPR,
+ EXPR_WITH_FILE_LOCATION and NON_LVALUE_EXPR nodes.
+ * tree-simple.h (create_tmp_var): Remove second argument.
+ (is_simple_binop): Remove.
+ (is_simple_relop): Remove.
+
+2002-04-22 Diego Novillo <dnovillo@redhat.com>
+
+ * c-simplify.c (stmt_has_effect): New function.
+ (simplify_stmt): Fix example code in comment.
+ Use EXPR_STMT_EXPR to access the expression in an expression
+ statement.
+ Call debug_c_node to display unhandled statements.
+ Call stmt_has_effect to determine whether the statement has been
+ nullified by the simplification process.
+ (simplify_for_stmt): Do not simplify the initialization expression
+ if it's NULL.
+ Do not convert post_cond_s into a statement chain.
+ Do not simplify the expression if it's NULL.
+ (simplify_switch_stmt): initialize post_cond_s to NULL before
+ simplifying the expression.
+ (simplify_expr): Rename argument IS_LHS to NEEDS_LVALUE. Update
+ all uses.
+ When simplifying assignments, return the LHS of the assignment if
+ the caller wants to use the assignment as an rvalue.
+ Do not simplify ADDR_EXPR nodes.
+ Handle NOP_EXPR, CONVERT_EXPR, FIX_TRUNC_EXPR, FIX_CEIL_EXPR,
+ FIX_ROUND_EXPR, INDIRECT_REF, NEGATE_EXPR, INTEGER_CST, STRING_CST,
+ COMPLEX_CST.
+ Abort if the expression has not been simplified and cannot be used
+ as an rvalue to assign it to a temporary.
+ When creating a new temporary to hold an lvalue, if the expression
+ is an indirect reference, use the address of the referenced object.
+ When creating an indirect reference, use the pointed-to type as the
+ type of the reference.
+ (simplify_self_mod_expr): If the LHS operand needs to be
+ simplified, simplify twice. Once to produce an lvalue and another
+ to produce a simple value.
+ (simplify_modify_expr): Break assignment chains (a = b = c = ...)
+ into individual assignments.
+ (simplify_compound_expr):
+ (create_tmp_var): If the type is an array, use TYPE_POINTER_TO as
+ the pointer type.
+ (update_line_number): Fix typo in comment.
+ (is_unop): Ditto.
+ (convert_to_stmt_chain): Only add statements that comply with
+ stmt_has_effect().
+ * tree-dfa.c (find_declaration): Fix typo in comment.
+ (debug_varref): Ditto.
+ * tree-flow.h: Ditto.
+ * tree-simple.c (is_simple_stmt): New function.
+ (is_simple_compstmt): New function.
+ (is_simple_expr): Fix typo in comment.
+ (is_simple_rhs): Allow conditional expressions.
+ (is_simple_modify_expr): Fix typo in comment.
+ (is_simple_modify_expr_lhs): Ditto.
+ (is_simple_binary_expr): Ditto.
+ (is_simple_condexpr): Ditto.
+ (is_simple_relop): Ditto.
+ (is_simple_unary_expr): Ditto.
+ Allow taking the address of a constant (for strings).
+ (is_simple_call_expr): Fix typo in comment.
+ Call is_simple_id to determine if the first operand is a SIMPLE
+ function identifier.
+ (is_simple_arglist): Fix typo in comment.
+ (is_simple_varname): Ditto.
+ (is_simple_const): Don't accept casts of SIMPLE constants.
+ (is_simple_id): Don't accept casts of SIMPLE identifiers.
+ (is_simple_val): Fix typo in comment.
+ (is_simple_arrayref): Ditto.
+ (is_simple_compref): Ditto.
+ (is_simple_compref_lhs): Ditto.
+ (is_simple_cast_op): Ditto.
+ (is_simple_exprseq): Allow NULL expression sequences.
+ * tree-simple.h (is_simple_stmt): Declare
+ (is_simple_compstmt): Declare.
+ * tree-ssa.c (follow_chain): Fix typo in comment.
+
+2002-04-22 Diego Novillo <dnovillo@redhat.com>
+
+ * c-pretty-print.c (dump_c_node): Don't print function
+ bodies of FUNCTION_DECL nodes.
+
+2002-04-19 Andreas Jaeger <aj@suse.de>
+
+ * Makefile.in (c-call-graph.o): New.
+
+2002-04-18 Sebastian Pop <s.pop@laposte.net>
+
+ * c-pretty-print.c (PRINT_FUNCTION_NAME): Define.
+ (dump_c_node): Call pretty_print_string to print string.
+ Call print_call_name to print function names.
+ (pretty_print_string): New function.
+ (print_call_name): New function.
+
+2002-04-17 Diego Novillo <dnovillo@redhat.com>
+
+ * c-simplify.c (simplify_do_stmt): Call is_simple_condexpr to test
+ if the conditional is in SIMPLE form.
+ (simplify_if_stmt): Ditto.
+
+2002-04-17 Diego Novillo <dnovillo@redhat.com>
+
+ * c-pretty-print.c (dump_c_node): Handle escape sequences in strings.
+ (op_symbol): Handle TRUTH_NOT_EXPR.
+ * c-simplify.c: Rename 'after' with 'post' and 'before' with 'pre'
+ everywhere.
+ Re-group some functions and add comments.
+ (simplify_stmt): Update calls to simplify_for_stmt,
+ simplify_while_stmt, simplify_do_stmt and simplify_switch_stmt.
+ Call simplify_if_stmt.
+ Do not test if expression is in SIMPLE form before calling
+ simplify_expr.
+ Call convert_to_stmt_chain to emit statement trees for side effects
+ found while simplifying.
+ (simplify_for_stmt): Re-implement. Do not change structure of the
+ statement. Simplify each header expression and emit side effects
+ at sequence points.
+ (simplify_while_stmt): Ditto.
+ (simplify_do_stmt): Ditto.
+ (simplify_switch_stmt): Ditto.
+ (new_simplified_if): Rename to simplify_if_stmt.
+ Call simplify_expr to simplify the conditional.
+ (simplify_if_stmt): New name for new_simplified_if.
+ (simplify_expr): Do not default simple_test_f to is_simple_expr.
+ If simple_test_f is not set, abort.
+ Handle COMPOUND_EXPR, MODIFY_EXPR, TRUTH_ANDIF_EXPR,
+ TRUTH_ORIF_EXPR, SAVE_EXPR and EXPR_WITH_FILE_LOCATION.
+ (simplify_arglist): Rename to simplify_tree_list.
+ (simplify_tree_list): New name for simplify_arglist.
+ (simplify_boolean_expr): New function.
+ (simplify_compound_expr): New function.
+ (tree_build_scope): Use SCOPE_BEGIN_P instead of TREE_LANG_FLAG_0
+ to access scope operands. Use COMPOUND_BODY instead of
+ TREE_OPERAND to access the body of the compound statement.
+ (add_tree): Use a TREE_LIST container instead of directly chaining the
+ trees.
+ (add_assignment_tree): Rename to add_modify_stmt. Update all
+ callers.
+ (add_modify_stmt): New name for add_assignment_tree.
+ (insert_before_continue_end): Do nothing it the tree to insert is
+ NULL.
+ (copy_stmt_chain): Rename to deep_copy_list. Update all callers.
+ (deep_copy_list): New name for copy_stmt_chain.
+ (copy_stmt): Rename to deep_copy_node. Update all callers.
+ (deep_copy_node): New name for copy_stmt. Handle TREE_LIST
+ trees.
+ (insert_before_first): New function.
+ (is_binop): Add COMPOUND_EXPR.
+ (convert_to_stmt_chain): New function.
+ * tree-cfg.c (make_for_stmt_blocks): Fix comment.
+ * tree-simple.c (is_simple_condexpr): New function.
+ (is_simple_const): Allow casts of SIMPLE constants.
+ (is_simple_id): Allow casts of SIMPLE identifiers.
+ (is_simple_cast): Call is_simple_cast_op.
+ (is_simple_cast_op): New function.
+ (is_simple_exprseq): New function.
+ * tree-simple.h (deep_copy_list): Declare.
+ (deep_copy_node): Declare.
+ (is_simple_cast_op): Declare.
+ (is_simple_exprseq): Declare.
+
+2002-04-03 Diego Novillo <dnovillo@redhat.com>
+
+ * c-simplify.c (simplify_expr): Add arguments simple_tree_f and
+ is_lhs. Update all callers.
+ Call simplify_call_expr, simplify_cond_expr, simplify_arglist and
+ simplify_modify_expr.
+ Call is_unop and is_binop to check for unary and binary operators.
+ (simplify_binary_expr): Remove.
+ (simplify_call_expr): New function.
+ (simplify_arglist): New function.
+ (simplify_cond_expr): New function.
+ (simplify_modify_expr): New function.
+ (keep_stmt_p): Remove.
+ (is_binop): New function.
+ (is_unop): New function.
+ (simplify_stmt): Don't call keep_stmt_p.
+ (simplify_decl_stmt): Call add_assignment_tree.
+ * tree-simple.c: Include c-tree.h
+ Add expression-statements to the SIMPLE grammar.
+ (is_simple_modify_expr_lhs): New function.
+ (is_simple_modify_expr): Call it.
+ (is_simple_relop): Update comment.
+ (is_simple_unary_expr): Allow expression-statements.
+ (is_simple_arglist): New function.
+ (is_simple_call_expr): Call it.
+ (is_simple_id): Accept expressions taking the address of a
+ function.
+ * tree-simple.h (is_simple_modify_expr_lhs): Declare.
+ (is_simple_arglist): Declare.
+
+2002-03-21 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (c-simplify.o): Add dependency on varray.h.
+ * c-simplify.c: Include varray.h.
+ Remove comments with SIMPLE grammar.
+ (simplify_array_ref): New.
+ (simplify_self_mod_expr): New.
+ (simplify_component_ref): New.
+ (add_assignment_tree): New.
+ (simplify_expr): Call simplify_array_ref to simplify array
+ references.
+ Call simplify_self_mod_expr to simplify ++, --, += and -=
+ expressions.
+ Call simplify_component_ref to simplify references to structures.
+ (simplify_binary_expr): Do not check whether the expression is
+ already in SIMPLE form.
+ * tree-simple.c: Document changes from original SIMPLE grammar.
+ (is_simple_unary_expr): Add check for *ID.
+ (is_simple_call_expr): Update comments.
+ (is_simple_const): Ditto.
+ (is_simple_id): Do not accept *ID expressions.
+ (is_simple_val): Update comments.
+ (is_simple_arrayref): Accept any variable name as the base address.
+ (is_simple_compref_lhs): New.
+ (is_simple_compref): Call it.
+ * tree-simple.h (is_simple_compref_lhs): Declare.
+
+2002-03-18 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (C_AND_OBJC_OBJS): Add tree-simple.o
+ (tree-simple.o): New rule.
+ * c-simplify.c (simplified_p): Remove.
+ (simplified_rec_p): Remove.
+ (simplified_condition_p): Remove.
+ (simplify_for_stmt): Call is_simple_expr instead of
+ simplified_condition_p.
+ (simplify_while_stmt): Ditto.
+ (simplify_do_stmt): Call is_simple_expr instead of simplified_p.
+ (new_simplified_if): Call is_simple_expr instead of
+ simplified_rec_p.
+ (simplify_decl_stmt): Update comment.
+ (simplify_expr): Return the original expression if it's already
+ in SIMPLE form.
+ Do not special case most binary and unary expressions.
+ When simplifying array references, create temporary variables to
+ hold the base address for the array.
+ Simplify COMPONENT_REF expressions separately.
+ Call simplify_binary_expr to handle most binary expressions.
+ (simplify_binary_expr): New function.
+ (keep_stmt_p): Call is_simple_unary_expr to determine whether the
+ statement should be kept or not.
+ * tree-simple.c: New file.
+ * tree-simple.h (is_simple_expr): Declare.
+ (is_simple_rhs): Declare.
+ (is_simple_modify_expr): Declare.
+ (is_simple_binary_expr): Declare.
+ (is_simple_binop): Declare.
+ (is_simple_relop): Declare.
+ (is_simple_unary_expr): Declare.
+ (is_simple_call_expr): Declare.
+ (is_simple_const): Declare.
+ (is_simple_id): Declare.
+ (is_simple_varname): Declare.
+ (is_simple_val): Declare.
+ (is_simple_arrayref): Declare.
+ (is_simple_compref): Declare.
+ (is_simple_cast): Declare.
+ * cp/Make-lang.in (CXX_C_OBJS): Add tree-simple.o
+
+2002-03-18 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-simple.h: New file.
+ * Makefile.in (c-simplify.o): Add dependency on tree-simple.h
+ * c-simplify.c: Reformat some comments.
+ (tree_last_decl): Declare.
+
+2002-03-18 Sebastian Pop <s.pop@laposte.net>
+
+ * c-simplify.c (insert_stmt_chain): Delete.
+ (simplified_condition_p, insert_after_case_labels): New.
+ (simplify_stmt, simplify_for_stmt, simplify_while_stmt,
+ simplify_do_stmt, new_simplified_if, simplify_switch_stmt):
+ Returns a single node, generate a chain of statements to be executed
+ before the if, and a list of new variables.
+ (new_simplified_if): Simplify clauses.
+ (simplify_expr): Remove unused parameter scope.
+
+2002-03-14 Sebastian Pop <s.pop@laposte.net>
+
+ * c-simplify.c (simplify_switch_stmt, simplify_expr): Add scope
+ parameter.
+ (simplify_while_stmt, simplify_do_stmt, simplify_for_stmt): Avoid
+ negating loop condition during simplification.
+ (new_simplified_if): Don't simplify the IF_BODY.
+ (copy_stmt_chain): Use copy_stmt.
+ (copy_stmt): New function.
+
+2002-02-28 Sebastian Pop <s.pop@laposte.net>
+
+ * tree-dfa.c (find_refs_in_stmt): Changed if/else statements in
+ a switch.
+
+2002-02-28 Sebastian Pop <s.pop@laposte.net>
+
+ * c-simplify.c (simplify_if_stmt): Deleted.
+ (new_simplified_if): New function.
+ (make_type_writable): New function.
+ (insert_before_continue_end): New function.
+ (insert_before_continue): New function.
+ (copy_stmt_chain): New function.
+ (insert_stmt_chain): New function.
+ (update_line_number): New function.
+ (simplified_p): New function.
+ (simplified_rec_p) New function.
+ (simplify_stmt): Modify the way to call simplification
+ of COMPOUND_STMT, FOR_STMT, WHILE_STMT, DO_STMT, IF_STMT,
+ and SCOPE_STMT in order to avoid to execute the code after
+ the switch. Add FILE_STMT, LABEL_STMT, GOTO_STMT, ASM_STMT cases.
+ Simplified a little the code after the switch.
+ (simplify_for_stmt): Change functions parameters.
+ Add code to simplify the FOR_INIT_STMT, FOR_COND, FOR_EXPR.
+ (simplify_while_stmt): Change functions parameters.
+ Add code to simplify the WHILE_COND.
+ (simplify_do_stmt): Change functions parameters.
+ Add code to simplify the DO_COND.
+ (simplify_switch_stmt): Change functions parameters.
+ (simplify_expr): Remove scope parameter.
+ Avoid to introduce a new temporary variable for an expression
+ that is already simplified.
+ ([ARRAY|COMPONENT]_REF, COND_EXPR): Handle them apart.
+ (TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR): Avoid to evaluate the second
+ operand if the value can be deduced from the first one.
+ (keep_stmt_p): Add some other cases in which we don't need to keep
+ a statement after its simplification.
+
+2002-02-28 Sebastian Pop <s.pop@laposte.net>
+
+ * Makefile.in: Add c-call-graph.o dependence.
+ * c-call-graph.c: New file.
+ * c-decl.c (c_expand_body): Add an entry point for call-graph.
+ * tree-dump.c (dump_files): Add the flag dump-call-graph.
+ * tree.h (tree_dump_index): Add TDI_xml.
+
+2002-02-28 Sebastian Pop <s.pop@laposte.net>
+
+ * c-pretty-print.c (dump_c_tree): Declare it extern.
+ (dump_c_node): Declare it extern.
+ (dump_c_scope_vars): Deleted, some code moved in print_declaration ().
+ (print_declaration): New function.
+ (print_function_decl): New function.
+ (print_struct_decl): New function.
+ (INDENT_PRINT_C_NODE): Deleted.
+ (INDENT): New macro.
+ (NIY): Define the macro body in a block.
+ (dump_c_node): Add dumping for TREE_PURPOSE operand in TREE_LIST.
+ [VOID|INTEGER|REAL|COMPLEX|VECTOR|ENUMERAL|BOOLEAN|CHAR]_TYPE nodes:
+ insert some code from print-tree.c:print_node_brief () in order to
+ stabilise the type printing.
+ [RECORD|UNION]_TYPE nodes: Don't print their contents by default,
+ move the existing code in print_struct_decl ().
+ [POSTDECREMENT|POSTINCREMENT]_EXPR: Print the operand in post postion.
+ [MIN|MAX|ABS]_EXPR: New code for printing these nodes.
+ FOR_STMT: Don't print the FOR_BODY if it is not present.
+ RETURN_STMT: Don't print the return expression for a void function.
+ ASM_STMT: New code for printing this node.
+ SCOPE_STMT: Use print_declaration instead of dump_c_scope_vars.
+ COMPOUND_LITERAL_EXPR: Add the node as not implemented yet.
+ (op_prio): Fix switch indent.
+ Add node EXPR_WITH_FILE_LOCATION with priority 16.
+ (op_symbol): Fix switch indent.
+
+2002-01-25 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (c-pretty-print.o): Add dependency on errors.h.
+ * c-decl.c (c_expand_body): React to -ftree-dump-simple.
+ * c-pretty-print.c: Fix typo in header comment.
+ (NYI): Flush output buffer, dump the tree and abort.
+ (dump_c_node): Add unparsing code for ERROR_MARK, IDENTIFIER_NODE,
+ ARRAY_TYPE, UNION_TYPE, STRING_CST, CEIL_DIV_EXPR, FLOOR_DIV_EXPR,
+ ROUND_DIV_EXPR, TRUNC_MOD_EXPR, FLOOR_MOD_EXPR, ROUND_MOD_EXPR,
+ RDIV_EXPR, EXACT_DIV_EXPR, LROTATE_EXPR, RROTATE_EXPR,
+ BIT_ANDTC_EXPR, BIT_NOT_EXPR, UNORDERED_EXPR, SAVE_EXPR and
+ EXPR_WITH_FILE_LOCATION.
+ Unify unparsing code for common binary and unary expressions.
+ Handle indirect references like any other unary expression.
+ (dump_c_scope_vars): Remove unused variable 'context'.
+ Call dump_c_node to print the type.
+ (dump_c_indirect_ref): Remove.
+ (op_prio): New function.
+ (op_symbol): New function.
+ * c-simplify.c (simplify_stmt): Do not simplify a return
+ expression, only its second operand.
+ Fix capitalization in error message.
+ (simplify_expr): Add documentation.
+ Fix capitalization in error message.
+ * tree-dump.c (dump_files): Add entry for -fdump-tree-simple.
+ (dump_options): Add entry for -unparse.
+ * tree.h (TDI_simple): Define.
+ (TDF_UNPARSE): Define.
+ * doc/invoke.texi: Document -fdump-tree-simple.
+
+2002-01-23 Sebastian Pop <s.pop@laposte.net>
+
+ * c-pretty-print.c: Clean C++ comments.
+ (debug_output_buffer): Remove declaration and definition.
+ * diagnostic.h (debug_output_buffer): Add declaration.
+ * diagnostic.c (debug_output_buffer): Add definition.
+
+2002-01-21 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (find_refs_in_stmt): Fix capitalization in error
+ message.
+ (find_refs_in_expr): Ditto.
+
+2002-01-20 Diego Novillo <dnovillo@redhat.com>
+ Sebastian Pop <s.pop@laposte.net>
+
+ * Makefile.in: Add c-simplify.o.
+ * cp/Make-lang.in: Ditto.
+ * c-decl.c (c_expand_body): Call simplify_stmt() before
+ calling optimize_tree().
+ * c-simplify.c: New file.
+ * c-tree.h (simplify_stmt): Declare.
+ (print_c_tree)
+ * tree-dfa.c (find_refs_in_stmt): Fix error message for unhandled
+ statement codes.
+
+2002-01-20 Sebastian Pop <s.pop@laposte.net>
+
+ * Makefile.in: Add c-pretty-print.o.
+ * cp/Make-lang.in: Ditto.
+ * c-pretty-print.c: New file.
+ * c-tree.h (print_c_tree): Declare.
+ (print_c_node): Declare.
+ (debug_c_tree): Declare.
+ (debug_c_node): Declare.
+
+2001-12-29 Diego Novillo <dnovillo@redhat.com>
+
+ * c-lang.c (c_post_options): Move code to enable tree-ssa
+ if -Wuninitialized is used ...
+ * c-common.c (c_common_post_options): ... here.
+
+2001-12-29 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree-optimize.o): Don't depend on c-common.h
+ * tree-cfg.c: Don't include c-tree.h. Explain why we need to
+ include c-common.h.
+ * tree-dfa.c: Explain why we need to include c-common.h.
+ * tree-ssa.c: Ditto.
+ * tree-optimize.c: Don't include c-common.h
+
+2001-12-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ Revert my patch of 2001-07-23 for the moment.
+
+2001-10-15 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (create_varref): If the new reference is inside a
+ statement, add it to the list of references for that statement.
+
+2001-10-14 Diego Novillo <dnovillo@redhat.com>
+
+ * Merge from mainline:
+
+ Tue Sep 11 11:37:52 CEST 2001 Jan Hubicka <jh@suse.cz>
+
+ * basic-block.h (cached_make_edge): New.
+ (make_edge): Remove first parameter.
+ * flow.c (cached_make_edge): Rename from make_edge; return
+ newly created edge; use obstack allocation.
+ (make_edge): New.
+ (flow_call_edges_add): Updaet make_edge call.
+ (add_noreturn_fake_exit_edges): Likewise.
+ (connect_infinite_loops_to_exit): Liekwise.
+ (make_label_edge, make_edges, find_sub_basic_blocks): Use
+ cached_make_edge.
+ * profile.c (branch_prob): Update make_edge call.
+ * ssa-dce.c (ssa_eliminate_dead_code): Likewise.
+
+2001-10-14 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree-ssa.o): Remove dependency on flags.h.
+ (tree-optimize.o): Add dependency on flags.h.
+ * bb-reorder.c (fixup_reorder_chain): Update call to make_edge.
+ * c-lang.c (c_post_options): Set flag_tree_ssa if -Wuninitialized
+ is given.
+ * ifcvt.c (find_if_case_1): Update call to make_edge.
+ * toplev.c (toplev_main): Do not warn about -Wuninitialized without
+ -O if -ftree-ssa is used.
+ * tree-cfg.c (dot_dump_file): Remove.
+ (dot_dump_flags): Remove.
+ (cfg_dump_file): Rename to dump_file.
+ (cfg_dump_flags): Rename to dump_flags.
+ (remove_bb_ann): New function.
+ (tree_find_basic_blocks): Do not open dump files at the beginning
+ of the function.
+ Do not call delete_cfg.
+ Create annotations for ENTRY_BLOCK_PTR and EXIT_BLOCK_PTR.
+ (make_for_stmt_blocks): Update FOR_INIT_STMT_BB and FOR_COND_BB
+ when creating the header blocks.
+ Create the blocks for the loop body before the expression block.
+ (make_while_stmt_blocks): Update END_WHILE_BB when creating the
+ header blocks.
+ Create the blocks for the loop body before the end-while block.
+ (make_do_stmt_blocks): Update DO_COND_BB when creating header
+ blocks.
+ Create the blocks for the loop body before the block for DO_COND.
+ (create_bb): When creating loop header blocks, allocate space for
+ the header_blocks union.
+ Call create_bb_ann to create a new annotation.
+ (remove_bb_ann): New function.
+ (tree_split_bb): New function.
+ (make_edges): Remove first argument from call to make_edge,
+ make_ctrl_stmt_edges, make_exit_edges, make_for_stmt_edges,
+ make_while_stmt_edges, make_do_stmt_edges, make_if_stmt_edges,
+ make_goto_stmt_edges, make_break_stmt_edges and
+ make_continue_stmt_edges.
+ When creating edges for the default label, remove the fallthru edge
+ that was created for the associated SWITCH_STMT entry block.
+ Do not call delete_unreachable_blocks.
+ Call tree_cleanup_cfg.
+ (make_ctrl_stmt_edges): Remove first argument.
+ (make_exit_edges): Remove first argument.
+ If the last element of the block is an EXPR_STMT, assume that it is
+ the call to a non-returning function and make an edge to the exit
+ block.
+ Do not call make_return_stmt_edges. Call make_edge directly.
+ (make_for_stmt_edges): Remove first argument.
+ Simplify the graph for infinite and zero-iteration loops.
+ (make_while_stmt_edges): Remove first argument.
+ Simplify the graph for infinite and zero-iteration loops.
+ (make_do_stmt_edges): Remove first argument.
+ Simplify the graph for infinite and one-iteration loops.
+ (make_if_stmt_edges): Remove first argument.
+ Simplify the graph for always-true and always-false conditionals.
+ (make_goto_stmt_edges): Remove first argument.
+ (make_break_stmt_edges): Remove first argument.
+ (make_continue_stmt_edges): Remove first argument.
+ (make_return_stmt_edges): Remove.
+ (tree_cleanup_cfg): New function.
+ (delete_unreachable_blocks): Do not react to -Wunreachable-code.
+ Write to dump file blocks that have been removed.
+ Call remove_edge.
+ (is_ctrl_altering_stmt): If the statement contains a call to a
+ non-returning function, return 1.
+ (delete_cfg): Call remove_bb_ann. Also remove annotations for
+ ENTRY_BLOCK_PTR and EXIT_BLOCK_PTR.
+ (latch_block): Use WHILE_COND_BB instead of END_WHILE_BB.
+ (insert_stmt_tree_before): Use cfg_dump_file instead of dump_file.
+ (insert_before_ctrl_stmt): Ditto.
+ (insert_before_normal_stmt): Ditto.
+ (insert_stmt_tree_after): Ditto.
+ (insert_after_ctrl_stmt): Ditto.
+ (insert_after_normal_stmt): Ditto.
+ (replace_expr_in_tree): Ditto.
+ (insert_bb_before): Ditto.
+ * tree-dfa.c (tree_find_varrefs): Call find_refs_in_expr when the
+ tree is not a statement.
+ (find_refs_in_stmt): Update comments.
+ Do not deal with FOR_STMT and DO_STMT trees separately.
+ When processing VAR_DECLs, call find_refs_in_expr with the
+ declaration, not its initial value.
+ (find_refs_in_expr): When processing COMPONENT_REFs and ARRAY_REFs,
+ recurse using the same reference type that was given by the
+ original caller.
+ (create_varref): Insert new PHI terms at the beginning of the
+ BB_REFS array, not the end.
+ * tree-flow.h (struct for_header_blocks): Declare.
+ (union header_blocks): Declare.
+ (struct bb_ann_def): Add new field 'loop_hdr'.
+ (BB_ANN): Re-define so that it can be used as an lvalue.
+ (BB_PARENT): Ditto.
+ (BB_REFS): Ditto.
+ (BB_PREV_CHAIN): Ditto.
+ (BB_BINDING_SCOPE): Ditto.
+ (BB_LOOP_HDR): Define.
+ (FOR_INIT_STMT_BB): Redefine using BB_LOOP_HDR.
+ (FOR_COND_BB): Ditto.
+ (FOR_EXPR_BB): Ditto.
+ (DO_COND_BB): Ditto.
+ (END_WHILE_BB): New name for WHILE_COND_BB.
+ (tree_warn_uninitialized): Declare.
+ (tree_cleanup_cfg): Declare.
+ (tree_split_bb): Declare.
+ * tree-optimize.c: Include flags.h.
+ (init_tree_flow): New function.
+ (optimize_tree): Call build_tree_ssa instead of building SSA
+ in-place.
+ (build_tree_ssa): New function.
+ * tree-optimize.h (build_tree_ssa): Declare.
+ * tree-ssa.c: Don't include toplev.h
+ (tree_warn_uninitialized): Define.
+ (tree_compute_rdefs): Do not call is_upward_exposed. Instead
+ traverse all the uses of each variable and warn if the use is
+ reached by the ghost definition.
+
+2001-10-10 Graham Stott <grahams@redhat.com>
+
+ * tree-cfg.c (create_bb): Add new binding_scope parameter which allows
+ the binding scope either to be explicitly specified if non-zero.
+ (make_blocks): Update call to create_bb.
+ (make_for_stmt_blocks): Ditto.
+ (make_while_stmt_blocks): Ditto.
+ (make_do_stmt_blocks): Ditto.
+ (make_if_stmt_blocks): Ditto.
+ (make_switch_stmt_blocks): Ditto.
+ (create_maximal_bb): Ditto.
+ (make_edges): If a statement expression is in the last basic
+ block create an edge to EXIT_BLOCK_PTR and not the next block.
+ (insert_before_normal_stmt): Pass the appropriate binding scope to
+ create_bb.
+
+2001-10-01 Graham Stott <grahams@redhat.com>
+ Diego Novillo <dnovillo@redhat.com>
+
+ * tree-optimize.c (optimize_tree): Early return if the program has
+ errors.
+
+2001-09-30 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-optimize.c (optimize_tree): Compute reaching definitions
+ after building SSA.
+
+2001-09-30 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (insert_after_ctrl_stmt): Remove unused argument.
+ (make_blocks): Pop top element from scope binding stack when an end
+ of scope statement is found.
+ (create_bb): Remove code for popping top element from scope binding
+ stack.
+ Do not push basic block 0 to initialize scope binding stack.
+ (insert_stmt_tree_after): Remove unused argument from call to
+ insert_after_ctrl_stmt.
+ (tree_dump_bb): Dump BB_BINDING_SCOPE if defined.
+ * doc/invoke.texi: Document debugging option -ftree-dump-ssa-rdefs.
+
+2001-09-29 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree-ssa.o): Update dependencies.
+ (tree-cfg.o): Ditto.
+ (tree-optimize.o): Ditto.
+ * basic-block.h (BB_CONTROL_EXPR): Define.
+ (BB_CONTROL_ENTRY): Define.
+ * c-common.h (TDF_RDEFS): Define.
+ * c-dump.c (dump_option_value_in): Add entry for TDF_RDEFS.
+ * tree-cfg.c: Include flags.h and c-tree.h
+ (binding_stack): New local variable.
+ (delete_block): Rename to delete_bb.
+ (tree_find_basic_blocks): Initialize varray 'binding_stack'.
+ Call make_blocks with an additional argument.
+ Adjust size of varray 'basic_block_info' after building CFG.
+ (make_blocks): Add new argument prev_chain_p.
+ Update all callers and callees.
+ Create sub-graphs for statement-expressions.
+ Update prev_chain_p when accessing the next tree in the chain.
+ (make_for_stmt_blocks): Add new argument prev_chain_p.
+ Update all callers and callees.
+ Update flags for control header blocks with BB_CONTROL_ENTRY and/or
+ BB_CONTROL_EXPR.
+ (make_while_stmt_blocks): Ditto.
+ (make_do_stmt_blocks): Ditto.
+ (make_if_stmt_blocks): Ditto.
+ (make_switch_stmt_blocks): Ditto.
+ (create_maximal_bb): Add new argument prev_chain_p.
+ Update all callers and callees.
+ (create_bb): Add new argument prev_chain_p.
+ Push basic block 0 the first time into the binding scope stack.
+ Associate the new basic block to the binding scope at the top of
+ the binding stack.
+ Push new binding scopes when a SCOPE_BEGIN statement is found.
+ Pop the top binding scope when a SCOPE_END statement is found.
+ (make_edges): Handle statement expressions.
+ Handle case labels preceded by scope statements in switch
+ statements.
+ (make_for_stmt_edges): Use FOR_INIT_STMT_BB, FOR_COND_BB and
+ FOR_EXPR_BB to access the header basic blocks.
+ (delete_unreachable_blocks): Call delete_bb instead of
+ delete_block.
+ (delete_block): Rename to delete_bb.
+ (block_invalidates_loop): Use data references to find calls to
+ non-pure functions.
+ (is_ctrl_stmt): Reformat.
+ (loop_body): New function.
+ (set_loop_body): New function.
+ (stmt_starts_bb_p): Statement expression trees also start a new
+ basic block.
+ (delete_cfg): Call VARRAY_FREE to delete all the references in each
+ basic block.
+ (latch_block): Use FOR_EXPR_BB, WHILE_COND_BB and DO_COND_BB to
+ find out the latch block for the loop.
+ (last_exec_stmt): New function.
+ (is_exec_stmt): Scope statements that begin a scope are also
+ considered executables.
+ (is_statement_expression): New function.
+ (first_non_decl_stmt): New function.
+ (first_decl_stmt): New function.
+ (first_non_label_in_bb): New function.
+ (insert_stmt_tree_before): New function.
+ (insert_before_ctrl_stmt): New function.
+ (insert_before_normal_stmt): New function.
+ (insert_stmt_tree_after): New function.
+ (insert_after_ctrl_stmt): New function.
+ (insert_after_normal_stmt): New function.
+ (insert_after_loop_body): New function.
+ (replace_expr_in_tree): New function.
+ (find_expr_in_tree): New function.
+ (insert_bb_before): New function.
+ (tree_dump_bb): Display the contents of BB_PREV_CHAIN_P.
+ * tree-dfa.c (tree_find_varrefs): Use accessor macros for array
+ 'referenced_symbols'.
+ (find_refs_in_stmt): Do not process error_mark_node trees.
+ Handle statement-expression nodes as any other statement tree.
+ Do not call find_refs_in_stmt_expr.
+ (find_refs_in_stmt_expr): Remove.
+ (add_ref_to_sym): Remove.
+ (add_ref_to_bb): Remove.
+ (find_refs_in_expr): Do not process error_mark_node trees.
+ ADDR_EXPR trees are not variable references except if used in a
+ CALL_EXPR node.
+ Handle EXPR_WITH_FILE_LOCATION nodes.
+ (create_varref): Remove variable 'is_new'.
+ Initialize data-flow arrays VARDEF_IMM_USES, VARDEF_RUSES,
+ VARDEF_PHI_CHAIN and VARUSE_RDEFS.
+ Do not call add_ref_to_sym and add_ref_to_bb.
+ (add_ref_symbol): Use accessor macros for varray
+ 'referenced_symbols'.
+ (function_may_recurse_p): New function.
+ (get_fcalls): New function.
+ (find_declaration): New function.
+ (dump_varref): Handle NULL values of VARREF_EXPR.
+ Use VARDEF_PHI_CHAIN instead of VARPHI_CHAIN.
+ (dump_varref_list): Check if the list is NULL before traversing it.
+ * tree-flow.h (struct vardef): Add fields 'ruses', 'marked' and
+ 'phi_chain'.
+ (VARDEF_RUSES): Define.
+ (VARDEF_MARKED): Define.
+ (VARDEF_PHI_CHAIN): Define.
+ (VARPHI_CHAIN): Remove.
+ (struct varphi): Remove.
+ (struct varuse): Add field 'rdefs'.
+ (VARUSE_RDEFS): Define.
+ (union varref_def): Remove field 'phi'.
+ (IS_GHOST_DEF): Define.
+ (IS_ARTIFICIAL_REF): Define.
+ (struct bb_ann_def): Add fields 'prev_chain_p' and 'binding_scope'.
+ (BB_PREV_CHAIN_P): Define.
+ (BB_BINDING_SCOPE): Define.
+ (FOR_INIT_STMT_BB): Define.
+ (FOR_COND_BB): Define.
+ (FOR_EXPR_BB): Define.
+ (WHILE_COND_BB): Define.
+ (DO_COND_BB): Define.
+ (IF_COND_BB): Define.
+ (CASE_COND_BB): Define.
+ (NREF_SYMBOLS): Define.
+ (REF_SYMBOL): Define.
+ (ADD_REF_SYMBOL): Define.
+ (FCALL_NON_PURE): Define.
+ (FCALL_PURE): Define.
+ (FCALL_BUILT_IN): Define.
+ (loop_body): Declare.
+ (set_loop_body): Declare.
+ (last_exec_stmt): Declare.
+ (is_statement_expression): Declare.
+ (first_non_decl_stmt): Declare.
+ (first_decl_stmt): Declare.
+ (first_non_label_in_bb): Declare.
+ (insert_stmt_tree_before): Declare.
+ (insert_stmt_tree_after): Declare.
+ (replace_expr_in_tree): Declare.
+ (find_expr_in_tree): Declare.
+ (insert_bb_before): Declare.
+ (function_may_recurse_p): Declare.
+ (get_fcalls): Declare.
+ (find_declaration): Declare.
+ (tree_compute_rdefs): Declare.
+ (analyze_rdefs): Declare.
+ (is_upward_exposed): Declare.
+ * tree-optimize.c (optimize_tree): Update name for varray
+ referenced_symbols.
+ Free varray referenced_symbols and call delete_ssa on exit.
+ * tree-ssa.c: Include flags.h, diagnostic.h and toplev.h.
+ (tree_build_ssa): Create ghost definitions before building FUD
+ chains.
+ (insert_phi_terms): Use accessor macros for 'referenced_symbols'.
+ Ignore ghost definitions when placing PHI terms.
+ (build_fud_chains): Call get_tree_ann to create an annotation for
+ the symbol if it doesn't already have one.
+ (search_fud_chains): Reformat comments.
+ Do not initialize varray VARDEF_IMM_USES.
+ If a successor basic block does not have references, continue on to
+ the next one, do not stop.
+ Do not initialize varray VARDEF_PHI_CHAIN.
+ (delete_ssa): New function.
+ (delete_refs): New function.
+ (tree_compute_rdefs): New function.
+ (analyze_rdefs): New function.
+ (follow_chain): New function.
+ (is_upward_exposed): New function.
+
+2001-09-14 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (tree_find_basic_blocks): Remove call to
+ mark_critical_edges.
+ (create_maximal_bb): Do not create annotations for non-executable
+ statements.
+ (map_stmt_to_bb): Rename basic_block_ann with bb_ann.
+ (delete_cfg): Ditto.
+ (is_exec_stmt): Reformat.
+ (create_bb_ann): New function.
+ * tree-dfa.c (create_node): Remove.
+ (ref_symbols_list): Remove.
+ (create_tree_ann): Declare.
+ (referenced_symbols): Declare.
+ (tree_find_varrefs): Replace usage of linked lists with variable
+ arrays.
+ (create_varref): Remove second argument from call to
+ add_ref_symbol.
+ Update comments.
+ (add_ref_to_sym): Replace usage of linked lists with variable
+ arrays.
+ Declare static.
+ (add_ref_to_bb): Ditto.
+ (add_ref_symbol): Ditto.
+ (dump_varref_list): Ditto.
+ (debug_varref_list): Ditto.
+ (create_varref_list): Remove.
+ (push_ref): Remove.
+ (create_node): Remove.
+ (delete_varref_list): Remove.
+ (get_tree_ann): Call create_tree_ann if the tree doesn't have an
+ annotation already.
+ (create_tree_ann): New function.
+ * tree-flow.h (varref_list_def): Remove.
+ (vardef): Change type of field 'imm_uses' to 'varray_type'.
+ (varphi): Change type of field 'phi_chain' to 'varray_type'.
+ (varref_node_def): Remove.
+ (varref_node): Remove.
+ (VARREF_NODE_ELEM): Remove.
+ (VARREF_NODE_NEXT): Remove.
+ (VARREF_NODE_PREV): Remove.
+ (varref_list_def): Remove.
+ (varref_list): Remove.
+ (VARREF_LIST_FIRST): Remove.
+ (VARREF_LIST_LAST): Remove.
+ (tree_ann_def): Change type of field 'refs' to 'varray_type'.
+ (basic_block_ann_def): Rename to 'bb_ann_def'.
+ Change type of field 'refs' to 'varray_type'.
+ (basic_block_ann): Rename to 'bb_ann'.
+ (ref_symbols_list): Remove.
+ (referenced_symbols): Declare.
+ (add_ref_to_sym): Remove.
+ (add_ref_to_bb): Remove.
+ (add_ref_symbol): Remove.
+ (remove_ann_from_sym): Remove.
+ (create_varref_list): Remove.
+ (push_ref): Remove.
+ (delete_varref_list): Remove.
+ (debug_varref_list): Update argument type to be 'varray_type'.
+ (dump_varref_list): Ditto.
+ * tree-optimize.c: Include 'basic-block.h'.
+ (optimize_tree): Replace references to 'ref_symbols_list' with
+ 'referenced_symbols'.
+ Remove call to delete_varref_list.
+ * tree-ssa.c (insert_phi_terms): Rename 'work_list' to
+ 'work_stack'.
+ Use VARRAY_PUSH and VARRAY_TOP to access 'work_stack' instead of
+ maintaining the stack pointer in 'work_list_top'.
+ Remove code to grow 'work_stack'.
+ Remove references to 'work_list_top'.
+ Replace references to 'ref_symbols_list' with 'referenced_symbols'.
+ (build_fud_chains): Replace references to 'ref_symbols_list' with
+ 'referenced_symbols'.
+ (search_fud_chains): If there are no variable references in the
+ basic block, return early.
+ Change usage of linked lists with variable arrays.
+
+2001-09-07 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (tree_find_basic_blocks): Document how to traverse
+ trees inside a basic block.
+ (make_for_stmt_blocks): Make sure that there is always a block for
+ FOR_EXPR, even if the loop does not have an expression.
+ Create a separate block for FOR_INIT_STMT.
+ (make_while_stmt_blocks): Always create an "end_while" block.
+ (make_if_stmt_blocks): Do not store IF_COND in the header block of
+ an IF statement.
+ (make_for_stmt_edges): Create an edge from the block header to the
+ block for FOR_INIT_STMT.
+ Determine the first block of the loop body calling BB_FOR_STMT on
+ the first executable statement in the body.
+ Remove the special case for missing FOR_EXPR trees.
+ (make_while_stmt_edges): Create a back edge from the end_while
+ block to the header block.
+ Determine the first block of the loop body calling BB_FOR_STMT on
+ the first executable statement in the body.
+ (make_do_stmt_edges): Determine the first block of the loop body
+ calling BB_FOR_STMT on the first executable statement in the body.
+ (condition_block): Rename to latch_block. Return the latch
+ block for the given loop header.
+ (make_continue_stmt_edges): Rename condition_block to
+ latch_block.
+ (successor_block): Ditto.
+ * tree-flow.h (condition_block): Rename to latch_block.
+
+2001-09-06 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dfa.c (tree_find_varrefs): Use TDF_REFS instead of TDF_VARREF.
+ * tree-flow.h (TDF_VARREF): Remove.
+
+2001-09-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * c-common.h (tree_dump_index): Add more comments.
+ (TDF_REFS): New dump flag.
+ * c-dump.c (dump_files): Name flags `tree' rather than `ast'.
+ (dump_option_value_info): New struct.
+ (dump_options): New array.
+ (dump_switch_p): Parse switch options symbolically.
+ * doc/invoke.texi (-fdump-ast): Rename to ...
+ (-fdump-tree): ... here. Document options are symbolic, and
+ not all are applicable. Combine ssa related flags into the other
+ tree dump flags.
+
+2001-08-27 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (tree-ssa.o): Update dependencies.
+ (tree-cfg.o): Ditto.
+ (tree-dfa.o): Ditto.
+ (tree-optimize.o): Ditto.
+
+2001-08-26 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (C_AND_OBJC_OBJS): Replace tree-opt.o with
+ tree-optimize.o.
+ (c-decl.o): Ditto.
+ (tree-ssa.o): Ditto.
+ (tree-cfg.o): Ditto.
+ (tree-dfa.o): Ditto.
+ (tree-opt.o): Ditto.
+ * c-decl.c: Replace tree-opt.h with tree-optimize.h.
+ (c_expand_body): Remove call to init_tree_opt.
+ * flow.c (flow_loop_dump): Do not display insn UIDs if this is not
+ an RTL basic block.
+ * tree-cfg.c: Replace tree-opt.h with tree-optimize.h.
+ (block_invalidates_loop): New local function.
+ (validate_loops): New function.
+ (tree_dump_bb): Display the loop depth of the block.
+ * tree-dfa.c: Replace tree-opt.h with tree-optimize.h.
+ * tree-flow.h (validate_loops): Declare.
+ * tree-opt.c: Rename to tree-optimize.c.
+ * tree-opt.h: Rename to tree-optimize.h.
+ * tree-optimize.c: Rename from tree-opt.c.
+ * tree-optimize.h: Rename from tree-opt.h.
+ * tree-ssa.c: Replace tree-opt.h with tree-optimize.h.
+ (tree_build_ssa): Call tree_dump_bb instead of tree_debug_bb.
+ * cp/Make-lang.in: Replace tree-opt.h with tree-optimize.h.
+
+2001-08-20 Diego Novillo <dnovillo@redhat.com>
+
+ * basic-block.h (basic_block): Remove field 'reachable'.
+ Add new field 'flags'.
+ (BB_REACHABLE): Define.
+ * c-common.h (tree_dump_index): Add TDI_cfg, TDI_dot, TDI_ssa.
+ * c-decl.c (c_decode_option): Skip '-f' prefix before calling
+ dump_switch_p.
+ * c-dump.c (dump_file_info): Add entries for -fdump-tree-cfg,
+ -fdump-tree-graphviz and -fdump-tree-ssa.
+ * flow.c (find_unreachable_blocks): Use BB_REACHABLE bit in bb->flags
+ instead of bb->reachable.
+ (delete_unreachable_blocks): Ditto.
+ * tree-cfg.c: Minor formatting changes throughout the file.
+ (DEBUG_TREE_FLOW): Remove.
+ (debug_tree_flow): Remove.
+ (cfg_dump_file): New local variable.
+ (dot_dump_file): New local variable.
+ (cfg_dump_flags): New local variable.
+ (dot_dump_flags): New local variable.
+ (tree_find_basic_blocks): Remove unused arguments.
+ Add code to react to -fdump-tree-cfg and -fdump-tree-graphviz.
+ Remove uses of DEBUG_TREE_FLOW.
+ (delete_unreachable_blocks): Use BB_REACHABLE bit in bb->flags
+ instead of bb->reachable.
+ (tree_dump_cfg): New.
+ (tree_debug_cfg): Call tree_dump_cfg().
+ (tree_cfg2dot): Accept a FILE pointer instead of a file name as
+ argument.
+ Name the graph with the current function name.
+ * tree-dfa.c: Minor formatting changes throughout the file.
+ (DEBUG_TREE_DFA): Remove.
+ (debug_tree_dfa): Remove.
+ (dump_file): New local variable.
+ (dump_flags): New local variable.
+ (tree_find_varrefs): Add code to react to -fdump-tree-ssa.
+ Remove uses of DEBUG_TREE_DFA.
+ (find_refs_in_expr): Remove uses of DEBUG_TREE_DFA.
+ (create_varref): Replace VARREF_BLOCK with VARREF_BB.
+ * tree-flow.h: Minor formatting changes throughout the file.
+ (VARREF_BLOCK): Rename to VARREF_BB.
+ (VARREF_NEXT): Remove.
+ (VARREF_PREV): Remove.
+ (TDF_VARREF): Define.
+ (tree_find_basic_blocks): Remove unused arguments.
+ (tree_dump_cfg): Declare.
+ (tree_cfg2dot): Change argument to FILE *.
+ * tree-opt.c: Minor formatting changes throughout the file.
+ (optimize_tree): Remove unused arguments in call to
+ tree_find_basic_blocks().
+ * tree-opt.h: Ditto.
+ * tree-ssa.c: Minor formatting changes throughout the file.
+ (DEBUG_TREE_SSA): Remove.
+ (debug_tree_ssa): Remove.
+ (dump_file): New local variable.
+ (dump_flags): New local variable.
+ (tree_build_ssa): Add code to react to -fdump-tree-ssa.
+ Remove uses of DEBUG_TREE_SSA.
+ (insert_phi_terms): Remove uses of DEBUG_TREE_SSA.
+ * doc/invoke.texi: Add documentation for -fdump-tree-cfg,
+ -fdump-tree-graphviz and -fdump-tree-ssa.
+ Replace existing references to -fdump-tree with -fdump-ast.
+
+2001-08-10 Diego Novillo <dnovillo@redhat.com>
+
+ * basic-block.h (basic_block): Add new field 'reachable'.
+ (expunge_block): Declare.
+ * flow.c (ENTRY_BLOCK_PTR): Initialize field 'reachable'.
+ (EXIT_BLOCK_PTR): Ditto.
+ (expunge_block): Remove static declaration.
+ (cleanup_cfg): Clear bb->aux on every basic block.
+ (find_unreachable_blocks): Use field 'reachable' when computing
+ reachability.
+ (delete_unreachable_blocks): Use field 'reachable'.
+
+ * tree-cfg.c: Rename all instance of 'node' with 'block.
+ (get_successor_block): Rename to successor_block.
+ (make_compound_stmt_edges): Remove.
+ (make_switch_stmt_edges): Remove.
+ (delete_unreachable_blocks): New.
+ (delete_block): New.
+ (make_blocks): Add new argument 'compound_stmt'. Do not include
+ COMPOUND_STMT trees in the flowgraph.
+ (make_for_stmt_blocks): Include FOR_INIT_STMT in the entry block of
+ the loop.
+ If FOR_COND does not exist, create a tree holding the constant 1.
+ Add new argument 'compound_stmt'.
+ (make_while_stmt_blocks): Include WHILE_COND in the entry block of
+ the loop.
+ Add new argument 'compound_stmt'.
+ (make_do_stmt_blocks): Add new argument 'compound_stmt'.
+ (make_if_stmt_blocks): Add new argument 'compound_stmt'.
+ Include IF_COND in the IF header block.
+ (make_switch_stmt_blocks): Add new argument 'compound_stmt'.
+ Include SWITCH_COND in the SWITCH header block.
+ (create_maximal_bb): Remove argument 'is_loop_header'.
+ Add new argument 'compound_stmt'.
+ Update all callers.
+ Return the newly created basic block instead of its last statement.
+ Update comments.
+ Do not store control flow altering statements in bb->exit_stmt.
+ Only add executable statements to the block.
+ Annotate with 'compound_stmt' each tree added to the block.
+ (create_bb): Do not update annotation 'is_loop_header'.
+ (make_edges): Remove naive reachability analysis.
+ When a label node is found, add an edge from the immediately
+ enclosing switch statement.
+ Call delete_unreachable_blocks() after adding all the edges.
+ (make_ctrl_stmt_edges): Do not consider COMPOUND_STMT trees.
+ Do nothing for SWITCH_STMT trees.
+ (make_exit_edges): Use bb->end_tree instead of BB_EXIT_STMT.
+ (make_for_stmt_edges): Remove code that added edges for the block
+ holding FOR_INIT_STMT.
+ Update comments.
+ Do not consider the case where FOR_COND is NULL.
+ Call first_exec_stmt() to determine if FOR_BODY is empty.
+ Only create an edge from expr_bb to cond_bb if FOR_EXPR is
+ non-null.
+ (make_while_stmt_edges): Remove code that added edges for the block
+ holding WHILE_COND.
+ Update comments.
+ Call first_exec_stmt() to determine if WHILE_BODY is empty.
+ (make_do_stmt_edges): Call first_exec_stmt() to determine if
+ DO_BODY is empty.
+ (make_if_stmt_edges): Remove code that added edges for the block
+ holding IF_COND.
+ Call first_exec_stmt() to determine if THEN_CLAUSE or ELSE_CLAUSE
+ are empty.
+ (make_switch_stmt_edges): Remove.
+ (make_goto_stmt_edges): Use bb->end_tree instead of BB_EXIT_STMT.
+ (make_break_stmt_edges): Use bb->end_tree instead of BB_EXIT_STMT.
+ Call switch_parent() and loop_parent() to determine if the
+ statement is inside an appropriate control structure.
+ (make_continue_stmt_edges): Use bb->end_tree instead of
+ BB_EXIT_STMT.
+ (make_return_stmt_edges): Ditto.
+ (get_successor_block): Rename to successor_block.
+ Call first_exec_stmt() to find the first executable statement in
+ TREE_CHAIN.
+ (is_ctrl_stmt): Do not consider COMPOUND_STMT trees.
+ (stmt_starts_bb_p): Ditto.
+ (stmt_ends_bb_p): Reformat comments.
+ (delete_cfg): Reformat comments.
+ (find_loop_parent): Rename to loop_parent.
+ (get_condition_block): Rename to condition_block.
+ Update to use new index numbers for control structure header
+ blocks.
+ (switch_parent): New.
+ (first_exec_stmt): New.
+ (is_exec_stmt): New.
+ (tree_cfg2dot): Reformat comments.
+ * tree-dfa.c (find_refs): Remove.
+ (find_refs_in_stmt): New
+ (find_refs_in_stmt_expr): New.
+ (tree_find_varrefs): Look for variables doing a CFG traversal
+ instead of the trees. Remove both arguments.
+ (find_refs_in_expr): Add new argument 'bb'.
+ Update all recursive calls.
+ (create_varref): Abort if the basic block 'bb' is NULL.
+ (add_ref_to_sym): Reformat comments.
+ (add_ref_symbol): Ditto.
+ (delete_varref_list): Ditto.
+ * tree-flow.h (struct tree_ann_def): Add 'compound_stmt'.
+ (TREE_COMPOUND_STMT): New macro.
+ (struct basic_block_ann_def): Remove 'exit_stmt' and
+ 'is_loop_header'.
+ (BB_EXIT_STMT): Remove.
+ (BB_IS_LOOP_HEADER): Remove.
+ * tree-opt.c (optimize_tree): Call tree_find_varrefs() with no
+ arguments.
+ Only build DFA and SSA information if n_basic_blocks is greater
+ than zero.
+ * tree-ssa.c: Rename all instances of 'node' with 'block'.
+ (tree_build_ssa): Reformat comments.
+ (insert_phi_terms): Ditto.
+
+2001-08-01 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-cfg.c (USE_TREE_IL): Remove.
+ (make_back_edges): Remove.
+ (make_fallthru_edge): Remove.
+ (get_outermost_scope_block): Remove.
+ (is_last_block_of_loop): Remove.
+ (tree_find_basic_blocks): Do not return early if 'errorcount' is set.
+ (make_edges): Do not treat back edges as a separate case.
+ Do not call make_fallthru_edge to create fall-through edges.
+ Do not emit a warning for unreachable blocks containing a single
+ closing brace.
+ (make_do_stmt_edges): Update comment.
+ (make_goto_stmt_edges): Do not call get_outermost_scope_block().
+ (make_break_stmt_edges): Do not call get_outermost_scope_block().
+ Do not call make_back_edges().
+ (make_continue_stmt_edges): Call find_loop_parent(). Emit an error
+ if the 'continue' statement is not inside a loop. Call
+ get_condition_block() to find the target node.
+ (make_return_stmt_edges): Do not call get_outermost_scope_block().
+ (get_successor_block): Return EXIT_BLOCK_PTR if 'bb' is the last
+ block in the graph.
+ Return the condition node of the loop if 'bb' doesn't have a
+ natural successor and its parent is a loop header.
+ (tree_cfg2dot): Output fake edges with dotted lines.
+ * tree-dfa.c (USE_TREE_IL): Remove.
+ * tree-opt.c (USE_TREE_IL): Remove.
+ * tree-ssa.c (USE_TREE_IL): Remove.
+ * tree-flow.h (is_last_block_of_loop): Remove.
+
+2001-07-23 Diego Novillo <dnovillo@redhat.com>
+
+ * Makefile.in (C_AND_OBJC_OBJS): Add tree-cfg.o, tree-dfa.o,
+ tree-ssa.o and tree-opt.o.
+ (c-decl.o): Add dependency on tree-opt.h
+ (tree-ssa.o): New rule.
+ (tree-cfg.o): New rule.
+ (tree-dfa.o): New rule.
+ (tree-opt.o): New rule.
+ * c-decl.c: Include tree-opt.h.
+ (c_expand_body): Call optimize_tree() when the -ftree-ssa flag is
+ given.
+ * flags.h (flag_tree_ssa): Declare.
+ * toplev.c (flag_tree_ssa): Define.
+ (lang_independent_options): Add -ftree-ssa.
+ * tree-cfg.c: New file.
+ * tree-dfa.c: New file.
+ * tree-flow.h: New file.
+ * tree-opt.c: New file.
+ * tree-opt.h: New file.
+ * tree-ssa.c: New file.
+ * cp/Make-lang.in (CXX_C_OBJS): Add tree-cfg.o, tree-dfa.o,
+ tree-opt.o and tree-ssa.o.
+ * doc/invoke.texi: Add documentation for -ftree-ssa.
+
+2001-07-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ * Makefile.in (calls.o): Depend on intl.h.
+ * calls.c: Include intl.h.
+ (ECF_NEED_STACK_FRAME, ECF_NEED_ARG_FRAME): New flags.
+ (special_function_p): Detect when we need a stack or arg
+ frame. Don't optimize on length.
+ (setjmp_call_p): Remove.
+ (uninlinable_call_p): New function.
+ * tree.h (setjmp_call_p): Remove.
+ (uninlinable_call_p): Declare.
+
+2001-07-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ * params.def (PARAM_MAX_INLINE_AST): New parameter.
+ (PARAM_ARG_INLINE_AST): New parameter.
+ * doc/invoke.texi (max-inline-ast, arg-inline-ast): Document
+ parameters.
+
+Local Variables:
+mode: change-log
+change-log-default-name: "ChangeLog.tree-ssa"
+End:
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index f75afff19ab..5379c8e59d4 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -140,7 +140,7 @@ XCFLAGS =
TCFLAGS =
CFLAGS = -g
STAGE1_CFLAGS = -g @stage1_cflags@
-BOOT_CFLAGS = -g -O2
+BOOT_CFLAGS = -g -O2
# Flags to determine code coverage. When coverage is disabled, this will
# contain the optimization flags, as you normally want code coverage
@@ -192,6 +192,14 @@ c-parse.o-warn = -Wno-error
gengtype-lex.o-warn = -Wno-error
# SYSCALLS.c misses prototypes
SYSCALLS.c.X-warn = -Wno-strict-prototypes -Wno-error
+# These files need -Wno-error because the gimplifier triggers hard to fix
+# warnings when converting to GIMPLE form. The warnings are triggered because
+# moving the condition into the loop prevents the loop optimizer from
+# recognizing that the loop will always be executed at least once. We need
+# a new loop optimizer.
+reload1.o-warn = -Wno-error
+# These warnings are due to libbanshee.
+tree-alias-ander.o-warn = -Wno-error
# All warnings have to be shut off in stage1 if the compiler used then
# isn't gcc; configure determines that. WARN_CFLAGS will be either
@@ -270,6 +278,12 @@ OUTPUT_OPTION = @OUTPUT_OPTION@
ZLIB = @zlibdir@ -lz
ZLIBINC = @zlibinc@
+# How to find GMP
+GMPLIBS = @GMPLIBS@
+GMPINC = @GMPINC@
+
+BANSHEELIB = @BANSHEELIB@
+BANSHEEINC = @BANSHEEINC@
# Substitution type for target's getgroups 2nd arg.
TARGET_GETGROUPS_T = @TARGET_GETGROUPS_T@
@@ -687,6 +701,11 @@ C_TREE_H = c-tree.h $(C_COMMON_H)
SYSTEM_H = system.h hwint.h $(srcdir)/../include/libiberty.h
PREDICT_H = predict.h predict.def
CPPLIB_H = cpplib.h line-map.h
+TREE_DUMP_H = tree-dump.h $(SPLAY_TREE_H)
+TREE_GIMPLE_H = tree-gimple.h tree-iterator.h
+TREE_FLOW_H = tree-flow.h tree-flow-inline.h tree-ssa-operands.h \
+ bitmap.h $(BASIC_BLOCK_H) hard-reg-set.h $(TREE_GIMPLE_H) \
+ $(HASHTAB_H)
PRETTY_PRINT_H = pretty-print.h input.h $(OBSTACK_H)
DIAGNOSTIC_H = diagnostic.h diagnostic.def $(PRETTY_PRINT_H)
C_PRETTY_PRINT_H = $(PRETTY_PRINT_H) $(C_COMMON_H) $(TREE_H)
@@ -713,7 +732,7 @@ LIBIBERTY = ../libiberty/libiberty.a
BUILD_LIBIBERTY = @FORBUILD@/libiberty/libiberty.a
# Dependencies on the intl and portability libraries.
-LIBDEPS= $(LIBIBERTY) $(LIBINTL_DEP) $(LIBICONV_DEP) libcpp.a
+LIBDEPS= $(LIBIBERTY) $(LIBINTL_DEP) $(LIBICONV_DEP) libcpp.a $(BANSHEELIB)
# Likewise, for use in the tools that must run on this machine
# even if we are cross-building GCC.
@@ -721,7 +740,7 @@ BUILD_LIBDEPS= $(BUILD_LIBIBERTY)
# How to link with both our special library facilities
# and the system's installed libraries.
-LIBS = @LIBS@ libcpp.a $(LIBIBERTY) $(LIBINTL) $(LIBICONV)
+LIBS = @LIBS@ libcpp.a $(LIBIBERTY) $(LIBINTL) $(LIBICONV) $(BANSHEELIB)
# Any system libraries needed just for GNAT.
SYSLIBS = @GNAT_LIBEXC@
@@ -750,7 +769,8 @@ BUILD_VARRAY = $(BUILD_PREFIX)varray.o
# currently being compiled, in both source trees, to be examined as well.
# libintl.h will be found in ../intl if we are using the included libintl.
INCLUDES = -I. -I$(@D) -I$(srcdir) -I$(srcdir)/$(@D) \
- -I$(srcdir)/../include @INCINTL@
+ -I$(srcdir)/../include @INCINTL@ \
+ $(BANSHEEINC) $(GMPINC)
.c.o:
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
@@ -838,14 +858,23 @@ CXX_TARGET_OBJS=@cxx_target_objs@
C_AND_OBJC_OBJS = attribs.o c-errors.o c-lex.o c-pragma.o c-decl.o c-typeck.o \
c-convert.o c-aux-info.o c-common.o c-opts.o c-format.o c-semantics.o \
c-incpath.o cppdefault.o c-ppoutput.o c-cppbuiltin.o prefix.o \
- c-objc-common.o c-dump.o c-pch.o $(C_TARGET_OBJS)
+ c-objc-common.o c-dump.o c-pch.o $(C_TARGET_OBJS) \
+ c-gimplify.o tree-mudflap.o c-mudflap.o c-pretty-print.o
# Language-specific object files for C.
-C_OBJS = c-parse.o c-lang.o c-pretty-print.o stub-objc.o $(C_AND_OBJC_OBJS)
+C_OBJS = c-parse.o c-lang.o stub-objc.o $(C_AND_OBJC_OBJS)
# Language-independent object files.
OBJS-common = \
+ tree-cfg.o tree-dfa.o tree-eh.o tree-ssa.o tree-optimize.o tree-gimple.o \
+ tree-alias-type.o gimplify.o tree-pretty-print.o tree-into-ssa.o \
+ tree-outof-ssa.o tree-alias-common.o tree-ssa-ccp.o \
+ @ANDER@ tree-ssa-dce.o tree-ssa-copy.o tree-nrv.o tree-ssa-copyrename.o \
+ tree-ssa-pre.o tree-ssa-live.o tree-ssa-operands.o tree-ssa-alias.o \
+ tree-ssa-phiopt.o tree-ssa-forwprop.o tree-nested.o tree-ssa-dse.o \
+ tree-ssa-dom.o domwalk.o tree-tailcall.o gimple-low.o tree-iterator.o \
+ tree-phinodes.o tree-ssanames.o tree-sra.o tree-complex.o tree-ssa-loop.o \
alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o \
cfg.o cfganal.o cfgbuild.o cfgcleanup.o cfglayout.o cfgloop.o \
cfgloopanal.o cfgloopmanip.o loop-init.o loop-unswitch.o loop-unroll.o \
@@ -863,14 +892,15 @@ OBJS-common = \
real.o recog.o reg-stack.o regclass.o regmove.o regrename.o \
reload.o reload1.o reorg.o resource.o rtl.o rtlanal.o rtl-error.o \
sbitmap.o sched-deps.o sched-ebb.o sched-rgn.o sched-vis.o sdbout.o \
- sibcall.o simplify-rtx.o sreal.o stmt.o stor-layout.o stringpool.o \
+ simplify-rtx.o sreal.o stmt.o stor-layout.o stringpool.o \
targhooks.o timevar.o toplev.o tracer.o tree.o tree-dump.o unroll.o \
varasm.o varray.o version.o vmsdbgout.o xcoffout.o alloc-pool.o \
- et-forest.o cfghooks.o bt-load.o pretty-print.o $(GGC) web.o passes.o
+ et-forest.o cfghooks.o bt-load.o pretty-print.o $(GGC) web.o passes.o \
+ rtl-profile.o tree-profile.o
OBJS-md = $(out_object_file)
OBJS-archive = $(EXTRA_OBJS) $(host_hook_obj) hashtable.o tree-inline.o \
- tree-optimize.o cgraph.o cgraphunit.o
+ cgraph.o cgraphunit.o tree-nomudflap.o
OBJS = $(OBJS-common) $(out_object_file) $(OBJS-archive)
@@ -905,7 +935,9 @@ STAGESTUFF = *$(objext) insn-flags.h insn-config.h insn-codes.h \
LIB2FUNCS_ST = _eprintf __gcc_bcmp
# Defined in libgcov.c, included only in gcov library
-LIBGCOV = _gcov _gcov_merge_add _gcov_merge_single _gcov_merge_delta
+LIBGCOV = _gcov _gcov_merge_add _gcov_merge_single _gcov_merge_delta \
+ _gcov_fork _gcov_execl _gcov_execlp _gcov_execle \
+ _gcov_execv _gcov_execvp _gcov_execve
FPBIT_FUNCS = _pack_sf _unpack_sf _addsub_sf _mul_sf _div_sf \
_fpcmp_parts_sf _compare_sf _eq_sf _ne_sf _gt_sf _ge_sf \
@@ -1123,9 +1155,9 @@ $(SPECS): xgcc$(exeext)
gcc-cross: xgcc$(exeext)
cp xgcc$(exeext) gcc-cross$(exeext)
-cc1$(exeext): $(C_OBJS) $(BACKEND) $(LIBDEPS)
+cc1$(exeext): $(C_OBJS) $(BACKEND) $(LIBDEPS) @TREEBROWSER@
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o cc1$(exeext) \
- $(C_OBJS) $(BACKEND) $(LIBS)
+ $(C_OBJS) @TREEBROWSER@ $(BACKEND) $(LIBS)
# Build the version of limits.h that we will install.
xlimits.h: glimits.h limitx.h limity.h
@@ -1306,7 +1338,7 @@ c-decl.o : c-decl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(RTL_H) $(C_TREE_H) $(GGC_H) $(TARGET_H) flags.h function.h output.h \
$(EXPR_H) debug.h toplev.h intl.h $(TM_P_H) tree-inline.h $(TIMEVAR_H) \
opts.h c-pragma.h gt-c-decl.h cgraph.h $(HASHTAB_H) libfuncs.h except.h \
- $(LANGHOOKS_DEF_H)
+ $(LANGHOOKS_DEF_H) $(TREE_DUMP_H)
c-typeck.o : c-typeck.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(C_TREE_H) \
$(TARGET_H) flags.h intl.h output.h $(EXPR_H) $(RTL_H) toplev.h $(TM_P_H) \
langhooks.h
@@ -1359,9 +1391,10 @@ c-common.o : c-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(OBSTACK_H) $(C_COMMON_H) flags.h toplev.h output.h c-pragma.h intl.h \
$(GGC_H) $(EXPR_H) $(TM_P_H) builtin-types.def builtin-attrs.def \
$(DIAGNOSTIC_H) gt-c-common.h langhooks.h varray.h $(RTL_H) \
- $(TARGET_H) $(C_TREE_H) langhooks.h
+ $(TARGET_H) $(C_TREE_H) tree-iterator.h langhooks.h
c-pretty-print.o : c-pretty-print.c $(C_PRETTY_PRINT_H) \
- $(C_COMMON_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) real.h
+ $(C_COMMON_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) real.h \
+ $(DIAGNOSTIC_H)
c-opts.o : c-opts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) c-pragma.h flags.h toplev.h langhooks.h \
@@ -1388,7 +1421,7 @@ c-semantics.o : c-semantics.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE
$(EXPR_H) $(PREDICT_H) tree-inline.h
c-dump.o : c-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
- $(C_TREE_H) tree-dump.h
+ $(C_TREE_H) $(TREE_DUMP_H)
c-pch.o : c-pch.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(CPPLIB_H) $(TREE_H) \
$(C_COMMON_H) output.h toplev.h c-pragma.h $(GGC_H) debug.h \
@@ -1474,7 +1507,7 @@ version.o: version.c version.h
gtype-desc.o: gtype-desc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) varray.h \
$(HASHTAB_H) $(TREE_H) $(RTL_H) function.h insn-config.h $(EXPR_H) $(OPTABS_H) \
libfuncs.h debug.h $(GGC_H) bitmap.h $(BASIC_BLOCK_H) hard-reg-set.h \
- cselib.h insn-addr.h
+ cselib.h insn-addr.h $(TREE_FLOW_H)
ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(GGC_H) \
$(HASHTAB_H) toplev.h $(PARAMS_H) hosthooks.h
@@ -1504,22 +1537,149 @@ langhooks.o : langhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H)
$(LANGHOOKS_DEF_H) flags.h $(GGC_H) gt-langhooks.h diagnostic.h
tree.o : tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) flags.h function.h \
toplev.h $(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) langhooks.h \
- real.h gt-tree.h
+ real.h gt-tree.h tree-iterator.h $(BASIC_BLOCK_H) $(TREE_FLOW_H)
tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(C_TREE_H) flags.h langhooks.h toplev.h output.h c-pragma.h $(RTL_H) $(GGC_H) \
- $(EXPR_H) $(SPLAY_TREE_H) tree-dump.h
+ $(EXPR_H) $(SPLAY_TREE_H) $(TREE_DUMP_H)
tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(RTL_H) $(EXPR_H) flags.h $(PARAMS_H) input.h insn-config.h \
$(INTEGRATE_H) $(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) toplev.h \
- langhooks.h $(C_COMMON_H) tree-inline.h cgraph.h intl.h function.h
-tree-optimize.o : tree-optimize.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(TREE_H) toplev.h langhooks.h cgraph.h $(TIMEVAR_H) function.h $(GGC_H)
-
+ langhooks.h $(C_COMMON_H) tree-inline.h cgraph.h intl.h function.h \
+ $(TREE_GIMPLE_H)
print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(GGC_H) langhooks.h real.h
stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
flags.h function.h $(EXPR_H) $(RTL_H) toplev.h $(GGC_H) $(TM_P_H) $(TARGET_H) \
langhooks.h
+tree-alias-type.o: tree-alias-type.c tree-alias-type.h $(SYSTEM_H) $(CONFIG_H) \
+ $(GGC_H) $(TM_H) coretypes.h $(VARRAY_H)
+tree-alias-ander.o: tree-alias-ander.c tree-alias-ander.h $(SYSTEM_H) \
+ $(CONFIG_H) $(GGC_H) $(TREE_H) $(TREE_FLOW_H) tree-alias-common.h \
+ $(TM_H) coretypes.h cgraph.h tree-pass.h
+tree-alias-common.o: tree-alias-common.c tree-alias-common.h $(SYSTEM_H) \
+ $(CONFIG_H) $(GGC_H) $(TREE_H) gt-tree-alias-common.h $(TREE_FLOW_H) \
+ $(TM_H) coretypes.h cgraph.h tree-pass.h $(TIMEVAR_H)
+tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
+ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h diagnostic.h \
+ errors.h toplev.h function.h $(TIMEVAR_H) tree-alias-common.h \
+ $(TM_H) coretypes.h $(TREE_DUMP_H) langhooks.h cfgloop.h \
+ tree-pass.h
+tree-into-ssa.o : tree-into-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
+ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h diagnostic.h \
+ errors.h toplev.h function.h $(TIMEVAR_H) tree-alias-common.h \
+ $(TM_H) coretypes.h $(TREE_DUMP_H) langhooks.h domwalk.h tree-pass.h
+tree-outof-ssa.o : tree-outof-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
+ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h diagnostic.h \
+ errors.h toplev.h function.h $(TIMEVAR_H) tree-alias-common.h \
+ $(TM_H) coretypes.h $(TREE_DUMP_H) langhooks.h domwalk.h \
+ tree-pass.h tree-ssa-live.h
+tree-ssa-dse.o : tree-ssa-dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TM_H) errors.h $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
+ $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) domwalk.h flags.h
+tree-ssa-forwprop.o : tree-ssa-forwprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TM_H) errors.h $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
+ $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H)
+tree-ssa-phiopt.o : tree-ssa-phiopt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TM_H) errors.h $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
+ $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) langhooks.h
+tree-nrv.o : tree-nrv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TM_H) $(TREE_H) $(RTL_H) function.h $(BASIC_BLOCK_H) $(EXPR_H) \
+ diagnostic.h $(TREE_FLOW_H) $(TIMEVAR_H) $(TREE_DUMP_H) tree-pass.h \
+ langhooks.h
+tree-ssa-copy.o : tree-ssa-copy.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
+ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h diagnostic.h \
+ errors.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
+ $(BASIC_BLOCK_H) tree-pass.h langhooks.h
+tree-ssa-dom.o : tree-ssa-dom.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
+ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h diagnostic.h \
+ errors.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
+ $(BASIC_BLOCK_H) domwalk.h real.h tree-pass.h flags.h langhooks.h
+tree-ssanames.o : tree-ssanames.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TM_H) $(TREE_H) varray.h $(GGC_H) gt-tree-ssanames.h
+tree-phinodes.o : tree-phinodes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TM_H) $(TREE_H) varray.h $(GGC_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) \
+ gt-tree-phinodes.h $(RTL_H)
+domwalk.o : domwalk.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(TREE_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) domwalk.h $(GGC_H)
+tree-ssa-live.o : tree-ssa-live.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
+ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h diagnostic.h \
+ errors.h toplev.h function.h $(TIMEVAR_H) tree-alias-common.h \
+ $(TM_H) coretypes.h $(TREE_DUMP_H) tree-ssa-live.h
+tree-ssa-copyrename.o : tree-ssa-copyrename.c $(TREE_FLOW_H) $(CONFIG_H) \
+ $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h \
+ diagnostic.h errors.h toplev.h function.h $(TIMEVAR_H) tree-pass.h \
+ tree-alias-common.h $(TM_H) coretypes.h $(TREE_DUMP_H) tree-ssa-live.h
+tree-ssa-pre.o : tree-ssa-pre.c $(TREE_FLOW_H) $(CONFIG_H) \
+ $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) \
+ $(GGC_H) output.h diagnostic.h errors.h toplev.h $(TIMEVAR_H) \
+ $(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h flags.h
+tree-cfg.o : tree-cfg.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
+ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) flags.h output.h \
+ diagnostic.h errors.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h \
+ $(TREE_DUMP_H) except.h langhooks.h cfgloop.h gt-tree-cfg.h tree-pass.h
+tree-tailcall.o : tree-tailcall.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
+ $(RTL_H) $(TREE_H) $(TM_P_H) function.h $(TM_H) coretypes.h \
+ $(TREE_DUMP_H) diagnostic.h except.h tree-pass.h flags.h langhooks.h
+tree-nested.o: tree-nested.c $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(TREE_H) \
+ $(RTL_H) $(TM_P_H) function.h tree-dump.h tree-inline.h tree-iterator.h \
+ tree-gimple.h cgraph.h $(EXPR_H) langhooks.h $(GGC_H) gt-tree-nested.h
+tree-iterator.o : tree-iterator.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
+ coretypes.h $(GGC_H) tree-iterator.h tree-gimple.h gt-tree-iterator.h
+tree-dfa.o : tree-dfa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
+ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h diagnostic.h \
+ errors.h tree-inline.h $(HASHTAB_H) flags.h function.h $(TIMEVAR_H) \
+ tree-alias-common.h convert.h $(TM_H) coretypes.h langhooks.h \
+ $(TREE_DUMP_H) tree-pass.h params.h
+tree-ssa-operands.o : tree-ssa-operands.c $(TREE_FLOW_H) $(CONFIG_H) \
+ $(SYSTEM_H) $(TREE_H) $(TM_P_H) $(GGC_H) diagnostic.h \
+ tree-inline.h flags.h function.h $(TM_H) $(TIMEVAR_H) tree-pass.h
+tree-eh.o : tree-eh.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
+ $(RTL_H) $(TREE_H) $(TM_H) flags.h function.h except.h langhooks.h \
+ $(GGC_H) tree-pass.h gt-tree-eh.h
+tree-ssa-loop.o : tree-ssa-loop.c $(TREE_FLOW_H) $(CONFIG_H) \
+ $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) cfgloop.h \
+ output.h diagnostic.h $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
+ tree-pass.h flags.h tree-inline.h
+tree-ssa-alias.o : tree-ssa-alias.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
+ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) tree-inline.h flags.h \
+ function.h $(TIMEVAR_H) tree-alias-common.h convert.h $(TM_H) coretypes.h \
+ langhooks.h $(TREE_DUMP_H) tree-pass.h params.h
+tree-optimize.o : tree-optimize.c $(TREE_FLOW_H) $(CONFIG_H) \
+ $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) \
+ $(GGC_H) output.h diagnostic.h errors.h flags.h tree-alias-common.h \
+ $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) toplev.h function.h \
+ langhooks.h flags.h cgraph.h tree-inline.h tree-mudflap.h $(GGC_H) \
+ cgraph.h tree-pass.h
+c-gimplify.o : c-gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) errors.h \
+ $(C_TREE_H) $(C_COMMON_H) diagnostic.h $(TREE_GIMPLE_H) varray.h flags.h \
+ langhooks.h toplev.h rtl.h $(TREE_FLOW_H) langhooks-def.h \
+ $(TM_H) coretypes.h $(C_PRETTY_PRINT_H) cgraph.h
+gimplify.o : gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) errors.h \
+ diagnostic.h $(TREE_GIMPLE_H) tree-inline.h varray.h langhooks.h \
+ langhooks-def.h $(TREE_FLOW_H) $(TIMEVAR_H) $(TM_H) coretypes.h except.h \
+ flags.h $(RTL_H) function.h $(EXPR_H) output.h $(GGC_H) gt-gimplify.h
+gimple-low.o : gimple-low.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) errors.h \
+ diagnostic.h $(TREE_GIMPLE_H) tree-inline.h varray.h langhooks.h \
+ langhooks-def.h $(TREE_FLOW_H) $(TIMEVAR_H) $(TM_H) coretypes.h except.h \
+ flags.h $(RTL_H) function.h tree-pass.h
+tree-browser.o : tree-browser.c tree-browser.def $(CONFIG_H) $(SYSTEM_H) \
+ $(TREE_H) errors.h tree-inline.h diagnostic.h $(HASHTAB_H) \
+ $(TM_H) coretypes.h
+tree-gimple.o : tree-gimple.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(EXPR_H) \
+ $(RTL_H) $(TREE_GIMPLE_H) $(TM_H) coretypes.h bitmap.h $(GGC_H)
+tree-mudflap.o : $(CONFIG_H) errors.h $(SYSTEM_H) $(TREE_H) tree-inline.h \
+ $(C_TREE_H) $(C_COMMON_H) $(TREE_GIMPLE_H) diagnostic.h $(HASHTAB_H) \
+ output.h varray.h langhooks.h tree-mudflap.h $(TM_H) coretypes.h \
+ $(TREE_DUMP_H) tree-pass.h
+c-mudflap.o : $(CONFIG_H) errors.h $(SYSTEM_H) $(TREE_H) tree-inline.h \
+ $(C_TREE_H) $(C_COMMON_H) $(TREE_GIMPLE_H) diagnostic.h $(HASHTAB_H) \
+ output.h varray.h langhooks.h tree-mudflap.h $(TM_H) coretypes.h
+tree-nomudflap.o : $(CONFIG_H) errors.h $(SYSTEM_H) $(TREE_H) tree-inline.h \
+ $(C_TREE_H) $(C_COMMON_H) $(TREE_GIMPLE_H) diagnostic.h $(HASHTAB_H) \
+ output.h varray.h langhooks.h tree-mudflap.h $(TM_H) coretypes.h
+tree-pretty-print.o : tree-pretty-print.c $(CONFIG_H) $(SYSTEM_H) \
+ errors.h $(TREE_H) diagnostic.h real.h $(HASHTAB_H) $(TREE_FLOW_H) \
+ $(TM_H) coretypes.h tree-iterator.h
fold-const.o : fold-const.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) flags.h real.h toplev.h $(HASHTAB_H) $(EXPR_H) $(RTL_H) $(GGC_H) \
$(TM_P_H) langhooks.h $(MD5_H)
@@ -1582,7 +1742,7 @@ varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_
function.o : function.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
flags.h function.h $(EXPR_H) $(OPTABS_H) libfuncs.h $(REGS_H) hard-reg-set.h \
insn-config.h $(RECOG_H) output.h toplev.h except.h $(HASHTAB_H) $(GGC_H) \
- $(TM_P_H) langhooks.h gt-function.h $(TARGET_H)
+ $(TM_P_H) langhooks.h gt-function.h $(TARGET_H) basic-block.h
stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) flags.h \
function.h insn-config.h hard-reg-set.h $(EXPR_H) libfuncs.h except.h \
$(LOOP_H) $(RECOG_H) toplev.h output.h varray.h $(GGC_H) $(TM_P_H) \
@@ -1595,7 +1755,8 @@ except.o : except.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) flags.h \
function.h $(REGS_H) $(EXPR_H) $(OPTABS_H) libfuncs.h $(INSN_ATTR_H) insn-config.h \
$(RECOG_H) output.h typeclass.h hard-reg-set.h toplev.h hard-reg-set.h \
- except.h reload.h $(GGC_H) langhooks.h intl.h $(TM_P_H) real.h $(TARGET_H)
+ except.h reload.h $(GGC_H) langhooks.h intl.h $(TM_P_H) real.h $(TARGET_H) \
+ tree-iterator.h
dojump.o : dojump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
flags.h function.h $(EXPR_H) $(OPTABS_H) $(INSN_ATTR_H) insn-config.h \
langhooks.h $(GGC_H) gt-dojump.h
@@ -1658,7 +1819,8 @@ cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
langhooks.h toplev.h flags.h $(GGC_H) $(TARGET_H) cgraph.h gt-cgraph.h \
output.h intl.h
cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
- langhooks.h tree-inline.h toplev.h flags.h $(GGC_H) $(TARGET_H) cgraph.h intl.h
+ langhooks.h tree-inline.h toplev.h flags.h $(GGC_H) $(TARGET_H) cgraph.h intl.h \
+ function.h
coverage.o : coverage.c gcov-io.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(TREE_H) flags.h output.h $(REGS_H) $(EXPR_H) function.h \
toplev.h $(GGC_H) $(TARGET_H) langhooks.h $(COVERAGE_H) libfuncs.h \
@@ -1677,14 +1839,26 @@ gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
hard-reg-set.h flags.h real.h insn-config.h $(GGC_H) $(RECOG_H) $(EXPR_H) \
$(BASIC_BLOCK_H) function.h output.h toplev.h $(TM_P_H) $(PARAMS_H) \
except.h gt-gcse.h $(TREE_H) cselib.h
-sibcall.o : sibcall.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
- function.h hard-reg-set.h flags.h insn-config.h $(RECOG_H) $(BASIC_BLOCK_H)
resource.o : resource.c $(CONFIG_H) $(RTL_H) hard-reg-set.h $(SYSTEM_H) coretypes.h \
$(TM_H) $(BASIC_BLOCK_H) $(REGS_H) flags.h output.h resource.h function.h toplev.h \
$(INSN_ATTR_H) except.h $(PARAMS_H) $(TM_P_H)
lcm.o : lcm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
hard-reg-set.h flags.h real.h insn-config.h $(INSN_ATTR_H) $(RECOG_H) $(EXPR_H) \
$(BASIC_BLOCK_H) $(TM_P_H) df.h function.h
+tree-ssa-dce.o : tree-ssa-dce.c $(CONFIG_H) system.h errors.h $(TREE_H) \
+ $(RTL_H) $(TM_P_H) $(TREE_FLOW_H) diagnostic.h $(TIMEVAR_H) $(TM_H) \
+ coretypes.h $(TREE_DUMP_H) tree-pass.h flags.h
+tree-ssa-ccp.o : tree-ssa-ccp.c $(CONFIG_H) system.h errors.h $(TREE_H) \
+ $(RTL_H) $(TM_P_H) $(TREE_FLOW_H) diagnostic.h tree-inline.h \
+ $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_GIMPLE_H) \
+ $(EXPR_H) tree-pass.h flags.h langhooks.h
+tree-sra.o : tree-sra.c $(CONFIG_H) system.h errors.h $(TREE_H) $(RTL_H) \
+ $(TM_P_H) $(TREE_FLOW_H) diagnostic.h tree-inline.h \
+ $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_GIMPLE_H) \
+ langhooks.h tree-pass.h flags.h
+tree-complex.o : tree-complex.c $(CONFIG_H) system.h $(TREE_H) \
+ $(TM_H) $(TREE_FLOW_H) $(TREE_GIMPLE_H) tree-iterator.h tree-pass.h \
+ flags.h
df.o : df.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
insn-config.h $(RECOG_H) function.h $(REGS_H) alloc-pool.h hard-reg-set.h \
$(BASIC_BLOCK_H) df.h $(FIBHEAP_H)
@@ -1695,7 +1869,14 @@ conflict.o : conflict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(OBSTACK_H)
$(HASHTAB_H) $(RTL_H) hard-reg-set.h $(BASIC_BLOCK_H)
profile.o : profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) flags.h output.h $(REGS_H) $(EXPR_H) function.h \
- toplev.h $(BASIC_BLOCK_H) $(COVERAGE_H) $(TREE_H) value-prof.h
+ toplev.h $(BASIC_BLOCK_H) $(COVERAGE_H) $(TREE_FLOW_H) value-prof.h
+tree-profile.o : tree-profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TM_H) $(RTL_H) $(TREE_H) flags.h output.h $(REGS_H) $(EXPR_H) function.h \
+ toplev.h $(BASIC_BLOCK_H) $(COVERAGE_H) $(TREE_H) value-prof.h \
+ tree-pass.h $(TREE_FLOW_H) $(TIMEVAR_H)
+rtl-profile.o : tree-profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TM_H) $(RTL_H) $(TREE_H) flags.h output.h $(REGS_H) $(EXPR_H) function.h \
+ toplev.h $(BASIC_BLOCK_H) $(COVERAGE_H) $(TREE_FLOW_H) value-prof.h
value-prof.o : value-prof.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(BASIC_BLOCK_H) hard-reg-set.h value-prof.h $(EXPR_H) output.h flags.h \
$(RECOG_H) insn-config.h $(OPTABS_H) $(REGS_H)
@@ -1716,9 +1897,9 @@ flow.o : flow.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
$(RECOG_H) function.h except.h $(EXPR_H) $(GGC_H) $(TM_P_H)
cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h insn-config.h \
$(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
- function.h except.h $(GGC_H) $(TM_P_H) alloc-pool.h
+ function.h except.h $(GGC_H) $(TM_P_H) alloc-pool.h $(TIMEVAR_H)
cfghooks.o: cfghooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
- $(BASIC_BLOCK_H) cfglayout.h $(TIMEVAR_H) toplev.h
+ $(BASIC_BLOCK_H) cfglayout.h $(TREE_FLOW_H) $(TIMEVAR_H) toplev.h
cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h \
insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
function.h except.h $(GGC_H) $(TM_P_H) insn-config.h $(EXPR_H)
@@ -1834,7 +2015,7 @@ recog.o : recog.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) function.
$(INSN_ATTR_H) real.h toplev.h output.h reload.h $(TM_P_H)
reg-stack.o : reg-stack.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
$(RECOG_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h toplev.h reload.h \
- varray.h function.h $(TM_P_H) $(GGC_H) gt-reg-stack.h
+ varray.h function.h $(TM_P_H) $(GGC_H) gt-reg-stack.h basic-block.h
sreal.o: sreal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) sreal.h
predict.o: predict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
flags.h insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
@@ -2082,7 +2263,7 @@ GTFILES = $(srcdir)/input.h $(srcdir)/coretypes.h $(srcdir)/cpplib.h \
$(host_xm_file_list) $(tm_file_list) $(HASHTAB_H) $(SPLAY_TREE_H) \
$(srcdir)/bitmap.h $(srcdir)/coverage.c $(srcdir)/function.h $(srcdir)/rtl.h \
$(srcdir)/optabs.h $(srcdir)/tree.h $(srcdir)/libfuncs.h $(srcdir)/hashtable.h \
- $(srcdir)/real.h $(srcdir)/varray.h $(srcdir)/insn-addr.h \
+ $(srcdir)/real.h $(srcdir)/varray.h $(srcdir)/insn-addr.h $(srcdir)/hwint.h \
$(srcdir)/cselib.h $(srcdir)/basic-block.h $(srcdir)/cgraph.h \
$(srcdir)/c-common.h $(srcdir)/c-tree.h \
$(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cselib.c $(srcdir)/cgraph.c \
@@ -2095,6 +2276,16 @@ GTFILES = $(srcdir)/input.h $(srcdir)/coretypes.h $(srcdir)/cpplib.h \
$(srcdir)/reg-stack.c $(srcdir)/cfglayout.c $(srcdir)/langhooks.c \
$(srcdir)/sdbout.c $(srcdir)/stmt.c $(srcdir)/stor-layout.c \
$(srcdir)/stringpool.c $(srcdir)/tree.c $(srcdir)/varasm.c \
+ $(srcdir)/tree-mudflap.c $(srcdir)/tree-flow.h \
+ $(srcdir)/c-objc-common.c $(srcdir)/c-common.c $(srcdir)/c-parse.in \
+ $(srcdir)/tree-ssanames.c $(srcdir)/tree-eh.c \
+ $(srcdir)/tree-phinodes.c $(srcdir)/tree-cfg.c \
+ $(srcdir)/tree-dfa.c $(srcdir)/tree-ssa-ccp.c \
+ $(srcdir)/tree-iterator.c $(srcdir)/gimplify.c \
+ $(srcdir)/tree-alias-type.h $(srcdir)/tree-alias-common.h \
+ $(srcdir)/tree-alias-type.c $(srcdir)/tree-alias-common.c \
+ $(srcdir)/tree-ssa-operands.h $(srcdir)/tree-ssa-operands.c \
+ $(srcdir)/tree-profile.c $(srcdir)/rtl-profile.c $(srcdir)/tree-nested.c \
$(out_file) \
@all_gtfiles@
@@ -2111,6 +2302,10 @@ gt-expr.h gt-sdbout.h gt-optabs.h gt-bitmap.h gt-dojump.h \
gt-dwarf2out.h gt-ra-build.h gt-reg-stack.h gt-dwarf2asm.h \
gt-dbxout.h gt-c-common.h gt-c-decl.h gt-c-parse.h \
gt-c-pragma.h gtype-c.h gt-input.h gt-cfglayout.h \
+gt-tree-alias-common.h gt-tree-mudflap.h \
+gt-tree-ssa-ccp.h gt-tree-eh.h \
+gt-tree-ssanames.h gt-tree-iterator.h gt-gimplify.h \
+gt-tree-phinodes.h gt-tree-cfg.h gt-tree-nested.h \
gt-stringpool.h gt-langhooks.h : s-gtype ; @true
gtyp-gen.h: s-gtyp-gen ; @true
@@ -2525,8 +2720,8 @@ specs.ready: specs
fi
# Until someone fixes this recursive make nightmare (please note where
-# BUILD_CFLAGS and WARN_CFLAGS are first expanded below versus which
-# later make invocation has the fine-grain -warn markings for fixinc):
+# BUILD_CFLAGS is first expanded below versus which later make invocation
+# has the fine-grain -warn markings for fixinc):
fixinc.sh-warn = -Wno-error
FIXINCSRCDIR=$(srcdir)/fixinc
@@ -2535,8 +2730,8 @@ fixinc.sh: $(FIXINCSRCDIR)/mkfixinc.sh $(FIXINCSRCDIR)/fixincl.c \
$(FIXINCSRCDIR)/server.h $(FIXINCSRCDIR)/inclhack.def specs.ready
(MAKE="$(MAKE)"; srcdir=`cd $(srcdir)/fixinc && ${PWD_COMMAND}` ; \
CC="$(CC_FOR_BUILD)"; CFLAGS="$(BUILD_CFLAGS)"; LDFLAGS="$(BUILD_LDFLAGS)"; \
- WARN_CFLAGS="$(WARN_CFLAGS)"; LIBERTY=`${PWD_COMMAND}`/"$(BUILD_LIBIBERTY)"; \
- export MAKE srcdir CC CFLAGS LDFLAGS WARN_CFLAGS LIBERTY; \
+ LIBERTY=`${PWD_COMMAND}`/"$(BUILD_LIBIBERTY)"; \
+ export MAKE srcdir CC CFLAGS LDFLAGS LIBERTY; \
cd ./fixinc && \
$(SHELL) $${srcdir}/mkfixinc.sh $(build) $(target))
@@ -2667,7 +2862,7 @@ TEXI_GCCINT_FILES = gccint.texi gcc-common.texi contribute.texi makefile.texi \
c-tree.texi rtl.texi md.texi tm.texi hostconfig.texi fragments.texi \
configfiles.texi collect2.texi headerdirs.texi funding.texi gnu.texi \
gpl.texi fdl.texi contrib.texi languages.texi sourcebuild.texi \
- gty.texi libgcc.texi
+ gty.texi libgcc.texi cfg.texi tree-ssa.texi
TEXI_GCCINSTALL_FILES = install.texi install-old.texi fdl.texi
@@ -2983,10 +3178,8 @@ $(DESTDIR)$(infodir)/%.info: doc/%.info installdirs
done; \
else true; fi
-if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \
- if [ -f $(DESTDIR)$(infodir)/dir ] ; then \
- if [ -f $@ ]; then \
- install-info --dir-file=$(DESTDIR)$(infodir)/dir $@; \
- else true; fi; \
+ if [ -f $@ ]; then \
+ install-info --dir-file=$(DESTDIR)$(infodir)/dir $@; \
else true; fi; \
else true; fi;
diff --git a/gcc/ada/5qsystem.ads b/gcc/ada/5qsystem.ads
index 4d17cdacde5..c8b94936ded 100644
--- a/gcc/ada/5qsystem.ads
+++ b/gcc/ada/5qsystem.ads
@@ -62,7 +62,7 @@ pragma Pure (System);
-- Storage-related Declarations
- type Address is private;
+ type Address is new Long_Integer;
Null_Address : constant Address;
Storage_Unit : constant := 8;
@@ -83,6 +83,18 @@ pragma Pure (System);
pragma Import (Intrinsic, ">=");
pragma Import (Intrinsic, "=");
+ -- Abstract declarations for arithmetic operations on type address.
+ -- These declarations are needed when Address is non-private. They
+ -- avoid excessive visibility of arithmetic operations on address
+ -- which are typically available elsewhere (e.g. Storage_Elements)
+ -- and which would cause excessive ambiguities in application code.
+
+ function "+" (Left, Right : Address) return Address is abstract;
+ function "-" (Left, Right : Address) return Address is abstract;
+ function "/" (Left, Right : Address) return Address is abstract;
+ function "*" (Left, Right : Address) return Address is abstract;
+ function "mod" (Left, Right : Address) return Address is abstract;
+
-- Other System-Dependent Declarations
type Bit_Order is (High_Order_First, Low_Order_First);
@@ -101,7 +113,6 @@ pragma Pure (System);
private
- type Address is mod Memory_Size;
Null_Address : constant Address := 0;
--------------------------------------
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 0a24bc008c9..16d3d0a7225 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,1397 @@
+2004-05-14 Robert Dewar <dewar@gnat.com>
+
+ * gnat_ugn.texi: Minor change to -gnatS documentation
+
+ * sprint.adb: Remove some instances of Assert (False) and for this
+ purpose replace them by output of a ??? string.
+
+ * checks.adb, exp_aggr.adb, sem_elim.adb: Remove useless pragma
+ Assert (False).
+
+ * lib-writ.adb, lib-load.adb, lib.ads, lib.adb: Remove Dependent_Unit
+ flag processing. This was suppressing required dependencies in
+ No_Run_Time mode and is not needed since the binder does not generate
+ references for things in libgnat anyway.
+
+ * sem_ch3.adb (Access_Type_Declaration): Reorganize code to avoid GCC
+ warning.
+
+2004-05-14 Thomas Quinot <quinot@act-europe.fr>
+
+ * gnat_ugn.texi: Document AIX-specific issue with initialization of
+ resolver library.
+
+ * exp_ch4.adb (Insert_Dereference_Action): Do not generate dereference
+ action for the case of an actual parameter in an init proc call.
+
+2004-05-14 Ed Schonberg <schonberg@gnat.com>
+
+ * sem_ch4.adb (Analyze_Selected_Component): If prefix is a protected
+ subtype, check visible entities in base type.
+
+ * exp_ch7.adb (Clean_Simple_Protected_Objects): Do not generate cleanup
+ actions if the object is a renaming.
+
+ * sem_ch12.adb (Same_Instantiated_Entity): Predicate for
+ Check_Formal_Package_Instance, to determine more precisely when the
+ formal and the actual denote the same entity.
+
+2004-05-14 Javier Miranda <miranda@gnat.com>
+
+ * par-ch10.adb (P_Context_Clause): Complete documentation on AI-262
+
+ * sem_ch10.adb (Analyze_With_Clause): After analyzed, the entity
+ corresponding to a private_with must be removed from visibility; it
+ will be made visible later, just before we analyze the private part of
+ the package.
+ (Check_Private_Child_Unit): Allow private_with clauses in public
+ siblings.
+ (Install_Siblings): Make visible the private entities of private-withed
+ siblings.
+ (Install_Withed_Unit): Do not install the private withed unit if we
+ are compiling a package declaration and the Private_With_OK flag was
+ not set by the caller. These declarations will be installed later,
+ just before we analyze the private part of the package.
+
+ * sem_ch3.adb (Analyze_Object_Declaration): In case of errors detected
+ during the evaluation of the expression that initializes the object,
+ decorate it with the expected type to avoid cascade errors.
+ Code cleanup.
+
+ * sem_ch6.adb (Analyze_Subprogram_Body): If we are compiling a library
+ subprogram we have to install the private_with clauses after its
+ specification has been analyzed (as documented in AI-262.TXT).
+
+ * sem_ch8.adb (Has_Private_With): New function. Determines if the
+ current compilation unit has a private with on a given entity.
+ (Find_Direct_Name): Detect the Beaujolais problem described in
+ AI-262.TXT
+
+ * sem_utils.ads, sem_util.adb (Is_Ancestor_Package): New function. It
+ provides the functionality of the function Is_Ancestor that was
+ previously available in sem_ch10. It has been renamed to avoid
+ overloading.
+
+ * sprint.adb (Sprint_Node_Actual): Print limited_with clauses
+
+2004-05-14 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * utils.c (build_vms_descriptor): Use SImode pointers.
+
+2004-05-14 Vasiliy Fofanov <fofanov@act-europe.fr>
+
+ * gnat_ugn.texi: Revised chapter "GNAT and Libraries".
+
+2004-05-14 GNAT Script <nobody@gnat.com>
+
+ * Make-lang.in: Makefile automatically updated
+
+2004-05-14 Arnaud Charlet <charlet@act-europe.fr>
+
+ Renaming of target specific files for clarity
+
+ * Makefile.in: Rename GNAT target specific files.
+
+ * 31soccon.ads, 31soliop.ads 35soccon.ads, 3asoccon.ads,
+ 3bsoccon.ads, 3gsoccon.ads, 3hsoccon.ads, 3psoccon.ads,
+ 3ssoccon.ads, 3ssoliop.ads, 3veacodu.adb, 3vexpect.adb,
+ 3vsoccon.ads, 3vsocthi.adb, 3vsocthi.ads, 3vtrasym.adb,
+ 3wsoccon.ads, 3wsocthi.adb, 3wsocthi.ads, 3wsoliop.ads,
+ 3zsoccon.ads, 3zsocthi.adb, 3zsocthi.ads, 41intnam.ads,
+ 42intnam.ads, 45intnam.ads, 4aintnam.ads, 4cintnam.ads,
+ 4gintnam.ads, 4hexcpol.adb, 4hintnam.ads, 4lintnam.ads,
+ 4nintnam.ads, 4ointnam.ads, 4onumaux.ads, 4pintnam.ads,
+ 4sintnam.ads, 4vcaldel.adb, 4vcalend.adb, 4vcalend.ads,
+ 4vintnam.ads, 4wcalend.adb, 4wexcpol.adb, 4wintnam.ads,
+ 4zintnam.ads, 4znumaux.ads, 4zsytaco.adb, 4zsytaco.ads,
+ 51osinte.adb, 51osinte.ads, 51system.ads,
+ 52osinte.adb, 52osinte.ads, 53osinte.ads, 54osinte.ads,
+ 55osinte.adb, 55osinte.ads, 55system.ads, 56osinte.adb,
+ 56osinte.ads, 56system.ads, 56taprop.adb, 56taspri.ads,
+ 56tpopsp.adb, 57system.ads, 58system.ads,
+ 5amastop.adb, 5aml-tgt.adb, 5aosinte.adb, 5aosinte.ads,
+ 5asystem.ads, 5ataprop.adb, 5atasinf.ads, 5ataspri.ads,
+ 5atpopsp.adb, 5avxwork.ads, 5bml-tgt.adb, 5bosinte.adb,
+ 5bosinte.ads, 5bsystem.ads, 5cosinte.ads, 5csystem.ads,
+ 5dsystem.ads, 5esystem.ads, 5fintman.adb, 5fosinte.adb,
+ 5fosinte.ads, 5fsystem.ads, 5ftaprop.adb, 5ftasinf.ads,
+ 5ginterr.adb, 5gintman.adb, 5gmastop.adb, 5gml-tgt.adb,
+ 5gosinte.ads, 5gproinf.adb, 5gproinf.ads, 5gsystem.ads,
+ 5gtaprop.adb, 5gtasinf.adb, 5gtasinf.ads, 5gtpgetc.adb,
+ 5hml-tgt.adb, 5hosinte.adb, 5hosinte.ads, 5hparame.ads,
+ 5hsystem.ads, 5htaprop.adb, 5htaspri.ads, 5htraceb.adb,
+ 5iosinte.adb, 5iosinte.ads, 5itaprop.adb, 5itaspri.ads,
+ 5ksystem.ads, 5kvxwork.ads, 5lml-tgt.adb, 5losinte.ads,
+ 5lparame.adb, 5lsystem.ads, 5msystem.ads, 5mvxwork.ads,
+ 5ninmaop.adb, 5nintman.adb, 5nosinte.ads, 5nsystem.ads,
+ 5ntaprop.adb, 5ntaspri.ads, 5ointerr.adb, 5omastop.adb,
+ 5oosinte.adb, 5oosinte.ads, 5oosprim.adb, 5oparame.adb,
+ 5osystem.ads, 5otaprop.adb, 5otaspri.ads, 5posinte.ads,
+ 5posprim.adb, 5psystem.ads, 5pvxwork.ads, 5sintman.adb,
+ 5sml-tgt.adb, 5sosinte.adb, 5sosinte.ads, 5sosprim.adb,
+ 5sparame.adb, 5ssystem.ads, 5staprop.adb, 5stasinf.adb,
+ 5stasinf.ads, 5staspri.ads, 5stpopsp.adb, 5svxwork.ads,
+ 5tosinte.ads, 5usystem.ads, 5vasthan.adb, 5vdirval.adb,
+ 5vinmaop.adb, 5vinterr.adb, 5vintman.adb, 5vintman.ads,
+ 5vmastop.adb, 5vml-tgt.adb, 5vosinte.adb, 5vosinte.ads,
+ 5vosprim.adb, 5vosprim.ads, 5vparame.ads, 5vsymbol.adb,
+ 5vsystem.ads, 5vtaprop.adb, 5vtaspri.ads, 5vtpopde.adb,
+ 5vtpopde.ads, 5vtraent.adb, 5vtraent.ads, 5vvaflop.adb,
+ 5wdirval.adb, 5wgloloc.adb, 5wintman.adb, 5wmemory.adb,
+ 5wml-tgt.adb, 5wosinte.ads, 5wosprim.adb, 5wsystem.ads,
+ 5wtaprop.adb, 5wtaspri.ads, 5xparame.ads, 5xsystem.ads,
+ 5xvxwork.ads, 5yparame.ads, 5ysystem.ads, 5zinterr.adb,
+ 5zintman.adb, 5zintman.ads, 5zml-tgt.adb, 5zosinte.adb,
+ 5zosinte.ads, 5zosprim.adb, 5zparame.ads, 5zstchop.adb,
+ 5zsystem.ads, 5ztaprop.adb, 5ztaspri.ads, 5ztfsetr.adb,
+ 5ztpopsp.adb, 6vcpp.adb, 6vcstrea.adb, 6vinterf.ads,
+ 7sinmaop.adb, 7sintman.adb, 7sosinte.adb, 7sosprim.adb,
+ 7staprop.adb, 7staspri.ads, 7stfsetr.adb, 7stpopsp.adb,
+ 7straceb.adb, 7straces.adb, 7strafor.adb, 7strafor.ads,
+ 7stratas.adb, 86numaux.adb, 86numaux.ads: Replaced by files below.
+
+ * a-caldel-vms.adb, a-calend-mingw.adb, a-calend-vms.adb,
+ a-calend-vms.ads, a-dirval-mingw.adb, a-dirval-vms.adb,
+ a-excpol-abort.adb, a-excpol-interix.adb, a-intnam-aix.ads,
+ a-intnam-dummy.ads, a-intnam-freebsd.ads, a-intnam-hpux.ads,
+ a-intnam-interix.ads, a-intnam-irix.ads, a-intnam-linux.ads,
+ a-intnam-lynxos.ads, a-intnam-mingw.ads, a-intnam-os2.ads,
+ a-intnam-solaris.ads, a-intnam-tru64.ads, a-intnam-unixware.ads,
+ a-intnam-vms.ads, a-intnam-vxworks.ads, a-numaux-libc-x86.ads,
+ a-numaux-vxworks.ads, a-numaux-x86.adb, a-numaux-x86.ads,
+ a-sytaco-vxworks.adb, a-sytaco-vxworks.ads, g-eacodu-vms.adb,
+ g-expect-vms.adb, g-soccon-aix.ads, g-soccon-freebsd.ads,
+ g-soccon-hpux.ads, g-soccon-interix.ads, g-soccon-irix.ads,
+ g-soccon-mingw.ads, g-soccon-solaris.ads, g-soccon-tru64.ads,
+ g-soccon-unixware.ads, g-soccon-vms.adb, g-soccon-vxworks.ads,
+ g-socthi-mingw.adb, g-socthi-mingw.ads, g-socthi-vms.adb,
+ g-socthi-vms.ads, g-socthi-vxworks.adb, g-socthi-vxworks.ads,
+ g-soliop-mingw.ads, g-soliop-solaris.ads, g-soliop-unixware.ads,
+ g-trasym-vms.adb, i-cpp-vms.adb, i-cstrea-vms.adb,
+ interfac-vms.ads, mlib-tgt-aix.adb, mlib-tgt-hpux.adb,
+ mlib-tgt-irix.adb, mlib-tgt-linux.adb, mlib-tgt-mingw.adb,
+ mlib-tgt-solaris.adb, mlib-tgt-tru64.adb, mlib-tgt-vms.adb,
+ mlib-tgt-vxworks.adb, s-asthan-vms.adb, s-gloloc-mingw.adb,
+ s-inmaop-dummy.adb, s-inmaop-posix.adb, s-inmaop-vms.adb,
+ s-interr-dummy.adb, s-interr-sigaction.adb, s-interr-vms.adb,
+ s-interr-vxworks.adb, s-intman-dummy.adb, s-intman-irix.adb,
+ s-intman-irix-athread.adb, s-intman-mingw.adb, s-intman-posix.adb,
+ s-intman-solaris.adb, s-intman-vms.adb, s-intman-vms.ads,
+ s-intman-vxworks.adb, s-intman-vxworks.ads, s-mastop-irix.adb,
+ s-mastop-tru64.adb, s-mastop-vms.adb, s-mastop-x86.adb,
+ s-memory-mingw.adb, s-osinte-aix.adb, s-osinte-aix.ads,
+ s-osinte-aix-fsu.ads, s-osinte-dummy.ads, s-osinte-freebsd.adb,
+ s-osinte-freebsd.ads, s-osinte-fsu.adb, s-osinte-hpux.ads,
+ s-osinte-hpux-dce.adb, s-osinte-hpux-dce.ads, s-osinte-interix.ads,
+ s-osinte-irix.adb, s-osinte-irix.ads, s-osinte-irix-athread.ads,
+ s-osinte-linux.ads, s-osinte-linux-fsu.ads, s-osinte-linux-ia64.ads,
+ s-osinte-lynxos-3.adb, s-osinte-lynxos-3.ads, s-osinte-lynxos.adb,
+ s-osinte-lynxos.ads, s-osinte-mingw.ads, s-osinte-os2.adb,
+ s-osinte-os2.ads, s-osinte-posix.adb, s-osinte-solaris.adb,
+ s-osinte-solaris.ads, s-osinte-solaris-fsu.ads,
+ s-osinte-solaris-posix.ads, s-osinte-tru64.adb, s-osinte-tru64.ads,
+ s-osinte-unixware.adb, s-osinte-unixware.ads, s-osinte-vms.adb,
+ s-osinte-vms.ads, s-osinte-vxworks.adb,
+ s-osinte-vxworks.ads, s-osprim-mingw.adb,
+ s-osprim-os2.adb, s-osprim-posix.adb, s-osprim-solaris.adb,
+ s-osprim-unix.adb, s-osprim-vms.adb, s-osprim-vms.ads,
+ s-osprim-vxworks.adb, s-parame-ae653.ads, s-parame-hpux.ads,
+ s-parame-linux.adb, s-parame-os2.adb, s-parame-solaris.adb,
+ s-parame-vms.ads, s-parame-vms-restrict.ads, s-parame-vxworks.ads,
+ s-proinf-irix-athread.adb, s-proinf-irix-athread.ads,
+ s-stchop-vxworks.adb, s-taprop-dummy.adb,
+ s-taprop-hpux-dce.adb, s-taprop-irix.adb,
+ s-taprop-irix-athread.adb, s-taprop-linux.adb, s-taprop-lynxos.adb,
+ s-taprop-mingw.adb, s-taprop-os2.adb, s-taprop-posix.adb,
+ s-taprop-solaris.adb, s-taprop-tru64.adb, s-taprop-vms.adb,
+ s-taprop-vxworks.adb, s-tasinf-irix.ads, s-tasinf-irix-athread.adb,
+ s-tasinf-irix-athread.ads, s-tasinf-solaris.adb, s-tasinf-solaris.ads,
+ s-tasinf-tru64.ads, s-taspri-dummy.ads, s-taspri-hpux-dce.ads,
+ s-taspri-linux.ads, s-taspri-lynxos.ads, s-taspri-mingw.ads,
+ s-taspri-os2.ads, s-taspri-posix.ads, s-taspri-solaris.ads,
+ s-taspri-tru64.ads, s-taspri-vms.ads, s-taspri-vxworks.ads,
+ s-tfsetr-default.adb, s-tfsetr-vxworks.adb, s-tpopde-vms.adb,
+ s-tpopde-vms.ads, s-tpopsp-lynxos.adb, s-tpopsp-posix.adb,
+ s-tpopsp-posix-foreign.adb, s-tpopsp-solaris.adb, s-tpopsp-vxworks.adb,
+ s-traceb-hpux.adb, s-traceb-mastop.adb, s-traces-default.adb,
+ s-traent-vms.adb, s-traent-vms.ads, s-trafor-default.adb,
+ s-trafor-default.ads, s-tratas-default.adb, s-vaflop-vms.adb,
+ s-vxwork-alpha.ads, s-vxwork-m68k.ads, s-vxwork-mips.ads,
+ s-vxwork-ppc.ads, s-vxwork-sparcv9.ads, s-vxwork-xscale.ads,
+ symbols-vms.adb, system-aix.ads, system-freebsd-x86.ads,
+ system-hpux.ads, system-interix.ads, system-irix-n32.ads,
+ system-irix-o32.ads, system-linux-x86_64.ads,
+ system-linux-x86.ads, system-lynxos-ppc.ads, system-lynxos-x86.ads,
+ system-mingw.ads, system-os2.ads, system-solaris-sparc.ads,
+ system-solaris-sparcv9.ads, system-solaris-x86.ads, system-tru64.ads,
+ system-unixware.ads, system-vms.ads, system-vms-zcx.ads,
+ system-vxworks-alpha.ads, system-vxworks-m68k.ads,
+ system-vxworks-mips.ads, system-vxworks-ppc.ads,
+ system-vxworks-sparcv9.ads, system-vxworks-xscale.ads: Replace files
+ above.
+
+2004-05-13 Zack Weinberg <zack@codesourcery.com>
+
+ * trans.c (gnat_stabilize_reference_1): Remove case 'b'.
+
+2004-05-13 Diego Novillo <dnovillo@redhat.com>
+
+ Merge from tree-ssa-20020619-branch.
+
+ * config-lang.in (boot_language, build_by_default): Set
+ to no.
+ * utils.c (unchecked_convert): Use OEP_ONLY_CONST.
+ (max_size): Add static chain op for call_expr.
+
+2004-05-12 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/15331
+ * 5gmastop.adb (Roff): Choose between '4' and '0', not '4' and ' '.
+
+2004-05-11 Roger Sayle <roger@eyesopen.com>
+
+ * utils.c (max_size): Use MIN_EXPR to find the minimum value of a
+ COND_EXPR.
+
+2004-05-10 Doug Rupp <rupp@gnat.com>
+
+ * 5qsystem.ads: Remove Short_Address subtype declaration. Moved to
+ system.aux_dec.
+
+ * s-auxdec.ads: Add Short_Address subtype (moved here from System).
+
+ * Makefile.in: [VMS]: Add translation for 5qauxdec.ads.
+
+ * init.c: [VMS] Macroize LIB$ calls for IA64 and Alpha.
+ Fixes undefined symbols in IA64 gnatlib.
+
+ * 5vinmaop.adb: Reference s-auxdec for Short_Address.
+
+ * 5xsystem.ads, 5vsystem.ads: Back out last change (addition of subtype
+ Short_Address). This will be moved to system.auxdec.
+
+2004-05-10 Thomas Quinot <quinot@act-europe.fr>
+
+ * sem_util.adb: Replace test for presence of a node that is always
+ present with a call to Discard_Node.
+
+ * sem_ch10.adb (Analyze_Compilation_Unit): Remove superfluous call to
+ Analyze on the library unit node after generation of distribution stub
+ constructs. The call was a no-op because Unit_Node has already been
+ Analyzed, and the tree fragments for the distribution stubs are
+ analyzed as they are inserted in Exp_Dist.
+ Update comment regarding to distribution stubs to reflect that we
+ do not generate stub in separate files anymore.
+
+ * einfo.ads: Clarify the fact that a tagged private type has the
+ E_Record_Type_With_Private Ekind.
+
+ * erroutc.adb: Minor reformatting
+
+ * erroutc.ads (Max_Msg_Length): Increase to cover possible larger
+ values if line length is increased using -gnatyM (noticed during code
+ reading).
+
+ * eval_fat.adb: Minor reformatting
+ Put spaces around exponentiation operator
+
+2004-05-10 Ed Schonberg <schonberg@gnat.com>
+
+ PR ada/15005
+ * sem_util.adb (Is_Dependent_Component_Of_Mutable_Object): If prefix
+ has been rewritten as an explicit dereference, retrieve type of
+ original node to check for possibly unconstrained record type.
+
+2004-05-10 Ed Schonberg <schonberg@gnat.com>
+
+ * exp_ch7.adb (Check_Visibly_Controlled): If given operation is not
+ overriding, use the operation of the parent unconditionally.
+
+ * sem_ch4.adb (Remove_Address_Interpretations): Remove address
+ operation when either operand is a literal, to avoid further
+ ambiguities.
+
+ * sem_ch6.adb (New_Overloaded_Entity): If new entity is inherited and
+ overridden by a previous explicit declaration, mark the previous entity
+ as overriding.
+
+ * sem_disp.adb (Check_Dispatching_Operation): New predicate
+ Is_Visibly_Controlled, to determine whether a declaration of a
+ primitive control operation for a derived type overrides an inherited
+ one. Add warning if the explicit declaration does not override.
+
+2004-05-10 Vincent Celier <celier@gnat.com>
+
+ * gnatls.adb (Gnatls): Initialize Snames, to avoid assertion error in
+ some cases when the sources are no longer present.
+
+ * make.adb (Collect_Arguments): Fail if an external source, not part
+ of any project need to be compiled, when switch -x has not been
+ specified.
+
+ * makeusg.adb: Document new switch -x
+
+ * opt.ads (External_Unit_Compilation_Allowed): New Boolean flag,
+ defaulted to False.
+
+ * switch-m.adb (Scan_Make_Switches): New switch -x
+
+ * vms_data.ads: Add VMS qualifier /NON_PROJECT_UNIT_COMPILATION for
+ gnatmake switch -x.
+
+ * gnat_ugn.texi: Document new gnatmake switch -x
+
+2004-05-10 Eric Botcazou <ebotcazou@act-europe.fr>
+
+ * misc.c (gnat_init_options): Set flag_zero_initialized_in_bss to 0.
+
+ * utils.c (create_var_decl): Do not modify the DECL_COMMON flag.
+ (process_attributes): Likewise.
+
+2004-05-10 Joel Brobecker <brobecker@gnat.com>
+
+ * s-inmaop.ads: Fix spelling mistake in one of the comments.
+
+2004-05-10 Robert Dewar <dewar@gnat.com>
+
+ * gnat_ugn.texi: Document that for config pragma files, the maximum
+ line length is always 32767.
+
+ * gnat_rm.texi: For pragma Eliminate, note that concatenation of string
+ literals is now allowed.
+
+ * gnat-style.texi: Remove statement about splitting long lines before
+ an operator rather than after, since we do not follow this rule at all.
+ Clarify rule (really lack of rule) for spaces around exponentiation
+
+ * sem_elim.adb: Allow concatenation of string literals as well as a
+ single string literal for pragma arguments.
+
+ * sem_prag.ads, sem_prag.adb: (Is_Config_Static_String): New function
+
+ * a-textio.adb (Terminate_Line): Do not add line feed if nothing
+ written for append case.
+
+ * frontend.adb: Changes to avoid checking max line length in config
+ pragma files.
+
+ * g-os_lib.ads: Minor reformatting
+
+ * mlib-utl.adb: Do not define Max_Line_Length locally (definition was
+ wrong in any case. Instead use standard value. Noticed during code
+ reading.
+
+ * opt.ads (Max_Line_Length): New field, used to implement removal of
+ limitation on length of lines when scanning config pragma files.
+
+ * osint.ads, prj-dect.adb, prj-strt.adb, prj-tree.adb,
+ makeutl.ads, makeutl.adb: Minor reformatting
+
+ * scn.adb: Do not check line length while scanning config pragma files
+ Do not check line length while scanning out license information
+
+ * scng.adb: Changes to avoid line length checks while parsing config
+ pragma files.
+
+2004-05-10 GNAT Script <nobody@gnat.com>
+
+ * Make-lang.in: Makefile automatically updated
+
+2004-05-05 Arnaud Charlet <charlet@act-europe.fr>
+
+ * osint.adb (Find_Program_Name): Fix handling of VMS version
+ number.
+
+2004-05-05 Emmanuel Briot <briot@act-europe.fr>
+
+ * g-os_lib.ads (Invalid_Time): New constant
+
+ * adaint.h, adaint.c (__gnat_file_time_name, __gnat_file_time_fd): Now
+ return OS_Time instead of time_t to match what is imported by Ada.
+ Now return -1 if the file doesn't exist, instead of a random value
+
+2004-05-05 Robert Dewar <dewar@gnat.com>
+
+ * usage.adb: Add line for -gnatR?s switch
+
+ * sem_ch13.adb, exp_ch2.adb: Minor reformatting
+
+ * g-regpat.ads, g-regpat.adb: Add documentation on handling of Size
+ and for Match (Data_First, Data_last)
+
+ * lib-writ.adb (Write_With_Lines): Ensure that correct index number is
+ written when we are dealing with multi-unit files.
+
+2004-05-05 Jerome Guitton <guitton@act-europe.fr>
+
+ * Makefile.in: Remove unused targets and variables.
+
+2004-05-05 Vincent Celier <celier@gnat.com>
+
+ * switch-m.adb: New gnatmake switch -eI
+
+ * vms_data.ads: Add VMS equivalents of new gnatclean swith -innn and
+ of new gnatmake switch -eInnn.
+
+ * makegpr.adb: Take into account new parameters Index and Src_Index in
+ Prj.Util.
+
+ * clean.adb: Implement support for multi-unit sources, including new
+ switch -i.
+
+ * gnatcmd.adb (GNATCmd): Call Prj.Util.Value_Of with new parameter
+ Src_Index.
+
+ * make.ads, make.adb (Insert_Q): New parameter Index, defaulted to 0
+ (Extract_From_Q): New out parameter Index
+ (Mark, Is_Marked): Subprograms moved to Makeutl
+ (Switches_Of): New parameter Source_Index
+ (Add_Switch): New parameter Index
+ (Check): New parameter Source_Index
+ (Collect_Arguments): New parameter Source_Index
+ (Collect_Arguments_And_Compile): New parameter Source_Index
+ (Compile): New parameter Source_Index
+ Put subprograms in alphabetical order
+ Add support for multi-source sources, including in project files.
+
+ * makeutl.ads, makeutl.adb (Unit_Index_Of): New function
+ (Mark, Is_Marked, Delete_All_Marks): New subprograms, moved from
+ Make.
+
+ * makeusg.adb: New gnatmake switch -eInnn
+
+ * mlib-prj.adb (Build_Library): Add new parameter Src_Index to call to
+ Prj.Util.Value_Of.
+
+ * opt.ads (Main_Index): New variable, defaulted to 0.
+
+ * osint.ads, osinte.adb (Add_File): New parameter Index
+ (Current_Source_Index): New function
+
+ * prj.adb: Take into account new components Index and Src_Index
+
+ * prj.ads (String_Element): New component Index
+ (Variable_Value): New component Index
+ (Array_Element): New component Src_Index
+
+ * prj-attr.adb: Indicate that optional index may be specified for
+ attributes Main, Executable, Spec, Body and some of Switches.
+
+ * prj-attr.ads (Attribute_Kind): New values for optional indexes
+ (Attribute_Record): New component Optional_Index
+
+ * prj-com.ads (File_Name_Data): New component Index
+
+ * prj-dect.adb (Parse_Attribute_Declaration): Process optional index
+
+ * prj-env.adb (Put): Output optional index
+
+ * prj-makr.adb: Put indexes for multi-unit sources in SFN pragmas and
+ attributes Spec and Body.
+
+ * prj-nmsc.adb: Process optional indexes
+
+ * prj-pp.adb: Ouput "at" for optional indexes
+
+ * prj-proc.adb: Take into account optional indexes
+
+ * prj-strt.ads, prj-strt.adb (Terms): New Boolean parameter
+ Optional_Index. For string literal,
+ process optional index when Optional_Index is True.
+ (Parse_Expresion): New Boolean parameter Optional_Index
+
+ * prj-tree.ads, prj-tree.adb (Source_Index_Of): New function
+ (Set_Source_Index_Of): New procedure
+
+ * prj-util.adb (Executable_Of, Value_Of): Take into account optional
+ index.
+
+ * prj-util.ads (Executable_Of): New parameter Index
+ (Value_Of (Name_Id, Array_Element_Id) returning Variable_Value):
+ New parameter Src_Index, defaulted to 0.
+
+2004-05-05 Ed Schonberg <schonberg@gnat.com>
+
+ PR ada/15257
+ * sem_ch3.adb (Access_Definition): If this is an access parameter
+ whose designated type is imported through a limited_with clause, do
+ not add the enclosing subprogram to the list of private dependents of
+ the type.
+
+2004-05-05 Ed Schonberg <schonberg@gnat.com>
+
+ PR ada/15258
+ * sem_ch6.adb (Base_Types_Match): True if one type is imported through
+ a limited_with clause, and the other is its non-limited view.
+
+2004-05-05 Thomas Quinot <quinot@act-europe.fr>
+
+ * cstand.adb (Create_Standard): Initialize Stand.Boolean_Literals.
+
+ * exp_attr.adb, exp_ch5.adb, exp_ch9.adb, exp_disp.adb,
+ exp_fixd.adb, sem_attr.adb, sem_dist.adb, sem_util.adb: Use
+ Stand.Boolean_Literals to produce references to entities
+ Standard_False and Standard_True from compile-time computed boolean
+ values.
+
+ * stand.ads (Boolean_Literals): New variable, provides the entity
+ values for False and True, for use by the expander.
+
+2004-05-05 Doug Rupp <rupp@gnat.com>
+
+ * 5vinmaop.adb, 5[vx]system.ads: Add Short_Address subtype
+ 5vinmaop.adb: Unchecked convert Short_Address vice Address
+
+ * adaint.c, raise.c: Caste CRTL function return value
+ to avoid gcc error on 32/64 bit IVMS.
+
+ * Makefile.in [VMS]: Use iar archiver if host = Alpha/VMS and
+ target = IA64/VMS.
+
+ * init.c[VMS]: Only call Alpha specific __gnat_error_prehandler IN_RTS.
+
+ * 5qsystem.ads (Address): Declare as Long_Integer
+ (Short_Address): Declare as 32 bit subtype of Address
+ Declare abstract address operations to avoid gratuitous ambiguities.
+
+2004-05-05 Jose Ruiz <ruiz@act-europe.fr>
+
+ * gnat_rm.texi: Use the new restriction Simple_Barriers (AI-249)
+ instead of the old Boolean_Entry_Barriers.
+ Ditto for No_Task_Attributes_Package instead of No_Task_Attributes.
+
+2004-05-05 GNAT Script <nobody@gnat.com>
+
+ * Make-lang.in: Makefile automatically updated
+
+2004-05-03 Arnaud Charlet <charlet@act-europe.fr>
+
+ * 50system.ads, 59system.ads, s-thread.ads: Removed, no longer used.
+
+2004-05-03 Olivier Hainque <hainque@act-europe.fr>
+
+ PR ada/15152
+
+ * exp_ch2.adb (Expand_Current_Value): Leave Machine_Code Asm arguments
+ alone. Replacing object references by literals is inappropriate in a
+ so low level context.
+
+2004-05-03 Arnaud Charlet <charlet@act-europe.fr>
+
+ * a-exexpr.adb: Add comments
+
+2004-05-03 Joel Brobecker <brobecker@gnat.com>
+
+ * a-tags.adb (Tag_Table): Add Index_Check pragma Suppress. Allows us to
+ declare the Ancestor_Tags array in Type_Specific_Data with a small size
+ without risking a bounds check error when accessing one of its
+ components.
+ (Type_Specific_Data): Define Ancestor_Tags as a small array.
+ This prevents us from hitting a limitation during the debug info
+ generation when using stabs.
+
+ * a-tags.adb (Dispatch_Table): Define the Prims_Ptr component as a
+ small array.
+ This prevents us from hitting a limitation during the debug info
+ generation when using stabs.
+
+2004-05-03 Eric Botcazou <ebotcazou@act-europe.fr>
+
+ lang-specs.h: Remove -gnatz* from specs.
+
+2004-05-03 Vincent Celier <celier@gnat.com>
+
+ * gprmake.adb, makegpr.ads, makegpr.adb: New files.
+
+ * Make-lang.in, Makefile.in: Add gprmake
+
+2004-05-03 Thomas Quinot <quinot@act-europe.fr>
+
+ * sem_aggr.adb: Fix typo in comment.
+
+2004-05-03 Robert Dewar <dewar@gnat.com>
+
+ * make.adb: Minor reformatting
+
+ * rtsfind.ads, rtsfind.adb: (RTU_Loaded): New function
+
+ * sem_attr.adb (Eval_Attribute, case Type_Class): Fix check for address
+ so that it works when address is not a private type.
+
+ * sem_ch13.adb (Check_Expr_Constants, case N_Integer_Literal): Deal
+ properly with rewritten unchecked conversions. This prevents
+ order-of-elaboration issues that can otherwise arise.
+ (Minimum_Size): Don't check size of access types under VMS
+
+ * sem_ch4.adb (Remove_Address_Interpretation): New circuit to remove
+ interpretations of integer literals as type System.Address.
+
+ * sem_util.ads, sem_util.adb (Is_Descendent_Of_Address): New function
+ (Is_Descendent_Of): New function
+
+2004-05-03 Jose Ruiz <ruiz@act-europe.fr>
+
+ * sem_prag.adb: Boolean_Entry_Barriers is a synonym of Simple_Barriers.
+ Max_Entry_Queue_Depth is a synonym of Max_Entry_Queue_Length.
+ No_Dynamic_Interrupts is a synonym of No_Dynamic_Attachment.
+
+ * sem_res.adb: Use the new restriction Max_Entry_Queue_Length instead
+ of the old Max_Entry_Queue_Depth.
+
+ * snames.adb: Boolean_Entry_Barriers is a synonym of Simple_Barriers.
+ Max_Entry_Queue_Depth is a synonym of Max_Entry_Queue_Length
+ No_Dynamic_Interrupts is a synonym of No_Dynamic_Attachment
+
+ * snames.ads: New entry for proper handling of Boolean_Entry_Barriers.
+ New entry for proper handling of Max_Entry_Queue_Depth.
+ New entry for proper handling of No_Dynamic_Interrupts.
+
+ * s-rident.ads: Adding restriction Simple_Barriers (AI-00249) that
+ supersedes the GNAT specific restriction Boolean_Entry_Barriers.
+ Adding restriction Max_Entry_Queue_Length (AI-00249) that supersedes
+ the GNAT specific restriction Max_Entry_Queue_Depth.
+ Adding restriction No_Dynamic_Attachment (AI-00249) that supersedes
+ the GNAT specific restriction No_Dynamic_Interrupts.
+
+ * restrict.ads, restrict.adb: Use the new restriction Simple_Barriers
+ instead of the old Boolean_Entry_Barriers.
+ Use the new restriction No_Dynamic_Attachment instead of the old
+ No_Dynamic_Interrupts.
+
+ * exp_ch9.adb: Check restriction Simple_Barriers (AI-00249) that
+ supersedes the GNAT specific restriction Boolean_Entry_Barriers.
+
+ * gnatbind.adb: Use the new restriction Max_Entry_Queue_Length instead
+ of the old Max_Entry_Queue_Depth.
+
+2004-05-03 GNAT Script <nobody@gnat.com>
+
+ * Make-lang.in: Makefile automatically updated
+
+2004-04-29 Ed Schonberg <schonberg@gnat.com>
+
+ * checks.adb (Enable_Range_Check): If the prefix of an index component
+ is an access to an unconstrained array, perform check unconditionally.
+
+2004-04-29 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * decl.c (gnat_to_gnu_field): Also call make_packable_type if
+ Component_Clause.
+
+2004-04-29 Olivier Hainque <hainque@act-europe.fr>
+
+ * init.c (__gnat_install_handler, __gnat_error_handler): Remove
+ alternate stack setting. There was no support for the tasking cases
+ and the changes eventually caused a number of side-effect failures in
+ the non-tasking case too.
+
+2004-04-29 Eric Botcazou <ebotcazou@act-europe.fr>
+
+ lang-specs.h: Redirect output to /dev/null if -gnatc or -gnatz or
+ -gnats is passed.
+
+2004-04-29 Vincent Celier <celier@gnat.com>
+
+ * make.adb (Gnatmake): Increase max size of argument array for
+ gnatbind for the potential addition of -F.
+ If there are Stand-Alone Library projects, invoke gnatbind with -F to
+ be sure that elaboration flags will be checked.
+
+ * switch-c.adb: Correct call to Scan_Pos for -gnateI
+
+2004-04-29 Thomas Quinot <quinot@act-europe.fr>
+
+ * sem_warn.adb (Check_References): Move '<access-variable> may be
+ null' warning out of under Warn_On_No_Value_Assigned.
+
+2004-04-29 Ed Falis <falis@gnat.com>
+
+ * gnat_ugn.texi: Fixed texi error
+
+2004-04-29 Robert Dewar <dewar@gnat.com>
+
+ * sem_ch4.adb (Remove_Abstract_Operations): Unconditionally remove
+ abstract operations if they come from predefined files.
+
+ * gnat_rm.texi: Fix bad doc for pragma Elaboration_Checks (should be
+ Dynamic, not RM).
+
+ * s-addope.adb: Correct obvious error in mod function
+
+2004-04-28 Andrew W. Reynolds <awreynolds@mac.com>
+
+ * Makefile.in: Add target pairs for powerpc darwin*
+ tasking support.
+
+ * a-intnam-darwin.ads, s-osinte-darwin.adb,
+ s-osinte-darwin.ads, system-darwin-ppc.ads: New files.
+
+2004-04-28 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * Makefile.in: Add target macro definitions for s390*-linux*.
+ * system-linux-s390.ads: New file.
+ * system-linux-s390x.ads: New file.
+
+2004-04-28 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * gnat_ugn.texi: Correct argument to @setfilename.
+
+2004-04-28 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * a-exexpr.adb (Unwind_Word): New data type.
+ (Unwind_Exception): Use it as type of Private1 and Private2.
+
+ * raise.c (db_action_for): Fix debug printf.
+
+2004-04-27 Ed Schonberg <schonberg@gnat.com>
+
+ * a-wtmoio.ads: Formal type must be a modular type, not a signed
+ integer type.
+
+2004-04-27 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * decl.c (gnat_to_gnu_entity, case object): Call
+ __builtin_update_setjmp_buf.
+
+ * gigi.h (update_setjmp_buf): Deleted.
+ (ADT_update_setjmp_buf_decl, update_setjmp_buf_decl): New.
+
+ * misc.c: (update_setjmp_buf): Deleted.
+
+ * trans.c (gnat_to_gnu): Call do_pending_stack_adjust and emit_queue
+ around block of RTL.
+
+ * utils.c (init_gigi_decls): Initialize update_setjmp_buf.
+
+2004-04-26 Thomas Quinot <quinot@act-europe.fr>
+
+ * sem_dist.adb, exp_dist.adb: When constructing a RAS value for a local
+ subprogram for which no pragma All_Calls_Remote applies, store the
+ address of the real subprogram in the underlying record type, so local
+ dereferences do not go through the PCS.
+
+2004-04-26 Robert Dewar <dewar@gnat.com>
+
+ * i-c.ads: Add some type qualifications to avoid ambiguities when
+ compiling with s-auxdec.ads and a non-private address type.
+
+2004-04-26 Arnaud Charlet <charlet@act-europe.fr>
+
+ * Makefile.rtl: Fix error in previous check-in:
+ Add s-addope.o to non tasking object list (rather than tasking object
+ list).
+
+2004-04-26 Javier Miranda <miranda@gnat.com>
+
+ * sem_aggr.adb: Fix typo in comments
+ (Resolve_Aggr_Expr): Propagate the type to the nested aggregate.
+ Required to check the null-exclusion attribute.
+
+ * sem_attr.adb (Resolve_Attribute): Check the accessibility level in
+ case of anonymous access types in record and array components. For a
+ component definition the level is the same of the enclosing composite
+ type.
+
+ * sem_ch3.adb (Analyze_Component_Declaration): In case of components
+ that are anonymous access types the level of accessibility depends on
+ the enclosing type declaration. In order to have this information, set
+ the scope of the anonymous access type to the enclosing record type
+ declaration.
+ (Array_Type_Declaration): In case of components that are anonymous
+ access types the level of accessibility depends on the enclosing type
+ declaration. In order to have this information, set the scope of the
+ anonymous access type to the enclosing array type declaration.
+
+ * sem_ch3.adb (Array_Type_Declaration): Set the scope of the anonymous
+ access type.
+
+ * sem_ch8.adb (Analyze_Object_Renaming): Add check to verify that
+ renaming of anonymous access-to-constant types allowed if and only if
+ the renamed object is access-to-constant.
+
+ * sem_util.adb (Type_Access_Level): In case of anonymous access types
+ that are component_definition or discriminants of a nonlimited type,
+ the level is the same as that of the enclosing component type.
+
+2004-04-26 Sergey Rybin <rybin@act-europe.fr>
+
+ * sem_elim.adb: Some minor code reorganization from code reading. Fix
+ misprint in the function name (File_Name_Match).
+
+2004-04-23 Laurent GUERBY <laurent@guerby.net>
+
+ * Makefile.in: Remove RANLIB_TEST, use -$(RANLIB) including after
+ install.
+
+2004-04-23 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * Make-lang.in (GNATBIND_OBJS): Add s-addope.o.
+
+2004-04-23 Emmanuel Briot <briot@act-europe.fr>
+
+ * adaint.c (__gnat_try_lock): No longer requires that the parent
+ directory be writable, the directory itself is enough.
+ (gnat_is_absolute_path): Change profile, so that the call from
+ GNAT.OS_Lib can be made more efficient.
+
+ * adaint.h (gnat_is_absolute_path): Change profile, so that the call
+ from GNAT.OS_Lib can be made more efficient.
+
+ * g-os_lib.adb (Is_Absolute_Path): More efficient implementation, avoid
+ one copy of the file name. Found by code reading.
+
+2004-04-23 Vincent Celier <celier@gnat.com>
+
+ * gnat_ugn.texi: Add documentation for gnatmake switch -eL
+ Correct documentation on gnatmake switches transmitted to the compiler
+
+ * ali.ads: Minor comment fix
+
+2004-04-23 Javier Miranda <miranda@gnat.com>
+
+ * sem_ch6.adb: (Confirming Types): Code cleanup
+
+ * decl.c (gnat_to_gnu_entity): Give support to anonymous access to
+ subprogram types: E_Anonymous_Access_Subprogram_Type and
+ E_Anonymous_Access_Protected_Subprogram_Type.
+
+2004-04-23 Thomas Quinot <quinot@act-europe.fr>
+
+ * sem_dist.adb: Add a new paramter to the RAS_Access TSS indicating
+ whether a pragma All_Calls_Remote applies to the subprogram on which
+ 'Access is taken.
+ No functional change is introduced by this revision; the new parameter
+ will be used to allow calls to local RCI subprograms to be optimized
+ to not use the PCS in the case where no pragma All_Calls_Remote applies,
+ as is already done in the PolyORB implementation of the DSA.
+
+ * exp_dist.adb: Add a new paramter to the RAS_Access TSS indicating
+ whether a pragma All_Calls_Remote applies to the subprogram on which
+ 'Access is taken.
+ No functional change is introduced by this revision; the new parameter
+ will be used to allow calls to local RCI subprograms to be optimized
+ to not use the PCS in the case where no pragma All_Calls_Remote applies,
+ as is already done in the PolyORB implementation of the DSA.
+
+2004-04-23 Robert Dewar <dewar@gnat.com>
+
+ * Makefile.rtl: Add entry for s-addope.o in run time library list
+ * Make-lang.in: Add entry for s-addope.o to GNAT1 objects
+ * s-addope.ads, s-addope.adb: New files.
+
+ * s-carsi8.adb, s-carun8.adb, s-casi16.adb, s-casi32.adb,
+ s-casi64.adb, s-caun16.adb, s-caun32.adb, s-caun64.adb,
+ s-finimp.adb, s-geveop.adb, s-stoele.adb: Modifications to allow
+ System.Address to be non-private and signed.
+
+ * sem_elim.adb: Minor reformatting (fairly extensive)
+ Some minor code reorganization from code reading
+ Add a couple of ??? comments
+
+2004-04-23 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * trans.c (tree_transform, build_unit_elab): Don't call getdecls.
+ (tree_transform, case N_If_Statement): Remove non-determinism.
+
+ * utils.c (begin_subprog_body): Just set DECL_CONTEXT in PARM_DECL.
+
+2004-04-23 Sergey Rybin <rybin@act-europe.fr>
+
+ * gnat_rm.texi: Small fixes in the changes made in the 'pragma
+ Eliminate' section.
+
+ * snames.ads, snames.adb: Remove Name_Homonym_Number (Homonym_Number is
+ no longer used as a parameter name for Eliminate pragma).
+
+2004-04-22 Laurent GUERBY <laurent@guerby.net>
+
+ PR optimization/14984
+ PR optimization/14985
+ * trans.c (gigi): Fix non determinism leading to bootstrap
+ comparison failures.
+
+2004-04-21 Pascal Obry <obry@gnat.com>
+
+ * adaint.c (__gnat_portable_spawn): Quote first argument (argv[0])
+ passed to spawnvp() to properly handle program pathname with spaces on
+ Win32.
+
+2004-04-21 Emmanuel Briot <briot@act-europe.fr>
+
+ * g-debpoo.adb (Print_Info): Avoid extra work if Display_Slots is False.
+ (Allocate, Deallocate, Free_Physically): Make sure the tasks are
+ unlocked in case of exceptions.
+
+2004-04-21 Joel Brobecker <brobecker@gnat.com>
+
+ * gigi.h (get_target_no_dollar_in_label): Remove extern declaration.
+ This function does not exist anymore.
+
+2004-04-21 Thomas Quinot <quinot@act-europe.fr>
+
+ * gnatbind.adb, gnatlink.adb: Update name of imported C symbol.
+
+ * link.c: Move variables to the __gnat name space.
+
+ * Makefile.in: list link.o explicitly when needed.
+
+ * mlib.adb: Remove pragma Linker_Option for "link.o" from mlib.
+
+2004-04-21 Javier Miranda <miranda@gnat.com>
+
+ * einfo.adb (Original_Access_Type): New subprogram
+ (Set_Original_Access_Type): New subprogram
+ (Write_Field21_Name): Write the name of the new field
+
+ * einfo.ads (Original_Access_Type): New field present in access to
+ subprogram types.
+ Addition of two new entities: E_Anonymous_Access_Subprogram_Type, and
+ E_Anonymous_Access_Protected_Subprogram_Type.
+
+ * lib-xref.adb (Output_One_Ref): Give support to anonymous access to
+ subprogram types.
+
+ * lib-xref.ads (Xref_Entity_Letters): Initialize values corresponding
+ to anonymous access to subprogram types.
+
+ * sem_attr.adb (Resolve_Attribute): Give support to anonymous access
+ to subprogram types.
+
+ * sem_ch3.adb (Access_Definition): Complete decoration of entities
+ corresponding to anonymous access to subprogram types.
+ (Analyze_Component_Declaration): Add new actual to the call to
+ subprogram replace_anonymous_access_to_protected_subprogram.
+ (Array_Type_Declaration): Add new actual to the call to subprogram
+ replace_anonymous_access_to_protected_subprogram.
+ (Process_Discriminants): Add new actual to the call to subprogram
+ replace_anonymous_access_to_protected_subprogram.
+ (Replace_Anonymous_Access_To_Protected_Subprogram): New formal.
+
+ * sem_ch3.ads (Replace_Anonymous_Access_To_Protected_Subprogram): New
+ formal.
+
+ * sem_ch6.adb, sem_type.adb, sem_res.adb: Give support to anonymous
+ access to subprogram types.
+
+ * sem_util.adb (Has_Declarations): Addition of package_specification
+ nodes.
+
+2004-04-21 Ed Schonberg <schonberg@gnat.com>
+
+ * sem_prag.adb (Make_Inline): If subprogram is a renaming, propagate
+ inlined flags to renamed entity only if in current unit.
+
+2004-04-21 Thomas Quinot <quinot@act-europe.fr>
+
+ * s-parint.ads: Add DSA implementation marker.
+
+ * rtsfind.ads, rtsfind.adb, snames.ads, snames.adb, s-rpc.adb: Use the
+ value of System.Partition_Interface.DSA_Implementation to determine
+ what version of the distributed systems annex is available (no
+ implementation, GLADE, or PolyORB).
+
+2004-04-21 Joel Brobecker <brobecker@gnat.com>
+
+ * targtyps.c (get_target_no_dollar_in_label): Remove, no longer used.
+
+2004-04-21 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * utils.c (convert, case CONSTRUCTOR, COMPONENT_REF): Do not make node
+ with new type if alias sets differ.
+ Fixes ACATS c41103b.
+
+2004-04-21 Vincent Celier <celier@gnat.com>
+
+ * prj.ads: Remove FORTRAN as an accepted language: not tested yet.
+ Add array Lang_Args for the language specific compiling argument
+ switches.
+
+ * gnat_ugn.texi: Explain in more details when a library is rebuilt.
+
+2004-04-21 Sergey Rybin <rybin@act-europe.fr>
+
+ * gnat_rm.texi: Update the descripton of the Eliminate pragma
+ according to the recent changes in the format of the parameters of the
+ pragma (replacing Homonym_Number with Source_Location).
+
+2004-04-19 Arnaud Charlet <charlet@act-europe.fr>
+
+ * 5isystem.ads: Removed, unused.
+
+ * gnat_rm.texi: Redo 1.13 change.
+
+2004-04-19 Robert Dewar <dewar@gnat.com>
+
+ * s-stoele.ads: Clean up definition of Storage_Offset (the new
+ definition is cleaner, avoids the kludge of explicit Standard operator
+ references, and also is consistent with a visible System.Address with
+ no visible operations.
+
+ * s-geveop.adb: Add declarations to avoid assumption of visible
+ operations on type System.Address (since these might not be available
+ if Address is a non-private type for which the operations
+ are made abstract).
+
+ * sem_eval.adb: Minor reformatting
+
+ * s-carsi8.ads, s-carun8.ads, s-casi16.ads, s-casi32.ads,
+ s-casi64.ads, s-caun16.ads, s-caun32.ads, s-caun64.ads: Minor
+ reformatting (new function spec format).
+
+ * s-auxdec.adb, s-carsi8.adb, s-carun8.adb, s-casi16.adb,
+ s-casi32.adb, s-casi64.adb, s-caun16.adb, s-caun32.adb,
+ s-caun64.adb: Add declarations to avoid assumption of visible
+ operations on type System.Address (since these might not be available
+ if Address is a non-private type for which the operations are made
+ abstract).
+
+ * lib.ads, lib.adb (Synchronize_Serial_Number): New procedure.
+
+ * exp_intr.adb: Minor comment update
+
+ * exp_aggr.adb, exp_attr.adb, exp_ch13.adb: Minor reformatting.
+
+ * 5omastop.adb: Add declarations to avoid assumption of visible
+ operations on type System.Address (since these might not be available
+ if Address is a non-private type for which the operations
+ are made abstract).
+
+2004-04-19 Vincent Celier <celier@gnat.com>
+
+ * switch-m.adb: (Scan_Make_Switches): Process new switch -eL
+
+ * prj-pars.ads (Parse): New Boolean parameter Process_Languages,
+ defaulted to Ada.
+
+ * prj-proc.adb (Process): New Boolean parameter Process_Languages,
+ defaulted to Ada.
+ Call Check with Process_Languages.
+ (Check): New Boolean parameter Process_Languages. Call Recursive_Check
+ with Process_Languages.
+ (Recursive_Check): New Boolean parameter Process_Languages. Call
+ Nmsc.Ada_Check or Nmsc.Other_Languages_Check according to
+ Process_Languages.
+
+ * prj-proc.ads (Process): New Boolean parameter Process_Languages,
+
+ * prj-util.ads, prj-util.adb (Executable_Of): New Boolean
+ parameter Ada_Main, defaulted to True.
+ Check for Ada specific characteristics only when Ada_Main is True.
+
+ * opt.ads: (Follow_Links): New Boolean flag for gnatmake
+
+ * prj.adb: (Project_Empty): Add new Project_Data components.
+
+ * prj.ads: New types and tables for non Ada languages.
+ (Project_Data): New components Languages, Impl_Suffixes,
+ First_Other_Source, Last_Other_Source, Imported_Directories_Switches,
+ Include_Path, Include_Data_Set.
+
+ * prj-env.ads, prj-env.adb: Minor reformatting
+
+ * prj-nmsc.ads, prj-nmsc.adb: (Other_Languages_Check): New procedure
+ Put subprograms in alphabetical order
+
+ * prj-pars.adb (Parse): New Boolean parameter Process_Languages,
+ defaulted to Ada; Call Prj.Proc.Process with Process_Languages and
+ Opt.Follow_Links.
+
+ * mlib-prj.adb: Back out modification in last version, as they are
+ incorrect.
+ (Build_Library.Check_Libs): Remove useless pragma Warnings (Off)
+
+ * make.adb: (Mains): Moved to package Makeutl
+ (Linker_Opts): Moved to package Makeutl
+ (Is_External_Assignment): Moved to package Makeutl
+ (Test_If_Relative_Path): Moved to package Makeutl
+ (Gnatmake): Move sorting of linker options to function
+ Makeutl.Linker_Options_Switches.
+
+ * makeutl.ads, makeutl.adb: New files.
+
+ * Makefile.in: Add makeutl.o to the object files for gnatmake
+
+ * makeusg.adb: Add line for new switch -eL.
+
+ * gnatls.adb (Image): New function.
+ (Output_Unit): If in verbose mode, output the list of restrictions
+ specified by pragmas Restrictions.
+
+ * 5bml-tgt.adb, 5vml-tgt.adb (Build_Dynamic_Library): Do not use
+ Text_IO.
+
+ * a-calend.adb (Split): Shift the date by multiple of 56 years, if
+ needed, to put it in the range 1970 (included) - 2026 (excluded).
+ (Time_Of): Do not shift Unix_Min_Year (1970).
+ Shift the date by multiple of 56 years, if needed, to put it in the
+ range 1970 (included) - 2026 (excluded).
+
+ * adaint.h, adaint.c (__gnat_set_executable): New function.
+
+2004-04-19 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * trans.c (tree_transform, case N_Subprogram_Body): Temporarily push
+ and pop GC context.
+ (tree_transform, case N_Procedure_Call): Fix typo in setting TREE_TYPE.
+ (tree_transform, case N_Label): Don't set LABEL_STMT_FIRST_IN_EH.
+ (tree_transform, case N_Procedure_Call_Statement): Build a tree.
+ (tree_transform, case N_Code_Statement): Likewise.
+ (gnat_expand_stmt, case LABEL_STMT): Don't look at
+ LABEL_STMT_FIRST_IN_EH.
+ (gnat_expand_stmt, case ASM_STMT): New case.
+
+ * utils2.c (build_unary_op): Properly set TREE_READONLY of
+ UNCONSTRAINED_ARRAY_REF.
+
+ * utils.c (poplevel): Temporarily push/pop GC context around inline
+ function expansion.
+
+ * decl.c (maybe_variable): Properly set TREE_READONLY of
+ UNCONSTRAINED_ARRAY_REF.
+ (make_packable_type): Only reference TYPE_IS_PADDING_P for RECORD_TYPE.
+
+ * ada-tree.def: (ASM_STMT): New.
+
+ * ada-tree.h: (LABEL_STMT_FIRST_IN_EH): Deleted.
+ (ASM_STMT_TEMPLATE, ASM_STMT_OUTPUT, ASM_STMT_ORIG_OUT,
+ ASM_STMT_INPUT): New.
+ (ASM_STMT_CLOBBER): Likewise.
+
+2004-04-19 Thomas Quinot <quinot@act-europe.fr>
+
+ * a-except.adb, s-parint.ads, s-parint.adb, types.ads, types.h: Use
+ general rcheck mechanism to raise Program_Error for E.4(18), instead
+ of a custom raiser in System.Partition_Interface.
+ Part of general cleanup work before PolyORB integration.
+
+ * snames.ads, snames.adb: Add new runtime library entities and names
+ for PolyORB DSA.
+
+ * sem_dist.ads, sem_dist.adb (Get_Subprogram_Id): Move from sem_dist to
+ exp_dist.
+ (Build_Subprogram_Id): New subprogram provided by exp_dist
+ Code reorganisation in preparation for PolyORB integration.
+
+ * exp_dist.ads, exp_dist.adb (Get_Subprogram_Id): Move from sem_dist to
+ exp_dist.
+ (Build_Subprogram_Id): New subprogram provided by exp_dist
+
+ * sem_ch4.adb (Analyze_One_Call): Fix error message for mismatch in
+ actual parameter types for call to dereference of an
+ access-to-subprogram type.
+
+ * rtsfind.ads: Add new runtime library entities and names for PolyORB
+ DSA.
+
+ * gnatlink.adb (Value): Remove. Use Interfaces.C.Strings.Value
+ instead, which has the same behaviour here since we never pass it a
+ NULL pointer.
+
+ * link.c (run_path_option, Solaris case): Use -Wl, as for other
+ platforms.
+
+ * Makefile.in: adjust object file lists for gnatlink and gnatmake
+ to account for new dependency upon Interfaces.C.Strings + link.o
+ For x86 FreeBSD, use 86numaux.
+
+ * make.adb, gnatcmd.adb: Linker_Library_Path_Option has been moved up
+ from Mlib.Tgt to Mlib.
+
+ * mlib.ads, mlib.adb (Linker_Library_Path_Option): New subprogram, now
+ target-independent.
+
+ * mlib-tgt.ads, mlib-tgt.adb (Linker_Library_Path_Option): Remove
+ target-specific versions of this subprogram, now implemented as a
+ target-independent function in Mlib.
+
+ * 5aml-tgt.adb, 5bml-tgt.adb, 5gml-tgt.adb, 5hml-tgt.adb, 5lml-tgt.adb,
+ 5sml-tgt.adb, 5vml-tgt.adb, 5zml-tgt.adb, 5wml-tgt.adb
+ (Linker_Library_Path_Option): Remove target-specific versions of this
+ subprogram, now implemented as a target-independent function in Mlib.
+
+ * atree.adb: (Allocate_Initialize_Node): New subprogram.
+ Factors out node table slots allocation.
+ (Fix_Parents): New subprogram.
+ Encapsulate the pattern of fixing up parent pointers for syntactic
+ children of a rewritten node.
+ (New_Copy_Tree): Use New_Copy to copy non-entity nodes.
+ (Rewrite): Use New_Copy when creating saved copy of original node.
+ (Replace): Use Copy_Node to copy nodes.
+
+2004-04-19 Javier Miranda <miranda@gnat.com>
+
+ * sprint.adb (Sprint_Node_Actual): Give support to the new
+ Access_To_Subprogram node available in Access_Definition nodes. In
+ addition, give support to the AI-231 node fields: null-exclusion,
+ all-present, constant-present.
+
+ * sem_util.ads, sem_util.adb: (Has_Declarations): New subprogram
+
+ * sinfo.ads, sinfo.adb:
+ New field Access_To_Subprogram_Definition in Access_Definition nodes
+
+ * sem_ch6.adb (Process_Formals): Move here the code that creates and
+ decorates internal subtype declaration corresponding to the
+ null-excluding formal. This code was previously in Set_Actual_Subtypes.
+ In addition, carry out some code cleanup on this code. In case of
+ access to protected subprogram call
+ Replace_Anonymous_Access_To_Protected_Subprogram.
+ (Set_Actual_Subtypes): Code cleanup.
+
+ * sem_ch8.adb (Analyze_Object_Renaming): Remove un-necessary call to
+ Find_Type in case of anonymous access renamings. Add warning in case of
+ null-excluding attribute used in anonymous access renaming.
+
+ * sem_ch3.ads (Replace_Anonymous_Access_To_Protected_Subprogram): New
+ subprogram
+
+ * sem_ch3.adb (Replace_Anonymous_Access_To_Protected_Subprogram): New
+ subprogram.
+ (Access_Definition): In case of anonymous access to subprograms call
+ the corresponding semantic routine to decorate the node.
+ (Access_Subprogram_Declaration): Addition of some comments indicating
+ some code that probably should be added here. Detected by comparison
+ with the access_definition subprogram.
+ (Analyze_Component_Declaration): In case of access to protected
+ subprogram call Replace_Anonymous_Access_To_Protected.
+ (Array_Type_Declaration): In case of access to protected subprogram call
+ Replace_Anonymous_Access_To_Protected_Subprogram.
+ (Process_Discriminants): In case of access to protected subprogram call
+ Replace_Anonymous_Access_To_Protected_Subprogram.
+
+ * par.adb (P_Access_Definition): New formal that indicates if the
+ null-exclusion part was present.
+ (P_Access_Type_Definition): New formal that indicates if the caller has
+ already parsed the null-excluding part.
+
+ * par-ch3.adb (P_Subtype_Declaration): Code cleanup.
+ (P_Identifier_Declarations): Code cleanup and give support to renamings
+ of anonymous access to subprogram types.
+ (P_Derived_Type_Def_Or_Private_Ext_Decl): Code cleanup.
+ (P_Array_Type_Definition): Give support to AI-254.
+ (P_Component_Items): Give support to AI-254.
+ (P_Access_Definition): New formal that indicates if the header was
+ already parsed by the caller.
+ (P_Access_Type_Definition): New formal that indicates if the caller has
+ already parsed the null-excluding part.
+
+ * par-ch6.adb (P_Formal_Part): Add the null-excluding parameter to the
+ call to P_Access_Definition.
+
+2004-04-19 Geert Bosch <bosch@gnat.com>
+
+ * checks.adb (Apply_Float_Conversion_Check): New procedure to implement
+ the delicate semantics of floating-point to integer conversion.
+ (Apply_Type_Conversion_Checks): Use Apply_Float_Conversion_Check.
+
+ * eval_fat.adb (Machine_Mantissa): Moved to spec.
+ (Machine_Radix): New function.
+
+ * eval_fat.ads (Machine_Mantissa): Moved from body for use in
+ conversion checks.
+ (Machine_Radix): New function also for use in conversion checks.
+
+2004-04-19 Ed Schonberg <schonberg@gnat.com>
+
+ * par-prag.adb (Source_File_Name_Project): Fix typo in error message.
+
+ * exp_ch9.adb (Expand_Access_Protected_Subprogram_Type): Call analyze
+ to decorate the access-to-protected subprogram and the equivalent type.
+
+ * checks.adb (Null_Exclusion_Static_Checks): Code cleanup. Give support
+ to anonymous access to subprogram types.
+
+ * exp_ch4.adb (Expand_N_In): Preserve Static flag before
+ constant-folding, for legality checks in contexts that require an RM
+ static expression.
+
+ * exp_ch6.adb (Expand_N_Function_Call): If call may generate large
+ temporary but stack checking is not enabled, increment serial number
+ to so that symbol generation is consistent with and without stack
+ checking.
+
+ * exp_util.ads, exp_util.adb (May_Generate_Large_Temp): Predicate is
+ independent on whether stack checking is enabled, caller must check
+ the corresponding flag.
+
+ * sem_ch3.adb (Constrain_Index): Index bounds given by attributes need
+ range checks.
+ (Build_Derived_Concurrent_Type): Inherit Is_Constrained flag from
+ parent if it has discriminants.
+ (Build_Derived_Private_Type): Constructed full view does
+ not come from source.
+ (Process_Discriminants): Default discriminants on a tagged type are
+ legal if this is the internal completion of a private untagged
+ derivation.
+
+ * sem_ch6.adb (Set_Actual_Subtypes): The generated declaration needs
+ no constraint checks, because it corresponds to an existing object.
+
+ * sem_prag.adb (Process_Convention): Pragma applies
+ only to subprograms in the same declarative part, i.e. the same unit,
+ not the same scope.
+
+ * sem_res.adb (Valid_Conversion): In an instance or inlined body,
+ ignore type mismatch on a numeric conversion if expression comes from
+ expansion.
+
+2004-04-19 Sergey Rybin <rybin@act-europe.fr>
+
+ * sem_elim.adb (Process_Eliminate_Pragma): Remove the processing for
+ Homonym_Number parameter, add processing for Source_Location parameter
+ corresponding.
+ (Check_Eliminated): Remove the check for homonym numbers, add the check
+ for source location traces.
+
+ * sem_elim.ads (Process_Eliminate_Pragma): Replace Arg_Homonym_Number
+ with Arg_Source_Location corresponding to the changes in the format of
+ the pragma.
+
+ * sem_prag.adb: (Analyze_Pragma): Changes in the processing of
+ Eliminate pragma corresponding to the changes in the format of the
+ pragma: Homonym_Number is replaced with Source_Location, two ways of
+ distinguishing homonyms are mutially-exclusive.
+
+2004-04-19 Joel Brobecker <brobecker@gnat.com>
+
+ * get_targ.ads (Get_No_Dollar_In_Label): Remove.
+
+ * exp_dbug.adb (Output_Homonym_Numbers_Suffix): Remove use of
+ No_Dollar_In_Label, no longer necessary, as it is always True.
+ (Strip_Suffixes): Likewise.
+
+2004-04-19 Gary Dismukes <dismukes@gnat.com>
+
+ * s-stalib.ads (type Exception_Code): Use Integer'Size for exponent of
+ modulus for compatibility with size clause on targets with 16-bit
+ Integer.
+
+ * layout.adb (Discrimify): In the case of private types, set Vtyp to
+ full type to fix type mismatches on calls to size functions for
+ discriminant-dependent array components.
+
+2004-04-19 Jerome Guitton <guitton@act-europe.fr>
+
+ * Makefile.in (gnatlib-zcx): New target, for building a ZCX run-time
+ lib.
+
+2004-04-19 Pascal Obry <obry@gnat.com>
+
+ * mdll-utl.adb (Locate): New version is idempotent.
+
+2004-04-17 Laurent Guerby <laurent@guerby.net>
+
+ PR ada/14988 (partial)
+ * impunit.adb: Fix typo.
+
+2004-04-14 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Make-lang.in: Remove obsolete rts-none, rts-cert, install-rts-none,
+ and install-rts-cert targets. Remove all gnatlib and gnattools
+ targets and all other rts-* targets (moved to libada). Remove (now)
+ unused Make variables CHMOD, CHMOD_AX_FLAGS, shext, THREAD_KIND,
+ TRACE, GNATLIBFLAGS, GNATLIBCFLAGS.
+
2004-04-08 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* trans.c (tree_transform): Shortcut returning error_mark_node for
@@ -68,7 +1462,7 @@
duplication between normal entities and those declared as renamings.
No functional change.
- * s-fileio.ads (Form): Remove pragma Inline, as we cannot currently
+ * s-fileio.ads (Form): Remove pragma Inline, as we cannot currently
inline functions returning an unconstrained result.
2004-04-08 Eric Botcazou <ebotcazou@act-europe.fr>
@@ -679,11 +2073,11 @@
(gnat_to_gnu_entity, case E_Array_Type): Don't set and clear it.
* misc.c (LANG_HOOK_HASH_TYPE): Redefine.
-2004-03-19 Laurent GUERBY <laurent@guerby.net>
+2004-03-19 Laurent Guerby <laurent@guerby.net>
- * sem_prag.adb (Suppress_Unsuppress_Echeck): use loop instead of
+ * sem_prag.adb (Suppress_Unsuppress_Echeck): use loop instead of
aggregate, allows bootstrap from 3.3 on powerpc-darwin.
-
+
2004-03-18 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* ada-tree.h (TYPE_LEFT_JUSTIFIED_MODULAR_P): Add checking.
@@ -992,7 +2386,7 @@
* a-tags.adb, a-tags.ads, s-finimp.adb, s-finroo.ads,
i-cpoint.ads, i-cpoint.adb, i-cstrin.adb, i-cstrin.ads,
- 5iosinte.ads, 5sosinte.ads, 5staspri.ads, 5itaprop.adb,
+ 5iosinte.ads, 5sosinte.ads, 5staspri.ads, 5itaprop.adb,
5staprop.adb, 5wtaprop.adb, s-tataat.ads, s-tataat.adb: Move
unchecked conversion to spec to avoid warnings.
@@ -1510,7 +2904,7 @@
PR ada/6637, PR ada/5911
Merge with libada-branch:
- * config-lang.in: Build libada only when ada is built.
+ * config-lang.in: Build libada only when ada is built.
2004-02-09 Ed Schonberg <schonberg@gnat.com>
@@ -1661,7 +3055,7 @@
2004-02-04 Ed Schonberg <schonberg@gnat.com>
- * sem_prag.adb:
+ * sem_prag.adb:
(Analyze_Pragma, case Warnings): In an inlined body, as in an instance
body, an identifier may be wrapped in an unchecked conversion.
@@ -1862,7 +3256,7 @@
2004-01-30 Kelley Cook <kcook@gcc.gnu.org>
- * Make-lang.in (doc/gnat_ug_unx.dvi): Use $(abs_docdir).
+ * Make-lang.in (doc/gnat_ug_unx.dvi): Use $(abs_docdir).
(doc/gnat_ug_vms.dvi, doc/gnat_ug_unx.dvi): Likewise.
(doc/gnat_ug_unx.dvi, doc/gnat-style.dvi): Likewise.
@@ -1881,7 +3275,7 @@
(Wakeup): Likewise.
(Exit_Task): Use Result.
(Check_No_Locks): Mark Self_ID unreferenced.
-
+
* 5gtasinf.adb (New_Sproc): Make Attr constant.
(Bound_Thread_Attributes): Make Sproc constant.
(New_Bound_Thread_Attributes): Likewise.
diff --git a/gcc/ada/ChangeLog.tree-ssa b/gcc/ada/ChangeLog.tree-ssa
new file mode 100644
index 00000000000..73524e5492b
--- /dev/null
+++ b/gcc/ada/ChangeLog.tree-ssa
@@ -0,0 +1,29 @@
+2004-05-05 Richard Henderson <rth@redhat.com>
+
+ * utils.c (unchecked_convert): Use OEP_ONLY_CONST.
+
+2004-03-25 Diego Novillo <dnovillo@redhat.com>
+
+ * config-lang.in: Disable Ada by default.
+
+2004-02-16 Richard Henderson <rth@redhat.com>
+
+ * utils.c (max_size): Add static chain op for call_expr.
+
+2003-09-25 Jason Merrill <jason@redhat.com>
+
+ * trans.c, utils.c: Revert 2003-01-15 change.
+
+2003-01-15 Jeff Law <law@redhat.com>
+
+ * trans.c (tree_transform): Use annotate_with_file_line to add
+ file/line information to nodes.
+ (build_unit_elab): Use TREE_FILENAME and TREE_LINENO to
+ retrieve file/line information from a node.
+ * utils.c (create_label_decl): Use annotate_with_file_line to
+ add file/line information to nodes.
+
+Local Variables:
+mode: change-log
+change-log-default-name: "ChangeLog.tree-ssa"
+End:
diff --git a/gcc/ada/Make-lang.in b/gcc/ada/Make-lang.in
index ba8a7a5242f..1342a542da2 100644
--- a/gcc/ada/Make-lang.in
+++ b/gcc/ada/Make-lang.in
@@ -35,16 +35,12 @@
# - the compiler proper (eg: cc1plus)
# - define the names for selecting the language in LANGUAGES.
# tool definitions
-CHMOD = chmod
-CHMOD_AX_FLAGS = a+x
CP = cp -p
ECHO = echo
MV = mv
MKDIR = mkdir -p
RM = rm -f
RMDIR = rm -rf
-# default extensions
-shext =
# Extra flags to pass to recursive makes.
@@ -56,12 +52,8 @@ FORCE_DEBUG_ADAFLAGS = -g
ADA_CFLAGS =
ALL_ADA_CFLAGS = $(X_ADA_CFLAGS) $(T_ADA_CFLAGS) $(ADA_CFLAGS)
ADA_INCLUDES = -I- -I. -Iada -I$(srcdir)/ada
-GNATLIBFLAGS= -W -Wall -gnatpg
-GNATLIBCFLAGS= -g -O2
ADA_INCLUDE_DIR = $(libsubdir)/adainclude
ADA_RTL_OBJ_DIR = $(libsubdir)/adalib
-THREAD_KIND=native
-TRACE=no
GNATBIND = $(STAGE_PREFIX)gnatbind
ADA_FLAGS_TO_PASS = \
"ADA_FOR_BUILD=$(ADA_FOR_BUILD)" \
@@ -137,7 +129,8 @@ GNAT_ADA_OBJS = ada/ada.o ada/a-charac.o ada/a-chlat1.o ada/a-except.o \
ada/lib-util.o ada/lib-xref.o ada/lib-writ.o ada/live.o ada/namet.o \
ada/nlists.o ada/nmake.o ada/opt.o ada/osint.o ada/osint-c.o ada/output.o \
ada/par.o ada/prep.o ada/prepcomp.o ada/repinfo.o ada/restrict.o \
- ada/rident.o ada/rtsfind.o ada/s-assert.o ada/s-parame.o ada/s-stache.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-stoele.o ada/s-soflin.o ada/s-exctab.o \
ada/s-secsta.o ada/s-traent.o ada/s-wchcnv.o ada/s-wchcon.o ada/s-wchjis.o \
ada/s-unstyp.o ada/scans.o ada/scng.o ada/scn.o ada/sdefault.o ada/sem.o \
@@ -211,6 +204,7 @@ GNATBIND_OBJS = \
ada/osint.o \
ada/output.o \
ada/rident.o \
+ ada/s-addope.o \
ada/s-assert.o \
ada/s-carun8.o \
ada/s-casuti.o \
@@ -285,81 +279,12 @@ gnatbind$(exeext): ada/b_gnatb.o $(CONFIG_H) $(GNATBIND_OBJS)
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ ada/b_gnatb.o $(GNATBIND_OBJS) \
$(LIBS) $(SYSLIBS)
-# use target-gcc target-gnatmake target-gnatbind target-gnatlink
-gnattools: $(GCC_PARTS) $(CONFIG_H) prefix.o force
- $(MAKE) -C ada $(FLAGS_TO_PASS) $(ADA_FLAGS_TO_PASS) \
- ADA_INCLUDES="-I- -I../rts"\
- CC="../../xgcc -B../../" STAGE_PREFIX=../../ gnattools1
- $(MAKE) -C ada $(ADA_TOOLS_FLAGS_TO_PASS) gnattools2
- $(MAKE) -C ada $(ADA_TOOLS_FLAGS_TO_PASS) gnattools3
-
-regnattools:
- $(MAKE) -C ada $(ADA_TOOLS_FLAGS_TO_PASS) gnattools1-re
- $(MAKE) -C ada $(ADA_TOOLS_FLAGS_TO_PASS) gnattools2
- $(MAKE) -C ada $(ADA_TOOLS_FLAGS_TO_PASS) gnattools3
-
-# use host-gcc host-gnatmake host-gnatbind host-gnatlink
-# put the host RTS dir first in the PATH to hide the default runtime
-# files that are among the sources
-RTS_DIR:=$(strip $(subst \,/,$(shell gnatls -v | grep adalib )))
-cross-gnattools: force
- $(MAKE) -C ada $(FLAGS_TO_PASS) $(ADA_FLAGS_TO_PASS)\
- ADA_INCLUDES="-I$(RTS_DIR)../adainclude -I$(RTS_DIR)" \
- GNATMAKE="gnatmake" \
- GNATBIND="gnatbind" \
- GNATLINK="gnatlink" \
- LIBGNAT="" \
- gnattools1-re gnattools2 gnattools4
-
-rts-zfp: force
- $(MAKE) -C ada $(FLAGS_TO_PASS) GNATMAKE=../gnatmake-cross rts-zfp
-
install-rts-zfp: force
$(MAKE) -C ada $(FLAGS_TO_PASS) install-rts RTS_NAME=zfp
-rts-none: force
- $(MAKE) -C ada $(FLAGS_TO_PASS) GNATMAKE=../gnatmake-cross rts-none
-
-install-rts-none: force
- $(MAKE) -C ada $(FLAGS_TO_PASS) install-rts RTS_NAME=none
-
-rts-ravenscar: force
- $(MAKE) -C ada $(FLAGS_TO_PASS) GNATMAKE=../gnatmake-cross rts-ravenscar
-
install-rts-ravenscar: force
$(MAKE) -C ada $(FLAGS_TO_PASS) install-rts RTS_NAME=ravenscar
-gnatlib: force
- $(MAKE) -C ada $(FLAGS_TO_PASS) \
- GNATLIBFLAGS="$(GNATLIBFLAGS)" \
- GNATLIBCFLAGS="$(GNATLIBCFLAGS)" \
- TARGET_LIBGCC2_CFLAGS="$(TARGET_LIBGCC2_CFLAGS)" \
- THREAD_KIND="$(THREAD_KIND)" \
- TRACE="$(TRACE)" \
- gnatlib
-
-gnatlib-sjlj: force
- $(MAKE) -C ada $(FLAGS_TO_PASS) \
- GNATLIBFLAGS="$(GNATLIBFLAGS)" \
- GNATLIBCFLAGS="$(GNATLIBCFLAGS)" \
- TARGET_LIBGCC2_CFLAGS="$(TARGET_LIBGCC2_CFLAGS)" \
- THREAD_KIND="$(THREAD_KIND)" \
- TRACE="$(TRACE)" \
- gnatlib-sjlj
-
-gnatlib-shared: force
- $(MAKE) -C ada $(FLAGS_TO_PASS) \
- GNATLIBFLAGS="$(GNATLIBFLAGS)" \
- GNATLIBCFLAGS="$(GNATLIBCFLAGS)" \
- GNATLIBLDFLAGS="$(GNATLIBLDFLAGS)" \
- TARGET_LIBGCC2_CFLAGS="$(TARGET_LIBGCC2_CFLAGS)" \
- THREAD_KIND="$(THREAD_KIND)" \
- TRACE="$(TRACE)" \
- gnatlib-shared
-
-# use only for native compiler
-gnatlib_and_tools: gnatlib gnattools
-
# use cross-gcc
gnat-cross: force
make $(GNAT1_ADA_OBJS) CC="gcc -B../stage1/" CFLAGS="-S -gnatp" \
@@ -430,6 +355,10 @@ ada.all.cross:
then \
$(MV) gnatsym$(exeext) gnatsym-cross$(exeext); \
fi
+ -if [ -f gprmake$(exeext) ] ; \
+ then \
+ $(MV) gprmake$(exeext) gprmake-cross$(exeext); \
+ fi
-if [ -f gpr2make$(exeext) ] ; \
then \
$(MV) gpr2make$(exeext) gpr2make-cross$(exeext); \
@@ -439,8 +368,8 @@ ada.all.cross:
$(MV) gprcmd$(exeext) gprcmd-cross$(exeext); \
fi
-ada.start.encap:
-ada.rest.encap:
+ada.start.encap:
+ada.rest.encap:
ada.man:
ada.srcextra:
ada.srcman:
@@ -520,7 +449,7 @@ ada.install-normal:
# and also as either gnatbind (if native) or $(tooldir)/bin/gnatbind
# likewise for gnatf, gnatchop, and gnatlink, gnatkr, gnatmake, gnat,
# gnatprep, gnatbl, gnatls, gnatxref, gnatfind, gnatname, gnatclean,
-# gnatsym
+# gnatsym, gprmake, gpr2make, gprcmd
ada.install-common:
$(MKDIR) $(DESTDIR)$(bindir)
-if [ -f gnat1$(exeext) ] ; \
@@ -715,6 +644,17 @@ ada.install-common:
fi
-if [ -f gnat1$(exeext) ] ; \
then \
+ if [ -f gprmake-cross$(exeext) ] ; \
+ then \
+ $(RM) $(DESTDIR)$(bindir)/$(target_noncanonical)-gprmake$(exeext); \
+ $(INSTALL_PROGRAM) gprmake-cross$(exeext) $(DESTDIR)$(bindir)/$(target_noncanonical)-gprmake$(exeext); \
+ else \
+ $(RM) $(bindir)/gprmake$(exeext); \
+ $(INSTALL_PROGRAM) gprmake$(exeext) $(DESTDIR)$(bindir)/gprmake$(exeext); \
+ fi ; \
+ fi
+ -if [ -f gnat1$(exeext) ] ; \
+ then \
if [ -f gpr2make$(exeext) ] ; \
then \
$(RM) $(DESTDIR)$(bindir)/gpr2make$(exeext); \
@@ -786,16 +726,6 @@ install-gnatlib:
install-gnatlib-obj:
$(MAKE) -C ada $(FLAGS_TO_PASS) $(ADA_FLAGS_TO_PASS) install-gnatlib-obj
-
-rts-cert: force
- $(MAKE) -C ada $(FLAGS_TO_PASS) \
- GNATLIBCFLAGS="$(GNATLIBCFLAGS)" \
- TARGET_LIBGCC2_CFLAGS="$(TARGET_LIBGCC2_CFLAGS)" \
- GNATMAKE=../gnatmake-cross rts-cert RTS_NAME=cert
-
-install-rts-cert: force
- $(MAKE) -C ada $(FLAGS_TO_PASS) install-rts RTS_NAME=none
-
ada.install-man:
ada.uninstall:
@@ -880,6 +810,8 @@ ada.distclean:
-$(RM) gnatxref$(exeext)
-$(RM) gnatclean$(exeext)
-$(RM) gnatsym$(exeext)
+ -$(RM) gpr2make$(exeext)
+ -$(RM) gprmake$(exeext)
# Gnatlbr is only used on VMS
-$(RM) gnatlbr$(exeext)
-$(RM) ada/rts/*
@@ -1096,44 +1028,44 @@ ada/mdll-fil.o : ada/mdll-fil.adb ada/mdll.ads ada/mdll-fil.ads
ada/mdll-utl.o : ada/mdll-utl.adb ada/mdll.ads ada/mdll-utl.ads ada/sdefault.ads ada/types.ads
$(CC) -c $(ALL_ADAFLAGS) $(ADA_INCLUDES) $< $(OUTPUT_OPTION)
-# force debugging information and no optimization on s-memory.o so that it
+# force debugging information and no optimization on s-memory.o so that it
# is always possible to set breakpoint on __gnat_malloc and __gnat_free
# this is important for gnatmem using GDB. memtrack.o is built from
# memtrack.adb, and used by the post-mortem analysis with gnatmem.
ada/s-memory.o : ada/s-memory.adb ada/s-memory.ads ada/memtrack.o
$(CC) -c $(ALL_ADAFLAGS) $(FORCE_DEBUG_ADAFLAGS) -O0 \
- $(ADA_INCLUDES) $< $(OUTPUT_OPTION)
+ $(ADA_INCLUDES) $< $(OUTPUT_OPTION)
ada/memtrack.o : ada/memtrack.adb ada/s-memory.ads
$(CC) -c $(ALL_ADAFLAGS) $(FORCE_DEBUG_ADAFLAGS) -O0 \
- $(ADA_INCLUDES) $< $(OUTPUT_OPTION)
+ $(ADA_INCLUDES) $< $(OUTPUT_OPTION)
ada/adadecode.o : ada/adadecode.c $(CONFIG_H) $(SYSTEM_H) ada/adadecode.h
ada/adaint.o : ada/adaint.c $(CONFIG_H) $(SYSTEM_H) ada/adaint.h
ada/argv.o : ada/argv.c $(CONFIG_H) $(SYSTEM_H) ada/adaint.h
ada/cstreams.o : ada/cstreams.c $(CONFIG_H) $(SYSTEM_H) ada/adaint.h
ada/exit.o : ada/exit.c $(CONFIG_H) $(SYSTEM_H) ada/adaint.h
-ada/final.o : ada/final.c $(CONFIG_H) $(SYSTEM_H) ada/raise.h
+ada/final.o : ada/final.c $(CONFIG_H) $(SYSTEM_H) ada/raise.h
ada/link.o : ada/link.c
ada/cio.o : ada/cio.c $(CONFIG_H) $(SYSTEM_H) ada/adaint.h
$(CC) -c $(ALL_CFLAGS) $(ALL_ADA_CFLAGS) $(RT_FLAGS) \
- $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
+ $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
ada/init.o : ada/init.c $(CONFIG_H) $(SYSTEM_H) ada/adaint.h ada/raise.h
$(CC) -c $(ALL_CFLAGS) $(ALL_ADA_CFLAGS) $(RT_FLAGS) \
- $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
+ $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
ada/raise.o : ada/raise.c $(CONFIG_H) $(SYSTEM_H) ada/adaint.h ada/raise.h
$(CC) -c $(ALL_CFLAGS) $(ALL_ADA_CFLAGS) $(RT_FLAGS) \
- $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
+ $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
# Need to keep the frame pointer in this file to pop the stack properly on
# some targets.
ada/tracebak.o : ada/tracebak.c $(CONFIG_H) $(SYSTEM_H)
$(CC) -c $(ALL_CFLAGS) $(ALL_ADA_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
- -fno-omit-frame-pointer $< $(OUTPUT_OPTION)
+ -fno-omit-frame-pointer $< $(OUTPUT_OPTION)
ada/cuintp.o : ada/cuintp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) ada/ada.h ada/types.h ada/uintp.h ada/atree.h ada/stringt.h \
@@ -1366,7 +1298,8 @@ ada/checks.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/atree.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/uintp.ads ada/uintp.adb ada/uname.ads \
- ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/validsw.ads
+ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/urealp.adb \
+ ada/validsw.ads
ada/comperr.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/comperr.ads ada/comperr.adb \
@@ -1649,65 +1582,66 @@ ada/exp_ch2.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/atree.ads \
ada/exp_ch3.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/checks.ads ada/checks.adb \
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_ch11.ads ada/exp_ch2.ads ada/exp_ch3.ads ada/exp_ch3.adb \
- ada/exp_ch4.ads ada/exp_ch7.ads ada/exp_ch9.ads ada/exp_disp.ads \
- ada/exp_dist.ads ada/exp_smem.ads ada/exp_strm.ads ada/exp_tss.ads \
- ada/exp_tss.adb ada/exp_util.ads ada/fname.ads ada/fname-uf.ads \
- ada/freeze.ads ada/get_targ.ads ada/gnat.ads ada/g-htable.ads \
- ada/g-os_lib.ads ada/g-string.ads ada/gnatvsn.ads ada/hostparm.ads \
- ada/lib.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/restrict.adb ada/rident.ads ada/rtsfind.ads ada/sem.ads \
- ada/sem_ch3.ads ada/sem_ch8.ads ada/sem_eval.ads ada/sem_mech.ads \
- ada/sem_res.ads ada/sem_util.ads ada/sem_warn.ads ada/sinfo.ads \
- ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/sprint.ads \
- ada/stand.ads ada/stringt.ads ada/stringt.adb ada/system.ads \
- ada/s-exctab.ads ada/s-htable.ads ada/s-imgenu.ads ada/s-memory.ads \
- ada/s-rident.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-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/uintp.ads ada/uintp.adb ada/uname.ads \
- ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/validsw.ads
+ ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/eval_fat.ads \
+ ada/exp_aggr.ads ada/exp_ch11.ads ada/exp_ch2.ads ada/exp_ch3.ads \
+ ada/exp_ch3.adb ada/exp_ch4.ads ada/exp_ch7.ads ada/exp_ch9.ads \
+ ada/exp_disp.ads ada/exp_dist.ads ada/exp_smem.ads ada/exp_strm.ads \
+ ada/exp_tss.ads ada/exp_tss.adb ada/exp_util.ads ada/fname.ads \
+ ada/fname-uf.ads ada/freeze.ads ada/get_targ.ads ada/gnat.ads \
+ ada/g-htable.ads ada/g-os_lib.ads ada/g-string.ads ada/gnatvsn.ads \
+ ada/hostparm.ads ada/lib.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/restrict.adb ada/rident.ads ada/rtsfind.ads \
+ ada/sem.ads ada/sem_ch3.ads ada/sem_ch8.ads ada/sem_eval.ads \
+ ada/sem_mech.ads ada/sem_res.ads ada/sem_util.ads ada/sem_warn.ads \
+ ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads \
+ ada/sprint.ads ada/stand.ads ada/stringt.ads ada/stringt.adb \
+ ada/system.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imgenu.ads \
+ ada/s-memory.ads ada/s-rident.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-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/uintp.ads \
+ ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \
+ ada/urealp.ads ada/validsw.ads
ada/exp_ch4.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/checks.ads ada/checks.adb \
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_ch11.ads ada/exp_ch2.ads ada/exp_ch3.ads ada/exp_ch4.ads \
- ada/exp_ch4.adb ada/exp_ch7.ads ada/exp_ch9.ads ada/exp_disp.ads \
- ada/exp_fixd.ads ada/exp_pakd.ads ada/exp_tss.ads ada/exp_util.ads \
- ada/exp_util.adb ada/exp_vfpt.ads ada/freeze.ads ada/get_targ.ads \
- ada/gnat.ads ada/g-htable.ads ada/g-os_lib.ads ada/g-string.ads \
- ada/gnatvsn.ads ada/hostparm.ads ada/inline.ads ada/itypes.ads \
- ada/lib.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/err_vars.ads ada/errout.ads ada/erroutc.ads ada/eval_fat.ads \
+ ada/exp_aggr.ads ada/exp_ch11.ads ada/exp_ch2.ads ada/exp_ch3.ads \
+ ada/exp_ch4.ads ada/exp_ch4.adb ada/exp_ch7.ads ada/exp_ch9.ads \
+ ada/exp_disp.ads ada/exp_fixd.ads ada/exp_pakd.ads ada/exp_tss.ads \
+ ada/exp_util.ads ada/exp_util.adb ada/exp_vfpt.ads ada/freeze.ads \
+ ada/get_targ.ads ada/gnat.ads ada/g-htable.ads ada/g-os_lib.ads \
+ ada/g-string.ads ada/gnatvsn.ads ada/hostparm.ads ada/inline.ads \
+ ada/itypes.ads ada/lib.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/sem.ads ada/sem_cat.ads \
- ada/sem_ch13.ads ada/sem_ch8.ads ada/sem_eval.ads ada/sem_res.ads \
- ada/sem_type.ads ada/sem_util.ads ada/sem_warn.ads ada/sinfo.ads \
- ada/sinfo.adb ada/sinfo-cn.ads ada/sinput.ads ada/snames.ads \
- ada/sprint.ads ada/stand.ads ada/stringt.ads ada/system.ads \
- ada/s-exctab.ads ada/s-htable.ads ada/s-imgenu.ads ada/s-memory.ads \
- ada/s-rident.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-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/uintp.ads ada/uintp.adb \
- ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/urealp.adb \
- ada/validsw.ads
+ ada/sem_ch13.ads ada/sem_ch8.ads ada/sem_eval.ads ada/sem_eval.adb \
+ ada/sem_res.ads ada/sem_type.ads ada/sem_util.ads ada/sem_warn.ads \
+ ada/sinfo.ads ada/sinfo.adb ada/sinfo-cn.ads ada/sinput.ads \
+ ada/snames.ads ada/sprint.ads ada/stand.ads ada/stringt.ads \
+ ada/stringt.adb ada/system.ads ada/s-exctab.ads ada/s-htable.ads \
+ ada/s-imgenu.ads ada/s-memory.ads ada/s-rident.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-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/uintp.ads ada/uintp.adb ada/unchconv.ads ada/unchdeal.ads \
+ ada/urealp.ads ada/urealp.adb ada/validsw.ads
ada/exp_ch5.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/checks.ads ada/checks.adb \
ada/csets.ads ada/debug.ads ada/einfo.ads ada/einfo.adb ada/elists.ads \
- ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/exp_aggr.ads \
- ada/exp_ch11.ads ada/exp_ch2.ads ada/exp_ch5.ads ada/exp_ch5.adb \
- ada/exp_ch7.ads ada/exp_dbug.ads ada/exp_pakd.ads ada/exp_tss.ads \
- ada/exp_util.ads ada/exp_util.adb ada/fname.ads ada/fname-uf.ads \
- ada/freeze.ads ada/get_targ.ads ada/gnat.ads ada/g-htable.ads \
- ada/g-os_lib.ads ada/g-string.ads ada/gnatvsn.ads ada/hostparm.ads \
- ada/inline.ads ada/interfac.ads ada/itypes.ads ada/lib.ads \
- ada/lib-xref.ads ada/namet.ads ada/namet.adb ada/nlists.ads \
+ ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/eval_fat.ads \
+ ada/exp_aggr.ads ada/exp_ch11.ads ada/exp_ch2.ads ada/exp_ch5.ads \
+ ada/exp_ch5.adb ada/exp_ch7.ads ada/exp_dbug.ads ada/exp_pakd.ads \
+ ada/exp_tss.ads ada/exp_util.ads ada/exp_util.adb ada/fname.ads \
+ ada/fname-uf.ads ada/freeze.ads ada/get_targ.ads ada/gnat.ads \
+ ada/g-htable.ads ada/g-os_lib.ads ada/g-string.ads ada/gnatvsn.ads \
+ ada/hostparm.ads ada/inline.ads ada/interfac.ads ada/itypes.ads \
+ ada/lib.ads ada/lib-xref.ads ada/namet.ads ada/namet.adb ada/nlists.ads \
ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads \
ada/restrict.ads ada/restrict.adb ada/rident.ads ada/rtsfind.ads \
ada/scans.ads ada/scn.ads ada/scng.ads ada/scng.adb ada/sem.ads \
@@ -1730,31 +1664,31 @@ ada/exp_ch6.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/checks.ads ada/checks.adb \
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_ch11.ads ada/exp_ch2.ads ada/exp_ch3.ads ada/exp_ch6.ads \
- ada/exp_ch6.adb ada/exp_ch7.ads ada/exp_ch9.ads ada/exp_dbug.ads \
- ada/exp_disp.ads ada/exp_dist.ads ada/exp_intr.ads ada/exp_pakd.ads \
- ada/exp_tss.ads ada/exp_util.ads ada/exp_util.adb ada/fname.ads \
- ada/fname-uf.ads ada/freeze.ads ada/get_targ.ads ada/gnat.ads \
- ada/g-hesora.ads ada/g-htable.ads ada/g-os_lib.ads ada/g-string.ads \
- ada/gnatvsn.ads ada/hostparm.ads ada/inline.ads ada/interfac.ads \
- ada/itypes.ads ada/lib.ads ada/lib.adb ada/lib-list.adb \
- ada/lib-sort.adb ada/lib-xref.ads ada/namet.ads ada/namet.adb \
- ada/nlists.ads ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads \
- ada/output.ads ada/restrict.ads ada/restrict.adb ada/rident.ads \
- ada/rtsfind.ads ada/scans.ads ada/scn.ads ada/scng.ads ada/scng.adb \
- ada/sem.ads ada/sem_ch12.ads ada/sem_ch13.ads ada/sem_ch6.ads \
- ada/sem_ch8.ads ada/sem_disp.ads ada/sem_dist.ads ada/sem_eval.ads \
- ada/sem_res.ads ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb \
- ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \
- ada/snames.ads ada/sprint.ads ada/stand.ads ada/stringt.ads \
- ada/style.ads ada/styleg.ads ada/styleg.adb ada/styleg-c.ads \
- ada/stylesw.ads ada/system.ads ada/s-crc32.ads ada/s-exctab.ads \
- ada/s-htable.ads ada/s-imgenu.ads ada/s-memory.ads ada/s-rident.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-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/uintp.ads ada/uintp.adb ada/uname.ads \
+ ada/eval_fat.ads ada/exp_ch11.ads ada/exp_ch2.ads ada/exp_ch3.ads \
+ ada/exp_ch6.ads ada/exp_ch6.adb ada/exp_ch7.ads ada/exp_ch9.ads \
+ ada/exp_dbug.ads ada/exp_disp.ads ada/exp_dist.ads ada/exp_intr.ads \
+ ada/exp_pakd.ads ada/exp_tss.ads ada/exp_util.ads ada/exp_util.adb \
+ ada/fname.ads ada/fname-uf.ads ada/freeze.ads ada/get_targ.ads \
+ ada/gnat.ads ada/g-hesora.ads ada/g-htable.ads ada/g-os_lib.ads \
+ ada/g-string.ads ada/gnatvsn.ads ada/hostparm.ads ada/inline.ads \
+ ada/interfac.ads ada/itypes.ads ada/lib.ads ada/lib.adb \
+ ada/lib-list.adb ada/lib-sort.adb ada/lib-xref.ads ada/namet.ads \
+ ada/namet.adb ada/nlists.ads ada/nlists.adb ada/nmake.ads ada/nmake.adb \
+ ada/opt.ads ada/output.ads ada/restrict.ads ada/restrict.adb \
+ ada/rident.ads ada/rtsfind.ads ada/scans.ads ada/scn.ads ada/scng.ads \
+ ada/scng.adb ada/sem.ads ada/sem_ch12.ads ada/sem_ch13.ads \
+ ada/sem_ch6.ads ada/sem_ch8.ads ada/sem_disp.ads ada/sem_dist.ads \
+ ada/sem_eval.ads ada/sem_res.ads ada/sem_type.ads ada/sem_util.ads \
+ ada/sem_util.adb ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb \
+ ada/sinput.ads ada/snames.ads ada/sprint.ads ada/stand.ads \
+ ada/stringt.ads ada/style.ads ada/styleg.ads ada/styleg.adb \
+ ada/styleg-c.ads ada/stylesw.ads ada/system.ads ada/s-crc32.ads \
+ ada/s-exctab.ads ada/s-htable.ads ada/s-imgenu.ads ada/s-memory.ads \
+ ada/s-rident.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-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/uintp.ads ada/uintp.adb ada/uname.ads \
ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/validsw.ads \
ada/widechar.ads
@@ -1764,10 +1698,9 @@ ada/exp_ch7.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/atree.ads \
ada/erroutc.ads ada/exp_ch11.ads ada/exp_ch7.ads ada/exp_ch7.adb \
ada/exp_ch9.ads ada/exp_dbug.ads ada/exp_tss.ads ada/exp_util.ads \
ada/exp_util.adb ada/fname.ads ada/fname-uf.ads ada/freeze.ads \
- ada/get_targ.ads ada/gnat.ads ada/g-hesora.ads ada/g-htable.ads \
- ada/g-os_lib.ads ada/g-string.ads ada/gnatvsn.ads ada/hostparm.ads \
- ada/inline.ads ada/itypes.ads ada/lib.ads ada/lib.adb ada/lib-list.adb \
- ada/lib-sort.adb ada/namet.ads ada/nlists.ads ada/nlists.adb \
+ ada/get_targ.ads ada/gnat.ads ada/g-htable.ads ada/g-os_lib.ads \
+ ada/g-string.ads ada/gnatvsn.ads ada/hostparm.ads ada/inline.ads \
+ ada/itypes.ads ada/lib.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/restrict.adb ada/rident.ads ada/rtsfind.ads ada/sem.ads \
ada/sem_ch3.ads ada/sem_ch7.ads ada/sem_ch8.ads ada/sem_eval.ads \
@@ -1991,25 +1924,26 @@ ada/exp_intr.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/atree.ads \
ada/exp_pakd.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/checks.ads ada/checks.adb \
ada/debug.ads ada/einfo.ads ada/einfo.adb ada/elists.ads \
- ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/exp_ch11.ads \
- ada/exp_ch2.ads ada/exp_ch7.ads ada/exp_dbug.ads ada/exp_pakd.ads \
- ada/exp_pakd.adb ada/exp_tss.ads ada/exp_util.ads ada/exp_util.adb \
- ada/freeze.ads ada/get_targ.ads ada/gnat.ads ada/g-htable.ads \
- ada/g-os_lib.ads ada/g-string.ads ada/gnatvsn.ads ada/hostparm.ads \
- ada/inline.ads ada/itypes.ads ada/lib.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/sem.ads \
- ada/sem_ch13.ads ada/sem_ch3.ads ada/sem_ch8.ads ada/sem_eval.ads \
- ada/sem_res.ads ada/sem_util.ads ada/sem_warn.ads ada/sinfo.ads \
- ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/sprint.ads \
- ada/stand.ads ada/stringt.ads ada/system.ads ada/s-exctab.ads \
- ada/s-htable.ads ada/s-imgenu.ads ada/s-memory.ads ada/s-rident.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-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/uintp.ads ada/uintp.adb ada/unchconv.ads \
- ada/unchdeal.ads ada/urealp.ads ada/validsw.ads
+ ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/eval_fat.ads \
+ ada/exp_ch11.ads ada/exp_ch2.ads ada/exp_ch7.ads ada/exp_dbug.ads \
+ ada/exp_pakd.ads ada/exp_pakd.adb ada/exp_tss.ads ada/exp_util.ads \
+ ada/exp_util.adb ada/freeze.ads ada/get_targ.ads ada/gnat.ads \
+ ada/g-htable.ads ada/g-os_lib.ads ada/g-string.ads ada/gnatvsn.ads \
+ ada/hostparm.ads ada/inline.ads ada/itypes.ads ada/lib.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/sem.ads ada/sem_ch13.ads ada/sem_ch3.ads \
+ ada/sem_ch8.ads ada/sem_eval.ads ada/sem_res.ads ada/sem_util.ads \
+ ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \
+ ada/snames.ads ada/sprint.ads ada/stand.ads ada/stringt.ads \
+ ada/system.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imgenu.ads \
+ ada/s-memory.ads ada/s-rident.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-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/uintp.ads \
+ ada/uintp.adb ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads \
+ ada/validsw.ads
ada/exp_prag.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/casing.adb ada/csets.ads ada/debug.ads \
@@ -2394,10 +2328,10 @@ ada/lib-load.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/atree.ads \
ada/s-htable.ads ada/s-imgenu.ads ada/s-memory.ads ada/s-rident.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-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/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-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/widechar.ads
ada/lib-util.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/debug.ads \
ada/gnat.ads ada/g-os_lib.ads ada/g-string.ads ada/gnatvsn.ads \
@@ -2676,12 +2610,16 @@ ada/rtsfind.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/atree.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-addope.o : ada/system.ads ada/s-addope.ads ada/s-addope.adb \
+ ada/unchconv.ads
+
ada/s-assert.o : ada/ada.ads ada/a-except.ads ada/system.ads \
ada/s-assert.ads ada/s-assert.adb ada/s-exctab.ads ada/s-exctab.adb \
ada/s-htable.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \
ada/s-stoele.ads ada/s-stoele.adb ada/s-traent.ads ada/unchconv.ads
-ada/s-carun8.o : ada/system.ads ada/s-carun8.ads ada/s-carun8.adb \
+ada/s-carun8.o : ada/system.ads ada/s-addope.ads ada/s-addope.adb \
+ ada/s-carun8.ads ada/s-carun8.adb ada/s-stoele.ads ada/s-stoele.adb \
ada/unchconv.ads
ada/s-casuti.o : ada/system.ads ada/s-casuti.ads ada/s-casuti.adb
@@ -3014,10 +2952,10 @@ ada/sem_ch13.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/atree.ads \
ada/s-imgenu.ads ada/s-memory.ads ada/s-rident.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-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/ttypes.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/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/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \
+ ada/unchdeal.ads ada/urealp.ads ada/urealp.adb
ada/sem_ch2.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/debug.ads ada/einfo.ads ada/elists.ads \
@@ -3074,9 +3012,10 @@ ada/sem_ch4.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/atree.ads \
ada/debug_a.ads ada/einfo.ads ada/einfo.adb ada/elists.ads \
ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/exp_ch7.ads \
ada/exp_tss.ads ada/exp_util.ads ada/expander.ads ada/fname.ads \
- ada/freeze.ads ada/get_targ.ads ada/gnat.ads ada/g-htable.ads \
- ada/g-os_lib.ads ada/g-speche.ads ada/g-string.ads ada/gnatvsn.ads \
- ada/hostparm.ads ada/interfac.ads ada/itypes.ads ada/lib.ads \
+ ada/freeze.ads ada/get_targ.ads ada/gnat.ads ada/g-hesora.ads \
+ ada/g-htable.ads ada/g-os_lib.ads ada/g-speche.ads ada/g-string.ads \
+ ada/gnatvsn.ads ada/hostparm.ads ada/interfac.ads ada/itypes.ads \
+ ada/lib.ads ada/lib.adb ada/lib-list.adb ada/lib-sort.adb \
ada/lib-xref.ads ada/namet.ads ada/namet.adb 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/scans.ads \
@@ -3094,8 +3033,8 @@ ada/sem_ch4.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/atree.ads \
ada/s-stoele.ads ada/s-stoele.adb 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/tree_io.ads ada/ttypes.ads ada/types.ads \
- ada/uintp.ads ada/uintp.adb ada/unchconv.ads ada/unchdeal.ads \
- ada/urealp.ads ada/widechar.ads
+ ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \
+ ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
ada/sem_ch5.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/checks.ads ada/checks.adb \
@@ -3217,31 +3156,32 @@ ada/sem_ch9.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/checks.ads ada/checks.adb \
ada/csets.ads ada/debug.ads ada/debug_a.ads ada/einfo.ads ada/einfo.adb \
ada/elists.ads ada/err_vars.ads ada/errout.ads ada/erroutc.ads \
- ada/exp_ch2.ads ada/exp_ch7.ads ada/exp_ch9.ads ada/exp_tss.ads \
- ada/exp_util.ads ada/expander.ads ada/fname.ads ada/fname-uf.ads \
- ada/freeze.ads ada/get_targ.ads ada/gnat.ads ada/g-htable.ads \
- ada/g-os_lib.ads ada/g-string.ads ada/gnatvsn.ads ada/hostparm.ads \
- ada/interfac.ads ada/itypes.ads ada/lib.ads ada/lib-xref.ads \
- ada/namet.ads ada/namet.adb ada/nlists.ads ada/nlists.adb ada/nmake.ads \
- ada/nmake.adb ada/opt.ads ada/output.ads ada/restrict.ads \
- ada/restrict.adb ada/rident.ads ada/rtsfind.ads ada/scans.ads \
- ada/scn.ads ada/scng.ads ada/scng.adb ada/sem.ads ada/sem_aggr.ads \
- ada/sem_attr.ads ada/sem_cat.ads ada/sem_ch3.ads ada/sem_ch4.ads \
- ada/sem_ch5.ads ada/sem_ch6.ads ada/sem_ch8.ads ada/sem_ch9.ads \
- ada/sem_ch9.adb ada/sem_disp.ads ada/sem_dist.ads ada/sem_elab.ads \
- ada/sem_eval.ads ada/sem_intr.ads ada/sem_res.ads ada/sem_res.adb \
- ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads \
- ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/sinput.adb \
- ada/snames.ads ada/sprint.ads ada/stand.ads ada/stringt.ads \
- ada/style.ads ada/styleg.ads ada/styleg.adb ada/styleg-c.ads \
- ada/stylesw.ads ada/system.ads ada/s-crc32.ads ada/s-exctab.ads \
- ada/s-htable.ads ada/s-imgenu.ads ada/s-memory.ads ada/s-rident.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-traent.ads ada/s-unstyp.ads \
- ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \
- ada/tbuild.ads ada/tree_io.ads ada/ttypes.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/widechar.ads
+ ada/eval_fat.ads ada/exp_ch2.ads ada/exp_ch7.ads ada/exp_ch9.ads \
+ ada/exp_tss.ads ada/exp_util.ads ada/expander.ads ada/fname.ads \
+ ada/fname-uf.ads ada/freeze.ads ada/get_targ.ads ada/gnat.ads \
+ ada/g-htable.ads ada/g-os_lib.ads ada/g-string.ads ada/gnatvsn.ads \
+ ada/hostparm.ads ada/interfac.ads ada/itypes.ads ada/lib.ads \
+ ada/lib-xref.ads ada/namet.ads ada/namet.adb ada/nlists.ads \
+ ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads \
+ ada/restrict.ads ada/restrict.adb ada/rident.ads ada/rtsfind.ads \
+ ada/scans.ads ada/scn.ads ada/scng.ads ada/scng.adb ada/sem.ads \
+ ada/sem_aggr.ads ada/sem_attr.ads ada/sem_cat.ads ada/sem_ch3.ads \
+ ada/sem_ch4.ads ada/sem_ch5.ads ada/sem_ch6.ads ada/sem_ch8.ads \
+ ada/sem_ch9.ads ada/sem_ch9.adb ada/sem_disp.ads ada/sem_dist.ads \
+ ada/sem_elab.ads ada/sem_eval.ads ada/sem_intr.ads ada/sem_res.ads \
+ ada/sem_res.adb ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb \
+ ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \
+ ada/sinput.adb ada/snames.ads ada/sprint.ads ada/stand.ads \
+ ada/stringt.ads ada/style.ads ada/styleg.ads ada/styleg.adb \
+ ada/styleg-c.ads ada/stylesw.ads ada/system.ads ada/s-crc32.ads \
+ ada/s-exctab.ads ada/s-htable.ads ada/s-imgenu.ads ada/s-memory.ads \
+ ada/s-rident.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-traent.ads \
+ ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \
+ ada/targparm.ads ada/tbuild.ads ada/tree_io.ads ada/ttypes.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/widechar.ads
ada/sem_disp.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/checks.ads ada/csets.ads ada/debug.ads \
@@ -3320,14 +3260,15 @@ ada/sem_elim.o : ada/ada.ads ada/a-except.ads ada/a-uncdea.ads \
ada/errout.ads ada/erroutc.ads ada/gnat.ads ada/g-htable.ads \
ada/g-os_lib.ads ada/g-string.ads ada/gnatvsn.ads ada/hostparm.ads \
ada/namet.ads ada/nlists.ads ada/nlists.adb ada/opt.ads ada/output.ads \
- ada/sem_elim.ads ada/sem_elim.adb 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-htable.adb \
- ada/s-imgenu.ads ada/s-memory.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-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/sem_elim.ads ada/sem_elim.adb ada/sem_prag.ads ada/sinfo.ads \
+ ada/sinfo.adb ada/sinput.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-htable.adb ada/s-imgenu.ads ada/s-memory.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-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/sem_eval.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/checks.ads ada/csets.ads ada/debug.ads \
@@ -3516,14 +3457,15 @@ ada/sem_util.o : ada/ada.ads ada/a-except.ads ada/alloc.ads ada/atree.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/eval_fat.ads ada/exp_tss.ads ada/exp_util.ads ada/fname.ads \
- ada/freeze.ads ada/get_targ.ads ada/gnat.ads ada/g-hesora.ads \
- ada/g-htable.ads ada/g-os_lib.ads ada/g-string.ads ada/gnatvsn.ads \
- ada/hostparm.ads ada/interfac.ads ada/lib.ads ada/lib.adb \
- ada/lib-list.adb ada/lib-sort.adb ada/lib-xref.ads ada/namet.ads \
- ada/namet.adb 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/scans.ads ada/scn.ads ada/scng.ads ada/scng.adb \
- ada/sem.ads ada/sem_cat.ads ada/sem_ch8.ads ada/sem_eval.ads \
+ ada/fname-uf.ads ada/freeze.ads ada/get_targ.ads ada/gnat.ads \
+ ada/g-hesora.ads ada/g-htable.ads ada/g-os_lib.ads ada/g-string.ads \
+ ada/gnatvsn.ads ada/hostparm.ads ada/interfac.ads ada/lib.ads \
+ ada/lib.adb ada/lib-list.adb ada/lib-load.ads ada/lib-sort.adb \
+ ada/lib-xref.ads ada/namet.ads ada/namet.adb 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/scans.ads ada/scn.ads ada/scng.ads ada/scng.adb ada/sem.ads \
+ ada/sem_cat.ads ada/sem_ch7.ads ada/sem_ch8.ads ada/sem_eval.ads \
ada/sem_eval.adb ada/sem_res.ads ada/sem_type.ads ada/sem_util.ads \
ada/sem_util.adb ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb \
ada/sinput.ads ada/sinput.adb ada/snames.ads ada/stand.ads \
diff --git a/gcc/ada/Makefile.in b/gcc/ada/Makefile.in
index 072c9e8f7d6..a094a82830e 100644
--- a/gcc/ada/Makefile.in
+++ b/gcc/ada/Makefile.in
@@ -105,10 +105,7 @@ MKDIR = mkdir -p
AR = ar
AR_FLAGS = rc
LS = ls
-# How to invoke ranlib.
-RANLIB = ranlib
-# Test to use to see whether ranlib exists on the system.
-RANLIB_TEST = [ -f /usr/bin/ranlib -o -f /bin/ranlib ]
+RANLIB = @RANLIB@
SHELL = @SHELL@
PWD_COMMAND = $${PWDCMD-pwd}
@@ -251,7 +248,7 @@ LIBIBERTY = ../../libiberty/libiberty.a
# and the system's installed libraries.
LIBS = $(LIBINTL) $(LIBIBERTY) $(SYSLIBS)
LIBDEPS = $(LIBINTL_DEP) $(LIBIBERTY)
-TOOLS_LIBS = $(LIBGNAT) $(EXTRA_GNATTOOLS_OBJS) ../../../libiberty/libiberty.a $(SYSLIBS)
+TOOLS_LIBS = $(LIBGNAT) $(EXTRA_GNATTOOLS_OBJS) link.o ../../../libiberty/libiberty.a $(SYSLIBS)
# Specify the directories to be searched for header files.
# Both . and srcdir are used, in that order,
@@ -299,22 +296,24 @@ Makefile: ../config.status $(srcdir)/Makefile.in $(srcdir)/../version.c
# Lists of files for various purposes.
-GNATLINK_OBJS = gnatlink.o link.o \
- ali.o alloc.o butil.o casing.o csets.o debug.o fmap.o fname.o gnatvsn.o \
- hostparm.o namet.o opt.o osint.o output.o rident.o sdefault.o \
- stylesw.o switch.o table.o tree_io.o types.o validsw.o widechar.o
+GNATLINK_OBJS = gnatlink.o \
+ a-except.o ali.o alloc.o butil.o casing.o csets.o debug.o fmap.o fname.o gnatvsn.o \
+ hostparm.o interfac.o i-c.o i-cstrin.o namet.o opt.o osint.o output.o rident.o \
+ s-exctab.o s-secsta.o s-stalib.o s-stoele.o sdefault.o stylesw.o switch.o system.o \
+ table.o tree_io.o types.o validsw.o widechar.o
-GNATMAKE_OBJS = ctrl_c.o ali.o ali-util.o s-casuti.o \
+GNATMAKE_OBJS = a-except.o ctrl_c.o ali.o ali-util.o s-casuti.o \
alloc.o atree.o binderr.o butil.o casing.o csets.o debug.o elists.o einfo.o\
erroutc.o errutil.o err_vars.o fmap.o fname.o fname-uf.o fname-sf.o \
- gnatmake.o gnatvsn.o hostparm.o krunch.o lib.o make.o makeusg.o \
- mlib.o mlib-fil.o mlib-prj.o mlib-tgt.o mlib-utl.o \
+ gnatmake.o gnatvsn.o hostparm.o interfac.o i-c.o i-cstrin.o krunch.o lib.o \
+ make.o makeusg.o makeutl.o mlib.o mlib-fil.o mlib-prj.o mlib-tgt.o mlib-utl.o \
namet.o nlists.o opt.o osint.o osint-m.o output.o \
prj.o prj-attr.o prj-com.o prj-dect.o prj-env.o prj-err.o prj-ext.o prj-nmsc.o \
prj-pars.o prj-part.o prj-proc.o prj-strt.o prj-tree.o prj-util.o \
- rident.o scans.o scng.o sdefault.o sfn_scan.o s-purexc.o s-htable.o \
+ rident.o s-exctab.o s-secsta.o s-stalib.o s-stoele.o \
+ scans.o scng.o sdefault.o sfn_scan.o s-purexc.o s-htable.o \
sinfo.o sinput.o sinput-c.o sinput-p.o \
- snames.o stand.o stringt.o styleg.o stylesw.o validsw.o switch.o switch-m.o \
+ snames.o stand.o stringt.o styleg.o stylesw.o system.o validsw.o switch.o switch-m.o \
table.o targparm.o tempdir.o tree_io.o types.o \
uintp.o uname.o urealp.o usage.o widechar.o \
$(EXTRA_GNATMAKE_OBJS)
@@ -342,13 +341,13 @@ endif
# Non-tasking case:
LIBGNAT_TARGET_PAIRS = \
-a-intnam.ads<4nintnam.ads \
-s-inmaop.adb<5ninmaop.adb \
-s-intman.adb<5nintman.adb \
-s-osinte.ads<5nosinte.ads \
-s-osprim.adb<7sosprim.adb \
-s-taprop.adb<5ntaprop.adb \
-s-taspri.ads<5ntaspri.ads
+a-intnam.ads<a-intnam-dummy.ads \
+s-inmaop.adb<s-inmaop-dummy.adb \
+s-intman.adb<s-intman-dummy.adb \
+s-osinte.ads<s-osinte-dummy.ads \
+s-osprim.adb<s-osprim-posix.adb \
+s-taprop.adb<s-taprop-dummy.adb \
+s-taspri.ads<s-taspri-dummy.ads
# Default shared object option. Note that we rely on the fact that the "soname"
# option will always be present and last in this flag, so that we can have
@@ -385,21 +384,21 @@ LIB_VERSION = $(strip $(shell grep ' Library_Version :' $(fsrcpfx)gnatvsn.ads |
ifeq ($(strip $(filter-out %86 os2 OS2 os2_emx,$(arch) $(osys))),)
LIBGNAT_TARGET_PAIRS = \
- a-excpol.adb<4wexcpol.adb \
- a-intnam.ads<4nintnam.ads \
- a-numaux.adb<86numaux.adb \
- a-numaux.ads<86numaux.ads \
- s-inmaop.adb<5ninmaop.adb \
- s-interr.adb<5ointerr.adb \
- s-intman.adb<5nintman.adb \
- s-mastop.adb<5omastop.adb \
- s-osinte.adb<5oosinte.adb \
- s-osinte.ads<5oosinte.ads \
- s-osprim.adb<5oosprim.adb \
- s-parame.adb<5oparame.adb \
- system.ads<5osystem.ads \
- s-taprop.adb<5otaprop.adb \
- s-taspri.ads<5otaspri.ads
+ a-excpol.adb<a-excpol-abort.adb \
+ a-intnam.ads<a-intnam-dummy.ads \
+ a-numaux.adb<a-numaux-x86.adb \
+ a-numaux.ads<a-numaux-x86.ads \
+ s-inmaop.adb<s-inmaop-dummy.adb \
+ s-interr.adb<s-interr-dummy.adb \
+ s-intman.adb<s-intman-dummy.adb \
+ s-mastop.adb<s-mastop-x86.adb \
+ s-osinte.adb<s-osinte-os2.adb \
+ s-osinte.ads<s-osinte-os2.ads \
+ s-osprim.adb<s-osprim-os2.adb \
+ s-parame.adb<s-parame-os2.adb \
+ system.ads<system-os2.ads \
+ s-taprop.adb<s-taprop-os2.adb \
+ s-taspri.ads<s-taspri-os2.ads
EXTRA_GNATRTL_NONTASKING_OBJS = \
i-os2err.o \
@@ -410,21 +409,21 @@ endif
ifeq ($(strip $(filter-out %86 interix%,$(arch) $(osys))),)
LIBGNAT_TARGET_PAIRS = \
- a-excpol.adb<4hexcpol.adb \
- a-intnam.ads<4pintnam.ads \
- a-numaux.adb<86numaux.adb \
- a-numaux.ads<86numaux.ads \
- g-soccon.ads<3psoccon.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-intman.adb<7sintman.adb \
- s-mastop.adb<5omastop.adb \
- s-osinte.adb<7sosinte.adb \
- s-osinte.ads<5posinte.ads \
- s-osprim.adb<5posprim.adb \
- s-taprop.adb<7staprop.adb \
- system.ads<5psystem.ads \
- s-taspri.ads<7staspri.ads \
- s-tpopsp.adb<7stpopsp.adb
+ a-excpol.adb<a-excpol-interix.adb \
+ a-intnam.ads<a-intnam-interix.ads \
+ a-numaux.adb<a-numaux-x86.adb \
+ a-numaux.ads<a-numaux-x86.ads \
+ g-soccon.ads<g-soccon-interix.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-posix.adb \
+ s-mastop.adb<s-mastop-x86.adb \
+ s-osinte.adb<s-osinte-fsu.adb \
+ s-osinte.ads<s-osinte-interix.ads \
+ s-osprim.adb<s-osprim-unix.adb \
+ s-taprop.adb<s-taprop-posix.adb \
+ system.ads<system-interix.ads \
+ s-taspri.ads<s-taspri-posix.ads \
+ s-tpopsp.adb<s-tpopsp-posix.adb
THREADSLIB = -lgthreads -lmalloc
PREFIX_OBJS=$(PREFIX_REAL_OBJS)
@@ -433,22 +432,22 @@ endif
# sysv5uw is SCO UnixWare 7
ifeq ($(strip $(filter-out %86 sysv5uw%,$(arch) $(osys))),)
LIBGNAT_TARGET_PAIRS = \
- a-excpol.adb<4wexcpol.adb \
- a-intnam.ads<41intnam.ads \
- a-numaux.adb<86numaux.adb \
- a-numaux.ads<86numaux.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-intman.adb<7sintman.adb \
- s-mastop.adb<5omastop.adb \
- s-osinte.ads<51osinte.ads \
- s-osinte.adb<51osinte.adb \
- s-osprim.adb<5posprim.adb \
- s-taprop.adb<7staprop.adb \
- s-taspri.ads<7staspri.ads \
- s-tpopsp.adb<5atpopsp.adb \
- system.ads<51system.ads \
- g-soccon.ads<31soccon.ads \
- g-soliop.ads<31soliop.ads
+ a-excpol.adb<a-excpol-abort.adb \
+ a-intnam.ads<a-intnam-unixware.ads \
+ a-numaux.adb<a-numaux-x86.adb \
+ a-numaux.ads<a-numaux-x86.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-posix.adb \
+ s-mastop.adb<s-mastop-x86.adb \
+ s-osinte.ads<s-osinte-unixware.ads \
+ s-osinte.adb<s-osinte-unixware.adb \
+ s-osprim.adb<s-osprim-unix.adb \
+ s-taprop.adb<s-taprop-posix.adb \
+ s-taspri.ads<s-taspri-posix.ads \
+ s-tpopsp.adb<s-tpopsp-posix-foreign.adb \
+ system.ads<system-unixware.ads \
+ g-soccon.ads<g-soccon-unixware.ads \
+ g-soliop.ads<g-soliop-unixware.ads
THREADSLIB = -lthread
PREFIX_OBJS=$(PREFIX_REAL_OBJS)
@@ -459,27 +458,27 @@ endif
ifeq ($(strip $(filter-out alpha% dec vx%,$(targ))),)
LIBGNAT_TARGET_PAIRS = \
- a-sytaco.ads<4zsytaco.ads \
- a-sytaco.adb<4zsytaco.adb \
- a-intnam.ads<4zintnam.ads \
- a-numaux.ads<4znumaux.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-interr.adb<5zinterr.adb \
- s-intman.ads<5zintman.ads \
- s-intman.adb<5zintman.adb \
- s-osinte.adb<5zosinte.adb \
- s-osinte.ads<5zosinte.ads \
- s-osprim.adb<5zosprim.adb \
- s-parame.ads<5zparame.ads \
- s-stchop.adb<5zstchop.adb \
- s-taprop.adb<5ztaprop.adb \
- s-tpopsp.adb<5ztpopsp.adb \
- s-taspri.ads<5ztaspri.ads \
- s-vxwork.ads<5avxwork.ads \
- g-soccon.ads<3zsoccon.ads \
- g-socthi.ads<3zsocthi.ads \
- g-socthi.adb<3zsocthi.adb \
- system.ads<5zsystem.ads
+ a-sytaco.ads<a-sytaco-vxworks.ads \
+ a-sytaco.adb<a-sytaco-vxworks.adb \
+ a-intnam.ads<a-intnam-vxworks.ads \
+ a-numaux.ads<a-numaux-vxworks.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-interr.adb<s-interr-vxworks.adb \
+ s-intman.ads<s-intman-vxworks.ads \
+ s-intman.adb<s-intman-vxworks.adb \
+ s-osinte.adb<s-osinte-vxworks.adb \
+ s-osinte.ads<s-osinte-vxworks.ads \
+ s-osprim.adb<s-osprim-vxworks.adb \
+ s-parame.ads<s-parame-vxworks.ads \
+ s-stchop.adb<s-stchop-vxworks.adb \
+ s-taprop.adb<s-taprop-vxworks.adb \
+ s-tpopsp.adb<s-tpopsp-vxworks.adb \
+ s-taspri.ads<s-taspri-vxworks.ads \
+ s-vxwork.ads<s-vxwork-alpha.ads \
+ g-soccon.ads<g-soccon-vxworks.ads \
+ g-socthi.ads<g-socthi-vxworks.ads \
+ g-socthi.adb<g-socthi-vxworks.adb \
+ system.ads<system-vxworks-alpha.ads
EXTRA_GNATRTL_NONTASKING_OBJS=i-vxwork.o i-vxwoio.o
EXTRA_GNATRTL_TASKING_OBJS=s-vxwork.o
@@ -487,155 +486,104 @@ endif
ifeq ($(strip $(filter-out m68k% wrs vx%,$(targ))),)
LIBGNAT_TARGET_PAIRS = \
- a-sytaco.ads<4zsytaco.ads \
- a-sytaco.adb<4zsytaco.adb \
- a-intnam.ads<4zintnam.ads \
- a-numaux.ads<4znumaux.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-interr.adb<5zinterr.adb \
- s-intman.ads<5zintman.ads \
- s-intman.adb<5zintman.adb \
- s-osinte.adb<5zosinte.adb \
- s-osinte.ads<5zosinte.ads \
- s-osprim.adb<5zosprim.adb \
- s-parame.ads<5zparame.ads \
- s-stchop.adb<5zstchop.adb \
- s-taprop.adb<5ztaprop.adb \
- s-taspri.ads<5ztaspri.ads \
- s-tpopsp.adb<5ztpopsp.adb \
- s-vxwork.ads<5kvxwork.ads \
- g-soccon.ads<3zsoccon.ads \
- g-socthi.ads<3zsocthi.ads \
- g-socthi.adb<3zsocthi.adb \
- system.ads<5ksystem.ads
-
- TOOLS_TARGET_PAIRS=mlib-tgt.adb<5zml-tgt.adb
+ a-sytaco.ads<a-sytaco-vxworks.ads \
+ a-sytaco.adb<a-sytaco-vxworks.adb \
+ a-intnam.ads<a-intnam-vxworks.ads \
+ a-numaux.ads<a-numaux-vxworks.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-interr.adb<s-interr-vxworks.adb \
+ s-intman.ads<s-intman-vxworks.ads \
+ s-intman.adb<s-intman-vxworks.adb \
+ s-osinte.adb<s-osinte-vxworks.adb \
+ s-osinte.ads<s-osinte-vxworks.ads \
+ s-osprim.adb<s-osprim-vxworks.adb \
+ s-parame.ads<s-parame-vxworks.ads \
+ s-stchop.adb<s-stchop-vxworks.adb \
+ s-taprop.adb<s-taprop-vxworks.adb \
+ s-taspri.ads<s-taspri-vxworks.ads \
+ s-tpopsp.adb<s-tpopsp-vxworks.adb \
+ s-vxwork.ads<s-vxwork-m68k.ads \
+ g-soccon.ads<g-soccon-vxworks.ads \
+ g-socthi.ads<g-socthi-vxworks.ads \
+ g-socthi.adb<g-socthi-vxworks.adb \
+ system.ads<system-vxworks-m68k.ads
+
+ TOOLS_TARGET_PAIRS=mlib-tgt.adb<mlib-tgt-vxworks.adb
EXTRA_GNATRTL_NONTASKING_OBJS=i-vxwork.o i-vxwoio.o
EXTRA_GNATRTL_TASKING_OBJS=s-vxwork.o
ifeq ($(strip $(filter-out yes,$(TRACE))),)
LIBGNAT_TARGET_PAIRS += \
- s-traces.adb<7straces.adb \
- s-tratas.adb<7stratas.adb \
- s-trafor.adb<7strafor.adb \
- s-trafor.ads<7strafor.ads \
- s-tfsetr.adb<5ztfsetr.adb
+ s-traces.adb<s-traces-default.adb \
+ s-tratas.adb<s-tratas-default.adb \
+ s-trafor.adb<s-trafor-default.adb \
+ s-trafor.ads<s-trafor-default.ads \
+ s-tfsetr.adb<s-tfsetr-vxworks.adb
endif
endif
ifeq ($(strip $(filter-out powerpc% wrs vxworks,$(targ))),)
LIBGNAT_TARGET_PAIRS = \
- a-sytaco.ads<4zsytaco.ads \
- a-sytaco.adb<4zsytaco.adb \
- a-intnam.ads<4zintnam.ads \
- a-numaux.ads<4znumaux.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-interr.adb<5zinterr.adb \
- s-intman.ads<5zintman.ads \
- s-intman.adb<5zintman.adb \
- s-osinte.adb<5zosinte.adb \
- s-osinte.ads<5zosinte.ads \
- s-osprim.adb<5zosprim.adb \
- s-parame.ads<5zparame.ads \
- s-stchop.adb<5zstchop.adb \
- s-taprop.adb<5ztaprop.adb \
- s-taspri.ads<5ztaspri.ads \
- s-tpopsp.adb<5ztpopsp.adb \
- s-vxwork.ads<5pvxwork.ads \
- g-soccon.ads<3zsoccon.ads \
- g-socthi.ads<3zsocthi.ads \
- g-socthi.adb<3zsocthi.adb \
- system.ads<5ysystem.ads
-
- TOOLS_TARGET_PAIRS=mlib-tgt.adb<5zml-tgt.adb
-
- EXTRA_HIE_NONE_TARGET_PAIRS= \
- system.ads<50system.ads
-
- EXTRA_RAVEN_SOURCES=i-vxwork.ads s-vxwork.ads
- EXTRA_RAVEN_OBJS=i-vxwork.o s-vxwork.o
- EXTRA_GNATRTL_NONTASKING_OBJS=i-vxwork.o i-vxwoio.o
- EXTRA_GNATRTL_TASKING_OBJS=s-vxwork.o
- HIE_RAVEN_TARGET_PAIRS=\
- $(HIE_NONE_TARGET_PAIRS) \
- a-reatim.ads<1areatim.ads \
- a-reatim.adb<1areatim.adb \
- a-retide.adb<1aretide.adb \
- a-interr.adb<1ainterr.adb \
- s-interr.ads<1sinterr.ads \
- s-interr.adb<1sinterr.adb \
- s-taskin.ads<1staskin.ads \
- s-taskin.adb<1staskin.adb \
- s-taspri.ads<1staspri.ads \
- s-tarest.adb<1starest.adb \
- s-tposen.ads<1stposen.ads \
- s-tposen.adb<1stposen.adb \
- s-osinte.adb<1sosinte.adb \
- s-taprop.ads<1staprop.ads \
- s-taprop.adb<1staprop.adb \
- s-taprob.ads<1staprob.ads \
- s-taprob.adb<1staprob.adb \
- a-sytaco.ads<1asytaco.ads \
- a-sytaco.adb<1asytaco.adb \
- a-intnam.ads<4zintnam.ads \
- s-osinte.ads<5zosinte.ads \
- s-parame.ads<5zparame.ads \
- s-taspri.ads<5ztaspri.ads \
- s-vxwork.ads<5pvxwork.ads \
- a-taside.adb<1ataside.adb \
+ a-sytaco.ads<a-sytaco-vxworks.ads \
+ a-sytaco.adb<a-sytaco-vxworks.adb \
+ a-intnam.ads<a-intnam-vxworks.ads \
+ a-numaux.ads<a-numaux-vxworks.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-interr.adb<s-interr-vxworks.adb \
+ s-intman.ads<s-intman-vxworks.ads \
+ s-intman.adb<s-intman-vxworks.adb \
+ s-osinte.adb<s-osinte-vxworks.adb \
+ s-osinte.ads<s-osinte-vxworks.ads \
+ s-osprim.adb<s-osprim-vxworks.adb \
+ s-parame.ads<s-parame-vxworks.ads \
+ s-stchop.adb<s-stchop-vxworks.adb \
+ s-taprop.adb<s-taprop-vxworks.adb \
+ s-taspri.ads<s-taspri-vxworks.ads \
+ s-tpopsp.adb<s-tpopsp-vxworks.adb \
+ s-vxwork.ads<s-vxwork-ppc.ads \
+ g-soccon.ads<g-soccon-vxworks.ads \
+ g-socthi.ads<g-socthi-vxworks.ads \
+ g-socthi.adb<g-socthi-vxworks.adb \
+ system.ads<system-vxworks-ppc.ads
+
+ TOOLS_TARGET_PAIRS=mlib-tgt.adb<mlib-tgt-vxworks.adb
ifeq ($(strip $(filter-out yes,$(TRACE))),)
LIBGNAT_TARGET_PAIRS += \
- s-traces.adb<7straces.adb \
- s-trafor.adb<7strafor.adb \
- s-trafor.ads<7strafor.ads \
- s-tratas.adb<7stratas.adb \
- s-tfsetr.adb<5ztfsetr.adb
+ s-traces.adb<s-traces-default.adb \
+ s-trafor.adb<s-trafor-default.adb \
+ s-trafor.ads<s-trafor-default.ads \
+ s-tratas.adb<s-tratas-default.adb \
+ s-tfsetr.adb<s-tfsetr-vxworks.adb
endif
endif
-ifeq ($(strip $(filter-out powerpc% unknown elf,$(targ))),)
- EXTRA_HIE_NONE_TARGET_PAIRS= \
- system.ads<59system.ads
-
- LIBGNAT_TARGET_PAIRS = \
- $(HIE_NONE_TARGET_PAIRS)
-endif
-
-ifeq ($(strip $(filter-out sparc% unknown elf,$(targ))),)
- EXTRA_HIE_NONE_TARGET_PAIRS= \
- system.ads<5rsystem.ads
-
- LIBGNAT_TARGET_PAIRS = \
- $(HIE_NONE_TARGET_PAIRS)
-endif
-
ifeq ($(strip $(filter-out sparc% wrs vx%,$(targ))),)
LIBGNAT_TARGET_PAIRS = \
- a-sytaco.ads<4zsytaco.ads \
- a-sytaco.adb<4zsytaco.adb \
- a-intnam.ads<4zintnam.ads \
- a-numaux.ads<4znumaux.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-interr.adb<5zinterr.adb \
- s-intman.ads<5zintman.ads \
- s-intman.adb<5zintman.adb \
- s-osinte.adb<5zosinte.adb \
- s-osinte.ads<5zosinte.ads \
- s-osprim.adb<5zosprim.adb \
- s-parame.ads<5zparame.ads \
- s-stchop.adb<5zstchop.adb \
- s-taprop.adb<5ztaprop.adb \
- s-taspri.ads<5ztaspri.ads \
- s-tpopsp.adb<5ztpopsp.adb \
- s-vxwork.ads<5svxwork.ads \
- g-soccon.ads<3zsoccon.ads \
- g-socthi.ads<3zsocthi.ads \
- g-socthi.adb<3zsocthi.adb \
- system.ads<5csystem.ads \
-
- TOOLS_TARGET_PAIRS=mlib-tgt.adb<5zml-tgt.adb
+ a-sytaco.ads<a-sytaco-vxworks.ads \
+ a-sytaco.adb<a-sytaco-vxworks.adb \
+ a-intnam.ads<a-intnam-vxworks.ads \
+ a-numaux.ads<a-numaux-vxworks.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-interr.adb<s-interr-vxworks.adb \
+ s-intman.ads<s-intman-vxworks.ads \
+ s-intman.adb<s-intman-vxworks.adb \
+ s-osinte.adb<s-osinte-vxworks.adb \
+ s-osinte.ads<s-osinte-vxworks.ads \
+ s-osprim.adb<s-osprim-vxworks.adb \
+ s-parame.ads<s-parame-vxworks.ads \
+ s-stchop.adb<s-stchop-vxworks.adb \
+ s-taprop.adb<s-taprop-vxworks.adb \
+ s-taspri.ads<s-taspri-vxworks.ads \
+ s-tpopsp.adb<s-tpopsp-vxworks.adb \
+ s-vxwork.ads<s-vxwork-sparcv9.ads \
+ g-soccon.ads<g-soccon-vxworks.ads \
+ g-socthi.ads<g-socthi-vxworks.ads \
+ g-socthi.adb<g-socthi-vxworks.adb \
+ system.ads<system-vxworks-sparcv9.ads \
+
+ TOOLS_TARGET_PAIRS=mlib-tgt.adb<mlib-tgt-vxworks.adb
EXTRA_GNATRTL_NONTASKING_OBJS=i-vxwork.o i-vxwoio.o
EXTRA_GNATRTL_TASKING_OBJS=s-vxwork.o
@@ -643,29 +591,29 @@ endif
ifeq ($(strip $(filter-out xscale% coff wrs vx%,$(targ))),)
LIBGNAT_TARGET_PAIRS = \
- a-sytaco.ads<4zsytaco.ads \
- a-sytaco.adb<4zsytaco.adb \
- a-intnam.ads<4zintnam.ads \
- a-numaux.ads<4znumaux.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-interr.adb<5zinterr.adb \
- s-intman.ads<5zintman.ads \
- s-intman.adb<5zintman.adb \
- s-osinte.adb<5zosinte.adb \
- s-osinte.ads<5zosinte.ads \
- s-osprim.adb<5zosprim.adb \
- s-parame.ads<5zparame.ads \
- s-stchop.adb<5zstchop.adb \
- s-taprop.adb<5ztaprop.adb \
- s-taspri.ads<5ztaspri.ads \
- s-tpopsp.adb<5ztpopsp.adb \
- s-vxwork.ads<5xvxwork.ads \
- g-soccon.ads<3zsoccon.ads \
- g-socthi.ads<3zsocthi.ads \
- g-socthi.adb<3zsocthi.adb \
- system.ads<5rsystem.ads
-
- TOOLS_TARGET_PAIRS=mlib-tgt.adb<5zml-tgt.adb
+ a-sytaco.ads<a-sytaco-vxworks.ads \
+ a-sytaco.adb<a-sytaco-vxworks.adb \
+ a-intnam.ads<a-intnam-vxworks.ads \
+ a-numaux.ads<a-numaux-vxworks.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-interr.adb<s-interr-vxworks.adb \
+ s-intman.ads<s-intman-vxworks.ads \
+ s-intman.adb<s-intman-vxworks.adb \
+ s-osinte.adb<s-osinte-vxworks.adb \
+ s-osinte.ads<s-osinte-vxworks.ads \
+ s-osprim.adb<s-osprim-vxworks.adb \
+ s-parame.ads<s-parame-vxworks.ads \
+ s-stchop.adb<s-stchop-vxworks.adb \
+ s-taprop.adb<s-taprop-vxworks.adb \
+ s-taspri.ads<s-taspri-vxworks.ads \
+ s-tpopsp.adb<s-tpopsp-vxworks.adb \
+ s-vxwork.ads<s-vxwork-xscale.ads \
+ g-soccon.ads<g-soccon-vxworks.ads \
+ g-socthi.ads<g-socthi-vxworks.ads \
+ g-socthi.adb<g-socthi-vxworks.adb \
+ system.ads<system-elf-sparc.ads
+
+ TOOLS_TARGET_PAIRS=mlib-tgt.adb<mlib-tgt-vxworks.adb
EXTRA_GNATRTL_NONTASKING_OBJS=i-vxwork.o i-vxwoio.o
EXTRA_GNATRTL_TASKING_OBJS=s-vxwork.o
@@ -673,29 +621,29 @@ endif
ifeq ($(strip $(filter-out mips% wrs vx%,$(targ))),)
LIBGNAT_TARGET_PAIRS = \
- a-sytaco.ads<4zsytaco.ads \
- a-sytaco.adb<4zsytaco.adb \
- a-intnam.ads<4zintnam.ads \
- a-numaux.ads<4znumaux.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-interr.adb<5zinterr.adb \
- s-intman.ads<5zintman.ads \
- s-intman.adb<5zintman.adb \
- s-osinte.adb<5zosinte.adb \
- s-osinte.ads<5zosinte.ads \
- s-osprim.adb<5zosprim.adb \
- s-parame.ads<5zparame.ads \
- s-stchop.adb<5zstchop.adb \
- s-taprop.adb<5ztaprop.adb \
- s-taspri.ads<5ztaspri.ads \
- s-tpopsp.adb<5ztpopsp.adb \
- s-vxwork.ads<5mvxwork.ads \
- g-soccon.ads<3zsoccon.ads \
- g-socthi.ads<3zsocthi.ads \
- g-socthi.adb<3zsocthi.adb \
- system.ads<5msystem.ads
-
- TOOLS_TARGET_PAIRS=mlib-tgt.adb<5zml-tgt.adb
+ a-sytaco.ads<a-sytaco-vxworks.ads \
+ a-sytaco.adb<a-sytaco-vxworks.adb \
+ a-intnam.ads<a-intnam-vxworks.ads \
+ a-numaux.ads<a-numaux-vxworks.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-interr.adb<s-interr-vxworks.adb \
+ s-intman.ads<s-intman-vxworks.ads \
+ s-intman.adb<s-intman-vxworks.adb \
+ s-osinte.adb<s-osinte-vxworks.adb \
+ s-osinte.ads<s-osinte-vxworks.ads \
+ s-osprim.adb<s-osprim-vxworks.adb \
+ s-parame.ads<s-parame-vxworks.ads \
+ s-stchop.adb<s-stchop-vxworks.adb \
+ s-taprop.adb<s-taprop-vxworks.adb \
+ s-taspri.ads<s-taspri-vxworks.ads \
+ s-tpopsp.adb<s-tpopsp-vxworks.adb \
+ s-vxwork.ads<s-vxwork-mips.ads \
+ g-soccon.ads<g-soccon-vxworks.ads \
+ g-socthi.ads<g-socthi-vxworks.ads \
+ g-socthi.adb<g-socthi-vxworks.adb \
+ system.ads<system-vxworks-mips.ads
+
+ TOOLS_TARGET_PAIRS=mlib-tgt.adb<mlib-tgt-vxworks.adb
EXTRA_GNATRTL_NONTASKING_OBJS=i-vxwork.o i-vxwoio.o
EXTRA_GNATRTL_TASKING_OBJS=s-vxwork.o
@@ -703,23 +651,23 @@ endif
ifeq ($(strip $(filter-out sparc sun solaris%,$(targ))),)
LIBGNAT_TARGET_PAIRS = \
- a-intnam.ads<4sintnam.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-intman.adb<5sintman.adb \
- s-osinte.adb<5sosinte.adb \
- s-osinte.ads<5sosinte.ads \
- s-osprim.adb<5sosprim.adb \
- s-parame.adb<5sparame.adb \
- s-taprop.adb<5staprop.adb \
- s-tasinf.adb<5stasinf.adb \
- s-tasinf.ads<5stasinf.ads \
- s-taspri.ads<5staspri.ads \
- s-tpopsp.adb<5stpopsp.adb \
- g-soccon.ads<3ssoccon.ads \
- g-soliop.ads<3ssoliop.ads \
- system.ads<5ssystem.ads
-
- TOOLS_TARGET_PAIRS=mlib-tgt.adb<5sml-tgt.adb
+ a-intnam.ads<a-intnam-solaris.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-solaris.adb \
+ s-osinte.adb<s-osinte-solaris.adb \
+ s-osinte.ads<s-osinte-solaris.ads \
+ s-osprim.adb<s-osprim-solaris.adb \
+ s-parame.adb<s-parame-solaris.adb \
+ s-taprop.adb<s-taprop-solaris.adb \
+ s-tasinf.adb<s-tasinf-solaris.adb \
+ s-tasinf.ads<s-tasinf-solaris.ads \
+ s-taspri.ads<s-taspri-solaris.ads \
+ s-tpopsp.adb<s-tpopsp-solaris.adb \
+ g-soccon.ads<g-soccon-solaris.ads \
+ g-soliop.ads<g-soliop-solaris.ads \
+ system.ads<system-solaris-sparc.ads
+
+ TOOLS_TARGET_PAIRS=mlib-tgt.adb<mlib-tgt-solaris.adb
THREADSLIB = -lposix4 -lthread
MISCLIB = -lposix4 -lnsl -lsocket
@@ -732,80 +680,80 @@ ifeq ($(strip $(filter-out sparc sun solaris%,$(targ))),)
ifeq ($(strip $(filter-out fsu FSU,$(THREAD_KIND))),)
LIBGNAT_TARGET_PAIRS = \
- a-intnam.ads<4sintnam.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-intman.adb<5sintman.adb \
- s-osinte.adb<7sosinte.adb \
- s-osinte.ads<5tosinte.ads \
- s-osprim.adb<5sosprim.adb \
- s-taprop.adb<7staprop.adb \
- s-taspri.ads<7staspri.ads \
- s-tpopsp.adb<7stpopsp.adb \
- g-soccon.ads<3ssoccon.ads \
- g-soliop.ads<3ssoliop.ads \
- system.ads<5ssystem.ads
+ a-intnam.ads<a-intnam-solaris.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-solaris.adb \
+ s-osinte.adb<s-osinte-fsu.adb \
+ s-osinte.ads<s-osinte-solaris-fsu.ads \
+ s-osprim.adb<s-osprim-solaris.adb \
+ s-taprop.adb<s-taprop-posix.adb \
+ s-taspri.ads<s-taspri-posix.ads \
+ s-tpopsp.adb<s-tpopsp-posix.adb \
+ g-soccon.ads<g-soccon-solaris.ads \
+ g-soliop.ads<g-soliop-solaris.ads \
+ system.ads<system-solaris-sparc.ads
THREADSLIB = -lgthreads -lmalloc
endif
ifeq ($(strip $(filter-out pthread PTHREAD,$(THREAD_KIND))),)
LIBGNAT_TARGET_PAIRS = \
- a-intnam.ads<4sintnam.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-intman.adb<7sintman.adb \
- s-osinte.adb<5iosinte.adb \
- s-osinte.ads<54osinte.ads \
- s-osprim.adb<5sosprim.adb \
- s-taprop.adb<7staprop.adb \
- s-taspri.ads<7staspri.ads \
- s-tpopsp.adb<5atpopsp.adb \
- g-soccon.ads<3ssoccon.ads \
- g-soliop.ads<3ssoliop.ads \
- system.ads<5ssystem.ads
+ a-intnam.ads<a-intnam-solaris.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-posix.adb \
+ s-osinte.adb<s-osinte-posix.adb \
+ s-osinte.ads<s-osinte-solaris-posix.ads \
+ s-osprim.adb<s-osprim-solaris.adb \
+ s-taprop.adb<s-taprop-posix.adb \
+ s-taspri.ads<s-taspri-posix.ads \
+ s-tpopsp.adb<s-tpopsp-posix-foreign.adb \
+ g-soccon.ads<g-soccon-solaris.ads \
+ g-soliop.ads<g-soliop-solaris.ads \
+ system.ads<system-solaris-sparc.ads
THREADSLIB = -lposix4 -lpthread
endif
ifeq ($(strip $(filter-out m64,$(THREAD_KIND))),)
LIBGNAT_TARGET_PAIRS = \
- a-intnam.ads<4sintnam.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-intman.adb<5sintman.adb \
- s-osinte.adb<5sosinte.adb \
- s-osinte.ads<5sosinte.ads \
- s-osprim.adb<5sosprim.adb \
- s-parame.adb<5sparame.adb \
- s-taprop.adb<5staprop.adb \
- s-tasinf.adb<5stasinf.adb \
- s-tasinf.ads<5stasinf.ads \
- s-taspri.ads<5staspri.ads \
- s-tpopsp.adb<5stpopsp.adb \
- g-soccon.ads<3ssoccon.ads \
- g-soliop.ads<3ssoliop.ads \
- system.ads<5usystem.ads
+ a-intnam.ads<a-intnam-solaris.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-solaris.adb \
+ s-osinte.adb<s-osinte-solaris.adb \
+ s-osinte.ads<s-osinte-solaris.ads \
+ s-osprim.adb<s-osprim-solaris.adb \
+ s-parame.adb<s-parame-solaris.adb \
+ s-taprop.adb<s-taprop-solaris.adb \
+ s-tasinf.adb<s-tasinf-solaris.adb \
+ s-tasinf.ads<s-tasinf-solaris.ads \
+ s-taspri.ads<s-taspri-solaris.ads \
+ s-tpopsp.adb<s-tpopsp-solaris.adb \
+ g-soccon.ads<g-soccon-solaris.ads \
+ g-soliop.ads<g-soliop-solaris.ads \
+ system.ads<system-solaris-sparcv9.ads
endif
endif
ifeq ($(strip $(filter-out %86 solaris2%,$(arch) $(osys))),)
LIBGNAT_TARGET_PAIRS = \
- a-numaux.adb<86numaux.adb \
- a-numaux.ads<86numaux.ads \
- a-intnam.ads<4sintnam.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-intman.adb<5sintman.adb \
- s-mastop.adb<5omastop.adb \
- s-osinte.adb<5sosinte.adb \
- s-osinte.ads<5sosinte.ads \
- s-osprim.adb<5sosprim.adb \
- s-parame.adb<5sparame.adb \
- s-taprop.adb<5staprop.adb \
- s-tasinf.adb<5stasinf.adb \
- s-tasinf.ads<5stasinf.ads \
- s-taspri.ads<5staspri.ads \
- s-tpopsp.adb<5stpopsp.adb \
- g-soccon.ads<3ssoccon.ads \
- g-soliop.ads<3ssoliop.ads \
- system.ads<5esystem.ads
+ a-numaux.adb<a-numaux-x86.adb \
+ a-numaux.ads<a-numaux-x86.ads \
+ a-intnam.ads<a-intnam-solaris.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-solaris.adb \
+ s-mastop.adb<s-mastop-x86.adb \
+ s-osinte.adb<s-osinte-solaris.adb \
+ s-osinte.ads<s-osinte-solaris.ads \
+ s-osprim.adb<s-osprim-solaris.adb \
+ s-parame.adb<s-parame-solaris.adb \
+ s-taprop.adb<s-taprop-solaris.adb \
+ s-tasinf.adb<s-tasinf-solaris.adb \
+ s-tasinf.ads<s-tasinf-solaris.ads \
+ s-taspri.ads<s-taspri-solaris.ads \
+ s-tpopsp.adb<s-tpopsp-solaris.adb \
+ g-soccon.ads<g-soccon-solaris.ads \
+ g-soliop.ads<g-soliop-solaris.ads \
+ system.ads<system-solaris-x86.ads
THREADSLIB = -lposix4 -lthread
MISCLIB = -lposix4 -lnsl -lsocket
@@ -817,23 +765,23 @@ endif
ifeq ($(strip $(filter-out %86 linux%,$(arch) $(osys))),)
LIBGNAT_TARGET_PAIRS = \
- a-intnam.ads<4lintnam.ads \
- a-numaux.adb<86numaux.adb \
- a-numaux.ads<86numaux.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-intman.adb<7sintman.adb \
- s-mastop.adb<5omastop.adb \
- s-osinte.adb<5iosinte.adb \
- s-osinte.ads<5iosinte.ads \
- s-osprim.adb<7sosprim.adb \
- s-taprop.adb<5itaprop.adb \
- s-taspri.ads<5itaspri.ads \
- s-tpopsp.adb<5atpopsp.adb \
- s-parame.adb<5lparame.adb \
- system.ads<5lsystem.ads
+ a-intnam.ads<a-intnam-linux.ads \
+ a-numaux.adb<a-numaux-x86.adb \
+ a-numaux.ads<a-numaux-x86.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-posix.adb \
+ s-mastop.adb<s-mastop-x86.adb \
+ s-osinte.adb<s-osinte-posix.adb \
+ s-osinte.ads<s-osinte-linux.ads \
+ s-osprim.adb<s-osprim-posix.adb \
+ s-taprop.adb<s-taprop-linux.adb \
+ s-taspri.ads<s-taspri-linux.ads \
+ s-tpopsp.adb<s-tpopsp-posix-foreign.adb \
+ s-parame.adb<s-parame-linux.adb \
+ system.ads<system-linux-x86.ads
TOOLS_TARGET_PAIRS = \
- mlib-tgt.adb<5lml-tgt.adb
+ mlib-tgt.adb<mlib-tgt-linux.adb
SYMLIB = $(ADDR2LINE_SYMLIB)
THREADSLIB = -lpthread
@@ -844,19 +792,19 @@ ifeq ($(strip $(filter-out %86 linux%,$(arch) $(osys))),)
ifeq ($(strip $(filter-out fsu FSU,$(THREAD_KIND))),)
LIBGNAT_TARGET_PAIRS = \
- a-intnam.ads<4lintnam.ads \
- a-numaux.adb<86numaux.adb \
- a-numaux.ads<86numaux.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-intman.adb<7sintman.adb \
- s-mastop.adb<5omastop.adb \
- s-osinte.adb<7sosinte.adb \
- s-osinte.ads<5losinte.ads \
- s-osprim.adb<7sosprim.adb \
- s-taprop.adb<7staprop.adb \
- s-taspri.ads<7staspri.ads \
- s-tpopsp.adb<7stpopsp.adb \
- system.ads<5lsystem.ads
+ a-intnam.ads<a-intnam-linux.ads \
+ a-numaux.adb<a-numaux-x86.adb \
+ a-numaux.ads<a-numaux-x86.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-posix.adb \
+ s-mastop.adb<s-mastop-x86.adb \
+ s-osinte.adb<s-osinte-fsu.adb \
+ s-osinte.ads<s-osinte-linux-fsu.ads \
+ s-osprim.adb<s-osprim-posix.adb \
+ s-taprop.adb<s-taprop-posix.adb \
+ s-taspri.ads<s-taspri-posix.ads \
+ s-tpopsp.adb<s-tpopsp-posix.adb \
+ system.ads<system-linux-x86.ads
THREADSLIB = -lgthreads -lmalloc
endif
@@ -864,21 +812,23 @@ endif
ifeq ($(strip $(filter-out %86 freebsd%,$(arch) $(osys))),)
LIBGNAT_TARGET_PAIRS = \
- a-intnam.ads<45intnam.ads \
- g-soccon.ads<35soccon.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-intman.adb<7sintman.adb \
- s-mastop.adb<5omastop.adb \
- s-osinte.adb<55osinte.adb \
- s-osinte.ads<55osinte.ads \
- s-osprim.adb<7sosprim.adb \
- s-taprop.adb<7staprop.adb \
- s-taspri.ads<7staspri.ads \
- s-tpopsp.adb<7stpopsp.adb \
- system.ads<56system.ads
+ a-intnam.ads<a-intnam-freebsd.ads \
+ a-numaux.adb<a-numaux-x86.adb \
+ a-numaux.ads<a-numaux-x86.ads \
+ g-soccon.ads<g-soccon-freebsd.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-posix.adb \
+ s-mastop.adb<s-mastop-x86.adb \
+ s-osinte.adb<s-osinte-freebsd.adb \
+ s-osinte.ads<s-osinte-freebsd.ads \
+ s-osprim.adb<s-osprim-posix.adb \
+ s-taprop.adb<s-taprop-posix.adb \
+ s-taspri.ads<s-taspri-posix.ads \
+ s-tpopsp.adb<s-tpopsp-posix.adb \
+ system.ads<system-freebsd-x86.ads
TOOLS_TARGET_PAIRS = \
- mlib-tgt.adb<5lml-tgt.adb
+ mlib-tgt.adb<mlib-tgt-linux.adb
GNATLIB_SHARED = gnatlib-shared-dual
SYMLIB = $(ADDR2LINE_SYMLIB)
@@ -888,51 +838,89 @@ ifeq ($(strip $(filter-out %86 freebsd%,$(arch) $(osys))),)
LIBRARY_VERSION := $(LIB_VERSION)
endif
+ifeq ($(strip $(filter-out s390% linux%,$(arch) $(osys))),)
+ ifeq ($(strip $(filter-out s390x,$(arch))),)
+ LIBGNAT_TARGET_PAIRS = \
+ a-intnam.ads<a-intnam-linux.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-posix.adb \
+ s-osinte.adb<s-osinte-posix.adb \
+ s-osinte.ads<s-osinte-linux.ads \
+ s-osprim.adb<s-osprim-posix.adb \
+ s-taprop.adb<s-taprop-linux.adb \
+ s-taspri.ads<s-taspri-linux.ads \
+ s-tpopsp.adb<s-tpopsp-posix-foreign.adb \
+ s-parame.adb<s-parame-linux.adb \
+ system.ads<system-linux-s390x.ads
+ else
+ LIBGNAT_TARGET_PAIRS = \
+ a-intnam.ads<a-intnam-linux.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-posix.adb \
+ s-osinte.adb<s-osinte-posix.adb \
+ s-osinte.ads<s-osinte-linux.ads \
+ s-osprim.adb<s-osprim-posix.adb \
+ s-taprop.adb<s-taprop-linux.adb \
+ s-taspri.ads<s-taspri-linux.ads \
+ s-tpopsp.adb<s-tpopsp-posix-foreign.adb \
+ s-parame.adb<s-parame-linux.adb \
+ system.ads<system-linux-s390.ads
+ endif
+
+ TOOLS_TARGET_PAIRS = \
+ mlib-tgt.adb<mlib-tgt-linux.adb
+
+ THREADSLIB = -lpthread
+ GNATLIB_SHARED = gnatlib-shared-dual
+ PREFIX_OBJS = $(PREFIX_REAL_OBJS)
+ LIBRARY_VERSION := $(LIB_VERSION)
+endif
+
ifeq ($(strip $(filter-out mips sgi irix%,$(targ))),)
ifeq ($(strip $(filter-out mips sgi irix6%,$(targ))),)
LIBGNAT_TARGET_PAIRS = \
- a-intnam.ads<4gintnam.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-intman.adb<5fintman.adb \
- s-mastop.adb<5gmastop.adb \
- s-osinte.adb<5fosinte.adb \
- s-osinte.ads<5fosinte.ads \
- s-osprim.adb<7sosprim.adb \
- s-proinf.adb<5gproinf.adb \
- s-proinf.ads<5gproinf.ads \
- s-taprop.adb<5ftaprop.adb \
- s-tasinf.ads<5ftasinf.ads \
- s-taspri.ads<7staspri.ads \
- s-tpopsp.adb<7stpopsp.adb \
- s-traceb.adb<7straceb.adb \
- g-soccon.ads<3gsoccon.ads \
- system.ads<5gsystem.ads
+ a-intnam.ads<a-intnam-irix.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-irix.adb \
+ s-mastop.adb<s-mastop-irix.adb \
+ s-osinte.adb<s-osinte-irix.adb \
+ s-osinte.ads<s-osinte-irix.ads \
+ s-osprim.adb<s-osprim-posix.adb \
+ s-proinf.adb<s-proinf-irix-athread.adb \
+ s-proinf.ads<s-proinf-irix-athread.ads \
+ s-taprop.adb<s-taprop-irix.adb \
+ s-tasinf.ads<s-tasinf-irix.ads \
+ s-taspri.ads<s-taspri-posix.ads \
+ s-tpopsp.adb<s-tpopsp-posix.adb \
+ s-traceb.adb<s-traceb-mastop.adb \
+ g-soccon.ads<g-soccon-irix.ads \
+ system.ads<system-irix-n32.ads
THREADSLIB = -lpthread
GNATLIB_SHARED = gnatlib-shared-default
else
LIBGNAT_TARGET_PAIRS = \
- a-intnam.ads<4gintnam.ads \
- s-inmaop.adb<5ninmaop.adb \
- s-interr.adb<5ginterr.adb \
- s-intman.adb<5gintman.adb \
- s-mastop.adb<5gmastop.adb \
- s-osinte.adb<5fosinte.adb \
- s-osinte.ads<5gosinte.ads \
- s-osprim.adb<7sosprim.adb \
- s-proinf.adb<5gproinf.adb \
- s-proinf.ads<5gproinf.ads \
- s-taprop.adb<5gtaprop.adb \
- s-tasinf.adb<5gtasinf.adb \
- s-tasinf.ads<5gtasinf.ads \
- s-taspri.ads<7staspri.ads \
- s-traceb.adb<7straceb.adb \
- g-soccon.ads<3gsoccon.ads \
- system.ads<5fsystem.ads
+ a-intnam.ads<a-intnam-irix.ads \
+ s-inmaop.adb<s-inmaop-dummy.adb \
+ s-interr.adb<s-interr-sigaction.adb \
+ s-intman.adb<s-intman-irix-athread.adb \
+ s-mastop.adb<s-mastop-irix.adb \
+ s-osinte.adb<s-osinte-irix.adb \
+ s-osinte.ads<s-osinte-irix-athread.ads \
+ s-osprim.adb<s-osprim-posix.adb \
+ s-proinf.adb<s-proinf-irix-athread.adb \
+ s-proinf.ads<s-proinf-irix-athread.ads \
+ s-taprop.adb<s-taprop-irix-athread.adb \
+ s-tasinf.adb<s-tasinf-irix-athread.adb \
+ s-tasinf.ads<s-tasinf-irix-athread.ads \
+ s-taspri.ads<s-taspri-posix.ads \
+ s-traceb.adb<s-traceb-mastop.adb \
+ g-soccon.ads<g-soccon-irix.ads \
+ system.ads<system-irix-o32.ads
endif
- TOOLS_TARGET_PAIRS = mlib-tgt.adb<5gml-tgt.adb
+ TOOLS_TARGET_PAIRS = mlib-tgt.adb<mlib-tgt-irix.adb
TGT_LIB = -lexc
MISCLIB = -lexc
SO_OPTS = -Wl,-all,-set_version,sgi1.0,-update_registry,../so_locations,-soname,
@@ -942,41 +930,41 @@ endif
ifeq ($(strip $(filter-out hppa% hp hpux10%,$(targ))),)
LIBGNAT_TARGET_PAIRS = \
- a-excpol.adb<4wexcpol.adb \
- a-intnam.ads<4hintnam.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-interr.adb<5ginterr.adb \
- s-intman.adb<7sintman.adb \
- s-osinte.adb<5hosinte.adb \
- s-osinte.ads<5hosinte.ads \
- s-parame.ads<5hparame.ads \
- s-osprim.adb<7sosprim.adb \
- s-taprop.adb<5htaprop.adb \
- s-taspri.ads<5htaspri.ads \
- s-tpopsp.adb<7stpopsp.adb \
- g-soccon.ads<3hsoccon.ads \
- system.ads<5hsystem.ads
+ a-excpol.adb<a-excpol-abort.adb \
+ a-intnam.ads<a-intnam-hpux.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-interr.adb<s-interr-sigaction.adb \
+ s-intman.adb<s-intman-posix.adb \
+ s-osinte.adb<s-osinte-hpux-dce.adb \
+ s-osinte.ads<s-osinte-hpux-dce.ads \
+ s-parame.ads<s-parame-hpux.ads \
+ s-osprim.adb<s-osprim-posix.adb \
+ s-taprop.adb<s-taprop-hpux-dce.adb \
+ s-taspri.ads<s-taspri-hpux-dce.ads \
+ s-tpopsp.adb<s-tpopsp-posix.adb \
+ g-soccon.ads<g-soccon-hpux.ads \
+ system.ads<system-hpux.ads
PREFIX_OBJS = $(PREFIX_REAL_OBJS)
endif
ifeq ($(strip $(filter-out hppa% hp hpux11%,$(targ))),)
LIBGNAT_TARGET_PAIRS = \
- a-intnam.ads<4hintnam.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-intman.adb<7sintman.adb \
- s-osinte.adb<5iosinte.adb \
- s-osinte.ads<53osinte.ads \
- s-parame.ads<5hparame.ads \
- s-osprim.adb<7sosprim.adb \
- s-traceb.adb<5htraceb.adb \
- s-taprop.adb<7staprop.adb \
- s-taspri.ads<7staspri.ads \
- s-tpopsp.adb<5atpopsp.adb \
- g-soccon.ads<3hsoccon.ads \
- system.ads<5hsystem.ads
-
- TOOLS_TARGET_PAIRS = mlib-tgt.adb<5hml-tgt.adb
+ a-intnam.ads<a-intnam-hpux.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-posix.adb \
+ s-osinte.adb<s-osinte-posix.adb \
+ s-osinte.ads<s-osinte-hpux.ads \
+ s-parame.ads<s-parame-hpux.ads \
+ s-osprim.adb<s-osprim-posix.adb \
+ s-traceb.adb<s-traceb-hpux.adb \
+ s-taprop.adb<s-taprop-posix.adb \
+ s-taspri.ads<s-taspri-posix.ads \
+ s-tpopsp.adb<s-tpopsp-posix-foreign.adb \
+ g-soccon.ads<g-soccon-hpux.ads \
+ system.ads<system-hpux.ads
+
+ TOOLS_TARGET_PAIRS = mlib-tgt.adb<mlib-tgt-hpux.adb
TGT_LIB = /usr/lib/libcl.a
THREADSLIB = -lpthread
SYMLIB = $(ADDR2LINE_SYMLIB)
@@ -989,20 +977,20 @@ ifeq ($(strip $(filter-out hppa% hp hpux11%,$(targ))),)
ifeq ($(strip $(filter-out dce DCE,$(THREAD_KIND))),)
LIBGNAT_TARGET_PAIRS = \
- a-excpol.adb<4wexcpol.adb \
- a-intnam.ads<4hintnam.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-interr.adb<5ginterr.adb \
- s-intman.adb<7sintman.adb \
- s-osinte.adb<5hosinte.adb \
- s-osinte.ads<5hosinte.ads \
- s-parame.ads<5hparame.ads \
- s-osprim.adb<7sosprim.adb \
- s-taprop.adb<5htaprop.adb \
- s-taspri.ads<5htaspri.ads \
- s-tpopsp.adb<7stpopsp.adb \
- g-soccon.ads<3hsoccon.ads \
- system.ads<5hsystem.ads
+ a-excpol.adb<a-excpol-abort.adb \
+ a-intnam.ads<a-intnam-hpux.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-interr.adb<s-interr-sigaction.adb \
+ s-intman.adb<s-intman-posix.adb \
+ s-osinte.adb<s-osinte-hpux-dce.adb \
+ s-osinte.ads<s-osinte-hpux-dce.ads \
+ s-parame.ads<s-parame-hpux.ads \
+ s-osprim.adb<s-osprim-posix.adb \
+ s-taprop.adb<s-taprop-hpux-dce.adb \
+ s-taspri.ads<s-taspri-hpux-dce.ads \
+ s-tpopsp.adb<s-tpopsp-posix.adb \
+ g-soccon.ads<g-soccon-hpux.ads \
+ system.ads<system-hpux.ads
TGT_LIB =
THREADSLIB = -lcma
@@ -1011,39 +999,39 @@ endif
ifeq ($(strip $(filter-out ibm aix%,$(manu) $(osys))),)
LIBGNAT_TARGET_PAIRS = \
- a-intnam.ads<4cintnam.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-intman.adb<7sintman.adb \
- s-osinte.adb<5bosinte.adb \
- s-osinte.ads<5bosinte.ads \
- s-osprim.adb<7sosprim.adb \
- s-taprop.adb<7staprop.adb \
- s-taspri.ads<7staspri.ads \
- s-tpopsp.adb<7stpopsp.adb \
- g-soccon.ads<3bsoccon.ads \
- system.ads<5bsystem.ads
+ a-intnam.ads<a-intnam-aix.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-posix.adb \
+ s-osinte.adb<s-osinte-aix.adb \
+ s-osinte.ads<s-osinte-aix.ads \
+ s-osprim.adb<s-osprim-posix.adb \
+ s-taprop.adb<s-taprop-posix.adb \
+ s-taspri.ads<s-taspri-posix.ads \
+ s-tpopsp.adb<s-tpopsp-posix.adb \
+ g-soccon.ads<g-soccon-aix.ads \
+ system.ads<system-aix.ads
THREADSLIB = -lpthreads
PREFIX_OBJS=$(PREFIX_REAL_OBJS)
ifeq ($(strip $(filter-out fsu FSU,$(THREAD_KIND))),)
LIBGNAT_TARGET_PAIRS = \
- a-intnam.ads<4cintnam.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-intman.adb<7sintman.adb \
- s-osinte.adb<7sosinte.adb \
- s-osinte.ads<5cosinte.ads \
- s-osprim.adb<7sosprim.adb \
- s-taprop.adb<7staprop.adb \
- s-taspri.ads<7staspri.ads \
- s-tpopsp.adb<7stpopsp.adb \
- g-soccon.ads<3bsoccon.ads \
- system.ads<5bsystem.ads
+ a-intnam.ads<a-intnam-aix.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-posix.adb \
+ s-osinte.adb<s-osinte-fsu.adb \
+ s-osinte.ads<s-osinte-aix-fsu.ads \
+ s-osprim.adb<s-osprim-posix.adb \
+ s-taprop.adb<s-taprop-posix.adb \
+ s-taspri.ads<s-taspri-posix.ads \
+ s-tpopsp.adb<s-tpopsp-posix.adb \
+ g-soccon.ads<g-soccon-aix.ads \
+ system.ads<system-aix.ads
THREADSLIB = -lgthreads -lmalloc
endif
- TOOLS_TARGET_PAIRS = mlib-tgt.adb<5bml-tgt.adb
+ TOOLS_TARGET_PAIRS = mlib-tgt.adb<mlib-tgt-aix.adb
GMEM_LIB = gmemlib
SYMLIB = $(ADDR2LINE_SYMLIB)
@@ -1052,47 +1040,47 @@ endif
ifeq ($(strip $(filter-out lynxos,$(osys))),)
ifeq ($(strip $(filter-out %86 lynxos,$(arch) $(osys))),)
LIBGNAT_TARGET_PAIRS = \
- a-numaux.adb<86numaux.adb \
- a-numaux.ads<86numaux.ads \
- a-intnam.ads<42intnam.ads \
- s-mastop.adb<5omastop.adb \
- s-inmaop.adb<7sinmaop.adb \
- s-intman.adb<7sintman.adb \
- s-osinte.adb<56osinte.adb \
- s-osinte.ads<56osinte.ads \
- s-osprim.adb<7sosprim.adb \
- s-taprop.adb<56taprop.adb \
- s-taspri.ads<56taspri.ads \
- s-tpopsp.adb<56tpopsp.adb \
- system.ads<58system.ads
+ a-numaux.adb<a-numaux-x86.adb \
+ a-numaux.ads<a-numaux-x86.ads \
+ a-intnam.ads<a-intnam-lynxos.ads \
+ s-mastop.adb<s-mastop-x86.adb \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-posix.adb \
+ s-osinte.adb<s-osinte-lynxos.adb \
+ s-osinte.ads<s-osinte-lynxos.ads \
+ s-osprim.adb<s-osprim-posix.adb \
+ s-taprop.adb<s-taprop-lynxos.adb \
+ s-taspri.ads<s-taspri-lynxos.ads \
+ s-tpopsp.adb<s-tpopsp-lynxos.adb \
+ system.ads<system-lynxos-x86.ads
PREFIX_OBJS=$(PREFIX_REAL_OBJS)
else
LIBGNAT_TARGET_PAIRS = \
- a-intnam.ads<42intnam.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-intman.adb<7sintman.adb \
- s-osinte.adb<52osinte.adb \
- s-osinte.ads<52osinte.ads \
- s-osprim.adb<7sosprim.adb \
- s-taprop.adb<7staprop.adb \
- s-taspri.ads<7staspri.ads \
- s-tpopsp.adb<7stpopsp.adb \
- system.ads<57system.ads
+ a-intnam.ads<a-intnam-lynxos.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-posix.adb \
+ s-osinte.adb<s-osinte-lynxos-3.adb \
+ s-osinte.ads<s-osinte-lynxos-3.ads \
+ s-osprim.adb<s-osprim-posix.adb \
+ s-taprop.adb<s-taprop-posix.adb \
+ s-taspri.ads<s-taspri-posix.ads \
+ s-tpopsp.adb<s-tpopsp-posix.adb \
+ system.ads<system-lynxos-ppc.ads
ifeq ($(strip $(filter-out pthread PTHREAD,$(THREAD_KIND))),)
LIBGNAT_TARGET_PAIRS = \
- a-intnam.ads<42intnam.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-intman.adb<7sintman.adb \
- s-osinte.adb<56osinte.adb \
- s-osinte.ads<56osinte.ads \
- s-osprim.adb<7sosprim.adb \
- s-taprop.adb<56taprop.adb \
- s-taspri.ads<56taspri.ads \
- s-tpopsp.adb<56tpopsp.adb \
- system.ads<57system.ads
+ a-intnam.ads<a-intnam-lynxos.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-posix.adb \
+ s-osinte.adb<s-osinte-lynxos.adb \
+ s-osinte.ads<s-osinte-lynxos.ads \
+ s-osprim.adb<s-osprim-posix.adb \
+ s-taprop.adb<s-taprop-lynxos.adb \
+ s-taspri.ads<s-taspri-lynxos.ads \
+ s-tpopsp.adb<s-tpopsp-lynxos.adb \
+ system.ads<system-lynxos-ppc.ads
endif
endif
@@ -1101,35 +1089,35 @@ endif
ifeq ($(strip $(filter-out rtems%,$(osys))),)
LIBGNAT_TARGET_PAIRS = \
a-intnam.ads<4rintnam.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-intman.adb<7sintman.adb \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-posix.adb \
s-osinte.adb<5rosinte.adb \
s-osinte.ads<5rosinte.ads \
- s-osprim.adb<7sosprim.adb \
+ s-osprim.adb<s-osprim-posix.adb \
s-parame.adb<5rparame.adb \
- s-taprop.adb<7staprop.adb \
- s-taspri.ads<7staspri.ads \
+ s-taprop.adb<s-taprop-posix.adb \
+ s-taspri.ads<s-taspri-posix.ads \
s-tpopsp.adb<5rtpopsp.adb
endif
ifeq ($(strip $(filter-out alpha% dec osf%,$(targ))),)
LIBGNAT_TARGET_PAIRS = \
- a-intnam.ads<4aintnam.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-intman.adb<7sintman.adb \
- s-mastop.adb<5amastop.adb \
- s-osinte.adb<5aosinte.adb \
- s-osinte.ads<5aosinte.ads \
- s-osprim.adb<5posprim.adb \
- s-taprop.adb<5ataprop.adb \
- s-tasinf.ads<5atasinf.ads \
- s-taspri.ads<5ataspri.ads \
- s-tpopsp.adb<5atpopsp.adb \
- s-traceb.adb<7straceb.adb \
- g-soccon.ads<3asoccon.ads \
- system.ads<5asystem.ads
-
- TOOLS_TARGET_PAIRS=mlib-tgt.adb<5aml-tgt.adb
+ a-intnam.ads<a-intnam-tru64.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-posix.adb \
+ s-mastop.adb<s-mastop-tru64.adb \
+ s-osinte.adb<s-osinte-tru64.adb \
+ s-osinte.ads<s-osinte-tru64.ads \
+ s-osprim.adb<s-osprim-unix.adb \
+ s-taprop.adb<s-taprop-tru64.adb \
+ s-tasinf.ads<s-tasinf-tru64.ads \
+ s-taspri.ads<s-taspri-tru64.ads \
+ s-tpopsp.adb<s-tpopsp-posix-foreign.adb \
+ s-traceb.adb<s-traceb-mastop.adb \
+ g-soccon.ads<g-soccon-tru64.ads \
+ system.ads<system-tru64.ads
+
+ TOOLS_TARGET_PAIRS=mlib-tgt.adb<mlib-tgt-tru64.adb
GMEM_LIB=gmemlib
SYMLIB = $(ADDR2LINE_SYMLIB)
@@ -1144,6 +1132,10 @@ ifeq ($(strip $(filter-out alpha% ia64 dec hp vms% openvms% alphavms%,$(host))),
soext = .exe
hyphen = _
+ifeq ($(strip $(filter-out ia64 hp vms% openvms%,$(targ))),)
+AR = iar
+endif
+
.SUFFIXES: .sym
.o.sym:
@@ -1153,62 +1145,63 @@ endif
ifeq ($(strip $(filter-out alpha% ia64 dec hp vms% openvms% alphavms%,$(targ))),)
ifeq ($(strip $(filter-out ia64 hp vms% openvms%,$(targ))),)
LIBGNAT_TARGET_PAIRS_AUX1 = \
- s-crtl.ads<5xcrtl.ads \
- s-osinte.adb<5xosinte.adb \
- s-osinte.ads<5xosinte.ads \
+ s-auxdec.ads<5qauxdec.ads \
+ s-crtl.ads<s-crtl-vms.ads \
+ s-osinte.adb<s-osinte-vms-ia64.adb \
+ s-osinte.ads<s-osinte-vms-ia64.ads \
system.ads<5qsystem.ads
else
ifeq ($(strip $(filter-out alpha% dec vms% openvms% alphavms%,$(targ))),)
LIBGNAT_TARGET_PAIRS_AUX1 = \
- s-crtl.ads<5vcrtl.ads \
- s-osinte.adb<5vosinte.adb \
- s-osinte.ads<5vosinte.ads \
- system.ads<5xsystem.ads
+ s-crtl.ads<s-crtl-vms.ads \
+ s-osinte.adb<s-osinte-vms.adb \
+ s-osinte.ads<s-osinte-vms.ads \
+ system.ads<system-vms-zcx.ads
endif
endif
ifeq ($(strip $(filter-out express EXPRESS,$(THREAD_KIND))),)
LIBGNAT_TARGET_PAIRS_AUX2 = \
- s-parame.ads<5xparame.ads
+ s-parame.ads<s-parame-vms-restrict.ads
else
LIBGNAT_TARGET_PAIRS_AUX2 = \
- s-parame.ads<5vparame.ads
+ s-parame.ads<s-parame-vms.ads
endif
LIBGNAT_TARGET_PAIRS = \
- a-caldel.adb<4vcaldel.adb \
- a-calend.adb<4vcalend.adb \
- a-calend.ads<4vcalend.ads \
- a-dirval.adb<5vdirval.adb \
- a-excpol.adb<4wexcpol.adb \
- a-intnam.ads<4vintnam.ads \
- a-numaux.ads<4vnumaux.ads \
- g-expect.adb<3vexpect.adb \
- g-soccon.ads<3vsoccon.ads \
- g-socthi.ads<3vsocthi.ads \
- g-socthi.adb<3vsocthi.adb \
- g-trasym.adb<3vtrasym.adb \
- i-cstrea.adb<6vcstrea.adb \
- i-cpp.adb<6vcpp.adb \
- interfac.ads<6vinterf.ads \
- s-asthan.adb<5vasthan.adb \
- s-inmaop.adb<5vinmaop.adb \
- s-interr.adb<5vinterr.adb \
- s-intman.adb<5vintman.adb \
- s-intman.ads<5vintman.ads \
- s-osprim.adb<5vosprim.adb \
- s-osprim.ads<5vosprim.ads \
- s-taprop.adb<5vtaprop.adb \
- s-taspri.ads<5vtaspri.ads \
- s-tpopsp.adb<7stpopsp.adb \
- s-tpopde.adb<5vtpopde.adb \
- s-tpopde.ads<5vtpopde.ads \
- s-traent.adb<5vtraent.adb \
- s-traent.ads<5vtraent.ads \
- s-vaflop.adb<5vvaflop.adb \
+ a-caldel.adb<a-caldel-vms.adb \
+ a-calend.adb<a-calend-vms.adb \
+ a-calend.ads<a-calend-vms.ads \
+ a-dirval.adb<a-dirval-vms.adb \
+ a-excpol.adb<a-excpol-abort.adb \
+ a-intnam.ads<a-intnam-vms.ads \
+ a-numaux.ads<a-numaux-vms.ads \
+ g-expect.adb<g-expect-vms.adb \
+ g-soccon.ads<g-soccon-vms.adb \
+ g-socthi.ads<g-socthi-vms.ads \
+ g-socthi.adb<g-socthi-vms.adb \
+ g-trasym.adb<g-trasym-vms.adb \
+ i-cstrea.adb<i-cstrea-vms.adb \
+ i-cpp.adb<i-cpp-vms.adb \
+ interfac.ads<interfac-vms.ads \
+ s-asthan.adb<s-asthan-vms.adb \
+ s-inmaop.adb<s-inmaop-vms.adb \
+ s-interr.adb<s-interr-vms.adb \
+ s-intman.adb<s-intman-vms.adb \
+ s-intman.ads<s-intman-vms.ads \
+ s-osprim.adb<s-osprim-vms.adb \
+ s-osprim.ads<s-osprim-vms.ads \
+ s-taprop.adb<s-taprop-vms.adb \
+ s-taspri.ads<s-taspri-vms.ads \
+ s-tpopsp.adb<s-tpopsp-posix.adb \
+ s-tpopde.adb<s-tpopde-vms.adb \
+ s-tpopde.ads<s-tpopde-vms.ads \
+ s-traent.adb<s-traent-vms.adb \
+ s-traent.ads<s-traent-vms.ads \
+ s-vaflop.adb<s-vaflop-vms.adb \
$(LIBGNAT_TARGET_PAIRS_AUX1) \
$(LIBGNAT_TARGET_PAIRS_AUX2)
- TOOLS_TARGET_PAIRS=mlib-tgt.adb<5vml-tgt.adb
+ TOOLS_TARGET_PAIRS=mlib-tgt.adb<mlib-tgt-vms.adb
GNATLIB_SHARED=gnatlib-shared-vms
ifeq ($(strip $(filter-out alpha% dec vms% openvms% alphavms%,$(targ))),)
@@ -1227,29 +1220,29 @@ endif
ifeq ($(strip $(filter-out cygwin32% mingw32% pe,$(osys))),)
LIBGNAT_TARGET_PAIRS = \
- a-calend.adb<4wcalend.adb \
- a-dirval.adb<5wdirval.adb \
- a-excpol.adb<4wexcpol.adb \
- a-intnam.ads<4wintnam.ads \
- a-numaux.adb<86numaux.adb \
- a-numaux.ads<86numaux.ads \
- s-gloloc.adb<5wgloloc.adb \
- s-inmaop.adb<5ninmaop.adb \
- s-interr.adb<5ginterr.adb \
- s-intman.adb<5wintman.adb \
- s-mastop.adb<5omastop.adb \
- s-memory.adb<5wmemory.adb \
- s-osinte.ads<5wosinte.ads \
- s-osprim.adb<5wosprim.adb \
- s-taprop.adb<5wtaprop.adb \
- s-taspri.ads<5wtaspri.ads \
- g-socthi.ads<3wsocthi.ads \
- g-socthi.adb<3wsocthi.adb \
- g-soccon.ads<3wsoccon.ads \
- g-soliop.ads<3wsoliop.ads \
- system.ads<5wsystem.ads
-
- TOOLS_TARGET_PAIRS=mlib-tgt.adb<5wml-tgt.adb
+ a-calend.adb<a-calend-mingw.adb \
+ a-dirval.adb<a-dirval-mingw.adb \
+ a-excpol.adb<a-excpol-abort.adb \
+ a-intnam.ads<a-intnam-mingw.ads \
+ a-numaux.adb<a-numaux-x86.adb \
+ a-numaux.ads<a-numaux-x86.ads \
+ s-gloloc.adb<s-gloloc-mingw.adb \
+ s-inmaop.adb<s-inmaop-dummy.adb \
+ s-interr.adb<s-interr-sigaction.adb \
+ s-intman.adb<s-intman-mingw.adb \
+ s-mastop.adb<s-mastop-x86.adb \
+ s-memory.adb<s-memory-mingw.adb \
+ s-osinte.ads<s-osinte-mingw.ads \
+ s-osprim.adb<s-osprim-mingw.adb \
+ s-taprop.adb<s-taprop-mingw.adb \
+ s-taspri.ads<s-taspri-mingw.ads \
+ g-socthi.ads<g-socthi-mingw.ads \
+ g-socthi.adb<g-socthi-mingw.adb \
+ g-soccon.ads<g-soccon-mingw.ads \
+ g-soliop.ads<g-soliop-mingw.ads \
+ system.ads<system-mingw.ads
+
+ TOOLS_TARGET_PAIRS=mlib-tgt.adb<mlib-tgt-mingw.adb
MISCLIB = -lwsock32
SYMLIB = $(ADDR2LINE_SYMLIB)
GMEM_LIB = gmemlib
@@ -1266,18 +1259,18 @@ endif
ifeq ($(strip $(filter-out %ia64 linux%,$(arch) $(osys))),)
LIBGNAT_TARGET_PAIRS = \
- a-intnam.ads<4lintnam.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-intman.adb<7sintman.adb \
- s-osinte.ads<5iosinte.ads \
- s-osinte.adb<5iosinte.adb \
- s-osprim.adb<7sosprim.adb \
- s-taprop.adb<5itaprop.adb \
- s-tpopsp.adb<5atpopsp.adb \
- s-taspri.ads<5itaspri.ads \
- system.ads<55system.ads
-
- TOOLS_TARGET_PAIRS=mlib-tgt.adb<5lml-tgt.adb
+ a-intnam.ads<a-intnam-linux.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-posix.adb \
+ s-osinte.ads<s-osinte-linux.ads \
+ s-osinte.adb<s-osinte-posix.adb \
+ s-osprim.adb<s-osprim-posix.adb \
+ s-taprop.adb<s-taprop-linux.adb \
+ s-tpopsp.adb<s-tpopsp-posix-foreign.adb \
+ s-taspri.ads<s-taspri-linux.ads \
+ system.ads<s-osinte-linux-ia64.ads
+
+ TOOLS_TARGET_PAIRS=mlib-tgt.adb<mlib-tgt-linux.adb
MISCLIB=
THREADSLIB=-lpthread
GNATLIB_SHARED=gnatlib-shared-dual
@@ -1287,27 +1280,41 @@ endif
ifeq ($(strip $(filter-out %x86_64 linux%,$(arch) $(osys))),)
LIBGNAT_TARGET_PAIRS = \
- a-intnam.ads<4lintnam.ads \
- a-numaux.adb<86numaux.adb \
- a-numaux.ads<86numaux.ads \
- s-inmaop.adb<7sinmaop.adb \
- s-intman.adb<7sintman.adb \
- s-osinte.ads<5iosinte.ads \
- s-osinte.adb<5iosinte.adb \
- s-osprim.adb<7sosprim.adb \
- s-taprop.adb<5itaprop.adb \
- s-tpopsp.adb<5atpopsp.adb \
- s-taspri.ads<5itaspri.ads \
- system.ads<5nsystem.ads
-
- TOOLS_TARGET_PAIRS=mlib-tgt.adb<5lml-tgt.adb
+ a-intnam.ads<a-intnam-linux.ads \
+ a-numaux.adb<a-numaux-x86.adb \
+ a-numaux.ads<a-numaux-x86.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-posix.adb \
+ s-osinte.ads<s-osinte-linux.ads \
+ s-osinte.adb<s-osinte-posix.adb \
+ s-osprim.adb<s-osprim-posix.adb \
+ s-taprop.adb<s-taprop-linux.adb \
+ s-tpopsp.adb<s-tpopsp-posix-foreign.adb \
+ s-taspri.ads<s-taspri-linux.ads \
+ system.ads<system-linux-x86_64.ads
+
+ TOOLS_TARGET_PAIRS=mlib-tgt.adb<mlib-tgt-linux.adb
SYMLIB = $(ADDR2LINE_SYMLIB)
THREADSLIB=-lpthread
GNATLIB_SHARED=gnatlib-shared-dual
GMEM_LIB = gmemlib
PREFIX_OBJS=$(PREFIX_REAL_OBJS)
LIBRARY_VERSION := $(LIB_VERSION)
+endif
+ifeq ($(strip $(filter-out powerpc darwin%,$(arch) $(osys))),)
+ LIBGNAT_TARGET_PAIRS = \
+ a-intnam.ads<a-intnam-darwin.ads \
+ s-inmaop.adb<s-inmaop-posix.adb \
+ s-intman.adb<s-intman-posix.adb \
+ s-osinte.adb<s-osinte-darwin.adb \
+ s-osinte.ads<s-osinte-darwin.ads \
+ s-osprim.adb<s-osprim-posix.adb \
+ s-taprop.adb<s-taprop-posix.adb \
+ s-taspri.ads<s-taspri-posix.ads \
+ s-tpopsp.adb<s-tpopsp-posix-foreign.adb \
+ g-soccon.ads<g-soccon-aix.ads \
+ system.ads<system-darwin-ppc.ads
endif
# The runtime library for gnat comprises two directories. One contains the
@@ -1342,131 +1349,6 @@ include $(fsrcdir)/Makefile.rtl
GNATRTL_OBJS = $(GNATRTL_NONTASKING_OBJS) $(GNATRTL_TASKING_OBJS) \
g-trasym.o memtrack.o
-# Files which are suitable in no run time/hi integrity mode
-
-COMPILABLE_HIE_SOURCES= \
- system.ads \
- ada.ads \
- gnat.ads \
- g-souinf.ads \
- interfac.ads \
- i-c.ads \
- s-stoele.ads \
- s-stoele.adb \
- s-maccod.ads \
- s-unstyp.ads \
- s-fatflt.ads \
- s-fatlfl.ads \
- s-fatllf.ads \
- s-fatsfl.ads \
- s-secsta.ads \
- s-secsta.adb \
- a-tags.ads \
- a-tags.adb \
- a-except.ads \
- a-except.adb $(EXTRA_HIE_SOURCES)
-
-NON_COMPILABLE_HIE_SOURCES= \
- a-unccon.ads \
- a-uncdea.ads \
- s-fatgen.adb \
- s-fatgen.ads \
- unchconv.ads \
- s-atacco.ads \
- s-atacco.adb \
- unchdeal.ads
-
-
-HIE_SOURCES = $(NON_COMPILABLE_HIE_SOURCES) $(COMPILABLE_HIE_SOURCES)
-
-# Object to generate for the HI run time
-
-HIE_OBJS = \
- system.o \
- ada.o \
- a-except.o \
- gnat.o \
- g-souinf.o \
- interfac.o \
- i-c.o \
- s-stoele.o \
- s-maccod.o \
- s-unstyp.o \
- s-fatflt.o \
- s-fatlfl.o \
- s-fatllf.o \
- s-fatsfl.o \
- s-secsta.o \
- a-tags.o $(EXTRA_HIE_OBJS)
-
-# Files which are needed in ravenscar mode
-
-COMPILABLE_RAVEN_SOURCES = \
-$(COMPILABLE_HIE_SOURCES) \
- s-parame.ads \
- s-parame.adb \
- s-purexc.ads \
- s-osinte.ads \
- s-osinte.adb \
- s-tasinf.ads \
- s-tasinf.adb \
- s-taspri.ads \
- s-taprop.ads \
- s-taprop.adb \
- s-taskin.ads \
- s-taskin.adb \
- s-interr.ads \
- s-interr.adb \
- a-interr.ads \
- a-interr.adb \
- a-intnam.ads \
- a-reatim.ads \
- a-reatim.adb \
- a-retide.ads \
- a-retide.adb \
- s-taprob.ads \
- s-taprob.adb \
- s-tposen.ads \
- s-tposen.adb \
- s-tasres.ads \
- s-tarest.ads \
- s-tarest.adb \
- a-sytaco.ads \
- a-sytaco.adb \
- a-taside.ads \
- a-taside.adb $(EXTRA_RAVEN_SOURCES)
-
-NON_COMPILABLE_RAVEN_SOURCES= $(NON_COMPILABLE_HIE_SOURCES)
-
-RAVEN_SOURCES = $(NON_COMPILABLE_RAVEN_SOURCES) $(COMPILABLE_RAVEN_SOURCES)
-
-# Objects to generate for the ravenscar run time
-
-RAVEN_LIBGNARL_OBJS = \
- s-parame.o \
- s-purexc.o \
- s-osinte.o \
- s-tasinf.o \
- s-taspri.o \
- s-taprop.o \
- s-taskin.o \
- s-interr.o \
- a-interr.o \
- a-intnam.o \
- a-reatim.o \
- a-retide.o \
- s-osinte.o \
- s-taprob.o \
- s-tposen.o \
- s-tasres.o \
- s-tarest.o \
- a-sytaco.o \
- a-taside.o $(EXTRA_RAVEN_OBJS)
-
-RAVEN_OBJS = \
- $(HIE_OBJS) \
- $(RAVEN_LIBGNARL_OBJS)
-
# Default run time files
ADA_INCLUDE_SRCS =\
@@ -1554,7 +1436,7 @@ gnattools2: ../stamp-tools
../../gnatls$(exeext) ../../gnatprep$(exeext) \
../../gnatxref$(exeext) \
../../gnatfind$(exeext) ../../gnatname$(exeext) \
- ../../gnatclean$(exeext) \
+ ../../gnatclean$(exeext) ../../gprmake$(exeext) \
../../gprcmd$(exeext) ../../gpr2make$(exeext)
# These tools are only built for the native version.
@@ -1596,6 +1478,12 @@ gnattools4: ../stamp-tools
$(GNATLINK) -v gnatname -o $@ --GCC="$(CC) $(ADA_INCLUDES)" \
$(TOOLS_LIBS)
+../../gprmake$(exeext): ../stamp-tools
+ $(GNATMAKE) -c $(ADA_INCLUDES) gprmake --GCC="$(CC) $(ALL_ADAFLAGS)"
+ $(GNATBIND) $(ADA_INCLUDES) $(GNATBIND_FLAGS) gprmake
+ $(GNATLINK) -v gprmake -o $@ --GCC="$(CC) $(ADA_INCLUDES)" \
+ $(TOOLS_LIBS)
+
../../gpr2make$(exeext): ../stamp-tools
$(GNATMAKE) -c $(ADA_INCLUDES) gpr2make --GCC="$(CC) $(ALL_ADAFLAGS)"
$(GNATBIND) $(ADA_INCLUDES) $(GNATBIND_FLAGS) gpr2make
@@ -1656,7 +1544,7 @@ endif
$(GNATBIND) $(ADA_INCLUDES) $(GNATBIND_FLAGS) vxaddr2line
$(GNATLINK) -v vxaddr2line -o $@ --GCC="$(CC) $(ADA_INCLUDES)" $(CLIB)
-gnatmake-re: ../stamp-tools
+gnatmake-re: ../stamp-tools link.o
$(GNATMAKE) $(ADA_INCLUDES) -u sdefault --GCC="$(CC) $(MOST_ADA_FLAGS)"
$(GNATMAKE) -c $(ADA_INCLUDES) gnatmake --GCC="$(CC) $(ALL_ADAFLAGS)"
$(GNATBIND) $(ADA_INCLUDES) $(GNATBIND_FLAGS) gnatmake
@@ -1669,7 +1557,7 @@ gnatlink-re: ../stamp-tools link.o
$(GNATMAKE) -c $(ADA_INCLUDES) gnatlink --GCC="$(CC) $(ALL_ADAFLAGS)"
$(GNATBIND) $(ADA_INCLUDES) $(GNATBIND_FLAGS) gnatlink
$(GNATLINK) -v gnatlink -o ../../gnatlinknew$(exeext) \
- --GCC="$(CC) $(ADA_INCLUDES)" link.o $(TOOLS_LIBS)
+ --GCC="$(CC) $(ADA_INCLUDES)" $(TOOLS_LIBS)
$(MV) ../../gnatlinknew$(exeext) ../../gnatlink$(exeext)
# Needs to be built with CC=gcc
@@ -1677,11 +1565,11 @@ gnatlink-re: ../stamp-tools link.o
# stamp target in the parent directory whenever gnat1 is rebuilt
# Likewise for the tools
-../../gnatmake$(exeext): $(P) b_gnatm.o $(GNATMAKE_OBJS)
+../../gnatmake$(exeext): $(P) b_gnatm.o link.o $(GNATMAKE_OBJS)
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ b_gnatm.o $(GNATMAKE_OBJS) \
$(TOOLS_LIBS)
-../../gnatlink$(exeext): $(P) b_gnatl.o $(GNATLINK_OBJS)
+../../gnatlink$(exeext): $(P) b_gnatl.o link.o $(GNATLINK_OBJS)
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ b_gnatl.o $(GNATLINK_OBJS) \
$(TOOLS_LIBS)
@@ -1719,8 +1607,9 @@ install-gnatlib: ../stamp-gnatlib
$(INSTALL_DATA_DATE) $$file $(DESTDIR)$(ADA_RTL_OBJ_DIR); \
done
-$(INSTALL_DATA) rts/g-trasym$(objext) $(DESTDIR)$(ADA_RTL_OBJ_DIR)
- -for file in rts/*$(arext);do \
+ -cd rts; for file in *$(arext);do \
$(INSTALL_DATA) $$file $(DESTDIR)$(ADA_RTL_OBJ_DIR); \
+ $(RANLIB) $(DESTDIR)$(ADA_RTL_OBJ_DIR)/$$file; \
done
# Install the shared libraries, if any, using $(INSTALL) instead
# of $(INSTALL_DATA). The latter may force a mode inappropriate
@@ -1808,98 +1697,17 @@ gnatlib: ../stamp-gnatlib1 ../stamp-gnatlib2
ifneq ($(PREFIX_OBJS),)
$(AR) $(AR_FLAGS) rts/libgccprefix$(arext) $(PREFIX_OBJS);
endif
- if $(RANLIB_TEST) ; then $(RANLIB) rts/libgnat$(arext); else true; fi
+ -$(RANLIB) rts/libgnat$(arext)
$(AR) $(AR_FLAGS) rts/libgnarl$(arext) \
$(addprefix rts/,$(GNATRTL_TASKING_OBJS))
- if $(RANLIB_TEST) ; then $(RANLIB) rts/libgnarl$(arext); else true; fi
+ -$(RANLIB) rts/libgnarl$(arext)
ifeq ($(GMEM_LIB),gmemlib)
- $(AR) $(AR_FLAGS) rts/libgmem$(arext) rts/memtrack.o;
+ $(AR) $(AR_FLAGS) rts/libgmem$(arext) rts/memtrack.o
+ -$(RANLIB) rts/libgmem$(arext)
endif
$(CHMOD) a-wx rts/*.ali
touch ../stamp-gnatlib
-HIE_NONE_TARGET_PAIRS=\
- a-except.ads<1aexcept.ads \
- a-except.adb<1aexcept.adb \
- a-tags.ads<1atags.ads \
- a-tags.adb<1atags.adb \
- s-secsta.ads<1ssecsta.ads \
- s-secsta.adb<1ssecsta.adb \
- i-c.ads<1ic.ads $(EXTRA_HIE_NONE_TARGET_PAIRS)
-
-# This target needs RTS_NAME, RTS_SRCS, RTS_TARGET_PAIRS to be set properly
-# it creates a rts with the proper structure and the right target
-# dependant srcs
-prepare-rts:
- $(RMDIR) rts-$(RTS_NAME)
- $(MKDIR) rts-$(RTS_NAME)
- $(CHMOD) u+w rts-$(RTS_NAME)
- $(MKDIR) rts-$(RTS_NAME)/adalib
- $(MKDIR) rts-$(RTS_NAME)/adainclude
- $(CHMOD) u+w rts-$(RTS_NAME)/*
-# Generate the project file
- $(ECHO) "project $(RTS_NAME) is" > rts-$(RTS_NAME)/$(RTS_NAME).gpr
- $(ECHO) " for Source_Dirs use (\"adainclude\");" \
- >> rts-$(RTS_NAME)/$(RTS_NAME).gpr
- $(ECHO) " for Object_Dir use \"adalib\";" \
- >> rts-$(RTS_NAME)/$(RTS_NAME).gpr
- $(ECHO) " for Source_List_File use " \
- >>rts-$(RTS_NAME)/$(RTS_NAME).gpr
- $(ECHO) " \"rts-$(RTS_NAME)_source_list.txt\";" \
- >>rts-$(RTS_NAME)/$(RTS_NAME).gpr
- $(ECHO) " package Builder is" >>rts-$(RTS_NAME)/$(RTS_NAME).gpr
- $(ECHO) " for Default_Switches (\"Ada\") use (\"-a\");" \
- >>rts-$(RTS_NAME)/$(RTS_NAME).gpr
- $(ECHO) " end Builder;" >>rts-$(RTS_NAME)/$(RTS_NAME).gpr
- $(ECHO) " package Compiler is" >> rts-$(RTS_NAME)/$(RTS_NAME).gpr
- $(ECHO) " for Default_Switches (\"Ada\") use (\"-nostdinc\");" \
- >>rts-$(RTS_NAME)/$(RTS_NAME).gpr
- $(ECHO) " end Compiler;" >>rts-$(RTS_NAME)/$(RTS_NAME).gpr
- $(ECHO) "end $(RTS_NAME);" >>rts-$(RTS_NAME)/$(RTS_NAME).gpr
-
- $(foreach f, $(COMPILABLE_SOURCES), \
- $(ECHO) $(f) >> \
- rts-$(RTS_NAME)/rts-$(RTS_NAME)_source_list.txt ;) true
-# Copy target independent sources
- $(foreach f,$(RTS_SRCS), \
- $(CP) $(fsrcpfx)$(f) rts-$(RTS_NAME)/adainclude/ ;) true
-# Remove files to be replaced by target dependent sources
- $(RM) $(foreach PAIR,$(RTS_TARGET_PAIRS), \
- rts-$(RTS_NAME)/adainclude/$(word 1,$(subst <, ,$(PAIR))))
-# Copy new target dependent sources
- $(foreach PAIR,$(RTS_TARGET_PAIRS), \
- $(CP) $(fsrcpfx)$(word 2,$(subst <, ,$(PAIR))) \
- rts-$(RTS_NAME)/adainclude/$(word 1,$(subst <, ,$(PAIR)));)
-
-install-rts: force
- $(CP) -r rts-$(RTS_NAME) $(DESTDIR)$(libsubdir)/
-
-rts-zfp: force
- $(MAKE) $(FLAGS_TO_PASS) prepare-rts \
- RTS_NAME=zfp RTS_SRCS="$(HIE_SOURCES)" \
- RTS_TARGET_PAIRS="$(HIE_NONE_TARGET_PAIRS)" \
- COMPILABLE_SOURCES="$(COMPILABLE_HIE_SOURCES)"
- $(GNATMAKE) -Prts-zfp/zfp.gpr --GCC="../../../xgcc -B../../../"
- cd rts-zfp/adalib/ ; $(AR) r libgnat.a *.o
- $(RM) rts-zfp/adalib/*.o
- $(CHMOD) a-wx rts-zfp/adalib/*.ali
- $(CHMOD) a-wx rts-zfp/adalib/libgnat.a
-
-rts-ravenscar: force
- $(MAKE) $(FLAGS_TO_PASS) prepare-rts \
- RTS_NAME=ravenscar RTS_SRCS="$(RAVEN_SOURCES)" \
- RTS_TARGET_PAIRS="$(HIE_RAVEN_TARGET_PAIRS)" \
- COMPILABLE_SOURCES="$(COMPILABLE_RAVEN_SOURCES)"
- $(GNATMAKE) -Prts-ravenscar/ravenscar.gpr \
- --GCC="../../../xgcc -B../../../"
- cd rts-ravenscar/adalib ; \
- $(foreach FILE,$(RAVEN_LIBGNARL_OBJS), $(AR) r libgnarl.a $(FILE);) \
- $(foreach FILE,$(HIE_OBJS), $(AR) r libgnat.a $(FILE);)
- $(RM) rts-ravenscar/adalib/*.o
- $(CHMOD) a-wx rts-ravenscar/adalib/*.ali
- $(CHMOD) a-wx rts-ravenscar/adalib/libgnat.a
- $(CHMOD) a-wx rts-ravenscar/adalib/libgnarl.a
-
# Warning: this target assumes that LIBRARY_VERSION has been set correctly.
gnatlib-shared-default:
$(MAKE) $(FLAGS_TO_PASS) \
@@ -1907,7 +1715,7 @@ gnatlib-shared-default:
GNATLIBCFLAGS="$(GNATLIBCFLAGS) $(TARGET_LIBGCC2_CFLAGS)" \
THREAD_KIND="$(THREAD_KIND)" \
gnatlib
- $(RM) rts/libgnat$(soext) rts/libgnarl$(soext)
+ $(RM) rts/libgna*$(soext)
cd rts; ../../xgcc -B../../ -shared $(TARGET_LIBGCC2_CFLAGS) \
-o libgnat$(hyphen)$(LIBRARY_VERSION)$(soext) \
$(GNATRTL_NONTASKING_OBJS) $(LIBGNAT_OBJS) \
@@ -1963,7 +1771,7 @@ gnatlib-shared-win32:
GNATLIBCFLAGS="$(GNATLIBCFLAGS) $(TARGET_LIBGCC2_CFLAGS)" \
THREAD_KIND="$(THREAD_KIND)" \
gnatlib
- $(RM) rts/libgnat$(soext) rts/libgnarl$(soext)
+ $(RM) rts/libgna*$(soext)
cd rts; ../../xgcc -B../../ -shared $(TARGET_LIBGCC2_CFLAGS) \
-o libgnat$(hyphen)$(LIBRARY_VERSION)$(soext) \
$(GNATRTL_NONTASKING_OBJS) $(LIBGNAT_OBJS) \
@@ -1980,7 +1788,7 @@ gnatlib-shared-vms:
GNATLIBCFLAGS="$(GNATLIBCFLAGS)" \
THREAD_KIND="$(THREAD_KIND)" \
gnatlib
- $(RM) rts/libgnat*$(soext) rts/libgnarl*$(soext)
+ $(RM) rts/libgna*$(soext)
cd rts && echo "case_sensitive=yes" > SYMVEC_$$$$.opt && \
objdump --syms $(LIBGNAT_OBJS) $(GNATRTL_NONTASKING_OBJS) | \
$(SHLIB_SYMVEC) >> SYMVEC_$$$$.opt && \
@@ -2020,6 +1828,15 @@ gnatlib-sjlj: ../stamp-gnatlib1
THREAD_KIND="$(THREAD_KIND)" \
TARGET_LIBGCC2_CFLAGS="$(TARGET_LIBGCC2_CFLAGS)" gnatlib
+gnatlib-zcx: ../stamp-gnatlib1
+ sed -e 's/ZCX_By_Default.*/ZCX_By_Default : constant Boolean := True;/' rts/system.ads > rts/s.ads
+ $(MV) rts/s.ads rts/system.ads
+ $(MAKE) $(FLAGS_TO_PASS) \
+ GNATLIBFLAGS="$(GNATLIBFLAGS)" \
+ GNATLIBCFLAGS="$(GNATLIBCFLAGS)" \
+ THREAD_KIND="$(THREAD_KIND)" \
+ TARGET_LIBGCC2_CFLAGS="$(TARGET_LIBGCC2_CFLAGS)" gnatlib
+
# .s files for cross-building
gnat-cross: force
make $(GNAT1_ADA_OBJS) CC="gcc -B../stage1/" CFLAGS="-S -gnatp"
diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl
index 3fe48f3016c..9e45d01e1b7 100644
--- a/gcc/ada/Makefile.rtl
+++ b/gcc/ada/Makefile.rtl
@@ -270,6 +270,7 @@ GNATRTL_NONTASKING_OBJS= \
ioexcept$(objext) \
machcode$(objext) \
s-addima$(objext) \
+ s-addope$(objext) \
s-arit64$(objext) \
s-assert$(objext) \
s-atacco$(objext) \
diff --git a/gcc/ada/a-caldel-vms.adb b/gcc/ada/a-caldel-vms.adb
new file mode 100644
index 00000000000..a95eae657b8
--- /dev/null
+++ b/gcc/ada/a-caldel-vms.adb
@@ -0,0 +1,99 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- A D A . C A L E N D A R . D E L A Y S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2003, Ada Core Technologies --
+-- --
+-- 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, 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, --
+-- 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 is the Alpha/VMS version.
+
+with System.OS_Primitives;
+-- Used for Max_Sensible_Delay
+
+with System.Soft_Links;
+-- Used for Timed_Delay
+
+package body Ada.Calendar.Delays is
+
+ package OSP renames System.OS_Primitives;
+ package TSL renames System.Soft_Links;
+
+ use type TSL.Timed_Delay_Call;
+
+ ---------------
+ -- Delay_For --
+ ---------------
+
+ procedure Delay_For (D : Duration) is
+ begin
+ TSL.Timed_Delay.all
+ (Duration'Min (D, OSP.Max_Sensible_Delay), OSP.Relative);
+ end Delay_For;
+
+ -----------------
+ -- Delay_Until --
+ -----------------
+
+ procedure Delay_Until (T : Time) is
+ begin
+ TSL.Timed_Delay.all (To_Duration (T), OSP.Absolute_Calendar);
+ end Delay_Until;
+
+ -----------------
+ -- To_Duration --
+ -----------------
+
+ function To_Duration (T : Time) return Duration is
+ begin
+ return OSP.To_Duration (OSP.OS_Time (T), OSP.Absolute_Calendar);
+ end To_Duration;
+
+ --------------------
+ -- Timed_Delay_NT --
+ --------------------
+
+ procedure Timed_Delay_NT (Time : Duration; Mode : Integer);
+
+ procedure Timed_Delay_NT (Time : Duration; Mode : Integer) is
+ begin
+ OSP.Timed_Delay (Time, Mode);
+ end Timed_Delay_NT;
+
+begin
+ -- Set up the Timed_Delay soft link to the non tasking version if it has
+ -- not been already set.
+ -- If tasking is present, Timed_Delay has already set this soft link, or
+ -- this will be overriden during the elaboration of
+ -- System.Tasking.Initialization
+
+ if TSL.Timed_Delay = null then
+ TSL.Timed_Delay := Timed_Delay_NT'Access;
+ end if;
+end Ada.Calendar.Delays;
diff --git a/gcc/ada/a-calend-mingw.adb b/gcc/ada/a-calend-mingw.adb
new file mode 100644
index 00000000000..25f8cc4720b
--- /dev/null
+++ b/gcc/ada/a-calend-mingw.adb
@@ -0,0 +1,394 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- A D A . C A L E N D A R --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1997-2002 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the Windows NT/95 version.
+
+with System.OS_Primitives;
+-- used for Clock
+
+with System.OS_Interface;
+
+package body Ada.Calendar is
+
+ use System.OS_Interface;
+
+ ------------------------------
+ -- Use of Pragma Unsuppress --
+ ------------------------------
+
+ -- This implementation of Calendar takes advantage of the permission in
+ -- Ada 95 of using arithmetic overflow checks to check for out of bounds
+ -- time values. This means that we must catch the constraint error that
+ -- results from arithmetic overflow, so we use pragma Unsuppress to make
+ -- sure that overflow is enabled, using software overflow checking if
+ -- necessary. That way, compiling Calendar with options to suppress this
+ -- checking will not affect its correctness.
+
+ ------------------------
+ -- Local Declarations --
+ ------------------------
+
+ Ada_Year_Min : constant := 1901;
+ Ada_Year_Max : constant := 2099;
+
+ -- Win32 time constants
+
+ 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;
+
+ ---------
+ -- "+" --
+ ---------
+
+ function "+" (Left : Time; Right : Duration) return Time is
+ pragma Unsuppress (Overflow_Check);
+ begin
+ return (Left + Time (Right));
+
+ exception
+ when Constraint_Error =>
+ raise Time_Error;
+ end "+";
+
+ function "+" (Left : Duration; Right : Time) return Time is
+ pragma Unsuppress (Overflow_Check);
+ begin
+ return (Time (Left) + Right);
+
+ exception
+ when Constraint_Error =>
+ raise Time_Error;
+ end "+";
+
+ ---------
+ -- "-" --
+ ---------
+
+ function "-" (Left : Time; Right : Duration) return Time is
+ pragma Unsuppress (Overflow_Check);
+ begin
+ return Left - Time (Right);
+
+ exception
+ when Constraint_Error =>
+ raise Time_Error;
+ end "-";
+
+ function "-" (Left : Time; Right : Time) return Duration is
+ pragma Unsuppress (Overflow_Check);
+ begin
+ return Duration (Left) - Duration (Right);
+
+ exception
+ when Constraint_Error =>
+ raise Time_Error;
+ end "-";
+
+ ---------
+ -- "<" --
+ ---------
+
+ function "<" (Left, Right : Time) return Boolean is
+ begin
+ return Duration (Left) < Duration (Right);
+ end "<";
+
+ ----------
+ -- "<=" --
+ ----------
+
+ function "<=" (Left, Right : Time) return Boolean is
+ begin
+ return Duration (Left) <= Duration (Right);
+ end "<=";
+
+ ---------
+ -- ">" --
+ ---------
+
+ function ">" (Left, Right : Time) return Boolean is
+ begin
+ return Duration (Left) > Duration (Right);
+ end ">";
+
+ ----------
+ -- ">=" --
+ ----------
+
+ function ">=" (Left, Right : Time) return Boolean is
+ begin
+ return Duration (Left) >= Duration (Right);
+ end ">=";
+
+ -----------
+ -- Clock --
+ -----------
+
+ -- The Ada.Calendar.Clock function gets the time from the soft links
+ -- interface which will call the appropriate function depending wether
+ -- tasking is involved or not.
+
+ function Clock return Time is
+ begin
+ return Time (System.OS_Primitives.Clock);
+ end Clock;
+
+ ---------
+ -- Day --
+ ---------
+
+ function Day (Date : Time) return Day_Number is
+ DY : Year_Number;
+ DM : Month_Number;
+ DD : Day_Number;
+ DS : Day_Duration;
+
+ begin
+ Split (Date, DY, DM, DD, DS);
+ return DD;
+ end Day;
+
+ -----------
+ -- Month --
+ -----------
+
+ function Month (Date : Time) return Month_Number is
+ DY : Year_Number;
+ DM : Month_Number;
+ DD : Day_Number;
+ DS : Day_Duration;
+
+ begin
+ Split (Date, DY, DM, DD, DS);
+ return DM;
+ end Month;
+
+ -------------
+ -- Seconds --
+ -------------
+
+ function Seconds (Date : Time) return Day_Duration is
+ DY : Year_Number;
+ DM : Month_Number;
+ DD : Day_Number;
+ DS : Day_Duration;
+
+ begin
+ Split (Date, DY, DM, DD, DS);
+ return DS;
+ end Seconds;
+
+ -----------
+ -- Split --
+ -----------
+
+ procedure Split
+ (Date : Time;
+ Year : out Year_Number;
+ Month : out Month_Number;
+ Day : out Day_Number;
+ Seconds : out Day_Duration)
+ is
+
+ Date_Int : aliased Long_Long_Integer;
+ Date_Loc : aliased Long_Long_Integer;
+ Timbuf : aliased SYSTEMTIME;
+ Int_Date : Long_Long_Integer;
+ Sub_Seconds : Duration;
+
+ begin
+ -- We take the sub-seconds (decimal part) of Date and this is added
+ -- to compute the Seconds. This way we keep the precision of the
+ -- high-precision clock that was lost with the Win32 API calls
+ -- below.
+
+ if Date < 0.0 then
+
+ -- this is a Date before Epoch (January 1st, 1970)
+
+ Sub_Seconds := Duration (Date) -
+ Duration (Long_Long_Integer (Date + Duration'(0.5)));
+
+ Int_Date := Long_Long_Integer (Date - Sub_Seconds);
+
+ -- For Date = -86400.1 we are 2 days before Epoch at 0.1 seconds
+ -- from day 1 before Epoch. It means that it is 23h 59m 59.9s.
+ -- here we adjust for that.
+
+ if Sub_Seconds < 0.0 then
+ Int_Date := Int_Date - 1;
+ Sub_Seconds := 1.0 + Sub_Seconds;
+ end if;
+
+ else
+
+ -- this is a Date after Epoch (January 1st, 1970)
+
+ Sub_Seconds := Duration (Date) -
+ Duration (Long_Long_Integer (Date - Duration'(0.5)));
+
+ Int_Date := Long_Long_Integer (Date - Sub_Seconds);
+
+ end if;
+
+ -- Date_Int is the number of seconds from Epoch.
+
+ Date_Int := Long_Long_Integer
+ (Int_Date * Sec_Unit / system_time_ns) + epoch_1970;
+
+ if not FileTimeToLocalFileTime (Date_Int'Access, Date_Loc'Access) then
+ raise Time_Error;
+ end if;
+
+ if not FileTimeToSystemTime (Date_Loc'Access, Timbuf'Access) then
+ raise Time_Error;
+ end if;
+
+ if Timbuf.wYear not in Ada_Year_Min .. Ada_Year_Max then
+ raise Time_Error;
+ end if;
+
+ Seconds :=
+ Duration (Timbuf.wHour) * 3_600.0 +
+ Duration (Timbuf.wMinute) * 60.0 +
+ Duration (Timbuf.wSecond) +
+ Sub_Seconds;
+
+ Day := Integer (Timbuf.wDay);
+ Month := Integer (Timbuf.wMonth);
+ Year := Integer (Timbuf.wYear);
+ end Split;
+
+ -------------
+ -- Time_Of --
+ -------------
+
+ function Time_Of
+ (Year : Year_Number;
+ Month : Month_Number;
+ Day : Day_Number;
+ Seconds : Day_Duration := 0.0)
+ return Time
+ is
+
+ Timbuf : aliased SYSTEMTIME;
+ Now : aliased Long_Long_Integer;
+ Loc : aliased Long_Long_Integer;
+ Int_Secs : Integer;
+ Secs : Integer;
+ Add_One_Day : Boolean := False;
+ Date : Time;
+
+ begin
+ -- The following checks are redundant with respect to the constraint
+ -- error checks that should normally be made on parameters, but we
+ -- decide to raise Constraint_Error in any case if bad values come
+ -- in (as a result of checks being off in the caller, or for other
+ -- erroneous or bounded error cases).
+
+ if not Year 'Valid
+ or else not Month 'Valid
+ or else not Day 'Valid
+ or else not Seconds'Valid
+ then
+ raise Constraint_Error;
+ end if;
+
+ if Seconds = 0.0 then
+ Int_Secs := 0;
+ else
+ Int_Secs := Integer (Seconds - 0.5);
+ end if;
+
+ -- Timbuf.wMillisec is to keep the msec. We can't use that because the
+ -- high-resolution clock has a precision of 1 Microsecond.
+ -- Anyway the sub-seconds part is not needed to compute the number
+ -- of seconds in UTC.
+
+ if Int_Secs = 86_400 then
+ Secs := 0;
+ Add_One_Day := True;
+ else
+ Secs := Int_Secs;
+ end if;
+
+ Timbuf.wMilliseconds := 0;
+ Timbuf.wSecond := WORD (Secs mod 60);
+ Timbuf.wMinute := WORD ((Secs / 60) mod 60);
+ Timbuf.wHour := WORD (Secs / 3600);
+ Timbuf.wDay := WORD (Day);
+ Timbuf.wMonth := WORD (Month);
+ Timbuf.wYear := WORD (Year);
+
+ if not SystemTimeToFileTime (Timbuf'Access, Loc'Access) then
+ raise Time_Error;
+ end if;
+
+ if not LocalFileTimeToFileTime (Loc'Access, Now'Access) then
+ raise Time_Error;
+ end if;
+
+ -- Here we have the UTC now translate UTC to Epoch time (UNIX style
+ -- time based on 1 january 1970) and add there the sub-seconds part.
+
+ declare
+ Sub_Sec : constant Duration := Seconds - Duration (Int_Secs);
+ begin
+ Date := Time ((Now - epoch_1970) * system_time_ns / Sec_Unit) +
+ Sub_Sec;
+ end;
+
+ if Add_One_Day then
+ Date := Date + Duration (86400.0);
+ end if;
+
+ return Date;
+ end Time_Of;
+
+ ----------
+ -- Year --
+ ----------
+
+ function Year (Date : Time) return Year_Number is
+ DY : Year_Number;
+ DM : Month_Number;
+ DD : Day_Number;
+ DS : Day_Duration;
+
+ begin
+ Split (Date, DY, DM, DD, DS);
+ return DY;
+ end Year;
+
+end Ada.Calendar;
diff --git a/gcc/ada/a-calend-vms.adb b/gcc/ada/a-calend-vms.adb
new file mode 100644
index 00000000000..74c2923cbf2
--- /dev/null
+++ b/gcc/ada/a-calend-vms.adb
@@ -0,0 +1,361 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- A D A . C A L E N D A R --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the Alpha/VMS version.
+
+with System.Aux_DEC; use System.Aux_DEC;
+
+package body Ada.Calendar is
+
+ ------------------------------
+ -- Use of Pragma Unsuppress --
+ ------------------------------
+
+ -- This implementation of Calendar takes advantage of the permission in
+ -- Ada 95 of using arithmetic overflow checks to check for out of bounds
+ -- time values. This means that we must catch the constraint error that
+ -- results from arithmetic overflow, so we use pragma Unsuppress to make
+ -- sure that overflow is enabled, using software overflow checking if
+ -- necessary. That way, compiling Calendar with options to suppress this
+ -- checking will not affect its correctness.
+
+ ------------------------
+ -- Local Declarations --
+ ------------------------
+
+ Ada_Year_Min : constant := 1901;
+ Ada_Year_Max : constant := 2099;
+
+ -- Some basic constants used throughout
+
+ function To_Relative_Time (D : Duration) return Time;
+
+ function To_Relative_Time (D : Duration) return Time is
+ begin
+ return Time (Long_Integer'Integer_Value (D) / 100);
+ end To_Relative_Time;
+
+ ---------
+ -- "+" --
+ ---------
+
+ function "+" (Left : Time; Right : Duration) return Time is
+ pragma Unsuppress (Overflow_Check);
+ begin
+ return (Left + To_Relative_Time (Right));
+
+ exception
+ when Constraint_Error =>
+ raise Time_Error;
+ end "+";
+
+ function "+" (Left : Duration; Right : Time) return Time is
+ pragma Unsuppress (Overflow_Check);
+ begin
+ return (To_Relative_Time (Left) + Right);
+
+ exception
+ when Constraint_Error =>
+ raise Time_Error;
+ end "+";
+
+ ---------
+ -- "-" --
+ ---------
+
+ function "-" (Left : Time; Right : Duration) return Time is
+ pragma Unsuppress (Overflow_Check);
+ begin
+ return Left - To_Relative_Time (Right);
+
+ exception
+ when Constraint_Error =>
+ raise Time_Error;
+ end "-";
+
+ function "-" (Left : Time; Right : Time) return Duration is
+ pragma Unsuppress (Overflow_Check);
+ begin
+ return Duration'Fixed_Value
+ ((Long_Integer (Left) - Long_Integer (Right)) * 100);
+
+ exception
+ when Constraint_Error =>
+ raise Time_Error;
+ end "-";
+
+ ---------
+ -- "<" --
+ ---------
+
+ function "<" (Left, Right : Time) return Boolean is
+ begin
+ return Long_Integer (Left) < Long_Integer (Right);
+ end "<";
+
+ ----------
+ -- "<=" --
+ ----------
+
+ function "<=" (Left, Right : Time) return Boolean is
+ begin
+ return Long_Integer (Left) <= Long_Integer (Right);
+ end "<=";
+
+ ---------
+ -- ">" --
+ ---------
+
+ function ">" (Left, Right : Time) return Boolean is
+ begin
+ return Long_Integer (Left) > Long_Integer (Right);
+ end ">";
+
+ ----------
+ -- ">=" --
+ ----------
+
+ function ">=" (Left, Right : Time) return Boolean is
+ begin
+ return Long_Integer (Left) >= Long_Integer (Right);
+ end ">=";
+
+ -----------
+ -- Clock --
+ -----------
+
+ -- The Ada.Calendar.Clock function gets the time.
+ -- Note that on other targets a soft-link is used to get a different clock
+ -- depending whether tasking is used or not. On VMS this isn't needed
+ -- since all clock calls end up using SYS$GETTIM, so call the
+ -- OS_Primitives version for efficiency.
+
+ function Clock return Time is
+ begin
+ return Time (OSP.OS_Clock);
+ end Clock;
+
+ ---------
+ -- Day --
+ ---------
+
+ function Day (Date : Time) return Day_Number is
+ DY : Year_Number;
+ DM : Month_Number;
+ DD : Day_Number;
+ DS : Day_Duration;
+
+ begin
+ Split (Date, DY, DM, DD, DS);
+ return DD;
+ end Day;
+
+ -----------
+ -- Month --
+ -----------
+
+ function Month (Date : Time) return Month_Number is
+ DY : Year_Number;
+ DM : Month_Number;
+ DD : Day_Number;
+ DS : Day_Duration;
+
+ begin
+ Split (Date, DY, DM, DD, DS);
+ return DM;
+ end Month;
+
+ -------------
+ -- Seconds --
+ -------------
+
+ function Seconds (Date : Time) return Day_Duration is
+ DY : Year_Number;
+ DM : Month_Number;
+ DD : Day_Number;
+ DS : Day_Duration;
+
+ begin
+ Split (Date, DY, DM, DD, DS);
+ return DS;
+ end Seconds;
+
+ -----------
+ -- Split --
+ -----------
+
+ procedure Split
+ (Date : Time;
+ Year : out Year_Number;
+ Month : out Month_Number;
+ Day : out Day_Number;
+ Seconds : out Day_Duration)
+ is
+ procedure Numtim (
+ Status : out Unsigned_Longword;
+ Timbuf : out Unsigned_Word_Array;
+ Timadr : in Time);
+
+ pragma Interface (External, Numtim);
+
+ pragma Import_Valued_Procedure (Numtim, "SYS$NUMTIM",
+ (Unsigned_Longword, Unsigned_Word_Array, Time),
+ (Value, Reference, Reference));
+
+ Status : Unsigned_Longword;
+ Timbuf : Unsigned_Word_Array (1 .. 7);
+
+ Subsecs : constant Time := Date mod 10_000_000;
+ Date_Secs : constant Time := Date - Subsecs;
+
+ begin
+ Numtim (Status, Timbuf, Date_Secs);
+
+ if Status mod 2 /= 1
+ or else Timbuf (1) not in Ada_Year_Min .. Ada_Year_Max
+ then
+ raise Time_Error;
+ end if;
+
+ Seconds := Day_Duration (Timbuf (6)
+ + 60 * (Timbuf (5) + 60 * Timbuf (4)))
+ + Duration (Subsecs) / 10_000_000.0;
+
+ Day := Integer (Timbuf (3));
+ Month := Integer (Timbuf (2));
+ Year := Integer (Timbuf (1));
+ end Split;
+
+ -------------
+ -- Time_Of --
+ -------------
+
+ function Time_Of
+ (Year : Year_Number;
+ Month : Month_Number;
+ Day : Day_Number;
+ Seconds : Day_Duration := 0.0)
+ return Time
+ is
+
+ procedure Cvt_Vectim (
+ Status : out Unsigned_Longword;
+ Input_Time : in Unsigned_Word_Array;
+ Resultant_Time : out Time);
+
+ pragma Interface (External, Cvt_Vectim);
+
+ pragma Import_Valued_Procedure (Cvt_Vectim, "LIB$CVT_VECTIM",
+ (Unsigned_Longword, Unsigned_Word_Array, Time),
+ (Value, Reference, Reference));
+
+ Status : Unsigned_Longword;
+ Timbuf : Unsigned_Word_Array (1 .. 7);
+ Date : Time;
+ Int_Secs : Integer;
+ Day_Hack : Boolean := False;
+ Subsecs : Day_Duration;
+
+ begin
+ -- The following checks are redundant with respect to the constraint
+ -- error checks that should normally be made on parameters, but we
+ -- decide to raise Constraint_Error in any case if bad values come
+ -- in (as a result of checks being off in the caller, or for other
+ -- erroneous or bounded error cases).
+
+ if not Year 'Valid
+ or else not Month 'Valid
+ or else not Day 'Valid
+ or else not Seconds'Valid
+ then
+ raise Constraint_Error;
+ end if;
+
+ -- Truncate seconds value by subtracting 0.5 and rounding,
+ -- but be careful with 0.0 since that will give -1.0 unless
+ -- it is treated specially.
+
+ if Seconds > 0.0 then
+ Int_Secs := Integer (Seconds - 0.5);
+ else
+ Int_Secs := Integer (Seconds);
+ end if;
+
+ Subsecs := Seconds - Day_Duration (Int_Secs);
+
+ -- Cvt_Vectim barfs on the largest Day_Duration, so trick it by
+ -- setting it to zero and then adding the difference after conversion.
+
+ if Int_Secs = 86_400 then
+ Int_Secs := 0;
+ Day_Hack := True;
+ end if;
+
+ Timbuf (7) := 0;
+ Timbuf (6) := Unsigned_Word (Int_Secs mod 60);
+ Timbuf (5) := Unsigned_Word ((Int_Secs / 60) mod 60);
+ Timbuf (4) := Unsigned_Word (Int_Secs / 3600);
+ Timbuf (3) := Unsigned_Word (Day);
+ Timbuf (2) := Unsigned_Word (Month);
+ Timbuf (1) := Unsigned_Word (Year);
+
+ Cvt_Vectim (Status, Timbuf, Date);
+
+ if Status mod 2 /= 1 then
+ raise Time_Error;
+ end if;
+
+ if Day_Hack then
+ Date := Date + 10_000_000 * 86_400;
+ end if;
+
+ Date := Date + Time (10_000_000.0 * Subsecs);
+ return Date;
+ end Time_Of;
+
+ ----------
+ -- Year --
+ ----------
+
+ function Year (Date : Time) return Year_Number is
+ DY : Year_Number;
+ DM : Month_Number;
+ DD : Day_Number;
+ DS : Day_Duration;
+
+ begin
+ Split (Date, DY, DM, DD, DS);
+ return DY;
+ end Year;
+
+end Ada.Calendar;
diff --git a/gcc/ada/a-calend-vms.ads b/gcc/ada/a-calend-vms.ads
new file mode 100644
index 00000000000..6704346cf70
--- /dev/null
+++ b/gcc/ada/a-calend-vms.ads
@@ -0,0 +1,121 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUNTIME COMPONENTS --
+-- --
+-- A D A . C A L E N D A R --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1992-2002 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the Alpha/VMS version.
+
+with System.OS_Primitives;
+package Ada.Calendar is
+
+ package OSP renames System.OS_Primitives;
+
+ type Time is private;
+
+ -- Declarations representing limits of allowed local time values. Note that
+ -- these do NOT constrain the possible stored values of time which may well
+ -- permit a larger range of times (this is explicitly allowed in Ada 95).
+
+ subtype Year_Number is Integer range 1901 .. 2099;
+ subtype Month_Number is Integer range 1 .. 12;
+ subtype Day_Number is Integer range 1 .. 31;
+
+ subtype Day_Duration is Duration range 0.0 .. 86_400.0;
+
+ function Clock return Time;
+
+ function Year (Date : Time) return Year_Number;
+ function Month (Date : Time) return Month_Number;
+ function Day (Date : Time) return Day_Number;
+ function Seconds (Date : Time) return Day_Duration;
+
+ procedure Split
+ (Date : Time;
+ Year : out Year_Number;
+ Month : out Month_Number;
+ Day : out Day_Number;
+ Seconds : out Day_Duration);
+
+ function Time_Of
+ (Year : Year_Number;
+ Month : Month_Number;
+ Day : Day_Number;
+ Seconds : Day_Duration := 0.0)
+ return Time;
+
+ function "+" (Left : Time; Right : Duration) return Time;
+ function "+" (Left : Duration; Right : Time) return Time;
+ function "-" (Left : Time; Right : Duration) return Time;
+ function "-" (Left : Time; Right : Time) return Duration;
+
+ function "<" (Left, Right : Time) return Boolean;
+ function "<=" (Left, Right : Time) return Boolean;
+ function ">" (Left, Right : Time) return Boolean;
+ function ">=" (Left, Right : Time) return Boolean;
+
+ Time_Error : exception;
+
+private
+
+ pragma Inline (Clock);
+
+ pragma Inline (Year);
+ pragma Inline (Month);
+ pragma Inline (Day);
+
+ pragma Inline ("+");
+ pragma Inline ("-");
+
+ pragma Inline ("<");
+ pragma Inline ("<=");
+ pragma Inline (">");
+ pragma Inline (">=");
+
+ -- Time is represented as the number of 100-nanosecond (ns) units offset
+ -- from the system base date and time, which is 00:00 o'clock,
+ -- November 17, 1858 (the Smithsonian base date and time for the
+ -- astronomic calendar).
+
+ -- The time value stored is typically a GMT value, as provided in standard
+ -- Unix environments. If this is the case then Split and Time_Of perform
+ -- required conversions to and from local times.
+
+ type Time is new OSP.OS_Time;
+
+ -- Notwithstanding this definition, Time is not quite the same as OS_Time.
+ -- Relative Time is positive, whereas relative OS_Time is negative,
+ -- but this declaration makes for easier conversion.
+
+end Ada.Calendar;
diff --git a/gcc/ada/a-calend.adb b/gcc/ada/a-calend.adb
index 1715d7f0ecb..fdab0cb5572 100644
--- a/gcc/ada/a-calend.adb
+++ b/gcc/ada/a-calend.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2001 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -89,14 +89,20 @@ package body Ada.Calendar is
-- TM.all cannot be represented.
-- The following constants are used in adjusting Ada dates so that they
- -- fit into the range that can be handled by Unix (1970 - 2038). The trick
- -- is that the number of days in any four year period in the Ada range of
- -- years (1901 - 2099) has a constant number of days. This is because we
- -- have the special case of 2000 which, contrary to the normal exception
- -- for centuries, is a leap year after all.
+ -- fit into a 56 year range that can be handled by Unix (1970 included -
+ -- 2026 excluded). Dates that are not in this 56 year range are shifted
+ -- by multiples of 56 years to fit in this range
+ -- The trick is that the number of days in any four year period in the Ada
+ -- range of years (1901 - 2099) has a constant number of days. This is
+ -- because we have the special case of 2000 which, contrary to the normal
+ -- exception for centuries, is a leap year after all.
+ -- 56 has been chosen, because it is not only a multiple of 4, but also
+ -- a multiple of 7. Thus two dates 56 years apart fall on the same day of
+ -- the week, and the Daylight Saving Time change dates are usually the same
+ -- for these two years.
Unix_Year_Min : constant := 1970;
- Unix_Year_Max : constant := 2038;
+ Unix_Year_Max : constant := 2026;
Ada_Year_Min : constant := 1901;
Ada_Year_Max : constant := 2099;
@@ -106,9 +112,10 @@ package body Ada.Calendar is
Days_In_Month : constant array (Month_Number) of Day_Number :=
(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
- Days_In_4_Years : constant := 365 * 3 + 366;
- Seconds_In_4_Years : constant := 86_400 * Days_In_4_Years;
- Seconds_In_4_YearsD : constant Duration := Duration (Seconds_In_4_Years);
+ Days_In_4_Years : constant := 365 * 3 + 366;
+ Seconds_In_4_Years : constant := 86_400 * Days_In_4_Years;
+ Seconds_In_56_Years : constant := Seconds_In_4_Years * 14;
+ Seconds_In_56_YearsD : constant := Duration (Seconds_In_56_Years);
---------
-- "+" --
@@ -270,15 +277,6 @@ package body Ada.Calendar is
LowD : constant Duration := Duration (Low);
HighD : constant Duration := Duration (High);
- -- The following declare the maximum duration value that can be
- -- successfully converted to a 32-bit integer suitable for passing
- -- to the localtime_r function. Note that we cannot assume that the
- -- localtime_r function expands to accept 64-bit input on a 64-bit
- -- machine, but we can count on a 32-bit range on all machines.
-
- Max_Time : constant := 2 ** 31 - 1;
- Max_TimeD : constant Duration := Duration (Max_Time);
-
-- Finally the actual variables used in the computation
D : Duration;
@@ -309,21 +307,21 @@ package body Ada.Calendar is
-- EPOCH through EPOCH + N seconds). N is in practice 2 ** 31 - 1.
-- If we have a value outside this range, then we first adjust it
- -- to be in the required range by adding multiples of four years.
+ -- to be in the required range by adding multiples of 56 years.
-- For the range we are interested in, the number of days in any
- -- consecutive four year period is constant. Then we do the split
+ -- consecutive 56 year period is constant. Then we do the split
-- on the adjusted value, and readjust the years value accordingly.
Year_Val := 0;
while D < 0.0 loop
- D := D + Seconds_In_4_YearsD;
- Year_Val := Year_Val - 4;
+ D := D + Seconds_In_56_YearsD;
+ Year_Val := Year_Val - 56;
end loop;
- while D > Max_TimeD loop
- D := D - Seconds_In_4_YearsD;
- Year_Val := Year_Val + 4;
+ while D >= Seconds_In_56_YearsD loop
+ D := D - Seconds_In_56_YearsD;
+ Year_Val := Year_Val + 56;
end loop;
-- Now we need to take the value D, which is now non-negative, and
@@ -435,18 +433,19 @@ package body Ada.Calendar is
TM_Val.tm_mon := Month - 1;
-- For the year, we have to adjust it to a year that Unix can handle.
- -- We do this in four year steps, since the number of days in four
- -- years is constant, so the timezone effect on the conversion from
- -- local time to GMT is unaffected.
-
- while Year_Val <= Unix_Year_Min loop
- Year_Val := Year_Val + 4;
- Duration_Adjust := Duration_Adjust - Seconds_In_4_YearsD;
+ -- We do this in 56 year steps, since the number of days in 56 years
+ -- is constant, so the timezone effect on the conversion from local
+ -- time to GMT is unaffected; also the DST change dates are usually
+ -- not modified.
+
+ while Year_Val < Unix_Year_Min loop
+ Year_Val := Year_Val + 56;
+ Duration_Adjust := Duration_Adjust - Seconds_In_56_YearsD;
end loop;
while Year_Val >= Unix_Year_Max loop
- Year_Val := Year_Val - 4;
- Duration_Adjust := Duration_Adjust + Seconds_In_4_YearsD;
+ Year_Val := Year_Val - 56;
+ Duration_Adjust := Duration_Adjust + Seconds_In_56_YearsD;
end loop;
TM_Val.tm_year := Year_Val - 1900;
diff --git a/gcc/ada/a-dirval-mingw.adb b/gcc/ada/a-dirval-mingw.adb
new file mode 100644
index 00000000000..a20ff177973
--- /dev/null
+++ b/gcc/ada/a-dirval-mingw.adb
@@ -0,0 +1,146 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- A D A . D I R E C T O R I E S . V A L I D I T Y --
+-- --
+-- B o d y --
+-- (Windows Version) --
+-- --
+-- Copyright (C) 2004 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the Windows version of this package
+
+with Ada.Characters.Latin_1; use Ada.Characters.Latin_1;
+
+package body Ada.Directories.Validity is
+
+ Invalid_Character : constant array (Character) of Boolean :=
+ (NUL .. US => True,
+ '/' | ':' | '*' | '?' => True,
+ '"' | '<' | '>' | '|' => True,
+ DEL .. NBSP => True,
+ others => False);
+
+ ------------------------
+ -- Is_Valid_Path_Name --
+ ------------------------
+
+ function Is_Valid_Path_Name (Name : String) return Boolean is
+ Start : Positive := Name'First;
+ Last : Natural;
+
+ begin
+ -- A path name cannot be empty, cannot contain more than 256 characters,
+ -- cannot contain invalid characters and each directory/file name need
+ -- to be valid.
+
+ if Name'Length = 0 or else Name'Length > 256 then
+ return False;
+
+ else
+ -- A drive letter may be specified at the beginning
+
+ if Name'Length >= 2
+ and then Name (Start + 1) = ':'
+ and then
+ (Name (Start) in 'A' .. 'Z' or else
+ Name (Start) in 'a' .. 'z')
+ then
+ Start := Start + 2;
+ end if;
+
+ loop
+ -- Look for the start of the next directory or file name
+
+ while Start <= Name'Last and then Name (Start) = '\' loop
+ Start := Start + 1;
+ end loop;
+
+ -- If all directories/file names are OK, return True
+
+ exit when Start > Name'Last;
+
+ Last := Start;
+
+ -- Look for the end of the directory/file name
+
+ while Last < Name'Last loop
+ exit when Name (Last + 1) = '\';
+ Last := Last + 1;
+ end loop;
+
+ -- Check if the directory/file name is valid
+
+ if not Is_Valid_Simple_Name (Name (Start .. Last)) then
+ return False;
+ end if;
+
+ -- Move to the next name
+
+ Start := Last + 1;
+ end loop;
+ end if;
+
+ -- If Name follows the rules, it is valid
+
+ return True;
+ end Is_Valid_Path_Name;
+
+ --------------------------
+ -- Is_Valid_Simple_Name --
+ --------------------------
+
+ function Is_Valid_Simple_Name (Name : String) return Boolean is
+ Only_Spaces : Boolean;
+
+ begin
+ -- A file name cannot be empty, cannot contain more than 256 characters,
+ -- and cannot contain invalid characters, including '\'
+
+ if Name'Length = 0 or else Name'Length > 256 then
+ return False;
+
+ -- Name length is OK
+
+ else
+ Only_Spaces := True;
+ for J in Name'Range loop
+ if Invalid_Character (Name (J)) or else Name (J) = '\' then
+ return False;
+ elsif Name (J) /= ' ' then
+ Only_Spaces := False;
+ end if;
+ end loop;
+
+ -- If no invalid chars, and not all spaces, file name is valid.
+
+ return not Only_Spaces;
+ end if;
+ end Is_Valid_Simple_Name;
+
+end Ada.Directories.Validity;
+
diff --git a/gcc/ada/a-dirval-vms.adb b/gcc/ada/a-dirval-vms.adb
new file mode 100644
index 00000000000..76cae74aa34
--- /dev/null
+++ b/gcc/ada/a-dirval-vms.adb
@@ -0,0 +1,175 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- A D A . D I R E C T O R I E S . V A L I D I T Y --
+-- --
+-- B o d y --
+-- (VMS Version) --
+-- --
+-- Copyright (C) 2004 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the OpenVMS version of this package
+
+package body Ada.Directories.Validity is
+
+ Max_Number_Of_Characters : constant := 39;
+ Max_Path_Length : constant := 1_024;
+
+ Invalid_Character : constant array (Character) of Boolean :=
+ ('a' .. 'z' => False,
+ 'A' .. 'Z' => False,
+ '_' | '$' | '-' | '.' => False,
+ others => True);
+
+ ------------------------
+ -- Is_Valid_Path_Name --
+ ------------------------
+
+ function Is_Valid_Path_Name (Name : String) return Boolean is
+ First : Positive := Name'First;
+ Last : Positive;
+ Dot_Found : Boolean := False;
+
+ begin
+ -- A valid path (directory) name cannot be empty, and cannot contain
+ -- more than 1024 characters. Directories can be ".", ".." or be simple
+ -- name without extensions.
+
+ if Name'Length = 0 or else Name'Length > Max_Path_Length then
+ return False;
+
+ else
+ loop
+ -- Look for the start of the next directory or file name
+
+ while First <= Name'Last and then Name (First) = '/' loop
+ First := First + 1;
+ end loop;
+
+ -- If all directories/file names are OK, return True
+
+ exit when First > Name'Last;
+
+ Last := First;
+ Dot_Found := False;
+
+ -- Look for the end of the directory/file name
+
+ while Last < Name'Last loop
+ exit when Name (Last + 1) = '/';
+ Last := Last + 1;
+
+ if Name (Last) = '.' then
+ Dot_Found := True;
+ end if;
+ end loop;
+
+ -- If name include a dot, it can only be ".", ".." or a the last
+ -- file name.
+
+ if Dot_Found then
+ if Name (First .. Last) /= "." and then
+ Name (First .. Last) /= ".."
+ then
+ return Last = Name'Last
+ and then Is_Valid_Simple_Name (Name (First .. Last));
+
+ end if;
+
+ -- Check if the directory/file name is valid
+
+ elsif not Is_Valid_Simple_Name (Name (First .. Last)) then
+ return False;
+ end if;
+
+ -- Move to the next name
+
+ First := Last + 1;
+ end loop;
+ end if;
+
+ -- If Name follows the rules, then it is valid
+
+ return True;
+ end Is_Valid_Path_Name;
+
+ --------------------------
+ -- Is_Valid_Simple_Name --
+ --------------------------
+
+ function Is_Valid_Simple_Name (Name : String) return Boolean is
+ In_Extension : Boolean := False;
+ Number_Of_Characters : Natural := 0;
+
+ begin
+ -- A file name cannot be empty, and cannot have more than 39 characters
+ -- before or after a single '.'.
+
+ if Name'Length = 0 then
+ return False;
+
+ else
+ -- Check each character for validity
+
+ for J in Name'Range loop
+ if Invalid_Character (Name (J)) then
+ return False;
+
+ elsif Name (J) = '.' then
+
+ -- Name cannot contain several dots
+
+ if In_Extension then
+ return False;
+
+ else
+ -- Reset the number of characters to count the characters
+ -- of the extension.
+
+ In_Extension := True;
+ Number_Of_Characters := 0;
+ end if;
+
+ else
+ -- Check that the number of character is not too large
+
+ Number_Of_Characters := Number_Of_Characters + 1;
+
+ if Number_Of_Characters > Max_Number_Of_Characters then
+ return False;
+ end if;
+ end if;
+ end loop;
+ end if;
+
+ -- If the rules are followed, then it is valid
+
+ return True;
+ end Is_Valid_Simple_Name;
+
+end Ada.Directories.Validity;
+
diff --git a/gcc/ada/a-except.adb b/gcc/ada/a-except.adb
index 8e9e98c342d..c07790ab4fe 100644
--- a/gcc/ada/a-except.adb
+++ b/gcc/ada/a-except.adb
@@ -501,6 +501,7 @@ package body Ada.Exceptions is
procedure Rcheck_26 (File : Big_String_Ptr; Line : Integer);
procedure Rcheck_27 (File : Big_String_Ptr; Line : Integer);
procedure Rcheck_28 (File : Big_String_Ptr; Line : Integer);
+ procedure Rcheck_29 (File : Big_String_Ptr; Line : Integer);
pragma Export (C, Rcheck_00, "__gnat_rcheck_00");
pragma Export (C, Rcheck_01, "__gnat_rcheck_01");
@@ -531,6 +532,7 @@ package body Ada.Exceptions is
pragma Export (C, Rcheck_26, "__gnat_rcheck_26");
pragma Export (C, Rcheck_27, "__gnat_rcheck_27");
pragma Export (C, Rcheck_28, "__gnat_rcheck_28");
+ pragma Export (C, Rcheck_29, "__gnat_rcheck_29");
---------------------------------------------
-- Reason Strings for Run-Time Check Calls --
@@ -565,11 +567,13 @@ package body Ada.Exceptions is
Rmsg_21 : constant String := "potentially blocking operation" & NUL;
Rmsg_22 : constant String := "stubbed subprogram called" & NUL;
Rmsg_23 : constant String := "unchecked union restriction" & NUL;
- Rmsg_24 : constant String := "empty storage pool" & NUL;
- Rmsg_25 : constant String := "explicit raise" & NUL;
- Rmsg_26 : constant String := "infinite recursion" & NUL;
- Rmsg_27 : constant String := "object too large" & NUL;
- Rmsg_28 : constant String := "restriction violation" & NUL;
+ Rmsg_24 : constant String := "illegal use of"
+ & " remote access-to-class-wide type, see RM E.4(18)" & NUL;
+ Rmsg_25 : constant String := "empty storage pool" & NUL;
+ Rmsg_26 : constant String := "explicit raise" & NUL;
+ Rmsg_27 : constant String := "infinite recursion" & NUL;
+ Rmsg_28 : constant String := "object too large" & NUL;
+ Rmsg_29 : constant String := "restriction violation" & NUL;
-----------------------
-- Polling Interface --
@@ -1146,7 +1150,7 @@ package body Ada.Exceptions is
procedure Rcheck_24 (File : Big_String_Ptr; Line : Integer) is
begin
- Raise_Storage_Error_Msg (File, Line, To_Ptr (Rmsg_24'Address));
+ Raise_Program_Error_Msg (File, Line, To_Ptr (Rmsg_24'Address));
end Rcheck_24;
procedure Rcheck_25 (File : Big_String_Ptr; Line : Integer) is
@@ -1169,6 +1173,11 @@ package body Ada.Exceptions is
Raise_Storage_Error_Msg (File, Line, To_Ptr (Rmsg_28'Address));
end Rcheck_28;
+ procedure Rcheck_29 (File : Big_String_Ptr; Line : Integer) is
+ begin
+ Raise_Storage_Error_Msg (File, Line, To_Ptr (Rmsg_29'Address));
+ end Rcheck_29;
+
-------------
-- Reraise --
-------------
diff --git a/gcc/ada/a-excpol-abort.adb b/gcc/ada/a-excpol-abort.adb
new file mode 100644
index 00000000000..afa93c1d3f2
--- /dev/null
+++ b/gcc/ada/a-excpol-abort.adb
@@ -0,0 +1,58 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- A D A . E X C E P T I O N S . P O L L --
+-- (version supporting asynchronous abort test) --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2000, 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- --
+-- 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, 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, --
+-- 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 version is for targets that do not support per-thread asynchronous
+-- signals. On such targets, we require compilation with the -gnatP switch
+-- that activates periodic polling. Then in the body of the polling routine
+-- we test for asynchronous abort.
+
+-- NT, OS/2, HPUX/DCE and SCO currently use this file
+
+with System.Soft_Links;
+-- used for Check_Abort_Status
+
+separate (Ada.Exceptions)
+
+----------
+-- Poll --
+----------
+
+procedure Poll is
+begin
+ -- Test for asynchronous abort on each poll
+
+ if System.Soft_Links.Check_Abort_Status.all /= 0 then
+ raise Standard'Abort_Signal;
+ end if;
+end Poll;
diff --git a/gcc/ada/a-excpol-interix.adb b/gcc/ada/a-excpol-interix.adb
new file mode 100644
index 00000000000..7deb26a8603
--- /dev/null
+++ b/gcc/ada/a-excpol-interix.adb
@@ -0,0 +1,66 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- A D A . E X C E P T I O N S . P O L L --
+-- (version supporting asynchronous abort test and time slicing) --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2000, 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- --
+-- 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, 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, --
+-- 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 version is for targets that do not support per-thread asynchronous
+-- signals or that do not handle async timers properly. On such targets, we
+-- require compilation with the -gnatP switch that activates periodic polling.
+-- Then in the body of the polling routine we test for asynchronous abort and
+-- yield periodically.
+
+-- HP-UX and SCO currently use this file
+
+with System.Soft_Links;
+-- used for Check_Abort_Status
+
+separate (Ada.Exceptions)
+
+----------
+-- Poll --
+----------
+
+procedure Poll is
+begin
+ if Counter = 10000 then
+ Counter := 0;
+ delay 0.0;
+ else
+ Counter := Counter + 1;
+ end if;
+
+ -- Test for asynchronous abort on each poll
+
+ if System.Soft_Links.Check_Abort_Status.all /= 0 then
+ raise Standard'Abort_Signal;
+ end if;
+end Poll;
diff --git a/gcc/ada/a-exexpr.adb b/gcc/ada/a-exexpr.adb
index faa89a3744c..b42b3fc7fd7 100644
--- a/gcc/ada/a-exexpr.adb
+++ b/gcc/ada/a-exexpr.adb
@@ -2,7 +2,7 @@
-- --
-- GNAT COMPILER COMPONENTS --
-- --
--- ADA.EXCEPTIONS.EXCEPTION_PROPAGATION --
+-- A D A . E X C E P T I O N S . E X C E P T I O N _ P R O P A G A T I O N --
-- --
-- B o d y --
-- --
@@ -102,14 +102,17 @@ package body Exception_Propagation is
GNAT_Exception_Class : constant Exception_Class := 16#474e552d41646100#;
-- "GNU-Ada\0"
+ type Unwind_Word is mod 2 ** System.Word_Size;
+ for Unwind_Word'Size use System.Word_Size;
+ -- Map the corresponding C type used in Unwind_Exception below.
+
type Unwind_Exception is record
Class : Exception_Class := GNAT_Exception_Class;
Cleanup : System.Address := System.Null_Address;
- Private1 : Integer;
- Private2 : Integer;
+ Private1 : Unwind_Word;
+ Private2 : Unwind_Word;
end record;
-
- pragma Convention (C, Unwind_Exception);
+ -- Map the GCC struct used for exception handling.
for Unwind_Exception'Alignment use Standard'Maximum_Alignment;
-- The C++ ABI mandates the common exception header to be at least
@@ -119,7 +122,7 @@ package body Exception_Propagation is
-- 1/ We pass pointers to such headers down to the underlying
-- libGCC unwinder,
- -- and
+ -- and
-- 2/ The GNAT_GCC_Exception record below starts with this common
-- common header and has a C counterpart which needs to be laid
diff --git a/gcc/ada/a-intnam-aix.ads b/gcc/ada/a-intnam-aix.ads
new file mode 100644
index 00000000000..fa56138b461
--- /dev/null
+++ b/gcc/ada/a-intnam-aix.ads
@@ -0,0 +1,201 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- A D A . I N T E R R U P T S . N A M E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-2002 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- --
+-- 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, 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, --
+-- 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 is a AIX version of this package.
+--
+-- The following signals are reserved by the run time (native threads):
+--
+-- SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGABRT, SIGTRAP, SIGINT, SIGTERM,
+-- SIGSTOP, SIGKILL
+--
+-- The following signals are reserved by the run time (FSU threads):
+--
+-- SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGABRT, SIGTRAP, SIGINT, SIGALRM,
+-- SIGWAITING, SIGSTOP, SIGKILL
+--
+-- The pragma Unreserve_All_Interrupts affects the following signal(s):
+--
+-- SIGINT: made available for Ada handler
+
+-- This target-dependent package spec contains names of interrupts
+-- supported by the local system.
+
+with System.OS_Interface;
+-- used for names of interrupts
+
+package Ada.Interrupts.Names is
+
+ -- Beware that the mapping of names to signals may be
+ -- many-to-one. There may be aliases. Also, for all
+ -- signal names that are not supported on the current system
+ -- the value of the corresponding constant will be zero.
+
+ SIGHUP : constant Interrupt_ID :=
+ System.OS_Interface.SIGHUP; -- hangup
+
+ SIGINT : constant Interrupt_ID :=
+ System.OS_Interface.SIGINT; -- interrupt (rubout)
+
+ SIGQUIT : constant Interrupt_ID :=
+ System.OS_Interface.SIGQUIT; -- quit (ASCD FS)
+
+ SIGILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGILL; -- illegal instruction (not reset)
+
+ SIGTRAP : constant Interrupt_ID :=
+ System.OS_Interface.SIGTRAP; -- trace trap (not reset)
+
+ SIGIOT : constant Interrupt_ID :=
+ System.OS_Interface.SIGIOT; -- IOT instruction
+
+ SIGABRT : constant Interrupt_ID := -- used by abort,
+ System.OS_Interface.SIGABRT; -- replace SIGIOT in the future
+
+ SIGEMT : constant Interrupt_ID :=
+ System.OS_Interface.SIGEMT; -- EMT instruction
+
+ SIGFPE : constant Interrupt_ID :=
+ System.OS_Interface.SIGFPE; -- floating point exception
+
+ SIGKILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGKILL; -- kill (cannot be caught or ignored)
+
+ SIGBUS : constant Interrupt_ID :=
+ System.OS_Interface.SIGBUS; -- bus error
+
+ SIGSEGV : constant Interrupt_ID :=
+ System.OS_Interface.SIGSEGV; -- segmentation violation
+
+ SIGSYS : constant Interrupt_ID :=
+ System.OS_Interface.SIGSYS; -- bad argument to system call
+
+ SIGPIPE : constant Interrupt_ID := -- write on a pipe with
+ System.OS_Interface.SIGPIPE; -- no one to read it
+
+ SIGALRM : constant Interrupt_ID :=
+ System.OS_Interface.SIGALRM; -- alarm clock
+
+ SIGTERM : constant Interrupt_ID :=
+ System.OS_Interface.SIGTERM; -- software termination signal from kill
+
+ SIGUSR1 : constant Interrupt_ID :=
+ System.OS_Interface.SIGUSR1; -- user defined signal 1
+
+ SIGUSR2 : constant Interrupt_ID :=
+ System.OS_Interface.SIGUSR2; -- user defined signal 2
+
+ SIGCLD : constant Interrupt_ID :=
+ System.OS_Interface.SIGCLD; -- child status change
+
+ SIGCHLD : constant Interrupt_ID :=
+ System.OS_Interface.SIGCHLD; -- 4.3BSD's/POSIX name for SIGCLD
+
+ SIGPWR : constant Interrupt_ID :=
+ System.OS_Interface.SIGPWR; -- power-fail restart
+
+ SIGWINCH : constant Interrupt_ID :=
+ System.OS_Interface.SIGWINCH; -- window size change
+
+ SIGURG : constant Interrupt_ID :=
+ System.OS_Interface.SIGURG; -- urgent condition on IO channel
+
+ SIGPOLL : constant Interrupt_ID :=
+ System.OS_Interface.SIGPOLL; -- pollable event occurred
+
+ SIGIO : constant Interrupt_ID := -- input/output possible,
+ System.OS_Interface.SIGIO; -- SIGPOLL alias (Solaris)
+
+ SIGSTOP : constant Interrupt_ID :=
+ System.OS_Interface.SIGSTOP; -- stop (cannot be caught or ignored)
+
+ SIGTSTP : constant Interrupt_ID :=
+ System.OS_Interface.SIGTSTP; -- user stop requested from tty
+
+ SIGCONT : constant Interrupt_ID :=
+ System.OS_Interface.SIGCONT; -- stopped process has been continued
+
+ SIGTTIN : constant Interrupt_ID :=
+ System.OS_Interface.SIGTTIN; -- background tty read attempted
+
+ SIGTTOU : constant Interrupt_ID :=
+ System.OS_Interface.SIGTTOU; -- background tty write attempted
+
+ SIGVTALRM : constant Interrupt_ID :=
+ System.OS_Interface.SIGVTALRM; -- virtual timer expired
+
+ SIGPROF : constant Interrupt_ID :=
+ System.OS_Interface.SIGPROF; -- profiling timer expired
+
+ SIGXCPU : constant Interrupt_ID :=
+ System.OS_Interface.SIGXCPU; -- CPU time limit exceeded
+
+ SIGXFSZ : constant Interrupt_ID :=
+ System.OS_Interface.SIGXFSZ; -- filesize limit exceeded
+
+ SIGMSG : constant Interrupt_ID :=
+ System.OS_Interface.SIGMSG; -- input data is in the ring buffer
+
+ SIGDANGER : constant Interrupt_ID :=
+ System.OS_Interface.SIGDANGER; -- system crash imminent;
+
+ SIGMIGRATE : constant Interrupt_ID :=
+ System.OS_Interface.SIGMIGRATE; -- migrate process
+
+ SIGPRE : constant Interrupt_ID :=
+ System.OS_Interface.SIGPRE; -- programming exception
+
+ SIGVIRT : constant Interrupt_ID :=
+ System.OS_Interface.SIGVIRT; -- AIX virtual time alarm
+
+ SIGALRM1 : constant Interrupt_ID :=
+ System.OS_Interface.SIGALRM1; -- m:n condition variables
+
+ SIGWAITING : constant Interrupt_ID :=
+ System.OS_Interface.SIGWAITING; -- m:n scheduling
+
+ SIGKAP : constant Interrupt_ID :=
+ System.OS_Interface.SIGKAP; -- keep alive poll from native keyboard
+
+ SIGGRANT : constant Interrupt_ID :=
+ System.OS_Interface.SIGGRANT; -- monitor mode granted
+
+ SIGRETRACT : constant Interrupt_ID :=
+ System.OS_Interface.SIGRETRACT; -- monitor mode should be relinguished
+
+ SIGSOUND : constant Interrupt_ID :=
+ System.OS_Interface.SIGSOUND; -- sound control has completed
+
+ SIGSAK : constant Interrupt_ID :=
+ System.OS_Interface.SIGSAK; -- secure attention key
+
+end Ada.Interrupts.Names;
diff --git a/gcc/ada/a-intnam-darwin.ads b/gcc/ada/a-intnam-darwin.ads
new file mode 100644
index 00000000000..73423f7283d
--- /dev/null
+++ b/gcc/ada/a-intnam-darwin.ads
@@ -0,0 +1,153 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- A D A . I N T E R R U P T S . N A M E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-2004 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- --
+-- 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, 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, --
+-- 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 is the Darwin version of this package.
+--
+-- The following signals are reserved by the run time:
+--
+-- SIGSTOP, SIGKILL
+--
+-- The pragma Unreserve_All_Interrupts affects the following signal(s):
+--
+-- SIGINT: made available for Ada handler
+
+-- This target-dependent package spec contains names of interrupts
+-- supported by the local system.
+
+with System.OS_Interface;
+-- used for names of interrupts
+
+package Ada.Interrupts.Names is
+
+ -- Beware that the mapping of names to signals may be
+ -- many-to-one. There may be aliases. Also, for all
+ -- signal names that are not supported on the current system
+ -- the value of the corresponding constant will be zero.
+
+ SIGHUP : constant Interrupt_ID :=
+ System.OS_Interface.SIGHUP; -- hangup
+
+ SIGINT : constant Interrupt_ID :=
+ System.OS_Interface.SIGINT; -- interrupt (rubout)
+
+ SIGQUIT : constant Interrupt_ID :=
+ System.OS_Interface.SIGQUIT; -- quit (ASCD FS)
+
+ SIGILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGILL; -- illegal instruction (not reset)
+
+ SIGTRAP : constant Interrupt_ID :=
+ System.OS_Interface.SIGTRAP; -- trace trap (not reset)
+
+ SIGIOT : constant Interrupt_ID :=
+ System.OS_Interface.SIGIOT; -- IOT instruction
+
+ SIGABRT : constant Interrupt_ID := -- used by abort,
+ System.OS_Interface.SIGABRT; -- replace SIGIOT in the future
+
+ SIGEMT : constant Interrupt_ID :=
+ System.OS_Interface.SIGEMT; -- EMT instruction
+
+ SIGFPE : constant Interrupt_ID :=
+ System.OS_Interface.SIGFPE; -- floating point exception
+
+ SIGKILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGKILL; -- kill (cannot be caught or ignored)
+
+ SIGBUS : constant Interrupt_ID :=
+ System.OS_Interface.SIGBUS; -- bus error
+
+ SIGSEGV : constant Interrupt_ID :=
+ System.OS_Interface.SIGSEGV; -- segmentation violation
+
+ SIGSYS : constant Interrupt_ID :=
+ System.OS_Interface.SIGSYS; -- bad argument to system call
+
+ SIGPIPE : constant Interrupt_ID := -- write on a pipe with
+ System.OS_Interface.SIGPIPE; -- no one to read it
+
+ SIGALRM : constant Interrupt_ID :=
+ System.OS_Interface.SIGALRM; -- alarm clock
+
+ SIGTERM : constant Interrupt_ID :=
+ System.OS_Interface.SIGTERM; -- software termination signal from kill
+
+ SIGURG : constant Interrupt_ID :=
+ System.OS_Interface.SIGURG; -- urgent condition on IO channel
+
+ SIGSTOP : constant Interrupt_ID :=
+ System.OS_Interface.SIGSTOP; -- stop (cannot be caught or ignored)
+
+ SIGTSTP : constant Interrupt_ID :=
+ System.OS_Interface.SIGTSTP; -- user stop requested from tty
+
+ SIGCONT : constant Interrupt_ID :=
+ System.OS_Interface.SIGCONT; -- stopped process has been continued
+
+ SIGCHLD : constant Interrupt_ID :=
+ System.OS_Interface.SIGCHLD; -- 4.3BSD's/POSIX name for SIGCLD
+
+ SIGTTIN : constant Interrupt_ID :=
+ System.OS_Interface.SIGTTIN; -- background tty read attempted
+
+ SIGTTOU : constant Interrupt_ID :=
+ System.OS_Interface.SIGTTOU; -- background tty write attempted
+
+ SIGIO : constant Interrupt_ID := -- input/output possible,
+ System.OS_Interface.SIGIO; -- SIGPOLL alias (Solaris)
+
+ SIGXCPU : constant Interrupt_ID :=
+ System.OS_Interface.SIGXCPU; -- CPU time limit exceeded
+
+ SIGXFSZ : constant Interrupt_ID :=
+ System.OS_Interface.SIGXFSZ; -- filesize limit exceeded
+
+ SIGVTALRM : constant Interrupt_ID :=
+ System.OS_Interface.SIGVTALRM; -- virtual timer expired
+
+ SIGPROF : constant Interrupt_ID :=
+ System.OS_Interface.SIGPROF; -- profiling timer expired
+
+ SIGWINCH : constant Interrupt_ID :=
+ System.OS_Interface.SIGWINCH; -- window size change
+
+ SIGINFO : constant Interrupt_ID :=
+ System.OS_Interface.SIGINFO; -- information request
+
+ SIGUSR1 : constant Interrupt_ID :=
+ System.OS_Interface.SIGUSR1; -- user defined signal 1
+
+ SIGUSR2 : constant Interrupt_ID :=
+ System.OS_Interface.SIGUSR2; -- user defined signal 2
+
+end Ada.Interrupts.Names;
diff --git a/gcc/ada/a-intnam-dummy.ads b/gcc/ada/a-intnam-dummy.ads
new file mode 100644
index 00000000000..427ba5cc18a
--- /dev/null
+++ b/gcc/ada/a-intnam-dummy.ads
@@ -0,0 +1,48 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUNTIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- A D A . I N T E R R U P T S . N A M E S --
+-- --
+-- S p e c --
+-- (No Tasking Version) --
+-- --
+-- Copyright (C) 1991-2002 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+------------------------------------------------------------------------------
+
+-- The standard implementation of this spec contains only dummy interrupt
+-- names. These dummy entries permit checking out code for correctness of
+-- semantics, even if interrupts are not supported.
+
+-- For specific implementations that fully support interrupts, this package
+-- spec is replaced by an implementation dependent version that defines the
+-- interrupts available on the system.
+
+package Ada.Interrupts.Names is
+
+ DUMMY_INTERRUPT_1 : constant Interrupt_ID := 1;
+ DUMMY_INTERRUPT_2 : constant Interrupt_ID := 2;
+
+end Ada.Interrupts.Names;
diff --git a/gcc/ada/a-intnam-freebsd.ads b/gcc/ada/a-intnam-freebsd.ads
new file mode 100644
index 00000000000..eb05daaa912
--- /dev/null
+++ b/gcc/ada/a-intnam-freebsd.ads
@@ -0,0 +1,136 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- A D A . I N T E R R U P T S . N A M E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-2003 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- --
+-- 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, 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, --
+-- 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 is the FreeBSD THREADS version of this package
+
+with System.OS_Interface;
+-- used for names of interrupts
+
+package Ada.Interrupts.Names is
+
+ SIGHUP : constant Interrupt_ID :=
+ System.OS_Interface.SIGHUP; -- hangup
+
+ SIGINT : constant Interrupt_ID :=
+ System.OS_Interface.SIGINT; -- interrupt (rubout)
+
+ SIGQUIT : constant Interrupt_ID :=
+ System.OS_Interface.SIGQUIT; -- quit (ASCD FS)
+
+ SIGILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGILL; -- illegal instruction (not reset)
+
+ SIGTRAP : constant Interrupt_ID :=
+ System.OS_Interface.SIGTRAP; -- trace trap (not reset)
+
+ SIGIOT : constant Interrupt_ID :=
+ System.OS_Interface.SIGIOT; -- IOT instruction
+
+ SIGABRT : constant Interrupt_ID := -- used by abort,
+ System.OS_Interface.SIGABRT; -- replace SIGIOT in the future
+
+ SIGFPE : constant Interrupt_ID :=
+ System.OS_Interface.SIGFPE; -- floating point exception
+
+ SIGKILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGKILL; -- kill (cannot be caught or ignored)
+
+ SIGBUS : constant Interrupt_ID :=
+ System.OS_Interface.SIGBUS; -- bus error
+
+ SIGSEGV : constant Interrupt_ID :=
+ System.OS_Interface.SIGSEGV; -- segmentation violation
+
+ SIGPIPE : constant Interrupt_ID := -- write on a pipe with
+ System.OS_Interface.SIGPIPE; -- no one to read it
+
+ SIGALRM : constant Interrupt_ID :=
+ System.OS_Interface.SIGALRM; -- alarm clock
+
+ SIGTERM : constant Interrupt_ID :=
+ System.OS_Interface.SIGTERM; -- software termination signal from kill
+
+ SIGURG : constant Interrupt_ID :=
+ System.OS_Interface.SIGURG; -- urgent condition on IO channel
+
+ SIGSTOP : constant Interrupt_ID :=
+ System.OS_Interface.SIGSTOP; -- stop (cannot be caught or ignored)
+
+ SIGTSTP : constant Interrupt_ID :=
+ System.OS_Interface.SIGTSTP; -- user stop requested from tty
+
+ SIGCONT : constant Interrupt_ID :=
+ System.OS_Interface.SIGCONT; -- stopped process has been continued
+
+ SIGCHLD : constant Interrupt_ID :=
+ System.OS_Interface.SIGCHLD; -- 4.3BSD's/POSIX name for SIGCLD
+
+ SIGCLD : constant Interrupt_ID :=
+ System.OS_Interface.SIGCLD; -- child status change
+
+ SIGTTIN : constant Interrupt_ID :=
+ System.OS_Interface.SIGTTIN; -- background tty read attempted
+
+ SIGTTOU : constant Interrupt_ID :=
+ System.OS_Interface.SIGTTOU; -- background tty write attempted
+
+ SIGIO : constant Interrupt_ID := -- input/output possible,
+ System.OS_Interface.SIGIO; -- SIGPOLL alias (Solaris)
+
+ SIGXCPU : constant Interrupt_ID :=
+ System.OS_Interface.SIGXCPU; -- CPU time limit exceeded
+
+ SIGXFSZ : constant Interrupt_ID :=
+ System.OS_Interface.SIGXFSZ; -- filesize limit exceeded
+
+ SIGVTALRM : constant Interrupt_ID :=
+ System.OS_Interface.SIGVTALRM; -- virtual timer expired
+
+ SIGPROF : constant Interrupt_ID :=
+ System.OS_Interface.SIGPROF; -- profiling timer expired
+
+ SIGWINCH : constant Interrupt_ID :=
+ System.OS_Interface.SIGWINCH; -- window size change
+
+ SIGUSR1 : constant Interrupt_ID :=
+ System.OS_Interface.SIGUSR1; -- user defined signal 1
+
+ SIGUSR2 : constant Interrupt_ID :=
+ System.OS_Interface.SIGUSR2; -- user defined signal 2
+
+ -- Beware that the mapping of names to signals may be
+ -- many-to-one. There may be aliases. Also, for all
+ -- signal names that are not supported on the current system
+ -- the value of the corresponding constant will be zero.
+
+end Ada.Interrupts.Names;
diff --git a/gcc/ada/a-intnam-hpux.ads b/gcc/ada/a-intnam-hpux.ads
new file mode 100644
index 00000000000..0e01a0fa74e
--- /dev/null
+++ b/gcc/ada/a-intnam-hpux.ads
@@ -0,0 +1,155 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- A D A . I N T E R R U P T S . N A M E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2003, Ada Core Technologies --
+-- --
+-- 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, 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, --
+-- 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 is a HP-UX version of this package.
+
+-- The following signals are reserved by the run time:
+
+-- SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGTRAP, SIGTERM, SIGABRT, SIGINT,
+-- SIGALRM, SIGSTOP, SIGKILL
+
+-- The pragma Unreserve_All_Interrupts affects the following signal(s):
+
+-- SIGINT: made available for Ada handler
+
+-- This target-dependent package spec contains names of interrupts
+-- supported by the local system.
+
+with System.OS_Interface;
+-- used for names of interrupts
+
+package Ada.Interrupts.Names is
+
+ -- Beware that the mapping of names to signals may be
+ -- many-to-one. There may be aliases. Also, for all
+ -- signal names that are not supported on the current system
+ -- the value of the corresponding constant will be zero.
+
+ SIGHUP : constant Interrupt_ID :=
+ System.OS_Interface.SIGHUP; -- hangup
+
+ SIGINT : constant Interrupt_ID :=
+ System.OS_Interface.SIGINT; -- interrupt (rubout)
+
+ SIGQUIT : constant Interrupt_ID :=
+ System.OS_Interface.SIGQUIT; -- quit (ASCD FS)
+
+ SIGILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGILL; -- illegal instruction (not reset)
+
+ SIGTRAP : constant Interrupt_ID :=
+ System.OS_Interface.SIGTRAP; -- trace trap (not reset)
+
+ SIGIOT : constant Interrupt_ID :=
+ System.OS_Interface.SIGIOT; -- IOT instruction
+
+ SIGABRT : constant Interrupt_ID := -- used by abort,
+ System.OS_Interface.SIGABRT; -- replace SIGIOT in the future
+
+ SIGEMT : constant Interrupt_ID :=
+ System.OS_Interface.SIGEMT; -- EMT instruction
+
+ SIGFPE : constant Interrupt_ID :=
+ System.OS_Interface.SIGFPE; -- floating point exception
+
+ SIGKILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGKILL; -- kill (cannot be caught or ignored)
+
+ SIGBUS : constant Interrupt_ID :=
+ System.OS_Interface.SIGBUS; -- bus error
+
+ SIGSEGV : constant Interrupt_ID :=
+ System.OS_Interface.SIGSEGV; -- segmentation violation
+
+ SIGSYS : constant Interrupt_ID :=
+ System.OS_Interface.SIGSYS; -- bad argument to system call
+
+ SIGPIPE : constant Interrupt_ID := -- write on a pipe with
+ System.OS_Interface.SIGPIPE; -- no one to read it
+
+ SIGALRM : constant Interrupt_ID :=
+ System.OS_Interface.SIGALRM; -- alarm clock
+
+ SIGTERM : constant Interrupt_ID :=
+ System.OS_Interface.SIGTERM; -- software termination signal from kill
+
+ SIGUSR1 : constant Interrupt_ID :=
+ System.OS_Interface.SIGUSR1; -- user defined signal 1
+
+ SIGUSR2 : constant Interrupt_ID :=
+ System.OS_Interface.SIGUSR2; -- user defined signal 2
+
+ SIGCLD : constant Interrupt_ID :=
+ System.OS_Interface.SIGCLD; -- child status change
+
+ SIGCHLD : constant Interrupt_ID :=
+ System.OS_Interface.SIGCHLD; -- 4.3BSD's/POSIX name for SIGCLD
+
+ SIGWINCH : constant Interrupt_ID :=
+ System.OS_Interface.SIGWINCH; -- window size change
+
+ SIGURG : constant Interrupt_ID :=
+ System.OS_Interface.SIGURG; -- urgent condition on IO channel
+
+ SIGPOLL : constant Interrupt_ID :=
+ System.OS_Interface.SIGPOLL; -- pollable event occurred
+
+ SIGIO : constant Interrupt_ID := -- input/output possible,
+ System.OS_Interface.SIGIO; -- SIGPOLL alias
+
+ SIGSTOP : constant Interrupt_ID :=
+ System.OS_Interface.SIGSTOP; -- stop (cannot be caught or ignored)
+
+ SIGTSTP : constant Interrupt_ID :=
+ System.OS_Interface.SIGTSTP; -- user stop requested from tty
+
+ SIGCONT : constant Interrupt_ID :=
+ System.OS_Interface.SIGCONT; -- stopped process has been continued
+
+ SIGTTIN : constant Interrupt_ID :=
+ System.OS_Interface.SIGTTIN; -- background tty read attempted
+
+ SIGTTOU : constant Interrupt_ID :=
+ System.OS_Interface.SIGTTOU; -- background tty write attempted
+
+ SIGVTALRM : constant Interrupt_ID :=
+ System.OS_Interface.SIGVTALRM; -- virtual timer expired
+
+ SIGPROF : constant Interrupt_ID :=
+ System.OS_Interface.SIGPROF; -- profiling timer expired
+
+ SIGPWR : constant Interrupt_ID :=
+ System.OS_Interface.SIGPWR; -- power-fail restart
+
+end Ada.Interrupts.Names;
diff --git a/gcc/ada/a-intnam-interix.ads b/gcc/ada/a-intnam-interix.ads
new file mode 100644
index 00000000000..f9cac69dc99
--- /dev/null
+++ b/gcc/ada/a-intnam-interix.ads
@@ -0,0 +1,154 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- A D A . I N T E R R U P T S . N A M E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-2002 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- --
+-- 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, 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, --
+-- 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 is a OpenNT (FSU THREAD) version of this package.
+--
+-- The following signals are reserved by the run time:
+--
+-- SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGTRAP, SIGABRT, SIGINT,
+-- SIGALRM, SIGVTALRM, SIGSTOP, SIGKILL
+--
+-- The pragma Unreserve_All_Interrupts affects the following signal(s):
+--
+-- SIGINT: made available for Ada handlers
+
+-- This target-dependent package spec contains names of interrupts
+-- supported by the local system.
+
+with System.OS_Interface;
+-- used for names of interrupts
+
+package Ada.Interrupts.Names is
+
+ -- Beware that the mapping of names to signals may be
+ -- many-to-one. There may be aliases. Also, for all
+ -- signal names that are not supported on the current system
+ -- the value of the corresponding constant will be zero.
+
+ SIGHUP : constant Interrupt_ID :=
+ System.OS_Interface.SIGHUP; -- hangup
+
+ SIGINT : constant Interrupt_ID :=
+ System.OS_Interface.SIGINT; -- interrupt (rubout)
+
+ SIGQUIT : constant Interrupt_ID :=
+ System.OS_Interface.SIGQUIT; -- quit (ASCD FS)
+
+ SIGILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGILL; -- illegal instruction (not reset)
+
+ SIGTRAP : constant Interrupt_ID :=
+ System.OS_Interface.SIGTRAP; -- trace trap (not reset)
+
+ SIGIOT : constant Interrupt_ID :=
+ System.OS_Interface.SIGIOT; -- IOT instruction
+
+ SIGABRT : constant Interrupt_ID := -- used by abort,
+ System.OS_Interface.SIGABRT; -- replace SIGIOT in the future
+
+ SIGFPE : constant Interrupt_ID :=
+ System.OS_Interface.SIGFPE; -- floating point exception
+
+ SIGKILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGKILL; -- kill (cannot be caught or ignored)
+
+ SIGBUS : constant Interrupt_ID :=
+ System.OS_Interface.SIGBUS; -- bus error
+
+ SIGSEGV : constant Interrupt_ID :=
+ System.OS_Interface.SIGSEGV; -- segmentation violation
+
+ SIGSYS : constant Interrupt_ID :=
+ System.OS_Interface.SIGSYS; -- bad argument to system call
+
+ SIGPIPE : constant Interrupt_ID := -- write on a pipe with
+ System.OS_Interface.SIGPIPE; -- no one to read it
+
+ SIGALRM : constant Interrupt_ID :=
+ System.OS_Interface.SIGALRM; -- alarm clock
+
+ SIGTERM : constant Interrupt_ID :=
+ System.OS_Interface.SIGTERM; -- software termination signal from kill
+
+ SIGUSR1 : constant Interrupt_ID :=
+ System.OS_Interface.SIGUSR1; -- user defined signal 1
+
+ SIGUSR2 : constant Interrupt_ID :=
+ System.OS_Interface.SIGUSR2; -- user defined signal 2
+
+ SIGCLD : constant Interrupt_ID :=
+ System.OS_Interface.SIGCLD; -- child status change
+
+ SIGCHLD : constant Interrupt_ID :=
+ System.OS_Interface.SIGCHLD; -- 4.3BSD's/POSIX name for SIGCLD
+
+ SIGWINCH : constant Interrupt_ID :=
+ System.OS_Interface.SIGWINCH; -- window size change
+
+ SIGURG : constant Interrupt_ID :=
+ System.OS_Interface.SIGURG; -- urgent condition on IO channel
+
+ SIGPOLL : constant Interrupt_ID :=
+ System.OS_Interface.SIGPOLL; -- pollable event occurred
+
+ SIGIO : constant Interrupt_ID := -- input/output possible,
+ System.OS_Interface.SIGIO; -- SIGPOLL alias (Solaris)
+
+ SIGSTOP : constant Interrupt_ID :=
+ System.OS_Interface.SIGSTOP; -- stop (cannot be caught or ignored)
+
+ SIGTSTP : constant Interrupt_ID :=
+ System.OS_Interface.SIGTSTP; -- user stop requested from tty
+
+ SIGCONT : constant Interrupt_ID :=
+ System.OS_Interface.SIGCONT; -- stopped process has been continued
+
+ SIGTTIN : constant Interrupt_ID :=
+ System.OS_Interface.SIGTTIN; -- background tty read attempted
+
+ SIGTTOU : constant Interrupt_ID :=
+ System.OS_Interface.SIGTTOU; -- background tty write attempted
+
+ SIGVTALRM : constant Interrupt_ID :=
+ System.OS_Interface.SIGVTALRM; -- virtual timer expired
+
+ SIGPROF : constant Interrupt_ID :=
+ System.OS_Interface.SIGPROF; -- profiling timer expired
+
+ SIGXCPU : constant Interrupt_ID :=
+ System.OS_Interface.SIGXCPU; -- CPU time limit exceeded
+
+ SIGXFSZ : constant Interrupt_ID :=
+ System.OS_Interface.SIGXFSZ; -- filesize limit exceeded
+
+end Ada.Interrupts.Names;
diff --git a/gcc/ada/a-intnam-irix.ads b/gcc/ada/a-intnam-irix.ads
new file mode 100644
index 00000000000..afd82f2bb6c
--- /dev/null
+++ b/gcc/ada/a-intnam-irix.ads
@@ -0,0 +1,196 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- A D A . I N T E R R U P T S . N A M E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2003, Ada Core Technologies --
+-- --
+-- GNARL is free software; you can redistribute it and/or modify it under --
+-- terms of the GNU Library General Public License as published by the --
+-- Free Software Foundation; either version 2, or (at your option) any --
+-- later version. GNARL is distributed in the hope that it will be use- --
+-- ful, but WITHOUT ANY WARRANTY; without even the implied warranty of --
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Gen- --
+-- eral Library Public License for more details. You should have received --
+-- a copy of the GNU Library General Public License along with GNARL; see --
+-- file COPYING.LIB. If not, write 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, --
+-- 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 is the Irix version of this package
+
+-- The following signals are reserved by the run time (Athread library):
+
+-- SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGTRAP, SIGSTOP, SIGKILL
+
+-- The following signals are reserved by the run time (Pthread library):
+
+-- SIGTSTP, SIGILL, SIGTRAP, SIGEMT, SIGFPE, SIGBUS, SIGSTOP, SIGKILL,
+-- SIGSEGV, SIGSYS, SIGXCPU, SIGXFSZ, SIGPROF, SIGPTINTR, SIGPTRESCHED,
+-- SIGABRT, SIGINT
+
+-- The pragma Unreserve_All_Interrupts affects the following signal
+-- (Pthread library):
+
+-- SIGINT: made available for Ada handler
+
+-- This target-dependent package spec contains names of interrupts
+-- supported by the local system.
+
+with System.OS_Interface;
+-- used for names of interrupts
+
+package Ada.Interrupts.Names is
+
+ -- Beware that the mapping of names to signals may be
+ -- many-to-one. There may be aliases. Also, for all
+ -- signal names that are not supported on the current system
+ -- the value of the corresponding constant will be zero.
+
+ SIGHUP : constant Interrupt_ID :=
+ System.OS_Interface.SIGHUP; -- hangup
+
+ SIGINT : constant Interrupt_ID :=
+ System.OS_Interface.SIGINT; -- interrupt (rubout)
+
+ SIGQUIT : constant Interrupt_ID :=
+ System.OS_Interface.SIGQUIT; -- quit (ASCD FS)
+
+ SIGILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGILL; -- illegal instruction (not reset)
+
+ SIGTRAP : constant Interrupt_ID :=
+ System.OS_Interface.SIGTRAP; -- trace trap (not reset)
+
+ SIGIOT : constant Interrupt_ID :=
+ System.OS_Interface.SIGIOT; -- IOT instruction
+
+ SIGABRT : constant Interrupt_ID :=
+ System.OS_Interface.SIGABRT; -- used by abort, replace SIGIOT in the
+ -- future
+
+ SIGEMT : constant Interrupt_ID :=
+ System.OS_Interface.SIGEMT; -- EMT instruction
+
+ SIGFPE : constant Interrupt_ID :=
+ System.OS_Interface.SIGFPE; -- floating point exception
+
+ SIGKILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGKILL; -- kill (cannot be caught or ignored)
+
+ SIGBUS : constant Interrupt_ID :=
+ System.OS_Interface.SIGBUS; -- bus error
+
+ SIGSEGV : constant Interrupt_ID :=
+ System.OS_Interface.SIGSEGV; -- segmentation violation
+
+ SIGSYS : constant Interrupt_ID :=
+ System.OS_Interface.SIGSYS; -- bad argument to system call
+
+ SIGPIPE : constant Interrupt_ID :=
+ System.OS_Interface.SIGPIPE; -- write on pipe with no one to read it
+
+ SIGALRM : constant Interrupt_ID :=
+ System.OS_Interface.SIGALRM; -- alarm clock
+
+ SIGTERM : constant Interrupt_ID :=
+ System.OS_Interface.SIGTERM; -- software termination signal from kill
+
+ SIGUSR1 : constant Interrupt_ID :=
+ System.OS_Interface.SIGUSR1; -- user defined signal 1
+
+ SIGUSR2 : constant Interrupt_ID :=
+ System.OS_Interface.SIGUSR2; -- user defined signal 2
+
+ SIGCLD : constant Interrupt_ID :=
+ System.OS_Interface.SIGCLD; -- alias for SIGCHLD
+
+ SIGCHLD : constant Interrupt_ID :=
+ System.OS_Interface.SIGCHLD; -- child status change
+
+ SIGPWR : constant Interrupt_ID :=
+ System.OS_Interface.SIGPWR; -- power-fail restart
+
+ SIGWINCH : constant Interrupt_ID :=
+ System.OS_Interface.SIGWINCH; -- window size change
+
+ SIGURG : constant Interrupt_ID :=
+ System.OS_Interface.SIGURG; -- urgent condition on IO channel
+
+ SIGPOLL : constant Interrupt_ID :=
+ System.OS_Interface.SIGPOLL; -- pollable event occurred
+
+ SIGIO : constant Interrupt_ID :=
+ System.OS_Interface.SIGIO; -- I/O possible (Solaris SIGPOLL alias)
+
+ SIGSTOP : constant Interrupt_ID :=
+ System.OS_Interface.SIGSTOP; -- stop (cannot be caught or ignored)
+
+ SIGTSTP : constant Interrupt_ID :=
+ System.OS_Interface.SIGTSTP; -- user stop requested from tty
+
+ SIGCONT : constant Interrupt_ID :=
+ System.OS_Interface.SIGCONT; -- stopped process has been continued
+
+ SIGTTIN : constant Interrupt_ID :=
+ System.OS_Interface.SIGTTIN; -- background tty read attempted
+
+ SIGTTOU : constant Interrupt_ID :=
+ System.OS_Interface.SIGTTOU; -- background tty write attempted
+
+ SIGVTALRM : constant Interrupt_ID :=
+ System.OS_Interface.SIGVTALRM; -- virtual timer expired
+
+ SIGPROF : constant Interrupt_ID :=
+ System.OS_Interface.SIGPROF; -- profiling timer expired
+
+ SIGXCPU : constant Interrupt_ID :=
+ System.OS_Interface.SIGXCPU; -- CPU time limit exceeded
+
+ SIGXFSZ : constant Interrupt_ID :=
+ System.OS_Interface.SIGXFSZ; -- filesize limit exceeded
+
+ SIGK32 : constant Interrupt_ID :=
+ System.OS_Interface.SIGK32; -- reserved for kernel (IRIX)
+
+ SIGCKPT : constant Interrupt_ID :=
+ System.OS_Interface.SIGCKPT; -- Checkpoint warning
+
+ SIGRESTART : constant Interrupt_ID :=
+ System.OS_Interface.SIGRESTART; -- Restart warning
+
+ SIGUME : constant Interrupt_ID :=
+ System.OS_Interface.SIGUME; -- Uncorrectable memory error
+
+ -- Signals defined for Posix 1003.1c.
+
+ SIGPTINTR : constant Interrupt_ID :=
+ System.OS_Interface.SIGPTINTR; -- Pthread Interrupt Signal
+
+ SIGPTRESCHED : constant Interrupt_ID :=
+ System.OS_Interface.SIGPTRESCHED; -- Pthread Rescheduling Signal
+
+ -- Posix 1003.1b signals
+
+ SIGRTMIN : constant Interrupt_ID :=
+ System.OS_Interface.SIGRTMIN; -- Posix 1003.1b signals
+
+ SIGRTMAX : constant Interrupt_ID :=
+ System.OS_Interface.SIGRTMAX; -- Posix 1003.1b signals
+
+end Ada.Interrupts.Names;
diff --git a/gcc/ada/a-intnam-linux.ads b/gcc/ada/a-intnam-linux.ads
new file mode 100644
index 00000000000..ce9ccc774db
--- /dev/null
+++ b/gcc/ada/a-intnam-linux.ads
@@ -0,0 +1,168 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- A D A . I N T E R R U P T S . N A M E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-2002 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- --
+-- 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, 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, --
+-- 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 is a GNU/Linux version of this package.
+--
+-- The following signals are reserved by the run time (FSU threads):
+--
+-- SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGTRAP, SIGABRT, SIGINT,
+-- SIGALRM, SIGVTALRM, SIGUNUSED, SIGSTOP, SIGKILL
+--
+-- The following signals are reserved by the run time (LinuxThreads):
+--
+-- SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGTRAP, SIGABRT, SIGINT,
+-- SIGUSR1, SIGUSR2, SIGVTALRM, SIGUNUSED, SIGSTOP, SIGKILL
+--
+-- The pragma Unreserve_All_Interrupts affects the following signal(s):
+--
+-- SIGINT: made available for Ada handler
+
+-- This target-dependent package spec contains names of interrupts
+-- supported by the local system.
+
+with System.OS_Interface;
+-- used for names of interrupts
+
+package Ada.Interrupts.Names is
+
+ -- Beware that the mapping of names to signals may be
+ -- many-to-one. There may be aliases. Also, for all
+ -- signal names that are not supported on the current system
+ -- the value of the corresponding constant will be zero.
+
+ SIGHUP : constant Interrupt_ID :=
+ System.OS_Interface.SIGHUP; -- hangup
+
+ SIGINT : constant Interrupt_ID :=
+ System.OS_Interface.SIGINT; -- interrupt (rubout)
+
+ SIGQUIT : constant Interrupt_ID :=
+ System.OS_Interface.SIGQUIT; -- quit (ASCD FS)
+
+ SIGILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGILL; -- illegal instruction (not reset)
+
+ SIGTRAP : constant Interrupt_ID :=
+ System.OS_Interface.SIGTRAP; -- trace trap (not reset)
+
+ SIGIOT : constant Interrupt_ID :=
+ System.OS_Interface.SIGIOT; -- IOT instruction
+
+ SIGABRT : constant Interrupt_ID := -- used by abort,
+ System.OS_Interface.SIGABRT; -- replace SIGIOT in the future
+
+ SIGFPE : constant Interrupt_ID :=
+ System.OS_Interface.SIGFPE; -- floating point exception
+
+ SIGKILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGKILL; -- kill (cannot be caught or ignored)
+
+ SIGBUS : constant Interrupt_ID :=
+ System.OS_Interface.SIGBUS; -- bus error
+
+ SIGSEGV : constant Interrupt_ID :=
+ System.OS_Interface.SIGSEGV; -- segmentation violation
+
+ SIGPIPE : constant Interrupt_ID := -- write on a pipe with
+ System.OS_Interface.SIGPIPE; -- no one to read it
+
+ SIGALRM : constant Interrupt_ID :=
+ System.OS_Interface.SIGALRM; -- alarm clock
+
+ SIGTERM : constant Interrupt_ID :=
+ System.OS_Interface.SIGTERM; -- software termination signal from kill
+
+ SIGUSR1 : constant Interrupt_ID :=
+ System.OS_Interface.SIGUSR1; -- user defined signal 1
+
+ SIGUSR2 : constant Interrupt_ID :=
+ System.OS_Interface.SIGUSR2; -- user defined signal 2
+
+ SIGCLD : constant Interrupt_ID :=
+ System.OS_Interface.SIGCLD; -- child status change
+
+ SIGCHLD : constant Interrupt_ID :=
+ System.OS_Interface.SIGCHLD; -- 4.3BSD's/POSIX name for SIGCLD
+
+ SIGWINCH : constant Interrupt_ID :=
+ System.OS_Interface.SIGWINCH; -- window size change
+
+ SIGURG : constant Interrupt_ID :=
+ System.OS_Interface.SIGURG; -- urgent condition on IO channel
+
+ SIGPOLL : constant Interrupt_ID :=
+ System.OS_Interface.SIGPOLL; -- pollable event occurred
+
+ SIGIO : constant Interrupt_ID := -- input/output possible,
+ System.OS_Interface.SIGIO; -- SIGPOLL alias (Solaris)
+
+ SIGSTOP : constant Interrupt_ID :=
+ System.OS_Interface.SIGSTOP; -- stop (cannot be caught or ignored)
+
+ SIGTSTP : constant Interrupt_ID :=
+ System.OS_Interface.SIGTSTP; -- user stop requested from tty
+
+ SIGCONT : constant Interrupt_ID :=
+ System.OS_Interface.SIGCONT; -- stopped process has been continued
+
+ SIGTTIN : constant Interrupt_ID :=
+ System.OS_Interface.SIGTTIN; -- background tty read attempted
+
+ SIGTTOU : constant Interrupt_ID :=
+ System.OS_Interface.SIGTTOU; -- background tty write attempted
+
+ SIGVTALRM : constant Interrupt_ID :=
+ System.OS_Interface.SIGVTALRM; -- virtual timer expired
+
+ SIGPROF : constant Interrupt_ID :=
+ System.OS_Interface.SIGPROF; -- profiling timer expired
+
+ SIGXCPU : constant Interrupt_ID :=
+ System.OS_Interface.SIGXCPU; -- CPU time limit exceeded
+
+ SIGXFSZ : constant Interrupt_ID :=
+ System.OS_Interface.SIGXFSZ; -- filesize limit exceeded
+
+ SIGUNUSED : constant Interrupt_ID :=
+ System.OS_Interface.SIGUNUSED; -- unused signal
+
+ SIGSTKFLT : constant Interrupt_ID :=
+ System.OS_Interface.SIGSTKFLT; -- stack fault on coprocessor
+
+ SIGLOST : constant Interrupt_ID :=
+ System.OS_Interface.SIGLOST; -- Linux alias for SIGIO
+
+ SIGPWR : constant Interrupt_ID :=
+ System.OS_Interface.SIGPWR; -- Power failure
+
+end Ada.Interrupts.Names;
diff --git a/gcc/ada/a-intnam-lynxos.ads b/gcc/ada/a-intnam-lynxos.ads
new file mode 100644
index 00000000000..edc91159690
--- /dev/null
+++ b/gcc/ada/a-intnam-lynxos.ads
@@ -0,0 +1,165 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- A D A . I N T E R R U P T S . N A M E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-2002 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- --
+-- 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, 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, --
+-- 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 is a LynxOS version of this package.
+--
+-- The following signals are reserved by the run time:
+--
+-- SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGTRAP, SIGABRT, SIGINT,
+-- SIGWAITING, SIGLWP, SIGTTIN, SIGTTOU, SIGTSTP, SIGPROF, SIGSTOP, SIGKILL
+--
+-- The pragma Unreserve_All_Interrupts affects the following signal(s):
+--
+-- SIGINT: made available for Ada handler
+
+with System.OS_Interface;
+-- used for names of interrupts
+
+package Ada.Interrupts.Names is
+
+ -- Beware that the mapping of names to signals may be
+ -- many-to-one. There may be aliases.
+
+ SIGHUP : constant Interrupt_ID :=
+ System.OS_Interface.SIGHUP; -- hangup
+
+ SIGINT : constant Interrupt_ID :=
+ System.OS_Interface.SIGINT; -- interrupt (rubout)
+
+ SIGQUIT : constant Interrupt_ID :=
+ System.OS_Interface.SIGQUIT; -- quit (ASCD FS)
+
+ SIGILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGILL; -- illegal instruction (not reset)
+
+ SIGTRAP : constant Interrupt_ID :=
+ System.OS_Interface.SIGTRAP; -- trace trap (not reset)
+
+ SIGBRK : constant Interrupt_ID :=
+ System.OS_Interface.SIGBRK; -- break
+
+ SIGIOT : constant Interrupt_ID :=
+ System.OS_Interface.SIGIOT; -- IOT instruction
+
+ SIGABRT : constant Interrupt_ID := -- used by abort,
+ System.OS_Interface.SIGABRT; -- replace SIGIOT in the future
+
+ SIGCORE : constant Interrupt_ID :=
+ System.OS_Interface.SIGCORE; -- kill with core dump
+
+ SIGEMT : constant Interrupt_ID :=
+ System.OS_Interface.SIGEMT; -- EMT instruction
+
+ SIGFPE : constant Interrupt_ID :=
+ System.OS_Interface.SIGFPE; -- floating point exception
+
+ SIGKILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGKILL; -- kill (cannot be caught or ignored)
+
+ SIGBUS : constant Interrupt_ID :=
+ System.OS_Interface.SIGBUS; -- bus error
+
+ SIGSEGV : constant Interrupt_ID :=
+ System.OS_Interface.SIGSEGV; -- segmentation violation
+
+ SIGSYS : constant Interrupt_ID :=
+ System.OS_Interface.SIGSYS; -- bad argument to system call
+
+ SIGPIPE : constant Interrupt_ID := -- write on a pipe with
+ System.OS_Interface.SIGPIPE; -- no one to read it
+
+ SIGALRM : constant Interrupt_ID :=
+ System.OS_Interface.SIGALRM; -- alarm clock
+
+ SIGTERM : constant Interrupt_ID :=
+ System.OS_Interface.SIGTERM; -- software termination signal from kill
+
+ SIGURG : constant Interrupt_ID :=
+ System.OS_Interface.SIGURG; -- urgent condition on IO channel
+
+ SIGSTOP : constant Interrupt_ID :=
+ System.OS_Interface.SIGSTOP; -- stop (cannot be caught or ignored)
+
+ SIGTSTP : constant Interrupt_ID :=
+ System.OS_Interface.SIGTSTP; -- user stop requested from tty
+
+ SIGCONT : constant Interrupt_ID :=
+ System.OS_Interface.SIGCONT; -- stopped process has been continued
+
+ SIGCLD : constant Interrupt_ID :=
+ System.OS_Interface.SIGCLD; -- child status change
+
+ SIGCHLD : constant Interrupt_ID :=
+ System.OS_Interface.SIGCHLD; -- 4.3BSD's/POSIX name for SIGCLD
+
+ SIGTTIN : constant Interrupt_ID :=
+ System.OS_Interface.SIGTTIN; -- background tty read attempted
+
+ SIGTTOU : constant Interrupt_ID :=
+ System.OS_Interface.SIGTTOU; -- background tty write attempted
+
+ SIGPOLL : constant Interrupt_ID :=
+ System.OS_Interface.SIGPOLL; -- pollable event occurred
+
+ SIGIO : constant Interrupt_ID := -- input/output possible,
+ System.OS_Interface.SIGIO; -- SIGPOLL alias (Solaris)
+
+ SIGXCPU : constant Interrupt_ID :=
+ System.OS_Interface.SIGXCPU; -- CPU time limit exceeded
+
+ SIGXFSZ : constant Interrupt_ID :=
+ System.OS_Interface.SIGXFSZ; -- filesize limit exceeded
+
+ SIGVTALRM : constant Interrupt_ID :=
+ System.OS_Interface.SIGVTALRM; -- virtual timer expired
+
+ SIGPROF : constant Interrupt_ID :=
+ System.OS_Interface.SIGPROF; -- profiling timer expired
+
+ SIGWINCH : constant Interrupt_ID :=
+ System.OS_Interface.SIGWINCH; -- window size change
+
+ SIGLOST : constant Interrupt_ID :=
+ System.OS_Interface.SIGLOST; -- SUN 4.1 compatibility
+
+ SIGUSR1 : constant Interrupt_ID :=
+ System.OS_Interface.SIGUSR1; -- user defined signal 1
+
+ SIGUSR2 : constant Interrupt_ID :=
+ System.OS_Interface.SIGUSR2; -- user defined signal 2
+
+ SIGPRIO : constant Interrupt_ID :=
+ System.OS_Interface.SIGPRIO;
+ -- sent to a process with its priority
+ -- or group is changed
+end Ada.Interrupts.Names;
diff --git a/gcc/ada/a-intnam-mingw.ads b/gcc/ada/a-intnam-mingw.ads
new file mode 100644
index 00000000000..4d02e17bf60
--- /dev/null
+++ b/gcc/ada/a-intnam-mingw.ads
@@ -0,0 +1,67 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- A D A . I N T E R R U P T S . N A M E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1997-2002 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- --
+-- 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, 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, --
+-- 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 is a NT (native) version of this package.
+
+-- This target-dependent package spec contains names of interrupts
+-- supported by the local system.
+
+with System.OS_Interface;
+-- used for names of interrupts
+
+package Ada.Interrupts.Names is
+
+ -- Beware that the mapping of names to signals may be
+ -- many-to-one. There may be aliases. Also, for all
+ -- signal names that are not supported on the current system
+ -- the value of the corresponding constant will be zero.
+
+ SIGINT : constant Interrupt_ID :=
+ System.OS_Interface.SIGINT; -- interrupt (rubout)
+
+ SIGILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGILL; -- illegal instruction (not reset)
+
+ SIGABRT : constant Interrupt_ID := -- used by abort,
+ System.OS_Interface.SIGABRT; -- replace SIGIOT in the future
+
+ SIGFPE : constant Interrupt_ID :=
+ System.OS_Interface.SIGFPE; -- floating point exception
+
+ SIGSEGV : constant Interrupt_ID :=
+ System.OS_Interface.SIGSEGV; -- segmentation violation
+
+ SIGTERM : constant Interrupt_ID :=
+ System.OS_Interface.SIGTERM; -- software termination signal from kill
+
+end Ada.Interrupts.Names;
diff --git a/gcc/ada/a-intnam-os2.ads b/gcc/ada/a-intnam-os2.ads
new file mode 100644
index 00000000000..6733730b372
--- /dev/null
+++ b/gcc/ada/a-intnam-os2.ads
@@ -0,0 +1,43 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- A D A . I N T E R R U P T S . N A M E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2003, Ada Core Technologies --
+-- --
+-- 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, 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, --
+-- 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 is an OS/2 version of this package.
+
+-- This target-dependent package spec contains names of interrupts
+-- supported by the local system.
+
+-- This is a stub, for systems that do not support interrupts (or signals)
+
+package Ada.Interrupts.Names is
+end Ada.Interrupts.Names;
diff --git a/gcc/ada/a-intnam-solaris.ads b/gcc/ada/a-intnam-solaris.ads
new file mode 100644
index 00000000000..d6fc181ea9e
--- /dev/null
+++ b/gcc/ada/a-intnam-solaris.ads
@@ -0,0 +1,179 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- A D A . I N T E R R U P T S . N A M E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-2002 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- --
+-- 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, 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, --
+-- 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 is a Solaris version of this package.
+--
+-- The following signals are reserved by the run time (native threads):
+--
+-- SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGTRAP, SIGABRT, SIGINT,
+-- SIGLWP, SIGWAITING, SIGCANCEL, SIGSTOP, SIGKILL
+--
+-- The following signals are reserved by the run time (FSU threads):
+--
+-- SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGTRAP, SIGTERM, SIGABRT, SIGINT,
+-- SIGLWP, SIGALRM, SIGVTALRM, SIGAITING, SIGSTOP, SIGKILL
+--
+-- The pragma Unreserve_All_Interrupts affects the following signal(s):
+--
+-- SIGINT: made available for Ada handlers
+
+with System.OS_Interface;
+-- used for names of interrupts
+
+package Ada.Interrupts.Names is
+
+ -- Beware that the mapping of names to signals may be
+ -- many-to-one. There may be aliases. Also, for all
+ -- signal names that are not supported on the current system
+ -- the value of the corresponding constant will be zero.
+
+ SIGHUP : constant Interrupt_ID :=
+ System.OS_Interface.SIGHUP; -- hangup
+
+ SIGINT : constant Interrupt_ID :=
+ System.OS_Interface.SIGINT; -- interrupt (rubout)
+
+ SIGQUIT : constant Interrupt_ID :=
+ System.OS_Interface.SIGQUIT; -- quit (ASCD FS)
+
+ SIGILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGILL; -- illegal instruction (not reset)
+
+ SIGTRAP : constant Interrupt_ID :=
+ System.OS_Interface.SIGTRAP; -- trace trap (not reset)
+
+ SIGIOT : constant Interrupt_ID :=
+ System.OS_Interface.SIGIOT; -- IOT instruction
+
+ SIGABRT : constant Interrupt_ID := -- used by abort,
+ System.OS_Interface.SIGABRT; -- replace SIGIOT in the future
+
+ SIGEMT : constant Interrupt_ID :=
+ System.OS_Interface.SIGEMT; -- EMT instruction
+
+ SIGFPE : constant Interrupt_ID :=
+ System.OS_Interface.SIGFPE; -- floating point exception
+
+ SIGKILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGKILL; -- kill (cannot be caught or ignored)
+
+ SIGBUS : constant Interrupt_ID :=
+ System.OS_Interface.SIGBUS; -- bus error
+
+ SIGSEGV : constant Interrupt_ID :=
+ System.OS_Interface.SIGSEGV; -- segmentation violation
+
+ SIGSYS : constant Interrupt_ID :=
+ System.OS_Interface.SIGSYS; -- bad argument to system call
+
+ SIGPIPE : constant Interrupt_ID := -- write on a pipe with
+ System.OS_Interface.SIGPIPE; -- no one to read it
+
+ SIGALRM : constant Interrupt_ID :=
+ System.OS_Interface.SIGALRM; -- alarm clock
+
+ SIGTERM : constant Interrupt_ID :=
+ System.OS_Interface.SIGTERM; -- software termination signal from kill
+
+ SIGUSR1 : constant Interrupt_ID :=
+ System.OS_Interface.SIGUSR1; -- user defined signal 1
+
+ SIGUSR2 : constant Interrupt_ID :=
+ System.OS_Interface.SIGUSR2; -- user defined signal 2
+
+ SIGCLD : constant Interrupt_ID :=
+ System.OS_Interface.SIGCLD; -- child status change
+
+ SIGCHLD : constant Interrupt_ID :=
+ System.OS_Interface.SIGCHLD; -- 4.3BSD's/POSIX name for SIGCLD
+
+ SIGWINCH : constant Interrupt_ID :=
+ System.OS_Interface.SIGWINCH; -- window size change
+
+ SIGURG : constant Interrupt_ID :=
+ System.OS_Interface.SIGURG; -- urgent condition on IO channel
+
+ SIGPOLL : constant Interrupt_ID :=
+ System.OS_Interface.SIGPOLL; -- pollable event occurred
+
+ SIGIO : constant Interrupt_ID := -- input/output possible,
+ System.OS_Interface.SIGIO; -- SIGPOLL alias (Solaris)
+
+ SIGSTOP : constant Interrupt_ID :=
+ System.OS_Interface.SIGSTOP; -- stop (cannot be caught or ignored)
+
+ SIGTSTP : constant Interrupt_ID :=
+ System.OS_Interface.SIGTSTP; -- user stop requested from tty
+
+ SIGCONT : constant Interrupt_ID :=
+ System.OS_Interface.SIGCONT; -- stopped process has been continued
+
+ SIGTTIN : constant Interrupt_ID :=
+ System.OS_Interface.SIGTTIN; -- background tty read attempted
+
+ SIGTTOU : constant Interrupt_ID :=
+ System.OS_Interface.SIGTTOU; -- background tty write attempted
+
+ SIGVTALRM : constant Interrupt_ID :=
+ System.OS_Interface.SIGVTALRM; -- virtual timer expired
+
+ SIGPROF : constant Interrupt_ID :=
+ System.OS_Interface.SIGPROF; -- profiling timer expired
+
+ SIGXCPU : constant Interrupt_ID :=
+ System.OS_Interface.SIGXCPU; -- CPU time limit exceeded
+
+ SIGXFSZ : constant Interrupt_ID :=
+ System.OS_Interface.SIGXFSZ; -- filesize limit exceeded
+
+ SIGPWR : constant Interrupt_ID :=
+ System.OS_Interface.SIGPWR; -- power-fail restart
+
+ SIGWAITING : constant Interrupt_ID :=
+ System.OS_Interface.SIGWAITING; -- process's lwps blocked (Solaris)
+
+ SIGLWP : constant Interrupt_ID :=
+ System.OS_Interface.SIGLWP; -- used by thread library (Solaris)
+
+ SIGFREEZE : constant Interrupt_ID :=
+ System.OS_Interface.SIGFREEZE; -- used by CPR (Solaris)
+
+-- what is CPR????
+
+ SIGTHAW : constant Interrupt_ID :=
+ System.OS_Interface.SIGTHAW; -- used by CPR (Solaris)
+
+ SIGCANCEL : constant Interrupt_ID :=
+ System.OS_Interface.SIGCANCEL; -- used for thread cancel (Solaris)
+
+end Ada.Interrupts.Names;
diff --git a/gcc/ada/a-intnam-tru64.ads b/gcc/ada/a-intnam-tru64.ads
new file mode 100644
index 00000000000..95509a89d94
--- /dev/null
+++ b/gcc/ada/a-intnam-tru64.ads
@@ -0,0 +1,151 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- A D A . I N T E R R U P T S . N A M E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-2002 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- --
+-- 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, 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, --
+-- 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 is the DEC Unix 4.0 version of this package.
+--
+-- The following signals are reserved by the run time:
+--
+-- SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGABRT, SIGTRAP, SIGINT, SIGALRM,
+-- SIGSTOP, SIGKILL
+--
+-- The pragma Unreserve_All_Interrupts affects the following signal(s):
+--
+-- SIGINT: made available for Ada handler
+
+with System.OS_Interface;
+-- used for names of interrupts
+
+package Ada.Interrupts.Names is
+
+ -- Beware that the mapping of names to signals may be
+ -- many-to-one. There may be aliases. Also, for all
+ -- signal names that are not supported on the current system
+ -- the value of the corresponding constant will be zero.
+
+ SIGHUP : constant Interrupt_ID :=
+ System.OS_Interface.SIGHUP; -- hangup
+
+ SIGINT : constant Interrupt_ID :=
+ System.OS_Interface.SIGINT; -- interrupt (rubout)
+
+ SIGQUIT : constant Interrupt_ID :=
+ System.OS_Interface.SIGQUIT; -- quit (ASCD FS)
+
+ SIGILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGILL; -- illegal instruction (not reset)
+
+ SIGTRAP : constant Interrupt_ID :=
+ System.OS_Interface.SIGTRAP; -- trace trap (not reset)
+
+ SIGIOT : constant Interrupt_ID :=
+ System.OS_Interface.SIGIOT; -- IOT instruction
+
+ SIGABRT : constant Interrupt_ID := -- used by abort,
+ System.OS_Interface.SIGABRT; -- replace SIGIOT in the future
+
+ SIGEMT : constant Interrupt_ID :=
+ System.OS_Interface.SIGEMT; -- EMT instruction
+
+ SIGFPE : constant Interrupt_ID :=
+ System.OS_Interface.SIGFPE; -- floating point exception
+
+ SIGKILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGKILL; -- kill (cannot be caught or ignored)
+
+ SIGBUS : constant Interrupt_ID :=
+ System.OS_Interface.SIGBUS; -- bus error
+
+ SIGSEGV : constant Interrupt_ID :=
+ System.OS_Interface.SIGSEGV; -- segmentation violation
+
+ SIGSYS : constant Interrupt_ID :=
+ System.OS_Interface.SIGSYS; -- bad argument to system call
+
+ SIGPIPE : constant Interrupt_ID := -- write on a pipe with
+ System.OS_Interface.SIGPIPE; -- no one to read it
+
+ SIGALRM : constant Interrupt_ID :=
+ System.OS_Interface.SIGALRM; -- alarm clock
+
+ SIGTERM : constant Interrupt_ID :=
+ System.OS_Interface.SIGTERM; -- software termination signal from kill
+
+ SIGUSR1 : constant Interrupt_ID :=
+ System.OS_Interface.SIGUSR1; -- user defined signal 1
+
+ SIGUSR2 : constant Interrupt_ID :=
+ System.OS_Interface.SIGUSR2; -- user defined signal 2
+
+ SIGCHLD : constant Interrupt_ID :=
+ System.OS_Interface.SIGCHLD; -- 4.3BSD's/POSIX name for SIGCLD
+
+ SIGWINCH : constant Interrupt_ID :=
+ System.OS_Interface.SIGWINCH; -- window size change
+
+ SIGURG : constant Interrupt_ID :=
+ System.OS_Interface.SIGURG; -- urgent condition on IO channel
+
+ SIGPOLL : constant Interrupt_ID :=
+ System.OS_Interface.SIGPOLL; -- pollable event occurred
+
+ SIGIO : constant Interrupt_ID := -- input/output possible,
+ System.OS_Interface.SIGIO; -- SIGPOLL alias (Solaris)
+
+ SIGSTOP : constant Interrupt_ID :=
+ System.OS_Interface.SIGSTOP; -- stop (cannot be caught or ignored)
+
+ SIGTSTP : constant Interrupt_ID :=
+ System.OS_Interface.SIGTSTP; -- user stop requested from tty
+
+ SIGCONT : constant Interrupt_ID :=
+ System.OS_Interface.SIGCONT; -- stopped process has been continued
+
+ SIGTTIN : constant Interrupt_ID :=
+ System.OS_Interface.SIGTTIN; -- background tty read attempted
+
+ SIGTTOU : constant Interrupt_ID :=
+ System.OS_Interface.SIGTTOU; -- background tty write attempted
+
+ SIGVTALRM : constant Interrupt_ID :=
+ System.OS_Interface.SIGVTALRM; -- virtual timer expired
+
+ SIGPROF : constant Interrupt_ID :=
+ System.OS_Interface.SIGPROF; -- profiling timer expired
+
+ SIGXCPU : constant Interrupt_ID :=
+ System.OS_Interface.SIGXCPU; -- CPU time limit exceeded
+
+ SIGXFSZ : constant Interrupt_ID :=
+ System.OS_Interface.SIGXFSZ; -- filesize limit exceeded
+
+end Ada.Interrupts.Names;
diff --git a/gcc/ada/a-intnam-unixware.ads b/gcc/ada/a-intnam-unixware.ads
new file mode 100644
index 00000000000..b7009ab569e
--- /dev/null
+++ b/gcc/ada/a-intnam-unixware.ads
@@ -0,0 +1,164 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- A D A . I N T E R R U P T S . N A M E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-2002 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- --
+-- 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, 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, --
+-- 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 is a SCO UnixWare version of this package.
+--
+-- The following signals are reserved by the run time:
+--
+-- SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGTRAP, SIGABRT, SIGINT,
+-- SIGWAITING, SIGLWP, SIGTTIN, SIGTTOU, SIGTSTP, SIGPROF, SIGSTOP, SIGKILL
+--
+-- The pragma Unreserve_All_Interrupts affects the following signal(s):
+--
+-- SIGINT: made available for Ada handler
+
+with System.OS_Interface;
+-- used for names of interrupts
+
+package Ada.Interrupts.Names is
+
+ -- Beware that the mapping of names to signals may be
+ -- many-to-one. There may be aliases.
+
+ SIGHUP : constant Interrupt_ID :=
+ System.OS_Interface.SIGHUP; -- hangup
+
+ SIGINT : constant Interrupt_ID :=
+ System.OS_Interface.SIGINT; -- interrupt (rubout)
+
+ SIGQUIT : constant Interrupt_ID :=
+ System.OS_Interface.SIGQUIT; -- quit (ASCD FS)
+
+ SIGILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGILL; -- illegal instruction (not reset)
+
+ SIGTRAP : constant Interrupt_ID :=
+ System.OS_Interface.SIGTRAP; -- trace trap (not reset)
+
+ SIGIOT : constant Interrupt_ID :=
+ System.OS_Interface.SIGIOT; -- IOT instruction
+
+ SIGABRT : constant Interrupt_ID := -- used by abort,
+ System.OS_Interface.SIGABRT; -- replace SIGIOT in the future
+
+ SIGEMT : constant Interrupt_ID :=
+ System.OS_Interface.SIGEMT; -- EMT instruction
+
+ SIGFPE : constant Interrupt_ID :=
+ System.OS_Interface.SIGFPE; -- floating point exception
+
+ SIGKILL : constant Interrupt_ID :=
+ System.OS_Interface.SIGKILL; -- kill (cannot be caught or ignored)
+
+ SIGBUS : constant Interrupt_ID :=
+ System.OS_Interface.SIGBUS; -- bus error
+
+ SIGSEGV : constant Interrupt_ID :=
+ System.OS_Interface.SIGSEGV; -- segmentation violation
+
+ SIGSYS : constant Interrupt_ID :=
+ System.OS_Interface.SIGSYS; -- bad argument to system call
+
+ SIGPIPE : constant Interrupt_ID := -- write on a pipe with
+ System.OS_Interface.SIGPIPE; -- no one to read it
+
+ SIGALRM : constant Interrupt_ID :=
+ System.OS_Interface.SIGALRM; -- alarm clock
+
+ SIGTERM : constant Interrupt_ID :=
+ System.OS_Interface.SIGTERM; -- software termination signal from kill
+
+ SIGUSR1 : constant Interrupt_ID :=
+ System.OS_Interface.SIGUSR1; -- user defined signal 1
+
+ SIGUSR2 : constant Interrupt_ID :=
+ System.OS_Interface.SIGUSR2; -- user defined signal 2
+
+ SIGCLD : constant Interrupt_ID :=
+ System.OS_Interface.SIGCLD; -- child status change
+
+ SIGCHLD : constant Interrupt_ID :=
+ System.OS_Interface.SIGCHLD; -- 4.3BSD's/POSIX name for SIGCLD
+
+ SIGPWR : constant Interrupt_ID :=
+ System.OS_Interface.SIGPWR; -- power-fail restart
+
+ SIGWINCH : constant Interrupt_ID :=
+ System.OS_Interface.SIGWINCH; -- window size change
+
+ SIGURG : constant Interrupt_ID :=
+ System.OS_Interface.SIGURG; -- urgent condition on IO channel
+
+ SIGPOLL : constant Interrupt_ID :=
+ System.OS_Interface.SIGPOLL; -- pollable event occurred
+
+ SIGIO : constant Interrupt_ID := -- input/output possible,
+ System.OS_Interface.SIGIO; -- SIGPOLL alias (Solaris)
+
+ SIGSTOP : constant Interrupt_ID :=
+ System.OS_Interface.SIGSTOP; -- stop (cannot be caught or ignored)
+
+ SIGTSTP : constant Interrupt_ID :=
+ System.OS_Interface.SIGTSTP; -- user stop requested from tty
+
+ SIGCONT : constant Interrupt_ID :=
+ System.OS_Interface.SIGCONT; -- stopped process has been continued
+
+ SIGTTIN : constant Interrupt_ID :=
+ System.OS_Interface.SIGTTIN; -- background tty read attempted
+
+ SIGTTOU : constant Interrupt_ID :=
+ System.OS_Interface.SIGTTOU; -- background tty write attempted
+
+ SIGVTALRM : constant Interrupt_ID :=
+ System.OS_Interface.SIGVTALRM; -- virtual timer expired
+
+ SIGPROF : constant Interrupt_ID :=
+ System.OS_Interface.SIGPROF; -- profiling timer expired
+
+ SIGXCPU : constant Interrupt_ID :=
+ System.OS_Interface.SIGXCPU; -- CPU time limit exceeded
+
+ SIGXFSZ : constant Interrupt_ID :=
+ System.OS_Interface.SIGXFSZ; -- filesize limit exceeded
+
+ SIGWAITING : constant Interrupt_ID :=
+ System.OS_Interface.SIGWAITING; -- process's lwps blocked (Solaris)
+
+ SIGLWP : constant Interrupt_ID :=
+ System.OS_Interface.SIGLWP; -- used by thread library (Solaris)
+
+ SIGAIO : constant Interrupt_ID :=
+ System.OS_Interface.SIGAIO; -- Asynchronous I/O signal
+
+end Ada.Interrupts.Names;
diff --git a/gcc/ada/a-intnam-vms.ads b/gcc/ada/a-intnam-vms.ads
new file mode 100644
index 00000000000..7eec58fbeb7
--- /dev/null
+++ b/gcc/ada/a-intnam-vms.ads
@@ -0,0 +1,77 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- A D A . I N T E R R U P T S . N A M E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-2002 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- --
+-- 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, 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, --
+-- 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 is a OpenVMS/Alpha version of this package.
+--
+-- This target-dependent package spec contains names of interrupts
+-- supported by the local system.
+
+with System.OS_Interface;
+package Ada.Interrupts.Names is
+
+ package OS renames System.OS_Interface;
+
+ Interrupt_ID_0 : constant Interrupt_ID := OS.Interrupt_ID_0;
+ Interrupt_ID_1 : constant Interrupt_ID := OS.Interrupt_ID_1;
+ Interrupt_ID_2 : constant Interrupt_ID := OS.Interrupt_ID_2;
+ Interrupt_ID_3 : constant Interrupt_ID := OS.Interrupt_ID_3;
+ Interrupt_ID_4 : constant Interrupt_ID := OS.Interrupt_ID_4;
+ Interrupt_ID_5 : constant Interrupt_ID := OS.Interrupt_ID_5;
+ Interrupt_ID_6 : constant Interrupt_ID := OS.Interrupt_ID_6;
+ Interrupt_ID_7 : constant Interrupt_ID := OS.Interrupt_ID_7;
+ Interrupt_ID_8 : constant Interrupt_ID := OS.Interrupt_ID_8;
+ Interrupt_ID_9 : constant Interrupt_ID := OS.Interrupt_ID_9;
+ Interrupt_ID_10 : constant Interrupt_ID := OS.Interrupt_ID_10;
+ Interrupt_ID_11 : constant Interrupt_ID := OS.Interrupt_ID_11;
+ Interrupt_ID_12 : constant Interrupt_ID := OS.Interrupt_ID_12;
+ Interrupt_ID_13 : constant Interrupt_ID := OS.Interrupt_ID_13;
+ Interrupt_ID_14 : constant Interrupt_ID := OS.Interrupt_ID_14;
+ Interrupt_ID_15 : constant Interrupt_ID := OS.Interrupt_ID_15;
+ Interrupt_ID_16 : constant Interrupt_ID := OS.Interrupt_ID_16;
+ Interrupt_ID_17 : constant Interrupt_ID := OS.Interrupt_ID_17;
+ Interrupt_ID_18 : constant Interrupt_ID := OS.Interrupt_ID_18;
+ Interrupt_ID_19 : constant Interrupt_ID := OS.Interrupt_ID_19;
+ Interrupt_ID_20 : constant Interrupt_ID := OS.Interrupt_ID_20;
+ Interrupt_ID_21 : constant Interrupt_ID := OS.Interrupt_ID_21;
+ Interrupt_ID_22 : constant Interrupt_ID := OS.Interrupt_ID_22;
+ Interrupt_ID_23 : constant Interrupt_ID := OS.Interrupt_ID_23;
+ Interrupt_ID_24 : constant Interrupt_ID := OS.Interrupt_ID_24;
+ Interrupt_ID_25 : constant Interrupt_ID := OS.Interrupt_ID_25;
+ Interrupt_ID_26 : constant Interrupt_ID := OS.Interrupt_ID_26;
+ Interrupt_ID_27 : constant Interrupt_ID := OS.Interrupt_ID_27;
+ Interrupt_ID_28 : constant Interrupt_ID := OS.Interrupt_ID_28;
+ Interrupt_ID_29 : constant Interrupt_ID := OS.Interrupt_ID_29;
+ Interrupt_ID_30 : constant Interrupt_ID := OS.Interrupt_ID_30;
+ Interrupt_ID_31 : constant Interrupt_ID := OS.Interrupt_ID_31;
+
+end Ada.Interrupts.Names;
diff --git a/gcc/ada/a-intnam-vxworks.ads b/gcc/ada/a-intnam-vxworks.ads
new file mode 100644
index 00000000000..757b15376fb
--- /dev/null
+++ b/gcc/ada/a-intnam-vxworks.ads
@@ -0,0 +1,44 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- A D A . I N T E R R U P T S . N A M E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1998-2001 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- --
+-- 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, 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, --
+-- 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 is the VxWorks version of this package.
+
+with System.OS_Interface;
+
+package Ada.Interrupts.Names is
+
+ subtype Hardware_Interrupts is Interrupt_ID
+ range Interrupt_ID'First .. System.OS_Interface.Max_HW_Interrupt;
+ -- Range of values that can be used for hardware interrupts.
+
+end Ada.Interrupts.Names;
diff --git a/gcc/ada/a-numaux-libc-x86.ads b/gcc/ada/a-numaux-libc-x86.ads
new file mode 100644
index 00000000000..0f84a9fe053
--- /dev/null
+++ b/gcc/ada/a-numaux-libc-x86.ads
@@ -0,0 +1,108 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUNTIME COMPONENTS --
+-- --
+-- A D A . N U M E R I C S . A U X --
+-- --
+-- S p e c --
+-- (C Library Version for x86) --
+-- --
+-- Copyright (C) 1992-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides the basic computational interface for the generic
+-- elementary functions. The C library version interfaces with the routines
+-- in the C mathematical library, and is thus quite portable, although it may
+-- not necessarily meet the requirements for accuracy in the numerics annex.
+-- One advantage of using this package is that it will interface directly to
+-- hardware instructions, such as the those provided on the Intel x86.
+
+-- Note: there are two versions of this package. One using the 80-bit x86
+-- long double format (which is this version), and one using 64-bit IEEE
+-- double (see file a-numaux.ads).
+
+package Ada.Numerics.Aux is
+pragma Pure (Aux);
+
+ pragma Linker_Options ("-lm");
+
+ type Double is digits 18;
+
+ -- We import these functions directly from C. Note that we label them
+ -- all as pure functions, because indeed all of them are in fact pure!
+
+ function Sin (X : Double) return Double;
+ pragma Import (C, Sin, "sinl");
+ pragma Pure_Function (Sin);
+
+ function Cos (X : Double) return Double;
+ pragma Import (C, Cos, "cosl");
+ pragma Pure_Function (Cos);
+
+ function Tan (X : Double) return Double;
+ pragma Import (C, Tan, "tanl");
+ pragma Pure_Function (Tan);
+
+ function Exp (X : Double) return Double;
+ pragma Import (C, Exp, "expl");
+ pragma Pure_Function (Exp);
+
+ function Sqrt (X : Double) return Double;
+ pragma Import (C, Sqrt, "sqrtl");
+ pragma Pure_Function (Sqrt);
+
+ function Log (X : Double) return Double;
+ pragma Import (C, Log, "logl");
+ pragma Pure_Function (Log);
+
+ function Acos (X : Double) return Double;
+ pragma Import (C, Acos, "acosl");
+ pragma Pure_Function (Acos);
+
+ function Asin (X : Double) return Double;
+ pragma Import (C, Asin, "asinl");
+ pragma Pure_Function (Asin);
+
+ function Atan (X : Double) return Double;
+ pragma Import (C, Atan, "atanl");
+ pragma Pure_Function (Atan);
+
+ function Sinh (X : Double) return Double;
+ pragma Import (C, Sinh, "sinhl");
+ pragma Pure_Function (Sinh);
+
+ function Cosh (X : Double) return Double;
+ pragma Import (C, Cosh, "coshl");
+ pragma Pure_Function (Cosh);
+
+ function Tanh (X : Double) return Double;
+ pragma Import (C, Tanh, "tanhl");
+ pragma Pure_Function (Tanh);
+
+ function Pow (X, Y : Double) return Double;
+ pragma Import (C, Pow, "powl");
+ pragma Pure_Function (Pow);
+
+end Ada.Numerics.Aux;
diff --git a/gcc/ada/a-numaux-vxworks.ads b/gcc/ada/a-numaux-vxworks.ads
new file mode 100644
index 00000000000..3a995a12bd1
--- /dev/null
+++ b/gcc/ada/a-numaux-vxworks.ads
@@ -0,0 +1,110 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUNTIME COMPONENTS --
+-- --
+-- A D A . N U M E R I C S . A U X --
+-- --
+-- S p e c --
+-- (C Library Version, VxWorks) --
+-- --
+-- Copyright (C) 1992-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides the basic computational interface for the generic
+-- elementary functions. The C library version interfaces with the routines
+-- in the C mathematical library, and is thus quite portable, although it may
+-- not necessarily meet the requirements for accuracy in the numerics annex.
+-- One advantage of using this package is that it will interface directly to
+-- hardware instructions, such as the those provided on the Intel x86.
+
+-- Note: there are two versions of this package. One using the normal IEEE
+-- 64-bit double format (which is this version), and one using 80-bit x86
+-- long double (see file 4onumaux.ads).
+
+package Ada.Numerics.Aux is
+pragma Pure (Aux);
+
+ -- This version omits the pragma linker_options ("-lm") since there is
+ -- no libm.a library for VxWorks.
+
+ type Double is digits 15;
+ -- Type Double is the type used to call the C routines
+
+ -- We import these functions directly from C. Note that we label them
+ -- all as pure functions, because indeed all of them are in fact pure!
+
+ function Sin (X : Double) return Double;
+ pragma Import (C, Sin, "sin");
+ pragma Pure_Function (Sin);
+
+ function Cos (X : Double) return Double;
+ pragma Import (C, Cos, "cos");
+ pragma Pure_Function (Cos);
+
+ function Tan (X : Double) return Double;
+ pragma Import (C, Tan, "tan");
+ pragma Pure_Function (Tan);
+
+ function Exp (X : Double) return Double;
+ pragma Import (C, Exp, "exp");
+ pragma Pure_Function (Exp);
+
+ function Sqrt (X : Double) return Double;
+ pragma Import (C, Sqrt, "sqrt");
+ pragma Pure_Function (Sqrt);
+
+ function Log (X : Double) return Double;
+ pragma Import (C, Log, "log");
+ pragma Pure_Function (Log);
+
+ function Acos (X : Double) return Double;
+ pragma Import (C, Acos, "acos");
+ pragma Pure_Function (Acos);
+
+ function Asin (X : Double) return Double;
+ pragma Import (C, Asin, "asin");
+ pragma Pure_Function (Asin);
+
+ function Atan (X : Double) return Double;
+ pragma Import (C, Atan, "atan");
+ pragma Pure_Function (Atan);
+
+ function Sinh (X : Double) return Double;
+ pragma Import (C, Sinh, "sinh");
+ pragma Pure_Function (Sinh);
+
+ function Cosh (X : Double) return Double;
+ pragma Import (C, Cosh, "cosh");
+ pragma Pure_Function (Cosh);
+
+ function Tanh (X : Double) return Double;
+ pragma Import (C, Tanh, "tanh");
+ pragma Pure_Function (Tanh);
+
+ function Pow (X, Y : Double) return Double;
+ pragma Import (C, Pow, "pow");
+ pragma Pure_Function (Pow);
+
+end Ada.Numerics.Aux;
diff --git a/gcc/ada/a-numaux-x86.adb b/gcc/ada/a-numaux-x86.adb
new file mode 100644
index 00000000000..a13733305a1
--- /dev/null
+++ b/gcc/ada/a-numaux-x86.adb
@@ -0,0 +1,592 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUNTIME COMPONENTS --
+-- --
+-- A D A . N U M E R I C S . A U X --
+-- --
+-- B o d y --
+-- (Machine Version for x86) --
+-- --
+-- Copyright (C) 1998-2001 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- File a-numaux.adb <- 86numaux.adb
+
+-- This version of Numerics.Aux is for the IEEE Double Extended floating
+-- point format on x86.
+
+with System.Machine_Code; use System.Machine_Code;
+
+package body Ada.Numerics.Aux is
+
+ NL : constant String := ASCII.LF & ASCII.HT;
+
+ type FPU_Stack_Pointer is range 0 .. 7;
+ for FPU_Stack_Pointer'Size use 3;
+
+ type FPU_Status_Word is record
+ B : Boolean; -- FPU Busy (for 8087 compatibility only)
+ ES : Boolean; -- Error Summary Status
+ SF : Boolean; -- Stack Fault
+
+ Top : FPU_Stack_Pointer;
+
+ -- Condition Code Flags
+
+ -- C2 is set by FPREM and FPREM1 to indicate incomplete reduction.
+ -- In case of successfull recorction, C0, C3 and C1 are set to the
+ -- three least significant bits of the result (resp. Q2, Q1 and Q0).
+
+ -- C2 is used by FPTAN, FSIN, FCOS, and FSINCOS to indicate that
+ -- that source operand is beyond the allowable range of
+ -- -2.0**63 .. 2.0**63.
+
+ C3 : Boolean;
+ C2 : Boolean;
+ C1 : Boolean;
+ C0 : Boolean;
+
+ -- Exception Flags
+
+ PE : Boolean; -- Precision
+ UE : Boolean; -- Underflow
+ OE : Boolean; -- Overflow
+ ZE : Boolean; -- Zero Divide
+ DE : Boolean; -- Denormalized Operand
+ IE : Boolean; -- Invalid Operation
+ end record;
+
+ for FPU_Status_Word use record
+ B at 0 range 15 .. 15;
+ C3 at 0 range 14 .. 14;
+ Top at 0 range 11 .. 13;
+ C2 at 0 range 10 .. 10;
+ C1 at 0 range 9 .. 9;
+ C0 at 0 range 8 .. 8;
+ ES at 0 range 7 .. 7;
+ SF at 0 range 6 .. 6;
+ PE at 0 range 5 .. 5;
+ UE at 0 range 4 .. 4;
+ OE at 0 range 3 .. 3;
+ ZE at 0 range 2 .. 2;
+ DE at 0 range 1 .. 1;
+ IE at 0 range 0 .. 0;
+ end record;
+
+ for FPU_Status_Word'Size use 16;
+
+ -----------------------
+ -- Local subprograms --
+ -----------------------
+
+ function Is_Nan (X : Double) return Boolean;
+ -- Return True iff X is a IEEE NaN value
+
+ function Logarithmic_Pow (X, Y : Double) return Double;
+ -- Implementation of X**Y using Exp and Log functions (binary base)
+ -- to calculate the exponentiation. This is used by Pow for values
+ -- for values of Y in the open interval (-0.25, 0.25)
+
+ function Reduce (X : Double) return Double;
+ -- Implement partial reduction of X by Pi in the x86.
+
+ -- Note that for the Sin, Cos and Tan functions completely accurate
+ -- reduction of the argument is done for arguments in the range of
+ -- -2.0**63 .. 2.0**63, using a 66-bit approximation of Pi.
+
+ pragma Inline (Is_Nan);
+ pragma Inline (Reduce);
+
+ ---------------------------------
+ -- Basic Elementary Functions --
+ ---------------------------------
+
+ -- This section implements a few elementary functions that are
+ -- used to build the more complex ones. This ordering enables
+ -- better inlining.
+
+ ----------
+ -- Atan --
+ ----------
+
+ function Atan (X : Double) return Double is
+ Result : Double;
+
+ begin
+ Asm (Template =>
+ "fld1" & NL
+ & "fpatan",
+ Outputs => Double'Asm_Output ("=t", Result),
+ Inputs => Double'Asm_Input ("0", X));
+
+ -- The result value is NaN iff input was invalid
+
+ if not (Result = Result) then
+ raise Argument_Error;
+ end if;
+
+ return Result;
+ end Atan;
+
+ ---------
+ -- Exp --
+ ---------
+
+ function Exp (X : Double) return Double is
+ Result : Double;
+ begin
+ Asm (Template =>
+ "fldl2e " & NL
+ & "fmulp %%st, %%st(1)" & NL -- X * log2 (E)
+ & "fld %%st(0) " & NL
+ & "frndint " & NL -- Integer (X * Log2 (E))
+ & "fsubr %%st, %%st(1)" & NL -- Fraction (X * Log2 (E))
+ & "fxch " & NL
+ & "f2xm1 " & NL -- 2**(...) - 1
+ & "fld1 " & NL
+ & "faddp %%st, %%st(1)" & NL -- 2**(Fraction (X * Log2 (E)))
+ & "fscale " & NL -- E ** X
+ & "fstp %%st(1) ",
+ Outputs => Double'Asm_Output ("=t", Result),
+ Inputs => Double'Asm_Input ("0", X));
+ return Result;
+ end Exp;
+
+ ------------
+ -- Is_Nan --
+ ------------
+
+ function Is_Nan (X : Double) return Boolean is
+ begin
+ -- The IEEE NaN values are the only ones that do not equal themselves
+
+ return not (X = X);
+ end Is_Nan;
+
+ ---------
+ -- Log --
+ ---------
+
+ function Log (X : Double) return Double is
+ Result : Double;
+
+ begin
+ Asm (Template =>
+ "fldln2 " & NL
+ & "fxch " & NL
+ & "fyl2x " & NL,
+ Outputs => Double'Asm_Output ("=t", Result),
+ Inputs => Double'Asm_Input ("0", X));
+ return Result;
+ end Log;
+
+ ------------
+ -- Reduce --
+ ------------
+
+ function Reduce (X : Double) return Double is
+ Result : Double;
+ begin
+ Asm
+ (Template =>
+ -- Partial argument reduction
+ "fldpi " & NL
+ & "fadd %%st(0), %%st" & NL
+ & "fxch %%st(1) " & NL
+ & "fprem1 " & NL
+ & "fstp %%st(1) ",
+ Outputs => Double'Asm_Output ("=t", Result),
+ Inputs => Double'Asm_Input ("0", X));
+ return Result;
+ end Reduce;
+
+ ----------
+ -- Sqrt --
+ ----------
+
+ function Sqrt (X : Double) return Double is
+ Result : Double;
+
+ begin
+ if X < 0.0 then
+ raise Argument_Error;
+ end if;
+
+ Asm (Template => "fsqrt",
+ Outputs => Double'Asm_Output ("=t", Result),
+ Inputs => Double'Asm_Input ("0", X));
+
+ return Result;
+ end Sqrt;
+
+ ---------------------------------
+ -- Other Elementary Functions --
+ ---------------------------------
+
+ -- These are built using the previously implemented basic functions
+
+ ----------
+ -- Acos --
+ ----------
+
+ function Acos (X : Double) return Double is
+ Result : Double;
+ begin
+ Result := 2.0 * Atan (Sqrt ((1.0 - X) / (1.0 + X)));
+
+ -- The result value is NaN iff input was invalid
+
+ if Is_Nan (Result) then
+ raise Argument_Error;
+ end if;
+
+ return Result;
+ end Acos;
+
+ ----------
+ -- Asin --
+ ----------
+
+ function Asin (X : Double) return Double is
+ Result : Double;
+ begin
+
+ Result := Atan (X / Sqrt ((1.0 - X) * (1.0 + X)));
+
+ -- The result value is NaN iff input was invalid
+
+ if Is_Nan (Result) then
+ raise Argument_Error;
+ end if;
+
+ return Result;
+ end Asin;
+
+ ---------
+ -- Cos --
+ ---------
+
+ function Cos (X : Double) return Double is
+ Reduced_X : Double := X;
+ Result : Double;
+ Status : FPU_Status_Word;
+
+ begin
+
+ loop
+ Asm
+ (Template =>
+ "fcos " & NL
+ & "xorl %%eax, %%eax " & NL
+ & "fnstsw %%ax ",
+ Outputs => (Double'Asm_Output ("=t", Result),
+ FPU_Status_Word'Asm_Output ("=a", Status)),
+ Inputs => Double'Asm_Input ("0", Reduced_X));
+
+ exit when not Status.C2;
+
+ -- Original argument was not in range and the result
+ -- is the unmodified argument.
+
+ Reduced_X := Reduce (Result);
+ end loop;
+
+ return Result;
+ end Cos;
+
+ ---------------------
+ -- Logarithmic_Pow --
+ ---------------------
+
+ function Logarithmic_Pow (X, Y : Double) return Double is
+ Result : Double;
+
+ begin
+ Asm (Template => "" -- X : Y
+ & "fyl2x " & NL -- Y * Log2 (X)
+ & "fst %%st(1) " & NL -- Y * Log2 (X) : Y * Log2 (X)
+ & "frndint " & NL -- Int (...) : Y * Log2 (X)
+ & "fsubr %%st, %%st(1)" & NL -- Int (...) : Fract (...)
+ & "fxch " & NL -- Fract (...) : Int (...)
+ & "f2xm1 " & NL -- 2**Fract (...) - 1 : Int (...)
+ & "fld1 " & NL -- 1 : 2**Fract (...) - 1 : Int (...)
+ & "faddp %%st, %%st(1)" & NL -- 2**Fract (...) : Int (...)
+ & "fscale " & NL -- 2**(Fract (...) + Int (...))
+ & "fstp %%st(1) ",
+ Outputs => Double'Asm_Output ("=t", Result),
+ Inputs =>
+ (Double'Asm_Input ("0", X),
+ Double'Asm_Input ("u", Y)));
+
+ return Result;
+ end Logarithmic_Pow;
+
+ ---------
+ -- Pow --
+ ---------
+
+ function Pow (X, Y : Double) return Double is
+ type Mantissa_Type is mod 2**Double'Machine_Mantissa;
+ -- Modular type that can hold all bits of the mantissa of Double
+
+ -- For negative exponents, a division is done
+ -- at the end of the processing.
+
+ Negative_Y : constant Boolean := Y < 0.0;
+ Abs_Y : constant Double := abs Y;
+
+ -- During this function the following invariant is kept:
+ -- X ** (abs Y) = Base**(Exp_High + Exp_Mid + Exp_Low) * Factor
+
+ Base : Double := X;
+
+ Exp_High : Double := Double'Floor (Abs_Y);
+ Exp_Mid : Double;
+ Exp_Low : Double;
+ Exp_Int : Mantissa_Type;
+
+ Factor : Double := 1.0;
+
+ begin
+ -- Select algorithm for calculating Pow:
+ -- integer cases fall through
+
+ if Exp_High >= 2.0**Double'Machine_Mantissa then
+
+ -- In case of Y that is IEEE infinity, just raise constraint error
+
+ if Exp_High > Double'Safe_Last then
+ raise Constraint_Error;
+ end if;
+
+ -- Large values of Y are even integers and will stay integer
+ -- after division by two.
+
+ loop
+ -- Exp_Mid and Exp_Low are zero, so
+ -- X**(abs Y) = Base ** Exp_High = (Base**2) ** (Exp_High / 2)
+
+ Exp_High := Exp_High / 2.0;
+ Base := Base * Base;
+ exit when Exp_High < 2.0**Double'Machine_Mantissa;
+ end loop;
+
+ elsif Exp_High /= Abs_Y then
+ Exp_Low := Abs_Y - Exp_High;
+
+ Factor := 1.0;
+
+ if Exp_Low /= 0.0 then
+
+ -- Exp_Low now is in interval (0.0, 1.0)
+ -- Exp_Mid := Double'Floor (Exp_Low * 4.0) / 4.0;
+
+ Exp_Mid := 0.0;
+ Exp_Low := Exp_Low - Exp_Mid;
+
+ if Exp_Low >= 0.5 then
+ Factor := Sqrt (X);
+ Exp_Low := Exp_Low - 0.5; -- exact
+
+ if Exp_Low >= 0.25 then
+ Factor := Factor * Sqrt (Factor);
+ Exp_Low := Exp_Low - 0.25; -- exact
+ end if;
+
+ elsif Exp_Low >= 0.25 then
+ Factor := Sqrt (Sqrt (X));
+ Exp_Low := Exp_Low - 0.25; -- exact
+ end if;
+
+ -- Exp_Low now is in interval (0.0, 0.25)
+
+ -- This means it is safe to call Logarithmic_Pow
+ -- for the remaining part.
+
+ Factor := Factor * Logarithmic_Pow (X, Exp_Low);
+ end if;
+
+ elsif X = 0.0 then
+ return 0.0;
+ end if;
+
+ -- Exp_High is non-zero integer smaller than 2**Double'Machine_Mantissa
+
+ Exp_Int := Mantissa_Type (Exp_High);
+
+ -- Standard way for processing integer powers > 0
+
+ while Exp_Int > 1 loop
+ if (Exp_Int and 1) = 1 then
+
+ -- Base**Y = Base**(Exp_Int - 1) * Exp_Int for Exp_Int > 0
+
+ Factor := Factor * Base;
+ end if;
+
+ -- Exp_Int is even and Exp_Int > 0, so
+ -- Base**Y = (Base**2)**(Exp_Int / 2)
+
+ Base := Base * Base;
+ Exp_Int := Exp_Int / 2;
+ end loop;
+
+ -- Exp_Int = 1 or Exp_Int = 0
+
+ if Exp_Int = 1 then
+ Factor := Base * Factor;
+ end if;
+
+ if Negative_Y then
+ Factor := 1.0 / Factor;
+ end if;
+
+ return Factor;
+ end Pow;
+
+ ---------
+ -- Sin --
+ ---------
+
+ function Sin (X : Double) return Double is
+ Reduced_X : Double := X;
+ Result : Double;
+ Status : FPU_Status_Word;
+
+ begin
+
+ loop
+ Asm
+ (Template =>
+ "fsin " & NL
+ & "xorl %%eax, %%eax " & NL
+ & "fnstsw %%ax ",
+ Outputs => (Double'Asm_Output ("=t", Result),
+ FPU_Status_Word'Asm_Output ("=a", Status)),
+ Inputs => Double'Asm_Input ("0", Reduced_X));
+
+ exit when not Status.C2;
+
+ -- Original argument was not in range and the result
+ -- is the unmodified argument.
+
+ Reduced_X := Reduce (Result);
+ end loop;
+
+ return Result;
+ end Sin;
+
+ ---------
+ -- Tan --
+ ---------
+
+ function Tan (X : Double) return Double is
+ Reduced_X : Double := X;
+ Result : Double;
+ Status : FPU_Status_Word;
+
+ begin
+
+ loop
+ Asm
+ (Template =>
+ "fptan " & NL
+ & "xorl %%eax, %%eax " & NL
+ & "fnstsw %%ax " & NL
+ & "ffree %%st(0) " & NL
+ & "fincstp ",
+
+ Outputs => (Double'Asm_Output ("=t", Result),
+ FPU_Status_Word'Asm_Output ("=a", Status)),
+ Inputs => Double'Asm_Input ("0", Reduced_X));
+
+ exit when not Status.C2;
+
+ -- Original argument was not in range and the result
+ -- is the unmodified argument.
+
+ Reduced_X := Reduce (Result);
+ end loop;
+
+ return Result;
+ end Tan;
+
+ ----------
+ -- Sinh --
+ ----------
+
+ function Sinh (X : Double) return Double is
+ begin
+ -- Mathematically Sinh (x) is defined to be (Exp (X) - Exp (-X)) / 2.0
+
+ if abs X < 25.0 then
+ return (Exp (X) - Exp (-X)) / 2.0;
+
+ else
+ return Exp (X) / 2.0;
+ end if;
+
+ end Sinh;
+
+ ----------
+ -- Cosh --
+ ----------
+
+ function Cosh (X : Double) return Double is
+ begin
+ -- Mathematically Cosh (X) is defined to be (Exp (X) + Exp (-X)) / 2.0
+
+ if abs X < 22.0 then
+ return (Exp (X) + Exp (-X)) / 2.0;
+
+ else
+ return Exp (X) / 2.0;
+ end if;
+
+ end Cosh;
+
+ ----------
+ -- Tanh --
+ ----------
+
+ function Tanh (X : Double) return Double is
+ begin
+ -- Return the Hyperbolic Tangent of x
+ --
+ -- x -x
+ -- e - e Sinh (X)
+ -- Tanh (X) is defined to be ----------- = --------
+ -- x -x Cosh (X)
+ -- e + e
+
+ if abs X > 23.0 then
+ return Double'Copy_Sign (1.0, X);
+ end if;
+
+ return 1.0 / (1.0 + Exp (-2.0 * X)) - 1.0 / (1.0 + Exp (2.0 * X));
+
+ end Tanh;
+
+end Ada.Numerics.Aux;
diff --git a/gcc/ada/a-numaux-x86.ads b/gcc/ada/a-numaux-x86.ads
new file mode 100644
index 00000000000..857499fdfc1
--- /dev/null
+++ b/gcc/ada/a-numaux-x86.ads
@@ -0,0 +1,84 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUNTIME COMPONENTS --
+-- --
+-- A D A . N U M E R I C S . A U X --
+-- --
+-- S p e c --
+-- (Machine Version for x86) --
+-- --
+-- Copyright (C) 1992-1998 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides the basic computational interface for the generic
+-- elementary functions. This implementation is based on the glibc assembly
+-- sources for the x86 glibc math library.
+
+-- Note: there are two versions of this package. One using the 80-bit x86
+-- long double format (which is this version), and one using 64-bit IEEE
+-- double (see file a-numaux.ads). The latter version imports the C
+-- routines directly.
+
+package Ada.Numerics.Aux is
+pragma Pure (Aux);
+
+ type Double is new Long_Long_Float;
+
+ function Sin (X : Double) return Double;
+
+ function Cos (X : Double) return Double;
+
+ function Tan (X : Double) return Double;
+
+ function Exp (X : Double) return Double;
+
+ function Sqrt (X : Double) return Double;
+
+ function Log (X : Double) return Double;
+
+ function Atan (X : Double) return Double;
+
+ function Acos (X : Double) return Double;
+
+ function Asin (X : Double) return Double;
+
+ function Sinh (X : Double) return Double;
+
+ function Cosh (X : Double) return Double;
+
+ function Tanh (X : Double) return Double;
+
+ function Pow (X, Y : Double) return Double;
+
+private
+ pragma Inline (Atan);
+ pragma Inline (Cos);
+ pragma Inline (Tan);
+ pragma Inline (Exp);
+ pragma Inline (Log);
+ pragma Inline (Sin);
+ pragma Inline (Sqrt);
+
+end Ada.Numerics.Aux;
diff --git a/gcc/ada/a-sytaco-vxworks.adb b/gcc/ada/a-sytaco-vxworks.adb
new file mode 100644
index 00000000000..fcb320a97ec
--- /dev/null
+++ b/gcc/ada/a-sytaco-vxworks.adb
@@ -0,0 +1,147 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUNTIME COMPONENTS --
+-- --
+-- A D A . S Y N C H R O N O U S _ T A S K _ C O N T R O L --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2004 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Interfaces.C;
+
+package body Ada.Synchronous_Task_Control is
+ use System.OS_Interface;
+ use type Interfaces.C.int;
+
+ -------------------
+ -- Current_State --
+ -------------------
+
+ function Current_State (S : Suspension_Object) return Boolean is
+ St : STATUS;
+ Result : Boolean := False;
+
+ begin
+ -- Determine state by attempting to take the semaphore with
+ -- a 0 timeout value. Status = OK indicates the semaphore was
+ -- full, so reset it to the full state.
+
+ St := semTake (S.Sema, NO_WAIT);
+
+ -- If we took the semaphore, reset semaphore state to FULL
+
+ if St = OK then
+ Result := True;
+ St := semGive (S.Sema);
+ end if;
+
+ return Result;
+ end Current_State;
+
+ ---------------
+ -- Set_False --
+ ---------------
+
+ procedure Set_False (S : in out Suspension_Object) is
+ St : STATUS;
+
+ begin
+ -- Need to get the semaphore into the "empty" state.
+ -- On return, this task will have made the semaphore
+ -- empty (St = OK) or have left it empty.
+
+ St := semTake (S.Sema, NO_WAIT);
+ pragma Assert (St = OK);
+ end Set_False;
+
+ --------------
+ -- Set_True --
+ --------------
+
+ procedure Set_True (S : in out Suspension_Object) is
+ St : STATUS;
+ pragma Unreferenced (St);
+ begin
+ St := semGive (S.Sema);
+ end Set_True;
+
+ ------------------------
+ -- Suspend_Until_True --
+ ------------------------
+
+ procedure Suspend_Until_True (S : in out Suspension_Object) is
+ St : STATUS;
+
+ begin
+ -- Determine whether another task is pending on the suspension
+ -- object. Should never be called from an ISR. Therefore semTake can
+ -- be called on the mutex
+
+ St := semTake (S.Mutex, NO_WAIT);
+
+ if St = OK then
+
+ -- Wait for suspension object
+
+ St := semTake (S.Sema, WAIT_FOREVER);
+ St := semGive (S.Mutex);
+
+ else
+ -- Another task is pending on the suspension object
+
+ raise Program_Error;
+ end if;
+ end Suspend_Until_True;
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize (S : in out Suspension_Object) is
+ begin
+ S.Sema := semBCreate (SEM_Q_FIFO, SEM_EMPTY);
+
+ -- Use simpler binary semaphore instead of VxWorks
+ -- mutual exclusion semaphore, because we don't need
+ -- the fancier semantics and their overhead.
+
+ S.Mutex := semBCreate (SEM_Q_FIFO, SEM_FULL);
+ end Initialize;
+
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize (S : in out Suspension_Object) is
+ St : STATUS;
+ pragma Unreferenced (St);
+ begin
+ St := semDelete (S.Sema);
+ St := semDelete (S.Mutex);
+ end Finalize;
+
+end Ada.Synchronous_Task_Control;
diff --git a/gcc/ada/a-sytaco-vxworks.ads b/gcc/ada/a-sytaco-vxworks.ads
new file mode 100644
index 00000000000..c3c54bee43c
--- /dev/null
+++ b/gcc/ada/a-sytaco-vxworks.ads
@@ -0,0 +1,68 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- A D A . S Y N C H R O N O U S _ T A S K _ C O N T R O L --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1992-2001 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with System.OS_Interface;
+with Ada.Finalization;
+package Ada.Synchronous_Task_Control is
+
+ type Suspension_Object is limited private;
+
+ procedure Set_True (S : in out Suspension_Object);
+
+ procedure Set_False (S : in out Suspension_Object);
+
+ function Current_State (S : Suspension_Object) return Boolean;
+
+ procedure Suspend_Until_True (S : in out Suspension_Object);
+
+private
+
+ procedure Initialize (S : in out Suspension_Object);
+
+ procedure Finalize (S : in out Suspension_Object);
+
+ -- Implement with a VxWorks binary semaphore. A second semaphore
+ -- is used to avoid a race condition related to the implementation of
+ -- the STC requirement to raise Program_Error when Suspend_Until_True is
+ -- called with a task already pending on the suspension object
+
+ type Suspension_Object is new Ada.Finalization.Controlled with record
+ Sema : System.OS_Interface.SEM_ID;
+ Mutex : System.OS_Interface.SEM_ID;
+ end record;
+
+end Ada.Synchronous_Task_Control;
diff --git a/gcc/ada/a-tags.adb b/gcc/ada/a-tags.adb
index a2e40f8d4ef..c232695ce75 100644
--- a/gcc/ada/a-tags.adb
+++ b/gcc/ada/a-tags.adb
@@ -65,8 +65,12 @@ package body Ada.Tags is
subtype Cstring is String (Positive);
type Cstring_Ptr is access all Cstring;
+
type Tag_Table is array (Natural range <>) of Tag;
pragma Suppress_Initialization (Tag_Table);
+ pragma Suppress (Index_Check, On => Tag_Table);
+ -- We suppress index checks because the declared size in the record
+ -- below is a dummy size of one (see below).
type Wide_Boolean is new Boolean;
-- This name should probably be changed sometime ??? and indeed
@@ -79,13 +83,33 @@ package body Ada.Tags is
HT_Link : Tag;
Remotely_Callable : Wide_Boolean;
RC_Offset : SSE.Storage_Offset;
- Ancestor_Tags : Tag_Table (Natural);
+ Ancestor_Tags : Tag_Table (0 .. 1);
end record;
+ -- The size of the Ancestor_Tags array actually depends on the tagged
+ -- type to which it applies. We are using the same mechanism as for
+ -- the Prims_Ptr array in the Dispatch_Table record. See comments
+ -- below for more details.
type Dispatch_Table is record
TSD : Type_Specific_Data_Ptr;
- Prims_Ptr : Address_Array (Positive);
+ Prims_Ptr : Address_Array (1 .. 1);
end record;
+ -- The size of the Prims_Ptr array actually depends on the tagged
+ -- type to which it applies. For each tagged type, the expander
+ -- computes the actual array size, and allocates the Dispatch_Table
+ -- record accordingly.
+ --
+ -- To avoid the use of discriminants to define the actual size
+ -- of the dispatch table, we used to declare the tag as a pointer
+ -- to a record that contains an arbitrary array of addresses, using
+ -- Positive as its index. This ensures that there are never range
+ -- checks when accessing the dispatch table, but it prevents GDB
+ -- from displaying tagged types properly. A better approach is
+ -- to declare this record type as holding a small number of addresses,
+ -- and to explicitly suppress checks on it.
+ --
+ -- Note that in both cases, this type is never allocated, and serves
+ -- only to declare the corresponding access type.
---------------------------------------------
-- Unchecked Conversions for String Fields --
@@ -182,7 +206,6 @@ package body Ada.Tags is
function H is new System.HTable.Hash (HTable_Headers);
Str : constant Cstring_Ptr := To_Cstring_Ptr (F);
Res : constant HTable_Headers := H (Str (1 .. Length (Str)));
-
begin
return Res;
end Hash;
@@ -219,7 +242,6 @@ package body Ada.Tags is
function CW_Membership (Obj_Tag : Tag; Typ_Tag : Tag) return Boolean is
Pos : constant Integer := Obj_Tag.TSD.Idepth - Typ_Tag.TSD.Idepth;
-
begin
return Pos >= 0 and then Obj_Tag.TSD.Ancestor_Tags (Pos) = Typ_Tag;
end CW_Membership;
@@ -230,7 +252,6 @@ package body Ada.Tags is
function Expanded_Name (T : Tag) return String is
Result : constant Cstring_Ptr := T.TSD.Expanded_Name;
-
begin
return Result (1 .. Length (Result));
end Expanded_Name;
@@ -241,7 +262,6 @@ package body Ada.Tags is
function External_Tag (T : Tag) return String is
Result : constant Cstring_Ptr := T.TSD.External_Tag;
-
begin
return Result (1 .. Length (Result));
end External_Tag;
diff --git a/gcc/ada/a-tags.ads b/gcc/ada/a-tags.ads
index 6dd97ff6642..6e6adbfa4e1 100644
--- a/gcc/ada/a-tags.ads
+++ b/gcc/ada/a-tags.ads
@@ -210,6 +210,10 @@ private
-- Size of each ancestor tag entry in the TSD
type Address_Array is array (Natural range <>) of System.Address;
+ pragma Suppress (Index_Check, On => Address_Array);
+ -- The reason we suppress index checks is that in the body, objects
+ -- of this type are declared with a dummy size of 1, the actual size
+ -- depending on the number of primitive operations.
type Dispatch_Table;
type Tag is access all Dispatch_Table;
diff --git a/gcc/ada/a-textio.adb b/gcc/ada/a-textio.adb
index 98766ce9bf3..7afb804ff9c 100644
--- a/gcc/ada/a-textio.adb
+++ b/gcc/ada/a-textio.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -1678,8 +1678,12 @@ package body Ada.Text_IO is
-- because it is too much of a nuisance to have these odd line
-- feeds when nothing has been written to the file.
+ -- We also avoid this for files opened in append mode, in
+ -- accordance with (RM A.8.2(10))
+
elsif (File /= Standard_Err and then File /= Standard_Out)
and then (File.Line = 1 and then File.Page = 1)
+ and then Mode (File) = Out_File
then
New_Line (File);
end if;
diff --git a/gcc/ada/a-wtmoio.ads b/gcc/ada/a-wtmoio.ads
index b123223e0da..cec719317ba 100644
--- a/gcc/ada/a-wtmoio.ads
+++ b/gcc/ada/a-wtmoio.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-1997 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 Free Software Foundation, Inc. --
-- --
-- This specification is derived from the Ada Reference Manual for use with --
-- GNAT. The copyright notice above, and the license provisions that follow --
@@ -42,7 +42,7 @@
-- difference in semantics so that it is invisible to the Ada programmer.
private generic
- type Num is range <>;
+ type Num is mod <>;
package Ada.Wide_Text_IO.Modular_IO is
diff --git a/gcc/ada/ada-tree.def b/gcc/ada/ada-tree.def
index e58963ed20a..e5fe7eb61fa 100644
--- a/gcc/ada/ada-tree.def
+++ b/gcc/ada/ada-tree.def
@@ -101,9 +101,12 @@ DEFTREECODE (IF_STMT, "if_stmt", 's', 4)
/* A goto just points to the label: GOTO_STMT_LABEL. */
DEFTREECODE (GOTO_STMT, "goto_stmt", 's', 1)
-/* A label: LABEL_STMT_LABEL is the label and LABEL_STMT_FIRST_IN_EH is set
- if this is the first label of an exception handler. */
+/* A label: LABEL_STMT_LABEL is the label. */
DEFTREECODE (LABEL_STMT, "label_stmt", 's', 1)
/* A "return". RETURN_STMT_EXPR is the value to return if non-null. */
DEFTREECODE (RETURN_STMT, "return_stmt", 's', 1)
+
+/* An "asm" statement. The operands are ASM_STMT_TEMPLATE, ASM_STMT_OUTPUT,
+ ASM_STMT_ORIG_OUT, ASM_STMT_INPUT, and ASM_STMT_CLOBBER. */
+DEFTREECODE (ASM_STMT, "asm_stmt", 's', 5)
diff --git a/gcc/ada/ada-tree.h b/gcc/ada/ada-tree.h
index 572a5b72e29..3f6faeddb30 100644
--- a/gcc/ada/ada-tree.h
+++ b/gcc/ada/ada-tree.h
@@ -302,7 +302,9 @@ struct lang_type GTY(())
#define IF_STMT_ELSE(NODE) TREE_OPERAND_CHECK_CODE (NODE, IF_STMT, 3)
#define GOTO_STMT_LABEL(NODE) TREE_OPERAND_CHECK_CODE (NODE, GOTO_STMT, 0)
#define LABEL_STMT_LABEL(NODE) TREE_OPERAND_CHECK_CODE (NODE, LABEL_STMT, 0)
-#define LABEL_STMT_FIRST_IN_EH(NODE) \
- (LABEL_STMT_CHECK (NODE)->common.unsigned_flag)
#define RETURN_STMT_EXPR(NODE) TREE_OPERAND_CHECK_CODE (NODE, RETURN_STMT, 0)
-
+#define ASM_STMT_TEMPLATE(NODE) TREE_OPERAND_CHECK_CODE (NODE, ASM_STMT, 0)
+#define ASM_STMT_OUTPUT(NODE) TREE_OPERAND_CHECK_CODE (NODE, ASM_STMT, 1)
+#define ASM_STMT_ORIG_OUT(NODE) TREE_OPERAND_CHECK_CODE (NODE, ASM_STMT, 2)
+#define ASM_STMT_INPUT(NODE) TREE_OPERAND_CHECK_CODE (NODE, ASM_STMT, 3)
+#define ASM_STMT_CLOBBER(NODE) TREE_OPERAND_CHECK_CODE (NODE, ASM_STMT, 4)
diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c
index 67a457c35d2..7b8813ab6ee 100644
--- a/gcc/ada/adaint.c
+++ b/gcc/ada/adaint.c
@@ -411,7 +411,8 @@ __gnat_try_lock (char *dir, char *file)
int fd;
sprintf (full_path, "%s%c%s", dir, DIR_SEPARATOR, file);
- sprintf (temp_file, "%s-%ld-%ld", dir, (long) getpid(), (long) getppid ());
+ sprintf (temp_file, "%s%cTMP-%ld-%ld",
+ dir, DIR_SEPARATOR, (long)getpid(), (long)getppid ());
/* Create the temporary file and write the process number. */
fd = open (temp_file, O_CREAT | O_WRONLY, 0600);
@@ -861,7 +862,7 @@ win32_filetime (HANDLE h)
/* Return a GNAT time stamp given a file name. */
-time_t
+OS_Time
__gnat_file_time_name (char *name)
{
@@ -869,7 +870,7 @@ __gnat_file_time_name (char *name)
int fd = open (name, O_RDONLY | O_BINARY);
time_t ret = __gnat_file_time_fd (fd);
close (fd);
- return ret;
+ return (OS_Time)ret;
#elif defined (_WIN32)
time_t ret = 0;
@@ -881,22 +882,25 @@ __gnat_file_time_name (char *name)
ret = win32_filetime (h);
CloseHandle (h);
}
- return ret;
+ return (OS_Time) ret;
#else
struct stat statbuf;
- (void) __gnat_stat (name, &statbuf);
+ if (__gnat_stat (name, &statbuf) != 0) {
+ return (OS_Time)-1;
+ } else {
#ifdef VMS
- /* VMS has file versioning. */
- return statbuf.st_ctime;
+ /* VMS has file versioning. */
+ return (OS_Time)statbuf.st_ctime;
#else
- return statbuf.st_mtime;
+ return (OS_Time)statbuf.st_mtime;
#endif
+ }
#endif
}
/* Return a GNAT time stamp given a file descriptor. */
-time_t
+OS_Time
__gnat_file_time_fd (int fd)
{
/* The following workaround code is due to the fact that under EMX and
@@ -964,24 +968,26 @@ __gnat_file_time_fd (int fd)
tot_secs += file_hour * 3600;
tot_secs += file_min * 60;
tot_secs += file_tsec * 2;
- return tot_secs;
+ return (OS_Time) tot_secs;
#elif defined (_WIN32)
HANDLE h = (HANDLE) _get_osfhandle (fd);
time_t ret = win32_filetime (h);
- return ret;
+ return (OS_Time) ret;
#else
struct stat statbuf;
- (void) fstat (fd, &statbuf);
-
+ if (fstat (fd, &statbuf) != 0) {
+ return (OS_Time) -1;
+ } else {
#ifdef VMS
- /* VMS has file versioning. */
- return statbuf.st_ctime;
+ /* VMS has file versioning. */
+ return (OS_Time) statbuf.st_ctime;
#else
- return statbuf.st_mtime;
+ return (OS_Time) statbuf.st_mtime;
#endif
+ }
#endif
}
@@ -1404,11 +1410,12 @@ __gnat_file_exists (char *name)
}
int
-__gnat_is_absolute_path (char *name)
+__gnat_is_absolute_path (char *name, int length)
{
- return (*name == '/' || *name == DIR_SEPARATOR
+ return (length != 0) &&
+ (*name == '/' || *name == DIR_SEPARATOR
#if defined (__EMX__) || defined (MSDOS) || defined (WINNT)
- || (strlen (name) > 1 && isalpha (name[0]) && name[1] == ':')
+ || (length > 1 && isalpha (name[0]) && name[1] == ':')
#endif
);
}
@@ -1472,6 +1479,20 @@ __gnat_set_writable (char *name)
}
void
+__gnat_set_executable (char *name)
+{
+#ifndef __vxworks
+ struct stat statbuf;
+
+ if (stat (name, &statbuf) == 0)
+ {
+ statbuf.st_mode = statbuf.st_mode | S_IXUSR;
+ chmod (name, statbuf.st_mode);
+ }
+#endif
+}
+
+void
__gnat_set_readonly (char *name)
{
#ifndef __vxworks
@@ -1529,7 +1550,19 @@ __gnat_portable_spawn (char *args[])
int pid ATTRIBUTE_UNUSED;
#if defined (MSDOS) || defined (_WIN32)
- status = spawnvp (P_WAIT, args[0],(const char* const*)args);
+ /* args[0] must be quotes as it could contain a full pathname with spaces */
+ const char *args_0 = args[0];
+ args[0] = (char *)xmalloc (strlen (args_0) + 3);
+ strcpy (args[0], "\"");
+ strcat (args[0], args_0);
+ strcat (args[0], "\"");
+
+ status = spawnvp (P_WAIT, args_0, (const char* const*)args);
+
+ /* restore previous value */
+ free (args[0]);
+ args[0] = args_0;
+
if (status < 0)
return -1;
else
@@ -1872,7 +1905,7 @@ char *
__gnat_locate_regular_file (char *file_name, char *path_val)
{
char *ptr;
- int absolute = __gnat_is_absolute_path (file_name);
+ int absolute = __gnat_is_absolute_path (file_name, strlen (file_name));
/* Handle absolute pathnames. */
if (absolute)
diff --git a/gcc/ada/adaint.h b/gcc/ada/adaint.h
index def011c678b..c45a5332309 100644
--- a/gcc/ada/adaint.h
+++ b/gcc/ada/adaint.h
@@ -70,19 +70,23 @@ extern long __gnat_named_file_length (char *);
extern void __gnat_tmp_name (char *);
extern char *__gnat_readdir (DIR *, char *);
extern int __gnat_readdir_is_thread_safe (void);
-extern time_t __gnat_file_time_name (char *);
-extern time_t __gnat_file_time_fd (int);
+
+extern OS_Time __gnat_file_time_name (char *);
+extern OS_Time __gnat_file_time_fd (int);
+/* return -1 in case of error */
+
extern void __gnat_set_file_time_name (char *, time_t);
extern void __gnat_get_env_value_ptr (char *, int *,
char **);
extern int __gnat_file_exists (char *);
extern int __gnat_is_regular_file (char *);
-extern int __gnat_is_absolute_path (char *);
+extern int __gnat_is_absolute_path (char *,int);
extern int __gnat_is_directory (char *);
extern int __gnat_is_writable_file (char *);
extern int __gnat_is_readable_file (char *name);
extern void __gnat_set_readonly (char *name);
extern void __gnat_set_writable (char *name);
+extern void __gnat_set_executable (char *name);
extern int __gnat_is_symbolic_link (char *name);
extern int __gnat_portable_spawn (char *[]);
extern int __gnat_portable_no_block_spawn (char *[]);
diff --git a/gcc/ada/ali.ads b/gcc/ada/ali.ads
index 9c7d35a8e5c..44f5ffa45b8 100644
--- a/gcc/ada/ali.ads
+++ b/gcc/ada/ali.ads
@@ -476,7 +476,7 @@ package ALI is
-- Indicates presence of ED parameter
Interface : Boolean := False;
- -- True if the Unit is an Interface of a Stand-Alole Library
+ -- True if the Unit is an Interface of a Stand-Alone Library
end record;
diff --git a/gcc/ada/atree.adb b/gcc/ada/atree.adb
index 49938b98ece..c03a1836194 100644
--- a/gcc/ada/atree.adb
+++ b/gcc/ada/atree.adb
@@ -380,11 +380,64 @@ package body Atree is
-- Local Subprograms --
-----------------------
- procedure Fix_Parent (Field : Union_Id; Old_Node, New_Node : Node_Id);
- -- This subprogram is used to fixup parent pointers that are rendered
- -- incorrect because of a node copy. Field is checked to see if it
- -- points to a node, list, or element list that has a parent that
- -- points to Old_Node. If so, the parent is reset to point to New_Node.
+ procedure Fix_Parents (Old_Node, New_Node : Node_Id);
+ -- Fixup parent pointers for the syntactic children of New_Node after
+ -- a copy, setting them to New_Node when they pointed to Old_Node.
+
+ function Allocate_Initialize_Node
+ (Src : Node_Id;
+ With_Extension : Boolean) return Node_Id;
+ -- Allocate a new node or node extension. If Src is not empty,
+ -- the information for the newly-allocated node is copied from it.
+
+ ------------------------------
+ -- Allocate_Initialize_Node --
+ ------------------------------
+
+ function Allocate_Initialize_Node
+ (Src : Node_Id;
+ With_Extension : Boolean) return Node_Id
+ is
+ New_Id : Node_Id := Src;
+ Nod : Node_Record := Default_Node;
+ Ext1 : Node_Record := Default_Node_Extension;
+ Ext2 : Node_Record := Default_Node_Extension;
+ Ext3 : Node_Record := Default_Node_Extension;
+ begin
+ if Present (Src) then
+ Nod := Nodes.Table (Src);
+
+ if Has_Extension (Src) then
+ Ext1 := Nodes.Table (Src + 1);
+ Ext2 := Nodes.Table (Src + 2);
+ Ext3 := Nodes.Table (Src + 3);
+ end if;
+ end if;
+
+ if not (Present (Src)
+ and then not Has_Extension (Src)
+ and then With_Extension
+ and then Src = Nodes.Last)
+ then
+ -- We are allocating a new node, or extending a node
+ -- other than Nodes.Last.
+
+ Nodes.Append (Nod);
+ New_Id := Nodes.Last;
+ Orig_Nodes.Append (New_Id);
+ Node_Count := Node_Count + 1;
+ end if;
+
+ if With_Extension then
+ Nodes.Append (Ext1);
+ Nodes.Append (Ext2);
+ Nodes.Append (Ext3);
+ end if;
+
+ Orig_Nodes.Set_Last (Nodes.Last);
+ Allocate_List_Tables (Nodes.Last);
+ return New_Id;
+ end Allocate_Initialize_Node;
--------------
-- Analyzed --
@@ -584,17 +637,7 @@ package body Atree is
return Copy_Entity (Source);
else
- Nodes.Increment_Last;
- New_Id := Nodes.Last;
- Nodes.Table (New_Id) := Nodes.Table (Source);
- Nodes.Table (New_Id).Link := Empty_List_Or_Node;
- Nodes.Table (New_Id).In_List := False;
- Nodes.Table (New_Id).Rewrite_Ins := False;
- Node_Count := Node_Count + 1;
-
- Orig_Nodes.Increment_Last;
- Allocate_List_Tables (Nodes.Last);
- Orig_Nodes.Table (New_Id) := New_Id;
+ New_Id := New_Copy (Source);
-- Recursively copy descendents
@@ -787,58 +830,53 @@ package body Atree is
pragma Inline (Debug_Extend_Node);
begin
- if Node /= Nodes.Last then
- Nodes.Increment_Last;
- Nodes.Table (Nodes.Last) := Nodes.Table (Node);
- Result := Nodes.Last;
-
- Orig_Nodes.Increment_Last;
- Orig_Nodes.Table (Nodes.Last) := Nodes.Last;
+ pragma Assert (not (Has_Extension (Node)));
+ Result := Allocate_Initialize_Node (Node, With_Extension => True);
+ pragma Debug (Debug_Extend_Node);
+ return Result;
+ end Extend_Node;
- else
- Result := Node;
- end if;
+ -----------------
+ -- Fix_Parents --
+ -----------------
- Nodes.Increment_Last;
- Nodes.Table (Nodes.Last) := Default_Node_Extension;
- Nodes.Increment_Last;
- Nodes.Table (Nodes.Last) := Default_Node_Extension;
- Nodes.Increment_Last;
- Nodes.Table (Nodes.Last) := Default_Node_Extension;
+ procedure Fix_Parents (Old_Node, New_Node : Node_Id) is
- Orig_Nodes.Set_Last (Nodes.Last);
- Allocate_List_Tables (Nodes.Last);
+ procedure Fix_Parent (Field : Union_Id; Old_Node, New_Node : Node_Id);
+ -- Fixup one parent pointer. Field is checked to see if it
+ -- points to a node, list, or element list that has a parent that
+ -- points to Old_Node. If so, the parent is reset to point to New_Node.
- pragma Debug (Debug_Extend_Node);
- return Result;
- end Extend_Node;
+ procedure Fix_Parent (Field : Union_Id; Old_Node, New_Node : Node_Id) is
+ begin
+ -- Fix parent of node that is referenced by Field. Note that we must
+ -- exclude the case where the node is a member of a list, because in
+ -- this case the parent is the parent of the list.
- ----------------
- -- Fix_Parent --
- ----------------
+ if Field in Node_Range
+ and then Present (Node_Id (Field))
+ and then not Nodes.Table (Node_Id (Field)).In_List
+ and then Parent (Node_Id (Field)) = Old_Node
+ then
+ Set_Parent (Node_Id (Field), New_Node);
- procedure Fix_Parent (Field : Union_Id; Old_Node, New_Node : Node_Id) is
- begin
- -- Fix parent of node that is referenced by Field. Note that we must
- -- exclude the case where the node is a member of a list, because in
- -- this case the parent is the parent of the list.
-
- if Field in Node_Range
- and then Present (Node_Id (Field))
- and then not Nodes.Table (Node_Id (Field)).In_List
- and then Parent (Node_Id (Field)) = Old_Node
- then
- Set_Parent (Node_Id (Field), New_Node);
+ -- Fix parent of list that is referenced by Field
- -- Fix parent of list that is referenced by Field
+ elsif Field in List_Range
+ and then Present (List_Id (Field))
+ and then Parent (List_Id (Field)) = Old_Node
+ then
+ Set_Parent (List_Id (Field), New_Node);
+ end if;
+ end Fix_Parent;
- elsif Field in List_Range
- and then Present (List_Id (Field))
- and then Parent (List_Id (Field)) = Old_Node
- then
- Set_Parent (List_Id (Field), New_Node);
- end if;
- end Fix_Parent;
+ begin
+ Fix_Parent (Field1 (New_Node), Old_Node, New_Node);
+ Fix_Parent (Field2 (New_Node), Old_Node, New_Node);
+ Fix_Parent (Field3 (New_Node), Old_Node, New_Node);
+ Fix_Parent (Field4 (New_Node), Old_Node, New_Node);
+ Fix_Parent (Field5 (New_Node), Old_Node, New_Node);
+ end Fix_Parents;
-----------------------------------
-- Get_Comes_From_Source_Default --
@@ -942,38 +980,23 @@ package body Atree is
--------------
function New_Copy (Source : Node_Id) return Node_Id is
- New_Id : Node_Id;
+ New_Id : Node_Id := Source;
begin
- if Source <= Empty_Or_Error then
- return Source;
+ if Source > Empty_Or_Error then
+
+ New_Id := Allocate_Initialize_Node (Source, Has_Extension (Source));
- else
- Nodes.Increment_Last;
- New_Id := Nodes.Last;
- Nodes.Table (New_Id) := Nodes.Table (Source);
Nodes.Table (New_Id).Link := Empty_List_Or_Node;
Nodes.Table (New_Id).In_List := False;
- Nodes.Table (New_Id).Rewrite_Ins := False;
- Orig_Nodes.Increment_Last;
- Orig_Nodes.Table (New_Id) := New_Id;
+ -- If the original is marked as a rewrite insertion, then unmark
+ -- the copy, since we inserted the original, not the copy.
- if Has_Extension (Source) then
- Nodes.Increment_Last;
- Nodes.Table (New_Id + 1) := Nodes.Table (Source + 1);
- Nodes.Increment_Last;
- Nodes.Table (New_Id + 2) := Nodes.Table (Source + 2);
- Nodes.Increment_Last;
- Nodes.Table (New_Id + 3) := Nodes.Table (Source + 3);
-
- Orig_Nodes.Set_Last (Nodes.Last);
- end if;
-
- Allocate_List_Tables (Nodes.Last);
- Node_Count := Node_Count + 1;
- return New_Id;
+ Nodes.Table (New_Id).Rewrite_Ins := False;
end if;
+
+ return New_Id;
end New_Copy;
-------------------
@@ -1353,17 +1376,7 @@ package body Atree is
return Assoc (Old_Node);
else
- Nodes.Increment_Last;
- New_Node := Nodes.Last;
- Nodes.Table (New_Node) := Nodes.Table (Old_Node);
- Nodes.Table (New_Node).Link := Empty_List_Or_Node;
- Nodes.Table (New_Node).In_List := False;
- Node_Count := Node_Count + 1;
-
- Orig_Nodes.Increment_Last;
- Allocate_List_Tables (Nodes.Last);
-
- Orig_Nodes.Table (Nodes.Last) := Nodes.Last;
+ New_Node := New_Copy (Old_Node);
-- If the node we are copying is the associated node of a
-- previously copied Itype, then adjust the associated node
@@ -1416,10 +1429,6 @@ package body Atree is
Set_Field5
(New_Node, Copy_Field_With_Replacement (Field5 (New_Node)));
- -- If the original is marked as a rewrite insertion, then unmark
- -- the copy, since we inserted the original, not the copy.
-
- Nodes.Table (New_Node).Rewrite_Ins := False;
-- Adjust Sloc of new node if necessary
@@ -1838,7 +1847,7 @@ package body Atree is
begin
if Debug_Flag_N then
Write_Str ("Allocate entity, Id = ");
- Write_Int (Int (Nodes.Last));
+ Write_Int (Int (Ent));
Write_Str (" ");
Write_Location (New_Sloc);
Write_Str (" ");
@@ -1852,8 +1861,7 @@ package body Atree is
begin
pragma Assert (New_Node_Kind in N_Entity);
- Nodes.Increment_Last;
- Ent := Nodes.Last;
+ Ent := Allocate_Initialize_Node (Empty, With_Extension => True);
-- If this is a node with a real location and we are generating
-- source nodes, then reset Current_Error_Node. This is useful
@@ -1863,26 +1871,10 @@ package body Atree is
Current_Error_Node := Ent;
end if;
- Nodes.Table (Nodes.Last) := Default_Node;
- Nodes.Table (Nodes.Last).Nkind := New_Node_Kind;
- Nodes.Table (Nodes.Last).Sloc := New_Sloc;
+ Nodes.Table (Ent).Nkind := New_Node_Kind;
+ Nodes.Table (Ent).Sloc := New_Sloc;
pragma Debug (New_Entity_Debugging_Output);
- Orig_Nodes.Increment_Last;
- Orig_Nodes.Table (Nodes.Last) := Nodes.Last;
-
- Nodes.Increment_Last;
- Nodes.Table (Nodes.Last) := Default_Node_Extension;
-
- Nodes.Increment_Last;
- Nodes.Table (Nodes.Last) := Default_Node_Extension;
-
- Nodes.Increment_Last;
- Nodes.Table (Nodes.Last) := Default_Node_Extension;
-
- Orig_Nodes.Set_Last (Nodes.Last);
- Allocate_List_Tables (Nodes.Last);
- Node_Count := Node_Count + 1;
return Ent;
end New_Entity;
@@ -1908,7 +1900,7 @@ package body Atree is
begin
if Debug_Flag_N then
Write_Str ("Allocate node, Id = ");
- Write_Int (Int (Nodes.Last));
+ Write_Int (Int (Nod));
Write_Str (" ");
Write_Location (New_Sloc);
Write_Str (" ");
@@ -1921,12 +1913,10 @@ package body Atree is
begin
pragma Assert (New_Node_Kind not in N_Entity);
- Nodes.Increment_Last;
- Nodes.Table (Nodes.Last) := Default_Node;
- Nodes.Table (Nodes.Last).Nkind := New_Node_Kind;
- Nodes.Table (Nodes.Last).Sloc := New_Sloc;
+ Nod := Allocate_Initialize_Node (Empty, With_Extension => False);
+ Nodes.Table (Nod).Nkind := New_Node_Kind;
+ Nodes.Table (Nod).Sloc := New_Sloc;
pragma Debug (New_Node_Debugging_Output);
- Nod := Nodes.Last;
-- If this is a node with a real location and we are generating
-- source nodes, then reset Current_Error_Node. This is useful
@@ -1936,10 +1926,6 @@ package body Atree is
Current_Error_Node := Nod;
end if;
- Node_Count := Node_Count + 1;
- Orig_Nodes.Increment_Last;
- Allocate_List_Tables (Nodes.Last);
- Orig_Nodes.Table (Nodes.Last) := Nodes.Last;
return Nod;
end New_Node;
@@ -2054,11 +2040,7 @@ package body Atree is
end if;
New_Node := New_Copy (Source);
- Fix_Parent (Field1 (Source), Source, New_Node);
- Fix_Parent (Field2 (Source), Source, New_Node);
- Fix_Parent (Field3 (Source), Source, New_Node);
- Fix_Parent (Field4 (Source), Source, New_Node);
- Fix_Parent (Field5 (Source), Source, New_Node);
+ Fix_Parents (Source, New_Node);
-- We now set the parent of the new node to be the same as the
-- parent of the source. Almost always this parent will be
@@ -2085,8 +2067,6 @@ package body Atree is
-------------
procedure Replace (Old_Node, New_Node : Node_Id) is
- Old_Link : constant Union_Id := Nodes.Table (Old_Node).Link;
- Old_InL : constant Boolean := Nodes.Table (Old_Node).In_List;
Old_Post : constant Boolean := Nodes.Table (Old_Node).Error_Posted;
Old_CFS : constant Boolean := Nodes.Table (Old_Node).Comes_From_Source;
@@ -2098,19 +2078,13 @@ package body Atree is
-- Do copy, preserving link and in list status and comes from source
- Nodes.Table (Old_Node) := Nodes.Table (New_Node);
- Nodes.Table (Old_Node).Link := Old_Link;
- Nodes.Table (Old_Node).In_List := Old_InL;
+ Copy_Node (Source => New_Node, Destination => Old_Node);
Nodes.Table (Old_Node).Comes_From_Source := Old_CFS;
Nodes.Table (Old_Node).Error_Posted := Old_Post;
-- Fix parents of substituted node, since it has changed identity
- Fix_Parent (Field1 (Old_Node), New_Node, Old_Node);
- Fix_Parent (Field2 (Old_Node), New_Node, Old_Node);
- Fix_Parent (Field3 (Old_Node), New_Node, Old_Node);
- Fix_Parent (Field4 (Old_Node), New_Node, Old_Node);
- Fix_Parent (Field5 (Old_Node), New_Node, Old_Node);
+ Fix_Parents (New_Node, Old_Node);
-- Since we are doing a replace, we assume that the original node
-- is intended to become the new replaced node. The call would be
@@ -2129,10 +2103,8 @@ package body Atree is
procedure Rewrite (Old_Node, New_Node : Node_Id) is
- Old_Link : constant Union_Id := Nodes.Table (Old_Node).Link;
- Old_In_List : constant Boolean := Nodes.Table (Old_Node).In_List;
Old_Error_P : constant Boolean := Nodes.Table (Old_Node).Error_Posted;
- -- These three fields are always preserved in the new node
+ -- This fields is always preserved in the new node
Old_Paren_Count : Paren_Count_Type;
Old_Must_Not_Freeze : Boolean;
@@ -2165,24 +2137,14 @@ package body Atree is
-- that does not reference the Old_Node.
if Orig_Nodes.Table (Old_Node) = Old_Node then
- Nodes.Increment_Last;
- Sav_Node := Nodes.Last;
- Nodes.Table (Sav_Node) := Nodes.Table (Old_Node);
- Nodes.Table (Sav_Node).In_List := False;
- Nodes.Table (Sav_Node).Link := Union_Id (Parent (Old_Node));
-
- Orig_Nodes.Increment_Last;
- Allocate_List_Tables (Nodes.Last);
-
+ Sav_Node := New_Copy (Old_Node);
Orig_Nodes.Table (Sav_Node) := Sav_Node;
Orig_Nodes.Table (Old_Node) := Sav_Node;
end if;
-- Copy substitute node into place, preserving old fields as required
- Nodes.Table (Old_Node) := Nodes.Table (New_Node);
- Nodes.Table (Old_Node).Link := Old_Link;
- Nodes.Table (Old_Node).In_List := Old_In_List;
+ Copy_Node (Source => New_Node, Destination => Old_Node);
Nodes.Table (Old_Node).Error_Posted := Old_Error_P;
if Nkind (New_Node) in N_Subexpr then
@@ -2190,11 +2152,7 @@ package body Atree is
Set_Must_Not_Freeze (Old_Node, Old_Must_Not_Freeze);
end if;
- Fix_Parent (Field1 (Old_Node), New_Node, Old_Node);
- Fix_Parent (Field2 (Old_Node), New_Node, Old_Node);
- Fix_Parent (Field3 (Old_Node), New_Node, Old_Node);
- Fix_Parent (Field4 (Old_Node), New_Node, Old_Node);
- Fix_Parent (Field5 (Old_Node), New_Node, Old_Node);
+ Fix_Parents (New_Node, Old_Node);
end Rewrite;
------------------
diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
index ea73f2f8d4f..713ea26306c 100644
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -31,6 +31,7 @@ with Errout; use Errout;
with Exp_Ch2; use Exp_Ch2;
with Exp_Util; use Exp_Util;
with Elists; use Elists;
+with Eval_Fat; use Eval_Fat;
with Freeze; use Freeze;
with Lib; use Lib;
with Nlists; use Nlists;
@@ -187,6 +188,14 @@ package body Checks is
-- Local Subprograms --
-----------------------
+ procedure Apply_Float_Conversion_Check
+ (Ck_Node : Node_Id;
+ Target_Typ : Entity_Id);
+ -- The checks on a conversion from a floating-point type to an integer
+ -- type are delicate. They have to be performed before conversion, they
+ -- have to raise an exception when the operand is a NaN, and rounding must
+ -- be taken into account to determine the safe bounds of the operand.
+
procedure Apply_Selected_Length_Checks
(Ck_Node : Node_Id;
Target_Typ : Entity_Id;
@@ -1346,6 +1355,186 @@ package body Checks is
end if;
end Apply_Divide_Check;
+ ----------------------------------
+ -- Apply_Float_Conversion_Check --
+ ----------------------------------
+
+ -- Let F and I be the source and target types of the conversion.
+ -- The Ada standard specifies that a floating-point value X is rounded
+ -- to the nearest integer, with halfway cases being rounded away from
+ -- zero. The rounded value of X is checked against I'Range.
+
+ -- The catch in the above paragraph is that there is no good way
+ -- to know whether the round-to-integer operation resulted in
+ -- overflow. A remedy is to perform a range check in the floating-point
+ -- domain instead, however:
+ -- (1) The bounds may not be known at compile time
+ -- (2) The check must take into account possible rounding.
+ -- (3) The range of type I may not be exactly representable in F.
+ -- (4) The end-points I'First - 0.5 and I'Last + 0.5 may or may
+ -- not be in range, depending on the sign of I'First and I'Last.
+ -- (5) X may be a NaN, which will fail any comparison
+
+ -- The following steps take care of these issues converting X:
+ -- (1) If either I'First or I'Last is not known at compile time, use
+ -- I'Base instead of I in the next three steps and perform a
+ -- regular range check against I'Range after conversion.
+ -- (2) If I'First - 0.5 is representable in F then let Lo be that
+ -- value and define Lo_OK as (I'First > 0). Otherwise, let Lo be
+ -- F'Machine (T) and let Lo_OK be (Lo >= I'First). In other words,
+ -- take one of the closest floating-point numbers to T, and see if
+ -- it is in range or not.
+ -- (3) If I'Last + 0.5 is representable in F then let Hi be that value
+ -- and define Hi_OK as (I'Last < 0). Otherwise, let Hi be
+ -- F'Rounding (T) and let Hi_OK be (Hi <= I'Last).
+ -- (4) Raise CE when (Lo_OK and X < Lo) or (not Lo_OK and X <= Lo)
+ -- or (Hi_OK and X > Hi) or (not Hi_OK and X >= Hi)
+
+ procedure Apply_Float_Conversion_Check
+ (Ck_Node : Node_Id;
+ Target_Typ : Entity_Id)
+ is
+ LB : constant Node_Id := Type_Low_Bound (Target_Typ);
+ HB : constant Node_Id := Type_High_Bound (Target_Typ);
+ Loc : constant Source_Ptr := Sloc (Ck_Node);
+ Expr_Type : constant Entity_Id := Base_Type (Etype (Ck_Node));
+ Target_Base : constant Entity_Id := Implementation_Base_Type
+ (Target_Typ);
+ Max_Bound : constant Uint := UI_Expon
+ (Machine_Radix (Expr_Type),
+ Machine_Mantissa (Expr_Type) - 1) - 1;
+ -- Largest bound, so bound plus or minus half is a machine number of F
+
+ Ifirst,
+ Ilast : Uint; -- Bounds of integer type
+ Lo, Hi : Ureal; -- Bounds to check in floating-point domain
+ Lo_OK,
+ Hi_OK : Boolean; -- True iff Lo resp. Hi belongs to I'Range
+
+ Lo_Chk,
+ Hi_Chk : Node_Id; -- Expressions that are False iff check fails
+
+ Reason : RT_Exception_Code;
+
+ begin
+ if not Compile_Time_Known_Value (LB)
+ or not Compile_Time_Known_Value (HB)
+ then
+ declare
+ -- First check that the value falls in the range of the base
+ -- type, to prevent overflow during conversion and then
+ -- perform a regular range check against the (dynamic) bounds.
+
+ Par : constant Node_Id := Parent (Ck_Node);
+
+ pragma Assert (Target_Base /= Target_Typ);
+ pragma Assert (Nkind (Par) = N_Type_Conversion);
+
+ Temp : constant Entity_Id :=
+ Make_Defining_Identifier (Loc,
+ Chars => New_Internal_Name ('T'));
+
+ begin
+ Apply_Float_Conversion_Check (Ck_Node, Target_Base);
+ Set_Etype (Temp, Target_Base);
+
+ Insert_Action (Parent (Par),
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Temp,
+ Object_Definition => New_Occurrence_Of (Target_Typ, Loc),
+ Expression => New_Copy_Tree (Par)),
+ Suppress => All_Checks);
+
+ Insert_Action (Par,
+ Make_Raise_Constraint_Error (Loc,
+ Condition =>
+ Make_Not_In (Loc,
+ Left_Opnd => New_Occurrence_Of (Temp, Loc),
+ Right_Opnd => New_Occurrence_Of (Target_Typ, Loc)),
+ Reason => CE_Range_Check_Failed));
+ Rewrite (Par, New_Occurrence_Of (Temp, Loc));
+
+ return;
+ end;
+ end if;
+
+ -- Get the bounds of the target type
+
+ Ifirst := Expr_Value (LB);
+ Ilast := Expr_Value (HB);
+
+ -- Check against lower bound
+
+ if abs (Ifirst) < Max_Bound then
+ Lo := UR_From_Uint (Ifirst) - Ureal_Half;
+ Lo_OK := (Ifirst > 0);
+ else
+ Lo := Machine (Expr_Type, UR_From_Uint (Ifirst), Round_Even, Ck_Node);
+ Lo_OK := (Lo >= UR_From_Uint (Ifirst));
+ end if;
+
+ if Lo_OK then
+
+ -- Lo_Chk := (X >= Lo)
+
+ Lo_Chk := Make_Op_Ge (Loc,
+ Left_Opnd => Duplicate_Subexpr_No_Checks (Ck_Node),
+ Right_Opnd => Make_Real_Literal (Loc, Lo));
+
+ else
+ -- Lo_Chk := (X > Lo)
+
+ Lo_Chk := Make_Op_Gt (Loc,
+ Left_Opnd => Duplicate_Subexpr_No_Checks (Ck_Node),
+ Right_Opnd => Make_Real_Literal (Loc, Lo));
+ end if;
+
+ -- Check against higher bound
+
+ if abs (Ilast) < Max_Bound then
+ Hi := UR_From_Uint (Ilast) + Ureal_Half;
+ Hi_OK := (Ilast < 0);
+ else
+ Hi := Machine (Expr_Type, UR_From_Uint (Ilast), Round_Even, Ck_Node);
+ Hi_OK := (Hi <= UR_From_Uint (Ilast));
+ end if;
+
+ if Hi_OK then
+
+ -- Hi_Chk := (X <= Hi)
+
+ Hi_Chk := Make_Op_Le (Loc,
+ Left_Opnd => Duplicate_Subexpr_No_Checks (Ck_Node),
+ Right_Opnd => Make_Real_Literal (Loc, Hi));
+
+ else
+ -- Hi_Chk := (X < Hi)
+
+ Hi_Chk := Make_Op_Lt (Loc,
+ Left_Opnd => Duplicate_Subexpr_No_Checks (Ck_Node),
+ Right_Opnd => Make_Real_Literal (Loc, Hi));
+ end if;
+
+ -- If the bounds of the target type are the same as those of the
+ -- base type, the check is an overflow check as a range check is
+ -- not performed in these cases.
+
+ if Expr_Value (Type_Low_Bound (Target_Base)) = Ifirst
+ and then Expr_Value (Type_High_Bound (Target_Base)) = Ilast
+ then
+ Reason := CE_Overflow_Check_Failed;
+ else
+ Reason := CE_Range_Check_Failed;
+ end if;
+
+ -- Raise CE if either conditions does not hold
+
+ Insert_Action (Ck_Node,
+ Make_Raise_Constraint_Error (Loc,
+ Condition => Make_Op_Not (Loc, Make_Op_And (Loc, Lo_Chk, Hi_Chk)),
+ Reason => Reason));
+ end Apply_Float_Conversion_Check;
+
------------------------
-- Apply_Length_Check --
------------------------
@@ -1918,9 +2107,14 @@ package body Checks is
-- and no floating point type is involved in the type conversion
-- then fixed point values must be read as integral values.
+ Float_To_Int : constant Boolean :=
+ Is_Floating_Point_Type (Expr_Type)
+ and then Is_Integer_Type (Target_Type);
+
begin
if not Overflow_Checks_Suppressed (Target_Base)
and then not In_Subrange_Of (Expr_Type, Target_Base, Conv_OK)
+ and then not Float_To_Int
then
Set_Do_Overflow_Check (N);
end if;
@@ -1928,8 +2122,12 @@ package body Checks is
if not Range_Checks_Suppressed (Target_Type)
and then not Range_Checks_Suppressed (Expr_Type)
then
- Apply_Scalar_Range_Check
- (Expr, Target_Type, Fixed_Int => Conv_OK);
+ if Float_To_Int then
+ Apply_Float_Conversion_Check (Expr, Target_Type);
+ else
+ Apply_Scalar_Range_Check
+ (Expr, Target_Type, Fixed_Int => Conv_OK);
+ end if;
end if;
end;
@@ -2193,162 +2391,213 @@ package body Checks is
procedure Null_Exclusion_Static_Checks (N : Node_Id) is
K : constant Node_Kind := Nkind (N);
- Expr : Node_Id;
Typ : Entity_Id;
Related_Nod : Node_Id;
Has_Null_Exclusion : Boolean := False;
- -- Following declarations and subprograms are just used to qualify the
- -- error messages
-
type Msg_Kind is (Components, Formals, Objects);
Msg_K : Msg_Kind := Objects;
+ -- Used by local subprograms to generate precise error messages
- procedure Must_Be_Initialized;
- procedure Null_Not_Allowed;
+ procedure Check_Must_Be_Access
+ (Typ : Entity_Id;
+ Has_Null_Exclusion : Boolean);
+ -- ??? local subprograms must have comment on spec
- -------------------------
- -- Must_Be_Initialized --
- -------------------------
+ procedure Check_Already_Null_Excluding_Type
+ (Typ : Entity_Id;
+ Has_Null_Exclusion : Boolean;
+ Related_Nod : Node_Id);
+ -- ??? local subprograms must have comment on spec
+
+ procedure Check_Must_Be_Initialized
+ (N : Node_Id;
+ Related_Nod : Node_Id);
+ -- ??? local subprograms must have comment on spec
+
+ procedure Check_Null_Not_Allowed (N : Node_Id);
+ -- ??? local subprograms must have comment on spec
+
+ -- ??? following bodies lack comments
+
+ --------------------------
+ -- Check_Must_Be_Access --
+ --------------------------
- procedure Must_Be_Initialized is
+ procedure Check_Must_Be_Access
+ (Typ : Entity_Id;
+ Has_Null_Exclusion : Boolean)
+ is
begin
- case Msg_K is
- when Components =>
- Error_Msg_N
- ("(Ada 0Y) null-excluding components must be initialized",
- Related_Nod);
-
- when Formals =>
- Error_Msg_N
- ("(Ada 0Y) null-excluding formals must be initialized",
- Related_Nod);
-
- when Objects =>
- Error_Msg_N
- ("(Ada 0Y) null-excluding objects must be initialized",
- Related_Nod);
- end case;
- end Must_Be_Initialized;
+ if Has_Null_Exclusion
+ and then not Is_Access_Type (Typ)
+ then
+ Error_Msg_N ("(Ada 0Y) must be an access type", Related_Nod);
+ end if;
+ end Check_Must_Be_Access;
- ----------------------
- -- Null_Not_Allowed --
- ----------------------
+ ---------------------------------------
+ -- Check_Already_Null_Excluding_Type --
+ ---------------------------------------
- procedure Null_Not_Allowed is
+ procedure Check_Already_Null_Excluding_Type
+ (Typ : Entity_Id;
+ Has_Null_Exclusion : Boolean;
+ Related_Nod : Node_Id)
+ is
begin
- case Msg_K is
- when Components =>
- Error_Msg_N
- ("(Ada 0Y) NULL not allowed in null-excluding components",
- Expr);
-
- when Formals =>
- Error_Msg_N
- ("(Ada 0Y) NULL not allowed in null-excluding formals",
- Expr);
-
- when Objects =>
- Error_Msg_N
- ("(Ada 0Y) NULL not allowed in null-excluding objects",
- Expr);
- end case;
- end Null_Not_Allowed;
+ if Has_Null_Exclusion
+ and then Can_Never_Be_Null (Typ)
+ then
+ Error_Msg_N
+ ("(Ada 0Y) already a null-excluding type", Related_Nod);
+ end if;
+ end Check_Already_Null_Excluding_Type;
+
+ -------------------------------
+ -- Check_Must_Be_Initialized --
+ -------------------------------
+
+ procedure Check_Must_Be_Initialized
+ (N : Node_Id;
+ Related_Nod : Node_Id)
+ is
+ Expr : constant Node_Id := Expression (N);
+
+ begin
+ pragma Assert (Nkind (N) = N_Component_Declaration
+ or else Nkind (N) = N_Object_Declaration);
+
+ if not Present (Expr) then
+ case Msg_K is
+ when Components =>
+ Error_Msg_N
+ ("(Ada 0Y) null-excluding components must be initialized",
+ Related_Nod);
+
+ when Formals =>
+ Error_Msg_N
+ ("(Ada 0Y) null-excluding formals must be initialized",
+ Related_Nod);
+
+ when Objects =>
+ Error_Msg_N
+ ("(Ada 0Y) null-excluding objects must be initialized",
+ Related_Nod);
+ end case;
+ end if;
+ end Check_Must_Be_Initialized;
+
+ ----------------------------
+ -- Check_Null_Not_Allowed --
+ ----------------------------
+
+ procedure Check_Null_Not_Allowed (N : Node_Id) is
+ Expr : constant Node_Id := Expression (N);
+
+ begin
+ if Present (Expr)
+ and then Nkind (Expr) = N_Null
+ then
+ case Msg_K is
+ when Components =>
+ Error_Msg_N
+ ("(Ada 0Y) NULL not allowed in null-excluding components",
+ Expr);
+
+ when Formals =>
+ Error_Msg_N
+ ("(Ada 0Y) NULL not allowed in null-excluding formals",
+ Expr);
+
+ when Objects =>
+ Error_Msg_N
+ ("(Ada 0Y) NULL not allowed in null-excluding objects",
+ Expr);
+ end case;
+ end if;
+ end Check_Null_Not_Allowed;
-- Start of processing for Null_Exclusion_Static_Checks
begin
pragma Assert (K = N_Component_Declaration
- or else K = N_Parameter_Specification
- or else K = N_Object_Declaration
- or else K = N_Discriminant_Specification
- or else K = N_Allocator);
-
- Expr := Expression (N);
+ or else K = N_Parameter_Specification
+ or else K = N_Object_Declaration
+ or else K = N_Discriminant_Specification
+ or else K = N_Allocator);
case K is
when N_Component_Declaration =>
- Msg_K := Components;
- Has_Null_Exclusion := Null_Exclusion_Present
- (Component_Definition (N));
- Typ := Etype (Subtype_Indication
- (Component_Definition (N)));
- Related_Nod := Subtype_Indication
- (Component_Definition (N));
+ Msg_K := Components;
+
+ if not Present (Access_Definition (Component_Definition (N))) then
+ Has_Null_Exclusion := Null_Exclusion_Present
+ (Component_Definition (N));
+ Typ := Etype (Subtype_Indication (Component_Definition (N)));
+ Related_Nod := Subtype_Indication (Component_Definition (N));
+ Check_Must_Be_Access (Typ, Has_Null_Exclusion);
+ Check_Already_Null_Excluding_Type
+ (Typ, Has_Null_Exclusion, Related_Nod);
+ Check_Must_Be_Initialized (N, Related_Nod);
+ end if;
+
+ Check_Null_Not_Allowed (N);
when N_Parameter_Specification =>
- Msg_K := Formals;
+ Msg_K := Formals;
Has_Null_Exclusion := Null_Exclusion_Present (N);
- Typ := Entity (Parameter_Type (N));
- Related_Nod := Parameter_Type (N);
+ Typ := Entity (Parameter_Type (N));
+ Related_Nod := Parameter_Type (N);
+ Check_Must_Be_Access (Typ, Has_Null_Exclusion);
+ Check_Already_Null_Excluding_Type
+ (Typ, Has_Null_Exclusion, Related_Nod);
+ Check_Null_Not_Allowed (N);
when N_Object_Declaration =>
- Msg_K := Objects;
+ Msg_K := Objects;
Has_Null_Exclusion := Null_Exclusion_Present (N);
- Typ := Entity (Object_Definition (N));
- Related_Nod := Object_Definition (N);
+ Typ := Entity (Object_Definition (N));
+ Related_Nod := Object_Definition (N);
+ Check_Must_Be_Access (Typ, Has_Null_Exclusion);
+ Check_Already_Null_Excluding_Type
+ (Typ, Has_Null_Exclusion, Related_Nod);
+ Check_Must_Be_Initialized (N, Related_Nod);
+ Check_Null_Not_Allowed (N);
when N_Discriminant_Specification =>
- Msg_K := Components;
-
- if Nkind (Discriminant_Type (N)) = N_Access_Definition then
-
- -- This case is special. We do not want to carry out some of
- -- the null-excluding checks. Reason: the analysis of the
- -- access_definition propagates the null-excluding attribute
- -- to the can_never_be_null entity attribute (and thus it is
- -- wrong to check it now)
+ Msg_K := Components;
- Has_Null_Exclusion := False;
- else
+ if Nkind (Discriminant_Type (N)) /= N_Access_Definition then
Has_Null_Exclusion := Null_Exclusion_Present (N);
+ Typ := Etype (Defining_Identifier (N));
+ Related_Nod := Discriminant_Type (N);
+ Check_Must_Be_Access (Typ, Has_Null_Exclusion);
+ Check_Already_Null_Excluding_Type
+ (Typ, Has_Null_Exclusion, Related_Nod);
end if;
- Typ := Etype (Defining_Identifier (N));
- Related_Nod := Discriminant_Type (N);
+ Check_Null_Not_Allowed (N);
when N_Allocator =>
- Msg_K := Objects;
+ Msg_K := Objects;
Has_Null_Exclusion := Null_Exclusion_Present (N);
- Typ := Etype (Expr);
+ Typ := Etype (Expression (N));
- if Nkind (Expr) = N_Qualified_Expression then
- Related_Nod := Subtype_Mark (Expr);
+ if Nkind (Expression (N)) = N_Qualified_Expression then
+ Related_Nod := Subtype_Mark (Expression (N));
else
- Related_Nod := Expr;
+ Related_Nod := Expression (N);
end if;
+ Check_Must_Be_Access (Typ, Has_Null_Exclusion);
+ Check_Already_Null_Excluding_Type
+ (Typ, Has_Null_Exclusion, Related_Nod);
+ Check_Null_Not_Allowed (N);
+
when others =>
- pragma Assert (False);
- null;
+ raise Program_Error;
end case;
-
- -- Check that the entity was already decorated
-
- pragma Assert (Typ /= Empty);
-
- if Has_Null_Exclusion
- and then not Is_Access_Type (Typ)
- then
- Error_Msg_N ("(Ada 0Y) must be an access type", Related_Nod);
-
- elsif Has_Null_Exclusion
- and then Can_Never_Be_Null (Typ)
- then
- Error_Msg_N
- ("(Ada 0Y) already a null-excluding type", Related_Nod);
-
- elsif (Nkind (N) = N_Component_Declaration
- or else Nkind (N) = N_Object_Declaration)
- and not Present (Expr)
- then
- Must_Be_Initialized;
-
- elsif Present (Expr)
- and then Nkind (Expr) = N_Null
- then
- Null_Not_Allowed;
- end if;
end Null_Exclusion_Static_Checks;
----------------------------------
@@ -3129,6 +3378,16 @@ package body Checks is
if Is_Access_Type (Atyp) then
Atyp := Designated_Type (Atyp);
+
+ -- If the prefix is an access to an unconstrained array,
+ -- perform check unconditionally: it depends on the bounds
+ -- of an object and we cannot currently recognize whether
+ -- the test may be redundant.
+
+ if not Is_Constrained (Atyp) then
+ Set_Do_Range_Check (N, True);
+ return;
+ end if;
end if;
Indx := First_Index (Atyp);
diff --git a/gcc/ada/clean.adb b/gcc/ada/clean.adb
index 7759bbb82e2..53f82d0d416 100644
--- a/gcc/ada/clean.adb
+++ b/gcc/ada/clean.adb
@@ -24,10 +24,13 @@
-- --
------------------------------------------------------------------------------
+with Ada.Command_Line; use Ada.Command_Line;
+
with ALI; use ALI;
with Csets;
with Gnatvsn;
with Hostparm;
+with Makeutl; use Makeutl;
with Namet; use Namet;
with Opt; use Opt;
with Osint; use Osint;
@@ -43,12 +46,10 @@ with System;
with Table;
with Types; use Types;
-with GNAT.Command_Line; use GNAT.Command_Line;
with GNAT.Directory_Operations; use GNAT.Directory_Operations;
with GNAT.IO; use GNAT.IO;
with GNAT.OS_Lib; use GNAT.OS_Lib;
-
package body Clean is
Initialized : Boolean := False;
@@ -136,15 +137,13 @@ package body Clean is
procedure Init_Q;
-- Must be called to initialize the Q
- procedure Insert_Q
- (Source_File : File_Name_Type);
- -- If Source_File is not marked, inserts it at the end of Q and mark it
+ procedure Insert_Q (Lib_File : File_Name_Type);
+ -- If Lib_File is not marked, inserts it at the end of Q and mark it
function Empty_Q return Boolean;
-- Returns True if Q is empty.
- procedure Extract_From_Q
- (Source_File : out File_Name_Type);
+ procedure Extract_From_Q (Lib_File : out File_Name_Type);
-- Extracts the first element from the Q.
Q_Front : Natural;
@@ -367,14 +366,14 @@ package body Clean is
Main_Source_File : File_Name_Type;
-- Current main source
- Source_File : File_Name_Type;
- -- Current source file
+ Main_Lib_File : File_Name_Type;
+ -- ALI file of the current main
Lib_File : File_Name_Type;
- -- Current library file
+ -- Current ALI file
Full_Lib_File : File_Name_Type;
- -- Full name of the current library file
+ -- Full name of the current ALI file
Text : Text_Buffer_Ptr;
The_ALI : ALI_Id;
@@ -393,12 +392,13 @@ package body Clean is
for N_File in 1 .. Osint.Number_Of_Files loop
Main_Source_File := Next_Main_Source;
- Insert_Q (Main_Source_File);
+ Main_Lib_File := Osint.Lib_File_Name
+ (Main_Source_File, Current_File_Index);
+ Insert_Q (Main_Lib_File);
while not Empty_Q loop
Sources.Set_Last (0);
- Extract_From_Q (Source_File);
- Lib_File := Osint.Lib_File_Name (Source_File);
+ Extract_From_Q (Lib_File);
Full_Lib_File := Osint.Full_Lib_File_Name (Lib_File);
-- If we have an existing ALI file that is not read-only,
@@ -428,7 +428,7 @@ package body Clean is
for K in ALI.Units.Table (J).First_With ..
ALI.Units.Table (J).Last_With
loop
- Insert_Q (Withs.Table (K).Sfile);
+ Insert_Q (Withs.Table (K).Afile);
end loop;
end loop;
@@ -499,7 +499,7 @@ package body Clean is
if not Compile_Only then
declare
- Source : constant Name_Id := Strip_Suffix (Main_Source_File);
+ Source : constant Name_Id := Strip_Suffix (Main_Lib_File);
Executable : constant String := Get_Name_String
(Executable_Name (Source));
begin
@@ -529,7 +529,10 @@ package body Clean is
Data : constant Project_Data := Projects.Table (Project);
U_Data : Prj.Com.Unit_Data;
File_Name1 : Name_Id;
+ Index1 : Int;
File_Name2 : Name_Id;
+ Index2 : Int;
+ Lib_File : File_Name_Type;
use Prj.Com;
@@ -583,14 +586,18 @@ package body Clean is
(U_Data.File_Names (Specification).Project, Project)
then
File_Name1 := U_Data.File_Names (Body_Part).Name;
+ Index1 := U_Data.File_Names (Body_Part).Index;
File_Name2 := U_Data.File_Names (Specification).Name;
+ Index2 := U_Data.File_Names (Specification).Index;
-- If there is no body file name, then there may be only a
-- spec.
if File_Name1 = No_Name then
File_Name1 := File_Name2;
+ Index1 := Index2;
File_Name2 := No_Name;
+ Index2 := 0;
end if;
end if;
@@ -598,11 +605,13 @@ package body Clean is
-- object directory.
if File_Name1 /= No_Name then
+ Lib_File := Osint.Lib_File_Name (File_Name1, Index1);
+
declare
- Asm : constant String := Assembly_File_Name (File_Name1);
- ALI : constant String := ALI_File_Name (File_Name1);
- Obj : constant String := Object_File_Name (File_Name1);
- Adt : constant String := Tree_File_Name (File_Name1);
+ Asm : constant String := Assembly_File_Name (Lib_File);
+ ALI : constant String := ALI_File_Name (Lib_File);
+ Obj : constant String := Object_File_Name (Lib_File);
+ Adt : constant String := Tree_File_Name (Lib_File);
Deb : constant String := Debug_File_Name (File_Name1);
Rep : constant String := Repinfo_File_Name (File_Name1);
Del : Boolean := True;
@@ -776,7 +785,11 @@ package body Clean is
Main_Source_File := Next_Main_Source;
if not Compile_Only then
- Executable := Executable_Of (Main_Project, Main_Source_File);
+ Executable :=
+ Executable_Of
+ (Main_Project,
+ Main_Source_File,
+ Current_File_Index);
if Is_Regular_File (Get_Name_String (Executable)) then
Delete (Exec_Dir, Get_Name_String (Executable));
@@ -938,12 +951,12 @@ package body Clean is
-- Extract_From_Q --
--------------------
- procedure Extract_From_Q (Source_File : out File_Name_Type) is
- File : constant File_Name_Type := Q.Table (Q_Front);
+ procedure Extract_From_Q (Lib_File : out File_Name_Type) is
+ Lib : constant File_Name_Type := Q.Table (Q_Front);
begin
- Q_Front := Q_Front + 1;
- Source_File := File;
+ Q_Front := Q_Front + 1;
+ Lib_File := Lib;
end Extract_From_Q;
---------------
@@ -1019,12 +1032,14 @@ package body Clean is
if Main_Project /= No_Project and then Osint.Number_Of_Files = 0 then
declare
Value : String_List_Id := Projects.Table (Main_Project).Mains;
-
+ Main : String_Element;
begin
while Value /= Prj.Nil_String loop
- Get_Name_String (String_Elements.Table (Value).Value);
- Osint.Add_File (Name_Buffer (1 .. Name_Len));
- Value := String_Elements.Table (Value).Next;
+ Main := String_Elements.Table (Value);
+ Osint.Add_File
+ (File_Name => Get_Name_String (Main.Value),
+ Index => Main.Index);
+ Value := Main.Next;
end loop;
end;
end if;
@@ -1152,19 +1167,17 @@ package body Clean is
-- Insert_Q --
--------------
- procedure Insert_Q (Source_File : File_Name_Type) is
+ procedure Insert_Q (Lib_File : File_Name_Type) is
begin
-- Do not insert an empty name or an already marked source
- if Source_File /= No_Name
- and then Get_Name_Table_Byte (Source_File) = 0
- then
- Q.Table (Q.Last) := Source_File;
+ if Lib_File /= No_Name and then not Is_Marked (Lib_File) then
+ Q.Table (Q.Last) := Lib_File;
Q.Increment_Last;
-- Mark the source that has been just added to the Q
- Set_Name_Table_Byte (Source_File, 1);
+ Mark (Lib_File);
end if;
end Insert_Q;
@@ -1196,165 +1209,236 @@ package body Clean is
--------------------
procedure Parse_Cmd_Line is
+ Source_Index : Int := 0;
+ Index : Positive := 1;
+ Last : constant Natural := Argument_Count;
begin
- loop
- case
- GNAT.Command_Line.Getopt
- ("aO: c D: F h I: I- n P: q r v vP0 vP1 vP2 X:")
- is
- when ASCII.NUL =>
- exit;
+ while Index <= Last loop
+ declare
+ Arg : constant String := Argument (Index);
- when 'a' =>
- Add_Lib_Search_Dir (GNAT.Command_Line.Parameter);
+ procedure Bad_Argument;
+ -- Signal bad argument
- when 'c' =>
- Compile_Only := True;
+ ------------------
+ -- Bad_Argument --
+ ------------------
- when 'D' =>
- declare
- Dir : constant String := GNAT.Command_Line.Parameter;
+ procedure Bad_Argument is
+ begin
+ Fail ("invalid argument """, Arg, """");
+ end Bad_Argument;
- begin
- if Object_Directory_Path /= null then
- Fail ("duplicate -D switch");
+ begin
+ if Arg'Length /= 0 then
+ if Arg (1) = '-' then
+ if Arg'Length = 1 then
+ Bad_Argument;
+ end if;
- elsif Project_File_Name /= null then
- Fail ("-P and -D cannot be used simultaneously");
+ case Arg (2) is
+ when 'a' =>
+ if Arg'Length < 4 or else Arg (3) /= 'O' then
+ Bad_Argument;
+ end if;
- elsif not Is_Directory (Dir) then
- Fail (Dir, " is not a directory");
+ Add_Lib_Search_Dir (Arg (3 .. Arg'Last));
- else
- Add_Lib_Search_Dir (Dir);
- end if;
- end;
+ when 'c' =>
+ Compile_Only := True;
- when 'F' =>
- Full_Path_Name_For_Brief_Errors := True;
+ when 'D' =>
+ if Object_Directory_Path /= null then
+ Fail ("duplicate -D switch");
- when 'h' =>
- Usage;
+ elsif Project_File_Name /= null then
+ Fail ("-P and -D cannot be used simultaneously");
+ end if;
- when 'I' =>
- if Full_Switch = "I-" then
- Opt.Look_In_Primary_Dir := False;
+ if Arg'Length > 2 then
+ declare
+ Dir : constant String := Arg (3 .. Arg'Last);
+ begin
+ if not Is_Directory (Dir) then
+ Fail (Dir, " is not a directory");
+ else
+ Add_Lib_Search_Dir (Dir);
+ end if;
+ end;
- else
- Add_Lib_Search_Dir (GNAT.Command_Line.Parameter);
- end if;
+ else
+ if Index = Last then
+ Fail ("no directory specified after -D");
+ end if;
- when 'n' =>
- Do_Nothing := True;
+ Index := Index + 1;
- when 'P' =>
- if Project_File_Name /= null then
- Fail ("multiple -P switches");
+ declare
+ Dir : constant String := Argument (Index);
+ begin
+ if not Is_Directory (Dir) then
+ Fail (Dir, " is not a directory");
+ else
+ Add_Lib_Search_Dir (Dir);
+ end if;
+ end;
+ end if;
- elsif Object_Directory_Path /= null then
- Fail ("-D and -P cannot be used simultaneously");
+ when 'F' =>
+ Full_Path_Name_For_Brief_Errors := True;
- else
- declare
- Prj : constant String := GNAT.Command_Line.Parameter;
- begin
- if Prj'Length > 1 and then Prj (Prj'First) = '=' then
- Project_File_Name :=
- new String'(Prj (Prj'First + 1 .. Prj'Last));
+ when 'h' =>
+ Usage;
- else
- Project_File_Name := new String'(Prj);
- end if;
- end;
- end if;
+ when 'i' =>
+ if Arg'Length = 2 then
+ Bad_Argument;
+ end if;
- when 'q' =>
- Quiet_Output := True;
+ Source_Index := 0;
- when 'r' =>
- All_Projects := True;
+ for J in 3 .. Arg'Last loop
+ if Arg (J) not in '0' .. '9' then
+ Bad_Argument;
+ end if;
- when 'v' =>
- if Full_Switch = "v" then
- Verbose_Mode := True;
+ Source_Index :=
+ (20 * Source_Index) +
+ (Character'Pos (Arg (J)) - Character'Pos ('0'));
+ end loop;
- elsif Full_Switch = "vP0" then
- Prj.Com.Current_Verbosity := Prj.Default;
+ when 'I' =>
+ if Arg = "-I-" then
+ Opt.Look_In_Primary_Dir := False;
- elsif Full_Switch = "vP1" then
- Prj.Com.Current_Verbosity := Prj.Medium;
+ else
+ if Arg'Length = 2 then
+ Bad_Argument;
+ end if;
- else
- Prj.Com.Current_Verbosity := Prj.High;
- end if;
+ Add_Lib_Search_Dir (Arg (3 .. Arg'Last));
+ end if;
- when 'X' =>
- declare
- Ext_Asgn : constant String := GNAT.Command_Line.Parameter;
- Start : Positive := Ext_Asgn'First;
- Stop : Natural := Ext_Asgn'Last;
- Equal_Pos : Natural;
- OK : Boolean := True;
+ when 'n' =>
+ Do_Nothing := True;
- begin
- if Ext_Asgn (Start) = '"' then
- if Ext_Asgn (Stop) = '"' then
- Start := Start + 1;
- Stop := Stop - 1;
+ when 'P' =>
+ if Project_File_Name /= null then
+ Fail ("multiple -P switches");
- else
- OK := False;
- end if;
- end if;
+ elsif Object_Directory_Path /= null then
+ Fail ("-D and -P cannot be used simultaneously");
- Equal_Pos := Start;
+ end if;
- while Equal_Pos <= Stop and then
- Ext_Asgn (Equal_Pos) /= '='
- loop
- Equal_Pos := Equal_Pos + 1;
- end loop;
+ if Arg'Length > 2 then
+ declare
+ Prj : constant String := Arg (3 .. Arg'Last);
+ begin
+ if Prj'Length > 1 and then
+ Prj (Prj'First) = '='
+ then
+ Project_File_Name :=
+ new String'
+ (Prj (Prj'First + 1 .. Prj'Last));
+ else
+ Project_File_Name := new String'(Prj);
+ end if;
+ end;
- if Equal_Pos = Start or else Equal_Pos > Stop then
- OK := False;
- end if;
+ else
+ if Index = Last then
+ Fail ("no project specified after -P");
+ end if;
- if OK then
- Prj.Ext.Add
- (External_Name => Ext_Asgn (Start .. Equal_Pos - 1),
- Value => Ext_Asgn (Equal_Pos + 1 .. Stop));
+ Index := Index + 1;
+ Project_File_Name := new String'(Argument (Index));
+ end if;
- else
- Fail ("illegal external assignment '", Ext_Asgn, "'");
- end if;
- end;
+ when 'q' =>
+ Quiet_Output := True;
- when others =>
- Fail ("INTERNAL ERROR, please report");
- end case;
- end loop;
+ when 'r' =>
+ All_Projects := True;
- -- Get the file names
+ when 'v' =>
+ if Arg = "-v" then
+ Verbose_Mode := True;
- loop
- declare
- S : constant String := GNAT.Command_Line.Get_Argument;
+ elsif Arg = "-vP0" then
+ Prj.Com.Current_Verbosity := Prj.Default;
- begin
- exit when S'Length = 0;
+ elsif Arg = "-vP1" then
+ Prj.Com.Current_Verbosity := Prj.Medium;
- Add_File (S);
- end;
- end loop;
+ elsif Arg = "-vP2" then
+ Prj.Com.Current_Verbosity := Prj.High;
- exception
- when GNAT.Command_Line.Invalid_Switch =>
- Usage;
- Fail ("invalid switch : "& GNAT.Command_Line.Full_Switch);
+ else
+ Bad_Argument;
+ end if;
- when GNAT.Command_Line.Invalid_Parameter =>
- Usage;
- Fail ("parameter missing for : " & GNAT.Command_Line.Full_Switch);
+ when 'X' =>
+ if Arg'Length = 2 then
+ Bad_Argument;
+ end if;
+
+ declare
+ Ext_Asgn : constant String := Arg (3 .. Arg'Last);
+ Start : Positive := Ext_Asgn'First;
+ Stop : Natural := Ext_Asgn'Last;
+ Equal_Pos : Natural;
+ OK : Boolean := True;
+
+ begin
+ if Ext_Asgn (Start) = '"' then
+ if Ext_Asgn (Stop) = '"' then
+ Start := Start + 1;
+ Stop := Stop - 1;
+
+ else
+ OK := False;
+ end if;
+ end if;
+
+ Equal_Pos := Start;
+
+ while Equal_Pos <= Stop
+ and then Ext_Asgn (Equal_Pos) /= '='
+ loop
+ Equal_Pos := Equal_Pos + 1;
+ end loop;
+
+ if Equal_Pos = Start or else Equal_Pos > Stop then
+ OK := False;
+ end if;
+
+ if OK then
+ Prj.Ext.Add
+ (External_Name =>
+ Ext_Asgn (Start .. Equal_Pos - 1),
+ Value =>
+ Ext_Asgn (Equal_Pos + 1 .. Stop));
+
+ else
+ Fail
+ ("illegal external assignment '",
+ Ext_Asgn, "'");
+ end if;
+ end;
+
+ when others =>
+ Bad_Argument;
+ end case;
+
+ else
+ Add_File (Arg, Source_Index);
+ end if;
+ end if;
+ end;
+
+ Index := Index + 1;
+ end loop;
end Parse_Cmd_Line;
-----------------------
@@ -1398,7 +1482,7 @@ package body Clean is
if not Usage_Displayed then
Usage_Displayed := True;
Display_Copyright;
- Put_Line ("Usage: gnatclean [switches] names");
+ Put_Line ("Usage: gnatclean [switches] {[-innn] name}");
New_Line;
Put_Line (" names is one or more file names from which " &
@@ -1411,6 +1495,7 @@ package body Clean is
Put_Line (" -F Full project path name " &
"in brief error messages");
Put_Line (" -h Display this message");
+ Put_Line (" -innn Index of unit in source for following names");
Put_Line (" -n Nothing to do: only list files to delete");
Put_Line (" -Pproj Use GNAT Project File proj");
Put_Line (" -q Be quiet/terse");
diff --git a/gcc/ada/config-lang.in b/gcc/ada/config-lang.in
index 9a9599dbf1b..eb044afdb81 100644
--- a/gcc/ada/config-lang.in
+++ b/gcc/ada/config-lang.in
@@ -27,7 +27,7 @@
# stagestuff - files to add to $(STAGESTUFF)
language="ada"
-boot_language=yes
+boot_language=no
boot_language_boot_flags='ADAFLAGS="$(BOOT_ADAFLAGS)"'
compilers="gnat1\$(exeext)"
@@ -39,3 +39,6 @@ gtfiles="\$(srcdir)/ada/ada-tree.h \$(srcdir)/ada/gigi.h \$(srcdir)/ada/decl.c \
outputs=ada/Makefile
target_libs="target-libada"
+
+# Ada will not work until the front end starts emitting GIMPLE trees.
+build_by_default=no
diff --git a/gcc/ada/cstand.adb b/gcc/ada/cstand.adb
index 7c133248c07..b7d1c90eb5c 100644
--- a/gcc/ada/cstand.adb
+++ b/gcc/ada/cstand.adb
@@ -402,6 +402,11 @@ package body CStand is
Set_Etype (R_Node, Standard_Boolean);
Set_Parent (R_Node, Standard_Boolean);
+ -- Record entity identifiers for boolean literals in the
+ -- Boolean_Literals array, for easy reference during expansion.
+
+ Boolean_Literals := (False => Standard_False, True => Standard_True);
+
-- Create type definition nodes for predefined integer types
Build_Signed_Integer_Type
diff --git a/gcc/ada/decl.c b/gcc/ada/decl.c
index 5b0581fd819..92e1342feb9 100644
--- a/gcc/ada/decl.c
+++ b/gcc/ada/decl.c
@@ -1048,7 +1048,11 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|| (flag_stack_check && ! STACK_CHECK_BUILTIN
&& 0 < compare_tree_int (DECL_SIZE_UNIT (gnu_decl),
STACK_CHECK_MAX_VAR_SIZE))))
- update_setjmp_buf (TREE_VALUE (gnu_block_stack));
+ expand_expr_stmt
+ (build_call_1_expr (update_setjmp_buf_decl,
+ build_unary_op
+ (ADDR_EXPR, NULL_TREE,
+ TREE_VALUE (gnu_block_stack))));
/* If this is a public constant or we're not optimizing and we're not
making a VAR_DECL for it, make one just for export or debugger
@@ -1060,10 +1064,11 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|| Address_Taken (gnat_entity)
|| Is_Aliased (gnat_entity)
|| Is_Aliased (Etype (gnat_entity))))
- SET_DECL_CONST_CORRESPONDING_VAR (gnu_decl,
- create_var_decl (gnu_entity_id, gnu_ext_name, gnu_type,
- gnu_expr, 0, Is_Public (gnat_entity), 0,
- static_p, 0));
+ SET_DECL_CONST_CORRESPONDING_VAR
+ (gnu_decl,
+ create_var_decl (gnu_entity_id, gnu_ext_name, gnu_type,
+ gnu_expr, 0, Is_Public (gnat_entity), 0,
+ static_p, 0));
/* If this is declared in a block that contains an block with an
exception handler, we must force this variable in memory to
@@ -2730,6 +2735,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
break;
case E_Access_Subprogram_Type:
+ case E_Anonymous_Access_Subprogram_Type:
/* If we are not defining this entity, and we have incomplete
entities being processed above us, make a dummy type and
fill it in later. */
@@ -3046,6 +3052,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
break;
case E_Access_Protected_Subprogram_Type:
+ case E_Anonymous_Access_Protected_Subprogram_Type:
if (type_annotate_only && No (Equivalent_Type (gnat_entity)))
gnu_type = build_pointer_type (void_type_node);
else
@@ -4407,8 +4414,15 @@ maybe_variable (tree gnu_operand, Node_Id gnat_node)
set_lineno (gnat_node, 1);
if (TREE_CODE (gnu_operand) == UNCONSTRAINED_ARRAY_REF)
- return build1 (UNCONSTRAINED_ARRAY_REF, TREE_TYPE (gnu_operand),
- variable_size (TREE_OPERAND (gnu_operand, 0)));
+ {
+ tree gnu_result = build1 (UNCONSTRAINED_ARRAY_REF,
+ TREE_TYPE (gnu_operand),
+ variable_size (TREE_OPERAND (gnu_operand, 0)));
+
+ TREE_READONLY (gnu_result) = TREE_STATIC (gnu_result)
+ = TYPE_READONLY (TREE_TYPE (TREE_TYPE (gnu_operand)));
+ return gnu_result;
+ }
else
return variable_size (gnu_operand);
}
@@ -4600,8 +4614,10 @@ make_packable_type (tree type)
TYPE_LEFT_JUSTIFIED_MODULAR_P (new_type)
= TYPE_LEFT_JUSTIFIED_MODULAR_P (type);
TYPE_CONTAINS_TEMPLATE_P (new_type) = TYPE_CONTAINS_TEMPLATE_P (type);
- TYPE_IS_PADDING_P (new_type) = TYPE_IS_PADDING_P (type);
- if (TREE_CODE (type) == QUAL_UNION_TYPE)
+
+ if (TREE_CODE (type) == RECORD_TYPE)
+ TYPE_IS_PADDING_P (new_type) = TYPE_IS_PADDING_P (type);
+ else if (TREE_CODE (type) == QUAL_UNION_TYPE)
{
TYPE_SIZE (new_type) = TYPE_SIZE (type);
TYPE_SIZE_UNIT (new_type) = TYPE_SIZE_UNIT (type);
@@ -4982,11 +4998,11 @@ gnat_to_gnu_field (Entity_Id gnat_field,
&& TYPE_LEFT_JUSTIFIED_MODULAR_P (gnu_field_type))
gnu_field_type = TREE_TYPE (TYPE_FIELDS (gnu_field_type));
- /* If we are packing this record or we have a specified size that's
- smaller than that of the field type and the field type is also a record
- that's BLKmode and with a small constant size, see if we can get a
- better form of the type that allows more packing. If we can, show
- a size was specified for it if there wasn't one so we know to
+ /* If we are packing this record, have a specified size that's smaller than
+ that of the field type, or a position is specified, and the field type
+ is also a record that's BLKmode and with a small constant size, see if
+ we can get a better form of the type that allows more packing. If we
+ can, show a size was specified for it if there wasn't one so we know to
make this a bitfield and avoid making things wider. */
if (TREE_CODE (gnu_field_type) == RECORD_TYPE
&& TYPE_MODE (gnu_field_type) == BLKmode
@@ -4994,7 +5010,8 @@ gnat_to_gnu_field (Entity_Id gnat_field,
&& compare_tree_int (TYPE_SIZE (gnu_field_type), BIGGEST_ALIGNMENT) <= 0
&& (packed
|| (gnu_size != 0 && tree_int_cst_lt (gnu_size,
- TYPE_SIZE (gnu_field_type)))))
+ TYPE_SIZE (gnu_field_type)))
+ || Present (Component_Clause (gnat_field))))
{
gnu_field_type = make_packable_type (gnu_field_type);
diff --git a/gcc/ada/einfo.adb b/gcc/ada/einfo.adb
index 543aa2caa94..b2ad23f4da1 100644
--- a/gcc/ada/einfo.adb
+++ b/gcc/ada/einfo.adb
@@ -1845,6 +1845,14 @@ package body Einfo is
return Node17 (Id);
end Object_Ref;
+ function Original_Access_Type (Id : E) return E is
+ begin
+ pragma Assert
+ (Ekind (Id) = E_Access_Subprogram_Type
+ or else Ekind (Id) = E_Access_Protected_Subprogram_Type);
+ return Node21 (Id);
+ end Original_Access_Type;
+
function Original_Array_Type (Id : E) return E is
begin
pragma Assert (Is_Array_Type (Id) or else Is_Modular_Integer_Type (Id));
@@ -3747,7 +3755,6 @@ package body Einfo is
Set_Flag136 (Id, V);
end Set_No_Strict_Aliasing;
-
procedure Set_Non_Binary_Modulus (Id : E; V : B := True) is
begin
pragma Assert (Ekind (Id) = E_Modular_Integer_Type);
@@ -3796,6 +3803,14 @@ package body Einfo is
Set_Node17 (Id, V);
end Set_Object_Ref;
+ procedure Set_Original_Access_Type (Id : E; V : E) is
+ begin
+ pragma Assert
+ (Ekind (Id) = E_Access_Subprogram_Type
+ or else Ekind (Id) = E_Access_Protected_Subprogram_Type);
+ Set_Node21 (Id, V);
+ end Set_Original_Access_Type;
+
procedure Set_Original_Array_Type (Id : E; V : E) is
begin
pragma Assert (Is_Array_Type (Id) or else Is_Modular_Integer_Type (Id));
@@ -6996,6 +7011,10 @@ package body Einfo is
Modular_Integer_Kind =>
Write_Str ("Original_Array_Type");
+ when E_Access_Subprogram_Type |
+ E_Access_Protected_Subprogram_Type =>
+ Write_Str ("Original_Access_Type");
+
when others =>
Write_Str ("Field21??");
end case;
diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads
index a8180e4c971..6487a22012e 100644
--- a/gcc/ada/einfo.ads
+++ b/gcc/ada/einfo.ads
@@ -2633,6 +2633,12 @@ package Einfo is
-- Applies to subprograms and subprogram types. Yields the number of
-- formals as a value of type Pos.
+-- Original_Access_Type (Node21)
+-- Present in access to subprogram types. Anonymous access to protected
+-- subprogram types are replaced by an occurrence of an internal access
+-- to subprogram type. This field links the replacement entity with the
+-- original entity.
+
-- Original_Array_Type (Node21)
-- Present in modular types and array types and subtypes. Set only
-- if the Is_Packed_Array_Type flag is set, indicating that the type
@@ -3113,7 +3119,11 @@ package Einfo is
-- The following three entity kinds are introduced by the corresponding
-- type definitions:
- -- E_Access_Type, E_General_Access_Type, E_Anonymous_Access_Type.
+ -- E_Access_Type,
+ -- E_General_Access_Type,
+ -- E_Anonymous_Access_Subprogram_Type,
+ -- E_Anonymous_Access_Protected_Subprogram_Type
+ -- E_Anonymous_Access_Type.
-- In addition, we define the kind E_Allocator_Type to label
-- allocators. This is because special resolution rules apply to this
@@ -3321,6 +3331,14 @@ package Einfo is
-- and a protected operation within, and have different compile-time
-- and run-time properties than other access to subprograms.
+ E_Anonymous_Access_Subprogram_Type,
+ -- An anonymous access to subprogram type, created by an access to
+ -- subprogram declaration.
+
+ E_Anonymous_Access_Protected_Subprogram_Type,
+ -- An anonymous access to protected subprogram type, created by an
+ -- access to subprogram declaration.
+
E_Anonymous_Access_Type,
-- An anonymous access type created by an access parameter or access
-- discriminant.
@@ -3365,18 +3383,19 @@ package Einfo is
-- A record subtype, created by a record subtype declaration.
E_Record_Type_With_Private,
- -- Used for types defined by a private extension declaration. Includes
- -- the fields for both private types and for record types (with the
- -- sole exception of Corresponding_Concurrent_Type which is obviously
- -- not needed). This entity is considered to be both a record type and
+ -- Used for types defined by a private extension declaration, and
+ -- for tagged private types. Includes the fields for both private
+ -- types and for record types (with the sole exception of
+ -- Corresponding_Concurrent_Type which is obviously not needed).
+ -- This entity is considered to be both a record type and
-- a private type.
E_Record_Subtype_With_Private,
-- A subtype of a type defined by a private extension declaration.
E_Private_Type,
- -- A private type, created by a private type declaration that does
- -- not have the keyword limited.
+ -- A private type, created by a private type declaration
+ -- that has neither the keyword limited nor the keyword tagged.
E_Private_Subtype,
-- A subtype of a private type, created by a subtype declaration used
@@ -3384,7 +3403,7 @@ package Einfo is
E_Limited_Private_Type,
-- A limited private type, created by a private type declaration that
- -- has the keyword limited.
+ -- has the keyword limited, but not the keyword tagged.
E_Limited_Private_Subtype,
-- A subtype of a limited private type, created by a subtype declaration
@@ -3542,6 +3561,8 @@ package Einfo is
-- E_General_Access_Type
-- E_Access_Subprogram_Type
-- E_Access_Protected_Subprogram_Type
+ -- E_Anonymous_Access_Subprogram_Type
+ -- E_Anonymous_Access_Protected_Subprogram_Type
E_Anonymous_Access_Type;
subtype Array_Kind is Entity_Kind range
@@ -3637,6 +3658,8 @@ package Einfo is
-- E_General_Access_Type
-- E_Access_Subprogram_Type
-- E_Access_Protected_Subprogram_Type
+ -- E_Anonymous_Access_Subprogram_Type
+ -- E_Anonymous_Access_Protected_Subprogram_Type
E_Anonymous_Access_Type;
subtype Enumeration_Kind is Entity_Kind range
@@ -3809,6 +3832,8 @@ package Einfo is
-- E_General_Access_Type
-- E_Access_Subprogram_Type,
-- E_Access_Protected_Subprogram_Type
+ -- E_Anonymous_Access_Subprogram_Type
+ -- E_Anonymous_Access_Protected_Subprogram_Type
-- E_Anonymous_Access_Type
-- E_Array_Type
-- E_Array_Subtype
@@ -3994,12 +4019,14 @@ package Einfo is
-- E_Access_Protected_Subprogram_Type
-- Equivalent_Type (Node18)
-- Directly_Designated_Type (Node20)
+ -- Original_Access_Type (Node21)
-- Needs_No_Actuals (Flag22)
-- (plus type attributes)
-- E_Access_Subprogram_Type
-- Equivalent_Type (Node18) (remote types only)
-- Directly_Designated_Type (Node20)
+ -- Original_Access_Type (Node21)
-- Needs_No_Actuals (Flag22)
-- (plus type attributes)
@@ -4025,6 +4052,8 @@ package Einfo is
-- Directly_Designated_Type (Node20)
-- (plus type attributes)
+ -- E_Anonymous_Access_Subprogram_Type
+ -- E_Anonymous_Access_Protected_Subprogram_Type
-- E_Anonymous_Access_Type
-- Storage_Size_Variable (Node15) ??? is this needed ???
-- Directly_Designated_Type (Node20)
@@ -5180,6 +5209,7 @@ package Einfo is
function Normalized_Position (Id : E) return U;
function Normalized_Position_Max (Id : E) return U;
function Object_Ref (Id : E) return E;
+ function Original_Access_Type (Id : E) return E;
function Original_Array_Type (Id : E) return E;
function Original_Record_Component (Id : E) return E;
function Packed_Array_Type (Id : E) return E;
@@ -5653,6 +5683,7 @@ package Einfo is
procedure Set_Normalized_Position (Id : E; V : U);
procedure Set_Normalized_Position_Max (Id : E; V : U);
procedure Set_Object_Ref (Id : E; V : E);
+ procedure Set_Original_Access_Type (Id : E; V : E);
procedure Set_Original_Array_Type (Id : E; V : E);
procedure Set_Original_Record_Component (Id : E; V : E);
procedure Set_Packed_Array_Type (Id : E; V : E);
@@ -6180,6 +6211,7 @@ package Einfo is
pragma Inline (Normalized_Position);
pragma Inline (Normalized_Position_Max);
pragma Inline (Object_Ref);
+ pragma Inline (Original_Access_Type);
pragma Inline (Original_Array_Type);
pragma Inline (Original_Record_Component);
pragma Inline (Packed_Array_Type);
@@ -6486,6 +6518,7 @@ package Einfo is
pragma Inline (Set_Normalized_Position);
pragma Inline (Set_Normalized_Position_Max);
pragma Inline (Set_Object_Ref);
+ pragma Inline (Set_Original_Access_Type);
pragma Inline (Set_Original_Array_Type);
pragma Inline (Set_Original_Record_Component);
pragma Inline (Set_Packed_Array_Type);
diff --git a/gcc/ada/erroutc.adb b/gcc/ada/erroutc.adb
index e46c7cd6314..31c97d5bc55 100644
--- a/gcc/ada/erroutc.adb
+++ b/gcc/ada/erroutc.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -33,7 +33,6 @@
with Casing; use Casing;
with Debug; use Debug;
with Err_Vars; use Err_Vars;
-with Hostparm;
with Namet; use Namet;
with Opt; use Opt;
with Output; use Output;
@@ -71,7 +70,6 @@ package body Erroutc is
function Buffer_Ends_With (S : String) return Boolean is
Len : constant Natural := S'Length;
-
begin
return
Msglen > Len
@@ -466,6 +464,10 @@ package body Erroutc is
-- Returns True for a message that is to be purged. Also adjusts
-- error counts appropriately.
+ ------------------
+ -- To_Be_Purged --
+ ------------------
+
function To_Be_Purged (E : Error_Msg_Id) return Boolean is
begin
if E /= No_Error_Msg
diff --git a/gcc/ada/erroutc.ads b/gcc/ada/erroutc.ads
index b0af72df446..cde38932df3 100644
--- a/gcc/ada/erroutc.ads
+++ b/gcc/ada/erroutc.ads
@@ -27,7 +27,6 @@
-- This packages contains global variables and routines common to error
-- reporting packages, including Errout and Prj.Err.
-with Hostparm;
with Table;
with Types; use Types;
@@ -77,11 +76,12 @@ package Erroutc is
Manual_Quote_Mode : Boolean := False;
-- Set True in manual quotation mode
- Max_Msg_Length : constant := 256 + 2 * Hostparm.Max_Line_Length;
- -- Maximum length of error message. The addition of Max_Line_Length
+ Max_Msg_Length : constant := 1024 + 2 * Int (Column_Number'Last);
+ -- Maximum length of error message. The addition of 2 * Column_Number'Last
-- ensures that two insertion tokens of maximum length can be accomodated.
- -- The value of 256 is an arbitrary value that should be more than long
- -- enough to accomodate any reasonable message.
+ -- The value of 1024 is an arbitrary value that should be more than long
+ -- enough to accomodate any reasonable message (and for that matter, some
+ -- pretty unreasonable messages!)
Msg_Buffer : String (1 .. Max_Msg_Length);
-- Buffer used to prepare error messages
diff --git a/gcc/ada/eval_fat.adb b/gcc/ada/eval_fat.adb
index 2a5357cb311..2d439930301 100644
--- a/gcc/ada/eval_fat.adb
+++ b/gcc/ada/eval_fat.adb
@@ -40,8 +40,8 @@ package body Eval_Fat is
type Radix_Power_Table is array (Int range 1 .. 4) of Int;
- Radix_Powers : constant Radix_Power_Table
- := (Radix**1, Radix**2, Radix**3, Radix**4);
+ Radix_Powers : constant Radix_Power_Table :=
+ (Radix ** 1, Radix ** 2, Radix ** 3, Radix ** 4);
function Float_Radix return T renames Ureal_2;
-- Radix expressed in real form
@@ -83,9 +83,6 @@ package body Eval_Fat is
function Machine_Emin (RT : R) return Int;
-- Return value of the Machine_Emin attribute
- function Machine_Mantissa (RT : R) return Nat;
- -- Return value of the Machine_Mantissa attribute
-
--------------
-- Adjacent --
--------------
@@ -706,6 +703,16 @@ package body Eval_Fat is
return Mant;
end Machine_Mantissa;
+ -------------------
+ -- Machine_Radix --
+ -------------------
+
+ function Machine_Radix (RT : R) return Nat is
+ pragma Warnings (Off, RT);
+ begin
+ return Radix;
+ end Machine_Radix;
+
-----------
-- Model --
-----------
diff --git a/gcc/ada/eval_fat.ads b/gcc/ada/eval_fat.ads
index 451326dd523..4f245696491 100644
--- a/gcc/ada/eval_fat.ads
+++ b/gcc/ada/eval_fat.ads
@@ -66,6 +66,10 @@ package Eval_Fat is
function Leading_Part (RT : R; X : T; Radix_Digits : UI) return T;
+ function Machine_Mantissa (RT : R) return Nat;
+
+ function Machine_Radix (RT : R) return Nat;
+
function Model (RT : R; X : T) return T;
function Pred (RT : R; X : T) return T;
diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index 37d9a618da6..966b848931c 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -1165,7 +1165,7 @@ package body Exp_Aggr is
Aggr_Low : constant Node_Id := Duplicate_Subexpr_No_Checks (Aggr_L);
Aggr_High : constant Node_Id := Duplicate_Subexpr_No_Checks (Aggr_H);
- -- After Duplicate_Subexpr these are side-effect free.
+ -- After Duplicate_Subexpr these are side-effect free
Low : Node_Id;
High : Node_Id;
@@ -4122,8 +4122,7 @@ package body Exp_Aggr is
-- Ada 0Y (AI-287): This case has not been analyzed???
- pragma Assert (False);
- null;
+ raise Program_Error;
end if;
-- Name in assignment is explicit dereference.
@@ -4743,11 +4742,13 @@ package body Exp_Aggr is
Typ : Entity_Id;
Target : Node_Id;
Flist : Node_Id := Empty;
- Obj : Entity_Id := Empty) return List_Id is
+ Obj : Entity_Id := Empty) return List_Id
+ is
begin
if Is_Record_Type (Etype (N)) then
return Build_Record_Aggr_Code (N, Typ, Target, Flist, Obj);
- elsif Is_Array_Type (Etype (N)) then
+
+ else pragma Assert (Is_Array_Type (Etype (N)));
return
Build_Array_Aggr_Code
(N => N,
@@ -4757,9 +4758,6 @@ package body Exp_Aggr is
Scalar_Comp => Is_Scalar_Type (Component_Type (Typ)),
Indices => No_List,
Flist => Flist);
- else
- pragma Assert (False);
- return New_List;
end if;
end Late_Expansion;
diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
index 28ece685557..edf358ef1b2 100644
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -1182,13 +1182,8 @@ package body Exp_Attr is
Res := Is_Constrained (Etype (Ent));
end if;
- if Res then
- Rewrite (N,
- New_Reference_To (Standard_True, Loc));
- else
- Rewrite (N,
- New_Reference_To (Standard_False, Loc));
- end if;
+ Rewrite (N,
+ New_Reference_To (Boolean_Literals (Res), Loc));
end;
-- Prefix is not an entity name. These are also cases where
@@ -1196,16 +1191,13 @@ package body Exp_Attr is
-- and type of the prefix.
else
- if not Is_Variable (Pref)
- or else Nkind (Pref) = N_Explicit_Dereference
- or else Is_Constrained (Etype (Pref))
- then
- Rewrite (N,
- New_Reference_To (Standard_True, Loc));
- else
- Rewrite (N,
- New_Reference_To (Standard_False, Loc));
- end if;
+ Rewrite (N,
+ New_Reference_To (
+ Boolean_Literals (
+ not Is_Variable (Pref)
+ or else Nkind (Pref) = N_Explicit_Dereference
+ or else Is_Constrained (Etype (Pref))),
+ Loc));
end if;
Analyze_And_Resolve (N, Standard_Boolean);
@@ -3625,8 +3617,8 @@ package body Exp_Attr is
-- type(X)'Pos (X) >= 0
-- We can't quite generate it that way because of the requirement
- -- for the non-standard second argument of False, so we have to
- -- explicitly create:
+ -- for the non-standard second argument of False in the resulting
+ -- rep_to_pos call, so we have to explicitly create:
-- _rep_to_pos (X, False) >= 0
@@ -3635,7 +3627,7 @@ package body Exp_Attr is
-- _rep_to_pos (X, False) >= 0
-- and then
- -- (X >= type(X)'First and then type(X)'Last <= X)
+ -- (X >= type(X)'First and then type(X)'Last <= X)
elsif Is_Enumeration_Type (Ptyp)
and then Present (Enum_Pos_To_Rep (Base_Type (Ptyp)))
@@ -3710,7 +3702,7 @@ package body Exp_Attr is
-- But that's precisely what won't work because of possible
-- unwanted optimization (and indeed the basic motivation for
- -- the Valid attribute -is exactly that this test does not work.
+ -- the Valid attribute is exactly that this test does not work!)
-- What will work is:
-- Btyp!(X) >= Btyp!(type(X)'First)
diff --git a/gcc/ada/exp_ch13.adb b/gcc/ada/exp_ch13.adb
index 0cde2a67035..60a11478cb7 100644
--- a/gcc/ada/exp_ch13.adb
+++ b/gcc/ada/exp_ch13.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2003, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004, 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- --
@@ -93,7 +93,6 @@ package body Exp_Ch13 is
declare
Decl : constant Node_Id := Declaration_Node (Ent);
-
begin
if Nkind (Decl) = N_Object_Declaration
and then Present (Expression (Decl))
diff --git a/gcc/ada/exp_ch2.adb b/gcc/ada/exp_ch2.adb
index bc8c2ff0d4f..7192cb9a333 100644
--- a/gcc/ada/exp_ch2.adb
+++ b/gcc/ada/exp_ch2.adb
@@ -41,6 +41,7 @@ with Sem_Res; use Sem_Res;
with Sem_Util; use Sem_Util;
with Sem_Warn; use Sem_Warn;
with Sinfo; use Sinfo;
+with Snames; use Snames;
with Stand; use Stand;
with Tbuild; use Tbuild;
with Uintp; use Uintp;
@@ -216,6 +217,14 @@ package body Exp_Ch2 is
-- issue that they do not get replaced when they could be).
and then Nkind (Parent (N)) /= N_Pragma_Argument_Association
+
+ -- Same for Asm_Input and Asm_Output attribute references
+
+ and then not (Nkind (Parent (N)) = N_Attribute_Reference
+ and then
+ (Attribute_Name (Parent (N)) = Name_Asm_Input
+ or else
+ Attribute_Name (Parent (N)) = Name_Asm_Output))
then
-- Case of Current_Value is a compile time known value
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index c9de061ec58..4ae959a992d 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -374,6 +374,7 @@ package body Exp_Ch4 is
-- We analyze by hand the new internal allocator to avoid
-- any recursion and inappropriate call to Initialize
+
if not Aggr_In_Place then
Remove_Side_Effects (Exp);
end if;
@@ -2698,10 +2699,11 @@ package body Exp_Ch4 is
-----------------
procedure Expand_N_In (N : Node_Id) is
- Loc : constant Source_Ptr := Sloc (N);
- Rtyp : constant Entity_Id := Etype (N);
- Lop : constant Node_Id := Left_Opnd (N);
- Rop : constant Node_Id := Right_Opnd (N);
+ Loc : constant Source_Ptr := Sloc (N);
+ Rtyp : constant Entity_Id := Etype (N);
+ Lop : constant Node_Id := Left_Opnd (N);
+ Rop : constant Node_Id := Right_Opnd (N);
+ Static : constant Boolean := Is_OK_Static_Expression (N);
begin
-- If we have an explicit range, do a bit of optimization based
@@ -2717,11 +2719,14 @@ package body Exp_Ch4 is
begin
-- If either check is known to fail, replace result
-- by False, since the other check does not matter.
+ -- Preserve the static flag for legality checks, because
+ -- we are constant-folding beyond RM 4.9.
if Lcheck = LT or else Ucheck = GT then
Rewrite (N,
New_Reference_To (Standard_False, Loc));
Analyze_And_Resolve (N, Rtyp);
+ Set_Is_Static_Expression (N, Static);
return;
-- If both checks are known to succeed, replace result
@@ -2731,6 +2736,7 @@ package body Exp_Ch4 is
Rewrite (N,
New_Reference_To (Standard_True, Loc));
Analyze_And_Resolve (N, Rtyp);
+ Set_Is_Static_Expression (N, Static);
return;
-- If lower bound check succeeds and upper bound check is
@@ -6523,7 +6529,7 @@ package body Exp_Ch4 is
Loc : constant Source_Ptr := Sloc (N);
Typ : constant Entity_Id := Etype (N);
Pool : constant Entity_Id := Associated_Storage_Pool (Typ);
- Pnod : constant Node_Id := Parent (N);
+ Pnod : Node_Id := Parent (N);
function Is_Checked_Storage_Pool (P : Entity_Id) return Boolean;
-- Return true if type of P is derived from Checked_Pool;
@@ -6572,6 +6578,25 @@ package body Exp_Ch4 is
return;
end if;
+ -- Do not generate a dereference check for the object passed
+ -- to an init proc: such a check is not desired (we know for
+ -- sure that a valid dereference is passed to init procs,
+ -- and the calls to 'Size and 'Alignment containent in the
+ -- dereference check would be erroneous anyway if the init proc
+ -- has not been executed yet.)
+
+ while Present (Pnod) loop
+ if Nkind (Pnod) = N_Procedure_Call_Statement
+ and then Is_Entity_Name (Name (Pnod))
+ and then Is_Init_Proc (Name (Pnod))
+ then
+ return;
+ end if;
+
+ Pnod := Parent (Pnod);
+ exit when Nkind (Pnod) not in N_Subexpr;
+ end loop;
+
Insert_Action (N,
Make_Procedure_Call_Statement (Loc,
Name => New_Reference_To (
diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb
index 08ec7d507b5..4a08a28477b 100644
--- a/gcc/ada/exp_ch5.adb
+++ b/gcc/ada/exp_ch5.adb
@@ -702,13 +702,9 @@ package body Exp_Ch5 is
Duplicate_Subexpr (Right_Lo, Name_Req => True),
Duplicate_Subexpr (Right_Hi, Name_Req => True));
- if Forwards_OK (N) then
- Append_To (Actuals,
- New_Occurrence_Of (Standard_False, Loc));
- else
- Append_To (Actuals,
- New_Occurrence_Of (Standard_True, Loc));
- end if;
+ Append_To (Actuals,
+ New_Occurrence_Of (
+ Boolean_Literals (not Forwards_OK (N)), Loc));
Rewrite (N,
Make_Procedure_Call_Statement (Loc,
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index 1bfb5c1c86d..c9d59c22d49 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -1626,9 +1626,8 @@ package body Exp_Ch6 is
Get_Remotely_Callable
(Duplicate_Subexpr_Move_Checks (Actual))),
Then_Statements => New_List (
- Make_Procedure_Call_Statement (Loc,
- New_Occurrence_Of (RTE
- (RE_Raise_Program_Error_For_E_4_18), Loc)))));
+ Make_Raise_Program_Error (Loc,
+ Reason => PE_Illegal_RACW_E_4_18))));
end if;
Next_Actual (Actual);
@@ -2459,18 +2458,19 @@ package body Exp_Ch6 is
declare
Original_Assignment : constant Node_Id := Parent (N);
- Saved_Assignment : constant Node_Id :=
- Relocate_Node (Original_Assignment);
- pragma Warnings (Off, Saved_Assignment);
+
+ begin
-- Preserve the original assignment node to keep the
-- complete assignment subtree consistent enough for
- -- Analyze_Assignment to proceed. We do not use the
- -- saved value, the point was just to do the relocation.
+ -- Analyze_Assignment to proceed (specifically, the
+ -- original Lhs node must still have an assignment
+ -- statement as its parent).
+
-- We cannot rely on Original_Node to go back from the
-- block node to the assignment node, because the
-- assignment might already be a rewrite substitution.
- begin
+ Discard_Node (Relocate_Node (Original_Assignment));
Rewrite (Original_Assignment, Blk);
end;
@@ -2766,11 +2766,16 @@ package body Exp_Ch6 is
----------------------------
procedure Expand_N_Function_Call (N : Node_Id) is
- Typ : constant Entity_Id := Etype (N);
+ Typ : constant Entity_Id := Etype (N);
function Returned_By_Reference return Boolean;
-- If the return type is returned through the secondary stack. that is
-- by reference, we don't want to create a temp to force stack checking.
+ -- Shouldn't this function be moved to exp_util???
+
+ ---------------------------
+ -- Returned_By_Reference --
+ ---------------------------
function Returned_By_Reference return Boolean is
S : Entity_Id := Current_Scope;
@@ -2816,68 +2821,84 @@ package body Exp_Ch6 is
or else Expression (Parent (N)) /= N)
and then not Returned_By_Reference
then
- -- Note: it might be thought that it would be OK to use a call to
- -- Force_Evaluation here, but that's not good enough, because that
- -- results in a 'Reference construct that may still need a temporary.
+ if Stack_Checking_Enabled then
- declare
- Loc : constant Source_Ptr := Sloc (N);
- Temp_Obj : constant Entity_Id :=
- Make_Defining_Identifier (Loc,
- Chars => New_Internal_Name ('F'));
- Temp_Typ : Entity_Id := Typ;
- Decl : Node_Id;
- A : Node_Id;
- F : Entity_Id;
- Proc : Entity_Id;
+ -- Note: it might be thought that it would be OK to use a call
+ -- to Force_Evaluation here, but that's not good enough, because
+ -- that can results in a 'Reference construct that may still
+ -- need a temporary.
- begin
- if Is_Tagged_Type (Typ)
- and then Present (Controlling_Argument (N))
- then
- if Nkind (Parent (N)) /= N_Procedure_Call_Statement
- and then Nkind (Parent (N)) /= N_Function_Call
+ declare
+ Loc : constant Source_Ptr := Sloc (N);
+ Temp_Obj : constant Entity_Id :=
+ Make_Defining_Identifier (Loc,
+ Chars => New_Internal_Name ('F'));
+ Temp_Typ : Entity_Id := Typ;
+ Decl : Node_Id;
+ A : Node_Id;
+ F : Entity_Id;
+ Proc : Entity_Id;
+
+ begin
+ if Is_Tagged_Type (Typ)
+ and then Present (Controlling_Argument (N))
then
- -- If this is a tag-indeterminate call, the object must
- -- be classwide.
+ if Nkind (Parent (N)) /= N_Procedure_Call_Statement
+ and then Nkind (Parent (N)) /= N_Function_Call
+ then
+ -- If this is a tag-indeterminate call, the object must
+ -- be classwide.
- if Is_Tag_Indeterminate (N) then
- Temp_Typ := Class_Wide_Type (Typ);
- end if;
+ if Is_Tag_Indeterminate (N) then
+ Temp_Typ := Class_Wide_Type (Typ);
+ end if;
- else
- -- If this is a dispatching call that is itself the
- -- controlling argument of an enclosing call, the nominal
- -- subtype of the object that replaces it must be classwide,
- -- so that dispatching will take place properly. If it is
- -- not a controlling argument, the object is not classwide.
-
- Proc := Entity (Name (Parent (N)));
- F := First_Formal (Proc);
- A := First_Actual (Parent (N));
-
- while A /= N loop
- Next_Formal (F);
- Next_Actual (A);
- end loop;
+ else
+ -- If this is a dispatching call that is itself the
+ -- controlling argument of an enclosing call, the
+ -- nominal subtype of the object that replaces it must
+ -- be classwide, so that dispatching will take place
+ -- properly. If it is not a controlling argument, the
+ -- object is not classwide.
+
+ Proc := Entity (Name (Parent (N)));
+ F := First_Formal (Proc);
+ A := First_Actual (Parent (N));
+
+ while A /= N loop
+ Next_Formal (F);
+ Next_Actual (A);
+ end loop;
- if Is_Controlling_Formal (F) then
- Temp_Typ := Class_Wide_Type (Typ);
+ if Is_Controlling_Formal (F) then
+ Temp_Typ := Class_Wide_Type (Typ);
+ end if;
end if;
end if;
- end if;
- Decl :=
- Make_Object_Declaration (Loc,
- Defining_Identifier => Temp_Obj,
- Object_Definition => New_Occurrence_Of (Temp_Typ, Loc),
- Constant_Present => True,
- Expression => Relocate_Node (N));
- Set_Assignment_OK (Decl);
-
- Insert_Actions (N, New_List (Decl));
- Rewrite (N, New_Occurrence_Of (Temp_Obj, Loc));
- end;
+ Decl :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Temp_Obj,
+ Object_Definition => New_Occurrence_Of (Temp_Typ, Loc),
+ Constant_Present => True,
+ Expression => Relocate_Node (N));
+ Set_Assignment_OK (Decl);
+
+ Insert_Actions (N, New_List (Decl));
+ Rewrite (N, New_Occurrence_Of (Temp_Obj, Loc));
+ end;
+
+ else
+ -- If stack-checking is not enabled, increment serial number
+ -- for internal names, so that subsequent symbols are consistent
+ -- with and without stack-checking.
+
+ Synchronize_Serial_Number;
+
+ -- Now we can expand the call with consistent symbol names
+
+ Expand_Call (N);
+ end if;
-- Normal case, expand the call
diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
index e78d9954082..426658564e2 100644
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -37,10 +37,8 @@ with Exp_Ch11; use Exp_Ch11;
with Exp_Dbug; use Exp_Dbug;
with Exp_Tss; use Exp_Tss;
with Exp_Util; use Exp_Util;
-with Fname; use Fname;
with Freeze; use Freeze;
with Hostparm; use Hostparm;
-with Lib; use Lib;
with Nlists; use Nlists;
with Nmake; use Nmake;
with Opt; use Opt;
@@ -708,6 +706,7 @@ package body Exp_Ch7 is
or else Ekind (E) = E_Constant)
and then Has_Simple_Protected_Object (Etype (E))
and then not Has_Task (Etype (E))
+ and then Nkind (Parent (E)) /= N_Object_Renaming_Declaration
then
declare
Typ : constant Entity_Id := Etype (E);
@@ -818,28 +817,16 @@ package body Exp_Ch7 is
begin
if Is_Derived_Type (Typ)
and then Comes_From_Source (E)
- and then Is_Overriding_Operation (E)
- and then
- (not Is_Predefined_File_Name
- (Unit_File_Name (Get_Source_Unit (Root_Type (Typ)))))
+ and then not Is_Overriding_Operation (E)
then
- -- We know that the explicit operation on the type overrode
+ -- We know that the explicit operation on the type does not override
-- the inherited operation of the parent, and that the derivation
-- is from a private type that is not visibly controlled.
Parent_Type := Etype (Typ);
Op := Find_Prim_Op (Parent_Type, Name_Of (Prim));
- if Present (Op)
- and then Is_Hidden (Op)
- and then Scope (Scope (Typ)) /= Scope (Op)
- and then not In_Open_Scopes (Scope (Typ))
- then
- -- If the parent operation is not visible, and the derived
- -- type is not declared in a child unit, then the explicit
- -- operation does not override, and we must use the operation
- -- of the parent.
-
+ if Present (Op) then
E := Op;
-- Wrap the object to be initialized into the proper
diff --git a/gcc/ada/exp_ch9.adb b/gcc/ada/exp_ch9.adb
index f60980ac25f..d8c43df42ad 100644
--- a/gcc/ada/exp_ch9.adb
+++ b/gcc/ada/exp_ch9.adb
@@ -3282,10 +3282,11 @@ package body Exp_Ch9 is
Defining_Identifier => D_T2,
Type_Definition => Def1);
+ Analyze (Decl1);
Insert_After (N, Decl1);
-- Create Equivalent_Type, a record with two components for an
- -- an access to object an an access to subprogram.
+ -- access to object and an access to subprogram.
Comps := New_List (
Make_Component_Declaration (Loc,
@@ -3314,6 +3315,7 @@ package body Exp_Ch9 is
Make_Component_List (Loc,
Component_Items => Comps)));
+ Analyze (Decl2);
Insert_After (Decl1, Decl2);
Set_Equivalent_Type (T, E_T);
end Expand_Access_Protected_Subprogram_Type;
@@ -3411,7 +3413,7 @@ package body Exp_Ch9 is
-- It is not a boolean variable or literal, so check the restriction
- Check_Restriction (Boolean_Entry_Barriers, Cond);
+ Check_Restriction (Simple_Barriers, Cond);
end Expand_Entry_Barrier;
------------------------------------
@@ -5733,19 +5735,16 @@ package body Exp_Ch9 is
RTS_Call : Entity_Id;
begin
- if Abort_Present (N) then
- Abortable := New_Occurrence_Of (Standard_True, Loc);
- else
- Abortable := New_Occurrence_Of (Standard_False, Loc);
- end if;
+ Abortable :=
+ New_Occurrence_Of (Boolean_Literals (Abort_Present (N)), Loc);
- -- Set up the target object.
+ -- Set up the target object
Extract_Entry (N, Concval, Ename, Index);
Conctyp := Etype (Concval);
New_Param := Concurrent_Ref (Concval);
- -- The target entry index and abortable flag are the same for all cases.
+ -- The target entry index and abortable flag are the same for all cases
Params := New_List (
Entry_Index_Expression (Loc, Entity (Ename), Index, Conctyp),
@@ -5802,7 +5801,7 @@ package body Exp_Ch9 is
end if;
end loop;
- -- Create the GNARLI call.
+ -- Create the GNARLI call
Rcall := Make_Procedure_Call_Statement (Loc,
Name =>
diff --git a/gcc/ada/exp_dbug.adb b/gcc/ada/exp_dbug.adb
index aa47c00153b..be3eee56af7 100644
--- a/gcc/ada/exp_dbug.adb
+++ b/gcc/ada/exp_dbug.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1996-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 1996-2004 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- --
@@ -913,12 +913,7 @@ package body Exp_Dbug is
-- If we exit the loop then suffix must be output
- if No_Dollar_In_Label then
- Add_Str_To_Name_Buffer ("__");
- else
- Add_Char_To_Name_Buffer ('$');
- end if;
-
+ Add_Str_To_Name_Buffer ("__");
Add_Str_To_Name_Buffer (Homonym_Numbers (1 .. Homonym_Len));
Homonym_Len := 0;
end if;
@@ -1310,54 +1305,28 @@ package body Exp_Dbug is
-- Search for and strip homonym numbers suffix
- -- Case of __ used for homonym numbers suffix
-
- if No_Dollar_In_Label then
- for J in reverse 2 .. Name_Len - 2 loop
- if Name_Buffer (J) = '_'
- and then Name_Buffer (J + 1) = '_'
- then
- if Name_Buffer (J + 2) in '0' .. '9' then
- if Homonym_Len > 0 then
- Homonym_Len := Homonym_Len + 1;
- Homonym_Numbers (Homonym_Len) := '-';
- end if;
-
- SL := Name_Len - (J + 1);
-
- Homonym_Numbers (Homonym_Len + 1 .. Homonym_Len + SL) :=
- Name_Buffer (J + 2 .. Name_Len);
- Name_Len := J - 1;
- Homonym_Len := Homonym_Len + SL;
+ for J in reverse 2 .. Name_Len - 2 loop
+ if Name_Buffer (J) = '_'
+ and then Name_Buffer (J + 1) = '_'
+ then
+ if Name_Buffer (J + 2) in '0' .. '9' then
+ if Homonym_Len > 0 then
+ Homonym_Len := Homonym_Len + 1;
+ Homonym_Numbers (Homonym_Len) := '-';
end if;
- exit;
- end if;
- end loop;
-
- -- Case of $ used for homonym numbers suffix
-
- else
- for J in reverse 2 .. Name_Len - 1 loop
- if Name_Buffer (J) = '$' then
- if Name_Buffer (J + 1) in '0' .. '9' then
- if Homonym_Len > 0 then
- Homonym_Len := Homonym_Len + 1;
- Homonym_Numbers (Homonym_Len) := '-';
- end if;
+ SL := Name_Len - (J + 1);
- SL := Name_Len - J;
+ Homonym_Numbers (Homonym_Len + 1 .. Homonym_Len + SL) :=
+ Name_Buffer (J + 2 .. Name_Len);
+ Name_Len := J - 1;
+ Homonym_Len := Homonym_Len + SL;
+ end if;
- Homonym_Numbers (Homonym_Len + 1 .. Homonym_Len + SL) :=
- Name_Buffer (J + 1 .. Name_Len);
- Name_Len := J - 1;
- Homonym_Len := Homonym_Len + SL;
- end if;
+ exit;
+ end if;
+ end loop;
- exit;
- end if;
- end loop;
- end if;
end Strip_Suffixes;
end Exp_Dbug;
diff --git a/gcc/ada/exp_disp.adb b/gcc/ada/exp_disp.adb
index 0d203b6d289..fb8f6be31e0 100644
--- a/gcc/ada/exp_disp.adb
+++ b/gcc/ada/exp_disp.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -876,24 +876,22 @@ package body Exp_Disp is
Node2 => Position)));
end;
- -- Generate: Set_Remotely_Callable (DT_Ptr, status);
- -- where status is described in E.4 (18)
+ -- Generate: Set_Remotely_Callable (DT_Ptr, Status);
+ -- where Status is described in E.4 (18)
declare
Status : Entity_Id;
begin
- if Is_Pure (Typ)
- or else Is_Shared_Passive (Typ)
- or else
- ((Is_Remote_Types (Typ) or else Is_Remote_Call_Interface (Typ))
- and then Original_View_In_Visible_Part (Typ))
- or else not Comes_From_Source (Typ)
- then
- Status := Standard_True;
- else
- Status := Standard_False;
- end if;
+ Status :=
+ Boolean_Literals
+ (Is_Pure (Typ)
+ or else Is_Shared_Passive (Typ)
+ or else
+ ((Is_Remote_Types (Typ)
+ or else Is_Remote_Call_Interface (Typ))
+ and then Original_View_In_Visible_Part (Typ))
+ or else not Comes_From_Source (Typ));
Append_To (Elab_Code,
Make_DT_Access_Action (Typ,
diff --git a/gcc/ada/exp_dist.adb b/gcc/ada/exp_dist.adb
index 4204cac71f9..6b4ced731c9 100644
--- a/gcc/ada/exp_dist.adb
+++ b/gcc/ada/exp_dist.adb
@@ -80,6 +80,10 @@ package body Exp_Dist is
-- Local subprograms --
-----------------------
+ function Get_Subprogram_Id (E : Entity_Id) return Int;
+ -- Given a subprogram defined in a RCI package, get its subprogram id
+ -- which will be used for remote calls.
+
procedure Build_General_Calling_Stubs
(Decls : in List_Id;
Statements : in List_Id;
@@ -1189,75 +1193,122 @@ package body Exp_Dist is
Proc_Decls : constant List_Id := New_List;
Proc_Statements : constant List_Id := New_List;
- Proc_Spec : Node_Id;
-
- Proc : Node_Id;
+ Proc_Spec : Node_Id;
+ Proc : Node_Id;
+ Local_Addr : Entity_Id;
+ Package_Name : Entity_Id;
+ Subp_Id : Entity_Id;
+ Asynch_P : Entity_Id;
+ Origin : Entity_Id;
+ Return_Value : Entity_Id;
- Param : Node_Id;
- Package_Name : Node_Id;
- Subp_Id : Node_Id;
- Asynchronous : Node_Id;
- Return_Value : Node_Id;
+ All_Calls_Remote : Entity_Id;
+ -- True if an All_Calls_Remote pragma applies to the RCI unit
+ -- that contains the subprogram (currently unused, all RAS
+ -- dereferences are handled through the PCS).
Loc : constant Source_Ptr := Sloc (N);
- procedure Set_Field (Field_Name : in Name_Id; Value : in Node_Id);
- -- Set a field name for the return value
+ function Set_Field
+ (Field_Name : Name_Id;
+ Value : Node_Id) return Node_Id;
+ -- Construct an assignment that sets the named component in the
+ -- returned record
- procedure Set_Field (Field_Name : in Name_Id; Value : in Node_Id)
+ ---------------
+ -- Set_Field --
+ ---------------
+
+ function Set_Field
+ (Field_Name : Name_Id;
+ Value : Node_Id) return Node_Id
is
begin
- Append_To (Proc_Statements,
+ return
Make_Assignment_Statement (Loc,
Name =>
Make_Selected_Component (Loc,
Prefix => New_Occurrence_Of (Return_Value, Loc),
Selector_Name => Make_Identifier (Loc, Field_Name)),
- Expression => Value));
+ Expression => Value);
end Set_Field;
-- Start of processing for Add_RAS_Access_Attribute
begin
- Param := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
- Package_Name := Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
- Subp_Id := Make_Defining_Identifier (Loc, New_Internal_Name ('N'));
- Asynchronous := Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
- Return_Value := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
+ Local_Addr := Make_Defining_Identifier (Loc, New_Internal_Name ('L'));
+ Package_Name := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
+ Subp_Id := Make_Defining_Identifier (Loc, New_Internal_Name ('N'));
+ Asynch_P := Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
+ Origin := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
+ Return_Value := Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
+ All_Calls_Remote :=
+ Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
-- Create the object which will be returned of type Fat_Type
- Append_To (Proc_Decls,
+ Append_List_To (Proc_Decls, New_List (
+
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Origin,
+ Constant_Present => True,
+ Object_Definition =>
+ New_Occurrence_Of (RTE (RE_Partition_ID), Loc),
+ Expression =>
+ Make_Function_Call (Loc,
+ Name =>
+ New_Occurrence_Of (RTE (RE_Get_Active_Partition_Id), Loc),
+ Parameter_Associations => New_List (
+ New_Occurrence_Of (Package_Name, Loc)))),
+
Make_Object_Declaration (Loc,
Defining_Identifier => Return_Value,
Object_Definition =>
- New_Occurrence_Of (Fat_Type, Loc)));
+ New_Occurrence_Of (Fat_Type, Loc))));
-- Initialize the fields of the record type with the appropriate data
- Set_Field (Name_Ras,
- OK_Convert_To (RTE (RE_Unsigned_64), New_Occurrence_Of (Param, Loc)));
+ Append_List_To (Proc_Statements, New_List (
+ Make_Implicit_If_Statement (N,
+ Condition =>
+ Make_And_Then (Loc,
+ Left_Opnd =>
+ Make_Op_Not (Loc,
+ New_Occurrence_Of (All_Calls_Remote, Loc)),
+ Right_Opnd =>
+ Make_Op_Eq (Loc,
+ Left_Opnd =>
+ New_Occurrence_Of (Origin, Loc),
+ Right_Opnd =>
+ Make_Function_Call (Loc,
+ New_Occurrence_Of (
+ RTE (RE_Get_Local_Partition_Id), Loc)))),
+
+ Then_Statements => New_List (
+ Set_Field (Name_Ras,
+ OK_Convert_To (RTE (RE_Unsigned_64),
+ New_Occurrence_Of (Local_Addr, Loc)))),
+
+ Else_Statements => New_List (
+ Set_Field (Name_Ras,
+ Make_Integer_Literal (Loc, Uint_0)))),
+
+ Set_Field (Name_Origin,
+ Unchecked_Convert_To (Standard_Integer,
+ New_Occurrence_Of (Origin, Loc))),
- Set_Field (Name_Origin,
- Unchecked_Convert_To (Standard_Integer,
+ Set_Field (Name_Receiver,
Make_Function_Call (Loc,
Name =>
- New_Occurrence_Of (RTE (RE_Get_Active_Partition_Id), Loc),
+ New_Occurrence_Of (RTE (RE_Get_RCI_Package_Receiver), Loc),
Parameter_Associations => New_List (
- New_Occurrence_Of (Package_Name, Loc)))));
-
- Set_Field (Name_Receiver,
- Make_Function_Call (Loc,
- Name =>
- New_Occurrence_Of (RTE (RE_Get_RCI_Package_Receiver), Loc),
- Parameter_Associations => New_List (
- New_Occurrence_Of (Package_Name, Loc))));
+ New_Occurrence_Of (Package_Name, Loc)))),
- Set_Field (Name_Subp_Id,
- New_Occurrence_Of (Subp_Id, Loc));
+ Set_Field (Name_Subp_Id,
+ New_Occurrence_Of (Subp_Id, Loc)),
- Set_Field (Name_Async,
- New_Occurrence_Of (Asynchronous, Loc));
+ Set_Field (Name_Async,
+ New_Occurrence_Of (Asynch_P, Loc))));
-- Return the newly created value
@@ -1275,7 +1326,7 @@ package body Exp_Dist is
Defining_Unit_Name => Proc,
Parameter_Specifications => New_List (
Make_Parameter_Specification (Loc,
- Defining_Identifier => Param,
+ Defining_Identifier => Local_Addr,
Parameter_Type =>
New_Occurrence_Of (RTE (RE_Address), Loc)),
@@ -1290,7 +1341,12 @@ package body Exp_Dist is
New_Occurrence_Of (Standard_Natural, Loc)),
Make_Parameter_Specification (Loc,
- Defining_Identifier => Asynchronous,
+ Defining_Identifier => Asynch_P,
+ Parameter_Type =>
+ New_Occurrence_Of (Standard_Boolean, Loc)),
+
+ Make_Parameter_Specification (Loc,
+ Defining_Identifier => All_Calls_Remote,
Parameter_Type =>
New_Occurrence_Of (Standard_Boolean, Loc))),
@@ -2749,6 +2805,18 @@ package body Exp_Dist is
Make_Handled_Sequence_Of_Statements (Loc, Statements));
end Build_Subprogram_Calling_Stubs;
+ -------------------------
+ -- Build_Subprogram_Id --
+ -------------------------
+
+ function Build_Subprogram_Id
+ (Loc : Source_Ptr;
+ E : Entity_Id) return Node_Id
+ is
+ begin
+ return Make_Integer_Literal (Loc, Get_Subprogram_Id (E));
+ end Build_Subprogram_Id;
+
--------------------------------------
-- Build_Subprogram_Receiving_Stubs --
--------------------------------------
@@ -2789,7 +2857,7 @@ package body Exp_Dist is
Excep_Code : List_Id;
Parameter_List : constant List_Id := New_List;
- -- List of parameters to be passed to the subprogram.
+ -- List of parameters to be passed to the subprogram
Current_Parameter : Node_Id;
@@ -3469,6 +3537,47 @@ package body Exp_Dist is
return End_String;
end Get_String_Id;
+ -----------------------
+ -- Get_Subprogram_Id --
+ -----------------------
+
+ function Get_Subprogram_Id (E : Entity_Id) return Int is
+ Current_Declaration : Node_Id;
+ Result : Int := 0;
+
+ begin
+ pragma Assert
+ (Is_Remote_Call_Interface (Scope (E))
+ and then
+ (Nkind (Parent (E)) = N_Procedure_Specification
+ or else
+ Nkind (Parent (E)) = N_Function_Specification));
+
+ Current_Declaration :=
+ First (Visible_Declarations
+ (Package_Specification_Of_Scope (Scope (E))));
+
+ while Current_Declaration /= Empty loop
+ if Nkind (Current_Declaration) = N_Subprogram_Declaration
+ and then Comes_From_Source (Current_Declaration)
+ then
+ if Defining_Unit_Name
+ (Specification (Current_Declaration)) = E
+ then
+ return Result;
+ end if;
+
+ Result := Result + 1;
+ end if;
+
+ Next (Current_Declaration);
+ end loop;
+
+ -- Error if we do not find it
+
+ raise Program_Error;
+ end Get_Subprogram_Id;
+
----------
-- Hash --
----------
diff --git a/gcc/ada/exp_dist.ads b/gcc/ada/exp_dist.ads
index 648803c70b8..10cbc60bdb4 100644
--- a/gcc/ada/exp_dist.ads
+++ b/gcc/ada/exp_dist.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-1998 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -78,4 +78,9 @@ package Exp_Dist is
-- Build stub for a shared passive package. U is the analyzed
-- compilation unit for a package declaration.
+ function Build_Subprogram_Id
+ (Loc : Source_Ptr;
+ E : Entity_Id) return Node_Id;
+ -- Build a literal representing the remote subprogram identifier of E
+
end Exp_Dist;
diff --git a/gcc/ada/exp_fixd.adb b/gcc/ada/exp_fixd.adb
index 41158104beb..75357a2f3ab 100644
--- a/gcc/ada/exp_fixd.adb
+++ b/gcc/ada/exp_fixd.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2002 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -561,11 +561,7 @@ package body Exp_Fixd is
-- call the runtime routine to compute the quotient and remainder
else
- if Rounded_Result_Set (N) then
- Rnd := Standard_True;
- else
- Rnd := Standard_False;
- end if;
+ Rnd := Boolean_Literals (Rounded_Result_Set (N));
Code := New_List (
Make_Object_Declaration (Loc,
@@ -947,11 +943,7 @@ package body Exp_Fixd is
-- call the runtime routine to compute the quotient and remainder
else
- if Rounded_Result_Set (N) then
- Rnd := Standard_True;
- else
- Rnd := Standard_False;
- end if;
+ Rnd := Boolean_Literals (Rounded_Result_Set (N));
Code := New_List (
Make_Object_Declaration (Loc,
diff --git a/gcc/ada/exp_intr.adb b/gcc/ada/exp_intr.adb
index f6889090645..9fe40522970 100644
--- a/gcc/ada/exp_intr.adb
+++ b/gcc/ada/exp_intr.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -214,7 +214,7 @@ package body Exp_Intr is
Nam : Name_Id;
begin
- -- If the intrinsic subprogram is generic, gets its original name.
+ -- If the intrinsic subprogram is generic, gets its original name
if Present (Parent (E))
and then Present (Generic_Parent (Parent (E)))
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index d79ec31e527..e38bcce3baf 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -3056,10 +3056,7 @@ package body Exp_Util is
function May_Generate_Large_Temp (Typ : Entity_Id) return Boolean is
begin
- if not Stack_Checking_Enabled then
- return False;
-
- elsif not Size_Known_At_Compile_Time (Typ) then
+ if not Size_Known_At_Compile_Time (Typ) then
return False;
elsif Esize (Typ) /= 0 and then Esize (Typ) <= 256 then
@@ -3785,7 +3782,9 @@ package body Exp_Util is
-- in stack checking mode.
elsif Size_Known_At_Compile_Time (Otyp)
- and then not May_Generate_Large_Temp (Otyp)
+ and then
+ (not Stack_Checking_Enabled
+ or else not May_Generate_Large_Temp (Otyp))
and then not (Is_Record_Type (Otyp) and then not Is_Constrained (Otyp))
then
return True;
diff --git a/gcc/ada/exp_util.ads b/gcc/ada/exp_util.ads
index 62568f513a1..2382207831b 100644
--- a/gcc/ada/exp_util.ads
+++ b/gcc/ada/exp_util.ads
@@ -490,12 +490,13 @@ package Exp_Util is
function May_Generate_Large_Temp (Typ : Entity_Id) return Boolean;
-- Determines if the given type, Typ, may require a large temporary
- -- of the type that causes trouble if stack checking is enabled. The
- -- result is True only if stack checking is enabled and the size of
- -- the type is known at compile time and large, where large is defined
- -- hueristically by the body of this routine. The purpose of this
- -- routine is to help avoid generating troublesome temporaries that
- -- intefere with the stack checking mechanism.
+ -- of the kind that causes back-end trouble if stack checking is enabled.
+ -- The result is True only the size of the type is known at compile time
+ -- and large, where large is defined heuristically by the body of this
+ -- routine. The purpose of this routine is to help avoid generating
+ -- troublesome temporaries that interfere with stack checking mechanism.
+ -- Note that the caller has to check whether stack checking is actually
+ -- enabled in order to guide the expansion (typically of a function call).
procedure Remove_Side_Effects
(Exp : Node_Id;
@@ -505,14 +506,14 @@ package Exp_Util is
-- if necessary by an equivalent subexpression that is guaranteed to be
-- side effect free. This is done by extracting any actions that could
-- cause side effects, and inserting them using Insert_Actions into the
- -- tree to which Exp is attached. Exp must be analayzed and resolved
+ -- tree to which Exp is attached. Exp must be analyzed and resolved
-- before the call and is analyzed and resolved on return. The Name_Req
-- may only be set to True if Exp has the form of a name, and the
-- effect is to guarantee that any replacement maintains the form of a
-- name. If Variable_Ref is set to TRUE, a variable is considered as a
-- side effect (used in implementing Force_Evaluation). Note: after a
- -- call to Remove_Side_Effects, it is safe to use a call to
- -- New_Copy_Tree to obtain a copy of the resulting expression.
+ -- call to Remove_Side_Effects, it is safe to call New_Copy_Tree to
+ -- obtain a copy of the resulting expression.
function Safe_Unchecked_Type_Conversion (Exp : Node_Id) return Boolean;
-- Given the node for an N_Unchecked_Type_Conversion, return True
diff --git a/gcc/ada/frontend.adb b/gcc/ada/frontend.adb
index f4f36f56aaf..35645bd0812 100644
--- a/gcc/ada/frontend.adb
+++ b/gcc/ada/frontend.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -124,10 +124,12 @@ begin
begin
-- We always analyze config files with style checks off, since
-- we don't want a miscellaneous gnat.adc that is around to
- -- discombobulate intended -gnatg or -gnaty compilations.
+ -- discombobulate intended -gnatg or -gnaty compilations. We
+ -- also disconnect checking for maximum line length.
Opt.Style_Check := False;
Style_Check := False;
+ Opt.Max_Line_Length := Int (Column_Number'Last);
-- Capture current suppress options, which may get modified
@@ -191,6 +193,7 @@ begin
-- Restore style check, but if config file turned on checks, leave on!
Opt.Style_Check := Save_Style_Check or Style_Check;
+ Opt.Max_Line_Length := Hostparm.Max_Line_Length;
-- Capture any modifications to suppress options from config pragmas
diff --git a/gcc/ada/g-debpoo.adb b/gcc/ada/g-debpoo.adb
index 4eeae1af222..4d93310db2f 100644
--- a/gcc/ada/g-debpoo.adb
+++ b/gcc/ada/g-debpoo.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -769,6 +769,11 @@ package body GNAT.Debug_Pools is
end if;
Unlock_Task.all;
+
+ exception
+ when others =>
+ Unlock_Task.all;
+ raise;
end Allocate;
------------------
@@ -1056,6 +1061,11 @@ package body GNAT.Debug_Pools is
end if;
Unlock_Task.all;
+
+ exception
+ when others =>
+ Unlock_Task.all;
+ raise;
end Free_Physically;
----------------
@@ -1166,6 +1176,11 @@ package body GNAT.Debug_Pools is
Unlock_Task.all;
end if;
+
+ exception
+ when others =>
+ Unlock_Task.all;
+ raise;
end Deallocate;
--------------------
@@ -1310,71 +1325,71 @@ package body GNAT.Debug_Pools is
Put_Line ("");
- Data := Backtrace_Htable.Get_First;
- while Data /= null loop
- if Data.Kind in Alloc .. Dealloc then
- Elem :=
- new Traceback_Htable_Elem'
- (Traceback => new Tracebacks_Array'(Data.Traceback.all),
- Count => Data.Count,
- Kind => Data.Kind,
- Total => Data.Total,
- Next => null);
- Backtrace_Htable_Cumulate.Set (Elem);
-
- if Cumulate then
- if Data.Kind = Alloc then
- K := Indirect_Alloc;
- else
- K := Indirect_Dealloc;
- end if;
+ if Display_Slots then
+ Data := Backtrace_Htable.Get_First;
+ while Data /= null loop
+ if Data.Kind in Alloc .. Dealloc then
+ Elem :=
+ new Traceback_Htable_Elem'
+ (Traceback => new Tracebacks_Array'(Data.Traceback.all),
+ Count => Data.Count,
+ Kind => Data.Kind,
+ Total => Data.Total,
+ Next => null);
+ Backtrace_Htable_Cumulate.Set (Elem);
+
+ if Cumulate then
+ if Data.Kind = Alloc then
+ K := Indirect_Alloc;
+ else
+ K := Indirect_Dealloc;
+ end if;
- -- Propagate the direct call to all its parents
+ -- Propagate the direct call to all its parents
- for T in Data.Traceback'First + 1 .. Data.Traceback'Last loop
- Elem := Backtrace_Htable_Cumulate.Get
- (Data.Traceback
- (T .. Data.Traceback'Last)'Unrestricted_Access);
+ for T in Data.Traceback'First + 1 .. Data.Traceback'Last loop
+ Elem := Backtrace_Htable_Cumulate.Get
+ (Data.Traceback
+ (T .. Data.Traceback'Last)'Unrestricted_Access);
- -- If not, insert it
+ -- If not, insert it
- if Elem = null then
- Elem := new Traceback_Htable_Elem'
- (Traceback => new Tracebacks_Array'
- (Data.Traceback (T .. Data.Traceback'Last)),
- Count => Data.Count,
- Kind => K,
- Total => Data.Total,
- Next => null);
- Backtrace_Htable_Cumulate.Set (Elem);
+ if Elem = null then
+ Elem := new Traceback_Htable_Elem'
+ (Traceback => new Tracebacks_Array'
+ (Data.Traceback (T .. Data.Traceback'Last)),
+ Count => Data.Count,
+ Kind => K,
+ Total => Data.Total,
+ Next => null);
+ Backtrace_Htable_Cumulate.Set (Elem);
- -- Properly take into account that the subprograms
- -- indirectly called might be doing either allocations
- -- or deallocations. This needs to be reflected in the
- -- counts.
+ -- Properly take into account that the subprograms
+ -- indirectly called might be doing either allocations
+ -- or deallocations. This needs to be reflected in the
+ -- counts.
- else
- Elem.Count := Elem.Count + Data.Count;
+ else
+ Elem.Count := Elem.Count + Data.Count;
- if K = Elem.Kind then
- Elem.Total := Elem.Total + Data.Total;
+ if K = Elem.Kind then
+ Elem.Total := Elem.Total + Data.Total;
- elsif Elem.Total > Data.Total then
- Elem.Total := Elem.Total - Data.Total;
+ elsif Elem.Total > Data.Total then
+ Elem.Total := Elem.Total - Data.Total;
- else
- Elem.Kind := K;
- Elem.Total := Data.Total - Elem.Total;
+ else
+ Elem.Kind := K;
+ Elem.Total := Data.Total - Elem.Total;
+ end if;
end if;
- end if;
- end loop;
- end if;
+ end loop;
+ end if;
- Data := Backtrace_Htable.Get_Next;
- end if;
- end loop;
+ Data := Backtrace_Htable.Get_Next;
+ end if;
+ end loop;
- if Display_Slots then
Put_Line ("List of allocations/deallocations: ");
Data := Backtrace_Htable_Cumulate.Get_First;
@@ -1397,6 +1412,8 @@ package body GNAT.Debug_Pools is
Data := Backtrace_Htable_Cumulate.Get_Next;
end loop;
+
+ Backtrace_Htable_Cumulate.Reset;
end if;
if Display_Leaks then
@@ -1421,8 +1438,6 @@ package body GNAT.Debug_Pools is
Current := Header.Next;
end loop;
end if;
-
- Backtrace_Htable_Cumulate.Reset;
end Print_Info;
------------------
diff --git a/gcc/ada/g-eacodu-vms.adb b/gcc/ada/g-eacodu-vms.adb
new file mode 100644
index 00000000000..2c31a28e299
--- /dev/null
+++ b/gcc/ada/g-eacodu-vms.adb
@@ -0,0 +1,73 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . E X C E P T I O N _ A C T I O N S . C O R E _ D U M P --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the VMS version.
+
+with System;
+with System.Aux_DEC;
+separate (GNAT.Exception_Actions)
+procedure Core_Dump (Occurrence : Exception_Occurrence) is
+
+ use System;
+ use System.Aux_DEC;
+
+ pragma Unreferenced (Occurrence);
+
+ SS_IMGDMP : constant := 1276;
+
+ subtype Cond_Value_Type is Unsigned_Longword;
+ subtype Access_Mode_Type is
+ Unsigned_Word range 0 .. 3;
+ Access_Mode_Zero : constant Access_Mode_Type := 0;
+
+ Status : Cond_Value_Type;
+
+ procedure Setexv (
+ Status : out Cond_Value_Type;
+ Vector : in Unsigned_Longword := 0;
+ Addres : in Address := Address_Zero;
+ Acmode : in Access_Mode_Type := Access_Mode_Zero;
+ Prvhnd : in Unsigned_Longword := 0);
+ pragma Interface (External, Setexv);
+ pragma Import_Valued_Procedure (Setexv, "SYS$SETEXV",
+ (Cond_Value_Type, Unsigned_Longword, Address, Access_Mode_Type,
+ Unsigned_Longword),
+ (Value, Value, Value, Value, Value));
+
+ procedure Lib_Signal (I : in Integer);
+ pragma Interface (C, Lib_Signal);
+ pragma Import_Procedure (Lib_Signal, "LIB$SIGNAL", Mechanism => (Value));
+begin
+ Setexv (Status, 1, Address_Zero, 3);
+ Lib_Signal (SS_IMGDMP);
+end Core_Dump;
diff --git a/gcc/ada/g-expect-vms.adb b/gcc/ada/g-expect-vms.adb
new file mode 100644
index 00000000000..1f18885c813
--- /dev/null
+++ b/gcc/ada/g-expect-vms.adb
@@ -0,0 +1,1184 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT LIBRARY COMPONENTS --
+-- --
+-- G N A T . E X P E C T --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2002-2003 Ada Core Technologies, 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the VMS version.
+
+with System; use System;
+with Ada.Calendar; use Ada.Calendar;
+
+with GNAT.IO;
+with GNAT.OS_Lib; use GNAT.OS_Lib;
+with GNAT.Regpat; use GNAT.Regpat;
+
+with Unchecked_Deallocation;
+
+package body GNAT.Expect is
+
+ type Array_Of_Pd is array (Positive range <>) of Process_Descriptor_Access;
+
+ Save_Input : File_Descriptor;
+ Save_Output : File_Descriptor;
+ Save_Error : File_Descriptor;
+
+ procedure Expect_Internal
+ (Descriptors : in out Array_Of_Pd;
+ Result : out Expect_Match;
+ Timeout : Integer;
+ Full_Buffer : Boolean);
+ -- Internal function used to read from the process Descriptor.
+ --
+ -- Three outputs are possible:
+ -- Result=Expect_Timeout, if no output was available before the timeout
+ -- expired.
+ -- Result=Expect_Full_Buffer, if Full_Buffer is True and some characters
+ -- had to be discarded from the internal buffer of Descriptor.
+ -- Result=<integer>, indicates how many characters were added to the
+ -- internal buffer. These characters are from indexes
+ -- Descriptor.Buffer_Index - Result + 1 .. Descriptor.Buffer_Index
+ -- Process_Died is raised if the process is no longer valid.
+
+ procedure Reinitialize_Buffer
+ (Descriptor : in out Process_Descriptor'Class);
+ -- Reinitialize the internal buffer.
+ -- The buffer is deleted up to the end of the last match.
+
+ procedure Free is new Unchecked_Deallocation
+ (Pattern_Matcher, Pattern_Matcher_Access);
+
+ procedure Call_Filters
+ (Pid : Process_Descriptor'Class;
+ Str : String;
+ Filter_On : Filter_Type);
+ -- Call all the filters that have the appropriate type.
+ -- This function does nothing if the filters are locked
+
+ ------------------------------
+ -- Target dependent section --
+ ------------------------------
+
+ function Dup (Fd : File_Descriptor) return File_Descriptor;
+ pragma Import (C, Dup);
+
+ procedure Dup2 (Old_Fd, New_Fd : File_Descriptor);
+ pragma Import (C, Dup2);
+
+ procedure Kill (Pid : Process_Id; Sig_Num : Integer);
+ pragma Import (C, Kill);
+
+ function Create_Pipe (Pipe : access Pipe_Type) return Integer;
+ pragma Import (C, Create_Pipe, "__gnat_pipe");
+
+ function Poll
+ (Fds : System.Address;
+ Num_Fds : Integer;
+ Timeout : Integer;
+ Is_Set : System.Address) return Integer;
+ pragma Import (C, Poll, "__gnat_expect_poll");
+ -- Check whether there is any data waiting on the file descriptor
+ -- Out_fd, and wait if there is none, at most Timeout milliseconds
+ -- Returns -1 in case of error, 0 if the timeout expired before
+ -- data became available.
+ --
+ -- Out_Is_Set is set to 1 if data was available, 0 otherwise.
+
+ function Waitpid (Pid : Process_Id) return Integer;
+ pragma Import (C, Waitpid, "__gnat_waitpid");
+ -- Wait for a specific process id, and return its exit code.
+
+ ---------
+ -- "+" --
+ ---------
+
+ function "+" (S : String) return GNAT.OS_Lib.String_Access is
+ begin
+ return new String'(S);
+ end "+";
+
+ ---------
+ -- "+" --
+ ---------
+
+ function "+"
+ (P : GNAT.Regpat.Pattern_Matcher) return Pattern_Matcher_Access
+ is
+ begin
+ return new GNAT.Regpat.Pattern_Matcher'(P);
+ end "+";
+
+ ----------------
+ -- Add_Filter --
+ ----------------
+
+ procedure Add_Filter
+ (Descriptor : in out Process_Descriptor;
+ Filter : Filter_Function;
+ Filter_On : Filter_Type := Output;
+ User_Data : System.Address := System.Null_Address;
+ After : Boolean := False)
+ is
+ Current : Filter_List := Descriptor.Filters;
+
+ begin
+ if After then
+ while Current /= null and then Current.Next /= null loop
+ Current := Current.Next;
+ end loop;
+
+ if Current = null then
+ Descriptor.Filters :=
+ new Filter_List_Elem'
+ (Filter => Filter, Filter_On => Filter_On,
+ User_Data => User_Data, Next => null);
+ else
+ Current.Next :=
+ new Filter_List_Elem'
+ (Filter => Filter, Filter_On => Filter_On,
+ User_Data => User_Data, Next => null);
+ end if;
+
+ else
+ Descriptor.Filters :=
+ new Filter_List_Elem'
+ (Filter => Filter, Filter_On => Filter_On,
+ User_Data => User_Data, Next => Descriptor.Filters);
+ end if;
+ end Add_Filter;
+
+ ------------------
+ -- Call_Filters --
+ ------------------
+
+ procedure Call_Filters
+ (Pid : Process_Descriptor'Class;
+ Str : String;
+ Filter_On : Filter_Type)
+ is
+ Current_Filter : Filter_List;
+
+ begin
+ if Pid.Filters_Lock = 0 then
+ Current_Filter := Pid.Filters;
+
+ while Current_Filter /= null loop
+ if Current_Filter.Filter_On = Filter_On then
+ Current_Filter.Filter
+ (Pid, Str, Current_Filter.User_Data);
+ end if;
+
+ Current_Filter := Current_Filter.Next;
+ end loop;
+ end if;
+ end Call_Filters;
+
+ -----------
+ -- Close --
+ -----------
+
+ procedure Close
+ (Descriptor : in out Process_Descriptor;
+ Status : out Integer)
+ is
+ begin
+ Close (Descriptor.Input_Fd);
+
+ if Descriptor.Error_Fd /= Descriptor.Output_Fd then
+ Close (Descriptor.Error_Fd);
+ end if;
+
+ Close (Descriptor.Output_Fd);
+
+ -- ??? Should have timeouts for different signals
+ Kill (Descriptor.Pid, 9);
+
+ GNAT.OS_Lib.Free (Descriptor.Buffer);
+ Descriptor.Buffer_Size := 0;
+
+ Status := Waitpid (Descriptor.Pid);
+ end Close;
+
+ procedure Close (Descriptor : in out Process_Descriptor) is
+ Status : Integer;
+ begin
+ Close (Descriptor, Status);
+ end Close;
+
+ ------------
+ -- Expect --
+ ------------
+
+ procedure Expect
+ (Descriptor : in out Process_Descriptor;
+ Result : out Expect_Match;
+ Regexp : String;
+ Timeout : Integer := 10000;
+ Full_Buffer : Boolean := False)
+ is
+ begin
+ if Regexp = "" then
+ Expect (Descriptor, Result, Never_Match, Timeout, Full_Buffer);
+ else
+ Expect (Descriptor, Result, Compile (Regexp), Timeout, Full_Buffer);
+ end if;
+ end Expect;
+
+ procedure Expect
+ (Descriptor : in out Process_Descriptor;
+ Result : out Expect_Match;
+ Regexp : String;
+ Matched : out GNAT.Regpat.Match_Array;
+ Timeout : Integer := 10000;
+ Full_Buffer : Boolean := False)
+ is
+ begin
+ pragma Assert (Matched'First = 0);
+ if Regexp = "" then
+ Expect
+ (Descriptor, Result, Never_Match, Matched, Timeout, Full_Buffer);
+ else
+ Expect
+ (Descriptor, Result, Compile (Regexp), Matched, Timeout,
+ Full_Buffer);
+ end if;
+ end Expect;
+
+ procedure Expect
+ (Descriptor : in out Process_Descriptor;
+ Result : out Expect_Match;
+ Regexp : GNAT.Regpat.Pattern_Matcher;
+ Timeout : Integer := 10000;
+ Full_Buffer : Boolean := False)
+ is
+ Matched : GNAT.Regpat.Match_Array (0 .. 0);
+
+ begin
+ Expect (Descriptor, Result, Regexp, Matched, Timeout, Full_Buffer);
+ end Expect;
+
+ procedure Expect
+ (Descriptor : in out Process_Descriptor;
+ Result : out Expect_Match;
+ Regexp : GNAT.Regpat.Pattern_Matcher;
+ Matched : out GNAT.Regpat.Match_Array;
+ Timeout : Integer := 10000;
+ Full_Buffer : Boolean := False)
+ is
+ N : Expect_Match;
+ Descriptors : Array_Of_Pd := (1 => Descriptor'Unrestricted_Access);
+ Try_Until : constant Time := Clock + Duration (Timeout) / 1000.0;
+ Timeout_Tmp : Integer := Timeout;
+
+ begin
+ pragma Assert (Matched'First = 0);
+ Reinitialize_Buffer (Descriptor);
+
+ loop
+ -- First, test if what is already in the buffer matches (This is
+ -- required if this package is used in multi-task mode, since one of
+ -- the tasks might have added something in the buffer, and we don't
+ -- want other tasks to wait for new input to be available before
+ -- checking the regexps).
+
+ Match
+ (Regexp, Descriptor.Buffer (1 .. Descriptor.Buffer_Index), Matched);
+
+ if Descriptor.Buffer_Index >= 1 and then Matched (0).First /= 0 then
+ Result := 1;
+ Descriptor.Last_Match_Start := Matched (0).First;
+ Descriptor.Last_Match_End := Matched (0).Last;
+ return;
+ end if;
+
+ -- Else try to read new input
+
+ Expect_Internal (Descriptors, N, Timeout_Tmp, Full_Buffer);
+
+ if N = Expect_Timeout or else N = Expect_Full_Buffer then
+ Result := N;
+ return;
+ end if;
+
+ -- Calculate the timeout for the next turn.
+ -- Note that Timeout is, from the caller's perspective, the maximum
+ -- time until a match, not the maximum time until some output is
+ -- read, and thus can not be reused as is for Expect_Internal.
+
+ if Timeout /= -1 then
+ Timeout_Tmp := Integer (Try_Until - Clock) * 1000;
+
+ if Timeout_Tmp < 0 then
+ Result := Expect_Timeout;
+ exit;
+ end if;
+ end if;
+ end loop;
+
+ -- Even if we had the general timeout above, we have to test that the
+ -- last test we read from the external process didn't match.
+
+ Match
+ (Regexp, Descriptor.Buffer (1 .. Descriptor.Buffer_Index), Matched);
+
+ if Matched (0).First /= 0 then
+ Result := 1;
+ Descriptor.Last_Match_Start := Matched (0).First;
+ Descriptor.Last_Match_End := Matched (0).Last;
+ return;
+ end if;
+ end Expect;
+
+ procedure Expect
+ (Descriptor : in out Process_Descriptor;
+ Result : out Expect_Match;
+ Regexps : Regexp_Array;
+ Timeout : Integer := 10000;
+ Full_Buffer : Boolean := False)
+ is
+ Patterns : Compiled_Regexp_Array (Regexps'Range);
+ Matched : GNAT.Regpat.Match_Array (0 .. 0);
+
+ begin
+ for J in Regexps'Range loop
+ Patterns (J) := new Pattern_Matcher'(Compile (Regexps (J).all));
+ end loop;
+
+ Expect (Descriptor, Result, Patterns, Matched, Timeout, Full_Buffer);
+
+ for J in Regexps'Range loop
+ Free (Patterns (J));
+ end loop;
+ end Expect;
+
+ procedure Expect
+ (Descriptor : in out Process_Descriptor;
+ Result : out Expect_Match;
+ Regexps : Compiled_Regexp_Array;
+ Timeout : Integer := 10000;
+ Full_Buffer : Boolean := False)
+ is
+ Matched : GNAT.Regpat.Match_Array (0 .. 0);
+
+ begin
+ Expect (Descriptor, Result, Regexps, Matched, Timeout, Full_Buffer);
+ end Expect;
+
+ procedure Expect
+ (Result : out Expect_Match;
+ Regexps : Multiprocess_Regexp_Array;
+ Timeout : Integer := 10000;
+ Full_Buffer : Boolean := False)
+ is
+ Matched : GNAT.Regpat.Match_Array (0 .. 0);
+
+ begin
+ Expect (Result, Regexps, Matched, Timeout, Full_Buffer);
+ end Expect;
+
+ procedure Expect
+ (Descriptor : in out Process_Descriptor;
+ Result : out Expect_Match;
+ Regexps : Regexp_Array;
+ Matched : out GNAT.Regpat.Match_Array;
+ Timeout : Integer := 10000;
+ Full_Buffer : Boolean := False)
+ is
+ Patterns : Compiled_Regexp_Array (Regexps'Range);
+
+ begin
+ pragma Assert (Matched'First = 0);
+
+ for J in Regexps'Range loop
+ Patterns (J) := new Pattern_Matcher'(Compile (Regexps (J).all));
+ end loop;
+
+ Expect (Descriptor, Result, Patterns, Matched, Timeout, Full_Buffer);
+
+ for J in Regexps'Range loop
+ Free (Patterns (J));
+ end loop;
+ end Expect;
+
+ procedure Expect
+ (Descriptor : in out Process_Descriptor;
+ Result : out Expect_Match;
+ Regexps : Compiled_Regexp_Array;
+ Matched : out GNAT.Regpat.Match_Array;
+ Timeout : Integer := 10000;
+ Full_Buffer : Boolean := False)
+ is
+ N : Expect_Match;
+ Descriptors : Array_Of_Pd := (1 => Descriptor'Unrestricted_Access);
+
+ begin
+ pragma Assert (Matched'First = 0);
+
+ Reinitialize_Buffer (Descriptor);
+
+ loop
+ -- First, test if what is already in the buffer matches (This is
+ -- required if this package is used in multi-task mode, since one of
+ -- the tasks might have added something in the buffer, and we don't
+ -- want other tasks to wait for new input to be available before
+ -- checking the regexps).
+
+ if Descriptor.Buffer /= null then
+ for J in Regexps'Range loop
+ Match
+ (Regexps (J).all,
+ Descriptor.Buffer (1 .. Descriptor.Buffer_Index),
+ Matched);
+
+ if Matched (0) /= No_Match then
+ Result := Expect_Match (J);
+ Descriptor.Last_Match_Start := Matched (0).First;
+ Descriptor.Last_Match_End := Matched (0).Last;
+ return;
+ end if;
+ end loop;
+ end if;
+
+ Expect_Internal (Descriptors, N, Timeout, Full_Buffer);
+
+ if N = Expect_Timeout or else N = Expect_Full_Buffer then
+ Result := N;
+ return;
+ end if;
+ end loop;
+ end Expect;
+
+ procedure Expect
+ (Result : out Expect_Match;
+ Regexps : Multiprocess_Regexp_Array;
+ Matched : out GNAT.Regpat.Match_Array;
+ Timeout : Integer := 10000;
+ Full_Buffer : Boolean := False)
+ is
+ N : Expect_Match;
+ Descriptors : Array_Of_Pd (Regexps'Range);
+
+ begin
+ pragma Assert (Matched'First = 0);
+
+ for J in Descriptors'Range loop
+ Descriptors (J) := Regexps (J).Descriptor;
+ Reinitialize_Buffer (Regexps (J).Descriptor.all);
+ end loop;
+
+ loop
+ -- First, test if what is already in the buffer matches (This is
+ -- required if this package is used in multi-task mode, since one of
+ -- the tasks might have added something in the buffer, and we don't
+ -- want other tasks to wait for new input to be available before
+ -- checking the regexps).
+
+ for J in Regexps'Range loop
+ Match (Regexps (J).Regexp.all,
+ Regexps (J).Descriptor.Buffer
+ (1 .. Regexps (J).Descriptor.Buffer_Index),
+ Matched);
+
+ if Matched (0) /= No_Match then
+ Result := Expect_Match (J);
+ Regexps (J).Descriptor.Last_Match_Start := Matched (0).First;
+ Regexps (J).Descriptor.Last_Match_End := Matched (0).Last;
+ return;
+ end if;
+ end loop;
+
+ Expect_Internal (Descriptors, N, Timeout, Full_Buffer);
+
+ if N = Expect_Timeout or else N = Expect_Full_Buffer then
+ Result := N;
+ return;
+ end if;
+ end loop;
+ end Expect;
+
+ ---------------------
+ -- Expect_Internal --
+ ---------------------
+
+ procedure Expect_Internal
+ (Descriptors : in out Array_Of_Pd;
+ Result : out Expect_Match;
+ Timeout : Integer;
+ Full_Buffer : Boolean)
+ is
+ Num_Descriptors : Integer;
+ Buffer_Size : Integer := 0;
+
+ N : Integer;
+
+ type File_Descriptor_Array is
+ array (Descriptors'Range) of File_Descriptor;
+ Fds : aliased File_Descriptor_Array;
+
+ type Integer_Array is array (Descriptors'Range) of Integer;
+ Is_Set : aliased Integer_Array;
+
+ begin
+ for J in Descriptors'Range loop
+ Fds (J) := Descriptors (J).Output_Fd;
+
+ if Descriptors (J).Buffer_Size = 0 then
+ Buffer_Size := Integer'Max (Buffer_Size, 4096);
+ else
+ Buffer_Size :=
+ Integer'Max (Buffer_Size, Descriptors (J).Buffer_Size);
+ end if;
+ end loop;
+
+ declare
+ Buffer : aliased String (1 .. Buffer_Size);
+ -- Buffer used for input. This is allocated only once, not for
+ -- every iteration of the loop
+
+ begin
+ -- Loop until we match or we have a timeout
+
+ loop
+ Num_Descriptors :=
+ Poll (Fds'Address, Fds'Length, Timeout, Is_Set'Address);
+
+ case Num_Descriptors is
+
+ -- Error?
+
+ when -1 =>
+ raise Process_Died;
+
+ -- Timeout?
+
+ when 0 =>
+ Result := Expect_Timeout;
+ return;
+
+ -- Some input
+
+ when others =>
+ for J in Descriptors'Range loop
+ if Is_Set (J) = 1 then
+ Buffer_Size := Descriptors (J).Buffer_Size;
+
+ if Buffer_Size = 0 then
+ Buffer_Size := 4096;
+ end if;
+
+ N := Read (Descriptors (J).Output_Fd, Buffer'Address,
+ Buffer_Size);
+
+ -- Error or End of file
+
+ if N <= 0 then
+ -- ??? Note that ddd tries again up to three times
+ -- in that case. See LiterateA.C:174
+ raise Process_Died;
+
+ else
+ -- If there is no limit to the buffer size
+
+ if Descriptors (J).Buffer_Size = 0 then
+
+ declare
+ Tmp : String_Access := Descriptors (J).Buffer;
+
+ begin
+ if Tmp /= null then
+ Descriptors (J).Buffer :=
+ new String (1 .. Tmp'Length + N);
+ Descriptors (J).Buffer (1 .. Tmp'Length) :=
+ Tmp.all;
+ Descriptors (J).Buffer
+ (Tmp'Length + 1 .. Tmp'Length + N) :=
+ Buffer (1 .. N);
+ Free (Tmp);
+ Descriptors (J).Buffer_Index :=
+ Descriptors (J).Buffer'Last;
+
+ else
+ Descriptors (J).Buffer :=
+ new String (1 .. N);
+ Descriptors (J).Buffer.all :=
+ Buffer (1 .. N);
+ Descriptors (J).Buffer_Index := N;
+ end if;
+ end;
+
+ else
+ -- Add what we read to the buffer
+
+ if Descriptors (J).Buffer_Index + N - 1 >
+ Descriptors (J).Buffer_Size
+ then
+ -- If the user wants to know when we have
+ -- read more than the buffer can contain.
+
+ if Full_Buffer then
+ Result := Expect_Full_Buffer;
+ return;
+ end if;
+
+ -- Keep as much as possible from the buffer,
+ -- and forget old characters.
+
+ Descriptors (J).Buffer
+ (1 .. Descriptors (J).Buffer_Size - N) :=
+ Descriptors (J).Buffer
+ (N - Descriptors (J).Buffer_Size +
+ Descriptors (J).Buffer_Index + 1 ..
+ Descriptors (J).Buffer_Index);
+ Descriptors (J).Buffer_Index :=
+ Descriptors (J).Buffer_Size - N;
+ end if;
+
+ -- Keep what we read in the buffer.
+
+ Descriptors (J).Buffer
+ (Descriptors (J).Buffer_Index + 1 ..
+ Descriptors (J).Buffer_Index + N) :=
+ Buffer (1 .. N);
+ Descriptors (J).Buffer_Index :=
+ Descriptors (J).Buffer_Index + N;
+ end if;
+
+ -- Call each of the output filter with what we
+ -- read.
+
+ Call_Filters
+ (Descriptors (J).all, Buffer (1 .. N), Output);
+
+ Result := Expect_Match (N);
+ return;
+ end if;
+ end if;
+ end loop;
+ end case;
+ end loop;
+ end;
+ end Expect_Internal;
+
+ ----------------
+ -- Expect_Out --
+ ----------------
+
+ function Expect_Out (Descriptor : Process_Descriptor) return String is
+ begin
+ return Descriptor.Buffer (1 .. Descriptor.Last_Match_End);
+ end Expect_Out;
+
+ ----------------------
+ -- Expect_Out_Match --
+ ----------------------
+
+ function Expect_Out_Match (Descriptor : Process_Descriptor) return String is
+ begin
+ return Descriptor.Buffer
+ (Descriptor.Last_Match_Start .. Descriptor.Last_Match_End);
+ end Expect_Out_Match;
+
+ -----------
+ -- Flush --
+ -----------
+
+ procedure Flush
+ (Descriptor : in out Process_Descriptor;
+ Timeout : Integer := 0)
+ is
+ Buffer_Size : constant Integer := 8192;
+ Num_Descriptors : Integer;
+ N : Integer;
+ Is_Set : aliased Integer;
+ Buffer : aliased String (1 .. Buffer_Size);
+
+ begin
+ -- Empty the current buffer
+
+ Descriptor.Last_Match_End := Descriptor.Buffer_Index;
+ Reinitialize_Buffer (Descriptor);
+
+ -- Read everything from the process to flush its output
+
+ loop
+ Num_Descriptors :=
+ Poll (Descriptor.Output_Fd'Address, 1, Timeout, Is_Set'Address);
+
+ case Num_Descriptors is
+
+ -- Error ?
+
+ when -1 =>
+ raise Process_Died;
+
+ -- Timeout => End of flush
+
+ when 0 =>
+ return;
+
+ -- Some input
+
+ when others =>
+ if Is_Set = 1 then
+ N := Read (Descriptor.Output_Fd, Buffer'Address,
+ Buffer_Size);
+
+ if N = -1 then
+ raise Process_Died;
+ elsif N = 0 then
+ return;
+ end if;
+ end if;
+ end case;
+ end loop;
+
+ end Flush;
+
+ ------------------
+ -- Get_Error_Fd --
+ ------------------
+
+ function Get_Error_Fd
+ (Descriptor : Process_Descriptor) return GNAT.OS_Lib.File_Descriptor
+ is
+ begin
+ return Descriptor.Error_Fd;
+ end Get_Error_Fd;
+
+ ------------------
+ -- Get_Input_Fd --
+ ------------------
+
+ function Get_Input_Fd
+ (Descriptor : Process_Descriptor) return GNAT.OS_Lib.File_Descriptor
+ is
+ begin
+ return Descriptor.Input_Fd;
+ end Get_Input_Fd;
+
+ -------------------
+ -- Get_Output_Fd --
+ -------------------
+
+ function Get_Output_Fd
+ (Descriptor : Process_Descriptor) return GNAT.OS_Lib.File_Descriptor
+ is
+ begin
+ return Descriptor.Output_Fd;
+ end Get_Output_Fd;
+
+ -------------
+ -- Get_Pid --
+ -------------
+
+ function Get_Pid
+ (Descriptor : Process_Descriptor) return Process_Id
+ is
+ begin
+ return Descriptor.Pid;
+ end Get_Pid;
+
+ ---------------
+ -- Interrupt --
+ ---------------
+
+ procedure Interrupt (Descriptor : in out Process_Descriptor) is
+ SIGINT : constant := 2;
+
+ begin
+ Send_Signal (Descriptor, SIGINT);
+ end Interrupt;
+
+ ------------------
+ -- Lock_Filters --
+ ------------------
+
+ procedure Lock_Filters (Descriptor : in out Process_Descriptor) is
+ begin
+ Descriptor.Filters_Lock := Descriptor.Filters_Lock + 1;
+ end Lock_Filters;
+
+ ------------------------
+ -- Non_Blocking_Spawn --
+ ------------------------
+
+ procedure Non_Blocking_Spawn
+ (Descriptor : out Process_Descriptor'Class;
+ Command : String;
+ Args : GNAT.OS_Lib.Argument_List;
+ Buffer_Size : Natural := 4096;
+ Err_To_Out : Boolean := False)
+ is
+ function Alloc_Vfork_Blocks return Integer;
+ pragma Import (C, Alloc_Vfork_Blocks, "decc$$alloc_vfork_blocks");
+
+ function Get_Vfork_Jmpbuf return System.Address;
+ pragma Import (C, Get_Vfork_Jmpbuf, "decc$$get_vfork_jmpbuf");
+
+ function Get_Current_Invo_Context
+ (Addr : System.Address) return Process_Id;
+ pragma Import (C, Get_Current_Invo_Context,
+ "LIB$GET_CURRENT_INVO_CONTEXT");
+
+ Pipe1, Pipe2, Pipe3 : aliased Pipe_Type;
+
+ Arg : String_Access;
+ Arg_List : aliased array (1 .. Args'Length + 2) of System.Address;
+
+ Command_With_Path : String_Access;
+
+ begin
+ -- Create the rest of the pipes
+
+ Set_Up_Communications
+ (Descriptor, Err_To_Out, Pipe1'Access, Pipe2'Access, Pipe3'Access);
+
+ Command_With_Path := Locate_Exec_On_Path (Command);
+
+ if Command_With_Path = null then
+ raise Invalid_Process;
+ end if;
+
+ -- Fork a new process. It's 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;
+
+ -- Are we now in the child (or, for Windows, still in the common
+ -- process).
+
+ if Descriptor.Pid = Null_Pid then
+ -- Prepare an array of arguments to pass to C
+
+ Arg := new String (1 .. Command_With_Path'Length + 1);
+ Arg (1 .. Command_With_Path'Length) := Command_With_Path.all;
+ Arg (Arg'Last) := ASCII.Nul;
+ Arg_List (1) := Arg.all'Address;
+
+ for J in Args'Range loop
+ Arg := new String (1 .. Args (J)'Length + 1);
+ Arg (1 .. Args (J)'Length) := Args (J).all;
+ Arg (Arg'Last) := ASCII.Nul;
+ Arg_List (J + 2 - Args'First) := Arg.all'Address;
+ end loop;
+
+ Arg_List (Arg_List'Last) := System.Null_Address;
+
+ -- This does not return on Unix systems
+
+ Set_Up_Child_Communications
+ (Descriptor, Pipe1, Pipe2, Pipe3, Command_With_Path.all,
+ Arg_List'Address);
+ end if;
+
+ Free (Command_With_Path);
+
+ -- Did we have an error when spawning the child ?
+
+ if Descriptor.Pid < Null_Pid then
+ raise Invalid_Process;
+ else
+ -- We are now in the parent process
+
+ Set_Up_Parent_Communications (Descriptor, Pipe1, Pipe2, Pipe3);
+ end if;
+
+ -- Create the buffer
+
+ Descriptor.Buffer_Size := Buffer_Size;
+
+ if Buffer_Size /= 0 then
+ Descriptor.Buffer := new String (1 .. Positive (Buffer_Size));
+ end if;
+ end Non_Blocking_Spawn;
+
+ -------------------------
+ -- Reinitialize_Buffer --
+ -------------------------
+
+ procedure Reinitialize_Buffer
+ (Descriptor : in out Process_Descriptor'Class)
+ is
+ begin
+ if Descriptor.Buffer_Size = 0 then
+ declare
+ Tmp : String_Access := Descriptor.Buffer;
+
+ begin
+ Descriptor.Buffer :=
+ new String
+ (1 .. Descriptor.Buffer_Index - Descriptor.Last_Match_End);
+
+ if Tmp /= null then
+ Descriptor.Buffer.all := Tmp
+ (Descriptor.Last_Match_End + 1 .. Descriptor.Buffer_Index);
+ Free (Tmp);
+ end if;
+ end;
+
+ Descriptor.Buffer_Index := Descriptor.Buffer'Last;
+
+ else
+ Descriptor.Buffer
+ (1 .. Descriptor.Buffer_Index - Descriptor.Last_Match_End) :=
+ Descriptor.Buffer
+ (Descriptor.Last_Match_End + 1 .. Descriptor.Buffer_Index);
+
+ if Descriptor.Buffer_Index > Descriptor.Last_Match_End then
+ Descriptor.Buffer_Index :=
+ Descriptor.Buffer_Index - Descriptor.Last_Match_End;
+ else
+ Descriptor.Buffer_Index := 0;
+ end if;
+ end if;
+
+ Descriptor.Last_Match_Start := 0;
+ Descriptor.Last_Match_End := 0;
+ end Reinitialize_Buffer;
+
+ -------------------
+ -- Remove_Filter --
+ -------------------
+
+ procedure Remove_Filter
+ (Descriptor : in out Process_Descriptor;
+ Filter : Filter_Function)
+ is
+ Previous : Filter_List := null;
+ Current : Filter_List := Descriptor.Filters;
+
+ begin
+ while Current /= null loop
+ if Current.Filter = Filter then
+ if Previous = null then
+ Descriptor.Filters := Current.Next;
+ else
+ Previous.Next := Current.Next;
+ end if;
+ end if;
+
+ Previous := Current;
+ Current := Current.Next;
+ end loop;
+ end Remove_Filter;
+
+ ----------
+ -- Send --
+ ----------
+
+ procedure Send
+ (Descriptor : in out Process_Descriptor;
+ Str : String;
+ Add_LF : Boolean := True;
+ Empty_Buffer : Boolean := False)
+ is
+ Full_Str : constant String := Str & ASCII.LF;
+ Last : Natural;
+ Result : Expect_Match;
+ Descriptors : Array_Of_Pd := (1 => Descriptor'Unrestricted_Access);
+
+ Discard : Natural;
+ pragma Unreferenced (Discard);
+
+ begin
+ if Empty_Buffer then
+
+ -- Force a read on the process if there is anything waiting
+
+ Expect_Internal (Descriptors, Result,
+ Timeout => 0, Full_Buffer => False);
+ Descriptor.Last_Match_End := Descriptor.Buffer_Index;
+
+ -- Empty the buffer
+
+ Reinitialize_Buffer (Descriptor);
+ end if;
+
+ if Add_LF then
+ Last := Full_Str'Last;
+ else
+ Last := Full_Str'Last - 1;
+ end if;
+
+ Call_Filters (Descriptor, Full_Str (Full_Str'First .. Last), Input);
+
+ Discard := Write (Descriptor.Input_Fd,
+ Full_Str'Address,
+ Last - Full_Str'First + 1);
+ -- Shouldn't we at least have a pragma Assert on the result ???
+ end Send;
+
+ -----------------
+ -- Send_Signal --
+ -----------------
+
+ procedure Send_Signal
+ (Descriptor : Process_Descriptor;
+ Signal : Integer)
+ is
+ begin
+ Kill (Descriptor.Pid, Signal);
+ -- ??? Need to check process status here.
+ end Send_Signal;
+
+ ---------------------------------
+ -- Set_Up_Child_Communications --
+ ---------------------------------
+
+ procedure Set_Up_Child_Communications
+ (Pid : in out Process_Descriptor;
+ Pipe1 : in out Pipe_Type;
+ Pipe2 : in out Pipe_Type;
+ Pipe3 : in out Pipe_Type;
+ Cmd : in String;
+ Args : in System.Address)
+ is
+ pragma Warnings (Off, Pid);
+
+ begin
+ -- Since the code between fork and exec on VMS executes
+ -- in the context of the parent process, we need to
+ -- perform the following actions:
+ -- - save stdin, stdout, stderr
+ -- - replace them by our pipes
+ -- - create the child with process handle inheritance
+ -- - revert to the previous stdin, stdout and stderr.
+
+ Save_Input := Dup (GNAT.OS_Lib.Standin);
+ Save_Output := Dup (GNAT.OS_Lib.Standout);
+ Save_Error := Dup (GNAT.OS_Lib.Standerr);
+
+ -- Since we are still called from the parent process, there is no way
+ -- currently we can cleanly close the unneeded ends of the pipes, but
+ -- this doesn't really matter.
+ -- We could close Pipe1.Output, Pipe2.Input, Pipe3.Input.
+
+ Dup2 (Pipe1.Input, GNAT.OS_Lib.Standin);
+ Dup2 (Pipe2.Output, GNAT.OS_Lib.Standout);
+ Dup2 (Pipe3.Output, GNAT.OS_Lib.Standerr);
+
+ Portable_Execvp (Pid.Pid'Access, Cmd & ASCII.Nul, Args);
+
+ end Set_Up_Child_Communications;
+
+ ---------------------------
+ -- Set_Up_Communications --
+ ---------------------------
+
+ procedure Set_Up_Communications
+ (Pid : in out Process_Descriptor;
+ Err_To_Out : Boolean;
+ Pipe1 : access Pipe_Type;
+ Pipe2 : access Pipe_Type;
+ Pipe3 : access Pipe_Type)
+ is
+ begin
+ -- Create the pipes
+
+ if Create_Pipe (Pipe1) /= 0 then
+ return;
+ end if;
+
+ if Create_Pipe (Pipe2) /= 0 then
+ return;
+ end if;
+
+ Pid.Input_Fd := Pipe1.Output;
+ Pid.Output_Fd := Pipe2.Input;
+
+ if Err_To_Out then
+ Pipe3.all := Pipe2.all;
+ else
+ if Create_Pipe (Pipe3) /= 0 then
+ return;
+ end if;
+ end if;
+
+ Pid.Error_Fd := Pipe3.Input;
+ end Set_Up_Communications;
+
+ ----------------------------------
+ -- Set_Up_Parent_Communications --
+ ----------------------------------
+
+ procedure Set_Up_Parent_Communications
+ (Pid : in out Process_Descriptor;
+ Pipe1 : in out Pipe_Type;
+ Pipe2 : in out Pipe_Type;
+ Pipe3 : in out Pipe_Type)
+ is
+ pragma Warnings (Off, Pid);
+
+ begin
+
+ Dup2 (Save_Input, GNAT.OS_Lib.Standin);
+ Dup2 (Save_Output, GNAT.OS_Lib.Standout);
+ Dup2 (Save_Error, GNAT.OS_Lib.Standerr);
+
+ Close (Save_Input);
+ Close (Save_Output);
+ Close (Save_Error);
+
+ Close (Pipe1.Input);
+ Close (Pipe2.Output);
+ Close (Pipe3.Output);
+ end Set_Up_Parent_Communications;
+
+ ------------------
+ -- Trace_Filter --
+ ------------------
+
+ procedure Trace_Filter
+ (Descriptor : Process_Descriptor'Class;
+ Str : String;
+ User_Data : System.Address := System.Null_Address)
+ is
+ pragma Warnings (Off, Descriptor);
+ pragma Warnings (Off, User_Data);
+
+ begin
+ GNAT.IO.Put (Str);
+ end Trace_Filter;
+
+ --------------------
+ -- Unlock_Filters --
+ --------------------
+
+ procedure Unlock_Filters (Descriptor : in out Process_Descriptor) is
+ begin
+ if Descriptor.Filters_Lock > 0 then
+ Descriptor.Filters_Lock := Descriptor.Filters_Lock - 1;
+ end if;
+ end Unlock_Filters;
+
+end GNAT.Expect;
diff --git a/gcc/ada/g-os_lib.adb b/gcc/ada/g-os_lib.adb
index 7c321b64fef..473e0eb7e27 100644
--- a/gcc/ada/g-os_lib.adb
+++ b/gcc/ada/g-os_lib.adb
@@ -1110,16 +1110,13 @@ package body GNAT.OS_Lib is
----------------------
function Is_Absolute_Path (Name : String) return Boolean is
- function Is_Absolute_Path (Name : Address) return Integer;
+ function Is_Absolute_Path
+ (Name : Address;
+ Length : Integer) return Integer;
pragma Import (C, Is_Absolute_Path, "__gnat_is_absolute_path");
- F_Name : String (1 .. Name'Length + 1);
-
begin
- F_Name (1 .. Name'Length) := Name;
- F_Name (F_Name'Last) := ASCII.NUL;
-
- return Is_Absolute_Path (F_Name'Address) /= 0;
+ return Is_Absolute_Path (Name'Address, Name'Length) /= 0;
end Is_Absolute_Path;
------------------
diff --git a/gcc/ada/g-os_lib.ads b/gcc/ada/g-os_lib.ads
index 6cd6b82f787..bd4201fc5f7 100644
--- a/gcc/ada/g-os_lib.ads
+++ b/gcc/ada/g-os_lib.ads
@@ -93,6 +93,7 @@ pragma Elaborate_Body (OS_Lib);
-- Time/Date Stuff --
---------------------
+ type OS_Time is private;
-- The OS's notion of time is represented by the private type OS_Time.
-- This is the type returned by the File_Time_Stamp functions to obtain
-- the time stamp of a specified file. Functions and a procedure (modeled
@@ -102,7 +103,8 @@ pragma Elaborate_Body (OS_Lib);
-- cases but rather the actual (time-zone independent) time stamp of the
-- file (of course in Unix systems, this *is* in GMT form).
- type OS_Time is private;
+ Invalid_Time : constant OS_Time;
+ -- A special unique value used to flag an invalid time stamp value
subtype Year_Type is Integer range 1900 .. 2099;
subtype Month_Type is Integer range 1 .. 12;
@@ -110,6 +112,8 @@ pragma Elaborate_Body (OS_Lib);
subtype Hour_Type is Integer range 0 .. 23;
subtype Minute_Type is Integer range 0 .. 59;
subtype Second_Type is Integer range 0 .. 59;
+ -- Declarations similar to those in Calendar, breaking down the time
+
function GM_Year (Date : OS_Time) return Year_Type;
function GM_Month (Date : OS_Time) return Month_Type;
@@ -117,6 +121,7 @@ pragma Elaborate_Body (OS_Lib);
function GM_Hour (Date : OS_Time) return Hour_Type;
function GM_Minute (Date : OS_Time) return Minute_Type;
function GM_Second (Date : OS_Time) return Second_Type;
+ -- Functions to extract information from OS_Time value
function "<" (X, Y : OS_Time) return Boolean;
function ">" (X, Y : OS_Time) return Boolean;
@@ -134,6 +139,8 @@ pragma Elaborate_Body (OS_Lib);
Hour : out Hour_Type;
Minute : out Minute_Type;
Second : out Second_Type);
+ -- Analogous to the routine of similar name in Calendar, takes an OS_Time
+ -- and splits it into its component parts with obvious meanings.
----------------
-- File Stuff --
@@ -368,9 +375,11 @@ pragma Elaborate_Body (OS_Lib);
function File_Time_Stamp (Name : String) return OS_Time;
-- Given the name of a file or directory, Name, obtains and returns the
-- time stamp. This function can be used for an unopened file.
+ -- Returns Invalid_Time is Name doesn't correspond to an existing file.
function File_Time_Stamp (FD : File_Descriptor) return OS_Time;
-- Get time stamp of file from file descriptor FD
+ -- Returns Invalid_Time is FD doesn't correspond to an existing file.
function Normalize_Pathname
(Name : String;
@@ -542,6 +551,7 @@ pragma Elaborate_Body (OS_Lib);
Success : out Boolean);
function File_Time_Stamp (Name : C_File_Name) return OS_Time;
+ -- Returns Invalid_Time is Name doesn't correspond to an existing file.
function Is_Regular_File (Name : C_File_Name) return Boolean;
@@ -735,6 +745,9 @@ private
-- but this was not properly supported till GNAT 3.15a, so that would
-- cause bootstrap path problems. To be changed later ???
+ Invalid_Time : constant OS_Time := -1;
+ -- This value should match the return valud by __gnat_file_time_*
+
pragma Inline ("<");
pragma Inline (">");
pragma Inline ("<=");
diff --git a/gcc/ada/g-regpat.adb b/gcc/ada/g-regpat.adb
index 8857edccbfc..76fd6abd46d 100644
--- a/gcc/ada/g-regpat.adb
+++ b/gcc/ada/g-regpat.adb
@@ -7,7 +7,7 @@
-- B o d y --
-- --
-- Copyright (C) 1986 by University of Toronto. --
--- Copyright (C) 1996-2003 Ada Core Technologies, Inc. --
+-- Copyright (C) 1996-2004 Ada Core Technologies, 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- --
@@ -3406,9 +3406,9 @@ package body GNAT.Regpat is
(Expression : String;
Data : String;
Matches : out Match_Array;
- Size : Program_Size := 0;
- Data_First : Integer := -1;
- Data_Last : Positive := Positive'Last)
+ Size : Program_Size := Auto_Size;
+ Data_First : Integer := -1;
+ Data_Last : Positive := Positive'Last)
is
PM : Pattern_Matcher (Size);
Finalize_Size : Program_Size;
@@ -3426,12 +3426,12 @@ package body GNAT.Regpat is
-- Match --
-----------
- function Match
+ function Match
(Expression : String;
Data : String;
- Size : Program_Size := 0;
- Data_First : Integer := -1;
- Data_Last : Positive := Positive'Last) return Natural
+ Size : Program_Size := Auto_Size;
+ Data_First : Integer := -1;
+ Data_Last : Positive := Positive'Last) return Natural
is
PM : Pattern_Matcher (Size);
Final_Size : Program_Size; -- unused
@@ -3452,9 +3452,9 @@ package body GNAT.Regpat is
function Match
(Expression : String;
Data : String;
- Size : Program_Size := 0;
- Data_First : Integer := -1;
- Data_Last : Positive := Positive'Last) return Boolean
+ Size : Program_Size := Auto_Size;
+ Data_First : Integer := -1;
+ Data_Last : Positive := Positive'Last) return Boolean
is
Matches : Match_Array (0 .. 0);
PM : Pattern_Matcher (Size);
diff --git a/gcc/ada/g-regpat.ads b/gcc/ada/g-regpat.ads
index 57bc076717a..82bab7f5bda 100644
--- a/gcc/ada/g-regpat.ads
+++ b/gcc/ada/g-regpat.ads
@@ -7,7 +7,7 @@
-- S p e c --
-- --
-- Copyright (C) 1986 by University of Toronto. --
--- Copyright (C) 1996-2003 Ada Core Technologies, Inc. --
+-- Copyright (C) 1996-2004 Ada Core Technologies, 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- --
@@ -300,19 +300,32 @@ pragma Preelaborate (Regpat);
-- This is limited by the size of a Character, as found in the
-- byte-compiled version of regular expressions.
- Max_Program_Size : constant := 2**15 - 1;
- -- Maximum size that can be allocated for a program
-
Max_Curly_Repeat : constant := 32767;
-- Maximum number of repetition for the curly operator.
-- The digits in the {n}, {n,} and {n,m } operators can not be higher
-- than this constant, since they have to fit on two characters in the
-- byte-compiled version of regular expressions.
+ Max_Program_Size : constant := 2**15 - 1;
+ -- Maximum size that can be allocated for a program
+
type Program_Size is range 0 .. Max_Program_Size;
for Program_Size'Size use 16;
-- Number of bytes allocated for the byte-compiled version of a regular
- -- expression.
+ -- expression. The size required depends on the complexity of the regular
+ -- expression in a complex manner that is undocumented (other than in the
+ -- body of the Compile procedure). Normally the size is automatically set
+ -- and the programmer need not be concerned about it. There are two
+ -- exceptions to this. First in the calls to Match, it is possible to
+ -- specify a non-zero size that is known to be large enough. This can
+ -- slightly increase the efficiency by avoiding a copy. Second, in the
+ -- case of calling compile, it is possible using the procedural form
+ -- of Compile to use a single Pattern_Matcher variable for several
+ -- different expressions by setting its size sufficiently large.
+
+ Auto_Size : constant := 0;
+ -- Used in calls to Match to indicate that the Size should be set to
+ -- a value appropriate to the expression being used automatically.
type Regexp_Flags is mod 256;
for Regexp_Flags'Size use 8;
@@ -368,9 +381,14 @@ pragma Preelaborate (Regpat);
-- matching a null string at position 1, which uses (1, 0)
-- and no match at all.
- ------------------------------
- -- Pattern_Matcher Creation --
- ------------------------------
+ ---------------------------------
+ -- Pattern_Matcher Compilation --
+ ---------------------------------
+
+ -- The subprograms here are used to precompile regular expressions
+ -- for use in subsequent Match calls. Precompilation improves
+ -- efficiency if the same regular expression is to be used in
+ -- more than one Match call.
type Pattern_Matcher (Size : Program_Size) is private;
-- Type used to represent a regular expression compiled into byte code
@@ -381,14 +399,18 @@ pragma Preelaborate (Regpat);
function Compile
(Expression : String;
Flags : Regexp_Flags := No_Flags) return Pattern_Matcher;
- -- Compile a regular expression into internal code.
- -- Raises Expression_Error if Expression is not a legal regular expression.
- -- The appropriate size is calculated automatically, but this means that
- -- the regular expression has to be compiled twice (the first time to
- -- calculate the size, the second time to actually generate the byte code).
+ -- Compile a regular expression into internal code
--
- -- Flags is the default value to use to set properties for Expression (case
- -- sensitivity,...).
+ -- Raises Expression_Error if Expression is not a legal regular expression
+ --
+ -- The appropriate size is calculated automatically to correspond to the
+ -- provided expression. This is the normal default method of compilation.
+ -- Note that it is generally not possible to assign the result of two
+ -- different calls to this Compile function to the same Pattern_Matcher
+ -- variable, since the sizes will differ.
+ --
+ -- Flags is the default value to use to set properties for Expression
+ -- (e.g. case sensitivity,...).
procedure Compile
(Matcher : out Pattern_Matcher;
@@ -396,11 +418,28 @@ pragma Preelaborate (Regpat);
Final_Code_Size : out Program_Size;
Flags : Regexp_Flags := No_Flags);
-- Compile a regular expression into into internal code
- -- This procedure is significantly faster than the function
- -- Compile, as there is a known maximum size for the matcher.
- -- This function raises Storage_Error if Matcher is too small
- -- to hold the resulting code, or Expression_Error is Expression
- -- is not a legal regular expression.
+
+ -- This procedure is significantly faster than the Compile function
+ -- since it avoids the extra step of precomputing the required size.
+ --
+ -- However, it requires the user to provide a Pattern_Matcher variable
+ -- whose size is preset to a large enough value. One advantage of this
+ -- approach, in addition to the improved efficiency, is that the same
+ -- Pattern_Matcher variable can be used to hold the compiled code for
+ -- several different regular expressions by setting a size that is
+ -- large enough to accomodate all possibilities.
+ --
+ -- In this version of the procedure call, the actual required code
+ -- size is returned. Also if Matcher.Size is zero on entry, then the
+ -- resulting code is not stored. A call with Matcher.Size set to Auto_Size
+ -- can thus be used to determine the space required for compiling the
+ -- given regular expression.
+ --
+ -- This function raises Storage_Error if Matcher is too small to hold
+ -- the resulting code (i.e. Matcher.Size has too small a value).
+ --
+ -- Expression_Error is raised if the string Expression does not contain
+ -- a valid regular expression.
--
-- Flags is the default value to use to set properties for Expression (case
-- sensitivity,...).
@@ -410,7 +449,7 @@ pragma Preelaborate (Regpat);
Expression : String;
Flags : Regexp_Flags := No_Flags);
-- Same procedure as above, expect it does not return the final
- -- program size.
+ -- program size, and Matcher.Size cannot be Auto_Size.
function Paren_Count (Regexp : Pattern_Matcher) return Match_Count;
pragma Inline (Paren_Count);
@@ -442,83 +481,96 @@ pragma Preelaborate (Regpat);
-- Matching --
--------------
- procedure Match
- (Expression : String;
- Data : String;
- Matches : out Match_Array;
- Size : Program_Size := 0;
- Data_First : Integer := -1;
- Data_Last : Positive := Positive'Last);
- -- Match Expression against Data (Data_First .. Data_Last) and store
- -- result in Matches.
- --
- -- Data_First defaults to Data'First if unspecified (that is the
- -- dummy value of -1 is interpreted to mean Data'First).
- --
- -- Data_Last defaults to Data'Last if unspecified (that is the
- -- dummy value of Positive'Last is interpreted to mean Data'Last)
- --
- -- It is important that Data contains the whole string (or file) you
- -- want to matched against, even if you start in the middle, since
- -- otherwise regular expressions starting with "^" or ending with "$" will
- -- be improperly processed.
+ -- The Match subprograms are given a regular expression in string
+ -- form, and perform the corresponding match. The following parameters
+ -- are present in all forms of the Match call.
+
+ -- Expression contains the regular expression to be matched as a string
+
+ -- Data contains the string to be matched
+
+ -- Data_First is the lower bound for the match, i.e. Data (Data_First)
+ -- will be the first character to be examined. If Data_First is set to
+ -- the special value of -1 (the default), then the first character to
+ -- be examined is Data (Data_First). However, the regular expression
+ -- character ^ (start of string) still refers to the first character
+ -- of the full string (Data (Data'First)), which is why there is a
+ -- separate mechanism for specifying Data_First.
+
+ -- Data_Last is the upper bound for the match, i.e. Data (Data_Last)
+ -- will be the last character to be examined. If Data_Last is set to
+ -- the special value of Positive'Last (the default), then the last
+ -- character to be examined is Data (Data_Last). However, the regular
+ -- expression character $ (end of string) still refers to the last
+ -- character of the full string (Data (Data'Last)), which is why there
+ -- is a separate mechanism for specifying Data_Last.
+
+ -- Note: the use of Data_First and Data_Last is not equivalent to
+ -- simply passing a slice as Expression because of the handling of
+ -- regular expression characters ^ and $.
+
+ -- Size is the size allocated for the compiled byte code. Normally
+ -- this is defaulted to Auto_Size which means that the appropriate
+ -- size is allocated automatically. It is possible to specify an
+ -- explicit size, which must be sufficiently large. This slightly
+ -- increases the efficiency by avoiding the extra step of computing
+ -- the appropriate size.
+
+ -- The following exceptions can be raised in calls to Match
--
- -- Function raises Storage_Error if Size is too small for Expression,
- -- or Expression_Error if Expression is not a legal regular expression.
- -- If Size is 0, then the appropriate size is automatically calculated
- -- by this package, but this is slightly slower.
+ -- Storage_Error is raised if a non-zero value is given for Size
+ -- and it is too small to hold the compiled byte code.
--
+ -- Expression_Error is raised if the given expression is not a legal
+ -- regular expression.
+
+
+ procedure Match
+ (Expression : String;
+ Data : String;
+ Matches : out Match_Array;
+ Size : Program_Size := Auto_Size;
+ Data_First : Integer := -1;
+ Data_Last : Positive := Positive'Last);
+ -- This version returns the result of the match stored in Match_Array.
-- At most Matches'Length parenthesis are returned.
- function Match
+ function Match
(Expression : String;
Data : String;
- Size : Program_Size := 0;
- Data_First : Integer := -1;
- Data_Last : Positive := Positive'Last) return Natural;
- -- Return the position where Data matches, or (Data'First - 1) if
- -- there is no match.
- --
- -- Function raises Storage_Error if Size is too small for Expression
- -- or Expression_Error if Expression is not a legal regular expression
- --
- -- If Size is 0, then the appropriate size is automatically calculated
- -- by this package, but this is slightly slower.
- -- See description of Data_First and Data_Last above.
+ Size : Program_Size := Auto_Size;
+ Data_First : Integer := -1;
+ Data_Last : Positive := Positive'Last) return Natural;
+ -- This version returns the position where Data matches, or if there is
+ -- no match, then the value Data'First - 1.
function Match
(Expression : String;
Data : String;
- Size : Program_Size := 0;
- Data_First : Integer := -1;
- Data_Last : Positive := Positive'Last) return Boolean;
- -- Return True if Data matches Expression. Match raises Storage_Error
- -- if Size is too small for Expression, or Expression_Error if Expression
- -- is not a legal regular expression.
- --
- -- If Size is 0, then the appropriate size is automatically calculated
- -- by this package, but this is slightly slower.
- --
- -- See description of Data_First and Data_Last above.
+ Size : Program_Size := Auto_Size;
+ Data_First : Integer := -1;
+ Data_Last : Positive := Positive'Last) return Boolean;
+ -- This version returns True if the match succeeds, False otherwise
------------------------------------------------
- -- Matching a pre-compiled regular expression --
+ -- Matching a Pre-Compiled Regular Expression --
------------------------------------------------
-- The following functions are significantly faster if you need to reuse
-- the same regular expression multiple times, since you only have to
- -- compile it once.
+ -- compile it once. For these functions you must first compile the
+ -- expression with a call to Compile as previously described.
+
+ -- The parameters Data, Data_First and Data_Last are as described
+ -- in the previous section.
function Match
(Self : Pattern_Matcher;
Data : String;
Data_First : Integer := -1;
Data_Last : Positive := Positive'Last) return Natural;
- -- Match Data using the given pattern matcher.
- -- Return the position where Data matches, or (Data'First - 1) if there is
- -- no match.
- --
- -- See description of Data_First and Data_Last above.
+ -- Match Data using the given pattern matcher. Returns the position
+ -- where Data matches, or (Data'First - 1) if there is no match.
function Match
(Self : Pattern_Matcher;
@@ -526,8 +578,6 @@ pragma Preelaborate (Regpat);
Data_First : Integer := -1;
Data_Last : Positive := Positive'Last) return Boolean;
-- Return True if Data matches using the given pattern matcher.
- --
- -- See description of Data_First and Data_Last above.
pragma Inline (Match);
-- All except the last one below
@@ -542,8 +592,6 @@ pragma Preelaborate (Regpat);
-- The expression matches if Matches (0) /= No_Match.
--
-- At most Matches'Length parenthesis are returned.
- --
- -- See description of Data_First and Data_Last above.
-----------
-- Debug --
diff --git a/gcc/ada/g-soccon-aix.ads b/gcc/ada/g-soccon-aix.ads
new file mode 100644
index 00000000000..0f5fe9d4c6b
--- /dev/null
+++ b/gcc/ada/g-soccon-aix.ads
@@ -0,0 +1,158 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . S O C K E T S . C O N S T A N T S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2000-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides target dependent definitions of constant for use
+-- by the GNAT.Sockets package (g-socket.ads). This package should not be
+-- directly with'ed by an applications program.
+
+-- This is the version for AIX
+
+package GNAT.Sockets.Constants is
+
+ --------------
+ -- Families --
+ --------------
+
+ AF_INET : constant := 2; -- IPv4 address family
+ AF_INET6 : constant := 24; -- IPv6 address family
+
+ -----------
+ -- Modes --
+ -----------
+
+ SOCK_STREAM : constant := 1; -- Stream socket
+ SOCK_DGRAM : constant := 2; -- Datagram socket
+
+ -------------------
+ -- Socket errors --
+ -------------------
+
+ EACCES : constant := 13; -- Permission denied
+ EADDRINUSE : constant := 67; -- Address already in use
+ EADDRNOTAVAIL : constant := 68; -- Cannot assign address
+ EAFNOSUPPORT : constant := 66; -- Addr family not supported
+ EALREADY : constant := 56; -- Operation in progress
+ EBADF : constant := 9; -- Bad file descriptor
+ ECONNABORTED : constant := 72; -- Connection aborted
+ ECONNREFUSED : constant := 79; -- Connection refused
+ ECONNRESET : constant := 73; -- Connection reset by peer
+ EDESTADDRREQ : constant := 58; -- Destination addr required
+ EFAULT : constant := 14; -- Bad address
+ EHOSTDOWN : constant := 80; -- Host is down
+ EHOSTUNREACH : constant := 81; -- No route to host
+ EINPROGRESS : constant := 55; -- Operation now in progress
+ EINTR : constant := 4; -- Interrupted system call
+ EINVAL : constant := 22; -- Invalid argument
+ EIO : constant := 5; -- Input output error
+ EISCONN : constant := 75; -- Socket already connected
+ ELOOP : constant := 85; -- Too many symbolic lynks
+ EMFILE : constant := 24; -- Too many open files
+ EMSGSIZE : constant := 59; -- Message too long
+ ENAMETOOLONG : constant := 86; -- Name too long
+ ENETDOWN : constant := 69; -- Network is down
+ ENETRESET : constant := 71; -- Disconn. on network reset
+ ENETUNREACH : constant := 70; -- Network is unreachable
+ ENOBUFS : constant := 74; -- No buffer space available
+ ENOPROTOOPT : constant := 61; -- Protocol not available
+ ENOTCONN : constant := 76; -- Socket not connected
+ ENOTSOCK : constant := 57; -- Operation on non socket
+ EOPNOTSUPP : constant := 64; -- Operation not supported
+ EPFNOSUPPORT : constant := 65; -- Unknown protocol family
+ EPROTONOSUPPORT : constant := 62; -- Unknown protocol
+ EPROTOTYPE : constant := 60; -- Unknown protocol type
+ ESHUTDOWN : constant := 77; -- Cannot send once shutdown
+ ESOCKTNOSUPPORT : constant := 63; -- Socket type not supported
+ ETIMEDOUT : constant := 78; -- Connection timed out
+ ETOOMANYREFS : constant := 115; -- Too many references
+ EWOULDBLOCK : constant := 11; -- Operation would block
+
+ -----------------
+ -- Host errors --
+ -----------------
+
+ HOST_NOT_FOUND : constant := 1; -- Unknown host
+ TRY_AGAIN : constant := 2; -- Host name lookup failure
+ NO_DATA : constant := 4; -- No data record for name
+ NO_RECOVERY : constant := 3; -- Non recoverable errors
+
+ -------------------
+ -- Control flags --
+ -------------------
+
+ FIONBIO : constant := -2147195266; -- Set/clear non-blocking io
+ FIONREAD : constant := 1074030207; -- How many bytes to read
+
+ --------------------
+ -- Shutdown modes --
+ --------------------
+
+ SHUT_RD : constant := 0; -- No more recv
+ SHUT_WR : constant := 1; -- No more send
+ SHUT_RDWR : constant := 2; -- No more recv/send
+
+ ---------------------
+ -- Protocol levels --
+ ---------------------
+
+ SOL_SOCKET : constant := 65535; -- Options for socket level
+ IPPROTO_IP : constant := 0; -- Dummy protocol for IP
+ IPPROTO_UDP : constant := 17; -- UDP
+ IPPROTO_TCP : constant := 6; -- TCP
+
+ -------------------
+ -- Request flags --
+ -------------------
+
+ MSG_OOB : constant := 1; -- Process out-of-band data
+ MSG_PEEK : constant := 2; -- Peek at incoming data
+ MSG_EOR : constant := 8; -- Send end of record
+ MSG_WAITALL : constant := 64; -- Wait for full reception
+
+ --------------------
+ -- Socket options --
+ --------------------
+
+ TCP_NODELAY : constant := 1; -- Do not coalesce packets
+ SO_SNDBUF : constant := 4097; -- Set/get send buffer size
+ SO_RCVBUF : constant := 4098; -- Set/get recv buffer size
+ SO_REUSEADDR : constant := 4; -- Bind reuse local address
+ SO_KEEPALIVE : constant := 8; -- Enable keep-alive msgs
+ SO_LINGER : constant := 128; -- Defer close to flush data
+ SO_ERROR : constant := 4103; -- Get/clear error status
+ SO_BROADCAST : constant := 32; -- Can send broadcast msgs
+ IP_ADD_MEMBERSHIP : constant := 12; -- Join a multicast group
+ IP_DROP_MEMBERSHIP : constant := 13; -- Leave a multicast group
+ IP_MULTICAST_TTL : constant := 10; -- Set/get multicast TTL
+ IP_MULTICAST_LOOP : constant := 11; -- Set/get mcast loopback
+
+end GNAT.Sockets.Constants;
diff --git a/gcc/ada/g-soccon-freebsd.ads b/gcc/ada/g-soccon-freebsd.ads
new file mode 100644
index 00000000000..cd19222e1a7
--- /dev/null
+++ b/gcc/ada/g-soccon-freebsd.ads
@@ -0,0 +1,158 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . S O C K E T S . C O N S T A N T S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2000-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides target dependent definitions of constant for use
+-- by the GNAT.Sockets package (g-socket.ads). This package should not be
+-- directly with'ed by an applications program.
+
+-- This is the version for i386 FreeBSD
+
+package GNAT.Sockets.Constants is
+
+ --------------
+ -- Families --
+ --------------
+
+ AF_INET : constant := 2; -- IPv4 address family
+ AF_INET6 : constant := 28; -- IPv6 address family
+
+ -----------
+ -- Modes --
+ -----------
+
+ SOCK_STREAM : constant := 1; -- Stream socket
+ SOCK_DGRAM : constant := 2; -- Datagram socket
+
+ -------------------
+ -- Socket errors --
+ -------------------
+
+ EACCES : constant := 13; -- Permission denied
+ EADDRINUSE : constant := 48; -- Address already in use
+ EADDRNOTAVAIL : constant := 49; -- Cannot assign address
+ EAFNOSUPPORT : constant := 47; -- Addr family not supported
+ EALREADY : constant := 37; -- Operation in progress
+ EBADF : constant := 9; -- Bad file descriptor
+ ECONNABORTED : constant := 53; -- Connection aborted
+ ECONNREFUSED : constant := 61; -- Connection refused
+ ECONNRESET : constant := 54; -- Connection reset by peer
+ EDESTADDRREQ : constant := 39; -- Destination addr required
+ EFAULT : constant := 14; -- Bad address
+ EHOSTDOWN : constant := 64; -- Host is down
+ EHOSTUNREACH : constant := 65; -- No route to host
+ EINPROGRESS : constant := 36; -- Operation now in progress
+ EINTR : constant := 4; -- Interrupted system call
+ EINVAL : constant := 22; -- Invalid argument
+ EIO : constant := 5; -- Input output error
+ EISCONN : constant := 56; -- Socket already connected
+ ELOOP : constant := 62; -- Too many symbolic lynks
+ EMFILE : constant := 24; -- Too many open files
+ EMSGSIZE : constant := 40; -- Message too long
+ ENAMETOOLONG : constant := 63; -- Name too long
+ ENETDOWN : constant := 50; -- Network is down
+ ENETRESET : constant := 52; -- Disconn. on network reset
+ ENETUNREACH : constant := 51; -- Network is unreachable
+ ENOBUFS : constant := 55; -- No buffer space available
+ ENOPROTOOPT : constant := 42; -- Protocol not available
+ ENOTCONN : constant := 57; -- Socket not connected
+ ENOTSOCK : constant := 38; -- Operation on non socket
+ EOPNOTSUPP : constant := 45; -- Operation not supported
+ EPFNOSUPPORT : constant := 46; -- Unknown protocol family
+ EPROTONOSUPPORT : constant := 43; -- Unknown protocol
+ EPROTOTYPE : constant := 41; -- Unknown protocol type
+ ESHUTDOWN : constant := 58; -- Cannot send once shutdown
+ ESOCKTNOSUPPORT : constant := 44; -- Socket type not supported
+ ETIMEDOUT : constant := 60; -- Connection timed out
+ ETOOMANYREFS : constant := 59; -- Too many references
+ EWOULDBLOCK : constant := 35; -- Operation would block
+
+ -----------------
+ -- Host errors --
+ -----------------
+
+ HOST_NOT_FOUND : constant := 1; -- Unknown host
+ TRY_AGAIN : constant := 2; -- Host name lookup failure
+ NO_DATA : constant := 4; -- No data record for name
+ NO_RECOVERY : constant := 3; -- Non recoverable errors
+
+ -------------------
+ -- Control flags --
+ -------------------
+
+ FIONBIO : constant := -2147195266; -- Set/clear non-blocking io
+ FIONREAD : constant := 1074030207; -- How many bytes to read
+
+ --------------------
+ -- Shutdown modes --
+ --------------------
+
+ SHUT_RD : constant := 0; -- No more recv
+ SHUT_WR : constant := 1; -- No more send
+ SHUT_RDWR : constant := 2; -- No more recv/send
+
+ ---------------------
+ -- Protocol levels --
+ ---------------------
+
+ SOL_SOCKET : constant := 65535; -- Options for socket level
+ IPPROTO_IP : constant := 0; -- Dummy protocol for IP
+ IPPROTO_UDP : constant := 17; -- UDP
+ IPPROTO_TCP : constant := 6; -- TCP
+
+ -------------------
+ -- Request flags --
+ -------------------
+
+ MSG_OOB : constant := 1; -- Process out-of-band data
+ MSG_PEEK : constant := 2; -- Peek at incoming data
+ MSG_EOR : constant := 8; -- Send end of record
+ MSG_WAITALL : constant := 64; -- Wait for full reception
+
+ --------------------
+ -- Socket options --
+ --------------------
+
+ TCP_NODELAY : constant := 1; -- Do not coalesce packets
+ SO_SNDBUF : constant := 4097; -- Set/get send buffer size
+ SO_RCVBUF : constant := 4098; -- Set/get recv buffer size
+ SO_REUSEADDR : constant := 4; -- Bind reuse local address
+ SO_KEEPALIVE : constant := 8; -- Enable keep-alive msgs
+ SO_LINGER : constant := 128; -- Defer close to flush data
+ SO_ERROR : constant := 4103; -- Get/clear error status
+ SO_BROADCAST : constant := 32; -- Can send broadcast msgs
+ IP_ADD_MEMBERSHIP : constant := 12; -- Join a multicast group
+ IP_DROP_MEMBERSHIP : constant := 13; -- Leave a multicast group
+ IP_MULTICAST_TTL : constant := 10; -- Set/get multicast TTL
+ IP_MULTICAST_LOOP : constant := 11; -- Set/get mcast loopback
+
+end GNAT.Sockets.Constants;
diff --git a/gcc/ada/g-soccon-hpux.ads b/gcc/ada/g-soccon-hpux.ads
new file mode 100644
index 00000000000..cbca2bee7a5
--- /dev/null
+++ b/gcc/ada/g-soccon-hpux.ads
@@ -0,0 +1,158 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . S O C K E T S . C O N S T A N T S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2000-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides target dependent definitions of constant for use
+-- by the GNAT.Sockets package (g-socket.ads). This package should not be
+-- directly with'ed by an applications program.
+
+-- This is the version for HP/UX
+
+package GNAT.Sockets.Constants is
+
+ --------------
+ -- Families --
+ --------------
+
+ AF_INET : constant := 2; -- IPv4 address family
+ AF_INET6 : constant := 26; -- IPv6 address family
+
+ -----------
+ -- Modes --
+ -----------
+
+ SOCK_STREAM : constant := 1; -- Stream socket
+ SOCK_DGRAM : constant := 2; -- Datagram socket
+
+ -------------------
+ -- Socket errors --
+ -------------------
+
+ EACCES : constant := 13; -- Permission denied
+ EADDRINUSE : constant := 226; -- Address already in use
+ EADDRNOTAVAIL : constant := 227; -- Cannot assign address
+ EAFNOSUPPORT : constant := 225; -- Addr family not supported
+ EALREADY : constant := 244; -- Operation in progress
+ EBADF : constant := 9; -- Bad file descriptor
+ ECONNABORTED : constant := 231; -- Connection aborted
+ ECONNREFUSED : constant := 239; -- Connection refused
+ ECONNRESET : constant := 232; -- Connection reset by peer
+ EDESTADDRREQ : constant := 217; -- Destination addr required
+ EFAULT : constant := 14; -- Bad address
+ EHOSTDOWN : constant := 241; -- Host is down
+ EHOSTUNREACH : constant := 242; -- No route to host
+ EINPROGRESS : constant := 245; -- Operation now in progress
+ EINTR : constant := 4; -- Interrupted system call
+ EINVAL : constant := 22; -- Invalid argument
+ EIO : constant := 5; -- Input output error
+ EISCONN : constant := 234; -- Socket already connected
+ ELOOP : constant := 249; -- Too many symbolic lynks
+ EMFILE : constant := 24; -- Too many open files
+ EMSGSIZE : constant := 218; -- Message too long
+ ENAMETOOLONG : constant := 248; -- Name too long
+ ENETDOWN : constant := 228; -- Network is down
+ ENETRESET : constant := 230; -- Disconn. on network reset
+ ENETUNREACH : constant := 229; -- Network is unreachable
+ ENOBUFS : constant := 233; -- No buffer space available
+ ENOPROTOOPT : constant := 220; -- Protocol not available
+ ENOTCONN : constant := 235; -- Socket not connected
+ ENOTSOCK : constant := 216; -- Operation on non socket
+ EOPNOTSUPP : constant := 223; -- Operation not supported
+ EPFNOSUPPORT : constant := 224; -- Unknown protocol family
+ EPROTONOSUPPORT : constant := 221; -- Unknown protocol
+ EPROTOTYPE : constant := 219; -- Unknown protocol type
+ ESHUTDOWN : constant := 236; -- Cannot send once shutdown
+ ESOCKTNOSUPPORT : constant := 222; -- Socket type not supported
+ ETIMEDOUT : constant := 238; -- Connection timed out
+ ETOOMANYREFS : constant := 237; -- Too many references
+ EWOULDBLOCK : constant := 246; -- Operation would block
+
+ -----------------
+ -- Host errors --
+ -----------------
+
+ HOST_NOT_FOUND : constant := 1; -- Unknown host
+ TRY_AGAIN : constant := 2; -- Host name lookup failure
+ NO_DATA : constant := 4; -- No data record for name
+ NO_RECOVERY : constant := 3; -- Non recoverable errors
+
+ -------------------
+ -- Control flags --
+ -------------------
+
+ FIONBIO : constant := -2147195266; -- Set/clear non-blocking io
+ FIONREAD : constant := 1074030207; -- How many bytes to read
+
+ --------------------
+ -- Shutdown modes --
+ --------------------
+
+ SHUT_RD : constant := 0; -- No more recv
+ SHUT_WR : constant := 1; -- No more send
+ SHUT_RDWR : constant := 2; -- No more recv/send
+
+ ---------------------
+ -- Protocol levels --
+ ---------------------
+
+ SOL_SOCKET : constant := 65535; -- Options for socket level
+ IPPROTO_IP : constant := 0; -- Dummy protocol for IP
+ IPPROTO_UDP : constant := 17; -- UDP
+ IPPROTO_TCP : constant := 6; -- TCP
+
+ -------------------
+ -- Request flags --
+ -------------------
+
+ MSG_OOB : constant := 1; -- Process out-of-band data
+ MSG_PEEK : constant := 2; -- Peek at incoming data
+ MSG_EOR : constant := 8; -- Send end of record
+ MSG_WAITALL : constant := 64; -- Wait for full reception
+
+ --------------------
+ -- Socket options --
+ --------------------
+
+ TCP_NODELAY : constant := 1; -- Do not coalesce packets
+ SO_SNDBUF : constant := 4097; -- Set/get send buffer size
+ SO_RCVBUF : constant := 4098; -- Set/get recv buffer size
+ SO_REUSEADDR : constant := 4; -- Bind reuse local address
+ SO_KEEPALIVE : constant := 8; -- Enable keep-alive msgs
+ SO_LINGER : constant := 128; -- Defer close to flush data
+ SO_ERROR : constant := 4103; -- Get/clear error status
+ SO_BROADCAST : constant := 32; -- Can send broadcast msgs
+ IP_ADD_MEMBERSHIP : constant := 5; -- Join a multicast group
+ IP_DROP_MEMBERSHIP : constant := 6; -- Leave a multicast group
+ IP_MULTICAST_TTL : constant := 3; -- Set/get multicast TTL
+ IP_MULTICAST_LOOP : constant := 4; -- Set/get mcast loopback
+
+end GNAT.Sockets.Constants;
diff --git a/gcc/ada/g-soccon-interix.ads b/gcc/ada/g-soccon-interix.ads
new file mode 100644
index 00000000000..61903079b82
--- /dev/null
+++ b/gcc/ada/g-soccon-interix.ads
@@ -0,0 +1,158 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . S O C K E T S . C O N S T A N T S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2000-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides target dependent definitions of constant for use
+-- by the GNAT.Sockets package (g-socket.ads). This package should not be
+-- directly with'ed by an applications program.
+
+-- This is the version for Interix
+
+package GNAT.Sockets.Constants is
+
+ --------------
+ -- Families --
+ --------------
+
+ AF_INET : constant := 2; -- IPv4 address family
+ AF_INET6 : constant := -1; -- IPv6 address family
+
+ -----------
+ -- Modes --
+ -----------
+
+ SOCK_STREAM : constant := 1; -- Stream socket
+ SOCK_DGRAM : constant := 2; -- Datagram socket
+
+ -------------------
+ -- Socket errors --
+ -------------------
+
+ EACCES : constant := 13; -- Permission denied
+ EADDRINUSE : constant := 48; -- Address already in use
+ EADDRNOTAVAIL : constant := 49; -- Cannot assign address
+ EAFNOSUPPORT : constant := 47; -- Addr family not supported
+ EALREADY : constant := 37; -- Operation in progress
+ EBADF : constant := 9; -- Bad file descriptor
+ ECONNABORTED : constant := 53; -- Connection aborted
+ ECONNREFUSED : constant := 61; -- Connection refused
+ ECONNRESET : constant := 54; -- Connection reset by peer
+ EDESTADDRREQ : constant := 82; -- Destination addr required
+ EFAULT : constant := 14; -- Bad address
+ EHOSTDOWN : constant := 64; -- Host is down
+ EHOSTUNREACH : constant := 65; -- No route to host
+ EINPROGRESS : constant := 80; -- Operation now in progress
+ EINTR : constant := 4; -- Interrupted system call
+ EINVAL : constant := 22; -- Invalid argument
+ EIO : constant := 5; -- Input output error
+ EISCONN : constant := 56; -- Socket already connected
+ ELOOP : constant := 62; -- Too many symbolic lynks
+ EMFILE : constant := 24; -- Too many open files
+ EMSGSIZE : constant := 83; -- Message too long
+ ENAMETOOLONG : constant := 38; -- Name too long
+ ENETDOWN : constant := 50; -- Network is down
+ ENETRESET : constant := 52; -- Disconn. on network reset
+ ENETUNREACH : constant := 51; -- Network is unreachable
+ ENOBUFS : constant := 55; -- No buffer space available
+ ENOPROTOOPT : constant := 85; -- Protocol not available
+ ENOTCONN : constant := 57; -- Socket not connected
+ ENOTSOCK : constant := 81; -- Operation on non socket
+ EOPNOTSUPP : constant := 45; -- Operation not supported
+ EPFNOSUPPORT : constant := 46; -- Unknown protocol family
+ EPROTONOSUPPORT : constant := 43; -- Unknown protocol
+ EPROTOTYPE : constant := 84; -- Unknown protocol type
+ ESHUTDOWN : constant := 58; -- Cannot send once shutdown
+ ESOCKTNOSUPPORT : constant := 44; -- Socket type not supported
+ ETIMEDOUT : constant := 60; -- Connection timed out
+ ETOOMANYREFS : constant := 59; -- Too many references
+ EWOULDBLOCK : constant := 11; -- Operation would block
+
+ -----------------
+ -- Host errors --
+ -----------------
+
+ HOST_NOT_FOUND : constant := 90; -- Unknown host
+ TRY_AGAIN : constant := 91; -- Host name lookup failure
+ NO_DATA : constant := 93; -- No data record for name
+ NO_RECOVERY : constant := 92; -- Non recoverable errors
+
+ -------------------
+ -- Control flags --
+ -------------------
+
+ FIONBIO : constant := -2147195390; -- Set/clear non-blocking io
+ FIONREAD : constant := 1074030081; -- How many bytes to read
+
+ --------------------
+ -- Shutdown modes --
+ --------------------
+
+ SHUT_RD : constant := 0; -- No more recv
+ SHUT_WR : constant := 1; -- No more send
+ SHUT_RDWR : constant := 2; -- No more recv/send
+
+ ---------------------
+ -- Protocol levels --
+ ---------------------
+
+ SOL_SOCKET : constant := 65535; -- Options for socket level
+ IPPROTO_IP : constant := 0; -- Dummy protocol for IP
+ IPPROTO_UDP : constant := 17; -- UDP
+ IPPROTO_TCP : constant := 6; -- TCP
+
+ -------------------
+ -- Request flags --
+ -------------------
+
+ MSG_OOB : constant := 1; -- Process out-of-band data
+ MSG_PEEK : constant := 2; -- Peek at incoming data
+ MSG_EOR : constant := 8; -- Send end of record
+ MSG_WAITALL : constant := 64; -- Wait for full reception
+
+ --------------------
+ -- Socket options --
+ --------------------
+
+ TCP_NODELAY : constant := 1; -- Do not coalesce packets
+ SO_SNDBUF : constant := 4097; -- Set/get send buffer size
+ SO_RCVBUF : constant := 4098; -- Set/get recv buffer size
+ SO_REUSEADDR : constant := 4; -- Bind reuse local address
+ SO_KEEPALIVE : constant := 8; -- Enable keep-alive msgs
+ SO_LINGER : constant := 128; -- Defer close to flush data
+ SO_ERROR : constant := 4103; -- Get/clear error status
+ SO_BROADCAST : constant := 32; -- Can send broadcast msgs
+ IP_ADD_MEMBERSHIP : constant := 5; -- Join a multicast group
+ IP_DROP_MEMBERSHIP : constant := 6; -- Leave a multicast group
+ IP_MULTICAST_TTL : constant := 3; -- Set/get multicast TTL
+ IP_MULTICAST_LOOP : constant := 4; -- Set/get mcast loopback
+
+end GNAT.Sockets.Constants;
diff --git a/gcc/ada/g-soccon-irix.ads b/gcc/ada/g-soccon-irix.ads
new file mode 100644
index 00000000000..f19f3cde5f6
--- /dev/null
+++ b/gcc/ada/g-soccon-irix.ads
@@ -0,0 +1,158 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . S O C K E T S . C O N S T A N T S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2000-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides target dependent definitions of constant for use
+-- by the GNAT.Sockets package (g-socket.ads). This package should not be
+-- directly with'ed by an applications program.
+
+-- This is the version for SGI
+
+package GNAT.Sockets.Constants is
+
+ --------------
+ -- Families --
+ --------------
+
+ AF_INET : constant := 2; -- IPv4 address family
+ AF_INET6 : constant := 24; -- IPv6 address family
+
+ -----------
+ -- Modes --
+ -----------
+
+ SOCK_STREAM : constant := 2; -- Stream socket
+ SOCK_DGRAM : constant := 1; -- Datagram socket
+
+ -------------------
+ -- Socket errors --
+ -------------------
+
+ EACCES : constant := 13; -- Permission denied
+ EADDRINUSE : constant := 125; -- Address already in use
+ EADDRNOTAVAIL : constant := 126; -- Cannot assign address
+ EAFNOSUPPORT : constant := 124; -- Addr family not supported
+ EALREADY : constant := 149; -- Operation in progress
+ EBADF : constant := 9; -- Bad file descriptor
+ ECONNABORTED : constant := 130; -- Connection aborted
+ ECONNREFUSED : constant := 146; -- Connection refused
+ ECONNRESET : constant := 131; -- Connection reset by peer
+ EDESTADDRREQ : constant := 96; -- Destination addr required
+ EFAULT : constant := 14; -- Bad address
+ EHOSTDOWN : constant := 147; -- Host is down
+ EHOSTUNREACH : constant := 148; -- No route to host
+ EINPROGRESS : constant := 150; -- Operation now in progress
+ EINTR : constant := 4; -- Interrupted system call
+ EINVAL : constant := 22; -- Invalid argument
+ EIO : constant := 5; -- Input output error
+ EISCONN : constant := 133; -- Socket already connected
+ ELOOP : constant := 90; -- Too many symbolic lynks
+ EMFILE : constant := 24; -- Too many open files
+ EMSGSIZE : constant := 97; -- Message too long
+ ENAMETOOLONG : constant := 78; -- Name too long
+ ENETDOWN : constant := 127; -- Network is down
+ ENETRESET : constant := 129; -- Disconn. on network reset
+ ENETUNREACH : constant := 128; -- Network is unreachable
+ ENOBUFS : constant := 132; -- No buffer space available
+ ENOPROTOOPT : constant := 99; -- Protocol not available
+ ENOTCONN : constant := 134; -- Socket not connected
+ ENOTSOCK : constant := 95; -- Operation on non socket
+ EOPNOTSUPP : constant := 122; -- Operation not supported
+ EPFNOSUPPORT : constant := 123; -- Unknown protocol family
+ EPROTONOSUPPORT : constant := 120; -- Unknown protocol
+ EPROTOTYPE : constant := 98; -- Unknown protocol type
+ ESHUTDOWN : constant := 143; -- Cannot send once shutdown
+ ESOCKTNOSUPPORT : constant := 121; -- Socket type not supported
+ ETIMEDOUT : constant := 145; -- Connection timed out
+ ETOOMANYREFS : constant := 144; -- Too many references
+ EWOULDBLOCK : constant := 11; -- Operation would block
+
+ -----------------
+ -- Host errors --
+ -----------------
+
+ HOST_NOT_FOUND : constant := 1; -- Unknown host
+ TRY_AGAIN : constant := 2; -- Host name lookup failure
+ NO_DATA : constant := 4; -- No data record for name
+ NO_RECOVERY : constant := 3; -- Non recoverable errors
+
+ -------------------
+ -- Control flags --
+ -------------------
+
+ FIONBIO : constant := -2147195266; -- Set/clear non-blocking io
+ FIONREAD : constant := 1074030207; -- How many bytes to read
+
+ --------------------
+ -- Shutdown modes --
+ --------------------
+
+ SHUT_RD : constant := 0; -- No more recv
+ SHUT_WR : constant := 1; -- No more send
+ SHUT_RDWR : constant := 2; -- No more recv/send
+
+ ---------------------
+ -- Protocol levels --
+ ---------------------
+
+ SOL_SOCKET : constant := 65535; -- Options for socket level
+ IPPROTO_IP : constant := 0; -- Dummy protocol for IP
+ IPPROTO_UDP : constant := 17; -- UDP
+ IPPROTO_TCP : constant := 6; -- TCP
+
+ -------------------
+ -- Request flags --
+ -------------------
+
+ MSG_OOB : constant := 1; -- Process out-of-band data
+ MSG_PEEK : constant := 2; -- Peek at incoming data
+ MSG_EOR : constant := 8; -- Send end of record
+ MSG_WAITALL : constant := 64; -- Wait for full reception
+
+ --------------------
+ -- Socket options --
+ --------------------
+
+ TCP_NODELAY : constant := 1; -- Do not coalesce packets
+ SO_SNDBUF : constant := 4097; -- Set/get send buffer size
+ SO_RCVBUF : constant := 4098; -- Set/get recv buffer size
+ SO_REUSEADDR : constant := 4; -- Bind reuse local address
+ SO_KEEPALIVE : constant := 8; -- Enable keep-alive msgs
+ SO_LINGER : constant := 128; -- Defer close to flush data
+ SO_ERROR : constant := 4103; -- Get/clear error status
+ SO_BROADCAST : constant := 32; -- Can send broadcast msgs
+ IP_ADD_MEMBERSHIP : constant := 23; -- Join a multicast group
+ IP_DROP_MEMBERSHIP : constant := 24; -- Leave a multicast group
+ IP_MULTICAST_TTL : constant := 21; -- Set/get multicast TTL
+ IP_MULTICAST_LOOP : constant := 22; -- Set/get mcast loopback
+
+end GNAT.Sockets.Constants;
diff --git a/gcc/ada/g-soccon-mingw.ads b/gcc/ada/g-soccon-mingw.ads
new file mode 100644
index 00000000000..b4bb31564dc
--- /dev/null
+++ b/gcc/ada/g-soccon-mingw.ads
@@ -0,0 +1,158 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . S O C K E T S . C O N S T A N T S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2000-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides target dependent definitions of constant for use
+-- by the GNAT.Sockets package (g-socket.ads). This package should not be
+-- directly with'ed by an applications program.
+
+-- This is the version for MINGW32 NT
+
+package GNAT.Sockets.Constants is
+
+ --------------
+ -- Families --
+ --------------
+
+ AF_INET : constant := 2; -- IPv4 address family
+ AF_INET6 : constant := 3; -- IPv6 address family
+
+ -----------
+ -- Modes --
+ -----------
+
+ SOCK_STREAM : constant := 1; -- Stream socket
+ SOCK_DGRAM : constant := 2; -- Datagram socket
+
+ -------------------
+ -- Socket errors --
+ -------------------
+
+ EACCES : constant := 10013; -- Permission denied
+ EADDRINUSE : constant := 10048; -- Address already in use
+ EADDRNOTAVAIL : constant := 10049; -- Cannot assign address
+ EAFNOSUPPORT : constant := 10047; -- Addr family not supported
+ EALREADY : constant := 10037; -- Operation in progress
+ EBADF : constant := 10009; -- Bad file descriptor
+ ECONNABORTED : constant := 10053; -- Connection aborted
+ ECONNREFUSED : constant := 10061; -- Connection refused
+ ECONNRESET : constant := 10054; -- Connection reset by peer
+ EDESTADDRREQ : constant := 10039; -- Destination addr required
+ EFAULT : constant := 10014; -- Bad address
+ EHOSTDOWN : constant := 10064; -- Host is down
+ EHOSTUNREACH : constant := 10065; -- No route to host
+ EINPROGRESS : constant := 10036; -- Operation now in progress
+ EINTR : constant := 10004; -- Interrupted system call
+ EINVAL : constant := 10022; -- Invalid argument
+ EIO : constant := 10101; -- Input output error
+ EISCONN : constant := 10056; -- Socket already connected
+ ELOOP : constant := 10062; -- Too many symbolic lynks
+ EMFILE : constant := 10024; -- Too many open files
+ EMSGSIZE : constant := 10040; -- Message too long
+ ENAMETOOLONG : constant := 10063; -- Name too long
+ ENETDOWN : constant := 10050; -- Network is down
+ ENETRESET : constant := 10052; -- Disconn. on network reset
+ ENETUNREACH : constant := 10051; -- Network is unreachable
+ ENOBUFS : constant := 10055; -- No buffer space available
+ ENOPROTOOPT : constant := 10042; -- Protocol not available
+ ENOTCONN : constant := 10057; -- Socket not connected
+ ENOTSOCK : constant := 10038; -- Operation on non socket
+ EOPNOTSUPP : constant := 10045; -- Operation not supported
+ EPFNOSUPPORT : constant := 10046; -- Unknown protocol family
+ EPROTONOSUPPORT : constant := 10043; -- Unknown protocol
+ EPROTOTYPE : constant := 10041; -- Unknown protocol type
+ ESHUTDOWN : constant := 10058; -- Cannot send once shutdown
+ ESOCKTNOSUPPORT : constant := 10044; -- Socket type not supported
+ ETIMEDOUT : constant := 10060; -- Connection timed out
+ ETOOMANYREFS : constant := 10059; -- Too many references
+ EWOULDBLOCK : constant := 10035; -- Operation would block
+
+ -----------------
+ -- Host errors --
+ -----------------
+
+ HOST_NOT_FOUND : constant := 11001; -- Unknown host
+ TRY_AGAIN : constant := 11002; -- Host name lookup failure
+ NO_DATA : constant := 11004; -- No data record for name
+ NO_RECOVERY : constant := 11003; -- Non recoverable errors
+
+ -------------------
+ -- Control flags --
+ -------------------
+
+ FIONBIO : constant := -2147195266; -- Set/clear non-blocking io
+ FIONREAD : constant := 1074030207; -- How many bytes to read
+
+ --------------------
+ -- Shutdown modes --
+ --------------------
+
+ SHUT_RD : constant := 0; -- No more recv
+ SHUT_WR : constant := 1; -- No more send
+ SHUT_RDWR : constant := 2; -- No more recv/send
+
+ ---------------------
+ -- Protocol levels --
+ ---------------------
+
+ SOL_SOCKET : constant := 65535; -- Options for socket level
+ IPPROTO_IP : constant := 0; -- Dummy protocol for IP
+ IPPROTO_UDP : constant := 17; -- UDP
+ IPPROTO_TCP : constant := 6; -- TCP
+
+ -------------------
+ -- Request flags --
+ -------------------
+
+ MSG_OOB : constant := 1; -- Process out-of-band data
+ MSG_PEEK : constant := 2; -- Peek at incoming data
+ MSG_EOR : constant := -1; -- Send end of record
+ MSG_WAITALL : constant := -1; -- Wait for full reception
+
+ --------------------
+ -- Socket options --
+ --------------------
+
+ TCP_NODELAY : constant := 1; -- Do not coalesce packets
+ SO_SNDBUF : constant := 4097; -- Set/get send buffer size
+ SO_RCVBUF : constant := 4098; -- Set/get recv buffer size
+ SO_REUSEADDR : constant := 4; -- Bind reuse local address
+ SO_KEEPALIVE : constant := 8; -- Enable keep-alive msgs
+ SO_LINGER : constant := 128; -- Defer close to flush data
+ SO_ERROR : constant := 4103; -- Get/clear error status
+ SO_BROADCAST : constant := 32; -- Can send broadcast msgs
+ IP_ADD_MEMBERSHIP : constant := 5; -- Join a multicast group
+ IP_DROP_MEMBERSHIP : constant := 6; -- Leave a multicast group
+ IP_MULTICAST_TTL : constant := 3; -- Set/get multicast TTL
+ IP_MULTICAST_LOOP : constant := 4; -- Set/get mcast loopback
+
+end GNAT.Sockets.Constants;
diff --git a/gcc/ada/g-soccon-solaris.ads b/gcc/ada/g-soccon-solaris.ads
new file mode 100644
index 00000000000..1ad58838ca9
--- /dev/null
+++ b/gcc/ada/g-soccon-solaris.ads
@@ -0,0 +1,158 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . S O C K E T S . C O N S T A N T S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2000-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides target dependent definitions of constant for use
+-- by the GNAT.Sockets package (g-socket.ads). This package should not be
+-- directly with'ed by an applications program.
+
+-- This is the version for Solaris
+
+package GNAT.Sockets.Constants is
+
+ --------------
+ -- Families --
+ --------------
+
+ AF_INET : constant := 2; -- IPv4 address family
+ AF_INET6 : constant := 26; -- IPv6 address family
+
+ -----------
+ -- Modes --
+ -----------
+
+ SOCK_STREAM : constant := 2; -- Stream socket
+ SOCK_DGRAM : constant := 1; -- Datagram socket
+
+ -------------------
+ -- Socket errors --
+ -------------------
+
+ EACCES : constant := 13; -- Permission denied
+ EADDRINUSE : constant := 125; -- Address already in use
+ EADDRNOTAVAIL : constant := 126; -- Cannot assign address
+ EAFNOSUPPORT : constant := 124; -- Addr family not supported
+ EALREADY : constant := 149; -- Operation in progress
+ EBADF : constant := 9; -- Bad file descriptor
+ ECONNABORTED : constant := 130; -- Connection aborted
+ ECONNREFUSED : constant := 146; -- Connection refused
+ ECONNRESET : constant := 131; -- Connection reset by peer
+ EDESTADDRREQ : constant := 96; -- Destination addr required
+ EFAULT : constant := 14; -- Bad address
+ EHOSTDOWN : constant := 147; -- Host is down
+ EHOSTUNREACH : constant := 148; -- No route to host
+ EINPROGRESS : constant := 150; -- Operation now in progress
+ EINTR : constant := 4; -- Interrupted system call
+ EINVAL : constant := 22; -- Invalid argument
+ EIO : constant := 5; -- Input output error
+ EISCONN : constant := 133; -- Socket already connected
+ ELOOP : constant := 90; -- Too many symbolic lynks
+ EMFILE : constant := 24; -- Too many open files
+ EMSGSIZE : constant := 97; -- Message too long
+ ENAMETOOLONG : constant := 78; -- Name too long
+ ENETDOWN : constant := 127; -- Network is down
+ ENETRESET : constant := 129; -- Disconn. on network reset
+ ENETUNREACH : constant := 128; -- Network is unreachable
+ ENOBUFS : constant := 132; -- No buffer space available
+ ENOPROTOOPT : constant := 99; -- Protocol not available
+ ENOTCONN : constant := 134; -- Socket not connected
+ ENOTSOCK : constant := 95; -- Operation on non socket
+ EOPNOTSUPP : constant := 122; -- Operation not supported
+ EPFNOSUPPORT : constant := 123; -- Unknown protocol family
+ EPROTONOSUPPORT : constant := 120; -- Unknown protocol
+ EPROTOTYPE : constant := 98; -- Unknown protocol type
+ ESHUTDOWN : constant := 143; -- Cannot send once shutdown
+ ESOCKTNOSUPPORT : constant := 121; -- Socket type not supported
+ ETIMEDOUT : constant := 145; -- Connection timed out
+ ETOOMANYREFS : constant := 144; -- Too many references
+ EWOULDBLOCK : constant := 11; -- Operation would block
+
+ -----------------
+ -- Host errors --
+ -----------------
+
+ HOST_NOT_FOUND : constant := 1; -- Unknown host
+ TRY_AGAIN : constant := 2; -- Host name lookup failure
+ NO_DATA : constant := 4; -- No data record for name
+ NO_RECOVERY : constant := 3; -- Non recoverable errors
+
+ -------------------
+ -- Control flags --
+ -------------------
+
+ FIONBIO : constant := -2147195266; -- Set/clear non-blocking io
+ FIONREAD : constant := 1074030207; -- How many bytes to read
+
+ --------------------
+ -- Shutdown modes --
+ --------------------
+
+ SHUT_RD : constant := 0; -- No more recv
+ SHUT_WR : constant := 1; -- No more send
+ SHUT_RDWR : constant := 2; -- No more recv/send
+
+ ---------------------
+ -- Protocol levels --
+ ---------------------
+
+ SOL_SOCKET : constant := 65535; -- Options for socket level
+ IPPROTO_IP : constant := 0; -- Dummy protocol for IP
+ IPPROTO_UDP : constant := 17; -- UDP
+ IPPROTO_TCP : constant := 6; -- TCP
+
+ -------------------
+ -- Request flags --
+ -------------------
+
+ MSG_OOB : constant := 1; -- Process out-of-band data
+ MSG_PEEK : constant := 2; -- Peek at incoming data
+ MSG_EOR : constant := 8; -- Send end of record
+ MSG_WAITALL : constant := 64; -- Wait for full reception
+
+ --------------------
+ -- Socket options --
+ --------------------
+
+ TCP_NODELAY : constant := 1; -- Do not coalesce packets
+ SO_SNDBUF : constant := 4097; -- Set/get send buffer size
+ SO_RCVBUF : constant := 4098; -- Set/get recv buffer size
+ SO_REUSEADDR : constant := 4; -- Bind reuse local address
+ SO_KEEPALIVE : constant := 8; -- Enable keep-alive msgs
+ SO_LINGER : constant := 128; -- Defer close to flush data
+ SO_ERROR : constant := 4103; -- Get/clear error status
+ SO_BROADCAST : constant := 32; -- Can send broadcast msgs
+ IP_ADD_MEMBERSHIP : constant := 19; -- Join a multicast group
+ IP_DROP_MEMBERSHIP : constant := 20; -- Leave a multicast group
+ IP_MULTICAST_TTL : constant := 17; -- Set/get multicast TTL
+ IP_MULTICAST_LOOP : constant := 18; -- Set/get mcast loopback
+
+end GNAT.Sockets.Constants;
diff --git a/gcc/ada/g-soccon-tru64.ads b/gcc/ada/g-soccon-tru64.ads
new file mode 100644
index 00000000000..ef3536e4bbc
--- /dev/null
+++ b/gcc/ada/g-soccon-tru64.ads
@@ -0,0 +1,158 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . S O C K E T S . C O N S T A N T S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2000-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides target dependent definitions of constant for use
+-- by the GNAT.Sockets package (g-socket.ads). This package should not be
+-- directly with'ed by an applications program.
+
+-- This is the version for OSF
+
+package GNAT.Sockets.Constants is
+
+ --------------
+ -- Families --
+ --------------
+
+ AF_INET : constant := 2; -- IPv4 address family
+ AF_INET6 : constant := 26; -- IPv6 address family
+
+ -----------
+ -- Modes --
+ -----------
+
+ SOCK_STREAM : constant := 1; -- Stream socket
+ SOCK_DGRAM : constant := 2; -- Datagram socket
+
+ -------------------
+ -- Socket errors --
+ -------------------
+
+ EACCES : constant := 13; -- Permission denied
+ EADDRINUSE : constant := 48; -- Address already in use
+ EADDRNOTAVAIL : constant := 49; -- Cannot assign address
+ EAFNOSUPPORT : constant := 47; -- Addr family not supported
+ EALREADY : constant := 37; -- Operation in progress
+ EBADF : constant := 9; -- Bad file descriptor
+ ECONNABORTED : constant := 53; -- Connection aborted
+ ECONNREFUSED : constant := 61; -- Connection refused
+ ECONNRESET : constant := 54; -- Connection reset by peer
+ EDESTADDRREQ : constant := 39; -- Destination addr required
+ EFAULT : constant := 14; -- Bad address
+ EHOSTDOWN : constant := 64; -- Host is down
+ EHOSTUNREACH : constant := 65; -- No route to host
+ EINPROGRESS : constant := 36; -- Operation now in progress
+ EINTR : constant := 4; -- Interrupted system call
+ EINVAL : constant := 22; -- Invalid argument
+ EIO : constant := 5; -- Input output error
+ EISCONN : constant := 56; -- Socket already connected
+ ELOOP : constant := 62; -- Too many symbolic lynks
+ EMFILE : constant := 24; -- Too many open files
+ EMSGSIZE : constant := 40; -- Message too long
+ ENAMETOOLONG : constant := 63; -- Name too long
+ ENETDOWN : constant := 50; -- Network is down
+ ENETRESET : constant := 52; -- Disconn. on network reset
+ ENETUNREACH : constant := 51; -- Network is unreachable
+ ENOBUFS : constant := 55; -- No buffer space available
+ ENOPROTOOPT : constant := 42; -- Protocol not available
+ ENOTCONN : constant := 57; -- Socket not connected
+ ENOTSOCK : constant := 38; -- Operation on non socket
+ EOPNOTSUPP : constant := 45; -- Operation not supported
+ EPFNOSUPPORT : constant := 46; -- Unknown protocol family
+ EPROTONOSUPPORT : constant := 43; -- Unknown protocol
+ EPROTOTYPE : constant := 41; -- Unknown protocol type
+ ESHUTDOWN : constant := 58; -- Cannot send once shutdown
+ ESOCKTNOSUPPORT : constant := 44; -- Socket type not supported
+ ETIMEDOUT : constant := 60; -- Connection timed out
+ ETOOMANYREFS : constant := 59; -- Too many references
+ EWOULDBLOCK : constant := 35; -- Operation would block
+
+ -----------------
+ -- Host errors --
+ -----------------
+
+ HOST_NOT_FOUND : constant := 1; -- Unknown host
+ TRY_AGAIN : constant := 2; -- Host name lookup failure
+ NO_DATA : constant := 4; -- No data record for name
+ NO_RECOVERY : constant := 3; -- Non recoverable errors
+
+ -------------------
+ -- Control flags --
+ -------------------
+
+ FIONBIO : constant := -2147195266; -- Set/clear non-blocking io
+ FIONREAD : constant := 1074030207; -- How many bytes to read
+
+ --------------------
+ -- Shutdown modes --
+ --------------------
+
+ SHUT_RD : constant := 0; -- No more recv
+ SHUT_WR : constant := 1; -- No more send
+ SHUT_RDWR : constant := 2; -- No more recv/send
+
+ ---------------------
+ -- Protocol levels --
+ ---------------------
+
+ SOL_SOCKET : constant := 65535; -- Options for socket level
+ IPPROTO_IP : constant := 0; -- Dummy protocol for IP
+ IPPROTO_UDP : constant := 17; -- UDP
+ IPPROTO_TCP : constant := 6; -- TCP
+
+ -------------------
+ -- Request flags --
+ -------------------
+
+ MSG_OOB : constant := 1; -- Process out-of-band data
+ MSG_PEEK : constant := 2; -- Peek at incoming data
+ MSG_EOR : constant := 8; -- Send end of record
+ MSG_WAITALL : constant := 64; -- Wait for full reception
+
+ --------------------
+ -- Socket options --
+ --------------------
+
+ TCP_NODELAY : constant := 1; -- Do not coalesce packets
+ SO_SNDBUF : constant := 4097; -- Set/get send buffer size
+ SO_RCVBUF : constant := 4098; -- Set/get recv buffer size
+ SO_REUSEADDR : constant := 4; -- Bind reuse local address
+ SO_KEEPALIVE : constant := 8; -- Enable keep-alive msgs
+ SO_LINGER : constant := 128; -- Defer close to flush data
+ SO_ERROR : constant := 4103; -- Get/clear error status
+ SO_BROADCAST : constant := 32; -- Can send broadcast msgs
+ IP_ADD_MEMBERSHIP : constant := 12; -- Join a multicast group
+ IP_DROP_MEMBERSHIP : constant := 13; -- Leave a multicast group
+ IP_MULTICAST_TTL : constant := 10; -- Set/get multicast TTL
+ IP_MULTICAST_LOOP : constant := 11; -- Set/get mcast loopback
+
+end GNAT.Sockets.Constants;
diff --git a/gcc/ada/g-soccon-unixware.ads b/gcc/ada/g-soccon-unixware.ads
new file mode 100644
index 00000000000..9f7065f6ffe
--- /dev/null
+++ b/gcc/ada/g-soccon-unixware.ads
@@ -0,0 +1,158 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . S O C K E T S . C O N S T A N T S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2000-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides target dependent definitions of constant for use
+-- by the GNAT.Sockets package (g-socket.ads). This package should not be
+-- directly with'ed by an applications program.
+
+-- This is the version for UnixWare
+
+package GNAT.Sockets.Constants is
+
+ --------------
+ -- Families --
+ --------------
+
+ AF_INET : constant := 2; -- IPv4 address family
+ AF_INET6 : constant := 27; -- IPv6 address family
+
+ -----------
+ -- Modes --
+ -----------
+
+ SOCK_STREAM : constant := 2; -- Stream socket
+ SOCK_DGRAM : constant := 1; -- Datagram socket
+
+ -------------------
+ -- Socket errors --
+ -------------------
+
+ EACCES : constant := 13; -- Permission denied
+ EADDRINUSE : constant := 125; -- Address already in use
+ EADDRNOTAVAIL : constant := 126; -- Cannot assign address
+ EAFNOSUPPORT : constant := 124; -- Addr family not supported
+ EALREADY : constant := 149; -- Operation in progress
+ EBADF : constant := 9; -- Bad file descriptor
+ ECONNABORTED : constant := 130; -- Connection aborted
+ ECONNREFUSED : constant := 146; -- Connection refused
+ ECONNRESET : constant := 131; -- Connection reset by peer
+ EDESTADDRREQ : constant := 96; -- Destination addr required
+ EFAULT : constant := 14; -- Bad address
+ EHOSTDOWN : constant := 147; -- Host is down
+ EHOSTUNREACH : constant := 148; -- No route to host
+ EINPROGRESS : constant := 150; -- Operation now in progress
+ EINTR : constant := 4; -- Interrupted system call
+ EINVAL : constant := 22; -- Invalid argument
+ EIO : constant := 5; -- Input output error
+ EISCONN : constant := 133; -- Socket already connected
+ ELOOP : constant := 90; -- Too many symbolic lynks
+ EMFILE : constant := 24; -- Too many open files
+ EMSGSIZE : constant := 97; -- Message too long
+ ENAMETOOLONG : constant := 78; -- Name too long
+ ENETDOWN : constant := 127; -- Network is down
+ ENETRESET : constant := 129; -- Disconn. on network reset
+ ENETUNREACH : constant := 128; -- Network is unreachable
+ ENOBUFS : constant := 132; -- No buffer space available
+ ENOPROTOOPT : constant := 99; -- Protocol not available
+ ENOTCONN : constant := 134; -- Socket not connected
+ ENOTSOCK : constant := 95; -- Operation on non socket
+ EOPNOTSUPP : constant := 122; -- Operation not supported
+ EPFNOSUPPORT : constant := 123; -- Unknown protocol family
+ EPROTONOSUPPORT : constant := 120; -- Unknown protocol
+ EPROTOTYPE : constant := 98; -- Unknown protocol type
+ ESHUTDOWN : constant := 143; -- Cannot send once shutdown
+ ESOCKTNOSUPPORT : constant := 121; -- Socket type not supported
+ ETIMEDOUT : constant := 145; -- Connection timed out
+ ETOOMANYREFS : constant := 144; -- Too many references
+ EWOULDBLOCK : constant := 11; -- Operation would block
+
+ -----------------
+ -- Host errors --
+ -----------------
+
+ HOST_NOT_FOUND : constant := 1; -- Unknown host
+ TRY_AGAIN : constant := 2; -- Host name lookup failure
+ NO_DATA : constant := 4; -- No data record for name
+ NO_RECOVERY : constant := 3; -- Non recoverable errors
+
+ -------------------
+ -- Control flags --
+ -------------------
+
+ FIONBIO : constant := -2147195266; -- Set/clear non-blocking io
+ FIONREAD : constant := 1074030207; -- How many bytes to read
+
+ --------------------
+ -- Shutdown modes --
+ --------------------
+
+ SHUT_RD : constant := 0; -- No more recv
+ SHUT_WR : constant := 1; -- No more send
+ SHUT_RDWR : constant := 2; -- No more recv/send
+
+ ---------------------
+ -- Protocol levels --
+ ---------------------
+
+ SOL_SOCKET : constant := 65535; -- Options for socket level
+ IPPROTO_IP : constant := 0; -- Dummy protocol for IP
+ IPPROTO_UDP : constant := 17; -- UDP
+ IPPROTO_TCP : constant := 6; -- TCP
+
+ -------------------
+ -- Request flags --
+ -------------------
+
+ MSG_OOB : constant := 1; -- Process out-of-band data
+ MSG_PEEK : constant := 2; -- Peek at incoming data
+ MSG_EOR : constant := 8; -- Send end of record
+ MSG_WAITALL : constant := 64; -- Wait for full reception
+
+ --------------------
+ -- Socket options --
+ --------------------
+
+ TCP_NODELAY : constant := 1; -- Do not coalesce packets
+ SO_SNDBUF : constant := 4097; -- Set/get send buffer size
+ SO_RCVBUF : constant := 4098; -- Set/get recv buffer size
+ SO_REUSEADDR : constant := 4; -- Bind reuse local address
+ SO_KEEPALIVE : constant := 8; -- Enable keep-alive msgs
+ SO_LINGER : constant := 128; -- Defer close to flush data
+ SO_ERROR : constant := 4103; -- Get/clear error status
+ SO_BROADCAST : constant := 32; -- Can send broadcast msgs
+ IP_ADD_MEMBERSHIP : constant := 11; -- Join a multicast group
+ IP_DROP_MEMBERSHIP : constant := 12; -- Leave a multicast group
+ IP_MULTICAST_TTL : constant := 16; -- Set/get multicast TTL
+ IP_MULTICAST_LOOP : constant := 10; -- Set/get mcast loopback
+
+end GNAT.Sockets.Constants;
diff --git a/gcc/ada/g-soccon-vms.adb b/gcc/ada/g-soccon-vms.adb
new file mode 100644
index 00000000000..76b2051e07c
--- /dev/null
+++ b/gcc/ada/g-soccon-vms.adb
@@ -0,0 +1,158 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . S O C K E T S . C O N S T A N T S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2000-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides target dependent definitions of constant for use
+-- by the GNAT.Sockets package (g-socket.ads). This package should not be
+-- directly with'ed by an applications program.
+
+-- This is the version for Alpha/VMS
+
+package GNAT.Sockets.Constants is
+
+ --------------
+ -- Families --
+ --------------
+
+ AF_INET : constant := 2; -- IPv4 address family
+ AF_INET6 : constant := 26; -- IPv6 address family
+
+ -----------
+ -- Modes --
+ -----------
+
+ SOCK_STREAM : constant := 1; -- Stream socket
+ SOCK_DGRAM : constant := 2; -- Datagram socket
+
+ -------------------
+ -- Socket errors --
+ -------------------
+
+ EACCES : constant := 13; -- Permission denied
+ EADDRINUSE : constant := 48; -- Address already in use
+ EADDRNOTAVAIL : constant := 49; -- Cannot assign address
+ EAFNOSUPPORT : constant := 47; -- Addr family not supported
+ EALREADY : constant := 37; -- Operation in progress
+ EBADF : constant := 9; -- Bad file descriptor
+ ECONNABORTED : constant := 53; -- Connection aborted
+ ECONNREFUSED : constant := 61; -- Connection refused
+ ECONNRESET : constant := 54; -- Connection reset by peer
+ EDESTADDRREQ : constant := 39; -- Destination addr required
+ EFAULT : constant := 45; -- Bad address
+ EHOSTDOWN : constant := 64; -- Host is down
+ EHOSTUNREACH : constant := 65; -- No route to host
+ EINPROGRESS : constant := 36; -- Operation now in progress
+ EINTR : constant := 4; -- Interrupted system call
+ EINVAL : constant := 22; -- Invalid argument
+ EIO : constant := 5; -- Input output error
+ EISCONN : constant := 56; -- Socket already connected
+ ELOOP : constant := 62; -- Too many symbolic lynks
+ EMFILE : constant := 24; -- Too many open files
+ EMSGSIZE : constant := 40; -- Message too long
+ ENAMETOOLONG : constant := 63; -- Name too long
+ ENETDOWN : constant := 50; -- Network is down
+ ENETRESET : constant := 52; -- Disconn. on network reset
+ ENETUNREACH : constant := 51; -- Network is unreachable
+ ENOBUFS : constant := 55; -- No buffer space available
+ ENOPROTOOPT : constant := 42; -- Protocol not available
+ ENOTCONN : constant := 57; -- Socket not connected
+ ENOTSOCK : constant := 38; -- Operation on non socket
+ EOPNOTSUPP : constant := 95; -- Operation not supported
+ EPFNOSUPPORT : constant := 46; -- Unknown protocol family
+ EPROTONOSUPPORT : constant := 43; -- Unknown protocol
+ EPROTOTYPE : constant := 41; -- Unknown protocol type
+ ESHUTDOWN : constant := 58; -- Cannot send once shutdown
+ ESOCKTNOSUPPORT : constant := 44; -- Socket type not supported
+ ETIMEDOUT : constant := 60; -- Connection timed out
+ ETOOMANYREFS : constant := 59; -- Too many references
+ EWOULDBLOCK : constant := 35; -- Operation would block
+
+ -----------------
+ -- Host errors --
+ -----------------
+
+ HOST_NOT_FOUND : constant := 1; -- Unknown host
+ TRY_AGAIN : constant := 2; -- Host name lookup failure
+ NO_DATA : constant := 4; -- No data record for name
+ NO_RECOVERY : constant := 3; -- Non recoverable errors
+
+ -------------------
+ -- Control flags --
+ -------------------
+
+ FIONBIO : constant := -2147195266; -- Set/clear non-blocking io
+ FIONREAD : constant := 1074030207; -- How many bytes to read
+
+ --------------------
+ -- Shutdown modes --
+ --------------------
+
+ SHUT_RD : constant := 0; -- No more recv
+ SHUT_WR : constant := 1; -- No more send
+ SHUT_RDWR : constant := 2; -- No more recv/send
+
+ ---------------------
+ -- Protocol levels --
+ ---------------------
+
+ SOL_SOCKET : constant := 16#FFFF#; -- Options for socket level
+ IPPROTO_IP : constant := 0; -- Dummy protocol for IP
+ IPPROTO_UDP : constant := 17; -- UDP
+ IPPROTO_TCP : constant := 6; -- TCP
+
+ -------------------
+ -- Request flags --
+ -------------------
+
+ MSG_OOB : constant := 1; -- Process out-of-band data
+ MSG_PEEK : constant := 2; -- Peek at incoming data
+ MSG_EOR : constant := 8; -- Send end of record
+ MSG_WAITALL : constant := 64; -- Wait for full reception
+
+ --------------------
+ -- Socket options --
+ --------------------
+
+ TCP_NODELAY : constant := 1; -- Do not coalesce packets
+ SO_SNDBUF : constant := 16#1001#; -- Set/get send buffer size
+ SO_RCVBUF : constant := 16#1002#; -- Set/get recv buffer size
+ SO_REUSEADDR : constant := 16#0004#; -- Bind reuse local address
+ SO_KEEPALIVE : constant := 16#0008#; -- Enable keep-alive msgs
+ SO_LINGER : constant := 16#0080#; -- Defer close to flush data
+ SO_ERROR : constant := 16#1007#; -- Get/clear error status
+ SO_BROADCAST : constant := 16#0020#; -- Can send broadcast msgs
+ IP_ADD_MEMBERSHIP : constant := 12; -- Join a multicast group
+ IP_DROP_MEMBERSHIP : constant := 13; -- Leave a multicast group
+ IP_MULTICAST_TTL : constant := 10; -- Set/get multicast TTL
+ IP_MULTICAST_LOOP : constant := 11; -- Set/get mcast loopback
+
+end GNAT.Sockets.Constants;
diff --git a/gcc/ada/g-soccon-vxworks.ads b/gcc/ada/g-soccon-vxworks.ads
new file mode 100644
index 00000000000..27dcb0c7a9e
--- /dev/null
+++ b/gcc/ada/g-soccon-vxworks.ads
@@ -0,0 +1,158 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . S O C K E T S . C O N S T A N T S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2000-2004 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides target dependent definitions of constant for use
+-- by the GNAT.Sockets package (g-socket.ads). This package should not be
+-- directly with'ed by an applications program.
+
+-- This is the version for VxWorks
+
+package GNAT.Sockets.Constants is
+
+ --------------
+ -- Families --
+ --------------
+
+ AF_INET : constant := 2; -- IPv4 address family
+ AF_INET6 : constant := -1; -- IPv6 address family
+
+ -----------
+ -- Modes --
+ -----------
+
+ SOCK_STREAM : constant := 1; -- Stream socket
+ SOCK_DGRAM : constant := 2; -- Datagram socket
+
+ -------------------
+ -- Socket errors --
+ -------------------
+
+ EACCES : constant := 13; -- Permission denied
+ EADDRINUSE : constant := 48; -- Address already in use
+ EADDRNOTAVAIL : constant := 49; -- Cannot assign address
+ EAFNOSUPPORT : constant := 47; -- Addr family not supported
+ EALREADY : constant := 69; -- Operation in progress
+ EBADF : constant := 9; -- Bad file descriptor
+ ECONNABORTED : constant := 53; -- Connection aborted
+ ECONNREFUSED : constant := 61; -- Connection refused
+ ECONNRESET : constant := 54; -- Connection reset by peer
+ EDESTADDRREQ : constant := 40; -- Destination addr required
+ EFAULT : constant := 14; -- Bad address
+ EHOSTDOWN : constant := 67; -- Host is down
+ EHOSTUNREACH : constant := 65; -- No route to host
+ EINPROGRESS : constant := 68; -- Operation now in progress
+ EINTR : constant := 4; -- Interrupted system call
+ EINVAL : constant := 22; -- Invalid argument
+ EIO : constant := 5; -- Input output error
+ EISCONN : constant := 56; -- Socket already connected
+ ELOOP : constant := 64; -- Too many symbolic lynks
+ EMFILE : constant := 24; -- Too many open files
+ EMSGSIZE : constant := 36; -- Message too long
+ ENAMETOOLONG : constant := 26; -- Name too long
+ ENETDOWN : constant := 62; -- Network is down
+ ENETRESET : constant := 52; -- Disconn. on network reset
+ ENETUNREACH : constant := 51; -- Network is unreachable
+ ENOBUFS : constant := 55; -- No buffer space available
+ ENOPROTOOPT : constant := 42; -- Protocol not available
+ ENOTCONN : constant := 57; -- Socket not connected
+ ENOTSOCK : constant := 50; -- Operation on non socket
+ EOPNOTSUPP : constant := 45; -- Operation not supported
+ EPFNOSUPPORT : constant := 46; -- Unknown protocol family
+ EPROTONOSUPPORT : constant := 43; -- Unknown protocol
+ EPROTOTYPE : constant := 41; -- Unknown protocol type
+ ESHUTDOWN : constant := 58; -- Cannot send once shutdown
+ ESOCKTNOSUPPORT : constant := 44; -- Socket type not supported
+ ETIMEDOUT : constant := 60; -- Connection timed out
+ ETOOMANYREFS : constant := 59; -- Too many references
+ EWOULDBLOCK : constant := 70; -- Operation would block
+
+ -----------------
+ -- Host errors --
+ -----------------
+
+ HOST_NOT_FOUND : constant := 1; -- Unknown host
+ TRY_AGAIN : constant := 2; -- Host name lookup failure
+ NO_DATA : constant := 4; -- No data record for name
+ NO_RECOVERY : constant := 3; -- Non recoverable errors
+
+ -------------------
+ -- Control flags --
+ -------------------
+
+ FIONBIO : constant := 16; -- Set/clear non-blocking io
+ FIONREAD : constant := 1; -- How many bytes to read
+
+ --------------------
+ -- Shutdown modes --
+ --------------------
+
+ SHUT_RD : constant := 0; -- No more recv
+ SHUT_WR : constant := 1; -- No more send
+ SHUT_RDWR : constant := 2; -- No more recv/send
+
+ ---------------------
+ -- Protocol levels --
+ ---------------------
+
+ SOL_SOCKET : constant := 65535; -- Options for socket level
+ IPPROTO_IP : constant := 0; -- Dummy protocol for IP
+ IPPROTO_UDP : constant := 17; -- UDP
+ IPPROTO_TCP : constant := 6; -- TCP
+
+ -------------------
+ -- Request flags --
+ -------------------
+
+ MSG_OOB : constant := 1; -- Process out-of-band data
+ MSG_PEEK : constant := 2; -- Peek at incoming data
+ MSG_EOR : constant := 8; -- Send end of record
+ MSG_WAITALL : constant := 64; -- Wait for full reception
+
+ --------------------
+ -- Socket options --
+ --------------------
+
+ TCP_NODELAY : constant := 1; -- Do not coalesce packets
+ SO_SNDBUF : constant := 4097; -- Set/get send buffer size
+ SO_RCVBUF : constant := 4098; -- Set/get recv buffer size
+ SO_REUSEADDR : constant := 4; -- Bind reuse local address
+ SO_KEEPALIVE : constant := 8; -- Enable keep-alive msgs
+ SO_LINGER : constant := 128; -- Defer close to flush data
+ SO_ERROR : constant := 4103; -- Get/clear error status
+ SO_BROADCAST : constant := 32; -- Can send broadcast msgs
+ IP_ADD_MEMBERSHIP : constant := 12; -- Join a multicast group
+ IP_DROP_MEMBERSHIP : constant := 13; -- Leave a multicast group
+ IP_MULTICAST_TTL : constant := 10; -- Set/get multicast TTL
+ IP_MULTICAST_LOOP : constant := 11; -- Set/get mcast loopback
+
+end GNAT.Sockets.Constants;
diff --git a/gcc/ada/g-socthi-mingw.adb b/gcc/ada/g-socthi-mingw.adb
new file mode 100644
index 00000000000..a948bdeedfa
--- /dev/null
+++ b/gcc/ada/g-socthi-mingw.adb
@@ -0,0 +1,587 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . S O C K E T S . T H I N --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2001-2004 Ada Core Technologies, 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides a target dependent thin interface to the sockets
+-- layer for use by the GNAT.Sockets package (g-socket.ads). This package
+-- should not be directly with'ed by an applications program.
+
+-- This version is for NT.
+
+with GNAT.Sockets.Constants; use GNAT.Sockets.Constants;
+with Interfaces.C.Strings; use Interfaces.C.Strings;
+
+with System; use System;
+
+package body GNAT.Sockets.Thin is
+
+ use type C.unsigned;
+
+ WSAData_Dummy : array (1 .. 512) of C.int;
+
+ WS_Version : constant := 16#0101#;
+ Initialized : Boolean := False;
+
+ SYSNOTREADY : constant := 10091;
+ VERNOTSUPPORTED : constant := 10092;
+ NOTINITIALISED : constant := 10093;
+ EDISCON : constant := 10101;
+
+ function Standard_Connect
+ (S : C.int;
+ Name : System.Address;
+ Namelen : C.int)
+ return C.int;
+ pragma Import (Stdcall, Standard_Connect, "connect");
+
+ function Standard_Select
+ (Nfds : C.int;
+ Readfds : Fd_Set_Access;
+ Writefds : Fd_Set_Access;
+ Exceptfds : Fd_Set_Access;
+ Timeout : Timeval_Access)
+ return C.int;
+ pragma Import (Stdcall, Standard_Select, "select");
+
+ type Error_Type is
+ (N_EINTR,
+ N_EBADF,
+ N_EACCES,
+ N_EFAULT,
+ N_EINVAL,
+ N_EMFILE,
+ N_EWOULDBLOCK,
+ N_EINPROGRESS,
+ N_EALREADY,
+ N_ENOTSOCK,
+ N_EDESTADDRREQ,
+ N_EMSGSIZE,
+ N_EPROTOTYPE,
+ N_ENOPROTOOPT,
+ N_EPROTONOSUPPORT,
+ N_ESOCKTNOSUPPORT,
+ N_EOPNOTSUPP,
+ N_EPFNOSUPPORT,
+ N_EAFNOSUPPORT,
+ N_EADDRINUSE,
+ N_EADDRNOTAVAIL,
+ N_ENETDOWN,
+ N_ENETUNREACH,
+ N_ENETRESET,
+ N_ECONNABORTED,
+ N_ECONNRESET,
+ N_ENOBUFS,
+ N_EISCONN,
+ N_ENOTCONN,
+ N_ESHUTDOWN,
+ N_ETOOMANYREFS,
+ N_ETIMEDOUT,
+ N_ECONNREFUSED,
+ N_ELOOP,
+ N_ENAMETOOLONG,
+ N_EHOSTDOWN,
+ N_EHOSTUNREACH,
+ N_SYSNOTREADY,
+ N_VERNOTSUPPORTED,
+ N_NOTINITIALISED,
+ N_EDISCON,
+ N_HOST_NOT_FOUND,
+ N_TRY_AGAIN,
+ N_NO_RECOVERY,
+ N_NO_DATA,
+ N_OTHERS);
+
+ Error_Messages : constant array (Error_Type) of chars_ptr :=
+ (N_EINTR =>
+ New_String ("Interrupted system call"),
+ N_EBADF =>
+ New_String ("Bad file number"),
+ N_EACCES =>
+ New_String ("Permission denied"),
+ N_EFAULT =>
+ New_String ("Bad address"),
+ N_EINVAL =>
+ New_String ("Invalid argument"),
+ N_EMFILE =>
+ New_String ("Too many open files"),
+ N_EWOULDBLOCK =>
+ New_String ("Operation would block"),
+ N_EINPROGRESS =>
+ New_String ("Operation now in progress. This error is "
+ & "returned if any Windows Sockets API "
+ & "function is called while a blocking "
+ & "function is in progress"),
+ N_EALREADY =>
+ New_String ("Operation already in progress"),
+ N_ENOTSOCK =>
+ New_String ("Socket operation on nonsocket"),
+ N_EDESTADDRREQ =>
+ New_String ("Destination address required"),
+ N_EMSGSIZE =>
+ New_String ("Message too long"),
+ N_EPROTOTYPE =>
+ New_String ("Protocol wrong type for socket"),
+ N_ENOPROTOOPT =>
+ New_String ("Protocol not available"),
+ N_EPROTONOSUPPORT =>
+ New_String ("Protocol not supported"),
+ N_ESOCKTNOSUPPORT =>
+ New_String ("Socket type not supported"),
+ N_EOPNOTSUPP =>
+ New_String ("Operation not supported on socket"),
+ N_EPFNOSUPPORT =>
+ New_String ("Protocol family not supported"),
+ N_EAFNOSUPPORT =>
+ New_String ("Address family not supported by protocol family"),
+ N_EADDRINUSE =>
+ New_String ("Address already in use"),
+ N_EADDRNOTAVAIL =>
+ New_String ("Cannot assign requested address"),
+ N_ENETDOWN =>
+ New_String ("Network is down. This error may be "
+ & "reported at any time if the Windows "
+ & "Sockets implementation detects an "
+ & "underlying failure"),
+ N_ENETUNREACH =>
+ New_String ("Network is unreachable"),
+ N_ENETRESET =>
+ New_String ("Network dropped connection on reset"),
+ N_ECONNABORTED =>
+ New_String ("Software caused connection abort"),
+ N_ECONNRESET =>
+ New_String ("Connection reset by peer"),
+ N_ENOBUFS =>
+ New_String ("No buffer space available"),
+ N_EISCONN =>
+ New_String ("Socket is already connected"),
+ N_ENOTCONN =>
+ New_String ("Socket is not connected"),
+ N_ESHUTDOWN =>
+ New_String ("Cannot send after socket shutdown"),
+ N_ETOOMANYREFS =>
+ New_String ("Too many references: cannot splice"),
+ N_ETIMEDOUT =>
+ New_String ("Connection timed out"),
+ N_ECONNREFUSED =>
+ New_String ("Connection refused"),
+ N_ELOOP =>
+ New_String ("Too many levels of symbolic links"),
+ N_ENAMETOOLONG =>
+ New_String ("File name too long"),
+ N_EHOSTDOWN =>
+ New_String ("Host is down"),
+ N_EHOSTUNREACH =>
+ New_String ("No route to host"),
+ N_SYSNOTREADY =>
+ New_String ("Returned by WSAStartup(), indicating that "
+ & "the network subsystem is unusable"),
+ N_VERNOTSUPPORTED =>
+ New_String ("Returned by WSAStartup(), indicating that "
+ & "the Windows Sockets DLL cannot support "
+ & "this application"),
+ N_NOTINITIALISED =>
+ New_String ("Winsock not initialized. This message is "
+ & "returned by any function except WSAStartup(), "
+ & "indicating that a successful WSAStartup() has "
+ & "not yet been performed"),
+ N_EDISCON =>
+ New_String ("Disconnect"),
+ N_HOST_NOT_FOUND =>
+ New_String ("Host not found. This message indicates "
+ & "that the key (name, address, and so on) was not found"),
+ N_TRY_AGAIN =>
+ New_String ("Nonauthoritative host not found. This error may "
+ & "suggest that the name service itself is not "
+ & "functioning"),
+ N_NO_RECOVERY =>
+ New_String ("Nonrecoverable error. This error may suggest that the "
+ & "name service itself is not functioning"),
+ N_NO_DATA =>
+ New_String ("Valid name, no data record of requested type. "
+ & "This error indicates that the key (name, address, "
+ & "and so on) was not found."),
+ N_OTHERS =>
+ New_String ("Unknown system error"));
+
+ ---------------
+ -- C_Connect --
+ ---------------
+
+ function C_Connect
+ (S : C.int;
+ Name : System.Address;
+ Namelen : C.int)
+ return C.int
+ is
+ Res : C.int;
+
+ begin
+ Res := Standard_Connect (S, Name, Namelen);
+
+ if Res = -1 then
+ if Socket_Errno = EWOULDBLOCK then
+ Set_Socket_Errno (EINPROGRESS);
+ end if;
+ end if;
+
+ return Res;
+ end C_Connect;
+
+ -------------
+ -- C_Readv --
+ -------------
+
+ function C_Readv
+ (Socket : C.int;
+ Iov : System.Address;
+ Iovcnt : C.int)
+ return C.int
+ is
+ Res : C.int;
+ Count : C.int := 0;
+
+ Iovec : array (0 .. Iovcnt - 1) of Vector_Element;
+ for Iovec'Address use Iov;
+ pragma Import (Ada, Iovec);
+
+ begin
+ for J in Iovec'Range loop
+ Res := C_Recv
+ (Socket,
+ Iovec (J).Base.all'Address,
+ C.int (Iovec (J).Length),
+ 0);
+
+ if Res < 0 then
+ return Res;
+ else
+ Count := Count + Res;
+ end if;
+ end loop;
+ return Count;
+ end C_Readv;
+
+ --------------
+ -- C_Select --
+ --------------
+
+ function C_Select
+ (Nfds : C.int;
+ Readfds : Fd_Set_Access;
+ Writefds : Fd_Set_Access;
+ Exceptfds : Fd_Set_Access;
+ Timeout : Timeval_Access)
+ return C.int
+ is
+ pragma Warnings (Off, Exceptfds);
+
+ RFS : constant Fd_Set_Access := Readfds;
+ WFS : constant Fd_Set_Access := Writefds;
+ WFSC : Fd_Set_Access := No_Fd_Set;
+ EFS : Fd_Set_Access := Exceptfds;
+ Res : C.int;
+ S : aliased C.int;
+ Last : aliased C.int;
+
+ begin
+ -- Asynchronous connection failures are notified in the
+ -- exception fd set instead of the write fd set. To ensure
+ -- POSIX compatitibility, copy write fd set into exception fd
+ -- set. Once select() returns, check any socket present in the
+ -- exception fd set and peek at incoming out-of-band data. If
+ -- the test is not successfull and if the socket is present in
+ -- the initial write fd set, then move the socket from the
+ -- exception fd set to the write fd set.
+
+ if WFS /= No_Fd_Set then
+ -- Add any socket present in write fd set into exception fd set
+
+ if EFS = No_Fd_Set then
+ EFS := New_Socket_Set (WFS);
+
+ else
+ WFSC := New_Socket_Set (WFS);
+
+ Last := Nfds - 1;
+ loop
+ Get_Socket_From_Set
+ (WFSC, S'Unchecked_Access, Last'Unchecked_Access);
+ exit when S = -1;
+ Insert_Socket_In_Set (EFS, S);
+ end loop;
+
+ Free_Socket_Set (WFSC);
+ end if;
+
+ -- Keep a copy of write fd set
+
+ WFSC := New_Socket_Set (WFS);
+ end if;
+
+ Res := Standard_Select (Nfds, RFS, WFS, EFS, Timeout);
+
+ if EFS /= No_Fd_Set then
+ declare
+ EFSC : constant Fd_Set_Access := New_Socket_Set (EFS);
+ Flag : constant C.int := MSG_PEEK + MSG_OOB;
+ Buffer : Character;
+ Length : C.int;
+ Fromlen : aliased C.int;
+
+ begin
+ Last := Nfds - 1;
+ loop
+ Get_Socket_From_Set
+ (EFSC, S'Unchecked_Access, Last'Unchecked_Access);
+
+ -- No more sockets in EFSC
+
+ exit when S = -1;
+
+ -- Check out-of-band data
+
+ Length := C_Recvfrom
+ (S, Buffer'Address, 1, Flag,
+ null, Fromlen'Unchecked_Access);
+
+ -- If the signal is not an out-of-band data, then it
+ -- is a connection failure notification.
+
+ if Length = -1 then
+ Remove_Socket_From_Set (EFS, S);
+
+ -- If S is present in the initial write fd set,
+ -- move it from exception fd set back to write fd
+ -- set. Otherwise, ignore this event since the user
+ -- is not watching for it.
+
+ if WFSC /= No_Fd_Set
+ and then Is_Socket_In_Set (WFSC, S)
+ then
+ Insert_Socket_In_Set (WFS, S);
+ end if;
+ end if;
+ end loop;
+
+ Free_Socket_Set (EFSC);
+ end;
+
+ if Exceptfds = No_Fd_Set then
+ Free_Socket_Set (EFS);
+ end if;
+ end if;
+
+ -- Free any copy of write fd set
+
+ if WFSC /= No_Fd_Set then
+ Free_Socket_Set (WFSC);
+ end if;
+
+ return Res;
+ end C_Select;
+
+ --------------
+ -- C_Writev --
+ --------------
+
+ function C_Writev
+ (Socket : C.int;
+ Iov : System.Address;
+ Iovcnt : C.int)
+ return C.int
+ is
+ Res : C.int;
+ Count : C.int := 0;
+
+ Iovec : array (0 .. Iovcnt - 1) of Vector_Element;
+ for Iovec'Address use Iov;
+ pragma Import (Ada, Iovec);
+
+ begin
+ for J in Iovec'Range loop
+ Res := C_Send
+ (Socket,
+ Iovec (J).Base.all'Address,
+ C.int (Iovec (J).Length),
+ 0);
+
+ if Res < 0 then
+ return Res;
+ else
+ Count := Count + Res;
+ end if;
+ end loop;
+ return Count;
+ end C_Writev;
+
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize is
+ begin
+ if Initialized then
+ WSACleanup;
+ Initialized := False;
+ end if;
+ end Finalize;
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize (Process_Blocking_IO : Boolean := False) is
+ pragma Unreferenced (Process_Blocking_IO);
+
+ Return_Value : Interfaces.C.int;
+
+ begin
+ if not Initialized then
+ Return_Value := WSAStartup (WS_Version, WSAData_Dummy'Address);
+ pragma Assert (Interfaces.C."=" (Return_Value, 0));
+ Initialized := True;
+ end if;
+ end Initialize;
+
+ -----------------
+ -- Set_Address --
+ -----------------
+
+ procedure Set_Address
+ (Sin : Sockaddr_In_Access;
+ Address : In_Addr)
+ is
+ begin
+ Sin.Sin_Addr := Address;
+ end Set_Address;
+
+ ----------------
+ -- Set_Family --
+ ----------------
+
+ procedure Set_Family
+ (Sin : Sockaddr_In_Access;
+ Family : C.int)
+ is
+ begin
+ Sin.Sin_Family := C.unsigned_short (Family);
+ end Set_Family;
+
+ ----------------
+ -- Set_Length --
+ ----------------
+
+ procedure Set_Length
+ (Sin : Sockaddr_In_Access;
+ Len : C.int)
+ is
+ pragma Unreferenced (Sin);
+ pragma Unreferenced (Len);
+
+ begin
+ null;
+ end Set_Length;
+
+ --------------
+ -- Set_Port --
+ --------------
+
+ procedure Set_Port
+ (Sin : Sockaddr_In_Access;
+ Port : C.unsigned_short)
+ is
+ begin
+ Sin.Sin_Port := Port;
+ end Set_Port;
+
+ --------------------------
+ -- Socket_Error_Message --
+ --------------------------
+
+ function Socket_Error_Message
+ (Errno : Integer)
+ return C.Strings.chars_ptr
+ is
+ use GNAT.Sockets.Constants;
+
+ begin
+ case Errno is
+ when EINTR => return Error_Messages (N_EINTR);
+ when EBADF => return Error_Messages (N_EBADF);
+ when EACCES => return Error_Messages (N_EACCES);
+ when EFAULT => return Error_Messages (N_EFAULT);
+ when EINVAL => return Error_Messages (N_EINVAL);
+ when EMFILE => return Error_Messages (N_EMFILE);
+ when EWOULDBLOCK => return Error_Messages (N_EWOULDBLOCK);
+ when EINPROGRESS => return Error_Messages (N_EINPROGRESS);
+ when EALREADY => return Error_Messages (N_EALREADY);
+ when ENOTSOCK => return Error_Messages (N_ENOTSOCK);
+ when EDESTADDRREQ => return Error_Messages (N_EDESTADDRREQ);
+ when EMSGSIZE => return Error_Messages (N_EMSGSIZE);
+ when EPROTOTYPE => return Error_Messages (N_EPROTOTYPE);
+ when ENOPROTOOPT => return Error_Messages (N_ENOPROTOOPT);
+ when EPROTONOSUPPORT => return Error_Messages (N_EPROTONOSUPPORT);
+ when ESOCKTNOSUPPORT => return Error_Messages (N_ESOCKTNOSUPPORT);
+ when EOPNOTSUPP => return Error_Messages (N_EOPNOTSUPP);
+ when EPFNOSUPPORT => return Error_Messages (N_EPFNOSUPPORT);
+ when EAFNOSUPPORT => return Error_Messages (N_EAFNOSUPPORT);
+ when EADDRINUSE => return Error_Messages (N_EADDRINUSE);
+ when EADDRNOTAVAIL => return Error_Messages (N_EADDRNOTAVAIL);
+ when ENETDOWN => return Error_Messages (N_ENETDOWN);
+ when ENETUNREACH => return Error_Messages (N_ENETUNREACH);
+ when ENETRESET => return Error_Messages (N_ENETRESET);
+ when ECONNABORTED => return Error_Messages (N_ECONNABORTED);
+ when ECONNRESET => return Error_Messages (N_ECONNRESET);
+ when ENOBUFS => return Error_Messages (N_ENOBUFS);
+ when EISCONN => return Error_Messages (N_EISCONN);
+ when ENOTCONN => return Error_Messages (N_ENOTCONN);
+ when ESHUTDOWN => return Error_Messages (N_ESHUTDOWN);
+ when ETOOMANYREFS => return Error_Messages (N_ETOOMANYREFS);
+ when ETIMEDOUT => return Error_Messages (N_ETIMEDOUT);
+ when ECONNREFUSED => return Error_Messages (N_ECONNREFUSED);
+ when ELOOP => return Error_Messages (N_ELOOP);
+ when ENAMETOOLONG => return Error_Messages (N_ENAMETOOLONG);
+ when EHOSTDOWN => return Error_Messages (N_EHOSTDOWN);
+ when EHOSTUNREACH => return Error_Messages (N_EHOSTUNREACH);
+ when SYSNOTREADY => return Error_Messages (N_SYSNOTREADY);
+ when VERNOTSUPPORTED => return Error_Messages (N_VERNOTSUPPORTED);
+ when NOTINITIALISED => return Error_Messages (N_NOTINITIALISED);
+ when EDISCON => return Error_Messages (N_EDISCON);
+ when HOST_NOT_FOUND => return Error_Messages (N_HOST_NOT_FOUND);
+ when TRY_AGAIN => return Error_Messages (N_TRY_AGAIN);
+ when NO_RECOVERY => return Error_Messages (N_NO_RECOVERY);
+ when NO_DATA => return Error_Messages (N_NO_DATA);
+ when others => return Error_Messages (N_OTHERS);
+ end case;
+ end Socket_Error_Message;
+
+end GNAT.Sockets.Thin;
diff --git a/gcc/ada/g-socthi-mingw.ads b/gcc/ada/g-socthi-mingw.ads
new file mode 100644
index 00000000000..5ee990e8628
--- /dev/null
+++ b/gcc/ada/g-socthi-mingw.ads
@@ -0,0 +1,433 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . S O C K E T S . T H I N --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2001-2004 Ada Core Technologies, 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides a target dependent thin interface to the sockets
+-- layer for use by the GNAT.Sockets package (g-socket.ads). This package
+-- should not be directly with'ed by an applications program.
+
+-- This version is for NT
+
+with Interfaces.C.Pointers;
+with Interfaces.C.Strings;
+
+with GNAT.Sockets.Constants;
+
+with System;
+
+package GNAT.Sockets.Thin is
+
+ package C renames Interfaces.C;
+
+ use type C.int;
+ -- So that we can declare the Failure constant below.
+
+ Success : constant C.int := 0;
+ Failure : constant C.int := -1;
+
+ function Socket_Errno return Integer;
+ -- Returns last socket error number.
+
+ procedure Set_Socket_Errno (Errno : Integer);
+ -- Set last socket error number.
+
+ function Socket_Error_Message
+ (Errno : Integer)
+ return C.Strings.chars_ptr;
+ -- Returns the error message string for the error number Errno. If
+ -- Errno is not known it returns "Unknown system error".
+
+ subtype Fd_Set_Access is System.Address;
+ No_Fd_Set : constant Fd_Set_Access := System.Null_Address;
+
+ type Timeval_Unit is new C.long;
+ pragma Convention (C, Timeval_Unit);
+
+ type Timeval is record
+ Tv_Sec : Timeval_Unit;
+ Tv_Usec : Timeval_Unit;
+ end record;
+ pragma Convention (C, Timeval);
+
+ type Timeval_Access is access all Timeval;
+ pragma Convention (C, Timeval_Access);
+
+ Immediat : constant Timeval := (0, 0);
+
+ type Int_Access is access all C.int;
+ pragma Convention (C, Int_Access);
+ -- Access to C integers
+
+ type Chars_Ptr_Array is array (C.size_t range <>) of
+ aliased C.Strings.chars_ptr;
+
+ package Chars_Ptr_Pointers is
+ new C.Pointers (C.size_t, C.Strings.chars_ptr, Chars_Ptr_Array,
+ C.Strings.Null_Ptr);
+ -- Arrays of C (char *)
+
+ type In_Addr is record
+ S_B1, S_B2, S_B3, S_B4 : C.unsigned_char;
+ end record;
+ pragma Convention (C, In_Addr);
+ -- Internet address
+
+ type In_Addr_Access is access all In_Addr;
+ pragma Convention (C, In_Addr_Access);
+ -- Access to internet address
+
+ Inaddr_Any : aliased constant In_Addr := (others => 0);
+ -- Any internet address (all the interfaces)
+
+ type In_Addr_Access_Array is array (C.size_t range <>)
+ of aliased In_Addr_Access;
+ pragma Convention (C, In_Addr_Access_Array);
+ package In_Addr_Access_Pointers is
+ new C.Pointers (C.size_t, In_Addr_Access, In_Addr_Access_Array, null);
+ -- Array of internet addresses
+
+ type Sockaddr is record
+ Sa_Family : C.unsigned_short;
+ Sa_Data : C.char_array (1 .. 14);
+ end record;
+ pragma Convention (C, Sockaddr);
+ -- Socket address
+
+ type Sockaddr_Access is access all Sockaddr;
+ pragma Convention (C, Sockaddr_Access);
+ -- Access to socket address
+
+ type Sockaddr_In is record
+ Sin_Family : C.unsigned_short := Constants.AF_INET;
+ Sin_Port : C.unsigned_short := 0;
+ Sin_Addr : In_Addr := Inaddr_Any;
+ Sin_Zero : C.char_array (1 .. 8) := (others => C.char'Val (0));
+ end record;
+ pragma Convention (C, Sockaddr_In);
+ -- Internet socket address
+
+ type Sockaddr_In_Access is access all Sockaddr_In;
+ pragma Convention (C, Sockaddr_In_Access);
+ -- Access to internet socket address
+
+ procedure Set_Length
+ (Sin : Sockaddr_In_Access;
+ Len : C.int);
+ pragma Inline (Set_Length);
+ -- Set Sin.Sin_Length to Len.
+ -- On this platform, nothing is done as there is no such field.
+
+ procedure Set_Family
+ (Sin : Sockaddr_In_Access;
+ Family : C.int);
+ pragma Inline (Set_Family);
+ -- Set Sin.Sin_Family to Family
+
+ procedure Set_Port
+ (Sin : Sockaddr_In_Access;
+ Port : C.unsigned_short);
+ pragma Inline (Set_Port);
+ -- Set Sin.Sin_Port to Port
+
+ procedure Set_Address
+ (Sin : Sockaddr_In_Access;
+ Address : In_Addr);
+ pragma Inline (Set_Address);
+ -- Set Sin.Sin_Addr to Address
+
+ type Hostent is record
+ H_Name : C.Strings.chars_ptr;
+ H_Aliases : Chars_Ptr_Pointers.Pointer;
+ H_Addrtype : C.short;
+ H_Length : C.short;
+ H_Addr_List : In_Addr_Access_Pointers.Pointer;
+ end record;
+ pragma Convention (C, Hostent);
+ -- Host entry
+
+ type Hostent_Access is access all Hostent;
+ pragma Convention (C, Hostent_Access);
+ -- Access to host entry
+
+ 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_Access is access all Servent;
+ pragma Convention (C, Servent_Access);
+ -- Access to service entry
+
+ type Two_Int is array (0 .. 1) of C.int;
+ pragma Convention (C, Two_Int);
+ -- Used with pipe()
+
+ function C_Accept
+ (S : C.int;
+ Addr : System.Address;
+ Addrlen : access C.int) return C.int;
+
+ function C_Bind
+ (S : C.int;
+ Name : System.Address;
+ Namelen : C.int) return C.int;
+
+ function C_Close
+ (Fd : C.int) return C.int;
+
+ function C_Connect
+ (S : C.int;
+ Name : System.Address;
+ Namelen : C.int) return C.int;
+
+ function C_Gethostbyaddr
+ (Addr : System.Address;
+ Length : C.int;
+ Typ : C.int) return Hostent_Access;
+
+ function C_Gethostbyname
+ (Name : C.char_array) return Hostent_Access;
+
+ function C_Gethostname
+ (Name : System.Address;
+ Namelen : C.int) return C.int;
+
+ function C_Getpeername
+ (S : C.int;
+ Name : System.Address;
+ Namelen : access C.int) return C.int;
+
+ function C_Getservbyname
+ (Name : C.char_array;
+ Proto : C.char_array) return Servent_Access;
+
+ function C_Getservbyport
+ (Port : C.int;
+ Proto : C.char_array) return Servent_Access;
+
+ function C_Getsockname
+ (S : C.int;
+ Name : System.Address;
+ Namelen : access C.int) return C.int;
+
+ function C_Getsockopt
+ (S : C.int;
+ Level : C.int;
+ Optname : C.int;
+ Optval : System.Address;
+ Optlen : access C.int) return C.int;
+
+ function C_Inet_Addr
+ (Cp : C.Strings.chars_ptr) return C.int;
+
+ function C_Ioctl
+ (S : C.int;
+ Req : C.int;
+ Arg : Int_Access) return C.int;
+
+ function C_Listen
+ (S : C.int;
+ Backlog : C.int) return C.int;
+
+ function C_Read
+ (Fildes : C.int;
+ Buf : System.Address;
+ Nbyte : C.int) return C.int;
+
+ function C_Readv
+ (Socket : C.int;
+ Iov : System.Address;
+ Iovcnt : C.int) return C.int;
+
+ function C_Recv
+ (S : C.int;
+ Buf : System.Address;
+ Len : C.int;
+ Flags : C.int) return C.int;
+
+ function C_Recvfrom
+ (S : C.int;
+ Buf : System.Address;
+ Len : C.int;
+ Flags : C.int;
+ From : Sockaddr_In_Access;
+ Fromlen : access C.int) return C.int;
+
+ function C_Select
+ (Nfds : C.int;
+ Readfds : Fd_Set_Access;
+ Writefds : Fd_Set_Access;
+ Exceptfds : Fd_Set_Access;
+ Timeout : Timeval_Access) return C.int;
+
+ function C_Send
+ (S : C.int;
+ Buf : System.Address;
+ Len : C.int;
+ Flags : C.int) return C.int;
+
+ function C_Sendto
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int;
+ To : Sockaddr_In_Access;
+ Tolen : C.int) return C.int;
+
+ function C_Setsockopt
+ (S : C.int;
+ Level : C.int;
+ Optname : C.int;
+ Optval : System.Address;
+ Optlen : C.int) return C.int;
+
+ function C_Shutdown
+ (S : C.int;
+ How : C.int) return C.int;
+
+ function C_Socket
+ (Domain : C.int;
+ 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;
+
+ function C_Write
+ (Fildes : C.int;
+ Buf : System.Address;
+ Nbyte : C.int) return C.int;
+
+ function C_Writev
+ (Socket : C.int;
+ Iov : System.Address;
+ Iovcnt : C.int) return C.int;
+
+ function WSAStartup
+ (WS_Version : Interfaces.C.int;
+ WSADataAddress : System.Address) return Interfaces.C.int;
+
+ procedure Free_Socket_Set
+ (Set : Fd_Set_Access);
+ -- Free system-dependent socket set.
+
+ procedure Get_Socket_From_Set
+ (Set : Fd_Set_Access;
+ Socket : Int_Access;
+ Last : Int_Access);
+ -- Get last socket in Socket and remove it from the socket
+ -- set. The parameter Last is a maximum value of the largest
+ -- socket. This hint is used to avoid scanning very large socket
+ -- sets. After a call to Get_Socket_From_Set, Last is set back to
+ -- the real largest socket in the socket set.
+
+ procedure Insert_Socket_In_Set
+ (Set : Fd_Set_Access;
+ Socket : C.int);
+ -- Insert socket in the socket set
+
+ function Is_Socket_In_Set
+ (Set : Fd_Set_Access;
+ Socket : C.int) return Boolean;
+ -- Check whether Socket is in the socket set
+
+ procedure Last_Socket_In_Set
+ (Set : Fd_Set_Access;
+ Last : Int_Access);
+ -- Find the largest socket in the socket set. This is needed for
+ -- select(). When Last_Socket_In_Set is called, parameter Last is
+ -- a maximum value of the largest socket. This hint is used to
+ -- avoid scanning very large socket sets. After the call, Last is
+ -- set back to the real largest socket in the socket set.
+
+ function New_Socket_Set
+ (Set : Fd_Set_Access) return Fd_Set_Access;
+ -- Allocate a new socket set which is a system-dependent structure
+ -- and initialize by copying Set if it is non-null, by making it
+ -- empty otherwise.
+
+ procedure Remove_Socket_From_Set
+ (Set : Fd_Set_Access;
+ Socket : C.int);
+ -- Remove socket from the socket set
+
+ procedure WSACleanup;
+
+ procedure Finalize;
+ procedure Initialize (Process_Blocking_IO : Boolean := False);
+
+private
+ pragma Import (Stdcall, C_Accept, "accept");
+ pragma Import (Stdcall, C_Bind, "bind");
+ pragma Import (Stdcall, C_Close, "closesocket");
+ pragma Import (Stdcall, C_Gethostbyaddr, "gethostbyaddr");
+ pragma Import (Stdcall, C_Gethostbyname, "gethostbyname");
+ pragma Import (Stdcall, C_Gethostname, "gethostname");
+ pragma Import (Stdcall, C_Getpeername, "getpeername");
+ pragma Import (Stdcall, C_Getservbyname, "getservbyname");
+ pragma Import (Stdcall, C_Getservbyport, "getservbyport");
+ pragma Import (Stdcall, C_Getsockname, "getsockname");
+ pragma Import (Stdcall, C_Getsockopt, "getsockopt");
+ pragma Import (Stdcall, C_Inet_Addr, "inet_addr");
+ pragma Import (Stdcall, C_Ioctl, "ioctlsocket");
+ pragma Import (Stdcall, C_Listen, "listen");
+ pragma Import (C, C_Read, "_read");
+ pragma Import (Stdcall, C_Recv, "recv");
+ pragma Import (Stdcall, C_Recvfrom, "recvfrom");
+ pragma Import (Stdcall, C_Send, "send");
+ pragma Import (Stdcall, C_Sendto, "sendto");
+ 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 (C, C_Write, "_write");
+ pragma Import (Stdcall, Socket_Errno, "WSAGetLastError");
+ pragma Import (Stdcall, Set_Socket_Errno, "WSASetLastError");
+ pragma Import (Stdcall, WSAStartup, "WSAStartup");
+ pragma Import (Stdcall, WSACleanup, "WSACleanup");
+
+ pragma Import (C, Free_Socket_Set, "__gnat_free_socket_set");
+ pragma Import (C, Get_Socket_From_Set, "__gnat_get_socket_from_set");
+ pragma Import (C, Is_Socket_In_Set, "__gnat_is_socket_in_set");
+ pragma Import (C, Last_Socket_In_Set, "__gnat_last_socket_in_set");
+ pragma Import (C, New_Socket_Set, "__gnat_new_socket_set");
+ pragma Import (C, Insert_Socket_In_Set, "__gnat_insert_socket_in_set");
+ pragma Import (C, Remove_Socket_From_Set, "__gnat_remove_socket_from_set");
+end GNAT.Sockets.Thin;
diff --git a/gcc/ada/g-socthi-vms.adb b/gcc/ada/g-socthi-vms.adb
new file mode 100644
index 00000000000..41b32d16e9a
--- /dev/null
+++ b/gcc/ada/g-socthi-vms.adb
@@ -0,0 +1,551 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . S O C K E T S . T H I N --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2001-2004 Ada Core Technologies, 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- Temporary version for Alpha/VMS.
+
+with GNAT.OS_Lib; use GNAT.OS_Lib;
+with GNAT.Task_Lock;
+
+with Interfaces.C; use Interfaces.C;
+
+package body GNAT.Sockets.Thin is
+
+ Non_Blocking_Sockets : constant Fd_Set_Access
+ := New_Socket_Set (No_Socket_Set);
+ -- When this package is initialized with Process_Blocking_IO set
+ -- to True, sockets are set in non-blocking mode to avoid blocking
+ -- the whole process when a thread wants to perform a blocking IO
+ -- operation. But the user can also set a socket in non-blocking
+ -- mode by purpose. In order to make a difference between these
+ -- two situations, we track the origin of non-blocking mode in
+ -- Non_Blocking_Sockets. If S is in Non_Blocking_Sockets, it has
+ -- been set in non-blocking mode by the user.
+
+ Quantum : constant Duration := 0.2;
+ -- When Thread_Blocking_IO is False, we set sockets in
+ -- non-blocking mode and we spend a period of time Quantum between
+ -- two attempts on a blocking operation.
+
+ Thread_Blocking_IO : Boolean := True;
+
+ Unknown_System_Error : constant C.Strings.chars_ptr :=
+ C.Strings.New_String ("Unknown system error");
+
+ function Syscall_Accept
+ (S : C.int;
+ Addr : System.Address;
+ Addrlen : access C.int) return C.int;
+ pragma Import (C, Syscall_Accept, "accept");
+
+ function Syscall_Connect
+ (S : C.int;
+ Name : System.Address;
+ Namelen : C.int) return C.int;
+ pragma Import (C, Syscall_Connect, "connect");
+
+ function Syscall_Ioctl
+ (S : C.int;
+ Req : C.int;
+ Arg : Int_Access) return C.int;
+ pragma Import (C, Syscall_Ioctl, "ioctl");
+
+ function Syscall_Recv
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int) return C.int;
+ pragma Import (C, Syscall_Recv, "recv");
+
+ function Syscall_Recvfrom
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int;
+ From : Sockaddr_In_Access;
+ Fromlen : access C.int) return C.int;
+ pragma Import (C, Syscall_Recvfrom, "recvfrom");
+
+ function Syscall_Send
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int)
+ return C.int;
+ pragma Import (C, Syscall_Send, "send");
+
+ function Syscall_Sendto
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int;
+ To : Sockaddr_In_Access;
+ Tolen : C.int)
+ return C.int;
+ pragma Import (C, Syscall_Sendto, "sendto");
+
+ function Syscall_Socket
+ (Domain, Typ, Protocol : C.int) return C.int;
+ pragma Import (C, Syscall_Socket, "socket");
+
+ function Non_Blocking_Socket (S : C.int) return Boolean;
+ procedure Set_Non_Blocking_Socket (S : C.int; V : Boolean);
+
+ --------------
+ -- C_Accept --
+ --------------
+
+ function C_Accept
+ (S : C.int;
+ Addr : System.Address;
+ Addrlen : access C.int) return C.int
+ is
+ R : C.int;
+ Val : aliased C.int := 1;
+
+ Discard : C.int;
+ pragma Warnings (Off, Discard);
+
+ begin
+ loop
+ R := Syscall_Accept (S, Addr, Addrlen);
+ exit when Thread_Blocking_IO
+ or else R /= Failure
+ or else Non_Blocking_Socket (S)
+ or else Errno /= Constants.EWOULDBLOCK;
+ delay Quantum;
+ end loop;
+
+ if not Thread_Blocking_IO
+ and then R /= Failure
+ then
+ -- A socket inherits the properties ot its server especially
+ -- the FIONBIO flag. Do not use C_Ioctl as this subprogram
+ -- tracks sockets set in non-blocking mode by user.
+
+ Set_Non_Blocking_Socket (R, Non_Blocking_Socket (S));
+ Discard := Syscall_Ioctl (R, Constants.FIONBIO, Val'Unchecked_Access);
+ end if;
+
+ return R;
+ end C_Accept;
+
+ ---------------
+ -- C_Connect --
+ ---------------
+
+ function C_Connect
+ (S : C.int;
+ Name : System.Address;
+ Namelen : C.int) return C.int
+ is
+ Res : C.int;
+
+ begin
+ Res := Syscall_Connect (S, Name, Namelen);
+
+ if Thread_Blocking_IO
+ or else Res /= Failure
+ or else Non_Blocking_Socket (S)
+ or else Errno /= Constants.EINPROGRESS
+ then
+ return Res;
+ end if;
+
+ declare
+ WSet : Fd_Set_Access;
+ Now : aliased Timeval;
+
+ begin
+ WSet := New_Socket_Set (No_Socket_Set);
+ loop
+ Insert_Socket_In_Set (WSet, S);
+ Now := Immediat;
+ Res := C_Select
+ (S + 1,
+ No_Fd_Set,
+ WSet,
+ No_Fd_Set,
+ Now'Unchecked_Access);
+
+ exit when Res > 0;
+
+ if Res = Failure then
+ Free_Socket_Set (WSet);
+ return Res;
+ end if;
+
+ delay Quantum;
+ end loop;
+
+ Free_Socket_Set (WSet);
+ end;
+
+ Res := Syscall_Connect (S, Name, Namelen);
+
+ if Res = Failure
+ and then Errno = Constants.EISCONN
+ then
+ return Thin.Success;
+ else
+ return Res;
+ end if;
+ end C_Connect;
+
+ -------------
+ -- C_Ioctl --
+ -------------
+
+ function C_Ioctl
+ (S : C.int;
+ Req : C.int;
+ Arg : Int_Access) return C.int
+ is
+ begin
+ if not Thread_Blocking_IO
+ and then Req = Constants.FIONBIO
+ then
+ if Arg.all /= 0 then
+ Set_Non_Blocking_Socket (S, True);
+ end if;
+ end if;
+
+ return Syscall_Ioctl (S, Req, Arg);
+ end C_Ioctl;
+
+ ------------
+ -- C_Recv --
+ ------------
+
+ function C_Recv
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int) return C.int
+ is
+ Res : C.int;
+
+ begin
+ loop
+ Res := Syscall_Recv (S, Msg, Len, Flags);
+ exit when Thread_Blocking_IO
+ or else Res /= Failure
+ or else Non_Blocking_Socket (S)
+ or else Errno /= Constants.EWOULDBLOCK;
+ delay Quantum;
+ end loop;
+
+ return Res;
+ end C_Recv;
+
+ ----------------
+ -- C_Recvfrom --
+ ----------------
+
+ function C_Recvfrom
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int;
+ From : Sockaddr_In_Access;
+ Fromlen : access C.int) return C.int
+ is
+ Res : C.int;
+
+ begin
+ loop
+ Res := Syscall_Recvfrom (S, Msg, Len, Flags, From, Fromlen);
+ exit when Thread_Blocking_IO
+ or else Res /= Failure
+ or else Non_Blocking_Socket (S)
+ or else Errno /= Constants.EWOULDBLOCK;
+ delay Quantum;
+ end loop;
+
+ return Res;
+ end C_Recvfrom;
+
+ ------------
+ -- C_Send --
+ ------------
+
+ function C_Send
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int) return C.int
+ is
+ Res : C.int;
+
+ begin
+ loop
+ Res := Syscall_Send (S, Msg, Len, Flags);
+ exit when Thread_Blocking_IO
+ or else Res /= Failure
+ or else Non_Blocking_Socket (S)
+ or else Errno /= Constants.EWOULDBLOCK;
+ delay Quantum;
+ end loop;
+
+ return Res;
+ end C_Send;
+
+ --------------
+ -- C_Sendto --
+ --------------
+
+ function C_Sendto
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int;
+ To : Sockaddr_In_Access;
+ Tolen : C.int) return C.int
+ is
+ Res : C.int;
+
+ begin
+ loop
+ Res := Syscall_Sendto (S, Msg, Len, Flags, To, Tolen);
+ exit when Thread_Blocking_IO
+ or else Res /= Failure
+ or else Non_Blocking_Socket (S)
+ or else Errno /= Constants.EWOULDBLOCK;
+ delay Quantum;
+ end loop;
+
+ return Res;
+ end C_Sendto;
+
+ --------------
+ -- C_Socket --
+ --------------
+
+ function C_Socket
+ (Domain : C.int;
+ Typ : C.int;
+ Protocol : C.int) return C.int
+ is
+ R : C.int;
+ Val : aliased C.int := 1;
+
+ Discard : C.int;
+ pragma Unreferenced (Discard);
+
+ begin
+ R := Syscall_Socket (Domain, Typ, Protocol);
+
+ if not Thread_Blocking_IO
+ and then R /= Failure
+ then
+ -- Do not use C_Ioctl as this subprogram tracks sockets set
+ -- in non-blocking mode by user.
+
+ Discard := Syscall_Ioctl (R, Constants.FIONBIO, Val'Unchecked_Access);
+ Set_Non_Blocking_Socket (R, False);
+ end if;
+
+ return R;
+ end C_Socket;
+
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize is
+ begin
+ null;
+ end Finalize;
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize (Process_Blocking_IO : Boolean) is
+ begin
+ Thread_Blocking_IO := not Process_Blocking_IO;
+ end Initialize;
+
+ -------------------------
+ -- Non_Blocking_Socket --
+ -------------------------
+
+ function Non_Blocking_Socket (S : C.int) return Boolean is
+ R : Boolean;
+ begin
+ Task_Lock.Lock;
+ R := Is_Socket_In_Set (Non_Blocking_Sockets, S);
+ Task_Lock.Unlock;
+ return R;
+ end Non_Blocking_Socket;
+
+ -----------------
+ -- Set_Address --
+ -----------------
+
+ procedure Set_Address (Sin : Sockaddr_In_Access; Address : In_Addr) is
+ begin
+ Sin.Sin_Addr := Address;
+ end Set_Address;
+
+ ----------------
+ -- Set_Family --
+ ----------------
+
+ procedure Set_Family (Sin : Sockaddr_In_Access; Family : C.int) is
+ begin
+ Sin.Sin_Family := C.unsigned_short (Family);
+ end Set_Family;
+
+ ----------------
+ -- Set_Length --
+ ----------------
+
+ procedure Set_Length (Sin : Sockaddr_In_Access; Len : C.int) is
+ pragma Unreferenced (Sin);
+ pragma Unreferenced (Len);
+ begin
+ null;
+ end Set_Length;
+
+ -----------------------------
+ -- Set_Non_Blocking_Socket --
+ -----------------------------
+
+ procedure Set_Non_Blocking_Socket (S : C.int; V : Boolean) is
+ begin
+ Task_Lock.Lock;
+
+ if V then
+ Insert_Socket_In_Set (Non_Blocking_Sockets, S);
+ else
+ Remove_Socket_From_Set (Non_Blocking_Sockets, S);
+ end if;
+
+ Task_Lock.Unlock;
+ end Set_Non_Blocking_Socket;
+
+ --------------
+ -- Set_Port --
+ --------------
+
+ procedure Set_Port (Sin : Sockaddr_In_Access; Port : C.unsigned_short) is
+ begin
+ Sin.Sin_Port := Port;
+ end Set_Port;
+
+ --------------------------
+ -- Socket_Error_Message --
+ --------------------------
+
+ 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;
+
+ -------------
+ -- C_Readv --
+ -------------
+
+ function C_Readv
+ (Fd : C.int;
+ Iov : System.Address;
+ Iovcnt : C.int) return C.int
+ is
+ Res : C.int;
+ Count : C.int := 0;
+
+ Iovec : array (0 .. Iovcnt - 1) of Vector_Element;
+ for Iovec'Address use Iov;
+ pragma Import (Ada, Iovec);
+
+ begin
+ for J in Iovec'Range loop
+ Res := C_Read
+ (Fd,
+ Iovec (J).Base.all'Address,
+ Interfaces.C.int (Iovec (J).Length));
+
+ if Res < 0 then
+ return Res;
+ else
+ Count := Count + Res;
+ end if;
+ end loop;
+ return Count;
+ end C_Readv;
+
+ --------------
+ -- C_Writev --
+ --------------
+
+ function C_Writev
+ (Fd : C.int;
+ Iov : System.Address;
+ Iovcnt : C.int) return C.int
+ is
+ Res : C.int;
+ Count : C.int := 0;
+
+ Iovec : array (0 .. Iovcnt - 1) of Vector_Element;
+ for Iovec'Address use Iov;
+ pragma Import (Ada, Iovec);
+
+ begin
+ for J in Iovec'Range loop
+ Res := C_Write
+ (Fd,
+ Iovec (J).Base.all'Address,
+ Interfaces.C.int (Iovec (J).Length));
+
+ if Res < 0 then
+ return Res;
+ else
+ Count := Count + Res;
+ end if;
+ end loop;
+ return Count;
+ end C_Writev;
+
+end GNAT.Sockets.Thin;
diff --git a/gcc/ada/g-socthi-vms.ads b/gcc/ada/g-socthi-vms.ads
new file mode 100644
index 00000000000..a3985525f7c
--- /dev/null
+++ b/gcc/ada/g-socthi-vms.ads
@@ -0,0 +1,445 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . S O C K E T S . T H I N --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2002-2004 Ada Core Technologies, 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides a target dependent thin interface to the sockets
+-- layer for use by the GNAT.Sockets package (g-socket.ads). This package
+-- should not be directly with'ed by an applications program.
+
+-- This is the Alpha/VMS version.
+
+with Interfaces.C.Pointers;
+
+with Interfaces.C.Strings;
+with GNAT.Sockets.Constants;
+with GNAT.OS_Lib;
+
+with System;
+
+package GNAT.Sockets.Thin is
+
+ -- ??? more comments needed ???
+
+ package C renames Interfaces.C;
+
+ use type C.int;
+ -- This is so we can declare the Failure constant below
+
+ Success : constant C.int := 0;
+ Failure : constant C.int := -1;
+
+ function Socket_Errno return Integer renames GNAT.OS_Lib.Errno;
+ -- Returns last socket error number.
+
+ function Socket_Error_Message (Errno : Integer) return C.Strings.chars_ptr;
+ -- Returns the error message string for the error number Errno. If
+ -- Errno is not known it returns "Unknown system error".
+
+ subtype Fd_Set_Access is System.Address;
+ No_Fd_Set : constant Fd_Set_Access := System.Null_Address;
+
+ type Timeval_Unit is new C.int;
+ pragma Convention (C, Timeval_Unit);
+
+ type Timeval is record
+ Tv_Sec : Timeval_Unit;
+ Tv_Usec : Timeval_Unit;
+ end record;
+ pragma Convention (C, Timeval);
+
+ type Timeval_Access is access all Timeval;
+ pragma Convention (C, Timeval_Access);
+
+ Immediat : constant Timeval := (0, 0);
+
+ type Int_Access is access all C.int;
+ pragma Convention (C, Int_Access);
+ -- Access to C integers
+
+ type Chars_Ptr_Array is array (C.size_t range <>) of
+ aliased C.Strings.chars_ptr;
+
+ package Chars_Ptr_Pointers is
+ new C.Pointers (C.size_t, C.Strings.chars_ptr, Chars_Ptr_Array,
+ C.Strings.Null_Ptr);
+ -- Arrays of C (char *)
+
+ type In_Addr is record
+ S_B1, S_B2, S_B3, S_B4 : C.unsigned_char;
+ end record;
+ pragma Convention (C, In_Addr);
+ -- Internet address
+
+ type In_Addr_Access is access all In_Addr;
+ pragma Convention (C, In_Addr_Access);
+ -- Access to internet address
+
+ Inaddr_Any : aliased constant In_Addr := (others => 0);
+ -- Any internet address (all the interfaces)
+
+ type In_Addr_Access_Array is array (C.size_t range <>)
+ of aliased In_Addr_Access;
+ pragma Convention (C, In_Addr_Access_Array);
+
+ package In_Addr_Access_Pointers is
+ new C.Pointers (C.size_t, In_Addr_Access, In_Addr_Access_Array, null);
+ -- Array of internet addresses
+
+ type Sockaddr is record
+ Sa_Family : C.unsigned_short;
+ Sa_Data : C.char_array (1 .. 14);
+ end record;
+ pragma Convention (C, Sockaddr);
+ -- Socket address
+
+ type Sockaddr_Access is access all Sockaddr;
+ pragma Convention (C, Sockaddr_Access);
+ -- Access to socket address
+
+ type Sockaddr_In is record
+ Sin_Family : C.unsigned_short := Constants.AF_INET;
+ Sin_Port : C.unsigned_short := 0;
+ Sin_Addr : In_Addr := Inaddr_Any;
+ Sin_Zero : C.char_array (1 .. 8) := (others => C.char'Val (0));
+ end record;
+ pragma Convention (C, Sockaddr_In);
+ -- Internet socket address
+
+ type Sockaddr_In_Access is access all Sockaddr_In;
+ pragma Convention (C, Sockaddr_In_Access);
+ -- Access to internet socket address
+
+ procedure Set_Length
+ (Sin : Sockaddr_In_Access;
+ Len : C.int);
+ pragma Inline (Set_Length);
+ -- Set Sin.Sin_Length to Len.
+ -- On this platform, nothing is done as there is no such field.
+
+ procedure Set_Family
+ (Sin : Sockaddr_In_Access;
+ Family : C.int);
+ pragma Inline (Set_Family);
+ -- Set Sin.Sin_Family to Family
+
+ procedure Set_Port
+ (Sin : Sockaddr_In_Access;
+ Port : C.unsigned_short);
+ pragma Inline (Set_Port);
+ -- Set Sin.Sin_Port to Port
+
+ procedure Set_Address
+ (Sin : Sockaddr_In_Access;
+ Address : In_Addr);
+ pragma Inline (Set_Address);
+ -- Set Sin.Sin_Addr to Address
+
+ type Hostent is record
+ H_Name : C.Strings.chars_ptr;
+ H_Aliases : Chars_Ptr_Pointers.Pointer;
+ H_Addrtype : C.int;
+ H_Length : C.int;
+ H_Addr_List : In_Addr_Access_Pointers.Pointer;
+ end record;
+ pragma Convention (C, Hostent);
+ -- Host entry
+
+ type Hostent_Access is access all Hostent;
+ pragma Convention (C, Hostent_Access);
+ -- Access to host entry
+
+ 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_Access is access all Servent;
+ pragma Convention (C, Servent_Access);
+ -- Access to service entry
+
+ type Two_Int is array (0 .. 1) of C.int;
+ pragma Convention (C, Two_Int);
+ -- Used with pipe()
+
+ function C_Accept
+ (S : C.int;
+ Addr : System.Address;
+ Addrlen : access C.int)
+ return C.int;
+
+ function C_Bind
+ (S : C.int;
+ Name : System.Address;
+ Namelen : C.int)
+ return C.int;
+
+ function C_Close
+ (Fd : C.int)
+ return C.int;
+
+ function C_Connect
+ (S : C.int;
+ Name : System.Address;
+ Namelen : C.int)
+ return C.int;
+
+ function C_Gethostbyaddr
+ (Addr : System.Address;
+ Len : C.int;
+ Typ : C.int)
+ return Hostent_Access;
+
+ function C_Gethostbyname
+ (Name : C.char_array)
+ return Hostent_Access;
+
+ function C_Gethostname
+ (Name : System.Address;
+ Namelen : C.int)
+ return C.int;
+
+ function C_Getpeername
+ (S : C.int;
+ Name : System.Address;
+ Namelen : access C.int)
+ return C.int;
+
+ function C_Getservbyname
+ (Name : C.char_array;
+ Proto : C.char_array)
+ return Servent_Access;
+
+ function C_Getservbyport
+ (Port : C.int;
+ Proto : C.char_array)
+ return Servent_Access;
+
+ function C_Getsockname
+ (S : C.int;
+ Name : System.Address;
+ Namelen : access C.int)
+ return C.int;
+
+ function C_Getsockopt
+ (S : C.int;
+ Level : C.int;
+ Optname : C.int;
+ Optval : System.Address;
+ Optlen : access C.int)
+ return C.int;
+
+ function C_Inet_Addr
+ (Cp : C.Strings.chars_ptr)
+ return C.int;
+
+ function C_Ioctl
+ (S : C.int;
+ Req : C.int;
+ Arg : Int_Access)
+ return C.int;
+
+ function C_Listen (S, Backlog : C.int) return C.int;
+
+ function C_Read
+ (Fd : C.int;
+ Buf : System.Address;
+ Count : C.int)
+ return C.int;
+
+ function C_Readv
+ (Fd : C.int;
+ Iov : System.Address;
+ Iovcnt : C.int)
+ return C.int;
+
+ function C_Recv
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int)
+ return C.int;
+
+ function C_Recvfrom
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int;
+ From : Sockaddr_In_Access;
+ Fromlen : access C.int)
+ return C.int;
+
+ function C_Select
+ (Nfds : C.int;
+ Readfds : Fd_Set_Access;
+ Writefds : Fd_Set_Access;
+ Exceptfds : Fd_Set_Access;
+ Timeout : Timeval_Access)
+ return C.int;
+
+ function C_Send
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int)
+ return C.int;
+
+ function C_Sendto
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int;
+ To : Sockaddr_In_Access;
+ Tolen : C.int)
+ return C.int;
+
+ function C_Setsockopt
+ (S : C.int;
+ Level : C.int;
+ Optname : C.int;
+ Optval : System.Address;
+ Optlen : C.int)
+ return C.int;
+
+ function C_Shutdown
+ (S : C.int;
+ How : C.int)
+ return C.int;
+
+ function C_Socket
+ (Domain : C.int;
+ 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;
+
+ function C_Write
+ (Fd : C.int;
+ Buf : System.Address;
+ Count : C.int)
+ return C.int;
+
+ function C_Writev
+ (Fd : C.int;
+ Iov : System.Address;
+ Iovcnt : C.int)
+ return C.int;
+
+ procedure Free_Socket_Set
+ (Set : Fd_Set_Access);
+ -- Free system-dependent socket set.
+
+ procedure Get_Socket_From_Set
+ (Set : Fd_Set_Access;
+ Socket : Int_Access;
+ Last : Int_Access);
+ -- Get last socket in Socket and remove it from the socket
+ -- set. The parameter Last is a maximum value of the largest
+ -- socket. This hint is used to avoid scanning very large socket
+ -- sets. After a call to Get_Socket_From_Set, Last is set back to
+ -- the real largest socket in the socket set.
+
+ procedure Insert_Socket_In_Set
+ (Set : Fd_Set_Access;
+ Socket : C.int);
+ -- Insert socket in the socket set.
+
+ function Is_Socket_In_Set
+ (Set : Fd_Set_Access;
+ Socket : C.int)
+ return Boolean;
+ -- Check whether Socket is in the socket set.
+
+ procedure Last_Socket_In_Set
+ (Set : Fd_Set_Access;
+ Last : Int_Access);
+ -- Find the largest socket in the socket set. This is needed for
+ -- select(). When Last_Socket_In_Set is called, parameter Last is
+ -- a maximum value of the largest socket. This hint is used to
+ -- avoid scanning very large socket sets. After the call, Last is
+ -- set back to the real largest socket in the socket set.
+
+ function New_Socket_Set
+ (Set : Fd_Set_Access)
+ return Fd_Set_Access;
+ -- Allocate a new socket set which is a system-dependent structure
+ -- and initialize by copying Set if it is non-null, by making it
+ -- empty otherwise.
+
+ procedure Remove_Socket_From_Set
+ (Set : Fd_Set_Access;
+ Socket : C.int);
+ -- Remove socket from the socket set.
+
+ procedure Finalize;
+ procedure Initialize (Process_Blocking_IO : Boolean);
+
+private
+
+ pragma Import (C, C_Bind, "DECC$BIND");
+ pragma Import (C, C_Close, "DECC$CLOSE");
+ pragma Import (C, C_Gethostbyaddr, "DECC$GETHOSTBYADDR");
+ pragma Import (C, C_Gethostbyname, "DECC$GETHOSTBYNAME");
+ pragma Import (C, C_Gethostname, "DECC$GETHOSTNAME");
+ pragma Import (C, C_Getpeername, "DECC$GETPEERNAME");
+ pragma Import (C, C_Getservbyname, "DECC$GETSERVBYNAME");
+ pragma Import (C, C_Getservbyport, "DECC$GETSERVBYPORT");
+ pragma Import (C, C_Getsockname, "DECC$GETSOCKNAME");
+ pragma Import (C, C_Getsockopt, "DECC$GETSOCKOPT");
+ pragma Import (C, C_Inet_Addr, "DECC$INET_ADDR");
+ pragma Import (C, C_Listen, "DECC$LISTEN");
+ pragma Import (C, C_Read, "DECC$READ");
+ 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, C_Write, "DECC$WRITE");
+
+ pragma Import (C, Free_Socket_Set, "__gnat_free_socket_set");
+ pragma Import (C, Get_Socket_From_Set, "__gnat_get_socket_from_set");
+ pragma Import (C, Is_Socket_In_Set, "__gnat_is_socket_in_set");
+ pragma Import (C, Last_Socket_In_Set, "__gnat_last_socket_in_set");
+ pragma Import (C, New_Socket_Set, "__gnat_new_socket_set");
+ pragma Import (C, Insert_Socket_In_Set, "__gnat_insert_socket_in_set");
+ pragma Import (C, Remove_Socket_From_Set, "__gnat_remove_socket_from_set");
+end GNAT.Sockets.Thin;
diff --git a/gcc/ada/g-socthi-vxworks.adb b/gcc/ada/g-socthi-vxworks.adb
new file mode 100644
index 00000000000..28e22418847
--- /dev/null
+++ b/gcc/ada/g-socthi-vxworks.adb
@@ -0,0 +1,624 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . S O C K E T S . T H I N --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2002-2004 Ada Core Technologies, 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides a target dependent thin interface to the sockets
+-- layer for use by the GNAT.Sockets package (g-socket.ads). This package
+-- should not be directly with'ed by an applications program.
+
+-- This version is for VxWorks
+
+with GNAT.OS_Lib; use GNAT.OS_Lib;
+with GNAT.Task_Lock;
+
+with Interfaces.C; use Interfaces.C;
+with Unchecked_Conversion;
+
+package body GNAT.Sockets.Thin is
+
+ Non_Blocking_Sockets : constant Fd_Set_Access :=
+ New_Socket_Set (No_Socket_Set);
+ -- When this package is initialized with Process_Blocking_IO set
+ -- to True, sockets are set in non-blocking mode to avoid blocking
+ -- the whole process when a thread wants to perform a blocking IO
+ -- operation. But the user can also set a socket in non-blocking
+ -- mode by purpose. In order to make a difference between these
+ -- two situations, we track the origin of non-blocking mode in
+ -- Non_Blocking_Sockets. If S is in Non_Blocking_Sockets, it has
+ -- been set in non-blocking mode by the user.
+
+ Quantum : constant Duration := 0.2;
+ -- When Thread_Blocking_IO is False, we set sockets in
+ -- non-blocking mode and we spend a period of time Quantum between
+ -- two attempts on a blocking operation.
+
+ Thread_Blocking_IO : Boolean := True;
+
+ Unknown_System_Error : constant C.Strings.chars_ptr :=
+ C.Strings.New_String ("Unknown system error");
+
+ -- The following types and variables are required to create a Hostent
+ -- record "by hand".
+
+ type In_Addr_Access_Array_Access is access In_Addr_Access_Array;
+
+ Alias_Access : constant Chars_Ptr_Pointers.Pointer :=
+ new C.Strings.chars_ptr'(C.Strings.Null_Ptr);
+
+ In_Addr_Access_Array_A : constant In_Addr_Access_Array_Access :=
+ new In_Addr_Access_Array'(new In_Addr, null);
+
+ In_Addr_Access_Ptr : constant In_Addr_Access_Pointers.Pointer :=
+ In_Addr_Access_Array_A
+ (In_Addr_Access_Array_A'First)'Access;
+
+ Local_Hostent : constant Hostent_Access := new Hostent;
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ -- All these require comments ???
+
+ function Syscall_Accept
+ (S : C.int;
+ Addr : System.Address;
+ Addrlen : access C.int) return C.int;
+ pragma Import (C, Syscall_Accept, "accept");
+
+ function Syscall_Connect
+ (S : C.int;
+ Name : System.Address;
+ Namelen : C.int) return C.int;
+ pragma Import (C, Syscall_Connect, "connect");
+
+ function Syscall_Ioctl
+ (S : C.int;
+ Req : C.int;
+ Arg : Int_Access) return C.int;
+ pragma Import (C, Syscall_Ioctl, "ioctl");
+
+ function Syscall_Recv
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int) return C.int;
+ pragma Import (C, Syscall_Recv, "recv");
+
+ function Syscall_Recvfrom
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int;
+ From : Sockaddr_In_Access;
+ Fromlen : access C.int) return C.int;
+ pragma Import (C, Syscall_Recvfrom, "recvfrom");
+
+ function Syscall_Send
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int) return C.int;
+ pragma Import (C, Syscall_Send, "send");
+
+ function Syscall_Sendto
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int;
+ To : Sockaddr_In_Access;
+ Tolen : C.int) return C.int;
+ pragma Import (C, Syscall_Sendto, "sendto");
+
+ function Syscall_Socket
+ (Domain : C.int;
+ Typ : C.int;
+ Protocol : C.int) return C.int;
+ pragma Import (C, Syscall_Socket, "socket");
+
+ function Non_Blocking_Socket (S : C.int) return Boolean;
+ procedure Set_Non_Blocking_Socket (S : C.int; V : Boolean);
+
+ --------------
+ -- C_Accept --
+ --------------
+
+ function C_Accept
+ (S : C.int;
+ Addr : System.Address;
+ Addrlen : access C.int) return C.int
+ is
+ R : C.int;
+ Val : aliased C.int := 1;
+
+ Res : C.int;
+ pragma Unreferenced (Res);
+
+ begin
+ loop
+ R := Syscall_Accept (S, Addr, Addrlen);
+ exit when Thread_Blocking_IO
+ or else R /= Failure
+ or else Non_Blocking_Socket (S)
+ or else Errno /= Constants.EWOULDBLOCK;
+ delay Quantum;
+ end loop;
+
+ if not Thread_Blocking_IO
+ and then R /= Failure
+ then
+ -- A socket inherits the properties ot its server especially
+ -- the FIONBIO flag. Do not use C_Ioctl as this subprogram
+ -- tracks sockets set in non-blocking mode by user.
+
+ Set_Non_Blocking_Socket (R, Non_Blocking_Socket (S));
+ Res := Syscall_Ioctl (R, Constants.FIONBIO, Val'Unchecked_Access);
+ -- Is it OK to ignore result ???
+ end if;
+
+ return R;
+ end C_Accept;
+
+ ---------------
+ -- C_Connect --
+ ---------------
+
+ function C_Connect
+ (S : C.int;
+ Name : System.Address;
+ Namelen : C.int) return C.int
+ is
+ Res : C.int;
+
+ begin
+ Res := Syscall_Connect (S, Name, Namelen);
+
+ if Thread_Blocking_IO
+ or else Res /= Failure
+ or else Non_Blocking_Socket (S)
+ or else Errno /= Constants.EINPROGRESS
+ then
+ return Res;
+ end if;
+
+ declare
+ WSet : Fd_Set_Access;
+ Now : aliased Timeval;
+
+ begin
+ WSet := New_Socket_Set (No_Socket_Set);
+
+ loop
+ Insert_Socket_In_Set (WSet, S);
+ Now := Immediat;
+ Res := C_Select
+ (S + 1,
+ No_Fd_Set,
+ WSet,
+ No_Fd_Set,
+ Now'Unchecked_Access);
+
+ exit when Res > 0;
+
+ if Res = Failure then
+ Free_Socket_Set (WSet);
+ return Res;
+ end if;
+
+ delay Quantum;
+ end loop;
+
+ Free_Socket_Set (WSet);
+ end;
+
+ Res := Syscall_Connect (S, Name, Namelen);
+
+ if Res = Failure
+ and then Errno = Constants.EISCONN
+ then
+ return Thin.Success;
+ else
+ return Res;
+ end if;
+ end C_Connect;
+
+ ---------------------
+ -- C_Gethostbyaddr --
+ ---------------------
+
+ function C_Gethostbyaddr
+ (Addr : System.Address;
+ Len : C.int;
+ Typ : C.int) return Hostent_Access
+ is
+ pragma Warnings (Off, Len);
+ pragma Warnings (Off, Typ);
+
+ type int_Access is access int;
+ function To_Pointer is
+ new Unchecked_Conversion (System.Address, int_Access);
+
+ procedure VxWorks_Gethostbyaddr
+ (Addr : C.int; Buf : out C.char_array);
+ pragma Import (C, VxWorks_Gethostbyaddr, "hostGetByAddr");
+
+ Host_Name : C.char_array (1 .. Max_Name_Length);
+
+ begin
+ VxWorks_Gethostbyaddr (To_Pointer (Addr).all, Host_Name);
+
+ In_Addr_Access_Ptr.all.all := To_In_Addr (To_Pointer (Addr).all);
+ Local_Hostent.all.H_Name := C.Strings.New_Char_Array (Host_Name);
+
+ return Local_Hostent;
+ end C_Gethostbyaddr;
+
+ ---------------------
+ -- C_Gethostbyname --
+ ---------------------
+
+ function C_Gethostbyname
+ (Name : C.char_array) return Hostent_Access
+ is
+ function VxWorks_Gethostbyname
+ (Name : C.char_array) return C.int;
+ pragma Import (C, VxWorks_Gethostbyname, "hostGetByName");
+
+ Addr : C.int;
+
+ begin
+ Addr := VxWorks_Gethostbyname (Name);
+
+ In_Addr_Access_Ptr.all.all := To_In_Addr (Addr);
+ Local_Hostent.all.H_Name := C.Strings.New_Char_Array (To_C (Host_Name));
+
+ return Local_Hostent;
+ end C_Gethostbyname;
+
+ ---------------------
+ -- C_Getservbyname --
+ ---------------------
+
+ function C_Getservbyname
+ (Name : C.char_array;
+ Proto : C.char_array) return Servent_Access
+ is
+ pragma Warnings (Off, Name);
+ pragma Warnings (Off, Proto);
+
+ begin
+ return null;
+ end C_Getservbyname;
+
+ ---------------------
+ -- C_Getservbyport --
+ ---------------------
+
+ function C_Getservbyport
+ (Port : C.int;
+ Proto : C.char_array) return Servent_Access
+ is
+ pragma Warnings (Off, Port);
+ pragma Warnings (Off, Proto);
+
+ begin
+ return null;
+ end C_Getservbyport;
+
+ -------------
+ -- C_Ioctl --
+ -------------
+
+ function C_Ioctl
+ (S : C.int;
+ Req : C.int;
+ Arg : Int_Access) return C.int
+ is
+ begin
+ if not Thread_Blocking_IO
+ and then Req = Constants.FIONBIO
+ then
+ if Arg.all /= 0 then
+ Set_Non_Blocking_Socket (S, True);
+ end if;
+ end if;
+
+ return Syscall_Ioctl (S, Req, Arg);
+ end C_Ioctl;
+
+ ------------
+ -- C_Recv --
+ ------------
+
+ function C_Recv
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int) return C.int
+ is
+ Res : C.int;
+
+ begin
+ loop
+ Res := Syscall_Recv (S, Msg, Len, Flags);
+ exit when Thread_Blocking_IO
+ or else Res /= Failure
+ or else Non_Blocking_Socket (S)
+ or else Errno /= Constants.EWOULDBLOCK;
+ delay Quantum;
+ end loop;
+
+ return Res;
+ end C_Recv;
+
+ ----------------
+ -- C_Recvfrom --
+ ----------------
+
+ function C_Recvfrom
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int;
+ From : Sockaddr_In_Access;
+ Fromlen : access C.int) return C.int
+ is
+ Res : C.int;
+
+ begin
+ loop
+ Res := Syscall_Recvfrom (S, Msg, Len, Flags, From, Fromlen);
+ exit when Thread_Blocking_IO
+ or else Res /= Failure
+ or else Non_Blocking_Socket (S)
+ or else Errno /= Constants.EWOULDBLOCK;
+ delay Quantum;
+ end loop;
+
+ return Res;
+ end C_Recvfrom;
+
+ ------------
+ -- C_Send --
+ ------------
+
+ function C_Send
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int) return C.int
+ is
+ Res : C.int;
+
+ begin
+ loop
+ Res := Syscall_Send (S, Msg, Len, Flags);
+ exit when Thread_Blocking_IO
+ or else Res /= Failure
+ or else Non_Blocking_Socket (S)
+ or else Errno /= Constants.EWOULDBLOCK;
+ delay Quantum;
+ end loop;
+
+ return Res;
+ end C_Send;
+
+ --------------
+ -- C_Sendto --
+ --------------
+
+ function C_Sendto
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int;
+ To : Sockaddr_In_Access;
+ Tolen : C.int) return C.int
+ is
+ Res : C.int;
+
+ begin
+ loop
+ Res := Syscall_Sendto (S, Msg, Len, Flags, To, Tolen);
+ exit when Thread_Blocking_IO
+ or else Res /= Failure
+ or else Non_Blocking_Socket (S)
+ or else Errno /= Constants.EWOULDBLOCK;
+ delay Quantum;
+ end loop;
+
+ return Res;
+ end C_Sendto;
+
+ --------------
+ -- C_Socket --
+ --------------
+
+ function C_Socket
+ (Domain : C.int;
+ Typ : C.int;
+ Protocol : C.int) return C.int
+ is
+ R : C.int;
+ Val : aliased C.int := 1;
+
+ Res : C.int;
+ pragma Unreferenced (Res);
+
+ begin
+ R := Syscall_Socket (Domain, Typ, Protocol);
+
+ if not Thread_Blocking_IO
+ and then R /= Failure
+ then
+ -- Do not use C_Ioctl as this subprogram tracks sockets set
+ -- in non-blocking mode by user.
+
+ Res := Syscall_Ioctl (R, Constants.FIONBIO, Val'Unchecked_Access);
+ -- Is it OK to ignore result ???
+ Set_Non_Blocking_Socket (R, False);
+ end if;
+
+ return R;
+ end C_Socket;
+
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize is
+ begin
+ null;
+ end Finalize;
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize (Process_Blocking_IO : Boolean) is
+ begin
+ Thread_Blocking_IO := not Process_Blocking_IO;
+ end Initialize;
+
+ -------------------------
+ -- Non_Blocking_Socket --
+ -------------------------
+
+ function Non_Blocking_Socket (S : C.int) return Boolean is
+ R : Boolean;
+
+ begin
+ Task_Lock.Lock;
+ R := Is_Socket_In_Set (Non_Blocking_Sockets, S);
+ Task_Lock.Unlock;
+ return R;
+ end Non_Blocking_Socket;
+
+ -----------------
+ -- Set_Address --
+ -----------------
+
+ procedure Set_Address
+ (Sin : Sockaddr_In_Access;
+ Address : In_Addr)
+ is
+ begin
+ Sin.Sin_Addr := Address;
+ end Set_Address;
+
+ ----------------
+ -- Set_Family --
+ ----------------
+
+ procedure Set_Family
+ (Sin : Sockaddr_In_Access;
+ Family : C.int)
+ is
+ begin
+ Sin.Sin_Family := C.unsigned_char (Family);
+ end Set_Family;
+
+ ----------------
+ -- Set_Length --
+ ----------------
+
+ procedure Set_Length
+ (Sin : Sockaddr_In_Access;
+ Len : C.int)
+ is
+ begin
+ Sin.Sin_Length := C.unsigned_char (Len);
+ end Set_Length;
+
+ -----------------------------
+ -- Set_Non_Blocking_Socket --
+ -----------------------------
+
+ procedure Set_Non_Blocking_Socket (S : C.int; V : Boolean) is
+ begin
+ Task_Lock.Lock;
+ if V then
+ Insert_Socket_In_Set (Non_Blocking_Sockets, S);
+ else
+ Remove_Socket_From_Set (Non_Blocking_Sockets, S);
+ end if;
+
+ Task_Lock.Unlock;
+ end Set_Non_Blocking_Socket;
+
+ --------------
+ -- Set_Port --
+ --------------
+
+ procedure Set_Port
+ (Sin : Sockaddr_In_Access;
+ Port : C.unsigned_short)
+ is
+ begin
+ Sin.Sin_Port := Port;
+ end Set_Port;
+
+ --------------------------
+ -- Socket_Error_Message --
+ --------------------------
+
+ 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;
+
+-- Package elaboration
+
+begin
+ Local_Hostent.all.H_Aliases := Alias_Access;
+
+ -- VxWorks currently only supports AF_INET
+
+ Local_Hostent.all.H_Addrtype := Constants.AF_INET;
+
+ Local_Hostent.all.H_Length := 1;
+ Local_Hostent.all.H_Addr_List := In_Addr_Access_Ptr;
+
+end GNAT.Sockets.Thin;
diff --git a/gcc/ada/g-socthi-vxworks.ads b/gcc/ada/g-socthi-vxworks.ads
new file mode 100644
index 00000000000..3642a038bec
--- /dev/null
+++ b/gcc/ada/g-socthi-vxworks.ads
@@ -0,0 +1,446 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . S O C K E T S . T H I N --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2002-2004 Ada Core Technologies, 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides a target dependent thin interface to the sockets
+-- layer for use by the GNAT.Sockets package (g-socket.ads). This package
+-- should not be directly with'ed by an applications program.
+
+-- This is the version for VxWorks
+
+with Interfaces.C.Pointers;
+
+with Ada.Unchecked_Conversion;
+with Interfaces.C.Strings;
+with GNAT.Sockets.Constants;
+with GNAT.OS_Lib;
+
+with System;
+
+package GNAT.Sockets.Thin is
+
+ package C renames Interfaces.C;
+
+ use type C.int;
+ -- This is so we can declare the Failure constant below
+
+ Success : constant C.int := 0;
+ Failure : constant C.int := -1;
+
+ function Socket_Errno return Integer renames GNAT.OS_Lib.Errno;
+ -- Returns last socket error number.
+
+ function Socket_Error_Message (Errno : Integer) return C.Strings.chars_ptr;
+ -- Returns the error message string for the error number Errno. If
+ -- Errno is not known it returns "Unknown system error".
+
+ subtype Fd_Set_Access is System.Address;
+ No_Fd_Set : constant Fd_Set_Access := System.Null_Address;
+
+ type Timeval_Unit is new C.int;
+ pragma Convention (C, Timeval_Unit);
+
+ type Timeval is record
+ Tv_Sec : Timeval_Unit;
+ Tv_Usec : Timeval_Unit;
+ end record;
+ pragma Convention (C, Timeval);
+
+ type Timeval_Access is access all Timeval;
+ pragma Convention (C, Timeval_Access);
+
+ Immediat : constant Timeval := (0, 0);
+
+ type Int_Access is access all C.int;
+ pragma Convention (C, Int_Access);
+ -- Access to C integers
+
+ type Chars_Ptr_Array is array (C.size_t range <>) of
+ aliased C.Strings.chars_ptr;
+
+ package Chars_Ptr_Pointers is
+ new C.Pointers (C.size_t, C.Strings.chars_ptr, Chars_Ptr_Array,
+ C.Strings.Null_Ptr);
+ -- Arrays of C (char *)
+
+ type In_Addr is record
+ S_B1, S_B2, S_B3, S_B4 : C.unsigned_char;
+ end record;
+ pragma Convention (C, In_Addr);
+ -- Internet address
+
+ function To_In_Addr is new Ada.Unchecked_Conversion (C.int, In_Addr);
+
+ type In_Addr_Access is access all In_Addr;
+ pragma Convention (C, In_Addr_Access);
+ -- Access to internet address
+
+ Inaddr_Any : aliased constant In_Addr := (others => 0);
+ -- Any internet address (all the interfaces)
+
+ type In_Addr_Access_Array is array (C.size_t range <>)
+ of aliased In_Addr_Access;
+ pragma Convention (C, In_Addr_Access_Array);
+
+ package In_Addr_Access_Pointers is
+ new C.Pointers (C.size_t, In_Addr_Access, In_Addr_Access_Array, null);
+ -- Array of internet addresses
+
+ type Sockaddr is record
+ Sa_Length : C.unsigned_char;
+ Sa_Family : C.unsigned_char;
+ Sa_Data : C.char_array (1 .. 14);
+ end record;
+ pragma Convention (C, Sockaddr);
+ -- Socket address
+
+ type Sockaddr_Access is access all Sockaddr;
+ pragma Convention (C, Sockaddr_Access);
+ -- Access to socket address
+
+ type Sockaddr_In is record
+ Sin_Length : C.unsigned_char := 0;
+ Sin_Family : C.unsigned_char := Constants.AF_INET;
+ Sin_Port : C.unsigned_short := 0;
+ Sin_Addr : In_Addr := Inaddr_Any;
+ Sin_Zero : C.char_array (1 .. 8) := (others => C.char'Val (0));
+ end record;
+ pragma Convention (C, Sockaddr_In);
+ -- Internet socket address
+
+ type Sockaddr_In_Access is access all Sockaddr_In;
+ pragma Convention (C, Sockaddr_In_Access);
+ -- Access to internet socket address
+
+ procedure Set_Length
+ (Sin : Sockaddr_In_Access;
+ Len : C.int);
+ pragma Inline (Set_Length);
+ -- Set Sin.Sin_Length to Len.
+
+ procedure Set_Family
+ (Sin : Sockaddr_In_Access;
+ Family : C.int);
+ pragma Inline (Set_Family);
+ -- Set Sin.Sin_Family to Family.
+
+ procedure Set_Port
+ (Sin : Sockaddr_In_Access;
+ Port : C.unsigned_short);
+ pragma Inline (Set_Port);
+ -- Set Sin.Sin_Port to Port.
+
+ procedure Set_Address
+ (Sin : Sockaddr_In_Access;
+ Address : In_Addr);
+ pragma Inline (Set_Address);
+ -- Set Sin.Sin_Addr to Address.
+
+ type Hostent is record
+ H_Name : C.Strings.chars_ptr;
+ H_Aliases : Chars_Ptr_Pointers.Pointer;
+ H_Addrtype : C.int;
+ H_Length : C.int;
+ H_Addr_List : In_Addr_Access_Pointers.Pointer;
+ end record;
+ pragma Convention (C, Hostent);
+ -- Host entry
+
+ type Hostent_Access is access all Hostent;
+ pragma Convention (C, Hostent_Access);
+ -- Access to host entry
+
+ 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_Access is access all Servent;
+ pragma Convention (C, Servent_Access);
+ -- Access to service entry
+
+ type Two_Int is array (0 .. 1) of C.int;
+ pragma Convention (C, Two_Int);
+ -- Used with pipe()
+
+ function C_Accept
+ (S : C.int;
+ Addr : System.Address;
+ Addrlen : access C.int)
+ return C.int;
+
+ function C_Bind
+ (S : C.int;
+ Name : System.Address;
+ Namelen : C.int)
+ return C.int;
+
+ function C_Close
+ (Fd : C.int)
+ return C.int;
+
+ function C_Connect
+ (S : C.int;
+ Name : System.Address;
+ Namelen : C.int)
+ return C.int;
+
+ function C_Gethostbyaddr
+ (Addr : System.Address;
+ Len : C.int;
+ Typ : C.int)
+ return Hostent_Access;
+
+ function C_Gethostbyname
+ (Name : C.char_array)
+ return Hostent_Access;
+
+ function C_Gethostname
+ (Name : System.Address;
+ Namelen : C.int)
+ return C.int;
+
+ function C_Getpeername
+ (S : C.int;
+ Name : System.Address;
+ Namelen : access C.int)
+ return C.int;
+
+ function C_Getservbyname
+ (Name : C.char_array;
+ Proto : C.char_array)
+ return Servent_Access;
+
+ function C_Getservbyport
+ (Port : C.int;
+ Proto : C.char_array)
+ return Servent_Access;
+
+ function C_Getsockname
+ (S : C.int;
+ Name : System.Address;
+ Namelen : access C.int)
+ return C.int;
+
+ function C_Getsockopt
+ (S : C.int;
+ Level : C.int;
+ Optname : C.int;
+ Optval : System.Address;
+ Optlen : access C.int)
+ return C.int;
+
+ function C_Inet_Addr
+ (Cp : C.Strings.chars_ptr)
+ return C.int;
+
+ function C_Ioctl
+ (S : C.int;
+ Req : C.int;
+ Arg : Int_Access)
+ return C.int;
+
+ function C_Listen (S, Backlog : C.int) return C.int;
+
+ function C_Read
+ (Fd : C.int;
+ Buf : System.Address;
+ Count : C.int)
+ return C.int;
+
+ function C_Readv
+ (Fd : C.int;
+ Iov : System.Address;
+ Iovcnt : C.int)
+ return C.int;
+
+ function C_Recv
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int)
+ return C.int;
+
+ function C_Recvfrom
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int;
+ From : Sockaddr_In_Access;
+ Fromlen : access C.int)
+ return C.int;
+
+ function C_Select
+ (Nfds : C.int;
+ Readfds : Fd_Set_Access;
+ Writefds : Fd_Set_Access;
+ Exceptfds : Fd_Set_Access;
+ Timeout : Timeval_Access)
+ return C.int;
+
+ function C_Send
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int)
+ return C.int;
+
+ function C_Sendto
+ (S : C.int;
+ Msg : System.Address;
+ Len : C.int;
+ Flags : C.int;
+ To : Sockaddr_In_Access;
+ Tolen : C.int)
+ return C.int;
+
+ function C_Setsockopt
+ (S : C.int;
+ Level : C.int;
+ Optname : C.int;
+ Optval : System.Address;
+ Optlen : C.int)
+ return C.int;
+
+ function C_Shutdown
+ (S : C.int;
+ How : C.int)
+ return C.int;
+
+ function C_Socket
+ (Domain : C.int;
+ 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;
+
+ function C_Write
+ (Fd : C.int;
+ Buf : System.Address;
+ Count : C.int)
+ return C.int;
+
+ function C_Writev
+ (Fd : C.int;
+ Iov : System.Address;
+ Iovcnt : C.int)
+ return C.int;
+
+ procedure Free_Socket_Set
+ (Set : Fd_Set_Access);
+ -- Free system-dependent socket set
+
+ procedure Get_Socket_From_Set
+ (Set : Fd_Set_Access;
+ Socket : Int_Access;
+ Last : Int_Access);
+ -- Get last socket in Socket and remove it from the socket
+ -- set. The parameter Last is a maximum value of the largest
+ -- socket. This hint is used to avoid scanning very large socket
+ -- sets. After a call to Get_Socket_From_Set, Last is set back to
+ -- the real largest socket in the socket set.
+
+ procedure Insert_Socket_In_Set
+ (Set : Fd_Set_Access;
+ Socket : C.int);
+ -- Insert socket in the socket set
+
+ function Is_Socket_In_Set
+ (Set : Fd_Set_Access;
+ Socket : C.int)
+ return Boolean;
+ -- Check whether Socket is in the socket set
+
+ procedure Last_Socket_In_Set
+ (Set : Fd_Set_Access;
+ Last : Int_Access);
+ -- Find the largest socket in the socket set. This is needed for
+ -- select(). When Last_Socket_In_Set is called, parameter Last is
+ -- a maximum value of the largest socket. This hint is used to
+ -- avoid scanning very large socket sets. After the call, Last is
+ -- set back to the real largest socket in the socket set.
+
+ function New_Socket_Set
+ (Set : Fd_Set_Access)
+ return Fd_Set_Access;
+ -- Allocate a new socket set which is a system-dependent structure
+ -- and initialize by copying Set if it is non-null, by making it
+ -- empty otherwise.
+
+ procedure Remove_Socket_From_Set
+ (Set : Fd_Set_Access;
+ Socket : C.int);
+ -- Remove socket from the socket set
+
+ procedure Finalize;
+ procedure Initialize (Process_Blocking_IO : Boolean);
+
+private
+
+ pragma Import (C, C_Bind, "bind");
+ pragma Import (C, C_Close, "close");
+ pragma Import (C, C_Gethostname, "gethostname");
+ pragma Import (C, C_Getpeername, "getpeername");
+ pragma Import (C, C_Getsockname, "getsockname");
+ pragma Import (C, C_Getsockopt, "getsockopt");
+ pragma Import (C, C_Inet_Addr, "inet_addr");
+ pragma Import (C, C_Listen, "listen");
+ pragma Import (C, C_Read, "read");
+ pragma Import (C, C_Readv, "readv");
+ 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, C_Write, "write");
+ pragma Import (C, C_Writev, "writev");
+
+ pragma Import (C, Free_Socket_Set, "__gnat_free_socket_set");
+ pragma Import (C, Get_Socket_From_Set, "__gnat_get_socket_from_set");
+ pragma Import (C, Is_Socket_In_Set, "__gnat_is_socket_in_set");
+ pragma Import (C, Last_Socket_In_Set, "__gnat_last_socket_in_set");
+ pragma Import (C, New_Socket_Set, "__gnat_new_socket_set");
+ pragma Import (C, Insert_Socket_In_Set, "__gnat_insert_socket_in_set");
+ pragma Import (C, Remove_Socket_From_Set, "__gnat_remove_socket_from_set");
+
+end GNAT.Sockets.Thin;
diff --git a/gcc/ada/g-soliop-mingw.ads b/gcc/ada/g-soliop-mingw.ads
new file mode 100644
index 00000000000..e930da934d5
--- /dev/null
+++ b/gcc/ada/g-soliop-mingw.ads
@@ -0,0 +1,43 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . S O C K E T S . L I N K E R _ O P T I O N S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2001-2003 Ada Core Technologies, 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package is used to provide target specific linker_options for the
+-- support of scokets as required by the package GNAT.Sockets.
+
+-- This is the Windows/NT version of this package
+
+
+package GNAT.Sockets.Linker_Options is
+private
+ pragma Linker_Options ("-lwsock32");
+end GNAT.Sockets.Linker_Options;
diff --git a/gcc/ada/g-soliop-solaris.ads b/gcc/ada/g-soliop-solaris.ads
new file mode 100644
index 00000000000..82ac94ff280
--- /dev/null
+++ b/gcc/ada/g-soliop-solaris.ads
@@ -0,0 +1,43 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . S O C K E T S . L I N K E R _ O P T I O N S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2001-2003 Ada Core Technologies, 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package is used to provide target specific linker_options for the
+-- support of scokets as required by the package GNAT.Sockets.
+
+-- This is the Solaris version of this package
+
+package GNAT.Sockets.Linker_Options is
+private
+ pragma Linker_Options ("-lnsl");
+ pragma Linker_Options ("-lsocket");
+end GNAT.Sockets.Linker_Options;
diff --git a/gcc/ada/g-soliop-unixware.ads b/gcc/ada/g-soliop-unixware.ads
new file mode 100644
index 00000000000..754cafd6a1e
--- /dev/null
+++ b/gcc/ada/g-soliop-unixware.ads
@@ -0,0 +1,43 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . S O C K E T S . L I N K E R _ O P T I O N S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2002-2003 Ada Core Technologies, 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package is used to provide target specific linker_options for the
+-- support of scokets as required by the package GNAT.Sockets.
+
+-- This is the UnixWare version of this package
+
+package GNAT.Sockets.Linker_Options is
+private
+ pragma Linker_Options ("-lnsl");
+ pragma Linker_Options ("-lsocket");
+end GNAT.Sockets.Linker_Options;
diff --git a/gcc/ada/g-trasym-vms.adb b/gcc/ada/g-trasym-vms.adb
new file mode 100644
index 00000000000..85f541d018b
--- /dev/null
+++ b/gcc/ada/g-trasym-vms.adb
@@ -0,0 +1,282 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- G N A T . T R A C E B A C K . S Y M B O L I C --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1999-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- Run-time symbolic traceback support for VMS
+
+with Ada.Exceptions.Traceback; use Ada.Exceptions.Traceback;
+with Interfaces.C;
+with System;
+with System.Aux_DEC;
+with System.Soft_Links;
+with System.Traceback_Entries;
+
+package body GNAT.Traceback.Symbolic is
+
+ pragma Warnings (Off);
+ pragma Linker_Options ("--for-linker=sys$library:trace.exe");
+
+ use Interfaces.C;
+ use System;
+ use System.Aux_DEC;
+ use System.Traceback_Entries;
+
+ subtype User_Arg_Type is Unsigned_Longword;
+ subtype Cond_Value_Type is Unsigned_Longword;
+
+ type ASCIC is record
+ Count : unsigned_char;
+ Data : char_array (1 .. 255);
+ end record;
+ pragma Convention (C, ASCIC);
+
+ for ASCIC use record
+ Count at 0 range 0 .. 7;
+ Data at 1 range 0 .. 8 * 255 - 1;
+ end record;
+ for ASCIC'Size use 8 * 256;
+
+ function Fetch_ASCIC is new Fetch_From_Address (ASCIC);
+
+ procedure Symbolize
+ (Status : out Cond_Value_Type;
+ Current_PC : in Address;
+ Adjusted_PC : in Address;
+ Current_FP : in Address;
+ Current_R26 : in Address;
+ Image_Name : out Address;
+ Module_Name : out Address;
+ Routine_Name : out Address;
+ Line_Number : out Integer;
+ Relative_PC : out Address;
+ Absolute_PC : out Address;
+ PC_Is_Valid : out Long_Integer;
+ User_Act_Proc : Address := Address'Null_Parameter;
+ User_Arg_Value : User_Arg_Type := User_Arg_Type'Null_Parameter);
+
+ pragma Interface (External, Symbolize);
+
+ pragma Import_Valued_Procedure
+ (Symbolize, "TBK$SYMBOLIZE",
+ (Cond_Value_Type, Address, Address, Address, Address,
+ Address, Address, Address, Integer,
+ Address, Address, Long_Integer,
+ Address, User_Arg_Type),
+ (Value, Value, Value, Value, Value,
+ Reference, Reference, Reference, Reference,
+ Reference, Reference, Reference,
+ Value, Value),
+ User_Act_Proc);
+
+ function Decode_Ada_Name (Encoded_Name : String) return String;
+ -- Decodes an Ada identifier name. Removes leading "_ada_" and trailing
+ -- __{DIGIT}+ or ${DIGIT}+, converts other "__" to '.'
+
+ ---------------------
+ -- Decode_Ada_Name --
+ ---------------------
+
+ function Decode_Ada_Name (Encoded_Name : String) return String is
+ Decoded_Name : String (1 .. Encoded_Name'Length);
+ Pos : Integer := Encoded_Name'First;
+ Last : Integer := Encoded_Name'Last;
+ DPos : Integer := 1;
+
+ begin
+ if Pos > Last then
+ return "";
+ end if;
+
+ -- Skip leading _ada_
+
+ if Encoded_Name'Length > 4
+ and then Encoded_Name (Pos .. Pos + 4) = "_ada_"
+ then
+ Pos := Pos + 5;
+ end if;
+
+ -- Skip trailing __{DIGIT}+ or ${DIGIT}+
+
+ if Encoded_Name (Last) in '0' .. '9' then
+ for J in reverse Pos + 2 .. Last - 1 loop
+ case Encoded_Name (J) is
+ when '0' .. '9' =>
+ null;
+ when '$' =>
+ Last := J - 1;
+ exit;
+ when '_' =>
+ if Encoded_Name (J - 1) = '_' then
+ Last := J - 2;
+ end if;
+ exit;
+ when others =>
+ exit;
+ end case;
+ end loop;
+ end if;
+
+ -- Now just copy encoded name to decoded name, converting "__" to '.'
+
+ while Pos <= Last loop
+ if Encoded_Name (Pos) = '_' and then Encoded_Name (Pos + 1) = '_'
+ and then Pos /= Encoded_Name'First
+ then
+ Decoded_Name (DPos) := '.';
+ Pos := Pos + 2;
+
+ else
+ Decoded_Name (DPos) := Encoded_Name (Pos);
+ Pos := Pos + 1;
+ end if;
+
+ DPos := DPos + 1;
+ end loop;
+
+ return Decoded_Name (1 .. DPos - 1);
+ end Decode_Ada_Name;
+
+ ------------------------
+ -- Symbolic_Traceback --
+ ------------------------
+
+ function Symbolic_Traceback (Traceback : Tracebacks_Array) return String is
+ Status : Cond_Value_Type;
+ Image_Name : ASCIC;
+ Image_Name_Addr : Address;
+ Module_Name : ASCIC;
+ Module_Name_Addr : Address;
+ Routine_Name : ASCIC;
+ Routine_Name_Addr : Address;
+ Line_Number : Integer;
+ Relative_PC : Address;
+ Absolute_PC : Address;
+ PC_Is_Valid : Long_Integer;
+ Return_Address : Address;
+ Res : String (1 .. 256 * Traceback'Length);
+ Len : Integer;
+
+ begin
+ if Traceback'Length > 0 then
+ Len := 0;
+
+ -- Since image computation is not thread-safe we need task lockout
+
+ 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;
+
+ Symbolize
+ (Status,
+ PC_For (Traceback (J)),
+ PC_For (Traceback (J)),
+ PV_For (Traceback (J)),
+ Return_Address,
+ Image_Name_Addr,
+ Module_Name_Addr,
+ Routine_Name_Addr,
+ Line_Number,
+ Relative_PC,
+ Absolute_PC,
+ PC_Is_Valid);
+
+ Image_Name := Fetch_ASCIC (Image_Name_Addr);
+ Module_Name := Fetch_ASCIC (Module_Name_Addr);
+ Routine_Name := Fetch_ASCIC (Routine_Name_Addr);
+
+ declare
+ First : Integer := Len + 1;
+ Last : Integer := First + 80 - 1;
+ Pos : Integer;
+ Routine_Name_D : String := Decode_Ada_Name
+ (To_Ada
+ (Routine_Name.Data (1 .. size_t (Routine_Name.Count)),
+ False));
+
+ begin
+ Res (First .. Last) := (others => ' ');
+
+ Res (First .. First + Integer (Image_Name.Count) - 1) :=
+ To_Ada
+ (Image_Name.Data (1 .. size_t (Image_Name.Count)),
+ False);
+
+ Res (First + 10 ..
+ First + 10 + Integer (Module_Name.Count) - 1) :=
+ To_Ada
+ (Module_Name.Data (1 .. size_t (Module_Name.Count)),
+ False);
+
+ Res (First + 30 ..
+ First + 30 + Routine_Name_D'Length - 1) :=
+ Routine_Name_D;
+
+ -- If routine name doesn't fit 20 characters, output
+ -- the line number on next line at 50th position
+
+ if Routine_Name_D'Length > 20 then
+ Pos := First + 30 + Routine_Name_D'Length;
+ Res (Pos) := ASCII.LF;
+ Last := Pos + 80;
+ Res (Pos + 1 .. Last) := (others => ' ');
+ Pos := Pos + 51;
+ else
+ Pos := First + 50;
+ end if;
+
+ Res (Pos .. Pos + Integer'Image (Line_Number)'Length - 1) :=
+ Integer'Image (Line_Number);
+
+ Res (Last) := ASCII.LF;
+ Len := Last;
+ end;
+ end loop;
+
+ System.Soft_Links.Unlock_Task.all;
+ return Res (1 .. Len);
+
+ else
+ return "";
+ end if;
+ end Symbolic_Traceback;
+
+ function Symbolic_Traceback (E : Exception_Occurrence) return String is
+ begin
+ return Symbolic_Traceback (Tracebacks (E));
+ end Symbolic_Traceback;
+
+end GNAT.Traceback.Symbolic;
diff --git a/gcc/ada/get_targ.ads b/gcc/ada/get_targ.ads
index 9d115f081d4..f3d62ffd325 100644
--- a/gcc/ada/get_targ.ads
+++ b/gcc/ada/get_targ.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -81,9 +81,6 @@ pragma Preelaborate (Get_Targ);
function Get_Maximum_Alignment return Pos;
pragma Import (C, Get_Maximum_Alignment, "get_target_maximum_alignment");
- function Get_No_Dollar_In_Label return Boolean;
- pragma Import (C, Get_No_Dollar_In_Label, "get_target_no_dollar_in_label");
-
function Get_Float_Words_BE return Nat;
pragma Import (C, Get_Float_Words_BE, "get_float_words_be");
diff --git a/gcc/ada/gigi.h b/gcc/ada/gigi.h
index 423b8980b33..99b858b223e 100644
--- a/gcc/ada/gigi.h
+++ b/gcc/ada/gigi.h
@@ -6,7 +6,7 @@
* *
* C Header File *
* *
- * Copyright (C) 1992-2003 Free Software Foundation, Inc. *
+ * Copyright (C) 1992-2004 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- *
@@ -58,10 +58,6 @@ extern tree emit_stack_check (tree);
/* Make a TRANSFORM_EXPR to later expand GNAT_NODE into code. */
extern tree make_transform_expr (Node_Id);
-/* Update the setjmp buffer BUF with the current stack pointer. We assume
- here that a __builtin_setjmp was done to BUF. */
-extern void update_setjmp_buf (tree);
-
/* GNU_TYPE is a type. Determine if it should be passed by reference by
default. */
extern int default_pass_by_ref (tree);
@@ -346,6 +342,7 @@ enum standard_datatypes
ADT_get_excptr_decl,
ADT_setjmp_decl,
ADT_longjmp_decl,
+ ADT_update_setjmp_buf_decl,
ADT_raise_nodefer_decl,
ADT_begin_handler_decl,
ADT_end_handler_decl,
@@ -369,6 +366,7 @@ extern GTY(()) tree gnat_raise_decls[(int) LAST_REASON_CODE + 1];
#define get_excptr_decl gnat_std_decls[(int) ADT_get_excptr_decl]
#define setjmp_decl gnat_std_decls[(int) ADT_setjmp_decl]
#define longjmp_decl gnat_std_decls[(int) ADT_longjmp_decl]
+#define update_setjmp_buf_decl gnat_std_decls[(int) ADT_update_setjmp_buf_decl]
#define raise_nodefer_decl gnat_std_decls[(int) ADT_raise_nodefer_decl]
#define begin_handler_decl gnat_std_decls[(int) ADT_begin_handler_decl]
#define end_handler_decl gnat_std_decls[(int) ADT_end_handler_decl]
@@ -756,7 +754,6 @@ extern Pos get_target_double_size (void);
extern Pos get_target_long_double_size (void);
extern Pos get_target_pointer_size (void);
extern Pos get_target_maximum_alignment (void);
-extern Boolean get_target_no_dollar_in_label (void);
extern Nat get_float_words_be (void);
extern Nat get_words_be (void);
extern Nat get_bytes_be (void);
diff --git a/gcc/ada/gnat-style.texi b/gcc/ada/gnat-style.texi
index 2fa09412589..ee425de5f29 100644
--- a/gcc/ada/gnat-style.texi
+++ b/gcc/ada/gnat-style.texi
@@ -382,8 +382,11 @@ one context, where comments explain their purpose.
@itemize @bullet
@item
-Every operator must be surrounded by spaces, except for the
-exponentiation operator.
+Every operator must be surrounded by spaces. An exception is that
+this rule does not apply to the exponentiation operator, for which
+there are no specific layout rules. The reason for this exception
+is that sometimes it makes clearer reading to leave out the spaces
+around exponentiation.
@cindex Operators
@smallexample @c adanocomment
@@ -391,9 +394,6 @@ exponentiation operator.
@end smallexample
@item
-When folding a long line, fold before an operator, not after.
-
-@item
Use parentheses where they clarify the intended association of operands
with operators:
@cindex Parenthesization of expressions
diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi
index b3097a1b592..614064ff313 100644
--- a/gcc/ada/gnat_rm.texi
+++ b/gcc/ada/gnat_rm.texi
@@ -1308,16 +1308,17 @@ debug procedures in the middle of declarations.
Syntax:
@smallexample @c ada
-pragma Elaboration_Checks (RM | Static);
+pragma Elaboration_Checks (Dynamic | Static);
@end smallexample
@noindent
This is a configuration pragma that provides control over the
elaboration model used by the compilation affected by the
-pragma. If the parameter is RM, then the dynamic elaboration
+pragma. If the parameter is @code{Dynamic},
+then the dynamic elaboration
model described in the Ada Reference Manual is used, as though
the @code{-gnatE} switch had been specified on the command
-line. If the parameter is Static, then the default GNAT static
+line. If the parameter is @code{Static}, then the default GNAT static
model is used. This configuration pragma overrides the setting
of the command line. For full details on the elaboration models
used by the GNAT compiler, see section ``Elaboration Order
@@ -1341,18 +1342,33 @@ pragma Eliminate (
[Entity =>] IDENTIFIER |
SELECTED_COMPONENT |
STRING_LITERAL
- [,[Parameter_Types =>] PARAMETER_TYPES]
- [,[Result_Type =>] result_SUBTYPE_NAME]
- [,[Homonym_Number =>] INTEGER_LITERAL]);
+ [,OVERLOADING_RESOLUTION]);
+
+OVERLOADING_RESOLUTION ::= PARAMETER_AND_RESULT_TYPE_PROFILE |
+ SOURCE_LOCATION
+
+PARAMETER_AND_RESULT_TYPE_PROFILE ::= PROCEDURE_PROFILE |
+ FUNCTION_PROFILE
+
+PROCEDURE_PROFILE ::= Parameter_Types => PARAMETER_TYPES
+
+FUNCTION_PROFILE ::= [Parameter_Types => PARAMETER_TYPES,]
+ Result_Type => result_SUBTYPE_NAME]
PARAMETER_TYPES ::= (SUBTYPE_NAME @{, SUBTYPE_NAME@})
-SUBTYPE_NAME ::= STRING_LITERAL
+SUBTYPE_NAME ::= STRING_VALUE
+
+SOURCE_LOCATION ::= Source_Location => SOURCE_TRACE
+SOURCE_TRACE ::= STRING_VALUE
+
+STRING_VALUE ::= STRING_LITERAL @{& STRING_LITERAL@}
@end smallexample
@noindent
This pragma indicates that the given entity is not used outside the
-compilation unit it is defined in. The entity may be either a subprogram
-or a variable.
+compilation unit it is defined in. The entity must be an explicitly declared
+subprogram; this includes generic subprogram instances and
+subprograms declared in generic package instances.
If the entity to be eliminated is a library level subprogram, then
the first form of pragma @code{Eliminate} is used with only a single argument.
@@ -1366,29 +1382,55 @@ the particular entity. If the second argument is in string form, it must
correspond to the internal manner in which GNAT stores entity names (see
compilation unit Namet in the compiler sources for details).
-The remaining parameters are optionally used to distinguish
-between overloaded subprograms. There are two ways of doing this.
+The remaining parameters (OVERLOADING_RESOLUTION) are optionally used
+to distinguish between overloaded subprograms. If a pragma does not contain
+the OVERLOADING_RESOLUTION parameter(s), it is applied to all the overloaded
+subprograms denoted by the first two parameters.
+
+Use PARAMETER_AND_RESULT_TYPE_PROFILE to specify the profile of the subprogram
+to be eliminated in a manner similar to that used for the extended
+@code{Import} and @code{Export} pragmas, except that the subtype names are
+always given as strings. At the moment, this form of distinguishing
+overloaded subprograms is implemented only partially, so we do not recommend
+using it for practical subprogram elimination.
-Use @code{Parameter_Types} and @code{Result_Type} to specify the
-profile of the subprogram to be eliminated in a manner similar to that
-used for
-the extended @code{Import} and @code{Export} pragmas, except that the
-subtype names are always given as string literals, again corresponding
-to the internal manner in which GNAT stores entity names.
+Note, that in case of a parameterless procedure its profile is represented
+as @code{Parameter_Types => ("")}
-Alternatively, the @code{Homonym_Number} parameter is used to specify
-which overloaded alternative is to be eliminated. A value of 1 indicates
-the first subprogram (in lexical order), 2 indicates the second etc.
+Alternatively, the @code{Source_Location} parameter is used to specify
+which overloaded alternative is to be eliminated by pointing to the
+location of the DEFINING_PROGRAM_UNIT_NAME of this subprogram in the
+source text. The string literal (or concatenation of string literals)
+given as SOURCE_TRACE must have the following format:
+
+@smallexample @c ada
+SOURCE_TRACE ::= SOURCE_LOCATION@{LBRACKET SOURCE_LOCATION RBRACKET@}
+
+LBRACKET ::= [
+RBRACKET ::= ]
+
+SOURCE_LOCATION ::= FILE_NAME:LINE_NUMBER
+FILE_NAME ::= STRING_LITERAL
+LINE_NUMBER ::= DIGIT @{DIGIT@}
+@end smallexample
+
+SOURCE_TRACE should be the short name of the source file (with no directory
+information), and LINE_NUMBER is supposed to point to the line where the
+defining name of the subprogram is located.
+
+For the subprograms that are not a part of generic instantiations, only one
+SOURCE_LOCATION is used. If a subprogram is declared in a package
+instantiation, SOURCE_TRACE contains two SOURCE_LOCATIONs, the first one is
+the location of the (DEFINING_PROGRAM_UNIT_NAME of the) instantiation, and the
+second one denotes the declaration of the corresponding subprogram in the
+generic package. This approach is recursively used to create SOURCE_LOCATIONs
+in case of nested instantiations.
The effect of the pragma is to allow the compiler to eliminate
the code or data associated with the named entity. Any reference to
an eliminated entity outside the compilation unit it is defined in,
causes a compile time or link time error.
-The parameters of this pragma may be given in any order, as long as
-the usual rules for use of named parameters and position parameters
-are used.
-
The intention of pragma @code{Eliminate} is to allow a program to be compiled
in a system independent manner, with unused entities eliminated, without
the requirement of modifying the source text. Normally the required set
@@ -1400,6 +1442,10 @@ Note that the reason this pragma takes string literals where names might
be expected is that a pragma @code{Eliminate} can appear in a context where the
relevant names are not visible.
+Note that any change in the source files that includes removing, splitting of
+adding lines may make the set of Eliminate pragmas using SOURCE_LOCATION
+parameter illegal.
+
@node Pragma Export_Exception
@unnumberedsec Pragma Export_Exception
@cindex OpenVMS
@@ -2926,14 +2972,13 @@ There are no semantic dependencies on the package Ada.Calendar.
@item No_Relative_Delay
There are no delay_relative_statements.
-@item No_Task_Attributes
-There are no semantic dependencies on the Ada.Task_Attributes package and
-there are no references to the attributes Callable and Terminated [RM 9.9].
+@item No_Task_Attributes_Package
+There are no semantic dependencies on the Ada.Task_Attributes package.
-@item Boolean_Entry_Barriers
-Entry barrier condition expressions shall be boolean
-objects which are declared in the protected type
-which contains the entry.
+@item Simple_Barriers
+Entry barrier condition expressions shall be either static
+boolean expressions or boolean objects which are declared in
+the protected type which contains the entry.
@item Max_Asynchronous_Select_Nesting = 0
[RM D.7] Specifies the maximum dynamic nesting level of asynchronous_selects.
@@ -2979,7 +3024,7 @@ and whose most recent description is available at
The above set is a superset of the restrictions provided by pragma
@code{Restricted_Run_Time}, it includes five additional restrictions
-(@code{Boolean_Entry_Barriers}, @code{No_Select_Statements},
+(@code{Simple_Barriers}, @code{No_Select_Statements},
@code{No_Calendar},
@code{No_Relative_Delay} and @code{No_Task_Termination}). This means
that pragma @code{Ravenscar}, like the pragma @code{Restricted_Run_Time},
@@ -3010,7 +3055,7 @@ A configuration pragma that establishes the following set of restrictions:
@item No_Protected_Type_Allocators
@item No_Local_Protected_Objects
@item No_Requeue_Statements
-@item No_Task_Attributes
+@item No_Task_Attributes_Package
@item Max_Asynchronous_Select_Nesting = 0
@item Max_Task_Entries = 0
@item Max_Protected_Entries = 1
@@ -6803,13 +6848,14 @@ then all compilation units in the partition must obey the restriction.
@table @code
-@item Boolean_Entry_Barriers
-@findex Boolean_Entry_Barriers
+@item Simple_Barriers
+@findex Simple_Barriers
This restriction ensures at compile time that barriers in entry declarations
-for protected types are restricted to references to simple boolean variables
-defined in the private part of the protected type. No other form of entry
-barriers is permitted. This is one of the restrictions of the Ravenscar
-profile for limited tasking (see also pragma @code{Ravenscar}).
+for protected types are restricted to either static boolean expressions or
+references to simple boolean variables defined in the private part of the
+protected type. No other form of entry barriers is permitted. This is one
+of the restrictions of the Ravenscar profile for limited tasking (see also
+pragma @code{Ravenscar}).
@item Max_Entry_Queue_Depth => Expr
@findex Max_Entry_Queue_Depth
@@ -6946,8 +6992,8 @@ user-defined storage pool.
This restriction ensures at compile time that there are no implicit or
explicit dependencies on the package @code{Ada.Streams}.
-@item No_Task_Attributes
-@findex No_Task_Attributes
+@item No_Task_Attributes_Package
+@findex No_Task_Attributes_Package
This restriction ensures at compile time that there are no implicit or
explicit dependencies on the package @code{Ada.Task_Attributes}.
@@ -12565,8 +12611,8 @@ of the length corresponding to the @code{@var{type}'Size} value in Ada.
@noindent
The interface to C++ makes use of the following pragmas, which are
primarily intended to be constructed automatically using a binding generator
-tool, although it is possible to construct them by hand. Ada Core
-Technologies does not currently supply a suitable binding generator tool.
+tool, although it is possible to construct them by hand. No suitable binding
+generator tool is supplied with GNAT though.
Using these pragmas it is possible to achieve complete
inter-operability between Ada tagged types and C class definitions.
@@ -12691,7 +12737,7 @@ including machine instructions in a subprogram.
The two features are similar, and both are closely related to the mechanism
provided by the asm instruction in the GNU C compiler. Full understanding
and use of the facilities in this package requires understanding the asm
-instruction as described in @cite{Using the GNU Compiler Collection (GCC)}
+instruction as described in @cite{Using the GNU Compiler Collection (GCC)}
by Richard Stallman. The relevant section is titled ``Extensions to the C
Language Family'' -> ``Assembler Instructions with C Expression Operands''.
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
index 795b2ec48b9..1a30c465a55 100644
--- a/gcc/ada/gnat_ugn.texi
+++ b/gcc/ada/gnat_ugn.texi
@@ -77,7 +77,13 @@
@c
@c oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
-@setfilename gnat_ugn.info
+@ifset vms
+@setfilename gnat_ugn_vms.info
+@end ifset
+
+@ifset unw
+@setfilename gnat_ugn_unw.info
+@end ifset
@ifset vms
@settitle GNAT User's Guide for Native Platforms / OpenVMS Alpha
@@ -444,10 +450,9 @@ Cleaning Up Using gnatclean
GNAT and Libraries
-* Creating an Ada Library::
-* Installing an Ada Library::
-* Using an Ada Library::
-* Creating an Ada Library to be Used in a Non-Ada Context::
+* Introduction to Libraries in GNAT::
+* General Ada Libraries::
+* Stand-alone Ada Libraries::
* Rebuilding the GNAT Run-Time Library::
Using the GNU make Utility
@@ -574,6 +579,7 @@ Platform-Specific Information for the Run-Time Libraries
* Solaris-Specific Considerations::
* IRIX-Specific Considerations::
* Linux-Specific Considerations::
+* AIX-Specific Considerations::
Example of Binder Output File
@@ -6258,7 +6264,7 @@ The use of the switch @option{-gnatS} for an
Ada compilation will cause the compiler to output a
representation of package Standard in a form very
close to standard Ada. It is not quite possible to
-do this and remain entirely Standard (since new
+do this entirely in standard Ada (since new
numeric base types cannot be created in standard
Ada), but the output is easily
readable to any Ada programmer, and is useful to
@@ -6622,7 +6628,7 @@ The content of the @file{ada_source_path} file which is part of the GNAT
installation tree and is used to store standard libraries such as the
GNAT Run Time Library (RTL) source files.
@ifclear vms
-@ref{Installing an Ada Library}
+@ref{Installing the library}
@end ifclear
@end enumerate
@@ -6929,7 +6935,7 @@ See also the packages @code{GNAT.Traceback} and
@ifclear vms
Note that on x86 ports, you must not use @option{-fomit-frame-pointer}
@code{gcc} option.
-@end ifclear vms
+@end ifclear
@item ^-F^/FORCE_ELABS_FLAGS^
@cindex @option{^-F^/FORCE_ELABS_FLAGS^} (@command{gnatbind})
@@ -7546,7 +7552,7 @@ installation tree and is used to store standard libraries such as the
GNAT Run Time Library (RTL) unless the switch @option{-nostdlib} is
specified.
@ifclear vms
-@ref{Installing an Ada Library}
+@ref{Installing the library}
@end ifclear
@end enumerate
@@ -8157,6 +8163,12 @@ and ALI files go in the current working directory.
This switch cannot be used when using a project file.
+@ifclear vms
+@item -eL
+@cindex @option{-eL} (@code{gnatmake})
+Follow all symbolic links when processing project files.
+@end ifclear
+
@item ^-f^/FORCE_COMPILE^
@cindex @option{^-f^/FORCE_COMPILE^} (@code{gnatmake})
Force recompilations. Recompile all sources, even though some object
@@ -8322,6 +8334,15 @@ decides are necessary.
Indicates the verbosity of the parsing of GNAT project files.
See @ref{Switches Related to Project Files}.
+@item ^-x^/NON_PROJECT_UNIT_COMPILATION^
+@cindex @option{^-x^/NON_PROJECT_UNIT_COMPILATION^} (@code{gnatmake})
+Indicates that sources that are not part of any Project File may be compiled.
+Normally, when using Project Files, only sources that are part of a Project
+File may be compile. When this switch is used, a source outside of all Project
+Files may be compiled. The ALI file and the object file will be put in the
+object directory of the main Project. The compilation switches used will only
+be those specified on the command line.
+
@item ^-X^/EXTERNAL_REFERENCE=^@var{name=value}
Indicates that external variable @var{name} has the value @var{value}.
The Project Manager will use this value for occurrences of
@@ -8345,10 +8366,8 @@ linker.
@table @asis
@item @code{gcc} @asis{switches}
@ifclear vms
-Any uppercase switch (other than @option{-A},
-@option{-L} or
-@option{-S}) or any switch that is more than one character is passed to
-@code{gcc} (e.g. @option{-O}, @option{-gnato,} etc.)
+Any uppercase or multi-character switch that is not a @code{gnatmake} switch
+is passed to @code{gcc} (e.g. @option{-O}, @option{-gnato,} etc.)
@end ifclear
@ifset vms
Any qualifier that cannot be recognized as a qualifier for @code{GNAT MAKE}
@@ -12441,12 +12460,37 @@ When @command{gnatmake} detects that a project file
is a library project file, it will check all immediate sources of the project
and rebuild the library if any of the sources have been recompiled.
-When a library is built or rebuilt, an attempt is made to delete all
+Standard project files can import library project files. In such cases,
+the libraries will only be rebuild if some of its sources are recompiled
+because they are in the closure of some other source in an importing project.
+Sources of the library project files that are not in such a closure will
+not be checked, unless the full library is checked, because one of its sources
+needs to be recompiled.
+
+For instance, assume the project file @code{A} imports the library project file
+@code{L}. The immediate sources of A are @file{a1.adb}, @file{a2.ads} and
+@file{a2.adb}. The immediate sources of L are @file{l1.ads}, @file{l1.adb},
+@file{l2.ads}, @file{l2.adb}.
+
+If @file{l1.adb} has been modified, then the library associated with @code{L}
+will be rebuild when compiling all the immediate sources of @code{A} only
+if @file{a1.ads}, @file{a2.ads} or @file{a2.adb} includes a statement
+@code{"with L1;"}.
+
+To be sure that all the sources in the library associated with @code{L} are
+up to date, and that all the sources of parject @code{A} are also up to date,
+the following two commands needs to be used:
+
+@smallexample
+gnatmake -Pl.gpr
+gnatmake -Pa.gpr
+@end smallexample
+
+When a library is built or rebuilt, an attempt is made first to delete all
files in the library directory.
All @file{ALI} files will also be copied from the object directory to the
library directory. To build executables, @command{gnatmake} will use the
-library rather than the individual object files. The copy of the @file{ALI}
-files are made read-only.
+library rather than the individual object files.
@c **********************************************
@@ -14359,8 +14403,8 @@ output source file
@item
@var{filename} is the name (including the extension) of the source file to
reformat; ``wildcards'' or several file names on the same gnatpp command are
-allowed. The file name may contain path information; it does not have to follow
-the GNAT file naming rules
+allowed. The file name may contain path information; it does not have to
+follow the GNAT file naming rules
@end itemize
@@ -14596,8 +14640,9 @@ Compact layout
Uncompact layout
@item ^-notab^/NOTABS^
-All the VT characters are removed from the comment text. All the HT characters are
-expanded with the sequences of space characters to get to the next tab stops.
+All the VT characters are removed from the comment text. All the HT characters
+are expanded with the sequences of space characters to get to the next tab
+stops.
@end table
@@ -16219,26 +16264,39 @@ where @code{gnatclean} was invoked.
@ifclear vms
@node GNAT and Libraries
@chapter GNAT and Libraries
-@cindex Library, building, installing
+@cindex Library, building, installing, using
@noindent
-This chapter addresses some of the issues related to building and using
-a library with GNAT. It also shows how the GNAT run-time library can be
-recompiled.
+This chapter addresses the issues related to building and using
+libraries with GNAT. It also shows how the GNAT run-time library can be
+recompiled. It is recommended that the user understands how to use the
+@ref{GNAT Project Manager} facility before reading this chapter.
@menu
-* Creating an Ada Library::
-* Installing an Ada Library::
-* Using an Ada Library::
-* Creating an Ada Library to be Used in a Non-Ada Context::
+* Introduction to Libraries in GNAT::
+* General Ada Libraries::
+* Stand-alone Ada Libraries::
* Rebuilding the GNAT Run-Time Library::
@end menu
-@node Creating an Ada Library
-@section Creating an Ada Library
+@node Introduction to Libraries in GNAT
+@section Introduction to Libraries in GNAT
@noindent
-In the GNAT environment, a library has two components:
+A library is, conceptually, a collection of objects which does not have its
+own main thread of execution, but rather provides certain services to the
+applications that use it. A library can be either statically linked with the
+application, in which case its code is directly included in the application,
+or, on platforms that support it, be dynamically linked, in which case
+its code is shared by all applications making use of this library. GNAT
+supports both types of libraries. In the static case, the compiled code can
+be provided in different ways. The simplest way is to provide directly the
+set of objects produced by the compiler during the compilation of the library.
+It is also possible to group the objects into an archive using whatever
+commands are provided by the operating system. For the later case, the objects
+are grouped into a shared library.
+
+In the GNAT environment, a library has two types of components:
@itemize @bullet
@item
Source files.
@@ -16247,37 +16305,76 @@ Compiled code and Ali files. See @ref{The Ada Library Information Files}.
@end itemize
@noindent
-In order to use other packages @ref{The GNAT Compilation Model}
-requires a certain number of sources to be available to the compiler.
-The minimal set of
-sources required includes the specs of all the packages that make up the
-visible part of the library as well as all the sources upon which they
-depend. The bodies of all visible generic units must also be provided.
-@noindent
-Although it is not strictly mandatory, it is recommended that all sources
-needed to recompile the library be provided, so that the user can make
-full use of inter-unit inlining and source-level debugging. This can also
-make the situation easier for users that need to upgrade their compilation
-toolchain and thus need to recompile the library from sources.
+GNAT libraries can either completely expose their source files to the
+compilation context of the user's application, or alternatively only expose
+a limited set of source files, called interface units, in which case they are
+called @ref{Stand-alone Ada Libraries}. In addition, GNAT provides full support
+for foreign libraries which are only available in the object format.
+
+Ada semantics requires that all compilation units comprising the application
+are elaborated in the timely fashion. Where possible, GNAT provides facilities
+to ensure that compilation units of a library are automatically elaborated;
+however, there are cases where this must be responsibility of a user. This will
+be addressed in greater detail further on.
+
+@node General Ada Libraries
+@section General Ada Libraries
+
+@menu
+* Building the library::
+* Installing the library::
+* Using the library::
+@end menu
+
+@node Building the library
+@subsection Building the library
@noindent
-The compiled code can be provided in different ways. The simplest way is
-to provide directly the set of objects produced by the compiler during
-the compilation of the library. It is also possible to group the objects
-into an archive using whatever commands are provided by the operating
-system. Finally, it is also possible to create a shared library (see
-option -shared in the GCC manual).
+The easiest way to build a library is to use the @ref{GNAT Project Manager},
+which supports a special type of projects called @ref{Library Projects}.
+
+A project is considered a library project, when two project-level attributes
+are defined in it: @code{Library_Name} and @code{Library_Dir}. In order to
+control different aspects of library configuration, additional optional
+project-level attributes can be specified:
+@itemize
+@item @code{Library_Kind}
+This attribute controls whether the library is to be static or shared
+@item @code{Library_Version}
+This attribute specifies what is the library version; this value is used
+during dynamic linking of shared libraries to determine if the currently
+installed versions of the binaries are compatible.
+@item @code{Library_Options}, @code{Library_GCC}
+These attributes specify additional low-level options to be used during
+library generation, and redefine the actual application used to generate
+library.
+@end itemize
@noindent
+GNAT Project Manager takes full care of the library maintenance task,
+including recompilation of the source files for which objects do not exist
+or are not up to date, assembly of the library archive, and installation of
+the library, i.e. the copy of associated source, object and ALI files to the
+specific location.
+
+It is not entirely trivial to correctly do all the steps required to
+produce a library. We recommend that you use @ref{GNAT Project Manager}
+for this task. In special cases where this is not desired, the necessary
+steps are discussed below.
+
There are various possibilities for compiling the units that make up the
library: for example with a Makefile @ref{Using the GNU make Utility},
or with a conventional script.
For simple libraries, it is also possible to create a
dummy main program which depends upon all the packages that comprise the
interface of the library. This dummy main program can then be given to
-gnatmake, in order to build all the necessary objects. Here is an example
-of such a dummy program and the generic commands used to build an
-archive or a shared library.
+gnatmake, which will ensure that all necessary objects are built.
+
+After this task is accomplished, the user should follow the standard procedure
+of the underlying operating system to produce the static or shared library.
+
+Below is an example of such a dummy program and the generic commands used to
+build an archive or a shared library.
@smallexample @c ada
@iftex
@@ -16317,29 +16414,22 @@ $ chmod -w *.ali
@end smallexample
@noindent
-When the objects are grouped in an archive or a shared library, the user
-needs to specify the desired library at link time, unless a pragma
-linker_options has been used in one of the sources:
-@smallexample @c ada
-pragma Linker_Options ("-lmy_lib");
-@end smallexample
-
-@noindent
Please note that the library must have a name of the form libxxx.a or
libxxx.so in order to be accessed by the directive -lxxx at link
time.
-@node Installing an Ada Library
-@section Installing an Ada Library
+@node Installing the library
+@subsection Installing the library
@noindent
In the GNAT model, installing a library consists in copying into a specific
-location the files that make up this library. It is possible to install
-the sources in a different directory from the other files (ALI, objects,
-archives) since the source path and the object path can easily be
-specified separately.
+location the files that make up this library. When the library is built using
+projects, it is automatically installed in the location specified in the
+project by means of the attribute @code{Library_Dir}, otherwise it is
+responsibility of the user. GNAT also supports installing the sources in a
+different directory from the other files (ALI, objects, archives) since the
+source path and the object path can be specified separately.
-@noindent
For general purpose libraries, it is possible for the system
administrator to put those libraries in the default compiler paths. To
achieve this, he must specify their location in the configuration files
@@ -16359,7 +16449,6 @@ in their order of appearance in the file. The names can be either absolute
or relative, in the latter case, they are relative to where theses files
are located.
-@noindent
@file{ada_source_path} and @file{ada_object_path} might actually not be
present in a
GNAT installation, in which case, GNAT will look for its run-time library in
@@ -16372,27 +16461,52 @@ be @file{adainclude}). In the same way, the @file{ada_object_path} file must
contain the location for the GNAT run-time objects (which can simply
be @file{adalib}).
-@noindent
You can also specify a new default path to the runtime library at compilation
time with the switch @option{--RTS=rts-path}. You can easily choose and change
the runtime you want your program to be compiled with. This switch is
recognized by gcc, gnatmake, gnatbind, gnatls, gnatfind and gnatxref.
-@noindent
It is possible to install a library before or after the standard GNAT
library, by reordering the lines in the configuration files. In general, a
library must be installed before the GNAT library if it redefines
any part of it.
-@node Using an Ada Library
-@section Using an Ada Library
+
+@node Using the library
+@subsection Using the library
+
+@noindent
+Once again, the project facility greatly simplifies the addition of libraries
+to the compilation. If the project file for an application lists a library
+project in its @code{with} clause, the project manager will ensure that the
+library files are consistent, and are considered during compilation and
+linking of the main application.
+
+Even if you have a third-party, non-Ada library, you can still use GNAT
+Project facility to provide a wrapper for it. The following project for
+example, when "withed" in your main project, will link with the third-party
+library liba.a:
+
+@smallexample @c projectfile
+@group
+project Liba is
+ for Source_Dirs use ();
+ for Library_Dir use "lib";
+ for Library_Name use "a";
+ for Library_Kind use "static";
+end Liba;
+@end group
+@end smallexample
@noindent
-In order to use a Ada library, you need to make sure that this
+In order to use an Ada library manually, you need to make sure that this
library is on both your source and object path
@ref{Search Paths and the Run-Time Library (RTL)}
-and @ref{Search Paths for gnatbind}. For
-instance, you can use the library @file{mylib} installed in
+and @ref{Search Paths for gnatbind}. Furthermore, when the objects are grouped
+in an archive or a shared library, the user needs to specify the desired
+library at link time.
+
+By means of example, you can use the library @file{mylib} installed in
@file{/dir/my_lib_src} and @file{/dir/my_lib_obj} with the following commands:
@smallexample
@@ -16416,98 +16530,173 @@ variable @code{ADA_INCLUDE_PATH}, or by the administrator to the file
variable @code{ADA_OBJECTS_PATH}, or by the administrator to the file
@file{ada_object_path}
@item
-a pragma @code{Linker_Options}, as mentioned in @ref{Creating an Ada Library},
-has been added to the sources.
+a pragma @code{Linker_Options}, has been added to one of the sources.
+For example:
+
+@smallexample @c ada
+pragma Linker_Options ("-lmy_lib");
+@end smallexample
@end itemize
-@noindent
-@node Creating an Ada Library to be Used in a Non-Ada Context
-@section Creating an Ada Library to be Used in a Non-Ada Context
-@noindent
-The previous sections detailed how to create and install a library that
-was usable from an Ada main program. Using this library in a non-Ada
-context is not possible, because the elaboration of the library is
-automatically done as part of the main program elaboration.
+@node Stand-alone Ada Libraries
+@section Stand-alone Ada Libraries
+@cindex Stand-alone library, building, using
-GNAT also provides the ability to build libraries that can be used both
-in an Ada and non-Ada context. This section describes how to build such
-a library, and then how to use it from a C program. The method for
-interfacing with the library from other languages such as Fortran for
-instance remains the same.
+@menu
+* Introduction to Stand-Alone Libraries::
+* Building SAL::
+* Creating SAL to be used in a non-Ada context::
+* Restrictions in SALs::
+@end menu
-@subsection Creating the Library
+@node Introduction to Stand-Alone Libraries
+@subsection Introduction to Stand-Alone Libraries
-@itemize @bullet
-@item Identify the units representing the interface of the library.
+@noindent
+A Stand-alone Library (SAL) is a library that contains the necessary code to
+elaborate the Ada units that are included in the library. Different from
+ordinary libraries, which consist of all sources, objects and ALI files of the
+library, the SAL creator can specify a restricted subset of compilation units
+comprising SAL to serve as a library interface. In this case, the fully
+self-sufficient set of files of such library will normally consist of objects
+archive, sources of interface units specs, and ALI files of interface units.
+Note that if interface specs contain generics or inlined subprograms, body
+source must also be provided; if the units that must be provided in the source
+form depend on other units, the source and ALIs of those must also be provided.
-Here is an example of simple library interface:
+The main purpose of SAL is to minimize the recompilation overhead of client
+applications when the new version of the library is installed. Specifically,
+if the interface sources have not changed, client applications do not need to
+be recompiled. If, furthermore, SAL is provided in the shared form and its
+version, controlled by @code{Library_Version} attribute, is not changed, the
+clients don't need to be relinked, either.
-@smallexample @c ada
-package Interface is
+SALs also allow the library providers to minimize amount of library source
+text exposed to the clients, which might be necessary for different reasons.
- procedure Do_Something;
+Stand-alone libraries are also well suited to be used in an executable which
+main is not written in Ada.
- procedure Do_Something_Else;
+@node Building SAL
+@subsection Building SAL
-end Interface;
-@end smallexample
+@noindent
+GNAT Project facility provides a simple way of building and installing
+stand-alone libraries, see @ref{Stand-alone Library Projects}.
+To be a Stand-alone Library Project, in addition to the two attributes
+that make a project a Library Project (@code{Library_Name} and
+@code{Library_Dir}, see @ref{Library Projects}), the attribute
+@code{Library_Interface} must be defined.
-@item Use @code{pragma Export} or @code{pragma Convention} for the
-exported entities.
+@smallexample @c projectfile
+@group
+ for Library_Dir use "lib_dir";
+ for Library_Name use "dummy";
+ for Library_Interface use ("int1", "int1.child");
+@end group
+@end smallexample
-Our package @code{Interface} is then updated as follow:
-@smallexample @c ada
-package Interface is
+Attribute @code{Library_Interface} has a non empty string list value,
+each string in the list designating a unit contained in an immediate source
+of the project file.
- procedure Do_Something;
- pragma Export (C, Do_Something, "do_something");
+When a Stand-alone Library is built, first the binder is invoked to build
+a package whose name depends on the library name
+(^b~dummy.ads/b^B$DUMMY.ADS/B^ in the example above).
+This binder-generated package includes initialization and
+finalization procedures whose
+names depend on the library name (dummyinit and dummyfinal in the example
+above). The object corresponding to this package is included in the library.
- procedure Do_Something_Else;
- pragma Export (C, Do_Something_Else, "do_something_else");
+The user must ensure timely (e.g. prior to any use of interfaces in the SAL)
+calling of these procedures if static SAL is built, or shared SAL is built
+with project-level attribute @code{Library_Auto_Init} set to "false".
-end Interface;
-@end smallexample
+For a Stand-Alone Library, only the @file{ALI} files of the Interface Units
+(those that are listed in attribute @code{Library_Interface}) are copied to
+the Library Directory. As a consequence, only the Interface Units may be
+imported from Ada units outside of the library. If other units are imported,
+the binding phase will fail.
-@item Compile all the units composing the library.
+The attribute @code{Library_Src_Dir}, may be specified for a
+Stand-Alone Library. @code{Library_Src_Dir} is a simple attribute that has a
+single string value. Its value must be the path (absolute or relative to the
+project directory) of an existing directory. This directory cannot be the
+object directory or one of the source directories, but it can be the same as
+the library directory. The sources of the Interface
+Units of the library, necessary to an Ada client of the library, will be
+copied to the designated directory, called Interface Copy directory.
+These sources includes the specs of the Interface Units, but they may also
+include bodies and subunits, when pragmas @code{Inline} or @code{Inline_Always}
+are used, or when there is a generic units in the spec. Before the sources
+are copied to the Interface Copy directory, an attempt is made to delete all
+files in the Interface Copy directory.
-@item Bind the library objects.
+Building stand-alone libraries by hand is difficult. Below are listed the steps
+necessary to be done by the user:
+@itemize @bullet
+@item
+compile all library sources
+@item
+invoke the binder with the switch -n (No Ada main program),
+with all the ALI files of the interfaces, and
+with the switch -L to give specific names to the init and final
+procedure.
+@smallexample
+ gnatbind -n int1.ali int2.ali -Lsal1
+@end smallexample
+@item
+compile the binder generated file
+@smallexample
+ gcc -c b~int2.adb
+@end smallexample
+@item
+link the dynamic library with all the necessary object files,
+indicating to the linker the names of the init (and possibly
+final) procedures for automatic initialization (and finalization).
+The built library should be put in a directory different from
+the object directory.
+@item
+copy the ALI files of the interface to the library directory,
+add in the copy the indication that it is an interface to a SAL
+(i.e. add a word @option{SL} on the line in ALI file that starts
+with letter P) and make the modified copy of the ALI file read-only.
+@end itemize
-This step is performed by invoking gnatbind with the @option{-L<prefix>}
-switch. @code{gnatbind} will then generate the library elaboration
-procedure (named @code{<prefix>init}) and the run-time finalization
-procedure (named @code{<prefix>final}).
+@noindent
+Using SALs is not different from using other libraries
+(see @ref{Using the library}).
-@smallexample
-# generate the binder file in Ada
-$ gnatbind -Lmylib interface
+@node Creating SAL to be used in a non-Ada context
+@subsection Creating SAL to be used in a non-Ada context
-# generate the binder file in C
-$ gnatbind -C -Lmylib interface
-@end smallexample
+@noindent
+It is easy to adapt SAL build procedure discussed above for use of SAL in
+a non-Ada context.
-@item Compile the files generated by the binder
+The only extra step required is to ensure that library interface subprograms
+are compatible with the main program, by means of @code{pragma Export}
+or @code{pragma Convention}.
-@smallexample
-$ gcc -c b~interface.adb
-@end smallexample
+Here is an example of simple library interface for use with C main program:
-@item Create the library;
+@smallexample @c ada
+package Interface is
-The procedure is identical to the procedure explained in
-@ref{Creating an Ada Library},
-except that @file{b~interface.o} needs to be added to
-the list of objects.
+ procedure Do_Something;
+ pragma Export (C, Do_Something, "do_something");
-@smallexample
-# create an archive file
-$ ar cr libmylib.a b~interface.o <other object files>
+ procedure Do_Something_Else;
+ pragma Export (C, Do_Something_Else, "do_something_else");
-# create a shared library
-$ gcc -shared -o libmylib.so b~interface.o <other object files>
+end Interface;
@end smallexample
-@item Provide a ``foreign'' view of the library interface;
+@noindent
+On the foreign language side, you must provide a ``foreign'' view of the
+library interface; remeber that it should contain elaboration routines in
+addition to interface subrporams.
The example below shows the content of @code{mylib_interface.h} (note
that there is no rule for the naming of this file, any name can be used)
@@ -16522,9 +16711,6 @@ extern void mylibfinal (void);
extern void do_something (void);
extern void do_something_else (void);
@end smallexample
-@end itemize
-
-@subsection Using the Library
@noindent
Libraries built as explained above can be used from any program, provided
@@ -16555,23 +16741,14 @@ main (void)
@end smallexample
@noindent
-Note that this same library can be used from an equivalent Ada main
-program. In addition, if the libraries are installed as detailed in
-@ref{Installing an Ada Library}, it is not necessary to invoke the
-library elaboration and finalization routines. The binder will ensure
-that this is done as part of the main program elaboration and
-finalization phases.
-
-@subsection The Finalization Phase
-
-@noindent
-Invoking any library finalization procedure generated by @code{gnatbind}
-shuts down the Ada run time permanently. Consequently, the finalization
-of all Ada libraries must be performed at the end of the program. No
-call to these libraries nor the Ada run time should be made past the
+Note that invoking any library finalization procedure generated by
+@code{gnatbind} shuts down the Ada run time permanently. Consequently, the
+finalization of all Ada libraries must be performed at the end of the program.
+No call to these libraries nor the Ada run time should be made past the
finalization phase.
-@subsection Restrictions in Libraries
+@node Restrictions in SALs
+@subsection Restrictions in SALs
@noindent
The pragmas listed below should be used with caution inside libraries,
@@ -16603,11 +16780,12 @@ to be a consideration.
@node Rebuilding the GNAT Run-Time Library
@section Rebuilding the GNAT Run-Time Library
+@cindex GNAT Run-Time Library, rebuilding
@noindent
It may be useful to recompile the GNAT library in various contexts, the
most important one being the use of partition-wide configuration pragmas
-such as Normalize_Scalar. A special Makefile called
+such as @code{Normalize_Scalars}. A special Makefile called
@code{Makefile.adalib} is provided to that effect and can be found in
the directory containing the GNAT library. The location of this
directory depends on the way the GNAT environment has been installed and can
@@ -16623,6 +16801,7 @@ gnat library. This Makefile contains its own documentation and in
particular the set of instructions needed to rebuild a new library and
to use it.
+
@node Using the GNU make Utility
@chapter Using the GNU @code{make} Utility
@findex make
@@ -17531,7 +17710,9 @@ by @command{gnatstub} to compile an argument source file.
@cindex @option{^-gnatyM^/MAX_LINE_LENGTH^} (@command{gnatstub})
(@var{n} is a non-negative integer). Set the maximum line length in the
body stub to @var{n}; the default is 79. The maximum value that can be
-specified is 32767.
+specified is 32767. Note that in the special case of configuration
+pragma files, the maximum is always 32767 regardless of whether or
+not this switch appears.
@item ^-gnaty^/STYLE_CHECKS=^@var{n}
@cindex @option{^-gnaty^/STYLE_CHECKS=^} (@command{gnatstub})
@@ -20648,6 +20829,7 @@ information about several specific platforms.
* Solaris-Specific Considerations::
* IRIX-Specific Considerations::
* Linux-Specific Considerations::
+* AIX-Specific Considerations::
@end menu
@@ -21060,7 +21242,22 @@ compared to other native thread libraries:
e.g. by using @code{killpg()}.
@end itemize
+@node AIX-Specific Considerations
+@section AIX-Specific Considerations
+@cindex AIX resolver library
+
+@noindent
+On AIX, the resolver library initializes some internal structure on
+the first call to @code{get*by*} functions, which are used to implement
+@code{GNAT.Sockets.Get_Host_By_Name} and @code{GNAT.Sockets.Get_Host_By_Addrss}.
+If such initialization occurs within an Ada task, and the stack size for
+the task is the default size, a stack overflow may occur.
+To avoid this overflow, the user should either ensure that the first call
+to @code{GNAT.Sockets.Get_Host_By_Name} or @code{GNAT.Sockets.Get_Host_By_Addrss}
+occurs in the environment task, or use @code{pragma Storage_Size} to
+specify a sufficiently large size for the stack of the task that contains
+this call.
@c *******************************
@node Example of Binder Output File
diff --git a/gcc/ada/gnatbind.adb b/gcc/ada/gnatbind.adb
index cb5c69520e8..3dc76ef0932 100644
--- a/gcc/ada/gnatbind.adb
+++ b/gcc/ada/gnatbind.adb
@@ -113,7 +113,7 @@ procedure Gnatbind is
No_Reentrancy => True,
-- Not checkable at compile time
- Max_Entry_Queue_Depth => True,
+ Max_Entry_Queue_Length => True,
-- Not checkable at compile time
Max_Storage_At_Blocking => True,
@@ -364,7 +364,8 @@ begin
declare
Shared_Libgnat_Default : Character;
- pragma Import (C, Shared_Libgnat_Default, "shared_libgnat_default");
+ pragma Import
+ (C, Shared_Libgnat_Default, "__gnat_shared_libgnat_default");
SHARED : constant Character := 'H';
STATIC : constant Character := 'T';
diff --git a/gcc/ada/gnatcmd.adb b/gcc/ada/gnatcmd.adb
index b793b48a7de..1747d25d307 100644
--- a/gcc/ada/gnatcmd.adb
+++ b/gcc/ada/gnatcmd.adb
@@ -278,7 +278,7 @@ procedure GNATCmd is
There_Are_Libraries : in out Boolean)
is
Path_Option : constant String_Access :=
- MLib.Tgt.Linker_Library_Path_Option;
+ MLib.Linker_Library_Path_Option;
begin
-- Case of library project
@@ -839,8 +839,9 @@ begin
(Name => Name_Default_Switches,
In_Arrays => Element.Decl.Arrays);
The_Switches := Prj.Util.Value_Of
- (Index => Name_Ada,
- In_Array => Default_Switches_Array);
+ (Index => Name_Ada,
+ Src_Index => 0,
+ In_Array => Default_Switches_Array);
end if;
end if;
@@ -936,7 +937,7 @@ begin
declare
There_Are_Libraries : Boolean := False;
Path_Option : constant String_Access :=
- MLib.Tgt.Linker_Library_Path_Option;
+ MLib.Linker_Library_Path_Option;
begin
Library_Paths.Set_Last (0);
diff --git a/gcc/ada/gnatlink.adb b/gcc/ada/gnatlink.adb
index 52920794600..41ef0a20929 100644
--- a/gcc/ada/gnatlink.adb
+++ b/gcc/ada/gnatlink.adb
@@ -42,6 +42,7 @@ with Ada.Command_Line; use Ada.Command_Line;
with Ada.Exceptions; use Ada.Exceptions;
with GNAT.OS_Lib; use GNAT.OS_Lib;
with Interfaces.C_Streams; use Interfaces.C_Streams;
+with Interfaces.C.Strings; use Interfaces.C.Strings;
with System.CRTL;
procedure Gnatlink is
@@ -121,8 +122,6 @@ procedure Gnatlink is
-- This table collects the arguments to be passed to compile the binder
-- generated file.
- subtype chars_ptr is System.Address;
-
Gcc : String_Access := Program_Name ("gcc");
Read_Mode : constant String := "r" & ASCII.Nul;
@@ -159,7 +158,8 @@ procedure Gnatlink is
-- Set to False if bind file is not to be compiled
Object_List_File_Supported : Boolean;
- pragma Import (C, Object_List_File_Supported, "objlist_file_supported");
+ pragma Import
+ (C, Object_List_File_Supported, "__gnat_objlist_file_supported");
-- Predicate indicating whether the linker has an option whereby the
-- names of object files can be passed to the linker in a file.
@@ -184,9 +184,6 @@ procedure Gnatlink is
procedure Process_Binder_File (Name : in String);
-- Reads the binder file and extracts linker arguments.
- function Value (chars : chars_ptr) return String;
- -- Return NUL-terminated string chars as an Ada string.
-
procedure Write_Header;
-- Show user the program name, version and copyright.
@@ -591,7 +588,7 @@ procedure Gnatlink is
-- Projected number of bytes for the linker command line
Link_Max : Integer;
- pragma Import (C, Link_Max, "link_max");
+ pragma Import (C, Link_Max, "__gnat_link_max");
-- Maximum number of bytes on the command line supported by the OS
-- linker. Passed this limit the response file mechanism must be used
-- if supported.
@@ -652,24 +649,25 @@ procedure Gnatlink is
RB_Nlast : Integer; -- Slice last index
RB_Nfirst : Integer; -- Slice first index
- Run_Path_Option_Ptr : Address;
- pragma Import (C, Run_Path_Option_Ptr, "run_path_option");
+ Run_Path_Option_Ptr : Interfaces.C.Strings.chars_ptr;
+ pragma Import (C, Run_Path_Option_Ptr, "__gnat_run_path_option");
-- Pointer to string representing the native linker option which
-- specifies the path where the dynamic loader should find shared
-- libraries. Equal to null string if this system doesn't support it.
- Object_Library_Ext_Ptr : Address;
- pragma Import (C, Object_Library_Ext_Ptr, "object_library_extension");
+ Object_Library_Ext_Ptr : Interfaces.C.Strings.chars_ptr;
+ pragma Import
+ (C, Object_Library_Ext_Ptr, "__gnat_object_library_extension");
-- Pointer to string specifying the default extension for
-- object libraries, e.g. Unix uses ".a", VMS uses ".olb".
- Object_File_Option_Ptr : Address;
- pragma Import (C, Object_File_Option_Ptr, "object_file_option");
+ Object_File_Option_Ptr : Interfaces.C.Strings.chars_ptr;
+ pragma Import (C, Object_File_Option_Ptr, "__gnat_object_file_option");
-- Pointer to a string representing the linker option which specifies
-- the response file.
Using_GNU_Linker : Boolean;
- pragma Import (C, Using_GNU_Linker, "using_gnu_linker");
+ pragma Import (C, Using_GNU_Linker, "__gnat_using_gnu_linker");
-- Predicate indicating whether this target uses the GNU linker. In
-- this case we must output a GNU linker compatible response file.
@@ -1247,31 +1245,6 @@ procedure Gnatlink is
Status := fclose (Fd);
end Process_Binder_File;
- -----------
- -- Value --
- -----------
-
- function Value (chars : chars_ptr) return String is
- function Strlen (chars : chars_ptr) return Natural;
- pragma Import (C, Strlen);
-
- begin
- if chars = Null_Address then
- return "";
-
- else
- declare
- subtype Result_Type is String (1 .. Strlen (chars));
-
- Result : Result_Type;
- for Result'Address use chars;
-
- begin
- return Result;
- end;
- end if;
- end Value;
-
------------------
-- Write_Header --
------------------
diff --git a/gcc/ada/gnatls.adb b/gcc/ada/gnatls.adb
index c66725114c0..1e491f2a7d3 100644
--- a/gcc/ada/gnatls.adb
+++ b/gcc/ada/gnatls.adb
@@ -37,9 +37,13 @@ with Opt; use Opt;
with Osint; use Osint;
with Osint.L; use Osint.L;
with Output; use Output;
+with Rident; use Rident;
+with Snames;
with Targparm; use Targparm;
with Types; use Types;
+with GNAT.Case_Util; use GNAT.Case_Util;
+
procedure Gnatls is
pragma Ident (Gnat_Static_Version_String);
@@ -147,7 +151,7 @@ procedure Gnatls is
-- Print out FS either in a coded form if verbose is false or in an
-- expanded form otherwise.
- procedure Output_Unit (U_Id : Unit_Id);
+ procedure Output_Unit (ALI : ALI_Id; U_Id : Unit_Id);
-- Print out information on the unit when requested
procedure Reset_Print;
@@ -159,6 +163,9 @@ procedure Gnatls is
procedure Usage;
-- Print usage message
+ function Image (Restriction : Restriction_Id) return String;
+ -- Returns the capitalized image of Restriction
+
-----------------
-- Add_Lib_Dir --
-----------------
@@ -361,6 +368,31 @@ procedure Gnatls is
end if;
end Find_Status;
+ -----------
+ -- Image --
+ -----------
+
+ function Image (Restriction : Restriction_Id) return String is
+ Result : String := Restriction'Img;
+ Skip : Boolean := True;
+
+ begin
+ for J in Result'Range loop
+ if Skip then
+ Skip := False;
+ Result (J) := To_Upper (Result (J));
+
+ elsif Result (J) = '_' then
+ Skip := True;
+
+ else
+ Result (J) := To_Lower (Result (J));
+ end if;
+ end loop;
+
+ return Result;
+ end Image;
+
-------------------
-- Output_Object --
-------------------
@@ -480,7 +512,7 @@ procedure Gnatls is
-- Output_Unit --
-----------------
- procedure Output_Unit (U_Id : Unit_Id) is
+ procedure Output_Unit (ALI : ALI_Id; U_Id : Unit_Id) is
Kind : Character;
U : Unit_Record renames Units.Table (U_Id);
@@ -604,6 +636,35 @@ procedure Gnatls is
end if;
end if;
+
+ declare
+ Restrictions : constant Restrictions_Info :=
+ ALIs.Table (ALI).Restrictions;
+ begin
+ -- If the source was compiled with pragmas Restrictions,
+ -- Display these restrictions.
+
+ if Restrictions.Set /= (All_Restrictions => False) then
+ Write_Eol; Write_Str (" Restrictions =>");
+
+ -- For boolean restrictions, just display the name of the
+ -- restriction; for valued restrictions, also display the
+ -- restriction value.
+
+ for Restriction in All_Restrictions loop
+ if Restrictions.Set (Restriction) then
+ Write_Eol;
+ Write_Str (" ");
+ Write_Str (Image (Restriction));
+
+ if Restriction in All_Parameter_Restrictions then
+ Write_Str (" =>");
+ Write_Str (Restrictions.Value (Restriction)'Img);
+ end if;
+ end if;
+ end loop;
+ end if;
+ end;
end if;
if Print_Source then
@@ -878,6 +939,7 @@ begin
Namet.Initialize;
Csets.Initialize;
+ Snames.Initialize;
-- Loop to scan out arguments
@@ -1049,7 +1111,7 @@ begin
Write_Eol;
end if;
- Output_Unit (U);
+ Output_Unit (Id, U);
-- Output source now, unless if it will be done as part of
-- outputing dependencies.
diff --git a/gcc/ada/gprmake.adb b/gcc/ada/gprmake.adb
new file mode 100644
index 00000000000..dc8a659b0b3
--- /dev/null
+++ b/gcc/ada/gprmake.adb
@@ -0,0 +1,36 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G P R M A K E --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2004 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- --
+-- 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, 59 Temple Place - Suite 330, Boston, --
+-- MA 02111-1307, USA. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- The driver for the gprmake tool.
+
+with Makegpr;
+
+procedure Gprmake is
+begin
+ -- The code is in Makegpr
+
+ Makegpr.Gprmake;
+end Gprmake;
diff --git a/gcc/ada/i-c.ads b/gcc/ada/i-c.ads
index 9b97258c181..bcd77a897e4 100644
--- a/gcc/ada/i-c.ads
+++ b/gcc/ada/i-c.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 Free Software Foundation, Inc. --
-- --
-- This specification is derived from the Ada Reference Manual for use with --
-- GNAT. The copyright notice above, and the license provisions that follow --
@@ -50,10 +50,14 @@ pragma Pure (C);
-- Signed and Unsigned Integers. Note that in GNAT, we have ensured that
-- the standard predefined Ada types correspond to the standard C types
+ -- Note: the Integer qualifications used in the declaration of type long
+ -- avoid ambiguities when compiling in the presence of s-auxdec.ads and
+ -- a non-private system.address type.
+
type int is new Integer;
type short is new Short_Integer;
- type long is range -(2 ** (System.Parameters.long_bits - 1))
- .. +(2 ** (System.Parameters.long_bits - 1)) - 1;
+ type long is range -(2 ** (System.Parameters.long_bits - Integer'(1)))
+ .. +(2 ** (System.Parameters.long_bits - Integer'(1))) - 1;
type signed_char is range SCHAR_MIN .. SCHAR_MAX;
for signed_char'Size use CHAR_BIT;
@@ -67,9 +71,13 @@ pragma Pure (C);
subtype plain_char is unsigned_char; -- ??? should be parametrized
+ -- Note: the Integer qualifications used in the declaration of ptrdiff_t
+ -- avoid ambiguities when compiling in the presence of s-auxdec.ads and
+ -- a non-private system.address type.
+
type ptrdiff_t is
- range -(2 ** (Standard'Address_Size - 1)) ..
- +(2 ** (Standard'Address_Size - 1) - 1);
+ range -(2 ** (Standard'Address_Size - Integer'(1))) ..
+ +(2 ** (Standard'Address_Size - Integer'(1)) - 1);
type size_t is mod 2 ** Standard'Address_Size;
diff --git a/gcc/ada/i-cpp-vms.adb b/gcc/ada/i-cpp-vms.adb
new file mode 100644
index 00000000000..a0a8a49962e
--- /dev/null
+++ b/gcc/ada/i-cpp-vms.adb
@@ -0,0 +1,346 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- I N T E R F A C E S . C P P --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2000-2004, 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the OpenVMS/Alpha DEC C++ (cxx) version of this package
+
+with Ada.Tags; use Ada.Tags;
+with System; use System;
+with System.Storage_Elements; use System.Storage_Elements;
+with Unchecked_Conversion;
+
+package body Interfaces.CPP is
+
+ subtype Cstring is String (Positive);
+ type Cstring_Ptr is access all Cstring;
+ type Tag_Table is array (Natural range <>) of Vtable_Ptr;
+ pragma Suppress_Initialization (Tag_Table);
+
+ type Type_Specific_Data is record
+ Idepth : Natural;
+ Expanded_Name : Cstring_Ptr;
+ External_Tag : Cstring_Ptr;
+ HT_Link : Tag;
+ Ancestor_Tags : Tag_Table (Natural);
+ end record;
+
+ type Vtable_Entry is record
+ Pfn : System.Address;
+ end record;
+
+ type Type_Specific_Data_Ptr is access all Type_Specific_Data;
+ type Vtable_Entry_Array is array (Positive range <>) of Vtable_Entry;
+
+ type VTable is record
+ Prims_Ptr : Vtable_Entry_Array (Positive);
+ TSD : Type_Specific_Data_Ptr;
+ -- Location of TSD is unknown so it got moved here to be out of the
+ -- way of Prims_Ptr. Find it later. ???
+ end record;
+
+ --------------------------------------------------------
+ -- Unchecked Conversions for Tag, Vtable_Ptr, and TSD --
+ --------------------------------------------------------
+
+ function To_Type_Specific_Data_Ptr is
+ new Unchecked_Conversion (Address, Type_Specific_Data_Ptr);
+
+ function To_Address is
+ new Unchecked_Conversion (Type_Specific_Data_Ptr, Address);
+
+ ---------------------------------------------
+ -- Unchecked Conversions for String Fields --
+ ---------------------------------------------
+
+ function To_Cstring_Ptr is
+ new Unchecked_Conversion (Address, Cstring_Ptr);
+
+ function To_Address is
+ new Unchecked_Conversion (Cstring_Ptr, Address);
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ function Length (Str : Cstring_Ptr) return Natural;
+ -- Length of string represented by the given pointer (treating the
+ -- string as a C-style string, which is Nul terminated).
+
+ --------------------
+ -- Displaced_This --
+ --------------------
+
+ function Displaced_This
+ (Current_This : System.Address;
+ Vptr : Vtable_Ptr;
+ Position : Positive) return System.Address
+ is
+ pragma Warnings (Off, Vptr);
+ pragma Warnings (Off, Position);
+ begin
+ return Current_This;
+ -- + Storage_Offset (Vptr.Prims_Ptr (Position).Delta1);
+ -- why is above line commented out ???
+ end Displaced_This;
+
+ -----------------------
+ -- CPP_CW_Membership --
+ -----------------------
+
+ function CPP_CW_Membership
+ (Obj_Tag : Vtable_Ptr;
+ Typ_Tag : Vtable_Ptr) return Boolean
+ is
+ Pos : constant Integer := Obj_Tag.TSD.Idepth - Typ_Tag.TSD.Idepth;
+ begin
+ return Pos >= 0 and then Obj_Tag.TSD.Ancestor_Tags (Pos) = Typ_Tag;
+ end CPP_CW_Membership;
+
+ ---------------------------
+ -- CPP_Get_Expanded_Name --
+ ---------------------------
+
+ function CPP_Get_Expanded_Name (T : Vtable_Ptr) return Address is
+ begin
+ return To_Address (T.TSD.Expanded_Name);
+ end CPP_Get_Expanded_Name;
+
+ --------------------------
+ -- CPP_Get_External_Tag --
+ --------------------------
+
+ function CPP_Get_External_Tag (T : Vtable_Ptr) return Address is
+ begin
+ return To_Address (T.TSD.External_Tag);
+ end CPP_Get_External_Tag;
+
+ -------------------------------
+ -- CPP_Get_Inheritance_Depth --
+ -------------------------------
+
+ function CPP_Get_Inheritance_Depth (T : Vtable_Ptr) return Natural is
+ begin
+ return T.TSD.Idepth;
+ end CPP_Get_Inheritance_Depth;
+
+ -----------------------
+ -- CPP_Get_RC_Offset --
+ -----------------------
+
+ function CPP_Get_RC_Offset (T : Vtable_Ptr) return SSE.Storage_Offset is
+ pragma Warnings (Off, T);
+ begin
+ return 0;
+ end CPP_Get_RC_Offset;
+
+ -----------------------------
+ -- CPP_Get_Prim_Op_Address --
+ -----------------------------
+
+ function CPP_Get_Prim_Op_Address
+ (T : Vtable_Ptr;
+ Position : Positive) return Address
+ is
+ begin
+ return T.Prims_Ptr (Position).Pfn;
+ end CPP_Get_Prim_Op_Address;
+
+ -------------------------------
+ -- CPP_Get_Remotely_Callable --
+ -------------------------------
+
+ function CPP_Get_Remotely_Callable (T : Vtable_Ptr) return Boolean is
+ pragma Warnings (Off, T);
+ begin
+ return True;
+ end CPP_Get_Remotely_Callable;
+
+ -----------------
+ -- CPP_Get_TSD --
+ -----------------
+
+ function CPP_Get_TSD (T : Vtable_Ptr) return Address is
+ begin
+ return To_Address (T.TSD);
+ end CPP_Get_TSD;
+
+ --------------------
+ -- CPP_Inherit_DT --
+ --------------------
+
+ procedure CPP_Inherit_DT
+ (Old_T : Vtable_Ptr;
+ New_T : Vtable_Ptr;
+ Entry_Count : Natural)
+ is
+ begin
+ if Old_T /= null then
+ New_T.Prims_Ptr (1 .. Entry_Count) :=
+ Old_T.Prims_Ptr (1 .. Entry_Count);
+ end if;
+ end CPP_Inherit_DT;
+
+ ---------------------
+ -- CPP_Inherit_TSD --
+ ---------------------
+
+ procedure CPP_Inherit_TSD
+ (Old_TSD : Address;
+ New_Tag : Vtable_Ptr)
+ is
+ TSD : constant Type_Specific_Data_Ptr :=
+ To_Type_Specific_Data_Ptr (Old_TSD);
+
+ New_TSD : Type_Specific_Data renames New_Tag.TSD.all;
+
+ begin
+ if TSD /= null then
+ New_TSD.Idepth := TSD.Idepth + 1;
+ New_TSD.Ancestor_Tags (1 .. New_TSD.Idepth)
+ := TSD.Ancestor_Tags (0 .. TSD.Idepth);
+ else
+ New_TSD.Idepth := 0;
+ end if;
+
+ New_TSD.Ancestor_Tags (0) := New_Tag;
+ end CPP_Inherit_TSD;
+
+ ---------------------------
+ -- CPP_Set_Expanded_Name --
+ ---------------------------
+
+ procedure CPP_Set_Expanded_Name (T : Vtable_Ptr; Value : Address) is
+ begin
+ T.TSD.Expanded_Name := To_Cstring_Ptr (Value);
+ end CPP_Set_Expanded_Name;
+
+ --------------------------
+ -- CPP_Set_External_Tag --
+ --------------------------
+
+ procedure CPP_Set_External_Tag (T : Vtable_Ptr; Value : Address) is
+ begin
+ T.TSD.External_Tag := To_Cstring_Ptr (Value);
+ end CPP_Set_External_Tag;
+
+ -------------------------------
+ -- CPP_Set_Inheritance_Depth --
+ -------------------------------
+
+ procedure CPP_Set_Inheritance_Depth
+ (T : Vtable_Ptr;
+ Value : Natural)
+ is
+ begin
+ T.TSD.Idepth := Value;
+ end CPP_Set_Inheritance_Depth;
+
+ -----------------------------
+ -- CPP_Set_Prim_Op_Address --
+ -----------------------------
+
+ procedure CPP_Set_Prim_Op_Address
+ (T : Vtable_Ptr;
+ Position : Positive;
+ Value : Address)
+ is
+ begin
+ T.Prims_Ptr (Position).Pfn := Value;
+ end CPP_Set_Prim_Op_Address;
+
+ -----------------------
+ -- CPP_Set_RC_Offset --
+ -----------------------
+
+ procedure CPP_Set_RC_Offset (T : Vtable_Ptr; Value : SSE.Storage_Offset) is
+ pragma Warnings (Off, T);
+ pragma Warnings (Off, Value);
+ begin
+ null;
+ end CPP_Set_RC_Offset;
+
+ -------------------------------
+ -- CPP_Set_Remotely_Callable --
+ -------------------------------
+
+ procedure CPP_Set_Remotely_Callable (T : Vtable_Ptr; Value : Boolean) is
+ pragma Warnings (Off, T);
+ pragma Warnings (Off, Value);
+ begin
+ null;
+ end CPP_Set_Remotely_Callable;
+
+ -----------------
+ -- CPP_Set_TSD --
+ -----------------
+
+ procedure CPP_Set_TSD (T : Vtable_Ptr; Value : Address) is
+ begin
+ T.TSD := To_Type_Specific_Data_Ptr (Value);
+ end CPP_Set_TSD;
+
+ -------------------
+ -- Expanded_Name --
+ -------------------
+
+ function Expanded_Name (T : Vtable_Ptr) return String is
+ Result : constant Cstring_Ptr := T.TSD.Expanded_Name;
+ begin
+ return Result (1 .. Length (Result));
+ end Expanded_Name;
+
+ ------------------
+ -- External_Tag --
+ ------------------
+
+ function External_Tag (T : Vtable_Ptr) return String is
+ Result : constant Cstring_Ptr := T.TSD.External_Tag;
+ begin
+ return Result (1 .. Length (Result));
+ end External_Tag;
+
+ ------------
+ -- Length --
+ ------------
+
+ function Length (Str : Cstring_Ptr) return Natural is
+ Len : Integer := 1;
+
+ begin
+ while Str (Len) /= ASCII.Nul loop
+ Len := Len + 1;
+ end loop;
+
+ return Len - 1;
+ end Length;
+
+end Interfaces.CPP;
diff --git a/gcc/ada/i-cstrea-vms.adb b/gcc/ada/i-cstrea-vms.adb
new file mode 100644
index 00000000000..75b35966021
--- /dev/null
+++ b/gcc/ada/i-cstrea-vms.adb
@@ -0,0 +1,255 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- I N T E R F A C E S . C _ S T R E A M S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1996-2004 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the Alpha/VMS version.
+
+with Unchecked_Conversion;
+package body Interfaces.C_Streams is
+
+ use type System.CRTL.size_t;
+
+ -- As the functions fread, fwrite and setvbuf are too big to be inlined,
+ -- they are just wrappers to the following implementation functions.
+
+ function fread_impl
+ (buffer : voids;
+ size : size_t;
+ count : size_t;
+ stream : FILEs) return size_t;
+
+ function fread_impl
+ (buffer : voids;
+ index : size_t;
+ size : size_t;
+ count : size_t;
+ stream : FILEs) return size_t;
+
+ function fwrite_impl
+ (buffer : voids;
+ size : size_t;
+ count : size_t;
+ stream : FILEs) return size_t;
+
+ function setvbuf_impl
+ (stream : FILEs;
+ buffer : chars;
+ mode : int;
+ size : size_t) return int;
+
+ ------------
+ -- fread --
+ ------------
+
+ function fread_impl
+ (buffer : voids;
+ size : size_t;
+ count : size_t;
+ stream : FILEs) return size_t
+ is
+ Get_Count : size_t := 0;
+
+ type Buffer_Type is array (size_t range 1 .. count,
+ size_t range 1 .. size) of Character;
+ type Buffer_Access is access Buffer_Type;
+ function To_BA is new Unchecked_Conversion (voids, Buffer_Access);
+
+ BA : constant Buffer_Access := To_BA (buffer);
+ Ch : int;
+
+ begin
+ -- This Fread goes with the Fwrite below.
+ -- The C library fread sometimes can't read fputc generated files.
+
+ for C in 1 .. count loop
+ for S in 1 .. size loop
+ Ch := fgetc (stream);
+
+ if Ch = EOF then
+ return Get_Count;
+ end if;
+
+ BA.all (C, S) := Character'Val (Ch);
+ end loop;
+
+ Get_Count := Get_Count + 1;
+ end loop;
+
+ return Get_Count;
+ end fread_impl;
+
+ function fread_impl
+ (buffer : voids;
+ index : size_t;
+ size : size_t;
+ count : size_t;
+ stream : FILEs) return size_t
+ is
+ Get_Count : size_t := 0;
+
+ type Buffer_Type is array (size_t range 1 .. count,
+ size_t range 1 .. size) of Character;
+ type Buffer_Access is access Buffer_Type;
+ function To_BA is new Unchecked_Conversion (voids, Buffer_Access);
+
+ BA : constant Buffer_Access := To_BA (buffer);
+ Ch : int;
+
+ begin
+ -- This Fread goes with the Fwrite below.
+ -- The C library fread sometimes can't read fputc generated files.
+
+ for C in 1 + index .. count + index loop
+ for S in 1 .. size loop
+ Ch := fgetc (stream);
+
+ if Ch = EOF then
+ return Get_Count;
+ end if;
+
+ BA.all (C, S) := Character'Val (Ch);
+ end loop;
+
+ Get_Count := Get_Count + 1;
+ end loop;
+
+ return Get_Count;
+ end fread_impl;
+
+ function fread
+ (buffer : voids;
+ size : size_t;
+ count : size_t;
+ stream : FILEs) return size_t
+ is
+ begin
+ return fread_impl (buffer, size, count, stream);
+ end fread;
+
+ function fread
+ (buffer : voids;
+ index : size_t;
+ size : size_t;
+ count : size_t;
+ stream : FILEs) return size_t
+ is
+ begin
+ return fread_impl (buffer, index, size, count, stream);
+ end fread;
+
+ ------------
+ -- fwrite --
+ ------------
+
+ function fwrite_impl
+ (buffer : voids;
+ size : size_t;
+ count : size_t;
+ stream : FILEs) return size_t
+ is
+ Put_Count : size_t := 0;
+
+ type Buffer_Type is array (size_t range 1 .. count,
+ size_t range 1 .. size) of Character;
+ type Buffer_Access is access Buffer_Type;
+ function To_BA is new Unchecked_Conversion (voids, Buffer_Access);
+
+ BA : constant Buffer_Access := To_BA (buffer);
+
+ begin
+ -- Fwrite on VMS has the undesirable effect of always generating at
+ -- least one record of output per call, regardless of buffering. To
+ -- get around this, we do multiple fputc calls instead.
+
+ for C in 1 .. count loop
+ for S in 1 .. size loop
+ if fputc (Character'Pos (BA.all (C, S)), stream) = EOF then
+ return Put_Count;
+ end if;
+ end loop;
+
+ Put_Count := Put_Count + 1;
+ end loop;
+
+ return Put_Count;
+ end fwrite_impl;
+
+ function fwrite
+ (buffer : voids;
+ size : size_t;
+ count : size_t;
+ stream : FILEs) return size_t
+ is
+ begin
+ return fwrite_impl (buffer, size, count, stream);
+ end fwrite;
+
+ -------------
+ -- setvbuf --
+ -------------
+
+ function setvbuf_impl
+ (stream : FILEs;
+ buffer : chars;
+ mode : int;
+ size : size_t) return int
+ is
+ use type System.Address;
+
+ begin
+ -- In order for the above fwrite hack to work, we must always buffer
+ -- stdout and stderr. Is_regular_file on VMS cannot detect when
+ -- these are redirected to a file, so checking for that condition
+ -- doesnt help.
+
+ if mode = IONBF
+ and then (stream = stdout or else stream = stderr)
+ then
+ return System.CRTL.setvbuf
+ (stream, buffer, IOLBF, System.CRTL.size_t (size));
+ else
+ return System.CRTL.setvbuf
+ (stream, buffer, mode, System.CRTL.size_t (size));
+ end if;
+ end setvbuf_impl;
+
+ function setvbuf
+ (stream : FILEs;
+ buffer : chars;
+ mode : int;
+ size : size_t) return int
+ is
+ begin
+ return setvbuf_impl (stream, buffer, mode, size);
+ end setvbuf;
+
+end Interfaces.C_Streams;
diff --git a/gcc/ada/impunit.adb b/gcc/ada/impunit.adb
index b69886cca90..0dbe4795980 100644
--- a/gcc/ada/impunit.adb
+++ b/gcc/ada/impunit.adb
@@ -122,7 +122,7 @@ package body Impunit is
"a-nlelfu", -- Ada.Numerics.Long_Elementary_Functions
"a-nllcef", -- Ada.Long_Long_Complex_Elementary_Functions
"a-nllefu", -- Ada.Numerics.Long_Long_Elementary_Functions
- "a-nltcty", -- Ada.Numerics.Long_Long_Complex_Types
+ "a-nllcty", -- Ada.Numerics.Long_Long_Complex_Types
"a-nscefu", -- Ada.Short_Complex_Elementary_Functions
"a-nscoty", -- Ada.Numerics.Short_Complex_Types
"a-nselfu", -- Ada.Numerics.Short_Elementary_Functions
diff --git a/gcc/ada/init.c b/gcc/ada/init.c
index efc1a25fc2a..b27e059ed9d 100644
--- a/gcc/ada/init.c
+++ b/gcc/ada/init.c
@@ -386,7 +386,6 @@ __gnat_initialize (void)
exclude this case in the above test. */
#include <signal.h>
-#include <setjmp.h>
#include <sys/siginfo.h>
static void __gnat_error_handler (int, siginfo_t *, struct sigcontext *);
@@ -404,7 +403,6 @@ __gnat_error_handler (int sig, siginfo_t *sip, struct sigcontext *context)
static int recurse = 0;
struct sigcontext *mstate;
const char *msg;
- jmp_buf handler_jmpbuf;
/* If this was an explicit signal from a "kill", just resignal it. */
if (SI_FROMUSER (sip))
@@ -414,43 +412,6 @@ __gnat_error_handler (int sig, siginfo_t *sip, struct sigcontext *context)
}
/* Otherwise, treat it as something we handle. */
-
- /* We are now going to raise the exception corresponding to the signal we
- caught, which may eventually end up resuming the application code if the
- exception is handled.
-
- When the exception is handled, merely arranging for the *exception*
- handler's context (stack pointer, program counter, other registers, ...)
- to be installed is *not* enough to let the kernel think we've left the
- *signal* handler. This has annoying implications if an alternate stack
- has been setup for this *signal* handler, because the kernel thinks we
- are still running on that alternate stack even after the jump, which
- causes trouble at least as soon as another signal is raised.
-
- We deal with this by forcing a "local" longjmp within the signal handler
- below, forcing the "on alternate stack" indication to be reset (kernel
- wise) on the way. If no alternate stack has been setup, this should be a
- neutral operation. Otherwise, we will be in a delicate situation for a
- short while because we are going to run the exception propagation code
- within the alternate stack area (that is, with the stack pointer inside
- the alternate stack bounds), but with the corresponding flag off from the
- kernel's standpoint. We expect this to be ok as long as the propagation
- code does not trigger a signal itself, which is expected.
-
- ??? A better approach would be to at least delay this operation until the
- last second, that is, until just before we jump to the exception handler,
- if any. */
-
- if (setjmp (handler_jmpbuf) == 0)
- {
-#define JB_ONSIGSTK 0
-
- /* Arrange for the "on alternate stack" flag to be reset. See the
- comments around "jmp_buf offsets" in /usr/include/setjmp.h. */
- handler_jmpbuf [JB_ONSIGSTK] = 0;
- longjmp (handler_jmpbuf, 1);
- }
-
switch (sig)
{
case SIGSEGV:
@@ -510,36 +471,12 @@ __gnat_install_handler (void)
{
struct sigaction act;
- /* stack-checking on this platform is performed by the back-end and conforms
- to what the ABI *mandates* (DEC OSF/1 Calling standard for AXP systems,
- chapter 6: Stack Limits in Multihtreaded Execution Environments). This
- does not include a "stack reserve" region, so nothing guarantees that
- enough room remains on the current stack to propagate an exception when
- a stack-overflow is signaled. We deal with this by requesting the use of
- an alternate stack region for signal handlers.
-
- ??? The actual use of this alternate region depends on the act.sa_flags
- including SA_ONSTACK below. Care should be taken to update s-intman if
- we want this to happen for tasks also. */
-
- static char sig_stack [8*1024];
- /* 8K is a mininum to be able to propagate an exception using the GCC/ZCX
- scheme. */
-
- struct sigaltstack ss;
-
- ss.ss_sp = (void *) sig_stack;
- ss.ss_size = sizeof (sig_stack);
- ss.ss_flags = 0;
-
- sigaltstack (&ss, 0);
-
/* Setup signal handler to map synchronous signals to appropriate
exceptions. Make sure that the handler isn't interrupted by another
signal that might cause a scheduling event! */
act.sa_handler = (void (*) (int)) __gnat_error_handler;
- act.sa_flags = SA_ONSTACK | SA_RESTART | SA_NODEFER | SA_SIGINFO;
+ act.sa_flags = SA_RESTART | SA_NODEFER | SA_SIGINFO;
sigemptyset (&act.sa_mask);
/* Do not install handlers if interrupt state is "System" */
@@ -1344,11 +1281,24 @@ __gnat_initialize (void)
#elif defined (VMS)
+#ifdef __IA64
+#define lib_get_curr_invo_context LIB$I64_GET_CURR_INVO_CONTEXT
+#define lib_get_prev_invo_context LIB$I64_GET_PREV_INVO_CONTEXT
+#define lib_get_invo_handle LIB$I64_GET_INVO_HANDLE
+#else
+#define lib_get_curr_invo_context LIB$GET_CURR_INVO_CONTEXT
+#define lib_get_prev_invo_context LIB$GET_PREV_INVO_CONTEXT
+#define lib_get_invo_handle LIB$GET_INVO_HANDLE
+#endif
+
+#if defined (IN_RTS) && !defined (__IA64)
+
/* The prehandler actually gets control first on a condition. It swaps the
stack pointer and calls the handler (__gnat_error_handler). */
extern long __gnat_error_prehandler (void);
extern char *__gnat_error_prehandler_stack; /* Alternate signal stack */
+#endif
/* Conditions that don't have an Ada exception counterpart must raise
Non_Ada_Error. Since this is defined in s-auxdec, it should only be
@@ -1524,10 +1474,10 @@ __gnat_error_handler (int *sigargs, void *mechargs)
mstate = (long *) (*Get_Machine_State_Addr) ();
if (mstate != 0)
{
- LIB$GET_CURR_INVO_CONTEXT (&curr_icb);
- LIB$GET_PREV_INVO_CONTEXT (&curr_icb);
- LIB$GET_PREV_INVO_CONTEXT (&curr_icb);
- curr_invo_handle = LIB$GET_INVO_HANDLE (&curr_icb);
+ lib_get_curr_invo_context (&curr_icb);
+ lib_get_prev_invo_context (&curr_icb);
+ lib_get_prev_invo_context (&curr_icb);
+ curr_invo_handle = lib_get_invo_handle (&curr_icb);
*mstate = curr_invo_handle;
}
Raise_From_Signal_Handler (exception, msg);
@@ -1537,6 +1487,7 @@ void
__gnat_install_handler (void)
{
long prvhnd;
+#if defined (IN_RTS) && !defined (__IA64)
char *c;
c = (char *) xmalloc (2049);
@@ -1545,6 +1496,9 @@ __gnat_install_handler (void)
/* __gnat_error_prehandler is an assembly function. */
SYS$SETEXV (1, __gnat_error_prehandler, 3, &prvhnd);
+#else
+ SYS$SETEXV (1, __gnat_error_handler, 3, &prvhnd);
+#endif
__gnat_handler_installed = 1;
}
diff --git a/gcc/ada/interfac-vms.ads b/gcc/ada/interfac-vms.ads
new file mode 100644
index 00000000000..e4c39108cc9
--- /dev/null
+++ b/gcc/ada/interfac-vms.ads
@@ -0,0 +1,194 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- I N T E R F A C E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2002-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the implementation dependent sections of this file. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the OpenVMS version of this package which adds Float_Representation
+-- pragmas to the IEEE floating point types to ensure they remain IEEE in
+-- the presence of a configuration pragma Float_Representation (Vax_Float).
+
+-- It assumes integer sizes of 8, 16, 32 and 64 are available, and that IEEE
+-- floating-point formats are available.
+
+package Interfaces is
+pragma Pure (Interfaces);
+
+ type Integer_8 is range -2 ** 7 .. 2 ** 7 - 1;
+ for Integer_8'Size use 8;
+
+ type Integer_16 is range -2 ** 15 .. 2 ** 15 - 1;
+ for Integer_16'Size use 16;
+
+ type Integer_32 is range -2 ** 31 .. 2 ** 31 - 1;
+ for Integer_32'Size use 32;
+
+ type Integer_64 is range -2 ** 63 .. 2 ** 63 - 1;
+ for Integer_64'Size use 64;
+
+ type Unsigned_8 is mod 2 ** 8;
+ for Unsigned_8'Size use 8;
+
+ type Unsigned_16 is mod 2 ** 16;
+ for Unsigned_16'Size use 16;
+
+ type Unsigned_32 is mod 2 ** 32;
+ for Unsigned_32'Size use 32;
+
+ type Unsigned_64 is mod 2 ** 64;
+ for Unsigned_64'Size use 64;
+
+ function Shift_Left
+ (Value : Unsigned_8;
+ Amount : Natural)
+ return Unsigned_8;
+
+ function Shift_Right
+ (Value : Unsigned_8;
+ Amount : Natural)
+ return Unsigned_8;
+
+ function Shift_Right_Arithmetic
+ (Value : Unsigned_8;
+ Amount : Natural)
+ return Unsigned_8;
+
+ function Rotate_Left
+ (Value : Unsigned_8;
+ Amount : Natural)
+ return Unsigned_8;
+
+ function Rotate_Right
+ (Value : Unsigned_8;
+ Amount : Natural)
+ return Unsigned_8;
+
+ function Shift_Left
+ (Value : Unsigned_16;
+ Amount : Natural)
+ return Unsigned_16;
+
+ function Shift_Right
+ (Value : Unsigned_16;
+ Amount : Natural)
+ return Unsigned_16;
+
+ function Shift_Right_Arithmetic
+ (Value : Unsigned_16;
+ Amount : Natural)
+ return Unsigned_16;
+
+ function Rotate_Left
+ (Value : Unsigned_16;
+ Amount : Natural)
+ return Unsigned_16;
+
+ function Rotate_Right
+ (Value : Unsigned_16;
+ Amount : Natural)
+ return Unsigned_16;
+
+ function Shift_Left
+ (Value : Unsigned_32;
+ Amount : Natural)
+ return Unsigned_32;
+
+ function Shift_Right
+ (Value : Unsigned_32;
+ Amount : Natural)
+ return Unsigned_32;
+
+ function Shift_Right_Arithmetic
+ (Value : Unsigned_32;
+ Amount : Natural)
+ return Unsigned_32;
+
+ function Rotate_Left
+ (Value : Unsigned_32;
+ Amount : Natural)
+ return Unsigned_32;
+
+ function Rotate_Right
+ (Value : Unsigned_32;
+ Amount : Natural)
+ return Unsigned_32;
+
+ function Shift_Left
+ (Value : Unsigned_64;
+ Amount : Natural)
+ return Unsigned_64;
+
+ function Shift_Right
+ (Value : Unsigned_64;
+ Amount : Natural)
+ return Unsigned_64;
+
+ function Shift_Right_Arithmetic
+ (Value : Unsigned_64;
+ Amount : Natural)
+ return Unsigned_64;
+
+ function Rotate_Left
+ (Value : Unsigned_64;
+ Amount : Natural)
+ return Unsigned_64;
+
+ function Rotate_Right
+ (Value : Unsigned_64;
+ Amount : Natural)
+ return Unsigned_64;
+
+ pragma Import (Intrinsic, Shift_Left);
+ pragma Import (Intrinsic, Shift_Right);
+ pragma Import (Intrinsic, Shift_Right_Arithmetic);
+ pragma Import (Intrinsic, Rotate_Left);
+ pragma Import (Intrinsic, Rotate_Right);
+
+ -- Floating point types. We use the digits value to define the IEEE
+ -- forms, otherwise a configuration pragma specifying VAX float can
+ -- default the digits to an illegal value for IEEE.
+ -- Note: it is harmless, and explicitly permitted, to include additional
+ -- types in interfaces, so it is not wrong to have IEEE_Extended_Float
+ -- defined even if the extended format is not available.
+
+ type IEEE_Float_32 is digits 6;
+ pragma Float_Representation (IEEE_Float, IEEE_Float_32);
+
+ type IEEE_Float_64 is digits 15;
+ pragma Float_Representation (IEEE_Float, IEEE_Float_64);
+
+ type IEEE_Extended_Float is digits 15;
+ pragma Float_Representation (IEEE_Float, IEEE_Extended_Float);
+
+end Interfaces;
diff --git a/gcc/ada/lang-specs.h b/gcc/ada/lang-specs.h
index c1ad1ae36f8..8cd85a81c60 100644
--- a/gcc/ada/lang-specs.h
+++ b/gcc/ada/lang-specs.h
@@ -6,7 +6,7 @@
* *
* C Header File *
* *
- * Copyright (C) 1992-2003 Free Software Foundation, Inc. *
+ * Copyright (C) 1992-2004 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- *
@@ -32,12 +32,13 @@
{"@ada",
"\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
- %{!gnatc*:%{!gnatz*:%{!gnats*:%{!S:%{!c:\
- %eone of -c, -S, -gnatc, -gnatz, or -gnats is required for Ada}}}}}\
+ %{!gnatc*:%{!gnats*:%{!S:%{!c:\
+ %eone of -c, -S, -gnatc or -gnats is required for Ada}}}}\
gnat1 %{I*} %{k8:-gnatk8} %{w:-gnatws} %1 %{!Q:-quiet} %{nostdinc*}\
%{nostdlib*}\
-dumpbase %{.adb:%b.adb}%{.ads:%b.ads}%{!.adb:%{!.ads:%b.ada}}\
%{g*} %{O*} %{W*} %{w} %{p} %{pg:-p} %{m*} %{a} %{f*} %{d*}\
%{!S:%{o*:%w%*-gnatO}} \
%i %{S:%W{o*}%{!o*:-o %b.s}} \
- %{!gnatc*:%{!gnatz*:%{!gnats*:%(invoke_as)}}}", 0, 0, 0},
+ %{!S:%{gnatc*|gnats*: -o %j}} \
+ %{!gnatc*:%{!gnats*:%(invoke_as)}}", 0, 0, 0},
diff --git a/gcc/ada/layout.adb b/gcc/ada/layout.adb
index 119d184041c..e1757666545 100644
--- a/gcc/ada/layout.adb
+++ b/gcc/ada/layout.adb
@@ -993,6 +993,12 @@ package body Layout is
Decl := Parent (Parent (Entity (N)));
Size := (Discrim, Size.Nod);
Vtyp := Defining_Identifier (Decl);
+
+ -- Ensure that we get a private type's full type
+
+ if Present (Underlying_Type (Vtyp)) then
+ Vtyp := Underlying_Type (Vtyp);
+ end if;
end if;
Typ := Etype (N);
diff --git a/gcc/ada/lib-load.adb b/gcc/ada/lib-load.adb
index b294a84305f..03dcfe8cd73 100644
--- a/gcc/ada/lib-load.adb
+++ b/gcc/ada/lib-load.adb
@@ -43,7 +43,6 @@ with Sinfo; use Sinfo;
with Sinput; use Sinput;
with Sinput.L; use Sinput.L;
with Stand; use Stand;
-with Targparm; use Targparm;
with Tbuild; use Tbuild;
with Uname; use Uname;
@@ -143,7 +142,6 @@ package body Lib.Load is
Cunit => Cunit,
Cunit_Entity => Cunit_Entity,
Dependency_Num => 0,
- Dependent_Unit => False,
Dynamic_Elab => False,
Error_Location => Sloc (With_Node),
Expected_Unit => Spec_Name,
@@ -215,7 +213,6 @@ package body Lib.Load is
Cunit => Empty,
Cunit_Entity => Empty,
Dependency_Num => 0,
- Dependent_Unit => True,
Dynamic_Elab => False,
Error_Location => No_Location,
Expected_Unit => No_Name,
@@ -253,39 +250,6 @@ package body Lib.Load is
Fname : File_Name_Type;
Src_Ind : Source_File_Index;
- procedure Set_Load_Unit_Dependency (U : Unit_Number_Type);
- -- Sets the Dependent_Unit flag unless we have a predefined unit
- -- being loaded in High_Integrity_Mode. In this case we do not want
- -- to create a dependency, since we have loaded the unit only
- -- to inline stuff from it. If this is not the case, an error
- -- message will be issued in Rtsfind in any case.
-
- ------------------------------
- -- Set_Load_Unit_Dependency --
- ------------------------------
-
- procedure Set_Load_Unit_Dependency (U : Unit_Number_Type) is
- begin
- -- Differentiate between pragma No_Run_Time mode (that can be
- -- used with a standard installation), and HI-E mode which comes
- -- with a special installation.
-
- -- For Configurable_Run_Time_Mode set by a pragma, we do not want to
- -- create a dependency since the binder would generate references to
- -- these units. In the case of configurable run-time, we do want to
- -- establish this dependency.
-
- if Configurable_Run_Time_Mode
- and then not Configurable_Run_Time_On_Target
- and then not Debug_Flag_YY
- and then Is_Internal_File_Name (Unit_File_Name (U))
- then
- null;
- else
- Units.Table (U).Dependent_Unit := True;
- end if;
- end Set_Load_Unit_Dependency;
-
-- Start of processing for Load_Unit
begin
@@ -547,7 +511,6 @@ package body Lib.Load is
end if;
Load_Stack.Decrement_Last;
- Set_Load_Unit_Dependency (Unum);
return Unum;
-- Unit is not already in table, so try to open the file
@@ -574,7 +537,6 @@ package body Lib.Load is
Cunit => Empty,
Cunit_Entity => Empty,
Dependency_Num => 0,
- Dependent_Unit => False,
Dynamic_Elab => False,
Error_Location => Sloc (Error_Node),
Expected_Unit => Uname_Actual,
@@ -631,7 +593,6 @@ package body Lib.Load is
-- Remove load stack entry and return the entry in the file table
Load_Stack.Decrement_Last;
- Set_Load_Unit_Dependency (Unum);
return Unum;
-- Case of file not found
diff --git a/gcc/ada/lib-writ.adb b/gcc/ada/lib-writ.adb
index bc6bfe54bf9..7168e69c9a2 100644
--- a/gcc/ada/lib-writ.adb
+++ b/gcc/ada/lib-writ.adb
@@ -68,7 +68,6 @@ package body Lib.Writ is
Cunit => Empty,
Cunit_Entity => Empty,
Dependency_Num => 0,
- Dependent_Unit => True,
Dynamic_Elab => False,
Fatal_Error => False,
Generate_Code => False,
@@ -122,7 +121,6 @@ package body Lib.Writ is
Cunit => Empty,
Cunit_Entity => Empty,
Dependency_Num => 0,
- Dependent_Unit => True,
Dynamic_Elab => False,
Fatal_Error => False,
Generate_Code => False,
@@ -600,6 +598,7 @@ package body Lib.Writ is
Pname : constant Unit_Name_Type :=
Get_Parent_Spec_Name (Unit_Name (Main_Unit));
Body_Fname : File_Name_Type;
+ Body_Index : Nat;
begin
-- Loop to build the with table. A with on the main unit itself
@@ -618,7 +617,6 @@ package body Lib.Writ is
if Unit_Name (J) /= No_Name
and then (With_Flags (J) or else Unit_Name (J) = Pname)
- and then Units.Table (J).Dependent_Unit
then
Num_Withs := Num_Withs + 1;
With_Table (Num_Withs) := J;
@@ -657,12 +655,18 @@ package body Lib.Writ is
(Get_Body_Name (Uname),
Subunit => False, May_Fail => True);
+ Body_Index :=
+ Get_Unit_Index
+ (Get_Body_Name (Uname));
+
if Body_Fname = No_File then
Body_Fname := Get_File_Name (Uname, Subunit => False);
+ Body_Index := Get_Unit_Index (Uname);
end if;
else
Body_Fname := Get_File_Name (Uname, Subunit => False);
+ Body_Index := Get_Unit_Index (Uname);
end if;
-- A package is considered to have a body if it requires
@@ -675,7 +679,7 @@ package body Lib.Writ is
Write_Info_Name (Body_Fname);
Write_Info_Tab (49);
Write_Info_Name
- (Lib_File_Name (Body_Fname, Munit_Index (Unum)));
+ (Lib_File_Name (Body_Fname, Body_Index));
else
Write_Info_Name (Fname);
Write_Info_Tab (49);
@@ -1035,11 +1039,9 @@ package body Lib.Writ is
Write_Info_Initiate ('D');
Write_Info_Char (' ');
- -- Normal case of a dependent unit entry with a source index
+ -- Normal case of a unit entry with a source index
- if Sind /= No_Source_File
- and then Units.Table (Unum).Dependent_Unit
- then
+ if Sind /= No_Source_File then
Write_Info_Name (File_Name (Sind));
Write_Info_Tab (25);
Write_Info_Str (String (Time_Stamp (Sind)));
@@ -1071,8 +1073,8 @@ package body Lib.Writ is
Write_Info_Name (Reference_Name (Sind));
end if;
- -- Case where there is no source index (happens for missing files)
- -- Also come here for non-dependent units.
+ -- Case where there is no source index (happens for missing
+ -- files). In this case we write a dummy time stamp.
else
Write_Info_Name (Unit_File_Name (Unum));
diff --git a/gcc/ada/lib-xref.adb b/gcc/ada/lib-xref.adb
index 200ad6a5730..107c84951c2 100644
--- a/gcc/ada/lib-xref.adb
+++ b/gcc/ada/lib-xref.adb
@@ -1147,16 +1147,25 @@ package body Lib.Xref is
-- Special handling for access parameter
- if Ekind (Etype (XE.Ent)) = E_Anonymous_Access_Type
- and then Is_Formal (XE.Ent)
- then
- Ctyp := 'p';
+ declare
+ K : constant Entity_Kind := Ekind (Etype (XE.Ent));
+
+ begin
+ if (K = E_Anonymous_Access_Type
+ or else
+ K = E_Anonymous_Access_Subprogram_Type
+ or else K =
+ E_Anonymous_Access_Protected_Subprogram_Type)
+ and then Is_Formal (XE.Ent)
+ then
+ Ctyp := 'p';
- -- Special handling for Boolean
+ -- Special handling for Boolean
- elsif Ctyp = 'e' and then Is_Boolean_Type (Ent) then
- Ctyp := 'b';
- end if;
+ elsif Ctyp = 'e' and then Is_Boolean_Type (Ent) then
+ Ctyp := 'b';
+ end if;
+ end;
end if;
-- Special handling for abstract types and operations.
diff --git a/gcc/ada/lib-xref.ads b/gcc/ada/lib-xref.ads
index 34434b9696f..59c703fb78e 100644
--- a/gcc/ada/lib-xref.ads
+++ b/gcc/ada/lib-xref.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1998-2003, Free Software Foundation, Inc. --
+-- Copyright (C) 1998-2004, 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- --
@@ -395,6 +395,8 @@ package Lib.Xref is
E_Access_Subprogram_Type => 'P',
E_Access_Protected_Subprogram_Type => 'P',
+ E_Anonymous_Access_Subprogram_Type => ' ',
+ E_Anonymous_Access_Protected_Subprogram_Type => ' ',
E_Anonymous_Access_Type => ' ',
E_Array_Type => 'A',
E_Array_Subtype => 'A',
diff --git a/gcc/ada/lib.adb b/gcc/ada/lib.adb
index 124ca39552d..d1e8781c904 100644
--- a/gcc/ada/lib.adb
+++ b/gcc/ada/lib.adb
@@ -83,11 +83,6 @@ package body Lib is
return Units.Table (U).Dependency_Num;
end Dependency_Num;
- function Dependent_Unit (U : Unit_Number_Type) return Boolean is
- begin
- return Units.Table (U).Dependent_Unit;
- end Dependent_Unit;
-
function Dynamic_Elab (U : Unit_Number_Type) return Boolean is
begin
return Units.Table (U).Dynamic_Elab;
@@ -945,6 +940,16 @@ package body Lib is
(Option => S, Unit => Current_Sem_Unit);
end Store_Linker_Option_String;
+ -------------------------------
+ -- Synchronize_Serial_Number --
+ -------------------------------
+
+ procedure Synchronize_Serial_Number is
+ TSN : Int renames Units.Table (Current_Sem_Unit).Serial_Number;
+ begin
+ TSN := TSN + 1;
+ end Synchronize_Serial_Number;
+
---------------
-- Tree_Read --
---------------
diff --git a/gcc/ada/lib.ads b/gcc/ada/lib.ads
index 2a94f86ead9..e48f2245775 100644
--- a/gcc/ada/lib.ads
+++ b/gcc/ada/lib.ads
@@ -361,14 +361,6 @@ package Lib is
-- then called to reflect the contributions of any unit on which this
-- unit is semantically dependent.
- -- Dependent_Unit
- -- This is a Boolean flag, which is set True to indicate that this
- -- entry is for a semantically dependent unit. This flag is nearly
- -- always set True, the only exception is for a unit that is loaded
- -- by an Rtsfind request in High_Integrity_Mode, where the entity that
- -- is obtained by Rtsfind.RTE is for an inlined subprogram or other
- -- entity for which a dependency need not be created.
-
-- The units table is reset to empty at the start of the compilation of
-- each main unit by Lib.Initialize. Entries are then added by calls to
-- the Lib.Load procedure. The following subprograms are used to access
@@ -381,7 +373,6 @@ package Lib is
function Cunit (U : Unit_Number_Type) return Node_Id;
function Cunit_Entity (U : Unit_Number_Type) return Entity_Id;
- function Dependent_Unit (U : Unit_Number_Type) return Boolean;
function Dependency_Num (U : Unit_Number_Type) return Nat;
function Dynamic_Elab (U : Unit_Number_Type) return Boolean;
function Error_Location (U : Unit_Number_Type) return Source_Ptr;
@@ -527,6 +518,15 @@ package Lib is
-- Increment Serial_Number field for current unit, and return the
-- incremented value.
+ procedure Synchronize_Serial_Number;
+ -- This function increments the Serial_Number field for the current
+ -- unit but does not return the incremented value. This is used when
+ -- there is a situation where one path of control increments a serial
+ -- number (using Increment_Serial_Number), and the other path does not
+ -- and it is important to keep the serial numbers synchronized in the
+ -- two cases (e.g. when the references in a package and a client must
+ -- be kept consistent).
+
procedure Replace_Linker_Option_String
(S : String_Id; Match_String : String);
-- Replace an existing Linker_Option if the prefix Match_String
@@ -612,7 +612,6 @@ private
pragma Inline (Cunit);
pragma Inline (Cunit_Entity);
pragma Inline (Dependency_Num);
- pragma Inline (Dependent_Unit);
pragma Inline (Fatal_Error);
pragma Inline (Generate_Code);
pragma Inline (Has_RACW);
@@ -641,7 +640,6 @@ private
Cunit : Node_Id;
Cunit_Entity : Entity_Id;
Dependency_Num : Int;
- Dependent_Unit : Boolean;
Fatal_Error : Boolean;
Generate_Code : Boolean;
Has_RACW : Boolean;
diff --git a/gcc/ada/link.c b/gcc/ada/link.c
index e16978eca3e..bf98e903581 100644
--- a/gcc/ada/link.c
+++ b/gcc/ada/link.c
@@ -30,10 +30,9 @@
* *
****************************************************************************/
-/* This file contains parameterizations used by gnatlink.adb in handling */
-/* very long linker lines in systems where there are limitations on the */
-/* argument length when the command line is used to pass items to the */
-/* linker */
+/* This file contains host-specific parameters describing the behaviour */
+/* of the linker. It is used by gnatlink as well as all tools that use */
+/* Mlib. */
#include <string.h>
@@ -83,113 +82,113 @@
#define STATIC 'T'
#if defined (__osf__)
-const char *object_file_option = "-Wl,-input,";
-const char *run_path_option = "-Wl,-rpath,";
-int link_max = 10000;
-unsigned char objlist_file_supported = 1;
-char shared_libgnat_default = STATIC;
-unsigned char using_gnu_linker = 0;
-const char *object_library_extension = ".a";
+const char *__gnat_object_file_option = "-Wl,-input,";
+const char *__gnat_run_path_option = "-Wl,-rpath,";
+int __gnat_link_max = 10000;
+unsigned char __gnat_objlist_file_supported = 1;
+char __gnat_shared_libgnat_default = STATIC;
+unsigned char __gnat_using_gnu_linker = 0;
+const char *__gnat_object_library_extension = ".a";
#elif defined (sgi)
-const char *object_file_option = "-Wl,-objectlist,";
-const char *run_path_option = "-Wl,-rpath,";
-int link_max = 5000;
-unsigned char objlist_file_supported = 1;
-char shared_libgnat_default = STATIC;
-unsigned char using_gnu_linker = 0;
-const char *object_library_extension = ".a";
+const char *__gnat_object_file_option = "-Wl,-objectlist,";
+const char *__gnat_run_path_option = "-Wl,-rpath,";
+int __gnat_link_max = 5000;
+unsigned char __gnat_objlist_file_supported = 1;
+char __gnat_shared_libgnat_default = STATIC;
+unsigned char __gnat_using_gnu_linker = 0;
+const char *__gnat_object_library_extension = ".a";
#elif defined (__WIN32)
-const char *object_file_option = "";
-const char *run_path_option = "";
-int link_max = 30000;
-unsigned char objlist_file_supported = 1;
-char shared_libgnat_default = STATIC;
-unsigned char using_gnu_linker = 1;
-const char *object_library_extension = ".a";
+const char *__gnat_object_file_option = "";
+const char *__gnat_run_path_option = "";
+int __gnat_link_max = 30000;
+unsigned char __gnat_objlist_file_supported = 1;
+char __gnat_shared_libgnat_default = STATIC;
+unsigned char __gnat_using_gnu_linker = 1;
+const char *__gnat_object_library_extension = ".a";
#elif defined (__INTERIX)
-const char *object_file_option = "";
-const char *run_path_option = "";
-int link_max = 5000;
-unsigned char objlist_file_supported = 1;
-char shared_libgnat_default = STATIC;
-unsigned char using_gnu_linker = 1;
-const char *object_library_extension = ".a";
+const char *__gnat_object_file_option = "";
+const char *__gnat_run_path_option = "";
+int __gnat_link_max = 5000;
+unsigned char __gnat_objlist_file_supported = 1;
+char __gnat_shared_libgnat_default = STATIC;
+unsigned char __gnat_using_gnu_linker = 1;
+const char *__gnat_object_library_extension = ".a";
#elif defined (hpux)
-const char *object_file_option = "-Wl,-c,";
-const char *run_path_option = "-Wl,+b,";
-int link_max = 5000;
-unsigned char objlist_file_supported = 1;
-char shared_libgnat_default = STATIC;
-unsigned char using_gnu_linker = 0;
-const char *object_library_extension = ".a";
+const char *__gnat_object_file_option = "-Wl,-c,";
+const char *__gnat_run_path_option = "-Wl,+b,";
+int __gnat_link_max = 5000;
+unsigned char __gnat_objlist_file_supported = 1;
+char __gnat_shared_libgnat_default = STATIC;
+unsigned char __gnat_using_gnu_linker = 0;
+const char *__gnat_object_library_extension = ".a";
#elif defined (_AIX)
-const char *object_file_option = "-Wl,-f,";
-const char *run_path_option = "";
-int link_max = 15000;
-const unsigned char objlist_file_supported = 1;
-char shared_libgnat_default = STATIC;
-unsigned char using_gnu_linker = 0;
-const char *object_library_extension = ".a";
+const char *__gnat_object_file_option = "-Wl,-f,";
+const char *__gnat_run_path_option = "";
+int __gnat_link_max = 15000;
+const unsigned char __gnat_objlist_file_supported = 1;
+char __gnat_shared_libgnat_default = STATIC;
+unsigned char __gnat_using_gnu_linker = 0;
+const char *__gnat_object_library_extension = ".a";
#elif defined (VMS)
-const char *object_file_option = "";
-const char *run_path_option = "";
-char shared_libgnat_default = STATIC;
-int link_max = 2147483647;
-unsigned char objlist_file_supported = 0;
-unsigned char using_gnu_linker = 0;
-const char *object_library_extension = ".olb";
+const char *__gnat_object_file_option = "";
+const char *__gnat_run_path_option = "";
+char __gnat_shared_libgnat_default = STATIC;
+int __gnat_link_max = 2147483647;
+unsigned char __gnat_objlist_file_supported = 0;
+unsigned char __gnat_using_gnu_linker = 0;
+const char *__gnat_object_library_extension = ".olb";
#elif defined (sun)
-const char *object_file_option = "";
-const char *run_path_option = "-R";
-char shared_libgnat_default = STATIC;
-int link_max = 2147483647;
-unsigned char objlist_file_supported = 0;
-unsigned char using_gnu_linker = 0;
-const char *object_library_extension = ".a";
+const char *__gnat_object_file_option = "";
+const char *__gnat_run_path_option = "-Wl,-R";
+char __gnat_shared_libgnat_default = STATIC;
+int __gnat_link_max = 2147483647;
+unsigned char __gnat_objlist_file_supported = 0;
+unsigned char __gnat_using_gnu_linker = 0;
+const char *__gnat_object_library_extension = ".a";
#elif defined (__FreeBSD__)
-char *object_file_option = "";
-char *run_path_option = "-Wl,-rpath,";
-char shared_libgnat_default = STATIC;
-int link_max = 2147483647;
-unsigned char objlist_file_supported = 0;
-unsigned char using_gnu_linker = 0;
-char *object_library_extension = ".a";
+char *__gnat_object_file_option = "";
+char *__gnat_run_path_option = "-Wl,-rpath,";
+char __gnat_shared_libgnat_default = STATIC;
+int __gnat_link_max = 2147483647;
+unsigned char __gnat_objlist_file_supported = 0;
+unsigned char __gnat_using_gnu_linker = 0;
+char *__gnat_object_library_extension = ".a";
#elif defined (linux)
-const char *object_file_option = "";
-const char *run_path_option = "-Wl,-rpath,";
-char shared_libgnat_default = STATIC;
-int link_max = 8192;
-unsigned char objlist_file_supported = 1;
-unsigned char using_gnu_linker = 1;
-const char *object_library_extension = ".a";
+const char *__gnat_object_file_option = "";
+const char *__gnat_run_path_option = "-Wl,-rpath,";
+char __gnat_shared_libgnat_default = STATIC;
+int __gnat_link_max = 8192;
+unsigned char __gnat_objlist_file_supported = 1;
+unsigned char __gnat_using_gnu_linker = 1;
+const char *__gnat_object_library_extension = ".a";
#elif defined (__svr4__) && defined (i386)
-const char *object_file_option = "";
-const char *run_path_option = "";
-char shared_libgnat_default = STATIC;
-int link_max = 2147483647;
-unsigned char objlist_file_supported = 0;
-unsigned char using_gnu_linker = 0;
-const char *object_library_extension = ".a";
+const char *__gnat_object_file_option = "";
+const char *__gnat_run_path_option = "";
+char __gnat_shared_libgnat_default = STATIC;
+int __gnat_link_max = 2147483647;
+unsigned char __gnat_objlist_file_supported = 0;
+unsigned char __gnat_using_gnu_linker = 0;
+const char *__gnat_object_library_extension = ".a";
#else
/* These are the default settings for all other systems. No response file
is supported, the shared library default is STATIC. */
-const char *run_path_option = "";
-const char *object_file_option = "";
-char shared_libgnat_default = STATIC;
-int link_max = 2147483647;
-unsigned char objlist_file_supported = 0;
-unsigned char using_gnu_linker = 0;
-const char *object_library_extension = ".a";
+const char *__gnat_run_path_option = "";
+const char *__gnat_object_file_option = "";
+char __gnat_shared_libgnat_default = STATIC;
+int __gnat_link_max = 2147483647;
+unsigned char __gnat_objlist_file_supported = 0;
+unsigned char __gnat_using_gnu_linker = 0;
+const char *__gnat_object_library_extension = ".a";
#endif
diff --git a/gcc/ada/make.adb b/gcc/ada/make.adb
index 35875997962..a4b2a41ff9f 100644
--- a/gcc/ada/make.adb
+++ b/gcc/ada/make.adb
@@ -35,6 +35,7 @@ with Fname.UF; use Fname.UF;
with Gnatvsn; use Gnatvsn;
with Hostparm; use Hostparm;
with Makeusg;
+with Makeutl; use Makeutl;
with MLib.Prj;
with MLib.Tgt; use MLib.Tgt;
with MLib.Utl;
@@ -47,7 +48,6 @@ with Output; use Output;
with Prj; use Prj;
with Prj.Com;
with Prj.Env;
-with Prj.Ext;
with Prj.Pars;
with Prj.Util;
with SFN_Scan;
@@ -124,16 +124,18 @@ package body Make is
procedure Insert_Q
(Source_File : File_Name_Type;
- Source_Unit : Unit_Name_Type := No_Name);
- -- Inserts Source_File at the end of Q. Provide Source_Unit when
- -- possible for external use (gnatdist).
+ Source_Unit : Unit_Name_Type := No_Name;
+ Index : Int := 0);
+ -- Inserts Source_File at the end of Q. Provide Source_Unit when possible
+ -- for external use (gnatdist). Provide index for multi-unit sources.
function Empty_Q return Boolean;
-- Returns True if Q is empty.
procedure Extract_From_Q
- (Source_File : out File_Name_Type;
- Source_Unit : out Unit_Name_Type);
+ (Source_File : out File_Name_Type;
+ Source_Unit : out Unit_Name_Type;
+ Source_Index : out Int);
-- Extracts the first element from the Q.
procedure Insert_Project_Sources
@@ -164,12 +166,14 @@ package body Make is
-- Used to detect multiple --RTS= switches
type Q_Record is record
- File : File_Name_Type;
- Unit : Unit_Name_Type;
+ File : File_Name_Type;
+ Unit : Unit_Name_Type;
+ Index : Int;
end record;
-- File is the name of the file to compile. Unit is for gnatdist
-- use in order to easily get the unit name of a file to compile
- -- when its name is krunched or declared in gnat.adc.
+ -- when its name is krunched or declared in gnat.adc. Index, when not 0,
+ -- is the index of the unit in a multi-unit source.
package Q is new Table.Table (
Table_Component_Type => Q_Record,
@@ -180,30 +184,6 @@ package body Make is
Table_Name => "Make.Q");
-- This is the actual Q.
- -- Package Mains is used to store the mains specified on the command line
- -- and to retrieve them when a project file is used, to verify that the
- -- files exist and that they belong to a project file.
-
- package Mains is
-
- -- Mains are stored in a table. An index is used to retrieve the mains
- -- from the table.
-
- procedure Add_Main (Name : String);
- -- Add one main to the table
-
- procedure Delete;
- -- Empty the table
-
- procedure Reset;
- -- Reset the index to the beginning of the table
-
- function Next_Main return String;
- -- Increase the index and return the next main.
- -- If table is exhausted, return an empty string.
-
- end Mains;
-
-- The following instantiations and variables are necessary to save what
-- is found on the command line, in case there is a project file specified.
@@ -271,19 +251,6 @@ package body Make is
Table_Increment => 100,
Table_Name => "Make.Library_Projs");
- type Linker_Options_Data is record
- Project : Project_Id;
- Options : String_List_Id;
- end record;
-
- package Linker_Opts is new Table.Table (
- Table_Component_Type => Linker_Options_Data,
- Table_Index_Type => Integer,
- Table_Low_Bound => 1,
- Table_Initial => 10,
- Table_Increment => 100,
- Table_Name => "Make.Linker_Opts");
-
-- Two variables to keep the last binder and linker switch index
-- in tables Binder_Switches and Linker_Switches, before adding
-- switches from the project file (if any) and switches from the
@@ -380,11 +347,12 @@ package body Make is
-- Can be set to False with the switches -c, -b and -l.
-- These flags are reset to True for each invokation of procedure Gnatmake.
- Shared_String : aliased String := "-shared";
+ Shared_String : aliased String := "-shared";
+ Force_Elab_Flags_String : aliased String := "-F";
- No_Shared_Switch : aliased Argument_List := (1 .. 0 => null);
- Shared_Switch : aliased Argument_List := (1 => Shared_String'Access);
- Bind_Shared : Argument_List_Access := No_Shared_Switch'Access;
+ No_Shared_Switch : aliased Argument_List := (1 .. 0 => null);
+ Shared_Switch : aliased Argument_List := (1 => Shared_String'Access);
+ Bind_Shared : Argument_List_Access := No_Shared_Switch'Access;
-- Switch to added in front of gnatbind switches. By default no switch is
-- added. Switch "-shared" is added if there is a non-static Library
-- Project File.
@@ -414,7 +382,9 @@ package body Make is
-- and is set to True whenever one of the source of the executable is
-- compiled, or has already been compiled for another executable.
- Max_Header : constant := 200; -- Arbitrary
+ Max_Header : constant := 200;
+ -- This needs a proper comment, it used to say "arbitrary"
+ -- that's not an adequate comment ???
type Header_Num is range 1 .. Max_Header;
-- Header_Num for the hash table Obsoleted below
@@ -493,20 +463,6 @@ package body Make is
-- pragmas file to be specified for For_Project,
-- otherwise return an empty argument list.
- ----------------------
- -- Marking Routines --
- ----------------------
-
- Marking_Label : Byte := 1;
- -- Value to mark the source files
-
- procedure Mark (Source_File : File_Name_Type);
- -- Mark Source_File. Marking is used to signal that Source_File has
- -- already been inserted in the Q.
-
- function Is_Marked (Source_File : File_Name_Type) return Boolean;
- -- Returns True if Source_File was previously marked.
-
-------------------
-- Misc Routines --
-------------------
@@ -588,16 +544,6 @@ package body Make is
-- Check what steps (Compile, Bind, Link) must be executed.
-- Set the step flags accordingly.
- function Is_External_Assignment (Argv : String) return Boolean;
- -- Verify that an external assignment switch is syntactically correct.
- -- Correct forms are
- -- -Xname=value
- -- -X"name=other value"
- -- Assumptions: 'First = 1, Argv (1 .. 2) = "-X"
- -- When this function returns True, the external assignment has
- -- been entered by a call to Prj.Ext.Add, so that in a project
- -- file, External ("name") will return "value".
-
function In_Ada_Lib_Dir (File : File_Name_Type) return Boolean;
-- Get directory prefix of this file and get lib mark stored in name
-- table for this directory. Then check if an Ada lib mark has been set.
@@ -618,6 +564,7 @@ package body Make is
function Switches_Of
(Source_File : Name_Id;
Source_File_Name : String;
+ Source_Index : Int;
Naming : Naming_Data;
In_Package : Package_Id;
Allow_ALI : Boolean) return Variable_Value;
@@ -628,16 +575,6 @@ package body Make is
-- the extension ".ali". If there is no switches for either names, try the
-- default switches for Ada. If all failed, return No_Variable_Value.
- procedure Test_If_Relative_Path
- (Switch : in out String_Access;
- Parent : String_Access;
- Including_L_Switch : Boolean := True);
- -- Test if Switch is a relative search path switch.
- -- If it is, fail if Parent is null, 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.
-
function Is_In_Object_Directory
(Source_File : File_Name_Type;
Full_Lib_File : File_Name_Type) return Boolean;
@@ -710,6 +647,7 @@ package body Make is
procedure Add_Switches
(The_Package : Package_Id;
File_Name : String;
+ Index : Int;
Program : Make_Program_Type);
procedure Add_Switch
(S : String_Access;
@@ -730,13 +668,14 @@ package body Make is
-- added at the beginning of the command line.
procedure Check
- (Source_File : File_Name_Type;
- The_Args : Argument_List;
- Lib_File : File_Name_Type;
- Read_Only : Boolean;
- ALI : out ALI_Id;
- O_File : out File_Name_Type;
- O_Stamp : out Time_Stamp_Type);
+ (Source_File : File_Name_Type;
+ Source_Index : Int;
+ The_Args : Argument_List;
+ Lib_File : File_Name_Type;
+ Read_Only : Boolean;
+ ALI : out ALI_Id;
+ O_File : out File_Name_Type;
+ O_Stamp : out Time_Stamp_Type);
-- Determines whether the library file Lib_File is up-to-date or not. The
-- full name (with path information) of the object file corresponding to
-- Lib_File is returned in O_File. Its time stamp is saved in O_Stamp.
@@ -757,8 +696,9 @@ package body Make is
-- Otherwise O_File is No_File.
procedure Collect_Arguments
- (Source_File : File_Name_Type;
- Args : Argument_List);
+ (Source_File : File_Name_Type;
+ Source_Index : Int;
+ Args : Argument_List);
-- Collect all arguments for a source to be compiled, including those
-- that come from a project file.
@@ -996,6 +936,7 @@ package body Make is
procedure Add_Switches
(The_Package : Package_Id;
File_Name : String;
+ Index : Int;
Program : Make_Program_Type)
is
Switches : Variable_Value;
@@ -1010,6 +951,7 @@ package body Make is
Switches_Of
(Source_File => Name_Find,
Source_File_Name => File_Name,
+ Source_Index => Index,
Naming => Projects.Table (Main_Project).Naming,
In_Package => The_Package,
Allow_ALI =>
@@ -1158,13 +1100,14 @@ package body Make is
-----------
procedure Check
- (Source_File : File_Name_Type;
- The_Args : Argument_List;
- Lib_File : File_Name_Type;
- Read_Only : Boolean;
- ALI : out ALI_Id;
- O_File : out File_Name_Type;
- O_Stamp : out Time_Stamp_Type)
+ (Source_File : File_Name_Type;
+ Source_Index : Int;
+ The_Args : Argument_List;
+ Lib_File : File_Name_Type;
+ Read_Only : Boolean;
+ ALI : out ALI_Id;
+ O_File : out File_Name_Type;
+ O_Stamp : out Time_Stamp_Type)
is
function First_New_Spec (A : ALI_Id) return File_Name_Type;
-- Looks in the with table entries of A and returns the spec file name
@@ -1396,7 +1339,7 @@ package body Make is
-- First, collect all the switches
- Collect_Arguments (Source_File, The_Args);
+ Collect_Arguments (Source_File, Source_Index, The_Args);
Prev_Switch := Dummy_Switch;
@@ -1759,8 +1702,9 @@ package body Make is
-----------------------
procedure Collect_Arguments
- (Source_File : File_Name_Type;
- Args : Argument_List)
+ (Source_File : File_Name_Type;
+ Source_Index : Int;
+ Args : Argument_List)
is
begin
Arguments_Collected := True;
@@ -1783,10 +1727,16 @@ package body Make is
Project => Arguments_Project,
Path => Arguments_Path_Name);
- -- If the source is not a source of a project file,
- -- we simply add the saved gcc switches.
+ -- If the source is not a source of a project file, check if
+ -- this is allowed.
if Arguments_Project = No_Project then
+ if not External_Unit_Compilation_Allowed then
+ Make_Failed ("external source, not part of any projects, " &
+ "cannot be compiled (", Source_File_Name, ")");
+ end if;
+
+ -- If it is allowed, simply add the saved gcc switches
Add_Arguments (The_Saved_Gcc_Switches.all);
@@ -1841,6 +1791,7 @@ package body Make is
Switches := Switches_Of
(Source_File => Source_File,
Source_File_Name => Source_File_Name,
+ Source_Index => Source_Index,
Naming => Data.Naming,
In_Package => Compiler_Package,
Allow_ALI => False);
@@ -1939,6 +1890,7 @@ package body Make is
Most_Recent_Obj_Stamp : out Time_Stamp_Type;
Main_Unit : out Boolean;
Compilation_Failures : out Natural;
+ Main_Index : Int := 0;
Check_Readonly_Files : Boolean := False;
Do_Not_Execute : Boolean := False;
Force_Compilations : Boolean := False;
@@ -1947,15 +1899,6 @@ package body Make is
Initialize_ALI_Data : Boolean := True;
Max_Process : Positive := 1)
is
- function Compile
- (S : Name_Id;
- L : Name_Id;
- Args : Argument_List) return Process_Id;
- -- Compiles S using Args. If S is a GNAT predefined source
- -- "-gnatpg" is added to Args. Non blocking call. L corresponds to the
- -- expected library file name. Process_Id of the process spawned to
- -- execute the compile.
-
No_Mapping_File : constant Natural := 0;
type Compilation_Data is record
@@ -2044,9 +1987,23 @@ package body Make is
-- resp. No_File, No_File and No_Name if there were no compilations
-- to wait for.
- procedure Collect_Arguments_And_Compile (Source_File : File_Name_Type);
+ function Bad_Compilation_Count return Natural;
+ -- Returns the number of compilation failures.
+
+ procedure Collect_Arguments_And_Compile
+ (Source_File : File_Name_Type; Source_Index : Int);
-- Collect arguments from project file (if any) and compile
+ function Compile
+ (S : Name_Id;
+ L : Name_Id;
+ Source_Index : Int;
+ Args : Argument_List) return Process_Id;
+ -- Compiles S using Args. If S is a GNAT predefined source
+ -- "-gnatpg" is added to Args. Non blocking call. L corresponds to the
+ -- expected library file name. Process_Id of the process spawned to
+ -- execute the compile.
+
package Good_ALI is new Table.Table (
Table_Component_Type => ALI_Id,
Table_Index_Type => Natural,
@@ -2056,12 +2013,13 @@ package body Make is
Table_Name => "Make.Good_ALI");
-- Contains the set of valid ALI files that have not yet been scanned.
- procedure Record_Good_ALI (A : ALI_Id);
- -- Records in the previous set the Id of an ALI file.
-
function Good_ALI_Present return Boolean;
-- Returns True if any ALI file was recorded in the previous set.
+ procedure Get_Mapping_File (Project : Project_Id);
+ -- Get a mapping file name. If there is one to be reused, reuse it.
+ -- Otherwise, create a new mapping file.
+
function Get_Next_Good_ALI return ALI_Id;
-- Returns the next good ALI_Id record;
@@ -2073,12 +2031,8 @@ package body Make is
-- If Found is False then the compilation of File failed because we
-- could not find it. Records also Unit when possible.
- function Bad_Compilation_Count return Natural;
- -- Returns the number of compilation failures.
-
- procedure Get_Mapping_File (Project : Project_Id);
- -- Get a mapping file name. If there is one to be reused, reuse it.
- -- Otherwise, create a new mapping file.
+ procedure Record_Good_ALI (A : ALI_Id);
+ -- Records in the previous set the Id of an ALI file.
-----------------
-- Add_Process --
@@ -2200,14 +2154,16 @@ package body Make is
-- Collect_Arguments_And_Compile --
-----------------------------------
- procedure Collect_Arguments_And_Compile (Source_File : File_Name_Type) is
+ procedure Collect_Arguments_And_Compile
+ (Source_File : File_Name_Type; Source_Index : Int)
+ is
begin
-- If arguments have not yet been collected (in Check), collect them
-- now.
if not Arguments_Collected then
- Collect_Arguments (Source_File, Args);
+ Collect_Arguments (Source_File, Source_Index, Args);
end if;
-- If we use mapping file (-P or -C switches), then get one
@@ -2255,7 +2211,7 @@ package body Make is
Change_To_Object_Directory (Arguments_Project);
- Pid := Compile (Arguments_Path_Name, Lib_File,
+ Pid := Compile (Arguments_Path_Name, Lib_File, Source_Index,
Arguments (1 .. Last_Argument));
else
@@ -2267,7 +2223,7 @@ package body Make is
Change_To_Object_Directory (Arguments_Project);
end if;
- Pid := Compile (Full_Source_File, Lib_File,
+ Pid := Compile (Full_Source_File, Lib_File, Source_Index,
Arguments (1 .. Last_Argument));
end if;
end Collect_Arguments_And_Compile;
@@ -2277,9 +2233,10 @@ package body Make is
-------------
function Compile
- (S : Name_Id;
- L : Name_Id;
- Args : Argument_List) return Process_Id
+ (S : Name_Id;
+ L : Name_Id;
+ Source_Index : Int;
+ Args : Argument_List) return Process_Id
is
Comp_Args : Argument_List (Args'First .. Args'Last + 8);
Comp_Next : Integer := Args'First;
@@ -2391,7 +2348,20 @@ package body Make is
Comp_Args (Comp_Last) := Ada_Flag_2;
end if;
- if L /= Strip_Directory (L) or else Object_Directory_Path /= null then
+ if Source_Index /= 0 then
+ declare
+ Num : constant String := Source_Index'Img;
+ begin
+ Comp_Last := Comp_Last + 1;
+ Comp_Args (Comp_Last) :=
+ new String'("-gnateI" & Num (Num'First + 1 .. Num'Last));
+ end;
+ end if;
+
+ if Source_Index /= 0 or else
+ L /= Strip_Directory (L) or else
+ Object_Directory_Path /= null
+ then
-- Build -o argument.
@@ -2555,9 +2525,9 @@ package body Make is
-- Only insert in the Q if it is not already done, to avoid simultaneous
-- compilations if -jnnn is used.
- if not Is_Marked (Main_Source) then
- Insert_Q (Main_Source);
- Mark (Main_Source);
+ if not Is_Marked (Main_Source, Main_Index) then
+ Insert_Q (Main_Source, Index => Main_Index);
+ Mark (Main_Source, Main_Index);
end if;
First_Compiled_File := No_File;
@@ -2591,157 +2561,156 @@ package body Make is
-- up all the available processes.
if not Empty_Q and then Outstanding_Compiles < Max_Process then
- Extract_From_Q (Source_File, Source_Unit);
- Full_Source_File := Osint.Full_Source_Name (Source_File);
- Lib_File := Osint.Lib_File_Name (Source_File);
- Full_Lib_File := Osint.Full_Lib_File_Name (Lib_File);
-
- -- If this source has already been compiled, the executable is
- -- obsolete.
-
- if Is_In_Obsoleted (Source_File) then
- Executable_Obsolete := True;
- end if;
+ declare
+ Source_Index : Int;
+ -- Index of the current unit in the current source file
- -- If the library file is an Ada library skip it
+ begin
+ Extract_From_Q (Source_File, Source_Unit, Source_Index);
+ Full_Source_File := Osint.Full_Source_Name (Source_File);
+ Lib_File := Osint.Lib_File_Name
+ (Source_File, Source_Index);
+ Full_Lib_File := Osint.Full_Lib_File_Name (Lib_File);
- if Full_Lib_File /= No_File
- and then In_Ada_Lib_Dir (Full_Lib_File)
- then
- Verbose_Msg (Lib_File, "is in an Ada library", Prefix => " ");
+ -- If this source has already been compiled, the executable is
+ -- obsolete.
- -- If the library file is a read-only library skip it, but only
- -- if, when using project files, this library file is in the
- -- right object directory (a read-only ALI file in the object
- -- directory of a project being extended should not be skipped).
+ if Is_In_Obsoleted (Source_File) then
+ Executable_Obsolete := True;
+ end if;
- elsif Full_Lib_File /= No_File
- and then not Check_Readonly_Files
- and then Is_Readonly_Library (Full_Lib_File)
- and then Is_In_Object_Directory (Source_File, Full_Lib_File)
- then
- Verbose_Msg
- (Lib_File, "is a read-only library", Prefix => " ");
+ -- If the library file is an Ada library skip it
- -- The source file that we are checking cannot be located
+ if Full_Lib_File /= No_File
+ and then In_Ada_Lib_Dir (Full_Lib_File)
+ then
+ Verbose_Msg
+ (Lib_File, "is in an Ada library", Prefix => " ");
+
+ -- If the library file is a read-only library skip it, but
+ -- only if, when using project files, this library file is
+ -- in the right object directory (a read-only ALI file
+ -- in the object directory of a project being extended
+ -- should not be skipped).
+
+ elsif Full_Lib_File /= No_File
+ and then not Check_Readonly_Files
+ and then Is_Readonly_Library (Full_Lib_File)
+ and then Is_In_Object_Directory (Source_File, Full_Lib_File)
+ then
+ Verbose_Msg
+ (Lib_File, "is a read-only library", Prefix => " ");
- elsif Full_Source_File = No_File then
- Record_Failure (Source_File, Source_Unit, False);
+ -- The source file that we are checking cannot be located
- -- Source and library files can be located but are internal
- -- files
+ elsif Full_Source_File = No_File then
+ Record_Failure (Source_File, Source_Unit, False);
- elsif not Check_Readonly_Files
- and then Full_Lib_File /= No_File
- and then Is_Internal_File_Name (Source_File)
- then
+ -- Source and library files can be located but are internal
+ -- files
- if Force_Compilations then
- Fail
- ("not allowed to compile """ &
- Get_Name_String (Source_File) &
- """; use -a switch, or compile file with " &
- """-gnatg"" switch");
- end if;
+ elsif not Check_Readonly_Files
+ and then Full_Lib_File /= No_File
+ and then Is_Internal_File_Name (Source_File)
+ then
+ if Force_Compilations then
+ Fail
+ ("not allowed to compile """ &
+ Get_Name_String (Source_File) &
+ """; use -a switch, or compile file with " &
+ """-gnatg"" switch");
+ end if;
- Verbose_Msg
- (Lib_File, "is an internal library", Prefix => " ");
+ Verbose_Msg
+ (Lib_File, "is an internal library", Prefix => " ");
- -- The source file that we are checking can be located
+ -- The source file that we are checking can be located
- else
- Arguments_Collected := False;
+ else
+ Arguments_Collected := False;
- -- Don't waste any time if we have to recompile anyway
+ -- Don't waste any time if we have to recompile anyway
- Obj_Stamp := Empty_Time_Stamp;
- Need_To_Compile := Force_Compilations;
+ Obj_Stamp := Empty_Time_Stamp;
+ Need_To_Compile := Force_Compilations;
- if not Force_Compilations then
- Read_Only :=
- Full_Lib_File /= No_File
- and then not Check_Readonly_Files
- and then Is_Readonly_Library (Full_Lib_File);
- Check (Source_File, Args, Lib_File, Read_Only,
- ALI, Obj_File, Obj_Stamp);
- Need_To_Compile := (ALI = No_ALI_Id);
- end if;
+ if not Force_Compilations then
+ Read_Only :=
+ Full_Lib_File /= No_File
+ and then not Check_Readonly_Files
+ and then Is_Readonly_Library (Full_Lib_File);
+ Check (Source_File, Source_Index, Args, Lib_File,
+ Read_Only, ALI, Obj_File, Obj_Stamp);
+ Need_To_Compile := (ALI = No_ALI_Id);
+ end if;
- if not Need_To_Compile then
+ 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);
+ Record_Good_ALI (ALI);
- -- Record the time stamp of the most recent object file
- -- as long as no (re)compilations are needed.
+ -- Record the time stamp of the most recent object file
+ -- as long as no (re)compilations are needed.
- if First_Compiled_File = No_File
- and then (Most_Recent_Obj_File = No_File
- or else Obj_Stamp > Most_Recent_Obj_Stamp)
- then
- Most_Recent_Obj_File := Obj_File;
- Most_Recent_Obj_Stamp := Obj_Stamp;
- end if;
+ if First_Compiled_File = No_File
+ and then (Most_Recent_Obj_File = No_File
+ or else Obj_Stamp > Most_Recent_Obj_Stamp)
+ then
+ Most_Recent_Obj_File := Obj_File;
+ Most_Recent_Obj_Stamp := Obj_Stamp;
+ end if;
- else
- -- Is this the first file we have to compile?
+ else
+ -- Is this the first file we have to compile?
- if First_Compiled_File = No_File then
- First_Compiled_File := Full_Source_File;
- Most_Recent_Obj_File := No_File;
+ if First_Compiled_File = No_File then
+ First_Compiled_File := Full_Source_File;
+ Most_Recent_Obj_File := No_File;
- if Do_Not_Execute then
- exit Make_Loop;
+ if Do_Not_Execute then
+ exit Make_Loop;
+ end if;
end if;
- end if;
-
- if In_Place_Mode then
- -- If the library file was not found, then save the
- -- library file near the source file.
+ if In_Place_Mode then
- if Full_Lib_File = No_File then
- Get_Name_String (Full_Source_File);
+ -- If the library file was not found, then save the
+ -- library file near the source file.
- for J in reverse 1 .. Name_Len loop
- if Name_Buffer (J) = '.' then
- Name_Buffer (J + 1 .. J + 3) := "ali";
- Name_Len := J + 3;
- exit;
- end if;
- end loop;
+ if Full_Lib_File = No_File then
+ Lib_File := Osint.Lib_File_Name
+ (Full_Source_File, Source_Index);
- Lib_File := Name_Find;
+ -- If the library file was found, then save the
+ -- library file in the same place.
- -- If the library file was found, then save the
- -- library file in the same place.
+ else
+ Lib_File := Full_Lib_File;
+ end if;
- else
- Lib_File := Full_Lib_File;
end if;
- end if;
-
- -- Start the compilation and record it. We can do this
- -- because there is at least one free process.
+ -- Start the compilation and record it. We can do this
+ -- because there is at least one free process.
- Collect_Arguments_And_Compile (Source_File);
+ Collect_Arguments_And_Compile (Source_File, Source_Index);
- -- Make sure we could successfully start the compilation
+ -- Make sure we could successfully start the compilation
- if Pid = Invalid_Pid then
- Record_Failure (Full_Source_File, Source_Unit);
- else
- Add_Process
- (Pid,
- Full_Source_File,
- Lib_File,
- Source_Unit,
- Mfile);
+ if Pid = Invalid_Pid then
+ Record_Failure (Full_Source_File, Source_Unit);
+ else
+ Add_Process
+ (Pid,
+ Full_Source_File,
+ Lib_File,
+ Source_Unit,
+ Mfile);
+ end if;
end if;
end if;
- end if;
+ end;
end if;
-- PHASE 2: Now check if we should wait for a compilation to
@@ -2838,96 +2807,111 @@ package body Make is
while Good_ALI_Present loop
ALI := Get_Next_Good_ALI;
- -- If we are processing the library file corresponding to the
- -- main source file check if this source can be a main unit.
+ declare
+ Source_Index : Int := Unit_Index_Of (ALIs.Table (ALI).Afile);
- if ALIs.Table (ALI).Sfile = Main_Source then
- Main_Unit := ALIs.Table (ALI).Main_Program /= None;
- end if;
+ begin
+ -- If we are processing the library file corresponding to the
+ -- main source file check if this source can be a main unit.
- -- 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.
+ if ALIs.Table (ALI).Sfile = Main_Source and then
+ Source_Index = Main_Index
+ then
+ Main_Unit := ALIs.Table (ALI).Main_Program /= None;
+ end if;
- -- 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.
+ -- 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.
- if Need_To_Check_Standard_Library then
- Need_To_Check_Standard_Library := False;
+ -- 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 not Targparm.Suppress_Standard_Library_On_Target then
- declare
- Sfile : Name_Id;
- Add_It : Boolean := True;
+ if Need_To_Check_Standard_Library then
+ Need_To_Check_Standard_Library := False;
- begin
- Name_Len := Standard_Library_Package_Body_Name'Length;
- Name_Buffer (1 .. Name_Len) :=
- Standard_Library_Package_Body_Name;
- Sfile := Name_Enter;
+ if not Targparm.Suppress_Standard_Library_On_Target then
+ declare
+ Sfile : Name_Id;
+ Add_It : Boolean := True;
- -- If we have a special runtime, we add the standard
- -- library only if we can find it.
+ begin
+ Name_Len := Standard_Library_Package_Body_Name'Length;
+ Name_Buffer (1 .. Name_Len) :=
+ Standard_Library_Package_Body_Name;
+ Sfile := Name_Enter;
- if RTS_Switch then
- Add_It := Find_File (Sfile, Osint.Source) /= No_File;
- end if;
+ -- If we have a special runtime, we add the standard
+ -- library only if we can find it.
- if Add_It then
- if Is_Marked (Sfile) then
- if Is_In_Obsoleted (Sfile) then
- Executable_Obsolete := True;
- end if;
+ if RTS_Switch then
+ Add_It :=
+ Find_File (Sfile, Osint.Source) /= No_File;
+ end if;
- else
- Insert_Q (Sfile);
- Mark (Sfile);
+ if Add_It then
+ if Is_Marked (Sfile) then
+ if Is_In_Obsoleted (Sfile) then
+ Executable_Obsolete := True;
+ end if;
+
+ else
+ Insert_Q (Sfile, Index => 0);
+ Mark (Sfile, Index => 0);
+ end if;
end if;
- end if;
- end;
+ end;
+ end if;
end if;
- 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
- ALIs.Table (ALI).First_Unit .. ALIs.Table (ALI).Last_Unit
- loop
- for K in
- Units.Table (J).First_With .. Units.Table (J).Last_With
+ if not Unique_Compile then
+ for J in
+ ALIs.Table (ALI).First_Unit .. ALIs.Table (ALI).Last_Unit
loop
- Sfile := Withs.Table (K).Sfile;
- Add_Dependency (ALIs.Table (ALI).Sfile, Sfile);
+ for K in
+ Units.Table (J).First_With .. Units.Table (J).Last_With
+ loop
+ Sfile := Withs.Table (K).Sfile;
+ Add_Dependency (ALIs.Table (ALI).Sfile, Sfile);
- if Is_In_Obsoleted (Sfile) then
- Executable_Obsolete := True;
- end if;
+ if Is_In_Obsoleted (Sfile) then
+ Executable_Obsolete := True;
+ end if;
+
+ if Sfile = No_File then
+ Debug_Msg
+ ("Skipping generic:", Withs.Table (K).Uname);
- if Sfile = No_File then
- Debug_Msg ("Skipping generic:", Withs.Table (K).Uname);
+ else
+ Source_Index :=
+ Unit_Index_Of (Withs.Table (K).Afile);
- elsif Is_Marked (Sfile) then
- Debug_Msg ("Skipping marked file:", Sfile);
+ if Is_Marked (Sfile, Source_Index) then
+ Debug_Msg ("Skipping marked file:", Sfile);
- elsif not Check_Readonly_Files
- and then Is_Internal_File_Name (Sfile)
- then
- Debug_Msg ("Skipping internal file:", Sfile);
+ elsif not Check_Readonly_Files
+ and then Is_Internal_File_Name (Sfile)
+ then
+ Debug_Msg ("Skipping internal file:", Sfile);
- else
- Insert_Q (Sfile, Withs.Table (K).Uname);
- Mark (Sfile);
- end if;
+ else
+ Insert_Q
+ (Sfile, Withs.Table (K).Uname, Source_Index);
+ Mark (Sfile, Source_Index);
+ end if;
+ end if;
+ end loop;
end loop;
- end loop;
- end if;
+ end if;
+ end;
end loop;
if Display_Compilation_Progress then
@@ -3320,35 +3304,34 @@ package body Make is
--------------------
procedure Extract_From_Q
- (Source_File : out File_Name_Type;
- Source_Unit : out Unit_Name_Type)
+ (Source_File : out File_Name_Type;
+ Source_Unit : out Unit_Name_Type;
+ Source_Index : out Int)
is
- File : constant File_Name_Type := Q.Table (Q_Front).File;
- Unit : constant Unit_Name_Type := Q.Table (Q_Front).Unit;
+ File : constant File_Name_Type := Q.Table (Q_Front).File;
+ Unit : constant Unit_Name_Type := Q.Table (Q_Front).Unit;
+ Index : constant Int := Q.Table (Q_Front).Index;
begin
if Debug.Debug_Flag_Q then
Write_Str (" Q := Q - [ ");
Write_Name (File);
+
+ if Index /= 0 then
+ Write_Str (", ");
+ Write_Int (Index);
+ end if;
+
Write_Str (" ]");
Write_Eol;
end if;
Q_Front := Q_Front + 1;
- Source_File := File;
- Source_Unit := Unit;
+ Source_File := File;
+ Source_Unit := Unit;
+ Source_Index := Index;
end Extract_From_Q;
- -----------------
- -- Make_Failed --
- -----------------
-
- procedure Make_Failed (S1 : String; S2 : String := ""; S3 : String := "") is
- begin
- Delete_All_Temp_Files;
- Osint.Fail (S1, S2, S3);
- end Make_Failed;
-
--------------
-- Gnatmake --
--------------
@@ -3380,6 +3363,13 @@ package body Make is
-- The current working directory, used to modify some relative path
-- switches on the command line when a project file is used.
+ Current_Main_Index : Int := 0;
+ -- If not zero, the index of the current main unit in its source file
+
+ There_Are_Stand_Alone_Libraries : Boolean := False;
+ -- Set to True when there are Stand-Alone Libraries, so that gnatbind
+ -- is invoked with the -F switch to force checking of elaboration flags.
+
begin
Gnatmake_Called := True;
@@ -3459,6 +3449,9 @@ package body Make is
end loop;
end if;
+ elsif Main_Index /= 0 and then Osint.Number_Of_Files > 1 then
+ Make_Failed ("cannot specify several mains with a multi-unit index");
+
elsif Main_Project /= No_Project then
-- If the main project file is a library project file, main(s)
@@ -3562,16 +3555,21 @@ package body Make is
Normalize_Pathname
(Real_Path.all,
Case_Sensitive => False);
+ Proj_Path : constant String :=
+ Normalize_Pathname
+ (Project_Path,
+ Case_Sensitive => False);
+
begin
Free (Real_Path);
-- Fail if it is not the correct path
- if Normed_Path /= Project_Path then
+ if Normed_Path /= Proj_Path then
if Verbose_Mode then
Write_Str (Normed_Path);
Write_Str (" /= ");
- Write_Line (Project_Path);
+ Write_Line (Proj_Path);
end if;
Make_Failed
@@ -3622,6 +3620,11 @@ package body Make is
-- the sources of the project file as mains.
else
+ if Main_Index /= 0 then
+ Make_Failed ("cannot specify a multi-unit index but no main " &
+ "on the command line");
+ end if;
+
declare
Value : String_List_Id := Projects.Table (Main_Project).Mains;
@@ -3716,7 +3719,8 @@ package body Make is
At_Least_One_Main := True;
Osint.Add_File
(Get_Name_String
- (String_Elements.Table (Value).Value));
+ (String_Elements.Table (Value).Value),
+ Index => String_Elements.Table (Value).Index);
end if;
Value := String_Elements.Table (Value).Next;
@@ -3790,6 +3794,10 @@ package body Make is
Main_Source_File := Next_Main_Source;
+ if Current_File_Index /= No_Index then
+ Main_Index := Current_File_Index;
+ end if;
+
Add_Switch ("-I-", Binder, And_Save => True);
Add_Switch ("-I-", Compiler, And_Save => True);
@@ -3982,6 +3990,7 @@ package body Make is
Add_Switches
(File_Name => Main_Unit_File_Name,
+ Index => Main_Index,
The_Package => Builder_Package,
Program => None);
@@ -3996,6 +4005,7 @@ package body Make is
Defaults : constant Variable_Value :=
Prj.Util.Value_Of
(Name => Name_Ada,
+ Index => 0,
Attribute_Or_Array_Name => Name_Default_Switches,
In_Package => Builder_Package);
@@ -4020,6 +4030,7 @@ package body Make is
Add_Switches
(File_Name => " ",
+ Index => 0,
The_Package => Builder_Package,
Program => None);
@@ -4057,6 +4068,7 @@ package body Make is
Add_Switches
(File_Name => Main_Unit_File_Name,
+ Index => Main_Index,
The_Package => Binder_Package,
Program => Binder);
end if;
@@ -4072,6 +4084,7 @@ package body Make is
Add_Switches
(File_Name => Main_Unit_File_Name,
+ Index => Main_Index,
The_Package => Linker_Package,
Program => Linker);
end if;
@@ -4303,6 +4316,8 @@ package body Make is
Bad_Compilation.Init;
+ Current_Main_Index := Main_Index;
+
-- Here is where the make process is started
-- We do the same process for each main
@@ -4359,7 +4374,7 @@ package body Make is
-- "main.2.ada", when the body termination is ".2.ada".
Executable := Prj.Util.Executable_Of
- (Main_Project, Main_Source_File);
+ (Main_Project, Main_Source_File, Main_Index);
end if;
end if;
@@ -4427,6 +4442,7 @@ package body Make is
Most_Recent_Obj_File => Youngest_Obj_File,
Most_Recent_Obj_Stamp => Youngest_Obj_Stamp,
Main_Unit => Is_Main_Unit,
+ Main_Index => Current_Main_Index,
Compilation_Failures => Compilation_Failures,
Check_Readonly_Files => Check_Readonly_Files,
Do_Not_Execute => Do_Not_Execute,
@@ -4480,6 +4496,10 @@ package body Make is
for Proj1 in Projects.First .. Projects.Last loop
+ if Projects.Table (Proj1).Standalone_Library then
+ There_Are_Stand_Alone_Libraries := True;
+ end if;
+
if Projects.Table (Proj1).Library
and then not Projects.Table (Proj1).Flag1
then
@@ -4672,7 +4692,7 @@ package body Make is
begin
Src_File := Strip_Directory (Main_Source_File);
- ALI_File := Lib_File_Name (Src_File);
+ ALI_File := Lib_File_Name (Src_File, Current_Main_Index);
Main_ALI_File := Full_Lib_File_Name (ALI_File);
-- When In_Place_Mode, the library file can be located in the
@@ -4695,7 +4715,7 @@ package body Make is
if Do_Bind_Step then
Bind_Step : declare
Args : Argument_List
- (Binder_Switches.First .. Binder_Switches.Last + 1);
+ (Binder_Switches.First .. Binder_Switches.Last + 2);
-- The arguments for the invocation of gnatbind
Last_Arg : Natural := Binder_Switches.Last;
@@ -4756,6 +4776,11 @@ package body Make is
Args (J) := Binder_Switches.Table (J);
end loop;
+ if There_Are_Stand_Alone_Libraries then
+ Last_Arg := Last_Arg + 1;
+ Args (Last_Arg) := Force_Elab_Flags_String'Access;
+ end if;
+
if Main_Project /= No_Project then
-- Put all the source directories in ADA_INCLUDE_PATH,
@@ -4963,7 +4988,7 @@ package body Make is
There_Are_Libraries : Boolean := False;
Linker_Switches_Last : constant Integer := Linker_Switches.Last;
Path_Option : constant String_Access :=
- MLib.Tgt.Linker_Library_Path_Option;
+ MLib.Linker_Library_Path_Option;
Current : Natural;
Proj2 : Project_Id;
Depth : Natural;
@@ -5118,95 +5143,14 @@ package body Make is
-- other than the main project
declare
- Linker_Package : Package_Id;
- Options : Variable_Value;
-
- begin
- Linker_Opts.Init;
-
- for Index in 1 .. Projects.Last loop
- if Index /= Main_Project then
- Linker_Package :=
- Prj.Util.Value_Of
- (Name => Name_Linker,
- In_Packages =>
- Projects.Table (Index).Decl.Packages);
- Options :=
- Prj.Util.Value_Of
- (Name => Name_Ada,
- Attribute_Or_Array_Name => Name_Linker_Options,
- In_Package => Linker_Package);
-
- -- If attribute is present, add the project with
- -- the attribute to table Linker_Opts.
-
- if Options /= Nil_Variable_Value then
- Linker_Opts.Increment_Last;
- Linker_Opts.Table (Linker_Opts.Last) :=
- (Project => Index, Options => Options.Values);
- end if;
- end if;
- end loop;
- end;
+ Linker_Options : constant String_List :=
+ Linker_Options_Switches (Main_Project);
- declare
- Opt1 : Linker_Options_Data;
- Opt2 : Linker_Options_Data;
- Depth : Natural;
- Options : String_List_Id;
- Option : Name_Id;
begin
- -- Sort the project by increasing depths
-
- for Index in 1 .. Linker_Opts.Last loop
- Opt1 := Linker_Opts.Table (Index);
- Depth := Projects.Table (Opt1.Project).Depth;
-
- for J in Index + 1 .. Linker_Opts.Last loop
- Opt2 := Linker_Opts.Table (J);
-
- if
- Projects.Table (Opt2.Project).Depth < Depth
- then
- Linker_Opts.Table (Index) := Opt2;
- Linker_Opts.Table (J) := Opt1;
- Opt1 := Opt2;
- Depth :=
- Projects.Table (Opt1.Project).Depth;
- end if;
- end loop;
-
- -- If Dir_Path has not been computed for this project,
- -- do it now.
-
- if Projects.Table (Opt1.Project).Dir_Path = null then
- Projects.Table (Opt1.Project).Dir_Path :=
- new String'
- (Get_Name_String
- (Projects.Table (Opt1.Project). Directory));
- end if;
-
- Options := Opt1.Options;
-
- -- Add each of the options to the linker switches
-
- while Options /= Nil_String loop
- Option := String_Elements.Table (Options).Value;
- Options := String_Elements.Table (Options).Next;
- Linker_Switches.Increment_Last;
- Linker_Switches.Table (Linker_Switches.Last) :=
- new String'(Get_Name_String (Option));
-
- -- Object files and -L switches specified with
- -- relative paths and must be converted to
- -- absolute paths.
-
- Test_If_Relative_Path
- (Switch =>
- Linker_Switches.Table (Linker_Switches.Last),
- Parent => Projects.Table (Opt1.Project).Dir_Path,
- Including_L_Switch => True);
- end loop;
+ for Option in Linker_Options'Range loop
+ Linker_Switches.Increment_Last;
+ Linker_Switches.Table (Linker_Switches.Last) :=
+ Linker_Options (Option);
end loop;
end;
end if;
@@ -5283,6 +5227,10 @@ package body Make is
if N_File < Osint.Number_Of_Files then
Main_Source_File := Next_Main_Source;
+ if Current_File_Index /= No_Index then
+ Main_Index := Current_File_Index;
+ end if;
+
if Main_Project /= No_Project then
-- Find the file name of the main unit
@@ -5368,6 +5316,7 @@ package body Make is
Add_Switches
(File_Name => Main_Unit_File_Name,
+ Index => Main_Index,
The_Package => Binder_Package,
Program => Binder);
end if;
@@ -5384,6 +5333,7 @@ package body Make is
Add_Switches
(File_Name => Main_Unit_File_Name,
+ Index => Main_Index,
The_Package => Linker_Package,
Program => Linker);
end if;
@@ -5436,17 +5386,10 @@ package body Make is
end if;
end if;
- -- Increase the marking label to be sure to check sources
- -- for all executables.
+ -- Remove all marks to be sure to check sources for all executables,
+ -- as the switches may be different and -s may be in use.
- Marking_Label := Marking_Label + 1;
-
- -- Make sure it is not 0, which is the default value for
- -- a file that has never been marked.
-
- if Marking_Label = 0 then
- Marking_Label := 1;
- end if;
+ Delete_All_Marks;
end loop Multiple_Main_Loop;
if Failed_Links.Last > 0 then
@@ -5776,14 +5719,11 @@ package body Make is
Project_Object_Directory := No_Project;
- -- Set the marking label to a value that is not zero
-
- Marking_Label := 1;
end Initialize;
- -----------------------------------
- -- Insert_Project_Sources_Into_Q --
- -----------------------------------
+ ----------------------------
+ -- Insert_Project_Sources --
+ ----------------------------
procedure Insert_Project_Sources
(The_Project : Project_Id;
@@ -5947,62 +5887,30 @@ package body Make is
procedure Insert_Q
(Source_File : File_Name_Type;
- Source_Unit : Unit_Name_Type := No_Name)
+ Source_Unit : Unit_Name_Type := No_Name;
+ Index : Int := 0)
is
begin
if Debug.Debug_Flag_Q then
Write_Str (" Q := Q + [ ");
Write_Name (Source_File);
+
+ if Index /= 0 then
+ Write_Str (", ");
+ Write_Int (Index);
+ end if;
+
Write_Str (" ] ");
Write_Eol;
end if;
- Q.Table (Q.Last).File := Source_File;
- Q.Table (Q.Last).Unit := Source_Unit;
+ Q.Table (Q.Last) :=
+ (File => Source_File,
+ Unit => Source_Unit,
+ Index => Index);
Q.Increment_Last;
end Insert_Q;
- ----------------------------
- -- Is_External_Assignment --
- ----------------------------
-
- function Is_External_Assignment (Argv : String) return Boolean is
- Start : Positive := 3;
- Finish : Natural := Argv'Last;
- Equal_Pos : Natural;
-
- begin
- if Argv'Last < 5 then
- return False;
-
- elsif Argv (3) = '"' then
- if Argv (Argv'Last) /= '"' or else Argv'Last < 7 then
- return False;
- else
- Start := 4;
- Finish := Argv'Last - 1;
- end if;
- end if;
-
- Equal_Pos := Start;
-
- while Equal_Pos <= Finish and then Argv (Equal_Pos) /= '=' loop
- Equal_Pos := Equal_Pos + 1;
- end loop;
-
- if Equal_Pos = Start
- or else Equal_Pos >= Finish
- then
- return False;
-
- else
- Prj.Ext.Add
- (External_Name => Argv (Start .. Equal_Pos - 1),
- Value => Argv (Equal_Pos + 1 .. Finish));
- return True;
- end if;
- end Is_External_Assignment;
-
---------------------
-- Is_In_Obsoleted --
---------------------
@@ -6123,15 +6031,6 @@ package body Make is
return True;
end Is_In_Object_Directory;
- ---------------
- -- Is_Marked --
- ---------------
-
- function Is_Marked (Source_File : File_Name_Type) return Boolean is
- begin
- return Get_Name_Table_Byte (Source_File) = Marking_Label;
- end Is_Marked;
-
----------
-- Link --
----------
@@ -6245,76 +6144,15 @@ package body Make is
Set_Standard_Error;
end List_Depend;
- -----------
- -- Mains --
- -----------
-
- package body Mains is
-
- package Names is new Table.Table
- (Table_Component_Type => File_Name_Type,
- Table_Index_Type => Integer,
- Table_Low_Bound => 1,
- Table_Initial => 10,
- Table_Increment => 100,
- Table_Name => "Make.Mains.Names");
- -- The table that stores the main
-
- Current : Natural := 0;
- -- The index of the last main retrieved from the table
-
- --------------
- -- Add_Main --
- --------------
-
- procedure Add_Main (Name : String) is
- begin
- Name_Len := 0;
- Add_Str_To_Name_Buffer (Name);
- Names.Increment_Last;
- Names.Table (Names.Last) := Name_Find;
- end Add_Main;
-
- ------------
- -- Delete --
- ------------
-
- procedure Delete is
- begin
- Names.Set_Last (0);
- Reset;
- end Delete;
-
- ---------------
- -- Next_Main --
- ---------------
-
- function Next_Main return String is
- begin
- if Current >= Names.Last then
- return "";
-
- else
- Current := Current + 1;
- return Get_Name_String (Names.Table (Current));
- end if;
- end Next_Main;
-
- procedure Reset is
- begin
- Current := 0;
- end Reset;
-
- end Mains;
-
- ----------
- -- Mark --
- ----------
+ -----------------
+ -- Make_Failed --
+ -----------------
- procedure Mark (Source_File : File_Name_Type) is
+ procedure Make_Failed (S1 : String; S2 : String := ""; S3 : String := "") is
begin
- Set_Name_Table_Byte (Source_File, Marking_Label);
- end Mark;
+ Delete_All_Temp_Files;
+ Osint.Fail (S1, S2, S3);
+ end Make_Failed;
--------------------
-- Mark_Directory --
@@ -6977,8 +6815,10 @@ package body Make is
-- or one character switches which are not in 'a' .. 'z'
-- (except 'C', 'F', 'M' and 'B') are passed to the compiler,
-- unless we are dealing with a debug switch (starts with 'd')
+ -- or an extended gnatmake switch (starts with 'e').
elsif Argv (2) /= 'd'
+ and then Argv (2) /= 'e'
and then Argv (2 .. Argv'Last) /= "C"
and then Argv (2 .. Argv'Last) /= "F"
and then Argv (2 .. Argv'Last) /= "M"
@@ -7008,6 +6848,7 @@ package body Make is
function Switches_Of
(Source_File : Name_Id;
Source_File_Name : String;
+ Source_Index : Int;
Naming : Naming_Data;
In_Package : Package_Id;
Allow_ALI : Boolean) return Variable_Value
@@ -7029,8 +6870,9 @@ package body Make is
begin
Switches :=
Prj.Util.Value_Of
- (Index => Source_File,
- In_Array => Switches_Array);
+ (Index => Source_File,
+ Src_Index => Source_Index,
+ In_Array => Switches_Array);
if Switches = Nil_Variable_Value then
declare
@@ -7067,8 +6909,9 @@ package body Make is
Name_Buffer (1 .. Name_Len) := Name (1 .. Last);
Switches :=
Prj.Util.Value_Of
- (Index => Name_Find,
- In_Array => Switches_Array);
+ (Index => Name_Find,
+ Src_Index => 0,
+ In_Array => Switches_Array);
if Switches = Nil_Variable_Value
and then Allow_ALI
@@ -7084,100 +6927,25 @@ package body Make is
Name_Buffer (1 .. Name_Len) := Name (1 .. Name_Len);
Switches :=
Prj.Util.Value_Of
- (Index => Name_Find,
- In_Array => Switches_Array);
+ (Index => Name_Find,
+ Src_Index => 0,
+ In_Array => Switches_Array);
end if;
end if;
end;
end if;
if Switches = Nil_Variable_Value then
- Switches := Prj.Util.Value_Of
- (Index => Name_Ada, In_Array => Defaults);
+ Switches :=
+ Prj.Util.Value_Of
+ (Index => Name_Ada,
+ Src_Index => 0,
+ In_Array => Defaults);
end if;
return Switches;
end Switches_Of;
- ---------------------------
- -- Test_If_Relative_Path --
- ---------------------------
-
- procedure Test_If_Relative_Path
- (Switch : in out String_Access;
- Parent : String_Access;
- Including_L_Switch : Boolean := True)
- is
- begin
- if Switch /= null then
-
- declare
- Sw : String (1 .. Switch'Length);
- Start : Positive;
-
- begin
- Sw := Switch.all;
-
- if Sw (1) = '-' then
- if Sw'Length >= 3
- and then (Sw (2) = 'A'
- or else Sw (2) = 'I'
- or else (Including_L_Switch and then Sw (2) = 'L'))
- then
- Start := 3;
-
- if Sw = "-I-" then
- return;
- end if;
-
- elsif Sw'Length >= 4
- and then (Sw (2 .. 3) = "aL"
- or else Sw (2 .. 3) = "aO"
- or else Sw (2 .. 3) = "aI")
- then
- Start := 4;
-
- else
- return;
- end if;
-
- -- Because relative path arguments to --RTS= may be relative
- -- to the search directory prefix, those relative path
- -- arguments are not converted.
-
- if not Is_Absolute_Path (Sw (Start .. Sw'Last)) then
- if Parent = null or else Parent'Length = 0 then
- Make_Failed
- ("relative search path switches (""",
- Sw,
- """) are not allowed");
-
- else
- Switch :=
- new String'
- (Sw (1 .. Start - 1) &
- Parent.all &
- Directory_Separator &
- Sw (Start .. Sw'Last));
- end if;
- end if;
-
- else
- if not Is_Absolute_Path (Sw) then
- if Parent = null or else Parent'Length = 0 then
- Make_Failed
- ("relative paths (""", Sw, """) are not allowed");
-
- else
- Switch :=
- new String'(Parent.all & Directory_Separator & Sw);
- end if;
- end if;
- end if;
- end;
- end if;
- end Test_If_Relative_Path;
-
-----------
-- Usage --
-----------
@@ -7225,6 +6993,7 @@ package body Make is
begin
-- Make sure that in case of failure, the temp files will be deleted
- Prj.Com.Fail := Make_Failed'Access;
- MLib.Fail := Make_Failed'Access;
+ Prj.Com.Fail := Make_Failed'Access;
+ MLib.Fail := Make_Failed'Access;
+ Makeutl.Do_Fail := Make_Failed'Access;
end Make;
diff --git a/gcc/ada/make.ads b/gcc/ada/make.ads
index f07846336c7..9fcdf6d3842 100644
--- a/gcc/ada/make.ads
+++ b/gcc/ada/make.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -112,6 +112,7 @@ package Make is
Most_Recent_Obj_Stamp : out Time_Stamp_Type;
Main_Unit : out Boolean;
Compilation_Failures : out Natural;
+ Main_Index : Int := 0;
Check_Readonly_Files : Boolean := False;
Do_Not_Execute : Boolean := False;
Force_Compilations : Boolean := False;
@@ -148,6 +149,10 @@ package Make is
-- Compilation_Failures is a count of compilation failures. This count
-- is used to extract compilation failure reports with Extract_Failure.
--
+ -- Main_Index, when not zero, is the index of the main unit in source
+ -- file Main_Source which is a multi-unit source.
+ -- Zero indicates that Main_Source is a single unit source file.
+ --
-- Check_Readonly_Files set it to True to compile source files
-- which library files are read-only. When compiling GNAT predefined
-- files the "-gnatg" flag is used.
diff --git a/gcc/ada/makegpr.adb b/gcc/ada/makegpr.adb
new file mode 100644
index 00000000000..a881bc30d49
--- /dev/null
+++ b/gcc/ada/makegpr.adb
@@ -0,0 +1,3574 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- M A K E G P R --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2004 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- --
+-- 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, 59 Temple Place - Suite 330, Boston, --
+-- MA 02111-1307, USA. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Ada.Command_Line; use Ada.Command_Line;
+with Ada.Strings.Fixed; use Ada.Strings.Fixed;
+with Ada.Text_IO; use Ada.Text_IO;
+with Ada.Unchecked_Deallocation;
+
+with Csets;
+with Gnatvsn;
+
+with GNAT.Directory_Operations; use GNAT.Directory_Operations;
+with GNAT.Dynamic_Tables;
+with GNAT.Expect; use GNAT.Expect;
+with GNAT.HTable;
+with GNAT.OS_Lib; use GNAT.OS_Lib;
+with GNAT.Regpat; use GNAT.Regpat;
+
+with Makeutl; use Makeutl;
+with MLib.Tgt; use MLib.Tgt;
+with Namet; use Namet;
+with Output; use Output;
+with Opt; use Opt;
+with Osint; use Osint;
+with Prj; use Prj;
+with Prj.Com; use Prj.Com;
+with Prj.Pars;
+with Prj.Util; use Prj.Util;
+with Snames; use Snames;
+with System;
+with System.Case_Util; use System.Case_Util;
+with Table;
+with Types; use Types;
+
+package body Makegpr is
+
+ Max_In_Archives : constant := 50;
+ -- The maximum number of arguments for a single invocation of the
+ -- Archive Indexer (ar).
+
+ Cpp_Linker : constant String := "c++linker";
+ -- The name of a linking script, built one the fly, when there are C++
+ -- sources and the C++ compiler is not g++.
+
+ No_Argument : constant Argument_List := (1 .. 0 => null);
+
+ FD : Process_Descriptor;
+ -- The process descriptor used when invoking a non GNU compiler with -M
+ -- and getting the output with GNAT.Expect.
+
+ Line_Matcher : constant Pattern_Matcher :=
+ Compile ("^.*?\n", Single_Line);
+ -- The pattern when using GNAT.Expect for the invocation of a non GNU
+ -- compiler with -M.
+
+ Name_Ide : Name_Id;
+ Name_Compiler_Command : Name_Id;
+ -- Names of package IDE and its attribute Compiler_Command.
+ -- Set up by Initialize.
+
+ Unique_Compile : Boolean := False;
+ -- True when switch -u is used on the command line
+
+ type Source_Index_Rec is record
+ Id : Other_Source_Id;
+ Found : Boolean := False;
+ end record;
+ -- Used as component of Source_Indexes, to check if an archive need to
+ -- be rebuilt.
+
+ type Source_Index_Array is array (Positive range <>) of Source_Index_Rec;
+ type Source_Indexes_Ref is access Source_Index_Array;
+
+ procedure Free is new Ada.Unchecked_Deallocation
+ (Source_Index_Array, Source_Indexes_Ref);
+
+ Initial_Source_Index_Count : constant Positive := 20;
+ Source_Indexes : Source_Indexes_Ref :=
+ new Source_Index_Array (1 .. Initial_Source_Index_Count);
+ -- A list of the Other_Source_Ids of a project file, with an indication
+ -- that they have been found in the archive dependency file.
+
+ Last_Source : Natural := 0;
+ -- The index of the last valid component of Source_Indexes
+
+ Compiler_Names : array (Programming_Language) of String_Access;
+ -- The names of the compilers to be used. Set up by Get_Compiler.
+ -- Used to display the commands spawned.
+
+ Compiler_Paths : array (Programming_Language) of String_Access;
+ -- The path names of the compiler to be used. Set up by Get_Compiler.
+ -- Used to spawn compiling/linking processes.
+
+ Compiler_Is_Gcc : array (Programming_Language) of Boolean;
+ -- An indication that a compiler is a GCC compiler, to be able to use
+ -- specific GCC switches.
+
+ Archive_Builder_Path : String_Access := null;
+ -- The path name of the archive builder (ar). To be used when spawning
+ -- ar commands.
+
+ Archive_Indexer_Path : String_Access := null;
+ -- The path name of the archive indexer (ranlib), if it exists.
+
+ Copyright_Output : Boolean := False;
+ Usage_Output : Boolean := False;
+ -- Flags to avoid multiple displays of the Copyright notice and of the
+ -- Usage.
+
+ Output_File_Name : String_Access := null;
+ -- The name given after a switch -o
+
+ Output_File_Name_Expected : Boolean := False;
+ -- True when last switch was -o
+
+ Project_File_Name : String_Access := null;
+ -- The name of the project file specified with switch -P
+
+ Project_File_Name_Expected : Boolean := False;
+ -- True when last switch was -P
+
+ Naming_String : aliased String := "naming";
+ Builder_String : aliased String := "builder";
+ Compiler_String : aliased String := "compiler";
+ Binder_String : aliased String := "binder";
+ Linker_String : aliased String := "linker";
+ -- Name of packages to be checked when parsing/processing project files
+
+ List_Of_Packages : aliased String_List :=
+ (Naming_String 'Access,
+ Builder_String 'Access,
+ Compiler_String 'Access,
+ Binder_String 'Access,
+ Linker_String 'Access);
+ Packages_To_Check : constant String_List_Access := List_Of_Packages'Access;
+ -- List of the packages to be checked when parsing/processing project
+ -- files.
+
+ Main_Project : Project_Id;
+ -- The project id of the main project
+
+ type Processor is (None, Linker, Compiler);
+ Current_Processor : Processor := None;
+ -- This variable changes when switches -*args are used
+
+ Current_Language : Programming_Language := Lang_Ada;
+ -- The compiler language to consider when Processor is Compiler
+
+ package Comp_Opts is new GNAT.Dynamic_Tables
+ (Table_Component_Type => String_Access,
+ Table_Index_Type => Integer,
+ Table_Low_Bound => 1,
+ Table_Initial => 20,
+ Table_Increment => 100);
+ Options : array (Programming_Language) of Comp_Opts.Instance;
+ -- Tables to store compiling options for the different compilers
+
+ package Linker_Options is new Table.Table
+ (Table_Component_Type => String_Access,
+ Table_Index_Type => Integer,
+ Table_Low_Bound => 1,
+ Table_Initial => 20,
+ Table_Increment => 100,
+ Table_Name => "Makegpr.Linker_Options");
+ -- Table to store the linking options
+
+ package Ada_Mains is new Table.Table
+ (Table_Component_Type => String_Access,
+ Table_Index_Type => Integer,
+ Table_Low_Bound => 1,
+ Table_Initial => 20,
+ Table_Increment => 100,
+ Table_Name => "Makegpr.Ada_Mains");
+ -- Table to store the Ada mains, either specified on the command line
+ -- or found in attribute Main of the main project file.
+
+ package Other_Mains is new Table.Table
+ (Table_Component_Type => Other_Source,
+ Table_Index_Type => Integer,
+ Table_Low_Bound => 1,
+ Table_Initial => 20,
+ Table_Increment => 100,
+ Table_Name => "Makegpr.Other_Mains");
+ -- Table to store the mains of languages other than Ada, either specified
+ -- on the command line or found in attribute Main of the main project file.
+
+ package Sources_Compiled is new GNAT.HTable.Simple_HTable
+ (Header_Num => Header_Num,
+ Element => Boolean,
+ No_Element => False,
+ Key => Name_Id,
+ Hash => Hash,
+ Equal => "=");
+
+ Initial_Argument_Count : constant Positive := 20;
+ type Boolean_Array is array (Positive range <>) of Boolean;
+ type Booleans is access Boolean_Array;
+
+ procedure Free is new Ada.Unchecked_Deallocation (Boolean_Array, Booleans);
+
+ Arguments : Argument_List_Access :=
+ new Argument_List (1 .. Initial_Argument_Count);
+ -- Used to store lists of arguments to be used when spawning a process
+
+ Arguments_Displayed : Booleans :=
+ new Boolean_Array (1 .. Initial_Argument_Count);
+ -- For each argument in Arguments, indicate if the argument should be
+ -- displayed when procedure Display_Command is called.
+
+ Last_Argument : Natural := 0;
+ -- Index of the last valid argument in Arguments
+
+ package Cache_Args is new Table.Table
+ (Table_Component_Type => String_Access,
+ Table_Index_Type => Integer,
+ Table_Low_Bound => 1,
+ Table_Initial => 200,
+ Table_Increment => 50,
+ Table_Name => "Makegpr.Cache_Args");
+ -- A table to cache arguments, to avoid multiple allocation of the same
+ -- strings. It is not possible to use a hash table, because String is
+ -- an unconstrained type.
+
+ -- Various switches used when spawning processes:
+
+ Dash_B_String : aliased String := "-B";
+ Dash_B : constant String_Access := Dash_B_String'Access;
+ Dash_c_String : aliased String := "-c";
+ Dash_c : constant String_Access := Dash_c_String'Access;
+ Dash_cargs_String : aliased String := "-cargs";
+ Dash_cargs : constant String_Access := Dash_cargs_String'Access;
+ Dash_f_String : aliased String := "-f";
+ Dash_f : constant String_Access := Dash_f_String'Access;
+ Dash_k_String : aliased String := "-k";
+ Dash_k : constant String_Access := Dash_k_String'Access;
+ Dash_largs_String : aliased String := "-largs";
+ Dash_largs : constant String_Access := Dash_largs_String'Access;
+ Dash_M_String : aliased String := "-M";
+ Dash_M : constant String_Access := Dash_M_String'Access;
+ Dash_margs_String : aliased String := "-margs";
+ Dash_margs : constant String_Access := Dash_margs_String'Access;
+ Dash_o_String : aliased String := "-o";
+ Dash_o : constant String_Access := Dash_o_String'Access;
+ Dash_P_String : aliased String := "-P";
+ Dash_P : constant String_Access := Dash_P_String'Access;
+ Dash_q_String : aliased String := "-q";
+ Dash_q : constant String_Access := Dash_q_String'Access;
+ Dash_u_String : aliased String := "-u";
+ Dash_u : constant String_Access := Dash_u_String'Access;
+ Dash_v_String : aliased String := "-v";
+ Dash_v : constant String_Access := Dash_v_String'Access;
+ Dash_vP1_String : aliased String := "-vP1";
+ Dash_vP1 : constant String_Access := Dash_vP1_String'Access;
+ Dash_vP2_String : aliased String := "-vP2";
+ Dash_vP2 : constant String_Access := Dash_vP2_String'Access;
+ Dash_x_String : aliased String := "-x";
+ Dash_x : constant String_Access := Dash_x_String'Access;
+ r_String : aliased String := "r";
+ r : constant String_Access := r_String'Access;
+
+ CPATH : constant String := "CPATH";
+ -- The environment variable to set when compiler is a GCC compiler
+ -- to indicate the include directory path.
+
+ Current_Include_Paths : array (Programming_Language) of String_Access;
+ -- A cache for the paths of included directories, to avoid setting
+ -- env var CPATH unnecessarily.
+
+ C_Plus_Plus_Is_Used : Boolean := False;
+ -- True when there are sources in C++
+
+ Link_Options_Switches : Argument_List_Access := null;
+ -- The link options coming from the attributes Linker'Linker_Options in
+ -- project files imported, directly or indirectly, by the main project.
+
+ Total_Number_Of_Errors : Natural := 0;
+ -- Used when Keep_Going is True (switch -k) to keep the total number
+ -- of compilation/linking errors, to report at the end of execution.
+
+ Error_Header : constant String := "*** ERROR: ";
+ -- The beginning of error message, when Keep_Going is True
+
+ Need_To_Relink : Boolean := False;
+ -- True when an executable of a language other than Ada need to be linked
+
+ Path_Option : String_Access;
+ -- The path option switch, when supported
+
+ package Lib_Path is new Table.Table
+ (Table_Component_Type => Character,
+ Table_Index_Type => Integer,
+ Table_Low_Bound => 1,
+ Table_Initial => 200,
+ Table_Increment => 50,
+ Table_Name => "Makegpr.Lib_Path");
+ -- A table to compute the path to put in the path option switch, when it
+ -- is supported.
+
+ procedure Add_Archives (For_Gnatmake : Boolean);
+ -- Add to Arguments the list of archives for linking an executable
+
+ procedure Add_Argument (Arg : String_Access; Display : Boolean);
+ procedure Add_Argument (Arg : String; Display : Boolean);
+ -- Add an argument to Arguments. Reallocate if necessary.
+
+ procedure Add_Arguments (Args : Argument_List; Display : Boolean);
+ -- Add a list of arguments to Arguments. Reallocate if necessary
+
+ procedure Add_Option (Arg : String);
+ -- Add a switch for the Ada, C or C++ compiler, or for the linker.
+ -- The table where this option is stored depends on the values of
+ -- Current_Processor and Current_Language.
+
+ procedure Add_Search_Directories
+ (Data : Project_Data; Language : Programming_Language);
+ -- Either add to the Arguments the necessary -I switches needed to
+ -- compile, or, when compiler is gcc/g++, set up the C*INCLUDE_PATH
+ -- environment variable, if necessary.
+
+ procedure Add_Source_Id (Id : Other_Source_Id);
+ -- Add a source id to Source_Indexes, with Found set to False
+
+ procedure Add_Switches
+ (Data : Project_Data;
+ Proc : Processor;
+ Language : Other_Programming_Language;
+ File_Name : Name_Id);
+ -- Add to Arguments the switches, if any, for a source (attribute Switches)
+ -- or language (attribute Default_Switches), coming from package Compiler
+ -- or Linker (depending on Proc) of a specified project file.
+
+ procedure Build_Archive (Project : Project_Id; Unconditionally : Boolean);
+ -- Build the archive for a specified project. If Unconditionally is
+ -- False, first check if the archive is up to date, and build it only
+ -- if it is not.
+
+ procedure Check_Compilation_Needed
+ (Source : Other_Source;
+ Need_To_Compile : out Boolean);
+ -- Check if a source of a language other than Ada needs to be compiled or
+ -- recompiled.
+
+ procedure Check_For_C_Plus_Plus;
+ -- Check if C++ is used in at least one project
+
+ procedure Compile
+ (Source_Id : Other_Source_Id;
+ Data : Project_Data;
+ Local_Errors : in out Boolean);
+
+ procedure Compile_Individual_Sources;
+ -- Compile the sources specified on the command line, when in
+ -- Unique_Compile mode.
+
+ procedure Compile_Link_With_Gnatmake (Mains_Specified : Boolean);
+ -- Compile/Link with gnatmake when there are Ada sources in the main
+ -- project. Arguments may already contain options to be used by
+ -- gnatmake. Used for both Ada mains and mains of other languages.
+ -- When Compile_Only is True, do not use the linking options
+
+ procedure Compile_Sources;
+ -- Compile the sources of languages other than Ada, if necessary
+
+ procedure Copyright;
+ -- Output the Copyright notice
+
+ procedure Create_Archive_Dependency_File
+ (Name : String;
+ First_Source : Other_Source_Id);
+ -- ??? needs comment
+
+ procedure Display_Command (Name : String; Path : String_Access);
+ -- Display the command for a spawned process, if in Verbose_Mode or
+ -- not in Quiet_Output.
+
+ procedure Get_Compiler (For_Language : Programming_Language);
+ -- Find the compiler name and path name for a specified programming
+ -- language, if not already done. Results are in the corresponding
+ -- elements of arrays Compiler_Names and Compiler_Paths. Name of compiler
+ -- is found in package IDE of the main project, or defaulted.
+ -- Fail if compiler cannot be found on the path. For the Ada language,
+ -- gnatmake, rather than the Ada compiler is returned.
+
+ procedure Get_Imported_Directories
+ (Project : Project_Id;
+ Data : in out Project_Data);
+ -- Find the necessary switches -I to be used when compiling sources
+ -- of languages other than Ada, in a specified project file. Cache the
+ -- result in component Imported_Directories_Switches of the project data.
+ -- For gcc/g++ compilers, get the value of the C*_INCLUDE_PATH, instead.
+
+ procedure Initialize;
+ -- Do the necessary package initialization and process the command line
+ -- arguments.
+
+ procedure Link_Executables;
+ -- Link executables
+
+ procedure Report_Error (S1 : String; S2 : String := ""; S3 : String := "");
+ -- Report an error. If Keep_Going is False, just call Osint.Fail.
+ -- If Keep_Going is True, display the error and increase the total number
+ -- of errors.
+
+ procedure Report_Total_Errors (Kind : String);
+ -- If Total_Number_Of_Errors is not zero, report it, and fail
+
+ procedure Scan_Arg (Arg : String);
+ -- Process one command line argument
+
+ function Strip_CR_LF (Text : String) return String;
+ -- Needs comment ???
+
+ procedure Usage;
+ -- Display the usage
+
+ ------------------
+ -- Add_Archives --
+ ------------------
+
+ procedure Add_Archives (For_Gnatmake : Boolean) is
+ Last_Arg : constant Natural := Last_Argument;
+ -- The position of the last argument before adding the archives.
+ -- Used to reverse the order of the arguments added when processing
+ -- the archives.
+
+ procedure Recursive_Add_Archives (Project : Project_Id);
+ -- Recursive procedure to add the archive of a project file, if any,
+ -- then call itself for the project imported.
+
+ ----------------------------
+ -- Recursive_Add_Archives --
+ ----------------------------
+
+ procedure Recursive_Add_Archives (Project : Project_Id) is
+ Data : Project_Data;
+ Imported : Project_List;
+ Prj : Project_Id;
+
+ begin
+ -- Nothing to do when there is no project specified
+
+ if Project /= No_Project then
+ Data := Projects.Table (Project);
+
+ -- Nothing to do if the project has already been processed
+
+ if not Data.Seen then
+
+ -- Mark the project as processed, to avoid processing it again
+
+ Projects.Table (Project).Seen := True;
+
+ Recursive_Add_Archives (Data.Extends);
+
+ Imported := Data.Imported_Projects;
+
+ -- Call itself recursively for all imported projects
+
+ while Imported /= Empty_Project_List loop
+ Prj := Project_Lists.Table (Imported).Project;
+
+ if Prj /= No_Project then
+ while Projects.Table (Prj).Extended_By /= No_Project loop
+ Prj := Projects.Table (Prj).Extended_By;
+ end loop;
+
+ Recursive_Add_Archives (Prj);
+ end if;
+
+ Imported := Project_Lists.Table (Imported).Next;
+ end loop;
+
+ -- If there is sources of language other than Ada in this
+ -- project, add the path of the archive to Arguments.
+
+ if Data.Sources_Present then
+ if Data.Library then
+
+ -- If it is a library project file, nothing to do if
+ -- gnatmake will be invoked, because gnatmake will take
+ -- care of it, even if the library is not an Ada library.
+
+ if not For_Gnatmake then
+ if Data.Library_Kind = Static then
+ Add_Argument
+ (Get_Name_String (Data.Library_Dir) &
+ Directory_Separator &
+ "lib" & Get_Name_String (Data.Library_Name) &
+ '.' & Archive_Ext,
+ Verbose_Mode);
+
+ else
+ -- As we first insert in the reverse order,
+ -- -L<dir> is put after -l<lib>
+
+ Add_Argument
+ ("-l" & Get_Name_String (Data.Library_Name),
+ Verbose_Mode);
+
+ Get_Name_String (Data.Library_Dir);
+
+ Add_Argument
+ ("-L" & Name_Buffer (1 .. Name_Len),
+ Verbose_Mode);
+
+ -- If there is a run path option, prepend this
+ -- directory to the library path. It is probable
+ -- that the order of the directories in the path
+ -- option is not important, but just in case
+ -- put the directories in the same order as the
+ -- libraries.
+
+ if Path_Option /= null then
+ -- If it is not the first directory, make room
+ -- at the beginning of the table, including
+ -- for a path separator.
+
+ if Lib_Path.Last > 0 then
+ declare
+ Increment : constant Positive :=
+ Name_Len + 1;
+ Prev_Last : constant Positive :=
+ Lib_Path.Last;
+
+ begin
+ Lib_Path.Set_Last (Prev_Last + Increment);
+
+ for Index in reverse 1 .. Prev_Last loop
+ Lib_Path.Table (Index + Increment) :=
+ Lib_Path.Table (Index);
+ end loop;
+
+ Lib_Path.Table (Increment) :=
+ Path_Separator;
+ end;
+
+ else
+ -- If it is the first directory, just set
+ -- Last to the length of the directory.
+
+ Lib_Path.Set_Last (Name_Len);
+ end if;
+
+ -- Put the directory at the beginning of the
+ -- table.
+
+ for Index in 1 .. Name_Len loop
+ Lib_Path.Table (Index) := Name_Buffer (Index);
+ end loop;
+ end if;
+ end if;
+ end if;
+
+ else
+ -- For a non library project, just add the path name of
+ -- the archive.
+
+ Add_Argument
+ (Get_Name_String (Data.Object_Directory) &
+ Directory_Separator &
+ "lib" & Get_Name_String (Data.Name) &
+ '.' & Archive_Ext,
+ Verbose_Mode);
+ end if;
+ end if;
+ end if;
+ end if;
+ end Recursive_Add_Archives;
+
+ begin
+ -- First, mark all projects as not processed
+
+ for Project in 1 .. Projects.Last loop
+ Projects.Table (Project).Seen := False;
+ end loop;
+
+ -- Take care of the run path option
+
+ if Path_Option = null then
+ Path_Option := MLib.Linker_Library_Path_Option;
+ end if;
+
+ Lib_Path.Set_Last (0);
+
+ -- Add archives in the reverse order
+
+ Recursive_Add_Archives (Main_Project);
+
+ -- And reverse the order
+
+ declare
+ First : Positive := Last_Arg + 1;
+ Last : Natural := Last_Argument;
+ Temp : String_Access;
+
+ begin
+ while First < Last loop
+ Temp := Arguments (First);
+ Arguments (First) := Arguments (Last);
+ Arguments (Last) := Temp;
+ First := First + 1;
+ Last := Last - 1;
+ end loop;
+ end;
+ end Add_Archives;
+
+ ------------------
+ -- Add_Argument --
+ ------------------
+
+ procedure Add_Argument (Arg : String_Access; Display : Boolean) is
+ begin
+ -- Nothing to do if no argument is specified or if argument is empty
+
+ if Arg /= null or else Arg'Length = 0 then
+
+ -- Reallocate arrays if necessary
+
+ if Last_Argument = Arguments'Last then
+ declare
+ New_Arguments : constant Argument_List_Access :=
+ new Argument_List
+ (1 .. Last_Argument +
+ Initial_Argument_Count);
+
+ New_Arguments_Displayed : constant Booleans :=
+ new Boolean_Array
+ (1 .. Last_Argument +
+ Initial_Argument_Count);
+
+ begin
+ New_Arguments (Arguments'Range) := Arguments.all;
+
+ -- To avoid deallocating the strings, nullify all components
+ -- of Arguments before calling Free.
+
+ Arguments.all := (others => null);
+
+ Free (Arguments);
+ Arguments := New_Arguments;
+
+ New_Arguments_Displayed (Arguments_Displayed'Range) :=
+ Arguments_Displayed.all;
+ Free (Arguments_Displayed);
+ Arguments_Displayed := New_Arguments_Displayed;
+ end;
+ end if;
+
+ -- Add the argument and its display indication
+
+ Last_Argument := Last_Argument + 1;
+ Arguments (Last_Argument) := Arg;
+ Arguments_Displayed (Last_Argument) := Display;
+ end if;
+ end Add_Argument;
+
+ procedure Add_Argument (Arg : String; Display : Boolean) is
+ Argument : String_Access := null;
+
+ begin
+ -- Nothing to do if argument is empty
+
+ if Arg'Length > 0 then
+ -- Check if the argument is already in the Cache_Args table.
+ -- If it is already there, reuse the allocated value.
+
+ for Index in 1 .. Cache_Args.Last loop
+ if Cache_Args.Table (Index).all = Arg then
+ Argument := Cache_Args.Table (Index);
+ exit;
+ end if;
+ end loop;
+
+ -- If the argument is not in the cache, create a new entry in the
+ -- cache.
+
+ if Argument = null then
+ Argument := new String'(Arg);
+ Cache_Args.Increment_Last;
+ Cache_Args.Table (Cache_Args.Last) := Argument;
+ end if;
+
+ -- And add the argument
+
+ Add_Argument (Argument, Display);
+ end if;
+ end Add_Argument;
+
+ -------------------
+ -- Add_Arguments --
+ -------------------
+
+ procedure Add_Arguments (Args : Argument_List; Display : Boolean) is
+ begin
+ -- Reallocate the arrays, if necessary
+
+ if Last_Argument + Args'Length > Arguments'Last then
+ declare
+ New_Arguments : constant Argument_List_Access :=
+ new Argument_List
+ (1 .. Last_Argument + Args'Length + Initial_Argument_Count);
+ New_Arguments_Displayed : constant Booleans :=
+ new Boolean_Array
+ (1 .. Last_Argument + Args'Length + Initial_Argument_Count);
+
+ begin
+ New_Arguments (1 .. Last_Argument) :=
+ Arguments (1 .. Last_Argument);
+
+ -- To avoid deallocating the strings, nullify all components
+ -- of Arguments before calling Free.
+
+ Arguments.all := (others => null);
+ Free (Arguments);
+
+ Arguments := New_Arguments;
+ New_Arguments_Displayed (1 .. Last_Argument) :=
+ Arguments_Displayed (1 .. Last_Argument);
+ Free (Arguments_Displayed);
+ Arguments_Displayed := New_Arguments_Displayed;
+ end;
+ end if;
+
+ -- Add the new arguments and the display indications
+
+ Arguments (Last_Argument + 1 .. Last_Argument + Args'Length) := Args;
+ Arguments_Displayed (Last_Argument + 1 .. Last_Argument + Args'Length) :=
+ (others => Display);
+ Last_Argument := Last_Argument + Args'Length;
+ end Add_Arguments;
+
+ ----------------
+ -- Add_Option --
+ ----------------
+
+ procedure Add_Option (Arg : String) is
+ Option : constant String_Access := new String'(Arg);
+
+ begin
+ case Current_Processor is
+ when None =>
+ null;
+
+ when Linker =>
+
+ -- Add option to the linker table
+
+ Linker_Options.Increment_Last;
+ Linker_Options.Table (Linker_Options.Last) := Option;
+
+ when Compiler =>
+
+ -- Add option to the compiler option table, depending on the
+ -- value of Current_Language.
+
+ Comp_Opts.Increment_Last (Options (Current_Language));
+ Options (Current_Language).Table
+ (Comp_Opts.Last (Options (Current_Language))) := Option;
+
+ end case;
+ end Add_Option;
+
+ -------------------
+ -- Add_Source_Id --
+ -------------------
+
+ procedure Add_Source_Id (Id : Other_Source_Id) is
+ begin
+ -- Reallocate the array, if necessary
+
+ if Last_Source = Source_Indexes'Last then
+ declare
+ New_Indexes : constant Source_Indexes_Ref :=
+ new Source_Index_Array
+ (1 .. Source_Indexes'Last +
+ Initial_Source_Index_Count);
+ begin
+ New_Indexes (Source_Indexes'Range) := Source_Indexes.all;
+ Free (Source_Indexes);
+ Source_Indexes := New_Indexes;
+ end;
+ end if;
+
+ Last_Source := Last_Source + 1;
+ Source_Indexes (Last_Source) := (Id, False);
+ end Add_Source_Id;
+
+ ----------------------------
+ -- Add_Search_Directories --
+ ----------------------------
+
+ procedure Add_Search_Directories
+ (Data : Project_Data;
+ Language : Programming_Language)
+ is
+ begin
+ -- If a GNU compiler is used, set the CPATH environment variable,
+ -- if it does not already has the correct value.
+
+ if Compiler_Is_Gcc (Language) then
+ if Current_Include_Paths (Language) /= Data.Include_Path then
+ Current_Include_Paths (Language) := Data.Include_Path;
+ Setenv (CPATH, Data.Include_Path.all);
+ end if;
+
+ else
+ Add_Arguments (Data.Imported_Directories_Switches.all, Verbose_Mode);
+ end if;
+ end Add_Search_Directories;
+
+ ------------------
+ -- Add_Switches --
+ ------------------
+
+ procedure Add_Switches
+ (Data : Project_Data;
+ Proc : Processor;
+ Language : Other_Programming_Language;
+ File_Name : Name_Id)
+ is
+ Switches : Variable_Value;
+ -- The switches, if any, for the file/language
+
+ Pkg : Package_Id;
+ -- The id of the package where to look for the switches
+
+ Defaults : Array_Element_Id;
+ -- The Default_Switches associative array
+
+ Switches_Array : Array_Element_Id;
+ -- The Switches associative array
+
+ Element_Id : String_List_Id;
+ Element : String_Element;
+
+ begin
+ -- First, choose the proper package
+
+ case Proc is
+ when None =>
+ raise Program_Error;
+
+ when Linker =>
+ Pkg := Value_Of (Name_Linker, Data.Decl.Packages);
+
+ when Compiler =>
+ Pkg := Value_Of (Name_Compiler, Data.Decl.Packages);
+ end case;
+
+ -- Get the Switches ("file name"), if they exist
+
+ Switches_Array := Prj.Util.Value_Of
+ (Name => Name_Switches,
+ In_Arrays =>
+ Packages.Table (Pkg).Decl.Arrays);
+
+ Switches :=
+ Prj.Util.Value_Of
+ (Index => File_Name,
+ Src_Index => 0,
+ In_Array => Switches_Array);
+
+ -- Otherwise, get the Default_Switches ("language"), if they exist
+
+ if Switches = Nil_Variable_Value then
+ Defaults := Prj.Util.Value_Of
+ (Name => Name_Default_Switches,
+ In_Arrays => Packages.Table (Pkg).Decl.Arrays);
+ Switches := Prj.Util.Value_Of
+ (Index => Lang_Name_Ids (Language),
+ Src_Index => 0,
+ In_Array => Defaults);
+ end if;
+
+ -- If there are switches, add them to Arguments
+
+ if Switches /= Nil_Variable_Value then
+ Element_Id := Switches.Values;
+
+ while Element_Id /= Nil_String loop
+ Element := String_Elements.Table (Element_Id);
+
+ if Element.Value /= No_Name then
+ Add_Argument (Get_Name_String (Element.Value), True);
+ end if;
+
+ Element_Id := Element.Next;
+ end loop;
+ end if;
+ end Add_Switches;
+
+ -------------------
+ -- Build_Archive --
+ -------------------
+
+ procedure Build_Archive (Project : Project_Id; Unconditionally : Boolean) is
+ Data : constant Project_Data := Projects.Table (Project);
+ Source_Id : Other_Source_Id;
+ Source : Other_Source;
+ Success : Boolean;
+
+ Archive_Name : constant String :=
+ "lib" & Get_Name_String (Data.Name) & '.' & Archive_Ext;
+ -- The name of the archive file for this project
+
+ Archive_Dep_Name : constant String :=
+ "lib" & Get_Name_String (Data.Name) & ".deps";
+ -- The name of the archive dependency file for this project
+
+ Need_To_Rebuild : Boolean := Unconditionally;
+ -- When True, archive will be rebuilt
+
+ File : Prj.Util.Text_File;
+
+ Object_Name : Name_Id;
+ Time_Stamp : Time_Stamp_Type;
+
+ Saved_Last_Argument : Natural;
+
+ begin
+ -- First, make sure that the archive builder (ar) is on the path
+
+ if Archive_Builder_Path = null then
+ Archive_Builder_Path := Locate_Exec_On_Path (Archive_Builder);
+
+ if Archive_Builder_Path = null then
+ Osint.Fail
+ ("unable to locate archive builder """,
+ Archive_Builder,
+ """");
+ end if;
+
+ -- If there is an archive indexer (ranlib), try to locate it on the
+ -- path. Don't fail if it is not found.
+
+ if Archive_Indexer /= "" then
+ Archive_Indexer_Path := Locate_Exec_On_Path (Archive_Indexer);
+ end if;
+ end if;
+
+ -- If Unconditionally is False, check if the archive need to be built
+
+ if not Need_To_Rebuild then
+ if Verbose_Mode then
+ Write_Str (" Checking ");
+ Write_Line (Archive_Name);
+ end if;
+
+ -- If the archive does not exist, of course it needs to be built
+
+ if not Is_Regular_File (Archive_Name) then
+ Need_To_Rebuild := True;
+
+ if Verbose_Mode then
+ Write_Line (" -> archive does not exist");
+ end if;
+
+ -- Archive does exist
+
+ else
+ -- Check the archive dependency file
+
+ Open (File, Archive_Dep_Name);
+
+ -- If the archive dependency file does not exist, we need to
+ -- to rebuild the archive and to create its dependency file.
+
+ if not Is_Valid (File) then
+ Need_To_Rebuild := True;
+
+ if Verbose_Mode then
+ Write_Str (" -> archive dependency file ");
+ Write_Str (Archive_Dep_Name);
+ Write_Line (" does not exist");
+ end if;
+
+ else
+ -- Put all sources of language other than Ada in
+ -- Source_Indexes.
+
+ Last_Source := 0;
+ Source_Id := Data.First_Other_Source;
+
+ while Source_Id /= No_Other_Source loop
+ Add_Source_Id (Source_Id);
+ Source_Id := Other_Sources.Table (Source_Id).Next;
+ end loop;
+
+ -- Read the dependency file, line by line
+
+ while not End_Of_File (File) loop
+ Get_Line (File, Name_Buffer, Name_Len);
+
+ -- First line is the name of an object file
+
+ Object_Name := Name_Find;
+ Source_Id := No_Other_Source;
+
+ -- Check if this object file is for a source of this project
+
+ for S in 1 .. Last_Source loop
+ if (not Source_Indexes (S).Found) and then
+ Other_Sources.Table
+ (Source_Indexes (S).Id).Object_Name =
+ Object_Name
+ then
+ -- We have found the object file: get the source
+ -- data, and mark it as found.
+
+ Source_Id := Source_Indexes (S).Id;
+ Source := Other_Sources.Table (Source_Id);
+ Source_Indexes (S).Found := True;
+ exit;
+ end if;
+ end loop;
+
+ -- If it is not for a source of this project, then the
+ -- archive needs to be rebuilt.
+
+ if Source_Id = No_Other_Source then
+ Need_To_Rebuild := True;
+ if Verbose_Mode then
+ Write_Str (" -> ");
+ Write_Str (Get_Name_String (Object_Name));
+ Write_Line (" is not an object of the project");
+ end if;
+
+ exit;
+ end if;
+
+ -- The second line is the time stamp of the object file.
+ -- If there is no next line, then the dependency file is
+ -- truncated, and the archive need to be rebuilt.
+
+ if End_Of_File (File) then
+ Need_To_Rebuild := True;
+
+ if Verbose_Mode then
+ Write_Str (" -> archive dependency file ");
+ Write_Line (" is truncated");
+ end if;
+
+ exit;
+ end if;
+
+ Get_Line (File, Name_Buffer, Name_Len);
+
+ -- If the line has the wrong number of character, then
+ -- the dependency file is incorrectly formatted, and the
+ -- archive needs to be rebuilt.
+
+ if Name_Len /= Time_Stamp_Length then
+ Need_To_Rebuild := True;
+
+ if Verbose_Mode then
+ Write_Str (" -> archive dependency file ");
+ Write_Line (" is incorrectly formatted (time stamp)");
+ end if;
+
+ exit;
+ end if;
+
+ Time_Stamp := Time_Stamp_Type (Name_Buffer (1 .. Name_Len));
+
+ -- If the time stamp in the dependency file is different
+ -- from the time stamp of the object file, then the archive
+ -- needs to be rebuilt.
+
+ if Time_Stamp /= Source.Object_TS then
+ Need_To_Rebuild := True;
+
+ if Verbose_Mode then
+ Write_Str (" -> time stamp of ");
+ Write_Str (Get_Name_String (Object_Name));
+ Write_Str (" is incorrect in the archive");
+ Write_Line (" dependency file");
+ end if;
+
+ exit;
+ end if;
+ end loop;
+
+ Close (File);
+
+ if not Need_To_Rebuild then
+
+ -- Now, check if all object files of the project have been
+ -- accounted for. If any of them is not in the dependency
+ -- file, the archive needs to be rebuilt.
+
+ for Index in 1 .. Last_Source loop
+ if not Source_Indexes (Index).Found then
+ Need_To_Rebuild := True;
+
+ if Verbose_Mode then
+ Source_Id := Source_Indexes (Index).Id;
+ Source := Other_Sources.Table (Source_Id);
+ Write_Str (" -> ");
+ Write_Str (Get_Name_String (Source.Object_Name));
+ Write_Str (" is not in the archive ");
+ Write_Line ("dependency file");
+ end if;
+
+ exit;
+ end if;
+ end loop;
+ end if;
+
+ if (not Need_To_Rebuild) and Verbose_Mode then
+ Write_Line (" -> up to date");
+ end if;
+ end if;
+ end if;
+ end if;
+
+ -- Build the archive if necessary
+
+ if Need_To_Rebuild then
+
+ -- If an archive is built, then linking will need to occur
+ -- unconditionally.
+
+ Need_To_Relink := True;
+
+ Last_Argument := 0;
+
+ -- If it is a library project file, we need to build the library
+ -- in the library directory.
+
+ if Data.Library then
+
+ -- If there are sources in Ada, then gnatmake will build the
+ -- library, so nothing to do.
+
+ if not Data.Languages (Lang_Ada) then
+
+ -- Get all the object files of the project
+
+ Source_Id := Data.First_Other_Source;
+
+ while Source_Id /= No_Other_Source loop
+ Source := Other_Sources.Table (Source_Id);
+ Add_Argument
+ (Get_Name_String (Source.Object_Name), Verbose_Mode);
+ Source_Id := Source.Next;
+ end loop;
+
+ -- If it is a library, it need to be built it the same way
+ -- Ada libraries are built.
+
+ if Data.Library_Kind = Static then
+ MLib.Build_Library
+ (Ofiles => Arguments (1 .. Last_Argument),
+ Afiles => No_Argument,
+ Output_File => Get_Name_String (Data.Library_Name),
+ Output_Dir => Get_Name_String (Data.Library_Dir));
+
+ else
+ MLib.Tgt.Build_Dynamic_Library
+ (Ofiles => Arguments (1 .. Last_Argument),
+ Foreign => Arguments (1 .. Last_Argument),
+ Afiles => No_Argument,
+ Options => No_Argument,
+ Interfaces => No_Argument,
+ Lib_Filename => Get_Name_String (Data.Library_Name),
+ Lib_Dir => Get_Name_String (Data.Library_Dir),
+ Symbol_Data => No_Symbols,
+ Driver_Name => No_Name,
+ Lib_Address => "",
+ Lib_Version => "",
+ Relocatable => Data.Library_Kind = Relocatable,
+ Auto_Init => False);
+ end if;
+ end if;
+
+ -- Create fake empty archive, so we can check its time stamp later
+
+ declare
+ Archive : Ada.Text_IO.File_Type;
+ use Ada.Text_IO;
+ begin
+ Create (Archive, Out_File, Archive_Name);
+ Close (Archive);
+ end;
+
+ Create_Archive_Dependency_File
+ (Archive_Dep_Name, Data.First_Other_Source);
+
+ return;
+ end if;
+
+ -- Start with the options found in MLib.Tgt (usually just "rc")
+
+ Add_Arguments (Archive_Builder_Options.all, True);
+
+ -- Followed by the archive name
+
+ Add_Argument (Archive_Name, True);
+
+ -- Followed by all the object files of the project
+
+ Source_Id := Data.First_Other_Source;
+
+ while Source_Id /= No_Other_Source loop
+ Source := Other_Sources.Table (Source_Id);
+ Add_Argument (Get_Name_String (Source.Object_Name), Verbose_Mode);
+ Source_Id := Source.Next;
+ end loop;
+
+ -- Spawn the archive builder (ar)
+
+ Saved_Last_Argument := Last_Argument;
+
+ Last_Argument := Max_In_Archives;
+
+ loop
+ if Last_Argument > Saved_Last_Argument then
+ Last_Argument := Saved_Last_Argument;
+ end if;
+
+ Display_Command (Archive_Builder, Archive_Builder_Path);
+
+ Spawn
+ (Archive_Builder_Path.all,
+ Arguments (1 .. Last_Argument),
+ Success);
+
+ exit when not Success;
+
+ exit when Last_Argument = Saved_Last_Argument;
+
+ Arguments (1) := r;
+ Arguments (3 .. Saved_Last_Argument - Last_Argument + 2) :=
+ Arguments (Last_Argument + 1 .. Saved_Last_Argument);
+ Saved_Last_Argument := Saved_Last_Argument - Last_Argument + 2;
+ end loop;
+
+ if Success then
+
+ -- If the archive was built, run the archive indexer (ranlib),
+ -- if there is one.
+
+ if Archive_Indexer_Path /= null then
+ Last_Argument := 0;
+ Add_Argument (Archive_Name, True);
+
+ Display_Command (Archive_Indexer, Archive_Indexer_Path);
+
+ Spawn (Archive_Indexer_Path.all, Arguments (1 .. 1), Success);
+
+ if not Success then
+
+ -- Running ranlib failed, delete the dependency file,
+ -- if it exists.
+
+ if Is_Regular_File (Archive_Dep_Name) then
+ Delete_File (Archive_Dep_Name, Success);
+ end if;
+
+ -- And report the error
+
+ Report_Error
+ ("running" & Archive_Indexer & " for project """,
+ Get_Name_String (Data.Name),
+ """ failed");
+ return;
+ end if;
+ end if;
+
+ -- The archive was correctly built, create its dependency file
+
+ Create_Archive_Dependency_File
+ (Archive_Dep_Name, Data.First_Other_Source);
+
+ else
+ -- Building the archive failed, delete the dependency file, if
+ -- one exists.
+
+ if Is_Regular_File (Archive_Dep_Name) then
+ Delete_File (Archive_Dep_Name, Success);
+ end if;
+
+ -- And report the error
+
+ Report_Error
+ ("building archive for project """,
+ Get_Name_String (Data.Name),
+ """ failed");
+ end if;
+ end if;
+ end Build_Archive;
+
+ ------------------------------
+ -- Check_Compilation_Needed --
+ ------------------------------
+
+ procedure Check_Compilation_Needed
+ (Source : Other_Source;
+ Need_To_Compile : out Boolean)
+ is
+ Source_Name : constant String := Get_Name_String (Source.File_Name);
+ Source_Path : constant String := Get_Name_String (Source.Path_Name);
+ Object_Name : constant String := Get_Name_String (Source.Object_Name);
+ Dep_Name : constant String := Get_Name_String (Source.Dep_Name);
+
+ Source_In_Dependencies : Boolean := False;
+ -- Set to True if the source was find in the dependency file of its
+ -- object file.
+
+ Dep_File : Prj.Util.Text_File;
+ Start : Natural;
+ Finish : Natural;
+
+ begin
+ -- Assume the worst, so that statement "return;" may be used if there
+ -- is any problem.
+
+ Need_To_Compile := True;
+
+ if Verbose_Mode then
+ Write_Str (" Checking ");
+ Write_Str (Source_Name);
+ Write_Line (" ... ");
+ end if;
+
+ -- If the object file does not exist, of course the source need to be
+ -- compiled.
+
+ if Source.Object_TS = Empty_Time_Stamp then
+ if Verbose_Mode then
+ Write_Str (" -> object file ");
+ Write_Str (Object_Name);
+ Write_Line (" does not exist");
+ end if;
+
+ return;
+ end if;
+
+ -- If the object file has been created before the last modification
+ -- of the source, the source need to be recompiled.
+
+ if Source.Object_TS < Source.Source_TS then
+ if Verbose_Mode then
+ Write_Str (" -> object file ");
+ Write_Str (Object_Name);
+ Write_Line (" has time stamp earlier than source");
+ end if;
+
+ return;
+ end if;
+
+ -- If there is no dependency file, then the source needs to be
+ -- recompiled and the dependency file need to be created.
+
+ if Source.Dep_TS = Empty_Time_Stamp then
+ if Verbose_Mode then
+ Write_Str (" -> dependency file ");
+ Write_Str (Dep_Name);
+ Write_Line (" does not exist");
+ end if;
+
+ return;
+ end if;
+
+ -- The source needs to be recompiled if the source has been modified
+ -- after the dependency file has been created.
+
+ if Source.Dep_TS < Source.Source_TS then
+ if Verbose_Mode then
+ Write_Str (" -> dependency file ");
+ Write_Str (Dep_Name);
+ Write_Line (" has time stamp earlier than source");
+ end if;
+
+ return;
+ end if;
+
+ -- Look for all dependencies
+
+ Open (Dep_File, Dep_Name);
+
+ -- If dependency file cannot be open, we need to recompile the source
+
+ if not Is_Valid (Dep_File) then
+ if Verbose_Mode then
+ Write_Str (" -> could not open dependency file ");
+ Write_Line (Dep_Name);
+ end if;
+
+ return;
+ end if;
+
+ declare
+ End_Of_File_Reached : Boolean := False;
+
+ begin
+ loop
+ if End_Of_File (Dep_File) then
+ End_Of_File_Reached := True;
+ exit;
+ end if;
+
+ Get_Line (Dep_File, Name_Buffer, Name_Len);
+
+ exit when Name_Len > 0 and then Name_Buffer (1) /= '#';
+ end loop;
+
+ -- If dependency file contains only empty lines or comments, then
+ -- the dependencies are unknown, and the source needs to be
+ -- recompiled.
+
+ if End_Of_File_Reached then
+ if Verbose_Mode then
+ Write_Str (" -> dependency file ");
+ Write_Str (Dep_Name);
+ Write_Line (" is empty");
+ end if;
+
+ Close (Dep_File);
+ return;
+ end if;
+ end;
+
+ Start := 1;
+ Finish := Index (Name_Buffer (1 .. Name_Len), ": ");
+
+ -- The first line must start with the name of the object file, followed
+ -- by a colon (:).
+
+ if Finish = 0 or else Name_Buffer (1 .. Finish - 1) /= Object_Name then
+ if Verbose_Mode then
+ Write_Str (" -> dependency file ");
+ Write_Str (Dep_Name);
+ Write_Line (" has wrong format");
+ end if;
+
+ Close (Dep_File);
+ return;
+
+ else
+ Start := Finish + 2;
+
+ -- Process each line
+
+ Line_Loop : loop
+ declare
+ Line : constant String := Name_Buffer (1 .. Name_Len);
+ Last : constant Natural := Name_Len;
+
+ begin
+ Name_Loop : loop
+
+ -- Find the beginning of the next source path name
+
+ while Start < Last and then Line (Start) = ' ' loop
+ Start := Start + 1;
+ end loop;
+
+ -- Go to next line when there is a continuation character \
+ -- at the end of the line.
+
+ exit Name_Loop when Start = Last
+ and then Line (Start) = '\';
+
+ -- We should not be at the end of the line, without
+ -- a continuation character \.
+
+ if Start = Last then
+ if Verbose_Mode then
+ Write_Str (" -> dependency file ");
+ Write_Str (Dep_Name);
+ Write_Line (" has wrong format");
+ end if;
+
+ Close (Dep_File);
+ return;
+ end if;
+
+ -- Look for the end of the source path name
+
+ Finish := Start;
+ while Finish < Last and then Line (Finish + 1) /= ' ' loop
+ Finish := Finish + 1;
+ end loop;
+
+ -- Check this source
+
+ declare
+ Src_Name : constant String :=
+ Normalize_Pathname
+ (Name => Line (Start .. Finish),
+ Case_Sensitive => False);
+ Src_TS : Time_Stamp_Type;
+
+ begin
+ -- If it is original source, set Source_In_Dependencies
+
+ if Src_Name = Source_Path then
+ Source_In_Dependencies := True;
+ end if;
+
+ Name_Len := 0;
+ Add_Str_To_Name_Buffer (Src_Name);
+ Src_TS := File_Stamp (Name_Find);
+
+ -- If the source does not exist, we need to recompile
+
+ if Src_TS = Empty_Time_Stamp then
+ if Verbose_Mode then
+ Write_Str (" -> source ");
+ Write_Str (Src_Name);
+ Write_Line (" does not exist");
+ end if;
+
+ Close (Dep_File);
+ return;
+
+ -- If the source has been modified after the object file,
+ -- we need to recompile.
+
+ elsif Src_TS > Source.Object_TS then
+ if Verbose_Mode then
+ Write_Str (" -> source ");
+ Write_Str (Src_Name);
+ Write_Line
+ (" has time stamp later than object file");
+ end if;
+
+ Close (Dep_File);
+ return;
+ end if;
+ end;
+
+ -- If the source path name ends the line, we are done.
+
+ exit Line_Loop when Finish = Last;
+
+ -- Go get the next source on the line
+
+ Start := Finish + 1;
+ end loop Name_Loop;
+ end;
+
+ -- If we are here, we had a continuation character \ at the end
+ -- of the line, so we continue with the next line.
+
+ Get_Line (Dep_File, Name_Buffer, Name_Len);
+ Start := 1;
+ end loop Line_Loop;
+ end if;
+
+ Close (Dep_File);
+
+ -- If the original sources were not in the dependency file, then we
+ -- need to recompile. It may mean that we are using a different source
+ -- (different variant) for this object file.
+
+ if not Source_In_Dependencies then
+ if Verbose_Mode then
+ Write_Str (" -> source ");
+ Write_Str (Source_Path);
+ Write_Line (" is not in the dependencies");
+ end if;
+
+ return;
+ end if;
+
+ -- If we are here, then everything is OK, and we don't need
+ -- to recompile.
+
+ if Verbose_Mode then
+ Write_Line (" -> up to date");
+ end if;
+
+ Need_To_Compile := False;
+ end Check_Compilation_Needed;
+
+ ---------------------------
+ -- Check_For_C_Plus_Plus --
+ ---------------------------
+
+ procedure Check_For_C_Plus_Plus is
+ begin
+ C_Plus_Plus_Is_Used := False;
+
+ for Project in 1 .. Projects.Last loop
+ if Projects.Table (Project).Languages (Lang_C_Plus_Plus) then
+ C_Plus_Plus_Is_Used := True;
+ exit;
+ end if;
+ end loop;
+ end Check_For_C_Plus_Plus;
+
+ -------------
+ -- Compile --
+ -------------
+
+ procedure Compile
+ (Source_Id : Other_Source_Id;
+ Data : in Project_Data;
+ Local_Errors : in out Boolean)
+ is
+ Source : Other_Source := Other_Sources.Table (Source_Id);
+ Success : Boolean;
+
+ begin
+ -- If the compiler is not know yet, get its path name
+
+ if Compiler_Names (Source.Language) = null then
+ Get_Compiler (Source.Language);
+ end if;
+
+ -- For non GCC compilers, get the dependency file, calling first the
+ -- compiler with the switch -M.
+
+ if not Compiler_Is_Gcc (Source.Language) then
+ Last_Argument := 0;
+
+ -- Add the source name, preceded by -M
+
+ Add_Argument (Dash_M, True);
+ Add_Argument (Get_Name_String (Source.Path_Name), True);
+
+ -- Add the compiling switches for this source found in
+ -- package Compiler of the project file, if they exist.
+
+ Add_Switches
+ (Data, Compiler, Source.Language, Source.File_Name);
+
+ -- Add the compiling switches for the language specified
+ -- on the command line, if any.
+
+ for
+ J in 1 .. Comp_Opts.Last (Options (Source.Language))
+ loop
+ Add_Argument (Options (Source.Language).Table (J), True);
+ end loop;
+
+ -- Finally, add the imported directory switches for this
+ -- project file.
+
+ Add_Search_Directories (Data, Source.Language);
+
+ -- And invoke the compiler using GNAT.Expect
+
+ Display_Command
+ (Compiler_Names (Source.Language).all,
+ Compiler_Paths (Source.Language));
+
+ begin
+ Non_Blocking_Spawn
+ (FD,
+ Compiler_Paths (Source.Language).all,
+ Arguments (1 .. Last_Argument),
+ Buffer_Size => 0,
+ Err_To_Out => True);
+
+ declare
+ Dep_File : Ada.Text_IO.File_Type;
+ Result : Expect_Match;
+ Status : Integer;
+
+ begin
+ -- Create the dependency file
+
+ Create (Dep_File, Out_File, Get_Name_String (Source.Dep_Name));
+
+ loop
+ Expect (FD, Result, Line_Matcher);
+
+ exit when Result = Expect_Timeout;
+
+ declare
+ S : constant String := Strip_CR_LF (Expect_Out (FD));
+
+ begin
+ -- Each line of the output is put in the dependency
+ -- file, including errors. If there are errors, the
+ -- syntax of the dependency file will be incorrect and
+ -- recompilation will occur automatically the next time
+ -- the dependencies are checked.
+
+ Put_Line (Dep_File, S);
+ end;
+ end loop;
+
+ -- If we are here, it means we had a timeout, so the
+ -- dependency file may be incomplete. It is safer to
+ -- delete it, otherwise the dependencies may be wrong.
+
+ Close (FD, Status);
+ Close (Dep_File);
+ Delete_File (Get_Name_String (Source.Dep_Name), Success);
+
+ exception
+ when Process_Died =>
+
+ -- This is the normal outcome. Just close the file
+
+ Close (FD, Status);
+ Close (Dep_File);
+
+ when others =>
+
+ -- Something wrong happened. It is safer to delete the
+ -- dependency file, otherwise the dependencies may be wrong.
+
+ Close (FD, Status);
+
+ if Is_Open (Dep_File) then
+ Close (Dep_File);
+ end if;
+
+ Delete_File (Get_Name_String (Source.Dep_Name), Success);
+ end;
+
+ exception
+ -- If we cannot spawn the compiler, then the dependencies are
+ -- not updated. It is safer then to delete the dependency file,
+ -- otherwise the dependencies may be wrong.
+
+ when Invalid_Process =>
+ Delete_File (Get_Name_String (Source.Dep_Name), Success);
+ end;
+ end if;
+
+ Last_Argument := 0;
+
+ -- For GCC compilers, make sure the language is always specified to
+ -- to the GCC driver, in case the extension is not recognized by the
+ -- GCC driver as a source of the language.
+
+ if Compiler_Is_Gcc (Source.Language) then
+ Add_Argument (Dash_x, Verbose_Mode);
+ Add_Argument
+ (Lang_Names (Source.Language), Verbose_Mode);
+ end if;
+
+ -- Specify the source to be compiled
+
+ Add_Argument (Dash_c, True);
+ Add_Argument (Get_Name_String (Source.Path_Name), True);
+
+ -- If non static library project, compile with the PIC option if there
+ -- is one (when there is no PIC option, function MLib.Tgt.PIC_Option
+ -- returns an empty string, and Add_Argument with an empty string has
+ -- no effect).
+
+ if Data.Library and then Data.Library_Kind /= Static then
+ Add_Argument (PIC_Option, True);
+ end if;
+
+ -- Indicate the name of the object
+
+ Add_Argument (Dash_o, True);
+ Add_Argument (Get_Name_String (Source.Object_Name), True);
+
+ -- When compiler is GCC, use the magic switch that creates
+ -- the dependency file in the correct format.
+
+ if Compiler_Is_Gcc (Source.Language) then
+ Add_Argument
+ ("-Wp,-MD," & Get_Name_String (Source.Dep_Name),
+ Verbose_Mode);
+ end if;
+
+ -- Add the compiling switches for this source found in
+ -- package Compiler of the project file, if they exist.
+
+ Add_Switches
+ (Data, Compiler, Source.Language, Source.File_Name);
+
+ -- Add the compiling switches for the language specified
+ -- on the command line, if any.
+
+ for
+ J in 1 .. Comp_Opts.Last (Options (Source.Language))
+ loop
+ Add_Argument (Options (Source.Language).Table (J), True);
+ end loop;
+
+ -- Finally, add the imported directory switches for this
+ -- project file (or, for gcc compilers, set up the CPATH env var
+ -- if needed).
+
+ Add_Search_Directories (Data, Source.Language);
+
+ -- And invoke the compiler
+
+ Display_Command
+ (Compiler_Names (Source.Language).all,
+ Compiler_Paths (Source.Language));
+
+ Spawn
+ (Compiler_Paths (Source.Language).all,
+ Arguments (1 .. Last_Argument),
+ Success);
+
+ if Success then
+
+ -- Compilation was successful, update the time stamp
+ -- of the object file.
+
+ Source.Object_TS := File_Stamp (Source.Object_Name);
+
+ -- Do some sanity checks
+
+ if Source.Object_TS = Empty_Time_Stamp then
+ Local_Errors := True;
+ Report_Error
+ ("object file ",
+ Get_Name_String (Source.Object_Name),
+ " has not been created");
+
+ elsif Source.Object_TS < Source.Source_TS then
+ Local_Errors := True;
+ Report_Error
+ ("object file ",
+ Get_Name_String (Source.Object_Name),
+ " has not been modified");
+
+ else
+ -- Everything looks fine, update the Other_Sources table
+
+ Other_Sources.Table (Source_Id) := Source;
+ end if;
+
+ else
+ Local_Errors := True;
+ Report_Error
+ ("compilation of ",
+ Get_Name_String (Source.Path_Name),
+ " failed");
+ end if;
+ end Compile;
+
+ --------------------------------
+ -- Compile_Individual_Sources --
+ --------------------------------
+
+ procedure Compile_Individual_Sources is
+ Data : Project_Data := Projects.Table (Main_Project);
+ Source_Id : Other_Source_Id;
+ Source : Other_Source;
+ Source_Name : Name_Id;
+ Project_Name : String := Get_Name_String (Data.Name);
+ Dummy : Boolean := False;
+
+ Ada_Is_A_Language : constant Boolean := Data.Languages (Lang_Ada);
+
+ begin
+ Ada_Mains.Init;
+
+ To_Mixed (Project_Name);
+
+ Compile_Only := True;
+
+ Get_Imported_Directories (Main_Project, Data);
+ Projects.Table (Main_Project) := Data;
+
+ if not Data.Sources_Present then
+ if Ada_Is_A_Language then
+ Mains.Reset;
+
+ loop
+ declare
+ Main : constant String := Mains.Next_Main;
+ begin
+ exit when Main'Length = 0;
+ Ada_Mains.Increment_Last;
+ Ada_Mains.Table (Ada_Mains.Last) := new String'(Main);
+ end;
+ end loop;
+
+ else
+ Osint.Fail
+ ("project ", Project_Name, " contains no source");
+ end if;
+
+ else
+ Mains.Reset;
+
+ loop
+ declare
+ Main : constant String := Mains.Next_Main;
+ begin
+ Name_Len := Main'Length;
+ exit when Name_Len = 0;
+ Name_Buffer (1 .. Name_Len) := Main;
+ Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
+ Source_Name := Name_Find;
+
+ if not Sources_Compiled.Get (Source_Name) then
+ Sources_Compiled.Set (Source_Name, True);
+
+ Source_Id := Data.First_Other_Source;
+
+ while Source_Id /= No_Other_Source loop
+ Source := Other_Sources.Table (Source_Id);
+ exit when Source.File_Name = Source_Name;
+ Source_Id := Source.Next;
+ end loop;
+
+ if Source_Id = No_Other_Source then
+ if Ada_Is_A_Language then
+ Ada_Mains.Increment_Last;
+ Ada_Mains.Table (Ada_Mains.Last) :=
+ new String'(Main);
+
+ else
+ Report_Error
+ (Main,
+ " is not a valid source of project ",
+ Project_Name);
+ end if;
+
+ else
+ Compile (Source_Id, Data, Dummy);
+ end if;
+ end if;
+ end;
+ end loop;
+ end if;
+
+ if Ada_Mains.Last > 0 then
+
+ -- Invoke gnatmake for all sources that are not of a non Ada language
+
+ Last_Argument := 0;
+
+ Add_Argument (Dash_u, True);
+
+ for Index in 1 .. Ada_Mains.Last loop
+ Add_Argument (Ada_Mains.Table (Index), True);
+ end loop;
+
+ Compile_Link_With_Gnatmake (Mains_Specified => False);
+ end if;
+ end Compile_Individual_Sources;
+
+ --------------------------------
+ -- Compile_Link_With_Gnatmake --
+ --------------------------------
+
+ procedure Compile_Link_With_Gnatmake (Mains_Specified : Boolean) is
+ Data : constant Project_Data := Projects.Table (Main_Project);
+ Success : Boolean;
+
+ begin
+ -- Array Arguments may already contain some arguments, so we don't
+ -- set Last_Argument to 0.
+
+ -- Get the gnatmake to invoke
+
+ Get_Compiler (Lang_Ada);
+
+ -- Specify the project file
+
+ Add_Argument (Dash_P, True);
+ Add_Argument (Get_Name_String (Data.Path_Name), True);
+
+ -- If Mains_Specified is True, find the mains in package Mains
+
+ if Mains_Specified then
+ Mains.Reset;
+
+ loop
+ declare
+ Main : constant String := Mains.Next_Main;
+ begin
+ exit when Main'Length = 0;
+ Add_Argument (Main, True);
+ end;
+ end loop;
+ end if;
+
+ -- Specify output file name, if any was specified on the command line
+
+ if Output_File_Name /= null then
+ Add_Argument (Dash_o, True);
+ Add_Argument (Output_File_Name, True);
+ end if;
+
+ -- Transmit to gnatmake some switches
+
+ -- -c
+
+ if Compile_Only then
+ Add_Argument (Dash_c, True);
+ end if;
+
+ -- -k
+
+ if Keep_Going then
+ Add_Argument (Dash_k, True);
+ end if;
+
+ -- -f
+
+ if Force_Compilations then
+ Add_Argument (Dash_f, True);
+ end if;
+
+ -- -v
+
+ if Verbose_Mode then
+ Add_Argument (Dash_v, True);
+ end if;
+
+ -- -q
+
+ if Quiet_Output then
+ Add_Argument (Dash_q, True);
+ end if;
+
+ -- -vP1 and -vP2
+
+ case Current_Verbosity is
+ when Default =>
+ null;
+
+ when Medium =>
+ Add_Argument (Dash_vP1, True);
+
+ when High =>
+ Add_Argument (Dash_vP2, True);
+ end case;
+
+ -- If there are compiling options for Ada, transmit them to gnatmake
+
+ if Comp_Opts.Last (Options (Lang_Ada)) /= 0 then
+ Add_Argument (Dash_cargs, True);
+
+ for Arg in 1 .. Comp_Opts.Last (Options (Lang_Ada)) loop
+ Add_Argument (Options (Lang_Ada).Table (Arg), True);
+ end loop;
+ end if;
+
+ if not Compile_Only then
+ -- If there are linking options from the command line, transmit them
+ -- to gnatmake.
+
+ if Linker_Options.Last /= 0 then
+ Add_Argument (Dash_largs, True);
+
+ for Arg in 1 .. Linker_Options.Last loop
+ Add_Argument (Linker_Options.Table (Arg), True);
+ end loop;
+
+ else
+ Add_Argument (Dash_largs, Verbose_Mode);
+ end if;
+
+ -- Add the archives
+
+ Add_Archives (For_Gnatmake => True);
+ end if;
+
+ -- And invoke gnatmake
+
+ Display_Command
+ (Compiler_Names (Lang_Ada).all, Compiler_Paths (Lang_Ada));
+
+ Spawn
+ (Compiler_Paths (Lang_Ada).all,
+ Arguments (1 .. Last_Argument),
+ Success);
+
+ -- Report an error if call to gnatmake failed
+
+ if not Success then
+ Report_Error
+ ("invocation of ", Compiler_Names (Lang_Ada).all, " failed");
+ end if;
+
+ end Compile_Link_With_Gnatmake;
+
+ ---------------------
+ -- Compile_Sources --
+ ---------------------
+
+ procedure Compile_Sources is
+ Data : Project_Data;
+ Source_Id : Other_Source_Id;
+ Source : Other_Source;
+
+ Local_Errors : Boolean := False;
+ -- Set to True when there is a compilation error. Used only when
+ -- Keep_Going is True, to inhibit the building of the archive.
+
+ Need_To_Compile : Boolean;
+ -- Set to True when a source needs to be compiled/recompiled.
+
+ Need_To_Rebuild_Archive : Boolean := Force_Compilations;
+ -- True when the archive needs to be built/rebuilt unconditionally
+
+ begin
+ -- For each project file
+
+ for Project in 1 .. Projects.Last loop
+ Local_Errors := False;
+ Data := Projects.Table (Project);
+
+ if not Data.Virtual then
+
+ -- If the imported directory switches are unknown, compute them
+
+ if not Data.Include_Data_Set then
+ Get_Imported_Directories (Project, Data);
+ Data.Include_Data_Set := True;
+ Projects.Table (Project) := Data;
+ end if;
+
+ -- Nothing to do when no sources of language other than Ada
+
+ if Data.Sources_Present then
+ Need_To_Rebuild_Archive := Force_Compilations;
+
+ -- Compilation will occur in the object directory
+
+ Change_Dir (Get_Name_String (Data.Object_Directory));
+
+ Source_Id := Data.First_Other_Source;
+
+ -- Process each source one by one
+
+ while Source_Id /= No_Other_Source loop
+ Source := Other_Sources.Table (Source_Id);
+ Need_To_Compile := Force_Compilations;
+
+ -- Check if compilation is needed
+
+ if not Need_To_Compile then
+ Check_Compilation_Needed (Source, Need_To_Compile);
+ end if;
+
+ -- Proceed, if compilation is needed
+
+ if Need_To_Compile then
+
+ -- If a source is compiled/recompiled, of course the
+ -- archive will need to be built/rebuilt.
+
+ Need_To_Rebuild_Archive := True;
+ Compile (Source_Id, Data, Local_Errors);
+ end if;
+
+ -- Next source, if any
+
+ Source_Id := Source.Next;
+ end loop;
+
+ -- If there was no compilation error, build/rebuild the archive
+ -- if necessary.
+
+ if not Local_Errors then
+ Build_Archive (Project, Need_To_Rebuild_Archive);
+ end if;
+ end if;
+ end if;
+ end loop;
+ end Compile_Sources;
+
+ ---------------
+ -- Copyright --
+ ---------------
+
+ procedure Copyright is
+ begin
+ -- Only output the Copyright notice once
+
+ if not Copyright_Output then
+ Copyright_Output := True;
+ Write_Eol;
+ Write_Str ("GPRMAKE ");
+ Write_Str (Gnatvsn.Gnat_Version_String);
+ Write_Str (" Copyright 2004 Free Software Foundation, Inc.");
+ Write_Eol;
+ end if;
+ end Copyright;
+
+ ------------------------------------
+ -- Create_Archive_Dependency_File --
+ ------------------------------------
+
+ procedure Create_Archive_Dependency_File
+ (Name : String;
+ First_Source : Other_Source_Id)
+ is
+ Source_Id : Other_Source_Id := First_Source;
+ Source : Other_Source;
+ Dep_File : Ada.Text_IO.File_Type;
+ use Ada.Text_IO;
+
+ begin
+ Create (Dep_File, Out_File, Name);
+
+ while Source_Id /= No_Other_Source loop
+ Source := Other_Sources.Table (Source_Id);
+ Put_Line (Dep_File, Get_Name_String (Source.Object_Name));
+ Put_Line (Dep_File, String (Source.Object_TS));
+ Source_Id := Source.Next;
+ end loop;
+
+ Close (Dep_File);
+
+ exception
+ when others =>
+ if Is_Open (Dep_File) then
+ Close (Dep_File);
+ end if;
+ end Create_Archive_Dependency_File;
+
+ ---------------------
+ -- Display_Command --
+ ---------------------
+
+ procedure Display_Command (Name : String; Path : String_Access) is
+ begin
+ -- Only display the command in Verbose Mode (-v) or when
+ -- not in Quiet Output (no -q).
+
+ if Verbose_Mode or (not Quiet_Output) then
+ -- In Verbose Mode output the full path of the spawned process
+
+ if Verbose_Mode then
+ Write_Str (Path.all);
+
+ else
+ Write_Str (Name);
+ end if;
+
+ -- Display only the arguments for which the display flag is set
+ -- (in Verbose Mode, the display flag is set for all arguments)
+
+ for Arg in 1 .. Last_Argument loop
+ if Arguments_Displayed (Arg) then
+ Write_Char (' ');
+ Write_Str (Arguments (Arg).all);
+ end if;
+ end loop;
+
+ Write_Eol;
+ end if;
+ end Display_Command;
+
+ ------------------
+ -- Get_Compiler --
+ ------------------
+
+ procedure Get_Compiler (For_Language : Programming_Language) is
+ Data : constant Project_Data := Projects.Table (Main_Project);
+
+ Ide : constant Package_Id :=
+ Value_Of (Name_Ide, In_Packages => Data.Decl.Packages);
+ -- The id of the package IDE in the project file
+
+ Compiler : constant Variable_Value :=
+ Value_Of
+ (Name => Lang_Name_Ids (For_Language),
+ Index => 0,
+ Attribute_Or_Array_Name => Name_Compiler_Command,
+ In_Package => Ide);
+ -- The value of Compiler_Command ("language") in package IDE, if defined
+
+ begin
+ -- No need to do it again if the compiler is known for this language
+
+ if Compiler_Names (For_Language) = null then
+
+ -- If compiler command is not defined for this language in package
+ -- IDE, use the default compiler for this language.
+
+ if Compiler = Nil_Variable_Value then
+ Compiler_Names (For_Language) :=
+ Default_Compiler_Names (For_Language);
+
+ else
+ Compiler_Names (For_Language) :=
+ new String'(Get_Name_String (Compiler.Value));
+ end if;
+
+ -- Check we have a GCC compiler (name ends with "gcc" or "g++")
+
+ declare
+ Comp_Name : constant String := Compiler_Names (For_Language).all;
+ Last3 : String (1 .. 3);
+ begin
+ if Comp_Name'Length >= 3 then
+ Last3 := Comp_Name (Comp_Name'Last - 2 .. Comp_Name'Last);
+ Compiler_Is_Gcc (For_Language) :=
+ (Last3 = "gcc") or (Last3 = "g++");
+ else
+ Compiler_Is_Gcc (For_Language) := False;
+ end if;
+ end;
+
+ -- Locate the compiler on the path
+
+ Compiler_Paths (For_Language) :=
+ Locate_Exec_On_Path (Compiler_Names (For_Language).all);
+
+ -- Fail if compiler cannot be found
+
+ if Compiler_Paths (For_Language) = null then
+ if For_Language = Lang_Ada then
+ Osint.Fail
+ ("unable to locate """,
+ Compiler_Names (For_Language).all,
+ """");
+
+ else
+ Osint.Fail
+ ("unable to locate " & Lang_Display_Names (For_Language).all,
+ " compiler """, Compiler_Names (For_Language).all & '"');
+ end if;
+ end if;
+ end if;
+ end Get_Compiler;
+
+ ------------------------------
+ -- Get_Imported_Directories --
+ ------------------------------
+
+ procedure Get_Imported_Directories
+ (Project : Project_Id;
+ Data : in out Project_Data)
+ is
+ Imported_Projects : Project_List := Data.Imported_Projects;
+
+ Path_Length : Natural := 0;
+ Position : Natural := 0;
+
+ procedure Add (Source_Dirs : String_List_Id);
+ -- Add a list of source directories
+
+ procedure Recursive_Get_Dirs (Prj : Project_Id);
+ -- Recursive procedure to get the source directories of this project
+ -- file and of the project files it imports, in the correct order.
+
+ ---------
+ -- Add --
+ ---------
+
+ procedure Add (Source_Dirs : String_List_Id) is
+ Element_Id : String_List_Id := Source_Dirs;
+ Element : String_Element;
+ Add_Arg : Boolean := True;
+ begin
+ -- Add each source directory path name, preceded by "-I" to
+ -- Arguments.
+
+ while Element_Id /= Nil_String loop
+ Element := String_Elements.Table (Element_Id);
+
+ if Element.Value /= No_Name then
+ Get_Name_String (Element.Value);
+
+ if Name_Len > 0 then
+ declare
+ Arg : constant String :=
+ "-I" & Name_Buffer (1 .. Name_Len);
+ begin
+ -- Check if directory is already in the list.
+ -- If it is, no need to put it again.
+
+ for Index in 1 .. Last_Argument loop
+ if Arguments (Index).all = Arg then
+ Add_Arg := False;
+ exit;
+ end if;
+ end loop;
+
+ if Add_Arg then
+ if Path_Length /= 0 then
+ Path_Length := Path_Length + 1;
+ end if;
+
+ Path_Length := Path_Length + Name_Len;
+
+ Add_Argument (Arg, True);
+ end if;
+ end;
+ end if;
+ end if;
+
+ Element_Id := Element.Next;
+ end loop;
+ end Add;
+
+ ------------------------
+ -- Recursive_Get_Dirs --
+ ------------------------
+
+ procedure Recursive_Get_Dirs (Prj : Project_Id) is
+ Data : Project_Data;
+ Imported : Project_List;
+
+ begin
+ -- Nothing to do if project is undefined
+
+ if Prj /= No_Project then
+ Data := Projects.Table (Prj);
+
+ -- Nothing to do if project has already been processed
+
+ if not Data.Seen then
+
+ -- Mark the project as processed, to avoid multiple processing
+ -- of the same project.
+
+ Projects.Table (Prj).Seen := True;
+
+ -- Add the source directories of this project
+
+ if not Data.Virtual then
+ Add (Data.Source_Dirs);
+ end if;
+
+ Recursive_Get_Dirs (Data.Extends);
+
+ Imported := Data.Imported_Projects;
+
+ -- Call itself for all imported projects, if any
+
+ while Imported /= Empty_Project_List loop
+ Recursive_Get_Dirs (Project_Lists.Table (Imported).Project);
+ Imported := Project_Lists.Table (Imported).Next;
+ end loop;
+ end if;
+ end if;
+ end Recursive_Get_Dirs;
+
+ begin
+ -- First, mark all project as not processed
+
+ for J in 1 .. Projects.Last loop
+ Projects.Table (J).Seen := False;
+ end loop;
+
+ -- Empty Arguments
+
+ Last_Argument := 0;
+
+ -- Process this project individually, project data are already known
+
+ Projects.Table (Project).Seen := True;
+
+ Add (Data.Source_Dirs);
+
+ Recursive_Get_Dirs (Data.Extends);
+
+ while Imported_Projects /= Empty_Project_List loop
+ Recursive_Get_Dirs (Project_Lists.Table (Imported_Projects).Project);
+ Imported_Projects := Project_Lists.Table (Imported_Projects).Next;
+ end loop;
+
+ Data.Imported_Directories_Switches :=
+ new Argument_List'(Arguments (1 .. Last_Argument));
+
+ -- Create the Include_Path, from the Arguments
+
+ Data.Include_Path := new String (1 .. Path_Length);
+ Data.Include_Path (1 .. Arguments (1)'Length - 2) :=
+ Arguments (1)(Arguments (1)'First + 2 .. Arguments (1)'Last);
+ Position := Arguments (1)'Length - 2;
+
+ for Arg in 2 .. Last_Argument loop
+ Position := Position + 1;
+ Data.Include_Path (Position) := Path_Separator;
+ Data.Include_Path
+ (Position + 1 .. Position + Arguments (Arg)'Length - 2) :=
+ Arguments (Arg)(Arguments (Arg)'First + 2 .. Arguments (Arg)'Last);
+ Position := Position + Arguments (Arg)'Length - 2;
+ end loop;
+
+ Last_Argument := 0;
+ end Get_Imported_Directories;
+
+ -------------
+ -- Gprmake --
+ -------------
+
+ procedure Gprmake is
+ begin
+ Initialize;
+
+ if Verbose_Mode then
+ Write_Eol;
+ Write_Str ("Parsing Project File """);
+ Write_Str (Project_File_Name.all);
+ Write_Str (""".");
+ Write_Eol;
+ end if;
+
+ -- Parse and process the project files for other languages
+ -- (not for Ada).
+
+ Prj.Pars.Parse
+ (Project => Main_Project,
+ Project_File_Name => Project_File_Name.all,
+ Packages_To_Check => Packages_To_Check,
+ Process_Languages => Other_Languages);
+
+ -- Fail if parsing/processing was unsuccessful
+
+ if Main_Project = No_Project then
+ Osint.Fail ("""", Project_File_Name.all, """ processing failed");
+ end if;
+
+ if Verbose_Mode then
+ Write_Eol;
+ Write_Str ("Parsing of Project File """);
+ Write_Str (Project_File_Name.all);
+ Write_Str (""" is finished.");
+ Write_Eol;
+ end if;
+
+ -- If -f was specified, we will certainly need to link (except when
+ -- -u or -c were specified, of course).
+
+ Need_To_Relink := Force_Compilations;
+
+ if Unique_Compile then
+ if Mains.Number_Of_Mains = 0 then
+ Osint.Fail
+ ("No source specified to compile in 'unique compile' mode");
+
+ else
+ Compile_Individual_Sources;
+ Report_Total_Errors ("compilation");
+ end if;
+
+ else
+ -- First compile sources and build archives, if necessary
+
+ Compile_Sources;
+
+ -- When Keep_Going is True, if we had some errors, fail now,
+ -- reporting the number of compilation errors.
+ -- Do not attempt to link.
+
+ Report_Total_Errors ("compilation");
+
+ -- If -c was not specified, link the executables, if there are any.
+
+ if not Compile_Only then
+ Check_For_C_Plus_Plus;
+ Link_Executables;
+ end if;
+
+ -- When Keep_Going is True, if we had some errors, fail, reporting
+ -- the number of linking errors.
+
+ Report_Total_Errors ("linking");
+ end if;
+ end Gprmake;
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize is
+ Next_Arg : Positive;
+
+ begin
+ -- Do some necessary package initializations
+
+ Csets.Initialize;
+ Namet.Initialize;
+ Snames.Initialize;
+ Prj.Initialize;
+ Mains.Delete;
+
+ -- Set Name_Ide and Name_Compiler_Command
+
+ Name_Len := 0;
+ Add_Str_To_Name_Buffer ("ide");
+ Name_Ide := Name_Find;
+
+ Name_Len := 0;
+ Add_Str_To_Name_Buffer ("compiler_command");
+ Name_Compiler_Command := Name_Find;
+
+ Next_Arg := 1;
+
+ -- Get the command line arguments
+
+ Scan_Args : while Next_Arg <= Argument_Count loop
+ Scan_Arg (Argument (Next_Arg));
+ Next_Arg := Next_Arg + 1;
+ end loop Scan_Args;
+
+ -- Fail if command line ended with "-P"
+
+ if Project_File_Name_Expected then
+ Osint.Fail ("project file name missing after -P");
+
+ -- Or if it ended with "-o"
+
+ elsif Output_File_Name_Expected then
+ Osint.Fail ("output file name missing after -o");
+ end if;
+
+ -- If no project file was specified, display the usage and fail
+
+ if Project_File_Name = null then
+ Usage;
+ Exit_Program (E_Success);
+ end if;
+
+ -- To be able of finding libgnat.a in MLib.Tgt, we need to have the
+ -- default search dirs established in Osint.
+
+ Osint.Add_Default_Search_Dirs;
+ end Initialize;
+
+ ----------------------
+ -- Link_Executables --
+ ----------------------
+
+ procedure Link_Executables is
+ Data : constant Project_Data := Projects.Table (Main_Project);
+
+ Mains_Specified : constant Boolean := Mains.Number_Of_Mains /= 0;
+ -- True if main sources were specified on the command line
+
+ Object_Dir : constant String := Get_Name_String (Data.Object_Directory);
+ -- Path of the object directory of the main project
+
+ Source_Id : Other_Source_Id;
+ Source : Other_Source;
+ Success : Boolean;
+
+ Linker_Name : String_Access;
+ Linker_Path : String_Access;
+ -- The linker name and path, when linking is not done by gnatlink
+
+ Link_Done : Boolean := False;
+ -- Set to True when the linker is invoked directly (not through
+ -- gnatmake) to be able to report if mains were up to date at the end
+ -- of execution.
+
+ procedure Add_C_Plus_Plus_Link_For_Gnatmake;
+ -- Add the --LINK= switch for gnatlink, depending on the C++ compiler
+
+ procedure Choose_C_Plus_Plus_Link_Process;
+ -- If the C++ compiler is not g++, create the correct script to link
+
+ ---------------------------------------
+ -- Add_C_Plus_Plus_Link_For_Gnatmake --
+ ---------------------------------------
+
+ procedure Add_C_Plus_Plus_Link_For_Gnatmake is
+ begin
+ if Compiler_Is_Gcc (Lang_C_Plus_Plus) then
+ Add_Argument
+ ("--LINK=" & Compiler_Names (Lang_C_Plus_Plus).all,
+ Verbose_Mode);
+
+ else
+ Add_Argument
+ ("--LINK=" &
+ Object_Dir & Directory_Separator &
+ Cpp_Linker,
+ Verbose_Mode);
+ end if;
+ end Add_C_Plus_Plus_Link_For_Gnatmake;
+
+ -------------------------------------
+ -- Choose_C_Plus_Plus_Link_Process --
+ -------------------------------------
+
+ procedure Choose_C_Plus_Plus_Link_Process is
+ begin
+ if Compiler_Names (Lang_C_Plus_Plus) = null then
+ Get_Compiler (Lang_C_Plus_Plus);
+ end if;
+
+ if not Compiler_Is_Gcc (Lang_C_Plus_Plus) then
+ Change_Dir (Object_Dir);
+
+ declare
+ procedure Set_Executable (Name : System.Address);
+ pragma Import
+ (C, Set_Executable, "__gnat_set_executable");
+
+ Name : constant String := Cpp_Linker & ASCII.NUL;
+
+ File : Ada.Text_IO.File_Type;
+ use Ada.Text_IO;
+
+ begin
+ Create (File, Out_File, Cpp_Linker);
+
+ Put_Line (File, "#!/bin/sh");
+
+ Put_Line (File, "LIBGCC=`gcc -print-libgcc-file-name`");
+ Put_Line
+ (File,
+ Compiler_Names (Lang_C_Plus_Plus).all &
+ " $* ${LIBGCC}");
+
+ Close (File);
+ Set_Executable (Name (Name'First)'Address);
+ end;
+ end if;
+ end Choose_C_Plus_Plus_Link_Process;
+
+ begin
+ -- If no mains specified, get mains from attribute Main, if it exists
+
+ if not Mains_Specified then
+ declare
+ Element_Id : String_List_Id := Data.Mains;
+ Element : String_Element;
+
+ begin
+ while Element_Id /= Nil_String loop
+ Element := String_Elements.Table (Element_Id);
+
+ if Element.Value /= No_Name then
+ Mains.Add_Main (Get_Name_String (Element.Value));
+ end if;
+
+ Element_Id := Element.Next;
+ end loop;
+ end;
+ end if;
+
+ if Mains.Number_Of_Mains = 0 then
+ -- If the attribute Main is an empty list or not specified,
+ -- there is nothing to do.
+
+ if Verbose_Mode then
+ Write_Line ("No main to link");
+ end if;
+ return;
+ end if;
+
+ -- Check if -o was used for several mains
+
+ if Output_File_Name /= null and then Mains.Number_Of_Mains > 1 then
+ Osint.Fail ("cannot specify an executable name for several mains");
+ end if;
+
+ -- Check how we are going to do the link
+
+ if not Data.Sources_Present then
+ -- Only Ada sources in the main project, and even maybe not
+
+ if not Data.Languages (Lang_Ada) then
+ -- Fail if the main project has no source of any language
+
+ Osint.Fail
+ ("project """,
+ Get_Name_String (Data.Name),
+ """ has no sources, so no main can be linked");
+
+ else
+ -- Only Ada sources in the main project, call gnatmake directly
+
+ Last_Argument := 0;
+
+ -- Choose the correct linker if there is C++ code in other
+ -- projects.
+
+ if C_Plus_Plus_Is_Used then
+ Choose_C_Plus_Plus_Link_Process;
+ Add_Argument (Dash_largs, Verbose_Mode);
+ Add_C_Plus_Plus_Link_For_Gnatmake;
+ Add_Argument (Dash_margs, Verbose_Mode);
+ end if;
+
+ Compile_Link_With_Gnatmake (Mains_Specified);
+ end if;
+
+ else
+ -- There are other language sources. First check if there are also
+ -- sources in Ada.
+
+ if Data.Languages (Lang_Ada) then
+ -- There is a mix of Ada and other language sources in the main
+ -- project. Any main that is not a source of the other languages
+ -- will be deemed to be an Ada main.
+ --
+ -- Find the mains of the other languages and the Ada mains.
+
+ Mains.Reset;
+ Ada_Mains.Set_Last (0);
+ Other_Mains.Set_Last (0);
+
+ -- For each main
+
+ loop
+ declare
+ Main : constant String := Mains.Next_Main;
+ Main_Id : Name_Id;
+ begin
+ exit when Main'Length = 0;
+
+ -- Get the main file name
+
+ Name_Len := 0;
+ Add_Str_To_Name_Buffer (Main);
+ Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
+ Main_Id := Name_Find;
+ Source_Id := Data.First_Other_Source;
+
+ -- Check if it is a source of a language other than Ada
+
+ while Source_Id /= No_Other_Source loop
+ Source := Other_Sources.Table (Source_Id);
+ exit when Source.File_Name = Main_Id;
+ Source_Id := Source.Next;
+ end loop;
+
+ -- If it is not, put it in the list of Ada mains
+
+ if Source_Id = No_Other_Source then
+ Ada_Mains.Increment_Last;
+ Ada_Mains.Table (Ada_Mains.Last) := new String'(Main);
+
+ -- Otherwise, put it in the list of other mains
+
+ else
+ Other_Mains.Increment_Last;
+ Other_Mains.Table (Other_Mains.Last) := Source;
+ end if;
+ end;
+ end loop;
+
+ -- If C++ is one of the other language, create the shell script
+ -- to do the link.
+
+ if C_Plus_Plus_Is_Used then
+ Choose_C_Plus_Plus_Link_Process;
+ end if;
+
+ -- Call gnatmake with the necessary switches for each non-Ada
+ -- main, if there are some.
+
+ for Main in 1 .. Other_Mains.Last loop
+ declare
+ Source : constant Other_Source := Other_Mains.Table (Main);
+ begin
+ Last_Argument := 0;
+
+ -- Add -o if -o was specified
+
+ if Output_File_Name = null then
+ Add_Argument (Dash_o, True);
+ Add_Argument
+ (Get_Name_String
+ (Executable_Of
+ (Project => Main_Project,
+ Main => Other_Mains.Table (Main).File_Name,
+ Index => 0,
+ Ada_Main => False)),
+ True);
+ end if;
+
+ -- Call gnatmake with the -B switch
+
+ Add_Argument (Dash_B, True);
+
+ -- Add to the linking options the object file of the source
+
+ Add_Argument (Dash_largs, Verbose_Mode);
+ Add_Argument
+ (Get_Name_String (Source.Object_Name), Verbose_Mode);
+
+ -- If C++ is one of the language, add the --LINK switch
+ -- to the linking switches.
+
+ if C_Plus_Plus_Is_Used then
+ Add_C_Plus_Plus_Link_For_Gnatmake;
+ end if;
+
+ -- Add -margs so that the following switches are for
+ -- gnatmake
+
+ Add_Argument (Dash_margs, Verbose_Mode);
+
+ -- And link with gnatmake
+
+ Compile_Link_With_Gnatmake (Mains_Specified => False);
+ end;
+ end loop;
+
+ -- If there are also Ada mains, call gnatmake for all these mains
+
+ if Ada_Mains.Last /= 0 then
+ Last_Argument := 0;
+
+ -- Put all the Ada mains as the first arguments
+
+ for Main in 1 .. Ada_Mains.Last loop
+ Add_Argument (Ada_Mains.Table (Main).all, True);
+ end loop;
+
+ -- If C++ is one of the languages, add the --LINK switch to
+ -- the linking switches.
+
+ if Data.Languages (Lang_C_Plus_Plus) then
+ Add_Argument (Dash_largs, Verbose_Mode);
+ Add_C_Plus_Plus_Link_For_Gnatmake;
+ Add_Argument (Dash_margs, Verbose_Mode);
+ end if;
+
+ -- And link with gnatmake
+
+ Compile_Link_With_Gnatmake (Mains_Specified => False);
+ end if;
+
+ else
+ -- No Ada source in main project
+
+ -- First, get the linker to invoke
+
+ if Data.Languages (Lang_C_Plus_Plus) then
+ Get_Compiler (Lang_C_Plus_Plus);
+ Linker_Name := Compiler_Names (Lang_C_Plus_Plus);
+ Linker_Path := Compiler_Paths (Lang_C_Plus_Plus);
+
+ else
+ Get_Compiler (Lang_C);
+ Linker_Name := Compiler_Names (Lang_C);
+ Linker_Path := Compiler_Paths (Lang_C);
+ end if;
+
+ Link_Done := False;
+
+ Mains.Reset;
+
+ -- Get each main, check if it is a source of the main project,
+ -- and if it is, invoke the linker.
+
+ loop
+ declare
+ Main : constant String := Mains.Next_Main;
+ Main_Id : Name_Id;
+ begin
+ exit when Main'Length = 0;
+
+ -- Get the file name of the main
+
+ Name_Len := 0;
+ Add_Str_To_Name_Buffer (Main);
+ Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
+ Main_Id := Name_Find;
+ Source_Id := Data.First_Other_Source;
+
+ -- Check if it is a source of the main project file
+
+ while Source_Id /= No_Other_Source loop
+ Source := Other_Sources.Table (Source_Id);
+ exit when Source.File_Name = Main_Id;
+ Source_Id := Source.Next;
+ end loop;
+
+ -- Report an error if it is not
+
+ if Source_Id = No_Other_Source then
+ Report_Error
+ (Main, "is not a source of project ",
+ Get_Name_String (Data.Name));
+
+ else
+ declare
+ Executable_Name : constant String :=
+ Get_Name_String
+ (Executable_Of
+ (Project => Main_Project,
+ Main => Main_Id,
+ Index => 0,
+ Ada_Main => False));
+ -- File name of the executable
+
+ Executable_Path : constant String :=
+ Get_Name_String
+ (Data.Exec_Directory) &
+ Directory_Separator &
+ Executable_Name;
+ -- Path name of the executable
+
+ Exec_Time_Stamp : Time_Stamp_Type;
+
+ begin
+ -- Now, check if the executable is up to date.
+ -- It is considered up to date if its time stamp is
+ -- not earlier that the time stamp of any archive.
+ -- Only do that if we don't know if we need to link.
+
+ if not Need_To_Relink then
+
+ -- Get the time stamp of the executable
+
+ Name_Len := 0;
+ Add_Str_To_Name_Buffer (Executable_Path);
+ Exec_Time_Stamp := File_Stamp (Name_Find);
+
+ if Verbose_Mode then
+ Write_Str (" Checking executable ");
+ Write_Line (Executable_Name);
+ end if;
+
+ -- If executable does not exist, we need to link
+
+ if Exec_Time_Stamp = Empty_Time_Stamp then
+ Need_To_Relink := True;
+
+ if Verbose_Mode then
+ Write_Line (" -> not found");
+ end if;
+
+ else
+ -- Otherwise, get the time stamps of each
+ -- archive. If one of them is found later than
+ -- the executable, we need to relink.
+
+ declare
+ Prj_Data : Project_Data;
+
+ begin
+ for Prj in 1 .. Projects.Last loop
+ Prj_Data := Projects.Table (Prj);
+
+ -- There is an archive only in project
+ -- files with sources other than Ada
+ -- sources.
+
+ if Data.Sources_Present then
+ declare
+ Archive_Path : constant String :=
+ Get_Name_String
+ (Prj_Data.Object_Directory) &
+ Directory_Separator &
+ "lib" &
+ Get_Name_String (Prj_Data.Name) &
+ '.' & Archive_Ext;
+ Archive_TS : Time_Stamp_Type;
+ begin
+ Name_Len := 0;
+ Add_Str_To_Name_Buffer
+ (Archive_Path);
+ Archive_TS := File_Stamp (Name_Find);
+
+ -- If the archive is later than the
+ -- executable, we need to relink.
+
+ if Archive_TS /= Empty_Time_Stamp
+ and then
+ Exec_Time_Stamp < Archive_TS
+ then
+ Need_To_Relink := True;
+
+ if Verbose_Mode then
+ Write_Str (" -> ");
+ Write_Str (Archive_Path);
+ Write_Str (" has time stamp ");
+ Write_Str ("later than ");
+ Write_Line ("executable");
+ end if;
+
+ exit;
+ end if;
+ end;
+ end if;
+ end loop;
+ end;
+ end if;
+
+ -- If Need_To_Relink is False, we are done
+
+ if Verbose_Mode and (not Need_To_Relink) then
+ Write_Line (" -> up to date");
+ end if;
+
+ end if;
+
+ -- Prepare to link
+
+ if Need_To_Relink then
+ Link_Done := True;
+
+ Last_Argument := 0;
+
+ -- Specify the executable path name
+
+ Add_Argument (Dash_o, True);
+ Add_Argument
+ (Get_Name_String (Data.Exec_Directory) &
+ Directory_Separator &
+ Get_Name_String
+ (Executable_Of
+ (Project => Main_Project,
+ Main => Main_Id,
+ Index => 0,
+ Ada_Main => False)),
+ True);
+
+ -- Specify the object file of the main source
+
+ Add_Argument
+ (Object_Dir & Directory_Separator &
+ Get_Name_String (Source.Object_Name),
+ True);
+
+ -- Add the switches specified in attribute
+ -- Linker_Options of packages Linker.
+
+ if Link_Options_Switches = null then
+ Link_Options_Switches :=
+ new Argument_List'
+ (Linker_Options_Switches (Main_Project));
+ end if;
+
+ Add_Arguments (Link_Options_Switches.all, True);
+
+ -- Add the linking options specified on the
+ -- command line.
+
+ for Arg in 1 .. Linker_Options.Last loop
+ Add_Argument (Linker_Options.Table (Arg), True);
+ end loop;
+
+ -- Add all the archives, in a correct order
+
+ Add_Archives (For_Gnatmake => False);
+
+ -- If there are shared libraries and the run path
+ -- option is supported, add the run path switch.
+
+ if Lib_Path.Last > 0 then
+ Add_Argument
+ (Path_Option.all &
+ String (Lib_Path.Table (1 .. Lib_Path.Last)),
+ Verbose_Mode);
+ end if;
+
+ -- And invoke the linker
+
+ Display_Command (Linker_Name.all, Linker_Path);
+ Spawn
+ (Linker_Path.all,
+ Arguments (1 .. Last_Argument),
+ Success);
+
+ if not Success then
+ Report_Error ("could not link ", Main);
+ end if;
+ end if;
+ end;
+ end if;
+ end;
+ end loop;
+
+ -- If no linking was done, report it, except in Quiet Output
+
+ if (Verbose_Mode or (not Quiet_Output)) and (not Link_Done) then
+ Osint.Write_Program_Name;
+
+ if Mains.Number_Of_Mains = 1 then
+ -- If there is only one executable, report its name too
+
+ Write_Str (": """);
+ Mains.Reset;
+
+ declare
+ Main : constant String := Mains.Next_Main;
+ Main_Id : Name_Id;
+ begin
+ Name_Len := 0;
+ Add_Str_To_Name_Buffer (Main);
+ Main_Id := Name_Find;
+ Write_Str
+ (Get_Name_String
+ (Executable_Of
+ (Project => Main_Project,
+ Main => Main_Id,
+ Index => 0,
+ Ada_Main => False)));
+ Write_Line (""" up to date");
+ end;
+
+ else
+ Write_Line (": all executables up to date");
+ end if;
+ end if;
+ end if;
+ end if;
+ end Link_Executables;
+
+ ------------------
+ -- Report_Error --
+ ------------------
+
+ procedure Report_Error
+ (S1 : String;
+ S2 : String := "";
+ S3 : String := "")
+ is
+ begin
+ -- If Keep_Going is True, output the error message, preceded by the
+ -- error header.
+
+ if Keep_Going then
+ Total_Number_Of_Errors := Total_Number_Of_Errors + 1;
+ Write_Str (Error_Header);
+ Write_Str (S1);
+ Write_Str (S2);
+ Write_Str (S3);
+ Write_Eol;
+
+ else
+ -- Otherwise, just fail
+
+ Osint.Fail (S1, S2, S3);
+ end if;
+ end Report_Error;
+
+ -------------------------
+ -- Report_Total_Errors --
+ -------------------------
+
+ procedure Report_Total_Errors (Kind : String) is
+ begin
+ if Total_Number_Of_Errors /= 0 then
+ if Total_Number_Of_Errors = 1 then
+ Osint.Fail
+ ("One ", Kind, " error");
+
+ else
+ Osint.Fail
+ ("Total of" & Total_Number_Of_Errors'Img,
+ ' ' & Kind & " errors");
+ end if;
+ end if;
+ end Report_Total_Errors;
+
+ --------------
+ -- Scan_Arg --
+ --------------
+
+ procedure Scan_Arg (Arg : String) is
+ begin
+ pragma Assert (Arg'First = 1);
+
+ if Arg'Length = 0 then
+ return;
+ end if;
+
+ -- If preceding switch was -P, a project file name need to be specified,
+ -- not a switch.
+
+ if Project_File_Name_Expected then
+ if Arg (1) = '-' then
+ Osint.Fail ("project file name missing after -P");
+ else
+ Project_File_Name_Expected := False;
+ Project_File_Name := new String'(Arg);
+ end if;
+
+ -- If preceding switch was -o, an executable name need to be specidied,
+ -- not a switch.
+
+ elsif Output_File_Name_Expected then
+ if Arg (1) = '-' then
+ Osint.Fail ("output file name missing after -o");
+ else
+ Output_File_Name_Expected := False;
+ Output_File_Name := new String'(Arg);
+ end if;
+
+ -- Set the processor/language for the following switches
+
+ -- -c???args: Compiler arguments
+
+ elsif Arg'Length >= 6 and then
+ Arg (Arg'First .. Arg'First + 1) = "-c" and then
+ Arg (Arg'Last - 3 .. Arg'Last) = "args"
+
+ then
+ declare
+ OK : Boolean := False;
+ Args_String : constant String :=
+ Arg (Arg'First + 2 .. Arg'Last - 4);
+
+ begin
+ for Lang in Programming_Language loop
+ if Args_String = Lang_Args (Lang).all then
+ OK := True;
+ Current_Language := Lang;
+ exit;
+ end if;
+ end loop;
+
+ if OK then
+ Current_Processor := Compiler;
+
+ else
+ Osint.Fail ("illegal option """, Arg, """");
+ end if;
+ end;
+
+ elsif Arg = "-largs" then
+ Current_Processor := Linker;
+
+ -- -gargs: gprmake
+
+ elsif Arg = "-gargs" then
+ Current_Processor := None;
+
+ -- A special test is needed for the -o switch within a -largs since
+ -- that is another way to specify the name of the final executable.
+
+ elsif Current_Processor = Linker and then Arg = "-o" then
+ Osint.Fail
+ ("switch -o not allowed within a -largs. Use -o directly.");
+
+ -- If current processor is not gprmake dirrectly, store the option in
+ -- the appropriate table.
+
+ elsif Current_Processor /= None then
+ Add_Option (Arg);
+
+ -- Switches start with '-'
+
+ elsif Arg (1) = '-' then
+ if Arg = "-c" then
+ Compile_Only := True;
+
+ elsif Arg = "-f" then
+ Force_Compilations := True;
+
+ elsif Arg = "-h" then
+ Usage;
+
+ elsif Arg = "-k" then
+ Keep_Going := True;
+
+ elsif Arg = "-o" then
+ if Output_File_Name /= null then
+ Osint.Fail ("cannot specify several -o switches");
+
+ else
+ Output_File_Name_Expected := True;
+ end if;
+
+ elsif Arg'Length >= 2 and then Arg (2) = 'P' then
+ if Project_File_Name /= null then
+ Osint.Fail ("cannot have several project files specified");
+
+ elsif Arg'Length = 2 then
+ Project_File_Name_Expected := True;
+
+ else
+ Project_File_Name := new String'(Arg (3 .. Arg'Last));
+ end if;
+
+ elsif Arg = "-q" then
+ Quiet_Output := True;
+
+ elsif Arg = "-u" then
+ Unique_Compile := True;
+ Compile_Only := True;
+
+ elsif Arg = "-v" then
+ Verbose_Mode := True;
+
+ elsif Arg'Length = 4 and then Arg (1 .. 3) = "-vP"
+ and then Arg (4) in '0' .. '2'
+ then
+ case Arg (4) is
+ when '0' =>
+ Current_Verbosity := Prj.Default;
+ when '1' =>
+ Current_Verbosity := Prj.Medium;
+ when '2' =>
+ Current_Verbosity := Prj.High;
+ when others =>
+ null;
+ end case;
+
+ elsif Arg'Length >= 3 and then Arg (2) = 'X'
+ and then Is_External_Assignment (Arg)
+ then
+ -- Is_External_Assignment has side effects
+ -- when it returns True;
+
+ null;
+
+ else
+ Osint.Fail ("illegal option """, Arg, """");
+ end if;
+
+ else
+ -- Not a switch: must be a main
+
+ Mains.Add_Main (Arg);
+ end if;
+ end Scan_Arg;
+
+ -----------------
+ -- Strip_CR_LF --
+ -----------------
+
+ function Strip_CR_LF (Text : String) return String is
+
+ To : String (1 .. Text'Length);
+ Index_To : Natural := 0;
+
+ begin
+ for Index in Text'Range loop
+ if (Text (Index) /= ASCII.CR) and then (Text (Index) /= ASCII.LF) then
+ Index_To := Index_To + 1;
+ To (Index_To) := Text (Index);
+ end if;
+ end loop;
+
+ return To (1 .. Index_To);
+ end Strip_CR_LF;
+
+ -----------
+ -- Usage --
+ -----------
+
+ procedure Usage is
+ begin
+ if not Usage_Output then
+ Usage_Output := True;
+ Copyright;
+
+ Write_Str ("Usage: ");
+ Osint.Write_Program_Name;
+ Write_Str (" -P<project file> [opts] [name] {");
+
+ for Lang in Programming_Language loop
+ Write_Str ("[-c");
+ Write_Str (Lang_Args (Lang).all);
+ Write_Str ("args opts] ");
+ end loop;
+
+ Write_Str ("[-largs opts] [-gargs opts]}");
+ Write_Eol;
+ Write_Eol;
+ Write_Str (" name is zero or more file names");
+ Write_Eol;
+ Write_Eol;
+
+ -- GPRMAKE switches
+
+ Write_Str ("gprmake switches:");
+ Write_Eol;
+
+ -- Line for -c
+
+ Write_Str (" -c Compile only");
+ Write_Eol;
+
+ -- Line for -f
+
+ Write_Str (" -f Force recompilations");
+ Write_Eol;
+
+ -- Line for -k
+
+ Write_Str (" -k Keep going after compilation errors");
+ Write_Eol;
+
+ -- Line for -o
+
+ Write_Str (" -o name Choose an alternate executable name");
+ Write_Eol;
+
+ -- Line for -P
+
+ Write_Str (" -Pproj Use GNAT Project File proj");
+ Write_Eol;
+
+ -- Line for -q
+
+ Write_Str (" -q Be quiet/terse");
+ Write_Eol;
+
+ -- Line for -u
+
+ Write_Str
+ (" -u Unique compilation. Only compile the given files");
+ Write_Eol;
+
+ -- Line for -v
+
+ Write_Str (" -v Verbose output");
+ Write_Eol;
+
+ -- Line for -vPx
+
+ Write_Str (" -vPx Specify verbosity when parsing Project Files");
+ Write_Eol;
+
+ -- Line for -X
+
+ Write_Str (" -Xnm=val Specify an external reference for " &
+ "Project Files");
+ Write_Eol;
+ Write_Eol;
+
+ -- Lines for -c*args
+
+ for Lang in Programming_Language loop
+ declare
+ Column : Positive := 13 + Lang_Args (Lang)'Length;
+ -- " -cargs opts" is the minimum and is 13 character long
+
+ begin
+ Write_Str (" -c");
+ Write_Str (Lang_Args (Lang).all);
+ Write_Str ("args opts");
+
+ loop
+ Write_Char (' ');
+ Column := Column + 1;
+ exit when Column >= 17;
+ end loop;
+
+ Write_Str ("opts are passed to the ");
+ Write_Str (Lang_Display_Names (Lang).all);
+ Write_Str (" compiler");
+ Write_Eol;
+ end;
+ end loop;
+
+ -- Line for -largs
+
+ Write_Str (" -largs opts opts are passed to the linker");
+ Write_Eol;
+
+ -- Line for -gargs
+
+ Write_Str (" -gargs opts opts directly interpreted by gprmake");
+ Write_Eol;
+ Write_Eol;
+
+ end if;
+ end Usage;
+
+begin
+ Makeutl.Do_Fail := Report_Error'Access;
+end Makegpr;
diff --git a/gcc/ada/makegpr.ads b/gcc/ada/makegpr.ads
new file mode 100644
index 00000000000..fc751e86411
--- /dev/null
+++ b/gcc/ada/makegpr.ads
@@ -0,0 +1,35 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- M A K E G P R --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2004 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- --
+-- 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, 59 Temple Place - Suite 330, Boston, --
+-- MA 02111-1307, USA. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- The following package implements the facilities to compile, bind and/or
+-- link a set of Ada and non Ada sources, specified in Project Files.
+
+package Makegpr is
+
+ procedure Gprmake;
+ -- The driver of gprmake.
+
+end Makegpr;
diff --git a/gcc/ada/makeusg.adb b/gcc/ada/makeusg.adb
index 73e91f12cfb..ed7140f84d7 100644
--- a/gcc/ada/makeusg.adb
+++ b/gcc/ada/makeusg.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -88,6 +88,17 @@ begin
Write_Str (" -D dir Specify dir as the object directory");
Write_Eol;
+ -- Line for -eI
+
+ Write_Str (" -eI Index of unit in multi-unit source file");
+ Write_Eol;
+
+ -- Line for -eL
+
+ Write_Str (" -eL Follow symbolic links when processing " &
+ "project files");
+ Write_Eol;
+
-- Line for -f
Write_Str (" -f Force recompilations of non predefined units");
@@ -180,6 +191,12 @@ begin
Write_Str (" -vPx Specify verbosity when parsing GNAT Project Files");
Write_Eol;
+ -- Line for -x
+
+ Write_Str (" -x " &
+ "Allow compilation of needed units external to the projects");
+ Write_Eol;
+
-- Line for -X
Write_Str (" -Xnm=val Specify an external reference for GNAT " &
diff --git a/gcc/ada/makeutl.adb b/gcc/ada/makeutl.adb
new file mode 100644
index 00000000000..926affc54c7
--- /dev/null
+++ b/gcc/ada/makeutl.adb
@@ -0,0 +1,509 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- M A K E U T L --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2004 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- --
+-- 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, 59 Temple Place - Suite 330, Boston, --
+-- MA 02111-1307, USA. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Namet; use Namet;
+with Osint; use Osint;
+with Prj; use Prj;
+with Prj.Ext;
+with Prj.Util;
+with Snames; use Snames;
+with Table;
+with Types; use Types;
+
+with System.HTable;
+
+package body Makeutl is
+
+ type Mark_Key is record
+ File : File_Name_Type;
+ Index : Int;
+ end record;
+ -- Identify either a mono-unit source (when Index = 0) or a specific unit
+ -- in a multi-unit source.
+
+ -- There follow many global undocumented declarations, comments needed ???
+
+ Max_Mask_Num : constant := 2048;
+
+ subtype Mark_Num is Union_Id range 0 .. Max_Mask_Num - 1;
+
+ function Hash (Key : Mark_Key) return Mark_Num;
+
+ package Marks is new System.HTable.Simple_HTable
+ (Header_Num => Mark_Num,
+ Element => Boolean,
+ No_Element => False,
+ Key => Mark_Key,
+ Hash => Hash,
+ Equal => "=");
+ -- A hash table to keep tracks of the marked units.
+
+ type Linker_Options_Data is record
+ Project : Project_Id;
+ Options : String_List_Id;
+ end record;
+
+ Linker_Option_Initial_Count : constant := 20;
+
+ Linker_Options_Buffer : String_List_Access :=
+ new String_List (1 .. Linker_Option_Initial_Count);
+
+ Last_Linker_Option : Natural := 0;
+
+ package Linker_Opts is new Table.Table (
+ Table_Component_Type => Linker_Options_Data,
+ Table_Index_Type => Integer,
+ Table_Low_Bound => 1,
+ Table_Initial => 10,
+ Table_Increment => 100,
+ Table_Name => "Make.Linker_Opts");
+
+ procedure Add_Linker_Option (Option : String);
+
+ -----------------------
+ -- Add_Linker_Option --
+ -----------------------
+
+ procedure Add_Linker_Option (Option : String) is
+ begin
+ if Option'Length > 0 then
+ if Last_Linker_Option = Linker_Options_Buffer'Last then
+ declare
+ New_Buffer : constant String_List_Access :=
+ new String_List
+ (1 .. Linker_Options_Buffer'Last +
+ Linker_Option_Initial_Count);
+ begin
+ New_Buffer (Linker_Options_Buffer'Range) :=
+ Linker_Options_Buffer.all;
+ Linker_Options_Buffer.all := (others => null);
+ Free (Linker_Options_Buffer);
+ Linker_Options_Buffer := New_Buffer;
+ end;
+ end if;
+
+ Last_Linker_Option := Last_Linker_Option + 1;
+ Linker_Options_Buffer (Last_Linker_Option) := new String'(Option);
+ end if;
+ end Add_Linker_Option;
+
+ ----------------------
+ -- Delete_All_Marks --
+ ----------------------
+
+ procedure Delete_All_Marks is
+ begin
+ Marks.Reset;
+ end Delete_All_Marks;
+
+ ----------
+ -- Hash --
+ ----------
+
+ function Hash (Key : Mark_Key) return Mark_Num is
+ begin
+ return Union_Id (Key.File) mod Max_Mask_Num;
+ end Hash;
+
+ ----------------------------
+ -- Is_External_Assignment --
+ ----------------------------
+
+ function Is_External_Assignment (Argv : String) return Boolean is
+ Start : Positive := 3;
+ Finish : Natural := Argv'Last;
+ Equal_Pos : Natural;
+
+ begin
+ if Argv'Last < 5 then
+ return False;
+
+ elsif Argv (3) = '"' then
+ if Argv (Argv'Last) /= '"' or else Argv'Last < 7 then
+ return False;
+ else
+ Start := 4;
+ Finish := Argv'Last - 1;
+ end if;
+ end if;
+
+ Equal_Pos := Start;
+
+ while Equal_Pos <= Finish and then Argv (Equal_Pos) /= '=' loop
+ Equal_Pos := Equal_Pos + 1;
+ end loop;
+
+ if Equal_Pos = Start
+ or else Equal_Pos >= Finish
+ then
+ return False;
+ else
+ Prj.Ext.Add
+ (External_Name => Argv (Start .. Equal_Pos - 1),
+ Value => Argv (Equal_Pos + 1 .. Finish));
+ return True;
+ end if;
+ end Is_External_Assignment;
+
+ ---------------
+ -- Is_Marked --
+ ---------------
+
+ function Is_Marked
+ (Source_File : File_Name_Type;
+ Index : Int := 0) return Boolean
+ is
+ begin
+ return Marks.Get (K => (File => Source_File, Index => Index));
+ end Is_Marked;
+
+ -----------------------------
+ -- Linker_Options_Switches --
+ -----------------------------
+
+ function Linker_Options_Switches
+ (Project : Project_Id) return String_List
+ is
+ procedure Recursive_Add_Linker_Options (Proj : Project_Id);
+ -- The recursive routine used to add linker options
+
+ ----------------------------------
+ -- Recursive_Add_Linker_Options --
+ ----------------------------------
+
+ procedure Recursive_Add_Linker_Options (Proj : Project_Id) is
+ Data : Project_Data;
+ Linker_Package : Package_Id;
+ Options : Variable_Value;
+ Imported : Project_List;
+
+ begin
+ if Proj /= No_Project then
+ Data := Projects.Table (Proj);
+
+ if not Data.Seen then
+ Projects.Table (Proj).Seen := True;
+ Imported := Data.Imported_Projects;
+
+ while Imported /= Empty_Project_List loop
+ Recursive_Add_Linker_Options
+ (Project_Lists.Table (Imported).Project);
+ Imported := Project_Lists.Table (Imported).Next;
+ end loop;
+
+ if Proj /= Project then
+ Linker_Package :=
+ Prj.Util.Value_Of
+ (Name => Name_Linker,
+ In_Packages => Data.Decl.Packages);
+ Options :=
+ Prj.Util.Value_Of
+ (Name => Name_Ada,
+ Index => 0,
+ Attribute_Or_Array_Name => Name_Linker_Options,
+ In_Package => Linker_Package);
+
+ -- If attribute is present, add the project with
+ -- the attribute to table Linker_Opts.
+
+ if Options /= Nil_Variable_Value then
+ Linker_Opts.Increment_Last;
+ Linker_Opts.Table (Linker_Opts.Last) :=
+ (Project => Proj, Options => Options.Values);
+ end if;
+ end if;
+ end if;
+ end if;
+ end Recursive_Add_Linker_Options;
+
+ -- Start of processing for Linker_Options_Switches
+
+ begin
+ Linker_Opts.Init;
+
+ for Index in 1 .. Projects.Last loop
+ Projects.Table (Index).Seen := False;
+ end loop;
+
+ Recursive_Add_Linker_Options (Project);
+
+ Last_Linker_Option := 0;
+
+ for Index in reverse 1 .. Linker_Opts.Last loop
+ declare
+ Options : String_List_Id := Linker_Opts.Table (Index).Options;
+ Proj : constant Project_Id :=
+ Linker_Opts.Table (Index).Project;
+ Option : Name_Id;
+
+ begin
+ -- If Dir_Path has not been computed for this project, do it now
+
+ if Projects.Table (Proj).Dir_Path = null then
+ Projects.Table (Proj).Dir_Path :=
+ new String'
+ (Get_Name_String (Projects.Table (Proj). Directory));
+ end if;
+
+ while Options /= Nil_String loop
+ Option := String_Elements.Table (Options).Value;
+ Options := String_Elements.Table (Options).Next;
+ Add_Linker_Option (Get_Name_String (Option));
+
+ -- Object files and -L switches specified with
+ -- relative paths and must be converted to
+ -- absolute paths.
+
+ Test_If_Relative_Path
+ (Switch =>
+ Linker_Options_Buffer (Last_Linker_Option),
+ Parent => Projects.Table (Proj).Dir_Path,
+ Including_L_Switch => True);
+ end loop;
+ end;
+ end loop;
+
+ return Linker_Options_Buffer (1 .. Last_Linker_Option);
+ end Linker_Options_Switches;
+
+ -----------
+ -- Mains --
+ -----------
+
+ package body Mains is
+
+ package Names is new Table.Table
+ (Table_Component_Type => File_Name_Type,
+ Table_Index_Type => Integer,
+ Table_Low_Bound => 1,
+ Table_Initial => 10,
+ Table_Increment => 100,
+ Table_Name => "Makeutl.Mains.Names");
+ -- The table that stores the mains
+
+ Current : Natural := 0;
+ -- The index of the last main retrieved from the table
+
+ --------------
+ -- Add_Main --
+ --------------
+
+ procedure Add_Main (Name : String) is
+ begin
+ Name_Len := 0;
+ Add_Str_To_Name_Buffer (Name);
+ Names.Increment_Last;
+ Names.Table (Names.Last) := Name_Find;
+ end Add_Main;
+
+ ------------
+ -- Delete --
+ ------------
+
+ procedure Delete is
+ begin
+ Names.Set_Last (0);
+ Reset;
+ end Delete;
+
+ ---------------
+ -- Next_Main --
+ ---------------
+
+ function Next_Main return String is
+ begin
+ if Current >= Names.Last then
+ return "";
+
+ else
+ Current := Current + 1;
+ return Get_Name_String (Names.Table (Current));
+ end if;
+ end Next_Main;
+
+ ---------------------
+ -- Number_Of_Mains --
+ ---------------------
+
+ function Number_Of_Mains return Natural is
+ begin
+ return Names.Last;
+ end Number_Of_Mains;
+
+ -----------
+ -- Reset --
+ -----------
+
+ procedure Reset is
+ begin
+ Current := 0;
+ end Reset;
+
+ end Mains;
+
+ ----------
+ -- Mark --
+ ----------
+
+ procedure Mark (Source_File : File_Name_Type; Index : Int := 0) is
+ begin
+ Marks.Set (K => (File => Source_File, Index => Index), E => True);
+ end Mark;
+
+ ---------------------------
+ -- Test_If_Relative_Path --
+ ---------------------------
+
+ procedure Test_If_Relative_Path
+ (Switch : in out String_Access;
+ Parent : String_Access;
+ Including_L_Switch : Boolean := True)
+ is
+ begin
+ if Switch /= null then
+ declare
+ Sw : String (1 .. Switch'Length);
+ Start : Positive;
+
+ begin
+ Sw := Switch.all;
+
+ if Sw (1) = '-' then
+ if Sw'Length >= 3
+ and then (Sw (2) = 'A'
+ or else Sw (2) = 'I'
+ or else (Including_L_Switch and then Sw (2) = 'L'))
+ then
+ Start := 3;
+
+ if Sw = "-I-" then
+ return;
+ end if;
+
+ elsif Sw'Length >= 4
+ and then (Sw (2 .. 3) = "aL"
+ or else Sw (2 .. 3) = "aO"
+ or else Sw (2 .. 3) = "aI")
+ then
+ Start := 4;
+
+ else
+ return;
+ end if;
+
+ -- Because relative path arguments to --RTS= may be relative
+ -- to the search directory prefix, those relative path
+ -- arguments are not converted.
+
+ if not Is_Absolute_Path (Sw (Start .. Sw'Last)) then
+ if Parent = null or else Parent'Length = 0 then
+ Do_Fail
+ ("relative search path switches (""",
+ Sw,
+ """) are not allowed");
+
+ else
+ Switch :=
+ new String'
+ (Sw (1 .. Start - 1) &
+ Parent.all &
+ Directory_Separator &
+ Sw (Start .. Sw'Last));
+ end if;
+ end if;
+
+ else
+ if not Is_Absolute_Path (Sw) then
+ if Parent = null or else Parent'Length = 0 then
+ Do_Fail
+ ("relative paths (""", Sw, """) are not allowed");
+
+ else
+ Switch :=
+ new String'(Parent.all & Directory_Separator & Sw);
+ end if;
+ end if;
+ end if;
+ end;
+ end if;
+ end Test_If_Relative_Path;
+
+ -------------------
+ -- Unit_Index_Of --
+ -------------------
+
+ function Unit_Index_Of (ALI_File : File_Name_Type) return Int is
+ Start : Natural;
+ Finish : Natural;
+ Result : Int := 0;
+
+ begin
+ Get_Name_String (ALI_File);
+
+ -- First, find the last dot
+
+ Finish := Name_Len;
+
+ while Finish >= 1 and then Name_Buffer (Finish) /= '.' loop
+ Finish := Finish - 1;
+ end loop;
+
+ if Finish = 1 then
+ return 0;
+ end if;
+
+ -- Now check that the dot is preceded by digits
+
+ Start := Finish;
+ Finish := Finish - 1;
+
+ while Start >= 1 and then Name_Buffer (Start - 1) in '0' .. '9' loop
+ Start := Start - 1;
+ end loop;
+
+ -- If there is no difits, or if the digits are not preceded by
+ -- the character that precedes a unit index, this is not the ALI file
+ -- of a unit in a multi-unit source.
+
+ if Start > Finish
+ or else Start = 1
+ or else Name_Buffer (Start - 1) /= Multi_Unit_Index_Character
+ then
+ return 0;
+ end if;
+
+ -- Build the index from the digit(s)
+
+ while Start <= Finish loop
+ Result := Result * 10 +
+ Character'Pos (Name_Buffer (Start)) - Character'Pos ('0');
+ Start := Start + 1;
+ end loop;
+
+ return Result;
+ end Unit_Index_Of;
+
+end Makeutl;
diff --git a/gcc/ada/makeutl.ads b/gcc/ada/makeutl.ads
new file mode 100644
index 00000000000..0a3f11a0aaf
--- /dev/null
+++ b/gcc/ada/makeutl.ads
@@ -0,0 +1,117 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- M A K E U T L --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2004 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- --
+-- 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, 59 Temple Place - Suite 330, Boston, --
+-- MA 02111-1307, USA. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Osint;
+with Prj; use Prj;
+with Types; use Types;
+
+with GNAT.OS_Lib; use GNAT.OS_Lib;
+
+package Makeutl is
+
+ type Fail_Proc is access procedure
+ (S1 : String;
+ S2 : String := "";
+ S3 : String := "");
+ Do_Fail : Fail_Proc := Osint.Fail'Access;
+ -- Comment required ???
+
+ function Unit_Index_Of (ALI_File : File_Name_Type) return Int;
+ -- Find the index of a unit in a source file. Return zero if the file
+ -- is not a multi-unit source file.
+
+ function Is_External_Assignment (Argv : String) return Boolean;
+ -- Verify that an external assignment switch is syntactically correct
+ --
+ -- Correct forms are:
+ --
+ -- -Xname=value
+ -- -X"name=other value"
+ --
+ -- Assumptions: 'First = 1, Argv (1 .. 2) = "-X"
+ -- When this function returns True, the external assignment has
+ -- been entered by a call to Prj.Ext.Add, so that in a project
+ -- file, External ("name") will return "value".
+
+ function Linker_Options_Switches (Project : Project_Id) return String_List;
+ -- Comment required ???
+
+ -- Package Mains is used to store the mains specified on the command line
+ -- and to retrieve them when a project file is used, to verify that the
+ -- files exist and that they belong to a project file.
+
+ package Mains is
+
+ -- Mains are stored in a table. An index is used to retrieve the mains
+ -- from the table.
+
+ procedure Add_Main (Name : String);
+ -- Add one main to the table
+
+ procedure Delete;
+ -- Empty the table
+
+ procedure Reset;
+ -- Reset the index to the beginning of the table
+
+ function Next_Main return String;
+ -- Increase the index and return the next main.
+ -- If table is exhausted, return an empty string.
+
+ function Number_Of_Mains return Natural;
+ -- Returns the number of mains added with Add_Main since the last call
+ -- to Delete.
+
+ end Mains;
+
+ procedure Test_If_Relative_Path
+ (Switch : in out String_Access;
+ Parent : String_Access;
+ Including_L_Switch : Boolean := True);
+ -- Test if Switch is a relative search path switch.
+ -- If it is, fail if Parent is null, 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.
+
+ ----------------------
+ -- Marking Routines --
+ ----------------------
+
+ procedure Mark (Source_File : File_Name_Type; Index : Int := 0);
+ -- Mark a unit, identified by its source file and, when Index is not 0,
+ -- the index of the unit in the source file. Marking is used to signal
+ -- that the unit has already been inserted in the Q.
+
+ function Is_Marked
+ (Source_File : File_Name_Type;
+ Index : Int := 0) return Boolean;
+ -- Returns True if the unit was previously marked.
+
+ procedure Delete_All_Marks;
+ -- Remove all file/index couples marked
+
+end Makeutl;
diff --git a/gcc/ada/mdll-utl.adb b/gcc/ada/mdll-utl.adb
index 2608e92f224..80da0ebd921 100644
--- a/gcc/ada/mdll-utl.adb
+++ b/gcc/ada/mdll-utl.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -308,53 +308,60 @@ package body MDLL.Utl is
begin
-- dlltool
- Dlltool_Exec := OS_Lib.Locate_Exec_On_Path (Dlltool_Name);
-
if Dlltool_Exec = null then
- Exceptions.Raise_Exception
- (Tools_Error'Identity, Dlltool_Name & " not found in path");
+ Dlltool_Exec := OS_Lib.Locate_Exec_On_Path (Dlltool_Name);
- elsif Verbose then
- Text_IO.Put_Line ("using " & Dlltool_Exec.all);
+ if Dlltool_Exec = null then
+ Exceptions.Raise_Exception
+ (Tools_Error'Identity, Dlltool_Name & " not found in path");
+
+ elsif Verbose then
+ Text_IO.Put_Line ("using " & Dlltool_Exec.all);
+ end if;
end if;
-- gcc
- Gcc_Exec := OS_Lib.Locate_Exec_On_Path (Gcc_Name);
-
if Gcc_Exec = null then
- Exceptions.Raise_Exception
- (Tools_Error'Identity, Gcc_Name & " not found in path");
+ Gcc_Exec := OS_Lib.Locate_Exec_On_Path (Gcc_Name);
+
+ if Gcc_Exec = null then
+ Exceptions.Raise_Exception
+ (Tools_Error'Identity, Gcc_Name & " not found in path");
- elsif Verbose then
- Text_IO.Put_Line ("using " & Gcc_Exec.all);
+ elsif Verbose then
+ Text_IO.Put_Line ("using " & Gcc_Exec.all);
+ end if;
end if;
-- gnatbind
- Gnatbind_Exec := OS_Lib.Locate_Exec_On_Path (Gnatbind_Name);
-
if Gnatbind_Exec = null then
- Exceptions.Raise_Exception
- (Tools_Error'Identity, Gnatbind_Name & " not found in path");
+ Gnatbind_Exec := OS_Lib.Locate_Exec_On_Path (Gnatbind_Name);
+
+ if Gnatbind_Exec = null then
+ Exceptions.Raise_Exception
+ (Tools_Error'Identity, Gnatbind_Name & " not found in path");
- elsif Verbose then
- Text_IO.Put_Line ("using " & Gnatbind_Exec.all);
+ elsif Verbose then
+ Text_IO.Put_Line ("using " & Gnatbind_Exec.all);
+ end if;
end if;
-- gnatlink
- Gnatlink_Exec := OS_Lib.Locate_Exec_On_Path (Gnatlink_Name);
-
if Gnatlink_Exec = null then
- Exceptions.Raise_Exception
- (Tools_Error'Identity, Gnatlink_Name & " not found in path");
+ Gnatlink_Exec := OS_Lib.Locate_Exec_On_Path (Gnatlink_Name);
- elsif Verbose then
- Text_IO.Put_Line ("using " & Gnatlink_Exec.all);
- Text_IO.New_Line;
- end if;
+ if Gnatlink_Exec = null then
+ Exceptions.Raise_Exception
+ (Tools_Error'Identity, Gnatlink_Name & " not found in path");
+ elsif Verbose then
+ Text_IO.Put_Line ("using " & Gnatlink_Exec.all);
+ Text_IO.New_Line;
+ end if;
+ end if;
end Locate;
end MDLL.Utl;
diff --git a/gcc/ada/misc.c b/gcc/ada/misc.c
index 7be3b5d6a98..dca2b0fe9f2 100644
--- a/gcc/ada/misc.c
+++ b/gcc/ada/misc.c
@@ -320,6 +320,9 @@ gnat_init_options (unsigned int argc, const char **argv)
save_argc = argc;
save_argv = argv;
+ /* Uninitialized really means uninitialized in Ada. */
+ flag_zero_initialized_in_bss = 0;
+
return CL_Ada;
}
@@ -671,40 +674,6 @@ make_transform_expr (Node_Id gnat_node)
return gnu_result;
}
-/* Update the setjmp buffer BUF with the current stack pointer. We assume
- here that a __builtin_setjmp was done to BUF. */
-
-void
-update_setjmp_buf (tree buf)
-{
- enum machine_mode sa_mode = Pmode;
- rtx stack_save;
-
-#ifdef HAVE_save_stack_nonlocal
- if (HAVE_save_stack_nonlocal)
- sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
-#endif
-#ifdef STACK_SAVEAREA_MODE
- sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
-#endif
-
- stack_save
- = gen_rtx_MEM (sa_mode,
- memory_address
- (sa_mode,
- plus_constant (expand_expr
- (build_unary_op (ADDR_EXPR, NULL_TREE, buf),
- NULL_RTX, VOIDmode, 0),
- 2 * GET_MODE_SIZE (Pmode))));
-
-#ifdef HAVE_setjmp
- if (HAVE_setjmp)
- emit_insn (gen_setjmp ());
-#endif
-
- emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
-}
-
/* These routines are used in conjunction with GCC exception handling. */
/* Map compile-time to run-time tree for GCC exception handling scheme. */
@@ -1006,4 +975,3 @@ fp_size_to_prec (int size)
abort ();
}
-
diff --git a/gcc/ada/mlib-prj.adb b/gcc/ada/mlib-prj.adb
index 612845c7f1f..b55d801388d 100644
--- a/gcc/ada/mlib-prj.adb
+++ b/gcc/ada/mlib-prj.adb
@@ -308,9 +308,6 @@ package body MLib.Prj is
Libdecgnat_Needed : Boolean := False;
-- On OpenVMS, set to True if library needs to be linked with libdecgnat
- Check_Libdecgnat : Boolean := Hostparm.OpenVMS;
- -- Set to False if package Dec is part of the library sources.
-
Data : Project_Data := Projects.Table (For_Project);
Object_Directory_Path : constant String :=
@@ -375,8 +372,7 @@ package body MLib.Prj is
-- to link with -lgnarl (this is the case when there is a dependency
-- on s-osinte.ads). On OpenVMS, set Libdecgnat_Needed if the ALI file
-- indicates that there is a need to link with -ldecgnat (this is the
- -- case when there is a dependency on dec.ads, except when it is the
- -- DEC library, the one that contains package DEC).
+ -- case when there is a dependency on dec.ads).
procedure Process (The_ALI : File_Name_Type);
-- Check if the closure of a library unit which is or should be in the
@@ -509,16 +505,8 @@ package body MLib.Prj is
Id : ALI.ALI_Id;
begin
- -- On OpenVMS, if we have package DEC, it means this is the DEC lib:
- -- no need to link with itself.
-
- if Check_Libdecgnat and then ALI_File = "dec.ali" then
- Check_Libdecgnat := False;
- Libdecgnat_Needed := False;
- end if;
-
if not Libgnarl_Needed or
- (Check_Libdecgnat and then (not Libdecgnat_Needed))
+ (Hostparm.OpenVMS and then (not Libdecgnat_Needed))
then
-- Scan the ALI file
@@ -535,7 +523,7 @@ package body MLib.Prj is
Read_Lines => "D");
Free (Text);
- -- Look for s-osinte.ads and dec.ads in the dependencies
+ -- Look for s-osinte.ads in the dependencies
for Index in ALI.ALIs.Table (Id).First_Sdep ..
ALI.ALIs.Table (Id).Last_Sdep
@@ -543,7 +531,7 @@ package body MLib.Prj is
if ALI.Sdep.Table (Index).Sfile = S_Osinte_Ads then
Libgnarl_Needed := True;
- elsif Check_Libdecgnat and then
+ elsif Hostparm.OpenVMS and then
ALI.Sdep.Table (Index).Sfile = S_Dec_Ads
then
Libdecgnat_Needed := True;
@@ -827,7 +815,9 @@ package body MLib.Prj is
if Defaults /= No_Array_Element then
Switches :=
Value_Of
- (Index => Name_Ada, In_Array => Defaults);
+ (Index => Name_Ada,
+ Src_Index => 0,
+ In_Array => Defaults);
if not Switches.Default then
Switch := Switches.Values;
@@ -1950,10 +1940,7 @@ package body MLib.Prj is
end if;
Status := fclose (Fd);
-
- -- It is safe to ignore any error when closing, because the file was
- -- only opened for reading.
-
+ -- Is it really right to ignore any close error ???
end Process_Binder_File;
------------------
diff --git a/gcc/ada/mlib-tgt-aix.adb b/gcc/ada/mlib-tgt-aix.adb
new file mode 100644
index 00000000000..c95d64893a4
--- /dev/null
+++ b/gcc/ada/mlib-tgt-aix.adb
@@ -0,0 +1,391 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- M L I B . T G T --
+-- (AIX Version) --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2003-2004, Ada Core Technologies, 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- --
+-- 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, 59 Temple Place - Suite 330, Boston, --
+-- MA 02111-1307, USA. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides a set of target dependent routines to build
+-- static, dynamic or relocatable libraries.
+
+-- This is the AIX version of the body.
+
+with Ada.Strings.Fixed; use Ada.Strings.Fixed;
+with GNAT.OS_Lib; use GNAT.OS_Lib;
+
+with MLib.Fil;
+with MLib.Utl;
+with Namet; use Namet;
+with Osint; use Osint;
+with Opt;
+with Output; use Output;
+with Prj.Com;
+with Prj.Util; use Prj.Util;
+
+package body MLib.Tgt is
+
+ No_Arguments : aliased Argument_List := (1 .. 0 => null);
+ Empty_Argument_List : constant Argument_List_Access := No_Arguments'Access;
+
+ Wl_Initfini_String : constant String := "-Wl,-binitfini:";
+
+ Init_Fini_List : constant Argument_List_Access :=
+ new Argument_List'(1 => null);
+ -- Used to put switch for automatic elaboration/finalization
+
+ Bexpall : aliased String := "-Wl,-bexpall";
+ Bexpall_Option : constant String_Access := Bexpall'Access;
+ -- The switch to export all symbols
+
+ Lpthreads : aliased String := "-lpthreads";
+ Native_Thread_Options : aliased Argument_List := (1 => Lpthreads'Access);
+ -- The switch to use when linking a library against libgnarl when using
+ -- Native threads.
+
+ Lgthreads : aliased String := "-lgthreads";
+ Lmalloc : aliased String := "-lmalloc";
+ FSU_Thread_Options : aliased Argument_List :=
+ (1 => Lgthreads'Access, 2 => Lmalloc'Access);
+ -- The switches to use when linking a library against libgnarl when using
+ -- FSU threads.
+
+ Thread_Options : Argument_List_Access := null;
+ -- Designate the thread switches to used when linking a library against
+ -- libgnarl. Depends on the thread library (Native or FSU). Resolved for
+ -- the first library linked against libgnarl.
+
+ ---------------------
+ -- Archive_Builder --
+ ---------------------
+
+ function Archive_Builder return String is
+ begin
+ return "ar";
+ end Archive_Builder;
+
+ -----------------------------
+ -- Archive_Builder_Options --
+ -----------------------------
+
+ function Archive_Builder_Options return String_List_Access is
+ begin
+ return new String_List'(1 => new String'("cr"));
+ end Archive_Builder_Options;
+
+ -----------------
+ -- Archive_Ext --
+ -----------------
+
+ function Archive_Ext return String is
+ begin
+ return "a";
+ end Archive_Ext;
+
+ ---------------------
+ -- Archive_Indexer --
+ ---------------------
+
+ function Archive_Indexer return String is
+ begin
+ return "ranlib";
+ end Archive_Indexer;
+
+ ---------------------------
+ -- Build_Dynamic_Library --
+ ---------------------------
+
+ procedure Build_Dynamic_Library
+ (Ofiles : Argument_List;
+ Foreign : Argument_List;
+ Afiles : Argument_List;
+ Options : Argument_List;
+ Interfaces : Argument_List;
+ Lib_Filename : String;
+ Lib_Dir : String;
+ Symbol_Data : Symbol_Record;
+ Driver_Name : Name_Id := No_Name;
+ Lib_Address : String := "";
+ Lib_Version : String := "";
+ Relocatable : Boolean := False;
+ Auto_Init : Boolean := False)
+ is
+ pragma Unreferenced (Foreign);
+ pragma Unreferenced (Afiles);
+ pragma Unreferenced (Interfaces);
+ pragma Unreferenced (Symbol_Data);
+ pragma Unreferenced (Lib_Address);
+ pragma Unreferenced (Lib_Version);
+ pragma Unreferenced (Relocatable);
+
+ Lib_File : constant String :=
+ Lib_Dir & Directory_Separator & "lib" &
+ MLib.Fil.Ext_To (Lib_Filename, DLL_Ext);
+ -- The file name of the library
+
+ Init_Fini : Argument_List_Access := Empty_Argument_List;
+ -- The switch for automatic initialization of Stand-Alone Libraries.
+ -- Changed to a real switch when Auto_Init is True.
+
+ Options_2 : Argument_List_Access := Empty_Argument_List;
+ -- Changed to the thread options, if -lgnarl is specified
+
+ begin
+ if Opt.Verbose_Mode then
+ Write_Str ("building relocatable shared library ");
+ Write_Line (Lib_File);
+ end if;
+
+ -- If specified, add automatic elaboration/finalization
+
+ if Auto_Init then
+ Init_Fini := Init_Fini_List;
+ Init_Fini (1) :=
+ new String'(Wl_Initfini_String & Lib_Filename & "init:" &
+ Lib_Filename & "final");
+ end if;
+
+ -- Look for -lgnarl in Options. If found, set the thread options.
+
+ for J in Options'Range loop
+ if Options (J).all = "-lgnarl" then
+
+ -- If Thread_Options is null, read s-osinte.ads to discover the
+ -- thread library and set Thread_Options accordingly.
+
+ if Thread_Options = null then
+ declare
+ File : Text_File;
+ Line : String (1 .. 100);
+ Last : Natural;
+
+ begin
+ Open
+ (File, Include_Dir_Default_Prefix & "/s-osinte.ads");
+
+ while not End_Of_File (File) loop
+ Get_Line (File, Line, Last);
+
+ if Index (Line (1 .. Last), "-lpthreads") /= 0 then
+ Thread_Options := Native_Thread_Options'Access;
+ exit;
+
+ elsif Index (Line (1 .. Last), "-lgthreads") /= 0 then
+ Thread_Options := FSU_Thread_Options'Access;
+ exit;
+ end if;
+ end loop;
+
+ Close (File);
+
+ if Thread_Options = null then
+ Prj.Com.Fail ("cannot find the thread library in use");
+ end if;
+
+ exception
+ when others =>
+ Prj.Com.Fail ("cannot open s-osinte.ads");
+ end;
+ end if;
+
+ Options_2 := Thread_Options;
+ exit;
+ end if;
+ end loop;
+
+ -- Finally, call GCC (or the driver specified) to build the library
+
+ MLib.Utl.Gcc
+ (Output_File => Lib_File,
+ Objects => Ofiles,
+ Options => Options & Bexpall_Option & Init_Fini.all,
+ Driver_Name => Driver_Name,
+ Options_2 => Options_2.all);
+ end Build_Dynamic_Library;
+
+ -------------------------
+ -- Default_DLL_Address --
+ -------------------------
+
+ function Default_DLL_Address return String is
+ begin
+ return "";
+ end Default_DLL_Address;
+
+ -------------
+ -- DLL_Ext --
+ -------------
+
+ function DLL_Ext return String is
+ begin
+ return "a";
+ end DLL_Ext;
+
+ --------------------
+ -- Dynamic_Option --
+ --------------------
+
+ function Dynamic_Option return String is
+ begin
+ return "-shared";
+ end Dynamic_Option;
+
+ -------------------
+ -- Is_Object_Ext --
+ -------------------
+
+ function Is_Object_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".o";
+ end Is_Object_Ext;
+
+ --------------
+ -- Is_C_Ext --
+ --------------
+
+ function Is_C_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".c";
+ end Is_C_Ext;
+
+ --------------------
+ -- Is_Archive_Ext --
+ --------------------
+
+ function Is_Archive_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".a";
+ end Is_Archive_Ext;
+
+ -------------
+ -- Libgnat --
+ -------------
+
+ function Libgnat return String is
+ begin
+ return "libgnat.a";
+ end Libgnat;
+
+ ------------------------
+ -- Library_Exists_For --
+ ------------------------
+
+ function Library_Exists_For (Project : Project_Id) return Boolean is
+ begin
+ if not Projects.Table (Project).Library then
+ Prj.Com.Fail ("INTERNAL ERROR: Library_Exists_For called " &
+ "for non library project");
+ return False;
+
+ else
+ declare
+ Lib_Dir : constant String :=
+ Get_Name_String
+ (Projects.Table (Project).Library_Dir);
+ Lib_Name : constant String :=
+ Get_Name_String
+ (Projects.Table (Project).Library_Name);
+
+ begin
+ if Projects.Table (Project).Library_Kind = Static then
+ return Is_Regular_File
+ (Lib_Dir & Directory_Separator & "lib" &
+ Fil.Ext_To (Lib_Name, Archive_Ext));
+
+ else
+ return Is_Regular_File
+ (Lib_Dir & Directory_Separator & "lib" &
+ Fil.Ext_To (Lib_Name, DLL_Ext));
+ end if;
+ end;
+ end if;
+ end Library_Exists_For;
+
+ ---------------------------
+ -- Library_File_Name_For --
+ ---------------------------
+
+ function Library_File_Name_For (Project : Project_Id) return Name_Id is
+ begin
+ if not Projects.Table (Project).Library then
+ Prj.Com.Fail ("INTERNAL ERROR: Library_File_Name_For called " &
+ "for non library project");
+ return No_Name;
+
+ else
+ declare
+ Lib_Name : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Name);
+
+ begin
+ Name_Len := 3;
+ Name_Buffer (1 .. Name_Len) := "lib";
+
+ if Projects.Table (Project).Library_Kind = Static then
+ Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, Archive_Ext));
+
+ else
+ Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, DLL_Ext));
+ end if;
+
+ return Name_Find;
+ end;
+ end if;
+ end Library_File_Name_For;
+
+ ----------------
+ -- Object_Ext --
+ ----------------
+
+ function Object_Ext return String is
+ begin
+ return "o";
+ end Object_Ext;
+
+ ----------------
+ -- PIC_Option --
+ ----------------
+
+ function PIC_Option return String is
+ begin
+ return "-fPIC";
+ end PIC_Option;
+
+ -----------------------------------------------
+ -- Standalone_Library_Auto_Init_Is_Supported --
+ -----------------------------------------------
+
+ function Standalone_Library_Auto_Init_Is_Supported return Boolean is
+ begin
+ return True;
+ end Standalone_Library_Auto_Init_Is_Supported;
+
+ ---------------------------
+ -- Support_For_Libraries --
+ ---------------------------
+
+ function Support_For_Libraries return Library_Support is
+ begin
+ return Full;
+ end Support_For_Libraries;
+
+end MLib.Tgt;
diff --git a/gcc/ada/mlib-tgt-hpux.adb b/gcc/ada/mlib-tgt-hpux.adb
new file mode 100644
index 00000000000..4eb2934cb51
--- /dev/null
+++ b/gcc/ada/mlib-tgt-hpux.adb
@@ -0,0 +1,368 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- M L I B . T G T --
+-- (HP-UX Version) --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2003-2004, Ada Core Technologies, 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- --
+-- 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, 59 Temple Place - Suite 330, Boston, --
+-- MA 02111-1307, USA. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides a set of target dependent routines to build
+-- libraries (static only on HP-UX).
+
+-- This is the HP-UX version of the body.
+
+with MLib.Fil;
+with MLib.Utl;
+with Namet; use Namet;
+with Opt;
+with Output; use Output;
+with Prj.Com;
+with System;
+
+package body MLib.Tgt is
+
+ No_Arguments : aliased Argument_List := (1 .. 0 => null);
+ Empty_Argument_List : constant Argument_List_Access := No_Arguments'Access;
+
+ Wl_Init_String : aliased String := "-Wl,+init";
+ Wl_Init : constant String_Access := Wl_Init_String'Access;
+ Wl_Fini_String : aliased String := "-Wl,+fini";
+ Wl_Fini : constant String_Access := Wl_Fini_String'Access;
+
+ Init_Fini_List : constant Argument_List_Access :=
+ new Argument_List'(1 => Wl_Init,
+ 2 => null,
+ 3 => Wl_Fini,
+ 4 => null);
+ -- Used to put switches for automatic elaboration/finalization
+ ---------------------
+ -- Archive_Builder --
+ ---------------------
+
+ function Archive_Builder return String is
+ begin
+ return "ar";
+ end Archive_Builder;
+
+ -----------------------------
+ -- Archive_Builder_Options --
+ -----------------------------
+
+ function Archive_Builder_Options return String_List_Access is
+ begin
+ return new String_List'(1 => new String'("cr"));
+ end Archive_Builder_Options;
+
+ -----------------
+ -- Archive_Ext --
+ -----------------
+
+ function Archive_Ext return String is
+ begin
+ return "a";
+ end Archive_Ext;
+
+ ---------------------
+ -- Archive_Indexer --
+ ---------------------
+
+ function Archive_Indexer return String is
+ begin
+ return "ranlib";
+ end Archive_Indexer;
+
+ ---------------------------
+ -- Build_Dynamic_Library --
+ ---------------------------
+
+ procedure Build_Dynamic_Library
+ (Ofiles : Argument_List;
+ Foreign : Argument_List;
+ Afiles : Argument_List;
+ Options : Argument_List;
+ Interfaces : Argument_List;
+ Lib_Filename : String;
+ Lib_Dir : String;
+ Symbol_Data : Symbol_Record;
+ Driver_Name : Name_Id := No_Name;
+ Lib_Address : String := "";
+ Lib_Version : String := "";
+ Relocatable : Boolean := False;
+ Auto_Init : Boolean := False)
+ is
+ pragma Unreferenced (Foreign);
+ pragma Unreferenced (Afiles);
+ pragma Unreferenced (Interfaces);
+ pragma Unreferenced (Symbol_Data);
+ pragma Unreferenced (Lib_Address);
+ pragma Unreferenced (Relocatable);
+
+ Lib_File : constant String :=
+ Lib_Dir & Directory_Separator & "lib" &
+ MLib.Fil.Ext_To (Lib_Filename, DLL_Ext);
+
+ Version_Arg : String_Access;
+ Symbolic_Link_Needed : Boolean := False;
+
+ Init_Fini : Argument_List_Access := Empty_Argument_List;
+
+ Common_Options : constant Argument_List :=
+ Options & new String'(PIC_Option);
+ -- Common set of options to the gcc command performing the link.
+ -- On HPUX, this command eventually resorts to collect2, which may
+ -- generate a C file and compile it on the fly. This compilation shall
+ -- also generate position independant code for the final link to
+ -- succeed.
+ begin
+ if Opt.Verbose_Mode then
+ Write_Str ("building relocatable shared library ");
+ Write_Line (Lib_File);
+ end if;
+
+ -- If specified, add automatic elaboration/finalization
+ if Auto_Init then
+ Init_Fini := Init_Fini_List;
+ Init_Fini (2) := new String'("-Wl," & Lib_Filename & "init");
+ Init_Fini (4) := new String'("-Wl," & Lib_Filename & "final");
+ end if;
+
+ if Lib_Version = "" then
+ MLib.Utl.Gcc
+ (Output_File => Lib_File,
+ Objects => Ofiles,
+ Options => Common_Options & Init_Fini.all,
+ Driver_Name => Driver_Name);
+
+ else
+ Version_Arg := new String'("-Wl,+h," & Lib_Version);
+
+ if Is_Absolute_Path (Lib_Version) then
+ MLib.Utl.Gcc
+ (Output_File => Lib_Version,
+ Objects => Ofiles,
+ Options => Common_Options & Version_Arg & Init_Fini.all,
+ Driver_Name => Driver_Name);
+ Symbolic_Link_Needed := Lib_Version /= Lib_File;
+
+ else
+ MLib.Utl.Gcc
+ (Output_File => Lib_Dir & Directory_Separator & Lib_Version,
+ Objects => Ofiles,
+ Options => Common_Options & Version_Arg & Init_Fini.all,
+ Driver_Name => Driver_Name);
+ Symbolic_Link_Needed :=
+ Lib_Dir & Directory_Separator & Lib_Version /= Lib_File;
+ end if;
+
+ if Symbolic_Link_Needed then
+ declare
+ Success : Boolean;
+ Oldpath : String (1 .. Lib_Version'Length + 1);
+ Newpath : String (1 .. Lib_File'Length + 1);
+
+ Result : Integer;
+ pragma Unreferenced (Result);
+
+ function Symlink
+ (Oldpath : System.Address;
+ Newpath : System.Address) return Integer;
+ pragma Import (C, Symlink, "__gnat_symlink");
+
+ begin
+ Oldpath (1 .. Lib_Version'Length) := Lib_Version;
+ Oldpath (Oldpath'Last) := ASCII.NUL;
+ Newpath (1 .. Lib_File'Length) := Lib_File;
+ Newpath (Newpath'Last) := ASCII.NUL;
+
+ Delete_File (Lib_File, Success);
+
+ Result := Symlink (Oldpath'Address, Newpath'Address);
+ end;
+ end if;
+ end if;
+ end Build_Dynamic_Library;
+
+ -------------------------
+ -- Default_DLL_Address --
+ -------------------------
+
+ function Default_DLL_Address return String is
+ begin
+ return "";
+ end Default_DLL_Address;
+
+ -------------
+ -- DLL_Ext --
+ -------------
+
+ function DLL_Ext return String is
+ begin
+ return "sl";
+ end DLL_Ext;
+
+ --------------------
+ -- Dynamic_Option --
+ --------------------
+
+ function Dynamic_Option return String is
+ begin
+ return "-shared";
+ end Dynamic_Option;
+
+ -------------------
+ -- Is_Object_Ext --
+ -------------------
+
+ function Is_Object_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".o";
+ end Is_Object_Ext;
+
+ --------------
+ -- Is_C_Ext --
+ --------------
+
+ function Is_C_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".c";
+ end Is_C_Ext;
+
+ --------------------
+ -- Is_Archive_Ext --
+ --------------------
+
+ function Is_Archive_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".a" or else Ext = ".so";
+ end Is_Archive_Ext;
+
+ -------------
+ -- Libgnat --
+ -------------
+
+ function Libgnat return String is
+ begin
+ return "libgnat.a";
+ end Libgnat;
+
+ ------------------------
+ -- Library_Exists_For --
+ ------------------------
+
+ function Library_Exists_For (Project : Project_Id) return Boolean is
+ begin
+ if not Projects.Table (Project).Library then
+ Prj.Com.Fail ("INTERNAL ERROR: Library_Exists_For called " &
+ "for non library project");
+ return False;
+
+ else
+ declare
+ Lib_Dir : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Dir);
+ Lib_Name : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Name);
+
+ begin
+ if Projects.Table (Project).Library_Kind = Static then
+ return Is_Regular_File
+ (Lib_Dir & Directory_Separator & "lib" &
+ Fil.Ext_To (Lib_Name, Archive_Ext));
+
+ else
+ return Is_Regular_File
+ (Lib_Dir & Directory_Separator & "lib" &
+ Fil.Ext_To (Lib_Name, DLL_Ext));
+ end if;
+ end;
+ end if;
+ end Library_Exists_For;
+
+ ---------------------------
+ -- Library_File_Name_For --
+ ---------------------------
+
+ function Library_File_Name_For (Project : Project_Id) return Name_Id is
+ begin
+ if not Projects.Table (Project).Library then
+ Prj.Com.Fail ("INTERNAL ERROR: Library_File_Name_For called " &
+ "for non library project");
+ return No_Name;
+
+ else
+ declare
+ Lib_Name : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Name);
+
+ begin
+ Name_Len := 3;
+ Name_Buffer (1 .. Name_Len) := "lib";
+
+ if Projects.Table (Project).Library_Kind = Static then
+ Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, Archive_Ext));
+
+ else
+ Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, DLL_Ext));
+ end if;
+
+ return Name_Find;
+ end;
+ end if;
+ end Library_File_Name_For;
+
+ ----------------
+ -- Object_Ext --
+ ----------------
+
+ function Object_Ext return String is
+ begin
+ return "o";
+ end Object_Ext;
+
+ ----------------
+ -- PIC_Option --
+ ----------------
+
+ function PIC_Option return String is
+ begin
+ return "-fPIC";
+ end PIC_Option;
+
+ -----------------------------------------------
+ -- Standalone_Library_Auto_Init_Is_Supported --
+ -----------------------------------------------
+
+ function Standalone_Library_Auto_Init_Is_Supported return Boolean is
+ begin
+ return True;
+ end Standalone_Library_Auto_Init_Is_Supported;
+
+ ---------------------------
+ -- Support_For_Libraries --
+ ---------------------------
+
+ function Support_For_Libraries return Library_Support is
+ begin
+ return Full;
+ end Support_For_Libraries;
+
+end MLib.Tgt;
diff --git a/gcc/ada/mlib-tgt-irix.adb b/gcc/ada/mlib-tgt-irix.adb
new file mode 100644
index 00000000000..c18819918dd
--- /dev/null
+++ b/gcc/ada/mlib-tgt-irix.adb
@@ -0,0 +1,363 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- M L I B . T G T --
+-- (IRIX Version) --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2003-2004, Ada Core Technologies, 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- --
+-- 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, 59 Temple Place - Suite 330, Boston, --
+-- MA 02111-1307, USA. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides a set of target dependent routines to build
+-- static, dynamic and shared libraries.
+
+-- This is the IRIX version of the body.
+
+with MLib.Fil;
+with MLib.Utl;
+with Namet; use Namet;
+with Opt;
+with Output; use Output;
+with Prj.Com;
+with System;
+
+package body MLib.Tgt is
+
+ No_Arguments : aliased Argument_List := (1 .. 0 => null);
+ Empty_Argument_List : constant Argument_List_Access := No_Arguments'Access;
+
+ Wl_Init_String : aliased String := "-Wl,-init";
+ Wl_Init : constant String_Access := Wl_Init_String'Access;
+ Wl_Fini_String : aliased String := "-Wl,-fini";
+ Wl_Fini : constant String_Access := Wl_Fini_String'Access;
+
+ Init_Fini_List : constant Argument_List_Access :=
+ new Argument_List'(1 => Wl_Init,
+ 2 => null,
+ 3 => Wl_Fini,
+ 4 => null);
+ -- Used to put switches for automatic elaboration/finalization
+
+ ---------------------
+ -- Archive_Builder --
+ ---------------------
+
+ function Archive_Builder return String is
+ begin
+ return "ar";
+ end Archive_Builder;
+
+ -----------------------------
+ -- Archive_Builder_Options --
+ -----------------------------
+
+ function Archive_Builder_Options return String_List_Access is
+ begin
+ return new String_List'(1 => new String'("cr"));
+ end Archive_Builder_Options;
+
+ -----------------
+ -- Archive_Ext --
+ -----------------
+
+ function Archive_Ext return String is
+ begin
+ return "a";
+ end Archive_Ext;
+
+ ---------------------
+ -- Archive_Indexer --
+ ---------------------
+
+ function Archive_Indexer return String is
+ begin
+ return "ranlib";
+ end Archive_Indexer;
+
+ ---------------------------
+ -- Build_Dynamic_Library --
+ ---------------------------
+
+ procedure Build_Dynamic_Library
+ (Ofiles : Argument_List;
+ Foreign : Argument_List;
+ Afiles : Argument_List;
+ Options : Argument_List;
+ Interfaces : Argument_List;
+ Lib_Filename : String;
+ Lib_Dir : String;
+ Symbol_Data : Symbol_Record;
+ Driver_Name : Name_Id := No_Name;
+ Lib_Address : String := "";
+ Lib_Version : String := "";
+ Relocatable : Boolean := False;
+ Auto_Init : Boolean := False)
+ is
+ pragma Unreferenced (Foreign);
+ pragma Unreferenced (Afiles);
+ pragma Unreferenced (Interfaces);
+ pragma Unreferenced (Symbol_Data);
+ pragma Unreferenced (Lib_Address);
+ pragma Unreferenced (Relocatable);
+
+ Lib_File : constant String :=
+ Lib_Dir & Directory_Separator & "lib" &
+ MLib.Fil.Ext_To (Lib_Filename, DLL_Ext);
+
+ Version_Arg : String_Access;
+ Symbolic_Link_Needed : Boolean := False;
+
+ Init_Fini : Argument_List_Access := Empty_Argument_List;
+
+ begin
+ if Opt.Verbose_Mode then
+ Write_Str ("building relocatable shared library ");
+ Write_Line (Lib_File);
+ end if;
+
+ -- If specified, add automatic elaboration/finalization
+ if Auto_Init then
+ Init_Fini := Init_Fini_List;
+ Init_Fini (2) := new String'("-Wl," & Lib_Filename & "init");
+ Init_Fini (4) := new String'("-Wl," & Lib_Filename & "final");
+ end if;
+
+ if Lib_Version = "" then
+ MLib.Utl.Gcc
+ (Output_File => Lib_File,
+ Objects => Ofiles,
+ Options => Options & Init_Fini.all,
+ Driver_Name => Driver_Name);
+
+ else
+ Version_Arg := new String'("-Wl,-soname," & Lib_Version);
+
+ if Is_Absolute_Path (Lib_Version) then
+ MLib.Utl.Gcc
+ (Output_File => Lib_Version,
+ Objects => Ofiles,
+ Options => Options & Version_Arg & Init_Fini.all,
+ Driver_Name => Driver_Name);
+ Symbolic_Link_Needed := Lib_Version /= Lib_File;
+
+ else
+ MLib.Utl.Gcc
+ (Output_File => Lib_Dir & Directory_Separator & Lib_Version,
+ Objects => Ofiles,
+ Options => Options & Version_Arg & Init_Fini.all,
+ Driver_Name => Driver_Name);
+ Symbolic_Link_Needed :=
+ Lib_Dir & Directory_Separator & Lib_Version /= Lib_File;
+ end if;
+
+ if Symbolic_Link_Needed then
+ declare
+ Success : Boolean;
+ Oldpath : String (1 .. Lib_Version'Length + 1);
+ Newpath : String (1 .. Lib_File'Length + 1);
+
+ Result : Integer;
+ pragma Unreferenced (Result);
+
+ function Symlink
+ (Oldpath : System.Address;
+ Newpath : System.Address)
+ return Integer;
+ pragma Import (C, Symlink, "__gnat_symlink");
+
+ begin
+ Oldpath (1 .. Lib_Version'Length) := Lib_Version;
+ Oldpath (Oldpath'Last) := ASCII.NUL;
+ Newpath (1 .. Lib_File'Length) := Lib_File;
+ Newpath (Newpath'Last) := ASCII.NUL;
+
+ Delete_File (Lib_File, Success);
+
+ Result := Symlink (Oldpath'Address, Newpath'Address);
+ end;
+ end if;
+ end if;
+ end Build_Dynamic_Library;
+
+ -------------------------
+ -- Default_DLL_Address --
+ -------------------------
+
+ function Default_DLL_Address return String is
+ begin
+ return "";
+ end Default_DLL_Address;
+
+ -------------
+ -- DLL_Ext --
+ -------------
+
+ function DLL_Ext return String is
+ begin
+ return "so";
+ end DLL_Ext;
+
+ --------------------
+ -- Dynamic_Option --
+ --------------------
+
+ function Dynamic_Option return String is
+ begin
+ return "-shared";
+ end Dynamic_Option;
+
+ -------------------
+ -- Is_Object_Ext --
+ -------------------
+
+ function Is_Object_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".o";
+ end Is_Object_Ext;
+
+ --------------
+ -- Is_C_Ext --
+ --------------
+
+ function Is_C_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".c";
+ end Is_C_Ext;
+
+ --------------------
+ -- Is_Archive_Ext --
+ --------------------
+
+ function Is_Archive_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".a" or else Ext = ".so";
+ end Is_Archive_Ext;
+
+ -------------
+ -- Libgnat --
+ -------------
+
+ function Libgnat return String is
+ begin
+ return "libgnat.a";
+ end Libgnat;
+
+ ------------------------
+ -- Library_Exists_For --
+ ------------------------
+
+ function Library_Exists_For (Project : Project_Id) return Boolean is
+ begin
+ if not Projects.Table (Project).Library then
+ Prj.Com.Fail ("INTERNAL ERROR: Library_Exists_For called " &
+ "for non library project");
+ return False;
+
+ else
+ declare
+ Lib_Dir : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Dir);
+ Lib_Name : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Name);
+
+ begin
+ if Projects.Table (Project).Library_Kind = Static then
+ return Is_Regular_File
+ (Lib_Dir & Directory_Separator & "lib" &
+ Fil.Ext_To (Lib_Name, Archive_Ext));
+
+ else
+ return Is_Regular_File
+ (Lib_Dir & Directory_Separator & "lib" &
+ Fil.Ext_To (Lib_Name, DLL_Ext));
+ end if;
+ end;
+ end if;
+ end Library_Exists_For;
+
+ ---------------------------
+ -- Library_File_Name_For --
+ ---------------------------
+
+ function Library_File_Name_For (Project : Project_Id) return Name_Id is
+ begin
+ if not Projects.Table (Project).Library then
+ Prj.Com.Fail ("INTERNAL ERROR: Library_File_Name_For called " &
+ "for non library project");
+ return No_Name;
+
+ else
+ declare
+ Lib_Name : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Name);
+
+ begin
+ Name_Len := 3;
+ Name_Buffer (1 .. Name_Len) := "lib";
+
+ if Projects.Table (Project).Library_Kind = Static then
+ Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, Archive_Ext));
+
+ else
+ Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, DLL_Ext));
+ end if;
+
+ return Name_Find;
+ end;
+ end if;
+ end Library_File_Name_For;
+
+ ----------------
+ -- Object_Ext --
+ ----------------
+
+ function Object_Ext return String is
+ begin
+ return "o";
+ end Object_Ext;
+
+ ----------------
+ -- PIC_Option --
+ ----------------
+
+ function PIC_Option return String is
+ begin
+ return "-fPIC";
+ end PIC_Option;
+
+ -----------------------------------------------
+ -- Standalone_Library_Auto_Init_Is_Supported --
+ -----------------------------------------------
+
+ function Standalone_Library_Auto_Init_Is_Supported return Boolean is
+ begin
+ return True;
+ end Standalone_Library_Auto_Init_Is_Supported;
+
+ ---------------------------
+ -- Support_For_Libraries --
+ ---------------------------
+
+ function Support_For_Libraries return Library_Support is
+ begin
+ return Full;
+ end Support_For_Libraries;
+
+end MLib.Tgt;
diff --git a/gcc/ada/mlib-tgt-linux.adb b/gcc/ada/mlib-tgt-linux.adb
new file mode 100644
index 00000000000..00ab3928b79
--- /dev/null
+++ b/gcc/ada/mlib-tgt-linux.adb
@@ -0,0 +1,365 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- M L I B . T G T --
+-- (GNU/Linux Version) --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2001-2004, 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- --
+-- 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, 59 Temple Place - Suite 330, Boston, --
+-- MA 02111-1307, USA. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides a set of target dependent routines to build
+-- static, dynamic and shared libraries.
+
+-- This is the GNU/Linux version of the body.
+
+with MLib.Fil;
+with MLib.Utl;
+with Namet; use Namet;
+with Opt;
+with Output; use Output;
+with Prj.Com;
+with System;
+
+package body MLib.Tgt is
+
+ use GNAT;
+ use MLib;
+
+ No_Arguments : aliased Argument_List := (1 .. 0 => null);
+ Empty_Argument_List : constant Argument_List_Access := No_Arguments'Access;
+
+ Wl_Init_String : aliased String := "-Wl,-init";
+ Wl_Init : constant String_Access := Wl_Init_String'Access;
+ Wl_Fini_String : aliased String := "-Wl,-fini";
+ Wl_Fini : constant String_Access := Wl_Fini_String'Access;
+
+ Init_Fini_List : constant Argument_List_Access :=
+ new Argument_List'(1 => Wl_Init,
+ 2 => null,
+ 3 => Wl_Fini,
+ 4 => null);
+ -- Used to put switches for automatic elaboration/finalization
+
+ ---------------------
+ -- Archive_Builder --
+ ---------------------
+
+ function Archive_Builder return String is
+ begin
+ return "ar";
+ end Archive_Builder;
+
+ -----------------------------
+ -- Archive_Builder_Options --
+ -----------------------------
+
+ function Archive_Builder_Options return String_List_Access is
+ begin
+ return new String_List'(1 => new String'("cr"));
+ end Archive_Builder_Options;
+
+ -----------------
+ -- Archive_Ext --
+ -----------------
+
+ function Archive_Ext return String is
+ begin
+ return "a";
+ end Archive_Ext;
+
+ ---------------------
+ -- Archive_Indexer --
+ ---------------------
+
+ function Archive_Indexer return String is
+ begin
+ return "ranlib";
+ end Archive_Indexer;
+
+ ---------------------------
+ -- Build_Dynamic_Library --
+ ---------------------------
+
+ procedure Build_Dynamic_Library
+ (Ofiles : Argument_List;
+ Foreign : Argument_List;
+ Afiles : Argument_List;
+ Options : Argument_List;
+ Interfaces : Argument_List;
+ Lib_Filename : String;
+ Lib_Dir : String;
+ Symbol_Data : Symbol_Record;
+ Driver_Name : Name_Id := No_Name;
+ Lib_Address : String := "";
+ Lib_Version : String := "";
+ Relocatable : Boolean := False;
+ Auto_Init : Boolean := False)
+ is
+ pragma Unreferenced (Foreign);
+ pragma Unreferenced (Afiles);
+ pragma Unreferenced (Interfaces);
+ pragma Unreferenced (Symbol_Data);
+ pragma Unreferenced (Lib_Address);
+ pragma Unreferenced (Relocatable);
+
+ Lib_File : constant String :=
+ Lib_Dir & Directory_Separator & "lib" &
+ Fil.Ext_To (Lib_Filename, DLL_Ext);
+
+ Version_Arg : String_Access;
+ Symbolic_Link_Needed : Boolean := False;
+
+ Init_Fini : Argument_List_Access := Empty_Argument_List;
+
+ begin
+ if Opt.Verbose_Mode then
+ Write_Str ("building relocatable shared library ");
+ Write_Line (Lib_File);
+ end if;
+
+ -- If specified, add automatic elaboration/finalization
+ if Auto_Init then
+ Init_Fini := Init_Fini_List;
+ Init_Fini (2) := new String'("-Wl," & Lib_Filename & "init");
+ Init_Fini (4) := new String'("-Wl," & Lib_Filename & "final");
+ end if;
+
+ if Lib_Version = "" then
+ Utl.Gcc
+ (Output_File => Lib_File,
+ Objects => Ofiles,
+ Options => Options & Init_Fini.all,
+ Driver_Name => Driver_Name);
+
+ else
+ Version_Arg := new String'("-Wl,-soname," & Lib_Version);
+
+ if Is_Absolute_Path (Lib_Version) then
+ Utl.Gcc
+ (Output_File => Lib_Version,
+ Objects => Ofiles,
+ Options => Options & Version_Arg & Init_Fini.all,
+ Driver_Name => Driver_Name);
+ Symbolic_Link_Needed := Lib_Version /= Lib_File;
+
+ else
+ Utl.Gcc
+ (Output_File => Lib_Dir & Directory_Separator & Lib_Version,
+ Objects => Ofiles,
+ Options => Options & Version_Arg & Init_Fini.all,
+ Driver_Name => Driver_Name);
+ Symbolic_Link_Needed :=
+ Lib_Dir & Directory_Separator & Lib_Version /= Lib_File;
+ end if;
+
+ if Symbolic_Link_Needed then
+ declare
+ Success : Boolean;
+ Oldpath : String (1 .. Lib_Version'Length + 1);
+ Newpath : String (1 .. Lib_File'Length + 1);
+
+ Result : Integer;
+ pragma Unreferenced (Result);
+
+ function Symlink
+ (Oldpath : System.Address;
+ Newpath : System.Address) return Integer;
+ pragma Import (C, Symlink, "__gnat_symlink");
+
+ begin
+ Oldpath (1 .. Lib_Version'Length) := Lib_Version;
+ Oldpath (Oldpath'Last) := ASCII.NUL;
+ Newpath (1 .. Lib_File'Length) := Lib_File;
+ Newpath (Newpath'Last) := ASCII.NUL;
+
+ Delete_File (Lib_File, Success);
+
+ Result := Symlink (Oldpath'Address, Newpath'Address);
+ end;
+ end if;
+ end if;
+ end Build_Dynamic_Library;
+
+ -------------------------
+ -- Default_DLL_Address --
+ -------------------------
+
+ function Default_DLL_Address return String is
+ begin
+ return "";
+ end Default_DLL_Address;
+
+ -------------
+ -- DLL_Ext --
+ -------------
+
+ function DLL_Ext return String is
+ begin
+ return "so";
+ end DLL_Ext;
+
+ --------------------
+ -- Dynamic_Option --
+ --------------------
+
+ function Dynamic_Option return String is
+ begin
+ return "-shared";
+ end Dynamic_Option;
+
+ -------------------
+ -- Is_Object_Ext --
+ -------------------
+
+ function Is_Object_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".o";
+ end Is_Object_Ext;
+
+ --------------
+ -- Is_C_Ext --
+ --------------
+
+ function Is_C_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".c";
+ end Is_C_Ext;
+
+ --------------------
+ -- Is_Archive_Ext --
+ --------------------
+
+ function Is_Archive_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".a" or else Ext = ".so";
+ end Is_Archive_Ext;
+
+ -------------
+ -- Libgnat --
+ -------------
+
+ function Libgnat return String is
+ begin
+ return "libgnat.a";
+ end Libgnat;
+
+ ------------------------
+ -- Library_Exists_For --
+ ------------------------
+
+ function Library_Exists_For (Project : Project_Id) return Boolean is
+ begin
+ if not Projects.Table (Project).Library then
+ Prj.Com.Fail ("INTERNAL ERROR: Library_Exists_For called " &
+ "for non library project");
+ return False;
+
+ else
+ declare
+ Lib_Dir : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Dir);
+ Lib_Name : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Name);
+
+ begin
+ if Projects.Table (Project).Library_Kind = Static then
+ return Is_Regular_File
+ (Lib_Dir & Directory_Separator & "lib" &
+ Fil.Ext_To (Lib_Name, Archive_Ext));
+
+ else
+ return Is_Regular_File
+ (Lib_Dir & Directory_Separator & "lib" &
+ Fil.Ext_To (Lib_Name, DLL_Ext));
+ end if;
+ end;
+ end if;
+ end Library_Exists_For;
+
+ ---------------------------
+ -- Library_File_Name_For --
+ ---------------------------
+
+ function Library_File_Name_For (Project : Project_Id) return Name_Id is
+ begin
+ if not Projects.Table (Project).Library then
+ Prj.Com.Fail ("INTERNAL ERROR: Library_File_Name_For called " &
+ "for non library project");
+ return No_Name;
+
+ else
+ declare
+ Lib_Name : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Name);
+
+ begin
+ Name_Len := 3;
+ Name_Buffer (1 .. Name_Len) := "lib";
+
+ if Projects.Table (Project).Library_Kind = Static then
+ Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, Archive_Ext));
+
+ else
+ Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, DLL_Ext));
+ end if;
+
+ return Name_Find;
+ end;
+ end if;
+ end Library_File_Name_For;
+
+ ----------------
+ -- Object_Ext --
+ ----------------
+
+ function Object_Ext return String is
+ begin
+ return "o";
+ end Object_Ext;
+
+ ----------------
+ -- PIC_Option --
+ ----------------
+
+ function PIC_Option return String is
+ begin
+ return "-fPIC";
+ end PIC_Option;
+
+ -----------------------------------------------
+ -- Standalone_Library_Auto_Init_Is_Supported --
+ -----------------------------------------------
+
+ function Standalone_Library_Auto_Init_Is_Supported return Boolean is
+ begin
+ return True;
+ end Standalone_Library_Auto_Init_Is_Supported;
+
+ ---------------------------
+ -- Support_For_Libraries --
+ ---------------------------
+
+ function Support_For_Libraries return Library_Support is
+ begin
+ return Full;
+ end Support_For_Libraries;
+
+end MLib.Tgt;
diff --git a/gcc/ada/mlib-tgt-mingw.adb b/gcc/ada/mlib-tgt-mingw.adb
new file mode 100644
index 00000000000..485be34bea6
--- /dev/null
+++ b/gcc/ada/mlib-tgt-mingw.adb
@@ -0,0 +1,347 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- M L I B . T G T --
+-- (Windows Version) --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2002-2004, Ada Core Technologies, 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- --
+-- 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, 59 Temple Place - Suite 330, Boston, --
+-- MA 02111-1307, USA. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides a set of target dependent routines to build
+-- static, dynamic and shared libraries.
+
+-- This is the Windows version of the body.
+
+with Namet; use Namet;
+with Opt;
+with Output; use Output;
+with Prj.Com;
+
+with GNAT.OS_Lib; use GNAT.OS_Lib;
+
+with MDLL;
+with MDLL.Utl;
+with MLib.Fil;
+
+package body MLib.Tgt is
+
+ ---------------------
+ -- Archive_Builder --
+ ---------------------
+
+ function Archive_Builder return String is
+ begin
+ return "ar";
+ end Archive_Builder;
+
+ -----------------------------
+ -- Archive_Builder_Options --
+ -----------------------------
+
+ function Archive_Builder_Options return String_List_Access is
+ begin
+ return new String_List'(1 => new String'("cr"));
+ end Archive_Builder_Options;
+
+ -----------------
+ -- Archive_Ext --
+ -----------------
+
+ function Archive_Ext return String is
+ begin
+ return "a";
+ end Archive_Ext;
+
+ ---------------------
+ -- Archive_Indexer --
+ ---------------------
+
+ function Archive_Indexer return String is
+ begin
+ return "ranlib";
+ end Archive_Indexer;
+
+ ---------------------------
+ -- Build_Dynamic_Library --
+ ---------------------------
+
+ procedure Build_Dynamic_Library
+ (Ofiles : Argument_List;
+ Foreign : Argument_List;
+ Afiles : Argument_List;
+ Options : Argument_List;
+ Interfaces : Argument_List;
+ Lib_Filename : String;
+ Lib_Dir : String;
+ Symbol_Data : Symbol_Record;
+ Driver_Name : Name_Id := No_Name;
+ Lib_Address : String := "";
+ Lib_Version : String := "";
+ Relocatable : Boolean := False;
+ Auto_Init : Boolean := False)
+ is
+ pragma Unreferenced (Ofiles);
+ pragma Unreferenced (Interfaces);
+ pragma Unreferenced (Symbol_Data);
+ pragma Unreferenced (Driver_Name);
+ pragma Unreferenced (Lib_Version);
+ pragma Unreferenced (Auto_Init);
+
+ Imp_File : constant String :=
+ "lib" & MLib.Fil.Ext_To (Lib_Filename, Archive_Ext);
+ -- Name of the import library
+
+ DLL_File : constant String := MLib.Fil.Ext_To (Lib_Filename, DLL_Ext);
+ -- Name of the DLL file
+
+ Lib_File : constant String := Lib_Dir & Directory_Separator & DLL_File;
+ -- Full path of the DLL file
+
+ Success : Boolean;
+
+ begin
+ if Opt.Verbose_Mode then
+ if Relocatable then
+ Write_Str ("building relocatable shared library ");
+ else
+ Write_Str ("building non-relocatable shared library ");
+ end if;
+
+ Write_Line (Lib_File);
+ end if;
+
+ MDLL.Verbose := Opt.Verbose_Mode;
+ MDLL.Quiet := not MDLL.Verbose;
+
+ MDLL.Utl.Locate;
+
+ MDLL.Build_Dynamic_Library
+ (Foreign, Afiles,
+ MDLL.Null_Argument_List, MDLL.Null_Argument_List, Options,
+ Lib_Filename, Lib_Filename & ".def",
+ Lib_Address, True, Relocatable);
+
+ -- Move the DLL and import library in the lib directory
+
+ Copy_File (DLL_File, Lib_Dir, Success, Mode => Overwrite);
+
+ if not Success then
+ Fail ("could not copy DLL to library dir");
+ end if;
+
+ Copy_File (Imp_File, Lib_Dir, Success, Mode => Overwrite);
+
+ if not Success then
+ Fail ("could not copy import library to library dir");
+ end if;
+
+ -- Delete files
+
+ Delete_File (DLL_File, Success);
+
+ if not Success then
+ Fail ("could not delete DLL from build dir");
+ end if;
+
+ Delete_File (Imp_File, Success);
+
+ if not Success then
+ Fail ("could not delete import library from build dir");
+ end if;
+ end Build_Dynamic_Library;
+
+ -------------------------
+ -- Default_DLL_Address --
+ -------------------------
+
+ function Default_DLL_Address return String is
+ begin
+ return "0x11000000";
+ end Default_DLL_Address;
+
+ -------------
+ -- DLL_Ext --
+ -------------
+
+ function DLL_Ext return String is
+ begin
+ return "dll";
+ end DLL_Ext;
+
+ --------------------
+ -- Dynamic_Option --
+ --------------------
+
+ function Dynamic_Option return String is
+ begin
+ return "";
+ end Dynamic_Option;
+
+ -------------------
+ -- Is_Object_Ext --
+ -------------------
+
+ function Is_Object_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".o";
+ end Is_Object_Ext;
+
+ --------------
+ -- Is_C_Ext --
+ --------------
+
+ function Is_C_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".c";
+ end Is_C_Ext;
+
+ --------------------
+ -- Is_Archive_Ext --
+ --------------------
+
+ function Is_Archive_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".a";
+ end Is_Archive_Ext;
+
+ -------------
+ -- Libgnat --
+ -------------
+
+ function Libgnat return String is
+ begin
+ return "libgnat.a";
+ end Libgnat;
+
+ ------------------------
+ -- Library_Exists_For --
+ ------------------------
+
+ function Library_Exists_For (Project : Project_Id) return Boolean is
+ begin
+ if not Projects.Table (Project).Library then
+ Prj.Com.Fail ("INTERNAL ERROR: Library_Exists_For called " &
+ "for non library project");
+ return False;
+
+ else
+ declare
+ Lib_Dir : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Dir);
+ Lib_Name : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Name);
+
+ begin
+ if Projects.Table (Project).Library_Kind = Static then
+
+ -- Static libraries are named : lib<name>.a
+
+ return Is_Regular_File
+ (Lib_Dir & Directory_Separator & "lib" &
+ MLib.Fil.Ext_To (Lib_Name, Archive_Ext));
+
+ else
+ -- Shared libraries are named : <name>.dll
+
+ return Is_Regular_File
+ (Lib_Dir & Directory_Separator &
+ MLib.Fil.Ext_To (Lib_Name, DLL_Ext));
+ end if;
+ end;
+ end if;
+ end Library_Exists_For;
+
+ ---------------------------
+ -- Library_File_Name_For --
+ ---------------------------
+
+ function Library_File_Name_For (Project : Project_Id) return Name_Id is
+ begin
+ if not Projects.Table (Project).Library then
+ Prj.Com.Fail ("INTERNAL ERROR: Library_File_Name_For called " &
+ "for non library project");
+ return No_Name;
+
+ else
+ declare
+ Lib_Name : constant String :=
+ Get_Name_String
+ (Projects.Table (Project).Library_Name);
+
+ begin
+ if Projects.Table (Project).Library_Kind = Static then
+
+ -- Static libraries are named : lib<name>.a
+
+ Name_Len := 3;
+ Name_Buffer (1 .. Name_Len) := "lib";
+
+ Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, Archive_Ext));
+
+ else
+ -- Shared libraries are named : <name>.dll
+
+ Name_Len := 0;
+ Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, DLL_Ext));
+ end if;
+
+ return Name_Find;
+ end;
+ end if;
+ end Library_File_Name_For;
+
+ ----------------
+ -- Object_Ext --
+ ----------------
+
+ function Object_Ext return String is
+ begin
+ return "o";
+ end Object_Ext;
+
+ ----------------
+ -- PIC_Option --
+ ----------------
+
+ function PIC_Option return String is
+ begin
+ return "";
+ end PIC_Option;
+
+ -----------------------------------------------
+ -- Standalone_Library_Auto_Init_Is_Supported --
+ -----------------------------------------------
+
+ function Standalone_Library_Auto_Init_Is_Supported return Boolean is
+ begin
+ return False;
+ end Standalone_Library_Auto_Init_Is_Supported;
+
+ ---------------------------
+ -- Support_For_Libraries --
+ ---------------------------
+
+ function Support_For_Libraries return Library_Support is
+ begin
+ return Full;
+ end Support_For_Libraries;
+
+end MLib.Tgt;
diff --git a/gcc/ada/mlib-tgt-solaris.adb b/gcc/ada/mlib-tgt-solaris.adb
new file mode 100644
index 00000000000..ac5e4b937fe
--- /dev/null
+++ b/gcc/ada/mlib-tgt-solaris.adb
@@ -0,0 +1,362 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- M L I B . T G T --
+-- (Solaris Version) --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2002-2004 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- --
+-- 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, 59 Temple Place - Suite 330, Boston, --
+-- MA 02111-1307, USA. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides a set of target dependent routines to build
+-- static, dynamic and shared libraries.
+
+-- This is the Solaris version of the body
+
+with MLib.Fil;
+with MLib.Utl;
+with Namet; use Namet;
+with Opt;
+with Output; use Output;
+with Prj.Com;
+with System;
+
+package body MLib.Tgt is
+
+ No_Arguments : aliased Argument_List := (1 .. 0 => null);
+ Empty_Argument_List : constant Argument_List_Access := No_Arguments'Access;
+
+ Wl_Init_String : constant String := "-Wl,-zinitarray=";
+ Wl_Fini_String : constant String := "-Wl,-zfiniarray=";
+
+ Init_Fini_List : constant Argument_List_Access :=
+ new Argument_List'(1 => null,
+ 2 => null);
+
+ -- Used to put switches for automatic elaboration/finalization
+
+ ---------------------
+ -- Archive_Builder --
+ ---------------------
+
+ function Archive_Builder return String is
+ begin
+ return "ar";
+ end Archive_Builder;
+
+ -----------------------------
+ -- Archive_Builder_Options --
+ -----------------------------
+
+ function Archive_Builder_Options return String_List_Access is
+ begin
+ return new String_List'(1 => new String'("cr"));
+ end Archive_Builder_Options;
+
+ -----------------
+ -- Archive_Ext --
+ -----------------
+
+ function Archive_Ext return String is
+ begin
+ return "a";
+ end Archive_Ext;
+
+ ---------------------
+ -- Archive_Indexer --
+ ---------------------
+
+ function Archive_Indexer return String is
+ begin
+ return "ranlib";
+ end Archive_Indexer;
+
+ ---------------------------
+ -- Build_Dynamic_Library --
+ ---------------------------
+
+ procedure Build_Dynamic_Library
+ (Ofiles : Argument_List;
+ Foreign : Argument_List;
+ Afiles : Argument_List;
+ Options : Argument_List;
+ Interfaces : Argument_List;
+ Lib_Filename : String;
+ Lib_Dir : String;
+ Symbol_Data : Symbol_Record;
+ Driver_Name : Name_Id := No_Name;
+ Lib_Address : String := "";
+ Lib_Version : String := "";
+ Relocatable : Boolean := False;
+ Auto_Init : Boolean := False)
+ is
+ pragma Unreferenced (Foreign);
+ pragma Unreferenced (Afiles);
+ pragma Unreferenced (Interfaces);
+ pragma Unreferenced (Symbol_Data);
+ pragma Unreferenced (Lib_Address);
+ pragma Unreferenced (Relocatable);
+
+ Lib_File : constant String :=
+ Lib_Dir & Directory_Separator & "lib" &
+ Fil.Ext_To (Lib_Filename, DLL_Ext);
+
+ Version_Arg : String_Access;
+ Symbolic_Link_Needed : Boolean := False;
+
+ Init_Fini : Argument_List_Access := Empty_Argument_List;
+
+ begin
+ if Opt.Verbose_Mode then
+ Write_Str ("building relocatable shared library ");
+ Write_Line (Lib_File);
+ end if;
+
+ -- If specified, add automatic elaboration/finalization
+ if Auto_Init then
+ Init_Fini := Init_Fini_List;
+ Init_Fini (1) :=
+ new String'(Wl_Init_String & Lib_Filename & "init");
+ Init_Fini (2) :=
+ new String'(Wl_Fini_String & Lib_Filename & "final");
+ end if;
+
+ if Lib_Version = "" then
+ Utl.Gcc
+ (Output_File => Lib_File,
+ Objects => Ofiles,
+ Options => Options & Init_Fini.all,
+ Driver_Name => Driver_Name);
+
+ else
+ Version_Arg := new String'("-Wl,-h," & Lib_Version);
+
+ if Is_Absolute_Path (Lib_Version) then
+ Utl.Gcc
+ (Output_File => Lib_Version,
+ Objects => Ofiles,
+ Options => Options & Version_Arg & Init_Fini.all,
+ Driver_Name => Driver_Name);
+ Symbolic_Link_Needed := Lib_Version /= Lib_File;
+
+ else
+ Utl.Gcc
+ (Output_File => Lib_Dir & Directory_Separator & Lib_Version,
+ Objects => Ofiles,
+ Options => Options & Version_Arg & Init_Fini.all,
+ Driver_Name => Driver_Name);
+ Symbolic_Link_Needed :=
+ Lib_Dir & Directory_Separator & Lib_Version /= Lib_File;
+ end if;
+
+ if Symbolic_Link_Needed then
+ declare
+ Success : Boolean;
+ Oldpath : String (1 .. Lib_Version'Length + 1);
+ Newpath : String (1 .. Lib_File'Length + 1);
+
+ Result : Integer;
+ pragma Unreferenced (Result);
+
+ function Symlink
+ (Oldpath : System.Address;
+ Newpath : System.Address)
+ return Integer;
+ pragma Import (C, Symlink, "__gnat_symlink");
+
+ begin
+ Oldpath (1 .. Lib_Version'Length) := Lib_Version;
+ Oldpath (Oldpath'Last) := ASCII.NUL;
+ Newpath (1 .. Lib_File'Length) := Lib_File;
+ Newpath (Newpath'Last) := ASCII.NUL;
+
+ Delete_File (Lib_File, Success);
+
+ Result := Symlink (Oldpath'Address, Newpath'Address);
+ end;
+ end if;
+ end if;
+ end Build_Dynamic_Library;
+
+ -------------------------
+ -- Default_DLL_Address --
+ -------------------------
+
+ function Default_DLL_Address return String is
+ begin
+ return "";
+ end Default_DLL_Address;
+
+ -------------
+ -- DLL_Ext --
+ -------------
+
+ function DLL_Ext return String is
+ begin
+ return "so";
+ end DLL_Ext;
+
+ --------------------
+ -- Dynamic_Option --
+ --------------------
+
+ function Dynamic_Option return String is
+ begin
+ return "-shared";
+ end Dynamic_Option;
+
+ -------------------
+ -- Is_Object_Ext --
+ -------------------
+
+ function Is_Object_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".o";
+ end Is_Object_Ext;
+
+ --------------
+ -- Is_C_Ext --
+ --------------
+
+ function Is_C_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".c";
+ end Is_C_Ext;
+
+ --------------------
+ -- Is_Archive_Ext --
+ --------------------
+
+ function Is_Archive_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".a" or else Ext = ".so";
+ end Is_Archive_Ext;
+
+ -------------
+ -- Libgnat --
+ -------------
+
+ function Libgnat return String is
+ begin
+ return "libgnat.a";
+ end Libgnat;
+
+ ------------------------
+ -- Library_Exists_For --
+ ------------------------
+
+ function Library_Exists_For (Project : Project_Id) return Boolean is
+ begin
+ if not Projects.Table (Project).Library then
+ Prj.Com.Fail ("INTERNAL ERROR: Library_Exists_For called " &
+ "for non library project");
+ return False;
+
+ else
+ declare
+ Lib_Dir : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Dir);
+ Lib_Name : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Name);
+
+ begin
+ if Projects.Table (Project).Library_Kind = Static then
+ return Is_Regular_File
+ (Lib_Dir & Directory_Separator & "lib" &
+ Fil.Ext_To (Lib_Name, Archive_Ext));
+
+ else
+ return Is_Regular_File
+ (Lib_Dir & Directory_Separator & "lib" &
+ Fil.Ext_To (Lib_Name, DLL_Ext));
+ end if;
+ end;
+ end if;
+ end Library_Exists_For;
+
+ ---------------------------
+ -- Library_File_Name_For --
+ ---------------------------
+
+ function Library_File_Name_For (Project : Project_Id) return Name_Id is
+ begin
+ if not Projects.Table (Project).Library then
+ Prj.Com.Fail ("INTERNAL ERROR: Library_File_Name_For called " &
+ "for non library project");
+ return No_Name;
+
+ else
+ declare
+ Lib_Name : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Name);
+
+ begin
+ Name_Len := 3;
+ Name_Buffer (1 .. Name_Len) := "lib";
+
+ if Projects.Table (Project).Library_Kind = Static then
+ Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, Archive_Ext));
+
+ else
+ Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, DLL_Ext));
+ end if;
+
+ return Name_Find;
+ end;
+ end if;
+ end Library_File_Name_For;
+
+ ----------------
+ -- Object_Ext --
+ ----------------
+
+ function Object_Ext return String is
+ begin
+ return "o";
+ end Object_Ext;
+
+ ----------------
+ -- PIC_Option --
+ ----------------
+
+ function PIC_Option return String is
+ begin
+ return "-fPIC";
+ end PIC_Option;
+
+ -----------------------------------------------
+ -- Standalone_Library_Auto_Init_Is_Supported --
+ -----------------------------------------------
+
+ function Standalone_Library_Auto_Init_Is_Supported return Boolean is
+ begin
+ return True;
+ end Standalone_Library_Auto_Init_Is_Supported;
+
+ ---------------------------
+ -- Support_For_Libraries --
+ ---------------------------
+
+ function Support_For_Libraries return Library_Support is
+ begin
+ return Full;
+ end Support_For_Libraries;
+
+end MLib.Tgt;
diff --git a/gcc/ada/mlib-tgt-tru64.adb b/gcc/ada/mlib-tgt-tru64.adb
new file mode 100644
index 00000000000..2474da3ea84
--- /dev/null
+++ b/gcc/ada/mlib-tgt-tru64.adb
@@ -0,0 +1,380 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- M L I B . T G T --
+-- (True64 Version) --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2002-2004 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- --
+-- 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, 59 Temple Place - Suite 330, Boston, --
+-- MA 02111-1307, USA. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides a set of target dependent routines to build
+-- static, dynamic and shared libraries.
+
+-- This is the True64 version of the body.
+
+with MLib.Fil;
+with MLib.Utl;
+with Namet; use Namet;
+with Opt;
+with Output; use Output;
+with Prj.Com;
+with System;
+
+package body MLib.Tgt is
+
+ use GNAT;
+ use MLib;
+
+ Expect_Unresolved : aliased String := "-Wl,-expect_unresolved,*";
+
+ No_Arguments : aliased Argument_List := (1 .. 0 => null);
+ Empty_Argument_List : constant Argument_List_Access := No_Arguments'Access;
+
+ Wl_Init_String : aliased String := "-Wl,-init";
+ Wl_Init : constant String_Access := Wl_Init_String'Access;
+ Wl_Fini_String : aliased String := "-Wl,-fini";
+ Wl_Fini : constant String_Access := Wl_Fini_String'Access;
+
+ Init_Fini_List : constant Argument_List_Access :=
+ new Argument_List'(1 => Wl_Init,
+ 2 => null,
+ 3 => Wl_Fini,
+ 4 => null);
+ -- Used to put switches for automatic elaboration/finalization
+
+ ---------------------
+ -- Archive_Builder --
+ ---------------------
+
+ function Archive_Builder return String is
+ begin
+ return "ar";
+ end Archive_Builder;
+
+ -----------------------------
+ -- Archive_Builder_Options --
+ -----------------------------
+
+ function Archive_Builder_Options return String_List_Access is
+ begin
+ return new String_List'(1 => new String'("cr"));
+ end Archive_Builder_Options;
+
+ -----------------
+ -- Archive_Ext --
+ -----------------
+
+ function Archive_Ext return String is
+ begin
+ return "a";
+ end Archive_Ext;
+
+ ---------------------
+ -- Archive_Indexer --
+ ---------------------
+
+ function Archive_Indexer return String is
+ begin
+ return "ranlib";
+ end Archive_Indexer;
+
+ ---------------------------
+ -- Build_Dynamic_Library --
+ ---------------------------
+
+ procedure Build_Dynamic_Library
+ (Ofiles : Argument_List;
+ Foreign : Argument_List;
+ Afiles : Argument_List;
+ Options : Argument_List;
+ Interfaces : Argument_List;
+ Lib_Filename : String;
+ Lib_Dir : String;
+ Symbol_Data : Symbol_Record;
+ Driver_Name : Name_Id := No_Name;
+ Lib_Address : String := "";
+ Lib_Version : String := "";
+ Relocatable : Boolean := False;
+ Auto_Init : Boolean := False)
+ is
+ pragma Unreferenced (Foreign);
+ pragma Unreferenced (Afiles);
+ pragma Unreferenced (Interfaces);
+ pragma Unreferenced (Symbol_Data);
+ pragma Unreferenced (Lib_Address);
+ pragma Unreferenced (Relocatable);
+
+ Lib_File : constant String :=
+ Lib_Dir & Directory_Separator & "lib" &
+ Fil.Ext_To (Lib_Filename, DLL_Ext);
+
+ Version_Arg : String_Access;
+ Symbolic_Link_Needed : Boolean := False;
+
+ Init_Fini : Argument_List_Access := Empty_Argument_List;
+
+ begin
+ if Opt.Verbose_Mode then
+ Write_Str ("building relocatable shared library ");
+ Write_Line (Lib_File);
+ end if;
+
+ -- If specified, add automatic elaboration/finalization
+
+ if Auto_Init then
+ Init_Fini := Init_Fini_List;
+ Init_Fini (2) := new String'("-Wl," & Lib_Filename & "init");
+ Init_Fini (4) := new String'("-Wl," & Lib_Filename & "final");
+ end if;
+
+ if Lib_Version = "" then
+ Utl.Gcc
+ (Output_File => Lib_File,
+ Objects => Ofiles,
+ Options =>
+ Options &
+ Expect_Unresolved'Access &
+ Init_Fini.all,
+ Driver_Name => Driver_Name);
+
+ else
+ Version_Arg := new String'("-Wl,-soname," & Lib_Version);
+
+ if Is_Absolute_Path (Lib_Version) then
+ Utl.Gcc
+ (Output_File => Lib_Version,
+ Objects => Ofiles,
+ Options =>
+ Options &
+ Version_Arg &
+ Expect_Unresolved'Access &
+ Init_Fini.all,
+ Driver_Name => Driver_Name);
+ Symbolic_Link_Needed := Lib_Version /= Lib_File;
+
+ else
+ Utl.Gcc
+ (Output_File => Lib_Dir & Directory_Separator & Lib_Version,
+ Objects => Ofiles,
+ Options =>
+ Options &
+ Version_Arg &
+ Expect_Unresolved'Access &
+ Init_Fini.all,
+ Driver_Name => Driver_Name);
+ Symbolic_Link_Needed :=
+ Lib_Dir & Directory_Separator & Lib_Version /= Lib_File;
+ end if;
+
+ if Symbolic_Link_Needed then
+ declare
+ Success : Boolean;
+ Oldpath : String (1 .. Lib_Version'Length + 1);
+ Newpath : String (1 .. Lib_File'Length + 1);
+
+ Result : Integer;
+ pragma Unreferenced (Result);
+
+ function Symlink
+ (Oldpath : System.Address;
+ Newpath : System.Address)
+ return Integer;
+ pragma Import (C, Symlink, "__gnat_symlink");
+
+ begin
+ Oldpath (1 .. Lib_Version'Length) := Lib_Version;
+ Oldpath (Oldpath'Last) := ASCII.NUL;
+ Newpath (1 .. Lib_File'Length) := Lib_File;
+ Newpath (Newpath'Last) := ASCII.NUL;
+
+ Delete_File (Lib_File, Success);
+
+ Result := Symlink (Oldpath'Address, Newpath'Address);
+ end;
+ end if;
+ end if;
+ end Build_Dynamic_Library;
+
+ -------------------------
+ -- Default_DLL_Address --
+ -------------------------
+
+ function Default_DLL_Address return String is
+ begin
+ return "";
+ end Default_DLL_Address;
+
+ -------------
+ -- DLL_Ext --
+ -------------
+
+ function DLL_Ext return String is
+ begin
+ return "so";
+ end DLL_Ext;
+
+ --------------------
+ -- Dynamic_Option --
+ --------------------
+
+ function Dynamic_Option return String is
+ begin
+ return "-shared";
+ end Dynamic_Option;
+
+ -------------------
+ -- Is_Object_Ext --
+ -------------------
+
+ function Is_Object_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".o";
+ end Is_Object_Ext;
+
+ --------------
+ -- Is_C_Ext --
+ --------------
+
+ function Is_C_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".c";
+ end Is_C_Ext;
+
+ --------------------
+ -- Is_Archive_Ext --
+ --------------------
+
+ function Is_Archive_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".a" or else Ext = ".so";
+ end Is_Archive_Ext;
+
+ -------------
+ -- Libgnat --
+ -------------
+
+ function Libgnat return String is
+ begin
+ return "libgnat.a";
+ end Libgnat;
+
+ ------------------------
+ -- Library_Exists_For --
+ ------------------------
+
+ function Library_Exists_For (Project : Project_Id) return Boolean is
+ begin
+ if not Projects.Table (Project).Library then
+ Prj.Com.Fail ("INTERNAL ERROR: Library_Exists_For called " &
+ "for non library project");
+ return False;
+
+ else
+ declare
+ Lib_Dir : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Dir);
+ Lib_Name : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Name);
+
+ begin
+ if Projects.Table (Project).Library_Kind = Static then
+ return Is_Regular_File
+ (Lib_Dir & Directory_Separator & "lib" &
+ Fil.Ext_To (Lib_Name, Archive_Ext));
+
+ else
+ return Is_Regular_File
+ (Lib_Dir & Directory_Separator & "lib" &
+ Fil.Ext_To (Lib_Name, DLL_Ext));
+ end if;
+ end;
+ end if;
+ end Library_Exists_For;
+
+ ---------------------------
+ -- Library_File_Name_For --
+ ---------------------------
+
+ function Library_File_Name_For (Project : Project_Id) return Name_Id is
+ begin
+ if not Projects.Table (Project).Library then
+ Prj.Com.Fail ("INTERNAL ERROR: Library_File_Name_For called " &
+ "for non library project");
+ return No_Name;
+
+ else
+ declare
+ Lib_Name : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Name);
+
+ begin
+ Name_Len := 3;
+ Name_Buffer (1 .. Name_Len) := "lib";
+
+ if Projects.Table (Project).Library_Kind = Static then
+ Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, Archive_Ext));
+
+ else
+ Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, DLL_Ext));
+ end if;
+
+ return Name_Find;
+ end;
+ end if;
+ end Library_File_Name_For;
+
+ ----------------
+ -- Object_Ext --
+ ----------------
+
+ function Object_Ext return String is
+ begin
+ return "o";
+ end Object_Ext;
+
+ ----------------
+ -- PIC_Option --
+ ----------------
+
+ function PIC_Option return String is
+ begin
+ return "";
+ end PIC_Option;
+
+ -----------------------------------------------
+ -- Standalone_Library_Auto_Init_Is_Supported --
+ -----------------------------------------------
+
+ function Standalone_Library_Auto_Init_Is_Supported return Boolean is
+ begin
+ return True;
+ end Standalone_Library_Auto_Init_Is_Supported;
+
+ ---------------------------
+ -- Support_For_Libraries --
+ ---------------------------
+
+ function Support_For_Libraries return Library_Support is
+ begin
+ return Full;
+ end Support_For_Libraries;
+
+end MLib.Tgt;
diff --git a/gcc/ada/mlib-tgt-vms.adb b/gcc/ada/mlib-tgt-vms.adb
new file mode 100644
index 00000000000..6db0dccb9dc
--- /dev/null
+++ b/gcc/ada/mlib-tgt-vms.adb
@@ -0,0 +1,703 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- M L I B . T G T --
+-- (VMS Version) --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2003-2004, 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- --
+-- 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, 59 Temple Place - Suite 330, Boston, --
+-- MA 02111-1307, USA. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the VMS version of the body
+
+with Ada.Characters.Handling; use Ada.Characters.Handling;
+
+with GNAT.Directory_Operations; use GNAT.Directory_Operations;
+with GNAT.OS_Lib; use GNAT.OS_Lib;
+
+with MLib.Fil;
+with MLib.Utl;
+with Namet; use Namet;
+with Opt; use Opt;
+with Output; use Output;
+with Prj.Com;
+with System; use System;
+with System.Case_Util; use System.Case_Util;
+
+package body MLib.Tgt is
+
+ use GNAT;
+
+ Empty_Argument_List : aliased Argument_List := (1 .. 0 => null);
+ Additional_Objects : Argument_List_Access := Empty_Argument_List'Access;
+ -- Used to add the generated auto-init object files for auto-initializing
+ -- stand-alone libraries.
+
+ Macro_Name : constant String := "mcr gnu:[bin]gcc -c -x assembler";
+ -- The name of the command to invoke the macro-assembler
+
+ VMS_Options : Argument_List := (1 .. 1 => null);
+
+ Gnatsym_Name : constant String := "gnatsym";
+
+ Gnatsym_Path : String_Access;
+
+ Arguments : Argument_List_Access := null;
+ Last_Argument : Natural := 0;
+
+ Success : Boolean := False;
+
+ Shared_Libgcc : aliased String := "-shared-libgcc";
+
+ No_Shared_Libgcc_Switch : aliased Argument_List := (1 .. 0 => null);
+ Shared_Libgcc_Switch : aliased Argument_List :=
+ (1 => Shared_Libgcc'Access);
+ Link_With_Shared_Libgcc : Argument_List_Access :=
+ No_Shared_Libgcc_Switch'Access;
+
+ ------------------------------
+ -- Target dependent section --
+ ------------------------------
+
+ function Popen (Command, Mode : System.Address) return System.Address;
+ pragma Import (C, Popen);
+
+ function Pclose (File : System.Address) return Integer;
+ pragma Import (C, Pclose);
+
+ ---------------------
+ -- Archive_Builder --
+ ---------------------
+
+ function Archive_Builder return String is
+ begin
+ return "ar";
+ end Archive_Builder;
+
+ -----------------------------
+ -- Archive_Builder_Options --
+ -----------------------------
+
+ function Archive_Builder_Options return String_List_Access is
+ begin
+ return new String_List'(1 => new String'("cr"));
+ end Archive_Builder_Options;
+
+ -----------------
+ -- Archive_Ext --
+ -----------------
+
+ function Archive_Ext return String is
+ begin
+ return "olb";
+ end Archive_Ext;
+
+ ---------------------
+ -- Archive_Indexer --
+ ---------------------
+
+ function Archive_Indexer return String is
+ begin
+ return "ranlib";
+ end Archive_Indexer;
+
+ ---------------------------
+ -- Build_Dynamic_Library --
+ ---------------------------
+
+ procedure Build_Dynamic_Library
+ (Ofiles : Argument_List;
+ Foreign : Argument_List;
+ Afiles : Argument_List;
+ Options : Argument_List;
+ Interfaces : Argument_List;
+ Lib_Filename : String;
+ Lib_Dir : String;
+ Symbol_Data : Symbol_Record;
+ Driver_Name : Name_Id := No_Name;
+ Lib_Address : String := "";
+ Lib_Version : String := "";
+ Relocatable : Boolean := False;
+ Auto_Init : Boolean := False)
+ is
+ pragma Unreferenced (Foreign);
+ pragma Unreferenced (Afiles);
+ pragma Unreferenced (Lib_Address);
+ pragma Unreferenced (Relocatable);
+
+ Lib_File : constant String :=
+ Lib_Dir & Directory_Separator & "lib" &
+ Fil.Ext_To (Lib_Filename, DLL_Ext);
+
+ Opts : Argument_List := Options;
+ Last_Opt : Natural := Opts'Last;
+ Opts2 : Argument_List (Options'Range);
+ Last_Opt2 : Natural := Opts2'First - 1;
+
+ Inter : constant Argument_List := Interfaces;
+
+ function Is_Interface (Obj_File : String) return Boolean;
+ -- For a Stand-Alone Library, returns True if Obj_File is the object
+ -- file name of an interface of the SAL.
+ -- For other libraries, always return True.
+
+ function Option_File_Name return String;
+ -- Returns Symbol_File, if not empty. Otherwise, returns "symvec.opt"
+
+ function Version_String return String;
+ -- Returns Lib_Version if not empty, otherwise returns "1".
+ -- Fails gnatmake if Lib_Version is not the image of a positive number.
+
+ ------------------
+ -- Is_Interface --
+ ------------------
+
+ function Is_Interface (Obj_File : String) return Boolean is
+ ALI : constant String :=
+ Fil.Ext_To
+ (Filename => To_Lower (Base_Name (Obj_File)),
+ New_Ext => "ali");
+
+ begin
+ if Inter'Length = 0 then
+ return True;
+
+ elsif ALI'Length > 2 and then
+ ALI (ALI'First .. ALI'First + 1) = "b$"
+ then
+ return True;
+
+ else
+ for J in Inter'Range loop
+ if Inter (J).all = ALI then
+ return True;
+ end if;
+ end loop;
+
+ return False;
+ end if;
+ end Is_Interface;
+
+ ----------------------
+ -- Option_File_Name --
+ ----------------------
+
+ function Option_File_Name return String is
+ begin
+ if Symbol_Data.Symbol_File = No_Name then
+ return "symvec.opt";
+ else
+ Get_Name_String (Symbol_Data.Symbol_File);
+ To_Lower (Name_Buffer (1 .. Name_Len));
+ return Name_Buffer (1 .. Name_Len);
+ end if;
+ end Option_File_Name;
+
+ --------------------
+ -- Version_String --
+ --------------------
+
+ function Version_String return String is
+ Version : Integer := 0;
+ begin
+ if Lib_Version = "" then
+ return "1";
+
+ else
+ begin
+ Version := Integer'Value (Lib_Version);
+
+ if Version <= 0 then
+ raise Constraint_Error;
+ end if;
+
+ return Lib_Version;
+
+ exception
+ when Constraint_Error =>
+ Fail ("illegal version """, Lib_Version,
+ """ (on VMS version must be a positive number)");
+ return "";
+ end;
+ end if;
+ end Version_String;
+
+ Opt_File_Name : constant String := Option_File_Name;
+ Version : constant String := Version_String;
+ For_Linker_Opt : String_Access;
+
+ -- Start of processing for Build_Dynamic_Library
+
+ begin
+ -- Invoke gcc with -shared-libgcc, but only for GCC 3 or higher
+
+ if GCC_Version >= 3 then
+ Link_With_Shared_Libgcc := Shared_Libgcc_Switch'Access;
+ else
+ Link_With_Shared_Libgcc := No_Shared_Libgcc_Switch'Access;
+ end if;
+
+ -- If option file name does not ends with ".opt", append "/OPTIONS"
+ -- to its specification for the VMS linker.
+
+ if Opt_File_Name'Length > 4
+ and then
+ Opt_File_Name (Opt_File_Name'Last - 3 .. Opt_File_Name'Last) = ".opt"
+ then
+ For_Linker_Opt := new String'("--for-linker=" & Opt_File_Name);
+ else
+ For_Linker_Opt :=
+ new String'("--for-linker=" & Opt_File_Name & "/OPTIONS");
+ end if;
+
+ VMS_Options (VMS_Options'First) := For_Linker_Opt;
+
+ for J in Inter'Range loop
+ To_Lower (Inter (J).all);
+ end loop;
+
+ -- "gnatsym" is necessary for building the option file
+
+ if Gnatsym_Path = null then
+ Gnatsym_Path := OS_Lib.Locate_Exec_On_Path (Gnatsym_Name);
+
+ if Gnatsym_Path = null then
+ Fail (Gnatsym_Name, " not found in path");
+ end if;
+ end if;
+
+ -- For auto-initialization of a stand-alone library, we create
+ -- a macro-assembly file and we invoke the macro-assembler.
+
+ if Auto_Init then
+ declare
+ Macro_File_Name : constant String := Lib_Filename & "$init.asm";
+ Macro_File : File_Descriptor;
+ Init_Proc : String := Lib_Filename & "INIT";
+ Popen_Result : System.Address;
+ Pclose_Result : Integer;
+ Len : Natural;
+ OK : Boolean := True;
+
+ Command : constant String :=
+ Macro_Name & " " & Macro_File_Name & ASCII.NUL;
+ -- The command to invoke the assembler on the generated auto-init
+ -- assembly file.
+
+ Mode : constant String := "r" & ASCII.NUL;
+ -- The mode for the invocation of Popen
+
+ begin
+ To_Upper (Init_Proc);
+
+ if Verbose_Mode then
+ Write_Str ("Creating auto-init assembly file """);
+ Write_Str (Macro_File_Name);
+ Write_Line ("""");
+ end if;
+
+ -- Create and write the auto-init assembly file
+
+ declare
+ First_Line : constant String :=
+ ASCII.HT & ".section LIB$INITIALIZE,GBL,NOWRT" &
+ ASCII.LF;
+ Second_Line : constant String :=
+ ASCII.HT & ".long " & Init_Proc & ASCII.LF;
+ -- First and second lines of the auto-init assembly file
+
+ begin
+ Macro_File := Create_File (Macro_File_Name, Text);
+ OK := Macro_File /= Invalid_FD;
+
+ if OK then
+ Len := Write
+ (Macro_File, First_Line (First_Line'First)'Address,
+ First_Line'Length);
+ OK := Len = First_Line'Length;
+ end if;
+
+ if OK then
+ Len := Write
+ (Macro_File, Second_Line (Second_Line'First)'Address,
+ Second_Line'Length);
+ OK := Len = Second_Line'Length;
+ end if;
+
+ if OK then
+ Close (Macro_File, OK);
+ end if;
+
+ if not OK then
+ Fail ("creation of auto-init assembly file """,
+ Macro_File_Name, """ failed");
+ end if;
+ end;
+
+ -- Invoke the macro-assembler
+
+ if Verbose_Mode then
+ Write_Str ("Assembling auto-init assembly file """);
+ Write_Str (Macro_File_Name);
+ Write_Line ("""");
+ end if;
+
+ Popen_Result := Popen (Command (Command'First)'Address,
+ Mode (Mode'First)'Address);
+
+ if Popen_Result = Null_Address then
+ Fail ("assembly of auto-init assembly file """,
+ Macro_File_Name, """ failed");
+ end if;
+
+ -- Wait for the end of execution of the macro-assembler
+
+ Pclose_Result := Pclose (Popen_Result);
+
+ if Pclose_Result < 0 then
+ Fail ("assembly of auto init assembly file """,
+ Macro_File_Name, """ failed");
+ end if;
+
+ -- Add the generated object file to the list of objects to be
+ -- included in the library.
+
+ Additional_Objects :=
+ new Argument_List'
+ (1 => new String'(Lib_Filename & "$init.obj"));
+ end;
+ end if;
+
+ -- Allocate the argument list and put the symbol file name, the
+ -- reference (if any) and the policy (if not autonomous).
+
+ Arguments := new Argument_List (1 .. Ofiles'Length + 8);
+
+ Last_Argument := 0;
+
+ -- Verbosity
+
+ if Verbose_Mode then
+ Last_Argument := Last_Argument + 1;
+ Arguments (Last_Argument) := new String'("-v");
+ end if;
+
+ -- Version number (major ID)
+
+ if Lib_Version /= "" then
+ Last_Argument := Last_Argument + 1;
+ Arguments (Last_Argument) := new String'("-V");
+ Last_Argument := Last_Argument + 1;
+ Arguments (Last_Argument) := new String'(Version);
+ end if;
+
+ -- Symbol file
+
+ Last_Argument := Last_Argument + 1;
+ Arguments (Last_Argument) := new String'("-s");
+ Last_Argument := Last_Argument + 1;
+ Arguments (Last_Argument) := new String'(Opt_File_Name);
+
+ -- Reference Symbol File
+
+ if Symbol_Data.Reference /= No_Name then
+ Last_Argument := Last_Argument + 1;
+ Arguments (Last_Argument) := new String'("-r");
+ Last_Argument := Last_Argument + 1;
+ Arguments (Last_Argument) :=
+ new String'(Get_Name_String (Symbol_Data.Reference));
+ end if;
+
+ -- Policy
+
+ case Symbol_Data.Symbol_Policy is
+ when Autonomous =>
+ null;
+
+ when Compliant =>
+ Last_Argument := Last_Argument + 1;
+ Arguments (Last_Argument) := new String'("-c");
+
+ when Controlled =>
+ Last_Argument := Last_Argument + 1;
+ Arguments (Last_Argument) := new String'("-C");
+ end case;
+
+ -- Add each relevant object file
+
+ for Index in Ofiles'Range loop
+ if Is_Interface (Ofiles (Index).all) then
+ Last_Argument := Last_Argument + 1;
+ Arguments (Last_Argument) := new String'(Ofiles (Index).all);
+ end if;
+ end loop;
+
+ -- Spawn gnatsym
+
+ Spawn (Program_Name => Gnatsym_Path.all,
+ Args => Arguments (1 .. Last_Argument),
+ Success => Success);
+
+ if not Success then
+ Fail ("unable to create symbol file for library """,
+ Lib_Filename, """");
+ end if;
+
+ Free (Arguments);
+
+ -- Move all the -l switches from Opts to Opts2
+
+ declare
+ Index : Natural := Opts'First;
+ Opt : String_Access;
+
+ begin
+ while Index <= Last_Opt loop
+ Opt := Opts (Index);
+
+ if Opt'Length > 2 and then
+ Opt (Opt'First .. Opt'First + 1) = "-l"
+ then
+ if Index < Last_Opt then
+ Opts (Index .. Last_Opt - 1) :=
+ Opts (Index + 1 .. Last_Opt);
+ end if;
+
+ Last_Opt := Last_Opt - 1;
+
+ Last_Opt2 := Last_Opt2 + 1;
+ Opts2 (Last_Opt2) := Opt;
+
+ else
+ Index := Index + 1;
+ end if;
+ end loop;
+ end;
+
+ -- Invoke gcc to build the library
+
+ Utl.Gcc
+ (Output_File => Lib_File,
+ Objects => Ofiles & Additional_Objects.all,
+ Options => VMS_Options,
+ Options_2 => Link_With_Shared_Libgcc.all &
+ Opts (Opts'First .. Last_Opt) &
+ Opts2 (Opts2'First .. Last_Opt2),
+ Driver_Name => Driver_Name);
+
+ -- The auto-init object file need to be deleted, so that it will not
+ -- be included in the library as a regular object file, otherwise
+ -- it will be included twice when the library will be built next
+ -- time, which may lead to errors.
+
+ if Auto_Init then
+ declare
+ Auto_Init_Object_File_Name : constant String :=
+ Lib_Filename & "$init.obj";
+ Disregard : Boolean;
+
+ begin
+ if Verbose_Mode then
+ Write_Str ("deleting auto-init object file """);
+ Write_Str (Auto_Init_Object_File_Name);
+ Write_Line ("""");
+ end if;
+
+ Delete_File (Auto_Init_Object_File_Name, Success => Disregard);
+ end;
+ end if;
+ end Build_Dynamic_Library;
+
+ -------------------------
+ -- Default_DLL_Address --
+ -------------------------
+
+ function Default_DLL_Address return String is
+ begin
+ return "";
+ end Default_DLL_Address;
+
+ -------------
+ -- DLL_Ext --
+ -------------
+
+ function DLL_Ext return String is
+ begin
+ return "exe";
+ end DLL_Ext;
+
+ --------------------
+ -- Dynamic_Option --
+ --------------------
+
+ function Dynamic_Option return String is
+ begin
+ return "-shared";
+ end Dynamic_Option;
+
+ -------------------
+ -- Is_Object_Ext --
+ -------------------
+
+ function Is_Object_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".obj";
+ end Is_Object_Ext;
+
+ --------------
+ -- Is_C_Ext --
+ --------------
+
+ function Is_C_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".c";
+ end Is_C_Ext;
+
+ --------------------
+ -- Is_Archive_Ext --
+ --------------------
+
+ function Is_Archive_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".olb" or else Ext = ".exe";
+ end Is_Archive_Ext;
+
+ -------------
+ -- Libgnat --
+ -------------
+
+ function Libgnat return String is
+ Libgnat_A : constant String := "libgnat.a";
+ Libgnat_Olb : constant String := "libgnat.olb";
+
+ begin
+ Name_Len := Libgnat_A'Length;
+ Name_Buffer (1 .. Name_Len) := Libgnat_A;
+
+ if Osint.Find_File (Name_Enter, Osint.Library) /= No_File then
+ return Libgnat_A;
+
+ else
+ return Libgnat_Olb;
+ end if;
+ end Libgnat;
+
+ ------------------------
+ -- Library_Exists_For --
+ ------------------------
+
+ function Library_Exists_For (Project : Project_Id) return Boolean is
+ begin
+ if not Projects.Table (Project).Library then
+ Fail ("INTERNAL ERROR: Library_Exists_For called " &
+ "for non library project");
+ return False;
+
+ else
+ declare
+ Lib_Dir : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Dir);
+ Lib_Name : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Name);
+
+ begin
+ if Projects.Table (Project).Library_Kind = Static then
+ return Is_Regular_File
+ (Lib_Dir & Directory_Separator & "lib" &
+ Fil.Ext_To (Lib_Name, Archive_Ext));
+
+ else
+ return Is_Regular_File
+ (Lib_Dir & Directory_Separator & "lib" &
+ Fil.Ext_To (Lib_Name, DLL_Ext));
+ end if;
+ end;
+ end if;
+ end Library_Exists_For;
+
+ ---------------------------
+ -- Library_File_Name_For --
+ ---------------------------
+
+ function Library_File_Name_For (Project : Project_Id) return Name_Id is
+ begin
+ if not Projects.Table (Project).Library then
+ Prj.Com.Fail ("INTERNAL ERROR: Library_File_Name_For called " &
+ "for non library project");
+ return No_Name;
+
+ else
+ declare
+ Lib_Name : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Name);
+
+ begin
+ Name_Len := 3;
+ Name_Buffer (1 .. Name_Len) := "lib";
+
+ if Projects.Table (Project).Library_Kind = Static then
+ Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, Archive_Ext));
+
+ else
+ Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, DLL_Ext));
+ end if;
+
+ return Name_Find;
+ end;
+ end if;
+ end Library_File_Name_For;
+
+ ----------------
+ -- Object_Ext --
+ ----------------
+
+ function Object_Ext return String is
+ begin
+ return "obj";
+ end Object_Ext;
+
+ ----------------
+ -- PIC_Option --
+ ----------------
+
+ function PIC_Option return String is
+ begin
+ return "";
+ end PIC_Option;
+
+ -----------------------------------------------
+ -- Standalone_Library_Auto_Init_Is_Supported --
+ -----------------------------------------------
+
+ function Standalone_Library_Auto_Init_Is_Supported return Boolean is
+ begin
+ return True;
+ end Standalone_Library_Auto_Init_Is_Supported;
+
+ ---------------------------
+ -- Support_For_Libraries --
+ ---------------------------
+
+ function Support_For_Libraries return Library_Support is
+ begin
+ return Full;
+ end Support_For_Libraries;
+
+end MLib.Tgt;
diff --git a/gcc/ada/mlib-tgt-vxworks.adb b/gcc/ada/mlib-tgt-vxworks.adb
new file mode 100644
index 00000000000..9b3f5757463
--- /dev/null
+++ b/gcc/ada/mlib-tgt-vxworks.adb
@@ -0,0 +1,317 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- M L I B . T G T --
+-- (VxWorks Version) --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2003-2004 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- --
+-- 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, 59 Temple Place - Suite 330, Boston, --
+-- MA 02111-1307, USA. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides a set of target dependent routines to build
+-- static libraries.
+
+-- This is the VxWorks version of the body
+
+with MLib.Fil;
+with Namet; use Namet;
+with Prj.Com;
+with Sdefault;
+
+package body MLib.Tgt is
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ function Get_Target_Suffix return String;
+ -- Returns the required suffix for some utilities
+ -- (such as ar and ranlib) that depend on the real target.
+
+ ---------------------
+ -- Archive_Builder --
+ ---------------------
+
+ function Archive_Builder return String is
+ begin
+ return "ar" & Get_Target_Suffix;
+ end Archive_Builder;
+
+ -----------------------------
+ -- Archive_Builder_Options --
+ -----------------------------
+
+ function Archive_Builder_Options return String_List_Access is
+ begin
+ return new String_List'(1 => new String'("cr"));
+ end Archive_Builder_Options;
+
+ -----------------
+ -- Archive_Ext --
+ -----------------
+
+ function Archive_Ext return String is
+ begin
+ return "a";
+ end Archive_Ext;
+
+ ---------------------
+ -- Archive_Indexer --
+ ---------------------
+
+ function Archive_Indexer return String is
+ begin
+ return "ranlib" & Get_Target_Suffix;
+ end Archive_Indexer;
+
+ ---------------------------
+ -- Build_Dynamic_Library --
+ ---------------------------
+
+ procedure Build_Dynamic_Library
+ (Ofiles : Argument_List;
+ Foreign : Argument_List;
+ Afiles : Argument_List;
+ Options : Argument_List;
+ Interfaces : Argument_List;
+ Lib_Filename : String;
+ Lib_Dir : String;
+ Symbol_Data : Symbol_Record;
+ Driver_Name : Name_Id := No_Name;
+ Lib_Address : String := "";
+ Lib_Version : String := "";
+ Relocatable : Boolean := False;
+ Auto_Init : Boolean := False)
+ is
+ pragma Unreferenced (Ofiles);
+ pragma Unreferenced (Foreign);
+ pragma Unreferenced (Afiles);
+ pragma Unreferenced (Options);
+ pragma Unreferenced (Interfaces);
+ pragma Unreferenced (Lib_Filename);
+ pragma Unreferenced (Lib_Dir);
+ pragma Unreferenced (Symbol_Data);
+ pragma Unreferenced (Driver_Name);
+ pragma Unreferenced (Lib_Address);
+ pragma Unreferenced (Lib_Version);
+ pragma Unreferenced (Relocatable);
+ pragma Unreferenced (Auto_Init);
+
+ begin
+ null;
+ end Build_Dynamic_Library;
+
+ -------------------------
+ -- Default_DLL_Address --
+ -------------------------
+
+ function Default_DLL_Address return String is
+ begin
+ return "";
+ end Default_DLL_Address;
+
+ -------------
+ -- DLL_Ext --
+ -------------
+
+ function DLL_Ext return String is
+ begin
+ return "";
+ end DLL_Ext;
+
+ --------------------
+ -- Dynamic_Option --
+ --------------------
+
+ function Dynamic_Option return String is
+ begin
+ return "";
+ end Dynamic_Option;
+
+ -----------------------------
+ -- Get_Target_Suffix --
+ -----------------------------
+
+ function Get_Target_Suffix return String is
+ Target_Name : constant String_Ptr := Sdefault.Target_Name;
+ Index : Positive := Target_Name'First;
+
+ begin
+ while Index < Target_Name'Last
+ and then Target_Name (Index + 1) /= '-'
+ loop
+ Index := Index + 1;
+ end loop;
+
+ if Target_Name (Target_Name'First .. Index) = "m68k" then
+ return "68k";
+ elsif Target_Name (Target_Name'First .. Index) = "mips" then
+ return "mips";
+ elsif Target_Name (Target_Name'First .. Index) = "powerpc" then
+ return "ppc";
+ elsif Target_Name (Target_Name'First .. Index) = "sparc" then
+ return "sparc";
+ elsif Target_Name (Target_Name'First .. Index) = "sparc64" then
+ return "sparc64";
+ elsif Target_Name (Target_Name'First .. Index) = "xscale" then
+ return "arm";
+ else
+ return "";
+ end if;
+ end Get_Target_Suffix;
+
+ -------------------
+ -- Is_Object_Ext --
+ -------------------
+
+ function Is_Object_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".o";
+ end Is_Object_Ext;
+
+ --------------
+ -- Is_C_Ext --
+ --------------
+
+ function Is_C_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".c";
+ end Is_C_Ext;
+
+ --------------------
+ -- Is_Archive_Ext --
+ --------------------
+
+ function Is_Archive_Ext (Ext : String) return Boolean is
+ begin
+ return Ext = ".a";
+ end Is_Archive_Ext;
+
+ -------------
+ -- Libgnat --
+ -------------
+
+ function Libgnat return String is
+ begin
+ return "libgnat.a";
+ end Libgnat;
+
+ ------------------------
+ -- Library_Exists_For --
+ ------------------------
+
+ function Library_Exists_For (Project : Project_Id) return Boolean is
+ begin
+ if not Projects.Table (Project).Library then
+ Prj.Com.Fail ("INTERNAL ERROR: Library_Exists_For called " &
+ "for non library project");
+ return False; -- To avoid warning;
+
+ else
+ declare
+ Lib_Dir : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Dir);
+ Lib_Name : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Name);
+
+ begin
+ if Projects.Table (Project).Library_Kind = Static then
+ return Is_Regular_File
+ (Lib_Dir & Directory_Separator & "lib" &
+ Fil.Ext_To (Lib_Name, Archive_Ext));
+
+ else
+ return Is_Regular_File
+ (Lib_Dir & Directory_Separator & "lib" &
+ Fil.Ext_To (Lib_Name, DLL_Ext));
+ end if;
+ end;
+ end if;
+ end Library_Exists_For;
+
+ ---------------------------
+ -- Library_File_Name_For --
+ ---------------------------
+
+ function Library_File_Name_For (Project : Project_Id) return Name_Id is
+ begin
+ if not Projects.Table (Project).Library then
+ Prj.Com.Fail ("INTERNAL ERROR: Library_File_Name_For called " &
+ "for non library project");
+ return No_Name;
+
+ else
+ declare
+ Lib_Name : constant String :=
+ Get_Name_String (Projects.Table (Project).Library_Name);
+
+ begin
+ Name_Len := 3;
+ Name_Buffer (1 .. Name_Len) := "lib";
+
+ if Projects.Table (Project).Library_Kind = Static then
+ Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, Archive_Ext));
+
+ else
+ Add_Str_To_Name_Buffer (Fil.Ext_To (Lib_Name, DLL_Ext));
+ end if;
+
+ return Name_Find;
+ end;
+ end if;
+ end Library_File_Name_For;
+
+ ----------------
+ -- Object_Ext --
+ ----------------
+
+ function Object_Ext return String is
+ begin
+ return "o";
+ end Object_Ext;
+
+ ----------------
+ -- PIC_Option --
+ ----------------
+
+ function PIC_Option return String is
+ begin
+ return "";
+ end PIC_Option;
+
+ -----------------------------------------------
+ -- Standalone_Library_Auto_Init_Is_Supported --
+ -----------------------------------------------
+
+ function Standalone_Library_Auto_Init_Is_Supported return Boolean is
+ begin
+ return False;
+ end Standalone_Library_Auto_Init_Is_Supported;
+
+ ---------------------------
+ -- Support_For_Libraries --
+ ---------------------------
+
+ function Support_For_Libraries return Library_Support is
+ begin
+ return Static_Only;
+ end Support_For_Libraries;
+
+end MLib.Tgt;
diff --git a/gcc/ada/mlib-tgt.adb b/gcc/ada/mlib-tgt.adb
index 6cebb5cd442..dc137737257 100644
--- a/gcc/ada/mlib-tgt.adb
+++ b/gcc/ada/mlib-tgt.adb
@@ -190,15 +190,6 @@ package body MLib.Tgt is
return No_Name;
end Library_File_Name_For;
- --------------------------------
- -- Linker_Library_Path_Option --
- --------------------------------
-
- function Linker_Library_Path_Option return String_Access is
- begin
- return null;
- end Linker_Library_Path_Option;
-
----------------
-- Object_Ext --
----------------
diff --git a/gcc/ada/mlib-tgt.ads b/gcc/ada/mlib-tgt.ads
index a6458956cdc..5d142ae9a5c 100644
--- a/gcc/ada/mlib-tgt.ads
+++ b/gcc/ada/mlib-tgt.ads
@@ -101,11 +101,6 @@ package MLib.Tgt is
function Is_Archive_Ext (Ext : String) return Boolean;
-- Returns True iff Ext is an extension for a library
- function Linker_Library_Path_Option return String_Access;
- -- Linker option to specify to the linker the library directory path.
- -- If non null, the library directory path is to be appended.
- -- Should be deallocated by the caller, when no longer needed.
-
procedure Build_Dynamic_Library
(Ofiles : Argument_List;
Foreign : Argument_List;
diff --git a/gcc/ada/mlib-utl.adb b/gcc/ada/mlib-utl.adb
index 7c3a4ee707f..152d272b035 100644
--- a/gcc/ada/mlib-utl.adb
+++ b/gcc/ada/mlib-utl.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2002-2003, Ada Core Technologies, Inc. --
+-- Copyright (C) 2002-2004, Ada Core Technologies, 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- --
@@ -64,7 +64,6 @@ package body MLib.Utl is
Success : Boolean;
Line_Length : Natural := 0;
- Max_Line_Length : constant := 200; -- arbitrary
begin
Initialize;
@@ -82,9 +81,12 @@ package body MLib.Utl is
Line_Length := Ar_Name'Length;
for J in Arguments'Range loop
+
-- Make sure the Output buffer does not overflow
- if Line_Length + 1 + Arguments (J)'Length > Max_Line_Length then
+ if Line_Length + 1 + Arguments (J)'Length >
+ Integer (Opt.Max_Line_Length)
+ then
Write_Eol;
Line_Length := 0;
end if;
diff --git a/gcc/ada/mlib.adb b/gcc/ada/mlib.adb
index 5016587d5f8..8e6d0e37db9 100644
--- a/gcc/ada/mlib.adb
+++ b/gcc/ada/mlib.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1999-2003, Ada Core Technologies, Inc. --
+-- Copyright (C) 1999-2004, Ada Core Technologies, 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- --
@@ -25,6 +25,7 @@
------------------------------------------------------------------------------
with Ada.Characters.Handling; use Ada.Characters.Handling;
+with Interfaces.C.Strings;
with Hostparm;
with Opt;
@@ -285,13 +286,34 @@ package body MLib is
end if;
end Copy_ALI_Files;
+ --------------------------------
+ -- Linker_Library_Path_Option --
+ --------------------------------
+
+ function Linker_Library_Path_Option return String_Access is
+
+ Run_Path_Option_Ptr : Interfaces.C.Strings.chars_ptr;
+ pragma Import (C, Run_Path_Option_Ptr, "__gnat_run_path_option");
+ -- Pointer to string representing the native linker option which
+ -- specifies the path where the dynamic loader should find shared
+ -- libraries. Equal to null string if this system doesn't support it.
+
+ S : constant String := Interfaces.C.Strings.Value (Run_Path_Option_Ptr);
+
+ begin
+ if S'Length = 0 then
+ return null;
+ else
+ return new String'(S);
+ end if;
+ end Linker_Library_Path_Option;
+
-- Package elaboration
begin
- if Hostparm.OpenVMS then
-
- -- Copy_Attributes always fails on VMS
+ -- Copy_Attributes always fails on VMS
+ if Hostparm.OpenVMS then
Preserve := None;
end if;
end MLib;
diff --git a/gcc/ada/mlib.ads b/gcc/ada/mlib.ads
index c844ccbb389..eb9b3fe8f07 100644
--- a/gcc/ada/mlib.ads
+++ b/gcc/ada/mlib.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1999-2003, Ada Core Technologies, Inc. --
+-- Copyright (C) 1999-2004, Ada Core Technologies, 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- --
@@ -65,6 +65,11 @@ package MLib is
-- Copy all ALI files Files to directory To.
-- Mark Interfaces ALI files as interfaces, if any.
+ function Linker_Library_Path_Option return String_Access;
+ -- Linker option to specify to the linker the library directory path.
+ -- If non null, the library directory path is to be appended.
+ -- Should be deallocated by the caller, when no longer needed.
+
private
Preserve : Attribute := Time_Stamps;
diff --git a/gcc/ada/opt.ads b/gcc/ada/opt.ads
index 77468fa319c..eb34e50f3fc 100644
--- a/gcc/ada/opt.ads
+++ b/gcc/ada/opt.ads
@@ -398,6 +398,11 @@ package Opt is
-- effect if an explicit Link_Name is supplied (a link name is always
-- used exactly as given).
+ External_Unit_Compilation_Allowed : Boolean := False;
+ -- GNATMAKE
+ -- When True (set by gnatmake switch -x), allow compilation of sources
+ -- that are not part of any project file.
+
Float_Format : Character := ' ';
-- GNAT
-- A non-blank value indicates that a Float_Format pragma has been
@@ -526,6 +531,10 @@ package Opt is
-- then elaboration flag checks are to be generated in the binder
-- generated file.
+ Follow_Links : Boolean := False;
+ -- GNATMAKE
+ -- Set to True (-eL) to process the project files in trusted mode
+
Front_End_Inlining : Boolean := False;
-- GNAT
-- Set True to activate inlining by front-end expansion.
@@ -634,6 +643,11 @@ package Opt is
-- Set to True when either Compile_Only, Bind_Only or Link_Only is
-- set to True.
+ Main_Index : Int := 0;
+ -- GNATMAKE
+ -- This is set to non-zero by gnatmake switch -eInnn to indicate that
+ -- the main program is the nnn unit in a multi-unit source file.
+
Mapping_File_Name : String_Ptr := null;
-- GNAT
-- File name of mapping between unit names, file names and path names.
@@ -650,6 +664,15 @@ package Opt is
-- extension, as set by the appropriate switch. If no switch is given,
-- then this value is initialized by Osint to the appropriate value.
+ Max_Line_Length : Int := Hostparm.Max_Line_Length;
+ -- This is a copy of Max_Line_Length used by the scanner. It is usually
+ -- set to be a copy of Hostparm.Max_Line_Length, and is used to check
+ -- the maximum line length in the scanner when style checking is inactive.
+ -- The only time it is set to a different value is during the scanning of
+ -- configuration pragma files, where we want to turn off all checking and
+ -- in particular we want to allow long lines. So we reset this value to
+ -- Column_Number'Last during scanning of configuration pragma files.
+
Maximum_Processes : Positive := 1;
-- GNATMAKE
-- Maximum number of processes that should be spawned to carry out
diff --git a/gcc/ada/osint.adb b/gcc/ada/osint.adb
index 2dc5c321509..aa45a7a03b4 100644
--- a/gcc/ada/osint.adb
+++ b/gcc/ada/osint.adb
@@ -520,7 +520,7 @@ package body Osint is
-- Add_File --
--------------
- procedure Add_File (File_Name : String) is
+ procedure Add_File (File_Name : String; Index : Int := No_Index) is
begin
Number_File_Names := Number_File_Names + 1;
@@ -530,9 +530,12 @@ package body Osint is
if Number_File_Names > File_Names'Last then
File_Names := new File_Name_Array'(File_Names.all & File_Names.all);
+ File_Indexes :=
+ new File_Index_Array'(File_Indexes.all & File_Indexes.all);
end if;
- File_Names (Number_File_Names) := new String'(File_Name);
+ File_Names (Number_File_Names) := new String'(File_Name);
+ File_Indexes (Number_File_Names) := Index;
end Add_File;
------------------------
@@ -670,6 +673,15 @@ package body Osint is
end if;
end Create_File_And_Check;
+ ------------------------
+ -- Current_File_Index --
+ ------------------------
+
+ function Current_File_Index return Int is
+ begin
+ return File_Indexes (Current_File_Name_Index);
+ end Current_File_Index;
+
--------------------------------
-- Current_Library_File_Stamp --
--------------------------------
@@ -1017,13 +1029,12 @@ package body Osint is
if Command_Name (Cindex2) in '0' .. '9' then
for J in reverse Cindex1 .. Cindex2 loop
-
- exit when Command_Name (J) not in '0' .. '9';
-
if Command_Name (J) = '.' or Command_Name (J) = ';' then
Cindex2 := J - 1;
exit;
end if;
+
+ exit when Command_Name (J) not in '0' .. '9';
end loop;
end if;
diff --git a/gcc/ada/osint.ads b/gcc/ada/osint.ads
index 44ad5bad4ed..6e5672d1aca 100644
--- a/gcc/ada/osint.ads
+++ b/gcc/ada/osint.ads
@@ -92,9 +92,15 @@ package Osint is
function Number_Of_Files return Int;
-- gives the total number of filenames found on the command line.
- procedure Add_File (File_Name : String);
+ No_Index : constant := -1;
+ -- Value used in Add_File to indicate that no index is specified
+ -- for a main.
+
+ procedure Add_File (File_Name : String; Index : Int := No_Index);
-- Called by the subprogram processing the command line for each
- -- file name found.
+ -- file name found. The index, when not defaulted to No_Index
+ -- is the index of the subprogram in its source, zero indicating
+ -- that the source is not multi-unit.
procedure Find_Program_Name;
-- Put simple name of current program being run (excluding the directory
@@ -379,6 +385,9 @@ package Osint is
-- every single time the routines are called unless you have previously
-- called Source_File_Data (Cache => True). See below.
+ function Current_File_Index return Int;
+ -- Return the index in its source file of the current main unit
+
function Matching_Full_Source_Name
(N : File_Name_Type;
T : Time_Stamp_Type) return File_Name_Type;
@@ -573,6 +582,11 @@ private
-- extensible, because when using project files, there may be
-- more files than arguments on the command line.
+ type File_Index_Array is array (Int range <>) of Int;
+ type File_Index_Array_Ptr is access File_Index_Array;
+ File_Indexes : File_Index_Array_Ptr :=
+ new File_Index_Array (1 .. Int (Argument_Count) + 2);
+
Current_File_Name_Index : Int := 0;
-- The index in File_Names of the last file opened by Next_Main_Source
-- or Next_Main_Lib_File. The value 0 indicates that no files have been
diff --git a/gcc/ada/par-ch10.adb b/gcc/ada/par-ch10.adb
index d45e727e97c..d776635a778 100644
--- a/gcc/ada/par-ch10.adb
+++ b/gcc/ada/par-ch10.adb
@@ -799,8 +799,8 @@ package body Ch10 is
-- Processing for WITH clause
- -- Ada0Y (AI-50217): First check for LIMITED WITH, PRIVATE WITH,
- -- or both.
+ -- Ada0Y (AI-50217, AI-262): First check for LIMITED WITH,
+ -- PRIVATE WITH, or both.
if Token = Tok_Limited then
Has_Limited := True;
diff --git a/gcc/ada/par-ch3.adb b/gcc/ada/par-ch3.adb
index c109d3f2387..dad0101e46a 100644
--- a/gcc/ada/par-ch3.adb
+++ b/gcc/ada/par-ch3.adb
@@ -741,10 +741,8 @@ package body Ch3 is
Scan; -- past NEW
end if;
- if Extensions_Allowed then -- Ada 0Y (AI-231)
- Not_Null_Present := P_Null_Exclusion;
- Set_Null_Exclusion_Present (Decl_Node, Not_Null_Present);
- end if;
+ Not_Null_Present := P_Null_Exclusion; -- Ada 0Y (AI-231)
+ Set_Null_Exclusion_Present (Decl_Node, Not_Null_Present);
Set_Subtype_Indication
(Decl_Node, P_Subtype_Indication (Not_Null_Present));
@@ -1293,7 +1291,6 @@ package body Ch3 is
else
Decl_Node := New_Node (N_Object_Declaration, Ident_Sloc);
- Set_Null_Exclusion_Present (Decl_Node, Not_Null_Present);
Set_Constant_Present (Decl_Node, True);
if Token_Name = Name_Aliased then
@@ -1312,10 +1309,8 @@ package body Ch3 is
(Decl_Node, P_Array_Type_Definition);
else
- if Extensions_Allowed then -- Ada 0Y (AI-231)
- Not_Null_Present := P_Null_Exclusion;
- Set_Null_Exclusion_Present (Decl_Node, Not_Null_Present);
- end if;
+ Not_Null_Present := P_Null_Exclusion; -- Ada 0Y (AI-231)
+ Set_Null_Exclusion_Present (Decl_Node, Not_Null_Present);
Set_Object_Definition (Decl_Node,
P_Subtype_Indication (Not_Null_Present));
@@ -1351,7 +1346,6 @@ package body Ch3 is
Scan; -- past ALIASED
Decl_Node := New_Node (N_Object_Declaration, Ident_Sloc);
Set_Aliased_Present (Decl_Node, True);
- Set_Null_Exclusion_Present (Decl_Node, Not_Null_Present);
if Token = Tok_Constant then
Scan; -- past CONSTANT
@@ -1363,11 +1357,8 @@ package body Ch3 is
(Decl_Node, P_Array_Type_Definition);
else
- if Extensions_Allowed then -- Ada 0Y (AI-231)
- Not_Null_Present := P_Null_Exclusion;
- Set_Null_Exclusion_Present (Decl_Node, Not_Null_Present);
- end if;
-
+ Not_Null_Present := P_Null_Exclusion; -- Ada 0Y (AI-231)
+ Set_Null_Exclusion_Present (Decl_Node, Not_Null_Present);
Set_Object_Definition (Decl_Node,
P_Subtype_Indication (Not_Null_Present));
end if;
@@ -1378,6 +1369,74 @@ package body Ch3 is
Decl_Node := New_Node (N_Object_Declaration, Ident_Sloc);
Set_Object_Definition (Decl_Node, P_Array_Type_Definition);
+ -- Ada 0Y (AI-254)
+
+ elsif Token = Tok_Not then
+
+ -- OBJECT_DECLARATION ::=
+ -- DEFINING_IDENTIFIER_LIST : [aliased] [constant]
+ -- [NULL_EXCLUSION] SUBTYPE_INDICATION [:= EXPRESSION];
+
+ -- OBJECT_RENAMING_DECLARATION ::=
+ -- ...
+ -- | DEFINING_IDENTIFIER : ACCESS_DEFINITION renames object_NAME;
+
+ Not_Null_Present := P_Null_Exclusion; -- Ada 0Y (AI-231)
+
+ if Token = Tok_Access then
+ if not Extensions_Allowed then
+ Error_Msg_SP
+ ("generalized use of anonymous access types " &
+ "is an Ada 0Y extension");
+ Error_Msg_SP ("\unit must be compiled with -gnatX switch");
+ end if;
+
+ Acc_Node := P_Access_Definition (Not_Null_Present);
+
+ if Token /= Tok_Renames then
+ Error_Msg_SC ("'RENAMES' expected");
+ raise Error_Resync;
+ end if;
+
+ Scan; -- past renames
+ No_List;
+ Decl_Node :=
+ New_Node (N_Object_Renaming_Declaration, Ident_Sloc);
+ Set_Access_Definition (Decl_Node, Acc_Node);
+ Set_Name (Decl_Node, P_Name);
+
+ else
+ Type_Node := P_Subtype_Mark;
+
+ -- Object renaming declaration
+
+ if Token_Is_Renames then
+ Error_Msg_SP ("(Ada 0Y) null-exclusion not allowed in "
+ & "object renamings");
+ raise Error_Resync;
+
+ -- Object declaration
+
+ else
+ Decl_Node := New_Node (N_Object_Declaration, Ident_Sloc);
+ Set_Null_Exclusion_Present (Decl_Node, Not_Null_Present);
+ Set_Object_Definition
+ (Decl_Node,
+ P_Subtype_Indication (Type_Node, Not_Null_Present));
+
+ -- RENAMES at this point means that we had the combination
+ -- of a constraint on the Type_Node and renames, which is
+ -- illegal
+
+ if Token_Is_Renames then
+ Error_Msg_N ("constraint not allowed in object renaming "
+ & "declaration",
+ Constraint (Object_Definition (Decl_Node)));
+ raise Error_Resync;
+ end if;
+ end if;
+ end if;
+
-- Ada 0Y (AI-230): Access Definition case
elsif Token = Tok_Access then
@@ -1388,7 +1447,7 @@ package body Ch3 is
Error_Msg_SP ("\unit must be compiled with -gnatX switch");
end if;
- Acc_Node := P_Access_Definition;
+ Acc_Node := P_Access_Definition (Null_Exclusion_Present => False);
if Token /= Tok_Renames then
Error_Msg_SC ("'RENAMES' expected");
@@ -1405,20 +1464,11 @@ package body Ch3 is
-- Subtype indication case
else
- if Extensions_Allowed then -- Ada 0Y (AI-231)
- Not_Null_Present := P_Null_Exclusion;
- end if;
-
Type_Node := P_Subtype_Mark;
-- Object renaming declaration
if Token_Is_Renames then
- if Not_Null_Present then
- Error_Msg_SP
- ("(Ada 0Y) null-exclusion not allowed in renamings");
- end if;
-
No_List;
Decl_Node :=
New_Node (N_Object_Renaming_Declaration, Ident_Sloc);
@@ -1551,11 +1601,8 @@ package body Ch3 is
Scan;
end if;
- if Extensions_Allowed then -- Ada 0Y (AI-231)
- Not_Null_Present := P_Null_Exclusion;
- Set_Null_Exclusion_Present (Typedef_Node, Not_Null_Present);
- end if;
-
+ Not_Null_Present := P_Null_Exclusion; -- Ada 0Y (AI-231)
+ Set_Null_Exclusion_Present (Typedef_Node, Not_Null_Present);
Set_Subtype_Indication (Typedef_Node,
P_Subtype_Indication (Not_Null_Present));
@@ -2130,6 +2177,7 @@ package body Ch3 is
Not_Null_Present : Boolean := False;
Subs_List : List_Id;
Scan_State : Saved_Scan_State;
+ Aliased_Present : Boolean := False;
begin
Array_Loc := Token_Ptr;
@@ -2189,6 +2237,17 @@ package body Ch3 is
CompDef_Node := New_Node (N_Component_Definition, Token_Ptr);
+ if Token_Name = Name_Aliased then
+ Check_95_Keyword (Tok_Aliased, Tok_Identifier);
+ end if;
+
+ if Token = Tok_Aliased then
+ Aliased_Present := True;
+ Scan; -- past ALIASED
+ end if;
+
+ Not_Null_Present := P_Null_Exclusion; -- Ada 0Y (AI-231/AI-254)
+
-- Ada 0Y (AI-230): Access Definition case
if Token = Tok_Access then
@@ -2199,28 +2258,21 @@ package body Ch3 is
Error_Msg_SP ("\unit must be compiled with -gnatX switch");
end if;
- Set_Subtype_Indication (CompDef_Node, Empty);
- Set_Aliased_Present (CompDef_Node, False);
- Set_Access_Definition (CompDef_Node, P_Access_Definition);
- else
- Set_Access_Definition (CompDef_Node, Empty);
-
- if Token_Name = Name_Aliased then
- Check_95_Keyword (Tok_Aliased, Tok_Identifier);
- end if;
-
- if Token = Tok_Aliased then
- Set_Aliased_Present (CompDef_Node, True);
- Scan; -- past ALIASED
+ if Aliased_Present then
+ Error_Msg_SP ("ALIASED not allowed here");
end if;
- if Extensions_Allowed then -- Ada 0Y (AI-231)
- Not_Null_Present := P_Null_Exclusion;
- Set_Null_Exclusion_Present (CompDef_Node, Not_Null_Present);
- end if;
+ Set_Subtype_Indication (CompDef_Node, Empty);
+ Set_Aliased_Present (CompDef_Node, False);
+ Set_Access_Definition (CompDef_Node,
+ P_Access_Definition (Not_Null_Present));
+ else
- Set_Subtype_Indication (CompDef_Node,
- P_Subtype_Indication (Not_Null_Present));
+ Set_Access_Definition (CompDef_Node, Empty);
+ Set_Aliased_Present (CompDef_Node, Aliased_Present);
+ Set_Null_Exclusion_Present (CompDef_Node, Not_Null_Present);
+ Set_Subtype_Indication (CompDef_Node,
+ P_Subtype_Indication (Not_Null_Present));
end if;
Set_Component_Definition (Def_Node, CompDef_Node);
@@ -2444,7 +2496,6 @@ package body Ch3 is
Specification_Node :=
New_Node (N_Discriminant_Specification, Ident_Sloc);
Set_Defining_Identifier (Specification_Node, Idents (Ident));
-
Not_Null_Present := P_Null_Exclusion; -- Ada 0Y (AI-231)
if Token = Tok_Access then
@@ -2454,11 +2505,10 @@ package body Ch3 is
end if;
Set_Discriminant_Type
- (Specification_Node, P_Access_Definition);
- Set_Null_Exclusion_Present -- Ada 0Y (AI-231)
- (Discriminant_Type (Specification_Node),
- Not_Null_Present);
+ (Specification_Node,
+ P_Access_Definition (Not_Null_Present));
else
+
Set_Discriminant_Type
(Specification_Node, P_Subtype_Mark);
No_Constraint;
@@ -2876,6 +2926,7 @@ package body Ch3 is
-- items, do we need to add this capability sometime in the future ???
procedure P_Component_Items (Decls : List_Id) is
+ Aliased_Present : Boolean := False;
CompDef_Node : Node_Id;
Decl_Node : Node_Id;
Scan_State : Saved_Scan_State;
@@ -2935,6 +2986,19 @@ package body Ch3 is
CompDef_Node := New_Node (N_Component_Definition, Token_Ptr);
+ if Token_Name = Name_Aliased then
+ Check_95_Keyword (Tok_Aliased, Tok_Identifier);
+ end if;
+
+ if Token = Tok_Aliased then
+ Aliased_Present := True;
+ Scan; -- past ALIASED
+ end if;
+
+ Not_Null_Present := P_Null_Exclusion; -- Ada 0Y (AI-231/AI-254)
+
+ -- Ada 0Y (AI-230): Access Definition case
+
if Token = Tok_Access then
if not Extensions_Allowed then
Error_Msg_SP
@@ -2943,21 +3007,19 @@ package body Ch3 is
Error_Msg_SP ("\unit must be compiled with -gnatX switch");
end if;
+ if Aliased_Present then
+ Error_Msg_SP ("ALIASED not allowed here");
+ end if;
+
Set_Subtype_Indication (CompDef_Node, Empty);
Set_Aliased_Present (CompDef_Node, False);
- Set_Access_Definition (CompDef_Node, P_Access_Definition);
+ Set_Access_Definition (CompDef_Node,
+ P_Access_Definition (Not_Null_Present));
else
- Set_Access_Definition (CompDef_Node, Empty);
-
- if Token_Name = Name_Aliased then
- Check_95_Keyword (Tok_Aliased, Tok_Identifier);
- end if;
-
- if Token = Tok_Aliased then
- Scan; -- past ALIASED
- Set_Aliased_Present (CompDef_Node, True);
- end if;
+ Set_Access_Definition (CompDef_Node, Empty);
+ Set_Aliased_Present (CompDef_Node, Aliased_Present);
+ Set_Null_Exclusion_Present (CompDef_Node, Not_Null_Present);
if Token = Tok_Array then
Error_Msg_SC
@@ -2965,13 +3027,8 @@ package body Ch3 is
raise Error_Resync;
end if;
- if Extensions_Allowed then -- Ada 0Y (AI-231)
- Not_Null_Present := P_Null_Exclusion;
- Set_Null_Exclusion_Present (CompDef_Node, Not_Null_Present);
- end if;
-
Set_Subtype_Indication (CompDef_Node,
- P_Subtype_Indication (Not_Null_Present));
+ P_Subtype_Indication (Not_Null_Present));
end if;
Set_Component_Definition (Decl_Node, CompDef_Node);
@@ -3231,15 +3288,18 @@ package body Ch3 is
-- PARAMETER_AND_RESULT_PROFILE ::= [FORMAL_PART] RETURN SUBTYPE_MARK
- -- The caller has checked that the initial token is ACCESS
+ -- Ada 0Y (AI-254): If Header_Already_Parsed then the caller has already
+ -- parsed the null_exclusion part and has also removed the ACCESS token;
+ -- otherwise the caller has just checked that the initial token is ACCESS
-- Error recovery: can raise Error_Resync
- function P_Access_Type_Definition return Node_Id is
- Prot_Flag : Boolean;
- Access_Loc : Source_Ptr;
- Not_Null_Present : Boolean := False;
- Type_Def_Node : Node_Id;
+ function P_Access_Type_Definition
+ (Header_Already_Parsed : Boolean := False) return Node_Id is
+ Access_Loc : constant Source_Ptr := Token_Ptr;
+ Prot_Flag : Boolean;
+ Not_Null_Present : Boolean := False;
+ Type_Def_Node : Node_Id;
procedure Check_Junk_Subprogram_Name;
-- Used in access to subprogram definition cases to check for an
@@ -3266,13 +3326,11 @@ package body Ch3 is
-- Start of processing for P_Access_Type_Definition
begin
- if Extensions_Allowed then -- Ada 0Y (AI-231)
- Not_Null_Present := P_Null_Exclusion;
+ if not Header_Already_Parsed then
+ Not_Null_Present := P_Null_Exclusion; -- Ada 0Y (AI-231)
+ Scan; -- past ACCESS
end if;
- Access_Loc := Token_Ptr;
- Scan; -- past ACCESS
-
if Token_Name = Name_Protected then
Check_95_Keyword (Tok_Protected, Tok_Procedure);
Check_95_Keyword (Tok_Protected, Tok_Function);
@@ -3366,33 +3424,74 @@ package body Ch3 is
-- ACCESS_DEFINITION ::=
-- [NULL_EXCLUSION] access [GENERAL_ACCESS_MODIFIER] SUBTYPE_MARK
+ -- | ACCESS_TO_SUBPROGRAM_DEFINITION
+ --
+ -- ACCESS_TO_SUBPROGRAM_DEFINITION
+ -- [NULL_EXCLUSION] access [protected] procedure PARAMETER_PROFILE
+ -- | [NULL_EXCLUSION] access [protected] function
+ -- PARAMETER_AND_RESULT_PROFILE
- -- The caller has checked that the initial token is ACCESS
+ -- The caller has parsed the null-exclusion part and it has also checked
+ -- that the next token is ACCESS
-- Error recovery: cannot raise Error_Resync
- function P_Access_Definition return Node_Id is
- Def_Node : Node_Id;
+ function P_Access_Definition
+ (Null_Exclusion_Present : Boolean) return Node_Id is
+ Def_Node : Node_Id;
+ Subp_Node : Node_Id;
begin
Def_Node := New_Node (N_Access_Definition, Token_Ptr);
Scan; -- past ACCESS
- -- Ada 0Y (AI-231)
+ -- Ada 0Y (AI-254/AI-231)
if Extensions_Allowed then
- if Token = Tok_All then
- Scan; -- past ALL
- Set_All_Present (Def_Node);
- elsif Token = Tok_Constant then
- Scan; -- past CONSTANT
- Set_Constant_Present (Def_Node);
+ -- Ada 0Y (AI-254): Access_To_Subprogram_Definition
+
+ if Token = Tok_Protected
+ or else Token = Tok_Procedure
+ or else Token = Tok_Function
+ then
+ Subp_Node :=
+ P_Access_Type_Definition (Header_Already_Parsed => True);
+ Set_Null_Exclusion_Present (Subp_Node, Null_Exclusion_Present);
+ Set_Access_To_Subprogram_Definition (Def_Node, Subp_Node);
+
+ -- Ada 0Y (AI-231)
+ -- [NULL_EXCLUSION] access [GENERAL_ACCESS_MODIFIER] SUBTYPE_MARK
+
+ else
+ Set_Null_Exclusion_Present (Def_Node, Null_Exclusion_Present);
+
+ if Token = Tok_All then
+ Scan; -- past ALL
+ Set_All_Present (Def_Node);
+
+ elsif Token = Tok_Constant then
+ Scan; -- past CONSTANT
+ Set_Constant_Present (Def_Node);
+ end if;
+
+ Set_Subtype_Mark (Def_Node, P_Subtype_Mark);
+ No_Constraint;
end if;
+
+ -- Ada 95
+
+ else
+ -- Ada 0Y (AI-254): The null-exclusion present is never present
+ -- in Ada 83 and Ada 95
+
+ pragma Assert (Null_Exclusion_Present = False);
+
+ Set_Null_Exclusion_Present (Def_Node, False);
+ Set_Subtype_Mark (Def_Node, P_Subtype_Mark);
+ No_Constraint;
end if;
- Set_Subtype_Mark (Def_Node, P_Subtype_Mark);
- No_Constraint;
return Def_Node;
end P_Access_Definition;
diff --git a/gcc/ada/par-ch6.adb b/gcc/ada/par-ch6.adb
index 3d7e2708c84..406545d4316 100644
--- a/gcc/ada/par-ch6.adb
+++ b/gcc/ada/par-ch6.adb
@@ -963,8 +963,8 @@ package body Ch6 is
Error_Msg_SC ("(Ada 83) access parameters not allowed");
end if;
- Set_Parameter_Type
- (Specification_Node, P_Access_Definition);
+ Set_Parameter_Type (Specification_Node,
+ P_Access_Definition (Not_Null_Present));
else
if Token = Tok_In or else Token = Tok_Out then
diff --git a/gcc/ada/par-prag.adb b/gcc/ada/par-prag.adb
index 23f280c4aba..941d7d256e0 100644
--- a/gcc/ada/par-prag.adb
+++ b/gcc/ada/par-prag.adb
@@ -655,7 +655,7 @@ begin
if Nast /= 1 then
Error_Msg_N
("file name pattern must have exactly one * character",
- Arg2);
+ Arg1);
return Pragma_Node;
end if;
diff --git a/gcc/ada/par.adb b/gcc/ada/par.adb
index 2d86577a48c..85a2fde13e2 100644
--- a/gcc/ada/par.adb
+++ b/gcc/ada/par.adb
@@ -557,8 +557,6 @@ function Par (Configuration_Pragmas : Boolean) return List_Id is
-- variable, then the caller can change it to an appropriate missing
-- begin message if indeed the BEGIN is missing.
- function P_Access_Definition return Node_Id;
- function P_Access_Type_Definition return Node_Id;
function P_Array_Type_Definition return Node_Id;
function P_Basic_Declarative_Items return List_Id;
function P_Constraint_Opt return Node_Id;
@@ -576,6 +574,17 @@ function Par (Configuration_Pragmas : Boolean) return List_Id is
function P_Subtype_Mark_Resync return Node_Id;
function P_Unknown_Discriminant_Part_Opt return Boolean;
+ function P_Access_Definition
+ (Null_Exclusion_Present : Boolean) return Node_Id;
+ -- Ada 0Y (AI-231/AI-254): The caller parses the null-exclusion part
+ -- and indicates if it was present
+
+ function P_Access_Type_Definition
+ (Header_Already_Parsed : Boolean := False) return Node_Id;
+ -- Ada 0Y (AI-254): The formal is used to indicate if the caller has
+ -- parsed the null_exclusion part. In this case the caller has also
+ -- removed the ACCESS token
+
procedure P_Component_Items (Decls : List_Id);
-- Scan out one or more component items and append them to the
-- given list. Only scans out more than one declaration in the
@@ -1268,7 +1277,6 @@ begin
Save_Style_Check : constant Boolean := Style_Check;
-
begin
Operating_Mode := Check_Syntax;
Style_Check := False;
diff --git a/gcc/ada/prj-attr.adb b/gcc/ada/prj-attr.adb
index 6e8cc6cccb0..a0588bcb4e1 100644
--- a/gcc/ada/prj-attr.adb
+++ b/gcc/ada/prj-attr.adb
@@ -39,7 +39,9 @@ package body Prj.Attr is
-- The first letter is one of
-- 'S' for Single
- -- 'L' for list
+ -- 's' for Single with optional index
+ -- 'L' for List
+ -- 'l' for List of strings with optional indexes
-- The second letter is one of
-- 'V' for single variable
@@ -47,6 +49,7 @@ package body Prj.Attr is
-- 'a' for case insensitive associative array
-- 'b' for associative array, case insensitive if file names are case
-- insensitive
+ -- 'c' same as 'b', with optional index
-- End is indicated by two consecutive '#'.
@@ -72,7 +75,7 @@ package body Prj.Attr is
"SVlibrary_symbol_file#" &
"SVlibrary_symbol_policy#" &
"SVlibrary_reference_symbol_file#" &
- "LVmain#" &
+ "lVmain#" &
"LVlanguages#" &
"SVmain_language#" &
@@ -86,10 +89,10 @@ package body Prj.Attr is
"SVseparate_suffix#" &
"SVcasing#" &
"SVdot_replacement#" &
- "SAspecification#" &
- "SAspec#" &
- "SAimplementation#" &
- "SAbody#" &
+ "sAspecification#" &
+ "sAspec#" &
+ "sAimplementation#" &
+ "sAbody#" &
"Laspecification_exceptions#" &
"Laimplementation_exceptions#" &
@@ -97,15 +100,15 @@ package body Prj.Attr is
"Pcompiler#" &
"Ladefault_switches#" &
- "Lbswitches#" &
+ "Lcswitches#" &
"SVlocal_configuration_pragmas#" &
-- package Builder
"Pbuilder#" &
"Ladefault_switches#" &
- "Lbswitches#" &
- "Sbexecutable#" &
+ "Lcswitches#" &
+ "Scexecutable#" &
"SVexecutable_suffix#" &
"SVglobal_configuration_pragmas#" &
@@ -118,13 +121,13 @@ package body Prj.Attr is
"Pbinder#" &
"Ladefault_switches#" &
- "Lbswitches#" &
+ "Lcswitches#" &
-- package Linker
"Plinker#" &
"Ladefault_switches#" &
- "Lbswitches#" &
+ "Lcswitches#" &
"LVlinker_options#" &
-- package Cross_Reference
@@ -184,6 +187,7 @@ package body Prj.Attr is
Current_Attribute : Attribute_Node_Id := Empty_Attribute;
Is_An_Attribute : Boolean := False;
Kind_1 : Variable_Kind := Undefined;
+ Optional_Index : Boolean := False;
Kind_2 : Attribute_Kind := Single;
Package_Name : Name_Id := No_Name;
Attribute_Name : Name_Id := No_Name;
@@ -232,10 +236,20 @@ package body Prj.Attr is
Start := Finish + 1;
when 'S' =>
- Kind_1 := Single;
+ Kind_1 := Single;
+ Optional_Index := False;
+
+ when 's' =>
+ Kind_1 := Single;
+ Optional_Index := True;
when 'L' =>
- Kind_1 := List;
+ Kind_1 := List;
+ Optional_Index := False;
+
+ when 'l' =>
+ Kind_1 := List;
+ Optional_Index := True;
when others =>
raise Program_Error;
@@ -263,6 +277,14 @@ package body Prj.Attr is
Kind_2 := Case_Insensitive_Associative_Array;
end if;
+ when 'c' =>
+ if File_Names_Case_Sensitive then
+ Kind_2 := Optional_Index_Associative_Array;
+ else
+ Kind_2 :=
+ Optional_Index_Case_Insensitive_Associative_Array;
+ end if;
+
when others =>
raise Program_Error;
end case;
@@ -279,6 +301,7 @@ package body Prj.Attr is
To_Lower (Initialization_Data (Start .. Finish - 1));
Attribute_Name := Name_Find;
Attributes.Increment_Last;
+
if Current_Attribute = Empty_Attribute then
First_Attribute := Attributes.Last;
@@ -306,10 +329,11 @@ package body Prj.Attr is
Current_Attribute := Attributes.Last;
Attributes.Table (Current_Attribute) :=
- (Name => Attribute_Name,
- Kind_1 => Kind_1,
- Kind_2 => Kind_2,
- Next => Empty_Attribute);
+ (Name => Attribute_Name,
+ Kind_1 => Kind_1,
+ Optional_Index => Optional_Index,
+ Kind_2 => Kind_2,
+ Next => Empty_Attribute);
Start := Finish + 1;
end if;
end loop;
diff --git a/gcc/ada/prj-attr.ads b/gcc/ada/prj-attr.ads
index cf3c140b11f..9ca7ded47c1 100644
--- a/gcc/ada/prj-attr.ads
+++ b/gcc/ada/prj-attr.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2001-2002 Free Software Foundation, Inc. --
+-- Copyright (C) 2001-2004 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- --
@@ -53,13 +53,16 @@ package Prj.Attr is
type Attribute_Kind is
(Single,
Associative_Array,
- Case_Insensitive_Associative_Array);
+ Optional_Index_Associative_Array,
+ Case_Insensitive_Associative_Array,
+ Optional_Index_Case_Insensitive_Associative_Array);
type Attribute_Record is record
- Name : Name_Id;
- Kind_1 : Variable_Kind;
- Kind_2 : Attribute_Kind;
- Next : Attribute_Node_Id;
+ Name : Name_Id;
+ Kind_1 : Variable_Kind;
+ Optional_Index : Boolean;
+ Kind_2 : Attribute_Kind;
+ Next : Attribute_Node_Id;
end record;
package Attributes is
diff --git a/gcc/ada/prj-com.ads b/gcc/ada/prj-com.ads
index 123ff290f67..e4e73d92209 100644
--- a/gcc/ada/prj-com.ads
+++ b/gcc/ada/prj-com.ads
@@ -56,6 +56,7 @@ package Prj.Com is
type File_Name_Data is record
Name : Name_Id := No_Name;
+ Index : Int := 0;
Display_Name : Name_Id := No_Name;
Path : Name_Id := No_Name;
Display_Path : Name_Id := No_Name;
diff --git a/gcc/ada/prj-dect.adb b/gcc/ada/prj-dect.adb
index ac39eeda369..0db8d9150bd 100644
--- a/gcc/ada/prj-dect.adb
+++ b/gcc/ada/prj-dect.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2001-2003 Free Software Foundation, Inc --
+-- Copyright (C) 2001-2004 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- --
@@ -33,6 +33,7 @@ with Scans; use Scans;
with Snames;
with Types; use Types;
with Prj.Attr; use Prj.Attr;
+with Uintp; use Uintp;
package body Prj.Dect is
@@ -121,6 +122,7 @@ package body Prj.Dect is
Current_Attribute : Attribute_Node_Id := First_Attribute;
Full_Associative_Array : Boolean := False;
Attribute_Name : Name_Id := No_Name;
+ Optional_Index : Boolean := False;
begin
Attribute := Default_Project_Node (Of_Kind => N_Attribute_Declaration);
@@ -194,8 +196,9 @@ package body Prj.Dect is
-- Set, if appropriate the index case insensitivity flag
- elsif Attributes.Table (Current_Attribute).Kind_2 =
- Case_Insensitive_Associative_Array
+ elsif Attributes.Table (Current_Attribute).Kind_2 in
+ Case_Insensitive_Associative_Array ..
+ Optional_Index_Case_Insensitive_Associative_Array
then
Set_Case_Insensitive (Attribute, To => True);
end if;
@@ -245,6 +248,41 @@ package body Prj.Dect is
if Token = Tok_String_Literal then
Set_Associative_Array_Index_Of (Attribute, Token_Name);
Scan; -- past the literal string index
+
+ if Token = Tok_At then
+ case Attributes.Table (Current_Attribute).Kind_2 is
+ when Optional_Index_Associative_Array |
+ Optional_Index_Case_Insensitive_Associative_Array =>
+ Scan;
+ Expect (Tok_Integer_Literal, "integer literal");
+
+ if Token = Tok_Integer_Literal then
+
+ -- Set the source index value from given literal
+
+ declare
+ Index : constant Int :=
+ UI_To_Int (Int_Literal_Value);
+ begin
+ if Index = 0 then
+ Error_Msg ("index cannot be zero", Token_Ptr);
+ else
+ Set_Source_Index_Of (Attribute, To => Index);
+ end if;
+ end;
+
+ Scan;
+ end if;
+
+ when others =>
+ Error_Msg ("index not allowed here", Token_Ptr);
+ Scan;
+
+ if Token = Tok_Integer_Literal then
+ Scan;
+ end if;
+ end case;
+ end if;
end if;
Expect (Tok_Right_Paren, "`)`");
@@ -271,6 +309,7 @@ package body Prj.Dect is
if Current_Attribute /= Empty_Attribute then
Set_Expression_Kind_Of
(Attribute, To => Attributes.Table (Current_Attribute).Kind_1);
+ Optional_Index := Attributes.Table (Current_Attribute).Optional_Index;
end if;
Expect (Tok_Use, "USE");
@@ -439,7 +478,8 @@ package body Prj.Dect is
Parse_Expression
(Expression => Expression,
Current_Project => Current_Project,
- Current_Package => Current_Package);
+ Current_Package => Current_Package,
+ Optional_Index => Optional_Index);
Set_Expression_Of (Attribute, To => Expression);
-- If the expression is legal, but not of the right kind
@@ -1225,7 +1265,8 @@ package body Prj.Dect is
Parse_Expression
(Expression => Expression,
Current_Project => Current_Project,
- Current_Package => Current_Package);
+ Current_Package => Current_Package,
+ Optional_Index => False);
Set_Expression_Of (Variable, To => Expression);
if Expression /= Empty_Node then
diff --git a/gcc/ada/prj-env.adb b/gcc/ada/prj-env.adb
index 5fd829039c3..b8e3fc7bf02 100644
--- a/gcc/ada/prj-env.adb
+++ b/gcc/ada/prj-env.adb
@@ -572,7 +572,9 @@ package body Prj.Env is
-- For call to Close
procedure Check (Project : Project_Id);
- -- ??? requires a comment
+ -- Recursive procedure that put in the config pragmas file any non
+ -- standard naming schemes, if it is not already in the file, then call
+ -- itself for any imported project.
procedure Check_Temp_File;
-- Check that a temporary file has been opened.
@@ -582,7 +584,8 @@ package body Prj.Env is
procedure Put
(Unit_Name : Name_Id;
File_Name : Name_Id;
- Unit_Kind : Spec_Or_Body);
+ Unit_Kind : Spec_Or_Body;
+ Index : Int);
-- Put an SFN pragma in the temporary file
procedure Put (File : File_Descriptor; S : String);
@@ -740,7 +743,8 @@ package body Prj.Env is
procedure Put
(Unit_Name : Name_Id;
File_Name : Name_Id;
- Unit_Kind : Spec_Or_Body)
+ Unit_Kind : Spec_Or_Body;
+ Index : Int)
is
begin
-- A temporary file needs to be open
@@ -759,7 +763,14 @@ package body Prj.Env is
end if;
Put (File, Namet.Get_Name_String (File_Name));
- Put_Line (File, """);");
+ Put (File, """");
+
+ if Index /= 0 then
+ Put (File, ", Index =>");
+ Put (File, Index'Img);
+ end if;
+
+ Put_Line (File, ");");
end Put;
procedure Put (File : File_Descriptor; S : String) is
@@ -786,7 +797,7 @@ package body Prj.Env is
Last : Natural;
begin
- -- Add an ASCII.LF to the string. As this gnat.adc is supposed to
+ -- Add an ASCII.LF to the string. As this config file is supposed to
-- be used only by the compiler, we don't care about the characters
-- for the end of line. In fact we could have put a space, but
-- it is more convenient to be able to read gnat.adc during
@@ -829,13 +840,15 @@ package body Prj.Env is
if Unit.File_Names (Specification).Needs_Pragma then
Put (Unit.Name,
Unit.File_Names (Specification).Name,
- Specification);
+ Specification,
+ Unit.File_Names (Specification).Index);
end if;
if Unit.File_Names (Body_Part).Needs_Pragma then
Put (Unit.Name,
Unit.File_Names (Body_Part).Name,
- Body_Part);
+ Body_Part,
+ Unit.File_Names (Body_Part).Index);
end if;
Current_Unit := Current_Unit + 1;
@@ -1267,7 +1280,6 @@ package body Prj.Env is
Write_Line (" OK");
end if;
-
if Full_Path then
return Get_Name_String
(Unit.File_Names (Specification).Path);
diff --git a/gcc/ada/prj-env.ads b/gcc/ada/prj-env.ads
index e5e6bf9be39..32dd37674a8 100644
--- a/gcc/ada/prj-env.ads
+++ b/gcc/ada/prj-env.ads
@@ -24,16 +24,16 @@
-- --
------------------------------------------------------------------------------
--- This package implements services for Project-aware tools, related
--- to the environment (gnat.adc, ADA_INCLUDE_PATH, ADA_OBJECTS_PATH)
+-- This package implements services for Project-aware tools, mostly related
+-- to the environment (configuration pragma files, path files, mapping files).
with GNAT.OS_Lib; use GNAT.OS_Lib;
package Prj.Env is
procedure Initialize;
- -- Put Standard_Naming_Data into Namings table (called by Prj.Initialize)
- -- Above comment is obsolete (see body) ???
+ -- Called by Prj.Initialize to perform required initialization
+ -- steps for this package.
procedure Print_Sources;
-- Output the list of sources, after Project files have been scanned
diff --git a/gcc/ada/prj-makr.adb b/gcc/ada/prj-makr.adb
index 6fdb3bba0e3..b6b66dd5195 100644
--- a/gcc/ada/prj-makr.adb
+++ b/gcc/ada/prj-makr.adb
@@ -136,9 +136,10 @@ package body Prj.Makr is
Args : Argument_List (1 .. Preproc_Switches'Length + 6);
type SFN_Pragma is record
- Unit : Name_Id;
- File : Name_Id;
- Spec : Boolean;
+ Unit : Name_Id;
+ File : Name_Id;
+ Index : Int := 0;
+ Spec : Boolean;
end record;
package SFN_Pragmas is new Table.Table
@@ -254,7 +255,7 @@ package body Prj.Makr is
then
Output.Write_Str (" Checking """);
Output.Write_Str (Str (1 .. Last));
- Output.Write_Str (""": ");
+ Output.Write_Line (""": ");
end if;
-- If the file name matches one of the regular expressions,
@@ -362,7 +363,7 @@ package body Prj.Makr is
if End_Of_File (File) then
if Opt.Verbose_Mode then
if not Success then
- Output.Write_Str ("(process died) ");
+ Output.Write_Str (" (process died) ");
end if;
end if;
@@ -383,10 +384,11 @@ package body Prj.Makr is
Name_Buffer (1 .. Name_Len) :=
Text_Line (6 .. J - 7);
SFN_Prag :=
- (Unit => Name_Find,
- File => File_Name_Id,
- Spec => Text_Line (J - 5 .. J) =
- "(spec)");
+ (Unit => Name_Find,
+ File => File_Name_Id,
+ Index => 0,
+ Spec => Text_Line (J - 5 .. J) =
+ "(spec)");
SFN_Pragmas.Increment_Last;
SFN_Pragmas.Table
@@ -400,107 +402,116 @@ package body Prj.Makr is
if Save_Last_Pragma_Index = SFN_Pragmas.Last then
if Opt.Verbose_Mode then
- Output.Write_Line ("not a unit");
- end if;
-
- elsif SFN_Pragmas.Last >
- Save_Last_Pragma_Index + 1
- then
- SFN_Pragmas.Set_Last (Save_Last_Pragma_Index);
-
- if Opt.Verbose_Mode then
- Output.Write_Line
- ("file contains multiple units");
+ Output.Write_Line (" not a unit");
end if;
else
- SFN_Prag := SFN_Pragmas.Table
- (SFN_Pragmas.Last);
-
- if Opt.Verbose_Mode then
- if SFN_Prag.Spec then
- Output.Write_Str ("spec of ");
-
- else
- Output.Write_Str ("body of ");
- end if;
-
- Output.Write_Line
- (Get_Name_String (SFN_Prag.Unit));
+ if SFN_Pragmas.Last >
+ Save_Last_Pragma_Index + 1
+ then
+ for Index in Save_Last_Pragma_Index + 1 ..
+ SFN_Pragmas.Last
+ loop
+ SFN_Pragmas.Table (Index).Index :=
+ Int (Index - Save_Last_Pragma_Index);
+ end loop;
end if;
- if Project_File then
-
- -- Add the corresponding attribute in the
- -- Naming package of the naming project.
-
- declare
- Decl_Item : constant Project_Node_Id :=
- Default_Project_Node
- (Of_Kind =>
- N_Declarative_Item);
-
- Attribute : constant Project_Node_Id :=
- Default_Project_Node
- (Of_Kind =>
- N_Attribute_Declaration);
-
- Expression : constant Project_Node_Id :=
- Default_Project_Node
- (Of_Kind => N_Expression,
- And_Expr_Kind => Single);
-
- Term : constant Project_Node_Id :=
- Default_Project_Node
- (Of_Kind => N_Term,
- And_Expr_Kind => Single);
-
- Value : constant Project_Node_Id :=
- Default_Project_Node
- (Of_Kind => N_Literal_String,
- And_Expr_Kind => Single);
-
- begin
- Set_Next_Declarative_Item
- (Decl_Item,
- To => First_Declarative_Item_Of
- (Naming_Package));
- Set_First_Declarative_Item_Of
- (Naming_Package, To => Decl_Item);
- Set_Current_Item_Node
- (Decl_Item, To => Attribute);
-
- -- Is it a spec or a body?
+ for Index in Save_Last_Pragma_Index + 1 ..
+ SFN_Pragmas.Last
+ loop
+ SFN_Prag := SFN_Pragmas.Table (Index);
+ if Opt.Verbose_Mode then
if SFN_Prag.Spec then
- Set_Name_Of
- (Attribute, To => Name_Spec);
+ Output.Write_Str (" spec of ");
+
else
- Set_Name_Of
- (Attribute,
- To => Name_Body);
+ Output.Write_Str (" body of ");
end if;
- -- Get the name of the unit
+ Output.Write_Line
+ (Get_Name_String (SFN_Prag.Unit));
+ end if;
+
+ if Project_File then
+
+ -- Add the corresponding attribute in the
+ -- Naming package of the naming project.
+
+ declare
+ Decl_Item : constant Project_Node_Id :=
+ Default_Project_Node
+ (Of_Kind =>
+ N_Declarative_Item);
+
+ Attribute : constant Project_Node_Id :=
+ Default_Project_Node
+ (Of_Kind =>
+ N_Attribute_Declaration);
+
+ Expression : constant Project_Node_Id :=
+ Default_Project_Node
+ (Of_Kind => N_Expression,
+ And_Expr_Kind => Single);
+
+ Term : constant Project_Node_Id :=
+ Default_Project_Node
+ (Of_Kind => N_Term,
+ And_Expr_Kind => Single);
+
+ Value : constant Project_Node_Id :=
+ Default_Project_Node
+ (Of_Kind => N_Literal_String,
+ And_Expr_Kind => Single);
+
+ begin
+ Set_Next_Declarative_Item
+ (Decl_Item,
+ To => First_Declarative_Item_Of
+ (Naming_Package));
+ Set_First_Declarative_Item_Of
+ (Naming_Package, To => Decl_Item);
+ Set_Current_Item_Node
+ (Decl_Item, To => Attribute);
+
+ -- Is it a spec or a body?
+
+ if SFN_Prag.Spec then
+ Set_Name_Of
+ (Attribute, To => Name_Spec);
+ else
+ Set_Name_Of
+ (Attribute,
+ To => Name_Body);
+ end if;
- Get_Name_String (SFN_Prag.Unit);
- To_Lower (Name_Buffer (1 .. Name_Len));
- Set_Associative_Array_Index_Of
- (Attribute, To => Name_Find);
+ -- Get the name of the unit
- Set_Expression_Of
- (Attribute, To => Expression);
- Set_First_Term
- (Expression, To => Term);
- Set_Current_Term (Term, To => Value);
+ Get_Name_String (SFN_Prag.Unit);
+ To_Lower (Name_Buffer (1 .. Name_Len));
+ Set_Associative_Array_Index_Of
+ (Attribute, To => Name_Find);
- -- And set the name of the file
+ Set_Expression_Of
+ (Attribute, To => Expression);
+ Set_First_Term
+ (Expression, To => Term);
+ Set_Current_Term (Term, To => Value);
- Set_String_Value_Of
- (Value, To => File_Name_Id);
- end;
+ -- And set the name of the file
- -- Add source file name to source list file
+ Set_String_Value_Of
+ (Value, To => File_Name_Id);
+ Set_Source_Index_Of
+ (Value, To => SFN_Prag.Index);
+ end;
+ end if;
+ end loop;
+
+ if Project_File then
+ -- Add source file name to source list
+ -- file.
Last := Last + 1;
Str (Last) := ASCII.LF;
@@ -1273,7 +1284,15 @@ package body Prj.Makr is
Write_A_String
(Get_Name_String (SFN_Pragmas.Table (Index).File));
- Write_A_String (""");");
+
+ Write_A_String ("""");
+
+ if SFN_Pragmas.Table (Index).Index /= 0 then
+ Write_A_String (", Index =>");
+ Write_A_String (SFN_Pragmas.Table (Index).Index'Img);
+ end if;
+
+ Write_A_String (");");
Write_Eol;
end loop;
diff --git a/gcc/ada/prj-nmsc.adb b/gcc/ada/prj-nmsc.adb
index 5b09f849127..f728d975d34 100644
--- a/gcc/ada/prj-nmsc.adb
+++ b/gcc/ada/prj-nmsc.adb
@@ -38,6 +38,7 @@ with Prj.Err;
with Prj.Util; use Prj.Util;
with Sinput.P;
with Snames; use Snames;
+with Table; use Table;
with Types; use Types;
with Ada.Characters.Handling; use Ada.Characters.Handling;
@@ -52,9 +53,14 @@ with GNAT.HTable;
package body Prj.Nmsc is
- Error_Report : Put_Line_Access := null;
+ Error_Report : Put_Line_Access := null;
+ -- Set to point to error reporting procedure
- ALI_Suffix : constant String := ".ali";
+ ALI_Suffix : constant String := ".ali";
+ -- File suffix for ali files
+
+ Object_Suffix : constant String := Get_Object_Suffix.all;
+ -- File suffix for object files
type Name_Location is record
Name : Name_Id;
@@ -92,6 +98,54 @@ package body Prj.Nmsc is
-- several times, and to avoid cycles that may be introduced by symbolic
-- links.
+ type Ada_Naming_Exception_Id is new Nat;
+ No_Ada_Naming_Exception : constant Ada_Naming_Exception_Id := 0;
+
+ type Unit_Info is record
+ Kind : Spec_Or_Body;
+ Unit : Name_Id;
+ Next : Ada_Naming_Exception_Id := No_Ada_Naming_Exception;
+ end record;
+ -- No_Unit : constant Unit_Info :=
+ -- (Specification, No_Name, No_Ada_Naming_Exception);
+
+ package Ada_Naming_Exception_Table is new Table.Table
+ (Table_Component_Type => Unit_Info,
+ Table_Index_Type => Ada_Naming_Exception_Id,
+ Table_Low_Bound => 1,
+ Table_Initial => 20,
+ Table_Increment => 100,
+ Table_Name => "Prj.Nmsc.Ada_Naming_Exception_Table");
+
+ package Ada_Naming_Exceptions is new GNAT.HTable.Simple_HTable
+ (Header_Num => Header_Num,
+ Element => Ada_Naming_Exception_Id,
+ No_Element => No_Ada_Naming_Exception,
+ Key => Name_Id,
+ Hash => Hash,
+ Equal => "=");
+ -- A hash table to store naming exceptions for Ada. For each file name
+ -- there is one or several unit in table Ada_Naming_Exception_Table.
+
+ function Hash (Unit : Unit_Info) return Header_Num;
+
+ type Name_And_Index is record
+ Name : Name_Id := No_Name;
+ Index : Int := 0;
+ end record;
+ No_Name_And_Index : constant Name_And_Index :=
+ (Name => No_Name, Index => 0);
+
+ package Reverse_Ada_Naming_Exceptions is new GNAT.HTable.Simple_HTable
+ (Header_Num => Header_Num,
+ Element => Name_And_Index,
+ No_Element => No_Name_And_Index,
+ Key => Unit_Info,
+ Hash => Hash,
+ Equal => "=");
+ -- A table to check if a unit with an exceptional name will hide
+ -- a source with a file name following the naming convention.
+
function ALI_File_Name (Source : String) return String;
-- Return the ALI file name corresponding to a source.
@@ -105,6 +159,34 @@ package body Prj.Nmsc is
Unit : out Name_Id);
-- Check that a name is a valid Ada unit name.
+ procedure Check_For_Source
+ (File_Name : Name_Id;
+ Path_Name : Name_Id;
+ Project : Project_Id;
+ Data : in out Project_Data;
+ Location : Source_Ptr;
+ Language : Other_Programming_Language;
+ Suffix : String;
+ Naming_Exception : Boolean);
+ -- Check if a file in a source directory is a source for a specific
+ -- language other than Ada.
+
+ procedure Check_Naming_Scheme
+ (Data : in out Project_Data;
+ Project : Project_Id);
+ -- Check the naming scheme part of Data
+
+ function Check_Project
+ (P : Project_Id;
+ Root_Project : Project_Id;
+ Extending : Boolean) return Boolean;
+ -- Returns True if P is Root_Project or, if Extending is True, a project
+ -- extended by Root_Project.
+
+ function Compute_Directory_Last (Dir : String) return Natural;
+ -- Return the index of the last significant character in Dir. This is used
+ -- to avoid duplicates '/' at the end of directory names
+
procedure Error_Msg
(Project : Project_Id;
Msg : String;
@@ -113,15 +195,40 @@ package body Prj.Nmsc is
-- Prj.Err.Error_Msg. Otherwise, disregard Flag_Location and use
-- Error_Report.
+ procedure Find_Sources
+ (Project : Project_Id;
+ Data : in out Project_Data;
+ For_Language : Programming_Language;
+ Follow_Links : Boolean := False);
+ -- Find all the sources in all of the source directories of a project for
+ -- a specified language.
+
+ procedure Free_Ada_Naming_Exceptions;
+ -- Free the internal hash tables used for checking naming exceptions
+
+ procedure Get_Mains (Project : Project_Id; Data : in out Project_Data);
+ -- Get the mains of a project from attribute Main, if it exists, and put
+ -- them in the project data.
+
+ procedure Get_Sources_From_File
+ (Path : String;
+ Location : Source_Ptr;
+ Project : Project_Id);
+ -- Get the list of sources from a text file and put them in hash table
+ -- Source_Names.
+
procedure Get_Unit
(Canonical_File_Name : Name_Id;
Naming : Naming_Data;
+ Exception_Id : out Ada_Naming_Exception_Id;
Unit_Name : out Name_Id;
Unit_Kind : out Spec_Or_Body;
Needs_Pragma : out Boolean);
-- Find out, from a file name, the unit name, the unit kind and if a
-- specific SFN pragma is needed. If the file name corresponds to no
- -- unit, then Unit_Name will be No_Name.
+ -- unit, then Unit_Name will be No_Name. If the file is a multi-unit source
+ -- or an exception to the naming scheme, then Exception_Id is set to
+ -- the unit or units that the source contains.
function Is_Illegal_Suffix
(Suffix : String;
@@ -129,21 +236,6 @@ package body Prj.Nmsc is
-- Returns True if the string Suffix cannot be used as
-- a spec suffix, a body suffix or a separate suffix.
- procedure Record_Source
- (File_Name : Name_Id;
- Path_Name : Name_Id;
- Project : Project_Id;
- Data : in out Project_Data;
- Location : Source_Ptr;
- Current_Source : in out String_List_Id;
- Source_Recorded : in out Boolean;
- Trusted_Mode : Boolean);
- -- Put a unit in the list of units of a project, if the file name
- -- corresponds to a valid unit name.
-
- procedure Show_Source_Dirs (Project : Project_Id);
- -- List all the source directories of a project.
-
procedure Locate_Directory
(Name : Name_Id;
Parent : Name_Id;
@@ -158,429 +250,46 @@ package body Prj.Nmsc is
-- Returns the path name of a (non project) file.
-- Returns an empty string if file cannot be found.
+ procedure Prepare_Ada_Naming_Exceptions
+ (List : Array_Element_Id;
+ Kind : Spec_Or_Body);
+ -- Prepare the internal hash tables used for checking naming exceptions
+ -- for Ada. Insert all elements of List in the tables.
+
function Project_Extends
(Extending : Project_Id;
Extended : Project_Id) return Boolean;
-- Returns True if Extending is extending directly or indirectly Extended.
- procedure Check_Naming_Scheme
- (Data : in out Project_Data;
- Project : Project_Id);
- -- Check the naming scheme part of Data
-
- type Unit_Info is record
- Kind : Spec_Or_Body;
- Unit : Name_Id;
- end record;
- No_Unit : constant Unit_Info := (Specification, No_Name);
-
- package Naming_Exceptions is new GNAT.HTable.Simple_HTable
- (Header_Num => Header_Num,
- Element => Unit_Info,
- No_Element => No_Unit,
- Key => Name_Id,
- Hash => Hash,
- Equal => "=");
-
- function Hash (Unit : Unit_Info) return Header_Num;
-
- package Reverse_Naming_Exceptions is new GNAT.HTable.Simple_HTable
- (Header_Num => Header_Num,
- Element => Name_Id,
- No_Element => No_Name,
- Key => Unit_Info,
- Hash => Hash,
- Equal => "=");
- -- A table to check if a unit with an exceptional name will hide
- -- a source with a file name following the naming convention.
-
- procedure Prepare_Naming_Exceptions
- (List : Array_Element_Id;
- Kind : Spec_Or_Body);
- -- Prepare the internal hash tables used for checking naming exceptions.
- -- Insert all elements of List in the tables.
-
- procedure Free_Naming_Exceptions;
- -- Free the internal hash tables used for checking naming exceptions
-
- function Compute_Directory_Last (Dir : String) return Natural;
- -- Return the index of the last significant character in Dir. This is used
- -- to avoid duplicates '/' at the end of directory names
-
- ----------------------------
- -- Compute_Directory_Last --
- ----------------------------
-
- function Compute_Directory_Last (Dir : String) return Natural is
- begin
- if Dir'Length > 1
- and then (Dir (Dir'Last - 1) = Directory_Separator
- or else Dir (Dir'Last - 1) = '/')
- then
- return Dir'Last - 1;
- else
- return Dir'Last;
- end if;
- end Compute_Directory_Last;
-
- -------------------------------
- -- Prepare_Naming_Exceptions --
- -------------------------------
-
- procedure Prepare_Naming_Exceptions
- (List : Array_Element_Id;
- Kind : Spec_Or_Body)
- is
- Current : Array_Element_Id := List;
- Element : Array_Element;
-
- begin
- while Current /= No_Array_Element loop
- Element := Array_Elements.Table (Current);
-
- if Element.Index /= No_Name then
- Naming_Exceptions.Set
- (Element.Value.Value,
- (Kind => Kind, Unit => Element.Index));
- Reverse_Naming_Exceptions.Set
- ((Kind => Kind, Unit => Element.Index),
- Element.Value.Value);
- end if;
-
- Current := Element.Next;
- end loop;
- end Prepare_Naming_Exceptions;
-
- ----------
- -- Hash --
- ----------
-
- function Hash (Unit : Unit_Info) return Header_Num is
- begin
- return Header_Num (Unit.Unit mod 2048);
- end Hash;
-
- ----------------------------
- -- Free_Naming_Exceptions --
- ----------------------------
-
- procedure Free_Naming_Exceptions is
- begin
- Naming_Exceptions.Reset;
- Reverse_Naming_Exceptions.Reset;
- end Free_Naming_Exceptions;
-
- -------------------------
- -- Check_Naming_Scheme --
- -------------------------
-
- procedure Check_Naming_Scheme
- (Data : in out Project_Data;
- Project : Project_Id)
- is
- Naming_Id : constant Package_Id :=
- Util.Value_Of (Name_Naming, Data.Decl.Packages);
-
- Naming : Package_Element;
-
- procedure Check_Unit_Names (List : Array_Element_Id);
- -- Check that a list of unit names contains only valid names.
-
- ----------------------
- -- Check_Unit_Names --
- ----------------------
-
- procedure Check_Unit_Names (List : Array_Element_Id) is
- Current : Array_Element_Id := List;
- Element : Array_Element;
- Unit_Name : Name_Id;
-
- begin
- -- Loop through elements of the string list
-
- while Current /= No_Array_Element loop
- Element := Array_Elements.Table (Current);
-
- -- Put file name in canonical case
-
- Get_Name_String (Element.Value.Value);
- Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
- Element.Value.Value := Name_Find;
-
- -- Check that it contains a valid unit name
-
- Get_Name_String (Element.Index);
- Check_Ada_Name (Name_Buffer (1 .. Name_Len), Unit_Name);
-
- if Unit_Name = No_Name then
- Err_Vars.Error_Msg_Name_1 := Element.Index;
- Error_Msg
- (Project,
- "{ is not a valid unit name.",
- Element.Value.Location);
-
- else
- if Current_Verbosity = High then
- Write_Str (" Unit (""");
- Write_Str (Get_Name_String (Unit_Name));
- Write_Line (""")");
- end if;
-
- Element.Index := Unit_Name;
- Array_Elements.Table (Current) := Element;
- end if;
-
- Current := Element.Next;
- end loop;
- end Check_Unit_Names;
-
- -- Start of processing for Check_Naming_Scheme
-
- begin
- -- If there is a package Naming, we will put in Data.Naming what is in
- -- this package Naming.
-
- if Naming_Id /= No_Package then
- Naming := Packages.Table (Naming_Id);
-
- if Current_Verbosity = High then
- Write_Line ("Checking ""Naming"" for Ada.");
- end if;
-
- declare
- Bodies : constant Array_Element_Id :=
- Util.Value_Of (Name_Body, Naming.Decl.Arrays);
-
- Specs : constant Array_Element_Id :=
- Util.Value_Of (Name_Spec, Naming.Decl.Arrays);
-
- begin
- if Bodies /= No_Array_Element then
-
- -- We have elements in the array Body_Part
-
- if Current_Verbosity = High then
- Write_Line ("Found Bodies.");
- end if;
-
- Data.Naming.Bodies := Bodies;
- Check_Unit_Names (Bodies);
-
- else
- if Current_Verbosity = High then
- Write_Line ("No Bodies.");
- end if;
- end if;
-
- if Specs /= No_Array_Element then
-
- -- We have elements in the array Specs
-
- if Current_Verbosity = High then
- Write_Line ("Found Specs.");
- end if;
-
- Data.Naming.Specs := Specs;
- Check_Unit_Names (Specs);
-
- else
- if Current_Verbosity = High then
- Write_Line ("No Specs.");
- end if;
- end if;
- end;
-
- -- We are now checking if variables Dot_Replacement, Casing,
- -- Spec_Suffix, Body_Suffix and/or Separate_Suffix
- -- exist.
-
- -- For each variable, if it does not exist, we do nothing,
- -- because we already have the default.
-
- -- Check Dot_Replacement
-
- declare
- Dot_Replacement : constant Variable_Value :=
- Util.Value_Of
- (Name_Dot_Replacement,
- Naming.Decl.Attributes);
-
- begin
- pragma Assert (Dot_Replacement.Kind = Single,
- "Dot_Replacement is not a single string");
-
- if not Dot_Replacement.Default then
- Get_Name_String (Dot_Replacement.Value);
-
- if Name_Len = 0 then
- Error_Msg
- (Project,
- "Dot_Replacement cannot be empty",
- Dot_Replacement.Location);
-
- else
- Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
- Data.Naming.Dot_Replacement := Name_Find;
- Data.Naming.Dot_Repl_Loc := Dot_Replacement.Location;
- end if;
- end if;
- end;
-
- if Current_Verbosity = High then
- Write_Str (" Dot_Replacement = """);
- Write_Str (Get_Name_String (Data.Naming.Dot_Replacement));
- Write_Char ('"');
- Write_Eol;
- end if;
-
- -- Check Casing
-
- declare
- Casing_String : constant Variable_Value :=
- Util.Value_Of
- (Name_Casing, Naming.Decl.Attributes);
-
- begin
- pragma Assert (Casing_String.Kind = Single,
- "Casing is not a single string");
-
- if not Casing_String.Default then
- declare
- Casing_Image : constant String :=
- Get_Name_String (Casing_String.Value);
- begin
- declare
- Casing : constant Casing_Type := Value (Casing_Image);
- begin
- Data.Naming.Casing := Casing;
- end;
-
- exception
- when Constraint_Error =>
- if Casing_Image'Length = 0 then
- Error_Msg
- (Project,
- "Casing cannot be an empty string",
- Casing_String.Location);
-
- else
- Name_Len := Casing_Image'Length;
- Name_Buffer (1 .. Name_Len) := Casing_Image;
- Err_Vars.Error_Msg_Name_1 := Name_Find;
- Error_Msg
- (Project,
- "{ is not a correct Casing",
- Casing_String.Location);
- end if;
- end;
- end if;
- end;
-
- if Current_Verbosity = High then
- Write_Str (" Casing = ");
- Write_Str (Image (Data.Naming.Casing));
- Write_Char ('.');
- Write_Eol;
- end if;
-
- -- Check Spec_Suffix
-
- declare
- Ada_Spec_Suffix : constant Variable_Value :=
- Prj.Util.Value_Of
- (Index => Name_Ada,
- In_Array => Data.Naming.Spec_Suffix);
-
- begin
- if Ada_Spec_Suffix.Kind = Single
- and then Get_Name_String (Ada_Spec_Suffix.Value) /= ""
- then
- Data.Naming.Current_Spec_Suffix := Ada_Spec_Suffix.Value;
- Data.Naming.Spec_Suffix_Loc := Ada_Spec_Suffix.Location;
-
- else
- Data.Naming.Current_Spec_Suffix := Default_Ada_Spec_Suffix;
- end if;
- end;
-
- if Current_Verbosity = High then
- Write_Str (" Spec_Suffix = """);
- Write_Str (Get_Name_String (Data.Naming.Current_Spec_Suffix));
- Write_Char ('"');
- Write_Eol;
- end if;
-
- -- Check Body_Suffix
-
- declare
- Ada_Body_Suffix : constant Variable_Value :=
- Prj.Util.Value_Of
- (Index => Name_Ada,
- In_Array => Data.Naming.Body_Suffix);
-
- begin
- if Ada_Body_Suffix.Kind = Single
- and then Get_Name_String (Ada_Body_Suffix.Value) /= ""
- then
- Data.Naming.Current_Body_Suffix := Ada_Body_Suffix.Value;
- Data.Naming.Body_Suffix_Loc := Ada_Body_Suffix.Location;
-
- else
- Data.Naming.Current_Body_Suffix := Default_Ada_Body_Suffix;
- end if;
- end;
-
- if Current_Verbosity = High then
- Write_Str (" Body_Suffix = """);
- Write_Str (Get_Name_String (Data.Naming.Current_Body_Suffix));
- Write_Char ('"');
- Write_Eol;
- end if;
-
- -- Check Separate_Suffix
-
- declare
- Ada_Sep_Suffix : constant Variable_Value :=
- Prj.Util.Value_Of
- (Variable_Name => Name_Separate_Suffix,
- In_Variables => Naming.Decl.Attributes);
-
- begin
- if Ada_Sep_Suffix.Default then
- Data.Naming.Separate_Suffix :=
- Data.Naming.Current_Body_Suffix;
-
- else
- if Get_Name_String (Ada_Sep_Suffix.Value) = "" then
- Error_Msg
- (Project,
- "Separate_Suffix cannot be empty",
- Ada_Sep_Suffix.Location);
-
- else
- Data.Naming.Separate_Suffix := Ada_Sep_Suffix.Value;
- Data.Naming.Sep_Suffix_Loc := Ada_Sep_Suffix.Location;
- end if;
- end if;
- end;
-
- if Current_Verbosity = High then
- Write_Str (" Separate_Suffix = """);
- Write_Str (Get_Name_String (Data.Naming.Separate_Suffix));
- Write_Char ('"');
- Write_Eol;
- end if;
+ procedure Record_Ada_Source
+ (File_Name : Name_Id;
+ Path_Name : Name_Id;
+ Project : Project_Id;
+ Data : in out Project_Data;
+ Location : Source_Ptr;
+ Current_Source : in out String_List_Id;
+ Source_Recorded : in out Boolean;
+ Follow_Links : Boolean);
+ -- Put a unit in the list of units of a project, if the file name
+ -- corresponds to a valid unit name.
- -- Check if Data.Naming is valid
+ procedure Record_Other_Sources
+ (Project : Project_Id;
+ Data : in out Project_Data;
+ Language : Programming_Language;
+ Naming_Exceptions : Boolean);
+ -- Record the sources of a language in a project.
+ -- When Naming_Exceptions is True, mark the found sources as such, to
+ -- later remove those that are not named in a list of sources.
- Check_Ada_Naming_Scheme (Project, Data.Naming);
+ procedure Show_Source_Dirs (Project : Project_Id);
+ -- List all the source directories of a project.
- else
- Data.Naming.Current_Spec_Suffix := Default_Ada_Spec_Suffix;
- Data.Naming.Current_Body_Suffix := Default_Ada_Body_Suffix;
- Data.Naming.Separate_Suffix := Default_Ada_Body_Suffix;
- end if;
- end Check_Naming_Scheme;
+ function Suffix_For
+ (Language : Programming_Language;
+ Naming : Naming_Data) return Name_Id;
+ -- Get the suffix for the source of a language from a package naming.
+ -- If not specified, return the default for the language.
---------------
-- Ada_Check --
@@ -589,20 +298,13 @@ package body Prj.Nmsc is
procedure Ada_Check
(Project : Project_Id;
Report_Error : Put_Line_Access;
- Trusted_Mode : Boolean)
+ Follow_Links : Boolean)
is
Data : Project_Data;
Languages : Variable_Value := Nil_Variable_Value;
Extending : Boolean := False;
- function Check_Project (P : Project_Id) return Boolean;
- -- Returns True if P is Project or a project extended by Project
-
- procedure Find_Sources;
- -- Find all the sources in all of the source directories
- -- of a project.
-
procedure Get_Path_Names_And_Record_Sources;
-- Find the path names of the source files in the Source_Names table
-- in the source directories and record those that are Ada sources.
@@ -618,157 +320,6 @@ package body Prj.Nmsc is
-- Check that individual naming conventions apply to immediate
-- sources of the project; if not, issue a warning.
- -------------------
- -- Check_Project --
- -------------------
-
- function Check_Project (P : Project_Id) return Boolean is
- begin
- if P = Project then
- return True;
- elsif Extending then
- declare
- Data : Project_Data := Projects.Table (Project);
-
- begin
- while Data.Extends /= No_Project loop
- if P = Data.Extends then
- return True;
- end if;
-
- Data := Projects.Table (Data.Extends);
- end loop;
- end;
- end if;
-
- return False;
- end Check_Project;
-
- ------------------
- -- Find_Sources --
- ------------------
-
- procedure Find_Sources is
- Source_Dir : String_List_Id := Data.Source_Dirs;
- Element : String_Element;
- Dir : Dir_Type;
- Current_Source : String_List_Id := Nil_String;
- Source_Recorded : Boolean := False;
-
- begin
- if Current_Verbosity = High then
- Write_Line ("Looking for sources:");
- end if;
-
- -- For each subdirectory
-
- while Source_Dir /= Nil_String loop
- begin
- Source_Recorded := False;
- Element := String_Elements.Table (Source_Dir);
- if Element.Value /= No_Name then
- Get_Name_String (Element.Display_Value);
- declare
- Source_Directory : constant String :=
- Name_Buffer (1 .. Name_Len) & Directory_Separator;
- Dir_Last : constant Natural :=
- Compute_Directory_Last (Source_Directory);
-
- begin
- if Current_Verbosity = High then
- Write_Str ("Source_Dir = ");
- Write_Line (Source_Directory);
- end if;
-
- -- We look to every entry in the source directory
-
- Open (Dir, Source_Directory
- (Source_Directory'First .. Dir_Last));
-
- -- Canonical_Case_File_Name (Source_Directory);
-
- loop
- Read (Dir, Name_Buffer, Name_Len);
-
- if Current_Verbosity = High then
- Write_Str (" Checking ");
- Write_Line (Name_Buffer (1 .. Name_Len));
- end if;
-
- exit when Name_Len = 0;
-
- declare
- File_Name : constant Name_Id := Name_Find;
- Path : constant String :=
- Normalize_Pathname
- (Name => Name_Buffer (1 .. Name_Len),
- Directory => Source_Directory
- (Source_Directory'First .. Dir_Last),
- Resolve_Links => False,
- Case_Sensitive => True);
- Path_Name : Name_Id;
-
- begin
- if Trusted_Mode or else Is_Regular_File (Path) then
- Name_Len := Path'Length;
- Name_Buffer (1 .. Name_Len) := Path;
- Path_Name := Name_Find;
-
- -- We attempt to register it as a source.
- -- However, there is no error if the file
- -- does not contain a valid source.
- -- But there is an error if we have a
- -- duplicate unit name.
-
- Record_Source
- (File_Name => File_Name,
- Path_Name => Path_Name,
- Project => Project,
- Data => Data,
- Location => No_Location,
- Current_Source => Current_Source,
- Source_Recorded => Source_Recorded,
- Trusted_Mode => Trusted_Mode);
- end if;
- end;
- end loop;
-
- Close (Dir);
- end;
- end if;
-
- exception
- when Directory_Error =>
- null;
- end;
-
- if Source_Recorded then
- String_Elements.Table (Source_Dir).Flag := True;
- end if;
-
- Source_Dir := Element.Next;
- end loop;
-
- if Current_Verbosity = High then
- Write_Line ("end Looking for sources.");
- end if;
-
- -- If we have looked for sources and found none, then
- -- it is an error, except if it is an extending project.
- -- If a non extending project is not supposed to contain
- -- any source, then we never call Find_Sources.
-
- if Current_Source /= Nil_String then
- Data.Sources_Present := True;
-
- elsif Data.Extends = No_Project then
- Error_Msg
- (Project,
- "there are no Ada sources in this project",
- Data.Location);
- end if;
- end Find_Sources;
-
---------------------------------------
-- Get_Path_Names_And_Record_Sources --
---------------------------------------
@@ -792,7 +343,8 @@ package body Prj.Nmsc is
Source_Recorded : Boolean := False;
begin
- -- We look in all source directories for this file name
+ -- We look in all source directories for the file names in the
+ -- hash table Source_Names
while Source_Dir /= Nil_String loop
Source_Recorded := False;
@@ -835,9 +387,9 @@ package body Prj.Nmsc is
Write_Line (Get_Name_String (Name));
end if;
- -- Register the source if it is an Ada compilation unit..
+ -- Register the source if it is an Ada compilation unit.
- Record_Source
+ Record_Ada_Source
(File_Name => Name,
Path_Name => Path,
Project => Project,
@@ -845,7 +397,7 @@ package body Prj.Nmsc is
Location => NL.Location,
Current_Source => Current_Source,
Source_Recorded => Source_Recorded,
- Trusted_Mode => Trusted_Mode);
+ Follow_Links => Follow_Links);
end if;
end loop;
@@ -895,54 +447,13 @@ package body Prj.Nmsc is
(Path : String;
Location : Source_Ptr)
is
- File : Prj.Util.Text_File;
- Line : String (1 .. 250);
- Last : Natural;
- Source_Name : Name_Id;
-
begin
- if Current_Verbosity = High then
- Write_Str ("Opening """);
- Write_Str (Path);
- Write_Line (""".");
- end if;
-
- -- We open the file
-
- Prj.Util.Open (File, Path);
-
- if not Prj.Util.Is_Valid (File) then
- Error_Msg (Project, "file does not exist", Location);
- else
- Source_Names.Reset;
+ -- Get the list of sources from the file and put them in hash table
+ -- Source_Names.
- while not Prj.Util.End_Of_File (File) loop
- Prj.Util.Get_Line (File, Line, Last);
+ Get_Sources_From_File (Path, Location, Project);
- -- If the line is not empty and does not start with "--",
- -- then it should contain a file name. However, if the
- -- file name does not exist, it may be for another language
- -- and we don't fail.
-
- if Last /= 0
- and then (Last = 1 or else Line (1 .. 2) /= "--")
- then
- Name_Len := Last;
- Name_Buffer (1 .. Name_Len) := Line (1 .. Last);
- Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
- Source_Name := Name_Find;
- Source_Names.Set
- (K => Source_Name,
- E =>
- (Name => Source_Name,
- Location => Location,
- Found => False));
- end if;
- end loop;
-
- Prj.Util.Close (File);
-
- end if;
+ -- Look in the source directories to find those sources
Get_Path_Names_And_Record_Sources;
@@ -991,7 +502,8 @@ package body Prj.Nmsc is
if Specs then
if not Check_Project
- (The_Unit_Data.File_Names (Specification).Project)
+ (The_Unit_Data.File_Names (Specification).Project,
+ Project, Extending)
then
Error_Msg
(Project,
@@ -1001,7 +513,8 @@ package body Prj.Nmsc is
else
if not Check_Project
- (The_Unit_Data.File_Names (Com.Body_Part).Project)
+ (The_Unit_Data.File_Names (Com.Body_Part).Project,
+ Project, Extending)
then
Error_Msg
(Project,
@@ -1060,8 +573,8 @@ package body Prj.Nmsc is
Check_Naming_Scheme (Data, Project);
- Prepare_Naming_Exceptions (Data.Naming.Bodies, Body_Part);
- Prepare_Naming_Exceptions (Data.Naming.Specs, Specification);
+ Prepare_Ada_Naming_Exceptions (Data.Naming.Bodies, Body_Part);
+ Prepare_Ada_Naming_Exceptions (Data.Naming.Specs, Specification);
-- If we have source directories, then find the sources
@@ -1147,7 +660,8 @@ package body Prj.Nmsc is
Get_Path_Names_And_Record_Sources;
end;
- -- No source_files specified.
+ -- No source_files specified
+
-- We check Source_List_File has been specified.
elsif not Source_List_File.Default then
@@ -1178,17 +692,17 @@ package body Prj.Nmsc is
else
-- Neither Source_Files nor Source_List_File has been
- -- specified.
- -- Find all the files that satisfy
- -- the naming scheme in all the source directories.
+ -- specified. Find all the files that satisfy the naming
+ -- scheme in all the source directories.
- Find_Sources;
+ Find_Sources (Project, Data, Lang_Ada, Follow_Links);
end if;
-- If there are sources that are locally removed, mark them as
-- such in the Units table.
if not Locally_Removed.Default then
+
-- Sources can be locally removed only in extending
-- project files.
@@ -1406,6 +920,7 @@ package body Prj.Nmsc is
String_Elements.Increment_Last;
String_Elements.Table (String_Elements.Last) :=
(Value => ALI_Name_Id,
+ Index => 0,
Display_Value => ALI_Name_Id,
Location => String_Elements.Table
(Interfaces).Location,
@@ -1463,7 +978,8 @@ package body Prj.Nmsc is
(Com.Body_Part).Path /= Slash
then
if Check_Project
- (The_Unit_Data.File_Names (Body_Part).Project)
+ (The_Unit_Data.File_Names (Body_Part).Project,
+ Project, Extending)
then
-- There is a body for this unit.
-- If there is no spec, we need to check
@@ -1515,7 +1031,8 @@ package body Prj.Nmsc is
(Com.Specification).Path /= Slash
and then Check_Project
(The_Unit_Data.File_Names
- (Specification).Project)
+ (Specification).Project,
+ Project, Extending)
then
-- The unit is part of the project, it has
@@ -1546,6 +1063,7 @@ package body Prj.Nmsc is
-- Lib_Auto_Init accordingly.
if Lib_Auto_Init.Default then
+
-- If no attribute Library_Auto_Init is declared, then
-- set auto init only if it is supported.
@@ -1837,34 +1355,11 @@ package body Prj.Nmsc is
-- Put the list of Mains, if any, in the project data
- declare
- Mains : constant Variable_Value :=
- Prj.Util.Value_Of (Name_Main, Data.Decl.Attributes);
-
- begin
- Data.Mains := Mains.Values;
-
- -- If no Mains were specified, and if we are an extending
- -- project, inherit the Mains from the project we are extending.
-
- if Mains.Default then
- if Data.Extends /= No_Project then
- Data.Mains := Projects.Table (Data.Extends).Mains;
- end if;
-
- -- In a library project file, Main cannot be specified
-
- elsif Data.Library then
- Error_Msg
- (Project,
- "a library project file cannot have Main specified",
- Mains.Location);
- end if;
- end;
+ Get_Mains (Project, Data);
Projects.Table (Project) := Data;
- Free_Naming_Exceptions;
+ Free_Ada_Naming_Exceptions;
end Ada_Check;
-------------------
@@ -2008,6 +1503,265 @@ package body Prj.Nmsc is
end if;
end Check_Ada_Name;
+ ----------------------
+ -- Check_For_Source --
+ ----------------------
+
+ procedure Check_For_Source
+ (File_Name : Name_Id;
+ Path_Name : Name_Id;
+ Project : Project_Id;
+ Data : in out Project_Data;
+ Location : Source_Ptr;
+ Language : Other_Programming_Language;
+ Suffix : String;
+ Naming_Exception : Boolean)
+ is
+ Name : String := Get_Name_String (File_Name);
+ Real_Location : Source_Ptr := Location;
+
+ begin
+ Canonical_Case_File_Name (Name);
+
+ -- A file is a source of a language if Naming_Exception is True (case
+ -- of naming exceptions) or if its file name ends with the suffix.
+
+ if Naming_Exception or else
+ (Name'Length > Suffix'Length and then
+ Name (Name'Last - Suffix'Length + 1 .. Name'Last) = Suffix)
+ then
+ if Real_Location = No_Location then
+ Real_Location := Data.Location;
+ end if;
+
+ declare
+ Path : String := Get_Name_String (Path_Name);
+
+ Path_Id : Name_Id;
+ -- The path name id (in canonical case)
+
+ File_Id : Name_Id;
+ -- The file name id (in canonical case)
+
+ Obj_Id : Name_Id;
+ -- The object file name
+
+ Obj_Path_Id : Name_Id;
+ -- The object path name
+
+ Dep_Id : Name_Id;
+ -- The dependency file name
+
+ Dep_Path_Id : Name_Id;
+ -- The dependency path name
+
+ Dot_Pos : Natural := 0;
+ -- Position of the last dot in Name
+
+ Source : Other_Source;
+ Source_Id : Other_Source_Id := Data.First_Other_Source;
+
+ begin
+ Canonical_Case_File_Name (Path);
+
+ -- Get the file name id
+
+ Name_Len := Name'Length;
+ Name_Buffer (1 .. Name_Len) := Name;
+ File_Id := Name_Find;
+
+ -- Get the path name id
+
+ Name_Len := Path'Length;
+ Name_Buffer (1 .. Name_Len) := Path;
+ Path_Id := Name_Find;
+
+ -- Find the position of the last dot
+
+ for J in reverse Name'Range loop
+ if Name (J) = '.' then
+ Dot_Pos := J;
+ exit;
+ end if;
+ end loop;
+
+ if Dot_Pos <= Name'First then
+ Dot_Pos := Name'Last + 1;
+ end if;
+
+ -- Compute the object file name
+
+ Get_Name_String (File_Id);
+ Name_Len := Dot_Pos - Name'First;
+
+ for J in Object_Suffix'Range loop
+ Name_Len := Name_Len + 1;
+ Name_Buffer (Name_Len) := Object_Suffix (J);
+ end loop;
+
+ Obj_Id := Name_Find;
+
+ -- Compute the object path name
+
+ Get_Name_String (Data.Object_Directory);
+
+ if Name_Buffer (Name_Len) /= Directory_Separator and then
+ Name_Buffer (Name_Len) /= '/'
+ then
+ Name_Len := Name_Len + 1;
+ Name_Buffer (Name_Len) := Directory_Separator;
+ end if;
+
+ Add_Str_To_Name_Buffer (Get_Name_String (Obj_Id));
+ Obj_Path_Id := Name_Find;
+
+ -- Compute the dependency file name
+
+ Get_Name_String (File_Id);
+ Name_Len := Dot_Pos - Name'First + 1;
+ Name_Buffer (Name_Len) := '.';
+ Name_Len := Name_Len + 1;
+ Name_Buffer (Name_Len) := 'd';
+ Dep_Id := Name_Find;
+
+ -- Compute the dependency path name
+
+ Get_Name_String (Data.Object_Directory);
+
+ if Name_Buffer (Name_Len) /= Directory_Separator and then
+ Name_Buffer (Name_Len) /= '/'
+ then
+ Name_Len := Name_Len + 1;
+ Name_Buffer (Name_Len) := Directory_Separator;
+ end if;
+
+ Add_Str_To_Name_Buffer (Get_Name_String (Dep_Id));
+ Dep_Path_Id := Name_Find;
+
+ -- Check if source is already in the list of source for this
+ -- project: it may have already been specified as a naming
+ -- exception for the same language or an other language, or they
+ -- may be two identical file names in different source
+ -- directories.
+
+ while Source_Id /= No_Other_Source loop
+ Source := Other_Sources.Table (Source_Id);
+ Source_Id := Source.Next;
+
+ if Source.File_Name = File_Id then
+ -- Two sources of different languages cannot have the same
+ -- file name.
+
+ if Source.Language /= Language then
+ Error_Msg_Name_1 := File_Name;
+ Error_Msg
+ (Project,
+ "{ cannot be a source of several languages",
+ Real_Location);
+ return;
+
+ -- No problem if a file has already been specified as
+ -- a naming exception of this language.
+
+ elsif Source.Path_Name = Path_Id then
+ -- Reset the naming exception flag, if this is not a
+ -- naming exception.
+
+ if not Naming_Exception then
+ Other_Sources.Table (Source_Id).Naming_Exception :=
+ False;
+ end if;
+
+ return;
+
+ -- There are several files with the same names, but the
+ -- order of the source directories is known (no /**):
+ -- only the first one encountered is kept, the other ones
+ -- are ignored.
+
+ elsif Data.Known_Order_Of_Source_Dirs then
+ return;
+
+ -- But it is an error if the order of the source directories
+ -- is not known.
+
+ else
+ Error_Msg_Name_1 := File_Name;
+ Error_Msg
+ (Project,
+ "{ is found in several source directories",
+ Real_Location);
+ return;
+ end if;
+
+ -- Two sources with different file names cannot have the same
+ -- object file name.
+
+ elsif Source.Object_Name = Obj_Id then
+ Error_Msg_Name_1 := File_Id;
+ Error_Msg_Name_2 := Source.File_Name;
+ Error_Msg_Name_3 := Obj_Id;
+ Error_Msg
+ (Project,
+ "{ and { have the same object file {",
+ Real_Location);
+ return;
+ end if;
+ end loop;
+
+ if Current_Verbosity = High then
+ Write_Str (" found ");
+ Write_Str (Lang_Display_Names (Language).all);
+ Write_Str (" source """);
+ Write_Str (Get_Name_String (File_Name));
+ Write_Line ("""");
+ Write_Str (" object path = ");
+ Write_Line (Get_Name_String (Obj_Path_Id));
+ end if;
+
+ -- Create the Other_Source record
+ Source :=
+ (Language => Language,
+ File_Name => File_Id,
+ Path_Name => Path_Id,
+ Source_TS => File_Stamp (Path_Id),
+ Object_Name => Obj_Id,
+ Object_Path => Obj_Path_Id,
+ Object_TS => File_Stamp (Obj_Path_Id),
+ Dep_Name => Dep_Id,
+ Dep_Path => Dep_Path_Id,
+ Dep_TS => File_Stamp (Dep_Path_Id),
+ Naming_Exception => Naming_Exception,
+ Next => No_Other_Source);
+
+ -- And add it to the Other_Sources table
+
+ Other_Sources.Increment_Last;
+ Other_Sources.Table (Other_Sources.Last) := Source;
+
+ -- There are sources of languages other than Ada in this project
+ Data.Sources_Present := True;
+
+ -- And there are sources of this language in this project
+
+ Data.Languages (Language) := True;
+
+ -- Add this source to the list of sources of languages other than
+ -- Ada of the project.
+
+ if Data.First_Other_Source = No_Other_Source then
+ Data.First_Other_Source := Other_Sources.Last;
+
+ else
+ Other_Sources.Table (Data.Last_Other_Source).Next :=
+ Other_Sources.Last;
+ end if;
+
+ Data.Last_Other_Source := Other_Sources.Last;
+ end;
+ end if;
+ end Check_For_Source;
+
-----------------------------
-- Check_Ada_Naming_Scheme --
-----------------------------
@@ -2143,6 +1897,383 @@ package body Prj.Nmsc is
end if;
end Check_Ada_Naming_Scheme;
+ -------------------------
+ -- Check_Naming_Scheme --
+ -------------------------
+
+ procedure Check_Naming_Scheme
+ (Data : in out Project_Data;
+ Project : Project_Id)
+ is
+ Naming_Id : constant Package_Id :=
+ Util.Value_Of (Name_Naming, Data.Decl.Packages);
+
+ Naming : Package_Element;
+
+ procedure Check_Unit_Names (List : Array_Element_Id);
+ -- Check that a list of unit names contains only valid names.
+
+ ----------------------
+ -- Check_Unit_Names --
+ ----------------------
+
+ procedure Check_Unit_Names (List : Array_Element_Id) is
+ Current : Array_Element_Id := List;
+ Element : Array_Element;
+ Unit_Name : Name_Id;
+
+ begin
+ -- Loop through elements of the string list
+
+ while Current /= No_Array_Element loop
+ Element := Array_Elements.Table (Current);
+
+ -- Put file name in canonical case
+
+ Get_Name_String (Element.Value.Value);
+ Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
+ Element.Value.Value := Name_Find;
+
+ -- Check that it contains a valid unit name
+
+ Get_Name_String (Element.Index);
+ Check_Ada_Name (Name_Buffer (1 .. Name_Len), Unit_Name);
+
+ if Unit_Name = No_Name then
+ Err_Vars.Error_Msg_Name_1 := Element.Index;
+ Error_Msg
+ (Project,
+ "{ is not a valid unit name.",
+ Element.Value.Location);
+
+ else
+ if Current_Verbosity = High then
+ Write_Str (" Unit (""");
+ Write_Str (Get_Name_String (Unit_Name));
+ Write_Line (""")");
+ end if;
+
+ Element.Index := Unit_Name;
+ Array_Elements.Table (Current) := Element;
+ end if;
+
+ Current := Element.Next;
+ end loop;
+ end Check_Unit_Names;
+
+ -- Start of processing for Check_Naming_Scheme
+
+ begin
+ -- If there is a package Naming, we will put in Data.Naming what is in
+ -- this package Naming.
+
+ if Naming_Id /= No_Package then
+ Naming := Packages.Table (Naming_Id);
+
+ if Current_Verbosity = High then
+ Write_Line ("Checking ""Naming"" for Ada.");
+ end if;
+
+ declare
+ Bodies : constant Array_Element_Id :=
+ Util.Value_Of (Name_Body, Naming.Decl.Arrays);
+
+ Specs : constant Array_Element_Id :=
+ Util.Value_Of (Name_Spec, Naming.Decl.Arrays);
+
+ begin
+ if Bodies /= No_Array_Element then
+
+ -- We have elements in the array Body_Part
+
+ if Current_Verbosity = High then
+ Write_Line ("Found Bodies.");
+ end if;
+
+ Data.Naming.Bodies := Bodies;
+ Check_Unit_Names (Bodies);
+
+ else
+ if Current_Verbosity = High then
+ Write_Line ("No Bodies.");
+ end if;
+ end if;
+
+ if Specs /= No_Array_Element then
+
+ -- We have elements in the array Specs
+
+ if Current_Verbosity = High then
+ Write_Line ("Found Specs.");
+ end if;
+
+ Data.Naming.Specs := Specs;
+ Check_Unit_Names (Specs);
+
+ else
+ if Current_Verbosity = High then
+ Write_Line ("No Specs.");
+ end if;
+ end if;
+ end;
+
+ -- We are now checking if variables Dot_Replacement, Casing,
+ -- Spec_Suffix, Body_Suffix and/or Separate_Suffix
+ -- exist.
+
+ -- For each variable, if it does not exist, we do nothing,
+ -- because we already have the default.
+
+ -- Check Dot_Replacement
+
+ declare
+ Dot_Replacement : constant Variable_Value :=
+ Util.Value_Of
+ (Name_Dot_Replacement,
+ Naming.Decl.Attributes);
+
+ begin
+ pragma Assert (Dot_Replacement.Kind = Single,
+ "Dot_Replacement is not a single string");
+
+ if not Dot_Replacement.Default then
+ Get_Name_String (Dot_Replacement.Value);
+
+ if Name_Len = 0 then
+ Error_Msg
+ (Project,
+ "Dot_Replacement cannot be empty",
+ Dot_Replacement.Location);
+
+ else
+ Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
+ Data.Naming.Dot_Replacement := Name_Find;
+ Data.Naming.Dot_Repl_Loc := Dot_Replacement.Location;
+ end if;
+ end if;
+ end;
+
+ if Current_Verbosity = High then
+ Write_Str (" Dot_Replacement = """);
+ Write_Str (Get_Name_String (Data.Naming.Dot_Replacement));
+ Write_Char ('"');
+ Write_Eol;
+ end if;
+
+ -- Check Casing
+
+ declare
+ Casing_String : constant Variable_Value :=
+ Util.Value_Of
+ (Name_Casing, Naming.Decl.Attributes);
+
+ begin
+ pragma Assert (Casing_String.Kind = Single,
+ "Casing is not a single string");
+
+ if not Casing_String.Default then
+ declare
+ Casing_Image : constant String :=
+ Get_Name_String (Casing_String.Value);
+ begin
+ declare
+ Casing_Value : constant Casing_Type :=
+ Value (Casing_Image);
+ begin
+ -- Ignore Casing on platforms where file names are
+ -- case-insensitive.
+
+ if not File_Names_Case_Sensitive then
+ Data.Naming.Casing := All_Lower_Case;
+
+ else
+ Data.Naming.Casing := Casing_Value;
+ end if;
+ end;
+
+ exception
+ when Constraint_Error =>
+ if Casing_Image'Length = 0 then
+ Error_Msg
+ (Project,
+ "Casing cannot be an empty string",
+ Casing_String.Location);
+
+ else
+ Name_Len := Casing_Image'Length;
+ Name_Buffer (1 .. Name_Len) := Casing_Image;
+ Err_Vars.Error_Msg_Name_1 := Name_Find;
+ Error_Msg
+ (Project,
+ "{ is not a correct Casing",
+ Casing_String.Location);
+ end if;
+ end;
+ end if;
+ end;
+
+ if Current_Verbosity = High then
+ Write_Str (" Casing = ");
+ Write_Str (Image (Data.Naming.Casing));
+ Write_Char ('.');
+ Write_Eol;
+ end if;
+
+ -- Check Spec_Suffix
+
+ declare
+ Ada_Spec_Suffix : constant Variable_Value :=
+ Prj.Util.Value_Of
+ (Index => Name_Ada,
+ Src_Index => 0,
+ In_Array => Data.Naming.Spec_Suffix);
+
+ begin
+ if Ada_Spec_Suffix.Kind = Single
+ and then Get_Name_String (Ada_Spec_Suffix.Value) /= ""
+ then
+ Get_Name_String (Ada_Spec_Suffix.Value);
+ Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
+ Data.Naming.Current_Spec_Suffix := Name_Find;
+ Data.Naming.Spec_Suffix_Loc := Ada_Spec_Suffix.Location;
+
+ else
+ Data.Naming.Current_Spec_Suffix := Default_Ada_Spec_Suffix;
+ end if;
+ end;
+
+ if Current_Verbosity = High then
+ Write_Str (" Spec_Suffix = """);
+ Write_Str (Get_Name_String (Data.Naming.Current_Spec_Suffix));
+ Write_Char ('"');
+ Write_Eol;
+ end if;
+
+ -- Check Body_Suffix
+
+ declare
+ Ada_Body_Suffix : constant Variable_Value :=
+ Prj.Util.Value_Of
+ (Index => Name_Ada,
+ Src_Index => 0,
+ In_Array => Data.Naming.Body_Suffix);
+
+ begin
+ if Ada_Body_Suffix.Kind = Single
+ and then Get_Name_String (Ada_Body_Suffix.Value) /= ""
+ then
+ Get_Name_String (Ada_Body_Suffix.Value);
+ Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
+ Data.Naming.Current_Body_Suffix := Name_Find;
+ Data.Naming.Body_Suffix_Loc := Ada_Body_Suffix.Location;
+
+ else
+ Data.Naming.Current_Body_Suffix := Default_Ada_Body_Suffix;
+ end if;
+ end;
+
+ if Current_Verbosity = High then
+ Write_Str (" Body_Suffix = """);
+ Write_Str (Get_Name_String (Data.Naming.Current_Body_Suffix));
+ Write_Char ('"');
+ Write_Eol;
+ end if;
+
+ -- Check Separate_Suffix
+
+ declare
+ Ada_Sep_Suffix : constant Variable_Value :=
+ Prj.Util.Value_Of
+ (Variable_Name => Name_Separate_Suffix,
+ In_Variables => Naming.Decl.Attributes);
+
+ begin
+ if Ada_Sep_Suffix.Default then
+ Data.Naming.Separate_Suffix :=
+ Data.Naming.Current_Body_Suffix;
+
+ else
+ Get_Name_String (Ada_Sep_Suffix.Value);
+
+ if Name_Len = 0 then
+ Error_Msg
+ (Project,
+ "Separate_Suffix cannot be empty",
+ Ada_Sep_Suffix.Location);
+
+ else
+ Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
+ Data.Naming.Separate_Suffix := Name_Find;
+ Data.Naming.Sep_Suffix_Loc := Ada_Sep_Suffix.Location;
+ end if;
+ end if;
+ end;
+
+ if Current_Verbosity = High then
+ Write_Str (" Separate_Suffix = """);
+ Write_Str (Get_Name_String (Data.Naming.Separate_Suffix));
+ Write_Char ('"');
+ Write_Eol;
+ end if;
+
+ -- Check if Data.Naming is valid
+
+ Check_Ada_Naming_Scheme (Project, Data.Naming);
+
+ else
+ Data.Naming.Current_Spec_Suffix := Default_Ada_Spec_Suffix;
+ Data.Naming.Current_Body_Suffix := Default_Ada_Body_Suffix;
+ Data.Naming.Separate_Suffix := Default_Ada_Body_Suffix;
+ end if;
+ end Check_Naming_Scheme;
+
+ -------------------
+ -- Check_Project --
+ -------------------
+
+ function Check_Project
+ (P : Project_Id;
+ Root_Project : Project_Id;
+ Extending : Boolean) return Boolean
+ is
+ begin
+ if P = Root_Project then
+ return True;
+
+ elsif Extending then
+ declare
+ Data : Project_Data := Projects.Table (Root_Project);
+
+ begin
+ while Data.Extends /= No_Project loop
+ if P = Data.Extends then
+ return True;
+ end if;
+
+ Data := Projects.Table (Data.Extends);
+ end loop;
+ end;
+ end if;
+
+ return False;
+ end Check_Project;
+
+ ----------------------------
+ -- Compute_Directory_Last --
+ ----------------------------
+
+ function Compute_Directory_Last (Dir : String) return Natural is
+ begin
+ if Dir'Length > 1
+ and then (Dir (Dir'Last - 1) = Directory_Separator
+ or else Dir (Dir'Last - 1) = '/')
+ then
+ return Dir'Last - 1;
+ else
+ return Dir'Last;
+ end if;
+ end Compute_Directory_Last;
+
---------------
-- Error_Msg --
---------------
@@ -2237,6 +2368,250 @@ package body Prj.Nmsc is
Error_Report (Error_Buffer (1 .. Error_Last), Project);
end Error_Msg;
+ ------------------
+ -- Find_Sources --
+ ------------------
+
+ procedure Find_Sources
+ (Project : Project_Id;
+ Data : in out Project_Data;
+ For_Language : Programming_Language;
+ Follow_Links : Boolean := False)
+ is
+ Source_Dir : String_List_Id := Data.Source_Dirs;
+ Element : String_Element;
+ Dir : Dir_Type;
+ Current_Source : String_List_Id := Nil_String;
+ Source_Recorded : Boolean := False;
+
+ begin
+ if Current_Verbosity = High then
+ Write_Line ("Looking for sources:");
+ end if;
+
+ -- For each subdirectory
+
+ while Source_Dir /= Nil_String loop
+ begin
+ Source_Recorded := False;
+ Element := String_Elements.Table (Source_Dir);
+ if Element.Value /= No_Name then
+ Get_Name_String (Element.Display_Value);
+
+ declare
+ Source_Directory : constant String :=
+ Name_Buffer (1 .. Name_Len) & Directory_Separator;
+ Dir_Last : constant Natural :=
+ Compute_Directory_Last (Source_Directory);
+
+ begin
+ if Current_Verbosity = High then
+ Write_Str ("Source_Dir = ");
+ Write_Line (Source_Directory);
+ end if;
+
+ -- We look to every entry in the source directory
+
+ Open (Dir, Source_Directory
+ (Source_Directory'First .. Dir_Last));
+
+ loop
+ Read (Dir, Name_Buffer, Name_Len);
+
+ if Current_Verbosity = High then
+ Write_Str (" Checking ");
+ Write_Line (Name_Buffer (1 .. Name_Len));
+ end if;
+
+ exit when Name_Len = 0;
+
+ declare
+ File_Name : constant Name_Id := Name_Find;
+ Path : constant String :=
+ Normalize_Pathname
+ (Name => Name_Buffer (1 .. Name_Len),
+ Directory => Source_Directory
+ (Source_Directory'First .. Dir_Last),
+ Resolve_Links => Follow_Links,
+ Case_Sensitive => True);
+ Path_Name : Name_Id;
+
+ begin
+ Name_Len := Path'Length;
+ Name_Buffer (1 .. Name_Len) := Path;
+ Path_Name := Name_Find;
+
+ if For_Language = Lang_Ada then
+ -- We attempt to register it as a source.
+ -- However, there is no error if the file
+ -- does not contain a valid source.
+ -- But there is an error if we have a
+ -- duplicate unit name.
+
+ Record_Ada_Source
+ (File_Name => File_Name,
+ Path_Name => Path_Name,
+ Project => Project,
+ Data => Data,
+ Location => No_Location,
+ Current_Source => Current_Source,
+ Source_Recorded => Source_Recorded,
+ Follow_Links => Follow_Links);
+
+ else
+ Check_For_Source
+ (File_Name => File_Name,
+ Path_Name => Path_Name,
+ Project => Project,
+ Data => Data,
+ Location => No_Location,
+ Language => For_Language,
+ Suffix =>
+ Get_Name_String
+ (Data.Impl_Suffixes (For_Language)),
+ Naming_Exception => False);
+ end if;
+ end;
+ end loop;
+
+ Close (Dir);
+ end;
+ end if;
+
+ exception
+ when Directory_Error =>
+ null;
+ end;
+
+ if Source_Recorded then
+ String_Elements.Table (Source_Dir).Flag := True;
+ end if;
+
+ Source_Dir := Element.Next;
+ end loop;
+
+ if Current_Verbosity = High then
+ Write_Line ("end Looking for sources.");
+ end if;
+
+ if For_Language = Lang_Ada then
+ -- If we have looked for sources and found none, then
+ -- it is an error, except if it is an extending project.
+ -- If a non extending project is not supposed to contain
+ -- any source, then we never call Find_Sources.
+
+ if Current_Source /= Nil_String then
+ Data.Sources_Present := True;
+
+ elsif Data.Extends = No_Project then
+ Error_Msg
+ (Project,
+ "there are no Ada sources in this project",
+ Data.Location);
+ end if;
+ end if;
+ end Find_Sources;
+
+ --------------------------------
+ -- Free_Ada_Naming_Exceptions --
+ --------------------------------
+
+ procedure Free_Ada_Naming_Exceptions is
+ begin
+ Ada_Naming_Exception_Table.Set_Last (0);
+ Ada_Naming_Exceptions.Reset;
+ Reverse_Ada_Naming_Exceptions.Reset;
+ end Free_Ada_Naming_Exceptions;
+
+ ---------------
+ -- Get_Mains --
+ ---------------
+
+ procedure Get_Mains (Project : Project_Id; Data : in out Project_Data) is
+ Mains : constant Variable_Value :=
+ Prj.Util.Value_Of (Name_Main, Data.Decl.Attributes);
+
+ begin
+ Data.Mains := Mains.Values;
+
+ -- If no Mains were specified, and if we are an extending
+ -- project, inherit the Mains from the project we are extending.
+
+ if Mains.Default then
+ if Data.Extends /= No_Project then
+ Data.Mains := Projects.Table (Data.Extends).Mains;
+ end if;
+
+ -- In a library project file, Main cannot be specified
+
+ elsif Data.Library then
+ Error_Msg
+ (Project,
+ "a library project file cannot have Main specified",
+ Mains.Location);
+ end if;
+ end Get_Mains;
+
+ ---------------------------
+ -- Get_Sources_From_File --
+ ---------------------------
+
+ procedure Get_Sources_From_File
+ (Path : String;
+ Location : Source_Ptr;
+ Project : Project_Id)
+ is
+ File : Prj.Util.Text_File;
+ Line : String (1 .. 250);
+ Last : Natural;
+ Source_Name : Name_Id;
+
+ begin
+ Source_Names.Reset;
+
+ if Current_Verbosity = High then
+ Write_Str ("Opening """);
+ Write_Str (Path);
+ Write_Line (""".");
+ end if;
+
+ -- Open the file
+
+ Prj.Util.Open (File, Path);
+
+ if not Prj.Util.Is_Valid (File) then
+ Error_Msg (Project, "file does not exist", Location);
+ else
+ -- Read the lines one by one
+
+ while not Prj.Util.End_Of_File (File) loop
+ Prj.Util.Get_Line (File, Line, Last);
+
+ -- A non empty, non comment line should contain a file name
+
+ if Last /= 0
+ and then (Last = 1 or else Line (1 .. 2) /= "--")
+ then
+ -- ??? we should check that there is no directory information
+
+ Name_Len := Last;
+ Name_Buffer (1 .. Name_Len) := Line (1 .. Last);
+ Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
+ Source_Name := Name_Find;
+ Source_Names.Set
+ (K => Source_Name,
+ E =>
+ (Name => Source_Name,
+ Location => Location,
+ Found => False));
+ end if;
+ end loop;
+
+ Prj.Util.Close (File);
+
+ end if;
+ end Get_Sources_From_File;
+
--------------
-- Get_Unit --
--------------
@@ -2244,57 +2619,42 @@ package body Prj.Nmsc is
procedure Get_Unit
(Canonical_File_Name : Name_Id;
Naming : Naming_Data;
+ Exception_Id : out Ada_Naming_Exception_Id;
Unit_Name : out Name_Id;
Unit_Kind : out Spec_Or_Body;
Needs_Pragma : out Boolean)
is
- function Check_Exception (Canonical : Name_Id) return Boolean;
- pragma Inline (Check_Exception);
- -- Check if Canonical is one of the exceptions in List.
- -- Returns True if Get_Unit should exit
-
- ---------------------
- -- Check_Exception --
- ---------------------
-
- function Check_Exception (Canonical : Name_Id) return Boolean is
- Info : Unit_Info := Naming_Exceptions.Get (Canonical);
- VMS_Name : Name_Id;
-
- begin
- if Info = No_Unit then
- if Hostparm.OpenVMS then
- VMS_Name := Canonical;
- Get_Name_String (VMS_Name);
-
- if Name_Buffer (Name_Len) = '.' then
- Name_Len := Name_Len - 1;
- VMS_Name := Name_Find;
- end if;
+ Info_Id : Ada_Naming_Exception_Id
+ := Ada_Naming_Exceptions.Get (Canonical_File_Name);
+ VMS_Name : Name_Id;
- Info := Naming_Exceptions.Get (VMS_Name);
+ begin
+ if Info_Id = No_Ada_Naming_Exception then
+ if Hostparm.OpenVMS then
+ VMS_Name := Canonical_File_Name;
+ Get_Name_String (VMS_Name);
+
+ if Name_Buffer (Name_Len) = '.' then
+ Name_Len := Name_Len - 1;
+ VMS_Name := Name_Find;
end if;
- if Info = No_Unit then
- return False;
- end if;
+ Info_Id := Ada_Naming_Exceptions.Get (VMS_Name);
end if;
- Unit_Kind := Info.Kind;
- Unit_Name := Info.Unit;
- Needs_Pragma := True;
- return True;
- end Check_Exception;
-
- -- Start of processing for Get_Unit
-
- begin
- Needs_Pragma := False;
+ end if;
- if Check_Exception (Canonical_File_Name) then
+ if Info_Id /= No_Ada_Naming_Exception then
+ Exception_Id := Info_Id;
+ Unit_Name := No_Name;
+ Unit_Kind := Specification;
+ Needs_Pragma := True;
return;
end if;
+ Needs_Pragma := False;
+ Exception_Id := No_Ada_Naming_Exception;
+
Get_Name_String (Canonical_File_Name);
declare
@@ -2514,6 +2874,15 @@ package body Prj.Nmsc is
end;
end Get_Unit;
+ ----------
+ -- Hash --
+ ----------
+
+ function Hash (Unit : Unit_Info) return Header_Num is
+ begin
+ return Header_Num (Unit.Unit mod 2048);
+ end Hash;
+
-----------------------
-- Is_Illegal_Suffix --
-----------------------
@@ -2648,7 +3017,8 @@ package body Prj.Nmsc is
Display_Value => Non_Canonical_Path,
Location => No_Location,
Flag => False,
- Next => Nil_String);
+ Next => Nil_String,
+ Index => 0);
-- Case of first source directory
@@ -3024,7 +3394,8 @@ package body Prj.Nmsc is
Display_Value => Data.Display_Directory,
Location => No_Location,
Flag => False,
- Next => Nil_String);
+ Next => Nil_String,
+ Index => 0);
if Current_Verbosity = High then
Write_Line ("Single source directory:");
@@ -3391,10 +3762,11 @@ package body Prj.Nmsc is
if Suffix2 = No_Array_Element then
Array_Elements.Increment_Last;
Array_Elements.Table (Array_Elements.Last) :=
- (Index => Element.Index,
+ (Index => Element.Index,
+ Src_Index => Element.Src_Index,
Index_Case_Sensitive => False,
- Value => Element.Value,
- Next => Spec_Suffixs);
+ Value => Element.Value,
+ Next => Spec_Suffixs);
Spec_Suffixs := Array_Elements.Last;
end if;
@@ -3467,6 +3839,7 @@ package body Prj.Nmsc is
Array_Elements.Increment_Last;
Array_Elements.Table (Array_Elements.Last) :=
(Index => Element.Index,
+ Src_Index => Element.Src_Index,
Index_Case_Sensitive => False,
Value => Element.Value,
Next => Impl_Suffixs);
@@ -3609,6 +3982,331 @@ package body Prj.Nmsc is
end if;
end Locate_Directory;
+ ---------------------------
+ -- Other_Languages_Check --
+ ---------------------------
+
+ procedure Other_Languages_Check
+ (Project : Project_Id;
+ Report_Error : Put_Line_Access) is
+
+ Data : Project_Data;
+
+ Languages : Variable_Value := Nil_Variable_Value;
+
+ begin
+ Language_Independent_Check (Project, Report_Error);
+
+ Error_Report := Report_Error;
+
+ Data := Projects.Table (Project);
+ Languages := Prj.Util.Value_Of (Name_Languages, Data.Decl.Attributes);
+
+ Data.Sources_Present := Data.Source_Dirs /= Nil_String;
+
+ if Data.Sources_Present then
+ -- Check if languages other than Ada are specified in this project
+
+ if Languages.Default then
+ -- Attribute Languages is not specified. So, it defaults to
+ -- a project of language Ada only.
+
+ Data.Languages (Lang_Ada) := True;
+
+ -- No sources of languages other than Ada
+
+ Data.Sources_Present := False;
+
+ else
+ declare
+ Current : String_List_Id := Languages.Values;
+ Element : String_Element;
+ OK : Boolean := False;
+ begin
+ -- Assumethat there is no language other than Ada specified.
+ -- If in fact there is at least one, we will set back
+ -- Sources_Present to True.
+
+ Data.Sources_Present := False;
+
+ -- Look through all the languages specified in attribute
+ -- Languages, if any
+
+ while Current /= Nil_String loop
+ Element := String_Elements.Table (Current);
+ Get_Name_String (Element.Value);
+ To_Lower (Name_Buffer (1 .. Name_Len));
+ OK := False;
+
+ -- Check if it is a known language
+
+ Lang_Loop : for Lang in Programming_Language loop
+ if
+ Name_Buffer (1 .. Name_Len) = Lang_Names (Lang).all
+ then
+ -- Yes, this is a known language
+
+ OK := True;
+
+ -- Indicate the presence of this language
+ Data.Languages (Lang) := True;
+
+ -- If it is a language other than Ada, indicate that
+ -- there should be some sources of a language other
+ -- than Ada.
+
+ if Lang /= Lang_Ada then
+ Data.Sources_Present := True;
+ end if;
+
+ exit Lang_Loop;
+ end if;
+ end loop Lang_Loop;
+
+ -- We don't support this language: report an error
+
+ if not OK then
+ Error_Msg_Name_1 := Element.Value;
+ Error_Msg
+ (Project,
+ "unknown programming language {",
+ Element.Location);
+ end if;
+
+ Current := Element.Next;
+ end loop;
+ end;
+ end if;
+ end if;
+
+ -- If there may be some sources, look for them
+
+ if Data.Sources_Present then
+ -- Set Source_Present to False. It will be set back to True whenever
+ -- a source is found.
+
+ Data.Sources_Present := False;
+
+ for Lang in Other_Programming_Language loop
+ -- For each language (other than Ada) in the project file
+
+ if Data.Languages (Lang) then
+ -- Reset the indication that there are sources of this
+ -- language. It will be set back to True whenever we find a
+ -- source of the language.
+
+ Data.Languages (Lang) := False;
+
+ -- First, get the source suffix for the language
+
+ Data.Impl_Suffixes (Lang) := Suffix_For (Lang, Data.Naming);
+
+ -- Then, deal with the naming exceptions, if any
+
+ Source_Names.Reset;
+
+ declare
+ Naming_Exceptions : constant Variable_Value :=
+ Value_Of
+ (Index => Lang_Name_Ids (Lang),
+ Src_Index => 0,
+ In_Array => Data.Naming.Implementation_Exceptions);
+ Element_Id : String_List_Id;
+ Element : String_Element;
+ File_Id : Name_Id;
+ Source_Found : Boolean := False;
+ begin
+ -- If there are naming exceptions, look through them one
+ -- by one.
+
+ if Naming_Exceptions /= Nil_Variable_Value then
+ Element_Id := Naming_Exceptions.Values;
+
+ while Element_Id /= Nil_String loop
+ Element := String_Elements.Table (Element_Id);
+ Get_Name_String (Element.Value);
+ Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
+ File_Id := Name_Find;
+
+ -- Put each naming exception in the Source_Names
+ -- hash table, but if there are repetition, don't
+ -- bother after the first instance.
+
+ if Source_Names.Get (File_Id) = No_Name_Location then
+ Source_Found := True;
+ Source_Names.Set
+ (File_Id,
+ (Name => File_Id,
+ Location => Element.Location,
+ Found => False));
+ end if;
+
+ Element_Id := Element.Next;
+ end loop;
+
+ -- If there is at least one naming exception, record
+ -- those that are found in the source directories.
+
+ if Source_Found then
+ Record_Other_Sources
+ (Project => Project,
+ Data => Data,
+ Language => Lang,
+ Naming_Exceptions => True);
+ end if;
+
+ end if;
+ end;
+
+ -- Now, check if a list of sources is declared either through
+ -- a string list (attribute Source_Files) or a text file
+ -- (attribute Source_List_File).
+ -- If a source list is declared, we will consider only those
+ -- naming exceptions that are on the list.
+
+ declare
+ Sources : constant Variable_Value :=
+ Util.Value_Of
+ (Name_Source_Files,
+ Data.Decl.Attributes);
+
+ Source_List_File : constant Variable_Value :=
+ Util.Value_Of
+ (Name_Source_List_File,
+ Data.Decl.Attributes);
+
+ begin
+ pragma Assert
+ (Sources.Kind = List,
+ "Source_Files is not a list");
+
+ pragma Assert
+ (Source_List_File.Kind = Single,
+ "Source_List_File is not a single string");
+
+ if not Sources.Default then
+ if not Source_List_File.Default then
+ Error_Msg
+ (Project,
+ "?both variables source_files and " &
+ "source_list_file are present",
+ Source_List_File.Location);
+ end if;
+
+ -- Sources is a list of file names
+
+ declare
+ Current : String_List_Id := Sources.Values;
+ Element : String_Element;
+ Location : Source_Ptr;
+ Name : Name_Id;
+
+ begin
+ Source_Names.Reset;
+
+ -- Put all the sources in the Source_Names hash
+ -- table.
+
+ while Current /= Nil_String loop
+ Element := String_Elements.Table (Current);
+ Get_Name_String (Element.Value);
+ Canonical_Case_File_Name
+ (Name_Buffer (1 .. Name_Len));
+ Name := Name_Find;
+
+ -- If the element has no location, then use the
+ -- location of Sources to report possible errors.
+
+ if Element.Location = No_Location then
+ Location := Sources.Location;
+
+ else
+ Location := Element.Location;
+ end if;
+
+ Source_Names.Set
+ (K => Name,
+ E =>
+ (Name => Name,
+ Location => Location,
+ Found => False));
+
+ Current := Element.Next;
+ end loop;
+
+ -- And look for their directories
+
+ Record_Other_Sources
+ (Project => Project,
+ Data => Data,
+ Language => Lang,
+ Naming_Exceptions => False);
+ end;
+
+ -- No source_files specified.
+ -- We check if Source_List_File has been specified.
+
+ elsif not Source_List_File.Default then
+
+ -- Source_List_File is the name of the file
+ -- that contains the source file names
+
+ declare
+ Source_File_Path_Name : constant String :=
+ Path_Name_Of
+ (Source_List_File.Value,
+ Data.Directory);
+
+ begin
+ if Source_File_Path_Name'Length = 0 then
+ Err_Vars.Error_Msg_Name_1 := Source_List_File.Value;
+ Error_Msg
+ (Project,
+ "file with sources { does not exist",
+ Source_List_File.Location);
+
+ else
+ -- Read the file, putting each source in the
+ -- Source_Names hash table.
+
+ Get_Sources_From_File
+ (Source_File_Path_Name,
+ Source_List_File.Location,
+ Project);
+
+ -- And look for their directories.
+
+ Record_Other_Sources
+ (Project => Project,
+ Data => Data,
+ Language => Lang,
+ Naming_Exceptions => False);
+ end if;
+ end;
+
+ else
+ -- Neither Source_Files nor Source_List_File has been
+ -- specified. Find all the files that satisfy
+ -- the naming scheme in all the source directories.
+ -- All the naming exceptions that effectively exist are
+ -- also part of the source of this language.
+
+ Find_Sources (Project, Data, Lang);
+ end if;
+
+ end;
+ end if;
+ end loop;
+ end if;
+
+ -- Finally, get the mains, if any
+
+ Get_Mains (Project, Data);
+
+ Projects.Table (Project) := Data;
+
+ end Other_Languages_Check;
+
------------------
-- Path_Name_Of --
------------------
@@ -3634,6 +4332,44 @@ package body Prj.Nmsc is
end if;
end Path_Name_Of;
+ -------------------------------
+ -- Prepare_Ada_Naming_Exceptions --
+ -------------------------------
+
+ procedure Prepare_Ada_Naming_Exceptions
+ (List : Array_Element_Id;
+ Kind : Spec_Or_Body)
+ is
+ Current : Array_Element_Id := List;
+ Element : Array_Element;
+
+ Unit : Unit_Info;
+
+ begin
+ -- Traverse the list
+
+ while Current /= No_Array_Element loop
+ Element := Array_Elements.Table (Current);
+
+ if Element.Index /= No_Name then
+ Unit :=
+ (Kind => Kind,
+ Unit => Element.Index,
+ Next => No_Ada_Naming_Exception);
+ Reverse_Ada_Naming_Exceptions.Set
+ (Unit, (Element.Value.Value, Element.Value.Index));
+ Unit.Next := Ada_Naming_Exceptions.Get (Element.Value.Value);
+ Ada_Naming_Exception_Table.Increment_Last;
+ Ada_Naming_Exception_Table.Table
+ (Ada_Naming_Exception_Table.Last) := Unit;
+ Ada_Naming_Exceptions.Set
+ (Element.Value.Value, Ada_Naming_Exception_Table.Last);
+ end if;
+
+ Current := Element.Next;
+ end loop;
+ end Prepare_Ada_Naming_Exceptions;
+
---------------------
-- Project_Extends --
---------------------
@@ -3656,11 +4392,11 @@ package body Prj.Nmsc is
end loop;
end Project_Extends;
- -------------------
- -- Record_Source --
- -------------------
+ -----------------------
+ -- Record_Ada_Source --
+ -----------------------
- procedure Record_Source
+ procedure Record_Ada_Source
(File_Name : Name_Id;
Path_Name : Name_Id;
Project : Project_Id;
@@ -3668,20 +4404,26 @@ package body Prj.Nmsc is
Location : Source_Ptr;
Current_Source : in out String_List_Id;
Source_Recorded : in out Boolean;
- Trusted_Mode : Boolean)
+ Follow_Links : Boolean)
is
Canonical_File_Name : Name_Id;
Canonical_Path_Name : Name_Id;
+ Exception_Id : Ada_Naming_Exception_Id;
Unit_Name : Name_Id;
Unit_Kind : Spec_Or_Body;
+ Unit_Index : Int := 0;
+ Info : Unit_Info;
+ Name_Index : Name_And_Index;
Needs_Pragma : Boolean;
The_Location : Source_Ptr := Location;
Previous_Source : constant String_List_Id := Current_Source;
- Except_Name : Name_Id := No_Name;
+ Except_Name : Name_And_Index := No_Name_And_Index;
Unit_Prj : Unit_Project;
+ File_Name_Recorded : Boolean := False;
+
begin
Get_Name_String (File_Name);
Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
@@ -3691,7 +4433,7 @@ package body Prj.Nmsc is
Canonical_Path : constant String :=
Normalize_Pathname
(Get_Name_String (Path_Name),
- Resolve_Links => not Trusted_Mode,
+ Resolve_Links => Follow_Links,
Case_Sensitive => False);
begin
Name_Len := 0;
@@ -3705,11 +4447,14 @@ package body Prj.Nmsc is
Get_Unit
(Canonical_File_Name => Canonical_File_Name,
Naming => Data.Naming,
+ Exception_Id => Exception_Id,
Unit_Name => Unit_Name,
Unit_Kind => Unit_Kind,
Needs_Pragma => Needs_Pragma);
- if Unit_Name = No_Name then
+ if Exception_Id = No_Ada_Naming_Exception and then
+ Unit_Name = No_Name
+ then
if Current_Verbosity = High then
Write_Str (" """);
Write_Str (Get_Name_String (Canonical_File_Name));
@@ -3717,19 +4462,21 @@ package body Prj.Nmsc is
end if;
else
+
-- Check to see if the source has been hidden by an exception,
-- but only if it is not an exception.
if not Needs_Pragma then
Except_Name :=
- Reverse_Naming_Exceptions.Get ((Unit_Kind, Unit_Name));
+ Reverse_Ada_Naming_Exceptions.Get
+ ((Unit_Kind, Unit_Name, No_Ada_Naming_Exception));
- if Except_Name /= No_Name then
+ if Except_Name /= No_Name_And_Index then
if Current_Verbosity = High then
Write_Str (" """);
Write_Str (Get_Name_String (Canonical_File_Name));
Write_Str (""" contains a unit that is found in """);
- Write_Str (Get_Name_String (Except_Name));
+ Write_Str (Get_Name_String (Except_Name.Name));
Write_Line (""" (ignored).");
end if;
@@ -3741,147 +4488,348 @@ package body Prj.Nmsc is
end if;
end if;
- -- Put the file name in the list of sources of the project
+ loop
+ if Exception_Id /= No_Ada_Naming_Exception then
+ Info := Ada_Naming_Exception_Table.Table (Exception_Id);
+ Exception_Id := Info.Next;
+ Info.Next := No_Ada_Naming_Exception;
+ Name_Index := Reverse_Ada_Naming_Exceptions.Get (Info);
- String_Elements.Increment_Last;
- String_Elements.Table (String_Elements.Last) :=
- (Value => Canonical_File_Name,
- Display_Value => File_Name,
- Location => No_Location,
- Flag => False,
- Next => Nil_String);
+ Unit_Name := Info.Unit;
+ Unit_Index := Name_Index.Index;
+ Unit_Kind := Info.Kind;
+ end if;
+ -- Put the file name in the list of sources of the project
- if Current_Source = Nil_String then
- Data.Sources := String_Elements.Last;
+ if not File_Name_Recorded then
+ String_Elements.Increment_Last;
+ String_Elements.Table (String_Elements.Last) :=
+ (Value => Canonical_File_Name,
+ Display_Value => File_Name,
+ Location => No_Location,
+ Flag => False,
+ Next => Nil_String,
+ Index => Unit_Index);
+ end if;
- else
- String_Elements.Table (Current_Source).Next :=
- String_Elements.Last;
- end if;
+ if Current_Source = Nil_String then
+ Data.Sources := String_Elements.Last;
- Current_Source := String_Elements.Last;
+ else
+ String_Elements.Table (Current_Source).Next :=
+ String_Elements.Last;
+ end if;
- -- Put the unit in unit list
+ Current_Source := String_Elements.Last;
- declare
- The_Unit : Unit_Id := Units_Htable.Get (Unit_Name);
- The_Unit_Data : Unit_Data;
+ -- Put the unit in unit list
- begin
- if Current_Verbosity = High then
- Write_Str ("Putting ");
- Write_Str (Get_Name_String (Unit_Name));
- Write_Line (" in the unit list.");
- end if;
+ declare
+ The_Unit : Unit_Id := Units_Htable.Get (Unit_Name);
+ The_Unit_Data : Unit_Data;
- -- The unit is already in the list, but may be it is
- -- only the other unit kind (spec or body), or what is
- -- in the unit list is a unit of a project we are extending.
+ begin
+ if Current_Verbosity = High then
+ Write_Str ("Putting ");
+ Write_Str (Get_Name_String (Unit_Name));
+ Write_Line (" in the unit list.");
+ end if;
- if The_Unit /= Prj.Com.No_Unit then
- The_Unit_Data := Units.Table (The_Unit);
+ -- The unit is already in the list, but may be it is
+ -- only the other unit kind (spec or body), or what is
+ -- in the unit list is a unit of a project we are extending.
- if The_Unit_Data.File_Names (Unit_Kind).Name = No_Name
- or else Project_Extends
- (Data.Extends,
- The_Unit_Data.File_Names (Unit_Kind).Project)
- then
- if The_Unit_Data.File_Names (Unit_Kind).Path = Slash then
- Remove_Forbidden_File_Name
- (The_Unit_Data.File_Names (Unit_Kind).Name);
- end if;
+ if The_Unit /= Prj.Com.No_Unit then
+ The_Unit_Data := Units.Table (The_Unit);
+
+ if The_Unit_Data.File_Names (Unit_Kind).Name = No_Name
+ or else Project_Extends
+ (Data.Extends,
+ The_Unit_Data.File_Names (Unit_Kind).Project)
+ then
+ if The_Unit_Data.File_Names (Unit_Kind).Path = Slash then
+ Remove_Forbidden_File_Name
+ (The_Unit_Data.File_Names (Unit_Kind).Name);
+ end if;
+
+ -- Record the file name in the hash table Files_Htable
+
+ Unit_Prj := (Unit => The_Unit, Project => Project);
+ Files_Htable.Set (Canonical_File_Name, Unit_Prj);
+
+ The_Unit_Data.File_Names (Unit_Kind) :=
+ (Name => Canonical_File_Name,
+ Index => Unit_Index,
+ Display_Name => File_Name,
+ Path => Canonical_Path_Name,
+ Display_Path => Path_Name,
+ Project => Project,
+ Needs_Pragma => Needs_Pragma);
+ Units.Table (The_Unit) := The_Unit_Data;
+ Source_Recorded := True;
+
+ elsif The_Unit_Data.File_Names (Unit_Kind).Project = Project
+ and then (Data.Known_Order_Of_Source_Dirs or else
+ The_Unit_Data.File_Names (Unit_Kind).Path =
+ Canonical_Path_Name)
+ then
+ if Previous_Source = Nil_String then
+ Data.Sources := Nil_String;
+ else
+ String_Elements.Table (Previous_Source).Next :=
+ Nil_String;
+ String_Elements.Decrement_Last;
+ end if;
+
+ Current_Source := Previous_Source;
- -- Record the file name in the hash table Files_Htable
-
- Unit_Prj := (Unit => The_Unit, Project => Project);
- Files_Htable.Set (Canonical_File_Name, Unit_Prj);
-
- The_Unit_Data.File_Names (Unit_Kind) :=
- (Name => Canonical_File_Name,
- Display_Name => File_Name,
- Path => Canonical_Path_Name,
- Display_Path => Path_Name,
- Project => Project,
- Needs_Pragma => Needs_Pragma);
- Units.Table (The_Unit) := The_Unit_Data;
- Source_Recorded := True;
-
- elsif The_Unit_Data.File_Names (Unit_Kind).Project = Project
- and then (Data.Known_Order_Of_Source_Dirs or else
- The_Unit_Data.File_Names (Unit_Kind).Path =
- Canonical_Path_Name)
- then
- if Previous_Source = Nil_String then
- Data.Sources := Nil_String;
else
- String_Elements.Table (Previous_Source).Next :=
- Nil_String;
- String_Elements.Decrement_Last;
+ -- It is an error to have two units with the same name
+ -- and the same kind (spec or body).
+
+ if The_Location = No_Location then
+ The_Location := Projects.Table (Project).Location;
+ end if;
+
+ Err_Vars.Error_Msg_Name_1 := Unit_Name;
+ Error_Msg (Project, "duplicate source {", The_Location);
+
+ Err_Vars.Error_Msg_Name_1 :=
+ Projects.Table
+ (The_Unit_Data.File_Names (Unit_Kind).Project).Name;
+ Err_Vars.Error_Msg_Name_2 :=
+ The_Unit_Data.File_Names (Unit_Kind).Path;
+ Error_Msg
+ (Project, "\ project file {, {", The_Location);
+
+ Err_Vars.Error_Msg_Name_1 :=
+ Projects.Table (Project).Name;
+ Err_Vars.Error_Msg_Name_2 := Canonical_Path_Name;
+ Error_Msg
+ (Project, "\ project file {, {", The_Location);
+
end if;
- Current_Source := Previous_Source;
+ -- It is a new unit, create a new record
else
- -- It is an error to have two units with the same name
- -- and the same kind (spec or body).
+ -- First, check if there is no other unit with this file
+ -- name in another project. If it is, report an error.
+ -- Of course, we do that only for the first unit in the
+ -- source file.
+
+ Unit_Prj := Files_Htable.Get (Canonical_File_Name);
- if The_Location = No_Location then
- The_Location := Projects.Table (Project).Location;
+ if not File_Name_Recorded and then
+ Unit_Prj /= No_Unit_Project
+ then
+ Error_Msg_Name_1 := File_Name;
+ Error_Msg_Name_2 :=
+ Projects.Table (Unit_Prj.Project).Name;
+ Error_Msg
+ (Project,
+ "{ is already a source of project {",
+ Location);
+
+ else
+ Units.Increment_Last;
+ The_Unit := Units.Last;
+ Units_Htable.Set (Unit_Name, The_Unit);
+ Unit_Prj := (Unit => The_Unit, Project => Project);
+ Files_Htable.Set (Canonical_File_Name, Unit_Prj);
+ The_Unit_Data.Name := Unit_Name;
+ The_Unit_Data.File_Names (Unit_Kind) :=
+ (Name => Canonical_File_Name,
+ Index => Unit_Index,
+ Display_Name => File_Name,
+ Path => Canonical_Path_Name,
+ Display_Path => Path_Name,
+ Project => Project,
+ Needs_Pragma => Needs_Pragma);
+ Units.Table (The_Unit) := The_Unit_Data;
+ Source_Recorded := True;
end if;
+ end if;
+ end;
+
+ exit when Exception_Id = No_Ada_Naming_Exception;
+ File_Name_Recorded := True;
+ end loop;
+ end if;
+ end Record_Ada_Source;
+
+ --------------------------
+ -- Record_Other_Sources --
+ --------------------------
+
+ procedure Record_Other_Sources
+ (Project : Project_Id;
+ Data : in out Project_Data;
+ Language : Programming_Language;
+ Naming_Exceptions : Boolean)
+ is
+ Source_Dir : String_List_Id := Data.Source_Dirs;
+ Element : String_Element;
+ Path : Name_Id;
+
+ Dir : Dir_Type;
+ Canonical_Name : Name_Id;
+ Name_Str : String (1 .. 1_024);
+ Last : Natural := 0;
+ NL : Name_Location;
- Err_Vars.Error_Msg_Name_1 := Unit_Name;
- Error_Msg (Project, "duplicate source {", The_Location);
+ First_Error : Boolean := True;
- Err_Vars.Error_Msg_Name_1 :=
- Projects.Table
- (The_Unit_Data.File_Names (Unit_Kind).Project).Name;
- Err_Vars.Error_Msg_Name_2 :=
- The_Unit_Data.File_Names (Unit_Kind).Path;
- Error_Msg (Project, "\ project file {, {", The_Location);
+ Suffix : constant String :=
+ Get_Name_String (Data.Impl_Suffixes (Language));
+
+ begin
+ while Source_Dir /= Nil_String loop
+ Element := String_Elements.Table (Source_Dir);
+
+ declare
+ Dir_Path : constant String := Get_Name_String (Element.Value);
+ begin
+ if Current_Verbosity = High then
+ Write_Str ("checking directory """);
+ Write_Str (Dir_Path);
+ Write_Str (""" for ");
- Err_Vars.Error_Msg_Name_1 := Projects.Table (Project).Name;
- Err_Vars.Error_Msg_Name_2 := Canonical_Path_Name;
- Error_Msg (Project, "\ project file {, {", The_Location);
+ if Naming_Exceptions then
+ Write_Str ("naming exceptions");
+ else
+ Write_Str ("sources");
end if;
- -- It is a new unit, create a new record
+ Write_Str (" of Language ");
+ Write_Line (Lang_Display_Names (Language).all);
+ end if;
- else
- -- First, check if there is no other unit with this file name
- -- in another project. If it is, report an error.
+ Open (Dir, Dir_Path);
+
+ loop
+ Read (Dir, Name_Str, Last);
+ exit when Last = 0;
+
+ if Is_Regular_File
+ (Dir_Path & Directory_Separator & Name_Str (1 .. Last))
+ then
+ Name_Len := Last;
+ Name_Buffer (1 .. Name_Len) := Name_Str (1 .. Last);
+ Canonical_Name := Name_Find;
+ NL := Source_Names.Get (Canonical_Name);
+
+ if NL /= No_Name_Location then
+ if NL.Found then
+ if not Data.Known_Order_Of_Source_Dirs then
+ Error_Msg_Name_1 := Canonical_Name;
+ Error_Msg
+ (Project,
+ "{ is found in several source directories",
+ NL.Location);
+ end if;
+
+ else
+ NL.Found := True;
+ Source_Names.Set (Canonical_Name, NL);
+ Name_Len := Dir_Path'Length;
+ Name_Buffer (1 .. Name_Len) := Dir_Path;
+ Add_Char_To_Name_Buffer (Directory_Separator);
+ Add_Str_To_Name_Buffer (Name_Str (1 .. Last));
+ Path := Name_Find;
+
+ Check_For_Source
+ (File_Name => Canonical_Name,
+ Path_Name => Path,
+ Project => Project,
+ Data => Data,
+ Location => NL.Location,
+ Language => Language,
+ Suffix => Suffix,
+ Naming_Exception => Naming_Exceptions);
+ end if;
+ end if;
+ end if;
+ end loop;
+
+ Close (Dir);
+ end;
+
+ Source_Dir := Element.Next;
+ end loop;
+
+ if not Naming_Exceptions then
+
+ NL := Source_Names.Get_First;
+
+ -- It is an error if a source file name in a source list or
+ -- in a source list file is not found.
- Unit_Prj := Files_Htable.Get (Canonical_File_Name);
+ while NL /= No_Name_Location loop
+ if not NL.Found then
+ Err_Vars.Error_Msg_Name_1 := NL.Name;
- if Unit_Prj /= No_Unit_Project then
- Error_Msg_Name_1 := File_Name;
- Error_Msg_Name_2 := Projects.Table (Unit_Prj.Project).Name;
+ if First_Error then
Error_Msg
(Project,
- "{ is already a source of project {",
- Location);
+ "source file { cannot be found",
+ NL.Location);
+ First_Error := False;
else
- Units.Increment_Last;
- The_Unit := Units.Last;
- Units_Htable.Set (Unit_Name, The_Unit);
- Unit_Prj := (Unit => The_Unit, Project => Project);
- Files_Htable.Set (Canonical_File_Name, Unit_Prj);
- The_Unit_Data.Name := Unit_Name;
- The_Unit_Data.File_Names (Unit_Kind) :=
- (Name => Canonical_File_Name,
- Display_Name => File_Name,
- Path => Canonical_Path_Name,
- Display_Path => Path_Name,
- Project => Project,
- Needs_Pragma => Needs_Pragma);
- Units.Table (The_Unit) := The_Unit_Data;
- Source_Recorded := True;
+ Error_Msg
+ (Project,
+ "\source file { cannot be found",
+ NL.Location);
end if;
end if;
+
+ NL := Source_Names.Get_Next;
+ end loop;
+
+ -- Any naming exception of this language that is not in a list
+ -- of sources must be removed.
+
+ declare
+ Source_Id : Other_Source_Id := Data.First_Other_Source;
+ Prev_Id : Other_Source_Id := No_Other_Source;
+ Source : Other_Source;
+ begin
+ while Source_Id /= No_Other_Source loop
+ Source := Other_Sources.Table (Source_Id);
+
+ if Source.Language = Language
+ and then Source.Naming_Exception
+ then
+ if Current_Verbosity = High then
+ Write_Str ("Naming exception """);
+ Write_Str (Get_Name_String (Source.File_Name));
+ Write_Str (""" is not in the list of sources,");
+ Write_Line (" so it is removed.");
+ end if;
+
+ if Prev_Id = No_Other_Source then
+ Data.First_Other_Source := Source.Next;
+
+ else
+ Other_Sources.Table (Prev_Id).Next := Source.Next;
+ end if;
+
+ Source_Id := Source.Next;
+
+ if Source_Id = No_Other_Source then
+ Data.Last_Other_Source := Prev_Id;
+ end if;
+
+ else
+ Prev_Id := Source_Id;
+ Source_Id := Source.Next;
+ end if;
+ end loop;
end;
end if;
- end Record_Source;
+ end Record_Other_Sources;
----------------------
-- Show_Source_Dirs --
@@ -3904,4 +4852,35 @@ package body Prj.Nmsc is
Write_Line ("end Source_Dirs.");
end Show_Source_Dirs;
+ ----------------
+ -- Suffix_For --
+ ----------------
+
+ function Suffix_For
+ (Language : Programming_Language;
+ Naming : Naming_Data) return Name_Id
+ is
+ Suffix : constant Variable_Value :=
+ Value_Of
+ (Index => Lang_Name_Ids (Language),
+ Src_Index => 0,
+ In_Array => Naming.Body_Suffix);
+ begin
+ -- If no suffix for this language is found in package Naming, use the
+ -- default.
+
+ if Suffix = Nil_Variable_Value then
+ Name_Len := 0;
+ Add_Str_To_Name_Buffer (Lang_Suffixes (Language).all);
+
+ -- Otherwise use the one specified
+
+ else
+ Get_Name_String (Suffix.Value);
+ end if;
+
+ Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
+ return Name_Find;
+ end Suffix_For;
+
end Prj.Nmsc;
diff --git a/gcc/ada/prj-nmsc.ads b/gcc/ada/prj-nmsc.ads
index 5d130714d93..9202ad33c40 100644
--- a/gcc/ada/prj-nmsc.ads
+++ b/gcc/ada/prj-nmsc.ads
@@ -24,8 +24,7 @@
-- --
------------------------------------------------------------------------------
--- Check the Naming Scheme of a project file, find the directories
--- and the source files.
+-- Check the Naming Scheme of a project file, find the source files.
private package Prj.Nmsc is
@@ -33,16 +32,31 @@ private package Prj.Nmsc is
-- procedures do (related to their names), rather than just an english
-- language summary of the implementation ???
+ procedure Other_Languages_Check
+ (Project : Project_Id;
+ Report_Error : Put_Line_Access);
+ -- Call Language_Independent_Check
+ --
+ -- Check the naming scheme for the supported languages (c, c++, ...) other
+ -- than Ada. Find the source files if any.
+ --
+ -- If Report_Error is null, use the standard error reporting mechanism
+ -- (Errout). Otherwise, report errors using Report_Error.
+
procedure Ada_Check
(Project : Project_Id;
Report_Error : Put_Line_Access;
- Trusted_Mode : Boolean);
- -- Call Language_Independent_Check.
- -- Check the naming scheme for Ada.
- -- Find the Ada source files if any.
+ Follow_Links : Boolean);
+ -- Call Language_Independent_Check
+ --
+ -- Check the naming scheme for Ada
+ --
+ -- Find the Ada source files if any
+ --
-- If Report_Error is null , use the standard error reporting mechanism
-- (Errout). Otherwise, report errors using Report_Error.
- -- If Trusted_Mode is True, it is assumed that the project doesn't contain
+ --
+ -- If Follow_Links is False, it is assumed that the project doesn't contain
-- any file duplicated through symbolic links (although the latter are
-- still valid if they point to a file which is outside of the project),
-- and that no directory has a name which is a valid source name.
@@ -50,9 +64,12 @@ private package Prj.Nmsc is
procedure Language_Independent_Check
(Project : Project_Id;
Report_Error : Put_Line_Access);
- -- Check the object directory and the source directories.
- -- Check the library attributes, including the library directory if any.
- -- Get the set of specification and implementation suffixes, if any.
+ -- Check the object directory and the source directories
+ --
+ -- Check the library attributes, including the library directory if any
+ --
+ -- Get the set of specification and implementation suffixes, if any
+ --
-- If Report_Error is null , use the standard error reporting mechanism
-- (Errout). Otherwise, report errors using Report_Error.
diff --git a/gcc/ada/prj-pars.adb b/gcc/ada/prj-pars.adb
index 19a560d6118..bf266880507 100644
--- a/gcc/ada/prj-pars.adb
+++ b/gcc/ada/prj-pars.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2001-2002 Free Software Foundation, Inc. --
+-- Copyright (C) 2001-2004 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- --
@@ -26,9 +26,10 @@
with Ada.Exceptions; use Ada.Exceptions;
-with Prj.Err; use Prj.Err;
+with Opt;
with Output; use Output;
with Prj.Com; use Prj.Com;
+with Prj.Err; use Prj.Err;
with Prj.Part;
with Prj.Proc;
with Prj.Tree; use Prj.Tree;
@@ -42,7 +43,8 @@ package body Prj.Pars is
procedure Parse
(Project : out Project_Id;
Project_File_Name : String;
- Packages_To_Check : String_List_Access := All_Packages)
+ Packages_To_Check : String_List_Access := All_Packages;
+ Process_Languages : Languages_Processed := Ada_Language)
is
Project_Tree : Project_Node_Id := Empty_Node;
The_Project : Project_Id := No_Project;
@@ -64,7 +66,9 @@ package body Prj.Pars is
(Project => The_Project,
Success => Success,
From_Project_Node => Project_Tree,
- Report_Error => null);
+ Report_Error => null,
+ Process_Languages => Process_Languages,
+ Follow_Links => Opt.Follow_Links);
Prj.Err.Finalize;
if not Success then
diff --git a/gcc/ada/prj-pars.ads b/gcc/ada/prj-pars.ads
index 4f157ef159e..be23e4bdc83 100644
--- a/gcc/ada/prj-pars.ads
+++ b/gcc/ada/prj-pars.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2000-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 2000-2004 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- --
@@ -36,7 +36,8 @@ package Prj.Pars is
procedure Parse
(Project : out Project_Id;
Project_File_Name : String;
- Packages_To_Check : String_List_Access := All_Packages);
+ Packages_To_Check : String_List_Access := All_Packages;
+ Process_Languages : Languages_Processed := Ada_Language);
-- Parse a project files and all its imported project files.
-- If parsing is successful, Project_Id is the project ID
-- of the main project file; otherwise, Project_Id is set
diff --git a/gcc/ada/prj-pp.adb b/gcc/ada/prj-pp.adb
index 965939db193..f9cceb5bc52 100644
--- a/gcc/ada/prj-pp.adb
+++ b/gcc/ada/prj-pp.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2001-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 2001-2004 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- --
@@ -454,6 +454,11 @@ package body Prj.PP is
pragma Debug (Indicate_Tested (N_Literal_String));
Output_String (String_Value_Of (Node));
+ if Source_Index_Of (Node) /= 0 then
+ Write_String (" at ");
+ Write_String (Source_Index_Of (Node)'Img);
+ end if;
+
when N_Attribute_Declaration =>
pragma Debug (Indicate_Tested (N_Attribute_Declaration));
Print (First_Comment_Before (Node), Indent);
@@ -464,6 +469,12 @@ package body Prj.PP is
if Associative_Array_Index_Of (Node) /= No_Name then
Write_String (" (");
Output_String (Associative_Array_Index_Of (Node));
+
+ if Source_Index_Of (Node) /= 0 then
+ Write_String (" at ");
+ Write_String (Source_Index_Of (Node)'Img);
+ end if;
+
Write_String (")");
end if;
diff --git a/gcc/ada/prj-proc.adb b/gcc/ada/prj-proc.adb
index 1258e244ee4..439645e4bb7 100644
--- a/gcc/ada/prj-proc.adb
+++ b/gcc/ada/prj-proc.adb
@@ -101,16 +101,22 @@ package body Prj.Proc is
-- recursively for all imported projects and a extended project, if any.
-- Then process the declarative items of the project.
- procedure Check (Project : in out Project_Id; Trusted_Mode : Boolean);
+ procedure Check
+ (Project : in out Project_Id;
+ Process_Languages : Languages_Processed;
+ Follow_Links : Boolean);
-- Set all projects to not checked, then call Recursive_Check for the
-- main project Project. Project is set to No_Project if errors occurred.
- -- See Prj.Nmsc.Ada_Check for information on Trusted_Mode.
+ -- See Prj.Nmsc.Ada_Check for information on Follow_Links.
- procedure Recursive_Check (Project : Project_Id; Trusted_Mode : Boolean);
+ procedure Recursive_Check
+ (Project : Project_Id;
+ Process_Languages : Languages_Processed;
+ Follow_Links : Boolean);
-- If Project is not marked as checked, mark it as checked, call
-- Check_Naming_Scheme for the project, then call itself for a
-- possible extended project and all the imported projects of Project.
- -- See Prj.Nmsc.Ada_Check for information on Trusted_Mode
+ -- See Prj.Nmsc.Ada_Check for information on Follow_Links
---------
-- Add --
@@ -176,7 +182,8 @@ package body Prj.Proc is
Kind => Single,
Location => No_Location,
Default => True,
- Value => Empty_String);
+ Value => Empty_String,
+ Index => 0);
-- List attributes have a default value of nil list
@@ -207,7 +214,10 @@ package body Prj.Proc is
-- Check --
-----------
- procedure Check (Project : in out Project_Id; Trusted_Mode : Boolean) is
+ procedure Check
+ (Project : in out Project_Id;
+ Process_Languages : Languages_Processed;
+ Follow_Links : Boolean) is
begin
-- Make sure that all projects are marked as not checked
@@ -215,7 +225,8 @@ package body Prj.Proc is
Projects.Table (Index).Checked := False;
end loop;
- Recursive_Check (Project, Trusted_Mode);
+ Recursive_Check (Project, Process_Languages, Follow_Links);
+
end Check;
----------------
@@ -265,6 +276,7 @@ package body Prj.Proc is
when Single =>
Add (Result.Value, String_Value_Of (The_Current_Term));
+ Result.Index := Source_Index_Of (The_Current_Term);
when List =>
@@ -285,6 +297,7 @@ package body Prj.Proc is
Last := String_Elements.Last;
String_Elements.Table (Last) :=
(Value => String_Value_Of (The_Current_Term),
+ Index => Source_Index_Of (The_Current_Term),
Display_Value => No_Name,
Location => Location_Of (The_Current_Term),
Flag => False,
@@ -332,7 +345,8 @@ package body Prj.Proc is
Display_Value => No_Name,
Location => Value.Location,
Flag => False,
- Next => Nil_String);
+ Next => Nil_String,
+ Index => Value.Index);
loop
-- Add the other element of the literal string list
@@ -360,7 +374,8 @@ package body Prj.Proc is
Display_Value => No_Name,
Location => Value.Location,
Flag => False,
- Next => Nil_String);
+ Next => Nil_String,
+ Index => Value.Index);
end loop;
end if;
@@ -550,7 +565,8 @@ package body Prj.Proc is
Kind => Single,
Location => No_Location,
Default => True,
- Value => Empty_String);
+ Value => Empty_String,
+ Index => 0);
end if;
end if;
end;
@@ -613,7 +629,8 @@ package body Prj.Proc is
Display_Value => No_Name,
Location => Location_Of (The_Current_Term),
Flag => False,
- Next => Nil_String);
+ Next => Nil_String,
+ Index => 0);
when List =>
@@ -643,7 +660,8 @@ package body Prj.Proc is
Location => Location_Of
(The_Current_Term),
Flag => False,
- Next => Nil_String);
+ Next => Nil_String,
+ Index => 0);
The_List :=
String_Elements.Table (The_List).Next;
end loop;
@@ -715,7 +733,8 @@ package body Prj.Proc is
Display_Value => No_Name,
Location => Location_Of (The_Current_Term),
Flag => False,
- Next => Nil_String);
+ Next => Nil_String,
+ Index => 0);
end case;
end;
@@ -817,7 +836,8 @@ package body Prj.Proc is
Success : out Boolean;
From_Project_Node : Project_Node_Id;
Report_Error : Put_Line_Access;
- Trusted_Mode : Boolean := False)
+ Process_Languages : Languages_Processed := Ada_Language;
+ Follow_Links : Boolean := True)
is
Obj_Dir : Name_Id;
Extending : Project_Id;
@@ -841,7 +861,7 @@ package body Prj.Proc is
Extended_By => No_Project);
if Project /= No_Project then
- Check (Project, Trusted_Mode);
+ Check (Project, Process_Languages, Follow_Links);
end if;
-- If main project is an extending all project, set the object
@@ -1571,6 +1591,7 @@ package body Prj.Proc is
Array_Elements.Table (The_Array_Element) :=
(Index => Index_Name,
+ Src_Index => Source_Index_Of (Current_Item),
Index_Case_Sensitive =>
not Case_Insensitive (Current_Item),
Value => New_Value,
@@ -1755,7 +1776,11 @@ package body Prj.Proc is
-- Recursive_Check --
---------------------
- procedure Recursive_Check (Project : Project_Id; Trusted_Mode : Boolean) is
+ procedure Recursive_Check
+ (Project : Project_Id;
+ Process_Languages : Languages_Processed;
+ Follow_Links : Boolean)
+ is
Data : Project_Data;
Imported_Project_List : Project_List := Empty_Project_List;
@@ -1776,7 +1801,7 @@ package body Prj.Proc is
-- Call itself for a possible extended project.
-- (if there is no extended project, then nothing happens).
- Recursive_Check (Data.Extends, Trusted_Mode);
+ Recursive_Check (Data.Extends, Process_Languages, Follow_Links);
-- Call itself for all imported projects
@@ -1784,7 +1809,7 @@ package body Prj.Proc is
while Imported_Project_List /= Empty_Project_List loop
Recursive_Check
(Project_Lists.Table (Imported_Project_List).Project,
- Trusted_Mode);
+ Process_Languages, Follow_Links);
Imported_Project_List :=
Project_Lists.Table (Imported_Project_List).Next;
end loop;
@@ -1795,7 +1820,13 @@ package body Prj.Proc is
Write_Line ("""");
end if;
- Prj.Nmsc.Ada_Check (Project, Error_Report, Trusted_Mode);
+ case Process_Languages is
+ when Ada_Language =>
+ Prj.Nmsc.Ada_Check (Project, Error_Report, Follow_Links);
+
+ when Other_Languages =>
+ Prj.Nmsc.Other_Languages_Check (Project, Error_Report);
+ end case;
end if;
end Recursive_Check;
diff --git a/gcc/ada/prj-proc.ads b/gcc/ada/prj-proc.ads
index 2d0cf449910..ca55a512a92 100644
--- a/gcc/ada/prj-proc.ads
+++ b/gcc/ada/prj-proc.ads
@@ -37,15 +37,17 @@ package Prj.Proc is
Success : out Boolean;
From_Project_Node : Project_Node_Id;
Report_Error : Put_Line_Access;
- Trusted_Mode : Boolean := False);
+ Process_Languages : Languages_Processed := Ada_Language;
+ Follow_Links : Boolean := True);
-- Process a project file tree into project file data structures.
-- If Report_Error is null, use the error reporting mechanism.
-- Otherwise, report errors using Report_Error.
--
- -- If Trusted_Mode is True, it is assumed that the project doesn't contain
+ -- If Follow_Links is False, it is assumed that the project doesn't contain
-- any file duplicated through symbolic links (although the latter are
-- still valid if they point to a file which is outside of the project),
-- and that no directory has a name which is a valid source name.
+ --
-- Process is a bit of a junk name, how about Process_Project_Tree???
end Prj.Proc;
diff --git a/gcc/ada/prj-strt.adb b/gcc/ada/prj-strt.adb
index 1d1d1a8cb5d..cc1bd83db80 100644
--- a/gcc/ada/prj-strt.adb
+++ b/gcc/ada/prj-strt.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2001-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 2001-2004 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- --
@@ -33,6 +33,7 @@ with Scans; use Scans;
with Snames;
with Table;
with Types; use Types;
+with Uintp; use Uintp;
package body Prj.Strt is
@@ -115,7 +116,8 @@ package body Prj.Strt is
(Term : out Project_Node_Id;
Expr_Kind : in out Variable_Kind;
Current_Project : Project_Node_Id;
- Current_Package : Project_Node_Id);
+ Current_Package : Project_Node_Id;
+ Optional_Index : Boolean);
-- Recursive procedure to parse one term or several terms concatenated
-- using "&".
@@ -454,7 +456,8 @@ package body Prj.Strt is
procedure Parse_Expression
(Expression : out Project_Node_Id;
Current_Project : Project_Node_Id;
- Current_Package : Project_Node_Id)
+ Current_Package : Project_Node_Id;
+ Optional_Index : Boolean)
is
First_Term : Project_Node_Id := Empty_Node;
Expression_Kind : Variable_Kind := Undefined;
@@ -470,7 +473,8 @@ package body Prj.Strt is
Terms (Term => First_Term,
Expr_Kind => Expression_Kind,
Current_Project => Current_Project,
- Current_Package => Current_Package);
+ Current_Package => Current_Package,
+ Optional_Index => Optional_Index);
-- Set the first term and the expression kind
@@ -1077,7 +1081,8 @@ package body Prj.Strt is
(Term : out Project_Node_Id;
Expr_Kind : in out Variable_Kind;
Current_Project : Project_Node_Id;
- Current_Package : Project_Node_Id)
+ Current_Package : Project_Node_Id;
+ Optional_Index : Boolean)
is
Next_Term : Project_Node_Id := Empty_Node;
Term_Id : Project_Node_Id := Empty_Node;
@@ -1143,7 +1148,8 @@ package body Prj.Strt is
Current_Location := Token_Ptr;
Parse_Expression (Expression => Next_Expression,
Current_Project => Current_Project,
- Current_Package => Current_Package);
+ Current_Package => Current_Package,
+ Optional_Index => Optional_Index);
-- The expression kind is String list, report an error
@@ -1199,6 +1205,39 @@ package body Prj.Strt is
Scan;
+ -- Check for possible index expression
+
+ if Token = Tok_At then
+ if not Optional_Index then
+ Error_Msg ("index not allowed here", Token_Ptr);
+ Scan;
+
+ if Token = Tok_Integer_Literal then
+ Scan;
+ end if;
+
+ -- Set the index value
+
+ else
+ Scan;
+ Expect (Tok_Integer_Literal, "integer literal");
+
+ if Token = Tok_Integer_Literal then
+ declare
+ Index : constant Int := UI_To_Int (Int_Literal_Value);
+ begin
+ if Index = 0 then
+ Error_Msg ("index cannot be zero", Token_Ptr);
+ else
+ Set_Source_Index_Of (Term_Id, To => Index);
+ end if;
+ end;
+
+ Scan;
+ end if;
+ end if;
+ end if;
+
when Tok_Identifier =>
Current_Location := Token_Ptr;
@@ -1292,7 +1331,8 @@ package body Prj.Strt is
Terms (Term => Next_Term,
Expr_Kind => Expr_Kind,
Current_Project => Current_Project,
- Current_Package => Current_Package);
+ Current_Package => Current_Package,
+ Optional_Index => Optional_Index);
-- And link the next term to this term
diff --git a/gcc/ada/prj-strt.ads b/gcc/ada/prj-strt.ads
index 69105690b51..633b022e8f5 100644
--- a/gcc/ada/prj-strt.ads
+++ b/gcc/ada/prj-strt.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2001-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 2001-2004 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- --
@@ -70,7 +70,8 @@ private package Prj.Strt is
procedure Parse_Expression
(Expression : out Project_Node_Id;
Current_Project : Project_Node_Id;
- Current_Package : Project_Node_Id);
+ Current_Package : Project_Node_Id;
+ Optional_Index : Boolean);
-- Parse a simple string expression or a string list expression.
-- Current_Project is the node of the project file being parsed.
-- Current_Package is the node of the package being parsed,
diff --git a/gcc/ada/prj-tree.adb b/gcc/ada/prj-tree.adb
index e8603c67bfb..2a67b57c5b1 100644
--- a/gcc/ada/prj-tree.adb
+++ b/gcc/ada/prj-tree.adb
@@ -111,6 +111,7 @@ package body Prj.Tree is
Packages => Empty_Node,
Pkg_Id => Empty_Package,
Name => No_Name,
+ Src_Index => 0,
Path_Name => No_Name,
Value => No_Name,
Field1 => Empty_Node,
@@ -157,6 +158,7 @@ package body Prj.Tree is
Packages => Empty_Node,
Pkg_Id => Empty_Package,
Name => No_Name,
+ Src_Index => 0,
Path_Name => No_Name,
Value => Comments.Table (J).Value,
Field1 => Empty_Node,
@@ -204,7 +206,6 @@ package body Prj.Tree is
Comments.Set_Last (0);
end Add_Comments;
-
--------------------------------
-- Associative_Array_Index_Of --
--------------------------------
@@ -310,6 +311,7 @@ package body Prj.Tree is
Packages => Empty_Node,
Pkg_Id => Empty_Package,
Name => No_Name,
+ Src_Index => 0,
Path_Name => No_Name,
Value => No_Name,
Field1 => Empty_Node,
@@ -379,6 +381,7 @@ package body Prj.Tree is
Packages => Empty_Node,
Pkg_Id => Empty_Package,
Name => No_Name,
+ Src_Index => 0,
Path_Name => No_Name,
Value => No_Name,
Field1 => Empty_Node,
@@ -411,6 +414,7 @@ package body Prj.Tree is
Packages => Empty_Node,
Pkg_Id => Empty_Package,
Name => No_Name,
+ Src_Index => 0,
Path_Name => No_Name,
Value => No_Name,
Field1 => Empty_Node,
@@ -441,6 +445,7 @@ package body Prj.Tree is
Packages => Empty_Node,
Pkg_Id => Empty_Package,
Name => No_Name,
+ Src_Index => 0,
Path_Name => No_Name,
Value => Comments.Table (J).Value,
Field1 => Empty_Node,
@@ -2323,6 +2328,24 @@ package body Prj.Tree is
Project_Nodes.Table (Node).Field1 := To;
end Set_Project_Of_Renamed_Package_Of;
+ -------------------------
+ -- Set_Source_Index_Of --
+ -------------------------
+
+ procedure Set_Source_Index_Of
+ (Node : Project_Node_Id;
+ To : Int)
+ is
+ begin
+ pragma Assert
+ (Node /= Empty_Node
+ and then
+ (Project_Nodes.Table (Node).Kind = N_Literal_String
+ or else
+ Project_Nodes.Table (Node).Kind = N_Attribute_Declaration));
+ Project_Nodes.Table (Node).Src_Index := To;
+ end Set_Source_Index_Of;
+
------------------------
-- Set_String_Type_Of --
------------------------
@@ -2338,8 +2361,8 @@ package body Prj.Tree is
(Project_Nodes.Table (Node).Kind = N_Variable_Reference
or else
Project_Nodes.Table (Node).Kind = N_Typed_Variable_Declaration)
- and then
- Project_Nodes.Table (To).Kind = N_String_Type_Declaration);
+ and then
+ Project_Nodes.Table (To).Kind = N_String_Type_Declaration);
if Project_Nodes.Table (Node).Kind = N_Variable_Reference then
Project_Nodes.Table (Node).Field3 := To;
@@ -2368,13 +2391,26 @@ package body Prj.Tree is
Project_Nodes.Table (Node).Value := To;
end Set_String_Value_Of;
+ ---------------------
+ -- Source_Index_Of --
+ ---------------------
+
+ function Source_Index_Of (Node : Project_Node_Id) return Int is
+ begin
+ pragma Assert
+ (Node /= Empty_Node
+ and then
+ (Project_Nodes.Table (Node).Kind = N_Literal_String
+ or else
+ Project_Nodes.Table (Node).Kind = N_Attribute_Declaration));
+ return Project_Nodes.Table (Node).Src_Index;
+ end Source_Index_Of;
+
--------------------
-- String_Type_Of --
--------------------
- function String_Type_Of
- (Node : Project_Node_Id) return Project_Node_Id
- is
+ function String_Type_Of (Node : Project_Node_Id) return Project_Node_Id is
begin
pragma Assert
(Node /= Empty_Node
@@ -2450,5 +2486,4 @@ package body Prj.Tree is
return Unkept_Comments;
end There_Are_Unkept_Comments;
-
end Prj.Tree;
diff --git a/gcc/ada/prj-tree.ads b/gcc/ada/prj-tree.ads
index 7192fcee796..c376d3beee2 100644
--- a/gcc/ada/prj-tree.ads
+++ b/gcc/ada/prj-tree.ads
@@ -269,6 +269,10 @@ package Prj.Tree is
pragma Inline (String_Value_Of);
-- Only valid for N_With_Clause, N_Literal_String nodes or N_Comment
+ function Source_Index_Of (Node : Project_Node_Id) return Int;
+ pragma Inline (Source_Index_Of);
+ -- Only valid for N_Literal_String and N_Attribute_Declaration nodes
+
function First_With_Clause_Of
(Node : Project_Node_Id) return Project_Node_Id;
pragma Inline (First_With_Clause_Of);
@@ -694,6 +698,11 @@ package Prj.Tree is
To : Project_Node_Id);
pragma Inline (Set_Package_Node_Of);
+ procedure Set_Source_Index_Of
+ (Node : Project_Node_Id;
+ To : Int);
+ pragma Inline (Set_Source_Index_Of);
+
procedure Set_String_Type_Of
(Node : Project_Node_Id;
To : Project_Node_Id);
@@ -773,6 +782,10 @@ package Prj.Tree is
Name : Name_Id := No_Name;
-- See below for what Project_Node_Kind it is used
+ Src_Index : Int := 0;
+ -- Index of a unit in a multi-unit source.
+ -- Onli for some N_Attribute_Declaration and N_Literal_String.
+
Path_Name : Name_Id := No_Name;
-- See below for what Project_Node_Kind it is used
diff --git a/gcc/ada/prj-util.adb b/gcc/ada/prj-util.adb
index 15f893a7ac8..9de974760dd 100644
--- a/gcc/ada/prj-util.adb
+++ b/gcc/ada/prj-util.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2001-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 2001-2004 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- --
@@ -74,7 +74,10 @@ package body Prj.Util is
-------------------
function Executable_Of
- (Project : Project_Id; Main : Name_Id) return Name_Id
+ (Project : Project_Id;
+ Main : Name_Id;
+ Index : Int;
+ Ada_Main : Boolean := True) return Name_Id
is
pragma Assert (Project /= No_Project);
@@ -89,12 +92,14 @@ package body Prj.Util is
Executable : Variable_Value :=
Prj.Util.Value_Of
(Name => Main,
+ Index => Index,
Attribute_Or_Array_Name => Name_Executable,
In_Package => Builder_Package);
Executable_Suffix : constant Variable_Value :=
Prj.Util.Value_Of
(Name => Main,
+ Index => 0,
Attribute_Or_Array_Name =>
Name_Executable_Suffix,
In_Package => Builder_Package);
@@ -111,7 +116,7 @@ package body Prj.Util is
begin
if Builder_Package /= No_Package then
- if Executable = Nil_Variable_Value then
+ if Executable = Nil_Variable_Value and Ada_Main then
Get_Name_String (Main);
-- Try as index the name minus the implementation suffix or minus
@@ -156,6 +161,7 @@ package body Prj.Util is
Executable :=
Prj.Util.Value_Of
(Name => Name_Find,
+ Index => 0,
Attribute_Or_Array_Name => Name_Executable,
In_Package => Builder_Package);
end if;
@@ -212,7 +218,7 @@ package body Prj.Util is
-- otherwise remove any suffix ('.' followed by other characters), if
-- there is one.
- if Name_Len > Body_Append'Length
+ if Ada_Main and then Name_Len > Body_Append'Length
and then Name_Buffer (Name_Len - Body_Append'Length + 1 .. Name_Len) =
Body_Append
then
@@ -220,7 +226,7 @@ package body Prj.Util is
Name_Len := Name_Len - Body_Append'Length;
- elsif Name_Len > Spec_Append'Length
+ elsif Ada_Main and then Name_Len > Spec_Append'Length
and then Name_Buffer (Name_Len - Spec_Append'Length + 1 .. Name_Len) =
Spec_Append
then
@@ -379,8 +385,7 @@ package body Prj.Util is
function Value_Of
(Variable : Variable_Value;
- Default : String)
- return String
+ Default : String) return String
is
begin
if Variable.Kind /= Single
@@ -394,9 +399,8 @@ package body Prj.Util is
end Value_Of;
function Value_Of
- (Index : Name_Id;
- In_Array : Array_Element_Id)
- return Name_Id
+ (Index : Name_Id;
+ In_Array : Array_Element_Id) return Name_Id
is
Current : Array_Element_Id := In_Array;
Element : Array_Element;
@@ -431,9 +435,9 @@ package body Prj.Util is
end Value_Of;
function Value_Of
- (Index : Name_Id;
- In_Array : Array_Element_Id)
- return Variable_Value
+ (Index : Name_Id;
+ Src_Index : Int := 0;
+ In_Array : Array_Element_Id) return Variable_Value
is
Current : Array_Element_Id := In_Array;
Element : Array_Element;
@@ -455,7 +459,9 @@ package body Prj.Util is
while Current /= No_Array_Element loop
Element := Array_Elements.Table (Current);
- if Real_Index = Element.Index then
+ if Real_Index = Element.Index and then
+ Src_Index = Element.Src_Index
+ then
return Element.Value;
else
Current := Element.Next;
@@ -467,9 +473,9 @@ package body Prj.Util is
function Value_Of
(Name : Name_Id;
+ Index : Int := 0;
Attribute_Or_Array_Name : Name_Id;
- In_Package : Package_Id)
- return Variable_Value
+ In_Package : Package_Id) return Variable_Value
is
The_Array : Array_Element_Id;
The_Attribute : Variable_Value := Nil_Variable_Value;
@@ -485,8 +491,9 @@ package body Prj.Util is
In_Arrays => Packages.Table (In_Package).Decl.Arrays);
The_Attribute :=
Value_Of
- (Index => Name,
- In_Array => The_Array);
+ (Index => Name,
+ Src_Index => Index,
+ In_Array => The_Array);
-- If there is no array element, look for a variable
@@ -504,8 +511,7 @@ package body Prj.Util is
function Value_Of
(Index : Name_Id;
In_Array : Name_Id;
- In_Arrays : Array_Id)
- return Name_Id
+ In_Arrays : Array_Id) return Name_Id
is
Current : Array_Id := In_Arrays;
The_Array : Array_Data;
@@ -525,8 +531,7 @@ package body Prj.Util is
function Value_Of
(Name : Name_Id;
- In_Arrays : Array_Id)
- return Array_Element_Id
+ In_Arrays : Array_Id) return Array_Element_Id
is
Current : Array_Id := In_Arrays;
The_Array : Array_Data;
@@ -547,8 +552,7 @@ package body Prj.Util is
function Value_Of
(Name : Name_Id;
- In_Packages : Package_Id)
- return Package_Id
+ In_Packages : Package_Id) return Package_Id
is
Current : Package_Id := In_Packages;
The_Package : Package_Element;
@@ -566,8 +570,7 @@ package body Prj.Util is
function Value_Of
(Variable_Name : Name_Id;
- In_Variables : Variable_Id)
- return Variable_Value
+ In_Variables : Variable_Id) return Variable_Value
is
Current : Variable_Id := In_Variables;
The_Variable : Variable;
diff --git a/gcc/ada/prj-util.ads b/gcc/ada/prj-util.ads
index 57067e225f2..7373a640d59 100644
--- a/gcc/ada/prj-util.ads
+++ b/gcc/ada/prj-util.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2001-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 2001-2004 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- --
@@ -33,7 +33,10 @@ with GNAT.OS_Lib; use GNAT.OS_Lib;
package Prj.Util is
function Executable_Of
- (Project : Project_Id; Main : Name_Id) return Name_Id;
+ (Project : Project_Id;
+ Main : Name_Id;
+ Index : Int;
+ Ada_Main : Boolean := True) return Name_Id;
-- Return the value of the attribute Builder'Executable for file Main in
-- the project Project, if it exists. If there is no attribute Executable
-- for Main, remove the suffix from Main; then, if the attribute
@@ -42,15 +45,13 @@ package Prj.Util is
function Value_Of
(Variable : Variable_Value;
- Default : String)
- return String;
+ Default : String) return String;
-- Get the value of a single string variable. If Variable is
-- Nil_Variable_Value, is a string list or is defaulted, return Default.
function Value_Of
(Index : Name_Id;
- In_Array : Array_Element_Id)
- return Name_Id;
+ In_Array : Array_Element_Id) return Name_Id;
-- Get a single string array component. Returns No_Name if there is no
-- component Index, if In_Array is null, or if the component is a String
-- list. Depending on the attribute (only attributes may be associative
@@ -59,9 +60,9 @@ package Prj.Util is
-- associative array.
function Value_Of
- (Index : Name_Id;
- In_Array : Array_Element_Id)
- return Variable_Value;
+ (Index : Name_Id;
+ Src_Index : Int := 0;
+ In_Array : Array_Element_Id) return Variable_Value;
-- Get a string array component (single String or String list).
-- Returns Nil_Variable_Value if there is no component Index
-- or if In_Array is null.
@@ -73,9 +74,9 @@ package Prj.Util is
function Value_Of
(Name : Name_Id;
+ Index : Int := 0;
Attribute_Or_Array_Name : Name_Id;
- In_Package : Package_Id)
- return Variable_Value;
+ In_Package : Package_Id) return Variable_Value;
-- In a specific package,
-- - if there exists an array Attribute_Or_Array_Name with an index
-- Name, returns the corresponding component (depending on the
@@ -89,32 +90,28 @@ package Prj.Util is
function Value_Of
(Index : Name_Id;
In_Array : Name_Id;
- In_Arrays : Array_Id)
- return Name_Id;
+ In_Arrays : Array_Id) return Name_Id;
-- Get a string array component in an array of an array list.
-- Returns No_Name if there is no component Index, if In_Arrays is null, if
-- In_Array is not found in In_Arrays or if the component is a String list.
function Value_Of
(Name : Name_Id;
- In_Arrays : Array_Id)
- return Array_Element_Id;
+ In_Arrays : Array_Id) return Array_Element_Id;
-- Returns a specified array in an array list. Returns No_Array_Element
-- if In_Arrays is null or if Name is not the name of an array in
-- In_Arrays. The caller must ensure that Name is in lower case.
function Value_Of
(Name : Name_Id;
- In_Packages : Package_Id)
- return Package_Id;
+ In_Packages : Package_Id) return Package_Id;
-- Returns a specified package in a package list. Returns No_Package
-- if In_Packages is null or if Name is not the name of a package in
-- Package_List. The caller must ensure that Name is in lower case.
function Value_Of
(Variable_Name : Name_Id;
- In_Variables : Variable_Id)
- return Variable_Value;
+ In_Variables : Variable_Id) return Variable_Value;
-- Returns a specified variable in a variable list. Returns null if
-- In_Variables is null or if Variable_Name is not the name of a
-- variable in In_Variables. Caller must ensure that Name is lower case.
diff --git a/gcc/ada/prj.adb b/gcc/ada/prj.adb
index 0f09236fd8f..55523435f4f 100644
--- a/gcc/ada/prj.adb
+++ b/gcc/ada/prj.adb
@@ -34,6 +34,7 @@ with Prj.Env;
with Prj.Err; use Prj.Err;
with Scans; use Scans;
with Snames; use Snames;
+with Uintp; use Uintp;
with GNAT.OS_Lib; use GNAT.OS_Lib;
@@ -41,8 +42,6 @@ package body Prj is
The_Empty_String : Name_Id;
- Ada_Language : constant Name_Id := Name_Ada;
-
subtype Known_Casing is Casing_Type range All_Upper_Case .. Mixed_Case;
The_Casing_Images : constant array (Known_Casing) of String_Access :=
@@ -74,7 +73,9 @@ package body Prj is
Implementation_Exceptions => No_Array_Element);
Project_Empty : constant Project_Data :=
- (First_Referred_By => No_Project,
+ (Languages => No_Languages,
+ Impl_Suffixes => No_Impl_Suffixes,
+ First_Referred_By => No_Project,
Name => No_Name,
Path_Name => No_Name,
Virtual => False,
@@ -99,6 +100,11 @@ package body Prj is
Symbol_Data => No_Symbols,
Sources_Present => True,
Sources => Nil_String,
+ First_Other_Source => No_Other_Source,
+ Last_Other_Source => No_Other_Source,
+ Imported_Directories_Switches => null,
+ Include_Path => null,
+ Include_Data_Set => False,
Source_Dirs => Nil_String,
Known_Order_Of_Source_Dirs => True,
Object_Directory => No_Name,
@@ -235,6 +241,7 @@ package body Prj is
begin
if not Initialized then
Initialized := True;
+ Uintp.Initialize;
Name_Len := 0;
The_Empty_String := Name_Find;
Empty_Name := The_Empty_String;
@@ -247,11 +254,21 @@ package body Prj is
Name_Len := 1;
Name_Buffer (1) := '/';
Slash := Name_Find;
+
+ for Lang in Programming_Language loop
+ Name_Len := Lang_Names (Lang)'Length;
+ Name_Buffer (1 .. Name_Len) := Lang_Names (Lang).all;
+ Lang_Name_Ids (Lang) := Name_Find;
+ Name_Len := Lang_Suffixes (Lang)'Length;
+ Name_Buffer (1 .. Name_Len) := Lang_Suffixes (Lang).all;
+ Lang_Suffix_Ids (Lang) := Name_Find;
+ end loop;
+
Std_Naming_Data.Current_Spec_Suffix := Default_Ada_Spec_Suffix;
Std_Naming_Data.Current_Body_Suffix := Default_Ada_Body_Suffix;
Std_Naming_Data.Separate_Suffix := Default_Ada_Body_Suffix;
Register_Default_Naming_Scheme
- (Language => Ada_Language,
+ (Language => Name_Ada,
Default_Spec_Suffix => Default_Ada_Spec_Suffix,
Default_Body_Suffix => Default_Ada_Body_Suffix);
Prj.Env.Initialize;
@@ -306,13 +323,15 @@ package body Prj is
if not Found then
Element :=
- (Index => Lang,
+ (Index => Lang,
+ Src_Index => 0,
Index_Case_Sensitive => False,
Value => (Project => No_Project,
Kind => Single,
Location => No_Location,
Default => False,
- Value => Default_Spec_Suffix),
+ Value => Default_Spec_Suffix,
+ Index => 0),
Next => Std_Naming_Data.Spec_Suffix);
Array_Elements.Increment_Last;
Array_Elements.Table (Array_Elements.Last) := Element;
@@ -342,13 +361,15 @@ package body Prj is
if not Found then
Element :=
- (Index => Lang,
+ (Index => Lang,
+ Src_Index => 0,
Index_Case_Sensitive => False,
Value => (Project => No_Project,
Kind => Single,
Location => No_Location,
Default => False,
- Value => Default_Body_Suffix),
+ Value => Default_Body_Suffix,
+ Index => 0),
Next => Std_Naming_Data.Body_Suffix);
Array_Elements.Increment_Last;
Array_Elements.Table (Array_Elements.Last) := Element;
diff --git a/gcc/ada/prj.ads b/gcc/ada/prj.ads
index 3f9033c7b3c..9d82b5ff841 100644
--- a/gcc/ada/prj.ads
+++ b/gcc/ada/prj.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2001-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 2001-2004 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- --
@@ -67,6 +67,103 @@ package Prj is
Slash : Name_Id;
-- "/", used as the path of locally removed files
+ type Languages_Processed is (Ada_Language, Other_Languages);
+ -- To specify how to process project files
+
+ type Programming_Language is
+ (Lang_Ada, Lang_C, Lang_C_Plus_Plus);
+ -- The list of language supported
+
+ subtype Other_Programming_Language is
+ Programming_Language range Lang_C .. Programming_Language'Last;
+ type Languages_In_Project is array (Programming_Language) of Boolean;
+ No_Languages : constant Languages_In_Project := (others => False);
+
+ type Impl_Suffix_Array is array (Programming_Language) of Name_Id;
+ No_Impl_Suffixes : constant Impl_Suffix_Array := (others => No_Name);
+
+ Lang_Ada_Name : aliased String := "ada";
+ Lang_C_Name : aliased String := "c";
+ Lang_C_Plus_Plus_Name : aliased String := "c++";
+ Lang_Names : constant array (Programming_Language) of String_Access :=
+ (Lang_Ada => Lang_Ada_Name 'Access,
+ Lang_C => Lang_C_Name 'Access,
+ Lang_C_Plus_Plus => Lang_C_Plus_Plus_Name'Access);
+ -- Names of the supported programming languages, to be used after switch
+ -- -x when using a GCC compiler.
+
+ Lang_Name_Ids : array (Programming_Language) of Name_Id;
+ -- Initialized by Prj.Initialize
+
+ Lang_Ada_Display_Name : aliased String := "Ada";
+ Lang_C_Display_Name : aliased String := "C";
+ Lang_C_Plus_Plus_Display_Name : aliased String := "C++";
+ Lang_Display_Names :
+ constant array (Programming_Language) of String_Access :=
+ (Lang_Ada => Lang_Ada_Display_Name 'Access,
+ Lang_C => Lang_C_Display_Name 'Access,
+ Lang_C_Plus_Plus => Lang_C_Plus_Plus_Display_Name'Access);
+ -- Names of the supported programming languages, to be used for display
+ -- purposes.
+
+ Ada_Impl_Suffix : aliased String := ".adb";
+ C_Impl_Suffix : aliased String := ".c";
+ C_Plus_Plus_Impl_Suffix : aliased String := ".cc";
+ Lang_Suffixes : constant array (Programming_Language) of String_Access :=
+ (Lang_Ada => Ada_Impl_Suffix 'Access,
+ Lang_C => C_Impl_Suffix 'Access,
+ Lang_C_Plus_Plus => C_Plus_Plus_Impl_Suffix'Access);
+ -- Default extension of the sources of the different languages.
+
+ Lang_Suffix_Ids : array (Programming_Language) of Name_Id;
+ -- Initialized by Prj.Initialize
+
+ Gnatmake_String : aliased String := "gnatmake";
+ Gcc_String : aliased String := "gcc";
+ G_Plus_Plus_String : aliased String := "g++";
+ Default_Compiler_Names :
+ constant array (Programming_Language) of String_Access :=
+ (Lang_Ada => Gnatmake_String 'Access,
+ Lang_C => Gcc_String 'Access,
+ Lang_C_Plus_Plus => G_Plus_Plus_String'Access);
+ -- Default names of the compilers for the supported languages.
+ -- Used when no IDE'Compiler_Command is specified for a language.
+ -- For Ada, specify the gnatmake executable.
+
+ Ada_Args_Strings : aliased String := "";
+ C_Args_String : aliased String := "c";
+ C_Plus_Plus_Args_String : aliased String := "xx";
+ Lang_Args : constant array (Programming_Language) of String_Access :=
+ (Lang_Ada => Ada_Args_Strings 'Access,
+ Lang_C => C_Args_String 'Access,
+ Lang_C_Plus_Plus => C_Plus_Plus_Args_String'Access);
+
+ type Other_Source_Id is new Nat;
+ No_Other_Source : constant Other_Source_Id := 0;
+ type Other_Source is record
+ Language : Programming_Language; -- language of the source
+ File_Name : Name_Id; -- source file simple name
+ Path_Name : Name_Id; -- source full path name
+ Source_TS : Time_Stamp_Type; -- source file time stamp
+ Object_Name : Name_Id; -- object file simple name
+ Object_Path : Name_Id; -- object full path name
+ Object_TS : Time_Stamp_Type; -- object file time stamp
+ Dep_Name : Name_Id; -- dependency file simple name
+ Dep_Path : Name_Id; -- dependency full path name
+ Dep_TS : Time_Stamp_Type; -- dependency file time stamp
+ Naming_Exception : Boolean := False; -- True if a naming exception
+ Next : Other_Source_Id := No_Other_Source;
+ end record;
+
+ package Other_Sources is new Table.Table
+ (Table_Component_Type => Other_Source,
+ Table_Index_Type => Other_Source_Id,
+ Table_Low_Bound => 1,
+ Table_Initial => 200,
+ Table_Increment => 100,
+ Table_Name => "Prj.Other_Sources");
+ -- The table for sources of languages other than Ada
+
type Verbosity is (Default, Medium, High);
-- Verbosity when parsing GNAT Project Files
-- Default is default (very quiet, if no errors).
@@ -100,6 +197,7 @@ package Prj is
Nil_String : constant String_List_Id := 0;
type String_Element is record
Value : Name_Id := No_Name;
+ Index : Int := 0;
Display_Value : Name_Id := No_Name;
Location : Source_Ptr := No_Location;
Flag : Boolean := False;
@@ -136,6 +234,7 @@ package Prj is
Values : String_List_Id := Nil_String;
when Single =>
Value : Name_Id := No_Name;
+ Index : Int := 0;
end case;
end record;
-- Values for variables and array elements.
@@ -170,6 +269,7 @@ package Prj is
No_Array_Element : constant Array_Element_Id := 0;
type Array_Element is record
Index : Name_Id;
+ Src_Index : Int := 0;
Index_Case_Sensitive : Boolean := True;
Value : Variable_Value;
Next : Array_Element_Id := No_Array_Element;
@@ -347,6 +447,12 @@ package Prj is
-- The following record describes a project file representation
type Project_Data is record
+ Languages : Languages_In_Project := No_Languages;
+ -- Indicate the different languages of the source of this project
+
+ Impl_Suffixes : Impl_Suffix_Array := No_Impl_Suffixes;
+ -- The source suffixes of the different languages other than Ada
+
First_Referred_By : Project_Id := No_Project;
-- The project, if any, that was the first to be known
-- as importing or extending this project.
@@ -447,6 +553,22 @@ package Prj is
-- The list of all the source file names.
-- Set by Prj.Nmsc.Check_Naming_Scheme.
+ First_Other_Source : Other_Source_Id := No_Other_Source;
+ Last_Other_Source : Other_Source_Id := No_Other_Source;
+ -- Head and tail of the list of sources of languages other than Ada
+
+ Imported_Directories_Switches : Argument_List_Access := null;
+ -- List of the -I switches to be used when compiling sources of
+ -- languages other than Ada.
+
+ Include_Path : String_Access := null;
+ -- Value to be used as CPATH, when using a GCC, instead of a list of
+ -- -I switches.
+
+ Include_Data_Set : Boolean := False;
+ -- Set to True when Imported_Directories_Switches or Include_Path are
+ -- set.
+
Source_Dirs : String_List_Id := Nil_String;
-- The list of all the source directories.
-- Set by Prj.Nmsc.Check_Naming_Scheme.
diff --git a/gcc/ada/raise.c b/gcc/ada/raise.c
index 9a965ef1515..2d7c61a057d 100644
--- a/gcc/ada/raise.c
+++ b/gcc/ada/raise.c
@@ -152,7 +152,7 @@ db_accepted_codes (void)
if (accepted_codes == -1)
{
- char * db_env = getenv ("EH_DEBUG");
+ char * db_env = (char *) getenv ("EH_DEBUG");
accepted_codes = db_env ? (atoi (db_env) | DB_ERR) : 0;
/* Arranged for ERR stuff to always be visible when the variable
@@ -671,7 +671,7 @@ db_action_for (action_descriptor *action, _Unwind_Context *uw_context)
{
case unknown:
db (DB_ACTIONS, "lpad @ 0x%x, record @ 0x%x\n",
- ip, action->landing_pad, action->table_entry);
+ action->landing_pad, action->table_entry);
break;
case nothing:
diff --git a/gcc/ada/restrict.adb b/gcc/ada/restrict.adb
index 4e7222701ee..e9a4a4be749 100644
--- a/gcc/ada/restrict.adb
+++ b/gcc/ada/restrict.adb
@@ -368,7 +368,7 @@ package body Restrict is
and then Restrictions.Set (No_Task_Allocators)
and then Restrictions.Set (No_Dynamic_Priorities)
and then Restrictions.Set (No_Terminate_Alternatives)
- and then Restrictions.Set (No_Dynamic_Interrupts)
+ and then Restrictions.Set (No_Dynamic_Attachment)
and then Restrictions.Set (No_Protected_Type_Allocators)
and then Restrictions.Set (No_Local_Protected_Objects)
and then Restrictions.Set (No_Requeue_Statements)
@@ -442,7 +442,7 @@ package body Restrict is
procedure Set_Ravenscar (N : Node_Id) is
begin
Set_Restricted_Profile (N);
- Set_Restriction (Boolean_Entry_Barriers, N);
+ Set_Restriction (Simple_Barriers, N);
Set_Restriction (No_Select_Statements, N);
Set_Restriction (No_Calendar, N);
Set_Restriction (No_Entry_Queue, N);
@@ -468,7 +468,7 @@ package body Restrict is
Set_Restriction (No_Task_Allocators, N);
Set_Restriction (No_Dynamic_Priorities, N);
Set_Restriction (No_Terminate_Alternatives, N);
- Set_Restriction (No_Dynamic_Interrupts, N);
+ Set_Restriction (No_Dynamic_Attachment, N);
Set_Restriction (No_Protected_Type_Allocators, N);
Set_Restriction (No_Local_Protected_Objects, N);
Set_Restriction (No_Requeue_Statements, N);
diff --git a/gcc/ada/restrict.ads b/gcc/ada/restrict.ads
index 0d2f72f350d..9029620b1f3 100644
--- a/gcc/ada/restrict.ads
+++ b/gcc/ada/restrict.ads
@@ -104,9 +104,9 @@ package Restrict is
-- (which is why this restriction itself is excluded from the list).
Implementation_Restriction : array (All_Restrictions) of Boolean :=
- (Boolean_Entry_Barriers => True,
+ (Simple_Barriers => True,
No_Calendar => True,
- No_Dynamic_Interrupts => True,
+ No_Dynamic_Attachment => True,
No_Enumeration_Maps => True,
No_Entry_Calls_In_Elaboration_Code => True,
No_Entry_Queue => True,
diff --git a/gcc/ada/rtsfind.adb b/gcc/ada/rtsfind.adb
index c0249de7875..b43da3db603 100644
--- a/gcc/ada/rtsfind.adb
+++ b/gcc/ada/rtsfind.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2003, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004, 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- --
@@ -174,6 +174,23 @@ package body Rtsfind is
-- used if you are sure that the message comes directly or indirectly from
-- a call to the RTE function.
+ ------------------------
+ -- Entity_Not_Defined --
+ ------------------------
+
+ procedure Entity_Not_Defined (Id : RE_Id) is
+ begin
+ if No_Run_Time_Mode then
+ RTE_Error_Msg ("|construct not allowed in no run time mode");
+ elsif Configurable_Run_Time_Mode then
+ RTE_Error_Msg ("|construct not allowed in this configuration>");
+ else
+ RTE_Error_Msg ("run-time configuration error");
+ end if;
+
+ Output_Entity_Name (Id, "not defined");
+ end Entity_Not_Defined;
+
-------------------
-- Get_Unit_Name --
-------------------
@@ -403,23 +420,6 @@ package body Rtsfind is
Chars (Sel) in Text_IO_Package_Name;
end Is_Text_IO_Kludge_Unit;
- ------------------------
- -- Entity_Not_Defined --
- ------------------------
-
- procedure Entity_Not_Defined (Id : RE_Id) is
- begin
- if No_Run_Time_Mode then
- RTE_Error_Msg ("|construct not allowed in no run time mode");
- elsif Configurable_Run_Time_Mode then
- RTE_Error_Msg ("|construct not allowed in this configuration>");
- else
- RTE_Error_Msg ("run-time configuration error");
- end if;
-
- Output_Entity_Name (Id, "not defined");
- end Entity_Not_Defined;
-
---------------
-- Load_Fail --
---------------
@@ -786,9 +786,6 @@ package body Rtsfind is
---------------
procedure Check_RPC is
- Body_Name : Unit_Name_Type;
- Unum : Unit_Number_Type;
-
begin
-- Bypass this check if debug flag -gnatdR set
@@ -799,47 +796,33 @@ package body Rtsfind is
-- Otherwise we need the check if we are going after one of
-- the critical entities in System.RPC in stubs mode.
+ -- ??? Should we do this for other s-parint/s-polint entities
+ -- too?
+
if (Distribution_Stub_Mode = Generate_Receiver_Stub_Body
or else
Distribution_Stub_Mode = Generate_Caller_Stub_Body)
and then (E = RE_Do_Rpc
- or else E = RE_Do_Apc
- or else E = RE_Params_Stream_Type
- or else E = RE_RPC_Receiver)
+ or else
+ E = RE_Do_Apc
+ or else
+ E = RE_Params_Stream_Type
+ or else
+ E = RE_RPC_Receiver)
then
- -- Load body of System.Rpc, and abort if this is the body that is
- -- provided by GNAT, for which these features are not supported
- -- on current target. We identify the gnat body by the presence
- -- of a local entity called Gnat in the first declaration.
-
- Lib_Unit := Unit (Cunit (U.Unum));
- Body_Name := Get_Body_Name (Get_Unit_Name (Lib_Unit));
- Unum :=
- Load_Unit
- (Load_Name => Body_Name,
- Required => False,
- Subunit => False,
- Error_Node => Empty,
- Renamings => True);
-
- if Unum /= No_Unit then
- declare
- Decls : constant List_Id :=
- Declarations (Unit (Cunit (Unum)));
-
- begin
- if Present (Decls)
- and then Nkind (First (Decls)) = N_Object_Declaration
- and then
- Chars (Defining_Identifier (First (Decls))) = Name_Gnat
- then
- Set_Standard_Error;
- Write_Str ("distribution feature not supported");
- Write_Eol;
- raise Unrecoverable_Error;
- end if;
- end;
- end if;
+ declare
+ DSA_Implementation : constant Entity_Id :=
+ RTE (RE_DSA_Implementation);
+ begin
+ if Chars (Entity (Expression
+ (Parent (DSA_Implementation)))) = Name_No_DSA
+ then
+ Set_Standard_Error;
+ Write_Str ("distribution feature not supported");
+ Write_Eol;
+ raise Unrecoverable_Error;
+ end if;
+ end;
end if;
end Check_RPC;
@@ -1063,6 +1046,15 @@ package body Rtsfind is
end if;
end RTE_Error_Msg;
+ ----------------
+ -- RTU_Loaded --
+ ----------------
+
+ function RTU_Loaded (U : RTU_Id) return Boolean is
+ begin
+ return Present (RT_Unit_Table (U).Entity);
+ end RTU_Loaded;
+
--------------------
-- Text_IO_Kludge --
--------------------
diff --git a/gcc/ada/rtsfind.ads b/gcc/ada/rtsfind.ads
index 04ef5b9dcd6..511242909d2 100644
--- a/gcc/ada/rtsfind.ads
+++ b/gcc/ada/rtsfind.ads
@@ -279,6 +279,7 @@ package Rtsfind is
System_Pack_63,
System_Parameters,
System_Partition_Interface,
+ System_PolyORB_Interface,
System_Pool_Global,
System_Pool_Empty,
System_Pool_Local,
@@ -996,6 +997,7 @@ package Rtsfind is
RE_Size_Type, -- System.Parameters
RE_Unspecified_Size, -- System.Parameters
+ RE_DSA_Implementation, -- System.Partition_Interface
RE_Get_Active_Partition_Id, -- System.Partition_Interface
RE_Get_Passive_Partition_Id, -- System.Partition_Interface
RE_Get_Local_Partition_Id, -- System.Partition_Interface
@@ -1003,7 +1005,6 @@ package Rtsfind is
RE_Get_Unique_Remote_Pointer, -- System.Partition_Interface
RE_RACW_Stub_Type, -- System.Partition_Interface
RE_RACW_Stub_Type_Access, -- System.Partition_Interface
- RE_Raise_Program_Error_For_E_4_18, -- System.Partition_Interface
RE_Raise_Program_Error_Unknown_Tag, -- System.Partition_Interface
RE_Register_Passive_Package, -- System.Partition_Interface
RE_Register_Receiving_Stub, -- System.Partition_Interface
@@ -1022,6 +1023,135 @@ package Rtsfind is
RE_Partition_ID, -- System.RPC
RE_RPC_Receiver, -- System.RPC
+ RE_To_PolyORB_String, -- System.PolyORB_Interface
+ RE_To_Standard_String, -- System.PolyORB_Interface
+ RE_Caseless_String_Eq, -- System.PolyORB_Interface
+ RE_TypeCode, -- System.PolyORB_Interface
+ RE_Any, -- System.PolyORB_Interface
+ RE_Mode_In, -- System.PolyORB_Interface
+ RE_Mode_Out, -- System.PolyORB_Interface
+ RE_Mode_Inout, -- System.PolyORB_Interface
+ RE_NamedValue, -- System.PolyORB_Interface
+ RE_Result_Name, -- System.PolyORB_Interface
+ RE_Object_Ref, -- System.PolyORB_Interface
+ RE_Create_Any, -- System.PolyORB_Interface
+ RE_Any_Aggregate_Build, -- System.PolyORB_Interface
+ RE_Add_Aggregate_Element, -- System.PolyORB_Interface
+ RE_Get_Aggregate_Element, -- System.PolyORB_Interface
+ RE_Content_Type, -- System.PolyORB_Interface
+ RE_Any_Member_Type, -- System.PolyORB_Interface
+ RE_Get_Nested_Sequence_Length, -- System.PolyORB_Interface
+ RE_Extract_Union_Value, -- System.PolyORB_Interface
+ RE_NVList_Ref, -- System.PolyORB_Interface
+ RE_NVList_Create, -- System.PolyORB_Interface
+ RE_NVList_Add_Item, -- System.PolyORB_Interface
+ RE_Request_Access, -- System.PolyORB_Interface
+ RE_Request_Create, -- System.PolyORB_Interface
+ RE_Request_Invoke, -- System.PolyORB_Interface
+ RE_Request_Arguments, -- System.PolyORB_Interface
+ RE_Request_Set_Out, -- System.PolyORB_Interface
+ RE_Request_Raise_Occurrence, -- System.PolyORB_Interface
+ RE_Nil_Exc_List, -- System.PolyORB_Interface
+ RE_Servant, -- System.PolyORB_Interface
+ RE_Copy_Any_Value, -- System.PolyORB_Interface
+ RE_Set_Result, -- System.PolyORB_Interface
+ RE_Register_Obj_Receiving_Stub, -- System.PolyORB_Interface
+ RE_Register_Pkg_Receiving_Stub, -- System.PolyORB_Interface
+ RE_Is_Nil, -- System.PolyORB_Interface
+ RE_Entity_Ptr, -- System.PolyORB_Interface
+ RE_Entity_Of, -- System.PolyORB_Interface
+ RE_Inc_Usage, -- System.PolyORB_Interface
+ RE_Set_Ref, -- System.PolyORB_Interface
+ RE_Get_Local_Address, -- System.PolyORB_Interface
+ RE_Get_Reference, -- System.PolyORB_Interface
+ RE_Local_Oid_To_Address, -- System.PolyORB_Interface
+ RE_RCI_Locator, -- System.PolyORB_Interface
+ RE_RCI_Subp_Info, -- System.PolyORB_Interface
+ RE_RCI_Subp_Info_Array, -- System.PolyORB_Interface
+ RE_Get_RAS_Ref, -- System.PolyORB_Interface
+ RE_Asynchronous_P_To_Sync_Scope, -- System.PolyORB_Interface
+ RE_Buffer_Stream_Type, -- System.PolyORB_Interface
+ RE_Allocate_Buffer, -- System.PolyORB_Interface
+ RE_Release_Buffer, -- System.PolyORB_Interface
+ RE_BS_To_Any, -- System.PolyORB_Interface
+ RE_Any_To_BS, -- System.PolyORB_Interface
+
+ RE_FA_AD, -- System.PolyORB_Interface
+ RE_FA_AS, -- System.PolyORB_Interface
+ RE_FA_B, -- System.PolyORB_Interface
+ RE_FA_C, -- System.PolyORB_Interface
+ RE_FA_F, -- System.PolyORB_Interface
+ RE_FA_I, -- System.PolyORB_Interface
+ RE_FA_LF, -- System.PolyORB_Interface
+ RE_FA_LI, -- System.PolyORB_Interface
+ RE_FA_LLF, -- System.PolyORB_Interface
+ RE_FA_LLI, -- System.PolyORB_Interface
+ RE_FA_LLU, -- System.PolyORB_Interface
+ RE_FA_LU, -- System.PolyORB_Interface
+ RE_FA_SF, -- System.PolyORB_Interface
+ RE_FA_SI, -- System.PolyORB_Interface
+ RE_FA_SSI, -- System.PolyORB_Interface
+ RE_FA_SSU, -- System.PolyORB_Interface
+ RE_FA_SU, -- System.PolyORB_Interface
+ RE_FA_U, -- System.PolyORB_Interface
+ RE_FA_WC, -- System.PolyORB_Interface
+ RE_FA_String, -- System.PolyORB_Interface
+ RE_FA_ObjRef, -- System.PolyORB_Interface
+
+ RE_TA_AD, -- System.PolyORB_Interface
+ RE_TA_AS, -- System.PolyORB_Interface
+ RE_TA_B, -- System.PolyORB_Interface
+ RE_TA_C, -- System.PolyORB_Interface
+ RE_TA_F, -- System.PolyORB_Interface
+ RE_TA_I, -- System.PolyORB_Interface
+ RE_TA_LF, -- System.PolyORB_Interface
+ RE_TA_LI, -- System.PolyORB_Interface
+ RE_TA_LLF, -- System.PolyORB_Interface
+ RE_TA_LLI, -- System.PolyORB_Interface
+ RE_TA_LLU, -- System.PolyORB_Interface
+ RE_TA_LU, -- System.PolyORB_Interface
+ RE_TA_SF, -- System.PolyORB_Interface
+ RE_TA_SI, -- System.PolyORB_Interface
+ RE_TA_SSI, -- System.PolyORB_Interface
+ RE_TA_SSU, -- System.PolyORB_Interface
+ RE_TA_SU, -- System.PolyORB_Interface
+ RE_TA_U, -- System.PolyORB_Interface
+ RE_TA_WC, -- System.PolyORB_Interface
+ RE_TA_String, -- System.PolyORB_Interface
+ RE_TA_ObjRef, -- System.PolyORB_Interface
+ RE_TA_TC, -- System.PolyORB_Interface
+
+ RE_TC_Alias, -- System.PolyORB_Interface
+ RE_TC_Build, -- System.PolyORB_Interface
+ RE_Set_TC, -- System.PolyORB_Interface
+ RE_TC_Any, -- System.PolyORB_Interface
+ RE_TC_AD, -- System.PolyORB_Interface
+ RE_TC_AS, -- System.PolyORB_Interface
+ RE_TC_B, -- System.PolyORB_Interface
+ RE_TC_C, -- System.PolyORB_Interface
+ RE_TC_F, -- System.PolyORB_Interface
+ RE_TC_I, -- System.PolyORB_Interface
+ RE_TC_LF, -- System.PolyORB_Interface
+ RE_TC_LI, -- System.PolyORB_Interface
+ RE_TC_LLF, -- System.PolyORB_Interface
+ RE_TC_LLI, -- System.PolyORB_Interface
+ RE_TC_LLU, -- System.PolyORB_Interface
+ RE_TC_LU, -- System.PolyORB_Interface
+ RE_TC_SF, -- System.PolyORB_Interface
+ RE_TC_SI, -- System.PolyORB_Interface
+ RE_TC_SSI, -- System.PolyORB_Interface
+ RE_TC_SSU, -- System.PolyORB_Interface
+ RE_TC_SU, -- System.PolyORB_Interface
+ RE_TC_U, -- System.PolyORB_Interface
+ RE_TC_Void, -- System.PolyORB_Interface
+ RE_TC_Opaque, -- System.PolyORB_Interface,
+ RE_TC_WC, -- System.PolyORB_Interface
+ RE_TC_Array, -- System.PolyORB_Interface,
+ RE_TC_Sequence, -- System.PolyORB_Interface,
+ RE_TC_String, -- System.PolyORB_Interface,
+ RE_TC_Struct, -- System.PolyORB_Interface,
+ RE_TC_Union, -- System.PolyORB_Interface,
+
RE_IS_Is1, -- System.Scalar_Values
RE_IS_Is2, -- System.Scalar_Values
RE_IS_Is4, -- System.Scalar_Values
@@ -1937,6 +2067,7 @@ package Rtsfind is
RE_Size_Type => System_Parameters,
RE_Unspecified_Size => System_Parameters,
+ RE_DSA_Implementation => System_Partition_Interface,
RE_Get_Active_Partition_Id => System_Partition_Interface,
RE_Get_Passive_Partition_Id => System_Partition_Interface,
RE_Get_Local_Partition_Id => System_Partition_Interface,
@@ -1944,13 +2075,141 @@ package Rtsfind is
RE_Get_Unique_Remote_Pointer => System_Partition_Interface,
RE_RACW_Stub_Type => System_Partition_Interface,
RE_RACW_Stub_Type_Access => System_Partition_Interface,
- RE_Raise_Program_Error_For_E_4_18 => System_Partition_Interface,
RE_Raise_Program_Error_Unknown_Tag => System_Partition_Interface,
RE_Register_Passive_Package => System_Partition_Interface,
RE_Register_Receiving_Stub => System_Partition_Interface,
RE_RCI_Info => System_Partition_Interface,
RE_Subprogram_Id => System_Partition_Interface,
+ RE_To_PolyORB_String => System_PolyORB_Interface,
+ RE_To_Standard_String => System_PolyORB_Interface,
+ RE_Caseless_String_Eq => System_PolyORB_Interface,
+ RE_TypeCode => System_PolyORB_Interface,
+ RE_Any => System_PolyORB_Interface,
+ RE_Mode_In => System_PolyORB_Interface,
+ RE_Mode_Out => System_PolyORB_Interface,
+ RE_Mode_Inout => System_PolyORB_Interface,
+ RE_NamedValue => System_PolyORB_Interface,
+ RE_Result_Name => System_PolyORB_Interface,
+ RE_Object_Ref => System_PolyORB_Interface,
+ RE_Create_Any => System_PolyORB_Interface,
+ RE_Any_Aggregate_Build => System_PolyORB_Interface,
+ RE_Add_Aggregate_Element => System_PolyORB_Interface,
+ RE_Get_Aggregate_Element => System_PolyORB_Interface,
+ RE_Content_Type => System_PolyORB_Interface,
+ RE_Any_Member_Type => System_PolyORB_Interface,
+ RE_Get_Nested_Sequence_Length => System_PolyORB_Interface,
+ RE_Extract_Union_Value => System_PolyORB_Interface,
+ RE_NVList_Ref => System_PolyORB_Interface,
+ RE_NVList_Create => System_PolyORB_Interface,
+ RE_NVList_Add_Item => System_PolyORB_Interface,
+ RE_Request_Access => System_PolyORB_Interface,
+ RE_Request_Create => System_PolyORB_Interface,
+ RE_Request_Invoke => System_PolyORB_Interface,
+ RE_Request_Arguments => System_PolyORB_Interface,
+ RE_Request_Set_Out => System_PolyORB_Interface,
+ RE_Request_Raise_Occurrence => System_PolyORB_Interface,
+ RE_Nil_Exc_List => System_PolyORB_Interface,
+ RE_Servant => System_PolyORB_Interface,
+ RE_Copy_Any_Value => System_PolyORB_Interface,
+ RE_Set_Result => System_PolyORB_Interface,
+ RE_Register_Obj_Receiving_Stub => System_PolyORB_Interface,
+ RE_Register_Pkg_Receiving_Stub => System_PolyORB_Interface,
+ RE_Is_Nil => System_PolyORB_Interface,
+ RE_Entity_Ptr => System_PolyORB_Interface,
+ RE_Entity_Of => System_PolyORB_Interface,
+ RE_Inc_Usage => System_PolyORB_Interface,
+ RE_Set_Ref => System_PolyORB_Interface,
+ RE_Get_Local_Address => System_PolyORB_Interface,
+ RE_Get_Reference => System_PolyORB_Interface,
+ RE_Local_Oid_To_Address => System_PolyORB_Interface,
+ RE_RCI_Locator => System_PolyORB_Interface,
+ RE_RCI_Subp_Info => System_PolyORB_Interface,
+ RE_RCI_Subp_Info_Array => System_PolyORB_Interface,
+ RE_Get_RAS_Ref => System_PolyORB_Interface,
+ RE_Asynchronous_P_To_Sync_Scope => System_PolyORB_Interface,
+ RE_Buffer_Stream_Type => System_PolyORB_Interface,
+ RE_Allocate_Buffer => System_PolyORB_Interface,
+ RE_Release_Buffer => System_PolyORB_Interface,
+ RE_BS_To_Any => System_PolyORB_Interface,
+ RE_Any_To_BS => System_PolyORB_Interface,
+
+ RE_FA_AD => System_PolyORB_Interface,
+ RE_FA_AS => System_PolyORB_Interface,
+ RE_FA_B => System_PolyORB_Interface,
+ RE_FA_C => System_PolyORB_Interface,
+ RE_FA_F => System_PolyORB_Interface,
+ RE_FA_I => System_PolyORB_Interface,
+ RE_FA_LF => System_PolyORB_Interface,
+ RE_FA_LI => System_PolyORB_Interface,
+ RE_FA_LLF => System_PolyORB_Interface,
+ RE_FA_LLI => System_PolyORB_Interface,
+ RE_FA_LLU => System_PolyORB_Interface,
+ RE_FA_LU => System_PolyORB_Interface,
+ RE_FA_SF => System_PolyORB_Interface,
+ RE_FA_SI => System_PolyORB_Interface,
+ RE_FA_SSI => System_PolyORB_Interface,
+ RE_FA_SSU => System_PolyORB_Interface,
+ RE_FA_SU => System_PolyORB_Interface,
+ RE_FA_U => System_PolyORB_Interface,
+ RE_FA_WC => System_PolyORB_Interface,
+ RE_FA_String => System_PolyORB_Interface,
+ RE_FA_ObjRef => System_PolyORB_Interface,
+
+ RE_TA_AD => System_PolyORB_Interface,
+ RE_TA_AS => System_PolyORB_Interface,
+ RE_TA_B => System_PolyORB_Interface,
+ RE_TA_C => System_PolyORB_Interface,
+ RE_TA_F => System_PolyORB_Interface,
+ RE_TA_I => System_PolyORB_Interface,
+ RE_TA_LF => System_PolyORB_Interface,
+ RE_TA_LI => System_PolyORB_Interface,
+ RE_TA_LLF => System_PolyORB_Interface,
+ RE_TA_LLI => System_PolyORB_Interface,
+ RE_TA_LLU => System_PolyORB_Interface,
+ RE_TA_LU => System_PolyORB_Interface,
+ RE_TA_SF => System_PolyORB_Interface,
+ RE_TA_SI => System_PolyORB_Interface,
+ RE_TA_SSI => System_PolyORB_Interface,
+ RE_TA_SSU => System_PolyORB_Interface,
+ RE_TA_SU => System_PolyORB_Interface,
+ RE_TA_U => System_PolyORB_Interface,
+ RE_TA_WC => System_PolyORB_Interface,
+ RE_TA_String => System_PolyORB_Interface,
+ RE_TA_ObjRef => System_PolyORB_Interface,
+ RE_TA_TC => System_PolyORB_Interface,
+
+ RE_TC_Alias => System_PolyORB_Interface,
+ RE_TC_Build => System_PolyORB_Interface,
+ RE_Set_TC => System_PolyORB_Interface,
+ RE_TC_Any => System_PolyORB_Interface,
+ RE_TC_AD => System_PolyORB_Interface,
+ RE_TC_AS => System_PolyORB_Interface,
+ RE_TC_B => System_PolyORB_Interface,
+ RE_TC_C => System_PolyORB_Interface,
+ RE_TC_F => System_PolyORB_Interface,
+ RE_TC_I => System_PolyORB_Interface,
+ RE_TC_LF => System_PolyORB_Interface,
+ RE_TC_LI => System_PolyORB_Interface,
+ RE_TC_LLF => System_PolyORB_Interface,
+ RE_TC_LLI => System_PolyORB_Interface,
+ RE_TC_LLU => System_PolyORB_Interface,
+ RE_TC_LU => System_PolyORB_Interface,
+ RE_TC_SF => System_PolyORB_Interface,
+ RE_TC_SI => System_PolyORB_Interface,
+ RE_TC_SSI => System_PolyORB_Interface,
+ RE_TC_SSU => System_PolyORB_Interface,
+ RE_TC_SU => System_PolyORB_Interface,
+ RE_TC_U => System_PolyORB_Interface,
+ RE_TC_Void => System_PolyORB_Interface,
+ RE_TC_Opaque => System_PolyORB_Interface,
+ RE_TC_WC => System_PolyORB_Interface,
+ RE_TC_Array => System_PolyORB_Interface,
+ RE_TC_Sequence => System_PolyORB_Interface,
+ RE_TC_String => System_PolyORB_Interface,
+ RE_TC_Struct => System_PolyORB_Interface,
+ RE_TC_Union => System_PolyORB_Interface,
+
RE_Global_Pool_Object => System_Pool_Global,
RE_Unbounded_Reclaim_Pool => System_Pool_Local,
@@ -2453,6 +2712,12 @@ package Rtsfind is
-- exception and without generating an error message, i.e. if the
-- call will obtain the desired entity without any problems.
+ function RTU_Loaded (U : RTU_Id) return Boolean;
+ pragma Inline (RTU_Loaded);
+ -- Returns true if indicated unit has already been successfully loaded.
+ -- If the unit has not been loaded, returns False. Note that this does
+ -- not mean that an attempt to load it subsequently would fail.
+
procedure Text_IO_Kludge (Nam : Node_Id);
-- In Ada 83, and hence for compatibility in Ada 9X, package Text_IO has
-- generic subpackages (e.g. Integer_IO). They really should be child
diff --git a/gcc/ada/s-addope.adb b/gcc/ada/s-addope.adb
new file mode 100644
index 00000000000..2b360f1c96f
--- /dev/null
+++ b/gcc/ada/s-addope.adb
@@ -0,0 +1,114 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . A D D R E S S _ O P E R A T I O N S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2004 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the implementation dependent sections of this file. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Unchecked_Conversion;
+
+package body System.Address_Operations is
+
+ type IA is mod 2 ** Address'Size;
+ -- The type used to provide the actual desired operations
+
+ function I is new Unchecked_Conversion (Address, IA);
+ function A is new Unchecked_Conversion (IA, Address);
+ -- The operations are implemented by unchecked conversion to type IA,
+ -- followed by doing the intrinsic operation on the IA values, followed
+ -- by converting the result back to type Address.
+
+ ----------
+ -- AddA --
+ ----------
+
+ function AddA (Left, Right : Address) return Address is
+ begin
+ return A (I (Left) + I (Right));
+ end AddA;
+
+ ----------
+ -- AndA --
+ ----------
+
+ function AndA (Left, Right : Address) return Address is
+ begin
+ return A (I (Left) and I (Right));
+ end AndA;
+
+ ----------
+ -- DivA --
+ ----------
+
+ function DivA (Left, Right : Address) return Address is
+ begin
+ return A (I (Left) / I (Right));
+ end DivA;
+
+ ----------
+ -- ModA --
+ ----------
+
+ function ModA (Left, Right : Address) return Address is
+ begin
+ return A (I (Left) mod I (Right));
+ end ModA;
+
+ ---------
+ -- MulA --
+ ---------
+
+ function MulA (Left, Right : Address) return Address is
+ begin
+ return A (I (Left) * I (Right));
+ end MulA;
+
+ ---------
+ -- OrA --
+ ---------
+
+ function OrA (Left, Right : Address) return Address is
+ begin
+ return A (I (Left) or I (Right));
+ end OrA;
+
+ ----------
+ -- SubA --
+ ----------
+
+ function SubA (Left, Right : Address) return Address is
+ begin
+ return A (I (Left) - I (Right));
+ end SubA;
+
+end System.Address_Operations;
diff --git a/gcc/ada/s-addope.ads b/gcc/ada/s-addope.ads
new file mode 100644
index 00000000000..1fc7d3576d3
--- /dev/null
+++ b/gcc/ada/s-addope.ads
@@ -0,0 +1,84 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . A D D R E S S _ O P E R A T I O N S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2004 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the implementation dependent sections of this file. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides arithmetic and logical operations on type Address.
+-- It is intended for use by other packages in the System hierarchy. For
+-- applications requiring this capability, see System.Storage_Elements or
+-- the operations introduced in System.Aux_DEC;
+
+-- The reason we need this package is that arithmetic operations may not
+-- be available in the case where type Address is non-private and the
+-- operations have been made abstract in the spec of System (to avoid
+-- inappropriate use by applications programs). In addition, the logical
+-- operations may not be available if type Address is a signed integer.
+
+package System.Address_Operations is
+pragma Pure (Address_Operations);
+
+ -- The semantics of the arithmetic operations are those that apply to
+ -- a modular type with the same length as Address, i.e. they provide
+ -- twos complement wrap around arithmetic treating the address value
+ -- as an unsigned value, with no overflow checking.
+
+ -- Note that we do not use the infix names for these operations to
+ -- avoid problems with ambiguities coming from declarations in package
+ -- Standard (which may or may not be visible depending on the exact
+ -- form of the declaration of type System.Address).
+
+ function AddA (Left, Right : Address) return Address;
+ function SubA (Left, Right : Address) return Address;
+ function MulA (Left, Right : Address) return Address;
+ function DivA (Left, Right : Address) return Address;
+ function ModA (Left, Right : Address) return Address;
+
+ -- The semantics of the logical operations are those that apply to
+ -- a modular type with the same length as Address, i.e. they provide
+ -- bit-wise operations on all bits of the value (including the sign
+ -- bit if Address is a signed integer type).
+
+ function AndA (Left, Right : Address) return Address;
+ function OrA (Left, Right : Address) return Address;
+
+ pragma Inline_Always (AddA);
+ pragma Inline_Always (SubA);
+ pragma Inline_Always (MulA);
+ pragma Inline_Always (DivA);
+ pragma Inline_Always (ModA);
+ pragma Inline_Always (AndA);
+ pragma Inline_Always (OrA);
+
+end System.Address_Operations;
diff --git a/gcc/ada/s-asthan-vms.adb b/gcc/ada/s-asthan-vms.adb
new file mode 100644
index 00000000000..86d04025dbf
--- /dev/null
+++ b/gcc/ada/s-asthan-vms.adb
@@ -0,0 +1,597 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . A S T _ H A N D L I N G --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1996-2004 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the OpenVMS/Alpha version.
+
+with System; use System;
+
+with System.IO;
+
+with System.Machine_Code;
+with System.Parameters;
+with System.Storage_Elements;
+
+with System.Tasking;
+with System.Tasking.Rendezvous;
+with System.Tasking.Initialization;
+with System.Tasking.Utilities;
+
+with System.Task_Primitives;
+with System.Task_Primitives.Operations;
+with System.Task_Primitives.Operations.DEC;
+
+-- with Ada.Finalization;
+-- removed, because of problem with controlled attribute ???
+
+with Ada.Task_Attributes;
+with Ada.Task_Identification;
+
+with Ada.Exceptions; use Ada.Exceptions;
+
+with Ada.Unchecked_Conversion;
+
+package body System.AST_Handling is
+
+ package ATID renames Ada.Task_Identification;
+
+ package SP renames System.Parameters;
+ package ST renames System.Tasking;
+ package STR renames System.Tasking.Rendezvous;
+ package STI renames System.Tasking.Initialization;
+ package STU renames System.Tasking.Utilities;
+
+ package SSE renames System.Storage_Elements;
+ package STPO renames System.Task_Primitives.Operations;
+ package STPOD renames System.Task_Primitives.Operations.DEC;
+
+ AST_Lock : aliased System.Task_Primitives.RTS_Lock;
+ -- This is a global lock; it is used to execute in mutual exclusion
+ -- from all other AST tasks. It is only used by Lock_AST and
+ -- Unlock_AST.
+
+ procedure Lock_AST (Self_ID : ST.Task_ID);
+ -- Locks out other AST tasks. Preceding a section of code by Lock_AST and
+ -- following it by Unlock_AST creates a critical region.
+
+ procedure Unlock_AST (Self_ID : ST.Task_ID);
+ -- Releases lock previously set by call to Lock_AST.
+ -- All nested locks must be released before other tasks competing for the
+ -- tasking lock are released.
+
+ --------------
+ -- Lock_AST --
+ --------------
+
+ procedure Lock_AST (Self_ID : ST.Task_ID) is
+ begin
+ STI.Defer_Abort_Nestable (Self_ID);
+ STPO.Write_Lock (AST_Lock'Access, Global_Lock => True);
+ end Lock_AST;
+
+ ----------------
+ -- Unlock_AST --
+ ----------------
+
+ procedure Unlock_AST (Self_ID : ST.Task_ID) is
+ begin
+ STPO.Unlock (AST_Lock'Access, Global_Lock => True);
+ STI.Undefer_Abort_Nestable (Self_ID);
+ end Unlock_AST;
+
+ ---------------------------------
+ -- AST_Handler Data Structures --
+ ---------------------------------
+
+ -- As noted in the private part of the spec of System.Aux_DEC, the
+ -- AST_Handler type is simply a pointer to a procedure that takes
+ -- a single 64bit parameter. The following is a local copy
+ -- of that definition.
+
+ -- We need our own copy because we need to get our hands on this
+ -- and we cannot see the private part of System.Aux_DEC. We don't
+ -- want to be a child of Aux_Dec because of complications resulting
+ -- from the use of pragma Extend_System. We will use unchecked
+ -- conversions between the two versions of the declarations.
+
+ type AST_Handler is access procedure (Param : Long_Integer);
+
+ -- However, this declaration is somewhat misleading, since the values
+ -- referenced by AST_Handler values (all produced in this package by
+ -- calls to Create_AST_Handler) are highly stylized.
+
+ -- The first point is that in VMS/Alpha, procedure pointers do not in
+ -- fact point to code, but rather to a 48-byte procedure descriptor.
+ -- So a value of type AST_Handler is in fact a pointer to one of these
+ -- 48-byte descriptors.
+
+ type Descriptor_Type is new SSE.Storage_Array (1 .. 48);
+ for Descriptor_Type'Alignment use Standard'Maximum_Alignment;
+ pragma Warnings (Off, Descriptor_Type);
+ -- Suppress harmless warnings about alignment.
+ -- Should explain why this warning is harmless ???
+
+ type Descriptor_Ref is access all Descriptor_Type;
+
+ -- Normally, there is only one such descriptor for a given procedure, but
+ -- it works fine to make a copy of the single allocated descriptor, and
+ -- use the copy itself, and we take advantage of this in the design here.
+ -- The idea is that AST_Handler values will all point to a record with the
+ -- following structure:
+
+ -- Note: When we say it works fine, there is one delicate point, which
+ -- is that the code for the AST procedure itself requires the original
+ -- descriptor address. We handle this by saving the orignal descriptor
+ -- address in this structure and restoring in Process_AST.
+
+ type AST_Handler_Data is record
+ Descriptor : Descriptor_Type;
+ Original_Descriptor_Ref : Descriptor_Ref;
+ Taskid : ATID.Task_Id;
+ Entryno : Natural;
+ end record;
+
+ type AST_Handler_Data_Ref is access all AST_Handler_Data;
+
+ function To_AST_Handler is new Ada.Unchecked_Conversion
+ (AST_Handler_Data_Ref, System.Aux_DEC.AST_Handler);
+
+ -- Each time Create_AST_Handler is called, a new value of this record
+ -- type is created, containing a copy of the procedure descriptor for
+ -- the routine used to handle all AST's (Process_AST), and the Task_Id
+ -- and entry number parameters identifying the task entry involved.
+
+ -- The AST_Handler value returned is a pointer to this record. Since
+ -- the record starts with the procedure descriptor, it can be used
+ -- by the system in the normal way to call the procedure. But now
+ -- when the procedure gets control, it can determine the address of
+ -- the procedure descriptor used to call it (since the ABI specifies
+ -- that this is left sitting in register r27 on entry), and then use
+ -- that address to retrieve the Task_Id and entry number so that it
+ -- knows on which entry to queue the AST request.
+
+ -- The next issue is where are these records placed. Since we intend
+ -- to pass pointers to these records to asynchronous system service
+ -- routines, they have to be on the heap, which means we have to worry
+ -- about when to allocate them and deallocate them.
+
+ -- We solve this problem by introducing a task attribute that points to
+ -- a vector, indexed by the entry number, of AST_Handler_Data records
+ -- for a given task. The pointer itself is a controlled object allowing
+ -- us to write a finalization routine that frees the referenced vector.
+
+ -- An entry in this vector is either initialized (Entryno non-zero) and
+ -- can be used for any subsequent reference to the same entry, or it is
+ -- unused, marked by the Entryno value being zero.
+
+ type AST_Handler_Vector is array (Natural range <>) of AST_Handler_Data;
+ type AST_Handler_Vector_Ref is access all AST_Handler_Vector;
+
+-- type AST_Vector_Ptr is new Ada.Finalization.Controlled with record
+-- removed due to problem with controlled attribute, consequence is that
+-- we have a memory leak if a task that has AST attribute entries is
+-- terminated. ???
+
+ type AST_Vector_Ptr is record
+ Vector : AST_Handler_Vector_Ref;
+ end record;
+
+ AST_Vector_Init : AST_Vector_Ptr;
+ -- Initial value, treated as constant, Vector will be null.
+
+ package AST_Attribute is new Ada.Task_Attributes
+ (Attribute => AST_Vector_Ptr,
+ Initial_Value => AST_Vector_Init);
+
+ use AST_Attribute;
+
+ -----------------------
+ -- AST Service Queue --
+ -----------------------
+
+ -- The following global data structures are used to queue pending
+ -- AST requests. When an AST is signalled, the AST service routine
+ -- Process_AST is called, and it makes an entry in this structure.
+
+ type AST_Instance is record
+ Taskid : ATID.Task_Id;
+ Entryno : Natural;
+ Param : Long_Integer;
+ end record;
+ -- The Taskid and Entryno indicate the entry on which this AST is to
+ -- be queued, and Param is the parameter provided from the AST itself.
+
+ AST_Service_Queue_Size : constant := 256;
+ AST_Service_Queue_Limit : constant := 250;
+ type AST_Service_Queue_Index is mod AST_Service_Queue_Size;
+ -- Index used to refer to entries in the circular buffer which holds
+ -- active AST_Instance values. The upper bound reflects the maximum
+ -- number of AST instances that can be stored in the buffer. Since
+ -- these entries are immediately serviced by the high priority server
+ -- task that does the actual entry queuing, it is very unusual to have
+ -- any significant number of entries simulaneously queued.
+
+ AST_Service_Queue : array (AST_Service_Queue_Index) of AST_Instance;
+ pragma Volatile_Components (AST_Service_Queue);
+ -- The circular buffer used to store active AST requests.
+
+ AST_Service_Queue_Put : AST_Service_Queue_Index := 0;
+ AST_Service_Queue_Get : AST_Service_Queue_Index := 0;
+ pragma Atomic (AST_Service_Queue_Put);
+ pragma Atomic (AST_Service_Queue_Get);
+ -- These two variables point to the next slots in the AST_Service_Queue
+ -- to be used for putting a new entry in and taking an entry out. This
+ -- is a circular buffer, so these pointers wrap around. If the two values
+ -- are equal the buffer is currently empty. The pointers are atomic to
+ -- ensure proper synchronization between the single producer (namely the
+ -- Process_AST procedure), and the single consumer (the AST_Service_Task).
+
+ --------------------------------
+ -- AST Server Task Structures --
+ --------------------------------
+
+ -- The basic approach is that when an AST comes in, a call is made to
+ -- the Process_AST procedure. It queues the request in the service queue
+ -- and then wakes up an AST server task to perform the actual call to the
+ -- required entry. We use this intermediate server task, since the AST
+ -- procedure itself cannot wait to return, and we need some caller for
+ -- the rendezvous so that we can use the normal rendezvous mechanism.
+
+ -- It would work to have only one AST server task, but then we would lose
+ -- all overlap in AST processing, and furthermore, we could get priority
+ -- inversion effects resulting in starvation of AST requests.
+
+ -- We therefore maintain a small pool of AST server tasks. We adjust
+ -- the size of the pool dynamically to reflect traffic, so that we have
+ -- a sufficient number of server tasks to avoid starvation.
+
+ Max_AST_Servers : constant Natural := 16;
+ -- Maximum number of AST server tasks that can be allocated
+
+ Num_AST_Servers : Natural := 0;
+ -- Number of AST server tasks currently active
+
+ Num_Waiting_AST_Servers : Natural := 0;
+ -- This is the number of AST server tasks that are either waiting for
+ -- work, or just about to go to sleep and wait for work.
+
+ Is_Waiting : array (1 .. Max_AST_Servers) of Boolean := (others => False);
+ -- An array of flags showing which AST server tasks are currently waiting
+
+ AST_Task_Ids : array (1 .. Max_AST_Servers) of ST.Task_ID;
+ -- Task Id's of allocated AST server tasks
+
+ task type AST_Server_Task (Num : Natural) is
+ pragma Priority (Priority'Last);
+ end AST_Server_Task;
+ -- Declaration for AST server task. This task has no entries, it is
+ -- controlled by sleep and wakeup calls at the task primitives level.
+
+ type AST_Server_Task_Ptr is access all AST_Server_Task;
+ -- Type used to allocate server tasks
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ procedure Allocate_New_AST_Server;
+ -- Allocate an additional AST server task
+
+ procedure Process_AST (Param : Long_Integer);
+ -- This is the central routine for processing all AST's, it is referenced
+ -- as the code address of all created AST_Handler values. See detailed
+ -- description in body to understand how it works to have a single such
+ -- procedure for all AST's even though it does not get any indication of
+ -- the entry involved passed as an explicit parameter. The single explicit
+ -- parameter Param is the parameter passed by the system with the AST.
+
+ -----------------------------
+ -- Allocate_New_AST_Server --
+ -----------------------------
+
+ procedure Allocate_New_AST_Server is
+ Dummy : AST_Server_Task_Ptr;
+ pragma Unreferenced (Dummy);
+
+ begin
+ if Num_AST_Servers = Max_AST_Servers then
+ return;
+
+ else
+ -- Note: it is safe to increment Num_AST_Servers immediately, since
+ -- no one will try to activate this task until it indicates that it
+ -- is sleeping by setting its entry in Is_Waiting to True.
+
+ Num_AST_Servers := Num_AST_Servers + 1;
+ Dummy := new AST_Server_Task (Num_AST_Servers);
+ end if;
+ end Allocate_New_AST_Server;
+
+ ---------------------
+ -- AST_Server_Task --
+ ---------------------
+
+ task body AST_Server_Task is
+ Taskid : ATID.Task_Id;
+ Entryno : Natural;
+ Param : aliased Long_Integer;
+ Self_Id : constant ST.Task_ID := ST.Self;
+
+ pragma Volatile (Param);
+
+ begin
+ -- By making this task independent of master, when the environment
+ -- task is finalizing, the AST_Server_Task will be notified that it
+ -- should terminate.
+
+ STU.Make_Independent;
+
+ -- Record our task Id for access by Process_AST
+
+ AST_Task_Ids (Num) := Self_Id;
+
+ -- Note: this entire task operates with the main task lock set, except
+ -- when it is sleeping waiting for work, or busy doing a rendezvous
+ -- with an AST server. This lock protects the data structures that
+ -- are shared by multiple instances of the server task.
+
+ Lock_AST (Self_Id);
+
+ -- This is the main infinite loop of the task. We go to sleep and
+ -- wait to be woken up by Process_AST when there is some work to do.
+
+ loop
+ Num_Waiting_AST_Servers := Num_Waiting_AST_Servers + 1;
+
+ Unlock_AST (Self_Id);
+
+ STI.Defer_Abort (Self_Id);
+
+ if SP.Single_Lock then
+ STPO.Lock_RTS;
+ end if;
+
+ STPO.Write_Lock (Self_Id);
+
+ Is_Waiting (Num) := True;
+
+ Self_Id.Common.State := ST.AST_Server_Sleep;
+ STPO.Sleep (Self_Id, ST.AST_Server_Sleep);
+ Self_Id.Common.State := ST.Runnable;
+
+ STPO.Unlock (Self_Id);
+
+ if SP.Single_Lock then
+ STPO.Unlock_RTS;
+ end if;
+
+ -- If the process is finalizing, Undefer_Abort will simply end
+ -- this task.
+
+ STI.Undefer_Abort (Self_Id);
+
+ -- We are awake, there is something to do!
+
+ Lock_AST (Self_Id);
+ Num_Waiting_AST_Servers := Num_Waiting_AST_Servers - 1;
+
+ -- Loop here to service outstanding requests. We are always
+ -- locked on entry to this loop.
+
+ while AST_Service_Queue_Get /= AST_Service_Queue_Put loop
+ Taskid := AST_Service_Queue (AST_Service_Queue_Get).Taskid;
+ Entryno := AST_Service_Queue (AST_Service_Queue_Get).Entryno;
+ Param := AST_Service_Queue (AST_Service_Queue_Get).Param;
+
+ AST_Service_Queue_Get := AST_Service_Queue_Get + 1;
+
+ -- This is a manual expansion of the normal call simple code
+
+ declare
+ type AA is access all Long_Integer;
+ P : AA := Param'Unrestricted_Access;
+
+ function To_ST_Task_Id is new Ada.Unchecked_Conversion
+ (ATID.Task_Id, ST.Task_ID);
+
+ begin
+ Unlock_AST (Self_Id);
+ STR.Call_Simple
+ (Acceptor => To_ST_Task_Id (Taskid),
+ E => ST.Task_Entry_Index (Entryno),
+ Uninterpreted_Data => P'Address);
+
+ exception
+ when E : others =>
+ System.IO.Put_Line ("%Debugging event");
+ System.IO.Put_Line (Exception_Name (E) &
+ " raised when trying to deliver an AST.");
+
+ if Exception_Message (E)'Length /= 0 then
+ System.IO.Put_Line (Exception_Message (E));
+ end if;
+
+ System.IO.Put_Line ("Task type is " & "Receiver_Type");
+ System.IO.Put_Line ("Task id is " & ATID.Image (Taskid));
+ end;
+
+ Lock_AST (Self_Id);
+ end loop;
+ end loop;
+ end AST_Server_Task;
+
+ ------------------------
+ -- Create_AST_Handler --
+ ------------------------
+
+ function Create_AST_Handler
+ (Taskid : ATID.Task_Id;
+ Entryno : Natural) return System.Aux_DEC.AST_Handler
+ is
+ Attr_Ref : Attribute_Handle;
+
+ Process_AST_Ptr : constant AST_Handler := Process_AST'Access;
+ -- Reference to standard procedure descriptor for Process_AST
+
+ function To_Descriptor_Ref is new Ada.Unchecked_Conversion
+ (AST_Handler, Descriptor_Ref);
+
+ Original_Descriptor_Ref : constant Descriptor_Ref :=
+ To_Descriptor_Ref (Process_AST_Ptr);
+
+ begin
+ if ATID.Is_Terminated (Taskid) then
+ raise Program_Error;
+ end if;
+
+ Attr_Ref := Reference (Taskid);
+
+ -- Allocate another server if supply is getting low
+
+ if Num_Waiting_AST_Servers < 2 then
+ Allocate_New_AST_Server;
+ end if;
+
+ -- No point in creating more if we have zillions waiting to
+ -- be serviced.
+
+ while AST_Service_Queue_Put - AST_Service_Queue_Get
+ > AST_Service_Queue_Limit
+ loop
+ delay 0.01;
+ end loop;
+
+ -- If no AST vector allocated, or the one we have is too short, then
+ -- allocate one of right size and initialize all entries except the
+ -- one we will use to unused. Note that the assignment automatically
+ -- frees the old allocated table if there is one.
+
+ if Attr_Ref.Vector = null
+ or else Attr_Ref.Vector'Length < Entryno
+ then
+ Attr_Ref.Vector := new AST_Handler_Vector (1 .. Entryno);
+
+ for E in 1 .. Entryno loop
+ Attr_Ref.Vector (E).Descriptor :=
+ Original_Descriptor_Ref.all;
+ Attr_Ref.Vector (E).Original_Descriptor_Ref :=
+ Original_Descriptor_Ref;
+ Attr_Ref.Vector (E).Taskid := Taskid;
+ Attr_Ref.Vector (E).Entryno := E;
+ end loop;
+ end if;
+
+ return To_AST_Handler (Attr_Ref.Vector (Entryno)'Unrestricted_Access);
+ end Create_AST_Handler;
+
+ ----------------------------
+ -- Expand_AST_Packet_Pool --
+ ----------------------------
+
+ procedure Expand_AST_Packet_Pool
+ (Requested_Packets : in Natural;
+ Actual_Number : out Natural;
+ Total_Number : out Natural)
+ is
+ pragma Unreferenced (Requested_Packets);
+ begin
+ -- The AST implementation of GNAT does not permit dynamic expansion
+ -- of the pool, so we simply add no entries and return the total. If
+ -- it is necessary to expand the allocation, then this package body
+ -- must be recompiled with a larger value for AST_Service_Queue_Size.
+
+ Actual_Number := 0;
+ Total_Number := AST_Service_Queue_Size;
+ end Expand_AST_Packet_Pool;
+
+ -----------------
+ -- Process_AST --
+ -----------------
+
+ procedure Process_AST (Param : Long_Integer) is
+
+ Handler_Data_Ptr : AST_Handler_Data_Ref;
+ -- This variable is set to the address of the descriptor through
+ -- which Process_AST is called. Since the descriptor is part of
+ -- an AST_Handler value, this is also the address of this value,
+ -- from which we can obtain the task and entry number information.
+
+ function To_Address is new Ada.Unchecked_Conversion
+ (ST.Task_ID, System.Address);
+
+ begin
+ System.Machine_Code.Asm
+ (Template => "addl $27,0,%0",
+ Outputs => AST_Handler_Data_Ref'Asm_Output ("=r", Handler_Data_Ptr),
+ Volatile => True);
+
+ System.Machine_Code.Asm
+ (Template => "ldl $27,%0",
+ Inputs => Descriptor_Ref'Asm_Input
+ ("m", Handler_Data_Ptr.Original_Descriptor_Ref),
+ Volatile => True);
+
+ AST_Service_Queue (AST_Service_Queue_Put) := AST_Instance'
+ (Taskid => Handler_Data_Ptr.Taskid,
+ Entryno => Handler_Data_Ptr.Entryno,
+ Param => Param);
+
+ -- OpenVMS Programming Concepts manual, chapter 8.2.3:
+ -- "Implicit synchronization can be achieved for data that is shared
+ -- for write by using only AST routines to write the data, since only
+ -- one AST can be running at any one time."
+
+ -- This subprogram runs at AST level so is guaranteed to be
+ -- called sequentially at a given access level.
+
+ AST_Service_Queue_Put := AST_Service_Queue_Put + 1;
+
+ -- Need to wake up processing task. If there is no waiting server
+ -- then we have temporarily run out, but things should still be
+ -- OK, since one of the active ones will eventually pick up the
+ -- service request queued in the AST_Service_Queue.
+
+ for J in 1 .. Num_AST_Servers loop
+ if Is_Waiting (J) then
+ Is_Waiting (J) := False;
+
+ -- Sleeps are handled by ASTs on VMS, so don't call Wakeup.
+
+ STPOD.Interrupt_AST_Handler (To_Address (AST_Task_Ids (J)));
+ exit;
+ end if;
+ end loop;
+ end Process_AST;
+
+begin
+ STPO.Initialize_Lock (AST_Lock'Access, STPO.Global_Task_Level);
+end System.AST_Handling;
diff --git a/gcc/ada/s-auxdec.adb b/gcc/ada/s-auxdec.adb
index 51d6ac55842..f2f71b28b37 100644
--- a/gcc/ada/s-auxdec.adb
+++ b/gcc/ada/s-auxdec.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -102,9 +102,8 @@ package body System.Aux_DEC is
function "-" (Left : Address; Right : Address) return Integer is
pragma Unsuppress (All_Checks);
-- Because this can raise Constraint_Error for 64-bit addresses
-
begin
- return Integer (From_A (Left - Right));
+ return Integer (From_A (Left) - From_A (Right));
end "-";
function "-" (Left : Address; Right : Integer) return Address is
@@ -120,7 +119,6 @@ package body System.Aux_DEC is
type T_Ptr is access all Target;
function To_T_Ptr is new Unchecked_Conversion (Address, T_Ptr);
Ptr : constant T_Ptr := To_T_Ptr (A);
-
begin
return Ptr.all;
end Fetch_From_Address;
@@ -133,7 +131,6 @@ package body System.Aux_DEC is
type T_Ptr is access all Target;
function To_T_Ptr is new Unchecked_Conversion (Address, T_Ptr);
Ptr : constant T_Ptr := To_T_Ptr (A);
-
begin
Ptr.all := T;
end Assign_To_Address;
diff --git a/gcc/ada/s-auxdec.ads b/gcc/ada/s-auxdec.ads
index c517ae5ee30..2d34ff111c9 100644
--- a/gcc/ada/s-auxdec.ads
+++ b/gcc/ada/s-auxdec.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1996-2002 Free Software Foundation, Inc. --
+-- Copyright (C) 1996-2004 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- --
@@ -42,6 +42,16 @@ with Unchecked_Conversion;
package System.Aux_DEC is
pragma Elaborate_Body (Aux_DEC);
+ subtype Short_Address is Address;
+ -- In some versions of System.Aux_DEC, notably that for VMS on the
+ -- ia64, there are two address types (64-bit and 32-bit), and the
+ -- name Short_Address is used for the short address form. To avoid
+ -- difficulties (in regression tests and elsewhere) with units that
+ -- reference Short_Address, it is provided for other targets as a
+ -- synonum for the normal Address type, and, as in the case where
+ -- the lengths are different, Address and Short_Address can be
+ -- freely inter-converted.
+
type Integer_8 is range -2 ** (8 - 1) .. +2 ** (8 - 1) - 1;
for Integer_8'Size use 8;
diff --git a/gcc/ada/s-carsi8.adb b/gcc/ada/s-carsi8.adb
index ebc86e78223..9a6ea466eb4 100644
--- a/gcc/ada/s-carsi8.adb
+++ b/gcc/ada/s-carsi8.adb
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2002 Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2004 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- --
@@ -31,6 +31,8 @@
-- --
------------------------------------------------------------------------------
+with System.Address_Operations; use System.Address_Operations;
+
with Unchecked_Conversion;
package body System.Compare_Array_Signed_8 is
@@ -64,15 +66,14 @@ package body System.Compare_Array_Signed_8 is
(Left : System.Address;
Right : System.Address;
Left_Len : Natural;
- Right_Len : Natural)
- return Integer
+ Right_Len : Natural) return Integer
is
Compare_Len : constant Natural := Natural'Min (Left_Len, Right_Len);
begin
-- If operands are non-aligned, or length is too short, go by bytes
- if (((Left or Right) and 2#11#) /= 0) or else Compare_Len < 4 then
+ if ModA (OrA (Left, Right), 4) /= 0 or else Compare_Len < 4 then
return Compare_Array_S8_Unaligned (Left, Right, Left_Len, Right_Len);
end if;
@@ -88,15 +89,15 @@ package body System.Compare_Array_Signed_8 is
for J in 0 .. Clen4 loop
if LeftP (J) /= RightP (J) then
return Compare_Array_S8_Unaligned
- (Left + Address (4 * J),
- Right + Address (4 * J),
+ (AddA (Left, Address (4 * J)),
+ AddA (Right, Address (4 * J)),
4, 4);
end if;
end loop;
return Compare_Array_S8_Unaligned
- (Left + Address (Clen4F),
- Right + Address (Clen4F),
+ (AddA (Left, Address (Clen4F)),
+ AddA (Right, Address (Clen4F)),
Left_Len - Clen4F,
Right_Len - Clen4F);
end;
@@ -110,8 +111,7 @@ package body System.Compare_Array_Signed_8 is
(Left : System.Address;
Right : System.Address;
Left_Len : Natural;
- Right_Len : Natural)
- return Integer
+ Right_Len : Natural) return Integer
is
Compare_Len : constant Natural := Natural'Min (Left_Len, Right_Len);
diff --git a/gcc/ada/s-carsi8.ads b/gcc/ada/s-carsi8.ads
index 64a52059e15..f810dd6a440 100644
--- a/gcc/ada/s-carsi8.ads
+++ b/gcc/ada/s-carsi8.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2002 Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2004 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- --
@@ -44,8 +44,7 @@ package System.Compare_Array_Signed_8 is
(Left : System.Address;
Right : System.Address;
Left_Len : Natural;
- Right_Len : Natural)
- return Integer;
+ Right_Len : Natural) return Integer;
-- Compare the array starting at address Left of length Left_Len
-- with the array starting at address Right of length Right_Len.
-- The comparison is in the normal Ada semantic sense of array
@@ -57,8 +56,7 @@ package System.Compare_Array_Signed_8 is
(Left : System.Address;
Right : System.Address;
Left_Len : Natural;
- Right_Len : Natural)
- return Integer;
+ Right_Len : Natural) return Integer;
-- Same functionality as Compare_Array_U8 but always proceeds by
-- bytes. Used when the caller knows that the operands are unaligned,
-- or short enough that it makes no sense to go by words.
diff --git a/gcc/ada/s-carun8.adb b/gcc/ada/s-carun8.adb
index 26a314e2c71..1c7348fa93d 100644
--- a/gcc/ada/s-carun8.adb
+++ b/gcc/ada/s-carun8.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2002 Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2004 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- --
@@ -31,6 +31,8 @@
-- --
------------------------------------------------------------------------------
+with System.Address_Operations; use System.Address_Operations;
+
with Unchecked_Conversion;
package body System.Compare_Array_Unsigned_8 is
@@ -63,15 +65,14 @@ package body System.Compare_Array_Unsigned_8 is
(Left : System.Address;
Right : System.Address;
Left_Len : Natural;
- Right_Len : Natural)
- return Integer
+ Right_Len : Natural) return Integer
is
Compare_Len : constant Natural := Natural'Min (Left_Len, Right_Len);
begin
-- If operands are non-aligned, or length is too short, go by bytes
- if (((Left or Right) and 2#11#) /= 0) or else Compare_Len < 4 then
+ if (ModA (OrA (Left, Right), 4) /= 0) or else Compare_Len < 4 then
return Compare_Array_U8_Unaligned (Left, Right, Left_Len, Right_Len);
end if;
@@ -87,15 +88,15 @@ package body System.Compare_Array_Unsigned_8 is
for J in 0 .. Clen4 loop
if LeftP (J) /= RightP (J) then
return Compare_Array_U8_Unaligned
- (Left + Address (4 * J),
- Right + Address (4 * J),
+ (AddA (Left, Address (4 * J)),
+ AddA (Right, Address (4 * J)),
4, 4);
end if;
end loop;
return Compare_Array_U8_Unaligned
- (Left + Address (Clen4F),
- Right + Address (Clen4F),
+ (AddA (Left, Address (Clen4F)),
+ AddA (Right, Address (Clen4F)),
Left_Len - Clen4F,
Right_Len - Clen4F);
end;
@@ -109,8 +110,7 @@ package body System.Compare_Array_Unsigned_8 is
(Left : System.Address;
Right : System.Address;
Left_Len : Natural;
- Right_Len : Natural)
- return Integer
+ Right_Len : Natural) return Integer
is
Compare_Len : constant Natural := Natural'Min (Left_Len, Right_Len);
diff --git a/gcc/ada/s-carun8.ads b/gcc/ada/s-carun8.ads
index e6ff79aa95a..1e3de470fd7 100644
--- a/gcc/ada/s-carun8.ads
+++ b/gcc/ada/s-carun8.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2002 Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2004 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- --
@@ -44,8 +44,7 @@ package System.Compare_Array_Unsigned_8 is
(Left : System.Address;
Right : System.Address;
Left_Len : Natural;
- Right_Len : Natural)
- return Integer;
+ Right_Len : Natural) return Integer;
-- Compare the array starting at address Left of length Left_Len
-- with the array starting at address Right of length Right_Len.
-- The comparison is in the normal Ada semantic sense of array
@@ -57,8 +56,7 @@ package System.Compare_Array_Unsigned_8 is
(Left : System.Address;
Right : System.Address;
Left_Len : Natural;
- Right_Len : Natural)
- return Integer;
+ Right_Len : Natural) return Integer;
-- Same functionality as Compare_Array_U8 but always proceeds by
-- bytes. Used when the caller knows that the operands are unaligned,
-- or short enough that it makes no sense to go by words.
diff --git a/gcc/ada/s-casi16.adb b/gcc/ada/s-casi16.adb
index dc417e3884d..03a8a9209b4 100644
--- a/gcc/ada/s-casi16.adb
+++ b/gcc/ada/s-casi16.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2002 Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2004 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- --
@@ -31,6 +31,8 @@
-- --
------------------------------------------------------------------------------
+with System.Address_Operations; use System.Address_Operations;
+
with Unchecked_Conversion;
package body System.Compare_Array_Signed_16 is
@@ -65,8 +67,7 @@ package body System.Compare_Array_Signed_16 is
(Left : System.Address;
Right : System.Address;
Left_Len : Natural;
- Right_Len : Natural)
- return Integer
+ Right_Len : Natural) return Integer
is
Clen : Natural := Natural'Min (Left_Len, Right_Len);
-- Number of elements left to compare
@@ -78,19 +79,19 @@ package body System.Compare_Array_Signed_16 is
begin
-- Go by words if possible
- if ((Left or Right) and (4 - 1)) = 0 then
+ if ModA (OrA (Left, Right), 4) = 0 then
while Clen > 1
and then W (L).all = W (R).all
loop
Clen := Clen - 2;
- L := L + 4;
- R := R + 4;
+ L := AddA (L, 4);
+ R := AddA (R, 4);
end loop;
end if;
-- Case of going by aligned half words
- if ((Left or Right) and (2 - 1)) = 0 then
+ if ModA (OrA (Left, Right), 2) = 0 then
while Clen /= 0 loop
if H (L).all /= H (R).all then
if H (L).all > H (R).all then
@@ -101,8 +102,8 @@ package body System.Compare_Array_Signed_16 is
end if;
Clen := Clen - 1;
- L := L + 2;
- R := R + 2;
+ L := AddA (L, 2);
+ R := AddA (R, 2);
end loop;
-- Case of going by unaligned half words
@@ -118,8 +119,8 @@ package body System.Compare_Array_Signed_16 is
end if;
Clen := Clen - 1;
- L := L + 2;
- R := R + 2;
+ L := AddA (L, 2);
+ R := AddA (R, 2);
end loop;
end if;
diff --git a/gcc/ada/s-casi16.ads b/gcc/ada/s-casi16.ads
index 234b360fae3..d3c226fb7f0 100644
--- a/gcc/ada/s-casi16.ads
+++ b/gcc/ada/s-casi16.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2002 Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2004 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- --
@@ -44,8 +44,7 @@ package System.Compare_Array_Signed_16 is
(Left : System.Address;
Right : System.Address;
Left_Len : Natural;
- Right_Len : Natural)
- return Integer;
+ Right_Len : Natural) return Integer;
-- Compare the array starting at address Left of length Left_Len
-- with the array starting at address Right of length Right_Len.
-- The comparison is in the normal Ada semantic sense of array
diff --git a/gcc/ada/s-casi32.adb b/gcc/ada/s-casi32.adb
index 2f280180ba4..e7322994469 100644
--- a/gcc/ada/s-casi32.adb
+++ b/gcc/ada/s-casi32.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2002 Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2004 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- --
@@ -31,6 +31,8 @@
-- --
------------------------------------------------------------------------------
+with System.Address_Operations; use System.Address_Operations;
+
with Unchecked_Conversion;
package body System.Compare_Array_Signed_32 is
@@ -60,8 +62,7 @@ package body System.Compare_Array_Signed_32 is
(Left : System.Address;
Right : System.Address;
Left_Len : Natural;
- Right_Len : Natural)
- return Integer
+ Right_Len : Natural) return Integer
is
Clen : Natural := Natural'Min (Left_Len, Right_Len);
-- Number of elements left to compare
@@ -73,7 +74,7 @@ package body System.Compare_Array_Signed_32 is
begin
-- Case of going by aligned words
- if ((Left or Right) and (4 - 1)) = 0 then
+ if ModA (OrA (Left, Right), 4) = 0 then
while Clen /= 0 loop
if W (L).all /= W (R).all then
if W (L).all > W (R).all then
@@ -84,8 +85,8 @@ package body System.Compare_Array_Signed_32 is
end if;
Clen := Clen - 1;
- L := L + 4;
- R := R + 4;
+ L := AddA (L, 4);
+ R := AddA (R, 4);
end loop;
-- Case of going by unaligned words
@@ -101,8 +102,8 @@ package body System.Compare_Array_Signed_32 is
end if;
Clen := Clen - 1;
- L := L + 4;
- R := R + 4;
+ L := AddA (L, 4);
+ R := AddA (R, 4);
end loop;
end if;
diff --git a/gcc/ada/s-casi32.ads b/gcc/ada/s-casi32.ads
index c97911d8812..de35addd48a 100644
--- a/gcc/ada/s-casi32.ads
+++ b/gcc/ada/s-casi32.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2002 Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2004 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- --
diff --git a/gcc/ada/s-casi64.adb b/gcc/ada/s-casi64.adb
index 5d6cea980e9..9caf3ab80cd 100644
--- a/gcc/ada/s-casi64.adb
+++ b/gcc/ada/s-casi64.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2002 Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2004 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- --
@@ -31,6 +31,8 @@
-- --
------------------------------------------------------------------------------
+with System.Address_Operations; use System.Address_Operations;
+
with Unchecked_Conversion;
package body System.Compare_Array_Signed_64 is
@@ -60,8 +62,7 @@ package body System.Compare_Array_Signed_64 is
(Left : System.Address;
Right : System.Address;
Left_Len : Natural;
- Right_Len : Natural)
- return Integer
+ Right_Len : Natural) return Integer
is
Clen : Natural := Natural'Min (Left_Len, Right_Len);
-- Number of elements left to compare
@@ -71,9 +72,9 @@ package body System.Compare_Array_Signed_64 is
-- Pointers to next elements to compare
begin
- -- Case of going by aligned words
+ -- Case of going by aligned double words
- if ((Left or Right) and (8 - 1)) = 0 then
+ if ModA (OrA (Left, Right), 8) = 0 then
while Clen /= 0 loop
if W (L).all /= W (R).all then
if W (L).all > W (R).all then
@@ -84,11 +85,11 @@ package body System.Compare_Array_Signed_64 is
end if;
Clen := Clen - 1;
- L := L + 8;
- R := R + 8;
+ L := AddA (L, 8);
+ R := AddA (R, 8);
end loop;
- -- Case of going by unaligned words
+ -- Case of going by unaligned double words
else
while Clen /= 0 loop
@@ -101,8 +102,8 @@ package body System.Compare_Array_Signed_64 is
end if;
Clen := Clen - 1;
- L := L + 8;
- R := R + 8;
+ L := AddA (L, 8);
+ R := AddA (R, 8);
end loop;
end if;
diff --git a/gcc/ada/s-casi64.ads b/gcc/ada/s-casi64.ads
index bc4d3b23ebc..0215badacb3 100644
--- a/gcc/ada/s-casi64.ads
+++ b/gcc/ada/s-casi64.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2002 Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2004 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- --
@@ -44,8 +44,7 @@ package System.Compare_Array_Signed_64 is
(Left : System.Address;
Right : System.Address;
Left_Len : Natural;
- Right_Len : Natural)
- return Integer;
+ Right_Len : Natural) return Integer;
-- Compare the array starting at address Left of length Left_Len
-- with the array starting at address Right of length Right_Len.
-- The comparison is in the normal Ada semantic sense of array
diff --git a/gcc/ada/s-caun16.adb b/gcc/ada/s-caun16.adb
index c9d1ffa3a94..57e1522bc08 100644
--- a/gcc/ada/s-caun16.adb
+++ b/gcc/ada/s-caun16.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2002 Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2004 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- --
@@ -31,6 +31,8 @@
-- --
------------------------------------------------------------------------------
+with System.Address_Operations; use System.Address_Operations;
+
with Unchecked_Conversion;
package body System.Compare_Array_Unsigned_16 is
@@ -65,8 +67,7 @@ package body System.Compare_Array_Unsigned_16 is
(Left : System.Address;
Right : System.Address;
Left_Len : Natural;
- Right_Len : Natural)
- return Integer
+ Right_Len : Natural) return Integer
is
Clen : Natural := Natural'Min (Left_Len, Right_Len);
-- Number of elements left to compare
@@ -78,19 +79,19 @@ package body System.Compare_Array_Unsigned_16 is
begin
-- Go by words if possible
- if ((Left or Right) and (4 - 1)) = 0 then
+ if ModA (OrA (Left, Right), 4) = 0 then
while Clen > 1
and then W (L).all = W (R).all
loop
Clen := Clen - 2;
- L := L + 4;
- R := R + 4;
+ L := AddA (L, 4);
+ R := AddA (R, 4);
end loop;
end if;
-- Case of going by aligned half words
- if ((Left or Right) and (2 - 1)) = 0 then
+ if ModA (OrA (Left, Right), 2) = 0 then
while Clen /= 0 loop
if H (L).all /= H (R).all then
if H (L).all > H (R).all then
@@ -101,8 +102,8 @@ package body System.Compare_Array_Unsigned_16 is
end if;
Clen := Clen - 1;
- L := L + 2;
- R := R + 2;
+ L := AddA (L, 2);
+ R := AddA (R, 2);
end loop;
-- Case of going by unaligned half words
@@ -118,8 +119,8 @@ package body System.Compare_Array_Unsigned_16 is
end if;
Clen := Clen - 1;
- L := L + 2;
- R := R + 2;
+ L := AddA (L, 2);
+ R := AddA (R, 2);
end loop;
end if;
diff --git a/gcc/ada/s-caun16.ads b/gcc/ada/s-caun16.ads
index e395c378b49..5bf4e352b63 100644
--- a/gcc/ada/s-caun16.ads
+++ b/gcc/ada/s-caun16.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2002 Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2004 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- --
@@ -44,8 +44,7 @@ package System.Compare_Array_Unsigned_16 is
(Left : System.Address;
Right : System.Address;
Left_Len : Natural;
- Right_Len : Natural)
- return Integer;
+ Right_Len : Natural) return Integer;
-- Compare the array starting at address Left of length Left_Len
-- with the array starting at address Right of length Right_Len.
-- The comparison is in the normal Ada semantic sense of array
diff --git a/gcc/ada/s-caun32.adb b/gcc/ada/s-caun32.adb
index 830312f5f8e..ff55d65822d 100644
--- a/gcc/ada/s-caun32.adb
+++ b/gcc/ada/s-caun32.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2002 Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2004 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- --
@@ -31,6 +31,8 @@
-- --
------------------------------------------------------------------------------
+with System.Address_Operations; use System.Address_Operations;
+
with Unchecked_Conversion;
package body System.Compare_Array_Unsigned_32 is
@@ -60,8 +62,7 @@ package body System.Compare_Array_Unsigned_32 is
(Left : System.Address;
Right : System.Address;
Left_Len : Natural;
- Right_Len : Natural)
- return Integer
+ Right_Len : Natural) return Integer
is
Clen : Natural := Natural'Min (Left_Len, Right_Len);
-- Number of elements left to compare
@@ -73,7 +74,7 @@ package body System.Compare_Array_Unsigned_32 is
begin
-- Case of going by aligned words
- if ((Left or Right) and (4 - 1)) = 0 then
+ if ModA (OrA (Left, Right), 4) = 0 then
while Clen /= 0 loop
if W (L).all /= W (R).all then
if W (L).all > W (R).all then
@@ -84,8 +85,8 @@ package body System.Compare_Array_Unsigned_32 is
end if;
Clen := Clen - 1;
- L := L + 4;
- R := R + 4;
+ L := AddA (L, 4);
+ R := AddA (R, 4);
end loop;
-- Case of going by unaligned words
@@ -101,8 +102,8 @@ package body System.Compare_Array_Unsigned_32 is
end if;
Clen := Clen - 1;
- L := L + 4;
- R := R + 4;
+ L := AddA (L, 4);
+ R := AddA (R, 4);
end loop;
end if;
diff --git a/gcc/ada/s-caun32.ads b/gcc/ada/s-caun32.ads
index 0ca7d0c7c00..9c6fb8da666 100644
--- a/gcc/ada/s-caun32.ads
+++ b/gcc/ada/s-caun32.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2002 Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2004 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- --
@@ -44,8 +44,7 @@ package System.Compare_Array_Unsigned_32 is
(Left : System.Address;
Right : System.Address;
Left_Len : Natural;
- Right_Len : Natural)
- return Integer;
+ Right_Len : Natural) return Integer;
-- Compare the array starting at address Left of length Left_Len
-- with the array starting at address Right of length Right_Len.
-- The comparison is in the normal Ada semantic sense of array
diff --git a/gcc/ada/s-caun64.adb b/gcc/ada/s-caun64.adb
index c05a47f0a4d..08fd9f2501b 100644
--- a/gcc/ada/s-caun64.adb
+++ b/gcc/ada/s-caun64.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2002 Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2004 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- --
@@ -31,6 +31,8 @@
-- --
------------------------------------------------------------------------------
+with System.Address_Operations; use System.Address_Operations;
+
with Unchecked_Conversion;
package body System.Compare_Array_Unsigned_64 is
@@ -59,8 +61,7 @@ package body System.Compare_Array_Unsigned_64 is
(Left : System.Address;
Right : System.Address;
Left_Len : Natural;
- Right_Len : Natural)
- return Integer
+ Right_Len : Natural) return Integer
is
Clen : Natural := Natural'Min (Left_Len, Right_Len);
-- Number of elements left to compare
@@ -70,9 +71,9 @@ package body System.Compare_Array_Unsigned_64 is
-- Pointers to next elements to compare
begin
- -- Case of going by aligned words
+ -- Case of going by aligned double words
- if ((Left or Right) and (8 - 1)) = 0 then
+ if ModA (OrA (Left, Right), 8) = 0 then
while Clen /= 0 loop
if W (L).all /= W (R).all then
if W (L).all > W (R).all then
@@ -83,11 +84,11 @@ package body System.Compare_Array_Unsigned_64 is
end if;
Clen := Clen - 1;
- L := L + 8;
- R := R + 8;
+ L := AddA (L, 8);
+ R := AddA (R, 8);
end loop;
- -- Case of going by unaligned words
+ -- Case of going by unaligned double words
else
while Clen /= 0 loop
@@ -100,8 +101,8 @@ package body System.Compare_Array_Unsigned_64 is
end if;
Clen := Clen - 1;
- L := L + 8;
- R := R + 8;
+ L := AddA (L, 8);
+ R := AddA (R, 8);
end loop;
end if;
diff --git a/gcc/ada/s-caun64.ads b/gcc/ada/s-caun64.ads
index b0446d6416c..c8421902b5d 100644
--- a/gcc/ada/s-caun64.ads
+++ b/gcc/ada/s-caun64.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2002 Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2004 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- --
@@ -44,8 +44,7 @@ package System.Compare_Array_Unsigned_64 is
(Left : System.Address;
Right : System.Address;
Left_Len : Natural;
- Right_Len : Natural)
- return Integer;
+ Right_Len : Natural) return Integer;
-- Compare the array starting at address Left of length Left_Len
-- with the array starting at address Right of length Right_Len.
-- The comparison is in the normal Ada semantic sense of array
diff --git a/gcc/ada/s-finimp.adb b/gcc/ada/s-finimp.adb
index a6c00bfcd19..41245373d59 100644
--- a/gcc/ada/s-finimp.adb
+++ b/gcc/ada/s-finimp.adb
@@ -499,10 +499,11 @@ package body System.Finalization_Implementation is
-- Reconstruction of a type with characteristics
-- comparable to the original type
- D : constant := Storage_Unit - 1;
+ D : constant := SSE.Storage_Offset (Storage_Unit - 1);
type Parent_Type is new SSE.Storage_Array
- (1 .. (Parent_Size (Obj, The_Tag) + D) / Storage_Unit);
+ (1 .. (Parent_Size (Obj, The_Tag) + D) /
+ SSE.Storage_Offset (Storage_Unit));
for Parent_Type'Alignment use Address'Alignment;
type Faked_Type_Of_Obj is record
diff --git a/gcc/ada/s-geveop.adb b/gcc/ada/s-geveop.adb
index 1820bdf2a47..be7b0a6d27e 100644
--- a/gcc/ada/s-geveop.adb
+++ b/gcc/ada/s-geveop.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2002-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2004 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- --
@@ -31,13 +31,17 @@
-- --
------------------------------------------------------------------------------
-with System; use System;
-with System.Storage_Elements; use System.Storage_Elements;
-with Ada.Unchecked_Conversion; use Ada;
+with System; use System;
+with System.Address_Operations; use System.Address_Operations;
+with System.Storage_Elements; use System.Storage_Elements;
+
+with Unchecked_Conversion;
package body System.Generic_Vector_Operations is
- VU : constant Address := Vectors.Vector'Size / Storage_Unit;
- EU : constant Address := Element_Array'Component_Size / Storage_Unit;
+
+ IU : constant Integer := Integer (Storage_Unit);
+ VU : constant Address := Address (Vectors.Vector'Size / IU);
+ EU : constant Address := Address (Element_Array'Component_Size / IU);
----------------------
-- Binary_Operation --
@@ -52,8 +56,11 @@ package body System.Generic_Vector_Operations is
YA : Address := Y;
-- Address of next element to process in R, X and Y
- Unaligned : constant Boolean := (RA or XA or YA) mod VU /= 0;
- -- False iff one or more argument addresses is not aligned
+ VI : constant Integer_Address := To_Integer (VU);
+
+ Unaligned : constant Integer_Address :=
+ Boolean'Pos (ModA (OrA (OrA (RA, XA), YA), VU) /= 0) - 1;
+ -- Zero iff one or more argument addresses is not aligned, else all 1's
type Vector_Ptr is access all Vectors.Vector;
type Element_Ptr is access all Element;
@@ -61,23 +68,24 @@ package body System.Generic_Vector_Operations is
function VP is new Unchecked_Conversion (Address, Vector_Ptr);
function EP is new Unchecked_Conversion (Address, Element_Ptr);
- SA : constant Address := XA + ((Length + 0) / VU * VU
- and (Boolean'Pos (Unaligned) - Address'(1)));
+ SA : constant Address :=
+ AddA (XA, To_Address
+ ((Integer_Address (Length) / VI * VI) and Unaligned));
-- First address of argument X to start serial processing
begin
while XA < SA loop
VP (RA).all := Vector_Op (VP (XA).all, VP (YA).all);
- XA := XA + VU;
- YA := YA + VU;
- RA := RA + VU;
+ XA := AddA (XA, VU);
+ YA := AddA (YA, VU);
+ RA := AddA (RA, VU);
end loop;
while XA < X + Length loop
EP (RA).all := Element_Op (EP (XA).all, EP (YA).all);
- XA := XA + EU;
- YA := YA + EU;
- RA := RA + EU;
+ XA := AddA (XA, EU);
+ YA := AddA (YA, EU);
+ RA := AddA (RA, EU);
end loop;
end Binary_Operation;
@@ -93,8 +101,11 @@ package body System.Generic_Vector_Operations is
XA : Address := X;
-- Address of next element to process in R and X
- Unaligned : constant Boolean := (RA or XA) mod VU /= 0;
- -- False iff one or more argument addresses is not aligned
+ VI : constant Integer_Address := To_Integer (VU);
+
+ Unaligned : constant Integer_Address :=
+ Boolean'Pos (ModA (OrA (RA, XA), VU) /= 0) - 1;
+ -- Zero iff one or more argument addresses is not aligned, else all 1's
type Vector_Ptr is access all Vectors.Vector;
type Element_Ptr is access all Element;
@@ -102,21 +113,22 @@ package body System.Generic_Vector_Operations is
function VP is new Unchecked_Conversion (Address, Vector_Ptr);
function EP is new Unchecked_Conversion (Address, Element_Ptr);
- SA : constant Address := XA + ((Length + 0) / VU * VU
- and (Boolean'Pos (Unaligned) - Address'(1)));
+ SA : constant Address :=
+ AddA (XA, To_Address
+ ((Integer_Address (Length) / VI * VI) and Unaligned));
-- First address of argument X to start serial processing
begin
while XA < SA loop
VP (RA).all := Vector_Op (VP (XA).all);
- XA := XA + VU;
- RA := RA + VU;
+ XA := AddA (XA, VU);
+ RA := AddA (RA, VU);
end loop;
while XA < X + Length loop
EP (RA).all := Element_Op (EP (XA).all);
- XA := XA + EU;
- RA := RA + EU;
+ XA := AddA (XA, EU);
+ RA := AddA (RA, EU);
end loop;
end Unary_Operation;
diff --git a/gcc/ada/s-gloloc-mingw.adb b/gcc/ada/s-gloloc-mingw.adb
new file mode 100644
index 00000000000..2b775b239db
--- /dev/null
+++ b/gcc/ada/s-gloloc-mingw.adb
@@ -0,0 +1,113 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . G L O B A L _ L O C K S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1999-2001 Ada Core Technologies, 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This implementation is specific to NT.
+
+with GNAT.Task_Lock;
+
+with Interfaces.C.Strings;
+with System.OS_Interface;
+
+package body System.Global_Locks is
+
+ package TSL renames GNAT.Task_Lock;
+ package OSI renames System.OS_Interface;
+ package ICS renames Interfaces.C.Strings;
+
+ subtype Lock_File_Entry is OSI.HANDLE;
+
+ Last_Lock : Lock_Type := Null_Lock;
+ Lock_Table : array (Lock_Type range 1 .. 15) of Lock_File_Entry;
+
+ -----------------
+ -- Create_Lock --
+ -----------------
+
+ procedure Create_Lock
+ (Lock : out Lock_Type;
+ Name : in String)
+ is
+ L : Lock_Type;
+
+ begin
+ TSL.Lock;
+ Last_Lock := Last_Lock + 1;
+ L := Last_Lock;
+ TSL.Unlock;
+
+ if L > Lock_Table'Last then
+ raise Lock_Error;
+ end if;
+
+ Lock_Table (L) :=
+ OSI.CreateMutex (null, OSI.BOOL (False), ICS.New_String (Name));
+ Lock := L;
+ end Create_Lock;
+
+ ------------------
+ -- Acquire_Lock --
+ ------------------
+
+ procedure Acquire_Lock
+ (Lock : in out Lock_Type)
+ is
+ use type OSI.DWORD;
+
+ Res : OSI.DWORD;
+ begin
+ Res := OSI.WaitForSingleObject (Lock_Table (Lock), OSI.Wait_Infinite);
+
+ if Res = OSI.WAIT_FAILED then
+ raise Lock_Error;
+ end if;
+ end Acquire_Lock;
+
+ ------------------
+ -- Release_Lock --
+ ------------------
+
+ procedure Release_Lock
+ (Lock : in out Lock_Type)
+ is
+ use type OSI.BOOL;
+
+ Res : OSI.BOOL;
+ begin
+ Res := OSI.ReleaseMutex (Lock_Table (Lock));
+
+ if Res = OSI.False then
+ raise Lock_Error;
+ end if;
+ end Release_Lock;
+
+end System.Global_Locks;
diff --git a/gcc/ada/s-inmaop-dummy.adb b/gcc/ada/s-inmaop-dummy.adb
new file mode 100644
index 00000000000..f99a104f671
--- /dev/null
+++ b/gcc/ada/s-inmaop-dummy.adb
@@ -0,0 +1,194 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- SYSTEM.INTERRUPT_MANAGEMENT.OPERATIONS --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2001 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- --
+-- 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, 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, --
+-- 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 is a NO tasking version of this package.
+
+package body System.Interrupt_Management.Operations is
+
+ -- Turn off warnings since many unused formals
+
+ pragma Warnings (Off);
+
+ ----------------------------
+ -- Thread_Block_Interrupt --
+ ----------------------------
+
+ procedure Thread_Block_Interrupt
+ (Interrupt : Interrupt_ID)
+ is
+ begin
+ null;
+ end Thread_Block_Interrupt;
+
+ ------------------------------
+ -- Thread_Unblock_Interrupt --
+ ------------------------------
+
+ procedure Thread_Unblock_Interrupt
+ (Interrupt : Interrupt_ID)
+ is
+ begin
+ null;
+ end Thread_Unblock_Interrupt;
+
+ ------------------------
+ -- Set_Interrupt_Mask --
+ ------------------------
+
+ procedure Set_Interrupt_Mask (Mask : access Interrupt_Mask) is
+ begin
+ null;
+ end Set_Interrupt_Mask;
+
+ procedure Set_Interrupt_Mask
+ (Mask : access Interrupt_Mask;
+ OMask : access Interrupt_Mask) is
+ begin
+ null;
+ end Set_Interrupt_Mask;
+
+ ------------------------
+ -- Get_Interrupt_Mask --
+ ------------------------
+
+ procedure Get_Interrupt_Mask (Mask : access Interrupt_Mask) is
+ begin
+ null;
+ end Get_Interrupt_Mask;
+
+ --------------------
+ -- Interrupt_Wait --
+ --------------------
+
+ function Interrupt_Wait
+ (Mask : access Interrupt_Mask)
+ return Interrupt_ID
+ is
+ begin
+ return 0;
+ end Interrupt_Wait;
+
+ ----------------------------
+ -- Install_Default_Action --
+ ----------------------------
+
+ procedure Install_Default_Action (Interrupt : Interrupt_ID) is
+ begin
+ null;
+ end Install_Default_Action;
+
+ ---------------------------
+ -- Install_Ignore_Action --
+ ---------------------------
+
+ procedure Install_Ignore_Action (Interrupt : Interrupt_ID) is
+ begin
+ null;
+ end Install_Ignore_Action;
+
+ -------------------------
+ -- Fill_Interrupt_Mask --
+ -------------------------
+
+ procedure Fill_Interrupt_Mask (Mask : access Interrupt_Mask) is
+ begin
+ null;
+ end Fill_Interrupt_Mask;
+
+ --------------------------
+ -- Empty_Interrupt_Mask --
+ --------------------------
+
+ procedure Empty_Interrupt_Mask (Mask : access Interrupt_Mask) is
+ begin
+ null;
+ end Empty_Interrupt_Mask;
+
+ -----------------------
+ -- Add_To_Sigal_Mask --
+ -----------------------
+
+ procedure Add_To_Interrupt_Mask
+ (Mask : access Interrupt_Mask;
+ Interrupt : Interrupt_ID)
+ is
+ begin
+ null;
+ end Add_To_Interrupt_Mask;
+
+ --------------------------------
+ -- Delete_From_Interrupt_Mask --
+ --------------------------------
+
+ procedure Delete_From_Interrupt_Mask
+ (Mask : access Interrupt_Mask;
+ Interrupt : Interrupt_ID)
+ is
+ begin
+ null;
+ end Delete_From_Interrupt_Mask;
+
+ ---------------
+ -- Is_Member --
+ ---------------
+
+ function Is_Member
+ (Mask : access Interrupt_Mask;
+ Interrupt : Interrupt_ID) return Boolean
+ is
+ begin
+ return False;
+ end Is_Member;
+
+ -------------------------
+ -- Copy_Interrupt_Mask --
+ -------------------------
+
+ procedure Copy_Interrupt_Mask
+ (X : out Interrupt_Mask;
+ Y : Interrupt_Mask)
+ is
+ begin
+ X := Y;
+ end Copy_Interrupt_Mask;
+
+ -------------------------
+ -- Interrupt_Self_Process --
+ -------------------------
+
+ procedure Interrupt_Self_Process (Interrupt : Interrupt_ID) is
+ begin
+ null;
+ end Interrupt_Self_Process;
+
+end System.Interrupt_Management.Operations;
diff --git a/gcc/ada/s-inmaop-posix.adb b/gcc/ada/s-inmaop-posix.adb
new file mode 100644
index 00000000000..8fe6b3a89bd
--- /dev/null
+++ b/gcc/ada/s-inmaop-posix.adb
@@ -0,0 +1,359 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- SYSTEM.INTERRUPT_MANAGEMENT.OPERATIONS --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2003, Ada Core Technologies --
+-- --
+-- 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, 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, --
+-- 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 is a POSIX-like version of this package.
+-- Note: this file can only be used for POSIX compliant systems.
+
+with Interfaces.C;
+-- used for int
+-- size_t
+-- unsigned
+
+with System.OS_Interface;
+-- used for various type, constant, and operations
+
+with System.Storage_Elements;
+-- used for To_Address
+-- Integer_Address
+
+with Unchecked_Conversion;
+
+package body System.Interrupt_Management.Operations is
+
+ use Interfaces.C;
+ use System.OS_Interface;
+
+ type Interrupt_Mask_Ptr is access all Interrupt_Mask;
+
+ function "+" is new
+ Unchecked_Conversion (Interrupt_Mask_Ptr, sigset_t_ptr);
+
+ ---------------------
+ -- Local Variables --
+ ---------------------
+
+ Initial_Action : array (Signal) of aliased struct_sigaction;
+
+ Default_Action : aliased struct_sigaction;
+
+ Ignore_Action : aliased struct_sigaction;
+
+ ----------------------------
+ -- Thread_Block_Interrupt --
+ ----------------------------
+
+ procedure Thread_Block_Interrupt
+ (Interrupt : Interrupt_ID)
+ is
+ Result : Interfaces.C.int;
+ Mask : aliased sigset_t;
+
+ begin
+ Result := sigemptyset (Mask'Access);
+ pragma Assert (Result = 0);
+ Result := sigaddset (Mask'Access, Signal (Interrupt));
+ pragma Assert (Result = 0);
+ Result := pthread_sigmask (SIG_BLOCK, Mask'Unchecked_Access, null);
+ pragma Assert (Result = 0);
+ end Thread_Block_Interrupt;
+
+ ------------------------------
+ -- Thread_Unblock_Interrupt --
+ ------------------------------
+
+ procedure Thread_Unblock_Interrupt
+ (Interrupt : Interrupt_ID)
+ is
+ Mask : aliased sigset_t;
+ Result : Interfaces.C.int;
+
+ begin
+ Result := sigemptyset (Mask'Access);
+ pragma Assert (Result = 0);
+ Result := sigaddset (Mask'Access, Signal (Interrupt));
+ pragma Assert (Result = 0);
+ Result := pthread_sigmask (SIG_UNBLOCK, Mask'Unchecked_Access, null);
+ pragma Assert (Result = 0);
+ end Thread_Unblock_Interrupt;
+
+ ------------------------
+ -- Set_Interrupt_Mask --
+ ------------------------
+
+ procedure Set_Interrupt_Mask (Mask : access Interrupt_Mask) is
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_sigmask
+ (SIG_SETMASK, +Interrupt_Mask_Ptr (Mask), null);
+ pragma Assert (Result = 0);
+ end Set_Interrupt_Mask;
+
+ procedure Set_Interrupt_Mask
+ (Mask : access Interrupt_Mask;
+ OMask : access Interrupt_Mask)
+ is
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_sigmask
+ (SIG_SETMASK, +Interrupt_Mask_Ptr (Mask), +Interrupt_Mask_Ptr (OMask));
+ pragma Assert (Result = 0);
+ end Set_Interrupt_Mask;
+
+ ------------------------
+ -- Get_Interrupt_Mask --
+ ------------------------
+
+ procedure Get_Interrupt_Mask (Mask : access Interrupt_Mask) is
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_sigmask
+ (SIG_SETMASK, null, +Interrupt_Mask_Ptr (Mask));
+ pragma Assert (Result = 0);
+ end Get_Interrupt_Mask;
+
+ --------------------
+ -- Interrupt_Wait --
+ --------------------
+
+ function Interrupt_Wait
+ (Mask : access Interrupt_Mask)
+ return Interrupt_ID
+ is
+ Result : Interfaces.C.int;
+ Sig : aliased Signal;
+
+ begin
+ Result := sigwait (Mask, Sig'Access);
+
+ if Result /= 0 then
+ return 0;
+ end if;
+
+ return Interrupt_ID (Sig);
+ end Interrupt_Wait;
+
+ ----------------------------
+ -- Install_Default_Action --
+ ----------------------------
+
+ procedure Install_Default_Action (Interrupt : Interrupt_ID) is
+ Result : Interfaces.C.int;
+
+ begin
+ Result := sigaction
+ (Signal (Interrupt),
+ Initial_Action (Signal (Interrupt))'Access, null);
+ pragma Assert (Result = 0);
+ end Install_Default_Action;
+
+ ---------------------------
+ -- Install_Ignore_Action --
+ ---------------------------
+
+ procedure Install_Ignore_Action (Interrupt : Interrupt_ID) is
+ Result : Interfaces.C.int;
+
+ begin
+ Result := sigaction (Signal (Interrupt), Ignore_Action'Access, null);
+ pragma Assert (Result = 0);
+ end Install_Ignore_Action;
+
+ -------------------------
+ -- Fill_Interrupt_Mask --
+ -------------------------
+
+ procedure Fill_Interrupt_Mask (Mask : access Interrupt_Mask) is
+ Result : Interfaces.C.int;
+
+ begin
+ Result := sigfillset (Mask);
+ pragma Assert (Result = 0);
+ end Fill_Interrupt_Mask;
+
+ --------------------------
+ -- Empty_Interrupt_Mask --
+ --------------------------
+
+ procedure Empty_Interrupt_Mask (Mask : access Interrupt_Mask) is
+ Result : Interfaces.C.int;
+
+ begin
+ Result := sigemptyset (Mask);
+ pragma Assert (Result = 0);
+ end Empty_Interrupt_Mask;
+
+ ---------------------------
+ -- Add_To_Interrupt_Mask --
+ ---------------------------
+
+ procedure Add_To_Interrupt_Mask
+ (Mask : access Interrupt_Mask;
+ Interrupt : Interrupt_ID)
+ is
+ Result : Interfaces.C.int;
+
+ begin
+ Result := sigaddset (Mask, Signal (Interrupt));
+ pragma Assert (Result = 0);
+ end Add_To_Interrupt_Mask;
+
+ --------------------------------
+ -- Delete_From_Interrupt_Mask --
+ --------------------------------
+
+ procedure Delete_From_Interrupt_Mask
+ (Mask : access Interrupt_Mask;
+ Interrupt : Interrupt_ID)
+ is
+ Result : Interfaces.C.int;
+
+ begin
+ Result := sigdelset (Mask, Signal (Interrupt));
+ pragma Assert (Result = 0);
+ end Delete_From_Interrupt_Mask;
+
+ ---------------
+ -- Is_Member --
+ ---------------
+
+ function Is_Member
+ (Mask : access Interrupt_Mask;
+ Interrupt : Interrupt_ID) return Boolean
+ is
+ Result : Interfaces.C.int;
+
+ begin
+ Result := sigismember (Mask, Signal (Interrupt));
+ pragma Assert (Result = 0 or else Result = 1);
+ return Result = 1;
+ end Is_Member;
+
+ -------------------------
+ -- Copy_Interrupt_Mask --
+ -------------------------
+
+ procedure Copy_Interrupt_Mask
+ (X : out Interrupt_Mask;
+ Y : Interrupt_Mask)
+ is
+ begin
+ X := Y;
+ end Copy_Interrupt_Mask;
+
+ ----------------------------
+ -- Interrupt_Self_Process --
+ ----------------------------
+
+ procedure Interrupt_Self_Process (Interrupt : Interrupt_ID) is
+ Result : Interfaces.C.int;
+
+ begin
+ Result := kill (getpid, Signal (Interrupt));
+ pragma Assert (Result = 0);
+ end Interrupt_Self_Process;
+
+begin
+
+ declare
+ mask : aliased sigset_t;
+ allmask : aliased sigset_t;
+ Result : Interfaces.C.int;
+
+ begin
+ for Sig in 1 .. Signal'Last loop
+ Result := sigaction
+ (Sig, null, Initial_Action (Sig)'Unchecked_Access);
+
+ -- ??? [assert 1]
+ -- we can't check Result here since sigaction will fail on
+ -- SIGKILL, SIGSTOP, and possibly other signals
+ -- pragma Assert (Result = 0);
+
+ end loop;
+
+ -- Setup the masks to be exported.
+
+ Result := sigemptyset (mask'Access);
+ pragma Assert (Result = 0);
+
+ Result := sigfillset (allmask'Access);
+ pragma Assert (Result = 0);
+
+ Default_Action.sa_flags := 0;
+ Default_Action.sa_mask := mask;
+ Default_Action.sa_handler :=
+ Storage_Elements.To_Address
+ (Storage_Elements.Integer_Address (SIG_DFL));
+
+ Ignore_Action.sa_flags := 0;
+ Ignore_Action.sa_mask := mask;
+ Ignore_Action.sa_handler :=
+ Storage_Elements.To_Address
+ (Storage_Elements.Integer_Address (SIG_IGN));
+
+ for J in Interrupt_ID loop
+
+ -- We need to check whether J is in Keep_Unmasked because
+ -- the index type of the Keep_Unmasked array is not always
+ -- Interrupt_ID; it may be a subtype of Interrupt_ID.
+
+ if J in Keep_Unmasked'Range and then Keep_Unmasked (J) then
+ Result := sigaddset (mask'Access, Signal (J));
+ pragma Assert (Result = 0);
+ Result := sigdelset (allmask'Access, Signal (J));
+ pragma Assert (Result = 0);
+ end if;
+ end loop;
+
+ -- The Keep_Unmasked signals should be unmasked for Environment task
+
+ Result := pthread_sigmask (SIG_UNBLOCK, mask'Unchecked_Access, null);
+ pragma Assert (Result = 0);
+
+ -- Get the signal mask of the Environment Task
+
+ Result := pthread_sigmask (SIG_SETMASK, null, mask'Unchecked_Access);
+ pragma Assert (Result = 0);
+
+ -- Setup the constants exported
+
+ Environment_Mask := Interrupt_Mask (mask);
+
+ All_Tasks_Mask := Interrupt_Mask (allmask);
+ end;
+
+end System.Interrupt_Management.Operations;
diff --git a/gcc/ada/s-inmaop-vms.adb b/gcc/ada/s-inmaop-vms.adb
new file mode 100644
index 00000000000..2cbfd0eb715
--- /dev/null
+++ b/gcc/ada/s-inmaop-vms.adb
@@ -0,0 +1,298 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . I N T E R R U P T _ M A N A G E M E N T . --
+-- O P E R A T I O N S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2004 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- --
+-- 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, 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, --
+-- 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 is a OpenVMS/Alpha version of this package.
+
+with System.OS_Interface;
+-- used for various type, constant, and operations
+
+with System.Aux_DEC;
+-- used for Short_Address
+
+with System.Parameters;
+
+with System.Tasking;
+
+with System.Tasking.Initialization;
+
+with System.Task_Primitives.Operations;
+
+with System.Task_Primitives.Operations.DEC;
+
+with Unchecked_Conversion;
+
+package body System.Interrupt_Management.Operations is
+
+ use System.OS_Interface;
+ use System.Parameters;
+ use System.Tasking;
+ use type unsigned_short;
+
+ function To_Address is new Unchecked_Conversion (Task_ID, System.Address);
+ package POP renames System.Task_Primitives.Operations;
+
+ ----------------------------
+ -- Thread_Block_Interrupt --
+ ----------------------------
+
+ procedure Thread_Block_Interrupt (Interrupt : Interrupt_ID) is
+ pragma Warnings (Off, Interrupt);
+ begin
+ null;
+ end Thread_Block_Interrupt;
+
+ ------------------------------
+ -- Thread_Unblock_Interrupt --
+ ------------------------------
+
+ procedure Thread_Unblock_Interrupt (Interrupt : Interrupt_ID) is
+ pragma Warnings (Off, Interrupt);
+ begin
+ null;
+ end Thread_Unblock_Interrupt;
+
+ ------------------------
+ -- Set_Interrupt_Mask --
+ ------------------------
+
+ procedure Set_Interrupt_Mask (Mask : access Interrupt_Mask) is
+ pragma Warnings (Off, Mask);
+ begin
+ null;
+ end Set_Interrupt_Mask;
+
+ procedure Set_Interrupt_Mask
+ (Mask : access Interrupt_Mask;
+ OMask : access Interrupt_Mask)
+ is
+ pragma Warnings (Off, Mask);
+ pragma Warnings (Off, OMask);
+ begin
+ null;
+ end Set_Interrupt_Mask;
+
+ ------------------------
+ -- Get_Interrupt_Mask --
+ ------------------------
+
+ procedure Get_Interrupt_Mask (Mask : access Interrupt_Mask) is
+ pragma Warnings (Off, Mask);
+ begin
+ null;
+ end Get_Interrupt_Mask;
+
+ --------------------
+ -- Interrupt_Wait --
+ --------------------
+
+ function To_unsigned_long is new
+ Unchecked_Conversion (System.Aux_DEC.Short_Address, unsigned_long);
+
+ function Interrupt_Wait (Mask : access Interrupt_Mask)
+ return Interrupt_ID
+ is
+ Self_ID : constant Task_ID := Self;
+ Iosb : IO_Status_Block_Type := (0, 0, 0);
+ Status : Cond_Value_Type;
+
+ begin
+
+ -- A QIO read is registered. The system call returns immediately
+ -- after scheduling an AST to be fired when the operation
+ -- completes.
+
+ Sys_QIO
+ (Status => Status,
+ Chan => Rcv_Interrupt_Chan,
+ Func => IO_READVBLK,
+ Iosb => Iosb,
+ Astadr =>
+ POP.DEC.Interrupt_AST_Handler'Access,
+ Astprm => To_Address (Self_ID),
+ P1 => To_unsigned_long (Interrupt_Mailbox'Address),
+ P2 => Interrupt_ID'Size / 8);
+
+ pragma Assert ((Status and 1) = 1);
+
+ loop
+
+ -- Wait to be woken up. Could be that the AST has fired,
+ -- in which case the Iosb.Status variable will be non-zero,
+ -- or maybe the wait is being aborted.
+
+ POP.Sleep
+ (Self_ID,
+ System.Tasking.Interrupt_Server_Blocked_On_Event_Flag);
+
+ if Iosb.Status /= 0 then
+ if (Iosb.Status and 1) = 1
+ and then Mask (Signal (Interrupt_Mailbox))
+ then
+ return Interrupt_Mailbox;
+ else
+ return 0;
+ end if;
+ else
+ POP.Unlock (Self_ID);
+
+ if Single_Lock then
+ POP.Unlock_RTS;
+ end if;
+
+ System.Tasking.Initialization.Undefer_Abort (Self_ID);
+ System.Tasking.Initialization.Defer_Abort (Self_ID);
+
+ if Single_Lock then
+ POP.Lock_RTS;
+ end if;
+
+ POP.Write_Lock (Self_ID);
+ end if;
+ end loop;
+ end Interrupt_Wait;
+
+ ----------------------------
+ -- Install_Default_Action --
+ ----------------------------
+
+ procedure Install_Default_Action (Interrupt : Interrupt_ID) is
+ pragma Warnings (Off, Interrupt);
+ begin
+ null;
+ end Install_Default_Action;
+
+ ---------------------------
+ -- Install_Ignore_Action --
+ ---------------------------
+
+ procedure Install_Ignore_Action (Interrupt : Interrupt_ID) is
+ pragma Warnings (Off, Interrupt);
+ begin
+ null;
+ end Install_Ignore_Action;
+
+ -------------------------
+ -- Fill_Interrupt_Mask --
+ -------------------------
+
+ procedure Fill_Interrupt_Mask (Mask : access Interrupt_Mask) is
+ begin
+ Mask.all := (others => True);
+ end Fill_Interrupt_Mask;
+
+ --------------------------
+ -- Empty_Interrupt_Mask --
+ --------------------------
+
+ procedure Empty_Interrupt_Mask (Mask : access Interrupt_Mask) is
+ begin
+ Mask.all := (others => False);
+ end Empty_Interrupt_Mask;
+
+ ---------------------------
+ -- Add_To_Interrupt_Mask --
+ ---------------------------
+
+ procedure Add_To_Interrupt_Mask
+ (Mask : access Interrupt_Mask;
+ Interrupt : Interrupt_ID)
+ is
+ begin
+ Mask (Signal (Interrupt)) := True;
+ end Add_To_Interrupt_Mask;
+
+ --------------------------------
+ -- Delete_From_Interrupt_Mask --
+ --------------------------------
+
+ procedure Delete_From_Interrupt_Mask
+ (Mask : access Interrupt_Mask;
+ Interrupt : Interrupt_ID)
+ is
+ begin
+ Mask (Signal (Interrupt)) := False;
+ end Delete_From_Interrupt_Mask;
+
+ ---------------
+ -- Is_Member --
+ ---------------
+
+ function Is_Member
+ (Mask : access Interrupt_Mask;
+ Interrupt : Interrupt_ID) return Boolean
+ is
+ begin
+ return Mask (Signal (Interrupt));
+ end Is_Member;
+
+ -------------------------
+ -- Copy_Interrupt_Mask --
+ -------------------------
+
+ procedure Copy_Interrupt_Mask
+ (X : out Interrupt_Mask;
+ Y : Interrupt_Mask)
+ is
+ begin
+ X := Y;
+ end Copy_Interrupt_Mask;
+
+ -------------------------
+ -- Interrupt_Self_Process --
+ -------------------------
+
+ procedure Interrupt_Self_Process (Interrupt : Interrupt_ID) is
+ Status : Cond_Value_Type;
+ begin
+ Sys_QIO
+ (Status => Status,
+ Chan => Snd_Interrupt_Chan,
+ Func => IO_WRITEVBLK,
+ P1 => To_unsigned_long (Interrupt'Address),
+ P2 => Interrupt_ID'Size / 8);
+
+ pragma Assert ((Status and 1) = 1);
+ end Interrupt_Self_Process;
+
+begin
+ Environment_Mask := (others => False);
+ All_Tasks_Mask := (others => True);
+
+ for J in Interrupt_ID loop
+ if Keep_Unmasked (J) then
+ Environment_Mask (Signal (J)) := True;
+ All_Tasks_Mask (Signal (J)) := False;
+ end if;
+ end loop;
+end System.Interrupt_Management.Operations;
diff --git a/gcc/ada/s-inmaop.ads b/gcc/ada/s-inmaop.ads
index d83f12184af..2bb8ef0caa1 100644
--- a/gcc/ada/s-inmaop.ads
+++ b/gcc/ada/s-inmaop.ads
@@ -7,7 +7,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-1998, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004, 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- --
@@ -35,78 +35,82 @@
package System.Interrupt_Management.Operations is
procedure Thread_Block_Interrupt (Interrupt : Interrupt_ID);
- -- Mask the calling thread for the interrupt
pragma Inline (Thread_Block_Interrupt);
+ -- Mask the calling thread for the interrupt
procedure Thread_Unblock_Interrupt (Interrupt : Interrupt_ID);
- -- Unmask the calling thread for the interrupt
pragma Inline (Thread_Unblock_Interrupt);
+ -- Unmask the calling thread for the interrupt
procedure Set_Interrupt_Mask (Mask : access Interrupt_Mask);
-- Set the interrupt mask of the calling thread
+
procedure Set_Interrupt_Mask
(Mask : access Interrupt_Mask;
OMask : access Interrupt_Mask);
+ pragma Inline (Set_Interrupt_Mask);
-- Set the interrupt mask of the calling thread while returning the
-- previous Mask.
- pragma Inline (Set_Interrupt_Mask);
procedure Get_Interrupt_Mask (Mask : access Interrupt_Mask);
- -- Get the interrupt mask of the calling thread
pragma Inline (Get_Interrupt_Mask);
+ -- Get the interrupt mask of the calling thread
function Interrupt_Wait (Mask : access Interrupt_Mask) return Interrupt_ID;
- -- Wait for the interrupts specified in Mask and return
- -- the interrupt received. Upon error it return 0.
pragma Inline (Interrupt_Wait);
+ -- Wait for the interrupts specified in Mask and return
+ -- the interrupt received. Return 0 upon error.
procedure Install_Default_Action (Interrupt : Interrupt_ID);
- -- Set the sigaction of the Interrupt to default (SIG_DFL).
pragma Inline (Install_Default_Action);
+ -- Set the sigaction of the Interrupt to default (SIG_DFL).
procedure Install_Ignore_Action (Interrupt : Interrupt_ID);
- -- Set the sigaction of the Interrupt to ignore (SIG_IGN).
pragma Inline (Install_Ignore_Action);
+ -- Set the sigaction of the Interrupt to ignore (SIG_IGN).
procedure Fill_Interrupt_Mask (Mask : access Interrupt_Mask);
- -- Get a Interrupt_Mask with all the interrupt masked
pragma Inline (Fill_Interrupt_Mask);
+ -- Get a Interrupt_Mask with all the interrupt masked
procedure Empty_Interrupt_Mask (Mask : access Interrupt_Mask);
- -- Get a Interrupt_Mask with all the interrupt unmasked
pragma Inline (Empty_Interrupt_Mask);
+ -- Get a Interrupt_Mask with all the interrupt unmasked
procedure Add_To_Interrupt_Mask
(Mask : access Interrupt_Mask;
Interrupt : Interrupt_ID);
- -- Mask the given interrupt in the Interrupt_Mask
pragma Inline (Add_To_Interrupt_Mask);
+ -- Mask the given interrupt in the Interrupt_Mask
procedure Delete_From_Interrupt_Mask
(Mask : access Interrupt_Mask;
Interrupt : Interrupt_ID);
- -- Unmask the given interrupt in the Interrupt_Mask
pragma Inline (Delete_From_Interrupt_Mask);
+ -- Unmask the given interrupt in the Interrupt_Mask
function Is_Member
(Mask : access Interrupt_Mask;
Interrupt : Interrupt_ID) return Boolean;
- -- See if a given interrupt is masked in the Interrupt_Mask
pragma Inline (Is_Member);
+ -- See if a given interrupt is masked in the Interrupt_Mask
procedure Copy_Interrupt_Mask (X : out Interrupt_Mask; Y : Interrupt_Mask);
- -- Assigment needed for limited private type Interrupt_Mask.
pragma Inline (Copy_Interrupt_Mask);
+ -- Assigment needed for limited private type Interrupt_Mask.
procedure Interrupt_Self_Process (Interrupt : Interrupt_ID);
- -- raise an Interrupt process-level
pragma Inline (Interrupt_Self_Process);
+ -- Raise an Interrupt process-level
-- The following objects serve as constants, but are initialized
-- in the body to aid portability. These actually belong to the
-- System.Interrupt_Management but since Interrupt_Mask is a
-- private type we can not have them declared there.
+ -- Why not make these deferred constants that are initialized using
+ -- function calls in the private part???
+
Environment_Mask : aliased Interrupt_Mask;
-- This mask represents the mask of Environment task when this package
-- is being elaborated, except the signals being
diff --git a/gcc/ada/s-interr-dummy.adb b/gcc/ada/s-interr-dummy.adb
new file mode 100644
index 00000000000..7dbe33f26a7
--- /dev/null
+++ b/gcc/ada/s-interr-dummy.adb
@@ -0,0 +1,307 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . I N T E R R U P T S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2003, Ada Core Technologies --
+-- --
+-- 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, 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, --
+-- 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 is an OS/2 version of this package.
+
+-- This version is a stub, for systems that
+-- do not support interrupts (or signals).
+
+with Ada.Exceptions;
+
+package body System.Interrupts is
+
+ pragma Warnings (Off); -- kill warnings on unreferenced formals
+
+ use System.Tasking;
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ procedure Unimplemented;
+ -- This procedure raises a Program_Error with an appropriate message
+ -- indicating that an unimplemented feature has been used.
+
+ --------------------
+ -- Attach_Handler --
+ --------------------
+
+ procedure Attach_Handler
+ (New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean := False)
+ is
+ begin
+ Unimplemented;
+ end Attach_Handler;
+
+ -----------------------------
+ -- Bind_Interrupt_To_Entry --
+ -----------------------------
+
+ procedure Bind_Interrupt_To_Entry
+ (T : Task_ID;
+ E : Task_Entry_Index;
+ Int_Ref : System.Address)
+ is
+ begin
+ Unimplemented;
+ end Bind_Interrupt_To_Entry;
+
+ ---------------------
+ -- Block_Interrupt --
+ ---------------------
+
+ procedure Block_Interrupt (Interrupt : Interrupt_ID) is
+ begin
+ Unimplemented;
+ end Block_Interrupt;
+
+ ---------------------
+ -- Current_Handler --
+ ---------------------
+
+ function Current_Handler
+ (Interrupt : Interrupt_ID)
+ return Parameterless_Handler
+ is
+ begin
+ Unimplemented;
+ return null;
+ end Current_Handler;
+
+ --------------------
+ -- Detach_Handler --
+ --------------------
+
+ procedure Detach_Handler
+ (Interrupt : Interrupt_ID;
+ Static : Boolean := False)
+ is
+ begin
+ Unimplemented;
+ end Detach_Handler;
+
+ ------------------------------
+ -- Detach_Interrupt_Entries --
+ ------------------------------
+
+ procedure Detach_Interrupt_Entries (T : Task_ID) is
+ begin
+ Unimplemented;
+ end Detach_Interrupt_Entries;
+
+ ----------------------
+ -- Exchange_Handler --
+ ----------------------
+
+ procedure Exchange_Handler
+ (Old_Handler : out Parameterless_Handler;
+ New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean := False)
+ is
+ begin
+ Old_Handler := null;
+ Unimplemented;
+ end Exchange_Handler;
+
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize (Object : in out Static_Interrupt_Protection) is
+ begin
+ Unimplemented;
+ end Finalize;
+
+ -------------------------------------
+ -- Has_Interrupt_Or_Attach_Handler --
+ -------------------------------------
+
+ function Has_Interrupt_Or_Attach_Handler
+ (Object : access Dynamic_Interrupt_Protection)
+ return Boolean
+ is
+ pragma Warnings (Off, Object);
+
+ begin
+ Unimplemented;
+ return True;
+ end Has_Interrupt_Or_Attach_Handler;
+
+ function Has_Interrupt_Or_Attach_Handler
+ (Object : access Static_Interrupt_Protection)
+ return Boolean
+ is
+ pragma Warnings (Off, Object);
+
+ begin
+ Unimplemented;
+ return True;
+ end Has_Interrupt_Or_Attach_Handler;
+
+ ----------------------
+ -- Ignore_Interrupt --
+ ----------------------
+
+ procedure Ignore_Interrupt (Interrupt : Interrupt_ID) is
+ begin
+ Unimplemented;
+ end Ignore_Interrupt;
+
+ ----------------------
+ -- Install_Handlers --
+ ----------------------
+
+ procedure Install_Handlers
+ (Object : access Static_Interrupt_Protection;
+ New_Handlers : New_Handler_Array)
+ is
+ begin
+ Unimplemented;
+ end Install_Handlers;
+
+ ----------------
+ -- Is_Blocked --
+ ----------------
+
+ function Is_Blocked (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ Unimplemented;
+ return True;
+ end Is_Blocked;
+
+ -----------------------
+ -- Is_Entry_Attached --
+ -----------------------
+
+ function Is_Entry_Attached (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ Unimplemented;
+ return True;
+ end Is_Entry_Attached;
+
+ -------------------------
+ -- Is_Handler_Attached --
+ -------------------------
+
+ function Is_Handler_Attached (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ Unimplemented;
+ return True;
+ end Is_Handler_Attached;
+
+ ----------------
+ -- Is_Ignored --
+ ----------------
+
+ function Is_Ignored (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ Unimplemented;
+ return True;
+ end Is_Ignored;
+
+ -----------------
+ -- Is_Reserved --
+ -----------------
+
+ function Is_Reserved (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ Unimplemented;
+ return True;
+ end Is_Reserved;
+
+ ---------------
+ -- Reference --
+ ---------------
+
+ function Reference (Interrupt : Interrupt_ID) return System.Address is
+ begin
+ Unimplemented;
+ return Interrupt'Address;
+ end Reference;
+
+ --------------------------------
+ -- Register_Interrupt_Handler --
+ --------------------------------
+
+ procedure Register_Interrupt_Handler
+ (Handler_Addr : System.Address)
+ is
+ begin
+ Unimplemented;
+ end Register_Interrupt_Handler;
+
+ -----------------------
+ -- Unblock_Interrupt --
+ -----------------------
+
+ procedure Unblock_Interrupt (Interrupt : Interrupt_ID) is
+ begin
+ Unimplemented;
+ end Unblock_Interrupt;
+
+ ------------------
+ -- Unblocked_By --
+ ------------------
+
+ function Unblocked_By (Interrupt : Interrupt_ID)
+ return System.Tasking.Task_ID is
+ begin
+ Unimplemented;
+ return null;
+ end Unblocked_By;
+
+ ------------------------
+ -- Unignore_Interrupt --
+ ------------------------
+
+ procedure Unignore_Interrupt (Interrupt : Interrupt_ID) is
+ begin
+ Unimplemented;
+ end Unignore_Interrupt;
+
+ -------------------
+ -- Unimplemented; --
+ -------------------
+
+ procedure Unimplemented is
+ begin
+ Ada.Exceptions.Raise_Exception
+ (Program_Error'Identity, "interrupts/signals not implemented");
+ raise Program_Error;
+ end Unimplemented;
+
+end System.Interrupts;
diff --git a/gcc/ada/s-interr-sigaction.adb b/gcc/ada/s-interr-sigaction.adb
new file mode 100644
index 00000000000..4ee53e00b09
--- /dev/null
+++ b/gcc/ada/s-interr-sigaction.adb
@@ -0,0 +1,682 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . I N T E R R U P T S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1998-2004 Free Software Fundation --
+-- --
+-- 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, 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, --
+-- 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 is the IRIX & NT version of this package.
+
+with Ada.Task_Identification;
+-- used for Task_Id
+
+with Ada.Exceptions;
+-- used for Raise_Exception
+
+with System.OS_Interface;
+-- used for intr_attach
+
+with System.Storage_Elements;
+-- used for To_Address
+-- To_Integer
+
+with System.Task_Primitives.Operations;
+-- used for Self
+-- Sleep
+-- Wakeup
+-- Write_Lock
+-- Unlock
+
+with System.Tasking.Utilities;
+-- used for Make_Independent
+
+with System.Tasking.Rendezvous;
+-- used for Call_Simple
+
+with System.Tasking.Initialization;
+-- used for Defer_Abort
+-- Undefer_Abort
+
+with System.Interrupt_Management;
+
+with System.Parameters;
+-- used for Single_Lock
+
+with Interfaces.C;
+-- used for int
+
+with Unchecked_Conversion;
+
+package body System.Interrupts is
+
+ use Parameters;
+ use Tasking;
+ use Ada.Exceptions;
+ use System.OS_Interface;
+ use Interfaces.C;
+
+ package STPO renames System.Task_Primitives.Operations;
+ package IMNG renames System.Interrupt_Management;
+
+ subtype int is Interfaces.C.int;
+
+ function To_System is new Unchecked_Conversion
+ (Ada.Task_Identification.Task_Id, Task_ID);
+
+ type Handler_Kind is (Unknown, Task_Entry, Protected_Procedure);
+
+ type Handler_Desc is record
+ Kind : Handler_Kind := Unknown;
+ T : Task_ID;
+ E : Task_Entry_Index;
+ H : Parameterless_Handler;
+ Static : Boolean := False;
+ end record;
+
+ task type Server_Task (Interrupt : Interrupt_ID) is
+ pragma Interrupt_Priority (System.Interrupt_Priority'Last);
+ end Server_Task;
+
+ type Server_Task_Access is access Server_Task;
+
+ Attached_Interrupts : array (Interrupt_ID) of Boolean;
+ Handlers : array (Interrupt_ID) of Task_ID;
+ Descriptors : array (Interrupt_ID) of Handler_Desc;
+ Interrupt_Count : array (Interrupt_ID) of Integer := (others => 0);
+
+ pragma Volatile_Components (Interrupt_Count);
+
+ procedure Attach_Handler
+ (New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean;
+ Restoration : Boolean);
+ -- This internal procedure is needed to finalize protected objects
+ -- that contain interrupt handlers.
+
+ procedure Signal_Handler (Sig : Interrupt_ID);
+ -- This procedure is used to handle all the signals.
+
+ -- Type and Head, Tail of the list containing Registered Interrupt
+ -- Handlers. These definitions are used to register the handlers
+ -- specified by the pragma Interrupt_Handler.
+
+ --
+ -- Handler Registration:
+ --
+
+ type Registered_Handler;
+ type R_Link is access all Registered_Handler;
+
+ type Registered_Handler is record
+ H : System.Address := System.Null_Address;
+ Next : R_Link := null;
+ end record;
+
+ Registered_Handlers : R_Link := null;
+
+ function Is_Registered (Handler : Parameterless_Handler) return Boolean;
+ -- See if the Handler has been "pragma"ed using Interrupt_Handler.
+ -- Always consider a null handler as registered.
+
+ type Handler_Ptr is access procedure (Sig : Interrupt_ID);
+
+ function TISR is new Unchecked_Conversion (Handler_Ptr, isr_address);
+
+ procedure Signal_Handler (Sig : Interrupt_ID) is
+ Handler : Task_ID renames Handlers (Sig);
+ begin
+ if Intr_Attach_Reset and then
+ intr_attach (int (Sig), TISR (Signal_Handler'Access)) = FUNC_ERR
+ then
+ raise Program_Error;
+ end if;
+
+ if Handler /= null then
+ Interrupt_Count (Sig) := Interrupt_Count (Sig) + 1;
+ STPO.Wakeup (Handler, Interrupt_Server_Idle_Sleep);
+ end if;
+ end Signal_Handler;
+
+ -----------------
+ -- Is_Reserved --
+ -----------------
+
+ function Is_Reserved (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ return IMNG.Reserve (IMNG.Interrupt_ID (Interrupt));
+ end Is_Reserved;
+
+ -----------------------
+ -- Is_Entry_Attached --
+ -----------------------
+
+ function Is_Entry_Attached (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ if Is_Reserved (Interrupt) then
+ Raise_Exception (Program_Error'Identity, "Interrupt" &
+ Interrupt_ID'Image (Interrupt) & " is reserved");
+ end if;
+
+ return Descriptors (Interrupt).T /= Null_Task;
+ end Is_Entry_Attached;
+
+ -------------------------
+ -- Is_Handler_Attached --
+ -------------------------
+
+ function Is_Handler_Attached (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ if Is_Reserved (Interrupt) then
+ Raise_Exception (Program_Error'Identity, "Interrupt" &
+ Interrupt_ID'Image (Interrupt) & " is reserved");
+ end if;
+
+ return Descriptors (Interrupt).Kind /= Unknown;
+ end Is_Handler_Attached;
+
+ ----------------
+ -- Is_Ignored --
+ ----------------
+
+ function Is_Ignored (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ raise Program_Error;
+ return False;
+ end Is_Ignored;
+
+ ------------------
+ -- Unblocked_By --
+ ------------------
+
+ function Unblocked_By (Interrupt : Interrupt_ID) return Task_ID is
+ begin
+ raise Program_Error;
+ return Null_Task;
+ end Unblocked_By;
+
+ ----------------------
+ -- Ignore_Interrupt --
+ ----------------------
+
+ procedure Ignore_Interrupt (Interrupt : Interrupt_ID) is
+ begin
+ raise Program_Error;
+ end Ignore_Interrupt;
+
+ ------------------------
+ -- Unignore_Interrupt --
+ ------------------------
+
+ procedure Unignore_Interrupt (Interrupt : Interrupt_ID) is
+ begin
+ raise Program_Error;
+ end Unignore_Interrupt;
+
+ -------------------------------------
+ -- Has_Interrupt_Or_Attach_Handler --
+ -------------------------------------
+
+ function Has_Interrupt_Or_Attach_Handler
+ (Object : access Dynamic_Interrupt_Protection) return Boolean
+ is
+ pragma Unreferenced (Object);
+ begin
+ return True;
+ end Has_Interrupt_Or_Attach_Handler;
+
+ ----------------
+ -- Finalize --
+ ----------------
+
+ procedure Finalize (Object : in out Static_Interrupt_Protection) is
+ begin
+ -- ??? loop to be executed only when we're not doing library level
+ -- finalization, since in this case all interrupt tasks are gone.
+
+ for N in reverse Object.Previous_Handlers'Range loop
+ Attach_Handler
+ (New_Handler => Object.Previous_Handlers (N).Handler,
+ Interrupt => Object.Previous_Handlers (N).Interrupt,
+ Static => Object.Previous_Handlers (N).Static,
+ Restoration => True);
+ end loop;
+
+ Tasking.Protected_Objects.Entries.Finalize
+ (Tasking.Protected_Objects.Entries.Protection_Entries (Object));
+ end Finalize;
+
+ -------------------------------------
+ -- Has_Interrupt_Or_Attach_Handler --
+ -------------------------------------
+
+ function Has_Interrupt_Or_Attach_Handler
+ (Object : access Static_Interrupt_Protection) return Boolean
+ is
+ pragma Unreferenced (Object);
+ begin
+ return True;
+ end Has_Interrupt_Or_Attach_Handler;
+
+ ----------------------
+ -- Install_Handlers --
+ ----------------------
+
+ procedure Install_Handlers
+ (Object : access Static_Interrupt_Protection;
+ New_Handlers : New_Handler_Array)
+ is
+ begin
+ for N in New_Handlers'Range loop
+
+ -- We need a lock around this ???
+
+ Object.Previous_Handlers (N).Interrupt := New_Handlers (N).Interrupt;
+ Object.Previous_Handlers (N).Static := Descriptors
+ (New_Handlers (N).Interrupt).Static;
+
+ -- We call Exchange_Handler and not directly Interrupt_Manager.
+ -- Exchange_Handler so we get the Is_Reserved check.
+
+ Exchange_Handler
+ (Old_Handler => Object.Previous_Handlers (N).Handler,
+ New_Handler => New_Handlers (N).Handler,
+ Interrupt => New_Handlers (N).Interrupt,
+ Static => True);
+ end loop;
+ end Install_Handlers;
+
+ ---------------------
+ -- Current_Handler --
+ ---------------------
+
+ function Current_Handler
+ (Interrupt : Interrupt_ID) return Parameterless_Handler
+ is
+ begin
+ if Is_Reserved (Interrupt) then
+ raise Program_Error;
+ end if;
+
+ if Descriptors (Interrupt).Kind = Protected_Procedure then
+ return Descriptors (Interrupt).H;
+ else
+ return null;
+ end if;
+ end Current_Handler;
+
+ --------------------
+ -- Attach_Handler --
+ --------------------
+
+ procedure Attach_Handler
+ (New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean := False) is
+ begin
+ Attach_Handler (New_Handler, Interrupt, Static, False);
+ end Attach_Handler;
+
+ procedure Attach_Handler
+ (New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean;
+ Restoration : Boolean)
+ is
+ New_Task : Server_Task_Access;
+
+ begin
+ if Is_Reserved (Interrupt) then
+ raise Program_Error;
+ end if;
+
+ if not Restoration and then not Static
+
+ -- Tries to overwrite a static Interrupt Handler with a
+ -- dynamic Handler
+
+ and then (Descriptors (Interrupt).Static
+
+ -- The new handler is not specified as an
+ -- Interrupt Handler by a pragma.
+
+ or else not Is_Registered (New_Handler))
+ then
+ Raise_Exception (Program_Error'Identity,
+ "Trying to overwrite a static Interrupt Handler with a " &
+ "dynamic Handler");
+ end if;
+
+ if Handlers (Interrupt) = null then
+ New_Task := new Server_Task (Interrupt);
+ Handlers (Interrupt) := To_System (New_Task.all'Identity);
+ end if;
+
+ if intr_attach (int (Interrupt),
+ TISR (Signal_Handler'Access)) = FUNC_ERR
+ then
+ raise Program_Error;
+ end if;
+
+ if New_Handler = null then
+
+ -- The null handler means we are detaching the handler.
+
+ Attached_Interrupts (Interrupt) := False;
+ Descriptors (Interrupt) :=
+ (Kind => Unknown, T => null, E => 0, H => null, Static => False);
+
+ else
+ Descriptors (Interrupt).Kind := Protected_Procedure;
+ Descriptors (Interrupt).H := New_Handler;
+ Descriptors (Interrupt).Static := Static;
+ Attached_Interrupts (Interrupt) := True;
+ end if;
+ end Attach_Handler;
+
+ ----------------------
+ -- Exchange_Handler --
+ ----------------------
+
+ procedure Exchange_Handler
+ (Old_Handler : out Parameterless_Handler;
+ New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean := False) is
+ begin
+ if Is_Reserved (Interrupt) then
+ raise Program_Error;
+ end if;
+
+ if Descriptors (Interrupt).Kind = Task_Entry then
+
+ -- In case we have an Interrupt Entry already installed.
+ -- raise a program error. (propagate it to the caller).
+
+ Raise_Exception (Program_Error'Identity,
+ "An interrupt is already installed");
+ end if;
+
+ Old_Handler := Current_Handler (Interrupt);
+ Attach_Handler (New_Handler, Interrupt, Static);
+ end Exchange_Handler;
+
+ --------------------
+ -- Detach_Handler --
+ --------------------
+
+ procedure Detach_Handler
+ (Interrupt : Interrupt_ID;
+ Static : Boolean := False) is
+ begin
+ if Is_Reserved (Interrupt) then
+ raise Program_Error;
+ end if;
+
+ if Descriptors (Interrupt).Kind = Task_Entry then
+ Raise_Exception (Program_Error'Identity,
+ "Trying to detach an Interrupt Entry");
+ end if;
+
+ if not Static and then Descriptors (Interrupt).Static then
+ Raise_Exception (Program_Error'Identity,
+ "Trying to detach a static Interrupt Handler");
+ end if;
+
+ Attached_Interrupts (Interrupt) := False;
+ Descriptors (Interrupt) :=
+ (Kind => Unknown, T => null, E => 0, H => null, Static => False);
+
+ if intr_attach (int (Interrupt), null) = FUNC_ERR then
+ raise Program_Error;
+ end if;
+ end Detach_Handler;
+
+ ---------------
+ -- Reference --
+ ---------------
+
+ function Reference (Interrupt : Interrupt_ID) return System.Address is
+ Signal : constant System.Address :=
+ System.Storage_Elements.To_Address
+ (System.Storage_Elements.Integer_Address (Interrupt));
+
+ begin
+ if Is_Reserved (Interrupt) then
+
+ -- Only usable Interrupts can be used for binding it to an Entry
+
+ raise Program_Error;
+ end if;
+
+ return Signal;
+ end Reference;
+
+ --------------------------------
+ -- Register_Interrupt_Handler --
+ --------------------------------
+
+ procedure Register_Interrupt_Handler (Handler_Addr : System.Address) is
+ begin
+ Registered_Handlers :=
+ new Registered_Handler'(H => Handler_Addr, Next => Registered_Handlers);
+ end Register_Interrupt_Handler;
+
+ -------------------
+ -- Is_Registered --
+ -------------------
+
+ -- See if the Handler has been "pragma"ed using Interrupt_Handler.
+ -- Always consider a null handler as registered.
+
+ function Is_Registered (Handler : Parameterless_Handler) return Boolean is
+ Ptr : R_Link := Registered_Handlers;
+
+ type Fat_Ptr is record
+ Object_Addr : System.Address;
+ Handler_Addr : System.Address;
+ end record;
+
+ function To_Fat_Ptr is new Unchecked_Conversion
+ (Parameterless_Handler, Fat_Ptr);
+
+ Fat : Fat_Ptr;
+
+ begin
+ if Handler = null then
+ return True;
+ end if;
+
+ Fat := To_Fat_Ptr (Handler);
+
+ while Ptr /= null loop
+
+ if Ptr.H = Fat.Handler_Addr then
+ return True;
+ end if;
+
+ Ptr := Ptr.Next;
+ end loop;
+
+ return False;
+ end Is_Registered;
+
+ -----------------------------
+ -- Bind_Interrupt_To_Entry --
+ -----------------------------
+
+ procedure Bind_Interrupt_To_Entry
+ (T : Task_ID;
+ E : Task_Entry_Index;
+ Int_Ref : System.Address)
+ is
+ Interrupt : constant Interrupt_ID :=
+ Interrupt_ID (Storage_Elements.To_Integer (Int_Ref));
+
+ New_Task : Server_Task_Access;
+
+ begin
+ if Is_Reserved (Interrupt) then
+ raise Program_Error;
+ end if;
+
+ if Descriptors (Interrupt).Kind /= Unknown then
+ Raise_Exception (Program_Error'Identity,
+ "A binding for this interrupt is already present");
+ end if;
+
+ if Handlers (Interrupt) = null then
+ New_Task := new Server_Task (Interrupt);
+ Handlers (Interrupt) := To_System (New_Task.all'Identity);
+ end if;
+
+ if intr_attach (int (Interrupt),
+ TISR (Signal_Handler'Access)) = FUNC_ERR
+ then
+ raise Program_Error;
+ end if;
+
+ Descriptors (Interrupt).Kind := Task_Entry;
+ Descriptors (Interrupt).T := T;
+ Descriptors (Interrupt).E := E;
+
+ -- Indicate the attachment of Interrupt Entry in ATCB.
+ -- This is need so that when an Interrupt Entry task terminates
+ -- the binding can be cleaned. The call to unbinding must be
+ -- make by the task before it terminates.
+
+ T.Interrupt_Entry := True;
+
+ Attached_Interrupts (Interrupt) := True;
+ end Bind_Interrupt_To_Entry;
+
+ ------------------------------
+ -- Detach_Interrupt_Entries --
+ ------------------------------
+
+ procedure Detach_Interrupt_Entries (T : Task_ID) is
+ begin
+ for I in Interrupt_ID loop
+ if not Is_Reserved (I) then
+ if Descriptors (I).Kind = Task_Entry and then
+ Descriptors (I).T = T then
+ Attached_Interrupts (I) := False;
+ Descriptors (I).Kind := Unknown;
+
+ if intr_attach (int (I), null) = FUNC_ERR then
+ raise Program_Error;
+ end if;
+ end if;
+ end if;
+ end loop;
+
+ -- Indicate in ATCB that no Interrupt Entries are attached.
+
+ T.Interrupt_Entry := True;
+ end Detach_Interrupt_Entries;
+
+ ---------------------
+ -- Block_Interrupt --
+ ---------------------
+
+ procedure Block_Interrupt (Interrupt : Interrupt_ID) is
+ begin
+ raise Program_Error;
+ end Block_Interrupt;
+
+ -----------------------
+ -- Unblock_Interrupt --
+ -----------------------
+
+ procedure Unblock_Interrupt (Interrupt : Interrupt_ID) is
+ begin
+ raise Program_Error;
+ end Unblock_Interrupt;
+
+ ----------------
+ -- Is_Blocked --
+ ----------------
+
+ function Is_Blocked (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ raise Program_Error;
+ return False;
+ end Is_Blocked;
+
+ task body Server_Task is
+ Desc : Handler_Desc renames Descriptors (Interrupt);
+ Self_Id : constant Task_ID := STPO.Self;
+ Temp : Parameterless_Handler;
+
+ begin
+ Utilities.Make_Independent;
+
+ loop
+ while Interrupt_Count (Interrupt) > 0 loop
+ Interrupt_Count (Interrupt) := Interrupt_Count (Interrupt) - 1;
+ begin
+ case Desc.Kind is
+ when Unknown =>
+ null;
+ when Task_Entry =>
+ Rendezvous.Call_Simple (Desc.T, Desc.E, Null_Address);
+ when Protected_Procedure =>
+ Temp := Desc.H;
+ Temp.all;
+ end case;
+ exception
+ when others => null;
+ end;
+ end loop;
+
+ Initialization.Defer_Abort (Self_Id);
+
+ if Single_Lock then
+ STPO.Lock_RTS;
+ end if;
+
+ STPO.Write_Lock (Self_Id);
+ Self_Id.Common.State := Interrupt_Server_Idle_Sleep;
+ STPO.Sleep (Self_Id, Interrupt_Server_Idle_Sleep);
+ Self_Id.Common.State := Runnable;
+ STPO.Unlock (Self_Id);
+
+ if Single_Lock then
+ STPO.Unlock_RTS;
+ end if;
+
+ Initialization.Undefer_Abort (Self_Id);
+
+ -- Undefer abort here to allow a window for this task
+ -- to be aborted at the time of system shutdown.
+
+ end loop;
+ end Server_Task;
+
+end System.Interrupts;
diff --git a/gcc/ada/s-interr-vms.adb b/gcc/ada/s-interr-vms.adb
new file mode 100644
index 00000000000..f302ead12e3
--- /dev/null
+++ b/gcc/ada/s-interr-vms.adb
@@ -0,0 +1,1176 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . I N T E R R U P T S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2004, 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- --
+-- 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, 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, --
+-- 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 is an OpenVMS/Alpha version of this package.
+
+-- Invariants:
+
+-- Once we associate a Server_Task with an interrupt, the task never
+-- goes away, and we never remove the association.
+
+-- There is no more than one interrupt per Server_Task and no more than
+-- one Server_Task per interrupt.
+
+-- Within this package, the lock L is used to protect the various status
+-- tables. If there is a Server_Task associated with an interrupt, we use
+-- the per-task lock of the Server_Task instead so that we protect the
+-- status between Interrupt_Manager and Server_Task. Protection among
+-- service requests are done using User Request to Interrupt_Manager
+-- rendezvous.
+
+with Ada.Task_Identification;
+-- used for Task_ID type
+
+with Ada.Exceptions;
+-- used for Raise_Exception
+
+with System.Task_Primitives;
+-- used for RTS_Lock
+-- Self
+
+with System.Interrupt_Management;
+-- used for Reserve
+-- Interrupt_ID
+-- Interrupt_Mask
+-- Abort_Task_Interrupt
+
+with System.Interrupt_Management.Operations;
+-- used for Thread_Block_Interrupt
+-- Thread_Unblock_Interrupt
+-- Install_Default_Action
+-- Install_Ignore_Action
+-- Copy_Interrupt_Mask
+-- Set_Interrupt_Mask
+-- Empty_Interrupt_Mask
+-- Fill_Interrupt_Mask
+-- Add_To_Interrupt_Mask
+-- Delete_From_Interrupt_Mask
+-- Interrupt_Wait
+-- Interrupt_Self_Process
+-- Get_Interrupt_Mask
+-- Set_Interrupt_Mask
+-- IS_Member
+-- Environment_Mask
+pragma Elaborate_All (System.Interrupt_Management.Operations);
+
+with System.Task_Primitives.Operations;
+-- used for Write_Lock
+-- Unlock
+-- Abort
+-- Wakeup_Task
+-- Sleep
+-- Initialize_Lock
+
+with System.Task_Primitives.Interrupt_Operations;
+-- used for Set_Interrupt_ID
+
+with System.Storage_Elements;
+-- used for To_Address
+-- To_Integer
+-- Integer_Address
+
+with System.Tasking;
+-- used for Task_ID
+-- Task_Entry_Index
+-- Null_Task
+-- Self
+-- Interrupt_Manager_ID
+
+with System.Tasking.Utilities;
+-- used for Make_Independent
+
+with System.Tasking.Rendezvous;
+-- used for Call_Simple
+pragma Elaborate_All (System.Tasking.Rendezvous);
+
+with System.Tasking.Initialization;
+-- used for Defer_Abort
+-- Undefer_Abort
+
+with System.Parameters;
+-- used for Single_Lock
+
+with Unchecked_Conversion;
+
+package body System.Interrupts is
+
+ use Tasking;
+ use System.Parameters;
+ use Ada.Exceptions;
+
+ package POP renames System.Task_Primitives.Operations;
+ package PIO renames System.Task_Primitives.Interrupt_Operations;
+ package IMNG renames System.Interrupt_Management;
+ package IMOP renames System.Interrupt_Management.Operations;
+
+ function To_System is new Unchecked_Conversion
+ (Ada.Task_Identification.Task_Id, Task_ID);
+
+ -----------------
+ -- Local Tasks --
+ -----------------
+
+ -- WARNING: System.Tasking.Stages performs calls to this task
+ -- with low-level constructs. Do not change this spec without synchro-
+ -- nizing it.
+
+ task Interrupt_Manager is
+ entry Detach_Interrupt_Entries (T : Task_ID);
+
+ entry Initialize (Mask : IMNG.Interrupt_Mask);
+
+ entry Attach_Handler
+ (New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean;
+ Restoration : Boolean := False);
+
+ entry Exchange_Handler
+ (Old_Handler : out Parameterless_Handler;
+ New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean);
+
+ entry Detach_Handler
+ (Interrupt : Interrupt_ID;
+ Static : Boolean);
+
+ entry Bind_Interrupt_To_Entry
+ (T : Task_ID;
+ E : Task_Entry_Index;
+ Interrupt : Interrupt_ID);
+
+ entry Block_Interrupt (Interrupt : Interrupt_ID);
+
+ entry Unblock_Interrupt (Interrupt : Interrupt_ID);
+
+ entry Ignore_Interrupt (Interrupt : Interrupt_ID);
+
+ entry Unignore_Interrupt (Interrupt : Interrupt_ID);
+
+ pragma Interrupt_Priority (System.Interrupt_Priority'Last);
+ end Interrupt_Manager;
+
+ task type Server_Task (Interrupt : Interrupt_ID) is
+ pragma Priority (System.Interrupt_Priority'Last);
+ -- Note: the above pragma Priority is strictly speaking improper
+ -- since it is outside the range of allowed priorities, but the
+ -- compiler treats system units specially and does not apply
+ -- this range checking rule to system units.
+
+ end Server_Task;
+
+ type Server_Task_Access is access Server_Task;
+
+ --------------------------------
+ -- Local Types and Variables --
+ --------------------------------
+
+ type Entry_Assoc is record
+ T : Task_ID;
+ E : Task_Entry_Index;
+ end record;
+
+ type Handler_Assoc is record
+ H : Parameterless_Handler;
+ Static : Boolean; -- Indicates static binding;
+ end record;
+
+ User_Handler : array (Interrupt_ID'Range) of Handler_Assoc :=
+ (others => (null, Static => False));
+ pragma Volatile_Components (User_Handler);
+ -- Holds the protected procedure handler (if any) and its Static
+ -- information for each interrupt. A handler is a Static one if
+ -- it is specified through the pragma Attach_Handler.
+ -- Attach_Handler. Otherwise, not static)
+
+ User_Entry : array (Interrupt_ID'Range) of Entry_Assoc :=
+ (others => (T => Null_Task, E => Null_Task_Entry));
+ pragma Volatile_Components (User_Entry);
+ -- Holds the task and entry index (if any) for each interrupt
+
+ Blocked : constant array (Interrupt_ID'Range) of Boolean :=
+ (others => False);
+-- ??? pragma Volatile_Components (Blocked);
+ -- True iff the corresponding interrupt is blocked in the process level
+
+ Ignored : array (Interrupt_ID'Range) of Boolean := (others => False);
+ pragma Volatile_Components (Ignored);
+ -- True iff the corresponding interrupt is blocked in the process level
+
+ Last_Unblocker : constant array (Interrupt_ID'Range) of Task_ID :=
+ (others => Null_Task);
+-- ??? pragma Volatile_Components (Last_Unblocker);
+ -- Holds the ID of the last Task which Unblocked this Interrupt.
+ -- It contains Null_Task if no tasks have ever requested the
+ -- Unblocking operation or the Interrupt is currently Blocked.
+
+ Server_ID : array (Interrupt_ID'Range) of Task_ID :=
+ (others => Null_Task);
+ pragma Atomic_Components (Server_ID);
+ -- Holds the Task_ID of the Server_Task for each interrupt.
+ -- Task_ID is needed to accomplish locking per Interrupt base. Also
+ -- is needed to decide whether to create a new Server_Task.
+
+ -- Type and Head, Tail of the list containing Registered Interrupt
+ -- Handlers. These definitions are used to register the handlers
+ -- specified by the pragma Interrupt_Handler.
+
+ type Registered_Handler;
+ type R_Link is access all Registered_Handler;
+
+ type Registered_Handler is record
+ H : System.Address := System.Null_Address;
+ Next : R_Link := null;
+ end record;
+
+ Registered_Handler_Head : R_Link := null;
+ Registered_Handler_Tail : R_Link := null;
+
+ Access_Hold : Server_Task_Access;
+ -- variable used to allocate Server_Task using "new".
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ function Is_Registered (Handler : Parameterless_Handler) return Boolean;
+ -- See if the Handler has been "pragma"ed using Interrupt_Handler.
+ -- Always consider a null handler as registered.
+
+ --------------------------------
+ -- Register_Interrupt_Handler --
+ --------------------------------
+
+ procedure Register_Interrupt_Handler (Handler_Addr : System.Address) is
+ New_Node_Ptr : R_Link;
+ begin
+ -- This routine registers the Handler as usable for Dynamic
+ -- Interrupt Handler. Routines attaching and detaching Handler
+ -- dynamically should first consult if the Handler is rgistered.
+ -- A Program Error should be raised if it is not registered.
+
+ -- The pragma Interrupt_Handler can only appear in the library
+ -- level PO definition and instantiation. Therefore, we do not need
+ -- to implement Unregistering operation. Neither we need to
+ -- protect the queue structure using a Lock.
+
+ pragma Assert (Handler_Addr /= System.Null_Address);
+
+ New_Node_Ptr := new Registered_Handler;
+ New_Node_Ptr.H := Handler_Addr;
+
+ if Registered_Handler_Head = null then
+ Registered_Handler_Head := New_Node_Ptr;
+ Registered_Handler_Tail := New_Node_Ptr;
+
+ else
+ Registered_Handler_Tail.Next := New_Node_Ptr;
+ Registered_Handler_Tail := New_Node_Ptr;
+ end if;
+ end Register_Interrupt_Handler;
+
+ -------------------
+ -- Is_Registered --
+ -------------------
+
+ function Is_Registered (Handler : Parameterless_Handler) return Boolean is
+ type Fat_Ptr is record
+ Object_Addr : System.Address;
+ Handler_Addr : System.Address;
+ end record;
+
+ function To_Fat_Ptr is new Unchecked_Conversion
+ (Parameterless_Handler, Fat_Ptr);
+
+ Ptr : R_Link;
+ Fat : Fat_Ptr;
+
+ begin
+ if Handler = null then
+ return True;
+ end if;
+
+ Fat := To_Fat_Ptr (Handler);
+
+ Ptr := Registered_Handler_Head;
+
+ while Ptr /= null loop
+ if Ptr.H = Fat.Handler_Addr then
+ return True;
+ end if;
+
+ Ptr := Ptr.Next;
+ end loop;
+
+ return False;
+
+ end Is_Registered;
+
+ -----------------
+ -- Is_Reserved --
+ -----------------
+
+ function Is_Reserved (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ return IMNG.Reserve (IMNG.Interrupt_ID (Interrupt));
+ end Is_Reserved;
+
+ -----------------------
+ -- Is_Entry_Attached --
+ -----------------------
+
+ function Is_Entry_Attached (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ if Is_Reserved (Interrupt) then
+ Raise_Exception (Program_Error'Identity, "Interrupt" &
+ Interrupt_ID'Image (Interrupt) & " is reserved");
+ end if;
+
+ return User_Entry (Interrupt).T /= Null_Task;
+ end Is_Entry_Attached;
+
+ -------------------------
+ -- Is_Handler_Attached --
+ -------------------------
+
+ function Is_Handler_Attached (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ if Is_Reserved (Interrupt) then
+ Raise_Exception (Program_Error'Identity, "Interrupt" &
+ Interrupt_ID'Image (Interrupt) & " is reserved");
+ end if;
+
+ return User_Handler (Interrupt).H /= null;
+ end Is_Handler_Attached;
+
+ ----------------
+ -- Is_Blocked --
+ ----------------
+
+ function Is_Blocked (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ if Is_Reserved (Interrupt) then
+ Raise_Exception (Program_Error'Identity, "Interrupt" &
+ Interrupt_ID'Image (Interrupt) & " is reserved");
+ end if;
+
+ return Blocked (Interrupt);
+ end Is_Blocked;
+
+ ----------------
+ -- Is_Ignored --
+ ----------------
+
+ function Is_Ignored (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ if Is_Reserved (Interrupt) then
+ Raise_Exception (Program_Error'Identity, "Interrupt" &
+ Interrupt_ID'Image (Interrupt) & " is reserved");
+ end if;
+
+ return Ignored (Interrupt);
+ end Is_Ignored;
+
+ ---------------------
+ -- Current_Handler --
+ ---------------------
+
+ function Current_Handler (Interrupt : Interrupt_ID)
+ return Parameterless_Handler is
+ begin
+ if Is_Reserved (Interrupt) then
+ Raise_Exception (Program_Error'Identity, "Interrupt" &
+ Interrupt_ID'Image (Interrupt) & " is reserved");
+ end if;
+
+ -- ??? Since Parameterless_Handler is not Atomic, the
+ -- current implementation is wrong. We need a new service in
+ -- Interrupt_Manager to ensure atomicity.
+
+ return User_Handler (Interrupt).H;
+ end Current_Handler;
+
+ --------------------
+ -- Attach_Handler --
+ --------------------
+
+ -- Calling this procedure with New_Handler = null and Static = True
+ -- means we want to detach the current handler regardless of the
+ -- previous handler's binding status (ie. do not care if it is a
+ -- dynamic or static handler).
+
+ -- This option is needed so that during the finalization of a PO, we
+ -- can detach handlers attached through pragma Attach_Handler.
+
+ procedure Attach_Handler
+ (New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean := False) is
+ begin
+ if Is_Reserved (Interrupt) then
+ Raise_Exception (Program_Error'Identity, "Interrupt" &
+ Interrupt_ID'Image (Interrupt) & " is reserved");
+ end if;
+
+ Interrupt_Manager.Attach_Handler (New_Handler, Interrupt, Static);
+
+ end Attach_Handler;
+
+ ----------------------
+ -- Exchange_Handler --
+ ----------------------
+
+ -- Calling this procedure with New_Handler = null and Static = True
+ -- means we want to detach the current handler regardless of the
+ -- previous handler's binding status (ie. do not care if it is a
+ -- dynamic or static handler).
+
+ -- This option is needed so that during the finalization of a PO, we
+ -- can detach handlers attached through pragma Attach_Handler.
+
+ procedure Exchange_Handler
+ (Old_Handler : out Parameterless_Handler;
+ New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean := False) is
+ begin
+ if Is_Reserved (Interrupt) then
+ Raise_Exception (Program_Error'Identity, "Interrupt" &
+ Interrupt_ID'Image (Interrupt) & " is reserved");
+ end if;
+
+ Interrupt_Manager.Exchange_Handler
+ (Old_Handler, New_Handler, Interrupt, Static);
+
+ end Exchange_Handler;
+
+ --------------------
+ -- Detach_Handler --
+ --------------------
+
+ -- Calling this procedure with Static = True means we want to Detach the
+ -- current handler regardless of the previous handler's binding status
+ -- (i.e. do not care if it is a dynamic or static handler).
+
+ -- This option is needed so that during the finalization of a PO, we can
+ -- detach handlers attached through pragma Attach_Handler.
+
+ procedure Detach_Handler
+ (Interrupt : Interrupt_ID;
+ Static : Boolean := False)
+ is
+ begin
+ if Is_Reserved (Interrupt) then
+ Raise_Exception (Program_Error'Identity, "Interrupt" &
+ Interrupt_ID'Image (Interrupt) & " is reserved");
+ end if;
+
+ Interrupt_Manager.Detach_Handler (Interrupt, Static);
+ end Detach_Handler;
+
+ ---------------
+ -- Reference --
+ ---------------
+
+ function Reference (Interrupt : Interrupt_ID) return System.Address is
+ begin
+ if Is_Reserved (Interrupt) then
+ Raise_Exception (Program_Error'Identity, "Interrupt" &
+ Interrupt_ID'Image (Interrupt) & " is reserved");
+ end if;
+
+ return Storage_Elements.To_Address
+ (Storage_Elements.Integer_Address (Interrupt));
+ end Reference;
+
+ -----------------------------
+ -- Bind_Interrupt_To_Entry --
+ -----------------------------
+
+ -- This procedure raises a Program_Error if it tries to
+ -- bind an interrupt to which an Entry or a Procedure is
+ -- already bound.
+
+ procedure Bind_Interrupt_To_Entry
+ (T : Task_ID;
+ E : Task_Entry_Index;
+ Int_Ref : System.Address)
+ is
+ Interrupt : constant Interrupt_ID :=
+ Interrupt_ID (Storage_Elements.To_Integer (Int_Ref));
+
+ begin
+ if Is_Reserved (Interrupt) then
+ Raise_Exception (Program_Error'Identity, "Interrupt" &
+ Interrupt_ID'Image (Interrupt) & " is reserved");
+ end if;
+
+ Interrupt_Manager.Bind_Interrupt_To_Entry (T, E, Interrupt);
+
+ end Bind_Interrupt_To_Entry;
+
+ ------------------------------
+ -- Detach_Interrupt_Entries --
+ ------------------------------
+
+ procedure Detach_Interrupt_Entries (T : Task_ID) is
+ begin
+ Interrupt_Manager.Detach_Interrupt_Entries (T);
+ end Detach_Interrupt_Entries;
+
+ ---------------------
+ -- Block_Interrupt --
+ ---------------------
+
+ procedure Block_Interrupt (Interrupt : Interrupt_ID) is
+ begin
+ if Is_Reserved (Interrupt) then
+ Raise_Exception (Program_Error'Identity, "Interrupt" &
+ Interrupt_ID'Image (Interrupt) & " is reserved");
+ end if;
+
+ Interrupt_Manager.Block_Interrupt (Interrupt);
+ end Block_Interrupt;
+
+ -----------------------
+ -- Unblock_Interrupt --
+ -----------------------
+
+ procedure Unblock_Interrupt (Interrupt : Interrupt_ID) is
+ begin
+ if Is_Reserved (Interrupt) then
+ Raise_Exception (Program_Error'Identity, "Interrupt" &
+ Interrupt_ID'Image (Interrupt) & " is reserved");
+ end if;
+
+ Interrupt_Manager.Unblock_Interrupt (Interrupt);
+ end Unblock_Interrupt;
+
+ ------------------
+ -- Unblocked_By --
+ ------------------
+
+ function Unblocked_By
+ (Interrupt : Interrupt_ID) return System.Tasking.Task_ID is
+ begin
+ if Is_Reserved (Interrupt) then
+ Raise_Exception (Program_Error'Identity, "Interrupt" &
+ Interrupt_ID'Image (Interrupt) & " is reserved");
+ end if;
+
+ return Last_Unblocker (Interrupt);
+ end Unblocked_By;
+
+ ----------------------
+ -- Ignore_Interrupt --
+ ----------------------
+
+ procedure Ignore_Interrupt (Interrupt : Interrupt_ID) is
+ begin
+ if Is_Reserved (Interrupt) then
+ Raise_Exception (Program_Error'Identity, "Interrupt" &
+ Interrupt_ID'Image (Interrupt) & " is reserved");
+ end if;
+
+ Interrupt_Manager.Ignore_Interrupt (Interrupt);
+ end Ignore_Interrupt;
+
+ ------------------------
+ -- Unignore_Interrupt --
+ ------------------------
+
+ procedure Unignore_Interrupt (Interrupt : Interrupt_ID) is
+ begin
+ if Is_Reserved (Interrupt) then
+ Raise_Exception (Program_Error'Identity, "Interrupt" &
+ Interrupt_ID'Image (Interrupt) & " is reserved");
+ end if;
+
+ Interrupt_Manager.Unignore_Interrupt (Interrupt);
+ end Unignore_Interrupt;
+
+ -----------------------
+ -- Interrupt_Manager --
+ -----------------------
+
+ task body Interrupt_Manager is
+
+ ---------------------
+ -- Local Routines --
+ ---------------------
+
+ procedure Unprotected_Exchange_Handler
+ (Old_Handler : out Parameterless_Handler;
+ New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean;
+ Restoration : Boolean := False);
+
+ procedure Unprotected_Detach_Handler
+ (Interrupt : Interrupt_ID;
+ Static : Boolean);
+
+ ----------------------------------
+ -- Unprotected_Exchange_Handler --
+ ----------------------------------
+
+ procedure Unprotected_Exchange_Handler
+ (Old_Handler : out Parameterless_Handler;
+ New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean;
+ Restoration : Boolean := False)
+ is
+ begin
+ if User_Entry (Interrupt).T /= Null_Task then
+ -- In case we have an Interrupt Entry already installed.
+ -- raise a program error. (propagate it to the caller).
+
+ Raise_Exception (Program_Error'Identity,
+ "An interrupt is already installed");
+ end if;
+
+ -- Note : A null handler with Static = True will
+ -- pass the following check. That is the case when we want to
+ -- Detach a handler regardless of the Static status
+ -- of the current_Handler.
+ -- We don't check anything if Restoration is True, since we
+ -- may be detaching a static handler to restore a dynamic one.
+
+ if not Restoration and then not Static
+ -- Tries to overwrite a static Interrupt Handler with a
+ -- dynamic Handler
+
+ and then (User_Handler (Interrupt).Static
+
+ -- The new handler is not specified as an
+ -- Interrupt Handler by a pragma.
+
+ or else not Is_Registered (New_Handler))
+ then
+ Raise_Exception (Program_Error'Identity,
+ "Trying to overwrite a static Interrupt Handler with a " &
+ "dynamic Handler");
+ end if;
+
+ -- The interrupt should no longer be ingnored if
+ -- it was ever ignored.
+
+ Ignored (Interrupt) := False;
+
+ -- Save the old handler
+
+ Old_Handler := User_Handler (Interrupt).H;
+
+ -- The new handler
+
+ User_Handler (Interrupt).H := New_Handler;
+
+ if New_Handler = null then
+
+ -- The null handler means we are detaching the handler.
+
+ User_Handler (Interrupt).Static := False;
+
+ else
+ User_Handler (Interrupt).Static := Static;
+ end if;
+
+ -- Invoke a corresponding Server_Task if not yet created.
+ -- Place Task_ID info in Server_ID array.
+
+ if Server_ID (Interrupt) = Null_Task then
+ Access_Hold := new Server_Task (Interrupt);
+ Server_ID (Interrupt) := To_System (Access_Hold.all'Identity);
+ else
+ POP.Wakeup (Server_ID (Interrupt), Interrupt_Server_Idle_Sleep);
+ end if;
+
+ end Unprotected_Exchange_Handler;
+
+ --------------------------------
+ -- Unprotected_Detach_Handler --
+ --------------------------------
+
+ procedure Unprotected_Detach_Handler
+ (Interrupt : Interrupt_ID;
+ Static : Boolean)
+ is
+ begin
+ if User_Entry (Interrupt).T /= Null_Task then
+ -- In case we have an Interrupt Entry installed.
+ -- raise a program error. (propagate it to the caller).
+
+ Raise_Exception (Program_Error'Identity,
+ "An interrupt entry is already installed");
+ end if;
+
+ -- Note : Static = True will pass the following check. That is the
+ -- case when we want to detach a handler regardless of the static
+ -- status of the current_Handler.
+
+ if not Static and then User_Handler (Interrupt).Static then
+ -- Tries to detach a static Interrupt Handler.
+ -- raise a program error.
+
+ Raise_Exception (Program_Error'Identity,
+ "Trying to detach a static Interrupt Handler");
+ end if;
+
+ -- The interrupt should no longer be ignored if
+ -- it was ever ignored.
+
+ Ignored (Interrupt) := False;
+
+ -- The new handler
+
+ User_Handler (Interrupt).H := null;
+ User_Handler (Interrupt).Static := False;
+ IMOP.Interrupt_Self_Process (IMNG.Interrupt_ID (Interrupt));
+
+ end Unprotected_Detach_Handler;
+
+ -- Start of processing for Interrupt_Manager
+
+ begin
+ -- By making this task independent of master, when the process
+ -- goes away, the Interrupt_Manager will terminate gracefully.
+
+ System.Tasking.Utilities.Make_Independent;
+
+ -- Environmen task gets its own interrupt mask, saves it,
+ -- and then masks all interrupts except the Keep_Unmasked set.
+
+ -- During rendezvous, the Interrupt_Manager receives the old
+ -- interrupt mask of the environment task, and sets its own
+ -- interrupt mask to that value.
+
+ -- The environment task will call the entry of Interrupt_Manager some
+ -- during elaboration of the body of this package.
+
+ accept Initialize (Mask : IMNG.Interrupt_Mask) do
+ pragma Warnings (Off, Mask);
+ null;
+ end Initialize;
+
+ -- Note: All tasks in RTS will have all the Reserve Interrupts
+ -- being masked (except the Interrupt_Manager) and Keep_Unmasked
+ -- unmasked when created.
+
+ -- Abort_Task_Interrupt is one of the Interrupt unmasked
+ -- in all tasks. We mask the Interrupt in this particular task
+ -- so that "sigwait" is possible to catch an explicitely sent
+ -- Abort_Task_Interrupt from the Server_Tasks.
+
+ -- This sigwaiting is needed so that we make sure a Server_Task is
+ -- out of its own sigwait state. This extra synchronization is
+ -- necessary to prevent following senarios.
+
+ -- 1) Interrupt_Manager sends an Abort_Task_Interrupt to the
+ -- Server_Task then changes its own interrupt mask (OS level).
+ -- If an interrupt (corresponding to the Server_Task) arrives
+ -- in the nean time we have the Interrupt_Manager umnasked and
+ -- the Server_Task waiting on sigwait.
+
+ -- 2) For unbinding handler, we install a default action in the
+ -- Interrupt_Manager. POSIX.1c states that the result of using
+ -- "sigwait" and "sigaction" simaltaneously on the same interrupt
+ -- is undefined. Therefore, we need to be informed from the
+ -- Server_Task of the fact that the Server_Task is out of its
+ -- sigwait stage.
+
+ loop
+ -- A block is needed to absorb Program_Error exception
+
+ declare
+ Old_Handler : Parameterless_Handler;
+ begin
+ select
+
+ accept Attach_Handler
+ (New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean;
+ Restoration : Boolean := False)
+ do
+ Unprotected_Exchange_Handler
+ (Old_Handler, New_Handler, Interrupt, Static, Restoration);
+ end Attach_Handler;
+
+ or accept Exchange_Handler
+ (Old_Handler : out Parameterless_Handler;
+ New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean)
+ do
+ Unprotected_Exchange_Handler
+ (Old_Handler, New_Handler, Interrupt, Static);
+ end Exchange_Handler;
+
+ or accept Detach_Handler
+ (Interrupt : Interrupt_ID;
+ Static : Boolean)
+ do
+ Unprotected_Detach_Handler (Interrupt, Static);
+ end Detach_Handler;
+
+ or accept Bind_Interrupt_To_Entry
+ (T : Task_ID;
+ E : Task_Entry_Index;
+ Interrupt : Interrupt_ID)
+ do
+ -- if there is a binding already (either a procedure or an
+ -- entry), raise Program_Error (propagate it to the caller).
+
+ if User_Handler (Interrupt).H /= null
+ or else User_Entry (Interrupt).T /= Null_Task
+ then
+ Raise_Exception (Program_Error'Identity,
+ "A binding for this interrupt is already present");
+ end if;
+
+ -- The interrupt should no longer be ingnored if
+ -- it was ever ignored.
+
+ Ignored (Interrupt) := False;
+ User_Entry (Interrupt) := Entry_Assoc'(T => T, E => E);
+
+ -- Indicate the attachment of Interrupt Entry in ATCB.
+ -- This is need so that when an Interrupt Entry task
+ -- terminates the binding can be cleaned.
+ -- The call to unbinding must be
+ -- make by the task before it terminates.
+
+ T.Interrupt_Entry := True;
+
+ -- Invoke a corresponding Server_Task if not yet created.
+ -- Place Task_ID info in Server_ID array.
+
+ if Server_ID (Interrupt) = Null_Task then
+
+ Access_Hold := new Server_Task (Interrupt);
+ Server_ID (Interrupt) :=
+ To_System (Access_Hold.all'Identity);
+ else
+ POP.Wakeup (Server_ID (Interrupt),
+ Interrupt_Server_Idle_Sleep);
+ end if;
+ end Bind_Interrupt_To_Entry;
+
+ or accept Detach_Interrupt_Entries (T : Task_ID)
+ do
+ for J in Interrupt_ID'Range loop
+ if not Is_Reserved (J) then
+ if User_Entry (J).T = T then
+
+ -- The interrupt should no longer be ignored if
+ -- it was ever ignored.
+
+ Ignored (J) := False;
+ User_Entry (J) :=
+ Entry_Assoc'(T => Null_Task, E => Null_Task_Entry);
+ IMOP.Interrupt_Self_Process (IMNG.Interrupt_ID (J));
+ end if;
+ end if;
+ end loop;
+
+ -- Indicate in ATCB that no Interrupt Entries are attached.
+
+ T.Interrupt_Entry := False;
+ end Detach_Interrupt_Entries;
+
+ or accept Block_Interrupt (Interrupt : Interrupt_ID) do
+ pragma Warnings (Off, Interrupt);
+ raise Program_Error;
+ end Block_Interrupt;
+
+ or accept Unblock_Interrupt (Interrupt : Interrupt_ID) do
+ pragma Warnings (Off, Interrupt);
+ raise Program_Error;
+ end Unblock_Interrupt;
+
+ or accept Ignore_Interrupt (Interrupt : Interrupt_ID) do
+ pragma Warnings (Off, Interrupt);
+ raise Program_Error;
+ end Ignore_Interrupt;
+
+ or accept Unignore_Interrupt (Interrupt : Interrupt_ID) do
+ pragma Warnings (Off, Interrupt);
+ raise Program_Error;
+ end Unignore_Interrupt;
+
+ end select;
+
+ exception
+ -- If there is a program error we just want to propagate it
+ -- to the caller and do not want to stop this task.
+
+ when Program_Error =>
+ null;
+
+ when others =>
+ pragma Assert (False);
+ null;
+ end;
+ end loop;
+ end Interrupt_Manager;
+
+ -----------------
+ -- Server_Task --
+ -----------------
+
+ task body Server_Task is
+ Self_ID : constant Task_ID := Self;
+ Tmp_Handler : Parameterless_Handler;
+ Tmp_ID : Task_ID;
+ Tmp_Entry_Index : Task_Entry_Index;
+ Intwait_Mask : aliased IMNG.Interrupt_Mask;
+
+ begin
+ -- By making this task independent of master, when the process
+ -- goes away, the Server_Task will terminate gracefully.
+
+ System.Tasking.Utilities.Make_Independent;
+
+ -- Install default action in system level.
+
+ IMOP.Install_Default_Action (IMNG.Interrupt_ID (Interrupt));
+
+ -- Set up the mask (also clears the event flag)
+
+ IMOP.Empty_Interrupt_Mask (Intwait_Mask'Access);
+ IMOP.Add_To_Interrupt_Mask
+ (Intwait_Mask'Access, IMNG.Interrupt_ID (Interrupt));
+
+ -- Remember the Interrupt_ID for Abort_Task.
+
+ PIO.Set_Interrupt_ID (IMNG.Interrupt_ID (Interrupt), Self_ID);
+
+ -- Note: All tasks in RTS will have all the Reserve Interrupts
+ -- being masked (except the Interrupt_Manager) and Keep_Unmasked
+ -- unmasked when created.
+
+ loop
+ System.Tasking.Initialization.Defer_Abort (Self_ID);
+
+ -- A Handler or an Entry is installed. At this point all tasks
+ -- mask for the Interrupt is masked. Catch the Interrupt using
+ -- sigwait.
+
+ -- This task may wake up from sigwait by receiving an interrupt
+ -- (Abort_Task_Interrupt) from the Interrupt_Manager for unbinding
+ -- a Procedure Handler or an Entry. Or it could be a wake up
+ -- from status change (Unblocked -> Blocked). If that is not
+ -- the case, we should exceute the attached Procedure or Entry.
+
+ if Single_Lock then
+ POP.Lock_RTS;
+ end if;
+
+ POP.Write_Lock (Self_ID);
+
+ if User_Handler (Interrupt).H = null
+ and then User_Entry (Interrupt).T = Null_Task
+ then
+ -- No Interrupt binding. If there is an interrupt,
+ -- Interrupt_Manager will take default action.
+
+ Self_ID.Common.State := Interrupt_Server_Idle_Sleep;
+ POP.Sleep (Self_ID, Interrupt_Server_Idle_Sleep);
+ Self_ID.Common.State := Runnable;
+
+ else
+ Self_ID.Common.State := Interrupt_Server_Blocked_On_Event_Flag;
+ Self_ID.Common.State := Runnable;
+
+ if not (Self_ID.Deferral_Level = 0
+ and then Self_ID.Pending_ATC_Level
+ < Self_ID.ATC_Nesting_Level)
+ then
+ if User_Handler (Interrupt).H /= null then
+ Tmp_Handler := User_Handler (Interrupt).H;
+
+ -- RTS calls should not be made with self being locked.
+
+ POP.Unlock (Self_ID);
+
+ if Single_Lock then
+ POP.Unlock_RTS;
+ end if;
+
+ Tmp_Handler.all;
+
+ if Single_Lock then
+ POP.Lock_RTS;
+ end if;
+
+ POP.Write_Lock (Self_ID);
+
+ elsif User_Entry (Interrupt).T /= Null_Task then
+ Tmp_ID := User_Entry (Interrupt).T;
+ Tmp_Entry_Index := User_Entry (Interrupt).E;
+
+ -- RTS calls should not be made with self being locked.
+
+ POP.Unlock (Self_ID);
+
+ if Single_Lock then
+ POP.Unlock_RTS;
+ end if;
+
+ System.Tasking.Rendezvous.Call_Simple
+ (Tmp_ID, Tmp_Entry_Index, System.Null_Address);
+
+ if Single_Lock then
+ POP.Lock_RTS;
+ end if;
+
+ POP.Write_Lock (Self_ID);
+ end if;
+ end if;
+ end if;
+
+ POP.Unlock (Self_ID);
+
+ if Single_Lock then
+ POP.Unlock_RTS;
+ end if;
+
+ System.Tasking.Initialization.Undefer_Abort (Self_ID);
+
+ -- Undefer abort here to allow a window for this task
+ -- to be aborted at the time of system shutdown.
+ end loop;
+ end Server_Task;
+
+ -------------------------------------
+ -- Has_Interrupt_Or_Attach_Handler --
+ -------------------------------------
+
+ function Has_Interrupt_Or_Attach_Handler
+ (Object : access Dynamic_Interrupt_Protection)
+ return Boolean
+ is
+ pragma Warnings (Off, Object);
+
+ begin
+ return True;
+ end Has_Interrupt_Or_Attach_Handler;
+
+ ----------------
+ -- Finalize --
+ ----------------
+
+ procedure Finalize (Object : in out Static_Interrupt_Protection) is
+ begin
+ -- ??? loop to be executed only when we're not doing library level
+ -- finalization, since in this case all interrupt tasks are gone.
+ if not Interrupt_Manager'Terminated then
+ for N in reverse Object.Previous_Handlers'Range loop
+ Interrupt_Manager.Attach_Handler
+ (New_Handler => Object.Previous_Handlers (N).Handler,
+ Interrupt => Object.Previous_Handlers (N).Interrupt,
+ Static => Object.Previous_Handlers (N).Static,
+ Restoration => True);
+ end loop;
+ end if;
+
+ Tasking.Protected_Objects.Entries.Finalize
+ (Tasking.Protected_Objects.Entries.Protection_Entries (Object));
+ end Finalize;
+
+ -------------------------------------
+ -- Has_Interrupt_Or_Attach_Handler --
+ -------------------------------------
+
+ function Has_Interrupt_Or_Attach_Handler
+ (Object : access Static_Interrupt_Protection)
+ return Boolean
+ is
+ pragma Warnings (Off, Object);
+ begin
+ return True;
+ end Has_Interrupt_Or_Attach_Handler;
+
+ ----------------------
+ -- Install_Handlers --
+ ----------------------
+
+ procedure Install_Handlers
+ (Object : access Static_Interrupt_Protection;
+ New_Handlers : New_Handler_Array)
+ is
+ begin
+ for N in New_Handlers'Range loop
+
+ -- We need a lock around this ???
+
+ Object.Previous_Handlers (N).Interrupt := New_Handlers (N).Interrupt;
+ Object.Previous_Handlers (N).Static := User_Handler
+ (New_Handlers (N).Interrupt).Static;
+
+ -- We call Exchange_Handler and not directly Interrupt_Manager.
+ -- Exchange_Handler so we get the Is_Reserved check.
+
+ Exchange_Handler
+ (Old_Handler => Object.Previous_Handlers (N).Handler,
+ New_Handler => New_Handlers (N).Handler,
+ Interrupt => New_Handlers (N).Interrupt,
+ Static => True);
+ end loop;
+ end Install_Handlers;
+
+-- Elaboration code for package System.Interrupts
+begin
+
+ -- Get Interrupt_Manager's ID so that Abort_Interrupt can be sent.
+
+ Interrupt_Manager_ID := To_System (Interrupt_Manager'Identity);
+
+ -- During the elaboration of this package body we want RTS to
+ -- inherit the interrupt mask from the Environment Task.
+
+ -- The Environment Task should have gotten its mask from
+ -- the enclosing process during the RTS start up. (See
+ -- in s-inmaop.adb). Pass the Interrupt_Mask of the Environment
+ -- task to the Interrupt_Manager.
+
+ -- Note : At this point we know that all tasks (including
+ -- RTS internal servers) are masked for non-reserved signals
+ -- (see s-taprop.adb). Only the Interrupt_Manager will have
+ -- masks set up differently inheriting the original Environment
+ -- Task's mask.
+
+ Interrupt_Manager.Initialize (IMOP.Environment_Mask);
+end System.Interrupts;
diff --git a/gcc/ada/s-interr-vxworks.adb b/gcc/ada/s-interr-vxworks.adb
new file mode 100644
index 00000000000..5898e6d7e26
--- /dev/null
+++ b/gcc/ada/s-interr-vxworks.adb
@@ -0,0 +1,1146 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . I N T E R R U P T S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2004, 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+------------------------------------------------------------------------------
+
+-- Invariants:
+
+-- All user-handleable signals are masked at all times in all
+-- tasks/threads except possibly for the Interrupt_Manager task.
+
+-- When a user task wants to have the effect of masking/unmasking an
+-- signal, it must call Block_Interrupt/Unblock_Interrupt, which
+-- will have the effect of unmasking/masking the signal in the
+-- Interrupt_Manager task. These comments do not apply to vectored
+-- hardware interrupts, which may be masked or unmasked using routined
+-- interfaced to the relevant VxWorks system calls.
+
+-- Once we associate a Signal_Server_Task with an signal, the task never
+-- goes away, and we never remove the association. On the other hand, it
+-- is more convenient to terminate an associated Interrupt_Server_Task
+-- for a vectored hardware interrupt (since we use a binary semaphore
+-- for synchronization with the umbrella handler).
+
+-- There is no more than one signal per Signal_Server_Task and no more than
+-- one Signal_Server_Task per signal. The same relation holds for hardware
+-- interrupts and Interrupt_Server_Task's at any given time. That is,
+-- only one non-terminated Interrupt_Server_Task exists for a give
+-- interrupt at any time.
+
+-- Within this package, the lock L is used to protect the various status
+-- tables. If there is a Server_Task associated with a signal or interrupt,
+-- we use the per-task lock of the Server_Task instead so that we protect the
+-- status between Interrupt_Manager and Server_Task. Protection among
+-- service requests are ensured via user calls to the Interrupt_Manager
+-- entries.
+
+-- This is the VxWorks version of this package, supporting vectored hardware
+-- interrupts.
+
+with Unchecked_Conversion;
+
+with System.OS_Interface; use System.OS_Interface;
+
+with Interfaces.VxWorks;
+
+with Ada.Task_Identification;
+-- used for Task_ID type
+
+with Ada.Exceptions;
+-- used for Raise_Exception
+
+with System.Interrupt_Management;
+-- used for Reserve
+
+with System.Task_Primitives.Operations;
+-- used for Write_Lock
+-- Unlock
+-- Abort
+-- Wakeup_Task
+-- Sleep
+-- Initialize_Lock
+
+with System.Storage_Elements;
+-- used for To_Address
+-- To_Integer
+-- Integer_Address
+
+with System.Tasking;
+-- used for Task_ID
+-- Task_Entry_Index
+-- Null_Task
+-- Self
+-- Interrupt_Manager_ID
+
+with System.Tasking.Utilities;
+-- used for Make_Independent
+
+with System.Tasking.Rendezvous;
+-- used for Call_Simple
+pragma Elaborate_All (System.Tasking.Rendezvous);
+
+package body System.Interrupts is
+
+ use Tasking;
+ use Ada.Exceptions;
+
+ package POP renames System.Task_Primitives.Operations;
+
+ function To_Ada is new Unchecked_Conversion
+ (System.Tasking.Task_ID, Ada.Task_Identification.Task_Id);
+
+ function To_System is new Unchecked_Conversion
+ (Ada.Task_Identification.Task_Id, Task_ID);
+
+ -----------------
+ -- Local Tasks --
+ -----------------
+
+ -- WARNING: System.Tasking.Stages performs calls to this task
+ -- with low-level constructs. Do not change this spec without synchro-
+ -- nizing it.
+
+ task Interrupt_Manager is
+ entry Detach_Interrupt_Entries (T : Task_ID);
+
+ entry Attach_Handler
+ (New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean;
+ Restoration : Boolean := False);
+
+ entry Exchange_Handler
+ (Old_Handler : out Parameterless_Handler;
+ New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean);
+
+ entry Detach_Handler
+ (Interrupt : Interrupt_ID;
+ Static : Boolean);
+
+ entry Bind_Interrupt_To_Entry
+ (T : Task_ID;
+ E : Task_Entry_Index;
+ Interrupt : Interrupt_ID);
+
+ pragma Interrupt_Priority (System.Interrupt_Priority'First);
+ end Interrupt_Manager;
+
+ task type Interrupt_Server_Task
+ (Interrupt : Interrupt_ID; Int_Sema : SEM_ID) is
+ -- Server task for vectored hardware interrupt handling
+ pragma Interrupt_Priority (System.Interrupt_Priority'First + 2);
+ end Interrupt_Server_Task;
+
+ type Interrupt_Task_Access is access Interrupt_Server_Task;
+
+ -------------------------------
+ -- Local Types and Variables --
+ -------------------------------
+
+ type Entry_Assoc is record
+ T : Task_ID;
+ E : Task_Entry_Index;
+ end record;
+
+ type Handler_Assoc is record
+ H : Parameterless_Handler;
+ Static : Boolean; -- Indicates static binding;
+ end record;
+
+ User_Handler : array (Interrupt_ID) of Handler_Assoc :=
+ (others => (null, Static => False));
+ pragma Volatile_Components (User_Handler);
+ -- Holds the protected procedure handler (if any) and its Static
+ -- information for each interrupt or signal. A handler is static
+ -- iff it is specified through the pragma Attach_Handler.
+
+ User_Entry : array (Interrupt_ID) of Entry_Assoc :=
+ (others => (T => Null_Task, E => Null_Task_Entry));
+ pragma Volatile_Components (User_Entry);
+ -- Holds the task and entry index (if any) for each interrupt / signal
+
+ -- Type and Head, Tail of the list containing Registered Interrupt
+ -- Handlers. These definitions are used to register the handlers
+ -- specified by the pragma Interrupt_Handler.
+
+ type Registered_Handler;
+ type R_Link is access all Registered_Handler;
+
+ type Registered_Handler is record
+ H : System.Address := System.Null_Address;
+ Next : R_Link := null;
+ end record;
+
+ Registered_Handler_Head : R_Link := null;
+ Registered_Handler_Tail : R_Link := null;
+
+ Server_ID : array (Interrupt_ID) of System.Tasking.Task_ID :=
+ (others => System.Tasking.Null_Task);
+ pragma Atomic_Components (Server_ID);
+ -- Holds the Task_ID of the Server_Task for each interrupt / signal.
+ -- Task_ID is needed to accomplish locking per interrupt base. Also
+ -- is needed to determine whether to create a new Server_Task.
+
+ Semaphore_ID_Map : array
+ (Interrupt_ID range 0 .. System.OS_Interface.Max_HW_Interrupt)
+ of SEM_ID := (others => 0);
+ -- Array of binary semaphores associated with vectored interrupts
+ -- Note that the last bound should be Max_HW_Interrupt, but this will raise
+ -- Storage_Error if Num_HW_Interrupts is null, so use an extra 4 bytes
+ -- instead.
+
+ Interrupt_Access_Hold : Interrupt_Task_Access;
+ -- Variable for allocating an Interrupt_Server_Task
+
+ Default_Handler : array (HW_Interrupt) of Interfaces.VxWorks.VOIDFUNCPTR;
+ -- Vectored interrupt handlers installed prior to program startup.
+ -- These are saved only when the umbrella handler is installed for
+ -- a given interrupt number.
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ procedure Check_Reserved_Interrupt (Interrupt : Interrupt_ID);
+ -- Check if Id is a reserved interrupt, and if so raise Program_Error
+ -- with an appropriate message, otherwise return.
+
+ procedure Finalize_Interrupt_Servers;
+ -- Unbind the handlers for hardware interrupt server tasks at program
+ -- termination.
+
+ function Is_Registered (Handler : Parameterless_Handler) return Boolean;
+ -- See if Handler has been "pragma"ed using Interrupt_Handler.
+ -- Always consider a null handler as registered.
+
+ procedure Notify_Interrupt (Param : System.Address);
+ -- Umbrella handler for vectored interrupts (not signals)
+
+ procedure Install_Default_Action (Interrupt : HW_Interrupt);
+ -- Restore a handler that was in place prior to program execution
+
+ procedure Install_Umbrella_Handler
+ (Interrupt : HW_Interrupt;
+ Handler : Interfaces.VxWorks.VOIDFUNCPTR);
+ -- Install the runtime umbrella handler for a vectored hardware
+ -- interrupt
+
+ procedure Unimplemented (Feature : String);
+ pragma No_Return (Unimplemented);
+ -- Used to mark a call to an unimplemented function. Raises Program_Error
+ -- with an appropriate message noting that Feature is unimplemented.
+
+ --------------------
+ -- Attach_Handler --
+ --------------------
+
+ -- Calling this procedure with New_Handler = null and Static = True
+ -- means we want to detach the current handler regardless of the
+ -- previous handler's binding status (ie. do not care if it is a
+ -- dynamic or static handler).
+
+ -- This option is needed so that during the finalization of a PO, we
+ -- can detach handlers attached through pragma Attach_Handler.
+
+ procedure Attach_Handler
+ (New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean := False) is
+ begin
+ Check_Reserved_Interrupt (Interrupt);
+ Interrupt_Manager.Attach_Handler (New_Handler, Interrupt, Static);
+ end Attach_Handler;
+
+ -----------------------------
+ -- Bind_Interrupt_To_Entry --
+ -----------------------------
+
+ -- This procedure raises a Program_Error if it tries to
+ -- bind an interrupt to which an Entry or a Procedure is
+ -- already bound.
+
+ procedure Bind_Interrupt_To_Entry
+ (T : Task_ID;
+ E : Task_Entry_Index;
+ Int_Ref : System.Address)
+ is
+ Interrupt : constant Interrupt_ID :=
+ Interrupt_ID (Storage_Elements.To_Integer (Int_Ref));
+
+ begin
+ Check_Reserved_Interrupt (Interrupt);
+ Interrupt_Manager.Bind_Interrupt_To_Entry (T, E, Interrupt);
+ end Bind_Interrupt_To_Entry;
+
+ ---------------------
+ -- Block_Interrupt --
+ ---------------------
+
+ procedure Block_Interrupt (Interrupt : Interrupt_ID) is
+ begin
+ Unimplemented ("Block_Interrupt");
+ end Block_Interrupt;
+
+ ------------------------------
+ -- Check_Reserved_Interrupt --
+ ------------------------------
+
+ procedure Check_Reserved_Interrupt (Interrupt : Interrupt_ID) is
+ begin
+ if Is_Reserved (Interrupt) then
+ Raise_Exception
+ (Program_Error'Identity,
+ "Interrupt" & Interrupt_ID'Image (Interrupt) & " is reserved");
+ else
+ return;
+ end if;
+ end Check_Reserved_Interrupt;
+
+ ---------------------
+ -- Current_Handler --
+ ---------------------
+
+ function Current_Handler
+ (Interrupt : Interrupt_ID) return Parameterless_Handler is
+ begin
+ Check_Reserved_Interrupt (Interrupt);
+
+ -- ??? Since Parameterless_Handler is not Atomic, the
+ -- current implementation is wrong. We need a new service in
+ -- Interrupt_Manager to ensure atomicity.
+
+ return User_Handler (Interrupt).H;
+ end Current_Handler;
+
+ --------------------
+ -- Detach_Handler --
+ --------------------
+
+ -- Calling this procedure with Static = True means we want to Detach the
+ -- current handler regardless of the previous handler's binding status
+ -- (i.e. do not care if it is a dynamic or static handler).
+
+ -- This option is needed so that during the finalization of a PO, we can
+ -- detach handlers attached through pragma Attach_Handler.
+
+ procedure Detach_Handler
+ (Interrupt : Interrupt_ID;
+ Static : Boolean := False) is
+ begin
+ Check_Reserved_Interrupt (Interrupt);
+ Interrupt_Manager.Detach_Handler (Interrupt, Static);
+ end Detach_Handler;
+
+ ------------------------------
+ -- Detach_Interrupt_Entries --
+ ------------------------------
+
+ procedure Detach_Interrupt_Entries (T : Task_ID) is
+ begin
+ Interrupt_Manager.Detach_Interrupt_Entries (T);
+ end Detach_Interrupt_Entries;
+
+ ----------------------
+ -- Exchange_Handler --
+ ----------------------
+
+ -- Calling this procedure with New_Handler = null and Static = True
+ -- means we want to detach the current handler regardless of the
+ -- previous handler's binding status (ie. do not care if it is a
+ -- dynamic or static handler).
+
+ -- This option is needed so that during the finalization of a PO, we
+ -- can detach handlers attached through pragma Attach_Handler.
+
+ procedure Exchange_Handler
+ (Old_Handler : out Parameterless_Handler;
+ New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean := False) is
+ begin
+ Check_Reserved_Interrupt (Interrupt);
+ Interrupt_Manager.Exchange_Handler
+ (Old_Handler, New_Handler, Interrupt, Static);
+ end Exchange_Handler;
+
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize (Object : in out Static_Interrupt_Protection) is
+ begin
+ -- ??? loop to be executed only when we're not doing library level
+ -- finalization, since in this case all interrupt / signal tasks are
+ -- gone.
+
+ if not Interrupt_Manager'Terminated then
+ for N in reverse Object.Previous_Handlers'Range loop
+ Interrupt_Manager.Attach_Handler
+ (New_Handler => Object.Previous_Handlers (N).Handler,
+ Interrupt => Object.Previous_Handlers (N).Interrupt,
+ Static => Object.Previous_Handlers (N).Static,
+ Restoration => True);
+ end loop;
+ end if;
+
+ Tasking.Protected_Objects.Entries.Finalize
+ (Tasking.Protected_Objects.Entries.Protection_Entries (Object));
+ end Finalize;
+
+ --------------------------------
+ -- Finalize_Interrupt_Servers --
+ --------------------------------
+
+ -- Restore default handlers for interrupt servers.
+
+ -- This is called by the Interrupt_Manager task when it receives the abort
+ -- signal during program finalization.
+
+ procedure Finalize_Interrupt_Servers is
+ HW_Interrupts : constant Boolean := HW_Interrupt'Last >= 0;
+
+ begin
+ if HW_Interrupts then
+ for Int in HW_Interrupt loop
+ if Server_ID (Interrupt_ID (Int)) /= null
+ and then
+ not Ada.Task_Identification.Is_Terminated
+ (To_Ada (Server_ID (Interrupt_ID (Int))))
+ then
+ Interrupt_Manager.Attach_Handler
+ (New_Handler => null,
+ Interrupt => Interrupt_ID (Int),
+ Static => True,
+ Restoration => True);
+ end if;
+ end loop;
+ end if;
+ end Finalize_Interrupt_Servers;
+
+ -------------------------------------
+ -- Has_Interrupt_Or_Attach_Handler --
+ -------------------------------------
+
+ function Has_Interrupt_Or_Attach_Handler
+ (Object : access Dynamic_Interrupt_Protection)
+ return Boolean
+ is
+ pragma Unreferenced (Object);
+
+ begin
+ return True;
+ end Has_Interrupt_Or_Attach_Handler;
+
+ function Has_Interrupt_Or_Attach_Handler
+ (Object : access Static_Interrupt_Protection)
+ return Boolean
+ is
+ pragma Unreferenced (Object);
+
+ begin
+ return True;
+ end Has_Interrupt_Or_Attach_Handler;
+
+ ----------------------
+ -- Ignore_Interrupt --
+ ----------------------
+
+ procedure Ignore_Interrupt (Interrupt : Interrupt_ID) is
+ begin
+ Unimplemented ("Ignore_Interrupt");
+ end Ignore_Interrupt;
+
+ ----------------------------
+ -- Install_Default_Action --
+ ----------------------------
+
+ procedure Install_Default_Action (Interrupt : HW_Interrupt) is
+ begin
+ -- Restore original interrupt handler
+
+ Interfaces.VxWorks.intVecSet
+ (Interfaces.VxWorks.INUM_TO_IVEC (Integer (Interrupt)),
+ Default_Handler (Interrupt));
+ Default_Handler (Interrupt) := null;
+ end Install_Default_Action;
+
+ ----------------------
+ -- Install_Handlers --
+ ----------------------
+
+ procedure Install_Handlers
+ (Object : access Static_Interrupt_Protection;
+ New_Handlers : New_Handler_Array) is
+ begin
+ for N in New_Handlers'Range loop
+ -- We need a lock around this ???
+
+ Object.Previous_Handlers (N).Interrupt := New_Handlers (N).Interrupt;
+ Object.Previous_Handlers (N).Static := User_Handler
+ (New_Handlers (N).Interrupt).Static;
+
+ -- We call Exchange_Handler and not directly Interrupt_Manager.
+ -- Exchange_Handler so we get the Is_Reserved check.
+
+ Exchange_Handler
+ (Old_Handler => Object.Previous_Handlers (N).Handler,
+ New_Handler => New_Handlers (N).Handler,
+ Interrupt => New_Handlers (N).Interrupt,
+ Static => True);
+ end loop;
+ end Install_Handlers;
+
+ ------------------------------
+ -- Install_Umbrella_Handler --
+ ------------------------------
+
+ procedure Install_Umbrella_Handler
+ (Interrupt : HW_Interrupt;
+ Handler : Interfaces.VxWorks.VOIDFUNCPTR)
+ is
+ use Interfaces.VxWorks;
+
+ Vec : constant Interrupt_Vector :=
+ INUM_TO_IVEC (Interfaces.VxWorks.int (Interrupt));
+
+ Old_Handler : constant VOIDFUNCPTR :=
+ intVecGet
+ (INUM_TO_IVEC (Interfaces.VxWorks.int (Interrupt)));
+
+ Stat : Interfaces.VxWorks.STATUS;
+ pragma Unreferenced (Stat);
+ -- ??? shouldn't we test Stat at least in a pragma Assert?
+
+ begin
+ -- Only install umbrella handler when no Ada handler has already been
+ -- installed. Note that the interrupt number is passed as a parameter
+ -- when an interrupt occurs, so the umbrella handler has a different
+ -- wrapper generated by intConnect for each interrupt number.
+
+ if Default_Handler (Interrupt) = null then
+ Stat :=
+ intConnect (Vec, Handler, System.Address (Interrupt));
+ Default_Handler (Interrupt) := Old_Handler;
+ end if;
+ end Install_Umbrella_Handler;
+
+ ----------------
+ -- Is_Blocked --
+ ----------------
+
+ function Is_Blocked (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ Unimplemented ("Is_Blocked");
+ return False;
+ end Is_Blocked;
+
+ -----------------------
+ -- Is_Entry_Attached --
+ -----------------------
+
+ function Is_Entry_Attached (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ Check_Reserved_Interrupt (Interrupt);
+ return User_Entry (Interrupt).T /= Null_Task;
+ end Is_Entry_Attached;
+
+ -------------------------
+ -- Is_Handler_Attached --
+ -------------------------
+
+ function Is_Handler_Attached (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ Check_Reserved_Interrupt (Interrupt);
+ return User_Handler (Interrupt).H /= null;
+ end Is_Handler_Attached;
+
+ ----------------
+ -- Is_Ignored --
+ ----------------
+
+ function Is_Ignored (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ Unimplemented ("Is_Ignored");
+ return False;
+ end Is_Ignored;
+
+ -------------------
+ -- Is_Registered --
+ -------------------
+
+ function Is_Registered (Handler : Parameterless_Handler) return Boolean is
+ type Fat_Ptr is record
+ Object_Addr : System.Address;
+ Handler_Addr : System.Address;
+ end record;
+
+ function To_Fat_Ptr is new Unchecked_Conversion
+ (Parameterless_Handler, Fat_Ptr);
+
+ Ptr : R_Link;
+ Fat : Fat_Ptr;
+
+ begin
+ if Handler = null then
+ return True;
+ end if;
+
+ Fat := To_Fat_Ptr (Handler);
+
+ Ptr := Registered_Handler_Head;
+
+ while Ptr /= null loop
+ if Ptr.H = Fat.Handler_Addr then
+ return True;
+ end if;
+
+ Ptr := Ptr.Next;
+ end loop;
+
+ return False;
+ end Is_Registered;
+
+ -----------------
+ -- Is_Reserved --
+ -----------------
+
+ function Is_Reserved (Interrupt : Interrupt_ID) return Boolean is
+ use System.Interrupt_Management;
+ begin
+ return Reserve (System.Interrupt_Management.Interrupt_ID (Interrupt));
+ end Is_Reserved;
+
+ ----------------------
+ -- Notify_Interrupt --
+ ----------------------
+
+ -- Umbrella handler for vectored hardware interrupts (as opposed to
+ -- signals and exceptions). As opposed to the signal implementation,
+ -- this handler is only installed in the vector table while there is
+ -- an active association of an Ada handler to the interrupt.
+
+ -- Otherwise, the handler that existed prior to program startup is
+ -- in the vector table. This ensures that handlers installed by
+ -- the BSP are active unless explicitly replaced in the program text.
+
+ -- Each Interrupt_Server_Task has an associated binary semaphore
+ -- on which it pends once it's been started. This routine determines
+ -- The appropriate semaphore and and issues a semGive call, waking
+ -- the server task. When a handler is unbound,
+ -- System.Interrupts.Unbind_Handler issues a semFlush, and the
+ -- server task deletes its semaphore and terminates.
+
+ procedure Notify_Interrupt (Param : System.Address) is
+ Interrupt : constant Interrupt_ID := Interrupt_ID (Param);
+
+ Discard_Result : STATUS;
+ pragma Unreferenced (Discard_Result);
+
+ begin
+ Discard_Result := semGive (Semaphore_ID_Map (Interrupt));
+ end Notify_Interrupt;
+
+ ---------------
+ -- Reference --
+ ---------------
+
+ function Reference (Interrupt : Interrupt_ID) return System.Address is
+ begin
+ Check_Reserved_Interrupt (Interrupt);
+ return Storage_Elements.To_Address
+ (Storage_Elements.Integer_Address (Interrupt));
+ end Reference;
+
+ --------------------------------
+ -- Register_Interrupt_Handler --
+ --------------------------------
+
+ procedure Register_Interrupt_Handler (Handler_Addr : System.Address) is
+ New_Node_Ptr : R_Link;
+ begin
+ -- This routine registers a handler as usable for dynamic
+ -- interrupt handler association. Routines attaching and detaching
+ -- handlers dynamically should determine whether the handler is
+ -- registered. Program_Error should be raised if it is not registered.
+
+ -- Pragma Interrupt_Handler can only appear in a library
+ -- level PO definition and instantiation. Therefore, we do not need
+ -- to implement an unregister operation. Nor do we need to
+ -- protect the queue structure with a lock.
+
+ pragma Assert (Handler_Addr /= System.Null_Address);
+
+ New_Node_Ptr := new Registered_Handler;
+ New_Node_Ptr.H := Handler_Addr;
+
+ if Registered_Handler_Head = null then
+ Registered_Handler_Head := New_Node_Ptr;
+ Registered_Handler_Tail := New_Node_Ptr;
+
+ else
+ Registered_Handler_Tail.Next := New_Node_Ptr;
+ Registered_Handler_Tail := New_Node_Ptr;
+ end if;
+ end Register_Interrupt_Handler;
+
+ -----------------------
+ -- Unblock_Interrupt --
+ -----------------------
+
+ procedure Unblock_Interrupt (Interrupt : Interrupt_ID) is
+ begin
+ Unimplemented ("Unblock_Interrupt");
+ end Unblock_Interrupt;
+
+ ------------------
+ -- Unblocked_By --
+ ------------------
+
+ function Unblocked_By
+ (Interrupt : Interrupt_ID) return System.Tasking.Task_ID is
+ begin
+ Unimplemented ("Unblocked_By");
+ return Null_Task;
+ end Unblocked_By;
+
+ ------------------------
+ -- Unignore_Interrupt --
+ ------------------------
+
+ procedure Unignore_Interrupt (Interrupt : Interrupt_ID) is
+ begin
+ Unimplemented ("Unignore_Interrupt");
+ end Unignore_Interrupt;
+
+ -------------------
+ -- Unimplemented --
+ -------------------
+
+ procedure Unimplemented (Feature : String) is
+ begin
+ Raise_Exception
+ (Program_Error'Identity,
+ Feature & " not implemented on VxWorks");
+ end Unimplemented;
+
+ -----------------------
+ -- Interrupt_Manager --
+ -----------------------
+
+ task body Interrupt_Manager is
+
+ --------------------
+ -- Local Routines --
+ --------------------
+
+ procedure Bind_Handler (Interrupt : Interrupt_ID);
+ -- This procedure does not do anything if a signal is blocked.
+ -- Otherwise, we have to interrupt Server_Task for status change through
+ -- a wakeup signal.
+
+ procedure Unbind_Handler (Interrupt : Interrupt_ID);
+ -- This procedure does not do anything if a signal is blocked.
+ -- Otherwise, we have to interrupt Server_Task for status change
+ -- through an abort signal.
+
+ procedure Unprotected_Exchange_Handler
+ (Old_Handler : out Parameterless_Handler;
+ New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean;
+ Restoration : Boolean := False);
+
+ procedure Unprotected_Detach_Handler
+ (Interrupt : Interrupt_ID;
+ Static : Boolean);
+
+ ------------------
+ -- Bind_Handler --
+ ------------------
+
+ procedure Bind_Handler (Interrupt : Interrupt_ID) is
+ begin
+ Install_Umbrella_Handler
+ (HW_Interrupt (Interrupt), Notify_Interrupt'Access);
+ end Bind_Handler;
+
+ --------------------
+ -- Unbind_Handler --
+ --------------------
+
+ procedure Unbind_Handler (Interrupt : Interrupt_ID) is
+ S : STATUS;
+ use type STATUS;
+
+ begin
+ -- Hardware interrupt
+
+ Install_Default_Action (HW_Interrupt (Interrupt));
+
+ -- Flush server task off semaphore, allowing it to terminate
+
+ S := semFlush (Semaphore_ID_Map (Interrupt));
+ pragma Assert (S = 0);
+ end Unbind_Handler;
+
+ --------------------------------
+ -- Unprotected_Detach_Handler --
+ --------------------------------
+
+ procedure Unprotected_Detach_Handler
+ (Interrupt : Interrupt_ID;
+ Static : Boolean)
+ is
+ Old_Handler : Parameterless_Handler;
+ begin
+ if User_Entry (Interrupt).T /= Null_Task then
+ -- If an interrupt entry is installed raise
+ -- Program_Error. (propagate it to the caller).
+
+ Raise_Exception (Program_Error'Identity,
+ "An interrupt entry is already installed");
+ end if;
+
+ -- Note : Static = True will pass the following check. This is the
+ -- case when we want to detach a handler regardless of the static
+ -- status of the Current_Handler.
+
+ if not Static and then User_Handler (Interrupt).Static then
+ -- Trying to detach a static Interrupt Handler.
+ -- raise Program_Error.
+
+ Raise_Exception (Program_Error'Identity,
+ "Trying to detach a static Interrupt Handler");
+ end if;
+
+ Old_Handler := User_Handler (Interrupt).H;
+
+ -- The new handler
+
+ User_Handler (Interrupt).H := null;
+ User_Handler (Interrupt).Static := False;
+
+ if Old_Handler /= null then
+ Unbind_Handler (Interrupt);
+ end if;
+ end Unprotected_Detach_Handler;
+
+ ----------------------------------
+ -- Unprotected_Exchange_Handler --
+ ----------------------------------
+
+ procedure Unprotected_Exchange_Handler
+ (Old_Handler : out Parameterless_Handler;
+ New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean;
+ Restoration : Boolean := False) is
+ begin
+ if User_Entry (Interrupt).T /= Null_Task then
+ -- If an interrupt entry is already installed, raise
+ -- Program_Error. (propagate it to the caller).
+
+ Raise_Exception
+ (Program_Error'Identity,
+ "An interrupt is already installed");
+ end if;
+
+ -- Note : A null handler with Static = True will
+ -- pass the following check. This is the case when we want to
+ -- detach a handler regardless of the Static status
+ -- of Current_Handler.
+ -- We don't check anything if Restoration is True, since we
+ -- may be detaching a static handler to restore a dynamic one.
+
+ if not Restoration and then not Static
+ and then (User_Handler (Interrupt).Static
+
+ -- Trying to overwrite a static Interrupt Handler with a
+ -- dynamic Handler
+
+ -- The new handler is not specified as an
+ -- Interrupt Handler by a pragma.
+
+ or else not Is_Registered (New_Handler))
+ then
+ Raise_Exception
+ (Program_Error'Identity,
+ "Trying to overwrite a static Interrupt Handler with a " &
+ "dynamic Handler");
+ end if;
+
+ -- Save the old handler
+
+ Old_Handler := User_Handler (Interrupt).H;
+
+ -- The new handler
+
+ User_Handler (Interrupt).H := New_Handler;
+
+ if New_Handler = null then
+
+ -- The null handler means we are detaching the handler.
+
+ User_Handler (Interrupt).Static := False;
+
+ else
+ User_Handler (Interrupt).Static := Static;
+ end if;
+
+ -- Invoke a corresponding Server_Task if not yet created.
+ -- Place Task_ID info in Server_ID array.
+
+ if New_Handler /= null
+ and then
+ (Server_ID (Interrupt) = Null_Task
+ or else
+ Ada.Task_Identification.Is_Terminated
+ (To_Ada (Server_ID (Interrupt))))
+ then
+ Interrupt_Access_Hold :=
+ new Interrupt_Server_Task
+ (Interrupt, semBCreate (SEM_Q_FIFO, SEM_EMPTY));
+ Server_ID (Interrupt) :=
+ To_System (Interrupt_Access_Hold.all'Identity);
+ end if;
+
+ if (New_Handler = null) and then Old_Handler /= null then
+ -- Restore default handler
+
+ Unbind_Handler (Interrupt);
+
+ elsif Old_Handler = null then
+ -- Save default handler
+
+ Bind_Handler (Interrupt);
+ end if;
+ end Unprotected_Exchange_Handler;
+
+ -- Start of processing for Interrupt_Manager
+
+ begin
+ -- By making this task independent of any master, when the process
+ -- goes away, the Interrupt_Manager will terminate gracefully.
+
+ System.Tasking.Utilities.Make_Independent;
+
+ loop
+ -- A block is needed to absorb Program_Error exception
+
+ declare
+ Old_Handler : Parameterless_Handler;
+
+ begin
+ select
+ accept Attach_Handler
+ (New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean;
+ Restoration : Boolean := False)
+ do
+ Unprotected_Exchange_Handler
+ (Old_Handler, New_Handler, Interrupt, Static, Restoration);
+ end Attach_Handler;
+
+ or
+ accept Exchange_Handler
+ (Old_Handler : out Parameterless_Handler;
+ New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean)
+ do
+ Unprotected_Exchange_Handler
+ (Old_Handler, New_Handler, Interrupt, Static);
+ end Exchange_Handler;
+
+ or
+ accept Detach_Handler
+ (Interrupt : Interrupt_ID;
+ Static : Boolean)
+ do
+ Unprotected_Detach_Handler (Interrupt, Static);
+ end Detach_Handler;
+ or
+ accept Bind_Interrupt_To_Entry
+ (T : Task_ID;
+ E : Task_Entry_Index;
+ Interrupt : Interrupt_ID)
+ do
+ -- If there is a binding already (either a procedure or an
+ -- entry), raise Program_Error (propagate it to the caller).
+
+ if User_Handler (Interrupt).H /= null
+ or else User_Entry (Interrupt).T /= Null_Task
+ then
+ Raise_Exception
+ (Program_Error'Identity,
+ "A binding for this interrupt is already present");
+ end if;
+
+ User_Entry (Interrupt) := Entry_Assoc'(T => T, E => E);
+
+ -- Indicate the attachment of interrupt entry in the ATCB.
+ -- This is needed so when an interrupt entry task terminates
+ -- the binding can be cleaned. The call to unbinding must be
+ -- make by the task before it terminates.
+
+ T.Interrupt_Entry := True;
+
+ -- Invoke a corresponding Server_Task if not yet created.
+ -- Place Task_ID info in Server_ID array.
+
+ if Server_ID (Interrupt) = Null_Task
+ or else
+ Ada.Task_Identification.Is_Terminated
+ (To_Ada (Server_ID (Interrupt)))
+ then
+ Interrupt_Access_Hold := new Interrupt_Server_Task
+ (Interrupt, semBCreate (SEM_Q_FIFO, SEM_EMPTY));
+ Server_ID (Interrupt) :=
+ To_System (Interrupt_Access_Hold.all'Identity);
+ end if;
+
+ Bind_Handler (Interrupt);
+ end Bind_Interrupt_To_Entry;
+
+ or
+ accept Detach_Interrupt_Entries (T : Task_ID) do
+ for Int in Interrupt_ID'Range loop
+ if not Is_Reserved (Int) then
+ if User_Entry (Int).T = T then
+ User_Entry (Int) :=
+ Entry_Assoc'
+ (T => Null_Task, E => Null_Task_Entry);
+ Unbind_Handler (Int);
+ end if;
+ end if;
+ end loop;
+
+ -- Indicate in ATCB that no interrupt entries are attached.
+
+ T.Interrupt_Entry := False;
+ end Detach_Interrupt_Entries;
+ end select;
+
+ exception
+ -- If there is a Program_Error we just want to propagate it to
+ -- the caller and do not want to stop this task.
+
+ when Program_Error =>
+ null;
+
+ when others =>
+ pragma Assert (False);
+ null;
+ end;
+ end loop;
+
+ exception
+ when Standard'Abort_Signal =>
+ -- Flush interrupt server semaphores, so they can terminate
+ Finalize_Interrupt_Servers;
+ raise;
+ end Interrupt_Manager;
+
+ ---------------------------
+ -- Interrupt_Server_Task --
+ ---------------------------
+
+ -- Server task for vectored hardware interrupt handling
+
+ task body Interrupt_Server_Task is
+ Self_Id : constant Task_ID := Self;
+ Tmp_Handler : Parameterless_Handler;
+ Tmp_ID : Task_ID;
+ Tmp_Entry_Index : Task_Entry_Index;
+ S : STATUS;
+
+ use type STATUS;
+
+ begin
+ System.Tasking.Utilities.Make_Independent;
+ Semaphore_ID_Map (Interrupt) := Int_Sema;
+
+ loop
+ -- Pend on semaphore that will be triggered by the
+ -- umbrella handler when the associated interrupt comes in
+
+ S := semTake (Int_Sema, WAIT_FOREVER);
+ pragma Assert (S = 0);
+
+ if User_Handler (Interrupt).H /= null then
+
+ -- Protected procedure handler
+
+ Tmp_Handler := User_Handler (Interrupt).H;
+ Tmp_Handler.all;
+
+ elsif User_Entry (Interrupt).T /= Null_Task then
+
+ -- Interrupt entry handler
+
+ Tmp_ID := User_Entry (Interrupt).T;
+ Tmp_Entry_Index := User_Entry (Interrupt).E;
+ System.Tasking.Rendezvous.Call_Simple
+ (Tmp_ID, Tmp_Entry_Index, System.Null_Address);
+
+ else
+ -- Semaphore has been flushed by an unbind operation in
+ -- the Interrupt_Manager. Terminate the server task.
+
+ -- Wait for the Interrupt_Manager to complete its work
+
+ POP.Write_Lock (Self_Id);
+
+ -- Delete the associated semaphore
+
+ S := semDelete (Int_Sema);
+
+ pragma Assert (S = 0);
+
+ -- Set status for the Interrupt_Manager
+
+ Semaphore_ID_Map (Interrupt) := 0;
+ Server_ID (Interrupt) := Null_Task;
+ POP.Unlock (Self_Id);
+
+ exit;
+ end if;
+ end loop;
+ end Interrupt_Server_Task;
+
+begin
+ -- Get Interrupt_Manager's ID so that Abort_Interrupt can be sent.
+
+ Interrupt_Manager_ID := To_System (Interrupt_Manager'Identity);
+end System.Interrupts;
diff --git a/gcc/ada/s-intman-dummy.adb b/gcc/ada/s-intman-dummy.adb
new file mode 100644
index 00000000000..9ef33ab5a15
--- /dev/null
+++ b/gcc/ada/s-intman-dummy.adb
@@ -0,0 +1,49 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . I N T E R R U P T _ M A N A G E M E N T --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1997-2002 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- --
+-- 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, 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, --
+-- 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 is a NO tasking version of this package.
+
+package body System.Interrupt_Management is
+
+ ---------------------------
+ -- Initialize_Interrupts --
+ ---------------------------
+
+ -- Nothing needs to be done on this platform.
+
+ procedure Initialize_Interrupts is
+ begin
+ null;
+ end Initialize_Interrupts;
+
+end System.Interrupt_Management;
diff --git a/gcc/ada/s-intman-irix-athread.adb b/gcc/ada/s-intman-irix-athread.adb
new file mode 100644
index 00000000000..57771303f16
--- /dev/null
+++ b/gcc/ada/s-intman-irix-athread.adb
@@ -0,0 +1,184 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . I N T E R R U P T _ M A N A G E M E N T --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2003, Ada Core Technologies --
+-- --
+-- 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, 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, --
+-- 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 is an Irix (old pthread library) version of this package.
+
+-- PLEASE DO NOT add any dependences on other packages.
+-- This package is designed to work with or without tasking support.
+
+-- Make a careful study of all signals available under the OS,
+-- to see which need to be reserved, kept always unmasked,
+-- or kept always unmasked.
+
+-- Be on the lookout for special signals that
+-- may be used by the thread library.
+
+with System.OS_Interface;
+-- used for various Constants, Signal and types
+
+with Interfaces.C;
+-- used for "int"
+package body System.Interrupt_Management is
+
+ use System.OS_Interface;
+
+ type Interrupt_List is array (Interrupt_ID range <>) of Interrupt_ID;
+
+ Exception_Interrupts : constant Interrupt_List :=
+ (SIGILL,
+ SIGABRT,
+ SIGFPE,
+ SIGSEGV,
+ SIGBUS);
+
+ Reserved_Interrupts : constant Interrupt_List :=
+ (0,
+ SIGTRAP,
+ SIGKILL,
+ SIGSYS,
+ SIGALRM,
+ SIGSTOP,
+ SIGPTINTR,
+ SIGPTRESCHED);
+
+ Abort_Signal : constant := 48;
+ --
+ -- Serious MOJO: The SGI pthreads library only supports the
+ -- unnamed signal number 48 for pthread_kill!
+ --
+
+ Unreserve_All_Interrupts : Interfaces.C.int;
+ pragma Import
+ (C, Unreserve_All_Interrupts, "__gl_unreserve_all_interrupts");
+
+ ----------------------
+ -- Notify_Exception --
+ ----------------------
+
+ -- This function identifies the Ada exception to be raised using the
+ -- information when the system received a synchronous signal.
+ -- Since this function is machine and OS dependent, different code has to
+ -- be provided for different target.
+ -- On SGI, the signal handling is done is a-init.c, even when tasking is
+ -- involved.
+
+ ---------------------------
+ -- Initialize_Interrupts --
+ ---------------------------
+
+ -- Nothing needs to be done on this platform.
+
+ procedure Initialize_Interrupts is
+ begin
+ null;
+ end Initialize_Interrupts;
+
+begin
+ declare
+ function State (Int : 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:
+
+ User : constant Character := 'u';
+ Runtime : constant Character := 'r';
+ Default : constant Character := 's';
+ -- 'n' this interrupt not set by any Interrupt_State pragma
+ -- 'u' Interrupt_State pragma set state to User
+ -- 'r' Interrupt_State pragma set state to Runtime
+ -- 's' Interrupt_State pragma set state to System (use "default"
+ -- system handler)
+
+ use Interfaces.C;
+
+ begin
+ Abort_Task_Interrupt := Abort_Signal;
+
+ pragma Assert (Keep_Unmasked = (Interrupt_ID'Range => False));
+ pragma Assert (Reserve = (Interrupt_ID'Range => False));
+
+ -- Process state of exception signals
+
+ for J in Exception_Interrupts'Range loop
+ if State (Exception_Interrupts (J)) /= User then
+ Keep_Unmasked (Exception_Interrupts (J)) := True;
+ Reserve (Exception_Interrupts (J)) := True;
+ end if;
+ end loop;
+
+ if State (Abort_Task_Interrupt) /= User then
+ Keep_Unmasked (Abort_Task_Interrupt) := True;
+ Reserve (Abort_Task_Interrupt) := True;
+ end if;
+
+ -- Set SIGINT to unmasked state as long as it's
+ -- not in "User" state. Check for Unreserve_All_Interrupts last
+
+ if State (SIGINT) /= User then
+ Keep_Unmasked (SIGINT) := True;
+ end if;
+
+ -- Check all signals for state that requires keeping them
+ -- unmasked and reserved
+
+ for J in Interrupt_ID'Range loop
+ if State (J) = Default or else State (J) = Runtime then
+ Keep_Unmasked (J) := True;
+ Reserve (J) := True;
+ end if;
+ end loop;
+
+ -- Add target-specific reserved signals
+
+ for J in Reserved_Interrupts'Range loop
+ Reserve (Interrupt_ID (Reserved_Interrupts (J))) := True;
+ end loop;
+
+ -- Process pragma Unreserve_All_Interrupts. This overrides any
+ -- settings due to pragma Interrupt_State:
+
+ if Unreserve_All_Interrupts /= 0 then
+ Keep_Unmasked (SIGINT) := False;
+ Reserve (SIGINT) := False;
+ end if;
+
+ -- We do not have Signal 0 in reality. We just use this value
+ -- to identify not existing signals (see s-intnam.ads). Therefore,
+ -- Signal 0 should not be used in all signal related operations hence
+ -- mark it as reserved.
+
+ Reserve (0) := True;
+ end;
+end System.Interrupt_Management;
diff --git a/gcc/ada/s-intman-irix.adb b/gcc/ada/s-intman-irix.adb
new file mode 100644
index 00000000000..2a290e105da
--- /dev/null
+++ b/gcc/ada/s-intman-irix.adb
@@ -0,0 +1,152 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . I N T E R R U P T _ M A N A G E M E N T --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2003, Ada Core Technologies --
+-- --
+-- 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, 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, --
+-- 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 is a SGI Pthread version of this package.
+
+-- PLEASE DO NOT add any dependences on other packages.
+-- This package is designed to work with or without tasking support.
+
+-- Make a careful study of all signals available under the OS,
+-- to see which need to be reserved, kept always unmasked,
+-- or kept always unmasked.
+-- Be on the lookout for special signals that
+-- may be used by the thread library.
+
+with Interfaces.C;
+-- used for int
+
+with System.OS_Interface;
+-- used for various Constants, Signal and types
+
+package body System.Interrupt_Management is
+
+ use System.OS_Interface;
+
+ type Interrupt_List is array (Interrupt_ID range <>) of Interrupt_ID;
+ Exception_Interrupts : constant Interrupt_List :=
+ (SIGTSTP, SIGILL, SIGTRAP, SIGEMT, SIGFPE, SIGBUS, SIGSTOP, SIGKILL,
+ SIGSEGV, SIGSYS, SIGXCPU, SIGXFSZ, SIGPROF, SIGPTINTR, SIGPTRESCHED,
+ SIGABRT, SIGPIPE);
+
+ ---------------------------
+ -- Initialize_Interrupts --
+ ---------------------------
+
+ -- Nothing needs to be done on this platform
+
+ procedure Initialize_Interrupts is
+ begin
+ null;
+ end Initialize_Interrupts;
+
+ Unreserve_All_Interrupts : Interfaces.C.int;
+ pragma Import
+ (C, Unreserve_All_Interrupts, "__gl_unreserve_all_interrupts");
+
+ use type Interfaces.C.int;
+
+begin
+ declare
+ function State (Int : 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:
+
+ User : constant Character := 'u';
+ Runtime : constant Character := 'r';
+ Default : constant Character := 's';
+ -- 'n' this interrupt not set by any Interrupt_State pragma
+ -- 'u' Interrupt_State pragma set state to User
+ -- 'r' Interrupt_State pragma set state to Runtime
+ -- 's' Interrupt_State pragma set state to System (use "default"
+ -- system handler)
+
+ begin
+ Abort_Task_Interrupt := SIGABRT;
+
+ -- Change this if you want to use another signal for task abort.
+ -- SIGTERM might be a good one.
+
+ pragma Assert (Keep_Unmasked = (Interrupt_ID'Range => False));
+ pragma Assert (Reserve = (Interrupt_ID'Range => False));
+
+ -- Process state of exception signals
+
+ for J in Exception_Interrupts'Range loop
+ if State (Exception_Interrupts (J)) /= User then
+ Keep_Unmasked (Exception_Interrupts (J)) := True;
+ Reserve (Exception_Interrupts (J)) := True;
+ end if;
+ end loop;
+
+ if State (Abort_Task_Interrupt) /= User then
+ Keep_Unmasked (Abort_Task_Interrupt) := True;
+ Reserve (Abort_Task_Interrupt) := True;
+ end if;
+
+ -- Set SIGINT to unmasked state as long as it's
+ -- not in "User" state. Check for Unreserve_All_Interrupts last
+
+ if State (SIGINT) /= User then
+ Keep_Unmasked (SIGINT) := True;
+ end if;
+
+ -- Check all signals for state that requires keeping them
+ -- unmasked and reserved
+
+ for J in Interrupt_ID'Range loop
+ if State (J) = Default or else State (J) = Runtime then
+ Keep_Unmasked (J) := True;
+ Reserve (J) := True;
+ end if;
+ end loop;
+
+ -- Process pragma Unreserve_All_Interrupts. This overrides any
+ -- settings due to pragma Interrupt_State:
+
+ if Unreserve_All_Interrupts /= 0 then
+ Keep_Unmasked (SIGINT) := False;
+ Reserve (SIGINT) := False;
+ end if;
+
+ -- We do not have Signal 0 in reality. We just use this value
+ -- to identify not existing signals (see s-intnam.ads). Therefore,
+ -- Signal 0 should not be used in all signal related operations hence
+ -- mark it as reserved.
+
+ Reserve (0) := True;
+ end;
+end System.Interrupt_Management;
diff --git a/gcc/ada/s-intman-mingw.adb b/gcc/ada/s-intman-mingw.adb
new file mode 100644
index 00000000000..362e50132ff
--- /dev/null
+++ b/gcc/ada/s-intman-mingw.adb
@@ -0,0 +1,78 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . I N T E R R U P T _ M A N A G E M E N T --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1991-2000 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- --
+-- 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, 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, --
+-- 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 is the NT version of this package
+
+-- This file performs the system-dependent translation between machine
+-- exceptions and the Ada exceptions, if any, that should be raised when they
+-- occur.
+
+-- PLEASE DO NOT add any dependences on other packages.
+-- This package is designed to work with or without tasking support.
+
+-- See the other warnings in the package specification before making any
+-- modifications to this file.
+
+-- Make a careful study of all signals available under the OS, to see which
+-- need to be reserved, kept always unmasked, or kept always unmasked. Be on
+-- the lookout for special signals that may be used by the thread library.
+
+with System.OS_Interface; use System.OS_Interface;
+
+package body System.Interrupt_Management is
+
+ ---------------------------
+ -- Initialize_Interrupts --
+ ---------------------------
+
+ -- Nothing needs to be done on this platform.
+
+ procedure Initialize_Interrupts is
+ begin
+ null;
+ end Initialize_Interrupts;
+
+begin
+ -- "Reserve" all the interrupts, except those that are explicitely defined
+
+ for J in Interrupt_ID'Range loop
+ Reserve (J) := True;
+ end loop;
+
+ Reserve (SIGINT) := False;
+ Reserve (SIGILL) := False;
+ Reserve (SIGABRT) := False;
+ Reserve (SIGFPE) := False;
+ Reserve (SIGSEGV) := False;
+ Reserve (SIGTERM) := False;
+end System.Interrupt_Management;
diff --git a/gcc/ada/s-intman-posix.adb b/gcc/ada/s-intman-posix.adb
new file mode 100644
index 00000000000..801adac39f2
--- /dev/null
+++ b/gcc/ada/s-intman-posix.adb
@@ -0,0 +1,285 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . I N T E R R U P T _ M A N A G E M E N T --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2003, 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- --
+-- 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, 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, --
+-- 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 is the POSIX threads version of this package
+
+-- PLEASE DO NOT add any dependences on other packages. ??? why not ???
+-- This package is designed to work with or without tasking support.
+
+-- See the other warnings in the package specification before making
+-- any modifications to this file.
+
+-- Make a careful study of all signals available under the OS, to see which
+-- need to be reserved, kept always unmasked, or kept always unmasked. Be on
+-- the lookout for special signals that may be used by the thread library.
+
+-- Since this is a multi target file, the signal <-> exception mapping
+-- is simple minded. If you need a more precise and target specific
+-- signal handling, create a new s-intman.adb that will fit your needs.
+
+-- This file assumes that:
+
+-- SIGFPE, SIGILL, SIGSEGV and SIGBUS exist. They are mapped as follows:
+-- SIGPFE => Constraint_Error
+-- SIGILL => Program_Error
+-- SIGSEGV => Storage_Error
+-- SIGBUS => Storage_Error
+
+-- SIGINT exists and will be kept unmasked unless the pragma
+-- Unreserve_All_Interrupts is specified anywhere in the application.
+
+-- System.OS_Interface contains the following:
+-- SIGADAABORT: the signal that will be used to abort tasks.
+-- Unmasked: the OS specific set of signals that should be unmasked in
+-- all the threads. SIGADAABORT is unmasked by
+-- default
+-- Reserved: the OS specific set of signals that are reserved.
+
+with Interfaces.C;
+-- used for int and other types
+
+with System.OS_Interface;
+-- used for various Constants, Signal and types
+
+package body System.Interrupt_Management is
+
+ use Interfaces.C;
+ use System.OS_Interface;
+
+ type Interrupt_List is array (Interrupt_ID range <>) of Interrupt_ID;
+ Exception_Interrupts : constant Interrupt_List :=
+ (SIGFPE, SIGILL, SIGSEGV, SIGBUS);
+
+ Unreserve_All_Interrupts : Interfaces.C.int;
+ pragma Import
+ (C, Unreserve_All_Interrupts, "__gl_unreserve_all_interrupts");
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ procedure Notify_Exception (signo : Signal);
+ -- This function identifies the Ada exception to be raised using
+ -- the information when the system received a synchronous signal.
+ -- Since this function is machine and OS dependent, different code
+ -- has to be provided for different target.
+
+ ----------------------
+ -- Notify_Exception --
+ ----------------------
+
+ Signal_Mask : aliased sigset_t;
+ -- The set of signals handled by Notify_Exception
+
+ procedure Notify_Exception (signo : Signal) is
+ Result : Interfaces.C.int;
+
+ begin
+ -- With the __builtin_longjmp, the signal mask is not restored, so we
+ -- need to restore it explicitely.
+
+ Result := pthread_sigmask (SIG_UNBLOCK, Signal_Mask'Access, null);
+ pragma Assert (Result = 0);
+
+ -- Check that treatment of exception propagation here
+ -- is consistent with treatment of the abort signal in
+ -- System.Task_Primitives.Operations.
+
+ case signo is
+ when SIGFPE =>
+ raise Constraint_Error;
+ when SIGILL =>
+ raise Program_Error;
+ when SIGSEGV =>
+ raise Storage_Error;
+ when SIGBUS =>
+ raise Storage_Error;
+ when others =>
+ null;
+ end case;
+ end Notify_Exception;
+
+ ---------------------------
+ -- Initialize_Interrupts --
+ ---------------------------
+
+ -- Nothing needs to be done on this platform.
+
+ procedure Initialize_Interrupts is
+ begin
+ null;
+ end Initialize_Interrupts;
+
+-------------------------
+-- Package Elaboration --
+-------------------------
+
+begin
+ declare
+ act : aliased struct_sigaction;
+ old_act : aliased struct_sigaction;
+ Result : System.OS_Interface.int;
+
+ function State (Int : 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:
+
+ User : constant Character := 'u';
+ Runtime : constant Character := 'r';
+ Default : constant Character := 's';
+ -- 'n' this interrupt not set by any Interrupt_State pragma
+ -- 'u' Interrupt_State pragma set state to User
+ -- 'r' Interrupt_State pragma set state to Runtime
+ -- 's' Interrupt_State pragma set state to System (use "default"
+ -- system handler)
+
+ begin
+ -- Need to call pthread_init very early because it is doing signal
+ -- initializations.
+
+ pthread_init;
+
+ Abort_Task_Interrupt := SIGADAABORT;
+
+ act.sa_handler := Notify_Exception'Address;
+
+ act.sa_flags := SA_SIGINFO;
+
+ -- Setting SA_SIGINFO asks the kernel to pass more than just the signal
+ -- number argument to the handler when it is called. The set of extra
+ -- parameters typically includes a pointer to a structure describing
+ -- the interrupted context. Although the Notify_Exception handler does
+ -- not use this information, it is actually required for the GCC/ZCX
+ -- exception propagation scheme because on some targets (at least
+ -- alpha-tru64), the structure contents are not even filled when this
+ -- flag is not set.
+
+ -- On some targets, we set sa_flags to SA_NODEFER so that during the
+ -- handler execution we do not change the Signal_Mask to be masked for
+ -- the Signal.
+
+ -- This is a temporary fix to the problem that the Signal_Mask is
+ -- not restored after the exception (longjmp) from the handler.
+ -- The right fix should be made in sigsetjmp so that we save
+ -- the Signal_Set and restore it after a longjmp.
+
+ -- Since SA_NODEFER is obsolete, instead we reset explicitely
+ -- the mask in the exception handler.
+
+ Result := sigemptyset (Signal_Mask'Access);
+ pragma Assert (Result = 0);
+
+ -- Add signals that map to Ada exceptions to the mask.
+ for J in Exception_Interrupts'Range loop
+ if State (Exception_Interrupts (J)) /= Default then
+ Result :=
+ sigaddset (Signal_Mask'Access, Signal (Exception_Interrupts (J)));
+ pragma Assert (Result = 0);
+ end if;
+ end loop;
+
+ act.sa_mask := Signal_Mask;
+
+ pragma Assert (Keep_Unmasked = (Interrupt_ID'Range => False));
+ pragma Assert (Reserve = (Interrupt_ID'Range => False));
+
+ -- Process state of exception signals
+ for J in Exception_Interrupts'Range loop
+ if State (Exception_Interrupts (J)) /= User then
+ Keep_Unmasked (Exception_Interrupts (J)) := True;
+ Reserve (Exception_Interrupts (J)) := True;
+
+ if State (Exception_Interrupts (J)) /= Default then
+ Result :=
+ sigaction
+ (Signal (Exception_Interrupts (J)), act'Unchecked_Access,
+ old_act'Unchecked_Access);
+ pragma Assert (Result = 0);
+ end if;
+ end if;
+ end loop;
+
+ if State (Abort_Task_Interrupt) /= User then
+ Keep_Unmasked (Abort_Task_Interrupt) := True;
+ Reserve (Abort_Task_Interrupt) := True;
+ end if;
+
+ -- Set SIGINT to unmasked state as long as it is not in "User"
+ -- state. Check for Unreserve_All_Interrupts last
+
+ if State (SIGINT) /= User then
+ Keep_Unmasked (SIGINT) := True;
+ Reserve (SIGINT) := True;
+ end if;
+
+ -- Check all signals for state that requires keeping them
+ -- unmasked and reserved
+
+ for J in Interrupt_ID'Range loop
+ if State (J) = Default or else State (J) = Runtime then
+ Keep_Unmasked (J) := True;
+ Reserve (J) := True;
+ end if;
+ end loop;
+
+ -- Add the set of signals that must always be unmasked for this target
+
+ for J in Unmasked'Range loop
+ Keep_Unmasked (Interrupt_ID (Unmasked (J))) := True;
+ Reserve (Interrupt_ID (Unmasked (J))) := True;
+ end loop;
+
+ -- Add target-specific reserved signals
+
+ for J in Reserved'Range loop
+ Reserve (Interrupt_ID (Reserved (J))) := True;
+ end loop;
+
+ -- Process pragma Unreserve_All_Interrupts. This overrides any
+ -- settings due to pragma Interrupt_State:
+
+ if Unreserve_All_Interrupts /= 0 then
+ Keep_Unmasked (SIGINT) := False;
+ Reserve (SIGINT) := False;
+ end if;
+
+ -- We do not have Signal 0 in reality. We just use this value
+ -- to identify non-existent signals (see s-intnam.ads). Therefore,
+ -- Signal 0 should not be used in all signal related operations hence
+ -- mark it as reserved.
+
+ Reserve (0) := True;
+ end;
+end System.Interrupt_Management;
diff --git a/gcc/ada/s-intman-solaris.adb b/gcc/ada/s-intman-solaris.adb
new file mode 100644
index 00000000000..d8d5963fca2
--- /dev/null
+++ b/gcc/ada/s-intman-solaris.adb
@@ -0,0 +1,263 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . I N T E R R U P T _ M A N A G E M E N T --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2002 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- --
+-- 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, 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, --
+-- 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 is a Solaris version of this package.
+
+-- PLEASE DO NOT add any dependences on other packages.
+-- This package is designed to work with or without tasking support.
+
+-- Make a careful study of all signals available under the OS,
+-- to see which need to be reserved, kept always unmasked,
+-- or kept always unmasked.
+
+-- Be on the lookout for special signals that
+-- may be used by the thread library.
+
+with Interfaces.C;
+-- used for int
+
+with System.OS_Interface;
+-- used for various Constants, Signal and types
+
+package body System.Interrupt_Management is
+
+ use Interfaces.C;
+ use System.OS_Interface;
+
+ type Interrupt_List is array (Interrupt_ID range <>) of Interrupt_ID;
+
+ Exception_Interrupts : constant Interrupt_List :=
+ (SIGFPE, SIGILL, SIGSEGV, SIGBUS);
+
+ Unreserve_All_Interrupts : Interfaces.C.int;
+ pragma Import
+ (C, Unreserve_All_Interrupts, "__gl_unreserve_all_interrupts");
+
+ ----------------------
+ -- Notify_Exception --
+ ----------------------
+
+ -- This function identifies the Ada exception to be raised using
+ -- the information when the system received a synchronous signal.
+ -- Since this function is machine and OS dependent, different code
+ -- has to be provided for different target.
+
+ procedure Notify_Exception
+ (signo : Signal;
+ info : access siginfo_t;
+ context : access ucontext_t);
+
+ ----------------------
+ -- Notify_Exception --
+ ----------------------
+
+ procedure Notify_Exception
+ (signo : Signal;
+ info : access siginfo_t;
+ context : access ucontext_t)
+ is
+ pragma Warnings (Off, context);
+
+ begin
+ -- Check that treatment of exception propagation here
+ -- is consistent with treatment of the abort signal in
+ -- System.Task_Primitives.Operations.
+
+ case signo is
+ when SIGFPE =>
+ case info.si_code is
+ when FPE_INTDIV |
+ FPE_INTOVF |
+ FPE_FLTDIV |
+ FPE_FLTOVF |
+ FPE_FLTUND |
+ FPE_FLTRES |
+ FPE_FLTINV |
+ FPE_FLTSUB =>
+
+ raise Constraint_Error;
+
+ when others =>
+ pragma Assert (False);
+ null;
+ end case;
+
+ when SIGILL | SIGSEGV | SIGBUS =>
+ raise Storage_Error;
+
+ when others =>
+ pragma Assert (False);
+ null;
+ end case;
+ end Notify_Exception;
+
+ ---------------------------
+ -- Initialize_Interrupts --
+ ---------------------------
+
+ -- Nothing needs to be done on this platform.
+
+ procedure Initialize_Interrupts is
+ begin
+ null;
+ end Initialize_Interrupts;
+
+----------------------------
+-- Package Initialization --
+----------------------------
+
+begin
+ declare
+ act : aliased struct_sigaction;
+ old_act : aliased struct_sigaction;
+ mask : aliased sigset_t;
+ Result : Interfaces.C.int;
+
+ function State (Int : 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:
+ --
+ User : constant Character := 'u';
+ Runtime : constant Character := 'r';
+ Default : constant Character := 's';
+ -- 'n' this interrupt not set by any Interrupt_State pragma
+ -- 'u' Interrupt_State pragma set state to User
+ -- 'r' Interrupt_State pragma set state to Runtime
+ -- 's' Interrupt_State pragma set state to System (use "default"
+ -- system handler)
+
+ begin
+ -- Need to call pthread_init very early because it is doing signal
+ -- initializations.
+
+ pthread_init;
+
+ -- Change this if you want to use another signal for task abort.
+ -- SIGTERM might be a good one.
+
+ Abort_Task_Interrupt := SIGABRT;
+
+ act.sa_handler := Notify_Exception'Address;
+
+ -- Set sa_flags to SA_NODEFER so that during the handler execution
+ -- we do not change the Signal_Mask to be masked for the Signal.
+ -- This is a temporary fix to the problem that the Signal_Mask is
+ -- not restored after the exception (longjmp) from the handler.
+ -- The right fix should be made in sigsetjmp so that we save
+ -- the Signal_Set and restore it after a longjmp.
+
+ -- In that case, this field should be changed back to 0. ??? (Dong-Ik)
+
+ act.sa_flags := 16;
+
+ Result := sigemptyset (mask'Access);
+ pragma Assert (Result = 0);
+
+ -- ??? For the same reason explained above, we can't mask these
+ -- signals because otherwise we won't be able to catch more than
+ -- one signal.
+
+ act.sa_mask := mask;
+
+ pragma Assert (Keep_Unmasked = (Interrupt_ID'Range => False));
+ pragma Assert (Reserve = (Interrupt_ID'Range => False));
+
+ for J in Exception_Interrupts'Range loop
+ if State (Exception_Interrupts (J)) /= User then
+ Keep_Unmasked (Exception_Interrupts (J)) := True;
+ Reserve (Exception_Interrupts (J)) := True;
+
+ if State (Exception_Interrupts (J)) /= Default then
+ Result :=
+ sigaction
+ (Signal (Exception_Interrupts (J)), act'Unchecked_Access,
+ old_act'Unchecked_Access);
+ pragma Assert (Result = 0);
+ end if;
+ end if;
+ end loop;
+
+ if State (Abort_Task_Interrupt) /= User then
+ Keep_Unmasked (Abort_Task_Interrupt) := True;
+ Reserve (Abort_Task_Interrupt) := True;
+ end if;
+
+ -- Set SIGINT to unmasked state as long as it's
+ -- not in "User" state. Check for Unreserve_All_Interrupts last
+
+ if State (SIGINT) /= User then
+ Keep_Unmasked (SIGINT) := True;
+ Reserve (SIGINT) := True;
+ end if;
+
+ -- Check all signals for state that requires keeping them
+ -- unmasked and reserved
+
+ for J in Interrupt_ID'Range loop
+ if State (J) = Default or else State (J) = Runtime then
+ Keep_Unmasked (J) := True;
+ Reserve (J) := True;
+ end if;
+ end loop;
+
+ -- Add the set of signals that must always be unmasked for this target
+
+ for J in Unmasked'Range loop
+ Keep_Unmasked (Interrupt_ID (Unmasked (J))) := True;
+ Reserve (Interrupt_ID (Unmasked (J))) := True;
+ end loop;
+
+ -- Add target-specific reserved signals
+
+ for J in Reserved'Range loop
+ Reserve (Interrupt_ID (Reserved (J))) := True;
+ end loop;
+
+ -- Process pragma Unreserve_All_Interrupts. This overrides any
+ -- settings due to pragma Interrupt_State:
+
+ if Unreserve_All_Interrupts /= 0 then
+ Keep_Unmasked (SIGINT) := False;
+ Reserve (SIGINT) := False;
+ end if;
+
+ -- We do not have Signal 0 in reality. We just use this value
+ -- to identify not existing signals (see s-intnam.ads). Therefore,
+ -- Signal 0 should not be used in all signal related operations hence
+ -- mark it as reserved.
+
+ Reserve (0) := True;
+ end;
+end System.Interrupt_Management;
diff --git a/gcc/ada/s-intman-vms.adb b/gcc/ada/s-intman-vms.adb
new file mode 100644
index 00000000000..1190378766f
--- /dev/null
+++ b/gcc/ada/s-intman-vms.adb
@@ -0,0 +1,88 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . I N T E R R U P T _ M A N A G E M E N T --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2002, 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- --
+-- 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, 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, --
+-- 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 is a OpenVMS/Alpha version of this package.
+
+-- PLEASE DO NOT add any dependences on other packages.
+-- This package is designed to work with or without tasking support.
+
+-- See the other warnings in the package specification before making
+-- any modifications to this file.
+
+with System.OS_Interface;
+-- used for various Constants, Signal and types
+
+package body System.Interrupt_Management is
+
+ use System.OS_Interface;
+ use type unsigned_long;
+
+ ---------------------------
+ -- Initialize_Interrupts --
+ ---------------------------
+
+ procedure Initialize_Interrupts is
+ Status : Cond_Value_Type;
+
+ begin
+ Sys_Crembx
+ (Status => Status,
+ Prmflg => False,
+ Chan => Rcv_Interrupt_Chan,
+ Maxmsg => Interrupt_ID'Size,
+ Bufquo => Interrupt_Bufquo,
+ Lognam => "GNAT_Interrupt_Mailbox",
+ Flags => CMB_M_READONLY);
+
+ pragma Assert ((Status and 1) = 1);
+
+ Sys_Assign
+ (Status => Status,
+ Devnam => "GNAT_Interrupt_Mailbox",
+ Chan => Snd_Interrupt_Chan,
+ Flags => AGN_M_WRITEONLY);
+
+ pragma Assert ((Status and 1) = 1);
+ end Initialize_Interrupts;
+
+begin
+ -- Unused
+
+ Abort_Task_Interrupt := Interrupt_ID_0;
+
+ Reserve := Reserve or Keep_Unmasked or Keep_Masked;
+
+ Reserve (Interrupt_ID_0) := True;
+
+ Initialize_Interrupts;
+end System.Interrupt_Management;
diff --git a/gcc/ada/s-intman-vms.ads b/gcc/ada/s-intman-vms.ads
new file mode 100644
index 00000000000..60f410b01d7
--- /dev/null
+++ b/gcc/ada/s-intman-vms.ads
@@ -0,0 +1,142 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . I N T E R R U P T _ M A N A G E M E N T --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-2003 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- --
+-- 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, 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, --
+-- 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 is the Alpha/VMS version of this package.
+--
+-- This package encapsulates and centralizes information about
+-- all uses of interrupts (or signals), including the
+-- target-dependent mapping of interrupts (or signals) to exceptions.
+
+-- PLEASE DO NOT add any with-clauses to this package.
+-- This is designed to work for both tasking and non-tasking systems,
+-- without pulling in any of the tasking support.
+
+-- PLEASE DO NOT remove the Elaborate_Body pragma from this package.
+-- Elaboration of this package should happen early, as most other
+-- initializations depend on it.
+-- Forcing immediate elaboration of the body also helps to enforce
+-- the design assumption that this is a second-level
+-- package, just one level above System.OS_Interface, with no
+-- cross-dependences.
+
+-- PLEASE DO NOT put any subprogram declarations with arguments of
+-- type Interrupt_ID into the visible part of this package.
+-- The type Interrupt_ID is used to derive the type in Ada.Interrupts,
+-- and adding more operations to that type would be illegal according
+-- to the Ada Reference Manual. (This is the reason why the signals sets
+-- below are implemented as visible arrays rather than functions.)
+
+with System.OS_Interface;
+-- used for Signal
+-- sigset_t
+
+package System.Interrupt_Management is
+
+ pragma Elaborate_Body;
+
+ type Interrupt_Mask is limited private;
+
+ type Interrupt_ID is new System.OS_Interface.Signal;
+
+ type Interrupt_Set is array (Interrupt_ID) of Boolean;
+
+ -- The following objects serve as constants, but are initialized
+ -- in the body to aid portability. This permits us
+ -- to use more portable names for interrupts,
+ -- where distinct names may map to the same interrupt ID value.
+ -- For example, suppose SIGRARE is a signal that is not defined on
+ -- all systems, but is always reserved when it is defined.
+ -- If we have the convention that ID zero is not used for any "real"
+ -- signals, and SIGRARE = 0 when SIGRARE is not one of the locally
+ -- supported signals, we can write
+ -- Reserved (SIGRARE) := true;
+ -- and the initialization code will be portable.
+
+ Abort_Task_Interrupt : Interrupt_ID;
+ -- The interrupt that is used to implement task abortion,
+ -- if an interrupt is used for that purpose.
+ -- This is one of the reserved interrupts.
+
+ Keep_Unmasked : Interrupt_Set := (others => False);
+ -- Keep_Unmasked (I) is true iff the interrupt I is
+ -- one that must be kept unmasked at all times,
+ -- except (perhaps) for short critical sections.
+ -- This includes interrupts that are mapped to exceptions
+ -- (see System.Interrupt_Exceptions.Is_Exception), but may also
+ -- include interrupts (e.g. timer) that need to be kept unmasked
+ -- for other reasons.
+ -- Where interrupts are implemented as OS signals, and signal masking
+ -- is per-task, the interrupt should be unmasked in ALL TASKS.
+
+ Reserve : Interrupt_Set := (others => False);
+ -- Reserve (I) is true iff the interrupt I is one that
+ -- cannot be permitted to be attached to a user handler.
+ -- The possible reasons are many. For example,
+ -- it may be mapped to an exception, used to implement task abortion,
+ -- or used to implement time delays.
+
+ Keep_Masked : Interrupt_Set := (others => False);
+ -- Keep_Masked (I) is true iff the interrupt I must always be masked.
+ -- Where interrupts are implemented as OS signals, and signal masking
+ -- is per-task, the interrupt should be masked in ALL TASKS.
+ -- There might not be any interrupts in this class, depending on
+ -- the environment. For example, if interrupts are OS signals
+ -- and signal masking is per-task, use of the sigwait operation
+ -- requires the signal be masked in all tasks.
+
+ procedure Initialize_Interrupts;
+ -- On systems where there is no signal inheritance between tasks (e.g
+ -- VxWorks, GNU/LinuxThreads), this procedure is used to initialize
+ -- interrupts handling in each task. Otherwise this function should
+ -- only be called by initialize in this package body.
+
+private
+
+ use type System.OS_Interface.unsigned_long;
+
+ type Interrupt_Mask is new System.OS_Interface.sigset_t;
+
+ -- Interrupts on VMS are implemented with a mailbox. A QIO read is
+ -- registered on the Rcv channel and the interrupt occurs by registering
+ -- a QIO write on the Snd channel. The maximum number of pending
+ -- interrupts is arbitrarily set at 1000. One nice feature of using
+ -- a mailbox is that it is trivially extendable to cross process
+ -- interrupts.
+
+ Rcv_Interrupt_Chan : System.OS_Interface.unsigned_short := 0;
+ Snd_Interrupt_Chan : System.OS_Interface.unsigned_short := 0;
+ Interrupt_Mailbox : Interrupt_ID := 0;
+ Interrupt_Bufquo : System.OS_Interface.unsigned_long
+ := 1000 * (Interrupt_ID'Size / 8);
+
+end System.Interrupt_Management;
diff --git a/gcc/ada/s-intman-vxworks.adb b/gcc/ada/s-intman-vxworks.adb
new file mode 100644
index 00000000000..411d86d0ae0
--- /dev/null
+++ b/gcc/ada/s-intman-vxworks.adb
@@ -0,0 +1,194 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . I N T E R R U P T _ M A N A G E M E N T --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2004 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- --
+-- 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, 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, --
+-- 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 is the VxWorks version of this package.
+
+-- It is likely to need tailoring to fit each operating system
+-- and machine architecture.
+
+-- PLEASE DO NOT add any dependences on other packages.
+-- This package is designed to work with or without tasking support.
+
+-- See the other warnings in the package specification before making
+-- any modifications to this file.
+
+-- Make a careful study of all signals available under the OS,
+-- to see which need to be reserved, kept always unmasked,
+-- or kept always unmasked.
+-- Be on the lookout for special signals that
+-- may be used by the thread library.
+
+with Interfaces.C;
+
+with System.OS_Interface;
+-- used for various Constants, Signal and types
+
+package body System.Interrupt_Management is
+
+ use System.OS_Interface;
+ use type Interfaces.C.int;
+
+ type Signal_List is array (Signal_ID range <>) of Signal_ID;
+ Exception_Signals : constant Signal_List (1 .. 4) :=
+ (SIGFPE, SIGILL, SIGSEGV, SIGBUS);
+
+ -- Keep these variables global so that they are initialized only once
+ -- What are "these variables" ???, I see only one
+
+ Exception_Action : aliased struct_sigaction;
+
+ procedure Map_And_Raise_Exception (signo : Signal);
+ pragma Import (C, Map_And_Raise_Exception, "__gnat_map_signal");
+ -- Map signal to Ada exception and raise it. Different versions
+ -- of VxWorks need different mappings.
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ procedure Notify_Exception (signo : Signal);
+ -- Identify the Ada exception to be raised using
+ -- the information when the system received a synchronous signal.
+
+ ----------------------
+ -- Notify_Exception --
+ ----------------------
+
+ procedure Notify_Exception (signo : Signal) is
+ Mask : aliased sigset_t;
+ My_Id : t_id;
+
+ Result : int;
+ pragma Unreferenced (Result);
+
+ begin
+ Result := pthread_sigmask (SIG_SETMASK, null, Mask'Unchecked_Access);
+ Result := sigdelset (Mask'Access, signo);
+ Result := pthread_sigmask (SIG_SETMASK, Mask'Unchecked_Access, null);
+
+ -- VxWorks will suspend the task when it gets a hardware
+ -- exception. We take the liberty of resuming the task
+ -- for the application.
+
+ My_Id := taskIdSelf;
+
+ if taskIsSuspended (My_Id) /= 0 then
+ Result := taskResume (My_Id);
+ end if;
+
+ Map_And_Raise_Exception (signo);
+ end Notify_Exception;
+
+ ---------------------------
+ -- Initialize_Interrupts --
+ ---------------------------
+
+ -- Since there is no signal inheritance between VxWorks tasks, we need
+ -- to initialize signal handling in each task.
+
+ procedure Initialize_Interrupts is
+ Result : int;
+ old_act : aliased struct_sigaction;
+
+ begin
+ for J in Exception_Signals'Range loop
+ Result :=
+ sigaction
+ (Signal (Exception_Signals (J)), Exception_Action'Access,
+ old_act'Unchecked_Access);
+ pragma Assert (Result = 0);
+ end loop;
+ end Initialize_Interrupts;
+
+begin
+ declare
+ mask : aliased sigset_t;
+ Result : int;
+
+ function State (Int : 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:
+
+ Runtime : constant Character := 'r';
+ Default : constant Character := 's';
+ -- 'n' this interrupt not set by any Interrupt_State pragma
+ -- 'u' Interrupt_State pragma set state to User
+ -- 'r' Interrupt_State pragma set state to Runtime
+ -- 's' Interrupt_State pragma set state to System (use "default"
+ -- system handler)
+
+ begin
+ -- Initialize signal handling
+
+ -- Change this if you want to use another signal for task abort.
+ -- SIGTERM might be a good one.
+
+ Abort_Task_Signal := SIGABRT;
+
+ Exception_Action.sa_handler := Notify_Exception'Address;
+ Exception_Action.sa_flags := SA_ONSTACK;
+ Result := sigemptyset (mask'Access);
+ pragma Assert (Result = 0);
+
+ for J in Exception_Signals'Range loop
+ Result := sigaddset (mask'Access, Signal (Exception_Signals (J)));
+ pragma Assert (Result = 0);
+ end loop;
+
+ Exception_Action.sa_mask := mask;
+
+ -- Initialize hardware interrupt handling
+
+ pragma Assert (Reserve = (Interrupt_ID'Range => False));
+
+ -- Check all interrupts for state that requires keeping them reserved
+
+ for J in Interrupt_ID'Range loop
+ if State (J) = Default or else State (J) = Runtime then
+ Reserve (J) := True;
+ end if;
+ end loop;
+
+ -- Add exception signals to the set of unmasked signals
+
+ for J in Exception_Signals'Range loop
+ Keep_Unmasked (Exception_Signals (J)) := True;
+ end loop;
+
+ -- The abort signal must also be unmasked
+
+ Keep_Unmasked (Abort_Task_Signal) := True;
+ end;
+end System.Interrupt_Management;
diff --git a/gcc/ada/s-intman-vxworks.ads b/gcc/ada/s-intman-vxworks.ads
new file mode 100644
index 00000000000..b0a4c3c5bda
--- /dev/null
+++ b/gcc/ada/s-intman-vxworks.ads
@@ -0,0 +1,123 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . I N T E R R U P T _ M A N A G E M E N T --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1992-2003 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- --
+-- 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, 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, --
+-- 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 is the VxWorks version of this package.
+
+-- This package encapsulates and centralizes information about all
+-- uses of interrupts (or signals), including the target-dependent
+-- mapping of interrupts (or signals) to exceptions.
+
+-- Unlike the original design, System.Interrupt_Management can only
+-- be used for tasking systems.
+
+-- PLEASE DO NOT remove the Elaborate_Body pragma from this package.
+-- Elaboration of this package should happen early, as most other
+-- initializations depend on it. Forcing immediate elaboration of
+-- the body also helps to enforce the design assumption that this
+-- is a second-level package, just one level above System.OS_Interface
+-- with no cross-dependencies.
+
+-- PLEASE DO NOT put any subprogram declarations with arguments of
+-- type Interrupt_ID into the visible part of this package. The type
+-- Interrupt_ID is used to derive the type in Ada.Interrupts, and
+-- adding more operations to that type would be illegal according
+-- to the Ada Reference Manual. This is the reason why the signals
+-- sets are implemeneted using visible arrays rather than functions.
+
+with System.OS_Interface;
+-- used for sigset_t
+
+with Interfaces.C;
+-- used for int
+
+package System.Interrupt_Management is
+
+ pragma Elaborate_Body;
+
+ type Interrupt_Mask is limited private;
+
+ type Interrupt_ID is new Interfaces.C.int
+ range 0 .. System.OS_Interface.Max_Interrupt;
+
+ type Interrupt_Set is array (Interrupt_ID) of Boolean;
+
+ subtype Signal_ID is Interrupt_ID
+ range 0 .. Interfaces.C."-" (System.OS_Interface.NSIG, 1);
+
+ type Signal_Set is array (Signal_ID) of Boolean;
+
+ -- The following objects serve as constants, but are initialized
+ -- in the body to aid portability. This permits us to use more
+ -- portable names for interrupts, where distinct names may map to
+ -- the same interrupt ID value.
+ --
+ -- For example, suppose SIGRARE is a signal that is not defined on
+ -- all systems, but is always reserved when it is defined. If we
+ -- have the convention that ID zero is not used for any "real"
+ -- signals, and SIGRARE = 0 when SIGRARE is not one of the locally
+ -- supported signals, we can write
+ -- Reserved (SIGRARE) := true;
+ -- and the initialization code will be portable.
+
+ Abort_Task_Signal : Signal_ID;
+ -- The signal that is used to implement task abortion if
+ -- an interrupt is used for that purpose. This is one of the
+ -- reserved signals.
+
+ Keep_Unmasked : Signal_Set := (others => False);
+ -- Keep_Unmasked (I) is true iff the signal I is one that must
+ -- that must be kept unmasked at all times, except (perhaps) for
+ -- short critical sections. This includes signals that are
+ -- mapped to exceptions, but may also include interrupts
+ -- (e.g. timer) that need to be kept unmasked for other
+ -- reasons. Where signal masking is per-task, the signal should be
+ -- unmasked in ALL TASKS.
+
+ Reserve : Interrupt_Set := (others => False);
+ -- Reserve (I) is true iff the interrupt I is one that cannot be
+ -- permitted to be attached to a user handler. The possible reasons
+ -- are many. For example, it may be mapped to an exception used to
+ -- implement task abortion, or used to implement time delays.
+
+ procedure Initialize_Interrupts;
+ -- On systems where there is no signal inheritance between tasks (e.g
+ -- VxWorks, GNU/LinuxThreads), this procedure is used to initialize
+ -- interrupts handling in each task. Otherwise this function should
+ -- only be called by initialize in this package body.
+
+private
+ type Interrupt_Mask is new System.OS_Interface.sigset_t;
+ -- In some implementation Interrupt_Mask can be represented
+ -- as a linked list.
+
+end System.Interrupt_Management;
diff --git a/gcc/ada/s-mastop-irix.adb b/gcc/ada/s-mastop-irix.adb
new file mode 100644
index 00000000000..6c85ce54f1a
--- /dev/null
+++ b/gcc/ada/s-mastop-irix.adb
@@ -0,0 +1,444 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- SYSTEM.MACHINE_STATE_OPERATIONS --
+-- --
+-- B o d y --
+-- (Version for IRIX/MIPS) --
+-- --
+-- Copyright (C) 1999-2004 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This version of Ada.Exceptions.Machine_State_Operations is for use on
+-- SGI Irix systems. By means of compile time conditional calculations, it
+-- can handle both n32/n64 and o32 modes.
+
+with System.Machine_Code; use System.Machine_Code;
+with System.Memory;
+with System.Soft_Links; use System.Soft_Links;
+with Unchecked_Conversion;
+
+package body System.Machine_State_Operations is
+
+ use System.Storage_Elements;
+ use System.Exceptions;
+
+ -- The exc_unwind function in libexc operats on a Sigcontext
+
+ -- Type sigcontext_t is defined in /usr/include/sys/signal.h.
+ -- We define an equivalent Ada type here. From the comments in
+ -- signal.h:
+
+ -- sigcontext is not part of the ABI - so this version is used to
+ -- handle 32 and 64 bit applications - it is a constant size regardless
+ -- of compilation mode, and always returns 64 bit register values
+
+ type Uns32 is mod 2 ** 32;
+ type Uns64 is mod 2 ** 64;
+
+ type Uns32_Ptr is access all Uns32;
+ type Uns64_Array is array (Integer range <>) of Uns64;
+
+ type Reg_Array is array (0 .. 31) of Uns64;
+
+ type Sigcontext is record
+ SC_Regmask : Uns32; -- 0
+ SC_Status : Uns32; -- 4
+ SC_PC : Uns64; -- 8
+ SC_Regs : Reg_Array; -- 16
+ SC_Fpregs : Reg_Array; -- 272
+ SC_Ownedfp : Uns32; -- 528
+ SC_Fpc_Csr : Uns32; -- 532
+ SC_Fpc_Eir : Uns32; -- 536
+ SC_Ssflags : Uns32; -- 540
+ SC_Mdhi : Uns64; -- 544
+ SC_Mdlo : Uns64; -- 552
+ SC_Cause : Uns64; -- 560
+ SC_Badvaddr : Uns64; -- 568
+ SC_Triggersave : Uns64; -- 576
+ SC_Sigset : Uns64; -- 584
+ SC_Fp_Rounded_Result : Uns64; -- 592
+ SC_Pancake : Uns64_Array (0 .. 5);
+ SC_Pad : Uns64_Array (0 .. 26);
+ end record;
+
+ type Sigcontext_Ptr is access all Sigcontext;
+
+ SC_Regs_Pos : constant String := "16";
+ SC_Fpregs_Pos : constant String := "272";
+ -- Byte offset of the Integer and Floating Point register save areas
+ -- within the Sigcontext.
+
+ function To_Sigcontext_Ptr is
+ new Unchecked_Conversion (Machine_State, Sigcontext_Ptr);
+
+ type Addr_Int is mod 2 ** Long_Integer'Size;
+ -- An unsigned integer type whose size is the same as System.Address.
+ -- We rely on the fact that Long_Integer'Size = System.Address'Size in
+ -- all ABIs. Type Addr_Int can be converted to Uns64.
+
+ function To_Code_Loc is new Unchecked_Conversion (Addr_Int, Code_Loc);
+ function To_Addr_Int is new Unchecked_Conversion (System.Address, Addr_Int);
+ function To_Uns32_Ptr is new Unchecked_Conversion (Addr_Int, Uns32_Ptr);
+
+ --------------------------------
+ -- ABI-Dependent Declarations --
+ --------------------------------
+
+ o32 : constant Boolean := System.Word_Size = 32;
+ n32 : constant Boolean := System.Word_Size = 64;
+ o32n : constant Natural := Boolean'Pos (o32);
+ n32n : constant Natural := Boolean'Pos (n32);
+ -- Flags to indicate which ABI is in effect for this compilation. For the
+ -- purposes of this unit, the n32 and n64 ABI's are identical.
+
+ LSC : constant Character := Character'Val (o32n * Character'Pos ('w') +
+ n32n * Character'Pos ('d'));
+ -- This is 'w' for o32, and 'd' for n32/n64, used for constructing the
+ -- load/store instructions used to save/restore machine instructions.
+
+ Roff : constant Character := Character'Val (o32n * Character'Pos ('4') +
+ n32n * Character'Pos ('0'));
+ -- Offset from first byte of a __uint64 register save location where
+ -- the register value is stored. For n32/64 we store the entire 64
+ -- bit register into the uint64. For o32, only 32 bits are stored
+ -- at an offset of 4 bytes.
+
+ procedure Update_GP (Scp : Sigcontext_Ptr);
+
+ ---------------
+ -- Update_GP --
+ ---------------
+
+ procedure Update_GP (Scp : Sigcontext_Ptr) is
+
+ type F_op is mod 2 ** 6;
+ type F_reg is mod 2 ** 5;
+ type F_imm is new Short_Integer;
+
+ type I_Type is record
+ op : F_op;
+ rs : F_reg;
+ rt : F_reg;
+ imm : F_imm;
+ end record;
+
+ pragma Pack (I_Type);
+ for I_Type'Size use 32;
+
+ type I_Type_Ptr is access all I_Type;
+
+ LW : constant F_op := 2#100011#;
+ Reg_GP : constant := 28;
+
+ type Address_Int is mod 2 ** Standard'Address_Size;
+ function To_I_Type_Ptr is new
+ Unchecked_Conversion (Address_Int, I_Type_Ptr);
+
+ Ret_Ins : constant I_Type_Ptr := To_I_Type_Ptr (Address_Int (Scp.SC_PC));
+ GP_Ptr : Uns32_Ptr;
+
+ begin
+ if Ret_Ins.op = LW and then Ret_Ins.rt = Reg_GP then
+ GP_Ptr := To_Uns32_Ptr
+ (Addr_Int (Scp.SC_Regs (Integer (Ret_Ins.rs)))
+ + Addr_Int (Ret_Ins.imm));
+ Scp.SC_Regs (Reg_GP) := Uns64 (GP_Ptr.all);
+ end if;
+ end Update_GP;
+
+ ----------------------------
+ -- Allocate_Machine_State --
+ ----------------------------
+
+ function Allocate_Machine_State return Machine_State is
+ begin
+ return Machine_State
+ (Memory.Alloc (Sigcontext'Max_Size_In_Storage_Elements));
+ end Allocate_Machine_State;
+
+ -------------------
+ -- Enter_Handler --
+ -------------------
+
+ procedure Enter_Handler (M : Machine_State; Handler : Handler_Loc) is
+ pragma Warnings (Off, M);
+ pragma Warnings (Off, Handler);
+
+ LOADI : constant String (1 .. 2) := 'l' & LSC;
+ -- This is "lw" in o32 mode, and "ld" in n32/n64 mode
+
+ LOADF : constant String (1 .. 4) := 'l' & LSC & "c1";
+ -- This is "lwc1" in o32 mode and "ldc1" in n32/n64 mode
+
+ begin
+ -- Restore integer registers from machine state. Note that we know
+ -- that $4 points to M, and $5 points to Handler, since this is
+ -- the standard calling sequence
+
+ Asm (LOADI & " $16, 16*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (LOADI & " $17, 17*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (LOADI & " $18, 18*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (LOADI & " $19, 19*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (LOADI & " $20, 20*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (LOADI & " $21, 21*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (LOADI & " $22, 22*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (LOADI & " $23, 23*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (LOADI & " $24, 24*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (LOADI & " $25, 25*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (LOADI & " $26, 26*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (LOADI & " $27, 27*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (LOADI & " $28, 28*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (LOADI & " $29, 29*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (LOADI & " $30, 30*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (LOADI & " $31, 31*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+
+ -- Restore floating-point registers from machine state
+
+ Asm (LOADF & " $f16, 16*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (LOADF & " $f17, 17*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (LOADF & " $f18, 18*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (LOADF & " $f19, 19*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (LOADF & " $f20, 20*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (LOADF & " $f21, 21*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (LOADF & " $f22, 22*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (LOADF & " $f23, 23*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (LOADF & " $f24, 24*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (LOADF & " $f25, 25*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (LOADF & " $f26, 26*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (LOADF & " $f27, 27*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (LOADF & " $f28, 28*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (LOADF & " $f29, 29*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (LOADF & " $f30, 30*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (LOADF & " $f31, 31*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+
+ -- Jump directly to the handler
+
+ Asm ("jr $5");
+ end Enter_Handler;
+
+ ----------------
+ -- Fetch_Code --
+ ----------------
+
+ function Fetch_Code (Loc : Code_Loc) return Code_Loc is
+ begin
+ return Loc;
+ end Fetch_Code;
+
+ ------------------------
+ -- Free_Machine_State --
+ ------------------------
+
+ procedure Free_Machine_State (M : in out Machine_State) is
+ begin
+ Memory.Free (Address (M));
+ M := Machine_State (Null_Address);
+ end Free_Machine_State;
+
+ ------------------
+ -- Get_Code_Loc --
+ ------------------
+
+ function Get_Code_Loc (M : Machine_State) return Code_Loc is
+ SC : constant Sigcontext_Ptr := To_Sigcontext_Ptr (M);
+ begin
+ return To_Code_Loc (Addr_Int (SC.SC_PC));
+ end Get_Code_Loc;
+
+ --------------------------
+ -- Machine_State_Length --
+ --------------------------
+
+ function Machine_State_Length return Storage_Offset is
+ begin
+ return Sigcontext'Max_Size_In_Storage_Elements;
+ end Machine_State_Length;
+
+ ---------------
+ -- Pop_Frame --
+ ---------------
+
+ procedure Pop_Frame
+ (M : Machine_State;
+ Info : Subprogram_Info_Type)
+ is
+ pragma Warnings (Off, Info);
+
+ Scp : constant Sigcontext_Ptr := To_Sigcontext_Ptr (M);
+
+ procedure Exc_Unwind (Scp : Sigcontext_Ptr; Fde : Long_Integer := 0);
+ pragma Import (C, Exc_Unwind, "exc_unwind");
+
+ -- ??? Calling exc_unwind in the current setup does not work and
+ -- triggers the emission of system warning messages. Why it does
+ -- not work remains to be investigated. Part of the problem is
+ -- probably a section naming issue (e.g. .eh_frame/.debug_frame).
+
+ -- Instead of letting the call take place for nothing and emit
+ -- messages we don't expect, we just arrange things to pretend it
+ -- occurred and failed.
+
+ -- ??? Until this is fixed, we shall document that the backtrace
+ -- computation facility does not work, and we inhibit the pragma below
+ -- because we arrange for the call not to be emitted and the linker
+ -- complains when a library is linked in but resolves nothing.
+
+ -- pragma Linker_Options ("-lexc");
+
+ begin
+ -- exc_unwind is apparently not thread-safe under IRIX, so protect it
+ -- against race conditions within the GNAT run time.
+ -- ??? Note that we might want to use a fine grained lock here since
+ -- Lock_Task is used in many other places.
+
+ Lock_Task.all;
+
+ if False then
+ Exc_Unwind (Scp);
+ else
+ Scp.SC_PC := 0;
+ end if;
+
+ Unlock_Task.all;
+
+ if Scp.SC_PC = 0 or else Scp.SC_PC = 1 then
+
+ -- A return value of 0 or 1 means exc_unwind couldn't find a parent
+ -- frame. Propagate_Exception expects a zero return address to
+ -- indicate TOS.
+
+ Scp.SC_PC := 0;
+
+ else
+ -- Set the GP to restore to the caller value (not callee value)
+ -- This is done only in o32 mode. In n32/n64 mode, GP is a normal
+ -- callee save register
+
+ if o32 then
+ Update_GP (Scp);
+ end if;
+
+ -- Adjust the return address to the call site, not the
+ -- instruction following the branch delay slot. This may
+ -- be necessary if the last instruction of a pragma No_Return
+ -- subprogram is a call. The first instruction following the
+ -- delay slot may be the start of another subprogram. We back
+ -- off the address by 8, which points safely into the middle
+ -- of the generated subprogram code, avoiding end effects.
+
+ Scp.SC_PC := Scp.SC_PC - 8;
+ end if;
+ end Pop_Frame;
+
+ -----------------------
+ -- Set_Machine_State --
+ -----------------------
+
+ procedure Set_Machine_State (M : Machine_State) is
+
+ STOREI : constant String (1 .. 2) := 's' & LSC;
+ -- This is "sw" in o32 mode, and "sd" in n32 mode
+
+ STOREF : constant String (1 .. 4) := 's' & LSC & "c1";
+ -- This is "swc1" in o32 mode and "sdc1" in n32 mode
+
+ Scp : Sigcontext_Ptr;
+
+ begin
+ -- Save the integer registers. Note that we know that $4 points
+ -- to M, since that is where the first parameter is passed.
+ -- Restore integer registers from machine state. Note that we know
+ -- that $4 points to M since this is the standard calling sequence
+
+ <<Past_Prolog>>
+
+ Asm (STOREI & " $16, 16*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (STOREI & " $17, 17*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (STOREI & " $18, 18*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (STOREI & " $19, 19*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (STOREI & " $20, 20*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (STOREI & " $21, 21*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (STOREI & " $22, 22*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (STOREI & " $23, 23*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (STOREI & " $24, 24*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (STOREI & " $25, 25*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (STOREI & " $26, 26*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (STOREI & " $27, 27*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (STOREI & " $28, 28*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (STOREI & " $29, 29*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (STOREI & " $30, 30*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+ Asm (STOREI & " $31, 31*8+" & Roff & "+" & SC_Regs_Pos & "($4)");
+
+ -- Restore floating-point registers from machine state
+
+ Asm (STOREF & " $f16, 16*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (STOREF & " $f17, 17*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (STOREF & " $f18, 18*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (STOREF & " $f19, 19*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (STOREF & " $f20, 20*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (STOREF & " $f21, 21*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (STOREF & " $f22, 22*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (STOREF & " $f23, 23*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (STOREF & " $f24, 24*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (STOREF & " $f25, 25*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (STOREF & " $f26, 26*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (STOREF & " $f27, 27*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (STOREF & " $f28, 28*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (STOREF & " $f29, 29*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (STOREF & " $f30, 30*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+ Asm (STOREF & " $f31, 31*8+" & Roff & "+" & SC_Fpregs_Pos & "($4)");
+
+ -- Set the PC value for the context to a location after the
+ -- prolog has been executed.
+
+ Scp := To_Sigcontext_Ptr (M);
+ Scp.SC_PC := Uns64 (To_Addr_Int (Past_Prolog'Address));
+
+ -- We saved the state *inside* this routine, but what we want is
+ -- the state at the call site. So we need to do one pop operation.
+ -- This pop operation will properly set the PC value in the machine
+ -- state, so there is no need to save PC in the above code.
+
+ Pop_Frame (M, Set_Machine_State'Address);
+ end Set_Machine_State;
+
+ ------------------------------
+ -- Set_Signal_Machine_State --
+ ------------------------------
+
+ procedure Set_Signal_Machine_State
+ (M : Machine_State;
+ Context : System.Address)
+ is
+ pragma Warnings (Off, M);
+ pragma Warnings (Off, Context);
+
+ begin
+ null;
+ end Set_Signal_Machine_State;
+
+end System.Machine_State_Operations;
diff --git a/gcc/ada/s-mastop-tru64.adb b/gcc/ada/s-mastop-tru64.adb
new file mode 100644
index 00000000000..956efa4e553
--- /dev/null
+++ b/gcc/ada/s-mastop-tru64.adb
@@ -0,0 +1,181 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- SYSTEM.MACHINE_STATE_OPERATIONS --
+-- --
+-- B o d y --
+-- (Version for Alpha/Dec Unix) --
+-- --
+-- Copyright (C) 1999-2003 Ada Core Technologies, 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This version of System.Machine_State_Operations is for use on
+-- Alpha systems running DEC Unix.
+
+with System.Memory;
+
+package body System.Machine_State_Operations is
+
+ use System.Exceptions;
+
+ pragma Linker_Options ("-lexc");
+ -- Needed for definitions of exc_capture_context and exc_virtual_unwind
+
+ ----------------------------
+ -- Allocate_Machine_State --
+ ----------------------------
+
+ function Allocate_Machine_State return Machine_State is
+ use System.Storage_Elements;
+
+ function c_machine_state_length return Storage_Offset;
+ pragma Import (C, c_machine_state_length, "__gnat_machine_state_length");
+
+ begin
+ return Machine_State
+ (Memory.Alloc (Memory.size_t (c_machine_state_length)));
+ end Allocate_Machine_State;
+
+ -------------------
+ -- Enter_Handler --
+ -------------------
+
+ procedure Enter_Handler (M : Machine_State; Handler : Handler_Loc) is
+ procedure c_enter_handler (M : Machine_State; Handler : Handler_Loc);
+ pragma Import (C, c_enter_handler, "__gnat_enter_handler");
+
+ begin
+ c_enter_handler (M, Handler);
+ end Enter_Handler;
+
+ ----------------
+ -- Fetch_Code --
+ ----------------
+
+ function Fetch_Code (Loc : Code_Loc) return Code_Loc is
+ begin
+ return Loc;
+ end Fetch_Code;
+
+ ------------------------
+ -- Free_Machine_State --
+ ------------------------
+
+ procedure Free_Machine_State (M : in out Machine_State) is
+ begin
+ Memory.Free (Address (M));
+ M := Machine_State (Null_Address);
+ end Free_Machine_State;
+
+ ------------------
+ -- Get_Code_Loc --
+ ------------------
+
+ function Get_Code_Loc (M : Machine_State) return Code_Loc is
+ Asm_Call_Size : constant := 4;
+
+ function c_get_code_loc (M : Machine_State) return Code_Loc;
+ pragma Import (C, c_get_code_loc, "__gnat_get_code_loc");
+
+ -- Code_Loc returned by c_get_code_loc is the return point but here we
+ -- want Get_Code_Loc to return the call point. Under DEC Unix a call
+ -- asm instruction takes 4 bytes. So we must remove this value from
+ -- c_get_code_loc to have the call point.
+
+ Loc : constant Code_Loc := c_get_code_loc (M);
+
+ begin
+ if Loc = 0 then
+ return 0;
+ else
+ return Loc - Asm_Call_Size;
+ end if;
+ end Get_Code_Loc;
+
+ --------------------------
+ -- Machine_State_Length --
+ --------------------------
+
+ function Machine_State_Length
+ return System.Storage_Elements.Storage_Offset
+ is
+ use System.Storage_Elements;
+
+ function c_machine_state_length return Storage_Offset;
+ pragma Import (C, c_machine_state_length, "__gnat_machine_state_length");
+
+ begin
+ return c_machine_state_length;
+ end Machine_State_Length;
+
+ ---------------
+ -- Pop_Frame --
+ ---------------
+
+ procedure Pop_Frame
+ (M : Machine_State;
+ Info : Subprogram_Info_Type)
+ is
+ pragma Warnings (Off, Info);
+
+ procedure exc_virtual_unwind
+ (Fcn : System.Address;
+ M : Machine_State);
+ pragma Import (C, exc_virtual_unwind, "exc_virtual_unwind");
+
+ begin
+ exc_virtual_unwind (System.Null_Address, M);
+ end Pop_Frame;
+
+ -----------------------
+ -- Set_Machine_State --
+ -----------------------
+
+ procedure Set_Machine_State (M : Machine_State) is
+ procedure c_capture_context (M : Machine_State);
+ pragma Import (C, c_capture_context, "exc_capture_context");
+
+ begin
+ c_capture_context (M);
+ Pop_Frame (M, System.Null_Address);
+ end Set_Machine_State;
+
+ ------------------------------
+ -- Set_Signal_Machine_State --
+ ------------------------------
+
+ procedure Set_Signal_Machine_State
+ (M : Machine_State;
+ Context : System.Address)
+ is
+ pragma Warnings (Off, M);
+ pragma Warnings (Off, Context);
+
+ begin
+ null;
+ end Set_Signal_Machine_State;
+
+end System.Machine_State_Operations;
diff --git a/gcc/ada/s-mastop-vms.adb b/gcc/ada/s-mastop-vms.adb
new file mode 100644
index 00000000000..5bb3f8a1eff
--- /dev/null
+++ b/gcc/ada/s-mastop-vms.adb
@@ -0,0 +1,339 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- SYSTEM.MACHINE_STATE_OPERATIONS --
+-- --
+-- B o d y --
+-- (Version for Alpha/VMS) --
+-- --
+-- Copyright (C) 2001-2002 Ada Core Technologies, 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This version of System.Machine_State_Operations is for use on
+-- Alpha systems running VMS.
+
+with System.Memory;
+with System.Aux_DEC; use System.Aux_DEC;
+with Unchecked_Conversion;
+
+package body System.Machine_State_Operations is
+
+ use System.Exceptions;
+ subtype Cond_Value_Type is Unsigned_Longword;
+
+ -- Record layouts copied from Starlet.
+
+ type ICB_Fflags_Bits_Type is record
+ Exception_Frame : Boolean;
+ Ast_Frame : Boolean;
+ Bottom_Of_Stack : Boolean;
+ Base_Frame : Boolean;
+ Filler_1 : Unsigned_20;
+ end record;
+
+ for ICB_Fflags_Bits_Type use record
+ Exception_Frame at 0 range 0 .. 0;
+ Ast_Frame at 0 range 1 .. 1;
+ Bottom_Of_Stack at 0 range 2 .. 2;
+ Base_Frame at 0 range 3 .. 3;
+ Filler_1 at 0 range 4 .. 23;
+ end record;
+ for ICB_Fflags_Bits_Type'Size use 24;
+
+ type ICB_Hdr_Quad_Type is record
+ Context_Length : Unsigned_Longword;
+ Fflags_Bits : ICB_Fflags_Bits_Type;
+ Block_Version : Unsigned_Byte;
+ end record;
+
+ for ICB_Hdr_Quad_Type use record
+ Context_Length at 0 range 0 .. 31;
+ Fflags_Bits at 4 range 0 .. 23;
+ Block_Version at 7 range 0 .. 7;
+ end record;
+ for ICB_Hdr_Quad_Type'Size use 64;
+
+ type Invo_Context_Blk_Type is record
+
+ Hdr_Quad : ICB_Hdr_Quad_Type;
+ -- The first quadword contains:
+ -- o The length of the structure in bytes (a longword field)
+ -- o The frame flags (a 3 byte field of bits)
+ -- o The version number (a 1 byte field)
+
+ Procedure_Descriptor : Unsigned_Quadword;
+ -- The address of the procedure descriptor for the procedure
+
+ Program_Counter : Integer_64;
+ -- The current PC of a given procedure invocation
+
+ Processor_Status : Integer_64;
+ -- The current PS of a given procedure invocation
+
+ Ireg : Unsigned_Quadword_Array (0 .. 30);
+ Freg : Unsigned_Quadword_Array (0 .. 30);
+ -- The register contents areas. 31 for scalars, 31 for float.
+
+ System_Defined : Unsigned_Quadword_Array (0 .. 1);
+ -- The following is an "internal" area that's reserved for use by
+ -- the operating system. It's size may vary over time.
+
+ -- Chfctx_Addr : Unsigned_Quadword;
+ -- Defined as a comment since it overlaps other fields
+
+ Filler_1 : String (1 .. 0);
+ -- Align to octaword
+ end record;
+
+ for Invo_Context_Blk_Type use record
+ Hdr_Quad at 0 range 0 .. 63;
+ Procedure_Descriptor at 8 range 0 .. 63;
+ Program_Counter at 16 range 0 .. 63;
+ Processor_Status at 24 range 0 .. 63;
+ Ireg at 32 range 0 .. 1983;
+ Freg at 280 range 0 .. 1983;
+ System_Defined at 528 range 0 .. 127;
+
+ -- Component representation spec(s) below are defined as
+ -- comments since they overlap other fields
+
+ -- Chfctx_Addr at 528 range 0 .. 63;
+
+ Filler_1 at 544 range 0 .. -1;
+ end record;
+ for Invo_Context_Blk_Type'Size use 4352;
+
+ subtype Invo_Handle_Type is Unsigned_Longword;
+
+ type Invo_Handle_Access_Type is access all Invo_Handle_Type;
+
+ function Fetch is new Fetch_From_Address (Code_Loc);
+
+ function To_Invo_Handle_Access is new Unchecked_Conversion
+ (Machine_State, Invo_Handle_Access_Type);
+
+ function To_Machine_State is new Unchecked_Conversion
+ (System.Address, Machine_State);
+
+ ----------------------------
+ -- Allocate_Machine_State --
+ ----------------------------
+
+ function Allocate_Machine_State return Machine_State is
+ begin
+ return To_Machine_State
+ (Memory.Alloc (Invo_Handle_Type'Max_Size_In_Storage_Elements));
+ end Allocate_Machine_State;
+
+ -------------------
+ -- Enter_Handler --
+ -------------------
+
+ procedure Enter_Handler (M : Machine_State; Handler : Handler_Loc) is
+ procedure Get_Invo_Context (
+ Result : out Unsigned_Longword; -- return value
+ Invo_Handle : Invo_Handle_Type;
+ Invo_Context : out Invo_Context_Blk_Type);
+
+ pragma Interface (External, Get_Invo_Context);
+
+ pragma Import_Valued_Procedure (Get_Invo_Context, "LIB$GET_INVO_CONTEXT",
+ (Unsigned_Longword, Invo_Handle_Type, Invo_Context_Blk_Type),
+ (Value, Value, Reference));
+
+ ICB : Invo_Context_Blk_Type;
+
+ procedure Goto_Unwind (
+ Status : out Cond_Value_Type; -- return value
+ Target_Invo : Address := Address_Zero;
+ Target_PC : Address := Address_Zero;
+ New_R0 : Unsigned_Quadword := Unsigned_Quadword'Null_Parameter;
+ New_R1 : Unsigned_Quadword := Unsigned_Quadword'Null_Parameter);
+
+ pragma Interface (External, Goto_Unwind);
+
+ pragma Import_Valued_Procedure
+ (Goto_Unwind, "SYS$GOTO_UNWIND",
+ (Cond_Value_Type, Address, Address,
+ Unsigned_Quadword, Unsigned_Quadword),
+ (Value, Reference, Reference,
+ Reference, Reference));
+
+ Status : Cond_Value_Type;
+
+ begin
+ Get_Invo_Context (Status, To_Invo_Handle_Access (M).all, ICB);
+ Goto_Unwind
+ (Status, System.Address (To_Invo_Handle_Access (M).all), Handler);
+ end Enter_Handler;
+
+ ----------------
+ -- Fetch_Code --
+ ----------------
+
+ function Fetch_Code (Loc : Code_Loc) return Code_Loc is
+ begin
+ -- The starting address is in the second longword pointed to by Loc.
+
+ return Fetch (System.Aux_DEC."+" (Loc, 8));
+ end Fetch_Code;
+
+ ------------------------
+ -- Free_Machine_State --
+ ------------------------
+
+ procedure Free_Machine_State (M : in out Machine_State) is
+ begin
+ Memory.Free (Address (M));
+ M := Machine_State (Null_Address);
+ end Free_Machine_State;
+
+ ------------------
+ -- Get_Code_Loc --
+ ------------------
+
+ function Get_Code_Loc (M : Machine_State) return Code_Loc is
+ procedure Get_Invo_Context (
+ Result : out Unsigned_Longword; -- return value
+ Invo_Handle : in Invo_Handle_Type;
+ Invo_Context : out Invo_Context_Blk_Type);
+
+ pragma Interface (External, Get_Invo_Context);
+
+ pragma Import_Valued_Procedure (Get_Invo_Context, "LIB$GET_INVO_CONTEXT",
+ (Unsigned_Longword, Invo_Handle_Type, Invo_Context_Blk_Type),
+ (Value, Value, Reference));
+
+ Asm_Call_Size : constant := 4;
+ -- Under VMS a call
+ -- asm instruction takes 4 bytes. So we must remove this amount.
+
+ ICB : Invo_Context_Blk_Type;
+ Status : Cond_Value_Type;
+
+ begin
+ Get_Invo_Context (Status, To_Invo_Handle_Access (M).all, ICB);
+
+ if (Status and 1) /= 1 then
+ return Code_Loc (System.Null_Address);
+ end if;
+
+ return Code_Loc (ICB.Program_Counter - Asm_Call_Size);
+ end Get_Code_Loc;
+
+ --------------------------
+ -- Machine_State_Length --
+ --------------------------
+
+ function Machine_State_Length
+ return System.Storage_Elements.Storage_Offset
+ is
+ use System.Storage_Elements;
+
+ begin
+ return Invo_Handle_Type'Size / 8;
+ end Machine_State_Length;
+
+ ---------------
+ -- Pop_Frame --
+ ---------------
+
+ procedure Pop_Frame
+ (M : Machine_State;
+ Info : Subprogram_Info_Type)
+ is
+ pragma Warnings (Off, Info);
+
+ procedure Get_Prev_Invo_Handle (
+ Result : out Invo_Handle_Type; -- return value
+ ICB : in Invo_Handle_Type);
+
+ pragma Interface (External, Get_Prev_Invo_Handle);
+
+ pragma Import_Valued_Procedure
+ (Get_Prev_Invo_Handle, "LIB$GET_PREV_INVO_HANDLE",
+ (Invo_Handle_Type, Invo_Handle_Type),
+ (Value, Value));
+
+ Prev_Handle : aliased Invo_Handle_Type;
+
+ begin
+ Get_Prev_Invo_Handle (Prev_Handle, To_Invo_Handle_Access (M).all);
+ To_Invo_Handle_Access (M).all := Prev_Handle;
+ end Pop_Frame;
+
+ -----------------------
+ -- Set_Machine_State --
+ -----------------------
+
+ procedure Set_Machine_State (M : Machine_State) is
+
+ procedure Get_Curr_Invo_Context
+ (Invo_Context : out Invo_Context_Blk_Type);
+
+ pragma Interface (External, Get_Curr_Invo_Context);
+
+ pragma Import_Valued_Procedure
+ (Get_Curr_Invo_Context, "LIB$GET_CURR_INVO_CONTEXT",
+ (Invo_Context_Blk_Type),
+ (Reference));
+
+ procedure Get_Invo_Handle (
+ Result : out Invo_Handle_Type; -- return value
+ Invo_Context : in Invo_Context_Blk_Type);
+
+ pragma Interface (External, Get_Invo_Handle);
+
+ pragma Import_Valued_Procedure (Get_Invo_Handle, "LIB$GET_INVO_HANDLE",
+ (Invo_Handle_Type, Invo_Context_Blk_Type),
+ (Value, Reference));
+
+ ICB : Invo_Context_Blk_Type;
+ Invo_Handle : aliased Invo_Handle_Type;
+
+ begin
+ Get_Curr_Invo_Context (ICB);
+ Get_Invo_Handle (Invo_Handle, ICB);
+ To_Invo_Handle_Access (M).all := Invo_Handle;
+ Pop_Frame (M, System.Null_Address);
+ end Set_Machine_State;
+
+ ------------------------------
+ -- Set_Signal_Machine_State --
+ ------------------------------
+
+ procedure Set_Signal_Machine_State
+ (M : Machine_State;
+ Context : System.Address)
+ is
+ pragma Warnings (Off, M);
+ pragma Warnings (Off, Context);
+
+ begin
+ null;
+ end Set_Signal_Machine_State;
+
+end System.Machine_State_Operations;
diff --git a/gcc/ada/s-mastop-x86.adb b/gcc/ada/s-mastop-x86.adb
new file mode 100644
index 00000000000..96ac1138d7e
--- /dev/null
+++ b/gcc/ada/s-mastop-x86.adb
@@ -0,0 +1,594 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- SYSTEM.MACHINE_STATE_OPERATIONS --
+-- --
+-- B o d y --
+-- (Version for x86) --
+-- --
+-- Copyright (C) 1999-2004 Ada Core Technologies, 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- Note: it is very important that this unit not generate any exception
+-- tables of any kind. Otherwise we get a nasty rtsfind recursion problem.
+-- This means no subprograms, including implicitly generated ones.
+
+with Unchecked_Conversion;
+with System.Storage_Elements;
+with System.Machine_Code; use System.Machine_Code;
+with System.Memory;
+
+package body System.Machine_State_Operations is
+
+ function "+" (Left, Right : Address) return Address;
+ pragma Import (Intrinsic, "+");
+ -- Provide addition operation on type Address (this may not be directly
+ -- available if type System.Address is non-private and the operations on
+ -- the type are made abstract to hide them from public users of System).
+
+ use System.Exceptions;
+
+ type Uns8 is mod 2 ** 8;
+ type Uns32 is mod 2 ** 32;
+
+ type Bits5 is mod 2 ** 5;
+ type Bits6 is mod 2 ** 6;
+
+ function To_Address is new Unchecked_Conversion (Uns32, Address);
+
+ type Uns32_Ptr is access all Uns32;
+ function To_Uns32_Ptr is new Unchecked_Conversion (Uns32, Uns32_Ptr);
+
+ -- Note: the type Uns32 has an alignment of 4. However, in some cases
+ -- values of type Uns32_Ptr will not be aligned (notably in the case
+ -- where we get the immediate field from an instruction). However this
+ -- does not matter in practice, since the x86 does not require that
+ -- operands be aligned.
+
+ ----------------------
+ -- General Approach --
+ ----------------------
+
+ -- For the x86 version of this unit, the Subprogram_Info_Type values
+ -- are simply the starting code address for the subprogram. Popping
+ -- of stack frames works by analyzing the code in the prolog, and
+ -- deriving from this analysis the necessary information for restoring
+ -- the registers, including the return point.
+
+ ---------------------------
+ -- Description of Prolog --
+ ---------------------------
+
+ -- If a frame pointer is present, the prolog looks like
+
+ -- pushl %ebp
+ -- movl %esp,%ebp
+ -- subl $nnn,%esp omitted if nnn = 0
+ -- pushl %edi omitted if edi not used
+ -- pushl %esi omitted if esi not used
+ -- pushl %ebx omitted if ebx not used
+
+ -- If a frame pointer is not present, the prolog looks like
+
+ -- subl $nnn,%esp omitted if nnn = 0
+ -- pushl %ebp omitted if ebp not used
+ -- pushl %edi omitted if edi not used
+ -- pushl %esi omitted if esi not used
+ -- pushl %ebx omitted if ebx not used
+
+ -- Note: any or all of the save over call registers may be used and
+ -- if so, will be saved using pushl as shown above. The order of the
+ -- pushl instructions will be as shown above for gcc generated code,
+ -- but the code in this unit does not assume this.
+
+ -------------------------
+ -- Description of Call --
+ -------------------------
+
+ -- A call looks like:
+
+ -- pushl ... push parameters
+ -- pushl ...
+ -- call ... perform the call
+ -- addl $nnn,%esp omitted if no parameters
+
+ -- Note that we are not absolutely guaranteed that the call is always
+ -- followed by an addl operation that readjusts %esp for this particular
+ -- call. There are two reasons for this:
+
+ -- 1) The addl can be delayed and combined in the case where more than
+ -- one call appears in sequence. This can be suppressed by using the
+ -- switch -fno-defer-pop and for Ada code, we automatically use
+ -- this switch, but we could still be dealing with C code that was
+ -- compiled without using this switch.
+
+ -- 2) Scheduling may result in moving the addl instruction away from
+ -- the call. It is not clear if this actually can happen at the
+ -- current time, but it is certainly conceptually possible.
+
+ -- The addl after the call is important, since we need to be able to
+ -- restore the proper %esp value when we pop the stack. However, we do
+ -- not try to compensate for either of the above effects. As noted above,
+ -- case 1 does not occur for Ada code, and it does not appear in practice
+ -- that case 2 occurs with any significant frequency (we have never seen
+ -- an example so far for gcc generated code).
+
+ -- Furthermore, it is only in the case of -fomit-frame-pointer that we
+ -- really get into trouble from not properly restoring %esp. If we have
+ -- a frame pointer, then the worst that happens is that %esp is slightly
+ -- more depressed than it should be. This could waste a bit of space on
+ -- the stack, and even in some cases cause a storage leak on the stack,
+ -- but it will not affect the functional correctness of the processing.
+
+ ----------------------------------------
+ -- Definitions of Instruction Formats --
+ ----------------------------------------
+
+ type Rcode is (eax, ecx, edx, ebx, esp, ebp, esi, edi);
+ pragma Warnings (Off, Rcode);
+ -- Code indicating which register is referenced in an instruction
+
+ -- The following define the format of a pushl instruction
+
+ Op_pushl : constant Bits5 := 2#01010#;
+
+ type Ins_pushl is record
+ Op : Bits5 := Op_pushl;
+ Reg : Rcode;
+ end record;
+
+ for Ins_pushl use record
+ Op at 0 range 3 .. 7;
+ Reg at 0 range 0 .. 2;
+ end record;
+
+ Ins_pushl_ebp : constant Ins_pushl := (Op_pushl, Reg => ebp);
+
+ type Ins_pushl_Ptr is access all Ins_pushl;
+
+ -- For the movl %esp,%ebp instruction, we only need to know the length
+ -- because we simply skip past it when we analyze the prolog.
+
+ Ins_movl_length : constant := 2;
+
+ -- The following define the format of addl/subl esp instructions
+
+ Op_Immed : constant Bits6 := 2#100000#;
+
+ Op2_addl_Immed : constant Bits5 := 2#11100#;
+ pragma Unreferenced (Op2_addl_Immed);
+
+ Op2_subl_Immed : constant Bits5 := 2#11101#;
+
+ type Word_Byte is (Word, Byte);
+ pragma Unreferenced (Byte);
+
+ type Ins_addl_subl_byte is record
+ Op : Bits6; -- Set to Op_Immed
+ w : Word_Byte; -- Word/Byte flag (set to 1 = byte)
+ s : Boolean; -- Sign extension bit (1 = extend)
+ Op2 : Bits5; -- Secondary opcode
+ Reg : Rcode; -- Register
+ Imm8 : Uns8; -- Immediate operand
+ end record;
+
+ for Ins_addl_subl_byte use record
+ Op at 0 range 2 .. 7;
+ w at 0 range 1 .. 1;
+ s at 0 range 0 .. 0;
+ Op2 at 1 range 3 .. 7;
+ Reg at 1 range 0 .. 2;
+ Imm8 at 2 range 0 .. 7;
+ end record;
+
+ type Ins_addl_subl_word is record
+ Op : Bits6; -- Set to Op_Immed
+ w : Word_Byte; -- Word/Byte flag (set to 0 = word)
+ s : Boolean; -- Sign extension bit (1 = extend)
+ Op2 : Bits5; -- Secondary opcode
+ Reg : Rcode; -- Register
+ Imm32 : Uns32; -- Immediate operand
+ end record;
+
+ for Ins_addl_subl_word use record
+ Op at 0 range 2 .. 7;
+ w at 0 range 1 .. 1;
+ s at 0 range 0 .. 0;
+ Op2 at 1 range 3 .. 7;
+ Reg at 1 range 0 .. 2;
+ Imm32 at 2 range 0 .. 31;
+ end record;
+
+ type Ins_addl_subl_byte_Ptr is access all Ins_addl_subl_byte;
+ type Ins_addl_subl_word_Ptr is access all Ins_addl_subl_word;
+
+ ---------------------
+ -- Prolog Analysis --
+ ---------------------
+
+ -- The analysis of the prolog answers the following questions:
+
+ -- 1. Is %ebp used as a frame pointer?
+ -- 2. How far is SP depressed (i.e. what is the stack frame size)
+ -- 3. Which registers are saved in the prolog, and in what order
+
+ -- The following data structure stores the answers to these questions
+
+ subtype SOC is Rcode range ebx .. edi;
+ -- Possible save over call registers
+
+ SOC_Max : constant := 4;
+ -- Max number of SOC registers that can be pushed
+
+ type SOC_Push_Regs_Type is array (1 .. 4) of Rcode;
+ -- Used to hold the register codes of pushed SOC registers
+
+ type Prolog_Type is record
+
+ Frame_Reg : Boolean;
+ -- This is set to True if %ebp is used as a frame register, and
+ -- False otherwise (in the False case, %ebp may be saved in the
+ -- usual manner along with the other SOC registers).
+
+ Frame_Length : Uns32;
+ -- Amount by which ESP is decremented on entry, includes the effects
+ -- of push's of save over call registers as indicated above, e.g. if
+ -- the prolog of a routine is:
+ --
+ -- pushl %ebp
+ -- movl %esp,%ebp
+ -- subl $424,%esp
+ -- pushl %edi
+ -- pushl %esi
+ -- pushl %ebx
+ --
+ -- Then the value of Frame_Length would be 436 (424 + 3 * 4). A
+ -- precise definition is that it is:
+ --
+ -- %esp on entry minus %esp after last SOC push
+ --
+ -- That definition applies both in the frame pointer present and
+ -- the frame pointer absent cases.
+
+ Num_SOC_Push : Integer range 0 .. SOC_Max;
+ -- Number of save over call registers actually saved by pushl
+ -- instructions (other than the initial pushl to save the frame
+ -- pointer if a frame pointer is in use).
+
+ SOC_Push_Regs : SOC_Push_Regs_Type;
+ -- The First Num_SOC_Push entries of this array are used to contain
+ -- the codes for the SOC registers, in the order in which they were
+ -- pushed. Note that this array excludes %ebp if it is used as a frame
+ -- register, since although %ebp is still considered an SOC register
+ -- in this case, it is saved and restored by a separate mechanism.
+ -- Also we will never see %esp represented in this list. Again, it is
+ -- true that %esp is saved over call, but it is restored by a separate
+ -- mechanism.
+
+ end record;
+
+ procedure Analyze_Prolog (A : Address; Prolog : out Prolog_Type);
+ -- Given the address of the start of the prolog for a procedure,
+ -- analyze the instructions of the prolog, and set Prolog to contain
+ -- the information obtained from this analysis.
+
+ ----------------------------------
+ -- Machine_State_Representation --
+ ----------------------------------
+
+ -- The type Machine_State is defined in the body of Ada.Exceptions as
+ -- a Storage_Array of length 1 .. Machine_State_Length. But really it
+ -- has structure as defined here. We use the structureless declaration
+ -- in Ada.Exceptions to avoid this unit from being implementation
+ -- dependent. The actual definition of Machine_State is as follows:
+
+ type SOC_Regs_Type is array (SOC) of Uns32;
+
+ type MState is record
+ eip : Uns32;
+ -- The instruction pointer location (which is the return point
+ -- value from the next level down in all cases).
+
+ Regs : SOC_Regs_Type;
+ -- Values of the save over call registers
+ end record;
+
+ for MState use record
+ eip at 0 range 0 .. 31;
+ Regs at 4 range 0 .. 5 * 32 - 1;
+ end record;
+ -- Note: the routines Enter_Handler, and Set_Machine_State reference
+ -- the fields in this structure non-symbolically.
+
+ type MState_Ptr is access all MState;
+
+ function To_MState_Ptr is
+ new Unchecked_Conversion (Machine_State, MState_Ptr);
+
+ ----------------------------
+ -- Allocate_Machine_State --
+ ----------------------------
+
+ function Allocate_Machine_State return Machine_State is
+ use System.Storage_Elements;
+
+ begin
+ return Machine_State
+ (Memory.Alloc (MState'Max_Size_In_Storage_Elements));
+ end Allocate_Machine_State;
+
+ --------------------
+ -- Analyze_Prolog --
+ --------------------
+
+ procedure Analyze_Prolog (A : Address; Prolog : out Prolog_Type) is
+ Ptr : Address;
+ Ppl : Ins_pushl_Ptr;
+ Pas : Ins_addl_subl_byte_Ptr;
+
+ function To_Ins_pushl_Ptr is
+ new Unchecked_Conversion (Address, Ins_pushl_Ptr);
+
+ function To_Ins_addl_subl_byte_Ptr is
+ new Unchecked_Conversion (Address, Ins_addl_subl_byte_Ptr);
+
+ function To_Ins_addl_subl_word_Ptr is
+ new Unchecked_Conversion (Address, Ins_addl_subl_word_Ptr);
+
+ begin
+ Ptr := A;
+ Prolog.Frame_Length := 0;
+
+ if Ptr = Null_Address then
+ Prolog.Num_SOC_Push := 0;
+ Prolog.Frame_Reg := True;
+ return;
+ end if;
+
+ if To_Ins_pushl_Ptr (Ptr).all = Ins_pushl_ebp then
+ Ptr := Ptr + 1 + Ins_movl_length;
+ Prolog.Frame_Reg := True;
+ else
+ Prolog.Frame_Reg := False;
+ end if;
+
+ Pas := To_Ins_addl_subl_byte_Ptr (Ptr);
+
+ if Pas.Op = Op_Immed
+ and then Pas.Op2 = Op2_subl_Immed
+ and then Pas.Reg = esp
+ then
+ if Pas.w = Word then
+ Prolog.Frame_Length := Prolog.Frame_Length +
+ To_Ins_addl_subl_word_Ptr (Ptr).Imm32;
+ Ptr := Ptr + 6;
+
+ else
+ Prolog.Frame_Length := Prolog.Frame_Length + Uns32 (Pas.Imm8);
+ Ptr := Ptr + 3;
+
+ -- Note: we ignore sign extension, since a sign extended
+ -- value that was negative would imply a ludicrous frame size.
+ end if;
+ end if;
+
+ -- Now scan push instructions for SOC registers
+
+ Prolog.Num_SOC_Push := 0;
+
+ loop
+ Ppl := To_Ins_pushl_Ptr (Ptr);
+
+ if Ppl.Op = Op_pushl and then Ppl.Reg in SOC then
+ Prolog.Num_SOC_Push := Prolog.Num_SOC_Push + 1;
+ Prolog.SOC_Push_Regs (Prolog.Num_SOC_Push) := Ppl.Reg;
+ Prolog.Frame_Length := Prolog.Frame_Length + 4;
+ Ptr := Ptr + 1;
+
+ else
+ exit;
+ end if;
+ end loop;
+
+ end Analyze_Prolog;
+
+ -------------------
+ -- Enter_Handler --
+ -------------------
+
+ procedure Enter_Handler (M : Machine_State; Handler : Handler_Loc) is
+ begin
+ Asm ("mov %0,%%edx", Inputs => Machine_State'Asm_Input ("r", M));
+ Asm ("mov %0,%%eax", Inputs => Handler_Loc'Asm_Input ("r", Handler));
+
+ Asm ("mov 4(%%edx),%%ebx"); -- M.Regs (ebx)
+ Asm ("mov 12(%%edx),%%ebp"); -- M.Regs (ebp)
+ Asm ("mov 16(%%edx),%%esi"); -- M.Regs (esi)
+ Asm ("mov 20(%%edx),%%edi"); -- M.Regs (edi)
+ Asm ("mov 8(%%edx),%%esp"); -- M.Regs (esp)
+ Asm ("jmp %*%%eax");
+ end Enter_Handler;
+
+ ----------------
+ -- Fetch_Code --
+ ----------------
+
+ function Fetch_Code (Loc : Code_Loc) return Code_Loc is
+ begin
+ return Loc;
+ end Fetch_Code;
+
+ ------------------------
+ -- Free_Machine_State --
+ ------------------------
+
+ procedure Free_Machine_State (M : in out Machine_State) is
+ begin
+ Memory.Free (Address (M));
+ M := Machine_State (Null_Address);
+ end Free_Machine_State;
+
+ ------------------
+ -- Get_Code_Loc --
+ ------------------
+
+ function Get_Code_Loc (M : Machine_State) return Code_Loc is
+
+ Asm_Call_Size : constant := 2;
+ -- Minimum size for a call instruction under ix86. Using the minimum
+ -- size is safe here as the call point computed from the return point
+ -- will always be inside the call instruction.
+
+ MS : constant MState_Ptr := To_MState_Ptr (M);
+
+ begin
+ if MS.eip = 0 then
+ return To_Address (MS.eip);
+ else
+ -- When doing a call the return address is pushed to the stack.
+ -- We want to return the call point address, so we substract
+ -- Asm_Call_Size from the return address. This value is set
+ -- to 5 as an asm call takes 5 bytes on x86 architectures.
+
+ return To_Address (MS.eip - Asm_Call_Size);
+ end if;
+ end Get_Code_Loc;
+
+ --------------------------
+ -- Machine_State_Length --
+ --------------------------
+
+ function Machine_State_Length
+ return System.Storage_Elements.Storage_Offset
+ is
+ begin
+ return MState'Max_Size_In_Storage_Elements;
+ end Machine_State_Length;
+
+ ---------------
+ -- Pop_Frame --
+ ---------------
+
+ procedure Pop_Frame
+ (M : Machine_State;
+ Info : Subprogram_Info_Type)
+ is
+ MS : constant MState_Ptr := To_MState_Ptr (M);
+ PL : Prolog_Type;
+
+ SOC_Ptr : Uns32;
+ -- Pointer to stack location after last SOC push
+
+ Rtn_Ptr : Uns32;
+ -- Pointer to stack location containing return address
+
+ begin
+ Analyze_Prolog (Info, PL);
+
+ -- Case of frame register, use EBP, safer than ESP
+
+ if PL.Frame_Reg then
+ SOC_Ptr := MS.Regs (ebp) - PL.Frame_Length;
+ Rtn_Ptr := MS.Regs (ebp) + 4;
+ MS.Regs (ebp) := To_Uns32_Ptr (MS.Regs (ebp)).all;
+
+ -- No frame pointer, use ESP, and hope we have it exactly right!
+
+ else
+ SOC_Ptr := MS.Regs (esp);
+ Rtn_Ptr := SOC_Ptr + PL.Frame_Length;
+ end if;
+
+ -- Get saved values of SOC registers
+
+ for J in reverse 1 .. PL.Num_SOC_Push loop
+ MS.Regs (PL.SOC_Push_Regs (J)) := To_Uns32_Ptr (SOC_Ptr).all;
+ SOC_Ptr := SOC_Ptr + 4;
+ end loop;
+
+ MS.eip := To_Uns32_Ptr (Rtn_Ptr).all;
+ MS.Regs (esp) := Rtn_Ptr + 4;
+ end Pop_Frame;
+
+ -----------------------
+ -- Set_Machine_State --
+ -----------------------
+
+ procedure Set_Machine_State (M : Machine_State) is
+ N : constant Asm_Output_Operand := No_Output_Operands;
+
+ begin
+ Asm ("mov %0,%%edx", N, Machine_State'Asm_Input ("r", M));
+
+ -- At this stage, we have the following situation (note that we
+ -- are assuming that the -fomit-frame-pointer switch has not been
+ -- used in compiling this procedure.
+
+ -- (value of M)
+ -- return point
+ -- old ebp <------ current ebp/esp value
+
+ -- The values of registers ebx/esi/edi are unchanged from entry
+ -- so they have the values we want, and %edx points to the parameter
+ -- value M, so we can store these values directly.
+
+ Asm ("mov %%ebx,4(%%edx)"); -- M.Regs (ebx)
+ Asm ("mov %%esi,16(%%edx)"); -- M.Regs (esi)
+ Asm ("mov %%edi,20(%%edx)"); -- M.Regs (edi)
+
+ -- The desired value of ebp is the old value
+
+ Asm ("mov 0(%%ebp),%%eax");
+ Asm ("mov %%eax,12(%%edx)"); -- M.Regs (ebp)
+
+ -- The return point is the desired eip value
+
+ Asm ("mov 4(%%ebp),%%eax");
+ Asm ("mov %%eax,(%%edx)"); -- M.eip
+
+ -- Finally, the desired %esp value is the value at the point of
+ -- call to this routine *before* pushing the parameter value.
+
+ Asm ("lea 12(%%ebp),%%eax");
+ Asm ("mov %%eax,8(%%edx)"); -- M.Regs (esp)
+ end Set_Machine_State;
+
+ ------------------------------
+ -- Set_Signal_Machine_State --
+ ------------------------------
+
+ procedure Set_Signal_Machine_State
+ (M : Machine_State;
+ Context : System.Address)
+ is
+ pragma Warnings (Off, M);
+ pragma Warnings (Off, Context);
+
+ begin
+ null;
+ end Set_Signal_Machine_State;
+
+end System.Machine_State_Operations;
diff --git a/gcc/ada/s-memory-mingw.adb b/gcc/ada/s-memory-mingw.adb
new file mode 100644
index 00000000000..a81665a0a59
--- /dev/null
+++ b/gcc/ada/s-memory-mingw.adb
@@ -0,0 +1,223 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . M E M O R Y --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2001-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This version provides ways to limit the amount of used memory for systems
+-- that do not have OS support for that.
+
+-- The amount of available memory available for dynamic allocation is limited
+-- by setting the environment variable GNAT_MEMORY_LIMIT to the number of
+-- kilobytes that can be used.
+--
+-- Windows is currently using this version.
+
+with Ada.Exceptions;
+with System.Soft_Links;
+
+package body System.Memory is
+
+ use Ada.Exceptions;
+ use System.Soft_Links;
+
+ function c_malloc (Size : size_t) return System.Address;
+ pragma Import (C, c_malloc, "malloc");
+
+ procedure c_free (Ptr : System.Address);
+ pragma Import (C, c_free, "free");
+
+ function c_realloc
+ (Ptr : System.Address; Size : size_t) return System.Address;
+ pragma Import (C, c_realloc, "realloc");
+
+ function msize (Ptr : System.Address) return size_t;
+ pragma Import (C, msize, "_msize");
+
+ function getenv (Str : String) return System.Address;
+ pragma Import (C, getenv);
+
+ function atoi (Str : System.Address) return Integer;
+ pragma Import (C, atoi);
+
+ Available_Memory : size_t := 0;
+ -- Amount of memory that is available for heap allocations.
+ -- A value of 0 means that the amount is not yet initialized.
+
+ Msize_Accuracy : constant := 4096;
+ -- Defines the amount of memory to add to requested allocation sizes,
+ -- because malloc may return a bigger block than requested. As msize
+ -- is used when by Free, it must be used on allocation as well. To
+ -- prevent underflow of available_memory we need to use a reserve.
+
+ procedure Check_Available_Memory (Size : size_t);
+ -- This routine must be called while holding the task lock. When the
+ -- memory limit is not yet initialized, it will be set to the value of
+ -- the GNAT_MEMORY_LIMIT environment variable or to unlimited if that
+ -- does not exist. If the size is larger than the amount of available
+ -- memory, the task lock will be freed and a storage_error exception
+ -- will be raised.
+
+ -----------
+ -- Alloc --
+ -----------
+
+ function Alloc (Size : size_t) return System.Address is
+ Result : System.Address;
+ Actual_Size : size_t := Size;
+
+ begin
+ if Size = size_t'Last then
+ Raise_Exception (Storage_Error'Identity, "object too large");
+ end if;
+
+ -- Change size from zero to non-zero. We still want a proper pointer
+ -- for the zero case because pointers to zero length objects have to
+ -- be distinct, but we can't just go ahead and allocate zero bytes,
+ -- since some malloc's return zero for a zero argument.
+
+ if Size = 0 then
+ Actual_Size := 1;
+ end if;
+
+ Lock_Task.all;
+
+ if Actual_Size + Msize_Accuracy >= Available_Memory then
+ Check_Available_Memory (Size + Msize_Accuracy);
+ end if;
+
+ Result := c_malloc (Actual_Size);
+
+ if Result /= System.Null_Address then
+ Available_Memory := Available_Memory - msize (Result);
+ end if;
+
+ Unlock_Task.all;
+
+ if Result = System.Null_Address then
+ Raise_Exception (Storage_Error'Identity, "heap exhausted");
+ end if;
+
+ return Result;
+ end Alloc;
+
+ ----------------------------
+ -- Check_Available_Memory --
+ ----------------------------
+
+ procedure Check_Available_Memory (Size : size_t) is
+ Gnat_Memory_Limit : System.Address;
+
+ begin
+ if Available_Memory = 0 then
+
+ -- The amount of available memory hasn't been initialized yet
+
+ Gnat_Memory_Limit := getenv ("GNAT_MEMORY_LIMIT" & ASCII.NUL);
+
+ if Gnat_Memory_Limit /= System.Null_Address then
+ Available_Memory :=
+ size_t (atoi (Gnat_Memory_Limit)) * 1024 + Msize_Accuracy;
+ else
+ Available_Memory := size_t'Last;
+ end if;
+ end if;
+
+ if Size >= Available_Memory then
+
+ -- There is a memory overflow
+
+ Unlock_Task.all;
+ Raise_Exception
+ (Storage_Error'Identity, "heap memory limit exceeded");
+ end if;
+ end Check_Available_Memory;
+
+ ----------
+ -- Free --
+ ----------
+
+ procedure Free (Ptr : System.Address) is
+ begin
+ Lock_Task.all;
+
+ if Ptr /= System.Null_Address then
+ Available_Memory := Available_Memory + msize (Ptr);
+ end if;
+
+ c_free (Ptr);
+
+ Unlock_Task.all;
+ end Free;
+
+ -------------
+ -- Realloc --
+ -------------
+
+ function Realloc
+ (Ptr : System.Address;
+ Size : size_t)
+ return System.Address
+ is
+ Result : System.Address;
+ Actual_Size : constant size_t := Size;
+ Old_Size : size_t;
+
+ begin
+ if Size = size_t'Last then
+ Raise_Exception (Storage_Error'Identity, "object too large");
+ end if;
+
+ Lock_Task.all;
+
+ Old_Size := msize (Ptr);
+
+ -- Conservative check - no need to try to be precise here
+
+ if Size + Msize_Accuracy >= Available_Memory then
+ Check_Available_Memory (Size + Msize_Accuracy);
+ end if;
+
+ Result := c_realloc (Ptr, Actual_Size);
+
+ if Result /= System.Null_Address then
+ Available_Memory := Available_Memory + Old_Size - msize (Result);
+ end if;
+
+ Unlock_Task.all;
+
+ if Result = System.Null_Address then
+ Raise_Exception (Storage_Error'Identity, "heap exhausted");
+ end if;
+
+ return Result;
+ end Realloc;
+
+end System.Memory;
diff --git a/gcc/ada/s-osinte-aix-fsu.ads b/gcc/ada/s-osinte-aix-fsu.ads
new file mode 100644
index 00000000000..7ea96a83299
--- /dev/null
+++ b/gcc/ada/s-osinte-aix-fsu.ads
@@ -0,0 +1,589 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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 is a AIX (FSU THREADS) version of this package
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+with Interfaces.C;
+with Unchecked_Conversion;
+
+package System.OS_Interface is
+ pragma Preelaborate;
+ -- pragma Elaborate_Body;
+
+ pragma Linker_Options ("-lgthreads");
+ pragma Linker_Options ("-lmalloc");
+
+ subtype int is Interfaces.C.int;
+ subtype short is Interfaces.C.short;
+ subtype long is Interfaces.C.long;
+ subtype unsigned is Interfaces.C.unsigned;
+ subtype unsigned_short is Interfaces.C.unsigned_short;
+ subtype unsigned_long is Interfaces.C.unsigned_long;
+ subtype unsigned_char is Interfaces.C.unsigned_char;
+ subtype plain_char is Interfaces.C.plain_char;
+ subtype size_t is Interfaces.C.size_t;
+
+ -----------
+ -- Errno --
+ -----------
+
+ function errno return int;
+ pragma Import (C, errno, "__get_errno");
+
+ EAGAIN : constant := 11;
+ EINTR : constant := 4;
+ EINVAL : constant := 22;
+ ENOMEM : constant := 12;
+ ETIMEDOUT : constant := 78;
+
+ -------------
+ -- Signals --
+ -------------
+
+ Max_Interrupt : constant := 63;
+ type Signal is new int range 0 .. Max_Interrupt;
+ for Signal'Size use int'Size;
+
+ SIGHUP : constant := 1; -- hangup
+ SIGINT : constant := 2; -- interrupt (rubout)
+ SIGQUIT : constant := 3; -- quit (ASCD FS)
+ SIGILL : constant := 4; -- illegal instruction (not reset)
+ SIGTRAP : constant := 5; -- trace trap (not reset)
+ SIGIOT : constant := 6; -- IOT instruction
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGEMT : constant := 7; -- EMT instruction
+ SIGFPE : constant := 8; -- floating point exception
+ SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
+ SIGBUS : constant := 10; -- bus error
+ SIGSEGV : constant := 11; -- segmentation violation
+ SIGSYS : constant := 12; -- bad argument to system call
+ SIGPIPE : constant := 13; -- write on a pipe with no one to read it
+ SIGALRM : constant := 14; -- alarm clock
+ SIGTERM : constant := 15; -- software termination signal from kill
+ SIGUSR1 : constant := 30; -- user defined signal 1
+ SIGUSR2 : constant := 31; -- user defined signal 2
+ SIGCLD : constant := 20; -- alias for SIGCHLD
+ SIGCHLD : constant := 20; -- child status change
+ SIGPWR : constant := 29; -- power-fail restart
+ SIGWINCH : constant := 28; -- window size change
+ SIGURG : constant := 16; -- urgent condition on IO channel
+ SIGPOLL : constant := 23; -- pollable event occurred
+ SIGIO : constant := 23; -- I/O possible (Solaris SIGPOLL alias)
+ SIGSTOP : constant := 17; -- stop (cannot be caught or ignored)
+ SIGTSTP : constant := 18; -- user stop requested from tty
+ SIGCONT : constant := 19; -- stopped process has been continued
+ SIGTTIN : constant := 21; -- background tty read attempted
+ SIGTTOU : constant := 22; -- background tty write attempted
+ SIGVTALRM : constant := 34; -- virtual timer expired
+ SIGPROF : constant := 32; -- profiling timer expired
+ SIGXCPU : constant := 24; -- CPU time limit exceeded
+ SIGXFSZ : constant := 25; -- filesize limit exceeded
+ SIGWAITING : constant := 39; -- m:n scheduling
+
+ -- the following signals are AIX specific
+ SIGMSG : constant := 27; -- input data is in the ring buffer
+ SIGDANGER : constant := 33; -- system crash imminent
+ SIGMIGRATE : constant := 35; -- migrate process
+ SIGPRE : constant := 36; -- programming exception
+ SIGVIRT : constant := 37; -- AIX virtual time alarm
+ SIGALRM1 : constant := 38; -- m:n condition variables
+ SIGKAP : constant := 60; -- keep alive poll from native keyboard
+ SIGGRANT : constant := SIGKAP; -- monitor mode granted
+ SIGRETRACT : constant := 61; -- monitor mode should be relinguished
+ SIGSOUND : constant := 62; -- sound control has completed
+ SIGSAK : constant := 63; -- secure attention key
+
+ SIGADAABORT : constant := SIGABRT;
+
+ type Signal_Set is array (Natural range <>) of Signal;
+
+ Unmasked : constant Signal_Set :=
+ (SIGTRAP, SIGTTIN, SIGTTOU, SIGTSTP, SIGPROF);
+ Reserved : constant Signal_Set :=
+ (SIGKILL, SIGSTOP, SIGALRM, SIGWAITING);
+
+ type sigset_t is private;
+
+ function sigaddset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigaddset, "sigaddset");
+
+ function sigdelset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigdelset, "sigdelset");
+
+ function sigfillset (set : access sigset_t) return int;
+ pragma Import (C, sigfillset, "sigfillset");
+
+ function sigismember (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigismember, "sigismember");
+
+ function sigemptyset (set : access sigset_t) return int;
+ pragma Import (C, sigemptyset, "sigemptyset");
+
+ type struct_sigaction is record
+ sa_handler : System.Address;
+ sa_mask : sigset_t;
+ sa_flags : int;
+ end record;
+ pragma Convention (C, struct_sigaction);
+ type struct_sigaction_ptr is access all struct_sigaction;
+
+ SA_SIGINFO : constant := 16#0100#;
+
+ SIG_BLOCK : constant := 0;
+ SIG_UNBLOCK : constant := 1;
+ SIG_SETMASK : constant := 2;
+
+ SIG_DFL : constant := 0;
+ SIG_IGN : constant := 1;
+
+ function sigaction
+ (sig : Signal;
+ act : struct_sigaction_ptr;
+ oact : struct_sigaction_ptr) return int;
+ pragma Import (C, sigaction, "_internal_sigaction");
+
+ ----------
+ -- Time --
+ ----------
+
+ Time_Slice_Supported : constant Boolean := True;
+ -- Indicates wether time slicing is supported (i.e FSU threads have been
+ -- compiled with DEF_RR)
+
+ type timespec is private;
+
+ type clockid_t is private;
+
+ CLOCK_REALTIME : constant clockid_t;
+
+ function clock_gettime
+ (clock_id : clockid_t;
+ tp : access timespec) return int;
+ pragma Import (C, clock_gettime, "clock_gettime");
+
+ function To_Duration (TS : timespec) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timespec (D : Duration) return timespec;
+ pragma Inline (To_Timespec);
+
+ type struct_timeval is private;
+
+ function To_Duration (TV : struct_timeval) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timeval (D : Duration) return struct_timeval;
+ pragma Inline (To_Timeval);
+
+ -------------------------
+ -- Priority Scheduling --
+ -------------------------
+
+ SCHED_FIFO : constant := 0;
+ SCHED_RR : constant := 1;
+ SCHED_OTHER : constant := 2;
+
+ -------------
+ -- Process --
+ -------------
+
+ type pid_t is private;
+
+ function kill (pid : pid_t; sig : Signal) return int;
+ pragma Import (C, kill, "kill");
+
+ function getpid return pid_t;
+ pragma Import (C, getpid, "getpid");
+
+ ---------
+ -- LWP --
+ ---------
+
+ function lwp_self return System.Address;
+ -- lwp_self does not exist on this thread library, revert to pthread_self
+ -- which is the closest approximation (with getpid). This function is
+ -- needed to share 7staprop.adb across POSIX-like targets.
+ pragma Import (C, lwp_self, "pthread_self");
+
+ -------------
+ -- Threads --
+ -------------
+
+ type Thread_Body is access
+ function (arg : System.Address) return System.Address;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ type pthread_t is private;
+ subtype Thread_Id is pthread_t;
+
+ type pthread_mutex_t is limited private;
+ type pthread_cond_t is limited private;
+ type pthread_attr_t is limited private;
+ type pthread_mutexattr_t is limited private;
+ type pthread_condattr_t is limited private;
+ type pthread_key_t is private;
+
+ PTHREAD_CREATE_DETACHED : constant := 1;
+
+ -----------
+ -- Stack --
+ -----------
+
+ Stack_Base_Available : constant Boolean := True;
+ -- Indicates wether the stack base is available on this target.
+ -- This allows us to share s-osinte.adb between all the FSU run time.
+ -- Note that this value can only be true if pthread_t has a complete
+ -- definition that corresponds exactly to the C header files.
+
+ function Get_Stack_Base (thread : pthread_t) return Address;
+ pragma Inline (Get_Stack_Base);
+ -- returns the stack base of the specified thread.
+ -- Only call this function when Stack_Base_Available is True.
+
+ 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
+
+ PROT_NONE : constant := 0;
+ PROT_READ : constant := 1;
+ PROT_WRITE : constant := 2;
+ PROT_EXEC : constant := 4;
+ PROT_ALL : constant := PROT_READ + PROT_WRITE + PROT_EXEC;
+
+ PROT_ON : constant := PROT_READ;
+ PROT_OFF : constant := PROT_ALL;
+
+ function mprotect (addr : Address; len : size_t; prot : int) return int;
+ pragma Import (C, mprotect);
+
+ ---------------------------------------
+ -- Nonstandard Thread Initialization --
+ ---------------------------------------
+
+ procedure pthread_init;
+ -- FSU_THREADS requires pthread_init, which is nonstandard
+ -- and this should be invoked during the elaboration of s-taprop.adb
+ pragma Import (C, pthread_init, "pthread_init");
+
+ -------------------------
+ -- POSIX.1c Section 3 --
+ -------------------------
+
+ function sigwait
+ (set : access sigset_t;
+ sig : access Signal) return int;
+ -- FSU_THREADS has a nonstandard sigwait
+
+ function pthread_kill
+ (thread : pthread_t;
+ sig : Signal) return int;
+ pragma Import (C, pthread_kill, "pthread_kill");
+
+ -- FSU threads does not have pthread_sigmask. Instead, it redefines
+ -- sigprocmask and then uses a special syscall API to call the system
+ -- version. Doing syscalls on AiX is very difficult, so we rename the
+ -- pthread version instead.
+
+ type sigset_t_ptr is access all sigset_t;
+
+ function pthread_sigmask
+ (how : int;
+ set : sigset_t_ptr;
+ oset : sigset_t_ptr) return int;
+ pragma Import (C, pthread_sigmask, "_internal_sigprocmask");
+
+ --------------------------
+ -- POSIX.1c Section 11 --
+ --------------------------
+
+ function pthread_mutexattr_init
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_init, "pthread_mutexattr_init");
+
+ function pthread_mutexattr_destroy
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_destroy, "pthread_mutexattr_destroy");
+
+ function pthread_mutex_init
+ (mutex : access pthread_mutex_t;
+ attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutex_init, "pthread_mutex_init");
+
+ function pthread_mutex_destroy (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_destroy, "pthread_mutex_destroy");
+
+ function pthread_mutex_lock (mutex : access pthread_mutex_t) return int;
+ -- FSU_THREADS has nonstandard pthread_mutex_lock
+
+ function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int;
+ -- FSU_THREADS has nonstandard pthread_mutex_lock
+
+ function pthread_condattr_init
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_init, "pthread_condattr_init");
+
+ function pthread_condattr_destroy
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_destroy, "pthread_condattr_destroy");
+
+ function pthread_cond_init
+ (cond : access pthread_cond_t;
+ attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_cond_init, "pthread_cond_init");
+
+ function pthread_cond_destroy (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_destroy, "pthread_cond_destroy");
+
+ function pthread_cond_signal (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_signal, "pthread_cond_signal");
+
+ function pthread_cond_wait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t) return int;
+ -- FSU_THREADS has a nonstandard pthread_cond_wait
+
+ function pthread_cond_timedwait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ abstime : access timespec) return int;
+ -- FSU_THREADS has a nonstandard pthread_cond_timedwait
+
+ Relative_Timed_Wait : constant Boolean := False;
+ -- pthread_cond_timedwait requires an absolute delay time
+
+ --------------------------
+ -- POSIX.1c Section 13 --
+ --------------------------
+
+ PTHREAD_PRIO_NONE : constant := 0;
+ PTHREAD_PRIO_PROTECT : constant := 2;
+ PTHREAD_PRIO_INHERIT : constant := 1;
+
+ function pthread_mutexattr_setprotocol
+ (attr : access pthread_mutexattr_t;
+ protocol : int) return int;
+ pragma Import (C, pthread_mutexattr_setprotocol);
+
+ function pthread_mutexattr_setprioceiling
+ (attr : access pthread_mutexattr_t;
+ prioceiling : int) return int;
+ pragma Import
+ (C, pthread_mutexattr_setprioceiling,
+ "pthread_mutexattr_setprio_ceiling");
+
+ type struct_sched_param is record
+ sched_priority : int; -- scheduling priority
+ end record;
+
+ function pthread_setschedparam
+ (thread : pthread_t;
+ policy : int;
+ param : access struct_sched_param) return int;
+ -- FSU_THREADS does not have pthread_setschedparam
+
+ function pthread_attr_setscope
+ (attr : access pthread_attr_t;
+ contentionscope : int) return int;
+ pragma Import (C, pthread_attr_setscope, "pthread_attr_setscope");
+
+ function pthread_attr_setinheritsched
+ (attr : access pthread_attr_t;
+ inheritsched : int) return int;
+ pragma Import (C, pthread_attr_setinheritsched);
+
+ function pthread_attr_setschedpolicy
+ (attr : access pthread_attr_t;
+ policy : int) return int;
+ pragma Import (C, pthread_attr_setschedpolicy, "pthread_attr_setsched");
+
+ function sched_yield return int;
+ -- FSU_THREADS does not have sched_yield;
+
+ ---------------------------
+ -- P1003.1c - Section 16 --
+ ---------------------------
+
+ function pthread_attr_init (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_init, "pthread_attr_init");
+
+ function pthread_attr_destroy
+ (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_destroy, "pthread_attr_destroy");
+
+ function pthread_attr_setdetachstate
+ (attr : access pthread_attr_t;
+ detachstate : int) return int;
+ -- FSU_THREADS has a nonstandard pthread_attr_setdetachstate
+
+ function pthread_attr_setstacksize
+ (attr : access pthread_attr_t;
+ stacksize : size_t) return int;
+ pragma Import (C, pthread_attr_setstacksize);
+
+ function pthread_create
+ (thread : access pthread_t;
+ attributes : access pthread_attr_t;
+ start_routine : Thread_Body;
+ arg : System.Address) return int;
+ pragma Import (C, pthread_create, "pthread_create");
+
+ procedure pthread_exit (status : System.Address);
+ pragma Import (C, pthread_exit, "pthread_exit");
+
+ function pthread_self return pthread_t;
+ pragma Import (C, pthread_self, "pthread_self");
+
+ --------------------------
+ -- POSIX.1c Section 17 --
+ --------------------------
+
+ function pthread_setspecific
+ (key : pthread_key_t;
+ value : System.Address) return int;
+ pragma Import (C, pthread_setspecific, "pthread_setspecific");
+
+ function pthread_getspecific (key : pthread_key_t) return System.Address;
+ -- FSU_THREADS has a nonstandard pthread_getspecific
+
+ type destructor_pointer is access procedure (arg : System.Address);
+
+ function pthread_key_create
+ (key : access pthread_key_t;
+ destructor : destructor_pointer) return int;
+ pragma Import (C, pthread_key_create, "pthread_key_create");
+
+private
+
+ type sigset_t is record
+ losigs : unsigned_long;
+ hisigs : unsigned_long;
+ end record;
+ pragma Convention (C_Pass_By_Copy, sigset_t);
+
+ type pid_t is new int;
+
+ type time_t is new long;
+
+ type timespec is record
+ tv_sec : time_t;
+ tv_nsec : long;
+ end record;
+ pragma Convention (C, timespec);
+
+ type clockid_t is new int;
+ CLOCK_REALTIME : constant clockid_t := 0;
+
+ type struct_timeval is record
+ tv_sec : long;
+ tv_usec : long;
+ end record;
+ pragma Convention (C, struct_timeval);
+
+ type pthread_attr_t is record
+ flags : int;
+ stacksize : int;
+ contentionscope : int;
+ inheritsched : int;
+ detachstate : int;
+ sched : int;
+ prio : int;
+ starttime : timespec;
+ deadline : timespec;
+ period : timespec;
+ end record;
+ pragma Convention (C_Pass_By_Copy, pthread_attr_t);
+
+ type pthread_condattr_t is record
+ flags : int;
+ end record;
+ pragma Convention (C, pthread_condattr_t);
+
+ type pthread_mutexattr_t is record
+ flags : int;
+ prio_ceiling : int;
+ protocol : int;
+ end record;
+ pragma Convention (C, pthread_mutexattr_t);
+
+ type sigjmp_buf is array (Integer range 0 .. 63) of int;
+
+ type pthread_t_struct is record
+ context : sigjmp_buf;
+ pbody : sigjmp_buf;
+ errno : int;
+ ret : int;
+ stack_base : System.Address;
+ end record;
+ pragma Convention (C, pthread_t_struct);
+
+ type pthread_t is access all pthread_t_struct;
+
+ type queue_t is record
+ head : System.Address;
+ tail : System.Address;
+ end record;
+ pragma Convention (C, queue_t);
+
+ type pthread_mutex_t is record
+ queue : queue_t;
+ lock : plain_char;
+ owner : System.Address;
+ flags : int;
+ prio_ceiling : int;
+ protocol : int;
+ prev_max_ceiling_prio : int;
+ end record;
+ pragma Convention (C, pthread_mutex_t);
+
+ type pthread_cond_t is record
+ queue : queue_t;
+ flags : int;
+ waiters : int;
+ mutex : System.Address;
+ end record;
+ pragma Convention (C, pthread_cond_t);
+
+ type pthread_key_t is new int;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-aix.adb b/gcc/ada/s-osinte-aix.adb
new file mode 100644
index 00000000000..5fe86b1d606
--- /dev/null
+++ b/gcc/ada/s-osinte-aix.adb
@@ -0,0 +1,159 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1997-2002, Free Software Fundation, 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- --
+-- 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, 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, --
+-- 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 is a AIX (Native) version of this package
+
+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 Interfaces.C;
+
+package body System.OS_Interface is
+
+ use Interfaces.C;
+
+ -----------------
+ -- To_Duration --
+ -----------------
+
+ function To_Duration (TS : timespec) return Duration is
+ begin
+ return Duration (TS.tv_sec) + Duration (TS.tv_nsec) / 10#1#E9;
+ end To_Duration;
+
+ function To_Duration (TV : struct_timeval) return Duration is
+ begin
+ return Duration (TV.tv_sec) + Duration (TV.tv_usec) / 10#1#E6;
+ end To_Duration;
+
+ -----------------
+ -- To_Timespec --
+ -----------------
+
+ function To_Timespec (D : Duration) return timespec is
+ S : time_t;
+ F : Duration;
+
+ begin
+ S := time_t (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return timespec'(tv_sec => S,
+ tv_nsec => long (Long_Long_Integer (F * 10#1#E9)));
+ end To_Timespec;
+
+ ----------------
+ -- To_Timeval --
+ ----------------
+
+ function To_Timeval (D : Duration) return struct_timeval is
+ S : long;
+ F : Duration;
+
+ begin
+ S := long (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return
+ struct_timeval'
+ (tv_sec => S,
+ tv_usec => long (Long_Long_Integer (F * 10#1#E6)));
+ end To_Timeval;
+
+ -------------------
+ -- clock_gettime --
+ -------------------
+
+ function clock_gettime
+ (clock_id : clockid_t;
+ tp : access timespec)
+ return int
+ is
+ pragma Warnings (Off, clock_id);
+
+ Result : int;
+ tv : aliased struct_timeval;
+
+ function gettimeofday
+ (tv : access struct_timeval;
+ tz : System.Address := System.Null_Address)
+ return int;
+ pragma Import (C, gettimeofday, "gettimeofday");
+
+ begin
+ Result := gettimeofday (tv'Unchecked_Access);
+ tp.all := To_Timespec (To_Duration (tv));
+ return Result;
+ end clock_gettime;
+
+ -----------------
+ -- sched_yield --
+ -----------------
+
+ -- AIX Thread does not have sched_yield;
+
+ function sched_yield return int is
+
+ procedure pthread_yield;
+ pragma Import (C, pthread_yield, "sched_yield");
+
+ begin
+ pthread_yield;
+ return 0;
+ end sched_yield;
+
+ function Get_Stack_Base (thread : pthread_t) return Address is
+ pragma Warnings (Off, thread);
+
+ begin
+ return Null_Address;
+ end Get_Stack_Base;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-aix.ads b/gcc/ada/s-osinte-aix.ads
new file mode 100644
index 00000000000..c761eb8a048
--- /dev/null
+++ b/gcc/ada/s-osinte-aix.ads
@@ -0,0 +1,586 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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 is a AIX (Native THREADS) version of this package
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+with Interfaces.C;
+with Unchecked_Conversion;
+
+package System.OS_Interface is
+ pragma Preelaborate;
+
+ pragma Linker_Options ("-lpthreads");
+ pragma Linker_Options ("-lc_r");
+
+ subtype int is Interfaces.C.int;
+ subtype short is Interfaces.C.short;
+ subtype long is Interfaces.C.long;
+ subtype unsigned is Interfaces.C.unsigned;
+ subtype unsigned_short is Interfaces.C.unsigned_short;
+ subtype unsigned_long is Interfaces.C.unsigned_long;
+ subtype unsigned_char is Interfaces.C.unsigned_char;
+ subtype plain_char is Interfaces.C.plain_char;
+ subtype size_t is Interfaces.C.size_t;
+
+ -----------
+ -- Errno --
+ -----------
+
+ function errno return int;
+ pragma Import (C, errno, "__get_errno");
+
+ EAGAIN : constant := 11;
+ EINTR : constant := 4;
+ EINVAL : constant := 22;
+ ENOMEM : constant := 12;
+ ETIMEDOUT : constant := 78;
+
+ -------------
+ -- Signals --
+ -------------
+
+ Max_Interrupt : constant := 63;
+ type Signal is new int range 0 .. Max_Interrupt;
+ for Signal'Size use int'Size;
+
+ SIGHUP : constant := 1; -- hangup
+ SIGINT : constant := 2; -- interrupt (rubout)
+ SIGQUIT : constant := 3; -- quit (ASCD FS)
+ SIGILL : constant := 4; -- illegal instruction (not reset)
+ SIGTRAP : constant := 5; -- trace trap (not reset)
+ SIGIOT : constant := 6; -- IOT instruction
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGEMT : constant := 7; -- EMT instruction
+ SIGFPE : constant := 8; -- floating point exception
+ SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
+ SIGBUS : constant := 10; -- bus error
+ SIGSEGV : constant := 11; -- segmentation violation
+ SIGSYS : constant := 12; -- bad argument to system call
+ SIGPIPE : constant := 13; -- write on a pipe with no one to read it
+ SIGALRM : constant := 14; -- alarm clock
+ SIGTERM : constant := 15; -- software termination signal from kill
+ SIGUSR1 : constant := 30; -- user defined signal 1
+ SIGUSR2 : constant := 31; -- user defined signal 2
+ SIGCLD : constant := 20; -- alias for SIGCHLD
+ SIGCHLD : constant := 20; -- child status change
+ SIGPWR : constant := 29; -- power-fail restart
+ SIGWINCH : constant := 28; -- window size change
+ SIGURG : constant := 16; -- urgent condition on IO channel
+ SIGPOLL : constant := 23; -- pollable event occurred
+ SIGIO : constant := 23; -- I/O possible (Solaris SIGPOLL alias)
+ SIGSTOP : constant := 17; -- stop (cannot be caught or ignored)
+ SIGTSTP : constant := 18; -- user stop requested from tty
+ SIGCONT : constant := 19; -- stopped process has been continued
+ SIGTTIN : constant := 21; -- background tty read attempted
+ SIGTTOU : constant := 22; -- background tty write attempted
+ SIGVTALRM : constant := 34; -- virtual timer expired
+ SIGPROF : constant := 32; -- profiling timer expired
+ SIGXCPU : constant := 24; -- CPU time limit exceeded
+ SIGXFSZ : constant := 25; -- filesize limit exceeded
+ SIGWAITING : constant := 39; -- m:n scheduling
+
+ -- the following signals are AIX specific
+ SIGMSG : constant := 27; -- input data is in the ring buffer
+ SIGDANGER : constant := 33; -- system crash imminent
+ SIGMIGRATE : constant := 35; -- migrate process
+ SIGPRE : constant := 36; -- programming exception
+ SIGVIRT : constant := 37; -- AIX virtual time alarm
+ SIGALRM1 : constant := 38; -- m:n condition variables
+ SIGKAP : constant := 60; -- keep alive poll from native keyboard
+ SIGGRANT : constant := SIGKAP; -- monitor mode granted
+ SIGRETRACT : constant := 61; -- monitor mode should be relinguished
+ SIGSOUND : constant := 62; -- sound control has completed
+ SIGSAK : constant := 63; -- secure attention key
+
+ SIGADAABORT : constant := SIGTERM;
+ -- Note: on other targets, we usually use SIGABRT, but on AiX, it
+ -- appears that SIGABRT can't be used in sigwait(), so we use SIGTERM.
+
+ type Signal_Set is array (Natural range <>) of Signal;
+
+ Unmasked : constant Signal_Set :=
+ (SIGTRAP, SIGTTIN, SIGTTOU, SIGTSTP, SIGPROF);
+ Reserved : constant Signal_Set := (SIGABRT, SIGKILL, SIGSTOP);
+
+ type sigset_t is private;
+
+ function sigaddset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigaddset, "sigaddset");
+
+ function sigdelset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigdelset, "sigdelset");
+
+ function sigfillset (set : access sigset_t) return int;
+ pragma Import (C, sigfillset, "sigfillset");
+
+ function sigismember (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigismember, "sigismember");
+
+ function sigemptyset (set : access sigset_t) return int;
+ pragma Import (C, sigemptyset, "sigemptyset");
+
+ type struct_sigaction is record
+ sa_handler : System.Address;
+ sa_mask : sigset_t;
+ sa_flags : int;
+ end record;
+ pragma Convention (C, struct_sigaction);
+ type struct_sigaction_ptr is access all struct_sigaction;
+
+ SA_SIGINFO : constant := 16#0100#;
+
+ SIG_BLOCK : constant := 0;
+ SIG_UNBLOCK : constant := 1;
+ SIG_SETMASK : constant := 2;
+
+ SIG_DFL : constant := 0;
+ SIG_IGN : constant := 1;
+
+ function sigaction
+ (sig : Signal;
+ act : struct_sigaction_ptr;
+ oact : struct_sigaction_ptr) return int;
+ pragma Import (C, sigaction, "sigaction");
+
+ ----------
+ -- Time --
+ ----------
+
+ Time_Slice_Supported : constant Boolean := False;
+ -- Indicates wether time slicing is supported
+
+ type timespec is private;
+
+ type clockid_t is private;
+
+ CLOCK_REALTIME : constant clockid_t;
+
+ function clock_gettime
+ (clock_id : clockid_t;
+ tp : access timespec) return int;
+ -- AiX threads don't have clock_gettime
+ -- We instead use gettimeofday()
+
+ function To_Duration (TS : timespec) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timespec (D : Duration) return timespec;
+ pragma Inline (To_Timespec);
+
+ type struct_timezone is record
+ tz_minuteswest : int;
+ tz_dsttime : int;
+ end record;
+ pragma Convention (C, struct_timezone);
+ type struct_timezone_ptr is access all struct_timezone;
+
+ type struct_timeval is private;
+ -- This is needed on systems that do not have clock_gettime()
+ -- but do have gettimeofday().
+
+ function To_Duration (TV : struct_timeval) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timeval (D : Duration) return struct_timeval;
+ pragma Inline (To_Timeval);
+
+ -------------------------
+ -- Priority Scheduling --
+ -------------------------
+
+ SCHED_FIFO : constant := 1;
+ SCHED_RR : constant := 2;
+ SCHED_OTHER : constant := 0;
+
+ -------------
+ -- Process --
+ -------------
+
+ type pid_t is private;
+
+ function kill (pid : pid_t; sig : Signal) return int;
+ pragma Import (C, kill, "kill");
+
+ function getpid return pid_t;
+ pragma Import (C, getpid, "getpid");
+
+ ---------
+ -- LWP --
+ ---------
+
+ function lwp_self return System.Address;
+ pragma Import (C, lwp_self, "thread_self");
+
+ -------------
+ -- Threads --
+ -------------
+
+ type Thread_Body is access
+ function (arg : System.Address) return System.Address;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ type pthread_t is private;
+ subtype Thread_Id is pthread_t;
+
+ type pthread_mutex_t is limited private;
+ type pthread_cond_t is limited private;
+ type pthread_attr_t is limited private;
+ type pthread_mutexattr_t is limited private;
+ type pthread_condattr_t is limited private;
+ type pthread_key_t is private;
+
+ PTHREAD_CREATE_DETACHED : constant := 1;
+
+ -----------
+ -- Stack --
+ -----------
+
+ Stack_Base_Available : constant Boolean := False;
+ -- Indicates wether the stack base is available on this target.
+
+ function Get_Stack_Base (thread : pthread_t) return Address;
+ pragma Inline (Get_Stack_Base);
+ -- returns the stack base of the specified thread.
+ -- Only call this function when Stack_Base_Available is True.
+
+ 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
+
+ PROT_NONE : constant := 0;
+ PROT_READ : constant := 1;
+ PROT_WRITE : constant := 2;
+ PROT_EXEC : constant := 4;
+ PROT_ALL : constant := PROT_READ + PROT_WRITE + PROT_EXEC;
+
+ PROT_ON : constant := PROT_READ;
+ PROT_OFF : constant := PROT_ALL;
+
+ function mprotect (addr : Address; len : size_t; prot : int) return int;
+ pragma Import (C, mprotect);
+
+ ---------------------------------------
+ -- Nonstandard Thread Initialization --
+ ---------------------------------------
+
+ -- Though not documented, pthread_init *must* be called before any other
+ -- pthread call
+
+ procedure pthread_init;
+ pragma Import (C, pthread_init, "pthread_init");
+
+ -------------------------
+ -- POSIX.1c Section 3 --
+ -------------------------
+
+ function sigwait
+ (set : access sigset_t;
+ sig : access Signal) return int;
+ pragma Import (C, sigwait, "sigwait");
+
+ function pthread_kill
+ (thread : pthread_t;
+ sig : Signal) return int;
+ pragma Import (C, pthread_kill, "pthread_kill");
+
+ type sigset_t_ptr is access all sigset_t;
+
+ function pthread_sigmask
+ (how : int;
+ set : sigset_t_ptr;
+ oset : sigset_t_ptr) return int;
+ pragma Import (C, pthread_sigmask, "sigthreadmask");
+
+ --------------------------
+ -- POSIX.1c Section 11 --
+ --------------------------
+
+ function pthread_mutexattr_init
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_init, "pthread_mutexattr_init");
+
+ function pthread_mutexattr_destroy
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_destroy, "pthread_mutexattr_destroy");
+
+ function pthread_mutex_init
+ (mutex : access pthread_mutex_t;
+ attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutex_init, "pthread_mutex_init");
+
+ function pthread_mutex_destroy (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_destroy, "pthread_mutex_destroy");
+
+ function pthread_mutex_lock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_lock, "pthread_mutex_lock");
+
+ function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_unlock, "pthread_mutex_unlock");
+
+ function pthread_condattr_init
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_init, "pthread_condattr_init");
+
+ function pthread_condattr_destroy
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_destroy, "pthread_condattr_destroy");
+
+ function pthread_cond_init
+ (cond : access pthread_cond_t;
+ attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_cond_init, "pthread_cond_init");
+
+ function pthread_cond_destroy (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_destroy, "pthread_cond_destroy");
+
+ function pthread_cond_signal (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_signal, "pthread_cond_signal");
+
+ function pthread_cond_wait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_cond_wait, "pthread_cond_wait");
+
+ function pthread_cond_timedwait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ abstime : access timespec) return int;
+ pragma Import (C, pthread_cond_timedwait, "pthread_cond_timedwait");
+
+ Relative_Timed_Wait : constant Boolean := False;
+ -- pthread_cond_timedwait requires an absolute delay time
+
+ ----------------------------
+ -- POSIX.1c Section 13 --
+ ----------------------------
+
+ PTHREAD_PRIO_NONE : constant := 0;
+ PTHREAD_PRIO_PROTECT : constant := 0;
+ PTHREAD_PRIO_INHERIT : constant := 0;
+
+ function pthread_mutexattr_setprotocol
+ (attr : access pthread_mutexattr_t;
+ protocol : int) return int;
+ pragma Import (C, pthread_mutexattr_setprotocol);
+
+ function pthread_mutexattr_setprioceiling
+ (attr : access pthread_mutexattr_t;
+ prioceiling : int) return int;
+ pragma Import (C, pthread_mutexattr_setprioceiling);
+
+ type Array_5_Int is array (0 .. 5) of int;
+ type struct_sched_param is record
+ sched_priority : int;
+ sched_policy : int;
+ sched_reserved : Array_5_Int;
+ end record;
+
+ function pthread_setschedparam
+ (thread : pthread_t;
+ policy : int;
+ param : access struct_sched_param) return int;
+ pragma Import (C, pthread_setschedparam, "pthread_setschedparam");
+
+ function pthread_attr_setscope
+ (attr : access pthread_attr_t;
+ contentionscope : int) return int;
+ pragma Import (C, pthread_attr_setscope, "pthread_attr_setscope");
+
+ function pthread_attr_setinheritsched
+ (attr : access pthread_attr_t;
+ inheritsched : int) return int;
+ pragma Import (C, pthread_attr_setinheritsched);
+
+ function pthread_attr_setschedpolicy
+ (attr : access pthread_attr_t;
+ policy : int) return int;
+ pragma Import (C, pthread_attr_setschedpolicy);
+
+ function pthread_attr_setschedparam
+ (attr : access pthread_attr_t;
+ sched_param : int) return int;
+ pragma Import (C, pthread_attr_setschedparam);
+
+ function sched_yield return int;
+ -- AiX have a nonstandard sched_yield.
+
+ ---------------------------
+ -- P1003.1c - Section 16 --
+ ---------------------------
+
+ function pthread_attr_init (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_init, "pthread_attr_init");
+
+ function pthread_attr_destroy
+ (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_destroy, "pthread_attr_destroy");
+
+ function pthread_attr_setdetachstate
+ (attr : access pthread_attr_t;
+ detachstate : int) return int;
+ pragma Import (C, pthread_attr_setdetachstate);
+
+ function pthread_attr_setstacksize
+ (attr : access pthread_attr_t;
+ stacksize : size_t) return int;
+ pragma Import (C, pthread_attr_setstacksize);
+
+ function pthread_create
+ (thread : access pthread_t;
+ attributes : access pthread_attr_t;
+ start_routine : Thread_Body;
+ arg : System.Address)
+ return int;
+ pragma Import (C, pthread_create, "pthread_create");
+
+ procedure pthread_exit (status : System.Address);
+ pragma Import (C, pthread_exit, "pthread_exit");
+
+ function pthread_self return pthread_t;
+ pragma Import (C, pthread_self, "pthread_self");
+
+ --------------------------
+ -- POSIX.1c Section 17 --
+ --------------------------
+
+ function pthread_setspecific
+ (key : pthread_key_t;
+ value : System.Address) return int;
+ pragma Import (C, pthread_setspecific, "pthread_setspecific");
+
+ function pthread_getspecific (key : pthread_key_t) return System.Address;
+ pragma Import (C, pthread_getspecific, "pthread_getspecific");
+
+ type destructor_pointer is access
+ procedure (arg : System.Address);
+
+ function pthread_key_create
+ (key : access pthread_key_t;
+ destructor : destructor_pointer) return int;
+ pragma Import (C, pthread_key_create, "pthread_key_create");
+
+private
+
+ type sigset_t is record
+ losigs : unsigned_long;
+ hisigs : unsigned_long;
+ end record;
+ pragma Convention (C_Pass_By_Copy, sigset_t);
+
+ type pid_t is new int;
+
+ type time_t is new long;
+
+ type timespec is record
+ tv_sec : time_t;
+ tv_nsec : long;
+ end record;
+ pragma Convention (C, timespec);
+
+ type clockid_t is new int;
+ CLOCK_REALTIME : constant clockid_t := 0;
+
+ type struct_timeval is record
+ tv_sec : long;
+ tv_usec : long;
+ end record;
+ pragma Convention (C, struct_timeval);
+
+ type pthread_attr_t is new System.Address;
+ pragma Convention (C, pthread_attr_t);
+ -- typedef struct __pt_attr *pthread_attr_t;
+
+ type pthread_condattr_t is new System.Address;
+ pragma Convention (C, pthread_condattr_t);
+ -- typedef struct __pt_attr *pthread_condattr_t;
+
+ type pthread_mutexattr_t is new System.Address;
+ pragma Convention (C, pthread_mutexattr_t);
+ -- typedef struct __pt_attr *pthread_mutexattr_t;
+
+ type pthread_t is new System.Address;
+ pragma Convention (C, pthread_t);
+ -- typedef void *pthread_t;
+
+ type ptq_queue;
+ type ptq_queue_ptr is access all ptq_queue;
+
+ type ptq_queue is record
+ ptq_next : ptq_queue_ptr;
+ ptq_prev : ptq_queue_ptr;
+ end record;
+
+ type Array_3_Int is array (0 .. 3) of int;
+ type pthread_mutex_t is record
+ link : ptq_queue;
+ ptmtx_lock : int;
+ ptmtx_flags : long;
+ protocol : int;
+ prioceiling : int;
+ ptmtx_owner : pthread_t;
+ mtx_id : int;
+ attr : pthread_attr_t;
+ mtx_kind : int;
+ lock_cpt : int;
+ reserved : Array_3_Int;
+ end record;
+ pragma Convention (C, pthread_mutex_t);
+ type pthread_mutex_t_ptr is access pthread_mutex_t;
+
+ type pthread_cond_t is record
+ link : ptq_queue;
+ ptcv_lock : int;
+ ptcv_flags : long;
+ ptcv_waiters : ptq_queue;
+ cv_id : int;
+ attr : pthread_attr_t;
+ mutex : pthread_mutex_t_ptr;
+ cptwait : int;
+ reserved : int;
+ end record;
+ pragma Convention (C, pthread_cond_t);
+
+ type pthread_key_t is new unsigned;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-darwin.adb b/gcc/ada/s-osinte-darwin.adb
new file mode 100644
index 00000000000..004648fb88e
--- /dev/null
+++ b/gcc/ada/s-osinte-darwin.adb
@@ -0,0 +1,163 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1999-2004 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- --
+-- 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, 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, --
+-- 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 is a Darwin Threads version of this package
+
+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 Interfaces.C;
+
+package body System.OS_Interface is
+
+ use Interfaces.C;
+
+ -----------------
+ -- To_Duration --
+ -----------------
+
+ function To_Duration (TS : timespec) return Duration is
+ begin
+ return Duration (TS.tv_sec) + Duration (TS.tv_nsec) / 10#1#E9;
+ end To_Duration;
+
+ function To_Duration (TV : struct_timeval) return Duration is
+ begin
+ return Duration (TV.tv_sec) + Duration (TV.tv_usec) / 10#1#E6;
+ end To_Duration;
+
+ -----------------
+ -- To_Timespec --
+ -----------------
+
+ function To_Timespec (D : Duration) return timespec is
+ S : time_t;
+ F : Duration;
+
+ begin
+ S := time_t (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return timespec'(tv_sec => S,
+ tv_nsec => long (Long_Long_Integer (F * 10#1#E9)));
+ end To_Timespec;
+
+ ----------------
+ -- To_Timeval --
+ ----------------
+
+ function To_Timeval (D : Duration) return struct_timeval is
+ S : long;
+ F : Duration;
+
+ begin
+ S := long (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return struct_timeval'(tv_sec => S,
+ tv_usec => long (Long_Long_Integer (F * 10#1#E6)));
+ end To_Timeval;
+
+ -------------------
+ -- clock_gettime --
+ -------------------
+
+ function clock_gettime
+ (clock_id : clockid_t;
+ tp : access timespec) return int
+ is
+ pragma Unreferenced (clock_id);
+ Result : int;
+ tv : aliased struct_timeval;
+
+ function gettimeofday
+ (tv : access struct_timeval;
+ tz : System.Address := System.Null_Address) return int;
+ pragma Import (C, gettimeofday, "gettimeofday");
+
+ begin
+ Result := gettimeofday (tv'Unchecked_Access);
+ tp.all := To_Timespec (To_Duration (tv));
+ return Result;
+ end clock_gettime;
+
+ -----------------
+ -- sched_yield --
+ -----------------
+
+ function sched_yield return int is
+ procedure sched_yield_base (arg : System.Address);
+ pragma Import (C, sched_yield_base, "pthread_yield_np");
+
+ begin
+ sched_yield_base (System.Null_Address);
+ return 0;
+ end sched_yield;
+
+ ------------------
+ -- pthread_init --
+ ------------------
+
+ procedure pthread_init is
+ begin
+ null;
+ end pthread_init;
+
+ ----------------
+ -- Stack_Base --
+ ----------------
+
+ function Get_Stack_Base (thread : pthread_t) return Address is
+ pragma Unreferenced (thread);
+ begin
+ return System.Null_Address;
+ end Get_Stack_Base;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-darwin.ads b/gcc/ada/s-osinte-darwin.ads
new file mode 100644
index 00000000000..eccc26ef6f2
--- /dev/null
+++ b/gcc/ada/s-osinte-darwin.ads
@@ -0,0 +1,641 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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 is Darwin pthreads version of this package.
+
+-- This package includes all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- PLEASE DO NOT add any with-clauses to this package
+-- or remove the pragma Elaborate_Body.
+-- It is designed to be a bottom-level (leaf) package.
+
+with Interfaces.C;
+package System.OS_Interface is
+ pragma Preelaborate;
+
+ subtype int is Interfaces.C.int;
+ subtype short is Interfaces.C.short;
+ subtype long is Interfaces.C.long;
+ subtype unsigned is Interfaces.C.unsigned;
+ subtype unsigned_short is Interfaces.C.unsigned_short;
+ subtype unsigned_long is Interfaces.C.unsigned_long;
+ subtype unsigned_char is Interfaces.C.unsigned_char;
+ subtype plain_char is Interfaces.C.plain_char;
+ subtype size_t is Interfaces.C.size_t;
+
+ -----------
+ -- Errno --
+ -----------
+
+ function errno return int;
+ pragma Import (C, errno, "__get_errno");
+
+ EINTR : constant := 4;
+ ENOMEM : constant := 12;
+ EINVAL : constant := 22;
+ EAGAIN : constant := 35;
+ ETIMEDOUT : constant := 60;
+
+ -------------
+ -- Signals --
+ -------------
+
+ Max_Interrupt : constant := 31;
+ type Signal is new int range 0 .. Max_Interrupt;
+ for Signal'Size use int'Size;
+
+ SIGHUP : constant := 1; -- hangup
+ SIGINT : constant := 2; -- interrupt (rubout)
+ SIGQUIT : constant := 3; -- quit (ASCD FS)
+ SIGILL : constant := 4; -- illegal instruction (not reset)
+ SIGTRAP : constant := 5; -- trace trap (not reset)
+ SIGIOT : constant := 6; -- IOT instruction
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGEMT : constant := 7; -- EMT instruction
+ SIGFPE : constant := 8; -- floating point exception
+ SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
+ SIGBUS : constant := 10; -- bus error
+ SIGSEGV : constant := 11; -- segmentation violation
+ SIGSYS : constant := 12; -- bad argument to system call
+ SIGPIPE : constant := 13; -- write on a pipe with no one to read it
+ SIGALRM : constant := 14; -- alarm clock
+ SIGTERM : constant := 15; -- software termination signal from kill
+ SIGURG : constant := 16; -- urgent condition on IO channel
+ SIGSTOP : constant := 17; -- stop (cannot be caught or ignored)
+ SIGTSTP : constant := 18; -- user stop requested from tty
+ SIGCONT : constant := 19; -- stopped process has been continued
+ SIGCHLD : constant := 20; -- child status change
+ SIGTTIN : constant := 21; -- background tty read attempted
+ SIGTTOU : constant := 22; -- background tty write attempted
+ SIGIO : constant := 23; -- I/O possible (Solaris SIGPOLL alias)
+ SIGXCPU : constant := 24; -- CPU time limit exceeded
+ SIGXFSZ : constant := 25; -- filesize limit exceeded
+ SIGVTALRM : constant := 26; -- virtual timer expired
+ SIGPROF : constant := 27; -- profiling timer expired
+ SIGWINCH : constant := 28; -- window size change
+ SIGINFO : constant := 29; -- information request
+ SIGUSR1 : constant := 30; -- user defined signal 1
+ SIGUSR2 : constant := 31; -- user defined signal 2
+
+ SIGADAABORT : constant := SIGABRT;
+ -- Change this if you want to use another signal for task abort.
+ -- SIGTERM might be a good one.
+
+ type Signal_Set is array (Natural range <>) of Signal;
+
+ Unmasked : constant Signal_Set :=
+ (SIGTTIN, SIGTTOU, SIGSTOP, SIGTSTP);
+
+ Reserved : constant Signal_Set :=
+ (SIGKILL, SIGSTOP);
+
+ type sigset_t is private;
+
+ function sigaddset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigaddset, "sigaddset");
+
+ function sigdelset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigdelset, "sigdelset");
+
+ function sigfillset (set : access sigset_t) return int;
+ pragma Import (C, sigfillset, "sigfillset");
+
+ function sigismember (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigismember, "sigismember");
+
+ function sigemptyset (set : access sigset_t) return int;
+ pragma Import (C, sigemptyset, "sigemptyset");
+
+ type siginfo_t is private;
+ type ucontext_t is private;
+
+ type Signal_Handler is access procedure
+ (signo : Signal;
+ info : access siginfo_t;
+ context : access ucontext_t);
+
+ type struct_sigaction is record
+ sa_handler : System.Address;
+ sa_mask : sigset_t;
+ sa_flags : int;
+ end record;
+ pragma Convention (C, struct_sigaction);
+ type struct_sigaction_ptr is access all struct_sigaction;
+
+ SIG_BLOCK : constant := 1;
+ SIG_UNBLOCK : constant := 2;
+ SIG_SETMASK : constant := 3;
+
+ SIG_DFL : constant := 0;
+ SIG_IGN : constant := 1;
+
+ SA_SIGINFO : constant := 16#0040#;
+
+ function sigaction
+ (sig : Signal;
+ act : struct_sigaction_ptr;
+ oact : struct_sigaction_ptr) return int;
+ pragma Import (C, sigaction, "sigaction");
+
+ ----------
+ -- Time --
+ ----------
+
+ Time_Slice_Supported : constant Boolean := True;
+ -- Indicates wether time slicing is supported.
+
+ type timespec is private;
+
+ type clockid_t is private;
+
+ CLOCK_REALTIME : constant clockid_t;
+
+ function clock_gettime
+ (clock_id : clockid_t;
+ tp : access timespec) return int;
+
+ function To_Duration (TS : timespec) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timespec (D : Duration) return timespec;
+ pragma Inline (To_Timespec);
+
+ type struct_timeval is private;
+
+ function To_Duration (TV : struct_timeval) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timeval (D : Duration) return struct_timeval;
+ pragma Inline (To_Timeval);
+
+ -------------------------
+ -- Priority Scheduling --
+ -------------------------
+
+ SCHED_OTHER : constant := 1;
+ SCHED_RR : constant := 2;
+ SCHED_FIFO : constant := 4;
+
+ -------------
+ -- Process --
+ -------------
+
+ type pid_t is private;
+
+ function kill (pid : pid_t; sig : Signal) return int;
+ pragma Import (C, kill, "kill");
+
+ function getpid return pid_t;
+ pragma Import (C, getpid, "getpid");
+
+ ---------
+ -- LWP --
+ ---------
+
+ function lwp_self return System.Address;
+ -- lwp_self does not exist on this thread library, revert to pthread_self
+ -- which is the closest approximation (with getpid). This function is
+ -- needed to share 7staprop.adb across POSIX-like targets.
+ pragma Import (C, lwp_self, "pthread_self");
+
+ -------------
+ -- Threads --
+ -------------
+
+ type Thread_Body is access
+ function (arg : System.Address) return System.Address;
+ type pthread_t is private;
+ subtype Thread_Id is pthread_t;
+
+ type pthread_mutex_t is limited private;
+ type pthread_cond_t is limited private;
+ type pthread_attr_t is limited private;
+ type pthread_mutexattr_t is limited private;
+ type pthread_condattr_t is limited private;
+ type pthread_key_t is private;
+
+ type pthread_mutex_ptr is access all pthread_mutex_t;
+ type pthread_cond_ptr is access all pthread_cond_t;
+
+ PTHREAD_CREATE_DETACHED : constant := 2;
+
+ -----------
+ -- Stack --
+ -----------
+
+ Stack_Base_Available : constant Boolean := False;
+ -- Indicates wether the stack base is available on this target.
+ -- This allows us to share s-osinte.adb between all the FSU run time.
+ -- Note that this value can only be true if pthread_t has a complete
+ -- definition that corresponds exactly to the C header files.
+
+ function Get_Stack_Base (thread : pthread_t) return System.Address;
+ pragma Inline (Get_Stack_Base);
+ -- returns the stack base of the specified thread.
+ -- Only call this function when Stack_Base_Available is True.
+
+ 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
+
+ PROT_NONE : constant := 0;
+ PROT_READ : constant := 1;
+ PROT_WRITE : constant := 2;
+ PROT_EXEC : constant := 4;
+ PROT_ALL : constant := PROT_READ + PROT_WRITE + PROT_EXEC;
+
+ PROT_ON : constant := PROT_NONE;
+ PROT_OFF : constant := PROT_ALL;
+
+ function mprotect (addr : System.Address;
+ len : size_t;
+ prot : int) return int;
+ pragma Import (C, mprotect);
+
+ ---------------------------------------
+ -- Nonstandard Thread Initialization --
+ ---------------------------------------
+
+ procedure pthread_init;
+
+ -------------------------
+ -- POSIX.1c Section 3 --
+ -------------------------
+
+ function sigwait (set : access sigset_t; sig : access Signal) return int;
+ pragma Import (C, sigwait, "sigwait");
+
+ function pthread_kill (thread : pthread_t; sig : Signal) return int;
+ pragma Import (C, pthread_kill, "pthread_kill");
+
+ type sigset_t_ptr is access all sigset_t;
+
+ function pthread_sigmask
+ (how : int;
+ set : sigset_t_ptr;
+ oset : sigset_t_ptr) return int;
+ pragma Import (C, pthread_sigmask, "sigprocmask");
+
+ --------------------------
+ -- POSIX.1c Section 11 --
+ --------------------------
+
+ function pthread_mutexattr_init
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_init, "pthread_mutexattr_init");
+
+ function pthread_mutexattr_destroy
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_destroy, "pthread_mutexattr_destroy");
+
+ function pthread_mutex_init
+ (mutex : access pthread_mutex_t;
+ attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutex_init, "pthread_mutex_init");
+
+ function pthread_mutex_destroy (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_destroy, "pthread_mutex_destroy");
+
+ function pthread_mutex_lock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_lock, "pthread_mutex_lock");
+
+ function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_unlock, "pthread_mutex_unlock");
+
+ function pthread_condattr_init
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_init, "pthread_condattr_init");
+
+ function pthread_condattr_destroy
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_destroy, "pthread_condattr_destroy");
+
+ function pthread_cond_init
+ (cond : access pthread_cond_t;
+ attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_cond_init, "pthread_cond_init");
+
+ function pthread_cond_destroy (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_destroy, "pthread_cond_destroy");
+
+ function pthread_cond_signal (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_signal, "pthread_cond_signal");
+
+ function pthread_cond_wait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_cond_wait, "pthread_cond_wait");
+
+ function pthread_cond_timedwait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ abstime : access timespec) return int;
+ pragma Import (C, pthread_cond_timedwait, "pthread_cond_timedwait");
+
+ Relative_Timed_Wait : constant Boolean := False;
+ -- pthread_cond_timedwait requires an absolute delay time
+
+ --------------------------
+ -- POSIX.1c Section 13 --
+ --------------------------
+
+ PTHREAD_PRIO_NONE : constant := 0;
+ PTHREAD_PRIO_INHERIT : constant := 1;
+ PTHREAD_PRIO_PROTECT : constant := 2;
+
+ function pthread_mutexattr_setprotocol
+ (attr : access pthread_mutexattr_t;
+ protocol : int) return int;
+ pragma Import
+ (C, pthread_mutexattr_setprotocol, "pthread_mutexattr_setprotocol");
+
+ function pthread_mutexattr_setprioceiling
+ (attr : access pthread_mutexattr_t;
+ prioceiling : int) return int;
+ pragma Import
+ (C, pthread_mutexattr_setprioceiling,
+ "pthread_mutexattr_setprioceiling");
+
+ type struct_sched_param is record
+ sched_priority : int; -- scheduling priority
+ end record;
+
+ function pthread_setschedparam
+ (thread : pthread_t;
+ policy : int;
+ param : access struct_sched_param) return int;
+ pragma Import (C, pthread_setschedparam, "pthread_setschedparam");
+
+ function pthread_attr_setscope
+ (attr : access pthread_attr_t;
+ contentionscope : int) return int;
+ pragma Import (C, pthread_attr_setscope, "pthread_attr_setscope");
+
+ function pthread_attr_setinheritsched
+ (attr : access pthread_attr_t;
+ inheritsched : int) return int;
+ pragma Import
+ (C, pthread_attr_setinheritsched, "pthread_attr_setinheritsched");
+
+ function pthread_attr_setschedpolicy
+ (attr : access pthread_attr_t;
+ policy : int) return int;
+ pragma Import (C, pthread_attr_setschedpolicy, "pthread_attr_setsched");
+
+ function sched_yield return int;
+
+ ---------------------------
+ -- P1003.1c - Section 16 --
+ ---------------------------
+
+ function pthread_attr_init (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_init, "pthread_attr_init");
+
+ function pthread_attr_destroy
+ (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_destroy, "pthread_attr_destroy");
+
+ function pthread_attr_setdetachstate
+ (attr : access pthread_attr_t;
+ detachstate : int) return int;
+ pragma Import
+ (C, pthread_attr_setdetachstate, "pthread_attr_setdetachstate");
+
+ function pthread_attr_setstacksize
+ (attr : access pthread_attr_t;
+ stacksize : size_t) return int;
+ pragma Import
+ (C, pthread_attr_setstacksize, "pthread_attr_setstacksize");
+
+ function pthread_create
+ (thread : access pthread_t;
+ attributes : access pthread_attr_t;
+ start_routine : Thread_Body;
+ arg : System.Address) return int;
+ pragma Import (C, pthread_create, "pthread_create");
+
+ procedure pthread_exit (status : System.Address);
+ pragma Import (C, pthread_exit, "pthread_exit");
+
+ function pthread_self return pthread_t;
+ pragma Import (C, pthread_self, "pthread_self");
+
+ --------------------------
+ -- POSIX.1c Section 17 --
+ --------------------------
+
+ function pthread_setspecific
+ (key : pthread_key_t;
+ value : System.Address) return int;
+ pragma Import (C, pthread_setspecific, "pthread_setspecific");
+
+ function pthread_getspecific (key : pthread_key_t) return System.Address;
+ pragma Import (C, pthread_getspecific, "pthread_getspecific");
+
+ type destructor_pointer is access procedure (arg : System.Address);
+
+ function pthread_key_create
+ (key : access pthread_key_t;
+ destructor : destructor_pointer) return int;
+ pragma Import (C, pthread_key_create, "pthread_key_create");
+
+private
+
+ type array_type_1 is array (Integer range 0 .. 3) of unsigned_long;
+ type sigset_t is record
+ X_X_sigbits : array_type_1;
+ end record;
+ pragma Convention (C, sigset_t);
+
+ type pid_t is new long;
+
+ type time_t is new long;
+
+ type timespec is record
+ tv_sec : time_t;
+ tv_nsec : long;
+ end record;
+ pragma Convention (C, timespec);
+
+ type clockid_t is new int;
+ CLOCK_REALTIME : constant clockid_t := 0;
+
+ type struct_timeval is record
+ tv_sec : long;
+ tv_usec : long;
+ end record;
+ pragma Convention (C, struct_timeval);
+
+ --
+ -- Darwin specific signal implementation
+ --
+ type Pad_Type is array (0 .. 7) of int;
+ type siginfo_t is record
+ si_signo : int; -- signal number
+ si_errno : int; -- errno association
+ si_code : int; -- signal code
+ si_pid : int; -- sending process
+ si_uid : unsigned; -- sender's ruid
+ si_status : int; -- exit value
+ si_addr : System.Address; -- faulting instruction
+ si_value : System.Address; -- signal value
+ si_band : long; -- band event for SIGPOLL
+ pad : Pad_Type; -- RFU
+ end record;
+ pragma Convention (C, siginfo_t);
+
+ type stack_t is record
+ ss_sp : System.Address;
+ ss_size : int;
+ ss_flags : int;
+ end record;
+ pragma Convention (C, stack_t);
+
+ type mcontext_t is new System.Address;
+
+ type ucontext_t is record
+ uc_onstack : int;
+ uc_sigmask : sigset_t; -- Signal Mask Used By This Context
+ uc_stack : stack_t; -- Stack Used By This Context
+ uc_link : System.Address; -- Pointer To Resuming Context
+ uc_mcsize : size_t; -- Size of The Machine Context
+ uc_mcontext : mcontext_t; -- Machine Specific Context
+ end record;
+ pragma Convention (C, ucontext_t);
+
+ --
+ -- Darwin specific pthread implementation
+ --
+ type pthread_t is new System.Address;
+
+ type pthread_lock_t is new long;
+
+ type sched_param_pad is array (0 .. 3) of plain_char;
+ type sched_param is record
+ sched_priority : int;
+ opaque : sched_param_pad;
+ end record;
+ pragma Convention (C, sched_param);
+ type boolean_t is new int;
+
+ type pthread_attr_t is record
+ sig : long;
+ lock : pthread_lock_t;
+ detached : int;
+ inherit : int;
+ policy : int;
+ param : sched_param;
+ stackaddr : System.Address;
+ stacksize : long;
+ freeStackOnExit : boolean_t;
+ end record;
+ pragma Convention (C, pthread_attr_t);
+
+ type pthread_mutexattr_t is record
+ sig : long;
+ prioceiling : int;
+ protocol : int;
+ end record;
+ pragma Convention (C, pthread_mutexattr_t);
+
+ type mach_port_t is new unsigned_long;
+
+ type pthread_mutex_t is record
+ sig : long;
+ lock : pthread_lock_t;
+ prioceiling : int;
+ priority : int;
+ protocol : int;
+ owner : pthread_t;
+ next : pthread_mutex_ptr;
+ prev : pthread_mutex_ptr;
+ busy : pthread_cond_ptr;
+ field : int;
+ sem : mach_port_t;
+ end record;
+ pragma Convention (C, pthread_mutex_t);
+
+ type pthread_condattr_t is record
+ sig : long;
+ unsupported : int;
+ end record;
+ pragma Convention (C, pthread_condattr_t);
+
+ type pthread_cond_t is record
+ sig : long;
+ lock : pthread_lock_t;
+ sem : mach_port_t;
+ next : pthread_cond_ptr;
+ prev : pthread_cond_ptr;
+ busy : pthread_mutex_ptr;
+ waiters : short;
+ sigspending : short;
+ end record;
+ pragma Convention (C, pthread_cond_t);
+
+ type pthread_once_t is record
+ sig : long;
+ lock : pthread_lock_t;
+ end record;
+ pragma Convention (C, pthread_once_t);
+
+ type rwlockattr_rfu_array is array (0 .. 1) of int;
+
+ type pthread_rwlockattr_t is record
+ sig : long;
+ pshared : int;
+ rfu : rwlockattr_rfu_array;
+ end record;
+ pragma Convention (C, pthread_rwlockattr_t);
+
+ type rwlock_rfu_array is array (0 .. 2) of int;
+
+ type pthread_rwlock_t is record
+ sig : long;
+ lock : pthread_mutex_t;
+ state : int;
+ read_signal : pthread_cond_t;
+ write_signal : pthread_cond_t;
+ block_writers : int;
+ pshared : int;
+ rfu : rwlock_rfu_array;
+ end record;
+ pragma Convention (C, pthread_rwlock_t);
+
+ type pthread_key_t is new unsigned_long;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-dummy.ads b/gcc/ada/s-osinte-dummy.ads
new file mode 100644
index 00000000000..f33370dd43d
--- /dev/null
+++ b/gcc/ada/s-osinte-dummy.ads
@@ -0,0 +1,53 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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 is the no tasking version
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+package System.OS_Interface is
+ pragma Preelaborate;
+
+ -------------
+ -- Signals --
+ -------------
+
+ Max_Interrupt : constant := 2;
+ type Signal is new Integer range 0 .. Max_Interrupt;
+
+ type sigset_t is new Integer;
+ type Thread_Id is new Integer;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-freebsd.adb b/gcc/ada/s-osinte-freebsd.adb
new file mode 100644
index 00000000000..466a15d2b33
--- /dev/null
+++ b/gcc/ada/s-osinte-freebsd.adb
@@ -0,0 +1,108 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUNTIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1991-2003 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- --
+-- 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, 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, --
+-- 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. It is --
+-- now maintained by Ada Core Technologies Inc. in cooperation with Florida --
+-- State University (http://www.gnat.com). --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the FreeBSD THREADS version of this package
+
+with Interfaces.C; use Interfaces.C;
+
+package body System.OS_Interface is
+
+ function Errno return int is
+ type int_ptr is access all int;
+
+ function internal_errno return int_ptr;
+ pragma Import (C, internal_errno, "__error");
+ begin
+ return (internal_errno.all);
+ end Errno;
+
+ function Get_Stack_Base (thread : pthread_t) return Address is
+ pragma Unreferenced (thread);
+ begin
+ return (0);
+ end Get_Stack_Base;
+
+ procedure pthread_init is
+ begin
+ null;
+ end pthread_init;
+
+ -----------------
+ -- To_Duration --
+ -----------------
+
+ function To_Duration (TS : timespec) return Duration is
+ begin
+ return Duration (TS.ts_sec) + Duration (TS.ts_nsec) / 10#1#E9;
+ end To_Duration;
+
+ -----------------
+ -- To_Timespec --
+ -----------------
+
+ function To_Timespec (D : Duration) return timespec is
+ S : time_t;
+ F : Duration;
+ begin
+ S := time_t (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+ if F < 0.0 then S := S - 1; F := F + 1.0; end if;
+ return timespec'(ts_sec => S,
+ ts_nsec => long (Long_Long_Integer (F * 10#1#E9)));
+ end To_Timespec;
+
+
+ function To_Duration (TV : struct_timeval) return Duration is
+ begin
+ return Duration (TV.tv_sec) + Duration (TV.tv_usec) / 10#1#E6;
+ end To_Duration;
+
+ function To_Timeval (D : Duration) return struct_timeval is
+ S : long;
+ F : Duration;
+ begin
+ S := long (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+ if F < 0.0 then S := S - 1; F := F + 1.0; end if;
+ return struct_timeval'(tv_sec => S,
+ tv_usec => long (Long_Long_Integer (F * 10#1#E6)));
+ end To_Timeval;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-freebsd.ads b/gcc/ada/s-osinte-freebsd.ads
new file mode 100644
index 00000000000..13e545871c1
--- /dev/null
+++ b/gcc/ada/s-osinte-freebsd.ads
@@ -0,0 +1,644 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUNTIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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. It is --
+-- now maintained by Ada Core Technologies Inc. in cooperation with Florida --
+-- State University (http://www.gnat.com). --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the FreeBSD PTHREADS version of this package
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+with Interfaces.C;
+with Unchecked_Conversion;
+
+package System.OS_Interface is
+ pragma Preelaborate;
+
+ pragma Linker_Options ("-pthread");
+
+ subtype int is Interfaces.C.int;
+ subtype short is Interfaces.C.short;
+ subtype long is Interfaces.C.long;
+ subtype unsigned is Interfaces.C.unsigned;
+ subtype unsigned_short is Interfaces.C.unsigned_short;
+ subtype unsigned_long is Interfaces.C.unsigned_long;
+ subtype unsigned_char is Interfaces.C.unsigned_char;
+ subtype plain_char is Interfaces.C.plain_char;
+ subtype size_t is Interfaces.C.size_t;
+
+ -----------
+ -- Errno --
+ -----------
+
+ function Errno return int;
+ pragma Inline (Errno);
+
+ EAGAIN : constant := 35;
+ EINTR : constant := 4;
+ EINVAL : constant := 22;
+ ENOMEM : constant := 12;
+ ETIMEDOUT : constant := 60;
+
+ -------------
+ -- Signals --
+ -------------
+
+ Max_Interrupt : constant := 31;
+ type Signal is new int range 0 .. Max_Interrupt;
+ for Signal'Size use int'Size;
+
+ SIGHUP : constant := 1; -- hangup
+ SIGINT : constant := 2; -- interrupt (rubout)
+ SIGQUIT : constant := 3; -- quit (ASCD FS)
+ SIGILL : constant := 4; -- illegal instruction (not reset)
+ SIGTRAP : constant := 5; -- trace trap (not reset)
+ SIGIOT : constant := 6; -- IOT instruction
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGEMT : constant := 7; -- EMT instruction
+ SIGFPE : constant := 8; -- floating point exception
+ SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
+ SIGBUS : constant := 10; -- bus error
+ SIGSEGV : constant := 11; -- segmentation violation
+ SIGSYS : constant := 12; -- bad argument to system call
+ SIGPIPE : constant := 13; -- write on a pipe with no one to read it
+ SIGALRM : constant := 14; -- alarm clock
+ SIGTERM : constant := 15; -- software termination signal from kill
+ SIGURG : constant := 16; -- urgent condition on IO channel
+ SIGSTOP : constant := 17; -- stop (cannot be caught or ignored)
+ SIGTSTP : constant := 18; -- user stop requested from tty
+ SIGCONT : constant := 19; -- stopped process has been continued
+ SIGCLD : constant := 20; -- alias for SIGCHLD
+ SIGCHLD : constant := 20; -- child status change
+ SIGTTIN : constant := 21; -- background tty read attempted
+ SIGTTOU : constant := 22; -- background tty write attempted
+ SIGIO : constant := 23; -- I/O possible (Solaris SIGPOLL alias)
+ SIGXCPU : constant := 24; -- CPU time limit exceeded
+ SIGXFSZ : constant := 25; -- filesize limit exceeded
+ SIGVTALRM : constant := 26; -- virtual timer expired
+ SIGPROF : constant := 27; -- profiling timer expired
+ SIGWINCH : constant := 28; -- window size change
+ SIGINFO : constant := 29; -- information request (NetBSD/FreeBSD)
+ SIGUSR1 : constant := 30; -- user defined signal 1
+ SIGUSR2 : constant := 31; -- user defined signal 2
+
+ SIGADAABORT : constant := SIGABRT;
+ -- Change this if you want to use another signal for task abort.
+ -- SIGTERM might be a good one.
+
+ type Signal_Set is array (Natural range <>) of Signal;
+
+ -- Interrupts that must be unmasked at all times. FreeBSD
+ -- pthreads will not allow an application to mask out any
+ -- interrupt needed by the threads library.
+ Unmasked : constant Signal_Set :=
+ (SIGTRAP, SIGBUS, SIGTTIN, SIGTTOU, SIGTSTP);
+
+ -- FreeBSD will uses SIGPROF for timing. Do not allow a
+ -- handler to attach to this signal.
+ Reserved : constant Signal_Set := (0 .. 0 => SIGPROF);
+
+ type sigset_t is private;
+
+ function sigaddset
+ (set : access sigset_t;
+ sig : Signal) return int;
+ pragma Import (C, sigaddset, "sigaddset");
+
+ function sigdelset
+ (set : access sigset_t;
+ sig : Signal) return int;
+ pragma Import (C, sigdelset, "sigdelset");
+
+ function sigfillset (set : access sigset_t) return int;
+ pragma Import (C, sigfillset, "sigfillset");
+
+ function sigismember
+ (set : access sigset_t;
+ sig : Signal) return int;
+ pragma Import (C, sigismember, "sigismember");
+
+ function sigemptyset (set : access sigset_t) return int;
+ pragma Import (C, sigemptyset, "sigemptyset");
+
+ -- sigcontext is architecture dependent, so define it private
+ type struct_sigcontext is private;
+
+ type old_struct_sigaction is record
+ sa_handler : System.Address;
+ sa_mask : sigset_t;
+ sa_flags : int;
+ end record;
+ pragma Convention (C, old_struct_sigaction);
+
+ type new_struct_sigaction is record
+ sa_handler : System.Address;
+ sa_flags : int;
+ sa_mask : sigset_t;
+ end record;
+ pragma Convention (C, new_struct_sigaction);
+
+ subtype struct_sigaction is new_struct_sigaction;
+ type struct_sigaction_ptr is access all struct_sigaction;
+
+ SIG_BLOCK : constant := 1;
+ SIG_UNBLOCK : constant := 2;
+ SIG_SETMASK : constant := 3;
+
+ SIG_DFL : constant := 0;
+ SIG_IGN : constant := 1;
+
+ SA_SIGINFO : constant := 16#0040#;
+
+ function sigaction
+ (sig : Signal;
+ act : struct_sigaction_ptr;
+ oact : struct_sigaction_ptr) return int;
+ pragma Import (C, sigaction, "sigaction");
+
+ ----------
+ -- Time --
+ ----------
+
+ Time_Slice_Supported : constant Boolean := True;
+ -- Indicates wether time slicing is supported (i.e SCHED_RR is supported)
+
+ type timespec is private;
+
+ function nanosleep (rqtp, rmtp : access timespec) return int;
+ pragma Import (C, nanosleep, "nanosleep");
+
+ type clockid_t is private;
+
+ CLOCK_REALTIME : constant clockid_t;
+
+ function clock_gettime
+ (clock_id : clockid_t;
+ tp : access timespec)
+ return int;
+ pragma Import (C, clock_gettime, "clock_gettime");
+
+ function To_Duration (TS : timespec) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timespec (D : Duration) return timespec;
+ pragma Inline (To_Timespec);
+
+ type struct_timezone is record
+ tz_minuteswest : int;
+ tz_dsttime : int;
+ end record;
+ pragma Convention (C, struct_timezone);
+ type struct_timeval is private;
+ -- This is needed on systems that do not have clock_gettime()
+ -- but do have gettimeofday().
+
+ function To_Duration (TV : struct_timeval) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timeval (D : Duration) return struct_timeval;
+ pragma Inline (To_Timeval);
+
+ function gettimeofday
+ (tv : access struct_timeval;
+ tz : System.Address) return int;
+ pragma Import (C, gettimeofday, "gettimeofday");
+
+ procedure usleep (useconds : unsigned_long);
+ pragma Import (C, usleep, "usleep");
+
+ -------------------------
+ -- Priority Scheduling --
+ -------------------------
+
+ SCHED_FIFO : constant := 1;
+ SCHED_OTHER : constant := 2;
+ SCHED_RR : constant := 3;
+
+ -------------
+ -- Process --
+ -------------
+
+ type pid_t is private;
+
+ Self_PID : constant pid_t;
+
+ function kill (pid : pid_t; sig : Signal) return int;
+ pragma Import (C, kill, "kill");
+
+ function getpid return pid_t;
+ pragma Import (C, getpid, "getpid");
+
+ ---------
+ -- LWP --
+ ---------
+
+ function lwp_self return System.Address;
+ -- lwp_self does not exist on this thread library, revert to pthread_self
+ -- which is the closest approximation (with getpid). This function is
+ -- needed to share 7staprop.adb across POSIX-like targets.
+ pragma Import (C, lwp_self, "pthread_self");
+
+ -------------
+ -- Threads --
+ -------------
+
+ type Thread_Body is access
+ function (arg : System.Address) return System.Address;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ type pthread_t is private;
+ subtype Thread_Id is pthread_t;
+
+ type pthread_mutex_t is limited private;
+ type pthread_cond_t is limited private;
+ type pthread_attr_t is limited private;
+ type pthread_mutexattr_t is limited private;
+ type pthread_condattr_t is limited private;
+ type pthread_key_t is private;
+
+ PTHREAD_CREATE_DETACHED : constant := 1;
+ PTHREAD_CREATE_JOINABLE : constant := 0;
+
+ -----------
+ -- Stack --
+ -----------
+
+ Stack_Base_Available : constant Boolean := False;
+ -- Indicates wether the stack base is available on this target.
+ -- This allows us to share s-osinte.adb between all the FSU run time.
+ -- Note that this value can only be true if pthread_t has a complete
+ -- definition that corresponds exactly to the C header files.
+
+ function Get_Stack_Base (thread : pthread_t) return Address;
+ pragma Inline (Get_Stack_Base);
+ -- returns the stack base of the specified thread.
+ -- Only call this function when Stack_Base_Available is True.
+
+ 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
+
+ PROT_NONE : constant := 0;
+ PROT_READ : constant := 1;
+ PROT_WRITE : constant := 2;
+ PROT_EXEC : constant := 4;
+ PROT_ALL : constant := PROT_READ + PROT_WRITE + PROT_EXEC;
+
+ PROT_ON : constant := PROT_NONE;
+ PROT_OFF : constant := PROT_ALL;
+
+ function mprotect
+ (addr : Address; len : size_t; prot : int) return int;
+ pragma Import (C, mprotect);
+
+ -----------------------------------------
+ -- Nonstandard Thread Initialization --
+ -----------------------------------------
+ -- FSU_THREADS requires pthread_init, which is nonstandard
+ -- and this should be invoked during the elaboration of s-taprop.adb
+ --
+ -- FreeBSD does not require this so we provide an empty Ada body.
+ procedure pthread_init;
+
+ ---------------------------
+ -- POSIX.1c Section 3 --
+ ---------------------------
+
+ function sigwait
+ (set : access sigset_t;
+ sig : access Signal) return int;
+ pragma Import (C, sigwait, "sigwait");
+
+ function pthread_kill
+ (thread : pthread_t;
+ sig : Signal) return int;
+ pragma Import (C, pthread_kill, "pthread_kill");
+
+ type sigset_t_ptr is access all sigset_t;
+
+ function pthread_sigmask
+ (how : int;
+ set : sigset_t_ptr;
+ oset : sigset_t_ptr) return int;
+ pragma Import (C, pthread_sigmask, "pthread_sigmask");
+
+ ----------------------------
+ -- POSIX.1c Section 11 --
+ ----------------------------
+
+ function pthread_mutexattr_init
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_init, "pthread_mutexattr_init");
+
+ function pthread_mutexattr_destroy
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_destroy, "pthread_mutexattr_destroy");
+
+ function pthread_mutex_init
+ (mutex : access pthread_mutex_t;
+ attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutex_init, "pthread_mutex_init");
+
+ function pthread_mutex_destroy (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_destroy, "pthread_mutex_destroy");
+
+ function pthread_mutex_lock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_lock, "pthread_mutex_lock");
+
+ function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_unlock, "pthread_mutex_unlock");
+
+ function pthread_condattr_init
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_init, "pthread_condattr_init");
+
+ function pthread_condattr_destroy
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_destroy, "pthread_condattr_destroy");
+
+ function pthread_cond_init
+ (cond : access pthread_cond_t;
+ attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_cond_init, "pthread_cond_init");
+
+ function pthread_cond_destroy (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_destroy, "pthread_cond_destroy");
+
+ function pthread_cond_signal (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_signal, "pthread_cond_signal");
+
+ function pthread_cond_wait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_cond_wait, "pthread_cond_wait");
+
+ function pthread_cond_timedwait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ abstime : access timespec) return int;
+ pragma Import (C, pthread_cond_timedwait, "pthread_cond_timedwait");
+
+ Relative_Timed_Wait : constant Boolean := False;
+ -- pthread_cond_timedwait requires an absolute delay time
+
+ ----------------------------
+ -- POSIX.1c Section 13 --
+ ----------------------------
+
+ PTHREAD_PRIO_NONE : constant := 0;
+ PTHREAD_PRIO_PROTECT : constant := 2;
+ PTHREAD_PRIO_INHERIT : constant := 1;
+
+ function pthread_mutexattr_setprotocol
+ (attr : access pthread_mutexattr_t;
+ protocol : int) return int;
+ pragma Import
+ (C, pthread_mutexattr_setprotocol, "pthread_mutexattr_setprotocol");
+
+ function pthread_mutexattr_getprotocol
+ (attr : access pthread_mutexattr_t;
+ protocol : access int) return int;
+ pragma Import
+ (C, pthread_mutexattr_getprotocol, "pthread_mutexattr_getprotocol");
+
+ function pthread_mutexattr_setprioceiling
+ (attr : access pthread_mutexattr_t;
+ prioceiling : int) return int;
+ pragma Import
+ (C, pthread_mutexattr_setprioceiling,
+ "pthread_mutexattr_setprioceiling");
+
+ function pthread_mutexattr_getprioceiling
+ (attr : access pthread_mutexattr_t;
+ prioceiling : access int) return int;
+ pragma Import
+ (C, pthread_mutexattr_getprioceiling,
+ "pthread_mutexattr_getprioceiling");
+
+ type struct_sched_param is record
+ sched_priority : int;
+ end record;
+ pragma Convention (C, struct_sched_param);
+
+ function pthread_getschedparam
+ (thread : pthread_t;
+ policy : access int;
+ param : access struct_sched_param) return int;
+ pragma Import (C, pthread_getschedparam, "pthread_getschedparam");
+
+ function pthread_setschedparam
+ (thread : pthread_t;
+ policy : int;
+ param : access struct_sched_param) return int;
+ pragma Import (C, pthread_setschedparam, "pthread_setschedparam");
+
+ function pthread_attr_setscope
+ (attr : access pthread_attr_t;
+ contentionscope : int) return int;
+ pragma Import (C, pthread_attr_setscope, "pthread_attr_setscope");
+
+ function pthread_attr_getscope
+ (attr : access pthread_attr_t;
+ contentionscope : access int) return int;
+ pragma Import (C, pthread_attr_getscope, "pthread_attr_getscope");
+
+ function pthread_attr_setinheritsched
+ (attr : access pthread_attr_t;
+ inheritsched : int) return int;
+ pragma Import
+ (C, pthread_attr_setinheritsched, "pthread_attr_setinheritsched");
+
+ function pthread_attr_getinheritsched
+ (attr : access pthread_attr_t;
+ inheritsched : access int) return int;
+ pragma Import
+ (C, pthread_attr_getinheritsched, "pthread_attr_getinheritsched");
+
+ function pthread_attr_setschedpolicy
+ (attr : access pthread_attr_t;
+ policy : int) return int;
+ pragma Import (C, pthread_attr_setschedpolicy,
+ "pthread_attr_setschedpolicy");
+
+ function pthread_attr_getschedpolicy
+ (attr : access pthread_attr_t;
+ policy : access int) return int;
+ pragma Import (C, pthread_attr_getschedpolicy,
+ "pthread_attr_getschedpolicy");
+
+ function pthread_attr_setschedparam
+ (attr : access pthread_attr_t;
+ sched_param : int) return int;
+ pragma Import (C, pthread_attr_setschedparam, "pthread_attr_setschedparam");
+
+ function pthread_attr_getschedparam
+ (attr : access pthread_attr_t;
+ sched_param : access int) return int;
+ pragma Import (C, pthread_attr_getschedparam, "pthread_attr_getschedparam");
+
+ function sched_yield return int;
+ pragma Import (C, sched_yield, "pthread_yield");
+
+ -----------------------------
+ -- P1003.1c - Section 16 --
+ -----------------------------
+
+ function pthread_attr_init (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_init, "pthread_attr_init");
+
+ function pthread_attr_destroy
+ (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_destroy, "pthread_attr_destroy");
+
+ function pthread_attr_setdetachstate
+ (attr : access pthread_attr_t;
+ detachstate : int) return int;
+ pragma Import
+ (C, pthread_attr_setdetachstate, "pthread_attr_setdetachstate");
+
+ function pthread_attr_getdetachstate
+ (attr : access pthread_attr_t;
+ detachstate : access int) return int;
+ pragma Import
+ (C, pthread_attr_getdetachstate, "pthread_attr_getdetachstate");
+
+ function pthread_attr_getstacksize
+ (attr : access pthread_attr_t;
+ stacksize : access size_t) return int;
+ pragma Import
+ (C, pthread_attr_getstacksize, "pthread_attr_getstacksize");
+
+ function pthread_attr_setstacksize
+ (attr : access pthread_attr_t;
+ stacksize : size_t) return int;
+ pragma Import
+ (C, pthread_attr_setstacksize, "pthread_attr_setstacksize");
+
+ function pthread_create
+ (thread : access pthread_t;
+ attributes : access pthread_attr_t;
+ start_routine : Thread_Body;
+ arg : System.Address) return int;
+ pragma Import (C, pthread_create, "pthread_create");
+
+ function pthread_detach (thread : pthread_t) return int;
+ pragma Import (C, pthread_detach, "pthread_detach");
+
+ procedure pthread_exit (status : System.Address);
+ pragma Import (C, pthread_exit, "pthread_exit");
+
+ function pthread_self return pthread_t;
+ pragma Import (C, pthread_self, "pthread_self");
+
+ ----------------------------
+ -- POSIX.1c Section 17 --
+ ----------------------------
+
+ function pthread_setspecific
+ (key : pthread_key_t;
+ value : System.Address) return int;
+ pragma Import (C, pthread_setspecific, "pthread_setspecific");
+
+ function pthread_getspecific (key : pthread_key_t) return System.Address;
+ pragma Import (C, pthread_getspecific, "pthread_getspecific");
+
+ type destructor_pointer is access
+ procedure (arg : System.Address);
+
+ function pthread_key_create
+ (key : access pthread_key_t;
+ destructor : destructor_pointer) return int;
+ pragma Import (C, pthread_key_create, "pthread_key_create");
+
+ --------------------------------------
+ -- Non-portable pthread functions --
+ --------------------------------------
+
+ function pthread_set_name_np
+ (thread : pthread_t;
+ name : System.Address) return int;
+ pragma Import (C, pthread_set_name_np, "pthread_set_name_np");
+
+private
+
+ type sigset_t is array (1 .. 4) of unsigned;
+
+ -- In FreeBSD the component sa_handler turns out to
+ -- be one a union type, and the selector is a macro:
+ -- #define sa_handler __sigaction_u._handler
+ -- #define sa_sigaction __sigaction_u._sigaction
+
+ -- Should we add a signal_context type here ?
+ -- How could it be done independent of the CPU architecture ?
+ -- sigcontext type is opaque, so it is architecturally neutral.
+ -- It is always passed as an access type, so define it as an empty record
+ -- since the contents are not used anywhere.
+ type struct_sigcontext is null record;
+ pragma Convention (C, struct_sigcontext);
+
+ type pid_t is new int;
+ Self_PID : constant pid_t := 0;
+
+ type time_t is new long;
+
+ type timespec is record
+ ts_sec : time_t;
+ ts_nsec : long;
+ end record;
+ pragma Convention (C, timespec);
+
+ type clockid_t is new int;
+ CLOCK_REALTIME : constant clockid_t := 0;
+
+ type struct_timeval is record
+ tv_sec : long;
+ tv_usec : long;
+ end record;
+ pragma Convention (C, struct_timeval);
+
+ type pthread_t is new System.Address;
+ type pthread_attr_t is new System.Address;
+ type pthread_mutex_t is new System.Address;
+ type pthread_mutexattr_t is new System.Address;
+ type pthread_cond_t is new System.Address;
+ type pthread_condattr_t is new System.Address;
+ type pthread_key_t is new int;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-fsu.adb b/gcc/ada/s-osinte-fsu.adb
new file mode 100644
index 00000000000..b646a789b50
--- /dev/null
+++ b/gcc/ada/s-osinte-fsu.adb
@@ -0,0 +1,366 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2003, Ada Core Technologies --
+-- --
+-- 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, 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, --
+-- 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 is a FSU Threads version of this package
+
+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 Interfaces.C;
+
+package body System.OS_Interface is
+
+ use Interfaces.C;
+
+ -----------------
+ -- To_Duration --
+ -----------------
+
+ function To_Duration (TS : timespec) return Duration is
+ begin
+ return Duration (TS.tv_sec) + Duration (TS.tv_nsec) / 10#1#E9;
+ end To_Duration;
+
+ function To_Duration (TV : struct_timeval) return Duration is
+ begin
+ return Duration (TV.tv_sec) + Duration (TV.tv_usec) / 10#1#E6;
+ end To_Duration;
+
+ -----------------
+ -- To_Timespec --
+ -----------------
+
+ function To_Timespec (D : Duration) return timespec is
+ S : time_t;
+ F : Duration;
+
+ begin
+ S := time_t (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return timespec'(tv_sec => S,
+ tv_nsec => long (Long_Long_Integer (F * 10#1#E9)));
+ end To_Timespec;
+
+ ----------------
+ -- To_Timeval --
+ ----------------
+
+ function To_Timeval (D : Duration) return struct_timeval is
+ S : long;
+ F : Duration;
+
+ begin
+ S := long (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return
+ struct_timeval'
+ (tv_sec => S,
+ tv_usec => long (Long_Long_Integer (F * 10#1#E6)));
+ end To_Timeval;
+
+ -------------
+ -- sigwait --
+ -------------
+
+ -- FSU_THREADS has a nonstandard sigwait
+
+ function sigwait
+ (set : access sigset_t;
+ sig : access Signal) return int
+ is
+ Result : int;
+
+ function sigwait_base (set : access sigset_t) return int;
+ pragma Import (C, sigwait_base, "sigwait");
+
+ begin
+ Result := sigwait_base (set);
+
+ if Result = -1 then
+ sig.all := 0;
+ return errno;
+ end if;
+
+ sig.all := Signal (Result);
+ return 0;
+ end sigwait;
+
+ ------------------------
+ -- pthread_mutex_lock --
+ ------------------------
+
+ -- FSU_THREADS has nonstandard pthread_mutex_lock and unlock.
+ -- It sets errno but the standard Posix requires it to be returned.
+
+ function pthread_mutex_lock (mutex : access pthread_mutex_t) return int is
+ function pthread_mutex_lock_base
+ (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_lock_base, "pthread_mutex_lock");
+
+ Result : int;
+
+ begin
+ Result := pthread_mutex_lock_base (mutex);
+
+ if Result /= 0 then
+ return errno;
+ end if;
+
+ return 0;
+ end pthread_mutex_lock;
+
+ --------------------------
+ -- pthread_mutex_unlock --
+ --------------------------
+
+ function pthread_mutex_unlock
+ (mutex : access pthread_mutex_t) return int
+ is
+ function pthread_mutex_unlock_base
+ (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_unlock_base, "pthread_mutex_unlock");
+
+ Result : int;
+
+ begin
+ Result := pthread_mutex_unlock_base (mutex);
+
+ if Result /= 0 then
+ return errno;
+ end if;
+
+ return 0;
+ end pthread_mutex_unlock;
+
+ -----------------------
+ -- pthread_cond_wait --
+ -----------------------
+
+ -- FSU_THREADS has a nonstandard pthread_cond_wait.
+ -- The FSU_THREADS version returns EINTR when interrupted.
+
+ function pthread_cond_wait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t) return int
+ is
+ function pthread_cond_wait_base
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_cond_wait_base, "pthread_cond_wait");
+
+ Result : int;
+
+ begin
+ Result := pthread_cond_wait_base (cond, mutex);
+
+ if Result = EINTR then
+ return 0;
+ else
+ return Result;
+ end if;
+ end pthread_cond_wait;
+
+ ----------------------------
+ -- pthread_cond_timedwait --
+ ----------------------------
+
+ -- FSU_THREADS has a nonstandard pthread_cond_timedwait. The
+ -- FSU_THREADS version returns -1 and set errno to EAGAIN for timeout.
+
+ function pthread_cond_timedwait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ abstime : access timespec) return int
+ is
+ function pthread_cond_timedwait_base
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ abstime : access timespec) return int;
+ pragma Import (C, pthread_cond_timedwait_base, "pthread_cond_timedwait");
+
+ Result : int;
+
+ begin
+ Result := pthread_cond_timedwait_base (cond, mutex, abstime);
+
+ if Result = -1 then
+ if errno = EAGAIN then
+ return ETIMEDOUT;
+ else
+ return EINVAL;
+ end if;
+ end if;
+
+ return 0;
+ end pthread_cond_timedwait;
+
+ ---------------------------
+ -- pthread_setschedparam --
+ ---------------------------
+
+ -- FSU_THREADS does not have pthread_setschedparam
+
+ -- This routine returns a non-negative value upon failure
+ -- but the error code can not be set conforming the POSIX standard.
+
+ function pthread_setschedparam
+ (thread : pthread_t;
+ policy : int;
+ param : access struct_sched_param) return int
+ is
+ function pthread_setschedattr
+ (thread : pthread_t;
+ attr : pthread_attr_t) return int;
+ pragma Import (C, pthread_setschedattr, "pthread_setschedattr");
+
+ attr : aliased pthread_attr_t;
+ Result : int;
+
+ begin
+ Result := pthread_attr_init (attr'Access);
+
+ if Result /= 0 then
+ return Result;
+ end if;
+
+ attr.sched := policy;
+
+ -- Short-cut around pthread_attr_setprio
+
+ attr.prio := param.sched_priority;
+
+ Result := pthread_setschedattr (thread, attr);
+
+ if Result /= 0 then
+ return Result;
+ end if;
+
+ Result := pthread_attr_destroy (attr'Access);
+
+ if Result /= 0 then
+ return Result;
+ else
+ return 0;
+ end if;
+ end pthread_setschedparam;
+
+ -------------------------
+ -- pthread_getspecific --
+ -------------------------
+
+ -- FSU_THREADS has a nonstandard pthread_getspecific
+
+ function pthread_getspecific (key : pthread_key_t) return System.Address is
+ function pthread_getspecific_base
+ (key : pthread_key_t;
+ value : access System.Address) return int;
+ pragma Import (C, pthread_getspecific_base, "pthread_getspecific");
+
+ Tmp : aliased System.Address;
+ Result : int;
+
+ begin
+ Result := pthread_getspecific_base (key, Tmp'Access);
+
+ if Result /= 0 then
+ return System.Null_Address;
+ end if;
+
+ return Tmp;
+ end pthread_getspecific;
+
+ ---------------------------------
+ -- pthread_attr_setdetachstate --
+ ---------------------------------
+
+ function pthread_attr_setdetachstate
+ (attr : access pthread_attr_t;
+ detachstate : int) return int
+ is
+ function pthread_attr_setdetachstate_base
+ (attr : access pthread_attr_t;
+ detachstate : access int) return int;
+ pragma Import
+ (C, pthread_attr_setdetachstate_base, "pthread_attr_setdetachstate");
+
+ Tmp : aliased int := detachstate;
+
+ begin
+ return pthread_attr_setdetachstate_base (attr, Tmp'Access);
+ end pthread_attr_setdetachstate;
+
+ -----------------
+ -- sched_yield --
+ -----------------
+
+ -- FSU_THREADS does not have sched_yield;
+
+ function sched_yield return int is
+ procedure sched_yield_base (arg : System.Address);
+ pragma Import (C, sched_yield_base, "pthread_yield");
+
+ begin
+ sched_yield_base (System.Null_Address);
+ return 0;
+ end sched_yield;
+
+ ----------------
+ -- Stack_Base --
+ ----------------
+
+ function Get_Stack_Base (thread : pthread_t) return Address is
+ begin
+ return thread.stack_base;
+ end Get_Stack_Base;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-hpux-dce.adb b/gcc/ada/s-osinte-hpux-dce.adb
new file mode 100644
index 00000000000..dcd169ccf62
--- /dev/null
+++ b/gcc/ada/s-osinte-hpux-dce.adb
@@ -0,0 +1,564 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2003, Ada Core Technologies --
+-- --
+-- 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, 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, --
+-- 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 is a DCE version of this package.
+-- Currently HP-UX and SNI use this file
+
+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.
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+with Interfaces.C; use Interfaces.C;
+
+package body System.OS_Interface is
+
+ -----------------
+ -- To_Duration --
+ -----------------
+
+ function To_Duration (TS : timespec) return Duration is
+ begin
+ return Duration (TS.tv_sec) + Duration (TS.tv_nsec) / 10#1#E9;
+ end To_Duration;
+
+ -----------------
+ -- To_Timespec --
+ -----------------
+
+ function To_Timespec (D : Duration) return timespec is
+ S : time_t;
+ F : Duration;
+
+ begin
+ S := time_t (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return timespec'(tv_sec => S,
+ tv_nsec => long (Long_Long_Integer (F * 10#1#E9)));
+ end To_Timespec;
+
+ function To_Duration (TV : struct_timeval) return Duration is
+ begin
+ return Duration (TV.tv_sec) + Duration (TV.tv_usec) / 10#1#E6;
+ end To_Duration;
+
+ function To_Timeval (D : Duration) return struct_timeval is
+ S : time_t;
+ F : Duration;
+ begin
+ S := time_t (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return
+ struct_timeval'
+ (tv_sec => S,
+ tv_usec => time_t (Long_Long_Integer (F * 10#1#E6)));
+ end To_Timeval;
+
+ ---------------------------
+ -- POSIX.1c Section 3 --
+ ---------------------------
+
+ function sigwait
+ (set : access sigset_t;
+ sig : access Signal)
+ return int
+ is
+ Result : int;
+
+ begin
+ Result := sigwait (set);
+
+ if Result = -1 then
+ sig.all := 0;
+ return errno;
+ end if;
+
+ sig.all := Signal (Result);
+ return 0;
+ end sigwait;
+
+ -- DCE_THREADS does not have pthread_kill. Instead, we just ignore it.
+
+ function pthread_kill (thread : pthread_t; sig : Signal) return int is
+ pragma Unreferenced (thread, sig);
+ begin
+ return 0;
+ end pthread_kill;
+
+ ----------------------------
+ -- POSIX.1c Section 11 --
+ ----------------------------
+
+ -- For all the following functions, DCE Threads has a non standard
+ -- behavior: it sets errno but the standard Posix requires it to be
+ -- returned.
+
+ function pthread_mutexattr_init
+ (attr : access pthread_mutexattr_t)
+ return int
+ is
+ function pthread_mutexattr_create
+ (attr : access pthread_mutexattr_t)
+ return int;
+ pragma Import (C, pthread_mutexattr_create, "pthread_mutexattr_create");
+
+ begin
+ if pthread_mutexattr_create (attr) /= 0 then
+ return errno;
+ else
+ return 0;
+ end if;
+ end pthread_mutexattr_init;
+
+ function pthread_mutexattr_destroy
+ (attr : access pthread_mutexattr_t)
+ return int
+ is
+ function pthread_mutexattr_delete
+ (attr : access pthread_mutexattr_t)
+ return int;
+ pragma Import (C, pthread_mutexattr_delete, "pthread_mutexattr_delete");
+
+ begin
+ if pthread_mutexattr_delete (attr) /= 0 then
+ return errno;
+ else
+ return 0;
+ end if;
+ end pthread_mutexattr_destroy;
+
+ function pthread_mutex_init
+ (mutex : access pthread_mutex_t;
+ attr : access pthread_mutexattr_t)
+ return int
+ is
+ function pthread_mutex_init_base
+ (mutex : access pthread_mutex_t;
+ attr : pthread_mutexattr_t)
+ return int;
+ pragma Import (C, pthread_mutex_init_base, "pthread_mutex_init");
+
+ begin
+ if pthread_mutex_init_base (mutex, attr.all) /= 0 then
+ return errno;
+ else
+ return 0;
+ end if;
+ end pthread_mutex_init;
+
+ function pthread_mutex_destroy
+ (mutex : access pthread_mutex_t)
+ return int
+ is
+ function pthread_mutex_destroy_base
+ (mutex : access pthread_mutex_t)
+ return int;
+ pragma Import (C, pthread_mutex_destroy_base, "pthread_mutex_destroy");
+
+ begin
+ if pthread_mutex_destroy_base (mutex) /= 0 then
+ return errno;
+ else
+ return 0;
+ end if;
+ end pthread_mutex_destroy;
+
+ function pthread_mutex_lock
+ (mutex : access pthread_mutex_t)
+ return int
+ is
+ function pthread_mutex_lock_base
+ (mutex : access pthread_mutex_t)
+ return int;
+ pragma Import (C, pthread_mutex_lock_base, "pthread_mutex_lock");
+
+ begin
+ if pthread_mutex_lock_base (mutex) /= 0 then
+ return errno;
+ else
+ return 0;
+ end if;
+ end pthread_mutex_lock;
+
+ function pthread_mutex_unlock
+ (mutex : access pthread_mutex_t)
+ return int
+ is
+ function pthread_mutex_unlock_base
+ (mutex : access pthread_mutex_t)
+ return int;
+ pragma Import (C, pthread_mutex_unlock_base, "pthread_mutex_unlock");
+
+ begin
+ if pthread_mutex_unlock_base (mutex) /= 0 then
+ return errno;
+ else
+ return 0;
+ end if;
+ end pthread_mutex_unlock;
+
+ function pthread_condattr_init
+ (attr : access pthread_condattr_t)
+ return int
+ is
+ function pthread_condattr_create
+ (attr : access pthread_condattr_t)
+ return int;
+ pragma Import (C, pthread_condattr_create, "pthread_condattr_create");
+
+ begin
+ if pthread_condattr_create (attr) /= 0 then
+ return errno;
+ else
+ return 0;
+ end if;
+ end pthread_condattr_init;
+
+ function pthread_condattr_destroy
+ (attr : access pthread_condattr_t)
+ return int
+ is
+ function pthread_condattr_delete
+ (attr : access pthread_condattr_t)
+ return int;
+ pragma Import (C, pthread_condattr_delete, "pthread_condattr_delete");
+
+ begin
+ if pthread_condattr_delete (attr) /= 0 then
+ return errno;
+ else
+ return 0;
+ end if;
+ end pthread_condattr_destroy;
+
+ function pthread_cond_init
+ (cond : access pthread_cond_t;
+ attr : access pthread_condattr_t)
+ return int
+ is
+ function pthread_cond_init_base
+ (cond : access pthread_cond_t;
+ attr : pthread_condattr_t)
+ return int;
+ pragma Import (C, pthread_cond_init_base, "pthread_cond_init");
+
+ begin
+ if pthread_cond_init_base (cond, attr.all) /= 0 then
+ return errno;
+ else
+ return 0;
+ end if;
+ end pthread_cond_init;
+
+ function pthread_cond_destroy
+ (cond : access pthread_cond_t)
+ return int
+ is
+ function pthread_cond_destroy_base
+ (cond : access pthread_cond_t)
+ return int;
+ pragma Import (C, pthread_cond_destroy_base, "pthread_cond_destroy");
+
+ begin
+ if pthread_cond_destroy_base (cond) /= 0 then
+ return errno;
+ else
+ return 0;
+ end if;
+ end pthread_cond_destroy;
+
+ function pthread_cond_signal
+ (cond : access pthread_cond_t)
+ return int
+ is
+ function pthread_cond_signal_base
+ (cond : access pthread_cond_t)
+ return int;
+ pragma Import (C, pthread_cond_signal_base, "pthread_cond_signal");
+
+ begin
+ if pthread_cond_signal_base (cond) /= 0 then
+ return errno;
+ else
+ return 0;
+ end if;
+ end pthread_cond_signal;
+
+ function pthread_cond_wait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t)
+ return int
+ is
+ function pthread_cond_wait_base
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t)
+ return int;
+ pragma Import (C, pthread_cond_wait_base, "pthread_cond_wait");
+
+ begin
+ if pthread_cond_wait_base (cond, mutex) /= 0 then
+ return errno;
+ else
+ return 0;
+ end if;
+ end pthread_cond_wait;
+
+ function pthread_cond_timedwait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ abstime : access timespec)
+ return int
+ is
+ function pthread_cond_timedwait_base
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ abstime : access timespec)
+ return int;
+ pragma Import (C, pthread_cond_timedwait_base, "pthread_cond_timedwait");
+
+ begin
+ if pthread_cond_timedwait_base (cond, mutex, abstime) /= 0 then
+ if errno = EAGAIN then
+ return ETIMEDOUT;
+ else
+ return errno;
+ end if;
+ else
+ return 0;
+ end if;
+ end pthread_cond_timedwait;
+
+ ----------------------------
+ -- POSIX.1c Section 13 --
+ ----------------------------
+
+ function pthread_setschedparam
+ (thread : pthread_t;
+ policy : int;
+ param : access struct_sched_param) return int
+ is
+ function pthread_setscheduler
+ (thread : pthread_t;
+ policy : int;
+ priority : int)
+ return int;
+ pragma Import (C, pthread_setscheduler, "pthread_setscheduler");
+
+ begin
+ if pthread_setscheduler (thread, policy, param.sched_priority) = -1 then
+ return errno;
+ else
+ return 0;
+ end if;
+ end pthread_setschedparam;
+
+ function sched_yield return int is
+ procedure pthread_yield;
+ pragma Import (C, pthread_yield, "pthread_yield");
+ begin
+ pthread_yield;
+ return 0;
+ end sched_yield;
+
+ -----------------------------
+ -- P1003.1c - Section 16 --
+ -----------------------------
+
+ function pthread_attr_init (attributes : access pthread_attr_t) return int
+ is
+ function pthread_attr_create
+ (attributes : access pthread_attr_t)
+ return int;
+ pragma Import (C, pthread_attr_create, "pthread_attr_create");
+
+ begin
+ if pthread_attr_create (attributes) /= 0 then
+ return errno;
+ else
+ return 0;
+ end if;
+ end pthread_attr_init;
+
+ function pthread_attr_destroy
+ (attributes : access pthread_attr_t) return int
+ is
+ function pthread_attr_delete
+ (attributes : access pthread_attr_t)
+ return int;
+ pragma Import (C, pthread_attr_delete, "pthread_attr_delete");
+
+ begin
+ if pthread_attr_delete (attributes) /= 0 then
+ return errno;
+ else
+ return 0;
+ end if;
+ end pthread_attr_destroy;
+
+ function pthread_attr_setstacksize
+ (attr : access pthread_attr_t;
+ stacksize : size_t) return int
+ is
+ function pthread_attr_setstacksize_base
+ (attr : access pthread_attr_t;
+ stacksize : size_t)
+ return int;
+ pragma Import (C, pthread_attr_setstacksize_base,
+ "pthread_attr_setstacksize");
+
+ begin
+ if pthread_attr_setstacksize_base (attr, stacksize) /= 0 then
+ return errno;
+ else
+ return 0;
+ end if;
+ end pthread_attr_setstacksize;
+
+ function pthread_create
+ (thread : access pthread_t;
+ attributes : access pthread_attr_t;
+ start_routine : Thread_Body;
+ arg : System.Address) return int
+ is
+ function pthread_create_base
+ (thread : access pthread_t;
+ attributes : pthread_attr_t;
+ start_routine : Thread_Body;
+ arg : System.Address)
+ return int;
+ pragma Import (C, pthread_create_base, "pthread_create");
+
+ begin
+ if pthread_create_base
+ (thread, attributes.all, start_routine, arg) /= 0
+ then
+ return errno;
+ else
+ return 0;
+ end if;
+ end pthread_create;
+
+ ----------------------------
+ -- POSIX.1c Section 17 --
+ ----------------------------
+
+ function pthread_setspecific
+ (key : pthread_key_t;
+ value : System.Address) return int
+ is
+ function pthread_setspecific_base
+ (key : pthread_key_t;
+ value : System.Address) return int;
+ pragma Import (C, pthread_setspecific_base, "pthread_setspecific");
+
+ begin
+ if pthread_setspecific_base (key, value) /= 0 then
+ return errno;
+ else
+ return 0;
+ end if;
+ end pthread_setspecific;
+
+ function pthread_getspecific (key : pthread_key_t) return System.Address is
+ function pthread_getspecific_base
+ (key : pthread_key_t;
+ value : access System.Address) return int;
+ pragma Import (C, pthread_getspecific_base, "pthread_getspecific");
+ Addr : aliased System.Address;
+
+ begin
+ if pthread_getspecific_base (key, Addr'Access) /= 0 then
+ return System.Null_Address;
+ else
+ return Addr;
+ end if;
+ end pthread_getspecific;
+
+ function pthread_key_create
+ (key : access pthread_key_t;
+ destructor : destructor_pointer) return int
+ is
+ function pthread_keycreate
+ (key : access pthread_key_t;
+ destructor : destructor_pointer) return int;
+ pragma Import (C, pthread_keycreate, "pthread_keycreate");
+
+ begin
+ if pthread_keycreate (key, destructor) /= 0 then
+ return errno;
+ else
+ return 0;
+ end if;
+ end pthread_key_create;
+
+ function Get_Stack_Base (thread : pthread_t) return Address is
+ pragma Warnings (Off, thread);
+
+ begin
+ return Null_Address;
+ end Get_Stack_Base;
+
+ procedure pthread_init is
+ begin
+ null;
+ end pthread_init;
+
+ function intr_attach (sig : int; handler : isr_address) return long is
+ function c_signal (sig : int; handler : isr_address) return long;
+ pragma Import (C, c_signal, "signal");
+
+ begin
+ return c_signal (sig, handler);
+ end intr_attach;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-hpux-dce.ads b/gcc/ada/s-osinte-hpux-dce.ads
new file mode 100644
index 00000000000..18de527be15
--- /dev/null
+++ b/gcc/ada/s-osinte-hpux-dce.ads
@@ -0,0 +1,495 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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 is the HP-UX version of this package
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+with Interfaces.C;
+with Unchecked_Conversion;
+
+package System.OS_Interface is
+ pragma Preelaborate;
+
+ pragma Linker_Options ("-lcma");
+
+ subtype int is Interfaces.C.int;
+ subtype short is Interfaces.C.short;
+ subtype long is Interfaces.C.long;
+ subtype unsigned is Interfaces.C.unsigned;
+ subtype unsigned_short is Interfaces.C.unsigned_short;
+ subtype unsigned_long is Interfaces.C.unsigned_long;
+ subtype unsigned_char is Interfaces.C.unsigned_char;
+ subtype plain_char is Interfaces.C.plain_char;
+ subtype size_t is Interfaces.C.size_t;
+
+ -----------
+ -- Errno --
+ -----------
+
+ function errno return int;
+ pragma Import (C, errno, "__get_errno");
+
+ EAGAIN : constant := 11;
+ EINTR : constant := 4;
+ EINVAL : constant := 22;
+ ENOMEM : constant := 12;
+ ETIME : constant := 52;
+ ETIMEDOUT : constant := 238;
+
+ FUNC_ERR : constant := -1;
+
+ -------------
+ -- Signals --
+ -------------
+
+ Max_Interrupt : constant := 44;
+ type Signal is new int range 0 .. Max_Interrupt;
+ for Signal'Size use int'Size;
+
+ SIGHUP : constant := 1; -- hangup
+ SIGINT : constant := 2; -- interrupt (rubout)
+ SIGQUIT : constant := 3; -- quit (ASCD FS)
+ SIGILL : constant := 4; -- illegal instruction (not reset)
+ SIGTRAP : constant := 5; -- trace trap (not reset)
+ SIGIOT : constant := 6; -- IOT instruction
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGEMT : constant := 7; -- EMT instruction
+ SIGFPE : constant := 8; -- floating point exception
+ SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
+ SIGBUS : constant := 10; -- bus error
+ SIGSEGV : constant := 11; -- segmentation violation
+ SIGSYS : constant := 12; -- bad argument to system call
+ SIGPIPE : constant := 13; -- write on a pipe with no one to read it
+ SIGALRM : constant := 14; -- alarm clock
+ SIGTERM : constant := 15; -- software termination signal from kill
+ SIGUSR1 : constant := 16; -- user defined signal 1
+ SIGUSR2 : constant := 17; -- user defined signal 2
+ SIGCLD : constant := 18; -- alias for SIGCHLD
+ SIGCHLD : constant := 18; -- child status change
+ SIGPWR : constant := 19; -- power-fail restart
+ SIGVTALRM : constant := 20; -- virtual timer alarm
+ SIGPROF : constant := 21; -- profiling timer alarm
+ SIGIO : constant := 22; -- asynchronous I/O
+ SIGPOLL : constant := 22; -- pollable event occurred
+ SIGWINCH : constant := 23; -- window size change
+ SIGSTOP : constant := 24; -- stop (cannot be caught or ignored)
+ SIGTSTP : constant := 25; -- user stop requested from tty
+ SIGCONT : constant := 26; -- stopped process has been continued
+ SIGTTIN : constant := 27; -- background tty read attempted
+ SIGTTOU : constant := 28; -- background tty write attempted
+ SIGURG : constant := 29; -- urgent condition on IO channel
+ SIGLOST : constant := 30; -- remote lock lost (NFS)
+ SIGDIL : constant := 32; -- DIL signal
+ SIGXCPU : constant := 33; -- CPU time limit exceeded (setrlimit)
+ SIGXFSZ : constant := 34; -- file size limit exceeded (setrlimit)
+
+ SIGADAABORT : constant := SIGABRT;
+ -- Note: on other targets, we usually use SIGABRT, but on HP/UX, it
+ -- appears that SIGABRT can't be used in sigwait(), so we use SIGTERM.
+
+ type Signal_Set is array (Natural range <>) of Signal;
+
+ Unmasked : constant Signal_Set :=
+ (SIGBUS, SIGTRAP, SIGTTIN, SIGTTOU, SIGTSTP);
+
+ Reserved : constant Signal_Set := (SIGKILL, SIGSTOP);
+
+ type sigset_t is private;
+
+ type isr_address is access procedure (sig : int);
+
+ function intr_attach (sig : int; handler : isr_address) return long;
+
+ Intr_Attach_Reset : constant Boolean := True;
+ -- True if intr_attach is reset after an interrupt handler is called
+
+ function sigaddset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigaddset, "sigaddset");
+
+ function sigdelset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigdelset, "sigdelset");
+
+ function sigfillset (set : access sigset_t) return int;
+ pragma Import (C, sigfillset, "sigfillset");
+
+ function sigismember (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigismember, "sigismember");
+
+ function sigemptyset (set : access sigset_t) return int;
+ pragma Import (C, sigemptyset, "sigemptyset");
+
+ type Signal_Handler is access procedure (signo : Signal);
+
+ type struct_sigaction is record
+ sa_handler : System.Address;
+ sa_mask : sigset_t;
+ sa_flags : int;
+ end record;
+ pragma Convention (C, struct_sigaction);
+ type struct_sigaction_ptr is access all struct_sigaction;
+
+ SA_RESTART : constant := 16#40#;
+ SA_SIGINFO : constant := 16#10#;
+
+ SIG_BLOCK : constant := 0;
+ SIG_UNBLOCK : constant := 1;
+ SIG_SETMASK : constant := 2;
+
+ SIG_DFL : constant := 0;
+ SIG_IGN : constant := 1;
+ SIG_ERR : constant := -1;
+
+ function sigaction
+ (sig : Signal;
+ act : struct_sigaction_ptr;
+ oact : struct_sigaction_ptr) return int;
+ pragma Import (C, sigaction, "sigaction");
+
+ ----------
+ -- Time --
+ ----------
+
+ type timespec is private;
+
+ function nanosleep (rqtp, rmtp : access timespec) return int;
+ pragma Import (C, nanosleep);
+
+ type clockid_t is private;
+
+ CLOCK_REALTIME : constant clockid_t;
+
+ function Clock_Gettime
+ (Clock_Id : clockid_t; Tp : access timespec) return int;
+ pragma Import (C, Clock_Gettime);
+
+ function To_Duration (TS : timespec) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timespec (D : Duration) return timespec;
+ pragma Inline (To_Timespec);
+
+ type struct_timeval is private;
+
+ function To_Duration (TV : struct_timeval) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timeval (D : Duration) return struct_timeval;
+ pragma Inline (To_Timeval);
+
+ -------------------------
+ -- Priority Scheduling --
+ -------------------------
+
+ SCHED_FIFO : constant := 0;
+ SCHED_RR : constant := 1;
+ SCHED_OTHER : constant := 2;
+
+ -------------
+ -- Process --
+ -------------
+
+ type pid_t is private;
+
+ function kill (pid : pid_t; sig : Signal) return int;
+ pragma Import (C, kill, "kill");
+
+ function getpid return pid_t;
+ pragma Import (C, getpid, "getpid");
+
+ -------------
+ -- Threads --
+ -------------
+
+ type Thread_Body is access
+ function (arg : System.Address) return System.Address;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ type pthread_t is private;
+ subtype Thread_Id is pthread_t;
+
+ type pthread_mutex_t is limited private;
+ type pthread_cond_t is limited private;
+ type pthread_attr_t is limited private;
+ type pthread_mutexattr_t is limited private;
+ type pthread_condattr_t is limited private;
+ type pthread_key_t is private;
+
+ -----------
+ -- Stack --
+ -----------
+
+ function Get_Stack_Base (thread : pthread_t) return Address;
+ pragma Inline (Get_Stack_Base);
+ -- This is a dummy procedure to share some GNULLI files
+
+ ---------------------------------------
+ -- Nonstandard Thread Initialization --
+ ---------------------------------------
+
+ procedure pthread_init;
+ pragma Inline (pthread_init);
+ -- This is a dummy procedure to share some GNULLI files
+
+ -------------------------
+ -- POSIX.1c Section 3 --
+ -------------------------
+
+ function sigwait (set : access sigset_t) return int;
+ pragma Import (C, sigwait, "cma_sigwait");
+
+ function sigwait
+ (set : access sigset_t;
+ sig : access Signal) return int;
+ pragma Inline (sigwait);
+ -- DCE_THREADS has a nonstandard sigwait
+
+ function pthread_kill
+ (thread : pthread_t;
+ sig : Signal) return int;
+ pragma Inline (pthread_kill);
+ -- DCE_THREADS doesn't have pthread_kill
+
+ type sigset_t_ptr is access all sigset_t;
+
+ function pthread_sigmask
+ (how : int;
+ set : sigset_t_ptr;
+ oset : sigset_t_ptr) return int;
+ -- DCE THREADS does not have pthread_sigmask. Instead, it uses
+ -- sigprocmask to do the signal handling when the thread library is
+ -- sucked in.
+ pragma Import (C, pthread_sigmask, "sigprocmask");
+
+ --------------------------
+ -- POSIX.1c Section 11 --
+ --------------------------
+
+ function pthread_mutexattr_init
+ (attr : access pthread_mutexattr_t) return int;
+ -- DCE_THREADS has a nonstandard pthread_mutexattr_init.
+
+ function pthread_mutexattr_destroy
+ (attr : access pthread_mutexattr_t) return int;
+ -- DCE_THREADS has a nonstandard pthread_mutexattr_destroy
+
+ function pthread_mutex_init
+ (mutex : access pthread_mutex_t;
+ attr : access pthread_mutexattr_t) return int;
+ -- DCE_THREADS has a nonstandard pthread_mutex_init
+
+ function pthread_mutex_destroy (mutex : access pthread_mutex_t) return int;
+ -- DCE_THREADS has a nonstandard pthread_mutex_destroy
+
+ function pthread_mutex_lock (mutex : access pthread_mutex_t) return int;
+ pragma Inline (pthread_mutex_lock);
+ -- DCE_THREADS has nonstandard pthread_mutex_lock
+
+ function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int;
+ pragma Inline (pthread_mutex_unlock);
+ -- DCE_THREADS has nonstandard pthread_mutex_lock
+
+ function pthread_condattr_init
+ (attr : access pthread_condattr_t) return int;
+ -- DCE_THREADS has nonstandard pthread_condattr_init
+
+ function pthread_condattr_destroy
+ (attr : access pthread_condattr_t) return int;
+ -- DCE_THREADS has nonstandard pthread_condattr_destroy
+
+ function pthread_cond_init
+ (cond : access pthread_cond_t;
+ attr : access pthread_condattr_t) return int;
+ -- DCE_THREADS has nonstandard pthread_cond_init
+
+ function pthread_cond_destroy (cond : access pthread_cond_t) return int;
+ -- DCE_THREADS has nonstandard pthread_cond_destroy
+
+ function pthread_cond_signal (cond : access pthread_cond_t) return int;
+ pragma Inline (pthread_cond_signal);
+ -- DCE_THREADS has nonstandard pthread_cond_signal
+
+ function pthread_cond_wait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t) return int;
+ pragma Inline (pthread_cond_wait);
+ -- DCE_THREADS has a nonstandard pthread_cond_wait
+
+ function pthread_cond_timedwait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ abstime : access timespec) return int;
+ pragma Inline (pthread_cond_timedwait);
+ -- DCE_THREADS has a nonstandard pthread_cond_timedwait
+
+ --------------------------
+ -- POSIX.1c Section 13 --
+ --------------------------
+
+ type struct_sched_param is record
+ sched_priority : int; -- scheduling priority
+ end record;
+
+ function pthread_setschedparam
+ (thread : pthread_t;
+ policy : int;
+ param : access struct_sched_param) return int;
+ pragma Inline (pthread_setschedparam);
+ -- DCE_THREADS has a nonstandard pthread_setschedparam
+
+ function sched_yield return int;
+ pragma Inline (sched_yield);
+ -- DCE_THREADS has a nonstandard sched_yield
+
+ ---------------------------
+ -- P1003.1c - Section 16 --
+ ---------------------------
+
+ function pthread_attr_init (attributes : access pthread_attr_t) return int;
+ pragma Inline (pthread_attr_init);
+ -- DCE_THREADS has a nonstandard pthread_attr_init
+
+ function pthread_attr_destroy
+ (attributes : access pthread_attr_t) return int;
+ pragma Inline (pthread_attr_destroy);
+ -- DCE_THREADS has a nonstandard pthread_attr_destroy
+
+ function pthread_attr_setstacksize
+ (attr : access pthread_attr_t;
+ stacksize : size_t) return int;
+ pragma Inline (pthread_attr_setstacksize);
+ -- DCE_THREADS has a nonstandard pthread_attr_setstacksize
+
+ function pthread_create
+ (thread : access pthread_t;
+ attributes : access pthread_attr_t;
+ start_routine : Thread_Body;
+ arg : System.Address) return int;
+ pragma Inline (pthread_create);
+ -- DCE_THREADS has a nonstandard pthread_create
+
+ procedure pthread_detach (thread : access pthread_t);
+ pragma Import (C, pthread_detach);
+
+ procedure pthread_exit (status : System.Address);
+ pragma Import (C, pthread_exit, "pthread_exit");
+
+ function pthread_self return pthread_t;
+ pragma Import (C, pthread_self, "pthread_self");
+
+ --------------------------
+ -- POSIX.1c Section 17 --
+ --------------------------
+
+ function pthread_setspecific
+ (key : pthread_key_t;
+ value : System.Address) return int;
+ pragma Inline (pthread_setspecific);
+ -- DCE_THREADS has a nonstandard pthread_setspecific
+
+ function pthread_getspecific (key : pthread_key_t) return System.Address;
+ pragma Inline (pthread_getspecific);
+ -- DCE_THREADS has a nonstandard pthread_getspecific
+
+ type destructor_pointer is access procedure (arg : System.Address);
+
+ function pthread_key_create
+ (key : access pthread_key_t;
+ destructor : destructor_pointer) return int;
+ pragma Inline (pthread_key_create);
+ -- DCE_THREADS has a nonstandard pthread_key_create
+
+private
+
+ type array_type_1 is array (Integer range 0 .. 7) of unsigned_long;
+ type sigset_t is record
+ X_X_sigbits : array_type_1;
+ end record;
+ pragma Convention (C, sigset_t);
+
+ type pid_t is new int;
+
+ type time_t is new long;
+
+ type timespec is record
+ tv_sec : time_t;
+ tv_nsec : long;
+ end record;
+ pragma Convention (C, timespec);
+
+ type clockid_t is new int;
+ CLOCK_REALTIME : constant clockid_t := 1;
+
+ type struct_timeval is record
+ tv_sec : time_t;
+ tv_usec : time_t;
+ end record;
+ pragma Convention (C, struct_timeval);
+
+ type cma_t_address is new System.Address;
+
+ type cma_t_handle is record
+ field1 : cma_t_address;
+ field2 : Short_Integer;
+ field3 : Short_Integer;
+ end record;
+ for cma_t_handle'Size use 64;
+
+ type pthread_attr_t is new cma_t_handle;
+ pragma Convention (C_Pass_By_Copy, pthread_attr_t);
+
+ type pthread_condattr_t is new cma_t_handle;
+ pragma Convention (C_Pass_By_Copy, pthread_condattr_t);
+
+ type pthread_mutexattr_t is new cma_t_handle;
+ pragma Convention (C_Pass_By_Copy, pthread_mutexattr_t);
+
+ type pthread_t is new cma_t_handle;
+ pragma Convention (C_Pass_By_Copy, pthread_t);
+
+ type pthread_mutex_t is new cma_t_handle;
+ pragma Convention (C_Pass_By_Copy, pthread_mutex_t);
+
+ type pthread_cond_t is new cma_t_handle;
+ pragma Convention (C_Pass_By_Copy, pthread_cond_t);
+
+ type pthread_key_t is new int;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-hpux.ads b/gcc/ada/s-osinte-hpux.ads
new file mode 100644
index 00000000000..95b093ae7fa
--- /dev/null
+++ b/gcc/ada/s-osinte-hpux.ads
@@ -0,0 +1,556 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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 is a HPUX 11.0 (Native THREADS) version of this package
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+with Interfaces.C;
+with Unchecked_Conversion;
+
+package System.OS_Interface is
+ pragma Preelaborate;
+
+ pragma Linker_Options ("-lpthread");
+
+ subtype int is Interfaces.C.int;
+ subtype short is Interfaces.C.short;
+ subtype long is Interfaces.C.long;
+ subtype unsigned is Interfaces.C.unsigned;
+ subtype unsigned_short is Interfaces.C.unsigned_short;
+ subtype unsigned_long is Interfaces.C.unsigned_long;
+ subtype unsigned_char is Interfaces.C.unsigned_char;
+ subtype plain_char is Interfaces.C.plain_char;
+ subtype size_t is Interfaces.C.size_t;
+
+ -----------
+ -- Errno --
+ -----------
+
+ function errno return int;
+ pragma Import (C, errno, "__get_errno");
+
+ EAGAIN : constant := 11;
+ EINTR : constant := 4;
+ EINVAL : constant := 22;
+ ENOMEM : constant := 12;
+ ETIMEDOUT : constant := 238;
+
+ -------------
+ -- Signals --
+ -------------
+
+ Max_Interrupt : constant := 44;
+ type Signal is new int range 0 .. Max_Interrupt;
+ for Signal'Size use int'Size;
+
+ SIGHUP : constant := 1; -- hangup
+ SIGINT : constant := 2; -- interrupt (rubout)
+ SIGQUIT : constant := 3; -- quit (ASCD FS)
+ SIGILL : constant := 4; -- illegal instruction (not reset)
+ SIGTRAP : constant := 5; -- trace trap (not reset)
+ SIGIOT : constant := 6; -- IOT instruction
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGEMT : constant := 7; -- EMT instruction
+ SIGFPE : constant := 8; -- floating point exception
+ SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
+ SIGBUS : constant := 10; -- bus error
+ SIGSEGV : constant := 11; -- segmentation violation
+ SIGSYS : constant := 12; -- bad argument to system call
+ SIGPIPE : constant := 13; -- write on a pipe with no one to read it
+ SIGALRM : constant := 14; -- alarm clock
+ SIGTERM : constant := 15; -- software termination signal from kill
+ SIGUSR1 : constant := 16; -- user defined signal 1
+ SIGUSR2 : constant := 17; -- user defined signal 2
+ SIGCLD : constant := 18; -- alias for SIGCHLD
+ SIGCHLD : constant := 18; -- child status change
+ SIGPWR : constant := 19; -- power-fail restart
+ SIGVTALRM : constant := 20; -- virtual timer alarm
+ SIGPROF : constant := 21; -- profiling timer alarm
+ SIGIO : constant := 22; -- asynchronous I/O
+ SIGPOLL : constant := 22; -- pollable event occurred
+ SIGWINCH : constant := 23; -- window size change
+ SIGSTOP : constant := 24; -- stop (cannot be caught or ignored)
+ SIGTSTP : constant := 25; -- user stop requested from tty
+ SIGCONT : constant := 26; -- stopped process has been continued
+ SIGTTIN : constant := 27; -- background tty read attempted
+ SIGTTOU : constant := 28; -- background tty write attempted
+ SIGURG : constant := 29; -- urgent condition on IO channel
+ SIGLOST : constant := 30; -- remote lock lost (NFS)
+ SIGDIL : constant := 32; -- DIL signal
+ SIGXCPU : constant := 33; -- CPU time limit exceeded (setrlimit)
+ SIGXFSZ : constant := 34; -- file size limit exceeded (setrlimit)
+ SIGCANCEL : constant := 35; -- used for pthread cancellation.
+ SIGGFAULT : constant := 36; -- Graphics framebuffer fault
+
+ SIGADAABORT : constant := SIGABRT;
+ -- Note: on other targets, we usually use SIGABRT, but on HPUX, it
+ -- appears that SIGABRT can't be used in sigwait(), so we use SIGTERM.
+
+ type Signal_Set is array (Natural range <>) of Signal;
+
+ Unmasked : constant Signal_Set :=
+ (SIGABRT, SIGPIPE, SIGBUS, SIGTRAP, SIGTTIN, SIGTTOU, SIGTSTP, SIGPROF,
+ SIGALRM, SIGVTALRM, SIGIO, SIGCHLD);
+
+ Reserved : constant Signal_Set := (SIGKILL, SIGSTOP);
+
+ type sigset_t is private;
+
+ function sigaddset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigaddset, "sigaddset");
+
+ function sigdelset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigdelset, "sigdelset");
+
+ function sigfillset (set : access sigset_t) return int;
+ pragma Import (C, sigfillset, "sigfillset");
+
+ function sigismember (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigismember, "sigismember");
+
+ function sigemptyset (set : access sigset_t) return int;
+ pragma Import (C, sigemptyset, "sigemptyset");
+
+ type struct_sigaction is record
+ sa_handler : System.Address;
+ sa_mask : sigset_t;
+ sa_flags : int;
+ end record;
+ pragma Convention (C, struct_sigaction);
+ type struct_sigaction_ptr is access all struct_sigaction;
+
+ SA_SIGINFO : constant := 16#10#;
+
+ SIG_BLOCK : constant := 0;
+ SIG_UNBLOCK : constant := 1;
+ SIG_SETMASK : constant := 2;
+
+ SIG_DFL : constant := 0;
+ SIG_IGN : constant := 1;
+
+ function sigaction
+ (sig : Signal;
+ act : struct_sigaction_ptr;
+ oact : struct_sigaction_ptr) return int;
+ pragma Import (C, sigaction, "sigaction");
+
+ ----------
+ -- Time --
+ ----------
+
+ Time_Slice_Supported : constant Boolean := True;
+ -- Indicates wether time slicing is supported
+
+ type timespec is private;
+
+ type clockid_t is private;
+
+ CLOCK_REALTIME : constant clockid_t;
+
+ function clock_gettime
+ (clock_id : clockid_t;
+ tp : access timespec) return int;
+ pragma Import (C, clock_gettime, "clock_gettime");
+
+ function clock_getres
+ (clock_id : clockid_t;
+ res : access timespec) return int;
+ pragma Import (C, clock_getres, "clock_getres");
+
+ function To_Duration (TS : timespec) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timespec (D : Duration) return timespec;
+ pragma Inline (To_Timespec);
+
+ type struct_timezone is record
+ tz_minuteswest : int;
+ tz_dsttime : int;
+ end record;
+ pragma Convention (C, struct_timezone);
+ type struct_timezone_ptr is access all struct_timezone;
+
+ type struct_timeval is private;
+ -- This is needed on systems that do not have clock_gettime()
+ -- but do have gettimeofday().
+
+ function To_Duration (TV : struct_timeval) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timeval (D : Duration) return struct_timeval;
+ pragma Inline (To_Timeval);
+
+ -------------------------
+ -- Priority Scheduling --
+ -------------------------
+
+ SCHED_FIFO : constant := 0;
+ SCHED_RR : constant := 1;
+ SCHED_OTHER : constant := 2;
+
+ -------------
+ -- Process --
+ -------------
+
+ type pid_t is private;
+
+ function kill (pid : pid_t; sig : Signal) return int;
+ pragma Import (C, kill, "kill");
+
+ function getpid return pid_t;
+ pragma Import (C, getpid, "getpid");
+
+ ---------
+ -- LWP --
+ ---------
+
+ function lwp_self return System.Address;
+ pragma Import (C, lwp_self, "_lwp_self");
+
+ -------------
+ -- Threads --
+ -------------
+
+ type Thread_Body is access
+ function (arg : System.Address) return System.Address;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ type pthread_t is private;
+ subtype Thread_Id is pthread_t;
+
+ type pthread_mutex_t is limited private;
+ type pthread_cond_t is limited private;
+ type pthread_attr_t is limited private;
+ type pthread_mutexattr_t is limited private;
+ type pthread_condattr_t is limited private;
+ type pthread_key_t is private;
+
+ PTHREAD_CREATE_DETACHED : constant := 16#de#;
+
+ -----------
+ -- Stack --
+ -----------
+
+ Stack_Base_Available : constant Boolean := False;
+ -- Indicates wether the stack base is available on this target.
+
+ function Get_Stack_Base (thread : pthread_t) return Address;
+ pragma Inline (Get_Stack_Base);
+ -- returns the stack base of the specified thread.
+ -- Only call this function when Stack_Base_Available is True.
+
+ 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
+
+ PROT_NONE : constant := 0;
+ PROT_READ : constant := 1;
+ PROT_WRITE : constant := 2;
+ PROT_EXEC : constant := 4;
+ PROT_ALL : constant := PROT_READ + PROT_WRITE + PROT_EXEC;
+
+ PROT_ON : constant := PROT_READ;
+ PROT_OFF : constant := PROT_ALL;
+
+ function mprotect (addr : Address; len : size_t; prot : int) return int;
+ pragma Import (C, mprotect);
+
+ ---------------------------------------
+ -- Nonstandard Thread Initialization --
+ ---------------------------------------
+
+ procedure pthread_init;
+ pragma Inline (pthread_init);
+ -- This is a dummy procedure to share some GNULLI files
+
+ -------------------------
+ -- POSIX.1c Section 3 --
+ -------------------------
+
+ function sigwait
+ (set : access sigset_t;
+ sig : access Signal) return int;
+ pragma Import (C, sigwait, "sigwait");
+
+ function pthread_kill
+ (thread : pthread_t;
+ sig : Signal) return int;
+ pragma Import (C, pthread_kill, "pthread_kill");
+
+ type sigset_t_ptr is access all sigset_t;
+
+ function pthread_sigmask
+ (how : int;
+ set : sigset_t_ptr;
+ oset : sigset_t_ptr) return int;
+ pragma Import (C, pthread_sigmask, "pthread_sigmask");
+
+ --------------------------
+ -- POSIX.1c Section 11 --
+ --------------------------
+
+ function pthread_mutexattr_init
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_init, "pthread_mutexattr_init");
+
+ function pthread_mutexattr_destroy
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_destroy, "pthread_mutexattr_destroy");
+
+ function pthread_mutex_init
+ (mutex : access pthread_mutex_t;
+ attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutex_init, "pthread_mutex_init");
+
+ function pthread_mutex_destroy (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_destroy, "pthread_mutex_destroy");
+
+ function pthread_mutex_lock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_lock, "pthread_mutex_lock");
+
+ function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_unlock, "pthread_mutex_unlock");
+
+ function pthread_condattr_init
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_init, "pthread_condattr_init");
+
+ function pthread_condattr_destroy
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_destroy, "pthread_condattr_destroy");
+
+ function pthread_cond_init
+ (cond : access pthread_cond_t;
+ attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_cond_init, "pthread_cond_init");
+
+ function pthread_cond_destroy (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_destroy, "pthread_cond_destroy");
+
+ function pthread_cond_signal (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_signal, "pthread_cond_signal");
+
+ function pthread_cond_wait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_cond_wait, "pthread_cond_wait");
+
+ function pthread_cond_timedwait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ abstime : access timespec) return int;
+ pragma Import (C, pthread_cond_timedwait, "pthread_cond_timedwait");
+
+ Relative_Timed_Wait : constant Boolean := False;
+ -- pthread_cond_timedwait requires an absolute delay time
+
+ ----------------------------
+ -- POSIX.1c Section 13 --
+ ----------------------------
+
+ PTHREAD_PRIO_NONE : constant := 16#100#;
+ PTHREAD_PRIO_PROTECT : constant := 16#200#;
+ PTHREAD_PRIO_INHERIT : constant := 16#400#;
+
+ function pthread_mutexattr_setprotocol
+ (attr : access pthread_mutexattr_t;
+ protocol : int) return int;
+ pragma Import (C, pthread_mutexattr_setprotocol);
+
+ function pthread_mutexattr_setprioceiling
+ (attr : access pthread_mutexattr_t;
+ prioceiling : int) return int;
+ pragma Import (C, pthread_mutexattr_setprioceiling);
+
+ type Array_7_Int is array (0 .. 6) of int;
+ type struct_sched_param is record
+ sched_priority : int;
+ sched_reserved : Array_7_Int;
+ end record;
+
+ function pthread_setschedparam
+ (thread : pthread_t;
+ policy : int;
+ param : access struct_sched_param)
+ return int;
+ pragma Import (C, pthread_setschedparam, "pthread_setschedparam");
+
+ function pthread_attr_setscope
+ (attr : access pthread_attr_t;
+ contentionscope : int) return int;
+ pragma Import (C, pthread_attr_setscope, "pthread_attr_setscope");
+
+ function pthread_attr_setinheritsched
+ (attr : access pthread_attr_t;
+ inheritsched : int) return int;
+ pragma Import (C, pthread_attr_setinheritsched);
+
+ function pthread_attr_setschedpolicy
+ (attr : access pthread_attr_t;
+ policy : int) return int;
+ pragma Import (C, pthread_attr_setschedpolicy);
+
+ function sched_yield return int;
+ pragma Import (C, sched_yield, "sched_yield");
+
+ ---------------------------
+ -- P1003.1c - Section 16 --
+ ---------------------------
+
+ function pthread_attr_init
+ (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_init, "__pthread_attr_init_system");
+
+ function pthread_attr_destroy
+ (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_destroy, "pthread_attr_destroy");
+
+ function pthread_attr_setdetachstate
+ (attr : access pthread_attr_t;
+ detachstate : int) return int;
+ pragma Import (C, pthread_attr_setdetachstate);
+
+ function pthread_attr_setstacksize
+ (attr : access pthread_attr_t;
+ stacksize : size_t) return int;
+ pragma Import (C, pthread_attr_setstacksize, "pthread_attr_setstacksize");
+
+ function pthread_create
+ (thread : access pthread_t;
+ attributes : access pthread_attr_t;
+ start_routine : Thread_Body;
+ arg : System.Address) return int;
+ pragma Import (C, pthread_create, "__pthread_create_system");
+
+ procedure pthread_exit (status : System.Address);
+ pragma Import (C, pthread_exit, "pthread_exit");
+
+ function pthread_self return pthread_t;
+ pragma Import (C, pthread_self, "pthread_self");
+
+ --------------------------
+ -- POSIX.1c Section 17 --
+ --------------------------
+
+ function pthread_setspecific
+ (key : pthread_key_t;
+ value : System.Address) return int;
+ pragma Import (C, pthread_setspecific, "pthread_setspecific");
+
+ function pthread_getspecific (key : pthread_key_t) return System.Address;
+ pragma Import (C, pthread_getspecific, "pthread_getspecific");
+
+ type destructor_pointer is access procedure (arg : System.Address);
+
+ function pthread_key_create
+ (key : access pthread_key_t;
+ destructor : destructor_pointer) return int;
+ pragma Import (C, pthread_key_create, "pthread_key_create");
+
+private
+
+ type unsigned_int_array_8 is array (0 .. 7) of unsigned;
+ type sigset_t is record
+ sigset : unsigned_int_array_8;
+ end record;
+ pragma Convention (C_Pass_By_Copy, sigset_t);
+
+ type pid_t is new int;
+
+ type time_t is new long;
+
+ type timespec is record
+ tv_sec : time_t;
+ tv_nsec : long;
+ end record;
+ pragma Convention (C, timespec);
+
+ type clockid_t is new int;
+ CLOCK_REALTIME : constant clockid_t := 1;
+
+ type struct_timeval is record
+ tv_sec : time_t;
+ tv_usec : time_t;
+ end record;
+ pragma Convention (C, struct_timeval);
+
+ type pthread_attr_t is new int;
+ type pthread_condattr_t is new int;
+ type pthread_mutexattr_t is new int;
+ type pthread_t is new int;
+
+ type short_array is array (Natural range <>) of short;
+ type int_array is array (Natural range <>) of int;
+
+ type pthread_mutex_t is record
+ m_short : short_array (0 .. 1);
+ m_int : int;
+ m_int1 : int_array (0 .. 3);
+ m_pad : int; -- needed for 32 bit ABI, but *not* for 64 bit
+ m_ptr : System.Address;
+ m_int2 : int_array (0 .. 1);
+ m_int3 : int_array (0 .. 3);
+ m_short2 : short_array (0 .. 1);
+ m_int4 : int_array (0 .. 4);
+ m_int5 : int_array (0 .. 1);
+ end record;
+ pragma Convention (C, pthread_mutex_t);
+
+ type pthread_cond_t is record
+ c_short : short_array (0 .. 1);
+ c_int : int;
+ c_int1 : int_array (0 .. 3);
+ m_pad : int; -- needed for 32 bit ABI, but *not* for 64 bit
+ m_ptr : System.Address;
+ c_int2 : int_array (0 .. 1);
+ c_int3 : int_array (0 .. 1);
+ c_int4 : int_array (0 .. 1);
+ end record;
+ pragma Convention (C, pthread_cond_t);
+
+ type pthread_key_t is new int;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-interix.ads b/gcc/ada/s-osinte-interix.ads
new file mode 100644
index 00000000000..4e5d9567df3
--- /dev/null
+++ b/gcc/ada/s-osinte-interix.ads
@@ -0,0 +1,574 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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 is a OpenNT/Interix (FSU THREADS) version of this package
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+with Interfaces.C;
+with Unchecked_Conversion;
+
+package System.OS_Interface is
+ pragma Preelaborate;
+
+ pragma Linker_Options ("-lgthreads");
+ pragma Linker_Options ("-lmalloc");
+
+ subtype int is Interfaces.C.int;
+ subtype short is Interfaces.C.short;
+ subtype long is Interfaces.C.long;
+ subtype unsigned is Interfaces.C.unsigned;
+ subtype unsigned_short is Interfaces.C.unsigned_short;
+ subtype unsigned_long is Interfaces.C.unsigned_long;
+ subtype unsigned_char is Interfaces.C.unsigned_char;
+ subtype plain_char is Interfaces.C.plain_char;
+ subtype size_t is Interfaces.C.size_t;
+
+ -----------
+ -- Errno --
+ -----------
+
+ function errno return int;
+ pragma Import (C, errno, "__get_errno");
+
+ EAGAIN : constant := 11;
+ EINTR : constant := 4;
+ EINVAL : constant := 22;
+ ENOMEM : constant := 12;
+ ETIMEDOUT : constant := 60;
+
+ -------------
+ -- Signals --
+ -------------
+
+ Max_Interrupt : constant := 31;
+ type Signal is new int range 0 .. Max_Interrupt;
+ for Signal'Size use int'Size;
+
+ SIGHUP : constant := 1; -- hangup
+ SIGINT : constant := 2; -- interrupt (rubout)
+ SIGQUIT : constant := 3; -- quit (ASCD FS)
+ SIGILL : constant := 4; -- illegal instruction (not reset)
+ SIGTRAP : constant := 5; -- trace trap (not reset)
+ SIGIOT : constant := 6; -- IOT instruction
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGEMT : constant := 0; -- EMT instruction
+ SIGFPE : constant := 8; -- floating point exception
+ SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
+ SIGBUS : constant := 10; -- bus error
+ SIGSEGV : constant := 11; -- segmentation violation
+ SIGSYS : constant := 12; -- bad argument to system call
+ SIGPIPE : constant := 13; -- write on a pipe with no one to read it
+ SIGALRM : constant := 14; -- alarm clock
+ SIGTERM : constant := 15; -- software termination signal from kill
+ SIGUSR1 : constant := 16; -- user defined signal 1
+ SIGUSR2 : constant := 17; -- user defined signal 2
+ SIGCLD : constant := 18; -- alias for SIGCHLD
+ SIGCHLD : constant := 18; -- child status change
+ SIGPWR : constant := 0; -- power-fail restart
+ SIGWINCH : constant := 20; -- window size change
+ SIGURG : constant := 21; -- urgent condition on IO channel
+ SIGPOLL : constant := 22; -- pollable event occurred
+ SIGIO : constant := 19; -- I/O possible (Solaris SIGPOLL alias)
+ SIGSTOP : constant := 23; -- stop (cannot be caught or ignored)
+ SIGTSTP : constant := 24; -- user stop requested from tty
+ SIGCONT : constant := 25; -- stopped process has been continued
+ SIGTTIN : constant := 26; -- background tty read attempted
+ SIGTTOU : constant := 27; -- background tty write attempted
+ SIGVTALRM : constant := 28; -- virtual timer expired
+ SIGPROF : constant := 29; -- profiling timer expired
+ SIGXCPU : constant := 30; -- CPU time limit exceeded
+ SIGXFSZ : constant := 31; -- filesize limit exceeded
+
+ SIGADAABORT : constant := SIGABRT;
+
+ type Signal_Set is array (Natural range <>) of Signal;
+
+ Unmasked : constant Signal_Set :=
+ (SIGTRAP, SIGALRM, SIGVTALRM, SIGTTIN, SIGTTOU, SIGTSTP, SIGPROF);
+
+ Reserved : constant Signal_Set := (SIGKILL, SIGSTOP);
+
+ type sigset_t is private;
+
+ function sigaddset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigaddset, "sigaddset");
+
+ function sigdelset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigdelset, "sigdelset");
+
+ function sigfillset (set : access sigset_t) return int;
+ pragma Import (C, sigfillset, "sigfillset");
+
+ function sigismember (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigismember, "sigismember");
+
+ function sigemptyset (set : access sigset_t) return int;
+ pragma Import (C, sigemptyset, "sigemptyset");
+
+ type struct_sigaction is record
+ sa_handler : System.Address;
+ sa_mask : sigset_t;
+ sa_flags : int;
+ sa_restorer : System.Address;
+ end record;
+ pragma Convention (C, struct_sigaction);
+ type struct_sigaction_ptr is access all struct_sigaction;
+
+ SIG_BLOCK : constant := 1;
+ SIG_UNBLOCK : constant := 2;
+ SIG_SETMASK : constant := 3;
+
+ SIG_DFL : constant := 0;
+ SIG_IGN : constant := 1;
+
+ SA_SIGINFO : constant := 0;
+ -- Dummy constant for a sa_flags bit. A proper definition is needed only
+ -- for the GCC/ZCX EH scheme (see System.Interrupt_Management).
+
+ function sigaction
+ (sig : Signal;
+ act : struct_sigaction_ptr;
+ oact : struct_sigaction_ptr) return int;
+ -- FSU pthreads redefines sigaction and then uses a special syscall
+ -- API to call the system version. Doing syscalls on OpenNT is very
+ -- difficult, so we rename the pthread version instead.
+ pragma Import (C, sigaction, "pthread_wrapper_sigaction");
+
+ ----------
+ -- Time --
+ ----------
+
+ Time_Slice_Supported : constant Boolean := False;
+ -- Indicates wether time slicing is supported (i.e FSU threads have been
+ -- compiled with DEF_RR)
+
+ type timespec is private;
+
+ type clockid_t is private;
+
+ CLOCK_REALTIME : constant clockid_t;
+
+ function clock_gettime
+ (clock_id : clockid_t;
+ tp : access timespec) return int;
+ pragma Import (C, clock_gettime, "clock_gettime");
+
+ function To_Duration (TS : timespec) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timespec (D : Duration) return timespec;
+ pragma Inline (To_Timespec);
+
+ type struct_timeval is private;
+
+ function To_Duration (TV : struct_timeval) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timeval (D : Duration) return struct_timeval;
+ pragma Inline (To_Timeval);
+
+ -------------------------
+ -- Priority Scheduling --
+ -------------------------
+
+ SCHED_FIFO : constant := 0;
+ SCHED_RR : constant := 1;
+ SCHED_OTHER : constant := 2;
+
+ -------------
+ -- Process --
+ -------------
+
+ type pid_t is private;
+
+ function kill (pid : pid_t; sig : Signal) return int;
+ pragma Import (C, kill, "kill");
+
+ function getpid return pid_t;
+ pragma Import (C, getpid, "getpid");
+
+ ---------
+ -- LWP --
+ ---------
+
+ function lwp_self return System.Address;
+ -- lwp_self does not exist on this thread library, revert to pthread_self
+ -- which is the closest approximation (with getpid). This function is
+ -- needed to share 7staprop.adb across POSIX-like targets.
+ pragma Import (C, lwp_self, "pthread_self");
+
+ -------------
+ -- Threads --
+ -------------
+
+ type Thread_Body is access
+ function (arg : System.Address) return System.Address;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ type pthread_t is private;
+ subtype Thread_Id is pthread_t;
+
+ type pthread_mutex_t is limited private;
+ type pthread_cond_t is limited private;
+ type pthread_attr_t is limited private;
+ type pthread_mutexattr_t is limited private;
+ type pthread_condattr_t is limited private;
+ type pthread_key_t is private;
+
+ PTHREAD_CREATE_DETACHED : constant := 1;
+ PTHREAD_CREATE_JOINABLE : constant := 0;
+
+ -----------
+ -- Stack --
+ -----------
+
+ Stack_Base_Available : constant Boolean := False;
+ -- Indicates wether the stack base is available on this target.
+ -- This allows us to share s-osinte.adb between all the FSU run time.
+ -- Note that this value can only be true if pthread_t has a complete
+ -- definition that corresponds exactly to the C header files.
+
+ function Get_Stack_Base (thread : pthread_t) return Address;
+ pragma Inline (Get_Stack_Base);
+ -- returns the stack base of the specified thread.
+ -- Only call this function when Stack_Base_Available is True.
+
+ 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
+
+ PROT_NONE : constant := 0;
+ PROT_READ : constant := 1;
+ PROT_WRITE : constant := 2;
+ PROT_EXEC : constant := 4;
+ PROT_ALL : constant := PROT_READ + PROT_WRITE + PROT_EXEC;
+
+ PROT_ON : constant := PROT_NONE;
+ PROT_OFF : constant := PROT_ALL;
+
+ function mprotect (addr : Address; len : size_t; prot : int) return int;
+ pragma Import (C, mprotect);
+
+ ---------------------------------------
+ -- Nonstandard Thread Initialization --
+ ---------------------------------------
+
+ procedure pthread_init;
+ -- FSU_THREADS requires pthread_init, which is nonstandard
+ -- and this should be invoked during the elaboration of s-taprop.adb
+ pragma Import (C, pthread_init, "pthread_init");
+
+ -------------------------
+ -- POSIX.1c Section 3 --
+ -------------------------
+
+ function sigwait
+ (set : access sigset_t;
+ sig : access Signal) return int;
+ -- FSU_THREADS has a nonstandard sigwait
+
+ function pthread_kill
+ (thread : pthread_t;
+ sig : Signal) return int;
+ pragma Import (C, pthread_kill, "pthread_kill");
+
+ type sigset_t_ptr is access all sigset_t;
+
+ function pthread_sigmask
+ (how : int;
+ set : sigset_t_ptr;
+ oset : sigset_t_ptr) return int;
+ pragma Import (C, pthread_sigmask, "pthread_wrapper_sigprocmask");
+
+ --------------------------
+ -- POSIX.1c Section 11 --
+ --------------------------
+
+ function pthread_mutexattr_init
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_init, "pthread_mutexattr_init");
+
+ function pthread_mutexattr_destroy
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_destroy, "pthread_mutexattr_destroy");
+
+ function pthread_mutex_init
+ (mutex : access pthread_mutex_t;
+ attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutex_init, "pthread_mutex_init");
+
+ function pthread_mutex_destroy (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_destroy, "pthread_mutex_destroy");
+
+ function pthread_mutex_lock (mutex : access pthread_mutex_t) return int;
+ -- FSU_THREADS has nonstandard pthread_mutex_lock
+
+ function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int;
+ -- FSU_THREADS has nonstandard pthread_mutex_lock
+
+ function pthread_condattr_init
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_init, "pthread_condattr_init");
+
+ function pthread_condattr_destroy
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_destroy, "pthread_condattr_destroy");
+
+ function pthread_cond_init
+ (cond : access pthread_cond_t;
+ attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_cond_init, "pthread_cond_init");
+
+ function pthread_cond_destroy (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_destroy, "pthread_cond_destroy");
+
+ function pthread_cond_signal (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_signal, "pthread_cond_signal");
+
+ function pthread_cond_wait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t) return int;
+ -- FSU_THREADS has a nonstandard pthread_cond_wait
+
+ function pthread_cond_timedwait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ abstime : access timespec) return int;
+ -- FSU_THREADS has a nonstandard pthread_cond_timedwait
+
+ Relative_Timed_Wait : constant Boolean := False;
+ -- pthread_cond_timedwait requires an absolute delay time
+
+ --------------------------
+ -- POSIX.1c Section 13 --
+ --------------------------
+
+ PTHREAD_PRIO_NONE : constant := 0;
+ PTHREAD_PRIO_PROTECT : constant := 2;
+ PTHREAD_PRIO_INHERIT : constant := 1;
+
+ function pthread_mutexattr_setprotocol
+ (attr : access pthread_mutexattr_t;
+ protocol : int) return int;
+ pragma Import (C, pthread_mutexattr_setprotocol);
+
+ function pthread_mutexattr_setprioceiling
+ (attr : access pthread_mutexattr_t;
+ prioceiling : int) return int;
+ pragma Import
+ (C, pthread_mutexattr_setprioceiling,
+ "pthread_mutexattr_setprio_ceiling");
+
+ type struct_sched_param is record
+ sched_priority : int; -- scheduling priority
+ end record;
+
+ function pthread_setschedparam
+ (thread : pthread_t;
+ policy : int;
+ param : access struct_sched_param) return int;
+ -- FSU_THREADS does not have pthread_setschedparam
+
+ function pthread_attr_setscope
+ (attr : access pthread_attr_t;
+ contentionscope : int) return int;
+ pragma Import (C, pthread_attr_setscope, "pthread_attr_setscope");
+
+ function pthread_attr_setinheritsched
+ (attr : access pthread_attr_t;
+ inheritsched : int) return int;
+ pragma Import (C, pthread_attr_setinheritsched);
+
+ function pthread_attr_setschedpolicy
+ (attr : access pthread_attr_t;
+ policy : int) return int;
+ pragma Import
+ (C, pthread_attr_setschedpolicy, "pthread_attr_setsched");
+
+ function sched_yield return int;
+ -- FSU_THREADS does not have sched_yield;
+
+ ---------------------------
+ -- P1003.1c - Section 16 --
+ ---------------------------
+
+ function pthread_attr_init (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_init, "pthread_attr_init");
+
+ function pthread_attr_destroy
+ (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_destroy, "pthread_attr_destroy");
+
+ function pthread_attr_setdetachstate
+ (attr : access pthread_attr_t;
+ detachstate : int) return int;
+ -- FSU_THREADS has a nonstandard pthread_attr_setdetachstate
+
+ function pthread_attr_setstacksize
+ (attr : access pthread_attr_t;
+ stacksize : size_t) return int;
+ pragma Import (C, pthread_attr_setstacksize);
+
+ function pthread_create
+ (thread : access pthread_t;
+ attributes : access pthread_attr_t;
+ start_routine : Thread_Body;
+ arg : System.Address) return int;
+ pragma Import (C, pthread_create, "pthread_create");
+
+ procedure pthread_exit (status : System.Address);
+ pragma Import (C, pthread_exit, "pthread_exit");
+
+ function pthread_self return pthread_t;
+ pragma Import (C, pthread_self, "pthread_self");
+
+ --------------------------
+ -- POSIX.1c Section 17 --
+ --------------------------
+
+ function pthread_setspecific
+ (key : pthread_key_t;
+ value : System.Address) return int;
+ pragma Import (C, pthread_setspecific, "pthread_setspecific");
+
+ function pthread_getspecific (key : pthread_key_t) return System.Address;
+ -- FSU_THREADS has a nonstandard pthread_getspecific
+
+ type destructor_pointer is access procedure (arg : System.Address);
+
+ function pthread_key_create
+ (key : access pthread_key_t;
+ destructor : destructor_pointer) return int;
+ pragma Import (C, pthread_key_create, "pthread_key_create");
+
+private
+
+ type sigset_t is new unsigned_long;
+ pragma Convention (C, sigset_t);
+
+ type pid_t is new int;
+
+ subtype time_t is long;
+
+ type timespec is record
+ tv_sec : time_t;
+ tv_nsec : long;
+ end record;
+ pragma Convention (C, timespec);
+
+ type clockid_t is new int;
+ CLOCK_REALTIME : constant clockid_t := 0;
+
+ type struct_timeval is record
+ tv_sec : time_t;
+ tv_usec : long;
+ end record;
+ pragma Convention (C, struct_timeval);
+
+ type pthread_attr_t is record
+ flags : int;
+ stacksize : int;
+ contentionscope : int;
+ inheritsched : int;
+ detachstate : int;
+ sched : int;
+ prio : int;
+ starttime : timespec;
+ deadline : timespec;
+ period : timespec;
+ end record;
+ pragma Convention (C_Pass_By_Copy, pthread_attr_t);
+
+ type pthread_condattr_t is record
+ flags : int;
+ end record;
+ pragma Convention (C, pthread_condattr_t);
+
+ type pthread_mutexattr_t is record
+ flags : int;
+ prio_ceiling : int;
+ protocol : int;
+ end record;
+ pragma Convention (C, pthread_mutexattr_t);
+
+ type sigjmp_buf is array (Integer range 0 .. 17) of int;
+
+ type pthread_t_struct is record
+ context : sigjmp_buf;
+ pbody : sigjmp_buf;
+ errno : int;
+ ret : int;
+ stack_base : System.Address;
+ end record;
+ pragma Convention (C, pthread_t_struct);
+
+ type pthread_t is access all pthread_t_struct;
+
+ type queue_t is record
+ head : System.Address;
+ tail : System.Address;
+ end record;
+ pragma Convention (C, queue_t);
+
+ type pthread_mutex_t is record
+ queue : queue_t;
+ lock : plain_char;
+ owner : System.Address;
+ flags : int;
+ prio_ceiling : int;
+ protocol : int;
+ prev_max_ceiling_prio : int;
+ end record;
+ pragma Convention (C, pthread_mutex_t);
+
+ type pthread_cond_t is record
+ queue : queue_t;
+ flags : int;
+ waiters : int;
+ mutex : System.Address;
+ end record;
+ pragma Convention (C, pthread_cond_t);
+
+ type pthread_key_t is new int;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-irix-athread.ads b/gcc/ada/s-osinte-irix-athread.ads
new file mode 100644
index 00000000000..e6df06813d7
--- /dev/null
+++ b/gcc/ada/s-osinte-irix-athread.ads
@@ -0,0 +1,699 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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 is an Irix (old pthread library) version of this package
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+with Interfaces;
+with Interfaces.C;
+with Interfaces.C.Strings;
+with Unchecked_Conversion;
+
+package System.OS_Interface is
+
+ pragma Preelaborate;
+
+ pragma Linker_Options ("-lathread");
+
+ subtype int is Interfaces.C.int;
+ subtype short is Interfaces.C.short;
+ subtype long is Interfaces.C.long;
+ subtype unsigned is Interfaces.C.unsigned;
+ subtype unsigned_short is Interfaces.C.unsigned_short;
+ subtype unsigned_long is Interfaces.C.unsigned_long;
+ subtype unsigned_char is Interfaces.C.unsigned_char;
+ subtype plain_char is Interfaces.C.plain_char;
+ subtype size_t is Interfaces.C.size_t;
+ subtype chars_ptr is Interfaces.C.Strings.chars_ptr;
+
+ -----------
+ -- Errno --
+ -----------
+
+ function errno return int;
+ pragma Import (C, errno, "__get_errno");
+
+ EINTR : constant := 4; -- interrupted system call
+ EAGAIN : constant := 11; -- No more processes
+ ENOMEM : constant := 12; -- Not enough core
+ EINVAL : constant := 22; -- Invalid argument
+ ETIMEDOUT : constant := 145; -- Connection timed out
+
+ -------------
+ -- Signals --
+ -------------
+
+ Max_Interrupt : constant := 64;
+ type Signal is new int range 0 .. Max_Interrupt;
+ for Signal'Size use int'Size;
+
+ SIGHUP : constant := 1; -- hangup
+ SIGINT : constant := 2; -- interrupt (rubout)
+ SIGQUIT : constant := 3; -- quit (ASCD FS)
+ SIGILL : constant := 4; -- illegal instruction (not reset)
+ SIGTRAP : constant := 5; -- trace trap (not reset)
+ SIGIOT : constant := 6; -- IOT instruction
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the
+ -- future
+ SIGEMT : constant := 7; -- EMT instruction
+ SIGFPE : constant := 8; -- floating point exception
+ SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
+ SIGBUS : constant := 10; -- bus error
+ SIGSEGV : constant := 11; -- segmentation violation
+ SIGSYS : constant := 12; -- bad argument to system call
+ SIGPIPE : constant := 13; -- write on a pipe with no one to read it
+ SIGALRM : constant := 14; -- alarm clock
+ SIGTERM : constant := 15; -- software termination signal from kill
+ SIGUSR1 : constant := 16; -- user defined signal 1
+ SIGUSR2 : constant := 17; -- user defined signal 2
+ SIGCLD : constant := 18; -- alias for SIGCHLD
+ SIGCHLD : constant := 18; -- child status change
+ SIGPWR : constant := 19; -- power-fail restart
+ SIGWINCH : constant := 20; -- window size change
+ SIGURG : constant := 21; -- urgent condition on IO channel
+ SIGPOLL : constant := 22; -- pollable event occurred
+ SIGIO : constant := 22; -- I/O possible (Solaris SIGPOLL alias)
+ SIGSTOP : constant := 23; -- stop (cannot be caught or ignored)
+ SIGTSTP : constant := 24; -- user stop requested from tty
+ SIGCONT : constant := 25; -- stopped process has been continued
+ SIGTTIN : constant := 26; -- background tty read attempted
+ SIGTTOU : constant := 27; -- background tty write attempted
+ SIGVTALRM : constant := 28; -- virtual timer expired
+ SIGPROF : constant := 29; -- profiling timer expired
+ SIGXCPU : constant := 30; -- CPU time limit exceeded
+ SIGXFSZ : constant := 31; -- filesize limit exceeded
+ SIGK32 : constant := 32; -- reserved for kernel (IRIX)
+ SIGCKPT : constant := 33; -- Checkpoint warning
+ SIGRESTART : constant := 34; -- Restart warning
+ SIGUME : constant := 35; -- Uncorrectable memory error
+ -- Signals defined for Posix 1003.1c.
+ SIGPTINTR : constant := 47;
+ SIGPTRESCHED : constant := 48;
+ -- Posix 1003.1b signals
+ SIGRTMIN : constant := 49; -- Posix 1003.1b signals
+ SIGRTMAX : constant := 64; -- Posix 1003.1b signals
+
+ type sigset_t is private;
+ type sigset_t_ptr is access all sigset_t;
+
+ function sigaddset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigaddset, "sigaddset");
+
+ function sigdelset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigdelset, "sigdelset");
+
+ function sigfillset (set : access sigset_t) return int;
+ pragma Import (C, sigfillset, "sigfillset");
+
+ function sigismember (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigismember, "sigismember");
+
+ function sigemptyset (set : access sigset_t) return int;
+ pragma Import (C, sigemptyset, "sigemptyset");
+
+ type siginfo_t is record
+ si_signo : int;
+ si_code : int;
+ si_errno : int;
+ bit_field_substitute_1 : String (1 .. 116);
+ end record;
+ pragma Convention (C, siginfo_t);
+
+ type array_type_2 is array (Integer range 0 .. 1) of int;
+ type struct_sigaction is record
+ sa_flags : int;
+ sa_handler : System.Address;
+ sa_mask : sigset_t;
+ sa_resv : array_type_2;
+ end record;
+ pragma Convention (C, struct_sigaction);
+ type struct_sigaction_ptr is access all struct_sigaction;
+
+ SIG_BLOCK : constant := 1;
+ SIG_UNBLOCK : constant := 2;
+ SIG_SETMASK : constant := 3;
+
+ SIG_DFL : constant := 0;
+ SIG_IGN : constant := 1;
+
+ function sigaction
+ (sig : Signal;
+ act : struct_sigaction_ptr;
+ oact : struct_sigaction_ptr := null) return int;
+ pragma Import (C, sigaction, "sigaction");
+
+ ----------
+ -- Time --
+ ----------
+
+ type time_t is new int;
+
+ type timespec is record
+ tv_sec : time_t;
+ tv_nsec : long;
+ end record;
+ pragma Convention (C, timespec);
+ type timespec_ptr is access all timespec;
+
+ function To_Duration (TS : timespec) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timespec (D : Duration) return timespec;
+ pragma Inline (To_Timespec);
+
+ type timer_t is new Integer;
+ type clockid_t is private;
+
+ CLOCK_REALTIME : constant clockid_t;
+ CLOCK_SGI_FAST : constant clockid_t;
+ CLOCK_SGI_CYCLE : constant clockid_t;
+
+ SGI_CYCLECNTR_SIZE : constant := 165;
+ function syssgi (request : Interfaces.C.int) return Interfaces.C.ptrdiff_t;
+
+ pragma Import (C, syssgi, "syssgi");
+
+ function clock_gettime
+ (clock_id : clockid_t;
+ tp : access timespec) return int;
+ pragma Import (C, clock_gettime, "clock_gettime");
+
+ function clock_getres
+ (clock_id : clockid_t; tp : access timespec) return int;
+ pragma Import (C, clock_getres, "clock_getres");
+
+ type struct_timeval is record
+ tv_sec : time_t;
+ tv_usec : time_t;
+ end record;
+ pragma Convention (C, struct_timeval);
+
+ function To_Duration (TV : struct_timeval) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timeval (D : Duration) return struct_timeval;
+ pragma Inline (To_Timeval);
+
+ function gettimeofday
+ (tv : access struct_timeval;
+ tz : System.Address := System.Null_Address) return int;
+ pragma Import (C, gettimeofday, "gettimeofday");
+
+ -------------------------
+ -- Priority Scheduling --
+ -------------------------
+
+ SCHED_FIFO : constant := 0;
+ SCHED_RR : constant := 0;
+ SCHED_OTHER : constant := 0;
+
+ -------------
+ -- Process --
+ -------------
+
+ type pid_t is private;
+
+ function kill (pid : pid_t; sig : Signal) return int;
+ pragma Import (C, kill, "kill");
+
+ function getpid return pid_t;
+ pragma Import (C, getpid, "getpid");
+
+ ---------------------------------------
+ -- Nonstandard Thread Initialization --
+ ---------------------------------------
+
+ procedure pthread_init;
+ pragma Inline (pthread_init);
+ -- This is a dummy procedure to share some GNULLI files
+
+ -------------
+ -- Threads --
+ -------------
+
+ type Thread_Body is access
+ function (arg : System.Address) return System.Address;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ type pthread_t is private; -- thread identifier
+ subtype Thread_Id is pthread_t;
+
+ type pthread_mutex_t is private; -- mutex identifier
+ type pthread_cond_t is private; -- cond identifier
+ type pthread_attr_t is private; -- pthread attributes
+ type pthread_mutexattr_t is private; -- mutex attributes
+ type pthread_condattr_t is private; -- mutex attributes
+ type sem_t is private; -- semaphore identifier
+ type pthread_key_t is private; -- per thread key
+
+ subtype pthread_once_t is int; -- dynamic package initialization
+ subtype resource_t is long; -- sproc. resource info.
+ type start_addr is access function (arg : Address) return Address;
+ type sproc_start_addr is access function (arg : Address) return int;
+ type callout_addr is
+ access function (arg : Address; arg1 : Address) return Address;
+
+ -- SGI specific types
+
+ subtype sproc_t is Address; -- sproc identifier
+ subtype sproc_attr_t is Address; -- sproc attributes
+
+ subtype spcb_p is Address;
+ subtype ptcb_p is Address;
+
+ -- Pthread Error Types
+
+ FUNC_OK : constant := 0;
+ FUNC_ERR : constant := -1;
+
+ -- pthread run-time initialization data structure
+
+ type pthread_init_struct is record
+ conf_initsize : int; -- shared area size
+ max_sproc_count : int; -- maximum number of sprocs
+ sproc_stack_size : size_t; -- sproc stack size
+ os_default_priority : int; -- default IRIX pri for main process
+ os_sched_signal : int; -- default OS scheduling signal
+ guard_pages : int; -- number of guard pages per stack
+ init_sproc_count : int; -- initial number of sprocs
+ end record;
+
+ --
+ -- Pthread Attribute Initialize / Destroy
+ --
+
+ function pthread_attr_init (attr : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_init, "pthread_attr_init");
+
+ function pthread_attr_destroy (attr : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_destroy, "pthread_attr_destroy");
+
+ --
+ -- Thread Attributes
+ --
+
+ function pthread_attr_setstacksize
+ (attr : access pthread_attr_t; stacksize : size_t) return int;
+ pragma Import (C, pthread_attr_setstacksize, "pthread_attr_setstacksize");
+
+ function pthread_attr_setdetachstate
+ (attr : access pthread_attr_t; detachstate : int) return int;
+ pragma Import (C, pthread_attr_setdetachstate);
+
+ function pthread_attr_setname
+ (attr : access pthread_attr_t; name : chars_ptr) return int;
+ pragma Import (C, pthread_attr_setname, "pthread_attr_setname");
+
+ --
+ -- Thread Scheduling Attributes
+ --
+
+ function pthread_attr_setscope
+ (attr : access pthread_attr_t; contentionscope : int) return int;
+ pragma Import (C, pthread_attr_setscope, "pthread_attr_setscope");
+
+ function pthread_attr_setinheritsched
+ (attr : access pthread_attr_t; inherit : int) return int;
+ pragma Import
+ (C, pthread_attr_setinheritsched, "pthread_attr_setinheritsched");
+
+ function pthread_attr_setsched
+ (attr : access pthread_attr_t; scheduler : int) return int;
+ pragma Import (C, pthread_attr_setsched, "pthread_attr_setsched");
+
+ function pthread_attr_setprio
+ (attr : access pthread_attr_t; priority : int) return int;
+ pragma Import (C, pthread_attr_setprio, "pthread_attr_setprio");
+
+ --
+ -- SGI Extensions to Thread Attributes
+ --
+
+ -- Bound to sproc attribute values
+
+ PTHREAD_BOUND : constant := 1;
+ PTHREAD_NOT_BOUND : constant := 0;
+
+ function pthread_attr_setresources
+ (attr : access pthread_attr_t; resources : resource_t) return int;
+ pragma Import (C, pthread_attr_setresources, "pthread_attr_setresources");
+
+ function pthread_attr_set_boundtosproc
+ (attr : access pthread_attr_t; bound_to_sproc : int) return int;
+ pragma Import
+ (C, pthread_attr_set_boundtosproc, "pthread_attr_set_boundtosproc");
+
+ function pthread_attr_set_bsproc
+ (attr : access pthread_attr_t; bsproc : spcb_p) return int;
+ pragma Import (C, pthread_attr_set_bsproc, "pthread_attr_set_bsproc");
+
+ function pthread_attr_set_tslice
+ (attr : access pthread_attr_t;
+ ts_interval : access struct_timeval) return int;
+ pragma Import (C, pthread_attr_set_tslice, "pthread_attr_set_tslice");
+
+ --
+ -- Thread Creation & Management
+ --
+
+ function pthread_create
+ (thread : access pthread_t;
+ attr : access pthread_attr_t;
+ start_routine : start_addr;
+ arg : Address) return int;
+ pragma Import (C, pthread_create, "pthread_create");
+
+ procedure pthread_exit (status : Address);
+ pragma Import (C, pthread_exit, "pthread_exit");
+
+ procedure pthread_yield (arg : Address := System.Null_Address);
+ pragma Import (C, pthread_yield, "pthread_yield");
+
+ function pthread_self return pthread_t;
+ pragma Import (C, pthread_self, "pthread_self");
+
+ function pthread_kill (thread : pthread_t; sig : int) return int;
+ pragma Import (C, pthread_kill, "pthread_kill");
+
+ --
+ -- SGI Extensions to POSIX thread operations
+ --
+
+ function pthread_setprio (thread : pthread_t; priority : int) return int;
+ pragma Import (C, pthread_setprio, "pthread_setprio");
+
+ function pthread_suspend (thread : pthread_t) return int;
+ pragma Import (C, pthread_suspend, "pthread_suspend");
+
+ function pthread_resume (thread : pthread_t) return int;
+ pragma Import (C, pthread_resume, "pthread_resume");
+
+ function pthread_get_current_ada_tcb return Address;
+ pragma Import (C, pthread_get_current_ada_tcb);
+
+ function pthread_set_ada_tcb
+ (thread : pthread_t; data : Address) return int;
+ pragma Import (C, pthread_set_ada_tcb, "pthread_set_ada_tcb");
+
+ -- Mutex Initialization / Destruction
+
+ function pthread_mutexattr_init
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_init, "pthread_mutexattr_init");
+
+ function pthread_mutexattr_destroy
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_destroy, "pthread_mutexattr_destroy");
+
+ function pthread_mutexattr_setqueueorder
+ (attr : access pthread_mutexattr_t; order : int) return int;
+ pragma Import (C, pthread_mutexattr_setqueueorder);
+
+ function pthread_mutexattr_setceilingprio
+ (attr : access pthread_mutexattr_t; priority : int) return int;
+ pragma Import (C, pthread_mutexattr_setceilingprio);
+
+ -- Mutex Attributes
+
+ -- Threads queueing order
+
+ MUTEX_PRIORITY : constant := 0; -- wait in priority order
+ MUTEX_FIFO : constant := 1; -- first-in-first-out
+ MUTEX_PRIORITY_INHERIT : constant := 2; -- priority inhertance mutex
+ MUTEX_PRIORITY_CEILING : constant := 3; -- priority ceiling mutex
+
+ -- Mutex debugging options
+
+ MUTEX_NO_DEBUG : constant := 0; -- no debugging on mutex
+ MUTEX_DEBUG : constant := 1; -- debugging is on
+
+ -- Mutex spin on lock operations
+
+ MUTEX_NO_SPIN : constant := 0; -- no spin, try once only
+ MUTEX_SPIN_ONLY : constant := -1; -- spin forever
+ -- cnt > 0, limited spin
+ -- Mutex sharing attributes
+
+ MUTEX_SHARED : constant := 0; -- shared between processes
+ MUTEX_NOTSHARED : constant := 1; -- not shared between processes
+
+ -- Mutex Operations
+
+ function pthread_mutex_init
+ (mutex : access pthread_mutex_t;
+ attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutex_init, "pthread_mutex_init");
+
+ function pthread_mutex_destroy
+ (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_destroy, "pthread_mutex_destroy");
+
+ function pthread_mutex_lock
+ (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_lock, "pthread_mutex_lock");
+
+ function pthread_mutex_unlock
+ (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_unlock, "pthread_mutex_unlock");
+
+ -- Condition Initialization / Destruction
+
+ function pthread_condattr_init
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_init, "pthread_condattr_init");
+
+ function pthread_condattr_destroy
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_destroy, "pthread_condattr_destroy");
+
+ -- Condition Attributes
+
+ COND_PRIORITY : constant := 0; -- wait in priority order
+ COND_FIFO : constant := 1; -- first-in-first-out
+
+ -- Condition debugging options
+
+ COND_NO_DEBUG : constant := 0; -- no debugging on mutex
+ COND_DEBUG : constant := 1; -- debugging is on
+
+ -- Condition sharing attributes
+
+ COND_SHARED : constant := 0; -- shared between processes
+ COND_NOTSHARED : constant := 1; -- not shared between processes
+
+ -- Condition Operations
+
+ function pthread_cond_init
+ (cond : access pthread_cond_t;
+ attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_cond_init, "pthread_cond_init");
+
+ function pthread_cond_destroy
+ (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_destroy, "pthread_cond_destroy");
+
+ function pthread_cond_signal (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_signal, "pthread_cond_signal");
+
+ function pthread_cond_wait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_cond_wait, "pthread_cond_wait");
+
+ function pthread_cond_timedwait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ abstime : access struct_timeval) return int;
+ pragma Import (C, pthread_cond_timedwait, "pthread_cond_timedwait");
+
+ -- Thread-Specific Data
+
+ type foo_h_proc_1 is access procedure (value : Address);
+
+ function pthread_key_create
+ (key : access pthread_key_t; destructor : foo_h_proc_1) return int;
+ pragma Import (C, pthread_key_create, "pthread_key_create");
+
+ function pthread_setspecific
+ (key : pthread_key_t; value : Address) return int;
+ pragma Import (C, pthread_setspecific, "pthread_setspecific");
+
+ function pthread_getspecific
+ (key : pthread_key_t; value : access Address) return int;
+ pragma Import (C, pthread_getspecific, "pthread_getspecific");
+
+ type foo_h_proc_2 is access procedure;
+
+ function pthread_exec_begin (init : access pthread_init_struct) return int;
+ pragma Import (C, pthread_exec_begin, "pthread_exec_begin");
+
+ function sproc_create
+ (sproc_id : access sproc_t;
+ attr : access sproc_attr_t;
+ start_routine : sproc_start_addr;
+ arg : Address) return int;
+ pragma Import (C, sproc_create, "sproc_create");
+
+ function sproc_self return sproc_t;
+ pragma Import (C, sproc_self, "sproc_self");
+
+ -- if equal fast TRUE is returned - common case
+ -- if not equal thread resource must NOT be null in order to compare bits
+
+ --
+ -- Sproc attribute initialize / destroy
+ --
+
+ function sproc_attr_init (attr : access sproc_attr_t) return int;
+ pragma Import (C, sproc_attr_init, "sproc_attr_init");
+
+ function sproc_attr_destroy (attr : access sproc_attr_t) return int;
+ pragma Import (C, sproc_attr_destroy, "sproc_attr_destroy");
+
+ function sproc_attr_setresources
+ (attr : access sproc_attr_t; resources : resource_t) return int;
+ pragma Import (C, sproc_attr_setresources, "sproc_attr_setresources");
+
+ function sproc_attr_getresources
+ (attr : access sproc_attr_t;
+ resources : access resource_t) return int;
+ pragma Import (C, sproc_attr_getresources, "sproc_attr_getresources");
+
+ function sproc_attr_setcpu
+ (attr : access sproc_attr_t; cpu_num : int) return int;
+ pragma Import (C, sproc_attr_setcpu, "sproc_attr_setcpu");
+
+ function sproc_attr_getcpu
+ (attr : access sproc_attr_t; cpu_num : access int) return int;
+ pragma Import (C, sproc_attr_getcpu, "sproc_attr_getcpu");
+
+ function sproc_attr_setresident
+ (attr : access sproc_attr_t; resident : int) return int;
+ pragma Import (C, sproc_attr_setresident, "sproc_attr_setresident");
+
+ function sproc_attr_getresident
+ (attr : access sproc_attr_t; resident : access int) return int;
+ pragma Import (C, sproc_attr_getresident, "sproc_attr_getresident");
+
+ function sproc_attr_setname
+ (attr : access sproc_attr_t; name : chars_ptr) return int;
+ pragma Import (C, sproc_attr_setname, "sproc_attr_setname");
+
+ function sproc_attr_getname
+ (attr : access sproc_attr_t; name : chars_ptr) return int;
+ pragma Import (C, sproc_attr_getname, "sproc_attr_getname");
+
+ function sproc_attr_setstacksize
+ (attr : access sproc_attr_t; stacksize : size_t) return int;
+ pragma Import (C, sproc_attr_setstacksize, "sproc_attr_setstacksize");
+
+ function sproc_attr_getstacksize
+ (attr : access sproc_attr_t; stacksize : access size_t) return int;
+ pragma Import (C, sproc_attr_getstacksize, "sproc_attr_getstacksize");
+
+ function sproc_attr_setprio
+ (attr : access sproc_attr_t; priority : int) return int;
+ pragma Import (C, sproc_attr_setprio, "sproc_attr_setprio");
+
+ function sproc_attr_getprio
+ (attr : access sproc_attr_t; priority : access int) return int;
+ pragma Import (C, sproc_attr_getprio, "sproc_attr_getprio");
+
+ function sproc_attr_setbthread
+ (attr : access sproc_attr_t; bthread : ptcb_p) return int;
+ pragma Import (C, sproc_attr_setbthread, "sproc_attr_setbthread");
+
+ function sproc_attr_getbthread
+ (attr : access sproc_attr_t; bthread : access ptcb_p) return int;
+ pragma Import (C, sproc_attr_getbthread, "sproc_attr_getbthread");
+
+ SPROC_NO_RESOURCES : constant := 0;
+ SPROC_ANY_CPU : constant := -1;
+ SPROC_MY_PRIORITY : constant := -1;
+ SPROC_SWAPPED : constant := 0;
+ SPROC_RESIDENT : constant := 1;
+
+ type isr_address is access procedure;
+
+ function intr_attach (sig : int; isr : isr_address) return int;
+ pragma Import (C, intr_attach, "intr_attach");
+
+ Intr_Attach_Reset : constant Boolean := False;
+ -- True if intr_attach is reset after an interrupt handler is called
+
+ function intr_exchange
+ (sig : int;
+ isr : isr_address;
+ oisr : access isr_address) return int;
+ pragma Import (C, intr_exchange, "intr_exchange");
+
+ function intr_current_isr
+ (sig : int;
+ oisr : access isr_address)
+ return int;
+ pragma Import (C, intr_current_isr, "intr_current_isr");
+
+private
+
+ type clockid_t is new int;
+
+ CLOCK_REALTIME : constant clockid_t := 1;
+ CLOCK_SGI_CYCLE : constant clockid_t := 2;
+ CLOCK_SGI_FAST : constant clockid_t := 3;
+
+ type pthread_t is new Address; -- thread identifier
+ type pthread_mutex_t is new Address; -- mutex identifier
+ type pthread_cond_t is new Address; -- cond identifier
+ type pthread_attr_t is new Address; -- pthread attributes
+ type pthread_mutexattr_t is new Address; -- mutex attributes
+ type pthread_condattr_t is new Address; -- mutex attributes
+ type sem_t is new Address; -- semaphore identifier
+ type pthread_key_t is new Address; -- per thread key
+
+ type sigbits_t is array (Integer range 0 .. 3) of unsigned;
+ type sigset_t is record
+ sigbits : sigbits_t;
+ end record;
+ pragma Convention (C, sigset_t);
+
+ type pid_t is new long;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-irix.adb b/gcc/ada/s-osinte-irix.adb
new file mode 100644
index 00000000000..9c4c616dfa2
--- /dev/null
+++ b/gcc/ada/s-osinte-irix.adb
@@ -0,0 +1,120 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2002, 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- --
+-- 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, 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, --
+-- 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 is the IRIX version of this package.
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+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 Interfaces.C; use Interfaces.C;
+
+package body System.OS_Interface is
+
+ ------------------
+ -- pthread_init --
+ ------------------
+
+ procedure pthread_init is
+ begin
+ null;
+ end pthread_init;
+
+ -----------------
+ -- To_Duration --
+ -----------------
+
+ function To_Duration (TS : timespec) return Duration is
+ begin
+ return Duration (TS.tv_sec) + Duration (TS.tv_nsec) / 10#1#E9;
+ end To_Duration;
+
+ function To_Duration (TV : struct_timeval) return Duration is
+ begin
+ return Duration (TV.tv_sec) + Duration (TV.tv_usec) / 10#1#E6;
+ end To_Duration;
+
+ -----------------
+ -- To_Timespec --
+ -----------------
+
+ function To_Timespec (D : Duration) return timespec is
+ S : time_t;
+ F : Duration;
+
+ begin
+ S := time_t (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return timespec'(tv_sec => S,
+ tv_nsec => long (Long_Long_Integer (F * 10#1#E9)));
+ end To_Timespec;
+
+ ----------------
+ -- To_Timeval --
+ ----------------
+
+ function To_Timeval (D : Duration) return struct_timeval is
+ S : time_t;
+ F : Duration;
+
+ begin
+ S := time_t (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return
+ struct_timeval'
+ (tv_sec => S,
+ tv_usec => time_t (Long_Long_Integer (F * 10#1#E6)));
+ end To_Timeval;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-irix.ads b/gcc/ada/s-osinte-irix.ads
new file mode 100644
index 00000000000..92c11070dad
--- /dev/null
+++ b/gcc/ada/s-osinte-irix.ads
@@ -0,0 +1,527 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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 is the SGI Pthreads version of this package
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+with Interfaces.C;
+with Unchecked_Conversion;
+
+package System.OS_Interface is
+
+ pragma Preelaborate;
+
+ pragma Linker_Options ("-lpthread");
+
+ subtype int is Interfaces.C.int;
+ subtype short is Interfaces.C.short;
+ subtype long is Interfaces.C.long;
+ subtype unsigned is Interfaces.C.unsigned;
+ subtype unsigned_short is Interfaces.C.unsigned_short;
+ subtype unsigned_long is Interfaces.C.unsigned_long;
+ subtype unsigned_char is Interfaces.C.unsigned_char;
+ subtype plain_char is Interfaces.C.plain_char;
+ subtype size_t is Interfaces.C.size_t;
+
+ -----------
+ -- Errno --
+ -----------
+
+ function errno return int;
+ pragma Import (C, errno, "__get_errno");
+
+ EINTR : constant := 4; -- interrupted system call
+ EAGAIN : constant := 11; -- No more processes
+ ENOMEM : constant := 12; -- Not enough core
+ EINVAL : constant := 22; -- Invalid argument
+ ETIMEDOUT : constant := 145; -- Connection timed out
+
+ -------------
+ -- Signals --
+ -------------
+
+ Max_Interrupt : constant := 64;
+ type Signal is new int range 0 .. Max_Interrupt;
+ for Signal'Size use int'Size;
+
+ SIGHUP : constant := 1; -- hangup
+ SIGINT : constant := 2; -- interrupt (rubout)
+ SIGQUIT : constant := 3; -- quit (ASCD FS)
+ SIGILL : constant := 4; -- illegal instruction (not reset)
+ SIGTRAP : constant := 5; -- trace trap (not reset)
+ SIGIOT : constant := 6; -- IOT instruction
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the
+ -- future
+ SIGEMT : constant := 7; -- EMT instruction
+ SIGFPE : constant := 8; -- floating point exception
+ SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
+ SIGBUS : constant := 10; -- bus error
+ SIGSEGV : constant := 11; -- segmentation violation
+ SIGSYS : constant := 12; -- bad argument to system call
+ SIGPIPE : constant := 13; -- write on a pipe with no one to read it
+ SIGALRM : constant := 14; -- alarm clock
+ SIGTERM : constant := 15; -- software termination signal from kill
+ SIGUSR1 : constant := 16; -- user defined signal 1
+ SIGUSR2 : constant := 17; -- user defined signal 2
+ SIGCLD : constant := 18; -- alias for SIGCHLD
+ SIGCHLD : constant := 18; -- child status change
+ SIGPWR : constant := 19; -- power-fail restart
+ SIGWINCH : constant := 20; -- window size change
+ SIGURG : constant := 21; -- urgent condition on IO channel
+ SIGPOLL : constant := 22; -- pollable event occurred
+ SIGIO : constant := 22; -- I/O possible (Solaris SIGPOLL alias)
+ SIGSTOP : constant := 23; -- stop (cannot be caught or ignored)
+ SIGTSTP : constant := 24; -- user stop requested from tty
+ SIGCONT : constant := 25; -- stopped process has been continued
+ SIGTTIN : constant := 26; -- background tty read attempted
+ SIGTTOU : constant := 27; -- background tty write attempted
+ SIGVTALRM : constant := 28; -- virtual timer expired
+ SIGPROF : constant := 29; -- profiling timer expired
+ SIGXCPU : constant := 30; -- CPU time limit exceeded
+ SIGXFSZ : constant := 31; -- filesize limit exceeded
+ SIGK32 : constant := 32; -- reserved for kernel (IRIX)
+ SIGCKPT : constant := 33; -- Checkpoint warning
+ SIGRESTART : constant := 34; -- Restart warning
+ SIGUME : constant := 35; -- Uncorrectable memory error
+ -- Signals defined for Posix 1003.1c.
+ SIGPTINTR : constant := 47;
+ SIGPTRESCHED : constant := 48;
+ -- Posix 1003.1b signals
+ SIGRTMIN : constant := 49; -- Posix 1003.1b signals
+ SIGRTMAX : constant := 64; -- Posix 1003.1b signals
+
+ type sigset_t is private;
+ type sigset_t_ptr is access all sigset_t;
+
+ function sigaddset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigaddset, "sigaddset");
+
+ function sigdelset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigdelset, "sigdelset");
+
+ function sigfillset (set : access sigset_t) return int;
+ pragma Import (C, sigfillset, "sigfillset");
+
+ function sigismember (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigismember, "sigismember");
+
+ function sigemptyset (set : access sigset_t) return int;
+ pragma Import (C, sigemptyset, "sigemptyset");
+
+ type array_type_2 is array (Integer range 0 .. 1) of int;
+ type struct_sigaction is record
+ sa_flags : int;
+ sa_handler : System.Address;
+ sa_mask : sigset_t;
+ sa_resv : array_type_2;
+ end record;
+ pragma Convention (C, struct_sigaction);
+
+ type struct_sigaction_ptr is access all struct_sigaction;
+
+ SIG_BLOCK : constant := 1;
+ SIG_UNBLOCK : constant := 2;
+ SIG_SETMASK : constant := 3;
+
+ SIG_DFL : constant := 0;
+ SIG_IGN : constant := 1;
+
+ function sigaction
+ (sig : Signal;
+ act : struct_sigaction_ptr;
+ oact : struct_sigaction_ptr := null) return int;
+ pragma Import (C, sigaction, "sigaction");
+
+ ----------
+ -- Time --
+ ----------
+
+ type timespec is private;
+ type timespec_ptr is access all timespec;
+
+ type clockid_t is private;
+
+ CLOCK_REALTIME : constant clockid_t;
+ CLOCK_SGI_FAST : constant clockid_t;
+ CLOCK_SGI_CYCLE : constant clockid_t;
+
+ SGI_CYCLECNTR_SIZE : constant := 165;
+
+ function syssgi (request : Interfaces.C.int) return Interfaces.C.ptrdiff_t;
+ pragma Import (C, syssgi, "syssgi");
+
+ function clock_gettime
+ (clock_id : clockid_t;
+ tp : access timespec) return int;
+ pragma Import (C, clock_gettime, "clock_gettime");
+
+ function clock_getres
+ (clock_id : clockid_t;
+ tp : access timespec) return int;
+ pragma Import (C, clock_getres, "clock_getres");
+
+ function To_Duration (TS : timespec) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timespec (D : Duration) return timespec;
+ pragma Inline (To_Timespec);
+
+ type struct_timeval is private;
+
+ function To_Duration (TV : struct_timeval) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timeval (D : Duration) return struct_timeval;
+ pragma Inline (To_Timeval);
+
+ -------------------------
+ -- Priority Scheduling --
+ -------------------------
+
+ SCHED_FIFO : constant := 1;
+ SCHED_RR : constant := 2;
+ SCHED_TS : constant := 3;
+ SCHED_OTHER : constant := 3;
+ SCHED_NP : constant := 4;
+
+ function sched_get_priority_min (Policy : int) return int;
+ pragma Import (C, sched_get_priority_min, "sched_get_priority_min");
+
+ function sched_get_priority_max (Policy : int) return int;
+ pragma Import (C, sched_get_priority_max, "sched_get_priority_max");
+
+ -------------
+ -- Process --
+ -------------
+
+ type pid_t is private;
+
+ function kill (pid : pid_t; sig : Signal) return int;
+ pragma Import (C, kill, "kill");
+
+ function getpid return pid_t;
+ pragma Import (C, getpid, "getpid");
+
+ -------------
+ -- Threads --
+ -------------
+
+ type Thread_Body is access
+ function (arg : System.Address) return System.Address;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ type pthread_t is private;
+ subtype Thread_Id is pthread_t;
+
+ type pthread_mutex_t is limited private;
+ type pthread_cond_t is limited private;
+ type pthread_attr_t is limited private;
+ type pthread_mutexattr_t is limited private;
+ type pthread_condattr_t is limited private;
+ type pthread_key_t is private;
+
+ PTHREAD_CREATE_DETACHED : constant := 1;
+
+ ---------------------------------------
+ -- Nonstandard Thread Initialization --
+ ---------------------------------------
+
+ procedure pthread_init;
+ pragma Inline (pthread_init);
+ -- This is a dummy procedure to share some GNULLI files
+
+ -------------------------
+ -- POSIX.1c Section 3 --
+ -------------------------
+
+ function sigwait
+ (set : access sigset_t;
+ sig : access Signal) return int;
+ pragma Import (C, sigwait, "sigwait");
+
+ function pthread_kill
+ (thread : pthread_t;
+ sig : Signal) return int;
+ pragma Import (C, pthread_kill, "pthread_kill");
+
+ function pthread_sigmask
+ (how : int;
+ set : sigset_t_ptr;
+ oset : sigset_t_ptr) return int;
+ pragma Import (C, pthread_sigmask, "pthread_sigmask");
+
+ --------------------------
+ -- POSIX.1c Section 11 --
+ --------------------------
+
+ function pthread_mutexattr_init
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_init, "pthread_mutexattr_init");
+
+ function pthread_mutexattr_destroy
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_destroy, "pthread_mutexattr_destroy");
+
+ function pthread_mutex_init
+ (mutex : access pthread_mutex_t;
+ attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutex_init, "pthread_mutex_init");
+
+ function pthread_mutex_destroy (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_destroy, "pthread_mutex_destroy");
+
+ function pthread_mutex_lock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_lock, "pthread_mutex_lock");
+
+ function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_unlock, "pthread_mutex_unlock");
+
+ function pthread_condattr_init
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_init, "pthread_condattr_init");
+
+ function pthread_condattr_destroy
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_destroy, "pthread_condattr_destroy");
+
+ function pthread_cond_init
+ (cond : access pthread_cond_t;
+ attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_cond_init, "pthread_cond_init");
+
+ function pthread_cond_destroy (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_destroy, "pthread_cond_destroy");
+
+ function pthread_cond_signal (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_signal, "pthread_cond_signal");
+
+ function pthread_cond_wait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_cond_wait, "pthread_cond_wait");
+
+ function pthread_cond_timedwait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ abstime : access timespec) return int;
+ pragma Import (C, pthread_cond_timedwait, "pthread_cond_timedwait");
+
+ --------------------------
+ -- POSIX.1c Section 13 --
+ --------------------------
+
+ PTHREAD_PRIO_NONE : constant := 0;
+ PTHREAD_PRIO_PROTECT : constant := 2;
+ PTHREAD_PRIO_INHERIT : constant := 1;
+
+ function pthread_mutexattr_setprotocol
+ (attr : access pthread_mutexattr_t;
+ protocol : int) return int;
+ pragma Import (C, pthread_mutexattr_setprotocol);
+
+ function pthread_mutexattr_setprioceiling
+ (attr : access pthread_mutexattr_t;
+ prioceiling : int) return int;
+ pragma Import (C, pthread_mutexattr_setprioceiling);
+
+ type struct_sched_param is record
+ sched_priority : int;
+ end record;
+ pragma Convention (C, struct_sched_param);
+
+ function pthread_setschedparam
+ (thread : pthread_t;
+ policy : int;
+ param : access struct_sched_param)
+ return int;
+ pragma Import (C, pthread_setschedparam, "pthread_setschedparam");
+
+ function pthread_attr_setscope
+ (attr : access pthread_attr_t;
+ contentionscope : int) return int;
+ pragma Import (C, pthread_attr_setscope, "pthread_attr_setscope");
+
+ function pthread_attr_setinheritsched
+ (attr : access pthread_attr_t;
+ inheritsched : int) return int;
+ pragma Import
+ (C, pthread_attr_setinheritsched, "pthread_attr_setinheritsched");
+
+ function pthread_attr_setschedpolicy
+ (attr : access pthread_attr_t;
+ policy : int) return int;
+ pragma Import (C, pthread_attr_setschedpolicy);
+
+ function pthread_attr_setschedparam
+ (attr : access pthread_attr_t;
+ sched_param : access struct_sched_param)
+ return int;
+ pragma Import (C, pthread_attr_setschedparam, "pthread_attr_setschedparam");
+
+ function sched_yield return int;
+ pragma Import (C, sched_yield, "sched_yield");
+
+ ---------------------------
+ -- P1003.1c - Section 16 --
+ ---------------------------
+
+ function pthread_attr_init (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_init, "pthread_attr_init");
+
+ function pthread_attr_destroy
+ (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_destroy, "pthread_attr_destroy");
+
+ function pthread_attr_setdetachstate
+ (attr : access pthread_attr_t;
+ detachstate : int) return int;
+ pragma Import (C, pthread_attr_setdetachstate);
+
+ function pthread_attr_setstacksize
+ (attr : access pthread_attr_t;
+ stacksize : size_t) return int;
+ pragma Import (C, pthread_attr_setstacksize, "pthread_attr_setstacksize");
+
+ function pthread_create
+ (thread : access pthread_t;
+ attributes : access pthread_attr_t;
+ start_routine : Thread_Body;
+ arg : System.Address) return int;
+ pragma Import (C, pthread_create, "pthread_create");
+
+ procedure pthread_exit (status : System.Address);
+ pragma Import (C, pthread_exit, "pthread_exit");
+
+ function pthread_self return pthread_t;
+ pragma Import (C, pthread_self, "pthread_self");
+
+ --------------------------
+ -- POSIX.1c Section 17 --
+ --------------------------
+
+ function pthread_setspecific
+ (key : pthread_key_t;
+ value : System.Address) return int;
+ pragma Import (C, pthread_setspecific, "pthread_setspecific");
+
+ function pthread_getspecific (key : pthread_key_t) return System.Address;
+ pragma Import (C, pthread_getspecific, "pthread_getspecific");
+
+ type destructor_pointer is access procedure (arg : System.Address);
+
+ function pthread_key_create
+ (key : access pthread_key_t;
+ destructor : destructor_pointer) return int;
+ pragma Import (C, pthread_key_create, "pthread_key_create");
+
+ ---------------------------------------------------------------
+ -- Non portable SGI 6.5 additions to the pthread interface --
+ -- must be executed from within the context of a system --
+ -- scope task --
+ ---------------------------------------------------------------
+
+ function pthread_setrunon_np (cpu : int) return int;
+ pragma Import (C, pthread_setrunon_np, "pthread_setrunon_np");
+
+private
+
+ type array_type_1 is array (Integer range 0 .. 3) of unsigned;
+ type sigset_t is record
+ X_X_sigbits : array_type_1;
+ end record;
+ pragma Convention (C, sigset_t);
+
+ type pid_t is new long;
+
+ type time_t is new long;
+
+ type timespec is record
+ tv_sec : time_t;
+ tv_nsec : long;
+ end record;
+ pragma Convention (C, timespec);
+
+ type clockid_t is new int;
+ CLOCK_REALTIME : constant clockid_t := 1;
+ CLOCK_SGI_CYCLE : constant clockid_t := 2;
+ CLOCK_SGI_FAST : constant clockid_t := 3;
+
+ type struct_timeval is record
+ tv_sec : time_t;
+ tv_usec : time_t;
+ end record;
+ pragma Convention (C, struct_timeval);
+
+ type array_type_9 is array (Integer range 0 .. 4) of long;
+ type pthread_attr_t is record
+ X_X_D : array_type_9;
+ end record;
+ pragma Convention (C, pthread_attr_t);
+
+ type array_type_8 is array (Integer range 0 .. 1) of long;
+ type pthread_condattr_t is record
+ X_X_D : array_type_8;
+ end record;
+ pragma Convention (C, pthread_condattr_t);
+
+ type array_type_7 is array (Integer range 0 .. 1) of long;
+ type pthread_mutexattr_t is record
+ X_X_D : array_type_7;
+ end record;
+ pragma Convention (C, pthread_mutexattr_t);
+
+ type pthread_t is new unsigned;
+
+ type array_type_10 is array (Integer range 0 .. 7) of long;
+ type pthread_mutex_t is record
+ X_X_D : array_type_10;
+ end record;
+ pragma Convention (C, pthread_mutex_t);
+
+ type array_type_11 is array (Integer range 0 .. 7) of long;
+ type pthread_cond_t is record
+ X_X_D : array_type_11;
+ end record;
+ pragma Convention (C, pthread_cond_t);
+
+ type pthread_key_t is new int;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-linux-fsu.ads b/gcc/ada/s-osinte-linux-fsu.ads
new file mode 100644
index 00000000000..df7a4322bf5
--- /dev/null
+++ b/gcc/ada/s-osinte-linux-fsu.ads
@@ -0,0 +1,599 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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 is a GNU/Linux (FSU THREADS) version of this package.
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+with Interfaces.C;
+with Unchecked_Conversion;
+
+package System.OS_Interface is
+ pragma Preelaborate;
+
+ pragma Linker_Options ("-lgthreads");
+ pragma Linker_Options ("-lmalloc");
+
+ subtype int is Interfaces.C.int;
+ subtype short is Interfaces.C.short;
+ subtype long is Interfaces.C.long;
+ subtype unsigned is Interfaces.C.unsigned;
+ subtype unsigned_short is Interfaces.C.unsigned_short;
+ subtype unsigned_long is Interfaces.C.unsigned_long;
+ subtype unsigned_char is Interfaces.C.unsigned_char;
+ subtype plain_char is Interfaces.C.plain_char;
+ subtype size_t is Interfaces.C.size_t;
+
+ -----------
+ -- Errno --
+ -----------
+
+ function errno return int;
+ pragma Import (C, errno, "__get_errno");
+
+ EAGAIN : constant := 11;
+ EINTR : constant := 4;
+ EINVAL : constant := 22;
+ ENOMEM : constant := 12;
+ ETIMEDOUT : constant := 110;
+
+ -------------
+ -- Signals --
+ -------------
+
+ Max_Interrupt : constant := 31;
+ type Signal is new int range 0 .. Max_Interrupt;
+ for Signal'Size use int'Size;
+
+ SIGHUP : constant := 1; -- hangup
+ SIGINT : constant := 2; -- interrupt (rubout)
+ SIGQUIT : constant := 3; -- quit (ASCD FS)
+ SIGILL : constant := 4; -- illegal instruction (not reset)
+ SIGTRAP : constant := 5; -- trace trap (not reset)
+ SIGIOT : constant := 6; -- IOT instruction
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGFPE : constant := 8; -- floating point exception
+ SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
+ SIGBUS : constant := 7; -- bus error
+ SIGSEGV : constant := 11; -- segmentation violation
+ SIGPIPE : constant := 13; -- write on a pipe with no one to read it
+ SIGALRM : constant := 14; -- alarm clock
+ SIGTERM : constant := 15; -- software termination signal from kill
+ SIGUSR1 : constant := 10; -- user defined signal 1
+ SIGUSR2 : constant := 12; -- user defined signal 2
+ SIGCLD : constant := 17; -- alias for SIGCHLD
+ SIGCHLD : constant := 17; -- child status change
+ SIGPWR : constant := 30; -- power-fail restart
+ SIGWINCH : constant := 28; -- window size change
+ SIGURG : constant := 23; -- urgent condition on IO channel
+ SIGPOLL : constant := 29; -- pollable event occurred
+ SIGIO : constant := 29; -- I/O now possible (4.2 BSD)
+ SIGLOST : constant := 29; -- File lock lost
+ SIGSTOP : constant := 19; -- stop (cannot be caught or ignored)
+ SIGTSTP : constant := 20; -- user stop requested from tty
+ SIGCONT : constant := 18; -- stopped process has been continued
+ SIGTTIN : constant := 21; -- background tty read attempted
+ SIGTTOU : constant := 22; -- background tty write attempted
+ SIGVTALRM : constant := 26; -- virtual timer expired
+ SIGPROF : constant := 27; -- profiling timer expired
+ SIGXCPU : constant := 24; -- CPU time limit exceeded
+ SIGXFSZ : constant := 25; -- filesize limit exceeded
+ SIGUNUSED : constant := 31; -- unused signal (GNU/Linux)
+ SIGSTKFLT : constant := 16; -- coprocessor stack fault (GNU/Linux)
+
+ SIGADAABORT : constant := SIGABRT;
+ -- Change this if you want to use another signal for task abort.
+ -- SIGTERM might be a good one.
+
+ type Signal_Set is array (Natural range <>) of Signal;
+
+ Unmasked : constant Signal_Set :=
+ (SIGTRAP, SIGBUS, SIGTTIN, SIGTTOU, SIGTSTP, SIGPROF);
+
+ Reserved : constant Signal_Set :=
+ (SIGKILL, SIGSTOP, SIGALRM, SIGVTALRM, SIGUNUSED);
+
+ type sigset_t is private;
+
+ function sigaddset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigaddset, "sigaddset");
+
+ function sigdelset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigdelset, "sigdelset");
+
+ function sigfillset (set : access sigset_t) return int;
+ pragma Import (C, sigfillset, "sigfillset");
+
+ function sigismember (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigismember, "sigismember");
+
+ function sigemptyset (set : access sigset_t) return int;
+ pragma Import (C, sigemptyset, "sigemptyset");
+
+ type struct_sigaction is record
+ sa_handler : System.Address;
+ sa_mask : sigset_t;
+ sa_flags : unsigned_long;
+ sa_restorer : System.Address;
+ end record;
+ pragma Convention (C, struct_sigaction);
+ type struct_sigaction_ptr is access all struct_sigaction;
+
+ type Machine_State is record
+ eip : unsigned_long;
+ ebx : unsigned_long;
+ esp : unsigned_long;
+ ebp : unsigned_long;
+ esi : unsigned_long;
+ edi : unsigned_long;
+ end record;
+ type Machine_State_Ptr is access all Machine_State;
+
+ SA_SIGINFO : constant := 16#04#;
+
+ SIG_BLOCK : constant := 0;
+ SIG_UNBLOCK : constant := 1;
+ SIG_SETMASK : constant := 2;
+
+ SIG_DFL : constant := 0;
+ SIG_IGN : constant := 1;
+
+ function sigaction
+ (sig : Signal;
+ act : struct_sigaction_ptr;
+ oact : struct_sigaction_ptr) return int;
+ pragma Import (C, sigaction, "sigaction");
+
+ ----------
+ -- Time --
+ ----------
+
+ Time_Slice_Supported : constant Boolean := False;
+ -- Indicates wether time slicing is supported (i.e FSU threads have been
+ -- compiled with DEF_RR)
+
+ type timespec is private;
+
+ type clockid_t is private;
+
+ CLOCK_REALTIME : constant clockid_t;
+
+ function clock_gettime
+ (clock_id : clockid_t;
+ tp : access timespec) return int;
+ pragma Import (C, clock_gettime, "clock_gettime");
+
+ function To_Duration (TS : timespec) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timespec (D : Duration) return timespec;
+ pragma Inline (To_Timespec);
+
+ type struct_timeval is private;
+
+ function To_Duration (TV : struct_timeval) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timeval (D : Duration) return struct_timeval;
+ pragma Inline (To_Timeval);
+
+ -------------------------
+ -- Priority Scheduling --
+ -------------------------
+
+ SCHED_FIFO : constant := 0;
+ SCHED_RR : constant := 1;
+ SCHED_OTHER : constant := 2;
+
+ -------------
+ -- Process --
+ -------------
+
+ type pid_t is private;
+
+ function kill (pid : pid_t; sig : Signal) return int;
+ pragma Import (C, kill, "kill");
+
+ function getpid return pid_t;
+ pragma Import (C, getpid, "getpid");
+
+ ---------
+ -- LWP --
+ ---------
+
+ function lwp_self return System.Address;
+ -- lwp_self does not exist on this thread library, revert to pthread_self
+ -- which is the closest approximation (with getpid). This function is
+ -- needed to share 7staprop.adb across POSIX-like targets.
+ pragma Import (C, lwp_self, "pthread_self");
+
+ -------------
+ -- Threads --
+ -------------
+
+ type Thread_Body is access
+ function (arg : System.Address) return System.Address;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ type pthread_t is private;
+ subtype Thread_Id is pthread_t;
+
+ type pthread_mutex_t is limited private;
+ type pthread_cond_t is limited private;
+ type pthread_attr_t is limited private;
+ type pthread_mutexattr_t is limited private;
+ type pthread_condattr_t is limited private;
+ type pthread_key_t is private;
+
+ PTHREAD_CREATE_DETACHED : constant := 1;
+
+ -----------
+ -- Stack --
+ -----------
+
+ Stack_Base_Available : constant Boolean := False;
+ -- Indicates wether the stack base is available on this target.
+ -- This allows us to share s-osinte.adb between all the FSU run time.
+ -- Note that this value can only be true if pthread_t has a complete
+ -- definition that corresponds exactly to the C header files.
+
+ function Get_Stack_Base (thread : pthread_t) return Address;
+ pragma Inline (Get_Stack_Base);
+ -- returns the stack base of the specified thread.
+ -- Only call this function when Stack_Base_Available is True.
+
+ 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
+
+ PROT_NONE : constant := 0;
+ PROT_READ : constant := 1;
+ PROT_WRITE : constant := 2;
+ PROT_EXEC : constant := 4;
+ PROT_ALL : constant := PROT_READ + PROT_WRITE + PROT_EXEC;
+
+ PROT_ON : constant := PROT_NONE;
+ PROT_OFF : constant := PROT_ALL;
+
+ function mprotect (addr : Address; len : size_t; prot : int) return int;
+ pragma Import (C, mprotect);
+
+ ---------------------------------------
+ -- Nonstandard Thread Initialization --
+ ---------------------------------------
+
+ procedure pthread_init;
+ -- FSU_THREADS requires pthread_init, which is nonstandard
+ -- and this should be invoked during the elaboration of s-taprop.adb
+ pragma Import (C, pthread_init, "pthread_init");
+
+ -------------------------
+ -- POSIX.1c Section 3 --
+ -------------------------
+
+ function sigwait
+ (set : access sigset_t;
+ sig : access Signal) return int;
+ pragma Inline (sigwait);
+ -- FSU_THREADS has a nonstandard sigwait
+
+ function pthread_kill
+ (thread : pthread_t;
+ sig : Signal) return int;
+ pragma Import (C, pthread_kill, "pthread_kill");
+
+ -- FSU threads does not have pthread_sigmask. Instead, it uses
+ -- sigprocmask to do the signal handling when the thread library is
+ -- sucked in.
+
+ type sigset_t_ptr is access all sigset_t;
+
+ function pthread_sigmask
+ (how : int;
+ set : sigset_t_ptr;
+ oset : sigset_t_ptr) return int;
+ pragma Import (C, pthread_sigmask, "sigprocmask");
+
+ --------------------------
+ -- POSIX.1c Section 11 --
+ --------------------------
+
+ function pthread_mutexattr_init
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_init, "pthread_mutexattr_init");
+
+ function pthread_mutexattr_destroy
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_destroy, "pthread_mutexattr_destroy");
+
+ function pthread_mutex_init
+ (mutex : access pthread_mutex_t;
+ attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutex_init, "pthread_mutex_init");
+
+ function pthread_mutex_destroy
+ (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_destroy, "pthread_mutex_destroy");
+
+ function pthread_mutex_lock
+ (mutex : access pthread_mutex_t) return int;
+ pragma Inline (pthread_mutex_lock);
+ -- FSU_THREADS has nonstandard pthread_mutex_lock
+
+ function pthread_mutex_unlock
+ (mutex : access pthread_mutex_t) return int;
+ pragma Inline (pthread_mutex_unlock);
+ -- FSU_THREADS has nonstandard pthread_mutex_lock
+
+ function pthread_condattr_init
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_init, "pthread_condattr_init");
+
+ function pthread_condattr_destroy
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_destroy, "pthread_condattr_destroy");
+
+ function pthread_cond_init
+ (cond : access pthread_cond_t;
+ attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_cond_init, "pthread_cond_init");
+
+ function pthread_cond_destroy (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_destroy, "pthread_cond_destroy");
+
+ function pthread_cond_signal (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_signal, "pthread_cond_signal");
+
+ function pthread_cond_wait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t) return int;
+ pragma Inline (pthread_cond_wait);
+ -- FSU_THREADS has a nonstandard pthread_cond_wait
+
+ function pthread_cond_timedwait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ abstime : access timespec) return int;
+ pragma Inline (pthread_cond_timedwait);
+ -- FSU_THREADS has a nonstandard pthread_cond_timedwait
+
+ Relative_Timed_Wait : constant Boolean := False;
+ -- pthread_cond_timedwait requires an absolute delay time
+
+ --------------------------
+ -- POSIX.1c Section 13 --
+ --------------------------
+
+ PTHREAD_PRIO_NONE : constant := 0;
+ PTHREAD_PRIO_PROTECT : constant := 2;
+ PTHREAD_PRIO_INHERIT : constant := 1;
+
+ function pthread_mutexattr_setprotocol
+ (attr : access pthread_mutexattr_t;
+ protocol : int) return int;
+ pragma Import (C, pthread_mutexattr_setprotocol);
+
+ function pthread_mutexattr_setprioceiling
+ (attr : access pthread_mutexattr_t;
+ prioceiling : int) return int;
+ pragma Import
+ (C, pthread_mutexattr_setprioceiling,
+ "pthread_mutexattr_setprio_ceiling");
+
+ type struct_sched_param is record
+ sched_priority : int; -- scheduling priority
+ end record;
+
+ function pthread_setschedparam
+ (thread : pthread_t;
+ policy : int;
+ param : access struct_sched_param) return int;
+ pragma Inline (pthread_setschedparam);
+ -- FSU_THREADS does not have pthread_setschedparam
+
+ function pthread_attr_setscope
+ (attr : access pthread_attr_t;
+ contentionscope : int) return int;
+ pragma Import (C, pthread_attr_setscope, "pthread_attr_setscope");
+
+ function pthread_attr_setinheritsched
+ (attr : access pthread_attr_t;
+ inheritsched : int) return int;
+ pragma Import (C, pthread_attr_setinheritsched);
+
+ function pthread_attr_setschedpolicy
+ (attr : access pthread_attr_t;
+ policy : int) return int;
+ pragma Import (C, pthread_attr_setschedpolicy, "pthread_attr_setsched");
+
+ function sched_yield return int;
+ pragma Inline (sched_yield);
+ -- FSU_THREADS does not have sched_yield;
+
+ ---------------------------
+ -- P1003.1c - Section 16 --
+ ---------------------------
+
+ function pthread_attr_init (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_init, "pthread_attr_init");
+
+ function pthread_attr_destroy
+ (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_destroy, "pthread_attr_destroy");
+
+ function pthread_attr_setdetachstate
+ (attr : access pthread_attr_t;
+ detachstate : int) return int;
+ pragma Inline (pthread_attr_setdetachstate);
+ -- FSU_THREADS has a nonstandard pthread_attr_setdetachstate
+
+ function pthread_attr_setstacksize
+ (attr : access pthread_attr_t;
+ stacksize : size_t) return int;
+ pragma Import (C, pthread_attr_setstacksize, "pthread_attr_setstacksize");
+
+ function pthread_create
+ (thread : access pthread_t;
+ attributes : access pthread_attr_t;
+ start_routine : Thread_Body;
+ arg : System.Address) return int;
+ pragma Import (C, pthread_create, "pthread_create");
+
+ procedure pthread_exit (status : System.Address);
+ pragma Import (C, pthread_exit, "pthread_exit");
+
+ function pthread_self return pthread_t;
+ pragma Import (C, pthread_self, "pthread_self");
+
+ --------------------------
+ -- POSIX.1c Section 17 --
+ --------------------------
+
+ function pthread_setspecific
+ (key : pthread_key_t;
+ value : System.Address) return int;
+ pragma Import (C, pthread_setspecific, "pthread_setspecific");
+
+ function pthread_getspecific (key : pthread_key_t) return System.Address;
+ pragma Inline (pthread_getspecific);
+ -- FSU_THREADS has a nonstandard pthread_getspecific
+
+ type destructor_pointer is access procedure (arg : System.Address);
+
+ function pthread_key_create
+ (key : access pthread_key_t;
+ destructor : destructor_pointer) return int;
+ pragma Import (C, pthread_key_create, "pthread_key_create");
+
+private
+
+ type sigset_t is array (0 .. 31) of unsigned_long;
+ pragma Convention (C, sigset_t);
+ -- This is for GNU libc version 2 but should be backward compatible with
+ -- other libc where sigset_t is smaller.
+
+ type pid_t is new int;
+
+ type time_t is new long;
+
+ type timespec is record
+ tv_sec : time_t;
+ tv_nsec : long;
+ end record;
+ pragma Convention (C, timespec);
+
+ type clockid_t is new int;
+ CLOCK_REALTIME : constant clockid_t := 0;
+
+ type struct_timeval is record
+ tv_sec : long;
+ tv_usec : long;
+ end record;
+ pragma Convention (C, struct_timeval);
+
+ type pthread_attr_t is record
+ flags : int;
+ stacksize : int;
+ contentionscope : int;
+ inheritsched : int;
+ detachstate : int;
+ sched : int;
+ prio : int;
+ starttime : timespec;
+ deadline : timespec;
+ period : timespec;
+ end record;
+ pragma Convention (C_Pass_By_Copy, pthread_attr_t);
+
+ type pthread_condattr_t is record
+ flags : int;
+ end record;
+ pragma Convention (C, pthread_condattr_t);
+
+ type pthread_mutexattr_t is record
+ flags : int;
+ prio_ceiling : int;
+ protocol : int;
+ end record;
+ pragma Convention (C, pthread_mutexattr_t);
+
+ type sigjmp_buf is array (Integer range 0 .. 38) of int;
+
+ type pthread_t_struct is record
+ context : sigjmp_buf;
+ pbody : sigjmp_buf;
+ errno : int;
+ ret : int;
+ stack_base : System.Address;
+ end record;
+ pragma Convention (C, pthread_t_struct);
+
+ type pthread_t is access all pthread_t_struct;
+
+ type queue_t is record
+ head : System.Address;
+ tail : System.Address;
+ end record;
+ pragma Convention (C, queue_t);
+
+ type pthread_mutex_t is record
+ queue : queue_t;
+ lock : plain_char;
+ owner : System.Address;
+ flags : int;
+ prio_ceiling : int;
+ protocol : int;
+ prev_max_ceiling_prio : int;
+ end record;
+ pragma Convention (C, pthread_mutex_t);
+
+ type pthread_cond_t is record
+ queue : queue_t;
+ flags : int;
+ waiters : int;
+ mutex : System.Address;
+ end record;
+ pragma Convention (C, pthread_cond_t);
+
+ type pthread_key_t is new int;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-linux-ia64.ads b/gcc/ada/s-osinte-linux-ia64.ads
new file mode 100644
index 00000000000..72c51b0df52
--- /dev/null
+++ b/gcc/ada/s-osinte-linux-ia64.ads
@@ -0,0 +1,150 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (GNU-Linux/ia64 Version) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.01;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 64;
+ Memory_Size : constant := 2 ** 64;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := Low_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ Max_Priority : constant Positive := 30;
+ Max_Interrupt_Priority : constant Positive := 31;
+
+ subtype Any_Priority is Integer range 0 .. 31;
+ subtype Priority is Any_Priority range 0 .. 30;
+ subtype Interrupt_Priority is Any_Priority range 31 .. 31;
+
+ Default_Priority : constant Priority := 15;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := False;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := True;
+ GCC_ZCX_Support : constant Boolean := True;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := True;
+
+end System;
diff --git a/gcc/ada/s-osinte-linux.ads b/gcc/ada/s-osinte-linux.ads
new file mode 100644
index 00000000000..c8f06916f13
--- /dev/null
+++ b/gcc/ada/s-osinte-linux.ads
@@ -0,0 +1,524 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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 is a GNU/Linux (GNU/LinuxThreads) version of this package
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+with Interfaces.C;
+with Unchecked_Conversion;
+
+package System.OS_Interface is
+ pragma Preelaborate;
+
+ pragma Linker_Options ("-lpthread");
+
+ subtype int is Interfaces.C.int;
+ subtype char is Interfaces.C.char;
+ subtype short is Interfaces.C.short;
+ subtype long is Interfaces.C.long;
+ subtype unsigned is Interfaces.C.unsigned;
+ subtype unsigned_short is Interfaces.C.unsigned_short;
+ subtype unsigned_long is Interfaces.C.unsigned_long;
+ subtype unsigned_char is Interfaces.C.unsigned_char;
+ subtype plain_char is Interfaces.C.plain_char;
+ subtype size_t is Interfaces.C.size_t;
+
+ -----------
+ -- Errno --
+ -----------
+
+ function errno return int;
+ pragma Import (C, errno, "__get_errno");
+
+ EAGAIN : constant := 11;
+ EINTR : constant := 4;
+ EINVAL : constant := 22;
+ ENOMEM : constant := 12;
+ EPERM : constant := 1;
+ ETIMEDOUT : constant := 110;
+
+ -------------
+ -- Signals --
+ -------------
+
+ Max_Interrupt : constant := 63;
+ type Signal is new int range 0 .. Max_Interrupt;
+ for Signal'Size use int'Size;
+
+ SIGHUP : constant := 1; -- hangup
+ SIGINT : constant := 2; -- interrupt (rubout)
+ SIGQUIT : constant := 3; -- quit (ASCD FS)
+ SIGILL : constant := 4; -- illegal instruction (not reset)
+ SIGTRAP : constant := 5; -- trace trap (not reset)
+ SIGIOT : constant := 6; -- IOT instruction
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGFPE : constant := 8; -- floating point exception
+ SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
+ SIGBUS : constant := 7; -- bus error
+ SIGSEGV : constant := 11; -- segmentation violation
+ SIGPIPE : constant := 13; -- write on a pipe with no one to read it
+ SIGALRM : constant := 14; -- alarm clock
+ SIGTERM : constant := 15; -- software termination signal from kill
+ SIGUSR1 : constant := 10; -- user defined signal 1
+ SIGUSR2 : constant := 12; -- user defined signal 2
+ SIGCLD : constant := 17; -- alias for SIGCHLD
+ SIGCHLD : constant := 17; -- child status change
+ SIGPWR : constant := 30; -- power-fail restart
+ SIGWINCH : constant := 28; -- window size change
+ SIGURG : constant := 23; -- urgent condition on IO channel
+ SIGPOLL : constant := 29; -- pollable event occurred
+ SIGIO : constant := 29; -- I/O now possible (4.2 BSD)
+ SIGLOST : constant := 29; -- File lock lost
+ SIGSTOP : constant := 19; -- stop (cannot be caught or ignored)
+ SIGTSTP : constant := 20; -- user stop requested from tty
+ SIGCONT : constant := 18; -- stopped process has been continued
+ SIGTTIN : constant := 21; -- background tty read attempted
+ SIGTTOU : constant := 22; -- background tty write attempted
+ SIGVTALRM : constant := 26; -- virtual timer expired
+ SIGPROF : constant := 27; -- profiling timer expired
+ SIGXCPU : constant := 24; -- CPU time limit exceeded
+ SIGXFSZ : constant := 25; -- filesize limit exceeded
+ SIGUNUSED : constant := 31; -- unused signal (GNU/Linux)
+ SIGSTKFLT : constant := 16; -- coprocessor stack fault (Linux)
+ SIGLTHRRES : constant := 32; -- GNU/LinuxThreads restart signal
+ SIGLTHRCAN : constant := 33; -- GNU/LinuxThreads cancel signal
+ SIGLTHRDBG : constant := 34; -- GNU/LinuxThreads debugger signal
+
+ SIGADAABORT : constant := SIGABRT;
+ -- Change this if you want to use another signal for task abort.
+ -- SIGTERM might be a good one.
+
+ type Signal_Set is array (Natural range <>) of Signal;
+
+ Unmasked : constant Signal_Set := (
+ SIGTRAP,
+ -- To enable debugging on multithreaded applications, mark SIGTRAP to
+ -- be kept unmasked.
+
+ SIGBUS,
+
+ SIGTTIN, SIGTTOU, SIGTSTP,
+ -- Keep these three signals unmasked so that background processes
+ -- and IO behaves as normal "C" applications
+
+ SIGPROF,
+ -- To avoid confusing the profiler
+
+ SIGKILL, SIGSTOP,
+ -- These two signals actually cannot be masked;
+ -- POSIX simply won't allow it.
+
+ SIGLTHRRES, SIGLTHRCAN, SIGLTHRDBG);
+ -- These three signals are used by GNU/LinuxThreads starting from
+ -- glibc 2.1 (future 2.2).
+
+ Reserved : constant Signal_Set :=
+ -- I am not sure why the following two signals are reserved.
+ -- I guess they are not supported by this version of GNU/Linux.
+ (SIGVTALRM, SIGUNUSED);
+
+ type sigset_t is private;
+
+ function sigaddset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigaddset, "sigaddset");
+
+ function sigdelset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigdelset, "sigdelset");
+
+ function sigfillset (set : access sigset_t) return int;
+ pragma Import (C, sigfillset, "sigfillset");
+
+ function sigismember (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigismember, "sigismember");
+
+ function sigemptyset (set : access sigset_t) return int;
+ pragma Import (C, sigemptyset, "sigemptyset");
+
+ type union_type_3 is new String (1 .. 116);
+ type siginfo_t is record
+ si_signo : int;
+ si_code : int;
+ si_errno : int;
+ X_data : union_type_3;
+ end record;
+ pragma Convention (C, siginfo_t);
+
+ type struct_sigaction is record
+ sa_handler : System.Address;
+ sa_mask : sigset_t;
+ sa_flags : unsigned_long;
+ sa_restorer : System.Address;
+ end record;
+ pragma Convention (C, struct_sigaction);
+ type struct_sigaction_ptr is access all struct_sigaction;
+
+ type Machine_State is record
+ eip : unsigned_long;
+ ebx : unsigned_long;
+ esp : unsigned_long;
+ ebp : unsigned_long;
+ esi : unsigned_long;
+ edi : unsigned_long;
+ end record;
+ type Machine_State_Ptr is access all Machine_State;
+
+ SA_SIGINFO : constant := 16#04#;
+
+ SIG_BLOCK : constant := 0;
+ SIG_UNBLOCK : constant := 1;
+ SIG_SETMASK : constant := 2;
+
+ SIG_DFL : constant := 0;
+ SIG_IGN : constant := 1;
+
+ function sigaction
+ (sig : Signal;
+ act : struct_sigaction_ptr;
+ oact : struct_sigaction_ptr) return int;
+ pragma Import (C, sigaction, "sigaction");
+
+ ----------
+ -- Time --
+ ----------
+
+ type timespec is private;
+
+ function To_Duration (TS : timespec) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timespec (D : Duration) return timespec;
+ pragma Inline (To_Timespec);
+
+ type struct_timeval is private;
+
+ function To_Duration (TV : struct_timeval) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timeval (D : Duration) return struct_timeval;
+ pragma Inline (To_Timeval);
+
+ function gettimeofday
+ (tv : access struct_timeval;
+ tz : System.Address := System.Null_Address) return int;
+ pragma Import (C, gettimeofday, "gettimeofday");
+
+ function sysconf (name : int) return long;
+ pragma Import (C, sysconf);
+
+ SC_CLK_TCK : constant := 2;
+
+ -------------------------
+ -- Priority Scheduling --
+ -------------------------
+
+ SCHED_OTHER : constant := 0;
+ SCHED_FIFO : constant := 1;
+ SCHED_RR : constant := 2;
+
+ -------------
+ -- Process --
+ -------------
+
+ type pid_t is private;
+
+ function kill (pid : pid_t; sig : Signal) return int;
+ pragma Import (C, kill, "kill");
+
+ function getpid return pid_t;
+ pragma Import (C, getpid, "getpid");
+
+ -------------
+ -- Threads --
+ -------------
+
+ type Thread_Body is access
+ function (arg : System.Address) return System.Address;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ type pthread_t is new unsigned_long;
+ subtype Thread_Id is pthread_t;
+
+ function To_pthread_t is new Unchecked_Conversion
+ (unsigned_long, pthread_t);
+
+ type pthread_mutex_t is limited private;
+ type pthread_cond_t is limited private;
+ type pthread_attr_t is limited private;
+ type pthread_mutexattr_t is limited private;
+ type pthread_condattr_t is limited private;
+ type pthread_key_t is private;
+
+ PTHREAD_CREATE_DETACHED : constant := 1;
+
+ -----------
+ -- Stack --
+ -----------
+
+ function Get_Stack_Base (thread : pthread_t) return Address;
+ pragma Inline (Get_Stack_Base);
+ -- This is a dummy procedure to share some GNULLI files
+
+ ---------------------------------------
+ -- Nonstandard Thread Initialization --
+ ---------------------------------------
+
+ procedure pthread_init;
+ pragma Inline (pthread_init);
+ -- This is a dummy procedure to share some GNULLI files
+
+ -------------------------
+ -- POSIX.1c Section 3 --
+ -------------------------
+
+ function sigwait (set : access sigset_t; sig : access Signal) return int;
+ pragma Import (C, sigwait, "sigwait");
+
+ function pthread_kill (thread : pthread_t; sig : Signal) return int;
+ pragma Import (C, pthread_kill, "pthread_kill");
+
+ type sigset_t_ptr is access all sigset_t;
+
+ function pthread_sigmask
+ (how : int;
+ set : sigset_t_ptr;
+ oset : sigset_t_ptr) return int;
+ pragma Import (C, pthread_sigmask, "pthread_sigmask");
+
+ --------------------------
+ -- POSIX.1c Section 11 --
+ --------------------------
+
+ function pthread_mutexattr_init
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_init, "pthread_mutexattr_init");
+
+ function pthread_mutexattr_destroy
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_destroy, "pthread_mutexattr_destroy");
+
+ function pthread_mutex_init
+ (mutex : access pthread_mutex_t;
+ attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutex_init, "pthread_mutex_init");
+
+ function pthread_mutex_destroy (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_destroy, "pthread_mutex_destroy");
+
+ function pthread_mutex_lock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_lock, "pthread_mutex_lock");
+
+ function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_unlock, "pthread_mutex_unlock");
+
+ function pthread_condattr_init
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_init, "pthread_condattr_init");
+
+ function pthread_condattr_destroy
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_destroy, "pthread_condattr_destroy");
+
+ function pthread_cond_init
+ (cond : access pthread_cond_t;
+ attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_cond_init, "pthread_cond_init");
+
+ function pthread_cond_destroy (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_destroy, "pthread_cond_destroy");
+
+ function pthread_cond_signal (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_signal, "pthread_cond_signal");
+
+ function pthread_cond_wait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_cond_wait, "pthread_cond_wait");
+
+ function pthread_cond_timedwait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ abstime : access timespec) return int;
+ pragma Import (C, pthread_cond_timedwait, "pthread_cond_timedwait");
+
+ --------------------------
+ -- POSIX.1c Section 13 --
+ --------------------------
+
+ type struct_sched_param is record
+ sched_priority : int; -- scheduling priority
+ end record;
+ pragma Convention (C, struct_sched_param);
+
+ function pthread_setschedparam
+ (thread : pthread_t;
+ policy : int;
+ param : access struct_sched_param) return int;
+ pragma Import (C, pthread_setschedparam, "pthread_setschedparam");
+
+ function pthread_attr_setschedpolicy
+ (attr : access pthread_attr_t;
+ policy : int) return int;
+ pragma Import
+ (C, pthread_attr_setschedpolicy, "pthread_attr_setschedpolicy");
+
+ function sched_yield return int;
+ pragma Import (C, sched_yield, "sched_yield");
+
+ ---------------------------
+ -- P1003.1c - Section 16 --
+ ---------------------------
+
+ function pthread_attr_init
+ (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_init, "pthread_attr_init");
+
+ function pthread_attr_destroy
+ (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_destroy, "pthread_attr_destroy");
+
+ function pthread_attr_setdetachstate
+ (attr : access pthread_attr_t;
+ detachstate : int) return int;
+ pragma Import
+ (C, pthread_attr_setdetachstate, "pthread_attr_setdetachstate");
+
+ function pthread_attr_setstacksize
+ (attr : access pthread_attr_t;
+ stacksize : size_t) return int;
+ pragma Import (C, pthread_attr_setstacksize, "pthread_attr_setstacksize");
+
+ function pthread_create
+ (thread : access pthread_t;
+ attributes : access pthread_attr_t;
+ start_routine : Thread_Body;
+ arg : System.Address) return int;
+ pragma Import (C, pthread_create, "pthread_create");
+
+ procedure pthread_exit (status : System.Address);
+ pragma Import (C, pthread_exit, "pthread_exit");
+
+ function pthread_self return pthread_t;
+ pragma Import (C, pthread_self, "pthread_self");
+
+ --------------------------
+ -- POSIX.1c Section 17 --
+ --------------------------
+
+ function pthread_setspecific
+ (key : pthread_key_t;
+ value : System.Address) return int;
+ pragma Import (C, pthread_setspecific, "pthread_setspecific");
+
+ function pthread_getspecific (key : pthread_key_t) return System.Address;
+ pragma Import (C, pthread_getspecific, "pthread_getspecific");
+
+ type destructor_pointer is access procedure (arg : System.Address);
+
+ function pthread_key_create
+ (key : access pthread_key_t;
+ destructor : destructor_pointer) return int;
+ pragma Import (C, pthread_key_create, "pthread_key_create");
+
+private
+
+ type sigset_t is array (0 .. 127) of unsigned_char;
+ pragma Convention (C, sigset_t);
+
+ type pid_t is new int;
+
+ type time_t is new long;
+
+ type timespec is record
+ tv_sec : time_t;
+ tv_nsec : long;
+ end record;
+ pragma Convention (C, timespec);
+
+ type struct_timeval is record
+ tv_sec : time_t;
+ tv_usec : time_t;
+ end record;
+ pragma Convention (C, struct_timeval);
+
+ type pthread_attr_t is record
+ detachstate : int;
+ schedpolicy : int;
+ schedparam : struct_sched_param;
+ inheritsched : int;
+ scope : int;
+ guardsize : size_t;
+ stackaddr_set : int;
+ stackaddr : System.Address;
+ stacksize : size_t;
+ end record;
+ pragma Convention (C, pthread_attr_t);
+
+ type pthread_condattr_t is record
+ dummy : int;
+ end record;
+ pragma Convention (C, pthread_condattr_t);
+
+ type pthread_mutexattr_t is record
+ mutexkind : int;
+ end record;
+ pragma Convention (C, pthread_mutexattr_t);
+
+ type struct_pthread_fast_lock is record
+ status : long;
+ spinlock : int;
+ end record;
+ pragma Convention (C, struct_pthread_fast_lock);
+
+ type pthread_mutex_t is record
+ m_reserved : int;
+ m_count : int;
+ m_owner : System.Address;
+ m_kind : int;
+ m_lock : struct_pthread_fast_lock;
+ end record;
+ pragma Convention (C, pthread_mutex_t);
+
+ type pthread_cond_t is array (0 .. 47) of unsigned_char;
+ pragma Convention (C, pthread_cond_t);
+
+ type pthread_key_t is new unsigned;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-lynxos-3.adb b/gcc/ada/s-osinte-lynxos-3.adb
new file mode 100644
index 00000000000..156601442b3
--- /dev/null
+++ b/gcc/ada/s-osinte-lynxos-3.adb
@@ -0,0 +1,597 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1999-2003 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- --
+-- 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, 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, --
+-- 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 is a LynxOS (Native) version of this package
+
+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 Interfaces.C;
+
+package body System.OS_Interface is
+
+ use Interfaces.C;
+
+ -------------------
+ -- clock_gettime --
+ -------------------
+
+ function clock_gettime
+ (clock_id : clockid_t;
+ tp : access timespec)
+ return int
+ is
+ function clock_gettime_base
+ (clock_id : clockid_t;
+ tp : access timespec)
+ return int;
+ pragma Import (C, clock_gettime_base, "clock_gettime");
+
+ begin
+ if clock_gettime_base (clock_id, tp) /= 0 then
+ return errno;
+ end if;
+
+ return 0;
+ end clock_gettime;
+
+ -----------------
+ -- To_Duration --
+ -----------------
+
+ function To_Duration (TS : timespec) return Duration is
+ begin
+ return Duration (TS.tv_sec) + Duration (TS.tv_nsec) / 10#1#E9;
+ end To_Duration;
+
+ function To_Duration (TV : struct_timeval) return Duration is
+ begin
+ return Duration (TV.tv_sec) + Duration (TV.tv_usec) / 10#1#E6;
+ end To_Duration;
+
+ -----------------
+ -- To_Timespec --
+ -----------------
+
+ function To_Timespec (D : Duration) return timespec is
+ S : time_t;
+ F : Duration;
+
+ begin
+ S := time_t (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return timespec'(tv_sec => S,
+ tv_nsec => long (Long_Long_Integer (F * 10#1#E9)));
+ end To_Timespec;
+
+ ----------------
+ -- To_Timeval --
+ ----------------
+
+ function To_Timeval (D : Duration) return struct_timeval is
+ S : time_t;
+ F : Duration;
+
+ begin
+ S := time_t (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return struct_timeval'(tv_sec => S,
+ tv_usec => time_t (Long_Long_Integer (F * 10#1#E6)));
+ end To_Timeval;
+
+ -------------------------
+ -- POSIX.1c Section 3 --
+ -------------------------
+
+ function sigwait
+ (set : access sigset_t;
+ sig : access Signal)
+ return int
+ is
+ function sigwait_base
+ (set : access sigset_t;
+ value : System.Address)
+ return Signal;
+ pragma Import (C, sigwait_base, "sigwait");
+
+ begin
+ sig.all := sigwait_base (set, Null_Address);
+
+ if sig.all = -1 then
+ return errno;
+ end if;
+
+ return 0;
+ end sigwait;
+
+ --------------------------
+ -- POSIX.1c Section 11 --
+ --------------------------
+
+ -- For all the following functions, LynxOS threads has the POSIX Draft 4
+ -- begavior; it sets errno but the standard Posix requires it to be
+ -- returned.
+
+ function pthread_mutexattr_init
+ (attr : access pthread_mutexattr_t)
+ return int
+ is
+ function pthread_mutexattr_create
+ (attr : access pthread_mutexattr_t)
+ return int;
+ pragma Import (C, pthread_mutexattr_create, "pthread_mutexattr_create");
+
+ begin
+ if pthread_mutexattr_create (attr) /= 0 then
+ return errno;
+ end if;
+
+ return 0;
+ end pthread_mutexattr_init;
+
+ function pthread_mutexattr_destroy
+ (attr : access pthread_mutexattr_t)
+ return int
+ is
+ function pthread_mutexattr_delete
+ (attr : access pthread_mutexattr_t)
+ return int;
+ pragma Import (C, pthread_mutexattr_delete, "pthread_mutexattr_delete");
+
+ begin
+ if pthread_mutexattr_delete (attr) /= 0 then
+ return errno;
+ end if;
+
+ return 0;
+ end pthread_mutexattr_destroy;
+
+ function pthread_mutex_init
+ (mutex : access pthread_mutex_t;
+ attr : access pthread_mutexattr_t)
+ return int
+ is
+ function pthread_mutex_init_base
+ (mutex : access pthread_mutex_t;
+ attr : pthread_mutexattr_t)
+ return int;
+ pragma Import (C, pthread_mutex_init_base, "pthread_mutex_init");
+
+ begin
+ if pthread_mutex_init_base (mutex, attr.all) /= 0 then
+ return errno;
+ end if;
+
+ return 0;
+ end pthread_mutex_init;
+
+ function pthread_mutex_destroy
+ (mutex : access pthread_mutex_t)
+ return int
+ is
+ function pthread_mutex_destroy_base
+ (mutex : access pthread_mutex_t)
+ return int;
+ pragma Import (C, pthread_mutex_destroy_base, "pthread_mutex_destroy");
+
+ begin
+ if pthread_mutex_destroy_base (mutex) /= 0 then
+ return errno;
+ end if;
+
+ return 0;
+ end pthread_mutex_destroy;
+
+ function pthread_mutex_lock
+ (mutex : access pthread_mutex_t)
+ return int
+ is
+ function pthread_mutex_lock_base
+ (mutex : access pthread_mutex_t)
+ return int;
+ pragma Import (C, pthread_mutex_lock_base, "pthread_mutex_lock");
+
+ begin
+ if pthread_mutex_lock_base (mutex) /= 0 then
+ return errno;
+ end if;
+
+ return 0;
+ end pthread_mutex_lock;
+
+ function pthread_mutex_unlock
+ (mutex : access pthread_mutex_t)
+ return int
+ is
+ function pthread_mutex_unlock_base
+ (mutex : access pthread_mutex_t)
+ return int;
+ pragma Import (C, pthread_mutex_unlock_base, "pthread_mutex_unlock");
+
+ begin
+ if pthread_mutex_unlock_base (mutex) /= 0 then
+ return errno;
+ end if;
+
+ return 0;
+ end pthread_mutex_unlock;
+
+ function pthread_condattr_init
+ (attr : access pthread_condattr_t)
+ return int
+ is
+ function pthread_condattr_create
+ (attr : access pthread_condattr_t)
+ return int;
+ pragma Import (C, pthread_condattr_create, "pthread_condattr_create");
+
+ begin
+ if pthread_condattr_create (attr) /= 0 then
+ return errno;
+ end if;
+
+ return 0;
+ end pthread_condattr_init;
+
+ function pthread_condattr_destroy
+ (attr : access pthread_condattr_t)
+ return int
+ is
+ function pthread_condattr_delete
+ (attr : access pthread_condattr_t)
+ return int;
+ pragma Import (C, pthread_condattr_delete, "pthread_condattr_delete");
+
+ begin
+ if pthread_condattr_delete (attr) /= 0 then
+ return errno;
+ end if;
+
+ return 0;
+ end pthread_condattr_destroy;
+
+ function pthread_cond_init
+ (cond : access pthread_cond_t;
+ attr : access pthread_condattr_t)
+ return int
+ is
+ function pthread_cond_init_base
+ (cond : access pthread_cond_t;
+ attr : pthread_condattr_t)
+ return int;
+ pragma Import (C, pthread_cond_init_base, "pthread_cond_init");
+
+ begin
+ if pthread_cond_init_base (cond, attr.all) /= 0 then
+ return errno;
+ end if;
+
+ return 0;
+ end pthread_cond_init;
+
+ function pthread_cond_destroy
+ (cond : access pthread_cond_t)
+ return int
+ is
+ function pthread_cond_destroy_base
+ (cond : access pthread_cond_t)
+ return int;
+ pragma Import (C, pthread_cond_destroy_base, "pthread_cond_destroy");
+
+ begin
+ if pthread_cond_destroy_base (cond) /= 0 then
+ return errno;
+ end if;
+
+ return 0;
+ end pthread_cond_destroy;
+
+ function pthread_cond_signal
+ (cond : access pthread_cond_t)
+ return int
+ is
+ function pthread_cond_signal_base
+ (cond : access pthread_cond_t)
+ return int;
+ pragma Import (C, pthread_cond_signal_base, "pthread_cond_signal");
+
+ begin
+ if pthread_cond_signal_base (cond) /= 0 then
+ return errno;
+ end if;
+
+ return 0;
+ end pthread_cond_signal;
+
+ function pthread_cond_wait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t)
+ return int
+ is
+ function pthread_cond_wait_base
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t)
+ return int;
+ pragma Import (C, pthread_cond_wait_base, "pthread_cond_wait");
+
+ begin
+ if pthread_cond_wait_base (cond, mutex) /= 0 then
+ return errno;
+ end if;
+
+ return 0;
+ end pthread_cond_wait;
+
+ function pthread_cond_timedwait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ reltime : access timespec) return int
+ is
+ function pthread_cond_timedwait_base
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ reltime : access timespec) return int;
+ pragma Import (C, pthread_cond_timedwait_base, "pthread_cond_timedwait");
+
+ begin
+ if pthread_cond_timedwait_base (cond, mutex, reltime) /= 0 then
+ if errno = EAGAIN then
+ return ETIMEDOUT;
+ end if;
+
+ return errno;
+ end if;
+
+ return 0;
+ end pthread_cond_timedwait;
+
+ --------------------------
+ -- POSIX.1c Section 13 --
+ --------------------------
+
+ function pthread_setschedparam
+ (thread : pthread_t;
+ policy : int;
+ param : access struct_sched_param)
+ return int
+ is
+ function pthread_setscheduler
+ (thread : pthread_t;
+ policy : int;
+ prio : int)
+ return int;
+ pragma Import (C, pthread_setscheduler, "pthread_setscheduler");
+
+ begin
+ if pthread_setscheduler (thread, policy, param.sched_priority) = -1 then
+ return errno;
+ end if;
+
+ return 0;
+ end pthread_setschedparam;
+
+ function pthread_mutexattr_setprotocol
+ (attr : access pthread_mutexattr_t;
+ protocol : int)
+ return int
+ is
+ pragma Unreferenced (attr, protocol);
+ begin
+ return 0;
+ end pthread_mutexattr_setprotocol;
+
+ function pthread_mutexattr_setprioceiling
+ (attr : access pthread_mutexattr_t;
+ prioceiling : int)
+ return int
+ is
+ pragma Unreferenced (attr, prioceiling);
+ begin
+ return 0;
+ end pthread_mutexattr_setprioceiling;
+
+ function pthread_attr_setscope
+ (attr : access pthread_attr_t;
+ contentionscope : int)
+ return int
+ is
+ pragma Unreferenced (attr, contentionscope);
+ begin
+ return 0;
+ end pthread_attr_setscope;
+
+ function sched_yield return int is
+ procedure pthread_yield;
+ pragma Import (C, pthread_yield, "pthread_yield");
+
+ begin
+ pthread_yield;
+ return 0;
+ end sched_yield;
+
+ -----------------------------
+ -- P1003.1c - Section 16 --
+ -----------------------------
+
+ function pthread_attr_setdetachstate
+ (attr : access pthread_attr_t;
+ detachstate : int)
+ return int
+ is
+ pragma Unreferenced (attr, detachstate);
+ begin
+ return 0;
+ end pthread_attr_setdetachstate;
+
+ function pthread_create
+ (thread : access pthread_t;
+ attributes : access pthread_attr_t;
+ start_routine : Thread_Body;
+ arg : System.Address)
+ return int
+ is
+ -- The LynxOS pthread_create doesn't seems to work.
+ -- Workaround : We're using st_new instead.
+ --
+ -- function pthread_create_base
+ -- (thread : access pthread_t;
+ -- attributes : pthread_attr_t;
+ -- start_routine : Thread_Body;
+ -- arg : System.Address)
+ -- return int;
+ -- pragma Import (C, pthread_create_base, "pthread_create");
+
+ St : aliased st_t := attributes.st;
+
+ function st_new
+ (start_routine : Thread_Body;
+ arg : System.Address;
+ attributes : access st_t;
+ thread : access pthread_t)
+ return int;
+ pragma Import (C, st_new, "st_new");
+
+ begin
+ -- Following code would be used if above commented function worked
+
+ -- if pthread_create_base
+ -- (thread, attributes.all, start_routine, arg) /= 0 then
+
+ if st_new (start_routine, arg, St'Access, thread) /= 0 then
+ return errno;
+ end if;
+
+ return 0;
+ end pthread_create;
+
+ function pthread_detach (thread : pthread_t) return int is
+ aliased_thread : aliased pthread_t := thread;
+
+ function pthread_detach_base (thread : access pthread_t) return int;
+ pragma Import (C, pthread_detach_base, "pthread_detach");
+
+ begin
+ if pthread_detach_base (aliased_thread'Access) /= 0 then
+ return errno;
+ end if;
+
+ return 0;
+ end pthread_detach;
+
+ --------------------------
+ -- POSIX.1c Section 17 --
+ --------------------------
+
+ function pthread_setspecific
+ (key : pthread_key_t;
+ value : System.Address)
+ return int
+ is
+ function pthread_setspecific_base
+ (key : pthread_key_t;
+ value : System.Address)
+ return int;
+ pragma Import (C, pthread_setspecific_base, "pthread_setspecific");
+
+ begin
+ if pthread_setspecific_base (key, value) /= 0 then
+ return errno;
+ end if;
+
+ return 0;
+ end pthread_setspecific;
+
+ function pthread_getspecific (key : pthread_key_t) return System.Address is
+ procedure pthread_getspecific_base
+ (key : pthread_key_t;
+ value : access System.Address);
+ pragma Import (C, pthread_getspecific_base, "pthread_getspecific");
+
+ value : aliased System.Address := System.Null_Address;
+
+ begin
+ pthread_getspecific_base (key, value'Unchecked_Access);
+ return value;
+ end pthread_getspecific;
+
+ function Get_Stack_Base (thread : pthread_t) return Address is
+ pragma Warnings (Off, thread);
+
+ begin
+ return Null_Address;
+ end Get_Stack_Base;
+
+ function pthread_key_create
+ (key : access pthread_key_t;
+ destructor : destructor_pointer)
+ return int
+ is
+ function pthread_keycreate
+ (key : access pthread_key_t;
+ destructor : destructor_pointer)
+ return int;
+ pragma Import (C, pthread_keycreate, "pthread_keycreate");
+
+ begin
+ if pthread_keycreate (key, destructor) /= 0 then
+ return errno;
+ end if;
+
+ return 0;
+ end pthread_key_create;
+
+ procedure pthread_init is
+ begin
+ null;
+ end pthread_init;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-lynxos-3.ads b/gcc/ada/s-osinte-lynxos-3.ads
new file mode 100644
index 00000000000..71607a408a6
--- /dev/null
+++ b/gcc/ada/s-osinte-lynxos-3.ads
@@ -0,0 +1,564 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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 is a LynxOS (Native) version of this package
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+with Interfaces.C;
+with Unchecked_Conversion;
+
+package System.OS_Interface is
+ pragma Preelaborate;
+
+ pragma Linker_Options ("-mthreads");
+
+ subtype int is Interfaces.C.int;
+ subtype char is Interfaces.C.char;
+ subtype short is Interfaces.C.short;
+ subtype long is Interfaces.C.long;
+ subtype unsigned is Interfaces.C.unsigned;
+ subtype unsigned_short is Interfaces.C.unsigned_short;
+ subtype unsigned_long is Interfaces.C.unsigned_long;
+ subtype unsigned_char is Interfaces.C.unsigned_char;
+ subtype plain_char is Interfaces.C.plain_char;
+ subtype size_t is Interfaces.C.size_t;
+
+ -----------
+ -- Errno --
+ -----------
+
+ function errno return int;
+ pragma Import (C, errno, "__get_errno");
+
+ EAGAIN : constant := 11;
+ EINTR : constant := 4;
+ EINVAL : constant := 22;
+ ENOMEM : constant := 12;
+ ETIMEDOUT : constant := 60;
+
+ -------------
+ -- Signals --
+ -------------
+
+ Max_Interrupt : constant := 63;
+ type Signal is new int range 0 .. Max_Interrupt;
+ for Signal'Size use int'Size;
+
+ SIGHUP : constant := 1; -- hangup
+ SIGINT : constant := 2; -- interrupt (rubout)
+ SIGQUIT : constant := 3; -- quit (ASCD FS)
+ SIGILL : constant := 4; -- illegal instruction (not reset)
+ SIGTRAP : constant := 5; -- trace trap (not reset)
+ SIGBRK : constant := 6; -- break
+ SIGIOT : constant := 6; -- IOT instruction
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGCORE : constant := 7; -- kill with core dump
+ SIGEMT : constant := 7; -- EMT instruction
+ SIGFPE : constant := 8; -- floating point exception
+ SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
+ SIGBUS : constant := 10; -- bus error
+ SIGSEGV : constant := 11; -- segmentation violation
+ SIGSYS : constant := 12; -- bad argument to system call
+ SIGPIPE : constant := 13; -- write on a pipe with no one to read it
+ SIGALRM : constant := 14; -- alarm clock
+ SIGTERM : constant := 15; -- software termination signal from kill
+ SIGURG : constant := 16; -- urgent condition on IO channel
+ SIGSTOP : constant := 17; -- stop (cannot be caught or ignored)
+ SIGTSTP : constant := 18; -- user stop requested from tty
+ SIGCONT : constant := 19; -- stopped process has been continued
+ SIGCLD : constant := 20; -- alias for SIGCHLD
+ SIGCHLD : constant := 20; -- child status change
+ SIGTTIN : constant := 21; -- background tty read attempted
+ SIGTTOU : constant := 22; -- background tty write attempted
+ SIGIO : constant := 23; -- I/O possible (Solaris SIGPOLL alias)
+ SIGPOLL : constant := 23; -- pollable event occurred
+ SIGXCPU : constant := 24; -- CPU time limit exceeded
+ SIGXFSZ : constant := 25; -- filesize limit exceeded
+ SIGVTALRM : constant := 26; -- virtual timer expired
+ SIGPROF : constant := 27; -- profiling timer expired
+ SIGWINCH : constant := 28; -- window size change
+ SIGLOST : constant := 29; -- SUN 4.1 compatibility
+ SIGUSR1 : constant := 30; -- user defined signal 1
+ SIGUSR2 : constant := 31; -- user defined signal 2
+ SIGPRIO : constant := 32; -- sent to a process with its priority or
+ -- group is changed
+
+ SIGADAABORT : constant := SIGABRT;
+ -- Change this if you want to use another signal for task abort.
+ -- SIGTERM might be a good one.
+
+ type Signal_Set is array (Natural range <>) of Signal;
+
+ Unmasked : constant Signal_Set :=
+ (SIGTRAP, SIGTTIN, SIGTTOU, SIGTSTP, SIGPROF);
+ Reserved : constant Signal_Set := (SIGABRT, SIGKILL, SIGSTOP, SIGPRIO);
+
+ type sigset_t is private;
+
+ function sigaddset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigaddset, "sigaddset");
+
+ function sigdelset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigdelset, "sigdelset");
+
+ function sigfillset (set : access sigset_t) return int;
+ pragma Import (C, sigfillset, "sigfillset");
+
+ function sigismember (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigismember, "sigismember");
+
+ function sigemptyset (set : access sigset_t) return int;
+ pragma Import (C, sigemptyset, "sigemptyset");
+
+ type struct_sigaction is record
+ sa_handler : System.Address;
+ sa_mask : sigset_t;
+ sa_flags : int;
+ end record;
+ pragma Convention (C, struct_sigaction);
+ type struct_sigaction_ptr is access all struct_sigaction;
+
+ SA_SIGINFO : constant := 16#80#;
+
+ SIG_BLOCK : constant := 0;
+ SIG_UNBLOCK : constant := 1;
+ SIG_SETMASK : constant := 2;
+
+ SIG_DFL : constant := 0;
+ SIG_IGN : constant := 1;
+
+ function sigaction
+ (sig : Signal;
+ act : struct_sigaction_ptr;
+ oact : struct_sigaction_ptr) return int;
+ pragma Import (C, sigaction, "sigaction");
+
+ ----------
+ -- Time --
+ ----------
+
+ Time_Slice_Supported : constant Boolean := True;
+ -- Indicates wether time slicing is supported
+
+ type timespec is private;
+
+ type clockid_t is private;
+
+ CLOCK_REALTIME : constant clockid_t;
+
+ function clock_gettime
+ (clock_id : clockid_t;
+ tp : access timespec) return int;
+ pragma Inline (clock_gettime);
+ -- LynxOS has non standard clock_gettime
+
+ function To_Duration (TS : timespec) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timespec (D : Duration) return timespec;
+ pragma Inline (To_Timespec);
+
+ type struct_timezone is record
+ tz_minuteswest : int;
+ tz_dsttime : int;
+ end record;
+ pragma Convention (C, struct_timezone);
+ type struct_timezone_ptr is access all struct_timezone;
+
+ type struct_timeval is private;
+ -- This is needed on systems that do not have clock_gettime()
+ -- but do have gettimeofday().
+
+ function To_Duration (TV : struct_timeval) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timeval (D : Duration) return struct_timeval;
+ pragma Inline (To_Timeval);
+
+ -------------------------
+ -- Priority Scheduling --
+ -------------------------
+
+ SCHED_FIFO : constant := 16#00200000#;
+ SCHED_RR : constant := 16#00100000#;
+ SCHED_OTHER : constant := 16#00400000#;
+
+ -------------
+ -- Process --
+ -------------
+
+ type pid_t is private;
+
+ function kill (pid : pid_t; sig : Signal) return int;
+ pragma Import (C, kill, "kill");
+
+ function getpid return pid_t;
+ pragma Import (C, getpid, "getpid");
+
+ ---------
+ -- LWP --
+ ---------
+
+ function lwp_self return System.Address;
+ -- lwp_self does not exist on this thread library, revert to pthread_self
+ -- which is the closest approximation (with getpid). This function is
+ -- needed to share 7staprop.adb across POSIX-like targets.
+ pragma Import (C, lwp_self, "pthread_self");
+
+ -------------
+ -- Threads --
+ -------------
+
+ type Thread_Body is access
+ function (arg : System.Address) return System.Address;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ type pthread_t is private;
+ subtype Thread_Id is pthread_t;
+
+ type pthread_mutex_t is limited private;
+ type pthread_cond_t is limited private;
+ type st_t is limited private;
+ type pthread_attr_t is limited private;
+ type pthread_mutexattr_t is limited private;
+ type pthread_condattr_t is limited private;
+ type pthread_key_t is private;
+
+ PTHREAD_CREATE_DETACHED : constant := 0;
+
+ -----------
+ -- Stack --
+ -----------
+
+ Stack_Base_Available : constant Boolean := False;
+ -- Indicates wether the stack base is available on this target.
+
+ function Get_Stack_Base (thread : pthread_t) return Address;
+ pragma Inline (Get_Stack_Base);
+ -- returns the stack base of the specified thread.
+ -- Only call this function when Stack_Base_Available is True.
+
+ 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
+
+ PROT_NONE : constant := 0;
+ PROT_READ : constant := 1;
+ PROT_WRITE : constant := 2;
+ PROT_EXEC : constant := 4;
+ PROT_USER : constant := 8;
+ PROT_ALL : constant := PROT_READ + PROT_WRITE + PROT_EXEC + PROT_USER;
+
+ PROT_ON : constant := PROT_READ;
+ PROT_OFF : constant := PROT_ALL;
+
+ function mprotect (addr : Address; len : size_t; prot : int) return int;
+ pragma Import (C, mprotect);
+
+ -------------------------
+ -- POSIX.1c Section 3 --
+ -------------------------
+
+ function sigwait
+ (set : access sigset_t;
+ sig : access Signal) return int;
+ pragma Inline (sigwait);
+ -- LynxOS has non standard sigwait
+
+ function pthread_kill (thread : pthread_t; sig : Signal) return int;
+ pragma Import (C, pthread_kill, "pthread_kill");
+
+ type sigset_t_ptr is access all sigset_t;
+
+ function pthread_sigmask
+ (how : int;
+ set : sigset_t_ptr;
+ oset : sigset_t_ptr) return int;
+ pragma Import (C, pthread_sigmask, "sigprocmask");
+
+ --------------------------
+ -- POSIX.1c Section 11 --
+ --------------------------
+
+ function pthread_mutexattr_init
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Inline (pthread_mutexattr_init);
+ -- LynxOS has a nonstandard pthread_mutexattr_init
+
+ function pthread_mutexattr_destroy
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Inline (pthread_mutexattr_destroy);
+ -- Lynxos has a nonstandard pthread_mutexattr_destroy
+
+ function pthread_mutex_init
+ (mutex : access pthread_mutex_t;
+ attr : access pthread_mutexattr_t) return int;
+ pragma Inline (pthread_mutex_init);
+ -- LynxOS has a nonstandard pthread_mutex_init
+
+ function pthread_mutex_destroy (mutex : access pthread_mutex_t) return int;
+ pragma Inline (pthread_mutex_destroy);
+ -- LynxOS has a nonstandard pthread_mutex_destroy
+
+ function pthread_mutex_lock (mutex : access pthread_mutex_t) return int;
+ pragma Inline (pthread_mutex_lock);
+ -- LynxOS has a nonstandard pthread_mutex_lock
+
+ function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int;
+ pragma Inline (pthread_mutex_unlock);
+ -- LynxOS has a nonstandard pthread_mutex_unlock
+
+ function pthread_condattr_init
+ (attr : access pthread_condattr_t) return int;
+ pragma Inline (pthread_condattr_init);
+ -- LynxOS has a nonstandard pthread_condattr_init
+
+ function pthread_condattr_destroy
+ (attr : access pthread_condattr_t) return int;
+ pragma Inline (pthread_condattr_destroy);
+ -- LynxOS has a nonstandard pthread_condattr_destroy
+
+ function pthread_cond_init
+ (cond : access pthread_cond_t;
+ attr : access pthread_condattr_t) return int;
+ pragma Inline (pthread_cond_init);
+ -- LynxOS has a non standard pthread_cond_init
+
+ function pthread_cond_destroy (cond : access pthread_cond_t) return int;
+ pragma Inline (pthread_cond_destroy);
+ -- LynxOS has a nonstandard pthread_cond_destroy
+
+ function pthread_cond_signal (cond : access pthread_cond_t) return int;
+ pragma Inline (pthread_cond_signal);
+ -- LynxOS has a nonstandard pthread_cond_signal
+
+ function pthread_cond_wait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t) return int;
+ pragma Inline (pthread_cond_wait);
+ -- LynxOS has a nonstandard pthread_cond_wait
+
+ function pthread_cond_timedwait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ reltime : access timespec) return int;
+ pragma Inline (pthread_cond_timedwait);
+ -- LynxOS has a nonstandard pthrad_cond_timedwait
+
+ Relative_Timed_Wait : constant Boolean := True;
+ -- pthread_cond_timedwait requires a relative delay time
+
+ --------------------------
+ -- POSIX.1c Section 13 --
+ --------------------------
+
+ PTHREAD_PRIO_NONE : constant := 0;
+ PTHREAD_PRIO_INHERIT : constant := 0;
+ PTHREAD_PRIO_PROTECT : constant := 0;
+
+ type struct_sched_param is record
+ sched_priority : int; -- scheduling priority
+ end record;
+
+ function pthread_setschedparam
+ (thread : pthread_t;
+ policy : int;
+ param : access struct_sched_param) return int;
+ pragma Inline (pthread_setschedparam);
+ -- LynxOS doesn't have pthread_setschedparam.
+ -- Instead, use pthread_setscheduler
+
+ function pthread_mutexattr_setprotocol
+ (attr : access pthread_mutexattr_t;
+ protocol : int) return int;
+ pragma Inline (pthread_mutexattr_setprotocol);
+ -- LynxOS doesn't have pthread_mutexattr_setprotocol
+
+ function pthread_mutexattr_setprioceiling
+ (attr : access pthread_mutexattr_t;
+ prioceiling : int) return int;
+ pragma Inline (pthread_mutexattr_setprioceiling);
+ -- LynxOS doesn't have pthread_mutexattr_setprioceiling
+
+ function pthread_attr_setscope
+ (attr : access pthread_attr_t;
+ contentionscope : int) return int;
+ -- LynxOS doesn't have pthread_attr_setscope: all threads have system scope
+ pragma Inline (pthread_attr_setscope);
+
+ function pthread_attr_setschedpolicy
+ (attr : access pthread_attr_t;
+ policy : int) return int;
+ pragma Import (C, pthread_attr_setschedpolicy, "pthread_attr_setsched");
+
+ function sched_yield return int;
+ -- pragma Import (C, sched_yield, "sched_yield");
+ pragma Inline (sched_yield);
+
+ ---------------------------
+ -- P1003.1c - Section 16 --
+ ---------------------------
+
+ function pthread_attr_init (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_init, "pthread_attr_create");
+
+ function pthread_attr_destroy
+ (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_destroy, "pthread_attr_delete");
+
+ function pthread_attr_setdetachstate
+ (attr : access pthread_attr_t;
+ detachstate : int) return int;
+ pragma Inline (pthread_attr_setdetachstate);
+ -- LynxOS doesn't have pthread_attr_setdetachstate
+
+ function pthread_attr_setstacksize
+ (attr : access pthread_attr_t;
+ stacksize : size_t) return int;
+ pragma Import (C, pthread_attr_setstacksize, "pthread_attr_setstacksize");
+
+ function pthread_create
+ (thread : access pthread_t;
+ attributes : access pthread_attr_t;
+ start_routine : Thread_Body;
+ arg : System.Address) return int;
+ pragma Inline (pthread_create);
+ -- LynxOS has a non standard pthread_create
+
+ function pthread_detach (thread : pthread_t) return int;
+ pragma Inline (pthread_detach);
+
+ procedure pthread_exit (status : System.Address);
+ pragma Import (C, pthread_exit, "pthread_exit");
+
+ function pthread_self return pthread_t;
+ pragma Import (C, pthread_self, "pthread_self");
+
+ --------------------------
+ -- POSIX.1c Section 17 --
+ --------------------------
+
+ function pthread_setspecific
+ (key : pthread_key_t;
+ value : System.Address) return int;
+ pragma Inline (pthread_setspecific);
+ -- LynxOS has a non standard pthread_setspecific
+
+ function pthread_getspecific (key : pthread_key_t) return System.Address;
+ pragma Inline (pthread_getspecific);
+ -- LynxOS has a non standard pthread_getspecific
+
+ type destructor_pointer is access procedure (arg : System.Address);
+
+ function pthread_key_create
+ (key : access pthread_key_t;
+ destructor : destructor_pointer) return int;
+ pragma Inline (pthread_key_create);
+ -- LynxOS has a non standard pthread_keycreate
+
+ procedure pthread_init;
+ -- This is a dummy procedure to share some GNULLI files
+
+private
+
+ type sigbit_array is array (1 .. 2) of long;
+ type sigset_t is record
+ sa_sigbits : sigbit_array;
+ end record;
+ pragma Convention (C_Pass_By_Copy, sigset_t);
+
+ type pid_t is new long;
+
+ type time_t is new long;
+
+ type timespec is record
+ tv_sec : time_t;
+ tv_nsec : long;
+ end record;
+ pragma Convention (C, timespec);
+
+ type clockid_t is new unsigned_char;
+ CLOCK_REALTIME : constant clockid_t := 0;
+
+ type struct_timeval is record
+ tv_sec : time_t;
+ tv_usec : time_t;
+ end record;
+ pragma Convention (C, struct_timeval);
+
+ type st_t is record
+ stksize : int;
+ prio : int;
+ inheritsched : int;
+ state : int;
+ sched : int;
+ end record;
+ pragma Convention (C, st_t);
+
+ type pthread_attr_t is record
+ st : st_t;
+ pthread_attr_scope : int; -- ignored
+ end record;
+ pragma Convention (C, pthread_attr_t);
+
+ type pthread_condattr_t is new int;
+
+ type pthread_mutexattr_t is new int;
+
+ type tid_t is new short;
+ type pthread_t is new tid_t;
+
+ type synch_ptr is access all pthread_mutex_t;
+ type pthread_mutex_t is record
+ w_count : int;
+ mut_owner : int;
+ id : unsigned;
+ next : synch_ptr;
+ end record;
+ pragma Convention (C, pthread_mutex_t);
+
+ type pthread_cond_t is new pthread_mutex_t;
+
+ type pthread_key_t is new int;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-lynxos.adb b/gcc/ada/s-osinte-lynxos.adb
new file mode 100644
index 00000000000..0cb052632a3
--- /dev/null
+++ b/gcc/ada/s-osinte-lynxos.adb
@@ -0,0 +1,154 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2001-2002 Ada Core Technologies, 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- --
+-- 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, 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, --
+-- 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 is a LynxOS (POSIX Threads) version of this package
+
+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 Interfaces.C;
+
+package body System.OS_Interface is
+
+ use Interfaces.C;
+
+ -----------------
+ -- To_Duration --
+ -----------------
+
+ function To_Duration (TS : timespec) return Duration is
+ begin
+ return Duration (TS.tv_sec) + Duration (TS.tv_nsec) / 10#1#E9;
+ end To_Duration;
+
+ function To_Duration (TV : struct_timeval) return Duration is
+ begin
+ return Duration (TV.tv_sec) + Duration (TV.tv_usec) / 10#1#E6;
+ end To_Duration;
+
+ -----------------
+ -- To_Timespec --
+ -----------------
+
+ function To_Timespec (D : Duration) return timespec is
+ S : time_t;
+ F : Duration;
+
+ begin
+ S := time_t (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return timespec'(tv_sec => S,
+ tv_nsec => long (Long_Long_Integer (F * 10#1#E9)));
+ end To_Timespec;
+
+ ----------------
+ -- To_Timeval --
+ ----------------
+
+ function To_Timeval (D : Duration) return struct_timeval is
+ S : time_t;
+ F : Duration;
+
+ begin
+ S := time_t (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return
+ struct_timeval'
+ (tv_sec => S,
+ tv_usec => time_t (Long_Long_Integer (F * 10#1#E6)));
+ end To_Timeval;
+
+ -------------
+ -- sigwait --
+ -------------
+
+ function sigwait
+ (set : access sigset_t;
+ sig : access Signal)
+ return int
+ is
+ function sigwaitinfo
+ (set : access sigset_t;
+ info : System.Address) return Signal;
+ pragma Import (C, sigwaitinfo, "sigwaitinfo");
+
+ begin
+ sig.all := sigwaitinfo (set, Null_Address);
+
+ if sig.all = -1 then
+ return errno;
+ end if;
+
+ return 0;
+ end sigwait;
+
+ --------------------
+ -- Get_Stack_Base --
+ --------------------
+
+ function Get_Stack_Base (thread : pthread_t) return Address is
+ pragma Warnings (Off, thread);
+
+ begin
+ return Null_Address;
+ end Get_Stack_Base;
+
+ ------------------
+ -- pthread_init --
+ ------------------
+
+ procedure pthread_init is
+ begin
+ null;
+ end pthread_init;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-lynxos.ads b/gcc/ada/s-osinte-lynxos.ads
new file mode 100644
index 00000000000..8b6b33885d1
--- /dev/null
+++ b/gcc/ada/s-osinte-lynxos.ads
@@ -0,0 +1,592 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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 is a LynxOS (POSIX Threads) version of this package
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+with Interfaces.C;
+with Unchecked_Conversion;
+
+package System.OS_Interface is
+ pragma Preelaborate;
+
+ pragma Linker_Options ("-mthreads");
+ -- Selects the POSIX 1.c runtime, rather than the non-threading runtime
+ -- or the deprecated legacy threads library. The -mthreads flag is
+ -- defined in patch.LynxOS and matches the definition for Lynx's gcc.
+
+ subtype int is Interfaces.C.int;
+ subtype short is Interfaces.C.short;
+ subtype long is Interfaces.C.long;
+ subtype unsigned is Interfaces.C.unsigned;
+ subtype unsigned_short is Interfaces.C.unsigned_short;
+ subtype unsigned_long is Interfaces.C.unsigned_long;
+ subtype unsigned_char is Interfaces.C.unsigned_char;
+ subtype plain_char is Interfaces.C.plain_char;
+ subtype size_t is Interfaces.C.size_t;
+
+ -----------
+ -- Errno --
+ -----------
+
+ function errno return int;
+ pragma Import (C, errno, "__get_errno");
+
+ EAGAIN : constant := 11;
+ EINTR : constant := 4;
+ EINVAL : constant := 22;
+ ENOMEM : constant := 12;
+ ETIMEDOUT : constant := 60;
+
+ -------------
+ -- Signals --
+ -------------
+
+ Max_Interrupt : constant := 63;
+
+ -- Max_Interrupt is the number of OS signals, as defined in:
+ --
+ -- /usr/include/sys/signal.h
+ --
+ --
+ -- The lowest numbered signal is 1, but 0 is a valid argument to some
+ -- library functions, eg. kill(2). However, 0 is not just another
+ -- signal: For instance 'I in Signal' and similar should be used with
+ -- caution.
+
+ type Signal is new int range 0 .. Max_Interrupt;
+ for Signal'Size use int'Size;
+
+ SIGHUP : constant := 1; -- hangup
+ SIGINT : constant := 2; -- interrupt (rubout)
+ SIGQUIT : constant := 3; -- quit (ASCD FS)
+ SIGILL : constant := 4; -- illegal instruction (not reset)
+ SIGTRAP : constant := 5; -- trace trap (not reset)
+ SIGBRK : constant := 6; -- break
+ SIGIOT : constant := 6; -- IOT instruction
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in future
+ SIGCORE : constant := 7; -- kill with core dump
+ SIGEMT : constant := 7; -- EMT instruction
+ SIGFPE : constant := 8; -- floating point exception
+ SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
+ SIGBUS : constant := 10; -- bus error
+ SIGSEGV : constant := 11; -- segmentation violation
+ SIGSYS : constant := 12; -- bad argument to system call
+ SIGPIPE : constant := 13; -- write on a pipe with no one to read it
+ SIGALRM : constant := 14; -- alarm clock
+ SIGTERM : constant := 15; -- software termination signal from kill
+ SIGURG : constant := 16; -- urgent condition on IO channel
+ SIGSTOP : constant := 17; -- stop (cannot be caught or ignored)
+ SIGTSTP : constant := 18; -- user stop requested from tty
+ SIGCONT : constant := 19; -- stopped process has been continued
+ SIGCLD : constant := 20; -- alias for SIGCHLD
+ SIGCHLD : constant := 20; -- child status change
+ SIGTTIN : constant := 21; -- background tty read attempted
+ SIGTTOU : constant := 22; -- background tty write attempted
+ SIGIO : constant := 23; -- I/O possible (Solaris SIGPOLL alias)
+ SIGPOLL : constant := 23; -- pollable event occurred
+ SIGTHREADKILL : constant := 24; -- Reserved by LynxOS runtime
+ SIGXCPU : constant := 24; -- CPU time limit exceeded
+ SIGXFSZ : constant := 25; -- filesize limit exceeded
+ SIGVTALRM : constant := 26; -- virtual timer expired
+ SIGPROF : constant := 27; -- profiling timer expired
+ SIGWINCH : constant := 28; -- window size change
+ SIGLOST : constant := 29; -- SUN 4.1 compatibility
+ SIGUSR1 : constant := 30; -- user defined signal 1
+ SIGUSR2 : constant := 31; -- user defined signal 2
+
+ SIGPRIO : constant := 32;
+ -- sent to a process with its priority or group is changed
+
+ SIGADAABORT : constant := SIGABRT;
+ -- Change this if you want to use another signal for task abort.
+ -- SIGTERM might be a good one.
+
+ type Signal_Set is array (Natural range <>) of Signal;
+
+ Unmasked : constant Signal_Set :=
+ (SIGTRAP, SIGTTIN, SIGTTOU, SIGTSTP, SIGPROF, SIGTHREADKILL);
+ Reserved : constant Signal_Set := (SIGABRT, SIGKILL, SIGSTOP, SIGPRIO);
+
+ type sigset_t is private;
+
+ function sigaddset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigaddset, "sigaddset");
+
+ function sigdelset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigdelset, "sigdelset");
+
+ function sigfillset (set : access sigset_t) return int;
+ pragma Import (C, sigfillset, "sigfillset");
+
+ function sigismember (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigismember, "sigismember");
+
+ function sigemptyset (set : access sigset_t) return int;
+ pragma Import (C, sigemptyset, "sigemptyset");
+
+ type struct_sigaction is record
+ sa_handler : System.Address;
+ sa_mask : sigset_t;
+ sa_flags : int;
+ end record;
+ pragma Convention (C, struct_sigaction);
+ type struct_sigaction_ptr is access all struct_sigaction;
+
+ SA_SIGINFO : constant := 16#80#;
+
+ SIG_BLOCK : constant := 0;
+ SIG_UNBLOCK : constant := 1;
+ SIG_SETMASK : constant := 2;
+
+ SIG_DFL : constant := 0;
+ SIG_IGN : constant := 1;
+
+ function sigaction
+ (sig : Signal;
+ act : struct_sigaction_ptr;
+ oact : struct_sigaction_ptr) return int;
+ pragma Import (C, sigaction, "sigaction");
+
+ ----------
+ -- Time --
+ ----------
+
+ Time_Slice_Supported : constant Boolean := True;
+ -- Indicates whether time slicing is supported
+
+ type timespec is private;
+
+ type clockid_t is private;
+
+ CLOCK_REALTIME : constant clockid_t;
+
+ function clock_gettime
+ (clock_id : clockid_t;
+ tp : access timespec) return int;
+ pragma Import (C, clock_gettime, "clock_gettime");
+
+ function clock_getres
+ (clock_id : clockid_t;
+ res : access timespec) return int;
+ pragma Import (C, clock_getres, "clock_getres");
+
+ function To_Duration (TS : timespec) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timespec (D : Duration) return timespec;
+ pragma Inline (To_Timespec);
+
+ type struct_timezone is record
+ tz_minuteswest : int;
+ tz_dsttime : int;
+ end record;
+ pragma Convention (C, struct_timezone);
+ type struct_timezone_ptr is access all struct_timezone;
+
+ type struct_timeval is private;
+ -- This is needed on systems that do not have clock_gettime()
+ -- but do have gettimeofday().
+
+ function To_Duration (TV : struct_timeval) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timeval (D : Duration) return struct_timeval;
+ pragma Inline (To_Timeval);
+
+ -------------------------
+ -- Priority Scheduling --
+ -------------------------
+
+ SCHED_FIFO : constant := 16#200000#;
+ SCHED_RR : constant := 16#100000#;
+ SCHED_OTHER : constant := 16#400000#;
+
+ -------------
+ -- Process --
+ -------------
+
+ type pid_t is private;
+
+ function kill (pid : pid_t; sig : Signal) return int;
+ pragma Import (C, kill, "kill");
+
+ function getpid return pid_t;
+ pragma Import (C, getpid, "getpid");
+
+ ---------
+ -- LWP --
+ ---------
+
+ function lwp_self return System.Address;
+ pragma Import (C, lwp_self, "pthread_self");
+
+ -------------
+ -- Threads --
+ -------------
+
+ type Thread_Body is access
+ function (arg : System.Address) return System.Address;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ type pthread_t is private;
+ subtype Thread_Id is pthread_t;
+
+ type pthread_mutex_t is limited private;
+ type pthread_cond_t is limited private;
+ type pthread_attr_t is limited private;
+ type pthread_mutexattr_t is limited private;
+ type pthread_condattr_t is limited private;
+ type pthread_key_t is private;
+
+ PTHREAD_CREATE_DETACHED : constant := 1;
+ PTHREAD_CREATE_JOINABLE : constant := 0;
+
+ -----------
+ -- Stack --
+ -----------
+
+ Stack_Base_Available : constant Boolean := False;
+ -- Indicates whether the stack base is available on this target.
+
+ function Get_Stack_Base (thread : pthread_t) return Address;
+ pragma Inline (Get_Stack_Base);
+ -- Returns the stack base of the specified thread.
+ -- Only call this function when Stack_Base_Available is True.
+
+ 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
+
+ PROT_NONE : constant := 1;
+ PROT_READ : constant := 2;
+ PROT_WRITE : constant := 4;
+ PROT_EXEC : constant := 8;
+ PROT_ALL : constant := PROT_READ + PROT_WRITE + PROT_EXEC;
+
+ PROT_ON : constant := PROT_READ;
+ PROT_OFF : constant := PROT_ALL;
+
+ function mprotect (addr : Address; len : size_t; prot : int) return int;
+ pragma Import (C, mprotect);
+
+ -----------------------------------------
+ -- Nonstandard Thread Initialization --
+ -----------------------------------------
+
+ procedure pthread_init;
+ -- This is a dummy procedure to share some GNULLI files
+
+ ---------------------------
+ -- POSIX.1c Section 3 --
+ ---------------------------
+
+ function sigwait
+ (set : access sigset_t;
+ sig : access Signal) return int;
+ pragma Inline (sigwait);
+ -- LynxOS has non standard sigwait
+
+ function pthread_kill
+ (thread : pthread_t;
+ sig : Signal) return int;
+ pragma Import (C, pthread_kill, "pthread_kill");
+
+ type sigset_t_ptr is access all sigset_t;
+
+ function pthread_sigmask
+ (how : int;
+ set : sigset_t_ptr;
+ oset : sigset_t_ptr) return int;
+ pragma Import (C, pthread_sigmask, "pthread_sigmask");
+ -- The behavior of pthread_sigmask on LynxOS requires
+ -- further investigation.
+
+ ----------------------------
+ -- POSIX.1c Section 11 --
+ ----------------------------
+
+ function pthread_mutexattr_init
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_init, "pthread_mutexattr_init");
+
+ function pthread_mutexattr_destroy
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_destroy, "pthread_mutexattr_destroy");
+
+ function pthread_mutex_init
+ (mutex : access pthread_mutex_t;
+ attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutex_init, "pthread_mutex_init");
+
+ function pthread_mutex_destroy (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_destroy, "pthread_mutex_destroy");
+
+ function pthread_mutex_lock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_lock, "pthread_mutex_lock");
+
+ function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_unlock, "pthread_mutex_unlock");
+
+ function pthread_condattr_init
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_init, "pthread_condattr_init");
+
+ function pthread_condattr_destroy
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_destroy, "pthread_condattr_destroy");
+
+ function pthread_cond_init
+ (cond : access pthread_cond_t;
+ attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_cond_init, "pthread_cond_init");
+
+ function pthread_cond_destroy (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_destroy, "pthread_cond_destroy");
+
+ function pthread_cond_signal (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_signal, "pthread_cond_signal");
+
+ function pthread_cond_wait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_cond_wait, "pthread_cond_wait");
+
+ function pthread_cond_timedwait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ abstime : access timespec) return int;
+ pragma Import (C, pthread_cond_timedwait, "pthread_cond_timedwait");
+
+ Relative_Timed_Wait : constant Boolean := False;
+ -- pthread_cond_timedwait requires an absolute delay time
+
+ --------------------------
+ -- POSIX.1c Section 13 --
+ --------------------------
+
+ PTHREAD_PRIO_NONE : constant := 0;
+ PTHREAD_PRIO_INHERIT : constant := 1;
+ PTHREAD_PRIO_PROTECT : constant := 2;
+
+ function pthread_mutexattr_setprotocol
+ (attr : access pthread_mutexattr_t;
+ protocol : int) return int;
+ pragma Import (C, pthread_mutexattr_setprotocol);
+
+ function pthread_mutexattr_setprioceiling
+ (attr : access pthread_mutexattr_t;
+ prioceiling : int) return int;
+ pragma Import (C, pthread_mutexattr_setprioceiling);
+
+ type struct_sched_param is record
+ sched_priority : int;
+ end record;
+
+ function pthread_setschedparam
+ (thread : pthread_t;
+ policy : int;
+ param : access struct_sched_param) return int;
+ pragma Import (C, pthread_setschedparam, "pthread_setschedparam");
+
+ function pthread_attr_setscope
+ (attr : access pthread_attr_t;
+ contentionscope : int) return int;
+ pragma Import (C, pthread_attr_setscope, "pthread_attr_setscope");
+
+ function pthread_attr_setinheritsched
+ (attr : access pthread_attr_t;
+ inheritsched : int) return int;
+ pragma Import (C, pthread_attr_setinheritsched);
+
+ function pthread_attr_setschedpolicy
+ (attr : access pthread_attr_t;
+ policy : int) return int;
+ pragma Import (C, pthread_attr_setschedpolicy);
+
+ function sched_yield return int;
+ pragma Import (C, sched_yield, "sched_yield");
+
+ ---------------------------
+ -- P1003.1c - Section 16 --
+ ---------------------------
+
+ function pthread_attr_init (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_init, "pthread_attr_init");
+
+ function pthread_attr_destroy
+ (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_destroy, "pthread_attr_destroy");
+
+ function pthread_attr_setdetachstate
+ (attr : access pthread_attr_t;
+ detachstate : int) return int;
+ pragma Import (C, pthread_attr_setdetachstate);
+
+ function pthread_attr_setstacksize
+ (attr : access pthread_attr_t;
+ stacksize : size_t) return int;
+ pragma Import (C, pthread_attr_setstacksize);
+
+ function pthread_create
+ (thread : access pthread_t;
+ attributes : access pthread_attr_t;
+ start_routine : Thread_Body;
+ arg : System.Address) return int;
+ pragma Import (C, pthread_create, "pthread_create");
+
+ procedure pthread_exit (status : System.Address);
+ pragma Import (C, pthread_exit, "pthread_exit");
+
+ function pthread_self return pthread_t;
+ pragma Import (C, pthread_self, "pthread_self");
+
+ --------------------------
+ -- POSIX.1c Section 17 --
+ --------------------------
+
+ function st_setspecific
+ (key : pthread_key_t;
+ value : System.Address) return int;
+ pragma Import (C, st_setspecific, "st_setspecific");
+
+ function st_getspecific
+ (key : pthread_key_t;
+ retval : System.Address) return int;
+ pragma Import (C, st_getspecific, "st_getspecific");
+
+ type destructor_pointer is access procedure (arg : System.Address);
+
+ function st_keycreate
+ (destructor : destructor_pointer;
+ key : access pthread_key_t) return int;
+ pragma Import (C, st_keycreate, "st_keycreate");
+
+private
+
+ type sigset_t is record
+ X1, X2 : long;
+ end record;
+ pragma Convention (C, sigset_t);
+
+ type pid_t is new long;
+
+ type time_t is new long;
+
+ type timespec is record
+ tv_sec : time_t;
+ tv_nsec : long;
+ end record;
+ pragma Convention (C, timespec);
+
+ type clockid_t is new unsigned_char;
+ CLOCK_REALTIME : constant clockid_t := 0;
+
+ type struct_timeval is record
+ tv_sec : time_t;
+ tv_usec : time_t;
+ end record;
+ pragma Convention (C, struct_timeval);
+
+ type st_attr_t is record
+ stksize : int;
+ prio : int;
+ inheritsched : int;
+ state : int;
+ sched : int;
+ detachstate : int;
+ guardsize : int;
+ end record;
+ pragma Convention (C, st_attr_t);
+
+ type pthread_attr_t is record
+ pthread_attr_magic : unsigned;
+ st : st_attr_t;
+ pthread_attr_scope : int;
+ end record;
+ pragma Convention (C, pthread_attr_t);
+
+ type pthread_condattr_t is record
+ cv_magic : unsigned;
+ cv_pshared : unsigned;
+ end record;
+ pragma Convention (C, pthread_condattr_t);
+
+ type pthread_mutexattr_t is record
+ m_flags : unsigned;
+ m_prio_c : int;
+ m_pshared : int;
+ end record;
+ pragma Convention (C, pthread_mutexattr_t);
+
+ type tid_t is new short;
+ type pthread_t is new tid_t;
+
+ type block_obj_t is new System.Address;
+ -- typedef struct _block_obj_s {
+ -- struct st_entry *b_head;
+ -- } block_obj_t;
+
+ type pthread_mutex_t is record
+ m_flags : unsigned;
+ m_owner : tid_t;
+ m_wait : block_obj_t;
+ m_prio_c : int;
+ m_oldprio : int;
+ m_count : int;
+ m_referenced : int;
+ end record;
+ pragma Convention (C, pthread_mutex_t);
+ type pthread_mutex_t_ptr is access all pthread_mutex_t;
+
+ type pthread_cond_t is record
+ cv_magic : unsigned;
+ cv_wait : block_obj_t;
+ cv_mutex : pthread_mutex_t_ptr;
+ cv_refcnt : int;
+ end record;
+ pragma Convention (C, pthread_cond_t);
+
+ type pthread_key_t is new int;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-mingw.ads b/gcc/ada/s-osinte-mingw.ads
new file mode 100644
index 00000000000..eec2e6ead98
--- /dev/null
+++ b/gcc/ada/s-osinte-mingw.ads
@@ -0,0 +1,451 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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 is a NT (native) version of this package
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+with Interfaces.C;
+with Interfaces.C.Strings;
+with Unchecked_Conversion;
+
+package System.OS_Interface is
+pragma Preelaborate;
+
+ pragma Linker_Options ("-mthreads");
+
+ subtype int is Interfaces.C.int;
+ subtype long is Interfaces.C.long;
+
+ -------------------
+ -- General Types --
+ -------------------
+
+ type DWORD is new Interfaces.C.unsigned_long;
+ type WORD is new Interfaces.C.unsigned_short;
+
+ -- The LARGE_INTEGER type is actually a fixed point type
+ -- that only can represent integers. The reason for this is
+ -- easier conversion to Duration or other fixed point types.
+ -- (See Operations.Clock)
+
+ type LARGE_INTEGER is delta 1.0 range -2.0**63 .. 2.0**63 - 1.0;
+
+ subtype PSZ is Interfaces.C.Strings.chars_ptr;
+ subtype PCHAR is Interfaces.C.Strings.chars_ptr;
+ subtype PVOID is System.Address;
+
+ Null_Void : constant PVOID := System.Null_Address;
+
+ type PLONG is access all Interfaces.C.long;
+ type PDWORD is access all DWORD;
+
+ type BOOL is new Boolean;
+ for BOOL'Size use Interfaces.C.unsigned_long'Size;
+
+ -------------------------
+ -- Handles for objects --
+ -------------------------
+
+ type HANDLE is new Interfaces.C.long;
+ type PHANDLE is access all HANDLE;
+
+ subtype Thread_Id is HANDLE;
+
+ -----------
+ -- Errno --
+ -----------
+
+ NO_ERROR : constant := 0;
+ FUNC_ERR : constant := -1;
+
+ -------------
+ -- Signals --
+ -------------
+
+ Max_Interrupt : constant := 31;
+ type Signal is new int range 0 .. Max_Interrupt;
+ for Signal'Size use int'Size;
+
+ SIGINT : constant := 2; -- interrupt (Ctrl-C)
+ SIGILL : constant := 4; -- illegal instruction (not reset)
+ SIGFPE : constant := 8; -- floating point exception
+ SIGSEGV : constant := 11; -- segmentation violation
+ SIGTERM : constant := 15; -- software termination signal from kill
+ SIGBREAK : constant := 21; -- break (Ctrl-Break)
+ SIGABRT : constant := 22; -- used by abort, replace SIGIOT in the future
+
+ type sigset_t is private;
+
+ type isr_address is access procedure (sig : int);
+
+ function intr_attach (sig : int; handler : isr_address) return long;
+ pragma Import (C, intr_attach, "signal");
+
+ Intr_Attach_Reset : constant Boolean := True;
+ -- True if intr_attach is reset after an interrupt handler is called
+
+ procedure kill (sig : Signal);
+ pragma Import (C, kill, "raise");
+
+ ---------------------
+ -- Time Management --
+ ---------------------
+
+ procedure Sleep (dwMilliseconds : DWORD);
+ pragma Import (Stdcall, Sleep, External_Name => "Sleep");
+
+ type SYSTEMTIME is record
+ wYear : WORD;
+ wMonth : WORD;
+ wDayOfWeek : WORD;
+ wDay : WORD;
+ wHour : WORD;
+ wMinute : WORD;
+ wSecond : WORD;
+ wMilliseconds : WORD;
+ end record;
+
+ procedure GetSystemTime (pSystemTime : access SYSTEMTIME);
+ pragma Import (Stdcall, GetSystemTime, "GetSystemTime");
+
+ procedure GetSystemTimeAsFileTime (lpFileTime : access Long_Long_Integer);
+ pragma Import (Stdcall, GetSystemTimeAsFileTime, "GetSystemTimeAsFileTime");
+
+ function SetSystemTime (pSystemTime : access SYSTEMTIME) return BOOL;
+ pragma Import (Stdcall, SetSystemTime, "SetSystemTime");
+
+ function FileTimeToSystemTime
+ (lpFileTime : access Long_Long_Integer;
+ lpSystemTime : access SYSTEMTIME) return BOOL;
+ pragma Import (Stdcall, FileTimeToSystemTime, "FileTimeToSystemTime");
+
+ function SystemTimeToFileTime
+ (lpSystemTime : access SYSTEMTIME;
+ lpFileTime : access Long_Long_Integer) return BOOL;
+ pragma Import (Stdcall, SystemTimeToFileTime, "SystemTimeToFileTime");
+
+ function FileTimeToLocalFileTime
+ (lpFileTime : access Long_Long_Integer;
+ lpLocalFileTime : access Long_Long_Integer) return BOOL;
+ pragma Import (Stdcall, FileTimeToLocalFileTime, "FileTimeToLocalFileTime");
+
+ function LocalFileTimeToFileTime
+ (lpFileTime : access Long_Long_Integer;
+ lpLocalFileTime : access Long_Long_Integer) return BOOL;
+ pragma Import (Stdcall, LocalFileTimeToFileTime, "LocalFileTimeToFileTime");
+
+ function QueryPerformanceCounter
+ (lpPerformanceCount : access LARGE_INTEGER) return BOOL;
+ pragma Import
+ (Stdcall, QueryPerformanceCounter, "QueryPerformanceCounter");
+
+ function QueryPerformanceFrequency
+ (lpFrequency : access LARGE_INTEGER) return BOOL;
+ pragma Import
+ (Stdcall, QueryPerformanceFrequency, "QueryPerformanceFrequency");
+
+ -------------
+ -- Threads --
+ -------------
+
+ type Thread_Body is access
+ function (arg : System.Address) return System.Address;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ procedure SwitchToThread;
+ pragma Import (Stdcall, SwitchToThread, "SwitchToThread");
+
+ -----------------------
+ -- Critical sections --
+ -----------------------
+
+ type CRITICAL_SECTION is private;
+ type PCRITICAL_SECTION is access all CRITICAL_SECTION;
+
+ procedure InitializeCriticalSection (pCriticalSection : PCRITICAL_SECTION);
+ pragma Import
+ (Stdcall, InitializeCriticalSection, "InitializeCriticalSection");
+
+ procedure EnterCriticalSection (pCriticalSection : PCRITICAL_SECTION);
+ pragma Import (Stdcall, EnterCriticalSection, "EnterCriticalSection");
+
+ procedure LeaveCriticalSection (pCriticalSection : PCRITICAL_SECTION);
+ pragma Import (Stdcall, LeaveCriticalSection, "LeaveCriticalSection");
+
+ procedure DeleteCriticalSection (pCriticalSection : PCRITICAL_SECTION);
+ pragma Import (Stdcall, DeleteCriticalSection, "DeleteCriticalSection");
+
+ -------------------------------------------------------------
+ -- Thread Creation, Activation, Suspension And Termination --
+ -------------------------------------------------------------
+
+ type PTHREAD_START_ROUTINE is access function
+ (pThreadParameter : PVOID) return DWORD;
+ pragma Convention (Stdcall, PTHREAD_START_ROUTINE);
+
+ function To_PTHREAD_START_ROUTINE is new
+ Unchecked_Conversion (System.Address, PTHREAD_START_ROUTINE);
+
+ type SECURITY_ATTRIBUTES is record
+ nLength : DWORD;
+ pSecurityDescriptor : PVOID;
+ bInheritHandle : BOOL;
+ end record;
+
+ type PSECURITY_ATTRIBUTES is access all SECURITY_ATTRIBUTES;
+
+ function CreateThread
+ (pThreadAttributes : PSECURITY_ATTRIBUTES;
+ dwStackSize : DWORD;
+ pStartAddress : PTHREAD_START_ROUTINE;
+ pParameter : PVOID;
+ dwCreationFlags : DWORD;
+ pThreadId : PDWORD) return HANDLE;
+ pragma Import (Stdcall, CreateThread, "CreateThread");
+
+ function BeginThreadEx
+ (pThreadAttributes : PSECURITY_ATTRIBUTES;
+ dwStackSize : DWORD;
+ pStartAddress : PTHREAD_START_ROUTINE;
+ pParameter : PVOID;
+ dwCreationFlags : DWORD;
+ pThreadId : PDWORD) return HANDLE;
+ pragma Import (C, BeginThreadEx, "_beginthreadex");
+
+ Debug_Process : constant := 16#00000001#;
+ Debug_Only_This_Process : constant := 16#00000002#;
+ Create_Suspended : constant := 16#00000004#;
+ Detached_Process : constant := 16#00000008#;
+ Create_New_Console : constant := 16#00000010#;
+
+ Create_New_Process_Group : constant := 16#00000200#;
+
+ Create_No_window : constant := 16#08000000#;
+
+ Profile_User : constant := 16#10000000#;
+ Profile_Kernel : constant := 16#20000000#;
+ Profile_Server : constant := 16#40000000#;
+
+ function GetExitCodeThread
+ (hThread : HANDLE;
+ pExitCode : PDWORD) return BOOL;
+ pragma Import (Stdcall, GetExitCodeThread, "GetExitCodeThread");
+
+ function ResumeThread (hThread : HANDLE) return DWORD;
+ pragma Import (Stdcall, ResumeThread, "ResumeThread");
+
+ function SuspendThread (hThread : HANDLE) return DWORD;
+ pragma Import (Stdcall, SuspendThread, "SuspendThread");
+
+ procedure ExitThread (dwExitCode : DWORD);
+ pragma Import (Stdcall, ExitThread, "ExitThread");
+
+ procedure EndThreadEx (dwExitCode : DWORD);
+ pragma Import (C, EndThreadEx, "_endthreadex");
+
+ function TerminateThread
+ (hThread : HANDLE;
+ dwExitCode : DWORD) return BOOL;
+ pragma Import (Stdcall, TerminateThread, "TerminateThread");
+
+ function GetCurrentThread return HANDLE;
+ pragma Import (Stdcall, GetCurrentThread, "GetCurrentThread");
+
+ function GetCurrentProcess return HANDLE;
+ pragma Import (Stdcall, GetCurrentProcess, "GetCurrentProcess");
+
+ function GetCurrentThreadId return DWORD;
+ pragma Import (Stdcall, GetCurrentThreadId, "GetCurrentThreadId");
+
+ function TlsAlloc return DWORD;
+ pragma Import (Stdcall, TlsAlloc, "TlsAlloc");
+
+ function TlsGetValue (dwTlsIndex : DWORD) return PVOID;
+ pragma Import (Stdcall, TlsGetValue, "TlsGetValue");
+
+ function TlsSetValue (dwTlsIndex : DWORD; pTlsValue : PVOID) return BOOL;
+ pragma Import (Stdcall, TlsSetValue, "TlsSetValue");
+
+ function TlsFree (dwTlsIndex : DWORD) return BOOL;
+ pragma Import (Stdcall, TlsFree, "TlsFree");
+
+ TLS_Nothing : constant := DWORD'Last;
+
+ procedure ExitProcess (uExitCode : Interfaces.C.unsigned);
+ pragma Import (Stdcall, ExitProcess, "ExitProcess");
+
+ function WaitForSingleObject
+ (hHandle : HANDLE;
+ dwMilliseconds : DWORD) return DWORD;
+ pragma Import (Stdcall, WaitForSingleObject, "WaitForSingleObject");
+
+ function WaitForSingleObjectEx
+ (hHandle : HANDLE;
+ dwMilliseconds : DWORD;
+ fAlertable : BOOL) return DWORD;
+ pragma Import (Stdcall, WaitForSingleObjectEx, "WaitForSingleObjectEx");
+
+ Wait_Infinite : constant := DWORD'Last;
+ WAIT_TIMEOUT : constant := 16#0000_0102#;
+ WAIT_FAILED : constant := 16#FFFF_FFFF#;
+
+ ------------------------------------
+ -- Semaphores, Events and Mutexes --
+ ------------------------------------
+
+ function CloseHandle (hObject : HANDLE) return BOOL;
+ pragma Import (Stdcall, CloseHandle, "CloseHandle");
+
+ function CreateSemaphore
+ (pSemaphoreAttributes : PSECURITY_ATTRIBUTES;
+ lInitialCount : Interfaces.C.long;
+ lMaximumCount : Interfaces.C.long;
+ pName : PSZ) return HANDLE;
+ pragma Import (Stdcall, CreateSemaphore, "CreateSemaphoreA");
+
+ function OpenSemaphore
+ (dwDesiredAccess : DWORD;
+ bInheritHandle : BOOL;
+ pName : PSZ) return HANDLE;
+ pragma Import (Stdcall, OpenSemaphore, "OpenSemaphoreA");
+
+ function ReleaseSemaphore
+ (hSemaphore : HANDLE;
+ lReleaseCount : Interfaces.C.long;
+ pPreviousCount : PLONG) return BOOL;
+ pragma Import (Stdcall, ReleaseSemaphore, "ReleaseSemaphore");
+
+ function CreateEvent
+ (pEventAttributes : PSECURITY_ATTRIBUTES;
+ bManualReset : BOOL;
+ bInitialState : BOOL;
+ pName : PSZ) return HANDLE;
+ pragma Import (Stdcall, CreateEvent, "CreateEventA");
+
+ function OpenEvent
+ (dwDesiredAccess : DWORD;
+ bInheritHandle : BOOL;
+ pName : PSZ) return HANDLE;
+ pragma Import (Stdcall, OpenEvent, "OpenEventA");
+
+ function SetEvent (hEvent : HANDLE) return BOOL;
+ pragma Import (Stdcall, SetEvent, "SetEvent");
+
+ function ResetEvent (hEvent : HANDLE) return BOOL;
+ pragma Import (Stdcall, ResetEvent, "ResetEvent");
+
+ function PulseEvent (hEvent : HANDLE) return BOOL;
+ pragma Import (Stdcall, PulseEvent, "PulseEvent");
+
+ function CreateMutex
+ (pMutexAttributes : PSECURITY_ATTRIBUTES;
+ bInitialOwner : BOOL;
+ pName : PSZ) return HANDLE;
+ pragma Import (Stdcall, CreateMutex, "CreateMutexA");
+
+ function OpenMutex
+ (dwDesiredAccess : DWORD;
+ bInheritHandle : BOOL;
+ pName : PSZ) return HANDLE;
+ pragma Import (Stdcall, OpenMutex, "OpenMutexA");
+
+ function ReleaseMutex (hMutex : HANDLE) return BOOL;
+ pragma Import (Stdcall, ReleaseMutex, "ReleaseMutex");
+
+ ---------------------------------------------------
+ -- Accessing properties of Threads and Processes --
+ ---------------------------------------------------
+
+ -----------------
+ -- Priorities --
+ -----------------
+
+ function SetThreadPriority
+ (hThread : HANDLE;
+ nPriority : Interfaces.C.int) return BOOL;
+ pragma Import (Stdcall, SetThreadPriority, "SetThreadPriority");
+
+ function GetThreadPriority (hThread : HANDLE) return Interfaces.C.int;
+ pragma Import (Stdcall, GetThreadPriority, "GetThreadPriority");
+
+ function SetPriorityClass
+ (hProcess : HANDLE;
+ dwPriorityClass : DWORD) return BOOL;
+ pragma Import (Stdcall, SetPriorityClass, "SetPriorityClass");
+
+ procedure SetThreadPriorityBoost
+ (hThread : HANDLE;
+ DisablePriorityBoost : BOOL);
+ pragma Import (Stdcall, SetThreadPriorityBoost, "SetThreadPriorityBoost");
+
+ Normal_Priority_Class : constant := 16#00000020#;
+ Idle_Priority_Class : constant := 16#00000040#;
+ High_Priority_Class : constant := 16#00000080#;
+ Realtime_Priority_Class : constant := 16#00000100#;
+
+ Thread_Priority_Idle : constant := -15;
+ Thread_Priority_Lowest : constant := -2;
+ Thread_Priority_Below_Normal : constant := -1;
+ Thread_Priority_Normal : constant := 0;
+ Thread_Priority_Above_Normal : constant := 1;
+ Thread_Priority_Highest : constant := 2;
+ Thread_Priority_Time_Critical : constant := 15;
+ Thread_Priority_Error_Return : constant := Interfaces.C.long'Last;
+
+ function GetLastError return DWORD;
+ pragma Import (Stdcall, GetLastError, "GetLastError");
+
+private
+
+ type sigset_t is new Interfaces.C.unsigned_long;
+
+ type CRITICAL_SECTION is record
+ DebugInfo : System.Address;
+ -- The following three fields control entering and
+ -- exiting the critical section for the resource
+ LockCount : Long_Integer;
+ RecursionCount : Long_Integer;
+ OwningThread : HANDLE;
+ LockSemaphore : HANDLE;
+ Reserved : DWORD;
+ end record;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-os2.adb b/gcc/ada/s-osinte-os2.adb
new file mode 100644
index 00000000000..e2a241118d5
--- /dev/null
+++ b/gcc/ada/s-osinte-os2.adb
@@ -0,0 +1,120 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2003, Ada Core Technologies --
+-- --
+-- 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, 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, --
+-- 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 is the OS/2 version of this package
+
+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 Interfaces.OS2Lib.Errors;
+with Interfaces.OS2Lib.Synchronization;
+
+package body System.OS_Interface is
+
+ use Interfaces;
+ use Interfaces.OS2Lib;
+ use Interfaces.OS2Lib.Synchronization;
+ use Interfaces.OS2Lib.Errors;
+
+ -----------
+ -- Yield --
+ -----------
+
+ -- Give up the remainder of the time-slice and yield the processor
+ -- to other threads of equal priority. Yield will return immediately
+ -- without giving up the current time-slice when the only threads
+ -- that are ready have a lower priority.
+
+ -- ??? Just giving up the current time-slice seems not to be enough
+ -- to get the thread to the end of the ready queue if OS/2 does use
+ -- a queue at all. As a partial work-around, we give up two time-slices.
+
+ -- This is the best we can do now, and at least is sufficient for passing
+ -- the ACVC 2.0.1 Annex D tests.
+
+ procedure Yield is
+ begin
+ Delay_For (0);
+ Delay_For (0);
+ end Yield;
+
+ ---------------
+ -- Delay_For --
+ ---------------
+
+ procedure Delay_For (Period : in Duration_In_Millisec) is
+ Result : APIRET;
+
+ begin
+ pragma Assert (Period >= 0, "GNULLI---Delay_For: negative argument");
+
+ -- ??? DosSleep is not the appropriate function for a delay in real
+ -- time. It only gives up some number of scheduled time-slices.
+ -- Use a timer instead or block for some semaphore with a time-out.
+ Result := DosSleep (ULONG (Period));
+
+ if Result = ERROR_TS_WAKEUP then
+
+ -- Do appropriate processing for interrupted sleep
+ -- Can we raise an exception here?
+
+ null;
+ end if;
+
+ pragma Assert (Result = NO_ERROR, "GNULLI---Error in Delay_For");
+ end Delay_For;
+
+ -----------
+ -- Clock --
+ -----------
+
+ function Clock return Duration is
+
+ -- Implement conversion from tick count to Duration
+ -- using fixed point arithmetic. The frequency of
+ -- the Intel 8254 timer chip is 18.2 * 2**16 Hz.
+
+ Tick_Duration : constant := 1.0 / (18.2 * 2**16);
+ Tick_Count : aliased QWORD;
+
+ begin
+ -- Read nr of clock ticks since boot time
+
+ Must_Not_Fail (DosTmrQueryTime (Tick_Count'Access));
+
+ return Tick_Count * Tick_Duration;
+ end Clock;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-os2.ads b/gcc/ada/s-osinte-os2.ads
new file mode 100644
index 00000000000..4ddd2d0b06d
--- /dev/null
+++ b/gcc/ada/s-osinte-os2.ads
@@ -0,0 +1,125 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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 is the OS/2 version of this package
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+with Interfaces.C;
+
+package System.OS_Interface is
+ pragma Preelaborate;
+
+ package C renames Interfaces.C;
+
+ subtype int is C.int;
+ subtype unsigned_long is C.unsigned_long;
+
+ type Duration_In_Millisec is new C.long;
+ -- New type to prevent confusing time functions in this package
+ -- with time functions returning seconds or other units.
+
+ type Thread_Id is new unsigned_long;
+
+ -----------
+ -- Errno --
+ -----------
+
+ function errno return int;
+ pragma Import (C, errno, "__get_errno");
+
+ EAGAIN : constant := 5;
+ EINTR : constant := 13;
+ EINVAL : constant := 14;
+ ENOMEM : constant := 25;
+
+ -------------
+ -- Signals --
+ -------------
+
+ Max_Interrupt : constant := 15;
+ type Signal is new int range 0 .. Max_Interrupt;
+
+ -- Signals for OS/2, only SIGTERM used currently. The values are
+ -- fake, since OS/2 uses 32 bit exception numbers that cannot be
+ -- used to index arrays etc. The GNULLI maps these Unix-like signals
+ -- to OS/2 exception numbers.
+
+ -- SIGTERM is used for the abort interrupt.
+
+ SIGHUP : constant := 1; -- hangup
+ SIGINT : constant := 2; -- interrupt (rubout)
+ SIGQUIT : constant := 3; -- quit (ASCD FS)
+ SIGILL : constant := 4; -- illegal instruction (not reset)
+ SIGTRAP : constant := 5; -- trace trap (not reset)
+ SIGIOT : constant := 6; -- IOT instruction
+ SIGEMT : constant := 0; -- EMT instruction
+ SIGFPE : constant := 8; -- floating point exception
+ SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
+ SIGBUS : constant := 10; -- bus error
+ SIGSEGV : constant := 11; -- segmentation violation
+ SIGSYS : constant := 12; -- bad argument to system call
+ SIGPIPE : constant := 13; -- write on a pipe with no one to read it
+ SIGALRM : constant := 14; -- alarm clock
+ SIGTERM : constant := 15; -- software termination signal from kill
+
+ subtype sigset_t is unsigned_long;
+
+ ----------
+ -- Time --
+ ----------
+
+ function Clock return Duration;
+ pragma Inline (Clock);
+ -- Clock measuring time since the epoch, which is the boot-time.
+ -- The clock resolution is approximately 838 ns.
+
+ procedure Delay_For (Period : in Duration_In_Millisec);
+ pragma Inline (Delay_For);
+ -- Changed Sleep to Delay_For, for consistency with System.Time_Operations
+
+ ----------------
+ -- Scheduling --
+ ----------------
+
+ -- Put the calling task at the end of the ready queue for its priority
+
+ procedure Yield;
+ pragma Inline (Yield);
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-posix.adb b/gcc/ada/s-osinte-posix.adb
new file mode 100644
index 00000000000..36c082c86aa
--- /dev/null
+++ b/gcc/ada/s-osinte-posix.adb
@@ -0,0 +1,132 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2003, Ada Core Technologies --
+-- --
+-- 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, 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, --
+-- 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 is a GNU/LinuxThreads, Solaris pthread and HP-UX pthread version
+-- of this package.
+
+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.
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+with Interfaces.C; use Interfaces.C;
+package body System.OS_Interface is
+
+ --------------------
+ -- Get_Stack_Base --
+ --------------------
+
+ function Get_Stack_Base (thread : pthread_t) return Address is
+ pragma Warnings (Off, thread);
+
+ begin
+ return Null_Address;
+ end Get_Stack_Base;
+
+ ------------------
+ -- pthread_init --
+ ------------------
+
+ procedure pthread_init is
+ begin
+ null;
+ end pthread_init;
+
+ -----------------
+ -- To_Duration --
+ -----------------
+
+ function To_Duration (TS : timespec) return Duration is
+ begin
+ return Duration (TS.tv_sec) + Duration (TS.tv_nsec) / 10#1#E9;
+ end To_Duration;
+
+ function To_Duration (TV : struct_timeval) return Duration is
+ begin
+ return Duration (TV.tv_sec) + Duration (TV.tv_usec) / 10#1#E6;
+ end To_Duration;
+
+ -----------------
+ -- To_Timespec --
+ -----------------
+
+ function To_Timespec (D : Duration) return timespec is
+ S : time_t;
+ F : Duration;
+
+ begin
+ S := time_t (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return timespec'(tv_sec => S,
+ tv_nsec => long (Long_Long_Integer (F * 10#1#E9)));
+ end To_Timespec;
+
+ ----------------
+ -- To_Timeval --
+ ----------------
+
+ function To_Timeval (D : Duration) return struct_timeval is
+ S : time_t;
+ F : Duration;
+
+ begin
+ S := time_t (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return
+ struct_timeval'
+ (tv_sec => S,
+ tv_usec => time_t (Long_Long_Integer (F * 10#1#E6)));
+ end To_Timeval;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-solaris-fsu.ads b/gcc/ada/s-osinte-solaris-fsu.ads
new file mode 100644
index 00000000000..14caf4e3ddd
--- /dev/null
+++ b/gcc/ada/s-osinte-solaris-fsu.ads
@@ -0,0 +1,667 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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 is a Solaris (FSU THREADS) version of this package
+
+-- This package includes all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+with Interfaces.C;
+with Unchecked_Conversion;
+
+package System.OS_Interface is
+ pragma Preelaborate;
+
+ pragma Linker_Options ("-lgthreads");
+ pragma Linker_Options ("-lmalloc");
+
+ subtype int is Interfaces.C.int;
+ subtype short is Interfaces.C.short;
+ subtype long is Interfaces.C.long;
+ subtype unsigned is Interfaces.C.unsigned;
+ subtype unsigned_short is Interfaces.C.unsigned_short;
+ subtype unsigned_long is Interfaces.C.unsigned_long;
+ subtype unsigned_char is Interfaces.C.unsigned_char;
+ subtype plain_char is Interfaces.C.plain_char;
+ subtype size_t is Interfaces.C.size_t;
+
+ -----------
+ -- Errno --
+ -----------
+
+ function errno return int;
+ pragma Import (C, errno, "__get_errno");
+
+ EAGAIN : constant := 11;
+ EINTR : constant := 4;
+ EINVAL : constant := 22;
+ ENOMEM : constant := 12;
+ ETIMEDOUT : constant := 145;
+
+ -------------
+ -- Signals --
+ -------------
+
+ Max_Interrupt : constant := 45;
+ type Signal is new int range 0 .. Max_Interrupt;
+ for Signal'Size use int'Size;
+
+ SIGHUP : constant := 1; -- hangup
+ SIGINT : constant := 2; -- interrupt (rubout)
+ SIGQUIT : constant := 3; -- quit (ASCD FS)
+ SIGILL : constant := 4; -- illegal instruction (not reset)
+ SIGTRAP : constant := 5; -- trace trap (not reset)
+ SIGIOT : constant := 6; -- IOT instruction
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGEMT : constant := 7; -- EMT instruction
+ SIGFPE : constant := 8; -- floating point exception
+ SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
+ SIGBUS : constant := 10; -- bus error
+ SIGSEGV : constant := 11; -- segmentation violation
+ SIGSYS : constant := 12; -- bad argument to system call
+ SIGPIPE : constant := 13; -- write on a pipe with no one to read it
+ SIGALRM : constant := 14; -- alarm clock
+ SIGTERM : constant := 15; -- software termination signal from kill
+ SIGUSR1 : constant := 16; -- user defined signal 1
+ SIGUSR2 : constant := 17; -- user defined signal 2
+ SIGCLD : constant := 18; -- alias for SIGCHLD
+ SIGCHLD : constant := 18; -- child status change
+ SIGPWR : constant := 19; -- power-fail restart
+ SIGWINCH : constant := 20; -- window size change
+ SIGURG : constant := 21; -- urgent condition on IO channel
+ SIGPOLL : constant := 22; -- pollable event occurred
+ SIGIO : constant := 22; -- I/O possible (Solaris SIGPOLL alias)
+ SIGSTOP : constant := 23; -- stop (cannot be caught or ignored)
+ SIGTSTP : constant := 24; -- user stop requested from tty
+ SIGCONT : constant := 25; -- stopped process has been continued
+ SIGTTIN : constant := 26; -- background tty read attempted
+ SIGTTOU : constant := 27; -- background tty write attempted
+ SIGVTALRM : constant := 28; -- virtual timer expired
+ SIGPROF : constant := 29; -- profiling timer expired
+ SIGXCPU : constant := 30; -- CPU time limit exceeded
+ SIGXFSZ : constant := 31; -- filesize limit exceeded
+ SIGWAITING : constant := 32; -- process's lwps blocked (Solaris)
+ SIGLWP : constant := 33; -- used by thread library (Solaris)
+ SIGFREEZE : constant := 34; -- used by CPR (Solaris)
+ SIGTHAW : constant := 35; -- used by CPR (Solaris)
+ SIGCANCEL : constant := 36; -- used for thread cancel (Solaris)
+ SIGRTMIN : constant := 38; -- first (highest-priority) realtime signal
+ SIGRTMAX : constant := 45; -- last (lowest-priority) realtime signal
+
+ type Signal_Set is array (Natural range <>) of Signal;
+
+ Unmasked : constant Signal_Set :=
+ (SIGTRAP, SIGLWP, SIGTTIN, SIGTTOU, SIGTSTP, SIGPROF);
+
+ Reserved : constant Signal_Set :=
+ (SIGKILL, SIGSTOP, SIGALRM, SIGVTALRM, SIGWAITING, SIGRTMAX);
+
+ type sigset_t is private;
+
+ function sigaddset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigaddset, "sigaddset");
+
+ function sigdelset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigdelset, "sigdelset");
+
+ function sigfillset (set : access sigset_t) return int;
+ pragma Import (C, sigfillset, "sigfillset");
+
+ function sigismember (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigismember, "sigismember");
+
+ function sigemptyset (set : access sigset_t) return int;
+ pragma Import (C, sigemptyset, "sigemptyset");
+
+ type union_type_3 is new String (1 .. 116);
+ type siginfo_t is record
+ si_signo : int;
+ si_code : int;
+ si_errno : int;
+ X_data : union_type_3;
+ end record;
+ pragma Convention (C, siginfo_t);
+
+ -- The types mcontext_t and gregset_t are part of the ucontext_t
+ -- information, which is specific to Solaris2.4 for SPARC
+ -- The ucontext_t info seems to be used by the handler
+ -- for SIGSEGV to decide whether it is a Storage_Error (stack overflow) or
+ -- a Constraint_Error (bad pointer). The original code that did this
+ -- is suspect, so it is not clear whether we really need this part of
+ -- the signal context information, or perhaps something else.
+ -- More analysis is needed, after which these declarations may need to
+ -- be changed.
+
+ EMT_TAGOVF : constant := 1; -- tag overflow
+ FPE_INTDIV : constant := 1; -- integer divide by zero
+ FPE_INTOVF : constant := 2; -- integer overflow
+ FPE_FLTDIV : constant := 3; -- floating point divide by zero
+ FPE_FLTOVF : constant := 4; -- floating point overflow
+ FPE_FLTUND : constant := 5; -- floating point underflow
+ FPE_FLTRES : constant := 6; -- floating point inexact result
+ FPE_FLTINV : constant := 7; -- invalid floating point operation
+ FPE_FLTSUB : constant := 8; -- subscript out of range
+
+ SEGV_MAPERR : constant := 1; -- address not mapped to object
+ SEGV_ACCERR : constant := 2; -- invalid permissions
+
+ BUS_ADRALN : constant := 1; -- invalid address alignment
+ BUS_ADRERR : constant := 2; -- non-existent physical address
+ BUS_OBJERR : constant := 3; -- object specific hardware error
+
+ ILL_ILLOPC : constant := 1; -- illegal opcode
+ ILL_ILLOPN : constant := 2; -- illegal operand
+ ILL_ILLADR : constant := 3; -- illegal addressing mode
+ ILL_ILLTRP : constant := 4; -- illegal trap
+ ILL_PRVOPC : constant := 5; -- privileged opcode
+ ILL_PRVREG : constant := 6; -- privileged register
+ ILL_COPROC : constant := 7; -- co-processor
+ ILL_BADSTK : constant := 8; -- bad stack
+
+ type greg_t is new int;
+
+ type gregset_t is array (Integer range 0 .. 18) of greg_t;
+
+ REG_O0 : constant := 11;
+ -- index of saved register O0 in ucontext.uc_mcontext.gregs array
+
+ type union_type_2 is new String (1 .. 128);
+ type record_type_1 is record
+ fpu_fr : union_type_2;
+ fpu_q : System.Address;
+ fpu_fsr : unsigned;
+ fpu_qcnt : unsigned_char;
+ fpu_q_entrysize : unsigned_char;
+ fpu_en : unsigned_char;
+ end record;
+ pragma Convention (C, record_type_1);
+ type array_type_7 is array (Integer range 0 .. 20) of long;
+ type mcontext_t is record
+ gregs : gregset_t;
+ gwins : System.Address;
+ fpregs : record_type_1;
+ filler : array_type_7;
+ end record;
+ pragma Convention (C, mcontext_t);
+
+ type record_type_2 is record
+ ss_sp : System.Address;
+ ss_size : int;
+ ss_flags : int;
+ end record;
+ pragma Convention (C, record_type_2);
+ type array_type_8 is array (Integer range 0 .. 22) of long;
+ type ucontext_t is record
+ uc_flags : unsigned_long;
+ uc_link : System.Address;
+ uc_sigmask : sigset_t;
+ uc_stack : record_type_2;
+ uc_mcontext : mcontext_t;
+ uc_filler : array_type_8;
+ end record;
+ pragma Convention (C, ucontext_t);
+
+ type Signal_Handler is access procedure
+ (signo : Signal;
+ info : access siginfo_t;
+ context : access ucontext_t);
+
+ type union_type_1 is new plain_char;
+ type array_type_2 is array (Integer range 0 .. 1) of int;
+ type struct_sigaction is record
+ sa_flags : int;
+ sa_handler : System.Address;
+ sa_mask : sigset_t;
+ sa_resv : array_type_2;
+ end record;
+ pragma Convention (C, struct_sigaction);
+ type struct_sigaction_ptr is access all struct_sigaction;
+
+ SA_SIGINFO : constant := 16#08#;
+
+ SIG_BLOCK : constant := 1;
+ SIG_UNBLOCK : constant := 2;
+ SIG_SETMASK : constant := 3;
+
+ SIG_DFL : constant := 0;
+ SIG_IGN : constant := 1;
+
+ function sigaction
+ (sig : Signal;
+ act : struct_sigaction_ptr;
+ oact : struct_sigaction_ptr) return int;
+ pragma Import (C, sigaction, "sigaction");
+
+ ----------
+ -- Time --
+ ----------
+
+ Time_Slice_Supported : constant Boolean := False;
+ -- Indicates wether time slicing is supported (i.e FSU threads have been
+ -- compiled with DEF_RR)
+
+ type timespec is private;
+
+ type clockid_t is private;
+
+ CLOCK_REALTIME : constant clockid_t;
+
+ function clock_gettime
+ (clock_id : clockid_t;
+ tp : access timespec) return int;
+ pragma Import (C, clock_gettime, "clock_gettime");
+
+ function To_Duration (TS : timespec) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timespec (D : Duration) return timespec;
+ pragma Inline (To_Timespec);
+
+ type struct_timeval is private;
+
+ function To_Duration (TV : struct_timeval) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timeval (D : Duration) return struct_timeval;
+ pragma Inline (To_Timeval);
+
+ -------------------------
+ -- Priority Scheduling --
+ -------------------------
+
+ SCHED_FIFO : constant := 0;
+ SCHED_RR : constant := 1;
+ SCHED_OTHER : constant := 2;
+
+ -------------
+ -- Process --
+ -------------
+
+ type pid_t is private;
+
+ function kill (pid : pid_t; sig : Signal) return int;
+ pragma Import (C, kill, "kill");
+
+ function getpid return pid_t;
+ pragma Import (C, getpid, "getpid");
+
+ ---------
+ -- LWP --
+ ---------
+
+ function lwp_self return System.Address;
+ -- lwp_self does not exist on this thread library, revert to pthread_self
+ -- which is the closest approximation (with getpid). This function is
+ -- needed to share 7staprop.adb across POSIX-like targets.
+ pragma Import (C, lwp_self, "pthread_self");
+
+ -------------
+ -- Threads --
+ -------------
+
+ type Thread_Body is access
+ function (arg : System.Address) return System.Address;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ type pthread_t is private;
+ subtype Thread_Id is pthread_t;
+
+ type pthread_mutex_t is limited private;
+ type pthread_cond_t is limited private;
+ type pthread_attr_t is limited private;
+ type pthread_mutexattr_t is limited private;
+ type pthread_condattr_t is limited private;
+ type pthread_key_t is private;
+
+ PTHREAD_CREATE_DETACHED : constant := 1;
+
+ -----------
+ -- Stack --
+ -----------
+
+ Stack_Base_Available : constant Boolean := False;
+ -- Indicates wether the stack base is available on this target.
+ -- This allows us to share s-osinte.adb between all the FSU run time.
+ -- Note that this value can only be true if pthread_t has a complete
+ -- definition that corresponds exactly to the C header files.
+
+ function Get_Stack_Base (thread : pthread_t) return Address;
+ pragma Inline (Get_Stack_Base);
+ -- returns the stack base of the specified thread.
+ -- Only call this function when Stack_Base_Available is True.
+
+ 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
+
+ PROT_NONE : constant := 0;
+ PROT_READ : constant := 1;
+ PROT_WRITE : constant := 2;
+ PROT_EXEC : constant := 4;
+ PROT_ALL : constant := PROT_READ + PROT_WRITE + PROT_EXEC;
+
+ PROT_ON : constant := PROT_NONE;
+ PROT_OFF : constant := PROT_ALL;
+
+ function mprotect (addr : Address; len : size_t; prot : int) return int;
+ pragma Import (C, mprotect);
+
+ ---------------------------------------
+ -- Nonstandard Thread Initialization --
+ ---------------------------------------
+
+ procedure pthread_init;
+ -- FSU_THREADS requires pthread_init, which is nonstandard
+ -- and this should be invoked during the elaboration of s-taprop.adb
+ pragma Import (C, pthread_init, "pthread_init");
+
+ -------------------------
+ -- POSIX.1c Section 3 --
+ -------------------------
+
+ function sigwait (set : access sigset_t; sig : access Signal) return int;
+ -- FSU_THREADS has a nonstandard sigwait
+
+ function pthread_kill (thread : pthread_t; sig : Signal) return int;
+ pragma Import (C, pthread_kill, "pthread_kill");
+
+ type sigset_t_ptr is access all sigset_t;
+
+ function pthread_sigmask
+ (how : int;
+ set : sigset_t_ptr;
+ oset : sigset_t_ptr) return int;
+ pragma Import (C, pthread_sigmask, "sigprocmask");
+
+ --------------------------
+ -- POSIX.1c Section 11 --
+ --------------------------
+
+ function pthread_mutexattr_init
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_init, "pthread_mutexattr_init");
+
+ function pthread_mutexattr_destroy
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_destroy, "pthread_mutexattr_destroy");
+
+ function pthread_mutex_init
+ (mutex : access pthread_mutex_t;
+ attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutex_init, "pthread_mutex_init");
+
+ function pthread_mutex_destroy (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_destroy, "pthread_mutex_destroy");
+
+ function pthread_mutex_lock (mutex : access pthread_mutex_t) return int;
+ -- FSU_THREADS has nonstandard pthread_mutex_lock
+
+ function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int;
+ -- FSU_THREADS has nonstandard pthread_mutex_lock
+
+ function pthread_condattr_init
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_init, "pthread_condattr_init");
+
+ function pthread_condattr_destroy
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_destroy, "pthread_condattr_destroy");
+
+ function pthread_cond_init
+ (cond : access pthread_cond_t;
+ attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_cond_init, "pthread_cond_init");
+
+ function pthread_cond_destroy (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_destroy, "pthread_cond_destroy");
+
+ function pthread_cond_signal (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_signal, "pthread_cond_signal");
+
+ function pthread_cond_wait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t) return int;
+ -- FSU_THREADS has a nonstandard pthread_cond_wait
+
+ function pthread_cond_timedwait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ abstime : access timespec) return int;
+ -- FSU_THREADS has a nonstandard pthread_cond_timedwait
+
+ Relative_Timed_Wait : constant Boolean := False;
+ -- pthread_cond_timedwait requires an absolute delay time
+
+ --------------------------
+ -- POSIX.1c Section 13 --
+ --------------------------
+
+ PTHREAD_PRIO_NONE : constant := 0;
+ PTHREAD_PRIO_PROTECT : constant := 2;
+ PTHREAD_PRIO_INHERIT : constant := 1;
+
+ function pthread_mutexattr_setprotocol
+ (attr : access pthread_mutexattr_t;
+ protocol : int) return int;
+ pragma Import (C, pthread_mutexattr_setprotocol);
+
+ function pthread_mutexattr_setprioceiling
+ (attr : access pthread_mutexattr_t;
+ prioceiling : int) return int;
+ pragma Import
+ (C, pthread_mutexattr_setprioceiling,
+ "pthread_mutexattr_setprio_ceiling");
+
+ type struct_sched_param is record
+ sched_priority : int; -- scheduling priority
+ end record;
+
+ function pthread_setschedparam
+ (thread : pthread_t;
+ policy : int;
+ param : access struct_sched_param) return int;
+ -- FSU_THREADS does not have pthread_setschedparam
+
+ function pthread_attr_setscope
+ (attr : access pthread_attr_t;
+ contentionscope : int) return int;
+ pragma Import (C, pthread_attr_setscope, "pthread_attr_setscope");
+
+ function pthread_attr_setinheritsched
+ (attr : access pthread_attr_t;
+ inheritsched : int) return int;
+ pragma Import (C, pthread_attr_setinheritsched);
+
+ function pthread_attr_setschedpolicy
+ (attr : access pthread_attr_t;
+ policy : int) return int;
+ pragma Import (C, pthread_attr_setschedpolicy, "pthread_attr_setsched");
+
+ function sched_yield return int;
+ -- FSU_THREADS does not have sched_yield;
+
+ ---------------------------
+ -- P1003.1c - Section 16 --
+ ---------------------------
+
+ function pthread_attr_init (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_init, "pthread_attr_init");
+
+ function pthread_attr_destroy
+ (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_destroy, "pthread_attr_destroy");
+
+ function pthread_attr_setdetachstate
+ (attr : access pthread_attr_t;
+ detachstate : int) return int;
+ -- FSU_THREADS has a nonstandard pthread_attr_setdetachstate
+
+ function pthread_attr_setstacksize
+ (attr : access pthread_attr_t;
+ stacksize : size_t) return int;
+ pragma Import (C, pthread_attr_setstacksize);
+
+ function pthread_create
+ (thread : access pthread_t;
+ attributes : access pthread_attr_t;
+ start_routine : Thread_Body;
+ arg : System.Address) return int;
+ pragma Import (C, pthread_create, "pthread_create");
+
+ procedure pthread_exit (status : System.Address);
+ pragma Import (C, pthread_exit, "pthread_exit");
+
+ function pthread_self return pthread_t;
+ pragma Import (C, pthread_self, "pthread_self");
+
+ --------------------------
+ -- POSIX.1c Section 17 --
+ --------------------------
+
+ function pthread_setspecific
+ (key : pthread_key_t;
+ value : System.Address) return int;
+ pragma Import (C, pthread_setspecific, "pthread_setspecific");
+
+ function pthread_getspecific (key : pthread_key_t) return System.Address;
+ -- FSU_THREADS has a nonstandard pthread_getspecific
+
+ type destructor_pointer is access procedure (arg : System.Address);
+
+ function pthread_key_create
+ (key : access pthread_key_t;
+ destructor : destructor_pointer) return int;
+ pragma Import (C, pthread_key_create, "pthread_key_create");
+
+private
+
+ type array_type_1 is array (Integer range 0 .. 3) of unsigned_long;
+ type sigset_t is record
+ X_X_sigbits : array_type_1;
+ end record;
+ pragma Convention (C, sigset_t);
+
+ type pid_t is new long;
+
+ type time_t is new long;
+
+ type timespec is record
+ tv_sec : time_t;
+ tv_nsec : long;
+ end record;
+ pragma Convention (C, timespec);
+
+ type clockid_t is new int;
+ CLOCK_REALTIME : constant clockid_t := 0;
+
+ type struct_timeval is record
+ tv_sec : long;
+ tv_usec : long;
+ end record;
+ pragma Convention (C, struct_timeval);
+
+ type pthread_attr_t is record
+ flags : int;
+ stacksize : int;
+ contentionscope : int;
+ inheritsched : int;
+ detachstate : int;
+ sched : int;
+ prio : int;
+ starttime : timespec;
+ deadline : timespec;
+ period : timespec;
+ end record;
+ pragma Convention (C, pthread_attr_t);
+
+ type pthread_condattr_t is record
+ flags : int;
+ end record;
+ pragma Convention (C, pthread_condattr_t);
+
+ type pthread_mutexattr_t is record
+ flags : int;
+ prio_ceiling : int;
+ protocol : int;
+ end record;
+ pragma Convention (C, pthread_mutexattr_t);
+
+ type sigjmp_buf is array (Integer range 0 .. 18) of int;
+
+ type pthread_t_struct is record
+ context : sigjmp_buf;
+ pbody : sigjmp_buf;
+ errno : int;
+ ret : int;
+ stack_base : System.Address;
+ end record;
+ pragma Convention (C, pthread_t_struct);
+
+ type pthread_t is access all pthread_t_struct;
+
+ type queue_t is record
+ head : System.Address;
+ tail : System.Address;
+ end record;
+ pragma Convention (C, queue_t);
+
+ type pthread_mutex_t is record
+ queue : queue_t;
+ lock : plain_char;
+ owner : System.Address;
+ flags : int;
+ prio_ceiling : int;
+ protocol : int;
+ prev_max_ceiling_prio : int;
+ end record;
+ pragma Convention (C, pthread_mutex_t);
+
+ type pthread_cond_t is record
+ queue : queue_t;
+ flags : int;
+ waiters : int;
+ mutex : System.Address;
+ end record;
+ pragma Convention (C, pthread_cond_t);
+
+ type pthread_key_t is new int;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-solaris-posix.ads b/gcc/ada/s-osinte-solaris-posix.ads
new file mode 100644
index 00000000000..b5ad0af3877
--- /dev/null
+++ b/gcc/ada/s-osinte-solaris-posix.ads
@@ -0,0 +1,539 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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 is a Solaris (POSIX Threads) version of this package
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+with Interfaces.C;
+with Unchecked_Conversion;
+
+package System.OS_Interface is
+ pragma Preelaborate;
+
+ pragma Linker_Options ("-lposix4");
+ pragma Linker_Options ("-lpthread");
+
+ subtype int is Interfaces.C.int;
+ subtype short is Interfaces.C.short;
+ subtype long is Interfaces.C.long;
+ subtype unsigned is Interfaces.C.unsigned;
+ subtype unsigned_short is Interfaces.C.unsigned_short;
+ subtype unsigned_long is Interfaces.C.unsigned_long;
+ subtype unsigned_char is Interfaces.C.unsigned_char;
+ subtype plain_char is Interfaces.C.plain_char;
+ subtype size_t is Interfaces.C.size_t;
+
+ -----------
+ -- Errno --
+ -----------
+
+ function errno return int;
+ pragma Import (C, errno, "__get_errno");
+
+ EAGAIN : constant := 11;
+ EINTR : constant := 4;
+ EINVAL : constant := 22;
+ ENOMEM : constant := 12;
+ ETIMEDOUT : constant := 145;
+
+ -------------
+ -- Signals --
+ -------------
+
+ Max_Interrupt : constant := 45;
+ type Signal is new int range 0 .. Max_Interrupt;
+ for Signal'Size use int'Size;
+
+ SIGHUP : constant := 1; -- hangup
+ SIGINT : constant := 2; -- interrupt (rubout)
+ SIGQUIT : constant := 3; -- quit (ASCD FS)
+ SIGILL : constant := 4; -- illegal instruction (not reset)
+ SIGTRAP : constant := 5; -- trace trap (not reset)
+ SIGIOT : constant := 6; -- IOT instruction
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGEMT : constant := 7; -- EMT instruction
+ SIGFPE : constant := 8; -- floating point exception
+ SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
+ SIGBUS : constant := 10; -- bus error
+ SIGSEGV : constant := 11; -- segmentation violation
+ SIGSYS : constant := 12; -- bad argument to system call
+ SIGPIPE : constant := 13; -- write on a pipe with no one to read it
+ SIGALRM : constant := 14; -- alarm clock
+ SIGTERM : constant := 15; -- software termination signal from kill
+ SIGUSR1 : constant := 16; -- user defined signal 1
+ SIGUSR2 : constant := 17; -- user defined signal 2
+ SIGCLD : constant := 18; -- alias for SIGCHLD
+ SIGCHLD : constant := 18; -- child status change
+ SIGPWR : constant := 19; -- power-fail restart
+ SIGWINCH : constant := 20; -- window size change
+ SIGURG : constant := 21; -- urgent condition on IO channel
+ SIGPOLL : constant := 22; -- pollable event occurred
+ SIGIO : constant := 22; -- I/O possible (Solaris SIGPOLL alias)
+ SIGSTOP : constant := 23; -- stop (cannot be caught or ignored)
+ SIGTSTP : constant := 24; -- user stop requested from tty
+ SIGCONT : constant := 25; -- stopped process has been continued
+ SIGTTIN : constant := 26; -- background tty read attempted
+ SIGTTOU : constant := 27; -- background tty write attempted
+ SIGVTALRM : constant := 28; -- virtual timer expired
+ SIGPROF : constant := 29; -- profiling timer expired
+ SIGXCPU : constant := 30; -- CPU time limit exceeded
+ SIGXFSZ : constant := 31; -- filesize limit exceeded
+ SIGWAITING : constant := 32; -- process's lwps blocked (Solaris)
+ SIGLWP : constant := 33; -- used by thread library (Solaris)
+ SIGFREEZE : constant := 34; -- used by CPR (Solaris)
+ SIGTHAW : constant := 35; -- used by CPR (Solaris)
+ SIGCANCEL : constant := 36; -- thread cancellation signal (libthread)
+
+ SIGADAABORT : constant := SIGABRT;
+
+ type Signal_Set is array (Natural range <>) of Signal;
+
+ Unmasked : constant Signal_Set := (SIGTRAP, SIGLWP, SIGPROF);
+
+ -- Following signals should not be disturbed.
+ -- See c-posix-signals.c in FLORIST
+
+ Reserved : constant Signal_Set :=
+ (SIGKILL, SIGSTOP, SIGWAITING, SIGCANCEL);
+
+ type sigset_t is private;
+
+ function sigaddset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigaddset, "sigaddset");
+
+ function sigdelset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigdelset, "sigdelset");
+
+ function sigfillset (set : access sigset_t) return int;
+ pragma Import (C, sigfillset, "sigfillset");
+
+ function sigismember (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigismember, "sigismember");
+
+ function sigemptyset (set : access sigset_t) return int;
+ pragma Import (C, sigemptyset, "sigemptyset");
+
+ type struct_sigaction is record
+ sa_flags : int;
+ sa_handler : System.Address;
+ sa_mask : sigset_t;
+ sa_resv1 : int;
+ sa_resv2 : int;
+ end record;
+ pragma Convention (C, struct_sigaction);
+ type struct_sigaction_ptr is access all struct_sigaction;
+
+ SA_SIGINFO : constant := 16#0008#;
+
+ SIG_BLOCK : constant := 1;
+ SIG_UNBLOCK : constant := 2;
+ SIG_SETMASK : constant := 3;
+
+ SIG_DFL : constant := 0;
+ SIG_IGN : constant := 1;
+
+ function sigaction
+ (sig : Signal;
+ act : struct_sigaction_ptr;
+ oact : struct_sigaction_ptr) return int;
+ pragma Import (C, sigaction, "sigaction");
+
+ ----------
+ -- Time --
+ ----------
+
+ Time_Slice_Supported : constant Boolean := True;
+ -- Indicates wether time slicing is supported
+
+ type timespec is private;
+
+ type clockid_t is private;
+
+ CLOCK_REALTIME : constant clockid_t;
+
+ function clock_gettime
+ (clock_id : clockid_t;
+ tp : access timespec) return int;
+ pragma Import (C, clock_gettime, "clock_gettime");
+
+ function To_Duration (TS : timespec) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timespec (D : Duration) return timespec;
+ pragma Inline (To_Timespec);
+
+ type struct_timeval is private;
+
+ function To_Duration (TV : struct_timeval) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timeval (D : Duration) return struct_timeval;
+ pragma Inline (To_Timeval);
+
+ -------------------------
+ -- Priority Scheduling --
+ -------------------------
+
+ SCHED_FIFO : constant := 1;
+ SCHED_RR : constant := 2;
+ SCHED_OTHER : constant := 0;
+
+ -------------
+ -- Process --
+ -------------
+
+ type pid_t is private;
+
+ function kill (pid : pid_t; sig : Signal) return int;
+ pragma Import (C, kill, "kill");
+
+ function getpid return pid_t;
+ pragma Import (C, getpid, "getpid");
+
+ ---------
+ -- LWP --
+ ---------
+
+ function lwp_self return System.Address;
+ pragma Import (C, lwp_self, "_lwp_self");
+
+ -------------
+ -- Threads --
+ -------------
+
+ type Thread_Body is access
+ function (arg : System.Address) return System.Address;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ type pthread_t is private;
+ subtype Thread_Id is pthread_t;
+
+ type pthread_mutex_t is limited private;
+ type pthread_cond_t is limited private;
+ type pthread_attr_t is limited private;
+ type pthread_mutexattr_t is limited private;
+ type pthread_condattr_t is limited private;
+ type pthread_key_t is private;
+
+ PTHREAD_CREATE_DETACHED : constant := 16#40#;
+
+ -----------
+ -- Stack --
+ -----------
+
+ Stack_Base_Available : constant Boolean := False;
+ -- Indicates wether the stack base is available on this target.
+
+ function Get_Stack_Base (thread : pthread_t) return Address;
+ pragma Inline (Get_Stack_Base);
+ -- returns the stack base of the specified thread.
+ -- Only call this function when Stack_Base_Available is True.
+
+ 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
+
+ PROT_NONE : constant := 0;
+ PROT_READ : constant := 1;
+ PROT_WRITE : constant := 2;
+ PROT_EXEC : constant := 4;
+ PROT_ALL : constant := PROT_READ + PROT_WRITE + PROT_EXEC;
+
+ PROT_ON : constant := PROT_READ;
+ PROT_OFF : constant := PROT_ALL;
+
+ function mprotect (addr : Address; len : size_t; prot : int) return int;
+ pragma Import (C, mprotect);
+
+ ---------------------------------------
+ -- Nonstandard Thread Initialization --
+ ---------------------------------------
+
+ procedure pthread_init;
+ -- This is a dummy procedure to share some GNULLI files
+
+ -------------------------
+ -- POSIX.1c Section 3 --
+ -------------------------
+
+ function sigwait
+ (set : access sigset_t;
+ sig : access Signal) return int;
+ pragma Import (C, sigwait, "__posix_sigwait");
+
+ function pthread_kill
+ (thread : pthread_t;
+ sig : Signal) return int;
+ pragma Import (C, pthread_kill, "pthread_kill");
+
+ type sigset_t_ptr is access all sigset_t;
+
+ function pthread_sigmask
+ (how : int;
+ set : sigset_t_ptr;
+ oset : sigset_t_ptr) return int;
+ pragma Import (C, pthread_sigmask, "pthread_sigmask");
+
+ --------------------------
+ -- POSIX.1c Section 11 --
+ --------------------------
+
+ function pthread_mutexattr_init
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_init, "pthread_mutexattr_init");
+
+ function pthread_mutexattr_destroy
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_destroy, "pthread_mutexattr_destroy");
+
+ function pthread_mutex_init
+ (mutex : access pthread_mutex_t;
+ attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutex_init, "pthread_mutex_init");
+
+ function pthread_mutex_destroy (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_destroy, "pthread_mutex_destroy");
+
+ function pthread_mutex_lock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_lock, "pthread_mutex_lock");
+
+ function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_unlock, "pthread_mutex_unlock");
+
+ function pthread_condattr_init
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_init, "pthread_condattr_init");
+
+ function pthread_condattr_destroy
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_destroy, "pthread_condattr_destroy");
+
+ function pthread_cond_init
+ (cond : access pthread_cond_t;
+ attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_cond_init, "pthread_cond_init");
+
+ function pthread_cond_destroy (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_destroy, "pthread_cond_destroy");
+
+ function pthread_cond_signal (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_signal, "pthread_cond_signal");
+
+ function pthread_cond_wait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_cond_wait, "pthread_cond_wait");
+
+ function pthread_cond_timedwait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ abstime : access timespec) return int;
+ pragma Import (C, pthread_cond_timedwait, "pthread_cond_timedwait");
+
+ Relative_Timed_Wait : constant Boolean := False;
+ -- pthread_cond_timedwait requires an absolute delay time
+
+ --------------------------
+ -- POSIX.1c Section 13 --
+ --------------------------
+
+ PTHREAD_PRIO_NONE : constant := 0;
+ PTHREAD_PRIO_INHERIT : constant := 16#10#;
+ PTHREAD_PRIO_PROTECT : constant := 16#20#;
+
+ function pthread_mutexattr_setprotocol
+ (attr : access pthread_mutexattr_t;
+ protocol : int) return int;
+ pragma Import (C, pthread_mutexattr_setprotocol);
+
+ function pthread_mutexattr_setprioceiling
+ (attr : access pthread_mutexattr_t;
+ prioceiling : int) return int;
+ pragma Import (C, pthread_mutexattr_setprioceiling);
+
+ type Array_8_Int is array (0 .. 7) of int;
+ type struct_sched_param is record
+ sched_priority : int;
+ sched_pad : Array_8_Int;
+ end record;
+
+ function pthread_setschedparam
+ (thread : pthread_t;
+ policy : int;
+ param : access struct_sched_param) return int;
+ pragma Import (C, pthread_setschedparam, "pthread_setschedparam");
+
+ function pthread_attr_setscope
+ (attr : access pthread_attr_t;
+ contentionscope : int) return int;
+ pragma Import (C, pthread_attr_setscope, "pthread_attr_setscope");
+
+ function pthread_attr_setinheritsched
+ (attr : access pthread_attr_t;
+ inheritsched : int) return int;
+ pragma Import (C, pthread_attr_setinheritsched);
+
+ function pthread_attr_setschedpolicy
+ (attr : access pthread_attr_t;
+ policy : int) return int;
+ pragma Import (C, pthread_attr_setschedpolicy);
+
+ function sched_yield return int;
+ pragma Import (C, sched_yield, "sched_yield");
+
+ ---------------------------
+ -- P1003.1c - Section 16 --
+ ---------------------------
+
+ function pthread_attr_init (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_init, "pthread_attr_init");
+
+ function pthread_attr_destroy
+ (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_destroy, "pthread_attr_destroy");
+
+ function pthread_attr_setdetachstate
+ (attr : access pthread_attr_t;
+ detachstate : int) return int;
+ pragma Import (C, pthread_attr_setdetachstate);
+
+ function pthread_attr_setstacksize
+ (attr : access pthread_attr_t;
+ stacksize : size_t) return int;
+ pragma Import (C, pthread_attr_setstacksize);
+
+ function pthread_create
+ (thread : access pthread_t;
+ attributes : access pthread_attr_t;
+ start_routine : Thread_Body;
+ arg : System.Address) return int;
+ pragma Import (C, pthread_create, "pthread_create");
+
+ procedure pthread_exit (status : System.Address);
+ pragma Import (C, pthread_exit, "pthread_exit");
+
+ function pthread_self return pthread_t;
+ pragma Import (C, pthread_self, "pthread_self");
+
+ --------------------------
+ -- POSIX.1c Section 17 --
+ --------------------------
+
+ function pthread_setspecific
+ (key : pthread_key_t;
+ value : System.Address) return int;
+ pragma Import (C, pthread_setspecific, "pthread_setspecific");
+
+ function pthread_getspecific (key : pthread_key_t) return System.Address;
+ pragma Import (C, pthread_getspecific, "pthread_getspecific");
+
+ type destructor_pointer is access procedure (arg : System.Address);
+
+ function pthread_key_create
+ (key : access pthread_key_t;
+ destructor : destructor_pointer) return int;
+ pragma Import (C, pthread_key_create, "pthread_key_create");
+
+private
+
+ type array_type_1 is array (Integer range 0 .. 3) of unsigned_long;
+ type sigset_t is record
+ X_X_sigbits : array_type_1;
+ end record;
+ pragma Convention (C, sigset_t);
+
+ type pid_t is new long;
+
+ type time_t is new long;
+
+ type timespec is record
+ tv_sec : time_t;
+ tv_nsec : long;
+ end record;
+ pragma Convention (C, timespec);
+
+ type clockid_t is new int;
+ CLOCK_REALTIME : constant clockid_t := 0;
+
+ type struct_timeval is record
+ tv_sec : time_t;
+ tv_usec : time_t;
+ end record;
+ pragma Convention (C, struct_timeval);
+
+ type pthread_attr_t is record
+ pthread_attrp : System.Address;
+ end record;
+ pragma Convention (C, pthread_attr_t);
+
+ type pthread_condattr_t is record
+ pthread_condattrp : System.Address;
+ end record;
+ pragma Convention (C, pthread_condattr_t);
+
+ type pthread_mutexattr_t is record
+ pthread_mutexattrp : System.Address;
+ end record;
+ pragma Convention (C, pthread_mutexattr_t);
+
+ type pthread_t is new unsigned;
+
+ type uint64_t is mod 2 ** 64;
+
+ type pthread_mutex_t is record
+ pthread_mutex_flags : uint64_t;
+ pthread_mutex_owner64 : uint64_t;
+ pthread_mutex_data : uint64_t;
+ end record;
+ pragma Convention (C, pthread_mutex_t);
+ type pthread_mutex_t_ptr is access pthread_mutex_t;
+
+ type pthread_cond_t is record
+ pthread_cond_flags : uint64_t;
+ pthread_cond_data : uint64_t;
+ end record;
+ pragma Convention (C, pthread_cond_t);
+
+ type pthread_key_t is new unsigned;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-solaris.adb b/gcc/ada/s-osinte-solaris.adb
new file mode 100644
index 00000000000..299625dadc2
--- /dev/null
+++ b/gcc/ada/s-osinte-solaris.adb
@@ -0,0 +1,100 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2003, Ada Core Technologies --
+-- --
+-- 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, 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, --
+-- 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 is a Solaris version of this package.
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+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 Interfaces.C; use Interfaces.C;
+package body System.OS_Interface is
+
+ -----------------
+ -- To_Duration --
+ -----------------
+
+ function To_Duration (TS : timespec) return Duration is
+ begin
+ return Duration (TS.tv_sec) + Duration (TS.tv_nsec) / 10#1#E9;
+ end To_Duration;
+
+ -----------------
+ -- To_Timespec --
+ -----------------
+
+ function To_Timespec (D : Duration) return timespec is
+ S : time_t;
+ F : Duration;
+ begin
+ S := time_t (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+ if F < 0.0 then S := S - 1; F := F + 1.0; end if;
+ return timespec'(tv_sec => S,
+ tv_nsec => long (Long_Long_Integer (F * 10#1#E9)));
+ end To_Timespec;
+
+ function To_Duration (TV : struct_timeval) return Duration is
+ begin
+ return Duration (TV.tv_sec) + Duration (TV.tv_usec) / 10#1#E6;
+ end To_Duration;
+
+ function To_Timeval (D : Duration) return struct_timeval is
+ S : long;
+ F : Duration;
+ begin
+ S := long (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+ if F < 0.0 then S := S - 1; F := F + 1.0; end if;
+ return
+ struct_timeval'
+ (tv_sec => S,
+ tv_usec => long (Long_Long_Integer (F * 10#1#E6)));
+ end To_Timeval;
+
+ procedure pthread_init is
+ begin
+ null;
+ end pthread_init;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-solaris.ads b/gcc/ada/s-osinte-solaris.ads
new file mode 100644
index 00000000000..b5754630372
--- /dev/null
+++ b/gcc/ada/s-osinte-solaris.ads
@@ -0,0 +1,569 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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 is a Solaris (native) version of this package
+
+-- This package includes all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+with Interfaces.C;
+with Unchecked_Conversion;
+
+package System.OS_Interface is
+ pragma Preelaborate;
+
+ pragma Linker_Options ("-lposix4");
+ pragma Linker_Options ("-lthread");
+
+ subtype int is Interfaces.C.int;
+ subtype short is Interfaces.C.short;
+ subtype long is Interfaces.C.long;
+ subtype unsigned is Interfaces.C.unsigned;
+ subtype unsigned_short is Interfaces.C.unsigned_short;
+ subtype unsigned_long is Interfaces.C.unsigned_long;
+ subtype unsigned_char is Interfaces.C.unsigned_char;
+ subtype plain_char is Interfaces.C.plain_char;
+ subtype size_t is Interfaces.C.size_t;
+
+ -----------
+ -- Errno --
+ -----------
+
+ function errno return int;
+ pragma Import (C, errno, "__get_errno");
+
+ EAGAIN : constant := 11;
+ EINTR : constant := 4;
+ EINVAL : constant := 22;
+ ENOMEM : constant := 12;
+ ETIME : constant := 62;
+ ETIMEDOUT : constant := 145;
+
+ -------------
+ -- Signals --
+ -------------
+
+ Max_Interrupt : constant := 45;
+ type Signal is new int range 0 .. Max_Interrupt;
+ for Signal'Size use int'Size;
+
+ SIGHUP : constant := 1; -- hangup
+ SIGINT : constant := 2; -- interrupt (rubout)
+ SIGQUIT : constant := 3; -- quit (ASCD FS)
+ SIGILL : constant := 4; -- illegal instruction (not reset)
+ SIGTRAP : constant := 5; -- trace trap (not reset)
+ SIGIOT : constant := 6; -- IOT instruction
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGEMT : constant := 7; -- EMT instruction
+ SIGFPE : constant := 8; -- floating point exception
+ SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
+ SIGBUS : constant := 10; -- bus error
+ SIGSEGV : constant := 11; -- segmentation violation
+ SIGSYS : constant := 12; -- bad argument to system call
+ SIGPIPE : constant := 13; -- write on a pipe with no one to read it
+ SIGALRM : constant := 14; -- alarm clock
+ SIGTERM : constant := 15; -- software termination signal from kill
+ SIGUSR1 : constant := 16; -- user defined signal 1
+ SIGUSR2 : constant := 17; -- user defined signal 2
+ SIGCLD : constant := 18; -- alias for SIGCHLD
+ SIGCHLD : constant := 18; -- child status change
+ SIGPWR : constant := 19; -- power-fail restart
+ SIGWINCH : constant := 20; -- window size change
+ SIGURG : constant := 21; -- urgent condition on IO channel
+ SIGPOLL : constant := 22; -- pollable event occurred
+ SIGIO : constant := 22; -- I/O possible (Solaris SIGPOLL alias)
+ SIGSTOP : constant := 23; -- stop (cannot be caught or ignored)
+ SIGTSTP : constant := 24; -- user stop requested from tty
+ SIGCONT : constant := 25; -- stopped process has been continued
+ SIGTTIN : constant := 26; -- background tty read attempted
+ SIGTTOU : constant := 27; -- background tty write attempted
+ SIGVTALRM : constant := 28; -- virtual timer expired
+ SIGPROF : constant := 29; -- profiling timer expired
+ SIGXCPU : constant := 30; -- CPU time limit exceeded
+ SIGXFSZ : constant := 31; -- filesize limit exceeded
+ SIGWAITING : constant := 32; -- process's lwps blocked (Solaris)
+ SIGLWP : constant := 33; -- used by thread library (Solaris)
+ SIGFREEZE : constant := 34; -- used by CPR (Solaris)
+ SIGTHAW : constant := 35; -- used by CPR (Solaris)
+ SIGCANCEL : constant := 36; -- thread cancellation signal (libthread)
+
+ type Signal_Set is array (Natural range <>) of Signal;
+
+ Unmasked : constant Signal_Set := (SIGTRAP, SIGLWP, SIGPROF);
+
+ -- Following signals should not be disturbed.
+ -- See c-posix-signals.c in FLORIST
+
+ Reserved : constant Signal_Set :=
+ (SIGKILL, SIGSTOP, SIGWAITING, SIGCANCEL, SIGTRAP, SIGSEGV);
+
+ type sigset_t is private;
+
+ function sigaddset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigaddset, "sigaddset");
+
+ function sigdelset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigdelset, "sigdelset");
+
+ function sigfillset (set : access sigset_t) return int;
+ pragma Import (C, sigfillset, "sigfillset");
+
+ function sigismember (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigismember, "sigismember");
+
+ function sigemptyset (set : access sigset_t) return int;
+ pragma Import (C, sigemptyset, "sigemptyset");
+
+ type union_type_3 is new String (1 .. 116);
+ type siginfo_t is record
+ si_signo : int;
+ si_code : int;
+ si_errno : int;
+ X_data : union_type_3;
+ end record;
+ pragma Convention (C, siginfo_t);
+
+ -- The types mcontext_t and gregset_t are part of the ucontext_t
+ -- information, which is specific to Solaris2.4 for SPARC
+ -- The ucontext_t info seems to be used by the handler
+ -- for SIGSEGV to decide whether it is a Storage_Error (stack overflow) or
+ -- a Constraint_Error (bad pointer). The original code that did this
+ -- is suspect, so it is not clear whether we really need this part of
+ -- the signal context information, or perhaps something else.
+ -- More analysis is needed, after which these declarations may need to
+ -- be changed.
+
+ FPE_INTDIV : constant := 1; -- integer divide by zero
+ FPE_INTOVF : constant := 2; -- integer overflow
+ FPE_FLTDIV : constant := 3; -- floating point divide by zero
+ FPE_FLTOVF : constant := 4; -- floating point overflow
+ FPE_FLTUND : constant := 5; -- floating point underflow
+ FPE_FLTRES : constant := 6; -- floating point inexact result
+ FPE_FLTINV : constant := 7; -- invalid floating point operation
+ FPE_FLTSUB : constant := 8; -- subscript out of range
+
+ type greg_t is new int;
+
+ type gregset_t is array (0 .. 18) of greg_t;
+
+ type union_type_2 is new String (1 .. 128);
+ type record_type_1 is record
+ fpu_fr : union_type_2;
+ fpu_q : System.Address;
+ fpu_fsr : unsigned;
+ fpu_qcnt : unsigned_char;
+ fpu_q_entrysize : unsigned_char;
+ fpu_en : unsigned_char;
+ end record;
+ pragma Convention (C, record_type_1);
+
+ type array_type_7 is array (Integer range 0 .. 20) of long;
+ type mcontext_t is record
+ gregs : gregset_t;
+ gwins : System.Address;
+ fpregs : record_type_1;
+ filler : array_type_7;
+ end record;
+ pragma Convention (C, mcontext_t);
+
+ type record_type_2 is record
+ ss_sp : System.Address;
+ ss_size : int;
+ ss_flags : int;
+ end record;
+ pragma Convention (C, record_type_2);
+
+ type array_type_8 is array (Integer range 0 .. 22) of long;
+ type ucontext_t is record
+ uc_flags : unsigned_long;
+ uc_link : System.Address;
+ uc_sigmask : sigset_t;
+ uc_stack : record_type_2;
+ uc_mcontext : mcontext_t;
+ uc_filler : array_type_8;
+ end record;
+ pragma Convention (C, ucontext_t);
+
+ type Signal_Handler is access procedure
+ (signo : Signal;
+ info : access siginfo_t;
+ context : access ucontext_t);
+
+ type union_type_1 is new plain_char;
+ type array_type_2 is array (Integer range 0 .. 1) of int;
+ type struct_sigaction is record
+ sa_flags : int;
+ sa_handler : System.Address;
+ sa_mask : sigset_t;
+ sa_resv : array_type_2;
+ end record;
+ pragma Convention (C, struct_sigaction);
+ type struct_sigaction_ptr is access all struct_sigaction;
+
+ SIG_BLOCK : constant := 1;
+ SIG_UNBLOCK : constant := 2;
+ SIG_SETMASK : constant := 3;
+
+ SIG_DFL : constant := 0;
+ SIG_IGN : constant := 1;
+
+ function sigaction
+ (sig : Signal;
+ act : struct_sigaction_ptr;
+ oact : struct_sigaction_ptr) return int;
+ pragma Import (C, sigaction, "sigaction");
+
+ ----------
+ -- Time --
+ ----------
+
+ type timespec is private;
+
+ type clockid_t is private;
+
+ CLOCK_REALTIME : constant clockid_t;
+
+ function clock_gettime
+ (clock_id : clockid_t; tp : access timespec) return int;
+ pragma Import (C, clock_gettime, "clock_gettime");
+
+ function clock_getres
+ (clock_id : clockid_t; res : access timespec) return int;
+ pragma Import (C, clock_getres, "clock_getres");
+
+ function To_Duration (TS : timespec) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timespec (D : Duration) return timespec;
+ pragma Inline (To_Timespec);
+
+ type struct_timeval is private;
+ -- This is needed on systems that do not have clock_gettime()
+ -- but do have gettimeofday().
+
+ function To_Duration (TV : struct_timeval) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timeval (D : Duration) return struct_timeval;
+ pragma Inline (To_Timeval);
+
+ -------------
+ -- Process --
+ -------------
+
+ type pid_t is private;
+
+ function kill (pid : pid_t; sig : Signal) return int;
+ pragma Import (C, kill, "kill");
+
+ function getpid return pid_t;
+ pragma Import (C, getpid, "getpid");
+
+ -------------
+ -- Threads --
+ -------------
+
+ type Thread_Body is access
+ function (arg : System.Address) return System.Address;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ THR_DETACHED : constant := 64;
+ THR_BOUND : constant := 1;
+ THR_NEW_LWP : constant := 2;
+ USYNC_THREAD : constant := 0;
+
+ type thread_t is new unsigned;
+ subtype Thread_Id is thread_t;
+ -- These types should be commented ???
+
+ function To_thread_t is new Unchecked_Conversion (Integer, thread_t);
+
+ type mutex_t is limited private;
+
+ type cond_t is limited private;
+
+ type thread_key_t is private;
+
+ function thr_create
+ (stack_base : System.Address;
+ stack_size : size_t;
+ start_routine : Thread_Body;
+ arg : System.Address;
+ flags : int;
+ new_thread : access thread_t) return int;
+ pragma Import (C, thr_create, "thr_create");
+
+ function thr_min_stack return size_t;
+ pragma Import (C, thr_min_stack, "thr_min_stack");
+
+ function thr_self return thread_t;
+ pragma Import (C, thr_self, "thr_self");
+
+ function mutex_init
+ (mutex : access mutex_t;
+ mtype : int;
+ arg : System.Address) return int;
+ pragma Import (C, mutex_init, "mutex_init");
+
+ function mutex_destroy (mutex : access mutex_t) return int;
+ pragma Import (C, mutex_destroy, "mutex_destroy");
+
+ function mutex_lock (mutex : access mutex_t) return int;
+ pragma Import (C, mutex_lock, "mutex_lock");
+
+ function mutex_unlock (mutex : access mutex_t) return int;
+ pragma Import (C, mutex_unlock, "mutex_unlock");
+
+ function cond_init
+ (cond : access cond_t;
+ ctype : int;
+ arg : int) return int;
+ pragma Import (C, cond_init, "cond_init");
+
+ function cond_wait
+ (cond : access cond_t; mutex : access mutex_t) return int;
+ pragma Import (C, cond_wait, "cond_wait");
+
+ function cond_timedwait
+ (cond : access cond_t;
+ mutex : access mutex_t;
+ abstime : access timespec) return int;
+ pragma Import (C, cond_timedwait, "cond_timedwait");
+
+ function cond_signal (cond : access cond_t) return int;
+ pragma Import (C, cond_signal, "cond_signal");
+
+ function cond_destroy (cond : access cond_t) return int;
+ pragma Import (C, cond_destroy, "cond_destroy");
+
+ function thr_setspecific
+ (key : thread_key_t; value : System.Address) return int;
+ pragma Import (C, thr_setspecific, "thr_setspecific");
+
+ function thr_getspecific
+ (key : thread_key_t;
+ value : access System.Address) return int;
+ pragma Import (C, thr_getspecific, "thr_getspecific");
+
+ function thr_keycreate
+ (key : access thread_key_t; destructor : System.Address) return int;
+ pragma Import (C, thr_keycreate, "thr_keycreate");
+
+ function thr_setprio (thread : thread_t; priority : int) return int;
+ pragma Import (C, thr_setprio, "thr_setprio");
+
+ procedure thr_exit (status : System.Address);
+ pragma Import (C, thr_exit, "thr_exit");
+
+ function thr_setconcurrency (new_level : int) return int;
+ pragma Import (C, thr_setconcurrency, "thr_setconcurrency");
+
+ function sigwait (set : access sigset_t; sig : access Signal) return int;
+ pragma Import (C, sigwait, "__posix_sigwait");
+
+ function thr_kill (thread : thread_t; sig : Signal) return int;
+ pragma Import (C, thr_kill, "thr_kill");
+
+ type sigset_t_ptr is access all sigset_t;
+
+ function thr_sigsetmask
+ (how : int;
+ set : sigset_t_ptr;
+ oset : sigset_t_ptr) return int;
+ pragma Import (C, thr_sigsetmask, "thr_sigsetmask");
+
+ function pthread_sigmask
+ (how : int;
+ set : sigset_t_ptr;
+ oset : sigset_t_ptr) return int;
+ pragma Import (C, pthread_sigmask, "thr_sigsetmask");
+
+ function thr_suspend (target_thread : thread_t) return int;
+ pragma Import (C, thr_suspend, "thr_suspend");
+
+ function thr_continue (target_thread : thread_t) return int;
+ pragma Import (C, thr_continue, "thr_continue");
+
+ procedure thr_yield;
+ pragma Import (C, thr_yield, "thr_yield");
+
+ ---------
+ -- LWP --
+ ---------
+
+ P_PID : constant := 0;
+ P_LWPID : constant := 8;
+
+ PC_GETCID : constant := 0;
+ PC_GETCLINFO : constant := 1;
+ PC_SETPARMS : constant := 2;
+ PC_GETPARMS : constant := 3;
+ PC_ADMIN : constant := 4;
+
+ PC_CLNULL : constant := -1;
+
+ RT_NOCHANGE : constant := -1;
+ RT_TQINF : constant := -2;
+ RT_TQDEF : constant := -3;
+
+ PC_CLNMSZ : constant := 16;
+
+ PC_VERSION : constant := 1;
+
+ type lwpid_t is new int;
+
+ type pri_t is new short;
+
+ type id_t is new long;
+
+ P_MYID : constant := -1;
+ -- the specified LWP or process is the current one.
+
+ type struct_pcinfo is record
+ pc_cid : id_t;
+ pc_clname : String (1 .. PC_CLNMSZ);
+ rt_maxpri : short;
+ end record;
+ pragma Convention (C, struct_pcinfo);
+
+ type struct_pcparms is record
+ pc_cid : id_t;
+ rt_pri : pri_t;
+ rt_tqsecs : long;
+ rt_tqnsecs : long;
+ end record;
+ pragma Convention (C, struct_pcparms);
+
+ function priocntl
+ (ver : int;
+ id_type : int;
+ id : lwpid_t;
+ cmd : int;
+ arg : System.Address) return Interfaces.C.long;
+ pragma Import (C, priocntl, "__priocntl");
+
+ function lwp_self return lwpid_t;
+ pragma Import (C, lwp_self, "_lwp_self");
+
+ type processorid_t is new int;
+ type processorid_t_ptr is access all processorid_t;
+
+ -- Constants for function processor_bind
+
+ PBIND_QUERY : constant processorid_t := -2;
+ -- the processor bindings are not changed.
+
+ PBIND_NONE : constant processorid_t := -1;
+ -- the processor bindings of the specified LWPs are cleared.
+
+ -- Flags for function p_online
+
+ PR_OFFLINE : constant int := 1;
+ -- processor is offline, as quiet as possible
+
+ PR_ONLINE : constant int := 2;
+ -- processor online
+
+ PR_STATUS : constant int := 3;
+ -- value passed to p_online to request status
+
+ function p_online (processorid : processorid_t; flag : int) return int;
+ pragma Import (C, p_online, "p_online");
+
+ function processor_bind
+ (id_type : int;
+ id : id_t;
+ proc_id : processorid_t;
+ obind : processorid_t_ptr) return int;
+ pragma Import (C, processor_bind, "processor_bind");
+
+ procedure pthread_init;
+ -- dummy procedure to share s-intman.adb with other Solaris targets.
+
+private
+
+ type array_type_1 is array (0 .. 3) of unsigned_long;
+ type sigset_t is record
+ X_X_sigbits : array_type_1;
+ end record;
+ pragma Convention (C, sigset_t);
+
+ type pid_t is new long;
+
+ type time_t is new long;
+
+ type timespec is record
+ tv_sec : time_t;
+ tv_nsec : long;
+ end record;
+ pragma Convention (C, timespec);
+
+ type clockid_t is new int;
+ CLOCK_REALTIME : constant clockid_t := 0;
+
+ type struct_timeval is record
+ tv_sec : long;
+ tv_usec : long;
+ end record;
+ pragma Convention (C, struct_timeval);
+
+ type array_type_9 is array (0 .. 3) of unsigned_char;
+ type record_type_3 is record
+ flag : array_type_9;
+ Xtype : unsigned_long;
+ end record;
+ pragma Convention (C, record_type_3);
+
+ type mutex_t is record
+ flags : record_type_3;
+ lock : String (1 .. 8);
+ data : String (1 .. 8);
+ end record;
+ pragma Convention (C, mutex_t);
+
+ type cond_t is record
+ flag : array_type_9;
+ Xtype : unsigned_long;
+ data : String (1 .. 8);
+ end record;
+ pragma Convention (C, cond_t);
+
+ type thread_key_t is new unsigned;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-tru64.adb b/gcc/ada/s-osinte-tru64.adb
new file mode 100644
index 00000000000..e0b683e52cd
--- /dev/null
+++ b/gcc/ada/s-osinte-tru64.adb
@@ -0,0 +1,135 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1998-2002, 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- --
+-- 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, 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, --
+-- 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 is the DEC Unix version of this package.
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+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 Interfaces.C; use Interfaces.C;
+with System.Machine_Code; use System.Machine_Code;
+
+package body System.OS_Interface is
+
+ ------------------
+ -- pthread_init --
+ ------------------
+
+ procedure pthread_init is
+ begin
+ null;
+ end pthread_init;
+
+ ------------------
+ -- pthread_self --
+ ------------------
+
+ function pthread_self return pthread_t is
+ Self : pthread_t;
+ begin
+ Asm ("call_pal 0x9e" & ASCII.LF & ASCII.HT &
+ "bis $31, $0, %0",
+ Outputs => pthread_t'Asm_Output ("=r", Self),
+ Clobber => "$0");
+ return Self;
+ end pthread_self;
+
+ -----------------
+ -- To_Duration --
+ -----------------
+
+ function To_Duration (TS : timespec) return Duration is
+ begin
+ return Duration (TS.tv_sec) + Duration (TS.tv_nsec) / 10#1#E9;
+ end To_Duration;
+
+ function To_Duration (TV : struct_timeval) return Duration is
+ begin
+ return Duration (TV.tv_sec) + Duration (TV.tv_usec) / 10#1#E6;
+ end To_Duration;
+
+ -----------------
+ -- To_Timespec --
+ -----------------
+
+ function To_Timespec (D : Duration) return timespec is
+ S : time_t;
+ F : Duration;
+
+ begin
+ S := time_t (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return timespec'(tv_sec => S,
+ tv_nsec => long (Long_Long_Integer (F * 10#1#E9)));
+ end To_Timespec;
+
+ ----------------
+ -- To_Timeval --
+ ----------------
+
+ function To_Timeval (D : Duration) return struct_timeval is
+ S : time_t;
+ F : Duration;
+
+ begin
+ S := time_t (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return
+ struct_timeval'
+ (tv_sec => S,
+ tv_usec => time_t (Long_Long_Integer (F * 10#1#E6)));
+ end To_Timeval;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-tru64.ads b/gcc/ada/s-osinte-tru64.ads
new file mode 100644
index 00000000000..dc01b058343
--- /dev/null
+++ b/gcc/ada/s-osinte-tru64.ads
@@ -0,0 +1,539 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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 is the DEC Unix 4.0/5.1 version of this package
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+with Interfaces.C;
+with Unchecked_Conversion;
+
+package System.OS_Interface is
+ pragma Preelaborate;
+
+ pragma Linker_Options ("-lpthread");
+ pragma Linker_Options ("-lmach");
+ pragma Linker_Options ("-lexc");
+ pragma Linker_Options ("-lrt");
+
+ subtype int is Interfaces.C.int;
+ subtype short is Interfaces.C.short;
+ subtype long is Interfaces.C.long;
+ subtype unsigned is Interfaces.C.unsigned;
+ subtype unsigned_short is Interfaces.C.unsigned_short;
+ subtype unsigned_long is Interfaces.C.unsigned_long;
+ subtype unsigned_char is Interfaces.C.unsigned_char;
+ subtype plain_char is Interfaces.C.plain_char;
+ subtype size_t is Interfaces.C.size_t;
+ subtype char_array is Interfaces.C.char_array;
+
+ -----------
+ -- Errno --
+ -----------
+
+ function errno return int;
+ pragma Import (C, errno, "_Geterrno");
+
+ EAGAIN : constant := 35;
+ EINTR : constant := 4;
+ EINVAL : constant := 22;
+ ENOMEM : constant := 12;
+ ETIMEDOUT : constant := 60;
+
+ -------------
+ -- Signals --
+ -------------
+
+ Max_Interrupt : constant := 48;
+ type Signal is new int range 0 .. Max_Interrupt;
+ for Signal'Size use int'Size;
+
+ SIGHUP : constant := 1; -- hangup
+ SIGINT : constant := 2; -- interrupt (rubout)
+ SIGQUIT : constant := 3; -- quit (ASCD FS)
+ SIGILL : constant := 4; -- illegal instruction (not reset)
+ SIGTRAP : constant := 5; -- trace trap (not reset)
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGIOT : constant := 6; -- abort (terminate) process
+ SIGLOST : constant := 6; -- old BSD signal ??
+ SIGEMT : constant := 7; -- EMT instruction
+ SIGFPE : constant := 8; -- floating point exception
+ SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
+ SIGBUS : constant := 10; -- bus error
+ SIGSEGV : constant := 11; -- segmentation violation
+ SIGSYS : constant := 12; -- bad argument to system call
+ SIGPIPE : constant := 13; -- write on a pipe with no one to read it
+ SIGALRM : constant := 14; -- alarm clock
+ SIGTERM : constant := 15; -- software termination signal from kill
+ SIGURG : constant := 16; -- urgent condition on IO channel
+ SIGIOINT : constant := 16; -- printer to backend error signal
+ SIGSTOP : constant := 17; -- stop (cannot be caught or ignored)
+ SIGTSTP : constant := 18; -- user stop requested from tty
+ SIGCONT : constant := 19; -- stopped process has been continued
+ SIGCHLD : constant := 20; -- child status change
+ SIGTTIN : constant := 21; -- background tty read attempted
+ SIGTTOU : constant := 22; -- background tty write attempted
+ SIGPOLL : constant := 23; -- I/O possible, or completed
+ SIGIO : constant := 23; -- STREAMS version of SIGPOLL
+ SIGAIO : constant := 23; -- base lan i/o
+ SIGPTY : constant := 23; -- pty i/o
+ SIGXCPU : constant := 24; -- CPU time limit exceeded
+ SIGXFSZ : constant := 25; -- filesize limit exceeded
+ SIGVTALRM : constant := 26; -- virtual timer expired
+ SIGPROF : constant := 27; -- profiling timer expired
+ SIGWINCH : constant := 28; -- window size change
+ SIGINFO : constant := 29; -- information request
+ SIGPWR : constant := 29; -- Power Fail/Restart -- SVID3/SVR4
+ SIGUSR1 : constant := 30; -- user defined signal 1
+ SIGUSR2 : constant := 31; -- user defined signal 2
+ SIGRESV : constant := 32; -- reserved by Digital for future use
+
+ SIGADAABORT : constant := SIGABRT;
+
+ type Signal_Set is array (Natural range <>) of Signal;
+
+ Unmasked : constant Signal_Set := (0 .. 0 => SIGTRAP);
+ Reserved : constant Signal_Set := (SIGALRM, SIGABRT, SIGKILL, SIGSTOP);
+
+ type sigset_t is private;
+
+ function sigaddset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigaddset);
+
+ function sigdelset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigdelset);
+
+ function sigfillset (set : access sigset_t) return int;
+ pragma Import (C, sigfillset);
+
+ function sigismember (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigismember);
+
+ function sigemptyset (set : access sigset_t) return int;
+ pragma Import (C, sigemptyset);
+
+ type union_type_3 is new String (1 .. 116);
+ type siginfo_t is record
+ si_signo : int;
+ si_errno : int;
+ si_code : int;
+ X_data : union_type_3;
+ end record;
+ for siginfo_t'Size use 8 * 128;
+ pragma Convention (C, siginfo_t);
+
+ type struct_sigaction is record
+ sa_handler : System.Address;
+ sa_mask : sigset_t;
+ sa_flags : int;
+ sa_signo : int;
+ end record;
+ pragma Convention (C, struct_sigaction);
+ type struct_sigaction_ptr is access all struct_sigaction;
+
+ SIG_BLOCK : constant := 1;
+ SIG_UNBLOCK : constant := 2;
+ SIG_SETMASK : constant := 3;
+
+ SIG_DFL : constant := 0;
+ SIG_IGN : constant := 1;
+
+ SA_NODEFER : constant := 8;
+ SA_SIGINFO : constant := 16#40#;
+
+ function sigaction
+ (sig : Signal;
+ act : struct_sigaction_ptr;
+ oact : struct_sigaction_ptr) return int;
+ pragma Import (C, sigaction);
+
+ ----------
+ -- Time --
+ ----------
+
+ type timespec is private;
+
+ function nanosleep (rqtp, rmtp : access timespec) return int;
+ pragma Import (C, nanosleep);
+
+ type clockid_t is private;
+
+ CLOCK_REALTIME : constant clockid_t;
+
+ function clock_gettime
+ (clock_id : clockid_t;
+ tp : access timespec) return int;
+ pragma Import (C, clock_gettime);
+
+ function To_Duration (TS : timespec) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timespec (D : Duration) return timespec;
+ pragma Inline (To_Timespec);
+
+ type struct_timezone is record
+ tz_minuteswest : int;
+ tz_dsttime : int;
+ end record;
+ pragma Convention (C, struct_timezone);
+ type struct_timeval is private;
+ -- This is needed on systems that do not have clock_gettime()
+ -- but do have gettimeofday().
+
+ function To_Duration (TV : struct_timeval) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timeval (D : Duration) return struct_timeval;
+ pragma Inline (To_Timeval);
+
+ -------------------------
+ -- Priority Scheduling --
+ -------------------------
+
+ SCHED_FIFO : constant := 1;
+ SCHED_RR : constant := 2;
+ SCHED_OTHER : constant := 3;
+ SCHED_LFI : constant := 5;
+
+ -------------
+ -- Process --
+ -------------
+
+ type pid_t is private;
+
+ function kill (pid : pid_t; sig : Signal) return int;
+ pragma Import (C, kill);
+
+ function getpid return pid_t;
+ pragma Import (C, getpid);
+
+ BIND_NO_INHERIT : constant := 1;
+
+ function bind_to_cpu
+ (pid : pid_t;
+ cpu_mask : unsigned_long;
+ flag : unsigned_long := BIND_NO_INHERIT) return int;
+ pragma Import (C, bind_to_cpu);
+
+ -------------
+ -- Threads --
+ -------------
+
+ type Thread_Body is access
+ function (arg : System.Address) return System.Address;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ type pthread_t is private;
+ subtype Thread_Id is pthread_t;
+
+ type pthread_mutex_t is limited private;
+ type pthread_cond_t is limited private;
+ type pthread_attr_t is limited private;
+ type pthread_mutexattr_t is limited private;
+ type pthread_condattr_t is limited private;
+ type pthread_key_t is private;
+
+ PTHREAD_CREATE_DETACHED : constant := 1;
+
+ PTHREAD_SCOPE_PROCESS : constant := 0;
+ PTHREAD_SCOPE_SYSTEM : constant := 1;
+
+ PTHREAD_EXPLICIT_SCHED : constant := 1;
+
+ ---------------------------------------
+ -- Nonstandard Thread Initialization --
+ ---------------------------------------
+
+ procedure pthread_init;
+ pragma Inline (pthread_init);
+ -- This is a dummy procedure to share some GNULLI files
+
+ ---------------------------
+ -- POSIX.1c Section 3 --
+ ---------------------------
+
+ function sigwait
+ (set : access sigset_t;
+ sig : access Signal) return int;
+ pragma Import (C, sigwait, "__sigwaitd10");
+
+ function pthread_kill
+ (thread : pthread_t;
+ sig : Signal) return int;
+ pragma Import (C, pthread_kill);
+
+ type sigset_t_ptr is access all sigset_t;
+
+ function pthread_sigmask
+ (how : int;
+ set : sigset_t_ptr;
+ oset : sigset_t_ptr) return int;
+ pragma Import (C, pthread_sigmask);
+
+ ----------------------------
+ -- POSIX.1c Section 11 --
+ ----------------------------
+
+ function pthread_mutexattr_init (attr : access pthread_mutexattr_t)
+ return int;
+ pragma Import (C, pthread_mutexattr_init);
+
+ function pthread_mutexattr_destroy
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_destroy);
+
+ function pthread_mutex_init
+ (mutex : access pthread_mutex_t;
+ attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutex_init, "__pthread_mutex_init");
+
+ function pthread_mutex_destroy (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_destroy, "__pthread_mutex_destroy");
+
+ function pthread_mutex_lock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_lock, "__pthread_mutex_lock");
+
+ function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_unlock, "__pthread_mutex_unlock");
+
+ function pthread_condattr_init
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_init);
+
+ function pthread_condattr_destroy
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_destroy);
+
+ function pthread_cond_init
+ (cond : access pthread_cond_t;
+ attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_cond_init, "__pthread_cond_init");
+
+ function pthread_cond_destroy (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_destroy, "__pthread_cond_destroy");
+
+ function pthread_cond_signal (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_signal, "__pthread_cond_signal");
+
+ function pthread_cond_wait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_cond_wait, "__pthread_cond_wait");
+
+ function pthread_cond_timedwait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ abstime : access timespec) return int;
+ pragma Import (C, pthread_cond_timedwait, "__pthread_cond_timedwait");
+
+ ----------------------------
+ -- POSIX.1c Section 13 --
+ ----------------------------
+
+ function pthread_mutexattr_setprotocol
+ (attr : access pthread_mutexattr_t;
+ protocol : int) return int;
+ pragma Import (C, pthread_mutexattr_setprotocol);
+
+ function pthread_mutexattr_setprioceiling
+ (attr : access pthread_mutexattr_t;
+ prioceiling : int) return int;
+ pragma Import (C, pthread_mutexattr_setprioceiling);
+
+ type struct_sched_param is record
+ sched_priority : int; -- scheduling priority
+ end record;
+
+ function pthread_setschedparam
+ (thread : pthread_t;
+ policy : int;
+ param : access struct_sched_param) return int;
+ pragma Import (C, pthread_setschedparam);
+
+ function pthread_attr_setscope
+ (attr : access pthread_attr_t;
+ contentionscope : int) return int;
+ pragma Import (C, pthread_attr_setscope);
+
+ function pthread_attr_setinheritsched
+ (attr : access pthread_attr_t;
+ inheritsched : int) return int;
+ pragma Import (C, pthread_attr_setinheritsched,
+ "__pthread_attr_setinheritsched");
+
+ function pthread_attr_setschedpolicy
+ (attr : access pthread_attr_t; policy : int) return int;
+ pragma Import (C, pthread_attr_setschedpolicy);
+
+ function pthread_attr_setschedparam
+ (attr : access pthread_attr_t;
+ sched_param : access struct_sched_param) return int;
+ pragma Import (C, pthread_attr_setschedparam);
+
+ function sched_yield return int;
+ pragma Import (C, sched_yield);
+
+ ---------------------------
+ -- P1003.1c - Section 16 --
+ ---------------------------
+
+ function pthread_attr_init (attributes : access pthread_attr_t)
+ return int;
+ pragma Import (C, pthread_attr_init);
+
+ function pthread_attr_destroy (attributes : access pthread_attr_t)
+ return int;
+ pragma Import (C, pthread_attr_destroy);
+
+ function pthread_attr_setdetachstate
+ (attr : access pthread_attr_t;
+ detachstate : int) return int;
+ pragma Import (C, pthread_attr_setdetachstate);
+
+ function pthread_attr_setstacksize
+ (attr : access pthread_attr_t;
+ stacksize : size_t) return int;
+ pragma Import (C, pthread_attr_setstacksize, "__pthread_attr_setstacksize");
+
+ function pthread_create
+ (thread : access pthread_t;
+ attributes : access pthread_attr_t;
+ start_routine : Thread_Body;
+ arg : System.Address) return int;
+ pragma Import (C, pthread_create, "__pthread_create");
+
+ procedure pthread_exit (status : System.Address);
+ pragma Import (C, pthread_exit, "__pthread_exit");
+
+ function pthread_self return pthread_t;
+ pragma Inline (pthread_self);
+
+ --------------------------
+ -- POSIX.1c Section 17 --
+ --------------------------
+
+ function pthread_setspecific
+ (key : pthread_key_t; value : System.Address) return int;
+ pragma Import (C, pthread_setspecific, "__pthread_setspecific");
+
+ function pthread_getspecific (key : pthread_key_t) return System.Address;
+ pragma Import (C, pthread_getspecific, "__pthread_getspecific");
+
+ type destructor_pointer is access procedure (arg : System.Address);
+
+ function pthread_key_create
+ (key : access pthread_key_t;
+ destructor : destructor_pointer) return int;
+ pragma Import (C, pthread_key_create);
+
+private
+
+ type sigset_t is new unsigned_long;
+
+ type pid_t is new int;
+
+ type time_t is new int;
+
+ type timespec is record
+ tv_sec : time_t;
+ tv_nsec : long;
+ end record;
+ pragma Convention (C, timespec);
+
+ type clockid_t is new int;
+ CLOCK_REALTIME : constant clockid_t := 1;
+
+ type struct_timeval is record
+ tv_sec : time_t;
+ tv_usec : time_t;
+ end record;
+ pragma Convention (C, struct_timeval);
+
+ type unsigned_long_array is array (Natural range <>) of unsigned_long;
+
+ type pthread_t is new System.Address;
+
+ type pthread_cond_t is record
+ state : unsigned;
+ valid : unsigned;
+ name : System.Address;
+ arg : unsigned;
+ reserved1 : unsigned;
+ sequence : unsigned_long;
+ block : System.Address;
+ end record;
+ pragma Convention (C, pthread_cond_t);
+
+ type pthread_attr_t is record
+ valid : long;
+ name : System.Address;
+ arg : unsigned_long;
+ reserved : unsigned_long_array (0 .. 18);
+ end record;
+ pragma Convention (C, pthread_attr_t);
+
+ type pthread_mutex_t is record
+ lock : unsigned;
+ valid : unsigned;
+ name : System.Address;
+ arg : unsigned;
+ depth : unsigned;
+ sequence : unsigned_long;
+ owner : unsigned_long;
+ block : System.Address;
+ end record;
+ for pthread_mutex_t'Size use 8 * 48;
+ pragma Convention (C, pthread_mutex_t);
+
+ type pthread_mutexattr_t is record
+ valid : long;
+ reserved : unsigned_long_array (0 .. 14);
+ end record;
+ pragma Convention (C, pthread_mutexattr_t);
+
+ type pthread_condattr_t is record
+ valid : long;
+ reserved : unsigned_long_array (0 .. 12);
+ end record;
+ pragma Convention (C, pthread_condattr_t);
+
+ type pthread_key_t is new unsigned;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-unixware.adb b/gcc/ada/s-osinte-unixware.adb
new file mode 100644
index 00000000000..9916e8846f4
--- /dev/null
+++ b/gcc/ada/s-osinte-unixware.adb
@@ -0,0 +1,182 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1999-2002 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- --
+-- 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, 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, --
+-- 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 is a UnixWare (Native) version of this package
+
+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 Interfaces.C;
+
+package body System.OS_Interface is
+
+ use Interfaces.C;
+
+ -----------------
+ -- To_Duration --
+ -----------------
+
+ function To_Duration (TS : timespec) return Duration is
+ begin
+ return Duration (TS.tv_sec) + Duration (TS.tv_nsec) / 10#1#E9;
+ end To_Duration;
+
+ function To_Duration (TV : struct_timeval) return Duration is
+ begin
+ return Duration (TV.tv_sec) + Duration (TV.tv_usec) / 10#1#E6;
+ end To_Duration;
+
+ -----------------
+ -- To_Timespec --
+ -----------------
+
+ function To_Timespec (D : Duration) return timespec is
+ S : time_t;
+ F : Duration;
+
+ begin
+ S := time_t (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return timespec'(tv_sec => S,
+ tv_nsec => long (Long_Long_Integer (F * 10#1#E9)));
+ end To_Timespec;
+
+ ----------------
+ -- To_Timeval --
+ ----------------
+
+ function To_Timeval (D : Duration) return struct_timeval is
+ S : long;
+ F : Duration;
+
+ begin
+ S := long (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return
+ struct_timeval'
+ (tv_sec => S,
+ tv_usec => long (Long_Long_Integer (F * 10#1#E6)));
+ end To_Timeval;
+
+ -------------------
+ -- clock_gettime --
+ -------------------
+
+ function clock_gettime
+ (clock_id : clockid_t;
+ tp : access timespec)
+ return int
+ is
+ pragma Warnings (Off, clock_id);
+
+ Result : int;
+ tv : aliased struct_timeval;
+
+ function gettimeofday
+ (tv : access struct_timeval;
+ tz : System.Address := System.Null_Address)
+ return int;
+ pragma Import (C, gettimeofday, "gettimeofday");
+
+ begin
+ Result := gettimeofday (tv'Unchecked_Access);
+ tp.all := To_Timespec (To_Duration (tv));
+ return Result;
+ end clock_gettime;
+
+ ---------------------------
+ -- POSIX.1c Section 3 --
+ ---------------------------
+
+ function sigwait (set : access sigset_t; sig : access Signal) return int is
+ Result : int;
+
+ function sigwait (set : access sigset_t) return int;
+ pragma Import (C, sigwait, "sigwait");
+
+ begin
+ Result := sigwait (set);
+
+ if Result < 0 then
+ sig.all := 0;
+ return errno;
+ end if;
+
+ sig.all := Signal (Result);
+ return 0;
+ end sigwait;
+
+ function pthread_kill (thread : pthread_t; sig : Signal) return int is
+ function pthread_kill_base
+ (thread : access pthread_t; sig : access Signal) return int;
+ pragma Import (C, pthread_kill_base, "pthread_kill");
+
+ thr : aliased pthread_t := thread;
+ signo : aliased Signal := sig;
+
+ begin
+ return pthread_kill_base (thr'Unchecked_Access, signo'Unchecked_Access);
+ end pthread_kill;
+
+ function Get_Stack_Base (thread : pthread_t) return Address is
+ pragma Warnings (Off, thread);
+
+ begin
+ return Null_Address;
+ end Get_Stack_Base;
+
+ procedure pthread_init is
+ begin
+ null;
+ end pthread_init;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-unixware.ads b/gcc/ada/s-osinte-unixware.ads
new file mode 100644
index 00000000000..efc55eb54d5
--- /dev/null
+++ b/gcc/ada/s-osinte-unixware.ads
@@ -0,0 +1,600 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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 is a UnixWare (Native THREADS) version of this package
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+with Interfaces.C;
+with Unchecked_Conversion;
+
+package System.OS_Interface is
+ pragma Preelaborate;
+
+ pragma Linker_Options ("-lthread");
+
+ subtype int is Interfaces.C.int;
+ subtype char is Interfaces.C.char;
+ subtype short is Interfaces.C.short;
+ subtype long is Interfaces.C.long;
+ subtype unsigned is Interfaces.C.unsigned;
+ subtype unsigned_short is Interfaces.C.unsigned_short;
+ subtype unsigned_long is Interfaces.C.unsigned_long;
+ subtype unsigned_char is Interfaces.C.unsigned_char;
+ subtype plain_char is Interfaces.C.plain_char;
+ subtype size_t is Interfaces.C.size_t;
+
+ -----------
+ -- Errno --
+ -----------
+
+ function errno return int;
+ pragma Import (C, errno, "__get_errno");
+
+ EAGAIN : constant := 11;
+ EINTR : constant := 4;
+ EINVAL : constant := 22;
+ ENOMEM : constant := 12;
+ ETIMEDOUT : constant := 145;
+
+ -------------
+ -- Signals --
+ -------------
+
+ Max_Interrupt : constant := 34;
+ type Signal is new int range 0 .. Max_Interrupt;
+ for Signal'Size use int'Size;
+
+ SIGHUP : constant := 1; -- hangup
+ SIGINT : constant := 2; -- interrupt (rubout)
+ SIGQUIT : constant := 3; -- quit (ASCD FS)
+ SIGILL : constant := 4; -- illegal instruction (not reset)
+ SIGTRAP : constant := 5; -- trace trap (not reset)
+ SIGIOT : constant := 6; -- IOT instruction
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGEMT : constant := 7; -- EMT instruction
+ SIGFPE : constant := 8; -- floating point exception
+ SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
+ SIGBUS : constant := 10; -- bus error
+ SIGSEGV : constant := 11; -- segmentation violation
+ SIGSYS : constant := 12; -- bad argument to system call
+ SIGPIPE : constant := 13; -- write on a pipe with no one to read it
+ SIGALRM : constant := 14; -- alarm clock
+ SIGTERM : constant := 15; -- software termination signal from kill
+ SIGUSR1 : constant := 16; -- user defined signal 1
+ SIGUSR2 : constant := 17; -- user defined signal 2
+ SIGCLD : constant := 18; -- alias for SIGCHLD
+ SIGCHLD : constant := 18; -- child status change
+ SIGPWR : constant := 19; -- power-fail restart
+ SIGWINCH : constant := 20; -- window size change
+ SIGURG : constant := 21; -- urgent condition on IO channel
+ SIGPOLL : constant := 22; -- pollable event occurred
+ SIGIO : constant := 22; -- I/O possible (Solaris SIGPOLL alias)
+ SIGSTOP : constant := 23; -- stop (cannot be caught or ignored)
+ SIGTSTP : constant := 24; -- user stop requested from tty
+ SIGCONT : constant := 25; -- stopped process has been continued
+ SIGTTIN : constant := 26; -- background tty read attempted
+ SIGTTOU : constant := 27; -- background tty write attempted
+ SIGVTALRM : constant := 28; -- virtual timer expired
+ SIGPROF : constant := 29; -- profiling timer expired
+ SIGXCPU : constant := 30; -- CPU time limit exceeded
+ SIGXFSZ : constant := 31; -- filesize limit exceeded
+ SIGWAITING : constant := 32; -- all LWPs blocked interruptibly notific.
+ SIGLWP : constant := 33; -- signal reserved for thread lib impl.
+ SIGAIO : constant := 34; -- Asynchronous I/O signal
+
+ SIGADAABORT : constant := SIGABRT;
+ -- Change this if you want to use another signal for task abort.
+ -- SIGTERM might be a good one.
+
+ type Signal_Set is array (Natural range <>) of Signal;
+
+ Unmasked : constant Signal_Set :=
+ (SIGTRAP, SIGLWP, SIGWAITING, SIGTTIN, SIGTTOU, SIGTSTP, SIGPROF);
+ Reserved : constant Signal_Set := (SIGABRT, SIGKILL, SIGSTOP);
+
+ type sigset_t is private;
+
+ function sigaddset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigaddset, "sigaddset");
+
+ function sigdelset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigdelset, "sigdelset");
+
+ function sigfillset (set : access sigset_t) return int;
+ pragma Import (C, sigfillset, "sigfillset");
+
+ function sigismember (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigismember, "sigismember");
+
+ function sigemptyset (set : access sigset_t) return int;
+ pragma Import (C, sigemptyset, "sigemptyset");
+
+ type struct_sigaction is record
+ sa_flags : int;
+ sa_handler : System.Address;
+ sa_mask : sigset_t;
+ sa_resv1 : int;
+ sa_resv2 : int;
+ end record;
+ pragma Convention (C, struct_sigaction);
+ type struct_sigaction_ptr is access all struct_sigaction;
+
+ SIG_BLOCK : constant := 1;
+ SIG_UNBLOCK : constant := 2;
+ SIG_SETMASK : constant := 3;
+
+ SIG_DFL : constant := 0;
+ SIG_IGN : constant := 1;
+ -- SIG_ERR : constant := -1;
+ -- not used
+
+ function sigaction
+ (sig : Signal;
+ act : struct_sigaction_ptr;
+ oact : struct_sigaction_ptr) return int;
+ pragma Import (C, sigaction, "sigaction");
+
+ ----------
+ -- Time --
+ ----------
+
+ Time_Slice_Supported : constant Boolean := False;
+ -- Indicates wether time slicing is supported
+
+ type timespec is private;
+
+ type clockid_t is private;
+
+ CLOCK_REALTIME : constant clockid_t;
+
+ function clock_gettime
+ (clock_id : clockid_t;
+ tp : access timespec) return int;
+ -- UnixWare threads don't have clock_gettime
+ -- We instead use gettimeofday()
+
+ function To_Duration (TS : timespec) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timespec (D : Duration) return timespec;
+ pragma Inline (To_Timespec);
+
+ type struct_timezone is record
+ tz_minuteswest : int;
+ tz_dsttime : int;
+ end record;
+ pragma Convention (C, struct_timezone);
+ type struct_timezone_ptr is access all struct_timezone;
+
+ type struct_timeval is private;
+ -- This is needed on systems that do not have clock_gettime()
+ -- but do have gettimeofday().
+
+ function To_Duration (TV : struct_timeval) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timeval (D : Duration) return struct_timeval;
+ pragma Inline (To_Timeval);
+
+ -------------------------
+ -- Priority Scheduling --
+ -------------------------
+
+ SCHED_FIFO : constant := 2;
+ SCHED_RR : constant := 3;
+ SCHED_OTHER : constant := 1;
+
+ -------------
+ -- Process --
+ -------------
+
+ type pid_t is private;
+
+ function kill (pid : pid_t; sig : Signal) return int;
+ pragma Import (C, kill, "kill");
+
+ function getpid return pid_t;
+ pragma Import (C, getpid, "getpid");
+
+ ---------
+ -- LWP --
+ ---------
+
+ function lwp_self return System.Address;
+ pragma Import (C, lwp_self, "_lwp_self");
+
+ -------------
+ -- Threads --
+ -------------
+
+ type Thread_Body is access
+ function (arg : System.Address) return System.Address;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ type pthread_t is private;
+ subtype Thread_Id is pthread_t;
+
+ type pthread_mutex_t is limited private;
+ type pthread_cond_t is limited private;
+ type pthread_attr_t is limited private;
+ type pthread_mutexattr_t is limited private;
+ type pthread_condattr_t is limited private;
+ type pthread_key_t is private;
+
+ PTHREAD_CREATE_DETACHED : constant := 0;
+
+ -----------
+ -- Stack --
+ -----------
+
+ Stack_Base_Available : constant Boolean := False;
+ -- Indicates wether the stack base is available on this target.
+
+ function Get_Stack_Base (thread : pthread_t) return Address;
+ pragma Inline (Get_Stack_Base);
+ -- returns the stack base of the specified thread.
+ -- Only call this function when Stack_Base_Available is True.
+
+ 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
+
+ PROT_NONE : constant := 0;
+ PROT_READ : constant := 1;
+ PROT_WRITE : constant := 2;
+ PROT_EXEC : constant := 4;
+ PROT_USER : constant := 8;
+ PROT_ALL : constant := PROT_READ + PROT_WRITE + PROT_EXEC + PROT_USER;
+
+ PROT_ON : constant := PROT_READ;
+ PROT_OFF : constant := PROT_ALL;
+
+ function mprotect (addr : Address; len : size_t; prot : int) return int;
+ pragma Import (C, mprotect);
+
+ -------------------------
+ -- POSIX.1c Section 3 --
+ -------------------------
+
+ function sigwait (set : access sigset_t; sig : access Signal) return int;
+ pragma Inline (sigwait);
+ -- UnixWare provides a non standard sigwait
+
+ function pthread_kill (thread : pthread_t; sig : Signal) return int;
+ pragma Inline (pthread_kill);
+ -- UnixWare provides a non standard pthread_kill
+
+ type sigset_t_ptr is access all sigset_t;
+
+ function pthread_sigmask
+ (how : int;
+ set : sigset_t_ptr;
+ oset : sigset_t_ptr) return int;
+ pragma Import (C, pthread_sigmask, "pthread_sigmask");
+
+ --------------------------
+ -- POSIX.1c Section 11 --
+ --------------------------
+
+ function pthread_mutexattr_init
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_init, "pthread_mutexattr_init");
+
+ function pthread_mutexattr_destroy
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_destroy, "pthread_mutexattr_destroy");
+
+ function pthread_mutex_init
+ (mutex : access pthread_mutex_t;
+ attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutex_init, "pthread_mutex_init");
+
+ function pthread_mutex_destroy (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_destroy, "pthread_mutex_destroy");
+
+ function pthread_mutex_lock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_lock, "pthread_mutex_lock");
+
+ function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_unlock, "pthread_mutex_unlock");
+
+ function pthread_condattr_init
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_init, "pthread_condattr_init");
+
+ function pthread_condattr_destroy
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_destroy, "pthread_condattr_destroy");
+
+ function pthread_cond_init
+ (cond : access pthread_cond_t;
+ attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_cond_init, "pthread_cond_init");
+
+ function pthread_cond_destroy (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_destroy, "pthread_cond_destroy");
+
+ function pthread_cond_signal (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_signal, "pthread_cond_signal");
+
+ function pthread_cond_wait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_cond_wait, "pthread_cond_wait");
+
+ function pthread_cond_timedwait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t;
+ abstime : access timespec) return int;
+ pragma Import (C, pthread_cond_timedwait, "pthread_cond_timedwait");
+
+ Relative_Timed_Wait : constant Boolean := False;
+ -- pthread_cond_timedwait requires an absolute delay time
+
+ --------------------------
+ -- POSIX.1c Section 13 --
+ --------------------------
+
+ PTHREAD_PRIO_NONE : constant := 1;
+ PTHREAD_PRIO_INHERIT : constant := 2;
+ PTHREAD_PRIO_PROTECT : constant := 3;
+
+ function pthread_mutexattr_setprotocol
+ (attr : access pthread_mutexattr_t;
+ protocol : int) return int;
+ pragma Import (C, pthread_mutexattr_setprotocol);
+
+ function pthread_mutexattr_setprioceiling
+ (attr : access pthread_mutexattr_t;
+ prioceiling : int) return int;
+ pragma Import (C, pthread_mutexattr_setprioceiling);
+
+ type sched_union is record
+ sched_fifo : int;
+ sched_fcfs : int;
+ sched_other : int;
+ sched_ts : int;
+ policy_params : long;
+ end record;
+
+ type struct_sched_param is record
+ sched_priority : int;
+ sched_other_stuff : sched_union;
+ end record;
+
+ function pthread_setschedparam
+ (thread : pthread_t;
+ policy : int;
+ param : access struct_sched_param) return int;
+ pragma Import (C, pthread_setschedparam, "pthread_setschedparam");
+
+ function pthread_attr_setscope
+ (attr : access pthread_attr_t;
+ contentionscope : int) return int;
+ pragma Import (C, pthread_attr_setscope, "pthread_attr_setscope");
+
+ function pthread_attr_setinheritsched
+ (attr : access pthread_attr_t;
+ inheritsched : int) return int;
+ pragma Import (C, pthread_attr_setinheritsched);
+
+ function pthread_attr_setschedpolicy
+ (attr : access pthread_attr_t;
+ policy : int) return int;
+ pragma Import (C, pthread_attr_setschedpolicy);
+
+ function sched_yield return int;
+ pragma Import (C, sched_yield, "sched_yield");
+
+ ---------------------------
+ -- P1003.1c - Section 16 --
+ ---------------------------
+
+ function pthread_attr_init (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_init, "pthread_attr_init");
+
+ function pthread_attr_destroy
+ (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_destroy, "pthread_attr_destroy");
+
+ function pthread_attr_setdetachstate
+ (attr : access pthread_attr_t;
+ detachstate : int) return int;
+ pragma Import (C, pthread_attr_setdetachstate);
+
+ function pthread_attr_setstacksize
+ (attr : access pthread_attr_t;
+ stacksize : size_t) return int;
+ pragma Import (C, pthread_attr_setstacksize);
+
+ function pthread_create
+ (thread : access pthread_t;
+ attributes : access pthread_attr_t;
+ start_routine : Thread_Body;
+ arg : System.Address) return int;
+ pragma Import (C, pthread_create, "pthread_create");
+
+ procedure pthread_exit (status : System.Address);
+ pragma Import (C, pthread_exit, "pthread_exit");
+
+ function pthread_self return pthread_t;
+ pragma Import (C, pthread_self, "pthread_self");
+
+ --------------------------
+ -- POSIX.1c Section 17 --
+ --------------------------
+
+ function pthread_setspecific
+ (key : pthread_key_t;
+ value : System.Address) return int;
+ pragma Import (C, pthread_setspecific, "pthread_setspecific");
+
+ function pthread_getspecific (key : pthread_key_t) return System.Address;
+ pragma Import (C, pthread_getspecific, "pthread_getspecific");
+
+ type destructor_pointer is access procedure (arg : System.Address);
+
+ function pthread_key_create
+ (key : access pthread_key_t;
+ destructor : destructor_pointer) return int;
+ pragma Import (C, pthread_key_create, "pthread_key_create");
+
+ procedure pthread_init;
+ -- This is a dummy procedure to share some GNULLI files
+
+private
+
+ type sigbit_array is array (1 .. 4) of unsigned;
+ type sigset_t is record
+ sa_sigbits : sigbit_array;
+ end record;
+ pragma Convention (C_Pass_By_Copy, sigset_t);
+
+ type pid_t is new unsigned;
+
+ type time_t is new long;
+
+ type timespec is record
+ tv_sec : time_t;
+ tv_nsec : long;
+ end record;
+ pragma Convention (C, timespec);
+
+ type clockid_t is new int;
+ CLOCK_REALTIME : constant clockid_t := 0;
+
+ type struct_timeval is record
+ tv_sec : long;
+ tv_usec : long;
+ end record;
+ pragma Convention (C, struct_timeval);
+
+ type pthread_attr_t is record
+ pt_attr_status : int;
+ pt_attr_stacksize : size_t;
+ pt_attr_stackaddr : System.Address;
+ pt_attr_detachstate : int;
+ pt_attr_contentionscope : int;
+ pt_attr_inheritsched : int;
+ pt_attr_schedpolicy : int;
+ pt_attr_sched_param : struct_sched_param;
+ pt_attr_tlflags : int;
+ end record;
+ pragma Convention (C, pthread_attr_t);
+
+ type pthread_condattr_t is record
+ pt_condattr_status : int;
+ pt_condattr_pshared : int;
+ end record;
+ pragma Convention (C, pthread_condattr_t);
+
+ type pthread_mutexattr_t is record
+ pt_mutexattr_status : int;
+ pt_mutexattr_pshared : int;
+ pt_mutexattr_type : int;
+ end record;
+ pragma Convention (C, pthread_mutexattr_t);
+
+ type thread_t is new long;
+ type pthread_t is new thread_t;
+
+ type thrq_elt_t;
+ type thrq_elt_t_ptr is access all thrq_elt_t;
+
+ type thrq_elt_t is record
+ thrq_next : thrq_elt_t_ptr;
+ thrq_prev : thrq_elt_t_ptr;
+ end record;
+ pragma Convention (C, thrq_elt_t);
+
+ type lwp_mutex_t is record
+ wanted : char;
+ lock : unsigned_char;
+ end record;
+ pragma Convention (C, lwp_mutex_t);
+ pragma Volatile (lwp_mutex_t);
+
+ type mutex_t is record
+ m_lmutex : lwp_mutex_t;
+ m_sync_lock : lwp_mutex_t;
+ m_type : int;
+ m_sleepq : thrq_elt_t;
+ filler1 : int;
+ filler2 : int;
+ end record;
+ pragma Convention (C, mutex_t);
+ pragma Volatile (mutex_t);
+
+ type pthread_mutex_t is record
+ pt_mutex_mutex : mutex_t;
+ pt_mutex_pid : pid_t;
+ pt_mutex_owner : thread_t;
+ pt_mutex_depth : int;
+ pt_mutex_attr : pthread_mutexattr_t;
+ end record;
+ pragma Convention (C, pthread_mutex_t);
+
+ type lwp_cond_t is record
+ wanted : char;
+ end record;
+ pragma Convention (C, lwp_cond_t);
+ pragma Volatile (lwp_cond_t);
+
+ type cond_t is record
+ c_lcond : lwp_cond_t;
+ c_sync_lock : lwp_mutex_t;
+ c_type : int;
+ c_syncq : thrq_elt_t;
+ end record;
+ pragma Convention (C, cond_t);
+ pragma Volatile (cond_t);
+
+ type pthread_cond_t is record
+ pt_cond_cond : cond_t;
+ pt_cond_attr : pthread_condattr_t;
+ end record;
+ pragma Convention (C, pthread_cond_t);
+
+ type pthread_key_t is new unsigned;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-vms.adb b/gcc/ada/s-osinte-vms.adb
new file mode 100644
index 00000000000..0b806daa809
--- /dev/null
+++ b/gcc/ada/s-osinte-vms.adb
@@ -0,0 +1,78 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2003, Ada Core Technologies --
+-- --
+-- 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, 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, --
+-- 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 is a OpenVMS/Alpha version of this package.
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+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 Interfaces.C; use Interfaces.C;
+with System.Machine_Code; use System.Machine_Code;
+
+package body System.OS_Interface is
+
+ ------------------
+ -- pthread_self --
+ ------------------
+
+ function pthread_self return pthread_t is
+ use ASCII;
+ Self : pthread_t;
+
+ begin
+ Asm ("call_pal 0x9e" & LF & HT &
+ "bis $31, $0, %0",
+ Outputs => pthread_t'Asm_Output ("=r", Self),
+ Clobber => "$0");
+ return Self;
+ end pthread_self;
+
+ -----------------
+ -- sched_yield --
+ -----------------
+
+ function sched_yield return int is
+ procedure sched_yield_base;
+ pragma Import (C, sched_yield_base, "PTHREAD_YIELD_NP");
+
+ begin
+ sched_yield_base;
+ return 0;
+ end sched_yield;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-vms.ads b/gcc/ada/s-osinte-vms.ads
new file mode 100644
index 00000000000..333e02a37b8
--- /dev/null
+++ b/gcc/ada/s-osinte-vms.ads
@@ -0,0 +1,646 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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 is a OpenVMS/Alpha version of this package
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+with Interfaces.C;
+with Unchecked_Conversion;
+
+package System.OS_Interface is
+ pragma Preelaborate;
+
+ pragma Linker_Options ("--for-linker=sys$library:pthread$rtl.exe");
+ -- Link in the DEC threads library.
+
+ -- pragma Linker_Options ("--for-linker=/threads_enable");
+ -- Enable upcalls and multiple kernel threads.
+
+ subtype int is Interfaces.C.int;
+ subtype short is Interfaces.C.short;
+ subtype long is Interfaces.C.long;
+ subtype unsigned is Interfaces.C.unsigned;
+ subtype unsigned_short is Interfaces.C.unsigned_short;
+ subtype unsigned_long is Interfaces.C.unsigned_long;
+ subtype unsigned_char is Interfaces.C.unsigned_char;
+ subtype plain_char is Interfaces.C.plain_char;
+ subtype size_t is Interfaces.C.size_t;
+
+ -----------------------------
+ -- Signals (Interrupt IDs) --
+ -----------------------------
+
+ -- Type signal has an arbitrary limit of 31
+
+ Max_Interrupt : constant := 31;
+ type Signal is new unsigned range 0 .. Max_Interrupt;
+ for Signal'Size use unsigned'Size;
+
+ type sigset_t is array (Signal) of Boolean;
+ pragma Pack (sigset_t);
+
+ -- Interrupt_Number_Type
+ -- Unsigned long integer denoting the number of an interrupt
+
+ subtype Interrupt_Number_Type is unsigned_long;
+
+ -- OpenVMS system services return values of type Cond_Value_Type.
+
+ subtype Cond_Value_Type is unsigned_long;
+ subtype Short_Cond_Value_Type is unsigned_short;
+
+ type IO_Status_Block_Type is record
+ Status : Short_Cond_Value_Type;
+ Count : unsigned_short;
+ Dev_Info : unsigned_long;
+ end record;
+
+ type AST_Handler is access procedure (Param : Address);
+ No_AST_Handler : constant AST_Handler := null;
+
+ CMB_M_READONLY : constant := 16#00000001#;
+ CMB_M_WRITEONLY : constant := 16#00000002#;
+ AGN_M_READONLY : constant := 16#00000001#;
+ AGN_M_WRITEONLY : constant := 16#00000002#;
+
+ IO_WRITEVBLK : constant := 48; -- WRITE VIRTUAL BLOCK
+ IO_READVBLK : constant := 49; -- READ VIRTUAL BLOCK
+
+ ----------------
+ -- Sys_Assign --
+ ----------------
+ --
+ -- Assign I/O Channel
+ --
+ -- Status = returned status
+ -- Devnam = address of device name or logical name string
+ -- descriptor
+ -- Chan = address of word to receive channel number assigned
+ -- Acmode = access mode associated with channel
+ -- Mbxnam = address of mailbox logical name string descriptor, if
+ -- mailbox associated with device
+ -- Flags = optional channel flags longword for specifying options
+ -- for the $ASSIGN operation
+ --
+
+ procedure Sys_Assign
+ (Status : out Cond_Value_Type;
+ Devnam : in String;
+ Chan : out unsigned_short;
+ Acmode : in unsigned_short := 0;
+ Mbxnam : in String := String'Null_Parameter;
+ Flags : in unsigned_long := 0);
+ pragma Interface (External, Sys_Assign);
+ pragma Import_Valued_Procedure
+ (Sys_Assign, "SYS$ASSIGN",
+ (Cond_Value_Type, String, unsigned_short,
+ unsigned_short, String, unsigned_long),
+ (Value, Descriptor (s), Reference,
+ Value, Descriptor (s), Value),
+ Flags);
+
+ ----------------
+ -- Sys_Cantim --
+ ----------------
+ --
+ -- Cancel Timer
+ --
+ -- Status = returned status
+ -- Reqidt = ID of timer to be cancelled
+ -- Acmode = Access mode
+ --
+ procedure Sys_Cantim
+ (Status : out Cond_Value_Type;
+ Reqidt : in Address;
+ Acmode : in unsigned);
+ pragma Interface (External, Sys_Cantim);
+ pragma Import_Valued_Procedure
+ (Sys_Cantim, "SYS$CANTIM",
+ (Cond_Value_Type, Address, unsigned),
+ (Value, Value, Value));
+
+ ----------------
+ -- Sys_Crembx --
+ ----------------
+ --
+ -- Create mailbox
+ --
+ -- Status = returned status
+ -- Prmflg = permanent flag
+ -- Chan = channel
+ -- Maxmsg = maximum message
+ -- Bufquo = buufer quote
+ -- Promsk = protection mast
+ -- Acmode = access mode
+ -- Lognam = logical name
+ -- Flags = flags
+ --
+ procedure Sys_Crembx
+ (Status : out Cond_Value_Type;
+ Prmflg : in Boolean;
+ Chan : out unsigned_short;
+ Maxmsg : in unsigned_long := 0;
+ Bufquo : in unsigned_long := 0;
+ Promsk : in unsigned_short := 0;
+ Acmode : in unsigned_short := 0;
+ Lognam : in String;
+ Flags : in unsigned_long := 0);
+ pragma Interface (External, Sys_Crembx);
+ pragma Import_Valued_Procedure
+ (Sys_Crembx, "SYS$CREMBX",
+ (Cond_Value_Type, Boolean, unsigned_short,
+ unsigned_long, unsigned_long, unsigned_short,
+ unsigned_short, String, unsigned_long),
+ (Value, Value, Reference,
+ Value, Value, Value,
+ Value, Descriptor (s), Value));
+
+ -------------
+ -- Sys_QIO --
+ -------------
+ --
+ -- Queue I/O
+ --
+ -- Status = Returned status of call
+ -- EFN = event flag to be set when I/O completes
+ -- Chan = channel
+ -- Func = function
+ -- Iosb = I/O status block
+ -- Astadr = system trap to be generated when I/O completes
+ -- Astprm = AST parameter
+ -- P1-6 = optional parameters
+
+ procedure Sys_QIO
+ (Status : out Cond_Value_Type;
+ EFN : in unsigned_long := 0;
+ Chan : in unsigned_short;
+ Func : in unsigned_long := 0;
+ Iosb : out IO_Status_Block_Type;
+ Astadr : in AST_Handler := No_AST_Handler;
+ Astprm : in Address := Null_Address;
+ P1 : in unsigned_long := 0;
+ P2 : in unsigned_long := 0;
+ P3 : in unsigned_long := 0;
+ P4 : in unsigned_long := 0;
+ P5 : in unsigned_long := 0;
+ P6 : in unsigned_long := 0);
+
+ procedure Sys_QIO
+ (Status : out Cond_Value_Type;
+ EFN : in unsigned_long := 0;
+ Chan : in unsigned_short;
+ Func : in unsigned_long := 0;
+ Iosb : in Address := Null_Address;
+ Astadr : in AST_Handler := No_AST_Handler;
+ Astprm : in Address := Null_Address;
+ P1 : in unsigned_long := 0;
+ P2 : in unsigned_long := 0;
+ P3 : in unsigned_long := 0;
+ P4 : in unsigned_long := 0;
+ P5 : in unsigned_long := 0;
+ P6 : in unsigned_long := 0);
+
+ pragma Interface (External, Sys_QIO);
+ pragma Import_Valued_Procedure
+ (Sys_QIO, "SYS$QIO",
+ (Cond_Value_Type, unsigned_long, unsigned_short, unsigned_long,
+ IO_Status_Block_Type, AST_Handler, Address,
+ unsigned_long, unsigned_long, unsigned_long,
+ unsigned_long, unsigned_long, unsigned_long),
+ (Value, Value, Value, Value,
+ Reference, Value, Value,
+ Value, Value, Value,
+ Value, Value, Value));
+
+ pragma Import_Valued_Procedure
+ (Sys_QIO, "SYS$QIO",
+ (Cond_Value_Type, unsigned_long, unsigned_short, unsigned_long,
+ Address, AST_Handler, Address,
+ unsigned_long, unsigned_long, unsigned_long,
+ unsigned_long, unsigned_long, unsigned_long),
+ (Value, Value, Value, Value,
+ Value, Value, Value,
+ Value, Value, Value,
+ Value, Value, Value));
+
+ ----------------
+ -- Sys_Setimr --
+ ----------------
+ --
+ -- Set Timer
+ --
+ -- Status = Returned status of call
+ -- EFN = event flag to be set when timer expires
+ -- Tim = expiration time
+ -- AST = system trap to be generated when timer expires
+ -- Redidt = returned ID of timer (e.g. to cancel timer)
+ -- Flags = flags
+ --
+ procedure Sys_Setimr
+ (Status : out Cond_Value_Type;
+ EFN : in unsigned_long;
+ Tim : in Long_Integer;
+ AST : in AST_Handler;
+ Reqidt : in Address;
+ Flags : in unsigned_long);
+ pragma Interface (External, Sys_Setimr);
+ pragma Import_Valued_Procedure
+ (Sys_Setimr, "SYS$SETIMR",
+ (Cond_Value_Type, unsigned_long, Long_Integer,
+ AST_Handler, Address, unsigned_long),
+ (Value, Value, Reference,
+ Value, Value, Value));
+
+ Interrupt_ID_0 : constant := 0;
+ Interrupt_ID_1 : constant := 1;
+ Interrupt_ID_2 : constant := 2;
+ Interrupt_ID_3 : constant := 3;
+ Interrupt_ID_4 : constant := 4;
+ Interrupt_ID_5 : constant := 5;
+ Interrupt_ID_6 : constant := 6;
+ Interrupt_ID_7 : constant := 7;
+ Interrupt_ID_8 : constant := 8;
+ Interrupt_ID_9 : constant := 9;
+ Interrupt_ID_10 : constant := 10;
+ Interrupt_ID_11 : constant := 11;
+ Interrupt_ID_12 : constant := 12;
+ Interrupt_ID_13 : constant := 13;
+ Interrupt_ID_14 : constant := 14;
+ Interrupt_ID_15 : constant := 15;
+ Interrupt_ID_16 : constant := 16;
+ Interrupt_ID_17 : constant := 17;
+ Interrupt_ID_18 : constant := 18;
+ Interrupt_ID_19 : constant := 19;
+ Interrupt_ID_20 : constant := 20;
+ Interrupt_ID_21 : constant := 21;
+ Interrupt_ID_22 : constant := 22;
+ Interrupt_ID_23 : constant := 23;
+ Interrupt_ID_24 : constant := 24;
+ Interrupt_ID_25 : constant := 25;
+ Interrupt_ID_26 : constant := 26;
+ Interrupt_ID_27 : constant := 27;
+ Interrupt_ID_28 : constant := 28;
+ Interrupt_ID_29 : constant := 29;
+ Interrupt_ID_30 : constant := 30;
+ Interrupt_ID_31 : constant := 31;
+
+ -----------
+ -- Errno --
+ -----------
+
+ function errno return int;
+ pragma Import (C, errno, "__get_errno");
+
+ EINTR : constant := 4; -- Interrupted system call
+ EAGAIN : constant := 11; -- No more processes
+ ENOMEM : constant := 12; -- Not enough core
+
+ -------------------------
+ -- Priority Scheduling --
+ -------------------------
+
+ SCHED_FIFO : constant := 1;
+ SCHED_RR : constant := 2;
+ SCHED_OTHER : constant := 3;
+ SCHED_BG : constant := 4;
+ SCHED_LFI : constant := 5;
+ SCHED_LRR : constant := 6;
+
+ -------------
+ -- Process --
+ -------------
+
+ type pid_t is private;
+
+ function kill (pid : pid_t; sig : Signal) return int;
+ pragma Import (C, kill);
+
+ function getpid return pid_t;
+ pragma Import (C, getpid);
+
+ -------------
+ -- Threads --
+ -------------
+
+ type Thread_Body is access
+ function (arg : System.Address) return System.Address;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ type pthread_t is private;
+ subtype Thread_Id is pthread_t;
+
+ type pthread_mutex_t is limited private;
+ type pthread_cond_t is limited private;
+ type pthread_attr_t is limited private;
+ type pthread_mutexattr_t is limited private;
+ type pthread_condattr_t is limited private;
+ type pthread_key_t is private;
+
+ PTHREAD_CREATE_JOINABLE : constant := 0;
+ PTHREAD_CREATE_DETACHED : constant := 1;
+
+ PTHREAD_CANCEL_DISABLE : constant := 0;
+ PTHREAD_CANCEL_ENABLE : constant := 1;
+
+ PTHREAD_CANCEL_DEFERRED : constant := 0;
+ PTHREAD_CANCEL_ASYNCHRONOUS : constant := 1;
+
+ -- Don't use ERRORCHECK mutexes, they don't work when a thread is not
+ -- the owner. AST's, at least, unlock others threads mutexes. Even
+ -- if the error is ignored, they don't work.
+ PTHREAD_MUTEX_NORMAL_NP : constant := 0;
+ PTHREAD_MUTEX_RECURSIVE_NP : constant := 1;
+ PTHREAD_MUTEX_ERRORCHECK_NP : constant := 2;
+
+ PTHREAD_INHERIT_SCHED : constant := 0;
+ PTHREAD_EXPLICIT_SCHED : constant := 1;
+
+ function pthread_cancel (thread : pthread_t) return int;
+ pragma Import (C, pthread_cancel, "PTHREAD_CANCEL");
+
+ procedure pthread_testcancel;
+ pragma Import (C, pthread_testcancel, "PTHREAD_TESTCANCEL");
+
+ function pthread_setcancelstate
+ (newstate : int; oldstate : access int) return int;
+ pragma Import (C, pthread_setcancelstate, "PTHREAD_SETCANCELSTATE");
+
+ function pthread_setcanceltype
+ (newtype : int; oldtype : access int) return int;
+ pragma Import (C, pthread_setcanceltype, "PTHREAD_SETCANCELTYPE");
+
+ ---------------------------
+ -- POSIX.1c Section 3 --
+ ---------------------------
+
+ function pthread_lock_global_np return int;
+ pragma Import (C, pthread_lock_global_np, "PTHREAD_LOCK_GLOBAL_NP");
+
+ function pthread_unlock_global_np return int;
+ pragma Import (C, pthread_unlock_global_np, "PTHREAD_UNLOCK_GLOBAL_NP");
+
+ ----------------------------
+ -- POSIX.1c Section 11 --
+ ----------------------------
+
+ function pthread_mutexattr_init
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_init, "PTHREAD_MUTEXATTR_INIT");
+
+ function pthread_mutexattr_destroy
+ (attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutexattr_destroy, "PTHREAD_MUTEXATTR_DESTROY");
+
+ function pthread_mutexattr_settype_np
+ (attr : access pthread_mutexattr_t;
+ mutextype : int) return int;
+ pragma Import (C, pthread_mutexattr_settype_np,
+ "PTHREAD_MUTEXATTR_SETTYPE_NP");
+
+ function pthread_mutex_init
+ (mutex : access pthread_mutex_t;
+ attr : access pthread_mutexattr_t) return int;
+ pragma Import (C, pthread_mutex_init, "PTHREAD_MUTEX_INIT");
+
+ function pthread_mutex_destroy (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_destroy, "PTHREAD_MUTEX_DESTROY");
+
+ function pthread_mutex_lock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_lock, "PTHREAD_MUTEX_LOCK");
+
+ function pthread_mutex_unlock (mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_mutex_unlock, "PTHREAD_MUTEX_UNLOCK");
+
+ function pthread_condattr_init
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_init, "PTHREAD_CONDATTR_INIT");
+
+ function pthread_condattr_destroy
+ (attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_condattr_destroy, "PTHREAD_CONDATTR_DESTROY");
+
+ function pthread_cond_init
+ (cond : access pthread_cond_t;
+ attr : access pthread_condattr_t) return int;
+ pragma Import (C, pthread_cond_init, "PTHREAD_COND_INIT");
+
+ function pthread_cond_destroy (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_destroy, "PTHREAD_COND_DESTROY");
+
+ function pthread_cond_signal (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_signal, "PTHREAD_COND_SIGNAL");
+
+ function pthread_cond_signal_int_np
+ (cond : access pthread_cond_t) return int;
+ pragma Import (C, pthread_cond_signal_int_np,
+ "PTHREAD_COND_SIGNAL_INT_NP");
+
+ function pthread_cond_wait
+ (cond : access pthread_cond_t;
+ mutex : access pthread_mutex_t) return int;
+ pragma Import (C, pthread_cond_wait, "PTHREAD_COND_WAIT");
+
+ --------------------------
+ -- POSIX.1c Section 13 --
+ --------------------------
+
+ function pthread_mutexattr_setprotocol
+ (attr : access pthread_mutexattr_t; protocol : int) return int;
+ pragma Import (C, pthread_mutexattr_setprotocol,
+ "PTHREAD_MUTEXATTR_SETPROTOCOL");
+
+ type struct_sched_param is record
+ sched_priority : int; -- scheduling priority
+ end record;
+ for struct_sched_param'Size use 8*4;
+ pragma Convention (C, struct_sched_param);
+
+ function pthread_setschedparam
+ (thread : pthread_t;
+ policy : int;
+ param : access struct_sched_param) return int;
+ pragma Import (C, pthread_setschedparam, "PTHREAD_SETSCHEDPARAM");
+
+ function pthread_attr_setscope
+ (attr : access pthread_attr_t;
+ contentionscope : int) return int;
+ pragma Import (C, pthread_attr_setscope, "PTHREAD_ATTR_SETSCOPE");
+
+ function pthread_attr_setinheritsched
+ (attr : access pthread_attr_t;
+ inheritsched : int) return int;
+ pragma Import (C, pthread_attr_setinheritsched,
+ "PTHREAD_ATTR_SETINHERITSCHED");
+
+ function pthread_attr_setschedpolicy
+ (attr : access pthread_attr_t; policy : int) return int;
+ pragma Import (C, pthread_attr_setschedpolicy,
+ "PTHREAD_ATTR_SETSCHEDPOLICY");
+
+ function pthread_attr_setschedparam
+ (attr : access pthread_attr_t;
+ sched_param : int) return int;
+ pragma Import (C, pthread_attr_setschedparam, "PTHREAD_ATTR_SETSCHEDPARAM");
+
+ function sched_yield return int;
+
+ -----------------------------
+ -- P1003.1c - Section 16 --
+ -----------------------------
+
+ function pthread_attr_init (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_init, "PTHREAD_ATTR_INIT");
+
+ function pthread_attr_destroy
+ (attributes : access pthread_attr_t) return int;
+ pragma Import (C, pthread_attr_destroy, "PTHREAD_ATTR_DESTROY");
+
+ function pthread_attr_setdetachstate
+ (attr : access pthread_attr_t;
+ detachstate : int) return int;
+ pragma Import (C, pthread_attr_setdetachstate,
+ "PTHREAD_ATTR_SETDETACHSTATE");
+
+ function pthread_attr_setstacksize
+ (attr : access pthread_attr_t;
+ stacksize : size_t) return int;
+ pragma Import (C, pthread_attr_setstacksize, "PTHREAD_ATTR_SETSTACKSIZE");
+
+ function pthread_create
+ (thread : access pthread_t;
+ attributes : access pthread_attr_t;
+ start_routine : Thread_Body;
+ arg : System.Address) return int;
+ pragma Import (C, pthread_create, "PTHREAD_CREATE");
+
+ procedure pthread_exit (status : System.Address);
+ pragma Import (C, pthread_exit, "PTHREAD_EXIT");
+
+ function pthread_self return pthread_t;
+
+ --------------------------
+ -- POSIX.1c Section 17 --
+ --------------------------
+
+ function pthread_setspecific
+ (key : pthread_key_t;
+ value : System.Address) return int;
+ pragma Import (C, pthread_setspecific, "PTHREAD_SETSPECIFIC");
+
+ function pthread_getspecific (key : pthread_key_t) return System.Address;
+ pragma Import (C, pthread_getspecific, "PTHREAD_GETSPECIFIC");
+
+ type destructor_pointer is access procedure (arg : System.Address);
+
+ function pthread_key_create
+ (key : access pthread_key_t;
+ destructor : destructor_pointer) return int;
+ pragma Import (C, pthread_key_create, "PTHREAD_KEY_CREATE");
+
+private
+
+ type pid_t is new int;
+
+ type pthreadLongAddr_p is mod 2 ** Long_Integer'Size;
+
+ type pthreadLongAddr_t is mod 2 ** Long_Integer'Size;
+ type pthreadLongAddr_t_ptr is mod 2 ** Long_Integer'Size;
+
+ type pthreadLongString_t is mod 2 ** Long_Integer'Size;
+
+ type pthreadLongUint_t is mod 2 ** Long_Integer'Size;
+ type pthreadLongUint_array is array (Natural range <>)
+ of pthreadLongUint_t;
+
+ type pthread_t is mod 2 ** Long_Integer'Size;
+
+ type pthread_cond_t is record
+ state : unsigned;
+ valid : unsigned;
+ name : pthreadLongString_t;
+ arg : unsigned;
+ sequence : unsigned;
+ block : pthreadLongAddr_t_ptr;
+ end record;
+ for pthread_cond_t'Size use 8*32;
+ pragma Convention (C, pthread_cond_t);
+
+ type pthread_attr_t is record
+ valid : long;
+ name : pthreadLongString_t;
+ arg : pthreadLongUint_t;
+ reserved : pthreadLongUint_array (0 .. 18);
+ end record;
+ for pthread_attr_t'Size use 8*176;
+ pragma Convention (C, pthread_attr_t);
+
+ type pthread_mutex_t is record
+ lock : unsigned;
+ valid : unsigned;
+ name : pthreadLongString_t;
+ arg : unsigned;
+ sequence : unsigned;
+ block : pthreadLongAddr_p;
+ owner : unsigned;
+ depth : unsigned;
+ end record;
+ for pthread_mutex_t'Size use 8*40;
+ pragma Convention (C, pthread_mutex_t);
+
+ type pthread_mutexattr_t is record
+ valid : long;
+ reserved : pthreadLongUint_array (0 .. 14);
+ end record;
+ for pthread_mutexattr_t'Size use 8*128;
+ pragma Convention (C, pthread_mutexattr_t);
+
+ type pthread_condattr_t is record
+ valid : long;
+ reserved : pthreadLongUint_array (0 .. 12);
+ end record;
+ for pthread_condattr_t'Size use 8*112;
+ pragma Convention (C, pthread_condattr_t);
+
+ type pthread_key_t is new unsigned;
+
+ pragma Inline (pthread_self);
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-vxworks.adb b/gcc/ada/s-osinte-vxworks.adb
new file mode 100644
index 00000000000..7c665e7d2a4
--- /dev/null
+++ b/gcc/ada/s-osinte-vxworks.adb
@@ -0,0 +1,164 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1997-2002 Free Software Foundation --
+-- --
+-- 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, 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, --
+-- 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 is the VxWorks version.
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+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.
+
+package body System.OS_Interface is
+
+ use type Interfaces.C.int;
+
+ Low_Priority : constant := 255;
+ -- VxWorks native (default) lowest scheduling priority.
+
+ -------------
+ -- sigwait --
+ -------------
+
+ function sigwait
+ (set : access sigset_t;
+ sig : access Signal) return int
+ is
+ Result : int;
+
+ function sigwaitinfo
+ (set : access sigset_t; sigvalue : System.Address) return int;
+ pragma Import (C, sigwaitinfo, "sigwaitinfo");
+
+ begin
+ Result := sigwaitinfo (set, System.Null_Address);
+
+ if Result /= -1 then
+ sig.all := Signal (Result);
+ return 0;
+ else
+ sig.all := 0;
+ return errno;
+ end if;
+ end sigwait;
+
+ -----------------
+ -- To_Duration --
+ -----------------
+
+ function To_Duration (TS : timespec) return Duration is
+ begin
+ return Duration (TS.ts_sec) + Duration (TS.ts_nsec) / 10#1#E9;
+ end To_Duration;
+
+ -----------------
+ -- To_Timespec --
+ -----------------
+
+ function To_Timespec (D : Duration) return timespec is
+ S : time_t;
+ F : Duration;
+ begin
+ S := time_t (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return timespec'(ts_sec => S,
+ ts_nsec => long (Long_Long_Integer (F * 10#1#E9)));
+ end To_Timespec;
+
+ -------------------------
+ -- To_VxWorks_Priority --
+ -------------------------
+
+ function To_VxWorks_Priority (Priority : in int) return int is
+ begin
+ return Low_Priority - Priority;
+ end To_VxWorks_Priority;
+
+ --------------------
+ -- To_Clock_Ticks --
+ --------------------
+
+ -- ??? - For now, we'll always get the system clock rate
+ -- since it is allowed to be changed during run-time in
+ -- VxWorks. A better method would be to provide an operation
+ -- to set it that so we can always know its value.
+ --
+ -- Another thing we should probably allow for is a resultant
+ -- tick count greater than int'Last. This should probably
+ -- be a procedure with two output parameters, one in the
+ -- range 0 .. int'Last, and another representing the overflow
+ -- count.
+
+ function To_Clock_Ticks (D : Duration) return int is
+ Ticks : Long_Long_Integer;
+ Rate_Duration : Duration;
+ Ticks_Duration : Duration;
+
+ begin
+ if D < 0.0 then
+ return -1;
+ end if;
+
+ -- Ensure that the duration can be converted to ticks
+ -- at the current clock tick rate without overflowing.
+
+ Rate_Duration := Duration (sysClkRateGet);
+
+ if D > (Duration'Last / Rate_Duration) then
+ Ticks := Long_Long_Integer (int'Last);
+ else
+ Ticks_Duration := D * Rate_Duration;
+ Ticks := Long_Long_Integer (Ticks_Duration);
+
+ if Ticks_Duration > Duration (Ticks) then
+ Ticks := Ticks + 1;
+ end if;
+
+ if Ticks > Long_Long_Integer (int'Last) then
+ Ticks := Long_Long_Integer (int'Last);
+ end if;
+ end if;
+
+ return int (Ticks);
+ end To_Clock_Ticks;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osinte-vxworks.ads b/gcc/ada/s-osinte-vxworks.ads
new file mode 100644
index 00000000000..7888cc18e68
--- /dev/null
+++ b/gcc/ada/s-osinte-vxworks.ads
@@ -0,0 +1,371 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2004, 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- --
+-- 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, 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, --
+-- 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 is the VxWorks version of this package
+
+-- This package encapsulates all direct interfaces to OS services
+-- that are needed by children of System.
+
+-- PLEASE DO NOT add any with-clauses to this package or remove the pragma
+-- Preelaborate. This package is designed to be a bottom-level (leaf) package.
+
+with Interfaces.C;
+with System.VxWorks;
+
+package System.OS_Interface is
+ pragma Preelaborate;
+
+ subtype int is Interfaces.C.int;
+ subtype short is Short_Integer;
+ type long is new Long_Integer;
+ type unsigned_long is mod 2 ** long'Size;
+ type size_t is mod 2 ** Standard'Address_Size;
+
+ -----------
+ -- Errno --
+ -----------
+
+ function errno return int;
+ pragma Import (C, errno, "errnoGet");
+
+ EINTR : constant := 4;
+ EAGAIN : constant := 35;
+ ENOMEM : constant := 12;
+ EINVAL : constant := 22;
+ ETIMEDOUT : constant := 60;
+
+ FUNC_ERR : constant := -1;
+
+ ----------------------------
+ -- Signals and Interrupts --
+ ----------------------------
+
+ NSIG : constant := 32;
+ -- Number of signals on the target OS
+ type Signal is new int range 0 .. Interfaces.C."-" (NSIG, 1);
+
+ Max_HW_Interrupt : constant := System.VxWorks.Num_HW_Interrupts - 1;
+ type HW_Interrupt is new int range 0 .. Max_HW_Interrupt;
+
+ Max_Interrupt : constant := Max_HW_Interrupt;
+
+ SIGILL : constant := 4; -- illegal instruction (not reset)
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGFPE : constant := 8; -- floating point exception
+ SIGBUS : constant := 10; -- bus error
+ SIGSEGV : constant := 11; -- segmentation violation
+
+ -----------------------------------
+ -- Signal processing definitions --
+ -----------------------------------
+
+ -- The how in sigprocmask().
+ SIG_BLOCK : constant := 1;
+ SIG_UNBLOCK : constant := 2;
+ SIG_SETMASK : constant := 3;
+
+ -- The sa_flags in struct sigaction.
+ SA_SIGINFO : constant := 16#0002#;
+ SA_ONSTACK : constant := 16#0004#;
+
+ SIG_DFL : constant := 0;
+ SIG_IGN : constant := 1;
+
+ type sigset_t is private;
+
+ type struct_sigaction is record
+ sa_handler : System.Address;
+ sa_mask : sigset_t;
+ sa_flags : int;
+ end record;
+ pragma Convention (C, struct_sigaction);
+ type struct_sigaction_ptr is access all struct_sigaction;
+
+ function sigaddset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigaddset, "sigaddset");
+
+ function sigdelset (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigdelset, "sigdelset");
+
+ function sigfillset (set : access sigset_t) return int;
+ pragma Import (C, sigfillset, "sigfillset");
+
+ function sigismember (set : access sigset_t; sig : Signal) return int;
+ pragma Import (C, sigismember, "sigismember");
+
+ function sigemptyset (set : access sigset_t) return int;
+ pragma Import (C, sigemptyset, "sigemptyset");
+
+ function sigaction
+ (sig : Signal;
+ act : struct_sigaction_ptr;
+ oact : struct_sigaction_ptr) return int;
+ pragma Import (C, sigaction, "sigaction");
+
+ type isr_address is access procedure (sig : int);
+
+ function c_signal (sig : Signal; handler : isr_address) return isr_address;
+ pragma Import (C, c_signal, "signal");
+
+ function sigwait (set : access sigset_t; sig : access Signal) return int;
+ pragma Inline (sigwait);
+
+ type sigset_t_ptr is access all sigset_t;
+
+ function pthread_sigmask
+ (how : int;
+ set : sigset_t_ptr;
+ oset : sigset_t_ptr) return int;
+ pragma Import (C, pthread_sigmask, "sigprocmask");
+
+ type t_id is new long;
+ subtype Thread_Id is t_id;
+
+ function kill (pid : t_id; sig : Signal) return int;
+ pragma Import (C, kill, "kill");
+
+ -- VxWorks doesn't have getpid; taskIdSelf is the equivalent
+ -- routine.
+ function getpid return t_id;
+ pragma Import (C, getpid, "taskIdSelf");
+
+ ----------
+ -- Time --
+ ----------
+
+ type time_t is new unsigned_long;
+
+ type timespec is record
+ ts_sec : time_t;
+ ts_nsec : long;
+ end record;
+ pragma Convention (C, timespec);
+
+ type clockid_t is private;
+
+ CLOCK_REALTIME : constant clockid_t; -- System wide realtime clock
+
+ function To_Duration (TS : timespec) return Duration;
+ pragma Inline (To_Duration);
+
+ function To_Timespec (D : Duration) return timespec;
+ pragma Inline (To_Timespec);
+
+ function To_Clock_Ticks (D : Duration) return int;
+ -- Convert a duration value (in seconds) into clock ticks.
+
+ function clock_gettime
+ (clock_id : clockid_t; tp : access timespec) return int;
+ pragma Import (C, clock_gettime, "clock_gettime");
+
+ type ULONG is new unsigned_long;
+
+ procedure tickSet (ticks : ULONG);
+ pragma Import (C, tickSet, "tickSet");
+
+ function tickGet return ULONG;
+ pragma Import (C, tickGet, "tickGet");
+
+ -----------------------------------------------------
+ -- Convenience routine to convert between VxWorks --
+ -- priority and Ada priority. --
+ -----------------------------------------------------
+
+ function To_VxWorks_Priority (Priority : in int) return int;
+ pragma Inline (To_VxWorks_Priority);
+
+ --------------------------
+ -- VxWorks specific API --
+ --------------------------
+
+ subtype STATUS is int;
+ -- Equivalent of the C type STATUS
+
+ OK : constant STATUS := 0;
+ ERROR : constant STATUS := Interfaces.C.int (-1);
+
+ function taskIdVerify (tid : t_id) return STATUS;
+ pragma Import (C, taskIdVerify, "taskIdVerify");
+
+ function taskIdSelf return t_id;
+ pragma Import (C, taskIdSelf, "taskIdSelf");
+
+ function taskSuspend (tid : t_id) return int;
+ pragma Import (C, taskSuspend, "taskSuspend");
+
+ function taskResume (tid : t_id) return int;
+ pragma Import (C, taskResume, "taskResume");
+
+ function taskIsSuspended (tid : t_id) return int;
+ pragma Import (C, taskIsSuspended, "taskIsSuspended");
+
+ function taskVarAdd
+ (tid : t_id; pVar : access System.Address) return int;
+ pragma Import (C, taskVarAdd, "taskVarAdd");
+
+ function taskVarDelete
+ (tid : t_id; pVar : access System.Address) return int;
+ pragma Import (C, taskVarDelete, "taskVarDelete");
+
+ function taskVarSet
+ (tid : t_id;
+ pVar : access System.Address;
+ value : System.Address) return int;
+ pragma Import (C, taskVarSet, "taskVarSet");
+
+ function taskVarGet
+ (tid : t_id;
+ pVar : access System.Address) return int;
+ pragma Import (C, taskVarGet, "taskVarGet");
+
+ function taskDelay (ticks : int) return int;
+ procedure taskDelay (ticks : int);
+ pragma Import (C, taskDelay, "taskDelay");
+
+ function sysClkRateGet return int;
+ pragma Import (C, sysClkRateGet, "sysClkRateGet");
+
+ -- Option flags for taskSpawn
+
+ VX_UNBREAKABLE : constant := 16#0002#;
+ VX_FP_TASK : constant := 16#0008#;
+ VX_FP_PRIVATE_ENV : constant := 16#0080#;
+ VX_NO_STACK_FILL : constant := 16#0100#;
+
+ function taskSpawn
+ (name : System.Address; -- Pointer to task name
+ priority : int;
+ options : int;
+ stacksize : size_t;
+ start_routine : System.Address;
+ arg1 : System.Address;
+ arg2 : int := 0;
+ arg3 : int := 0;
+ arg4 : int := 0;
+ arg5 : int := 0;
+ arg6 : int := 0;
+ arg7 : int := 0;
+ arg8 : int := 0;
+ arg9 : int := 0;
+ arg10 : int := 0) return t_id;
+ pragma Import (C, taskSpawn, "taskSpawn");
+
+ procedure taskDelete (tid : t_id);
+ pragma Import (C, taskDelete, "taskDelete");
+
+ function kernelTimeSlice (ticks : int) return int;
+ pragma Import (C, kernelTimeSlice, "kernelTimeSlice");
+
+ function taskPrioritySet
+ (tid : t_id; newPriority : int) return int;
+ pragma Import (C, taskPrioritySet, "taskPrioritySet");
+
+ -- Semaphore creation flags.
+
+ SEM_Q_FIFO : constant := 0;
+ SEM_Q_PRIORITY : constant := 1;
+ SEM_DELETE_SAFE : constant := 4; -- only valid for binary semaphore
+ SEM_INVERSION_SAFE : constant := 8; -- only valid for binary semaphore
+
+ -- Semaphore initial state flags
+
+ SEM_EMPTY : constant := 0;
+ SEM_FULL : constant := 1;
+
+ -- Semaphore take (semTake) time constants.
+
+ WAIT_FOREVER : constant := -1;
+ NO_WAIT : constant := 0;
+
+ -- Error codes (errno). The lower level 16 bits are the
+ -- error code, with the upper 16 bits representing the
+ -- module number in which the error occurred. By convention,
+ -- the module number is 0 for UNIX errors. VxWorks reserves
+ -- module numbers 1-500, with the remaining module numbers
+ -- being available for user applications.
+
+ M_objLib : constant := 61 * 2**16;
+ -- semTake() failure with ticks = NO_WAIT
+ S_objLib_OBJ_UNAVAILABLE : constant := M_objLib + 2;
+ -- semTake() timeout with ticks > NO_WAIT
+ S_objLib_OBJ_TIMEOUT : constant := M_objLib + 4;
+
+ type SEM_ID is new System.Address;
+ -- typedef struct semaphore *SEM_ID;
+
+ -- We use two different kinds of VxWorks semaphores: mutex
+ -- and binary semaphores. A null ID is returned when
+ -- a semaphore cannot be created.
+
+ function semBCreate (options : int; initial_state : int) return SEM_ID;
+ -- Create a binary semaphore. Return ID, or 0 if memory could not
+ -- be allocated.
+ pragma Import (C, semBCreate, "semBCreate");
+
+ function semMCreate (options : int) return SEM_ID;
+ pragma Import (C, semMCreate, "semMCreate");
+
+ function semDelete (Sem : SEM_ID) return int;
+ -- Delete a semaphore
+ pragma Import (C, semDelete, "semDelete");
+
+ function semGive (Sem : SEM_ID) return int;
+ pragma Import (C, semGive, "semGive");
+
+ function semTake (Sem : SEM_ID; timeout : int) return int;
+ -- Attempt to take binary semaphore. Error is returned if operation
+ -- times out
+ pragma Import (C, semTake, "semTake");
+
+ function semFlush (SemID : SEM_ID) return STATUS;
+ -- Release all threads blocked on the semaphore
+ pragma Import (C, semFlush, "semFlush");
+
+ function taskLock return int;
+ pragma Import (C, taskLock, "taskLock");
+
+ function taskUnlock return int;
+ pragma Import (C, taskUnlock, "taskUnlock");
+
+private
+ type sigset_t is new long;
+
+ type pid_t is new int;
+
+ ERROR_PID : constant pid_t := -1;
+
+ type clockid_t is new int;
+ CLOCK_REALTIME : constant clockid_t := 0;
+
+end System.OS_Interface;
diff --git a/gcc/ada/s-osprim-mingw.adb b/gcc/ada/s-osprim-mingw.adb
new file mode 100644
index 00000000000..07a8ca79eab
--- /dev/null
+++ b/gcc/ada/s-osprim-mingw.adb
@@ -0,0 +1,286 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ P R I M I T I V E S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1998-2003 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- --
+-- 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, 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, --
+-- 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 is the NT version of this package
+
+with Ada.Exceptions;
+with Interfaces.C;
+
+package body System.OS_Primitives is
+
+ ---------------------------
+ -- Win32 API Definitions --
+ ---------------------------
+
+ -- These definitions are copied from System.OS_Interface because we do not
+ -- want to depend on gnarl here.
+
+ type DWORD is new Interfaces.C.unsigned_long;
+
+ type LARGE_INTEGER is delta 1.0 range -2.0**63 .. 2.0**63 - 1.0;
+
+ type BOOL is new Boolean;
+ for BOOL'Size use Interfaces.C.unsigned_long'Size;
+
+ procedure GetSystemTimeAsFileTime (lpFileTime : access Long_Long_Integer);
+ pragma Import (Stdcall, GetSystemTimeAsFileTime, "GetSystemTimeAsFileTime");
+
+ function QueryPerformanceCounter
+ (lpPerformanceCount : access LARGE_INTEGER) return BOOL;
+ pragma Import
+ (Stdcall, QueryPerformanceCounter, "QueryPerformanceCounter");
+
+ function QueryPerformanceFrequency
+ (lpFrequency : access LARGE_INTEGER) return BOOL;
+ pragma Import
+ (Stdcall, QueryPerformanceFrequency, "QueryPerformanceFrequency");
+
+ procedure Sleep (dwMilliseconds : DWORD);
+ pragma Import (Stdcall, Sleep, External_Name => "Sleep");
+
+ ----------------------------------------
+ -- Data for the high resolution clock --
+ ----------------------------------------
+
+ -- Declare some pointers to access multi-word data above. This is needed
+ -- to workaround a limitation in the GNU/Linker auto-import feature used
+ -- to build the GNAT runtime DLLs. In fact the Clock and Monotonic_Clock
+ -- routines are inlined and they are using some multi-word variables.
+ -- GNU/Linker will fail to auto-import those variables when building
+ -- libgnarl.dll. The indirection level introduced here has no measurable
+ -- penalties.
+ --
+ -- Note that access variables below must not be declared as constant
+ -- otherwise the compiler optimization will remove this indirect access.
+
+ type DA is access all Duration;
+ -- Use to have indirect access to multi-word variables
+
+ type LIA is access all LARGE_INTEGER;
+ -- Use to have indirect access to multi-word variables
+
+ type LLIA is access all Long_Long_Integer;
+ -- Use to have indirect access to multi-word variables
+
+ Tick_Frequency : aliased LARGE_INTEGER;
+ TFA : constant LIA := Tick_Frequency'Access;
+ -- Holds frequency of high-performance counter used by Clock
+ -- Windows NT uses a 1_193_182 Hz counter on PCs.
+
+ Base_Ticks : aliased LARGE_INTEGER;
+ BTA : constant LIA := Base_Ticks'Access;
+ -- Holds the Tick count for the base time.
+
+ Base_Monotonic_Ticks : aliased LARGE_INTEGER;
+ BMTA : constant LIA := Base_Monotonic_Ticks'Access;
+ -- Holds the Tick count for the base monotonic time
+
+ Base_Clock : aliased Duration;
+ BCA : constant DA := Base_Clock'Access;
+ -- Holds the current clock for the standard clock's base time
+
+ Base_Monotonic_Clock : aliased Duration;
+ BMCA : constant DA := Base_Monotonic_Clock'Access;
+ -- Holds the current clock for monotonic clock's base time
+
+ Base_Time : aliased Long_Long_Integer;
+ BTiA : constant LLIA := Base_Time'Access;
+ -- Holds the base time used to check for system time change, used with
+ -- the standard clock.
+
+ procedure Get_Base_Time;
+ -- Retrieve the base time and base ticks. These values will be used by
+ -- clock to compute the current time by adding to it a fraction of the
+ -- performance counter. This is for the implementation of a
+ -- high-resolution clock. Note that this routine does not change the base
+ -- monotonic values used by the monotonic clock.
+
+ -----------
+ -- Clock --
+ -----------
+
+ -- This implementation of clock provides high resolution timer values
+ -- using QueryPerformanceCounter. This call return a 64 bits values (based
+ -- on the 8253 16 bits counter). This counter is updated every 1/1_193_182
+ -- times per seconds. The call to QueryPerformanceCounter takes 6
+ -- microsecs to complete.
+
+ function Clock return Duration is
+ Max_Shift : constant Duration := 2.0;
+ Hundreds_Nano_In_Sec : constant Long_Long_Float := 1.0E7;
+ Current_Ticks : aliased LARGE_INTEGER;
+ Elap_Secs_Tick : Duration;
+ Elap_Secs_Sys : Duration;
+ Now : aliased Long_Long_Integer;
+
+ begin
+ if not QueryPerformanceCounter (Current_Ticks'Access) then
+ return 0.0;
+ end if;
+
+ GetSystemTimeAsFileTime (Now'Access);
+
+ Elap_Secs_Sys :=
+ Duration (Long_Long_Float (abs (Now - BTiA.all)) /
+ Hundreds_Nano_In_Sec);
+
+ Elap_Secs_Tick :=
+ Duration (Long_Long_Float (Current_Ticks - BTA.all) /
+ Long_Long_Float (TFA.all));
+
+ -- If we have a shift of more than Max_Shift seconds we resynchonize the
+ -- Clock. This is probably due to a manual Clock adjustment, an DST
+ -- adjustment or an NTP synchronisation. And we want to adjust the
+ -- time for this system (non-monotonic) clock.
+
+ if abs (Elap_Secs_Sys - Elap_Secs_Tick) > Max_Shift then
+ Get_Base_Time;
+
+ Elap_Secs_Tick :=
+ Duration (Long_Long_Float (Current_Ticks - BTA.all) /
+ Long_Long_Float (TFA.all));
+ end if;
+
+ return BCA.all + Elap_Secs_Tick;
+ end Clock;
+
+ -------------------
+ -- Get_Base_Time --
+ -------------------
+
+ procedure Get_Base_Time is
+ -- The resolution for GetSystemTime is 1 millisecond.
+
+ -- The time to get both base times should take less than 1 millisecond.
+ -- Therefore, the elapsed time reported by GetSystemTime between both
+ -- actions should be null.
+
+ Max_Elapsed : constant := 0;
+
+ Test_Now : aliased Long_Long_Integer;
+
+ 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;
+
+ begin
+ -- Here we must be sure that both of these calls are done in a short
+ -- amount of time. Both are base time and should in theory be taken
+ -- at the very same time.
+
+ loop
+ GetSystemTimeAsFileTime (Base_Time'Access);
+
+ if not QueryPerformanceCounter (Base_Ticks'Access) then
+ pragma Assert
+ (Standard.False,
+ "Could not query high performance counter in Clock");
+ null;
+ end if;
+
+ GetSystemTimeAsFileTime (Test_Now'Access);
+
+ exit when Test_Now - Base_Time = Max_Elapsed;
+ end loop;
+
+ Base_Clock := Duration
+ (Long_Long_Float ((Base_Time - epoch_1970) * system_time_ns) /
+ Long_Long_Float (Sec_Unit));
+ end Get_Base_Time;
+
+ ---------------------
+ -- Monotonic_Clock --
+ ---------------------
+
+ function Monotonic_Clock return Duration is
+ Current_Ticks : aliased LARGE_INTEGER;
+ Elap_Secs_Tick : Duration;
+ begin
+ if not QueryPerformanceCounter (Current_Ticks'Access) then
+ return 0.0;
+ end if;
+
+ Elap_Secs_Tick :=
+ Duration (Long_Long_Float (Current_Ticks - BMTA.all) /
+ Long_Long_Float (TFA.all));
+
+ return BMCA.all + Elap_Secs_Tick;
+ end Monotonic_Clock;
+
+ -----------------
+ -- Timed_Delay --
+ -----------------
+
+ procedure Timed_Delay (Time : Duration; Mode : Integer) is
+ Rel_Time : Duration;
+ Abs_Time : Duration;
+ Check_Time : Duration := Monotonic_Clock;
+
+ begin
+ if Mode = Relative then
+ Rel_Time := Time;
+ Abs_Time := Time + Check_Time;
+ else
+ Rel_Time := Time - Check_Time;
+ Abs_Time := Time;
+ end if;
+
+ if Rel_Time > 0.0 then
+ loop
+ Sleep (DWORD (Rel_Time * 1000.0));
+ Check_Time := Monotonic_Clock;
+
+ exit when Abs_Time <= Check_Time;
+
+ Rel_Time := Abs_Time - Check_Time;
+ end loop;
+ end if;
+ end Timed_Delay;
+
+-- Package elaboration, get starting time as base
+
+begin
+ if not QueryPerformanceFrequency (Tick_Frequency'Access) then
+ Ada.Exceptions.Raise_Exception
+ (Program_Error'Identity,
+ "cannot get high performance counter frequency");
+ end if;
+
+ Get_Base_Time;
+
+ -- Keep base clock and ticks for the monotonic clock. These values should
+ -- never be changed to ensure proper behavior of the monotonic clock.
+
+ Base_Monotonic_Clock := Base_Clock;
+ Base_Monotonic_Ticks := Base_Ticks;
+end System.OS_Primitives;
diff --git a/gcc/ada/s-osprim-os2.adb b/gcc/ada/s-osprim-os2.adb
new file mode 100644
index 00000000000..42e414cde44
--- /dev/null
+++ b/gcc/ada/s-osprim-os2.adb
@@ -0,0 +1,172 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ P R I M I T I V E S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1998-2001 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- --
+-- 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, 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, --
+-- 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 is the OS/2 version of this package
+
+with Interfaces.C; use Interfaces.C;
+with Interfaces.OS2Lib; use Interfaces.OS2Lib;
+with Interfaces.OS2Lib.Synchronization; use Interfaces.OS2Lib.Synchronization;
+
+package body System.OS_Primitives is
+
+ ----------------
+ -- Local Data --
+ ----------------
+
+ Epoch_Offset : Duration; -- See Set_Epoch_Offset
+ Max_Tick_Count : QWORD := 0.0;
+ -- This is needed to compensate for small glitches in the
+ -- hardware clock or the way it is read by the OS
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ procedure Set_Epoch_Offset;
+ -- Initializes the Epoch_1970_Offset to the offset of the System_Clock
+ -- relative to the Unix epoch (Jan 1, 1970), such that
+ -- Clock = System_Clock + Epoch_1970_Offset
+
+ function System_Clock return Duration;
+ pragma Inline (System_Clock);
+ -- Function returning value of system clock with system-dependent timebase.
+ -- For OS/2 the system clock returns the elapsed time since system boot.
+ -- The clock resolution is approximately 838 ns.
+
+ ------------------
+ -- System_Clock --
+ ------------------
+
+ function System_Clock return Duration is
+
+ -- Implement conversion from tick count to Duration
+ -- using fixed point arithmetic. The frequency of
+ -- the Intel 8254 timer chip is 18.2 * 2**16 Hz.
+
+ Tick_Duration : constant := 1.0 / (18.2 * 2**16);
+ Tick_Count : aliased QWORD;
+
+ begin
+ Must_Not_Fail (DosTmrQueryTime (Tick_Count'Access));
+ -- Read nr of clock ticks since boot time
+
+ Max_Tick_Count := QWORD'Max (Tick_Count, Max_Tick_Count);
+
+ return Max_Tick_Count * Tick_Duration;
+ end System_Clock;
+
+ -----------
+ -- Clock --
+ -----------
+
+ function Clock return Duration is
+ begin
+ return System_Clock + Epoch_Offset;
+ end Clock;
+
+ ---------------------
+ -- Monotonic_Clock --
+ ---------------------
+
+ function Monotonic_Clock return Duration renames Clock;
+
+ ----------------------
+ -- Set_Epoch_Offset --
+ ----------------------
+
+ procedure Set_Epoch_Offset is
+
+ -- Interface to Unix C style gettimeofday
+
+ type timeval is record
+ tv_sec : long;
+ tv_usec : long;
+ end record;
+
+ procedure gettimeofday
+ (time : access timeval;
+ zone : System.Address := System.Address'Null_Parameter);
+ pragma Import (C, gettimeofday);
+
+ Time_Of_Day : aliased timeval;
+ Micro_To_Nano : constant := 1.0E3;
+ Sec_To_Nano : constant := 1.0E9;
+ Nanos_Since_Epoch : QWORD;
+
+ begin
+ gettimeofday (Time_Of_Day'Access);
+ Nanos_Since_Epoch := QWORD (Time_Of_Day.tv_sec) * Sec_To_Nano
+ + QWORD (Time_Of_Day.tv_usec) * Micro_To_Nano;
+
+ Epoch_Offset :=
+ Duration'(Nanos_Since_Epoch / Sec_To_Nano) - System_Clock;
+
+ end Set_Epoch_Offset;
+
+ -----------------
+ -- Timed_Delay --
+ -----------------
+
+ procedure Timed_Delay
+ (Time : Duration;
+ Mode : Integer)
+ is
+ Rel_Time : Duration;
+ Abs_Time : Duration;
+ Check_Time : Duration := Clock;
+
+ begin
+ if Mode = Relative then
+ Rel_Time := Time;
+ Abs_Time := Time + Check_Time;
+ else
+ Rel_Time := Time - Check_Time;
+ Abs_Time := Time;
+ end if;
+
+ if Rel_Time > 0.0 then
+ loop
+ Must_Not_Fail (DosSleep (ULONG (Rel_Time * 1000.0)));
+
+ Check_Time := Clock;
+
+ exit when Abs_Time <= Check_Time;
+
+ Rel_Time := Abs_Time - Check_Time;
+ end loop;
+ end if;
+ end Timed_Delay;
+
+begin
+ Set_Epoch_Offset;
+end System.OS_Primitives;
diff --git a/gcc/ada/s-osprim-posix.adb b/gcc/ada/s-osprim-posix.adb
new file mode 100644
index 00000000000..c4a7a112380
--- /dev/null
+++ b/gcc/ada/s-osprim-posix.adb
@@ -0,0 +1,159 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ P R I M I T I V E S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1998-2003 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- --
+-- 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, 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, --
+-- 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 version is for POSIX-like operating systems
+
+package body System.OS_Primitives is
+
+ -- ??? These definitions are duplicated from System.OS_Interface
+ -- because we don't want to depend on any package. Consider removing
+ -- these declarations in System.OS_Interface and move these ones in
+ -- the spec.
+
+ type struct_timezone is record
+ tz_minuteswest : Integer;
+ tz_dsttime : Integer;
+ end record;
+ pragma Convention (C, struct_timezone);
+ type struct_timezone_ptr is access all struct_timezone;
+
+ type time_t is new Long_Integer;
+
+ type struct_timeval is record
+ tv_sec : time_t;
+ tv_usec : Long_Integer;
+ end record;
+ pragma Convention (C, struct_timeval);
+
+ function gettimeofday
+ (tv : access struct_timeval;
+ tz : struct_timezone_ptr) return Integer;
+ pragma Import (C, gettimeofday, "gettimeofday");
+
+ type timespec is record
+ tv_sec : time_t;
+ tv_nsec : Long_Integer;
+ end record;
+ pragma Convention (C, timespec);
+
+ function nanosleep (rqtp, rmtp : access timespec) return Integer;
+ pragma Import (C, nanosleep, "nanosleep");
+
+ -----------
+ -- Clock --
+ -----------
+
+ function Clock return Duration is
+ TV : aliased struct_timeval;
+
+ Result : Integer;
+ pragma Unreferenced (Result);
+
+ begin
+ Result := gettimeofday (TV'Access, null);
+ return Duration (TV.tv_sec) + Duration (TV.tv_usec) / 10#1#E6;
+ end Clock;
+
+ ---------------------
+ -- Monotonic_Clock --
+ ---------------------
+
+ function Monotonic_Clock return Duration renames Clock;
+
+ -----------------
+ -- To_Timespec --
+ -----------------
+
+ function To_Timespec (D : Duration) return timespec;
+
+ function To_Timespec (D : Duration) return timespec is
+ S : time_t;
+ F : Duration;
+
+ begin
+ S := time_t (Long_Long_Integer (D));
+ F := D - Duration (S);
+
+ -- If F has negative value due to a round-up, adjust for positive F
+ -- value.
+
+ if F < 0.0 then
+ S := S - 1;
+ F := F + 1.0;
+ end if;
+
+ return
+ timespec'(tv_sec => S,
+ tv_nsec => Long_Integer (Long_Long_Integer (F * 10#1#E9)));
+ end To_Timespec;
+
+ -----------------
+ -- Timed_Delay --
+ -----------------
+
+ procedure Timed_Delay
+ (Time : Duration;
+ Mode : Integer)
+ is
+ Request : aliased timespec;
+ Remaind : aliased timespec;
+ Rel_Time : Duration;
+ Abs_Time : Duration;
+ Check_Time : Duration := Clock;
+
+ Result : Integer;
+ pragma Unreferenced (Result);
+
+ begin
+ if Mode = Relative then
+ Rel_Time := Time;
+ Abs_Time := Time + Check_Time;
+ else
+ Rel_Time := Time - Check_Time;
+ Abs_Time := Time;
+ end if;
+
+ if Rel_Time > 0.0 then
+ loop
+ Request := To_Timespec (Rel_Time);
+ Result := nanosleep (Request'Access, Remaind'Access);
+ Check_Time := Clock;
+
+ exit when Abs_Time <= Check_Time;
+
+ Rel_Time := Abs_Time - Check_Time;
+ end loop;
+ end if;
+ end Timed_Delay;
+
+end System.OS_Primitives;
diff --git a/gcc/ada/s-osprim-solaris.adb b/gcc/ada/s-osprim-solaris.adb
new file mode 100644
index 00000000000..b6d529d206c
--- /dev/null
+++ b/gcc/ada/s-osprim-solaris.adb
@@ -0,0 +1,124 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ P R I M I T I V E S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1998-2003 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- --
+-- 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, 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, --
+-- 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 version uses gettimeofday and select
+-- This file is suitable for Solaris (32 and 64 bits).
+
+package body System.OS_Primitives is
+
+ -- ??? These definitions are duplicated from System.OS_Interface
+ -- because we don't want to depend on any package. Consider removing
+ -- these declarations in System.OS_Interface and move these ones in
+ -- the spec.
+
+ type struct_timeval is record
+ tv_sec : Long_Integer;
+ tv_usec : Long_Integer;
+ end record;
+ pragma Convention (C, struct_timeval);
+
+ procedure gettimeofday
+ (tv : access struct_timeval;
+ tz : Address := Null_Address);
+ pragma Import (C, gettimeofday, "gettimeofday");
+
+ procedure C_select
+ (n : Integer := 0;
+ readfds,
+ writefds,
+ exceptfds : Address := Null_Address;
+ timeout : access struct_timeval);
+ pragma Import (C, C_select, "select");
+
+ -----------
+ -- Clock --
+ -----------
+
+ function Clock return Duration is
+ TV : aliased struct_timeval;
+
+ begin
+ gettimeofday (TV'Access);
+ return Duration (TV.tv_sec) + Duration (TV.tv_usec) / 10#1#E6;
+ end Clock;
+
+ ---------------------
+ -- Monotonic_Clock --
+ ---------------------
+
+ function Monotonic_Clock return Duration renames Clock;
+
+ -----------------
+ -- Timed_Delay --
+ -----------------
+
+ procedure Timed_Delay
+ (Time : Duration;
+ Mode : Integer)
+ is
+ Rel_Time : Duration;
+ Abs_Time : Duration;
+ Check_Time : Duration := Clock;
+ timeval : aliased struct_timeval;
+
+ begin
+ if Mode = Relative then
+ Rel_Time := Time;
+ Abs_Time := Time + Check_Time;
+ else
+ Rel_Time := Time - Check_Time;
+ Abs_Time := Time;
+ end if;
+
+ if Rel_Time > 0.0 then
+ loop
+ timeval.tv_sec := Long_Integer (Rel_Time);
+
+ if Duration (timeval.tv_sec) > Rel_Time then
+ timeval.tv_sec := timeval.tv_sec - 1;
+ end if;
+
+ timeval.tv_usec :=
+ Long_Integer ((Rel_Time - Duration (timeval.tv_sec)) * 10#1#E6);
+
+ C_select (timeout => timeval'Unchecked_Access);
+ Check_Time := Clock;
+
+ exit when Abs_Time <= Check_Time;
+
+ Rel_Time := Abs_Time - Check_Time;
+ end loop;
+ end if;
+ end Timed_Delay;
+
+end System.OS_Primitives;
diff --git a/gcc/ada/s-osprim-unix.adb b/gcc/ada/s-osprim-unix.adb
new file mode 100644
index 00000000000..ed8a6f40f55
--- /dev/null
+++ b/gcc/ada/s-osprim-unix.adb
@@ -0,0 +1,124 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ P R I M I T I V E S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1998-2003 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- --
+-- 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, 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, --
+-- 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 version uses gettimeofday and select
+-- This file is suitable for OpenNT, Dec Unix and SCO UnixWare.
+
+package body System.OS_Primitives is
+
+ -- ??? These definitions are duplicated from System.OS_Interface
+ -- because we don't want to depend on any package. Consider removing
+ -- these declarations in System.OS_Interface and move these ones in
+ -- the spec.
+
+ type struct_timeval is record
+ tv_sec : Integer;
+ tv_usec : Integer;
+ end record;
+ pragma Convention (C, struct_timeval);
+
+ procedure gettimeofday
+ (tv : access struct_timeval;
+ tz : Address := Null_Address);
+ pragma Import (C, gettimeofday, "gettimeofday");
+
+ procedure C_select
+ (n : Integer := 0;
+ readfds,
+ writefds,
+ exceptfds : Address := Null_Address;
+ timeout : access struct_timeval);
+ pragma Import (C, C_select, "select");
+
+ -----------
+ -- Clock --
+ -----------
+
+ function Clock return Duration is
+ TV : aliased struct_timeval;
+
+ begin
+ gettimeofday (TV'Access);
+ return Duration (TV.tv_sec) + Duration (TV.tv_usec) / 10#1#E6;
+ end Clock;
+
+ ---------------------
+ -- Monotonic_Clock --
+ ---------------------
+
+ function Monotonic_Clock return Duration renames Clock;
+
+ -----------------
+ -- Timed_Delay --
+ -----------------
+
+ procedure Timed_Delay
+ (Time : Duration;
+ Mode : Integer)
+ is
+ Rel_Time : Duration;
+ Abs_Time : Duration;
+ Check_Time : Duration := Clock;
+ timeval : aliased struct_timeval;
+
+ begin
+ if Mode = Relative then
+ Rel_Time := Time;
+ Abs_Time := Time + Check_Time;
+ else
+ Rel_Time := Time - Check_Time;
+ Abs_Time := Time;
+ end if;
+
+ if Rel_Time > 0.0 then
+ loop
+ timeval.tv_sec := Integer (Rel_Time);
+
+ if Duration (timeval.tv_sec) > Rel_Time then
+ timeval.tv_sec := timeval.tv_sec - 1;
+ end if;
+
+ timeval.tv_usec :=
+ Integer ((Rel_Time - Duration (timeval.tv_sec)) * 10#1#E6);
+
+ C_select (timeout => timeval'Unchecked_Access);
+ Check_Time := Clock;
+
+ exit when Abs_Time <= Check_Time;
+
+ Rel_Time := Abs_Time - Check_Time;
+ end loop;
+ end if;
+ end Timed_Delay;
+
+end System.OS_Primitives;
diff --git a/gcc/ada/s-osprim-vms.adb b/gcc/ada/s-osprim-vms.adb
new file mode 100644
index 00000000000..c49c861bf34
--- /dev/null
+++ b/gcc/ada/s-osprim-vms.adb
@@ -0,0 +1,193 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ P R I M I T I V E S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1998-2002 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- --
+-- 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, 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, --
+-- 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 is the OpenVMS/Alpha version of this file
+
+with System.Aux_DEC;
+
+package body System.OS_Primitives is
+
+ --------------------------------------
+ -- Local functions and declarations --
+ --------------------------------------
+
+ function Get_GMToff return Integer;
+ pragma Import (C, Get_GMToff, "get_gmtoff");
+ -- Get the offset from GMT for this timezone
+
+ VMS_Epoch_Offset : constant Long_Integer :=
+ 10_000_000 *
+ (3_506_716_800 + Long_Integer (Get_GMToff));
+ -- The offset between the Unix Epoch and the VMS Epoch
+
+ subtype Cond_Value_Type is System.Aux_DEC.Unsigned_Longword;
+ -- Condition Value return type
+
+ ----------------
+ -- Sys_Schdwk --
+ ----------------
+ --
+ -- Schedule Wakeup
+ --
+ -- status = returned status
+ -- pidadr = address of process id to be woken up
+ -- prcnam = name of process to be woken up
+ -- daytim = time to wake up
+ -- reptim = repitition interval of wakeup calls
+ --
+
+ procedure Sys_Schdwk
+ (
+ Status : out Cond_Value_Type;
+ Pidadr : in Address := Null_Address;
+ Prcnam : in String := String'Null_Parameter;
+ Daytim : in Long_Integer;
+ Reptim : in Long_Integer := Long_Integer'Null_Parameter
+ );
+
+ pragma Interface (External, Sys_Schdwk);
+ -- VMS system call to schedule a wakeup event
+ pragma Import_Valued_Procedure
+ (Sys_Schdwk, "SYS$SCHDWK",
+ (Cond_Value_Type, Address, String, Long_Integer, Long_Integer),
+ (Value, Value, Descriptor (S), Reference, Reference)
+ );
+
+ ----------------
+ -- Sys_Gettim --
+ ----------------
+ --
+ -- Get System Time
+ --
+ -- status = returned status
+ -- tim = current system time
+ --
+
+ procedure Sys_Gettim
+ (
+ Status : out Cond_Value_Type;
+ Tim : out OS_Time
+ );
+ -- VMS system call to get the current system time
+ pragma Interface (External, Sys_Gettim);
+ pragma Import_Valued_Procedure
+ (Sys_Gettim, "SYS$GETTIM",
+ (Cond_Value_Type, OS_Time),
+ (Value, Reference)
+ );
+
+ ---------------
+ -- Sys_Hiber --
+ ---------------
+
+ -- Hibernate (until woken up)
+
+ -- status = returned status
+
+ procedure Sys_Hiber (Status : out Cond_Value_Type);
+ -- VMS system call to hibernate the current process
+ pragma Interface (External, Sys_Hiber);
+ pragma Import_Valued_Procedure
+ (Sys_Hiber, "SYS$HIBER",
+ (Cond_Value_Type),
+ (Value)
+ );
+
+ -----------
+ -- Clock --
+ -----------
+
+ function OS_Clock return OS_Time is
+ Status : Cond_Value_Type;
+ T : OS_Time;
+ begin
+ Sys_Gettim (Status, T);
+ return (T);
+ end OS_Clock;
+
+ -----------
+ -- Clock --
+ -----------
+
+ function Clock return Duration is
+ begin
+ return To_Duration (OS_Clock, Absolute_Calendar);
+ end Clock;
+
+ ---------------------
+ -- Monotonic_Clock --
+ ---------------------
+
+ function Monotonic_Clock return Duration renames Clock;
+
+ -----------------
+ -- Timed_Delay --
+ -----------------
+
+ procedure Timed_Delay
+ (Time : Duration;
+ Mode : Integer)
+ is
+ Sleep_Time : OS_Time;
+ Status : Cond_Value_Type;
+
+ begin
+ Sleep_Time := To_OS_Time (Time, Mode);
+ Sys_Schdwk (Status => Status, Daytim => Sleep_Time);
+ Sys_Hiber (Status);
+ end Timed_Delay;
+
+ -----------------
+ -- To_Duration --
+ -----------------
+
+ function To_Duration (T : OS_Time; Mode : Integer) return Duration is
+ pragma Warnings (Off, Mode);
+ begin
+ return Duration'Fixed_Value (T - VMS_Epoch_Offset) * 100;
+ end To_Duration;
+
+ ----------------
+ -- To_OS_Time --
+ ----------------
+
+ function To_OS_Time (D : Duration; Mode : Integer) return OS_Time is
+ begin
+ if Mode = Relative then
+ return -(Long_Integer'Integer_Value (D) / 100);
+ else
+ return Long_Integer'Integer_Value (D) / 100 + VMS_Epoch_Offset;
+ end if;
+ end To_OS_Time;
+
+end System.OS_Primitives;
diff --git a/gcc/ada/s-osprim-vms.ads b/gcc/ada/s-osprim-vms.ads
new file mode 100644
index 00000000000..a777bea3b83
--- /dev/null
+++ b/gcc/ada/s-osprim-vms.ads
@@ -0,0 +1,106 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ P R I M I T I V E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1998-2003 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- --
+-- 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, 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, --
+-- 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 provides low level primitives used to implement clock and
+-- delays in non tasking applications on Alpha/VMS
+
+-- The choice of the real clock/delay implementation (depending on whether
+-- tasking is involved or not) is done via soft links (see s-tasoli.ads)
+
+-- NEVER add any dependency to tasking packages here
+
+package System.OS_Primitives is
+
+ subtype OS_Time is Long_Integer;
+ -- System time on VMS is used for performance reasons.
+ -- Note that OS_Time is *not* the same as Ada.Calendar.Time, the
+ -- difference being that relative OS_Time is negative, but relative
+ -- Calendar.Time is positive.
+ -- See Ada.Calendar.Delays for more information on VMS Time.
+
+ Max_Sensible_Delay : constant Duration :=
+ Duration'Min (183 * 24 * 60 * 60.0,
+ Duration'Last);
+ -- Max of half a year delay, needed to prevent exceptions for large
+ -- delay values. It seems unlikely that any test will notice this
+ -- restriction, except in the case of applications setting the clock at
+ -- at run time (see s-tastim.adb). Also note that a larger value might
+ -- cause problems (e.g overflow, or more likely OS limitation in the
+ -- primitives used). In the case where half a year is too long (which
+ -- occurs in high integrity mode with 32-bit words, and possibly on
+ -- some specific ports of GNAT), Duration'Last is used instead.
+
+ function OS_Clock return OS_Time;
+ -- Returns "absolute" time, represented as an offset
+ -- relative to "the Epoch", which is Nov 17, 1858 on VMS.
+
+ function Clock return Duration;
+ pragma Inline (Clock);
+ -- Returns "absolute" time, represented as an offset
+ -- relative to "the Epoch", which is Jan 1, 1970 on unixes.
+ -- This implementation is affected by system's clock changes.
+
+ function Monotonic_Clock return Duration;
+ pragma Inline (Monotonic_Clock);
+ -- Returns "absolute" time, represented as an offset
+ -- relative to "the Epoch", which is Jan 1, 1970.
+ -- This clock implementation is immune to the system's clock changes.
+
+ Relative : constant := 0;
+ Absolute_Calendar : constant := 1;
+ Absolute_RT : constant := 2;
+ -- Values for Mode call below. Note that the compiler (exp_ch9.adb)
+ -- relies on these values. So any change here must be reflected in
+ -- corresponding changes in the compiler.
+
+ procedure Timed_Delay (Time : Duration; Mode : Integer);
+ -- Implements the semantics of the delay statement when no tasking is
+ -- used in the application.
+ --
+ -- Mode is one of the three values above
+ --
+ -- Time is a relative or absolute duration value, depending on Mode.
+ --
+ -- Note that currently Ada.Real_Time always uses the tasking run time, so
+ -- this procedure should never be called with Mode set to Absolute_RT.
+ -- This may change in future or bare board implementations.
+
+ function To_Duration (T : OS_Time; Mode : Integer) return Duration;
+ -- Convert VMS system time to Duration
+ -- Mode is one of the three values above
+
+ function To_OS_Time (D : Duration; Mode : Integer) return OS_Time;
+ -- Convert Duration to VMS system time
+ -- Mode is one of the three values above
+
+end System.OS_Primitives;
diff --git a/gcc/ada/s-osprim-vxworks.adb b/gcc/ada/s-osprim-vxworks.adb
new file mode 100644
index 00000000000..0f32bbe6dce
--- /dev/null
+++ b/gcc/ada/s-osprim-vxworks.adb
@@ -0,0 +1,161 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . O S _ P R I M I T I V E S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1998-2002 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- --
+-- 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, 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, --
+-- 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 version is for VxWorks targets
+
+with System.OS_Interface;
+-- Since the thread library is part of the VxWorks kernel, using OS_Interface
+-- is not a problem here, as long as we only use System.OS_Interface as a
+-- set of C imported routines: using Ada routines from this package would
+-- create a dependency on libgnarl in libgnat, which is not desirable.
+
+with Interfaces.C;
+-- used for type int
+
+package body System.OS_Primitives is
+
+ use System.OS_Interface;
+ use type Interfaces.C.int;
+
+ --------------------------
+ -- Internal functions --
+ --------------------------
+
+ function To_Clock_Ticks (D : Duration) return int;
+ -- Convert a duration value (in seconds) into clock ticks.
+ -- Note that this routine is duplicated from System.OS_Interface since
+ -- as explained above, we do not want to depend on libgnarl
+
+ function To_Clock_Ticks (D : Duration) return int is
+ Ticks : Long_Long_Integer;
+ Rate_Duration : Duration;
+ Ticks_Duration : Duration;
+
+ begin
+ if D < 0.0 then
+ return -1;
+ end if;
+
+ -- Ensure that the duration can be converted to ticks
+ -- at the current clock tick rate without overflowing.
+
+ Rate_Duration := Duration (sysClkRateGet);
+
+ if D > (Duration'Last / Rate_Duration) then
+ Ticks := Long_Long_Integer (int'Last);
+ else
+ Ticks_Duration := D * Rate_Duration;
+ Ticks := Long_Long_Integer (Ticks_Duration);
+
+ if Ticks_Duration > Duration (Ticks) then
+ Ticks := Ticks + 1;
+ end if;
+
+ if Ticks > Long_Long_Integer (int'Last) then
+ Ticks := Long_Long_Integer (int'Last);
+ end if;
+ end if;
+
+ return int (Ticks);
+ end To_Clock_Ticks;
+
+ -----------
+ -- Clock --
+ -----------
+
+ function Clock return Duration is
+ TS : aliased timespec;
+ Result : int;
+
+ use type Interfaces.C.int;
+
+ begin
+ Result := clock_gettime (CLOCK_REALTIME, TS'Unchecked_Access);
+ pragma Assert (Result = 0);
+ return Duration (TS.ts_sec) + Duration (TS.ts_nsec) / 10#1#E9;
+ end Clock;
+
+ ---------------------
+ -- Monotonic_Clock --
+ ---------------------
+
+ function Monotonic_Clock return Duration renames Clock;
+
+ -----------------
+ -- Timed_Delay --
+ -----------------
+
+ procedure Timed_Delay
+ (Time : Duration;
+ Mode : Integer)
+ is
+ Rel_Time : Duration;
+ Abs_Time : Duration;
+ Check_Time : Duration := Clock;
+ Ticks : int;
+
+ Result : int;
+ pragma Unreferenced (Result);
+
+ begin
+ if Mode = Relative then
+ Rel_Time := Time;
+ Abs_Time := Time + Check_Time;
+ else
+ Rel_Time := Time - Check_Time;
+ Abs_Time := Time;
+ end if;
+
+ if Rel_Time > 0.0 then
+ loop
+ Ticks := To_Clock_Ticks (Rel_Time);
+
+ if Mode = Relative and then Ticks < int'Last then
+ -- The first tick will delay anytime between 0 and
+ -- 1 / sysClkRateGet seconds, so we need to add one to
+ -- be on the safe side.
+
+ Ticks := Ticks + 1;
+ end if;
+
+ Result := taskDelay (Ticks);
+ Check_Time := Clock;
+
+ exit when Abs_Time <= Check_Time;
+
+ Rel_Time := Abs_Time - Check_Time;
+ end loop;
+ end if;
+ end Timed_Delay;
+
+end System.OS_Primitives;
diff --git a/gcc/ada/s-parame-ae653.ads b/gcc/ada/s-parame-ae653.ads
new file mode 100644
index 00000000000..af397c2aeb7
--- /dev/null
+++ b/gcc/ada/s-parame-ae653.ads
@@ -0,0 +1,203 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . P A R A M E T E R S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1992-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the default VxWorks AE 653 version of the package.`
+
+-- This package defines some system dependent parameters for GNAT. These
+-- are values that are referenced by the runtime library and are therefore
+-- relevant to the target machine.
+
+-- The parameters whose value is defined in the spec are not generally
+-- expected to be changed. If they are changed, it will be necessary to
+-- recompile the run-time library.
+
+-- The parameters which are defined by functions can be changed by modifying
+-- the body of System.Parameters in file s-parame.adb. A change to this body
+-- requires only rebinding and relinking of the application.
+
+-- Note: do not introduce any pragma Inline statements into this unit, since
+-- otherwise the relinking and rebinding capability would be deactivated.
+
+package System.Parameters is
+pragma Pure (Parameters);
+
+ ---------------------------------------
+ -- Task And Stack Allocation Control --
+ ---------------------------------------
+
+ type Task_Storage_Size is new Integer;
+ -- Type used in tasking units for task storage size
+
+ type Size_Type is new Task_Storage_Size;
+ -- Type used to provide task storage size to runtime
+
+ Unspecified_Size : constant Size_Type := Size_Type'First;
+ -- Value used to indicate that no size type is set
+
+ subtype Ratio is Size_Type range -1 .. 100;
+ Dynamic : constant Size_Type := -1;
+ -- The secondary stack ratio is a constant between 0 and 100 which
+ -- determines the percentage of the allocated task stack that is
+ -- used by the secondary stack (the rest being the primary stack).
+ -- The special value of minus one indicates that the secondary
+ -- stack is to be allocated from the heap instead.
+
+ Sec_Stack_Ratio : constant Ratio := 50;
+ -- This constant defines the handling of the secondary stack
+
+ Sec_Stack_Dynamic : constant Boolean := Sec_Stack_Ratio = Dynamic;
+ -- Convenient Boolean for testing for dynamic secondary stack
+
+ function Default_Stack_Size return Size_Type;
+ -- Default task stack size used if none is specified
+
+ function Minimum_Stack_Size return Size_Type;
+ -- Minimum task stack size permitted
+
+ function Adjust_Storage_Size (Size : Size_Type) return Size_Type;
+ -- Given the storage size stored in the TCB, return the Storage_Size
+ -- value required by the RM for the Storage_Size attribute. The
+ -- required adjustment is as follows:
+ --
+ -- when Size = Unspecified_Size, return Default_Stack_Size
+ -- when Size < Minimum_Stack_Size, return Minimum_Stack_Size
+ -- otherwise return given Size
+
+ Default_Env_Stack_Size : constant Size_Type := 14_336;
+ -- Assumed size of the environment task, if no other information
+ -- is available. This value is used when stack checking is
+ -- enabled and no GNAT_STACK_LIMIT environment variable is set.
+ -- This value is chosen as the VxWorks default stack size is 20kB,
+ -- and a little more than 4kB is necessary for the run time.
+
+ Stack_Grows_Down : constant Boolean := True;
+ -- This constant indicates whether the stack grows up (False) or
+ -- down (True) in memory as functions are called. It is used for
+ -- proper implementation of the stack overflow check.
+
+ ----------------------------------------------
+ -- Characteristics of types in Interfaces.C --
+ ----------------------------------------------
+
+ long_bits : constant := Long_Integer'Size;
+ -- Number of bits in type long and unsigned_long. The normal convention
+ -- is that this is the same as type Long_Integer, but this is not true
+ -- of all targets. For example, in OpenVMS long /= Long_Integer.
+
+ ----------------------------------------------
+ -- Behavior of Pragma Finalize_Storage_Only --
+ ----------------------------------------------
+
+ -- Garbage_Collected is a Boolean constant whose value indicates the
+ -- effect of the pragma Finalize_Storage_Entry on a controlled type.
+
+ -- Garbage_Collected = False
+
+ -- The system releases all storage on program termination only,
+ -- but not other garbage collection occurs, so finalization calls
+ -- are ommitted only for outer level onjects can be omitted if
+ -- pragma Finalize_Storage_Only is used.
+
+ -- Garbage_Collected = True
+
+ -- The system provides full garbage collection, so it is never
+ -- necessary to release storage for controlled objects for which
+ -- a pragma Finalize_Storage_Only is used.
+
+ Garbage_Collected : constant Boolean := False;
+ -- The storage mode for this system (release on program exit)
+
+ ---------------------
+ -- Tasking Profile --
+ ---------------------
+
+ -- In the following sections, constant parameters are defined to
+ -- allow some optimizations and fine tuning within the tasking run time
+ -- based on restrictions on the tasking features.
+
+ ----------------------
+ -- Locking Strategy --
+ ----------------------
+
+ Single_Lock : constant Boolean := False;
+ -- Indicates whether a single lock should be used within the tasking
+ -- run-time to protect internal structures. If True, a single lock
+ -- will be used, meaning less locking/unlocking operations, but also
+ -- more global contention. In general, Single_Lock should be set to
+ -- True on single processor machines, and to False to multi-processor
+ -- systems, but this can vary from application to application and also
+ -- depends on the scheduling policy.
+
+ -------------------
+ -- Task Abortion --
+ -------------------
+
+ No_Abort : constant Boolean := False;
+ -- This constant indicates whether abort statements and asynchronous
+ -- transfer of control (ATC) are disallowed. If set to True, it is
+ -- assumed that neither construct is used, and the run time does not
+ -- need to defer/undefer abort and check for pending actions at
+ -- completion points. A value of True for No_Abort corresponds to:
+ -- pragma Restrictions (No_Abort_Statements);
+ -- pragma Restrictions (Max_Asynchronous_Select_Nesting => 0);
+
+ ----------------------
+ -- Dynamic Priority --
+ ----------------------
+
+ Dynamic_Priority_Support : constant Boolean := True;
+ -- This constant indicates whether dynamic changes of task priorities
+ -- are allowed (True means normal RM mode in which such changes are
+ -- allowed). In particular, if this is False, then we do not need to
+ -- poll for pending base priority changes at every abort completion
+ -- point. A value of False for Dynamic_Priority_Support corresponds
+ -- to pragma Restrictions (No_Dynamic_Priorities);
+
+ ---------------------
+ -- Task Attributes --
+ ---------------------
+
+ Default_Attribute_Count : constant := 4;
+ -- Number of pre-allocated Address-sized task attributes stored in the
+ -- task control block.
+
+ --------------------
+ -- Runtime Traces --
+ --------------------
+
+ Runtime_Traces : constant Boolean := False;
+ -- This constant indicates whether the runtime outputs traces to a
+ -- predefined output or not (True means that traces are output).
+ -- See System.Traces for more details.
+
+end System.Parameters;
diff --git a/gcc/ada/s-parame-hpux.ads b/gcc/ada/s-parame-hpux.ads
new file mode 100644
index 00000000000..8be952a18c2
--- /dev/null
+++ b/gcc/ada/s-parame-hpux.ads
@@ -0,0 +1,202 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . P A R A M E T E R S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1992-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the HP version of this package
+-- Blank line intentional so that it lines up exactly with default.
+
+-- This package defines some system dependent parameters for GNAT. These
+-- are values that are referenced by the runtime library and are therefore
+-- relevant to the target machine.
+
+-- The parameters whose value is defined in the spec are not generally
+-- expected to be changed. If they are changed, it will be necessary to
+-- recompile the run-time library.
+
+-- The parameters which are defined by functions can be changed by modifying
+-- the body of System.Parameters in file s-parame.adb. A change to this body
+-- requires only rebinding and relinking of the application.
+
+-- Note: do not introduce any pragma Inline statements into this unit, since
+-- otherwise the relinking and rebinding capability would be deactivated.
+
+package System.Parameters is
+pragma Pure (Parameters);
+
+ ---------------------------------------
+ -- Task And Stack Allocation Control --
+ ---------------------------------------
+
+ type Task_Storage_Size is new Integer;
+ -- Type used in tasking units for task storage size
+
+ type Size_Type is new Task_Storage_Size;
+ -- Type used to provide task storage size to runtime
+
+ Unspecified_Size : constant Size_Type := Size_Type'First;
+ -- Value used to indicate that no size type is set
+
+ subtype Ratio is Size_Type range -1 .. 100;
+ Dynamic : constant Size_Type := -1;
+ -- The secondary stack ratio is a constant between 0 and 100 which
+ -- determines the percentage of the allocated task stack that is
+ -- used by the secondary stack (the rest being the primary stack).
+ -- The special value of minus one indicates that the secondary
+ -- stack is to be allocated from the heap instead.
+
+ Sec_Stack_Ratio : constant Ratio := Dynamic;
+ -- This constant defines the handling of the secondary stack
+
+ Sec_Stack_Dynamic : constant Boolean := Sec_Stack_Ratio = Dynamic;
+ -- Convenient Boolean for testing for dynamic secondary stack
+
+ function Default_Stack_Size return Size_Type;
+ -- Default task stack size used if none is specified
+
+ function Minimum_Stack_Size return Size_Type;
+ -- Minimum task stack size permitted
+
+ function Adjust_Storage_Size (Size : Size_Type) return Size_Type;
+ -- Given the storage size stored in the TCB, return the Storage_Size
+ -- value required by the RM for the Storage_Size attribute. The
+ -- required adjustment is as follows:
+ --
+ -- when Size = Unspecified_Size, return Default_Stack_Size
+ -- when Size < Minimum_Stack_Size, return Minimum_Stack_Size
+ -- otherwise return given Size
+
+ Default_Env_Stack_Size : constant Size_Type := 8_192_000;
+ -- Assumed size of the environment task, if no other information
+ -- is available. This value is used when stack checking is
+ -- enabled and no GNAT_STACK_LIMIT environment variable is set.
+
+ Stack_Grows_Down : constant Boolean := False;
+ -- This constant indicates whether the stack grows up (False) or
+ -- down (True) in memory as functions are called. It is used for
+ -- proper implementation of the stack overflow check.
+
+ ----------------------------------------------
+ -- Characteristics of Types in Interfaces.C --
+ ----------------------------------------------
+
+ long_bits : constant := Long_Integer'Size;
+ -- Number of bits in type long and unsigned_long. The normal convention
+ -- is that this is the same as type Long_Integer, but this is not true
+ -- of all targets. For example, in OpenVMS long /= Long_Integer.
+
+ ----------------------------------------------
+ -- Behavior of Pragma Finalize_Storage_Only --
+ ----------------------------------------------
+
+ -- Garbage_Collected is a Boolean constant whose value indicates the
+ -- effect of the pragma Finalize_Storage_Entry on a controlled type.
+
+ -- Garbage_Collected = False
+
+ -- The system releases all storage on program termination only,
+ -- but not other garbage collection occurs, so finalization calls
+ -- are ommitted only for outer level onjects can be omitted if
+ -- pragma Finalize_Storage_Only is used.
+
+ -- Garbage_Collected = True
+
+ -- The system provides full garbage collection, so it is never
+ -- necessary to release storage for controlled objects for which
+ -- a pragma Finalize_Storage_Only is used.
+
+ Garbage_Collected : constant Boolean := False;
+ -- The storage mode for this system (release on program exit)
+
+ ---------------------
+ -- Tasking Profile --
+ ---------------------
+
+ -- In the following sections, constant parameters are defined to
+ -- allow some optimizations and fine tuning within the tasking run time
+ -- based on restrictions on the tasking features.
+
+ ----------------------
+ -- Locking Strategy --
+ ----------------------
+
+ Single_Lock : constant Boolean := False;
+ -- Indicates whether a single lock should be used within the tasking
+ -- run-time to protect internal structures. If True, a single lock
+ -- will be used, meaning less locking/unlocking operations, but also
+ -- more global contention. In general, Single_Lock should be set to
+ -- True on single processor machines, and to False to multi-processor
+ -- systems, but this can vary from application to application and also
+ -- depends on the scheduling policy.
+
+ -------------------
+ -- Task Abortion --
+ -------------------
+
+ No_Abort : constant Boolean := False;
+ -- This constant indicates whether abort statements and asynchronous
+ -- transfer of control (ATC) are disallowed. If set to True, it is
+ -- assumed that neither construct is used, and the run time does not
+ -- need to defer/undefer abort and check for pending actions at
+ -- completion points. A value of True for No_Abort corresponds to:
+ -- pragma Restrictions (No_Abort_Statements);
+ -- pragma Restrictions (Max_Asynchronous_Select_Nesting => 0);
+
+ ----------------------
+ -- Dynamic Priority --
+ ----------------------
+
+ Dynamic_Priority_Support : constant Boolean := True;
+ -- This constant indicates whether dynamic changes of task priorities
+ -- are allowed (True means normal RM mode in which such changes are
+ -- allowed). In particular, if this is False, then we do not need to
+ -- poll for pending base priority changes at every abort completion
+ -- point. A value of False for Dynamic_Priority_Support corresponds
+ -- to pragma Restrictions (No_Dynamic_Priorities);
+
+ ---------------------
+ -- Task Attributes --
+ ---------------------
+
+ Default_Attribute_Count : constant := 4;
+ -- Number of pre-allocated Address-sized task attributes stored in the
+ -- task control block.
+
+ --------------------
+ -- Runtime Traces --
+ --------------------
+
+ Runtime_Traces : constant Boolean := False;
+ -- This constant indicates whether the runtime outputs traces to a
+ -- predefined output or not (True means that traces are output).
+ -- See System.Traces for more details.
+
+end System.Parameters;
diff --git a/gcc/ada/s-parame-linux.adb b/gcc/ada/s-parame-linux.adb
new file mode 100644
index 00000000000..9b17c158733
--- /dev/null
+++ b/gcc/ada/s-parame-linux.adb
@@ -0,0 +1,73 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . P A R A M E T E R S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1995-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the Linux (native) specific version
+
+package body System.Parameters is
+
+ -------------------------
+ -- Adjust_Storage_Size --
+ -------------------------
+
+ function Adjust_Storage_Size (Size : Size_Type) return Size_Type is
+ begin
+ if Size = Unspecified_Size then
+ return Default_Stack_Size;
+
+ elsif Size < Minimum_Stack_Size then
+ return Minimum_Stack_Size;
+
+ else
+ return Size;
+ end if;
+ end Adjust_Storage_Size;
+
+ ------------------------
+ -- Default_Stack_Size --
+ ------------------------
+
+ function Default_Stack_Size return Size_Type is
+ begin
+ return 2 * 1024 * 1024;
+ end Default_Stack_Size;
+
+ ------------------------
+ -- Minimum_Stack_Size --
+ ------------------------
+
+ function Minimum_Stack_Size return Size_Type is
+ begin
+ return 8 * 1024;
+ end Minimum_Stack_Size;
+
+end System.Parameters;
diff --git a/gcc/ada/s-parame-os2.adb b/gcc/ada/s-parame-os2.adb
new file mode 100644
index 00000000000..1ae7463618b
--- /dev/null
+++ b/gcc/ada/s-parame-os2.adb
@@ -0,0 +1,83 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . P A R A M E T E R S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1997-2002 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the OS/2 specific version - default stacksizes need to be large
+
+package body System.Parameters is
+
+ ------------------------
+ -- Default_Stack_Size --
+ ------------------------
+
+ function Default_Stack_Size return Size_Type is
+ begin
+ -- The default stack size for extra tasks is based on the
+ -- default stack size for the main task (8 MB) and for the heap
+ -- (32 MB).
+
+ -- In OS/2 it doesn't hurt to define large stacks, unless
+ -- the system is configured to commit all memory reservations.
+ -- This is not a default configuration however.
+
+ return 1024 * 1024;
+ end Default_Stack_Size;
+
+ ------------------------
+ -- Minimum_Stack_Size --
+ ------------------------
+
+ function Minimum_Stack_Size return Size_Type is
+ begin
+ -- System functions may need 8 kB of stack, so 12 kB seems a
+ -- good minimum.
+ return 12 * 1024;
+ end Minimum_Stack_Size;
+
+ -------------------------
+ -- Adjust_Storage_Size --
+ -------------------------
+
+ function Adjust_Storage_Size (Size : Size_Type) return Size_Type is
+ begin
+ if Size = Unspecified_Size then
+ return Default_Stack_Size;
+
+ elsif Size < Minimum_Stack_Size then
+ return Minimum_Stack_Size;
+
+ else
+ return Size;
+ end if;
+ end Adjust_Storage_Size;
+
+end System.Parameters;
diff --git a/gcc/ada/s-parame-solaris.adb b/gcc/ada/s-parame-solaris.adb
new file mode 100644
index 00000000000..847dda820e8
--- /dev/null
+++ b/gcc/ada/s-parame-solaris.adb
@@ -0,0 +1,80 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . P A R A M E T E R S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1998-2001 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the Solaris (native) specific version
+
+package body System.Parameters is
+
+ ------------------------
+ -- Default_Stack_Size --
+ ------------------------
+
+ function Default_Stack_Size return Size_Type is
+ begin
+ return 100_000;
+ end Default_Stack_Size;
+
+ ------------------------
+ -- Minimum_Stack_Size --
+ ------------------------
+
+ function Minimum_Stack_Size return Size_Type is
+
+ thr_min_stack : constant Size_Type := 1160;
+ -- hard coded value for Solaris 8 to avoid adding dependency on
+ -- libthread for every Ada program.
+ -- This value does not really matter anyway, since this is checked
+ -- and adjusted at the library level when creating a thread.
+
+ begin
+ return thr_min_stack;
+ end Minimum_Stack_Size;
+
+ -------------------------
+ -- Adjust_Storage_Size --
+ -------------------------
+
+ function Adjust_Storage_Size (Size : Size_Type) return Size_Type is
+ begin
+ if Size = Unspecified_Size then
+ return Default_Stack_Size;
+
+ elsif Size < Minimum_Stack_Size then
+ return Minimum_Stack_Size;
+
+ else
+ return Size;
+ end if;
+ end Adjust_Storage_Size;
+
+end System.Parameters;
diff --git a/gcc/ada/s-parame-vms-restrict.ads b/gcc/ada/s-parame-vms-restrict.ads
new file mode 100644
index 00000000000..d1d48188176
--- /dev/null
+++ b/gcc/ada/s-parame-vms-restrict.ads
@@ -0,0 +1,203 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . P A R A M E T E R S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1992-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the OpenVMS version for restricted tasking.
+
+-- Blank line intentional so that it lines up exactly with default.
+
+-- This package defines some system dependent parameters for GNAT. These
+-- are values that are referenced by the runtime library and are therefore
+-- relevant to the target machine.
+
+-- The parameters whose value is defined in the spec are not generally
+-- expected to be changed. If they are changed, it will be necessary to
+-- recompile the run-time library.
+
+-- The parameters which are defined by functions can be changed by modifying
+-- the body of System.Parameters in file s-parame.adb. A change to this body
+-- requires only rebinding and relinking of the application.
+
+-- Note: do not introduce any pragma Inline statements into this unit, since
+-- otherwise the relinking and rebinding capability would be deactivated.
+
+package System.Parameters is
+pragma Pure (Parameters);
+
+ ---------------------------------------
+ -- Task And Stack Allocation Control --
+ ---------------------------------------
+
+ type Task_Storage_Size is new Integer;
+ -- Type used in tasking units for task storage size
+
+ type Size_Type is new Task_Storage_Size;
+ -- Type used to provide task storage size to runtime
+
+ Unspecified_Size : constant Size_Type := Size_Type'First;
+ -- Value used to indicate that no size type is set
+
+ subtype Ratio is Size_Type range -1 .. 100;
+ Dynamic : constant Size_Type := -1;
+ -- The secondary stack ratio is a constant between 0 and 100 which
+ -- determines the percentage of the allocated task stack that is
+ -- used by the secondary stack (the rest being the primary stack).
+ -- The special value of minus one indicates that the secondary
+ -- stack is to be allocated from the heap instead.
+
+ Sec_Stack_Ratio : constant Ratio := Dynamic;
+ -- This constant defines the handling of the secondary stack
+
+ Sec_Stack_Dynamic : constant Boolean := Sec_Stack_Ratio = Dynamic;
+ -- Convenient Boolean for testing for dynamic secondary stack
+
+ function Default_Stack_Size return Size_Type;
+ -- Default task stack size used if none is specified
+
+ function Minimum_Stack_Size return Size_Type;
+ -- Minimum task stack size permitted
+
+ function Adjust_Storage_Size (Size : Size_Type) return Size_Type;
+ -- Given the storage size stored in the TCB, return the Storage_Size
+ -- value required by the RM for the Storage_Size attribute. The
+ -- required adjustment is as follows:
+ --
+ -- when Size = Unspecified_Size, return Default_Stack_Size
+ -- when Size < Minimum_Stack_Size, return Minimum_Stack_Size
+ -- otherwise return given Size
+
+ Default_Env_Stack_Size : constant Size_Type := 8_192_000;
+ -- Assumed size of the environment task, if no other information
+ -- is available. This value is used when stack checking is
+ -- enabled and no GNAT_STACK_LIMIT environment variable is set.
+
+ Stack_Grows_Down : constant Boolean := True;
+ -- This constant indicates whether the stack grows up (False) or
+ -- down (True) in memory as functions are called. It is used for
+ -- proper implementation of the stack overflow check.
+
+ ----------------------------------------------
+ -- Characteristics of types in Interfaces.C --
+ ----------------------------------------------
+
+ long_bits : constant := 32;
+ -- Number of bits in type long and unsigned_long. The normal convention
+ -- is that this is the same as type Long_Integer, but this is not true
+ -- of all targets. For example, in OpenVMS long /= Long_Integer.
+
+ ----------------------------------------------
+ -- Behavior of Pragma Finalize_Storage_Only --
+ ----------------------------------------------
+
+ -- Garbage_Collected is a Boolean constant whose value indicates the
+ -- effect of the pragma Finalize_Storage_Entry on a controlled type.
+
+ -- Garbage_Collected = False
+
+ -- The system releases all storage on program termination only,
+ -- but not other garbage collection occurs, so finalization calls
+ -- are ommitted only for outer level onjects can be omitted if
+ -- pragma Finalize_Storage_Only is used.
+
+ -- Garbage_Collected = True
+
+ -- The system provides full garbage collection, so it is never
+ -- necessary to release storage for controlled objects for which
+ -- a pragma Finalize_Storage_Only is used.
+
+ Garbage_Collected : constant Boolean := False;
+ -- The storage mode for this system (release on program exit)
+
+ ---------------------
+ -- Tasking Profile --
+ ---------------------
+
+ -- In the following sections, constant parameters are defined to
+ -- allow some optimizations and fine tuning within the tasking run time
+ -- based on restrictions on the tasking features.
+
+ ----------------------
+ -- Locking Strategy --
+ ----------------------
+
+ Single_Lock : constant Boolean := True;
+ -- Indicates whether a single lock should be used within the tasking
+ -- run-time to protect internal structures. If True, a single lock
+ -- will be used, meaning less locking/unlocking operations, but also
+ -- more global contention. In general, Single_Lock should be set to
+ -- True on single processor machines, and to False to multi-processor
+ -- systems, but this can vary from application to application and also
+ -- depends on the scheduling policy.
+
+ -------------------
+ -- Task Abortion --
+ -------------------
+
+ No_Abort : constant Boolean := True;
+ -- This constant indicates whether abort statements and asynchronous
+ -- transfer of control (ATC) are disallowed. If set to True, it is
+ -- assumed that neither construct is used, and the run time does not
+ -- need to defer/undefer abort and check for pending actions at
+ -- completion points. A value of True for No_Abort corresponds to:
+ -- pragma Restrictions (No_Abort_Statements);
+ -- pragma Restrictions (Max_Asynchronous_Select_Nesting => 0);
+
+ ----------------------
+ -- Dynamic Priority --
+ ----------------------
+
+ Dynamic_Priority_Support : constant Boolean := False;
+ -- This constant indicates whether dynamic changes of task priorities
+ -- are allowed (True means normal RM mode in which such changes are
+ -- allowed). In particular, if this is False, then we do not need to
+ -- poll for pending base priority changes at every abort completion
+ -- point. A value of False for Dynamic_Priority_Support corresponds
+ -- to pragma Restrictions (No_Dynamic_Priorities);
+
+ ---------------------
+ -- Task Attributes --
+ ---------------------
+
+ Default_Attribute_Count : constant := 4;
+ -- Number of pre-allocated Address-sized task attributes stored in the
+ -- task control block.
+
+ --------------------
+ -- Runtime Traces --
+ --------------------
+
+ Runtime_Traces : constant Boolean := False;
+ -- This constant indicates whether the runtime outputs traces to a
+ -- predefined output or not (True means that traces are output).
+ -- See System.Traces for more details.
+
+end System.Parameters;
diff --git a/gcc/ada/s-parame-vms.ads b/gcc/ada/s-parame-vms.ads
new file mode 100644
index 00000000000..5b41ab79ec6
--- /dev/null
+++ b/gcc/ada/s-parame-vms.ads
@@ -0,0 +1,202 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . P A R A M E T E R S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1992-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the OpenVMS version.
+-- Blank line intentional so that it lines up exactly with default.
+
+-- This package defines some system dependent parameters for GNAT. These
+-- are values that are referenced by the runtime library and are therefore
+-- relevant to the target machine.
+
+-- The parameters whose value is defined in the spec are not generally
+-- expected to be changed. If they are changed, it will be necessary to
+-- recompile the run-time library.
+
+-- The parameters which are defined by functions can be changed by modifying
+-- the body of System.Parameters in file s-parame.adb. A change to this body
+-- requires only rebinding and relinking of the application.
+
+-- Note: do not introduce any pragma Inline statements into this unit, since
+-- otherwise the relinking and rebinding capability would be deactivated.
+
+package System.Parameters is
+pragma Pure (Parameters);
+
+ ---------------------------------------
+ -- Task And Stack Allocation Control --
+ ---------------------------------------
+
+ type Task_Storage_Size is new Integer;
+ -- Type used in tasking units for task storage size
+
+ type Size_Type is new Task_Storage_Size;
+ -- Type used to provide task storage size to runtime
+
+ Unspecified_Size : constant Size_Type := Size_Type'First;
+ -- Value used to indicate that no size type is set
+
+ subtype Ratio is Size_Type range -1 .. 100;
+ Dynamic : constant Size_Type := -1;
+ -- The secondary stack ratio is a constant between 0 and 100 which
+ -- determines the percentage of the allocated task stack that is
+ -- used by the secondary stack (the rest being the primary stack).
+ -- The special value of minus one indicates that the secondary
+ -- stack is to be allocated from the heap instead.
+
+ Sec_Stack_Ratio : constant Ratio := Dynamic;
+ -- This constant defines the handling of the secondary stack
+
+ Sec_Stack_Dynamic : constant Boolean := Sec_Stack_Ratio = Dynamic;
+ -- Convenient Boolean for testing for dynamic secondary stack
+
+ function Default_Stack_Size return Size_Type;
+ -- Default task stack size used if none is specified
+
+ function Minimum_Stack_Size return Size_Type;
+ -- Minimum task stack size permitted
+
+ function Adjust_Storage_Size (Size : Size_Type) return Size_Type;
+ -- Given the storage size stored in the TCB, return the Storage_Size
+ -- value required by the RM for the Storage_Size attribute. The
+ -- required adjustment is as follows:
+ --
+ -- when Size = Unspecified_Size, return Default_Stack_Size
+ -- when Size < Minimum_Stack_Size, return Minimum_Stack_Size
+ -- otherwise return given Size
+
+ Default_Env_Stack_Size : constant Size_Type := 8_192_000;
+ -- Assumed size of the environment task, if no other information
+ -- is available. This value is used when stack checking is
+ -- enabled and no GNAT_STACK_LIMIT environment variable is set.
+
+ Stack_Grows_Down : constant Boolean := True;
+ -- This constant indicates whether the stack grows up (False) or
+ -- down (True) in memory as functions are called. It is used for
+ -- proper implementation of the stack overflow check.
+
+ ----------------------------------------------
+ -- Characteristics of types in Interfaces.C --
+ ----------------------------------------------
+
+ long_bits : constant := 32;
+ -- Number of bits in type long and unsigned_long. The normal convention
+ -- is that this is the same as type Long_Integer, but this is not true
+ -- of all targets. For example, in OpenVMS long /= Long_Integer.
+
+ ----------------------------------------------
+ -- Behavior of Pragma Finalize_Storage_Only --
+ ----------------------------------------------
+
+ -- Garbage_Collected is a Boolean constant whose value indicates the
+ -- effect of the pragma Finalize_Storage_Entry on a controlled type.
+
+ -- Garbage_Collected = False
+
+ -- The system releases all storage on program termination only,
+ -- but not other garbage collection occurs, so finalization calls
+ -- are ommitted only for outer level onjects can be omitted if
+ -- pragma Finalize_Storage_Only is used.
+
+ -- Garbage_Collected = True
+
+ -- The system provides full garbage collection, so it is never
+ -- necessary to release storage for controlled objects for which
+ -- a pragma Finalize_Storage_Only is used.
+
+ Garbage_Collected : constant Boolean := False;
+ -- The storage mode for this system (release on program exit)
+
+ ---------------------
+ -- Tasking Profile --
+ ---------------------
+
+ -- In the following sections, constant parameters are defined to
+ -- allow some optimizations and fine tuning within the tasking run time
+ -- based on restrictions on the tasking features.
+
+ ----------------------
+ -- Locking Strategy --
+ ----------------------
+
+ Single_Lock : constant Boolean := True;
+ -- Indicates whether a single lock should be used within the tasking
+ -- run-time to protect internal structures. If True, a single lock
+ -- will be used, meaning less locking/unlocking operations, but also
+ -- more global contention. In general, Single_Lock should be set to
+ -- True on single processor machines, and to False to multi-processor
+ -- systems, but this can vary from application to application and also
+ -- depends on the scheduling policy.
+
+ -------------------
+ -- Task Abortion --
+ -------------------
+
+ No_Abort : constant Boolean := False;
+ -- This constant indicates whether abort statements and asynchronous
+ -- transfer of control (ATC) are disallowed. If set to True, it is
+ -- assumed that neither construct is used, and the run time does not
+ -- need to defer/undefer abort and check for pending actions at
+ -- completion points. A value of True for No_Abort corresponds to:
+ -- pragma Restrictions (No_Abort_Statements);
+ -- pragma Restrictions (Max_Asynchronous_Select_Nesting => 0);
+
+ ----------------------
+ -- Dynamic Priority --
+ ----------------------
+
+ Dynamic_Priority_Support : constant Boolean := True;
+ -- This constant indicates whether dynamic changes of task priorities
+ -- are allowed (True means normal RM mode in which such changes are
+ -- allowed). In particular, if this is False, then we do not need to
+ -- poll for pending base priority changes at every abort completion
+ -- point. A value of False for Dynamic_Priority_Support corresponds
+ -- to pragma Restrictions (No_Dynamic_Priorities);
+
+ ---------------------
+ -- Task Attributes --
+ ---------------------
+
+ Default_Attribute_Count : constant := 4;
+ -- Number of pre-allocated Address-sized task attributes stored in the
+ -- task control block.
+
+ --------------------
+ -- Runtime Traces --
+ --------------------
+
+ Runtime_Traces : constant Boolean := False;
+ -- This constant indicates whether the runtime outputs traces to a
+ -- predefined output or not (True means that traces are output).
+ -- See System.Traces for more details.
+
+end System.Parameters;
diff --git a/gcc/ada/s-parame-vxworks.ads b/gcc/ada/s-parame-vxworks.ads
new file mode 100644
index 00000000000..774280f8307
--- /dev/null
+++ b/gcc/ada/s-parame-vxworks.ads
@@ -0,0 +1,203 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . P A R A M E T E R S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1992-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the default VxWorks version of the package.`
+
+-- This package defines some system dependent parameters for GNAT. These
+-- are values that are referenced by the runtime library and are therefore
+-- relevant to the target machine.
+
+-- The parameters whose value is defined in the spec are not generally
+-- expected to be changed. If they are changed, it will be necessary to
+-- recompile the run-time library.
+
+-- The parameters which are defined by functions can be changed by modifying
+-- the body of System.Parameters in file s-parame.adb. A change to this body
+-- requires only rebinding and relinking of the application.
+
+-- Note: do not introduce any pragma Inline statements into this unit, since
+-- otherwise the relinking and rebinding capability would be deactivated.
+
+package System.Parameters is
+pragma Pure (Parameters);
+
+ ---------------------------------------
+ -- Task And Stack Allocation Control --
+ ---------------------------------------
+
+ type Task_Storage_Size is new Integer;
+ -- Type used in tasking units for task storage size
+
+ type Size_Type is new Task_Storage_Size;
+ -- Type used to provide task storage size to runtime
+
+ Unspecified_Size : constant Size_Type := Size_Type'First;
+ -- Value used to indicate that no size type is set
+
+ subtype Ratio is Size_Type range -1 .. 100;
+ Dynamic : constant Size_Type := -1;
+ -- The secondary stack ratio is a constant between 0 and 100 which
+ -- determines the percentage of the allocated task stack that is
+ -- used by the secondary stack (the rest being the primary stack).
+ -- The special value of minus one indicates that the secondary
+ -- stack is to be allocated from the heap instead.
+
+ Sec_Stack_Ratio : constant Ratio := Dynamic;
+ -- This constant defines the handling of the secondary stack
+
+ Sec_Stack_Dynamic : constant Boolean := Sec_Stack_Ratio = Dynamic;
+ -- Convenient Boolean for testing for dynamic secondary stack
+
+ function Default_Stack_Size return Size_Type;
+ -- Default task stack size used if none is specified
+
+ function Minimum_Stack_Size return Size_Type;
+ -- Minimum task stack size permitted
+
+ function Adjust_Storage_Size (Size : Size_Type) return Size_Type;
+ -- Given the storage size stored in the TCB, return the Storage_Size
+ -- value required by the RM for the Storage_Size attribute. The
+ -- required adjustment is as follows:
+ --
+ -- when Size = Unspecified_Size, return Default_Stack_Size
+ -- when Size < Minimum_Stack_Size, return Minimum_Stack_Size
+ -- otherwise return given Size
+
+ Default_Env_Stack_Size : constant Size_Type := 14_336;
+ -- Assumed size of the environment task, if no other information
+ -- is available. This value is used when stack checking is
+ -- enabled and no GNAT_STACK_LIMIT environment variable is set.
+ -- This value is chosen as the VxWorks default stack size is 20kB,
+ -- and a little more than 4kB is necessary for the run time.
+
+ Stack_Grows_Down : constant Boolean := True;
+ -- This constant indicates whether the stack grows up (False) or
+ -- down (True) in memory as functions are called. It is used for
+ -- proper implementation of the stack overflow check.
+
+ ----------------------------------------------
+ -- Characteristics of types in Interfaces.C --
+ ----------------------------------------------
+
+ long_bits : constant := Long_Integer'Size;
+ -- Number of bits in type long and unsigned_long. The normal convention
+ -- is that this is the same as type Long_Integer, but this is not true
+ -- of all targets. For example, in OpenVMS long /= Long_Integer.
+
+ ----------------------------------------------
+ -- Behavior of Pragma Finalize_Storage_Only --
+ ----------------------------------------------
+
+ -- Garbage_Collected is a Boolean constant whose value indicates the
+ -- effect of the pragma Finalize_Storage_Entry on a controlled type.
+
+ -- Garbage_Collected = False
+
+ -- The system releases all storage on program termination only,
+ -- but not other garbage collection occurs, so finalization calls
+ -- are ommitted only for outer level onjects can be omitted if
+ -- pragma Finalize_Storage_Only is used.
+
+ -- Garbage_Collected = True
+
+ -- The system provides full garbage collection, so it is never
+ -- necessary to release storage for controlled objects for which
+ -- a pragma Finalize_Storage_Only is used.
+
+ Garbage_Collected : constant Boolean := False;
+ -- The storage mode for this system (release on program exit)
+
+ ---------------------
+ -- Tasking Profile --
+ ---------------------
+
+ -- In the following sections, constant parameters are defined to
+ -- allow some optimizations and fine tuning within the tasking run time
+ -- based on restrictions on the tasking features.
+
+ ----------------------
+ -- Locking Strategy --
+ ----------------------
+
+ Single_Lock : constant Boolean := False;
+ -- Indicates whether a single lock should be used within the tasking
+ -- run-time to protect internal structures. If True, a single lock
+ -- will be used, meaning less locking/unlocking operations, but also
+ -- more global contention. In general, Single_Lock should be set to
+ -- True on single processor machines, and to False to multi-processor
+ -- systems, but this can vary from application to application and also
+ -- depends on the scheduling policy.
+
+ -------------------
+ -- Task Abortion --
+ -------------------
+
+ No_Abort : constant Boolean := False;
+ -- This constant indicates whether abort statements and asynchronous
+ -- transfer of control (ATC) are disallowed. If set to True, it is
+ -- assumed that neither construct is used, and the run time does not
+ -- need to defer/undefer abort and check for pending actions at
+ -- completion points. A value of True for No_Abort corresponds to:
+ -- pragma Restrictions (No_Abort_Statements);
+ -- pragma Restrictions (Max_Asynchronous_Select_Nesting => 0);
+
+ ----------------------
+ -- Dynamic Priority --
+ ----------------------
+
+ Dynamic_Priority_Support : constant Boolean := True;
+ -- This constant indicates whether dynamic changes of task priorities
+ -- are allowed (True means normal RM mode in which such changes are
+ -- allowed). In particular, if this is False, then we do not need to
+ -- poll for pending base priority changes at every abort completion
+ -- point. A value of False for Dynamic_Priority_Support corresponds
+ -- to pragma Restrictions (No_Dynamic_Priorities);
+
+ ---------------------
+ -- Task Attributes --
+ ---------------------
+
+ Default_Attribute_Count : constant := 4;
+ -- Number of pre-allocated Address-sized task attributes stored in the
+ -- task control block.
+
+ --------------------
+ -- Runtime Traces --
+ --------------------
+
+ Runtime_Traces : constant Boolean := False;
+ -- This constant indicates whether the runtime outputs traces to a
+ -- predefined output or not (True means that traces are output).
+ -- See System.Traces for more details.
+
+end System.Parameters;
diff --git a/gcc/ada/s-parint.adb b/gcc/ada/s-parint.adb
index 0f0484df0e9..1174d75e565 100644
--- a/gcc/ada/s-parint.adb
+++ b/gcc/ada/s-parint.adb
@@ -7,7 +7,7 @@
-- B o d y --
-- (Dummy body for non-distributed case) --
-- --
--- Copyright (C) 1995-2001 Free Software Foundation, Inc. --
+-- Copyright (C) 1995-2004 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- --
@@ -162,20 +162,6 @@ package body System.Partition_Interface is
null;
end Get_Unique_Remote_Pointer;
- ------------
- -- Launch --
- ------------
-
- procedure Launch
- (Rsh_Command : in String;
- Name_Is_Host : in Boolean;
- General_Name : in String;
- Command_Line : in String)
- is
- begin
- null;
- end Launch;
-
-----------
-- Lower --
-----------
@@ -195,17 +181,6 @@ package body System.Partition_Interface is
return T;
end Lower;
- ------------------------------------
- -- Raise_Program_Error_For_E_4_18 --
- ------------------------------------
-
- procedure Raise_Program_Error_For_E_4_18 is
- begin
- Ada.Exceptions.Raise_Exception
- (Program_Error'Identity,
- "Illegal usage of remote access to class-wide type. See RM E.4(18)");
- end Raise_Program_Error_For_E_4_18;
-
-------------------------------------
-- Raise_Program_Error_Unknown_Tag --
-------------------------------------
diff --git a/gcc/ada/s-parint.ads b/gcc/ada/s-parint.ads
index d37325e5acf..cf0a8b396e5 100644
--- a/gcc/ada/s-parint.ads
+++ b/gcc/ada/s-parint.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1995-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 1995-2004 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- --
@@ -42,6 +42,9 @@ package System.Partition_Interface is
pragma Elaborate_Body;
+ type DSA_Implementation_Name is (No_DSA, GLADE_DSA, PolyORB_DSA);
+ DSA_Implementation : constant DSA_Implementation_Name := No_DSA;
+
type Subprogram_Id is new Natural;
-- This type is used exclusively by stubs
@@ -98,23 +101,6 @@ package System.Partition_Interface is
(Handler : in out RACW_Stub_Type_Access);
-- Get a unique pointer on a remote object
- procedure Launch
- (Rsh_Command : in String;
- Name_Is_Host : in Boolean;
- General_Name : in String;
- Command_Line : in String);
- -- General_Name represents the name of the machine or the name of the
- -- partition (depending on the value of Name_Is_Host). Command_Line
- -- holds the extra options that will be given on the command line.
- -- Rsh_Command is typically "rsh", that will be used to launch the
- -- other partition.
-
- procedure Raise_Program_Error_For_E_4_18;
- pragma No_Return (Raise_Program_Error_For_E_4_18);
- -- Raise Program_Error with an error message explaining why it has been
- -- raised. The rule in E.4 (18) is tricky and misleading for most users
- -- of the distributed systems annex.
-
procedure Raise_Program_Error_Unknown_Tag
(E : in Ada.Exceptions.Exception_Occurrence);
pragma No_Return (Raise_Program_Error_Unknown_Tag);
diff --git a/gcc/ada/s-proinf-irix-athread.adb b/gcc/ada/s-proinf-irix-athread.adb
new file mode 100644
index 00000000000..3e6bbc9557d
--- /dev/null
+++ b/gcc/ada/s-proinf-irix-athread.adb
@@ -0,0 +1,221 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . P R O G R A M _ I N F O --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1997-1999 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is an Irix (old pthread library) version of this package.
+
+-- This package contains the parameters used by the run-time system at
+-- program startup. These parameters are isolated in this package body to
+-- facilitate replacement by the end user.
+--
+-- To replace the default values, copy this source file into your build
+-- directory, edit the file to reflect your desired behavior, and recompile
+-- with the command:
+--
+-- % gcc -c -O2 -gnatpg s-proinf.adb
+--
+-- then relink your application as usual.
+--
+
+with GNAT.OS_Lib;
+
+package body System.Program_Info is
+
+ Kbytes : constant := 1024;
+
+ Default_Initial_Sproc_Count : constant := 0;
+ Default_Max_Sproc_Count : constant := 128;
+ Default_Sproc_Stack_Size : constant := 16#4000#;
+ Default_Stack_Guard_Pages : constant := 1;
+ Default_Default_Time_Slice : constant := 0.0;
+ Default_Default_Task_Stack : constant := 12 * Kbytes;
+ Default_Pthread_Sched_Signal : constant := 35;
+ Default_Pthread_Arena_Size : constant := 16#40000#;
+ Default_Os_Default_Priority : constant := 0;
+
+ -------------------------
+ -- Initial_Sproc_Count --
+ -------------------------
+
+ function Initial_Sproc_Count return Integer is
+
+ function sysmp (P1 : Integer) return Integer;
+ pragma Import (C, sysmp, "sysmp", "sysmp");
+
+ MP_NPROCS : constant := 1; -- # processor in complex
+
+ Pthread_Sproc_Count : constant GNAT.OS_Lib.String_Access :=
+ GNAT.OS_Lib.Getenv ("PTHREAD_SPROC_COUNT");
+
+ begin
+ if Pthread_Sproc_Count.all'Length = 0 then
+ return Default_Initial_Sproc_Count;
+
+ elsif Pthread_Sproc_Count.all = "AUTO" then
+ return sysmp (MP_NPROCS);
+
+ else
+ return Integer'Value (Pthread_Sproc_Count.all);
+ end if;
+ exception
+ when others =>
+ return Default_Initial_Sproc_Count;
+ end Initial_Sproc_Count;
+
+ ---------------------
+ -- Max_Sproc_Count --
+ ---------------------
+
+ function Max_Sproc_Count return Integer is
+ Pthread_Max_Sproc_Count : constant GNAT.OS_Lib.String_Access :=
+ GNAT.OS_Lib.Getenv ("PTHREAD_MAX_SPROC_COUNT");
+
+ begin
+ if Pthread_Max_Sproc_Count.all'Length = 0 then
+ return Default_Max_Sproc_Count;
+ else
+ return Integer'Value (Pthread_Max_Sproc_Count.all);
+ end if;
+ exception
+ when others =>
+ return Default_Max_Sproc_Count;
+ end Max_Sproc_Count;
+
+ ----------------------
+ -- Sproc_Stack_Size --
+ ----------------------
+
+ function Sproc_Stack_Size return Integer is
+ begin
+ return Default_Sproc_Stack_Size;
+ end Sproc_Stack_Size;
+
+ ------------------------
+ -- Default_Time_Slice --
+ ------------------------
+
+ function Default_Time_Slice return Duration is
+ Pthread_Time_Slice_Sec : constant GNAT.OS_Lib.String_Access :=
+ GNAT.OS_Lib.Getenv ("PTHREAD_TIME_SLICE_SEC");
+ Pthread_Time_Slice_Usec : constant GNAT.OS_Lib.String_Access :=
+ GNAT.OS_Lib.Getenv ("PTHREAD_TIME_SLICE_USEC");
+
+ Val_Sec, Val_Usec : Integer := 0;
+
+ begin
+ if Pthread_Time_Slice_Sec.all'Length /= 0 or
+ Pthread_Time_Slice_Usec.all'Length /= 0
+ then
+ if Pthread_Time_Slice_Sec.all'Length /= 0 then
+ Val_Sec := Integer'Value (Pthread_Time_Slice_Sec.all);
+ end if;
+
+ if Pthread_Time_Slice_Usec.all'Length /= 0 then
+ Val_Usec := Integer'Value (Pthread_Time_Slice_Usec.all);
+ end if;
+
+ return Duration (Val_Sec) + Duration (Val_Usec) / 1000.0;
+ else
+ return Default_Default_Time_Slice;
+ end if;
+
+ exception
+ when others =>
+ return Default_Default_Time_Slice;
+ end Default_Time_Slice;
+
+ ------------------------
+ -- Default_Task_Stack --
+ ------------------------
+
+ function Default_Task_Stack return Integer is
+ begin
+ return Default_Default_Task_Stack;
+ end Default_Task_Stack;
+
+ -----------------------
+ -- Stack_Guard_Pages --
+ -----------------------
+
+ function Stack_Guard_Pages return Integer is
+ Pthread_Stack_Guard_Pages : constant GNAT.OS_Lib.String_Access :=
+ GNAT.OS_Lib.Getenv ("PTHREAD_STACK_GUARD_PAGES");
+
+ begin
+ if Pthread_Stack_Guard_Pages.all'Length /= 0 then
+ return Integer'Value (Pthread_Stack_Guard_Pages.all);
+ else
+ return Default_Stack_Guard_Pages;
+ end if;
+ exception
+ when others =>
+ return Default_Stack_Guard_Pages;
+ end Stack_Guard_Pages;
+
+ --------------------------
+ -- Pthread_Sched_Signal --
+ --------------------------
+
+ function Pthread_Sched_Signal return Integer is
+ begin
+ return Default_Pthread_Sched_Signal;
+ end Pthread_Sched_Signal;
+
+ ------------------------
+ -- Pthread_Arena_Size --
+ ------------------------
+
+ function Pthread_Arena_Size return Integer is
+ Pthread_Arena_Size : constant GNAT.OS_Lib.String_Access :=
+ GNAT.OS_Lib.Getenv ("PTHREAD_ARENA_SIZE");
+
+ begin
+ if Pthread_Arena_Size.all'Length = 0 then
+ return Default_Pthread_Arena_Size;
+ else
+ return Integer'Value (Pthread_Arena_Size.all);
+ end if;
+ exception
+ when others =>
+ return Default_Pthread_Arena_Size;
+ end Pthread_Arena_Size;
+
+ -------------------------
+ -- Os_Default_Priority --
+ -------------------------
+
+ function Os_Default_Priority return Integer is
+ begin
+ return Default_Os_Default_Priority;
+ end Os_Default_Priority;
+
+end System.Program_Info;
diff --git a/gcc/ada/s-proinf-irix-athread.ads b/gcc/ada/s-proinf-irix-athread.ads
new file mode 100644
index 00000000000..a4259c3c916
--- /dev/null
+++ b/gcc/ada/s-proinf-irix-athread.ads
@@ -0,0 +1,96 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . P R O G R A M _ I N F O --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1997-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains the definitions and routines used as parameters
+-- to the run-time system at program startup for the SGI implementation.
+
+package System.Program_Info is
+
+ function Initial_Sproc_Count return Integer;
+ --
+ -- The number of sproc created at program startup for scheduling
+ -- threads.
+ --
+
+ function Max_Sproc_Count return Integer;
+ --
+ -- The maximum number of sprocs that can be created by the program
+ -- for servicing threads. This limit includes both the pre-created
+ -- sprocs and those explicitly created under program control.
+ --
+
+ function Sproc_Stack_Size return Integer;
+ --
+ -- The size, in bytes, of the sproc's initial stack.
+ --
+
+ function Default_Time_Slice return Duration;
+ --
+ -- The default time quanta for round-robin scheduling of threads of
+ -- equal priority. This default value can be overridden on a per-task
+ -- basis by specifying an alternate value via the implementation-defined
+ -- Task_Info pragma. See s-tasinf.ads for more information.
+ --
+
+ function Default_Task_Stack return Integer;
+ --
+ -- The default stack size for each created thread. This default value
+ -- can be overriden on a per-task basis by the language-defined
+ -- Storage_Size pragma.
+ --
+
+ function Stack_Guard_Pages return Integer;
+ --
+ -- The number of non-writable, guard pages to append to the bottom of
+ -- each thread's stack.
+ --
+
+ function Pthread_Sched_Signal return Integer;
+ --
+ -- The signal used by the Pthreads library to affect scheduling actions
+ -- in remote sprocs.
+ --
+
+ function Pthread_Arena_Size return Integer;
+ --
+ -- The size of the shared arena from which pthread locks are allocated.
+ -- See the usinit(3p) man page for more information on shared arenas.
+ --
+
+ function Os_Default_Priority return Integer;
+ --
+ -- The default Irix Non-Degrading priority for each sproc created to
+ -- service threads.
+ --
+
+end System.Program_Info;
diff --git a/gcc/ada/s-rident.ads b/gcc/ada/s-rident.ads
index 50229e82e6c..e3bdbff6876 100644
--- a/gcc/ada/s-rident.ads
+++ b/gcc/ada/s-rident.ads
@@ -57,7 +57,7 @@ package System.Rident is
-- The following cases are checked for consistency in the binder
- (Boolean_Entry_Barriers, -- GNAT (Ravenscar)
+ (Simple_Barriers, -- GNAT (Ravenscar)
No_Abort_Statements, -- (RM D.7(5), H.4(3))
No_Access_Subprograms, -- (RM H.4(17))
No_Allocators, -- (RM H.4(7))
@@ -66,7 +66,7 @@ package System.Rident is
No_Delay, -- (RM H.4(21))
No_Direct_Boolean_Operators, -- GNAT
No_Dispatch, -- (RM H.4(19))
- No_Dynamic_Interrupts, -- GNAT
+ No_Dynamic_Attachment, -- GNAT
No_Dynamic_Priorities, -- (RM D.9(9))
No_Enumeration_Maps, -- GNAT
No_Entry_Calls_In_Elaboration_Code, -- GNAT
@@ -144,7 +144,7 @@ package System.Rident is
-- between different non-zero values.
Max_Asynchronous_Select_Nesting, -- (RM D.7(18), H.4(3))
- Max_Entry_Queue_Depth, -- GNAT
+ Max_Entry_Queue_Length, -- GNAT
-- The remaining entries are not checked at compile/bind time
@@ -154,19 +154,22 @@ package System.Rident is
-- Synonyms permitted for historical purposes of compatibility
- -- No_Requeue synonym for No_Requeue_Statements
- -- No_Task_Attributes synonym for No_Task_Attributes_Package
+ -- Boolean_Entry_Barriers synonym for Simple_Barriers
+ -- Max_Entry_Queue_Depth synonym for Max_Entry_Queue_Length
+ -- No_Dynamic_Interrupts synonym for No_Dynamic_Attachment
+ -- No_Requeue synonym for No_Requeue_Statements
+ -- No_Task_Attributes synonym for No_Task_Attributes_Package
subtype All_Restrictions is Restriction_Id range
- Boolean_Entry_Barriers .. Max_Storage_At_Blocking;
+ Simple_Barriers .. Max_Storage_At_Blocking;
-- All restrictions (excluding only Not_A_Restriction_Id)
subtype All_Boolean_Restrictions is Restriction_Id range
- Boolean_Entry_Barriers .. No_Elaboration_Code;
+ Simple_Barriers .. No_Elaboration_Code;
-- All restrictions which do not take a parameter
subtype Partition_Boolean_Restrictions is All_Boolean_Restrictions range
- Boolean_Entry_Barriers .. Static_Storage_Size;
+ Simple_Barriers .. Static_Storage_Size;
-- Boolean restrictions that are checked for partition consistency.
-- Note that all parameter restrictions are checked for partition
-- consistency by default, so this distinction is only needed in the
@@ -186,7 +189,7 @@ package System.Rident is
subtype Checked_Parameter_Restrictions is
All_Parameter_Restrictions range
- Max_Protected_Entries .. Max_Entry_Queue_Depth;
+ Max_Protected_Entries .. Max_Entry_Queue_Length;
-- These are the parameter restrictions that can be at least partially
-- checked at compile/binder time. Minimally, the compiler can detect
-- violations of a restriction pragma with a value of zero reliably.
@@ -213,7 +216,7 @@ package System.Rident is
subtype Checked_Zero_Parameter_Restrictions is
Checked_Parameter_Restrictions range
- Max_Asynchronous_Select_Nesting .. Max_Entry_Queue_Depth;
+ Max_Asynchronous_Select_Nesting .. Max_Entry_Queue_Length;
-- Restrictions with parameters where the compiler can detect the use of
-- the feature, and hence violations of a restriction specifying a value
-- of zero, but cannot detect specific values other than zero/nonzero.
diff --git a/gcc/ada/s-rpc.adb b/gcc/ada/s-rpc.adb
index 33ab366f278..ba4d0d9f1f6 100644
--- a/gcc/ada/s-rpc.adb
+++ b/gcc/ada/s-rpc.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2002 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -43,13 +43,6 @@ with Ada.Exceptions; use Ada.Exceptions;
package body System.RPC is
- GNAT : constant Boolean := True;
- pragma Unreferenced (GNAT);
- -- This dummy entity allows the compiler to recognize that this is the
- -- version of this package that is supplied by GNAT, not by the user.
- -- This is used to cause a compile time error if an attempt is made to
- -- use features in System.RPC that are only available from a true PCS.
-
CRLF : constant String := ASCII.CR & ASCII.LF;
Msg : constant String :=
diff --git a/gcc/ada/s-stalib.ads b/gcc/ada/s-stalib.ads
index 84bf0b9e737..c2865a95dbf 100644
--- a/gcc/ada/s-stalib.ads
+++ b/gcc/ada/s-stalib.ads
@@ -97,7 +97,7 @@ package System.Standard_Library is
type Exception_Data_Ptr is access all Exception_Data;
-- An equivalent of Exception_Id that is public
- type Exception_Code is mod 2 ** 32;
+ type Exception_Code is mod 2 ** Integer'Size;
-- A scalar value bound to some exception data. Typically used for
-- imported or exported exceptions on VMS. Having a separate type for this
-- is useful to enforce consistency throughout the various run-time units
diff --git a/gcc/ada/s-stchop-vxworks.adb b/gcc/ada/s-stchop-vxworks.adb
new file mode 100644
index 00000000000..b19bb56f274
--- /dev/null
+++ b/gcc/ada/s-stchop-vxworks.adb
@@ -0,0 +1,255 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . S T A C K _ C H E C K I N G . O P E R A T I O N S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1999-2004 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- --
+-- 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, 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, --
+-- 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 is the VxWorks version of this package.
+-- This file should be kept synchronized with the general implementation
+-- provided by s-stchop.adb.
+
+pragma Restrictions (No_Elaboration_Code);
+-- We want to guarantee the absence of elaboration code because the
+-- binder does not handle references to this package.
+
+with Ada.Exceptions;
+
+with System.Storage_Elements; use System.Storage_Elements;
+with System.Parameters; use System.Parameters;
+with System.Soft_Links;
+with Interfaces.C;
+with System.OS_Interface;
+
+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:
+ -- * defining INCLUDE_SHOW_ROUTINES in config.h when using
+ -- configuration header files, or
+ -- * selecting INCLUDE_TASK_SHOW when using the Tornado project
+ -- facility.
+
+ function Set_Stack_Info (Stack : access Stack_Access) return Stack_Access;
+
+ -- The function Set_Stack_Info is the actual function that updates
+ -- the cache containing a pointer to the Stack_Info. It may also
+ -- be used for detecting asynchronous abort in combination with
+ -- Invalidate_Self_Cache.
+
+ -- Set_Stack_Info should do the following things in order:
+ -- 1) Get the Stack_Access value for the current task
+ -- 2) Set Stack.all to the value obtained in 1)
+ -- 3) Optionally Poll to check for asynchronous abort
+
+ -- This order is important because if at any time a write to
+ -- the stack cache is pending, that write should be followed
+ -- by a Poll to prevent loosing signals.
+
+ -- Note: This function must be compiled with Polling turned off
+
+ -- Note: on systems like VxWorks and OS/2 with real thread-local storage,
+ -- Set_Stack_Info should return an access value for such local
+ -- storage. In those cases the cache will always be up-to-date.
+
+ -- The following constants should be imported from some system-specific
+ -- constants package. The constants must be static for performance reasons.
+
+ ----------------------------
+ -- Invalidate_Stack_Cache --
+ ----------------------------
+
+ procedure Invalidate_Stack_Cache (Any_Stack : Stack_Access) is
+ pragma Warnings (Off, Any_Stack);
+ begin
+ Cache := Null_Stack;
+ end Invalidate_Stack_Cache;
+
+ --------------------
+ -- Set_Stack_Info --
+ --------------------
+
+ function Set_Stack_Info
+ (Stack : access Stack_Access) return Stack_Access
+ is
+
+ -- Task descriptor that is handled internally by the VxWorks kernel
+ type Task_Descriptor is record
+ T_Id : Interfaces.C.int; -- task identifier
+ Td_Name : System.Address; -- task name
+ Td_Priority : Interfaces.C.int; -- task priority
+ Td_Status : Interfaces.C.int; -- task status
+ Td_Options : Interfaces.C.int; -- task option bits (see below)
+ Td_Entry : System.Address; -- original entry point of task
+ Td_Sp : System.Address; -- saved stack pointer
+ Td_PStackBase : System.Address; -- the bottom of the stack
+ Td_PStackLimit : System.Address; -- the effective end of the stack
+ Td_PStackEnd : System.Address; -- the actual end of the stack
+ Td_StackSize : Interfaces.C.int; -- size of stack in bytes
+ Td_StackCurrent : Interfaces.C.int; -- current stack usage in bytes
+ Td_StackHigh : Interfaces.C.int; -- maximum stack usage in bytes
+ Td_StackMargin : Interfaces.C.int; -- current stack margin in bytes
+ Td_ErrorStatus : Interfaces.C.int; -- most recent task error status
+ Td_Delay : Interfaces.C.int; -- delay/timeout ticks
+ end record;
+
+ -- This VxWorks procedure fills in a specified task descriptor
+ -- for a specified task.
+ procedure TaskInfoGet (T_Id : System.OS_Interface.t_id;
+ Task_Desc : access Task_Descriptor);
+ pragma Import (C, TaskInfoGet, "taskInfoGet");
+
+ My_Stack : Stack_Access;
+ Task_Desc : aliased Task_Descriptor;
+
+ begin
+ -- The order of steps 1 .. 3 is important, see specification.
+
+ -- 1) Get the Stack_Access value for the current task
+
+ My_Stack := Soft_Links.Get_Stack_Info.all;
+
+ if My_Stack.Base = Null_Address then
+
+ -- First invocation. Ask the VxWorks kernel about stack
+ -- values.
+ TaskInfoGet (System.OS_Interface.taskIdSelf, Task_Desc'Access);
+
+ My_Stack.Size := System.Storage_Elements.Storage_Offset
+ (Task_Desc.Td_StackSize);
+ My_Stack.Base := Task_Desc.Td_PStackBase;
+ My_Stack.Limit := Task_Desc.Td_PStackLimit;
+
+ end if;
+
+ -- 2) Set Stack.all to the value obtained in 1)
+
+ Stack.all := My_Stack;
+
+ -- 3) Optionally Poll to check for asynchronous abort
+
+ if Soft_Links.Check_Abort_Status.all /= 0 then
+ raise Standard'Abort_Signal;
+ end if;
+
+ return My_Stack; -- Never trust the cached value, but return local copy!
+ end Set_Stack_Info;
+
+ --------------------
+ -- Set_Stack_Size --
+ --------------------
+
+ -- Specify the stack size for the current frame.
+
+ procedure Set_Stack_Size
+ (Stack_Size : System.Storage_Elements.Storage_Offset)
+ is
+ My_Stack : Stack_Access;
+ Frame_Address : constant System.Address := My_Stack'Address;
+
+ begin
+ My_Stack := Stack_Check (Frame_Address);
+
+ if Stack_Grows_Down then
+ My_Stack.Limit := My_Stack.Base - Stack_Size;
+ else
+ My_Stack.Limit := My_Stack.Base + Stack_Size;
+ end if;
+ end Set_Stack_Size;
+
+ -----------------
+ -- Stack_Check --
+ -----------------
+
+ function Stack_Check
+ (Stack_Address : System.Address) return Stack_Access
+ is
+ type Frame_Marker is null record;
+ Marker : Frame_Marker;
+ Cached_Stack : constant Stack_Access := Cache;
+ Frame_Address : constant System.Address := Marker'Address;
+
+ begin
+ -- This function first does a "cheap" check which is correct
+ -- if it succeeds. In case of failure, the full check is done.
+ -- Ideally the cheap check should be done in an optimized manner,
+ -- or be inlined.
+
+ if (Stack_Grows_Down and then
+ (Frame_Address <= Cached_Stack.Base
+ and
+ Stack_Address > Cached_Stack.Limit))
+ or else
+ (not Stack_Grows_Down and then
+ (Frame_Address >= Cached_Stack.Base
+ and
+ Stack_Address < Cached_Stack.Limit))
+ then
+ -- Cached_Stack is valid as it passed the stack check
+ return Cached_Stack;
+ end if;
+
+ Full_Check :
+ declare
+ My_Stack : constant Stack_Access := Set_Stack_Info (Cache'Access);
+ -- At this point Stack.all might already be invalid, so
+ -- it is essential to use our local copy of Stack!
+
+ begin
+ if (Stack_Grows_Down and then
+ Stack_Address < My_Stack.Limit)
+ or else
+ (not Stack_Grows_Down and then
+ Stack_Address > My_Stack.Limit)
+ then
+ Ada.Exceptions.Raise_Exception
+ (E => Storage_Error'Identity,
+ Message => "stack overflow detected");
+ end if;
+
+ return My_Stack;
+ end Full_Check;
+ end Stack_Check;
+
+ ------------------------
+ -- Update_Stack_Cache --
+ ------------------------
+
+ procedure Update_Stack_Cache (Stack : Stack_Access) is
+ begin
+ if not Multi_Processor then
+ Cache := Stack;
+ end if;
+ end Update_Stack_Cache;
+
+end System.Stack_Checking.Operations;
diff --git a/gcc/ada/s-stoele.adb b/gcc/ada/s-stoele.adb
index fc69d1e1db8..cf81d579a9e 100644
--- a/gcc/ada/s-stoele.adb
+++ b/gcc/ada/s-stoele.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992,1993,1994 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -43,31 +43,33 @@ package body System.Storage_Elements is
function "+" (Left : Address; Right : Storage_Offset) return Address is
begin
- return Left + To_Address (Right);
+ return To_Address (To_Integer (Left) + To_Integer (To_Address (Right)));
end "+";
function "+" (Left : Storage_Offset; Right : Address) return Address is
begin
- return To_Address (Left) + Right;
+ return To_Address (To_Integer (To_Address (Left)) + To_Integer (Right));
end "+";
function "-" (Left : Address; Right : Storage_Offset) return Address is
begin
- return Left - To_Address (Right);
+ return To_Address (To_Integer (Left) - To_Integer (To_Address (Right)));
end "-";
function "-" (Left, Right : Address) return Storage_Offset is
begin
- return To_Offset (Left - Right);
+ return To_Offset (To_Address (To_Integer (Left) - To_Integer (Right)));
end "-";
function "mod" (Left : Address; Right : Storage_Offset)
return Storage_Offset is
begin
if Right >= 0 then
- return Storage_Offset (Address'(Left mod Address (Right)));
+ return Storage_Offset
+ (To_Integer (Left) mod Integer_Address (Right));
else
- return -Storage_Offset (Address'(Left mod Address (-Right)));
+ return -Storage_Offset
+ (To_Integer (Left) mod Integer_Address (-Right));
end if;
end "mod";
diff --git a/gcc/ada/s-stoele.ads b/gcc/ada/s-stoele.ads
index 535813852b0..1799a7e5476 100644
--- a/gcc/ada/s-stoele.ads
+++ b/gcc/ada/s-stoele.ads
@@ -51,12 +51,8 @@ pragma Pure (Storage_Elements);
-- and it would be unsafe to treat such functions as pure.
type Storage_Offset is range
- -(2 ** (Standard."-" (Standard'Address_Size, 1))) ..
- +(2 ** (Standard."-" (Standard'Address_Size, 1))) - 1;
-
- -- Note: the reason for the qualification of "-" here by Standard is
- -- that we have a current bug in GNAT that otherwise causes a bogus
- -- ambiguity when this unit is analyzed in an Rtsfind context.
+ -(2 ** (Integer'(Standard'Address_Size) - 1)) ..
+ +(2 ** (Integer'(Standard'Address_Size) - 1)) - Long_Long_Integer'(1);
subtype Storage_Count is Storage_Offset range 0 .. Storage_Offset'Last;
diff --git a/gcc/ada/s-taprop-dummy.adb b/gcc/ada/s-taprop-dummy.adb
new file mode 100644
index 00000000000..365b0d911d3
--- /dev/null
+++ b/gcc/ada/s-taprop-dummy.adb
@@ -0,0 +1,438 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S . O P E R A T I O N S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2002, 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- --
+-- 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, 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, --
+-- 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 is a no tasking version of this package
+
+-- This package contains all the GNULL primitives that interface directly
+-- with the underlying OS.
+
+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.Tasking;
+-- used for Ada_Task_Control_Block
+-- Task_ID
+
+with System.Error_Reporting;
+-- used for Shutdown
+
+package body System.Task_Primitives.Operations is
+
+ use System.Tasking;
+ use System.Parameters;
+
+ pragma Warnings (Off);
+ -- Turn off warnings since so many unreferenced parameters
+
+ -----------------
+ -- Stack_Guard --
+ -----------------
+
+ procedure Stack_Guard (T : ST.Task_ID; On : Boolean) is
+ begin
+ null;
+ end Stack_Guard;
+
+ --------------------
+ -- Get_Thread_Id --
+ --------------------
+
+ function Get_Thread_Id (T : ST.Task_ID) return OSI.Thread_Id is
+ begin
+ return OSI.Thread_Id (T.Common.LL.Thread);
+ end Get_Thread_Id;
+
+ ----------
+ -- Self --
+ ----------
+
+ function Self return Task_ID is
+ begin
+ return Null_Task;
+ end Self;
+
+ ---------------------
+ -- Initialize_Lock --
+ ---------------------
+
+ procedure Initialize_Lock
+ (Prio : System.Any_Priority;
+ L : access Lock)
+ is
+ begin
+ null;
+ end Initialize_Lock;
+
+ procedure Initialize_Lock (L : access RTS_Lock; Level : Lock_Level) is
+ begin
+ null;
+ end Initialize_Lock;
+
+ -------------------
+ -- Finalize_Lock --
+ -------------------
+
+ procedure Finalize_Lock (L : access Lock) is
+ begin
+ null;
+ end Finalize_Lock;
+
+ procedure Finalize_Lock (L : access RTS_Lock) is
+ begin
+ null;
+ end Finalize_Lock;
+
+ ----------------
+ -- Write_Lock --
+ ----------------
+
+ procedure Write_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ begin
+ Ceiling_Violation := False;
+ end Write_Lock;
+
+ procedure Write_Lock
+ (L : access RTS_Lock;
+ Global_Lock : Boolean := False)
+ is
+ begin
+ null;
+ end Write_Lock;
+
+ procedure Write_Lock (T : Task_ID) is
+ begin
+ null;
+ end Write_Lock;
+
+ ---------------
+ -- Read_Lock --
+ ---------------
+
+ procedure Read_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ begin
+ Ceiling_Violation := False;
+ end Read_Lock;
+
+ ------------
+ -- Unlock --
+ ------------
+
+ procedure Unlock (L : access Lock) is
+ begin
+ null;
+ end Unlock;
+
+ procedure Unlock (L : access RTS_Lock; Global_Lock : Boolean := False) is
+ begin
+ null;
+ end Unlock;
+
+ procedure Unlock (T : Task_ID) is
+ begin
+ null;
+ end Unlock;
+
+ -----------
+ -- Sleep --
+ -----------
+
+ procedure Sleep (Self_ID : Task_ID; Reason : System.Tasking.Task_States) is
+ begin
+ null;
+ end Sleep;
+
+ -----------------
+ -- Timed_Sleep --
+ -----------------
+
+ procedure Timed_Sleep
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes;
+ Reason : System.Tasking.Task_States;
+ Timedout : out Boolean;
+ Yielded : out Boolean) is
+ begin
+ Timedout := False;
+ Yielded := False;
+ end Timed_Sleep;
+
+ -----------------
+ -- Timed_Delay --
+ -----------------
+
+ procedure Timed_Delay
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes) is
+ begin
+ null;
+ end Timed_Delay;
+
+ ---------------------
+ -- Monotonic_Clock --
+ ---------------------
+
+ function Monotonic_Clock return Duration is
+ begin
+ return 0.0;
+ end Monotonic_Clock;
+
+ -------------------
+ -- RT_Resolution --
+ -------------------
+
+ function RT_Resolution return Duration is
+ begin
+ return 10#1.0#E-6;
+ end RT_Resolution;
+
+ ------------
+ -- Wakeup --
+ ------------
+
+ procedure Wakeup (T : Task_ID; Reason : System.Tasking.Task_States) is
+ begin
+ null;
+ end Wakeup;
+
+ ------------------
+ -- Set_Priority --
+ ------------------
+
+ procedure Set_Priority
+ (T : Task_ID;
+ Prio : System.Any_Priority;
+ Loss_Of_Inheritance : Boolean := False) is
+ begin
+ null;
+ end Set_Priority;
+
+ ------------------
+ -- Get_Priority --
+ ------------------
+
+ function Get_Priority (T : Task_ID) return System.Any_Priority is
+ begin
+ return 0;
+ end Get_Priority;
+
+ ----------------
+ -- Enter_Task --
+ ----------------
+
+ procedure Enter_Task (Self_ID : Task_ID) is
+ begin
+ null;
+ end Enter_Task;
+
+ --------------
+ -- New_ATCB --
+ --------------
+
+ function New_ATCB (Entry_Num : Task_Entry_Index) return Task_ID is
+ begin
+ return new Ada_Task_Control_Block (Entry_Num);
+ end New_ATCB;
+
+ -------------------
+ -- Is_Valid_Task --
+ -------------------
+
+ function Is_Valid_Task return Boolean is
+ begin
+ return False;
+ end Is_Valid_Task;
+
+ -----------------------------
+ -- Register_Foreign_Thread --
+ -----------------------------
+
+ function Register_Foreign_Thread return Task_ID is
+ begin
+ return null;
+ end Register_Foreign_Thread;
+
+ ----------------------
+ -- Initialize_TCB --
+ ----------------------
+
+ procedure Initialize_TCB (Self_ID : Task_ID; Succeeded : out Boolean) is
+ begin
+ Succeeded := False;
+ end Initialize_TCB;
+
+ -----------------
+ -- Create_Task --
+ -----------------
+
+ procedure Create_Task
+ (T : Task_ID;
+ Wrapper : System.Address;
+ Stack_Size : System.Parameters.Size_Type;
+ Priority : System.Any_Priority;
+ Succeeded : out Boolean) is
+ begin
+ Succeeded := False;
+ end Create_Task;
+
+ ------------------
+ -- Finalize_TCB --
+ ------------------
+
+ procedure Finalize_TCB (T : Task_ID) is
+ begin
+ null;
+ end Finalize_TCB;
+
+ ---------------
+ -- Exit_Task --
+ ---------------
+
+ procedure Exit_Task is
+ begin
+ null;
+ end Exit_Task;
+
+ ----------------
+ -- Abort_Task --
+ ----------------
+
+ procedure Abort_Task (T : Task_ID) is
+ begin
+ null;
+ end Abort_Task;
+
+ -----------
+ -- Yield --
+ -----------
+
+ procedure Yield (Do_Yield : Boolean := True) is
+ begin
+ null;
+ end Yield;
+
+ ----------------
+ -- Check_Exit --
+ ----------------
+
+ -- Dummy versions. The only currently working versions is for solaris
+ -- (native).
+
+ function Check_Exit (Self_ID : ST.Task_ID) return Boolean is
+ begin
+ return True;
+ end Check_Exit;
+
+ --------------------
+ -- Check_No_Locks --
+ --------------------
+
+ function Check_No_Locks (Self_ID : ST.Task_ID) return Boolean is
+ begin
+ return True;
+ end Check_No_Locks;
+
+ ----------------------
+ -- Environment_Task --
+ ----------------------
+
+ function Environment_Task return Task_ID is
+ begin
+ return null;
+ end Environment_Task;
+
+ --------------
+ -- Lock_RTS --
+ --------------
+
+ procedure Lock_RTS is
+ begin
+ null;
+ end Lock_RTS;
+
+ ----------------
+ -- Unlock_RTS --
+ ----------------
+
+ procedure Unlock_RTS is
+ begin
+ null;
+ end Unlock_RTS;
+
+ ------------------
+ -- Suspend_Task --
+ ------------------
+
+ function Suspend_Task
+ (T : ST.Task_ID;
+ Thread_Self : OSI.Thread_Id)
+ return Boolean
+ is
+ begin
+ return False;
+ end Suspend_Task;
+
+ -----------------
+ -- Resume_Task --
+ -----------------
+
+ function Resume_Task
+ (T : ST.Task_ID;
+ Thread_Self : OSI.Thread_Id)
+ return Boolean
+ is
+ begin
+ return False;
+ end Resume_Task;
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize (Environment_Task : Task_ID) is
+ begin
+ null;
+ end Initialize;
+
+ No_Tasking : Boolean;
+
+begin
+ -- Can't raise an exception because target independent packages try to
+ -- do an Abort_Defer, which gets a memory fault.
+
+ No_Tasking :=
+ System.Error_Reporting.Shutdown
+ ("Tasking not implemented on this configuration");
+end System.Task_Primitives.Operations;
diff --git a/gcc/ada/s-taprop-hpux-dce.adb b/gcc/ada/s-taprop-hpux-dce.adb
new file mode 100644
index 00000000000..1aaf3c26c56
--- /dev/null
+++ b/gcc/ada/s-taprop-hpux-dce.adb
@@ -0,0 +1,1061 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S . O P E R A T I O N S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2004, 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- --
+-- 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, 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, --
+-- 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 is a HP-UX DCE threads (HPUX 10) version of this package
+
+-- This package contains all the GNULL primitives that interface directly
+-- with the underlying OS.
+
+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.Tasking.Debug;
+-- used for Known_Tasks
+
+with Interfaces.C;
+-- used for int
+-- size_t
+
+with System.Interrupt_Management;
+-- used for Keep_Unmasked
+-- Abort_Task_Interrupt
+-- Interrupt_ID
+
+with System.Interrupt_Management.Operations;
+-- used for Set_Interrupt_Mask
+-- All_Tasks_Mask
+pragma Elaborate_All (System.Interrupt_Management.Operations);
+
+with System.Parameters;
+-- used for Size_Type
+
+with System.Task_Primitives.Interrupt_Operations;
+-- used for Get_Interrupt_ID
+
+with System.Tasking;
+-- used for Ada_Task_Control_Block
+-- Task_ID
+
+with System.Soft_Links;
+-- used for Defer/Undefer_Abort
+
+-- Note that we do not use System.Tasking.Initialization directly since
+-- this is a higher level package that we shouldn't depend on. For example
+-- when using the restricted run time, it is replaced by
+-- System.Tasking.Restricted.Initialization
+
+with System.OS_Primitives;
+-- used for Delay_Modes
+
+with Unchecked_Conversion;
+with Unchecked_Deallocation;
+
+package body System.Task_Primitives.Operations is
+
+ use System.Tasking.Debug;
+ use System.Tasking;
+ use Interfaces.C;
+ use System.OS_Interface;
+ use System.Parameters;
+ use System.OS_Primitives;
+
+ package PIO renames System.Task_Primitives.Interrupt_Operations;
+ package SSL renames System.Soft_Links;
+
+ ------------------
+ -- Local Data --
+ ------------------
+
+ -- The followings are logically constants, but need to be initialized
+ -- at run time.
+
+ Single_RTS_Lock : aliased RTS_Lock;
+ -- This is a lock to allow only one thread of control in the RTS at
+ -- a time; it is used to execute in mutual exclusion from all other tasks.
+ -- Used mainly in Single_Lock mode, but also to protect All_Tasks_List
+
+ ATCB_Key : aliased pthread_key_t;
+ -- Key used to find the Ada Task_ID associated with a thread
+
+ Environment_Task_ID : Task_ID;
+ -- A variable to hold Task_ID for the environment task.
+
+ Unblocked_Signal_Mask : aliased sigset_t;
+ -- The set of signals that should unblocked in all tasks
+
+ Time_Slice_Val : Integer;
+ pragma Import (C, Time_Slice_Val, "__gl_time_slice_val");
+
+ Dispatching_Policy : Character;
+ pragma Import (C, Dispatching_Policy, "__gl_task_dispatching_policy");
+
+ -- Note: the reason that Locking_Policy is not needed is that this
+ -- is not implemented for DCE threads. The HPUX 10 port is at this
+ -- stage considered dead, and no further work is planned on it.
+
+ FIFO_Within_Priorities : constant Boolean := Dispatching_Policy = 'F';
+ -- Indicates whether FIFO_Within_Priorities is set.
+
+ Foreign_Task_Elaborated : aliased Boolean := True;
+ -- Used to identified fake tasks (i.e., non-Ada Threads).
+
+ --------------------
+ -- Local Packages --
+ --------------------
+
+ package Specific is
+
+ procedure Initialize (Environment_Task : Task_ID);
+ pragma Inline (Initialize);
+ -- Initialize various data needed by this package.
+
+ function Is_Valid_Task return Boolean;
+ pragma Inline (Is_Valid_Task);
+ -- Does the executing thread have a TCB?
+
+ procedure Set (Self_Id : Task_ID);
+ pragma Inline (Set);
+ -- Set the self id for the current task.
+
+ function Self return Task_ID;
+ pragma Inline (Self);
+ -- Return a pointer to the Ada Task Control Block of the calling task.
+
+ end Specific;
+
+ package body Specific is separate;
+ -- The body of this package is target specific.
+
+ ---------------------------------
+ -- Support for foreign threads --
+ ---------------------------------
+
+ function Register_Foreign_Thread (Thread : Thread_Id) return Task_ID;
+ -- Allocate and Initialize a new ATCB for the current Thread.
+
+ function Register_Foreign_Thread
+ (Thread : Thread_Id) return Task_ID is separate;
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ procedure Abort_Handler (Sig : Signal);
+
+ function To_Address is new Unchecked_Conversion (Task_ID, System.Address);
+
+ -------------------
+ -- Abort_Handler --
+ -------------------
+
+ procedure Abort_Handler (Sig : Signal) is
+ pragma Unreferenced (Sig);
+
+ Self_Id : constant Task_ID := Self;
+ Result : Interfaces.C.int;
+ Old_Set : aliased sigset_t;
+
+ begin
+ if Self_Id.Deferral_Level = 0
+ and then Self_Id.Pending_ATC_Level < Self_Id.ATC_Nesting_Level and then
+ not Self_Id.Aborting
+ then
+ Self_Id.Aborting := True;
+
+ -- Make sure signals used for RTS internal purpose are unmasked
+
+ Result := pthread_sigmask (SIG_UNBLOCK,
+ Unblocked_Signal_Mask'Unchecked_Access, Old_Set'Unchecked_Access);
+ pragma Assert (Result = 0);
+
+ raise Standard'Abort_Signal;
+ end if;
+ end Abort_Handler;
+
+ -----------------
+ -- Stack_Guard --
+ -----------------
+
+ -- The underlying thread system sets a guard page at the
+ -- bottom of a thread stack, so nothing is needed.
+ -- ??? Check the comment above
+
+ procedure Stack_Guard (T : ST.Task_ID; On : Boolean) is
+ pragma Unreferenced (T, On);
+ begin
+ null;
+ end Stack_Guard;
+
+ -------------------
+ -- Get_Thread_Id --
+ -------------------
+
+ function Get_Thread_Id (T : ST.Task_ID) return OSI.Thread_Id is
+ begin
+ return T.Common.LL.Thread;
+ end Get_Thread_Id;
+
+ ----------
+ -- Self --
+ ----------
+
+ function Self return Task_ID renames Specific.Self;
+
+ ---------------------
+ -- Initialize_Lock --
+ ---------------------
+
+ -- Note: mutexes and cond_variables needed per-task basis are
+ -- initialized in Initialize_TCB and the Storage_Error is
+ -- handled. Other mutexes (such as RTS_Lock, Memory_Lock...)
+ -- used in RTS is initialized before any status change of RTS.
+ -- Therefore rasing Storage_Error in the following routines
+ -- should be able to be handled safely.
+
+ procedure Initialize_Lock
+ (Prio : System.Any_Priority;
+ L : access Lock)
+ is
+ Attributes : aliased pthread_mutexattr_t;
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_mutexattr_init (Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ raise Storage_Error;
+ end if;
+
+ L.Priority := Prio;
+
+ Result := pthread_mutex_init (L.L'Access, Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ raise Storage_Error;
+ end if;
+
+ Result := pthread_mutexattr_destroy (Attributes'Access);
+ pragma Assert (Result = 0);
+ end Initialize_Lock;
+
+ procedure Initialize_Lock (L : access RTS_Lock; Level : Lock_Level) is
+ pragma Unreferenced (Level);
+
+ Attributes : aliased pthread_mutexattr_t;
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_mutexattr_init (Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ raise Storage_Error;
+ end if;
+
+ Result := pthread_mutex_init (L, Attributes'Access);
+
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ raise Storage_Error;
+ end if;
+
+ Result := pthread_mutexattr_destroy (Attributes'Access);
+ pragma Assert (Result = 0);
+ end Initialize_Lock;
+
+ -------------------
+ -- Finalize_Lock --
+ -------------------
+
+ procedure Finalize_Lock (L : access Lock) is
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_mutex_destroy (L.L'Access);
+ pragma Assert (Result = 0);
+ end Finalize_Lock;
+
+ procedure Finalize_Lock (L : access RTS_Lock) is
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_mutex_destroy (L);
+ pragma Assert (Result = 0);
+ end Finalize_Lock;
+
+ ----------------
+ -- Write_Lock --
+ ----------------
+
+ procedure Write_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ Result : Interfaces.C.int;
+
+ begin
+ L.Owner_Priority := Get_Priority (Self);
+
+ if L.Priority < L.Owner_Priority then
+ Ceiling_Violation := True;
+ return;
+ end if;
+
+ Result := pthread_mutex_lock (L.L'Access);
+ pragma Assert (Result = 0);
+ Ceiling_Violation := False;
+ end Write_Lock;
+
+ procedure Write_Lock
+ (L : access RTS_Lock; Global_Lock : Boolean := False)
+ is
+ Result : Interfaces.C.int;
+
+ begin
+ if not Single_Lock or else Global_Lock then
+ Result := pthread_mutex_lock (L);
+ pragma Assert (Result = 0);
+ end if;
+ end Write_Lock;
+
+ procedure Write_Lock (T : Task_ID) is
+ Result : Interfaces.C.int;
+
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_lock (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Write_Lock;
+
+ ---------------
+ -- Read_Lock --
+ ---------------
+
+ procedure Read_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ begin
+ Write_Lock (L, Ceiling_Violation);
+ end Read_Lock;
+
+ ------------
+ -- Unlock --
+ ------------
+
+ procedure Unlock (L : access Lock) is
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_mutex_unlock (L.L'Access);
+ pragma Assert (Result = 0);
+ end Unlock;
+
+ procedure Unlock (L : access RTS_Lock; Global_Lock : Boolean := False) is
+ Result : Interfaces.C.int;
+ begin
+ if not Single_Lock or else Global_Lock then
+ Result := pthread_mutex_unlock (L);
+ pragma Assert (Result = 0);
+ end if;
+ end Unlock;
+
+ procedure Unlock (T : Task_ID) is
+ Result : Interfaces.C.int;
+
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_unlock (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Unlock;
+
+ -----------
+ -- Sleep --
+ -----------
+
+ procedure Sleep
+ (Self_ID : Task_ID;
+ Reason : System.Tasking.Task_States)
+ 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;
+
+ -- EINTR is not considered a failure.
+ pragma Assert (Result = 0 or else Result = EINTR);
+ end Sleep;
+
+ -----------------
+ -- Timed_Sleep --
+ -----------------
+
+ procedure Timed_Sleep
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes;
+ Reason : System.Tasking.Task_States;
+ Timedout : out Boolean;
+ Yielded : out Boolean)
+ is
+ pragma Unreferenced (Reason);
+
+ Check_Time : constant Duration := Monotonic_Clock;
+ Abs_Time : Duration;
+ Request : aliased timespec;
+ Result : Interfaces.C.int;
+
+ begin
+ 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;
+
+ if Abs_Time > Check_Time then
+ Request := To_Timespec (Abs_Time);
+
+ loop
+ exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level
+ or else Self_ID.Pending_Priority_Change;
+
+ 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;
+
+ exit when Abs_Time <= Monotonic_Clock;
+
+ if Result = 0 or Result = EINTR then
+
+ -- Somebody may have called Wakeup for us
+
+ Timedout := False;
+ exit;
+ end if;
+
+ pragma Assert (Result = ETIMEDOUT);
+ end loop;
+ end if;
+ end Timed_Sleep;
+
+ -----------------
+ -- Timed_Delay --
+ -----------------
+
+ procedure Timed_Delay
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes)
+ is
+ Check_Time : constant Duration := Monotonic_Clock;
+ Abs_Time : Duration;
+ Request : aliased timespec;
+ Result : Interfaces.C.int;
+
+ begin
+ -- Only the little window between deferring abort and
+ -- locking Self_ID is the reason we need to
+ -- check for pending abort and priority change below! :(
+
+ SSL.Abort_Defer.all;
+
+ if Single_Lock then
+ Lock_RTS;
+ end if;
+
+ 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;
+
+ if Abs_Time > Check_Time then
+ Request := To_Timespec (Abs_Time);
+ Self_ID.Common.State := Delay_Sleep;
+
+ loop
+ if Self_ID.Pending_Priority_Change then
+ Self_ID.Pending_Priority_Change := False;
+ Self_ID.Common.Base_Priority := Self_ID.New_Base_Priority;
+ Set_Priority (Self_ID, Self_ID.Common.Base_Priority);
+ end if;
+
+ 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;
+
+ exit when Abs_Time <= Monotonic_Clock;
+
+ pragma Assert (Result = 0 or else
+ Result = ETIMEDOUT or else
+ Result = EINTR);
+ end loop;
+
+ Self_ID.Common.State := Runnable;
+ end if;
+
+ Unlock (Self_ID);
+
+ if Single_Lock then
+ Unlock_RTS;
+ end if;
+
+ Result := sched_yield;
+ SSL.Abort_Undefer.all;
+ end Timed_Delay;
+
+ ---------------------
+ -- Monotonic_Clock --
+ ---------------------
+
+ function Monotonic_Clock return Duration is
+ TS : aliased timespec;
+ Result : Interfaces.C.int;
+
+ begin
+ Result := Clock_Gettime (CLOCK_REALTIME, TS'Unchecked_Access);
+ pragma Assert (Result = 0);
+ return To_Duration (TS);
+ end Monotonic_Clock;
+
+ -------------------
+ -- RT_Resolution --
+ -------------------
+
+ function RT_Resolution return Duration is
+ begin
+ return 10#1.0#E-6;
+ end RT_Resolution;
+
+ ------------
+ -- Wakeup --
+ ------------
+
+ procedure Wakeup (T : Task_ID; Reason : System.Tasking.Task_States) is
+ pragma Unreferenced (Reason);
+
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_cond_signal (T.Common.LL.CV'Access);
+ pragma Assert (Result = 0);
+ end Wakeup;
+
+ -----------
+ -- Yield --
+ -----------
+
+ procedure Yield (Do_Yield : Boolean := True) is
+ Result : Interfaces.C.int;
+ pragma Unreferenced (Result);
+ begin
+ if Do_Yield then
+ Result := sched_yield;
+ end if;
+ end Yield;
+
+ ------------------
+ -- Set_Priority --
+ ------------------
+
+ type Prio_Array_Type is array (System.Any_Priority) of Integer;
+ pragma Atomic_Components (Prio_Array_Type);
+
+ Prio_Array : Prio_Array_Type;
+ -- Global array containing the id of the currently running task for
+ -- each priority.
+ --
+ -- Note: we assume that we are on a single processor with run-til-blocked
+ -- scheduling.
+
+ procedure Set_Priority
+ (T : Task_ID;
+ Prio : System.Any_Priority;
+ Loss_Of_Inheritance : Boolean := False)
+ is
+ Result : Interfaces.C.int;
+ Array_Item : Integer;
+ Param : aliased struct_sched_param;
+
+ begin
+ Param.sched_priority := Interfaces.C.int (Underlying_Priorities (Prio));
+
+ if Time_Slice_Val > 0 then
+ Result := pthread_setschedparam
+ (T.Common.LL.Thread, SCHED_RR, Param'Access);
+
+ elsif FIFO_Within_Priorities or else Time_Slice_Val = 0 then
+ Result := pthread_setschedparam
+ (T.Common.LL.Thread, SCHED_FIFO, Param'Access);
+
+ else
+ Result := pthread_setschedparam
+ (T.Common.LL.Thread, SCHED_OTHER, Param'Access);
+ end if;
+
+ pragma Assert (Result = 0);
+
+ if FIFO_Within_Priorities then
+
+ -- Annex D requirement [RM D.2.2 par. 9]:
+ -- If the task drops its priority due to the loss of inherited
+ -- priority, it is added at the head of the ready queue for its
+ -- new active priority.
+
+ if Loss_Of_Inheritance
+ and then Prio < T.Common.Current_Priority
+ then
+ Array_Item := Prio_Array (T.Common.Base_Priority) + 1;
+ Prio_Array (T.Common.Base_Priority) := Array_Item;
+
+ loop
+ -- Let some processes a chance to arrive
+
+ Yield;
+
+ -- Then wait for our turn to proceed
+
+ exit when Array_Item = Prio_Array (T.Common.Base_Priority)
+ or else Prio_Array (T.Common.Base_Priority) = 1;
+ end loop;
+
+ Prio_Array (T.Common.Base_Priority) :=
+ Prio_Array (T.Common.Base_Priority) - 1;
+ end if;
+ end if;
+
+ T.Common.Current_Priority := Prio;
+ end Set_Priority;
+
+ ------------------
+ -- Get_Priority --
+ ------------------
+
+ function Get_Priority (T : Task_ID) return System.Any_Priority is
+ begin
+ return T.Common.Current_Priority;
+ end Get_Priority;
+
+ ----------------
+ -- Enter_Task --
+ ----------------
+
+ procedure Enter_Task (Self_ID : Task_ID) is
+ begin
+ Self_ID.Common.LL.Thread := pthread_self;
+ Specific.Set (Self_ID);
+
+ Lock_RTS;
+
+ for J in Known_Tasks'Range loop
+ if Known_Tasks (J) = null then
+ Known_Tasks (J) := Self_ID;
+ Self_ID.Known_Tasks_Index := J;
+ exit;
+ end if;
+ end loop;
+
+ Unlock_RTS;
+ end Enter_Task;
+
+ --------------
+ -- New_ATCB --
+ --------------
+
+ function New_ATCB (Entry_Num : Task_Entry_Index) return Task_ID is
+ begin
+ return new Ada_Task_Control_Block (Entry_Num);
+ end New_ATCB;
+
+ -------------------
+ -- Is_Valid_Task --
+ -------------------
+
+ function Is_Valid_Task return Boolean renames Specific.Is_Valid_Task;
+
+ -----------------------------
+ -- Register_Foreign_Thread --
+ -----------------------------
+
+ function Register_Foreign_Thread return Task_ID is
+ begin
+ if Is_Valid_Task then
+ return Self;
+ else
+ return Register_Foreign_Thread (pthread_self);
+ end if;
+ end Register_Foreign_Thread;
+
+ --------------------
+ -- Initialize_TCB --
+ --------------------
+
+ procedure Initialize_TCB (Self_ID : Task_ID; Succeeded : out Boolean) is
+ Mutex_Attr : aliased pthread_mutexattr_t;
+ Result : Interfaces.C.int;
+ Cond_Attr : aliased pthread_condattr_t;
+
+ begin
+ if not Single_Lock then
+ Result := pthread_mutexattr_init (Mutex_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = 0 then
+ Result := pthread_mutex_init (Self_ID.Common.LL.L'Access,
+ Mutex_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+ end if;
+
+ if Result /= 0 then
+ Succeeded := False;
+ return;
+ end if;
+
+ Result := pthread_mutexattr_destroy (Mutex_Attr'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Result := pthread_condattr_init (Cond_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = 0 then
+ Result := pthread_cond_init (Self_ID.Common.LL.CV'Access,
+ Cond_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+ end if;
+
+ if Result = 0 then
+ Succeeded := True;
+ else
+ if not Single_Lock then
+ Result := pthread_mutex_destroy (Self_ID.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Succeeded := False;
+ end if;
+
+ Result := pthread_condattr_destroy (Cond_Attr'Access);
+ pragma Assert (Result = 0);
+ end Initialize_TCB;
+
+ -----------------
+ -- Create_Task --
+ -----------------
+
+ procedure Create_Task
+ (T : Task_ID;
+ Wrapper : System.Address;
+ Stack_Size : System.Parameters.Size_Type;
+ Priority : System.Any_Priority;
+ Succeeded : out Boolean)
+ is
+ Attributes : aliased pthread_attr_t;
+ Adjusted_Stack_Size : Interfaces.C.size_t;
+ Result : Interfaces.C.int;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ begin
+ if Stack_Size = Unspecified_Size then
+ Adjusted_Stack_Size := Interfaces.C.size_t (Default_Stack_Size);
+
+ elsif Stack_Size < Minimum_Stack_Size then
+ Adjusted_Stack_Size := Interfaces.C.size_t (Minimum_Stack_Size);
+
+ else
+ Adjusted_Stack_Size := Interfaces.C.size_t (Stack_Size);
+ end if;
+
+ Result := pthread_attr_init (Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result /= 0 then
+ Succeeded := False;
+ return;
+ end if;
+
+ Result := pthread_attr_setstacksize
+ (Attributes'Access, Adjusted_Stack_Size);
+ pragma Assert (Result = 0);
+
+ -- Since the initial signal mask of a thread is inherited from the
+ -- creator, and the Environment task has all its signals masked, we
+ -- do not need to manipulate caller's signal mask at this point.
+ -- All tasks in RTS will have All_Tasks_Mask initially.
+
+ Result := pthread_create
+ (T.Common.LL.Thread'Access,
+ Attributes'Access,
+ Thread_Body_Access (Wrapper),
+ To_Address (T));
+ pragma Assert (Result = 0 or else Result = EAGAIN);
+
+ Succeeded := Result = 0;
+
+ pthread_detach (T.Common.LL.Thread'Access);
+ -- Detach the thread using pthread_detach, sinc DCE threads do not have
+ -- pthread_attr_set_detachstate.
+
+ Result := pthread_attr_destroy (Attributes'Access);
+ pragma Assert (Result = 0);
+
+ Set_Priority (T, Priority);
+ end Create_Task;
+
+ ------------------
+ -- Finalize_TCB --
+ ------------------
+
+ procedure Finalize_TCB (T : Task_ID) is
+ Result : Interfaces.C.int;
+ Tmp : Task_ID := T;
+ Is_Self : constant Boolean := T = Self;
+
+ procedure Free is new
+ Unchecked_Deallocation (Ada_Task_Control_Block, Task_ID);
+
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_destroy (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Result := pthread_cond_destroy (T.Common.LL.CV'Access);
+ pragma Assert (Result = 0);
+
+ if T.Known_Tasks_Index /= -1 then
+ Known_Tasks (T.Known_Tasks_Index) := null;
+ end if;
+
+ Free (Tmp);
+
+ if Is_Self then
+ Specific.Set (null);
+ end if;
+ end Finalize_TCB;
+
+ ---------------
+ -- Exit_Task --
+ ---------------
+
+ procedure Exit_Task is
+ begin
+ Specific.Set (null);
+ end Exit_Task;
+
+ ----------------
+ -- Abort_Task --
+ ----------------
+
+ procedure Abort_Task (T : Task_ID) is
+ begin
+ --
+ -- Interrupt Server_Tasks may be waiting on an "event" flag (signal)
+ --
+ if T.Common.State = Interrupt_Server_Blocked_On_Event_Flag then
+ System.Interrupt_Management.Operations.Interrupt_Self_Process
+ (System.Interrupt_Management.Interrupt_ID
+ (PIO.Get_Interrupt_ID (T)));
+ end if;
+ end Abort_Task;
+
+ ----------------
+ -- Check_Exit --
+ ----------------
+
+ -- Dummy versions. The only currently working versions is for solaris
+ -- (native).
+
+ function Check_Exit (Self_ID : ST.Task_ID) return Boolean is
+ pragma Unreferenced (Self_ID);
+ begin
+ return True;
+ end Check_Exit;
+
+ --------------------
+ -- Check_No_Locks --
+ --------------------
+
+ function Check_No_Locks (Self_ID : ST.Task_ID) return Boolean is
+ pragma Unreferenced (Self_ID);
+ begin
+ return True;
+ end Check_No_Locks;
+
+ ----------------------
+ -- Environment_Task --
+ ----------------------
+
+ function Environment_Task return Task_ID is
+ begin
+ return Environment_Task_ID;
+ end Environment_Task;
+
+ --------------
+ -- Lock_RTS --
+ --------------
+
+ procedure Lock_RTS is
+ begin
+ Write_Lock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Lock_RTS;
+
+ ----------------
+ -- Unlock_RTS --
+ ----------------
+
+ procedure Unlock_RTS is
+ begin
+ Unlock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Unlock_RTS;
+
+ ------------------
+ -- Suspend_Task --
+ ------------------
+
+ function Suspend_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id)
+ return Boolean
+ is
+ pragma Unreferenced (T);
+ pragma Unreferenced (Thread_Self);
+
+ begin
+ return False;
+ end Suspend_Task;
+
+ -----------------
+ -- Resume_Task --
+ -----------------
+
+ function Resume_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id)
+ return Boolean
+ is
+ pragma Unreferenced (T);
+ pragma Unreferenced (Thread_Self);
+
+ begin
+ return False;
+ end Resume_Task;
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize (Environment_Task : Task_ID) is
+ act : aliased struct_sigaction;
+ old_act : aliased struct_sigaction;
+ Tmp_Set : aliased sigset_t;
+ Result : Interfaces.C.int;
+
+ 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:
+
+ Default : constant Character := 's';
+ -- 'n' this interrupt not set by any Interrupt_State pragma
+ -- 'u' Interrupt_State pragma set state to User
+ -- 'r' Interrupt_State pragma set state to Runtime
+ -- 's' Interrupt_State pragma set state to System (use "default"
+ -- system handler)
+
+ begin
+ Environment_Task_ID := Environment_Task;
+
+ -- Initialize the lock used to synchronize chain of all ATCBs.
+
+ Initialize_Lock (Single_RTS_Lock'Access, RTS_Lock_Level);
+
+ Specific.Initialize (Environment_Task);
+
+ Enter_Task (Environment_Task);
+
+ -- Install the abort-signal handler
+
+ if State (System.Interrupt_Management.Abort_Task_Interrupt)
+ /= Default
+ then
+ act.sa_flags := 0;
+ act.sa_handler := Abort_Handler'Address;
+
+ Result := sigemptyset (Tmp_Set'Access);
+ pragma Assert (Result = 0);
+ act.sa_mask := Tmp_Set;
+
+ Result :=
+ sigaction (
+ Signal (System.Interrupt_Management.Abort_Task_Interrupt),
+ act'Unchecked_Access,
+ old_act'Unchecked_Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Initialize;
+
+ -- NOTE: Unlike other pthread implementations, we do *not* mask all
+ -- signals here since we handle signals using the process-wide primitive
+ -- signal, rather than using sigthreadmask and sigwait. The reason of
+ -- this difference is that sigwait doesn't work when some critical
+ -- signals (SIGABRT, SIGPIPE) are masked.
+
+end System.Task_Primitives.Operations;
diff --git a/gcc/ada/s-taprop-irix-athread.adb b/gcc/ada/s-taprop-irix-athread.adb
new file mode 100644
index 00000000000..3c70a347ef2
--- /dev/null
+++ b/gcc/ada/s-taprop-irix-athread.adb
@@ -0,0 +1,955 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S . O P E R A T I O N S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2004, 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- --
+-- 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, 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, --
+-- 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 is an Irix (old athread library) version of this package
+
+-- This package contains all the GNULL primitives that interface directly
+-- with the underlying OS.
+
+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 Interfaces.C;
+-- used for int
+-- size_t
+
+with System.Tasking.Debug;
+-- used for Known_Tasks
+
+with System.Task_Info;
+
+with System.Interrupt_Management;
+-- used for Keep_Unmasked
+-- Abort_Task_Interrupt
+-- Interrupt_ID
+
+with System.Parameters;
+-- used for Size_Type
+
+with System.Tasking;
+-- used for Ada_Task_Control_Block
+-- Task_ID
+
+with System.Program_Info;
+-- used for Default_Task_Stack
+-- Default_Time_Slice
+-- Stack_Guard_Pages
+-- Pthread_Sched_Signal
+-- Pthread_Arena_Size
+
+with System.Soft_Links;
+-- used for Defer/Undefer_Abort
+
+-- Note that we do not use System.Tasking.Initialization directly since
+-- this is a higher level package that we shouldn't depend on. For example
+-- when using the restricted run time, it is replaced by
+-- System.Tasking.Restricted.Initialization
+
+with System.OS_Primitives;
+-- used for Delay_Modes
+
+with System.Storage_Elements;
+-- used for To_Address
+
+with Unchecked_Conversion;
+with Unchecked_Deallocation;
+
+package body System.Task_Primitives.Operations is
+
+ use System.Tasking.Debug;
+ use System.Tasking;
+ use Interfaces.C;
+ use System.OS_Interface;
+ use System.Parameters;
+ use System.OS_Primitives;
+
+ package SSL renames System.Soft_Links;
+
+ -----------------
+ -- Local Data --
+ -----------------
+
+ -- The followings are logically constants, but need to be initialized
+ -- at run time.
+
+ Single_RTS_Lock : aliased RTS_Lock;
+ -- This is a lock to allow only one thread of control in the RTS at
+ -- a time; it is used to execute in mutual exclusion from all other tasks.
+ -- Used mainly in Single_Lock mode, but also to protect All_Tasks_List
+
+ Environment_Task_ID : Task_ID;
+ -- A variable to hold Task_ID for the environment task.
+
+ Locking_Policy : Character;
+ pragma Import (C, Locking_Policy, "__gl_locking_policy");
+
+ Clock_Address : constant System.Address :=
+ System.Storage_Elements.To_Address (16#200F90#);
+
+ RT_Clock_Id : clockid_t;
+ for RT_Clock_Id'Address use Clock_Address;
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ procedure Initialize_Athread_Library;
+
+ function To_Task_ID is new Unchecked_Conversion (System.Address, Task_ID);
+
+ function To_Address is new Unchecked_Conversion (Task_ID, System.Address);
+
+ -------------------
+ -- Stack_Guard --
+ -------------------
+
+ -- The underlying thread system sets a guard page at the
+ -- bottom of a thread stack, so nothing is needed.
+ -- ??? Check the comment above
+
+ procedure Stack_Guard (T : ST.Task_ID; On : Boolean) is
+ pragma Unreferenced (T);
+ pragma Unreferenced (On);
+ begin
+ null;
+ end Stack_Guard;
+
+ --------------------
+ -- Get_Thread_Id --
+ --------------------
+
+ function Get_Thread_Id (T : ST.Task_ID) return OSI.Thread_Id is
+ begin
+ return T.Common.LL.Thread;
+ end Get_Thread_Id;
+
+ ----------
+ -- Self --
+ ----------
+
+ function Self return Task_ID is
+ begin
+ return To_Task_ID (pthread_get_current_ada_tcb);
+ end Self;
+
+ ---------------------
+ -- Initialize_Lock --
+ ---------------------
+
+ -- Note: mutexes and cond_variables needed per-task basis are
+ -- initialized in Initialize_TCB and the Storage_Error is
+ -- handled. Other mutexes (such as RTS_Lock, Memory_Lock...)
+ -- used in RTS is initialized before any status change of RTS.
+ -- Therefore rasing Storage_Error in the following routines
+ -- should be able to be handled safely.
+
+ procedure Initialize_Lock
+ (Prio : System.Any_Priority;
+ L : access Lock)
+ is
+ Attributes : aliased pthread_mutexattr_t;
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_mutexattr_init (Attributes'Access);
+
+ if Result = FUNC_ERR then
+ raise Storage_Error;
+ end if;
+
+ if Locking_Policy = 'C' then
+
+ Result := pthread_mutexattr_setqueueorder
+ (Attributes'Access, MUTEX_PRIORITY_CEILING);
+
+ pragma Assert (Result /= FUNC_ERR);
+
+ Result := pthread_mutexattr_setceilingprio
+ (Attributes'Access, Interfaces.C.int (Prio));
+
+ pragma Assert (Result /= FUNC_ERR);
+ end if;
+
+ Result := pthread_mutex_init (L, Attributes'Access);
+
+ if Result = FUNC_ERR then
+ Result := pthread_mutexattr_destroy (Attributes'Access);
+ raise Storage_Error;
+ end if;
+
+ Result := pthread_mutexattr_destroy (Attributes'Access);
+ end Initialize_Lock;
+
+ procedure Initialize_Lock (L : access RTS_Lock; Level : Lock_Level) is
+ pragma Unreferenced (Level);
+
+ Attributes : aliased pthread_mutexattr_t;
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_mutexattr_init (Attributes'Access);
+
+ if Result = FUNC_ERR then
+ raise Storage_Error;
+ end if;
+
+ if Locking_Policy = 'C' then
+ Result := pthread_mutexattr_setqueueorder
+ (Attributes'Access, MUTEX_PRIORITY_CEILING);
+ pragma Assert (Result /= FUNC_ERR);
+
+ Result := pthread_mutexattr_setceilingprio
+ (Attributes'Access, Interfaces.C.int (System.Any_Priority'Last));
+ pragma Assert (Result /= FUNC_ERR);
+ end if;
+
+ Result := pthread_mutex_init (L, Attributes'Access);
+
+ if Result = FUNC_ERR then
+ Result := pthread_mutexattr_destroy (Attributes'Access);
+ raise Storage_Error;
+ end if;
+
+ Result := pthread_mutexattr_destroy (Attributes'Access);
+ end Initialize_Lock;
+
+ -------------------
+ -- Finalize_Lock --
+ -------------------
+
+ procedure Finalize_Lock (L : access Lock) is
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_mutex_destroy (L);
+ pragma Assert (Result = 0);
+ end Finalize_Lock;
+
+ procedure Finalize_Lock (L : access RTS_Lock) is
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_mutex_destroy (L);
+ pragma Assert (Result = 0);
+ end Finalize_Lock;
+
+ ----------------
+ -- Write_Lock --
+ ----------------
+
+ procedure Write_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_mutex_lock (L);
+ Ceiling_Violation := Result = FUNC_ERR and then errno = EINVAL;
+ pragma Assert (Result /= FUNC_ERR);
+ end Write_Lock;
+
+ procedure Write_Lock
+ (L : access RTS_Lock; Global_Lock : Boolean := False)
+ is
+ Result : Interfaces.C.int;
+ begin
+ if not Single_Lock or else Global_Lock then
+ Result := pthread_mutex_lock (L);
+ pragma Assert (Result = 0);
+ end if;
+ end Write_Lock;
+
+ procedure Write_Lock (T : Task_ID) is
+ Result : Interfaces.C.int;
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_lock (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Write_Lock;
+
+ ---------------
+ -- Read_Lock --
+ ---------------
+
+ procedure Read_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ begin
+ Write_Lock (L, Ceiling_Violation);
+ end Read_Lock;
+
+ ------------
+ -- Unlock --
+ ------------
+
+ procedure Unlock (L : access Lock) is
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_mutex_unlock (L);
+ pragma Assert (Result = 0);
+ end Unlock;
+
+ procedure Unlock (L : access RTS_Lock; Global_Lock : Boolean := False) is
+ Result : Interfaces.C.int;
+ begin
+ if not Single_Lock or else Global_Lock then
+ Result := pthread_mutex_unlock (L);
+ pragma Assert (Result = 0);
+ end if;
+ end Unlock;
+
+ procedure Unlock (T : Task_ID) is
+ Result : Interfaces.C.int;
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_unlock (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Unlock;
+
+ -----------
+ -- Sleep --
+ -----------
+
+ procedure Sleep
+ (Self_ID : ST.Task_ID;
+ Reason : System.Tasking.Task_States)
+ 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;
+
+ -- EINTR is not considered a failure.
+
+ pragma Assert (Result = 0 or else Result = EINTR);
+ end Sleep;
+
+ -----------------
+ -- Timed_Sleep --
+ -----------------
+
+ procedure Timed_Sleep
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes;
+ Reason : System.Tasking.Task_States;
+ Timedout : out Boolean;
+ Yielded : out Boolean)
+ is
+ pragma Unreferenced (Reason);
+
+ Check_Time : constant Duration := Monotonic_Clock;
+ Abs_Time : Duration;
+ Request : aliased struct_timeval;
+ Result : Interfaces.C.int;
+
+ begin
+ 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;
+
+ if Abs_Time > Check_Time then
+ Request := To_Timeval (Abs_Time);
+
+ loop
+ exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level
+ or else Self_ID.Pending_Priority_Change;
+
+ 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;
+
+ exit when Abs_Time <= Monotonic_Clock;
+
+ if Result = 0 or Result = EINTR then
+ -- somebody may have called Wakeup for us
+ Timedout := False;
+ exit;
+ end if;
+
+ pragma Assert (Result = ETIMEDOUT
+ or else (Result = -1 and then errno = EAGAIN));
+ end loop;
+ end if;
+ end Timed_Sleep;
+
+ -----------------
+ -- Timed_Delay --
+ -----------------
+
+ procedure Timed_Delay
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes)
+ is
+ Check_Time : constant Duration := Monotonic_Clock;
+ Abs_Time : Duration;
+ Request : aliased struct_timeval;
+ Result : Interfaces.C.int;
+
+ begin
+ -- Only the little window between deferring abort and
+ -- locking Self_ID is the reason we need to
+ -- check for pending abort and priority change below!
+
+ SSL.Abort_Defer.all;
+
+ if Single_Lock then
+ Lock_RTS;
+ end if;
+
+ 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;
+
+ if Abs_Time > Check_Time then
+ Request := To_Timeval (Abs_Time);
+ Self_ID.Common.State := Delay_Sleep;
+
+ loop
+ if Self_ID.Pending_Priority_Change then
+ Self_ID.Pending_Priority_Change := False;
+ Self_ID.Common.Base_Priority := Self_ID.New_Base_Priority;
+ Set_Priority (Self_ID, Self_ID.Common.Base_Priority);
+ end if;
+
+ 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;
+
+ exit when Abs_Time <= Monotonic_Clock;
+
+ pragma Assert (Result = 0 or else
+ Result = ETIMEDOUT or else
+ (Result = -1 and then errno = EAGAIN) or else
+ Result = EINTR);
+ end loop;
+
+ Self_ID.Common.State := Runnable;
+ end if;
+
+ Unlock (Self_ID);
+
+ if Single_Lock then
+ Unlock_RTS;
+ end if;
+
+ pthread_yield;
+ SSL.Abort_Undefer.all;
+ end Timed_Delay;
+
+ ---------------------
+ -- Monotonic_Clock --
+ ---------------------
+
+ function Monotonic_Clock return Duration is
+ type timeval is record
+ tv_sec : Integer;
+ tv_usec : Integer;
+ end record;
+ pragma Convention (C, timeval);
+
+ tv : aliased timeval;
+
+ procedure gettimeofday (tp : access timeval);
+ pragma Import (C, gettimeofday, "gettimeofday", "gettimeofday");
+
+ begin
+ gettimeofday (tv'Access);
+ return Duration (tv.tv_sec) + Duration (tv.tv_usec) / 1_000_000.0;
+ end Monotonic_Clock;
+
+ -------------------
+ -- RT_Resolution --
+ -------------------
+
+ function RT_Resolution return Duration is
+ begin
+ return 10#1.0#E-6;
+ end RT_Resolution;
+
+ ------------
+ -- Wakeup --
+ ------------
+
+ procedure Wakeup
+ (T : ST.Task_ID;
+ Reason : System.Tasking.Task_States)
+ is
+ pragma Unreferenced (Reason);
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_cond_signal (T.Common.LL.CV'Access);
+ pragma Assert (Result = 0);
+ end Wakeup;
+
+ -----------
+ -- Yield --
+ -----------
+
+ procedure Yield (Do_Yield : Boolean := True) is
+ begin
+ if Do_Yield then
+ pthread_yield;
+ end if;
+ end Yield;
+
+ ------------------
+ -- Set_Priority --
+ ------------------
+
+ procedure Set_Priority
+ (T : Task_ID;
+ Prio : System.Any_Priority;
+ Loss_Of_Inheritance : Boolean := False)
+ is
+ pragma Unreferenced (Loss_Of_Inheritance);
+
+ Result : Interfaces.C.int;
+
+ begin
+ T.Common.Current_Priority := Prio;
+ Result := pthread_setprio (T.Common.LL.Thread, Interfaces.C.int (Prio));
+ pragma Assert (Result /= FUNC_ERR);
+
+ end Set_Priority;
+
+ ------------------
+ -- Get_Priority --
+ ------------------
+
+ function Get_Priority (T : Task_ID) return System.Any_Priority is
+ begin
+ return T.Common.Current_Priority;
+ end Get_Priority;
+
+ ----------------
+ -- Enter_Task --
+ ----------------
+
+ procedure Enter_Task (Self_ID : Task_ID) is
+ Result : Interfaces.C.int;
+
+ begin
+ Self_ID.Common.LL.Thread := pthread_self;
+ Self_ID.Common.LL.LWP := sproc_self;
+
+ Result :=
+ pthread_set_ada_tcb (Self_ID.Common.LL.Thread, To_Address (Self_ID));
+
+ pragma Assert (Result = 0);
+
+ Lock_RTS;
+
+ for J in Known_Tasks'Range loop
+ if Known_Tasks (J) = null then
+ Known_Tasks (J) := Self_ID;
+ Self_ID.Known_Tasks_Index := J;
+ exit;
+ end if;
+ end loop;
+
+ Unlock_RTS;
+ end Enter_Task;
+
+ --------------
+ -- New_ATCB --
+ --------------
+
+ function New_ATCB (Entry_Num : Task_Entry_Index) return Task_ID is
+ begin
+ return new Ada_Task_Control_Block (Entry_Num);
+ end New_ATCB;
+
+ -------------------
+ -- Is_Valid_Task --
+ -------------------
+
+ function Is_Valid_Task return Boolean is
+ begin
+ return False;
+ end Is_Valid_Task;
+
+ -----------------------------
+ -- Register_Foreign_Thread --
+ -----------------------------
+
+ function Register_Foreign_Thread return Task_ID is
+ begin
+ return null;
+ end Register_Foreign_Thread;
+
+ ----------------------
+ -- Initialize_TCB --
+ ----------------------
+
+ procedure Initialize_TCB (Self_ID : Task_ID; Succeeded : out Boolean) is
+ Result : Interfaces.C.int;
+ Cond_Attr : aliased pthread_condattr_t;
+
+ begin
+ if not Single_Lock then
+ Initialize_Lock (Self_ID.Common.LL.L'Access, ATCB_Level);
+ end if;
+
+ Result := pthread_condattr_init (Cond_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = 0 then
+ Result := pthread_cond_init (Self_ID.Common.LL.CV'Access,
+ Cond_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+ end if;
+
+ if Result = 0 then
+ Succeeded := True;
+ else
+ if not Single_Lock then
+ Result := pthread_mutex_destroy (Self_ID.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Succeeded := False;
+ end if;
+
+ Result := pthread_condattr_destroy (Cond_Attr'Access);
+ pragma Assert (Result = 0);
+ end Initialize_TCB;
+
+ -----------------
+ -- Create_Task --
+ -----------------
+
+ procedure Create_Task
+ (T : Task_ID;
+ Wrapper : System.Address;
+ Stack_Size : System.Parameters.Size_Type;
+ Priority : System.Any_Priority;
+ Succeeded : out Boolean)
+ is
+ Attributes : aliased pthread_attr_t;
+ Adjusted_Stack_Size : Interfaces.C.size_t;
+ Result : Interfaces.C.int;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, start_addr);
+
+ function To_Resource_T is new Unchecked_Conversion
+ (System.Task_Info.Resource_Vector_T, System.OS_Interface.resource_t);
+
+ use System.Task_Info;
+
+ begin
+ if Stack_Size = Unspecified_Size then
+ Adjusted_Stack_Size :=
+ Interfaces.C.size_t (System.Program_Info.Default_Task_Stack);
+
+ elsif Stack_Size < Minimum_Stack_Size then
+ Adjusted_Stack_Size := Interfaces.C.size_t (Minimum_Stack_Size);
+
+ else
+ Adjusted_Stack_Size := Interfaces.C.size_t (Stack_Size);
+ end if;
+
+ Result := pthread_attr_init (Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result /= 0 then
+ Succeeded := False;
+ return;
+ end if;
+
+ Result := pthread_attr_setdetachstate (Attributes'Access, 1);
+ pragma Assert (Result = 0);
+
+ Result := pthread_attr_setstacksize
+ (Attributes'Access, Adjusted_Stack_Size);
+ pragma Assert (Result = 0);
+
+ if T.Common.Task_Info /= null then
+ Result := pthread_attr_setresources
+ (Attributes'Access,
+ To_Resource_T (T.Common.Task_Info.Thread_Resources));
+ pragma Assert (Result /= FUNC_ERR);
+
+ if T.Common.Task_Info.Thread_Timeslice /= 0.0 then
+ declare
+ use System.OS_Interface;
+
+ Tv : aliased struct_timeval := To_Timeval
+ (T.Common.Task_Info.Thread_Timeslice);
+ begin
+ Result := pthread_attr_set_tslice
+ (Attributes'Access, Tv'Access);
+ end;
+ end if;
+
+ if T.Common.Task_Info.Bound_To_Sproc then
+ Result := pthread_attr_set_boundtosproc
+ (Attributes'Access, PTHREAD_BOUND);
+ Result := pthread_attr_set_bsproc
+ (Attributes'Access, T.Common.Task_Info.Sproc);
+ end if;
+
+ end if;
+
+ -- Since the initial signal mask of a thread is inherited from the
+ -- creator, and the Environment task has all its signals masked, we
+ -- do not need to manipulate caller's signal mask at this point.
+ -- All tasks in RTS will have All_Tasks_Mask initially.
+
+ Result := pthread_create
+ (T.Common.LL.Thread'Access,
+ Attributes'Access,
+ Thread_Body_Access (Wrapper),
+ To_Address (T));
+ pragma Assert (Result = 0 or else Result = EAGAIN);
+
+ Succeeded := Result = 0;
+
+ Set_Priority (T, Priority);
+
+ Result := pthread_attr_destroy (Attributes'Access);
+ pragma Assert (Result /= FUNC_ERR);
+ end Create_Task;
+
+ ------------------
+ -- Finalize_TCB --
+ ------------------
+
+ procedure Finalize_TCB (T : Task_ID) is
+ procedure Free is new
+ Unchecked_Deallocation (Ada_Task_Control_Block, Task_ID);
+
+ Result : Interfaces.C.int;
+ Tmp : Task_ID := T;
+
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_destroy (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Result := pthread_cond_destroy (T.Common.LL.CV'Access);
+ pragma Assert (Result = 0);
+
+ if T.Known_Tasks_Index /= -1 then
+ Known_Tasks (T.Known_Tasks_Index) := null;
+ end if;
+
+ Free (Tmp);
+ end Finalize_TCB;
+
+ ---------------
+ -- Exit_Task --
+ ---------------
+
+ procedure Exit_Task is
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_set_ada_tcb (pthread_self, System.Null_Address);
+ pragma Assert (Result = 0);
+ end Exit_Task;
+
+ ----------------
+ -- Abort_Task --
+ ----------------
+
+ procedure Abort_Task (T : Task_ID) is
+ Result : Interfaces.C.int;
+ begin
+ Result :=
+ pthread_kill (T.Common.LL.Thread,
+ Interfaces.C.int
+ (System.Interrupt_Management.Abort_Task_Interrupt));
+ pragma Assert (Result = 0);
+ end Abort_Task;
+
+ ----------------
+ -- Check_Exit --
+ ----------------
+
+ -- Dummy version
+
+ function Check_Exit (Self_ID : ST.Task_ID) return Boolean is
+ pragma Unreferenced (Self_ID);
+
+ begin
+ return True;
+ end Check_Exit;
+
+ --------------------
+ -- Check_No_Locks --
+ --------------------
+
+ function Check_No_Locks (Self_ID : ST.Task_ID) return Boolean is
+ pragma Unreferenced (Self_ID);
+ begin
+ return True;
+ end Check_No_Locks;
+
+ ----------------------
+ -- Environment_Task --
+ ----------------------
+
+ function Environment_Task return Task_ID is
+ begin
+ return Environment_Task_ID;
+ end Environment_Task;
+
+ --------------
+ -- Lock_RTS --
+ --------------
+
+ procedure Lock_RTS is
+ begin
+ Write_Lock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Lock_RTS;
+
+ ----------------
+ -- Unlock_RTS --
+ ----------------
+
+ procedure Unlock_RTS is
+ begin
+ Unlock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Unlock_RTS;
+
+ ------------------
+ -- Suspend_Task --
+ ------------------
+
+ function Suspend_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id) return Boolean
+ is
+ begin
+ if T.Common.LL.Thread /= Thread_Self then
+ return pthread_suspend (T.Common.LL.Thread) = 0;
+ else
+ return True;
+ end if;
+ end Suspend_Task;
+
+ -----------------
+ -- Resume_Task --
+ -----------------
+
+ function Resume_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id) return Boolean
+ is
+ begin
+ if T.Common.LL.Thread /= Thread_Self then
+ return pthread_resume (T.Common.LL.Thread) = 0;
+ else
+ return True;
+ end if;
+ end Resume_Task;
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize (Environment_Task : Task_ID) is
+ begin
+ Environment_Task_ID := Environment_Task;
+
+ Initialize_Lock (Single_RTS_Lock'Access, RTS_Lock_Level);
+ -- Initialize the lock used to synchronize chain of all ATCBs.
+
+ Enter_Task (Environment_Task);
+
+ Set_Priority (Environment_Task,
+ Environment_Task.Common.Current_Priority);
+ end Initialize;
+
+ --------------------------------
+ -- Initialize_Athread_Library --
+ --------------------------------
+
+ procedure Initialize_Athread_Library is
+ Result : Interfaces.C.int;
+ Init : aliased pthread_init_struct;
+
+ package PINF renames System.Program_Info;
+ package C renames Interfaces.C;
+
+ begin
+ Init.conf_initsize := C.int (PINF.Pthread_Arena_Size);
+ Init.max_sproc_count := C.int (PINF.Max_Sproc_Count);
+ Init.sproc_stack_size := C.size_t (PINF.Sproc_Stack_Size);
+ Init.os_default_priority := C.int (PINF.Os_Default_Priority);
+ Init.os_sched_signal := C.int (PINF.Pthread_Sched_Signal);
+ Init.guard_pages := C.int (PINF.Stack_Guard_Pages);
+ Init.init_sproc_count := C.int (PINF.Initial_Sproc_Count);
+
+ Result := pthread_exec_begin (Init'Access);
+ pragma Assert (Result /= FUNC_ERR);
+
+ if Result = FUNC_ERR then
+ raise Storage_Error; -- Insufficient resources.
+ end if;
+ end Initialize_Athread_Library;
+
+-- Package initialization
+
+begin
+ Initialize_Athread_Library;
+end System.Task_Primitives.Operations;
diff --git a/gcc/ada/s-taprop-irix.adb b/gcc/ada/s-taprop-irix.adb
new file mode 100644
index 00000000000..6eb6e2ad52a
--- /dev/null
+++ b/gcc/ada/s-taprop-irix.adb
@@ -0,0 +1,1139 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S . O P E R A T I O N S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2004, 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- --
+-- 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, 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, --
+-- 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 is a IRIX (pthread library) version of this package
+
+-- This package contains all the GNULL primitives that interface directly
+-- with the underlying OS.
+
+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 Interfaces.C;
+-- used for int
+-- size_t
+
+with System.Task_Info;
+
+with System.Tasking.Debug;
+-- used for Known_Tasks
+
+with System.IO;
+-- used for Put_Line
+
+with System.Interrupt_Management;
+-- used for Keep_Unmasked
+-- Abort_Task_Interrupt
+-- Interrupt_ID
+
+with System.Interrupt_Management.Operations;
+-- used for Set_Interrupt_Mask
+-- All_Tasks_Mask
+pragma Elaborate_All (System.Interrupt_Management.Operations);
+
+with System.Parameters;
+-- used for Size_Type
+
+with System.Tasking;
+-- used for Ada_Task_Control_Block
+-- Task_ID
+
+with System.Soft_Links;
+-- used for Defer/Undefer_Abort
+
+-- Note that we do not use System.Tasking.Initialization directly since
+-- this is a higher level package that we shouldn't depend on. For example
+-- when using the restricted run time, it is replaced by
+-- System.Tasking.Restricted.Initialization
+
+with System.Program_Info;
+-- used for Default_Task_Stack
+-- Default_Time_Slice
+-- Stack_Guard_Pages
+-- Pthread_Sched_Signal
+-- Pthread_Arena_Size
+
+with System.OS_Interface;
+-- used for various type, constant, and operations
+
+with System.OS_Primitives;
+-- used for Delay_Modes
+
+with Unchecked_Conversion;
+with Unchecked_Deallocation;
+
+package body System.Task_Primitives.Operations is
+
+ use System.Tasking;
+ use System.Tasking.Debug;
+ use Interfaces.C;
+ use System.OS_Interface;
+ use System.OS_Primitives;
+ use System.Parameters;
+
+ package SSL renames System.Soft_Links;
+
+ ------------------
+ -- Local Data --
+ ------------------
+
+ -- The followings are logically constants, but need to be initialized
+ -- at run time.
+
+ Single_RTS_Lock : aliased RTS_Lock;
+ -- This is a lock to allow only one thread of control in the RTS at
+ -- a time; it is used to execute in mutual exclusion from all other tasks.
+ -- Used mainly in Single_Lock mode, but also to protect All_Tasks_List
+
+ ATCB_Key : aliased pthread_key_t;
+ -- Key used to find the Ada Task_ID associated with a thread
+
+ Environment_Task_ID : Task_ID;
+ -- A variable to hold Task_ID for the environment task.
+
+ Locking_Policy : Character;
+ pragma Import (C, Locking_Policy, "__gl_locking_policy");
+
+ Real_Time_Clock_Id : constant clockid_t := CLOCK_REALTIME;
+
+ Unblocked_Signal_Mask : aliased sigset_t;
+
+ Foreign_Task_Elaborated : aliased Boolean := True;
+ -- Used to identified fake tasks (i.e., non-Ada Threads).
+
+ --------------------
+ -- Local Packages --
+ --------------------
+
+ package Specific is
+
+ procedure Initialize (Environment_Task : Task_ID);
+ pragma Inline (Initialize);
+ -- Initialize various data needed by this package.
+
+ function Is_Valid_Task return Boolean;
+ pragma Inline (Is_Valid_Task);
+ -- Does executing thread have a TCB?
+
+ procedure Set (Self_Id : Task_ID);
+ pragma Inline (Set);
+ -- Set the self id for the current task.
+
+ function Self return Task_ID;
+ pragma Inline (Self);
+ -- Return a pointer to the Ada Task Control Block of the calling task.
+
+ end Specific;
+
+ package body Specific is separate;
+ -- The body of this package is target specific.
+
+ ---------------------------------
+ -- Support for foreign threads --
+ ---------------------------------
+
+ function Register_Foreign_Thread (Thread : Thread_Id) return Task_ID;
+ -- Allocate and Initialize a new ATCB for the current Thread.
+
+ function Register_Foreign_Thread
+ (Thread : Thread_Id) return Task_ID is separate;
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ function To_Address is new Unchecked_Conversion (Task_ID, System.Address);
+
+ procedure Abort_Handler (Sig : Signal);
+ -- Signal handler used to implement asynchronous abort.
+
+ -------------------
+ -- Abort_Handler --
+ -------------------
+
+ procedure Abort_Handler (Sig : Signal) is
+ pragma Unreferenced (Sig);
+
+ T : constant Task_ID := Self;
+ Result : Interfaces.C.int;
+ Old_Set : aliased sigset_t;
+
+ begin
+ -- It is not safe to raise an exception when using ZCX and the GCC
+ -- exception handling mechanism.
+
+ if ZCX_By_Default and then GCC_ZCX_Support then
+ return;
+ end if;
+
+ if T.Deferral_Level = 0
+ and then T.Pending_ATC_Level < T.ATC_Nesting_Level
+ then
+ -- Make sure signals used for RTS internal purpose are unmasked
+
+ Result := pthread_sigmask
+ (SIG_UNBLOCK,
+ Unblocked_Signal_Mask'Unchecked_Access,
+ Old_Set'Unchecked_Access);
+ pragma Assert (Result = 0);
+
+ raise Standard'Abort_Signal;
+ end if;
+ end Abort_Handler;
+
+ -----------------
+ -- Stack_Guard --
+ -----------------
+
+ -- The underlying thread system sets a guard page at the
+ -- bottom of a thread stack, so nothing is needed.
+
+ procedure Stack_Guard (T : ST.Task_ID; On : Boolean) is
+ pragma Unreferenced (On);
+ pragma Unreferenced (T);
+ begin
+ null;
+ end Stack_Guard;
+
+ -------------------
+ -- Get_Thread_Id --
+ -------------------
+
+ function Get_Thread_Id (T : ST.Task_ID) return OSI.Thread_Id is
+ begin
+ return T.Common.LL.Thread;
+ end Get_Thread_Id;
+
+ ----------
+ -- Self --
+ ----------
+
+ function Self return Task_ID renames Specific.Self;
+
+ ---------------------
+ -- Initialize_Lock --
+ ---------------------
+
+ -- Note: mutexes and cond_variables needed per-task basis are
+ -- initialized in Initialize_TCB and the Storage_Error is
+ -- handled. Other mutexes (such as RTS_Lock, Memory_Lock...)
+ -- used in RTS is initialized before any status change of RTS.
+ -- Therefore rasing Storage_Error in the following routines
+ -- should be able to be handled safely.
+
+ procedure Initialize_Lock
+ (Prio : System.Any_Priority;
+ L : access Lock)
+ is
+ Attributes : aliased pthread_mutexattr_t;
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_mutexattr_init (Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ raise Storage_Error;
+ end if;
+
+ if Locking_Policy = 'C' then
+ Result := pthread_mutexattr_setprotocol
+ (Attributes'Access, PTHREAD_PRIO_PROTECT);
+ pragma Assert (Result = 0);
+
+ Result := pthread_mutexattr_setprioceiling
+ (Attributes'Access, Interfaces.C.int (Prio));
+ pragma Assert (Result = 0);
+ end if;
+
+ Result := pthread_mutex_init (L, Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ Result := pthread_mutexattr_destroy (Attributes'Access);
+ raise Storage_Error;
+ end if;
+
+ Result := pthread_mutexattr_destroy (Attributes'Access);
+ pragma Assert (Result = 0);
+ end Initialize_Lock;
+
+ procedure Initialize_Lock (L : access RTS_Lock; Level : Lock_Level) is
+ pragma Unreferenced (Level);
+
+ Attributes : aliased pthread_mutexattr_t;
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_mutexattr_init (Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ raise Storage_Error;
+ end if;
+
+ if Locking_Policy = 'C' then
+ Result := pthread_mutexattr_setprotocol
+ (Attributes'Access, PTHREAD_PRIO_PROTECT);
+ pragma Assert (Result = 0);
+
+ Result := pthread_mutexattr_setprioceiling
+ (Attributes'Access, Interfaces.C.int (System.Any_Priority'Last));
+ pragma Assert (Result = 0);
+ end if;
+
+ Result := pthread_mutex_init (L, Attributes'Access);
+
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ Result := pthread_mutexattr_destroy (Attributes'Access);
+ raise Storage_Error;
+ end if;
+
+ Result := pthread_mutexattr_destroy (Attributes'Access);
+ end Initialize_Lock;
+
+ -------------------
+ -- Finalize_Lock --
+ -------------------
+
+ procedure Finalize_Lock (L : access Lock) is
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_mutex_destroy (L);
+ pragma Assert (Result = 0);
+ end Finalize_Lock;
+
+ procedure Finalize_Lock (L : access RTS_Lock) is
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_mutex_destroy (L);
+ pragma Assert (Result = 0);
+ end Finalize_Lock;
+
+ ----------------
+ -- Write_Lock --
+ ----------------
+
+ procedure Write_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_mutex_lock (L);
+ Ceiling_Violation := Result = EINVAL;
+
+ -- Assumes the cause of EINVAL is a priority ceiling violation
+
+ pragma Assert (Result = 0 or else Result = EINVAL);
+ end Write_Lock;
+
+ procedure Write_Lock
+ (L : access RTS_Lock;
+ Global_Lock : Boolean := False)
+ is
+ Result : Interfaces.C.int;
+ begin
+ if not Single_Lock or else Global_Lock then
+ Result := pthread_mutex_lock (L);
+ pragma Assert (Result = 0);
+ end if;
+ end Write_Lock;
+
+ procedure Write_Lock (T : Task_ID) is
+ Result : Interfaces.C.int;
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_lock (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Write_Lock;
+
+ ---------------
+ -- Read_Lock --
+ ---------------
+
+ procedure Read_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ begin
+ Write_Lock (L, Ceiling_Violation);
+ end Read_Lock;
+
+ ------------
+ -- Unlock --
+ ------------
+
+ procedure Unlock (L : access Lock) is
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_mutex_unlock (L);
+ pragma Assert (Result = 0);
+ end Unlock;
+
+ procedure Unlock (L : access RTS_Lock; Global_Lock : Boolean := False) is
+ Result : Interfaces.C.int;
+
+ begin
+ if not Single_Lock or else Global_Lock then
+ Result := pthread_mutex_unlock (L);
+ pragma Assert (Result = 0);
+ end if;
+ end Unlock;
+
+ procedure Unlock (T : Task_ID) is
+ Result : Interfaces.C.int;
+
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_unlock (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Unlock;
+
+ -----------
+ -- Sleep --
+ -----------
+
+ procedure Sleep
+ (Self_ID : ST.Task_ID;
+ Reason : System.Tasking.Task_States)
+ 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;
+
+ -- EINTR is not considered a failure.
+
+ pragma Assert (Result = 0 or else Result = EINTR);
+ end Sleep;
+
+ -----------------
+ -- Timed_Sleep --
+ -----------------
+
+ procedure Timed_Sleep
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes;
+ Reason : Task_States;
+ Timedout : out Boolean;
+ Yielded : out Boolean)
+ is
+ pragma Unreferenced (Reason);
+
+ Check_Time : constant Duration := Monotonic_Clock;
+ Abs_Time : Duration;
+ Request : aliased timespec;
+ Result : Interfaces.C.int;
+
+ begin
+ 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;
+
+ if Abs_Time > Check_Time then
+ Request := To_Timespec (Abs_Time);
+
+ loop
+ exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level
+ or else Self_ID.Pending_Priority_Change;
+
+ 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;
+
+ exit when Abs_Time <= Monotonic_Clock;
+
+ if Result = 0 or else errno = EINTR then
+ Timedout := False;
+ exit;
+ end if;
+ end loop;
+ end if;
+ end Timed_Sleep;
+
+ -----------------
+ -- Timed_Delay --
+ -----------------
+
+ -- This is for use in implementing delay statements, so
+ -- we assume the caller is abort-deferred but is holding
+ -- no locks.
+
+ procedure Timed_Delay
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes)
+ is
+ Check_Time : constant Duration := Monotonic_Clock;
+ Abs_Time : Duration;
+ Request : aliased timespec;
+ Result : Interfaces.C.int;
+
+ begin
+ -- Only the little window between deferring abort and
+ -- locking Self_ID is the reason we need to
+ -- check for pending abort and priority change below! :(
+
+ SSL.Abort_Defer.all;
+
+ if Single_Lock then
+ Lock_RTS;
+ end if;
+
+ 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;
+
+ if Abs_Time > Check_Time then
+ Request := To_Timespec (Abs_Time);
+ Self_ID.Common.State := Delay_Sleep;
+
+ loop
+ if Self_ID.Pending_Priority_Change then
+ Self_ID.Pending_Priority_Change := False;
+ Self_ID.Common.Base_Priority := Self_ID.New_Base_Priority;
+ Set_Priority (Self_ID, Self_ID.Common.Base_Priority);
+ end if;
+
+ exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level;
+
+ Result := pthread_cond_timedwait (Self_ID.Common.LL.CV'Access,
+ Self_ID.Common.LL.L'Access, Request'Access);
+ exit when Abs_Time <= Monotonic_Clock;
+
+ pragma Assert (Result = 0
+ or else Result = ETIMEDOUT
+ or else Result = EINTR);
+ end loop;
+
+ Self_ID.Common.State := Runnable;
+ end if;
+
+ Unlock (Self_ID);
+
+ if Single_Lock then
+ Unlock_RTS;
+ end if;
+
+ Yield;
+ SSL.Abort_Undefer.all;
+ end Timed_Delay;
+
+ ---------------------
+ -- Monotonic_Clock --
+ ---------------------
+
+ function Monotonic_Clock return Duration is
+ TS : aliased timespec;
+ Result : Interfaces.C.int;
+ begin
+ Result := clock_gettime (Real_Time_Clock_Id, TS'Unchecked_Access);
+ pragma Assert (Result = 0);
+ return To_Duration (TS);
+ end Monotonic_Clock;
+
+ -------------------
+ -- RT_Resolution --
+ -------------------
+
+ function RT_Resolution return Duration is
+ begin
+ -- The clock_getres (Real_Time_Clock_Id) function appears to return
+ -- the interrupt resolution of the realtime clock and not the actual
+ -- resolution of reading the clock. Even though this last value is
+ -- only guaranteed to be 100 Hz, at least the Origin 200 appears to
+ -- have a microsecond resolution or better.
+ -- ??? We should figure out a method to return the right value on
+ -- all SGI hardware.
+
+ return 0.000_001; -- Assume microsecond resolution of clock
+ end RT_Resolution;
+
+ ------------
+ -- Wakeup --
+ ------------
+
+ procedure Wakeup (T : ST.Task_ID; Reason : System.Tasking.Task_States) is
+ pragma Unreferenced (Reason);
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_cond_signal (T.Common.LL.CV'Access);
+ pragma Assert (Result = 0);
+ end Wakeup;
+
+ -----------
+ -- Yield --
+ -----------
+
+ procedure Yield (Do_Yield : Boolean := True) is
+ Result : Interfaces.C.int;
+ pragma Unreferenced (Result);
+ begin
+ if Do_Yield then
+ Result := sched_yield;
+ end if;
+ end Yield;
+
+ ------------------
+ -- Set_Priority --
+ ------------------
+
+ procedure Set_Priority
+ (T : Task_ID;
+ Prio : System.Any_Priority;
+ Loss_Of_Inheritance : Boolean := False)
+ is
+ pragma Unreferenced (Loss_Of_Inheritance);
+
+ Result : Interfaces.C.int;
+ Param : aliased struct_sched_param;
+ Sched_Policy : Interfaces.C.int;
+
+ use type System.Task_Info.Task_Info_Type;
+
+ function To_Int is new Unchecked_Conversion
+ (System.Task_Info.Thread_Scheduling_Policy, Interfaces.C.int);
+
+ begin
+ T.Common.Current_Priority := Prio;
+ Param.sched_priority := Interfaces.C.int (Prio);
+
+ if T.Common.Task_Info /= null then
+ Sched_Policy := To_Int (T.Common.Task_Info.Policy);
+ else
+ Sched_Policy := SCHED_FIFO;
+ end if;
+
+ Result := pthread_setschedparam (T.Common.LL.Thread, Sched_Policy,
+ Param'Access);
+ pragma Assert (Result = 0);
+ end Set_Priority;
+
+ ------------------
+ -- Get_Priority --
+ ------------------
+
+ function Get_Priority (T : Task_ID) return System.Any_Priority is
+ begin
+ return T.Common.Current_Priority;
+ end Get_Priority;
+
+ ----------------
+ -- Enter_Task --
+ ----------------
+
+ procedure Enter_Task (Self_ID : Task_ID) is
+ Result : Interfaces.C.int;
+
+ function To_Int is new Unchecked_Conversion
+ (System.Task_Info.CPU_Number, Interfaces.C.int);
+
+ use System.Task_Info;
+
+ begin
+ Self_ID.Common.LL.Thread := pthread_self;
+ Specific.Set (Self_ID);
+
+ if Self_ID.Common.Task_Info /= null
+ and then Self_ID.Common.Task_Info.Scope = PTHREAD_SCOPE_SYSTEM
+ and then Self_ID.Common.Task_Info.Runon_CPU /= ANY_CPU
+ then
+ Result := pthread_setrunon_np
+ (To_Int (Self_ID.Common.Task_Info.Runon_CPU));
+ pragma Assert (Result = 0);
+ end if;
+
+ Lock_RTS;
+
+ for J in Known_Tasks'Range loop
+ if Known_Tasks (J) = null then
+ Known_Tasks (J) := Self_ID;
+ Self_ID.Known_Tasks_Index := J;
+ exit;
+ end if;
+ end loop;
+
+ Unlock_RTS;
+ end Enter_Task;
+
+ --------------
+ -- New_ATCB --
+ --------------
+
+ function New_ATCB (Entry_Num : Task_Entry_Index) return Task_ID is
+ begin
+ return new Ada_Task_Control_Block (Entry_Num);
+ end New_ATCB;
+
+ -------------------
+ -- Is_Valid_Task --
+ -------------------
+
+ function Is_Valid_Task return Boolean renames Specific.Is_Valid_Task;
+
+ -----------------------------
+ -- Register_Foreign_Thread --
+ -----------------------------
+
+ function Register_Foreign_Thread return Task_ID is
+ begin
+ if Is_Valid_Task then
+ return Self;
+ else
+ return Register_Foreign_Thread (pthread_self);
+ end if;
+ end Register_Foreign_Thread;
+
+ --------------------
+ -- Initialize_TCB --
+ --------------------
+
+ procedure Initialize_TCB (Self_ID : Task_ID; Succeeded : out Boolean) is
+ Result : Interfaces.C.int;
+ Cond_Attr : aliased pthread_condattr_t;
+
+ begin
+ if not Single_Lock then
+ Initialize_Lock (Self_ID.Common.LL.L'Access, ATCB_Level);
+ end if;
+
+ Result := pthread_condattr_init (Cond_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = 0 then
+ Result := pthread_cond_init (Self_ID.Common.LL.CV'Access,
+ Cond_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+ end if;
+
+ if Result = 0 then
+ Succeeded := True;
+ else
+ if not Single_Lock then
+ Result := pthread_mutex_destroy (Self_ID.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Succeeded := False;
+ end if;
+
+ Result := pthread_condattr_destroy (Cond_Attr'Access);
+ pragma Assert (Result = 0);
+ end Initialize_TCB;
+
+ -----------------
+ -- Create_Task --
+ -----------------
+
+ procedure Create_Task
+ (T : Task_ID;
+ Wrapper : System.Address;
+ Stack_Size : System.Parameters.Size_Type;
+ Priority : System.Any_Priority;
+ Succeeded : out Boolean)
+ is
+ use System.Task_Info;
+
+ Attributes : aliased pthread_attr_t;
+ Sched_Param : aliased struct_sched_param;
+ Adjusted_Stack_Size : Interfaces.C.size_t;
+ Result : Interfaces.C.int;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ function To_Int is new Unchecked_Conversion
+ (System.Task_Info.Thread_Scheduling_Scope, Interfaces.C.int);
+ function To_Int is new Unchecked_Conversion
+ (System.Task_Info.Thread_Scheduling_Inheritance, Interfaces.C.int);
+ function To_Int is new Unchecked_Conversion
+ (System.Task_Info.Thread_Scheduling_Policy, Interfaces.C.int);
+
+ begin
+ if Stack_Size = System.Parameters.Unspecified_Size then
+ Adjusted_Stack_Size :=
+ Interfaces.C.size_t (System.Program_Info.Default_Task_Stack);
+
+ elsif Stack_Size < Size_Type (Minimum_Stack_Size) then
+ Adjusted_Stack_Size :=
+ Interfaces.C.size_t (Minimum_Stack_Size);
+
+ else
+ Adjusted_Stack_Size := Interfaces.C.size_t (Stack_Size);
+ end if;
+
+ Result := pthread_attr_init (Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result /= 0 then
+ Succeeded := False;
+ return;
+ end if;
+
+ Result := pthread_attr_setdetachstate
+ (Attributes'Access, PTHREAD_CREATE_DETACHED);
+ pragma Assert (Result = 0);
+
+ Result := pthread_attr_setstacksize
+ (Attributes'Access, Adjusted_Stack_Size);
+ pragma Assert (Result = 0);
+
+ if T.Common.Task_Info /= null then
+ Result := pthread_attr_setscope
+ (Attributes'Access, To_Int (T.Common.Task_Info.Scope));
+ pragma Assert (Result = 0);
+
+ Result := pthread_attr_setinheritsched
+ (Attributes'Access, To_Int (T.Common.Task_Info.Inheritance));
+ pragma Assert (Result = 0);
+
+ Result := pthread_attr_setschedpolicy
+ (Attributes'Access, To_Int (T.Common.Task_Info.Policy));
+ pragma Assert (Result = 0);
+
+ Sched_Param.sched_priority :=
+ Interfaces.C.int (T.Common.Task_Info.Priority);
+
+ Result := pthread_attr_setschedparam
+ (Attributes'Access, Sched_Param'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ -- Since the initial signal mask of a thread is inherited from the
+ -- creator, and the Environment task has all its signals masked, we
+ -- do not need to manipulate caller's signal mask at this point.
+ -- All tasks in RTS will have All_Tasks_Mask initially.
+
+ Result := pthread_create
+ (T.Common.LL.Thread'Access,
+ Attributes'Access,
+ Thread_Body_Access (Wrapper),
+ To_Address (T));
+
+ if Result /= 0
+ and then T.Common.Task_Info /= null
+ and then T.Common.Task_Info.Scope = PTHREAD_SCOPE_SYSTEM
+ then
+ -- The pthread_create call may have failed because we
+ -- asked for a system scope pthread and none were
+ -- available (probably because the program was not executed
+ -- by the superuser). Let's try for a process scope pthread
+ -- instead of raising Tasking_Error.
+
+ System.IO.Put_Line
+ ("Request for PTHREAD_SCOPE_SYSTEM in Task_Info pragma for task");
+ System.IO.Put ("""");
+ System.IO.Put (T.Common.Task_Image (1 .. T.Common.Task_Image_Len));
+ System.IO.Put_Line (""" could not be honored. ");
+ System.IO.Put_Line ("Scope changed to PTHREAD_SCOPE_PROCESS");
+
+ T.Common.Task_Info.Scope := PTHREAD_SCOPE_PROCESS;
+ Result := pthread_attr_setscope
+ (Attributes'Access, To_Int (T.Common.Task_Info.Scope));
+ pragma Assert (Result = 0);
+
+ Result := pthread_create
+ (T.Common.LL.Thread'Access,
+ Attributes'Access,
+ Thread_Body_Access (Wrapper),
+ To_Address (T));
+ end if;
+
+ pragma Assert (Result = 0 or else Result = EAGAIN);
+
+ Succeeded := Result = 0;
+
+ -- The following needs significant commenting ???
+
+ if T.Common.Task_Info /= null then
+ T.Common.Base_Priority := T.Common.Task_Info.Priority;
+ Set_Priority (T, T.Common.Task_Info.Priority);
+ else
+ Set_Priority (T, Priority);
+ end if;
+
+ Result := pthread_attr_destroy (Attributes'Access);
+ pragma Assert (Result = 0);
+ end Create_Task;
+
+ ------------------
+ -- Finalize_TCB --
+ ------------------
+
+ procedure Finalize_TCB (T : Task_ID) is
+ Result : Interfaces.C.int;
+ Tmp : Task_ID := T;
+ Is_Self : constant Boolean := T = Self;
+
+ procedure Free is new
+ Unchecked_Deallocation (Ada_Task_Control_Block, Task_ID);
+
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_destroy (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Result := pthread_cond_destroy (T.Common.LL.CV'Access);
+ pragma Assert (Result = 0);
+
+ if T.Known_Tasks_Index /= -1 then
+ Known_Tasks (T.Known_Tasks_Index) := null;
+ end if;
+
+ Free (Tmp);
+
+ if Is_Self then
+ Specific.Set (null);
+ end if;
+ end Finalize_TCB;
+
+ ---------------
+ -- Exit_Task --
+ ---------------
+
+ procedure Exit_Task is
+ begin
+ Specific.Set (null);
+ end Exit_Task;
+
+ ----------------
+ -- Abort_Task --
+ ----------------
+
+ procedure Abort_Task (T : Task_ID) is
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_kill (T.Common.LL.Thread,
+ Signal (System.Interrupt_Management.Abort_Task_Interrupt));
+ pragma Assert (Result = 0);
+ end Abort_Task;
+
+ ----------------
+ -- Check_Exit --
+ ----------------
+
+ -- Dummy version
+
+ function Check_Exit (Self_ID : ST.Task_ID) return Boolean is
+ pragma Unreferenced (Self_ID);
+
+ begin
+ return True;
+ end Check_Exit;
+
+ --------------------
+ -- Check_No_Locks --
+ --------------------
+
+ function Check_No_Locks (Self_ID : ST.Task_ID) return Boolean is
+ pragma Unreferenced (Self_ID);
+
+ begin
+ return True;
+ end Check_No_Locks;
+
+ ----------------------
+ -- Environment_Task --
+ ----------------------
+
+ function Environment_Task return Task_ID is
+ begin
+ return Environment_Task_ID;
+ end Environment_Task;
+
+ --------------
+ -- Lock_RTS --
+ --------------
+
+ procedure Lock_RTS is
+ begin
+ Write_Lock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Lock_RTS;
+
+ ----------------
+ -- Unlock_RTS --
+ ----------------
+
+ procedure Unlock_RTS is
+ begin
+ Unlock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Unlock_RTS;
+
+ ------------------
+ -- Suspend_Task --
+ ------------------
+
+ function Suspend_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id)
+ return Boolean
+ is
+ pragma Unreferenced (T);
+ pragma Unreferenced (Thread_Self);
+
+ begin
+ return False;
+ end Suspend_Task;
+
+ -----------------
+ -- Resume_Task --
+ -----------------
+
+ function Resume_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id)
+ return Boolean
+ is
+ pragma Unreferenced (T);
+ pragma Unreferenced (Thread_Self);
+
+ begin
+ return False;
+ end Resume_Task;
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize (Environment_Task : Task_ID) is
+ act : aliased struct_sigaction;
+ old_act : aliased struct_sigaction;
+ Tmp_Set : aliased sigset_t;
+ Result : Interfaces.C.int;
+
+ 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:
+
+ Default : constant Character := 's';
+ -- 'n' this interrupt not set by any Interrupt_State pragma
+ -- 'u' Interrupt_State pragma set state to User
+ -- 'r' Interrupt_State pragma set state to Runtime
+ -- 's' Interrupt_State pragma set state to System (use "default"
+ -- system handler)
+
+ begin
+ Environment_Task_ID := Environment_Task;
+
+ -- Initialize the lock used to synchronize chain of all ATCBs.
+
+ Initialize_Lock (Single_RTS_Lock'Access, RTS_Lock_Level);
+
+ Specific.Initialize (Environment_Task);
+
+ Enter_Task (Environment_Task);
+
+ -- Install the abort-signal handler
+
+ if State (System.Interrupt_Management.Abort_Task_Interrupt)
+ /= Default
+ then
+ act.sa_flags := 0;
+ act.sa_handler := Abort_Handler'Address;
+
+ Result := sigemptyset (Tmp_Set'Access);
+ pragma Assert (Result = 0);
+ act.sa_mask := Tmp_Set;
+
+ Result :=
+ sigaction (
+ Signal (System.Interrupt_Management.Abort_Task_Interrupt),
+ act'Unchecked_Access,
+ old_act'Unchecked_Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Initialize;
+
+begin
+ declare
+ Result : Interfaces.C.int;
+
+ begin
+ -- Mask Environment task for all signals. The original mask of the
+ -- Environment task will be recovered by Interrupt_Server task
+ -- during the elaboration of s-interr.adb.
+
+ System.Interrupt_Management.Operations.Set_Interrupt_Mask
+ (System.Interrupt_Management.Operations.All_Tasks_Mask'Access);
+
+ -- Prepare the set of signals that should unblocked in all tasks
+
+ Result := sigemptyset (Unblocked_Signal_Mask'Access);
+ pragma Assert (Result = 0);
+
+ for J in Interrupt_Management.Interrupt_ID loop
+ if System.Interrupt_Management.Keep_Unmasked (J) then
+ Result := sigaddset (Unblocked_Signal_Mask'Access, Signal (J));
+ pragma Assert (Result = 0);
+ end if;
+ end loop;
+
+ -- Pick the highest resolution Clock for Clock_Realtime
+ -- ??? This code currently doesn't work (see c94007[ab] for example)
+ --
+ -- if syssgi (SGI_CYCLECNTR_SIZE) = 64 then
+ -- Real_Time_Clock_Id := CLOCK_SGI_CYCLE;
+ -- else
+ -- Real_Time_Clock_Id := CLOCK_REALTIME;
+ -- end if;
+ end;
+end System.Task_Primitives.Operations;
diff --git a/gcc/ada/s-taprop-linux.adb b/gcc/ada/s-taprop-linux.adb
new file mode 100644
index 00000000000..6ab670f9722
--- /dev/null
+++ b/gcc/ada/s-taprop-linux.adb
@@ -0,0 +1,1094 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S . O P E R A T I O N S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2004, 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- --
+-- 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, 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, --
+-- 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 is a GNU/Linux (GNU/LinuxThreads) version of this package
+
+-- This package contains all the GNULL primitives that interface directly
+-- with the underlying OS.
+
+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.Tasking.Debug;
+-- used for Known_Tasks
+
+with Interfaces.C;
+-- used for int
+-- size_t
+
+with System.Interrupt_Management;
+-- used for Keep_Unmasked
+-- Abort_Task_Interrupt
+-- Interrupt_ID
+
+with System.Interrupt_Management.Operations;
+-- used for Set_Interrupt_Mask
+-- All_Tasks_Mask
+pragma Elaborate_All (System.Interrupt_Management.Operations);
+
+with System.Parameters;
+-- used for Size_Type
+
+with System.Tasking;
+-- used for Ada_Task_Control_Block
+-- Task_ID
+
+with Ada.Exceptions;
+-- used for Raise_Exception
+-- Raise_From_Signal_Handler
+-- Exception_Id
+
+with System.Soft_Links;
+-- used for Defer/Undefer_Abort
+
+-- Note that we do not use System.Tasking.Initialization directly since
+-- this is a higher level package that we shouldn't depend on. For example
+-- when using the restricted run time, it is replaced by
+-- System.Tasking.Restricted.Initialization
+
+with System.OS_Primitives;
+-- used for Delay_Modes
+
+with System.Soft_Links;
+-- used for Get_Machine_State_Addr
+
+with Unchecked_Conversion;
+with Unchecked_Deallocation;
+
+package body System.Task_Primitives.Operations is
+
+ use System.Tasking.Debug;
+ use System.Tasking;
+ use Interfaces.C;
+ use System.OS_Interface;
+ use System.Parameters;
+ use System.OS_Primitives;
+
+ package SSL renames System.Soft_Links;
+
+ ------------------
+ -- Local Data --
+ ------------------
+
+ -- The followings are logically constants, but need to be initialized
+ -- at run time.
+
+ Single_RTS_Lock : aliased RTS_Lock;
+ -- This is a lock to allow only one thread of control in the RTS at
+ -- a time; it is used to execute in mutual exclusion from all other tasks.
+ -- Used mainly in Single_Lock mode, but also to protect All_Tasks_List
+
+ ATCB_Key : aliased pthread_key_t;
+ -- Key used to find the Ada Task_ID associated with a thread
+
+ Environment_Task_ID : Task_ID;
+ -- A variable to hold Task_ID for the environment task.
+
+ Unblocked_Signal_Mask : aliased sigset_t;
+ -- The set of signals that should unblocked in all tasks
+
+ -- The followings are internal configuration constants needed.
+ Priority_Ceiling_Emulation : constant Boolean := True;
+
+ Next_Serial_Number : Task_Serial_Number := 100;
+ -- We start at 100, to reserve some special values for
+ -- using in error checking.
+ -- The following are internal configuration constants needed.
+
+ Time_Slice_Val : Integer;
+ pragma Import (C, Time_Slice_Val, "__gl_time_slice_val");
+
+ Dispatching_Policy : Character;
+ pragma Import (C, Dispatching_Policy, "__gl_task_dispatching_policy");
+
+ FIFO_Within_Priorities : constant Boolean := Dispatching_Policy = 'F';
+ -- Indicates whether FIFO_Within_Priorities is set.
+
+ -- The following are effectively constants, but they need to
+ -- be initialized by calling a pthread_ function.
+
+ Mutex_Attr : aliased pthread_mutexattr_t;
+ Cond_Attr : aliased pthread_condattr_t;
+
+ Foreign_Task_Elaborated : aliased Boolean := True;
+ -- Used to identified fake tasks (i.e., non-Ada Threads).
+
+ --------------------
+ -- Local Packages --
+ --------------------
+
+ package Specific is
+
+ procedure Initialize (Environment_Task : Task_ID);
+ pragma Inline (Initialize);
+ -- Initialize various data needed by this package.
+
+ function Is_Valid_Task return Boolean;
+ pragma Inline (Is_Valid_Task);
+ -- Does executing thread have a TCB?
+
+ procedure Set (Self_Id : Task_ID);
+ pragma Inline (Set);
+ -- Set the self id for the current task.
+
+ function Self return Task_ID;
+ pragma Inline (Self);
+ -- Return a pointer to the Ada Task Control Block of the calling task.
+
+ end Specific;
+
+ package body Specific is separate;
+ -- The body of this package is target specific.
+
+ ---------------------------------
+ -- Support for foreign threads --
+ ---------------------------------
+
+ function Register_Foreign_Thread (Thread : Thread_Id) return Task_ID;
+ -- Allocate and Initialize a new ATCB for the current Thread.
+
+ function Register_Foreign_Thread
+ (Thread : Thread_Id) return Task_ID is separate;
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ subtype unsigned_long is Interfaces.C.unsigned_long;
+
+ procedure Abort_Handler (signo : Signal);
+
+ function To_pthread_t is new Unchecked_Conversion
+ (unsigned_long, System.OS_Interface.pthread_t);
+
+ -------------------
+ -- Abort_Handler --
+ -------------------
+
+ procedure Abort_Handler (signo : Signal) is
+ pragma Unreferenced (signo);
+
+ Self_Id : constant Task_ID := Self;
+ Result : Interfaces.C.int;
+ Old_Set : aliased sigset_t;
+
+ begin
+ if ZCX_By_Default and then GCC_ZCX_Support then
+ return;
+ end if;
+
+ if Self_Id.Deferral_Level = 0
+ and then Self_Id.Pending_ATC_Level < Self_Id.ATC_Nesting_Level
+ and then not Self_Id.Aborting
+ then
+ Self_Id.Aborting := True;
+
+ -- Make sure signals used for RTS internal purpose are unmasked
+
+ Result := pthread_sigmask (SIG_UNBLOCK,
+ Unblocked_Signal_Mask'Unchecked_Access, Old_Set'Unchecked_Access);
+ pragma Assert (Result = 0);
+
+ raise Standard'Abort_Signal;
+ end if;
+ end Abort_Handler;
+
+ --------------
+ -- Lock_RTS --
+ --------------
+
+ procedure Lock_RTS is
+ begin
+ Write_Lock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Lock_RTS;
+
+ ----------------
+ -- Unlock_RTS --
+ ----------------
+
+ procedure Unlock_RTS is
+ begin
+ Unlock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Unlock_RTS;
+
+ -----------------
+ -- Stack_Guard --
+ -----------------
+
+ -- The underlying thread system extends the memory (up to 2MB) when needed
+
+ procedure Stack_Guard (T : ST.Task_ID; On : Boolean) is
+ pragma Unreferenced (T);
+ pragma Unreferenced (On);
+
+ begin
+ null;
+ end Stack_Guard;
+
+ --------------------
+ -- Get_Thread_Id --
+ --------------------
+
+ function Get_Thread_Id (T : ST.Task_ID) return OSI.Thread_Id is
+ begin
+ return T.Common.LL.Thread;
+ end Get_Thread_Id;
+
+ ----------
+ -- Self --
+ ----------
+
+ function Self return Task_ID renames Specific.Self;
+
+ ---------------------
+ -- Initialize_Lock --
+ ---------------------
+
+ -- Note: mutexes and cond_variables needed per-task basis are
+ -- initialized in Initialize_TCB and the Storage_Error is
+ -- handled. Other mutexes (such as RTS_Lock, Memory_Lock...)
+ -- used in RTS is initialized before any status change of RTS.
+ -- Therefore rasing Storage_Error in the following routines
+ -- should be able to be handled safely.
+
+ procedure Initialize_Lock
+ (Prio : System.Any_Priority;
+ L : access Lock)
+ is
+ Result : Interfaces.C.int;
+
+ begin
+ if Priority_Ceiling_Emulation then
+ L.Ceiling := Prio;
+ end if;
+
+ Result := pthread_mutex_init (L.L'Access, Mutex_Attr'Access);
+
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ Ada.Exceptions.Raise_Exception (Storage_Error'Identity,
+ "Failed to allocate a lock");
+ end if;
+ end Initialize_Lock;
+
+ procedure Initialize_Lock (L : access RTS_Lock; Level : Lock_Level) is
+ pragma Unreferenced (Level);
+
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_mutex_init (L, Mutex_Attr'Access);
+
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ raise Storage_Error;
+ end if;
+ end Initialize_Lock;
+
+ -------------------
+ -- Finalize_Lock --
+ -------------------
+
+ procedure Finalize_Lock (L : access Lock) is
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_mutex_destroy (L.L'Access);
+ pragma Assert (Result = 0);
+ end Finalize_Lock;
+
+ procedure Finalize_Lock (L : access RTS_Lock) is
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_mutex_destroy (L);
+ pragma Assert (Result = 0);
+ end Finalize_Lock;
+
+ ----------------
+ -- Write_Lock --
+ ----------------
+
+ procedure Write_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ Result : Interfaces.C.int;
+
+ begin
+ if Priority_Ceiling_Emulation then
+ declare
+ Self_ID : constant Task_ID := Self;
+
+ begin
+ if Self_ID.Common.LL.Active_Priority > L.Ceiling then
+ Ceiling_Violation := True;
+ return;
+ end if;
+
+ L.Saved_Priority := Self_ID.Common.LL.Active_Priority;
+
+ if Self_ID.Common.LL.Active_Priority < L.Ceiling then
+ Self_ID.Common.LL.Active_Priority := L.Ceiling;
+ end if;
+
+ Result := pthread_mutex_lock (L.L'Access);
+ pragma Assert (Result = 0);
+ Ceiling_Violation := False;
+ end;
+
+ else
+ Result := pthread_mutex_lock (L.L'Access);
+ Ceiling_Violation := Result = EINVAL;
+
+ -- Assume the cause of EINVAL is a priority ceiling violation
+
+ pragma Assert (Result = 0 or else Result = EINVAL);
+ end if;
+ end Write_Lock;
+
+ procedure Write_Lock
+ (L : access RTS_Lock;
+ Global_Lock : Boolean := False)
+ is
+ Result : Interfaces.C.int;
+
+ begin
+ if not Single_Lock or else Global_Lock then
+ Result := pthread_mutex_lock (L);
+ pragma Assert (Result = 0);
+ end if;
+ end Write_Lock;
+
+ procedure Write_Lock (T : Task_ID) is
+ Result : Interfaces.C.int;
+
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_lock (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Write_Lock;
+
+ ---------------
+ -- Read_Lock --
+ ---------------
+
+ procedure Read_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ begin
+ Write_Lock (L, Ceiling_Violation);
+ end Read_Lock;
+
+ ------------
+ -- Unlock --
+ ------------
+
+ procedure Unlock (L : access Lock) is
+ Result : Interfaces.C.int;
+
+ begin
+ if Priority_Ceiling_Emulation then
+ declare
+ Self_ID : constant Task_ID := Self;
+
+ begin
+ Result := pthread_mutex_unlock (L.L'Access);
+ pragma Assert (Result = 0);
+
+ if Self_ID.Common.LL.Active_Priority > L.Saved_Priority then
+ Self_ID.Common.LL.Active_Priority := L.Saved_Priority;
+ end if;
+ end;
+
+ else
+ Result := pthread_mutex_unlock (L.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Unlock;
+
+ procedure Unlock (L : access RTS_Lock; Global_Lock : Boolean := False) is
+ Result : Interfaces.C.int;
+
+ begin
+ if not Single_Lock or else Global_Lock then
+ Result := pthread_mutex_unlock (L);
+ pragma Assert (Result = 0);
+ end if;
+ end Unlock;
+
+ procedure Unlock (T : Task_ID) is
+ Result : Interfaces.C.int;
+
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_unlock (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Unlock;
+
+ -----------
+ -- Sleep --
+ -----------
+
+ procedure Sleep
+ (Self_ID : Task_ID;
+ Reason : System.Tasking.Task_States)
+ is
+ pragma Unreferenced (Reason);
+
+ Result : Interfaces.C.int;
+
+ 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;
+
+ -- EINTR is not considered a failure.
+ pragma Assert (Result = 0 or else Result = EINTR);
+ end Sleep;
+
+ -----------------
+ -- Timed_Sleep --
+ -----------------
+
+ -- This is for use within the run-time system, so abort is
+ -- assumed to be already deferred, and the caller should be
+ -- holding its own ATCB lock.
+
+ procedure Timed_Sleep
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes;
+ Reason : System.Tasking.Task_States;
+ Timedout : out Boolean;
+ Yielded : out Boolean)
+ is
+ pragma Unreferenced (Reason);
+
+ Check_Time : constant Duration := Monotonic_Clock;
+ Abs_Time : Duration;
+ Request : aliased timespec;
+ Result : Interfaces.C.int;
+
+ begin
+ 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;
+
+ if Abs_Time > Check_Time then
+ Request := To_Timespec (Abs_Time);
+
+ loop
+ exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level
+ or else Self_ID.Pending_Priority_Change;
+
+ 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;
+
+ exit when Abs_Time <= Monotonic_Clock;
+
+ if Result = 0 or Result = EINTR then
+ -- somebody may have called Wakeup for us
+ Timedout := False;
+ exit;
+ end if;
+
+ pragma Assert (Result = ETIMEDOUT);
+ end loop;
+ end if;
+ end Timed_Sleep;
+
+ -----------------
+ -- Timed_Delay --
+ -----------------
+
+ -- This is for use in implementing delay statements, so
+ -- we assume the caller is abort-deferred but is holding
+ -- no locks.
+
+ procedure Timed_Delay
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes)
+ is
+ Check_Time : constant Duration := Monotonic_Clock;
+ Abs_Time : Duration;
+ Request : aliased timespec;
+ Result : Interfaces.C.int;
+ begin
+
+ -- Only the little window between deferring abort and
+ -- locking Self_ID is the reason we need to
+ -- check for pending abort and priority change below! :(
+
+ SSL.Abort_Defer.all;
+
+ if Single_Lock then
+ Lock_RTS;
+ end if;
+
+ 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;
+
+ if Abs_Time > Check_Time then
+ Request := To_Timespec (Abs_Time);
+ Self_ID.Common.State := Delay_Sleep;
+
+ loop
+ if Self_ID.Pending_Priority_Change then
+ Self_ID.Pending_Priority_Change := False;
+ Self_ID.Common.Base_Priority := Self_ID.New_Base_Priority;
+ Set_Priority (Self_ID, Self_ID.Common.Base_Priority);
+ end if;
+
+ 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;
+
+ exit when Abs_Time <= Monotonic_Clock;
+
+ pragma Assert (Result = 0 or else
+ Result = ETIMEDOUT or else
+ Result = EINTR);
+ end loop;
+
+ Self_ID.Common.State := Runnable;
+ end if;
+
+ Unlock (Self_ID);
+
+ if Single_Lock then
+ Unlock_RTS;
+ end if;
+
+ Result := sched_yield;
+ SSL.Abort_Undefer.all;
+ end Timed_Delay;
+
+ ---------------------
+ -- Monotonic_Clock --
+ ---------------------
+
+ function Monotonic_Clock return Duration is
+ TV : aliased struct_timeval;
+ Result : Interfaces.C.int;
+
+ begin
+ Result := gettimeofday (TV'Access, System.Null_Address);
+ pragma Assert (Result = 0);
+ return To_Duration (TV);
+ end Monotonic_Clock;
+
+ -------------------
+ -- RT_Resolution --
+ -------------------
+
+ function RT_Resolution return Duration is
+ begin
+ return 10#1.0#E-6;
+ end RT_Resolution;
+
+ ------------
+ -- Wakeup --
+ ------------
+
+ procedure Wakeup (T : Task_ID; Reason : System.Tasking.Task_States) is
+ pragma Unreferenced (Reason);
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_cond_signal (T.Common.LL.CV'Access);
+ pragma Assert (Result = 0);
+ end Wakeup;
+
+ -----------
+ -- Yield --
+ -----------
+
+ procedure Yield (Do_Yield : Boolean := True) is
+ Result : Interfaces.C.int;
+ pragma Unreferenced (Result);
+ begin
+ if Do_Yield then
+ Result := sched_yield;
+ end if;
+ end Yield;
+
+ ------------------
+ -- Set_Priority --
+ ------------------
+
+ procedure Set_Priority
+ (T : Task_ID;
+ Prio : System.Any_Priority;
+ Loss_Of_Inheritance : Boolean := False)
+ is
+ pragma Unreferenced (Loss_Of_Inheritance);
+
+ Result : Interfaces.C.int;
+ Param : aliased struct_sched_param;
+
+ begin
+ T.Common.Current_Priority := Prio;
+
+ if Priority_Ceiling_Emulation then
+ if T.Common.LL.Active_Priority < Prio then
+ T.Common.LL.Active_Priority := Prio;
+ end if;
+ end if;
+
+ -- Priorities are in range 1 .. 99 on GNU/Linux, so we map
+ -- map 0 .. 31 to 1 .. 32
+
+ Param.sched_priority := Interfaces.C.int (Prio) + 1;
+
+ if Time_Slice_Val > 0 then
+ Result := pthread_setschedparam
+ (T.Common.LL.Thread, SCHED_RR, Param'Access);
+
+ elsif FIFO_Within_Priorities or else Time_Slice_Val = 0 then
+ Result := pthread_setschedparam
+ (T.Common.LL.Thread, SCHED_FIFO, Param'Access);
+
+ else
+ Param.sched_priority := 0;
+ Result := pthread_setschedparam
+ (T.Common.LL.Thread, SCHED_OTHER, Param'Access);
+ end if;
+
+ pragma Assert (Result = 0 or else Result = EPERM);
+ end Set_Priority;
+
+ ------------------
+ -- Get_Priority --
+ ------------------
+
+ function Get_Priority (T : Task_ID) return System.Any_Priority is
+ begin
+ return T.Common.Current_Priority;
+ end Get_Priority;
+
+ ----------------
+ -- Enter_Task --
+ ----------------
+
+ procedure Enter_Task (Self_ID : Task_ID) is
+ begin
+ Self_ID.Common.LL.Thread := pthread_self;
+
+ Specific.Set (Self_ID);
+
+ Lock_RTS;
+
+ for J in Known_Tasks'Range loop
+ if Known_Tasks (J) = null then
+ Known_Tasks (J) := Self_ID;
+ Self_ID.Known_Tasks_Index := J;
+ exit;
+ end if;
+ end loop;
+
+ Unlock_RTS;
+ end Enter_Task;
+
+ --------------
+ -- New_ATCB --
+ --------------
+
+ function New_ATCB (Entry_Num : Task_Entry_Index) return Task_ID is
+ begin
+ return new Ada_Task_Control_Block (Entry_Num);
+ end New_ATCB;
+
+ -------------------
+ -- Is_Valid_Task --
+ -------------------
+
+ function Is_Valid_Task return Boolean renames Specific.Is_Valid_Task;
+
+ -----------------------------
+ -- Register_Foreign_Thread --
+ -----------------------------
+
+ function Register_Foreign_Thread return Task_ID is
+ begin
+ if Is_Valid_Task then
+ return Self;
+ else
+ return Register_Foreign_Thread (pthread_self);
+ end if;
+ end Register_Foreign_Thread;
+
+ --------------------
+ -- Initialize_TCB --
+ --------------------
+
+ procedure Initialize_TCB (Self_ID : Task_ID; Succeeded : out Boolean) is
+ Result : Interfaces.C.int;
+
+ begin
+ -- Give the task a unique serial number.
+
+ Self_ID.Serial_Number := Next_Serial_Number;
+ Next_Serial_Number := Next_Serial_Number + 1;
+ pragma Assert (Next_Serial_Number /= 0);
+
+ Self_ID.Common.LL.Thread := To_pthread_t (-1);
+
+ if not Single_Lock then
+ Result := pthread_mutex_init (Self_ID.Common.LL.L'Access,
+ Mutex_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result /= 0 then
+ Succeeded := False;
+ return;
+ end if;
+ end if;
+
+ Result := pthread_cond_init (Self_ID.Common.LL.CV'Access,
+ Cond_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = 0 then
+ Succeeded := True;
+ else
+ if not Single_Lock then
+ Result := pthread_mutex_destroy (Self_ID.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Succeeded := False;
+ end if;
+ end Initialize_TCB;
+
+ -----------------
+ -- Create_Task --
+ -----------------
+
+ procedure Create_Task
+ (T : Task_ID;
+ Wrapper : System.Address;
+ Stack_Size : System.Parameters.Size_Type;
+ Priority : System.Any_Priority;
+ Succeeded : out Boolean)
+ is
+ Adjusted_Stack_Size : Interfaces.C.size_t;
+
+ Attributes : aliased pthread_attr_t;
+ Result : Interfaces.C.int;
+
+ begin
+ if Stack_Size = Unspecified_Size then
+ Adjusted_Stack_Size := Interfaces.C.size_t (Default_Stack_Size);
+
+ elsif Stack_Size < Minimum_Stack_Size then
+ Adjusted_Stack_Size := Interfaces.C.size_t (Minimum_Stack_Size);
+
+ else
+ Adjusted_Stack_Size := Interfaces.C.size_t (Stack_Size);
+ end if;
+
+ Result := pthread_attr_init (Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result /= 0 then
+ Succeeded := False;
+ return;
+ end if;
+
+ Result :=
+ pthread_attr_setstacksize
+ (Attributes'Access, Adjusted_Stack_Size);
+ pragma Assert (Result = 0);
+
+ Result :=
+ pthread_attr_setdetachstate
+ (Attributes'Access, PTHREAD_CREATE_DETACHED);
+ pragma Assert (Result = 0);
+
+ -- Since the initial signal mask of a thread is inherited from the
+ -- creator, and the Environment task has all its signals masked, we
+ -- do not need to manipulate caller's signal mask at this point.
+ -- All tasks in RTS will have All_Tasks_Mask initially.
+
+ Result := pthread_create
+ (T.Common.LL.Thread'Access,
+ Attributes'Access,
+ Thread_Body_Access (Wrapper),
+ To_Address (T));
+ pragma Assert (Result = 0 or else Result = EAGAIN);
+
+ Succeeded := Result = 0;
+
+ Result := pthread_attr_destroy (Attributes'Access);
+ pragma Assert (Result = 0);
+
+ Set_Priority (T, Priority);
+ end Create_Task;
+
+ ------------------
+ -- Finalize_TCB --
+ ------------------
+
+ procedure Finalize_TCB (T : Task_ID) is
+ Result : Interfaces.C.int;
+ Tmp : Task_ID := T;
+ Is_Self : constant Boolean := T = Self;
+
+ procedure Free is new
+ Unchecked_Deallocation (Ada_Task_Control_Block, Task_ID);
+
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_destroy (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Result := pthread_cond_destroy (T.Common.LL.CV'Access);
+ pragma Assert (Result = 0);
+
+ if T.Known_Tasks_Index /= -1 then
+ Known_Tasks (T.Known_Tasks_Index) := null;
+ end if;
+
+ Free (Tmp);
+
+ if Is_Self then
+ Specific.Set (null);
+ end if;
+ end Finalize_TCB;
+
+ ---------------
+ -- Exit_Task --
+ ---------------
+
+ procedure Exit_Task is
+ begin
+ Specific.Set (null);
+ end Exit_Task;
+
+ ----------------
+ -- Abort_Task --
+ ----------------
+
+ procedure Abort_Task (T : Task_ID) is
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_kill (T.Common.LL.Thread,
+ Signal (System.Interrupt_Management.Abort_Task_Interrupt));
+ pragma Assert (Result = 0);
+ end Abort_Task;
+
+ ----------------
+ -- Check_Exit --
+ ----------------
+
+ -- Dummy version
+
+ function Check_Exit (Self_ID : ST.Task_ID) return Boolean is
+ pragma Unreferenced (Self_ID);
+
+ begin
+ return True;
+ end Check_Exit;
+
+ --------------------
+ -- Check_No_Locks --
+ --------------------
+
+ function Check_No_Locks (Self_ID : ST.Task_ID) return Boolean is
+ pragma Unreferenced (Self_ID);
+
+ begin
+ return True;
+ end Check_No_Locks;
+
+ ----------------------
+ -- Environment_Task --
+ ----------------------
+
+ function Environment_Task return Task_ID is
+ begin
+ return Environment_Task_ID;
+ end Environment_Task;
+
+ ------------------
+ -- Suspend_Task --
+ ------------------
+
+ function Suspend_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id) return Boolean
+ is
+ begin
+ if T.Common.LL.Thread /= Thread_Self then
+ return pthread_kill (T.Common.LL.Thread, SIGSTOP) = 0;
+ else
+ return True;
+ end if;
+ end Suspend_Task;
+
+ -----------------
+ -- Resume_Task --
+ -----------------
+
+ function Resume_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id) return Boolean
+ is
+ begin
+ if T.Common.LL.Thread /= Thread_Self then
+ return pthread_kill (T.Common.LL.Thread, SIGCONT) = 0;
+ else
+ return True;
+ end if;
+ end Resume_Task;
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize (Environment_Task : Task_ID) is
+ act : aliased struct_sigaction;
+ old_act : aliased struct_sigaction;
+ Tmp_Set : aliased sigset_t;
+ Result : Interfaces.C.int;
+
+ 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:
+
+ Default : constant Character := 's';
+ -- 'n' this interrupt not set by any Interrupt_State pragma
+ -- 'u' Interrupt_State pragma set state to User
+ -- 'r' Interrupt_State pragma set state to Runtime
+ -- 's' Interrupt_State pragma set state to System (use "default"
+ -- system handler)
+
+ begin
+ Environment_Task_ID := Environment_Task;
+
+ Initialize_Lock (Single_RTS_Lock'Access, RTS_Lock_Level);
+
+ -- Initialize the global RTS lock
+
+ Specific.Initialize (Environment_Task);
+
+ Enter_Task (Environment_Task);
+
+ -- Install the abort-signal handler
+
+ if State (System.Interrupt_Management.Abort_Task_Interrupt)
+ /= Default
+ then
+ act.sa_flags := 0;
+ act.sa_handler := Abort_Handler'Address;
+
+ Result := sigemptyset (Tmp_Set'Access);
+ pragma Assert (Result = 0);
+ act.sa_mask := Tmp_Set;
+
+ Result :=
+ sigaction
+ (Signal (Interrupt_Management.Abort_Task_Interrupt),
+ act'Unchecked_Access,
+ old_act'Unchecked_Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Initialize;
+
+begin
+ declare
+ Result : Interfaces.C.int;
+
+ begin
+ -- Mask Environment task for all signals. The original mask of the
+ -- Environment task will be recovered by Interrupt_Server task
+ -- during the elaboration of s-interr.adb.
+
+ System.Interrupt_Management.Operations.Set_Interrupt_Mask
+ (System.Interrupt_Management.Operations.All_Tasks_Mask'Access);
+
+ -- Prepare the set of signals that should unblocked in all tasks
+
+ Result := sigemptyset (Unblocked_Signal_Mask'Access);
+ pragma Assert (Result = 0);
+
+ for J in Interrupt_Management.Interrupt_ID loop
+ if System.Interrupt_Management.Keep_Unmasked (J) then
+ Result := sigaddset (Unblocked_Signal_Mask'Access, Signal (J));
+ pragma Assert (Result = 0);
+ end if;
+ end loop;
+
+ Result := pthread_mutexattr_init (Mutex_Attr'Access);
+ pragma Assert (Result = 0);
+
+ Result := pthread_condattr_init (Cond_Attr'Access);
+ pragma Assert (Result = 0);
+ end;
+end System.Task_Primitives.Operations;
diff --git a/gcc/ada/s-taprop-lynxos.adb b/gcc/ada/s-taprop-lynxos.adb
new file mode 100644
index 00000000000..6276d7f5092
--- /dev/null
+++ b/gcc/ada/s-taprop-lynxos.adb
@@ -0,0 +1,1184 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S . O P E R A T I O N S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2004, 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- --
+-- 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, 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, --
+-- 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 is a LynxOS version of this file, adapted to make
+-- SCHED_FIFO and ceiling locking (Annex D compliance) work properly
+
+-- This package contains all the GNULL primitives that interface directly
+-- with the underlying OS.
+
+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.Tasking.Debug;
+-- used for Known_Tasks
+
+with System.Task_Info;
+-- used for Task_Info_Type
+
+with Interfaces.C;
+-- used for int
+-- size_t
+
+with System.Interrupt_Management;
+-- used for Keep_Unmasked
+-- Abort_Task_Interrupt
+-- Interrupt_ID
+
+with System.Interrupt_Management.Operations;
+-- used for Set_Interrupt_Mask
+-- All_Tasks_Mask
+pragma Elaborate_All (System.Interrupt_Management.Operations);
+
+with System.Parameters;
+-- used for Size_Type
+
+with System.Tasking;
+-- used for Ada_Task_Control_Block
+-- Task_ID
+
+with System.Soft_Links;
+-- used for Defer/Undefer_Abort
+
+-- Note that we do not use System.Tasking.Initialization directly since
+-- this is a higher level package that we shouldn't depend on. For example
+-- when using the restricted run time, it is replaced by
+-- System.Tasking.Restricted.Initialization
+
+with System.OS_Primitives;
+-- used for Delay_Modes
+
+with Unchecked_Deallocation;
+
+package body System.Task_Primitives.Operations is
+
+ use System.Tasking.Debug;
+ use System.Tasking;
+ use Interfaces.C;
+ use System.OS_Interface;
+ use System.Parameters;
+ use System.OS_Primitives;
+
+ package SSL renames System.Soft_Links;
+
+ ----------------
+ -- Local Data --
+ ----------------
+
+ -- The followings are logically constants, but need to be initialized
+ -- at run time.
+
+ Single_RTS_Lock : aliased RTS_Lock;
+ -- This is a lock to allow only one thread of control in the RTS at
+ -- a time; it is used to execute in mutual exclusion from all other tasks.
+ -- Used mainly in Single_Lock mode, but also to protect All_Tasks_List
+
+ ATCB_Key : aliased pthread_key_t;
+ -- Key used to find the Ada Task_ID associated with a thread
+
+ Environment_Task_ID : Task_ID;
+ -- A variable to hold Task_ID for the environment task.
+
+ Locking_Policy : Character;
+ pragma Import (C, Locking_Policy, "__gl_locking_policy");
+ -- Value of the pragma Locking_Policy:
+ -- 'C' for Ceiling_Locking
+ -- 'I' for Inherit_Locking
+ -- ' ' for none.
+
+ Unblocked_Signal_Mask : aliased sigset_t;
+ -- The set of signals that should unblocked in all tasks
+
+ -- The followings are internal configuration constants needed.
+
+ Next_Serial_Number : Task_Serial_Number := 100;
+ -- We start at 100, to reserve some special values for
+ -- using in error checking.
+
+ Time_Slice_Val : Integer;
+ pragma Import (C, Time_Slice_Val, "__gl_time_slice_val");
+
+ Dispatching_Policy : Character;
+ pragma Import (C, Dispatching_Policy, "__gl_task_dispatching_policy");
+
+ FIFO_Within_Priorities : constant Boolean := Dispatching_Policy = 'F';
+ -- Indicates whether FIFO_Within_Priorities is set.
+
+ Foreign_Task_Elaborated : aliased Boolean := True;
+ -- Used to identified fake tasks (i.e., non-Ada Threads).
+
+ --------------------
+ -- Local Packages --
+ --------------------
+
+ package Specific is
+
+ procedure Initialize (Environment_Task : Task_ID);
+ pragma Inline (Initialize);
+ -- Initialize various data needed by this package.
+
+ function Is_Valid_Task return Boolean;
+ pragma Inline (Is_Valid_Task);
+ -- Does the current thread have an ATCB?
+
+ procedure Set (Self_Id : Task_ID);
+ pragma Inline (Set);
+ -- Set the self id for the current task.
+
+ function Self return Task_ID;
+ pragma Inline (Self);
+ -- Return a pointer to the Ada Task Control Block of the calling task.
+
+ end Specific;
+
+ package body Specific is separate;
+ -- The body of this package is target specific.
+
+ ---------------------------------
+ -- Support for foreign threads --
+ ---------------------------------
+
+ function Register_Foreign_Thread (Thread : Thread_Id) return Task_ID;
+ -- Allocate and Initialize a new ATCB for the current Thread.
+
+ function Register_Foreign_Thread
+ (Thread : Thread_Id) return Task_ID is separate;
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ procedure Abort_Handler (Sig : Signal);
+ -- Signal handler used to implement asynchronous abort.
+
+ procedure Set_OS_Priority (T : Task_ID; Prio : System.Any_Priority);
+ -- This procedure calls the scheduler of the OS to set thread's priority
+
+ -------------------
+ -- Abort_Handler --
+ -------------------
+
+ procedure Abort_Handler (Sig : Signal) is
+ pragma Unreferenced (Sig);
+
+ T : constant Task_ID := Self;
+ Result : Interfaces.C.int;
+ Old_Set : aliased sigset_t;
+
+ begin
+ -- It is not safe to raise an exception when using ZCX and the GCC
+ -- exception handling mechanism.
+
+ if ZCX_By_Default and then GCC_ZCX_Support then
+ return;
+ end if;
+
+ if T.Deferral_Level = 0
+ and then T.Pending_ATC_Level < T.ATC_Nesting_Level and then
+ not T.Aborting
+ then
+ T.Aborting := True;
+
+ -- Make sure signals used for RTS internal purpose are unmasked
+
+ Result :=
+ pthread_sigmask (SIG_UNBLOCK,
+ Unblocked_Signal_Mask'Unchecked_Access,
+ Old_Set'Unchecked_Access);
+ pragma Assert (Result = 0);
+
+ raise Standard'Abort_Signal;
+ end if;
+ end Abort_Handler;
+
+ -----------------
+ -- Stack_Guard --
+ -----------------
+
+ procedure Stack_Guard (T : ST.Task_ID; On : Boolean) is
+ Stack_Base : constant Address := Get_Stack_Base (T.Common.LL.Thread);
+ Guard_Page_Address : Address;
+
+ Res : Interfaces.C.int;
+
+ begin
+ if Stack_Base_Available then
+
+ -- Compute the guard page address
+
+ 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;
+
+ pragma Assert (Res = 0);
+ end if;
+ end Stack_Guard;
+
+ --------------------
+ -- Get_Thread_Id --
+ --------------------
+
+ function Get_Thread_Id (T : ST.Task_ID) return OSI.Thread_Id is
+ begin
+ return T.Common.LL.Thread;
+ end Get_Thread_Id;
+
+ ----------
+ -- Self --
+ ----------
+
+ function Self return Task_ID renames Specific.Self;
+
+ ---------------------
+ -- Initialize_Lock --
+ ---------------------
+
+ procedure Initialize_Lock
+ (Prio : System.Any_Priority;
+ L : access Lock)
+ is
+ Attributes : aliased pthread_mutexattr_t;
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_mutexattr_init (Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ raise Storage_Error;
+ end if;
+
+ if Locking_Policy = 'C' then
+ L.Ceiling := Prio;
+ end if;
+
+ Result := pthread_mutex_init (L.Mutex'Access, Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ raise Storage_Error;
+ end if;
+
+ Result := pthread_mutexattr_destroy (Attributes'Access);
+ pragma Assert (Result = 0);
+ end Initialize_Lock;
+
+ procedure Initialize_Lock (L : access RTS_Lock; Level : Lock_Level) is
+ pragma Unreferenced (Level);
+
+ Attributes : aliased pthread_mutexattr_t;
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_mutexattr_init (Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ raise Storage_Error;
+ end if;
+
+ Result := pthread_mutex_init (L, Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ Result := pthread_mutexattr_destroy (Attributes'Access);
+ raise Storage_Error;
+ end if;
+
+ Result := pthread_mutexattr_destroy (Attributes'Access);
+ pragma Assert (Result = 0);
+ end Initialize_Lock;
+
+ -------------------
+ -- Finalize_Lock --
+ -------------------
+
+ procedure Finalize_Lock (L : access Lock) is
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_mutex_destroy (L.Mutex'Access);
+ pragma Assert (Result = 0);
+ end Finalize_Lock;
+
+ procedure Finalize_Lock (L : access RTS_Lock) is
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_mutex_destroy (L);
+ pragma Assert (Result = 0);
+ end Finalize_Lock;
+
+ ----------------
+ -- Write_Lock --
+ ----------------
+
+ procedure Write_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ Result : Interfaces.C.int;
+ T : constant Task_ID := Self;
+
+ begin
+ if Locking_Policy = 'C' then
+ if T.Common.Current_Priority > L.Ceiling then
+ Ceiling_Violation := True;
+ return;
+ end if;
+
+ L.Saved_Priority := T.Common.Current_Priority;
+
+ if T.Common.Current_Priority < L.Ceiling then
+ Set_OS_Priority (T, L.Ceiling);
+ end if;
+ end if;
+
+ Result := pthread_mutex_lock (L.Mutex'Access);
+
+ -- Assume that the cause of EINVAL is a priority ceiling violation
+
+ Ceiling_Violation := (Result = EINVAL);
+ pragma Assert (Result = 0 or else Result = EINVAL);
+ end Write_Lock;
+
+ -- No tricks on RTS_Locks
+
+ procedure Write_Lock
+ (L : access RTS_Lock; Global_Lock : Boolean := False)
+ is
+ Result : Interfaces.C.int;
+ begin
+ if not Single_Lock or else Global_Lock then
+ Result := pthread_mutex_lock (L);
+ pragma Assert (Result = 0);
+ end if;
+ end Write_Lock;
+
+ procedure Write_Lock (T : Task_ID) is
+ Result : Interfaces.C.int;
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_lock (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Write_Lock;
+
+ ---------------
+ -- Read_Lock --
+ ---------------
+
+ procedure Read_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ begin
+ Write_Lock (L, Ceiling_Violation);
+ end Read_Lock;
+
+ ------------
+ -- Unlock --
+ ------------
+
+ procedure Unlock (L : access Lock) is
+ Result : Interfaces.C.int;
+ T : constant Task_ID := Self;
+
+ begin
+ Result := pthread_mutex_unlock (L.Mutex'Access);
+ pragma Assert (Result = 0);
+
+ if Locking_Policy = 'C' then
+ if T.Common.Current_Priority > L.Saved_Priority then
+ Set_OS_Priority (T, L.Saved_Priority);
+ end if;
+ end if;
+ end Unlock;
+
+ procedure Unlock (L : access RTS_Lock; Global_Lock : Boolean := False) is
+ Result : Interfaces.C.int;
+ begin
+ if not Single_Lock or else Global_Lock then
+ Result := pthread_mutex_unlock (L);
+ pragma Assert (Result = 0);
+ end if;
+ end Unlock;
+
+ procedure Unlock (T : Task_ID) is
+ Result : Interfaces.C.int;
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_unlock (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Unlock;
+
+ -----------
+ -- Sleep --
+ -----------
+
+ procedure Sleep
+ (Self_ID : Task_ID;
+ Reason : System.Tasking.Task_States)
+ 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;
+
+ -- EINTR is not considered a failure
+
+ pragma Assert (Result = 0 or else Result = EINTR);
+ end Sleep;
+
+ -----------------
+ -- Timed_Sleep --
+ -----------------
+
+ -- This is for use within the run-time system, so abort is
+ -- assumed to be already deferred, and the caller should be
+ -- holding its own ATCB lock.
+
+ procedure Timed_Sleep
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes;
+ Reason : Task_States;
+ Timedout : out Boolean;
+ Yielded : out Boolean)
+ is
+ pragma Unreferenced (Reason);
+
+ Check_Time : constant Duration := Monotonic_Clock;
+ Rel_Time : Duration;
+ Abs_Time : Duration;
+ Request : aliased timespec;
+ Result : Interfaces.C.int;
+
+ begin
+ Timedout := True;
+ Yielded := False;
+
+ if Mode = Relative then
+ Abs_Time := Duration'Min (Time, Max_Sensible_Delay) + Check_Time;
+
+ if Relative_Timed_Wait then
+ Rel_Time := Duration'Min (Max_Sensible_Delay, Time);
+ end if;
+
+ else
+ Abs_Time := Duration'Min (Check_Time + Max_Sensible_Delay, Time);
+
+ if Relative_Timed_Wait then
+ Rel_Time := Duration'Min (Max_Sensible_Delay, Time - Check_Time);
+ end if;
+ 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;
+
+ loop
+ exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level
+ or else Self_ID.Pending_Priority_Change;
+
+ 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;
+
+ exit when Abs_Time <= Monotonic_Clock;
+
+ if Result = 0 or Result = EINTR then
+
+ -- Somebody may have called Wakeup for us
+
+ Timedout := False;
+ exit;
+ end if;
+
+ pragma Assert (Result = ETIMEDOUT);
+ end loop;
+ end if;
+ end Timed_Sleep;
+
+ -----------------
+ -- Timed_Delay --
+ -----------------
+
+ -- This is for use in implementing delay statements, so we assume
+ -- the caller is abort-deferred but is holding no locks.
+
+ procedure Timed_Delay
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes)
+ is
+ Check_Time : constant Duration := Monotonic_Clock;
+ Abs_Time : Duration;
+ Rel_Time : Duration;
+ Request : aliased timespec;
+ Result : Interfaces.C.int;
+
+ begin
+ -- Only the little window between deferring abort and
+ -- locking Self_ID is the reason we need to
+ -- check for pending abort and priority change below!
+
+ SSL.Abort_Defer.all;
+
+ if Single_Lock then
+ Lock_RTS;
+ end if;
+
+ -- Comments needed in code below ???
+
+ Write_Lock (Self_ID);
+
+ if Mode = Relative then
+ Abs_Time := Duration'Min (Time, Max_Sensible_Delay) + Check_Time;
+
+ if Relative_Timed_Wait then
+ Rel_Time := Duration'Min (Max_Sensible_Delay, Time);
+ end if;
+
+ else
+ Abs_Time := Duration'Min (Check_Time + Max_Sensible_Delay, Time);
+
+ if Relative_Timed_Wait then
+ Rel_Time := Duration'Min (Max_Sensible_Delay, Time - Check_Time);
+ end if;
+ 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;
+
+ Self_ID.Common.State := Delay_Sleep;
+
+ loop
+ if Self_ID.Pending_Priority_Change then
+ Self_ID.Pending_Priority_Change := False;
+ Self_ID.Common.Base_Priority := Self_ID.New_Base_Priority;
+ Set_Priority (Self_ID, Self_ID.Common.Base_Priority);
+ end if;
+
+ 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;
+
+ exit when Abs_Time <= Monotonic_Clock;
+
+ pragma Assert (Result = 0
+ or else Result = ETIMEDOUT
+ or else Result = EINTR);
+ end loop;
+
+ Self_ID.Common.State := Runnable;
+ end if;
+
+ Unlock (Self_ID);
+
+ if Single_Lock then
+ Unlock_RTS;
+ end if;
+
+ Result := sched_yield;
+ SSL.Abort_Undefer.all;
+ end Timed_Delay;
+
+ ---------------------
+ -- Monotonic_Clock --
+ ---------------------
+
+ function Monotonic_Clock return Duration is
+ TS : aliased timespec;
+ Result : Interfaces.C.int;
+ begin
+ Result := clock_gettime
+ (clock_id => CLOCK_REALTIME, tp => TS'Unchecked_Access);
+ pragma Assert (Result = 0);
+ return To_Duration (TS);
+ end Monotonic_Clock;
+
+ -------------------
+ -- RT_Resolution --
+ -------------------
+
+ function RT_Resolution return Duration is
+ Res : aliased timespec;
+ Result : Interfaces.C.int;
+ begin
+ Result := clock_getres
+ (clock_id => CLOCK_REALTIME, Res => Res'Unchecked_Access);
+ pragma Assert (Result = 0);
+ return To_Duration (Res);
+ end RT_Resolution;
+
+ ------------
+ -- Wakeup --
+ ------------
+
+ procedure Wakeup (T : Task_ID; Reason : System.Tasking.Task_States) is
+ pragma Unreferenced (Reason);
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_cond_signal (T.Common.LL.CV'Access);
+ pragma Assert (Result = 0);
+ end Wakeup;
+
+ -----------
+ -- Yield --
+ -----------
+
+ procedure Yield (Do_Yield : Boolean := True) is
+ Result : Interfaces.C.int;
+ pragma Unreferenced (Result);
+ begin
+ if Do_Yield then
+ Result := sched_yield;
+ end if;
+ end Yield;
+
+ ------------------
+ -- Set_Priority --
+ ------------------
+
+ procedure Set_OS_Priority (T : Task_ID; Prio : System.Any_Priority) is
+ Result : Interfaces.C.int;
+ Param : aliased struct_sched_param;
+
+ begin
+ Param.sched_priority := Interfaces.C.int (Prio);
+
+ if Time_Slice_Supported and then Time_Slice_Val > 0 then
+ Result := pthread_setschedparam
+ (T.Common.LL.Thread, SCHED_RR, Param'Access);
+
+ elsif FIFO_Within_Priorities or else Time_Slice_Val = 0 then
+ Result := pthread_setschedparam
+ (T.Common.LL.Thread, SCHED_FIFO, Param'Access);
+
+ else
+ Result := pthread_setschedparam
+ (T.Common.LL.Thread, SCHED_OTHER, Param'Access);
+ end if;
+
+ pragma Assert (Result = 0);
+ end Set_OS_Priority;
+
+ type Prio_Array_Type is array (System.Any_Priority) of Integer;
+ pragma Atomic_Components (Prio_Array_Type);
+ Prio_Array : Prio_Array_Type;
+ -- Comments needed for these declarations ???
+
+ procedure Set_Priority
+ (T : Task_ID;
+ Prio : System.Any_Priority;
+ Loss_Of_Inheritance : Boolean := False)
+ is
+ Array_Item : Integer;
+
+ begin
+ Set_OS_Priority (T, Prio);
+
+ if Locking_Policy = 'C' then
+ -- Annex D requirements: loss of inheritance puts task at the
+ -- beginning of the queue for that prio; copied from 5ztaprop
+ -- (VxWorks)
+
+ if Loss_Of_Inheritance
+ and then Prio < T.Common.Current_Priority then
+
+ Array_Item := Prio_Array (T.Common.Base_Priority) + 1;
+ Prio_Array (T.Common.Base_Priority) := Array_Item;
+
+ loop
+ Yield;
+ exit when Array_Item = Prio_Array (T.Common.Base_Priority)
+ or else Prio_Array (T.Common.Base_Priority) = 1;
+ end loop;
+
+ Prio_Array (T.Common.Base_Priority) :=
+ Prio_Array (T.Common.Base_Priority) - 1;
+ end if;
+ end if;
+
+ T.Common.Current_Priority := Prio;
+ end Set_Priority;
+
+ ------------------
+ -- Get_Priority --
+ ------------------
+
+ function Get_Priority (T : Task_ID) return System.Any_Priority is
+ begin
+ return T.Common.Current_Priority;
+ end Get_Priority;
+
+ ----------------
+ -- Enter_Task --
+ ----------------
+
+ procedure Enter_Task (Self_ID : Task_ID) is
+ begin
+ Self_ID.Common.LL.Thread := pthread_self;
+ Self_ID.Common.LL.LWP := lwp_self;
+
+ Specific.Set (Self_ID);
+
+ Lock_RTS;
+
+ for J in Known_Tasks'Range loop
+ if Known_Tasks (J) = null then
+ Known_Tasks (J) := Self_ID;
+ Self_ID.Known_Tasks_Index := J;
+ exit;
+ end if;
+ end loop;
+
+ Unlock_RTS;
+ end Enter_Task;
+
+ --------------
+ -- New_ATCB --
+ --------------
+
+ function New_ATCB (Entry_Num : Task_Entry_Index) return Task_ID is
+ begin
+ return new Ada_Task_Control_Block (Entry_Num);
+ end New_ATCB;
+
+ -------------------
+ -- Is_Valid_Task --
+ -------------------
+
+ function Is_Valid_Task return Boolean renames Specific.Is_Valid_Task;
+
+ -----------------------------
+ -- Register_Foreign_Thread --
+ -----------------------------
+
+ function Register_Foreign_Thread return Task_ID is
+ begin
+ if Is_Valid_Task then
+ return Self;
+ else
+ return Register_Foreign_Thread (pthread_self);
+ end if;
+ end Register_Foreign_Thread;
+
+ ----------------------
+ -- Initialize_TCB --
+ ----------------------
+
+ procedure Initialize_TCB (Self_ID : Task_ID; Succeeded : out Boolean) is
+ Mutex_Attr : aliased pthread_mutexattr_t;
+ Result : Interfaces.C.int;
+ Cond_Attr : aliased pthread_condattr_t;
+
+ begin
+ -- Give the task a unique serial number.
+
+ Self_ID.Serial_Number := Next_Serial_Number;
+ Next_Serial_Number := Next_Serial_Number + 1;
+ pragma Assert (Next_Serial_Number /= 0);
+
+ if not Single_Lock then
+ Result := pthread_mutexattr_init (Mutex_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = 0 then
+ Result := pthread_mutex_init (Self_ID.Common.LL.L'Access,
+ Mutex_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+ end if;
+
+ if Result /= 0 then
+ Succeeded := False;
+ return;
+ end if;
+
+ Result := pthread_mutexattr_destroy (Mutex_Attr'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Result := pthread_condattr_init (Cond_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = 0 then
+ Result := pthread_cond_init (Self_ID.Common.LL.CV'Access,
+ Cond_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+ end if;
+
+ if Result = 0 then
+ Succeeded := True;
+ else
+ if not Single_Lock then
+ Result := pthread_mutex_destroy (Self_ID.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Succeeded := False;
+ end if;
+
+ Result := pthread_condattr_destroy (Cond_Attr'Access);
+ pragma Assert (Result = 0);
+ end Initialize_TCB;
+
+ -----------------
+ -- Create_Task --
+ -----------------
+
+ procedure Create_Task
+ (T : Task_ID;
+ Wrapper : System.Address;
+ Stack_Size : System.Parameters.Size_Type;
+ Priority : System.Any_Priority;
+ Succeeded : out Boolean)
+ is
+ Attributes : aliased pthread_attr_t;
+ Adjusted_Stack_Size : Interfaces.C.size_t;
+ Result : Interfaces.C.int;
+
+ use System.Task_Info;
+
+ begin
+ if Stack_Size = Unspecified_Size then
+ Adjusted_Stack_Size := Interfaces.C.size_t (Default_Stack_Size);
+
+ elsif Stack_Size < Minimum_Stack_Size then
+ Adjusted_Stack_Size := Interfaces.C.size_t (Minimum_Stack_Size);
+
+ else
+ Adjusted_Stack_Size := Interfaces.C.size_t (Stack_Size);
+ end if;
+
+ if Stack_Base_Available then
+
+ -- If Stack Checking is supported then allocate 2 additional pages:
+ --
+ -- In the worst case, stack is allocated at something like
+ -- N * Get_Page_Size - epsilon, we need to add the size for 2 pages
+ -- to be sure the effective stack size is greater than what
+ -- has been asked.
+
+ Adjusted_Stack_Size := Adjusted_Stack_Size + 2 * Get_Page_Size;
+ end if;
+
+ Result := pthread_attr_init (Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result /= 0 then
+ Succeeded := False;
+ return;
+ end if;
+
+ Result := pthread_attr_setdetachstate
+ (Attributes'Access, PTHREAD_CREATE_DETACHED);
+ pragma Assert (Result = 0);
+
+ Result := pthread_attr_setstacksize
+ (Attributes'Access, Adjusted_Stack_Size);
+ pragma Assert (Result = 0);
+
+ if T.Common.Task_Info /= Default_Scope then
+
+ -- We are assuming that Scope_Type has the same values than the
+ -- corresponding C macros
+
+ Result := pthread_attr_setscope
+ (Attributes'Access, Task_Info_Type'Pos (T.Common.Task_Info));
+ pragma Assert (Result = 0);
+ end if;
+
+ -- Since the initial signal mask of a thread is inherited from the
+ -- creator, and the Environment task has all its signals masked, we
+ -- do not need to manipulate caller's signal mask at this point.
+ -- All tasks in RTS will have All_Tasks_Mask initially.
+
+ Result := pthread_create
+ (T.Common.LL.Thread'Access,
+ Attributes'Access,
+ Thread_Body_Access (Wrapper),
+ To_Address (T));
+ pragma Assert (Result = 0 or else Result = EAGAIN);
+
+ Succeeded := Result = 0;
+
+ Result := pthread_attr_destroy (Attributes'Access);
+ pragma Assert (Result = 0);
+
+ Set_Priority (T, Priority);
+ end Create_Task;
+
+ ------------------
+ -- Finalize_TCB --
+ ------------------
+
+ procedure Finalize_TCB (T : Task_ID) is
+ Result : Interfaces.C.int;
+ Tmp : Task_ID := T;
+ Is_Self : constant Boolean := T = Self;
+
+ procedure Free is new
+ Unchecked_Deallocation (Ada_Task_Control_Block, Task_ID);
+
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_destroy (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Result := pthread_cond_destroy (T.Common.LL.CV'Access);
+ pragma Assert (Result = 0);
+
+ if T.Known_Tasks_Index /= -1 then
+ Known_Tasks (T.Known_Tasks_Index) := null;
+ end if;
+
+ Free (Tmp);
+
+ if Is_Self then
+ Result := st_setspecific (ATCB_Key, System.Null_Address);
+ pragma Assert (Result = 0);
+ end if;
+
+ end Finalize_TCB;
+
+ ---------------
+ -- Exit_Task --
+ ---------------
+
+ procedure Exit_Task is
+ begin
+ Specific.Set (null);
+ end Exit_Task;
+
+ ----------------
+ -- Abort_Task --
+ ----------------
+
+ procedure Abort_Task (T : Task_ID) is
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_kill (T.Common.LL.Thread,
+ Signal (System.Interrupt_Management.Abort_Task_Interrupt));
+ pragma Assert (Result = 0);
+ end Abort_Task;
+
+ ----------------
+ -- Check_Exit --
+ ----------------
+
+ -- Dummy versions
+
+ function Check_Exit (Self_ID : ST.Task_ID) return Boolean is
+ pragma Unreferenced (Self_ID);
+ begin
+ return True;
+ end Check_Exit;
+
+ --------------------
+ -- Check_No_Locks --
+ --------------------
+
+ function Check_No_Locks (Self_ID : ST.Task_ID) return Boolean is
+ pragma Unreferenced (Self_ID);
+ begin
+ return True;
+ end Check_No_Locks;
+
+ ----------------------
+ -- Environment_Task --
+ ----------------------
+
+ function Environment_Task return Task_ID is
+ begin
+ return Environment_Task_ID;
+ end Environment_Task;
+
+ --------------
+ -- Lock_RTS --
+ --------------
+
+ procedure Lock_RTS is
+ begin
+ Write_Lock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Lock_RTS;
+
+ ----------------
+ -- Unlock_RTS --
+ ----------------
+
+ procedure Unlock_RTS is
+ begin
+ Unlock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Unlock_RTS;
+
+ ------------------
+ -- Suspend_Task --
+ ------------------
+
+ function Suspend_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id)
+ return Boolean
+ is
+ pragma Unreferenced (T);
+ pragma Unreferenced (Thread_Self);
+ begin
+ return False;
+ end Suspend_Task;
+
+ -----------------
+ -- Resume_Task --
+ -----------------
+
+ function Resume_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id) return Boolean
+ is
+ pragma Unreferenced (T);
+ pragma Unreferenced (Thread_Self);
+ begin
+ return False;
+ end Resume_Task;
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize (Environment_Task : Task_ID) is
+ act : aliased struct_sigaction;
+ old_act : aliased struct_sigaction;
+ Tmp_Set : aliased sigset_t;
+ Result : Interfaces.C.int;
+
+ 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:
+
+ Default : constant Character := 's';
+ -- 'n' this interrupt not set by any Interrupt_State pragma
+ -- 'u' Interrupt_State pragma set state to User
+ -- 'r' Interrupt_State pragma set state to Runtime
+ -- 's' Interrupt_State pragma set state to System (use "default"
+ -- system handler)
+
+ begin
+ Environment_Task_ID := Environment_Task;
+
+ -- Initialize the lock used to synchronize chain of all ATCBs.
+
+ Initialize_Lock (Single_RTS_Lock'Access, RTS_Lock_Level);
+
+ Specific.Initialize (Environment_Task);
+
+ Enter_Task (Environment_Task);
+
+ -- Install the abort-signal handler
+
+ if State (System.Interrupt_Management.Abort_Task_Interrupt)
+ /= Default
+ then
+ act.sa_flags := 0;
+ act.sa_handler := Abort_Handler'Address;
+
+ Result := sigemptyset (Tmp_Set'Access);
+ pragma Assert (Result = 0);
+ act.sa_mask := Tmp_Set;
+
+ Result :=
+ sigaction
+ (Signal (System.Interrupt_Management.Abort_Task_Interrupt),
+ act'Unchecked_Access,
+ old_act'Unchecked_Access);
+
+ pragma Assert (Result = 0);
+ end if;
+ end Initialize;
+
+begin
+ declare
+ Result : Interfaces.C.int;
+
+ begin
+ -- Mask Environment task for all signals. The original mask of the
+ -- Environment task will be recovered by Interrupt_Server task
+ -- during the elaboration of s-interr.adb.
+
+ System.Interrupt_Management.Operations.Set_Interrupt_Mask
+ (System.Interrupt_Management.Operations.All_Tasks_Mask'Access);
+
+ -- Prepare the set of signals that should unblocked in all tasks
+
+ Result := sigemptyset (Unblocked_Signal_Mask'Access);
+ pragma Assert (Result = 0);
+
+ for J in Interrupt_Management.Interrupt_ID loop
+ if System.Interrupt_Management.Keep_Unmasked (J) then
+ Result := sigaddset (Unblocked_Signal_Mask'Access, Signal (J));
+ pragma Assert (Result = 0);
+ end if;
+ end loop;
+ end;
+end System.Task_Primitives.Operations;
diff --git a/gcc/ada/s-taprop-mingw.adb b/gcc/ada/s-taprop-mingw.adb
new file mode 100644
index 00000000000..1e24de0c6ec
--- /dev/null
+++ b/gcc/ada/s-taprop-mingw.adb
@@ -0,0 +1,1106 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S . O P E R A T I O N S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2004, 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- --
+-- 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, 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, --
+-- 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 is a NT (native) version of this package
+
+-- This package contains all the GNULL primitives that interface directly
+-- with the underlying OS.
+
+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.Tasking.Debug;
+-- used for Known_Tasks
+
+with Interfaces.C;
+-- used for int
+-- size_t
+
+with Interfaces.C.Strings;
+-- used for Null_Ptr
+
+with System.OS_Interface;
+-- used for various type, constant, and operations
+
+with System.Parameters;
+-- used for Size_Type
+
+with System.Tasking;
+-- used for Ada_Task_Control_Block
+-- Task_ID
+
+with System.Soft_Links;
+-- used for Defer/Undefer_Abort
+-- to initialize TSD for a C thread, in function Self
+
+-- Note that we do not use System.Tasking.Initialization directly since
+-- this is a higher level package that we shouldn't depend on. For example
+-- when using the restricted run time, it is replaced by
+-- System.Tasking.Restricted.Initialization
+
+with System.OS_Primitives;
+-- used for Delay_Modes
+
+with System.Task_Info;
+-- used for Unspecified_Task_Info
+
+with Unchecked_Deallocation;
+
+package body System.Task_Primitives.Operations is
+
+ use System.Tasking.Debug;
+ use System.Tasking;
+ use Interfaces.C;
+ use Interfaces.C.Strings;
+ use System.OS_Interface;
+ use System.Parameters;
+ use System.OS_Primitives;
+
+ pragma Link_With ("-Xlinker --stack=0x800000,0x1000");
+ -- Change the stack size (8 MB) for tasking programs on Windows. This
+ -- permit to have more than 30 tasks running at the same time. Note that
+ -- we set the stack size for non tasking programs on System unit.
+
+ package SSL renames System.Soft_Links;
+
+ ----------------
+ -- Local Data --
+ ----------------
+
+ Environment_Task_ID : Task_ID;
+ -- A variable to hold Task_ID for the environment task.
+
+ Single_RTS_Lock : aliased RTS_Lock;
+ -- This is a lock to allow only one thread of control in the RTS at
+ -- a time; it is used to execute in mutual exclusion from all other tasks.
+ -- Used mainly in Single_Lock mode, but also to protect All_Tasks_List
+
+ Time_Slice_Val : Integer;
+ pragma Import (C, Time_Slice_Val, "__gl_time_slice_val");
+
+ Dispatching_Policy : Character;
+ pragma Import (C, Dispatching_Policy, "__gl_task_dispatching_policy");
+
+ FIFO_Within_Priorities : constant Boolean := Dispatching_Policy = 'F';
+ -- Indicates whether FIFO_Within_Priorities is set.
+
+ Foreign_Task_Elaborated : aliased Boolean := True;
+ -- Used to identified fake tasks (i.e., non-Ada Threads).
+
+ ------------------------------------
+ -- The thread local storage index --
+ ------------------------------------
+
+ TlsIndex : DWORD;
+ pragma Export (Ada, TlsIndex);
+ -- To ensure that this variable won't be local to this package, since
+ -- in some cases, inlining forces this variable to be global anyway.
+
+ --------------------
+ -- Local Packages --
+ --------------------
+
+ package Specific is
+
+ function Is_Valid_Task return Boolean;
+ pragma Inline (Is_Valid_Task);
+ -- Does executing thread have a TCB?
+
+ procedure Set (Self_Id : Task_ID);
+ pragma Inline (Set);
+ -- Set the self id for the current task.
+
+ end Specific;
+
+ package body Specific is
+
+ function Is_Valid_Task return Boolean is
+ begin
+ return TlsGetValue (TlsIndex) /= System.Null_Address;
+ end Is_Valid_Task;
+
+ procedure Set (Self_Id : Task_ID) is
+ Succeeded : BOOL;
+ begin
+ Succeeded := TlsSetValue (TlsIndex, To_Address (Self_Id));
+ pragma Assert (Succeeded = True);
+ end Set;
+
+ end Specific;
+
+ ---------------------------------
+ -- Support for foreign threads --
+ ---------------------------------
+
+ function Register_Foreign_Thread (Thread : Thread_Id) return Task_ID;
+ -- Allocate and Initialize a new ATCB for the current Thread.
+
+ function Register_Foreign_Thread
+ (Thread : Thread_Id) return Task_ID is separate;
+
+ ----------------------------------
+ -- Condition Variable Functions --
+ ----------------------------------
+
+ procedure Initialize_Cond (Cond : access Condition_Variable);
+ -- Initialize given condition variable Cond
+
+ procedure Finalize_Cond (Cond : access Condition_Variable);
+ -- Finalize given condition variable Cond.
+
+ procedure Cond_Signal (Cond : access Condition_Variable);
+ -- Signal condition variable Cond
+
+ procedure Cond_Wait
+ (Cond : access Condition_Variable;
+ L : access RTS_Lock);
+ -- Wait on conditional variable Cond, using lock L
+
+ procedure Cond_Timed_Wait
+ (Cond : access Condition_Variable;
+ L : access RTS_Lock;
+ Rel_Time : Duration;
+ Timed_Out : out Boolean;
+ Status : out Integer);
+ -- Do timed wait on condition variable Cond using lock L. The duration
+ -- of the timed wait is given by Rel_Time. When the condition is
+ -- signalled, Timed_Out shows whether or not a time out occurred.
+ -- Status is only valid if Timed_Out is False, in which case it
+ -- shows whether Cond_Timed_Wait completed successfully.
+
+ ---------------------
+ -- Initialize_Cond --
+ ---------------------
+
+ procedure Initialize_Cond (Cond : access Condition_Variable) is
+ hEvent : HANDLE;
+
+ begin
+ hEvent := CreateEvent (null, True, False, Null_Ptr);
+ pragma Assert (hEvent /= 0);
+ Cond.all := Condition_Variable (hEvent);
+ end Initialize_Cond;
+
+ -------------------
+ -- Finalize_Cond --
+ -------------------
+
+ -- No such problem here, DosCloseEventSem has been derived.
+ -- What does such refer to in above comment???
+
+ procedure Finalize_Cond (Cond : access Condition_Variable) is
+ Result : BOOL;
+ begin
+ Result := CloseHandle (HANDLE (Cond.all));
+ pragma Assert (Result = True);
+ end Finalize_Cond;
+
+ -----------------
+ -- Cond_Signal --
+ -----------------
+
+ procedure Cond_Signal (Cond : access Condition_Variable) is
+ Result : BOOL;
+ begin
+ Result := SetEvent (HANDLE (Cond.all));
+ pragma Assert (Result = True);
+ end Cond_Signal;
+
+ ---------------
+ -- Cond_Wait --
+ ---------------
+
+ -- Pre-assertion: Cond is posted
+ -- L is locked.
+
+ -- Post-assertion: Cond is posted
+ -- L is locked.
+
+ procedure Cond_Wait
+ (Cond : access Condition_Variable;
+ L : access RTS_Lock)
+ is
+ Result : DWORD;
+ Result_Bool : BOOL;
+
+ begin
+ -- Must reset Cond BEFORE L is unlocked.
+
+ Result_Bool := ResetEvent (HANDLE (Cond.all));
+ pragma Assert (Result_Bool = True);
+ Unlock (L);
+
+ -- No problem if we are interrupted here: if the condition is signaled,
+ -- WaitForSingleObject will simply not block
+
+ Result := WaitForSingleObject (HANDLE (Cond.all), Wait_Infinite);
+ pragma Assert (Result = 0);
+
+ Write_Lock (L);
+ end Cond_Wait;
+
+ ---------------------
+ -- Cond_Timed_Wait --
+ ---------------------
+
+ -- Pre-assertion: Cond is posted
+ -- L is locked.
+
+ -- Post-assertion: Cond is posted
+ -- L is locked.
+
+ procedure Cond_Timed_Wait
+ (Cond : access Condition_Variable;
+ L : access RTS_Lock;
+ Rel_Time : Duration;
+ Timed_Out : out Boolean;
+ Status : out Integer)
+ is
+ Time_Out_Max : constant DWORD := 16#FFFF0000#;
+ -- NT 4 cannot handle timeout values that are too large,
+ -- e.g. DWORD'Last - 1
+
+ Time_Out : DWORD;
+ Result : BOOL;
+ Wait_Result : DWORD;
+
+ begin
+ -- Must reset Cond BEFORE L is unlocked.
+
+ Result := ResetEvent (HANDLE (Cond.all));
+ pragma Assert (Result = True);
+ Unlock (L);
+
+ -- No problem if we are interrupted here: if the condition is signaled,
+ -- 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;
+
+ Wait_Result := WaitForSingleObject (HANDLE (Cond.all), Time_Out);
+
+ if Wait_Result = WAIT_TIMEOUT then
+ Timed_Out := True;
+ Wait_Result := 0;
+ else
+ Timed_Out := False;
+ end if;
+ end if;
+
+ Write_Lock (L);
+
+ -- Ensure post-condition
+
+ if Timed_Out then
+ Result := SetEvent (HANDLE (Cond.all));
+ pragma Assert (Result = True);
+ end if;
+
+ Status := Integer (Wait_Result);
+ end Cond_Timed_Wait;
+
+ ------------------
+ -- Stack_Guard --
+ ------------------
+
+ -- The underlying thread system sets a guard page at the
+ -- bottom of a thread stack, so nothing is needed.
+ -- ??? Check the comment above
+
+ procedure Stack_Guard (T : ST.Task_ID; On : Boolean) is
+ pragma Warnings (Off, T);
+ pragma Warnings (Off, On);
+
+ begin
+ null;
+ end Stack_Guard;
+
+ --------------------
+ -- Get_Thread_Id --
+ --------------------
+
+ function Get_Thread_Id (T : ST.Task_ID) return OSI.Thread_Id is
+ begin
+ return T.Common.LL.Thread;
+ end Get_Thread_Id;
+
+ ----------
+ -- Self --
+ ----------
+
+ function Self return Task_ID is
+ Self_Id : constant Task_ID := To_Task_ID (TlsGetValue (TlsIndex));
+ begin
+ if Self_Id = null then
+ return Register_Foreign_Thread (GetCurrentThread);
+ else
+ return Self_Id;
+ end if;
+ end Self;
+
+ ---------------------
+ -- Initialize_Lock --
+ ---------------------
+
+ -- Note: mutexes and cond_variables needed per-task basis are
+ -- initialized in Intialize_TCB and the Storage_Error is handled.
+ -- Other mutexes (such as RTS_Lock, Memory_Lock...) used in
+ -- the RTS is initialized before any status change of RTS.
+ -- Therefore raising Storage_Error in the following routines
+ -- should be able to be handled safely.
+
+ procedure Initialize_Lock
+ (Prio : System.Any_Priority;
+ L : access Lock)
+ is
+ begin
+ InitializeCriticalSection (L.Mutex'Access);
+ L.Owner_Priority := 0;
+ L.Priority := Prio;
+ end Initialize_Lock;
+
+ procedure Initialize_Lock (L : access RTS_Lock; Level : Lock_Level) is
+ pragma Unreferenced (Level);
+
+ begin
+ InitializeCriticalSection (CRITICAL_SECTION (L.all)'Unrestricted_Access);
+ end Initialize_Lock;
+
+ -------------------
+ -- Finalize_Lock --
+ -------------------
+
+ procedure Finalize_Lock (L : access Lock) is
+ begin
+ DeleteCriticalSection (L.Mutex'Access);
+ end Finalize_Lock;
+
+ procedure Finalize_Lock (L : access RTS_Lock) is
+ begin
+ DeleteCriticalSection (CRITICAL_SECTION (L.all)'Unrestricted_Access);
+ end Finalize_Lock;
+
+ ----------------
+ -- Write_Lock --
+ ----------------
+
+ procedure Write_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ begin
+ L.Owner_Priority := Get_Priority (Self);
+
+ if L.Priority < L.Owner_Priority then
+ Ceiling_Violation := True;
+ return;
+ end if;
+
+ EnterCriticalSection (L.Mutex'Access);
+
+ Ceiling_Violation := False;
+ end Write_Lock;
+
+ procedure Write_Lock
+ (L : access RTS_Lock;
+ Global_Lock : Boolean := False)
+ is
+ begin
+ if not Single_Lock or else Global_Lock then
+ EnterCriticalSection (CRITICAL_SECTION (L.all)'Unrestricted_Access);
+ end if;
+ end Write_Lock;
+
+ procedure Write_Lock (T : Task_ID) is
+ begin
+ if not Single_Lock then
+ EnterCriticalSection
+ (CRITICAL_SECTION (T.Common.LL.L)'Unrestricted_Access);
+ end if;
+ end Write_Lock;
+
+ ---------------
+ -- Read_Lock --
+ ---------------
+
+ procedure Read_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ begin
+ Write_Lock (L, Ceiling_Violation);
+ end Read_Lock;
+
+ ------------
+ -- Unlock --
+ ------------
+
+ procedure Unlock (L : access Lock) is
+ begin
+ LeaveCriticalSection (L.Mutex'Access);
+ end Unlock;
+
+ procedure Unlock (L : access RTS_Lock; Global_Lock : Boolean := False) is
+ begin
+ if not Single_Lock or else Global_Lock then
+ LeaveCriticalSection (CRITICAL_SECTION (L.all)'Unrestricted_Access);
+ end if;
+ end Unlock;
+
+ procedure Unlock (T : Task_ID) is
+ begin
+ if not Single_Lock then
+ LeaveCriticalSection
+ (CRITICAL_SECTION (T.Common.LL.L)'Unrestricted_Access);
+ end if;
+ end Unlock;
+
+ -----------
+ -- Sleep --
+ -----------
+
+ procedure Sleep
+ (Self_ID : Task_ID;
+ Reason : System.Tasking.Task_States)
+ is
+ pragma Unreferenced (Reason);
+
+ begin
+ pragma Assert (Self_ID = Self);
+
+ if Single_Lock then
+ Cond_Wait (Self_ID.Common.LL.CV'Access, Single_RTS_Lock'Access);
+ else
+ Cond_Wait (Self_ID.Common.LL.CV'Access, Self_ID.Common.LL.L'Access);
+ end if;
+
+ if Self_ID.Deferral_Level = 0
+ and then Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level
+ then
+ Unlock (Self_ID);
+ raise Standard'Abort_Signal;
+ end if;
+ end Sleep;
+
+ -----------------
+ -- Timed_Sleep --
+ -----------------
+
+ -- This is for use within the run-time system, so abort is
+ -- assumed to be already deferred, and the caller should be
+ -- holding its own ATCB lock.
+
+ procedure Timed_Sleep
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes;
+ Reason : System.Tasking.Task_States;
+ Timedout : out Boolean;
+ Yielded : out Boolean)
+ is
+ pragma Unreferenced (Reason);
+ Check_Time : Duration := Monotonic_Clock;
+ Rel_Time : Duration;
+ Abs_Time : Duration;
+ Result : Integer;
+
+ Local_Timedout : Boolean;
+
+ begin
+ Timedout := True;
+ Yielded := False;
+
+ if Mode = Relative then
+ Rel_Time := Time;
+ Abs_Time := Duration'Min (Time, Max_Sensible_Delay) + Check_Time;
+ else
+ Rel_Time := Time - Check_Time;
+ Abs_Time := Time;
+ end if;
+
+ if Rel_Time > 0.0 then
+ loop
+ exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level
+ or else Self_ID.Pending_Priority_Change;
+
+ if Single_Lock then
+ Cond_Timed_Wait (Self_ID.Common.LL.CV'Access,
+ Single_RTS_Lock'Access, Rel_Time, Local_Timedout, Result);
+ else
+ Cond_Timed_Wait (Self_ID.Common.LL.CV'Access,
+ Self_ID.Common.LL.L'Access, Rel_Time, Local_Timedout, Result);
+ end if;
+
+ Check_Time := Monotonic_Clock;
+ exit when Abs_Time <= Check_Time;
+
+ if not Local_Timedout then
+
+ -- Somebody may have called Wakeup for us
+
+ Timedout := False;
+ exit;
+ end if;
+
+ Rel_Time := Abs_Time - Check_Time;
+ end loop;
+ end if;
+ end Timed_Sleep;
+
+ -----------------
+ -- Timed_Delay --
+ -----------------
+
+ procedure Timed_Delay
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes)
+ is
+ Check_Time : Duration := Monotonic_Clock;
+ Rel_Time : Duration;
+ Abs_Time : Duration;
+ Result : Integer;
+ Timedout : Boolean;
+
+ begin
+ -- Only the little window between deferring abort and
+ -- locking Self_ID is the reason we need to
+ -- check for pending abort and priority change below!
+
+ SSL.Abort_Defer.all;
+
+ if Single_Lock then
+ Lock_RTS;
+ end if;
+
+ Write_Lock (Self_ID);
+
+ if Mode = Relative then
+ Rel_Time := Time;
+ Abs_Time := Time + Check_Time;
+ else
+ Rel_Time := Time - Check_Time;
+ Abs_Time := Time;
+ end if;
+
+ if Rel_Time > 0.0 then
+ Self_ID.Common.State := Delay_Sleep;
+
+ loop
+ if Self_ID.Pending_Priority_Change then
+ Self_ID.Pending_Priority_Change := False;
+ Self_ID.Common.Base_Priority := Self_ID.New_Base_Priority;
+ Set_Priority (Self_ID, Self_ID.Common.Base_Priority);
+ end if;
+
+ exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level;
+
+ if Single_Lock then
+ Cond_Timed_Wait (Self_ID.Common.LL.CV'Access,
+ Single_RTS_Lock'Access, Rel_Time, Timedout, Result);
+ else
+ Cond_Timed_Wait (Self_ID.Common.LL.CV'Access,
+ Self_ID.Common.LL.L'Access, Rel_Time, Timedout, Result);
+ end if;
+
+ Check_Time := Monotonic_Clock;
+ exit when Abs_Time <= Check_Time;
+
+ Rel_Time := Abs_Time - Check_Time;
+ end loop;
+
+ Self_ID.Common.State := Runnable;
+ end if;
+
+ Unlock (Self_ID);
+
+ if Single_Lock then
+ Unlock_RTS;
+ end if;
+
+ Yield;
+ SSL.Abort_Undefer.all;
+ end Timed_Delay;
+
+ ------------
+ -- Wakeup --
+ ------------
+
+ procedure Wakeup (T : Task_ID; Reason : System.Tasking.Task_States) is
+ pragma Unreferenced (Reason);
+
+ begin
+ Cond_Signal (T.Common.LL.CV'Access);
+ end Wakeup;
+
+ -----------
+ -- Yield --
+ -----------
+
+ procedure Yield (Do_Yield : Boolean := True) is
+ begin
+ if Do_Yield then
+ Sleep (0);
+ end if;
+ end Yield;
+
+ ------------------
+ -- Set_Priority --
+ ------------------
+
+ type Prio_Array_Type is array (System.Any_Priority) of Integer;
+ pragma Atomic_Components (Prio_Array_Type);
+
+ Prio_Array : Prio_Array_Type;
+ -- Global array containing the id of the currently running task for
+ -- each priority.
+ --
+ -- Note: we assume that we are on a single processor with run-til-blocked
+ -- scheduling.
+
+ procedure Set_Priority
+ (T : Task_ID;
+ Prio : System.Any_Priority;
+ Loss_Of_Inheritance : Boolean := False)
+ is
+ Res : BOOL;
+ Array_Item : Integer;
+
+ begin
+ Res := SetThreadPriority
+ (T.Common.LL.Thread, Interfaces.C.int (Underlying_Priorities (Prio)));
+ pragma Assert (Res = True);
+
+ if FIFO_Within_Priorities then
+
+ -- Annex D requirement [RM D.2.2 par. 9]:
+ -- If the task drops its priority due to the loss of inherited
+ -- priority, it is added at the head of the ready queue for its
+ -- new active priority.
+
+ if Loss_Of_Inheritance
+ and then Prio < T.Common.Current_Priority
+ then
+ Array_Item := Prio_Array (T.Common.Base_Priority) + 1;
+ Prio_Array (T.Common.Base_Priority) := Array_Item;
+
+ loop
+ -- Let some processes a chance to arrive
+
+ Yield;
+
+ -- Then wait for our turn to proceed
+
+ exit when Array_Item = Prio_Array (T.Common.Base_Priority)
+ or else Prio_Array (T.Common.Base_Priority) = 1;
+ end loop;
+
+ Prio_Array (T.Common.Base_Priority) :=
+ Prio_Array (T.Common.Base_Priority) - 1;
+ end if;
+ end if;
+
+ T.Common.Current_Priority := Prio;
+ end Set_Priority;
+
+ ------------------
+ -- Get_Priority --
+ ------------------
+
+ function Get_Priority (T : Task_ID) return System.Any_Priority is
+ begin
+ return T.Common.Current_Priority;
+ end Get_Priority;
+
+ ----------------
+ -- Enter_Task --
+ ----------------
+
+ -- There were two paths were we needed to call Enter_Task :
+ -- 1) from System.Task_Primitives.Operations.Initialize
+ -- 2) from System.Tasking.Stages.Task_Wrapper
+ --
+ -- The thread initialisation has to be done only for the first case.
+ --
+ -- This is because the GetCurrentThread NT call does not return the
+ -- real thread handler but only a "pseudo" one. It is not possible to
+ -- release the thread handle and free the system ressources from this
+ -- "pseudo" handle. So we really want to keep the real thread handle
+ -- set in System.Task_Primitives.Operations.Create_Task during the
+ -- thread creation.
+
+ procedure Enter_Task (Self_ID : Task_ID) is
+ procedure Init_Float;
+ pragma Import (C, Init_Float, "__gnat_init_float");
+ -- Properly initializes the FPU for x86 systems.
+
+ begin
+ Specific.Set (Self_ID);
+ Init_Float;
+
+ Self_ID.Common.LL.Thread_Id := GetCurrentThreadId;
+
+ Lock_RTS;
+
+ for J in Known_Tasks'Range loop
+ if Known_Tasks (J) = null then
+ Known_Tasks (J) := Self_ID;
+ Self_ID.Known_Tasks_Index := J;
+ exit;
+ end if;
+ end loop;
+
+ Unlock_RTS;
+ end Enter_Task;
+
+ --------------
+ -- New_ATCB --
+ --------------
+
+ function New_ATCB (Entry_Num : Task_Entry_Index) return Task_ID is
+ begin
+ return new Ada_Task_Control_Block (Entry_Num);
+ end New_ATCB;
+
+ -------------------
+ -- Is_Valid_Task --
+ -------------------
+
+ function Is_Valid_Task return Boolean renames Specific.Is_Valid_Task;
+
+ -----------------------------
+ -- Register_Foreign_Thread --
+ -----------------------------
+
+ function Register_Foreign_Thread return Task_ID is
+ begin
+ if Is_Valid_Task then
+ return Self;
+ else
+ return Register_Foreign_Thread (GetCurrentThread);
+ end if;
+ end Register_Foreign_Thread;
+
+ --------------------
+ -- Initialize_TCB --
+ --------------------
+
+ procedure Initialize_TCB (Self_ID : Task_ID; Succeeded : out Boolean) is
+ begin
+ -- Initialize thread ID to 0, this is needed to detect threads that
+ -- are not yet activated.
+
+ Self_ID.Common.LL.Thread := 0;
+
+ Initialize_Cond (Self_ID.Common.LL.CV'Access);
+
+ if not Single_Lock then
+ Initialize_Lock (Self_ID.Common.LL.L'Access, ATCB_Level);
+ end if;
+
+ Succeeded := True;
+ end Initialize_TCB;
+
+ -----------------
+ -- Create_Task --
+ -----------------
+
+ procedure Create_Task
+ (T : Task_ID;
+ Wrapper : System.Address;
+ Stack_Size : System.Parameters.Size_Type;
+ Priority : System.Any_Priority;
+ Succeeded : out Boolean)
+ is
+ hTask : HANDLE;
+ TaskId : aliased DWORD;
+ pTaskParameter : System.OS_Interface.PVOID;
+ dwStackSize : DWORD;
+ Result : DWORD;
+ Entry_Point : PTHREAD_START_ROUTINE;
+
+ begin
+ pTaskParameter := To_Address (T);
+
+ if Stack_Size = Unspecified_Size then
+ dwStackSize := DWORD (Default_Stack_Size);
+
+ elsif Stack_Size < Minimum_Stack_Size then
+ dwStackSize := DWORD (Minimum_Stack_Size);
+
+ else
+ dwStackSize := DWORD (Stack_Size);
+ end if;
+
+ Entry_Point := To_PTHREAD_START_ROUTINE (Wrapper);
+
+ hTask := CreateThread
+ (null,
+ dwStackSize,
+ Entry_Point,
+ pTaskParameter,
+ DWORD (Create_Suspended),
+ TaskId'Unchecked_Access);
+
+ -- Step 1: Create the thread in blocked mode
+
+ if hTask = 0 then
+ raise Storage_Error;
+ end if;
+
+ -- Step 2: set its TCB
+
+ T.Common.LL.Thread := hTask;
+
+ -- Step 3: set its priority (child has inherited priority from parent)
+
+ Set_Priority (T, Priority);
+
+ if Time_Slice_Val = 0 or else FIFO_Within_Priorities then
+ -- Here we need Annex E semantics so we disable the NT priority
+ -- boost. A priority boost is temporarily given by the system to a
+ -- thread when it is taken out of a wait state.
+
+ SetThreadPriorityBoost (hTask, DisablePriorityBoost => True);
+ end if;
+
+ -- Step 4: Now, start it for good:
+
+ Result := ResumeThread (hTask);
+ pragma Assert (Result = 1);
+
+ Succeeded := Result = 1;
+ end Create_Task;
+
+ ------------------
+ -- Finalize_TCB --
+ ------------------
+
+ procedure Finalize_TCB (T : Task_ID) is
+ Self_ID : Task_ID := T;
+ Result : DWORD;
+ Succeeded : BOOL;
+ Is_Self : constant Boolean := T = Self;
+
+ procedure Free is new
+ Unchecked_Deallocation (Ada_Task_Control_Block, Task_ID);
+
+ begin
+ if not Single_Lock then
+ Finalize_Lock (T.Common.LL.L'Access);
+ end if;
+
+ Finalize_Cond (T.Common.LL.CV'Access);
+
+ if T.Known_Tasks_Index /= -1 then
+ Known_Tasks (T.Known_Tasks_Index) := null;
+ end if;
+
+ if Self_ID.Common.LL.Thread /= 0 then
+
+ -- This task has been activated. Wait for the thread to terminate
+ -- then close it. this is needed to release system ressources.
+
+ Result := WaitForSingleObject (T.Common.LL.Thread, Wait_Infinite);
+ pragma Assert (Result /= WAIT_FAILED);
+ Succeeded := CloseHandle (T.Common.LL.Thread);
+ pragma Assert (Succeeded = True);
+ end if;
+
+ Free (Self_ID);
+
+ if Is_Self then
+ Specific.Set (null);
+ end if;
+ end Finalize_TCB;
+
+ ---------------
+ -- Exit_Task --
+ ---------------
+
+ procedure Exit_Task is
+ begin
+ Specific.Set (null);
+ end Exit_Task;
+
+ ----------------
+ -- Abort_Task --
+ ----------------
+
+ procedure Abort_Task (T : Task_ID) is
+ pragma Unreferenced (T);
+ begin
+ null;
+ end Abort_Task;
+
+ ----------------------
+ -- Environment_Task --
+ ----------------------
+
+ function Environment_Task return Task_ID is
+ begin
+ return Environment_Task_ID;
+ end Environment_Task;
+
+ --------------
+ -- Lock_RTS --
+ --------------
+
+ procedure Lock_RTS is
+ begin
+ Write_Lock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Lock_RTS;
+
+ ----------------
+ -- Unlock_RTS --
+ ----------------
+
+ procedure Unlock_RTS is
+ begin
+ Unlock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Unlock_RTS;
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize (Environment_Task : Task_ID) is
+ Discard : BOOL;
+ pragma Unreferenced (Discard);
+
+ begin
+ Environment_Task_ID := Environment_Task;
+
+ if Time_Slice_Val = 0 or else FIFO_Within_Priorities then
+
+ -- Here we need Annex E semantics, switch the current process to the
+ -- High_Priority_Class.
+
+ Discard :=
+ OS_Interface.SetPriorityClass
+ (GetCurrentProcess, High_Priority_Class);
+
+ -- ??? In theory it should be possible to use the priority class
+ -- Realtime_Prioriry_Class but we suspect a bug in the NT scheduler
+ -- which prevents (in some obscure cases) a thread to get on top of
+ -- the running queue by another thread of lower priority. For
+ -- example cxd8002 ACATS test freeze.
+ end if;
+
+ TlsIndex := TlsAlloc;
+
+ -- Initialize the lock used to synchronize chain of all ATCBs.
+
+ Initialize_Lock (Single_RTS_Lock'Access, RTS_Lock_Level);
+
+ Environment_Task.Common.LL.Thread := GetCurrentThread;
+ Enter_Task (Environment_Task);
+ end Initialize;
+
+ ---------------------
+ -- Monotonic_Clock --
+ ---------------------
+
+ function Monotonic_Clock return Duration
+ renames System.OS_Primitives.Monotonic_Clock;
+
+ -------------------
+ -- RT_Resolution --
+ -------------------
+
+ function RT_Resolution return Duration is
+ begin
+ return 0.000_001; -- 1 micro-second
+ end RT_Resolution;
+
+ ----------------
+ -- Check_Exit --
+ ----------------
+
+ -- Dummy versions. The only currently working versions is for solaris
+ -- (native).
+
+ function Check_Exit (Self_ID : ST.Task_ID) return Boolean is
+ pragma Unreferenced (Self_ID);
+
+ begin
+ return True;
+ end Check_Exit;
+
+ --------------------
+ -- Check_No_Locks --
+ --------------------
+
+ function Check_No_Locks (Self_ID : ST.Task_ID) return Boolean is
+ pragma Unreferenced (Self_ID);
+
+ begin
+ return True;
+ end Check_No_Locks;
+
+ ------------------
+ -- Suspend_Task --
+ ------------------
+
+ function Suspend_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id) return Boolean
+ is
+ begin
+ if T.Common.LL.Thread /= Thread_Self then
+ return SuspendThread (T.Common.LL.Thread) = NO_ERROR;
+ else
+ return True;
+ end if;
+ end Suspend_Task;
+
+ -----------------
+ -- Resume_Task --
+ -----------------
+
+ function Resume_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id) return Boolean
+ is
+ begin
+ if T.Common.LL.Thread /= Thread_Self then
+ return ResumeThread (T.Common.LL.Thread) = NO_ERROR;
+ else
+ return True;
+ end if;
+ end Resume_Task;
+
+end System.Task_Primitives.Operations;
diff --git a/gcc/ada/s-taprop-os2.adb b/gcc/ada/s-taprop-os2.adb
new file mode 100644
index 00000000000..924f477bb67
--- /dev/null
+++ b/gcc/ada/s-taprop-os2.adb
@@ -0,0 +1,1157 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S . O P E R A T I O N S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2003, 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- --
+-- 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, 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, --
+-- 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 is an OS/2 version of this package
+
+-- This package contains all the GNULL primitives that interface directly
+-- with the underlying OS.
+
+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.Tasking.Debug;
+-- used for Known_Tasks
+
+with Interfaces.C;
+-- used for size_t
+
+with Interfaces.C.Strings;
+-- used for Null_Ptr
+
+with Interfaces.OS2Lib.Errors;
+with Interfaces.OS2Lib.Threads;
+with Interfaces.OS2Lib.Synchronization;
+
+with System.Parameters;
+-- used for Size_Type
+
+with System.Tasking;
+-- used for Task_ID
+
+with System.Parameters;
+-- used for Size_Type
+
+with System.Soft_Links;
+-- used for Defer/Undefer_Abort
+
+-- Note that we do not use System.Tasking.Initialization directly since
+-- this is a higher level package that we shouldn't depend on. For example
+-- when using the restricted run time, it is replaced by
+-- System.Tasking.Restricted.Initialization
+
+with System.OS_Primitives;
+-- used for Delay_Modes
+-- Clock
+
+with Unchecked_Conversion;
+with Unchecked_Deallocation;
+
+package body System.Task_Primitives.Operations is
+
+ package IC renames Interfaces.C;
+ package ICS renames Interfaces.C.Strings;
+ package OSP renames System.OS_Primitives;
+ package SSL renames System.Soft_Links;
+
+ use Interfaces.OS2Lib;
+ use Interfaces.OS2Lib.Errors;
+ use Interfaces.OS2Lib.Threads;
+ use Interfaces.OS2Lib.Synchronization;
+ use System.Parameters;
+ use System.Tasking.Debug;
+ use System.Tasking;
+ use System.OS_Interface;
+ use Interfaces.C;
+ use System.OS_Primitives;
+
+ ---------------------
+ -- Local Constants --
+ ---------------------
+
+ Max_Locks_Per_Task : constant := 100;
+ Suppress_Owner_Check : constant Boolean := False;
+
+ -----------------
+ -- Local Types --
+ -----------------
+
+ subtype Lock_Range is Integer range 0 .. Max_Locks_Per_Task;
+
+ -----------------
+ -- Local Data --
+ -----------------
+
+ -- The OS/2 DosAllocThreadLocalMemory API is used to allocate our TCB_Ptr.
+
+ -- This API reserves a small range of virtual addresses that is backed
+ -- by different physical memory for each running thread. In this case we
+ -- create a pointer at a fixed address that points to the TCB_Ptr for the
+ -- running thread. So all threads will be able to query and update their
+ -- own TCB_Ptr without destroying the TCB_Ptr of other threads.
+
+ type Thread_Local_Data is record
+ Self_ID : Task_ID; -- ID of the current thread
+ Lock_Prio_Level : Lock_Range; -- Nr of priority changes due to locks
+
+ -- ... room for expansion here, if we decide to make access to
+ -- jump-buffer and exception stack more efficient in future
+ end record;
+
+ type Access_Thread_Local_Data is access all Thread_Local_Data;
+
+ -- Pointer to Thread Local Data
+ Thread_Local_Data_Ptr : aliased Access_Thread_Local_Data;
+
+ type PPTLD is access all Access_Thread_Local_Data;
+
+ Single_RTS_Lock : aliased RTS_Lock;
+ -- This is a lock to allow only one thread of control in the RTS at
+ -- a time; it is used to execute in mutual exclusion from all other tasks.
+ -- Used mainly in Single_Lock mode, but also to protect All_Tasks_List
+
+ Environment_Task_ID : Task_ID;
+ -- A variable to hold Task_ID for the environment task.
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ function To_PPVOID is new Unchecked_Conversion (PPTLD, PPVOID);
+ function To_Address is new Unchecked_Conversion (Task_ID, System.Address);
+ function To_PFNTHREAD is
+ new Unchecked_Conversion (System.Address, PFNTHREAD);
+
+ function To_MS (D : Duration) return ULONG;
+
+ procedure Set_Temporary_Priority
+ (T : in Task_ID;
+ New_Priority : in System.Any_Priority);
+
+ -----------
+ -- To_MS --
+ -----------
+
+ function To_MS (D : Duration) return ULONG is
+ begin
+ return ULONG (D * 1_000);
+ end To_MS;
+
+ -----------
+ -- Clock --
+ -----------
+
+ function Monotonic_Clock return Duration renames OSP.Monotonic_Clock;
+
+ -------------------
+ -- RT_Resolution --
+ -------------------
+
+ function RT_Resolution return Duration is
+ begin
+ return 10#1.0#E-6;
+ end RT_Resolution;
+
+ -------------------
+ -- Abort_Handler --
+ -------------------
+
+ -- OS/2 only has limited support for asynchronous signals.
+ -- It seems not to be possible to jump out of an exception
+ -- handler or to change the execution context of the thread.
+ -- So asynchonous transfer of control is not supported.
+
+ -----------------
+ -- Stack_Guard --
+ -----------------
+
+ -- The underlying thread system sets a guard page at the
+ -- bottom of a thread stack, so nothing is needed.
+ -- ??? Check the comment above
+
+ procedure Stack_Guard (T : ST.Task_ID; On : Boolean) is
+ pragma Unreferenced (T);
+ pragma Unreferenced (On);
+
+ begin
+ null;
+ end Stack_Guard;
+
+ --------------------
+ -- Get_Thread_Id --
+ --------------------
+
+ function Get_Thread_Id (T : ST.Task_ID) return OSI.Thread_Id is
+ begin
+ return OSI.Thread_Id (T.Common.LL.Thread);
+ end Get_Thread_Id;
+
+ ----------
+ -- Self --
+ ----------
+
+ function Self return Task_ID is
+ Self_ID : Task_ID renames Thread_Local_Data_Ptr.Self_ID;
+ begin
+ -- Check that the thread local data has been initialized.
+
+ pragma Assert
+ ((Thread_Local_Data_Ptr /= null
+ and then Thread_Local_Data_Ptr.Self_ID /= null));
+
+ return Self_ID;
+ end Self;
+
+ ---------------------
+ -- Initialize_Lock --
+ ---------------------
+
+ procedure Initialize_Lock
+ (Prio : System.Any_Priority;
+ L : access Lock)
+ is
+ begin
+ if DosCreateMutexSem
+ (ICS.Null_Ptr, L.Mutex'Unchecked_Access, 0, False32) /= NO_ERROR
+ then
+ raise Storage_Error;
+ end if;
+
+ pragma Assert (L.Mutex /= 0, "Error creating Mutex");
+ L.Priority := Prio;
+ L.Owner_ID := Null_Address;
+ end Initialize_Lock;
+
+ procedure Initialize_Lock (L : access RTS_Lock; Level : Lock_Level) is
+ pragma Unreferenced (Level);
+
+ begin
+ if DosCreateMutexSem
+ (ICS.Null_Ptr, L.Mutex'Unchecked_Access, 0, False32) /= NO_ERROR
+ then
+ raise Storage_Error;
+ end if;
+
+ pragma Assert (L.Mutex /= 0, "Error creating Mutex");
+
+ L.Priority := System.Any_Priority'Last;
+ L.Owner_ID := Null_Address;
+ end Initialize_Lock;
+
+ -------------------
+ -- Finalize_Lock --
+ -------------------
+
+ procedure Finalize_Lock (L : access Lock) is
+ begin
+ Must_Not_Fail (DosCloseMutexSem (L.Mutex));
+ end Finalize_Lock;
+
+ procedure Finalize_Lock (L : access RTS_Lock) is
+ begin
+ Must_Not_Fail (DosCloseMutexSem (L.Mutex));
+ end Finalize_Lock;
+
+ ----------------
+ -- Write_Lock --
+ ----------------
+
+ procedure Write_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ Self_ID : constant Task_ID := Thread_Local_Data_Ptr.Self_ID;
+ Old_Priority : constant Any_Priority :=
+ Self_ID.Common.LL.Current_Priority;
+
+ begin
+ if L.Priority < Old_Priority then
+ Ceiling_Violation := True;
+ return;
+ end if;
+
+ Ceiling_Violation := False;
+
+ -- Increase priority before getting the lock
+ -- to prevent priority inversion
+
+ Thread_Local_Data_Ptr.Lock_Prio_Level :=
+ Thread_Local_Data_Ptr.Lock_Prio_Level + 1;
+ if L.Priority > Old_Priority then
+ Set_Temporary_Priority (Self_ID, L.Priority);
+ end if;
+
+ -- Request the lock and then update the lock owner data
+
+ Must_Not_Fail (DosRequestMutexSem (L.Mutex, SEM_INDEFINITE_WAIT));
+ L.Owner_Priority := Old_Priority;
+ L.Owner_ID := Self_ID.all'Address;
+ end Write_Lock;
+
+ procedure Write_Lock
+ (L : access RTS_Lock;
+ Global_Lock : Boolean := False)
+ is
+ Self_ID : Task_ID;
+ Old_Priority : Any_Priority;
+
+ begin
+ if not Single_Lock or else Global_Lock then
+ Self_ID := Thread_Local_Data_Ptr.Self_ID;
+ Old_Priority := Self_ID.Common.LL.Current_Priority;
+
+ -- Increase priority before getting the lock
+ -- to prevent priority inversion
+
+ Thread_Local_Data_Ptr.Lock_Prio_Level :=
+ Thread_Local_Data_Ptr.Lock_Prio_Level + 1;
+
+ if L.Priority > Old_Priority then
+ Set_Temporary_Priority (Self_ID, L.Priority);
+ end if;
+
+ -- Request the lock and then update the lock owner data
+
+ Must_Not_Fail (DosRequestMutexSem (L.Mutex, SEM_INDEFINITE_WAIT));
+ L.Owner_Priority := Old_Priority;
+ L.Owner_ID := Self_ID.all'Address;
+ end if;
+ end Write_Lock;
+
+ procedure Write_Lock (T : Task_ID) is
+ begin
+ if not Single_Lock then
+
+ -- Request the lock and then update the lock owner data
+
+ Must_Not_Fail
+ (DosRequestMutexSem (T.Common.LL.L.Mutex, SEM_INDEFINITE_WAIT));
+ T.Common.LL.L.Owner_ID := Null_Address;
+ end if;
+ end Write_Lock;
+
+ ---------------
+ -- Read_Lock --
+ ---------------
+
+ procedure Read_Lock
+ (L : access Lock; Ceiling_Violation : out Boolean) renames Write_Lock;
+
+ ------------
+ -- Unlock --
+ ------------
+
+ procedure Unlock (L : access Lock) is
+ Self_ID : constant Task_ID := Thread_Local_Data_Ptr.Self_ID;
+ Old_Priority : constant Any_Priority := L.Owner_Priority;
+
+ begin
+ -- Check that this task holds the lock
+
+ pragma Assert (Suppress_Owner_Check
+ or else L.Owner_ID = Self_ID.all'Address);
+
+ -- Upate the owner data
+
+ L.Owner_ID := Null_Address;
+
+ -- Do the actual unlocking. No more references
+ -- to owner data of L after this point.
+
+ Must_Not_Fail (DosReleaseMutexSem (L.Mutex));
+
+ -- Reset priority after unlocking to avoid priority inversion
+
+ Thread_Local_Data_Ptr.Lock_Prio_Level :=
+ Thread_Local_Data_Ptr.Lock_Prio_Level - 1;
+ if L.Priority /= Old_Priority then
+ Set_Temporary_Priority (Self_ID, Old_Priority);
+ end if;
+ end Unlock;
+
+ procedure Unlock (L : access RTS_Lock; Global_Lock : Boolean := False) is
+ Self_ID : Task_ID;
+ Old_Priority : Any_Priority;
+
+ begin
+ if not Single_Lock or else Global_Lock then
+ Self_ID := Thread_Local_Data_Ptr.Self_ID;
+ Old_Priority := L.Owner_Priority;
+ -- Check that this task holds the lock
+
+ pragma Assert (Suppress_Owner_Check
+ or else L.Owner_ID = Self_ID.all'Address);
+
+ -- Upate the owner data
+
+ L.Owner_ID := Null_Address;
+
+ -- Do the actual unlocking. No more references
+ -- to owner data of L after this point.
+
+ Must_Not_Fail (DosReleaseMutexSem (L.Mutex));
+
+ -- Reset priority after unlocking to avoid priority inversion
+
+ Thread_Local_Data_Ptr.Lock_Prio_Level :=
+ Thread_Local_Data_Ptr.Lock_Prio_Level - 1;
+
+ if L.Priority /= Old_Priority then
+ Set_Temporary_Priority (Self_ID, Old_Priority);
+ end if;
+ end if;
+ end Unlock;
+
+ procedure Unlock (T : Task_ID) is
+ begin
+ if not Single_Lock then
+
+ -- Check the owner data
+
+ pragma Assert (Suppress_Owner_Check
+ or else T.Common.LL.L.Owner_ID = Null_Address);
+
+ -- Do the actual unlocking. No more references
+ -- to owner data of T.Common.LL.L after this point.
+
+ Must_Not_Fail (DosReleaseMutexSem (T.Common.LL.L.Mutex));
+ end if;
+ end Unlock;
+
+ -----------
+ -- Sleep --
+ -----------
+
+ procedure Sleep
+ (Self_ID : Task_ID;
+ Reason : System.Tasking.Task_States)
+ is
+ pragma Unreferenced (Reason);
+
+ Count : aliased ULONG; -- Used to store dummy result
+
+ begin
+ -- Must reset Cond BEFORE L is unlocked.
+
+ Sem_Must_Not_Fail
+ (DosResetEventSem (Self_ID.Common.LL.CV, Count'Unchecked_Access));
+
+ if Single_Lock then
+ Unlock_RTS;
+ else
+ Unlock (Self_ID);
+ end if;
+
+ -- No problem if we are interrupted here.
+ -- If the condition is signaled, DosWaitEventSem will simply not block.
+
+ Sem_Must_Not_Fail
+ (DosWaitEventSem (Self_ID.Common.LL.CV, SEM_INDEFINITE_WAIT));
+
+ -- Since L was previously accquired, lock operation should not fail.
+
+ if Single_Lock then
+ Lock_RTS;
+ else
+ Write_Lock (Self_ID);
+ end if;
+ end Sleep;
+
+ -----------------
+ -- Timed_Sleep --
+ -----------------
+
+ -- This is for use within the run-time system, so abort is
+ -- assumed to be already deferred, and the caller should be
+ -- holding its own ATCB lock.
+
+ -- Pre-assertion: Cond is posted
+ -- Self is locked.
+
+ -- Post-assertion: Cond is posted
+ -- Self is locked.
+
+ procedure Timed_Sleep
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes;
+ Reason : System.Tasking.Task_States;
+ Timedout : out Boolean;
+ Yielded : out Boolean)
+ is
+ pragma Unreferenced (Reason);
+
+ Check_Time : constant Duration := OSP.Monotonic_Clock;
+ Rel_Time : Duration;
+ Abs_Time : Duration;
+ Time_Out : ULONG;
+ Result : APIRET;
+ Count : aliased ULONG; -- Used to store dummy result
+
+ begin
+ -- Must reset Cond BEFORE Self_ID is unlocked.
+
+ Sem_Must_Not_Fail
+ (DosResetEventSem (Self_ID.Common.LL.CV,
+ Count'Unchecked_Access));
+
+ if Single_Lock then
+ Unlock_RTS;
+ else
+ Unlock (Self_ID);
+ end if;
+
+ Timedout := True;
+ Yielded := False;
+
+ if Mode = Relative then
+ Rel_Time := Time;
+ Abs_Time := Duration'Min (Time, Max_Sensible_Delay) + Check_Time;
+ else
+ Rel_Time := Time - Check_Time;
+ Abs_Time := Time;
+ end if;
+
+ if Rel_Time > 0.0 then
+ loop
+ exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level
+ or else Self_ID.Pending_Priority_Change;
+
+ Time_Out := To_MS (Rel_Time);
+ Result := DosWaitEventSem (Self_ID.Common.LL.CV, Time_Out);
+ pragma Assert
+ ((Result = NO_ERROR or Result = ERROR_TIMEOUT
+ or Result = ERROR_INTERRUPT));
+
+ -- ???
+ -- What to do with error condition ERROR_NOT_ENOUGH_MEMORY? Can
+ -- we raise an exception here? And what about ERROR_INTERRUPT?
+ -- Should that be treated as a simple timeout?
+ -- For now, consider only ERROR_TIMEOUT to be a timeout.
+
+ exit when Abs_Time <= OSP.Monotonic_Clock;
+
+ if Result /= ERROR_TIMEOUT then
+ -- somebody may have called Wakeup for us
+ Timedout := False;
+ exit;
+ end if;
+
+ Rel_Time := Abs_Time - OSP.Monotonic_Clock;
+ end loop;
+ end if;
+
+ -- Ensure post-condition
+
+ if Single_Lock then
+ Lock_RTS;
+ else
+ Write_Lock (Self_ID);
+ end if;
+
+ if Timedout then
+ Sem_Must_Not_Fail (DosPostEventSem (Self_ID.Common.LL.CV));
+ end if;
+ end Timed_Sleep;
+
+ -----------------
+ -- Timed_Delay --
+ -----------------
+
+ procedure Timed_Delay
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes)
+ is
+ Check_Time : constant Duration := OSP.Monotonic_Clock;
+ Rel_Time : Duration;
+ Abs_Time : Duration;
+ Timedout : Boolean := True;
+ Time_Out : ULONG;
+ Result : APIRET;
+ Count : aliased ULONG; -- Used to store dummy result
+
+ begin
+ -- Only the little window between deferring abort and
+ -- locking Self_ID is the reason we need to
+ -- check for pending abort and priority change below! :(
+
+ SSL.Abort_Defer.all;
+
+ if Single_Lock then
+ Lock_RTS;
+ else
+ Write_Lock (Self_ID);
+ end if;
+
+ -- Must reset Cond BEFORE Self_ID is unlocked.
+
+ Sem_Must_Not_Fail
+ (DosResetEventSem (Self_ID.Common.LL.CV,
+ Count'Unchecked_Access));
+
+ if Single_Lock then
+ Unlock_RTS;
+ else
+ Unlock (Self_ID);
+ end if;
+
+ if Mode = Relative then
+ Rel_Time := Time;
+ Abs_Time := Time + Check_Time;
+ else
+ Rel_Time := Time - Check_Time;
+ Abs_Time := Time;
+ end if;
+
+ if Rel_Time > 0.0 then
+ Self_ID.Common.State := Delay_Sleep;
+
+ loop
+ if Self_ID.Pending_Priority_Change then
+ Self_ID.Pending_Priority_Change := False;
+ Self_ID.Common.Base_Priority := Self_ID.New_Base_Priority;
+ Set_Priority (Self_ID, Self_ID.Common.Base_Priority);
+ end if;
+
+ exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level;
+
+ Time_Out := To_MS (Rel_Time);
+ Result := DosWaitEventSem (Self_ID.Common.LL.CV, Time_Out);
+
+ exit when Abs_Time <= OSP.Monotonic_Clock;
+
+ Rel_Time := Abs_Time - OSP.Monotonic_Clock;
+ end loop;
+
+ Self_ID.Common.State := Runnable;
+ Timedout := Result = ERROR_TIMEOUT;
+ end if;
+
+ if Single_Lock then
+ Lock_RTS;
+ else
+ Write_Lock (Self_ID);
+ end if;
+
+ if Timedout then
+ Sem_Must_Not_Fail (DosPostEventSem (Self_ID.Common.LL.CV));
+ end if;
+
+ if Single_Lock then
+ Unlock_RTS;
+ else
+ Unlock (Self_ID);
+ end if;
+
+ System.OS_Interface.Yield;
+ SSL.Abort_Undefer.all;
+ end Timed_Delay;
+
+ ------------
+ -- Wakeup --
+ ------------
+
+ procedure Wakeup (T : Task_ID; Reason : System.Tasking.Task_States) is
+ pragma Unreferenced (Reason);
+
+ begin
+ Sem_Must_Not_Fail (DosPostEventSem (T.Common.LL.CV));
+ end Wakeup;
+
+ -----------
+ -- Yield --
+ -----------
+
+ procedure Yield (Do_Yield : Boolean := True) is
+ begin
+ if Do_Yield then
+ System.OS_Interface.Yield;
+ end if;
+ end Yield;
+
+ ----------------------------
+ -- Set_Temporary_Priority --
+ ----------------------------
+
+ procedure Set_Temporary_Priority
+ (T : Task_ID;
+ New_Priority : System.Any_Priority)
+ is
+ use Interfaces.C;
+ Delta_Priority : Integer;
+
+ begin
+ -- When Lock_Prio_Level = 0, we always need to set the
+ -- Active_Priority. In this way we can make priority changes
+ -- due to locking independent of those caused by calling
+ -- Set_Priority.
+
+ if Thread_Local_Data_Ptr.Lock_Prio_Level = 0
+ or else New_Priority < T.Common.Current_Priority
+ then
+ Delta_Priority := T.Common.Current_Priority -
+ T.Common.LL.Current_Priority;
+ else
+ Delta_Priority := New_Priority - T.Common.LL.Current_Priority;
+ end if;
+
+ if Delta_Priority /= 0 then
+ -- ??? There is a race-condition here
+ -- The TCB is updated before the system call to make
+ -- pre-emption in the critical section less likely.
+
+ T.Common.LL.Current_Priority :=
+ T.Common.LL.Current_Priority + Delta_Priority;
+ Must_Not_Fail
+ (DosSetPriority (Scope => PRTYS_THREAD,
+ Class => PRTYC_NOCHANGE,
+ Delta_P => IC.long (Delta_Priority),
+ PorTid => T.Common.LL.Thread));
+ end if;
+ end Set_Temporary_Priority;
+
+ ------------------
+ -- Set_Priority --
+ ------------------
+
+ procedure Set_Priority
+ (T : Task_ID;
+ Prio : System.Any_Priority;
+ Loss_Of_Inheritance : Boolean := False)
+ is
+ pragma Unreferenced (Loss_Of_Inheritance);
+
+ begin
+ T.Common.Current_Priority := Prio;
+ Set_Temporary_Priority (T, Prio);
+ end Set_Priority;
+
+ ------------------
+ -- Get_Priority --
+ ------------------
+
+ function Get_Priority (T : Task_ID) return System.Any_Priority is
+ begin
+ return T.Common.Current_Priority;
+ end Get_Priority;
+
+ ----------------
+ -- Enter_Task --
+ ----------------
+
+ procedure Enter_Task (Self_ID : Task_ID) is
+ begin
+ -- Initialize thread local data. Must be done first.
+
+ Thread_Local_Data_Ptr.Self_ID := Self_ID;
+ Thread_Local_Data_Ptr.Lock_Prio_Level := 0;
+
+ Lock_RTS;
+
+ for J in Known_Tasks'Range loop
+ if Known_Tasks (J) = null then
+ Known_Tasks (J) := Self_ID;
+ Self_ID.Known_Tasks_Index := J;
+ exit;
+ end if;
+ end loop;
+
+ Unlock_RTS;
+
+ -- For OS/2, we can set Self_ID.Common.LL.Thread in
+ -- Create_Task, since the thread is created suspended.
+ -- That is, there is no danger of the thread racing ahead
+ -- and trying to reference Self_ID.Common.LL.Thread before it
+ -- has been initialized.
+
+ -- .... Do we need to do anything with signals for OS/2 ???
+ end Enter_Task;
+
+ --------------
+ -- New_ATCB --
+ --------------
+
+ function New_ATCB (Entry_Num : Task_Entry_Index) return Task_ID is
+ begin
+ return new Ada_Task_Control_Block (Entry_Num);
+ end New_ATCB;
+
+ -------------------
+ -- Is_Valid_Task --
+ -------------------
+
+ function Is_Valid_Task return Boolean is
+ begin
+ return False;
+ end Is_Valid_Task;
+
+ -----------------------------
+ -- Register_Foreign_Thread --
+ -----------------------------
+
+ function Register_Foreign_Thread return Task_ID is
+ begin
+ return null;
+ end Register_Foreign_Thread;
+
+ --------------------
+ -- Initialize_TCB --
+ --------------------
+
+ procedure Initialize_TCB (Self_ID : Task_ID; Succeeded : out Boolean) is
+ begin
+ if DosCreateEventSem (ICS.Null_Ptr,
+ Self_ID.Common.LL.CV'Unchecked_Access, 0, True32) = NO_ERROR
+ then
+ if not Single_Lock
+ and then DosCreateMutexSem
+ (ICS.Null_Ptr,
+ Self_ID.Common.LL.L.Mutex'Unchecked_Access,
+ 0,
+ False32) /= NO_ERROR
+ then
+ Succeeded := False;
+ Must_Not_Fail (DosCloseEventSem (Self_ID.Common.LL.CV));
+ else
+ Succeeded := True;
+ end if;
+
+ -- We now want to do the equivalent of:
+
+ -- Initialize_Lock
+ -- (Self_ID.Common.LL.L'Unchecked_Access, ATCB_Level);
+
+ -- But we avoid that because the Initialize_TCB routine has an
+ -- exception handler, and it is too early for us to deal with
+ -- installing handlers (see comment below), so we do our own
+ -- Initialize_Lock operation manually.
+
+ Self_ID.Common.LL.L.Priority := System.Any_Priority'Last;
+ Self_ID.Common.LL.L.Owner_ID := Null_Address;
+
+ else
+ Succeeded := False;
+ end if;
+
+ -- Note: at one time we had an exception handler here, whose code
+ -- was as follows:
+
+ -- exception
+
+ -- Assumes any failure must be due to insufficient resources
+
+ -- when Storage_Error =>
+ -- Must_Not_Fail (DosCloseEventSem (Self_ID.Common.LL.CV));
+ -- Succeeded := False;
+
+ -- but that won't work with the old exception scheme, since it would
+ -- result in messing with Jmpbuf values too early. If and when we get
+ -- switched entirely to the new zero-cost exception scheme, we could
+ -- put this handler back in!
+ end Initialize_TCB;
+
+ -----------------
+ -- Create_Task --
+ -----------------
+
+ procedure Create_Task
+ (T : Task_ID;
+ Wrapper : System.Address;
+ Stack_Size : System.Parameters.Size_Type;
+ Priority : System.Any_Priority;
+ Succeeded : out Boolean)
+ is
+ Result : aliased APIRET;
+ Adjusted_Stack_Size : System.Parameters.Size_Type;
+ use System.Parameters;
+
+ begin
+ -- In OS/2 the allocated stack size should be based on the
+ -- amount of address space that should be reserved for the stack.
+ -- Actual memory will only be used when the stack is touched anyway.
+
+ -- The new minimum size is 12 kB, although the EMX docs
+ -- recommend a minimum size of 32 kB. (The original was 4 kB)
+ -- Systems that use many tasks (say > 30) and require much
+ -- memory may run out of virtual address space, since OS/2
+ -- has a per-proces limit of 512 MB, of which max. 300 MB is
+ -- usable in practise.
+
+ if Stack_Size = Unspecified_Size then
+ Adjusted_Stack_Size := Default_Stack_Size;
+
+ elsif Stack_Size < Minimum_Stack_Size then
+ Adjusted_Stack_Size := Minimum_Stack_Size;
+
+ else
+ Adjusted_Stack_Size := Stack_Size;
+ end if;
+
+ -- GB970222:
+ -- Because DosCreateThread is called directly here, the
+ -- C RTL doesn't get initialized for the new thead. EMX by
+ -- default uses per-thread local heaps in addition to the
+ -- global heap. There might be other effects of by-passing the
+ -- C library here.
+
+ -- When using _beginthread the newly created thread is not
+ -- blocked initially. Does this matter or can I create the
+ -- thread running anyway? The LL.Thread variable will be set
+ -- anyway because the variable is passed by reference to OS/2.
+
+ T.Common.LL.Wrapper := To_PFNTHREAD (Wrapper);
+
+ -- The OS implicitly gives the new task the priority of this task.
+
+ T.Common.LL.Current_Priority := Self.Common.LL.Current_Priority;
+
+ -- If task was locked before activator task was
+ -- initialized, assume it has OS standard priority
+
+ if T.Common.LL.L.Owner_Priority not in Any_Priority'Range then
+ T.Common.LL.L.Owner_Priority := 1;
+ end if;
+
+ -- Create the thread, in blocked mode
+
+ Result := DosCreateThread
+ (F_ptid => T.Common.LL.Thread'Unchecked_Access,
+ pfn => T.Common.LL.Wrapper,
+ param => To_Address (T),
+ flag => Block_Child + Commit_Stack,
+ cbStack => ULONG (Adjusted_Stack_Size));
+
+ Succeeded := (Result = NO_ERROR);
+
+ if not Succeeded then
+ return;
+ end if;
+
+ -- Set the new thread's priority
+ -- (child has inherited priority from parent)
+
+ Set_Priority (T, Priority);
+
+ -- Start the thread executing
+
+ Must_Not_Fail (DosResumeThread (T.Common.LL.Thread));
+
+ end Create_Task;
+
+ ------------------
+ -- Finalize_TCB --
+ ------------------
+
+ procedure Finalize_TCB (T : Task_ID) is
+ Tmp : Task_ID := T;
+
+ procedure Free is new
+ Unchecked_Deallocation (Ada_Task_Control_Block, Task_ID);
+
+ begin
+ Must_Not_Fail (DosCloseEventSem (T.Common.LL.CV));
+
+ if not Single_Lock then
+ Finalize_Lock (T.Common.LL.L'Unchecked_Access);
+ end if;
+
+ if T.Known_Tasks_Index /= -1 then
+ Known_Tasks (T.Known_Tasks_Index) := null;
+ end if;
+
+ Free (Tmp);
+ end Finalize_TCB;
+
+ ---------------
+ -- Exit_Task --
+ ---------------
+
+ procedure Exit_Task is
+ begin
+ Thread_Local_Data_Ptr := null;
+ end Exit_Task;
+
+ ----------------
+ -- Abort_Task --
+ ----------------
+
+ procedure Abort_Task (T : Task_ID) is
+ pragma Unreferenced (T);
+
+ begin
+ null;
+
+ -- Task abortion not implemented yet.
+ -- Should perform other action ???
+
+ end Abort_Task;
+
+ ----------------
+ -- Check_Exit --
+ ----------------
+
+ -- Dummy version
+
+ function Check_Exit (Self_ID : ST.Task_ID) return Boolean is
+ begin
+ return Check_No_Locks (Self_ID);
+ end Check_Exit;
+
+ --------------------
+ -- Check_No_Locks --
+ --------------------
+
+ function Check_No_Locks (Self_ID : ST.Task_ID) return Boolean is
+ TLD : constant Access_Thread_Local_Data := Thread_Local_Data_Ptr;
+
+ begin
+ return Self_ID = TLD.Self_ID
+ and then TLD.Lock_Prio_Level = 0;
+ end Check_No_Locks;
+
+ ----------------------
+ -- Environment_Task --
+ ----------------------
+
+ function Environment_Task return Task_ID is
+ begin
+ return Environment_Task_ID;
+ end Environment_Task;
+
+ --------------
+ -- Lock_RTS --
+ --------------
+
+ procedure Lock_RTS is
+ begin
+ Write_Lock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Lock_RTS;
+
+ ----------------
+ -- Unlock_RTS --
+ ----------------
+
+ procedure Unlock_RTS is
+ begin
+ Unlock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Unlock_RTS;
+
+ ------------------
+ -- Suspend_Task --
+ ------------------
+
+ function Suspend_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id)
+ return Boolean
+ is
+ begin
+ if Thread_Id (T.Common.LL.Thread) /= Thread_Self then
+ return DosSuspendThread (T.Common.LL.Thread) = NO_ERROR;
+ else
+ return True;
+ end if;
+ end Suspend_Task;
+
+ -----------------
+ -- Resume_Task --
+ -----------------
+
+ function Resume_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id)
+ return Boolean
+ is
+ begin
+ if Thread_Id (T.Common.LL.Thread) /= Thread_Self then
+ return DosResumeThread (T.Common.LL.Thread) = NO_ERROR;
+ else
+ return True;
+ end if;
+ end Resume_Task;
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize (Environment_Task : Task_ID) is
+ Succeeded : Boolean;
+ begin
+ Environment_Task_ID := Environment_Task;
+
+ Initialize_Lock (Single_RTS_Lock'Access, RTS_Lock_Level);
+ -- Initialize the lock used to synchronize chain of all ATCBs.
+
+ -- Set ID of environment task.
+
+ Thread_Local_Data_Ptr.Self_ID := Environment_Task;
+ Environment_Task.Common.LL.Thread := 1; -- By definition
+
+ -- This priority is unknown in fact.
+ -- If actual current priority is different,
+ -- it will get synchronized later on anyway.
+
+ Environment_Task.Common.LL.Current_Priority :=
+ Environment_Task.Common.Current_Priority;
+
+ -- Initialize TCB for this task.
+ -- This includes all the normal task-external initialization.
+ -- This is also done by Initialize_ATCB, why ???
+
+ Initialize_TCB (Environment_Task, Succeeded);
+
+ -- Consider raising Storage_Error,
+ -- if propagation can be tolerated ???
+
+ pragma Assert (Succeeded);
+
+ -- Do normal task-internal initialization,
+ -- which depends on an initialized TCB.
+
+ Enter_Task (Environment_Task);
+
+ -- Insert here any other special
+ -- initialization needed for the environment task.
+ end Initialize;
+
+begin
+ -- Initialize pointer to task local data.
+ -- This is done once, for all tasks.
+
+ Must_Not_Fail (DosAllocThreadLocalMemory
+ ((Thread_Local_Data'Size + 31) / 32, -- nr of 32-bit words
+ To_PPVOID (Thread_Local_Data_Ptr'Access)));
+
+ -- Initialize thread local data for main thread
+
+ Thread_Local_Data_Ptr.Self_ID := null;
+ Thread_Local_Data_Ptr.Lock_Prio_Level := 0;
+end System.Task_Primitives.Operations;
diff --git a/gcc/ada/s-taprop-posix.adb b/gcc/ada/s-taprop-posix.adb
new file mode 100644
index 00000000000..f5bc6174ccb
--- /dev/null
+++ b/gcc/ada/s-taprop-posix.adb
@@ -0,0 +1,1212 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S . O P E R A T I O N S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2004, 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- --
+-- 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, 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, --
+-- 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 is a POSIX-like version of this package
+
+-- This package contains all the GNULL primitives that interface directly
+-- with the underlying OS.
+
+-- Note: this file can only be used for POSIX compliant systems that
+-- implement SCHED_FIFO and Ceiling Locking correctly.
+
+-- For configurations where SCHED_FIFO and priority ceiling are not a
+-- requirement, this file can also be used (e.g AiX threads)
+
+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.Tasking.Debug;
+-- used for Known_Tasks
+
+with System.Task_Info;
+-- used for Task_Info_Type
+
+with Interfaces.C;
+-- used for int
+-- size_t
+
+with System.Interrupt_Management;
+-- used for Keep_Unmasked
+-- Abort_Task_Interrupt
+-- Interrupt_ID
+
+with System.Interrupt_Management.Operations;
+-- used for Set_Interrupt_Mask
+-- All_Tasks_Mask
+pragma Elaborate_All (System.Interrupt_Management.Operations);
+
+with System.Parameters;
+-- used for Size_Type
+
+with System.Tasking;
+-- used for Ada_Task_Control_Block
+-- Task_ID
+
+with System.Soft_Links;
+-- used for Defer/Undefer_Abort
+
+-- Note that we do not use System.Tasking.Initialization directly since
+-- this is a higher level package that we shouldn't depend on. For example
+-- when using the restricted run time, it is replaced by
+-- System.Tasking.Restricted.Initialization
+
+with System.OS_Primitives;
+-- used for Delay_Modes
+
+with Unchecked_Conversion;
+with Unchecked_Deallocation;
+
+package body System.Task_Primitives.Operations is
+
+ use System.Tasking.Debug;
+ use System.Tasking;
+ use Interfaces.C;
+ use System.OS_Interface;
+ use System.Parameters;
+ use System.OS_Primitives;
+
+ package SSL renames System.Soft_Links;
+
+ ----------------
+ -- Local Data --
+ ----------------
+
+ -- The followings are logically constants, but need to be initialized
+ -- at run time.
+
+ Single_RTS_Lock : aliased RTS_Lock;
+ -- This is a lock to allow only one thread of control in the RTS at
+ -- a time; it is used to execute in mutual exclusion from all other tasks.
+ -- Used mainly in Single_Lock mode, but also to protect All_Tasks_List
+
+ ATCB_Key : aliased pthread_key_t;
+ -- Key used to find the Ada Task_ID associated with a thread
+
+ Environment_Task_ID : Task_ID;
+ -- A variable to hold Task_ID for the environment task.
+
+ Locking_Policy : Character;
+ pragma Import (C, Locking_Policy, "__gl_locking_policy");
+ -- Value of the pragma Locking_Policy:
+ -- 'C' for Ceiling_Locking
+ -- 'I' for Inherit_Locking
+ -- ' ' for none.
+
+ Unblocked_Signal_Mask : aliased sigset_t;
+ -- The set of signals that should unblocked in all tasks
+
+ -- The followings are internal configuration constants needed.
+
+ Next_Serial_Number : Task_Serial_Number := 100;
+ -- We start at 100, to reserve some special values for
+ -- using in error checking.
+
+ Time_Slice_Val : Integer;
+ pragma Import (C, Time_Slice_Val, "__gl_time_slice_val");
+
+ Dispatching_Policy : Character;
+ pragma Import (C, Dispatching_Policy, "__gl_task_dispatching_policy");
+
+ FIFO_Within_Priorities : constant Boolean := Dispatching_Policy = 'F';
+ -- Indicates whether FIFO_Within_Priorities is set.
+
+ Foreign_Task_Elaborated : aliased Boolean := True;
+ -- Used to identified fake tasks (i.e., non-Ada Threads).
+
+ --------------------
+ -- Local Packages --
+ --------------------
+
+ package Specific is
+
+ procedure Initialize (Environment_Task : Task_ID);
+ pragma Inline (Initialize);
+ -- Initialize various data needed by this package.
+
+ function Is_Valid_Task return Boolean;
+ pragma Inline (Is_Valid_Task);
+ -- Does executing thread have a TCB?
+
+ procedure Set (Self_Id : Task_ID);
+ pragma Inline (Set);
+ -- Set the self id for the current task.
+
+ function Self return Task_ID;
+ pragma Inline (Self);
+ -- Return a pointer to the Ada Task Control Block of the calling task.
+
+ end Specific;
+
+ package body Specific is separate;
+ -- The body of this package is target specific.
+
+ ---------------------------------
+ -- Support for foreign threads --
+ ---------------------------------
+
+ function Register_Foreign_Thread (Thread : Thread_Id) return Task_ID;
+ -- Allocate and Initialize a new ATCB for the current Thread.
+
+ function Register_Foreign_Thread
+ (Thread : Thread_Id) return Task_ID is separate;
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ procedure Abort_Handler (Sig : Signal);
+ -- Signal handler used to implement asynchronous abort.
+ -- See also comment before body, below.
+
+ function To_Address is new Unchecked_Conversion (Task_ID, System.Address);
+
+ -------------------
+ -- Abort_Handler --
+ -------------------
+
+ -- Target-dependent binding of inter-thread Abort signal to
+ -- the raising of the Abort_Signal exception.
+
+ -- The technical issues and alternatives here are essentially
+ -- the same as for raising exceptions in response to other
+ -- signals (e.g. Storage_Error). See code and comments in
+ -- the package body System.Interrupt_Management.
+
+ -- Some implementations may not allow an exception to be propagated
+ -- out of a handler, and others might leave the signal or
+ -- interrupt that invoked this handler masked after the exceptional
+ -- return to the application code.
+
+ -- GNAT exceptions are originally implemented using setjmp()/longjmp().
+ -- On most UNIX systems, this will allow transfer out of a signal handler,
+ -- which is usually the only mechanism available for implementing
+ -- asynchronous handlers of this kind. However, some
+ -- systems do not restore the signal mask on longjmp(), leaving the
+ -- abort signal masked.
+
+ procedure Abort_Handler (Sig : Signal) is
+ pragma Warnings (Off, Sig);
+
+ T : constant Task_ID := Self;
+ Result : Interfaces.C.int;
+ Old_Set : aliased sigset_t;
+
+ begin
+ -- It is not safe to raise an exception when using ZCX and the GCC
+ -- exception handling mechanism.
+
+ if ZCX_By_Default and then GCC_ZCX_Support then
+ return;
+ end if;
+
+ if T.Deferral_Level = 0
+ and then T.Pending_ATC_Level < T.ATC_Nesting_Level and then
+ not T.Aborting
+ then
+ T.Aborting := True;
+
+ -- Make sure signals used for RTS internal purpose are unmasked
+
+ Result := pthread_sigmask (SIG_UNBLOCK,
+ Unblocked_Signal_Mask'Unchecked_Access, Old_Set'Unchecked_Access);
+ pragma Assert (Result = 0);
+
+ raise Standard'Abort_Signal;
+ end if;
+ end Abort_Handler;
+
+ -----------------
+ -- Stack_Guard --
+ -----------------
+
+ procedure Stack_Guard (T : ST.Task_ID; On : Boolean) is
+ Stack_Base : constant Address := Get_Stack_Base (T.Common.LL.Thread);
+ Guard_Page_Address : Address;
+
+ Res : Interfaces.C.int;
+
+ begin
+ if Stack_Base_Available then
+
+ -- Compute the guard page address
+
+ 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;
+
+ pragma Assert (Res = 0);
+ end if;
+ end Stack_Guard;
+
+ --------------------
+ -- Get_Thread_Id --
+ --------------------
+
+ function Get_Thread_Id (T : ST.Task_ID) return OSI.Thread_Id is
+ begin
+ return T.Common.LL.Thread;
+ end Get_Thread_Id;
+
+ ----------
+ -- Self --
+ ----------
+
+ function Self return Task_ID renames Specific.Self;
+
+ ---------------------
+ -- Initialize_Lock --
+ ---------------------
+
+ -- Note: mutexes and cond_variables needed per-task basis are
+ -- initialized in Intialize_TCB and the Storage_Error is
+ -- handled. Other mutexes (such as RTS_Lock, Memory_Lock...)
+ -- used in RTS is initialized before any status change of RTS.
+ -- Therefore rasing Storage_Error in the following routines
+ -- should be able to be handled safely.
+
+ procedure Initialize_Lock
+ (Prio : System.Any_Priority;
+ L : access Lock)
+ is
+ Attributes : aliased pthread_mutexattr_t;
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_mutexattr_init (Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ raise Storage_Error;
+ end if;
+
+ if Locking_Policy = 'C' then
+ Result := pthread_mutexattr_setprotocol
+ (Attributes'Access, PTHREAD_PRIO_PROTECT);
+ pragma Assert (Result = 0);
+
+ Result := pthread_mutexattr_setprioceiling
+ (Attributes'Access, Interfaces.C.int (Prio));
+ pragma Assert (Result = 0);
+
+ elsif Locking_Policy = 'I' then
+ Result := pthread_mutexattr_setprotocol
+ (Attributes'Access, PTHREAD_PRIO_INHERIT);
+ pragma Assert (Result = 0);
+ end if;
+
+ Result := pthread_mutex_init (L, Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ raise Storage_Error;
+ end if;
+
+ Result := pthread_mutexattr_destroy (Attributes'Access);
+ pragma Assert (Result = 0);
+ end Initialize_Lock;
+
+ procedure Initialize_Lock (L : access RTS_Lock; Level : Lock_Level) is
+ pragma Warnings (Off, Level);
+
+ Attributes : aliased pthread_mutexattr_t;
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_mutexattr_init (Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ raise Storage_Error;
+ end if;
+
+ if Locking_Policy = 'C' then
+ Result := pthread_mutexattr_setprotocol
+ (Attributes'Access, PTHREAD_PRIO_PROTECT);
+ pragma Assert (Result = 0);
+
+ Result := pthread_mutexattr_setprioceiling
+ (Attributes'Access, Interfaces.C.int (System.Any_Priority'Last));
+ pragma Assert (Result = 0);
+
+ elsif Locking_Policy = 'I' then
+ Result := pthread_mutexattr_setprotocol
+ (Attributes'Access, PTHREAD_PRIO_INHERIT);
+ pragma Assert (Result = 0);
+ end if;
+
+ Result := pthread_mutex_init (L, Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ Result := pthread_mutexattr_destroy (Attributes'Access);
+ raise Storage_Error;
+ end if;
+
+ Result := pthread_mutexattr_destroy (Attributes'Access);
+ pragma Assert (Result = 0);
+ end Initialize_Lock;
+
+ -------------------
+ -- Finalize_Lock --
+ -------------------
+
+ procedure Finalize_Lock (L : access Lock) is
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_mutex_destroy (L);
+ pragma Assert (Result = 0);
+ end Finalize_Lock;
+
+ procedure Finalize_Lock (L : access RTS_Lock) is
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_mutex_destroy (L);
+ pragma Assert (Result = 0);
+ end Finalize_Lock;
+
+ ----------------
+ -- Write_Lock --
+ ----------------
+
+ procedure Write_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_mutex_lock (L);
+
+ -- Assume that the cause of EINVAL is a priority ceiling violation
+
+ Ceiling_Violation := (Result = EINVAL);
+ pragma Assert (Result = 0 or else Result = EINVAL);
+ end Write_Lock;
+
+ procedure Write_Lock
+ (L : access RTS_Lock;
+ Global_Lock : Boolean := False)
+ is
+ Result : Interfaces.C.int;
+
+ begin
+ if not Single_Lock or else Global_Lock then
+ Result := pthread_mutex_lock (L);
+ pragma Assert (Result = 0);
+ end if;
+ end Write_Lock;
+
+ procedure Write_Lock (T : Task_ID) is
+ Result : Interfaces.C.int;
+
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_lock (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Write_Lock;
+
+ ---------------
+ -- Read_Lock --
+ ---------------
+
+ procedure Read_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ begin
+ Write_Lock (L, Ceiling_Violation);
+ end Read_Lock;
+
+ ------------
+ -- Unlock --
+ ------------
+
+ procedure Unlock (L : access Lock) is
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_mutex_unlock (L);
+ pragma Assert (Result = 0);
+ end Unlock;
+
+ procedure Unlock (L : access RTS_Lock; Global_Lock : Boolean := False) is
+ Result : Interfaces.C.int;
+
+ begin
+ if not Single_Lock or else Global_Lock then
+ Result := pthread_mutex_unlock (L);
+ pragma Assert (Result = 0);
+ end if;
+ end Unlock;
+
+ procedure Unlock (T : Task_ID) is
+ Result : Interfaces.C.int;
+
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_unlock (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Unlock;
+
+ -----------
+ -- Sleep --
+ -----------
+
+ procedure Sleep
+ (Self_ID : Task_ID;
+ Reason : System.Tasking.Task_States)
+ is
+ pragma Warnings (Off, 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;
+
+ -- EINTR is not considered a failure.
+
+ pragma Assert (Result = 0 or else Result = EINTR);
+ end Sleep;
+
+ -----------------
+ -- Timed_Sleep --
+ -----------------
+
+ -- This is for use within the run-time system, so abort is
+ -- assumed to be already deferred, and the caller should be
+ -- holding its own ATCB lock.
+
+ procedure Timed_Sleep
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes;
+ Reason : Task_States;
+ Timedout : out Boolean;
+ Yielded : out Boolean)
+ is
+ pragma Warnings (Off, Reason);
+
+ Check_Time : constant Duration := Monotonic_Clock;
+ Rel_Time : Duration;
+ Abs_Time : Duration;
+ Request : aliased timespec;
+ Result : Interfaces.C.int;
+
+ begin
+ Timedout := True;
+ Yielded := False;
+
+ if Mode = Relative then
+ Abs_Time := Duration'Min (Time, Max_Sensible_Delay) + Check_Time;
+
+ if Relative_Timed_Wait then
+ Rel_Time := Duration'Min (Max_Sensible_Delay, Time);
+ end if;
+
+ else
+ Abs_Time := Duration'Min (Check_Time + Max_Sensible_Delay, Time);
+
+ if Relative_Timed_Wait then
+ Rel_Time := Duration'Min (Max_Sensible_Delay, Time - Check_Time);
+ end if;
+ 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;
+
+ loop
+ exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level
+ or else Self_ID.Pending_Priority_Change;
+
+ 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;
+
+ exit when Abs_Time <= Monotonic_Clock;
+
+ if Result = 0 or Result = EINTR then
+
+ -- Somebody may have called Wakeup for us
+
+ Timedout := False;
+ exit;
+ end if;
+
+ pragma Assert (Result = ETIMEDOUT);
+ end loop;
+ end if;
+ end Timed_Sleep;
+
+ -----------------
+ -- Timed_Delay --
+ -----------------
+
+ -- This is for use in implementing delay statements, so
+ -- we assume the caller is abort-deferred but is holding
+ -- no locks.
+
+ procedure Timed_Delay
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes)
+ is
+ Check_Time : constant Duration := Monotonic_Clock;
+ Abs_Time : Duration;
+ Rel_Time : Duration;
+ Request : aliased timespec;
+ Result : Interfaces.C.int;
+
+ begin
+ -- Only the little window between deferring abort and
+ -- locking Self_ID is the reason we need to
+ -- check for pending abort and priority change below! :(
+
+ SSL.Abort_Defer.all;
+
+ if Single_Lock then
+ Lock_RTS;
+ end if;
+
+ Write_Lock (Self_ID);
+
+ if Mode = Relative then
+ Abs_Time := Duration'Min (Time, Max_Sensible_Delay) + Check_Time;
+
+ if Relative_Timed_Wait then
+ Rel_Time := Duration'Min (Max_Sensible_Delay, Time);
+ end if;
+
+ else
+ Abs_Time := Duration'Min (Check_Time + Max_Sensible_Delay, Time);
+
+ if Relative_Timed_Wait then
+ Rel_Time := Duration'Min (Max_Sensible_Delay, Time - Check_Time);
+ end if;
+ 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;
+
+ Self_ID.Common.State := Delay_Sleep;
+
+ loop
+ if Self_ID.Pending_Priority_Change then
+ Self_ID.Pending_Priority_Change := False;
+ Self_ID.Common.Base_Priority := Self_ID.New_Base_Priority;
+ Set_Priority (Self_ID, Self_ID.Common.Base_Priority);
+ end if;
+
+ 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;
+
+ exit when Abs_Time <= Monotonic_Clock;
+
+ pragma Assert (Result = 0
+ or else Result = ETIMEDOUT
+ or else Result = EINTR);
+ end loop;
+
+ Self_ID.Common.State := Runnable;
+ end if;
+
+ Unlock (Self_ID);
+
+ if Single_Lock then
+ Unlock_RTS;
+ end if;
+
+ Result := sched_yield;
+ SSL.Abort_Undefer.all;
+ end Timed_Delay;
+
+ ---------------------
+ -- Monotonic_Clock --
+ ---------------------
+
+ function Monotonic_Clock return Duration is
+ TS : aliased timespec;
+ Result : Interfaces.C.int;
+
+ begin
+ Result := clock_gettime
+ (clock_id => CLOCK_REALTIME, tp => TS'Unchecked_Access);
+ pragma Assert (Result = 0);
+ return To_Duration (TS);
+ end Monotonic_Clock;
+
+ -------------------
+ -- RT_Resolution --
+ -------------------
+
+ function RT_Resolution return Duration is
+ begin
+ return 10#1.0#E-6;
+ end RT_Resolution;
+
+ ------------
+ -- Wakeup --
+ ------------
+
+ procedure Wakeup (T : Task_ID; Reason : System.Tasking.Task_States) is
+ pragma Warnings (Off, Reason);
+
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_cond_signal (T.Common.LL.CV'Access);
+ pragma Assert (Result = 0);
+ end Wakeup;
+
+ -----------
+ -- Yield --
+ -----------
+
+ procedure Yield (Do_Yield : Boolean := True) is
+ Result : Interfaces.C.int;
+ pragma Unreferenced (Result);
+ begin
+ if Do_Yield then
+ Result := sched_yield;
+ end if;
+ end Yield;
+
+ ------------------
+ -- Set_Priority --
+ ------------------
+
+ procedure Set_Priority
+ (T : Task_ID;
+ Prio : System.Any_Priority;
+ Loss_Of_Inheritance : Boolean := False)
+ is
+ pragma Warnings (Off, Loss_Of_Inheritance);
+
+ Result : Interfaces.C.int;
+ Param : aliased struct_sched_param;
+
+ begin
+ T.Common.Current_Priority := Prio;
+ Param.sched_priority := Interfaces.C.int (Prio);
+
+ if Time_Slice_Supported and then Time_Slice_Val > 0 then
+ Result := pthread_setschedparam
+ (T.Common.LL.Thread, SCHED_RR, Param'Access);
+
+ elsif FIFO_Within_Priorities or else Time_Slice_Val = 0 then
+ Result := pthread_setschedparam
+ (T.Common.LL.Thread, SCHED_FIFO, Param'Access);
+
+ else
+ Result := pthread_setschedparam
+ (T.Common.LL.Thread, SCHED_OTHER, Param'Access);
+ end if;
+
+ pragma Assert (Result = 0);
+ end Set_Priority;
+
+ ------------------
+ -- Get_Priority --
+ ------------------
+
+ function Get_Priority (T : Task_ID) return System.Any_Priority is
+ begin
+ return T.Common.Current_Priority;
+ end Get_Priority;
+
+ ----------------
+ -- Enter_Task --
+ ----------------
+
+ procedure Enter_Task (Self_ID : Task_ID) is
+ begin
+ Self_ID.Common.LL.Thread := pthread_self;
+ Self_ID.Common.LL.LWP := lwp_self;
+
+ Specific.Set (Self_ID);
+
+ Lock_RTS;
+
+ for J in Known_Tasks'Range loop
+ if Known_Tasks (J) = null then
+ Known_Tasks (J) := Self_ID;
+ Self_ID.Known_Tasks_Index := J;
+ exit;
+ end if;
+ end loop;
+
+ Unlock_RTS;
+ end Enter_Task;
+
+ --------------
+ -- New_ATCB --
+ --------------
+
+ function New_ATCB (Entry_Num : Task_Entry_Index) return Task_ID is
+ begin
+ return new Ada_Task_Control_Block (Entry_Num);
+ end New_ATCB;
+
+ -------------------
+ -- Is_Valid_Task --
+ -------------------
+
+ function Is_Valid_Task return Boolean renames Specific.Is_Valid_Task;
+
+ -----------------------------
+ -- Register_Foreign_Thread --
+ -----------------------------
+
+ function Register_Foreign_Thread return Task_ID is
+ begin
+ if Is_Valid_Task then
+ return Self;
+ else
+ return Register_Foreign_Thread (pthread_self);
+ end if;
+ end Register_Foreign_Thread;
+
+ --------------------
+ -- Initialize_TCB --
+ --------------------
+
+ procedure Initialize_TCB (Self_ID : Task_ID; Succeeded : out Boolean) is
+ Mutex_Attr : aliased pthread_mutexattr_t;
+ Result : Interfaces.C.int;
+ Cond_Attr : aliased pthread_condattr_t;
+
+ begin
+ -- Give the task a unique serial number.
+
+ Self_ID.Serial_Number := Next_Serial_Number;
+ Next_Serial_Number := Next_Serial_Number + 1;
+ pragma Assert (Next_Serial_Number /= 0);
+
+ if not Single_Lock then
+ Result := pthread_mutexattr_init (Mutex_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = 0 then
+ if Locking_Policy = 'C' then
+ Result := pthread_mutexattr_setprotocol
+ (Mutex_Attr'Access, PTHREAD_PRIO_PROTECT);
+ pragma Assert (Result = 0);
+
+ Result := pthread_mutexattr_setprioceiling
+ (Mutex_Attr'Access,
+ Interfaces.C.int (System.Any_Priority'Last));
+ pragma Assert (Result = 0);
+
+ elsif Locking_Policy = 'I' then
+ Result := pthread_mutexattr_setprotocol
+ (Mutex_Attr'Access, PTHREAD_PRIO_INHERIT);
+ pragma Assert (Result = 0);
+ end if;
+
+ Result := pthread_mutex_init (Self_ID.Common.LL.L'Access,
+ Mutex_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+ end if;
+
+ if Result /= 0 then
+ Succeeded := False;
+ return;
+ end if;
+
+ Result := pthread_mutexattr_destroy (Mutex_Attr'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Result := pthread_condattr_init (Cond_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = 0 then
+ Result := pthread_cond_init (Self_ID.Common.LL.CV'Access,
+ Cond_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+ end if;
+
+ if Result = 0 then
+ Succeeded := True;
+ else
+ if not Single_Lock then
+ Result := pthread_mutex_destroy (Self_ID.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Succeeded := False;
+ end if;
+
+ Result := pthread_condattr_destroy (Cond_Attr'Access);
+ pragma Assert (Result = 0);
+ end Initialize_TCB;
+
+ -----------------
+ -- Create_Task --
+ -----------------
+
+ procedure Create_Task
+ (T : Task_ID;
+ Wrapper : System.Address;
+ Stack_Size : System.Parameters.Size_Type;
+ Priority : System.Any_Priority;
+ Succeeded : out Boolean)
+ is
+ Attributes : aliased pthread_attr_t;
+ Adjusted_Stack_Size : Interfaces.C.size_t;
+ Result : Interfaces.C.int;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ use System.Task_Info;
+
+ begin
+ if Stack_Size = Unspecified_Size then
+ Adjusted_Stack_Size := Interfaces.C.size_t (Default_Stack_Size);
+
+ elsif Stack_Size < Minimum_Stack_Size then
+ Adjusted_Stack_Size := Interfaces.C.size_t (Minimum_Stack_Size);
+
+ else
+ Adjusted_Stack_Size := Interfaces.C.size_t (Stack_Size);
+ end if;
+
+ if Stack_Base_Available then
+ -- If Stack Checking is supported then allocate 2 additional pages:
+ --
+ -- In the worst case, stack is allocated at something like
+ -- N * Get_Page_Size - epsilon, we need to add the size for 2 pages
+ -- to be sure the effective stack size is greater than what
+ -- has been asked.
+
+ Adjusted_Stack_Size := Adjusted_Stack_Size + 2 * Get_Page_Size;
+ end if;
+
+ Result := pthread_attr_init (Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result /= 0 then
+ Succeeded := False;
+ return;
+ end if;
+
+ Result := pthread_attr_setdetachstate
+ (Attributes'Access, PTHREAD_CREATE_DETACHED);
+ pragma Assert (Result = 0);
+
+ Result := pthread_attr_setstacksize
+ (Attributes'Access, Adjusted_Stack_Size);
+ pragma Assert (Result = 0);
+
+ if T.Common.Task_Info /= Default_Scope then
+
+ -- We are assuming that Scope_Type has the same values than the
+ -- corresponding C macros
+
+ Result := pthread_attr_setscope
+ (Attributes'Access, Task_Info_Type'Pos (T.Common.Task_Info));
+ pragma Assert (Result = 0);
+ end if;
+
+ -- Since the initial signal mask of a thread is inherited from the
+ -- creator, and the Environment task has all its signals masked, we
+ -- do not need to manipulate caller's signal mask at this point.
+ -- All tasks in RTS will have All_Tasks_Mask initially.
+
+ Result := pthread_create
+ (T.Common.LL.Thread'Access,
+ Attributes'Access,
+ Thread_Body_Access (Wrapper),
+ To_Address (T));
+ pragma Assert (Result = 0 or else Result = EAGAIN);
+
+ Succeeded := Result = 0;
+
+ Result := pthread_attr_destroy (Attributes'Access);
+ pragma Assert (Result = 0);
+
+ Set_Priority (T, Priority);
+ end Create_Task;
+
+ ------------------
+ -- Finalize_TCB --
+ ------------------
+
+ procedure Finalize_TCB (T : Task_ID) is
+ Result : Interfaces.C.int;
+ Tmp : Task_ID := T;
+ Is_Self : constant Boolean := T = Self;
+
+ procedure Free is new
+ Unchecked_Deallocation (Ada_Task_Control_Block, Task_ID);
+
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_destroy (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Result := pthread_cond_destroy (T.Common.LL.CV'Access);
+ pragma Assert (Result = 0);
+
+ if T.Known_Tasks_Index /= -1 then
+ Known_Tasks (T.Known_Tasks_Index) := null;
+ end if;
+
+ Free (Tmp);
+
+ if Is_Self then
+ Specific.Set (null);
+ end if;
+ end Finalize_TCB;
+
+ ---------------
+ -- Exit_Task --
+ ---------------
+
+ procedure Exit_Task is
+ begin
+ -- Mark this task as unknown, so that if Self is called, it won't
+ -- return a dangling pointer.
+
+ Specific.Set (null);
+ end Exit_Task;
+
+ ----------------
+ -- Abort_Task --
+ ----------------
+
+ procedure Abort_Task (T : Task_ID) is
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_kill (T.Common.LL.Thread,
+ Signal (System.Interrupt_Management.Abort_Task_Interrupt));
+ pragma Assert (Result = 0);
+ end Abort_Task;
+
+ ----------------
+ -- Check_Exit --
+ ----------------
+
+ -- Dummy version
+
+ function Check_Exit (Self_ID : ST.Task_ID) return Boolean is
+ pragma Warnings (Off, Self_ID);
+
+ begin
+ return True;
+ end Check_Exit;
+
+ --------------------
+ -- Check_No_Locks --
+ --------------------
+
+ function Check_No_Locks (Self_ID : ST.Task_ID) return Boolean is
+ pragma Warnings (Off, Self_ID);
+
+ begin
+ return True;
+ end Check_No_Locks;
+
+ ----------------------
+ -- Environment_Task --
+ ----------------------
+
+ function Environment_Task return Task_ID is
+ begin
+ return Environment_Task_ID;
+ end Environment_Task;
+
+ --------------
+ -- Lock_RTS --
+ --------------
+
+ procedure Lock_RTS is
+ begin
+ Write_Lock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Lock_RTS;
+
+ ----------------
+ -- Unlock_RTS --
+ ----------------
+
+ procedure Unlock_RTS is
+ begin
+ Unlock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Unlock_RTS;
+
+ ------------------
+ -- Suspend_Task --
+ ------------------
+
+ function Suspend_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id)
+ return Boolean
+ is
+ pragma Warnings (Off, T);
+ pragma Warnings (Off, Thread_Self);
+
+ begin
+ return False;
+ end Suspend_Task;
+
+ -----------------
+ -- Resume_Task --
+ -----------------
+
+ function Resume_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id)
+ return Boolean
+ is
+ pragma Warnings (Off, T);
+ pragma Warnings (Off, Thread_Self);
+
+ begin
+ return False;
+ end Resume_Task;
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize (Environment_Task : Task_ID) is
+ act : aliased struct_sigaction;
+ old_act : aliased struct_sigaction;
+ Tmp_Set : aliased sigset_t;
+ Result : Interfaces.C.int;
+
+ 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:
+
+ Default : constant Character := 's';
+ -- 'n' this interrupt not set by any Interrupt_State pragma
+ -- 'u' Interrupt_State pragma set state to User
+ -- 'r' Interrupt_State pragma set state to Runtime
+ -- 's' Interrupt_State pragma set state to System (use "default"
+ -- system handler)
+
+ begin
+ Environment_Task_ID := Environment_Task;
+
+ -- Initialize the lock used to synchronize chain of all ATCBs.
+
+ Initialize_Lock (Single_RTS_Lock'Access, RTS_Lock_Level);
+
+ Specific.Initialize (Environment_Task);
+
+ Enter_Task (Environment_Task);
+
+ -- Install the abort-signal handler
+
+ if State (System.Interrupt_Management.Abort_Task_Interrupt)
+ /= Default
+ then
+ act.sa_flags := 0;
+ act.sa_handler := Abort_Handler'Address;
+
+ Result := sigemptyset (Tmp_Set'Access);
+ pragma Assert (Result = 0);
+ act.sa_mask := Tmp_Set;
+
+ Result :=
+ sigaction
+ (Signal (System.Interrupt_Management.Abort_Task_Interrupt),
+ act'Unchecked_Access,
+ old_act'Unchecked_Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Initialize;
+
+begin
+ declare
+ Result : Interfaces.C.int;
+ begin
+ -- Mask Environment task for all signals. The original mask of the
+ -- Environment task will be recovered by Interrupt_Server task
+ -- during the elaboration of s-interr.adb.
+
+ System.Interrupt_Management.Operations.Set_Interrupt_Mask
+ (System.Interrupt_Management.Operations.All_Tasks_Mask'Access);
+
+ -- Prepare the set of signals that should unblocked in all tasks
+
+ Result := sigemptyset (Unblocked_Signal_Mask'Access);
+ pragma Assert (Result = 0);
+
+ for J in Interrupt_Management.Interrupt_ID loop
+ if System.Interrupt_Management.Keep_Unmasked (J) then
+ Result := sigaddset (Unblocked_Signal_Mask'Access, Signal (J));
+ pragma Assert (Result = 0);
+ end if;
+ end loop;
+ end;
+end System.Task_Primitives.Operations;
diff --git a/gcc/ada/s-taprop-solaris.adb b/gcc/ada/s-taprop-solaris.adb
new file mode 100644
index 00000000000..a264b029693
--- /dev/null
+++ b/gcc/ada/s-taprop-solaris.adb
@@ -0,0 +1,1815 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S . O P E R A T I O N S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2004, 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- --
+-- 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, 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, --
+-- 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 is a Solaris (native) version of this package
+
+-- This package contains all the GNULL primitives that interface directly
+-- with the underlying OS.
+
+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.Tasking.Debug;
+-- used for Known_Tasks
+
+with Ada.Exceptions;
+-- used for Raise_Exception
+
+with GNAT.OS_Lib;
+-- used for String_Access, Getenv
+
+with Interfaces.C;
+-- used for int
+-- size_t
+
+with System.Interrupt_Management;
+-- used for Keep_Unmasked
+-- Abort_Task_Interrupt
+-- Interrupt_ID
+
+with System.Interrupt_Management.Operations;
+-- used for Set_Interrupt_Mask
+-- All_Tasks_Mask
+pragma Elaborate_All (System.Interrupt_Management.Operations);
+
+with System.Parameters;
+-- used for Size_Type
+
+with System.Tasking;
+-- used for Ada_Task_Control_Block
+-- Task_ID
+-- ATCB components and types
+
+with System.Task_Info;
+-- to initialize Task_Info for a C thread, in function Self
+
+with System.Soft_Links;
+-- used for Defer/Undefer_Abort
+-- to initialize TSD for a C thread, in function Self
+
+-- Note that we do not use System.Tasking.Initialization directly since
+-- this is a higher level package that we shouldn't depend on. For example
+-- when using the restricted run time, it is replaced by
+-- System.Tasking.Restricted.Initialization
+
+with System.OS_Primitives;
+-- used for Delay_Modes
+
+with Unchecked_Deallocation;
+
+package body System.Task_Primitives.Operations is
+
+ use System.Tasking.Debug;
+ use System.Tasking;
+ use Interfaces.C;
+ use System.OS_Interface;
+ use System.Parameters;
+ use Ada.Exceptions;
+ use System.OS_Primitives;
+
+ package SSL renames System.Soft_Links;
+
+ ----------------
+ -- Local Data --
+ ----------------
+
+ -- The following are logically constants, but need to be initialized
+ -- at run time.
+
+ Environment_Task_ID : Task_ID;
+ -- A variable to hold Task_ID for the environment task.
+ -- If we use this variable to get the Task_ID, we need the following
+ -- ATCB_Key only for non-Ada threads.
+
+ Unblocked_Signal_Mask : aliased sigset_t;
+ -- The set of signals that should unblocked in all tasks
+
+ ATCB_Key : aliased thread_key_t;
+ -- Key used to find the Ada Task_ID associated with a thread,
+ -- at least for C threads unknown to the Ada run-time system.
+
+ Single_RTS_Lock : aliased RTS_Lock;
+ -- This is a lock to allow only one thread of control in the RTS at
+ -- a time; it is used to execute in mutual exclusion from all other tasks.
+ -- Used mainly in Single_Lock mode, but also to protect All_Tasks_List
+
+ Next_Serial_Number : Task_Serial_Number := 100;
+ -- We start at 100, to reserve some special values for
+ -- using in error checking.
+ -- The following are internal configuration constants needed.
+
+ ----------------------
+ -- Priority Support --
+ ----------------------
+
+ Priority_Ceiling_Emulation : constant Boolean := True;
+ -- controls whether we emulate priority ceiling locking
+
+ -- To get a scheduling close to annex D requirements, we use the real-time
+ -- class provided for LWP's and map each task/thread to a specific and
+ -- unique LWP (there is 1 thread per LWP, and 1 LWP per thread).
+
+ -- The real time class can only be set when the process has root
+ -- priviledges, so in the other cases, we use the normal thread scheduling
+ -- and priority handling.
+
+ Using_Real_Time_Class : Boolean := False;
+ -- indicates wether the real time class is being used (i.e the process
+ -- has root priviledges).
+
+ Prio_Param : aliased struct_pcparms;
+ -- Hold priority info (Real_Time) initialized during the package
+ -- elaboration.
+
+ -----------------------------------
+ -- External Configuration Values --
+ -----------------------------------
+
+ Time_Slice_Val : Interfaces.C.long;
+ pragma Import (C, Time_Slice_Val, "__gl_time_slice_val");
+
+ Locking_Policy : Character;
+ pragma Import (C, Locking_Policy, "__gl_locking_policy");
+
+ Dispatching_Policy : Character;
+ pragma Import (C, Dispatching_Policy, "__gl_task_dispatching_policy");
+
+ Foreign_Task_Elaborated : aliased Boolean := True;
+ -- Used to identified fake tasks (i.e., non-Ada Threads).
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ function sysconf (name : System.OS_Interface.int) return processorid_t;
+ pragma Import (C, sysconf, "sysconf");
+
+ SC_NPROCESSORS_CONF : constant System.OS_Interface.int := 14;
+
+ function Num_Procs
+ (name : System.OS_Interface.int := SC_NPROCESSORS_CONF)
+ return processorid_t renames sysconf;
+
+ procedure Abort_Handler
+ (Sig : Signal;
+ Code : access siginfo_t;
+ Context : access ucontext_t);
+ -- Target-dependent binding of inter-thread Abort signal to
+ -- the raising of the Abort_Signal exception.
+ -- See also comments in 7staprop.adb
+
+ ------------
+ -- Checks --
+ ------------
+
+ function Check_Initialize_Lock
+ (L : Lock_Ptr;
+ Level : Lock_Level) return Boolean;
+ pragma Inline (Check_Initialize_Lock);
+
+ function Check_Lock (L : Lock_Ptr) return Boolean;
+ pragma Inline (Check_Lock);
+
+ function Record_Lock (L : Lock_Ptr) return Boolean;
+ pragma Inline (Record_Lock);
+
+ function Check_Sleep (Reason : Task_States) return Boolean;
+ pragma Inline (Check_Sleep);
+
+ function Record_Wakeup
+ (L : Lock_Ptr;
+ Reason : Task_States) return Boolean;
+ pragma Inline (Record_Wakeup);
+
+ function Check_Wakeup
+ (T : Task_ID;
+ Reason : Task_States) return Boolean;
+ pragma Inline (Check_Wakeup);
+
+ function Check_Unlock (L : Lock_Ptr) return Boolean;
+ pragma Inline (Check_Unlock);
+
+ function Check_Finalize_Lock (L : Lock_Ptr) return Boolean;
+ pragma Inline (Check_Finalize_Lock);
+
+ --------------------
+ -- Local Packages --
+ --------------------
+
+ package Specific is
+
+ procedure Initialize (Environment_Task : Task_ID);
+ pragma Inline (Initialize);
+ -- Initialize various data needed by this package.
+
+ function Is_Valid_Task return Boolean;
+ pragma Inline (Is_Valid_Task);
+ -- Does executing thread have a TCB?
+
+ procedure Set (Self_Id : Task_ID);
+ pragma Inline (Set);
+ -- Set the self id for the current task.
+
+ function Self return Task_ID;
+ pragma Inline (Self);
+ -- Return a pointer to the Ada Task Control Block of the calling task.
+
+ end Specific;
+
+ package body Specific is separate;
+ -- The body of this package is target specific.
+
+ ---------------------------------
+ -- Support for foreign threads --
+ ---------------------------------
+
+ function Register_Foreign_Thread (Thread : Thread_Id) return Task_ID;
+ -- Allocate and Initialize a new ATCB for the current Thread.
+
+ function Register_Foreign_Thread
+ (Thread : Thread_Id) return Task_ID is separate;
+
+ ------------
+ -- Checks --
+ ------------
+
+ Check_Count : Integer := 0;
+ Lock_Count : Integer := 0;
+ Unlock_Count : Integer := 0;
+
+ -------------------
+ -- Abort_Handler --
+ -------------------
+
+ procedure Abort_Handler
+ (Sig : Signal;
+ Code : access siginfo_t;
+ Context : access ucontext_t)
+ is
+ pragma Unreferenced (Sig);
+ pragma Unreferenced (Code);
+ pragma Unreferenced (Context);
+
+ Self_ID : constant Task_ID := Self;
+ Old_Set : aliased sigset_t;
+
+ Result : Interfaces.C.int;
+ pragma Unreferenced (Result);
+
+ begin
+ -- It is not safe to raise an exception when using ZCX and the GCC
+ -- exception handling mechanism.
+
+ if ZCX_By_Default and then GCC_ZCX_Support then
+ return;
+ end if;
+
+ if Self_ID.Deferral_Level = 0
+ and then Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level
+ and then not Self_ID.Aborting
+ then
+ Self_ID.Aborting := True;
+
+ -- Make sure signals used for RTS internal purpose are unmasked
+
+ Result := thr_sigsetmask (SIG_UNBLOCK,
+ Unblocked_Signal_Mask'Unchecked_Access, Old_Set'Unchecked_Access);
+ pragma Assert (Result = 0);
+
+ raise Standard'Abort_Signal;
+ end if;
+ end Abort_Handler;
+
+ -------------------
+ -- Stack_Guard --
+ -------------------
+
+ -- The underlying thread system sets a guard page at the
+ -- bottom of a thread stack, so nothing is needed.
+
+ procedure Stack_Guard (T : ST.Task_ID; On : Boolean) is
+ pragma Unreferenced (T);
+ pragma Unreferenced (On);
+
+ begin
+ null;
+ end Stack_Guard;
+
+ --------------------
+ -- Get_Thread_Id --
+ --------------------
+
+ function Get_Thread_Id (T : ST.Task_ID) return OSI.Thread_Id is
+ begin
+ return T.Common.LL.Thread;
+ end Get_Thread_Id;
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize (Environment_Task : ST.Task_ID) is
+ act : aliased struct_sigaction;
+ old_act : aliased struct_sigaction;
+ Tmp_Set : aliased sigset_t;
+ Result : Interfaces.C.int;
+
+ procedure Configure_Processors;
+ -- Processors configuration
+ -- The user can specify a processor which the program should run
+ -- on to emulate a single-processor system. This can be easily
+ -- done by setting environment variable GNAT_PROCESSOR to one of
+ -- the following :
+ --
+ -- -2 : use the default configuration (run the program on all
+ -- available processors) - this is the same as having
+ -- GNAT_PROCESSOR unset
+ -- -1 : let the RTS choose one processor and run the program on
+ -- that processor
+ -- 0 .. Last_Proc : run the program on the specified processor
+ --
+ -- Last_Proc is equal to the value of the system variable
+ -- _SC_NPROCESSORS_CONF, minus one.
+
+ procedure Configure_Processors is
+ Proc_Acc : constant GNAT.OS_Lib.String_Access :=
+ GNAT.OS_Lib.Getenv ("GNAT_PROCESSOR");
+ Proc : aliased processorid_t; -- User processor #
+ Last_Proc : processorid_t; -- Last processor #
+
+ begin
+ if Proc_Acc.all'Length /= 0 then
+ -- Environment variable is defined
+
+ Last_Proc := Num_Procs - 1;
+
+ if Last_Proc /= -1 then
+ Proc := processorid_t'Value (Proc_Acc.all);
+
+ if Proc <= -2 or else Proc > Last_Proc then
+ -- Use the default configuration
+ null;
+ elsif Proc = -1 then
+ -- Choose a processor
+
+ Result := 0;
+
+ while Proc < Last_Proc loop
+ Proc := Proc + 1;
+ Result := p_online (Proc, PR_STATUS);
+ exit when Result = PR_ONLINE;
+ end loop;
+
+ pragma Assert (Result = PR_ONLINE);
+ Result := processor_bind (P_PID, P_MYID, Proc, null);
+ pragma Assert (Result = 0);
+
+ else
+ -- Use user processor
+
+ Result := processor_bind (P_PID, P_MYID, Proc, null);
+ pragma Assert (Result = 0);
+ end if;
+ end if;
+ end if;
+
+ exception
+ when Constraint_Error =>
+
+ -- Illegal environment variable GNAT_PROCESSOR - ignored
+
+ null;
+ end Configure_Processors;
+
+ 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:
+
+ Default : constant Character := 's';
+ -- 'n' this interrupt not set by any Interrupt_State pragma
+ -- 'u' Interrupt_State pragma set state to User
+ -- 'r' Interrupt_State pragma set state to Runtime
+ -- 's' Interrupt_State pragma set state to System (use "default"
+ -- system handler)
+
+ -- Start of processing for Initialize
+
+ begin
+ Environment_Task_ID := Environment_Task;
+
+ -- This is done in Enter_Task, but this is too late for the
+ -- Environment Task, since we need to call Self in Check_Locks when
+ -- the run time is compiled with assertions on.
+
+ Specific.Initialize (Environment_Task);
+
+ -- Initialize the lock used to synchronize chain of all ATCBs.
+
+ Initialize_Lock (Single_RTS_Lock'Access, RTS_Lock_Level);
+
+ Enter_Task (Environment_Task);
+
+ -- Install the abort-signal handler
+
+ if State (System.Interrupt_Management.Abort_Task_Interrupt)
+ /= Default
+ then
+ -- Set sa_flags to SA_NODEFER so that during the handler execution
+ -- we do not change the Signal_Mask to be masked for the Abort_Signal
+ -- This is a temporary fix to the problem that the Signal_Mask is
+ -- not restored after the exception (longjmp) from the handler.
+ -- The right fix should be made in sigsetjmp so that we save
+ -- the Signal_Set and restore it after a longjmp.
+ -- In that case, this field should be changed back to 0. ???
+
+ act.sa_flags := 16;
+
+ act.sa_handler := Abort_Handler'Address;
+ Result := sigemptyset (Tmp_Set'Access);
+ pragma Assert (Result = 0);
+ act.sa_mask := Tmp_Set;
+
+ Result :=
+ sigaction (
+ Signal (System.Interrupt_Management.Abort_Task_Interrupt),
+ act'Unchecked_Access,
+ old_act'Unchecked_Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Configure_Processors;
+ end Initialize;
+
+ ---------------------
+ -- Initialize_Lock --
+ ---------------------
+
+ -- Note: mutexes and cond_variables needed per-task basis are
+ -- initialized in Initialize_TCB and the Storage_Error is
+ -- handled. Other mutexes (such as RTS_Lock, Memory_Lock...)
+ -- used in RTS is initialized before any status change of RTS.
+ -- Therefore rasing Storage_Error in the following routines
+ -- should be able to be handled safely.
+
+ procedure Initialize_Lock
+ (Prio : System.Any_Priority;
+ L : access Lock)
+ is
+ Result : Interfaces.C.int;
+
+ begin
+ pragma Assert (Check_Initialize_Lock (Lock_Ptr (L), PO_Level));
+
+ if Priority_Ceiling_Emulation then
+ L.Ceiling := Prio;
+ end if;
+
+ Result := mutex_init (L.L'Access, USYNC_THREAD, System.Null_Address);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ Raise_Exception (Storage_Error'Identity, "Failed to allocate a lock");
+ end if;
+ end Initialize_Lock;
+
+ procedure Initialize_Lock
+ (L : access RTS_Lock;
+ Level : Lock_Level)
+ is
+ Result : Interfaces.C.int;
+
+ begin
+ pragma Assert (Check_Initialize_Lock
+ (To_Lock_Ptr (RTS_Lock_Ptr (L)), Level));
+ Result := mutex_init (L.L'Access, USYNC_THREAD, System.Null_Address);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ Raise_Exception (Storage_Error'Identity, "Failed to allocate a lock");
+ end if;
+ end Initialize_Lock;
+
+ -------------------
+ -- Finalize_Lock --
+ -------------------
+
+ procedure Finalize_Lock (L : access Lock) is
+ Result : Interfaces.C.int;
+
+ begin
+ pragma Assert (Check_Finalize_Lock (Lock_Ptr (L)));
+ Result := mutex_destroy (L.L'Access);
+ pragma Assert (Result = 0);
+ end Finalize_Lock;
+
+ procedure Finalize_Lock (L : access RTS_Lock) is
+ Result : Interfaces.C.int;
+
+ begin
+ pragma Assert (Check_Finalize_Lock (To_Lock_Ptr (RTS_Lock_Ptr (L))));
+ Result := mutex_destroy (L.L'Access);
+ pragma Assert (Result = 0);
+ end Finalize_Lock;
+
+ ----------------
+ -- Write_Lock --
+ ----------------
+
+ procedure Write_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ Result : Interfaces.C.int;
+
+ begin
+ pragma Assert (Check_Lock (Lock_Ptr (L)));
+
+ if Priority_Ceiling_Emulation and then Locking_Policy = 'C' then
+ declare
+ Self_Id : constant Task_ID := Self;
+ Saved_Priority : System.Any_Priority;
+
+ begin
+ if Self_Id.Common.LL.Active_Priority > L.Ceiling then
+ Ceiling_Violation := True;
+ return;
+ end if;
+
+ Saved_Priority := Self_Id.Common.LL.Active_Priority;
+
+ if Self_Id.Common.LL.Active_Priority < L.Ceiling then
+ Set_Priority (Self_Id, L.Ceiling);
+ end if;
+
+ Result := mutex_lock (L.L'Access);
+ pragma Assert (Result = 0);
+ Ceiling_Violation := False;
+
+ L.Saved_Priority := Saved_Priority;
+ end;
+
+ else
+ Result := mutex_lock (L.L'Access);
+ pragma Assert (Result = 0);
+ Ceiling_Violation := False;
+ end if;
+
+ pragma Assert (Record_Lock (Lock_Ptr (L)));
+ end Write_Lock;
+
+ procedure Write_Lock
+ (L : access RTS_Lock;
+ Global_Lock : Boolean := False)
+ is
+ Result : Interfaces.C.int;
+
+ begin
+ if not Single_Lock or else Global_Lock then
+ pragma Assert (Check_Lock (To_Lock_Ptr (RTS_Lock_Ptr (L))));
+ Result := mutex_lock (L.L'Access);
+ pragma Assert (Result = 0);
+ pragma Assert (Record_Lock (To_Lock_Ptr (RTS_Lock_Ptr (L))));
+ end if;
+ end Write_Lock;
+
+ procedure Write_Lock (T : Task_ID) is
+ Result : Interfaces.C.int;
+
+ begin
+ if not Single_Lock then
+ pragma Assert (Check_Lock (To_Lock_Ptr (T.Common.LL.L'Access)));
+ Result := mutex_lock (T.Common.LL.L.L'Access);
+ pragma Assert (Result = 0);
+ pragma Assert (Record_Lock (To_Lock_Ptr (T.Common.LL.L'Access)));
+ end if;
+ end Write_Lock;
+
+ ---------------
+ -- Read_Lock --
+ ---------------
+
+ procedure Read_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ begin
+ Write_Lock (L, Ceiling_Violation);
+ end Read_Lock;
+
+ ------------
+ -- Unlock --
+ ------------
+
+ procedure Unlock (L : access Lock) is
+ Result : Interfaces.C.int;
+
+ begin
+ pragma Assert (Check_Unlock (Lock_Ptr (L)));
+
+ if Priority_Ceiling_Emulation and then Locking_Policy = 'C' then
+ declare
+ Self_Id : constant Task_ID := Self;
+
+ begin
+ Result := mutex_unlock (L.L'Access);
+ pragma Assert (Result = 0);
+
+ if Self_Id.Common.LL.Active_Priority > L.Saved_Priority then
+ Set_Priority (Self_Id, L.Saved_Priority);
+ end if;
+ end;
+ else
+ Result := mutex_unlock (L.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Unlock;
+
+ procedure Unlock (L : access RTS_Lock; Global_Lock : Boolean := False) is
+ Result : Interfaces.C.int;
+
+ begin
+ if not Single_Lock or else Global_Lock then
+ pragma Assert (Check_Unlock (To_Lock_Ptr (RTS_Lock_Ptr (L))));
+ Result := mutex_unlock (L.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Unlock;
+
+ procedure Unlock (T : Task_ID) is
+ Result : Interfaces.C.int;
+
+ begin
+ if not Single_Lock then
+ pragma Assert (Check_Unlock (To_Lock_Ptr (T.Common.LL.L'Access)));
+ Result := mutex_unlock (T.Common.LL.L.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Unlock;
+
+ -- For the time delay implementation, we need to make sure we
+ -- achieve following criteria:
+
+ -- 1) We have to delay at least for the amount requested.
+ -- 2) We have to give up CPU even though the actual delay does not
+ -- result in blocking.
+ -- 3) Except for restricted run-time systems that do not support
+ -- ATC or task abort, the delay must be interrupted by the
+ -- abort_task operation.
+ -- 4) The implementation has to be efficient so that the delay overhead
+ -- is relatively cheap.
+ -- (1)-(3) are Ada requirements. Even though (2) is an Annex-D
+ -- requirement we still want to provide the effect in all cases.
+ -- The reason is that users may want to use short delays to implement
+ -- their own scheduling effect in the absence of language provided
+ -- scheduling policies.
+
+ ---------------------
+ -- Monotonic_Clock --
+ ---------------------
+
+ function Monotonic_Clock return Duration is
+ TS : aliased timespec;
+ Result : Interfaces.C.int;
+
+ begin
+ Result := clock_gettime (CLOCK_REALTIME, TS'Unchecked_Access);
+ pragma Assert (Result = 0);
+ return To_Duration (TS);
+ end Monotonic_Clock;
+
+ -------------------
+ -- RT_Resolution --
+ -------------------
+
+ function RT_Resolution return Duration is
+ begin
+ return 10#1.0#E-6;
+ end RT_Resolution;
+
+ -----------
+ -- Yield --
+ -----------
+
+ procedure Yield (Do_Yield : Boolean := True) is
+ begin
+ if Do_Yield then
+ System.OS_Interface.thr_yield;
+ end if;
+ end Yield;
+
+ -----------
+ -- Self ---
+ -----------
+
+ function Self return Task_ID renames Specific.Self;
+
+ ------------------
+ -- Set_Priority --
+ ------------------
+
+ procedure Set_Priority
+ (T : Task_ID;
+ Prio : System.Any_Priority;
+ Loss_Of_Inheritance : Boolean := False)
+ is
+ pragma Unreferenced (Loss_Of_Inheritance);
+
+ Result : Interfaces.C.int;
+ pragma Unreferenced (Result);
+
+ Param : aliased struct_pcparms;
+
+ use Task_Info;
+
+ begin
+ T.Common.Current_Priority := Prio;
+
+ if Priority_Ceiling_Emulation then
+ T.Common.LL.Active_Priority := Prio;
+ end if;
+
+ if Using_Real_Time_Class then
+ Param.pc_cid := Prio_Param.pc_cid;
+ Param.rt_pri := pri_t (Prio);
+ Param.rt_tqsecs := Prio_Param.rt_tqsecs;
+ Param.rt_tqnsecs := Prio_Param.rt_tqnsecs;
+
+ Result := Interfaces.C.int (
+ priocntl (PC_VERSION, P_LWPID, T.Common.LL.LWP, PC_SETPARMS,
+ Param'Address));
+
+ else
+ if T.Common.Task_Info /= null
+ and then not T.Common.Task_Info.Bound_To_LWP
+ then
+ -- The task is not bound to a LWP, so use thr_setprio
+
+ Result :=
+ thr_setprio (T.Common.LL.Thread, Interfaces.C.int (Prio));
+
+ else
+
+ -- The task is bound to a LWP, use priocntl
+ -- ??? TBD
+
+ null;
+ end if;
+ end if;
+ end Set_Priority;
+
+ ------------------
+ -- Get_Priority --
+ ------------------
+
+ function Get_Priority (T : Task_ID) return System.Any_Priority is
+ begin
+ return T.Common.Current_Priority;
+ end Get_Priority;
+
+ ----------------
+ -- Enter_Task --
+ ----------------
+
+ procedure Enter_Task (Self_ID : Task_ID) is
+ Result : Interfaces.C.int;
+ Proc : processorid_t; -- User processor #
+ Last_Proc : processorid_t; -- Last processor #
+
+ use System.Task_Info;
+ begin
+ Self_ID.Common.LL.Thread := thr_self;
+
+ Self_ID.Common.LL.LWP := lwp_self;
+
+ if Self_ID.Common.Task_Info /= null then
+ if Self_ID.Common.Task_Info.New_LWP
+ and then Self_ID.Common.Task_Info.CPU /= CPU_UNCHANGED
+ then
+ Last_Proc := Num_Procs - 1;
+
+ if Self_ID.Common.Task_Info.CPU = ANY_CPU then
+ Result := 0;
+ Proc := 0;
+
+ while Proc < Last_Proc loop
+ Result := p_online (Proc, PR_STATUS);
+ exit when Result = PR_ONLINE;
+ Proc := Proc + 1;
+ end loop;
+
+ Result := processor_bind (P_LWPID, P_MYID, Proc, null);
+ pragma Assert (Result = 0);
+
+ else
+ -- Use specified processor
+
+ if Self_ID.Common.Task_Info.CPU < 0
+ or else Self_ID.Common.Task_Info.CPU > Last_Proc
+ then
+ raise Invalid_CPU_Number;
+ end if;
+
+ Result := processor_bind
+ (P_LWPID, P_MYID, Self_ID.Common.Task_Info.CPU, null);
+ pragma Assert (Result = 0);
+ end if;
+ end if;
+ end if;
+
+ Specific.Set (Self_ID);
+
+ -- We need the above code even if we do direct fetch of Task_ID in Self
+ -- for the main task on Sun, x86 Solaris and for gcc 2.7.2.
+
+ Lock_RTS;
+
+ for J in Known_Tasks'Range loop
+ if Known_Tasks (J) = null then
+ Known_Tasks (J) := Self_ID;
+ Self_ID.Known_Tasks_Index := J;
+ exit;
+ end if;
+ end loop;
+
+ Unlock_RTS;
+ end Enter_Task;
+
+ --------------
+ -- New_ATCB --
+ --------------
+
+ function New_ATCB (Entry_Num : Task_Entry_Index) return Task_ID is
+ begin
+ return new Ada_Task_Control_Block (Entry_Num);
+ end New_ATCB;
+
+ -------------------
+ -- Is_Valid_Task --
+ -------------------
+
+ function Is_Valid_Task return Boolean renames Specific.Is_Valid_Task;
+
+ -----------------------------
+ -- Register_Foreign_Thread --
+ -----------------------------
+
+ function Register_Foreign_Thread return Task_ID is
+ begin
+ if Is_Valid_Task then
+ return Self;
+ else
+ return Register_Foreign_Thread (thr_self);
+ end if;
+ end Register_Foreign_Thread;
+
+ --------------------
+ -- Initialize_TCB --
+ --------------------
+
+ procedure Initialize_TCB (Self_ID : Task_ID; Succeeded : out Boolean) is
+ Result : Interfaces.C.int := 0;
+
+ begin
+ -- Give the task a unique serial number.
+
+ Self_ID.Serial_Number := Next_Serial_Number;
+ Next_Serial_Number := Next_Serial_Number + 1;
+ pragma Assert (Next_Serial_Number /= 0);
+
+ Self_ID.Common.LL.Thread := To_thread_t (-1);
+
+ if not Single_Lock then
+ Result := mutex_init
+ (Self_ID.Common.LL.L.L'Access, USYNC_THREAD, System.Null_Address);
+ Self_ID.Common.LL.L.Level :=
+ Private_Task_Serial_Number (Self_ID.Serial_Number);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+ end if;
+
+ if Result = 0 then
+ Result := cond_init (Self_ID.Common.LL.CV'Access, USYNC_THREAD, 0);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+ end if;
+
+ if Result = 0 then
+ Succeeded := True;
+ else
+ if not Single_Lock then
+ Result := mutex_destroy (Self_ID.Common.LL.L.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Succeeded := False;
+ end if;
+ end Initialize_TCB;
+
+ -----------------
+ -- Create_Task --
+ -----------------
+
+ procedure Create_Task
+ (T : Task_ID;
+ Wrapper : System.Address;
+ Stack_Size : System.Parameters.Size_Type;
+ Priority : System.Any_Priority;
+ Succeeded : out Boolean)
+ is
+ pragma Unreferenced (Priority);
+
+ Result : Interfaces.C.int;
+ Adjusted_Stack_Size : Interfaces.C.size_t;
+ Opts : Interfaces.C.int := THR_DETACHED;
+
+ Page_Size : constant System.Parameters.Size_Type := 4096;
+ -- This constant is for reserving extra space at the
+ -- end of the stack, which can be used by the stack
+ -- checking as guard page. The idea is that we need
+ -- to have at least Stack_Size bytes available for
+ -- actual use.
+
+ use System.Task_Info;
+
+ begin
+ if Stack_Size = System.Parameters.Unspecified_Size then
+ Adjusted_Stack_Size :=
+ Interfaces.C.size_t (Default_Stack_Size + Page_Size);
+
+ elsif Stack_Size < Minimum_Stack_Size then
+ Adjusted_Stack_Size :=
+ Interfaces.C.size_t (Minimum_Stack_Size + Page_Size);
+
+ else
+ Adjusted_Stack_Size :=
+ Interfaces.C.size_t (Stack_Size + Page_Size);
+ end if;
+
+ -- Since the initial signal mask of a thread is inherited from the
+ -- creator, and the Environment task has all its signals masked, we
+ -- do not need to manipulate caller's signal mask at this point.
+ -- All tasks in RTS will have All_Tasks_Mask initially.
+
+ if T.Common.Task_Info /= null then
+ if T.Common.Task_Info.New_LWP then
+ Opts := Opts + THR_NEW_LWP;
+ end if;
+
+ if T.Common.Task_Info.Bound_To_LWP then
+ Opts := Opts + THR_BOUND;
+ end if;
+
+ else
+ Opts := THR_DETACHED + THR_BOUND;
+ end if;
+
+ Result := thr_create
+ (System.Null_Address,
+ Adjusted_Stack_Size,
+ Thread_Body_Access (Wrapper),
+ To_Address (T),
+ Opts,
+ T.Common.LL.Thread'Access);
+
+ Succeeded := Result = 0;
+ pragma Assert
+ (Result = 0
+ or else Result = ENOMEM
+ or else Result = EAGAIN);
+ end Create_Task;
+
+ ------------------
+ -- Finalize_TCB --
+ ------------------
+
+ procedure Finalize_TCB (T : Task_ID) is
+ Result : Interfaces.C.int;
+ Tmp : Task_ID := T;
+ Is_Self : constant Boolean := T = Self;
+
+ procedure Free is new
+ Unchecked_Deallocation (Ada_Task_Control_Block, Task_ID);
+
+ begin
+ T.Common.LL.Thread := To_thread_t (0);
+
+ if not Single_Lock then
+ Result := mutex_destroy (T.Common.LL.L.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Result := cond_destroy (T.Common.LL.CV'Access);
+ pragma Assert (Result = 0);
+
+ if T.Known_Tasks_Index /= -1 then
+ Known_Tasks (T.Known_Tasks_Index) := null;
+ end if;
+
+ Free (Tmp);
+
+ if Is_Self then
+ Specific.Set (null);
+ end if;
+ end Finalize_TCB;
+
+ ---------------
+ -- Exit_Task --
+ ---------------
+
+ -- This procedure must be called with abort deferred.
+ -- It can no longer call Self or access
+ -- the current task's ATCB, since the ATCB has been deallocated.
+
+ procedure Exit_Task is
+ begin
+ Specific.Set (null);
+ end Exit_Task;
+
+ ----------------
+ -- Abort_Task --
+ ----------------
+
+ procedure Abort_Task (T : Task_ID) is
+ Result : Interfaces.C.int;
+ begin
+ pragma Assert (T /= Self);
+
+ Result := thr_kill (T.Common.LL.Thread,
+ Signal (System.Interrupt_Management.Abort_Task_Interrupt));
+ null;
+
+ pragma Assert (Result = 0);
+ end Abort_Task;
+
+ -----------
+ -- Sleep --
+ -----------
+
+ procedure Sleep
+ (Self_ID : Task_ID;
+ Reason : Task_States)
+ is
+ Result : Interfaces.C.int;
+
+ begin
+ pragma Assert (Check_Sleep (Reason));
+
+ if Dynamic_Priority_Support
+ and then Self_ID.Pending_Priority_Change
+ then
+ Self_ID.Pending_Priority_Change := False;
+ Self_ID.Common.Base_Priority := Self_ID.New_Base_Priority;
+ Set_Priority (Self_ID, Self_ID.Common.Base_Priority);
+ end if;
+
+ if Single_Lock then
+ Result := cond_wait
+ (Self_ID.Common.LL.CV'Access, Single_RTS_Lock.L'Access);
+ else
+ Result := cond_wait
+ (Self_ID.Common.LL.CV'Access, Self_ID.Common.LL.L.L'Access);
+ end if;
+
+ pragma Assert (Record_Wakeup
+ (To_Lock_Ptr (Self_ID.Common.LL.L'Access), Reason));
+ pragma Assert (Result = 0 or else Result = EINTR);
+ end Sleep;
+
+ -- Note that we are relying heaviliy here on the GNAT feature
+ -- that Calendar.Time, System.Real_Time.Time, Duration, and
+ -- System.Real_Time.Time_Span are all represented in the same
+ -- way, i.e., as a 64-bit count of nanoseconds.
+
+ -- This allows us to always pass the timeout value as a Duration.
+
+ -- ???
+ -- We are taking liberties here with the semantics of the delays.
+ -- That is, we make no distinction between delays on the Calendar clock
+ -- and delays on the Real_Time clock. That is technically incorrect, if
+ -- the Calendar clock happens to be reset or adjusted.
+ -- To solve this defect will require modification to the compiler
+ -- interface, so that it can pass through more information, to tell
+ -- us here which clock to use!
+
+ -- cond_timedwait will return if any of the following happens:
+ -- 1) some other task did cond_signal on this condition variable
+ -- In this case, the return value is 0
+ -- 2) the call just returned, for no good reason
+ -- This is called a "spurious wakeup".
+ -- In this case, the return value may also be 0.
+ -- 3) the time delay expires
+ -- In this case, the return value is ETIME
+ -- 4) this task received a signal, which was handled by some
+ -- handler procedure, and now the thread is resuming execution
+ -- UNIX calls this an "interrupted" system call.
+ -- In this case, the return value is EINTR
+
+ -- If the cond_timedwait returns 0 or EINTR, it is still
+ -- possible that the time has actually expired, and by chance
+ -- a signal or cond_signal occurred at around the same time.
+
+ -- We have also observed that on some OS's the value ETIME
+ -- will be returned, but the clock will show that the full delay
+ -- has not yet expired.
+
+ -- For these reasons, we need to check the clock after return
+ -- from cond_timedwait. If the time has expired, we will set
+ -- Timedout = True.
+
+ -- This check might be omitted for systems on which the
+ -- cond_timedwait() never returns early or wakes up spuriously.
+
+ -- Annex D requires that completion of a delay cause the task
+ -- to go to the end of its priority queue, regardless of whether
+ -- the task actually was suspended by the delay. Since
+ -- cond_timedwait does not do this on Solaris, we add a call
+ -- to thr_yield at the end. We might do this at the beginning,
+ -- instead, but then the round-robin effect would not be the
+ -- same; the delayed task would be ahead of other tasks of the
+ -- same priority that awoke while it was sleeping.
+
+ -- For Timed_Sleep, we are expecting possible cond_signals
+ -- to indicate other events (e.g., completion of a RV or
+ -- completion of the abortable part of an async. select),
+ -- we want to always return if interrupted. The caller will
+ -- be responsible for checking the task state to see whether
+ -- the wakeup was spurious, and to go back to sleep again
+ -- in that case. We don't need to check for pending abort
+ -- or priority change on the way in our out; that is the
+ -- caller's responsibility.
+
+ -- For Timed_Delay, we are not expecting any cond_signals or
+ -- other interruptions, except for priority changes and aborts.
+ -- Therefore, we don't want to return unless the delay has
+ -- actually expired, or the call has been aborted. In this
+ -- case, since we want to implement the entire delay statement
+ -- semantics, we do need to check for pending abort and priority
+ -- changes. We can quietly handle priority changes inside the
+ -- procedure, since there is no entry-queue reordering involved.
+
+ -----------------
+ -- Timed_Sleep --
+ -----------------
+
+ procedure Timed_Sleep
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes;
+ Reason : System.Tasking.Task_States;
+ Timedout : out Boolean;
+ Yielded : out Boolean)
+ is
+ Check_Time : constant Duration := Monotonic_Clock;
+ Abs_Time : Duration;
+ Request : aliased timespec;
+ Result : Interfaces.C.int;
+
+ begin
+ pragma Assert (Check_Sleep (Reason));
+ 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;
+
+ if Abs_Time > Check_Time then
+ Request := To_Timespec (Abs_Time);
+
+ loop
+ exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level
+ or else (Dynamic_Priority_Support and then
+ Self_ID.Pending_Priority_Change);
+
+ if Single_Lock then
+ Result := cond_timedwait (Self_ID.Common.LL.CV'Access,
+ Single_RTS_Lock.L'Access, Request'Access);
+ else
+ Result := cond_timedwait (Self_ID.Common.LL.CV'Access,
+ Self_ID.Common.LL.L.L'Access, Request'Access);
+ end if;
+
+ Yielded := True;
+
+ exit when Abs_Time <= Monotonic_Clock;
+
+ if Result = 0 or Result = EINTR then
+
+ -- Somebody may have called Wakeup for us
+
+ Timedout := False;
+ exit;
+ end if;
+
+ pragma Assert (Result = ETIME);
+ end loop;
+ end if;
+
+ pragma Assert (Record_Wakeup
+ (To_Lock_Ptr (Self_ID.Common.LL.L'Access), Reason));
+ end Timed_Sleep;
+
+ -----------------
+ -- Timed_Delay --
+ -----------------
+
+ procedure Timed_Delay
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes)
+ is
+ Check_Time : constant Duration := Monotonic_Clock;
+ Abs_Time : Duration;
+ Request : aliased timespec;
+ Result : Interfaces.C.int;
+ Yielded : Boolean := False;
+
+ begin
+ -- Only the little window between deferring abort and
+ -- locking Self_ID is the reason we need to
+ -- check for pending abort and priority change below!
+
+ SSL.Abort_Defer.all;
+
+ if Single_Lock then
+ Lock_RTS;
+ end if;
+
+ 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;
+
+ if Abs_Time > Check_Time then
+ Request := To_Timespec (Abs_Time);
+ Self_ID.Common.State := Delay_Sleep;
+
+ pragma Assert (Check_Sleep (Delay_Sleep));
+
+ loop
+ if Dynamic_Priority_Support and then
+ Self_ID.Pending_Priority_Change then
+ Self_ID.Pending_Priority_Change := False;
+ Self_ID.Common.Base_Priority := Self_ID.New_Base_Priority;
+ Set_Priority (Self_ID, Self_ID.Common.Base_Priority);
+ end if;
+
+ exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level;
+
+ if Single_Lock then
+ Result := cond_timedwait (Self_ID.Common.LL.CV'Access,
+ Single_RTS_Lock.L'Access, Request'Access);
+ else
+ Result := cond_timedwait (Self_ID.Common.LL.CV'Access,
+ Self_ID.Common.LL.L.L'Access, Request'Access);
+ end if;
+
+ Yielded := True;
+
+ exit when Abs_Time <= Monotonic_Clock;
+
+ pragma Assert (Result = 0 or else
+ Result = ETIME or else
+ Result = EINTR);
+ end loop;
+
+ pragma Assert (Record_Wakeup
+ (To_Lock_Ptr (Self_ID.Common.LL.L'Access), Delay_Sleep));
+
+ Self_ID.Common.State := Runnable;
+ end if;
+
+ Unlock (Self_ID);
+
+ if Single_Lock then
+ Unlock_RTS;
+ end if;
+
+ if not Yielded then
+ thr_yield;
+ end if;
+
+ SSL.Abort_Undefer.all;
+ end Timed_Delay;
+
+ ------------
+ -- Wakeup --
+ ------------
+
+ procedure Wakeup
+ (T : Task_ID;
+ Reason : Task_States)
+ is
+ Result : Interfaces.C.int;
+
+ begin
+ pragma Assert (Check_Wakeup (T, Reason));
+ Result := cond_signal (T.Common.LL.CV'Access);
+ pragma Assert (Result = 0);
+ end Wakeup;
+
+ ---------------------------
+ -- Check_Initialize_Lock --
+ ---------------------------
+
+ -- The following code is intended to check some of the invariant
+ -- assertions related to lock usage, on which we depend.
+
+ function Check_Initialize_Lock
+ (L : Lock_Ptr;
+ Level : Lock_Level) return Boolean
+ is
+ Self_ID : constant Task_ID := Self;
+
+ begin
+ -- Check that caller is abort-deferred
+
+ if Self_ID.Deferral_Level <= 0 then
+ return False;
+ end if;
+
+ -- Check that the lock is not yet initialized
+
+ if L.Level /= 0 then
+ return False;
+ end if;
+
+ L.Level := Lock_Level'Pos (Level) + 1;
+ return True;
+ end Check_Initialize_Lock;
+
+ ----------------
+ -- Check_Lock --
+ ----------------
+
+ function Check_Lock (L : Lock_Ptr) return Boolean is
+ Self_ID : constant Task_ID := Self;
+ P : Lock_Ptr;
+
+ begin
+ -- Check that the argument is not null
+
+ if L = null then
+ return False;
+ end if;
+
+ -- Check that L is not frozen
+
+ if L.Frozen then
+ return False;
+ end if;
+
+ -- Check that caller is abort-deferred
+
+ if Self_ID.Deferral_Level <= 0 then
+ return False;
+ end if;
+
+ -- Check that caller is not holding this lock already
+
+ if L.Owner = To_Owner_ID (To_Address (Self_ID)) then
+ return False;
+ end if;
+
+ if Single_Lock then
+ return True;
+ end if;
+
+ -- Check that TCB lock order rules are satisfied
+
+ P := Self_ID.Common.LL.Locks;
+ if P /= null then
+ if P.Level >= L.Level
+ and then (P.Level > 2 or else L.Level > 2)
+ then
+ return False;
+ end if;
+ end if;
+
+ return True;
+ end Check_Lock;
+
+ -----------------
+ -- Record_Lock --
+ -----------------
+
+ function Record_Lock (L : Lock_Ptr) return Boolean is
+ Self_ID : constant Task_ID := Self;
+ P : Lock_Ptr;
+
+ begin
+ Lock_Count := Lock_Count + 1;
+
+ -- There should be no owner for this lock at this point
+
+ if L.Owner /= null then
+ return False;
+ end if;
+
+ -- Record new owner
+
+ L.Owner := To_Owner_ID (To_Address (Self_ID));
+
+ if Single_Lock then
+ return True;
+ end if;
+
+ -- Check that TCB lock order rules are satisfied
+
+ P := Self_ID.Common.LL.Locks;
+
+ if P /= null then
+ L.Next := P;
+ end if;
+
+ Self_ID.Common.LL.Locking := null;
+ Self_ID.Common.LL.Locks := L;
+ return True;
+ end Record_Lock;
+
+ -----------------
+ -- Check_Sleep --
+ -----------------
+
+ function Check_Sleep (Reason : Task_States) return Boolean is
+ pragma Unreferenced (Reason);
+
+ Self_ID : constant Task_ID := Self;
+ P : Lock_Ptr;
+
+ begin
+ -- Check that caller is abort-deferred
+
+ if Self_ID.Deferral_Level <= 0 then
+ return False;
+ end if;
+
+ if Single_Lock then
+ return True;
+ end if;
+
+ -- Check that caller is holding own lock, on top of list
+
+ if Self_ID.Common.LL.Locks /=
+ To_Lock_Ptr (Self_ID.Common.LL.L'Access)
+ then
+ return False;
+ end if;
+
+ -- Check that TCB lock order rules are satisfied
+
+ if Self_ID.Common.LL.Locks.Next /= null then
+ return False;
+ end if;
+
+ Self_ID.Common.LL.L.Owner := null;
+ P := Self_ID.Common.LL.Locks;
+ Self_ID.Common.LL.Locks := Self_ID.Common.LL.Locks.Next;
+ P.Next := null;
+ return True;
+ end Check_Sleep;
+
+ -------------------
+ -- Record_Wakeup --
+ -------------------
+
+ function Record_Wakeup
+ (L : Lock_Ptr;
+ Reason : Task_States) return Boolean
+ is
+ pragma Unreferenced (Reason);
+
+ Self_ID : constant Task_ID := Self;
+ P : Lock_Ptr;
+
+ begin
+ -- Record new owner
+
+ L.Owner := To_Owner_ID (To_Address (Self_ID));
+
+ if Single_Lock then
+ return True;
+ end if;
+
+ -- Check that TCB lock order rules are satisfied
+
+ P := Self_ID.Common.LL.Locks;
+
+ if P /= null then
+ L.Next := P;
+ end if;
+
+ Self_ID.Common.LL.Locking := null;
+ Self_ID.Common.LL.Locks := L;
+ return True;
+ end Record_Wakeup;
+
+ ------------------
+ -- Check_Wakeup --
+ ------------------
+
+ function Check_Wakeup
+ (T : Task_ID;
+ Reason : Task_States) return Boolean
+ is
+ Self_ID : constant Task_ID := Self;
+
+ begin
+ -- Is caller holding T's lock?
+
+ if T.Common.LL.L.Owner /= To_Owner_ID (To_Address (Self_ID)) then
+ return False;
+ end if;
+
+ -- Are reasons for wakeup and sleep consistent?
+
+ if T.Common.State /= Reason then
+ return False;
+ end if;
+
+ return True;
+ end Check_Wakeup;
+
+ ------------------
+ -- Check_Unlock --
+ ------------------
+
+ function Check_Unlock (L : Lock_Ptr) return Boolean is
+ Self_ID : constant Task_ID := Self;
+ P : Lock_Ptr;
+
+ begin
+ Unlock_Count := Unlock_Count + 1;
+
+ if L = null then
+ return False;
+ end if;
+
+ if L.Buddy /= null then
+ return False;
+ end if;
+
+ if L.Level = 4 then
+ Check_Count := Unlock_Count;
+ end if;
+
+ if Unlock_Count - Check_Count > 1000 then
+ Check_Count := Unlock_Count;
+ end if;
+
+ -- Check that caller is abort-deferred
+
+ if Self_ID.Deferral_Level <= 0 then
+ return False;
+ end if;
+
+ -- Check that caller is holding this lock, on top of list
+
+ if Self_ID.Common.LL.Locks /= L then
+ return False;
+ end if;
+
+ -- Record there is no owner now
+
+ L.Owner := null;
+ P := Self_ID.Common.LL.Locks;
+ Self_ID.Common.LL.Locks := Self_ID.Common.LL.Locks.Next;
+ P.Next := null;
+ return True;
+ end Check_Unlock;
+
+ --------------------
+ -- Check_Finalize --
+ --------------------
+
+ function Check_Finalize_Lock (L : Lock_Ptr) return Boolean is
+ Self_ID : constant Task_ID := Self;
+
+ begin
+ -- Check that caller is abort-deferred
+
+ if Self_ID.Deferral_Level <= 0 then
+ return False;
+ end if;
+
+ -- Check that no one is holding this lock
+
+ if L.Owner /= null then
+ return False;
+ end if;
+
+ L.Frozen := True;
+ return True;
+ end Check_Finalize_Lock;
+
+ ----------------
+ -- Check_Exit --
+ ----------------
+
+ function Check_Exit (Self_ID : Task_ID) return Boolean is
+ begin
+ -- Check that caller is just holding Global_Task_Lock
+ -- and no other locks
+
+ if Self_ID.Common.LL.Locks = null then
+ return False;
+ end if;
+
+ -- 2 = Global_Task_Level
+
+ if Self_ID.Common.LL.Locks.Level /= 2 then
+ return False;
+ end if;
+
+ if Self_ID.Common.LL.Locks.Next /= null then
+ return False;
+ end if;
+
+ -- Check that caller is abort-deferred
+
+ if Self_ID.Deferral_Level <= 0 then
+ return False;
+ end if;
+
+ return True;
+ end Check_Exit;
+
+ --------------------
+ -- Check_No_Locks --
+ --------------------
+
+ function Check_No_Locks (Self_ID : Task_ID) return Boolean is
+ begin
+ return Self_ID.Common.LL.Locks = null;
+ end Check_No_Locks;
+
+ ----------------------
+ -- Environment_Task --
+ ----------------------
+
+ function Environment_Task return Task_ID is
+ begin
+ return Environment_Task_ID;
+ end Environment_Task;
+
+ --------------
+ -- Lock_RTS --
+ --------------
+
+ procedure Lock_RTS is
+ begin
+ Write_Lock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Lock_RTS;
+
+ ----------------
+ -- Unlock_RTS --
+ ----------------
+
+ procedure Unlock_RTS is
+ begin
+ Unlock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Unlock_RTS;
+
+ ------------------
+ -- Suspend_Task --
+ ------------------
+
+ function Suspend_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id) return Boolean
+ is
+ begin
+ if T.Common.LL.Thread /= Thread_Self then
+ return thr_suspend (T.Common.LL.Thread) = 0;
+ else
+ return True;
+ end if;
+ end Suspend_Task;
+
+ -----------------
+ -- Resume_Task --
+ -----------------
+
+ function Resume_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id) return Boolean
+ is
+ begin
+ if T.Common.LL.Thread /= Thread_Self then
+ return thr_continue (T.Common.LL.Thread) = 0;
+ else
+ return True;
+ end if;
+ end Resume_Task;
+
+-- Package elaboration
+
+begin
+ declare
+ Result : Interfaces.C.int;
+
+ begin
+ -- Mask Environment task for all signals. The original mask of the
+ -- Environment task will be recovered by Interrupt_Server task
+ -- during the elaboration of s-interr.adb.
+
+ System.Interrupt_Management.Operations.Set_Interrupt_Mask
+ (System.Interrupt_Management.Operations.All_Tasks_Mask'Access);
+
+ -- Prepare the set of signals that should unblocked in all tasks
+
+ Result := sigemptyset (Unblocked_Signal_Mask'Access);
+ pragma Assert (Result = 0);
+
+ for J in Interrupt_Management.Interrupt_ID loop
+ if System.Interrupt_Management.Keep_Unmasked (J) then
+ Result := sigaddset (Unblocked_Signal_Mask'Access, Signal (J));
+ pragma Assert (Result = 0);
+ end if;
+ end loop;
+
+ -- We need the following code to support automatic creation of fake
+ -- ATCB's for C threads that call the Ada run-time system, even if
+ -- we use a faster way of getting Self for real Ada tasks.
+
+ Result := thr_keycreate (ATCB_Key'Access, System.Null_Address);
+ pragma Assert (Result = 0);
+ end;
+
+ if Dispatching_Policy = 'F' then
+ declare
+ Result : Interfaces.C.long;
+ Class_Info : aliased struct_pcinfo;
+ Secs, Nsecs : Interfaces.C.long;
+
+ begin
+ -- If a pragma Time_Slice is specified, takes the value in account.
+
+ if Time_Slice_Val > 0 then
+ -- Convert Time_Slice_Val (microseconds) into seconds and
+ -- nanoseconds
+
+ Secs := Time_Slice_Val / 1_000_000;
+ Nsecs := (Time_Slice_Val rem 1_000_000) * 1_000;
+
+ -- Otherwise, default to no time slicing (i.e run until blocked)
+
+ else
+ Secs := RT_TQINF;
+ Nsecs := RT_TQINF;
+ end if;
+
+ -- Get the real time class id.
+
+ Class_Info.pc_clname (1) := 'R';
+ Class_Info.pc_clname (2) := 'T';
+ Class_Info.pc_clname (3) := ASCII.NUL;
+
+ Result := priocntl (PC_VERSION, P_LWPID, P_MYID, PC_GETCID,
+ Class_Info'Address);
+
+ -- Request the real time class
+
+ Prio_Param.pc_cid := Class_Info.pc_cid;
+ Prio_Param.rt_pri := pri_t (Class_Info.rt_maxpri);
+ Prio_Param.rt_tqsecs := Secs;
+ Prio_Param.rt_tqnsecs := Nsecs;
+
+ Result := priocntl (PC_VERSION, P_LWPID, P_MYID, PC_SETPARMS,
+ Prio_Param'Address);
+
+ Using_Real_Time_Class := Result /= -1;
+ end;
+ end if;
+end System.Task_Primitives.Operations;
diff --git a/gcc/ada/s-taprop-tru64.adb b/gcc/ada/s-taprop-tru64.adb
new file mode 100644
index 00000000000..1fa1c22fa4b
--- /dev/null
+++ b/gcc/ada/s-taprop-tru64.adb
@@ -0,0 +1,1136 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S . O P E R A T I O N S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2004, 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- --
+-- 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, 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, --
+-- 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 is a DEC Unix 4.0d version of this package
+
+-- This package contains all the GNULL primitives that interface directly
+-- with the underlying OS.
+
+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.Tasking.Debug;
+-- used for Known_Tasks
+
+with System.Task_Info;
+-- used for Task_Info_Type
+
+with Interfaces;
+-- used for Shift_Left
+
+with Interfaces.C;
+-- used for int
+-- size_t
+
+with System.Interrupt_Management;
+-- used for Keep_Unmasked
+-- Abort_Task_Interrupt
+-- Interrupt_ID
+
+with System.Interrupt_Management.Operations;
+-- used for Set_Interrupt_Mask
+-- All_Tasks_Mask
+pragma Elaborate_All (System.Interrupt_Management.Operations);
+
+with System.Parameters;
+-- used for Size_Type
+
+with System.Tasking;
+-- used for Ada_Task_Control_Block
+-- Task_ID
+-- ATCB components and types
+
+with System.Soft_Links;
+-- used for Defer/Undefer_Abort
+
+-- Note that we do not use System.Tasking.Initialization directly since
+-- this is a higher level package that we shouldn't depend on. For example
+-- when using the restricted run time, it is replaced by
+-- System.Tasking.Restricted.Initialization
+
+with System.OS_Primitives;
+-- used for Delay_Modes
+
+with Unchecked_Deallocation;
+
+package body System.Task_Primitives.Operations is
+
+ use System.Tasking.Debug;
+ use System.Tasking;
+ use Interfaces.C;
+ use System.OS_Interface;
+ use System.Parameters;
+ use System.OS_Primitives;
+
+ package SSL renames System.Soft_Links;
+
+ ----------------
+ -- Local Data --
+ ----------------
+
+ -- The followings are logically constants, but need to be initialized
+ -- at run time.
+
+ Single_RTS_Lock : aliased RTS_Lock;
+ -- This is a lock to allow only one thread of control in the RTS at
+ -- a time; it is used to execute in mutual exclusion from all other tasks.
+ -- Used mainly in Single_Lock mode, but also to protect All_Tasks_List
+
+ ATCB_Key : aliased pthread_key_t;
+ -- Key used to find the Ada Task_ID associated with a thread
+
+ Environment_Task_ID : Task_ID;
+ -- A variable to hold Task_ID for the environment task.
+
+ Unblocked_Signal_Mask : aliased sigset_t;
+ -- The set of signals that should unblocked in all tasks
+
+ Time_Slice_Val : Integer;
+ pragma Import (C, Time_Slice_Val, "__gl_time_slice_val");
+
+ Locking_Policy : Character;
+ pragma Import (C, Locking_Policy, "__gl_locking_policy");
+
+ Dispatching_Policy : Character;
+ pragma Import (C, Dispatching_Policy, "__gl_task_dispatching_policy");
+
+ FIFO_Within_Priorities : constant Boolean := Dispatching_Policy = 'F';
+ -- Indicates whether FIFO_Within_Priorities is set.
+
+ Curpid : pid_t;
+
+ Foreign_Task_Elaborated : aliased Boolean := True;
+ -- Used to identified fake tasks (i.e., non-Ada Threads).
+
+ --------------------
+ -- Local Packages --
+ --------------------
+
+ package Specific is
+
+ procedure Initialize (Environment_Task : Task_ID);
+ pragma Inline (Initialize);
+ -- Initialize various data needed by this package.
+
+ function Is_Valid_Task return Boolean;
+ pragma Inline (Is_Valid_Task);
+ -- Does executing thread have a TCB?
+
+ procedure Set (Self_Id : Task_ID);
+ pragma Inline (Set);
+ -- Set the self id for the current task.
+
+ function Self return Task_ID;
+ pragma Inline (Self);
+ -- Return a pointer to the Ada Task Control Block of the calling task.
+
+ end Specific;
+
+ package body Specific is separate;
+ -- The body of this package is target specific.
+
+ ---------------------------------
+ -- Support for foreign threads --
+ ---------------------------------
+
+ function Register_Foreign_Thread (Thread : Thread_Id) return Task_ID;
+ -- Allocate and Initialize a new ATCB for the current Thread.
+
+ function Register_Foreign_Thread
+ (Thread : Thread_Id) return Task_ID is separate;
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ procedure Abort_Handler (Sig : Signal);
+ -- Signal handler used to implement asynchronous abortion.
+
+ -------------------
+ -- Abort_Handler --
+ -------------------
+
+ procedure Abort_Handler (Sig : Signal) is
+ pragma Unreferenced (Sig);
+
+ T : constant Task_ID := Self;
+ Result : Interfaces.C.int;
+ Old_Set : aliased sigset_t;
+
+ begin
+ -- It is not safe to raise an exception when using ZCX and the GCC
+ -- exception handling mechanism.
+
+ if ZCX_By_Default and then GCC_ZCX_Support then
+ return;
+ end if;
+
+ if T.Deferral_Level = 0
+ and then T.Pending_ATC_Level < T.ATC_Nesting_Level and then
+ not T.Aborting
+ then
+ T.Aborting := True;
+
+ -- Make sure signals used for RTS internal purpose are unmasked
+
+ Result := pthread_sigmask (SIG_UNBLOCK,
+ Unblocked_Signal_Mask'Unchecked_Access, Old_Set'Unchecked_Access);
+ pragma Assert (Result = 0);
+
+ raise Standard'Abort_Signal;
+ end if;
+ end Abort_Handler;
+
+ ------------------
+ -- Stack_Guard --
+ ------------------
+
+ -- The underlying thread system sets a guard page at the
+ -- bottom of a thread stack, so nothing is needed.
+
+ procedure Stack_Guard (T : ST.Task_ID; On : Boolean) is
+ pragma Unreferenced (T);
+ pragma Unreferenced (On);
+
+ begin
+ null;
+ end Stack_Guard;
+
+ --------------------
+ -- Get_Thread_Id --
+ --------------------
+
+ function Get_Thread_Id (T : ST.Task_ID) return OSI.Thread_Id is
+ begin
+ return T.Common.LL.Thread;
+ end Get_Thread_Id;
+
+ ----------
+ -- Self --
+ ----------
+
+ function Self return Task_ID renames Specific.Self;
+
+ ---------------------
+ -- Initialize_Lock --
+ ---------------------
+
+ -- Note: mutexes and cond_variables needed per-task basis are
+ -- initialized in Initialize_TCB and the Storage_Error is
+ -- handled. Other mutexes (such as RTS_Lock, Memory_Lock...)
+ -- used in RTS is initialized before any status change of RTS.
+ -- Therefore rasing Storage_Error in the following routines
+ -- should be able to be handled safely.
+
+ procedure Initialize_Lock
+ (Prio : System.Any_Priority;
+ L : access Lock)
+ is
+ Attributes : aliased pthread_mutexattr_t;
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_mutexattr_init (Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ raise Storage_Error;
+ end if;
+
+ if Locking_Policy = 'C' then
+ L.Ceiling := Interfaces.C.int (Prio);
+ end if;
+
+ Result := pthread_mutex_init (L.L'Access, Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ Result := pthread_mutexattr_destroy (Attributes'Access);
+ raise Storage_Error;
+ end if;
+
+ Result := pthread_mutexattr_destroy (Attributes'Access);
+ pragma Assert (Result = 0);
+ end Initialize_Lock;
+
+ procedure Initialize_Lock (L : access RTS_Lock; Level : Lock_Level) is
+ pragma Unreferenced (Level);
+
+ Attributes : aliased pthread_mutexattr_t;
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_mutexattr_init (Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ raise Storage_Error;
+ end if;
+
+ Result := pthread_mutex_init (L, Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ Result := pthread_mutexattr_destroy (Attributes'Access);
+ raise Storage_Error;
+ end if;
+
+ Result := pthread_mutexattr_destroy (Attributes'Access);
+ pragma Assert (Result = 0);
+ end Initialize_Lock;
+
+ -------------------
+ -- Finalize_Lock --
+ -------------------
+
+ procedure Finalize_Lock (L : access Lock) is
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_mutex_destroy (L.L'Access);
+ pragma Assert (Result = 0);
+ end Finalize_Lock;
+
+ procedure Finalize_Lock (L : access RTS_Lock) is
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_mutex_destroy (L);
+ pragma Assert (Result = 0);
+ end Finalize_Lock;
+
+ ----------------
+ -- Write_Lock --
+ ----------------
+
+ procedure Write_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ Result : Interfaces.C.int;
+ Self_ID : Task_ID;
+ All_Tasks_Link : Task_ID;
+ Current_Prio : System.Any_Priority;
+
+ begin
+ -- Perform ceiling checks only when this is the locking policy in use.
+
+ if Locking_Policy = 'C' then
+ Self_ID := Self;
+ All_Tasks_Link := Self_ID.Common.All_Tasks_Link;
+ Current_Prio := Get_Priority (Self_ID);
+
+ -- If there is no other task, no need to check priorities
+
+ if All_Tasks_Link /= Null_Task
+ and then L.Ceiling < Interfaces.C.int (Current_Prio)
+ then
+ Ceiling_Violation := True;
+ return;
+ end if;
+ end if;
+
+ Result := pthread_mutex_lock (L.L'Access);
+ pragma Assert (Result = 0);
+
+ Ceiling_Violation := False;
+ end Write_Lock;
+
+ procedure Write_Lock
+ (L : access RTS_Lock; Global_Lock : Boolean := False)
+ is
+ Result : Interfaces.C.int;
+ begin
+ if not Single_Lock or else Global_Lock then
+ Result := pthread_mutex_lock (L);
+ pragma Assert (Result = 0);
+ end if;
+ end Write_Lock;
+
+ procedure Write_Lock (T : Task_ID) is
+ Result : Interfaces.C.int;
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_lock (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Write_Lock;
+
+ ---------------
+ -- Read_Lock --
+ ---------------
+
+ procedure Read_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ begin
+ Write_Lock (L, Ceiling_Violation);
+ end Read_Lock;
+
+ ------------
+ -- Unlock --
+ ------------
+
+ procedure Unlock (L : access Lock) is
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_mutex_unlock (L.L'Access);
+ pragma Assert (Result = 0);
+ end Unlock;
+
+ procedure Unlock (L : access RTS_Lock; Global_Lock : Boolean := False) is
+ Result : Interfaces.C.int;
+ begin
+ if not Single_Lock or else Global_Lock then
+ Result := pthread_mutex_unlock (L);
+ pragma Assert (Result = 0);
+ end if;
+ end Unlock;
+
+ procedure Unlock (T : Task_ID) is
+ Result : Interfaces.C.int;
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_unlock (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Unlock;
+
+ -----------
+ -- Sleep --
+ -----------
+
+ procedure Sleep
+ (Self_ID : Task_ID;
+ Reason : System.Tasking.Task_States)
+ 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;
+
+ -- EINTR is not considered a failure.
+
+ pragma Assert (Result = 0 or else Result = EINTR);
+ end Sleep;
+
+ -----------------
+ -- Timed_Sleep --
+ -----------------
+
+ -- This is for use within the run-time system, so abort is
+ -- assumed to be already deferred, and the caller should be
+ -- holding its own ATCB lock.
+
+ procedure Timed_Sleep
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes;
+ Reason : System.Tasking.Task_States;
+ Timedout : out Boolean;
+ Yielded : out Boolean)
+ is
+ pragma Unreferenced (Reason);
+
+ Check_Time : constant Duration := Monotonic_Clock;
+ Abs_Time : Duration;
+ Request : aliased timespec;
+ Result : Interfaces.C.int;
+
+ begin
+ 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;
+
+ if Abs_Time > Check_Time then
+ Request := To_Timespec (Abs_Time);
+
+ loop
+ exit when Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level
+ or else Self_ID.Pending_Priority_Change;
+
+ 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;
+
+ exit when Abs_Time <= Monotonic_Clock;
+
+ if Result = 0 or Result = EINTR then
+
+ -- Somebody may have called Wakeup for us
+
+ Timedout := False;
+ exit;
+ end if;
+
+ pragma Assert (Result = ETIMEDOUT);
+ end loop;
+ end if;
+ end Timed_Sleep;
+
+ -----------------
+ -- Timed_Delay --
+ -----------------
+
+ -- This is for use in implementing delay statements, so
+ -- we assume the caller is abort-deferred but is holding
+ -- no locks.
+
+ procedure Timed_Delay
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes)
+ is
+ Check_Time : constant Duration := Monotonic_Clock;
+ Abs_Time : Duration;
+ Request : aliased timespec;
+ Result : Interfaces.C.int;
+
+ begin
+ -- Only the little window between deferring abort and
+ -- locking Self_ID is the reason we need to
+ -- check for pending abort and priority change below! :(
+
+ SSL.Abort_Defer.all;
+
+ if Single_Lock then
+ Lock_RTS;
+ end if;
+
+ 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;
+
+ if Abs_Time > Check_Time then
+ Request := To_Timespec (Abs_Time);
+ Self_ID.Common.State := Delay_Sleep;
+
+ loop
+ if Self_ID.Pending_Priority_Change then
+ Self_ID.Pending_Priority_Change := False;
+ Self_ID.Common.Base_Priority := Self_ID.New_Base_Priority;
+ Set_Priority (Self_ID, Self_ID.Common.Base_Priority);
+ end if;
+
+ 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;
+
+ exit when Abs_Time <= Monotonic_Clock;
+
+ pragma Assert (Result = 0 or else
+ Result = ETIMEDOUT or else
+ Result = EINTR);
+ end loop;
+
+ Self_ID.Common.State := Runnable;
+ end if;
+
+ Unlock (Self_ID);
+
+ if Single_Lock then
+ Unlock_RTS;
+ end if;
+
+ Yield;
+ SSL.Abort_Undefer.all;
+ end Timed_Delay;
+
+ ---------------------
+ -- Monotonic_Clock --
+ ---------------------
+
+ function Monotonic_Clock return Duration is
+ TS : aliased timespec;
+ Result : Interfaces.C.int;
+
+ begin
+ Result := clock_gettime (CLOCK_REALTIME, TS'Unchecked_Access);
+ pragma Assert (Result = 0);
+ return To_Duration (TS);
+ end Monotonic_Clock;
+
+ -------------------
+ -- RT_Resolution --
+ -------------------
+
+ function RT_Resolution return Duration is
+ begin
+ return 1.0 / 1024.0; -- Clock on DEC Alpha ticks at 1024 Hz
+ end RT_Resolution;
+
+ ------------
+ -- Wakeup --
+ ------------
+
+ procedure Wakeup (T : Task_ID; Reason : System.Tasking.Task_States) is
+ pragma Unreferenced (Reason);
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_cond_signal (T.Common.LL.CV'Access);
+ pragma Assert (Result = 0);
+ end Wakeup;
+
+ -----------
+ -- Yield --
+ -----------
+
+ procedure Yield (Do_Yield : Boolean := True) is
+ Result : Interfaces.C.int;
+ pragma Unreferenced (Result);
+ begin
+ if Do_Yield then
+ Result := sched_yield;
+ end if;
+ end Yield;
+
+ ------------------
+ -- Set_Priority --
+ ------------------
+
+ procedure Set_Priority
+ (T : Task_ID;
+ Prio : System.Any_Priority;
+ Loss_Of_Inheritance : Boolean := False)
+ is
+ pragma Unreferenced (Loss_Of_Inheritance);
+
+ Result : Interfaces.C.int;
+ Param : aliased struct_sched_param;
+
+ begin
+ T.Common.Current_Priority := Prio;
+ Param.sched_priority := Interfaces.C.int (Underlying_Priorities (Prio));
+
+ if Time_Slice_Val > 0 then
+ Result := pthread_setschedparam
+ (T.Common.LL.Thread, SCHED_RR, Param'Access);
+
+ elsif FIFO_Within_Priorities or else Time_Slice_Val = 0 then
+ Result := pthread_setschedparam
+ (T.Common.LL.Thread, SCHED_FIFO, Param'Access);
+
+ else
+ Result := pthread_setschedparam
+ (T.Common.LL.Thread, SCHED_OTHER, Param'Access);
+ end if;
+
+ pragma Assert (Result = 0);
+ end Set_Priority;
+
+ ------------------
+ -- Get_Priority --
+ ------------------
+
+ function Get_Priority (T : Task_ID) return System.Any_Priority is
+ begin
+ return T.Common.Current_Priority;
+ end Get_Priority;
+
+ ----------------
+ -- Enter_Task --
+ ----------------
+
+ procedure Enter_Task (Self_ID : Task_ID) is
+ begin
+ Self_ID.Common.LL.Thread := pthread_self;
+ Specific.Set (Self_ID);
+
+ Lock_RTS;
+
+ for J in Known_Tasks'Range loop
+ if Known_Tasks (J) = null then
+ Known_Tasks (J) := Self_ID;
+ Self_ID.Known_Tasks_Index := J;
+ exit;
+ end if;
+ end loop;
+
+ Unlock_RTS;
+ end Enter_Task;
+
+ --------------
+ -- New_ATCB --
+ --------------
+
+ function New_ATCB (Entry_Num : Task_Entry_Index) return Task_ID is
+ begin
+ return new Ada_Task_Control_Block (Entry_Num);
+ end New_ATCB;
+
+ -------------------
+ -- Is_Valid_Task --
+ -------------------
+
+ function Is_Valid_Task return Boolean renames Specific.Is_Valid_Task;
+
+ -----------------------------
+ -- Register_Foreign_Thread --
+ -----------------------------
+
+ function Register_Foreign_Thread return Task_ID is
+ begin
+ if Is_Valid_Task then
+ return Self;
+ else
+ return Register_Foreign_Thread (pthread_self);
+ end if;
+ end Register_Foreign_Thread;
+
+ --------------------
+ -- Initialize_TCB --
+ --------------------
+
+ procedure Initialize_TCB (Self_ID : Task_ID; Succeeded : out Boolean) is
+ Mutex_Attr : aliased pthread_mutexattr_t;
+ Result : Interfaces.C.int;
+ Cond_Attr : aliased pthread_condattr_t;
+
+ begin
+ if not Single_Lock then
+ Result := pthread_mutexattr_init (Mutex_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = 0 then
+ Result := pthread_mutex_init
+ (Self_ID.Common.LL.L'Access, Mutex_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+ end if;
+
+ if Result /= 0 then
+ Succeeded := False;
+ return;
+ end if;
+
+ Result := pthread_mutexattr_destroy (Mutex_Attr'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Result := pthread_condattr_init (Cond_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = 0 then
+ Result := pthread_cond_init
+ (Self_ID.Common.LL.CV'Access, Cond_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+ end if;
+
+ if Result = 0 then
+ Succeeded := True;
+ else
+ if not Single_Lock then
+ Result := pthread_mutex_destroy (Self_ID.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Succeeded := False;
+ end if;
+
+ Result := pthread_condattr_destroy (Cond_Attr'Access);
+ pragma Assert (Result = 0);
+ end Initialize_TCB;
+
+ -----------------
+ -- Create_Task --
+ -----------------
+
+ procedure Create_Task
+ (T : Task_ID;
+ Wrapper : System.Address;
+ Stack_Size : System.Parameters.Size_Type;
+ Priority : System.Any_Priority;
+ Succeeded : out Boolean)
+ is
+ Attributes : aliased pthread_attr_t;
+ Adjusted_Stack_Size : Interfaces.C.size_t;
+ Result : Interfaces.C.int;
+ Param : aliased System.OS_Interface.struct_sched_param;
+
+ use System.Task_Info;
+
+ begin
+ if Stack_Size = Unspecified_Size then
+ Adjusted_Stack_Size := Interfaces.C.size_t (Default_Stack_Size);
+
+ elsif Stack_Size < Minimum_Stack_Size then
+ Adjusted_Stack_Size := Interfaces.C.size_t (Minimum_Stack_Size);
+
+ else
+ Adjusted_Stack_Size := Interfaces.C.size_t (Stack_Size);
+ end if;
+
+ Result := pthread_attr_init (Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result /= 0 then
+ Succeeded := False;
+ return;
+ end if;
+
+ Result := pthread_attr_setdetachstate
+ (Attributes'Access, PTHREAD_CREATE_DETACHED);
+ pragma Assert (Result = 0);
+
+ Result := pthread_attr_setstacksize
+ (Attributes'Access, Adjusted_Stack_Size);
+ pragma Assert (Result = 0);
+
+ Param.sched_priority :=
+ Interfaces.C.int (Underlying_Priorities (Priority));
+ Result := pthread_attr_setschedparam
+ (Attributes'Access, Param'Access);
+ pragma Assert (Result = 0);
+
+ if Time_Slice_Val > 0 then
+ Result := pthread_attr_setschedpolicy
+ (Attributes'Access, System.OS_Interface.SCHED_RR);
+
+ elsif FIFO_Within_Priorities or else Time_Slice_Val = 0 then
+ Result := pthread_attr_setschedpolicy
+ (Attributes'Access, System.OS_Interface.SCHED_FIFO);
+
+ else
+ Result := pthread_attr_setschedpolicy
+ (Attributes'Access, System.OS_Interface.SCHED_OTHER);
+ end if;
+
+ pragma Assert (Result = 0);
+
+ -- Set the scheduling parameters explicitly, since this is the
+ -- only way to force the OS to take e.g. the sched policy and scope
+ -- attributes into account.
+
+ Result := pthread_attr_setinheritsched
+ (Attributes'Access, PTHREAD_EXPLICIT_SCHED);
+ pragma Assert (Result = 0);
+
+ T.Common.Current_Priority := Priority;
+
+ if T.Common.Task_Info /= null then
+ case T.Common.Task_Info.Contention_Scope is
+ when System.Task_Info.Process_Scope =>
+ Result := pthread_attr_setscope
+ (Attributes'Access, PTHREAD_SCOPE_PROCESS);
+
+ when System.Task_Info.System_Scope =>
+ Result := pthread_attr_setscope
+ (Attributes'Access, PTHREAD_SCOPE_SYSTEM);
+
+ when System.Task_Info.Default_Scope =>
+ Result := 0;
+ end case;
+
+ pragma Assert (Result = 0);
+ end if;
+
+ -- Since the initial signal mask of a thread is inherited from the
+ -- creator, and the Environment task has all its signals masked, we
+ -- do not need to manipulate caller's signal mask at this point.
+ -- All tasks in RTS will have All_Tasks_Mask initially.
+
+ Result := pthread_create
+ (T.Common.LL.Thread'Access,
+ Attributes'Access,
+ Thread_Body_Access (Wrapper),
+ To_Address (T));
+ pragma Assert (Result = 0 or else Result = EAGAIN);
+
+ Succeeded := Result = 0;
+
+ Result := pthread_attr_destroy (Attributes'Access);
+ pragma Assert (Result = 0);
+
+ if T.Common.Task_Info /= null then
+ -- ??? We're using a process-wide function to implement a task
+ -- specific characteristic.
+
+ if T.Common.Task_Info.Bind_To_Cpu_Number = 0 then
+ Result := bind_to_cpu (Curpid, 0);
+ elsif T.Common.Task_Info.Bind_To_Cpu_Number > 0 then
+ Result := bind_to_cpu
+ (Curpid,
+ Interfaces.C.unsigned_long (
+ Interfaces.Shift_Left
+ (Interfaces.Unsigned_64'(1),
+ T.Common.Task_Info.Bind_To_Cpu_Number - 1)));
+ pragma Assert (Result = 0);
+ end if;
+ end if;
+ end Create_Task;
+
+ ------------------
+ -- Finalize_TCB --
+ ------------------
+
+ procedure Finalize_TCB (T : Task_ID) is
+ Result : Interfaces.C.int;
+ Tmp : Task_ID := T;
+ Is_Self : constant Boolean := T = Self;
+
+ procedure Free is new
+ Unchecked_Deallocation (Ada_Task_Control_Block, Task_ID);
+
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_destroy (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Result := pthread_cond_destroy (T.Common.LL.CV'Access);
+ pragma Assert (Result = 0);
+
+ if T.Known_Tasks_Index /= -1 then
+ Known_Tasks (T.Known_Tasks_Index) := null;
+ end if;
+
+ Free (Tmp);
+
+ if Is_Self then
+ Specific.Set (null);
+ end if;
+ end Finalize_TCB;
+
+ ---------------
+ -- Exit_Task --
+ ---------------
+
+ procedure Exit_Task is
+ begin
+ Specific.Set (null);
+ end Exit_Task;
+
+ ----------------
+ -- Abort_Task --
+ ----------------
+
+ procedure Abort_Task (T : Task_ID) is
+ Result : Interfaces.C.int;
+ begin
+ Result :=
+ pthread_kill
+ (T.Common.LL.Thread,
+ Signal (System.Interrupt_Management.Abort_Task_Interrupt));
+ pragma Assert (Result = 0);
+ end Abort_Task;
+
+ ----------------
+ -- Check_Exit --
+ ----------------
+
+ -- Dummy version
+
+ function Check_Exit (Self_ID : ST.Task_ID) return Boolean is
+ pragma Unreferenced (Self_ID);
+
+ begin
+ return True;
+ end Check_Exit;
+
+ --------------------
+ -- Check_No_Locks --
+ --------------------
+
+ function Check_No_Locks (Self_ID : ST.Task_ID) return Boolean is
+ pragma Unreferenced (Self_ID);
+
+ begin
+ return True;
+ end Check_No_Locks;
+
+ ----------------------
+ -- Environment_Task --
+ ----------------------
+
+ function Environment_Task return Task_ID is
+ begin
+ return Environment_Task_ID;
+ end Environment_Task;
+
+ --------------
+ -- Lock_RTS --
+ --------------
+
+ procedure Lock_RTS is
+ begin
+ Write_Lock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Lock_RTS;
+
+ ----------------
+ -- Unlock_RTS --
+ ----------------
+
+ procedure Unlock_RTS is
+ begin
+ Unlock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Unlock_RTS;
+
+ ------------------
+ -- Suspend_Task --
+ ------------------
+
+ function Suspend_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id) return Boolean
+ is
+ pragma Warnings (Off, T);
+ pragma Warnings (Off, Thread_Self);
+
+ begin
+ return False;
+ end Suspend_Task;
+
+ -----------------
+ -- Resume_Task --
+ -----------------
+
+ function Resume_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id) return Boolean
+ is
+ pragma Warnings (Off, T);
+ pragma Warnings (Off, Thread_Self);
+
+ begin
+ return False;
+ end Resume_Task;
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize (Environment_Task : Task_ID) is
+ act : aliased struct_sigaction;
+ old_act : aliased struct_sigaction;
+ Tmp_Set : aliased sigset_t;
+ Result : Interfaces.C.int;
+
+ 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:
+
+ Default : constant Character := 's';
+ -- 'n' this interrupt not set by any Interrupt_State pragma
+ -- 'u' Interrupt_State pragma set state to User
+ -- 'r' Interrupt_State pragma set state to Runtime
+ -- 's' Interrupt_State pragma set state to System (use "default"
+ -- system handler)
+
+ begin
+ Environment_Task_ID := Environment_Task;
+
+ -- Initialize the lock used to synchronize chain of all ATCBs.
+
+ Initialize_Lock (Single_RTS_Lock'Access, RTS_Lock_Level);
+
+ Specific.Initialize (Environment_Task);
+
+ Enter_Task (Environment_Task);
+
+ -- Install the abort-signal handler
+
+ if State (System.Interrupt_Management.Abort_Task_Interrupt)
+ /= Default
+ then
+ act.sa_flags := 0;
+ act.sa_handler := Abort_Handler'Address;
+
+ Result := sigemptyset (Tmp_Set'Access);
+ pragma Assert (Result = 0);
+ act.sa_mask := Tmp_Set;
+
+ Result :=
+ sigaction
+ (Signal (System.Interrupt_Management.Abort_Task_Interrupt),
+ act'Unchecked_Access,
+ old_act'Unchecked_Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Initialize;
+
+begin
+ declare
+ Result : Interfaces.C.int;
+
+ begin
+ -- Mask Environment task for all signals. The original mask of the
+ -- Environment task will be recovered by Interrupt_Server task
+ -- during the elaboration of s-interr.adb.
+
+ System.Interrupt_Management.Operations.Set_Interrupt_Mask
+ (System.Interrupt_Management.Operations.All_Tasks_Mask'Access);
+
+ -- Prepare the set of signals that should unblocked in all tasks
+
+ Result := sigemptyset (Unblocked_Signal_Mask'Access);
+ pragma Assert (Result = 0);
+
+ for J in Interrupt_Management.Interrupt_ID loop
+ if System.Interrupt_Management.Keep_Unmasked (J) then
+ Result := sigaddset (Unblocked_Signal_Mask'Access, Signal (J));
+ pragma Assert (Result = 0);
+ end if;
+ end loop;
+ end;
+
+ Curpid := getpid;
+end System.Task_Primitives.Operations;
diff --git a/gcc/ada/s-taprop-vms.adb b/gcc/ada/s-taprop-vms.adb
new file mode 100644
index 00000000000..5a7739d3abc
--- /dev/null
+++ b/gcc/ada/s-taprop-vms.adb
@@ -0,0 +1,1005 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S . O P E R A T I O N S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2004, 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- --
+-- 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, 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, --
+-- 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 is a OpenVMS/Alpha version of this package
+
+-- This package contains all the GNULL primitives that interface directly
+-- with the underlying OS.
+
+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.Tasking.Debug;
+-- used for Known_Tasks
+
+with Interfaces.C;
+-- used for int
+-- size_t
+
+with System.Parameters;
+-- used for Size_Type
+
+with System.Tasking;
+-- used for Ada_Task_Control_Block
+-- Task_ID
+
+with System.Soft_Links;
+-- used for Defer/Undefer_Abort
+-- Set_Exc_Stack_Addr
+
+-- Note that we do not use System.Tasking.Initialization directly since
+-- this is a higher level package that we shouldn't depend on. For example
+-- when using the restricted run time, it is replaced by
+-- System.Tasking.Restricted.Initialization
+
+with System.OS_Primitives;
+-- used for Delay_Modes
+
+with Unchecked_Conversion;
+with Unchecked_Deallocation;
+
+package body System.Task_Primitives.Operations is
+
+ use System.Tasking.Debug;
+ use System.Tasking;
+ use Interfaces.C;
+ use System.OS_Interface;
+ use System.Parameters;
+ use System.OS_Primitives;
+ use type System.OS_Primitives.OS_Time;
+
+ package SSL renames System.Soft_Links;
+
+ ------------------
+ -- Local Data --
+ ------------------
+
+ -- The followings are logically constants, but need to be initialized
+ -- at run time.
+
+ Single_RTS_Lock : aliased RTS_Lock;
+ -- This is a lock to allow only one thread of control in the RTS at
+ -- a time; it is used to execute in mutual exclusion from all other tasks.
+ -- Used mainly in Single_Lock mode, but also to protect All_Tasks_List
+
+ ATCB_Key : aliased pthread_key_t;
+ -- Key used to find the Ada Task_ID associated with a thread
+
+ Environment_Task_ID : Task_ID;
+ -- A variable to hold Task_ID for the environment task.
+
+ Time_Slice_Val : Integer;
+ pragma Import (C, Time_Slice_Val, "__gl_time_slice_val");
+
+ Dispatching_Policy : Character;
+ pragma Import (C, Dispatching_Policy, "__gl_task_dispatching_policy");
+
+ FIFO_Within_Priorities : constant Boolean := Dispatching_Policy = 'F';
+ -- Indicates whether FIFO_Within_Priorities is set.
+
+ Foreign_Task_Elaborated : aliased Boolean := True;
+ -- Used to identified fake tasks (i.e., non-Ada Threads).
+
+ --------------------
+ -- Local Packages --
+ --------------------
+
+ package Specific is
+
+ procedure Initialize (Environment_Task : Task_ID);
+ pragma Inline (Initialize);
+ -- Initialize various data needed by this package.
+
+ function Is_Valid_Task return Boolean;
+ pragma Inline (Is_Valid_Task);
+ -- Does executing thread have a TCB?
+
+ procedure Set (Self_Id : Task_ID);
+ pragma Inline (Set);
+ -- Set the self id for the current task
+
+ function Self return Task_ID;
+ pragma Inline (Self);
+ -- Return a pointer to the Ada Task Control Block of the calling task
+
+ end Specific;
+
+ package body Specific is separate;
+ -- The body of this package is target specific.
+
+ ---------------------------------
+ -- Support for foreign threads --
+ ---------------------------------
+
+ function Register_Foreign_Thread (Thread : Thread_Id) return Task_ID;
+ -- Allocate and Initialize a new ATCB for the current Thread
+
+ function Register_Foreign_Thread
+ (Thread : Thread_Id) return Task_ID is separate;
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ function To_Task_ID is new Unchecked_Conversion (System.Address, Task_ID);
+
+ function To_Address is new Unchecked_Conversion (Task_ID, System.Address);
+
+ procedure Timer_Sleep_AST (ID : Address);
+ -- Signal the condition variable when AST fires.
+
+ procedure Timer_Sleep_AST (ID : Address) is
+ Result : Interfaces.C.int;
+ Self_ID : constant Task_ID := To_Task_ID (ID);
+ begin
+ Self_ID.Common.LL.AST_Pending := False;
+ Result := pthread_cond_signal_int_np (Self_ID.Common.LL.CV'Access);
+ pragma Assert (Result = 0);
+ end Timer_Sleep_AST;
+
+ -----------------
+ -- Stack_Guard --
+ -----------------
+
+ -- The underlying thread system sets a guard page at the
+ -- bottom of a thread stack, so nothing is needed.
+ -- ??? Check the comment above
+
+ procedure Stack_Guard (T : ST.Task_ID; On : Boolean) is
+ pragma Unreferenced (T);
+ pragma Unreferenced (On);
+ begin
+ null;
+ end Stack_Guard;
+
+ --------------------
+ -- Get_Thread_Id --
+ --------------------
+
+ function Get_Thread_Id (T : ST.Task_ID) return OSI.Thread_Id is
+ begin
+ return T.Common.LL.Thread;
+ end Get_Thread_Id;
+
+ ----------
+ -- Self --
+ ----------
+
+ function Self return Task_ID renames Specific.Self;
+
+ ---------------------
+ -- Initialize_Lock --
+ ---------------------
+
+ -- Note: mutexes and cond_variables needed per-task basis are
+ -- initialized in Initialize_TCB and the Storage_Error is
+ -- handled. Other mutexes (such as RTS_Lock, Memory_Lock...)
+ -- used in RTS is initialized before any status change of RTS.
+ -- Therefore rasing Storage_Error in the following routines
+ -- should be able to be handled safely.
+
+ procedure Initialize_Lock (Prio : System.Any_Priority; L : access Lock) is
+ Attributes : aliased pthread_mutexattr_t;
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_mutexattr_init (Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ raise Storage_Error;
+ end if;
+
+ L.Prio_Save := 0;
+ L.Prio := Interfaces.C.int (Prio);
+
+ Result := pthread_mutex_init (L.L'Access, Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ raise Storage_Error;
+ end if;
+
+ Result := pthread_mutexattr_destroy (Attributes'Access);
+ pragma Assert (Result = 0);
+ end Initialize_Lock;
+
+ procedure Initialize_Lock (L : access RTS_Lock; Level : Lock_Level) is
+ pragma Unreferenced (Level);
+
+ Attributes : aliased pthread_mutexattr_t;
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_mutexattr_init (Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ raise Storage_Error;
+ end if;
+
+-- Don't use, see comment in s-osinte.ads about ERRORCHECK mutexes???
+-- Result := pthread_mutexattr_settype_np
+-- (Attributes'Access, PTHREAD_MUTEX_ERRORCHECK_NP);
+-- pragma Assert (Result = 0);
+
+-- Result := pthread_mutexattr_setprotocol
+-- (Attributes'Access, PTHREAD_PRIO_PROTECT);
+-- pragma Assert (Result = 0);
+
+-- Result := pthread_mutexattr_setprioceiling
+-- (Attributes'Access, Interfaces.C.int (System.Any_Priority'Last));
+-- pragma Assert (Result = 0);
+
+ Result := pthread_mutex_init (L, Attributes'Access);
+
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = ENOMEM then
+ raise Storage_Error;
+ end if;
+
+ Result := pthread_mutexattr_destroy (Attributes'Access);
+ pragma Assert (Result = 0);
+ end Initialize_Lock;
+
+ -------------------
+ -- Finalize_Lock --
+ -------------------
+
+ procedure Finalize_Lock (L : access Lock) is
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_mutex_destroy (L.L'Access);
+ pragma Assert (Result = 0);
+ end Finalize_Lock;
+
+ procedure Finalize_Lock (L : access RTS_Lock) is
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_mutex_destroy (L);
+ pragma Assert (Result = 0);
+ end Finalize_Lock;
+
+ ----------------
+ -- Write_Lock --
+ ----------------
+
+ procedure Write_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ Self_ID : constant Task_ID := Self;
+ All_Tasks_Link : constant Task_ID := Self.Common.All_Tasks_Link;
+ Current_Prio : System.Any_Priority;
+ Result : Interfaces.C.int;
+
+ begin
+ Current_Prio := Get_Priority (Self_ID);
+
+ -- If there is no other tasks, no need to check priorities
+
+ if All_Tasks_Link /= Null_Task
+ and then L.Prio < Interfaces.C.int (Current_Prio)
+ then
+ Ceiling_Violation := True;
+ return;
+ end if;
+
+ Result := pthread_mutex_lock (L.L'Access);
+ pragma Assert (Result = 0);
+
+ Ceiling_Violation := False;
+-- Why is this commented out ???
+-- L.Prio_Save := Interfaces.C.int (Current_Prio);
+-- Set_Priority (Self_ID, System.Any_Priority (L.Prio));
+ end Write_Lock;
+
+ procedure Write_Lock
+ (L : access RTS_Lock;
+ Global_Lock : Boolean := False)
+ is
+ Result : Interfaces.C.int;
+ begin
+ if not Single_Lock or else Global_Lock then
+ Result := pthread_mutex_lock (L);
+ pragma Assert (Result = 0);
+ end if;
+ end Write_Lock;
+
+ procedure Write_Lock (T : Task_ID) is
+ Result : Interfaces.C.int;
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_lock (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Write_Lock;
+
+ ---------------
+ -- Read_Lock --
+ ---------------
+
+ procedure Read_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ begin
+ Write_Lock (L, Ceiling_Violation);
+ end Read_Lock;
+
+ ------------
+ -- Unlock --
+ ------------
+
+ procedure Unlock (L : access Lock) is
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_mutex_unlock (L.L'Access);
+ pragma Assert (Result = 0);
+ end Unlock;
+
+ procedure Unlock (L : access RTS_Lock; Global_Lock : Boolean := False) is
+ Result : Interfaces.C.int;
+ begin
+ if not Single_Lock or else Global_Lock then
+ Result := pthread_mutex_unlock (L);
+ pragma Assert (Result = 0);
+ end if;
+ end Unlock;
+
+ procedure Unlock (T : Task_ID) is
+ Result : Interfaces.C.int;
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_unlock (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+ end Unlock;
+
+ -----------
+ -- Sleep --
+ -----------
+
+ procedure Sleep
+ (Self_ID : Task_ID;
+ Reason : System.Tasking.Task_States)
+ 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;
+
+ -- EINTR is not considered a failure
+
+ pragma Assert (Result = 0 or else Result = EINTR);
+
+ if Self_ID.Deferral_Level = 0
+ and then Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level
+ then
+ Unlock (Self_ID);
+ raise Standard'Abort_Signal;
+ end if;
+ end Sleep;
+
+ -----------------
+ -- Timed_Sleep --
+ -----------------
+
+ procedure Timed_Sleep
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes;
+ Reason : System.Tasking.Task_States;
+ Timedout : out Boolean;
+ Yielded : out Boolean)
+ is
+ pragma Unreferenced (Reason);
+
+ Sleep_Time : OS_Time;
+ Result : Interfaces.C.int;
+ Status : Cond_Value_Type;
+
+ -- The body below requires more comments ???
+
+ begin
+ Timedout := False;
+ Yielded := False;
+
+ Sleep_Time := To_OS_Time (Time, Mode);
+
+ if Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level
+ or else Self_ID.Pending_Priority_Change
+ then
+ return;
+ end if;
+
+ Self_ID.Common.LL.AST_Pending := True;
+
+ Sys_Setimr
+ (Status, 0, Sleep_Time,
+ Timer_Sleep_AST'Access, To_Address (Self_ID), 0);
+
+ if (Status and 1) /= 1 then
+ raise Storage_Error;
+ 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;
+
+ Yielded := True;
+
+ if not Self_ID.Common.LL.AST_Pending then
+ Timedout := True;
+ else
+ Sys_Cantim (Status, To_Address (Self_ID), 0);
+ pragma Assert ((Status and 1) = 1);
+ end if;
+ end Timed_Sleep;
+
+ -----------------
+ -- Timed_Delay --
+ -----------------
+
+ procedure Timed_Delay
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes)
+ is
+ Sleep_Time : OS_Time;
+ Result : Interfaces.C.int;
+ Status : Cond_Value_Type;
+ Yielded : Boolean := False;
+
+ begin
+ -- Only the little window between deferring abort and
+ -- locking Self_ID is the reason we need to
+ -- check for pending abort and priority change below!
+
+ if Single_Lock then
+ Lock_RTS;
+ end if;
+
+ -- More comments required in body below ???
+
+ SSL.Abort_Defer.all;
+ Write_Lock (Self_ID);
+
+ if Time /= 0.0 or else Mode /= Relative then
+ Sleep_Time := To_OS_Time (Time, Mode);
+
+ if Mode = Relative or else OS_Clock < Sleep_Time then
+ Self_ID.Common.State := Delay_Sleep;
+ Self_ID.Common.LL.AST_Pending := True;
+
+ Sys_Setimr
+ (Status, 0, Sleep_Time,
+ Timer_Sleep_AST'Access, To_Address (Self_ID), 0);
+
+ if (Status and 1) /= 1 then
+ raise Storage_Error;
+ end if;
+
+ loop
+ if Self_ID.Pending_Priority_Change then
+ Self_ID.Pending_Priority_Change := False;
+ Self_ID.Common.Base_Priority := Self_ID.New_Base_Priority;
+ Set_Priority (Self_ID, Self_ID.Common.Base_Priority);
+ end if;
+
+ if Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level then
+ Sys_Cantim (Status, To_Address (Self_ID), 0);
+ pragma Assert ((Status and 1) = 1);
+ 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;
+
+ Yielded := True;
+
+ exit when not Self_ID.Common.LL.AST_Pending;
+ end loop;
+
+ Self_ID.Common.State := Runnable;
+ end if;
+ end if;
+
+ Unlock (Self_ID);
+
+ if Single_Lock then
+ Unlock_RTS;
+ end if;
+
+ if not Yielded then
+ Result := sched_yield;
+ pragma Assert (Result = 0);
+ end if;
+
+ SSL.Abort_Undefer.all;
+ end Timed_Delay;
+
+ ---------------------
+ -- Monotonic_Clock --
+ ---------------------
+
+ function Monotonic_Clock return Duration
+ renames System.OS_Primitives.Monotonic_Clock;
+
+ -------------------
+ -- RT_Resolution --
+ -------------------
+
+ function RT_Resolution return Duration is
+ begin
+ return 10#1.0#E-3;
+ end RT_Resolution;
+
+ ------------
+ -- Wakeup --
+ ------------
+
+ procedure Wakeup (T : Task_ID; Reason : System.Tasking.Task_States) is
+ pragma Unreferenced (Reason);
+
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_cond_signal (T.Common.LL.CV'Access);
+ pragma Assert (Result = 0);
+ end Wakeup;
+
+ -----------
+ -- Yield --
+ -----------
+
+ procedure Yield (Do_Yield : Boolean := True) is
+ Result : Interfaces.C.int;
+ pragma Unreferenced (Result);
+ begin
+ if Do_Yield then
+ Result := sched_yield;
+ end if;
+ end Yield;
+
+ ------------------
+ -- Set_Priority --
+ ------------------
+
+ procedure Set_Priority
+ (T : Task_ID;
+ Prio : System.Any_Priority;
+ Loss_Of_Inheritance : Boolean := False)
+ is
+ pragma Unreferenced (Loss_Of_Inheritance);
+
+ Result : Interfaces.C.int;
+ Param : aliased struct_sched_param;
+
+ begin
+ T.Common.Current_Priority := Prio;
+ Param.sched_priority := Interfaces.C.int (Underlying_Priorities (Prio));
+
+ if Time_Slice_Val > 0 then
+ Result := pthread_setschedparam
+ (T.Common.LL.Thread, SCHED_RR, Param'Access);
+
+ elsif FIFO_Within_Priorities or else Time_Slice_Val = 0 then
+ Result := pthread_setschedparam
+ (T.Common.LL.Thread, SCHED_FIFO, Param'Access);
+
+ else
+ -- SCHED_OTHER priorities are restricted to the range 8 - 15.
+ -- Since the translation from Underlying priorities results
+ -- in a range of 16 - 31, dividing by 2 gives the correct result.
+
+ Param.sched_priority := Param.sched_priority / 2;
+ Result := pthread_setschedparam
+ (T.Common.LL.Thread, SCHED_OTHER, Param'Access);
+ end if;
+
+ pragma Assert (Result = 0);
+ end Set_Priority;
+
+ ------------------
+ -- Get_Priority --
+ ------------------
+
+ function Get_Priority (T : Task_ID) return System.Any_Priority is
+ begin
+ return T.Common.Current_Priority;
+ end Get_Priority;
+
+ ----------------
+ -- Enter_Task --
+ ----------------
+
+ procedure Enter_Task (Self_ID : Task_ID) is
+ begin
+ Self_ID.Common.LL.Thread := pthread_self;
+
+ Specific.Set (Self_ID);
+
+ Lock_RTS;
+
+ for J in Known_Tasks'Range loop
+ if Known_Tasks (J) = null then
+ Known_Tasks (J) := Self_ID;
+ Self_ID.Known_Tasks_Index := J;
+ exit;
+ end if;
+ end loop;
+
+ Unlock_RTS;
+ end Enter_Task;
+
+ --------------
+ -- New_ATCB --
+ --------------
+
+ function New_ATCB (Entry_Num : Task_Entry_Index) return Task_ID is
+ begin
+ return new Ada_Task_Control_Block (Entry_Num);
+ end New_ATCB;
+
+ -------------------
+ -- Is_Valid_Task --
+ -------------------
+
+ function Is_Valid_Task return Boolean renames Specific.Is_Valid_Task;
+
+ -----------------------------
+ -- Register_Foreign_Thread --
+ -----------------------------
+
+ function Register_Foreign_Thread return Task_ID is
+ begin
+ if Is_Valid_Task then
+ return Self;
+ else
+ return Register_Foreign_Thread (pthread_self);
+ end if;
+ end Register_Foreign_Thread;
+
+ ----------------------
+ -- Initialize_TCB --
+ ----------------------
+
+ procedure Initialize_TCB (Self_ID : Task_ID; Succeeded : out Boolean) is
+ Mutex_Attr : aliased pthread_mutexattr_t;
+ Result : Interfaces.C.int;
+ Cond_Attr : aliased pthread_condattr_t;
+
+ begin
+ -- More comments required in body below ???
+
+ if not Single_Lock then
+ Result := pthread_mutexattr_init (Mutex_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = 0 then
+ Result := pthread_mutex_init (Self_ID.Common.LL.L'Access,
+ Mutex_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+ end if;
+
+ if Result /= 0 then
+ Succeeded := False;
+ return;
+ end if;
+
+ Result := pthread_mutexattr_destroy (Mutex_Attr'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Result := pthread_condattr_init (Cond_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result = 0 then
+ Result := pthread_cond_init (Self_ID.Common.LL.CV'Access,
+ Cond_Attr'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+ end if;
+
+ if Result = 0 then
+ Succeeded := True;
+ Self_ID.Common.LL.Exc_Stack_Ptr := new Exc_Stack_T;
+ SSL.Set_Exc_Stack_Addr
+ (To_Address (Self_ID),
+ Self_ID.Common.LL.Exc_Stack_Ptr (Exc_Stack_T'Last)'Address);
+
+ else
+ if not Single_Lock then
+ Result := pthread_mutex_destroy (Self_ID.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Succeeded := False;
+ end if;
+
+ Result := pthread_condattr_destroy (Cond_Attr'Access);
+ pragma Assert (Result = 0);
+ end Initialize_TCB;
+
+ -----------------
+ -- Create_Task --
+ -----------------
+
+ procedure Create_Task
+ (T : Task_ID;
+ Wrapper : System.Address;
+ Stack_Size : System.Parameters.Size_Type;
+ Priority : System.Any_Priority;
+ Succeeded : out Boolean)
+ is
+ Attributes : aliased pthread_attr_t;
+ Adjusted_Stack_Size : Interfaces.C.size_t;
+ Result : Interfaces.C.int;
+
+ function Thread_Body_Access is new
+ Unchecked_Conversion (System.Address, Thread_Body);
+
+ begin
+ if Stack_Size = Unspecified_Size then
+ Adjusted_Stack_Size := Interfaces.C.size_t (Default_Stack_Size);
+
+ elsif Stack_Size < Minimum_Stack_Size then
+ Adjusted_Stack_Size := Interfaces.C.size_t (Minimum_Stack_Size);
+
+ else
+ Adjusted_Stack_Size := Interfaces.C.size_t (Stack_Size);
+ end if;
+
+ -- Since the initial signal mask of a thread is inherited from the
+ -- creator, we need to set our local signal mask mask all signals
+ -- during the creation operation, to make sure the new thread is
+ -- not disturbed by signals before it has set its own Task_ID.
+
+ Result := pthread_attr_init (Attributes'Access);
+ pragma Assert (Result = 0 or else Result = ENOMEM);
+
+ if Result /= 0 then
+ Succeeded := False;
+ return;
+ end if;
+
+ Result := pthread_attr_setdetachstate
+ (Attributes'Access, PTHREAD_CREATE_DETACHED);
+ pragma Assert (Result = 0);
+
+ Result := pthread_attr_setstacksize
+ (Attributes'Access, Adjusted_Stack_Size);
+ pragma Assert (Result = 0);
+
+ -- This call may be unnecessary, not sure. ???
+
+ Result :=
+ pthread_attr_setinheritsched
+ (Attributes'Access, PTHREAD_EXPLICIT_SCHED);
+ pragma Assert (Result = 0);
+
+ Result := pthread_create
+ (T.Common.LL.Thread'Access,
+ Attributes'Access,
+ Thread_Body_Access (Wrapper),
+ To_Address (T));
+
+ -- ENOMEM is a valid run-time error. Don't shut down.
+
+ pragma Assert (Result = 0
+ or else Result = EAGAIN or else Result = ENOMEM);
+
+ Succeeded := Result = 0;
+
+ Result := pthread_attr_destroy (Attributes'Access);
+ pragma Assert (Result = 0);
+
+ if Succeeded then
+ Set_Priority (T, Priority);
+ end if;
+ end Create_Task;
+
+ ------------------
+ -- Finalize_TCB --
+ ------------------
+
+ procedure Finalize_TCB (T : Task_ID) is
+ Result : Interfaces.C.int;
+ Tmp : Task_ID := T;
+ Is_Self : constant Boolean := T = Self;
+
+ procedure Free is new
+ Unchecked_Deallocation (Ada_Task_Control_Block, Task_ID);
+
+ procedure Free is new Unchecked_Deallocation
+ (Exc_Stack_T, Exc_Stack_Ptr_T);
+
+ begin
+ if not Single_Lock then
+ Result := pthread_mutex_destroy (T.Common.LL.L'Access);
+ pragma Assert (Result = 0);
+ end if;
+
+ Result := pthread_cond_destroy (T.Common.LL.CV'Access);
+ pragma Assert (Result = 0);
+
+ if T.Known_Tasks_Index /= -1 then
+ Known_Tasks (T.Known_Tasks_Index) := null;
+ end if;
+
+ Free (T.Common.LL.Exc_Stack_Ptr);
+
+ Free (Tmp);
+
+ if Is_Self then
+ Specific.Set (null);
+ end if;
+ end Finalize_TCB;
+
+ ---------------
+ -- Exit_Task --
+ ---------------
+
+ procedure Exit_Task is
+ begin
+ Specific.Set (null);
+ end Exit_Task;
+
+ ----------------
+ -- Abort_Task --
+ ----------------
+
+ procedure Abort_Task (T : Task_ID) is
+ begin
+ -- Interrupt Server_Tasks may be waiting on an event flag
+
+ if T.Common.State = Interrupt_Server_Blocked_On_Event_Flag then
+ Wakeup (T, Interrupt_Server_Blocked_On_Event_Flag);
+ end if;
+ end Abort_Task;
+
+ ----------------
+ -- Check_Exit --
+ ----------------
+
+ -- Dummy version
+
+ function Check_Exit (Self_ID : ST.Task_ID) return Boolean is
+ pragma Unreferenced (Self_ID);
+
+ begin
+ return True;
+ end Check_Exit;
+
+ --------------------
+ -- Check_No_Locks --
+ --------------------
+
+ function Check_No_Locks (Self_ID : ST.Task_ID) return Boolean is
+ pragma Unreferenced (Self_ID);
+
+ begin
+ return True;
+ end Check_No_Locks;
+
+ ----------------------
+ -- Environment_Task --
+ ----------------------
+
+ function Environment_Task return Task_ID is
+ begin
+ return Environment_Task_ID;
+ end Environment_Task;
+
+ --------------
+ -- Lock_RTS --
+ --------------
+
+ procedure Lock_RTS is
+ begin
+ Write_Lock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Lock_RTS;
+
+ ----------------
+ -- Unlock_RTS --
+ ----------------
+
+ procedure Unlock_RTS is
+ begin
+ Unlock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Unlock_RTS;
+
+ ------------------
+ -- Suspend_Task --
+ ------------------
+
+ function Suspend_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id) return Boolean
+ is
+ pragma Unreferenced (T);
+ pragma Unreferenced (Thread_Self);
+
+ begin
+ return False;
+ end Suspend_Task;
+
+ -----------------
+ -- Resume_Task --
+ -----------------
+
+ function Resume_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id) return Boolean
+ is
+ pragma Unreferenced (T);
+ pragma Unreferenced (Thread_Self);
+ begin
+ return False;
+ end Resume_Task;
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize (Environment_Task : Task_ID) is
+ begin
+ Environment_Task_ID := Environment_Task;
+
+ -- Initialize the lock used to synchronize chain of all ATCBs
+
+ Initialize_Lock (Single_RTS_Lock'Access, RTS_Lock_Level);
+
+ Specific.Initialize (Environment_Task);
+
+ Enter_Task (Environment_Task);
+ end Initialize;
+
+end System.Task_Primitives.Operations;
diff --git a/gcc/ada/s-taprop-vxworks.adb b/gcc/ada/s-taprop-vxworks.adb
new file mode 100644
index 00000000000..8bbbf0e13b0
--- /dev/null
+++ b/gcc/ada/s-taprop-vxworks.adb
@@ -0,0 +1,1144 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S . O P E R A T I O N S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2003, 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- --
+-- 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, 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, --
+-- 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 is the VxWorks version of this package
+
+-- This package contains all the GNULL primitives that interface directly
+-- with the underlying OS.
+
+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.Tasking.Debug;
+-- used for Known_Tasks
+
+with System.Interrupt_Management;
+-- used for Keep_Unmasked
+-- Abort_Task_Signal
+-- Signal_ID
+-- Initialize_Interrupts
+
+with System.Soft_Links;
+-- used for Defer/Undefer_Abort
+
+-- Note that we do not use System.Tasking.Initialization directly since
+-- this is a higher level package that we shouldn't depend on. For example
+-- when using the restricted run time, it is replaced by
+-- System.Tasking.Restricted.Initialization
+
+with System.OS_Interface;
+-- used for various type, constant, and operations
+
+with System.Parameters;
+-- used for Size_Type
+
+with System.Tasking;
+-- used for Ada_Task_Control_Block
+-- Task_ID
+-- ATCB components and types
+
+with Interfaces.C;
+
+with Unchecked_Conversion;
+with Unchecked_Deallocation;
+
+package body System.Task_Primitives.Operations is
+
+ use System.Tasking.Debug;
+ use System.Tasking;
+ use System.OS_Interface;
+ use System.Parameters;
+ use type Interfaces.C.int;
+
+ package SSL renames System.Soft_Links;
+
+ subtype int is System.OS_Interface.int;
+
+ Relative : constant := 0;
+
+ ----------------
+ -- Local Data --
+ ----------------
+
+ -- The followings are logically constants, but need to be initialized
+ -- at run time.
+
+ Single_RTS_Lock : aliased RTS_Lock;
+ -- This is a lock to allow only one thread of control in the RTS at
+ -- a time; it is used to execute in mutual exclusion from all other tasks.
+ -- Used mainly in Single_Lock mode, but also to protect All_Tasks_List
+
+ ATCB_Key : aliased System.Address := System.Null_Address;
+ -- Key used to find the Ada Task_ID associated with a thread
+
+ ATCB_Key_Addr : System.Address := ATCB_Key'Address;
+ pragma Export (Ada, ATCB_Key_Addr, "__gnat_ATCB_key_addr");
+ -- Exported to support the temporary AE653 task registration
+ -- implementation. This mechanism is used to minimize impact on other
+ -- targets.
+
+ Environment_Task_ID : Task_ID;
+ -- A variable to hold Task_ID for the environment task.
+
+ Unblocked_Signal_Mask : aliased sigset_t;
+ -- The set of signals that should unblocked in all tasks
+
+ -- The followings are internal configuration constants needed.
+
+ Time_Slice_Val : Integer;
+ pragma Import (C, Time_Slice_Val, "__gl_time_slice_val");
+
+ Locking_Policy : Character;
+ pragma Import (C, Locking_Policy, "__gl_locking_policy");
+
+ Dispatching_Policy : Character;
+ pragma Import (C, Dispatching_Policy, "__gl_task_dispatching_policy");
+
+ FIFO_Within_Priorities : constant Boolean := Dispatching_Policy = 'F';
+ -- Indicates whether FIFO_Within_Priorities is set.
+
+ Mutex_Protocol : Priority_Type;
+
+ Foreign_Task_Elaborated : aliased Boolean := True;
+ -- Used to identified fake tasks (i.e., non-Ada Threads).
+
+ --------------------
+ -- Local Packages --
+ --------------------
+
+ package Specific is
+
+ function Is_Valid_Task return Boolean;
+ pragma Inline (Is_Valid_Task);
+ -- Does executing thread have a TCB?
+
+ procedure Set (Self_Id : Task_ID);
+ pragma Inline (Set);
+ -- Set the self id for the current task.
+
+ function Self return Task_ID;
+ pragma Inline (Self);
+ -- Return a pointer to the Ada Task Control Block of the calling task.
+
+ end Specific;
+
+ package body Specific is separate;
+ -- The body of this package is target specific.
+
+ ---------------------------------
+ -- Support for foreign threads --
+ ---------------------------------
+
+ function Register_Foreign_Thread (Thread : Thread_Id) return Task_ID;
+ -- Allocate and Initialize a new ATCB for the current Thread.
+
+ function Register_Foreign_Thread
+ (Thread : Thread_Id) return Task_ID is separate;
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ procedure Abort_Handler (signo : Signal);
+ -- Handler for the abort (SIGABRT) signal to handle asynchronous abortion.
+
+ procedure Install_Signal_Handlers;
+ -- Install the default signal handlers for the current task
+
+ function To_Address is new Unchecked_Conversion (Task_ID, System.Address);
+
+ -------------------
+ -- Abort_Handler --
+ -------------------
+
+ procedure Abort_Handler (signo : Signal) is
+ pragma Unreferenced (signo);
+
+ Self_ID : constant Task_ID := Self;
+ Result : int;
+ Old_Set : aliased sigset_t;
+
+ begin
+ -- It is not safe to raise an exception when using ZCX and the GCC
+ -- exception handling mechanism.
+
+ if ZCX_By_Default and then GCC_ZCX_Support then
+ return;
+ end if;
+
+ if Self_ID.Deferral_Level = 0
+ and then Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level
+ and then not Self_ID.Aborting
+ then
+ Self_ID.Aborting := True;
+
+ -- Make sure signals used for RTS internal purpose are unmasked
+
+ Result := pthread_sigmask (SIG_UNBLOCK,
+ Unblocked_Signal_Mask'Unchecked_Access, Old_Set'Unchecked_Access);
+ pragma Assert (Result = 0);
+
+ raise Standard'Abort_Signal;
+ end if;
+ end Abort_Handler;
+
+ -----------------
+ -- Stack_Guard --
+ -----------------
+
+ procedure Stack_Guard (T : ST.Task_ID; On : Boolean) is
+ pragma Unreferenced (T);
+ pragma Unreferenced (On);
+
+ begin
+ -- Nothing needed (why not???)
+
+ null;
+ end Stack_Guard;
+
+ -------------------
+ -- Get_Thread_Id --
+ -------------------
+
+ function Get_Thread_Id (T : ST.Task_ID) return OSI.Thread_Id is
+ begin
+ return T.Common.LL.Thread;
+ end Get_Thread_Id;
+
+ ----------
+ -- Self --
+ ----------
+
+ function Self return Task_ID renames Specific.Self;
+
+ -----------------------------
+ -- Install_Signal_Handlers --
+ -----------------------------
+
+ procedure Install_Signal_Handlers is
+ act : aliased struct_sigaction;
+ old_act : aliased struct_sigaction;
+ Tmp_Set : aliased sigset_t;
+ Result : int;
+
+ begin
+ act.sa_flags := 0;
+ act.sa_handler := Abort_Handler'Address;
+
+ Result := sigemptyset (Tmp_Set'Access);
+ pragma Assert (Result = 0);
+ act.sa_mask := Tmp_Set;
+
+ Result :=
+ sigaction
+ (Signal (Interrupt_Management.Abort_Task_Signal),
+ act'Unchecked_Access,
+ old_act'Unchecked_Access);
+ pragma Assert (Result = 0);
+
+ Interrupt_Management.Initialize_Interrupts;
+ end Install_Signal_Handlers;
+
+ ---------------------
+ -- Initialize_Lock --
+ ---------------------
+
+ procedure Initialize_Lock (Prio : System.Any_Priority; L : access Lock) is
+ begin
+ L.Mutex := semMCreate (SEM_Q_PRIORITY + SEM_INVERSION_SAFE);
+ L.Prio_Ceiling := int (Prio);
+ L.Protocol := Mutex_Protocol;
+ pragma Assert (L.Mutex /= 0);
+ end Initialize_Lock;
+
+ procedure Initialize_Lock (L : access RTS_Lock; Level : Lock_Level) is
+ pragma Unreferenced (Level);
+
+ begin
+ L.Mutex := semMCreate (SEM_Q_PRIORITY + SEM_INVERSION_SAFE);
+ L.Prio_Ceiling := int (System.Any_Priority'Last);
+ L.Protocol := Mutex_Protocol;
+ pragma Assert (L.Mutex /= 0);
+ end Initialize_Lock;
+
+ -------------------
+ -- Finalize_Lock --
+ -------------------
+
+ procedure Finalize_Lock (L : access Lock) is
+ Result : int;
+
+ begin
+ Result := semDelete (L.Mutex);
+ pragma Assert (Result = 0);
+ end Finalize_Lock;
+
+ procedure Finalize_Lock (L : access RTS_Lock) is
+ Result : int;
+
+ begin
+ Result := semDelete (L.Mutex);
+ pragma Assert (Result = 0);
+ end Finalize_Lock;
+
+ ----------------
+ -- Write_Lock --
+ ----------------
+
+ procedure Write_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ Result : int;
+
+ begin
+ if L.Protocol = Prio_Protect
+ and then int (Self.Common.Current_Priority) > L.Prio_Ceiling
+ then
+ Ceiling_Violation := True;
+ return;
+ else
+ Ceiling_Violation := False;
+ end if;
+
+ Result := semTake (L.Mutex, WAIT_FOREVER);
+ pragma Assert (Result = 0);
+ end Write_Lock;
+
+ procedure Write_Lock
+ (L : access RTS_Lock;
+ Global_Lock : Boolean := False)
+ is
+ Result : int;
+
+ begin
+ if not Single_Lock or else Global_Lock then
+ Result := semTake (L.Mutex, WAIT_FOREVER);
+ pragma Assert (Result = 0);
+ end if;
+ end Write_Lock;
+
+ procedure Write_Lock (T : Task_ID) is
+ Result : int;
+
+ begin
+ if not Single_Lock then
+ Result := semTake (T.Common.LL.L.Mutex, WAIT_FOREVER);
+ pragma Assert (Result = 0);
+ end if;
+ end Write_Lock;
+
+ ---------------
+ -- Read_Lock --
+ ---------------
+
+ procedure Read_Lock (L : access Lock; Ceiling_Violation : out Boolean) is
+ begin
+ Write_Lock (L, Ceiling_Violation);
+ end Read_Lock;
+
+ ------------
+ -- Unlock --
+ ------------
+
+ procedure Unlock (L : access Lock) is
+ Result : int;
+
+ begin
+ Result := semGive (L.Mutex);
+ pragma Assert (Result = 0);
+ end Unlock;
+
+ procedure Unlock (L : access RTS_Lock; Global_Lock : Boolean := False) is
+ Result : int;
+
+ begin
+ if not Single_Lock or else Global_Lock then
+ Result := semGive (L.Mutex);
+ pragma Assert (Result = 0);
+ end if;
+ end Unlock;
+
+ procedure Unlock (T : Task_ID) is
+ Result : int;
+
+ begin
+ if not Single_Lock then
+ Result := semGive (T.Common.LL.L.Mutex);
+ pragma Assert (Result = 0);
+ end if;
+ end Unlock;
+
+ -----------
+ -- Sleep --
+ -----------
+
+ procedure Sleep (Self_ID : Task_ID; Reason : System.Tasking.Task_States) is
+ pragma Unreferenced (Reason);
+
+ Result : int;
+
+ begin
+ pragma Assert (Self_ID = Self);
+
+ -- 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;
+
+ pragma Assert (Result = 0);
+
+ -- Perform a blocking operation to take the CV semaphore.
+ -- Note that a blocking operation in VxWorks will reenable
+ -- task scheduling. When we are no longer blocked and control
+ -- is returned, task scheduling will again be disabled.
+
+ Result := semTake (Self_ID.Common.LL.CV, WAIT_FOREVER);
+ pragma Assert (Result = 0);
+
+ -- 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;
+
+ pragma Assert (Result = 0);
+ end Sleep;
+
+ -----------------
+ -- Timed_Sleep --
+ -----------------
+
+ -- This is for use within the run-time system, so abort is
+ -- assumed to be already deferred, and the caller should be
+ -- holding its own ATCB lock.
+
+ procedure Timed_Sleep
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes;
+ Reason : System.Tasking.Task_States;
+ Timedout : out Boolean;
+ Yielded : out Boolean)
+ is
+ pragma Unreferenced (Reason);
+
+ Orig : constant Duration := Monotonic_Clock;
+ Absolute : Duration;
+ Ticks : int;
+ Result : int;
+ Wakeup : Boolean := False;
+
+ begin
+ Timedout := False;
+ Yielded := True;
+
+ if Mode = Relative then
+ Absolute := Orig + Time;
+
+ -- Systematically add one since the first tick will delay
+ -- *at most* 1 / Rate_Duration seconds, so we need to add one to
+ -- be on the safe side.
+
+ Ticks := To_Clock_Ticks (Time);
+
+ if Ticks > 0 and then Ticks < int'Last then
+ Ticks := Ticks + 1;
+ end if;
+
+ else
+ Absolute := Time;
+ Ticks := To_Clock_Ticks (Time - Monotonic_Clock);
+ end if;
+
+ if Ticks > 0 then
+ 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;
+
+ pragma Assert (Result = 0);
+
+ -- Perform a blocking operation to take the CV semaphore.
+ -- Note that a blocking operation in VxWorks will reenable
+ -- task scheduling. When we are no longer blocked and control
+ -- is returned, task scheduling will again be disabled.
+
+ Result := semTake (Self_ID.Common.LL.CV, Ticks);
+
+ if Result = 0 then
+ -- Somebody may have called Wakeup for us
+
+ Wakeup := True;
+
+ else
+ if errno /= S_objLib_OBJ_TIMEOUT then
+ Wakeup := True;
+ else
+ -- If Ticks = int'last, it was most probably truncated
+ -- so let's make another round after recomputing Ticks
+ -- from the the absolute time.
+
+ if Ticks /= int'Last then
+ Timedout := True;
+ else
+ Ticks := To_Clock_Ticks (Absolute - Monotonic_Clock);
+
+ if Ticks < 0 then
+ Timedout := True;
+ end if;
+ end if;
+ end if;
+ end if;
+
+ -- 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;
+
+ pragma Assert (Result = 0);
+
+ exit when Timedout or Wakeup;
+ end loop;
+
+ else
+ Timedout := True;
+
+ -- Should never hold a lock while yielding.
+ if Single_Lock then
+ Result := semGive (Single_RTS_Lock.Mutex);
+ taskDelay (0);
+ Result := semTake (Single_RTS_Lock.Mutex, WAIT_FOREVER);
+
+ else
+ Result := semGive (Self_ID.Common.LL.L.Mutex);
+ taskDelay (0);
+ Result := semTake (Self_ID.Common.LL.L.Mutex, WAIT_FOREVER);
+ end if;
+ end if;
+ end Timed_Sleep;
+
+ -----------------
+ -- Timed_Delay --
+ -----------------
+
+ -- This is for use in implementing delay statements, so
+ -- we assume the caller is holding no locks.
+
+ procedure Timed_Delay
+ (Self_ID : Task_ID;
+ Time : Duration;
+ Mode : ST.Delay_Modes)
+ is
+ Orig : constant Duration := Monotonic_Clock;
+ Absolute : Duration;
+ Ticks : int;
+ Timedout : Boolean;
+ Result : int;
+ Aborted : Boolean := False;
+
+ begin
+ SSL.Abort_Defer.all;
+
+ if Mode = Relative then
+ Absolute := Orig + Time;
+ Ticks := To_Clock_Ticks (Time);
+
+ if Ticks > 0 and then Ticks < int'Last then
+
+ -- The first tick will delay anytime between 0 and
+ -- 1 / sysClkRateGet seconds, so we need to add one to
+ -- be on the safe side.
+
+ Ticks := Ticks + 1;
+ end if;
+
+ else
+ Absolute := Time;
+ Ticks := To_Clock_Ticks (Time - Orig);
+ end if;
+
+ if Ticks > 0 then
+ -- Modifying State and Pending_Priority_Change, 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;
+
+ pragma Assert (Result = 0);
+
+ Self_ID.Common.State := Delay_Sleep;
+ Timedout := False;
+
+ loop
+ if Self_ID.Pending_Priority_Change then
+ Self_ID.Pending_Priority_Change := False;
+ Self_ID.Common.Base_Priority := Self_ID.New_Base_Priority;
+ Set_Priority (Self_ID, Self_ID.Common.Base_Priority);
+ end if;
+
+ Aborted := Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level;
+
+ -- 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;
+ pragma Assert (Result = 0);
+
+ exit when Aborted;
+
+ Result := semTake (Self_ID.Common.LL.CV, Ticks);
+
+ if Result /= 0 then
+ -- If Ticks = int'last, it was most probably truncated
+ -- so let's make another round after recomputing Ticks
+ -- from the the absolute time.
+
+ if errno = S_objLib_OBJ_TIMEOUT and then Ticks /= int'Last then
+ Timedout := True;
+ else
+ Ticks := To_Clock_Ticks (Absolute - Monotonic_Clock);
+
+ if Ticks < 0 then
+ Timedout := True;
+ end if;
+ end if;
+ end if;
+
+ -- 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;
+
+ pragma Assert (Result = 0);
+
+ exit when Timedout;
+ end loop;
+
+ 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;
+
+ else
+ taskDelay (0);
+ end if;
+
+ SSL.Abort_Undefer.all;
+ end Timed_Delay;
+
+ ---------------------
+ -- Monotonic_Clock --
+ ---------------------
+
+ function Monotonic_Clock return Duration is
+ TS : aliased timespec;
+ Result : int;
+
+ begin
+ Result := clock_gettime (CLOCK_REALTIME, TS'Unchecked_Access);
+ pragma Assert (Result = 0);
+ return To_Duration (TS);
+ end Monotonic_Clock;
+
+ -------------------
+ -- RT_Resolution --
+ -------------------
+
+ function RT_Resolution return Duration is
+ begin
+ return 1.0 / Duration (sysClkRateGet);
+ end RT_Resolution;
+
+ ------------
+ -- Wakeup --
+ ------------
+
+ procedure Wakeup (T : Task_ID; Reason : System.Tasking.Task_States) is
+ pragma Unreferenced (Reason);
+
+ Result : int;
+
+ begin
+ Result := semGive (T.Common.LL.CV);
+ pragma Assert (Result = 0);
+ end Wakeup;
+
+ -----------
+ -- Yield --
+ -----------
+
+ procedure Yield (Do_Yield : Boolean := True) is
+ pragma Unreferenced (Do_Yield);
+ Result : int;
+ pragma Unreferenced (Result);
+ begin
+ Result := taskDelay (0);
+ end Yield;
+
+ ------------------
+ -- Set_Priority --
+ ------------------
+
+ type Prio_Array_Type is array (System.Any_Priority) of Integer;
+ pragma Atomic_Components (Prio_Array_Type);
+
+ Prio_Array : Prio_Array_Type;
+ -- Global array containing the id of the currently running task for
+ -- each priority. Note that we assume that we are on a single processor
+ -- with run-till-blocked scheduling.
+
+ procedure Set_Priority
+ (T : Task_ID;
+ Prio : System.Any_Priority;
+ Loss_Of_Inheritance : Boolean := False)
+ is
+ Array_Item : Integer;
+ Result : int;
+
+ begin
+ Result :=
+ taskPrioritySet
+ (T.Common.LL.Thread, To_VxWorks_Priority (int (Prio)));
+ pragma Assert (Result = 0);
+
+ if FIFO_Within_Priorities then
+
+ -- Annex D requirement [RM D.2.2 par. 9]:
+ -- If the task drops its priority due to the loss of inherited
+ -- priority, it is added at the head of the ready queue for its
+ -- new active priority.
+
+ if Loss_Of_Inheritance
+ and then Prio < T.Common.Current_Priority
+ then
+ Array_Item := Prio_Array (T.Common.Base_Priority) + 1;
+ Prio_Array (T.Common.Base_Priority) := Array_Item;
+
+ loop
+ -- Give some processes a chance to arrive
+
+ taskDelay (0);
+
+ -- Then wait for our turn to proceed
+
+ exit when Array_Item = Prio_Array (T.Common.Base_Priority)
+ or else Prio_Array (T.Common.Base_Priority) = 1;
+ end loop;
+
+ Prio_Array (T.Common.Base_Priority) :=
+ Prio_Array (T.Common.Base_Priority) - 1;
+ end if;
+ end if;
+
+ T.Common.Current_Priority := Prio;
+ end Set_Priority;
+
+ ------------------
+ -- Get_Priority --
+ ------------------
+
+ function Get_Priority (T : Task_ID) return System.Any_Priority is
+ begin
+ return T.Common.Current_Priority;
+ end Get_Priority;
+
+ ----------------
+ -- Enter_Task --
+ ----------------
+
+ procedure Enter_Task (Self_ID : Task_ID) is
+ procedure Init_Float;
+ pragma Import (C, Init_Float, "__gnat_init_float");
+ -- Properly initializes the FPU for PPC/MIPS systems.
+
+ begin
+ Self_ID.Common.LL.Thread := taskIdSelf;
+ Specific.Set (Self_ID);
+
+ Init_Float;
+
+ -- Install the signal handlers.
+ -- This is called for each task since there is no signal inheritance
+ -- between VxWorks tasks.
+
+ Install_Signal_Handlers;
+
+ Lock_RTS;
+
+ for J in Known_Tasks'Range loop
+ if Known_Tasks (J) = null then
+ Known_Tasks (J) := Self_ID;
+ Self_ID.Known_Tasks_Index := J;
+ exit;
+ end if;
+ end loop;
+
+ Unlock_RTS;
+ end Enter_Task;
+
+ --------------
+ -- New_ATCB --
+ --------------
+
+ function New_ATCB (Entry_Num : Task_Entry_Index) return Task_ID is
+ begin
+ return new Ada_Task_Control_Block (Entry_Num);
+ end New_ATCB;
+
+ -------------------
+ -- Is_Valid_Task --
+ -------------------
+
+ function Is_Valid_Task return Boolean renames Specific.Is_Valid_Task;
+
+ -----------------------------
+ -- Register_Foreign_Thread --
+ -----------------------------
+
+ function Register_Foreign_Thread return Task_ID is
+ begin
+ if Is_Valid_Task then
+ return Self;
+ else
+ return Register_Foreign_Thread (taskIdSelf);
+ end if;
+ end Register_Foreign_Thread;
+
+ --------------------
+ -- Initialize_TCB --
+ --------------------
+
+ procedure Initialize_TCB (Self_ID : Task_ID; Succeeded : out Boolean) is
+ begin
+ Self_ID.Common.LL.CV := semBCreate (SEM_Q_PRIORITY, SEM_EMPTY);
+ Self_ID.Common.LL.Thread := 0;
+
+ if Self_ID.Common.LL.CV = 0 then
+ Succeeded := False;
+ else
+ Succeeded := True;
+
+ if not Single_Lock then
+ Initialize_Lock (Self_ID.Common.LL.L'Access, ATCB_Level);
+ end if;
+ end if;
+ end Initialize_TCB;
+
+ -----------------
+ -- Create_Task --
+ -----------------
+
+ procedure Create_Task
+ (T : Task_ID;
+ Wrapper : System.Address;
+ Stack_Size : System.Parameters.Size_Type;
+ Priority : System.Any_Priority;
+ Succeeded : out Boolean)
+ is
+ Adjusted_Stack_Size : size_t;
+ begin
+ if Stack_Size = Unspecified_Size then
+ Adjusted_Stack_Size := size_t (Default_Stack_Size);
+
+ elsif Stack_Size < Minimum_Stack_Size then
+ Adjusted_Stack_Size := size_t (Minimum_Stack_Size);
+
+ else
+ Adjusted_Stack_Size := size_t (Stack_Size);
+ end if;
+
+ -- Ask for 4 extra bytes of stack space so that the ATCB
+ -- pointer can be stored below the stack limit, plus extra
+ -- space for the frame of Task_Wrapper. This is so the user
+ -- gets the amount of stack requested exclusive of the needs
+ -- of the runtime.
+ --
+ -- We also have to allocate n more bytes for the task name
+ -- storage and enough space for the Wind Task Control Block
+ -- which is around 0x778 bytes. VxWorks also seems to carve out
+ -- additional space, so use 2048 as a nice round number.
+ -- We might want to increment to the nearest page size in
+ -- case we ever support VxVMI.
+ --
+ -- XXX - we should come back and visit this so we can
+ -- set the task name to something appropriate.
+
+ Adjusted_Stack_Size := Adjusted_Stack_Size + 2048;
+
+ -- Since the initial signal mask of a thread is inherited from the
+ -- creator, and the Environment task has all its signals masked, we
+ -- do not need to manipulate caller's signal mask at this point.
+ -- All tasks in RTS will have All_Tasks_Mask initially.
+
+ if T.Common.Task_Image_Len = 0 then
+ T.Common.LL.Thread := taskSpawn
+ (System.Null_Address,
+ To_VxWorks_Priority (int (Priority)),
+ VX_FP_TASK,
+ Adjusted_Stack_Size,
+ Wrapper,
+ To_Address (T));
+ else
+ declare
+ Name : aliased String (1 .. T.Common.Task_Image_Len + 1);
+ begin
+ Name (1 .. Name'Last - 1) :=
+ T.Common.Task_Image (1 .. T.Common.Task_Image_Len);
+ Name (Name'Last) := ASCII.NUL;
+
+ T.Common.LL.Thread := taskSpawn
+ (Name'Address,
+ To_VxWorks_Priority (int (Priority)),
+ VX_FP_TASK,
+ Adjusted_Stack_Size,
+ Wrapper,
+ To_Address (T));
+ end;
+ end if;
+
+ if T.Common.LL.Thread = -1 then
+ Succeeded := False;
+ else
+ Succeeded := True;
+ end if;
+
+ Task_Creation_Hook (T.Common.LL.Thread);
+ Set_Priority (T, Priority);
+ end Create_Task;
+
+ ------------------
+ -- Finalize_TCB --
+ ------------------
+
+ procedure Finalize_TCB (T : Task_ID) is
+ Result : int;
+ Tmp : Task_ID := T;
+ Is_Self : constant Boolean := (T = Self);
+
+ procedure Free is new
+ Unchecked_Deallocation (Ada_Task_Control_Block, Task_ID);
+
+ begin
+ if not Single_Lock then
+ Result := semDelete (T.Common.LL.L.Mutex);
+ pragma Assert (Result = 0);
+ end if;
+
+ T.Common.LL.Thread := 0;
+
+ Result := semDelete (T.Common.LL.CV);
+ pragma Assert (Result = 0);
+
+ if T.Known_Tasks_Index /= -1 then
+ Known_Tasks (T.Known_Tasks_Index) := null;
+ end if;
+
+ Free (Tmp);
+
+ if Is_Self then
+ Result := taskVarDelete (taskIdSelf, ATCB_Key'Access);
+ pragma Assert (Result /= ERROR);
+ end if;
+ end Finalize_TCB;
+
+ ---------------
+ -- Exit_Task --
+ ---------------
+
+ procedure Exit_Task is
+ begin
+ Specific.Set (null);
+ end Exit_Task;
+
+ ----------------
+ -- Abort_Task --
+ ----------------
+
+ procedure Abort_Task (T : Task_ID) is
+ Result : int;
+
+ begin
+ Result := kill (T.Common.LL.Thread,
+ Signal (Interrupt_Management.Abort_Task_Signal));
+ pragma Assert (Result = 0);
+ end Abort_Task;
+
+ ----------------
+ -- Check_Exit --
+ ----------------
+
+ -- Dummy version
+
+ function Check_Exit (Self_ID : ST.Task_ID) return Boolean is
+ pragma Unreferenced (Self_ID);
+
+ begin
+ return True;
+ end Check_Exit;
+
+ --------------------
+ -- Check_No_Locks --
+ --------------------
+
+ function Check_No_Locks (Self_ID : ST.Task_ID) return Boolean is
+ pragma Unreferenced (Self_ID);
+
+ begin
+ return True;
+ end Check_No_Locks;
+
+ ----------------------
+ -- Environment_Task --
+ ----------------------
+
+ function Environment_Task return Task_ID is
+ begin
+ return Environment_Task_ID;
+ end Environment_Task;
+
+ --------------
+ -- Lock_RTS --
+ --------------
+
+ procedure Lock_RTS is
+ begin
+ Write_Lock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Lock_RTS;
+
+ ----------------
+ -- Unlock_RTS --
+ ----------------
+
+ procedure Unlock_RTS is
+ begin
+ Unlock (Single_RTS_Lock'Access, Global_Lock => True);
+ end Unlock_RTS;
+
+ ------------------
+ -- Suspend_Task --
+ ------------------
+
+ function Suspend_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id)
+ return Boolean
+ is
+ begin
+ if T.Common.LL.Thread /= 0
+ and then T.Common.LL.Thread /= Thread_Self
+ then
+ return taskSuspend (T.Common.LL.Thread) = 0;
+ else
+ return True;
+ end if;
+ end Suspend_Task;
+
+ -----------------
+ -- Resume_Task --
+ -----------------
+
+ function Resume_Task
+ (T : ST.Task_ID;
+ Thread_Self : Thread_Id)
+ return Boolean
+ is
+ begin
+ if T.Common.LL.Thread /= 0
+ and then T.Common.LL.Thread /= Thread_Self
+ then
+ return taskResume (T.Common.LL.Thread) = 0;
+ else
+ return True;
+ end if;
+ end Resume_Task;
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize (Environment_Task : Task_ID) is
+ Result : int;
+
+ begin
+ if Locking_Policy = 'C' then
+ Mutex_Protocol := Prio_Protect;
+ elsif Locking_Policy = 'I' then
+ Mutex_Protocol := Prio_Inherit;
+ else
+ Mutex_Protocol := Prio_None;
+ end if;
+
+ if Time_Slice_Val > 0 then
+ Result := kernelTimeSlice
+ (To_Clock_Ticks
+ (Duration (Time_Slice_Val) / Duration (1_000_000.0)));
+ end if;
+
+ Result := sigemptyset (Unblocked_Signal_Mask'Access);
+ pragma Assert (Result = 0);
+
+ for J in Interrupt_Management.Signal_ID loop
+ if System.Interrupt_Management.Keep_Unmasked (J) then
+ Result := sigaddset (Unblocked_Signal_Mask'Access, Signal (J));
+ pragma Assert (Result = 0);
+ end if;
+ end loop;
+
+ Environment_Task_ID := Environment_Task;
+
+ -- Initialize the lock used to synchronize chain of all ATCBs.
+
+ Initialize_Lock (Single_RTS_Lock'Access, RTS_Lock_Level);
+
+ Enter_Task (Environment_Task);
+ end Initialize;
+
+end System.Task_Primitives.Operations;
diff --git a/gcc/ada/s-tasinf-irix-athread.adb b/gcc/ada/s-tasinf-irix-athread.adb
new file mode 100644
index 00000000000..5413ebf8830
--- /dev/null
+++ b/gcc/ada/s-tasinf-irix-athread.adb
@@ -0,0 +1,312 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ I N F O --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2004 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package body contains the routines associated with the implementation
+-- of the Task_Info pragma.
+
+-- This is the SGI specific version of this module.
+
+with Interfaces.C;
+with System.OS_Interface;
+with System;
+with Unchecked_Conversion;
+
+package body System.Task_Info is
+
+ use System.OS_Interface;
+ use type Interfaces.C.int;
+
+ function To_Resource_T is new
+ Unchecked_Conversion (Resource_Vector_T, resource_t);
+
+ MP_NPROCS : constant := 1;
+
+ function Sysmp (Cmd : Integer) return Integer;
+ pragma Import (C, Sysmp);
+
+ function Num_Processors (Cmd : Integer := MP_NPROCS) return Integer
+ renames Sysmp;
+
+ function Geteuid return Integer;
+ pragma Import (C, Geteuid);
+
+ Locking_Map : constant array (Page_Locking) of Interfaces.C.int :=
+ (NOLOCK => 0,
+ PROCLOCK => 1,
+ TXTLOCK => 2,
+ DATLOCK => 4);
+
+ -------------------------------
+ -- Resource_Vector_Functions --
+ -------------------------------
+
+ package body Resource_Vector_Functions is
+
+ ---------
+ -- "+" --
+ ---------
+
+ function "+" (R : Resource_T) return Resource_Vector_T is
+ Result : Resource_Vector_T := NO_RESOURCES;
+ begin
+ Result (Resource_T'Pos (R)) := True;
+ return Result;
+ end "+";
+
+ function "+" (R1, R2 : Resource_T) return Resource_Vector_T is
+ Result : Resource_Vector_T := NO_RESOURCES;
+ begin
+ Result (Resource_T'Pos (R1)) := True;
+ Result (Resource_T'Pos (R2)) := True;
+ return Result;
+ end "+";
+
+ function "+"
+ (R : Resource_T;
+ S : Resource_Vector_T) return Resource_Vector_T
+ is
+ Result : Resource_Vector_T := S;
+ begin
+ Result (Resource_T'Pos (R)) := True;
+ return Result;
+ end "+";
+
+ function "+"
+ (S : Resource_Vector_T;
+ R : Resource_T) return Resource_Vector_T
+ is
+ Result : Resource_Vector_T := S;
+ begin
+ Result (Resource_T'Pos (R)) := True;
+ return Result;
+ end "+";
+
+ function "+" (S1, S2 : Resource_Vector_T) return Resource_Vector_T is
+ Result : Resource_Vector_T;
+ begin
+ Result := S1 or S2;
+ return Result;
+ end "+";
+
+ function "-"
+ (S : Resource_Vector_T;
+ R : Resource_T) return Resource_Vector_T
+ is
+ Result : Resource_Vector_T := S;
+ begin
+ Result (Resource_T'Pos (R)) := False;
+ return Result;
+ end "-";
+
+ end Resource_Vector_Functions;
+
+ ---------------
+ -- New_Sproc --
+ ---------------
+
+ function New_Sproc (Attr : Sproc_Attributes) return sproc_t is
+ Sproc_Attr : aliased sproc_attr_t;
+ Sproc : aliased sproc_t;
+ Status : int;
+
+ begin
+ Status := sproc_attr_init (Sproc_Attr'Unrestricted_Access);
+
+ if Status = 0 then
+ Status := sproc_attr_setresources
+ (Sproc_Attr'Unrestricted_Access,
+ To_Resource_T (Attr.Sproc_Resources));
+
+ if Attr.CPU /= ANY_CPU then
+ if Attr.CPU > Num_Processors then
+ raise Invalid_CPU_Number;
+ end if;
+
+ Status := sproc_attr_setcpu
+ (Sproc_Attr'Unrestricted_Access,
+ int (Attr.CPU));
+ end if;
+
+ if Attr.Resident /= NOLOCK then
+ if Geteuid /= 0 then
+ raise Permission_Error;
+ end if;
+
+ Status := sproc_attr_setresident
+ (Sproc_Attr'Unrestricted_Access,
+ Locking_Map (Attr.Resident));
+ end if;
+
+ if Attr.NDPRI /= NDP_NONE then
+
+-- ??? why is this commented out, should it be removed ?
+-- if Geteuid /= 0 then
+-- raise Permission_Error;
+-- end if;
+
+ Status :=
+ sproc_attr_setprio
+ (Sproc_Attr'Unrestricted_Access, int (Attr.NDPRI));
+ end if;
+
+ Status :=
+ sproc_create
+ (Sproc'Unrestricted_Access,
+ Sproc_Attr'Unrestricted_Access,
+ null,
+ System.Null_Address);
+
+ if Status /= 0 then
+ Status := sproc_attr_destroy (Sproc_Attr'Unrestricted_Access);
+ raise Sproc_Create_Error;
+ end if;
+
+ Status := sproc_attr_destroy (Sproc_Attr'Unrestricted_Access);
+ end if;
+
+ if Status /= 0 then
+ raise Sproc_Create_Error;
+ end if;
+
+ return Sproc;
+ end New_Sproc;
+
+ ---------------
+ -- New_Sproc --
+ ---------------
+
+ function New_Sproc
+ (Sproc_Resources : Resource_Vector_T := NO_RESOURCES;
+ CPU : CPU_Number := ANY_CPU;
+ Resident : Page_Locking := NOLOCK;
+ NDPRI : Non_Degrading_Priority := NDP_NONE) return sproc_t
+ is
+ Attr : constant Sproc_Attributes :=
+ (Sproc_Resources, CPU, Resident, NDPRI);
+ begin
+ return New_Sproc (Attr);
+ end New_Sproc;
+
+ -------------------------------
+ -- Unbound_Thread_Attributes --
+ -------------------------------
+
+ function Unbound_Thread_Attributes
+ (Thread_Resources : Resource_Vector_T := NO_RESOURCES;
+ Thread_Timeslice : Duration := 0.0) return Thread_Attributes
+ is
+ begin
+ return (False, Thread_Resources, Thread_Timeslice);
+ end Unbound_Thread_Attributes;
+
+ -----------------------------
+ -- Bound_Thread_Attributes --
+ -----------------------------
+
+ function Bound_Thread_Attributes
+ (Thread_Resources : Resource_Vector_T := NO_RESOURCES;
+ Thread_Timeslice : Duration := 0.0;
+ Sproc : sproc_t)
+ return Thread_Attributes
+ is
+ begin
+ return (True, Thread_Resources, Thread_Timeslice, Sproc);
+ end Bound_Thread_Attributes;
+
+ -----------------------------
+ -- Bound_Thread_Attributes --
+ -----------------------------
+
+ function Bound_Thread_Attributes
+ (Thread_Resources : Resource_Vector_T := NO_RESOURCES;
+ Thread_Timeslice : Duration := 0.0;
+ Sproc_Resources : Resource_Vector_T := NO_RESOURCES;
+ CPU : CPU_Number := ANY_CPU;
+ Resident : Page_Locking := NOLOCK;
+ NDPRI : Non_Degrading_Priority := NDP_NONE)
+ return Thread_Attributes
+ is
+ Sproc : constant sproc_t := New_Sproc
+ (Sproc_Resources, CPU, Resident, NDPRI);
+ begin
+ return (True, Thread_Resources, Thread_Timeslice, Sproc);
+ end Bound_Thread_Attributes;
+
+ -----------------------------------
+ -- New_Unbound_Thread_Attributes --
+ -----------------------------------
+
+ function New_Unbound_Thread_Attributes
+ (Thread_Resources : Resource_Vector_T := NO_RESOURCES;
+ Thread_Timeslice : Duration := 0.0) return Task_Info_Type
+ is
+ begin
+ return new Thread_Attributes'
+ (False, Thread_Resources, Thread_Timeslice);
+ end New_Unbound_Thread_Attributes;
+
+ ---------------------------------
+ -- New_Bound_Thread_Attributes --
+ ---------------------------------
+
+ function New_Bound_Thread_Attributes
+ (Thread_Resources : Resource_Vector_T := NO_RESOURCES;
+ Thread_Timeslice : Duration := 0.0;
+ Sproc : sproc_t) return Task_Info_Type
+ is
+ begin
+ return new Thread_Attributes'
+ (True, Thread_Resources, Thread_Timeslice, Sproc);
+ end New_Bound_Thread_Attributes;
+
+ ---------------------------------
+ -- New_Bound_Thread_Attributes --
+ ---------------------------------
+
+ function New_Bound_Thread_Attributes
+ (Thread_Resources : Resource_Vector_T := NO_RESOURCES;
+ Thread_Timeslice : Duration := 0.0;
+ Sproc_Resources : Resource_Vector_T := NO_RESOURCES;
+ CPU : CPU_Number := ANY_CPU;
+ Resident : Page_Locking := NOLOCK;
+ NDPRI : Non_Degrading_Priority := NDP_NONE)
+ return Task_Info_Type
+ is
+ Sproc : constant sproc_t := New_Sproc
+ (Sproc_Resources, CPU, Resident, NDPRI);
+ begin
+ return new Thread_Attributes'
+ (True, Thread_Resources, Thread_Timeslice, Sproc);
+ end New_Bound_Thread_Attributes;
+
+end System.Task_Info;
diff --git a/gcc/ada/s-tasinf-irix-athread.ads b/gcc/ada/s-tasinf-irix-athread.ads
new file mode 100644
index 00000000000..f986bf934af
--- /dev/null
+++ b/gcc/ada/s-tasinf-irix-athread.ads
@@ -0,0 +1,274 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ I N F O --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1992-2004 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains the definitions and routines associated with the
+-- implementation and use of the Task_Info pragma. It is specialized
+-- appropriately for targets that make use of this pragma.
+
+-- Note: the compiler generates direct calls to this interface, via Rtsfind.
+-- Any changes to this interface may require corresponding compiler changes.
+
+-- This unit may be used directly from an application program by providing
+-- an appropriate WITH, and the interface can be expected to remain stable.
+
+-- This is the SGI (libathread) specific version of this module.
+
+with System.OS_Interface;
+
+package System.Task_Info is
+ pragma Elaborate_Body;
+ -- To ensure that a body is allowed
+
+ ---------------------------------------------------------
+ -- Binding of Tasks to sprocs and sprocs to processors --
+ ---------------------------------------------------------
+
+ -- The SGI implementation of the GNU Low-Level Interface (GNULLI)
+ -- implements each Ada task as a Posix thread (Pthread). The SGI
+ -- Pthread library distributes threads across one or more processes
+ -- that are members of a common share group. Irix distributes
+ -- processes across the available CPUs on a given machine. The
+ -- pragma Task_Info provides the mechanism to control the distribution
+ -- of tasks to sprocs, and sprocs to processors.
+
+ -- Each thread has a number of attributes that dictate it's scheduling.
+ -- These attributes are:
+
+ -- Bound_To_Sproc: whether the thread is bound to a specific sproc
+ -- for its entire lifetime.
+
+ -- Timeslice: Amount of time that a thread is allowed to execute
+ -- before the system yeilds control to another thread
+ -- of equal priority.
+
+ -- Resource_Vector: A bitmask used to control the binding of threads
+ -- to sprocs.
+ --
+
+ -- Each share group process (sproc)
+
+ -- The Task_Info pragma:
+
+ -- pragma Task_Info (EXPRESSION);
+
+ -- allows the specification on a task by task basis of a value of type
+ -- System.Task_Info.Task_Info_Type to be passed to a task when it is
+ -- created. The specification of this type, and the effect on the task
+ -- that is created is target dependent.
+
+ -- The Task_Info pragma appears within a task definition (compare the
+ -- definition and implementation of pragma Priority). If no such pragma
+ -- appears, then the value Task_Info_Unspecified is passed. If a pragma
+ -- is present, then it supplies an alternative value. If the argument of
+ -- the pragma is a discriminant reference, then the value can be set on
+ -- a task by task basis by supplying the appropriate discriminant value.
+
+ -- Note that this means that the type used for Task_Info_Type must be
+ -- suitable for use as a discriminant (i.e. a scalar or access type).
+
+ ----------------------
+ -- Resource Vectors --
+ ----------------------
+
+ -- <discussion>
+
+ type Resource_Vector_T is array (0 .. 31) of Boolean;
+ pragma Pack (Resource_Vector_T);
+
+ NO_RESOURCES : constant Resource_Vector_T := (others => False);
+
+ generic
+ type Resource_T is (<>);
+ -- Discrete type up to 32 entries
+
+ package Resource_Vector_Functions is
+ function "+"
+ (R : Resource_T) return Resource_Vector_T;
+
+ function "+"
+ (R1 : Resource_T;
+ R2 : Resource_T) return Resource_Vector_T;
+
+ function "+"
+ (R : Resource_T;
+ S : Resource_Vector_T) return Resource_Vector_T;
+
+ function "+"
+ (S : Resource_Vector_T;
+ R : Resource_T) return Resource_Vector_T;
+
+ function "+"
+ (S1 : Resource_Vector_T;
+ S2 : Resource_Vector_T) return Resource_Vector_T;
+
+ function "-"
+ (S : Resource_Vector_T;
+ R : Resource_T) return Resource_Vector_T;
+ end Resource_Vector_Functions;
+
+ ----------------------
+ -- Sproc Attributes --
+ ----------------------
+
+ subtype sproc_t is System.OS_Interface.sproc_t;
+
+ subtype CPU_Number is Integer range -1 .. Integer'Last;
+
+ ANY_CPU : constant CPU_Number := CPU_Number'First;
+
+ type Non_Degrading_Priority is range 0 .. 255;
+ -- Specification of IRIX Non Degrading Priorities.
+ --
+ -- WARNING: IRIX priorities have the reverse meaning of Ada priorities.
+ -- The lower the priority value, the greater the greater the
+ -- scheduling preference.
+ --
+ -- See the schedctl(2) man page for a complete discussion of non-degrading
+ -- priorities.
+
+ NDPHIMAX : constant Non_Degrading_Priority := 30;
+ NDPHIMIN : constant Non_Degrading_Priority := 39;
+ -- These priorities are higher than ALL normal user process priorities
+
+ subtype NDP_High is Non_Degrading_Priority range NDPHIMAX .. NDPHIMIN;
+
+ NDPNORMMAX : constant Non_Degrading_Priority := 40;
+ NDPNORMMIN : constant Non_Degrading_Priority := 127;
+ -- These priorities overlap normal user process priorities
+
+ subtype NDP_Norm is Non_Degrading_Priority range NDPNORMMAX .. NDPNORMMIN;
+
+ NDPLOMAX : constant Non_Degrading_Priority := 128;
+ NDPLOMIN : constant Non_Degrading_Priority := 254;
+ -- These priorities are below ALL normal user process priorities
+
+ NDP_NONE : constant Non_Degrading_Priority := 255;
+
+ subtype NDP_LOW is Non_Degrading_Priority range NDPLOMAX .. NDPLOMIN;
+
+ type Page_Locking is
+ (NOLOCK, -- Do not lock pages in memory
+ PROCLOCK, -- Lock text and data segments into memory (process lock)
+ TXTLOCK, -- Lock text segment into memory (text lock)
+ DATLOCK -- Lock data segment into memory (data lock)
+ );
+
+ type Sproc_Attributes is record
+ Sproc_Resources : Resource_Vector_T := NO_RESOURCES;
+ CPU : CPU_Number := ANY_CPU;
+ Resident : Page_Locking := NOLOCK;
+ NDPRI : Non_Degrading_Priority := NDP_NONE;
+-- ??? why is that commented out, should it be removed ?
+-- Sproc_Slice : Duration := 0.0;
+-- Deadline_Period : Duration := 0.0;
+-- Deadline_Alloc : Duration := 0.0;
+ end record;
+
+ Default_Sproc_Attributes : constant Sproc_Attributes :=
+ (NO_RESOURCES, ANY_CPU, NOLOCK, NDP_NONE);
+
+ function New_Sproc (Attr : Sproc_Attributes) return sproc_t;
+ function New_Sproc
+ (Sproc_Resources : Resource_Vector_T := NO_RESOURCES;
+ CPU : CPU_Number := ANY_CPU;
+ Resident : Page_Locking := NOLOCK;
+ NDPRI : Non_Degrading_Priority := NDP_NONE) return sproc_t;
+ -- Allocates a sproc_t control structure and creates the
+ -- corresponding sproc.
+
+ Invalid_CPU_Number : exception;
+ Permission_Error : exception;
+ Sproc_Create_Error : exception;
+
+ -----------------------
+ -- Thread Attributes --
+ -----------------------
+
+ type Thread_Attributes (Bound_To_Sproc : Boolean) is record
+ Thread_Resources : Resource_Vector_T := NO_RESOURCES;
+
+ Thread_Timeslice : Duration := 0.0;
+
+ case Bound_To_Sproc is
+ when False =>
+ null;
+ when True =>
+ Sproc : sproc_t;
+ end case;
+ end record;
+
+ Default_Thread_Attributes : constant Thread_Attributes :=
+ (False, NO_RESOURCES, 0.0);
+
+ function Unbound_Thread_Attributes
+ (Thread_Resources : Resource_Vector_T := NO_RESOURCES;
+ Thread_Timeslice : Duration := 0.0) return Thread_Attributes;
+
+ function Bound_Thread_Attributes
+ (Thread_Resources : Resource_Vector_T := NO_RESOURCES;
+ Thread_Timeslice : Duration := 0.0;
+ Sproc : sproc_t) return Thread_Attributes;
+
+ function Bound_Thread_Attributes
+ (Thread_Resources : Resource_Vector_T := NO_RESOURCES;
+ Thread_Timeslice : Duration := 0.0;
+ Sproc_Resources : Resource_Vector_T := NO_RESOURCES;
+ CPU : CPU_Number := ANY_CPU;
+ Resident : Page_Locking := NOLOCK;
+ NDPRI : Non_Degrading_Priority := NDP_NONE)
+ return Thread_Attributes;
+
+ type Task_Info_Type is access all Thread_Attributes;
+
+ function New_Unbound_Thread_Attributes
+ (Thread_Resources : Resource_Vector_T := NO_RESOURCES;
+ Thread_Timeslice : Duration := 0.0)
+ return Task_Info_Type;
+
+ function New_Bound_Thread_Attributes
+ (Thread_Resources : Resource_Vector_T := NO_RESOURCES;
+ Thread_Timeslice : Duration := 0.0;
+ Sproc : sproc_t) return Task_Info_Type;
+
+ function New_Bound_Thread_Attributes
+ (Thread_Resources : Resource_Vector_T := NO_RESOURCES;
+ Thread_Timeslice : Duration := 0.0;
+ Sproc_Resources : Resource_Vector_T := NO_RESOURCES;
+ CPU : CPU_Number := ANY_CPU;
+ Resident : Page_Locking := NOLOCK;
+ NDPRI : Non_Degrading_Priority := NDP_NONE)
+ return Task_Info_Type;
+
+ Unspecified_Task_Info : constant Task_Info_Type := null;
+
+end System.Task_Info;
diff --git a/gcc/ada/s-tasinf-irix.ads b/gcc/ada/s-tasinf-irix.ads
new file mode 100644
index 00000000000..2954f8ee66c
--- /dev/null
+++ b/gcc/ada/s-tasinf-irix.ads
@@ -0,0 +1,136 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ I N F O --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1992-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains the definitions and routines associated with the
+-- implementation and use of the Task_Info pragma. It is specialized
+-- appropriately for targets that make use of this pragma.
+
+-- Note: the compiler generates direct calls to this interface, via Rtsfind.
+-- Any changes to this interface may require corresponding compiler changes.
+
+-- This unit may be used directly from an application program by providing
+-- an appropriate WITH, and the interface can be expected to remain stable.
+
+-- This is the IRIX (kernel threads) version of this package
+
+with Interfaces.C;
+with System.OS_Interface;
+
+package System.Task_Info is
+ pragma Elaborate_Body;
+ -- To ensure that a body is allowed
+
+ package OSI renames System.OS_Interface;
+
+ -----------------------------------------
+ -- Implementation of Task_Info Feature --
+ -----------------------------------------
+
+ -- Pragma Task_Info allows an application to set the underlying
+ -- pthread scheduling attributes for a specific task.
+
+ ------------------
+ -- Declarations --
+ ------------------
+
+ type Thread_Scheduling_Scope is
+ (PTHREAD_SCOPE_PROCESS, PTHREAD_SCOPE_SYSTEM);
+
+ for Thread_Scheduling_Scope'Size use Interfaces.C.int'Size;
+
+ type Thread_Scheduling_Inheritance is
+ (PTHREAD_EXPLICIT_SCHED, PTHREAD_INHERIT_SCHED);
+
+ for Thread_Scheduling_Inheritance'Size use Interfaces.C.int'Size;
+
+ type Thread_Scheduling_Policy is
+ (SCHED_FIFO, -- The first-in-first-out real-time policy
+ SCHED_RR, -- The round-robin real-time scheduling policy
+ SCHED_TS); -- The timeshare earnings based scheduling policy
+
+ for Thread_Scheduling_Policy'Size use Interfaces.C.int'Size;
+ for Thread_Scheduling_Policy use
+ (SCHED_FIFO => 1,
+ SCHED_RR => 2,
+ SCHED_TS => 3);
+
+ function SCHED_OTHER return Thread_Scheduling_Policy renames SCHED_TS;
+
+ No_Specified_Priority : constant := -1;
+
+ subtype Thread_Scheduling_Priority is Integer range
+ No_Specified_Priority .. 255;
+
+ function Min (Policy : Interfaces.C.int) return Interfaces.C.int
+ renames OSI.sched_get_priority_min;
+
+ function Max (Policy : Interfaces.C.int) return Interfaces.C.int
+ renames OSI.sched_get_priority_max;
+
+ subtype FIFO_Priority is Thread_Scheduling_Priority range
+ Thread_Scheduling_Priority (Min (OSI.SCHED_FIFO)) ..
+ Thread_Scheduling_Priority (Max (OSI.SCHED_FIFO));
+
+ subtype RR_Priority is Thread_Scheduling_Priority range
+ Thread_Scheduling_Priority (Min (OSI.SCHED_RR)) ..
+ Thread_Scheduling_Priority (Max (OSI.SCHED_RR));
+
+ subtype TS_Priority is Thread_Scheduling_Priority range
+ Thread_Scheduling_Priority (Min (OSI.SCHED_TS)) ..
+ Thread_Scheduling_Priority (Max (OSI.SCHED_TS));
+
+ subtype OTHER_Priority is Thread_Scheduling_Priority range
+ Thread_Scheduling_Priority (Min (OSI.SCHED_OTHER)) ..
+ Thread_Scheduling_Priority (Max (OSI.SCHED_OTHER));
+
+ subtype CPU_Number is Integer range -1 .. Integer'Last;
+ ANY_CPU : constant CPU_Number := CPU_Number'First;
+
+ type Thread_Attributes is record
+ Scope : Thread_Scheduling_Scope := PTHREAD_SCOPE_PROCESS;
+ Inheritance : Thread_Scheduling_Inheritance := PTHREAD_EXPLICIT_SCHED;
+ Policy : Thread_Scheduling_Policy := SCHED_RR;
+ Priority : Thread_Scheduling_Priority := No_Specified_Priority;
+ Runon_CPU : CPU_Number := ANY_CPU;
+ end record;
+
+ Default_Thread_Attributes : constant Thread_Attributes :=
+ (PTHREAD_SCOPE_PROCESS, PTHREAD_EXPLICIT_SCHED, SCHED_RR,
+ No_Specified_Priority, ANY_CPU);
+
+ type Task_Info_Type is access all Thread_Attributes;
+
+ Unspecified_Task_Info : constant Task_Info_Type := null;
+ -- Value passed to task in the absence of a Task_Info pragma
+
+end System.Task_Info;
diff --git a/gcc/ada/s-tasinf-solaris.adb b/gcc/ada/s-tasinf-solaris.adb
new file mode 100644
index 00000000000..859bcd082ec
--- /dev/null
+++ b/gcc/ada/s-tasinf-solaris.adb
@@ -0,0 +1,73 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ I N F O --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2002 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package body contains the routines associated with the implementation
+-- of the Task_Info pragma.
+
+-- This is the Solaris (native) version of this module.
+
+package body System.Task_Info is
+
+ function Unbound_Thread_Attributes return Thread_Attributes is
+ begin
+ return (False, False);
+ end Unbound_Thread_Attributes;
+
+ function Bound_Thread_Attributes return Thread_Attributes is
+ begin
+ return (False, True);
+ end Bound_Thread_Attributes;
+
+ function Bound_Thread_Attributes (CPU : CPU_Number)
+ return Thread_Attributes is
+ begin
+ return (True, True, CPU);
+ end Bound_Thread_Attributes;
+
+ function New_Unbound_Thread_Attributes return Task_Info_Type is
+ begin
+ return new Thread_Attributes'(False, False);
+ end New_Unbound_Thread_Attributes;
+
+ function New_Bound_Thread_Attributes return Task_Info_Type is
+ begin
+ return new Thread_Attributes'(False, True);
+ end New_Bound_Thread_Attributes;
+
+ function New_Bound_Thread_Attributes (CPU : CPU_Number)
+ return Task_Info_Type is
+ begin
+ return new Thread_Attributes'(True, True, CPU);
+ end New_Bound_Thread_Attributes;
+
+end System.Task_Info;
diff --git a/gcc/ada/s-tasinf-solaris.ads b/gcc/ada/s-tasinf-solaris.ads
new file mode 100644
index 00000000000..ded456effa1
--- /dev/null
+++ b/gcc/ada/s-tasinf-solaris.ads
@@ -0,0 +1,142 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ I N F O --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1992-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains the definitions and routines associated with the
+-- implementation and use of the Task_Info pragma. It is specialized
+-- appropriately for targets that make use of this pragma.
+
+-- Note: the compiler generates direct calls to this interface, via Rtsfind.
+-- Any changes to this interface may require corresponding compiler changes.
+
+-- This unit may be used directly from an application program by providing
+-- an appropriate WITH, and the interface can be expected to remain stable.
+
+-- This is the Solaris (native) version of this module.
+
+with System.OS_Interface;
+
+package System.Task_Info is
+ pragma Elaborate_Body;
+ -- To ensure that a body is allowed
+
+ -----------------------------------------------------
+ -- Binding of Tasks to LWPs and LWPs to processors --
+ -----------------------------------------------------
+
+ -- The Solaris implementation of the GNU Low-Level Interface (GNULLI)
+ -- implements each Ada task as a Solaris thread. The Solaris thread
+ -- library distributes threads across one or more LWPs (Light Weight
+ -- Process) that are members of the same process. Solaris distributes
+ -- processes and LWPs across the available CPUs on a given machine. The
+ -- pragma Task_Info provides the mechanism to control the distribution
+ -- of tasks to LWPs, and LWPs to processors.
+
+ -- Each thread has a number of attributes that dictate it's scheduling.
+ -- These attributes are:
+ --
+ -- New_LWP: whether a new LWP is created for this thread.
+ --
+ -- Bound_To_LWP: whether the thread is bound to a specific LWP
+ -- for its entire lifetime.
+ --
+ -- CPU: the CPU number associated to the LWP
+ --
+
+ -- The Task_Info pragma:
+
+ -- pragma Task_Info (EXPRESSION);
+
+ -- allows the specification on a task by task basis of a value of type
+ -- System.Task_Info.Task_Info_Type to be passed to a task when it is
+ -- created. The specification of this type, and the effect on the task
+ -- that is created is target dependent.
+
+ -- The Task_Info pragma appears within a task definition (compare the
+ -- definition and implementation of pragma Priority). If no such pragma
+ -- appears, then the value Task_Info_Unspecified is passed. If a pragma
+ -- is present, then it supplies an alternative value. If the argument of
+ -- the pragma is a discriminant reference, then the value can be set on
+ -- a task by task basis by supplying the appropriate discriminant value.
+
+ -- Note that this means that the type used for Task_Info_Type must be
+ -- suitable for use as a discriminant (i.e. a scalar or access type).
+
+ -----------------------
+ -- Thread Attributes --
+ -----------------------
+
+ subtype CPU_Number is System.OS_Interface.processorid_t;
+
+ CPU_UNCHANGED : constant CPU_Number := System.OS_Interface.PBIND_QUERY;
+ -- Do not bind the LWP to a specific processor
+
+ ANY_CPU : constant CPU_Number := System.OS_Interface.PBIND_NONE;
+ -- Bind the LWP to any processor
+
+ Invalid_CPU_Number : exception;
+
+ type Thread_Attributes (New_LWP : Boolean) is record
+ Bound_To_LWP : Boolean := True;
+ case New_LWP is
+ when False =>
+ null;
+ when True =>
+ CPU : CPU_Number := CPU_UNCHANGED;
+ end case;
+ end record;
+
+ Default_Thread_Attributes : constant Thread_Attributes := (False, True);
+
+ function Unbound_Thread_Attributes
+ return Thread_Attributes;
+
+ function Bound_Thread_Attributes
+ return Thread_Attributes;
+
+ function Bound_Thread_Attributes (CPU : CPU_Number)
+ return Thread_Attributes;
+
+ type Task_Info_Type is access all Thread_Attributes;
+
+ function New_Unbound_Thread_Attributes
+ return Task_Info_Type;
+
+ function New_Bound_Thread_Attributes
+ return Task_Info_Type;
+
+ function New_Bound_Thread_Attributes (CPU : CPU_Number)
+ return Task_Info_Type;
+
+ Unspecified_Task_Info : constant Task_Info_Type := null;
+
+end System.Task_Info;
diff --git a/gcc/ada/s-tasinf-tru64.ads b/gcc/ada/s-tasinf-tru64.ads
new file mode 100644
index 00000000000..179f469c37c
--- /dev/null
+++ b/gcc/ada/s-tasinf-tru64.ads
@@ -0,0 +1,111 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ I N F O --
+-- --
+-- S p e c --
+-- (Compiler Interface) --
+-- --
+-- Copyright (C) 1998-2003 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains the definitions and routines associated with the
+-- implementation and use of the Task_Info pragma. It is specialized
+-- appropriately for targets that make use of this pragma.
+
+-- Note: the compiler generates direct calls to this interface, via Rtsfind.
+-- Any changes to this interface may require corresponding compiler changes.
+
+-- This unit may be used directly from an application program by providing
+-- an appropriate WITH, and the interface can be expected to remain stable.
+
+-- This is a DEC Unix 4.0d version of this package.
+
+package System.Task_Info is
+ pragma Elaborate_Body;
+ -- To ensure that a body is allowed
+
+ -----------------------------------------
+ -- Implementation of Task_Info Feature --
+ -----------------------------------------
+
+ -- The Task_Info pragma:
+
+ -- pragma Task_Info (EXPRESSION);
+
+ -- allows the specification on a task by task basis of a value of type
+ -- System.Task_Info.Task_Info_Type to be passed to a task when it is
+ -- created. The specification of this type, and the effect on the task
+ -- that is created is target dependent.
+
+ -- The Task_Info pragma appears within a task definition (compare the
+ -- definition and implementation of pragma Priority). If no such pragma
+ -- appears, then the value Task_Info_Unspecified is passed. If a pragma
+ -- is present, then it supplies an alternative value. If the argument of
+ -- the pragma is a discriminant reference, then the value can be set on
+ -- a task by task basis by supplying the appropriate discriminant value.
+
+ -- Note that this means that the type used for Task_Info_Type must be
+ -- suitable for use as a discriminant (i.e. a scalar or access type).
+
+ ------------------
+ -- Declarations --
+ ------------------
+
+ type Scope_Type is
+ (Process_Scope,
+ -- Contend only with threads in same process
+
+ System_Scope,
+ -- Contend with all threads on same CPU
+
+ Default_Scope);
+
+ type Thread_Attributes is record
+ Bind_To_Cpu_Number : Integer;
+ -- -1: Do nothing
+ -- 0: Unbind
+ -- 1-N: Bind all unbound threads to this CPU
+
+ Contention_Scope : Scope_Type;
+ end record;
+
+ type Task_Info_Type is access all Thread_Attributes;
+ -- Type used for passing information to task create call, using the
+ -- Task_Info pragma. This type may be specialized for individual
+ -- implementations, but it must be a type that can be used as a
+ -- discriminant (i.e. a scalar or access type).
+
+ Unspecified_Thread_Attribute : aliased Thread_Attributes :=
+ Thread_Attributes'(-1, Default_Scope);
+
+ Unspecified_Task_Info : constant Task_Info_Type :=
+ Unspecified_Thread_Attribute'Access;
+ -- Value passed to task in the absence of a Task_Info pragma
+ -- Don't call new here because the tasking run time has not been
+ -- elaborated yet, so calling Task_Lock is unsafe.
+
+end System.Task_Info;
diff --git a/gcc/ada/s-taspri-dummy.ads b/gcc/ada/s-taspri-dummy.ads
new file mode 100644
index 00000000000..6e6025c589d
--- /dev/null
+++ b/gcc/ada/s-taspri-dummy.ads
@@ -0,0 +1,55 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-2000 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- --
+-- 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, 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, --
+-- 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 is a no tasking version of this package
+
+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.
+
+package System.Task_Primitives is
+ pragma Preelaborate;
+
+ type Lock is new Integer;
+
+ type RTS_Lock is new Integer;
+
+ type Task_Body_Access is access procedure;
+
+ type Private_Data is record
+ Thread : aliased Integer;
+ CV : aliased Integer;
+ L : aliased RTS_Lock;
+ end record;
+
+end System.Task_Primitives;
diff --git a/gcc/ada/s-taspri-hpux-dce.ads b/gcc/ada/s-taspri-hpux-dce.ads
new file mode 100644
index 00000000000..4f422c24271
--- /dev/null
+++ b/gcc/ada/s-taspri-hpux-dce.ads
@@ -0,0 +1,89 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-2000 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- --
+-- 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, 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, --
+-- 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 is a HP-UX version of this package.
+
+-- This package provides low-level support for most tasking features.
+
+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.OS_Interface;
+-- used for pthread_mutex_t
+-- pthread_cond_t
+-- pthread_t
+
+package System.Task_Primitives is
+
+ type Lock is limited private;
+ -- Should be used for implementation of protected objects.
+
+ type RTS_Lock is limited private;
+ -- Should be used inside the runtime system.
+ -- The difference between Lock and the RTS_Lock is that the later
+ -- one serves only as a semaphore so that do not check for
+ -- ceiling violations.
+
+ type Task_Body_Access is access procedure;
+ -- Pointer to the task body's entry point (or possibly a wrapper
+ -- declared local to the GNARL).
+
+ type Private_Data is limited private;
+ -- Any information that the GNULLI needs maintained on a per-task
+ -- basis. A component of this type is guaranteed to be included
+ -- in the Ada_Task_Control_Block.
+
+private
+ type Lock is record
+ L : aliased System.OS_Interface.pthread_mutex_t;
+ Priority : Integer;
+ Owner_Priority : Integer;
+ end record;
+
+ type RTS_Lock is new System.OS_Interface.pthread_mutex_t;
+ type Private_Data is record
+ Thread : aliased System.OS_Interface.pthread_t;
+ pragma Atomic (Thread);
+ -- Thread field may be updated by two different threads of control.
+ -- (See, Enter_Task and Create_Task in s-taprop.adb).
+ -- They put the same value (thr_self value). We do not want to
+ -- use lock on those operations and the only thing we have to
+ -- make sure is that they are updated in atomic fashion.
+
+ CV : aliased System.OS_Interface.pthread_cond_t;
+ L : aliased RTS_Lock;
+ -- protection for all components is lock L
+ end record;
+
+end System.Task_Primitives;
diff --git a/gcc/ada/s-taspri-linux.ads b/gcc/ada/s-taspri-linux.ads
new file mode 100644
index 00000000000..078ef3e0e8a
--- /dev/null
+++ b/gcc/ada/s-taspri-linux.ads
@@ -0,0 +1,96 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-2001 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- --
+-- 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, 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, --
+-- 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 is the GNU/Linux (GNU/LinuxThreads) version of this package.
+
+-- This package provides low-level support for most tasking features.
+
+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.OS_Interface;
+-- used for pthread_mutex_t
+-- pthread_cond_t
+-- pthread_t
+
+package System.Task_Primitives is
+
+ type Lock is limited private;
+ -- Should be used for implementation of protected objects.
+
+ type RTS_Lock is limited private;
+ -- Should be used inside the runtime system.
+ -- The difference between Lock and the RTS_Lock is that the later
+ -- one serves only as a semaphore so that do not check for
+ -- ceiling violations.
+
+ type Task_Body_Access is access procedure;
+ -- Pointer to the task body's entry point (or possibly a wrapper
+ -- declared local to the GNARL).
+
+ type Private_Data is limited private;
+ -- Any information that the GNULLI needs maintained on a per-task
+ -- basis. A component of this type is guaranteed to be included
+ -- in the Ada_Task_Control_Block.
+
+private
+
+ type Prio_Array_Type is array (System.Any_Priority) of Integer;
+
+ type Lock is record
+ L : aliased System.OS_Interface.pthread_mutex_t;
+ Ceiling : System.Any_Priority := System.Any_Priority'First;
+ Saved_Priority : System.Any_Priority := System.Any_Priority'First;
+ end record;
+
+ type RTS_Lock is new System.OS_Interface.pthread_mutex_t;
+ type Private_Data is record
+ Thread : aliased System.OS_Interface.pthread_t;
+ pragma Atomic (Thread);
+ -- Thread field may be updated by two different threads of control.
+ -- (See, Enter_Task and Create_Task in s-taprop.adb).
+ -- They put the same value (thr_self value). We do not want to
+ -- use lock on those operations and the only thing we have to
+ -- make sure is that they are updated in atomic fashion.
+
+ CV : aliased System.OS_Interface.pthread_cond_t;
+ L : aliased RTS_Lock;
+ -- protection for all components is lock L
+
+ Active_Priority : System.Any_Priority := System.Any_Priority'First;
+ -- Simulated active priority,
+ -- used only if Priority_Ceiling_Support is True.
+ end record;
+
+end System.Task_Primitives;
diff --git a/gcc/ada/s-taspri-lynxos.ads b/gcc/ada/s-taspri-lynxos.ads
new file mode 100644
index 00000000000..bf079fd34a3
--- /dev/null
+++ b/gcc/ada/s-taspri-lynxos.ads
@@ -0,0 +1,97 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2003, Ada Core Technologies --
+-- --
+-- 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, 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, --
+-- 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 is a LynxOS version of this package, derived from
+-- 7staspri.ads
+
+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.OS_Interface;
+-- used for pthread_mutex_t
+-- pthread_cond_t
+-- pthread_t
+
+package System.Task_Primitives is
+
+ type Lock is limited private;
+ -- Should be used for implementation of protected objects.
+
+ type RTS_Lock is limited private;
+ -- Should be used inside the runtime system.
+ -- The difference between Lock and the RTS_Lock is that the later
+ -- one serves only as a semaphore so that do not check for
+ -- ceiling violations.
+
+ type Task_Body_Access is access procedure;
+ -- Pointer to the task body's entry point (or possibly a wrapper
+ -- declared local to the GNARL).
+
+ type Private_Data is limited private;
+ -- Any information that the GNULLI needs maintained on a per-task
+ -- basis. A component of this type is guaranteed to be included
+ -- in the Ada_Task_Control_Block.
+
+private
+
+ type Lock is record
+ Mutex : aliased System.OS_Interface.pthread_mutex_t;
+ Ceiling : System.Any_Priority;
+ Saved_Priority : System.Any_Priority;
+ end record;
+
+ type RTS_Lock is new System.OS_Interface.pthread_mutex_t;
+
+ type Private_Data is record
+ Thread : aliased System.OS_Interface.pthread_t;
+ pragma Atomic (Thread);
+ -- Thread field may be updated by two different threads of control.
+ -- (See, Enter_Task and Create_Task in s-taprop.adb).
+ -- They put the same value (thr_self value). We do not want to
+ -- use lock on those operations and the only thing we have to
+ -- make sure is that they are updated in atomic fashion.
+
+ LWP : aliased System.Address;
+ -- The purpose of this field is to provide a better tasking support on
+ -- gdb. The order of the two first fields (Thread and LWP) is important.
+ -- On targets where lwp is not relevant, this is equivalent to Thread.
+
+ CV : aliased System.OS_Interface.pthread_cond_t;
+
+ L : aliased RTS_Lock;
+ -- Protection for all components is lock L
+ end record;
+
+end System.Task_Primitives;
diff --git a/gcc/ada/s-taspri-mingw.ads b/gcc/ada/s-taspri-mingw.ads
new file mode 100644
index 00000000000..01cde2c6910
--- /dev/null
+++ b/gcc/ada/s-taspri-mingw.ads
@@ -0,0 +1,97 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-2003 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- --
+-- 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, 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, --
+-- 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 is a NT (native) version of this package.
+
+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.OS_Interface;
+-- used for pthread_mutex_t
+-- pthread_cond_t
+-- pthread_t
+
+package System.Task_Primitives is
+
+ type Lock is limited private;
+ -- Should be used for implementation of protected objects.
+
+ type RTS_Lock is limited private;
+ -- Should be used inside the runtime system.
+ -- The difference between Lock and the RTS_Lock is that the later
+ -- one serves only as a semaphore so that do not check for
+ -- ceiling violations.
+
+ type Task_Body_Access is access procedure;
+ -- Pointer to the task body's entry point (or possibly a wrapper
+ -- declared local to the GNARL).
+
+ type Private_Data is limited private;
+ -- Any information that the GNULLI needs maintained on a per-task
+ -- basis. A component of this type is guaranteed to be included
+ -- in the Ada_Task_Control_Block.
+
+private
+
+ type Lock is record
+ Mutex : aliased System.OS_Interface.CRITICAL_SECTION;
+ Priority : Integer;
+ Owner_Priority : Integer;
+ end record;
+
+ type Condition_Variable is new System.OS_Interface.HANDLE;
+
+ type RTS_Lock is new System.OS_Interface.CRITICAL_SECTION;
+
+ type Private_Data is record
+ Thread : aliased System.OS_Interface.HANDLE;
+ pragma Atomic (Thread);
+ -- Thread field may be updated by two different threads of control.
+ -- (See, Enter_Task and Create_Task in s-taprop.adb).
+ -- They put the same value (thr_self value). We do not want to
+ -- use lock on those operations and the only thing we have to
+ -- make sure is that they are updated in atomic fashion.
+
+ Thread_Id : aliased System.OS_Interface.DWORD;
+ -- The purpose of this field is to provide a better tasking support
+ -- in gdb.
+
+ CV : aliased Condition_Variable;
+ -- Condition Variable used to implement Sleep/Wakeup
+
+ L : aliased RTS_Lock;
+ -- Protection for all components is lock L
+ end record;
+
+end System.Task_Primitives;
diff --git a/gcc/ada/s-taspri-os2.ads b/gcc/ada/s-taspri-os2.ads
new file mode 100644
index 00000000000..cb5b0295b13
--- /dev/null
+++ b/gcc/ada/s-taspri-os2.ads
@@ -0,0 +1,107 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2003, Ada Core Technologies --
+-- --
+-- 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, 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, --
+-- 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 is an OS/2 version of this package.
+
+-- This package provides low-level support for most tasking features.
+
+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 Interfaces.OS2Lib.Threads;
+with Interfaces.OS2Lib.Synchronization;
+
+package System.Task_Primitives is
+
+ pragma Preelaborate;
+
+-- type Lock is limited private;
+ -- Should be used for implementation of protected objects.
+
+-- type RTS_Lock is limited private;
+ -- Should be used inside the runtime system.
+ -- The difference between Lock and the RTS_Lock is that the later
+ -- one serves only as a semaphore so that do not check for
+ -- ceiling violations.
+
+ type Task_Body_Access is access procedure;
+ -- Pointer to the task body's entry point (or possibly a wrapper
+ -- declared local to the GNARL).
+
+-- type Private_Data is limited private;
+ -- Any information that the GNULLI needs maintained on a per-task
+ -- basis. A component of this type is guaranteed to be included
+ -- in the Ada_Task_Control_Block.
+
+-- private
+
+ type Lock is record
+ Mutex : aliased Interfaces.OS2Lib.Synchronization.HMTX;
+ Priority : Integer;
+ Owner_Priority : Integer;
+ Owner_ID : Address;
+ end record;
+
+ type RTS_Lock is new Lock;
+
+ type Private_Data is record
+ Thread : aliased Interfaces.OS2Lib.Threads.TID;
+ pragma Atomic (Thread);
+ -- Thread field may be updated by two different threads of control.
+ -- (See, Enter_Task and Create_Task in s-taprop.adb).
+ -- They put the same value (thr_self value). We do not want to
+ -- use lock on those operations and the only thing we have to
+ -- make sure is that they are updated in atomic fashion.
+
+ CV : aliased Interfaces.OS2Lib.Synchronization.HEV;
+
+ L : aliased RTS_Lock;
+ -- Protection for all components is lock L
+
+ Current_Priority : Integer := -1;
+ -- The Current_Priority is the actual priority of a thread.
+ -- This field is needed because it is only possible to set a
+ -- delta priority in OS/2. The only places where this field should
+ -- be set are Set_Priority, Create_Task and Initialize (Environment).
+
+ Wrapper : Interfaces.OS2Lib.Threads.PFNTHREAD;
+ -- This is the original wrapper passed by Operations.Create_Task.
+ -- When installing an exception handler in a thread, the thread
+ -- starts executing the Exception_Wrapper which calls Wrapper
+ -- when the handler has been installed. The handler is removed when
+ -- wrapper returns.
+ end record;
+
+end System.Task_Primitives;
diff --git a/gcc/ada/s-taspri-posix.ads b/gcc/ada/s-taspri-posix.ads
new file mode 100644
index 00000000000..1717cce47f5
--- /dev/null
+++ b/gcc/ada/s-taspri-posix.ads
@@ -0,0 +1,92 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-1994, Florida State University --
+-- Copyright (C) 1995-2003, Ada Core Technologies --
+-- --
+-- 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, 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, --
+-- 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 is a POSIX-like version of this package.
+-- Note: this file can only be used for POSIX compliant systems.
+
+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.OS_Interface;
+-- used for pthread_mutex_t
+-- pthread_cond_t
+-- pthread_t
+
+package System.Task_Primitives is
+
+ type Lock is limited private;
+ -- Should be used for implementation of protected objects.
+
+ type RTS_Lock is limited private;
+ -- Should be used inside the runtime system.
+ -- The difference between Lock and the RTS_Lock is that the later
+ -- one serves only as a semaphore so that do not check for
+ -- ceiling violations.
+
+ type Task_Body_Access is access procedure;
+ -- Pointer to the task body's entry point (or possibly a wrapper
+ -- declared local to the GNARL).
+
+ type Private_Data is limited private;
+ -- Any information that the GNULLI needs maintained on a per-task
+ -- basis. A component of this type is guaranteed to be included
+ -- in the Ada_Task_Control_Block.
+
+private
+
+ type Lock is new System.OS_Interface.pthread_mutex_t;
+ type RTS_Lock is new System.OS_Interface.pthread_mutex_t;
+
+ type Private_Data is record
+ Thread : aliased System.OS_Interface.pthread_t;
+ pragma Atomic (Thread);
+ -- Thread field may be updated by two different threads of control.
+ -- (See, Enter_Task and Create_Task in s-taprop.adb).
+ -- They put the same value (thr_self value). We do not want to
+ -- use lock on those operations and the only thing we have to
+ -- make sure is that they are updated in atomic fashion.
+
+ LWP : aliased System.Address;
+ -- The purpose of this field is to provide a better tasking support on
+ -- gdb. The order of the two first fields (Thread and LWP) is important.
+ -- On targets where lwp is not relevant, this is equivalent to Thread.
+
+ CV : aliased System.OS_Interface.pthread_cond_t;
+
+ L : aliased RTS_Lock;
+ -- Protection for all components is lock L
+ end record;
+
+end System.Task_Primitives;
diff --git a/gcc/ada/s-taspri-solaris.ads b/gcc/ada/s-taspri-solaris.ads
new file mode 100644
index 00000000000..335079b7cec
--- /dev/null
+++ b/gcc/ada/s-taspri-solaris.ads
@@ -0,0 +1,130 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1992-2004, 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- --
+-- 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, 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, --
+-- 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 is a Solaris version of this package
+
+-- This package provides low-level support for most tasking features.
+
+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.OS_Interface;
+-- used for mutex_t
+-- cond_t
+-- thread_t
+
+with Unchecked_Conversion;
+
+package System.Task_Primitives is
+ pragma Preelaborate;
+
+ type Lock is limited private;
+ type Lock_Ptr is access all Lock;
+ -- Should be used for implementation of protected objects
+
+ type RTS_Lock is limited private;
+ type RTS_Lock_Ptr is access all RTS_Lock;
+ -- Should be used inside the runtime system.
+ -- The difference between Lock and the RTS_Lock is that the later
+ -- one serves only as a semaphore so that do not check for
+ -- ceiling violations.
+
+ function To_Lock_Ptr is new Unchecked_Conversion (RTS_Lock_Ptr, Lock_Ptr);
+
+ type Task_Body_Access is access procedure;
+ -- Pointer to the task body's entry point (or possibly a wrapper
+ -- declared local to the GNARL).
+
+ type Private_Data is limited private;
+ -- Any information that the GNULLI needs maintained on a per-task
+ -- basis. A component of this type is guaranteed to be included
+ -- in the Ada_Task_Control_Block.
+
+private
+
+ type Private_Task_Serial_Number is mod 2 ** 64;
+ -- Used to give each task a unique serial number.
+
+ type Base_Lock is new System.OS_Interface.mutex_t;
+
+ type Owner_Int is new Integer;
+ for Owner_Int'Alignment use Standard'Maximum_Alignment;
+
+ type Owner_ID is access all Owner_Int;
+
+ function To_Owner_ID is
+ new Unchecked_Conversion (System.Address, Owner_ID);
+
+ type Lock is record
+ L : aliased Base_Lock;
+ Ceiling : System.Any_Priority := System.Any_Priority'First;
+ Saved_Priority : System.Any_Priority := System.Any_Priority'First;
+ Owner : Owner_ID;
+ Next : Lock_Ptr;
+ Level : Private_Task_Serial_Number := 0;
+ Buddy : Owner_ID;
+ Frozen : Boolean := False;
+ end record;
+
+ type RTS_Lock is new Lock;
+
+ -- Note that task support on gdb relies on the fact that the first
+ -- 2 fields of Private_Data are Thread and LWP.
+
+ type Private_Data is record
+ Thread : aliased System.OS_Interface.thread_t;
+ pragma Atomic (Thread);
+ -- Thread field may be updated by two different threads of control.
+ -- (See, Enter_Task and Create_Task in s-taprop.adb).
+ -- They put the same value (thr_self value). We do not want to
+ -- use lock on those operations and the only thing we have to
+ -- make sure is that they are updated in atomic fashion.
+
+ LWP : System.OS_Interface.lwpid_t;
+ -- The LWP id of the thread. Set by self in Enter_Task.
+
+ CV : aliased System.OS_Interface.cond_t;
+ L : aliased RTS_Lock;
+ -- Protection for all components is lock L
+
+ Active_Priority : System.Any_Priority := System.Any_Priority'First;
+ -- Simulated active priority,
+ -- used only if Priority_Ceiling_Support is True.
+
+ Locking : Lock_Ptr;
+ Locks : Lock_Ptr;
+ Wakeups : Natural := 0;
+ end record;
+
+end System.Task_Primitives;
diff --git a/gcc/ada/s-taspri-tru64.ads b/gcc/ada/s-taspri-tru64.ads
new file mode 100644
index 00000000000..2caf54b5f25
--- /dev/null
+++ b/gcc/ada/s-taspri-tru64.ads
@@ -0,0 +1,93 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-2000 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- --
+-- 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, 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, --
+-- 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 is the DEC Unix 4.0 version of this package.
+
+-- This package provides low-level support for most tasking features.
+
+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 Interfaces.C;
+-- used for int
+-- size_t
+
+with System.OS_Interface;
+-- used for pthread_mutex_t
+-- pthread_cond_t
+-- pthread_t
+
+package System.Task_Primitives is
+
+ type Lock is limited private;
+ -- Should be used for implementation of protected objects.
+
+ type RTS_Lock is limited private;
+ -- Should be used inside the runtime system.
+ -- The difference between Lock and the RTS_Lock is that the later
+ -- one serves only as a semaphore so that do not check for
+ -- ceiling violations.
+
+ type Task_Body_Access is access procedure;
+ -- Pointer to the task body's entry point (or possibly a wrapper
+ -- declared local to the GNARL).
+
+ type Private_Data is limited private;
+ -- Any information that the GNULLI needs maintained on a per-task
+ -- basis. A component of this type is guaranteed to be included
+ -- in the Ada_Task_Control_Block.
+
+private
+
+ type Lock is record
+ L : aliased System.OS_Interface.pthread_mutex_t;
+ Ceiling : Interfaces.C.int;
+ end record;
+
+ type RTS_Lock is new System.OS_Interface.pthread_mutex_t;
+ type Private_Data is record
+ Thread : aliased System.OS_Interface.pthread_t;
+ pragma Atomic (Thread);
+ -- Thread field may be updated by two different threads of control.
+ -- (See, Enter_Task and Create_Task in s-taprop.adb).
+ -- They put the same value (thr_self value). We do not want to
+ -- use lock on those operations and the only thing we have to
+ -- make sure is that they are updated in atomic fashion.
+
+ CV : aliased System.OS_Interface.pthread_cond_t;
+ L : aliased RTS_Lock;
+ -- protection for all components is lock L
+ end record;
+
+end System.Task_Primitives;
diff --git a/gcc/ada/s-taspri-vms.ads b/gcc/ada/s-taspri-vms.ads
new file mode 100644
index 00000000000..09179325c81
--- /dev/null
+++ b/gcc/ada/s-taspri-vms.ads
@@ -0,0 +1,105 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1991-2000 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- --
+-- 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, 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, --
+-- 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 is a OpenVMS/Alpha version of this package.
+
+-- This package provides low-level support for most tasking features.
+
+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 Interfaces.C;
+-- used for int
+-- size_t
+
+with System.OS_Interface;
+-- used for pthread_mutex_t
+-- pthread_cond_t
+-- pthread_t
+
+package System.Task_Primitives is
+
+ type Lock is limited private;
+ -- Should be used for implementation of protected objects.
+
+ type RTS_Lock is limited private;
+ -- Should be used inside the runtime system.
+ -- The difference between Lock and the RTS_Lock is that the later
+ -- one serves only as a semaphore so that do not check for
+ -- ceiling violations.
+
+ type Task_Body_Access is access procedure;
+ -- Pointer to the task body's entry point (or possibly a wrapper
+ -- declared local to the GNARL).
+
+ type Private_Data is limited private;
+ -- Any information that the GNULLI needs maintained on a per-task
+ -- basis. A component of this type is guaranteed to be included
+ -- in the Ada_Task_Control_Block.
+
+private
+
+ type Exc_Stack_T is array (0 .. 8192) of aliased Character;
+ for Exc_Stack_T'Alignment use Standard'Maximum_Alignment;
+ type Exc_Stack_Ptr_T is access all Exc_Stack_T;
+
+ type Lock is record
+ L : aliased System.OS_Interface.pthread_mutex_t;
+ Prio : Interfaces.C.int;
+ Prio_Save : Interfaces.C.int;
+ end record;
+
+ type RTS_Lock is new System.OS_Interface.pthread_mutex_t;
+ type Private_Data is record
+ Thread : aliased System.OS_Interface.pthread_t;
+ pragma Atomic (Thread);
+ -- Thread field may be updated by two different threads of control.
+ -- (See, Enter_Task and Create_Task in s-taprop.adb).
+ -- They put the same value (thr_self value). We do not want to
+ -- use lock on those operations and the only thing we have to
+ -- make sure is that they are updated in atomic fashion.
+
+ CV : aliased System.OS_Interface.pthread_cond_t;
+ L : aliased RTS_Lock;
+ -- protection for all components is lock L
+
+ Exc_Stack_Ptr : Exc_Stack_Ptr_T;
+ -- ??? This needs comments.
+
+ AST_Pending : Boolean;
+ -- Used to detect delay and sleep timeouts
+
+ end record;
+
+end System.Task_Primitives;
diff --git a/gcc/ada/s-taspri-vxworks.ads b/gcc/ada/s-taspri-vxworks.ads
new file mode 100644
index 00000000000..efd41ccd984
--- /dev/null
+++ b/gcc/ada/s-taspri-vxworks.ads
@@ -0,0 +1,95 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T A S K _ P R I M I T I V E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2001-2002 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- --
+-- 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, 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, --
+-- 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 is a VxWorks version of this package.
+
+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.OS_Interface;
+
+package System.Task_Primitives is
+
+ type Lock is limited private;
+ -- Should be used for implementation of protected objects.
+
+ type RTS_Lock is limited private;
+ -- Should be used inside the runtime system.
+ -- The difference between Lock and the RTS_Lock is that the later
+ -- one serves only as a semaphore so that do not check for
+ -- ceiling violations.
+
+ type Task_Body_Access is access procedure;
+ -- Pointer to the task body's entry point (or possibly a wrapper
+ -- declared local to the GNARL).
+
+ type Private_Data is limited private;
+ -- Any information that the GNULLI needs maintained on a per-task
+ -- basis. A component of this type is guaranteed to be included
+ -- in the Ada_Task_Control_Block.
+
+private
+
+ type Priority_Type is (Prio_None, Prio_Protect, Prio_Inherit);
+
+ type Lock is record
+ Mutex : System.OS_Interface.SEM_ID;
+ Protocol : Priority_Type;
+ Prio_Ceiling : System.OS_Interface.int;
+ -- priority ceiling of lock
+ end record;
+
+ type RTS_Lock is new Lock;
+
+ type Private_Data is record
+ Thread : aliased System.OS_Interface.t_id := 0;
+ pragma Atomic (Thread);
+ -- Thread field may be updated by two different threads of control.
+ -- (See, Enter_Task and Create_Task in s-taprop.adb).
+ -- They put the same value (thr_self value). We do not want to
+ -- use lock on those operations and the only thing we have to
+ -- make sure is that they are updated in atomic fashion.
+
+ LWP : aliased System.Address;
+ -- The purpose of this field is to provide a better tasking support on
+ -- gdb. The order of the two first fields (Thread and LWP) is important.
+ -- On targets where lwp is not relevant, this is equivalent to Thread.
+
+ CV : aliased System.OS_Interface.SEM_ID;
+
+ L : aliased RTS_Lock;
+ -- Protection for all components is lock L
+ end record;
+
+end System.Task_Primitives;
diff --git a/gcc/ada/s-tfsetr-default.adb b/gcc/ada/s-tfsetr-default.adb
new file mode 100644
index 00000000000..a8e166d04ed
--- /dev/null
+++ b/gcc/ada/s-tfsetr-default.adb
@@ -0,0 +1,313 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T R A C E S . S E N D --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2001-2002 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This version is for all targets, provided that System.IO.Put_Line is
+-- functional. It prints debug information to Standard Output
+
+with System.IO; use System.IO;
+with GNAT.Regpat; use GNAT.Regpat;
+
+----------------
+-- Send_Trace --
+----------------
+
+-- Prints debug information both in a human readable form
+-- and in the form they are sent from upper layers.
+
+separate (System.Traces.Format)
+procedure Send_Trace (Id : Trace_T; Info : String) is
+
+ type Param_Type is
+ (Name_Param,
+ Caller_Param,
+ Entry_Param,
+ Timeout_Param,
+ Acceptor_Param,
+ Parent_Param,
+ Number_Param);
+ -- Type of parameter found in the message
+
+ Info_Trace : String_Trace := Format_Trace (Info);
+
+ function Get_Param
+ (Input : String_Trace;
+ Param : Param_Type;
+ How_Many : Integer)
+ return String;
+ -- Extract a parameter from the given input string
+
+ ---------------
+ -- Get_Param --
+ ---------------
+
+ function Get_Param
+ (Input : String_Trace;
+ Param : Param_Type;
+ How_Many : Integer)
+ return String
+ is
+ pragma Unreferenced (How_Many);
+
+ Matches : Match_Array (1 .. 2);
+ begin
+ -- We need comments here ???
+
+ case Param is
+ when Name_Param =>
+ Match ("/N:([\w]+)", Input, Matches);
+
+ when Caller_Param =>
+ Match ("/C:([\w]+)", Input, Matches);
+
+ when Entry_Param =>
+ Match ("/E:([\s]*) +([0-9 ,]+)", Input, Matches);
+
+ when Timeout_Param =>
+ Match ("/T:([\s]*) +([0-9]+.[0-9]+)", Input, Matches);
+
+ when Acceptor_Param =>
+ Match ("/A:([\w]+)", Input, Matches);
+
+ when Parent_Param =>
+ Match ("/P:([\w]+)", Input, Matches);
+
+ when Number_Param =>
+ Match ("/#:([\s]*) +([0-9]+)", Input, Matches);
+ end case;
+
+ if Matches (1).First < Input'First then
+ return "";
+ end if;
+
+ case Param is
+ when Timeout_Param | Entry_Param | Number_Param =>
+ return Input (Matches (2).First .. Matches (2).Last);
+
+ when others =>
+ return Input (Matches (1).First .. Matches (1).Last);
+ end case;
+ end Get_Param;
+
+-- Start of processing for Send_Trace
+
+begin
+ New_Line;
+ Put_Line ("- Trace Debug Info ----------------");
+ Put ("Caught event Id : ");
+
+ case Id is
+ when M_Accept_Complete => Put ("M_Accept_Complete");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " completes accept on entry "
+ & Get_Param (Info_Trace, Entry_Param, 1) & " with "
+ & Get_Param (Info_Trace, Caller_Param, 1));
+
+ when M_Select_Else => Put ("M_Select_Else");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " selects else statement");
+
+ when M_RDV_Complete => Put ("M_RDV_Complete");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " completes rendezvous with "
+ & Get_Param (Info_Trace, Caller_Param, 1));
+
+ when M_Call_Complete => Put ("M_Call_Complete");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " completes call");
+
+ when M_Delay => Put ("M_Delay");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " completes delay "
+ & Get_Param (Info_Trace, Timeout_Param, 1));
+
+ when E_Missed => Put ("E_Missed");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " got an invalid acceptor "
+ & Get_Param (Info_Trace, Acceptor_Param, 1));
+
+ when E_Timeout => Put ("E_Timeout");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " ends select due to timeout ");
+
+ when E_Kill => Put ("E_Kill");
+ New_Line;
+ Put_Line ("Asynchronous Transfer of Control on task "
+ & Get_Param (Info_Trace, Name_Param, 1));
+
+ when W_Delay => Put ("W_Delay");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " sleeping "
+ & Get_Param (Info_Trace, Timeout_Param, 1)
+ & " seconds");
+
+ when WU_Delay => Put ("WU_Delay");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " sleeping until "
+ & Get_Param (Info_Trace, Timeout_Param, 1));
+
+ when W_Call => Put ("W_Call");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " calling entry "
+ & Get_Param (Info_Trace, Entry_Param, 1)
+ & " of " & Get_Param (Info_Trace, Acceptor_Param, 1));
+
+ when W_Accept => Put ("W_Accept");
+ New_Line;
+ Put ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " waiting on "
+ & Get_Param (Info_Trace, Number_Param, 1)
+ & " accept(s)"
+ & ", " & Get_Param (Info_Trace, Entry_Param, 1));
+ New_Line;
+
+ when W_Select => Put ("W_Select");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " waiting on "
+ & Get_Param (Info_Trace, Number_Param, 1)
+ & " select(s)"
+ & ", " & Get_Param (Info_Trace, Entry_Param, 1));
+ New_Line;
+
+ when W_Completion => Put ("W_Completion");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " waiting for completion ");
+
+ when WT_Select => Put ("WT_Select");
+ New_Line;
+ Put ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " waiting " & Get_Param (Info_Trace, Timeout_Param, 1)
+ & " seconds on "
+ & Get_Param (Info_Trace, Number_Param, 1)
+ & " select(s)");
+
+ if Get_Param (Info_Trace, Number_Param, 1) /= "" then
+ Put (", " & Get_Param (Info_Trace, Entry_Param, 1));
+ end if;
+
+ New_Line;
+
+ when WT_Call => Put ("WT_Call");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " calling entry "
+ & Get_Param (Info_Trace, Entry_Param, 1)
+ & " of " & Get_Param (Info_Trace, Acceptor_Param, 1)
+ & " with timeout "
+ & Get_Param (Info_Trace, Timeout_Param, 1));
+
+ when WT_Completion => Put ("WT_Completion");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " waiting "
+ & Get_Param (Info_Trace, Timeout_Param, 1)
+ & " for call completion");
+
+ when PO_Call => Put ("PO_Call");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " calling protected entry "
+ & Get_Param (Info_Trace, Entry_Param, 1));
+
+ when POT_Call => Put ("POT_Call");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " calling protected entry "
+ & Get_Param (Info_Trace, Entry_Param, 1)
+ & " with timeout "
+ & Get_Param (Info_Trace, Timeout_Param, 1));
+
+ when PO_Run => Put ("PO_Run");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " running entry "
+ & Get_Param (Info_Trace, Entry_Param, 1)
+ & " for "
+ & Get_Param (Info_Trace, Caller_Param, 1));
+
+ when PO_Done => Put ("PO_Done");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " finished call from "
+ & Get_Param (Info_Trace, Caller_Param, 1));
+
+ when PO_Lock => Put ("PO_Lock");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " took lock");
+
+ when PO_Unlock => Put ("PO_Unlock");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " released lock");
+
+ when T_Create => Put ("T_Create");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " created");
+
+ when T_Activate => Put ("T_Activate");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " activated");
+
+ when T_Abort => Put ("T_Abort");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " aborted by "
+ & Get_Param (Info_Trace, Parent_Param, 1));
+
+ when T_Terminate => Put ("T_Terminate");
+ New_Line;
+ Put_Line ("Task " & Get_Param (Info_Trace, Name_Param, 1)
+ & " terminated");
+
+ when others
+ => Put ("Invalid Id");
+ end case;
+
+ Put_Line (" --> " & Info_Trace);
+ Put_Line ("-----------------------------------");
+ New_Line;
+end Send_Trace;
diff --git a/gcc/ada/s-tfsetr-vxworks.adb b/gcc/ada/s-tfsetr-vxworks.adb
new file mode 100644
index 00000000000..0cd3d1b1107
--- /dev/null
+++ b/gcc/ada/s-tfsetr-vxworks.adb
@@ -0,0 +1,107 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T R A C E S . S E N D --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2001 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This version is for VxWorks targets.
+
+-- Trace information is sent to WindView using the wvEvent function.
+
+-- Note that wvEvent is from the VxWorks API.
+
+-- When adding a new event, just give an Id to then event, and then modify
+-- the WindView events database.
+
+-- Refer to WindView User's Guide for more details on how to add new events
+-- to the events database.
+
+----------------
+-- Send_Trace --
+----------------
+
+-- This procedure formats the string, maps the event Id to an Id
+-- recognized by WindView, and send the event using wvEvent
+
+separate (System.Traces.Format)
+procedure Send_Trace (Id : Trace_T; Info : String) is
+
+ procedure Wv_Event
+ (Id : Integer;
+ Buffer : System.Address;
+ Size : Integer);
+ pragma Import (C, Wv_Event, "wvEvent");
+
+ Info_Trace : String_Trace;
+ Id_Event : Integer;
+
+begin
+ Info_Trace := Format_Trace (Info);
+
+ case Id is
+ when M_Accept_Complete => Id_Event := 30000;
+ when M_Select_Else => Id_Event := 30001;
+ when M_RDV_Complete => Id_Event := 30002;
+ when M_Call_Complete => Id_Event := 30003;
+ when M_Delay => Id_Event := 30004;
+ when E_Kill => Id_Event := 30005;
+ when E_Missed => Id_Event := 30006;
+ when E_Timeout => Id_Event := 30007;
+
+ when W_Call => Id_Event := 30010;
+ when W_Accept => Id_Event := 30011;
+ when W_Select => Id_Event := 30012;
+ when W_Completion => Id_Event := 30013;
+ when W_Delay => Id_Event := 30014;
+ when WT_Select => Id_Event := 30015;
+ when WT_Call => Id_Event := 30016;
+ when WT_Completion => Id_Event := 30017;
+ when WU_Delay => Id_Event := 30018;
+
+ when PO_Call => Id_Event := 30020;
+ when POT_Call => Id_Event := 30021;
+ when PO_Run => Id_Event := 30022;
+ when PO_Lock => Id_Event := 30023;
+ when PO_Unlock => Id_Event := 30024;
+ when PO_Done => Id_Event := 30025;
+
+ when T_Create => Id_Event := 30030;
+ when T_Activate => Id_Event := 30031;
+ when T_Abort => Id_Event := 30032;
+ when T_Terminate => Id_Event := 30033;
+
+ -- Unrecognized events are given the special Id_Event value 29999
+
+ when others => Id_Event := 29999;
+
+ end case;
+
+ Wv_Event (Id_Event, Info_Trace'Address, Max_Size);
+end Send_Trace;
diff --git a/gcc/ada/s-tpopde-vms.adb b/gcc/ada/s-tpopde-vms.adb
new file mode 100644
index 00000000000..89db8240ad8
--- /dev/null
+++ b/gcc/ada/s-tpopde-vms.adb
@@ -0,0 +1,163 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- SYSTEM.TASK_PRIMITIVES.OPERATIONS.DEC --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2000-2004 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- --
+-- 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, 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, --
+-- 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 is for OpenVMS/Alpha
+
+with System.OS_Interface;
+with System.Parameters;
+with System.Tasking;
+with Unchecked_Conversion;
+with System.Soft_Links;
+
+package body System.Task_Primitives.Operations.DEC is
+
+ use System.OS_Interface;
+ use System.Parameters;
+ use System.Tasking;
+ use System.Aux_DEC;
+ use type Interfaces.C.int;
+
+ package SSL renames System.Soft_Links;
+
+ -- The FAB_RAB_Type specifies where the context field (the calling
+ -- task) is stored. Other fields defined for FAB_RAB arent' need and
+ -- so are ignored.
+
+ type FAB_RAB_Type is record
+ CTX : Unsigned_Longword;
+ end record;
+
+ for FAB_RAB_Type use record
+ CTX at 24 range 0 .. 31;
+ end record;
+
+ for FAB_RAB_Type'Size use 224;
+
+ type FAB_RAB_Access_Type is access all FAB_RAB_Type;
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ function To_Unsigned_Longword is new
+ Unchecked_Conversion (Task_ID, Unsigned_Longword);
+
+ function To_Task_Id is new
+ Unchecked_Conversion (Unsigned_Longword, Task_ID);
+
+ function To_FAB_RAB is new
+ Unchecked_Conversion (Address, FAB_RAB_Access_Type);
+
+ ---------------------------
+ -- Interrupt_AST_Handler --
+ ---------------------------
+
+ procedure Interrupt_AST_Handler (ID : Address) is
+ Result : Interfaces.C.int;
+ AST_Self_ID : constant Task_ID := To_Task_ID (ID);
+ begin
+ Result := pthread_cond_signal_int_np (AST_Self_ID.Common.LL.CV'Access);
+ pragma Assert (Result = 0);
+ end Interrupt_AST_Handler;
+
+ ---------------------
+ -- RMS_AST_Handler --
+ ---------------------
+
+ procedure RMS_AST_Handler (ID : Address) is
+ AST_Self_ID : constant Task_ID := To_Task_Id (To_FAB_RAB (ID).CTX);
+ Result : Interfaces.C.int;
+
+ begin
+ AST_Self_ID.Common.LL.AST_Pending := False;
+ Result := pthread_cond_signal_int_np (AST_Self_ID.Common.LL.CV'Access);
+ pragma Assert (Result = 0);
+ end RMS_AST_Handler;
+
+ ----------
+ -- Self --
+ ----------
+
+ function Self return Unsigned_Longword is
+ Self_ID : constant Task_ID := Self;
+ begin
+ Self_ID.Common.LL.AST_Pending := True;
+ return To_Unsigned_Longword (Self);
+ end Self;
+
+ -------------------------
+ -- Starlet_AST_Handler --
+ -------------------------
+
+ procedure Starlet_AST_Handler (ID : Address) is
+ Result : Interfaces.C.int;
+ AST_Self_ID : constant Task_ID := To_Task_ID (ID);
+ begin
+ AST_Self_ID.Common.LL.AST_Pending := False;
+ Result := pthread_cond_signal_int_np (AST_Self_ID.Common.LL.CV'Access);
+ pragma Assert (Result = 0);
+ end Starlet_AST_Handler;
+
+ ----------------
+ -- Task_Synch --
+ ----------------
+
+ procedure Task_Synch is
+ Synch_Self_ID : constant Task_ID := Self;
+
+ begin
+ if Single_Lock then
+ Lock_RTS;
+ else
+ Write_Lock (Synch_Self_ID);
+ end if;
+
+ SSL.Abort_Defer.all;
+ Synch_Self_ID.Common.State := AST_Server_Sleep;
+
+ while Synch_Self_ID.Common.LL.AST_Pending loop
+ Sleep (Synch_Self_ID, AST_Server_Sleep);
+ end loop;
+
+ Synch_Self_ID.Common.State := Runnable;
+
+ if Single_Lock then
+ Unlock_RTS;
+ else
+ Unlock (Synch_Self_ID);
+ end if;
+
+ SSL.Abort_Undefer.all;
+ end Task_Synch;
+
+end System.Task_Primitives.Operations.DEC;
diff --git a/gcc/ada/s-tpopde-vms.ads b/gcc/ada/s-tpopde-vms.ads
new file mode 100644
index 00000000000..46d92470f0b
--- /dev/null
+++ b/gcc/ada/s-tpopde-vms.ads
@@ -0,0 +1,54 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- SYSTEM.TASK_PRIMITIVES.OPERATIONS.DEC --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2000-2003 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- --
+-- 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, 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, --
+-- 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 is for OpenVMS/Alpha.
+--
+with System.Aux_DEC;
+package System.Task_Primitives.Operations.DEC is
+
+ procedure Interrupt_AST_Handler (ID : Address);
+ -- Handles the AST for Ada95 Interrupts.
+
+ procedure RMS_AST_Handler (ID : Address);
+ -- Handles the AST for RMS_Asynch_Operations.
+
+ function Self return System.Aux_DEC.Unsigned_Longword;
+ -- Returns the task identification for the AST.
+
+ procedure Starlet_AST_Handler (ID : Address);
+ -- Handles the AST for Starlet Tasking_Services.
+
+ procedure Task_Synch;
+ -- Synchronizes the task after the system service completes.
+
+end System.Task_Primitives.Operations.DEC;
diff --git a/gcc/ada/s-tpopsp-lynxos.adb b/gcc/ada/s-tpopsp-lynxos.adb
new file mode 100644
index 00000000000..2673d0e30b6
--- /dev/null
+++ b/gcc/ada/s-tpopsp-lynxos.adb
@@ -0,0 +1,113 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- SYSTEM.TASK_PRIMITIVES.OPERATIONS.SPECIFIC --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2004, 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- --
+-- 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, 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, --
+-- 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 is a LynxOS version of this package.
+
+separate (System.Task_Primitives.Operations)
+package body Specific is
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize (Environment_Task : Task_ID) is
+ pragma Warnings (Off, Environment_Task);
+ Result : Interfaces.C.int;
+
+ begin
+ Result := st_keycreate (null, ATCB_Key'Access);
+ pragma Assert (Result = 0);
+ end Initialize;
+
+ -------------------
+ -- Is_Valid_Task --
+ -------------------
+
+ function Is_Valid_Task return Boolean is
+ Result : Interfaces.C.int;
+ Value : aliased System.Address;
+ begin
+ Result := st_getspecific (ATCB_Key, Value'Address);
+ pragma Assert (Result = 0);
+ return (Value /= System.Null_Address);
+ end Is_Valid_Task;
+
+ ---------
+ -- Set --
+ ---------
+
+ procedure Set (Self_Id : Task_ID) is
+ Result : Interfaces.C.int;
+
+ begin
+ Result := st_setspecific (ATCB_Key, To_Address (Self_Id));
+ pragma Assert (Result = 0);
+ end Set;
+
+ ----------
+ -- Self --
+ ----------
+
+ -- To make Ada tasks and C threads interoperate better, we have added some
+ -- functionality to Self. Suppose a C main program (with threads) calls an
+ -- Ada procedure and the Ada procedure calls the tasking runtime system.
+ -- Eventually, a call will be made to self. Since the call is not coming
+ -- from an Ada task, there will be no corresponding ATCB.
+
+ -- What we do in Self is to catch references that do not come from
+ -- recognized Ada tasks, and create an ATCB for the calling thread.
+
+ -- The new ATCB will be "detached" from the normal Ada task master
+ -- hierarchy, much like the existing implicitly created signal-server
+ -- tasks.
+
+ function Self return Task_ID is
+ Value : aliased System.Address;
+
+ Result : Interfaces.C.int;
+ pragma Unreferenced (Result);
+
+ begin
+ Result := st_getspecific (ATCB_Key, Value'Address);
+ -- Is it OK not to check this result???
+
+ -- If the key value is Null, then it is a non-Ada task.
+
+ if Value /= System.Null_Address then
+ return To_Task_ID (Value);
+ else
+ return Register_Foreign_Thread;
+ end if;
+ end Self;
+
+end Specific;
diff --git a/gcc/ada/s-tpopsp-posix-foreign.adb b/gcc/ada/s-tpopsp-posix-foreign.adb
new file mode 100644
index 00000000000..c1c0815c790
--- /dev/null
+++ b/gcc/ada/s-tpopsp-posix-foreign.adb
@@ -0,0 +1,108 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- SYSTEM.TASK_PRIMITIVES.OPERATIONS.SPECIFIC --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2004, 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- --
+-- 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, 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, --
+-- 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 is a POSIX version of this package where foreign threads are
+-- recognized.
+
+-- Currently, DEC Unix, SCO UnixWare, Solaris pthread, HPUX pthread and
+-- GNU/Linux threads use this version.
+
+separate (System.Task_Primitives.Operations)
+package body Specific is
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize (Environment_Task : Task_ID) is
+ pragma Warnings (Off, Environment_Task);
+ Result : Interfaces.C.int;
+
+ begin
+ Result := pthread_key_create (ATCB_Key'Access, null);
+ pragma Assert (Result = 0);
+ end Initialize;
+
+ -------------------
+ -- Is_Valid_Task --
+ -------------------
+
+ function Is_Valid_Task return Boolean is
+ begin
+ return pthread_getspecific (ATCB_Key) /= System.Null_Address;
+ end Is_Valid_Task;
+
+ ---------
+ -- Set --
+ ---------
+
+ procedure Set (Self_Id : Task_ID) is
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_setspecific (ATCB_Key, To_Address (Self_Id));
+ pragma Assert (Result = 0);
+ end Set;
+
+ ----------
+ -- Self --
+ ----------
+
+ -- To make Ada tasks and C threads interoperate better, we have added some
+ -- functionality to Self. Suppose a C main program (with threads) calls an
+ -- Ada procedure and the Ada procedure calls the tasking runtime system.
+ -- Eventually, a call will be made to self. Since the call is not coming
+ -- from an Ada task, there will be no corresponding ATCB.
+
+ -- What we do in Self is to catch references that do not come from
+ -- recognized Ada tasks, and create an ATCB for the calling thread.
+
+ -- The new ATCB will be "detached" from the normal Ada task master
+ -- hierarchy, much like the existing implicitly created signal-server
+ -- tasks.
+
+ function Self return Task_ID is
+ Result : System.Address;
+
+ begin
+ Result := pthread_getspecific (ATCB_Key);
+
+ -- If the key value is Null, then it is a non-Ada task.
+
+ if Result /= System.Null_Address then
+ return To_Task_ID (Result);
+ else
+ return Register_Foreign_Thread;
+ end if;
+ end Self;
+
+end Specific;
diff --git a/gcc/ada/s-tpopsp-posix.adb b/gcc/ada/s-tpopsp-posix.adb
new file mode 100644
index 00000000000..f7a67a074ca
--- /dev/null
+++ b/gcc/ada/s-tpopsp-posix.adb
@@ -0,0 +1,80 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- SYSTEM.TASK_PRIMITIVES.OPERATIONS.SPECIFIC --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2004, Free Software Fundation, 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- --
+-- 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, 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, --
+-- 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 is a POSIX-like version of this package.
+
+separate (System.Task_Primitives.Operations)
+package body Specific is
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize (Environment_Task : Task_ID) is
+ pragma Warnings (Off, Environment_Task);
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_key_create (ATCB_Key'Access, null);
+ pragma Assert (Result = 0);
+ end Initialize;
+
+ -------------------
+ -- Is_Valid_Task --
+ -------------------
+
+ function Is_Valid_Task return Boolean is
+ begin
+ return pthread_getspecific (ATCB_Key) /= System.Null_Address;
+ end Is_Valid_Task;
+
+ ---------
+ -- Set --
+ ---------
+
+ procedure Set (Self_Id : Task_ID) is
+ Result : Interfaces.C.int;
+ begin
+ Result := pthread_setspecific (ATCB_Key, To_Address (Self_Id));
+ pragma Assert (Result = 0);
+ end Set;
+
+ ----------
+ -- Self --
+ ----------
+
+ function Self return Task_ID is
+ begin
+ return To_Task_ID (pthread_getspecific (ATCB_Key));
+ end Self;
+
+end Specific;
diff --git a/gcc/ada/s-tpopsp-solaris.adb b/gcc/ada/s-tpopsp-solaris.adb
new file mode 100644
index 00000000000..eb32dd2cb81
--- /dev/null
+++ b/gcc/ada/s-tpopsp-solaris.adb
@@ -0,0 +1,107 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- SYSTEM.TASK_PRIMITIVES.OPERATIONS.SPECIFIC --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2003, 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- --
+-- 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, 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, --
+-- 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 is a version for Solaris native threads
+
+separate (System.Task_Primitives.Operations)
+package body Specific is
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize (Environment_Task : Task_ID) is
+ Result : Interfaces.C.int;
+ begin
+ Result := thr_setspecific (ATCB_Key, To_Address (Environment_Task));
+ pragma Assert (Result = 0);
+ end Initialize;
+
+ -------------------
+ -- Is_Valid_Task --
+ -------------------
+
+ function Is_Valid_Task return Boolean is
+ Unknown_Task : aliased System.Address;
+ Result : Interfaces.C.int;
+ begin
+ Result := thr_getspecific (ATCB_Key, Unknown_Task'Unchecked_Access);
+ pragma Assert (Result = 0);
+ return Unknown_Task /= System.Null_Address;
+ end Is_Valid_Task;
+
+ ---------
+ -- Set --
+ ---------
+
+ procedure Set (Self_Id : Task_ID) is
+ Result : Interfaces.C.int;
+ begin
+ Result := thr_setspecific (ATCB_Key, To_Address (Self_Id));
+ pragma Assert (Result = 0);
+ end Set;
+
+ ----------
+ -- Self --
+ ----------
+
+ -- To make Ada tasks and C threads interoperate better, we have
+ -- added some functionality to Self. Suppose a C main program
+ -- (with threads) calls an Ada procedure and the Ada procedure
+ -- calls the tasking run-time system. Eventually, a call will be
+ -- made to self. Since the call is not coming from an Ada task,
+ -- there will be no corresponding ATCB.
+
+ -- What we do in Self is to catch references that do not come
+ -- from recognized Ada tasks, and create an ATCB for the calling
+ -- thread.
+
+ -- The new ATCB will be "detached" from the normal Ada task
+ -- master hierarchy, much like the existing implicitly created
+ -- signal-server tasks.
+
+ function Self return Task_ID is
+ Result : Interfaces.C.int;
+ Self_Id : aliased System.Address;
+ begin
+ Result := thr_getspecific (ATCB_Key, Self_Id'Unchecked_Access);
+ pragma Assert (Result = 0);
+
+ if Self_Id = System.Null_Address then
+ return Register_Foreign_Thread;
+ else
+ return To_Task_ID (Self_Id);
+ end if;
+ end Self;
+
+end Specific;
diff --git a/gcc/ada/s-tpopsp-vxworks.adb b/gcc/ada/s-tpopsp-vxworks.adb
new file mode 100644
index 00000000000..02983287d2c
--- /dev/null
+++ b/gcc/ada/s-tpopsp-vxworks.adb
@@ -0,0 +1,74 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- SYSTEM.TASK_PRIMITIVES.OPERATIONS.SPECIFIC --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2004, 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- --
+-- 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, 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, --
+-- 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 is a VxWorks version of this package where foreign threads are
+-- recognized.
+
+separate (System.Task_Primitives.Operations)
+package body Specific is
+
+ -------------------
+ -- Is_Valid_Task --
+ -------------------
+
+ function Is_Valid_Task return Boolean is
+ begin
+ return taskVarGet (taskIdSelf, ATCB_Key'Access) /= ERROR;
+ end Is_Valid_Task;
+
+ ---------
+ -- Set --
+ ---------
+
+ procedure Set (Self_Id : Task_ID) is
+ Result : STATUS;
+
+ begin
+ if taskVarGet (0, ATCB_Key'Access) = ERROR then
+ Result := taskVarAdd (0, ATCB_Key'Access);
+ pragma Assert (Result = OK);
+ end if;
+
+ ATCB_Key := To_Address (Self_Id);
+ end Set;
+
+ ----------
+ -- Self --
+ ----------
+
+ function Self return Task_ID is
+ begin
+ return To_Task_ID (ATCB_Key);
+ end Self;
+
+end Specific;
diff --git a/gcc/ada/s-traceb-hpux.adb b/gcc/ada/s-traceb-hpux.adb
new file mode 100644
index 00000000000..dce251a05a9
--- /dev/null
+++ b/gcc/ada/s-traceb-hpux.adb
@@ -0,0 +1,600 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . T R A C E B A C K --
+-- (HP/UX Version) --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1999-2003 Ada Core Technologies, 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Ada.Unchecked_Conversion;
+
+package body System.Traceback is
+
+ -- This package implements the backtracing facility by way of a dedicated
+ -- HP library for stack unwinding described in the "Runtime Architecture
+ -- Document".
+
+ pragma Linker_Options ("/usr/lib/libcl.a");
+
+ -- The library basically offers services to fetch information about a
+ -- "previous" frame based on information about a "current" one.
+
+ type Current_Frame_Descriptor is record
+ cur_fsz : Address; -- Frame size of current routine.
+ cur_sp : Address; -- The current value of stack pointer.
+ cur_rls : Address; -- PC-space of the caller.
+ cur_rlo : Address; -- PC-offset of the caller.
+ cur_dp : Address; -- Data Pointer of the current routine.
+ top_rp : Address; -- Initial value of RP.
+ top_mrp : Address; -- Initial value of MRP.
+ top_sr0 : Address; -- Initial value of sr0.
+ top_sr4 : Address; -- Initial value of sr4.
+ top_r3 : Address; -- Initial value of gr3.
+ cur_r19 : Address; -- GR19 value of the calling routine.
+ top_r4 : Address; -- Initial value of gr4.
+ dummy : Address; -- Reserved.
+ out_rlo : Address; -- PC-offset of the caller after get_previous.
+ end record;
+
+ type Previous_Frame_Descriptor is record
+ prev_fsz : Address; -- frame size of calling routine.
+ prev_sp : Address; -- SP of calling routine.
+ prev_rls : Address; -- PC_space of calling routine's caller.
+ prev_rlo : Address; -- PC_offset of calling routine's caller.
+ prev_dp : Address; -- DP of calling routine.
+ udescr0 : Address; -- low word of calling routine's unwind desc.
+ udescr1 : Address; -- high word of calling routine's unwind desc.
+ ustart : Address; -- start of the unwind region.
+ uend : Address; -- end of the unwind region.
+ uw_index : Address; -- index into the unwind table.
+ prev_r19 : Address; -- GR19 value of the caller's caller.
+ top_r3 : Address; -- Caller's initial gr3.
+ top_r4 : Address; -- Caller's initial gr4.
+ end record;
+
+ -- Provide useful shortcuts for the names
+
+ subtype CFD is Current_Frame_Descriptor;
+ subtype PFD is Previous_Frame_Descriptor;
+
+ -- Frames with dynamic stack allocation are handled using the associated
+ -- frame pointer, but HP compilers and GCC setup this pointer differently.
+ -- HP compilers set it to point at the top (highest address) of the static
+ -- part of the frame, wheras GCC sets it to point at the bottom of this
+ -- region. We have to fake the unwinder to compensate for this difference,
+ -- for which we'll need to access some subprograms unwind descriptors.
+
+ type Bits_2_Value is mod 2 ** 2;
+ for Bits_2_Value'Size use 2;
+
+ type Bits_4_Value is mod 2 ** 4;
+ for Bits_4_Value'Size use 4;
+
+ type Bits_5_Value is mod 2 ** 5;
+ for Bits_5_Value'Size use 5;
+
+ type Bits_27_Value is mod 2 ** 27;
+ for Bits_27_Value'Size use 27;
+
+ type Unwind_Descriptor is record
+ cannot_unwind : Boolean;
+ mcode : Boolean;
+ mcode_save_restore : Boolean;
+ region_desc : Bits_2_Value;
+ reserved0 : Boolean;
+ entry_sr : Boolean;
+ entry_fr : Bits_4_Value;
+ entry_gr : Bits_5_Value;
+
+ args_stored : Boolean;
+ variable_frame : Boolean;
+ separate_package_body : Boolean;
+ frame_extension_mcode : Boolean;
+
+ stack_overflow_check : Boolean;
+ two_steps_sp_adjust : Boolean;
+ sr4_export : Boolean;
+ cxx_info : Boolean;
+
+ cxx_try_catch : Boolean;
+ sched_entry_seq : Boolean;
+ reserved1 : Boolean;
+ save_sp : Boolean;
+
+ save_rp : Boolean;
+ save_mrp : Boolean;
+ save_r19 : Boolean;
+ cleanups : Boolean;
+
+ hpe_interrupt_marker : Boolean;
+ hpux_interrupt_marker : Boolean;
+ large_frame : Boolean;
+ alloca_frame : Boolean;
+
+ reserved2 : Boolean;
+ frame_size : Bits_27_Value;
+ end record;
+
+ for Unwind_Descriptor'Size use 64;
+
+ for Unwind_Descriptor use record
+ cannot_unwind at 0 range 0 .. 0;
+ mcode at 0 range 1 .. 1;
+ mcode_save_restore at 0 range 2 .. 2;
+ region_desc at 0 range 3 .. 4;
+ reserved0 at 0 range 5 .. 5;
+ entry_sr at 0 range 6 .. 6;
+ entry_fr at 0 range 7 .. 10;
+
+ entry_gr at 1 range 3 .. 7;
+
+ args_stored at 2 range 0 .. 0;
+ variable_frame at 2 range 1 .. 1;
+ separate_package_body at 2 range 2 .. 2;
+ frame_extension_mcode at 2 range 3 .. 3;
+ stack_overflow_check at 2 range 4 .. 4;
+ two_steps_sp_adjust at 2 range 5 .. 5;
+ sr4_export at 2 range 6 .. 6;
+ cxx_info at 2 range 7 .. 7;
+
+ cxx_try_catch at 3 range 0 .. 0;
+ sched_entry_seq at 3 range 1 .. 1;
+ reserved1 at 3 range 2 .. 2;
+ save_sp at 3 range 3 .. 3;
+ save_rp at 3 range 4 .. 4;
+ save_mrp at 3 range 5 .. 5;
+ save_r19 at 3 range 6 .. 6;
+ cleanups at 3 range 7 .. 7;
+
+ hpe_interrupt_marker at 4 range 0 .. 0;
+ hpux_interrupt_marker at 4 range 1 .. 1;
+ large_frame at 4 range 2 .. 2;
+ alloca_frame at 4 range 3 .. 3;
+
+ reserved2 at 4 range 4 .. 4;
+ frame_size at 4 range 5 .. 31;
+ end record;
+
+ subtype UWD is Unwind_Descriptor;
+ type UWD_Ptr is access all UWD;
+
+ function To_UWD_Access is new Ada.Unchecked_Conversion (Address, UWD_Ptr);
+
+ -- The descriptor associated with a given code location is retrieved
+ -- using functions imported from the HP library, requiring the definition
+ -- of additional structures.
+
+ type Unwind_Table_Region is record
+ Table_Start : Address;
+ Table_End : Address;
+ end record;
+ -- An Unwind Table region, which is a memory area containing Unwind
+ -- Descriptors.
+
+ subtype UWT is Unwind_Table_Region;
+
+ -- The subprograms imported below are provided by the HP library
+
+ function U_get_unwind_table return UWT;
+ pragma Import (C, U_get_unwind_table, "U_get_unwind_table");
+ -- Get the unwind table region associated with the current executable.
+ -- This function is actually documented as having an argument, but which
+ -- is only used for the MPE/iX targets.
+
+ function U_get_shLib_unwind_table (r19 : Address) return UWT;
+ pragma Import (C, U_get_shLib_unwind_table, "U_get_shLib_unw_tbl");
+ -- Return the unwind table region associated with a possible shared
+ -- library, as determined by the provided r19 value.
+
+ function U_get_shLib_text_addr (r19 : Address) return Address;
+ pragma Import (C, U_get_shLib_text_addr, "U_get_shLib_text_addr");
+ -- Return the address at which the code for a shared library begins, or
+ -- -1 if the value provided for r19 does not identify shared library code.
+
+ function U_get_unwind_entry
+ (Pc : Address;
+ Space : Address;
+ Table_Start : Address;
+ Table_End : Address) return Address;
+ pragma Import (C, U_get_unwind_entry, "U_get_unwind_entry");
+ -- Given the bounds of an unwind table, return the address of the
+ -- unwind descriptor associated with a code location/space. In the case
+ -- of shared library code, the offset from the beginning of the library
+ -- is expected as Pc.
+
+ procedure U_init_frame_record (Frame : access CFD);
+ pragma Import (C, U_init_frame_record, "U_init_frame_record");
+
+ procedure U_prep_frame_rec_for_unwind (Frame : access CFD);
+ pragma Import (C, U_prep_frame_rec_for_unwind,
+ "U_prep_frame_rec_for_unwind");
+
+ -- Fetch the description data of the frame in which these two procedures
+ -- are called.
+
+ function U_get_u_rlo (Cur : access CFD; Prev : access PFD) return Integer;
+ pragma Import (C, U_get_u_rlo, "U_IS_STUB_OR_CALLX");
+ -- From a complete current frame with a return location possibly located
+ -- into a linker generated stub, and basic information about the previous
+ -- frame, place the first non stub return location into the current frame.
+ -- Return -1 if something went wrong during the computation.
+
+ function U_is_shared_pc (rlo : Address; r19 : Address) return Address;
+ pragma Import (C, U_is_shared_pc, "U_is_shared_pc");
+ -- Return 0 if the provided return location does not correspond to code
+ -- in a shared library, or something non null otherwise.
+
+ function U_get_previous_frame_x
+ (current_frame : access CFD;
+ previous_frame : access PFD;
+ previous_size : Integer) return Integer;
+ pragma Import (C, U_get_previous_frame_x, "U_get_previous_frame_x");
+ -- Fetch the data describing the "previous" frame relatively to the
+ -- "current" one. "previous_size" should be the size of the "previous"
+ -- frame descriptor provided.
+ --
+ -- The library provides a simpler interface without the size parameter
+ -- but it is not usable when frames with dynamically allocated space are
+ -- on the way.
+
+ ------------------
+ -- C_Call_Chain --
+ ------------------
+
+ function C_Call_Chain
+ (Traceback : System.Address;
+ Max_Len : Natural) return Natural
+ is
+ Val : Natural;
+
+ begin
+ Call_Chain (Traceback, Max_Len, Val);
+ return Val;
+ end C_Call_Chain;
+
+ ----------------
+ -- Call_Chain --
+ ----------------
+
+ procedure Call_Chain
+ (Traceback : System.Address;
+ Max_Len : Natural;
+ Len : out Natural;
+ Exclude_Min : System.Address := System.Null_Address;
+ Exclude_Max : System.Address := System.Null_Address;
+ Skip_Frames : Natural := 1)
+ is
+ type Tracebacks_Array is array (1 .. Max_Len) of System.Address;
+ pragma Suppress_Initialization (Tracebacks_Array);
+
+ -- The code location returned by the unwinder is a return location but
+ -- what we need is a call point. Under HP-UX call instructions are 4
+ -- bytes long and the return point they specify is 4 bytes beyond the
+ -- next instruction because of the delay slot.
+
+ Call_Size : constant := 4;
+ DSlot_Size : constant := 4;
+ Rlo_Offset : constant := Call_Size + DSlot_Size;
+
+ -- Moreover, the return point is passed via a register which two least
+ -- significant bits specify a privilege level that we will have to mask.
+
+ Priv_Mask : constant := 16#00000003#;
+
+ Frame : aliased CFD;
+ Code : System.Address;
+ J : Natural := 1;
+ Pop_Success : Boolean;
+ Trace : Tracebacks_Array;
+ for Trace'Address use Traceback;
+
+ -- The backtracing process needs a set of subprograms :
+
+ function UWD_For_RLO_Of (Frame : access CFD) return UWD_Ptr;
+ -- Return an access to the unwind descriptor for the caller of
+ -- a given frame, using only the provided return location.
+
+ function UWD_For_Caller_Of (Frame : access CFD) return UWD_Ptr;
+ -- Return an access to the unwind descriptor for the user code caller
+ -- of a given frame, or null if the information is not available.
+
+ function Pop_Frame (Frame : access CFD) return Boolean;
+ -- Update the provided machine state structure so that it reflects
+ -- the state one call frame "above" the initial one.
+ --
+ -- Return True if the operation has been successful, False otherwise.
+ -- Failure typically occurs when the top of the call stack has been
+ -- reached.
+
+ function Prepare_For_Unwind_Of (Frame : access CFD) return Boolean;
+ -- Perform the necessary adaptations to the machine state before
+ -- calling the unwinder. Currently used for the specific case of
+ -- dynamically sized previous frames.
+ --
+ -- Return True if everything went fine, or False otherwise.
+
+ Program_UWT : constant UWT := U_get_unwind_table;
+
+ ---------------
+ -- Pop_Frame --
+ ---------------
+
+ function Pop_Frame (Frame : access CFD) return Boolean is
+ Up_Frame : aliased PFD;
+ State_Ready : Boolean;
+
+ begin
+ -- Check/adapt the state before calling the unwinder and return
+ -- if anything went wrong.
+
+ State_Ready := Prepare_For_Unwind_Of (Frame);
+
+ if not State_Ready then
+ return False;
+ end if;
+
+ -- Now, safely call the unwinder and use the results.
+
+ if U_get_previous_frame_x (Frame,
+ Up_Frame'Access,
+ Up_Frame'Size) /= 0
+ then
+ return False;
+ end if;
+
+ -- In case a stub is on the way, the usual previous return location
+ -- (the one in prev_rlo) is the one in the stub and the "real" one
+ -- is placed in the "current" record, so let's take this one into
+ -- account.
+
+ Frame.out_rlo := Frame.cur_rlo;
+
+ Frame.cur_fsz := Up_Frame.prev_fsz;
+ Frame.cur_sp := Up_Frame.prev_sp;
+ Frame.cur_rls := Up_Frame.prev_rls;
+ Frame.cur_rlo := Up_Frame.prev_rlo;
+ Frame.cur_dp := Up_Frame.prev_dp;
+ Frame.cur_r19 := Up_Frame.prev_r19;
+ Frame.top_r3 := Up_Frame.top_r3;
+ Frame.top_r4 := Up_Frame.top_r4;
+
+ return True;
+ end Pop_Frame;
+
+ ---------------------------------
+ -- Prepare_State_For_Unwind_Of --
+ ---------------------------------
+
+ function Prepare_For_Unwind_Of (Frame : access CFD) return Boolean
+ is
+ Caller_UWD : UWD_Ptr;
+ FP_Adjustment : Integer;
+
+ begin
+ -- No need to bother doing anything if the stack is already fully
+ -- unwound.
+
+ if Frame.cur_rlo = 0 then
+ return False;
+ end if;
+
+ -- When ALLOCA_FRAME is set in an unwind descriptor, the unwinder
+ -- uses the value provided in current.top_r3 or current.top_r4 as
+ -- a frame pointer to compute the size of the frame. What decides
+ -- between r3 or r4 is the unwind descriptor LARGE_FRAME bit, with
+ -- r4 chosen if the bit is set.
+
+ -- The size computed by the unwinder is STATIC_PART + (SP - FP),
+ -- which is correct with HP's frame pointer convention, but not
+ -- with GCC's one since we end up with the static part accounted
+ -- for twice.
+
+ -- We have to compute r4 when it is required because the unwinder
+ -- has looked for it at a place where it was not if we went through
+ -- GCC frames.
+
+ -- The size of the static part of a frame can be found in the
+ -- associated unwind descriptor.
+
+ Caller_UWD := UWD_For_Caller_Of (Frame);
+
+ -- If we cannot get it, we are unable to compute the potentially
+ -- necessary adjustments. We'd better not try to go on then.
+
+ if Caller_UWD = null then
+ return False;
+ end if;
+
+ -- If the caller frame is a GCC one, r3 is its frame pointer and
+ -- points to the bottom of the frame. The value to provide for r4
+ -- can then be computed directly from the one of r3, compensating
+ -- for the static part of the frame.
+
+ -- If the caller frame is an HP one, r3 is used to locate the
+ -- previous frame marker, that is it also points to the bottom of
+ -- the frame (this is why r3 cannot be used as the frame pointer in
+ -- the HP sense for large frames). The value to provide for r4 can
+ -- then also be computed from the one of r3 with the compensation
+ -- for the static part of the frame.
+
+ FP_Adjustment := Integer (Caller_UWD.frame_size * 8);
+ Frame.top_r4 := Address (Integer (Frame.top_r3) + FP_Adjustment);
+
+ return True;
+ end Prepare_For_Unwind_Of;
+
+ -----------------------
+ -- UWD_For_Caller_Of --
+ -----------------------
+
+ function UWD_For_Caller_Of (Frame : access CFD) return UWD_Ptr
+ is
+ UWD_Access : UWD_Ptr;
+
+ begin
+ -- First try the most direct path, using the return location data
+ -- associated with the frame.
+
+ UWD_Access := UWD_For_RLO_Of (Frame);
+
+ if UWD_Access /= null then
+ return UWD_Access;
+ end if;
+
+ -- If we did not get a result, we might face an in-stub return
+ -- address. In this case U_get_previous_frame can tell us what the
+ -- first not-in-stub return point is. We cannot call it directly,
+ -- though, because we haven't computed the potentially necessary
+ -- frame pointer adjustments, which might lead to SEGV in some
+ -- circumstances. Instead, we directly call the libcl routine which
+ -- is called by U_get_previous_frame and which only requires few
+ -- information. Take care, however, that the information is provided
+ -- in the "current" argument, so we need to work on a copy to avoid
+ -- disturbing our caller.
+
+ declare
+ U_Current : aliased CFD := Frame.all;
+ U_Previous : aliased PFD;
+
+ begin
+ U_Previous.prev_dp := U_Current.cur_dp;
+ U_Previous.prev_rls := U_Current.cur_rls;
+ U_Previous.prev_sp := U_Current.cur_sp - U_Current.cur_fsz;
+
+ if U_get_u_rlo (U_Current'Access, U_Previous'Access) /= -1 then
+ UWD_Access := UWD_For_RLO_Of (U_Current'Access);
+ end if;
+ end;
+
+ return UWD_Access;
+ end UWD_For_Caller_Of;
+
+ --------------------
+ -- UWD_For_RLO_Of --
+ --------------------
+
+ function UWD_For_RLO_Of (Frame : access CFD) return UWD_Ptr
+ is
+ UWD_Address : Address;
+
+ -- The addresses returned by the library point to full descriptors
+ -- including the frame information bits but also the applicable PC
+ -- range. We need to account for this.
+
+ Frame_Info_Offset : constant := 8;
+
+ begin
+ -- First try to locate the descriptor in the program's unwind table.
+
+ UWD_Address := U_get_unwind_entry (Frame.cur_rlo,
+ Frame.cur_rls,
+ Program_UWT.Table_Start,
+ Program_UWT.Table_End);
+
+ -- If we did not get it, we might have a frame from code in a
+ -- stub or shared library. For code in stub we would have to
+ -- compute the first non-stub return location but this is not
+ -- the role of this subprogram, so let's just try to see if we
+ -- can get a result from the tables in shared libraries.
+
+ if UWD_Address = -1
+ and then U_is_shared_pc (Frame.cur_rlo, Frame.cur_r19) /= 0
+ then
+ declare
+ Shlib_UWT : constant UWT :=
+ U_get_shLib_unwind_table (Frame.cur_r19);
+ Shlib_Start : constant Address :=
+ U_get_shLib_text_addr (Frame.cur_r19);
+ Rlo_Offset : constant Address :=
+ Frame.cur_rlo - Shlib_Start;
+ begin
+ UWD_Address := U_get_unwind_entry (Rlo_Offset,
+ Frame.cur_rls,
+ Shlib_UWT.Table_Start,
+ Shlib_UWT.Table_End);
+ end;
+ end if;
+
+ if UWD_Address /= -1 then
+ return To_UWD_Access (UWD_Address + Frame_Info_Offset);
+ else
+ return null;
+ end if;
+ end UWD_For_RLO_Of;
+
+ -- Start of processing for Call_Chain
+
+ begin
+ -- Fetch the state for this subprogram's frame and pop it so that we
+ -- start with an initial out_rlo "here".
+
+ U_init_frame_record (Frame'Access);
+ Frame.top_sr0 := 0;
+ Frame.top_sr4 := 0;
+
+ U_prep_frame_rec_for_unwind (Frame'Access);
+
+ Pop_Success := Pop_Frame (Frame'Access);
+
+ -- Skip the requested number of frames.
+
+ for I in 1 .. Skip_Frames loop
+ Pop_Success := Pop_Frame (Frame'Access);
+ end loop;
+
+ -- Loop popping frames and storing locations until either a problem
+ -- occurs, or the top of the call chain is reached, or the provided
+ -- array is full.
+
+ loop
+ -- We have to test some conditions against the return location
+ -- as it is returned, so get it as is first.
+
+ Code := Frame.out_rlo;
+
+ exit when not Pop_Success or else Code = 0 or else J = Max_Len + 1;
+
+ -- Compute the call point from the retrieved return location :
+ -- Mask the privilege bits and account for the delta between the
+ -- call site and the return point.
+
+ Code := (Code and not Priv_Mask) - Rlo_Offset;
+
+ if Code < Exclude_Min or else Code > Exclude_Max then
+ Trace (J) := Code;
+ J := J + 1;
+ end if;
+
+ Pop_Success := Pop_Frame (Frame'Access);
+ end loop;
+
+ Len := J - 1;
+ end Call_Chain;
+
+end System.Traceback;
diff --git a/gcc/ada/s-traceb-mastop.adb b/gcc/ada/s-traceb-mastop.adb
new file mode 100644
index 00000000000..1811c5a603b
--- /dev/null
+++ b/gcc/ada/s-traceb-mastop.adb
@@ -0,0 +1,113 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . T R A C E B A C K --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1999-2003 Ada Core Technologies, 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This version assumes that System.Machine_State_Operations.Pop_Frame can
+-- work with the Info parameter being null.
+
+with System.Machine_State_Operations;
+
+package body System.Traceback is
+
+ use System.Machine_State_Operations;
+
+ ----------------
+ -- Call_Chain --
+ ----------------
+
+ procedure Call_Chain
+ (Traceback : System.Address;
+ Max_Len : Natural;
+ Len : out Natural;
+ Exclude_Min : System.Address := System.Null_Address;
+ Exclude_Max : System.Address := System.Null_Address;
+ Skip_Frames : Natural := 1)
+ is
+ type Tracebacks_Array is array (1 .. Max_Len) of Code_Loc;
+ pragma Suppress_Initialization (Tracebacks_Array);
+
+ M : Machine_State;
+ Code : Code_Loc;
+
+ Trace : Tracebacks_Array;
+ for Trace'Address use Traceback;
+
+ N_Skips : Natural := 0;
+
+ begin
+ M := Allocate_Machine_State;
+ Set_Machine_State (M);
+
+ -- Skip the requested number of frames
+
+ loop
+ Code := Get_Code_Loc (M);
+ exit when Code = Null_Address or else N_Skips = Skip_Frames;
+
+ Pop_Frame (M, System.Null_Address);
+ N_Skips := N_Skips + 1;
+ end loop;
+
+ -- Now, record the frames outside the exclusion bounds, updating
+ -- the Len output value along the way.
+
+ Len := 0;
+ loop
+ Code := Get_Code_Loc (M);
+ exit when Code = Null_Address or else Len = Max_Len;
+
+ if Code < Exclude_Min or else Code > Exclude_Max then
+ Len := Len + 1;
+ Trace (Len) := Code;
+ end if;
+
+ Pop_Frame (M, System.Null_Address);
+ end loop;
+
+ Free_Machine_State (M);
+ end Call_Chain;
+
+ ------------------
+ -- C_Call_Chain --
+ ------------------
+
+ function C_Call_Chain
+ (Traceback : System.Address;
+ Max_Len : Natural) return Natural
+ is
+ Val : Natural;
+ begin
+ Call_Chain (Traceback, Max_Len, Val);
+ return Val;
+ end C_Call_Chain;
+
+end System.Traceback;
diff --git a/gcc/ada/s-traces-default.adb b/gcc/ada/s-traces-default.adb
new file mode 100644
index 00000000000..46822242a40
--- /dev/null
+++ b/gcc/ada/s-traces-default.adb
@@ -0,0 +1,73 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T R A C E S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2001 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with System.Soft_Links;
+with System.Parameters;
+with System.Traces.Format;
+
+package body System.Traces is
+
+ package SSL renames System.Soft_Links;
+ use System.Traces.Format;
+
+ ----------------------
+ -- Send_Trace_Info --
+ ----------------------
+
+ procedure Send_Trace_Info (Id : Trace_T) is
+ Task_S : String := SSL.Task_Name.all;
+ Trace_S : String (1 .. 3 + Task_S'Length);
+
+ begin
+ if Parameters.Runtime_Traces then
+ Trace_S (1 .. 3) := "/N:";
+ Trace_S (4 .. Trace_S'Last) := Task_S;
+ Send_Trace (Id, Trace_S);
+ end if;
+ end Send_Trace_Info;
+
+ procedure Send_Trace_Info (Id : Trace_T; Timeout : Duration) is
+ Task_S : String := SSL.Task_Name.all;
+ Timeout_S : String := Duration'Image (Timeout);
+ Trace_S : String (1 .. 6 + Task_S'Length + Timeout_S'Length);
+
+ begin
+ if Parameters.Runtime_Traces then
+ Trace_S (1 .. 3) := "/N:";
+ Trace_S (4 .. 3 + Task_S'Length) := Task_S;
+ Trace_S (4 + Task_S'Length .. 6 + Task_S'Length) := "/T:";
+ Trace_S (7 + Task_S'Length .. Trace_S'Last) := Timeout_S;
+ Send_Trace (Id, Trace_S);
+ end if;
+ end Send_Trace_Info;
+end System.Traces;
diff --git a/gcc/ada/s-traent-vms.adb b/gcc/ada/s-traent-vms.adb
new file mode 100644
index 00000000000..532acad6e32
--- /dev/null
+++ b/gcc/ada/s-traent-vms.adb
@@ -0,0 +1,68 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . T R A C E B A C K _ E N T R I E S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package body System.Traceback_Entries is
+
+ ------------
+ -- PC_For --
+ ------------
+
+ function PC_For (TB_Entry : Traceback_Entry) return System.Address is
+ begin
+ return TB_Entry.PC;
+ end PC_For;
+
+ ------------
+ -- PV_For --
+ ------------
+
+ function PV_For (TB_Entry : Traceback_Entry) return System.Address is
+ begin
+ return TB_Entry.PV;
+ end PV_For;
+
+ ------------------
+ -- TB_Entry_For --
+ ------------------
+
+ function TB_Entry_For (PC : System.Address) return Traceback_Entry is
+ begin
+ return (PC => PC, PV => System.Null_Address);
+ end TB_Entry_For;
+
+end System.Traceback_Entries;
+
diff --git a/gcc/ada/s-traent-vms.ads b/gcc/ada/s-traent-vms.ads
new file mode 100644
index 00000000000..0d27c197fff
--- /dev/null
+++ b/gcc/ada/s-traent-vms.ads
@@ -0,0 +1,59 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . T R A C E B A C K _ E N T R I E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the Alpha/OpenVMS version of this package
+
+package System.Traceback_Entries is
+
+ type Traceback_Entry is record
+ PC : System.Address;
+ PV : System.Address;
+ end record;
+
+ pragma Suppress_Initialization (Traceback_Entry);
+
+ Null_TB_Entry : constant Traceback_Entry :=
+ (PC => System.Null_Address,
+ PV => System.Null_Address);
+
+ function PC_For (TB_Entry : Traceback_Entry) return System.Address;
+ function PV_For (TB_Entry : Traceback_Entry) return System.Address;
+
+ function TB_Entry_For (PC : System.Address) return Traceback_Entry;
+
+end System.Traceback_Entries;
+
diff --git a/gcc/ada/s-trafor-default.adb b/gcc/ada/s-trafor-default.adb
new file mode 100644
index 00000000000..8aa564463ad
--- /dev/null
+++ b/gcc/ada/s-trafor-default.adb
@@ -0,0 +1,113 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T R A C E S . F O R M A T --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2001 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with System.Parameters;
+
+package body System.Traces.Format is
+
+ procedure Send_Trace (Id : Trace_T; Info : String) is separate;
+
+ ------------------
+ -- Format_Trace --
+ ------------------
+
+ function Format_Trace (Source : in String) return String_Trace is
+ Length : Integer := Source'Length;
+ Result : String_Trace := (others => ' ');
+
+ begin
+ -- If run-time tracing active, then fill the string
+
+ if Parameters.Runtime_Traces then
+ if Max_Size - Length > 0 then
+ Result (1 .. Length) := Source (1 .. Length);
+ Result (Length + 1 .. Max_Size) := (others => ' ');
+ Result (Length + 1) := ASCII.NUL;
+ else
+ Result (1 .. Max_Size - 1) := Source (1 .. Max_Size - 1);
+ Result (Max_Size) := ASCII.NUL;
+ end if;
+ end if;
+
+ return Result;
+ end Format_Trace;
+
+ ------------
+ -- Append --
+ ------------
+
+ function Append
+ (Source : String_Trace;
+ Annex : String)
+ return String_Trace
+ is
+ Result : String_Trace := (others => ' ');
+ Source_Length : Integer := 1;
+ Annex_Length : Integer := Annex'Length;
+
+ begin
+ if Parameters.Runtime_Traces then
+
+ -- First we determine the size used, without the spaces at the
+ -- end, if a String_Trace is present. Look at
+ -- System.Traces.Tasking for examples.
+
+ while Source (Source_Length) /= ASCII.NUL loop
+ Source_Length := Source_Length + 1;
+ end loop;
+
+ -- Then we fill the string.
+
+ if Source_Length - 1 + Annex_Length <= Max_Size then
+ Result (1 .. Source_Length - 1) :=
+ Source (1 .. Source_Length - 1);
+
+ Result (Source_Length .. Source_Length - 1 + Annex_Length) :=
+ Annex (1 .. Annex_Length);
+
+ Result (Source_Length + Annex_Length) := ASCII.NUL;
+
+ Result (Source_Length + Annex_Length + 1 .. Max_Size) :=
+ (others => ' ');
+ else
+ Result (1 .. Source_Length - 1) := Source (1 .. Source_Length - 1);
+ Result (Source_Length .. Max_Size - 1) :=
+ Annex (1 .. Max_Size - Source_Length);
+ Result (Max_Size) := ASCII.NUL;
+ end if;
+ end if;
+
+ return Result;
+ end Append;
+
+end System.Traces.Format;
diff --git a/gcc/ada/s-trafor-default.ads b/gcc/ada/s-trafor-default.ads
new file mode 100644
index 00000000000..fe232beeea8
--- /dev/null
+++ b/gcc/ada/s-trafor-default.ads
@@ -0,0 +1,62 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T R A C E S . F O R M A T --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2001 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package implements functions to format run-time traces
+
+package System.Traces.Format is
+
+ Max_Size : constant Integer := 128;
+ -- Event messages' maximum size.
+
+ subtype String_Trace is String (1 .. Max_Size);
+ -- Specific type in which trace information is stored. An ASCII.NUL
+ -- character ends the string so that it is compatible with C strings
+ -- which is useful on some targets (eg. VxWorks)
+
+ -- These private functions handles String_Trace formatting
+
+ function Format_Trace (Source : String) return String_Trace;
+ -- Put a String in a String_Trace, truncates the string if necessary.
+ -- Similar to Head( .. ) found in Ada.Strings.Bounded
+
+ function Append
+ (Source : String_Trace;
+ Annex : String)
+ return String_Trace;
+ pragma Inline (Append);
+ -- Concatenates two string, similar to & operator from Ada.String.Unbounded
+
+ procedure Send_Trace (Id : Trace_T; Info : String);
+ -- This function (which is a subunit) send messages to external programs
+
+end System.Traces.Format;
diff --git a/gcc/ada/s-tratas-default.adb b/gcc/ada/s-tratas-default.adb
new file mode 100644
index 00000000000..0e18aed2d96
--- /dev/null
+++ b/gcc/ada/s-tratas-default.adb
@@ -0,0 +1,367 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . T R A C E S . T A S K I N G --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2001-2002 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with System.Tasking; use System.Tasking;
+with System.Soft_Links;
+with System.Parameters;
+with System.Traces.Format; use System.Traces.Format;
+with System.Traces; use System.Traces;
+
+package body System.Traces.Tasking is
+
+ use System.Tasking;
+ use System.Traces;
+ use System.Traces.Format;
+
+ package SSL renames System.Soft_Links;
+
+ function Extract_Accepts (Task_Name : Task_ID) return String_Trace;
+ -- This function is used to extract data joined with
+ -- W_Select, WT_Select, W_Accept events
+
+ ---------------------
+ -- Send_Trace_Info --
+ ---------------------
+
+ procedure Send_Trace_Info (Id : Trace_T; Task_Name2 : Task_ID) is
+ Task_S : constant String := SSL.Task_Name.all;
+ Task2_S : constant String :=
+ Task_Name2.Common.Task_Image
+ (1 .. Task_Name2.Common.Task_Image_Len);
+ Trace_S : String (1 .. 6 + Task_S'Length + Task2_S'Length);
+
+ L0 : Integer := Task_S'Length;
+ L1 : Integer := Task2_S'Length;
+
+ begin
+ if Parameters.Runtime_Traces then
+ case Id is
+ when M_RDV_Complete | PO_Done =>
+ Trace_S (1 .. 3) := "/N:";
+ Trace_S (4 .. 3 + L0) := Task_S;
+ Trace_S (4 + L0 .. 6 + L0) := "/C:";
+ Trace_S (7 + L0 .. Trace_S'Last) := Task2_S;
+ Send_Trace (Id, Trace_S);
+
+ when E_Missed =>
+ Trace_S (1 .. 3) := "/N:";
+ Trace_S (4 .. 3 + L0) := Task_S;
+ Trace_S (4 + L0 .. 6 + L0) := "/A:";
+ Trace_S (7 + L0 .. Trace_S'Last) := Task2_S;
+ Send_Trace (Id, Trace_S);
+
+ when E_Kill =>
+ Trace_S (1 .. 3) := "/N:";
+ Trace_S (4 .. 3 + L1) := Task2_S;
+ Trace_S (4 + L1 .. Trace_S'Last) := (others => ' ');
+ Send_Trace (Id, Trace_S);
+
+ when T_Create =>
+ Trace_S (1 .. 3) := "/N:";
+ Trace_S (4 .. 3 + L1) := Task2_S;
+ Trace_S (4 + L1 .. Trace_S'Last) := (others => ' ');
+ Send_Trace (Id, Trace_S);
+
+ when others =>
+ null;
+ -- should raise an exception ???
+ end case;
+ end if;
+ end Send_Trace_Info;
+
+ procedure Send_Trace_Info
+ (Id : Trace_T;
+ Task_Name2 : Task_ID;
+ Entry_Number : Entry_Index)
+ is
+ Task_S : constant String := SSL.Task_Name.all;
+ Task2_S : constant String :=
+ Task_Name2.Common.Task_Image
+ (1 .. Task_Name2.Common.Task_Image_Len);
+ Entry_S : String := Integer'Image (Integer (Entry_Number));
+ Trace_S : String (1 .. 9 + Task_S'Length
+ + Task2_S'Length + Entry_S'Length);
+
+ L0 : Integer := Task_S'Length;
+ L1 : Integer := Task_S'Length + Entry_S'Length;
+ L2 : Integer := Task_S'Length + Task2_S'Length;
+
+ begin
+ if Parameters.Runtime_Traces then
+ case Id is
+ when M_Accept_Complete =>
+ Trace_S (1 .. 3) := "/N:";
+ Trace_S (4 .. 3 + L0) := Task_S;
+ Trace_S (4 + L0 .. 6 + L0) := "/E:";
+ Trace_S (7 + L0 .. 6 + L1) := Entry_S;
+ Trace_S (7 + L1 .. 9 + L1) := "/C:";
+ Trace_S (10 + L1 .. Trace_S'Last) := Task2_S;
+ Send_Trace (Id, Trace_S);
+
+ when W_Call =>
+ Trace_S (1 .. 3) := "/N:";
+ Trace_S (4 .. 3 + L0) := Task_S;
+ Trace_S (4 + L0 .. 6 + L0) := "/A:";
+ Trace_S (7 + L0 .. 6 + L2) := Task2_S;
+ Trace_S (7 + L2 .. 9 + L2) := "/C:";
+ Trace_S (10 + L2 .. Trace_S'Last) := Entry_S;
+ Send_Trace (Id, Trace_S);
+
+ when others =>
+ null;
+ -- should raise an exception ???
+ end case;
+ end if;
+ end Send_Trace_Info;
+
+ procedure Send_Trace_Info
+ (Id : Trace_T;
+ Task_Name : Task_ID;
+ Task_Name2 : Task_ID;
+ Entry_Number : Entry_Index)
+ is
+ Task_S : constant String :=
+ Task_Name.Common.Task_Image
+ (1 .. Task_Name.Common.Task_Image_Len);
+ Task2_S : constant String :=
+ Task_Name2.Common.Task_Image
+ (1 .. Task_Name2.Common.Task_Image_Len);
+ Entry_S : String := Integer'Image (Integer (Entry_Number));
+ Trace_S : String (1 .. 9 + Task_S'Length
+ + Task2_S'Length + Entry_S'Length);
+
+ L0 : Integer := Task_S'Length;
+ L1 : Integer := Task_S'Length + Entry_S'Length;
+
+ begin
+ if Parameters.Runtime_Traces then
+ case Id is
+ when PO_Run =>
+ Trace_S (1 .. 3) := "/N:";
+ Trace_S (4 .. 3 + L0) := Task_S;
+ Trace_S (4 + L0 .. 6 + L0) := "/E:";
+ Trace_S (7 + L0 .. 6 + L1) := Entry_S;
+ Trace_S (7 + L1 .. 9 + L1) := "/C:";
+ Trace_S (10 + L1 .. Trace_S'Last) := Task2_S;
+ Send_Trace (Id, Trace_S);
+
+ when others =>
+ null;
+ -- should raise an exception ???
+ end case;
+ end if;
+ end Send_Trace_Info;
+
+ procedure Send_Trace_Info (Id : Trace_T; Entry_Number : Entry_Index) is
+ Task_S : String := SSL.Task_Name.all;
+ Entry_S : String := Integer'Image (Integer (Entry_Number));
+ Trace_S : String (1 .. 6 + Task_S'Length + Entry_S'Length);
+
+ L0 : Integer := Task_S'Length;
+
+ begin
+ if Parameters.Runtime_Traces then
+ Trace_S (1 .. 3) := "/N:";
+ Trace_S (4 .. 3 + L0) := Task_S;
+ Trace_S (4 + L0 .. 6 + L0) := "/E:";
+ Trace_S (7 + L0 .. Trace_S'Last) := Entry_S;
+ Send_Trace (Id, Trace_S);
+ end if;
+ end Send_Trace_Info;
+
+ procedure Send_Trace_Info
+ (Id : Trace_T;
+ Task_Name : Task_ID;
+ Task_Name2 : Task_ID)
+ is
+ Task_S : constant String :=
+ Task_Name.Common.Task_Image
+ (1 .. Task_Name.Common.Task_Image_Len);
+ Task2_S : constant String :=
+ Task_Name2.Common.Task_Image
+ (1 .. Task_Name2.Common.Task_Image_Len);
+ Trace_S : String (1 .. 6 + Task_S'Length + Task2_S'Length);
+
+ L0 : Integer := Task2_S'Length;
+
+ begin
+ if Parameters.Runtime_Traces then
+ Trace_S (1 .. 3) := "/N:";
+ Trace_S (4 .. 3 + L0) := Task2_S;
+ Trace_S (4 + L0 .. 6 + L0) := "/P:";
+ Trace_S (7 + L0 .. Trace_S'Last) := Task_S;
+ Send_Trace (Id, Trace_S);
+ end if;
+ end Send_Trace_Info;
+
+ procedure Send_Trace_Info
+ (Id : Trace_T;
+ Acceptor : Task_ID;
+ Entry_Number : Entry_Index;
+ Timeout : Duration)
+ is
+ Task_S : constant String := SSL.Task_Name.all;
+ Acceptor_S : constant String :=
+ Acceptor.Common.Task_Image
+ (1 .. Acceptor.Common.Task_Image_Len);
+ Entry_S : String := Integer'Image (Integer (Entry_Number));
+ Timeout_S : String := Duration'Image (Timeout);
+ Trace_S : String (1 .. 12 + Task_S'Length + Acceptor_S'Length
+ + Entry_S'Length + Timeout_S'Length);
+
+ L0 : Integer := Task_S'Length;
+ L1 : Integer := Task_S'Length + Acceptor_S'Length;
+ L2 : Integer := Task_S'Length + Acceptor_S'Length + Entry_S'Length;
+
+ begin
+ if Parameters.Runtime_Traces then
+ Trace_S (1 .. 3) := "/N:";
+ Trace_S (4 .. 3 + L0) := Task_S;
+ Trace_S (4 + L0 .. 6 + L0) := "/A:";
+ Trace_S (7 + L0 .. 6 + L1) := Acceptor_S;
+ Trace_S (7 + L1 .. 9 + L1) := "/E:";
+ Trace_S (10 + L1 .. 9 + L2) := Entry_S;
+ Trace_S (10 + L2 .. 12 + L2) := "/T:";
+ Trace_S (13 + L2 .. Trace_S'Last) := Timeout_S;
+ Send_Trace (Id, Trace_S);
+ end if;
+ end Send_Trace_Info;
+
+ procedure Send_Trace_Info
+ (Id : Trace_T;
+ Entry_Number : Entry_Index;
+ Timeout : Duration)
+ is
+ Task_S : String := SSL.Task_Name.all;
+ Entry_S : String := Integer'Image (Integer (Entry_Number));
+ Timeout_S : String := Duration'Image (Timeout);
+ Trace_S : String (1 .. 9 + Task_S'Length
+ + Entry_S'Length + Timeout_S'Length);
+
+ L0 : Integer := Task_S'Length;
+ L1 : Integer := Task_S'Length + Entry_S'Length;
+
+ begin
+ if Parameters.Runtime_Traces then
+ Trace_S (1 .. 3) := "/N:";
+ Trace_S (4 .. 3 + L0) := Task_S;
+ Trace_S (4 + L0 .. 6 + L0) := "/E:";
+ Trace_S (7 + L0 .. 6 + L1) := Entry_S;
+ Trace_S (7 + L1 .. 9 + L1) := "/T:";
+ Trace_S (10 + L1 .. Trace_S'Last) := Timeout_S;
+ Send_Trace (Id, Trace_S);
+ end if;
+ end Send_Trace_Info;
+
+ procedure Send_Trace_Info
+ (Id : Trace_T;
+ Task_Name : Task_ID;
+ Number : Integer)
+ is
+ Task_S : String := SSL.Task_Name.all;
+ Number_S : String := Integer'Image (Number);
+ Accepts_S : String := Extract_Accepts (Task_Name);
+ Trace_S : String (1 .. 9 + Task_S'Length
+ + Number_S'Length + Accepts_S'Length);
+
+ L0 : Integer := Task_S'Length;
+ L1 : Integer := Task_S'Length + Number_S'Length;
+
+ begin
+ if Parameters.Runtime_Traces then
+ Trace_S (1 .. 3) := "/N:";
+ Trace_S (4 .. 3 + L0) := Task_S;
+ Trace_S (4 + L0 .. 6 + L0) := "/#:";
+ Trace_S (7 + L0 .. 6 + L1) := Number_S;
+ Trace_S (7 + L1 .. 9 + L1) := "/E:";
+ Trace_S (10 + L1 .. Trace_S'Last) := Accepts_S;
+ Send_Trace (Id, Trace_S);
+ end if;
+ end Send_Trace_Info;
+
+ procedure Send_Trace_Info
+ (Id : Trace_T;
+ Task_Name : Task_ID;
+ Number : Integer;
+ Timeout : Duration)
+ is
+ Task_S : String := SSL.Task_Name.all;
+ Timeout_S : String := Duration'Image (Timeout);
+ Number_S : String := Integer'Image (Number);
+ Accepts_S : String := Extract_Accepts (Task_Name);
+ Trace_S : String (1 .. 12 + Task_S'Length + Timeout_S'Length
+ + Number_S'Length + Accepts_S'Length);
+
+ L0 : Integer := Task_S'Length;
+ L1 : Integer := Task_S'Length + Timeout_S'Length;
+ L2 : Integer := Task_S'Length + Timeout_S'Length + Number_S'Length;
+
+ begin
+ if Parameters.Runtime_Traces then
+ Trace_S (1 .. 3) := "/N:";
+ Trace_S (4 .. 3 + L0) := Task_S;
+ Trace_S (4 + L0 .. 6 + L0) := "/T:";
+ Trace_S (7 + L0 .. 6 + L1) := Timeout_S;
+ Trace_S (7 + L1 .. 9 + L1) := "/#:";
+ Trace_S (10 + L1 .. 9 + L2) := Number_S;
+ Trace_S (10 + L2 .. 12 + L2) := "/E:";
+ Trace_S (13 + L2 .. Trace_S'Last) := Accepts_S;
+ Send_Trace (Id, Trace_S);
+ end if;
+ end Send_Trace_Info;
+
+ ---------------------
+ -- Extract_Accepts --
+ ---------------------
+
+ -- This function returns a string in which all opened
+ -- Accepts or Selects are given, separated by semi-colons.
+
+ function Extract_Accepts (Task_Name : Task_ID) return String_Trace is
+ Info_Annex : String_Trace := (ASCII.NUL, others => ' ');
+
+ begin
+ for J in Task_Name.Open_Accepts'First ..
+ Task_Name.Open_Accepts'Last - 1
+ loop
+ Info_Annex := Append (Info_Annex, Integer'Image
+ (Integer (Task_Name.Open_Accepts (J).S)) & ",");
+ end loop;
+
+ Info_Annex := Append (Info_Annex,
+ Integer'Image (Integer
+ (Task_Name.Open_Accepts
+ (Task_Name.Open_Accepts'Last).S)));
+ return Info_Annex;
+ end Extract_Accepts;
+end System.Traces.Tasking;
diff --git a/gcc/ada/s-vaflop-vms.adb b/gcc/ada/s-vaflop-vms.adb
new file mode 100644
index 00000000000..8b1bf031fa4
--- /dev/null
+++ b/gcc/ada/s-vaflop-vms.adb
@@ -0,0 +1,621 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . V A X _ F L O A T _ O P E R A T I O N S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1997-2000 Free Software Foundation, Inc. --
+-- (Version for Alpha OpenVMS) --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with System.IO; use System.IO;
+with System.Machine_Code; use System.Machine_Code;
+
+package body System.Vax_Float_Operations is
+
+ -- Ensure this gets compiled with -O to avoid extra (and possibly
+ -- improper) memory stores.
+
+ pragma Optimize (Time);
+
+ -- Declare the functions that do the conversions between floating-point
+ -- formats. Call the operands IEEE float so they get passed in
+ -- FP registers.
+
+ function Cvt_G_T (X : T) return T;
+ function Cvt_T_G (X : T) return T;
+ function Cvt_T_F (X : T) return S;
+
+ pragma Import (C, Cvt_G_T, "OTS$CVT_FLOAT_G_T");
+ pragma Import (C, Cvt_T_G, "OTS$CVT_FLOAT_T_G");
+ pragma Import (C, Cvt_T_F, "OTS$CVT_FLOAT_T_F");
+
+ -- In each of the conversion routines that are done with OTS calls,
+ -- we define variables of the corresponding IEEE type so that they are
+ -- passed and kept in the proper register class.
+
+ ------------
+ -- D_To_G --
+ ------------
+
+ function D_To_G (X : D) return G is
+ A, B : T;
+ C : G;
+
+ begin
+ Asm ("ldg %0,%1", T'Asm_Output ("=f", A), D'Asm_Input ("m", X));
+ Asm ("cvtdg %1,%0", T'Asm_Output ("=f", B), T'Asm_Input ("f", A));
+ Asm ("stg %1,%0", G'Asm_Output ("=m", C), T'Asm_Input ("f", B));
+ return C;
+ end D_To_G;
+
+ ------------
+ -- F_To_G --
+ ------------
+
+ function F_To_G (X : F) return G is
+ A : T;
+ B : G;
+
+ begin
+ Asm ("ldf %0,%1", T'Asm_Output ("=f", A), F'Asm_Input ("m", X));
+ Asm ("stg %1,%0", G'Asm_Output ("=m", B), T'Asm_Input ("f", A));
+ return B;
+ end F_To_G;
+
+ ------------
+ -- F_To_S --
+ ------------
+
+ function F_To_S (X : F) return S is
+ A : T;
+ B : S;
+
+ begin
+ -- Because converting to a wider FP format is a no-op, we say
+ -- A is 64-bit even though we are loading 32 bits into it.
+ Asm ("ldf %0,%1", T'Asm_Output ("=f", A), F'Asm_Input ("m", X));
+
+ B := S (Cvt_G_T (A));
+ return B;
+ end F_To_S;
+
+ ------------
+ -- G_To_D --
+ ------------
+
+ function G_To_D (X : G) return D is
+ A, B : T;
+ C : D;
+
+ begin
+ Asm ("ldg %0,%1", T'Asm_Output ("=f", A), G'Asm_Input ("m", X));
+ Asm ("cvtgd %1,%0", T'Asm_Output ("=f", B), T'Asm_Input ("f", A));
+ Asm ("stg %1,%0", D'Asm_Output ("=m", C), T'Asm_Input ("f", B));
+ return C;
+ end G_To_D;
+
+ ------------
+ -- G_To_F --
+ ------------
+
+ function G_To_F (X : G) return F is
+ A : T;
+ B : S;
+ C : F;
+
+ begin
+ Asm ("ldg %0,%1", T'Asm_Output ("=f", A), G'Asm_Input ("m", X));
+ Asm ("cvtgf %1,%0", S'Asm_Output ("=f", B), T'Asm_Input ("f", A));
+ Asm ("stf %1,%0", F'Asm_Output ("=m", C), S'Asm_Input ("f", B));
+ return C;
+ end G_To_F;
+
+ ------------
+ -- G_To_Q --
+ ------------
+
+ function G_To_Q (X : G) return Q is
+ A : T;
+ B : Q;
+
+ begin
+ Asm ("ldg %0,%1", T'Asm_Output ("=f", A), G'Asm_Input ("m", X));
+ Asm ("cvtgq %1,%0", Q'Asm_Output ("=f", B), T'Asm_Input ("f", A));
+ return B;
+ end G_To_Q;
+
+ ------------
+ -- G_To_T --
+ ------------
+
+ function G_To_T (X : G) return T is
+ A, B : T;
+
+ begin
+ Asm ("ldg %0,%1", T'Asm_Output ("=f", A), G'Asm_Input ("m", X));
+ B := Cvt_G_T (A);
+ return B;
+ end G_To_T;
+
+ ------------
+ -- F_To_Q --
+ ------------
+
+ function F_To_Q (X : F) return Q is
+ begin
+ return G_To_Q (F_To_G (X));
+ end F_To_Q;
+
+ ------------
+ -- Q_To_F --
+ ------------
+
+ function Q_To_F (X : Q) return F is
+ A : S;
+ B : F;
+
+ begin
+ Asm ("cvtqf %1,%0", S'Asm_Output ("=f", A), Q'Asm_Input ("f", X));
+ Asm ("stf %1,%0", F'Asm_Output ("=m", B), S'Asm_Input ("f", A));
+ return B;
+ end Q_To_F;
+
+ ------------
+ -- Q_To_G --
+ ------------
+
+ function Q_To_G (X : Q) return G is
+ A : T;
+ B : G;
+
+ begin
+ Asm ("cvtqg %1,%0", T'Asm_Output ("=f", A), Q'Asm_Input ("f", X));
+ Asm ("stg %1,%0", G'Asm_Output ("=m", B), T'Asm_Input ("f", A));
+ return B;
+ end Q_To_G;
+
+ ------------
+ -- S_To_F --
+ ------------
+
+ function S_To_F (X : S) return F is
+ A : S;
+ B : F;
+
+ begin
+ A := Cvt_T_F (T (X));
+ Asm ("stf %1,%0", F'Asm_Output ("=m", B), S'Asm_Input ("f", A));
+ return B;
+ end S_To_F;
+
+ ------------
+ -- T_To_D --
+ ------------
+
+ function T_To_D (X : T) return D is
+ begin
+ return G_To_D (T_To_G (X));
+ end T_To_D;
+
+ ------------
+ -- T_To_G --
+ ------------
+
+ function T_To_G (X : T) return G is
+ A : T;
+ B : G;
+
+ begin
+ A := Cvt_T_G (X);
+ Asm ("stg %1,%0", G'Asm_Output ("=m", B), T'Asm_Input ("f", A));
+ return B;
+ end T_To_G;
+
+ -----------
+ -- Abs_F --
+ -----------
+
+ function Abs_F (X : F) return F is
+ A, B : S;
+ C : F;
+
+ begin
+ Asm ("ldf %0,%1", S'Asm_Output ("=f", A), F'Asm_Input ("m", X));
+ Asm ("cpys $f31,%1,%0", S'Asm_Output ("=f", B), S'Asm_Input ("f", A));
+ Asm ("stf %1,%0", F'Asm_Output ("=m", C), S'Asm_Input ("f", B));
+ return C;
+ end Abs_F;
+
+ -----------
+ -- Abs_G --
+ -----------
+
+ function Abs_G (X : G) return G is
+ A, B : T;
+ C : G;
+
+ begin
+ Asm ("ldg %0,%1", T'Asm_Output ("=f", A), G'Asm_Input ("m", X));
+ Asm ("cpys $f31,%1,%0", T'Asm_Output ("=f", B), T'Asm_Input ("f", A));
+ Asm ("stg %1,%0", G'Asm_Output ("=m", C), T'Asm_Input ("f", B));
+ return C;
+ end Abs_G;
+
+ -----------
+ -- Add_F --
+ -----------
+
+ function Add_F (X, Y : F) return F is
+ X1, Y1, R : S;
+ R1 : F;
+
+ begin
+ Asm ("ldf %0,%1", S'Asm_Output ("=f", X1), F'Asm_Input ("m", X));
+ Asm ("ldf %0,%1", S'Asm_Output ("=f", Y1), F'Asm_Input ("m", Y));
+ Asm ("addf %1,%2,%0", S'Asm_Output ("=f", R),
+ (S'Asm_Input ("f", X1), S'Asm_Input ("f", Y1)));
+ Asm ("stf %1,%0", F'Asm_Output ("=m", R1), S'Asm_Input ("f", R));
+ return R1;
+ end Add_F;
+
+ -----------
+ -- Add_G --
+ -----------
+
+ function Add_G (X, Y : G) return G is
+ X1, Y1, R : T;
+ R1 : G;
+
+ begin
+ Asm ("ldg %0,%1", T'Asm_Output ("=f", X1), G'Asm_Input ("m", X));
+ Asm ("ldg %0,%1", T'Asm_Output ("=f", Y1), G'Asm_Input ("m", Y));
+ Asm ("addg %1,%2,%0", T'Asm_Output ("=f", R),
+ (T'Asm_Input ("f", X1), T'Asm_Input ("f", Y1)));
+ Asm ("stg %1,%0", G'Asm_Output ("=m", R1), T'Asm_Input ("f", R));
+ return R1;
+ end Add_G;
+
+ --------------------
+ -- Debug_Output_D --
+ --------------------
+
+ procedure Debug_Output_D (Arg : D) is
+ begin
+ Put (D'Image (Arg));
+ end Debug_Output_D;
+
+ --------------------
+ -- Debug_Output_F --
+ --------------------
+
+ procedure Debug_Output_F (Arg : F) is
+ begin
+ Put (F'Image (Arg));
+ end Debug_Output_F;
+
+ --------------------
+ -- Debug_Output_G --
+ --------------------
+
+ procedure Debug_Output_G (Arg : G) is
+ begin
+ Put (G'Image (Arg));
+ end Debug_Output_G;
+
+ --------------------
+ -- Debug_String_D --
+ --------------------
+
+ Debug_String_Buffer : String (1 .. 32);
+ -- Buffer used by all Debug_String_x routines for returning result
+
+ function Debug_String_D (Arg : D) return System.Address is
+ Image_String : constant String := D'Image (Arg) & ASCII.NUL;
+ Image_Size : constant Integer := Image_String'Length;
+
+ begin
+ Debug_String_Buffer (1 .. Image_Size) := Image_String;
+ return Debug_String_Buffer (1)'Address;
+ end Debug_String_D;
+
+ --------------------
+ -- Debug_String_F --
+ --------------------
+
+ function Debug_String_F (Arg : F) return System.Address is
+ Image_String : constant String := F'Image (Arg) & ASCII.NUL;
+ Image_Size : constant Integer := Image_String'Length;
+
+ begin
+ Debug_String_Buffer (1 .. Image_Size) := Image_String;
+ return Debug_String_Buffer (1)'Address;
+ end Debug_String_F;
+
+ --------------------
+ -- Debug_String_G --
+ --------------------
+
+ function Debug_String_G (Arg : G) return System.Address is
+ Image_String : constant String := G'Image (Arg) & ASCII.NUL;
+ Image_Size : constant Integer := Image_String'Length;
+
+ begin
+ Debug_String_Buffer (1 .. Image_Size) := Image_String;
+ return Debug_String_Buffer (1)'Address;
+ end Debug_String_G;
+
+ -----------
+ -- Div_F --
+ -----------
+
+ function Div_F (X, Y : F) return F is
+ X1, Y1, R : S;
+
+ R1 : F;
+ begin
+ Asm ("ldf %0,%1", S'Asm_Output ("=f", X1), F'Asm_Input ("m", X));
+ Asm ("ldf %0,%1", S'Asm_Output ("=f", Y1), F'Asm_Input ("m", Y));
+ Asm ("divf %1,%2,%0", S'Asm_Output ("=f", R),
+ (S'Asm_Input ("f", X1), S'Asm_Input ("f", Y1)));
+ Asm ("stf %1,%0", F'Asm_Output ("=m", R1), S'Asm_Input ("f", R));
+ return R1;
+ end Div_F;
+
+ -----------
+ -- Div_G --
+ -----------
+
+ function Div_G (X, Y : G) return G is
+ X1, Y1, R : T;
+ R1 : G;
+
+ begin
+ Asm ("ldg %0,%1", T'Asm_Output ("=f", X1), G'Asm_Input ("m", X));
+ Asm ("ldg %0,%1", T'Asm_Output ("=f", Y1), G'Asm_Input ("m", Y));
+ Asm ("divg %1,%2,%0", T'Asm_Output ("=f", R),
+ (T'Asm_Input ("f", X1), T'Asm_Input ("f", Y1)));
+ Asm ("stg %1,%0", G'Asm_Output ("=m", R1), T'Asm_Input ("f", R));
+ return R1;
+ end Div_G;
+
+ ----------
+ -- Eq_F --
+ ----------
+
+ function Eq_F (X, Y : F) return Boolean is
+ X1, Y1, R : S;
+
+ begin
+ Asm ("ldf %0,%1", S'Asm_Output ("=f", X1), F'Asm_Input ("m", X));
+ Asm ("ldf %0,%1", S'Asm_Output ("=f", Y1), F'Asm_Input ("m", Y));
+ Asm ("cmpgeq %1,%2,%0", S'Asm_Output ("=f", R),
+ (S'Asm_Input ("f", X1), S'Asm_Input ("f", Y1)));
+ return R /= 0.0;
+ end Eq_F;
+
+ ----------
+ -- Eq_G --
+ ----------
+
+ function Eq_G (X, Y : G) return Boolean is
+ X1, Y1, R : T;
+
+ begin
+ Asm ("ldg %0,%1", T'Asm_Output ("=f", X1), G'Asm_Input ("m", X));
+ Asm ("ldg %0,%1", T'Asm_Output ("=f", Y1), G'Asm_Input ("m", Y));
+ Asm ("cmpgeq %1,%2,%0", T'Asm_Output ("=f", R),
+ (T'Asm_Input ("f", X1), T'Asm_Input ("f", Y1)));
+ return R /= 0.0;
+ end Eq_G;
+
+ ----------
+ -- Le_F --
+ ----------
+
+ function Le_F (X, Y : F) return Boolean is
+ X1, Y1, R : S;
+
+ begin
+ Asm ("ldf %0,%1", S'Asm_Output ("=f", X1), F'Asm_Input ("m", X));
+ Asm ("ldf %0,%1", S'Asm_Output ("=f", Y1), F'Asm_Input ("m", Y));
+ Asm ("cmpgle %1,%2,%0", S'Asm_Output ("=f", R),
+ (S'Asm_Input ("f", X1), S'Asm_Input ("f", Y1)));
+ return R /= 0.0;
+ end Le_F;
+
+ ----------
+ -- Le_G --
+ ----------
+
+ function Le_G (X, Y : G) return Boolean is
+ X1, Y1, R : T;
+
+ begin
+ Asm ("ldg %0,%1", T'Asm_Output ("=f", X1), G'Asm_Input ("m", X));
+ Asm ("ldg %0,%1", T'Asm_Output ("=f", Y1), G'Asm_Input ("m", Y));
+ Asm ("cmpgle %1,%2,%0", T'Asm_Output ("=f", R),
+ (T'Asm_Input ("f", X1), T'Asm_Input ("f", Y1)));
+ return R /= 0.0;
+ end Le_G;
+
+ ----------
+ -- Lt_F --
+ ----------
+
+ function Lt_F (X, Y : F) return Boolean is
+ X1, Y1, R : S;
+
+ begin
+ Asm ("ldf %0,%1", S'Asm_Output ("=f", X1), F'Asm_Input ("m", X));
+ Asm ("ldf %0,%1", S'Asm_Output ("=f", Y1), F'Asm_Input ("m", Y));
+ Asm ("cmpglt %1,%2,%0", S'Asm_Output ("=f", R),
+ (S'Asm_Input ("f", X1), S'Asm_Input ("f", Y1)));
+ return R /= 0.0;
+ end Lt_F;
+
+ ----------
+ -- Lt_G --
+ ----------
+
+ function Lt_G (X, Y : G) return Boolean is
+ X1, Y1, R : T;
+
+ begin
+ Asm ("ldg %0,%1", T'Asm_Output ("=f", X1), G'Asm_Input ("m", X));
+ Asm ("ldg %0,%1", T'Asm_Output ("=f", Y1), G'Asm_Input ("m", Y));
+ Asm ("cmpglt %1,%2,%0", T'Asm_Output ("=f", R),
+ (T'Asm_Input ("f", X1), T'Asm_Input ("f", Y1)));
+ return R /= 0.0;
+ end Lt_G;
+
+ -----------
+ -- Mul_F --
+ -----------
+
+ function Mul_F (X, Y : F) return F is
+ X1, Y1, R : S;
+ R1 : F;
+
+ begin
+ Asm ("ldf %0,%1", S'Asm_Output ("=f", X1), F'Asm_Input ("m", X));
+ Asm ("ldf %0,%1", S'Asm_Output ("=f", Y1), F'Asm_Input ("m", Y));
+ Asm ("mulf %1,%2,%0", S'Asm_Output ("=f", R),
+ (S'Asm_Input ("f", X1), S'Asm_Input ("f", Y1)));
+ Asm ("stf %1,%0", F'Asm_Output ("=m", R1), S'Asm_Input ("f", R));
+ return R1;
+ end Mul_F;
+
+ -----------
+ -- Mul_G --
+ -----------
+
+ function Mul_G (X, Y : G) return G is
+ X1, Y1, R : T;
+ R1 : G;
+
+ begin
+ Asm ("ldg %0,%1", T'Asm_Output ("=f", X1), G'Asm_Input ("m", X));
+ Asm ("ldg %0,%1", T'Asm_Output ("=f", Y1), G'Asm_Input ("m", Y));
+ Asm ("mulg %1,%2,%0", T'Asm_Output ("=f", R),
+ (T'Asm_Input ("f", X1), T'Asm_Input ("f", Y1)));
+ Asm ("stg %1,%0", G'Asm_Output ("=m", R1), T'Asm_Input ("f", R));
+ return R1;
+ end Mul_G;
+
+ -----------
+ -- Neg_F --
+ -----------
+
+ function Neg_F (X : F) return F is
+ A, B : S;
+ C : F;
+
+ begin
+ Asm ("ldf %0,%1", S'Asm_Output ("=f", A), F'Asm_Input ("m", X));
+ Asm ("cpysn %1,%1,%0", S'Asm_Output ("=f", B), S'Asm_Input ("f", A));
+ Asm ("stf %1,%0", F'Asm_Output ("=m", C), S'Asm_Input ("f", B));
+ return C;
+ end Neg_F;
+
+ -----------
+ -- Neg_G --
+ -----------
+
+ function Neg_G (X : G) return G is
+ A, B : T;
+ C : G;
+
+ begin
+ Asm ("ldg %0,%1", T'Asm_Output ("=f", A), G'Asm_Input ("m", X));
+ Asm ("cpysn %1,%1,%0", T'Asm_Output ("=f", B), T'Asm_Input ("f", A));
+ Asm ("stg %1,%0", G'Asm_Output ("=m", C), T'Asm_Input ("f", B));
+ return C;
+ end Neg_G;
+
+ --------
+ -- pd --
+ --------
+
+ procedure pd (Arg : D) is
+ begin
+ Put_Line (D'Image (Arg));
+ end pd;
+
+ --------
+ -- pf --
+ --------
+
+ procedure pf (Arg : F) is
+ begin
+ Put_Line (F'Image (Arg));
+ end pf;
+
+ --------
+ -- pg --
+ --------
+
+ procedure pg (Arg : G) is
+ begin
+ Put_Line (G'Image (Arg));
+ end pg;
+
+ -----------
+ -- Sub_F --
+ -----------
+
+ function Sub_F (X, Y : F) return F is
+ X1, Y1, R : S;
+ R1 : F;
+
+ begin
+ Asm ("ldf %0,%1", S'Asm_Output ("=f", X1), F'Asm_Input ("m", X));
+ Asm ("ldf %0,%1", S'Asm_Output ("=f", Y1), F'Asm_Input ("m", Y));
+ Asm ("subf %1,%2,%0", S'Asm_Output ("=f", R),
+ (S'Asm_Input ("f", X1), S'Asm_Input ("f", Y1)));
+ Asm ("stf %1,%0", F'Asm_Output ("=m", R1), S'Asm_Input ("f", R));
+ return R1;
+ end Sub_F;
+
+ -----------
+ -- Sub_G --
+ -----------
+
+ function Sub_G (X, Y : G) return G is
+ X1, Y1, R : T;
+ R1 : G;
+
+ begin
+ Asm ("ldg %0,%1", T'Asm_Output ("=f", X1), G'Asm_Input ("m", X));
+ Asm ("ldg %0,%1", T'Asm_Output ("=f", Y1), G'Asm_Input ("m", Y));
+ Asm ("subg %1,%2,%0", T'Asm_Output ("=f", R),
+ (T'Asm_Input ("f", X1), T'Asm_Input ("f", Y1)));
+ Asm ("stg %1,%0", G'Asm_Output ("=m", R1), T'Asm_Input ("f", R));
+ return R1;
+ end Sub_G;
+
+end System.Vax_Float_Operations;
diff --git a/gcc/ada/s-vxwork-alpha.ads b/gcc/ada/s-vxwork-alpha.ads
new file mode 100644
index 00000000000..6d5e424a33c
--- /dev/null
+++ b/gcc/ada/s-vxwork-alpha.ads
@@ -0,0 +1,57 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . V X W O R K S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1998-2001 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- --
+-- 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, 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, --
+-- 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 is the Alpha VxWorks version of this package.
+
+with Interfaces.C;
+
+package System.VxWorks is
+ pragma Preelaborate (System.VxWorks);
+
+ package IC renames Interfaces.C;
+
+ -- Floating point context record. Alpha version
+
+ FP_NUM_DREGS : constant := 32;
+ type Fpx_Array is array (1 .. FP_NUM_DREGS) of IC.double;
+
+ type FP_CONTEXT is record
+ fpx : Fpx_Array;
+ fpcsr : IC.long;
+ end record;
+ pragma Convention (C, FP_CONTEXT);
+
+ Num_HW_Interrupts : constant := 256;
+ -- Number of entries in hardware interrupt vector table.
+
+end System.VxWorks;
diff --git a/gcc/ada/s-vxwork-m68k.ads b/gcc/ada/s-vxwork-m68k.ads
new file mode 100644
index 00000000000..a0f10be72a0
--- /dev/null
+++ b/gcc/ada/s-vxwork-m68k.ads
@@ -0,0 +1,76 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . V X W O R K S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1998-2001 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- --
+-- 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, 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, --
+-- 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 is the M68K VxWorks version of this package.
+
+with Interfaces.C;
+
+package System.VxWorks is
+ pragma Preelaborate (System.VxWorks);
+
+ package IC renames Interfaces.C;
+
+ -- Floating point context record. 68K version
+
+ FP_NUM_DREGS : constant := 8;
+ FP_STATE_FRAME_SIZE : constant := 216;
+
+ type DOUBLEX is array (1 .. 12) of Interfaces.Unsigned_8;
+ pragma Pack (DOUBLEX);
+ for DOUBLEX'Size use 12 * 8;
+
+ type DOUBLEX_Array is array (1 .. FP_NUM_DREGS) of DOUBLEX;
+ pragma Pack (DOUBLEX_Array);
+ for DOUBLEX_Array'Size use FP_NUM_DREGS * 12 * 8;
+
+ type FPREG_SET is record
+ fpcr : IC.int;
+ fpsr : IC.int;
+ fpiar : IC.int;
+ fpx : DOUBLEX_Array;
+ end record;
+
+ type Fp_State_Frame_Array is array (1 .. FP_STATE_FRAME_SIZE) of IC.char;
+ pragma Pack (Fp_State_Frame_Array);
+ for Fp_State_Frame_Array'Size use 8 * FP_STATE_FRAME_SIZE;
+
+ type FP_CONTEXT is record
+ fpRegSet : FPREG_SET;
+ stateFrame : Fp_State_Frame_Array;
+ end record;
+ pragma Convention (C, FP_CONTEXT);
+
+ Num_HW_Interrupts : constant := 256;
+ -- Number of entries in the hardware interrupt vector table
+
+end System.VxWorks;
diff --git a/gcc/ada/s-vxwork-mips.ads b/gcc/ada/s-vxwork-mips.ads
new file mode 100644
index 00000000000..2e31d728aed
--- /dev/null
+++ b/gcc/ada/s-vxwork-mips.ads
@@ -0,0 +1,57 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . V X W O R K S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1998-2001 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- --
+-- 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, 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, --
+-- 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 is the MIPS VxWorks version of this package.
+
+with Interfaces.C;
+
+package System.VxWorks is
+ pragma Preelaborate (System.VxWorks);
+
+ package IC renames Interfaces.C;
+
+ -- Floating point context record. MIPS version
+
+ FP_NUM_DREGS : constant := 16;
+ type Fpx_Array is array (1 .. FP_NUM_DREGS) of IC.double;
+
+ type FP_CONTEXT is record
+ fpx : Fpx_Array;
+ fpcsr : IC.int;
+ end record;
+ pragma Convention (C, FP_CONTEXT);
+
+ Num_HW_Interrupts : constant := 256;
+ -- Number of entries in hardware interrupt vector table.
+
+end System.VxWorks;
diff --git a/gcc/ada/s-vxwork-ppc.ads b/gcc/ada/s-vxwork-ppc.ads
new file mode 100644
index 00000000000..17118681fc3
--- /dev/null
+++ b/gcc/ada/s-vxwork-ppc.ads
@@ -0,0 +1,57 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . V X W O R K S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1998-2001 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- --
+-- 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, 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, --
+-- 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 is the PPC VxWorks version of this package.
+
+with Interfaces.C;
+
+package System.VxWorks is
+ pragma Preelaborate (System.VxWorks);
+
+ package IC renames Interfaces.C;
+
+ -- Floating point context record. PPC version
+
+ FP_NUM_DREGS : constant := 32;
+ type Fpr_Array is array (1 .. FP_NUM_DREGS) of IC.double;
+
+ type FP_CONTEXT is record
+ fpr : Fpr_Array;
+ fpcsr : IC.int;
+ pad : IC.int;
+ end record;
+ pragma Convention (C, FP_CONTEXT);
+
+ Num_HW_Interrupts : constant := 256;
+
+end System.VxWorks;
diff --git a/gcc/ada/s-vxwork-sparcv9.ads b/gcc/ada/s-vxwork-sparcv9.ads
new file mode 100644
index 00000000000..4fc9fd156e3
--- /dev/null
+++ b/gcc/ada/s-vxwork-sparcv9.ads
@@ -0,0 +1,62 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . V X W O R K S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1998-2002 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- --
+-- 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, 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, --
+-- 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 is the Sparc64 VxWorks version of this package.
+
+with Interfaces;
+
+package System.VxWorks is
+ pragma Preelaborate (System.VxWorks);
+
+ -- Floating point context record. SPARCV9 version
+
+ FP_NUM_DREGS : constant := 32;
+
+ type RType is new Interfaces.Unsigned_64;
+ for RType'Alignment use 8;
+
+ type Fpd_Array is array (1 .. FP_NUM_DREGS) of RType;
+ for Fpd_Array'Alignment use 8;
+
+ type FP_CONTEXT is record
+ fpd : Fpd_Array;
+ fsr : RType;
+ end record;
+
+ for FP_CONTEXT'Alignment use 8;
+ pragma Convention (C, FP_CONTEXT);
+
+ Num_HW_Interrupts : constant := 256;
+ -- Number of entries in hardware interrupt vector table.
+
+end System.VxWorks;
diff --git a/gcc/ada/s-vxwork-xscale.ads b/gcc/ada/s-vxwork-xscale.ads
new file mode 100644
index 00000000000..4183ee6bb1f
--- /dev/null
+++ b/gcc/ada/s-vxwork-xscale.ads
@@ -0,0 +1,54 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . V X W O R K S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1998-2002 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- --
+-- 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, 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, --
+-- 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 is the Xscale VxWorks version of this package.
+
+package System.VxWorks is
+ pragma Preelaborate (System.VxWorks);
+
+ -- Floating point context record. Xscale version
+
+ -- There is no floating point unit on Xscale. The record definition
+ -- below matches what arch/arm/fppArmLib.h says.
+
+ type FP_CONTEXT is record
+ Dummy : Integer;
+ end record;
+
+ for FP_CONTEXT'Alignment use 4;
+ pragma Convention (C, FP_CONTEXT);
+
+ Num_HW_Interrupts : constant := 256;
+ -- Number of entries in hardware interrupt vector table.
+
+end System.VxWorks;
diff --git a/gcc/ada/scn.adb b/gcc/ada/scn.adb
index 0398551d5dd..5e8fbbf2298 100644
--- a/gcc/ada/scn.adb
+++ b/gcc/ada/scn.adb
@@ -26,7 +26,6 @@
with Atree; use Atree;
with Csets; use Csets;
-with Hostparm;
with Namet; use Namet;
with Opt; use Opt;
with Scans; use Scans;
@@ -99,13 +98,11 @@ package body Scn is
procedure Check_End_Of_Line is
Len : constant Int := Int (Scan_Ptr) - Int (Current_Line_Start);
-
begin
- if Len > Hostparm.Max_Line_Length then
- Error_Long_Line;
-
- elsif Style_Check then
+ if Style_Check then
Style.Check_Line_Terminator (Len);
+ elsif Len > Opt.Max_Line_Length then
+ Error_Long_Line;
end if;
end Check_End_Of_Line;
@@ -115,6 +112,7 @@ package body Scn is
function Determine_License return License_Type is
GPL_Found : Boolean := False;
+ Result : License_Type;
function Contains (S : String) return Boolean;
-- See if current comment contains successive non-blank characters
@@ -191,14 +189,17 @@ package body Scn is
or else Source (Scan_Ptr + 1) /= '-'
then
if GPL_Found then
- return GPL;
+ Result := GPL;
+ exit;
else
- return Unknown;
+ Result := Unknown;
+ exit;
end if;
elsif Contains ("Asaspecialexception") then
if GPL_Found then
- return Modified_GPL;
+ Result := Modified_GPL;
+ exit;
end if;
elsif Contains ("GNUGeneralPublicLicense") then
@@ -211,7 +212,8 @@ package body Scn is
Contains
("ThisspecificationisderivedfromtheAdaReferenceManual")
then
- return Unrestricted;
+ Result := Unrestricted;
+ exit;
end if;
Skip_EOL;
@@ -240,6 +242,8 @@ package body Scn is
end;
end if;
end loop;
+
+ return Result;
end Determine_License;
----------------------------
@@ -259,7 +263,7 @@ package body Scn is
begin
Error_Msg
("this line is too long",
- Current_Line_Start + Hostparm.Max_Line_Length);
+ Current_Line_Start + Source_Ptr (Opt.Max_Line_Length));
end Error_Long_Line;
------------------------
diff --git a/gcc/ada/scng.adb b/gcc/ada/scng.adb
index 93e340f54ac..92b3c74810d 100644
--- a/gcc/ada/scng.adb
+++ b/gcc/ada/scng.adb
@@ -26,7 +26,6 @@
with Csets; use Csets;
with Err_Vars; use Err_Vars;
-with Hostparm; use Hostparm;
with Namet; use Namet;
with Opt; use Opt;
with Scans; use Scans;
@@ -302,7 +301,14 @@ package body Scng is
if Style_Check and Style_Check_Max_Line_Length then
Style.Check_Line_Terminator (Len);
- elsif Len > Hostparm.Max_Line_Length then
+ -- If style checking is inactive, check maximum line length against
+ -- standard value. Note that we take this from Opt.Max_Line_Length
+ -- rather than Hostparm.Max_Line_Length because we do not want to
+ -- impose any limit during scanning of configuration pragma files,
+ -- and Opt.Max_Line_Length (normally set to Hostparm.Max_Line_Length)
+ -- is reset to Column_Number'Max during scanning of such files.
+
+ elsif Len > Opt.Max_Line_Length then
Error_Long_Line;
end if;
end Check_End_Of_Line;
@@ -359,7 +365,7 @@ package body Scng is
begin
Error_Msg
("this line is too long",
- Current_Line_Start + Hostparm.Max_Line_Length);
+ Current_Line_Start + Source_Ptr (Opt.Max_Line_Length));
end Error_Long_Line;
-------------------------------
diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb
index 4d8a67d9a17..e5646e7f338 100644
--- a/gcc/ada/sem_aggr.adb
+++ b/gcc/ada/sem_aggr.adb
@@ -212,7 +212,7 @@ package body Sem_Aggr is
-- This procedure performs the semantic checks for an array aggregate.
-- True is returned if the aggregate resolution succeeds.
-- The procedure works by recursively checking each nested aggregate.
- -- Specifically, after checking a sub-aggreate nested at the i-th level
+ -- Specifically, after checking a sub-aggregate nested at the i-th level
-- we recursively check all the subaggregates at the i+1-st level (if any).
-- Note that for aggregates analysis and resolution go hand in hand.
-- Aggregate analysis has been delayed up to here and it is done while
@@ -960,7 +960,7 @@ package body Sem_Aggr is
Aggr_Typ : constant Entity_Id := Etype (Typ);
-- This is the unconstrained array type, which is the type
- -- against which the aggregate is to be resoved. Typ itself
+ -- against which the aggregate is to be resolved. Typ itself
-- is the array type of the context which may not be the same
-- subtype as the subtype for the final aggregate.
@@ -977,7 +977,7 @@ package body Sem_Aggr is
-- formal parameter. Consequently we also need to test for
-- N_Procedure_Call_Statement or N_Function_Call.
- Set_Etype (N, Aggr_Typ); -- may be overridden later on.
+ Set_Etype (N, Aggr_Typ); -- may be overridden later on
-- Ada 0Y (AI-231): Propagate the null_exclusion attribute to the
-- components of the array aggregate
@@ -1399,6 +1399,12 @@ package body Sem_Aggr is
end if;
end if;
+ -- Ada 0Y (AI-231): Propagate the type to the nested aggregate.
+ -- Required to check the null-exclusion attribute (if present).
+ -- This value may be overridden later on.
+
+ Set_Etype (Expr, Etype (N));
+
Resolution_OK := Resolve_Array_Aggregate
(Expr, Nxt_Ind, Nxt_Ind_Constr, Component_Typ, Others_Allowed);
diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
index 370bc1df999..afe954e71ac 100644
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -4820,19 +4820,9 @@ package body Sem_Attr is
--------------
when Attribute_Definite =>
- declare
- Result : Node_Id;
-
- begin
- if Is_Indefinite_Subtype (P_Entity) then
- Result := New_Occurrence_Of (Standard_False, Loc);
- else
- Result := New_Occurrence_Of (Standard_True, Loc);
- end if;
-
- Rewrite (N, Result);
- Analyze_And_Resolve (N, Standard_Boolean);
- end;
+ Rewrite (N, New_Occurrence_Of (
+ Boolean_Literals (not Is_Indefinite_Subtype (P_Entity)), Loc));
+ Analyze_And_Resolve (N, Standard_Boolean);
------------
-- Denorm --
@@ -4961,19 +4951,9 @@ package body Sem_Attr is
-----------------------
when Attribute_Has_Discriminants =>
- declare
- Result : Node_Id;
-
- begin
- if Has_Discriminants (P_Entity) then
- Result := New_Occurrence_Of (Standard_True, Loc);
- else
- Result := New_Occurrence_Of (Standard_False, Loc);
- end if;
-
- Rewrite (N, Result);
- Analyze_And_Resolve (N, Standard_Boolean);
- end;
+ Rewrite (N, New_Occurrence_Of (
+ Boolean_Literals (Has_Discriminants (P_Entity)), Loc));
+ Analyze_And_Resolve (N, Standard_Boolean);
--------------
-- Identity --
@@ -5896,7 +5876,7 @@ package body Sem_Attr is
Id : RE_Id;
begin
- if Is_RTE (P_Root_Type, RE_Address) then
+ if Is_Descendent_Of_Address (Typ) then
Id := RE_Type_Class_Address;
elsif Is_Enumeration_Type (Typ) then
@@ -5962,13 +5942,10 @@ package body Sem_Attr is
Typ : constant Entity_Id := Underlying_Type (P_Type);
begin
- if Is_Array_Type (P_Type)
- and then not Is_Constrained (Typ)
- then
- Rewrite (N, New_Occurrence_Of (Standard_True, Loc));
- else
- Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
- end if;
+ Rewrite (N, New_Occurrence_Of (
+ Boolean_Literals (
+ Is_Array_Type (P_Type)
+ and then not Is_Constrained (Typ)), Loc));
-- Analyze and resolve as boolean, note that this attribute is
-- a static attribute in GNAT.
@@ -6507,7 +6484,12 @@ package body Sem_Attr is
-- also be accessibility checks on those, this is where the
-- checks can eventually be centralized ???
- if Ekind (Btyp) = E_Access_Subprogram_Type then
+ if Ekind (Btyp) = E_Access_Subprogram_Type
+ or else
+ Ekind (Btyp) = E_Anonymous_Access_Subprogram_Type
+ or else
+ Ekind (Btyp) = E_Anonymous_Access_Protected_Subprogram_Type
+ then
if Convention (Btyp) /= Convention (Entity (P)) then
Error_Msg_N
("subprogram has invalid convention for context", P);
@@ -6533,8 +6515,12 @@ package body Sem_Attr is
-- warning is needed.
elsif Attr_Id = Attribute_Access
- and then Subprogram_Access_Level (Entity (P))
- > Type_Access_Level (Btyp)
+ and then Subprogram_Access_Level (Entity (P)) >
+ Type_Access_Level (Btyp)
+ and then Ekind (Btyp) /=
+ E_Anonymous_Access_Subprogram_Type
+ and then Ekind (Btyp) /=
+ E_Anonymous_Access_Protected_Subprogram_Type
then
if not In_Instance_Body then
Error_Msg_N
@@ -6617,9 +6603,12 @@ package body Sem_Attr is
-- The rule does not apply to 'Unrestricted_Access.
if not (Ekind (Btyp) = E_Access_Subprogram_Type
+ or else Ekind (Btyp) = E_Anonymous_Access_Subprogram_Type
or else (Is_Record_Type (Btyp) and then
Present (Corresponding_Remote_Type (Btyp)))
or else Ekind (Btyp) = E_Access_Protected_Subprogram_Type
+ or else Ekind (Btyp)
+ = E_Anonymous_Access_Protected_Subprogram_Type
or else Is_Access_Constant (Btyp)
or else Is_Variable (P)
or else Attr_Id = Attribute_Unrestricted_Access)
@@ -6633,8 +6622,37 @@ package body Sem_Attr is
or else
Attr_Id = Attribute_Unchecked_Access)
and then (Ekind (Btyp) = E_General_Access_Type
- or else Ekind (Btyp) = E_Anonymous_Access_Type)
+ or else Ekind (Btyp) = E_Anonymous_Access_Type)
then
+ -- Ada 0Y (AI-230): Check the accessibility of anonymous access
+ -- types in record and array components. For a component defini
+ -- tion the level is the same of the enclosing composite type.
+
+ if Extensions_Allowed
+ and then Ekind (Btyp) = E_Anonymous_Access_Type
+ and then (Is_Array_Type (Scope (Btyp))
+ or else Ekind (Scope (Btyp)) = E_Record_Type)
+ and then Object_Access_Level (P)
+ > Type_Access_Level (Btyp)
+ then
+ -- In an instance, this is a runtime check, but one we
+ -- know will fail, so generate an appropriate warning.
+
+ if In_Instance_Body then
+ Error_Msg_N
+ ("?non-local pointer cannot point to local object", P);
+ Error_Msg_N
+ ("?Program_Error will be raised at run time", P);
+ Rewrite (N,
+ Make_Raise_Program_Error (Loc,
+ Reason => PE_Accessibility_Check_Failed));
+ Set_Etype (N, Typ);
+ else
+ Error_Msg_N
+ ("non-local pointer cannot point to local object", P);
+ end if;
+ end if;
+
if Is_Dependent_Component_Of_Mutable_Object (P) then
Error_Msg_N
("illegal attribute for discriminant-dependent component",
@@ -6791,13 +6809,17 @@ package body Sem_Attr is
end if;
end if;
- if Ekind (Btyp) = E_Access_Protected_Subprogram_Type
+ if (Ekind (Btyp) = E_Access_Protected_Subprogram_Type
+ or else
+ Ekind (Btyp) = E_Anonymous_Access_Protected_Subprogram_Type)
and then Is_Entity_Name (P)
and then not Is_Protected_Type (Scope (Entity (P)))
then
Error_Msg_N ("context requires a protected subprogram", P);
- elsif Ekind (Btyp) = E_Access_Subprogram_Type
+ elsif (Ekind (Btyp) = E_Access_Subprogram_Type
+ or else
+ Ekind (Btyp) = E_Anonymous_Access_Subprogram_Type)
and then Ekind (Etype (N)) = E_Access_Protected_Subprogram_Type
then
Error_Msg_N ("context requires a non-protected subprogram", P);
diff --git a/gcc/ada/sem_ch10.adb b/gcc/ada/sem_ch10.adb
index c821c7c2fc0..4283ae0beb2 100644
--- a/gcc/ada/sem_ch10.adb
+++ b/gcc/ada/sem_ch10.adb
@@ -511,7 +511,7 @@ package body Sem_Ch10 is
end;
end if;
- -- Generate distribution stub files if requested and no error
+ -- Generate distribution stubs if requested and no error
if N = Main_Cunit
and then (Distribution_Stub_Mode = Generate_Receiver_Stub_Body
@@ -546,9 +546,6 @@ package body Sem_Ch10 is
Add_Stub_Constructs (N);
end if;
- -- Reanalyze the unit with the new constructs
-
- Analyze (Unit_Node);
end if;
if Nkind (Unit_Node) = N_Package_Declaration
@@ -1815,6 +1812,14 @@ package body Sem_Ch10 is
null;
end if;
+
+ -- Ada 0Y (AI-262): Remove from visibility the entity corresponding to
+ -- private_with units; they will be made visible later (just before the
+ -- private part is analyzed)
+
+ if Private_Present (N) then
+ Set_Is_Immediately_Visible (E_Name, False);
+ end if;
end Analyze_With_Clause;
------------------------------
@@ -2229,8 +2234,12 @@ package body Sem_Ch10 is
Item := First (Context_Items (N));
while Present (Item) loop
+ -- Ada 0Y (AI-262): Allow private_with of a private child package in
+ -- public siblings
+
if Nkind (Item) = N_With_Clause
and then not Implicit_With (Item)
+ and then not Private_Present (Item)
and then Is_Private_Descendant (Entity (Name (Item)))
then
Priv_Child := Entity (Name (Item));
@@ -2425,7 +2434,7 @@ package body Sem_Ch10 is
Mark_Rewrite_Insertion (Withn);
end if;
- elsif Nkind (Nam) = N_Selected_Component then
+ else pragma Assert (Nkind (Nam) = N_Selected_Component);
Withn :=
Make_With_Clause
(Loc,
@@ -2456,10 +2465,6 @@ package body Sem_Ch10 is
Expand_Limited_With_Clause (Prefix (Nam), N);
end if;
-
- else
- null;
- pragma Assert (False);
end if;
New_Nodes_OK := New_Nodes_OK - 1;
@@ -3157,6 +3162,12 @@ package body Sem_Ch10 is
Clause : Node_Id;
begin
+ if Debug_Flag_I then
+ Write_Str ("install private with clauses of ");
+ Write_Name (Chars (P));
+ Write_Eol;
+ end if;
+
if Nkind (Parent (Decl)) = N_Compilation_Unit then
Clause := First (Context_Items (Parent (Decl)));
while Present (Clause) loop
@@ -3179,36 +3190,6 @@ package body Sem_Ch10 is
Item : Node_Id;
Id : Entity_Id;
Prev : Entity_Id;
-
- function Is_Ancestor (E : Entity_Id) return Boolean;
- -- Determine whether the scope of a child unit is an ancestor of
- -- the current unit.
- -- Shouldn't this be somewhere more general ???
-
- -----------------
- -- Is_Ancestor --
- -----------------
-
- function Is_Ancestor (E : Entity_Id) return Boolean is
- Par : Entity_Id;
-
- begin
- Par := U_Name;
- while Present (Par)
- and then Par /= Standard_Standard
- loop
- if Par = E then
- return True;
- end if;
-
- Par := Scope (Par);
- end loop;
-
- return False;
- end Is_Ancestor;
-
- -- Start of processing for Install_Siblings
-
begin
-- Iterate over explicit with clauses, and check whether the
-- scope of each entity is an ancestor of the current unit.
@@ -3222,14 +3203,22 @@ package body Sem_Ch10 is
Id := Entity (Name (Item));
if Is_Child_Unit (Id)
- and then Is_Ancestor (Scope (Id))
+ and then Is_Ancestor_Package (Scope (Id), U_Name)
then
Set_Is_Immediately_Visible (Id);
- Prev := Current_Entity (Id);
+
+ -- Ada 0Y (AI-262): Make visible the private entities of
+ -- private-withed siblings
+
+ if Private_Present (Item) then
+ Install_Private_Declarations (Id);
+ end if;
-- Check for the presence of another unit in the context,
-- that may be inadvertently hidden by the child.
+ Prev := Current_Entity (Id);
+
if Present (Prev)
and then Is_Immediately_Visible (Prev)
and then not Is_Child_Unit (Prev)
@@ -3260,7 +3249,7 @@ package body Sem_Ch10 is
-- the child immediately visible.
elsif Is_Child_Unit (Scope (Id))
- and then Is_Ancestor (Scope (Scope (Id)))
+ and then Is_Ancestor_Package (Scope (Scope (Id)), U_Name)
then
Set_Is_Immediately_Visible (Scope (Id));
end if;
@@ -3330,8 +3319,7 @@ package body Sem_Ch10 is
return;
when others =>
- pragma Assert (False);
- null;
+ raise Program_Error;
end case;
P := Defining_Unit_Name (Specification (P_Unit));
@@ -3475,9 +3463,25 @@ package body Sem_Ch10 is
P : constant Entity_Id := Scope (Uname);
begin
+ -- Ada 0Y (AI-262): Do not install the private withed unit if we are
+ -- compiling a package declaration and the Private_With_OK flag was not
+ -- set by the caller. These declarations will be installed later (before
+ -- analyzing the private part of the package).
+
+ if Private_Present (With_Clause)
+ and then Nkind (Cunit (Current_Sem_Unit)) = N_Package_Declaration
+ and then not (Private_With_OK)
+ then
+ return;
+ end if;
if Debug_Flag_I then
- Write_Str ("install withed unit ");
+ if Private_Present (With_Clause) then
+ Write_Str ("install private withed unit ");
+ else
+ Write_Str ("install withed unit ");
+ end if;
+
Write_Name (Chars (Uname));
Write_Eol;
end if;
@@ -3495,17 +3499,13 @@ package body Sem_Ch10 is
end if;
if P /= Standard_Standard then
- if Private_Present (With_Clause)
- and then not (Private_With_OK)
- then
- return;
-- If the unit is not analyzed after analysis of the with clause,
-- and it is an instantiation, then it awaits a body and is the main
-- unit. Its appearance in the context of some other unit indicates
-- a circular dependency (DEC suite perversity).
- elsif not Analyzed (Uname)
+ if not Analyzed (Uname)
and then Nkind (Parent (Uname)) = N_Package_Instantiation
then
Error_Msg_N
@@ -3523,7 +3523,6 @@ package body Sem_Ch10 is
Set_Is_Visible_Child_Unit
(Related_Instance
(Defining_Entity (Unit (Library_Unit (With_Clause)))));
- null;
end if;
-- The parent unit may have been installed already, and
@@ -3912,8 +3911,7 @@ package body Sem_Ch10 is
return;
when others =>
- pragma Assert (False);
- null;
+ raise Program_Error;
end case;
-- Check if the chain is already built
diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
index 69930b81a04..7684845103a 100644
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -3636,6 +3636,16 @@ package body Sem_Ch12 is
-- Common error routine for mismatch between the parameters of
-- the actual instance and those of the formal package.
+ function Same_Instantiated_Entity (E1, E2 : Entity_Id) return Boolean;
+ -- The formal may come from a nested formal package, and the actual
+ -- may have been constant-folded. To determine whether the two denote
+ -- the same entity we may have to traverse several definitions to
+ -- recover the ultimate entity that they refer to.
+
+ --------------------
+ -- Check_Mismatch --
+ --------------------
+
procedure Check_Mismatch (B : Boolean) is
begin
if B then
@@ -3645,6 +3655,42 @@ package body Sem_Ch12 is
end if;
end Check_Mismatch;
+ ------------------------------
+ -- Same_Instantiated_Entity --
+ ------------------------------
+
+ function Same_Instantiated_Entity (E1, E2 : Entity_Id) return Boolean is
+ Ent : Entity_Id;
+
+ begin
+ Ent := E2;
+ while Present (Ent) loop
+ if E1 = Ent then
+ return True;
+
+ elsif Ekind (Ent) /= E_Constant then
+ return False;
+
+ elsif Is_Entity_Name (Constant_Value (Ent)) then
+ if Entity (Constant_Value (Ent)) = E1 then
+ return True;
+ else
+ Ent := Entity (Constant_Value (Ent));
+ end if;
+
+ -- The actual may be a constant that has been folded. Recover
+ -- original name.
+
+ elsif Is_Entity_Name (Original_Node (Constant_Value (Ent))) then
+ Ent := Entity (Original_Node (Constant_Value (Ent)));
+ else
+ return False;
+ end if;
+ end loop;
+
+ return False;
+ end Same_Instantiated_Entity;
+
-- Start of processing for Check_Formal_Package_Instance
begin
@@ -3723,10 +3769,8 @@ package body Sem_Ch12 is
if Entity (Expr1) = Entity (Expr2) then
null;
- elsif Ekind (Entity (Expr2)) = E_Constant
- and then Is_Entity_Name (Constant_Value (Entity (Expr2)))
- and then
- Entity (Constant_Value (Entity (Expr2))) = Entity (Expr1)
+ elsif
+ Same_Instantiated_Entity (Entity (Expr1), Entity (Expr2))
then
null;
else
@@ -3736,6 +3780,14 @@ package body Sem_Ch12 is
Check_Mismatch (True);
end if;
+ elsif Is_Entity_Name (Original_Node (Expr1))
+ and then Is_Entity_Name (Expr2)
+ and then
+ Same_Instantiated_Entity
+ (Entity (Original_Node (Expr1)), Entity (Expr2))
+ then
+ null;
+
elsif Nkind (Expr1) = N_Null then
Check_Mismatch (Nkind (Expr1) /= N_Null);
@@ -6160,8 +6212,7 @@ package body Sem_Ch12 is
end loop;
when others =>
- null;
- pragma Assert (False);
+ raise Program_Error;
end case;
end Find_Matching_Actual;
@@ -8650,6 +8701,10 @@ package body Sem_Ch12 is
Set_In_Private_Part (P);
end if;
+ -- This looks incomplete: what about compilation units that
+ -- were made visible by Install_Parent but should not remain
+ -- visible??? Standard is on the scope stack.
+
elsif not In_Open_Scopes (Scope (P)) then
Set_Is_Immediately_Visible (P, False);
end if;
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index e89041a0eb7..69e324b0a7f 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -45,6 +45,7 @@ with Snames; use Snames;
with Stand; use Stand;
with Sinfo; use Sinfo;
with Table;
+with Targparm; use Targparm;
with Ttypes; use Ttypes;
with Tbuild; use Tbuild;
with Urealp; use Urealp;
@@ -1398,6 +1399,10 @@ package body Sem_Ch13 is
-- Return true if the entity is a procedure with an
-- appropriate profile for the write attribute.
+ ----------------------
+ -- Has_Good_Profile --
+ ----------------------
+
function Has_Good_Profile (Subp : Entity_Id) return Boolean is
F : Entity_Id;
Ok : Boolean := False;
@@ -2699,8 +2704,19 @@ package body Sem_Ch13 is
end if;
end if;
- when N_Integer_Literal |
- N_Real_Literal |
+ when N_Integer_Literal =>
+
+ -- If this is a rewritten unchecked conversion, in a system
+ -- where Address is an integer type, always use the base type
+ -- for a literal value. This is user-friendly and prevents
+ -- order-of-elaboration issues with instances of unchecked
+ -- conversion.
+
+ if Nkind (Original_Node (Nod)) = N_Function_Call then
+ Set_Etype (Nod, Base_Type (Etype (Nod)));
+ end if;
+
+ when N_Real_Literal |
N_String_Literal |
N_Character_Literal =>
return;
@@ -3068,10 +3084,19 @@ package body Sem_Ch13 is
then
return 0;
- -- Access types
+ -- Access types. Normally an access type cannot have a size smaller
+ -- than the size of System.Address. The exception is on VMS, where
+ -- we have short and long addresses, and it is possible for an access
+ -- type to have a short address size (and thus be less than the size
+ -- of System.Address itself). We simply skip the check for VMS, and
+ -- leave the back end to do the check.
elsif Is_Access_Type (T) then
- return System_Address_Size;
+ if OpenVMS_On_Target then
+ return 0;
+ else
+ return System_Address_Size;
+ end if;
-- Floating-point types
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index cf0ba5e6678..88480d8332b 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -677,6 +677,25 @@ package body Sem_Ch3 is
Error_Msg_N ("task entries cannot have access parameters", N);
end if;
+ -- Ada 0Y (AI-254): In case of anonymous access to subprograms
+ -- call the corresponding semantic routine
+
+ if Present (Access_To_Subprogram_Definition (N)) then
+ Access_Subprogram_Declaration
+ (T_Name => Anon_Type,
+ T_Def => Access_To_Subprogram_Definition (N));
+
+ if Ekind (Anon_Type) = E_Access_Protected_Subprogram_Type then
+ Set_Ekind
+ (Anon_Type, E_Anonymous_Access_Protected_Subprogram_Type);
+ else
+ Set_Ekind
+ (Anon_Type, E_Anonymous_Access_Subprogram_Type);
+ end if;
+
+ return Anon_Type;
+ end if;
+
Find_Type (Subtype_Mark (N));
Desig_Type := Entity (Subtype_Mark (N));
@@ -715,9 +734,12 @@ package body Sem_Ch3 is
-- discriminant, in a private or a full type declaration. In
-- the case of a subprogram, If the designated type is incomplete,
-- the operation will be a primitive operation of the full type, to
- -- be updated subsequently.
+ -- be updated subsequently. If the type is imported through a limited
+ -- with clause, it is not a primitive operation of the type (which
+ -- is declared elsewhere in some other scope).
if Ekind (Desig_Type) = E_Incomplete_Type
+ and then not From_With_Type (Desig_Type)
and then Is_Overloadable (Current_Scope)
then
Append_Elmt (Current_Scope, Private_Dependents (Desig_Type));
@@ -832,9 +854,6 @@ package body Sem_Ch3 is
Desig : Entity_Id;
-- Designated type
- N_Desig : Entity_Id;
- -- Non-limited view, when needed
-
begin
-- Check for permissible use of incomplete type
@@ -884,26 +903,28 @@ package body Sem_Ch3 is
-- available, use it as the designated type of the access type, so that
-- the back-end gets a usable entity.
- if From_With_Type (Desig) then
- Set_From_With_Type (T);
+ declare
+ N_Desig : Entity_Id;
+
+ begin
+ if From_With_Type (Desig) then
+ Set_From_With_Type (T);
- if Ekind (Desig) = E_Incomplete_Type then
- N_Desig := Non_Limited_View (Desig);
+ if Ekind (Desig) = E_Incomplete_Type then
+ N_Desig := Non_Limited_View (Desig);
- elsif Ekind (Desig) = E_Class_Wide_Type then
- if From_With_Type (Etype (Desig)) then
- N_Desig := Non_Limited_View (Etype (Desig));
- else
- N_Desig := Etype (Desig);
+ else pragma Assert (Ekind (Desig) = E_Class_Wide_Type);
+ if From_With_Type (Etype (Desig)) then
+ N_Desig := Non_Limited_View (Etype (Desig));
+ else
+ N_Desig := Etype (Desig);
+ end if;
end if;
- else
- null;
- pragma Assert (False);
- end if;
- pragma Assert (Present (N_Desig));
- Set_Directly_Designated_Type (T, N_Desig);
- end if;
+ pragma Assert (Present (N_Desig));
+ Set_Directly_Designated_Type (T, N_Desig);
+ end if;
+ end;
-- Note that Has_Task is always false, since the access type itself
-- is not a task type. See Einfo for more description on this point.
@@ -938,14 +959,30 @@ package body Sem_Ch3 is
-- Ada 0Y (AI-230): Access Definition case
- elsif Present (Access_Definition (Component_Definition (N))) then
+ else
+ pragma Assert (Present
+ (Access_Definition (Component_Definition (N))));
+
T := Access_Definition
(Related_Nod => N,
N => Access_Definition (Component_Definition (N)));
- else
- pragma Assert (False);
- null;
+ -- Ada 0Y (AI-230): In case of components that are anonymous access
+ -- types the level of accessibility depends on the enclosing type
+ -- declaration
+
+ Set_Scope (T, Current_Scope); -- Ada 0Y (AI-230)
+
+ -- Ada 0Y (AI-254)
+
+ if Present (Access_To_Subprogram_Definition
+ (Access_Definition (Component_Definition (N))))
+ and then Protected_Present (Access_To_Subprogram_Definition
+ (Access_Definition
+ (Component_Definition (N))))
+ then
+ T := Replace_Anonymous_Access_To_Protected_Subprogram (N, T);
+ end if;
end if;
-- If the subtype is a constrained subtype of the enclosing record,
@@ -1645,6 +1682,13 @@ package body Sem_Ch3 is
if Present (E) and then E /= Error then
Analyze (E);
+ -- In case of errors detected in the analysis of the expression,
+ -- decorate it with the expected type to avoid cascade errors
+
+ if not Present (Etype (E)) then
+ Set_Etype (E, T);
+ end if;
+
-- If an initialization expression is present, then we set the
-- Is_True_Constant flag. It will be reset if this is a variable
-- and it is indeed modified.
@@ -2927,14 +2971,30 @@ package body Sem_Ch3 is
-- Ada 0Y (AI-230): Access Definition case
- elsif Present (Access_Definition (Component_Def)) then
+ else pragma Assert (Present (Access_Definition (Component_Def)));
Element_Type := Access_Definition
(Related_Nod => Related_Id,
N => Access_Definition (Component_Def));
- else
- pragma Assert (False);
- null;
+ -- Ada 0Y (AI-230): In case of components that are anonymous access
+ -- types the level of accessibility depends on the enclosing type
+ -- declaration
+
+ Set_Scope (Element_Type, T); -- Ada 0Y (AI-230)
+
+ -- Ada 0Y (AI-254)
+
+ declare
+ CD : constant Node_Id :=
+ Access_To_Subprogram_Definition
+ (Access_Definition (Component_Def));
+ begin
+ if Present (CD) and then Protected_Present (CD) then
+ Element_Type :=
+ Replace_Anonymous_Access_To_Protected_Subprogram
+ (Def, Element_Type);
+ end if;
+ end;
end if;
-- Constrained array case
@@ -3074,6 +3134,100 @@ package body Sem_Ch3 is
end Array_Type_Declaration;
+ ------------------------------------------------------
+ -- Replace_Anonymous_Access_To_Protected_Subprogram --
+ ------------------------------------------------------
+
+ function Replace_Anonymous_Access_To_Protected_Subprogram
+ (N : Node_Id;
+ Prev_E : Entity_Id) return Entity_Id
+ is
+ Loc : constant Source_Ptr := Sloc (N);
+
+ Curr_Scope : constant Scope_Stack_Entry :=
+ Scope_Stack.Table (Scope_Stack.Last);
+
+ Anon : constant Entity_Id :=
+ Make_Defining_Identifier (Loc,
+ Chars => New_Internal_Name ('S'));
+
+ Acc : Node_Id;
+ Comp : Node_Id;
+ Decl : Node_Id;
+ P : Node_Id := Parent (N);
+
+ begin
+ Set_Is_Internal (Anon);
+
+ case Nkind (N) is
+ when N_Component_Declaration |
+ N_Unconstrained_Array_Definition |
+ N_Constrained_Array_Definition =>
+ Comp := Component_Definition (N);
+ Acc := Access_Definition (Component_Definition (N));
+
+ when N_Discriminant_Specification =>
+ Comp := Discriminant_Type (N);
+ Acc := Discriminant_Type (N);
+
+ when N_Parameter_Specification =>
+ Comp := Parameter_Type (N);
+ Acc := Parameter_Type (N);
+
+ when others =>
+ raise Program_Error;
+ end case;
+
+ Decl := Make_Full_Type_Declaration (Loc,
+ Defining_Identifier => Anon,
+ Type_Definition =>
+ Copy_Separate_Tree (Access_To_Subprogram_Definition (Acc)));
+
+ Mark_Rewrite_Insertion (Decl);
+
+ -- Insert the new declaration in the nearest enclosing scope
+
+ while Present (P) and then not Has_Declarations (P) loop
+ P := Parent (P);
+ end loop;
+
+ pragma Assert (Present (P));
+
+ if Nkind (P) = N_Package_Specification then
+ Prepend (Decl, Visible_Declarations (P));
+ else
+ Prepend (Decl, Declarations (P));
+ end if;
+
+ -- Replace the anonymous type with an occurrence of the new declaration.
+ -- In all cases the rewriten node does not have the null-exclusion
+ -- attribute because (if present) it was already inherited by the
+ -- anonymous entity (Anon). Thus, in case of components we do not
+ -- inherit this attribute.
+
+ if Nkind (N) = N_Parameter_Specification then
+ Rewrite (Comp, New_Occurrence_Of (Anon, Loc));
+ Set_Etype (Defining_Identifier (N), Anon);
+ Set_Null_Exclusion_Present (N, False);
+ else
+ Rewrite (Comp,
+ Make_Component_Definition (Loc,
+ Subtype_Indication => New_Occurrence_Of (Anon, Loc)));
+ end if;
+
+ Mark_Rewrite_Insertion (Comp);
+
+ -- Temporarily remove the current scope from the stack to add the new
+ -- declarations to the enclosing scope
+
+ Scope_Stack.Decrement_Last;
+ Analyze (Decl);
+ Scope_Stack.Append (Curr_Scope);
+
+ Set_Original_Access_Type (Anon, Prev_E);
+ return Anon;
+ end Replace_Anonymous_Access_To_Protected_Subprogram;
+
-------------------------------
-- Build_Derived_Access_Type --
-------------------------------
@@ -3425,6 +3579,7 @@ package body Sem_Ch3 is
else
Set_First_Entity (Derived_Type, First_Entity (Parent_Type));
if Has_Discriminants (Parent_Type) then
+ Set_Is_Constrained (Derived_Type, Is_Constrained (Parent_Type));
Set_Discriminant_Constraint (
Derived_Type, Discriminant_Constraint (Parent_Type));
end if;
@@ -3917,10 +4072,12 @@ package body Sem_Ch3 is
-- Copy declaration for subsequent analysis, to
-- provide a completion for what is a private
- -- declaration.
+ -- declaration. Indicate that the full type is
+ -- internally generated.
Full_Decl := New_Copy_Tree (N);
Full_Der := New_Copy (Derived_Type);
+ Set_Comes_From_Source (Full_Decl, False);
Insert_After (N, Full_Decl);
@@ -7916,10 +8073,9 @@ package body Sem_Ch3 is
Suffix : Character;
Suffix_Index : Nat)
is
- Def_Id : Entity_Id;
- R : Node_Id := Empty;
- Checks_Off : Boolean := False;
- T : constant Entity_Id := Etype (Index);
+ Def_Id : Entity_Id;
+ R : Node_Id := Empty;
+ T : constant Entity_Id := Etype (Index);
begin
if Nkind (S) = N_Range
@@ -7933,21 +8089,7 @@ package body Sem_Ch3 is
Set_Etype (S, T);
R := S;
- -- ??? Why on earth do we turn checks of in this very specific case ?
-
- -- From the revision history: (Constrain_Index): Call
- -- Process_Range_Expr_In_Decl with range checking off for range
- -- bounds that are attributes. This avoids some horrible
- -- constraint error checks.
-
- if Nkind (R) = N_Range
- and then Nkind (Low_Bound (R)) = N_Attribute_Reference
- and then Nkind (High_Bound (R)) = N_Attribute_Reference
- then
- Checks_Off := True;
- end if;
-
- Process_Range_Expr_In_Decl (R, T, Empty_List, Checks_Off);
+ Process_Range_Expr_In_Decl (R, T, Empty_List);
if not Error_Posted (S)
and then
@@ -9274,7 +9416,7 @@ package body Sem_Ch3 is
elsif Is_Unchecked_Union (Parent_Type) then
Error_Msg_N ("cannot derive from Unchecked_Union type", N);
- -- Ada 0Y (AI-231)
+ -- Ada 0Y (AI-231): Static check
elsif Is_Access_Type (Parent_Type)
and then Null_Exclusion_Present (Type_Definition (N))
@@ -9818,7 +9960,7 @@ package body Sem_Ch3 is
Defining_Identifier => T,
Subtype_Indication => Relocate_Node (Obj_Def)));
- -- This subtype may need freezing and it will not be done
+ -- This subtype may need freezing, and this will not be done
-- automatically if the object declaration is not in a
-- declarative part. Since this is an object declaration, the
-- type cannot always be frozen here. Deferred constants do not
@@ -9955,7 +10097,7 @@ package body Sem_Ch3 is
elsif Can_Derive_From (Standard_Long_Long_Float) then
Base_Typ := Standard_Long_Long_Float;
- -- If we can't derive from any existing type, use long long float
+ -- If we can't derive from any existing type, use long_long_float
-- and give appropriate message explaining the problem.
else
@@ -11467,6 +11609,18 @@ package body Sem_Ch3 is
if Nkind (Discriminant_Type (Discr)) = N_Access_Definition then
Discr_Type := Access_Definition (N, Discriminant_Type (Discr));
+ -- Ada 0Y (AI-254)
+
+ if Present (Access_To_Subprogram_Definition
+ (Discriminant_Type (Discr)))
+ and then Protected_Present (Access_To_Subprogram_Definition
+ (Discriminant_Type (Discr)))
+ then
+ Discr_Type :=
+ Replace_Anonymous_Access_To_Protected_Subprogram
+ (Discr, Discr_Type);
+ end if;
+
else
Find_Type (Discriminant_Type (Discr));
Discr_Type := Etype (Discriminant_Type (Discr));
@@ -11514,7 +11668,13 @@ package body Sem_Ch3 is
("discriminant defaults not allowed for formal type",
Expression (Discr));
- elsif Is_Tagged_Type (Current_Scope) then
+ -- Tagged types cannot have defaulted discriminants, but a
+ -- non-tagged private type with defaulted discriminants
+ -- can have a tagged completion.
+
+ elsif Is_Tagged_Type (Current_Scope)
+ and then Comes_From_Source (N)
+ then
Error_Msg_N
("discriminants of tagged type cannot have defaults",
Expression (Discr));
@@ -12310,7 +12470,7 @@ package body Sem_Ch3 is
Find_Type (S);
Check_Incomplete (S);
- -- Ada 0Y (AI-231)
+ -- Ada 0Y (AI-231): Static check
if Extensions_Allowed
and then Present (Parent (S))
diff --git a/gcc/ada/sem_ch3.ads b/gcc/ada/sem_ch3.ads
index 3cae7d3d739..08b2c202f56 100644
--- a/gcc/ada/sem_ch3.ads
+++ b/gcc/ada/sem_ch3.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -206,6 +206,16 @@ package Sem_Ch3 is
-- N_Incomplete_Type_Decl node N. If the declaration is a completion,
-- Prev is entity on the partial view, on which references are posted.
+ function Replace_Anonymous_Access_To_Protected_Subprogram
+ (N : Node_Id;
+ Prev_E : Entity_Id) return Entity_Id;
+ -- Ada 0Y (AI-254): Create and decorate an internal full type declaration
+ -- in the enclosing scope corresponding to an anonymous access to protected
+ -- subprogram. In addition, replace the anonymous access by an occurrence
+ -- of this internal type. Prev_Etype is used to link the new internal
+ -- entity with the anonymous entity. Return the entity of this type
+ -- declaration.
+
procedure Set_Completion_Referenced (E : Entity_Id);
-- If E is the completion of a private or incomplete type declaration,
-- or the completion of a deferred constant declaration, mark the entity
diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb
index 2b958a839c9..8722b77692d 100644
--- a/gcc/ada/sem_ch4.adb
+++ b/gcc/ada/sem_ch4.adb
@@ -30,7 +30,9 @@ with Debug; use Debug;
with Einfo; use Einfo;
with Errout; use Errout;
with Exp_Util; use Exp_Util;
+with Fname; use Fname;
with Itypes; use Itypes;
+with Lib; use Lib;
with Lib.Xref; use Lib.Xref;
with Namet; use Namet;
with Nlists; use Nlists;
@@ -2095,8 +2097,22 @@ package body Sem_Ch4 is
then
Error_Msg_NE
(" =='> in call to &#(inherited)!", Actual, Nam);
+
+ elsif Ekind (Nam) = E_Subprogram_Type then
+ declare
+ Access_To_Subprogram_Typ :
+ constant Entity_Id :=
+ Defining_Identifier
+ (Associated_Node_For_Itype (Nam));
+ begin
+ Error_Msg_NE (
+ " =='> in call to dereference of &#!",
+ Actual, Access_To_Subprogram_Typ);
+ end;
+
else
Error_Msg_NE (" =='> in call to &#!", Actual, Nam);
+
end if;
end if;
end if;
@@ -2752,7 +2768,8 @@ package body Sem_Ch4 is
<<Next_Comp>>
Next_Entity (Comp);
exit when not In_Scope
- and then Comp = First_Private_Entity (Prefix_Type);
+ and then
+ Comp = First_Private_Entity (Base_Type (Prefix_Type));
end loop;
Set_Is_Overloaded (N, Is_Overloaded (Sel));
@@ -4330,22 +4347,68 @@ package body Sem_Ch4 is
--------------------------------
procedure Remove_Abstract_Operations (N : Node_Id) is
- I : Interp_Index;
- It : Interp;
- Abstract_Op : Entity_Id := Empty;
+ I : Interp_Index;
+ It : Interp;
+ Abstract_Op : Entity_Id := Empty;
-- AI-310: If overloaded, remove abstract non-dispatching
- -- operations.
+ -- operations. We activate this if either extensions are
+ -- enabled, or if the abstract operation in question comes
+ -- from a predefined file. This latter test allows us to
+ -- use abstract to make operations invisible to users. In
+ -- particular, if type Address is non-private and abstract
+ -- subprograms are used to hide its operators, they will be
+ -- truly hidden.
+
+ type Operand_Position is (First_Op, Second_Op);
+
+ procedure Remove_Address_Interpretations (Op : Operand_Position);
+ -- Ambiguities may arise when the operands are literal and the
+ -- address operations in s-auxdec are visible. In that case, remove
+ -- the interpretation of a literal as Address, to retain the semantics
+ -- of Address as a private type.
+
+ ------------------------------------
+ -- Remove_Address_Interpretations --
+ ------------------------------------
+
+ procedure Remove_Address_Interpretations (Op : Operand_Position) is
+ Formal : Entity_Id;
+
+ begin
+ if Is_Overloaded (N) then
+ Get_First_Interp (N, I, It);
+ while Present (It.Nam) loop
+ Formal := First_Entity (It.Nam);
+
+ if Op = Second_Op then
+ Formal := Next_Entity (Formal);
+ end if;
+
+ if Is_Descendent_Of_Address (Etype (Formal)) then
+ Remove_Interp (I);
+ end if;
+
+ Get_Next_Interp (I, It);
+ end loop;
+ end if;
+ end Remove_Address_Interpretations;
+
+ -- Start of processing for Remove_Abstract_Operations
begin
- if Extensions_Allowed
- and then Is_Overloaded (N)
- then
+ if Is_Overloaded (N) then
Get_First_Interp (N, I, It);
+
while Present (It.Nam) loop
if not Is_Type (It.Nam)
and then Is_Abstract (It.Nam)
and then not Is_Dispatching_Operation (It.Nam)
+ and then
+ (Extensions_Allowed
+ or else Is_Predefined_File_Name
+ (Unit_File_Name (Get_Source_Unit (It.Nam))))
+
then
Abstract_Op := It.Nam;
Remove_Interp (I);
@@ -4355,34 +4418,43 @@ package body Sem_Ch4 is
Get_Next_Interp (I, It);
end loop;
- -- Remove corresponding predefined operator, which is
- -- always added to the overload set, unless it is a universal
- -- operation.
-
if No (Abstract_Op) then
return;
elsif Nkind (N) in N_Op then
- if Nkind (N) in N_Unary_Op
- and then Present (Universal_Interpretation (Right_Opnd (N)))
- then
- return;
+ -- Remove interpretations that treat literals as addresses.
+ -- This is never appropriate.
- elsif Nkind (N) in N_Binary_Op
- and then Present (Universal_Interpretation (Right_Opnd (N)))
- and then Present (Universal_Interpretation (Left_Opnd (N)))
- then
- return;
+ if Nkind (N) in N_Binary_Op then
+ declare
+ U1 : constant Boolean :=
+ Present (Universal_Interpretation (Right_Opnd (N)));
+ U2 : constant Boolean :=
+ Present (Universal_Interpretation (Left_Opnd (N)));
- else
- Get_First_Interp (N, I, It);
- while Present (It.Nam) loop
- if Scope (It.Nam) = Standard_Standard then
- Remove_Interp (I);
+ begin
+ if U1 and then not U2 then
+ Remove_Address_Interpretations (Second_Op);
+
+ elsif U2 and then not U1 then
+ Remove_Address_Interpretations (First_Op);
end if;
- Get_Next_Interp (I, It);
- end loop;
+ if not (U1 and U2) then
+
+ -- Remove corresponding predefined operator, which is
+ -- always added to the overload set.
+
+ Get_First_Interp (N, I, It);
+ while Present (It.Nam) loop
+ if Scope (It.Nam) = Standard_Standard then
+ Remove_Interp (I);
+ end if;
+
+ Get_Next_Interp (I, It);
+ end loop;
+ end if;
+ end;
end if;
elsif Nkind (N) = N_Function_Call
@@ -4393,21 +4465,29 @@ package body Sem_Ch4 is
and then
Nkind (Selector_Name (Name (N))) = N_Operator_Symbol))
then
+
declare
Arg1 : constant Node_Id := First (Parameter_Associations (N));
+ U1 : constant Boolean :=
+ Present (Universal_Interpretation (Arg1));
+ U2 : constant Boolean :=
+ Present (Next (Arg1)) and then
+ Present (Universal_Interpretation (Next (Arg1)));
begin
- if Present (Universal_Interpretation (Arg1))
- and then
- (No (Next (Arg1))
- or else Present (Universal_Interpretation (Next (Arg1))))
- then
- return;
+ if U1 and then not U2 then
+ Remove_Address_Interpretations (First_Op);
- else
+ elsif U2 and then not U1 then
+ Remove_Address_Interpretations (Second_Op);
+ end if;
+
+ if not (U1 and U2) then
Get_First_Interp (N, I, It);
while Present (It.Nam) loop
- if Scope (It.Nam) = Standard_Standard then
+ if Scope (It.Nam) = Standard_Standard
+ and then It.Typ = Base_Type (Etype (Abstract_Op))
+ then
Remove_Interp (I);
end if;
@@ -4418,7 +4498,7 @@ package body Sem_Ch4 is
end if;
-- If the removal has left no valid interpretations, emit
- -- error message now an label node as illegal.
+ -- error message now and label node as illegal.
if Present (Abstract_Op) then
Get_First_Interp (N, I, It);
diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
index bd2a07fcd10..8e2cd6a8ea7 100644
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -48,6 +48,7 @@ with Sem_Ch3; use Sem_Ch3;
with Sem_Ch4; use Sem_Ch4;
with Sem_Ch5; use Sem_Ch5;
with Sem_Ch8; use Sem_Ch8;
+with Sem_Ch10; use Sem_Ch10;
with Sem_Ch12; use Sem_Ch12;
with Sem_Disp; use Sem_Disp;
with Sem_Dist; use Sem_Dist;
@@ -88,6 +89,8 @@ package body Sem_Ch6 is
-- subsequenty used for inline expansions at call sites. If subprogram can
-- be inlined (depending on size and nature of local declarations) this
-- function returns true. Otherwise subprogram body is treated normally.
+ -- If proper warnings are enabled and the subprogram contains a construct
+ -- that cannot be inlined, the offending construct is flagged accordingly.
type Conformance_Type is
(Type_Conformant, Mode_Conformant, Subtype_Conformant, Fully_Conformant);
@@ -1147,6 +1150,15 @@ package body Sem_Ch6 is
Build_Body_To_Inline (N, Spec_Id);
end if;
+ -- Ada 0Y (AI-262): In library subprogram bodies, after the analysis
+ -- if its specification we have to install the private withed units.
+
+ if Is_Compilation_Unit (Body_Id)
+ and then Scope (Body_Id) = Standard_Standard
+ then
+ Install_Private_With_Clauses (Body_Id);
+ end if;
+
-- Now we can go on to analyze the body
HSS := Handled_Statement_Sequence (N);
@@ -2956,6 +2968,7 @@ package body Sem_Ch6 is
is
Type_1 : Entity_Id := T1;
Type_2 : Entity_Id := T2;
+ Are_Anonymous_Access_To_Subprogram_Types : Boolean := False;
function Base_Types_Match (T1, T2 : Entity_Id) return Boolean;
-- If neither T1 nor T2 are generic actual types, or if they are
@@ -2985,6 +2998,17 @@ package body Sem_Ch6 is
or else not Is_Generic_Actual_Type (T2)
or else Scope (T1) /= Scope (T2);
+ -- In some cases a type imported through a limited_with clause,
+ -- and its non-limited view are both visible, for example in an
+ -- anonymous access_to_classwide type in a formal. Both entities
+ -- designate the same type.
+
+ elsif From_With_Type (T1)
+ and then Ekind (T1) = E_Incomplete_Type
+ and then T2 = Non_Limited_View (T1)
+ then
+ return True;
+
else
return False;
end if;
@@ -3030,11 +3054,38 @@ package body Sem_Ch6 is
or else Subtypes_Statically_Match (Type_1, Full_View (Type_2));
end if;
+ -- Ada 0Y (AI-254): Detect anonymous access to subprogram types.
+
+ Are_Anonymous_Access_To_Subprogram_Types :=
+
+ -- Case 1: Anonymous access to subprogram types
+
+ (Ekind (Type_1) = E_Anonymous_Access_Subprogram_Type
+ and then Ekind (Type_2) = E_Anonymous_Access_Subprogram_Type)
+
+ -- Case 2: Anonymous access to PROTECTED subprogram types. In this
+ -- case the anonymous type_declaration has been replaced by an
+ -- occurrence of an internal access to subprogram type declaration
+ -- available through the Original_Access_Type attribute
+
+ or else
+ (Ekind (Type_1) = E_Access_Protected_Subprogram_Type
+ and then Ekind (Type_2) = E_Access_Protected_Subprogram_Type
+ and then not Comes_From_Source (Type_1)
+ and then not Comes_From_Source (Type_2)
+ and then Present (Original_Access_Type (Type_1))
+ and then Present (Original_Access_Type (Type_2))
+ and then Ekind (Original_Access_Type (Type_1)) =
+ E_Anonymous_Access_Protected_Subprogram_Type
+ and then Ekind (Original_Access_Type (Type_2)) =
+ E_Anonymous_Access_Protected_Subprogram_Type);
+
-- Test anonymous access type case. For this case, static subtype
-- matching is required for mode conformance (RM 6.3.1(15))
- if Ekind (Type_1) = E_Anonymous_Access_Type
- and then Ekind (Type_2) = E_Anonymous_Access_Type
+ if (Ekind (Type_1) = E_Anonymous_Access_Type
+ and then Ekind (Type_2) = E_Anonymous_Access_Type)
+ or else Are_Anonymous_Access_To_Subprogram_Types -- Ada 0Y (AI-254)
then
declare
Desig_1 : Entity_Id;
@@ -3043,7 +3094,7 @@ package body Sem_Ch6 is
begin
Desig_1 := Directly_Designated_Type (Type_1);
- -- An access parameter can designate an incomplete type.
+ -- An access parameter can designate an incomplete type
if Ekind (Desig_1) = E_Incomplete_Type
and then Present (Full_View (Desig_1))
@@ -3083,11 +3134,17 @@ package body Sem_Ch6 is
Conforming_Types
(Etype (Base_Type (Desig_1)),
Etype (Base_Type (Desig_2)), Ctype);
+
+ elsif Are_Anonymous_Access_To_Subprogram_Types then
+ return Ctype = Type_Conformant
+ or else
+ Subtypes_Statically_Match (Desig_1, Desig_2);
+
else
return Base_Type (Desig_1) = Base_Type (Desig_2)
and then (Ctype = Type_Conformant
- or else
- Subtypes_Statically_Match (Desig_1, Desig_2));
+ or else
+ Subtypes_Statically_Match (Desig_1, Desig_2));
end if;
end;
@@ -4552,8 +4609,9 @@ package body Sem_Ch6 is
end if;
-- In any case the implicit operation remains hidden by
- -- the existing declaration.
+ -- the existing declaration, which is overriding.
+ Set_Is_Overriding_Operation (E);
return;
-- Within an instance, the renaming declarations for
@@ -4881,15 +4939,97 @@ package body Sem_Ch6 is
Parameter_Type (Param_Spec), Formal_Type);
end if;
+ -- Ada 0Y (AI-231): Create and decorate an internal subtype
+ -- declaration corresponding to the null-excluding type of the
+ -- formal in the enclosing scope. In addition, replace the
+ -- parameter type of the formal to this internal subtype.
+
+ if Null_Exclusion_Present (Param_Spec) then
+ declare
+ Loc : constant Source_Ptr := Sloc (Param_Spec);
+
+ Anon : constant Entity_Id :=
+ Make_Defining_Identifier (Loc,
+ Chars => New_Internal_Name ('S'));
+
+ Curr_Scope : constant Scope_Stack_Entry :=
+ Scope_Stack.Table (Scope_Stack.Last);
+
+ Ptype : constant Node_Id := Parameter_Type (Param_Spec);
+ Decl : Node_Id;
+ P : Node_Id := Parent (Parent (Related_Nod));
+
+ begin
+ Set_Is_Internal (Anon);
+
+ Decl :=
+ Make_Subtype_Declaration (Loc,
+ Defining_Identifier => Anon,
+ Null_Exclusion_Present => True,
+ Subtype_Indication =>
+ New_Occurrence_Of (Etype (Ptype), Loc));
+
+ -- Propagate the null-excluding attribute to the new entity
+
+ if Null_Exclusion_Present (Param_Spec) then
+ Set_Null_Exclusion_Present (Param_Spec, False);
+ Set_Can_Never_Be_Null (Anon);
+ end if;
+
+ Mark_Rewrite_Insertion (Decl);
+
+ -- Insert the new declaration in the nearest enclosing scope
+
+ while not Has_Declarations (P) loop
+ P := Parent (P);
+ end loop;
+
+ Prepend (Decl, Declarations (P));
+
+ Rewrite (Ptype, New_Occurrence_Of (Anon, Loc));
+ Mark_Rewrite_Insertion (Ptype);
+
+ -- Analyze the new declaration in the context of the
+ -- enclosing scope
+
+ Scope_Stack.Decrement_Last;
+ Analyze (Decl);
+ Scope_Stack.Append (Curr_Scope);
+
+ Formal_Type := Anon;
+ end;
+ end if;
+
+ -- Ada 0Y (AI-231): Static checks
+
+ if Null_Exclusion_Present (Param_Spec)
+ or else Can_Never_Be_Null (Entity (Ptype))
+ then
+ Null_Exclusion_Static_Checks (Param_Spec);
+ end if;
+
-- An access formal type
else
Formal_Type :=
Access_Definition (Related_Nod, Parameter_Type (Param_Spec));
+
+ -- Ada 0Y (AI-254)
+
+ declare
+ AD : constant Node_Id :=
+ Access_To_Subprogram_Definition
+ (Parameter_Type (Param_Spec));
+ begin
+ if Present (AD) and then Protected_Present (AD) then
+ Formal_Type :=
+ Replace_Anonymous_Access_To_Protected_Subprogram
+ (Param_Spec, Formal_Type);
+ end if;
+ end;
end if;
Set_Etype (Formal, Formal_Type);
-
Default := Expression (Param_Spec);
if Present (Default) then
@@ -4948,19 +5088,6 @@ package body Sem_Ch6 is
Apply_Scalar_Range_Check (Default, Formal_Type);
end if;
-
- end if;
-
- -- Ada 0Y (AI-231): Static checks
-
- Ptype := Parameter_Type (Param_Spec);
-
- if Extensions_Allowed
- and then Nkind (Ptype) /= N_Access_Definition
- and then (Null_Exclusion_Present (Parent (Formal))
- or else Can_Never_Be_Null (Entity (Ptype)))
- then
- Null_Exclusion_Static_Checks (Param_Spec);
end if;
end if;
@@ -5010,7 +5137,6 @@ package body Sem_Ch6 is
T : Entity_Id;
First_Stmt : Node_Id := Empty;
AS_Needed : Boolean;
- Null_Exclusion : Boolean := False;
begin
-- If this is an emtpy initialization procedure, no need to create
@@ -5065,17 +5191,6 @@ package body Sem_Ch6 is
then
AS_Needed := True;
- -- Ada 0Y (AI-231)
-
- elsif Extensions_Allowed
- and then Is_Access_Type (T)
- and then Null_Exclusion_Present (Parent (Formal))
- and then Nkind (Parameter_Type (Parent (Formal)))
- /= N_Access_Definition
- then
- AS_Needed := True;
- Null_Exclusion := True;
-
-- All other cases do not need an actual subtype
else
@@ -5086,40 +5201,7 @@ package body Sem_Ch6 is
-- unconstrained discriminated records.
if AS_Needed then
-
- -- Ada 0Y (AI-231): Generate actual null-excluding subtype
-
- if Extensions_Allowed
- and then Null_Exclusion
- then
- declare
- Loc : constant Source_Ptr := Sloc (Formal);
- Anon : constant Entity_Id :=
- Make_Defining_Identifier (Loc,
- New_Internal_Name ('S'));
- Ptype : constant Node_Id
- := Parameter_Type (Parent (Formal));
- begin
- -- T == Etype (Formal)
- Set_Is_Internal (Anon);
- Decl :=
- Make_Subtype_Declaration (Loc,
- Defining_Identifier => Anon,
- Null_Exclusion_Present => True,
- Subtype_Indication =>
- New_Occurrence_Of (Etype (Ptype), Loc));
- Mark_Rewrite_Insertion (Decl);
- Prepend (Decl, Declarations (Parent (N)));
-
- Rewrite (Ptype, New_Occurrence_Of (Anon, Loc));
- Mark_Rewrite_Insertion (Ptype);
- -- Set_Scope (Anon, Scope (Scope (Formal)));
-
- Set_Etype (Formal, Anon);
- Set_Null_Exclusion_Present (Parent (Formal), False);
- end;
-
- elsif Nkind (N) = N_Accept_Statement then
+ if Nkind (N) = N_Accept_Statement then
-- If expansion is active, The formal is replaced by a local
-- variable that renames the corresponding entry of the
@@ -5151,17 +5233,10 @@ package body Sem_Ch6 is
Mark_Rewrite_Insertion (Decl);
end if;
- Analyze (Decl);
-
- -- Ada 0Y (AI-231): Previous analysis leaves the entity of the
- -- null-excluding subtype declaration associated with the internal
- -- scope; because this declaration has been inserted before the
- -- subprogram we associate it now with the enclosing scope.
+ -- The declaration uses the bounds of an existing object,
+ -- and therefore needs no constraint checks.
- if Null_Exclusion then
- Set_Scope (Defining_Identifier (Decl),
- Scope (Scope (Formal)));
- end if;
+ Analyze (Decl, Suppress => All_Checks);
-- We need to freeze manually the generated type when it is
-- inserted anywhere else than in a declarative part.
diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb
index 9a61938b035..518179d8587 100644
--- a/gcc/ada/sem_ch8.adb
+++ b/gcc/ada/sem_ch8.adb
@@ -428,6 +428,10 @@ package body Sem_Ch8 is
-- Find a type derived from Character or Wide_Character in the prefix of N.
-- Used to resolved qualified names whose selector is a character literal.
+ function Has_Private_With (E : Entity_Id) return Boolean;
+ -- Ada 0Y (AI-262): Determines if the current compilation unit has a
+ -- private with on E
+
procedure Find_Expanded_Name (N : Node_Id);
-- Selected component is known to be expanded name. Verify legality
-- of selector given the scope denoted by prefix.
@@ -683,18 +687,28 @@ package body Sem_Ch8 is
T := Entity (Subtype_Mark (N));
Analyze_And_Resolve (Nam, T);
- -- Ada 0Y (AI-230): Access renaming
+ -- Ada 0Y (AI-230/AI-254): Access renaming
- elsif Present (Access_Definition (N)) then
- Find_Type (Subtype_Mark (Access_Definition (N)));
+ else pragma Assert (Present (Access_Definition (N)));
T := Access_Definition
(Related_Nod => N,
N => Access_Definition (N));
+
Analyze_And_Resolve (Nam, T);
- else
- pragma Assert (False);
- null;
+ -- Ada 0Y (AI-230): Renaming of anonymous access-to-constant types
+ -- allowed if and only if the renamed object is access-to-constant
+
+ if Constant_Present (Access_Definition (N))
+ and then not Is_Access_Constant (Etype (Nam))
+ then
+ Error_Msg_N ("(Ada 0Y): the renamed object is not "
+ & "access-to-constant ('R'M 8.5.1(6))", N);
+
+ elsif Null_Exclusion_Present (Access_Definition (N)) then
+ Error_Msg_N ("(Ada 0Y): null-excluding attribute ignored "
+ & "('R'M 8.5.1(6))?", N);
+ end if;
end if;
-- An object renaming requires an exact match of the type;
@@ -2392,6 +2406,11 @@ package body Sem_Ch8 is
-- user point of view to warrant an error message of "not visible"
-- rather than undefined.
+ Nvis_Is_Private_Subprg : Boolean := False;
+ -- Ada 0Y (AI-262): Set True to indicate that a form of Beaujolais
+ -- effect concerning library subprograms has been detected. Used to
+ -- generate the precise error message.
+
function From_Actual_Package (E : Entity_Id) return Boolean;
-- Returns true if the entity is declared in a package that is
-- an actual for a formal package of the current instance. Such an
@@ -2552,10 +2571,46 @@ package body Sem_Ch8 is
-------------------
procedure Nvis_Messages is
- Ent : Entity_Id;
- Hidden : Boolean := False;
+ Comp_Unit : Node_Id;
+ Ent : Entity_Id;
+ Hidden : Boolean := False;
+ Item : Node_Id;
begin
+ -- Ada 0Y (AI-262): Generate a precise error concerning the
+ -- Beaujolais effect that was previously detected
+
+ if Nvis_Is_Private_Subprg then
+
+ pragma Assert (Nkind (E2) = N_Defining_Identifier
+ and then Ekind (E2) = E_Function
+ and then Scope (E2) = Standard_Standard
+ and then Has_Private_With (E2));
+
+ -- Find the sloc corresponding to the private with'ed unit
+
+ Comp_Unit := Cunit (Current_Sem_Unit);
+ Item := First (Context_Items (Comp_Unit));
+ Error_Msg_Sloc := No_Location;
+
+ while Present (Item) loop
+ if Nkind (Item) = N_With_Clause
+ and then Private_Present (Item)
+ and then Entity (Name (Item)) = E2
+ then
+ Error_Msg_Sloc := Sloc (Item);
+ exit;
+ end if;
+
+ Next (Item);
+ end loop;
+
+ pragma Assert (Error_Msg_Sloc /= No_Location);
+
+ Error_Msg_N ("(Ada 0Y): hidden by private with clause #", N);
+ return;
+ end if;
+
Undefined (Nvis => True);
if Msg then
@@ -2935,6 +2990,29 @@ package body Sem_Ch8 is
elsif Is_Potentially_Use_Visible (E2) then
Only_One_Visible := False;
All_Overloadable := All_Overloadable and Is_Overloadable (E2);
+
+ -- Ada 0Y (AI-262): Protect against a form of Beujolais effect
+ -- that can occurr in private_with clauses. Example:
+
+ -- with A;
+ -- private with B; package A is
+ -- package C is function B return Integer;
+ -- use A; end A;
+ -- V1 : Integer := B;
+ -- private function B return Integer;
+ -- V2 : Integer := B;
+ -- end C;
+
+ -- V1 resolves to A.B, but V2 resolves to library unit B.
+
+ elsif Ekind (E2) = E_Function
+ and then Scope (E2) = Standard_Standard
+ and then Has_Private_With (E2)
+ then
+ Only_One_Visible := False;
+ All_Overloadable := False;
+ Nvis_Is_Private_Subprg := True;
+ exit;
end if;
E2 := Homonym (E2);
@@ -4419,6 +4497,30 @@ package body Sem_Ch8 is
return Found;
end Has_Implicit_Character_Literal;
+ ----------------------
+ -- Has_Private_With --
+ ----------------------
+
+ function Has_Private_With (E : Entity_Id) return Boolean is
+ Comp_Unit : constant Node_Id := Cunit (Current_Sem_Unit);
+ Item : Node_Id;
+
+ begin
+ Item := First (Context_Items (Comp_Unit));
+ while Present (Item) loop
+ if Nkind (Item) = N_With_Clause
+ and then Private_Present (Item)
+ and then Entity (Name (Item)) = E
+ then
+ return True;
+ end if;
+
+ Next (Item);
+ end loop;
+
+ return False;
+ end Has_Private_With;
+
---------------------------
-- Has_Implicit_Operator --
---------------------------
@@ -5342,6 +5444,7 @@ package body Sem_Ch8 is
Prev : Entity_Id;
Current_Instance : Entity_Id := Empty;
Real_P : Entity_Id;
+ Private_With_OK : Boolean := False;
begin
if Ekind (P) /= E_Package then
@@ -5382,12 +5485,25 @@ package body Sem_Ch8 is
Real_P := P;
end if;
+ -- Ada 0Y (AI-262): Check the use_clause of a private withed package
+ -- found in the private part of a package specification
+
+ if In_Private_Part (Current_Scope)
+ and then Has_Private_With (P)
+ and then Is_Child_Unit (Current_Scope)
+ and then Is_Child_Unit (P)
+ and then Is_Ancestor_Package (Scope (Current_Scope), P)
+ then
+ Private_With_OK := True;
+ end if;
+
-- Loop through entities in one package making them potentially
-- use-visible.
Id := First_Entity (P);
while Present (Id)
- and then Id /= First_Private_Entity (P)
+ and then (Id /= First_Private_Entity (P)
+ or else Private_With_OK) -- Ada 0Y (AI-262)
loop
Prev := Current_Entity (Id);
diff --git a/gcc/ada/sem_disp.adb b/gcc/ada/sem_disp.adb
index 4c538b0ff40..5c85af2d600 100644
--- a/gcc/ada/sem_disp.adb
+++ b/gcc/ada/sem_disp.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -41,6 +41,7 @@ with Sem_Ch6; use Sem_Ch6;
with Sem_Eval; use Sem_Eval;
with Sem_Util; use Sem_Util;
with Snames; use Snames;
+with Stand; use Stand;
with Sinfo; use Sinfo;
with Uintp; use Uintp;
@@ -423,6 +424,27 @@ 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;
@@ -595,8 +617,19 @@ package body Sem_Disp is
if Present (Old_Subp) then
Check_Subtype_Conformant (Subp, Old_Subp);
- Override_Dispatching_Operation (Tagged_Type, Old_Subp, Subp);
- Set_Is_Overriding_Operation (Subp);
+ if (Chars (Subp) = Name_Initialize
+ or else Chars (Subp) = Name_Adjust
+ or else Chars (Subp) = Name_Finalize)
+ and then Is_Controlled (Tagged_Type)
+ 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);
+ else
+ Override_Dispatching_Operation (Tagged_Type, Old_Subp, Subp);
+ Set_Is_Overriding_Operation (Subp);
+ end if;
else
Add_Dispatching_Operation (Tagged_Type, Subp);
end if;
diff --git a/gcc/ada/sem_dist.adb b/gcc/ada/sem_dist.adb
index efaf5a19241..c48361092fe 100644
--- a/gcc/ada/sem_dist.adb
+++ b/gcc/ada/sem_dist.adb
@@ -151,47 +151,6 @@ package body Sem_Dist is
return End_String;
end Full_Qualified_Name;
- -----------------------
- -- Get_Subprogram_Id --
- -----------------------
-
- function Get_Subprogram_Id (E : Entity_Id) return Int is
- Current_Declaration : Node_Id;
- Result : Int := 0;
-
- begin
- pragma Assert
- (Is_Remote_Call_Interface (Scope (E))
- and then
- (Nkind (Parent (E)) = N_Procedure_Specification
- or else
- Nkind (Parent (E)) = N_Function_Specification));
-
- Current_Declaration :=
- First (Visible_Declarations
- (Package_Specification_Of_Scope (Scope (E))));
-
- while Current_Declaration /= Empty loop
- if Nkind (Current_Declaration) = N_Subprogram_Declaration
- and then Comes_From_Source (Current_Declaration)
- then
- if Defining_Unit_Name
- (Specification (Current_Declaration)) = E
- then
- return Result;
- end if;
-
- Result := Result + 1;
- end if;
-
- Next (Current_Declaration);
- end loop;
-
- -- Error if we do not find it
-
- raise Program_Error;
- end Get_Subprogram_Id;
-
------------------------
-- Is_All_Remote_Call --
------------------------
@@ -334,9 +293,9 @@ package body Sem_Dist is
RS_Pkg_E : Entity_Id;
RAS_Type : Entity_Id;
Async_E : Entity_Id;
- Subp_Id : Int;
+ All_Calls_Remote_E : Entity_Id;
Attribute_Subp : Entity_Id;
- Parameter : Node_Id;
+ Local_Addr : Node_Id;
begin
-- Check if we have to expand the access attribute
@@ -373,27 +332,28 @@ package body Sem_Dist is
RS_Pkg_Specif := Parent (Remote_Subp_Decl);
RS_Pkg_E := Defining_Entity (RS_Pkg_Specif);
- Subp_Id := Get_Subprogram_Id (Remote_Subp);
+ Async_E :=
+ Boolean_Literals (Ekind (Remote_Subp) = E_Procedure
+ and then Is_Asynchronous (Remote_Subp));
- if Ekind (Remote_Subp) = E_Procedure
- and then Is_Asynchronous (Remote_Subp)
- then
- Async_E := Standard_True;
- else
- Async_E := Standard_False;
- end if;
+ All_Calls_Remote_E :=
+ Boolean_Literals (Has_All_Calls_Remote (RS_Pkg_E));
- Parameter := New_Occurrence_Of (RTE (RE_Null_Address), Loc);
+ Local_Addr :=
+ Make_Attribute_Reference (Loc,
+ Prefix => New_Occurrence_Of (Remote_Subp, Loc),
+ Attribute_Name => Name_Address);
Tick_Access_Conv_Call :=
Make_Function_Call (Loc,
Name => New_Occurrence_Of (Attribute_Subp, Loc),
Parameter_Associations =>
New_List (
- Parameter,
+ Local_Addr,
Make_String_Literal (Loc, Full_Qualified_Name (RS_Pkg_E)),
- Make_Integer_Literal (Loc, Subp_Id),
- New_Occurrence_Of (Async_E, Loc)));
+ Build_Subprogram_Id (Loc, Remote_Subp),
+ New_Occurrence_Of (Async_E, Loc),
+ New_Occurrence_Of (All_Calls_Remote_E, Loc)));
Rewrite (N, Tick_Access_Conv_Call);
Analyze_And_Resolve (N, RAS_Type);
diff --git a/gcc/ada/sem_dist.ads b/gcc/ada/sem_dist.ads
index 1ce18bfe9a6..efadbef6644 100644
--- a/gcc/ada/sem_dist.ads
+++ b/gcc/ada/sem_dist.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2000 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -83,10 +83,6 @@ package Sem_Dist is
-- aggregate and will return True in this case. Otherwise, it will
-- return False.
- function Get_Subprogram_Id (E : Entity_Id) return Int;
- -- Given a subprogram defined in a RCI package, get its subprogram id
- -- which will be used for remote calls.
-
function Package_Specification_Of_Scope (E : Entity_Id) return Node_Id;
-- Return the N_Package_Specification corresponding to a scope E
diff --git a/gcc/ada/sem_elim.adb b/gcc/ada/sem_elim.adb
index 3f99d828fc4..f5200ca5406 100644
--- a/gcc/ada/sem_elim.adb
+++ b/gcc/ada/sem_elim.adb
@@ -24,19 +24,21 @@
-- --
------------------------------------------------------------------------------
-with Atree; use Atree;
-with Einfo; use Einfo;
-with Errout; use Errout;
-with Namet; use Namet;
-with Nlists; use Nlists;
-with Sinfo; use Sinfo;
-with Snames; use Snames;
-with Stand; use Stand;
-with Stringt; use Stringt;
+with Atree; use Atree;
+with Einfo; use Einfo;
+with Errout; use Errout;
+with Namet; use Namet;
+with Nlists; use Nlists;
+with Sem_Prag; use Sem_Prag;
+with Sinput; use Sinput;
+with Sinfo; use Sinfo;
+with Snames; use Snames;
+with Stand; use Stand;
+with Stringt; use Stringt;
with Table;
-with Uintp; use Uintp;
with GNAT.HTable; use GNAT.HTable;
+
package body Sem_Elim is
No_Elimination : Boolean;
@@ -83,8 +85,9 @@ package body Sem_Elim is
Result_Type : Name_Id;
-- Result type name if Result_Types parameter present, No_Name if not
- Homonym_Number : Uint;
- -- Homonyn number if Homonym_Number parameter present, No_Uint if not.
+ Source_Location : Name_Id;
+ -- String describing the source location of subprogram defining name if
+ -- Source_Location parameter present, No_Name if not
Hash_Link : Access_Elim_Data;
-- Link for hash table use
@@ -229,8 +232,6 @@ package body Sem_Elim is
Elmt : Access_Elim_Data;
Scop : Entity_Id;
Form : Entity_Id;
- Ctr : Nat;
- Ent : Entity_Id;
function Original_Chars (S : Entity_Id) return Name_Id;
-- If the candidate subprogram is a protected operation of a single
@@ -265,10 +266,9 @@ package body Sem_Elim is
return;
end if;
- Elmt := Elim_Hash_Table.Get (Chars (E));
-
-- Loop through homonyms for this key
+ Elmt := Elim_Hash_Table.Get (Chars (E));
while Elmt /= null loop
declare
procedure Set_Eliminated;
@@ -355,27 +355,231 @@ package body Sem_Elim is
Set_Eliminated;
return;
- -- Check for case of subprogram
+ -- Check for case of subprogram
elsif Ekind (E) = E_Function
or else Ekind (E) = E_Procedure
then
- -- If Homonym_Number present, then see if it matches
+ -- If Source_Location present, then see if it matches
+
+ if Elmt.Source_Location /= No_Name then
+ Get_Name_String (Elmt.Source_Location);
+
+ declare
+ Sloc_Trace : constant String :=
+ Name_Buffer (1 .. Name_Len);
+
+ Idx : Natural := Sloc_Trace'First;
+ -- Index in Sloc_Trace, if equals to 0, then we have
+ -- completely traversed Sloc_Trace
+
+ Last : constant Natural := Sloc_Trace'Last;
+
+ P : Source_Ptr;
+ Sindex : Source_File_Index;
+
+ function File_Name_Match return Boolean;
+ -- This function is supposed to be called when Idx points
+ -- to the beginning of the new file name, and Name_Buffer
+ -- is set to contain the name of the proper source file
+ -- from the chain corresponding to the Sloc of E. First
+ -- it checks that these two files have the same name. If
+ -- this check is successful, moves Idx to point to the
+ -- beginning of the column number.
+
+ function Line_Num_Match return Boolean;
+ -- This function is supposed to be called when Idx points
+ -- to the beginning of the column number, and P is
+ -- set to point to the proper Sloc the chain
+ -- corresponding to the Sloc of E. First it checks that
+ -- the line number Idx points on and the line number
+ -- corresponding to P are the same. If this check is
+ -- successful, moves Idx to point to the beginning of
+ -- the next file name in Sloc_Trace. If there is no file
+ -- name any more, Idx is set to 0.
+
+ function Different_Trace_Lengths return Boolean;
+ -- From Idx and P, defines if there are in both traces
+ -- more element(s) in the instantiation chains. Returns
+ -- False if one trace contains more element(s), but
+ -- another does not. If both traces contains more
+ -- elements (that is, the function returns False), moves
+ -- P ahead in the chain corresponding to E, recomputes
+ -- Sindex and sets the name of the corresponding file in
+ -- Name_Buffer
+
+ function Skip_Spaces return Natural;
+ -- If Sloc_Trace (Idx) is not space character, returns
+ -- Idx. Otherwise returns the index of the nearest
+ -- non-space character in Sloc_Trace to the right of
+ -- Idx. Returns 0 if there is no such character.
+
+ -----------------------------
+ -- Different_Trace_Lengths --
+ -----------------------------
+
+ function Different_Trace_Lengths return Boolean is
+ begin
+ P := Instantiation (Sindex);
+
+ if (P = No_Location and then Idx /= 0)
+ or else
+ (P /= No_Location and then Idx = 0)
+ then
+ return True;
- if Elmt.Homonym_Number /= No_Uint then
- Ctr := 1;
+ else
+ if P /= No_Location then
+ Sindex := Get_Source_File_Index (P);
+ Get_Name_String (File_Name (Sindex));
+ end if;
- Ent := E;
- while Present (Homonym (Ent))
- and then Scope (Ent) = Scope (Homonym (Ent))
- loop
- Ctr := Ctr + 1;
- Ent := Homonym (Ent);
- end loop;
+ return False;
+ end if;
+ end Different_Trace_Lengths;
- if Ctr /= Elmt.Homonym_Number then
- goto Continue;
- end if;
+ ---------------------
+ -- File_Name_Match --
+ ---------------------
+
+ function File_Name_Match return Boolean is
+ Tmp_Idx : Natural;
+ End_Idx : Natural;
+
+ begin
+ if Idx = 0 then
+ return False;
+ end if;
+
+ -- Find first colon. If no colon, then return False.
+ -- If there is a colon, Tmp_Idx is set to point just
+ -- before the colon.
+
+ Tmp_Idx := Idx - 1;
+ loop
+ if Tmp_Idx >= Last then
+ return False;
+ elsif Sloc_Trace (Tmp_Idx + 1) = ':' then
+ exit;
+ else
+ Tmp_Idx := Tmp_Idx + 1;
+ end if;
+ end loop;
+
+ -- Find last non-space before this colon. If there
+ -- is no no space character before this colon, then
+ -- return False. Otherwise, End_Idx set to point to
+ -- this non-space character.
+
+ End_Idx := Tmp_Idx;
+ loop
+ if End_Idx < Idx then
+ return False;
+ elsif Sloc_Trace (End_Idx) /= ' ' then
+ exit;
+ else
+ End_Idx := End_Idx - 1;
+ end if;
+ end loop;
+
+ -- Now see if file name matches what is in Name_Buffer
+ -- and if so, step Idx past it and return True. If the
+ -- name does not match, return False.
+
+ if Sloc_Trace (Idx .. End_Idx) =
+ Name_Buffer (1 .. Name_Len)
+ then
+ Idx := Tmp_Idx + 2;
+ Idx := Skip_Spaces;
+ return True;
+ else
+ return False;
+ end if;
+ end File_Name_Match;
+
+ --------------------
+ -- Line_Num_Match --
+ --------------------
+
+ function Line_Num_Match return Boolean is
+ N : Int := 0;
+
+ begin
+ if Idx = 0 then
+ return False;
+ end if;
+
+ while Idx <= Last
+ and then Sloc_Trace (Idx) in '0' .. '9'
+ loop
+ N := N * 10 +
+ (Character'Pos (Sloc_Trace (Idx)) -
+ Character'Pos ('0'));
+ Idx := Idx + 1;
+ end loop;
+
+ if Get_Physical_Line_Number (P) =
+ Physical_Line_Number (N)
+ then
+ while Sloc_Trace (Idx) /= '['
+ and then Idx <= Last
+ loop
+ Idx := Idx + 1;
+ end loop;
+
+ if Sloc_Trace (Idx) = '['
+ and then Idx < Last
+ then
+ Idx := Idx + 1;
+ Idx := Skip_Spaces;
+ else
+ Idx := 0;
+ end if;
+
+ return True;
+ else
+ return False;
+ end if;
+ end Line_Num_Match;
+
+ -----------------
+ -- Skip_Spaces --
+ -----------------
+
+ function Skip_Spaces return Natural is
+ Res : Natural := Idx;
+
+ begin
+ while Sloc_Trace (Res) = ' ' loop
+ Res := Res + 1;
+
+ if Res > Last then
+ Res := 0;
+ exit;
+ end if;
+ end loop;
+
+ return Res;
+ end Skip_Spaces;
+
+ begin
+ P := Sloc (E);
+ Sindex := Get_Source_File_Index (P);
+ Get_Name_String (File_Name (Sindex));
+
+ Idx := Skip_Spaces;
+ while Idx > 0 loop
+ if not File_Name_Match then
+ goto Continue;
+ elsif not Line_Num_Match then
+ goto Continue;
+ end if;
+
+ if Different_Trace_Lengths then
+ goto Continue;
+ end if;
+ end loop;
+ end;
end if;
-- If we have a Result_Type, then we must have a function
@@ -394,7 +598,12 @@ package body Sem_Elim is
if Elmt.Parameter_Types /= null then
Form := First_Formal (E);
- if No (Form) and then Elmt.Parameter_Types = null then
+ if No (Form)
+ and then Elmt.Parameter_Types'Length = 1
+ and then Elmt.Parameter_Types (1) = No_Name
+ then
+ -- Parameterless procedure matches
+
null;
elsif Elmt.Parameter_Types = null then
@@ -423,9 +632,10 @@ package body Sem_Elim is
Set_Eliminated;
return;
end if;
-
- <<Continue>> Elmt := Elmt.Homonym;
end;
+
+ <<Continue>>
+ Elmt := Elmt.Homonym;
end loop;
return;
@@ -447,7 +657,7 @@ package body Sem_Elim is
-- Should never fall through, since entry should be in table
- pragma Assert (False);
+ raise Program_Error;
end Eliminate_Error_Msg;
----------------
@@ -471,7 +681,7 @@ package body Sem_Elim is
Arg_Entity : Node_Id;
Arg_Parameter_Types : Node_Id;
Arg_Result_Type : Node_Id;
- Arg_Homonym_Number : Node_Id)
+ Arg_Source_Location : Node_Id)
is
Data : constant Access_Elim_Data := new Elim_Data;
-- Build result data here
@@ -566,15 +776,11 @@ package body Sem_Elim is
Data.Entity_Scope (1) := Chars (Arg_Ent);
- elsif Nkind (Arg_Entity) = N_String_Literal then
- String_To_Name_Buffer (Strval (Arg_Entity));
+ elsif Is_Config_Static_String (Arg_Entity) then
Data.Entity_Name := Name_Find;
Data.Entity_Node := Arg_Entity;
else
- Error_Msg_N
- ("wrong form for Entity_Argument parameter of pragma%",
- Arg_Unit_Name);
return;
end if;
else
@@ -586,86 +792,77 @@ package body Sem_Elim is
if Present (Arg_Parameter_Types) then
- -- Case of one name, which looks like a parenthesized literal
- -- rather than an aggregate.
-
- if Nkind (Arg_Parameter_Types) = N_String_Literal
- and then Paren_Count (Arg_Parameter_Types) = 1
- then
- String_To_Name_Buffer (Strval (Arg_Parameter_Types));
- Data.Parameter_Types := new Names'(1 => Name_Find);
-
- -- Otherwise must be an aggregate
-
- elsif Nkind (Arg_Parameter_Types) /= N_Aggregate
- or else Present (Component_Associations (Arg_Parameter_Types))
- or else No (Expressions (Arg_Parameter_Types))
- then
- Error_Msg_N
- ("Parameter_Types for pragma% must be list of string literals",
- Arg_Parameter_Types);
- return;
-
-- Here for aggregate case
- else
+ if Nkind (Arg_Parameter_Types) = N_Aggregate then
Data.Parameter_Types :=
new Names
(1 .. List_Length (Expressions (Arg_Parameter_Types)));
Lit := First (Expressions (Arg_Parameter_Types));
for J in Data.Parameter_Types'Range loop
- if Nkind (Lit) /= N_String_Literal then
- Error_Msg_N
- ("parameter types for pragma% must be string literals",
- Lit);
+ if Is_Config_Static_String (Lit) then
+ Data.Parameter_Types (J) := Name_Find;
+ Next (Lit);
+ else
return;
end if;
-
- String_To_Name_Buffer (Strval (Lit));
- Data.Parameter_Types (J) := Name_Find;
- Next (Lit);
end loop;
+
+ -- Otherwise we must have case of one name, which looks like a
+ -- parenthesized literal rather than an aggregate.
+
+ elsif Paren_Count (Arg_Parameter_Types) /= 1 then
+ Error_Msg_N
+ ("wrong form for argument of pragma Eliminate",
+ Arg_Parameter_Types);
+ return;
+
+ elsif Is_Config_Static_String (Arg_Parameter_Types) then
+ String_To_Name_Buffer (Strval (Arg_Parameter_Types));
+
+ if Name_Len = 0 then
+
+ -- Parameterless procedure
+
+ Data.Parameter_Types := new Names'(1 => No_Name);
+
+ else
+ Data.Parameter_Types := new Names'(1 => Name_Find);
+ end if;
+
+ else
+ return;
end if;
end if;
-- Process Result_Types argument
if Present (Arg_Result_Type) then
-
- if Nkind (Arg_Result_Type) /= N_String_Literal then
- Error_Msg_N
- ("Result_Type argument for pragma% must be string literal",
- Arg_Result_Type);
+ if Is_Config_Static_String (Arg_Result_Type) then
+ Data.Result_Type := Name_Find;
+ else
return;
end if;
- String_To_Name_Buffer (Strval (Arg_Result_Type));
- Data.Result_Type := Name_Find;
+ -- Here if no Result_Types argument
else
Data.Result_Type := No_Name;
end if;
- -- Process Homonym_Number argument
-
- if Present (Arg_Homonym_Number) then
+ -- Process Source_Location argument
- if Nkind (Arg_Homonym_Number) /= N_Integer_Literal then
- Error_Msg_N
- ("Homonym_Number argument for pragma% must be integer literal",
- Arg_Homonym_Number);
+ if Present (Arg_Source_Location) then
+ if Is_Config_Static_String (Arg_Source_Location) then
+ Data.Source_Location := Name_Find;
+ else
return;
end if;
-
- Data.Homonym_Number := Intval (Arg_Homonym_Number);
-
else
- Data.Homonym_Number := No_Uint;
+ Data.Source_Location := No_Name;
end if;
- -- Now link this new entry into the hash table
-
Elmt := Elim_Hash_Table.Get (Hash_Subprograms.Get_Key (Data));
-- If we already have an entry with this same key, then link
diff --git a/gcc/ada/sem_elim.ads b/gcc/ada/sem_elim.ads
index 133219e3310..4e9911f8850 100644
--- a/gcc/ada/sem_elim.ads
+++ b/gcc/ada/sem_elim.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1997-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 1997-2004 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- --
@@ -39,7 +39,7 @@ package Sem_Elim is
Arg_Entity : Node_Id;
Arg_Parameter_Types : Node_Id;
Arg_Result_Type : Node_Id;
- Arg_Homonym_Number : Node_Id);
+ Arg_Source_Location : Node_Id);
-- Process eliminate pragma (given by Pragma_Node). The number of
-- arguments has been checked, as well as possible optional identifiers,
-- but no other checks have been made. This subprogram completes the
diff --git a/gcc/ada/sem_eval.adb b/gcc/ada/sem_eval.adb
index 9c203101342..b33973f2051 100644
--- a/gcc/ada/sem_eval.adb
+++ b/gcc/ada/sem_eval.adb
@@ -1954,6 +1954,7 @@ package body Sem_Eval is
if Nkind (Operand) = N_Raise_Constraint_Error then
Set_Raises_Constraint_Error (N);
end if;
+
return;
end if;
diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index ea1eab3405a..5ab5bdeed45 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -888,7 +888,7 @@ package body Sem_Prag is
("argument of pragma% must be entity name", Arg1);
elsif Prag_Id = Pragma_Interrupt_Handler then
- Check_Restriction (No_Dynamic_Interrupts, N);
+ Check_Restriction (No_Dynamic_Attachment, N);
end if;
declare
@@ -1693,6 +1693,7 @@ package body Sem_Prag is
Id : Node_Id;
E1 : Entity_Id;
Cname : Name_Id;
+ Comp_Unit : Unit_Number_Type;
procedure Set_Convention_From_Pragma (E : Entity_Id);
-- Set convention in entity E, and also flag that the entity has a
@@ -1907,9 +1908,11 @@ package body Sem_Prag is
end if;
-- For the subprogram case, set proper convention for all homonyms
- -- in same scope.
+ -- in same scope and the same declarative part, i.e. the same
+ -- compilation unit.
else
+ Comp_Unit := Get_Source_Unit (E);
Set_Convention_From_Pragma (E);
-- Treat a pragma Import as an implicit body, for GPS use.
@@ -1928,6 +1931,7 @@ package body Sem_Prag is
-- than one Rep_Item chain, to be fixed later ???
if Comes_From_Source (E1)
+ and then Comp_Unit = Get_Source_Unit (E1)
and then Nkind (Original_Node (Parent (E1))) /=
N_Full_Type_Declaration
then
@@ -2945,21 +2949,24 @@ package body Sem_Prag is
-- Processing for procedure, operator or function.
-- If subprogram is aliased (as for an instance) indicate
- -- that the renamed entity is inlined.
+ -- that the renamed entity (if declared in the same unit)
+ -- is inlined.
if Is_Subprogram (Subp) then
while Present (Alias (Inner_Subp)) loop
Inner_Subp := Alias (Inner_Subp);
end loop;
- Set_Inline_Flags (Inner_Subp);
+ if In_Same_Source_Unit (Subp, Inner_Subp) then
+ Set_Inline_Flags (Inner_Subp);
- Decl := Parent (Parent (Inner_Subp));
+ Decl := Parent (Parent (Inner_Subp));
- if Nkind (Decl) = N_Subprogram_Declaration
- and then Present (Corresponding_Body (Decl))
- then
- Set_Inline_Flags (Corresponding_Body (Decl));
+ if Nkind (Decl) = N_Subprogram_Declaration
+ and then Present (Corresponding_Body (Decl))
+ then
+ Set_Inline_Flags (Corresponding_Body (Decl));
+ end if;
end if;
Applies := True;
@@ -3269,10 +3276,61 @@ package body Sem_Prag is
Error_Pragma_Arg
("invalid form for restriction", Arg);
+ -- Deal with synonyms. This should be done more cleanly ???
+
else
+ -- Boolean_Entry_Barriers is a synonym of Simple_Barriers
+
+ if Chars (Expr) = Name_Boolean_Entry_Barriers then
+ Check_Restriction
+ (No_Implementation_Restrictions, Arg);
+ Set_Restriction (Simple_Barriers, N);
+ Set_Warning (Simple_Barriers);
+
+ -- Max_Entry_Queue_Depth is a synonym of
+ -- Max_Entry_Queue_Length
+
+ elsif Chars (Expr) = Name_Max_Entry_Queue_Depth then
+ Analyze_And_Resolve (Expr, Any_Integer);
+
+ if not Is_OK_Static_Expression (Expr) then
+ Flag_Non_Static_Expr
+ ("value must be static expression!", Expr);
+ raise Pragma_Exit;
+
+ elsif not Is_Integer_Type (Etype (Expr))
+ or else Expr_Value (Expr) < 0
+ then
+ Error_Pragma_Arg
+ ("value must be non-negative integer", Arg);
+
+ -- Restriction pragma is active
+
+ else
+ Val := Expr_Value (Expr);
+
+ if not UI_Is_In_Int_Range (Val) then
+ Error_Pragma_Arg
+ ("pragma ignored, value too large?", Arg);
+ else
+ Set_Restriction (Max_Entry_Queue_Length, N,
+ Integer (UI_To_Int (Val)));
+ Set_Warning (Max_Entry_Queue_Length);
+ end if;
+ end if;
+
+ -- No_Dynamic_Interrupts is a synonym for
+ -- No_Dynamic_Attachment
+
+ elsif Chars (Expr) = Name_No_Dynamic_Interrupts then
+ Check_Restriction
+ (No_Implementation_Restrictions, Arg);
+ Set_Restriction (No_Dynamic_Attachment, N);
+ Set_Warning (No_Dynamic_Attachment);
+
-- No_Requeue is a synonym for No_Requeue_Statements
- if Chars (Expr) = Name_No_Requeue then
+ elsif Chars (Expr) = Name_No_Requeue then
Check_Restriction
(No_Implementation_Restrictions, Arg);
Set_Restriction (No_Requeue_Statements, N);
@@ -3556,10 +3614,11 @@ package body Sem_Prag is
Set_Is_Statically_Allocated (E);
-- Warn if the corresponding W flag is set and the pragma
- -- comes from source. The latter may be not be true e.g. on
+ -- comes from source. The latter may not be true e.g. on
-- VMS where we expand export pragmas for exception codes
- -- associated with imported or exported exceptions. We don't
- -- want the user to be warned about something he didn't write.
+ -- associated with imported or exported exceptions. We do
+ -- not want to generate a warning for something that the
+ -- user did not write.
if Warn_On_Export_Import
and then Comes_From_Source (Arg)
@@ -5405,13 +5464,25 @@ package body Sem_Prag is
-- [,[Entity =>] IDENTIFIER |
-- SELECTED_COMPONENT |
-- STRING_LITERAL]
- -- [,[Parameter_Types =>] PARAMETER_TYPES]
- -- [,[Result_Type =>] result_SUBTYPE_NAME]
- -- [,[Homonym_Number =>] INTEGER_LITERAL]);
+ -- [,]OVERLOADING_RESOLUTION);
+
+ -- OVERLOADING_RESOLUTION ::= PARAMETER_AND_RESULT_TYPE_PROFILE |
+ -- SOURCE_LOCATION
+
+ -- PARAMETER_AND_RESULT_TYPE_PROFILE ::= PROCEDURE_PROFILE |
+ -- FUNCTION_PROFILE
+
+ -- PROCEDURE_PROFILE ::= Parameter_Types => PARAMETER_TYPES
+
+ -- FUNCTION_PROFILE ::= [Parameter_Types => PARAMETER_TYPES,]
+ -- Result_Type => result_SUBTYPE_NAME]
-- PARAMETER_TYPES ::= (SUBTYPE_NAME {, SUBTYPE_NAME})
-- SUBTYPE_NAME ::= STRING_LITERAL
+ -- SOURCE_LOCATION ::= Source_Location => SOURCE_TRACE
+ -- SOURCE_TRACE ::= STRING_LITERAL
+
when Pragma_Eliminate => Eliminate : declare
Args : Args_List (1 .. 5);
Names : constant Name_List (1 .. 5) := (
@@ -5419,13 +5490,13 @@ package body Sem_Prag is
Name_Entity,
Name_Parameter_Types,
Name_Result_Type,
- Name_Homonym_Number);
+ Name_Source_Location);
Unit_Name : Node_Id renames Args (1);
Entity : Node_Id renames Args (2);
Parameter_Types : Node_Id renames Args (3);
Result_Type : Node_Id renames Args (4);
- Homonym_Number : Node_Id renames Args (5);
+ Source_Location : Node_Id renames Args (5);
begin
GNAT_Pragma;
@@ -5441,18 +5512,29 @@ package body Sem_Prag is
or else
Present (Result_Type)
or else
- Present (Homonym_Number))
+ Present (Source_Location))
then
Error_Pragma ("missing Entity argument for pragma%");
end if;
+ if (Present (Parameter_Types)
+ or else
+ Present (Result_Type))
+ and then
+ Present (Source_Location)
+ then
+ Error_Pragma
+ ("parameter profile and source location can not " &
+ "be used together in pragma%");
+ end if;
+
Process_Eliminate_Pragma
(N,
Unit_Name,
Entity,
Parameter_Types,
Result_Type,
- Homonym_Number);
+ Source_Location);
end Eliminate;
--------------------------
@@ -9834,7 +9916,6 @@ package body Sem_Prag is
when Unknown_Pragma =>
raise Program_Error;
-
end case;
exception
@@ -9866,7 +9947,7 @@ package body Sem_Prag is
and then
(Is_Generic_Instance (Result)
or else Nkind (Parent (Declaration_Node (Result))) =
- N_Subprogram_Renaming_Declaration)
+ N_Subprogram_Renaming_Declaration)
and then Present (Alias (Result))
loop
Result := Alias (Result);
@@ -9875,6 +9956,65 @@ package body Sem_Prag is
return Result;
end Get_Base_Subprogram;
+ -----------------------------
+ -- Is_Config_Static_String --
+ -----------------------------
+
+ function Is_Config_Static_String (Arg : Node_Id) return Boolean is
+
+ function Add_Config_Static_String (Arg : Node_Id) return Boolean;
+ -- This is an internal recursive function that is just like the
+ -- outer function except that it adds the string to the name buffer
+ -- rather than placing the string in the name buffer.
+
+ ------------------------------
+ -- Add_Config_Static_String --
+ ------------------------------
+
+ function Add_Config_Static_String (Arg : Node_Id) return Boolean is
+ N : Node_Id;
+ C : Char_Code;
+
+ begin
+ N := Arg;
+
+ if Nkind (N) = N_Op_Concat then
+ if Add_Config_Static_String (Left_Opnd (N)) then
+ N := Right_Opnd (N);
+ else
+ return False;
+ end if;
+ end if;
+
+ if Nkind (N) /= N_String_Literal then
+ Error_Msg_N ("string literal expected for pragma argument", N);
+ return False;
+
+ else
+ for J in 1 .. String_Length (Strval (N)) loop
+ C := Get_String_Char (Strval (N), J);
+
+ if not In_Character_Range (C) then
+ Error_Msg
+ ("string literal contains invalid wide character",
+ Sloc (N) + 1 + Source_Ptr (J));
+ return False;
+ end if;
+
+ Add_Char_To_Name_Buffer (Get_Character (C));
+ end loop;
+ end if;
+
+ return True;
+ end Add_Config_Static_String;
+
+ -- Start of prorcessing for Is_Config_Static_String
+
+ begin
+ Name_Len := 0;
+ return Add_Config_Static_String (Arg);
+ end Is_Config_Static_String;
+
-----------------------------------------
-- Is_Non_Significant_Pragma_Reference --
-----------------------------------------
diff --git a/gcc/ada/sem_prag.ads b/gcc/ada/sem_prag.ads
index 9ff4ede80a2..fe5cd93320a 100644
--- a/gcc/ada/sem_prag.ads
+++ b/gcc/ada/sem_prag.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2002 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -59,6 +59,17 @@ package Sem_Prag is
-- False is returned, then the argument is treated as an entity reference
-- to the operator.
+ function Is_Config_Static_String (Arg : Node_Id) return Boolean;
+ -- This is called for a configuration pragma that requires either a
+ -- string literal or a concatenation of string literals. We cannot
+ -- use normal static string processing because it is too early in
+ -- the case of the pragma appearing in a configuration pragmas file.
+ -- If Arg is of an appropriate form, then this call obtains the string
+ -- (doing any necessary concatenations) and places it in Name_Buffer,
+ -- setting Name_Len to its length, and then returns True. If it is
+ -- not of the correct form, then an appropriate error message is
+ -- posted, and False is returned.
+
procedure Process_Compilation_Unit_Pragmas (N : Node_Id);
-- Called at the start of processing compilation unit N to deal with
-- any special issues regarding pragmas. In particular, we have to
diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
index 103ebfdd947..275e9584993 100644
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -3730,6 +3730,7 @@ package body Sem_Res is
-- we will try later to detect some cases here at run time by
-- expanding checking code (see Detect_Infinite_Recursion in
-- package Exp_Ch6).
+
-- If the recursive call is within a handler we do not emit a
-- warning, because this is a common idiom: loop until input
-- is correct, catch illegal input in handler and restart.
@@ -4486,7 +4487,7 @@ package body Sem_Res is
-- call at all violates a specified nesting depth of zero.
if Is_Protected_Type (Scope (Nam)) then
- Check_Restriction (Max_Entry_Queue_Depth, N);
+ Check_Restriction (Max_Entry_Queue_Length, N);
end if;
-- Use context type to disambiguate a protected function that can be
@@ -6866,6 +6867,12 @@ package body Sem_Res is
elsif Is_Numeric_Type (Target_Type) then
if Opnd_Type = Universal_Fixed then
return True;
+
+ elsif (In_Instance or else In_Inlined_Body)
+ and then not Comes_From_Source (N)
+ then
+ return True;
+
else
return Conversion_Check (Is_Numeric_Type (Opnd_Type),
"illegal operand for numeric conversion");
@@ -7069,7 +7076,9 @@ package body Sem_Res is
end if;
end;
- elsif Ekind (Target_Type) = E_Access_Subprogram_Type
+ elsif (Ekind (Target_Type) = E_Access_Subprogram_Type
+ or else
+ Ekind (Target_Type) = E_Anonymous_Access_Subprogram_Type)
and then Conversion_Check
(Ekind (Base_Type (Opnd_Type)) = E_Access_Subprogram_Type,
"illegal operand for access subprogram conversion")
diff --git a/gcc/ada/sem_type.adb b/gcc/ada/sem_type.adb
index 0ac96860a28..5da129f9294 100644
--- a/gcc/ada/sem_type.adb
+++ b/gcc/ada/sem_type.adb
@@ -731,6 +731,27 @@ package body Sem_Type is
then
return True;
+ -- Ada 0Y (AI-254): An Anonymous_Access_To_Subprogram is compatible with
+ -- itself, or with an anonymous type created for an attribute
+ -- reference Access.
+
+ elsif (Ekind (Base_Type (T1)) = E_Anonymous_Access_Subprogram_Type
+ or else
+ Ekind (Base_Type (T1))
+ = E_Anonymous_Access_Protected_Subprogram_Type)
+ and then Is_Access_Type (T2)
+ and then (not Comes_From_Source (T1)
+ or else not Comes_From_Source (T2))
+ and then (Is_Overloadable (Designated_Type (T2))
+ or else
+ Ekind (Designated_Type (T2)) = E_Subprogram_Type)
+ and then
+ Type_Conformant (Designated_Type (T1), Designated_Type (T2))
+ and then
+ Mode_Conformant (Designated_Type (T1), Designated_Type (T2))
+ then
+ return True;
+
-- The context can be a remote access type, and the expression the
-- corresponding source type declared in a categorized package, or
-- viceversa.
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index a3adc6ed3cb..9eb9af0b388 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -42,6 +42,7 @@ with Nmake; use Nmake;
with Output; use Output;
with Opt; use Opt;
with Restrict; use Restrict;
+with Rtsfind; use Rtsfind;
with Scans; use Scans;
with Scn; use Scn;
with Sem; use Sem;
@@ -135,9 +136,10 @@ package body Sem_Util is
Rtyp := Typ;
end if;
- if No (Compile_Time_Constraint_Error (N, Msg, Ent, Loc, Warn => Warn))
- or else not Rep
- then
+ Discard_Node (
+ Compile_Time_Constraint_Error (N, Msg, Ent, Loc, Warn => Warn));
+
+ if not Rep then
return;
end if;
@@ -2674,6 +2676,24 @@ package body Sem_Util is
return Task_Body_Procedure (Declaration_Node (Root_Type (E)));
end Get_Task_Body_Procedure;
+ ----------------------
+ -- Has_Declarations --
+ ----------------------
+
+ function Has_Declarations (N : Node_Id) return Boolean is
+ K : constant Node_Kind := Nkind (N);
+ begin
+ return K = N_Accept_Statement
+ or else K = N_Block_Statement
+ or else K = N_Compilation_Unit_Aux
+ or else K = N_Entry_Body
+ or else K = N_Package_Body
+ or else K = N_Protected_Body
+ or else K = N_Subprogram_Body
+ or else K = N_Task_Body
+ or else K = N_Package_Specification;
+ end Has_Declarations;
+
--------------------
-- Has_Infinities --
--------------------
@@ -3132,6 +3152,31 @@ package body Sem_Util is
end if;
end Is_Aliased_View;
+ -------------------------
+ -- Is_Ancestor_Package --
+ -------------------------
+
+ function Is_Ancestor_Package
+ (E1 : Entity_Id;
+ E2 : Entity_Id) return Boolean
+ is
+ Par : Entity_Id;
+
+ begin
+ Par := E2;
+ while Present (Par)
+ and then Par /= Standard_Standard
+ loop
+ if Par = E1 then
+ return True;
+ end if;
+
+ Par := Scope (Par);
+ end loop;
+
+ return False;
+ end Is_Ancestor_Package;
+
----------------------
-- Is_Atomic_Object --
----------------------
@@ -3290,9 +3335,21 @@ package body Sem_Util is
P_Aliased := True;
end if;
+ -- A discriminant check on a selected component may be
+ -- expanded into a dereference when removing side-effects.
+ -- Recover the original node and its type, which may be
+ -- unconstrained.
+
+ elsif Nkind (P) = N_Explicit_Dereference
+ and then not (Comes_From_Source (P))
+ then
+ P := Original_Node (P);
+ Prefix_Type := Etype (P);
+
else
-- Check for prefix being an aliased component ???
null;
+
end if;
if Is_Access_Type (Prefix_Type)
@@ -3362,6 +3419,88 @@ package body Sem_Util is
and then Prefix (P) = N;
end Is_Dereferenced;
+ ----------------------
+ -- Is_Descendent_Of --
+ ----------------------
+
+ function Is_Descendent_Of (T1 : Entity_Id; T2 : Entity_Id) return Boolean is
+ T : Entity_Id;
+ Etyp : Entity_Id;
+
+ begin
+ pragma Assert (Nkind (T1) in N_Entity);
+ pragma Assert (Nkind (T2) in N_Entity);
+
+ T := Base_Type (T1);
+
+ -- Immediate return if the types match
+
+ if T = T2 then
+ return True;
+
+ -- Comment needed here ???
+
+ elsif Ekind (T) = E_Class_Wide_Type then
+ return Etype (T) = T2;
+
+ -- All other cases
+
+ else
+ loop
+ Etyp := Etype (T);
+
+ -- Done if we found the type we are looking for
+
+ if Etyp = T2 then
+ return True;
+
+ -- Done if no more derivations to check
+
+ elsif T = T1 then
+ return False;
+
+ -- Following test catches error cases resulting from prev errors
+
+ elsif No (Etyp) then
+ return False;
+
+ elsif Is_Private_Type (T) and then Etyp = Full_View (T) then
+ return False;
+
+ elsif Is_Private_Type (Etyp) and then Full_View (Etyp) = T then
+ return False;
+ end if;
+
+ -- Return if no further entries to check
+
+ if T = Base_Type (T1) or else T = T1 then
+ return False;
+ end if;
+ end loop;
+ end if;
+
+ raise Program_Error;
+ end Is_Descendent_Of;
+
+ ------------------------------
+ -- Is_Descendent_Of_Address --
+ ------------------------------
+
+ function Is_Descendent_Of_Address (T1 : Entity_Id) return Boolean is
+ begin
+ -- If Address has not been loaded, answer must be False
+
+ if not RTU_Loaded (System) then
+ return False;
+
+ -- Otherwise we can get the entity we are interested in without
+ -- causing an unwanted dependency on System, and do the test.
+
+ else
+ return Is_Descendent_Of (T1, Base_Type (RTE (RE_Address)));
+ end if;
+ end Is_Descendent_Of_Address;
+
--------------
-- Is_False --
--------------
@@ -5487,11 +5626,8 @@ package body Sem_Util is
function Rep_To_Pos_Flag (E : Entity_Id; Loc : Source_Ptr) return Node_Id is
begin
- if Range_Checks_Suppressed (E) then
- return New_Occurrence_Of (Standard_False, Loc);
- else
- return New_Occurrence_Of (Standard_True, Loc);
- end if;
+ return New_Occurrence_Of
+ (Boolean_Literals (not Range_Checks_Suppressed (E)), Loc);
end Rep_To_Pos_Flag;
--------------------
@@ -6083,9 +6219,16 @@ package body Sem_Util is
-- declared at the library level to ensure that names such as
-- X.all'access don't fail static accessibility checks.
+ -- Ada 0Y (AI-230): In case of anonymous access types that are
+ -- component_definition or discriminants of a nonlimited type,
+ -- the level is the same as that of the enclosing component type.
+
Btyp := Base_Type (Typ);
if Ekind (Btyp) in Access_Kind then
- if Ekind (Btyp) = E_Anonymous_Access_Type then
+ if Ekind (Btyp) = E_Anonymous_Access_Type
+ and then not Is_Array_Type (Scope (Btyp)) -- Ada 0Y (AI-230)
+ and then Ekind (Scope (Btyp)) /= E_Record_Type -- Ada 0Y (AI-230)
+ then
return Scope_Depth (Standard_Standard);
end if;
diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads
index 9b8c4c1aabc..a32ddc09239 100644
--- a/gcc/ada/sem_util.ads
+++ b/gcc/ada/sem_util.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2003, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004, 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- --
@@ -259,28 +259,28 @@ package Sem_Util is
Governed_By : List_Id;
Into : Elist_Id;
Report_Errors : out Boolean);
- -- The purpose of this procedure is to gather the valid components
- -- in a record type according to the values of its discriminants, in order
- -- to validate the components of a record aggregate.
+ -- The purpose of this procedure is to gather the valid components in a
+ -- record type according to the values of its discriminants, in order to
+ -- validate the components of a record aggregate.
--
-- Typ is the type of the aggregate when its constrained discriminants
-- need to be collected, otherwise it is Empty.
--
-- Comp_List is an N_Component_List node.
--
- -- Governed_By is a list of N_Component_Association nodes,
- -- where each choice list contains the name of a discriminant and
- -- the expression field gives its value. The values of the
- -- discriminants governing the (possibly nested) variant parts in
- -- Comp_List are found in this Component_Association List.
+ -- Governed_By is a list of N_Component_Association nodes, where each
+ -- choice list contains the name of a discriminant and the expression
+ -- field gives its value. The values of the discriminants governing
+ -- the (possibly nested) variant parts in Comp_List are found in this
+ -- Component_Association List.
--
- -- Into is the list where the valid components are appended.
- -- Note that Into need not be an Empty list. If it's not, components
- -- are attached to its tail.
+ -- Into is the list where the valid components are appended. Note that
+ -- Into need not be an Empty list. If it's not, components are attached
+ -- to its tail.
+ --
+ -- Report_Errors is set to True if the values of the discriminants are
+ -- non-static.
--
- -- Report_Errors is set to True if the values of the discriminants
- -- are non-static.
-
-- This procedure is also used when building a record subtype. If the
-- discriminant constraint of the subtype is static, the components of the
-- subtype are only those of the variants selected by the values of the
@@ -357,6 +357,9 @@ package Sem_Util is
-- Task_Body_Procedure field from the corresponding task type
-- declaration.
+ function Has_Declarations (N : Node_Id) return Boolean;
+ -- Determines if the node can have declarations
+
function Has_Infinities (E : Entity_Id) return Boolean;
-- Determines if the range of the floating-point type E includes
-- infinities. Returns False if E is not a floating-point type.
@@ -421,6 +424,11 @@ package Sem_Util is
-- Determine if Obj is an aliased view, i.e. the name of an
-- object to which 'Access or 'Unchecked_Access can apply.
+ function Is_Ancestor_Package
+ (E1 : Entity_Id;
+ E2 : Entity_Id) return Boolean;
+ -- Determine whether package E1 is an ancestor of E2
+
function Is_Atomic_Object (N : Node_Id) return Boolean;
-- Determines if the given node denotes an atomic object in the sense
-- of the legality checks described in RM C.6(12).
@@ -439,6 +447,16 @@ package Sem_Util is
-- 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.
+ -- This is the RM definition, a type is a descendent of another type if it
+ -- is the same type or is derived from a descendent of the other type.
+
+ function Is_Descendent_Of_Address (T1 : Entity_Id) return Boolean;
+ -- Returns True if type T1 is a descendent of Address or its base type.
+ -- Similar to calling Is_Descendent_Of with Base_Type (RTE (RE_Address))
+ -- except that it avoids creating an unconditional dependency on System.
+
function Is_False (U : Uint) return Boolean;
-- The argument is a Uint value which is the Boolean'Pos value of a
-- Boolean operand (i.e. is either 0 for False, or 1 for True). This
@@ -468,8 +486,8 @@ package Sem_Util is
-- an lvalue, but it can answer True when N is not an lvalue. An lvalue is
-- defined as any expression which appears in a context where a name is
-- required by the syntax, and the identity, rather than merely the value
- -- of the node is needed (for example, the prefix of an attribute is in
- -- this category).
+ -- of the node is needed (for example, the prefix of an Access attribute
+ -- is in this category).
function Is_Library_Level_Entity (E : Entity_Id) return Boolean;
-- A library-level declaration is one that is accessible from Standard,
diff --git a/gcc/ada/sem_warn.adb b/gcc/ada/sem_warn.adb
index 187fc9bf389..970213e7905 100644
--- a/gcc/ada/sem_warn.adb
+++ b/gcc/ada/sem_warn.adb
@@ -384,8 +384,7 @@ package body Sem_Warn is
then
null;
- elsif Warn_On_No_Value_Assigned
- and then Present (UR)
+ elsif Present (UR)
and then Is_Access_Type (Etype (E1))
then
diff --git a/gcc/ada/sinfo.adb b/gcc/ada/sinfo.adb
index e19321adeb1..65ee94ef2c0 100644
--- a/gcc/ada/sinfo.adb
+++ b/gcc/ada/sinfo.adb
@@ -126,6 +126,14 @@ package body Sinfo is
return Node3 (N);
end Access_Definition;
+ function Access_To_Subprogram_Definition
+ (N : Node_Id) return Node_Id is
+ begin
+ pragma Assert (False
+ or else NT (N).Nkind = N_Access_Definition);
+ return Node3 (N);
+ end Access_To_Subprogram_Definition;
+
function Access_Types_To_Process
(N : Node_Id) return Elist_Id is
begin
@@ -2612,6 +2620,14 @@ package body Sinfo is
Set_Node3_With_Parent (N, Val);
end Set_Access_Definition;
+ procedure Set_Access_To_Subprogram_Definition
+ (N : Node_Id; Val : Node_Id) is
+ begin
+ pragma Assert (False
+ or else NT (N).Nkind = N_Access_Definition);
+ Set_Node3_With_Parent (N, Val);
+ end Set_Access_To_Subprogram_Definition;
+
procedure Set_Access_Types_To_Process
(N : Node_Id; Val : Elist_Id) is
begin
diff --git a/gcc/ada/sinfo.ads b/gcc/ada/sinfo.ads
index c86ac9d8322..63a6e0c243e 100644
--- a/gcc/ada/sinfo.ads
+++ b/gcc/ada/sinfo.ads
@@ -2705,6 +2705,9 @@ package Sinfo is
-- ACCESS_DEFINITION ::=
-- [NULL_EXCLUSION] access [GENERAL_ACCESS_MODIFIER] SUBTYPE_MARK
+ -- | ACCESS_TO_SUBPROGRAM_DEFINITION
+
+ -- Note: access to subprograms are an Ada 0Y (AI-254) extension
-- N_Access_Definition
-- Sloc points to ACCESS
@@ -2712,6 +2715,7 @@ package Sinfo is
-- All_Present (Flag15)
-- Constant_Present (Flag17)
-- Subtype_Mark (Node4)
+ -- Access_To_Subprogram_Definition (Node3) (set to Empty if not present)
-----------------------------------------
-- 3.10.1 Incomplete Type Declaration --
@@ -4242,7 +4246,7 @@ package Sinfo is
-- PRIVATE_TYPE_DECLARATION ::=
-- type DEFINING_IDENTIFIER [DISCRIMINANT_PART]
- -- is [abstract] tagged] [limited] private;
+ -- is [[abstract] tagged] [limited] private;
-- Note: TAGGED is not permitted in Ada 83 mode
@@ -6929,6 +6933,9 @@ package Sinfo is
function Access_Definition
(N : Node_Id) return Node_Id; -- Node3
+ function Access_To_Subprogram_Definition
+ (N : Node_Id) return Node_Id; -- Node3
+
function Access_Types_To_Process
(N : Node_Id) return Elist_Id; -- Elist2
@@ -7721,6 +7728,9 @@ package Sinfo is
procedure Set_Access_Definition
(N : Node_Id; Val : Node_Id); -- Node3
+ procedure Set_Access_To_Subprogram_Definition
+ (N : Node_Id; Val : Node_Id); -- Node3
+
procedure Set_Access_Types_To_Process
(N : Node_Id; Val : Elist_Id); -- Elist2
@@ -8514,6 +8524,7 @@ package Sinfo is
pragma Inline (Accept_Handler_Records);
pragma Inline (Accept_Statement);
pragma Inline (Access_Definition);
+ pragma Inline (Access_To_Subprogram_Definition);
pragma Inline (Access_Types_To_Process);
pragma Inline (Actions);
pragma Inline (Activation_Chain_Entity);
@@ -8775,6 +8786,7 @@ package Sinfo is
pragma Inline (Set_Accept_Handler_Records);
pragma Inline (Set_Accept_Statement);
pragma Inline (Set_Access_Definition);
+ pragma Inline (Set_Access_To_Subprogram_Definition);
pragma Inline (Set_Access_Types_To_Process);
pragma Inline (Set_Actions);
pragma Inline (Set_Activation_Chain_Entity);
diff --git a/gcc/ada/snames.adb b/gcc/ada/snames.adb
index 70b9608a538..d764320be36 100644
--- a/gcc/ada/snames.adb
+++ b/gcc/ada/snames.adb
@@ -92,6 +92,9 @@ package body Snames is
"finalize#" &
"next#" &
"prev#" &
+ "_typecode#" &
+ "_from_any#" &
+ "_to_any#" &
"allocate#" &
"deallocate#" &
"dereference#" &
@@ -116,20 +119,32 @@ package body Snames is
"system#" &
"text_io#" &
"wide_text_io#" &
+ "no_dsa#" &
+ "glade_dsa#" &
+ "polyorb_dsa#" &
"addr#" &
"async#" &
"get_active_partition_id#" &
"get_rci_package_receiver#" &
+ "get_rci_package_ref#" &
"origin#" &
"params#" &
"partition#" &
"partition_interface#" &
"ras#" &
+ "call#" &
"rci_name#" &
"receiver#" &
"result#" &
"rpc#" &
"subp_id#" &
+ "operation#" &
+ "argument#" &
+ "arg_modes#" &
+ "handler#" &
+ "target#" &
+ "req#" &
+ "obj_typecode#" &
"Oabs#" &
"Oand#" &
"Omod#" &
@@ -304,6 +319,7 @@ package body Snames is
"win32#" &
"as_is#" &
"body_file_name#" &
+ "boolean_entry_barriers#" &
"casing#" &
"code#" &
"component#" &
@@ -322,10 +338,10 @@ package body Snames is
"gnat#" &
"gpl#" &
"ieee_float#" &
- "homonym_number#" &
"internal#" &
"link_name#" &
"lowercase#" &
+ "max_entry_queue_depth#" &
"max_size#" &
"mechanism#" &
"mixedcase#" &
@@ -336,6 +352,7 @@ package body Snames is
"on#" &
"parameter_types#" &
"reference#" &
+ "no_dynamic_interrupts#" &
"no_requeue#" &
"no_task_attributes#" &
"restricted#" &
diff --git a/gcc/ada/snames.ads b/gcc/ada/snames.ads
index 2985ddbfd22..402a791ef63 100644
--- a/gcc/ada/snames.ads
+++ b/gcc/ada/snames.ads
@@ -183,92 +183,113 @@ package Snames is
Name_Next : constant Name_Id := N + 033;
Name_Prev : constant Name_Id := N + 034;
+ -- Names of TSS routines for implementation of DSA over PolyORB
+
+ Name_uTypeCode : constant Name_Id := N + 035;
+ Name_uFrom_Any : constant Name_Id := N + 036;
+ Name_uTo_Any : constant Name_Id := N + 037;
+
-- Names of allocation routines, also needed by expander
- Name_Allocate : constant Name_Id := N + 035;
- Name_Deallocate : constant Name_Id := N + 036;
- Name_Dereference : constant Name_Id := N + 037;
+ Name_Allocate : constant Name_Id := N + 038;
+ Name_Deallocate : constant Name_Id := N + 039;
+ Name_Dereference : constant Name_Id := N + 040;
-- Names of Text_IO generic subpackages (see Rtsfind.Text_IO_Kludge)
- First_Text_IO_Package : constant Name_Id := N + 038;
- Name_Decimal_IO : constant Name_Id := N + 038;
- Name_Enumeration_IO : constant Name_Id := N + 039;
- Name_Fixed_IO : constant Name_Id := N + 040;
- Name_Float_IO : constant Name_Id := N + 041;
- Name_Integer_IO : constant Name_Id := N + 042;
- Name_Modular_IO : constant Name_Id := N + 043;
- Last_Text_IO_Package : constant Name_Id := N + 043;
+ First_Text_IO_Package : constant Name_Id := N + 041;
+ Name_Decimal_IO : constant Name_Id := N + 041;
+ Name_Enumeration_IO : constant Name_Id := N + 042;
+ Name_Fixed_IO : constant Name_Id := N + 043;
+ Name_Float_IO : constant Name_Id := N + 044;
+ Name_Integer_IO : constant Name_Id := N + 045;
+ Name_Modular_IO : constant Name_Id := N + 046;
+ Last_Text_IO_Package : constant Name_Id := N + 046;
subtype Text_IO_Package_Name is Name_Id
range First_Text_IO_Package .. Last_Text_IO_Package;
-- Names of files in library for Ada.Text_IO and Ada.Wide_Text_IO
- Name_a_textio : constant Name_Id := N + 044;
- Name_a_witeio : constant Name_Id := N + 045;
+ Name_a_textio : constant Name_Id := N + 047;
+ Name_a_witeio : constant Name_Id := N + 048;
-- Some miscellaneous names used for error detection/recovery
- Name_Const : constant Name_Id := N + 046;
- Name_Error : constant Name_Id := N + 047;
- Name_Go : constant Name_Id := N + 048;
- Name_Put : constant Name_Id := N + 049;
- Name_Put_Line : constant Name_Id := N + 050;
- Name_To : constant Name_Id := N + 051;
+ Name_Const : constant Name_Id := N + 049;
+ Name_Error : constant Name_Id := N + 050;
+ Name_Go : constant Name_Id := N + 051;
+ Name_Put : constant Name_Id := N + 052;
+ Name_Put_Line : constant Name_Id := N + 053;
+ Name_To : constant Name_Id := N + 054;
-- Names for packages that are treated specially by the compiler
- Name_Finalization : constant Name_Id := N + 052;
- Name_Finalization_Root : constant Name_Id := N + 053;
- Name_Interfaces : constant Name_Id := N + 054;
- Name_Standard : constant Name_Id := N + 055;
- Name_System : constant Name_Id := N + 056;
- Name_Text_IO : constant Name_Id := N + 057;
- Name_Wide_Text_IO : constant Name_Id := N + 058;
+ Name_Finalization : constant Name_Id := N + 055;
+ Name_Finalization_Root : constant Name_Id := N + 056;
+ Name_Interfaces : constant Name_Id := N + 057;
+ Name_Standard : constant Name_Id := N + 058;
+ Name_System : constant Name_Id := N + 059;
+ Name_Text_IO : constant Name_Id := N + 060;
+ Name_Wide_Text_IO : constant Name_Id := N + 061;
+
+ -- Names of implementations of the distributed systems annex
+
+ Name_No_DSA : constant Name_Id := N + 062;
+ Name_GLADE_DSA : constant Name_Id := N + 063;
+ Name_PolyORB_DSA : constant Name_Id := N + 064;
-- Names of identifiers used in expanding distribution stubs
- Name_Addr : constant Name_Id := N + 059;
- Name_Async : constant Name_Id := N + 060;
- Name_Get_Active_Partition_ID : constant Name_Id := N + 061;
- Name_Get_RCI_Package_Receiver : constant Name_Id := N + 062;
- Name_Origin : constant Name_Id := N + 063;
- Name_Params : constant Name_Id := N + 064;
- Name_Partition : constant Name_Id := N + 065;
- Name_Partition_Interface : constant Name_Id := N + 066;
- Name_Ras : constant Name_Id := N + 067;
- Name_RCI_Name : constant Name_Id := N + 068;
- Name_Receiver : constant Name_Id := N + 069;
- Name_Result : constant Name_Id := N + 070;
- Name_Rpc : constant Name_Id := N + 071;
- Name_Subp_Id : constant Name_Id := N + 072;
+ Name_Addr : constant Name_Id := N + 065;
+ Name_Async : constant Name_Id := N + 066;
+ Name_Get_Active_Partition_ID : constant Name_Id := N + 067;
+ Name_Get_RCI_Package_Receiver : constant Name_Id := N + 068;
+ Name_Get_RCI_Package_Ref : constant Name_Id := N + 069;
+ Name_Origin : constant Name_Id := N + 070;
+ Name_Params : constant Name_Id := N + 071;
+ Name_Partition : constant Name_Id := N + 072;
+ Name_Partition_Interface : constant Name_Id := N + 073;
+ Name_Ras : constant Name_Id := N + 074;
+ Name_Call : constant Name_Id := N + 075;
+ Name_RCI_Name : constant Name_Id := N + 076;
+ Name_Receiver : constant Name_Id := N + 077;
+ Name_Result : constant Name_Id := N + 078;
+ Name_Rpc : constant Name_Id := N + 079;
+ Name_Subp_Id : constant Name_Id := N + 080;
+ Name_Operation : constant Name_Id := N + 081;
+ Name_Argument : constant Name_Id := N + 082;
+ Name_Arg_Modes : constant Name_Id := N + 083;
+ Name_Handler : constant Name_Id := N + 084;
+ Name_Target : constant Name_Id := N + 085;
+ Name_Req : constant Name_Id := N + 086;
+ Name_Obj_TypeCode : constant Name_Id := N + 087;
-- Operator Symbol entries. The actual names have an upper case O at
-- the start in place of the Op_ prefix (e.g. the actual name that
-- corresponds to Name_Op_Abs is "Oabs".
- First_Operator_Name : constant Name_Id := N + 073;
- Name_Op_Abs : constant Name_Id := N + 073; -- "abs"
- Name_Op_And : constant Name_Id := N + 074; -- "and"
- Name_Op_Mod : constant Name_Id := N + 075; -- "mod"
- Name_Op_Not : constant Name_Id := N + 076; -- "not"
- Name_Op_Or : constant Name_Id := N + 077; -- "or"
- Name_Op_Rem : constant Name_Id := N + 078; -- "rem"
- Name_Op_Xor : constant Name_Id := N + 079; -- "xor"
- Name_Op_Eq : constant Name_Id := N + 080; -- "="
- Name_Op_Ne : constant Name_Id := N + 081; -- "/="
- Name_Op_Lt : constant Name_Id := N + 082; -- "<"
- Name_Op_Le : constant Name_Id := N + 083; -- "<="
- Name_Op_Gt : constant Name_Id := N + 084; -- ">"
- Name_Op_Ge : constant Name_Id := N + 085; -- ">="
- Name_Op_Add : constant Name_Id := N + 086; -- "+"
- Name_Op_Subtract : constant Name_Id := N + 087; -- "-"
- Name_Op_Concat : constant Name_Id := N + 088; -- "&"
- Name_Op_Multiply : constant Name_Id := N + 089; -- "*"
- Name_Op_Divide : constant Name_Id := N + 090; -- "/"
- Name_Op_Expon : constant Name_Id := N + 091; -- "**"
- Last_Operator_Name : constant Name_Id := N + 091;
+ First_Operator_Name : constant Name_Id := N + 088;
+ Name_Op_Abs : constant Name_Id := N + 088; -- "abs"
+ Name_Op_And : constant Name_Id := N + 089; -- "and"
+ Name_Op_Mod : constant Name_Id := N + 090; -- "mod"
+ Name_Op_Not : constant Name_Id := N + 091; -- "not"
+ Name_Op_Or : constant Name_Id := N + 092; -- "or"
+ Name_Op_Rem : constant Name_Id := N + 093; -- "rem"
+ Name_Op_Xor : constant Name_Id := N + 094; -- "xor"
+ Name_Op_Eq : constant Name_Id := N + 095; -- "="
+ Name_Op_Ne : constant Name_Id := N + 096; -- "/="
+ Name_Op_Lt : constant Name_Id := N + 097; -- "<"
+ Name_Op_Le : constant Name_Id := N + 098; -- "<="
+ Name_Op_Gt : constant Name_Id := N + 099; -- ">"
+ Name_Op_Ge : constant Name_Id := N + 100; -- ">="
+ Name_Op_Add : constant Name_Id := N + 101; -- "+"
+ Name_Op_Subtract : constant Name_Id := N + 102; -- "-"
+ Name_Op_Concat : constant Name_Id := N + 103; -- "&"
+ Name_Op_Multiply : constant Name_Id := N + 104; -- "*"
+ Name_Op_Divide : constant Name_Id := N + 105; -- "/"
+ Name_Op_Expon : constant Name_Id := N + 106; -- "**"
+ Last_Operator_Name : constant Name_Id := N + 106;
-- Names for all pragmas recognized by GNAT. The entries with the comment
-- "Ada 83" are pragmas that are defined in Ada 83, but not in Ada 95.
@@ -291,61 +312,61 @@ package Snames is
-- only in GNAT for the AAMP. They are ignored in other versions with
-- appropriate warnings.
- First_Pragma_Name : constant Name_Id := N + 092;
+ First_Pragma_Name : constant Name_Id := N + 107;
-- Configuration pragmas are grouped at start
- Name_Ada_83 : constant Name_Id := N + 092; -- GNAT
- Name_Ada_95 : constant Name_Id := N + 093; -- GNAT
- Name_C_Pass_By_Copy : constant Name_Id := N + 094; -- GNAT
- Name_Compile_Time_Warning : constant Name_Id := N + 095; -- GNAT
- Name_Component_Alignment : constant Name_Id := N + 096; -- GNAT
- Name_Convention_Identifier : constant Name_Id := N + 097; -- GNAT
- Name_Discard_Names : constant Name_Id := N + 098;
- Name_Elaboration_Checks : constant Name_Id := N + 099; -- GNAT
- Name_Eliminate : constant Name_Id := N + 100; -- GNAT
- Name_Explicit_Overriding : constant Name_Id := N + 101;
- Name_Extend_System : constant Name_Id := N + 102; -- GNAT
- Name_Extensions_Allowed : constant Name_Id := N + 103; -- GNAT
- Name_External_Name_Casing : constant Name_Id := N + 104; -- GNAT
- Name_Float_Representation : constant Name_Id := N + 105; -- GNAT
- Name_Initialize_Scalars : constant Name_Id := N + 106; -- GNAT
- Name_Interrupt_State : constant Name_Id := N + 107; -- GNAT
- Name_License : constant Name_Id := N + 108; -- GNAT
- Name_Locking_Policy : constant Name_Id := N + 109;
- Name_Long_Float : constant Name_Id := N + 110; -- VMS
- Name_No_Run_Time : constant Name_Id := N + 111; -- GNAT
- Name_No_Strict_Aliasing : constant Name_Id := N + 112; -- GNAT
- Name_Normalize_Scalars : constant Name_Id := N + 113;
- Name_Polling : constant Name_Id := N + 114; -- GNAT
- Name_Persistent_Data : constant Name_Id := N + 115; -- GNAT
- Name_Persistent_Object : constant Name_Id := N + 116; -- GNAT
- Name_Profile : constant Name_Id := N + 117; -- Ada0Y
- Name_Propagate_Exceptions : constant Name_Id := N + 118; -- GNAT
- Name_Queuing_Policy : constant Name_Id := N + 119;
- Name_Ravenscar : constant Name_Id := N + 120;
- Name_Restricted_Run_Time : constant Name_Id := N + 121;
- Name_Restrictions : constant Name_Id := N + 122;
- Name_Restriction_Warnings : constant Name_Id := N + 123; -- GNAT
- Name_Reviewable : constant Name_Id := N + 124;
- Name_Source_File_Name : constant Name_Id := N + 125; -- GNAT
- Name_Source_File_Name_Project : constant Name_Id := N + 126; -- GNAT
- Name_Style_Checks : constant Name_Id := N + 127; -- GNAT
- Name_Suppress : constant Name_Id := N + 128;
- Name_Suppress_Exception_Locations : constant Name_Id := N + 129; -- GNAT
- Name_Task_Dispatching_Policy : constant Name_Id := N + 130;
- Name_Universal_Data : constant Name_Id := N + 131; -- AAMP
- Name_Unsuppress : constant Name_Id := N + 132; -- GNAT
- Name_Use_VADS_Size : constant Name_Id := N + 133; -- GNAT
- Name_Validity_Checks : constant Name_Id := N + 134; -- GNAT
- Name_Warnings : constant Name_Id := N + 135; -- GNAT
- Last_Configuration_Pragma_Name : constant Name_Id := N + 135;
+ Name_Ada_83 : constant Name_Id := N + 107; -- GNAT
+ Name_Ada_95 : constant Name_Id := N + 108; -- GNAT
+ Name_C_Pass_By_Copy : constant Name_Id := N + 109; -- GNAT
+ Name_Compile_Time_Warning : constant Name_Id := N + 110; -- GNAT
+ Name_Component_Alignment : constant Name_Id := N + 111; -- GNAT
+ Name_Convention_Identifier : constant Name_Id := N + 112; -- GNAT
+ Name_Discard_Names : constant Name_Id := N + 113;
+ Name_Elaboration_Checks : constant Name_Id := N + 114; -- GNAT
+ Name_Eliminate : constant Name_Id := N + 115; -- GNAT
+ Name_Explicit_Overriding : constant Name_Id := N + 116;
+ Name_Extend_System : constant Name_Id := N + 117; -- GNAT
+ Name_Extensions_Allowed : constant Name_Id := N + 118; -- GNAT
+ Name_External_Name_Casing : constant Name_Id := N + 119; -- GNAT
+ Name_Float_Representation : constant Name_Id := N + 120; -- GNAT
+ Name_Initialize_Scalars : constant Name_Id := N + 121; -- GNAT
+ Name_Interrupt_State : constant Name_Id := N + 122; -- GNAT
+ Name_License : constant Name_Id := N + 123; -- GNAT
+ Name_Locking_Policy : constant Name_Id := N + 124;
+ Name_Long_Float : constant Name_Id := N + 125; -- VMS
+ Name_No_Run_Time : constant Name_Id := N + 126; -- GNAT
+ Name_No_Strict_Aliasing : constant Name_Id := N + 127; -- GNAT
+ Name_Normalize_Scalars : constant Name_Id := N + 128;
+ Name_Polling : constant Name_Id := N + 129; -- GNAT
+ Name_Persistent_Data : constant Name_Id := N + 130; -- GNAT
+ Name_Persistent_Object : constant Name_Id := N + 131; -- GNAT
+ Name_Profile : constant Name_Id := N + 132; -- Ada0Y
+ Name_Propagate_Exceptions : constant Name_Id := N + 133; -- GNAT
+ Name_Queuing_Policy : constant Name_Id := N + 134;
+ Name_Ravenscar : constant Name_Id := N + 135;
+ Name_Restricted_Run_Time : constant Name_Id := N + 136;
+ Name_Restrictions : constant Name_Id := N + 137;
+ Name_Restriction_Warnings : constant Name_Id := N + 138; -- GNAT
+ Name_Reviewable : constant Name_Id := N + 139;
+ Name_Source_File_Name : constant Name_Id := N + 140; -- GNAT
+ Name_Source_File_Name_Project : constant Name_Id := N + 141; -- GNAT
+ Name_Style_Checks : constant Name_Id := N + 142; -- GNAT
+ Name_Suppress : constant Name_Id := N + 143;
+ Name_Suppress_Exception_Locations : constant Name_Id := N + 144; -- GNAT
+ Name_Task_Dispatching_Policy : constant Name_Id := N + 145;
+ Name_Universal_Data : constant Name_Id := N + 146; -- AAMP
+ Name_Unsuppress : constant Name_Id := N + 147; -- GNAT
+ Name_Use_VADS_Size : constant Name_Id := N + 148; -- GNAT
+ Name_Validity_Checks : constant Name_Id := N + 149; -- GNAT
+ Name_Warnings : constant Name_Id := N + 150; -- GNAT
+ Last_Configuration_Pragma_Name : constant Name_Id := N + 150;
-- Remaining pragma names
- Name_Abort_Defer : constant Name_Id := N + 136; -- GNAT
- Name_All_Calls_Remote : constant Name_Id := N + 137;
- Name_Annotate : constant Name_Id := N + 138; -- GNAT
+ Name_Abort_Defer : constant Name_Id := N + 151; -- GNAT
+ Name_All_Calls_Remote : constant Name_Id := N + 152;
+ Name_Annotate : constant Name_Id := N + 153; -- GNAT
-- Note: AST_Entry is not in this list because its name matches the
-- name of the corresponding attribute. However, it is included in the
@@ -353,78 +374,78 @@ package Snames is
-- and Check_Pragma_Id correctly recognize and process Name_AST_Entry.
-- AST_Entry is a VMS specific pragma.
- Name_Assert : constant Name_Id := N + 139; -- GNAT
- Name_Asynchronous : constant Name_Id := N + 140;
- Name_Atomic : constant Name_Id := N + 141;
- Name_Atomic_Components : constant Name_Id := N + 142;
- Name_Attach_Handler : constant Name_Id := N + 143;
- Name_Comment : constant Name_Id := N + 144; -- GNAT
- Name_Common_Object : constant Name_Id := N + 145; -- GNAT
- Name_Complex_Representation : constant Name_Id := N + 146; -- GNAT
- Name_Controlled : constant Name_Id := N + 147;
- Name_Convention : constant Name_Id := N + 148;
- Name_CPP_Class : constant Name_Id := N + 149; -- GNAT
- Name_CPP_Constructor : constant Name_Id := N + 150; -- GNAT
- Name_CPP_Virtual : constant Name_Id := N + 151; -- GNAT
- Name_CPP_Vtable : constant Name_Id := N + 152; -- GNAT
- Name_Debug : constant Name_Id := N + 153; -- GNAT
- Name_Elaborate : constant Name_Id := N + 154; -- Ada 83
- Name_Elaborate_All : constant Name_Id := N + 155;
- Name_Elaborate_Body : constant Name_Id := N + 156;
- Name_Export : constant Name_Id := N + 157;
- Name_Export_Exception : constant Name_Id := N + 158; -- VMS
- Name_Export_Function : constant Name_Id := N + 159; -- GNAT
- Name_Export_Object : constant Name_Id := N + 160; -- GNAT
- Name_Export_Procedure : constant Name_Id := N + 161; -- GNAT
- Name_Export_Value : constant Name_Id := N + 162; -- GNAT
- Name_Export_Valued_Procedure : constant Name_Id := N + 163; -- GNAT
- Name_External : constant Name_Id := N + 164; -- GNAT
- Name_Finalize_Storage_Only : constant Name_Id := N + 165; -- GNAT
- Name_Ident : constant Name_Id := N + 166; -- VMS
- Name_Import : constant Name_Id := N + 167;
- Name_Import_Exception : constant Name_Id := N + 168; -- VMS
- Name_Import_Function : constant Name_Id := N + 169; -- GNAT
- Name_Import_Object : constant Name_Id := N + 170; -- GNAT
- Name_Import_Procedure : constant Name_Id := N + 171; -- GNAT
- Name_Import_Valued_Procedure : constant Name_Id := N + 172; -- GNAT
- Name_Inline : constant Name_Id := N + 173;
- Name_Inline_Always : constant Name_Id := N + 174; -- GNAT
- Name_Inline_Generic : constant Name_Id := N + 175; -- GNAT
- Name_Inspection_Point : constant Name_Id := N + 176;
- Name_Interface : constant Name_Id := N + 177; -- Ada 83
- Name_Interface_Name : constant Name_Id := N + 178; -- GNAT
- Name_Interrupt_Handler : constant Name_Id := N + 179;
- Name_Interrupt_Priority : constant Name_Id := N + 180;
- Name_Java_Constructor : constant Name_Id := N + 181; -- GNAT
- Name_Java_Interface : constant Name_Id := N + 182; -- GNAT
- Name_Keep_Names : constant Name_Id := N + 183; -- GNAT
- Name_Link_With : constant Name_Id := N + 184; -- GNAT
- Name_Linker_Alias : constant Name_Id := N + 185; -- GNAT
- Name_Linker_Options : constant Name_Id := N + 186;
- Name_Linker_Section : constant Name_Id := N + 187; -- GNAT
- Name_List : constant Name_Id := N + 188;
- Name_Machine_Attribute : constant Name_Id := N + 189; -- GNAT
- Name_Main : constant Name_Id := N + 190; -- GNAT
- Name_Main_Storage : constant Name_Id := N + 191; -- GNAT
- Name_Memory_Size : constant Name_Id := N + 192; -- Ada 83
- Name_No_Return : constant Name_Id := N + 193; -- GNAT
- Name_Obsolescent : constant Name_Id := N + 194; -- GNAT
- Name_Optimize : constant Name_Id := N + 195;
- Name_Optional_Overriding : constant Name_Id := N + 196;
- Name_Overriding : constant Name_Id := N + 197;
- Name_Pack : constant Name_Id := N + 198;
- Name_Page : constant Name_Id := N + 199;
- Name_Passive : constant Name_Id := N + 200; -- GNAT
- Name_Preelaborate : constant Name_Id := N + 201;
- Name_Priority : constant Name_Id := N + 202;
- Name_Psect_Object : constant Name_Id := N + 203; -- VMS
- Name_Pure : constant Name_Id := N + 204;
- Name_Pure_Function : constant Name_Id := N + 205; -- GNAT
- Name_Remote_Call_Interface : constant Name_Id := N + 206;
- Name_Remote_Types : constant Name_Id := N + 207;
- Name_Share_Generic : constant Name_Id := N + 208; -- GNAT
- Name_Shared : constant Name_Id := N + 209; -- Ada 83
- Name_Shared_Passive : constant Name_Id := N + 210;
+ Name_Assert : constant Name_Id := N + 154; -- GNAT
+ Name_Asynchronous : constant Name_Id := N + 155;
+ Name_Atomic : constant Name_Id := N + 156;
+ Name_Atomic_Components : constant Name_Id := N + 157;
+ Name_Attach_Handler : constant Name_Id := N + 158;
+ Name_Comment : constant Name_Id := N + 159; -- GNAT
+ Name_Common_Object : constant Name_Id := N + 160; -- GNAT
+ Name_Complex_Representation : constant Name_Id := N + 161; -- GNAT
+ Name_Controlled : constant Name_Id := N + 162;
+ Name_Convention : constant Name_Id := N + 163;
+ Name_CPP_Class : constant Name_Id := N + 164; -- GNAT
+ Name_CPP_Constructor : constant Name_Id := N + 165; -- GNAT
+ Name_CPP_Virtual : constant Name_Id := N + 166; -- GNAT
+ Name_CPP_Vtable : constant Name_Id := N + 167; -- GNAT
+ Name_Debug : constant Name_Id := N + 168; -- GNAT
+ Name_Elaborate : constant Name_Id := N + 169; -- Ada 83
+ Name_Elaborate_All : constant Name_Id := N + 170;
+ Name_Elaborate_Body : constant Name_Id := N + 171;
+ Name_Export : constant Name_Id := N + 172;
+ Name_Export_Exception : constant Name_Id := N + 173; -- VMS
+ Name_Export_Function : constant Name_Id := N + 174; -- GNAT
+ Name_Export_Object : constant Name_Id := N + 175; -- GNAT
+ Name_Export_Procedure : constant Name_Id := N + 176; -- GNAT
+ Name_Export_Value : constant Name_Id := N + 177; -- GNAT
+ Name_Export_Valued_Procedure : constant Name_Id := N + 178; -- GNAT
+ Name_External : constant Name_Id := N + 179; -- GNAT
+ Name_Finalize_Storage_Only : constant Name_Id := N + 180; -- GNAT
+ Name_Ident : constant Name_Id := N + 181; -- VMS
+ Name_Import : constant Name_Id := N + 182;
+ Name_Import_Exception : constant Name_Id := N + 183; -- VMS
+ Name_Import_Function : constant Name_Id := N + 184; -- GNAT
+ Name_Import_Object : constant Name_Id := N + 185; -- GNAT
+ Name_Import_Procedure : constant Name_Id := N + 186; -- GNAT
+ Name_Import_Valued_Procedure : constant Name_Id := N + 187; -- GNAT
+ Name_Inline : constant Name_Id := N + 188;
+ Name_Inline_Always : constant Name_Id := N + 189; -- GNAT
+ Name_Inline_Generic : constant Name_Id := N + 190; -- GNAT
+ Name_Inspection_Point : constant Name_Id := N + 191;
+ Name_Interface : constant Name_Id := N + 192; -- Ada 83
+ Name_Interface_Name : constant Name_Id := N + 193; -- GNAT
+ Name_Interrupt_Handler : constant Name_Id := N + 194;
+ Name_Interrupt_Priority : constant Name_Id := N + 195;
+ Name_Java_Constructor : constant Name_Id := N + 196; -- GNAT
+ Name_Java_Interface : constant Name_Id := N + 197; -- GNAT
+ Name_Keep_Names : constant Name_Id := N + 198; -- GNAT
+ Name_Link_With : constant Name_Id := N + 199; -- GNAT
+ Name_Linker_Alias : constant Name_Id := N + 200; -- GNAT
+ Name_Linker_Options : constant Name_Id := N + 201;
+ Name_Linker_Section : constant Name_Id := N + 202; -- GNAT
+ Name_List : constant Name_Id := N + 203;
+ Name_Machine_Attribute : constant Name_Id := N + 204; -- GNAT
+ Name_Main : constant Name_Id := N + 205; -- GNAT
+ Name_Main_Storage : constant Name_Id := N + 206; -- GNAT
+ Name_Memory_Size : constant Name_Id := N + 207; -- Ada 83
+ Name_No_Return : constant Name_Id := N + 208; -- GNAT
+ Name_Obsolescent : constant Name_Id := N + 209; -- GNAT
+ Name_Optimize : constant Name_Id := N + 210;
+ Name_Optional_Overriding : constant Name_Id := N + 211;
+ Name_Overriding : constant Name_Id := N + 212;
+ Name_Pack : constant Name_Id := N + 213;
+ Name_Page : constant Name_Id := N + 214;
+ Name_Passive : constant Name_Id := N + 215; -- GNAT
+ Name_Preelaborate : constant Name_Id := N + 216;
+ Name_Priority : constant Name_Id := N + 217;
+ Name_Psect_Object : constant Name_Id := N + 218; -- VMS
+ Name_Pure : constant Name_Id := N + 219;
+ Name_Pure_Function : constant Name_Id := N + 220; -- GNAT
+ Name_Remote_Call_Interface : constant Name_Id := N + 221;
+ Name_Remote_Types : constant Name_Id := N + 222;
+ Name_Share_Generic : constant Name_Id := N + 223; -- GNAT
+ Name_Shared : constant Name_Id := N + 224; -- Ada 83
+ Name_Shared_Passive : constant Name_Id := N + 225;
-- Note: Storage_Size is not in this list because its name matches the
-- name of the corresponding attribute. However, it is included in the
@@ -434,27 +455,27 @@ package Snames is
-- Note: Storage_Unit is also omitted from the list because of a clash
-- with an attribute name, and is treated similarly.
- Name_Source_Reference : constant Name_Id := N + 211; -- GNAT
- Name_Stream_Convert : constant Name_Id := N + 212; -- GNAT
- Name_Subtitle : constant Name_Id := N + 213; -- GNAT
- Name_Suppress_All : constant Name_Id := N + 214; -- GNAT
- Name_Suppress_Debug_Info : constant Name_Id := N + 215; -- GNAT
- Name_Suppress_Initialization : constant Name_Id := N + 216; -- GNAT
- Name_System_Name : constant Name_Id := N + 217; -- Ada 83
- Name_Task_Info : constant Name_Id := N + 218; -- GNAT
- Name_Task_Name : constant Name_Id := N + 219; -- GNAT
- Name_Task_Storage : constant Name_Id := N + 220; -- VMS
- Name_Thread_Body : constant Name_Id := N + 221; -- GNAT
- Name_Time_Slice : constant Name_Id := N + 222; -- GNAT
- Name_Title : constant Name_Id := N + 223; -- GNAT
- Name_Unchecked_Union : constant Name_Id := N + 224; -- GNAT
- Name_Unimplemented_Unit : constant Name_Id := N + 225; -- GNAT
- Name_Unreferenced : constant Name_Id := N + 226; -- GNAT
- Name_Unreserve_All_Interrupts : constant Name_Id := N + 227; -- GNAT
- Name_Volatile : constant Name_Id := N + 228;
- Name_Volatile_Components : constant Name_Id := N + 229;
- Name_Weak_External : constant Name_Id := N + 230; -- GNAT
- Last_Pragma_Name : constant Name_Id := N + 230;
+ Name_Source_Reference : constant Name_Id := N + 226; -- GNAT
+ Name_Stream_Convert : constant Name_Id := N + 227; -- GNAT
+ Name_Subtitle : constant Name_Id := N + 228; -- GNAT
+ Name_Suppress_All : constant Name_Id := N + 229; -- GNAT
+ Name_Suppress_Debug_Info : constant Name_Id := N + 230; -- GNAT
+ Name_Suppress_Initialization : constant Name_Id := N + 231; -- GNAT
+ Name_System_Name : constant Name_Id := N + 232; -- Ada 83
+ Name_Task_Info : constant Name_Id := N + 233; -- GNAT
+ Name_Task_Name : constant Name_Id := N + 234; -- GNAT
+ Name_Task_Storage : constant Name_Id := N + 235; -- VMS
+ Name_Thread_Body : constant Name_Id := N + 236; -- GNAT
+ Name_Time_Slice : constant Name_Id := N + 237; -- GNAT
+ Name_Title : constant Name_Id := N + 238; -- GNAT
+ Name_Unchecked_Union : constant Name_Id := N + 239; -- GNAT
+ Name_Unimplemented_Unit : constant Name_Id := N + 240; -- GNAT
+ Name_Unreferenced : constant Name_Id := N + 241; -- GNAT
+ Name_Unreserve_All_Interrupts : constant Name_Id := N + 242; -- GNAT
+ Name_Volatile : constant Name_Id := N + 243;
+ Name_Volatile_Components : constant Name_Id := N + 244;
+ Name_Weak_External : constant Name_Id := N + 245; -- GNAT
+ Last_Pragma_Name : constant Name_Id := N + 245;
-- Language convention names for pragma Convention/Export/Import/Interface
-- Note that Name_C is not included in this list, since it was already
@@ -465,98 +486,100 @@ package Snames is
-- Entry and Protected, this is because these conventions cannot be
-- specified by a pragma.
- First_Convention_Name : constant Name_Id := N + 231;
- Name_Ada : constant Name_Id := N + 231;
- Name_Assembler : constant Name_Id := N + 232;
- Name_COBOL : constant Name_Id := N + 233;
- Name_CPP : constant Name_Id := N + 234;
- Name_Fortran : constant Name_Id := N + 235;
- Name_Intrinsic : constant Name_Id := N + 236;
- Name_Java : constant Name_Id := N + 237;
- Name_Stdcall : constant Name_Id := N + 238;
- Name_Stubbed : constant Name_Id := N + 239;
- Last_Convention_Name : constant Name_Id := N + 239;
+ First_Convention_Name : constant Name_Id := N + 246;
+ Name_Ada : constant Name_Id := N + 246;
+ Name_Assembler : constant Name_Id := N + 247;
+ Name_COBOL : constant Name_Id := N + 248;
+ Name_CPP : constant Name_Id := N + 249;
+ Name_Fortran : constant Name_Id := N + 250;
+ Name_Intrinsic : constant Name_Id := N + 251;
+ Name_Java : constant Name_Id := N + 252;
+ Name_Stdcall : constant Name_Id := N + 253;
+ Name_Stubbed : constant Name_Id := N + 254;
+ Last_Convention_Name : constant Name_Id := N + 254;
-- The following names are preset as synonyms for Assembler
- Name_Asm : constant Name_Id := N + 240;
- Name_Assembly : constant Name_Id := N + 241;
+ Name_Asm : constant Name_Id := N + 255;
+ Name_Assembly : constant Name_Id := N + 256;
-- The following names are preset as synonyms for C
- Name_Default : constant Name_Id := N + 242;
+ Name_Default : constant Name_Id := N + 257;
-- Name_Exernal (previously defined as pragma)
-- The following names are present as synonyms for Stdcall
- Name_DLL : constant Name_Id := N + 243;
- Name_Win32 : constant Name_Id := N + 244;
+ Name_DLL : constant Name_Id := N + 258;
+ Name_Win32 : constant Name_Id := N + 259;
-- Other special names used in processing pragmas
- Name_As_Is : constant Name_Id := N + 245;
- Name_Body_File_Name : constant Name_Id := N + 246;
- Name_Casing : constant Name_Id := N + 247;
- Name_Code : constant Name_Id := N + 248;
- Name_Component : constant Name_Id := N + 249;
- Name_Component_Size_4 : constant Name_Id := N + 250;
- Name_Copy : constant Name_Id := N + 251;
- Name_D_Float : constant Name_Id := N + 252;
- Name_Descriptor : constant Name_Id := N + 253;
- Name_Dot_Replacement : constant Name_Id := N + 254;
- Name_Dynamic : constant Name_Id := N + 255;
- Name_Entity : constant Name_Id := N + 256;
- Name_External_Name : constant Name_Id := N + 257;
- Name_First_Optional_Parameter : constant Name_Id := N + 258;
- Name_Form : constant Name_Id := N + 259;
- Name_G_Float : constant Name_Id := N + 260;
- Name_Gcc : constant Name_Id := N + 261;
- Name_Gnat : constant Name_Id := N + 262;
- Name_GPL : constant Name_Id := N + 263;
- Name_IEEE_Float : constant Name_Id := N + 264;
- Name_Homonym_Number : constant Name_Id := N + 265;
- Name_Internal : constant Name_Id := N + 266;
- Name_Link_Name : constant Name_Id := N + 267;
- Name_Lowercase : constant Name_Id := N + 268;
- Name_Max_Size : constant Name_Id := N + 269;
- Name_Mechanism : constant Name_Id := N + 270;
- Name_Mixedcase : constant Name_Id := N + 271;
- Name_Modified_GPL : constant Name_Id := N + 272;
- Name_Name : constant Name_Id := N + 273;
- Name_NCA : constant Name_Id := N + 274;
- Name_No : constant Name_Id := N + 275;
- Name_On : constant Name_Id := N + 276;
- Name_Parameter_Types : constant Name_Id := N + 277;
- Name_Reference : constant Name_Id := N + 278;
- Name_No_Requeue : constant Name_Id := N + 279;
- Name_No_Task_Attributes : constant Name_Id := N + 280;
- Name_Restricted : constant Name_Id := N + 281;
- Name_Result_Mechanism : constant Name_Id := N + 282;
- Name_Result_Type : constant Name_Id := N + 283;
- Name_Runtime : constant Name_Id := N + 284;
- Name_SB : constant Name_Id := N + 285;
- Name_Secondary_Stack_Size : constant Name_Id := N + 286;
- Name_Section : constant Name_Id := N + 287;
- Name_Semaphore : constant Name_Id := N + 288;
- Name_Spec_File_Name : constant Name_Id := N + 289;
- Name_Static : constant Name_Id := N + 290;
- Name_Stack_Size : constant Name_Id := N + 291;
- Name_Subunit_File_Name : constant Name_Id := N + 292;
- Name_Task_Stack_Size_Default : constant Name_Id := N + 293;
- Name_Task_Type : constant Name_Id := N + 294;
- Name_Time_Slicing_Enabled : constant Name_Id := N + 295;
- Name_Top_Guard : constant Name_Id := N + 296;
- Name_UBA : constant Name_Id := N + 297;
- Name_UBS : constant Name_Id := N + 298;
- Name_UBSB : constant Name_Id := N + 299;
- Name_Unit_Name : constant Name_Id := N + 300;
- Name_Unknown : constant Name_Id := N + 301;
- Name_Unrestricted : constant Name_Id := N + 302;
- Name_Uppercase : constant Name_Id := N + 303;
- Name_User : constant Name_Id := N + 304;
- Name_VAX_Float : constant Name_Id := N + 305;
- Name_VMS : constant Name_Id := N + 306;
- Name_Working_Storage : constant Name_Id := N + 307;
+ Name_As_Is : constant Name_Id := N + 260;
+ Name_Body_File_Name : constant Name_Id := N + 261;
+ Name_Boolean_Entry_Barriers : constant Name_Id := N + 262;
+ Name_Casing : constant Name_Id := N + 263;
+ Name_Code : constant Name_Id := N + 264;
+ Name_Component : constant Name_Id := N + 265;
+ Name_Component_Size_4 : constant Name_Id := N + 266;
+ Name_Copy : constant Name_Id := N + 267;
+ Name_D_Float : constant Name_Id := N + 268;
+ Name_Descriptor : constant Name_Id := N + 269;
+ Name_Dot_Replacement : constant Name_Id := N + 270;
+ Name_Dynamic : constant Name_Id := N + 271;
+ Name_Entity : constant Name_Id := N + 272;
+ Name_External_Name : constant Name_Id := N + 273;
+ Name_First_Optional_Parameter : constant Name_Id := N + 274;
+ Name_Form : constant Name_Id := N + 275;
+ Name_G_Float : constant Name_Id := N + 276;
+ Name_Gcc : constant Name_Id := N + 277;
+ Name_Gnat : constant Name_Id := N + 278;
+ Name_GPL : constant Name_Id := N + 279;
+ Name_IEEE_Float : constant Name_Id := N + 280;
+ Name_Internal : constant Name_Id := N + 281;
+ Name_Link_Name : constant Name_Id := N + 282;
+ Name_Lowercase : constant Name_Id := N + 283;
+ Name_Max_Entry_Queue_Depth : constant Name_Id := N + 284;
+ Name_Max_Size : constant Name_Id := N + 285;
+ Name_Mechanism : constant Name_Id := N + 286;
+ Name_Mixedcase : constant Name_Id := N + 287;
+ Name_Modified_GPL : constant Name_Id := N + 288;
+ Name_Name : constant Name_Id := N + 289;
+ Name_NCA : constant Name_Id := N + 290;
+ Name_No : constant Name_Id := N + 291;
+ Name_On : constant Name_Id := N + 292;
+ Name_Parameter_Types : constant Name_Id := N + 293;
+ Name_Reference : constant Name_Id := N + 294;
+ Name_No_Dynamic_Interrupts : constant Name_Id := N + 295;
+ Name_No_Requeue : constant Name_Id := N + 296;
+ Name_No_Task_Attributes : constant Name_Id := N + 297;
+ Name_Restricted : constant Name_Id := N + 298;
+ Name_Result_Mechanism : constant Name_Id := N + 299;
+ Name_Result_Type : constant Name_Id := N + 300;
+ Name_Runtime : constant Name_Id := N + 301;
+ Name_SB : constant Name_Id := N + 302;
+ Name_Secondary_Stack_Size : constant Name_Id := N + 303;
+ Name_Section : constant Name_Id := N + 304;
+ Name_Semaphore : constant Name_Id := N + 305;
+ Name_Spec_File_Name : constant Name_Id := N + 306;
+ Name_Static : constant Name_Id := N + 307;
+ Name_Stack_Size : constant Name_Id := N + 308;
+ Name_Subunit_File_Name : constant Name_Id := N + 309;
+ Name_Task_Stack_Size_Default : constant Name_Id := N + 310;
+ Name_Task_Type : constant Name_Id := N + 311;
+ Name_Time_Slicing_Enabled : constant Name_Id := N + 312;
+ Name_Top_Guard : constant Name_Id := N + 313;
+ Name_UBA : constant Name_Id := N + 314;
+ Name_UBS : constant Name_Id := N + 315;
+ Name_UBSB : constant Name_Id := N + 316;
+ Name_Unit_Name : constant Name_Id := N + 317;
+ Name_Unknown : constant Name_Id := N + 318;
+ Name_Unrestricted : constant Name_Id := N + 319;
+ Name_Uppercase : constant Name_Id := N + 320;
+ Name_User : constant Name_Id := N + 321;
+ Name_VAX_Float : constant Name_Id := N + 322;
+ Name_VMS : constant Name_Id := N + 323;
+ Name_Working_Storage : constant Name_Id := N + 324;
-- Names of recognized attributes. The entries with the comment "Ada 83"
-- are attributes that are defined in Ada 83, but not in Ada 95. These
@@ -570,158 +593,158 @@ package Snames is
-- The entries marked VMS are recognized only in OpenVMS implementations
-- of GNAT, and are treated as illegal in all other contexts.
- First_Attribute_Name : constant Name_Id := N + 308;
- Name_Abort_Signal : constant Name_Id := N + 308; -- GNAT
- Name_Access : constant Name_Id := N + 309;
- Name_Address : constant Name_Id := N + 310;
- Name_Address_Size : constant Name_Id := N + 311; -- GNAT
- Name_Aft : constant Name_Id := N + 312;
- Name_Alignment : constant Name_Id := N + 313;
- Name_Asm_Input : constant Name_Id := N + 314; -- GNAT
- Name_Asm_Output : constant Name_Id := N + 315; -- GNAT
- Name_AST_Entry : constant Name_Id := N + 316; -- VMS
- Name_Bit : constant Name_Id := N + 317; -- GNAT
- Name_Bit_Order : constant Name_Id := N + 318;
- Name_Bit_Position : constant Name_Id := N + 319; -- GNAT
- Name_Body_Version : constant Name_Id := N + 320;
- Name_Callable : constant Name_Id := N + 321;
- Name_Caller : constant Name_Id := N + 322;
- Name_Code_Address : constant Name_Id := N + 323; -- GNAT
- Name_Component_Size : constant Name_Id := N + 324;
- Name_Compose : constant Name_Id := N + 325;
- Name_Constrained : constant Name_Id := N + 326;
- Name_Count : constant Name_Id := N + 327;
- Name_Default_Bit_Order : constant Name_Id := N + 328; -- GNAT
- Name_Definite : constant Name_Id := N + 329;
- Name_Delta : constant Name_Id := N + 330;
- Name_Denorm : constant Name_Id := N + 331;
- Name_Digits : constant Name_Id := N + 332;
- Name_Elaborated : constant Name_Id := N + 333; -- GNAT
- Name_Emax : constant Name_Id := N + 334; -- Ada 83
- Name_Enum_Rep : constant Name_Id := N + 335; -- GNAT
- Name_Epsilon : constant Name_Id := N + 336; -- Ada 83
- Name_Exponent : constant Name_Id := N + 337;
- Name_External_Tag : constant Name_Id := N + 338;
- Name_First : constant Name_Id := N + 339;
- Name_First_Bit : constant Name_Id := N + 340;
- Name_Fixed_Value : constant Name_Id := N + 341; -- GNAT
- Name_Fore : constant Name_Id := N + 342;
- Name_Has_Discriminants : constant Name_Id := N + 343; -- GNAT
- Name_Identity : constant Name_Id := N + 344;
- Name_Img : constant Name_Id := N + 345; -- GNAT
- Name_Integer_Value : constant Name_Id := N + 346; -- GNAT
- Name_Large : constant Name_Id := N + 347; -- Ada 83
- Name_Last : constant Name_Id := N + 348;
- Name_Last_Bit : constant Name_Id := N + 349;
- Name_Leading_Part : constant Name_Id := N + 350;
- Name_Length : constant Name_Id := N + 351;
- Name_Machine_Emax : constant Name_Id := N + 352;
- Name_Machine_Emin : constant Name_Id := N + 353;
- Name_Machine_Mantissa : constant Name_Id := N + 354;
- Name_Machine_Overflows : constant Name_Id := N + 355;
- Name_Machine_Radix : constant Name_Id := N + 356;
- Name_Machine_Rounds : constant Name_Id := N + 357;
- Name_Machine_Size : constant Name_Id := N + 358; -- GNAT
- Name_Mantissa : constant Name_Id := N + 359; -- Ada 83
- Name_Max_Size_In_Storage_Elements : constant Name_Id := N + 360;
- Name_Maximum_Alignment : constant Name_Id := N + 361; -- GNAT
- Name_Mechanism_Code : constant Name_Id := N + 362; -- GNAT
- Name_Model_Emin : constant Name_Id := N + 363;
- Name_Model_Epsilon : constant Name_Id := N + 364;
- Name_Model_Mantissa : constant Name_Id := N + 365;
- Name_Model_Small : constant Name_Id := N + 366;
- Name_Modulus : constant Name_Id := N + 367;
- Name_Null_Parameter : constant Name_Id := N + 368; -- GNAT
- Name_Object_Size : constant Name_Id := N + 369; -- GNAT
- Name_Partition_ID : constant Name_Id := N + 370;
- Name_Passed_By_Reference : constant Name_Id := N + 371; -- GNAT
- Name_Pool_Address : constant Name_Id := N + 372;
- Name_Pos : constant Name_Id := N + 373;
- Name_Position : constant Name_Id := N + 374;
- Name_Range : constant Name_Id := N + 375;
- Name_Range_Length : constant Name_Id := N + 376; -- GNAT
- Name_Round : constant Name_Id := N + 377;
- Name_Safe_Emax : constant Name_Id := N + 378; -- Ada 83
- Name_Safe_First : constant Name_Id := N + 379;
- Name_Safe_Large : constant Name_Id := N + 380; -- Ada 83
- Name_Safe_Last : constant Name_Id := N + 381;
- Name_Safe_Small : constant Name_Id := N + 382; -- Ada 83
- Name_Scale : constant Name_Id := N + 383;
- Name_Scaling : constant Name_Id := N + 384;
- Name_Signed_Zeros : constant Name_Id := N + 385;
- Name_Size : constant Name_Id := N + 386;
- Name_Small : constant Name_Id := N + 387;
- Name_Storage_Size : constant Name_Id := N + 388;
- Name_Storage_Unit : constant Name_Id := N + 389; -- GNAT
- Name_Tag : constant Name_Id := N + 390;
- Name_Target_Name : constant Name_Id := N + 391; -- GNAT
- Name_Terminated : constant Name_Id := N + 392;
- Name_To_Address : constant Name_Id := N + 393; -- GNAT
- Name_Type_Class : constant Name_Id := N + 394; -- GNAT
- Name_UET_Address : constant Name_Id := N + 395; -- GNAT
- Name_Unbiased_Rounding : constant Name_Id := N + 396;
- Name_Unchecked_Access : constant Name_Id := N + 397;
- Name_Unconstrained_Array : constant Name_Id := N + 398;
- Name_Universal_Literal_String : constant Name_Id := N + 399; -- GNAT
- Name_Unrestricted_Access : constant Name_Id := N + 400; -- GNAT
- Name_VADS_Size : constant Name_Id := N + 401; -- GNAT
- Name_Val : constant Name_Id := N + 402;
- Name_Valid : constant Name_Id := N + 403;
- Name_Value_Size : constant Name_Id := N + 404; -- GNAT
- Name_Version : constant Name_Id := N + 405;
- Name_Wchar_T_Size : constant Name_Id := N + 406; -- GNAT
- Name_Wide_Width : constant Name_Id := N + 407;
- Name_Width : constant Name_Id := N + 408;
- Name_Word_Size : constant Name_Id := N + 409; -- GNAT
+ First_Attribute_Name : constant Name_Id := N + 325;
+ Name_Abort_Signal : constant Name_Id := N + 325; -- GNAT
+ Name_Access : constant Name_Id := N + 326;
+ Name_Address : constant Name_Id := N + 327;
+ Name_Address_Size : constant Name_Id := N + 328; -- GNAT
+ Name_Aft : constant Name_Id := N + 329;
+ Name_Alignment : constant Name_Id := N + 330;
+ Name_Asm_Input : constant Name_Id := N + 331; -- GNAT
+ Name_Asm_Output : constant Name_Id := N + 332; -- GNAT
+ Name_AST_Entry : constant Name_Id := N + 333; -- VMS
+ Name_Bit : constant Name_Id := N + 334; -- GNAT
+ Name_Bit_Order : constant Name_Id := N + 335;
+ Name_Bit_Position : constant Name_Id := N + 336; -- GNAT
+ Name_Body_Version : constant Name_Id := N + 337;
+ Name_Callable : constant Name_Id := N + 338;
+ Name_Caller : constant Name_Id := N + 339;
+ Name_Code_Address : constant Name_Id := N + 340; -- GNAT
+ Name_Component_Size : constant Name_Id := N + 341;
+ Name_Compose : constant Name_Id := N + 342;
+ Name_Constrained : constant Name_Id := N + 343;
+ Name_Count : constant Name_Id := N + 344;
+ Name_Default_Bit_Order : constant Name_Id := N + 345; -- GNAT
+ Name_Definite : constant Name_Id := N + 346;
+ Name_Delta : constant Name_Id := N + 347;
+ Name_Denorm : constant Name_Id := N + 348;
+ Name_Digits : constant Name_Id := N + 349;
+ Name_Elaborated : constant Name_Id := N + 350; -- GNAT
+ Name_Emax : constant Name_Id := N + 351; -- Ada 83
+ Name_Enum_Rep : constant Name_Id := N + 352; -- GNAT
+ Name_Epsilon : constant Name_Id := N + 353; -- Ada 83
+ Name_Exponent : constant Name_Id := N + 354;
+ Name_External_Tag : constant Name_Id := N + 355;
+ Name_First : constant Name_Id := N + 356;
+ Name_First_Bit : constant Name_Id := N + 357;
+ Name_Fixed_Value : constant Name_Id := N + 358; -- GNAT
+ Name_Fore : constant Name_Id := N + 359;
+ Name_Has_Discriminants : constant Name_Id := N + 360; -- GNAT
+ Name_Identity : constant Name_Id := N + 361;
+ Name_Img : constant Name_Id := N + 362; -- GNAT
+ Name_Integer_Value : constant Name_Id := N + 363; -- GNAT
+ Name_Large : constant Name_Id := N + 364; -- Ada 83
+ Name_Last : constant Name_Id := N + 365;
+ Name_Last_Bit : constant Name_Id := N + 366;
+ Name_Leading_Part : constant Name_Id := N + 367;
+ Name_Length : constant Name_Id := N + 368;
+ Name_Machine_Emax : constant Name_Id := N + 369;
+ Name_Machine_Emin : constant Name_Id := N + 370;
+ Name_Machine_Mantissa : constant Name_Id := N + 371;
+ Name_Machine_Overflows : constant Name_Id := N + 372;
+ Name_Machine_Radix : constant Name_Id := N + 373;
+ Name_Machine_Rounds : constant Name_Id := N + 374;
+ Name_Machine_Size : constant Name_Id := N + 375; -- GNAT
+ Name_Mantissa : constant Name_Id := N + 376; -- Ada 83
+ Name_Max_Size_In_Storage_Elements : constant Name_Id := N + 377;
+ Name_Maximum_Alignment : constant Name_Id := N + 378; -- GNAT
+ Name_Mechanism_Code : constant Name_Id := N + 379; -- GNAT
+ Name_Model_Emin : constant Name_Id := N + 380;
+ Name_Model_Epsilon : constant Name_Id := N + 381;
+ Name_Model_Mantissa : constant Name_Id := N + 382;
+ Name_Model_Small : constant Name_Id := N + 383;
+ Name_Modulus : constant Name_Id := N + 384;
+ Name_Null_Parameter : constant Name_Id := N + 385; -- GNAT
+ Name_Object_Size : constant Name_Id := N + 386; -- GNAT
+ Name_Partition_ID : constant Name_Id := N + 387;
+ Name_Passed_By_Reference : constant Name_Id := N + 388; -- GNAT
+ Name_Pool_Address : constant Name_Id := N + 389;
+ Name_Pos : constant Name_Id := N + 390;
+ Name_Position : constant Name_Id := N + 391;
+ Name_Range : constant Name_Id := N + 392;
+ Name_Range_Length : constant Name_Id := N + 393; -- GNAT
+ Name_Round : constant Name_Id := N + 394;
+ Name_Safe_Emax : constant Name_Id := N + 395; -- Ada 83
+ Name_Safe_First : constant Name_Id := N + 396;
+ Name_Safe_Large : constant Name_Id := N + 397; -- Ada 83
+ Name_Safe_Last : constant Name_Id := N + 398;
+ Name_Safe_Small : constant Name_Id := N + 399; -- Ada 83
+ Name_Scale : constant Name_Id := N + 400;
+ Name_Scaling : constant Name_Id := N + 401;
+ Name_Signed_Zeros : constant Name_Id := N + 402;
+ Name_Size : constant Name_Id := N + 403;
+ Name_Small : constant Name_Id := N + 404;
+ Name_Storage_Size : constant Name_Id := N + 405;
+ Name_Storage_Unit : constant Name_Id := N + 406; -- GNAT
+ Name_Tag : constant Name_Id := N + 407;
+ Name_Target_Name : constant Name_Id := N + 408; -- GNAT
+ Name_Terminated : constant Name_Id := N + 409;
+ Name_To_Address : constant Name_Id := N + 410; -- GNAT
+ Name_Type_Class : constant Name_Id := N + 411; -- GNAT
+ Name_UET_Address : constant Name_Id := N + 412; -- GNAT
+ Name_Unbiased_Rounding : constant Name_Id := N + 413;
+ Name_Unchecked_Access : constant Name_Id := N + 414;
+ Name_Unconstrained_Array : constant Name_Id := N + 415;
+ Name_Universal_Literal_String : constant Name_Id := N + 416; -- GNAT
+ Name_Unrestricted_Access : constant Name_Id := N + 417; -- GNAT
+ Name_VADS_Size : constant Name_Id := N + 418; -- GNAT
+ Name_Val : constant Name_Id := N + 419;
+ Name_Valid : constant Name_Id := N + 420;
+ Name_Value_Size : constant Name_Id := N + 421; -- GNAT
+ Name_Version : constant Name_Id := N + 422;
+ Name_Wchar_T_Size : constant Name_Id := N + 423; -- GNAT
+ Name_Wide_Width : constant Name_Id := N + 424;
+ Name_Width : constant Name_Id := N + 425;
+ Name_Word_Size : constant Name_Id := N + 426; -- GNAT
-- Attributes that designate attributes returning renamable functions,
-- i.e. functions that return other than a universal value.
- First_Renamable_Function_Attribute : constant Name_Id := N + 410;
- Name_Adjacent : constant Name_Id := N + 410;
- Name_Ceiling : constant Name_Id := N + 411;
- Name_Copy_Sign : constant Name_Id := N + 412;
- Name_Floor : constant Name_Id := N + 413;
- Name_Fraction : constant Name_Id := N + 414;
- Name_Image : constant Name_Id := N + 415;
- Name_Input : constant Name_Id := N + 416;
- Name_Machine : constant Name_Id := N + 417;
- Name_Max : constant Name_Id := N + 418;
- Name_Min : constant Name_Id := N + 419;
- Name_Model : constant Name_Id := N + 420;
- Name_Pred : constant Name_Id := N + 421;
- Name_Remainder : constant Name_Id := N + 422;
- Name_Rounding : constant Name_Id := N + 423;
- Name_Succ : constant Name_Id := N + 424;
- Name_Truncation : constant Name_Id := N + 425;
- Name_Value : constant Name_Id := N + 426;
- Name_Wide_Image : constant Name_Id := N + 427;
- Name_Wide_Value : constant Name_Id := N + 428;
- Last_Renamable_Function_Attribute : constant Name_Id := N + 428;
+ First_Renamable_Function_Attribute : constant Name_Id := N + 427;
+ Name_Adjacent : constant Name_Id := N + 427;
+ Name_Ceiling : constant Name_Id := N + 428;
+ Name_Copy_Sign : constant Name_Id := N + 429;
+ Name_Floor : constant Name_Id := N + 430;
+ Name_Fraction : constant Name_Id := N + 431;
+ Name_Image : constant Name_Id := N + 432;
+ Name_Input : constant Name_Id := N + 433;
+ Name_Machine : constant Name_Id := N + 434;
+ Name_Max : constant Name_Id := N + 435;
+ Name_Min : constant Name_Id := N + 436;
+ Name_Model : constant Name_Id := N + 437;
+ Name_Pred : constant Name_Id := N + 438;
+ Name_Remainder : constant Name_Id := N + 439;
+ Name_Rounding : constant Name_Id := N + 440;
+ Name_Succ : constant Name_Id := N + 441;
+ Name_Truncation : constant Name_Id := N + 442;
+ Name_Value : constant Name_Id := N + 443;
+ Name_Wide_Image : constant Name_Id := N + 444;
+ Name_Wide_Value : constant Name_Id := N + 445;
+ Last_Renamable_Function_Attribute : constant Name_Id := N + 445;
-- Attributes that designate procedures
- First_Procedure_Attribute : constant Name_Id := N + 429;
- Name_Output : constant Name_Id := N + 429;
- Name_Read : constant Name_Id := N + 430;
- Name_Write : constant Name_Id := N + 431;
- Last_Procedure_Attribute : constant Name_Id := N + 431;
+ First_Procedure_Attribute : constant Name_Id := N + 446;
+ Name_Output : constant Name_Id := N + 446;
+ Name_Read : constant Name_Id := N + 447;
+ Name_Write : constant Name_Id := N + 448;
+ Last_Procedure_Attribute : constant Name_Id := N + 448;
-- Remaining attributes are ones that return entities
- First_Entity_Attribute_Name : constant Name_Id := N + 432;
- Name_Elab_Body : constant Name_Id := N + 432; -- GNAT
- Name_Elab_Spec : constant Name_Id := N + 433; -- GNAT
- Name_Storage_Pool : constant Name_Id := N + 434;
+ First_Entity_Attribute_Name : constant Name_Id := N + 449;
+ Name_Elab_Body : constant Name_Id := N + 449; -- GNAT
+ Name_Elab_Spec : constant Name_Id := N + 450; -- GNAT
+ Name_Storage_Pool : constant Name_Id := N + 451;
-- These attributes are the ones that return types
- First_Type_Attribute_Name : constant Name_Id := N + 435;
- Name_Base : constant Name_Id := N + 435;
- Name_Class : constant Name_Id := N + 436;
- Last_Type_Attribute_Name : constant Name_Id := N + 436;
- Last_Entity_Attribute_Name : constant Name_Id := N + 436;
- Last_Attribute_Name : constant Name_Id := N + 436;
+ First_Type_Attribute_Name : constant Name_Id := N + 452;
+ Name_Base : constant Name_Id := N + 452;
+ Name_Class : constant Name_Id := N + 453;
+ Last_Type_Attribute_Name : constant Name_Id := N + 453;
+ Last_Entity_Attribute_Name : constant Name_Id := N + 453;
+ Last_Attribute_Name : constant Name_Id := N + 453;
-- Names of recognized locking policy identifiers
@@ -729,10 +752,10 @@ package Snames is
-- name (e.g. C for Ceiling_Locking). If new policy names are added,
-- the first character must be distinct.
- First_Locking_Policy_Name : constant Name_Id := N + 437;
- Name_Ceiling_Locking : constant Name_Id := N + 437;
- Name_Inheritance_Locking : constant Name_Id := N + 438;
- Last_Locking_Policy_Name : constant Name_Id := N + 438;
+ First_Locking_Policy_Name : constant Name_Id := N + 454;
+ Name_Ceiling_Locking : constant Name_Id := N + 454;
+ Name_Inheritance_Locking : constant Name_Id := N + 455;
+ Last_Locking_Policy_Name : constant Name_Id := N + 455;
-- Names of recognized queuing policy identifiers.
@@ -740,10 +763,10 @@ package Snames is
-- name (e.g. F for FIFO_Queuing). If new policy names are added,
-- the first character must be distinct.
- First_Queuing_Policy_Name : constant Name_Id := N + 439;
- Name_FIFO_Queuing : constant Name_Id := N + 439;
- Name_Priority_Queuing : constant Name_Id := N + 440;
- Last_Queuing_Policy_Name : constant Name_Id := N + 440;
+ First_Queuing_Policy_Name : constant Name_Id := N + 456;
+ Name_FIFO_Queuing : constant Name_Id := N + 456;
+ Name_Priority_Queuing : constant Name_Id := N + 457;
+ Last_Queuing_Policy_Name : constant Name_Id := N + 457;
-- Names of recognized task dispatching policy identifiers
@@ -751,193 +774,193 @@ package Snames is
-- name (e.g. F for FIFO_WIthinn_Priorities). If new policy names
-- are added, the first character must be distinct.
- First_Task_Dispatching_Policy_Name : constant Name_Id := N + 441;
- Name_FIFO_Within_Priorities : constant Name_Id := N + 441;
- Last_Task_Dispatching_Policy_Name : constant Name_Id := N + 441;
+ First_Task_Dispatching_Policy_Name : constant Name_Id := N + 458;
+ Name_FIFO_Within_Priorities : constant Name_Id := N + 458;
+ Last_Task_Dispatching_Policy_Name : constant Name_Id := N + 458;
-- Names of recognized checks for pragma Suppress
- First_Check_Name : constant Name_Id := N + 442;
- Name_Access_Check : constant Name_Id := N + 442;
- Name_Accessibility_Check : constant Name_Id := N + 443;
- Name_Discriminant_Check : constant Name_Id := N + 444;
- Name_Division_Check : constant Name_Id := N + 445;
- Name_Elaboration_Check : constant Name_Id := N + 446;
- Name_Index_Check : constant Name_Id := N + 447;
- Name_Length_Check : constant Name_Id := N + 448;
- Name_Overflow_Check : constant Name_Id := N + 449;
- Name_Range_Check : constant Name_Id := N + 450;
- Name_Storage_Check : constant Name_Id := N + 451;
- Name_Tag_Check : constant Name_Id := N + 452;
- Name_All_Checks : constant Name_Id := N + 453;
- Last_Check_Name : constant Name_Id := N + 453;
+ First_Check_Name : constant Name_Id := N + 459;
+ Name_Access_Check : constant Name_Id := N + 459;
+ Name_Accessibility_Check : constant Name_Id := N + 460;
+ Name_Discriminant_Check : constant Name_Id := N + 461;
+ Name_Division_Check : constant Name_Id := N + 462;
+ Name_Elaboration_Check : constant Name_Id := N + 463;
+ Name_Index_Check : constant Name_Id := N + 464;
+ Name_Length_Check : constant Name_Id := N + 465;
+ Name_Overflow_Check : constant Name_Id := N + 466;
+ Name_Range_Check : constant Name_Id := N + 467;
+ Name_Storage_Check : constant Name_Id := N + 468;
+ Name_Tag_Check : constant Name_Id := N + 469;
+ Name_All_Checks : constant Name_Id := N + 470;
+ Last_Check_Name : constant Name_Id := N + 470;
-- Names corresponding to reserved keywords, excluding those already
-- declared in the attribute list (Access, Delta, Digits, Range).
- Name_Abort : constant Name_Id := N + 454;
- Name_Abs : constant Name_Id := N + 455;
- Name_Accept : constant Name_Id := N + 456;
- Name_And : constant Name_Id := N + 457;
- Name_All : constant Name_Id := N + 458;
- Name_Array : constant Name_Id := N + 459;
- Name_At : constant Name_Id := N + 460;
- Name_Begin : constant Name_Id := N + 461;
- Name_Body : constant Name_Id := N + 462;
- Name_Case : constant Name_Id := N + 463;
- Name_Constant : constant Name_Id := N + 464;
- Name_Declare : constant Name_Id := N + 465;
- Name_Delay : constant Name_Id := N + 466;
- Name_Do : constant Name_Id := N + 467;
- Name_Else : constant Name_Id := N + 468;
- Name_Elsif : constant Name_Id := N + 469;
- Name_End : constant Name_Id := N + 470;
- Name_Entry : constant Name_Id := N + 471;
- Name_Exception : constant Name_Id := N + 472;
- Name_Exit : constant Name_Id := N + 473;
- Name_For : constant Name_Id := N + 474;
- Name_Function : constant Name_Id := N + 475;
- Name_Generic : constant Name_Id := N + 476;
- Name_Goto : constant Name_Id := N + 477;
- Name_If : constant Name_Id := N + 478;
- Name_In : constant Name_Id := N + 479;
- Name_Is : constant Name_Id := N + 480;
- Name_Limited : constant Name_Id := N + 481;
- Name_Loop : constant Name_Id := N + 482;
- Name_Mod : constant Name_Id := N + 483;
- Name_New : constant Name_Id := N + 484;
- Name_Not : constant Name_Id := N + 485;
- Name_Null : constant Name_Id := N + 486;
- Name_Of : constant Name_Id := N + 487;
- Name_Or : constant Name_Id := N + 488;
- Name_Others : constant Name_Id := N + 489;
- Name_Out : constant Name_Id := N + 490;
- Name_Package : constant Name_Id := N + 491;
- Name_Pragma : constant Name_Id := N + 492;
- Name_Private : constant Name_Id := N + 493;
- Name_Procedure : constant Name_Id := N + 494;
- Name_Raise : constant Name_Id := N + 495;
- Name_Record : constant Name_Id := N + 496;
- Name_Rem : constant Name_Id := N + 497;
- Name_Renames : constant Name_Id := N + 498;
- Name_Return : constant Name_Id := N + 499;
- Name_Reverse : constant Name_Id := N + 500;
- Name_Select : constant Name_Id := N + 501;
- Name_Separate : constant Name_Id := N + 502;
- Name_Subtype : constant Name_Id := N + 503;
- Name_Task : constant Name_Id := N + 504;
- Name_Terminate : constant Name_Id := N + 505;
- Name_Then : constant Name_Id := N + 506;
- Name_Type : constant Name_Id := N + 507;
- Name_Use : constant Name_Id := N + 508;
- Name_When : constant Name_Id := N + 509;
- Name_While : constant Name_Id := N + 510;
- Name_With : constant Name_Id := N + 511;
- Name_Xor : constant Name_Id := N + 512;
+ Name_Abort : constant Name_Id := N + 471;
+ Name_Abs : constant Name_Id := N + 472;
+ Name_Accept : constant Name_Id := N + 473;
+ Name_And : constant Name_Id := N + 474;
+ Name_All : constant Name_Id := N + 475;
+ Name_Array : constant Name_Id := N + 476;
+ Name_At : constant Name_Id := N + 477;
+ Name_Begin : constant Name_Id := N + 478;
+ Name_Body : constant Name_Id := N + 479;
+ Name_Case : constant Name_Id := N + 480;
+ Name_Constant : constant Name_Id := N + 481;
+ Name_Declare : constant Name_Id := N + 482;
+ Name_Delay : constant Name_Id := N + 483;
+ Name_Do : constant Name_Id := N + 484;
+ Name_Else : constant Name_Id := N + 485;
+ Name_Elsif : constant Name_Id := N + 486;
+ Name_End : constant Name_Id := N + 487;
+ Name_Entry : constant Name_Id := N + 488;
+ Name_Exception : constant Name_Id := N + 489;
+ Name_Exit : constant Name_Id := N + 490;
+ Name_For : constant Name_Id := N + 491;
+ Name_Function : constant Name_Id := N + 492;
+ Name_Generic : constant Name_Id := N + 493;
+ Name_Goto : constant Name_Id := N + 494;
+ Name_If : constant Name_Id := N + 495;
+ Name_In : constant Name_Id := N + 496;
+ Name_Is : constant Name_Id := N + 497;
+ Name_Limited : constant Name_Id := N + 498;
+ Name_Loop : constant Name_Id := N + 499;
+ Name_Mod : constant Name_Id := N + 500;
+ Name_New : constant Name_Id := N + 501;
+ Name_Not : constant Name_Id := N + 502;
+ Name_Null : constant Name_Id := N + 503;
+ Name_Of : constant Name_Id := N + 504;
+ Name_Or : constant Name_Id := N + 505;
+ Name_Others : constant Name_Id := N + 506;
+ Name_Out : constant Name_Id := N + 507;
+ Name_Package : constant Name_Id := N + 508;
+ Name_Pragma : constant Name_Id := N + 509;
+ Name_Private : constant Name_Id := N + 510;
+ Name_Procedure : constant Name_Id := N + 511;
+ Name_Raise : constant Name_Id := N + 512;
+ Name_Record : constant Name_Id := N + 513;
+ Name_Rem : constant Name_Id := N + 514;
+ Name_Renames : constant Name_Id := N + 515;
+ Name_Return : constant Name_Id := N + 516;
+ Name_Reverse : constant Name_Id := N + 517;
+ Name_Select : constant Name_Id := N + 518;
+ Name_Separate : constant Name_Id := N + 519;
+ Name_Subtype : constant Name_Id := N + 520;
+ Name_Task : constant Name_Id := N + 521;
+ Name_Terminate : constant Name_Id := N + 522;
+ Name_Then : constant Name_Id := N + 523;
+ Name_Type : constant Name_Id := N + 524;
+ Name_Use : constant Name_Id := N + 525;
+ Name_When : constant Name_Id := N + 526;
+ Name_While : constant Name_Id := N + 527;
+ Name_With : constant Name_Id := N + 528;
+ Name_Xor : constant Name_Id := N + 529;
-- Names of intrinsic subprograms
-- Note: Asm is missing from this list, since Asm is a legitimate
-- convention name. So is To_Adress, which is a GNAT attribute.
- First_Intrinsic_Name : constant Name_Id := N + 513;
- Name_Divide : constant Name_Id := N + 513;
- Name_Enclosing_Entity : constant Name_Id := N + 514;
- Name_Exception_Information : constant Name_Id := N + 515;
- Name_Exception_Message : constant Name_Id := N + 516;
- Name_Exception_Name : constant Name_Id := N + 517;
- Name_File : constant Name_Id := N + 518;
- Name_Import_Address : constant Name_Id := N + 519;
- Name_Import_Largest_Value : constant Name_Id := N + 520;
- Name_Import_Value : constant Name_Id := N + 521;
- Name_Is_Negative : constant Name_Id := N + 522;
- Name_Line : constant Name_Id := N + 523;
- Name_Rotate_Left : constant Name_Id := N + 524;
- Name_Rotate_Right : constant Name_Id := N + 525;
- Name_Shift_Left : constant Name_Id := N + 526;
- Name_Shift_Right : constant Name_Id := N + 527;
- Name_Shift_Right_Arithmetic : constant Name_Id := N + 528;
- Name_Source_Location : constant Name_Id := N + 529;
- Name_Unchecked_Conversion : constant Name_Id := N + 530;
- Name_Unchecked_Deallocation : constant Name_Id := N + 531;
- Name_To_Pointer : constant Name_Id := N + 532;
- Last_Intrinsic_Name : constant Name_Id := N + 532;
+ First_Intrinsic_Name : constant Name_Id := N + 530;
+ Name_Divide : constant Name_Id := N + 530;
+ Name_Enclosing_Entity : constant Name_Id := N + 531;
+ Name_Exception_Information : constant Name_Id := N + 532;
+ Name_Exception_Message : constant Name_Id := N + 533;
+ Name_Exception_Name : constant Name_Id := N + 534;
+ Name_File : constant Name_Id := N + 535;
+ Name_Import_Address : constant Name_Id := N + 536;
+ Name_Import_Largest_Value : constant Name_Id := N + 537;
+ Name_Import_Value : constant Name_Id := N + 538;
+ Name_Is_Negative : constant Name_Id := N + 539;
+ Name_Line : constant Name_Id := N + 540;
+ Name_Rotate_Left : constant Name_Id := N + 541;
+ Name_Rotate_Right : constant Name_Id := N + 542;
+ Name_Shift_Left : constant Name_Id := N + 543;
+ Name_Shift_Right : constant Name_Id := N + 544;
+ Name_Shift_Right_Arithmetic : constant Name_Id := N + 545;
+ Name_Source_Location : constant Name_Id := N + 546;
+ Name_Unchecked_Conversion : constant Name_Id := N + 547;
+ Name_Unchecked_Deallocation : constant Name_Id := N + 548;
+ Name_To_Pointer : constant Name_Id := N + 549;
+ Last_Intrinsic_Name : constant Name_Id := N + 549;
-- Reserved words used only in Ada 95
- First_95_Reserved_Word : constant Name_Id := N + 533;
- Name_Abstract : constant Name_Id := N + 533;
- Name_Aliased : constant Name_Id := N + 534;
- Name_Protected : constant Name_Id := N + 535;
- Name_Until : constant Name_Id := N + 536;
- Name_Requeue : constant Name_Id := N + 537;
- Name_Tagged : constant Name_Id := N + 538;
- Last_95_Reserved_Word : constant Name_Id := N + 538;
+ First_95_Reserved_Word : constant Name_Id := N + 550;
+ Name_Abstract : constant Name_Id := N + 550;
+ Name_Aliased : constant Name_Id := N + 551;
+ Name_Protected : constant Name_Id := N + 552;
+ Name_Until : constant Name_Id := N + 553;
+ Name_Requeue : constant Name_Id := N + 554;
+ Name_Tagged : constant Name_Id := N + 555;
+ Last_95_Reserved_Word : constant Name_Id := N + 555;
subtype Ada_95_Reserved_Words is
Name_Id range First_95_Reserved_Word .. Last_95_Reserved_Word;
-- Miscellaneous names used in semantic checking
- Name_Raise_Exception : constant Name_Id := N + 539;
+ Name_Raise_Exception : constant Name_Id := N + 556;
-- Additional reserved words in GNAT Project Files
-- Note that Name_External is already previously declared
- Name_Binder : constant Name_Id := N + 540;
- Name_Body_Suffix : constant Name_Id := N + 541;
- Name_Builder : constant Name_Id := N + 542;
- Name_Compiler : constant Name_Id := N + 543;
- Name_Cross_Reference : constant Name_Id := N + 544;
- Name_Default_Switches : constant Name_Id := N + 545;
- Name_Exec_Dir : constant Name_Id := N + 546;
- Name_Executable : constant Name_Id := N + 547;
- Name_Executable_Suffix : constant Name_Id := N + 548;
- Name_Extends : constant Name_Id := N + 549;
- Name_Finder : constant Name_Id := N + 550;
- Name_Global_Configuration_Pragmas : constant Name_Id := N + 551;
- Name_Gnatls : constant Name_Id := N + 552;
- Name_Gnatstub : constant Name_Id := N + 553;
- Name_Implementation : constant Name_Id := N + 554;
- Name_Implementation_Exceptions : constant Name_Id := N + 555;
- Name_Implementation_Suffix : constant Name_Id := N + 556;
- Name_Languages : constant Name_Id := N + 557;
- Name_Library_Dir : constant Name_Id := N + 558;
- Name_Library_Auto_Init : constant Name_Id := N + 559;
- Name_Library_GCC : constant Name_Id := N + 560;
- Name_Library_Interface : constant Name_Id := N + 561;
- Name_Library_Kind : constant Name_Id := N + 562;
- Name_Library_Name : constant Name_Id := N + 563;
- Name_Library_Options : constant Name_Id := N + 564;
- Name_Library_Reference_Symbol_File : constant Name_Id := N + 565;
- Name_Library_Src_Dir : constant Name_Id := N + 566;
- Name_Library_Symbol_File : constant Name_Id := N + 567;
- Name_Library_Symbol_Policy : constant Name_Id := N + 568;
- Name_Library_Version : constant Name_Id := N + 569;
- Name_Linker : constant Name_Id := N + 570;
- Name_Local_Configuration_Pragmas : constant Name_Id := N + 571;
- Name_Locally_Removed_Files : constant Name_Id := N + 572;
- Name_Naming : constant Name_Id := N + 573;
- Name_Object_Dir : constant Name_Id := N + 574;
- Name_Pretty_Printer : constant Name_Id := N + 575;
- Name_Project : constant Name_Id := N + 576;
- Name_Separate_Suffix : constant Name_Id := N + 577;
- Name_Source_Dirs : constant Name_Id := N + 578;
- Name_Source_Files : constant Name_Id := N + 579;
- Name_Source_List_File : constant Name_Id := N + 580;
- Name_Spec : constant Name_Id := N + 581;
- Name_Spec_Suffix : constant Name_Id := N + 582;
- Name_Specification : constant Name_Id := N + 583;
- Name_Specification_Exceptions : constant Name_Id := N + 584;
- Name_Specification_Suffix : constant Name_Id := N + 585;
- Name_Switches : constant Name_Id := N + 586;
+ Name_Binder : constant Name_Id := N + 557;
+ Name_Body_Suffix : constant Name_Id := N + 558;
+ Name_Builder : constant Name_Id := N + 559;
+ Name_Compiler : constant Name_Id := N + 560;
+ Name_Cross_Reference : constant Name_Id := N + 561;
+ Name_Default_Switches : constant Name_Id := N + 562;
+ Name_Exec_Dir : constant Name_Id := N + 563;
+ Name_Executable : constant Name_Id := N + 564;
+ Name_Executable_Suffix : constant Name_Id := N + 565;
+ Name_Extends : constant Name_Id := N + 566;
+ Name_Finder : constant Name_Id := N + 567;
+ Name_Global_Configuration_Pragmas : constant Name_Id := N + 568;
+ Name_Gnatls : constant Name_Id := N + 569;
+ Name_Gnatstub : constant Name_Id := N + 570;
+ Name_Implementation : constant Name_Id := N + 571;
+ Name_Implementation_Exceptions : constant Name_Id := N + 572;
+ Name_Implementation_Suffix : constant Name_Id := N + 573;
+ Name_Languages : constant Name_Id := N + 574;
+ Name_Library_Dir : constant Name_Id := N + 575;
+ Name_Library_Auto_Init : constant Name_Id := N + 576;
+ Name_Library_GCC : constant Name_Id := N + 577;
+ Name_Library_Interface : constant Name_Id := N + 578;
+ Name_Library_Kind : constant Name_Id := N + 579;
+ Name_Library_Name : constant Name_Id := N + 580;
+ Name_Library_Options : constant Name_Id := N + 581;
+ Name_Library_Reference_Symbol_File : constant Name_Id := N + 582;
+ Name_Library_Src_Dir : constant Name_Id := N + 583;
+ Name_Library_Symbol_File : constant Name_Id := N + 584;
+ Name_Library_Symbol_Policy : constant Name_Id := N + 585;
+ Name_Library_Version : constant Name_Id := N + 586;
+ Name_Linker : constant Name_Id := N + 587;
+ Name_Local_Configuration_Pragmas : constant Name_Id := N + 588;
+ Name_Locally_Removed_Files : constant Name_Id := N + 589;
+ Name_Naming : constant Name_Id := N + 590;
+ Name_Object_Dir : constant Name_Id := N + 591;
+ Name_Pretty_Printer : constant Name_Id := N + 592;
+ Name_Project : constant Name_Id := N + 593;
+ Name_Separate_Suffix : constant Name_Id := N + 594;
+ Name_Source_Dirs : constant Name_Id := N + 595;
+ Name_Source_Files : constant Name_Id := N + 596;
+ Name_Source_List_File : constant Name_Id := N + 597;
+ Name_Spec : constant Name_Id := N + 598;
+ Name_Spec_Suffix : constant Name_Id := N + 599;
+ Name_Specification : constant Name_Id := N + 600;
+ Name_Specification_Exceptions : constant Name_Id := N + 601;
+ Name_Specification_Suffix : constant Name_Id := N + 602;
+ Name_Switches : constant Name_Id := N + 603;
-- Other miscellaneous names used in front end
- Name_Unaligned_Valid : constant Name_Id := N + 587;
+ Name_Unaligned_Valid : constant Name_Id := N + 604;
-- Mark last defined name for consistency check in Snames body
- Last_Predefined_Name : constant Name_Id := N + 587;
+ Last_Predefined_Name : constant Name_Id := N + 604;
subtype Any_Operator_Name is Name_Id range
First_Operator_Name .. Last_Operator_Name;
diff --git a/gcc/ada/sprint.adb b/gcc/ada/sprint.adb
index 8c936705b47..5fe9e1c550e 100644
--- a/gcc/ada/sprint.adb
+++ b/gcc/ada/sprint.adb
@@ -693,14 +693,27 @@ package body Sprint is
when N_Access_Definition =>
- -- Ada 0Y (AI-231)
+ -- Ada 0Y (AI-254)
- if Null_Exclusion_Present (Node) then
- Write_Str ("not null ");
- end if;
+ if Present (Access_To_Subprogram_Definition (Node)) then
+ Sprint_Node (Access_To_Subprogram_Definition (Node));
+ else
+ -- Ada 0Y (AI-231)
- Write_Str_With_Col_Check_Sloc ("access ");
- Sprint_Node (Subtype_Mark (Node));
+ if Null_Exclusion_Present (Node) then
+ Write_Str ("not null ");
+ end if;
+
+ Write_Str_With_Col_Check_Sloc ("access ");
+
+ if All_Present (Node) then
+ Write_Str ("all ");
+ elsif Constant_Present (Node) then
+ Write_Str ("constant ");
+ end if;
+
+ Sprint_Node (Subtype_Mark (Node));
+ end if;
when N_Access_Function_Definition =>
@@ -1001,9 +1014,9 @@ package body Sprint is
end if;
Sprint_Node (Subtype_Indication (Node));
+
else
- pragma Assert (False);
- null;
+ Write_Str (" ??? ");
end if;
when N_Component_Declaration =>
@@ -1769,8 +1782,7 @@ package body Sprint is
Sprint_Node (Subtype_Mark (Node));
else
- pragma Assert (False);
- null;
+ Write_Str (" ??? ");
end if;
Write_Str_With_Col_Check (" renames ");
@@ -2588,8 +2600,15 @@ package body Sprint is
-- Ada 0Y (AI-50217): Print limited with_clauses
- if Limited_Present (Node) then
+ if Private_Present (Node) and Limited_Present (Node) then
+ Write_Indent_Str ("limited private with ");
+
+ elsif Private_Present (Node) then
+ Write_Indent_Str ("private with ");
+
+ elsif Limited_Present (Node) then
Write_Indent_Str ("limited with ");
+
else
Write_Indent_Str ("with ");
end if;
diff --git a/gcc/ada/stand.ads b/gcc/ada/stand.ads
index 91207695765..0970a06a6ee 100644
--- a/gcc/ada/stand.ads
+++ b/gcc/ada/stand.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2001 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -310,6 +310,9 @@ package Stand is
-- Highest List_Id value used by Standard (including those used by
-- normal list headers, element list headers, and list elements)
+ Boolean_Literals : array (Boolean) of Entity_Id;
+ -- Entities for the two boolean literals, used by the expander
+
-------------------------------------
-- Semantic Phase Special Entities --
-------------------------------------
diff --git a/gcc/ada/switch-c.adb b/gcc/ada/switch-c.adb
index df91201a7ae..a378f209d9b 100644
--- a/gcc/ada/switch-c.adb
+++ b/gcc/ada/switch-c.adb
@@ -386,7 +386,7 @@ package body Switch.C is
when 'I' =>
Ptr := Ptr + 1;
- Scan_Pos (Switch_Chars, 999, Ptr, Multiple_Unit_Index);
+ Scan_Pos (Switch_Chars, Max, Ptr, Multiple_Unit_Index);
-- -gnatem (mapping file)
diff --git a/gcc/ada/switch-m.adb b/gcc/ada/switch-m.adb
index 4001ba86a89..5215fe15029 100644
--- a/gcc/ada/switch-m.adb
+++ b/gcc/ada/switch-m.adb
@@ -551,6 +551,33 @@ package body Switch.M is
return;
+ -- Processing for e switch
+
+ when 'e' =>
+ Ptr := Ptr + 1;
+
+ if Ptr > Max then
+ raise Bad_Switch;
+ end if;
+
+ case Switch_Chars (Ptr) is
+
+ -- processing for eI switch
+
+ when 'I' =>
+ Ptr := Ptr + 1;
+ Scan_Pos (Switch_Chars, Max, Ptr, Main_Index);
+
+ -- processing for eL switch
+
+ when 'L' =>
+ Ptr := Ptr + 1;
+ Follow_Links := True;
+
+ when others =>
+ raise Bad_Switch;
+ end case;
+
-- Processing for f switch
when 'f' =>
@@ -645,6 +672,12 @@ package body Switch.M is
Ptr := Ptr + 1;
Verbose_Mode := True;
+ -- Processing for x switch
+
+ when 'x' =>
+ Ptr := Ptr + 1;
+ External_Unit_Compilation_Allowed := True;
+
-- Processing for z switch
when 'z' =>
diff --git a/gcc/ada/symbols-vms.adb b/gcc/ada/symbols-vms.adb
new file mode 100644
index 00000000000..c623e42b383
--- /dev/null
+++ b/gcc/ada/symbols-vms.adb
@@ -0,0 +1,743 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y M B O L S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2003 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- --
+-- 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, 59 Temple Place - Suite 330, Boston, --
+-- MA 02111-1307, USA. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the VMS version of this package
+
+with Ada.Exceptions; use Ada.Exceptions;
+with Ada.Sequential_IO;
+with Ada.Text_IO; use Ada.Text_IO;
+
+package body Symbols is
+
+ Case_Sensitive : constant String := "case_sensitive=";
+ Symbol_Vector : constant String := "SYMBOL_VECTOR=(";
+ Equal_Data : constant String := "=DATA)";
+ Equal_Procedure : constant String := "=PROCEDURE)";
+ Gsmatch : constant String := "gsmatch=equal,";
+
+ Symbol_File_Name : String_Access := null;
+ -- Name of the symbol file
+
+ Sym_Policy : Policy := Autonomous;
+ -- The symbol policy. Set by Initialize
+
+ Major_ID : Integer := 1;
+ -- The Major ID. May be modified by Initialize if Library_Version is
+ -- specified or if it is read from the reference symbol file.
+
+ Soft_Major_ID : Boolean := True;
+ -- False if library version is specified in procedure Initialize.
+ -- When True, Major_ID may be modified if found in the reference symbol
+ -- file.
+
+ Minor_ID : Natural := 0;
+ -- The Minor ID. May be modified if read from the reference symbol file
+
+ Soft_Minor_ID : Boolean := True;
+ -- False if symbol policy is Autonomous, if library version is specified
+ -- in procedure Initialize and is not the same as the major ID read from
+ -- the reference symbol file. When True, Minor_ID may be increased in
+ -- Compliant symbol policy.
+
+ subtype Byte is Character;
+ -- Object files are stream of bytes, but some of these bytes, those for
+ -- the names of the symbols, are ASCII characters.
+
+ package Byte_IO is new Ada.Sequential_IO (Byte);
+ use Byte_IO;
+
+ type Number is mod 2**16;
+ -- 16 bits unsigned number for number of characters
+
+ GSD : constant Number := 10;
+ -- Code for the Global Symbol Definition section
+
+ C_SYM : constant Number := 1;
+ -- Code for a Symbol subsection
+
+ V_DEF_Mask : constant Number := 2**1;
+ V_NORM_Mask : constant Number := 2**6;
+
+ File : Byte_IO.File_Type;
+ -- Each object file is read as a stream of bytes (characters)
+
+ B : Byte;
+
+ Number_Of_Characters : Natural := 0;
+ -- The number of characters of each section
+
+ -- The following variables are used by procedure Process when reading an
+ -- object file.
+
+ Code : Number := 0;
+ Length : Natural := 0;
+
+ Dummy : Number;
+
+ Nchars : Natural := 0;
+ Flags : Number := 0;
+
+ Symbol : String (1 .. 255);
+ LSymb : Natural;
+
+ function Equal (Left, Right : Symbol_Data) return Boolean;
+ -- Test for equality of symbols
+
+ procedure Get (N : out Number);
+ -- Read two bytes from the object file LSB first as unsigned 16 bit number
+
+ procedure Get (N : out Natural);
+ -- Read two bytes from the object file, LSByte first, as a Natural
+
+
+ function Image (N : Integer) return String;
+ -- Returns the image of N, without the initial space
+
+ -----------
+ -- Equal --
+ -----------
+
+ function Equal (Left, Right : Symbol_Data) return Boolean is
+ begin
+ return Left.Name /= null and then
+ Right.Name /= null and then
+ Left.Name.all = Right.Name.all and then
+ Left.Kind = Right.Kind and then
+ Left.Present = Right.Present;
+ end Equal;
+
+ ---------
+ -- Get --
+ ---------
+
+ procedure Get (N : out Number) is
+ C : Byte;
+ LSByte : Number;
+ begin
+ Read (File, C);
+ LSByte := Byte'Pos (C);
+ Read (File, C);
+ N := LSByte + (256 * Byte'Pos (C));
+ end Get;
+
+ procedure Get (N : out Natural) is
+ Result : Number;
+ begin
+ Get (Result);
+ N := Natural (Result);
+ end Get;
+
+ -----------
+ -- Image --
+ -----------
+
+ function Image (N : Integer) return String is
+ Result : constant String := N'Img;
+ begin
+ if Result (Result'First) = ' ' then
+ return Result (Result'First + 1 .. Result'Last);
+
+ else
+ return Result;
+ end if;
+ end Image;
+
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize
+ (Symbol_File : String;
+ Reference : String;
+ Symbol_Policy : Policy;
+ Quiet : Boolean;
+ Version : String;
+ Success : out Boolean)
+ is
+ File : Ada.Text_IO.File_Type;
+ Line : String (1 .. 1_000);
+ Last : Natural;
+
+ begin
+ -- Record the symbol file name
+
+ Symbol_File_Name := new String'(Symbol_File);
+
+ -- Record the policy
+
+ Sym_Policy := Symbol_Policy;
+
+ -- Record the version (Major ID)
+
+ if Version = "" then
+ Major_ID := 1;
+ Soft_Major_ID := True;
+
+ else
+ begin
+ Major_ID := Integer'Value (Version);
+ Soft_Major_ID := False;
+
+ if Major_ID <= 0 then
+ raise Constraint_Error;
+ end if;
+
+ exception
+ when Constraint_Error =>
+ if not Quiet then
+ Put_Line ("Version """ & Version & """ is illegal.");
+ Put_Line ("On VMS, version must be a positive number");
+ end if;
+
+ Success := False;
+ return;
+ end;
+ end if;
+
+ Minor_ID := 0;
+ Soft_Minor_ID := Sym_Policy /= Autonomous;
+
+ -- Empty the symbol tables
+
+ Symbol_Table.Set_Last (Original_Symbols, 0);
+ Symbol_Table.Set_Last (Complete_Symbols, 0);
+
+ -- Assume that everything will be fine
+
+ Success := True;
+
+ -- If policy is not autonomous, attempt to read the reference file
+
+ if Sym_Policy /= Autonomous then
+ begin
+ Open (File, In_File, Reference);
+
+ exception
+ when Ada.Text_IO.Name_Error =>
+ return;
+
+ when X : others =>
+ if not Quiet then
+ Put_Line ("could not open """ & Reference & """");
+ Put_Line (Exception_Message (X));
+ end if;
+
+ Success := False;
+ return;
+ end;
+
+ -- Read line by line
+
+ while not End_Of_File (File) loop
+ Get_Line (File, Line, Last);
+
+ -- Ignore empty lines
+
+ if Last = 0 then
+ null;
+
+ -- Ignore lines starting with "case_sensitive="
+
+ elsif Last > Case_Sensitive'Length
+ and then Line (1 .. Case_Sensitive'Length) = Case_Sensitive
+ then
+ null;
+
+ -- Line starting with "SYMBOL_VECTOR=("
+
+ elsif Last > Symbol_Vector'Length
+ and then Line (1 .. Symbol_Vector'Length) = Symbol_Vector
+ then
+
+ -- SYMBOL_VECTOR=(<symbol>=DATA)
+
+ if Last > Symbol_Vector'Length + Equal_Data'Length and then
+ Line (Last - Equal_Data'Length + 1 .. Last) = Equal_Data
+ then
+ Symbol_Table.Increment_Last (Original_Symbols);
+ Original_Symbols.Table
+ (Symbol_Table.Last (Original_Symbols)) :=
+ (Name =>
+ new String'(Line (Symbol_Vector'Length + 1 ..
+ Last - Equal_Data'Length)),
+ Kind => Data,
+ Present => True);
+
+ -- SYMBOL_VECTOR=(<symbol>=PROCEDURE)
+
+ elsif Last > Symbol_Vector'Length + Equal_Procedure'Length
+ and then
+ Line (Last - Equal_Procedure'Length + 1 .. Last) =
+ Equal_Procedure
+ then
+ Symbol_Table.Increment_Last (Original_Symbols);
+ Original_Symbols.Table
+ (Symbol_Table.Last (Original_Symbols)) :=
+ (Name =>
+ new String'(Line (Symbol_Vector'Length + 1 ..
+ Last - Equal_Procedure'Length)),
+ Kind => Proc,
+ Present => True);
+
+ -- Anything else is incorrectly formatted
+
+ else
+ if not Quiet then
+ Put_Line ("symbol file """ & Reference &
+ """ is incorrectly formatted:");
+ Put_Line ("""" & Line (1 .. Last) & """");
+ end if;
+
+ Close (File);
+ Success := False;
+ return;
+ end if;
+
+ -- Lines with "gsmatch=equal,<Major_ID>,<Minor_Id>
+
+ elsif Last > Gsmatch'Length
+ and then Line (1 .. Gsmatch'Length) = Gsmatch
+ then
+ declare
+ Start : Positive := Gsmatch'Length + 1;
+ Finish : Positive := Start;
+ OK : Boolean := True;
+ ID : Integer;
+
+ begin
+ loop
+ if Line (Finish) not in '0' .. '9'
+ or else Finish >= Last - 1
+ then
+ OK := False;
+ exit;
+ end if;
+
+ exit when Line (Finish + 1) = ',';
+
+ Finish := Finish + 1;
+ end loop;
+
+ if OK then
+ ID := Integer'Value (Line (Start .. Finish));
+ OK := ID /= 0;
+
+ -- If Soft_Major_ID is True, it means that
+ -- Library_Version was not specified.
+
+ if Soft_Major_ID then
+ Major_ID := ID;
+
+ -- If the Major ID in the reference file is different
+ -- from the Library_Version, then the Minor ID will be 0
+ -- because there is no point in taking the Minor ID in
+ -- the reference file, or incrementing it. So, we set
+ -- Soft_Minor_ID to False, so that we don't modify
+ -- the Minor_ID later.
+
+ elsif Major_ID /= ID then
+ Soft_Minor_ID := False;
+ end if;
+
+ Start := Finish + 2;
+ Finish := Start;
+
+ loop
+ if Line (Finish) not in '0' .. '9' then
+ OK := False;
+ exit;
+ end if;
+
+ exit when Finish = Last;
+
+ Finish := Finish + 1;
+ end loop;
+
+ -- Only set Minor_ID if Soft_Minor_ID is True (see above)
+
+ if OK and then Soft_Minor_ID then
+ Minor_ID := Integer'Value (Line (Start .. Finish));
+ end if;
+ end if;
+
+ -- If OK is not True, that means the line is not correctly
+ -- formatted.
+
+ if not OK then
+ if not Quiet then
+ Put_Line ("symbol file """ & Reference &
+ """ is incorrectly formatted");
+ Put_Line ("""" & Line (1 .. Last) & """");
+ end if;
+
+ Close (File);
+ Success := False;
+ return;
+ end if;
+ end;
+
+ -- Anything else is incorrectly formatted
+
+ else
+ if not Quiet then
+ Put_Line ("unexpected line in symbol file """ &
+ Reference & """");
+ Put_Line ("""" & Line (1 .. Last) & """");
+ end if;
+
+ Close (File);
+ Success := False;
+ return;
+ end if;
+ end loop;
+
+ Close (File);
+ end if;
+ end Initialize;
+
+ -------------
+ -- Process --
+ -------------
+
+ procedure Process
+ (Object_File : String;
+ Success : out Boolean)
+ is
+ begin
+ -- Open the object file with Byte_IO. Return with Success = False if
+ -- this fails.
+
+ begin
+ Open (File, In_File, Object_File);
+ exception
+ when others =>
+ Put_Line
+ ("*** Unable to open object file """ & Object_File & """");
+ Success := False;
+ return;
+ end;
+
+ -- Assume that the object file has a correct format
+
+ Success := True;
+
+ -- Get the different sections one by one from the object file
+
+ while not End_Of_File (File) loop
+
+ Get (Code);
+ Get (Number_Of_Characters);
+ Number_Of_Characters := Number_Of_Characters - 4;
+
+ -- If this is not a Global Symbol Definition section, skip to the
+ -- next section.
+
+ if Code /= GSD then
+
+ for J in 1 .. Number_Of_Characters loop
+ Read (File, B);
+ end loop;
+
+ else
+
+ -- Skip over the next 4 bytes
+
+ Get (Dummy);
+ Get (Dummy);
+ Number_Of_Characters := Number_Of_Characters - 4;
+
+ -- Get each subsection in turn
+
+ loop
+ Get (Code);
+ Get (Nchars);
+ Get (Dummy);
+ Get (Flags);
+ Number_Of_Characters := Number_Of_Characters - 8;
+ Nchars := Nchars - 8;
+
+ -- If this is a symbol and the V_DEF flag is set, get the
+ -- symbol.
+
+ if Code = C_SYM and then ((Flags and V_DEF_Mask) /= 0) then
+ -- First, reach the symbol length
+
+ for J in 1 .. 25 loop
+ Read (File, B);
+ Nchars := Nchars - 1;
+ Number_Of_Characters := Number_Of_Characters - 1;
+ end loop;
+
+ Length := Byte'Pos (B);
+ LSymb := 0;
+
+ -- Get the symbol characters
+
+ for J in 1 .. Nchars loop
+ Read (File, B);
+ Number_Of_Characters := Number_Of_Characters - 1;
+ if Length > 0 then
+ LSymb := LSymb + 1;
+ Symbol (LSymb) := B;
+ Length := Length - 1;
+ end if;
+ end loop;
+
+ -- Create the new Symbol
+
+ declare
+ S_Data : Symbol_Data;
+ begin
+ S_Data.Name := new String'(Symbol (1 .. LSymb));
+
+ -- The symbol kind (Data or Procedure) depends on the
+ -- V_NORM flag.
+
+ if (Flags and V_NORM_Mask) = 0 then
+ S_Data.Kind := Data;
+
+ else
+ S_Data.Kind := Proc;
+ end if;
+
+ -- Put the new symbol in the table
+
+ Symbol_Table.Increment_Last (Complete_Symbols);
+ Complete_Symbols.Table
+ (Symbol_Table.Last (Complete_Symbols)) := S_Data;
+ end;
+
+ else
+ -- As it is not a symbol subsection, skip to the next
+ -- subsection.
+
+ for J in 1 .. Nchars loop
+ Read (File, B);
+ Number_Of_Characters := Number_Of_Characters - 1;
+ end loop;
+ end if;
+
+ -- Exit the GSD section when number of characters reaches 0
+
+ exit when Number_Of_Characters = 0;
+ end loop;
+ end if;
+ end loop;
+
+ -- The object file has been processed, close it
+
+ Close (File);
+
+ exception
+ -- For any exception, output an error message, close the object file
+ -- and return with Success = False.
+
+ when X : others =>
+ Put_Line ("unexpected exception raised while processing """
+ & Object_File & """");
+ Put_Line (Exception_Information (X));
+ Close (File);
+ Success := False;
+ end Process;
+
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize
+ (Quiet : Boolean;
+ Success : out Boolean)
+ is
+ File : Ada.Text_IO.File_Type;
+ -- The symbol file
+
+ S_Data : Symbol_Data;
+ -- A symbol
+
+ Cur : Positive := 1;
+ -- Most probable index in the Complete_Symbols of the current symbol
+ -- in Original_Symbol.
+
+ Found : Boolean;
+
+ begin
+ -- Nothing to be done if Initialize has never been called
+
+ if Symbol_File_Name = null then
+ Success := False;
+
+ else
+
+ -- First find if the symbols in the reference symbol file are also
+ -- in the object files. Note that this is not done if the policy is
+ -- Autonomous, because no reference symbol file has been read.
+
+ -- Expect the first symbol in the symbol file to also be the first
+ -- in Complete_Symbols.
+
+ Cur := 1;
+
+ for Index_1 in 1 .. Symbol_Table.Last (Original_Symbols) loop
+ S_Data := Original_Symbols.Table (Index_1);
+ Found := False;
+
+ First_Object_Loop :
+ for Index_2 in Cur .. Symbol_Table.Last (Complete_Symbols) loop
+ if Equal (S_Data, Complete_Symbols.Table (Index_2)) then
+ Cur := Index_2 + 1;
+ Complete_Symbols.Table (Index_2).Present := False;
+ Found := True;
+ exit First_Object_Loop;
+ end if;
+ end loop First_Object_Loop;
+
+ -- If the symbol could not be found between Cur and Last, try
+ -- before Cur.
+
+ if not Found then
+ Second_Object_Loop :
+ for Index_2 in 1 .. Cur - 1 loop
+ if Equal (S_Data, Complete_Symbols.Table (Index_2)) then
+ Cur := Index_2 + 1;
+ Complete_Symbols.Table (Index_2).Present := False;
+ Found := True;
+ exit Second_Object_Loop;
+ end if;
+ end loop Second_Object_Loop;
+ end if;
+
+ -- If the symbol is not found, mark it as such in the table
+
+ if not Found then
+ if (not Quiet) or else Sym_Policy = Controlled then
+ Put_Line ("symbol """ & S_Data.Name.all &
+ """ is no longer present in the object files");
+ end if;
+
+ if Sym_Policy = Controlled then
+ Success := False;
+ return;
+
+ elsif Soft_Minor_ID then
+ Minor_ID := Minor_ID + 1;
+ Soft_Minor_ID := False;
+ end if;
+
+ Original_Symbols.Table (Index_1).Present := False;
+ Free (Original_Symbols.Table (Index_1).Name);
+
+ if Soft_Minor_ID then
+ Minor_ID := Minor_ID + 1;
+ Soft_Minor_ID := False;
+ end if;
+ end if;
+ end loop;
+
+ -- Append additional symbols, if any, to the Original_Symbols table
+
+ for Index in 1 .. Symbol_Table.Last (Complete_Symbols) loop
+ S_Data := Complete_Symbols.Table (Index);
+
+ if S_Data.Present then
+
+ if Sym_Policy = Controlled then
+ Put_Line ("symbol """ & S_Data.Name.all &
+ """ is not in the reference symbol file");
+ Success := False;
+ return;
+
+ elsif Soft_Minor_ID then
+ Minor_ID := Minor_ID + 1;
+ Soft_Minor_ID := False;
+ end if;
+
+ Symbol_Table.Increment_Last (Original_Symbols);
+ Original_Symbols.Table (Symbol_Table.Last (Original_Symbols)) :=
+ S_Data;
+ Complete_Symbols.Table (Index).Present := False;
+ end if;
+ end loop;
+
+ -- Create the symbol file
+
+ Create (File, Ada.Text_IO.Out_File, Symbol_File_Name.all);
+
+ Put (File, Case_Sensitive);
+ Put_Line (File, "yes");
+
+ -- Put a line in the symbol file for each symbol in the symbol table
+
+ for Index in 1 .. Symbol_Table.Last (Original_Symbols) loop
+ if Original_Symbols.Table (Index).Present then
+ Put (File, Symbol_Vector);
+ Put (File, Original_Symbols.Table (Index).Name.all);
+
+ if Original_Symbols.Table (Index).Kind = Data then
+ Put_Line (File, Equal_Data);
+
+ else
+ Put_Line (File, Equal_Procedure);
+ end if;
+
+ Free (Original_Symbols.Table (Index).Name);
+ end if;
+ end loop;
+
+ Put (File, Case_Sensitive);
+ Put_Line (File, "NO");
+
+ -- Put the version IDs
+
+ Put (File, Gsmatch);
+ Put (File, Image (Major_ID));
+ Put (File, ',');
+ Put_Line (File, Image (Minor_ID));
+
+ -- And we are done
+
+ Close (File);
+
+ -- Reset both tables
+
+ Symbol_Table.Set_Last (Original_Symbols, 0);
+ Symbol_Table.Set_Last (Complete_Symbols, 0);
+
+ -- Clear the symbol file name
+
+ Free (Symbol_File_Name);
+
+ Success := True;
+ end if;
+
+ exception
+ when X : others =>
+ Put_Line ("unexpected exception raised while finalizing """
+ & Symbol_File_Name.all & """");
+ Put_Line (Exception_Information (X));
+ Success := False;
+ end Finalize;
+
+end Symbols;
diff --git a/gcc/ada/system-aix.ads b/gcc/ada/system-aix.ads
new file mode 100644
index 00000000000..fa28445a423
--- /dev/null
+++ b/gcc/ada/system-aix.ads
@@ -0,0 +1,150 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (AIX/PPC Version) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.01;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 32;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := High_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ Max_Priority : constant Positive := 30;
+ Max_Interrupt_Priority : constant Positive := 31;
+
+ subtype Any_Priority is Integer range 0 .. 31;
+ subtype Priority is Any_Priority range 0 .. 30;
+ subtype Interrupt_Priority is Any_Priority range 31 .. 31;
+
+ Default_Priority : constant Priority := 15;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := False;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := False;
+ GCC_ZCX_Support : constant Boolean := False;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := True;
+
+end System;
diff --git a/gcc/ada/system-darwin-ppc.ads b/gcc/ada/system-darwin-ppc.ads
new file mode 100644
index 00000000000..6b16d1f53f1
--- /dev/null
+++ b/gcc/ada/system-darwin-ppc.ads
@@ -0,0 +1,176 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (Darwin/PPC Version) --
+-- --
+-- Copyright (C) 1992-2004 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.01;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 32;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := High_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ -- The values defined here are derived from the following Darwin
+ -- sources:
+ --
+ -- Libc/pthreads/pthread.c
+ -- pthread_init calls host_info to retrieve the HOST_PRIORITY_INFO.
+ -- This file includes "pthread_internals".
+ -- Libc/pthreads/pthread_internals.h
+ -- This file includes <mach/mach.h>.
+ -- xnu/osfmk/mach/mach.h
+ -- This file includes <mach/mach_types.h>.
+ -- xnu/osfmk/mach/mach_types.h
+ -- This file includes <mach/host_info.h>.
+ -- xnu/osfmk/mach/host_info.h
+ -- This file contains the definition of the host_info_t data structure
+ -- and the function prototype for host_info.
+ -- xnu/osfmk/kern/host.c
+ -- This file defines the function host_info which sets the
+ -- priority_info field of struct host_info_t. This file includes
+ -- <kern/processor.h>.
+ -- xnu/osfmk/kern/processor.h
+ -- This file includes <kern/sched.h>.
+ -- xnu/osfmk/kern/sched.h
+ -- This file defines the values for each level of priority.
+
+ Max_Interrupt_Priority : constant Positive := 63;
+ Max_Priority : constant Positive := Max_Interrupt_Priority - 1;
+
+ subtype Any_Priority is Integer range 0 .. Max_Interrupt_Priority;
+ subtype Priority is Any_Priority range 0 .. Max_Priority;
+ subtype Interrupt_Priority is Any_Priority
+ range Priority'Last + 1 .. Max_Interrupt_Priority;
+
+ Default_Priority : constant Priority :=
+ (Priority'Last - Priority'First) / 2;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := False;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := False;
+ GCC_ZCX_Support : constant Boolean := False;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ -- High_Integrity_Mode : constant Boolean := False;
+ -- Long_Shifts_Inlined : constant Boolean := True;
+
+end System;
diff --git a/gcc/ada/system-freebsd-x86.ads b/gcc/ada/system-freebsd-x86.ads
new file mode 100644
index 00000000000..a7371a2d9a2
--- /dev/null
+++ b/gcc/ada/system-freebsd-x86.ads
@@ -0,0 +1,150 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (FreeBSD/x86 Version) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.000_001;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 32;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := Low_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ Max_Priority : constant Positive := 30;
+ Max_Interrupt_Priority : constant Positive := 31;
+
+ subtype Any_Priority is Integer range 0 .. 31;
+ subtype Priority is Any_Priority range 0 .. 30;
+ subtype Interrupt_Priority is Any_Priority range 31 .. 31;
+
+ Default_Priority : constant Priority := 15;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := False;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := False;
+ GCC_ZCX_Support : constant Boolean := False;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := True;
+
+end System;
diff --git a/gcc/ada/system-hpux.ads b/gcc/ada/system-hpux.ads
new file mode 100644
index 00000000000..3b971a587f4
--- /dev/null
+++ b/gcc/ada/system-hpux.ads
@@ -0,0 +1,226 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (HP-UX Version) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.01;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 32;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := High_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ Max_Priority : constant Positive := 30;
+ Max_Interrupt_Priority : constant Positive := 31;
+
+ subtype Any_Priority is Integer range 0 .. 31;
+ subtype Priority is Any_Priority range 0 .. 30;
+ subtype Interrupt_Priority is Any_Priority range 31 .. 31;
+
+ Default_Priority : constant Priority := 15;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := False;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := False;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := True;
+ GCC_ZCX_Support : constant Boolean := True;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := False;
+
+ --------------------------
+ -- Underlying Priorities --
+ ---------------------------
+
+ -- Important note: this section of the file must come AFTER the
+ -- definition of the system implementation parameters to ensure
+ -- that the value of these parameters is available for analysis
+ -- of the declarations here (using Rtsfind at compile time).
+
+ -- The underlying priorities table provides a generalized mechanism
+ -- for mapping from Ada priorities to system priorities. In some
+ -- cases a 1-1 mapping is not the convenient or optimal choice.
+
+ -- For HP/UX DCE Threads, we use the full range of 31 priorities
+ -- in the Ada model, but map them by compression onto the more limited
+ -- range of priorities available in HP/UX.
+ -- For POSIX Threads, this table is ignored.
+
+ -- To replace the default values of the Underlying_Priorities mapping,
+ -- copy this source file into your build directory, edit the file to
+ -- reflect your desired behavior, and recompile with the command:
+
+ -- $ gcc -c -O2 -gnatpgn system.ads
+
+ -- then recompile the run-time parts that depend on this package:
+
+ -- $ gnatmake -a -gnatn -O2 <your application>
+
+ -- then force rebuilding your application if you need different options:
+
+ -- $ gnatmake -f <your options> <your application>
+
+ type Priorities_Mapping is array (Any_Priority) of Integer;
+ pragma Suppress_Initialization (Priorities_Mapping);
+ -- Suppress initialization in case gnat.adc specifies Normalize_Scalars
+
+ Underlying_Priorities : constant Priorities_Mapping :=
+
+ (Priority'First => 16,
+
+ 1 => 17,
+ 2 => 18,
+ 3 => 18,
+ 4 => 18,
+ 5 => 18,
+ 6 => 19,
+ 7 => 19,
+ 8 => 19,
+ 9 => 20,
+ 10 => 20,
+ 11 => 21,
+ 12 => 21,
+ 13 => 22,
+ 14 => 23,
+
+ Default_Priority => 24,
+
+ 16 => 25,
+ 17 => 25,
+ 18 => 25,
+ 19 => 26,
+ 20 => 26,
+ 21 => 26,
+ 22 => 27,
+ 23 => 27,
+ 24 => 27,
+ 25 => 28,
+ 26 => 28,
+ 27 => 29,
+ 28 => 29,
+ 29 => 30,
+
+ Priority'Last => 30,
+
+ Interrupt_Priority => 31);
+
+end System;
diff --git a/gcc/ada/system-interix.ads b/gcc/ada/system-interix.ads
new file mode 100644
index 00000000000..11058290e59
--- /dev/null
+++ b/gcc/ada/system-interix.ads
@@ -0,0 +1,150 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (OpenNT/Interix Version) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.01;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 32;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := Low_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ Max_Priority : constant Positive := 30;
+ Max_Interrupt_Priority : constant Positive := 31;
+
+ subtype Any_Priority is Integer range 0 .. 31;
+ subtype Priority is Any_Priority range 0 .. 30;
+ subtype Interrupt_Priority is Any_Priority range 31 .. 31;
+
+ Default_Priority : constant Priority := 15;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := False;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := False;
+ GCC_ZCX_Support : constant Boolean := False;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := True;
+
+end System;
diff --git a/gcc/ada/system-irix-n32.ads b/gcc/ada/system-irix-n32.ads
new file mode 100644
index 00000000000..398a355899f
--- /dev/null
+++ b/gcc/ada/system-irix-n32.ads
@@ -0,0 +1,153 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (SGI Irix, n32 ABI) --
+-- --
+-- Copyright (C) 1992-2004 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.01;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 64;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := High_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ Max_Priority : constant Positive := 30;
+ Max_Interrupt_Priority : constant Positive := 31;
+
+ subtype Any_Priority is Integer range 0 .. 31;
+ subtype Priority is Any_Priority range 0 .. 30;
+ subtype Interrupt_Priority is Any_Priority range 31 .. 31;
+
+ Default_Priority : constant Priority := 15;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := False;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := True;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := True;
+ GCC_ZCX_Support : constant Boolean := True;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := True;
+
+ -- Note: Denorm is False because denormals are not supported on the
+ -- R10000, and we want the code to be valid for this processor.
+
+end System;
diff --git a/gcc/ada/system-irix-o32.ads b/gcc/ada/system-irix-o32.ads
new file mode 100644
index 00000000000..7ccbe6c65eb
--- /dev/null
+++ b/gcc/ada/system-irix-o32.ads
@@ -0,0 +1,153 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (SGI Irix, o32 ABI) --
+-- --
+-- Copyright (C) 1992-2004 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.01;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 32;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := High_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ Max_Priority : constant Positive := 30;
+ Max_Interrupt_Priority : constant Positive := 31;
+
+ subtype Any_Priority is Integer range 0 .. 31;
+ subtype Priority is Any_Priority range 0 .. 30;
+ subtype Interrupt_Priority is Any_Priority range 31 .. 31;
+
+ Default_Priority : constant Priority := 15;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := False;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := True;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := True;
+ GCC_ZCX_Support : constant Boolean := True;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := True;
+
+ -- Note: Denorm is False because denormals are not supported on the
+ -- R10000, and we want the code to be valid for this processor.
+
+end System;
diff --git a/gcc/ada/system-linux-s390.ads b/gcc/ada/system-linux-s390.ads
new file mode 100644
index 00000000000..2c18a6c15bb
--- /dev/null
+++ b/gcc/ada/system-linux-s390.ads
@@ -0,0 +1,150 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (GNU-Linux/s390 Version) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.000_001;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 32;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := High_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ Max_Priority : constant Positive := 30;
+ Max_Interrupt_Priority : constant Positive := 31;
+
+ subtype Any_Priority is Integer range 0 .. 31;
+ subtype Priority is Any_Priority range 0 .. 30;
+ subtype Interrupt_Priority is Any_Priority range 31 .. 31;
+
+ Default_Priority : constant Priority := 15;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := False;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := True;
+ GCC_ZCX_Support : constant Boolean := True;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := True;
+
+end System;
diff --git a/gcc/ada/system-linux-s390x.ads b/gcc/ada/system-linux-s390x.ads
new file mode 100644
index 00000000000..e1484a35599
--- /dev/null
+++ b/gcc/ada/system-linux-s390x.ads
@@ -0,0 +1,150 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (GNU-Linux/s390x Version) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.000_001;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 64;
+ Memory_Size : constant := 2 ** 64;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := High_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ Max_Priority : constant Positive := 30;
+ Max_Interrupt_Priority : constant Positive := 31;
+
+ subtype Any_Priority is Integer range 0 .. 31;
+ subtype Priority is Any_Priority range 0 .. 30;
+ subtype Interrupt_Priority is Any_Priority range 31 .. 31;
+
+ Default_Priority : constant Priority := 15;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := False;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := True;
+ GCC_ZCX_Support : constant Boolean := True;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := True;
+
+end System;
diff --git a/gcc/ada/system-linux-x86.ads b/gcc/ada/system-linux-x86.ads
new file mode 100644
index 00000000000..8bcf7808221
--- /dev/null
+++ b/gcc/ada/system-linux-x86.ads
@@ -0,0 +1,150 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (GNU-Linux/x86 Version) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.000_001;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 32;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := Low_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ Max_Priority : constant Positive := 30;
+ Max_Interrupt_Priority : constant Positive := 31;
+
+ subtype Any_Priority is Integer range 0 .. 31;
+ subtype Priority is Any_Priority range 0 .. 30;
+ subtype Interrupt_Priority is Any_Priority range 31 .. 31;
+
+ Default_Priority : constant Priority := 15;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := False;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := True;
+ GCC_ZCX_Support : constant Boolean := True;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := True;
+
+end System;
diff --git a/gcc/ada/system-linux-x86_64.ads b/gcc/ada/system-linux-x86_64.ads
new file mode 100644
index 00000000000..37a495d8870
--- /dev/null
+++ b/gcc/ada/system-linux-x86_64.ads
@@ -0,0 +1,150 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (GNU-Linux/x86-64 Version) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.000_001;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 64;
+ Memory_Size : constant := 2 ** 64;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := Low_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ Max_Priority : constant Positive := 30;
+ Max_Interrupt_Priority : constant Positive := 31;
+
+ subtype Any_Priority is Integer range 0 .. 31;
+ subtype Priority is Any_Priority range 0 .. 30;
+ subtype Interrupt_Priority is Any_Priority range 31 .. 31;
+
+ Default_Priority : constant Priority := 15;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := False;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := True;
+ GCC_ZCX_Support : constant Boolean := True;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := True;
+
+end System;
diff --git a/gcc/ada/system-lynxos-ppc.ads b/gcc/ada/system-lynxos-ppc.ads
new file mode 100644
index 00000000000..caeae17a168
--- /dev/null
+++ b/gcc/ada/system-lynxos-ppc.ads
@@ -0,0 +1,150 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (LynxOS PPC Version) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.01;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 32;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := High_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ Max_Priority : constant Positive := 254;
+ Max_Interrupt_Priority : constant Positive := 255;
+
+ subtype Any_Priority is Integer range 0 .. 255;
+ subtype Priority is Any_Priority range 0 .. 254;
+ subtype Interrupt_Priority is Any_Priority range 255 .. 255;
+
+ Default_Priority : constant Priority := 15;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := False;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := False;
+ GCC_ZCX_Support : constant Boolean := False;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := True;
+
+end System;
diff --git a/gcc/ada/system-lynxos-x86.ads b/gcc/ada/system-lynxos-x86.ads
new file mode 100644
index 00000000000..130b5f0d451
--- /dev/null
+++ b/gcc/ada/system-lynxos-x86.ads
@@ -0,0 +1,150 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (LynxOS x86 Version) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.01;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 32;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := Low_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ Max_Priority : constant Positive := 254;
+ Max_Interrupt_Priority : constant Positive := 255;
+
+ subtype Any_Priority is Integer range 0 .. 255;
+ subtype Priority is Any_Priority range 0 .. 254;
+ subtype Interrupt_Priority is Any_Priority range 255 .. 255;
+
+ Default_Priority : constant Priority := 15;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := False;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := False;
+ GCC_ZCX_Support : constant Boolean := False;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := True;
+
+end System;
diff --git a/gcc/ada/system-mingw.ads b/gcc/ada/system-mingw.ads
new file mode 100644
index 00000000000..9316644e0d9
--- /dev/null
+++ b/gcc/ada/system-mingw.ads
@@ -0,0 +1,208 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (NT Version) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.01;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 32;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := Low_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ Max_Priority : constant Positive := 30;
+ Max_Interrupt_Priority : constant Positive := 31;
+
+ subtype Any_Priority is Integer range 0 .. 31;
+ subtype Priority is Any_Priority range 0 .. 30;
+ subtype Interrupt_Priority is Any_Priority range 31 .. 31;
+
+ Default_Priority : constant Priority := 15;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := False;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := False;
+ GCC_ZCX_Support : constant Boolean := True;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := False;
+
+ ---------------------------
+ -- Underlying Priorities --
+ ---------------------------
+
+ -- Important note: this section of the file must come AFTER the
+ -- definition of the system implementation parameters to ensure
+ -- that the value of these parameters is available for analysis
+ -- of the declarations here (using Rtsfind at compile time).
+
+ -- The underlying priorities table provides a generalized mechanism
+ -- for mapping from Ada priorities to system priorities. In some
+ -- cases a 1-1 mapping is not the convenient or optimal choice.
+
+ type Priorities_Mapping is array (Any_Priority) of Integer;
+ pragma Suppress_Initialization (Priorities_Mapping);
+ -- Suppress initialization in case gnat.adc specifies Normalize_Scalars
+
+ -- On NT, the default mapping preserves the standard 31 priorities
+ -- of the Ada model, but maps them using compression onto the 7
+ -- priority levels available in NT.
+
+ -- To replace the default values of the Underlying_Priorities mapping,
+ -- copy this source file into your build directory, edit the file to
+ -- reflect your desired behavior, and recompile with the command:
+
+ -- $ gcc -c -O3 -gnatpgn system.ads
+
+ -- then recompile the run-time parts that depend on this package:
+
+ -- $ gnatmake -a -gnatn -O3 <your application>
+
+ -- then force rebuilding your application if you need different options:
+
+ -- $ gnatmake -f <your options> <your application>
+
+ Underlying_Priorities : constant Priorities_Mapping :=
+
+ (Priority'First .. 1 => -15,
+
+ 2 .. Default_Priority - 2 => -2,
+
+ Default_Priority - 1 => -1,
+
+ Default_Priority => 0,
+
+ Default_Priority + 1 .. 19 => 1,
+
+ 20 .. Priority'Last => 2,
+
+ Interrupt_Priority => 15);
+
+ pragma Linker_Options ("-Wl,--stack=0x2000000");
+ -- This is used to change the default stack (32 MB) size for non tasking
+ -- programs. We change this value for GNAT on Windows here because the
+ -- binutils on this platform have switched to a too low value for Ada
+ -- programs. Note that we also set the stack size for tasking programs in
+ -- System.Task_Primitives.Operations.
+
+end System;
diff --git a/gcc/ada/system-os2.ads b/gcc/ada/system-os2.ads
new file mode 100644
index 00000000000..17acb5bc21e
--- /dev/null
+++ b/gcc/ada/system-os2.ads
@@ -0,0 +1,150 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (OS/2 Version) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.01;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 32;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := Low_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ Max_Priority : constant Positive := 30;
+ Max_Interrupt_Priority : constant Positive := 31;
+
+ subtype Any_Priority is Integer range 0 .. 31;
+ subtype Priority is Any_Priority range 0 .. 30;
+ subtype Interrupt_Priority is Any_Priority range 31 .. 31;
+
+ Default_Priority : constant Priority := 15;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := False;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := False;
+ GCC_ZCX_Support : constant Boolean := False;
+ Front_End_ZCX_Support : constant Boolean := True;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := True;
+
+end System;
diff --git a/gcc/ada/system-solaris-sparc.ads b/gcc/ada/system-solaris-sparc.ads
new file mode 100644
index 00000000000..80621a76517
--- /dev/null
+++ b/gcc/ada/system-solaris-sparc.ads
@@ -0,0 +1,150 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (SUN Solaris Version) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.01;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 32;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := High_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ Max_Priority : constant Positive := 30;
+ Max_Interrupt_Priority : constant Positive := 31;
+
+ subtype Any_Priority is Integer range 0 .. 31;
+ subtype Priority is Any_Priority range 0 .. 30;
+ subtype Interrupt_Priority is Any_Priority range 31 .. 31;
+
+ Default_Priority : constant Priority := 15;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := True;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := True;
+ GCC_ZCX_Support : constant Boolean := True;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := True;
+
+end System;
diff --git a/gcc/ada/system-solaris-sparcv9.ads b/gcc/ada/system-solaris-sparcv9.ads
new file mode 100644
index 00000000000..dca552ebc5a
--- /dev/null
+++ b/gcc/ada/system-solaris-sparcv9.ads
@@ -0,0 +1,150 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (Solaris Sparcv9 Version) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.01;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 64;
+ Memory_Size : constant := 2 ** 64;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := High_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ Max_Priority : constant Positive := 30;
+ Max_Interrupt_Priority : constant Positive := 31;
+
+ subtype Any_Priority is Integer range 0 .. 31;
+ subtype Priority is Any_Priority range 0 .. 30;
+ subtype Interrupt_Priority is Any_Priority range 31 .. 31;
+
+ Default_Priority : constant Priority := 15;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := True;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := True;
+ GCC_ZCX_Support : constant Boolean := True;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := True;
+
+end System;
diff --git a/gcc/ada/system-solaris-x86.ads b/gcc/ada/system-solaris-x86.ads
new file mode 100644
index 00000000000..d48b684f84c
--- /dev/null
+++ b/gcc/ada/system-solaris-x86.ads
@@ -0,0 +1,150 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (x86 Solaris Version) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.01;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 32;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := Low_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ Max_Priority : constant Positive := 30;
+ Max_Interrupt_Priority : constant Positive := 31;
+
+ subtype Any_Priority is Integer range 0 .. 31;
+ subtype Priority is Any_Priority range 0 .. 30;
+ subtype Interrupt_Priority is Any_Priority range 31 .. 31;
+
+ Default_Priority : constant Priority := 15;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := True;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := False;
+ GCC_ZCX_Support : constant Boolean := False;
+ Front_End_ZCX_Support : constant Boolean := True;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := True;
+
+end System;
diff --git a/gcc/ada/system-tru64.ads b/gcc/ada/system-tru64.ads
new file mode 100644
index 00000000000..f0067b37f84
--- /dev/null
+++ b/gcc/ada/system-tru64.ads
@@ -0,0 +1,221 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (DEC Unix Version) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 1.0 / 1024.0;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 64;
+ Memory_Size : constant := 2 ** 64;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := Low_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ Max_Priority : constant Positive := 60;
+ Max_Interrupt_Priority : constant Positive := 63;
+
+ subtype Any_Priority is Integer range 0 .. 63;
+ subtype Priority is Any_Priority range 0 .. 60;
+ subtype Interrupt_Priority is Any_Priority range 61 .. 63;
+
+ Default_Priority : constant Priority := 30;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := False;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := True;
+ Stack_Check_Probes : constant Boolean := True;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := True;
+ GCC_ZCX_Support : constant Boolean := True;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := True;
+
+ -- Note: Denorm is False because denormals are only handled properly
+ -- if the -mieee switch is set, and we do not require this usage.
+
+ ---------------------------
+ -- Underlying Priorities --
+ ---------------------------
+
+ -- Important note: this section of the file must come AFTER the
+ -- definition of the system implementation parameters to ensure
+ -- that the value of these parameters is available for analysis
+ -- of the declarations here (using Rtsfind at compile time).
+
+ -- The underlying priorities table provides a generalized mechanism
+ -- for mapping from Ada priorities to system priorities. In some
+ -- cases a 1-1 mapping is not the convenient or optimal choice.
+
+ -- For Dec Unix 4.0d, we use a default 1-to-1 mapping that provides
+ -- the full range of 64 priorities available from the operating system.
+
+ -- On DU prior to 4.0d, less than 64 priorities are available so there
+ -- are two possibilities:
+
+ -- Limit your range of priorities to the range provided by the
+ -- OS (e.g 16 .. 32 on 4.0b)
+
+ -- Replace the standard table as described below
+
+ -- To replace the default values of the Underlying_Priorities mapping,
+ -- copy this source file into your build directory, edit the file to
+ -- reflect your desired behavior, and recompile with the command:
+
+ -- $ gcc -c -O3 -gnatpgn system.ads
+
+ -- then recompile the run-time parts that depend on this package:
+
+ -- $ gnatmake -a -gnatn -O3 <your application>
+
+ -- then force rebuilding your application if you need different options:
+
+ -- $ gnatmake -f <your options> <your application>
+
+ type Priorities_Mapping is array (Any_Priority) of Integer;
+ pragma Suppress_Initialization (Priorities_Mapping);
+ -- Suppress initialization in case gnat.adc specifies Normalize_Scalars
+
+ Underlying_Priorities : constant Priorities_Mapping :=
+
+ (Priority'First => 0,
+
+ 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5,
+ 6 => 6, 7 => 7, 8 => 8, 9 => 9, 10 => 10,
+ 11 => 11, 12 => 12, 13 => 13, 14 => 14, 15 => 15,
+ 16 => 16, 17 => 17, 18 => 18, 19 => 19, 20 => 20,
+ 21 => 21, 22 => 22, 23 => 23, 24 => 24, 25 => 25,
+ 26 => 26, 27 => 27, 28 => 28, 29 => 29,
+
+ Default_Priority => 30,
+
+ 31 => 31, 32 => 32, 33 => 33, 34 => 34, 35 => 35,
+ 36 => 36, 37 => 37, 38 => 38, 39 => 39, 40 => 40,
+ 41 => 41, 42 => 42, 43 => 43, 44 => 44, 45 => 45,
+ 46 => 46, 47 => 47, 48 => 48, 49 => 49, 50 => 50,
+ 51 => 51, 52 => 52, 53 => 53, 54 => 54, 55 => 55,
+ 56 => 56, 57 => 57, 58 => 58, 59 => 59,
+
+ Priority'Last => 60,
+
+ 61 => 61, 62 => 62,
+
+ Interrupt_Priority'Last => 63);
+
+end System;
diff --git a/gcc/ada/system-unixware.ads b/gcc/ada/system-unixware.ads
new file mode 100644
index 00000000000..01404ee32aa
--- /dev/null
+++ b/gcc/ada/system-unixware.ads
@@ -0,0 +1,150 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (SCO UnixWare Version) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.01;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 32;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := Low_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ Max_Priority : constant Positive := 30;
+ Max_Interrupt_Priority : constant Positive := 31;
+
+ subtype Any_Priority is Integer range 0 .. 31;
+ subtype Priority is Any_Priority range 0 .. 30;
+ subtype Interrupt_Priority is Any_Priority range 31 .. 31;
+
+ Default_Priority : constant Priority := 15;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := False;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := False;
+ GCC_ZCX_Support : constant Boolean := False;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := True;
+
+end System;
diff --git a/gcc/ada/system-vms-zcx.ads b/gcc/ada/system-vms-zcx.ads
new file mode 100644
index 00000000000..3ba5e692195
--- /dev/null
+++ b/gcc/ada/system-vms-zcx.ads
@@ -0,0 +1,236 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (OpenVMS GCC_ZCX DEC Threads Version) --
+-- --
+-- Copyright (C) 2002-2004 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.01;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 32;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := Low_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ Max_Priority : constant Positive := 30;
+ Max_Interrupt_Priority : constant Positive := 31;
+
+ subtype Any_Priority is Integer range 0 .. 31;
+ subtype Priority is Any_Priority range 0 .. 30;
+ subtype Interrupt_Priority is Any_Priority range 31 .. 31;
+
+ Default_Priority : constant Priority := 15;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := False;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := True;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := True;
+ Stack_Check_Probes : constant Boolean := True;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := True;
+ GCC_ZCX_Support : constant Boolean := True;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := False;
+
+ --------------------------
+ -- Underlying Priorities --
+ ---------------------------
+
+ -- Important note: this section of the file must come AFTER the
+ -- definition of the system implementation parameters to ensure
+ -- that the value of these parameters is available for analysis
+ -- of the declarations here (using Rtsfind at compile time).
+
+ -- The underlying priorities table provides a generalized mechanism
+ -- for mapping from Ada priorities to system priorities. In some
+ -- cases a 1-1 mapping is not the convenient or optimal choice.
+
+ -- For DEC Threads OpenVMS, we use the full range of 31 priorities
+ -- in the Ada model, but map them by compression onto the more limited
+ -- range of priorities available in OpenVMS.
+
+ -- To replace the default values of the Underlying_Priorities mapping,
+ -- copy this source file into your build directory, edit the file to
+ -- reflect your desired behavior, and recompile with the command:
+
+ -- $ gcc -c -O3 -gnatpgn system.ads
+
+ -- then recompile the run-time parts that depend on this package:
+
+ -- $ gnatmake -a -gnatn -O3 <your application>
+
+ -- then force rebuilding your application if you need different options:
+
+ -- $ gnatmake -f <your options> <your application>
+
+ type Priorities_Mapping is array (Any_Priority) of Integer;
+ pragma Suppress_Initialization (Priorities_Mapping);
+ -- Suppress initialization in case gnat.adc specifies Normalize_Scalars
+
+ Underlying_Priorities : constant Priorities_Mapping :=
+
+ (Priority'First => 16,
+
+ 1 => 17,
+ 2 => 18,
+ 3 => 18,
+ 4 => 18,
+ 5 => 18,
+ 6 => 19,
+ 7 => 19,
+ 8 => 19,
+ 9 => 20,
+ 10 => 20,
+ 11 => 21,
+ 12 => 21,
+ 13 => 22,
+ 14 => 23,
+
+ Default_Priority => 24,
+
+ 16 => 25,
+ 17 => 25,
+ 18 => 25,
+ 19 => 26,
+ 20 => 26,
+ 21 => 26,
+ 22 => 27,
+ 23 => 27,
+ 24 => 27,
+ 25 => 28,
+ 26 => 28,
+ 27 => 29,
+ 28 => 29,
+ 29 => 30,
+
+ Priority'Last => 30,
+
+ Interrupt_Priority => 31);
+
+ ----------------------------
+ -- Special VMS Interfaces --
+ ----------------------------
+
+ procedure Lib_Stop (I : in Integer);
+ pragma Interface (C, Lib_Stop);
+ pragma Import_Procedure (Lib_Stop, "LIB$STOP", Mechanism => (Value));
+ -- Interface to VMS condition handling. Used by RTSfind and pragma
+ -- {Import,Export}_Exception. Put here because this is the only
+ -- VMS specific package that doesn't drag in tasking.
+
+end System;
diff --git a/gcc/ada/system-vms.ads b/gcc/ada/system-vms.ads
new file mode 100644
index 00000000000..fc4fb2e6d6f
--- /dev/null
+++ b/gcc/ada/system-vms.ads
@@ -0,0 +1,236 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (OpenVMS DEC Threads Version) --
+-- --
+-- Copyright (C) 1992-2004 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.01;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 32;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := Low_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ Max_Priority : constant Positive := 30;
+ Max_Interrupt_Priority : constant Positive := 31;
+
+ subtype Any_Priority is Integer range 0 .. 31;
+ subtype Priority is Any_Priority range 0 .. 30;
+ subtype Interrupt_Priority is Any_Priority range 31 .. 31;
+
+ Default_Priority : constant Priority := 15;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := False;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := True;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := True;
+ Stack_Check_Probes : constant Boolean := True;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := True;
+ GCC_ZCX_Support : constant Boolean := False;
+ Front_End_ZCX_Support : constant Boolean := True;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := False;
+
+ --------------------------
+ -- Underlying Priorities --
+ ---------------------------
+
+ -- Important note: this section of the file must come AFTER the
+ -- definition of the system implementation parameters to ensure
+ -- that the value of these parameters is available for analysis
+ -- of the declarations here (using Rtsfind at compile time).
+
+ -- The underlying priorities table provides a generalized mechanism
+ -- for mapping from Ada priorities to system priorities. In some
+ -- cases a 1-1 mapping is not the convenient or optimal choice.
+
+ -- For DEC Threads OpenVMS, we use the full range of 31 priorities
+ -- in the Ada model, but map them by compression onto the more limited
+ -- range of priorities available in OpenVMS.
+
+ -- To replace the default values of the Underlying_Priorities mapping,
+ -- copy this source file into your build directory, edit the file to
+ -- reflect your desired behavior, and recompile with the command:
+
+ -- $ gcc -c -O3 -gnatpgn system.ads
+
+ -- then recompile the run-time parts that depend on this package:
+
+ -- $ gnatmake -a -gnatn -O3 <your application>
+
+ -- then force rebuilding your application if you need different options:
+
+ -- $ gnatmake -f <your options> <your application>
+
+ type Priorities_Mapping is array (Any_Priority) of Integer;
+ pragma Suppress_Initialization (Priorities_Mapping);
+ -- Suppress initialization in case gnat.adc specifies Normalize_Scalars
+
+ Underlying_Priorities : constant Priorities_Mapping :=
+
+ (Priority'First => 16,
+
+ 1 => 17,
+ 2 => 18,
+ 3 => 18,
+ 4 => 18,
+ 5 => 18,
+ 6 => 19,
+ 7 => 19,
+ 8 => 19,
+ 9 => 20,
+ 10 => 20,
+ 11 => 21,
+ 12 => 21,
+ 13 => 22,
+ 14 => 23,
+
+ Default_Priority => 24,
+
+ 16 => 25,
+ 17 => 25,
+ 18 => 25,
+ 19 => 26,
+ 20 => 26,
+ 21 => 26,
+ 22 => 27,
+ 23 => 27,
+ 24 => 27,
+ 25 => 28,
+ 26 => 28,
+ 27 => 29,
+ 28 => 29,
+ 29 => 30,
+
+ Priority'Last => 30,
+
+ Interrupt_Priority => 31);
+
+ ----------------------------
+ -- Special VMS Interfaces --
+ ----------------------------
+
+ procedure Lib_Stop (I : in Integer);
+ pragma Interface (C, Lib_Stop);
+ pragma Import_Procedure (Lib_Stop, "LIB$STOP", Mechanism => (Value));
+ -- Interface to VMS condition handling. Used by RTSfind and pragma
+ -- {Import,Export}_Exception. Put here because this is the only
+ -- VMS specific package that doesn't drag in tasking.
+
+end System;
diff --git a/gcc/ada/system-vxworks-alpha.ads b/gcc/ada/system-vxworks-alpha.ads
new file mode 100644
index 00000000000..12bbec478ff
--- /dev/null
+++ b/gcc/ada/system-vxworks-alpha.ads
@@ -0,0 +1,158 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (VxWorks Version Alpha) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 1.0 / 60.0;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 64;
+ Memory_Size : constant := 2 ** 64;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := Low_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ -- 256 is reserved for the VxWorks kernel
+ -- 248 - 255 correspond to hardware interrupt levels 0 .. 7
+ -- 247 is a catchall default "interrupt" priority for signals,
+ -- allowing higher priority than normal tasks, but lower than
+ -- hardware priority levels. Protected Object ceilings can
+ -- override these values.
+ -- 246 is used by the Interrupt_Manager task
+
+ Max_Priority : constant Positive := 245;
+ Max_Interrupt_Priority : constant Positive := 255;
+
+ subtype Any_Priority is Integer range 0 .. 255;
+ subtype Priority is Any_Priority range 0 .. 245;
+ subtype Interrupt_Priority is Any_Priority range 246 .. 255;
+
+ Default_Priority : constant Priority := 122;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := False;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := False;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := False;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := True;
+ ZCX_By_Default : constant Boolean := False;
+ GCC_ZCX_Support : constant Boolean := False;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := False;
+
+end System;
diff --git a/gcc/ada/system-vxworks-m68k.ads b/gcc/ada/system-vxworks-m68k.ads
new file mode 100644
index 00000000000..3e1e3cf9895
--- /dev/null
+++ b/gcc/ada/system-vxworks-m68k.ads
@@ -0,0 +1,158 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (VxWorks version M68K) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 1.0 / 60.0;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 32;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := High_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ -- 256 is reserved for the VxWorks kernel
+ -- 248 - 255 correspond to hardware interrupt levels 0 .. 7
+ -- 247 is a catchall default "interrupt" priority for signals,
+ -- allowing higher priority than normal tasks, but lower than
+ -- hardware priority levels. Protected Object ceilings can
+ -- override these values.
+ -- 246 is used by the Interrupt_Manager task
+
+ Max_Priority : constant Positive := 245;
+ Max_Interrupt_Priority : constant Positive := 255;
+
+ subtype Any_Priority is Integer range 0 .. 255;
+ subtype Priority is Any_Priority range 0 .. 245;
+ subtype Interrupt_Priority is Any_Priority range 246 .. 255;
+
+ Default_Priority : constant Priority := 122;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := False;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := False;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := False;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := True;
+ ZCX_By_Default : constant Boolean := False;
+ GCC_ZCX_Support : constant Boolean := False;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := False;
+
+end System;
diff --git a/gcc/ada/system-vxworks-mips.ads b/gcc/ada/system-vxworks-mips.ads
new file mode 100644
index 00000000000..19c96d0d6ea
--- /dev/null
+++ b/gcc/ada/system-vxworks-mips.ads
@@ -0,0 +1,158 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (VxWorks Version Mips) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 1.0 / 60.0;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 32;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := High_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ -- 256 is reserved for the VxWorks kernel
+ -- 248 - 255 correspond to hardware interrupt levels 0 .. 7
+ -- 247 is a catchall default "interrupt" priority for signals,
+ -- allowing higher priority than normal tasks, but lower than
+ -- hardware priority levels. Protected Object ceilings can
+ -- override these values.
+ -- 246 is used by the Interrupt_Manager task
+
+ Max_Priority : constant Positive := 245;
+ Max_Interrupt_Priority : constant Positive := 255;
+
+ subtype Any_Priority is Integer range 0 .. 255;
+ subtype Priority is Any_Priority range 0 .. 245;
+ subtype Interrupt_Priority is Any_Priority range 246 .. 255;
+
+ Default_Priority : constant Priority := 122;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := False;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := False;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := False;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := True;
+ ZCX_By_Default : constant Boolean := False;
+ GCC_ZCX_Support : constant Boolean := False;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := False;
+
+end System;
diff --git a/gcc/ada/system-vxworks-ppc.ads b/gcc/ada/system-vxworks-ppc.ads
new file mode 100644
index 00000000000..bcb415c0277
--- /dev/null
+++ b/gcc/ada/system-vxworks-ppc.ads
@@ -0,0 +1,158 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (VxWorks Version PPC) --
+-- --
+-- Copyright (C) 1992-2004 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 1.0 / 60.0;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 32;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := High_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ -- 256 is reserved for the VxWorks kernel
+ -- 248 - 255 correspond to hardware interrupt levels 0 .. 7
+ -- 247 is a catchall default "interrupt" priority for signals,
+ -- allowing higher priority than normal tasks, but lower than
+ -- hardware priority levels. Protected Object ceilings can
+ -- override these values.
+ -- 246 is used by the Interrupt_Manager task
+
+ Max_Priority : constant Positive := 245;
+ Max_Interrupt_Priority : constant Positive := 255;
+
+ subtype Any_Priority is Integer range 0 .. 255;
+ subtype Priority is Any_Priority range 0 .. 245;
+ subtype Interrupt_Priority is Any_Priority range 246 .. 255;
+
+ Default_Priority : constant Priority := 122;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := False;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := False;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := True;
+ ZCX_By_Default : constant Boolean := False;
+ GCC_ZCX_Support : constant Boolean := True;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := False;
+
+end System;
diff --git a/gcc/ada/system-vxworks-sparcv9.ads b/gcc/ada/system-vxworks-sparcv9.ads
new file mode 100644
index 00000000000..8ddf3b06a6a
--- /dev/null
+++ b/gcc/ada/system-vxworks-sparcv9.ads
@@ -0,0 +1,160 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (VxWorks Version Sparc/64) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 1.0 / 60.0;
+
+ -- Storage-related Declarations
+
+ -- VxWorks for UltraSparc uses 64bit words but 32bit pointers
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 64;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := High_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ -- 256 is reserved for the VxWorks kernel
+ -- 248 - 255 correspond to hardware interrupt levels 0 .. 7
+ -- 247 is a catchall default "interrupt" priority for signals,
+ -- allowing higher priority than normal tasks, but lower than
+ -- hardware priority levels. Protected Object ceilings can
+ -- override these values.
+ -- 246 is used by the Interrupt_Manager task
+
+ Max_Priority : constant Positive := 245;
+ Max_Interrupt_Priority : constant Positive := 255;
+
+ subtype Any_Priority is Integer range 0 .. 255;
+ subtype Priority is Any_Priority range 0 .. 245;
+ subtype Interrupt_Priority is Any_Priority range 246 .. 255;
+
+ Default_Priority : constant Priority := 122;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := False;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := False;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := True;
+ ZCX_By_Default : constant Boolean := False;
+ GCC_ZCX_Support : constant Boolean := False;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := False;
+
+end System;
diff --git a/gcc/ada/system-vxworks-xscale.ads b/gcc/ada/system-vxworks-xscale.ads
new file mode 100644
index 00000000000..1fa021d5187
--- /dev/null
+++ b/gcc/ada/system-vxworks-xscale.ads
@@ -0,0 +1,158 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (VxWorks Version Xscale) --
+-- --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- 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- --
+-- 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, 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, --
+-- 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. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+pragma Pure (System);
+-- Note that we take advantage of the implementation permission to
+-- make this unit Pure instead of Preelaborable, see RM 13.7(36)
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := Integer'Last;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 1.0 / 60.0;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 32;
+ Memory_Size : constant := 2 ** 32;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order := Low_Order_First;
+
+ -- Priority-related Declarations (RM D.1)
+
+ -- 256 is reserved for the VxWorks kernel
+ -- 248 - 255 correspond to hardware interrupt levels 0 .. 7
+ -- 247 is a catchall default "interrupt" priority for signals,
+ -- allowing higher priority than normal tasks, but lower than
+ -- hardware priority levels. Protected Object ceilings can
+ -- override these values.
+ -- 246 is used by the Interrupt_Manager task
+
+ Max_Priority : constant Positive := 245;
+ Max_Interrupt_Priority : constant Positive := 255;
+
+ subtype Any_Priority is Integer range 0 .. 255;
+ subtype Priority is Any_Priority range 0 .. 245;
+ subtype Interrupt_Priority is Any_Priority range 246 .. 255;
+
+ Default_Priority : constant Priority := 122;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ AAMP : constant Boolean := False;
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := False;
+ Command_Line_Args : constant Boolean := False;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Functions_Return_By_DSP : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ OpenVMS : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := False;
+ Support_64_Bit_Divides : constant Boolean := True;
+ Support_Aggregates : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := True;
+ ZCX_By_Default : constant Boolean := False;
+ GCC_ZCX_Support : constant Boolean := False;
+ Front_End_ZCX_Support : constant Boolean := False;
+
+ -- Obsolete entries, to be removed eventually (bootstrap issues!)
+
+ High_Integrity_Mode : constant Boolean := False;
+ Long_Shifts_Inlined : constant Boolean := False;
+
+end System;
diff --git a/gcc/ada/targtyps.c b/gcc/ada/targtyps.c
index 465edb672ad..0e81142a835 100644
--- a/gcc/ada/targtyps.c
+++ b/gcc/ada/targtyps.c
@@ -6,7 +6,7 @@
* *
* Body *
* *
- * Copyright (C) 1992-2003 Free Software Foundation, Inc. *
+ * Copyright (C) 1992-2004 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- *
@@ -148,16 +148,6 @@ get_target_maximum_alignment (void)
return BIGGEST_ALIGNMENT / BITS_PER_UNIT;
}
-Boolean
-get_target_no_dollar_in_label (void)
-{
-#ifdef NO_DOLLAR_IN_LABEL
- return 1;
-#else
- return 0;
-#endif
-}
-
#ifndef FLOAT_WORDS_BIG_ENDIAN
#define FLOAT_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
#endif
diff --git a/gcc/ada/trans.c b/gcc/ada/trans.c
index 8b24761c3a5..117a95360dc 100644
--- a/gcc/ada/trans.c
+++ b/gcc/ada/trans.c
@@ -265,6 +265,8 @@ gnat_to_gnu (Node_Id gnat_node)
we do generates RTL and returns error_mark_node. */
if (!global_bindings_p ())
{
+ do_pending_stack_adjust ();
+ emit_queue ();
start_sequence ();
emit_note (NOTE_INSN_DELETED);
made_sequence = true;
@@ -285,14 +287,19 @@ gnat_to_gnu (Node_Id gnat_node)
gigi_abort (303);
}
+ do_pending_stack_adjust ();
+ emit_queue ();
gnu_root = make_expr_stmt_from_rtl (first_nondeleted_insn (get_insns ()),
gnat_node);
end_sequence ();
}
else if (made_sequence)
{
- rtx insns = first_nondeleted_insn (get_insns ());
+ rtx insns;
+ do_pending_stack_adjust ();
+ emit_queue ();
+ insns = first_nondeleted_insn (get_insns ());
end_sequence ();
if (insns)
@@ -2073,10 +2080,6 @@ tree_transform (Node_Id gnat_node)
case N_Label:
gnu_result = build_nt (LABEL_STMT, gnat_to_gnu (Identifier (gnat_node)));
- LABEL_STMT_FIRST_IN_EH (gnu_result)
- = (Present (Parent (gnat_node))
- && Nkind (Parent (gnat_node)) == N_Exception_Handler
- && First (Statements (Parent (gnat_node))) == gnat_node);
break;
case N_Null_Statement:
@@ -2111,26 +2114,31 @@ tree_transform (Node_Id gnat_node)
case N_If_Statement:
gnu_result = NULL_TREE;
- /* Make an IF_STMT for each of the "else if" parts. */
+ /* Make an IF_STMT for each of the "else if" parts. Avoid
+ non-determinism. */
if (Present (Elsif_Parts (gnat_node)))
for (gnat_temp = First (Elsif_Parts (gnat_node));
Present (gnat_temp); gnat_temp = Next (gnat_temp))
{
- tree gnu_elseif
- = build_nt (IF_STMT, gnat_to_gnu (Condition (gnat_temp)),
- build_block_stmt (Then_Statements (gnat_temp)),
- NULL_TREE, NULL_TREE);
-
- TREE_SLOC (gnu_elseif) = Sloc (Condition (gnat_temp));
- TREE_CHAIN (gnu_elseif) = gnu_result;
- TREE_TYPE (gnu_elseif) = void_type_node;
- gnu_result = gnu_elseif;
+ gnu_expr = make_node (IF_STMT);
+
+ IF_STMT_COND (gnu_expr) = gnat_to_gnu (Condition (gnat_temp));
+ IF_STMT_TRUE (gnu_expr)
+ = build_block_stmt (Then_Statements (gnat_temp));
+ IF_STMT_ELSE (gnu_expr) = IF_STMT_ELSEIF (gnu_expr) = NULL_TREE;
+ TREE_SLOC (gnu_expr) = Sloc (Condition (gnat_temp));
+ TREE_CHAIN (gnu_expr) = gnu_result;
+ TREE_TYPE (gnu_expr) = void_type_node;
+ gnu_result = gnu_expr;
}
- gnu_result = build_nt (IF_STMT, gnat_to_gnu (Condition (gnat_node)),
- build_block_stmt (Then_Statements (gnat_node)),
- nreverse (gnu_result),
- build_block_stmt (Else_Statements (gnat_node)));
+ /* Now make the IF_STMT. Also avoid non-determinism. */
+ gnu_expr = make_node (IF_STMT);
+ IF_STMT_COND (gnu_expr) = gnat_to_gnu (Condition (gnat_node));
+ IF_STMT_TRUE (gnu_expr) = build_block_stmt (Then_Statements (gnat_node));
+ IF_STMT_ELSEIF (gnu_expr) = nreverse (gnu_result);
+ IF_STMT_ELSE (gnu_expr) = build_block_stmt (Else_Statements (gnat_node));
+ gnu_result = gnu_expr;
break;
case N_Case_Statement:
@@ -2257,7 +2265,7 @@ tree_transform (Node_Id gnat_node)
/* Communicate to GCC that we are done with the current WHEN,
i.e. insert a "break" statement. */
expand_exit_something ();
- expand_end_bindings (getdecls (), kept_level_p (), -1);
+ expand_end_bindings (NULL_TREE, kept_level_p (), -1);
poplevel (kept_level_p (), 1, 0);
}
@@ -2396,7 +2404,7 @@ tree_transform (Node_Id gnat_node)
gnat_statement = Next (gnat_statement))
gnat_to_code (gnat_statement);
- expand_end_bindings (getdecls (), kept_level_p (), -1);
+ expand_end_bindings (NULL_TREE, kept_level_p (), -1);
poplevel (kept_level_p (), 1, 0);
gnu_block_stack = TREE_CHAIN (gnu_block_stack);
@@ -2422,7 +2430,7 @@ tree_transform (Node_Id gnat_node)
/* Close the nesting level that sourround the loop that was used to
declare the loop index variable. */
set_lineno (gnat_node, 1);
- expand_end_bindings (getdecls (), 1, -1);
+ expand_end_bindings (NULL_TREE, 1, -1);
poplevel (1, 1, 0);
}
@@ -2440,7 +2448,7 @@ tree_transform (Node_Id gnat_node)
expand_start_bindings (0);
process_decls (Declarations (gnat_node), Empty, Empty, 1, 1);
gnat_to_code (Handled_Statement_Sequence (gnat_node));
- expand_end_bindings (getdecls (), kept_level_p (), -1);
+ expand_end_bindings (NULL_TREE, kept_level_p (), -1);
poplevel (kept_level_p (), 1, 0);
gnu_block_stack = TREE_CHAIN (gnu_block_stack);
if (Present (Identifier (gnat_node)))
@@ -2649,6 +2657,9 @@ tree_transform (Node_Id gnat_node)
gnu_subprog_type = TREE_TYPE (gnu_subprog_decl);
+ /* ??? Temporarily do this to avoid GC throwing away outer stuff. */
+ ggc_push_context ();
+
/* Set the line number in the decl to correspond to that of
the body so that the line number notes are written
correctly. */
@@ -2723,7 +2734,7 @@ tree_transform (Node_Id gnat_node)
will be present and any OUT parameters will be handled there. */
gnat_to_code (Handled_Statement_Sequence (gnat_node));
- expand_end_bindings (getdecls (), kept_level_p (), -1);
+ expand_end_bindings (NULL_TREE, kept_level_p (), -1);
poplevel (kept_level_p (), 1, 0);
gnu_block_stack = TREE_CHAIN (gnu_block_stack);
@@ -2769,15 +2780,12 @@ tree_transform (Node_Id gnat_node)
mark_out_of_scope (Defining_Unit_Name (Specification (gnat_node)));
write_symbols = save_write_symbols;
debug_hooks = save_debug_hooks;
+ ggc_pop_context ();
}
break;
case N_Function_Call:
case N_Procedure_Call_Statement:
-
- if (type_annotate_only)
- break;
-
{
/* The GCC node corresponding to the GNAT subprogram name. This can
either be a FUNCTION_DECL node if we are dealing with a standard
@@ -2792,6 +2800,7 @@ tree_transform (Node_Id gnat_node)
Node_Id gnat_actual;
tree gnu_actual_list = NULL_TREE;
tree gnu_name_list = NULL_TREE;
+ tree gnu_before_list = NULL_TREE;
tree gnu_after_list = NULL_TREE;
tree gnu_subprog_call;
@@ -2827,8 +2836,9 @@ tree_transform (Node_Id gnat_node)
build_call_raise (PE_Stubbed_Subprogram_Called));
}
else
- expand_expr_stmt
- (build_call_raise (PE_Stubbed_Subprogram_Called));
+ gnu_result
+ = build_nt (EXPR_STMT,
+ build_call_raise (PE_Stubbed_Subprogram_Called));
break;
}
@@ -2920,10 +2930,15 @@ tree_transform (Node_Id gnat_node)
}
/* Set up to move the copy back to the original. */
- gnu_after_list = tree_cons (gnu_copy, gnu_actual,
- gnu_after_list);
-
- gnu_name = gnu_actual;
+ gnu_temp
+ = build_nt (EXPR_STMT,
+ build (MODIFY_EXPR, TREE_TYPE (gnu_copy),
+ gnu_copy, gnu_actual));
+
+ TREE_TYPE (gnu_temp) = void_type_node;
+ TREE_SLOC (gnu_temp) = Sloc (gnat_actual);
+ TREE_CHAIN (gnu_temp) = gnu_after_list;
+ gnu_after_list = gnu_temp;
}
}
@@ -3115,6 +3130,7 @@ tree_transform (Node_Id gnat_node)
gnu_result);
gnu_result_type = get_unpadded_type (Etype (gnat_node));
+ break;
}
/* If this is the case where the GNAT tree contains a procedure call
@@ -3218,26 +3234,29 @@ tree_transform (Node_Id gnat_node)
gnu_result);
}
- set_lineno (gnat_node, 1);
- expand_expr_stmt (build_binary_op (MODIFY_EXPR, NULL_TREE,
- gnu_actual, gnu_result));
+ gnu_result
+ = build_nt (EXPR_STMT,
+ build_binary_op (MODIFY_EXPR, NULL_TREE,
+ gnu_actual, gnu_result));
+ TREE_TYPE (gnu_result) = void_type_node;
+ TREE_SLOC (gnu_result) = Sloc (gnat_actual);
+ TREE_CHAIN (gnu_result) = gnu_before_list;
+ gnu_before_list = gnu_result;
scalar_return_list = TREE_CHAIN (scalar_return_list);
gnu_name_list = TREE_CHAIN (gnu_name_list);
}
}
else
{
- set_lineno (gnat_node, 1);
- expand_expr_stmt (gnu_subprog_call);
+ gnu_before_list = build_nt (EXPR_STMT, gnu_subprog_call);
+ TREE_TYPE (gnu_before_list) = void_type_node;
+ TREE_SLOC (gnu_before_list) = Sloc (gnat_node);
}
- /* Handle anything we need to assign back. */
- for (gnu_expr = gnu_after_list;
- gnu_expr;
- gnu_expr = TREE_CHAIN (gnu_expr))
- expand_expr_stmt (build_binary_op (MODIFY_EXPR, NULL_TREE,
- TREE_PURPOSE (gnu_expr),
- TREE_VALUE (gnu_expr)));
+ gnu_result = chainon (nreverse (gnu_before_list),
+ nreverse (gnu_after_list));
+ if (TREE_CHAIN (gnu_result))
+ gnu_result = build_nt (BLOCK_STMT, gnu_result);
}
break;
@@ -3521,7 +3540,7 @@ tree_transform (Node_Id gnat_node)
gnu_except_ptr_stack = TREE_CHAIN (gnu_except_ptr_stack);
/* End the binding level dedicated to the exception handlers. */
- expand_end_bindings (getdecls (), kept_level_p (), -1);
+ expand_end_bindings (NULL_TREE, kept_level_p (), -1);
poplevel (kept_level_p (), 1, 0);
/* End the "if" on setjmp. Note that we have arranged things so
@@ -3584,7 +3603,7 @@ tree_transform (Node_Id gnat_node)
/* Close the binding level we made, if any. */
if (exitable_binding_for_block)
{
- expand_end_bindings (getdecls (), kept_level_p (), -1);
+ expand_end_bindings (NULL_TREE, kept_level_p (), -1);
poplevel (kept_level_p (), 1, 0);
}
}
@@ -3792,7 +3811,7 @@ tree_transform (Node_Id gnat_node)
if (Exception_Mechanism == GCC_ZCX)
{
/* Tell the back end that we're done with the current handler. */
- expand_end_bindings (getdecls (), kept_level_p (), -1);
+ expand_end_bindings (NULL_TREE, kept_level_p (), -1);
poplevel (kept_level_p (), 1, 0);
expand_end_catch ();
@@ -3895,22 +3914,10 @@ tree_transform (Node_Id gnat_node)
gnu_input_list = nreverse (gnu_input_list);
gnu_output_list = nreverse (gnu_output_list);
gnu_orig_out_list = nreverse (gnu_orig_out_list);
- expand_asm_operands (gnu_template, gnu_output_list, gnu_input_list,
- gnu_clobber_list, Is_Asm_Volatile (gnat_node),
- input_location);
-
- /* Copy all the intermediate outputs into the specified outputs. */
- for (; gnu_output_list;
- (gnu_output_list = TREE_CHAIN (gnu_output_list),
- gnu_orig_out_list = TREE_CHAIN (gnu_orig_out_list)))
- if (TREE_VALUE (gnu_orig_out_list) != TREE_VALUE (gnu_output_list))
- {
- expand_expr_stmt
- (build_binary_op (MODIFY_EXPR, NULL_TREE,
- TREE_VALUE (gnu_orig_out_list),
- TREE_VALUE (gnu_output_list)));
- free_temp_slots ();
- }
+ gnu_result = build_nt (ASM_STMT, gnu_template, gnu_output_list,
+ gnu_orig_out_list, gnu_input_list,
+ gnu_clobber_list);
+ TREE_THIS_VOLATILE (gnu_result) = Is_Asm_Volatile (gnat_node);
}
break;
@@ -3974,11 +3981,12 @@ tree_transform (Node_Id gnat_node)
gnu_ptr, gnu_byte_offset);
}
- set_lineno (gnat_node, 1);
- expand_expr_stmt
- (build_call_alloc_dealloc (gnu_ptr, gnu_obj_size, align,
- Procedure_To_Call (gnat_node),
- Storage_Pool (gnat_node), gnat_node));
+ gnu_result
+ = build_nt (EXPR_STMT,
+ build_call_alloc_dealloc
+ (gnu_ptr, gnu_obj_size, align,
+ Procedure_To_Call (gnat_node),
+ Storage_Pool (gnat_node), gnat_node));
}
break;
@@ -3997,15 +4005,14 @@ tree_transform (Node_Id gnat_node)
is one. */
if (TREE_CODE (gnu_result_type) == VOID_TYPE)
{
- set_lineno (gnat_node, 1);
-
- if (Present (Condition (gnat_node)))
- expand_start_cond (gnat_to_gnu (Condition (gnat_node)), 0);
+ gnu_result = build_nt (EXPR_STMT, gnu_result);
+ TREE_TYPE (gnu_result) = void_type_node;
+ TREE_SLOC (gnu_result) = Sloc (gnat_node);
- expand_expr_stmt (gnu_result);
if (Present (Condition (gnat_node)))
- expand_end_cond ();
- gnu_result = error_mark_node;
+ gnu_result = build_nt (IF_STMT,
+ gnat_to_gnu (Condition (gnat_node)),
+ gnu_result, NULL_TREE, NULL_TREE);
}
else
gnu_result = build1 (NULL_EXPR, gnu_result_type, gnu_result);
@@ -4235,7 +4242,7 @@ make_expr_stmt_from_rtl (rtx insns, Node_Id gnat_node)
void
gnat_expand_stmt (tree gnu_stmt)
{
- tree gnu_elmt;
+ tree gnu_elmt, gnu_elmt_2;
if (TREE_SLOC (gnu_stmt))
set_lineno_from_sloc (TREE_SLOC (gnu_stmt), 1);
@@ -4283,11 +4290,6 @@ gnat_expand_stmt (tree gnu_stmt)
case LABEL_STMT:
expand_label (LABEL_STMT_LABEL (gnu_stmt));
- if (LABEL_STMT_FIRST_IN_EH (gnu_stmt))
- nonlocal_goto_handler_labels
- = gen_rtx_EXPR_LIST (VOIDmode,
- label_rtx (LABEL_STMT_LABEL (gnu_stmt)),
- nonlocal_goto_handler_labels);
break;
case RETURN_STMT:
@@ -4299,6 +4301,29 @@ gnat_expand_stmt (tree gnu_stmt)
expand_null_return ();
break;
+ case ASM_STMT:
+ expand_asm_operands (ASM_STMT_TEMPLATE (gnu_stmt),
+ ASM_STMT_OUTPUT (gnu_stmt),
+ ASM_STMT_INPUT (gnu_stmt),
+ ASM_STMT_CLOBBER (gnu_stmt),
+ TREE_THIS_VOLATILE (gnu_stmt), input_location);
+
+ /* Copy all the intermediate outputs into the specified outputs. */
+ for ((gnu_elmt = ASM_STMT_OUTPUT (gnu_stmt),
+ gnu_elmt_2 = ASM_STMT_ORIG_OUT (gnu_stmt));
+ gnu_elmt;
+ (gnu_elmt = TREE_CHAIN (gnu_elmt),
+ gnu_elmt_2 = TREE_CHAIN (gnu_elmt_2)))
+ if (TREE_VALUE (gnu_elmt) != TREE_VALUE (gnu_elmt_2))
+ {
+ expand_expr_stmt
+ (build_binary_op (MODIFY_EXPR, NULL_TREE,
+ TREE_VALUE (gnu_elmt_2),
+ TREE_VALUE (gnu_elmt)));
+ free_temp_slots ();
+ }
+ break;
+
default:
abort ();
}
@@ -5406,7 +5431,6 @@ gnat_stabilize_reference_1 (tree e, int force)
case 'x':
case 't':
case 'd':
- case 'b':
case '<':
case 's':
case 'e':
@@ -5518,7 +5542,7 @@ build_unit_elab (Entity_Id gnat_unit, int body_p, tree gnu_elab_list)
break;
}
- expand_end_bindings (getdecls (), kept_level_p (), -1);
+ expand_end_bindings (NULL_TREE, kept_level_p (), -1);
poplevel (kept_level_p (), 1, 0);
gnu_block_stack = TREE_CHAIN (gnu_block_stack);
end_subprog_body ();
diff --git a/gcc/ada/types.ads b/gcc/ada/types.ads
index a2c15984cf6..75a2acbc16d 100644
--- a/gcc/ada/types.ads
+++ b/gcc/ada/types.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2004 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- --
@@ -785,6 +785,7 @@ pragma Preelaborate (Types);
PE_Potentially_Blocking_Operation,
PE_Stubbed_Subprogram_Called,
PE_Unchecked_Union_Restriction,
+ PE_Illegal_RACW_E_4_18,
SE_Empty_Storage_Pool,
SE_Explicit_Raise,
@@ -798,7 +799,7 @@ pragma Preelaborate (Types);
subtype RT_PE_Exceptions is RT_Exception_Code range
PE_Access_Before_Elaboration ..
- PE_Unchecked_Union_Restriction;
+ PE_Illegal_RACW_E_4_18;
subtype RT_SE_Exceptions is RT_Exception_Code range
SE_Empty_Storage_Pool ..
diff --git a/gcc/ada/types.h b/gcc/ada/types.h
index 19d2fc7f03e..b4c4eb4419f 100644
--- a/gcc/ada/types.h
+++ b/gcc/ada/types.h
@@ -6,7 +6,7 @@
* *
* C Header File *
* *
- * Copyright (C) 1992-2003, Free Software Foundation, Inc. *
+ * Copyright (C) 1992-2004, 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- *
@@ -357,10 +357,11 @@ typedef Int Mechanism_Type;
#define PE_Potentially_Blocking_Operation 21
#define PE_Stubbed_Subprogram_Called 22
#define PE_Unchecked_Union_Restriction 23
-#define SE_Empty_Storage_Pool 24
-#define SE_Explicit_Raise 25
-#define SE_Infinite_Recursion 26
-#define SE_Object_Too_Large 27
-#define SE_Restriction_Violation 28
-
-#define LAST_REASON_CODE 28
+#define PE_Illegal_RACW_E_4_18 24
+#define SE_Empty_Storage_Pool 25
+#define SE_Explicit_Raise 26
+#define SE_Infinite_Recursion 27
+#define SE_Object_Too_Large 28
+#define SE_Restriction_Violation 29
+
+#define LAST_REASON_CODE 29
diff --git a/gcc/ada/usage.adb b/gcc/ada/usage.adb
index 3adf3044049..b5903da0190 100644
--- a/gcc/ada/usage.adb
+++ b/gcc/ada/usage.adb
@@ -269,10 +269,12 @@ begin
Write_Switch_Char ("Q");
Write_Line ("Don't quit, write ali/tree file even if compile errors");
- -- Line for -gnatR switch
+ -- Lines for -gnatR switch
Write_Switch_Char ("R?");
- Write_Line ("List rep inf (?=0/1/2/3 for none/types/all/variable)");
+ Write_Line ("List rep info (?=0/1/2/3 for none/types/all/variable)");
+ Write_Switch_Char ("R?s");
+ Write_Line ("List rep info to file.rep instead of standard output");
-- Lines for -gnats switch
diff --git a/gcc/ada/utils.c b/gcc/ada/utils.c
index 8b0bf8183dd..6022dbfe758 100644
--- a/gcc/ada/utils.c
+++ b/gcc/ada/utils.c
@@ -310,7 +310,10 @@ poplevel (int keep, int reverse, int functionbody)
&& DECL_INITIAL (decl_node) != 0)
{
push_function_context ();
+ /* ??? This is temporary. */
+ ggc_push_context ();
output_inline_function (decl_node);
+ ggc_pop_context ();
pop_function_context ();
}
@@ -685,6 +688,18 @@ init_gigi_decls (tree long_long_float_type, tree exception_type)
DECL_BUILT_IN_CLASS (setjmp_decl) = BUILT_IN_NORMAL;
DECL_FUNCTION_CODE (setjmp_decl) = BUILT_IN_SETJMP;
+ /* update_setjmp_buf updates a setjmp buffer from the current stack pointer
+ address. */
+ update_setjmp_buf_decl
+ = create_subprog_decl
+ (get_identifier ("__builtin_update_setjmp_buf"), NULL_TREE,
+ build_function_type (void_type_node,
+ tree_cons (NULL_TREE, jmpbuf_ptr_type, endlink)),
+ NULL_TREE, 0, 1, 1, 0);
+
+ DECL_BUILT_IN_CLASS (update_setjmp_buf_decl) = BUILT_IN_NORMAL;
+ DECL_FUNCTION_CODE (update_setjmp_buf_decl) = BUILT_IN_UPDATE_SETJMP_BUF;
+
main_identifier_node = get_identifier ("main");
}
@@ -1333,7 +1348,6 @@ create_var_decl (tree var_name,
|| (static_flag && ! init_const)))
assign_init = var_init, var_init = 0;
- DECL_COMMON (var_decl) = !flag_no_common;
DECL_INITIAL (var_decl) = var_init;
TREE_READONLY (var_decl) = const_flag;
DECL_EXTERNAL (var_decl) = extern_flag;
@@ -1606,7 +1620,6 @@ process_attributes (tree decl, struct attrib *attr_list)
DECL_SECTION_NAME (decl)
= build_string (IDENTIFIER_LENGTH (attr_list->name),
IDENTIFIER_POINTER (attr_list->name));
- DECL_COMMON (decl) = 0;
}
else
post_error ("?section attributes are not supported for this target",
@@ -1838,9 +1851,7 @@ static int function_nesting_depth;
void
begin_subprog_body (tree subprog_decl)
{
- tree param_decl_list;
tree param_decl;
- tree next_param;
if (function_nesting_depth++ != 0)
push_function_context ();
@@ -1856,32 +1867,14 @@ begin_subprog_body (tree subprog_decl)
the C sense! */
TREE_STATIC (subprog_decl) = 1;
- /* Enter a new binding level. */
+ /* Enter a new binding level and show that all the parameters belong to
+ this function. */
current_function_decl = subprog_decl;
pushlevel (0);
- /* Push all the PARM_DECL nodes onto the current scope (i.e. the scope of the
- subprogram body) so that they can be recognized as local variables in the
- subprogram.
-
- The list of PARM_DECL nodes is stored in the right order in
- DECL_ARGUMENTS. Since ..._DECL nodes get stored in the reverse order in
- which they are transmitted to `pushdecl' we need to reverse the list of
- PARM_DECLs if we want it to be stored in the right order. The reason why
- we want to make sure the PARM_DECLs are stored in the correct order is
- that this list will be retrieved in a few lines with a call to `getdecl'
- to store it back into the DECL_ARGUMENTS field. */
- param_decl_list = nreverse (DECL_ARGUMENTS (subprog_decl));
-
- for (param_decl = param_decl_list; param_decl; param_decl = next_param)
- {
- next_param = TREE_CHAIN (param_decl);
- TREE_CHAIN (param_decl) = NULL;
- pushdecl (param_decl);
- }
-
- /* Store back the PARM_DECL nodes. They appear in the right order. */
- DECL_ARGUMENTS (subprog_decl) = getdecls ();
+ for (param_decl = DECL_ARGUMENTS (subprog_decl); param_decl;
+ param_decl = TREE_CHAIN (param_decl))
+ DECL_CONTEXT (param_decl) = subprog_decl;
init_function_start (subprog_decl);
expand_function_start (subprog_decl, 0);
@@ -2222,12 +2215,12 @@ max_size (tree exp, int max_p)
if (code == SAVE_EXPR)
return exp;
else if (code == COND_EXPR)
- return fold (build (MAX_EXPR, type,
+ return fold (build (max_p ? MAX_EXPR : MIN_EXPR, type,
max_size (TREE_OPERAND (exp, 1), max_p),
max_size (TREE_OPERAND (exp, 2), max_p)));
else if (code == CALL_EXPR && TREE_OPERAND (exp, 1) != 0)
return build (CALL_EXPR, type, TREE_OPERAND (exp, 0),
- max_size (TREE_OPERAND (exp, 1), max_p));
+ max_size (TREE_OPERAND (exp, 1), max_p), NULL);
}
}
@@ -2451,13 +2444,12 @@ build_vms_descriptor (tree type, Mechanism_Type mech, Entity_Id gnat_entity)
field_list
= chainon (field_list,
- make_descriptor_field ("POINTER",
- build_pointer_type (type),
- record_type,
- build1 (ADDR_EXPR,
- build_pointer_type (type),
- build (PLACEHOLDER_EXPR,
- type))));
+ make_descriptor_field
+ ("POINTER",
+ build_pointer_type_for_mode (type, SImode, false), record_type,
+ build1 (ADDR_EXPR,
+ build_pointer_type_for_mode (type, SImode, false),
+ build (PLACEHOLDER_EXPR, type))));
switch (mech)
{
@@ -2527,8 +2519,13 @@ build_vms_descriptor (tree type, Mechanism_Type mech, Entity_Id gnat_entity)
field_list
= chainon (field_list,
make_descriptor_field
- ("A0", build_pointer_type (inner_type), record_type,
- build1 (ADDR_EXPR, build_pointer_type (inner_type), tem)));
+ ("A0",
+ build_pointer_type_for_mode (inner_type, SImode, false),
+ record_type,
+ build1 (ADDR_EXPR,
+ build_pointer_type_for_mode (inner_type, SImode,
+ false),
+ tem)));
/* Next come the addressing coefficients. */
tem = size_int (1);
@@ -2991,11 +2988,13 @@ convert (tree type, tree expr)
case STRING_CST:
case CONSTRUCTOR:
/* If we are converting a STRING_CST to another constrained array type,
- just make a new one in the proper type. Likewise for a
- CONSTRUCTOR. */
+ just make a new one in the proper type. Likewise for
+ CONSTRUCTOR if the alias sets are the same. */
if (code == ecode && AGGREGATE_TYPE_P (etype)
&& ! (TREE_CODE (TYPE_SIZE (etype)) == INTEGER_CST
- && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST))
+ && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
+ && (TREE_CODE (expr) == STRING_CST
+ || get_alias_set (etype) == get_alias_set (type)))
{
expr = copy_node (expr);
TREE_TYPE (expr) = type;
@@ -3011,7 +3010,8 @@ convert (tree type, tree expr)
if (code == ecode && TYPE_MODE (type) == TYPE_MODE (etype)
&& AGGREGATE_TYPE_P (type) && AGGREGATE_TYPE_P (etype)
&& TYPE_ALIGN (type) == TYPE_ALIGN (etype)
- && operand_equal_p (TYPE_SIZE (type), TYPE_SIZE (etype), 0))
+ && operand_equal_p (TYPE_SIZE (type), TYPE_SIZE (etype), 0)
+ && get_alias_set (type) == get_alias_set (etype))
return build (COMPONENT_REF, type, TREE_OPERAND (expr, 0),
TREE_OPERAND (expr, 1));
@@ -3436,7 +3436,8 @@ unchecked_convert (tree type, tree expr, int notrunc_p)
/* If the sizes of the types differ and this is an VIEW_CONVERT_EXPR,
show no longer constant. */
if (TREE_CODE (expr) == VIEW_CONVERT_EXPR
- && ! operand_equal_p (TYPE_SIZE_UNIT (type), TYPE_SIZE_UNIT (etype), 1))
+ && ! operand_equal_p (TYPE_SIZE_UNIT (type), TYPE_SIZE_UNIT (etype),
+ OEP_ONLY_CONST))
TREE_CONSTANT (expr) = 0;
return expr;
diff --git a/gcc/ada/utils2.c b/gcc/ada/utils2.c
index 3c0e26b8da0..5882d094b5d 100644
--- a/gcc/ada/utils2.c
+++ b/gcc/ada/utils2.c
@@ -1225,9 +1225,12 @@ build_unary_op (enum tree_code op_code, tree result_type, tree operand)
}
if (TYPE_FAT_POINTER_P (type))
- result = build1 (UNCONSTRAINED_ARRAY_REF,
- TYPE_UNCONSTRAINED_ARRAY (type), operand);
-
+ {
+ result = build1 (UNCONSTRAINED_ARRAY_REF,
+ TYPE_UNCONSTRAINED_ARRAY (type), operand);
+ TREE_READONLY (result) = TREE_STATIC (result)
+ = TYPE_READONLY (TYPE_UNCONSTRAINED_ARRAY (type));
+ }
else if (TREE_CODE (operand) == ADDR_EXPR)
result = TREE_OPERAND (operand, 0);
diff --git a/gcc/ada/vms_data.ads b/gcc/ada/vms_data.ads
index fd9cb34057d..ca621b033b6 100644
--- a/gcc/ada/vms_data.ads
+++ b/gcc/ada/vms_data.ads
@@ -191,7 +191,6 @@ package VMS_Data is
-- Switches for GNAT BIND --
----------------------------
-
S_Bind_Bind : aliased constant S := "/BIND_FILE=" &
"ADA " &
"-A " &
@@ -490,7 +489,6 @@ package VMS_Data is
"!-b,!-v";
-- NODOC (see /REPORT_ERRORS)
-
S_Bind_Restr : aliased constant S := "/RESTRICTION_LIST " &
"-r";
-- /NORESTRICTION_LIST (D)
@@ -814,6 +812,13 @@ package VMS_Data is
--
-- Output a message explaining the usage of gnatclean.
+ S_Clean_Index : aliased constant S := "/SOURCE_INDEX=#" &
+ "-i#";
+ -- /SOURCE_INDEX=nnn
+ --
+ -- Specifies the index of the units in the source file
+ -- By default, source files are mono-unit and there is no index
+
S_Clean_Mess : aliased constant S := "/MESSAGES_PROJECT_FILE=" &
"DEFAULT " &
"-vP0 " &
@@ -833,7 +838,6 @@ package VMS_Data is
-- HIGH A great number of messages are output, most of them not
-- being useful for the user.
-
S_Clean_Object : aliased constant S := "/OBJECT_SEARCH=*" &
"-aO*";
-- /OBJECT_SEARCH=(directory,...)
@@ -892,6 +896,7 @@ package VMS_Data is
S_Clean_Ext 'Access,
S_Clean_Full 'Access,
S_Clean_Help 'Access,
+ S_Clean_Index 'Access,
S_Clean_Mess 'Access,
S_Clean_Object 'Access,
S_Clean_Project'Access,
@@ -3738,6 +3743,15 @@ package VMS_Data is
-- are found on the Ada object path, the new object and ALI files are
-- created in the directory containing the source being compiled.
+ S_Make_Index : aliased constant S := "/SOURCE_INDEX=#" &
+ "-eI#";
+ -- /SOURCE_INDEX=nnn
+ --
+ -- Specifies the index of the units in the source file
+ -- By default, source files are mono-unit and there is no index
+ -- When /SOURCE_INDEX=nnn is specified, only one main may be specified
+ -- on the command line.
+
S_Make_Library : aliased constant S := "/LIBRARY_SEARCH=*" &
"-L*";
-- /LIBRARY_SEARCH=(directory[,...])
@@ -3825,6 +3839,14 @@ package VMS_Data is
-- will execute the elaboration routines of the package and its closure,
-- then the finalization routines.
+ S_Make_Nonpro : aliased constant S := "/NON_PROJECT_UNIT_COMPILATION " &
+ "-x";
+ -- /NON_PROJECT_UNIT_COMPILATION
+ --
+ -- Normally, when using project files, a unit that is not part of any
+ -- project file, cannot be compile. These units may be compile, when
+ -- needed, if this qualifier is specified.
+
S_Make_Nostinc : aliased constant S := "/NOSTD_INCLUDES " &
"-nostdinc";
-- /NOSTD_INCLUDES
@@ -3965,6 +3987,7 @@ package VMS_Data is
S_Make_Force 'Access,
S_Make_Full 'Access,
S_Make_Inplace 'Access,
+ S_Make_Index 'Access,
S_Make_Library 'Access,
S_Make_Link 'Access,
S_Make_Make 'Access,
@@ -3973,6 +3996,7 @@ package VMS_Data is
S_Make_Minimal 'Access,
S_Make_Nolink 'Access,
S_Make_Nomain 'Access,
+ S_Make_Nonpro 'Access,
S_Make_Nostinc 'Access,
S_Make_Nostlib 'Access,
S_Make_Object 'Access,
diff --git a/gcc/attribs.c b/gcc/attribs.c
index 5d8450ff601..671528ccacd 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -294,7 +294,26 @@ decl_attributes (tree *node, tree attributes, int flags)
if (DECL_P (*anode))
DECL_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
- TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
+ {
+ TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
+ /* If this is the main variant, also push the attributes
+ out to the other variants. */
+ if (*anode == TYPE_MAIN_VARIANT (*anode))
+ {
+ tree variant;
+ for (variant = *anode; variant;
+ variant = TYPE_NEXT_VARIANT (variant))
+ {
+ if (TYPE_ATTRIBUTES (variant) == old_attrs)
+ TYPE_ATTRIBUTES (variant)
+ = TYPE_ATTRIBUTES (*anode);
+ else if (!lookup_attribute
+ (spec->name, TYPE_ATTRIBUTES (variant)))
+ TYPE_ATTRIBUTES (variant) = tree_cons
+ (name, args, TYPE_ATTRIBUTES (variant));
+ }
+ }
+ }
else
*anode = build_type_attribute_variant (*anode,
tree_cons (name, args,
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 2c3ef581111..c64b7b0d556 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -27,9 +27,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "varray.h"
#include "partition.h"
#include "hard-reg-set.h"
+#include "predict.h"
/* Head of register set linked list. */
typedef bitmap_head regset_head;
+
/* A pointer to a regset_head. */
typedef bitmap regset;
@@ -121,18 +123,24 @@ do { \
typedef HOST_WIDEST_INT gcov_type;
/* Control flow edge information. */
-typedef struct edge_def {
+struct edge_def GTY((chain_next ("%h.pred_next")))
+{
/* Links through the predecessor and successor lists. */
- struct edge_def *pred_next, *succ_next;
+ struct edge_def *pred_next;
+ struct edge_def *succ_next;
/* The two blocks at the ends of the edge. */
- struct basic_block_def *src, *dest;
+ struct basic_block_def *src;
+ struct basic_block_def *dest;
/* Instructions queued on the edge. */
- rtx insns;
+ union edge_def_insns {
+ rtx GTY ((tag ("0"))) r;
+ tree GTY ((tag ("1"))) t;
+ } GTY ((desc ("ir_type ()"))) insns;
/* Auxiliary info specific to a pass. */
- void *aux;
+ PTR GTY ((skip (""))) aux;
int flags; /* see EDGE_* below */
int probability; /* biased by REG_BR_PROB_BASE */
@@ -140,7 +148,9 @@ typedef struct edge_def {
in profile.c */
bool crossing_edge; /* Crosses between hot and cold sections, when
we do partitioning. */
-} *edge;
+};
+
+typedef struct edge_def *edge;
#define EDGE_FALLTHRU 1 /* 'Straight line' flow */
#define EDGE_ABNORMAL 2 /* Strange flow, like computed
@@ -155,7 +165,13 @@ typedef struct edge_def {
#define EDGE_IRREDUCIBLE_LOOP 128 /* Part of irreducible loop. */
#define EDGE_SIBCALL 256 /* Edge from sibcall to exit. */
#define EDGE_LOOP_EXIT 512 /* Exit of a loop. */
-#define EDGE_ALL_FLAGS 1023
+#define EDGE_TRUE_VALUE 1024 /* Edge taken when controlling
+ predicate is non zero. */
+#define EDGE_FALSE_VALUE 2048 /* Edge taken when controlling
+ predicate is zero. */
+#define EDGE_EXECUTABLE 4096 /* Edge is executable. Only
+ valid during SSA-CCP. */
+#define EDGE_ALL_FLAGS 8191
#define EDGE_COMPLEX (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH)
@@ -167,6 +183,9 @@ extern const struct gcov_ctr_summary *profile_info;
struct loop;
struct loops;
+/* Declared in tree-flow.h. */
+struct bb_ann_d;
+
/* A basic block is a sequence of instructions with only entry and
only one exit. If any one of the instructions are executed, they
will all be executed, and in sequence from first to last.
@@ -193,51 +212,54 @@ struct loops;
basic blocks. */
/* Basic block information indexed by block number. */
-typedef struct basic_block_def {
+struct basic_block_def GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb")))
+{
/* The first and last insns of the block. */
- rtx head_, end_;
+ rtx head_;
+ rtx end_;
- /* The first and last trees of the block. */
- tree head_tree;
- tree end_tree;
+ /* Pointers to the first and last trees of the block. */
+ tree stmt_list;
/* The edges into and out of the block. */
- edge pred, succ;
+ edge pred;
+ edge succ;
/* Liveness info. */
/* The registers that are modified within this in block. */
- regset local_set;
+ bitmap GTY ((skip (""))) local_set;
/* The registers that are conditionally modified within this block.
In other words, registers that are set only as part of a
COND_EXEC. */
- regset cond_local_set;
+ bitmap GTY ((skip (""))) cond_local_set;
/* The registers that are live on entry to this block.
Note that in SSA form, global_live_at_start does not reflect the
use of regs in phi functions, since the liveness of these regs
may depend on which edge was taken into the block. */
- regset global_live_at_start;
+ bitmap GTY ((skip (""))) global_live_at_start;
/* The registers that are live on exit from this block. */
- regset global_live_at_end;
+ bitmap GTY ((skip (""))) global_live_at_end;
/* Auxiliary info specific to a pass. */
- void *aux;
+ PTR GTY ((skip (""))) aux;
/* The index of this block. */
int index;
/* Previous and next blocks in the chain. */
- struct basic_block_def *prev_bb, *next_bb;
+ struct basic_block_def *prev_bb;
+ struct basic_block_def *next_bb;
/* The loop depth of this block. */
int loop_depth;
- /* Outermost loop containing the block. */
- struct loop *loop_father;
+ /* Innermost loop containing the block. */
+ struct loop * GTY ((skip (""))) loop_father;
/* The dominance and postdominance information node. */
- struct et_node *dom[2];
+ struct et_node * GTY ((skip (""))) dom[2];
/* Expected number of executions: calculated in profile.c. */
gcov_type count;
@@ -251,9 +273,31 @@ typedef struct basic_block_def {
/* Which section block belongs in, when partitioning basic blocks. */
int partition;
- /* Additional data maintained by cfg_layout routines. */
- struct reorder_block_def *rbi;
-} *basic_block;
+ /* The data used by basic block copying and reordering functions. */
+ struct reorder_block_def * GTY ((skip (""))) rbi;
+
+ /* Annotations used at the tree level. */
+ struct bb_ann_d *tree_annotations;
+};
+
+typedef struct basic_block_def *basic_block;
+
+/* Structure to hold information about the blocks during reordering and
+ copying. */
+
+typedef struct reorder_block_def
+{
+ rtx header;
+ rtx footer;
+ basic_block next;
+ basic_block original;
+ /* Used by loop copying. */
+ basic_block copy;
+ int duplicated;
+
+ /* These fields are used by bb-reorder pass. */
+ int visited;
+} *reorder_block_def;
#define BB_FREQ_MAX 10000
@@ -285,7 +329,7 @@ extern int n_edges;
/* Index by basic block number, get basic block struct info. */
-extern varray_type basic_block_info;
+extern GTY(()) varray_type basic_block_info;
#define BASIC_BLOCK(N) (VARRAY_BB (basic_block_info, (N)))
@@ -352,9 +396,8 @@ extern struct obstack flow_obstack;
#define INVALID_BLOCK (-3)
/* Similarly, block pointers for the edge list. */
-extern struct basic_block_def entry_exit_blocks[2];
-#define ENTRY_BLOCK_PTR (&entry_exit_blocks[0])
-#define EXIT_BLOCK_PTR (&entry_exit_blocks[1])
+extern GTY(()) basic_block ENTRY_BLOCK_PTR;
+extern GTY(()) basic_block EXIT_BLOCK_PTR;
#define BLOCK_NUM(INSN) (BLOCK_FOR_INSN (INSN)->index + 0)
#define set_block_for_insn(INSN, BB) (BLOCK_FOR_INSN (INSN) = BB)
@@ -363,7 +406,7 @@ extern void compute_bb_for_insn (void);
extern void free_bb_for_insn (void);
extern void update_bb_for_insn (basic_block);
-extern void free_basic_block_vars (int);
+extern void free_basic_block_vars (void);
extern void insert_insn_on_edge (rtx, edge);
bool safe_insert_insn_on_edge (rtx, edge);
@@ -374,7 +417,6 @@ extern void commit_edge_insertions_watch_calls (void);
extern void remove_fake_edges (void);
extern void add_noreturn_fake_exit_edges (void);
extern void connect_infinite_loops_to_exit (void);
-extern int flow_call_edges_add (sbitmap);
extern edge unchecked_make_edge (basic_block, basic_block, int);
extern edge cached_make_edge (sbitmap *, basic_block, basic_block, int);
extern edge make_edge (basic_block, basic_block, int);
@@ -392,6 +434,7 @@ extern int dfs_enumerate_from (basic_block, int,
bool (*)(basic_block, void *),
basic_block *, int, void *);
extern void dump_edge_info (FILE *, edge, int);
+extern void brief_dump_cfg (FILE *);
extern void clear_edges (void);
extern void mark_critical_edges (void);
extern rtx first_insn_after_basic_block_note (basic_block);
@@ -472,6 +515,7 @@ void free_edge_list (struct edge_list *);
void print_edge_list (FILE *, struct edge_list *);
void verify_edge_list (FILE *, struct edge_list *);
int find_edge_index (struct edge_list *, basic_block, basic_block);
+edge find_edge (basic_block, basic_block);
enum update_life_extent
@@ -554,6 +598,11 @@ extern void expected_value_to_br_prob (void);
extern bool maybe_hot_bb_p (basic_block);
extern bool probably_cold_bb_p (basic_block);
extern bool probably_never_executed_bb_p (basic_block);
+extern bool tree_predicted_by_p (basic_block, enum br_predictor);
+extern bool rtl_predicted_by_p (basic_block, enum br_predictor);
+extern void tree_predict_edge (edge, enum br_predictor, int);
+extern void rtl_predict_edge (edge, enum br_predictor, int);
+extern void predict_edge_def (edge, enum br_predictor, enum prediction);
/* In flow.c */
extern void init_flow (void);
@@ -577,7 +626,7 @@ extern bool purge_all_dead_edges (int);
extern bool purge_dead_edges (basic_block);
extern void find_sub_basic_blocks (basic_block);
extern void find_many_sub_basic_blocks (sbitmap);
-extern void make_eh_edge (sbitmap *, basic_block, rtx);
+extern void rtl_make_eh_edge (sbitmap *, basic_block, rtx);
extern bool can_fallthru (basic_block, basic_block);
extern void flow_nodes_print (const char *, const sbitmap, FILE *);
extern void flow_edge_list_print (const char *, const edge *, int, FILE *);
@@ -589,6 +638,10 @@ extern void alloc_aux_for_edge (edge, int);
extern void alloc_aux_for_edges (int);
extern void clear_aux_for_edges (void);
extern void free_aux_for_edges (void);
+extern void find_basic_blocks (rtx, int, FILE *);
+extern bool cleanup_cfg (int);
+extern bool delete_unreachable_blocks (void);
+extern bool merge_seq_blocks (void);
typedef struct conflict_graph_def *conflict_graph;
@@ -624,6 +677,11 @@ extern bool control_flow_insn_p (rtx);
extern void reorder_basic_blocks (void);
extern void partition_hot_cold_basic_blocks (void);
+/* In cfg.c */
+extern void alloc_rbi_pool (void);
+extern void initialize_bb_rbi (basic_block bb);
+extern void free_rbi_pool (void);
+
/* In dominance.c */
enum cdi_direction
@@ -661,7 +719,7 @@ extern void iterate_fix_dominators (enum cdi_direction, basic_block *, int);
extern void verify_dominators (enum cdi_direction);
extern basic_block first_dom_son (enum cdi_direction, basic_block);
extern basic_block next_dom_son (enum cdi_direction, basic_block);
-extern bool try_redirect_by_replacing_jump (edge, basic_block, bool);
+extern edge try_redirect_by_replacing_jump (edge, basic_block, bool);
extern void break_superblocks (void);
#include "cfghooks.h"
diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c
index 022cb33eb2e..0e45d1605cb 100644
--- a/gcc/bb-reorder.c
+++ b/gcc/bb-reorder.c
@@ -78,6 +78,7 @@
#include "fibheap.h"
#include "target.h"
#include "function.h"
+#include "tm_p.h"
#include "obstack.h"
#include "expr.h"
#include "regs.h"
@@ -87,6 +88,15 @@
the .o file there will be an extra round.*/
#define N_ROUNDS 5
+/* Stubs in case we don't have a return insn.
+ We have to check at runtime too, not only compiletime. */
+
+#ifndef HAVE_return
+#define HAVE_return 0
+#define gen_return() NULL_RTX
+#endif
+
+
/* Branch thresholds in thousandths (per mille) of the REG_BR_PROB_BASE. */
static int branch_threshold[N_ROUNDS] = {400, 200, 100, 0, 0};
@@ -739,7 +749,7 @@ copy_bb (basic_block old_bb, edge e, basic_block bb, int trace)
{
basic_block new_bb;
- new_bb = cfg_layout_duplicate_bb (old_bb, e);
+ new_bb = duplicate_block (old_bb, e);
if (e->dest != new_bb)
abort ();
if (e->dest->rbi->visited)
@@ -891,7 +901,7 @@ connect_traces (int n_traces, struct trace *traces)
last_trace = -1;
/* If we are partitioning hot/cold basic blocks, mark the cold
- traces as already connnected, to remove them from consideration
+ traces as already connected, to remove them from consideration
for connection to the hot traces. After the hot traces have all
been connected (determined by "unconnected_hot_trace_count"), we
will go back and connect the cold traces. */
@@ -1149,6 +1159,7 @@ connect_traces (int n_traces, struct trace *traces)
}
FREE (connected);
+ FREE (cold_traces);
}
/* Return true when BB can and should be copied. CODE_MAY_GROW is true
@@ -1167,7 +1178,7 @@ copy_bb_p (basic_block bb, int code_may_grow)
return false;
if (!bb->pred || !bb->pred->pred_next)
return false;
- if (!cfg_layout_can_duplicate_bb_p (bb))
+ if (!can_duplicate_block_p (bb))
return false;
/* Avoid duplicating blocks which have many successors (PR/13430). */
@@ -1399,7 +1410,7 @@ fix_up_fall_thru_edges (void)
edge succ1;
edge succ2;
edge fall_thru;
- edge cond_jump;
+ edge cond_jump = NULL;
edge e;
bool cond_jump_crosses;
int invert_worked;
@@ -1684,11 +1695,10 @@ fix_crossing_conditional_branches (void)
(old_label),
BB_END (new_bb));
}
-#ifdef HAVE_return
- else if (GET_CODE (old_label) == RETURN)
+ else if (HAVE_return
+ && GET_CODE (old_label) == RETURN)
new_jump = emit_jump_insn_after (gen_return (),
BB_END (new_bb));
-#endif
else
abort ();
@@ -1771,7 +1781,7 @@ fix_crossing_unconditional_branches (void)
reference of label, as target for jump. */
label = JUMP_LABEL (last_insn);
- label_addr = gen_rtx_LABEL_REF (VOIDmode, label);
+ label_addr = gen_rtx_LABEL_REF (Pmode, label);
LABEL_NUSES (label) += 1;
/* Get a register to use for the indirect jump. */
diff --git a/gcc/bitmap.c b/gcc/bitmap.c
index 70e0a93d086..ebbb6ee805f 100644
--- a/gcc/bitmap.c
+++ b/gcc/bitmap.c
@@ -414,7 +414,9 @@ bitmap_first_set_bit (bitmap a)
#else
for (word_num = 0; word_num < BITMAP_ELEMENT_WORDS; ++word_num)
if ((word = ptr->bits[word_num]) != 0)
- break;
+ goto word_found;
+ abort ();
+ word_found:
#endif
/* Binary search for the first set bit. */
@@ -469,7 +471,9 @@ bitmap_last_set_bit (bitmap a)
#else
for (word_num = BITMAP_ELEMENT_WORDS; word_num-- > 0; )
if ((word = ptr->bits[word_num]) != 0)
- break;
+ goto word_found;
+ abort ();
+ word_found:
#endif
/* Binary search for the last set bit. */
diff --git a/gcc/builtin-attrs.def b/gcc/builtin-attrs.def
index 92fe65e1e0d..10d58649a82 100644
--- a/gcc/builtin-attrs.def
+++ b/gcc/builtin-attrs.def
@@ -69,7 +69,7 @@ DEF_LIST_INT_INT (3,0)
DEF_LIST_INT_INT (3,4)
#undef DEF_LIST_INT_INT
-/* Construct tress for identifiers. */
+/* Construct trees for identifiers. */
DEF_ATTR_IDENT (ATTR_CONST, "const")
DEF_ATTR_IDENT (ATTR_FORMAT, "format")
DEF_ATTR_IDENT (ATTR_FORMAT_ARG, "format_arg")
diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def
index 81fdeb18505..a809a477928 100644
--- a/gcc/builtin-types.def
+++ b/gcc/builtin-types.def
@@ -80,6 +80,7 @@ DEF_PRIMITIVE_TYPE (BT_INT_PTR, integer_ptr_type_node)
DEF_PRIMITIVE_TYPE (BT_FLOAT_PTR, float_ptr_type_node)
DEF_PRIMITIVE_TYPE (BT_DOUBLE_PTR, double_ptr_type_node)
DEF_PRIMITIVE_TYPE (BT_LONGDOUBLE_PTR, long_double_ptr_type_node)
+DEF_PRIMITIVE_TYPE (BT_PID, pid_type_node)
DEF_PRIMITIVE_TYPE (BT_SIZE, size_type_node)
DEF_PRIMITIVE_TYPE (BT_SSIZE, signed_size_type_node)
DEF_PRIMITIVE_TYPE (BT_WINT, wint_type_node)
@@ -89,8 +90,11 @@ DEF_PRIMITIVE_TYPE (BT_CONST_STRING, const_string_type_node)
DEF_PRIMITIVE_TYPE (BT_VALIST_REF, va_list_ref_type_node)
DEF_PRIMITIVE_TYPE (BT_VALIST_ARG, va_list_arg_type_node)
+DEF_POINTER_TYPE (BT_PTR_CONST_STRING, BT_CONST_STRING)
+
DEF_FUNCTION_TYPE_0 (BT_FN_VOID, BT_VOID)
DEF_FUNCTION_TYPE_0 (BT_FN_PTR, BT_PTR)
+DEF_FUNCTION_TYPE_0 (BT_FN_PID, BT_PID)
DEF_FUNCTION_TYPE_0 (BT_FN_UNSIGNED, BT_UNSIGNED)
DEF_FUNCTION_TYPE_0 (BT_FN_FLOAT, BT_FLOAT)
DEF_FUNCTION_TYPE_0 (BT_FN_DOUBLE, BT_DOUBLE)
@@ -223,6 +227,9 @@ DEF_FUNCTION_TYPE_2 (BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE,
BT_COMPLEX_DOUBLE, BT_COMPLEX_DOUBLE, BT_COMPLEX_DOUBLE)
DEF_FUNCTION_TYPE_2 (BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE,
BT_COMPLEX_LONGDOUBLE, BT_COMPLEX_LONGDOUBLE, BT_COMPLEX_LONGDOUBLE)
+DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_PTR, BT_VOID, BT_PTR, BT_PTR)
+DEF_FUNCTION_TYPE_2 (BT_FN_INT_CONST_STRING_PTR_CONST_STRING,
+ BT_INT, BT_CONST_STRING, BT_PTR_CONST_STRING)
DEF_FUNCTION_TYPE_3 (BT_FN_STRING_STRING_CONST_STRING_SIZE,
BT_STRING, BT_STRING, BT_CONST_STRING, BT_SIZE)
@@ -264,6 +271,9 @@ DEF_FUNCTION_TYPE_3 (BT_FN_VOID_DOUBLE_DOUBLEPTR_DOUBLEPTR,
BT_VOID, BT_DOUBLE, BT_DOUBLE_PTR, BT_DOUBLE_PTR)
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_LONGDOUBLE_LONGDOUBLEPTR_LONGDOUBLEPTR,
BT_VOID, BT_LONGDOUBLE, BT_LONGDOUBLE_PTR, BT_LONGDOUBLE_PTR)
+DEF_FUNCTION_TYPE_3 (BT_FN_VOID_PTR_PTR_PTR, BT_VOID, BT_PTR, BT_PTR, BT_PTR)
+DEF_FUNCTION_TYPE_3 (BT_FN_INT_CONST_STRING_PTR_CONST_STRING_PTR_CONST_STRING,
+ BT_INT, BT_CONST_STRING, BT_PTR_CONST_STRING, BT_PTR_CONST_STRING)
DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_CONST_PTR_SIZE_SIZE_PTR,
BT_SIZE, BT_CONST_PTR, BT_SIZE, BT_SIZE, BT_PTR)
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 8720666c7c0..b0375c377aa 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -68,11 +68,10 @@ const char *const built_in_names[(int) END_BUILTINS] =
tree built_in_decls[(int) END_BUILTINS];
/* Declarations used when constructing the builtin implicitly in the compiler.
It may be NULL_TREE when this is invalid (for instance runtime is not
- required to implement the function call in all cases. */
+ required to implement the function call in all cases). */
tree implicit_built_in_decls[(int) END_BUILTINS];
static int get_pointer_alignment (tree, unsigned int);
-static tree c_strlen (tree, int);
static const char *c_getstr (tree);
static rtx c_readstr (const char *, enum machine_mode);
static int target_char_cast (tree, char *);
@@ -84,6 +83,7 @@ static int apply_result_size (void);
static rtx result_vector (int, rtx);
#endif
static rtx expand_builtin_setjmp (tree, rtx);
+static void expand_builtin_update_setjmp_buf (rtx);
static void expand_builtin_prefetch (tree);
static rtx expand_builtin_apply_args (void);
static rtx expand_builtin_apply_args_1 (void);
@@ -95,7 +95,6 @@ static void expand_errno_check (tree, rtx);
static rtx expand_builtin_mathfn (tree, rtx, rtx);
static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
-static rtx expand_builtin_constant_p (tree, enum machine_mode);
static rtx expand_builtin_args_info (tree);
static rtx expand_builtin_next_arg (tree);
static rtx expand_builtin_va_start (tree);
@@ -146,7 +145,7 @@ static bool readonly_data_expr (tree);
static rtx expand_builtin_fabs (tree, rtx, rtx);
static rtx expand_builtin_cabs (tree, rtx);
static rtx expand_builtin_signbit (tree, rtx);
-static tree fold_builtin_cabs (tree, tree, tree);
+static tree fold_builtin_cabs (tree, tree);
static tree fold_builtin_trunc (tree);
static tree fold_builtin_floor (tree);
static tree fold_builtin_ceil (tree);
@@ -162,6 +161,22 @@ static tree fold_builtin_strcmp (tree);
static tree fold_builtin_strncmp (tree);
static tree fold_builtin_signbit (tree);
+static tree simplify_builtin_memcmp (tree);
+static tree simplify_builtin_strcmp (tree);
+static tree simplify_builtin_strncmp (tree);
+static tree simplify_builtin_strpbrk (tree);
+static tree simplify_builtin_strstr (tree);
+static tree simplify_builtin_strchr (tree);
+static tree simplify_builtin_strrchr (tree);
+static tree simplify_builtin_strcat (tree);
+static tree simplify_builtin_strncat (tree);
+static tree simplify_builtin_strspn (tree);
+static tree simplify_builtin_strcspn (tree);
+static void simplify_builtin_next_arg (tree);
+static void simplify_builtin_va_start (tree);
+static tree simplify_builtin_sprintf (tree, int);
+
+
/* Return the alignment in bits of EXP, a pointer valued expression.
But don't return more than MAX_ALIGN no matter what.
The alignment returned is, by default, the alignment of the thing that
@@ -246,7 +261,7 @@ get_pointer_alignment (tree exp, unsigned int max_align)
Unfortunately, string_constant can't access the values of const char
arrays with initializers, so neither can we do so here. */
-static tree
+tree
c_strlen (tree src, int only_value)
{
tree offset_node;
@@ -406,6 +421,21 @@ target_char_cast (tree cst, char *p)
return 0;
}
+/* Similar to save_expr, but assumes that arbitrary code is not executed
+ in between the multiple evaluations. In particular, we assume that a
+ non-addressable local variable will not be modified. */
+
+static tree
+builtin_save_expr (tree exp)
+{
+ if (TREE_ADDRESSABLE (exp) == 0
+ && (TREE_CODE (exp) == PARM_DECL
+ || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
+ return exp;
+
+ return save_expr (exp);
+}
+
/* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
times to get the address of either a higher stack frame, or a return
address located within it (depending on FNDECL_CODE). */
@@ -738,6 +768,113 @@ expand_builtin_longjmp (rtx buf_addr, rtx value)
}
}
+/* Expand a call to __builtin_nonlocal_goto. We're passed the target label
+ and the address of the save area. */
+
+static rtx
+expand_builtin_nonlocal_goto (tree arglist)
+{
+ tree t_label, t_save_area;
+ rtx r_label, r_save_area, r_fp, r_sp, insn;
+
+ if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
+ return NULL_RTX;
+
+ t_label = TREE_VALUE (arglist);
+ arglist = TREE_CHAIN (arglist);
+ t_save_area = TREE_VALUE (arglist);
+
+ r_label = expand_expr (t_label, NULL_RTX, VOIDmode, 0);
+ r_save_area = expand_expr (t_save_area, NULL_RTX, VOIDmode, 0);
+ r_fp = gen_rtx_MEM (Pmode, r_save_area);
+ r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
+ plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
+
+ current_function_has_nonlocal_goto = 1;
+
+#if HAVE_nonlocal_goto
+ /* ??? We no longer need to pass the static chain value, afaik. */
+ if (HAVE_nonlocal_goto)
+ emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
+ else
+#endif
+ {
+ r_label = copy_to_reg (r_label);
+
+ emit_insn (gen_rtx_CLOBBER (VOIDmode,
+ gen_rtx_MEM (BLKmode,
+ gen_rtx_SCRATCH (VOIDmode))));
+
+ emit_insn (gen_rtx_CLOBBER (VOIDmode,
+ gen_rtx_MEM (BLKmode,
+ hard_frame_pointer_rtx)));
+
+ /* Restore frame pointer for containing function.
+ This sets the actual hard register used for the frame pointer
+ to the location of the function's incoming static chain info.
+ The non-local goto handler will then adjust it to contain the
+ proper value and reload the argument pointer, if needed. */
+ emit_move_insn (hard_frame_pointer_rtx, r_fp);
+ emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
+
+ /* USE of hard_frame_pointer_rtx added for consistency;
+ not clear if really needed. */
+ emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
+ emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
+ emit_indirect_jump (r_label);
+ }
+
+ /* Search backwards to the jump insn and mark it as a
+ non-local goto. */
+ for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
+ {
+ if (GET_CODE (insn) == JUMP_INSN)
+ {
+ REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
+ const0_rtx, REG_NOTES (insn));
+ break;
+ }
+ else if (GET_CODE (insn) == CALL_INSN)
+ break;
+ }
+
+ return const0_rtx;
+}
+
+/* __builtin_update_setjmp_buf is passed a pointer to an array of five words
+ (not all will be used on all machines) that was passed to __builtin_setjmp.
+ It updates the stack pointer in that block to correspond to the current
+ stack pointer. */
+
+static void
+expand_builtin_update_setjmp_buf (rtx buf_addr)
+{
+ enum machine_mode sa_mode = Pmode;
+ rtx stack_save;
+
+
+#ifdef HAVE_save_stack_nonlocal
+ if (HAVE_save_stack_nonlocal)
+ sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
+#endif
+#ifdef STACK_SAVEAREA_MODE
+ sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
+#endif
+
+ stack_save
+ = gen_rtx_MEM (sa_mode,
+ memory_address
+ (sa_mode,
+ plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
+
+#ifdef HAVE_setjmp
+ if (HAVE_setjmp)
+ emit_insn (gen_setjmp ());
+#endif
+
+ emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
+}
+
/* Expand a call to __builtin_prefetch. For a target that does not support
data prefetch, evaluate the memory address argument in case it has side
effects. */
@@ -1195,7 +1332,7 @@ expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
}
/* All arguments and registers used for the call are set up by now! */
- function = prepare_call_address (function, NULL_TREE, &call_fusage, 0, 0);
+ function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
/* Ensure address is valid. SYMBOL_REF is already valid, so no need,
and we don't want to load it into a register as an optimization,
@@ -1349,32 +1486,6 @@ expand_builtin_classify_type (tree arglist)
return GEN_INT (no_type_class);
}
-/* Expand expression EXP, which is a call to __builtin_constant_p. */
-
-static rtx
-expand_builtin_constant_p (tree arglist, enum machine_mode target_mode)
-{
- rtx tmp;
-
- if (arglist == 0)
- return const0_rtx;
- arglist = TREE_VALUE (arglist);
-
- /* We have taken care of the easy cases during constant folding. This
- case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE
- get a chance to see if it can deduce whether ARGLIST is constant.
- If CSE isn't going to run, of course, don't bother waiting. */
-
- if (cse_not_expected)
- return const0_rtx;
-
- current_function_calls_constant_p = 1;
-
- tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0);
- tmp = gen_rtx_CONSTANT_P_RTX (target_mode, tmp);
- return tmp;
-}
-
/* This helper macro, meant to be used in mathfn_built_in below,
determines which among a set of three builtin math functions is
appropriate for a given type mode. The `F' and `L' cases are
@@ -1565,6 +1676,18 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
case BUILT_IN_EXP2F:
case BUILT_IN_EXP2L:
errno_set = true; builtin_optab = exp2_optab; break;
+ case BUILT_IN_EXPM1:
+ case BUILT_IN_EXPM1F:
+ case BUILT_IN_EXPM1L:
+ errno_set = true; builtin_optab = expm1_optab; break;
+ case BUILT_IN_LOGB:
+ case BUILT_IN_LOGBF:
+ case BUILT_IN_LOGBL:
+ errno_set = true; builtin_optab = logb_optab; break;
+ case BUILT_IN_ILOGB:
+ case BUILT_IN_ILOGBF:
+ case BUILT_IN_ILOGBL:
+ errno_set = true; builtin_optab = ilogb_optab; break;
case BUILT_IN_LOG:
case BUILT_IN_LOGF:
case BUILT_IN_LOGL:
@@ -1577,6 +1700,18 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
case BUILT_IN_LOG2F:
case BUILT_IN_LOG2L:
errno_set = true; builtin_optab = log2_optab; break;
+ case BUILT_IN_LOG1P:
+ case BUILT_IN_LOG1PF:
+ case BUILT_IN_LOG1PL:
+ errno_set = true; builtin_optab = log1p_optab; break;
+ case BUILT_IN_ASIN:
+ case BUILT_IN_ASINF:
+ case BUILT_IN_ASINL:
+ builtin_optab = asin_optab; break;
+ case BUILT_IN_ACOS:
+ case BUILT_IN_ACOSF:
+ case BUILT_IN_ACOSL:
+ builtin_optab = acos_optab; break;
case BUILT_IN_TAN:
case BUILT_IN_TANF:
case BUILT_IN_TANL:
@@ -1623,7 +1758,7 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
/* Wrap the computation of the argument in a SAVE_EXPR, as we may
need to expand the argument again. This way, we will not perform
side-effects more the once. */
- narg = save_expr (arg);
+ narg = builtin_save_expr (arg);
if (narg != arg)
{
arglist = build_tree_list (NULL_TREE, arg);
@@ -1738,6 +1873,14 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
case BUILT_IN_ATAN2F:
case BUILT_IN_ATAN2L:
builtin_optab = atan2_optab; break;
+ case BUILT_IN_FMOD:
+ case BUILT_IN_FMODF:
+ case BUILT_IN_FMODL:
+ builtin_optab = fmod_optab; break;
+ case BUILT_IN_DREM:
+ case BUILT_IN_DREMF:
+ case BUILT_IN_DREML:
+ builtin_optab = drem_optab; break;
default:
abort ();
}
@@ -1754,8 +1897,8 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
if (! flag_errno_math || ! HONOR_NANS (mode))
errno_set = false;
- /* Alway stabilize the argument list. */
- narg = save_expr (arg1);
+ /* Always stabilize the argument list. */
+ narg = builtin_save_expr (arg1);
if (narg != arg1)
{
temp = build_tree_list (NULL_TREE, narg);
@@ -1764,7 +1907,7 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
else
temp = TREE_CHAIN (arglist);
- narg = save_expr (arg0);
+ narg = builtin_save_expr (arg0);
if (narg != arg0)
{
arglist = tree_cons (NULL_TREE, narg, temp);
@@ -1896,13 +2039,13 @@ expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
case BUILT_IN_SIN:
case BUILT_IN_SINF:
case BUILT_IN_SINL:
- if (! expand_twoval_unop(builtin_optab, 0, target, op0, 0))
+ if (!expand_twoval_unop (builtin_optab, op0, 0, target, 0))
abort();
break;
case BUILT_IN_COS:
case BUILT_IN_COSF:
case BUILT_IN_COSL:
- if (! expand_twoval_unop(builtin_optab, target, 0, op0, 0))
+ if (!expand_twoval_unop (builtin_optab, op0, target, 0, 0))
abort();
break;
default:
@@ -2331,9 +2474,9 @@ expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
return const0_rtx;
/* Return an offset into the constant string argument. */
- return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
- s1, convert (TREE_TYPE (s1),
- ssize_int (r - p1)))),
+ return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1), s1,
+ fold_convert (TREE_TYPE (s1),
+ ssize_int (r - p1)))),
target, mode, EXPAND_NORMAL);
}
@@ -2389,9 +2532,9 @@ expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
return const0_rtx;
/* Return an offset into the constant string argument. */
- return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
- s1, convert (TREE_TYPE (s1),
- ssize_int (r - p1)))),
+ return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1), s1,
+ fold_convert (TREE_TYPE (s1),
+ ssize_int (r - p1)))),
target, mode, EXPAND_NORMAL);
}
@@ -2434,9 +2577,9 @@ expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
return const0_rtx;
/* Return an offset into the constant string argument. */
- return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
- s1, convert (TREE_TYPE (s1),
- ssize_int (r - p1)))),
+ return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1), s1,
+ fold_convert (TREE_TYPE (s1),
+ ssize_int (r - p1)))),
target, mode, EXPAND_NORMAL);
}
@@ -2481,9 +2624,9 @@ expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
return const0_rtx;
/* Return an offset into the constant string argument. */
- return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
- s1, convert (TREE_TYPE (s1),
- ssize_int (r - p1)))),
+ return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1), s1,
+ fold_convert (TREE_TYPE (s1),
+ ssize_int (r - p1)))),
target, mode, EXPAND_NORMAL);
}
@@ -2671,7 +2814,7 @@ expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
if (endp == 2)
len = fold (build (MINUS_EXPR, TREE_TYPE (len), dest,
integer_one_node));
- len = convert (TREE_TYPE (dest), len);
+ len = fold_convert (TREE_TYPE (dest), len);
expr = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
return expand_expr (expr, target, mode, EXPAND_NORMAL);
}
@@ -2815,7 +2958,7 @@ expand_builtin_bcopy (tree arglist)
so that if it isn't expanded inline, we fallback to
calling bcopy instead of memmove. */
- newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
+ newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
newarglist = tree_cons (NULL_TREE, src, newarglist);
newarglist = tree_cons (NULL_TREE, dest, newarglist);
@@ -3153,7 +3296,7 @@ expand_builtin_bzero (tree arglist)
so that if it isn't expanded inline, we fallback to
calling bzero instead of memset. */
- newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
+ newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
newarglist = tree_cons (NULL_TREE, dest, newarglist);
@@ -3221,11 +3364,11 @@ expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
tree ind1 =
fold (build1 (CONVERT_EXPR, integer_type_node,
build1 (INDIRECT_REF, cst_uchar_node,
- build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
+ fold_convert (cst_uchar_ptr_node, arg1))));
tree ind2 =
fold (build1 (CONVERT_EXPR, integer_type_node,
build1 (INDIRECT_REF, cst_uchar_node,
- build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
+ fold_convert (cst_uchar_ptr_node, arg2))));
tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
return expand_expr (result, target, mode, EXPAND_NORMAL);
}
@@ -3349,11 +3492,11 @@ expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
tree ind1 =
fold (build1 (CONVERT_EXPR, integer_type_node,
build1 (INDIRECT_REF, cst_uchar_node,
- build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
+ fold_convert (cst_uchar_ptr_node, arg1))));
tree ind2 =
fold (build1 (CONVERT_EXPR, integer_type_node,
build1 (INDIRECT_REF, cst_uchar_node,
- build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
+ fold_convert (cst_uchar_ptr_node, arg2))));
tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
return expand_expr (result, target, mode, EXPAND_NORMAL);
}
@@ -3421,8 +3564,8 @@ expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
result = gen_reg_rtx (insn_mode);
/* Stabilize the arguments in case gen_cmpstrsi fails. */
- arg1 = save_expr (arg1);
- arg2 = save_expr (arg2);
+ arg1 = builtin_save_expr (arg1);
+ arg2 = builtin_save_expr (arg2);
arg1_rtx = get_memory_rtx (arg1);
arg2_rtx = get_memory_rtx (arg2);
@@ -3514,11 +3657,11 @@ expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
tree ind1 =
fold (build1 (CONVERT_EXPR, integer_type_node,
build1 (INDIRECT_REF, cst_uchar_node,
- build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
+ fold_convert (cst_uchar_ptr_node, arg1))));
tree ind2 =
fold (build1 (CONVERT_EXPR, integer_type_node,
build1 (INDIRECT_REF, cst_uchar_node,
- build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
+ fold_convert (cst_uchar_ptr_node, arg2))));
tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
return expand_expr (result, target, mode, EXPAND_NORMAL);
}
@@ -3592,9 +3735,9 @@ expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
result = gen_reg_rtx (insn_mode);
/* Stabilize the arguments in case gen_cmpstrsi fails. */
- arg1 = save_expr (arg1);
- arg2 = save_expr (arg2);
- len = save_expr (len);
+ arg1 = builtin_save_expr (arg1);
+ arg2 = builtin_save_expr (arg2);
+ len = builtin_save_expr (len);
arg1_rtx = get_memory_rtx (arg1);
arg2_rtx = get_memory_rtx (arg2);
@@ -3664,7 +3807,7 @@ expand_builtin_strcat (tree arglist, rtx target, enum machine_mode mode)
arglist = tree_cons (NULL_TREE, src, arglist);
/* We're going to use dst more than once. */
- dst = save_expr (dst);
+ dst = builtin_save_expr (dst);
/* Create strlen (dst). */
newdst =
@@ -3959,7 +4102,7 @@ stabilize_va_list (tree valist, int needs_lvalue)
tree p2 = build_pointer_type (va_list_type_node);
valist = build1 (ADDR_EXPR, p2, valist);
- valist = fold (build1 (NOP_EXPR, p1, valist));
+ valist = fold_convert (p1, valist);
}
}
else
@@ -4334,6 +4477,12 @@ expand_builtin_alloca (tree arglist, rtx target)
rtx op0;
rtx result;
+ /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
+ should always expand to function calls. These can be intercepted
+ in libmudflap. */
+ if (flag_mudflap)
+ return 0;
+
if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
return 0;
@@ -4681,6 +4830,7 @@ build_string_literal (int len, const char *str)
type = build_array_type (elem, index);
TREE_TYPE (t) = type;
TREE_CONSTANT (t) = 1;
+ TREE_INVARIANT (t) = 1;
TREE_READONLY (t) = 1;
TREE_STATIC (t) = 1;
@@ -4934,7 +5084,7 @@ expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
if (target == const0_rtx)
return const0_rtx;
exp = build_int_2 (strlen (fmt_str), 0);
- exp = fold (build1 (NOP_EXPR, integer_type_node, exp));
+ exp = fold_convert (integer_type_node, exp);
return expand_expr (exp, target, mode, EXPAND_NORMAL);
}
/* If the format is "%s", use strcpy if the result isn't used. */
@@ -4974,6 +5124,111 @@ expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
return 0;
}
+/* Expand a call to either the entry or exit function profiler. */
+
+static rtx
+expand_builtin_profile_func (bool exitp)
+{
+ rtx this, which;
+
+ this = DECL_RTL (current_function_decl);
+ if (GET_CODE (this) == MEM)
+ this = XEXP (this, 0);
+ else
+ abort ();
+
+ if (exitp)
+ which = profile_function_exit_libfunc;
+ else
+ which = profile_function_entry_libfunc;
+
+ emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
+ expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
+ 0, hard_frame_pointer_rtx),
+ Pmode);
+
+ return const0_rtx;
+}
+
+/* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
+
+static rtx
+round_trampoline_addr (rtx tramp)
+{
+ rtx temp, addend, mask;
+
+ /* If we don't need too much alignment, we'll have been guaranteed
+ proper alignment by get_trampoline_type. */
+ if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
+ return tramp;
+
+ /* Round address up to desired boundary. */
+ temp = gen_reg_rtx (Pmode);
+ addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
+ mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
+
+ temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
+ temp, 0, OPTAB_LIB_WIDEN);
+ tramp = expand_simple_binop (Pmode, AND, temp, mask,
+ temp, 0, OPTAB_LIB_WIDEN);
+
+ return tramp;
+}
+
+static rtx
+expand_builtin_init_trampoline (tree arglist)
+{
+ tree t_tramp, t_func, t_chain;
+ rtx r_tramp, r_func, r_chain;
+#ifdef TRAMPOLINE_TEMPLATE
+ rtx blktramp;
+#endif
+
+ if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
+ POINTER_TYPE, VOID_TYPE))
+ return NULL_RTX;
+
+ t_tramp = TREE_VALUE (arglist);
+ arglist = TREE_CHAIN (arglist);
+ t_func = TREE_VALUE (arglist);
+ arglist = TREE_CHAIN (arglist);
+ t_chain = TREE_VALUE (arglist);
+
+ r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
+ r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
+ r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
+
+ /* Generate insns to initialize the trampoline. */
+ r_tramp = round_trampoline_addr (r_tramp);
+#ifdef TRAMPOLINE_TEMPLATE
+ blktramp = gen_rtx_MEM (BLKmode, r_tramp);
+ set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
+ emit_block_move (blktramp, assemble_trampoline_template (),
+ GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
+#endif
+ trampolines_created = 1;
+ INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
+
+ return const0_rtx;
+}
+
+static rtx
+expand_builtin_adjust_trampoline (tree arglist)
+{
+ rtx tramp;
+
+ if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
+ return NULL_RTX;
+
+ tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
+ tramp = round_trampoline_addr (tramp);
+#ifdef TRAMPOLINE_ADJUST_ADDRESS
+ TRAMPOLINE_ADJUST_ADDRESS (tramp);
+#endif
+
+ return tramp;
+}
+
/* Expand a call to the built-in signbit, signbitf or signbitl function.
Return NULL_RTX if a normal call should be emitted rather than expanding
the function in-line. EXP is the expression that is a call to the builtin
@@ -5036,7 +5291,7 @@ expand_builtin_signbit (tree exp, rtx target)
if (GET_MODE_BITSIZE (imode) > GET_MODE_BITSIZE (rmode))
{
- if (BITS_BIG_ENDIAN)
+ if (BYTES_BIG_ENDIAN)
bitpos = GET_MODE_BITSIZE (imode) - 1 - bitpos;
temp = copy_to_mode_reg (imode, temp);
temp = extract_bit_field (temp, 1, bitpos, 1,
@@ -5065,6 +5320,69 @@ expand_builtin_signbit (tree exp, rtx target)
}
return temp;
}
+
+/* Expand fork or exec calls. TARGET is the desired target of the
+ call. ARGLIST is the list of arguments of the call. FN is the
+ identificator of the actual function. IGNORE is nonzero if the
+ value is to be ignored. */
+
+static rtx
+expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
+{
+ tree id, decl;
+ tree call;
+
+ /* If we are not profiling, just call the function. */
+ if (!profile_arc_flag)
+ return NULL_RTX;
+
+ /* Otherwise call the wrapper. This should be equivalent for the rest of
+ compiler, so the code does not diverge, and the wrapper may run the
+ code necessary for keeping the profiling sane. */
+
+ switch (DECL_FUNCTION_CODE (fn))
+ {
+ case BUILT_IN_FORK:
+ id = get_identifier ("__gcov_fork");
+ break;
+
+ case BUILT_IN_EXECL:
+ id = get_identifier ("__gcov_execl");
+ break;
+
+ case BUILT_IN_EXECV:
+ id = get_identifier ("__gcov_execv");
+ break;
+
+ case BUILT_IN_EXECLP:
+ id = get_identifier ("__gcov_execlp");
+ break;
+
+ case BUILT_IN_EXECLE:
+ id = get_identifier ("__gcov_execle");
+ break;
+
+ case BUILT_IN_EXECVP:
+ id = get_identifier ("__gcov_execvp");
+ break;
+
+ case BUILT_IN_EXECVE:
+ id = get_identifier ("__gcov_execve");
+ break;
+
+ default:
+ abort ();
+ }
+
+ decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
+ DECL_EXTERNAL (decl) = 1;
+ TREE_PUBLIC (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+ TREE_NOTHROW (decl) = 1;
+ call = build_function_call_expr (decl, arglist);
+
+ return expand_call (call, target, ignore);
+}
/* Expand an expression EXP that calls a built-in function,
with result going to TARGET if that's convenient
@@ -5178,6 +5496,15 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
case BUILT_IN_EXP2:
case BUILT_IN_EXP2F:
case BUILT_IN_EXP2L:
+ case BUILT_IN_EXPM1:
+ case BUILT_IN_EXPM1F:
+ case BUILT_IN_EXPM1L:
+ case BUILT_IN_LOGB:
+ case BUILT_IN_LOGBF:
+ case BUILT_IN_LOGBL:
+ case BUILT_IN_ILOGB:
+ case BUILT_IN_ILOGBF:
+ case BUILT_IN_ILOGBL:
case BUILT_IN_LOG:
case BUILT_IN_LOGF:
case BUILT_IN_LOGL:
@@ -5187,9 +5514,18 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
case BUILT_IN_LOG2:
case BUILT_IN_LOG2F:
case BUILT_IN_LOG2L:
+ case BUILT_IN_LOG1P:
+ case BUILT_IN_LOG1PF:
+ case BUILT_IN_LOG1PL:
case BUILT_IN_TAN:
case BUILT_IN_TANF:
case BUILT_IN_TANL:
+ case BUILT_IN_ASIN:
+ case BUILT_IN_ASINF:
+ case BUILT_IN_ASINL:
+ case BUILT_IN_ACOS:
+ case BUILT_IN_ACOSF:
+ case BUILT_IN_ACOSL:
case BUILT_IN_ATAN:
case BUILT_IN_ATANF:
case BUILT_IN_ATANL:
@@ -5231,6 +5567,12 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
case BUILT_IN_ATAN2:
case BUILT_IN_ATAN2F:
case BUILT_IN_ATAN2L:
+ case BUILT_IN_FMOD:
+ case BUILT_IN_FMODF:
+ case BUILT_IN_FMODL:
+ case BUILT_IN_DREM:
+ case BUILT_IN_DREMF:
+ case BUILT_IN_DREML:
if (! flag_unsafe_math_optimizations)
break;
target = expand_builtin_mathfn_2 (exp, target, subtarget);
@@ -5299,13 +5641,14 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
/* Return the address of the first anonymous stack arg. */
case BUILT_IN_NEXT_ARG:
+ simplify_builtin_next_arg (arglist);
return expand_builtin_next_arg (arglist);
case BUILT_IN_CLASSIFY_TYPE:
return expand_builtin_classify_type (arglist);
case BUILT_IN_CONSTANT_P:
- return expand_builtin_constant_p (arglist, target_mode);
+ return const0_rtx;
case BUILT_IN_FRAME_ADDRESS:
case BUILT_IN_RETURN_ADDRESS:
@@ -5327,6 +5670,18 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
return target;
break;
+ case BUILT_IN_STACK_ALLOC:
+ expand_stack_alloc (TREE_VALUE (arglist),
+ TREE_VALUE (TREE_CHAIN (arglist)));
+ return const0_rtx;
+
+ case BUILT_IN_STACK_SAVE:
+ return expand_stack_save ();
+
+ case BUILT_IN_STACK_RESTORE:
+ expand_stack_restore (TREE_VALUE (arglist));
+ return const0_rtx;
+
case BUILT_IN_FFS:
case BUILT_IN_FFSL:
case BUILT_IN_FFSLL:
@@ -5530,6 +5885,25 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
return const0_rtx;
}
+ case BUILT_IN_NONLOCAL_GOTO:
+ target = expand_builtin_nonlocal_goto (arglist);
+ if (target)
+ return target;
+ break;
+
+ /* This updates the setjmp buffer that is its argument with the value
+ of the current stack pointer. */
+ case BUILT_IN_UPDATE_SETJMP_BUF:
+ if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
+ {
+ rtx buf_addr
+ = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
+
+ expand_builtin_update_setjmp_buf (buf_addr);
+ return const0_rtx;
+ }
+ break;
+
case BUILT_IN_TRAP:
expand_builtin_trap ();
return const0_rtx;
@@ -5551,7 +5925,6 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
if (target)
return target;
break;
-
case BUILT_IN_FPUTS_UNLOCKED:
target = expand_builtin_fputs (arglist, target, true);
if (target)
@@ -5625,6 +5998,27 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
expand_builtin_prefetch (arglist);
return const0_rtx;
+ case BUILT_IN_PROFILE_FUNC_ENTER:
+ return expand_builtin_profile_func (false);
+ case BUILT_IN_PROFILE_FUNC_EXIT:
+ return expand_builtin_profile_func (true);
+
+ case BUILT_IN_INIT_TRAMPOLINE:
+ return expand_builtin_init_trampoline (arglist);
+ case BUILT_IN_ADJUST_TRAMPOLINE:
+ return expand_builtin_adjust_trampoline (arglist);
+
+ case BUILT_IN_FORK:
+ case BUILT_IN_EXECL:
+ case BUILT_IN_EXECV:
+ case BUILT_IN_EXECLP:
+ case BUILT_IN_EXECLE:
+ case BUILT_IN_EXECVP:
+ case BUILT_IN_EXECVE:
+ target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
+ if (target)
+ return target;
+ break;
default: /* just do library call, if unknown builtin */
if (!DECL_ASSEMBLER_NAME_SET_P (fndecl))
@@ -5749,6 +6143,44 @@ fold_builtin_constant_p (tree arglist)
return 0;
}
+/* Fold a call to __builtin_expect, if we expect that a comparison against
+ the argument will fold to a constant. In practice, this means a true
+ constant or the address of a non-weak symbol. ARGLIST is the argument
+ list of the call. */
+
+static tree
+fold_builtin_expect (tree arglist)
+{
+ tree arg, inner;
+
+ if (arglist == 0)
+ return 0;
+
+ arg = TREE_VALUE (arglist);
+
+ /* If the argument isn't invariant, then there's nothing we can do. */
+ if (!TREE_INVARIANT (arg))
+ return 0;
+
+ /* If we're looking at an address of a weak decl, then do not fold. */
+ inner = arg;
+ STRIP_NOPS (inner);
+ if (TREE_CODE (inner) == ADDR_EXPR)
+ {
+ do
+ {
+ inner = TREE_OPERAND (inner, 0);
+ }
+ while (TREE_CODE (inner) == COMPONENT_REF
+ || TREE_CODE (inner) == ARRAY_REF);
+ if (DECL_P (inner) && DECL_WEAK (inner))
+ return 0;
+ }
+
+ /* Otherwise, ARG already has the proper type for the return value. */
+ return arg;
+}
+
/* Fold a call to __builtin_classify_type. */
static tree
@@ -5917,20 +6349,59 @@ fold_trunc_transparent_mathfn (tree exp)
&& (decl = mathfn_built_in (newtype, fcode)))
{
arglist =
- build_tree_list (NULL_TREE, fold (convert (newtype, arg0)));
- return convert (ftype,
- build_function_call_expr (decl, arglist));
+ build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
+ return fold_convert (ftype,
+ build_function_call_expr (decl, arglist));
}
}
return 0;
}
-/* Fold function call to builtin cabs, cabsf or cabsl. FNDECL is the
- function's DECL, ARGLIST is the argument list and TYPE is the return
- type. Return NULL_TREE if no simplification can be made. */
+/* EXP is assumed to be builtin call which can narrow the FP type of
+ the argument, for instance lround((double)f) -> lroundf (f). */
static tree
-fold_builtin_cabs (tree fndecl, tree arglist, tree type)
+fold_fixed_mathfn (tree exp)
+{
+ tree fndecl = get_callee_fndecl (exp);
+ tree arglist = TREE_OPERAND (exp, 1);
+ enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
+ tree arg;
+
+ if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+ return 0;
+
+ arg = TREE_VALUE (arglist);
+
+ /* If argument is already integer valued, and we don't need to worry
+ about setting errno, there's no need to perform rounding. */
+ if (! flag_errno_math && integer_valued_real_p (arg))
+ return fold (build1 (FIX_TRUNC_EXPR, TREE_TYPE (exp), arg));
+
+ if (optimize)
+ {
+ tree ftype = TREE_TYPE (arg);
+ tree arg0 = strip_float_extensions (arg);
+ tree newtype = TREE_TYPE (arg0);
+ tree decl;
+
+ if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
+ && (decl = mathfn_built_in (newtype, fcode)))
+ {
+ arglist =
+ build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
+ return build_function_call_expr (decl, arglist);
+ }
+ }
+ return 0;
+}
+
+/* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
+ is the argument list and TYPE is the return type. Return
+ NULL_TREE if no if no simplification can be made. */
+
+static tree
+fold_builtin_cabs (tree arglist, tree type)
{
tree arg;
@@ -5973,30 +6444,19 @@ fold_builtin_cabs (tree fndecl, tree arglist, tree type)
if (flag_unsafe_math_optimizations)
{
- enum built_in_function fcode;
- tree sqrtfn;
-
- fcode = DECL_FUNCTION_CODE (fndecl);
- if (fcode == BUILT_IN_CABS)
- sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
- else if (fcode == BUILT_IN_CABSF)
- sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
- else if (fcode == BUILT_IN_CABSL)
- sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
- else
- sqrtfn = NULL_TREE;
+ tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
if (sqrtfn != NULL_TREE)
{
tree rpart, ipart, result, arglist;
- arg = save_expr (arg);
+ arg = builtin_save_expr (arg);
rpart = fold (build1 (REALPART_EXPR, type, arg));
ipart = fold (build1 (IMAGPART_EXPR, type, arg));
- rpart = save_expr (rpart);
- ipart = save_expr (ipart);
+ rpart = builtin_save_expr (rpart);
+ ipart = builtin_save_expr (ipart);
result = fold (build (PLUS_EXPR, type,
fold (build (MULT_EXPR, type,
@@ -6115,7 +6575,7 @@ fold_builtin_round (tree exp)
if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
return 0;
- /* Optimize ceil of constant value. */
+ /* Optimize round of constant value. */
arg = TREE_VALUE (arglist);
if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
{
@@ -6135,6 +6595,42 @@ fold_builtin_round (tree exp)
return fold_trunc_transparent_mathfn (exp);
}
+/* Fold function call to builtin lround, lroundf or lroundl (or the
+ corresponding long long versions). Return NULL_TREE if no
+ simplification can be made. */
+
+static tree
+fold_builtin_lround (tree exp)
+{
+ tree arglist = TREE_OPERAND (exp, 1);
+ tree arg;
+
+ if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+ return 0;
+
+ /* Optimize lround of constant value. */
+ arg = TREE_VALUE (arglist);
+ if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
+ {
+ const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
+
+ if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
+ {
+ tree itype = TREE_TYPE (exp), ftype = TREE_TYPE (arg), result;
+ HOST_WIDE_INT hi, lo;
+ REAL_VALUE_TYPE r;
+
+ real_round (&r, TYPE_MODE (ftype), &x);
+ REAL_VALUE_TO_INT (&lo, &hi, r);
+ result = build_int_2 (lo, hi);
+ if (int_fits_type_p (result, itype))
+ return fold_convert (itype, result);
+ }
+ }
+
+ return fold_fixed_mathfn (exp);
+}
+
/* Fold function call to builtin ffs, clz, ctz, popcount and parity
and their long and long long variants (i.e. ffsl and ffsll).
Return NULL_TREE if no simplification can be made. */
@@ -6300,7 +6796,7 @@ fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
|| fcode == BUILT_IN_EXP2F
|| fcode == BUILT_IN_EXP2L))
|| (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
- return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
+ return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
/* Optimize logN(func()) for various exponential functions. We
want to determine the value "x" and the power "exponent" in
@@ -6443,7 +6939,7 @@ fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
&& (fcode == BUILT_IN_LOG10
|| fcode == BUILT_IN_LOG10F
|| fcode == BUILT_IN_LOG10L)))
- return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
+ return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
}
}
@@ -6502,9 +6998,9 @@ fold_builtin_mempcpy (tree exp)
/* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
if (operand_equal_p (src, dest, 0))
{
- tree temp = convert (TREE_TYPE (dest), len);
- temp = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
- return convert (TREE_TYPE (exp), temp);
+ tree temp = fold_convert (TREE_TYPE (dest), len);
+ temp = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, temp));
+ return fold_convert (TREE_TYPE (exp), temp);
}
return 0;
@@ -6556,7 +7052,7 @@ fold_builtin_strcpy (tree exp)
/* If SRC and DEST are the same (and not volatile), return DEST. */
if (operand_equal_p (src, dest, 0))
- return convert (TREE_TYPE (exp), dest);
+ return fold_convert (TREE_TYPE (exp), dest);
return 0;
}
@@ -6635,7 +7131,7 @@ fold_builtin_strcmp (tree exp)
/* If ARG1 and ARG2 are the same (and not volatile), return zero. */
if (operand_equal_p (arg1, arg2, 0))
- return convert (TREE_TYPE (exp), integer_zero_node);
+ return fold_convert (TREE_TYPE (exp), integer_zero_node);
p1 = c_getstr (arg1);
p2 = c_getstr (arg2);
@@ -6650,7 +7146,7 @@ fold_builtin_strcmp (tree exp)
temp = integer_one_node;
else
temp = integer_zero_node;
- return convert (TREE_TYPE (exp), temp);
+ return fold_convert (TREE_TYPE (exp), temp);
}
return 0;
@@ -6698,7 +7194,7 @@ fold_builtin_strncmp (tree exp)
temp = integer_one_node;
else
temp = integer_zero_node;
- return convert (TREE_TYPE (exp), temp);
+ return fold_convert (TREE_TYPE (exp), temp);
}
return 0;
@@ -6726,7 +7222,7 @@ fold_builtin_signbit (tree exp)
c = TREE_REAL_CST (arg);
temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
- return convert (TREE_TYPE (exp), temp);
+ return fold_convert (TREE_TYPE (exp), temp);
}
/* If ARG is non-negative, the result is always zero. */
@@ -6753,11 +7249,16 @@ fold_builtin_isascii (tree arglist)
/* Transform isascii(c) -> ((c & ~0x7f) == 0). */
tree arg = TREE_VALUE (arglist);
- return fold (build (EQ_EXPR, integer_type_node,
- build (BIT_AND_EXPR, integer_type_node, arg,
- build_int_2 (~ (unsigned HOST_WIDE_INT) 0x7f,
- ~ (HOST_WIDE_INT) 0)),
- integer_zero_node));
+ arg = fold (build (EQ_EXPR, integer_type_node,
+ build (BIT_AND_EXPR, integer_type_node, arg,
+ build_int_2 (~ (unsigned HOST_WIDE_INT) 0x7f,
+ ~ (HOST_WIDE_INT) 0)),
+ integer_zero_node));
+
+ if (in_gimple_form && !TREE_CONSTANT (arg))
+ return NULL_TREE;
+ else
+ return arg;
}
}
@@ -6778,12 +7279,37 @@ fold_builtin_toascii (tree arglist)
}
}
+/* Fold a call to builtin isdigit. */
+
+static tree
+fold_builtin_isdigit (tree arglist)
+{
+ if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
+ return 0;
+ else
+ {
+ /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
+ /* According to the C standard, isdigit is unaffected by locale. */
+ tree arg = TREE_VALUE (arglist);
+ arg = fold_convert (unsigned_type_node, arg);
+ arg = build (MINUS_EXPR, unsigned_type_node, arg,
+ fold_convert (unsigned_type_node,
+ build_int_2 (TARGET_DIGIT0, 0)));
+ arg = build (LE_EXPR, integer_type_node, arg,
+ fold_convert (unsigned_type_node, build_int_2 (9, 0)));
+ arg = fold (arg);
+ if (in_gimple_form && !TREE_CONSTANT (arg))
+ return NULL_TREE;
+ else
+ return arg;
+ }
+}
/* Used by constant folding to eliminate some builtin calls early. EXP is
the CALL_EXPR of a call to a builtin function. */
-tree
-fold_builtin (tree exp)
+static tree
+fold_builtin_1 (tree exp)
{
tree fndecl = get_callee_fndecl (exp);
tree arglist = TREE_OPERAND (exp, 1);
@@ -6797,6 +7323,9 @@ fold_builtin (tree exp)
case BUILT_IN_CONSTANT_P:
return fold_builtin_constant_p (arglist);
+ case BUILT_IN_EXPECT:
+ return fold_builtin_expect (arglist);
+
case BUILT_IN_CLASSIFY_TYPE:
return fold_builtin_classify_type (arglist);
@@ -6808,7 +7337,7 @@ fold_builtin (tree exp)
{
/* Convert from the internal "sizetype" type to "size_t". */
if (size_type_node)
- len = convert (size_type_node, len);
+ len = fold_convert (size_type_node, len);
return len;
}
}
@@ -6824,7 +7353,7 @@ fold_builtin (tree exp)
case BUILT_IN_CABS:
case BUILT_IN_CABSF:
case BUILT_IN_CABSL:
- return fold_builtin_cabs (fndecl, arglist, type);
+ return fold_builtin_cabs (arglist, type);
case BUILT_IN_SQRT:
case BUILT_IN_SQRTF:
@@ -7097,17 +7626,7 @@ fold_builtin (tree exp)
if (flag_unsafe_math_optimizations
&& REAL_VALUES_EQUAL (c, dconsthalf))
{
- tree sqrtfn;
-
- fcode = DECL_FUNCTION_CODE (fndecl);
- if (fcode == BUILT_IN_POW)
- sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
- else if (fcode == BUILT_IN_POWF)
- sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
- else if (fcode == BUILT_IN_POWL)
- sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
- else
- sqrtfn = NULL_TREE;
+ tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
if (sqrtfn != NULL_TREE)
{
@@ -7226,6 +7745,22 @@ fold_builtin (tree exp)
case BUILT_IN_RINTL:
return fold_trunc_transparent_mathfn (exp);
+ case BUILT_IN_LROUND:
+ case BUILT_IN_LROUNDF:
+ case BUILT_IN_LROUNDL:
+ case BUILT_IN_LLROUND:
+ case BUILT_IN_LLROUNDF:
+ case BUILT_IN_LLROUNDL:
+ return fold_builtin_lround (exp);
+
+ case BUILT_IN_LRINT:
+ case BUILT_IN_LRINTF:
+ case BUILT_IN_LRINTL:
+ case BUILT_IN_LLRINT:
+ case BUILT_IN_LLRINTF:
+ case BUILT_IN_LLRINTL:
+ return fold_fixed_mathfn (exp);
+
case BUILT_IN_FFS:
case BUILT_IN_FFSL:
case BUILT_IN_FFSLL:
@@ -7278,6 +7813,9 @@ fold_builtin (tree exp)
case BUILT_IN_TOASCII:
return fold_builtin_toascii (arglist);
+ case BUILT_IN_ISDIGIT:
+ return fold_builtin_isdigit (arglist);
+
default:
break;
}
@@ -7285,6 +7823,24 @@ fold_builtin (tree exp)
return 0;
}
+/* A wrapper function for builtin folding that prevents warnings for
+ "statement without effect" and the like, caused by removing the
+ call node earlier than the warning is generated. */
+
+tree
+fold_builtin (tree exp)
+{
+ exp = fold_builtin_1 (exp);
+ if (exp)
+ {
+ /* ??? Don't clobber shared nodes such as integer_zero_node. */
+ if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
+ exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
+ TREE_NO_WARNING (exp) = 1;
+ }
+ return exp;
+}
+
/* Conveniently construct a function call expression. */
tree
@@ -7294,7 +7850,7 @@ build_function_call_expr (tree fn, tree arglist)
call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
- call_expr, arglist);
+ call_expr, arglist, NULL_TREE);
return fold (call_expr);
}
@@ -7359,31 +7915,6 @@ default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
return NULL_RTX;
}
-/* Instantiate all remaining CONSTANT_P_RTX nodes. */
-
-void
-purge_builtin_constant_p (void)
-{
- rtx insn, set, arg, new, note;
-
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- if (INSN_P (insn)
- && (set = single_set (insn)) != NULL_RTX
- && (GET_CODE (arg = SET_SRC (set)) == CONSTANT_P_RTX
- || (GET_CODE (arg) == SUBREG
- && (GET_CODE (arg = SUBREG_REG (arg))
- == CONSTANT_P_RTX))))
- {
- arg = XEXP (arg, 0);
- new = CONSTANT_P (arg) ? const1_rtx : const0_rtx;
- validate_change (insn, &SET_SRC (set), new, 0);
-
- /* Remove the REG_EQUAL note from the insn. */
- if ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
- remove_note (insn, note);
- }
-}
-
/* Returns true is EXP represents data that would potentially reside
in a readonly section. */
@@ -7397,3 +7928,1105 @@ readonly_data_expr (tree exp)
else
return false;
}
+
+/* Front-end to the simplify_builtin_XXX routines.
+
+ EXP is a call to a builtin function. If possible try to simplify
+ that into a constant, expression or call to a more efficient
+ builtin function.
+
+ If IGNORE is nonzero, then the result of this builtin function
+ call is ignored.
+
+ If simplification is possible, return the simplified tree, otherwise
+ return NULL_TREE. */
+
+tree
+simplify_builtin (tree exp, int ignore)
+{
+ tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
+ tree arglist = TREE_OPERAND (exp, 1);
+ enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
+ tree val;
+
+ switch (fcode)
+ {
+ case BUILT_IN_FPUTS:
+ val = simplify_builtin_fputs (arglist, ignore, 0, NULL_TREE);
+ break;
+ case BUILT_IN_FPUTS_UNLOCKED:
+ val = simplify_builtin_fputs (arglist, ignore, 1, NULL_TREE);
+ break;
+ case BUILT_IN_STRSTR:
+ val = simplify_builtin_strstr (arglist);
+ break;
+ case BUILT_IN_STRCAT:
+ val = simplify_builtin_strcat (arglist);
+ break;
+ case BUILT_IN_STRNCAT:
+ val = simplify_builtin_strncat (arglist);
+ break;
+ case BUILT_IN_STRSPN:
+ val = simplify_builtin_strspn (arglist);
+ break;
+ case BUILT_IN_STRCSPN:
+ val = simplify_builtin_strcspn (arglist);
+ break;
+ case BUILT_IN_STRCHR:
+ case BUILT_IN_INDEX:
+ val = simplify_builtin_strchr (arglist);
+ break;
+ case BUILT_IN_STRRCHR:
+ case BUILT_IN_RINDEX:
+ val = simplify_builtin_strrchr (arglist);
+ break;
+ case BUILT_IN_STRCPY:
+ val = simplify_builtin_strcpy (arglist, NULL_TREE);
+ break;
+ case BUILT_IN_STRNCPY:
+ val = simplify_builtin_strncpy (arglist, NULL_TREE);
+ break;
+ case BUILT_IN_STRCMP:
+ val = simplify_builtin_strcmp (arglist);
+ break;
+ case BUILT_IN_STRNCMP:
+ val = simplify_builtin_strncmp (arglist);
+ break;
+ case BUILT_IN_STRPBRK:
+ val = simplify_builtin_strpbrk (arglist);
+ break;
+ case BUILT_IN_BCMP:
+ case BUILT_IN_MEMCMP:
+ val = simplify_builtin_memcmp (arglist);
+ break;
+ case BUILT_IN_VA_START:
+ simplify_builtin_va_start (arglist);
+ val = NULL_TREE;
+ break;
+ case BUILT_IN_SPRINTF:
+ val = simplify_builtin_sprintf (arglist, ignore);
+ break;
+ case BUILT_IN_CONSTANT_P:
+ val = fold_builtin_constant_p (arglist);
+ /* Gimplification will pull the CALL_EXPR for the builtin out of
+ an if condition. When not optimizing, we'll not CSE it back.
+ To avoid link error types of regressions, return false now. */
+ if (!val && !optimize)
+ val = integer_zero_node;
+ break;
+ default:
+ val = NULL_TREE;
+ break;
+ }
+
+ if (val)
+ val = convert (TREE_TYPE (exp), val);
+ return val;
+}
+
+/* Simplify a call to the strstr builtin.
+
+ Return 0 if no simplification was possible, otherwise return the
+ simplified form of the call as a tree.
+
+ The simplified form may be a constant or other expression which
+ computes the same value, but in a more efficient manner (including
+ calls to other builtin functions).
+
+ The call may contain arguments which need to be evaluated, but
+ which are not useful to determine the result of the call. In
+ this case we return a chain of COMPOUND_EXPRs. The LHS of each
+ COMPOUND_EXPR will be an argument which must be evaluated.
+ COMPOUND_EXPRs are chained through their RHS. The RHS of the last
+ COMPOUND_EXPR in the chain will contain the tree for the simplified
+ form of the builtin function call. */
+
+static tree
+simplify_builtin_strstr (tree arglist)
+{
+ if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
+ return 0;
+ else
+ {
+ tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
+ tree fn;
+ const char *p1, *p2;
+
+ p2 = c_getstr (s2);
+ if (p2 == NULL)
+ return 0;
+
+ p1 = c_getstr (s1);
+ if (p1 != NULL)
+ {
+ const char *r = strstr (p1, p2);
+
+ /* Return an offset into the constant string argument. */
+ if (r == NULL)
+ return integer_zero_node;
+ else
+ return fold (build (PLUS_EXPR, TREE_TYPE (s1),
+ s1, convert (TREE_TYPE (s1),
+ ssize_int (r - p1))));
+ }
+
+ if (p2[0] == '\0')
+ return s1;
+
+ if (p2[1] != '\0')
+ return 0;
+
+ fn = implicit_built_in_decls[BUILT_IN_STRCHR];
+ if (!fn)
+ return 0;
+
+ /* New argument list transforming strstr(s1, s2) to
+ strchr(s1, s2[0]). */
+ arglist = build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
+ arglist = tree_cons (NULL_TREE, s1, arglist);
+ return build_function_call_expr (fn, arglist);
+ }
+}
+
+/* Simplify a call to the strstr builtin.
+
+ Return 0 if no simplification was possible, otherwise return the
+ simplified form of the call as a tree.
+
+ The simplified form may be a constant or other expression which
+ computes the same value, but in a more efficient manner (including
+ calls to other builtin functions).
+
+ The call may contain arguments which need to be evaluated, but
+ which are not useful to determine the result of the call. In
+ this case we return a chain of COMPOUND_EXPRs. The LHS of each
+ COMPOUND_EXPR will be an argument which must be evaluated.
+ COMPOUND_EXPRs are chained through their RHS. The RHS of the last
+ COMPOUND_EXPR in the chain will contain the tree for the simplified
+ form of the builtin function call. */
+
+static tree
+simplify_builtin_strchr (tree arglist)
+{
+ if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
+ return 0;
+ else
+ {
+ tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
+ const char *p1;
+
+ if (TREE_CODE (s2) != INTEGER_CST)
+ return 0;
+
+ p1 = c_getstr (s1);
+ if (p1 != NULL)
+ {
+ char c;
+ const char *r;
+
+ if (target_char_cast (s2, &c))
+ return 0;
+
+ r = strchr (p1, c);
+
+ if (r == NULL)
+ return integer_zero_node;
+
+ /* Return an offset into the constant string argument. */
+ return fold (build (PLUS_EXPR, TREE_TYPE (s1),
+ s1, convert (TREE_TYPE (s1),
+ ssize_int (r - p1))));
+ }
+
+ /* FIXME: Should use here strchrM optab so that ports can optimize
+ this. */
+ return 0;
+ }
+}
+
+/* Simplify a call to the strrchr builtin.
+
+ Return 0 if no simplification was possible, otherwise return the
+ simplified form of the call as a tree.
+
+ The simplified form may be a constant or other expression which
+ computes the same value, but in a more efficient manner (including
+ calls to other builtin functions).
+
+ The call may contain arguments which need to be evaluated, but
+ which are not useful to determine the result of the call. In
+ this case we return a chain of COMPOUND_EXPRs. The LHS of each
+ COMPOUND_EXPR will be an argument which must be evaluated.
+ COMPOUND_EXPRs are chained through their RHS. The RHS of the last
+ COMPOUND_EXPR in the chain will contain the tree for the simplified
+ form of the builtin function call. */
+
+static tree
+simplify_builtin_strrchr (tree arglist)
+{
+ if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
+ return 0;
+ else
+ {
+ tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
+ tree fn;
+ const char *p1;
+
+ if (TREE_CODE (s2) != INTEGER_CST)
+ return 0;
+
+ p1 = c_getstr (s1);
+ if (p1 != NULL)
+ {
+ char c;
+ const char *r;
+
+ if (target_char_cast (s2, &c))
+ return 0;
+
+ r = strrchr (p1, c);
+
+ if (r == NULL)
+ return integer_zero_node;
+
+ /* Return an offset into the constant string argument. */
+ return fold (build (PLUS_EXPR, TREE_TYPE (s1),
+ s1, convert (TREE_TYPE (s1),
+ ssize_int (r - p1))));
+ }
+
+ if (! integer_zerop (s2))
+ return 0;
+
+ fn = implicit_built_in_decls[BUILT_IN_STRCHR];
+ if (!fn)
+ return 0;
+
+ /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
+ return build_function_call_expr (fn, arglist);
+ }
+}
+
+/* Simplify a call to the strpbrk builtin.
+
+ Return 0 if no simplification was possible, otherwise return the
+ simplified form of the call as a tree.
+
+ The simplified form may be a constant or other expression which
+ computes the same value, but in a more efficient manner (including
+ calls to other builtin functions).
+
+ The call may contain arguments which need to be evaluated, but
+ which are not useful to determine the result of the call. In
+ this case we return a chain of COMPOUND_EXPRs. The LHS of each
+ COMPOUND_EXPR will be an argument which must be evaluated.
+ COMPOUND_EXPRs are chained through their RHS. The RHS of the last
+ COMPOUND_EXPR in the chain will contain the tree for the simplified
+ form of the builtin function call. */
+
+static tree
+simplify_builtin_strpbrk (tree arglist)
+{
+ if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
+ return 0;
+ else
+ {
+ tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
+ tree fn;
+ const char *p1, *p2;
+
+ p2 = c_getstr (s2);
+ if (p2 == NULL)
+ return 0;
+
+ p1 = c_getstr (s1);
+ if (p1 != NULL)
+ {
+ const char *r = strpbrk (p1, p2);
+
+ if (r == NULL)
+ return integer_zero_node;
+
+ /* Return an offset into the constant string argument. */
+ return fold (build (PLUS_EXPR, TREE_TYPE (s1),
+ s1, convert (TREE_TYPE (s1),
+ ssize_int (r - p1))));
+ }
+
+ if (p2[0] == '\0')
+ {
+ /* strpbrk(x, "") == NULL.
+ Evaluate and ignore the arguments in case they had
+ side-effects. */
+ return build (COMPOUND_EXPR, integer_type_node, s1,
+ integer_zero_node);
+ }
+
+ if (p2[1] != '\0')
+ return 0; /* Really call strpbrk. */
+
+ fn = implicit_built_in_decls[BUILT_IN_STRCHR];
+ if (!fn)
+ return 0;
+
+ /* New argument list transforming strpbrk(s1, s2) to
+ strchr(s1, s2[0]). */
+ arglist =
+ build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
+ arglist = tree_cons (NULL_TREE, s1, arglist);
+ return build_function_call_expr (fn, arglist);
+ }
+}
+
+/* Simplify a call to the strcpy builtin.
+
+ Return 0 if no simplification was possible, otherwise return the
+ simplified form of the call as a tree.
+
+ The simplified form may be a constant or other expression which
+ computes the same value, but in a more efficient manner (including
+ calls to other builtin functions).
+
+ The call may contain arguments which need to be evaluated, but
+ which are not useful to determine the result of the call. In
+ this case we return a chain of COMPOUND_EXPRs. The LHS of each
+ COMPOUND_EXPR will be an argument which must be evaluated.
+ COMPOUND_EXPRs are chained through their RHS. The RHS of the last
+ COMPOUND_EXPR in the chain will contain the tree for the simplified
+ form of the builtin function call. */
+
+tree
+simplify_builtin_strcpy (tree arglist, tree len)
+{
+ tree fn;
+
+ if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
+ return 0;
+
+ fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
+ if (!fn)
+ return 0;
+
+ if (!len)
+ {
+ len = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
+ if (!len)
+ return 0;
+ if (TREE_SIDE_EFFECTS (len))
+ return 0;
+ }
+
+ len = size_binop (PLUS_EXPR, len, ssize_int (1));
+ chainon (arglist, build_tree_list (NULL_TREE, len));
+ return build_function_call_expr (fn, arglist);
+}
+
+/* Simplify a call to the strncpy builtin.
+
+ Return 0 if no simplification was possible, otherwise return the
+ simplified form of the call as a tree.
+
+ The simplified form may be a constant or other expression which
+ computes the same value, but in a more efficient manner (including
+ calls to other builtin functions).
+
+ The call may contain arguments which need to be evaluated, but
+ which are not useful to determine the result of the call. In
+ this case we return a chain of COMPOUND_EXPRs. The LHS of each
+ COMPOUND_EXPR will be an argument which must be evaluated.
+ COMPOUND_EXPRs are chained through their RHS. The RHS of the last
+ COMPOUND_EXPR in the chain will contain the tree for the simplified
+ form of the builtin function call. */
+
+tree
+simplify_builtin_strncpy (tree arglist, tree slen)
+{
+ if (!validate_arglist (arglist,
+ POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
+ return 0;
+ else
+ {
+ tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
+ tree fn;
+
+ /* We must be passed a constant len parameter. */
+ if (TREE_CODE (len) != INTEGER_CST)
+ return 0;
+
+ /* If the len parameter is zero, return the dst parameter. */
+ if (integer_zerop (len))
+ {
+ /* Evaluate and ignore the src argument in case it has
+ side-effects and return the dst parameter. */
+ return build (COMPOUND_EXPR, TREE_TYPE (TREE_VALUE (arglist)),
+ TREE_VALUE (TREE_CHAIN (arglist)),
+ TREE_VALUE (arglist));
+ }
+
+ if (!slen)
+ slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 0);
+
+ /* Now, we must be passed a constant src ptr parameter. */
+ if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
+ return 0;
+
+ slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
+
+ /* We do not support simplification of this case, though we do
+ support it when expanding trees into RTL. */
+ /* FIXME: generate a call to __builtin_memset. */
+ if (tree_int_cst_lt (slen, len))
+ return 0;
+
+ /* OK transform into builtin memcpy. */
+ fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
+ if (!fn)
+ return 0;
+ return build_function_call_expr (fn, arglist);
+ }
+}
+
+/* Simplify a call to the memcmp builtin.
+
+ Return 0 if no simplification was possible, otherwise return the
+ simplified form of the call as a tree.
+
+ The simplified form may be a constant or other expression which
+ computes the same value, but in a more efficient manner (including
+ calls to other builtin functions).
+
+ The call may contain arguments which need to be evaluated, but
+ which are not useful to determine the result of the call. In
+ this case we return a chain of COMPOUND_EXPRs. The LHS of each
+ COMPOUND_EXPR will be an argument which must be evaluated.
+ COMPOUND_EXPRs are chained through their RHS. The RHS of the last
+ COMPOUND_EXPR in the chain will contain the tree for the simplified
+ form of the builtin function call. */
+
+static tree
+simplify_builtin_memcmp (tree arglist)
+{
+ tree arg1, arg2, len;
+ const char *p1, *p2;
+
+ if (!validate_arglist (arglist,
+ POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
+ return 0;
+
+ arg1 = TREE_VALUE (arglist);
+ arg2 = TREE_VALUE (TREE_CHAIN (arglist));
+ len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
+
+ /* If the len parameter is zero, return zero. */
+ if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
+ {
+ /* Evaluate and ignore arg1 and arg2 in case they have
+ side-effects. */
+ return build (COMPOUND_EXPR, integer_type_node, arg1,
+ build (COMPOUND_EXPR, integer_type_node,
+ arg2, integer_zero_node));
+ }
+
+ p1 = c_getstr (arg1);
+ p2 = c_getstr (arg2);
+
+ /* If all arguments are constant, and the value of len is not greater
+ than the lengths of arg1 and arg2, evaluate at compile-time. */
+ if (host_integerp (len, 1) && p1 && p2
+ && compare_tree_int (len, strlen (p1) + 1) <= 0
+ && compare_tree_int (len, strlen (p2) + 1) <= 0)
+ {
+ const int r = memcmp (p1, p2, tree_low_cst (len, 1));
+
+ return (r < 0
+ ? integer_minus_one_node
+ : (r > 0 ? integer_one_node : integer_zero_node));
+ }
+
+ /* If len parameter is one, return an expression corresponding to
+ (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
+ if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
+ {
+ tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
+ tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
+ tree ind1 =
+ fold (build1 (CONVERT_EXPR, integer_type_node,
+ build1 (INDIRECT_REF, cst_uchar_node,
+ build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
+ tree ind2 =
+ fold (build1 (CONVERT_EXPR, integer_type_node,
+ build1 (INDIRECT_REF, cst_uchar_node,
+ build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
+ return fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
+ }
+
+ return 0;
+}
+
+/* Simplify a call to the strcmp builtin.
+
+ Return 0 if no simplification was possible, otherwise return the
+ simplified form of the call as a tree.
+
+ The simplified form may be a constant or other expression which
+ computes the same value, but in a more efficient manner (including
+ calls to other builtin functions).
+
+ The call may contain arguments which need to be evaluated, but
+ which are not useful to determine the result of the call. In
+ this case we return a chain of COMPOUND_EXPRs. The LHS of each
+ COMPOUND_EXPR will be an argument which must be evaluated.
+ COMPOUND_EXPRs are chained through their RHS. The RHS of the last
+ COMPOUND_EXPR in the chain will contain the tree for the simplified
+ form of the builtin function call. */
+
+static tree
+simplify_builtin_strcmp (tree arglist)
+{
+ tree arg1, arg2;
+ const char *p1, *p2;
+
+ if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
+ return 0;
+
+ arg1 = TREE_VALUE (arglist);
+ arg2 = TREE_VALUE (TREE_CHAIN (arglist));
+
+ /* If both arguments are equal (and not volatile), return zero. */
+ if (operand_equal_p (arg1, arg2, 0))
+ return integer_zero_node;
+
+ p1 = c_getstr (arg1);
+ p2 = c_getstr (arg2);
+
+ if (p1 && p2)
+ {
+ const int i = strcmp (p1, p2);
+ return (i < 0
+ ? integer_minus_one_node
+ : (i > 0 ? integer_one_node : integer_zero_node));
+ }
+
+ /* If either arg is "", return an expression corresponding to
+ (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
+ if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
+ {
+ tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
+ tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
+ tree ind1 =
+ fold (build1 (CONVERT_EXPR, integer_type_node,
+ build1 (INDIRECT_REF, cst_uchar_node,
+ build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
+ tree ind2 =
+ fold (build1 (CONVERT_EXPR, integer_type_node,
+ build1 (INDIRECT_REF, cst_uchar_node,
+ build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
+ return fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
+ }
+
+ return 0;
+}
+
+/* Simplify a call to the strncmp builtin.
+
+ Return 0 if no simplification was possible, otherwise return the
+ simplified form of the call as a tree.
+
+ The simplified form may be a constant or other expression which
+ computes the same value, but in a more efficient manner (including
+ calls to other builtin functions).
+
+ The call may contain arguments which need to be evaluated, but
+ which are not useful to determine the result of the call. In
+ this case we return a chain of COMPOUND_EXPRs. The LHS of each
+ COMPOUND_EXPR will be an argument which must be evaluated.
+ COMPOUND_EXPRs are chained through their RHS. The RHS of the last
+ COMPOUND_EXPR in the chain will contain the tree for the simplified
+ form of the builtin function call. */
+
+static tree
+simplify_builtin_strncmp (tree arglist)
+{
+ tree arg1, arg2, arg3;
+ const char *p1, *p2;
+
+ if (!validate_arglist (arglist,
+ POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
+ return 0;
+
+ arg1 = TREE_VALUE (arglist);
+ arg2 = TREE_VALUE (TREE_CHAIN (arglist));
+ arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
+
+ /* If the len parameter is zero, return zero. */
+ if (integer_zerop (arg3))
+ {
+ /* Evaluate and ignore arg1 and arg2 in case they have
+ side-effects. */
+ return build (COMPOUND_EXPR, integer_type_node, arg1,
+ build (COMPOUND_EXPR, integer_type_node,
+ arg2, integer_zero_node));
+ }
+
+ /* If arg1 and arg2 are equal (and not volatile), return zero. */
+ if (operand_equal_p (arg1, arg2, 0))
+ {
+ /* Evaluate and ignore arg3 in case it has side-effects. */
+ return build (COMPOUND_EXPR, integer_type_node, arg3, integer_zero_node);
+ }
+
+ p1 = c_getstr (arg1);
+ p2 = c_getstr (arg2);
+
+ /* If all arguments are constant, evaluate at compile-time. */
+ if (host_integerp (arg3, 1) && p1 && p2)
+ {
+ const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
+ return (r < 0
+ ? integer_minus_one_node
+ : (r > 0 ? integer_one_node : integer_zero_node));
+ }
+
+ /* If len == 1 or (either string parameter is "" and (len >= 1)),
+ return (*(const u_char*)arg1 - *(const u_char*)arg2). */
+ if (host_integerp (arg3, 1)
+ && (tree_low_cst (arg3, 1) == 1
+ || (tree_low_cst (arg3, 1) > 1
+ && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
+ {
+ tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
+ tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
+ tree ind1 =
+ fold (build1 (CONVERT_EXPR, integer_type_node,
+ build1 (INDIRECT_REF, cst_uchar_node,
+ build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
+ tree ind2 =
+ fold (build1 (CONVERT_EXPR, integer_type_node,
+ build1 (INDIRECT_REF, cst_uchar_node,
+ build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
+ return fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
+ }
+
+ return 0;
+}
+
+/* Simplify a call to the strcat builtin.
+
+ Return 0 if no simplification was possible, otherwise return the
+ simplified form of the call as a tree.
+
+ The simplified form may be a constant or other expression which
+ computes the same value, but in a more efficient manner (including
+ calls to other builtin functions).
+
+ The call may contain arguments which need to be evaluated, but
+ which are not useful to determine the result of the call. In
+ this case we return a chain of COMPOUND_EXPRs. The LHS of each
+ COMPOUND_EXPR will be an argument which must be evaluated.
+ COMPOUND_EXPRs are chained through their RHS. The RHS of the last
+ COMPOUND_EXPR in the chain will contain the tree for the simplified
+ form of the builtin function call. */
+
+static tree
+simplify_builtin_strcat (tree arglist)
+{
+ if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
+ return 0;
+ else
+ {
+ tree dst = TREE_VALUE (arglist),
+ src = TREE_VALUE (TREE_CHAIN (arglist));
+ const char *p = c_getstr (src);
+
+ /* If the string length is zero, return the dst parameter. */
+ if (p && *p == '\0')
+ return dst;
+
+ return 0;
+ }
+}
+
+/* Simplify a call to the strncat builtin.
+
+ Return 0 if no simplification was possible, otherwise return the
+ simplified form of the call as a tree.
+
+ The simplified form may be a constant or other expression which
+ computes the same value, but in a more efficient manner (including
+ calls to other builtin functions).
+
+ The call may contain arguments which need to be evaluated, but
+ which are not useful to determine the result of the call. In
+ this case we return a chain of COMPOUND_EXPRs. The LHS of each
+ COMPOUND_EXPR will be an argument which must be evaluated.
+ COMPOUND_EXPRs are chained through their RHS. The RHS of the last
+ COMPOUND_EXPR in the chain will contain the tree for the simplified
+ form of the builtin function call. */
+
+static tree
+simplify_builtin_strncat (tree arglist)
+{
+ if (!validate_arglist (arglist,
+ POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
+ return 0;
+ else
+ {
+ tree dst = TREE_VALUE (arglist);
+ tree src = TREE_VALUE (TREE_CHAIN (arglist));
+ tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
+ const char *p = c_getstr (src);
+
+ /* If the requested length is zero, or the src parameter string
+ length is zero, return the dst parameter. */
+ if (integer_zerop (len) || (p && *p == '\0'))
+ return build (COMPOUND_EXPR, TREE_TYPE (dst), src,
+ build (COMPOUND_EXPR, integer_type_node, len, dst));
+
+ /* If the requested len is greater than or equal to the string
+ length, call strcat. */
+ if (TREE_CODE (len) == INTEGER_CST && p
+ && compare_tree_int (len, strlen (p)) >= 0)
+ {
+ tree newarglist
+ = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
+ tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
+
+ /* If the replacement _DECL isn't initialized, don't do the
+ transformation. */
+ if (!fn)
+ return 0;
+
+ return build_function_call_expr (fn, newarglist);
+ }
+ return 0;
+ }
+}
+
+/* Simplify a call to the strspn builtin.
+
+ Return 0 if no simplification was possible, otherwise return the
+ simplified form of the call as a tree.
+
+ The simplified form may be a constant or other expression which
+ computes the same value, but in a more efficient manner (including
+ calls to other builtin functions).
+
+ The call may contain arguments which need to be evaluated, but
+ which are not useful to determine the result of the call. In
+ this case we return a chain of COMPOUND_EXPRs. The LHS of each
+ COMPOUND_EXPR will be an argument which must be evaluated.
+ COMPOUND_EXPRs are chained through their RHS. The RHS of the last
+ COMPOUND_EXPR in the chain will contain the tree for the simplified
+ form of the builtin function call. */
+
+static tree
+simplify_builtin_strspn (tree arglist)
+{
+ if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
+ return 0;
+ else
+ {
+ tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
+ const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
+
+ /* If both arguments are constants, evaluate at compile-time. */
+ if (p1 && p2)
+ {
+ const size_t r = strspn (p1, p2);
+ return size_int (r);
+ }
+
+ /* If either argument is "", return 0. */
+ if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
+ {
+ /* Evaluate and ignore both arguments in case either one has
+ side-effects. */
+ return build (COMPOUND_EXPR, integer_type_node, s1,
+ build (COMPOUND_EXPR, integer_type_node,
+ s2, integer_zero_node));
+ }
+ return 0;
+ }
+}
+
+/* Simplify a call to the strcspn builtin.
+
+ Return 0 if no simplification was possible, otherwise return the
+ simplified form of the call as a tree.
+
+ The simplified form may be a constant or other expression which
+ computes the same value, but in a more efficient manner (including
+ calls to other builtin functions).
+
+ The call may contain arguments which need to be evaluated, but
+ which are not useful to determine the result of the call. In
+ this case we return a chain of COMPOUND_EXPRs. The LHS of each
+ COMPOUND_EXPR will be an argument which must be evaluated.
+ COMPOUND_EXPRs are chained through their RHS. The RHS of the last
+ COMPOUND_EXPR in the chain will contain the tree for the simplified
+ form of the builtin function call. */
+
+static tree
+simplify_builtin_strcspn (tree arglist)
+{
+ if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
+ return 0;
+ else
+ {
+ tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
+ const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
+
+ /* If both arguments are constants, evaluate at compile-time. */
+ if (p1 && p2)
+ {
+ const size_t r = strcspn (p1, p2);
+ return size_int (r);
+ }
+
+ /* If the first argument is "", return 0. */
+ if (p1 && *p1 == '\0')
+ {
+ /* Evaluate and ignore argument s2 in case it has
+ side-effects. */
+ return build (COMPOUND_EXPR, integer_type_node,
+ s2, integer_zero_node);
+ }
+
+ /* If the second argument is "", return __builtin_strlen(s1). */
+ if (p2 && *p2 == '\0')
+ {
+ tree newarglist = build_tree_list (NULL_TREE, s1),
+ fn = implicit_built_in_decls[BUILT_IN_STRLEN];
+
+ /* If the replacement _DECL isn't initialized, don't do the
+ transformation. */
+ if (!fn)
+ return 0;
+
+ return build_function_call_expr (fn, newarglist);
+ }
+ return 0;
+ }
+}
+
+/* Simplify a call to the fputs builtin.
+
+ Return 0 if no simplification was possible, otherwise return the
+ simplified form of the call as a tree.
+
+ The simplified form may be a constant or other expression which
+ computes the same value, but in a more efficient manner (including
+ calls to other builtin functions).
+
+ The call may contain arguments which need to be evaluated, but
+ which are not useful to determine the result of the call. In
+ this case we return a chain of COMPOUND_EXPRs. The LHS of each
+ COMPOUND_EXPR will be an argument which must be evaluated.
+ COMPOUND_EXPRs are chained through their RHS. The RHS of the last
+ COMPOUND_EXPR in the chain will contain the tree for the simplified
+ form of the builtin function call.
+
+ If KNOWN_LEN is non-NULL, it represents the known length of the string.
+ This is determined by SSA-CCP in cases where the string itself is not
+ known to be constant but its length is always the same constant. */
+
+tree
+simplify_builtin_fputs (tree arglist, int ignore, int unlocked, tree known_len)
+{
+ tree len, fn;
+ tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
+ : implicit_built_in_decls[BUILT_IN_FPUTC];
+ tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
+ : implicit_built_in_decls[BUILT_IN_FWRITE];
+
+ /* If the return value is used, or the replacement _DECL isn't
+ initialized, don't do the transformation. */
+ if (!ignore || !fn_fputc || !fn_fwrite)
+ return 0;
+
+ /* Verify the arguments in the original call. */
+ if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
+ return 0;
+
+ len = (known_len) ? known_len : c_strlen (TREE_VALUE (arglist), 0);
+
+ /* Get the length of the string passed to fputs. If the length
+ can't be determined, punt. */
+ if (!len
+ || TREE_CODE (len) != INTEGER_CST)
+ return 0;
+
+ switch (compare_tree_int (len, 1))
+ {
+ case -1: /* length is 0, delete the call entirely . */
+ {
+ return build (COMPOUND_EXPR, integer_type_node,
+ TREE_VALUE (TREE_CHAIN (arglist)), integer_zero_node);
+ }
+ case 0: /* length is 1, call fputc. */
+ {
+ const char *p = c_getstr (TREE_VALUE (arglist));
+
+ if (p != NULL)
+ {
+ /* New argument list transforming fputs(string, stream) to
+ fputc(string[0], stream). */
+ arglist =
+ build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
+ arglist =
+ tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
+ fn = fn_fputc;
+ break;
+ }
+ }
+ /* FALLTHROUGH */
+ case 1: /* length is greater than 1, call fwrite. */
+ {
+ tree string_arg;
+
+ /* If optimizing for size keep fputs. */
+ if (optimize_size)
+ return 0;
+ string_arg = TREE_VALUE (arglist);
+ /* New argument list transforming fputs(string, stream) to
+ fwrite(string, 1, len, stream). */
+ arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
+ arglist = tree_cons (NULL_TREE, len, arglist);
+ arglist = tree_cons (NULL_TREE, size_one_node, arglist);
+ arglist = tree_cons (NULL_TREE, string_arg, arglist);
+ fn = fn_fwrite;
+ break;
+ }
+ default:
+ abort ();
+ }
+
+ return build_function_call_expr (fn, arglist);
+}
+
+static void
+simplify_builtin_va_start (tree arglist)
+{
+ tree chain = TREE_CHAIN (arglist);
+
+ if (TREE_CHAIN (chain))
+ error ("too many arguments to function `va_start'");
+
+ simplify_builtin_next_arg (chain);
+}
+
+static void
+simplify_builtin_next_arg (tree arglist)
+{
+ tree fntype = TREE_TYPE (current_function_decl);
+
+ if (TYPE_ARG_TYPES (fntype) == 0
+ || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
+ == void_type_node))
+ error ("`va_start' used in function with fixed args");
+ else if (arglist)
+ {
+ tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
+ tree arg = TREE_VALUE (arglist);
+
+ /* Strip off all nops for the sake of the comparison. This
+ is not quite the same as STRIP_NOPS. It does more.
+ We must also strip off INDIRECT_EXPR for C++ reference
+ parameters. */
+ while (TREE_CODE (arg) == NOP_EXPR
+ || TREE_CODE (arg) == CONVERT_EXPR
+ || TREE_CODE (arg) == NON_LVALUE_EXPR
+ || TREE_CODE (arg) == INDIRECT_REF)
+ arg = TREE_OPERAND (arg, 0);
+ if (arg != last_parm)
+ warning ("second parameter of `va_start' not last named argument");
+ TREE_VALUE (arglist) = arg;
+ }
+ else
+ /* Evidently an out of date version of <stdarg.h>; can't validate
+ va_start's second argument, but can still work as intended. */
+ warning ("`__builtin_next_arg' called without an argument");
+}
+
+
+/* Simplify a call to the sprintf builtin.
+
+ Return 0 if no simplification was possible, otherwise return the
+ simplified form of the call as a tree. If IGNORED is true, it means that
+ the caller does not use the returned value of the function. */
+
+static tree
+simplify_builtin_sprintf (tree arglist, int ignored)
+{
+ tree call, retval, dest, fmt;
+ const char *fmt_str = NULL;
+
+ /* Verify the required arguments in the original call. We deal with two
+ types of sprintf() calls: 'sprintf (str, fmt)' and
+ 'sprintf (dest, "%s", orig)'. */
+ if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
+ && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
+ VOID_TYPE))
+ return NULL_TREE;
+
+ /* Get the destination string and the format specifier. */
+ dest = TREE_VALUE (arglist);
+ fmt = TREE_VALUE (TREE_CHAIN (arglist));
+
+ /* Check whether the format is a literal string constant. */
+ fmt_str = c_getstr (fmt);
+ if (fmt_str == NULL)
+ return NULL_TREE;
+
+ call = NULL_TREE;
+ retval = NULL_TREE;
+
+ /* If the format doesn't contain % args or %%, use strcpy. */
+ if (strchr (fmt_str, '%') == NULL)
+ {
+ tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
+
+ if (!fn)
+ return NULL_TREE;
+
+ /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
+ 'format' is known to contain no % formats. */
+ arglist = build_tree_list (NULL_TREE, fmt);
+ arglist = tree_cons (NULL_TREE, dest, arglist);
+ call = build_function_call_expr (fn, arglist);
+ if (!ignored)
+ retval = build_int_2 (strlen (fmt_str), 0);
+ }
+
+ /* If the format is "%s", use strcpy if the result isn't used. */
+ else if (fmt_str && strcmp (fmt_str, "%s") == 0)
+ {
+ tree fn, orig;
+ fn = implicit_built_in_decls[BUILT_IN_STRCPY];
+
+ if (!fn)
+ return NULL_TREE;
+
+ /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
+ orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
+ arglist = build_tree_list (NULL_TREE, orig);
+ arglist = tree_cons (NULL_TREE, dest, arglist);
+ if (!ignored)
+ {
+ retval = c_strlen (orig, 1);
+ if (!retval || TREE_CODE (retval) != INTEGER_CST)
+ return NULL_TREE;
+ }
+ call = build_function_call_expr (fn, arglist);
+ }
+
+ if (call && retval)
+ {
+ retval = convert
+ (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
+ retval);
+ return build (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
+ }
+ else
+ return call;
+}
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 0d2be2c437a..f52b128d2e5 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -504,14 +504,14 @@ DEF_LIB_BUILTIN (BUILT_IN_ISALPHA, "isalpha", BT_FN_INT_INT, ATTR_PURE_NO
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISASCII, "isascii", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LIST)
DEF_C99_BUILTIN (BUILT_IN_ISBLANK, "isblank", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
DEF_LIB_BUILTIN (BUILT_IN_ISCNTRL, "iscntrl", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
-DEF_LIB_BUILTIN (BUILT_IN_ISDIGIT, "isdigit", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
+DEF_LIB_BUILTIN (BUILT_IN_ISDIGIT, "isdigit", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LIST)
DEF_LIB_BUILTIN (BUILT_IN_ISGRAPH, "isgraph", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
DEF_LIB_BUILTIN (BUILT_IN_ISLOWER, "islower", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
DEF_LIB_BUILTIN (BUILT_IN_ISPRINT, "isprint", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
DEF_LIB_BUILTIN (BUILT_IN_ISPUNCT, "ispunct", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
DEF_LIB_BUILTIN (BUILT_IN_ISSPACE, "isspace", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
DEF_LIB_BUILTIN (BUILT_IN_ISUPPER, "isupper", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
-DEF_LIB_BUILTIN (BUILT_IN_ISXDIGIT, "isxdigit", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
+DEF_LIB_BUILTIN (BUILT_IN_ISXDIGIT, "isxdigit", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LIST)
DEF_EXT_LIB_BUILTIN (BUILT_IN_TOASCII, "toascii", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LIST)
DEF_LIB_BUILTIN (BUILT_IN_TOLOWER, "tolower", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
DEF_LIB_BUILTIN (BUILT_IN_TOUPPER, "toupper", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
@@ -555,10 +555,17 @@ DEF_GCC_BUILTIN (BUILT_IN_DWARF_CFA, "dwarf_cfa", BT_FN_PTR, ATTR_NULL)
DEF_GCC_BUILTIN (BUILT_IN_DWARF_SP_COLUMN, "dwarf_sp_column", BT_FN_UNSIGNED, ATTR_NULL)
DEF_GCC_BUILTIN (BUILT_IN_EH_RETURN, "eh_return", BT_FN_VOID_PTRMODE_PTR, ATTR_NORETURN_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_EH_RETURN_DATA_REGNO, "eh_return_data_regno", BT_FN_INT_INT, ATTR_NULL)
+DEF_LIB_BUILTIN (BUILT_IN_EXECL, "execl", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_NOTHROW_LIST)
+DEF_LIB_BUILTIN (BUILT_IN_EXECLP, "execlp", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_NOTHROW_LIST)
+DEF_LIB_BUILTIN (BUILT_IN_EXECLE, "execle", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_NOTHROW_LIST)
+DEF_LIB_BUILTIN (BUILT_IN_EXECV, "execv", BT_FN_INT_CONST_STRING_PTR_CONST_STRING, ATTR_NOTHROW_LIST)
+DEF_LIB_BUILTIN (BUILT_IN_EXECVP, "execvp", BT_FN_INT_CONST_STRING_PTR_CONST_STRING, ATTR_NOTHROW_LIST)
+DEF_LIB_BUILTIN (BUILT_IN_EXECVE, "execve", BT_FN_INT_CONST_STRING_PTR_CONST_STRING_PTR_CONST_STRING, ATTR_NOTHROW_LIST)
DEF_LIB_BUILTIN (BUILT_IN_EXIT, "exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_EXPECT, "expect", BT_FN_LONG_LONG_LONG, ATTR_NULL)
DEF_GCC_BUILTIN (BUILT_IN_EXTEND_POINTER, "extend_pointer", BT_FN_WORD_PTR, ATTR_CONST_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_EXTRACT_RETURN_ADDR, "extract_return_addr", BT_FN_PTR_PTR, ATTR_NULL)
+DEF_LIB_BUILTIN (BUILT_IN_FORK, "fork", BT_FN_PID, ATTR_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_FRAME_ADDRESS, "frame_address", BT_FN_PTR_UNSIGNED, ATTR_NULL)
DEF_GCC_BUILTIN (BUILT_IN_FROB_RETURN_ADDR, "frob_return_addr", BT_FN_PTR_PTR, ATTR_NULL)
DEF_EXT_LIB_BUILTIN (BUILT_IN_GETTEXT, "gettext", BT_FN_STRING_CONST_STRING, ATTR_FORMAT_ARG_1)
@@ -586,13 +593,26 @@ DEF_GCC_BUILTIN (BUILT_IN_RETURN, "return", BT_FN_VOID_PTR, ATTR_NORETURN
DEF_GCC_BUILTIN (BUILT_IN_RETURN_ADDRESS, "return_address", BT_FN_PTR_UNSIGNED, ATTR_NULL)
DEF_GCC_BUILTIN (BUILT_IN_SAVEREGS, "saveregs", BT_FN_PTR_VAR, ATTR_NULL)
DEF_GCC_BUILTIN (BUILT_IN_SETJMP, "setjmp", BT_FN_INT_PTR, ATTR_NULL)
+DEF_GCC_BUILTIN (BUILT_IN_STACK_ALLOC, "stack_alloc", BT_FN_VOID_PTR_SIZE, ATTR_NULL)
+DEF_GCC_BUILTIN (BUILT_IN_STACK_SAVE, "stack_save", BT_FN_PTR, ATTR_NULL)
+DEF_GCC_BUILTIN (BUILT_IN_STACK_RESTORE, "stack_restore", BT_FN_VOID_PTR, ATTR_NULL)
DEF_GCC_BUILTIN (BUILT_IN_STDARG_START, "stdarg_start", BT_FN_VOID_VALIST_REF_VAR, ATTR_NULL)
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRFMON, "strfmon", BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_STRFMON_3_4)
DEF_LIB_BUILTIN (BUILT_IN_STRFTIME, "strftime", BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR, ATTR_FORMAT_STRFTIME_3_0)
DEF_GCC_BUILTIN (BUILT_IN_TRAP, "trap", BT_FN_VOID, ATTR_NORETURN_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_UNWIND_INIT, "unwind_init", BT_FN_VOID, ATTR_NULL)
+DEF_GCC_BUILTIN (BUILT_IN_UPDATE_SETJMP_BUF, "update_setjmp_buf", BT_FN_VOID_PTR_INT, ATTR_NULL)
DEF_GCC_BUILTIN (BUILT_IN_VA_COPY, "va_copy", BT_FN_VOID_VALIST_REF_VALIST_ARG, ATTR_NULL)
DEF_GCC_BUILTIN (BUILT_IN_VA_END, "va_end", BT_FN_VOID_VALIST_REF, ATTR_NULL)
DEF_GCC_BUILTIN (BUILT_IN_VA_START, "va_start", BT_FN_VOID_VALIST_REF_VAR, ATTR_NULL)
DEF_EXT_LIB_BUILTIN (BUILT_IN__EXIT, "_exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST)
DEF_C99_BUILTIN (BUILT_IN__EXIT2, "_Exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_INIT_TRAMPOLINE, "init_trampoline", BT_FN_VOID_PTR_PTR_PTR, ATTR_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_ADJUST_TRAMPOLINE, "adjust_trampoline", BT_FN_PTR_PTR, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_NONLOCAL_GOTO, "nonlocal_goto", BT_FN_PTR_PTR, ATTR_NORETURN_NOTHROW_LIST)
+
+/* Profiling hooks. */
+DEF_GCC_BUILTIN (BUILT_IN_PROFILE_FUNC_ENTER, "profile_func_enter",
+ BT_FN_VOID, ATTR_NULL)
+DEF_GCC_BUILTIN (BUILT_IN_PROFILE_FUNC_EXIT, "profile_func_exit",
+ BT_FN_VOID, ATTR_NULL)
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 9c868291e09..11b4b875d2c 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -42,6 +42,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tree-inline.h"
#include "c-tree.h"
#include "toplev.h"
+#include "tree-iterator.h"
+#include "hashtab.h"
cpp_reader *parse_in; /* Declared in c-pragma.h. */
@@ -55,6 +57,10 @@ cpp_reader *parse_in; /* Declared in c-pragma.h. */
#define SIZE_TYPE "long unsigned int"
#endif
+#ifndef PID_TYPE
+#define PID_TYPE "int"
+#endif
+
#ifndef WCHAR_TYPE
#define WCHAR_TYPE "int"
#endif
@@ -677,6 +683,15 @@ tree *ridpointers;
tree (*make_fname_decl) (tree, int);
+/* If non-NULL, the address of a language-specific function that
+ returns 1 for language-specific statement codes. */
+int (*lang_statement_code_p) (enum tree_code);
+
+/* If non-NULL, the address of a language-specific function that does any
+ language-specific gimplification for _STMT nodes and returns 1 iff
+ handled. */
+int (*lang_gimplify_stmt) (tree *, tree *);
+
/* If non-NULL, the address of a language-specific function that takes
any action required right before expand_function_end is called. */
void (*lang_expand_function_end) (void);
@@ -914,7 +929,7 @@ c_expand_end_cond (void)
if_stack_pointer--;
if (if_stack[if_stack_pointer].needs_warning)
warning ("%Hsuggest explicit braces to avoid ambiguous `else'",
- &if_stack[if_stack_pointer].locus);
+ &if_stack[if_stack_pointer].locus);
last_expr_type = NULL_TREE;
}
@@ -1179,6 +1194,7 @@ fix_string_type (tree value)
build_index_type (build_int_2 (nchars - 1, 0)));
TREE_CONSTANT (value) = 1;
+ TREE_INVARIANT (value) = 1;
TREE_READONLY (value) = 1;
TREE_STATIC (value) = 1;
return value;
@@ -1273,6 +1289,16 @@ constant_fits_type_p (tree c, tree type)
return !TREE_OVERFLOW (c);
}
+/* Nonzero if vector types T1 and T2 can be converted to each other
+ without an explicit cast. */
+int
+vector_types_convertible_p (tree t1, tree t2)
+{
+ return targetm.vector_opaque_p (t1)
+ || targetm.vector_opaque_p (t2)
+ || TYPE_MODE (t1) == TYPE_MODE (t2);
+}
+
/* Convert EXPR to TYPE, warning about conversion problems with constants.
Invoke this function on every expression that is converted implicitly,
i.e. because of language rules and not because of an explicit cast. */
@@ -1301,7 +1327,7 @@ convert_and_check (tree type, tree expr)
|| TYPE_UNSIGNED (type)
|| ! constant_fits_type_p (expr,
c_common_unsigned_type (type)))
- && skip_evaluation == 0)
+ && skip_evaluation == 0)
warning ("overflow in implicit constant conversion");
}
else
@@ -1666,7 +1692,6 @@ verify_tree (tree x, struct tlist **pbefore_sp, struct tlist **pno_sp,
case 'r':
case '<':
case '2':
- case 'b':
case 'e':
case 's':
case 'x':
@@ -1837,7 +1862,7 @@ c_common_type_for_mode (enum machine_mode mode, int unsignedp)
if (mode == TYPE_MODE (widest_integer_literal_type_node))
return unsignedp ? widest_unsigned_literal_type_node
- : widest_integer_literal_type_node;
+ : widest_integer_literal_type_node;
if (mode == QImode)
return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
@@ -2459,9 +2484,6 @@ pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
{
tree size_exp;
- tree result;
- tree folded;
-
/* The result is a pointer of the same type that is being added. */
tree result_type = TREE_TYPE (ptrop);
@@ -2535,13 +2557,7 @@ pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
convert (TREE_TYPE (intop), size_exp), 1));
/* Create the sum or difference. */
-
- result = build (resultcode, result_type, ptrop, intop);
-
- folded = fold (result);
- if (folded == result)
- TREE_CONSTANT (folded) = TREE_CONSTANT (ptrop) & TREE_CONSTANT (intop);
- return folded;
+ return fold (build (resultcode, result_type, ptrop, intop));
}
/* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
@@ -2782,6 +2798,49 @@ c_apply_type_quals_to_decl (int type_quals, tree decl)
}
}
+/* Hash function for the problem of multiple type definitions in
+ different files. This must hash all types that will compare
+ equal via comptypes to the same value. In practice it hashes
+ on some of the simple stuff and leaves the details to comptypes. */
+
+static hashval_t
+c_type_hash (const void *p)
+{
+ int i = 0;
+ int shift, size;
+ tree t = (tree)p;
+ tree t2;
+ switch (TREE_CODE (t))
+ {
+ /* For pointers, hash on pointee type plus some swizzling. */
+ case POINTER_TYPE:
+ return c_type_hash (TREE_TYPE (t)) ^ 0x3003003;
+ /* Hash on number of elements and total size. */
+ case ENUMERAL_TYPE:
+ shift = 3;
+ t2 = TYPE_VALUES (t);
+ break;
+ case RECORD_TYPE:
+ shift = 0;
+ t2 = TYPE_FIELDS (t);
+ break;
+ case QUAL_UNION_TYPE:
+ shift = 1;
+ t2 = TYPE_FIELDS (t);
+ break;
+ case UNION_TYPE:
+ shift = 2;
+ t2 = TYPE_FIELDS (t);
+ break;
+ default:
+ abort ();
+ }
+ for (; t2; t2 = TREE_CHAIN (t2))
+ i++;
+ size = TREE_INT_CST_LOW (TYPE_SIZE (t));
+ return ((size << 24) | (i << shift));
+}
+
/* Return the typed-based alias set for T, which may be an expression
or a type. Return -1 if we don't do anything special. */
@@ -2789,6 +2848,8 @@ HOST_WIDE_INT
c_common_get_alias_set (tree t)
{
tree u;
+ PTR *slot;
+ static htab_t type_hash_table;
/* Permit type-punning when accessing a union, provided the access
is directly through the union. For example, this code does not
@@ -2845,14 +2906,14 @@ c_common_get_alias_set (tree t)
technically, an `int **' and `const int **' cannot point at
the same thing.
- But, the standard is wrong. In particular, this code is
+ But, the standard is wrong. In particular, this code is
legal C++:
int *ip;
int **ipp = &ip;
const int* const* cipp = ipp;
- And, it doesn't make sense for that to be legal unless you
+ And, it doesn't make sense for that to be legal unless you
can dereference IPP and CIPP. So, we ignore cv-qualifiers on
the pointed-to types. This issue has been reported to the
C++ committee. */
@@ -2861,6 +2922,63 @@ c_common_get_alias_set (tree t)
return get_alias_set (t1);
}
+ /* Handle the case of multiple type nodes referring to "the same" type,
+ which occurs with IMA. These share an alias set. FIXME: Currently only
+ C90 is handled. (In C99 type compatibility is not transitive, which
+ complicates things mightily. The alias set splay trees can theoretically
+ represent this, but insertion is tricky when you consider all the
+ different orders things might arrive in.) */
+
+ if (c_language != clk_c || flag_isoc99)
+ return -1;
+
+ /* Save time if there's only one input file. */
+ if (!current_file_decl || TREE_CHAIN (current_file_decl) == NULL_TREE)
+ return -1;
+
+ /* Pointers need special handling if they point to any type that
+ needs special handling (below). */
+ if (TREE_CODE (t) == POINTER_TYPE)
+ {
+ tree t2;
+ /* Find bottom type under any nested POINTERs. */
+ for (t2 = TREE_TYPE (t);
+ TREE_CODE (t2) == POINTER_TYPE;
+ t2 = TREE_TYPE (t2))
+ ;
+ if (TREE_CODE (t2) != RECORD_TYPE
+ && TREE_CODE (t2) != ENUMERAL_TYPE
+ && TREE_CODE (t2) != QUAL_UNION_TYPE
+ && TREE_CODE (t2) != UNION_TYPE)
+ return -1;
+ if (TYPE_SIZE (t2) == 0)
+ return -1;
+ }
+ /* These are the only cases that need special handling. */
+ if (TREE_CODE (t) != RECORD_TYPE
+ && TREE_CODE (t) != ENUMERAL_TYPE
+ && TREE_CODE (t) != QUAL_UNION_TYPE
+ && TREE_CODE (t) != UNION_TYPE
+ && TREE_CODE (t) != POINTER_TYPE)
+ return -1;
+ /* Undefined? */
+ if (TYPE_SIZE (t) == 0)
+ return -1;
+
+ /* Look up t in hash table. Only one of the compatible types within each
+ alias set is recorded in the table. */
+ if (!type_hash_table)
+ type_hash_table = htab_create (1021, c_type_hash,
+ (htab_eq) lang_hooks.types_compatible_p,
+ NULL);
+ slot = htab_find_slot (type_hash_table, t, INSERT);
+ if (*slot != NULL)
+ return TYPE_ALIAS_SET ((tree)*slot);
+ else
+ /* Our caller will assign and record (in t) a new alias set; all we need
+ to do is remember t in the hash table. */
+ *slot = t;
+
return -1;
}
@@ -3113,6 +3231,9 @@ c_common_nodes_and_builtins (void)
signed_size_type_node = c_common_signed_type (size_type_node);
set_sizetype (size_type_node);
+ pid_type_node =
+ TREE_TYPE (identifier_global_value (get_identifier (PID_TYPE)));
+
build_common_tree_nodes_2 (flag_short_double);
record_builtin_type (RID_FLOAT, NULL, float_type_node);
@@ -3396,7 +3517,7 @@ c_common_nodes_and_builtins (void)
\
built_in_decls[(int) ENUM] = decl; \
if (IMPLICIT) \
- implicit_built_in_decls[(int) ENUM] = decl; \
+ implicit_built_in_decls[(int) ENUM] = decl; \
}
#include "builtins.def"
#undef DEF_BUILTIN
@@ -3826,19 +3947,12 @@ c_add_case_label (splay_tree cases, tree cond, tree low_value,
splay_tree_node node;
/* Create the LABEL_DECL itself. */
- label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
- DECL_CONTEXT (label) = current_function_decl;
+ label = create_artificial_label ();
/* If there was an error processing the switch condition, bail now
before we get more confused. */
if (!cond || cond == error_mark_node)
- {
- /* Add a label anyhow so that the back-end doesn't think that
- the beginning of the switch is unreachable. */
- if (!cases->root)
- add_stmt (build_case_label (NULL_TREE, NULL_TREE, label));
- return error_mark_node;
- }
+ goto error_out;
if ((low_value && TREE_TYPE (low_value)
&& POINTER_TYPE_P (TREE_TYPE (low_value)))
@@ -3864,11 +3978,7 @@ c_add_case_label (splay_tree cases, tree cond, tree low_value,
/* If an error has occurred, bail out now. */
if (low_value == error_mark_node || high_value == error_mark_node)
- {
- if (!cases->root)
- add_stmt (build_case_label (NULL_TREE, NULL_TREE, label));
- return error_mark_node;
- }
+ goto error_out;
/* If the LOW_VALUE and HIGH_VALUE are the same, then this isn't
really a case range, even though it was written that way. Remove
@@ -3941,8 +4051,7 @@ c_add_case_label (splay_tree cases, tree cond, tree low_value,
error ("multiple default labels in one switch");
error ("%Jthis is the first default label", duplicate);
}
- if (!cases->root)
- add_stmt (build_case_label (NULL_TREE, NULL_TREE, label));
+ goto error_out;
}
/* Add a CASE_LABEL to the statement-tree. */
@@ -3953,6 +4062,160 @@ c_add_case_label (splay_tree cases, tree cond, tree low_value,
(splay_tree_value) case_label);
return case_label;
+
+ error_out:
+ /* Add a label so that the back-end doesn't think that the beginning o
+ the switch is unreachable. Note that we do not add a case label, as
+ that just leads to duplicates and thence to aborts later on. */
+ if (!cases->root)
+ {
+ tree t = create_artificial_label ();
+ add_stmt (build_stmt (LABEL_STMT, t));
+ }
+ return error_mark_node;
+}
+
+/* Subroutines of c_do_switch_warnings, called via splay_tree_foreach.
+ Used to verify that case values match up with enumerator values. */
+
+static void
+match_case_to_enum_1 (tree key, tree type, tree label)
+{
+ char buf[2 + 2*HOST_BITS_PER_WIDE_INT/4 + 1];
+
+ /* ??? Not working too hard to print the double-word value.
+ Should perhaps be done with %lwd in the diagnostic routines? */
+ if (TREE_INT_CST_HIGH (key) == 0)
+ snprintf (buf, sizeof (buf), HOST_WIDE_INT_PRINT_UNSIGNED,
+ TREE_INT_CST_LOW (key));
+ else if (!TYPE_UNSIGNED (type)
+ && TREE_INT_CST_HIGH (key) == -1
+ && TREE_INT_CST_LOW (key) != 0)
+ snprintf (buf, sizeof (buf), "-" HOST_WIDE_INT_PRINT_UNSIGNED,
+ -TREE_INT_CST_LOW (key));
+ else
+ snprintf (buf, sizeof (buf), HOST_WIDE_INT_PRINT_DOUBLE_HEX,
+ TREE_INT_CST_HIGH (key), TREE_INT_CST_LOW (key));
+
+ if (TYPE_NAME (type) == 0)
+ warning ("%Jcase value `%s' not in enumerated type",
+ CASE_LABEL_DECL (label), buf);
+ else
+ warning ("%Jcase value `%s' not in enumerated type `%T'",
+ CASE_LABEL_DECL (label), buf, type);
+}
+
+static int
+match_case_to_enum (splay_tree_node node, void *data)
+{
+ tree label = (tree) node->value;
+ tree type = data;
+
+ /* Skip default case. */
+ if (!CASE_LOW (label))
+ return 0;
+
+ /* If TREE_ADDRESSABLE is not set, that means CASE_LOW did not appear
+ when we did our enum->case scan. Reset our scratch bit after. */
+ if (!TREE_ADDRESSABLE (label))
+ match_case_to_enum_1 (CASE_LOW (label), type, label);
+ else
+ TREE_ADDRESSABLE (label) = 0;
+
+ /* If CASE_HIGH is non-null, we have a range. Here we must search.
+ Note that the old code in stmt.c did not check for the values in
+ the range either, just the endpoints. */
+ if (CASE_HIGH (label))
+ {
+ tree chain, key = CASE_HIGH (label);
+
+ for (chain = TYPE_VALUES (type);
+ chain && !tree_int_cst_equal (key, TREE_VALUE (chain));
+ chain = TREE_CHAIN (chain))
+ continue;
+ if (!chain)
+ match_case_to_enum_1 (key, type, label);
+ }
+
+ return 0;
+}
+
+/* Handle -Wswitch*. Called from the front end after parsing the switch
+ construct. */
+/* ??? Should probably be somewhere generic, since other languages besides
+ C and C++ would want this. We'd want to agree on the datastructure,
+ however, which is a problem. Alternately, we operate on gimplified
+ switch_exprs, which I don't especially like. At the moment, however,
+ C/C++ are the only tree-ssa languages that support enumerations at all,
+ so the point is moot. */
+
+void
+c_do_switch_warnings (splay_tree cases, tree switch_stmt)
+{
+ splay_tree_node default_node;
+ location_t *switch_locus;
+ tree type;
+
+ if (!warn_switch && !warn_switch_enum && !warn_switch_default)
+ return;
+
+ switch_locus = EXPR_LOCUS (switch_stmt);
+ if (!switch_locus)
+ switch_locus = &input_location;
+ type = SWITCH_TYPE (switch_stmt);
+
+ default_node = splay_tree_lookup (cases, (splay_tree_key) NULL);
+ if (warn_switch_default && !default_node)
+ warning ("%Hswitch missing default case", switch_locus);
+
+ /* If the switch expression was an enumerated type, check that
+ exactly all enumeration literals are covered by the cases.
+ The check is made when -Wswitch was specified and there is no
+ default case, or when -Wswitch-enum was specified. */
+ if (((warn_switch && !default_node) || warn_switch_enum)
+ && type && TREE_CODE (type) == ENUMERAL_TYPE
+ && TREE_CODE (SWITCH_COND (switch_stmt)) != INTEGER_CST)
+ {
+ tree chain;
+
+ /* The time complexity here is O(N*lg(N)) worst case, but for the
+ common case of monotonically increasing enumerators, it is
+ O(N), since the nature of the splay tree will keep the next
+ element adjacent to the root at all times. */
+
+ for (chain = TYPE_VALUES (type); chain; chain = TREE_CHAIN (chain))
+ {
+ splay_tree_node node
+ = splay_tree_lookup (cases, (splay_tree_key) TREE_VALUE (chain));
+
+ if (node)
+ {
+ /* Mark the CASE_LOW part of the case entry as seen, so
+ that we save time later. Choose TREE_ADDRESSABLE
+ randomly as a bit that won't have been set to-date. */
+ tree label = (tree) node->value;
+ TREE_ADDRESSABLE (label) = 1;
+ }
+ else
+ {
+ /* Warn if there are enumerators that don't correspond to
+ case expressions. */
+ warning ("%Henumeration value `%E' not handled in switch",
+ switch_locus, TREE_PURPOSE (chain));
+ }
+ }
+
+ /* Warn if there are case expressions that don't correspond to
+ enumerators. This can occur since C and C++ don't enforce
+ type-checking of assignments to enumeration variables.
+
+ The time complexity here is O(N**2) worst case, since we've
+ not sorted the enumeration values. However, in the absence
+ of case ranges this is O(N), since all single cases that
+ corresponded to enumerations have been marked above. */
+
+ splay_tree_foreach (cases, match_case_to_enum, type);
+ }
}
/* Finish an expression taking the address of LABEL (an
@@ -3976,7 +4239,6 @@ finish_label_address_expr (tree label)
{
TREE_USED (label) = 1;
result = build1 (ADDR_EXPR, ptr_type_node, label);
- TREE_CONSTANT (result) = 1;
/* The current function in not necessarily uninlinable.
Computed gotos are incompatible with inlining, but the value
here could be used only in a diagnostic, for example. */
@@ -3986,6 +4248,9 @@ finish_label_address_expr (tree label)
}
/* Hook used by expand_expr to expand language-specific tree codes. */
+/* The only things that should go here are bits needed to expand
+ constant initalizers. Everything else should be handled by the
+ gimplification routines. */
rtx
c_expand_expr (tree exp, rtx target, enum machine_mode tmode,
@@ -3994,88 +4259,6 @@ c_expand_expr (tree exp, rtx target, enum machine_mode tmode,
{
switch (TREE_CODE (exp))
{
- case STMT_EXPR:
- {
- tree rtl_expr;
- rtx result;
- bool preserve_result = false;
-
- if (STMT_EXPR_WARN_UNUSED_RESULT (exp) && target == const0_rtx)
- {
- tree stmt = STMT_EXPR_STMT (exp);
- tree scope;
-
- for (scope = COMPOUND_BODY (stmt);
- scope && TREE_CODE (scope) != SCOPE_STMT;
- scope = TREE_CHAIN (scope));
-
- if (scope && SCOPE_STMT_BLOCK (scope))
- warning ("%Hignoring return value of `%D', "
- "declared with attribute warn_unused_result",
- &expr_wfl_stack->location,
- BLOCK_ABSTRACT_ORIGIN (SCOPE_STMT_BLOCK (scope)));
- else
- warning ("%Hignoring return value of function "
- "declared with attribute warn_unused_result",
- &expr_wfl_stack->location);
- }
-
- /* Since expand_expr_stmt calls free_temp_slots after every
- expression statement, we must call push_temp_slots here.
- Otherwise, any temporaries in use now would be considered
- out-of-scope after the first EXPR_STMT from within the
- STMT_EXPR. */
- push_temp_slots ();
- rtl_expr = expand_start_stmt_expr (!STMT_EXPR_NO_SCOPE (exp));
-
- /* If we want the result of this expression, find the last
- EXPR_STMT in the COMPOUND_STMT and mark it as addressable. */
- if (target != const0_rtx
- && TREE_CODE (STMT_EXPR_STMT (exp)) == COMPOUND_STMT
- && TREE_CODE (COMPOUND_BODY (STMT_EXPR_STMT (exp))) == SCOPE_STMT)
- {
- tree expr = COMPOUND_BODY (STMT_EXPR_STMT (exp));
- tree last = TREE_CHAIN (expr);
-
- while (TREE_CHAIN (last))
- {
- expr = last;
- last = TREE_CHAIN (last);
- }
-
- if (TREE_CODE (last) == SCOPE_STMT
- && TREE_CODE (expr) == EXPR_STMT)
- {
- /* Otherwise, note that we want the value from the last
- expression. */
- TREE_ADDRESSABLE (expr) = 1;
- preserve_result = true;
- }
- }
-
- expand_stmt (STMT_EXPR_STMT (exp));
- expand_end_stmt_expr (rtl_expr);
-
- result = expand_expr_real (rtl_expr, target, tmode, modifier, alt_rtl);
- if (preserve_result && GET_CODE (result) == MEM)
- {
- if (GET_MODE (result) != BLKmode)
- result = copy_to_reg (result);
- else
- preserve_temp_slots (result);
- }
-
- /* If the statment-expression does not have a scope, then the
- new temporaries we created within it must live beyond the
- statement-expression. */
- if (STMT_EXPR_NO_SCOPE (exp))
- preserve_temp_slots (NULL_RTX);
-
- pop_temp_slots ();
- return result;
- }
- break;
-
case COMPOUND_LITERAL_EXPR:
{
/* Initialize the anonymous variable declared in the compound
@@ -4088,9 +4271,6 @@ c_expand_expr (tree exp, rtx target, enum machine_mode tmode,
default:
abort ();
}
-
- abort ();
- return NULL;
}
/* Hook used by safe_from_p to handle language-specific tree codes. */
@@ -4667,7 +4847,7 @@ handle_section_attribute (tree *node, tree name ATTRIBUTE_UNUSED, tree args,
&& ! TREE_STATIC (decl))
{
error ("%Jsection attribute cannot be specified for "
- "local variables", decl);
+ "local variables", decl);
*no_add_attrs = true;
}
@@ -4678,7 +4858,7 @@ handle_section_attribute (tree *node, tree name ATTRIBUTE_UNUSED, tree args,
TREE_STRING_POINTER (TREE_VALUE (args))) != 0)
{
error ("%Jsection of '%D' conflicts with previous declaration",
- *node, *node);
+ *node, *node);
*no_add_attrs = true;
}
else
@@ -4831,7 +5011,10 @@ handle_alias_attribute (tree *node, tree name, tree args,
if (TREE_CODE (decl) == FUNCTION_DECL)
DECL_INITIAL (decl) = error_mark_node;
else
- DECL_EXTERNAL (decl) = 0;
+ {
+ DECL_EXTERNAL (decl) = 0;
+ TREE_STATIC (decl) = 1;
+ }
}
else
{
@@ -5174,7 +5357,7 @@ handle_nonnull_attribute (tree *node, tree name ATTRIBUTE_UNUSED,
if (! TYPE_ARG_TYPES (type))
{
error ("nonnull attribute without arguments on a non-prototype");
- *no_add_attrs = true;
+ *no_add_attrs = true;
}
return NULL_TREE;
}
@@ -5184,7 +5367,7 @@ handle_nonnull_attribute (tree *node, tree name ATTRIBUTE_UNUSED,
for (attr_arg_num = 1; args; args = TREE_CHAIN (args))
{
tree argument;
- unsigned HOST_WIDE_INT arg_num, ck_num;
+ unsigned HOST_WIDE_INT arg_num = 0, ck_num;
if (! get_nonnull_operand (TREE_VALUE (args), &arg_num))
{
@@ -5204,7 +5387,7 @@ handle_nonnull_attribute (tree *node, tree name ATTRIBUTE_UNUSED,
argument = TREE_CHAIN (argument);
}
- if (! argument
+ if (! argument
|| TREE_CODE (TREE_VALUE (argument)) == VOID_TYPE)
{
error ("nonnull argument with out-of-range operand number (arg %lu, operand %lu)",
@@ -5213,7 +5396,7 @@ handle_nonnull_attribute (tree *node, tree name ATTRIBUTE_UNUSED,
return NULL_TREE;
}
- if (TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE)
+ if (TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE)
{
error ("nonnull argument references non-pointer operand (arg %lu, operand %lu)",
(unsigned long) attr_arg_num, (unsigned long) arg_num);
@@ -5239,22 +5422,22 @@ check_function_nonnull (tree attrs, tree params)
{
if (is_attribute_p ("nonnull", TREE_PURPOSE (a)))
{
- args = TREE_VALUE (a);
+ args = TREE_VALUE (a);
- /* Walk the argument list. If we encounter an argument number we
- should check for non-null, do it. If the attribute has no args,
- then every pointer argument is checked (in which case the check
+ /* Walk the argument list. If we encounter an argument number we
+ should check for non-null, do it. If the attribute has no args,
+ then every pointer argument is checked (in which case the check
for pointer type is done in check_nonnull_arg). */
- for (param = params, param_num = 1; ;
- param_num++, param = TREE_CHAIN (param))
- {
- if (! param)
+ for (param = params, param_num = 1; ;
+ param_num++, param = TREE_CHAIN (param))
+ {
+ if (! param)
break;
- if (! args || nonnull_check_p (args, param_num))
+ if (! args || nonnull_check_p (args, param_num))
check_function_arguments_recurse (check_nonnull_arg, NULL,
TREE_VALUE (param),
param_num);
- }
+ }
}
}
}
@@ -5266,12 +5449,12 @@ check_function_nonnull (tree attrs, tree params)
static bool
nonnull_check_p (tree args, unsigned HOST_WIDE_INT param_num)
{
- unsigned HOST_WIDE_INT arg_num;
+ unsigned HOST_WIDE_INT arg_num = 0;
for (; args; args = TREE_CHAIN (args))
{
if (! get_nonnull_operand (TREE_VALUE (args), &arg_num))
- abort ();
+ abort ();
if (arg_num == param_num)
return true;
@@ -5296,7 +5479,7 @@ check_nonnull_arg (void *ctx ATTRIBUTE_UNUSED, tree param,
if (integer_zerop (param))
warning ("null argument where non-null required (arg %lu)",
- (unsigned long) param_num);
+ (unsigned long) param_num);
}
/* Helper for nonnull attribute handling; fetch the operand number
@@ -5430,7 +5613,7 @@ check_function_arguments_recurse (void (*callback)
{
/* Strip coercion. */
check_function_arguments_recurse (callback, ctx,
- TREE_OPERAND (param, 0), param_num);
+ TREE_OPERAND (param, 0), param_num);
return;
}
@@ -5492,15 +5675,74 @@ check_function_arguments_recurse (void (*callback)
{
/* Check both halves of the conditional expression. */
check_function_arguments_recurse (callback, ctx,
- TREE_OPERAND (param, 1), param_num);
+ TREE_OPERAND (param, 1), param_num);
check_function_arguments_recurse (callback, ctx,
- TREE_OPERAND (param, 2), param_num);
+ TREE_OPERAND (param, 2), param_num);
return;
}
(*callback) (ctx, param, param_num);
}
+/* C implementation of lang_hooks.tree_inlining.walk_subtrees. Tracks the
+ locus from EXPR_LOCUS and handles DECL_STMT specially. */
+
+tree
+c_walk_subtrees (tree *tp, int *walk_subtrees_p ATTRIBUTE_UNUSED,
+ walk_tree_fn func, void *data, void *htab)
+{
+ enum tree_code code = TREE_CODE (*tp);
+ location_t save_locus;
+ tree result;
+
+#define WALK_SUBTREE(NODE) \
+ do \
+ { \
+ result = walk_tree (&(NODE), func, data, htab); \
+ if (result) goto out; \
+ } \
+ while (0)
+
+ if (code != DECL_STMT)
+ return NULL_TREE;
+
+ /* Set input_location here so we get the right instantiation context
+ if we call instantiate_decl from inlinable_function_p. */
+ save_locus = input_location;
+ if (EXPR_LOCUS (*tp))
+ input_location = *EXPR_LOCUS (*tp);
+
+ /* Walk the DECL_INITIAL and DECL_SIZE. We don't want to walk
+ into declarations that are just mentioned, rather than
+ declared; they don't really belong to this part of the tree.
+ And, we can see cycles: the initializer for a declaration can
+ refer to the declaration itself. */
+ WALK_SUBTREE (DECL_INITIAL (DECL_STMT_DECL (*tp)));
+ WALK_SUBTREE (DECL_SIZE (DECL_STMT_DECL (*tp)));
+ WALK_SUBTREE (DECL_SIZE_UNIT (DECL_STMT_DECL (*tp)));
+ WALK_SUBTREE (TREE_CHAIN (*tp));
+ *walk_subtrees_p = 0;
+
+ /* We didn't find what we were looking for. */
+ out:
+ input_location = save_locus;
+ return result;
+
+#undef WALK_SUBTREE
+}
+
+/* C implementation of lang_hooks.tree_inlining.tree_chain_matters_p.
+ Apart from TREE_LISTs, the only trees whose TREE_CHAIN we care about are
+ _STMT nodes. */
+
+int
+c_tree_chain_matters_p (tree t)
+{
+ /* For statements, we also walk the chain so that we cover the
+ entire statement tree. */
+ return STATEMENT_CODE_P (TREE_CODE (t));
+}
+
/* Function to help qsort sort FIELD_DECLs by name order. */
int
@@ -5556,15 +5798,15 @@ resort_field_decl_cmp (const void *x_p, const void *y_p)
void
resort_sorted_fields (void *obj,
- void *orig_obj ATTRIBUTE_UNUSED ,
- gt_pointer_operator new_value,
- void *cookie)
+ void *orig_obj ATTRIBUTE_UNUSED ,
+ gt_pointer_operator new_value,
+ void *cookie)
{
struct sorted_fields_type *sf = obj;
resort_data.new_value = new_value;
resort_data.cookie = cookie;
qsort (&sf->elts[0], sf->len, sizeof (tree),
- resort_field_decl_cmp);
+ resort_field_decl_cmp);
}
/* Used by estimate_num_insns. Estimate number of instructions seen
@@ -5658,14 +5900,12 @@ c_estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
case EXIT_EXPR:
case LABELED_BLOCK_EXPR:
case EXIT_BLOCK_EXPR:
- case EXPR_WITH_FILE_LOCATION:
case EXPR_STMT:
case COMPOUND_STMT:
case RETURN_STMT:
case LABEL_STMT:
case SCOPE_STMT:
- case FILE_STMT:
case CASE_LABEL:
case STMT_EXPR:
case CLEANUP_STMT:
@@ -5694,37 +5934,6 @@ c_estimate_num_insns (tree decl)
return num;
}
-/* Used by c_decl_uninit to find where expressions like x = x + 1; */
-
-static tree
-c_decl_uninit_1 (tree *t, int *walk_sub_trees, void *x)
-{
- /* If x = EXP(&x)EXP, then do not warn about the use of x. */
- if (TREE_CODE (*t) == ADDR_EXPR && TREE_OPERAND (*t, 0) == x)
- {
- *walk_sub_trees = 0;
- return NULL_TREE;
- }
- if (*t == x)
- return *t;
- return NULL_TREE;
-}
-
-/* Find out if a variable is uninitialized based on DECL_INITIAL. */
-
-bool
-c_decl_uninit (tree t)
-{
- /* int x = x; is GCC extension to turn off this warning, only if warn_init_self is zero. */
- if (DECL_INITIAL (t) == t)
- return warn_init_self ? true : false;
-
- /* Walk the trees looking for the variable itself. */
- if (walk_tree_without_duplicates (&DECL_INITIAL (t), c_decl_uninit_1, t))
- return true;
- return false;
-}
-
/* Issue the error given by MSGID, indicating that it occurred before
TOKEN, which had the associated VALUE. */
@@ -5757,4 +5966,74 @@ c_parse_error (const char *msgid, enum cpp_ttype token, tree value)
error ("%s", string);
}
+/* Walk a gimplified function and warn for functions whose return value is
+ ignored and attribute((warn_unused_result)) is set. This is done before
+ inlining, so we don't have to worry about that. */
+
+void
+c_warn_unused_result (tree *top_p)
+{
+ tree t = *top_p;
+ tree_stmt_iterator i;
+ tree fdecl, ftype;
+
+ switch (TREE_CODE (t))
+ {
+ case STATEMENT_LIST:
+ for (i = tsi_start (*top_p); !tsi_end_p (i); tsi_next (&i))
+ c_warn_unused_result (tsi_stmt_ptr (i));
+ break;
+
+ case COND_EXPR:
+ c_warn_unused_result (&COND_EXPR_THEN (t));
+ c_warn_unused_result (&COND_EXPR_ELSE (t));
+ break;
+ case BIND_EXPR:
+ c_warn_unused_result (&BIND_EXPR_BODY (t));
+ break;
+ case TRY_FINALLY_EXPR:
+ case TRY_CATCH_EXPR:
+ c_warn_unused_result (&TREE_OPERAND (t, 0));
+ c_warn_unused_result (&TREE_OPERAND (t, 1));
+ break;
+ case CATCH_EXPR:
+ c_warn_unused_result (&CATCH_BODY (t));
+ break;
+ case EH_FILTER_EXPR:
+ c_warn_unused_result (&EH_FILTER_FAILURE (t));
+ break;
+
+ case CALL_EXPR:
+ /* This is a naked call, as opposed to a CALL_EXPR nested inside
+ a MODIFY_EXPR. All calls whose value is ignored should be
+ represented like this. Look for the attribute. */
+ fdecl = get_callee_fndecl (t);
+ if (fdecl)
+ ftype = TREE_TYPE (fdecl);
+ else
+ {
+ ftype = TREE_TYPE (TREE_OPERAND (t, 0));
+ /* Look past pointer-to-function to the function type itself. */
+ ftype = TREE_TYPE (ftype);
+ }
+
+ if (lookup_attribute ("warn_unused_result", TYPE_ATTRIBUTES (ftype)))
+ {
+ if (fdecl)
+ warning ("%Hignoring return value of `%D', "
+ "declared with attribute warn_unused_result",
+ EXPR_LOCUS (t), fdecl);
+ else
+ warning ("%Hignoring return value of function "
+ "declared with attribute warn_unused_result",
+ EXPR_LOCUS (t));
+ }
+ break;
+
+ default:
+ /* Not a container, not a call, or a call whose value is used. */
+ break;
+ }
+}
+
#include "gt-c-common.h"
diff --git a/gcc/c-common.def b/gcc/c-common.def
index dfdec8c4df0..3282cc603e4 100644
--- a/gcc/c-common.def
+++ b/gcc/c-common.def
@@ -79,7 +79,7 @@ DEFTREECODE (GOTO_STMT, "goto_stmt", 'e', 1)
DEFTREECODE (LABEL_STMT, "label_stmt", 'e', 1)
/* Used to represent an inline assembly statement. */
-DEFTREECODE (ASM_STMT, "asm_stmt", 'e', 5)
+DEFTREECODE (ASM_STMT, "asm_stmt", 'e', 4)
/* A SCOPE_STMT marks the beginning or end of a scope. If
SCOPE_BEGIN_P holds, then this is the start of a scope. If
@@ -89,10 +89,6 @@ DEFTREECODE (ASM_STMT, "asm_stmt", 'e', 5)
variables declared in this scope. */
DEFTREECODE (SCOPE_STMT, "scope_stmt", 'e', 1)
-/* A FILE_STMT marks the spot where a function changes files. It has no
- other semantics. FILE_STMT_FILENAME gives the name. */
-DEFTREECODE (FILE_STMT, "file_stmt", 'e', 1)
-
/* Used to represent a CASE_LABEL. The operands are CASE_LOW and
CASE_HIGH, respectively. If CASE_LOW is NULL_TREE, the label is a
'default' label. If CASE_HIGH is NULL_TREE, the label is a normal case
diff --git a/gcc/c-common.h b/gcc/c-common.h
index 6e9099a3875..74999104428 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -37,10 +37,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
STMT_EXPR_NO_SCOPE (in STMT_EXPR)
1: C_DECLARED_LABEL_FLAG (in LABEL_DECL)
STMT_IS_FULL_EXPR_P (in _STMT)
- 2: STMT_LINENO_FOR_FN_P (in _STMT)
+ 2: unused
3: SCOPE_NO_CLEANUPS_P (in SCOPE_STMT)
COMPOUND_STMT_BODY_BLOCK (in COMPOUND_STMT)
- STMT_EXPR_WARN_UNUSED_RESULT (in STMT_EXPR)
4: SCOPE_PARTIAL_P (in SCOPE_STMT)
*/
@@ -321,8 +320,7 @@ struct c_language_function GTY(()) {
/* Language-specific hooks. */
-extern void (*lang_expand_stmt) (tree);
-extern void (*lang_expand_decl_stmt) (tree);
+extern int (*lang_gimplify_stmt) (tree *, tree *);
extern void (*lang_expand_function_end) (void);
/* Callback that determines if it's ok for a function to have no
@@ -342,7 +340,6 @@ extern void finish_stmt_tree (tree *);
extern tree walk_stmt_tree (tree *, walk_tree_fn, void *);
extern void prep_stmt (tree);
-extern void expand_stmt (tree);
extern tree c_begin_if_stmt (void);
extern tree c_begin_while_stmt (void);
extern void c_finish_while_stmt_cond (tree, tree);
@@ -999,22 +996,9 @@ extern void finish_file (void);
#define FOR_EXPR(NODE) TREE_OPERAND (FOR_STMT_CHECK (NODE), 2)
#define FOR_BODY(NODE) TREE_OPERAND (FOR_STMT_CHECK (NODE), 3)
-/* SWITCH_STMT accessors. These give access to the condition, body and
- original condition type (before any compiler conversions)
- of the switch statement, respectively. */
-#define SWITCH_COND(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 0)
-#define SWITCH_BODY(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 1)
#define SWITCH_TYPE(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 2)
-
-/* CASE_LABEL accessors. These give access to the high and low values
- of a case label, respectively. */
-#define CASE_LOW(NODE) TREE_OPERAND (CASE_LABEL_CHECK (NODE), 0)
-#define CASE_HIGH(NODE) TREE_OPERAND (CASE_LABEL_CHECK (NODE), 1)
#define CASE_LABEL_DECL(NODE) TREE_OPERAND (CASE_LABEL_CHECK (NODE), 2)
-/* GOTO_STMT accessor. This gives access to the label associated with
- a goto statement. */
-#define GOTO_DESTINATION(NODE) TREE_OPERAND (GOTO_STMT_CHECK (NODE), 0)
/* True for goto created artificially by the compiler. */
#define GOTO_FAKE_P(NODE) (TREE_LANG_FLAG_0 (GOTO_STMT_CHECK (NODE)))
@@ -1024,16 +1008,6 @@ extern void finish_file (void);
calling TREE_CHAIN on a node in the list. */
#define COMPOUND_BODY(NODE) TREE_OPERAND (COMPOUND_STMT_CHECK (NODE), 0)
-/* ASM_STMT accessors. ASM_STRING returns a STRING_CST for the
- instruction (e.g., "mov x, y"). ASM_OUTPUTS, ASM_INPUTS, and
- ASM_CLOBBERS represent the outputs, inputs, and clobbers for the
- statement. */
-#define ASM_CV_QUAL(NODE) TREE_OPERAND (ASM_STMT_CHECK (NODE), 0)
-#define ASM_STRING(NODE) TREE_OPERAND (ASM_STMT_CHECK (NODE), 1)
-#define ASM_OUTPUTS(NODE) TREE_OPERAND (ASM_STMT_CHECK (NODE), 2)
-#define ASM_INPUTS(NODE) TREE_OPERAND (ASM_STMT_CHECK (NODE), 3)
-#define ASM_CLOBBERS(NODE) TREE_OPERAND (ASM_STMT_CHECK (NODE), 4)
-
/* DECL_STMT accessor. This gives access to the DECL associated with
the given declaration statement. */
#define DECL_STMT_DECL(NODE) TREE_OPERAND (DECL_STMT_CHECK (NODE), 0)
@@ -1045,11 +1019,6 @@ extern void finish_file (void);
#define STMT_EXPR_NO_SCOPE(NODE) \
TREE_LANG_FLAG_0 (STMT_EXPR_CHECK (NODE))
-/* Nonzero if this statement-expression should cause warning if its result
- is not used. */
-#define STMT_EXPR_WARN_UNUSED_RESULT(NODE) \
- TREE_LANG_FLAG_3 (STMT_EXPR_CHECK (NODE))
-
/* LABEL_STMT accessor. This gives access to the label associated with
the given label statement. */
#define LABEL_STMT_LABEL(NODE) TREE_OPERAND (LABEL_STMT_CHECK (NODE), 0)
@@ -1097,10 +1066,6 @@ extern void finish_file (void);
#define SCOPE_PARTIAL_P(NODE) \
(TREE_LANG_FLAG_4 (SCOPE_STMT_CHECK (NODE)))
-/* Nonzero for an ASM_STMT if the assembly statement is volatile. */
-#define ASM_VOLATILE_P(NODE) \
- (ASM_CV_QUAL (ASM_STMT_CHECK (NODE)) != NULL_TREE)
-
/* The VAR_DECL to clean up in a CLEANUP_STMT. */
#define CLEANUP_DECL(NODE) \
TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 0)
@@ -1108,31 +1073,10 @@ extern void finish_file (void);
#define CLEANUP_EXPR(NODE) \
TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 1)
-/* The filename we are changing to as of this FILE_STMT. */
-#define FILE_STMT_FILENAME_NODE(NODE) \
- (TREE_OPERAND (FILE_STMT_CHECK (NODE), 0))
-#define FILE_STMT_FILENAME(NODE) \
- (IDENTIFIER_POINTER (FILE_STMT_FILENAME_NODE (NODE)))
-
-/* The line-number at which a statement began. But if
- STMT_LINENO_FOR_FN_P does holds, then this macro gives the
- line number for the end of the current function instead. */
-#define STMT_LINENO(NODE) \
- (TREE_COMPLEXITY ((NODE)))
-
-/* If nonzero, the STMT_LINENO for NODE is the line at which the
- function ended. */
-#define STMT_LINENO_FOR_FN_P(NODE) \
- (TREE_LANG_FLAG_2 ((NODE)))
-
/* Nonzero if we want the new ISO rules for pushing a new scope for `for'
initialization variables. */
#define NEW_FOR_SCOPE_P(NODE) (TREE_LANG_FLAG_0 (NODE))
-/* Nonzero if we want to create an ASM_INPUT instead of an
- ASM_OPERAND with no operands. */
-#define ASM_INPUT_P(NODE) (TREE_LANG_FLAG_0 (NODE))
-
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM,
enum c_tree_code {
@@ -1149,7 +1093,7 @@ enum c_tree_code {
WHILE_STMT, DO_STMT, RETURN_STMT, \
BREAK_STMT, CONTINUE_STMT, SCOPE_STMT, \
SWITCH_STMT, GOTO_STMT, LABEL_STMT, \
- ASM_STMT, FILE_STMT, CASE_LABEL
+ ASM_STMT, CASE_LABEL
/* TRUE if a code represents a statement. The front end init
langhook should take care of initialization of this array. */
@@ -1165,24 +1109,6 @@ extern bool statement_code_p[MAX_TREE_CODES];
statement_code_p[STMT_CODES[i]] = true; \
} while (0)
-extern void genrtl_do_pushlevel (void);
-extern void genrtl_goto_stmt (tree);
-extern void genrtl_expr_stmt (tree);
-extern void genrtl_expr_stmt_value (tree, int, int);
-extern void genrtl_decl_stmt (tree);
-extern void genrtl_if_stmt (tree);
-extern void genrtl_while_stmt (tree);
-extern void genrtl_do_stmt (tree);
-extern void genrtl_return_stmt (tree);
-extern void genrtl_for_stmt (tree);
-extern void genrtl_break_stmt (void);
-extern void genrtl_continue_stmt (void);
-extern void genrtl_scope_stmt (tree);
-extern void genrtl_switch_stmt (tree);
-extern void genrtl_case_label (tree);
-extern void genrtl_compound_stmt (tree);
-extern void genrtl_asm_stmt (tree, tree, tree, tree, tree, int);
-extern void genrtl_cleanup_stmt (tree);
extern int stmts_are_full_exprs_p (void);
extern int anon_aggr_type_p (tree);
@@ -1198,13 +1124,8 @@ extern int anon_aggr_type_p (tree);
#define CLEAR_DECL_C_BIT_FIELD(NODE) \
(DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) = 0)
-/* In a VAR_DECL, nonzero if the decl is a register variable with
- an explicit asm specification. */
-#define DECL_C_HARD_REGISTER(DECL) DECL_LANG_FLAG_4 (VAR_DECL_CHECK (DECL))
-
extern void emit_local_var (tree);
extern void make_rtl_for_local_static (tree);
-extern tree expand_cond (tree);
extern tree c_expand_return (tree);
extern tree do_case (tree, tree);
extern tree build_stmt (enum tree_code, ...);
@@ -1249,6 +1170,8 @@ extern int case_compare (splay_tree_key, splay_tree_key);
extern tree c_add_case_label (splay_tree, tree, tree, tree);
+extern void c_do_switch_warnings (splay_tree, tree);
+
extern tree build_function_call (tree, tree);
extern tree finish_label_address_expr (tree);
@@ -1257,6 +1180,8 @@ extern tree finish_label_address_expr (tree);
different implementations. Used in c-common.c. */
extern tree lookup_label (tree);
+extern int vector_types_convertible_p (tree t1, tree t2);
+
extern rtx c_expand_expr (tree, rtx, enum machine_mode, int, rtx *);
extern int c_safe_from_p (rtx, tree);
@@ -1287,6 +1212,17 @@ extern void dump_time_statistics (void);
extern bool c_dump_tree (void *, tree);
+extern int c_gimplify_expr (tree *, tree *, tree *);
+extern tree c_walk_subtrees (tree*, int*, walk_tree_fn, void*, void*);
+extern int c_tree_chain_matters_p (tree);
+
+extern void c_warn_unused_result (tree *);
+
+/* In c-simplify.c */
+extern void c_genericize (tree);
+extern int c_gimplify_stmt (tree *);
+extern tree stmt_expr_last_stmt (tree);
+
extern void pch_init (void);
extern int c_common_valid_pch (cpp_reader *pfile, const char *name, int fd);
extern void c_common_read_pch (cpp_reader *pfile, const char *name, int fd,
@@ -1297,7 +1233,6 @@ extern void builtin_define_with_value (const char *, const char *, int);
extern void c_stddef_cpp_builtins (void);
extern void fe_file_change (const struct line_map *);
extern int c_estimate_num_insns (tree decl);
-extern bool c_decl_uninit (tree t);
extern void c_parse_error (const char *, enum cpp_ttype, tree);
/* The following have been moved here from c-tree.h, since they're needed
diff --git a/gcc/c-convert.c b/gcc/c-convert.c
index 582ec8bfe34..3067137c372 100644
--- a/gcc/c-convert.c
+++ b/gcc/c-convert.c
@@ -114,6 +114,9 @@ convert (tree type, tree expr)
return fold (convert_to_complex (type, e));
if (code == VECTOR_TYPE)
return fold (convert_to_vector (type, e));
+ if ((code == RECORD_TYPE || code == UNION_TYPE)
+ && lang_hooks.types_compatible_p (type, TREE_TYPE (expr)))
+ return e;
error ("conversion to non-scalar type requested");
return error_mark_node;
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 8f1964717da..8ca5b086ca2 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -49,6 +49,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "timevar.h"
#include "c-common.h"
#include "c-pragma.h"
+#include "langhooks.h"
+#include "tree-mudflap.h"
+#include "tree-gimple.h"
+#include "diagnostic.h"
+#include "tree-dump.h"
#include "cgraph.h"
#include "hashtab.h"
#include "libfuncs.h"
@@ -108,9 +113,11 @@ static GTY(()) tree c_scope_stmt_stack;
int c_in_iteration_stmt;
int c_in_case_stmt;
-/* A DECL for the current file-scope context. */
+/* Linked list of TRANSLATION_UNIT_DECLS for the translation units
+ included in this invocation. Note that the current translation
+ unit is not included in this list. */
-static GTY(()) tree current_file_decl;
+static GTY(()) tree all_translation_units;
/* A list of decls to be made automatically visible in each file scope. */
static GTY(()) tree visible_builtins;
@@ -649,7 +656,12 @@ pop_scope (void)
if (scope->function_body)
context = current_function_decl;
else if (scope == file_scope)
- context = current_file_decl;
+ {
+ tree file_decl = build_decl (TRANSLATION_UNIT_DECL, 0, 0);
+ TREE_CHAIN (file_decl) = all_translation_units;
+ all_translation_units = file_decl;
+ context = file_decl;
+ }
else
context = block;
@@ -736,6 +748,9 @@ pop_scope (void)
TREE_CHAIN (p) = BLOCK_VARS (block);
BLOCK_VARS (block) = p;
}
+ /* If this is the file scope, must set DECL_CONTEXT on these. */
+ if (!C_DECL_IN_EXTERNAL_SCOPE (p) && scope == file_scope)
+ DECL_CONTEXT (p) = context;
/* Fall through. */
/* Parameters go in DECL_ARGUMENTS, not BLOCK_VARS, and have
@@ -795,9 +810,6 @@ void
push_file_scope (void)
{
tree decl;
- tree file_decl = build_decl (TRANSLATION_UNIT_DECL, 0, 0);
- TREE_CHAIN (file_decl) = current_file_decl;
- current_file_decl = file_decl;
push_scope ();
file_scope = current_scope;
@@ -1657,7 +1669,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
static bool
duplicate_decls (tree newdecl, tree olddecl)
{
- tree newtype, oldtype;
+ tree newtype = NULL, oldtype = NULL;
if (!diagnose_mismatched_decls (newdecl, olddecl, &newtype, &oldtype))
return false;
@@ -1796,14 +1808,12 @@ pushdecl (tree x)
if (TREE_CODE (x) == FUNCTION_DECL && ! DECL_LANG_SPECIFIC (x))
DECL_LANG_SPECIFIC (x) = ggc_alloc_cleared (sizeof (struct lang_decl));
- /* A local extern declaration for a function doesn't constitute nesting.
- A local auto declaration does, since it's a forward decl
- for a nested function coming later. */
- if (current_function_decl == NULL
- || ((TREE_CODE (x) == FUNCTION_DECL || TREE_CODE (x) == VAR_DECL)
- && DECL_INITIAL (x) == 0 && DECL_EXTERNAL (x)))
- DECL_CONTEXT (x) = current_file_decl;
- else
+ /* Must set DECL_CONTEXT for everything not at file scope or
+ DECL_FILE_SCOPE_P won't work. Local externs don't count
+ unless they have initializers (which generate code). */
+ if (current_function_decl
+ && ((TREE_CODE (x) != FUNCTION_DECL && TREE_CODE (x) != VAR_DECL)
+ || DECL_INITIAL (x) || !DECL_EXTERNAL (x)))
DECL_CONTEXT (x) = current_function_decl;
/* Anonymous decls are just inserted in the scope. */
@@ -1927,7 +1937,6 @@ pushdecl_top_level (tree x)
if (I_SYMBOL_BINDING (name))
abort ();
- DECL_CONTEXT (x) = current_file_decl;
if (DECL_EXTERNAL (x) || TREE_PUBLIC (x))
{
C_DECL_IN_EXTERNAL_SCOPE (x) = 1;
@@ -2109,10 +2118,6 @@ lookup_label (tree name)
any that may be inherited from containing functions or containing
scopes. This is called for __label__ declarations. */
-/* Note that valid use, if the label being shadowed comes from another
- scope in the same function, requires calling declare_nonlocal_label
- right away. (Is this still true? -zw 2003-07-17) */
-
tree
declare_label (tree name)
{
@@ -2932,7 +2937,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
in a particular register. */
if (C_DECL_REGISTER (decl))
{
- DECL_C_HARD_REGISTER (decl) = 1;
+ DECL_HARD_REGISTER (decl) = 1;
/* This cannot be done for a structure with volatile
fields, on which DECL_REGISTER will have been
reset. */
@@ -3300,11 +3305,14 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name)
else
w = tree_low_cst (*width, 1);
- if (TREE_CODE (*type) == ENUMERAL_TYPE
- && (w < min_precision (TYPE_MIN_VALUE (*type), TYPE_UNSIGNED (*type))
- || w < min_precision (TYPE_MAX_VALUE (*type),
- TYPE_UNSIGNED (*type))))
- warning ("`%s' is narrower than values of its type", name);
+ if (TREE_CODE (*type) == ENUMERAL_TYPE)
+ {
+ struct lang_type *lt = TYPE_LANG_SPECIFIC (*type);
+ if (!lt
+ || w < min_precision (lt->enum_min, TYPE_UNSIGNED (*type))
+ || w < min_precision (lt->enum_max, TYPE_UNSIGNED (*type)))
+ warning ("`%s' is narrower than values of its type", name);
+ }
}
/* Given declspecs and a declarator,
@@ -4055,6 +4063,11 @@ grokdeclarator (tree declarator, tree declspecs,
TYPE_SIZE (type) = bitsize_zero_node;
TYPE_SIZE_UNIT (type) = size_zero_node;
}
+ else if (declarator && TREE_CODE (declarator) == INDIRECT_REF)
+ /* We can never complete an array type which is the target of a
+ pointer, so go ahead and lay it out. */
+ layout_type (type);
+
if (decl_context != PARM
&& (array_ptr_quals != NULL_TREE || array_parm_static))
{
@@ -4798,9 +4811,9 @@ get_parm_info (bool ellipsis)
}
break;
- case ENUMERAL_TYPE: keyword = "struct"; goto tag;
+ case ENUMERAL_TYPE: keyword = "enum"; goto tag;
case UNION_TYPE: keyword = "union"; goto tag;
- case RECORD_TYPE: keyword = "enum"; goto tag;
+ case RECORD_TYPE: keyword = "struct"; goto tag;
tag:
/* Types may not have tag-names, in which case the type
appears in the bindings list with b->id NULL. */
@@ -5247,7 +5260,7 @@ finish_struct (tree t, tree fieldlist, tree attributes)
ensure that this lives as long as the rest of the struct decl.
All decls in an inline function need to be saved. */
- space = ggc_alloc (sizeof (struct lang_type));
+ space = ggc_alloc_cleared (sizeof (struct lang_type));
space2 = ggc_alloc (sizeof (struct sorted_fields_type) + len * sizeof (tree));
len = 0;
@@ -5382,9 +5395,10 @@ tree
finish_enum (tree enumtype, tree values, tree attributes)
{
tree pair, tem;
- tree minnode = 0, maxnode = 0, enum_value_type;
+ tree minnode = 0, maxnode = 0;
int precision, unsign;
bool toplevel = (file_scope == current_scope);
+ struct lang_type *lt;
decl_attributes (&enumtype, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
@@ -5414,27 +5428,20 @@ finish_enum (tree enumtype, tree values, tree attributes)
min_precision (maxnode, unsign));
if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node))
{
- tree narrowest = c_common_type_for_size (precision, unsign);
- if (narrowest == 0)
+ tem = c_common_type_for_size (precision, unsign);
+ if (tem == NULL)
{
warning ("enumeration values exceed range of largest integer");
- narrowest = long_long_integer_type_node;
+ tem = long_long_integer_type_node;
}
-
- precision = TYPE_PRECISION (narrowest);
}
else
- precision = TYPE_PRECISION (integer_type_node);
+ tem = unsign ? unsigned_type_node : integer_type_node;
- if (precision == TYPE_PRECISION (integer_type_node))
- enum_value_type = c_common_type_for_size (precision, 0);
- else
- enum_value_type = enumtype;
-
- TYPE_MIN_VALUE (enumtype) = minnode;
- TYPE_MAX_VALUE (enumtype) = maxnode;
- TYPE_PRECISION (enumtype) = precision;
- TYPE_UNSIGNED (enumtype) = unsign;
+ TYPE_MIN_VALUE (enumtype) = TYPE_MIN_VALUE (tem);
+ TYPE_MAX_VALUE (enumtype) = TYPE_MAX_VALUE (tem);
+ TYPE_PRECISION (enumtype) = TYPE_PRECISION (tem);
+ TYPE_UNSIGNED (enumtype) = TYPE_UNSIGNED (tem);
TYPE_SIZE (enumtype) = 0;
layout_type (enumtype);
@@ -5450,6 +5457,7 @@ finish_enum (tree enumtype, tree values, tree attributes)
for (pair = values; pair; pair = TREE_CHAIN (pair))
{
tree enu = TREE_PURPOSE (pair);
+ tree ini = DECL_INITIAL (enu);
TREE_TYPE (enu) = enumtype;
@@ -5460,18 +5468,27 @@ finish_enum (tree enumtype, tree values, tree attributes)
when comparing integers with enumerators that fit in the
int range. When -pedantic is given, build_enumerator()
would have already taken care of those that don't fit. */
- if (int_fits_type_p (DECL_INITIAL (enu), enum_value_type))
- DECL_INITIAL (enu) = convert (enum_value_type, DECL_INITIAL (enu));
+ if (int_fits_type_p (ini, integer_type_node))
+ tem = integer_type_node;
else
- DECL_INITIAL (enu) = convert (enumtype, DECL_INITIAL (enu));
+ tem = enumtype;
+ ini = convert (tem, ini);
+ DECL_INITIAL (enu) = ini;
TREE_PURPOSE (pair) = DECL_NAME (enu);
- TREE_VALUE (pair) = DECL_INITIAL (enu);
+ TREE_VALUE (pair) = ini;
}
TYPE_VALUES (enumtype) = values;
}
+ /* Record the min/max values so that we can warn about bit-field
+ enumerations that are too small for the values. */
+ lt = ggc_alloc_cleared (sizeof (struct lang_type));
+ lt->enum_min = minnode;
+ lt->enum_max = maxnode;
+ TYPE_LANG_SPECIFIC (enumtype) = lt;
+
/* Fix up all variant types of this enum type. */
for (tem = TYPE_MAIN_VARIANT (enumtype); tem; tem = TYPE_NEXT_VARIANT (tem))
{
@@ -5487,6 +5504,7 @@ finish_enum (tree enumtype, tree values, tree attributes)
TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype);
TYPE_USER_ALIGN (tem) = TYPE_USER_ALIGN (enumtype);
TYPE_UNSIGNED (tem) = TYPE_UNSIGNED (enumtype);
+ TYPE_LANG_SPECIFIC (tem) = TYPE_LANG_SPECIFIC (enumtype);
}
/* Finish debugging output for this type. */
@@ -5824,8 +5842,7 @@ store_parm_decls_newstyle (tree fndecl, tree arg_info)
warning if we got here because ARG_INFO_TYPES was error_mark_node
(this happens when a function definition has just an ellipsis in
its parameter list). */
- else if (warn_traditional && !in_system_header
- && DECL_CONTEXT (fndecl) == current_file_decl
+ else if (warn_traditional && !in_system_header && !current_function_scope
&& ARG_INFO_TYPES (arg_info) != error_mark_node)
warning ("%Jtraditional C rejects ISO C style function definitions",
fndecl);
@@ -6082,6 +6099,25 @@ store_parm_decls_oldstyle (tree fndecl, tree arg_info)
}
}
+/* A subroutine of store_parm_decls called via walk_tree. Mark all
+ decls non-local. */
+
+static tree
+set_decl_nonlocal (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
+{
+ tree t = *tp;
+
+ if (DECL_P (t))
+ {
+ DECL_NONLOCAL (t) = 1;
+ *walk_subtrees = 0;
+ }
+ else if (TYPE_P (t))
+ *walk_subtrees = 0;
+
+ return NULL;
+}
+
/* Store the parameter declarations into the current function declaration.
This is called after parsing the parameter declarations, before
digesting the body of the function.
@@ -6139,7 +6175,14 @@ store_parm_decls (void)
for (t = DECL_LANG_SPECIFIC (fndecl)->pending_sizes;
t;
t = TREE_CHAIN (t))
- SAVE_EXPR_CONTEXT (TREE_VALUE (t)) = context;
+ {
+ /* We will have a nonlocal use of whatever variables are
+ buried inside here. */
+ walk_tree (&TREE_OPERAND (TREE_VALUE (t), 0),
+ set_decl_nonlocal, NULL, NULL);
+
+ SAVE_EXPR_CONTEXT (TREE_VALUE (t)) = context;
+ }
}
/* This function is being processed in whole-function mode. */
@@ -6153,6 +6196,32 @@ store_parm_decls (void)
cfun->x_dont_save_pending_sizes_p = 1;
}
+/* Give FNDECL and all its nested functions to cgraph for compilation. */
+
+static void
+c_finalize (tree fndecl)
+{
+ struct cgraph_node *cgn;
+
+ /* Handle attribute((warn_unused_result)). Relies on gimple input. */
+ c_warn_unused_result (&DECL_SAVED_TREE (fndecl));
+
+ /* ??? Objc emits functions after finalizing the compilation unit.
+ This should be cleaned up later and this conditional removed. */
+ if (cgraph_global_info_ready)
+ {
+ c_expand_body (fndecl);
+ return;
+ }
+
+ /* Finalize all nested functions now. */
+ cgn = cgraph_node (fndecl);
+ for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
+ c_finalize (cgn->decl);
+
+ cgraph_finalize_function (fndecl, false);
+}
+
/* Finish up a function declaration and compile that function
all the way to assembler language output. The free the storage
for the function definition.
@@ -6250,17 +6319,44 @@ finish_function (void)
&& current_function_returns_null)
warning ("this function may return with or without a value");
+ /* Store the end of the function, so that we get good line number
+ info for the epilogue. */
+ cfun->function_end_locus = input_location;
+
+ /* If we don't have ctors/dtors sections, and this is a static
+ constructor or destructor, it must be recorded now. */
+ if (DECL_STATIC_CONSTRUCTOR (fndecl)
+ && !targetm.have_ctors_dtors)
+ static_ctors = tree_cons (NULL_TREE, fndecl, static_ctors);
+ if (DECL_STATIC_DESTRUCTOR (fndecl)
+ && !targetm.have_ctors_dtors)
+ static_dtors = tree_cons (NULL_TREE, fndecl, static_dtors);
+
+ /* Genericize before inlining. Delay genericizing nested functions
+ until their parent function is genericized. Since finalizing
+ requires GENERIC, delay that as well. */
+
+ if (DECL_INITIAL (fndecl) && DECL_INITIAL (fndecl) != error_mark_node)
+ {
+ if (!decl_function_context (fndecl))
+ {
+ c_genericize (fndecl);
+ lower_nested_functions (fndecl);
+ c_finalize (fndecl);
+ }
+ else
+ {
+ /* Register this function with cgraph just far enough to get it
+ added to our parent's nested function list. Handy, since the
+ C front end doesn't have such a list. */
+ (void) cgraph_node (fndecl);
+ }
+ }
+
/* We're leaving the context of this function, so zap cfun.
- It's still in DECL_STRUCT_FUNCTION , and we'll restore it in
+ It's still in DECL_STRUCT_FUNCTION, and we'll restore it in
tree_rest_of_compilation. */
cfun = NULL;
-
- /* ??? Objc emits functions after finalizing the compilation unit.
- This should be cleaned up later and this conditional removed. */
- if (!cgraph_global_info_ready)
- cgraph_finalize_function (fndecl, false);
- else
- c_expand_body (fndecl);
current_function_decl = NULL;
}
@@ -6287,23 +6383,14 @@ c_expand_body_1 (tree fndecl, int nested_p)
/* Return to the enclosing function. */
pop_function_context ();
- if (DECL_STATIC_CONSTRUCTOR (fndecl))
- {
- if (targetm.have_ctors_dtors)
- targetm.asm_out.constructor (XEXP (DECL_RTL (fndecl), 0),
- DEFAULT_INIT_PRIORITY);
- else
- static_ctors = tree_cons (NULL_TREE, fndecl, static_ctors);
- }
-
- if (DECL_STATIC_DESTRUCTOR (fndecl))
- {
- if (targetm.have_ctors_dtors)
- targetm.asm_out.destructor (XEXP (DECL_RTL (fndecl), 0),
- DEFAULT_INIT_PRIORITY);
- else
- static_dtors = tree_cons (NULL_TREE, fndecl, static_dtors);
- }
+ if (DECL_STATIC_CONSTRUCTOR (fndecl)
+ && targetm.have_ctors_dtors)
+ targetm.asm_out.constructor (XEXP (DECL_RTL (fndecl), 0),
+ DEFAULT_INIT_PRIORITY);
+ if (DECL_STATIC_DESTRUCTOR (fndecl)
+ && targetm.have_ctors_dtors)
+ targetm.asm_out.destructor (XEXP (DECL_RTL (fndecl), 0),
+ DEFAULT_INIT_PRIORITY);
}
/* Like c_expand_body_1 but only for unnested functions. */
@@ -6509,19 +6596,32 @@ c_begin_compound_stmt (void)
return stmt;
}
-/* Expand T (a DECL_STMT) if it declares an entity not handled by the
+/* Expand DECL if it declares an entity not handled by the
common code. */
-void
-c_expand_decl_stmt (tree t)
+int
+c_expand_decl (tree decl)
{
- tree decl = DECL_STMT_DECL (t);
-
+ if (TREE_CODE (decl) == VAR_DECL && !TREE_STATIC (decl))
+ {
+ /* Let the back-end know about this variable. */
+ if (!anon_aggr_type_p (TREE_TYPE (decl)))
+ emit_local_var (decl);
+ else
+ expand_anon_union_decl (decl, NULL_TREE,
+ DECL_ANON_UNION_ELEMS (decl));
+ }
+ else if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
+ make_rtl_for_local_static (decl);
/* Expand nested functions. */
- if (TREE_CODE (decl) == FUNCTION_DECL
- && DECL_CONTEXT (decl) == current_function_decl
- && DECL_SAVED_TREE (decl))
+ else if (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_CONTEXT (decl) == current_function_decl
+ && DECL_SAVED_TREE (decl))
c_expand_body_1 (decl, 1);
+ else
+ return 0;
+
+ return 1;
}
/* Return the global value of T as a symbol. */
@@ -6625,7 +6725,7 @@ c_write_global_declarations (void)
return;
/* Process all file scopes in this compilation. */
- for (t = current_file_decl; t; t = TREE_CHAIN (t))
+ for (t = all_translation_units; t; t = TREE_CHAIN (t))
c_write_global_declarations_1 (BLOCK_VARS (DECL_INITIAL (t)));
/* Now do the same for the externals scope. */
diff --git a/gcc/c-dump.c b/gcc/c-dump.c
index 5403bf88601..859d8504169 100644
--- a/gcc/c-dump.c
+++ b/gcc/c-dump.c
@@ -32,7 +32,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
void
dump_stmt (dump_info_p di, tree t)
{
- dump_int (di, "line", STMT_LINENO (t));
+ location_t *locus = EXPR_LOCUS (t);
+ if (locus)
+ dump_int (di, "line", locus->line);
}
/* Dump the next statement after STMT. */
diff --git a/gcc/c-format.c b/gcc/c-format.c
index 3a51c6b63b4..17ef68a608a 100644
--- a/gcc/c-format.c
+++ b/gcc/c-format.c
@@ -86,7 +86,7 @@ handle_format_arg_attribute (tree *node, tree name ATTRIBUTE_UNUSED,
{
tree type = *node;
tree format_num_expr = TREE_VALUE (args);
- unsigned HOST_WIDE_INT format_num;
+ unsigned HOST_WIDE_INT format_num = 0;
tree argument;
if (!get_constant (format_num_expr, &format_num, 0))
diff --git a/gcc/c-gimplify.c b/gcc/c-gimplify.c
new file mode 100644
index 00000000000..49b3a671b75
--- /dev/null
+++ b/gcc/c-gimplify.c
@@ -0,0 +1,1102 @@
+/* Tree lowering pass. This pass gimplifies the tree representation built
+ by the C-based front ends. The structure of gimplified, or
+ language-independent, trees is dictated by the grammar described in this
+ file.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Lowering of expressions contributed by Sebastian Pop <s.pop@laposte.net>
+ Re-written to support lowering of whole function trees, documentation
+ and miscellaneous cleanups by Diego Novillo <dnovillo@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "errors.h"
+#include "varray.h"
+#include "c-tree.h"
+#include "c-common.h"
+#include "tree-gimple.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "tree-flow.h"
+#include "tree-inline.h"
+#include "diagnostic.h"
+#include "langhooks.h"
+#include "langhooks-def.h"
+#include "flags.h"
+#include "rtl.h"
+#include "toplev.h"
+#include "tree-dump.h"
+#include "c-pretty-print.h"
+#include "cgraph.h"
+
+
+/* The gimplification pass converts the language-dependent trees
+ (ld-trees) emitted by the parser into language-independent trees
+ (li-trees) that are the target of SSA analysis and transformations.
+
+ Language-independent trees are based on the SIMPLE intermediate
+ representation used in the McCAT compiler framework:
+
+ "Designing the McCAT Compiler Based on a Family of Structured
+ Intermediate Representations,"
+ L. Hendren, C. Donawa, M. Emami, G. Gao, Justiani, and B. Sridharan,
+ Proceedings of the 5th International Workshop on Languages and
+ Compilers for Parallel Computing, no. 757 in Lecture Notes in
+ Computer Science, New Haven, Connecticut, pp. 406-420,
+ Springer-Verlag, August 3-5, 1992.
+
+ http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
+
+ Basically, we walk down gimplifying the nodes that we encounter. As we
+ walk back up, we check that they fit our constraints, and copy them
+ into temporaries if not. */
+
+/* Local declarations. */
+
+static enum gimplify_status gimplify_expr_stmt (tree *);
+static enum gimplify_status gimplify_decl_stmt (tree *);
+static enum gimplify_status gimplify_for_stmt (tree *, tree *);
+static enum gimplify_status gimplify_while_stmt (tree *);
+static enum gimplify_status gimplify_do_stmt (tree *);
+static enum gimplify_status gimplify_if_stmt (tree *);
+static enum gimplify_status gimplify_switch_stmt (tree *);
+static enum gimplify_status gimplify_return_stmt (tree *);
+static enum gimplify_status gimplify_stmt_expr (tree *);
+static enum gimplify_status gimplify_compound_literal_expr (tree *);
+#if defined ENABLE_CHECKING
+static int is_last_stmt_of_scope (tree);
+#endif
+static enum gimplify_status gimplify_block (tree *, tree *);
+static enum gimplify_status gimplify_cleanup (tree *, tree *);
+static tree gimplify_c_loop (tree, tree, tree, bool);
+static void push_context (void);
+static void pop_context (void);
+static tree c_build_bind_expr (tree, tree);
+static void add_block_to_enclosing (tree);
+static void gimplify_condition (tree *);
+
+enum bc_t { bc_break = 0, bc_continue = 1 };
+static tree begin_bc_block (enum bc_t);
+static tree finish_bc_block (tree, tree);
+static tree build_bc_goto (enum bc_t);
+
+static struct c_gimplify_ctx
+{
+ /* For handling break and continue. */
+ tree current_bc_label;
+ tree bc_id[2];
+} *ctxp;
+
+static void
+push_context (void)
+{
+ if (ctxp)
+ abort ();
+ ctxp = (struct c_gimplify_ctx *) xcalloc (1, sizeof (struct c_gimplify_ctx));
+ ctxp->bc_id[bc_continue] = get_identifier ("continue");
+ ctxp->bc_id[bc_break] = get_identifier ("break");
+}
+
+static void
+pop_context (void)
+{
+ if (!ctxp || ctxp->current_bc_label)
+ abort ();
+ free (ctxp);
+ ctxp = NULL;
+}
+
+/* Gimplification of statement trees. */
+
+/* Convert the tree representation of FNDECL from C frontend trees to
+ GENERIC. */
+
+void
+c_genericize (tree fndecl)
+{
+ FILE *dump_file;
+ int local_dump_flags;
+ struct cgraph_node *cgn;
+
+ /* Dump the C-specific tree IR. */
+ dump_file = dump_begin (TDI_original, &local_dump_flags);
+ if (dump_file)
+ {
+ fprintf (dump_file, "\n;; Function %s",
+ (*lang_hooks.decl_printable_name) (fndecl, 2));
+ fprintf (dump_file, " (%s)\n",
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)));
+ fprintf (dump_file, ";; enabled by -%s\n", dump_flag_name (TDI_original));
+ fprintf (dump_file, "\n");
+
+ if (local_dump_flags & TDF_RAW)
+ dump_node (DECL_SAVED_TREE (fndecl),
+ TDF_SLIM | local_dump_flags, dump_file);
+ else
+ print_c_tree (dump_file, DECL_SAVED_TREE (fndecl));
+ fprintf (dump_file, "\n");
+
+ dump_end (TDI_original, dump_file);
+ }
+
+ /* Go ahead and gimplify for now. */
+ push_context ();
+ gimplify_function_tree (fndecl);
+ pop_context ();
+
+ /* Dump the genericized tree IR. */
+ dump_function (TDI_generic, fndecl);
+
+ /* Genericize all nested functions now. We do things in this order so
+ that items like VLA sizes are expanded properly in the context of
+ the correct function. */
+ cgn = cgraph_node (fndecl);
+ for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
+ c_genericize (cgn->decl);
+}
+
+/* Entry point for the tree lowering pass. Recursively scan
+ *STMT_P and convert it to a GIMPLE tree. */
+
+int
+c_gimplify_stmt (tree *stmt_p)
+{
+ tree stmt, next;
+ tree outer_pre = NULL_TREE;
+
+ /* PRE and POST are tree chains that contain the side-effects of the
+ gimplified tree. For instance, given the expression tree:
+
+ c = ++a * 3 + b++;
+
+ After gimplification, the tree will be re-written as:
+
+ a = a + 1;
+ t1 = a * 3; <-- PRE
+ c = t1 + b;
+ b = b + 1; <-- POST */
+
+ for (stmt = *stmt_p; stmt && stmt != error_mark_node; stmt = next)
+ {
+ tree pre, post;
+ int saved_stmts_are_full_exprs_p;
+ location_t stmt_locus;
+ enum gimplify_status ret;
+
+ /* Set up context appropriately for handling this statement. */
+ saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
+ prep_stmt (stmt);
+ stmt_locus = input_location;
+
+ pre = NULL_TREE;
+ post = NULL_TREE;
+
+ next = TREE_CHAIN (stmt);
+
+ switch (TREE_CODE (stmt))
+ {
+ case COMPOUND_STMT:
+ stmt = COMPOUND_BODY (stmt);
+ ret = GS_OK;
+ break;
+
+ case SCOPE_STMT:
+ ret = gimplify_block (&stmt, &next);
+ break;
+
+ case FOR_STMT:
+ ret = gimplify_for_stmt (&stmt, &next);
+ break;
+
+ case WHILE_STMT:
+ ret = gimplify_while_stmt (&stmt);
+ break;
+
+ case DO_STMT:
+ ret = gimplify_do_stmt (&stmt);
+ break;
+
+ case IF_STMT:
+ ret = gimplify_if_stmt (&stmt);
+ break;
+
+ case SWITCH_STMT:
+ ret = gimplify_switch_stmt (&stmt);
+ break;
+
+ case EXPR_STMT:
+ ret = gimplify_expr_stmt (&stmt);
+ break;
+
+ case RETURN_STMT:
+ ret = gimplify_return_stmt (&stmt);
+ break;
+
+ case DECL_STMT:
+ ret = gimplify_decl_stmt (&stmt);
+ break;
+
+ case LABEL_STMT:
+ stmt = build1 (LABEL_EXPR, void_type_node, LABEL_STMT_LABEL (stmt));
+ ret = GS_OK;
+ break;
+
+ case GOTO_STMT:
+ stmt = build1 (GOTO_EXPR, void_type_node, GOTO_DESTINATION (stmt));
+ ret = GS_OK;
+ break;
+
+ case CASE_LABEL:
+ {
+ tree label = create_artificial_label ();
+ stmt = build (CASE_LABEL_EXPR, void_type_node,
+ CASE_LOW (stmt), CASE_HIGH (stmt), label);
+ ret = GS_OK;
+ }
+ break;
+
+ case CONTINUE_STMT:
+ stmt = build_bc_goto (bc_continue);
+ ret = GS_OK;
+ break;
+
+ case BREAK_STMT:
+ stmt = build_bc_goto (bc_break);
+ ret = GS_OK;
+ break;
+
+ case CLEANUP_STMT:
+ ret = gimplify_cleanup (&stmt, &next);
+ break;
+
+ case ASM_STMT:
+ {
+ tree new_stmt = build (ASM_EXPR, void_type_node, ASM_STRING (stmt),
+ ASM_OUTPUTS (stmt), ASM_INPUTS (stmt),
+ ASM_CLOBBERS (stmt));
+ ASM_INPUT_P (new_stmt) = ASM_INPUT_P (stmt);
+ ASM_VOLATILE_P (new_stmt) = ASM_VOLATILE_P (stmt);
+ stmt = new_stmt;
+ ret = GS_OK;
+ }
+ break;
+
+ default:
+ if (lang_gimplify_stmt && (*lang_gimplify_stmt) (&stmt, &next))
+ {
+ ret = GS_OK;
+ break;
+ }
+
+ fprintf (stderr, "unhandled statement node in c_gimplify_stmt:\n");
+ debug_tree (stmt);
+ abort ();
+ break;
+ }
+
+ switch (ret)
+ {
+ case GS_ERROR:
+ goto cont;
+ case GS_OK:
+ gimplify_stmt (&stmt);
+ break;
+ case GS_ALL_DONE:
+ break;
+ default:
+ abort ();
+ }
+
+ /* PRE and POST now contain a list of statements for all the
+ side-effects in STMT. */
+
+ append_to_statement_list (stmt, &pre);
+ append_to_statement_list (post, &pre);
+ annotate_all_with_locus (&pre, stmt_locus);
+
+ append_to_statement_list (pre, &outer_pre);
+ cont:
+ /* Restore saved state. */
+ current_stmt_tree ()->stmts_are_full_exprs_p
+ = saved_stmts_are_full_exprs_p;
+ }
+ append_to_statement_list (stmt, &outer_pre);
+ *stmt_p = outer_pre;
+
+ return GS_ALL_DONE;
+}
+
+static void
+add_block_to_enclosing (tree block)
+{
+ tree enclosing;
+
+ for (enclosing = gimple_current_bind_expr ();
+ enclosing; enclosing = TREE_CHAIN (enclosing))
+ if (BIND_EXPR_BLOCK (enclosing))
+ break;
+
+ enclosing = BIND_EXPR_BLOCK (enclosing);
+ BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block);
+}
+
+/* Genericize a scope by creating a new BIND_EXPR.
+ BLOCK is either a BLOCK representing the scope or a chain of _DECLs.
+ In the latter case, we need to create a new BLOCK and add it to the
+ BLOCK_SUBBLOCKS of the enclosing block.
+ BODY is a chain of C _STMT nodes for the contents of the scope, to be
+ genericized. */
+
+static tree
+c_build_bind_expr (tree block, tree body)
+{
+ tree decls, bind;
+
+ if (block == NULL_TREE)
+ decls = NULL_TREE;
+ else if (TREE_CODE (block) == BLOCK)
+ decls = BLOCK_VARS (block);
+ else
+ {
+ decls = block;
+ if (DECL_ARTIFICIAL (decls))
+ block = NULL_TREE;
+ else
+ {
+ block = make_node (BLOCK);
+ BLOCK_VARS (block) = decls;
+ add_block_to_enclosing (block);
+ }
+ }
+
+ if (!body)
+ body = build_empty_stmt ();
+
+ bind = build (BIND_EXPR, void_type_node, decls, body, block);
+ TREE_SIDE_EFFECTS (bind) = 1;
+
+ return bind;
+}
+
+/* Genericize a syntactic block by removing the bracketing SCOPE_STMTs and
+ wrapping the intervening code in a BIND_EXPR. This function assumes
+ that matching SCOPE_STMTs will always appear in the same statement
+ sequence. */
+
+static enum gimplify_status
+gimplify_block (tree *stmt_p, tree *next_p)
+{
+ tree *p;
+ tree block;
+ tree bind;
+ int depth;
+ location_t stmt_locus;
+
+ if (!SCOPE_BEGIN_P (*stmt_p))
+ {
+ /* Can wind up mismatched with syntax errors. */
+ if (!errorcount && !sorrycount)
+ abort ();
+ *stmt_p = NULL;
+ return GS_ERROR;
+ }
+
+ block = SCOPE_STMT_BLOCK (*stmt_p);
+
+ /* Find the matching ending SCOPE_STMT. */
+ depth = 1;
+ for (p = &TREE_CHAIN (*stmt_p);; p = &TREE_CHAIN (*p))
+ {
+ if (*p == NULL)
+ break;
+ if (TREE_CODE (*p) == SCOPE_STMT)
+ {
+ if (SCOPE_BEGIN_P (*p))
+ ++depth;
+ else if (--depth == 0)
+ break;
+ }
+ }
+
+ stmt_locus = input_location;
+ if (*p)
+ {
+ if (SCOPE_STMT_BLOCK (*p) != block)
+ abort ();
+ if (EXPR_LOCUS (*p))
+ stmt_locus = *EXPR_LOCUS (*p);
+ *next_p = TREE_CHAIN (*p);
+ *p = NULL_TREE;
+ }
+ else
+ {
+ /* Can wind up mismatched with syntax errors. */
+ if (!errorcount && !sorrycount)
+ abort ();
+ }
+
+ bind = c_build_bind_expr (block, TREE_CHAIN (*stmt_p));
+ *stmt_p = bind;
+ input_location = stmt_locus;
+
+ return GS_OK;
+}
+
+/* Genericize a CLEANUP_STMT. Just wrap everything from here to the end of
+ the block in a TRY_FINALLY_EXPR. Or a TRY_CATCH_EXPR, if it's an
+ EH-only cleanup. */
+
+static enum gimplify_status
+gimplify_cleanup (tree *stmt_p, tree *next_p)
+{
+ tree stmt = *stmt_p;
+ tree body = TREE_CHAIN (stmt);
+ tree cleanup = CLEANUP_EXPR (stmt);
+ enum tree_code code
+ = (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR);
+
+ if (!body)
+ body = build_empty_stmt ();
+ if (!cleanup)
+ cleanup = build_empty_stmt ();
+
+ *stmt_p = build (code, void_type_node, body, cleanup);
+ *next_p = NULL_TREE;
+
+ return GS_OK;
+}
+
+/* Gimplify an EXPR_STMT node.
+
+ STMT is the statement node.
+
+ PRE_P points to the list where side effects that must happen before
+ STMT should be stored.
+
+ POST_P points to the list where side effects that must happen after
+ STMT should be stored. */
+
+static enum gimplify_status
+gimplify_expr_stmt (tree *stmt_p)
+{
+ tree stmt = EXPR_STMT_EXPR (*stmt_p);
+
+ if (stmt == error_mark_node)
+ stmt = NULL;
+
+ /* Gimplification of a statement expression will nullify the
+ statement if all its side effects are moved to *PRE_P and *POST_P.
+
+ In this case we will not want to emit the gimplified statement.
+ However, we may still want to emit a warning, so we do that before
+ gimplification. */
+ if (stmt && (extra_warnings || warn_unused_value))
+ {
+ if (!TREE_SIDE_EFFECTS (stmt))
+ {
+ if (!IS_EMPTY_STMT (stmt)
+ && !VOID_TYPE_P (TREE_TYPE (stmt))
+ && !TREE_NO_WARNING (stmt))
+ warning ("statement with no effect");
+ }
+ else if (warn_unused_value)
+ {
+ /* Kludge for 20020220-2.c. warn_if_unused_value shouldn't use
+ the stmt file location info. */
+ set_file_and_line_for_stmt (input_location);
+ warn_if_unused_value (stmt);
+ }
+ }
+
+ if (stmt == NULL_TREE)
+ stmt = build_empty_stmt ();
+ else if (stmts_are_full_exprs_p ())
+ stmt = build1 (CLEANUP_POINT_EXPR, void_type_node, stmt);
+
+ *stmt_p = stmt;
+
+ return GS_OK;
+}
+
+/* If the condition for a loop (or the like) is a decl, it will be a
+ TREE_LIST where the TREE_PURPOSE is a DECL_STMT and the TREE_VALUE is
+ a use of the decl. Turn such a thing into a COMPOUND_EXPR. */
+
+static void
+gimplify_condition (tree *cond_p)
+{
+ tree cond = *cond_p;
+ if (cond && TREE_CODE (cond) == TREE_LIST)
+ {
+ tree decl = TREE_PURPOSE (cond);
+ tree value = TREE_VALUE (cond);
+ c_gimplify_stmt (&decl);
+ *cond_p = build (COMPOUND_EXPR, TREE_TYPE (value), decl, value);
+ }
+}
+
+/* Begin a scope which can be exited by a break or continue statement. BC
+ indicates which.
+
+ Just creates a label and pushes it into the current context. */
+
+static tree
+begin_bc_block (enum bc_t bc)
+{
+ tree label = create_artificial_label ();
+ DECL_NAME (label) = ctxp->bc_id[bc];
+ TREE_CHAIN (label) = ctxp->current_bc_label;
+ ctxp->current_bc_label = label;
+ return label;
+}
+
+/* Finish a scope which can be exited by a break or continue statement.
+ LABEL was returned from the most recent call to begin_bc_block. BODY is
+ an expression for the contents of the scope.
+
+ If we saw a break (or continue) in the scope, append a LABEL_EXPR to
+ body. Otherwise, just forget the label. */
+
+static tree
+finish_bc_block (tree label, tree body)
+{
+ if (label != ctxp->current_bc_label)
+ abort ();
+
+ if (TREE_USED (label))
+ {
+ tree t, sl = NULL;
+
+ /* Clear the name so flow can delete the label. */
+ DECL_NAME (label) = NULL_TREE;
+ t = build1 (LABEL_EXPR, void_type_node, label);
+
+ append_to_statement_list (body, &sl);
+ append_to_statement_list (t, &sl);
+ body = sl;
+ }
+
+ ctxp->current_bc_label = TREE_CHAIN (label);
+ TREE_CHAIN (label) = NULL_TREE;
+ return body;
+}
+
+/* Build a GOTO_EXPR to represent a break or continue statement. BC
+ indicates which. */
+
+static tree
+build_bc_goto (enum bc_t bc)
+{
+ tree label;
+ tree target_name = ctxp->bc_id[bc];
+
+ /* Look for the appropriate type of label. */
+ for (label = ctxp->current_bc_label;
+ label;
+ label = TREE_CHAIN (label))
+ if (DECL_NAME (label) == target_name)
+ break;
+
+ if (label == NULL_TREE)
+ {
+ if (bc == bc_break)
+ error ("break statement not within loop or switch");
+ else
+ error ("continue statement not within loop or switch");
+
+ return NULL_TREE;
+ }
+
+ /* Mark the label used for finish_bc_block. */
+ TREE_USED (label) = 1;
+ return build1 (GOTO_EXPR, void_type_node, label);
+}
+
+/* Build a generic representation of one of the C loop forms. COND is the
+ loop condition or NULL_TREE. BODY is the (possibly compound) statement
+ controlled by the loop. INCR is the increment expression of a for-loop,
+ or NULL_TREE. COND_IS_FIRST indicates whether the condition is
+ evaluated before the loop body as in while and for loops, or after the
+ loop body as in do-while loops. */
+
+static tree
+gimplify_c_loop (tree cond, tree body, tree incr, bool cond_is_first)
+{
+ tree top, entry, exit, cont_block, break_block, stmt_list, t;
+ location_t stmt_locus;
+
+ stmt_locus = input_location;
+
+ /* Detect do { ... } while (0) and don't generate loop construct. */
+ if (!cond_is_first && cond && integer_zerop (cond))
+ top = cond = NULL;
+ else
+ {
+ /* If we use a LOOP_EXPR here, we have to feed the whole thing
+ back through the main gimplifier to lower it. Given that we
+ have to gimplify the loop body NOW so that we can resolve
+ break/continue stmts, seems easier to just expand to gotos. */
+ top = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
+ }
+
+ break_block = begin_bc_block (bc_break);
+
+ if (top)
+ {
+ /* If we have an exit condition, then we build an IF with gotos either
+ out of the loop, or to the top of it. If there's no exit condition,
+ then we just build a jump back to the top. */
+ exit = build_and_jump (&LABEL_EXPR_LABEL (top));
+ if (cond)
+ {
+ gimplify_condition (&cond);
+ t = build_bc_goto (bc_break);
+ exit = build (COND_EXPR, void_type_node, cond, exit, t);
+ exit = fold (exit);
+ gimplify_stmt (&exit);
+ }
+ }
+ else
+ exit = NULL_TREE;
+
+ cont_block = begin_bc_block (bc_continue);
+
+ gimplify_stmt (&body);
+ if (incr && stmts_are_full_exprs_p ())
+ incr = fold (build1 (CLEANUP_POINT_EXPR, void_type_node, incr));
+ gimplify_stmt (&incr);
+
+ body = finish_bc_block (cont_block, body);
+
+ stmt_list = NULL;
+
+ if (cond_is_first && cond)
+ {
+ entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
+ t = build_and_jump (&LABEL_EXPR_LABEL (entry));
+ append_to_statement_list (t, &stmt_list);
+ }
+ else
+ entry = NULL_TREE;
+
+ append_to_statement_list (top, &stmt_list);
+ append_to_statement_list (body, &stmt_list);
+ append_to_statement_list (incr, &stmt_list);
+ append_to_statement_list (entry, &stmt_list);
+ append_to_statement_list (exit, &stmt_list);
+
+ annotate_all_with_locus (&stmt_list, stmt_locus);
+
+ return finish_bc_block (break_block, stmt_list);
+}
+
+/* Gimplify a FOR_STMT node. Move the stuff in the for-init-stmt into the
+ prequeue and hand off to gimplify_c_loop. */
+
+static enum gimplify_status
+gimplify_for_stmt (tree *stmt_p, tree *next_p)
+{
+ tree stmt = *stmt_p;
+ tree init = FOR_INIT_STMT (stmt);
+
+ if (init)
+ {
+ /* Reorganize the statements so that we do the right thing with a
+ CLEANUP_STMT. We want the FOR_STMT and nothing else to be in the
+ scope of the cleanup, so play with pointers to accomplish that. */
+ FOR_INIT_STMT (stmt) = NULL_TREE;
+ chainon (init, stmt);
+ *stmt_p = init;
+ *next_p = TREE_CHAIN (stmt);
+ TREE_CHAIN (stmt) = NULL_TREE;
+ c_gimplify_stmt (stmt_p);
+ }
+ else
+ *stmt_p = gimplify_c_loop (FOR_COND (stmt), FOR_BODY (stmt),
+ FOR_EXPR (stmt), 1);
+
+ return GS_ALL_DONE;
+}
+
+/* Gimplify a WHILE_STMT node. */
+
+static enum gimplify_status
+gimplify_while_stmt (tree *stmt_p)
+{
+ tree stmt = *stmt_p;
+ *stmt_p = gimplify_c_loop (WHILE_COND (stmt), WHILE_BODY (stmt),
+ NULL_TREE, 1);
+ return GS_ALL_DONE;
+}
+
+/* Gimplify a DO_STMT node. */
+
+static enum gimplify_status
+gimplify_do_stmt (tree *stmt_p)
+{
+ tree stmt = *stmt_p;
+ *stmt_p = gimplify_c_loop (DO_COND (stmt), DO_BODY (stmt),
+ NULL_TREE, 0);
+ return GS_ALL_DONE;
+}
+
+/* Genericize an IF_STMT by turning it into a COND_EXPR. */
+
+static enum gimplify_status
+gimplify_if_stmt (tree *stmt_p)
+{
+ tree stmt, then_, else_;
+
+ stmt = *stmt_p;
+ restart:
+ then_ = THEN_CLAUSE (stmt);
+ else_ = ELSE_CLAUSE (stmt);
+
+ if (!then_)
+ then_ = build_empty_stmt ();
+ if (!else_)
+ else_ = build_empty_stmt ();
+
+ stmt = build (COND_EXPR, void_type_node, IF_COND (stmt), then_, else_);
+ gimplify_condition (& TREE_OPERAND (stmt, 0));
+ *stmt_p = stmt;
+
+ /* Handle properly nested if-else chains via iteration instead of
+ mutual recursion between gimplify.c and c-simplify.c. */
+ annotate_with_locus (stmt, input_location);
+ if (TREE_CODE (else_) == IF_STMT && !TREE_CHAIN (else_))
+ {
+ stmt_p = &COND_EXPR_ELSE (stmt);
+ stmt = else_;
+ prep_stmt (stmt);
+ goto restart;
+ }
+
+ return GS_OK;
+}
+
+/* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR. */
+
+static enum gimplify_status
+gimplify_switch_stmt (tree *stmt_p)
+{
+ tree stmt = *stmt_p;
+ tree break_block, body;
+ location_t stmt_locus = input_location;
+
+ break_block = begin_bc_block (bc_break);
+
+ gimplify_condition (&SWITCH_COND (stmt));
+
+ body = SWITCH_BODY (stmt);
+ if (!body)
+ body = build_empty_stmt ();
+
+ *stmt_p = build (SWITCH_EXPR, SWITCH_TYPE (stmt), SWITCH_COND (stmt),
+ body, NULL_TREE);
+ annotate_with_locus (*stmt_p, stmt_locus);
+ gimplify_stmt (stmt_p);
+
+ *stmt_p = finish_bc_block (break_block, *stmt_p);
+ return GS_ALL_DONE;
+}
+
+/* Genericize a RETURN_STMT by turning it into a RETURN_EXPR. */
+
+static enum gimplify_status
+gimplify_return_stmt (tree *stmt_p)
+{
+ tree expr = RETURN_STMT_EXPR (*stmt_p);
+ expr = build1 (RETURN_EXPR, void_type_node, expr);
+ if (stmts_are_full_exprs_p ())
+ expr = build1 (CLEANUP_POINT_EXPR, void_type_node, expr);
+ *stmt_p = expr;
+ return GS_OK;
+}
+
+/* Gimplifies a DECL_STMT node T.
+
+ If a declaration V has an initial value I, create an expression 'V = I'
+ and insert it after the DECL_STMT.
+
+ PRE_P is a queue for effects that should happen before the DECL_STMT.
+
+ MID_P is a queue for effects that should happen after the DECL_STMT,
+ but before uses of the initialized decl.
+
+ POST_P is a queue for effects that should happen after uses of the
+ initialized decl.
+
+ Usually these last two will be the same, but they may need to be
+ different if the DECL_STMT is somehow embedded in an expression. */
+
+static enum gimplify_status
+gimplify_decl_stmt (tree *stmt_p)
+{
+ tree stmt = *stmt_p;
+ tree decl = DECL_STMT_DECL (stmt);
+ tree pre = NULL_TREE;
+ tree post = NULL_TREE;
+
+ if (TREE_TYPE (decl) == error_mark_node)
+ {
+ *stmt_p = NULL;
+ return GS_ERROR;
+ }
+
+ if (TREE_CODE (decl) == TYPE_DECL)
+ {
+ tree type = TREE_TYPE (decl);
+ if (TYPE_SIZE_UNIT (type)
+ && !TREE_CONSTANT (TYPE_SIZE_UNIT (type)))
+ {
+ /* This is a variable-sized array type. Simplify its size. */
+ tree temp = TYPE_SIZE_UNIT (type);
+ gimplify_expr (&temp, &pre, &post, is_gimple_val, fb_rvalue);
+ }
+ }
+
+ if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
+ {
+ tree init = DECL_INITIAL (decl);
+
+ if (!TREE_CONSTANT (DECL_SIZE (decl)))
+ {
+ tree pt_type = build_pointer_type (TREE_TYPE (decl));
+ tree alloc, size;
+
+ /* This is a variable-sized decl. Simplify its size and mark it
+ for deferred expansion. Note that mudflap depends on the format
+ of the emitted code: see mx_register_decls(). */
+
+ size = get_initialized_tmp_var (DECL_SIZE_UNIT (decl), &pre, &post);
+ DECL_DEFER_OUTPUT (decl) = 1;
+ alloc = build_function_call_expr
+ (implicit_built_in_decls[BUILT_IN_STACK_ALLOC],
+ tree_cons (NULL_TREE,
+ build1 (ADDR_EXPR, pt_type, decl),
+ tree_cons (NULL_TREE, size, NULL_TREE)));
+ append_to_compound_expr (alloc, &pre);
+ }
+
+ if (init && init != error_mark_node)
+ {
+ if (!TREE_STATIC (decl))
+ {
+ /* Do not warn about int x = x; as it is a GCC extension
+ to turn off this warning but only if warn_init_self
+ is zero. */
+ if (init == decl && !warn_init_self)
+ TREE_NO_WARNING (decl) = 1;
+
+ DECL_INITIAL (decl) = NULL_TREE;
+ init = build (MODIFY_EXPR, void_type_node, decl, init);
+ if (stmts_are_full_exprs_p ())
+ init = build1 (CLEANUP_POINT_EXPR, void_type_node, init);
+ append_to_compound_expr (init, &pre);
+ }
+ else
+ {
+ /* We must still examine initializers for static variables
+ as they may contain a label address. */
+ walk_tree (&init, force_labels_r, NULL, NULL);
+ }
+ }
+
+ /* This decl isn't mentioned in the enclosing block, so add it to the
+ list of temps. FIXME it seems a bit of a kludge to say that
+ anonymous artificial vars aren't pushed, but everything else is. */
+ if (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
+ gimple_add_tmp_var (decl);
+ }
+
+ append_to_compound_expr (post, &pre);
+ *stmt_p = pre;
+ return GS_OK;
+}
+
+/* Gimplification of expression trees. */
+
+/* Gimplify a C99 compound literal expression. This just means adding the
+ DECL_STMT before the current EXPR_STMT and using its anonymous decl
+ instead. */
+
+static enum gimplify_status
+gimplify_compound_literal_expr (tree *expr_p)
+{
+ tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
+ tree decl = DECL_STMT_DECL (decl_s);
+
+ /* This decl isn't mentioned in the enclosing block, so add it to the
+ list of temps. FIXME it seems a bit of a kludge to say that
+ anonymous artificial vars aren't pushed, but everything else is. */
+ if (DECL_NAME (decl) == NULL_TREE)
+ gimple_add_tmp_var (decl);
+
+ gimplify_decl_stmt (&decl_s);
+ *expr_p = decl_s ? decl_s : decl;
+ return GS_OK;
+}
+
+/* Do C-specific gimplification. Args are as for gimplify_expr. */
+
+int
+c_gimplify_expr (tree *expr_p, tree *pre_p ATTRIBUTE_UNUSED,
+ tree *post_p ATTRIBUTE_UNUSED)
+{
+ enum tree_code code = TREE_CODE (*expr_p);
+
+ if (STATEMENT_CODE_P (code))
+ return c_gimplify_stmt (expr_p);
+
+ switch (code)
+ {
+ case COMPOUND_LITERAL_EXPR:
+ return gimplify_compound_literal_expr (expr_p);
+
+ case STMT_EXPR:
+ return gimplify_stmt_expr (expr_p);
+
+ default:
+ return GS_UNHANDLED;
+ }
+}
+
+/* Returns the final EXPR_STMT which represents the return value of a
+ STMT_EXPR, or NULL_TREE if none. */
+
+tree
+stmt_expr_last_stmt (tree stmt_expr)
+{
+ tree body = STMT_EXPR_STMT (stmt_expr);
+ tree last_stmt, substmt;
+
+ /* Splice the last expression out of the STMT chain. */
+ last_stmt = NULL_TREE;
+ for (substmt = COMPOUND_BODY (body); substmt;
+ substmt = TREE_CHAIN (substmt))
+ if (TREE_CODE (substmt) != SCOPE_STMT)
+ last_stmt = substmt;
+
+ if (last_stmt == NULL_TREE
+ || TREE_CODE (last_stmt) != EXPR_STMT
+ || (TREE_TYPE (last_stmt)
+ && VOID_TYPE_P (TREE_TYPE (last_stmt))))
+ {
+ location_t loc;
+ if (last_stmt && EXPR_LOCUS (last_stmt))
+ loc = *EXPR_LOCUS (last_stmt);
+ else if (EXPR_LOCUS (stmt_expr))
+ loc = *EXPR_LOCUS (stmt_expr);
+ else
+ loc = input_location;
+ warning ("%Hstatement-expressions should end with a "
+ "non-void expression", &loc);
+ last_stmt = NULL_TREE;
+ }
+
+#if defined ENABLE_CHECKING
+ if (last_stmt && !is_last_stmt_of_scope (last_stmt))
+ abort ();
+#endif
+
+ return last_stmt;
+}
+
+/* Gimplify a STMT_EXPR. EXPR_P points to the expression to gimplify.
+ After gimplification, if the STMT_EXPR returns a value, EXPR_P will
+ point to a new temporary that holds that value; otherwise it will be
+ null.
+
+ PRE_P points to the list where side effects that must happen before
+ *EXPR_P should be stored. */
+
+static enum gimplify_status
+gimplify_stmt_expr (tree *expr_p)
+{
+ tree body = STMT_EXPR_STMT (*expr_p);
+
+ if (VOID_TYPE_P (TREE_TYPE (*expr_p)))
+ {
+ *expr_p = body;
+ return c_gimplify_stmt (expr_p);
+ }
+ else
+ {
+ tree last_stmt = stmt_expr_last_stmt (*expr_p);
+ tree last_expr = NULL_TREE;
+
+ if (last_stmt)
+ {
+ last_expr = EXPR_STMT_EXPR (last_stmt);
+
+ if (stmts_are_full_exprs_p ())
+ last_expr = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (last_expr),
+ last_expr);
+ EXPR_STMT_EXPR (last_stmt) = NULL_TREE;
+ }
+
+ /* Genericize the block. */
+ c_gimplify_stmt (&body);
+
+ /* Now retrofit that last expression into the BIND_EXPR. */
+ if (last_expr)
+ {
+ tree *sub_p;
+
+ if (!STMT_EXPR_NO_SCOPE (*expr_p))
+ {
+ /* Our BIND_EXPR will always be hidden within
+ a STATEMENT_LIST. Discard that. */
+ body = expr_first (body);
+ sub_p = &BIND_EXPR_BODY (body);
+
+ /* Append the last expression to the end of the BIND_EXPR.
+ We'll now re-process this, and let voidify_wrapper_expr
+ do its job. */
+ append_to_statement_list_force (last_expr, sub_p);
+ TREE_TYPE (body) = TREE_TYPE (last_expr);
+ }
+ else
+ append_to_compound_expr (last_expr, &body);
+ }
+
+ *expr_p = body;
+ return GS_OK;
+ }
+}
+
+/* Code generation. */
+
+/* Miscellaneous helpers. */
+
+#if defined ENABLE_CHECKING
+/* Return nonzero if STMT is the last statement of its scope. */
+
+static int
+is_last_stmt_of_scope (tree stmt)
+{
+ return (TREE_CHAIN (stmt) == NULL_TREE
+ || (TREE_CODE (TREE_CHAIN (stmt)) == SCOPE_STMT
+ && SCOPE_END_P (TREE_CHAIN (stmt))));
+}
+#endif
diff --git a/gcc/c-incpath.c b/gcc/c-incpath.c
index 167b05a0d9a..b4da86fb7ba 100644
--- a/gcc/c-incpath.c
+++ b/gcc/c-incpath.c
@@ -171,6 +171,7 @@ add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc)
JOIN, unless it duplicates JOIN in which case the last path is
removed. Return the head of the resulting chain. Any of HEAD,
JOIN and SYSTEM can be NULL. */
+
static struct cpp_dir *
remove_duplicates (cpp_reader *pfile, struct cpp_dir *head,
struct cpp_dir *system, struct cpp_dir *join,
@@ -243,9 +244,10 @@ remove_duplicates (cpp_reader *pfile, struct cpp_dir *head,
We can't just merge the lists and then uniquify them because then
we may lose directories from the <> search path that should be
- there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however safe
- to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written -Ibar -I- -Ifoo
- -Iquux. */
+ there; consider -iquote foo -iquote bar -Ifoo -Iquux. It is
+ however safe to treat -iquote bar -iquote foo -Ifoo -Iquux as if
+ written -iquote bar -Ifoo -Iquux. */
+
static void
merge_include_chains (cpp_reader *pfile, int verbose)
{
diff --git a/gcc/c-lang.c b/gcc/c-lang.c
index 93dc4052916..cf422cb3cc5 100644
--- a/gcc/c-lang.c
+++ b/gcc/c-lang.c
@@ -30,6 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "ggc.h"
#include "langhooks.h"
#include "langhooks-def.h"
+#include "tree-inline.h"
#include "diagnostic.h"
#include "c-pretty-print.h"
@@ -63,6 +64,8 @@ enum c_language_kind c_language = clk_c;
#define LANG_HOOKS_SAFE_FROM_P c_safe_from_p
#undef LANG_HOOKS_EXPAND_EXPR
#define LANG_HOOKS_EXPAND_EXPR c_expand_expr
+#undef LANG_HOOKS_EXPAND_DECL
+#define LANG_HOOKS_EXPAND_DECL c_expand_decl
#undef LANG_HOOKS_MARK_ADDRESSABLE
#define LANG_HOOKS_MARK_ADDRESSABLE c_mark_addressable
#undef LANG_HOOKS_PARSE_FILE
@@ -89,13 +92,10 @@ enum c_language_kind c_language = clk_c;
#define LANG_HOOKS_FUNCTION_ENTER_NESTED c_push_function_context
#undef LANG_HOOKS_FUNCTION_LEAVE_NESTED
#define LANG_HOOKS_FUNCTION_LEAVE_NESTED c_pop_function_context
+#undef LANG_HOOKS_FUNCTION_MISSING_NORETURN_OK_P
+#define LANG_HOOKS_FUNCTION_MISSING_NORETURN_OK_P c_missing_noreturn_ok_p
#undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL c_dup_lang_specific_decl
-#undef LANG_HOOKS_DECL_UNINIT
-#define LANG_HOOKS_DECL_UNINIT c_decl_uninit
-
-#undef LANG_HOOKS_RTL_EXPAND_STMT
-#define LANG_HOOKS_RTL_EXPAND_STMT expand_stmt
/* Attribute hooks. */
#undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
@@ -103,20 +103,24 @@ enum c_language_kind c_language = clk_c;
#undef LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE
#define LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE c_common_format_attribute_table
+#undef LANG_HOOKS_TREE_INLINING_WALK_SUBTREES
+#define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES \
+ c_walk_subtrees
#undef LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN
#define LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN \
c_cannot_inline_tree_fn
#undef LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS
#define LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS \
c_disregard_inline_limits
+#undef LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P
+#define LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P \
+ c_tree_chain_matters_p
#undef LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P
#define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P \
anon_aggr_type_p
#undef LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING
#define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
c_convert_parm_for_inlining
-#undef LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS
-#define LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS c_estimate_num_insns
#undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
#define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN c_dump_tree
@@ -156,6 +160,13 @@ enum c_language_kind c_language = clk_c;
#undef LANG_HOOKS_WRITE_GLOBALS
#define LANG_HOOKS_WRITE_GLOBALS c_write_global_declarations
+/* Hooks for tree gimplification. */
+#undef LANG_HOOKS_GIMPLIFY_EXPR
+#define LANG_HOOKS_GIMPLIFY_EXPR c_gimplify_expr
+
+#undef LANG_HOOKS_TYPES_COMPATIBLE_P
+#define LANG_HOOKS_TYPES_COMPATIBLE_P c_types_compatible_p
+
/* ### When changing hooks, consider if ObjC needs changing too!! ### */
/* Each front end provides its own. */
@@ -202,6 +213,11 @@ finish_file (void)
c_objc_common_finish_file ();
}
+int
+c_types_compatible_p (tree x, tree y)
+{
+ return comptypes (TYPE_MAIN_VARIANT (x), TYPE_MAIN_VARIANT (y), 0);
+}
static void
c_initialize_diagnostics (diagnostic_context *context)
{
diff --git a/gcc/c-mudflap.c b/gcc/c-mudflap.c
new file mode 100644
index 00000000000..e2fa5b1a438
--- /dev/null
+++ b/gcc/c-mudflap.c
@@ -0,0 +1,100 @@
+/* Mudflap: narrow-pointer bounds-checking by tree rewriting:
+ C front-end interface.
+
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Frank Ch. Eigler <fche@redhat.com>
+ and Graydon Hoare <graydon@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#include "config.h"
+#include "errors.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "tree-inline.h"
+#include "c-tree.h"
+#include "c-common.h"
+#include "diagnostic.h"
+#include "output.h"
+#include "varray.h"
+#include "tree-mudflap.h"
+#include "target.h"
+#include "flags.h"
+#include "rtl.h"
+#include "toplev.h"
+#include "function.h"
+
+
+
+/* ------------------------------------------------------------------------ */
+
+
+/* Initialize the global tree nodes that correspond to mf-runtime.h
+ declarations. */
+tree
+mflang_lookup_decl (const char* name)
+{
+ tree decl = lookup_name (get_identifier (name));
+ if (decl == NULL_TREE)
+ internal_error ("mudflap: cannot find declaration of `%s' from mf-runtime.h",
+ name);
+
+ return decl;
+}
+
+
+/* Emit a synthetic CTOR function for the current file. Populate it from
+ the enqueued __mf_register calls. Compile the function. */
+
+void
+mflang_flush_calls (tree enqueued_call_stmt_chain)
+{
+ tree fnname, t1, t2, body, block, scope;
+
+ /* Short-circuit! */
+ if (enqueued_call_stmt_chain == NULL_TREE)
+ return;
+
+ fnname = get_identifier ("__mudflap_static_initializer");
+ t1 = build_tree_list (NULL_TREE, void_type_node);
+ t2 = tree_cons (NULL, NULL, t1);
+ start_function (t1, build_nt (CALL_EXPR, fnname, t2, NULL), NULL);
+ store_parm_decls ();
+
+ DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
+ TREE_PUBLIC (current_function_decl) = 0;
+ TREE_USED (current_function_decl) = 1;
+ mf_mark (current_function_decl);
+
+ body = c_begin_compound_stmt ();
+ push_scope ();
+ clear_last_expr ();
+ add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
+
+ c_expand_expr_stmt (enqueued_call_stmt_chain);
+
+ scope = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
+ block = pop_scope ();
+ SCOPE_STMT_BLOCK (TREE_PURPOSE (scope)) = block;
+ SCOPE_STMT_BLOCK (TREE_VALUE (scope)) = block;
+ RECHAIN_STMTS (body, COMPOUND_BODY (body));
+ finish_function ();
+}
diff --git a/gcc/c-objc-common.c b/gcc/c-objc-common.c
index e736110e6be..f7e7c8acb10 100644
--- a/gcc/c-objc-common.c
+++ b/gcc/c-objc-common.c
@@ -36,14 +36,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "varray.h"
#include "ggc.h"
#include "langhooks.h"
+#include "tree-mudflap.h"
#include "target.h"
#include "cgraph.h"
static bool c_tree_printer (pretty_printer *, text_info *);
-static tree start_cdtor (int);
-static void finish_cdtor (tree);
-int
+bool
c_missing_noreturn_ok_p (tree decl)
{
/* A missing noreturn is not ok for freestanding implementations and
@@ -166,13 +165,10 @@ c_objc_common_init (void)
if (c_common_init () == false)
return false;
- lang_expand_decl_stmt = c_expand_decl_stmt;
-
/* These were not defined in the Objective-C front end, but I'm
putting them here anyway. The diagnostic format decoder might
want an enhanced ObjC implementation. */
diagnostic_format_decoder (global_dc) = &c_tree_printer;
- lang_missing_noreturn_ok_p = &c_missing_noreturn_ok_p;
/* If still unspecified, make it match -std=c99
(allowing for -pedantic-errors). */
@@ -187,40 +183,33 @@ c_objc_common_init (void)
return true;
}
-static tree
-start_cdtor (int method_type)
+/* Synthesize a function which calls all the global ctors or global dtors
+ in this file. */
+static void
+build_cdtor (int method_type, tree cdtors)
{
tree fnname = get_file_function_name (method_type);
- tree void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
tree body;
+ tree scope;
+ tree block;
- start_function (void_list_node_1,
+ start_function (void_list_node,
build_nt (CALL_EXPR, fnname,
- tree_cons (NULL_TREE, NULL_TREE, void_list_node_1),
+ tree_cons (NULL_TREE, NULL_TREE, void_list_node),
NULL_TREE),
NULL_TREE);
store_parm_decls ();
- current_function_cannot_inline
- = "static constructors and destructors cannot be inlined";
-
body = c_begin_compound_stmt ();
-
- push_scope ();
- clear_last_expr ();
add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
- return body;
-}
-
-static void
-finish_cdtor (tree body)
-{
- tree scope;
- tree block;
+ for (; cdtors; cdtors = TREE_CHAIN (cdtors))
+ add_stmt (build_stmt (EXPR_STMT,
+ build_function_call (TREE_VALUE (cdtors), 0)));
scope = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
- block = pop_scope ();
+
+ block = make_node (BLOCK);
SCOPE_STMT_BLOCK (TREE_PURPOSE (scope)) = block;
SCOPE_STMT_BLOCK (TREE_VALUE (scope)) = block;
@@ -237,30 +226,22 @@ c_objc_common_finish_file (void)
if (pch_file)
c_common_write_pch ();
- cgraph_finalize_compilation_unit ();
- cgraph_optimize ();
-
if (static_ctors)
{
- tree body = start_cdtor ('I');
-
- for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors))
- c_expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors),
- NULL_TREE));
-
- finish_cdtor (body);
+ build_cdtor ('I', static_ctors);
+ static_ctors = 0;
}
-
if (static_dtors)
{
- tree body = start_cdtor ('D');
+ build_cdtor ('D', static_dtors);
+ static_dtors = 0;
+ }
- for (; static_dtors; static_dtors = TREE_CHAIN (static_dtors))
- c_expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors),
- NULL_TREE));
+ cgraph_finalize_compilation_unit ();
+ cgraph_optimize ();
- finish_cdtor (body);
- }
+ if (flag_mudflap)
+ mudflap_finish_file ();
}
/* Called during diagnostic message formatting process to print a
diff --git a/gcc/c-opts.c b/gcc/c-opts.c
index 7aa21c4458f..1300b69cd0b 100644
--- a/gcc/c-opts.c
+++ b/gcc/c-opts.c
@@ -101,7 +101,7 @@ static size_t deferred_count;
/* Number of deferred options scanned for -include. */
static size_t include_cursor;
-/* Permit Fotran front-end options. */
+/* Permit Fortran front-end options. */
static bool permit_fortran_options;
static void set_Wimplicit (int);
@@ -162,6 +162,7 @@ c_common_missing_argument (const char *opt, size_t code)
case OPT_idirafter:
case OPT_isysroot:
case OPT_isystem:
+ case OPT_iquote:
error ("missing path after \"%s\"", opt);
break;
@@ -303,6 +304,7 @@ c_common_handle_option (size_t scode, const char *arg, int value)
error ("-I- specified twice");
quote_chain_split = true;
split_quote_chain ();
+ inform ("obsolete option -I- used, please use -iquote instead");
}
break;
@@ -731,11 +733,6 @@ c_common_handle_option (size_t scode, const char *arg, int value)
cpp_opts->dollars_in_ident = value;
break;
- case OPT_fdump_:
- if (!dump_switch_p (arg))
- result = 0;
- break;
-
case OPT_ffreestanding:
value = !value;
/* Fall through.... */
@@ -954,6 +951,10 @@ c_common_handle_option (size_t scode, const char *arg, int value)
iprefix = arg;
break;
+ case OPT_iquote:
+ add_path (xstrdup (arg), QUOTE, 0);
+ break;
+
case OPT_isysroot:
sysroot = arg;
break;
@@ -1094,17 +1095,13 @@ c_common_post_options (const char **pfilename)
flag_inline_trees = 1;
- /* Use tree inlining if possible. Function instrumentation is only
- done in the RTL level, so we disable tree inlining. */
- if (! flag_instrument_function_entry_exit)
+ /* Use tree inlining. */
+ if (!flag_no_inline)
+ flag_no_inline = 1;
+ if (flag_inline_functions)
{
- if (!flag_no_inline)
- flag_no_inline = 1;
- if (flag_inline_functions)
- {
- flag_inline_trees = 2;
- flag_inline_functions = 0;
- }
+ flag_inline_trees = 2;
+ flag_inline_functions = 0;
}
/* -Wextra implies -Wsign-compare, but not if explicitly
@@ -1171,8 +1168,12 @@ c_common_post_options (const char **pfilename)
*pfilename = this_input_filename
= cpp_read_main_file (parse_in, in_fnames[0]);
+ /* Don't do any compilation or preprocessing if there is no input file. */
if (this_input_filename == NULL)
- return true;
+ {
+ errorcount++;
+ return false;
+ }
if (flag_working_directory
&& flag_preprocess_only && ! flag_no_line_commands)
diff --git a/gcc/c-parse.in b/gcc/c-parse.in
index 91a42d91814..07854c48d6b 100644
--- a/gcc/c-parse.in
+++ b/gcc/c-parse.in
@@ -661,6 +661,7 @@ primary:
last_expr_type = void_type_node;
$$ = build1 (STMT_EXPR, last_expr_type, $1);
TREE_SIDE_EFFECTS ($$) = 1;
+ annotate_with_locus ($$, input_location);
}
| compstmt_primary_start error ')'
{
@@ -2130,7 +2131,7 @@ simple_if:
if_prefix:
/* We must build the IF_STMT node before parsing its
- condition so that STMT_LINENO refers to the line
+ condition so that EXPR_LOCUS refers to the line
containing the "if", and not the line containing
the close-parenthesis.
@@ -2194,12 +2195,8 @@ lineno_stmt:
save_location stmt
{ if ($2)
{
- STMT_LINENO ($2) = $1.line;
- /* ??? We currently have no way of recording
- the filename for a statement. This probably
- matters little in practice at the moment,
- but I suspect that problems will occur when
- doing inlining at the tree level. */
+ SET_EXPR_LOCUS ($2, NULL);
+ annotate_with_locus ($2, $1);
}
}
;
@@ -2208,7 +2205,8 @@ lineno_label:
save_location label
{ if ($2)
{
- STMT_LINENO ($2) = $1.line;
+ SET_EXPR_LOCUS ($2, NULL);
+ annotate_with_locus ($2, $1);
}
}
;
@@ -2237,7 +2235,7 @@ select_or_iter_stmt:
| simple_if ELSE error
{ c_expand_end_cond (); }
/* We must build the WHILE_STMT node before parsing its
- condition so that STMT_LINENO refers to the line
+ condition so that EXPR_LOCUS refers to the line
containing the "while", and not the line containing
the close-parenthesis.
diff --git a/gcc/c-pragma.c b/gcc/c-pragma.c
index c9e15056e78..31a17a109d2 100644
--- a/gcc/c-pragma.c
+++ b/gcc/c-pragma.c
@@ -352,7 +352,6 @@ maybe_apply_pragma_weak (tree decl ATTRIBUTE_UNUSED)
static GTY(()) tree pending_redefine_extname;
-#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
static void handle_pragma_redefine_extname (cpp_reader *);
/* #pragma redefined_extname oldname newname */
@@ -377,7 +376,8 @@ handle_pragma_redefine_extname (cpp_reader *dummy ATTRIBUTE_UNUSED)
warning ("junk at end of #pragma redefine_extname");
decl = identifier_global_value (oldname);
- if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
+ if (decl && (TREE_CODE (decl) == FUNCTION_DECL
+ || TREE_CODE (decl) == VAR_DECL))
{
if (DECL_ASSEMBLER_NAME_SET_P (decl)
&& DECL_ASSEMBLER_NAME (decl) != newname)
@@ -387,7 +387,6 @@ handle_pragma_redefine_extname (cpp_reader *dummy ATTRIBUTE_UNUSED)
else
add_to_renaming_pragma_list(oldname, newname);
}
-#endif
void
add_to_renaming_pragma_list (tree oldname, tree newname)
@@ -501,6 +500,9 @@ init_pragma (void)
#endif
#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
c_register_pragma (0, "redefine_extname", handle_pragma_redefine_extname);
+#else
+ if (flag_mudflap)
+ c_register_pragma (0, "redefine_extname", handle_pragma_redefine_extname);
#endif
#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);
diff --git a/gcc/c-pretty-print.c b/gcc/c-pretty-print.c
index 5673d73c7c1..e73ab1b51e3 100644
--- a/gcc/c-pretty-print.c
+++ b/gcc/c-pretty-print.c
@@ -26,6 +26,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "real.h"
#include "c-pretty-print.h"
#include "c-tree.h"
+#include "diagnostic.h"
/* The pretty-printer code is primarily designed to closely follow
(GNU) C and C++ grammars. That is to be contrasted with spaghetti
@@ -280,7 +281,7 @@ pp_c_type_specifier (c_pretty_printer *pp, tree t)
break;
case IDENTIFIER_NODE:
- pp_c_tree_identifier (pp, t);
+ pp_c_tree_decl_identifier (pp, t);
break;
case VOID_TYPE:
@@ -561,11 +562,10 @@ pp_c_direct_declarator (c_pretty_printer *pp, tree t)
case TYPE_DECL:
case FIELD_DECL:
case LABEL_DECL:
- if (DECL_NAME (t))
- {
- pp_c_space_for_pointer_operator (pp, TREE_TYPE (t));
- pp_c_tree_identifier (pp, DECL_NAME (t));
- }
+ pp_c_space_for_pointer_operator (pp, TREE_TYPE (t));
+ pp_c_tree_decl_identifier (pp, t);
+ break;
+
case ARRAY_TYPE:
case POINTER_TYPE:
pp_abstract_declarator (pp, TREE_TYPE (t));
@@ -578,7 +578,7 @@ pp_c_direct_declarator (c_pretty_printer *pp, tree t)
case FUNCTION_DECL:
pp_c_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t)));
- pp_c_tree_identifier (pp, DECL_NAME (t));
+ pp_c_tree_decl_identifier (pp, t);
if (pp_c_base (pp)->flags & pp_c_flag_abstract)
pp_abstract_declarator (pp, TREE_TYPE (t));
else
@@ -960,8 +960,9 @@ pp_c_primary_expression (c_pretty_printer *pp, tree e)
case CONST_DECL:
case FUNCTION_DECL:
case LABEL_DECL:
- e = DECL_NAME (e);
- /* Fall through. */
+ pp_c_tree_decl_identifier (pp, e);
+ break;
+
case IDENTIFIER_NODE:
pp_c_tree_identifier (pp, e);
break;
@@ -980,6 +981,22 @@ pp_c_primary_expression (c_pretty_printer *pp, tree e)
pp_c_constant (pp, e);
break;
+ case TARGET_EXPR:
+ pp_c_identifier (pp, "__builtin_memcpy");
+ pp_c_left_paren (pp);
+ pp_ampersand (pp);
+ pp_primary_expression (pp, TREE_OPERAND (e, 0));
+ pp_separate_with (pp, ',');
+ pp_ampersand (pp);
+ pp_initializer (pp, TREE_OPERAND (e, 1));
+ if (TREE_OPERAND (e, 2))
+ {
+ pp_separate_with (pp, ',');
+ pp_c_expression (pp, TREE_OPERAND (e, 2));
+ }
+ pp_c_right_paren (pp);
+ break;
+
case STMT_EXPR:
pp_c_left_paren (pp);
pp_statement (pp, STMT_EXPR_STMT (e));
@@ -1005,13 +1022,7 @@ static void
pp_c_initializer (c_pretty_printer *pp, tree e)
{
if (TREE_CODE (e) == CONSTRUCTOR)
- {
- enum tree_code code = TREE_CODE (TREE_TYPE (e));
- if (code == RECORD_TYPE || code == UNION_TYPE || code == ARRAY_TYPE)
- pp_c_brace_enclosed_initializer_list (pp, e);
- else
- pp_unsupported_tree (pp, TREE_OPERAND (e, 1));
- }
+ pp_c_brace_enclosed_initializer_list (pp, e);
else
pp_expression (pp, e);
}
@@ -1099,25 +1110,36 @@ pp_c_initializer_list (c_pretty_printer *pp, tree e)
pp_separate_with (pp, ',');
}
}
- break;
+ return;
case VECTOR_TYPE:
- pp_c_expression_list (pp, TREE_VECTOR_CST_ELTS (e));
- break;
+ if (TREE_CODE (e) == VECTOR_CST)
+ pp_c_expression_list (pp, TREE_VECTOR_CST_ELTS (e));
+ else if (TREE_CODE (e) == CONSTRUCTOR)
+ pp_c_expression_list (pp, CONSTRUCTOR_ELTS (e));
+ else
+ break;
+ return;
case COMPLEX_TYPE:
- {
- const bool cst = TREE_CODE (e) == COMPLEX_CST;
- pp_expression (pp, cst ? TREE_REALPART (e) : TREE_OPERAND (e, 0));
- pp_separate_with (pp, ',');
- pp_expression (pp, cst ? TREE_IMAGPART (e) : TREE_OPERAND (e, 1));
- }
- break;
+ if (TREE_CODE (e) == CONSTRUCTOR)
+ pp_c_expression_list (pp, CONSTRUCTOR_ELTS (e));
+ else if (TREE_CODE (e) == COMPLEX_CST || TREE_CODE (e) == COMPLEX_EXPR)
+ {
+ const bool cst = TREE_CODE (e) == COMPLEX_CST;
+ pp_expression (pp, cst ? TREE_REALPART (e) : TREE_OPERAND (e, 0));
+ pp_separate_with (pp, ',');
+ pp_expression (pp, cst ? TREE_IMAGPART (e) : TREE_OPERAND (e, 1));
+ }
+ else
+ break;
+ return;
default:
- pp_unsupported_tree (pp, type);
break;
}
+
+ pp_unsupported_tree (pp, type);
}
/* Pretty-print a brace-enclosed initializer-list. */
@@ -1149,7 +1171,9 @@ pp_c_id_expression (c_pretty_printer *pp, tree t)
case FUNCTION_DECL:
case FIELD_DECL:
case LABEL_DECL:
- t = DECL_NAME (t);
+ pp_c_tree_decl_identifier (pp, t);
+ break;
+
case IDENTIFIER_NODE:
pp_c_tree_identifier (pp, t);
break;
@@ -1862,7 +1886,7 @@ pp_c_statement (c_pretty_printer *pp, tree stmt)
else
pp_indentation (pp) -= 3;
if (code == LABEL_STMT)
- pp_tree_identifier (pp, DECL_NAME (LABEL_STMT_LABEL (stmt)));
+ pp_c_tree_decl_identifier (pp, LABEL_STMT_LABEL (stmt));
else if (code == CASE_LABEL)
{
if (CASE_LOW (stmt) == NULL_TREE)
@@ -2121,16 +2145,6 @@ pp_c_statement (c_pretty_printer *pp, tree stmt)
}
break;
- case FILE_STMT:
- pp_c_identifier (pp, "__FILE__");
- pp_space (pp);
- pp_equal (pp);
- pp_c_whitespace (pp);
- pp_c_identifier (pp, FILE_STMT_FILENAME (stmt));
- pp_c_semicolon (pp);
- pp_needs_newline (pp) = true;
- break;
-
default:
pp_unsupported_tree (pp, stmt);
}
@@ -2170,3 +2184,60 @@ pp_c_pretty_printer_init (c_pretty_printer *pp)
pp->assignment_expression = pp_c_assignment_expression;
pp->expression = pp_c_expression;
}
+
+
+/* Print the tree T in full, on file FILE. */
+
+void
+print_c_tree (FILE *file, tree t)
+{
+ static c_pretty_printer pp_rec;
+ static bool initialized = 0;
+ c_pretty_printer *pp = &pp_rec;
+
+ if (!initialized)
+ {
+ initialized = 1;
+ pp_construct (pp_base (pp), NULL, 0);
+ pp_c_pretty_printer_init (pp);
+ pp_needs_newline (pp) = true;
+ }
+ pp_base (pp)->buffer->stream = file;
+
+ pp_statement (pp, t);
+
+ pp_newline (pp);
+ pp_flush (pp);
+}
+
+/* Print the tree T in full, on stderr. */
+
+void
+debug_c_tree (tree t)
+{
+ print_c_tree (stderr, t);
+ fputc ('\n', stderr);
+}
+
+/* Output the DECL_NAME of T. If T has no DECL_NAME, output a string made
+ up of T's memory address. */
+
+void
+pp_c_tree_decl_identifier (c_pretty_printer *pp, tree t)
+{
+ const char *name;
+
+ if (!DECL_P (t))
+ abort ();
+
+ if (DECL_NAME (t))
+ name = IDENTIFIER_POINTER (DECL_NAME (t));
+ else
+ {
+ static char xname[8];
+ sprintf (xname, "<U%4x>", ((unsigned)((unsigned long)(t) & 0xffff)));
+ name = xname;
+ }
+
+ pp_c_identifier (pp, name);
+}
diff --git a/gcc/c-pretty-print.h b/gcc/c-pretty-print.h
index 39e0be77d2d..efffa234d4b 100644
--- a/gcc/c-pretty-print.h
+++ b/gcc/c-pretty-print.h
@@ -95,7 +95,7 @@ struct c_pretty_print_info
#undef pp_base
#define pp_base(PP) (&pp_c_base (PP)->base)
-
+
#define pp_c_tree_identifier(PPI, ID) \
pp_c_identifier (PPI, IDENTIFIER_POINTER (ID))
@@ -166,6 +166,7 @@ void pp_c_semicolon (c_pretty_printer *);
void pp_c_space_for_pointer_operator (c_pretty_printer *, tree);
/* Declarations. */
+void pp_c_tree_decl_identifier (c_pretty_printer *, tree);
void pp_c_function_definition (c_pretty_printer *, tree);
void pp_c_attributes (c_pretty_printer *, tree);
void pp_c_type_qualifier_list (c_pretty_printer *, tree);
@@ -197,4 +198,6 @@ void pp_c_id_expression (c_pretty_printer *, tree);
void pp_c_identifier (c_pretty_printer *, const char *);
void pp_c_string_literal (c_pretty_printer *, tree);
+void print_c_tree (FILE *file, tree t);
+
#endif /* GCC_C_PRETTY_PRINTER */
diff --git a/gcc/c-semantics.c b/gcc/c-semantics.c
index a8693f9b3f1..b74fda6302a 100644
--- a/gcc/c-semantics.c
+++ b/gcc/c-semantics.c
@@ -44,23 +44,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "timevar.h"
#include "predict.h"
#include "tree-inline.h"
-
-/* If non-NULL, the address of a language-specific function for
- expanding statements. */
-void (*lang_expand_stmt) (tree);
-
-/* If non-NULL, the address of a language-specific function for
- expanding a DECL_STMT. After the language-independent cases are
- handled, this function will be called. If this function is not
- defined, it is assumed that declarations other than those for
- variables and labels do not require any RTL generation. */
-void (*lang_expand_decl_stmt) (tree);
-
-static tree find_reachable_label_1 (tree *, int *, void *);
-static tree find_reachable_label (tree);
-static bool expand_unreachable_if_stmt (tree);
-static tree expand_unreachable_stmt (tree, int);
-static void genrtl_do_stmt_1 (tree, tree);
+#include "langhooks.h"
/* Create an empty statement tree rooted at T. */
@@ -81,18 +65,8 @@ begin_stmt_tree (tree *t)
tree
add_stmt (tree t)
{
- if (input_filename != last_expr_filename)
- {
- /* If the filename has changed, also add in a FILE_STMT. Do a string
- compare first, though, as it might be an equivalent string. */
- int add = (strcmp (input_filename, last_expr_filename) != 0);
- last_expr_filename = input_filename;
- if (add)
- {
- tree pos = build_nt (FILE_STMT, get_identifier (input_filename));
- add_stmt (pos);
- }
- }
+ if (!EXPR_LOCUS (t))
+ annotate_with_locus (t, input_location);
/* Add T to the statement-tree. */
TREE_CHAIN (last_tree) = t;
@@ -171,58 +145,53 @@ finish_stmt_tree (tree *t)
stmt = TREE_CHAIN (*t);
*t = stmt;
last_tree = NULL_TREE;
-
- if (cfun && stmt)
- {
- /* The line-number recorded in the outermost statement in a function
- is the line number of the end of the function. */
- STMT_LINENO (stmt) = input_line;
- STMT_LINENO_FOR_FN_P (stmt) = 1;
- }
}
/* Build a generic statement based on the given type of node and
arguments. Similar to `build_nt', except that we set
- STMT_LINENO to be the current line number. */
+ EXPR_LOCUS to be the current source location. */
/* ??? This should be obsolete with the lineno_stmt productions
in the grammar. */
tree
build_stmt (enum tree_code code, ...)
{
- tree t;
- int length;
- int i;
+ tree ret;
+ int length, i;
va_list p;
+ bool side_effects;
va_start (p, code);
- t = make_node (code);
+ ret = make_node (code);
length = TREE_CODE_LENGTH (code);
- STMT_LINENO (t) = input_line;
-
- for (i = 0; i < length; i++)
- TREE_OPERAND (t, i) = va_arg (p, tree);
-
- va_end (p);
- return t;
-}
+ annotate_with_locus (ret, input_location);
-/* Some statements, like for-statements or if-statements, require a
- condition. This condition can be a declaration. If T is such a
- declaration it is processed, and an expression appropriate to use
- as the condition is returned. Otherwise, T itself is returned. */
+ /* Most statements have implicit side effects all on their own,
+ such as control transfer. For those that do, we'll compute
+ the real value of TREE_SIDE_EFFECTS from its arguments. */
+ switch (code)
+ {
+ case EXPR_STMT:
+ side_effects = false;
+ break;
+ default:
+ side_effects = true;
+ break;
+ }
-tree
-expand_cond (tree t)
-{
- if (t && TREE_CODE (t) == TREE_LIST)
+ for (i = 0; i < length; i++)
{
- expand_stmt (TREE_PURPOSE (t));
- return TREE_VALUE (t);
+ tree t = va_arg (p, tree);
+ if (t && IS_NON_TYPE_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (t))))
+ side_effects |= TREE_SIDE_EFFECTS (t);
+ TREE_OPERAND (ret, i) = t;
}
- else
- return t;
+
+ TREE_SIDE_EFFECTS (ret) = side_effects;
+
+ va_end (p);
+ return ret;
}
/* Create RTL for the local static variable DECL. */
@@ -268,7 +237,7 @@ emit_local_var (tree decl)
/* Create RTL for this variable. */
if (!DECL_RTL_SET_P (decl))
{
- if (DECL_C_HARD_REGISTER (decl))
+ if (DECL_HARD_REGISTER (decl))
/* The user specified an assembler name for this variable.
Set that up now. */
rest_of_decl_compilation
@@ -291,214 +260,6 @@ emit_local_var (tree decl)
}
}
-/* Helper for generating the RTL at the beginning of a scope. */
-
-void
-genrtl_do_pushlevel (void)
-{
- emit_line_note (input_location);
- clear_last_expr ();
-}
-
-/* Generate the RTL for DESTINATION, which is a GOTO_STMT. */
-
-void
-genrtl_goto_stmt (tree destination)
-{
- if (TREE_CODE (destination) == IDENTIFIER_NODE)
- abort ();
-
- /* We warn about unused labels with -Wunused. That means we have to
- mark the used labels as used. */
- if (TREE_CODE (destination) == LABEL_DECL)
- TREE_USED (destination) = 1;
-
- emit_line_note (input_location);
-
- if (TREE_CODE (destination) == LABEL_DECL)
- {
- label_rtx (destination);
- expand_goto (destination);
- }
- else
- expand_computed_goto (destination);
-}
-
-/* Generate the RTL for EXPR, which is an EXPR_STMT. Provided just
- for backward compatibility. genrtl_expr_stmt_value() should be
- used for new code. */
-
-void
-genrtl_expr_stmt (tree expr)
-{
- genrtl_expr_stmt_value (expr, -1, 1);
-}
-
-/* Generate the RTL for EXPR, which is an EXPR_STMT. WANT_VALUE tells
- whether to (1) save the value of the expression, (0) discard it or
- (-1) use expr_stmts_for_value to tell. The use of -1 is
- deprecated, and retained only for backward compatibility.
- MAYBE_LAST is nonzero if this EXPR_STMT might be the last statement
- in expression statement. */
-
-void
-genrtl_expr_stmt_value (tree expr, int want_value, int maybe_last)
-{
- if (expr != NULL_TREE)
- {
- emit_line_note (input_location);
-
- if (stmts_are_full_exprs_p ())
- expand_start_target_temps ();
-
- if (expr != error_mark_node)
- expand_expr_stmt_value (expr, want_value, maybe_last);
-
- if (stmts_are_full_exprs_p ())
- expand_end_target_temps ();
- }
-}
-
-/* Generate the RTL for T, which is a DECL_STMT. */
-
-void
-genrtl_decl_stmt (tree t)
-{
- tree decl;
- emit_line_note (input_location);
- decl = DECL_STMT_DECL (t);
- /* If this is a declaration for an automatic local
- variable, initialize it. Note that we might also see a
- declaration for a namespace-scope object (declared with
- `extern'). We don't have to handle the initialization
- of those objects here; they can only be declarations,
- rather than definitions. */
- if (TREE_CODE (decl) == VAR_DECL
- && !TREE_STATIC (decl)
- && !DECL_EXTERNAL (decl))
- {
- /* Let the back-end know about this variable. */
- if (!anon_aggr_type_p (TREE_TYPE (decl)))
- emit_local_var (decl);
- else
- expand_anon_union_decl (decl, NULL_TREE,
- DECL_ANON_UNION_ELEMS (decl));
- }
- else if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
- make_rtl_for_local_static (decl);
- else if (TREE_CODE (decl) == LABEL_DECL
- && C_DECLARED_LABEL_FLAG (decl))
- declare_nonlocal_label (decl);
- else if (TREE_CODE (decl) == TYPE_DECL)
- force_type_save_exprs (TREE_TYPE (decl));
- else if (lang_expand_decl_stmt)
- (*lang_expand_decl_stmt) (t);
-}
-
-/* Generate the RTL for T, which is an IF_STMT. */
-
-void
-genrtl_if_stmt (tree t)
-{
- tree cond;
- genrtl_do_pushlevel ();
- cond = expand_cond (IF_COND (t));
- emit_line_note (input_location);
- expand_start_cond (cond, 0);
- if (THEN_CLAUSE (t))
- {
- tree nextt = THEN_CLAUSE (t);
-
- if (cond && integer_zerop (cond))
- nextt = expand_unreachable_stmt (nextt, warn_notreached);
- expand_stmt (nextt);
- }
-
- if (ELSE_CLAUSE (t))
- {
- tree nextt = ELSE_CLAUSE (t);
- expand_start_else ();
- if (cond && integer_nonzerop (cond))
- nextt = expand_unreachable_stmt (nextt, warn_notreached);
- expand_stmt (nextt);
- }
- expand_end_cond ();
-}
-
-/* Generate the RTL for T, which is a WHILE_STMT. */
-
-void
-genrtl_while_stmt (tree t)
-{
- tree cond = WHILE_COND (t);
-
- emit_line_note (input_location);
- expand_start_loop (1);
- genrtl_do_pushlevel ();
-
- if (cond && !integer_nonzerop (cond))
- {
- cond = expand_cond (cond);
- emit_line_note (input_location);
- expand_exit_loop_top_cond (0, cond);
- genrtl_do_pushlevel ();
- }
-
- expand_stmt (WHILE_BODY (t));
-
- expand_end_loop ();
-}
-
-/* Generate the RTL for a DO_STMT with condition COND and loop BODY
- body. This is reused for expanding unreachable WHILE_STMTS. */
-
-static void
-genrtl_do_stmt_1 (tree cond, tree body)
-{
- /* Recognize the common special-case of do { ... } while (0) and do
- not emit the loop widgetry in this case. In particular this
- avoids cluttering the rtl with dummy loop notes, which can affect
- alignment of adjacent labels. COND can be NULL due to parse
- errors. */
- if (!cond || integer_zerop (cond))
- {
- expand_start_null_loop ();
- expand_stmt (body);
- expand_end_null_loop ();
- }
- else if (integer_nonzerop (cond))
- {
- emit_line_note (input_location);
- expand_start_loop (1);
-
- expand_stmt (body);
-
- emit_line_note (input_location);
- expand_end_loop ();
- }
- else
- {
- emit_line_note (input_location);
- expand_start_loop_continue_elsewhere (1);
-
- expand_stmt (body);
-
- expand_loop_continue_here ();
- cond = expand_cond (cond);
- emit_line_note (input_location);
- expand_exit_loop_if_false (0, cond);
- expand_end_loop ();
- }
-}
-
-/* Generate the RTL for T, which is a DO_STMT. */
-
-void
-genrtl_do_stmt (tree t)
-{
- genrtl_do_stmt_1 (DO_COND (t), DO_BODY (t));
-}
-
/* Build the node for a return statement and return it. */
tree
@@ -507,74 +268,6 @@ build_return_stmt (tree expr)
return (build_stmt (RETURN_STMT, expr));
}
-/* Generate the RTL for STMT, which is a RETURN_STMT. */
-
-void
-genrtl_return_stmt (tree stmt)
-{
- tree expr;
-
- expr = RETURN_STMT_EXPR (stmt);
-
- emit_line_note (input_location);
- if (!expr)
- expand_null_return ();
- else
- {
- expand_start_target_temps ();
- expand_return (expr);
- expand_end_target_temps ();
- }
-}
-
-/* Generate the RTL for T, which is a FOR_STMT. */
-
-void
-genrtl_for_stmt (tree t)
-{
- tree cond = FOR_COND (t);
- location_t saved_loc;
-
- if (NEW_FOR_SCOPE_P (t))
- genrtl_do_pushlevel ();
-
- expand_stmt (FOR_INIT_STMT (t));
-
- /* Expand the initialization. */
- emit_line_note (input_location);
- if (FOR_EXPR (t))
- expand_start_loop_continue_elsewhere (1);
- else
- expand_start_loop (1);
- genrtl_do_pushlevel ();
-
- /* Save the filename and line number so that we expand the FOR_EXPR
- we can reset them back to the saved values. */
- saved_loc = input_location;
-
- /* Expand the condition. */
- if (cond && !integer_nonzerop (cond))
- {
- cond = expand_cond (cond);
- emit_line_note (input_location);
- expand_exit_loop_top_cond (0, cond);
- genrtl_do_pushlevel ();
- }
-
- /* Expand the body. */
- expand_stmt (FOR_BODY (t));
-
- /* Expand the increment expression. */
- input_location = saved_loc;
- emit_line_note (input_location);
- if (FOR_EXPR (t))
- {
- expand_loop_continue_here ();
- genrtl_expr_stmt (FOR_EXPR (t));
- }
- expand_end_loop ();
-}
-
/* Build a break statement node and return it. */
tree
@@ -583,16 +276,6 @@ build_break_stmt (void)
return (build_stmt (BREAK_STMT));
}
-/* Generate the RTL for a BREAK_STMT. */
-
-void
-genrtl_break_stmt (void)
-{
- emit_line_note (input_location);
- if ( ! expand_exit_something ())
- abort ();
-}
-
/* Build a continue statement node and return it. */
tree
@@ -601,80 +284,6 @@ build_continue_stmt (void)
return (build_stmt (CONTINUE_STMT));
}
-/* Generate the RTL for a CONTINUE_STMT. */
-
-void
-genrtl_continue_stmt (void)
-{
- emit_line_note (input_location);
- if (! expand_continue_loop (0))
- abort ();
-}
-
-/* Generate the RTL for T, which is a SCOPE_STMT. */
-
-void
-genrtl_scope_stmt (tree t)
-{
- tree block = SCOPE_STMT_BLOCK (t);
-
- if (!SCOPE_NO_CLEANUPS_P (t))
- {
- if (SCOPE_BEGIN_P (t))
- expand_start_bindings_and_block (2 * SCOPE_NULLIFIED_P (t), block);
- else if (SCOPE_END_P (t))
- expand_end_bindings (NULL_TREE, !SCOPE_NULLIFIED_P (t), 0);
- }
- else if (!SCOPE_NULLIFIED_P (t))
- {
- rtx note = emit_note (SCOPE_BEGIN_P (t)
- ? NOTE_INSN_BLOCK_BEG : NOTE_INSN_BLOCK_END);
- NOTE_BLOCK (note) = block;
- }
-
- /* If we're at the end of a scope that contains inlined nested
- functions, we have to decide whether or not to write them out. */
- if (block && SCOPE_END_P (t))
- {
- tree fn;
-
- for (fn = BLOCK_VARS (block); fn; fn = TREE_CHAIN (fn))
- {
- if (TREE_CODE (fn) == FUNCTION_DECL
- && DECL_CONTEXT (fn) == current_function_decl
- && DECL_STRUCT_FUNCTION (fn)
- && DECL_STRUCT_FUNCTION (fn)->saved_for_inline
- && !TREE_ASM_WRITTEN (fn)
- && TREE_ADDRESSABLE (fn))
- {
- push_function_context ();
- output_inline_function (fn);
- pop_function_context ();
- }
- }
- }
-}
-
-/* Generate the RTL for T, which is a SWITCH_STMT. */
-
-void
-genrtl_switch_stmt (tree t)
-{
- tree cond;
- genrtl_do_pushlevel ();
-
- cond = expand_cond (SWITCH_COND (t));
- if (cond == error_mark_node)
- /* The code is in error, but we don't want expand_end_case to
- crash. */
- cond = truthvalue_false_node;
-
- emit_line_note (input_location);
- expand_start_case (1, cond, TREE_TYPE (cond), "switch statement");
- expand_stmt (expand_unreachable_stmt (SWITCH_BODY (t), warn_notreached));
- expand_end_case_type (cond, SWITCH_TYPE (t));
-}
-
/* Create a CASE_LABEL tree node and return it. */
tree
@@ -683,378 +292,13 @@ build_case_label (tree low_value, tree high_value, tree label_decl)
return build_stmt (CASE_LABEL, low_value, high_value, label_decl);
}
-
-/* Generate the RTL for a CASE_LABEL. */
-
-void
-genrtl_case_label (tree case_label)
-{
- tree duplicate;
- tree cleanup;
-
- cleanup = last_cleanup_this_contour ();
- if (cleanup)
- {
- static int explained = 0;
- warning ("destructor needed for `%D'", (TREE_PURPOSE (cleanup)));
- warning ("where case label appears here");
- if (!explained)
- {
- warning ("(enclose actions of previous case statements requiring destructors in their own scope.)");
- explained = 1;
- }
- }
-
- add_case_node (CASE_LOW (case_label), CASE_HIGH (case_label),
- CASE_LABEL_DECL (case_label), &duplicate);
-}
-
-/* Generate the RTL for T, which is a COMPOUND_STMT. */
-
-void
-genrtl_compound_stmt (tree t)
-{
-#ifdef ENABLE_CHECKING
- struct nesting *n = current_nesting_level ();
-#endif
-
- expand_stmt (COMPOUND_BODY (t));
-
-#ifdef ENABLE_CHECKING
- /* Make sure that we've pushed and popped the same number of levels. */
- if (!COMPOUND_STMT_NO_SCOPE (t) && n != current_nesting_level ())
- abort ();
-#endif
-}
-
-/* Generate the RTL for an ASM_STMT. */
-
-void
-genrtl_asm_stmt (tree cv_qualifier, tree string, tree output_operands,
- tree input_operands, tree clobbers, int asm_input_p)
-{
- if (cv_qualifier != NULL_TREE
- && cv_qualifier != ridpointers[(int) RID_VOLATILE])
- {
- warning ("%s qualifier ignored on asm",
- IDENTIFIER_POINTER (cv_qualifier));
- cv_qualifier = NULL_TREE;
- }
-
- emit_line_note (input_location);
- if (asm_input_p)
- expand_asm (string, cv_qualifier != NULL_TREE);
- else
- c_expand_asm_operands (string, output_operands, input_operands,
- clobbers, cv_qualifier != NULL_TREE,
- input_location);
-}
-
-/* Generate the RTL for a CLEANUP_STMT. */
-
-void
-genrtl_cleanup_stmt (tree t)
-{
- tree decl = CLEANUP_DECL (t);
- if (!decl || !DECL_P (decl)
- || (DECL_SIZE (decl) && TREE_TYPE (decl) != error_mark_node))
- expand_decl_cleanup_eh (decl, CLEANUP_EXPR (t), CLEANUP_EH_ONLY (t));
-}
-
/* We're about to expand T, a statement. Set up appropriate context
for the substitution. */
void
prep_stmt (tree t)
{
- if (!STMT_LINENO_FOR_FN_P (t))
- input_line = STMT_LINENO (t);
+ if (EXPR_LOCUS (t))
+ input_location = *EXPR_LOCUS (t);
current_stmt_tree ()->stmts_are_full_exprs_p = STMT_IS_FULL_EXPR_P (t);
}
-
-/* Generate the RTL for the statement T, its substatements, and any
- other statements at its nesting level. */
-
-void
-expand_stmt (tree t)
-{
- while (t && t != error_mark_node)
- {
- int saved_stmts_are_full_exprs_p;
-
- /* Set up context appropriately for handling this statement. */
- saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
- prep_stmt (t);
-
- switch (TREE_CODE (t))
- {
- case FILE_STMT:
- input_filename = FILE_STMT_FILENAME (t);
- break;
-
- case RETURN_STMT:
- genrtl_return_stmt (t);
- t = expand_unreachable_stmt (TREE_CHAIN (t), warn_notreached);
- goto process_t;
-
- case EXPR_STMT:
- genrtl_expr_stmt_value (EXPR_STMT_EXPR (t), TREE_ADDRESSABLE (t),
- TREE_CHAIN (t) == NULL
- || (TREE_CODE (TREE_CHAIN (t)) == SCOPE_STMT
- && TREE_CHAIN (TREE_CHAIN (t)) == NULL));
- break;
-
- case DECL_STMT:
- genrtl_decl_stmt (t);
- break;
-
- case FOR_STMT:
- genrtl_for_stmt (t);
- break;
-
- case WHILE_STMT:
- genrtl_while_stmt (t);
- break;
-
- case DO_STMT:
- genrtl_do_stmt (t);
- break;
-
- case IF_STMT:
- genrtl_if_stmt (t);
- break;
-
- case COMPOUND_STMT:
- genrtl_compound_stmt (t);
- break;
-
- case BREAK_STMT:
- genrtl_break_stmt ();
- t = expand_unreachable_stmt (TREE_CHAIN (t), warn_notreached);
- goto process_t;
-
- case CONTINUE_STMT:
- genrtl_continue_stmt ();
- t = expand_unreachable_stmt (TREE_CHAIN (t), warn_notreached);
- goto process_t;
-
- case SWITCH_STMT:
- genrtl_switch_stmt (t);
- break;
-
- case CASE_LABEL:
- genrtl_case_label (t);
- break;
-
- case LABEL_STMT:
- expand_label (LABEL_STMT_LABEL (t));
- break;
-
- case GOTO_STMT:
- /* Emit information for branch prediction. */
- if (!GOTO_FAKE_P (t)
- && TREE_CODE (GOTO_DESTINATION (t)) == LABEL_DECL
- && flag_guess_branch_prob)
- {
- rtx note = emit_note (NOTE_INSN_PREDICTION);
-
- NOTE_PREDICTION (note) = NOTE_PREDICT (PRED_GOTO, NOT_TAKEN);
- }
- genrtl_goto_stmt (GOTO_DESTINATION (t));
- t = expand_unreachable_stmt (TREE_CHAIN (t), warn_notreached);
- goto process_t;
-
- case ASM_STMT:
- genrtl_asm_stmt (ASM_CV_QUAL (t), ASM_STRING (t),
- ASM_OUTPUTS (t), ASM_INPUTS (t),
- ASM_CLOBBERS (t), ASM_INPUT_P (t));
- break;
-
- case SCOPE_STMT:
- genrtl_scope_stmt (t);
- break;
-
- case CLEANUP_STMT:
- genrtl_cleanup_stmt (t);
- break;
-
- default:
- if (lang_expand_stmt)
- (*lang_expand_stmt) (t);
- else
- abort ();
- break;
- }
-
- /* Go on to the next statement in this scope. */
- t = TREE_CHAIN (t);
-
- process_t:
- /* Restore saved state. */
- current_stmt_tree ()->stmts_are_full_exprs_p
- = saved_stmts_are_full_exprs_p;
- }
-}
-
-/* If *TP is a potentially reachable label, return nonzero. */
-
-static tree
-find_reachable_label_1 (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
- void *data ATTRIBUTE_UNUSED)
-{
- switch (TREE_CODE (*tp))
- {
- case LABEL_STMT:
- case CASE_LABEL:
- return *tp;
-
- default:
- break;
- }
- return NULL_TREE;
-}
-
-/* Determine whether expression EXP contains a potentially
- reachable label. */
-static tree
-find_reachable_label (tree exp)
-{
- location_t saved_loc = input_location;
- tree ret = walk_tree_without_duplicates
- (&exp, find_reachable_label_1, NULL);
- input_location = saved_loc;
- return ret;
-}
-
-/* Expand an unreachable if statement, T. This function returns
- true if the IF_STMT contains a potentially reachable code_label. */
-static bool
-expand_unreachable_if_stmt (tree t)
-{
- tree n;
-
- if (find_reachable_label (IF_COND (t)) != NULL_TREE)
- {
- genrtl_if_stmt (t);
- return true;
- }
-
- if (THEN_CLAUSE (t) && ELSE_CLAUSE (t))
- {
- n = expand_unreachable_stmt (THEN_CLAUSE (t), 0);
-
- if (n != NULL_TREE)
- {
- rtx label;
- expand_stmt (n);
- label = gen_label_rtx ();
- emit_jump (label);
- expand_stmt (expand_unreachable_stmt (ELSE_CLAUSE (t), 0));
- emit_label (label);
- return true;
- }
- else
- n = expand_unreachable_stmt (ELSE_CLAUSE (t), 0);
- }
- else if (THEN_CLAUSE (t))
- n = expand_unreachable_stmt (THEN_CLAUSE (t), 0);
- else if (ELSE_CLAUSE (t))
- n = expand_unreachable_stmt (ELSE_CLAUSE (t), 0);
- else
- n = NULL_TREE;
-
- expand_stmt (n);
-
- return n != NULL_TREE;
-}
-
-/* Expand an unreachable statement list. This function skips all
- statements preceding the first potentially reachable label and
- then returns the label (or, in same cases, the statement after
- one containing the label). */
-static tree
-expand_unreachable_stmt (tree t, int warn)
-{
- int saved;
-
- while (t && t != error_mark_node)
- {
- if (warn)
- switch (TREE_CODE (t))
- {
- case BREAK_STMT:
- case CONTINUE_STMT:
- case EXPR_STMT:
- case GOTO_STMT:
- case IF_STMT:
- case RETURN_STMT:
- if (!STMT_LINENO_FOR_FN_P (t))
- input_line = STMT_LINENO (t);
- warning("will never be executed");
- warn = false;
- break;
-
- default:
- break;
- }
-
- switch (TREE_CODE (t))
- {
- case GOTO_STMT:
- case CONTINUE_STMT:
- case BREAK_STMT:
- break;
-
- case FILE_STMT:
- input_filename = FILE_STMT_FILENAME (t);
- break;
-
- case RETURN_STMT:
- if (find_reachable_label (RETURN_STMT_EXPR (t)) != NULL_TREE)
- return t;
- break;
-
- case EXPR_STMT:
- if (find_reachable_label (EXPR_STMT_EXPR (t)) != NULL_TREE)
- return t;
- break;
-
- case IF_STMT:
- if (expand_unreachable_if_stmt (t))
- return TREE_CHAIN (t);
- break;
-
- case WHILE_STMT:
- /* If the start of a while statement is unreachable, there is
- no need to rotate the loop, instead the WHILE_STMT can be
- expanded like a DO_STMT. */
- genrtl_do_stmt_1 (WHILE_COND (t), WHILE_BODY (t));
- return TREE_CHAIN (t);
-
- case COMPOUND_STMT:
- {
- tree n;
- n = expand_unreachable_stmt (COMPOUND_BODY (t), warn);
- if (n != NULL_TREE)
- {
- expand_stmt (n);
- return TREE_CHAIN (t);
- }
- warn = false;
- break;
- }
-
- case SCOPE_STMT:
- saved = stmts_are_full_exprs_p ();
- prep_stmt (t);
- genrtl_scope_stmt (t);
- current_stmt_tree ()->stmts_are_full_exprs_p = saved;
- break;
-
- default:
- return t;
- }
- t = TREE_CHAIN (t);
- }
- return NULL_TREE;
-}
diff --git a/gcc/c-tree.h b/gcc/c-tree.h
index 01f86e999f2..da41c3a5c7a 100644
--- a/gcc/c-tree.h
+++ b/gcc/c-tree.h
@@ -29,6 +29,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define C_SIZEOF_STRUCT_LANG_IDENTIFIER \
(sizeof (struct c_common_identifier) + 3 * sizeof (void *))
+/* For gc purposes, return the most likely link for the longest chain. */
+#define C_LANG_TREE_NODE_CHAIN_NEXT(T) \
+ ((union lang_tree_node *) \
+ (TREE_CODE (T) == INTEGER_TYPE ? TYPE_NEXT_VARIANT (T) \
+ : TREE_CODE (T) == COMPOUND_EXPR ? TREE_OPERAND (T, 1) \
+ : TREE_CHAIN (T)))
+
/* Language-specific declaration information. */
struct lang_decl GTY(())
@@ -58,10 +65,13 @@ struct lang_decl GTY(())
and C_RID_YYCODE is the token number wanted by Yacc. */
#define C_IS_RESERVED_WORD(ID) TREE_LANG_FLAG_0 (ID)
-/* In a RECORD_TYPE, a sorted array of the fields of the type. */
struct lang_type GTY(())
{
+ /* In a RECORD_TYPE, a sorted array of the fields of the type. */
struct sorted_fields_type * GTY ((reorder ("resort_sorted_fields"))) s;
+ /* In an ENUMERAL_TYPE, the min and max values. */
+ tree enum_min;
+ tree enum_max;
};
/* Record whether a type or decl was written with nonconstant size.
@@ -182,7 +192,7 @@ extern tree start_struct (enum tree_code, tree);
extern void store_parm_decls (void);
extern tree xref_tag (enum tree_code, tree);
extern tree c_begin_compound_stmt (void);
-extern void c_expand_decl_stmt (tree);
+extern int c_expand_decl (tree);
extern void c_static_assembler_name (tree);
extern tree make_pointer_declarator (tree, tree);
@@ -190,8 +200,8 @@ extern tree make_pointer_declarator (tree, tree);
extern int c_disregard_inline_limits (tree);
extern int c_cannot_inline_tree_fn (tree *);
extern bool c_objc_common_init (void);
+extern bool c_missing_noreturn_ok_p (tree);
extern tree c_objc_common_truthvalue_conversion (tree expr);
-extern int c_missing_noreturn_ok_p (tree);
extern void c_objc_common_finish_file (void);
extern int defer_fn (tree);
extern bool c_warn_unused_global_decl (tree);
@@ -248,6 +258,7 @@ extern void c_finish_case (void);
extern tree build_asm_expr (tree, tree, tree, tree, bool);
extern tree build_asm_stmt (tree, tree);
extern tree c_convert_parm_for_inlining (tree, tree, tree, int);
+extern int c_types_compatible_p (tree, tree);
/* Set to 0 at beginning of a function definition, set to 1 if
a return statement that specifies a return value is seen. */
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index 2170222d769..6305cc4fb0a 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -592,10 +592,8 @@ comptypes (tree type1, tree type2, int flags)
break;
case VECTOR_TYPE:
- /* The target might allow certain vector types to be compatible. */
- val = targetm.vector_opaque_p (t1)
- || targetm.vector_opaque_p (t2)
- || TYPE_MODE (t1) == TYPE_MODE (t2);
+ val = TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2)
+ && comptypes (TREE_TYPE (t1), TREE_TYPE (t2), 0);
break;
default:
@@ -642,7 +640,7 @@ same_translation_unit_p (tree t1, tree t2)
{
case 'd': t1 = DECL_CONTEXT (t1); break;
case 't': t1 = TYPE_CONTEXT (t1); break;
- case 'b': t1 = BLOCK_SUPERCONTEXT (t1); break;
+ case 'x': t1 = BLOCK_SUPERCONTEXT (t1); break; /* assume block */
default: abort ();
}
@@ -651,7 +649,7 @@ same_translation_unit_p (tree t1, tree t2)
{
case 'd': t2 = DECL_CONTEXT (t2); break;
case 't': t2 = TYPE_CONTEXT (t2); break;
- case 'b': t2 = BLOCK_SUPERCONTEXT (t2); break;
+ case 'x': t2 = BLOCK_SUPERCONTEXT (t2); break; /* assume block */
default: abort ();
}
@@ -689,7 +687,9 @@ tagged_types_tu_compatible_p (tree t1, tree t2, int flags)
/* We have to verify that the tags of the types are the same. This
is harder than it looks because this may be a typedef, so we have
to go look at the original type. It may even be a typedef of a
- typedef... */
+ typedef...
+ In the case of compiler-created builtin structs the TYPE_DECL
+ may be a dummy, with no DECL_ORIGINAL_TYPE. Don't fault. */
while (TYPE_NAME (t1)
&& TREE_CODE (TYPE_NAME (t1)) == TYPE_DECL
&& DECL_ORIGINAL_TYPE (TYPE_NAME (t1)))
@@ -1145,7 +1145,6 @@ default_function_array_conversion (tree exp)
adr = build1 (ADDR_EXPR, ptrtype, exp);
if (!c_mark_addressable (exp))
return error_mark_node;
- TREE_CONSTANT (adr) = staticp (exp);
TREE_SIDE_EFFECTS (adr) = 0; /* Default would be, same as EXP. */
return adr;
}
@@ -1491,8 +1490,7 @@ build_array_ref (tree array, tree index)
|| TREE_TYPE (index) == error_mark_node)
return error_mark_node;
- if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE
- && TREE_CODE (array) != INDIRECT_REF)
+ if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
{
tree rval, type;
@@ -1662,6 +1660,7 @@ build_external_ref (tree id, int fun)
{
ref = DECL_INITIAL (ref);
TREE_CONSTANT (ref) = 1;
+ TREE_INVARIANT (ref) = 1;
}
else if (current_function_decl != 0
&& !DECL_FILE_SCOPE_P (current_function_decl)
@@ -2090,14 +2089,12 @@ parser_build_binary_op (enum tree_code code, tree arg1, tree arg2)
C_SET_EXP_ORIGINAL_CODE (result, code);
else
{
- int flag = TREE_CONSTANT (result);
/* We used to use NOP_EXPR rather than NON_LVALUE_EXPR
so that convert_for_assignment wouldn't strip it.
That way, we got warnings for things like p = (1 - 1).
But it turns out we should not get those warnings. */
result = build1 (NON_LVALUE_EXPR, TREE_TYPE (result), result);
C_SET_EXP_ORIGINAL_CODE (result, code);
- TREE_CONSTANT (result) = flag;
}
return result;
@@ -2129,7 +2126,6 @@ c_tree_expr_nonnegative_p (tree t)
static tree
pointer_diff (tree op0, tree op1)
{
- tree result, folded;
tree restype = ptrdiff_type_node;
tree target_type = TREE_TYPE (TREE_TYPE (op0));
@@ -2193,13 +2189,7 @@ pointer_diff (tree op0, tree op1)
op1 = c_size_in_bytes (target_type);
/* Divide by the size, in easiest possible way. */
-
- result = build (EXACT_DIV_EXPR, restype, op0, convert (restype, op1));
-
- folded = fold (result);
- if (folded == result)
- TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1);
- return folded;
+ return fold (build (EXACT_DIV_EXPR, restype, op0, convert (restype, op1)));
}
/* Construct and perhaps optimize a tree representation
@@ -2422,7 +2412,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
TREE_SIDE_EFFECTS (val) = 1;
val = convert (result_type, val);
if (TREE_CODE (val) != code)
- TREE_NO_UNUSED_WARNING (val) = 1;
+ TREE_NO_WARNING (val) = 1;
return val;
}
@@ -2494,12 +2484,6 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
else
addr = build1 (code, argtype, arg);
- /* Address of a static or external variable or
- file-scope function counts as a constant. */
- if (staticp (arg)
- && ! (TREE_CODE (arg) == FUNCTION_DECL
- && !DECL_FILE_SCOPE_P (arg)))
- TREE_CONSTANT (addr) = 1;
return addr;
}
@@ -2935,6 +2919,7 @@ build_c_cast (tree type, tree expr)
build_tree_list (field, value)),
0);
TREE_CONSTANT (t) = TREE_CONSTANT (value);
+ TREE_INVARIANT (t) = TREE_INVARIANT (value);
return t;
}
error ("cast to union type from type not present in union");
@@ -3292,7 +3277,7 @@ convert_for_assignment (tree type, tree rhs, const char *errtype,
}
/* Some types can interconvert without explicit casts. */
else if (codel == VECTOR_TYPE
- && comptypes (type, TREE_TYPE (rhs), COMPARE_STRICT) == 1)
+ && vector_types_convertible_p (type, TREE_TYPE (rhs)))
return convert (type, rhs);
/* Arithmetic types all interconvert, and enum is treated like int. */
else if ((codel == INTEGER_TYPE || codel == REAL_TYPE
@@ -3937,11 +3922,11 @@ digest_init (tree type, tree init, int require_constant)
vector constructor is not constant (e.g. {1,2,3,foo()}) then punt
below and handle as a constructor. */
if (code == VECTOR_TYPE
- && comptypes (TREE_TYPE (inside_init), type, COMPARE_STRICT)
+ && vector_types_convertible_p (TREE_TYPE (inside_init), type)
&& TREE_CONSTANT (inside_init))
{
if (TREE_CODE (inside_init) == VECTOR_CST
- && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
+ && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
TYPE_MAIN_VARIANT (type),
COMPARE_STRICT))
return inside_init;
@@ -4042,7 +4027,8 @@ digest_init (tree type, tree init, int require_constant)
/* Handle scalar types, including conversions. */
if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE
- || code == ENUMERAL_TYPE || code == BOOLEAN_TYPE || code == COMPLEX_TYPE)
+ || code == ENUMERAL_TYPE || code == BOOLEAN_TYPE || code == COMPLEX_TYPE
+ || code == VECTOR_TYPE)
{
/* Note that convert_for_assignment calls default_conversion
for arrays and functions. We must not call it in the
@@ -4759,7 +4745,7 @@ pop_init_level (int implicit)
constructor = build_constructor (constructor_type,
nreverse (constructor_elements));
if (constructor_constant)
- TREE_CONSTANT (constructor) = 1;
+ TREE_CONSTANT (constructor) = TREE_INVARIANT (constructor) = 1;
if (constructor_constant && constructor_simple)
TREE_STATIC (constructor) = 1;
}
@@ -6053,8 +6039,8 @@ process_init_element (tree value)
tree
build_asm_stmt (tree cv_qualifier, tree args)
{
- if (!TREE_OPERAND (args, 0))
- TREE_OPERAND (args, 0) = cv_qualifier;
+ if (!ASM_VOLATILE_P (args) && cv_qualifier)
+ ASM_VOLATILE_P (args) = 1;
return add_stmt (args);
}
@@ -6069,36 +6055,42 @@ build_asm_expr (tree string, tree outputs, tree inputs, tree clobbers,
{
tree tail;
tree args;
+ int i;
+ const char *constraint;
+ bool allows_mem, allows_reg, is_inout;
+ int ninputs;
+ int noutputs;
+
+ ninputs = list_length (inputs);
+ noutputs = list_length (outputs);
- /* We can remove output conversions that change the type,
- but not the mode. */
- for (tail = outputs; tail; tail = TREE_CHAIN (tail))
+ /* Remove output conversions that change the type but not the mode. */
+ for (i = 0, tail = outputs; tail; ++i, tail = TREE_CHAIN (tail))
{
tree output = TREE_VALUE (tail);
-
STRIP_NOPS (output);
TREE_VALUE (tail) = output;
+ lvalue_or_else (output, "invalid lvalue in asm statement");
- /* Allow conversions as LHS here. build_modify_expr as called below
- will do the right thing with them. */
- while (TREE_CODE (output) == NOP_EXPR
- || TREE_CODE (output) == CONVERT_EXPR
- || TREE_CODE (output) == FLOAT_EXPR
- || TREE_CODE (output) == FIX_TRUNC_EXPR
- || TREE_CODE (output) == FIX_FLOOR_EXPR
- || TREE_CODE (output) == FIX_ROUND_EXPR
- || TREE_CODE (output) == FIX_CEIL_EXPR)
- output = TREE_OPERAND (output, 0);
+ constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail)));
- lvalue_or_else (TREE_VALUE (tail), "invalid lvalue in asm statement");
- }
+ if (!parse_output_constraint (&constraint, i, ninputs, noutputs,
+ &allows_mem, &allows_reg, &is_inout))
+ {
+ /* By marking this operand as erroneous, we will not try
+ to process this operand again in expand_asm_operands. */
+ TREE_VALUE (tail) = error_mark_node;
+ continue;
+ }
- /* Remove output conversions that change the type but not the mode. */
- for (tail = outputs; tail; tail = TREE_CHAIN (tail))
- {
- tree output = TREE_VALUE (tail);
- STRIP_NOPS (output);
- TREE_VALUE (tail) = output;
+ /* If the operand is a DECL that is going to end up in
+ memory, assume it is addressable. This is a bit more
+ conservative than it would ideally be; the exact test is
+ buried deep in expand_asm_operands and depends on the
+ DECL_RTL for the OPERAND -- which we don't have at this
+ point. */
+ if (!allows_reg && DECL_P (output))
+ c_mark_addressable (output);
}
/* Perform default conversions on array and function inputs.
@@ -6107,12 +6099,12 @@ build_asm_expr (tree string, tree outputs, tree inputs, tree clobbers,
for (tail = inputs; tail; tail = TREE_CHAIN (tail))
TREE_VALUE (tail) = default_function_array_conversion (TREE_VALUE (tail));
- args = build_stmt (ASM_STMT, 0, string, outputs, inputs, clobbers);
+ args = build_stmt (ASM_STMT, string, outputs, inputs, clobbers);
/* Simple asm statements are treated as volatile. */
if (simple)
{
- TREE_OPERAND (args, 0) = ridpointers[RID_VOLATILE];
+ ASM_VOLATILE_P (args) = 1;
ASM_INPUT_P (args) = 1;
}
return args;
@@ -6376,6 +6368,9 @@ c_finish_case (void)
{
struct c_switch *cs = switch_stack;
+ /* Emit warnings as needed. */
+ c_do_switch_warnings (cs->cases, cs->switch_stmt);
+
/* Rechain the next statements to the SWITCH_STMT. */
last_tree = cs->switch_stmt;
@@ -7104,16 +7099,14 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
{
tree result = build (resultcode, build_type, op0, op1);
- tree folded;
/* Treat expressions in initializers specially as they can't trap. */
- folded = initializer_stack ? fold_initializer (result)
+ result = initializer_stack ? fold_initializer (result)
: fold (result);
- if (folded == result)
- TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1);
+
if (final_type != 0)
- return convert (final_type, folded);
- return folded;
+ result = convert (final_type, result);
+ return result;
}
}
diff --git a/gcc/c.opt b/gcc/c.opt
index e8627700b65..bafe6a14d8b 100644
--- a/gcc/c.opt
+++ b/gcc/c.opt
@@ -103,7 +103,7 @@ Print the name of header files as they are used
I
C ObjC C++ ObjC++ Joined Separate
--I <dir> Add <dir> to the end of the main include path. -I- gives more include path control; see info documentation
+-I <dir> Add <dir> to the end of the main include path
M
C ObjC C++ ObjC++
@@ -469,10 +469,6 @@ fdollars-in-identifiers
C ObjC C++ ObjC++
Permit '$' as an identifier character
-fdump-
-C ObjC C++ ObjC++ Joined RejectNegative
--fdump-<type> Dump various compiler internals to a file
-
felide-constructors
C++ ObjC++
@@ -720,6 +716,10 @@ isystem
C ObjC C++ ObjC++ Joined Separate
-isystem <dir> Add <dir> to the start of the system include path
+iquote
+C ObjC C++ ObjC++ Joined Separate
+-iquote <dir> Add <dir> to the end of the quote include path
+
iwithprefix
C ObjC C++ ObjC++ Joined Separate
-iwithprefix <dir> Add <dir> to the end of the system include path
diff --git a/gcc/calls.c b/gcc/calls.c
index 44d6360d9bf..35021ea137f 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -120,7 +120,7 @@ int stack_arg_under_construction;
static int calls_function (tree, int);
static int calls_function_1 (tree, int);
-static void emit_call_1 (rtx, tree, tree, HOST_WIDE_INT, HOST_WIDE_INT,
+static void emit_call_1 (rtx, tree, tree, tree, HOST_WIDE_INT, HOST_WIDE_INT,
HOST_WIDE_INT, rtx, rtx, int, rtx, int,
CUMULATIVE_ARGS *);
static void precompute_register_parameters (int, struct arg_data *, int *);
@@ -134,7 +134,7 @@ static void initialize_argument_information (int, struct arg_data *,
struct args_size *, int, tree,
tree, CUMULATIVE_ARGS *, int,
rtx *, int *, int *, int *,
- bool);
+ bool *, bool);
static void compute_argument_addresses (struct arg_data *, rtx, int);
static rtx rtx_for_function_call (tree, tree);
static void load_register_parameters (struct arg_data *, int, rtx *, int,
@@ -142,7 +142,6 @@ static void load_register_parameters (struct arg_data *, int, rtx *, int,
static rtx emit_library_call_value_1 (int, rtx, rtx, enum libcall_type,
enum machine_mode, int, va_list);
static int special_function_p (tree, int);
-static rtx try_to_integrate (tree, tree, rtx, int, tree, rtx);
static int check_sibcall_argument_overlap_1 (rtx);
static int check_sibcall_argument_overlap (rtx, struct arg_data *, int);
@@ -260,8 +259,9 @@ calls_function_1 (tree exp, int which)
break;
}
- /* Only expressions and blocks can contain calls. */
- if (! IS_EXPR_CODE_CLASS (class) && class != 'b')
+ /* Only expressions and blocks can contain calls.
+ Blocks were handled above. */
+ if (! IS_EXPR_CODE_CLASS (class))
return 0;
for (i = 0; i < length; i++)
@@ -280,17 +280,11 @@ calls_function_1 (tree exp, int which)
CALL_INSN_FUNCTION_USAGE information. */
rtx
-prepare_call_address (rtx funexp, tree fndecl, rtx *call_fusage,
- int reg_parm_seen, int sibcallp)
+prepare_call_address (rtx funexp, rtx static_chain_value,
+ rtx *call_fusage, int reg_parm_seen, int sibcallp)
{
- rtx static_chain_value = 0;
-
funexp = protect_from_queue (funexp, 0);
- if (fndecl != 0)
- /* Get possible static chain value for nested function in C. */
- static_chain_value = lookup_static_chain (fndecl);
-
/* Make a valid memory address and copy constants through pseudo-regs,
but not for a constant address if -fno-function-cse. */
if (GET_CODE (funexp) != SYMBOL_REF)
@@ -362,7 +356,8 @@ prepare_call_address (rtx funexp, tree fndecl, rtx *call_fusage,
denote registers used by the called function. */
static void
-emit_call_1 (rtx funexp, tree fndecl ATTRIBUTE_UNUSED, tree funtype ATTRIBUTE_UNUSED,
+emit_call_1 (rtx funexp, tree fntree, tree fndecl ATTRIBUTE_UNUSED,
+ tree funtype ATTRIBUTE_UNUSED,
HOST_WIDE_INT stack_size ATTRIBUTE_UNUSED,
HOST_WIDE_INT rounded_stack_size,
HOST_WIDE_INT struct_value_size ATTRIBUTE_UNUSED,
@@ -506,7 +501,16 @@ emit_call_1 (rtx funexp, tree fndecl ATTRIBUTE_UNUSED, tree funtype ATTRIBUTE_UN
REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, const0_rtx,
REG_NOTES (call_insn));
else
- note_eh_region_may_contain_throw ();
+ {
+ int rn = lookup_stmt_eh_region (fntree);
+
+ /* If rn < 0, then either (1) tree-ssa not used or (2) doesn't
+ throw, which we already took care of. */
+ if (rn > 0)
+ REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (rn),
+ REG_NOTES (call_insn));
+ note_current_region_may_contain_throw ();
+ }
if (ecf_flags & ECF_NORETURN)
REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_NORETURN, const0_rtx,
@@ -590,8 +594,7 @@ emit_call_1 (rtx funexp, tree fndecl ATTRIBUTE_UNUSED, tree funtype ATTRIBUTE_UN
static int
special_function_p (tree fndecl, int flags)
{
- if (! (flags & ECF_MALLOC)
- && fndecl && DECL_NAME (fndecl)
+ if (fndecl && DECL_NAME (fndecl)
&& IDENTIFIER_LENGTH (DECL_NAME (fndecl)) <= 17
/* Exclude functions not at the file scope, or not `extern',
since they are not the magic functions we would otherwise
@@ -653,21 +656,8 @@ special_function_p (tree fndecl, int flags)
else if (tname[0] == 'l' && tname[1] == 'o'
&& ! strcmp (tname, "longjmp"))
flags |= ECF_LONGJMP;
-
- else if ((tname[0] == 'f' && tname[1] == 'o'
- && ! strcmp (tname, "fork"))
- /* Linux specific: __clone. check NAME to insist on the
- leading underscores, to avoid polluting the ISO / POSIX
- namespace. */
- || (name[0] == '_' && name[1] == '_'
- && ! strcmp (tname, "clone"))
- || (tname[0] == 'e' && tname[1] == 'x' && tname[2] == 'e'
- && tname[3] == 'c' && (tname[4] == 'l' || tname[4] == 'v')
- && (tname[5] == '\0'
- || ((tname[5] == 'p' || tname[5] == 'e')
- && tname[6] == '\0'))))
- flags |= ECF_FORK_OR_EXEC;
}
+
return flags;
}
@@ -727,6 +717,8 @@ flags_from_decl_or_type (tree exp)
if (TREE_READONLY (exp) && ! TREE_THIS_VOLATILE (exp))
flags |= ECF_LIBCALL_BLOCK | ECF_CONST;
+
+ flags = special_function_p (exp, flags);
}
else if (TYPE_P (exp) && TYPE_READONLY (exp) && ! TREE_THIS_VOLATILE (exp))
flags |= ECF_CONST;
@@ -1025,6 +1017,9 @@ store_unaligned_arguments_into_pseudos (struct arg_data *args, int num_actuals)
OLD_PENDING_ADJ, MUST_PREALLOCATE and FLAGS are pointers to integer
flags which may may be modified by this routine.
+ MAY_TAILCALL is cleared if we encounter an invisible pass-by-reference
+ that requires allocation of stack space.
+
CALL_FROM_THUNK_P is true if this call is the jump from a thunk to
the thunked-to function. */
@@ -1038,7 +1033,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
int reg_parm_stack_space,
rtx *old_stack_level, int *old_pending_adj,
int *must_preallocate, int *ecf_flags,
- bool call_from_thunk_p)
+ bool *may_tailcall, bool call_from_thunk_p)
{
/* 1 if scanning parms front to back, -1 if scanning back to front. */
int inc;
@@ -1151,6 +1146,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
build_pointer_type (type),
args[i].tree_value);
type = build_pointer_type (type);
+ *may_tailcall = false;
}
else
{
@@ -1190,6 +1186,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
build_pointer_type (type),
make_tree (type, copy));
type = build_pointer_type (type);
+ *may_tailcall = false;
}
}
@@ -1407,7 +1404,7 @@ precompute_arguments (int flags, int num_actuals, struct arg_data *args)
args[i].value
= convert_modes (args[i].mode, mode,
args[i].value, args[i].unsignedp);
-#ifdef PROMOTE_FOR_CALL_ONLY
+#if defined(PROMOTE_FUNCTION_MODE) && !defined(PROMOTE_MODE)
/* CSE will replace this only if it contains args[i].value
pseudo, so convert it down to the declared mode using
a SUBREG. */
@@ -1718,120 +1715,6 @@ load_register_parameters (struct arg_data *args, int num_actuals,
}
}
-/* Try to integrate function. See expand_inline_function for documentation
- about the parameters. */
-
-static rtx
-try_to_integrate (tree fndecl, tree actparms, rtx target, int ignore,
- tree type, rtx structure_value_addr)
-{
- rtx temp;
- rtx before_call;
- int i;
- rtx old_stack_level = 0;
- int reg_parm_stack_space = 0;
-
-#ifdef REG_PARM_STACK_SPACE
- reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
-#endif
-
- before_call = get_last_insn ();
-
- timevar_push (TV_INTEGRATION);
-
- temp = expand_inline_function (fndecl, actparms, target,
- ignore, type,
- structure_value_addr);
-
- timevar_pop (TV_INTEGRATION);
-
- /* If inlining succeeded, return. */
- if (temp != (rtx) (size_t) - 1)
- {
- if (ACCUMULATE_OUTGOING_ARGS)
- {
- /* If the outgoing argument list must be preserved, push
- the stack before executing the inlined function if it
- makes any calls. */
-
- i = reg_parm_stack_space;
- if (i > highest_outgoing_arg_in_use)
- i = highest_outgoing_arg_in_use;
- while (--i >= 0 && stack_usage_map[i] == 0)
- ;
-
- if (stack_arg_under_construction || i >= 0)
- {
- rtx first_insn
- = before_call ? NEXT_INSN (before_call) : get_insns ();
- rtx insn = NULL_RTX, seq;
-
- /* Look for a call in the inline function code.
- If DECL_STRUCT_FUNCTION (fndecl)->outgoing_args_size is
- nonzero then there is a call and it is not necessary
- to scan the insns. */
-
- if (DECL_STRUCT_FUNCTION (fndecl)->outgoing_args_size == 0)
- for (insn = first_insn; insn; insn = NEXT_INSN (insn))
- if (GET_CODE (insn) == CALL_INSN)
- break;
-
- if (insn)
- {
- /* Reserve enough stack space so that the largest
- argument list of any function call in the inline
- function does not overlap the argument list being
- evaluated. This is usually an overestimate because
- allocate_dynamic_stack_space reserves space for an
- outgoing argument list in addition to the requested
- space, but there is no way to ask for stack space such
- that an argument list of a certain length can be
- safely constructed.
-
- Add the stack space reserved for register arguments, if
- any, in the inline function. What is really needed is the
- largest value of reg_parm_stack_space in the inline
- function, but that is not available. Using the current
- value of reg_parm_stack_space is wrong, but gives
- correct results on all supported machines. */
-
- int adjust =
- (DECL_STRUCT_FUNCTION (fndecl)->outgoing_args_size
- + reg_parm_stack_space);
-
- start_sequence ();
- emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
- allocate_dynamic_stack_space (GEN_INT (adjust),
- NULL_RTX, BITS_PER_UNIT);
- seq = get_insns ();
- end_sequence ();
- emit_insn_before (seq, first_insn);
- emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
- }
- }
- }
-
- /* If the result is equivalent to TARGET, return TARGET to simplify
- checks in store_expr. They can be equivalent but not equal in the
- case of a function that returns BLKmode. */
- if (temp != target && rtx_equal_p (temp, target))
- return target;
- return temp;
- }
-
- /* If inlining failed, mark FNDECL as needing to be compiled
- separately after all. If function was declared inline,
- give a warning. */
- if (DECL_INLINE (fndecl) && warn_inline && !flag_no_inline
- && optimize > 0 && !TREE_ADDRESSABLE (fndecl))
- {
- warning ("%Jinlining failed in call to '%F'", fndecl, fndecl);
- warning ("called from here");
- }
- lang_hooks.mark_addressable (fndecl);
- return (rtx) (size_t) - 1;
-}
-
/* We need to pop PENDING_STACK_ADJUST bytes. But, if the arguments
wouldn't fill up an even multiple of PREFERRED_UNIT_STACK_BOUNDARY
bytes, then we would need to push some additional bytes to pad the
@@ -2042,6 +1925,69 @@ shift_returned_value (tree type, rtx *value)
return false;
}
+/* Remove all REG_EQUIV notes found in the insn chain. */
+
+static void
+purge_reg_equiv_notes (void)
+{
+ rtx insn;
+
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ {
+ while (1)
+ {
+ rtx note = find_reg_note (insn, REG_EQUIV, 0);
+ if (note)
+ {
+ /* Remove the note and keep looking at the notes for
+ this insn. */
+ remove_note (insn, note);
+ continue;
+ }
+ break;
+ }
+ }
+}
+
+/* Clear RTX_UNCHANGING_P flag of incoming argument MEMs. */
+
+static void
+purge_mem_unchanging_flag (rtx x)
+{
+ RTX_CODE code;
+ int i, j;
+ const char *fmt;
+
+ if (x == NULL_RTX)
+ return;
+
+ code = GET_CODE (x);
+
+ if (code == MEM)
+ {
+ if (RTX_UNCHANGING_P (x)
+ && (XEXP (x, 0) == current_function_internal_arg_pointer
+ || (GET_CODE (XEXP (x, 0)) == PLUS
+ && XEXP (XEXP (x, 0), 0) ==
+ current_function_internal_arg_pointer
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)))
+ RTX_UNCHANGING_P (x) = 0;
+ return;
+ }
+
+ /* Scan all subexpressions. */
+ fmt = GET_RTX_FORMAT (code);
+ for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
+ {
+ if (*fmt == 'e')
+ purge_mem_unchanging_flag (XEXP (x, i));
+ else if (*fmt == 'E')
+ for (j = 0; j < XVECLEN (x, i); j++)
+ purge_mem_unchanging_flag (XVECEXP (x, i, j));
+ }
+}
+
+
/* Generate all the code for a function call
and return an rtx for its value.
Store the value in TARGET (specified as an rtx) if convenient.
@@ -2058,11 +2004,9 @@ expand_call (tree exp, rtx target, int ignore)
tree actparms = TREE_OPERAND (exp, 1);
/* RTX for the function to be called. */
rtx funexp;
- /* Sequence of insns to perform a tail recursive "call". */
- rtx tail_recursion_insns = NULL_RTX;
/* Sequence of insns to perform a normal "call". */
rtx normal_call_insns = NULL_RTX;
- /* Sequence of insns to perform a tail recursive "call". */
+ /* Sequence of insns to perform a tail "call". */
rtx tail_call_insns = NULL_RTX;
/* Data type of the function. */
tree funtype;
@@ -2072,9 +2016,7 @@ expand_call (tree exp, rtx target, int ignore)
tree fndecl = 0;
/* The type of the function being called. */
tree fntype;
- rtx insn;
- int try_tail_call = 1;
- int try_tail_recursion = 1;
+ bool try_tail_call = CALL_EXPR_TAILCALL (exp);
int pass;
/* Register in which non-BLKmode value will be returned,
@@ -2135,8 +2077,6 @@ expand_call (tree exp, rtx target, int ignore)
/* Mask of ECF_ flags. */
int flags = 0;
- /* Nonzero if this is a call to an inline function. */
- int is_integrable = 0;
#ifdef REG_PARM_STACK_SPACE
/* Define the boundary of the register parm stack space that needs to be
saved, if any. */
@@ -2145,7 +2085,6 @@ expand_call (tree exp, rtx target, int ignore)
#endif
int initial_highest_arg_in_use = highest_outgoing_arg_in_use;
- rtx temp_target = 0;
char *initial_stack_usage_map = stack_usage_map;
int old_stack_allocated;
@@ -2169,58 +2108,23 @@ expand_call (tree exp, rtx target, int ignore)
HOST_WIDE_INT preferred_stack_boundary;
/* The alignment of the stack, in bytes. */
HOST_WIDE_INT preferred_unit_stack_boundary;
-
+ /* The static chain value to use for this call. */
+ rtx static_chain_value;
/* See if this is "nothrow" function call. */
if (TREE_NOTHROW (exp))
flags |= ECF_NOTHROW;
- /* See if we can find a DECL-node for the actual function.
- As a result, decide whether this is a call to an integrable function. */
-
+ /* See if we can find a DECL-node for the actual function, and get the
+ function attributes (flags) from the function decl or type node. */
fndecl = get_callee_fndecl (exp);
if (fndecl)
{
fntype = TREE_TYPE (fndecl);
- if (!flag_no_inline
- && fndecl != current_function_decl
- && DECL_INLINE (fndecl)
- && DECL_STRUCT_FUNCTION (fndecl)
- && DECL_STRUCT_FUNCTION (fndecl)->inlinable)
- is_integrable = 1;
- else if (! TREE_ADDRESSABLE (fndecl))
- {
- /* In case this function later becomes inlinable,
- record that there was already a non-inline call to it.
-
- Use abstraction instead of setting TREE_ADDRESSABLE
- directly. */
- if (DECL_INLINE (fndecl) && warn_inline && !flag_no_inline
- && optimize > 0)
- {
- warning ("%Jcan't inline call to '%F'", fndecl, fndecl);
- warning ("called from here");
- }
- lang_hooks.mark_addressable (fndecl);
- }
-
- if (ignore
- && lookup_attribute ("warn_unused_result",
- TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
- warning ("ignoring return value of `%D', "
- "declared with attribute warn_unused_result", fndecl);
-
flags |= flags_from_decl_or_type (fndecl);
}
-
- /* If we don't have specific function to call, see if we have a
- attributes set in the type. */
else
{
fntype = TREE_TYPE (TREE_TYPE (p));
- if (ignore
- && lookup_attribute ("warn_unused_result", TYPE_ATTRIBUTES (fntype)))
- warning ("ignoring return value of function "
- "declared with attribute warn_unused_result");
flags |= flags_from_decl_or_type (fntype);
}
@@ -2277,15 +2181,6 @@ expand_call (tree exp, rtx target, int ignore)
#ifdef PCC_STATIC_STRUCT_RETURN
{
pcc_struct_value = 1;
- /* Easier than making that case work right. */
- if (is_integrable)
- {
- /* In case this is a static function, note that it has been
- used. */
- if (! TREE_ADDRESSABLE (fndecl))
- lang_hooks.mark_addressable (fndecl);
- is_integrable = 0;
- }
}
#else /* not PCC_STATIC_STRUCT_RETURN */
{
@@ -2318,17 +2213,6 @@ expand_call (tree exp, rtx target, int ignore)
#endif /* not PCC_STATIC_STRUCT_RETURN */
}
- /* If called function is inline, try to integrate it. */
-
- if (is_integrable)
- {
- rtx temp = try_to_integrate (fndecl, actparms, target,
- ignore, TREE_TYPE (exp),
- structure_value_addr);
- if (temp != (rtx) (size_t) - 1)
- return temp;
- }
-
/* Figure out the amount to which the stack should be aligned. */
preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
if (fndecl)
@@ -2354,10 +2238,6 @@ expand_call (tree exp, rtx target, int ignore)
else
type_arg_types = TYPE_ARG_TYPES (funtype);
- /* See if this is a call to a function that can return more than once
- or a call to longjmp or malloc. */
- flags |= special_function_p (fndecl, flags);
-
if (flags & ECF_MAY_BE_ALLOCA)
current_function_calls_alloca = 1;
@@ -2440,7 +2320,7 @@ expand_call (tree exp, rtx target, int ignore)
&args_so_far, reg_parm_stack_space,
&old_stack_level, &old_pending_adj,
&must_preallocate, &flags,
- CALL_FROM_THUNK_P (exp));
+ &try_tail_call, CALL_FROM_THUNK_P (exp));
if (args_size.var)
{
@@ -2489,14 +2369,9 @@ expand_call (tree exp, rtx target, int ignore)
|| !rtx_equal_function_value_matters
|| current_nesting_level () == 0
|| any_pending_cleanups ()
- || args_size.var)
- try_tail_call = try_tail_recursion = 0;
-
- /* Tail recursion fails, when we are not dealing with recursive calls. */
- if (!try_tail_recursion
- || TREE_CODE (addr) != ADDR_EXPR
- || TREE_OPERAND (addr, 0) != current_function_decl)
- try_tail_recursion = 0;
+ || args_size.var
+ || lookup_stmt_eh_region (exp) >= 0)
+ try_tail_call = 0;
/* Rest of purposes for tail call optimizations to fail. */
if (
@@ -2534,7 +2409,7 @@ expand_call (tree exp, rtx target, int ignore)
|| !lang_hooks.decls.ok_for_sibcall (fndecl))
try_tail_call = 0;
- if (try_tail_call || try_tail_recursion)
+ if (try_tail_call)
{
int end, inc;
actparms = NULL_TREE;
@@ -2569,11 +2444,6 @@ expand_call (tree exp, rtx target, int ignore)
for (; i != end; i += inc)
{
args[i].tree_value = fix_unsafe_tree (args[i].tree_value);
- /* We need to build actparms for optimize_tail_recursion. We can
- safely trash away TREE_PURPOSE, since it is unused by this
- function. */
- if (try_tail_recursion)
- actparms = tree_cons (NULL_TREE, args[i].tree_value, actparms);
}
/* Do the same for the function address if it is an expression. */
if (!fndecl)
@@ -2581,62 +2451,9 @@ expand_call (tree exp, rtx target, int ignore)
/* Expanding one of those dangerous arguments could have added
cleanups, but otherwise give it a whirl. */
if (any_pending_cleanups ())
- try_tail_call = try_tail_recursion = 0;
+ try_tail_call = 0;
}
- /* Generate a tail recursion sequence when calling ourselves. */
-
- if (try_tail_recursion)
- {
- /* We want to emit any pending stack adjustments before the tail
- recursion "call". That way we know any adjustment after the tail
- recursion call can be ignored if we indeed use the tail recursion
- call expansion. */
- int save_pending_stack_adjust = pending_stack_adjust;
- int save_stack_pointer_delta = stack_pointer_delta;
-
- /* Emit any queued insns now; otherwise they would end up in
- only one of the alternates. */
- emit_queue ();
-
- /* Use a new sequence to hold any RTL we generate. We do not even
- know if we will use this RTL yet. The final decision can not be
- made until after RTL generation for the entire function is
- complete. */
- start_sequence ();
- /* If expanding any of the arguments creates cleanups, we can't
- do a tailcall. So, we'll need to pop the pending cleanups
- list. If, however, all goes well, and there are no cleanups
- then the call to expand_start_target_temps will have no
- effect. */
- expand_start_target_temps ();
- if (optimize_tail_recursion (actparms, get_last_insn ()))
- {
- if (any_pending_cleanups ())
- try_tail_call = try_tail_recursion = 0;
- else
- tail_recursion_insns = get_insns ();
- }
- expand_end_target_temps ();
- end_sequence ();
-
- /* Restore the original pending stack adjustment for the sibling and
- normal call cases below. */
- pending_stack_adjust = save_pending_stack_adjust;
- stack_pointer_delta = save_stack_pointer_delta;
- }
-
- if (profile_arc_flag && (flags & ECF_FORK_OR_EXEC))
- {
- /* A fork duplicates the profile information, and an exec discards
- it. We can't rely on fork/exec to be paired. So write out the
- profile information we have gathered so far, and clear it. */
- /* ??? When Linux's __clone is called with CLONE_VM set, profiling
- is subject to race conditions, just as with multithreaded
- programs. */
-
- emit_library_call (gcov_flush_libfunc, LCT_ALWAYS_RETURN, VOIDmode, 0);
- }
/* Ensure current function's preferred stack boundary is at least
what we need. We don't have to increase alignment for recursive
@@ -2659,7 +2476,7 @@ expand_call (tree exp, rtx target, int ignore)
int sibcall_failure = 0;
/* We want to emit any pending stack adjustments before the tail
recursion "call". That way we know any adjustment after the tail
- recursion call can be ignored if we indeed use the tail recursion
+ recursion call can be ignored if we indeed use the tail
call expansion. */
int save_pending_stack_adjust = 0;
int save_stack_pointer_delta = 0;
@@ -2991,6 +2808,12 @@ expand_call (tree exp, rtx target, int ignore)
once we have started filling any specific hard regs. */
precompute_register_parameters (num_actuals, args, &reg_parm_seen);
+ if (TREE_OPERAND (exp, 2))
+ static_chain_value = expand_expr (TREE_OPERAND (exp, 2),
+ NULL_RTX, VOIDmode, 0);
+ else
+ static_chain_value = 0;
+
#ifdef REG_PARM_STACK_SPACE
/* Save the fixed argument area if it's part of the caller's frame and
is clobbered by argument setup for this call. */
@@ -3081,8 +2904,8 @@ expand_call (tree exp, rtx target, int ignore)
use_reg (&call_fusage, struct_value);
}
- funexp = prepare_call_address (funexp, fndecl, &call_fusage,
- reg_parm_seen, pass == 0);
+ funexp = prepare_call_address (funexp, static_chain_value,
+ &call_fusage, reg_parm_seen, pass == 0);
load_register_parameters (args, num_actuals, &call_fusage, flags,
pass == 0, &sibcall_failure);
@@ -3113,7 +2936,7 @@ expand_call (tree exp, rtx target, int ignore)
abort ();
/* Generate the actual call instruction. */
- emit_call_1 (funexp, fndecl, funtype, unadjusted_args_size,
+ emit_call_1 (funexp, exp, fndecl, funtype, unadjusted_args_size,
adjusted_args_size.constant, struct_value_size,
next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage,
flags, & args_so_far);
@@ -3280,11 +3103,7 @@ expand_call (tree exp, rtx target, int ignore)
The Irix 6 ABI has examples of this. */
else if (GET_CODE (valreg) == PARALLEL)
{
- /* Second condition is added because "target" is freed at the
- the end of "pass0" for -O2 when call is made to
- expand_end_target_temps (). Its "in_use" flag has been set
- to false, so allocate a new temp. */
- if (target == 0 || (pass == 1 && target == temp_target))
+ if (target == 0)
{
/* This will only be assigned once, so it can be readonly. */
tree nt = build_qualified_type (TREE_TYPE (exp),
@@ -3292,7 +3111,6 @@ expand_call (tree exp, rtx target, int ignore)
| TYPE_QUAL_CONST));
target = assign_temp (nt, 0, 1, 1);
- temp_target = target;
preserve_temp_slots (target);
}
@@ -3417,8 +3235,8 @@ expand_call (tree exp, rtx target, int ignore)
Check for the handler slots since we might not have a save area
for non-local gotos. */
- if ((flags & ECF_MAY_BE_ALLOCA) && nonlocal_goto_handler_slots != 0)
- emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level, NULL_RTX);
+ if ((flags & ECF_MAY_BE_ALLOCA) && cfun->nonlocal_goto_save_area != 0)
+ update_nonlocal_goto_save_area ();
/* Free up storage we no longer need. */
for (i = 0; i < num_actuals; ++i)
@@ -3487,48 +3305,16 @@ expand_call (tree exp, rtx target, int ignore)
zero out the sequence. */
if (sibcall_failure)
tail_call_insns = NULL_RTX;
+ else
+ break;
}
- /* The function optimize_sibling_and_tail_recursive_calls doesn't
- handle CALL_PLACEHOLDERs inside other CALL_PLACEHOLDERs. This
- can happen if the arguments to this function call an inline
- function who's expansion contains another CALL_PLACEHOLDER.
-
- If there are any C_Ps in any of these sequences, replace them
- with their normal call. */
-
- for (insn = normal_call_insns; insn; insn = NEXT_INSN (insn))
- if (GET_CODE (insn) == CALL_INSN
- && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
- replace_call_placeholder (insn, sibcall_use_normal);
-
- for (insn = tail_call_insns; insn; insn = NEXT_INSN (insn))
- if (GET_CODE (insn) == CALL_INSN
- && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
- replace_call_placeholder (insn, sibcall_use_normal);
-
- for (insn = tail_recursion_insns; insn; insn = NEXT_INSN (insn))
- if (GET_CODE (insn) == CALL_INSN
- && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
- replace_call_placeholder (insn, sibcall_use_normal);
-
- /* If this was a potential tail recursion site, then emit a
- CALL_PLACEHOLDER with the normal and the tail recursion streams.
- One of them will be selected later. */
- if (tail_recursion_insns || tail_call_insns)
+ /* If tail call production suceeded, we need to remove REG_EQUIV notes on
+ arguments too, as argument area is now clobbered by the call. */
+ if (tail_call_insns)
{
- /* The tail recursion label must be kept around. We could expose
- its use in the CALL_PLACEHOLDER, but that creates unwanted edges
- and makes determining true tail recursion sites difficult.
-
- So we set LABEL_PRESERVE_P here, then clear it when we select
- one of the call sequences after rtl generation is complete. */
- if (tail_recursion_insns)
- LABEL_PRESERVE_P (tail_recursion_label) = 1;
- emit_call_insn (gen_rtx_CALL_PLACEHOLDER (VOIDmode, normal_call_insns,
- tail_call_insns,
- tail_recursion_insns,
- tail_recursion_label));
+ emit_insn (tail_call_insns);
+ cfun->tail_call_emit = true;
}
else
emit_insn (normal_call_insns);
@@ -3549,6 +3335,47 @@ expand_call (tree exp, rtx target, int ignore)
return target;
}
+/* A sibling call sequence invalidates any REG_EQUIV notes made for
+ this function's incoming arguments.
+
+ At the start of RTL generation we know the only REG_EQUIV notes
+ in the rtl chain are those for incoming arguments, so we can safely
+ flush any REG_EQUIV note.
+
+ This is (slight) overkill. We could keep track of the highest
+ argument we clobber and be more selective in removing notes, but it
+ does not seem to be worth the effort. */
+void
+fixup_tail_calls (void)
+{
+ rtx insn;
+ tree arg;
+
+ purge_reg_equiv_notes ();
+
+ /* A sibling call sequence also may invalidate RTX_UNCHANGING_P
+ flag of some incoming arguments MEM RTLs, because it can write into
+ those slots. We clear all those bits now.
+
+ This is (slight) overkill, we could keep track of which arguments
+ we actually write into. */
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ {
+ if (INSN_P (insn))
+ purge_mem_unchanging_flag (PATTERN (insn));
+ }
+
+ /* Similarly, invalidate RTX_UNCHANGING_P for any incoming
+ arguments passed in registers. */
+ for (arg = DECL_ARGUMENTS (current_function_decl);
+ arg;
+ arg = TREE_CHAIN (arg))
+ {
+ if (REG_P (DECL_RTL (arg)))
+ RTX_UNCHANGING_P (DECL_RTL (arg)) = false;
+ }
+}
+
/* Traverse an argument list in VALUES and expand all complex
arguments into their components. */
tree
@@ -4160,7 +3987,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
else
argnum = 0;
- fun = prepare_call_address (fun, NULL_TREE, &call_fusage, 0, 0);
+ fun = prepare_call_address (fun, NULL, &call_fusage, 0, 0);
/* Now load any reg parms into their regs. */
@@ -4222,7 +4049,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
always signed. We also assume that the list of arguments passed has
no impact, so we pretend it is unknown. */
- emit_call_1 (fun,
+ emit_call_1 (fun, NULL,
get_identifier (XSTR (orgfun, 0)),
build_function_type (tfom, NULL_TREE),
original_args_size.constant, args_size.constant,
diff --git a/gcc/cfg.c b/gcc/cfg.c
index 5eb9c248c5b..4b6de6d66a8 100644
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -62,20 +62,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tm_p.h"
#include "obstack.h"
#include "alloc-pool.h"
+#include "timevar.h"
+#include "ggc.h"
/* The obstack on which the flow graph components are allocated. */
struct obstack flow_obstack;
static char *flow_firstobj;
-/* Basic block object pool. */
-
-static alloc_pool bb_pool;
-
-/* Edge object pool. */
-
-static alloc_pool edge_pool;
-
/* Number of basic blocks in the current function. */
int n_basic_blocks;
@@ -93,56 +87,10 @@ int n_edges;
varray_type basic_block_info;
/* The special entry and exit blocks. */
+basic_block ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR;
-struct basic_block_def entry_exit_blocks[2]
-= {{NULL, /* head */
- NULL, /* end */
- NULL, /* head_tree */
- NULL, /* end_tree */
- NULL, /* pred */
- NULL, /* succ */
- NULL, /* local_set */
- NULL, /* cond_local_set */
- NULL, /* global_live_at_start */
- NULL, /* global_live_at_end */
- NULL, /* aux */
- ENTRY_BLOCK, /* index */
- NULL, /* prev_bb */
- EXIT_BLOCK_PTR, /* next_bb */
- 0, /* loop_depth */
- NULL, /* loop_father */
- { NULL, NULL }, /* dom */
- 0, /* count */
- 0, /* frequency */
- 0, /* flags */
- 0, /* partition */
- NULL /* rbi */
- },
- {
- NULL, /* head */
- NULL, /* end */
- NULL, /* head_tree */
- NULL, /* end_tree */
- NULL, /* pred */
- NULL, /* succ */
- NULL, /* local_set */
- NULL, /* cond_local_set */
- NULL, /* global_live_at_start */
- NULL, /* global_live_at_end */
- NULL, /* aux */
- EXIT_BLOCK, /* index */
- ENTRY_BLOCK_PTR, /* prev_bb */
- NULL, /* next_bb */
- 0, /* loop_depth */
- NULL, /* loop_father */
- { NULL, NULL }, /* dom */
- 0, /* count */
- 0, /* frequency */
- 0, /* flags */
- 0, /* partition */
- NULL /* rbi */
- }
-};
+/* Memory alloc pool for bb member rbi. */
+alloc_pool rbi_pool;
void debug_flow_info (void);
static void free_edge (edge);
@@ -164,25 +112,26 @@ init_flow (void)
}
else
{
- free_alloc_pool (bb_pool);
- free_alloc_pool (edge_pool);
obstack_free (&flow_obstack, flow_firstobj);
flow_firstobj = obstack_alloc (&flow_obstack, 0);
}
- bb_pool = create_alloc_pool ("Basic block pool",
- sizeof (struct basic_block_def), 100);
- edge_pool = create_alloc_pool ("Edge pool",
- sizeof (struct edge_def), 100);
+
+ ENTRY_BLOCK_PTR = ggc_alloc_cleared (sizeof (*ENTRY_BLOCK_PTR));
+ ENTRY_BLOCK_PTR->index = ENTRY_BLOCK;
+ EXIT_BLOCK_PTR = ggc_alloc_cleared (sizeof (*EXIT_BLOCK_PTR));
+ EXIT_BLOCK_PTR->index = EXIT_BLOCK;
+ ENTRY_BLOCK_PTR->next_bb = EXIT_BLOCK_PTR;
+ EXIT_BLOCK_PTR->prev_bb = ENTRY_BLOCK_PTR;
}
/* Helper function for remove_edge and clear_edges. Frees edge structure
without actually unlinking it from the pred/succ lists. */
static void
-free_edge (edge e)
+free_edge (edge e ATTRIBUTE_UNUSED)
{
n_edges--;
- pool_free (edge_pool, e);
+ /* ggc_free (e); */
}
/* Free the memory associated with the edge structures. */
@@ -231,11 +180,40 @@ basic_block
alloc_block (void)
{
basic_block bb;
- bb = pool_alloc (bb_pool);
- memset (bb, 0, sizeof (*bb));
+ bb = ggc_alloc_cleared (sizeof (*bb));
return bb;
}
+/* Create memory pool for rbi_pool. */
+
+void
+alloc_rbi_pool (void)
+{
+ rbi_pool = create_alloc_pool ("rbi pool",
+ sizeof (struct reorder_block_def),
+ n_basic_blocks + 2);
+}
+
+/* Free rbi_pool. */
+
+void
+free_rbi_pool (void)
+{
+ free_alloc_pool (rbi_pool);
+}
+
+/* Initialize rbi (the structure containing data used by basic block
+ duplication and reordering) for the given basic block. */
+
+void
+initialize_bb_rbi (basic_block bb)
+{
+ if (bb->rbi)
+ abort ();
+ bb->rbi = pool_alloc (rbi_pool);
+ memset (bb->rbi, 0, sizeof (struct reorder_block_def));
+}
+
/* Link block B to chain after AFTER. */
void
link_block (basic_block b, basic_block after)
@@ -252,6 +230,8 @@ unlink_block (basic_block b)
{
b->next_bb->prev_bb = b->prev_bb;
b->prev_bb->next_bb = b->next_bb;
+ b->prev_bb = NULL;
+ b->next_bb = NULL;
}
/* Sequentially order blocks and compact the arrays. */
@@ -272,6 +252,9 @@ compact_blocks (void)
if (i != n_basic_blocks)
abort ();
+ for (; i < last_basic_block; i++)
+ BASIC_BLOCK (i) = NULL;
+
last_basic_block = n_basic_blocks;
}
@@ -283,7 +266,7 @@ expunge_block (basic_block b)
unlink_block (b);
BASIC_BLOCK (b->index) = NULL;
n_basic_blocks--;
- pool_free (bb_pool, b);
+ /* ggc_free (b); */
}
/* Create an edge connecting SRC and DEST with flags FLAGS. Return newly
@@ -294,8 +277,7 @@ edge
unchecked_make_edge (basic_block src, basic_block dst, int flags)
{
edge e;
- e = pool_alloc (edge_pool);
- memset (e, 0, sizeof (*e));
+ e = ggc_alloc_cleared (sizeof (*e));
n_edges++;
e->succ_next = src->succ;
@@ -490,54 +472,56 @@ void
dump_flow_info (FILE *file)
{
int i;
- int max_regno = max_reg_num ();
basic_block bb;
static const char * const reg_class_names[] = REG_CLASS_NAMES;
- fprintf (file, "%d registers.\n", max_regno);
if (reg_n_info)
- for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
- if (REG_N_REFS (i))
- {
- enum reg_class class, altclass;
-
- fprintf (file, "\nRegister %d used %d times across %d insns",
- i, REG_N_REFS (i), REG_LIVE_LENGTH (i));
- if (REG_BASIC_BLOCK (i) >= 0)
- fprintf (file, " in block %d", REG_BASIC_BLOCK (i));
- if (REG_N_SETS (i))
- fprintf (file, "; set %d time%s", REG_N_SETS (i),
- (REG_N_SETS (i) == 1) ? "" : "s");
- if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i]))
- fprintf (file, "; user var");
- if (REG_N_DEATHS (i) != 1)
- fprintf (file, "; dies in %d places", REG_N_DEATHS (i));
- if (REG_N_CALLS_CROSSED (i) == 1)
- fprintf (file, "; crosses 1 call");
- else if (REG_N_CALLS_CROSSED (i))
- fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i));
- if (regno_reg_rtx[i] != NULL
- && PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD)
- fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i));
-
- class = reg_preferred_class (i);
- altclass = reg_alternate_class (i);
- if (class != GENERAL_REGS || altclass != ALL_REGS)
- {
- if (altclass == ALL_REGS || class == ALL_REGS)
- fprintf (file, "; pref %s", reg_class_names[(int) class]);
- else if (altclass == NO_REGS)
- fprintf (file, "; %s or none", reg_class_names[(int) class]);
- else
- fprintf (file, "; pref %s, else %s",
- reg_class_names[(int) class],
- reg_class_names[(int) altclass]);
- }
-
- if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i]))
- fprintf (file, "; pointer");
- fprintf (file, ".\n");
- }
+ {
+ int max_regno = max_reg_num ();
+ fprintf (file, "%d registers.\n", max_regno);
+ for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
+ if (REG_N_REFS (i))
+ {
+ enum reg_class class, altclass;
+
+ fprintf (file, "\nRegister %d used %d times across %d insns",
+ i, REG_N_REFS (i), REG_LIVE_LENGTH (i));
+ if (REG_BASIC_BLOCK (i) >= 0)
+ fprintf (file, " in block %d", REG_BASIC_BLOCK (i));
+ if (REG_N_SETS (i))
+ fprintf (file, "; set %d time%s", REG_N_SETS (i),
+ (REG_N_SETS (i) == 1) ? "" : "s");
+ if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i]))
+ fprintf (file, "; user var");
+ if (REG_N_DEATHS (i) != 1)
+ fprintf (file, "; dies in %d places", REG_N_DEATHS (i));
+ if (REG_N_CALLS_CROSSED (i) == 1)
+ fprintf (file, "; crosses 1 call");
+ else if (REG_N_CALLS_CROSSED (i))
+ fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i));
+ if (regno_reg_rtx[i] != NULL
+ && PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD)
+ fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i));
+
+ class = reg_preferred_class (i);
+ altclass = reg_alternate_class (i);
+ if (class != GENERAL_REGS || altclass != ALL_REGS)
+ {
+ if (altclass == ALL_REGS || class == ALL_REGS)
+ fprintf (file, "; pref %s", reg_class_names[(int) class]);
+ else if (altclass == NO_REGS)
+ fprintf (file, "; %s or none", reg_class_names[(int) class]);
+ else
+ fprintf (file, "; pref %s, else %s",
+ reg_class_names[(int) class],
+ reg_class_names[(int) altclass]);
+ }
+
+ if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i]))
+ fprintf (file, "; pointer");
+ fprintf (file, ".\n");
+ }
+ }
fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks, n_edges);
FOR_EACH_BB (bb)
@@ -546,8 +530,7 @@ dump_flow_info (FILE *file)
int sum;
gcov_type lsum;
- fprintf (file, "\nBasic block %d: first insn %d, last %d, ",
- bb->index, INSN_UID (BB_HEAD (bb)), INSN_UID (BB_END (bb)));
+ fprintf (file, "\nBasic block %d ", bb->index);
fprintf (file, "prev %d, next %d, ",
bb->prev_bb->index, bb->next_bb->index);
fprintf (file, "loop_depth %d, count ", bb->loop_depth);
@@ -641,7 +624,8 @@ dump_edge_info (FILE *file, edge e, int do_succ)
{
static const char * const bitnames[] = {
"fallthru", "ab", "abcall", "eh", "fake", "dfs_back",
- "can_fallthru", "irreducible", "sibcall", "loop_exit"
+ "can_fallthru", "irreducible", "sibcall", "loop_exit",
+ "true", "false", "exec"
};
int comma = 0;
int i, flags = e->flags;
@@ -825,3 +809,55 @@ debug_bb_n (int n)
dump_bb (bb, stderr, 0);
return bb;
}
+
+/* Dumps cfg related information about basic block BB to FILE. */
+
+static void
+dump_cfg_bb_info (FILE *file, basic_block bb)
+{
+ unsigned i;
+ bool first = true;
+ static const char * const bb_bitnames[] =
+ {
+ "dirty", "new", "reachable", "visited", "irreducible_loop", "superblock"
+ };
+ const unsigned n_bitnames = sizeof (bb_bitnames) / sizeof (char *);
+ edge e;
+
+ fprintf (file, "Basic block %d", bb->index);
+ for (i = 0; i < n_bitnames; i++)
+ if (bb->flags & (1 << i))
+ {
+ if (first)
+ fprintf (file, " (");
+ else
+ fprintf (file, ", ");
+ first = false;
+ fprintf (file, bb_bitnames[i]);
+ }
+ if (!first)
+ fprintf (file, ")");
+ fprintf (file, "\n");
+
+ fprintf (file, "Predecessors: ");
+ for (e = bb->pred; e; e = e->pred_next)
+ dump_edge_info (file, e, 0);
+
+ fprintf (file, "\nSuccessors: ");
+ for (e = bb->succ; e; e = e->succ_next)
+ dump_edge_info (file, e, 1);
+ fprintf (file, "\n\n");
+}
+
+/* Dumps a brief description of cfg to FILE. */
+
+void
+brief_dump_cfg (FILE *file)
+{
+ basic_block bb;
+
+ FOR_EACH_BB (bb)
+ {
+ dump_cfg_bb_info (file, bb);
+ }
+}
diff --git a/gcc/cfganal.c b/gcc/cfganal.c
index 00771b47703..1a7d280513f 100644
--- a/gcc/cfganal.c
+++ b/gcc/cfganal.c
@@ -52,7 +52,6 @@ static void flow_dfs_compute_reverse_add_bb (depth_first_search_ds,
static basic_block flow_dfs_compute_reverse_execute (depth_first_search_ds);
static void flow_dfs_compute_reverse_finish (depth_first_search_ds);
static void remove_fake_successors (basic_block);
-static bool need_fake_edge_p (rtx);
static bool flow_active_insn_p (rtx);
/* Like active_insn_p, except keep the return value clobber around
@@ -242,169 +241,6 @@ set_edge_can_fallthru_flag (void)
}
}
-/* Return true if we need to add fake edge to exit.
- Helper function for the flow_call_edges_add. */
-
-static bool
-need_fake_edge_p (rtx insn)
-{
- if (!INSN_P (insn))
- return false;
-
- if ((GET_CODE (insn) == CALL_INSN
- && !SIBLING_CALL_P (insn)
- && !find_reg_note (insn, REG_NORETURN, NULL)
- && !find_reg_note (insn, REG_ALWAYS_RETURN, NULL)
- && !CONST_OR_PURE_CALL_P (insn)))
- return true;
-
- return ((GET_CODE (PATTERN (insn)) == ASM_OPERANDS
- && MEM_VOLATILE_P (PATTERN (insn)))
- || (GET_CODE (PATTERN (insn)) == PARALLEL
- && asm_noperands (insn) != -1
- && MEM_VOLATILE_P (XVECEXP (PATTERN (insn), 0, 0)))
- || GET_CODE (PATTERN (insn)) == ASM_INPUT);
-}
-
-/* Add fake edges to the function exit for any non constant and non noreturn
- calls, volatile inline assembly in the bitmap of blocks specified by
- BLOCKS or to the whole CFG if BLOCKS is zero. Return the number of blocks
- that were split.
-
- The goal is to expose cases in which entering a basic block does not imply
- that all subsequent instructions must be executed. */
-
-int
-flow_call_edges_add (sbitmap blocks)
-{
- int i;
- int blocks_split = 0;
- int last_bb = last_basic_block;
- bool check_last_block = false;
-
- if (n_basic_blocks == 0)
- return 0;
-
- if (! blocks)
- check_last_block = true;
- else
- check_last_block = TEST_BIT (blocks, EXIT_BLOCK_PTR->prev_bb->index);
-
- /* In the last basic block, before epilogue generation, there will be
- a fallthru edge to EXIT. Special care is required if the last insn
- of the last basic block is a call because make_edge folds duplicate
- edges, which would result in the fallthru edge also being marked
- fake, which would result in the fallthru edge being removed by
- remove_fake_edges, which would result in an invalid CFG.
-
- Moreover, we can't elide the outgoing fake edge, since the block
- profiler needs to take this into account in order to solve the minimal
- spanning tree in the case that the call doesn't return.
-
- Handle this by adding a dummy instruction in a new last basic block. */
- if (check_last_block)
- {
- basic_block bb = EXIT_BLOCK_PTR->prev_bb;
- rtx insn = BB_END (bb);
-
- /* Back up past insns that must be kept in the same block as a call. */
- while (insn != BB_HEAD (bb)
- && keep_with_call_p (insn))
- insn = PREV_INSN (insn);
-
- if (need_fake_edge_p (insn))
- {
- edge e;
-
- for (e = bb->succ; e; e = e->succ_next)
- if (e->dest == EXIT_BLOCK_PTR)
- {
- insert_insn_on_edge (gen_rtx_USE (VOIDmode, const0_rtx), e);
- commit_edge_insertions ();
- break;
- }
- }
- }
-
- /* Now add fake edges to the function exit for any non constant
- calls since there is no way that we can determine if they will
- return or not... */
-
- for (i = 0; i < last_bb; i++)
- {
- basic_block bb = BASIC_BLOCK (i);
- rtx libcall_end = NULL_RTX;
- rtx insn;
- rtx prev_insn;
-
- if (!bb)
- continue;
-
- if (blocks && !TEST_BIT (blocks, i))
- continue;
-
- for (insn = BB_END (bb); ; insn = prev_insn)
- {
- prev_insn = PREV_INSN (insn);
- if (need_fake_edge_p (insn))
- {
- edge e;
- rtx split_at_insn = insn;
-
- /* Don't split libcalls. */
- if (libcall_end)
- split_at_insn = libcall_end;
-
- /* Don't split the block between a call and an insn that should
- remain in the same block as the call. */
- else if (GET_CODE (insn) == CALL_INSN)
- while (split_at_insn != BB_END (bb)
- && keep_with_call_p (NEXT_INSN (split_at_insn)))
- split_at_insn = NEXT_INSN (split_at_insn);
-
- /* The handling above of the final block before the epilogue
- should be enough to verify that there is no edge to the exit
- block in CFG already. Calling make_edge in such case would
- cause us to mark that edge as fake and remove it later. */
-
-#ifdef ENABLE_CHECKING
- if (split_at_insn == BB_END (bb))
- for (e = bb->succ; e; e = e->succ_next)
- if (e->dest == EXIT_BLOCK_PTR)
- abort ();
-#endif
-
- /* Note that the following may create a new basic block
- and renumber the existing basic blocks. */
- if (split_at_insn != BB_END (bb))
- {
- e = split_block (bb, split_at_insn);
- if (e)
- blocks_split++;
- }
-
- make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
- }
-
- /* Watch out for REG_LIBCALL/REG_RETVAL notes so that we know
- whether we are currently in a libcall or not. Remember that
- we are scanning backwards! */
- if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
- libcall_end = insn;
- if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
- libcall_end = NULL_RTX;
-
- if (insn == BB_HEAD (bb))
- break;
- }
- }
-
- if (blocks_split)
- verify_flow_info ();
-
- return blocks_split;
-}
-
/* Find unreachable blocks. An unreachable block will have 0 in
the reachable bit in block->flags. A nonzero value indicates the
block is reachable. */
@@ -603,6 +439,21 @@ verify_edge_list (FILE *f, struct edge_list *elist)
}
}
+/* Given PRED and SUCC blocks, return the edge which connects the blocks.
+ If no such edge exists, return NULL. */
+
+edge
+find_edge (basic_block pred, basic_block succ)
+{
+ edge e;
+
+ for (e = pred->succ; e; e = e->succ_next)
+ if (e->dest == succ)
+ return e;
+
+ return NULL;
+}
+
/* This routine will determine what, if any, edge there is between
a specified predecessor and successor. */
diff --git a/gcc/cfgbuild.c b/gcc/cfgbuild.c
index cd936a27b9d..3e9a36cca4d 100644
--- a/gcc/cfgbuild.c
+++ b/gcc/cfgbuild.c
@@ -240,7 +240,7 @@ make_label_edge (sbitmap *edge_cache, basic_block src, rtx label, int flags)
/* Create the edges generated by INSN in REGION. */
void
-make_eh_edge (sbitmap *edge_cache, basic_block src, rtx insn)
+rtl_make_eh_edge (sbitmap *edge_cache, basic_block src, rtx insn)
{
int is_call = GET_CODE (insn) == CALL_INSN ? EDGE_ABNORMAL_CALL : 0;
rtx handlers, i;
@@ -325,7 +325,7 @@ make_edges (rtx label_value_list, basic_block min, basic_block max, int update_p
/* Recognize exception handling placeholders. */
if (GET_CODE (PATTERN (insn)) == RESX)
- make_eh_edge (edge_cache, bb, insn);
+ rtl_make_eh_edge (edge_cache, bb, insn);
/* Recognize a non-local goto as a branch outside the
current function. */
@@ -405,7 +405,7 @@ make_edges (rtx label_value_list, basic_block min, basic_block max, int update_p
else if (code == CALL_INSN || flag_non_call_exceptions)
{
/* Add any appropriate EH edges. */
- make_eh_edge (edge_cache, bb, insn);
+ rtl_make_eh_edge (edge_cache, bb, insn);
if (code == CALL_INSN && nonlocal_goto_handler_labels)
{
@@ -610,7 +610,7 @@ find_basic_blocks (rtx f, int nregs ATTRIBUTE_UNUSED,
FOR_EACH_BB (bb)
bb->aux = NULL;
- VARRAY_FREE (basic_block_info);
+ basic_block_info = NULL;
}
n_basic_blocks = count_basic_blocks (f);
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index 51182e3f400..10d9e96c135 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -1368,7 +1368,7 @@ outgoing_edges_match (int mode, basic_block bb1, basic_block bb2)
/* The labels should never be the same rtx. If they really are same
the jump tables are same too. So disable crossjumping of blocks BB1
and BB2 because when deleting the common insns in the end of BB1
- by delete_block () the jump table would be deleted too. */
+ by delete_basic_block () the jump table would be deleted too. */
/* If LABEL2 is referenced in BB1->END do not do anything
because we would loose information when replacing
LABEL1 by LABEL2 and then LABEL2 by LABEL1 in BB1->END. */
@@ -1501,6 +1501,8 @@ try_crossjump_to_edge (int mode, edge e1, edge e2)
rtx newpos1, newpos2;
edge s;
+ newpos1 = newpos2 = NULL_RTX;
+
/* If we have partitioned hot/cold basic blocks, it is a bad idea
to try this optimization. */
@@ -2033,6 +2035,32 @@ delete_unreachable_blocks (void)
tidy_fallthru_edges ();
return changed;
}
+
+/* Merges sequential blocks if possible. */
+
+bool
+merge_seq_blocks (void)
+{
+ basic_block bb;
+ bool changed = false;
+
+ for (bb = ENTRY_BLOCK_PTR->next_bb; bb != EXIT_BLOCK_PTR; )
+ {
+ if (bb->succ
+ && !bb->succ->succ_next
+ && can_merge_blocks_p (bb, bb->succ->dest))
+ {
+ /* Merge the blocks and retry. */
+ merge_blocks (bb, bb->succ->dest);
+ changed = true;
+ continue;
+ }
+
+ bb = bb->next_bb;
+ }
+
+ return changed;
+}
/* Tidy the CFG by deleting unreachable code and whatnot. */
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c
index 001dfe29bd4..29f5dfd1695 100644
--- a/gcc/cfghooks.c
+++ b/gcc/cfghooks.c
@@ -26,6 +26,7 @@ Boston, MA 02111-1307, USA. */
#include "tree.h"
#include "rtl.h"
#include "basic-block.h"
+#include "tree-flow.h"
#include "timevar.h"
#include "toplev.h"
@@ -46,6 +47,22 @@ cfg_layout_rtl_register_cfg_hooks (void)
cfg_hooks = &cfg_layout_rtl_cfg_hooks;
}
+/* Initialization of functions specific to the tree IR. */
+
+void
+tree_register_cfg_hooks (void)
+{
+ cfg_hooks = &tree_cfg_hooks;
+}
+
+/* Returns current ir type (rtl = 0, trees = 1). */
+
+int
+ir_type (void)
+{
+ return cfg_hooks == &tree_cfg_hooks ? 1 : 0;
+}
+
/* Verify the CFG consistency.
Currently it does following: checks edge and basic block list correctness
@@ -246,10 +263,10 @@ dump_bb (basic_block bb, FILE *outf, int indent)
be equivalent to E in the case of duplicate edges being removed) or NULL
if edge is not easily redirectable for whatever reason. */
-bool
+edge
redirect_edge_and_branch (edge e, basic_block dest)
{
- bool ret;
+ edge ret;
if (!cfg_hooks->redirect_edge_and_branch)
internal_error ("%s does not support redirect_edge_and_branch.",
@@ -286,7 +303,6 @@ edge
split_block (basic_block bb, void *i)
{
basic_block new_bb;
- edge e;
if (!cfg_hooks->split_block)
internal_error ("%s does not support split_block.", cfg_hooks->name);
@@ -305,11 +321,7 @@ split_block (basic_block bb, void *i)
set_immediate_dominator (CDI_DOMINATORS, new_bb, bb);
}
- e = make_edge (bb, new_bb, EDGE_FALLTHRU);
- e->probability = REG_BR_PROB_BASE;
- e->count = bb->count;
-
- return e;
+ return make_edge (bb, new_bb, EDGE_FALLTHRU);
}
/* Splits block BB just after labels. The newly created edge is returned. */
@@ -464,6 +476,24 @@ can_merge_blocks_p (basic_block bb1, basic_block bb2)
return ret;
}
+void
+predict_edge (edge e, enum br_predictor predictor, int probability)
+{
+ if (!cfg_hooks->predict_edge)
+ internal_error ("%s does not support predict_edge.", cfg_hooks->name);
+
+ cfg_hooks->predict_edge (e, predictor, probability);
+}
+
+bool
+predicted_by_p (basic_block bb, enum br_predictor predictor)
+{
+ if (!cfg_hooks->predict_edge)
+ internal_error ("%s does not support predicted_by_p.", cfg_hooks->name);
+
+ return cfg_hooks->predicted_by_p (bb, predictor);
+}
+
/* Merges basic block B into basic block A. */
void
@@ -605,3 +635,140 @@ tidy_fallthru_edges (void)
tidy_fallthru_edge (s);
}
}
+
+/* Returns true if we can duplicate basic block BB. */
+
+bool
+can_duplicate_block_p (basic_block bb)
+{
+ edge e;
+
+ if (!cfg_hooks->can_duplicate_block_p)
+ internal_error ("%s does not support can_duplicate_block_p.",
+ cfg_hooks->name);
+
+ if (bb == EXIT_BLOCK_PTR || bb == ENTRY_BLOCK_PTR)
+ return false;
+
+ /* Duplicating fallthru block to exit would require adding a jump
+ and splitting the real last BB. */
+ for (e = bb->succ; e; e = e->succ_next)
+ if (e->dest == EXIT_BLOCK_PTR && e->flags & EDGE_FALLTHRU)
+ return false;
+
+ return cfg_hooks->can_duplicate_block_p (bb);
+}
+
+/* Duplicates basic block BB and redirects edge E to it. Returns the
+ new basic block. */
+
+basic_block
+duplicate_block (basic_block bb, edge e)
+{
+ edge s, n;
+ basic_block new_bb;
+ gcov_type new_count = e ? e->count : 0;
+
+ if (!cfg_hooks->duplicate_block)
+ internal_error ("%s does not support duplicate_block.",
+ cfg_hooks->name);
+
+ if (bb->count < new_count)
+ new_count = bb->count;
+ if (!bb->pred)
+ abort ();
+#ifdef ENABLE_CHECKING
+ if (!can_duplicate_block_p (bb))
+ abort ();
+#endif
+
+ new_bb = cfg_hooks->duplicate_block (bb);
+
+ new_bb->loop_depth = bb->loop_depth;
+ new_bb->flags = bb->flags;
+ for (s = bb->succ; s; s = s->succ_next)
+ {
+ /* Since we are creating edges from a new block to successors
+ of another block (which therefore are known to be disjoint), there
+ is no need to actually check for duplicated edges. */
+ n = unchecked_make_edge (new_bb, s->dest, s->flags);
+ n->probability = s->probability;
+ if (e && bb->count)
+ {
+ /* Take care for overflows! */
+ n->count = s->count * (new_count * 10000 / bb->count) / 10000;
+ s->count -= n->count;
+ }
+ else
+ n->count = s->count;
+ n->aux = s->aux;
+ }
+
+ if (e)
+ {
+ new_bb->count = new_count;
+ bb->count -= new_count;
+
+ new_bb->frequency = EDGE_FREQUENCY (e);
+ bb->frequency -= EDGE_FREQUENCY (e);
+
+ redirect_edge_and_branch_force (e, new_bb);
+
+ if (bb->count < 0)
+ bb->count = 0;
+ if (bb->frequency < 0)
+ bb->frequency = 0;
+ }
+ else
+ {
+ new_bb->count = bb->count;
+ new_bb->frequency = bb->frequency;
+ }
+
+ new_bb->rbi->original = bb;
+ bb->rbi->copy = new_bb;
+
+ return new_bb;
+}
+
+/* Return 1 if BB ends with a call, possibly followed by some
+ instructions that must stay with the call, 0 otherwise. */
+
+bool
+block_ends_with_call_p (basic_block bb)
+{
+ if (!cfg_hooks->block_ends_with_call_p)
+ internal_error ("%s does not support block_ends_with_call_p", cfg_hooks->name);
+
+ return (cfg_hooks->block_ends_with_call_p) (bb);
+}
+
+/* Return 1 if BB ends with a conditional branch, 0 otherwise. */
+
+bool
+block_ends_with_condjump_p (basic_block bb)
+{
+ if (!cfg_hooks->block_ends_with_condjump_p)
+ internal_error ("%s does not support block_ends_with_condjump_p",
+ cfg_hooks->name);
+
+ return (cfg_hooks->block_ends_with_condjump_p) (bb);
+}
+
+/* Add fake edges to the function exit for any non constant and non noreturn
+ calls, volatile inline assembly in the bitmap of blocks specified by
+ BLOCKS or to the whole CFG if BLOCKS is zero. Return the number of blocks
+ that were split.
+
+ The goal is to expose cases in which entering a basic block does not imply
+ that all subsequent instructions must be executed. */
+
+int
+flow_call_edges_add (sbitmap blocks)
+{
+ if (!cfg_hooks->flow_call_edges_add)
+ internal_error ("%s does not support flow_call_edges_add",
+ cfg_hooks->name);
+
+ return (cfg_hooks->flow_call_edges_add) (blocks);
+}
diff --git a/gcc/cfghooks.h b/gcc/cfghooks.h
index 4bffe74be9f..7cbe700df36 100644
--- a/gcc/cfghooks.h
+++ b/gcc/cfghooks.h
@@ -37,9 +37,10 @@ struct cfg_hooks
basic_block (*create_basic_block) (void *head, void *end, basic_block after);
/* Redirect edge E to the given basic block B and update underlying program
- representation. Returns false when edge is not easily redirectable for
- whatever reason. */
- bool (*redirect_edge_and_branch) (edge e, basic_block b);
+ representation. Returns edge representing redirected branch (that may not
+ be equivalent to E in the case of duplicate edges being removed) or NULL
+ if edge is not easily redirectable for whatever reason. */
+ edge (*redirect_edge_and_branch) (edge e, basic_block b);
/* Same as the above but allows redirecting of fallthru edges. In that case
newly created forwarder basic block is returned. It aborts when called
@@ -62,6 +63,19 @@ struct cfg_hooks
/* Merge blocks A and B. */
void (*merge_blocks) (basic_block a, basic_block b);
+ /* Predict edge E using PREDICTOR to given PROBABILITY. */
+ void (*predict_edge) (edge e, enum br_predictor predictor, int probability);
+
+ /* Return true if the one of outgoing edges is already predicted by
+ PREDICTOR. */
+ bool (*predicted_by_p) (basic_block bb, enum br_predictor predictor);
+
+ /* Return true when block A can be duplicated. */
+ bool (*can_duplicate_block_p) (basic_block a);
+
+ /* Duplicate block A. */
+ basic_block (*duplicate_block) (basic_block a);
+
/* Higher level functions representable by primitive operations above if
we didn't have some oddities in RTL and Tree representations. */
basic_block (*split_edge) (edge);
@@ -69,11 +83,28 @@ struct cfg_hooks
/* Tries to make the edge fallthru. */
void (*tidy_fallthru_edge) (edge);
+
+ /* Say whether a block ends with a call, possibly followed by some
+ other code that must stay with the call. */
+ bool (*block_ends_with_call_p) (basic_block);
+
+ /* Say whether a block ends with a conditional branch. Switches
+ and unconditional branches do not qualify. */
+ bool (*block_ends_with_condjump_p) (basic_block);
+
+ /* Add fake edges to the function exit for any non constant and non noreturn
+ calls, volatile inline assembly in the bitmap of blocks specified by
+ BLOCKS or to the whole CFG if BLOCKS is zero. Return the number of blocks
+ that were split.
+
+ The goal is to expose cases in which entering a basic block does not imply
+ that all subsequent instructions must be executed. */
+ int (*flow_call_edges_add) (sbitmap);
};
extern void verify_flow_info (void);
extern void dump_bb (basic_block, FILE *, int);
-extern bool redirect_edge_and_branch (edge, basic_block);
+extern edge redirect_edge_and_branch (edge, basic_block);
extern basic_block redirect_edge_and_branch_force (edge, basic_block);
extern edge split_block (basic_block, void *);
extern edge split_block_after_labels (basic_block);
@@ -88,13 +119,23 @@ extern edge make_forwarder_block (basic_block, bool (*)(edge),
void (*) (basic_block));
extern void tidy_fallthru_edge (edge);
extern void tidy_fallthru_edges (void);
+extern void predict_edge (edge e, enum br_predictor predictor, int probability);
+extern bool predicted_by_p (basic_block bb, enum br_predictor predictor);
+extern bool can_duplicate_block_p (basic_block);
+extern basic_block duplicate_block (basic_block, edge);
+extern bool block_ends_with_call_p (basic_block bb);
+extern bool block_ends_with_condjump_p (basic_block bb);
+extern int flow_call_edges_add (sbitmap);
/* Hooks containers. */
+extern struct cfg_hooks tree_cfg_hooks;
extern struct cfg_hooks rtl_cfg_hooks;
extern struct cfg_hooks cfg_layout_rtl_cfg_hooks;
/* Declarations. */
+extern int ir_type (void);
extern void rtl_register_cfg_hooks (void);
extern void cfg_layout_rtl_register_cfg_hooks (void);
+extern void tree_register_cfg_hooks (void);
#endif /* GCC_CFGHOOKS_H */
diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c
index c5b89ac92ad..8a57c68c2b2 100644
--- a/gcc/cfglayout.c
+++ b/gcc/cfglayout.c
@@ -41,8 +41,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
in this obstack, and all are freed at the end of the function. */
extern struct obstack flow_obstack;
-alloc_pool cfg_layout_pool;
-
/* Holds the interesting trailing notes for the function. */
rtx cfg_layout_function_footer, cfg_layout_function_header;
@@ -311,10 +309,14 @@ insn_locators_initialize (void)
switch (NOTE_LINE_NUMBER (insn))
{
case NOTE_INSN_BLOCK_BEG:
+ if (cfun->dont_emit_block_notes)
+ abort ();
block = NOTE_BLOCK (insn);
delete_insn (insn);
break;
case NOTE_INSN_BLOCK_END:
+ if (cfun->dont_emit_block_notes)
+ abort ();
block = BLOCK_SUPERCONTEXT (block);
if (block && TREE_CODE (block) == FUNCTION_DECL)
block = 0;
@@ -329,11 +331,17 @@ insn_locators_initialize (void)
break;
}
}
+
+ if (cfun->dont_emit_block_notes)
+ check_block_change (insn, &block);
}
/* Tag the blocks with a depth number so that change_scope can find
the common parent easily. */
set_block_levels (DECL_INITIAL (cfun->decl), 0);
+
+ if (cfun->dont_emit_block_notes)
+ free_block_changes ();
}
/* For each lexical block, set BLOCK_NUMBER to the depth at which it is
@@ -771,7 +779,7 @@ fixup_reorder_chain (void)
nb = force_nonfallthru (e_fall);
if (nb)
{
- cfg_layout_initialize_rbi (nb);
+ initialize_bb_rbi (nb);
nb->rbi->visited = 1;
nb->rbi->next = bb->rbi->next;
bb->rbi->next = nb;
@@ -933,20 +941,15 @@ fixup_fallthru_exit_predecessor (void)
/* Return true in case it is possible to duplicate the basic block BB. */
+/* We do not want to declare the function in a header file, since it should
+ only be used through the cfghooks interface, and we do not want to move
+ it to cfgrtl.c since it would require also moving quite a lot of related
+ code. */
+extern bool cfg_layout_can_duplicate_bb_p (basic_block);
+
bool
cfg_layout_can_duplicate_bb_p (basic_block bb)
{
- edge s;
-
- if (bb == EXIT_BLOCK_PTR || bb == ENTRY_BLOCK_PTR)
- return false;
-
- /* Duplicating fallthru block to exit would require adding a jump
- and splitting the real last BB. */
- for (s = bb->succ; s; s = s->succ_next)
- if (s->dest == EXIT_BLOCK_PTR && s->flags & EDGE_FALLTHRU)
- return false;
-
/* Do not attempt to duplicate tablejumps, as we need to unshare
the dispatch table. This is difficult to do, as the instructions
computing jump destination may be hoisted outside the basic block. */
@@ -1062,26 +1065,19 @@ duplicate_insn_chain (rtx from, rtx to)
delete_insn (last);
return insn;
}
-/* Create a duplicate of the basic block BB and redirect edge E into it.
- If E is not specified, BB is just copied, but updating the frequencies
- etc. is left to the caller. */
+/* Create a duplicate of the basic block BB. */
+
+/* We do not want to declare the function in a header file, since it should
+ only be used through the cfghooks interface, and we do not want to move
+ it to cfgrtl.c since it would require also moving quite a lot of related
+ code. */
+extern basic_block cfg_layout_duplicate_bb (basic_block);
basic_block
-cfg_layout_duplicate_bb (basic_block bb, edge e)
+cfg_layout_duplicate_bb (basic_block bb)
{
rtx insn;
- edge s, n;
basic_block new_bb;
- gcov_type new_count = e ? e->count : 0;
-
- if (bb->count < new_count)
- new_count = bb->count;
- if (!bb->pred)
- abort ();
-#ifdef ENABLE_CHECKING
- if (!cfg_layout_can_duplicate_bb_p (bb))
- abort ();
-#endif
insn = duplicate_insn_chain (BB_HEAD (bb), BB_END (bb));
new_bb = create_basic_block (insn,
@@ -1116,63 +1112,10 @@ cfg_layout_duplicate_bb (basic_block bb, edge e)
COPY_REG_SET (new_bb->global_live_at_end, bb->global_live_at_end);
}
- new_bb->loop_depth = bb->loop_depth;
- new_bb->flags = bb->flags;
- for (s = bb->succ; s; s = s->succ_next)
- {
- /* Since we are creating edges from a new block to successors
- of another block (which therefore are known to be disjoint), there
- is no need to actually check for duplicated edges. */
- n = unchecked_make_edge (new_bb, s->dest, s->flags);
- n->probability = s->probability;
- if (e && bb->count)
- {
- /* Take care for overflows! */
- n->count = s->count * (new_count * 10000 / bb->count) / 10000;
- s->count -= n->count;
- }
- else
- n->count = s->count;
- n->aux = s->aux;
- }
-
- if (e)
- {
- new_bb->count = new_count;
- bb->count -= new_count;
-
- new_bb->frequency = EDGE_FREQUENCY (e);
- bb->frequency -= EDGE_FREQUENCY (e);
-
- redirect_edge_and_branch_force (e, new_bb);
-
- if (bb->count < 0)
- bb->count = 0;
- if (bb->frequency < 0)
- bb->frequency = 0;
- }
- else
- {
- new_bb->count = bb->count;
- new_bb->frequency = bb->frequency;
- }
-
- new_bb->rbi->original = bb;
- bb->rbi->copy = new_bb;
-
return new_bb;
}
-void
-cfg_layout_initialize_rbi (basic_block bb)
-{
- if (bb->rbi)
- abort ();
- bb->rbi = pool_alloc (cfg_layout_pool);
- memset (bb->rbi, 0, sizeof (struct reorder_block_def));
-}
-
-/* Main entry point to this module - initialize the datastructures for
+/* Main entry point to this module - initialize the data structures for
CFG layout changes. It keeps LOOPS up-to-date if not null. */
void
@@ -1180,13 +1123,12 @@ cfg_layout_initialize (void)
{
basic_block bb;
- /* Our algorithm depends on fact that there are now dead jumptables
+ /* Our algorithm depends on fact that there are no dead jumptables
around the code. */
- cfg_layout_pool =
- create_alloc_pool ("cfg layout pool", sizeof (struct reorder_block_def),
- n_basic_blocks + 2);
+ alloc_rbi_pool ();
+
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
- cfg_layout_initialize_rbi (bb);
+ initialize_bb_rbi (bb);
cfg_layout_rtl_register_cfg_hooks ();
@@ -1242,7 +1184,7 @@ cfg_layout_finalize (void)
verify_insn_chain ();
#endif
- free_alloc_pool (cfg_layout_pool);
+ free_rbi_pool ();
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
bb->rbi = NULL;
@@ -1275,7 +1217,7 @@ can_copy_bbs_p (basic_block *bbs, unsigned n)
goto end;
}
- if (!cfg_layout_can_duplicate_bb_p (bbs[i]))
+ if (!can_duplicate_block_p (bbs[i]))
{
ret = false;
break;
@@ -1318,7 +1260,7 @@ copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
{
/* Duplicate. */
bb = bbs[i];
- new_bb = new_bbs[i] = cfg_layout_duplicate_bb (bb, NULL);
+ new_bb = new_bbs[i] = duplicate_block (bb, NULL);
bb->rbi->duplicated = 1;
/* Add to loop. */
add_bb_to_loop (new_bb, bb->loop_father->copy);
diff --git a/gcc/cfglayout.h b/gcc/cfglayout.h
index 0361dc68e05..b074f642633 100644
--- a/gcc/cfglayout.h
+++ b/gcc/cfglayout.h
@@ -18,31 +18,13 @@
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-/* Structure to hold information about the blocks during reordering. */
-typedef struct reorder_block_def
-{
- rtx header;
- rtx footer;
- basic_block next;
- basic_block original;
- /* Used by loop copying. */
- basic_block copy;
- int duplicated;
-
- /* These fields are used by bb-reorder pass. */
- int visited;
-} *reorder_block_def;
-
extern rtx cfg_layout_function_footer;
extern void cfg_layout_initialize (void);
extern void cfg_layout_finalize (void);
-extern bool cfg_layout_can_duplicate_bb_p (basic_block);
-extern basic_block cfg_layout_duplicate_bb (basic_block, edge);
extern void insn_locators_initialize (void);
extern void reemit_insn_block_notes (void);
extern bool can_copy_bbs_p (basic_block *, unsigned);
extern void copy_bbs (basic_block *, unsigned, basic_block *,
edge *, unsigned, edge *, struct loop *);
-extern void cfg_layout_initialize_rbi (basic_block);
extern bool scan_ahead_for_unlikely_executed_note (rtx);
diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
index 2be4b7cc0b7..3d13386ba4e 100644
--- a/gcc/cfgloop.c
+++ b/gcc/cfgloop.c
@@ -28,6 +28,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "toplev.h"
#include "cfgloop.h"
#include "flags.h"
+#include "tree.h"
+#include "tree-flow.h"
/* Ratio of frequencies of edges so that one of more latch edges is
considered to belong to inner loop with same header. */
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index b233d2652c6..d9c758408f2 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -237,6 +237,7 @@ extern void flow_loop_dump (const struct loop *, FILE *,
extern int flow_loop_scan (struct loop *, int);
extern void flow_loop_free (struct loop *);
void mark_irreducible_loops (struct loops *);
+extern void create_loop_notes (void);
/* Loop data structure manipulation/querying. */
extern void flow_loop_tree_node_add (struct loop *, struct loop *);
diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c
index 63d6f4121b0..358bfa765b8 100644
--- a/gcc/cfgloopanal.c
+++ b/gcc/cfgloopanal.c
@@ -431,9 +431,9 @@ expected_loop_iterations (const struct loop *loop)
count_in += e->count;
if (count_in == 0)
- return 0;
-
- expected = (count_latch + count_in - 1) / count_in;
+ expected = count_latch * 2;
+ else
+ expected = (count_latch + count_in - 1) / count_in;
/* Avoid overflows. */
return (expected > REG_BR_PROB_BASE ? REG_BR_PROB_BASE : expected);
@@ -452,7 +452,7 @@ expected_loop_iterations (const struct loop *loop)
freq_in += EDGE_FREQUENCY (e);
if (freq_in == 0)
- return 0;
+ return freq_latch * 2;
return (freq_latch + freq_in - 1) / freq_in;
}
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index 2dc46432aa9..9e10d8e6ccb 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -41,7 +41,7 @@ static bool rpe_enum_p (basic_block, void *);
static int find_path (edge, basic_block **);
static bool alp_enum_p (basic_block, void *);
static void add_loop (struct loops *, struct loop *);
-static void fix_loop_placements (struct loop *);
+static void fix_loop_placements (struct loops *, struct loop *);
static bool fix_bb_placement (struct loops *, basic_block);
static void fix_bb_placements (struct loops *, basic_block);
static void place_new_loop (struct loops *, struct loop *);
@@ -50,6 +50,8 @@ static void scale_bbs_frequencies (basic_block *, int, int, int);
static basic_block create_preheader (struct loop *, int);
static void fix_irreducible_loops (basic_block);
+#define RDIV(X,Y) (((X) + (Y) / 2) / (Y))
+
/* Splits basic block BB after INSN, returns created edge. Updates loops
and dominators. */
edge
@@ -411,7 +413,7 @@ remove_path (struct loops *loops, edge e)
/* Fix placements of basic blocks inside loops and the placement of
loops in the loop tree. */
fix_bb_placements (loops, from);
- fix_loop_placements (from->loop_father);
+ fix_loop_placements (loops, from->loop_father);
return true;
}
@@ -458,7 +460,7 @@ scale_bbs_frequencies (basic_block *bbs, int nbbs, int num, int den)
for (i = 0; i < nbbs; i++)
{
bbs[i]->frequency = (bbs[i]->frequency * num) / den;
- bbs[i]->count = (bbs[i]->count * num) / den;
+ bbs[i]->count = RDIV (bbs[i]->count * num, den);
for (e = bbs[i]->succ; e; e = e->succ_next)
e->count = (e->count * num) /den;
}
@@ -666,7 +668,7 @@ fix_loop_placement (struct loop *loop)
It is used in case when we removed some edges coming out of LOOP, which
may cause the right placement of LOOP inside loop tree to change. */
static void
-fix_loop_placements (struct loop *loop)
+fix_loop_placements (struct loops *loops, struct loop *loop)
{
struct loop *outer;
@@ -675,6 +677,13 @@ fix_loop_placements (struct loop *loop)
outer = loop->outer;
if (!fix_loop_placement (loop))
break;
+
+ /* Changing the placement of a loop in the loop tree may alter the
+ validity of condition 2) of the description of fix_bb_placement
+ for its preheader, because the successor is the header and belongs
+ to the loop. So call fix_bb_placements to fix up the placement
+ of the preheader and (possibly) of its predecessors. */
+ fix_bb_placements (loops, loop_preheader_edge (loop)->src);
loop = outer;
}
}
@@ -812,7 +821,6 @@ can_duplicate_loop_p (struct loop *loop)
return ret;
}
-#define RDIV(X,Y) (((X) + (Y) / 2) / (Y))
/* Duplicates body of LOOP to given edge E NDUPL times. Takes care of updating
LOOPS structure and dominators. E's destination must be LOOP header for
@@ -1234,3 +1242,99 @@ loop_split_edge_with (edge e, rtx insns)
return new_bb;
}
+
+/* Uses the natural loop discovery to recreate loop notes. */
+void
+create_loop_notes (void)
+{
+ rtx insn, head, end;
+ struct loops loops;
+ struct loop *loop;
+ basic_block *first, *last, bb, pbb;
+ struct loop **stack, **top;
+
+#ifdef ENABLE_CHECKING
+ /* Verify that there really are no loop notes. */
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ if (GET_CODE (insn) == NOTE
+ && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
+ abort ();
+#endif
+
+ flow_loops_find (&loops, LOOP_TREE);
+ free_dominance_info (CDI_DOMINATORS);
+ if (loops.num > 1)
+ {
+ last = xcalloc (loops.num, sizeof (basic_block));
+
+ FOR_EACH_BB (bb)
+ {
+ for (loop = bb->loop_father; loop->outer; loop = loop->outer)
+ last[loop->num] = bb;
+ }
+
+ first = xcalloc (loops.num, sizeof (basic_block));
+ stack = xcalloc (loops.num, sizeof (struct loop *));
+ top = stack;
+
+ FOR_EACH_BB (bb)
+ {
+ for (loop = bb->loop_father; loop->outer; loop = loop->outer)
+ {
+ if (!first[loop->num])
+ {
+ *top++ = loop;
+ first[loop->num] = bb;
+ }
+
+ if (bb == last[loop->num])
+ {
+ /* Prevent loops from overlapping. */
+ while (*--top != loop)
+ last[(*top)->num] = EXIT_BLOCK_PTR;
+
+ /* If loop starts with jump into it, place the note in
+ front of the jump. */
+ insn = PREV_INSN (BB_HEAD (first[loop->num]));
+ if (insn
+ && GET_CODE (insn) == BARRIER)
+ insn = PREV_INSN (insn);
+
+ if (insn
+ && GET_CODE (insn) == JUMP_INSN
+ && any_uncondjump_p (insn)
+ && onlyjump_p (insn))
+ {
+ pbb = BLOCK_FOR_INSN (insn);
+ if (!pbb || !pbb->succ || pbb->succ->succ_next)
+ abort ();
+
+ if (!flow_bb_inside_loop_p (loop, pbb->succ->dest))
+ insn = BB_HEAD (first[loop->num]);
+ }
+ else
+ insn = BB_HEAD (first[loop->num]);
+
+ head = BB_HEAD (first[loop->num]);
+ emit_note_before (NOTE_INSN_LOOP_BEG, insn);
+ BB_HEAD (first[loop->num]) = head;
+
+ /* Position the note correctly wrto barrier. */
+ insn = BB_END (last[loop->num]);
+ if (NEXT_INSN (insn)
+ && GET_CODE (NEXT_INSN (insn)) == BARRIER)
+ insn = NEXT_INSN (insn);
+
+ end = BB_END (last[loop->num]);
+ emit_note_after (NOTE_INSN_LOOP_END, insn);
+ BB_END (last[loop->num]) = end;
+ }
+ }
+ }
+
+ free (first);
+ free (last);
+ free (stack);
+ }
+ flow_loops_free (&loops);
+}
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index 461eb34a6f7..486128a0074 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -74,12 +74,12 @@ static basic_block rtl_split_edge (edge);
static bool rtl_move_block_after (basic_block, basic_block);
static int rtl_verify_flow_info (void);
static basic_block cfg_layout_split_block (basic_block, void *);
-static bool cfg_layout_redirect_edge_and_branch (edge, basic_block);
+static edge cfg_layout_redirect_edge_and_branch (edge, basic_block);
static basic_block cfg_layout_redirect_edge_and_branch_force (edge, basic_block);
static void cfg_layout_delete_block (basic_block);
static void rtl_delete_block (basic_block);
static basic_block rtl_redirect_edge_and_branch_force (edge, basic_block);
-static bool rtl_redirect_edge_and_branch (edge, basic_block);
+static edge rtl_redirect_edge_and_branch (edge, basic_block);
static basic_block rtl_split_block (basic_block, void *);
static void rtl_dump_bb (basic_block, FILE *, int);
static int rtl_verify_flow_info_1 (void);
@@ -259,7 +259,6 @@ create_basic_block_structure (rtx head, rtx end, rtx bb_note, basic_block after)
basic_block bb;
if (bb_note
- && ! RTX_INTEGRATED_P (bb_note)
&& (bb = NOTE_BASIC_BLOCK (bb_note)) != NULL
&& bb->aux == NULL)
{
@@ -354,7 +353,7 @@ cfg_layout_create_basic_block (void *head, void *end, basic_block after)
{
basic_block newbb = rtl_create_basic_block (head, end, after);
- cfg_layout_initialize_rbi (newbb);
+ initialize_bb_rbi (newbb);
return newbb;
}
@@ -392,8 +391,6 @@ rtl_delete_block (basic_block b)
insn = BB_HEAD (b);
- never_reached_warning (insn, BB_END (b));
-
if (GET_CODE (insn) == CODE_LABEL)
maybe_remove_eh_handler (insn);
@@ -666,7 +663,7 @@ block_label (basic_block block)
apply only if all edges now point to the same block. The parameters and
return values are equivalent to redirect_edge_and_branch. */
-bool
+edge
try_redirect_by_replacing_jump (edge e, basic_block target, bool in_cfglayout)
{
basic_block src = e->src;
@@ -690,14 +687,14 @@ try_redirect_by_replacing_jump (edge e, basic_block target, bool in_cfglayout)
break;
if (tmp || !onlyjump_p (insn))
- return false;
+ return NULL;
if ((!optimize || reload_completed) && tablejump_p (insn, NULL, NULL))
- return false;
+ return NULL;
/* Avoid removing branch with side effects. */
set = single_set (insn);
if (!set || side_effects_p (set))
- return false;
+ return NULL;
/* In case we zap a conditional jump, we'll need to kill
the cc0 setter too. */
@@ -746,21 +743,21 @@ try_redirect_by_replacing_jump (edge e, basic_block target, bool in_cfglayout)
else if (simplejump_p (insn))
{
if (e->dest == target)
- return false;
+ return NULL;
if (dump_file)
fprintf (dump_file, "Redirecting jump %i from %i to %i.\n",
INSN_UID (insn), e->dest->index, target->index);
if (!redirect_jump (insn, block_label (target), 0))
{
if (target == EXIT_BLOCK_PTR)
- return false;
+ return NULL;
abort ();
}
}
/* Cannot do anything for target exit block. */
else if (target == EXIT_BLOCK_PTR)
- return false;
+ return NULL;
/* Or replace possibly complicated jump insn by simple jump insn. */
else
@@ -834,7 +831,7 @@ try_redirect_by_replacing_jump (edge e, basic_block target, bool in_cfglayout)
if (e->dest != target)
redirect_edge_succ (e, target);
- return true;
+ return e;
}
/* Return last loop_beg note appearing after INSN, before start of next
@@ -859,8 +856,9 @@ last_loop_beg_note (rtx insn)
return last;
}
-/* Redirect edge representing branch of (un)conditional jump or tablejump. */
-static bool
+/* Redirect edge representing branch of (un)conditional jump or tablejump,
+ NULL on failure */
+static edge
redirect_branch_edge (edge e, basic_block target)
{
rtx tmp;
@@ -870,9 +868,9 @@ redirect_branch_edge (edge e, basic_block target)
/* We can only redirect non-fallthru edges of jump insn. */
if (e->flags & EDGE_FALLTHRU)
- return false;
+ return NULL;
else if (GET_CODE (insn) != JUMP_INSN)
- return false;
+ return NULL;
/* Recognize a tablejump and adjust all matching cases. */
if (tablejump_p (insn, NULL, &tmp))
@@ -882,7 +880,7 @@ redirect_branch_edge (edge e, basic_block target)
rtx new_label = block_label (target);
if (target == EXIT_BLOCK_PTR)
- return false;
+ return NULL;
if (GET_CODE (PATTERN (tmp)) == ADDR_VEC)
vec = XVEC (PATTERN (tmp), 0);
else
@@ -917,7 +915,7 @@ redirect_branch_edge (edge e, basic_block target)
if (computed_jump_p (insn)
/* A return instruction can't be redirected. */
|| returnjump_p (insn))
- return false;
+ return NULL;
/* If the insn doesn't go where we think, we're confused. */
if (JUMP_LABEL (insn) != old_label)
@@ -929,7 +927,7 @@ redirect_branch_edge (edge e, basic_block target)
if (!redirect_jump (insn, block_label (target), 0))
{
if (target == EXIT_BLOCK_PTR)
- return false;
+ return NULL;
abort ();
}
}
@@ -939,8 +937,8 @@ redirect_branch_edge (edge e, basic_block target)
e->src->index, e->dest->index, target->index);
if (e->dest != target)
- redirect_edge_succ_nodup (e, target);
- return true;
+ e = redirect_edge_succ_nodup (e, target);
+ return e;
}
/* Attempt to change code to redirect edge E to TARGET. Don't do that on
@@ -949,32 +947,35 @@ redirect_branch_edge (edge e, basic_block target)
Function can be also called with edge destination equivalent to the TARGET.
Then it should try the simplifications and do nothing if none is possible.
- Return true if transformation succeeded. We still return false in case E
- already destinated TARGET and we didn't managed to simplify instruction
- stream. */
+ Return edge representing the branch if transformation succeeded. Return NULL
+ on failure.
+ We still return NULL in case E already destinated TARGET and we didn't
+ managed to simplify instruction stream. */
-static bool
+static edge
rtl_redirect_edge_and_branch (edge e, basic_block target)
{
+ edge ret;
basic_block src = e->src;
if (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH))
- return false;
+ return NULL;
if (e->dest == target)
- return true;
+ return e;
- if (try_redirect_by_replacing_jump (e, target, false))
+ if ((ret = try_redirect_by_replacing_jump (e, target, false)) != NULL)
{
src->flags |= BB_DIRTY;
- return true;
+ return ret;
}
- if (!redirect_branch_edge (e, target))
- return false;
+ ret = redirect_branch_edge (e, target);
+ if (!ret)
+ return NULL;
src->flags |= BB_DIRTY;
- return true;
+ return ret;
}
/* Like force_nonfallthru below, but additionally performs redirection
@@ -1376,14 +1377,14 @@ insert_insn_on_edge (rtx pattern, edge e)
if ((e->flags & EDGE_ABNORMAL) && EDGE_CRITICAL_P (e))
abort ();
- if (e->insns == NULL_RTX)
+ if (e->insns.r == NULL_RTX)
start_sequence ();
else
- push_to_sequence (e->insns);
+ push_to_sequence (e->insns.r);
emit_insn (pattern);
- e->insns = get_insns ();
+ e->insns.r = get_insns ();
end_sequence ();
}
@@ -1491,8 +1492,8 @@ commit_one_edge_insertion (edge e, int watch_calls)
basic_block bb = NULL;
/* Pull the insns off the edge now since the edge might go away. */
- insns = e->insns;
- e->insns = NULL_RTX;
+ insns = e->insns.r;
+ e->insns.r = NULL_RTX;
/* Special case -- avoid inserting code between call and storing
its return value. */
@@ -1663,10 +1664,10 @@ commit_edge_insertions (void)
for (e = bb->succ; e; e = next)
{
next = e->succ_next;
- if (e->insns)
+ if (e->insns.r)
{
- changed = true;
- commit_one_edge_insertion (e, false);
+ changed = true;
+ commit_one_edge_insertion (e, false);
}
}
}
@@ -1711,7 +1712,7 @@ commit_edge_insertions_watch_calls (void)
for (e = bb->succ; e; e = next)
{
next = e->succ_next;
- if (e->insns)
+ if (e->insns.r)
{
changed = true;
commit_one_edge_insertion (e, true);
@@ -2467,23 +2468,23 @@ cfg_layout_split_block (basic_block bb, void *insnp)
/* Redirect Edge to DEST. */
-static bool
+static edge
cfg_layout_redirect_edge_and_branch (edge e, basic_block dest)
{
basic_block src = e->src;
- bool ret;
+ edge ret;
if (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH))
- return false;
+ return NULL;
if (e->dest == dest)
- return true;
+ return e;
if (e->src != ENTRY_BLOCK_PTR
- && try_redirect_by_replacing_jump (e, dest, true))
+ && (ret = try_redirect_by_replacing_jump (e, dest, true)))
{
src->flags |= BB_DIRTY;
- return true;
+ return ret;
}
if (e->src == ENTRY_BLOCK_PTR
@@ -2495,7 +2496,7 @@ cfg_layout_redirect_edge_and_branch (edge e, basic_block dest)
e->src->flags |= BB_DIRTY;
redirect_edge_succ (e, dest);
- return true;
+ return e;
}
/* Redirect_edge_and_branch may decide to turn branch into fallthru edge
@@ -2518,7 +2519,7 @@ cfg_layout_redirect_edge_and_branch (edge e, basic_block dest)
abort ();
e->flags |= EDGE_FALLTHRU;
e->src->flags |= BB_DIRTY;
- return true;
+ return e;
}
/* In case we are redirecting fallthru edge to the branch edge
of conditional jump, remove it. */
@@ -2531,13 +2532,10 @@ cfg_layout_redirect_edge_and_branch (edge e, basic_block dest)
&& onlyjump_p (BB_END (src)))
delete_insn (BB_END (src));
}
-
+ ret = redirect_edge_succ_nodup (e, dest);
if (dump_file)
fprintf (dump_file, "Fallthru edge %i->%i redirected to %i\n",
e->src->index, e->dest->index, dest->index);
- redirect_edge_succ_nodup (e, dest);
-
- ret = true;
}
else
ret = redirect_branch_edge (e, dest);
@@ -2781,6 +2779,179 @@ rtl_make_forwarder_block (edge fallthru ATTRIBUTE_UNUSED)
{
}
+/* Return 1 if BB ends with a call, possibly followed by some
+ instructions that must stay with the call, 0 otherwise. */
+
+static bool
+rtl_block_ends_with_call_p (basic_block bb)
+{
+ rtx insn = BB_END (bb);
+
+ while (GET_CODE (insn) != CALL_INSN
+ && insn != BB_HEAD (bb)
+ && keep_with_call_p (insn))
+ insn = PREV_INSN (insn);
+ return (GET_CODE (insn) == CALL_INSN);
+}
+
+/* Return 1 if BB ends with a conditional branch, 0 otherwise. */
+
+static bool
+rtl_block_ends_with_condjump_p (basic_block bb)
+{
+ return any_condjump_p (BB_END (bb));
+}
+
+/* Return true if we need to add fake edge to exit.
+ Helper function for rtl_flow_call_edges_add. */
+
+static bool
+need_fake_edge_p (rtx insn)
+{
+ if (!INSN_P (insn))
+ return false;
+
+ if ((GET_CODE (insn) == CALL_INSN
+ && !SIBLING_CALL_P (insn)
+ && !find_reg_note (insn, REG_NORETURN, NULL)
+ && !find_reg_note (insn, REG_ALWAYS_RETURN, NULL)
+ && !CONST_OR_PURE_CALL_P (insn)))
+ return true;
+
+ return ((GET_CODE (PATTERN (insn)) == ASM_OPERANDS
+ && MEM_VOLATILE_P (PATTERN (insn)))
+ || (GET_CODE (PATTERN (insn)) == PARALLEL
+ && asm_noperands (insn) != -1
+ && MEM_VOLATILE_P (XVECEXP (PATTERN (insn), 0, 0)))
+ || GET_CODE (PATTERN (insn)) == ASM_INPUT);
+}
+
+/* Add fake edges to the function exit for any non constant and non noreturn
+ calls, volatile inline assembly in the bitmap of blocks specified by
+ BLOCKS or to the whole CFG if BLOCKS is zero. Return the number of blocks
+ that were split.
+
+ The goal is to expose cases in which entering a basic block does not imply
+ that all subsequent instructions must be executed. */
+
+static int
+rtl_flow_call_edges_add (sbitmap blocks)
+{
+ int i;
+ int blocks_split = 0;
+ int last_bb = last_basic_block;
+ bool check_last_block = false;
+
+ if (n_basic_blocks == 0)
+ return 0;
+
+ if (! blocks)
+ check_last_block = true;
+ else
+ check_last_block = TEST_BIT (blocks, EXIT_BLOCK_PTR->prev_bb->index);
+
+ /* In the last basic block, before epilogue generation, there will be
+ a fallthru edge to EXIT. Special care is required if the last insn
+ of the last basic block is a call because make_edge folds duplicate
+ edges, which would result in the fallthru edge also being marked
+ fake, which would result in the fallthru edge being removed by
+ remove_fake_edges, which would result in an invalid CFG.
+
+ Moreover, we can't elide the outgoing fake edge, since the block
+ profiler needs to take this into account in order to solve the minimal
+ spanning tree in the case that the call doesn't return.
+
+ Handle this by adding a dummy instruction in a new last basic block. */
+ if (check_last_block)
+ {
+ basic_block bb = EXIT_BLOCK_PTR->prev_bb;
+ rtx insn = BB_END (bb);
+
+ /* Back up past insns that must be kept in the same block as a call. */
+ while (insn != BB_HEAD (bb)
+ && keep_with_call_p (insn))
+ insn = PREV_INSN (insn);
+
+ if (need_fake_edge_p (insn))
+ {
+ edge e;
+
+ for (e = bb->succ; e; e = e->succ_next)
+ if (e->dest == EXIT_BLOCK_PTR)
+ {
+ insert_insn_on_edge (gen_rtx_USE (VOIDmode, const0_rtx), e);
+ commit_edge_insertions ();
+ break;
+ }
+ }
+ }
+
+ /* Now add fake edges to the function exit for any non constant
+ calls since there is no way that we can determine if they will
+ return or not... */
+
+ for (i = 0; i < last_bb; i++)
+ {
+ basic_block bb = BASIC_BLOCK (i);
+ rtx insn;
+ rtx prev_insn;
+
+ if (!bb)
+ continue;
+
+ if (blocks && !TEST_BIT (blocks, i))
+ continue;
+
+ for (insn = BB_END (bb); ; insn = prev_insn)
+ {
+ prev_insn = PREV_INSN (insn);
+ if (need_fake_edge_p (insn))
+ {
+ edge e;
+ rtx split_at_insn = insn;
+
+ /* Don't split the block between a call and an insn that should
+ remain in the same block as the call. */
+ if (GET_CODE (insn) == CALL_INSN)
+ while (split_at_insn != BB_END (bb)
+ && keep_with_call_p (NEXT_INSN (split_at_insn)))
+ split_at_insn = NEXT_INSN (split_at_insn);
+
+ /* The handling above of the final block before the epilogue
+ should be enough to verify that there is no edge to the exit
+ block in CFG already. Calling make_edge in such case would
+ cause us to mark that edge as fake and remove it later. */
+
+#ifdef ENABLE_CHECKING
+ if (split_at_insn == BB_END (bb))
+ for (e = bb->succ; e; e = e->succ_next)
+ if (e->dest == EXIT_BLOCK_PTR)
+ abort ();
+#endif
+
+ /* Note that the following may create a new basic block
+ and renumber the existing basic blocks. */
+ if (split_at_insn != BB_END (bb))
+ {
+ e = split_block (bb, split_at_insn);
+ if (e)
+ blocks_split++;
+ }
+
+ make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
+ }
+
+ if (insn == BB_HEAD (bb))
+ break;
+ }
+ }
+
+ if (blocks_split)
+ verify_flow_info ();
+
+ return blocks_split;
+}
+
/* Implementation of CFG manipulation for linearized RTL. */
struct cfg_hooks rtl_cfg_hooks = {
"rtl",
@@ -2794,15 +2965,30 @@ struct cfg_hooks rtl_cfg_hooks = {
rtl_move_block_after,
rtl_can_merge_blocks, /* can_merge_blocks_p */
rtl_merge_blocks,
+ rtl_predict_edge,
+ rtl_predicted_by_p,
+ NULL, /* can_duplicate_block_p */
+ NULL, /* duplicate_block */
rtl_split_edge,
rtl_make_forwarder_block,
- rtl_tidy_fallthru_edge
+ rtl_tidy_fallthru_edge,
+ rtl_block_ends_with_call_p,
+ rtl_block_ends_with_condjump_p,
+ rtl_flow_call_edges_add
};
/* Implementation of CFG manipulation for cfg layout RTL, where
basic block connected via fallthru edges does not have to be adjacent.
This representation will hopefully become the default one in future
version of the compiler. */
+
+/* We do not want to declare these functions in a header file, since they
+ should only be used through the cfghooks interface, and we do not want to
+ move them here since it would require also moving quite a lot of related
+ code. */
+extern bool cfg_layout_can_duplicate_bb_p (basic_block);
+extern basic_block cfg_layout_duplicate_bb (basic_block);
+
struct cfg_hooks cfg_layout_rtl_cfg_hooks = {
"cfglayout mode",
rtl_verify_flow_info_1,
@@ -2815,7 +3001,15 @@ struct cfg_hooks cfg_layout_rtl_cfg_hooks = {
rtl_move_block_after,
cfg_layout_can_merge_blocks_p,
cfg_layout_merge_blocks,
+ rtl_predict_edge,
+ rtl_predicted_by_p,
+ cfg_layout_can_duplicate_bb_p,
+ cfg_layout_duplicate_bb,
cfg_layout_split_edge,
rtl_make_forwarder_block,
- NULL
+ NULL,
+ rtl_block_ends_with_call_p,
+ rtl_block_ends_with_condjump_p,
+ rtl_flow_call_edges_add
};
+
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 04049df6bf5..5669edd8f08 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -50,9 +50,9 @@ The callgraph:
Intraprocedural information:
Callgraph is place to store data needed for intraprocedural optimization.
- All datastructures are divided into three components: local_info that
+ All data structures are divided into three components: local_info that
is produced while analyzing the function, global_info that is result
- of global walkking of the callgraph on the end of compilation and
+ of global walking of the callgraph on the end of compilation and
rtl_info used by RTL backend to propagate data from already compiled
functions to their callers.
@@ -60,16 +60,16 @@ The callgraph:
The function inlining information is decided in advance and maintained
in the callgraph as so called inline plan.
- For each inlined call, the calle's node is clonned to represent the
+ For each inlined call, the callee's node is cloned to represent the
new function copy produced by inlininer.
- Each inlined call gets unque corresponding clone node of the callee
- and the datastructure is updated while inlining is performed, so
- the clones are elliminated and their callee edges redirected to the
+ Each inlined call gets a unique corresponding clone node of the callee
+ and the data structure is updated while inlining is performed, so
+ the clones are eliminated and their callee edges redirected to the
caller.
Each edge has "inline_failed" field. When the field is set to NULL,
- the call will be inlined. When it is non-NULL it contains an reason
- why inlining wasn't performaned.
+ the call will be inlined. When it is non-NULL it contains a reason
+ why inlining wasn't performed.
The varpool data structure:
@@ -99,8 +99,8 @@ The varpool data structure:
/* Hash table used to convert declarations into nodes. */
static GTY((param_is (struct cgraph_node))) htab_t cgraph_hash;
-/* We destructivly update callgraph during inlining and thus we need to
- keep information on whether inlining happent separately. */
+/* We destructively update callgraph during inlining and thus we need to
+ keep information on whether inlining happened separately. */
htab_t cgraph_inline_hash;
/* The linked list of cgraph nodes. */
@@ -152,7 +152,7 @@ eq_node (const void *p1, const void *p2)
(tree) p2);
}
-/* Allocate new callgraph node and insert it into basic datastructures. */
+/* Allocate new callgraph node and insert it into basic data structures. */
static struct cgraph_node *
cgraph_create_node (void)
{
@@ -209,7 +209,7 @@ cgraph_edge (struct cgraph_node *node, tree call_expr)
/* This loop may turn out to be performance problem. In such case adding
hashtables into call nodes with very many edges is probably best
- sollution. It is not good idea to add pointer into CALL_EXPR itself
+ solution. It is not good idea to add pointer into CALL_EXPR itself
because we want to make possible having multiple cgraph nodes representing
different clones of the same body before the body is actually cloned. */
for (e = node->callees; e; e= e->next_callee)
@@ -407,16 +407,6 @@ cgraph_mark_reachable_node (struct cgraph_node *node)
node->next_needed = cgraph_nodes_queue;
cgraph_nodes_queue = node;
-
- /* At the moment frontend automatically emits all nested functions. */
- if (node->nested)
- {
- struct cgraph_node *node2;
-
- for (node2 = node->nested; node2; node2 = node2->next_nested)
- if (!node2->reachable)
- cgraph_mark_reachable_node (node2);
- }
}
}
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 617861be1ce..c76b5dc6caf 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -30,7 +30,6 @@ struct cgraph_local_info GTY(())
{
/* Size of the function before inlining. */
int self_insns;
-
/* Set when function function is visible in current compilation unit only
and it's address is never taken. */
bool local;
@@ -66,9 +65,9 @@ struct cgraph_global_info GTY(())
struct cgraph_rtl_info GTY(())
{
+ int preferred_incoming_stack_boundary;
bool const_function;
bool pure_function;
- int preferred_incoming_stack_boundary;
};
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 7495a7595e5..c079e404ee5 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -36,7 +36,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
- cgraph_varpool_finalize_variable
- This function has same behaviour as the above but is used for static
+ This function has same behavior as the above but is used for static
variables.
- cgraph_finalize_compilation_unit
@@ -183,6 +183,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "fibheap.h"
#include "c-common.h"
#include "intl.h"
+#include "function.h"
#define INSNS_PER_CALL 10
@@ -215,6 +216,8 @@ static htab_t visited_nodes;
static bool
decide_is_function_needed (struct cgraph_node *node, tree decl)
{
+ struct cgraph_node *origin;
+
/* If we decided it was needed before, but at the time we didn't have
the body of the function available, then it's still needed. We have
to go back and re-check its dependencies now. */
@@ -251,6 +254,11 @@ decide_is_function_needed (struct cgraph_node *node, tree decl)
/* "extern inline" functions are never output locally. */
if (DECL_EXTERNAL (decl))
return false;
+ /* Nested functions of extern inline function shall not be emit unless
+ we inlined the origin. */
+ for (origin = node->origin; origin; origin = origin->origin)
+ if (DECL_EXTERNAL (origin->decl))
+ return false;
/* We want to emit COMDAT functions only when absolutely necessary. */
if (DECL_COMDAT (decl))
return false;
@@ -282,7 +290,7 @@ cgraph_assemble_pending_functions (void)
cgraph_nodes_queue = cgraph_nodes_queue->next_needed;
n->next_needed = NULL;
- if (!n->origin && !n->global.inlined_to && !DECL_EXTERNAL (n->decl))
+ if (!n->global.inlined_to && !DECL_EXTERNAL (n->decl))
{
cgraph_expand_function (n);
output = true;
@@ -323,7 +331,7 @@ cgraph_finalize_function (tree decl, bool nested)
if (node->output)
abort ();
- /* Reset our datastructures so we can analyze the function again. */
+ /* Reset our data structures so we can analyze the function again. */
memset (&node->local, 0, sizeof (node->local));
memset (&node->global, 0, sizeof (node->global));
memset (&node->rtl, 0, sizeof (node->rtl));
@@ -373,10 +381,9 @@ cgraph_finalize_function (tree decl, bool nested)
if (!TREE_ASM_WRITTEN (decl))
(*debug_hooks->deferred_inline_function) (decl);
- /* We will never really output the function body, clear the STRUCT_FUNCTION array
- early then. */
- if (DECL_EXTERNAL (decl))
- DECL_STRUCT_FUNCTION (decl) = NULL;
+ /* Possibly warn about unused parameters. */
+ if (warn_unused_parameter)
+ do_warn_unused_parameter (decl);
}
/* Walk tree and record all calls. Called via walk_tree. */
@@ -613,9 +620,7 @@ cgraph_analyze_function (struct cgraph_node *node)
cgraph_create_edges (node, DECL_SAVED_TREE (decl));
node->local.inlinable = tree_inlinable_function_p (decl);
- if (!node->local.self_insns)
- node->local.self_insns
- = lang_hooks.tree_inlining.estimate_num_insns (decl);
+ node->local.self_insns = estimate_num_insns (DECL_SAVED_TREE (decl));
if (node->local.inlinable)
node->local.disregard_inline_limits
= lang_hooks.tree_inlining.disregard_inline_limits (decl);
@@ -732,7 +737,6 @@ cgraph_finalize_compilation_unit (void)
ggc_collect ();
timevar_pop (TV_CGRAPH);
}
-
/* Figure out what functions we want to assemble. */
static void
@@ -744,7 +748,6 @@ cgraph_mark_functions_to_output (void)
{
tree decl = node->decl;
struct cgraph_edge *e;
-
if (node->output)
abort ();
@@ -759,12 +762,12 @@ cgraph_mark_functions_to_output (void)
&& !node->global.inlined_to
&& (node->needed
|| (e && node->reachable))
- && !TREE_ASM_WRITTEN (decl) && !node->origin
+ && !TREE_ASM_WRITTEN (decl)
&& !DECL_EXTERNAL (decl))
node->output = 1;
/* We should've reclaimed all functions that are not needed. */
else if (!node->global.inlined_to && DECL_SAVED_TREE (decl)
- && !node->origin && !DECL_EXTERNAL (decl))
+ && !DECL_EXTERNAL (decl))
{
dump_cgraph_node (stderr, node);
abort ();
@@ -789,15 +792,21 @@ cgraph_expand_function (struct cgraph_node *node)
/* Generate RTL for the body of DECL. Nested functions are expanded
via lang_expand_decl_stmt. */
lang_hooks.callgraph.expand_function (decl);
- if (DECL_DEFER_OUTPUT (decl))
- abort ();
- /* Make sure that BE didn't gave up on compiling. */
- if (!TREE_ASM_WRITTEN (node->decl)
- && !(sorrycount || errorcount))
+ /* Make sure that BE didn't give up on compiling. */
+ /* ??? Can happen with nested function of extern inline. */
+ if (!TREE_ASM_WRITTEN (node->decl))
abort ();
current_function_decl = NULL;
+ if (DECL_SAVED_TREE (node->decl)
+ && !cgraph_preserve_function_body_p (node->decl))
+ {
+ DECL_SAVED_TREE (node->decl) = NULL;
+ DECL_STRUCT_FUNCTION (node->decl) = NULL;
+ DECL_ARGUMENTS (node->decl) = NULL;
+ DECL_INITIAL (node->decl) = error_mark_node;
+ }
}
/* Fill array order with all nodes with output flag set in the reverse
@@ -817,7 +826,7 @@ cgraph_postorder (struct cgraph_node **order)
/* We have to deal with cycles nicely, so use a depth first traversal
output algorithm. Ignore the fact that some functions won't need
to be output and put them into order as well, so we get dependencies
- right throughout inline functions. */
+ right through intline functions. */
for (node = cgraph_nodes; node; node = node->next)
node->aux = NULL;
for (node = cgraph_nodes; node; node = node->next)
@@ -884,7 +893,8 @@ cgraph_remove_unreachable_nodes (void)
abort ();
#endif
for (node = cgraph_nodes; node; node = node->next)
- if (node->needed && (!DECL_EXTERNAL (node->decl) || !node->analyzed))
+ if (node->needed && !node->global.inlined_to
+ && (!DECL_EXTERNAL (node->decl) || !node->analyzed))
{
node->aux = first;
first = node;
@@ -915,10 +925,10 @@ cgraph_remove_unreachable_nodes (void)
/* Remove unreachable nodes. Extern inline functions need special care;
Unreachable extern inline functions shall be removed.
Reachable extern inline functions we never inlined shall get their bodies
- eliminated
+ eliminated.
Reachable extern inline functions we sometimes inlined will be turned into
unanalyzed nodes so they look like for true extern functions to the rest
- of code. Body of such functions is relased via remove_node once the
+ of code. Body of such functions is released via remove_node once the
inline clones are eliminated. */
for (node = cgraph_nodes; node; node = node->next)
{
@@ -927,6 +937,7 @@ cgraph_remove_unreachable_nodes (void)
int local_insns;
tree decl = node->decl;
+ node->global.inlined_to = NULL;
if (DECL_STRUCT_FUNCTION (decl))
local_insns = node->local.self_insns;
else
@@ -1001,7 +1012,7 @@ cgraph_estimate_growth (struct cgraph_node *node)
/* ??? Wrong for self recursive functions or cases where we decide to not
inline for different reasons, but it is not big deal as in that case
we will keep the body around, but we will also avoid some inlining. */
- if (!node->needed && !node->origin && !DECL_EXTERNAL (node->decl))
+ if (!node->needed && !DECL_EXTERNAL (node->decl))
growth -= node->global.insns;
return growth;
@@ -1017,11 +1028,10 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate)
{
struct cgraph_node *n;
- /* We may elliminate the need for out-of-line copy to be output. In that
+ /* We may eliminate the need for out-of-line copy to be output. In that
case just go ahead and re-use it. */
if (!e->callee->callers->next_caller
&& (!e->callee->needed || DECL_EXTERNAL (e->callee->decl))
- && !e->callee->origin
&& duplicate
&& flag_unit_at_a_time)
{
@@ -1042,7 +1052,7 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate)
else
e->callee->global.inlined_to = e->caller;
- /* Recursivly clone all bodies. */
+ /* Recursively clone all bodies. */
for (e = e->callee->callees; e; e = e->next_callee)
if (!e->inline_failed)
cgraph_clone_inlined_nodes (e, duplicate);
@@ -1105,7 +1115,7 @@ cgraph_mark_inline (struct cgraph_edge *edge)
struct cgraph_edge *e, *next;
int times = 0;
- /* Look for all calls, mark them inline and clone recursivly
+ /* Look for all calls, mark them inline and clone recursively
all inlined functions. */
for (e = what->callers; e; e = next)
{
@@ -1177,35 +1187,24 @@ cgraph_default_inline_p (struct cgraph_node *n)
/* Return true when inlining WHAT would create recursive inlining.
We call recursive inlining all cases where same function appears more than
- once in the single recusion nest path in the inline graph. */
+ once in the single recursion nest path in the inline graph. */
static bool
cgraph_recursive_inlining_p (struct cgraph_node *to,
struct cgraph_node *what,
const char **reason)
{
- struct cgraph_node *node;
-
- /* Walk TO and all functions TO is inlined in. */
- while (1)
- {
- /* We create recursive inlining either by inlining WHAT into something
- already inlined in possibly different clone of WHAT. */
- if (what->decl == to->decl)
- goto recursive;
- /* Or by inlining WHAT into something that is already inlined in WHAT. */
- for (node = cgraph_node (to->decl); node; node = node->next_clone)
- if (node->global.inlined_to == what)
- goto recursive;
- if (!to->callers || to->callers->inline_failed)
- return false;
- to = to->callers->caller;
- }
-recursive:
- if (reason)
+ bool recursive;
+ if (to->global.inlined_to)
+ recursive = what->decl == to->global.inlined_to->decl;
+ else
+ recursive = what->decl == to->decl;
+ /* Marking recursive function inlinine has sane semantic and thus we should
+ not warn on it. */
+ if (recursive && reason)
*reason = (what->local.disregard_inline_limits
? N_("recursive inlining") : "");
- return true;
+ return recursive;
}
/* Recompute heap nodes for each of callees. */
@@ -1223,6 +1222,110 @@ update_callee_keys (fibheap_t heap, struct fibnode **heap_node,
update_callee_keys (heap, heap_node, e->callee);
}
+/* Enqueue all recursive calls from NODE into queue linked via aux pointers
+ in between FIRST and LAST. WHERE is used for bookkeeping while looking
+ int calls inlined within NODE. */
+static void
+lookup_recursive_calls (struct cgraph_node *node, struct cgraph_node *where,
+ struct cgraph_edge **first, struct cgraph_edge **last)
+{
+ struct cgraph_edge *e;
+ for (e = where->callees; e; e = e->next_callee)
+ if (e->callee == node)
+ {
+ if (!*first)
+ *first = e;
+ else
+ (*last)->aux = e;
+ *last = e;
+ }
+ for (e = where->callees; e; e = e->next_callee)
+ if (!e->inline_failed)
+ lookup_recursive_calls (node, e->callee, first, last);
+}
+
+/* Decide on recursive inlining: in the case function has recursive calls,
+ inline until body size reaches given argument. */
+static void
+cgraph_decide_recursive_inlining (struct cgraph_node *node)
+{
+ int limit = PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RECURSIVE_AUTO);
+ int max_depth = PARAM_VALUE (PARAM_MAX_INLINE_RECURSIVE_DEPTH_AUTO);
+ struct cgraph_edge *first_call = NULL, *last_call = NULL;
+ struct cgraph_edge *last_in_current_depth;
+ struct cgraph_edge *e;
+ struct cgraph_node *master_clone;
+ int depth = 0;
+ int n = 0;
+
+ if (DECL_DECLARED_INLINE_P (node->decl))
+ {
+ limit = PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RECURSIVE);
+ max_depth = PARAM_VALUE (PARAM_MAX_INLINE_RECURSIVE_DEPTH);
+ }
+
+ /* Make sure that function is small enought to be considered for inlining. */
+ if (!max_depth
+ || cgraph_estimate_size_after_inlining (1, node, node) >= limit)
+ return;
+ lookup_recursive_calls (node, node, &first_call, &last_call);
+ if (!first_call)
+ return;
+
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file,
+ "\nPerforming recursive inlining on %s\n",
+ cgraph_node_name (node));
+
+ /* We need original clone to copy around. */
+ master_clone = cgraph_clone_node (node);
+ master_clone->needed = true;
+ for (e = master_clone->callees; e; e = e->next_callee)
+ if (!e->inline_failed)
+ cgraph_clone_inlined_nodes (e, true);
+
+ /* Do the inlining and update list of recursive call during process. */
+ last_in_current_depth = last_call;
+ while (first_call
+ && cgraph_estimate_size_after_inlining (1, node, master_clone) <= limit)
+ {
+ struct cgraph_edge *curr = first_call;
+
+ first_call = first_call->aux;
+ curr->aux = NULL;
+
+ cgraph_redirect_edge_callee (curr, master_clone);
+ cgraph_mark_inline_edge (curr);
+ lookup_recursive_calls (node, curr->callee, &first_call, &last_call);
+
+ if (last_in_current_depth
+ && ++depth >= max_depth)
+ break;
+ n++;
+ }
+
+ /* Cleanup queue pointers. */
+ while (first_call)
+ {
+ struct cgraph_edge *next = first_call->aux;
+ first_call->aux = NULL;
+ first_call = next;
+ }
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file,
+ "\n Inlined %i times, body grown from %i to %i insns\n", n,
+ master_clone->global.insns, node->global.insns);
+
+ /* Remove master clone we used for inlining. We rely that clones inlined
+ into master clone gets queued just before master clone so we don't
+ need recursion. */
+ for (node = cgraph_nodes; node != master_clone;
+ node = node->next)
+ if (node->global.inlined_to == master_clone)
+ cgraph_remove_node (node);
+ cgraph_remove_node (master_clone);
+}
+
/* Set inline_failed for all callers of given function to REASON. */
static void
@@ -1326,6 +1429,8 @@ cgraph_decide_inlining_of_small_functions (void)
}
}
+ cgraph_decide_recursive_inlining (node);
+
/* Similarly all functions called by the function we just inlined
are now called more times; update keys. */
update_callee_keys (heap, heap_node, node);
@@ -1343,7 +1448,7 @@ cgraph_decide_inlining_of_small_functions (void)
}
/* Decide on the inlining. We do so in the topological order to avoid
- expenses on updating datastructures. */
+ expenses on updating data structures. */
static void
cgraph_decide_inlining (void)
@@ -1376,38 +1481,36 @@ cgraph_decide_inlining (void)
so none of our later choices will make this impossible. */
for (i = nnodes - 1; i >= 0; i--)
{
- struct cgraph_edge *e;
+ struct cgraph_edge *e, *next;
node = order[i];
- for (e = node->callees; e; e = e->next_callee)
- if (e->callee->local.disregard_inline_limits)
- break;
- if (!e)
+ if (!node->local.disregard_inline_limits)
continue;
if (cgraph_dump_file)
fprintf (cgraph_dump_file,
"\nConsidering %s %i insns (always inline)\n",
cgraph_node_name (e->callee), e->callee->global.insns);
- for (; e; e = e->next_callee)
+ old_insns = overall_insns;
+ for (e = node->callers; e; e = next)
{
- old_insns = overall_insns;
- if (!e->inline_failed || !e->callee->local.disregard_inline_limits)
+ next = e->next_caller;
+ if (!e->inline_failed)
continue;
- if (cgraph_recursive_inlining_p (order[i], e->callee,
+ if (cgraph_recursive_inlining_p (e->caller, e->callee,
&e->inline_failed))
continue;
- cgraph_mark_inline (e);
+ cgraph_mark_inline_edge (e);
if (cgraph_dump_file)
fprintf (cgraph_dump_file,
" Inlined into %s which now has %i insns.\n",
cgraph_node_name (node->callees->caller),
node->callees->caller->global.insns);
}
- if (cgraph_dump_file)
- fprintf (cgraph_dump_file,
- " Inlined for a net change of %+i insns.\n",
- overall_insns - old_insns);
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file,
+ " Inlined for a net change of %+i insns.\n",
+ overall_insns - old_insns);
}
if (!flag_really_no_inline)
@@ -1486,7 +1589,7 @@ cgraph_decide_inlining (void)
}
/* Decide on the inlining. We do so in the topological order to avoid
- expenses on updating datastructures. */
+ expenses on updating data structures. */
static void
cgraph_decide_inlining_incrementally (struct cgraph_node *node)
@@ -1556,7 +1659,7 @@ cgraph_expand_all_functions (void)
if (order_pos != cgraph_n_nodes)
abort ();
- /* Garbage collector may remove inline clones we elliminate during
+ /* Garbage collector may remove inline clones we eliminate during
optimization. So we must be sure to not reference them. */
for (i = 0; i < order_pos; i++)
if (order[i]->output)
@@ -1668,5 +1771,25 @@ cgraph_optimize (void)
}
#ifdef ENABLE_CHECKING
verify_cgraph ();
+ /* Double check that all inline clones are gone and that all
+ function bodies have been released from memory. */
+ if (flag_unit_at_a_time
+ && !dump_enabled_p (TDI_all)
+ && !(sorrycount || errorcount))
+ {
+ struct cgraph_node *node;
+ bool error_found = false;
+
+ for (node = cgraph_nodes; node; node = node->next)
+ if (node->analyzed
+ && (node->global.inlined_to
+ || DECL_SAVED_TREE (node->decl)))
+ {
+ error_found = true;
+ dump_cgraph_node (stderr, node);
+ }
+ if (error_found)
+ internal_error ("Nodes with no released memory found.");
+ }
#endif
}
diff --git a/gcc/combine.c b/gcc/combine.c
index 568862d6b0a..2abd3d86c5c 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -143,13 +143,103 @@ static int max_uid_cuid;
static unsigned int combine_max_regno;
-/* Record last point of death of (hard or pseudo) register n. */
+struct reg_stat {
+ /* Record last point of death of (hard or pseudo) register n. */
+ rtx last_death;
-static rtx *reg_last_death;
+ /* Record last point of modification of (hard or pseudo) register n. */
+ rtx last_set;
-/* Record last point of modification of (hard or pseudo) register n. */
+ /* The next group of fields allows the recording of the last value assigned
+ to (hard or pseudo) register n. We use this information to see if an
+ operation being processed is redundant given a prior operation performed
+ on the register. For example, an `and' with a constant is redundant if
+ all the zero bits are already known to be turned off.
-static rtx *reg_last_set;
+ We use an approach similar to that used by cse, but change it in the
+ following ways:
+
+ (1) We do not want to reinitialize at each label.
+ (2) It is useful, but not critical, to know the actual value assigned
+ to a register. Often just its form is helpful.
+
+ Therefore, we maintain the following fields:
+
+ last_set_value the last value assigned
+ last_set_label records the value of label_tick when the
+ register was assigned
+ last_set_table_tick records the value of label_tick when a
+ value using the register is assigned
+ last_set_invalid set to nonzero when it is not valid
+ to use the value of this register in some
+ register's value
+
+ To understand the usage of these tables, it is important to understand
+ the distinction between the value in last_set_value being valid and
+ the register being validly contained in some other expression in the
+ table.
+
+ (The next two parameters are out of date).
+
+ reg_stat[i].last_set_value is valid if it is nonzero, and either
+ reg_n_sets[i] is 1 or reg_stat[i].last_set_label == label_tick.
+
+ Register I may validly appear in any expression returned for the value
+ of another register if reg_n_sets[i] is 1. It may also appear in the
+ value for register J if reg_stat[j].last_set_invalid is zero, or
+ reg_stat[i].last_set_label < reg_stat[j].last_set_label.
+
+ If an expression is found in the table containing a register which may
+ not validly appear in an expression, the register is replaced by
+ something that won't match, (clobber (const_int 0)). */
+
+ /* Record last value assigned to (hard or pseudo) register n. */
+
+ rtx last_set_value;
+
+ /* Record the value of label_tick when an expression involving register n
+ is placed in last_set_value. */
+
+ int last_set_table_tick;
+
+ /* Record the value of label_tick when the value for register n is placed in
+ last_set_value. */
+
+ int last_set_label;
+
+ /* These fields are maintained in parallel with last_set_value and are
+ used to store the mode in which the register was last set, te bits
+ that were known to be zero when it was last set, and the number of
+ sign bits copies it was known to have when it was last set. */
+
+ unsigned HOST_WIDE_INT last_set_nonzero_bits;
+ char last_set_sign_bit_copies;
+ ENUM_BITFIELD(machine_mode) last_set_mode : 8;
+
+ /* Set nonzero if references to register n in expressions should not be
+ used. last_set_invalid is set nonzero when this register is being
+ assigned to and last_set_table_tick == label_tick. */
+
+ char last_set_invalid;
+
+ /* Some registers that are set more than once and used in more than one
+ basic block are nevertheless always set in similar ways. For example,
+ a QImode register may be loaded from memory in two places on a machine
+ where byte loads zero extend.
+
+ We record in the following fields if a register has some leading bits
+ that are always equal to the sign bit, and what we know about the
+ nonzero bits of a register, specifically which bits are known to be
+ zero.
+
+ If an entry is zero, it means that we don't know anything special. */
+
+ unsigned char sign_bit_copies;
+
+ unsigned HOST_WIDE_INT nonzero_bits;
+};
+
+static struct reg_stat *reg_stat;
/* Record the cuid of the last insn that invalidated memory
(anything that writes memory, and subroutine calls, but not pushes). */
@@ -197,110 +287,23 @@ static basic_block this_basic_block;
those blocks as starting points. */
static sbitmap refresh_blocks;
-/* The next group of arrays allows the recording of the last value assigned
- to (hard or pseudo) register n. We use this information to see if an
- operation being processed is redundant given a prior operation performed
- on the register. For example, an `and' with a constant is redundant if
- all the zero bits are already known to be turned off.
-
- We use an approach similar to that used by cse, but change it in the
- following ways:
-
- (1) We do not want to reinitialize at each label.
- (2) It is useful, but not critical, to know the actual value assigned
- to a register. Often just its form is helpful.
-
- Therefore, we maintain the following arrays:
-
- reg_last_set_value the last value assigned
- reg_last_set_label records the value of label_tick when the
- register was assigned
- reg_last_set_table_tick records the value of label_tick when a
- value using the register is assigned
- reg_last_set_invalid set to nonzero when it is not valid
- to use the value of this register in some
- register's value
-
- To understand the usage of these tables, it is important to understand
- the distinction between the value in reg_last_set_value being valid
- and the register being validly contained in some other expression in the
- table.
-
- Entry I in reg_last_set_value is valid if it is nonzero, and either
- reg_n_sets[i] is 1 or reg_last_set_label[i] == label_tick.
-
- Register I may validly appear in any expression returned for the value
- of another register if reg_n_sets[i] is 1. It may also appear in the
- value for register J if reg_last_set_label[i] < reg_last_set_label[j] or
- reg_last_set_invalid[j] is zero.
-
- If an expression is found in the table containing a register which may
- not validly appear in an expression, the register is replaced by
- something that won't match, (clobber (const_int 0)).
-
- reg_last_set_invalid[i] is set nonzero when register I is being assigned
- to and reg_last_set_table_tick[i] == label_tick. */
-
-/* Record last value assigned to (hard or pseudo) register n. */
-
-static rtx *reg_last_set_value;
-
-/* Record the value of label_tick when the value for register n is placed in
- reg_last_set_value[n]. */
-
-static int *reg_last_set_label;
-
-/* Record the value of label_tick when an expression involving register n
- is placed in reg_last_set_value. */
-
-static int *reg_last_set_table_tick;
-
-/* Set nonzero if references to register n in expressions should not be
- used. */
-
-static char *reg_last_set_invalid;
-
/* Incremented for each label. */
static int label_tick;
-/* Some registers that are set more than once and used in more than one
- basic block are nevertheless always set in similar ways. For example,
- a QImode register may be loaded from memory in two places on a machine
- where byte loads zero extend.
-
- We record in the following array what we know about the nonzero
- bits of a register, specifically which bits are known to be zero.
-
- If an entry is zero, it means that we don't know anything special. */
-
-static unsigned HOST_WIDE_INT *reg_nonzero_bits;
-
-/* Mode used to compute significance in reg_nonzero_bits. It is the largest
- integer mode that can fit in HOST_BITS_PER_WIDE_INT. */
+/* Mode used to compute significance in reg_stat[].nonzero_bits. It is the
+ largest integer mode that can fit in HOST_BITS_PER_WIDE_INT. */
static enum machine_mode nonzero_bits_mode;
-/* Nonzero if we know that a register has some leading bits that are always
- equal to the sign bit. */
-
-static unsigned char *reg_sign_bit_copies;
-
-/* Nonzero when reg_nonzero_bits and reg_sign_bit_copies can be safely used.
- It is zero while computing them and after combine has completed. This
- former test prevents propagating values based on previously set values,
- which can be incorrect if a variable is modified in a loop. */
+/* Nonzero when reg_stat[].nonzero_bits and reg_stat[].sign_bit_copies can
+ be safely used. It is zero while computing them and after combine has
+ completed. This former test prevents propagating values based on
+ previously set values, which can be incorrect if a variable is modified
+ in a loop. */
static int nonzero_sign_valid;
-/* These arrays are maintained in parallel with reg_last_set_value
- and are used to store the mode in which the register was last set,
- the bits that were known to be zero when it was last set, and the
- number of sign bits copies it was known to have when it was last set. */
-
-static enum machine_mode *reg_last_set_mode;
-static unsigned HOST_WIDE_INT *reg_last_set_nonzero_bits;
-static char *reg_last_set_sign_bit_copies;
/* Record one modification to rtl structure
to be undone by storing old_contents into *where.
@@ -336,7 +339,7 @@ static int n_occurrences;
static void do_SUBST (rtx *, rtx);
static void do_SUBST_INT (int *, int);
-static void init_reg_last_arrays (void);
+static void init_reg_last (void);
static void setup_incoming_promotions (void);
static void set_nonzero_bits_and_sign_copies (rtx, rtx, void *);
static int cant_combine_insn_p (rtx);
@@ -523,20 +526,7 @@ combine_instructions (rtx f, unsigned int nregs)
See comments in gen_lowpart_for_combine. */
gen_lowpart = gen_lowpart_for_combine;
- reg_nonzero_bits = xcalloc (nregs, sizeof (unsigned HOST_WIDE_INT));
- reg_sign_bit_copies = xcalloc (nregs, sizeof (unsigned char));
-
- reg_last_death = xmalloc (nregs * sizeof (rtx));
- reg_last_set = xmalloc (nregs * sizeof (rtx));
- reg_last_set_value = xmalloc (nregs * sizeof (rtx));
- reg_last_set_table_tick = xmalloc (nregs * sizeof (int));
- reg_last_set_label = xmalloc (nregs * sizeof (int));
- reg_last_set_invalid = xmalloc (nregs * sizeof (char));
- reg_last_set_mode = xmalloc (nregs * sizeof (enum machine_mode));
- reg_last_set_nonzero_bits = xmalloc (nregs * sizeof (HOST_WIDE_INT));
- reg_last_set_sign_bit_copies = xmalloc (nregs * sizeof (char));
-
- init_reg_last_arrays ();
+ reg_stat = xcalloc (nregs, sizeof (struct reg_stat));
init_recog_no_volatile ();
@@ -551,8 +541,8 @@ combine_instructions (rtx f, unsigned int nregs)
nonzero_bits_mode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0);
- /* Don't use reg_nonzero_bits when computing it. This can cause problems
- when, for example, we have j <<= 1 in a loop. */
+ /* Don't use reg_stat[].nonzero_bits when computing it. This can cause
+ problems when, for example, we have j <<= 1 in a loop. */
nonzero_sign_valid = 0;
@@ -605,7 +595,7 @@ combine_instructions (rtx f, unsigned int nregs)
label_tick = 1;
last_call_cuid = 0;
mem_last_set = 0;
- init_reg_last_arrays ();
+ init_reg_last ();
setup_incoming_promotions ();
FOR_EACH_BB (this_basic_block)
@@ -768,17 +758,7 @@ combine_instructions (rtx f, unsigned int nregs)
/* Clean up. */
sbitmap_free (refresh_blocks);
- free (reg_nonzero_bits);
- free (reg_sign_bit_copies);
- free (reg_last_death);
- free (reg_last_set);
- free (reg_last_set_value);
- free (reg_last_set_table_tick);
- free (reg_last_set_label);
- free (reg_last_set_invalid);
- free (reg_last_set_mode);
- free (reg_last_set_nonzero_bits);
- free (reg_last_set_sign_bit_copies);
+ free (reg_stat);
free (uid_cuid);
{
@@ -805,22 +785,14 @@ combine_instructions (rtx f, unsigned int nregs)
return new_direct_jump_p;
}
-/* Wipe the reg_last_xxx arrays in preparation for another pass. */
+/* Wipe the last_xxx fields of reg_stat in preparation for another pass. */
static void
-init_reg_last_arrays (void)
+init_reg_last (void)
{
- unsigned int nregs = combine_max_regno;
-
- memset (reg_last_death, 0, nregs * sizeof (rtx));
- memset (reg_last_set, 0, nregs * sizeof (rtx));
- memset (reg_last_set_value, 0, nregs * sizeof (rtx));
- memset (reg_last_set_table_tick, 0, nregs * sizeof (int));
- memset (reg_last_set_label, 0, nregs * sizeof (int));
- memset (reg_last_set_invalid, 0, nregs * sizeof (char));
- memset (reg_last_set_mode, 0, nregs * sizeof (enum machine_mode));
- memset (reg_last_set_nonzero_bits, 0, nregs * sizeof (HOST_WIDE_INT));
- memset (reg_last_set_sign_bit_copies, 0, nregs * sizeof (char));
+ unsigned int i;
+ for (i = 0; i < combine_max_regno; i++)
+ memset (reg_stat + i, 0, offsetof (struct reg_stat, sign_bit_copies));
}
/* Set up any promoted values for incoming argument registers. */
@@ -878,8 +850,8 @@ set_nonzero_bits_and_sign_copies (rtx x, rtx set,
{
if (set == 0 || GET_CODE (set) == CLOBBER)
{
- reg_nonzero_bits[REGNO (x)] = GET_MODE_MASK (GET_MODE (x));
- reg_sign_bit_copies[REGNO (x)] = 1;
+ reg_stat[REGNO (x)].nonzero_bits = GET_MODE_MASK (GET_MODE (x));
+ reg_stat[REGNO (x)].sign_bit_copies = 1;
return;
}
@@ -901,7 +873,7 @@ set_nonzero_bits_and_sign_copies (rtx x, rtx set,
#ifdef SHORT_IMMEDIATES_SIGN_EXTEND
/* If X is narrower than a word and SRC is a non-negative
constant that would appear negative in the mode of X,
- sign-extend it for use in reg_nonzero_bits because some
+ sign-extend it for use in reg_stat[].nonzero_bits because some
machines (maybe most) will actually do the sign-extension
and this is the conservative approach.
@@ -920,18 +892,18 @@ set_nonzero_bits_and_sign_copies (rtx x, rtx set,
#endif
/* Don't call nonzero_bits if it cannot change anything. */
- if (reg_nonzero_bits[REGNO (x)] != ~(unsigned HOST_WIDE_INT) 0)
- reg_nonzero_bits[REGNO (x)]
+ if (reg_stat[REGNO (x)].nonzero_bits != ~(unsigned HOST_WIDE_INT) 0)
+ reg_stat[REGNO (x)].nonzero_bits
|= nonzero_bits (src, nonzero_bits_mode);
num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
- if (reg_sign_bit_copies[REGNO (x)] == 0
- || reg_sign_bit_copies[REGNO (x)] > num)
- reg_sign_bit_copies[REGNO (x)] = num;
+ if (reg_stat[REGNO (x)].sign_bit_copies == 0
+ || reg_stat[REGNO (x)].sign_bit_copies > num)
+ reg_stat[REGNO (x)].sign_bit_copies = num;
}
else
{
- reg_nonzero_bits[REGNO (x)] = GET_MODE_MASK (GET_MODE (x));
- reg_sign_bit_copies[REGNO (x)] = 1;
+ reg_stat[REGNO (x)].nonzero_bits = GET_MODE_MASK (GET_MODE (x));
+ reg_stat[REGNO (x)].sign_bit_copies = 1;
}
}
}
@@ -1101,7 +1073,7 @@ can_combine_p (rtx insn, rtx i3, rtx pred ATTRIBUTE_UNUSED, rtx succ,
does not use any registers whose values alter in between. However,
If the insns are adjacent, a use can't cross a set even though we
think it might (this can happen for a sequence of insns each setting
- the same destination; reg_last_set of that register might point to
+ the same destination; last_set of that register might point to
a NOTE). If INSN has a REG_EQUIV note, the register is always
equivalent to the memory so the substitution is valid even if there
are intervening stores. Also, don't move a volatile asm or
@@ -2331,18 +2303,18 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
&& GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != STRICT_LOW_PART
&& ! (temp = SET_DEST (XVECEXP (newpat, 0, 1)),
(GET_CODE (temp) == REG
- && reg_nonzero_bits[REGNO (temp)] != 0
+ && reg_stat[REGNO (temp)].nonzero_bits != 0
&& GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD
&& GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT
- && (reg_nonzero_bits[REGNO (temp)]
+ && (reg_stat[REGNO (temp)].nonzero_bits
!= GET_MODE_MASK (word_mode))))
&& ! (GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) == SUBREG
&& (temp = SUBREG_REG (SET_DEST (XVECEXP (newpat, 0, 1))),
(GET_CODE (temp) == REG
- && reg_nonzero_bits[REGNO (temp)] != 0
+ && reg_stat[REGNO (temp)].nonzero_bits != 0
&& GET_MODE_BITSIZE (GET_MODE (temp)) < BITS_PER_WORD
&& GET_MODE_BITSIZE (GET_MODE (temp)) < HOST_BITS_PER_INT
- && (reg_nonzero_bits[REGNO (temp)]
+ && (reg_stat[REGNO (temp)].nonzero_bits
!= GET_MODE_MASK (word_mode)))))
&& ! reg_overlap_mentioned_p (SET_DEST (XVECEXP (newpat, 0, 1)),
SET_SRC (XVECEXP (newpat, 0, 1)))
@@ -2783,9 +2755,10 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
REG_N_SETS (regno)--;
}
- /* Update reg_nonzero_bits et al for any changes that may have been made
- to this insn. The order of set_nonzero_bits_and_sign_copies() is
- important. Because newi2pat can affect nonzero_bits of newpat */
+ /* Update reg_stat[].nonzero_bits et al for any changes that may have
+ been made to this insn. The order of
+ set_nonzero_bits_and_sign_copies() is important. Because newi2pat
+ can affect nonzero_bits of newpat */
if (newi2pat)
note_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL);
note_stores (newpat, set_nonzero_bits_and_sign_copies, NULL);
@@ -4994,23 +4967,23 @@ simplify_set (rtx x)
rtx op0, op1, tmp;
int other_changed = 0;
enum machine_mode compare_mode = GET_MODE (dest);
- enum machine_mode tmp_mode;
if (GET_CODE (src) == COMPARE)
op0 = XEXP (src, 0), op1 = XEXP (src, 1);
else
op0 = src, op1 = const0_rtx;
- /* Check whether the comparison is known at compile time. */
- if (GET_MODE (op0) != VOIDmode)
- tmp_mode = GET_MODE (op0);
- else if (GET_MODE (op1) != VOIDmode)
- tmp_mode = GET_MODE (op1);
+ tmp = simplify_relational_operation (old_code, compare_mode, VOIDmode,
+ op0, op1);
+ if (!tmp)
+ new_code = old_code;
+ else if (!CONSTANT_P (tmp))
+ {
+ new_code = GET_CODE (tmp);
+ op0 = XEXP (tmp, 0);
+ op1 = XEXP (tmp, 1);
+ }
else
- tmp_mode = compare_mode;
- tmp = simplify_const_relational_operation (old_code, tmp_mode,
- op0, op1);
- if (tmp != NULL_RTX)
{
rtx pat = PATTERN (other_insn);
undobuf.other_insn = other_insn;
@@ -5031,12 +5004,15 @@ simplify_set (rtx x)
}
/* Simplify our comparison, if possible. */
- new_code = simplify_comparison (old_code, &op0, &op1);
+ new_code = simplify_comparison (new_code, &op0, &op1);
#ifdef SELECT_CC_MODE
/* If this machine has CC modes other than CCmode, check to see if we
need to use a different CC mode here. */
- compare_mode = SELECT_CC_MODE (new_code, op0, op1);
+ if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
+ compare_mode = GET_MODE (op0);
+ else
+ compare_mode = SELECT_CC_MODE (new_code, op0, op1);
#ifndef HAVE_cc0
/* If the mode changed, we have to change SET_DEST, the mode in the
@@ -6685,17 +6661,15 @@ get_pos_from_mask (unsigned HOST_WIDE_INT m, unsigned HOST_WIDE_INT *plen)
{
/* Get the bit number of the first 1 bit from the right, -1 if none. */
int pos = exact_log2 (m & -m);
- int len;
+ int len = 0;
- if (pos < 0)
- return -1;
-
- /* Now shift off the low-order zero bits and see if we have a power of
- two minus 1. */
- len = exact_log2 ((m >> pos) + 1);
+ if (pos >= 0)
+ /* Now shift off the low-order zero bits and see if we have a
+ power of two minus 1. */
+ len = exact_log2 ((m >> pos) + 1);
if (len <= 0)
- return -1;
+ pos = -1;
*plen = len;
return pos;
@@ -8168,17 +8142,17 @@ nonzero_bits1 (rtx x, enum machine_mode mode, rtx known_x,
value. Otherwise, use the previously-computed global nonzero bits
for this register. */
- if (reg_last_set_value[REGNO (x)] != 0
- && (reg_last_set_mode[REGNO (x)] == mode
- || (GET_MODE_CLASS (reg_last_set_mode[REGNO (x)]) == MODE_INT
+ if (reg_stat[REGNO (x)].last_set_value != 0
+ && (reg_stat[REGNO (x)].last_set_mode == mode
+ || (GET_MODE_CLASS (reg_stat[REGNO (x)].last_set_mode) == MODE_INT
&& GET_MODE_CLASS (mode) == MODE_INT))
- && (reg_last_set_label[REGNO (x)] == label_tick
+ && (reg_stat[REGNO (x)].last_set_label == label_tick
|| (REGNO (x) >= FIRST_PSEUDO_REGISTER
&& REG_N_SETS (REGNO (x)) == 1
&& ! REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start,
REGNO (x))))
- && INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid)
- return reg_last_set_nonzero_bits[REGNO (x)] & nonzero;
+ && INSN_CUID (reg_stat[REGNO (x)].last_set) < subst_low_cuid)
+ return reg_stat[REGNO (x)].last_set_nonzero_bits & nonzero;
tem = get_last_value (x);
@@ -8187,8 +8161,8 @@ nonzero_bits1 (rtx x, enum machine_mode mode, rtx known_x,
#ifdef SHORT_IMMEDIATES_SIGN_EXTEND
/* If X is narrower than MODE and TEM is a non-negative
constant that would appear negative in the mode of X,
- sign-extend it for use in reg_nonzero_bits because some
- machines (maybe most) will actually do the sign-extension
+ sign-extend it for use in reg_stat[].nonzero_bits because
+ some machines (maybe most) will actually do the sign-extension
and this is the conservative approach.
??? For 2.5, try to tighten up the MD files in this regard
@@ -8206,9 +8180,9 @@ nonzero_bits1 (rtx x, enum machine_mode mode, rtx known_x,
#endif
return nonzero_bits_with_known (tem, mode) & nonzero;
}
- else if (nonzero_sign_valid && reg_nonzero_bits[REGNO (x)])
+ else if (nonzero_sign_valid && reg_stat[REGNO (x)].nonzero_bits)
{
- unsigned HOST_WIDE_INT mask = reg_nonzero_bits[REGNO (x)];
+ unsigned HOST_WIDE_INT mask = reg_stat[REGNO (x)].nonzero_bits;
if (GET_MODE_BITSIZE (GET_MODE (x)) < mode_width)
/* We don't know anything about the upper bits. */
@@ -8664,23 +8638,23 @@ num_sign_bit_copies1 (rtx x, enum machine_mode mode, rtx known_x,
return GET_MODE_BITSIZE (Pmode) - GET_MODE_BITSIZE (ptr_mode) + 1;
#endif
- if (reg_last_set_value[REGNO (x)] != 0
- && reg_last_set_mode[REGNO (x)] == mode
- && (reg_last_set_label[REGNO (x)] == label_tick
+ if (reg_stat[REGNO (x)].last_set_value != 0
+ && reg_stat[REGNO (x)].last_set_mode == mode
+ && (reg_stat[REGNO (x)].last_set_label == label_tick
|| (REGNO (x) >= FIRST_PSEUDO_REGISTER
&& REG_N_SETS (REGNO (x)) == 1
&& ! REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start,
REGNO (x))))
- && INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid)
- return reg_last_set_sign_bit_copies[REGNO (x)];
+ && INSN_CUID (reg_stat[REGNO (x)].last_set) < subst_low_cuid)
+ return reg_stat[REGNO (x)].last_set_sign_bit_copies;
tem = get_last_value (x);
if (tem != 0)
return num_sign_bit_copies_with_known (tem, mode);
- if (nonzero_sign_valid && reg_sign_bit_copies[REGNO (x)] != 0
+ if (nonzero_sign_valid && reg_stat[REGNO (x)].sign_bit_copies != 0
&& GET_MODE_BITSIZE (GET_MODE (x)) == bitwidth)
- return reg_sign_bit_copies[REGNO (x)];
+ return reg_stat[REGNO (x)].sign_bit_copies;
break;
case MEM:
@@ -11364,7 +11338,7 @@ reversed_comparison (rtx exp, enum machine_mode mode, rtx op0, rtx op1)
}
/* Utility function for following routine. Called when X is part of a value
- being stored into reg_last_set_value. Sets reg_last_set_table_tick
+ being stored into last_set_value. Sets last_set_table_tick
for each register mentioned. Similar to mention_regs in cse.c */
static void
@@ -11383,7 +11357,7 @@ update_table_tick (rtx x)
unsigned int r;
for (r = regno; r < endregno; r++)
- reg_last_set_table_tick[r] = label_tick;
+ reg_stat[r].last_set_table_tick = label_tick;
return;
}
@@ -11431,8 +11405,9 @@ update_table_tick (rtx x)
/* Record that REG is set to VALUE in insn INSN. If VALUE is zero, we
are saying that the register is clobbered and we no longer know its
- value. If INSN is zero, don't update reg_last_set; this is only permitted
- with VALUE also zero and is used to invalidate the register. */
+ value. If INSN is zero, don't update reg_stat[].last_set; this is
+ only permitted with VALUE also zero and is used to invalidate the
+ register. */
static void
record_value_for_reg (rtx reg, rtx insn, rtx value)
@@ -11476,13 +11451,13 @@ record_value_for_reg (rtx reg, rtx insn, rtx value)
for (i = regno; i < endregno; i++)
{
if (insn)
- reg_last_set[i] = insn;
+ reg_stat[i].last_set = insn;
- reg_last_set_value[i] = 0;
- reg_last_set_mode[i] = 0;
- reg_last_set_nonzero_bits[i] = 0;
- reg_last_set_sign_bit_copies[i] = 0;
- reg_last_death[i] = 0;
+ reg_stat[i].last_set_value = 0;
+ reg_stat[i].last_set_mode = 0;
+ reg_stat[i].last_set_nonzero_bits = 0;
+ reg_stat[i].last_set_sign_bit_copies = 0;
+ reg_stat[i].last_death = 0;
}
/* Mark registers that are being referenced in this value. */
@@ -11498,40 +11473,40 @@ record_value_for_reg (rtx reg, rtx insn, rtx value)
for (i = regno; i < endregno; i++)
{
- reg_last_set_label[i] = label_tick;
- if (value && reg_last_set_table_tick[i] == label_tick)
- reg_last_set_invalid[i] = 1;
+ reg_stat[i].last_set_label = label_tick;
+ if (value && reg_stat[i].last_set_table_tick == label_tick)
+ reg_stat[i].last_set_invalid = 1;
else
- reg_last_set_invalid[i] = 0;
+ reg_stat[i].last_set_invalid = 0;
}
/* The value being assigned might refer to X (like in "x++;"). In that
case, we must replace it with (clobber (const_int 0)) to prevent
infinite loops. */
if (value && ! get_last_value_validate (&value, insn,
- reg_last_set_label[regno], 0))
+ reg_stat[regno].last_set_label, 0))
{
value = copy_rtx (value);
if (! get_last_value_validate (&value, insn,
- reg_last_set_label[regno], 1))
+ reg_stat[regno].last_set_label, 1))
value = 0;
}
/* For the main register being modified, update the value, the mode, the
nonzero bits, and the number of sign bit copies. */
- reg_last_set_value[regno] = value;
+ reg_stat[regno].last_set_value = value;
if (value)
{
enum machine_mode mode = GET_MODE (reg);
subst_low_cuid = INSN_CUID (insn);
- reg_last_set_mode[regno] = mode;
+ reg_stat[regno].last_set_mode = mode;
if (GET_MODE_CLASS (mode) == MODE_INT
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
mode = nonzero_bits_mode;
- reg_last_set_nonzero_bits[regno] = nonzero_bits (value, mode);
- reg_last_set_sign_bit_copies[regno]
+ reg_stat[regno].last_set_nonzero_bits = nonzero_bits (value, mode);
+ reg_stat[regno].last_set_sign_bit_copies
= num_sign_bit_copies (value, GET_MODE (reg));
}
}
@@ -11576,11 +11551,11 @@ record_dead_and_set_regs_1 (rtx dest, rtx setter, void *data)
for the things done by INSN. This is the last thing done in processing
INSN in the combiner loop.
- We update reg_last_set, reg_last_set_value, reg_last_set_mode,
- reg_last_set_nonzero_bits, reg_last_set_sign_bit_copies, reg_last_death,
- and also the similar information mem_last_set (which insn most recently
- modified memory) and last_call_cuid (which insn was the most recent
- subroutine call). */
+ We update reg_stat[], in particular fields last_set, last_set_value,
+ last_set_mode, last_set_nonzero_bits, last_set_sign_bit_copies,
+ last_death, and also the similar information mem_last_set (which insn
+ most recently modified memory) and last_call_cuid (which insn was the
+ most recent subroutine call). */
static void
record_dead_and_set_regs (rtx insn)
@@ -11600,7 +11575,7 @@ record_dead_and_set_regs (rtx insn)
: 1);
for (i = regno; i < endregno; i++)
- reg_last_death[i] = insn;
+ reg_stat[i].last_death = insn;
}
else if (REG_NOTE_KIND (link) == REG_INC)
record_value_for_reg (XEXP (link, 0), insn, NULL_RTX);
@@ -11611,11 +11586,11 @@ record_dead_and_set_regs (rtx insn)
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
{
- reg_last_set_value[i] = 0;
- reg_last_set_mode[i] = 0;
- reg_last_set_nonzero_bits[i] = 0;
- reg_last_set_sign_bit_copies[i] = 0;
- reg_last_death[i] = 0;
+ reg_stat[i].last_set_value = 0;
+ reg_stat[i].last_set_mode = 0;
+ reg_stat[i].last_set_nonzero_bits = 0;
+ reg_stat[i].last_set_sign_bit_copies = 0;
+ reg_stat[i].last_death = 0;
}
last_call_cuid = mem_last_set = INSN_CUID (insn);
@@ -11663,10 +11638,10 @@ record_promoted_value (rtx insn, rtx subreg)
continue;
}
- if (reg_last_set[regno] == insn)
+ if (reg_stat[regno].last_set == insn)
{
if (SUBREG_PROMOTED_UNSIGNED_P (subreg) > 0)
- reg_last_set_nonzero_bits[regno] &= GET_MODE_MASK (mode);
+ reg_stat[regno].last_set_nonzero_bits &= GET_MODE_MASK (mode);
}
if (GET_CODE (SET_SRC (set)) == REG)
@@ -11736,14 +11711,14 @@ get_last_value_validate (rtx *loc, rtx insn, int tick, int replace)
unsigned int j;
for (j = regno; j < endregno; j++)
- if (reg_last_set_invalid[j]
+ if (reg_stat[j].last_set_invalid
/* If this is a pseudo-register that was only set once and not
live at the beginning of the function, it is always valid. */
|| (! (regno >= FIRST_PSEUDO_REGISTER
&& REG_N_SETS (regno) == 1
&& (! REGNO_REG_SET_P
(ENTRY_BLOCK_PTR->next_bb->global_live_at_start, regno)))
- && reg_last_set_label[j] > tick))
+ && reg_stat[j].last_set_label > tick))
{
if (replace)
*loc = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
@@ -11835,7 +11810,7 @@ get_last_value (rtx x)
return 0;
regno = REGNO (x);
- value = reg_last_set_value[regno];
+ value = reg_stat[regno].last_set_value;
/* If we don't have a value, or if it isn't for this basic block and
it's either a hard register, set more than once, or it's a live
@@ -11848,7 +11823,7 @@ get_last_value (rtx x)
block. */
if (value == 0
- || (reg_last_set_label[regno] != label_tick
+ || (reg_stat[regno].last_set_label != label_tick
&& (regno < FIRST_PSEUDO_REGISTER
|| REG_N_SETS (regno) != 1
|| (REGNO_REG_SET_P
@@ -11857,20 +11832,20 @@ get_last_value (rtx x)
/* If the value was set in a later insn than the ones we are processing,
we can't use it even if the register was only set once. */
- if (INSN_CUID (reg_last_set[regno]) >= subst_low_cuid)
+ if (INSN_CUID (reg_stat[regno].last_set) >= subst_low_cuid)
return 0;
/* If the value has all its registers valid, return it. */
- if (get_last_value_validate (&value, reg_last_set[regno],
- reg_last_set_label[regno], 0))
+ if (get_last_value_validate (&value, reg_stat[regno].last_set,
+ reg_stat[regno].last_set_label, 0))
return value;
/* Otherwise, make a copy and replace any invalid register with
(clobber (const_int 0)). If that fails for some reason, return 0. */
value = copy_rtx (value);
- if (get_last_value_validate (&value, reg_last_set[regno],
- reg_last_set_label[regno], 1))
+ if (get_last_value_validate (&value, reg_stat[regno].last_set,
+ reg_stat[regno].last_set_label, 1))
return value;
return 0;
@@ -11899,8 +11874,8 @@ use_crosses_set_p (rtx x, int from_cuid)
return 1;
#endif
for (; regno < endreg; regno++)
- if (reg_last_set[regno]
- && INSN_CUID (reg_last_set[regno]) > from_cuid)
+ if (reg_stat[regno].last_set
+ && INSN_CUID (reg_stat[regno].last_set) > from_cuid)
return 1;
return 0;
}
@@ -12160,7 +12135,7 @@ move_deaths (rtx x, rtx maybe_kill_insn, int from_cuid, rtx to_insn,
if (code == REG)
{
unsigned int regno = REGNO (x);
- rtx where_dead = reg_last_death[regno];
+ rtx where_dead = reg_stat[regno].last_death;
rtx before_dead, after_dead;
/* Don't move the register if it gets killed in between from and to. */
@@ -12187,7 +12162,7 @@ move_deaths (rtx x, rtx maybe_kill_insn, int from_cuid, rtx to_insn,
rtx note = remove_death (regno, where_dead);
/* It is possible for the call above to return 0. This can occur
- when reg_last_death points to I2 or I1 that we combined with.
+ when last_death points to I2 or I1 that we combined with.
In that case make a new note.
We must also check for the case where X is a hard register
@@ -12589,6 +12564,9 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2)
libcall sequence, don't add the notes. */
else if (XEXP (note, 0) == from_insn)
tem = place = 0;
+ /* Don't add the dangling REG_RETVAL note. */
+ else if (! tem)
+ place = 0;
}
break;
@@ -12606,6 +12584,9 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2)
libcall sequence, don't add the notes. */
else if (XEXP (note, 0) == from_insn)
tem = place = 0;
+ /* Don't add the dangling REG_LIBCALL note. */
+ else if (! tem)
+ place = 0;
}
break;
@@ -12794,14 +12775,14 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2)
|| reg_bitfield_target_p (XEXP (note, 0), PATTERN (place)))
{
/* Unless the register previously died in PLACE, clear
- reg_last_death. [I no longer understand why this is
+ last_death. [I no longer understand why this is
being done.] */
- if (reg_last_death[regno] != place)
- reg_last_death[regno] = 0;
+ if (reg_stat[regno].last_death != place)
+ reg_stat[regno].last_death = 0;
place = 0;
}
else
- reg_last_death[regno] = place;
+ reg_stat[regno].last_death = place;
/* If this is a death note for a hard reg that is occupying
multiple registers, ensure that we are still using all
diff --git a/gcc/common.opt b/gcc/common.opt
index d7bed08d4ae..5309365a0f5 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -76,6 +76,10 @@ Wextra
Common
Print extra (possibly unwanted) warnings
+Wfatal-errors
+Common
+Exit on the first error occurred
+
Winline
Common
Warn when an inlined function cannot be inlined
@@ -306,6 +310,10 @@ fdiagnostics-show-location=
Common Joined RejectNegative
-fdiagnostics-show-location=[once|every-line] How often to emit source location at the beginning of line-wrapped diagnostics
+fdump-
+Common Joined RejectNegative
+-fdump-<type> Dump various compiler internals to a file
+
fdump-unnumbered
Common
Suppress output of instruction numbers and line number notes in debugging dumps
@@ -462,6 +470,18 @@ fmove-all-movables
Common
Force all loop invariant computations out of loops
+fmudflap
+Common RejectNegative
+Add mudflap bounds-checking instrumentation for single-threaded program.
+
+fmudflapth
+Common RejectNegative
+Add mudflap bounds-checking instrumentation for multi-threaded program.
+
+fmudflapir
+Common RejectNegative
+Ignore read operations when inserting mudflap instrumentation.
+
fnew-ra
Common
Use graph-coloring register allocation
@@ -708,6 +728,61 @@ ftrapv
Common
Trap for signed overflow in addition, subtraction and multiplication
+ftree-based-profiling
+Common
+Use tree-ssa based implementation of profiling
+
+ftree-ccp
+Common
+Enable SSA-CCP optimization on trees
+
+ftree-ch
+Common
+Enable loop header copying on trees
+
+ftree-combine-temps
+Common
+Coalesce memory temporaries in the SSA->normal pass
+
+ftree-copyrename
+Common
+Replace SSA temporaries with better names in copies.
+
+ftree-dce
+Common
+Enable SSA dead code elimination optimization on trees
+
+ftree-dominator-opts
+Common
+Enable dominator optimizations
+
+ftree-dse
+Common
+Enable dead store elimination
+
+ftree-loop-optimize
+Common
+Enable loop optimizations on trees
+
+ftree-points-to=
+Common Joined RejectNegative
+
+ftree-pre
+Common
+Enable SSA-PRE optimization on trees
+
+ftree-sra
+Common
+Perform scalar replacement of aggregates
+
+ftree-ter
+Common
+Replace temporary expressions in the SSA->normal pass
+
+ftree-lrs
+Common
+Perform live range splitting during the SSA->normal pass.
+
funit-at-a-time
Common
Compile whole compilation unit at a time
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 6d3cab12d95..67efab57f15 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -331,6 +331,10 @@ esac
# Common parts for widely ported systems.
case ${target} in
*-*-darwin*)
+ case ${target} in
+ *-darwin[0-6]*) ;;
+ *) tm_file="${tm_file} darwin7.h" ;;
+ esac
tm_file="${tm_file} darwin.h"
tm_p_file="${tm_p_file} darwin-protos.h"
tmake_file="t-darwin t-slibgcc-darwin"
@@ -987,6 +991,11 @@ i[34567]86-*-solaris2*)
else
tmake_file="$tmake_file t-slibgcc-sld"
fi
+ case ${target} in
+ *-*-solaris2.[789] | *-*-solaris2.1[0-9])
+ tm_file="$tm_file tm-dwarf2.h"
+ ;;
+ esac
extra_parts="crt1.o crti.o crtn.o gcrt1.o gmon.o crtbegin.o crtend.o"
case ${enable_threads}:${have_pthread_h}:${have_thread_h} in
no:*:*) ;;
@@ -1811,7 +1820,7 @@ sparc-*-rtems*)
extra_parts="crti.o crtn.o crtbegin.o crtend.o"
;;
sparc64-*-solaris2* | sparcv9-*-solaris2*)
- tm_file="sparc/biarch64.h ${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/sol2-64.h sparc/sol2-bi.h"
+ tm_file="sparc/biarch64.h ${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/sol2-64.h sparc/sol2-bi.h tm-dwarf2.h"
if test x$gnu_ld = xyes; then
tm_file="${tm_file} sparc/sol2-gld.h sparc/sol2-gld-bi.h"
fi
@@ -1850,7 +1859,7 @@ sparc-*-solaris2*)
fi
;;
*-*-solaris2.[789] | *-*-solaris2.1[0-9])
- tm_file="sparc/biarch64.h ${tm_file} sparc/sol2-bi.h"
+ tm_file="sparc/biarch64.h ${tm_file} sparc/sol2-bi.h tm-dwarf2.h"
if test x$gnu_ld = xyes; then
tm_file="${tm_file} sparc/sol2-gld-bi.h"
fi
@@ -2164,6 +2173,15 @@ if test x$with_cpu = x ; then
esac
fi
+# Similarly for --with-float
+if test x$with_float = x; then
+ case ${target} in
+ ep9312-*-*)
+ with_float=hard
+ ;;
+ esac
+fi
+
# Similarly for --with-schedule.
if test x$with_schedule = x; then
case ${target} in
@@ -2203,33 +2221,24 @@ fi
arm*-*-*)
supported_defaults="arch cpu float tune fpu abi"
for which in cpu tune; do
+ # See if it matches any of the entries in arm-cores.def
eval "val=\$with_$which"
- case "$val" in
- "" \
- | arm[236789] | arm250 | arm[67][01]0 \
- | arm60 | arm620 | arm7d | arm7di \
- | arm7m | arm7dm | arm7dmi | arm[79]tdmi \
- | arm70 | arm700i | arm710t | arm720 \
- | arm720t | arm740t | arm710c | arm920 \
- | arm920t | arm926ejs | arm940t | arm9e | arm10tdmi \
- | arm7100 | arm7500 | arm7500fe | arm810 \
- | arm1026ejs | arm1020t | arm1136js | arm1136jfs \
- | xscale | iwmmxt \
- | ep9312 \
- | strongarm | strongarm110 | strongarm11[01]0)
- # OK
- ;;
- *)
- echo "Unknown CPU used in --with-$which=$val" 1>&2
- exit 1
- ;;
- esac
+ if [ x"$val" = x ] \
+ || grep "^ARM_CORE($val," \
+ ${srcdir}/config/arm/arm-cores.def \
+ > /dev/null; then
+ # Ok
+ true
+ else
+ echo "Unknown CPU used in --with-$which=$val" 1>&2
+ exit 1
+ fi
done
case "$with_arch" in
"" \
| armv[23456] | armv2a | armv3m | armv4t | armv5t \
- | armv5te | armv6j | ep9312)
+ | armv5te | armv6j | iwmmxt | ep9312)
# OK
;;
*)
@@ -2571,10 +2580,6 @@ fi
;;
powerpc*-*-* | rs6000-*-*)
- if test x$enable_altivec = xyes
- then
- tm_file="$tm_file rs6000/altivec-defs.h"
- fi
# FIXME: The PowerPC port uses the value set at compile time,
# although it's only cosmetic.
if test "x$with_cpu" != x
diff --git a/gcc/config.in b/gcc/config.in
index 2d8f5836dc1..6f0661fd6ee 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -262,6 +262,10 @@
skip when using the GAS .p2align command. */
#undef HAVE_GAS_MAX_SKIP_P2ALIGN
+/* Define if your assembler and linker support 32-bit section relative relocs
+ via '.secrel32 label'. */
+#undef HAVE_GAS_PE_SECREL32_RELOC
+
/* Define 0/1 if your assembler supports marking sections with SHF_MERGE flag.
*/
#undef HAVE_GAS_SHF_MERGE
@@ -564,6 +568,15 @@
/* Define to `int' if <sys/types.h> does not define. */
#undef ssize_t
+/* Define if your linker supports -pie option. */
+#undef HAVE_LD_PIE
+
+/* Define if BANSHEE is available */
+#undef HAVE_BANSHEE
+
+/* Define to PREFIX/include if cpp should also search that directory. */
+#undef PREFIX_INCLUDE_DIR
+
/* Define to `int' if <sys/types.h> doesn't define. */
#undef uid_t
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index b37b311d55f..1f78205771c 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -801,9 +801,6 @@ input_operand (rtx op, enum machine_mode mode)
case CONST_INT:
return mode == QImode || mode == HImode || add_operand (op, mode);
- case CONSTANT_P_RTX:
- return 1;
-
default:
break;
}
@@ -2156,7 +2153,7 @@ alpha_rtx_costs (rtx x, int code, int outer_code, int *total)
&& const48_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
{
*total = (rtx_cost (XEXP (XEXP (x, 0), 0), outer_code)
- + rtx_cost (XEXP (x, 1), outer_code) + 2);
+ + rtx_cost (XEXP (x, 1), outer_code) + COSTS_N_INSNS (1));
return true;
}
return false;
@@ -7855,6 +7852,10 @@ alpha_expand_epilogue (void)
void
alpha_end_function (FILE *file, const char *fnname, tree decl ATTRIBUTE_UNUSED)
{
+#if TARGET_ABI_OPEN_VMS
+ alpha_write_linkage (file, fnname, decl);
+#endif
+
/* End the function. */
if (!TARGET_ABI_UNICOSMK && !flag_inhibit_size_directive)
{
@@ -7864,10 +7865,6 @@ alpha_end_function (FILE *file, const char *fnname, tree decl ATTRIBUTE_UNUSED)
}
inside_function = FALSE;
-#if TARGET_ABI_OPEN_VMS
- alpha_write_linkage (file, fnname, decl);
-#endif
-
/* Output jump tables and the static subroutine information block. */
if (TARGET_ABI_UNICOSMK)
{
diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md
index 64c88e32332..3d3b7313cc7 100644
--- a/gcc/config/alpha/alpha.md
+++ b/gcc/config/alpha/alpha.md
@@ -7185,7 +7185,7 @@
(define_expand "builtin_insbl"
[(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
@@ -7201,7 +7201,7 @@
(define_expand "builtin_inswl"
[(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
@@ -7217,7 +7217,7 @@
(define_expand "builtin_insll"
[(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
diff --git a/gcc/config/alpha/ev4.md b/gcc/config/alpha/ev4.md
index cee3ae608ee..5056fa1277a 100644
--- a/gcc/config/alpha/ev4.md
+++ b/gcc/config/alpha/ev4.md
@@ -98,7 +98,7 @@
"ev4_ist"
"store_data_bypass_p")
-; Multiplies use a non-piplined imul unit. Also, "no [ebox] insn can
+; Multiplies use a non-pipelined imul unit. Also, "no [ebox] insn can
; be issued exactly three cycles before an integer multiply completes".
(define_insn_reservation "ev4_imulsi" 21
diff --git a/gcc/config/alpha/ev5.md b/gcc/config/alpha/ev5.md
index 20757e15159..ece25d7e961 100644
--- a/gcc/config/alpha/ev5.md
+++ b/gcc/config/alpha/ev5.md
@@ -18,7 +18,7 @@
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
-;; EV5 has two asymetric integer units, E0 and E1, plus separate
+;; EV5 has two asymmetric integer units, E0 and E1, plus separate
;; FP add and multiply units.
(define_automaton "ev5_0,ev5_1")
@@ -97,7 +97,7 @@
; Conditional move and branch can issue the same cycle as the test.
(define_bypass 0 "ev5_ilogcmp" "ev5_ibr,ev5_cmov" "if_test_bypass_p")
-; Multiplies use a non-piplined imul unit. Also, "no insn can be issued
+; Multiplies use a non-pipelined imul unit. Also, "no insn can be issued
; to E0 exactly two cycles before an integer multiply completes".
(define_insn_reservation "ev5_imull" 8
@@ -136,7 +136,7 @@
(define_bypass 13 "ev5_imulq" "ev5_imull,ev5_imulq,ev5_imulh")
(define_bypass 15 "ev5_imulh" "ev5_imull,ev5_imulq,ev5_imulh")
-; Similarly for the FPU we have two asymetric units.
+; Similarly for the FPU we have two asymmetric units.
(define_insn_reservation "ev5_fadd" 4
(and (eq_attr "cpu" "ev5")
diff --git a/gcc/config/alpha/ev6.md b/gcc/config/alpha/ev6.md
index 23a09b053a3..561ca709d5d 100644
--- a/gcc/config/alpha/ev6.md
+++ b/gcc/config/alpha/ev6.md
@@ -22,7 +22,7 @@
; expected to help over-much, but a precise description can be important
; for software pipelining.
;
-; EV6 has two symmetric pairs ("clusters") of two asymetric integer
+; EV6 has two symmetric pairs ("clusters") of two asymmetric integer
; units ("upper" and "lower"), yielding pipe names U0, U1, L0, L1.
;
; ??? The clusters have independent register files that are re-synced
diff --git a/gcc/config/alpha/freebsd.h b/gcc/config/alpha/freebsd.h
index 6b10d495b97..0b293610f4c 100644
--- a/gcc/config/alpha/freebsd.h
+++ b/gcc/config/alpha/freebsd.h
@@ -20,6 +20,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#undef SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS \
{ "fbsd_dynamic_linker", FBSD_DYNAMIC_LINKER }
diff --git a/gcc/config/alpha/linux.h b/gcc/config/alpha/linux.h
index a4bc3d3e4a4..e2a16dff3db 100644
--- a/gcc/config/alpha/linux.h
+++ b/gcc/config/alpha/linux.h
@@ -1,6 +1,7 @@
/* Definitions of target machine for GNU compiler,
for Alpha Linux-based GNU systems.
- Copyright (C) 1996, 1997, 1998, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by Richard Henderson.
This file is part of GCC.
@@ -70,6 +71,11 @@ Boston, MA 02111-1307, USA. */
#define LINK_GCC_C_SEQUENCE_SPEC \
"%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
+/* Use --as-needed -lgcc_s for eh support. */
+#ifdef HAVE_LD_AS_NEEDED
+#define USE_LD_AS_NEEDED 1
+#endif
+
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
diff --git a/gcc/config/alpha/osf.h b/gcc/config/alpha/osf.h
index fd72ba38132..f8b4eca49b3 100644
--- a/gcc/config/alpha/osf.h
+++ b/gcc/config/alpha/osf.h
@@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha on OSF/1.
- Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2001, 2002, 2003
- Free Software Foundation, Inc.
+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2001, 2002, 2003,
+ 2004 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GCC.
@@ -169,6 +169,10 @@ __enable_execute_stack (void *addr) \
#define LD_INIT_SWITCH "-init"
#define LD_FINI_SWITCH "-fini"
+/* The linker needs a space after "-o". This allows -oldstyle_liblookup to
+ be passed to ld. */
+#define SWITCHES_NEED_SPACES "o"
+
/* Select a format to encode pointers in exception handling data. CODE
is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
true if the symbol may be affected by dynamic relocations.
diff --git a/gcc/config/alpha/xm-vms.h b/gcc/config/alpha/xm-vms.h
index bdac52e78aa..cf18b2f7019 100644
--- a/gcc/config/alpha/xm-vms.h
+++ b/gcc/config/alpha/xm-vms.h
@@ -1,5 +1,5 @@
/* Configuration for GNU C-compiler for openVMS/Alpha.
- Copyright (C) 1996, 1997, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 2001, 2004 Free Software Foundation, Inc.
Contributed by Klaus Kaempf (kkaempf@progis.de).
This file is part of GCC.
@@ -43,3 +43,15 @@ Boston, MA 02111-1307, USA. */
#define HOST_OBJECT_SUFFIX ".obj"
#define DUMPFILE_FORMAT "_%02d_"
+
+#define DELETE_IF_ORDINARY(NAME,ST,VERBOSE_FLAG) \
+do \
+ { \
+ while (stat (NAME, &ST) >= 0 && S_ISREG (ST.st_mode)) \
+ if (unlink (NAME) < 0) \
+ { \
+ if (VERBOSE_FLAG) \
+ perror_with_name (NAME); \
+ break; \
+ } \
+ } while (0)
diff --git a/gcc/config/arm/arm-cores.def b/gcc/config/arm/arm-cores.def
index 774ba6f10f2..cf08aa865f3 100644
--- a/gcc/config/arm/arm-cores.def
+++ b/gcc/config/arm/arm-cores.def
@@ -20,68 +20,73 @@
02111-1307, USA. */
/* Before using #include to read this file, define a macro:
-
- ARM_CORE(CORE_NAME, FLAGS)
+
+ ARM_CORE(CORE_NAME, ARCH, FLAGS, COSTS)
The CORE_NAME is the name of the core, represented as an identifier
- rather than a string constant. The FLAGS are the bitwise-or of the
- traits that apply to that core.
+ rather than a string constant.
+ ARCH is the architecture revision implemeted by the chip.
+ FLAGS are the bitwise-or of the traits that apply to that core.
+ This need not include flags implied by the architecture.
+ COSTS is the name of the rtx_costs routine to use.
If you update this table, you must update the "tune" attribute in
- arm.md. */
+ arm.md.
+
+ Some tools assume no whitespace up to the first "," in each entry. */
-ARM_CORE(arm2, FL_CO_PROC | FL_MODE26, slowmul)
-ARM_CORE(arm250, FL_CO_PROC | FL_MODE26, slowmul)
-ARM_CORE(arm3, FL_CO_PROC | FL_MODE26, slowmul)
-ARM_CORE(arm6, FL_CO_PROC | FL_MODE26 | FL_MODE32, slowmul)
-ARM_CORE(arm60, FL_CO_PROC | FL_MODE26 | FL_MODE32, slowmul)
-ARM_CORE(arm600, FL_CO_PROC | FL_MODE26 | FL_MODE32, slowmul)
-ARM_CORE(arm610, FL_MODE26 | FL_MODE32, slowmul)
-ARM_CORE(arm620, FL_CO_PROC | FL_MODE26 | FL_MODE32, slowmul)
-ARM_CORE(arm7, FL_CO_PROC | FL_MODE26 | FL_MODE32, slowmul)
+ARM_CORE(arm2, 2, FL_CO_PROC | FL_MODE26, slowmul)
+ARM_CORE(arm250, 2, FL_CO_PROC | FL_MODE26, slowmul)
+ARM_CORE(arm3, 2, FL_CO_PROC | FL_MODE26, slowmul)
+ARM_CORE(arm6, 3, FL_CO_PROC | FL_MODE26, slowmul)
+ARM_CORE(arm60, 3, FL_CO_PROC | FL_MODE26, slowmul)
+ARM_CORE(arm600, 3, FL_CO_PROC | FL_MODE26, slowmul)
+ARM_CORE(arm610, 3, FL_MODE26, slowmul)
+ARM_CORE(arm620, 3, FL_CO_PROC | FL_MODE26, slowmul)
+ARM_CORE(arm7, 3, FL_CO_PROC | FL_MODE26, slowmul)
/* arm7m doesn't exist on its own, but only with D, (and I), but
those don't alter the code, so arm7m is sometimes used. */
-ARM_CORE(arm7m, FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_ARCH3M, fastmul)
-ARM_CORE(arm7d, FL_CO_PROC | FL_MODE26 | FL_MODE32, slowmul)
-ARM_CORE(arm7dm, FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_ARCH3M, fastmul)
-ARM_CORE(arm7di, FL_CO_PROC | FL_MODE26 | FL_MODE32, slowmul)
-ARM_CORE(arm7dmi, FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_ARCH3M, fastmul)
-ARM_CORE(arm70, FL_CO_PROC | FL_MODE26 | FL_MODE32, slowmul)
-ARM_CORE(arm700, FL_CO_PROC | FL_MODE26 | FL_MODE32, slowmul)
-ARM_CORE(arm700i, FL_CO_PROC | FL_MODE26 | FL_MODE32, slowmul)
-ARM_CORE(arm710, FL_MODE26 | FL_MODE32, slowmul)
-ARM_CORE(arm720, FL_MODE26 | FL_MODE32, slowmul)
-ARM_CORE(arm710c, FL_MODE26 | FL_MODE32, slowmul)
-ARM_CORE(arm7100, FL_MODE26 | FL_MODE32, slowmul)
-ARM_CORE(arm7500, FL_MODE26 | FL_MODE32, slowmul)
+ARM_CORE(arm7m, 3M, FL_CO_PROC | FL_MODE26, fastmul)
+ARM_CORE(arm7d, 3, FL_CO_PROC | FL_MODE26, slowmul)
+ARM_CORE(arm7dm, 3M, FL_CO_PROC | FL_MODE26, fastmul)
+ARM_CORE(arm7di, 3, FL_CO_PROC | FL_MODE26, slowmul)
+ARM_CORE(arm7dmi, 3M, FL_CO_PROC | FL_MODE26, fastmul)
+ARM_CORE(arm70, 3, FL_CO_PROC | FL_MODE26, slowmul)
+ARM_CORE(arm700, 3, FL_CO_PROC | FL_MODE26, slowmul)
+ARM_CORE(arm700i, 3, FL_CO_PROC | FL_MODE26, slowmul)
+ARM_CORE(arm710, 3, FL_MODE26, slowmul)
+ARM_CORE(arm720, 3, FL_MODE26, slowmul)
+ARM_CORE(arm710c, 3, FL_MODE26, slowmul)
+ARM_CORE(arm7100, 3, FL_MODE26, slowmul)
+ARM_CORE(arm7500, 3, FL_MODE26, slowmul)
/* Doesn't have an external co-proc, but does have embedded fpa. */
-ARM_CORE(arm7500fe, FL_CO_PROC | FL_MODE26 | FL_MODE32, slowmul)
+ARM_CORE(arm7500fe, 3, FL_CO_PROC | FL_MODE26, slowmul)
/* V4 Architecture Processors */
-ARM_CORE(arm7tdmi, FL_CO_PROC | FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB, fastmul)
-ARM_CORE(arm710t, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB, fastmul)
-ARM_CORE(arm720t, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB, fastmul)
-ARM_CORE(arm740t, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB, fastmul)
-ARM_CORE(arm8, FL_MODE26 | FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_LDSCHED, fastmul)
-ARM_CORE(arm810, FL_MODE26 | FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_LDSCHED, fastmul)
-ARM_CORE(arm9, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_LDSCHED, fastmul)
-ARM_CORE(arm920, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_LDSCHED, fastmul)
-ARM_CORE(arm920t, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_LDSCHED, fastmul)
-ARM_CORE(arm940t, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_LDSCHED, fastmul)
-ARM_CORE(arm9tdmi, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_LDSCHED, fastmul)
-ARM_CORE(arm9e, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_LDSCHED, 9e)
+ARM_CORE(arm7tdmi, 4T, FL_CO_PROC , fastmul)
+ARM_CORE(arm710t, 4T, 0 , fastmul)
+ARM_CORE(arm720t, 4T, 0 , fastmul)
+ARM_CORE(arm740t, 4T, 0 , fastmul)
+ARM_CORE(arm8, 4, FL_MODE26 | FL_LDSCHED, fastmul)
+ARM_CORE(arm810, 4, FL_MODE26 | FL_LDSCHED, fastmul)
+ARM_CORE(arm9, 4T, FL_LDSCHED, fastmul)
+ARM_CORE(arm920, 4, FL_LDSCHED, fastmul)
+ARM_CORE(arm920t, 4T, FL_LDSCHED, fastmul)
+ARM_CORE(arm940t, 4T, FL_LDSCHED, fastmul)
+ARM_CORE(arm9tdmi, 4T, FL_LDSCHED, fastmul)
+ARM_CORE(arm9e, 4, FL_LDSCHED, 9e)
-ARM_CORE(ep9312, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_LDSCHED | FL_CIRRUS, fastmul)
-ARM_CORE(strongarm, FL_MODE26 | FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_LDSCHED | FL_STRONG, fastmul)
-ARM_CORE(strongarm110, FL_MODE26 | FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_LDSCHED | FL_STRONG, fastmul)
-ARM_CORE(strongarm1100, FL_MODE26 | FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_LDSCHED | FL_STRONG, fastmul)
-ARM_CORE(strongarm1110, FL_MODE26 | FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_LDSCHED | FL_STRONG, fastmul)
+ARM_CORE(ep9312, 4T, FL_LDSCHED | FL_CIRRUS, fastmul)
+ARM_CORE(strongarm, 4, FL_MODE26 | FL_LDSCHED | FL_STRONG, fastmul)
+ARM_CORE(strongarm110, 4, FL_MODE26 | FL_LDSCHED | FL_STRONG, fastmul)
+ARM_CORE(strongarm1100, 4, FL_MODE26 | FL_LDSCHED | FL_STRONG, fastmul)
+ARM_CORE(strongarm1110, 4, FL_MODE26 | FL_LDSCHED | FL_STRONG, fastmul)
/* V5 Architecture Processors */
-ARM_CORE(arm10tdmi, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_ARCH5, fastmul)
-ARM_CORE(arm1020t, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_ARCH5, fastmul)
-ARM_CORE(arm926ejs, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E, 9e)
-ARM_CORE(arm1026ejs, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E, 9e)
-ARM_CORE(xscale, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_STRONG | FL_ARCH5 | FL_ARCH5E | FL_XSCALE, xscale)
-ARM_CORE(iwmmxt, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_STRONG | FL_ARCH5 | FL_ARCH5E | FL_XSCALE | FL_IWMMXT, xscale)
+ARM_CORE(arm10tdmi, 5T, FL_LDSCHED, fastmul)
+ARM_CORE(arm1020t, 5T, FL_LDSCHED, fastmul)
+ARM_CORE(arm926ejs, 5TEJ, 0, 9e)
+ARM_CORE(arm1026ejs, 5TEJ, 0, 9e)
+ARM_CORE(xscale, 5TE, FL_LDSCHED | FL_STRONG | FL_XSCALE, xscale)
+ARM_CORE(iwmmxt, 5TE, FL_LDSCHED | FL_STRONG | FL_XSCALE | FL_IWMMXT, xscale)
/* V6 Architecture Processors */
-ARM_CORE(arm1136js, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E | FL_ARCH6, 9e)
-ARM_CORE(arm1136jfs, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E | FL_ARCH6 | FL_VFPV2, 9e)
+ARM_CORE(arm1136js, 6J, 0, 9e)
+ARM_CORE(arm1136jfs, 6J, FL_VFPV2, 9e)
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 0359fe77116..0605803a3fe 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -100,7 +100,7 @@ extern int cirrus_general_operand (rtx, enum machine_mode);
extern int cirrus_register_operand (rtx, enum machine_mode);
extern int cirrus_shift_const (rtx, enum machine_mode);
extern int cirrus_memory_offset (rtx);
-extern int vfp_mem_operand (rtx);
+extern int arm_coproc_mem_operand (rtx, bool);
extern int vfp_compare_operand (rtx, enum machine_mode);
extern int arm_float_compare_operand (rtx, enum machine_mode);
extern int arm_no_early_store_addr_dep (rtx, rtx);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 6f340df7a90..acbdb77f15b 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -158,6 +158,9 @@ static void aof_file_end (void);
static rtx arm_struct_value_rtx (tree, int);
static void arm_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
tree, int *, int);
+static bool arm_promote_prototypes (tree);
+static bool arm_default_short_enums (void);
+static bool arm_align_anon_bitfield (void);
/* Initialize the GCC target structure. */
@@ -247,7 +250,7 @@ static void arm_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
#undef TARGET_PROMOTE_FUNCTION_RETURN
#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
#undef TARGET_PROMOTE_PROTOTYPES
-#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_false
+#define TARGET_PROMOTE_PROTOTYPES arm_promote_prototypes
#undef TARGET_STRUCT_VALUE_RTX
#define TARGET_STRUCT_VALUE_RTX arm_struct_value_rtx
@@ -255,6 +258,12 @@ static void arm_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
#undef TARGET_SETUP_INCOMING_VARARGS
#define TARGET_SETUP_INCOMING_VARARGS arm_setup_incoming_varargs
+#undef TARGET_DEFAULT_SHORT_ENUMS
+#define TARGET_DEFAULT_SHORT_ENUMS arm_default_short_enums
+
+#undef TARGET_ALIGN_ANON_BITFIELD
+#define TARGET_ALIGN_ANON_BITFIELD arm_align_anon_bitfield
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Obstack for minipool constant handling. */
@@ -330,6 +339,19 @@ int arm_structure_size_boundary = DEFAULT_STRUCTURE_SIZE_BOUNDARY;
#define FL_IWMMXT (1 << 29) /* XScale v2 or "Intel Wireless MMX technology". */
+#define FL_FOR_ARCH2 0
+#define FL_FOR_ARCH3 FL_MODE32
+#define FL_FOR_ARCH3M (FL_FOR_ARCH3 | FL_ARCH3M)
+#define FL_FOR_ARCH4 (FL_FOR_ARCH3M | FL_ARCH4)
+#define FL_FOR_ARCH4T (FL_FOR_ARCH4 | FL_THUMB)
+#define FL_FOR_ARCH5 (FL_FOR_ARCH4 | FL_ARCH5)
+#define FL_FOR_ARCH5T (FL_FOR_ARCH5 | FL_THUMB)
+#define FL_FOR_ARCH5E (FL_FOR_ARCH5 | FL_ARCH5E)
+#define FL_FOR_ARCH5TE (FL_FOR_ARCH5E | FL_THUMB)
+#define FL_FOR_ARCH5TEJ FL_FOR_ARCH5TE
+#define FL_FOR_ARCH6 (FL_FOR_ARCH5TE | FL_ARCH6)
+#define FL_FOR_ARCH6J FL_FOR_ARCH6
+
/* The bits in this mask specify which
instructions we are allowed to generate. */
static unsigned long insn_flags = 0;
@@ -362,6 +384,9 @@ int arm_ld_sched = 0;
/* Nonzero if this chip is a StrongARM. */
int arm_is_strong = 0;
+/* Nonzero if this chip is a Cirrus variant. */
+int arm_arch_cirrus = 0;
+
/* Nonzero if this chip supports Intel Wireless MMX technology. */
int arm_arch_iwmmxt = 0;
@@ -418,6 +443,7 @@ struct processors
{
const char *const name;
enum processor_type core;
+ const char *arch;
const unsigned long flags;
bool (* rtx_costs) (rtx, int, int, int *);
};
@@ -427,11 +453,11 @@ struct processors
static const struct processors all_cores[] =
{
/* ARM Cores */
-#define ARM_CORE(NAME, FLAGS, COSTS) \
- {#NAME, arm_none, FLAGS, arm_##COSTS##_rtx_costs},
+#define ARM_CORE(NAME, ARCH, FLAGS, COSTS) \
+ {#NAME, arm_none, #ARCH, FLAGS | FL_FOR_ARCH##ARCH, arm_##COSTS##_rtx_costs},
#include "arm-cores.def"
#undef ARM_CORE
- {NULL, arm_none, 0, NULL}
+ {NULL, arm_none, NULL, 0, NULL}
};
static const struct processors all_architectures[] =
@@ -440,22 +466,23 @@ static const struct processors all_architectures[] =
/* We don't specify rtx_costs here as it will be figured out
from the core. */
- { "armv2", arm2, FL_CO_PROC | FL_MODE26 , NULL},
- { "armv2a", arm2, FL_CO_PROC | FL_MODE26 , NULL},
- { "armv3", arm6, FL_CO_PROC | FL_MODE26 | FL_MODE32 , NULL},
- { "armv3m", arm7m, FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_ARCH3M , NULL},
- { "armv4", arm7tdmi, FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_ARCH3M | FL_ARCH4 , NULL},
+ {"armv2", arm2, "2", FL_CO_PROC | FL_MODE26 | FL_FOR_ARCH2, NULL},
+ {"armv2a", arm2, "2", FL_CO_PROC | FL_MODE26 | FL_FOR_ARCH2, NULL},
+ {"armv3", arm6, "3", FL_CO_PROC | FL_MODE26 | FL_FOR_ARCH3, NULL},
+ {"armv3m", arm7m, "3M", FL_CO_PROC | FL_MODE26 | FL_FOR_ARCH3M, NULL},
+ {"armv4", arm7tdmi, "4", FL_CO_PROC | FL_MODE26 | FL_FOR_ARCH4, NULL},
/* Strictly, FL_MODE26 is a permitted option for v4t, but there are no
implementations that support it, so we will leave it out for now. */
- { "armv4t", arm7tdmi, FL_CO_PROC | FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB , NULL},
- { "armv5", arm10tdmi, FL_CO_PROC | FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_ARCH5 , NULL},
- { "armv5t", arm10tdmi, FL_CO_PROC | FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_ARCH5 , NULL},
- { "armv5te", arm1026ejs, FL_CO_PROC | FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E , NULL},
- { "armv6", arm1136js, FL_CO_PROC | FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E | FL_ARCH6 , NULL},
- { "armv6j", arm1136js, FL_CO_PROC | FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E | FL_ARCH6 , NULL},
- { "ep9312", ep9312, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_LDSCHED | FL_CIRRUS , NULL},
- {"iwmmxt", iwmmxt, FL_MODE32 | FL_ARCH3M | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_STRONG | FL_ARCH5 | FL_ARCH5E | FL_XSCALE | FL_IWMMXT , NULL},
- { NULL, arm_none, 0 , NULL}
+ {"armv4t", arm7tdmi, "4T", FL_CO_PROC | FL_FOR_ARCH4T, NULL},
+ {"armv5", arm10tdmi, "5", FL_CO_PROC | FL_FOR_ARCH5, NULL},
+ {"armv5t", arm10tdmi, "5T", FL_CO_PROC | FL_FOR_ARCH5T, NULL},
+ {"armv5e", arm1026ejs, "5E", FL_CO_PROC | FL_FOR_ARCH5E, NULL},
+ {"armv5te", arm1026ejs, "5TE", FL_CO_PROC | FL_FOR_ARCH5TE, NULL},
+ {"armv6", arm1136js, "6", FL_CO_PROC | FL_FOR_ARCH6, NULL},
+ {"armv6j", arm1136js, "6J", FL_CO_PROC | FL_FOR_ARCH6J, NULL},
+ {"ep9312", ep9312, "4T", FL_LDSCHED | FL_CIRRUS | FL_FOR_ARCH4, NULL},
+ {"iwmmxt", iwmmxt, "5TE", FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT , NULL},
+ {NULL, arm_none, NULL, 0 , NULL}
};
/* This is a magic structure. The 'string' field is magically filled in
@@ -470,6 +497,11 @@ struct arm_cpu_select arm_select[] =
{ NULL, "-mtune=", all_cores }
};
+
+/* The name of the proprocessor macro to define for this architecture. */
+
+char arm_arch_name[] = "__ARM_ARCH_0UNK__";
+
struct fpu_desc
{
const char * name;
@@ -572,6 +604,10 @@ arm_override_options (void)
for (sel = ptr->processors; sel->name != NULL; sel++)
if (streq (ptr->string, sel->name))
{
+ /* Set the architecture define. */
+ if (i != 2)
+ sprintf (arm_arch_name, "__ARM_ARCH_%s__", sel->arch);
+
/* Determine the processor core for which we should
tune code-generation. */
if (/* -mcpu= is a sensible default. */
@@ -610,52 +646,21 @@ arm_override_options (void)
{
const struct processors * sel;
unsigned int sought;
- static const struct cpu_default
- {
- const int cpu;
- const char *const name;
- }
- cpu_defaults[] =
- {
- { TARGET_CPU_arm2, "arm2" },
- { TARGET_CPU_arm6, "arm6" },
- { TARGET_CPU_arm610, "arm610" },
- { TARGET_CPU_arm710, "arm710" },
- { TARGET_CPU_arm7m, "arm7m" },
- { TARGET_CPU_arm7500fe, "arm7500fe" },
- { TARGET_CPU_arm7tdmi, "arm7tdmi" },
- { TARGET_CPU_arm8, "arm8" },
- { TARGET_CPU_arm810, "arm810" },
- { TARGET_CPU_arm9, "arm9" },
- { TARGET_CPU_strongarm, "strongarm" },
- { TARGET_CPU_xscale, "xscale" },
- { TARGET_CPU_ep9312, "ep9312" },
- { TARGET_CPU_iwmmxt, "iwmmxt" },
- { TARGET_CPU_arm926ejs, "arm926ejs" },
- { TARGET_CPU_arm1026ejs, "arm1026ejs" },
- { TARGET_CPU_arm1136js, "arm1136js" },
- { TARGET_CPU_arm1136jfs, "arm1136jfs" },
- { TARGET_CPU_generic, "arm" },
- { 0, 0 }
- };
- const struct cpu_default * def;
-
- /* Find the default. */
- for (def = cpu_defaults; def->name; def++)
- if (def->cpu == TARGET_CPU_DEFAULT)
- break;
+ enum processor_type cpu;
- /* Make sure we found the default CPU. */
- if (def->name == NULL)
- abort ();
-
- /* Find the default CPU's flags. */
- for (sel = all_cores; sel->name != NULL; sel++)
- if (streq (def->name, sel->name))
- break;
-
- if (sel->name == NULL)
- abort ();
+ cpu = TARGET_CPU_DEFAULT;
+ if (cpu == arm_none)
+ {
+#ifdef SUBTARGET_CPU_DEFAULT
+ /* Use the subtarget default CPU if none was specified by
+ configure. */
+ cpu = SUBTARGET_CPU_DEFAULT;
+#endif
+ /* Default to ARM6. */
+ if (cpu == arm_none)
+ cpu = arm6;
+ }
+ sel = &all_cores[cpu];
insn_flags = sel->flags;
@@ -728,6 +733,7 @@ arm_override_options (void)
insn_flags = sel->flags;
}
+ sprintf (arm_arch_name, "__ARM_ARCH_%s__", sel->arch);
if (arm_tune == arm_none)
arm_tune = (enum processor_type) (sel - all_cores);
}
@@ -833,6 +839,7 @@ arm_override_options (void)
arm_arch5e = (insn_flags & FL_ARCH5E) != 0;
arm_arch6 = (insn_flags & FL_ARCH6) != 0;
arm_arch_xscale = (insn_flags & FL_XSCALE) != 0;
+ arm_arch_cirrus = (insn_flags & FL_CIRRUS) != 0;
arm_ld_sched = (tune_flags & FL_LDSCHED) != 0;
arm_is_strong = (tune_flags & FL_STRONG) != 0;
@@ -894,14 +901,17 @@ arm_override_options (void)
else
{
#ifdef FPUTYPE_DEFAULT
- /* Use the default is it is specified for this platform. */
+ /* Use the default if it is specified for this platform. */
arm_fpu_arch = FPUTYPE_DEFAULT;
arm_fpu_tune = FPUTYPE_DEFAULT;
#else
/* Pick one based on CPU type. */
+ /* ??? Some targets assume FPA is the default.
if ((insn_flags & FL_VFP) != 0)
arm_fpu_arch = FPUTYPE_VFP;
- else if (insn_flags & FL_CIRRUS)
+ else
+ */
+ if (arm_arch_cirrus)
arm_fpu_arch = FPUTYPE_MAVERICK;
else
arm_fpu_arch = FPUTYPE_FPA_EMU2;
@@ -1114,7 +1124,7 @@ arm_compute_func_type (void)
&& TREE_THIS_VOLATILE (current_function_decl))
type |= ARM_FT_VOLATILE;
- if (current_function_needs_context)
+ if (cfun->static_chain_decl != NULL)
type |= ARM_FT_NESTED;
attr = DECL_ATTRIBUTES (current_function_decl);
@@ -2317,11 +2327,8 @@ arm_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype,
bool
arm_needs_doubleword_align (enum machine_mode mode, tree type)
{
- return (mode == DImode
- || mode == DFmode
- || VECTOR_MODE_SUPPORTED_P (mode)
- || (mode == BLKmode
- && TYPE_ALIGN (type) > PARM_BOUNDARY));
+ return (GET_MODE_ALIGNMENT (mode) > PARM_BOUNDARY
+ || (type && TYPE_ALIGN (type) > PARM_BOUNDARY));
}
@@ -2984,25 +2991,44 @@ int
arm_legitimate_address_p (enum machine_mode mode, rtx x, RTX_CODE outer,
int strict_p)
{
+ bool use_ldrd;
+ enum rtx_code code = GET_CODE (x);
+
if (arm_address_register_rtx_p (x, strict_p))
return 1;
- else if (GET_CODE (x) == POST_INC || GET_CODE (x) == PRE_DEC)
+ use_ldrd = (TARGET_LDRD
+ && (mode == DImode
+ || (mode == DFmode && (TARGET_SOFT_FLOAT || TARGET_VFP))));
+
+ if (code == POST_INC || code == PRE_DEC
+ || ((code == PRE_INC || code == POST_DEC)
+ && (use_ldrd || GET_MODE_SIZE (mode) <= 4)))
return arm_address_register_rtx_p (XEXP (x, 0), strict_p);
- else if ((GET_CODE (x) == POST_MODIFY || GET_CODE (x) == PRE_MODIFY)
- && GET_MODE_SIZE (mode) <= 4
+ else if ((code == POST_MODIFY || code == PRE_MODIFY)
&& arm_address_register_rtx_p (XEXP (x, 0), strict_p)
&& GET_CODE (XEXP (x, 1)) == PLUS
- && XEXP (XEXP (x, 1), 0) == XEXP (x, 0))
- return arm_legitimate_index_p (mode, XEXP (XEXP (x, 1), 1), outer,
- strict_p);
+ && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
+ {
+ rtx addend = XEXP (XEXP (x, 1), 1);
+
+ /* Don't allow ldrd post increment by register becuase it's hard
+ to fixup invalid register choices. */
+ if (use_ldrd
+ && GET_CODE (x) == POST_MODIFY
+ && GET_CODE (addend) == REG)
+ return 0;
+
+ return ((use_ldrd || GET_MODE_SIZE (mode) <= 4)
+ && arm_legitimate_index_p (mode, addend, outer, strict_p));
+ }
/* After reload constants split into minipools will have addresses
from a LABEL_REF. */
else if (reload_completed
- && (GET_CODE (x) == LABEL_REF
- || (GET_CODE (x) == CONST
+ && (code == LABEL_REF
+ || (code == CONST
&& GET_CODE (XEXP (x, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF
&& GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)))
@@ -3011,38 +3037,7 @@ arm_legitimate_address_p (enum machine_mode mode, rtx x, RTX_CODE outer,
else if (mode == TImode)
return 0;
- else if (mode == DImode || (TARGET_SOFT_FLOAT && mode == DFmode))
- {
- if (GET_CODE (x) == PLUS
- && arm_address_register_rtx_p (XEXP (x, 0), strict_p)
- && GET_CODE (XEXP (x, 1)) == CONST_INT)
- {
- HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
-
- if (val == 4 || val == -4 || val == -8)
- return 1;
- }
- }
-
- else if (TARGET_HARD_FLOAT && TARGET_VFP && mode == DFmode)
- {
- if (GET_CODE (x) == PLUS
- && arm_address_register_rtx_p (XEXP (x, 0), strict_p)
- && GET_CODE (XEXP (x, 1)) == CONST_INT)
- {
- HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
-
- /* ??? valid arm offsets are a subset of VFP offsets.
- For now only allow this subset. Proper fix is to add an
- additional memory constraint for arm address modes.
- Alternatively allow full vfp addressing and let
- output_move_double fix it up with a sub-optimal sequence. */
- if (val == 4 || val == -4 || val == -8)
- return 1;
- }
- }
-
- else if (GET_CODE (x) == PLUS)
+ else if (code == PLUS)
{
rtx xop0 = XEXP (x, 0);
rtx xop1 = XEXP (x, 1);
@@ -3066,17 +3061,12 @@ arm_legitimate_address_p (enum machine_mode mode, rtx x, RTX_CODE outer,
#endif
else if (GET_MODE_CLASS (mode) != MODE_FLOAT
- && GET_CODE (x) == SYMBOL_REF
+ && code == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (x)
&& ! (flag_pic
&& symbol_mentioned_p (get_pool_constant (x))))
return 1;
- else if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == POST_DEC)
- && (GET_MODE_SIZE (mode) <= 4)
- && arm_address_register_rtx_p (XEXP (x, 0), strict_p))
- return 1;
-
return 0;
}
@@ -3089,25 +3079,39 @@ arm_legitimate_index_p (enum machine_mode mode, rtx index, RTX_CODE outer,
HOST_WIDE_INT range;
enum rtx_code code = GET_CODE (index);
- if (TARGET_HARD_FLOAT && TARGET_FPA && GET_MODE_CLASS (mode) == MODE_FLOAT)
+ /* Standard coprocessor addressing modes. */
+ if (TARGET_HARD_FLOAT
+ && (TARGET_FPA || TARGET_MAVERICK)
+ && (GET_MODE_CLASS (mode) == MODE_FLOAT
+ || (TARGET_MAVERICK && mode == DImode)))
return (code == CONST_INT && INTVAL (index) < 1024
&& INTVAL (index) > -1024
&& (INTVAL (index) & 3) == 0);
- if (TARGET_HARD_FLOAT && TARGET_MAVERICK
- && (GET_MODE_CLASS (mode) == MODE_FLOAT || mode == DImode))
+ if (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (mode))
return (code == CONST_INT
- && INTVAL (index) < 255
- && INTVAL (index) > -255);
+ && INTVAL (index) < 1024
+ && INTVAL (index) > -1024
+ && (INTVAL (index) & 3) == 0);
if (arm_address_register_rtx_p (index, strict_p)
- && GET_MODE_SIZE (mode) <= 4)
+ && (GET_MODE_SIZE (mode) <= 4))
return 1;
- if (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (mode))
- return (code == CONST_INT
- && INTVAL (index) < 256
- && INTVAL (index) > -256);
+ if (mode == DImode || mode == DFmode)
+ {
+ if (code == CONST_INT)
+ {
+ HOST_WIDE_INT val = INTVAL (index);
+
+ if (TARGET_LDRD)
+ return val > -256 && val < 256;
+ else
+ return val == 4 || val == -4 || val == -8;
+ }
+
+ return TARGET_LDRD && arm_address_register_rtx_p (index, strict_p);
+ }
if (GET_MODE_SIZE (mode) <= 4
&& ! (arm_arch4
@@ -4616,14 +4620,15 @@ cirrus_shift_const (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
}
-/* Return TRUE if OP is a valid VFP memory address pattern. */
-/* Copied from cirrus_memory_offset but with restricted offset range. */
+/* Return TRUE if OP is a valid VFP memory address pattern.
+ WB if true if writeback address modes are allowed. */
int
-vfp_mem_operand (rtx op)
+arm_coproc_mem_operand (rtx op, bool wb)
{
- /* Reject eliminable registers. */
+ rtx ind;
+ /* Reject eliminable registers. */
if (! (reload_in_progress || reload_completed)
&& ( reg_mentioned_p (frame_pointer_rtx, op)
|| reg_mentioned_p (arg_pointer_rtx, op)
@@ -4634,35 +4639,49 @@ vfp_mem_operand (rtx op)
return FALSE;
/* Constants are converted into offsets from labels. */
- if (GET_CODE (op) == MEM)
- {
- rtx ind;
-
- ind = XEXP (op, 0);
+ if (GET_CODE (op) != MEM)
+ return FALSE;
- if (reload_completed
- && (GET_CODE (ind) == LABEL_REF
- || (GET_CODE (ind) == CONST
- && GET_CODE (XEXP (ind, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (ind, 0), 0)) == LABEL_REF
- && GET_CODE (XEXP (XEXP (ind, 0), 1)) == CONST_INT)))
- return TRUE;
+ ind = XEXP (op, 0);
- /* Match: (mem (reg)). */
- if (GET_CODE (ind) == REG)
- return arm_address_register_rtx_p (ind, 0);
+ if (reload_completed
+ && (GET_CODE (ind) == LABEL_REF
+ || (GET_CODE (ind) == CONST
+ && GET_CODE (XEXP (ind, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (ind, 0), 0)) == LABEL_REF
+ && GET_CODE (XEXP (XEXP (ind, 0), 1)) == CONST_INT)))
+ return TRUE;
- /* Match:
- (mem (plus (reg)
- (const))). */
- if (GET_CODE (ind) == PLUS
- && GET_CODE (XEXP (ind, 0)) == REG
- && REG_MODE_OK_FOR_BASE_P (XEXP (ind, 0), VOIDmode)
- && GET_CODE (XEXP (ind, 1)) == CONST_INT
- && INTVAL (XEXP (ind, 1)) > -1024
- && INTVAL (XEXP (ind, 1)) < 1024)
- return TRUE;
- }
+ /* Match: (mem (reg)). */
+ if (GET_CODE (ind) == REG)
+ return arm_address_register_rtx_p (ind, 0);
+
+ /* Autoincremment addressing modes. */
+ if (wb
+ && (GET_CODE (ind) == PRE_INC
+ || GET_CODE (ind) == POST_INC
+ || GET_CODE (ind) == PRE_DEC
+ || GET_CODE (ind) == POST_DEC))
+ return arm_address_register_rtx_p (XEXP (ind, 0), 0);
+
+ if (wb
+ && (GET_CODE (ind) == POST_MODIFY || GET_CODE (ind) == PRE_MODIFY)
+ && arm_address_register_rtx_p (XEXP (ind, 0), 0)
+ && GET_CODE (XEXP (ind, 1)) == PLUS
+ && rtx_equal_p (XEXP (XEXP (ind, 1), 0), XEXP (ind, 0)))
+ ind = XEXP (ind, 1);
+
+ /* Match:
+ (plus (reg)
+ (const)). */
+ if (GET_CODE (ind) == PLUS
+ && GET_CODE (XEXP (ind, 0)) == REG
+ && REG_MODE_OK_FOR_BASE_P (XEXP (ind, 0), VOIDmode)
+ && GET_CODE (XEXP (ind, 1)) == CONST_INT
+ && INTVAL (XEXP (ind, 1)) > -1024
+ && INTVAL (XEXP (ind, 1)) < 1024
+ && (INTVAL (XEXP (ind, 1)) & 3) == 0)
+ return TRUE;
return FALSE;
}
@@ -4686,7 +4705,7 @@ vfp_compare_operand (rtx op, enum machine_mode mode)
enum reg_class
vfp_secondary_reload_class (enum machine_mode mode, rtx x)
{
- if (vfp_mem_operand (x) || s_register_operand (x, mode))
+ if (arm_coproc_mem_operand (x, FALSE) || s_register_operand (x, mode))
return NO_REGS;
return GENERAL_REGS;
@@ -7877,7 +7896,7 @@ print_multi_reg (FILE *stream, const char *instr, int reg, int mask)
/* Add a ^ character for the 26-bit ABI, but only if we were loading
the PC. Otherwise we would generate an UNPREDICTABLE instruction.
- Strictly speaking the instruction would be unpredicatble only if
+ Strictly speaking the instruction would be unpredictable only if
we were writing back the base register as well, but since we never
want to generate an LDM type 2 instruction (register bank switching)
which is what you get if the PC is not being loaded, we do not need
@@ -8386,7 +8405,9 @@ output_move_double (rtx *operands)
break;
case PRE_INC:
- abort (); /* Should never happen now. */
+ if (!TARGET_LDRD)
+ abort (); /* Should never happen now. */
+ output_asm_insn ("ldr%?d\t%0, [%m1, #8]!", operands);
break;
case PRE_DEC:
@@ -8398,7 +8419,33 @@ output_move_double (rtx *operands)
break;
case POST_DEC:
- abort (); /* Should never happen now. */
+ if (!TARGET_LDRD)
+ abort (); /* Should never happen now. */
+ output_asm_insn ("ldr%?d\t%0, [%m1], #-8", operands);
+ break;
+
+ case PRE_MODIFY:
+ case POST_MODIFY:
+ otherops[0] = operands[0];
+ otherops[1] = XEXP (XEXP (XEXP (operands[1], 0), 1), 0);
+ otherops[2] = XEXP (XEXP (XEXP (operands[1], 0), 1), 1);
+
+ if (GET_CODE (XEXP (operands[1], 0)) == PRE_MODIFY)
+ {
+ if (reg_overlap_mentioned_p (otherops[0], otherops[2]))
+ {
+ /* Registers overlap so split out the increment. */
+ output_asm_insn ("add%?\t%1, %1, %2", otherops);
+ output_asm_insn ("ldr%?d\t%0, [%1] @split", otherops);
+ }
+ else
+ output_asm_insn ("ldr%?d\t%0, [%1, %2]!", otherops);
+ }
+ else
+ {
+ /* We only allow constant increments, so this is safe. */
+ output_asm_insn ("ldr%?d\t%0, [%1], %2", otherops);
+ }
break;
case LABEL_REF:
@@ -8431,7 +8478,41 @@ output_move_double (rtx *operands)
output_asm_insn ("ldm%?ib\t%1, %M0", otherops);
return "";
}
-
+ }
+ if (TARGET_LDRD
+ && (GET_CODE (otherops[2]) == REG
+ || (GET_CODE (otherops[2]) == CONST_INT
+ && INTVAL (otherops[2]) > -256
+ && INTVAL (otherops[2]) < 256)))
+ {
+ if (reg_overlap_mentioned_p (otherops[0],
+ otherops[2]))
+ {
+ /* Swap base and index registers over to
+ avoid a conflict. */
+ otherops[1] = XEXP (XEXP (operands[1], 0), 1);
+ otherops[2] = XEXP (XEXP (operands[1], 0), 0);
+
+ }
+ /* If both registers conflict, it will usually
+ have been fixed by a splitter. */
+ if (reg_overlap_mentioned_p (otherops[0],
+ otherops[2]))
+ {
+ output_asm_insn ("add%?\t%1, %1, %2", otherops);
+ output_asm_insn ("ldr%?d\t%0, [%1]",
+ otherops);
+ return "";
+ }
+ else
+ {
+ output_asm_insn ("ldr%?d\t%0, [%1, %2]",
+ otherops);
+ return "";
+ }
+ }
+ if (GET_CODE (otherops[2]) == CONST_INT)
+ {
if (!(const_ok_for_arm (INTVAL (otherops[2]))))
output_asm_insn ("sub%?\t%0, %1, #%n2", otherops);
else
@@ -8477,7 +8558,9 @@ output_move_double (rtx *operands)
break;
case PRE_INC:
- abort (); /* Should never happen now. */
+ if (!TARGET_LDRD)
+ abort (); /* Should never happen now. */
+ output_asm_insn ("str%?d\t%1, [%m0, #8]!", operands);
break;
case PRE_DEC:
@@ -8489,11 +8572,26 @@ output_move_double (rtx *operands)
break;
case POST_DEC:
- abort (); /* Should never happen now. */
+ if (!TARGET_LDRD)
+ abort (); /* Should never happen now. */
+ output_asm_insn ("str%?d\t%1, [%m0], #-8", operands);
+ break;
+
+ case PRE_MODIFY:
+ case POST_MODIFY:
+ otherops[0] = operands[1];
+ otherops[1] = XEXP (XEXP (XEXP (operands[0], 0), 1), 0);
+ otherops[2] = XEXP (XEXP (XEXP (operands[0], 0), 1), 1);
+
+ if (GET_CODE (XEXP (operands[0], 0)) == PRE_MODIFY)
+ output_asm_insn ("str%?d\t%0, [%1, %2]!", otherops);
+ else
+ output_asm_insn ("str%?d\t%0, [%1], %2", otherops);
break;
case PLUS:
- if (GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
+ otherops[2] = XEXP (XEXP (operands[0], 0), 1);
+ if (GET_CODE (otherops[2]) == CONST_INT)
{
switch ((int) INTVAL (XEXP (XEXP (operands[0], 0), 1)))
{
@@ -8510,6 +8608,17 @@ output_move_double (rtx *operands)
return "";
}
}
+ if (TARGET_LDRD
+ && (GET_CODE (otherops[2]) == REG
+ || (GET_CODE (otherops[2]) == CONST_INT
+ && INTVAL (otherops[2]) > -256
+ && INTVAL (otherops[2]) < 256)))
+ {
+ otherops[0] = operands[1];
+ otherops[1] = XEXP (XEXP (operands[0], 0), 0);
+ output_asm_insn ("str%?d\t%0, [%1, %2]", otherops);
+ return "";
+ }
/* Fall through */
default:
@@ -9492,7 +9601,7 @@ arm_output_epilogue (rtx sibling)
the live_regs_mask. */
lrm_count += (lrm_count % 2 ? 2 : 1);
- for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
+ for (reg = LAST_IWMMXT_REGNUM; reg >= FIRST_IWMMXT_REGNUM; reg--)
if (regs_ever_live[reg] && !call_used_regs[reg])
{
asm_fprintf (f, "\twldrd\t%r, [%r, #-%d]\n",
@@ -9613,7 +9722,7 @@ arm_output_epilogue (rtx sibling)
if (TARGET_IWMMXT)
for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
if (regs_ever_live[reg] && !call_used_regs[reg])
- asm_fprintf (f, "\twldrd\t%r, [%r, #+8]!\n", reg, SP_REGNUM);
+ asm_fprintf (f, "\twldrd\t%r, [%r], #8\n", reg, SP_REGNUM);
/* If we can, restore the LR into the PC. */
if (ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL
@@ -10126,10 +10235,10 @@ arm_compute_initial_elimination_offset (unsigned int from, unsigned int to)
frame pointer and the arg pointer coincide. */
if (offsets->frame == offsets->saved_regs)
return 0;
- /* FIXME: Not sure about this. Maybe we should always return 0 ? */
- return (frame_pointer_needed
- && current_function_needs_context
- && ! cfun->machine->uses_anonymous_args) ? 4 : 0;
+ /* FIXME: Not sure about this. Maybe we should always return 0 ? */
+ return (frame_pointer_needed
+ && cfun->static_chain_decl != NULL
+ && ! cfun->machine->uses_anonymous_args) ? 4 : 0;
case STACK_POINTER_REGNUM:
/* If nothing has been pushed on the stack at all
@@ -10339,7 +10448,7 @@ arm_expand_prologue (void)
}
if (TARGET_IWMMXT)
- for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
+ for (reg = LAST_IWMMXT_REGNUM; reg >= FIRST_IWMMXT_REGNUM; reg--)
if (regs_ever_live[reg] && ! call_used_regs [reg])
{
insn = gen_rtx_PRE_DEC (V2SImode, stack_pointer_rtx);
@@ -10381,6 +10490,7 @@ arm_expand_prologue (void)
{
insn = emit_sfm (reg, 4);
RTX_FRAME_RELATED_P (insn) = 1;
+ saved_regs += 48;
start_reg = reg - 1;
}
}
@@ -10390,7 +10500,7 @@ arm_expand_prologue (void)
{
insn = emit_sfm (reg + 1, start_reg - reg);
RTX_FRAME_RELATED_P (insn) = 1;
- saved_regs += (reg - start_reg) * 12;
+ saved_regs += (start_reg - reg) * 12;
}
start_reg = reg - 1;
}
@@ -10399,7 +10509,7 @@ arm_expand_prologue (void)
if (start_reg != reg)
{
insn = emit_sfm (reg + 1, start_reg - reg);
- saved_regs += (reg - start_reg) * 12;
+ saved_regs += (start_reg - reg) * 12;
RTX_FRAME_RELATED_P (insn) = 1;
}
}
@@ -11394,9 +11504,11 @@ arm_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
if (IS_IWMMXT_REGNUM (regno))
return VALID_IWMMXT_REG_MODE (mode);
+ /* We allow any value to be stored in the general registers.
+ Restrict doubleword quantities to even register pairs so that we can
+ use ldrd. */
if (regno <= LAST_ARM_REGNUM)
- /* We allow any value to be stored in the general registers. */
- return 1;
+ return !(TARGET_LDRD && GET_MODE_SIZE (mode) > 4 && (regno & 1) != 0);
if ( regno == FRAME_POINTER_REGNUM
|| regno == ARG_POINTER_REGNUM)
@@ -14439,3 +14551,30 @@ arm_no_early_mul_dep (rtx producer, rtx consumer)
&& !reg_overlap_mentioned_p (value, XEXP (op, 0)));
}
+
+/* We can't rely on the caller doing the proper promotion when
+ using APCS or ATPCS. */
+
+static bool
+arm_promote_prototypes (tree t ATTRIBUTE_UNUSED)
+{
+ return !TARGET_AAPCS_BASED;
+}
+
+
+/* AAPCS based ABIs use short enums by default. */
+
+static bool
+arm_default_short_enums (void)
+{
+ return TARGET_AAPCS_BASED;
+}
+
+
+/* AAPCS requires that anonymous bitfields affect structure alignment. */
+
+static bool
+arm_align_anon_bitfield (void)
+{
+ return TARGET_AAPCS_BASED;
+}
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 8af53df8c88..fe693a83ce1 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -26,6 +26,9 @@
#ifndef GCC_ARM_H
#define GCC_ARM_H
+/* The archetecture define. */
+extern char arm_arch_name[];
+
/* Target CPU builtins. */
#define TARGET_CPU_CPP_BUILTINS() \
do \
@@ -69,45 +72,20 @@
\
builtin_assert ("cpu=arm"); \
builtin_assert ("machine=arm"); \
+ \
+ builtin_define (arm_arch_name); \
+ if (arm_arch_cirrus) \
+ builtin_define ("__MAVERICK__"); \
+ if (arm_arch_xscale) \
+ builtin_define ("__XSCALE__"); \
+ if (arm_arch_iwmmxt) \
+ builtin_define ("__IWMMXT__"); \
} while (0)
-#define TARGET_CPU_arm2 0x0000
-#define TARGET_CPU_arm250 0x0000
-#define TARGET_CPU_arm3 0x0000
-#define TARGET_CPU_arm6 0x0001
-#define TARGET_CPU_arm600 0x0001
-#define TARGET_CPU_arm610 0x0002
-#define TARGET_CPU_arm7 0x0001
-#define TARGET_CPU_arm7m 0x0004
-#define TARGET_CPU_arm7dm 0x0004
-#define TARGET_CPU_arm7dmi 0x0004
-#define TARGET_CPU_arm700 0x0001
-#define TARGET_CPU_arm710 0x0002
-#define TARGET_CPU_arm7100 0x0002
-#define TARGET_CPU_arm7500 0x0002
-#define TARGET_CPU_arm7500fe 0x1001
-#define TARGET_CPU_arm7tdmi 0x0008
-#define TARGET_CPU_arm8 0x0010
-#define TARGET_CPU_arm810 0x0020
-#define TARGET_CPU_strongarm 0x0040
-#define TARGET_CPU_strongarm110 0x0040
-#define TARGET_CPU_strongarm1100 0x0040
-#define TARGET_CPU_arm9 0x0080
-#define TARGET_CPU_arm9tdmi 0x0080
-#define TARGET_CPU_xscale 0x0100
-#define TARGET_CPU_ep9312 0x0200
-#define TARGET_CPU_iwmmxt 0x0400
-#define TARGET_CPU_arm926ejs 0x0800
-#define TARGET_CPU_arm1026ejs 0x1000
-#define TARGET_CPU_arm1136js 0x2000
-#define TARGET_CPU_arm1136jfs 0x4000
-/* Configure didn't specify. */
-#define TARGET_CPU_generic 0x8000
-
/* The various ARM cores. */
enum processor_type
{
-#define ARM_CORE(NAME, FLAGS, COSTS) \
+#define ARM_CORE(NAME, ARCH, FLAGS, COSTS) \
NAME,
#include "arm-cores.def"
#undef ARM_CORE
@@ -115,6 +93,15 @@ enum processor_type
arm_none
};
+enum target_cpus
+{
+#define ARM_CORE(NAME, ARCH, FLAGS, COSTS) \
+ TARGET_CPU_##NAME,
+#include "arm-cores.def"
+#undef ARM_CORE
+ TARGET_CPU_generic
+};
+
/* The processor for which instructions should be scheduled. */
extern enum processor_type arm_tune;
@@ -159,69 +146,9 @@ extern GTY(()) rtx aof_pic_label;
#define TARGET_CPU_DEFAULT TARGET_CPU_generic
#endif
-/* If the configuration file doesn't specify the cpu, the subtarget may
- override it. If it doesn't, then default to an ARM6. */
-#if TARGET_CPU_DEFAULT == TARGET_CPU_generic
-#undef TARGET_CPU_DEFAULT
-
-#ifdef SUBTARGET_CPU_DEFAULT
-#define TARGET_CPU_DEFAULT SUBTARGET_CPU_DEFAULT
-#else
-#define TARGET_CPU_DEFAULT TARGET_CPU_arm6
-#endif
-#endif
-
-#if TARGET_CPU_DEFAULT == TARGET_CPU_arm2
-#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_2__"
-#else
-#if TARGET_CPU_DEFAULT == TARGET_CPU_arm6 || TARGET_CPU_DEFAULT == TARGET_CPU_arm610 || TARGET_CPU_DEFAULT == TARGET_CPU_arm7500fe
-#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_3__"
-#else
-#if TARGET_CPU_DEFAULT == TARGET_CPU_arm7m
-#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_3M__"
-#else
-#if TARGET_CPU_DEFAULT == TARGET_CPU_arm7tdmi || TARGET_CPU_DEFAULT == TARGET_CPU_arm9 || TARGET_CPU_DEFAULT == TARGET_CPU_arm9tdmi
-#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_4T__"
-#else
-#if TARGET_CPU_DEFAULT == TARGET_CPU_arm8 || TARGET_CPU_DEFAULT == TARGET_CPU_arm810 || TARGET_CPU_DEFAULT == TARGET_CPU_strongarm || TARGET_CPU_DEFAULT == TARGET_CPU_strongarm110 || TARGET_CPU_DEFAULT == TARGET_CPU_strongarm1100
-#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_4__"
-#else
-#if TARGET_CPU_DEFAULT == TARGET_CPU_xscale
-#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_5TE__ -D__XSCALE__"
-#else
-#if TARGET_CPU_DEFAULT == TARGET_CPU_ep9312
-#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_4T__ -D__MAVERICK__"
-/* Set TARGET_DEFAULT to the default, but without soft-float. */
-#ifdef TARGET_DEFAULT
-#undef TARGET_DEFAULT
-#define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME)
-#endif
-#else
-#if TARGET_CPU_DEFAULT == TARGET_CPU_iwmmxt
-#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_5TE__ -D__XSCALE__ -D__IWMMXT__"
-#else
-#if (TARGET_CPU_DEFAULT == TARGET_CPU_arm926ejs || \
- TARGET_CPU_DEFAULT == TARGET_CPU_arm1026ejs)
-#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_5TEJ__"
-#else
-#if (TARGET_CPU_DEFAULT == TARGET_CPU_arm1136js || \
- TARGET_CPU_DEFAULT == TARGET_CPU_arm1136jfs)
-#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_6J__"
-#else
-#error Unrecognized value in TARGET_CPU_DEFAULT.
-#endif
-#endif
-#endif
-#endif
-#endif
-#endif
-#endif
-#endif
-#endif
-#endif
#undef CPP_SPEC
-#define CPP_SPEC "%(cpp_cpu_arch) %(subtarget_cpp_spec) \
+#define CPP_SPEC "%(subtarget_cpp_spec) \
%{mapcs-32:%{mapcs-26: \
%e-mapcs-26 and -mapcs-32 may not be used together}} \
%{msoft-float:%{mhard-float: \
@@ -229,96 +156,6 @@ extern GTY(()) rtx aof_pic_label;
%{mbig-endian:%{mlittle-endian: \
%e-mbig-endian and -mlittle-endian may not be used together}}"
-/* Set the architecture define -- if -march= is set, then it overrides
- the -mcpu= setting. */
-#define CPP_CPU_ARCH_SPEC "\
-%{march=arm2:-D__ARM_ARCH_2__} \
-%{march=arm250:-D__ARM_ARCH_2__} \
-%{march=arm3:-D__ARM_ARCH_2__} \
-%{march=arm6:-D__ARM_ARCH_3__} \
-%{march=arm600:-D__ARM_ARCH_3__} \
-%{march=arm610:-D__ARM_ARCH_3__} \
-%{march=arm7:-D__ARM_ARCH_3__} \
-%{march=arm700:-D__ARM_ARCH_3__} \
-%{march=arm710:-D__ARM_ARCH_3__} \
-%{march=arm720:-D__ARM_ARCH_3__} \
-%{march=arm7100:-D__ARM_ARCH_3__} \
-%{march=arm7500:-D__ARM_ARCH_3__} \
-%{march=arm7500fe:-D__ARM_ARCH_3__} \
-%{march=arm7m:-D__ARM_ARCH_3M__} \
-%{march=arm7dm:-D__ARM_ARCH_3M__} \
-%{march=arm7dmi:-D__ARM_ARCH_3M__} \
-%{march=arm7tdmi:-D__ARM_ARCH_4T__} \
-%{march=arm8:-D__ARM_ARCH_4__} \
-%{march=arm810:-D__ARM_ARCH_4__} \
-%{march=arm9:-D__ARM_ARCH_4T__} \
-%{march=arm920:-D__ARM_ARCH_4__} \
-%{march=arm920t:-D__ARM_ARCH_4T__} \
-%{march=arm926ejs:-D__ARM_ARCH_5TEJ__} \
-%{march=arm9tdmi:-D__ARM_ARCH_4T__} \
-%{march=arm1026ejs:-D__ARM_ARCH_5TEJ__} \
-%{march=arm1136js:-D__ARM_ARCH_6J__} \
-%{march=arm1136jfs:-D__ARM_ARCH_6J__} \
-%{march=strongarm:-D__ARM_ARCH_4__} \
-%{march=strongarm110:-D__ARM_ARCH_4__} \
-%{march=strongarm1100:-D__ARM_ARCH_4__} \
-%{march=xscale:-D__ARM_ARCH_5TE__} \
-%{march=xscale:-D__XSCALE__} \
-%{march=ep9312:-D__ARM_ARCH_4T__} \
-%{march=ep9312:-D__MAVERICK__} \
-%{march=armv2:-D__ARM_ARCH_2__} \
-%{march=armv2a:-D__ARM_ARCH_2__} \
-%{march=armv3:-D__ARM_ARCH_3__} \
-%{march=armv3m:-D__ARM_ARCH_3M__} \
-%{march=armv4:-D__ARM_ARCH_4__} \
-%{march=armv4t:-D__ARM_ARCH_4T__} \
-%{march=armv5:-D__ARM_ARCH_5__} \
-%{march=armv5t:-D__ARM_ARCH_5T__} \
-%{march=armv5e:-D__ARM_ARCH_5E__} \
-%{march=armv5te:-D__ARM_ARCH_5TE__} \
-%{march=armv6:-D__ARM_ARCH6__} \
-%{march=armv6j:-D__ARM_ARCH6J__} \
-%{!march=*: \
- %{mcpu=arm2:-D__ARM_ARCH_2__} \
- %{mcpu=arm250:-D__ARM_ARCH_2__} \
- %{mcpu=arm3:-D__ARM_ARCH_2__} \
- %{mcpu=arm6:-D__ARM_ARCH_3__} \
- %{mcpu=arm600:-D__ARM_ARCH_3__} \
- %{mcpu=arm610:-D__ARM_ARCH_3__} \
- %{mcpu=arm7:-D__ARM_ARCH_3__} \
- %{mcpu=arm700:-D__ARM_ARCH_3__} \
- %{mcpu=arm710:-D__ARM_ARCH_3__} \
- %{mcpu=arm720:-D__ARM_ARCH_3__} \
- %{mcpu=arm7100:-D__ARM_ARCH_3__} \
- %{mcpu=arm7500:-D__ARM_ARCH_3__} \
- %{mcpu=arm7500fe:-D__ARM_ARCH_3__} \
- %{mcpu=arm7m:-D__ARM_ARCH_3M__} \
- %{mcpu=arm7dm:-D__ARM_ARCH_3M__} \
- %{mcpu=arm7dmi:-D__ARM_ARCH_3M__} \
- %{mcpu=arm7tdmi:-D__ARM_ARCH_4T__} \
- %{mcpu=arm8:-D__ARM_ARCH_4__} \
- %{mcpu=arm810:-D__ARM_ARCH_4__} \
- %{mcpu=arm9:-D__ARM_ARCH_4T__} \
- %{mcpu=arm920:-D__ARM_ARCH_4__} \
- %{mcpu=arm920t:-D__ARM_ARCH_4T__} \
- %{mcpu=arm926ejs:-D__ARM_ARCH_5TEJ__} \
- %{mcpu=arm9tdmi:-D__ARM_ARCH_4T__} \
- %{mcpu=arm1026ejs:-D__ARM_ARCH_5TEJ__} \
- %{mcpu=arm1136js:-D__ARM_ARCH_6J__} \
- %{mcpu=arm1136jfs:-D__ARM_ARCH_6J__} \
- %{mcpu=strongarm:-D__ARM_ARCH_4__} \
- %{mcpu=strongarm110:-D__ARM_ARCH_4__} \
- %{mcpu=strongarm1100:-D__ARM_ARCH_4__} \
- %{mcpu=xscale:-D__ARM_ARCH_5TE__} \
- %{mcpu=xscale:-D__XSCALE__} \
- %{mcpu=ep9312:-D__ARM_ARCH_4T__} \
- %{mcpu=ep9312:-D__MAVERICK__} \
- %{mcpu=iwmmxt:-D__ARM_ARCH_5TE__} \
- %{mcpu=iwmmxt:-D__XSCALE__} \
- %{mcpu=iwmmxt:-D__IWMMXT__} \
- %{!mcpu*:%(cpp_cpu_arch_default)}} \
-"
-
#ifndef CC1_SPEC
#define CC1_SPEC ""
#endif
@@ -333,8 +170,6 @@ extern GTY(()) rtx aof_pic_label;
Do not define this macro if it does not need to do anything. */
#define EXTRA_SPECS \
- { "cpp_cpu_arch", CPP_CPU_ARCH_SPEC }, \
- { "cpp_cpu_arch_default", CPP_ARCH_DEFAULT_SPEC }, \
{ "subtarget_cpp_spec", SUBTARGET_CPP_SPEC }, \
SUBTARGET_EXTRA_SPECS
@@ -471,6 +306,9 @@ extern GTY(()) rtx aof_pic_label;
? (target_flags & THUMB_FLAG_LEAF_BACKTRACE) \
: (target_flags & THUMB_FLAG_BACKTRACE))
#define TARGET_CIRRUS_FIX_INVALID_INSNS (target_flags & CIRRUS_FIX_INVALID_INSNS)
+#define TARGET_LDRD (arm_arch5e && ARM_DOUBLEWORD_ALIGN)
+#define TARGET_AAPCS_BASED \
+ (arm_abi != ARM_ABI_APCS && arm_abi != ARM_ABI_ATPCS)
/* SUBTARGET_SWITCHES is used to add flags on a per-config basis. */
#ifndef SUBTARGET_SWITCHES
@@ -669,21 +507,6 @@ enum float_abi_type
extern enum float_abi_type arm_float_abi;
-/* Default floating point architecture. Override in sub-target if
- necessary.
- FIXME: Is this still necessary/desirable? Do we want VFP chips to
- default to VFP unless overridden by a subtarget? If so it would be best
- to remove these definitions. It also assumes there is only one cpu model
- with a Maverick fpu. */
-#ifndef FPUTYPE_DEFAULT
-#define FPUTYPE_DEFAULT FPUTYPE_FPA_EMU2
-#endif
-
-#if TARGET_CPU_DEFAULT == TARGET_CPU_ep9312
-#undef FPUTYPE_DEFAULT
-#define FPUTYPE_DEFAULT FPUTYPE_MAVERICK
-#endif
-
/* Which ABI to use. */
enum arm_abi_type
{
@@ -724,7 +547,7 @@ extern int thumb_code;
extern int arm_is_strong;
/* Nonzero if this chip is a Cirrus variant. */
-extern int arm_is_cirrus;
+extern int arm_arch_cirrus;
/* Nonzero if this chip supports Intel XScale with Wireless MMX technology. */
extern int arm_arch_iwmmxt;
@@ -834,8 +657,8 @@ extern int arm_is_6_or_7;
#define UNITS_PER_WORD 4
/* True if natural alignment is used for doubleword types. */
-#define ARM_DOUBLEWORD_ALIGN \
- (arm_abi == ARM_ABI_AAPCS || arm_abi == ARM_ABI_IWMMXT)
+#define ARM_DOUBLEWORD_ALIGN TARGET_AAPCS_BASED
+
#define DOUBLEWORD_ALIGNMENT 64
#define PARM_BOUNDARY 32
@@ -895,6 +718,23 @@ extern const char * structure_size_string;
/* Nonzero if move instructions will actually fail to work
when given unaligned data. */
#define STRICT_ALIGNMENT 1
+
+/* wchar_t is unsigned under the AAPCS. */
+#ifndef WCHAR_TYPE
+#define WCHAR_TYPE (TARGET_AAPCS_BASED ? "unsigned int" : "int")
+
+#define WCHAR_TYPE_SIZE BITS_PER_WORD
+#endif
+
+#ifndef SIZE_TYPE
+#define SIZE_TYPE (TARGET_AAPCS_BASED ? "unsigned int" : "long unsigned int")
+#endif
+
+/* AAPCS requires that structure alignment is affected by bitfields. */
+#ifndef PCC_BITFIELD_TYPE_MATTERS
+#define PCC_BITFIELD_TYPE_MATTERS TARGET_AAPCS_BASED
+#endif
+
/* Standard register usage. */
@@ -1472,6 +1312,7 @@ enum reg_class
accessed without using a load.
'U' Prefixes an extended memory constraint where:
'Uv' is an address valid for VFP load/store insns.
+ 'Uy' is an address valid for iwmmxt load/store insns.
'Uq' is an address valid for ldrsb. */
#define EXTRA_CONSTRAINT_STR_ARM(OP, C, STR) \
@@ -1482,7 +1323,8 @@ enum reg_class
&& CONSTANT_POOL_ADDRESS_P (XEXP (OP, 0))) : \
((C) == 'S') ? (optimize > 0 && CONSTANT_ADDRESS_P (OP)) : \
((C) == 'T') ? cirrus_memory_offset (OP) : \
- ((C) == 'U' && (STR)[1] == 'v') ? vfp_mem_operand (OP) : \
+ ((C) == 'U' && (STR)[1] == 'v') ? arm_coproc_mem_operand (OP, FALSE) : \
+ ((C) == 'U' && (STR)[1] == 'y') ? arm_coproc_mem_operand (OP, TRUE) : \
((C) == 'U' && (STR)[1] == 'q') \
? arm_extendqisi_mem_op (OP, GET_MODE (OP)) \
: 0)
@@ -2210,7 +2052,6 @@ typedef struct
#define THUMB_LEGITIMATE_CONSTANT_P(X) \
( GET_CODE (X) == CONST_INT \
|| GET_CODE (X) == CONST_DOUBLE \
- || GET_CODE (X) == CONSTANT_P_RTX \
|| CONSTANT_ADDRESS_P (X) \
|| flag_pic)
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 7255b325997..554b332283b 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -4073,7 +4073,7 @@
)
(define_insn "*arm_movdi"
- [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, o<>")
+ [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r ,m")
(match_operand:DI 1 "di_operand" "rIK,mi,r"))]
"TARGET_ARM
&& !(TARGET_HARD_FLOAT && (TARGET_MAVERICK || TARGET_VFP))
@@ -4087,6 +4087,26 @@
(set_attr "neg_pool_range" "*,1008,*")]
)
+;; We can't actually do base+index doubleword loads if the index and
+;; destination overlap. Split here so that we at least have chance to
+;; schedule.
+(define_split
+ [(set (match_operand:DI 0 "s_register_operand" "")
+ (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
+ (match_operand:SI 2 "s_register_operand" ""))))]
+ "TARGET_LDRD
+ && reg_overlap_mentioned_p (operands[0], operands[1])
+ && reg_overlap_mentioned_p (operands[0], operands[2])"
+ [(set (match_dup 4)
+ (plus:SI (match_dup 1)
+ (match_dup 2)))
+ (set (match_dup 0)
+ (mem:DI (match_dup 4)))]
+ "
+ operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
+ "
+)
+
;;; ??? This should have alternatives for constants.
;;; ??? This was originally identical to the movdf_insn pattern.
;;; ??? The 'i' constraint looks funny, but it should always be replaced by
diff --git a/gcc/config/arm/crti.asm b/gcc/config/arm/crti.asm
index ac58e44838d..3597e42b02e 100644
--- a/gcc/config/arm/crti.asm
+++ b/gcc/config/arm/crti.asm
@@ -42,12 +42,12 @@
#ifdef __thumb__
.thumb
- push {r4, r5, r6, r7, lr}
+ push {r3, r4, r5, r6, r7, lr}
#else
.arm
# Create a stack frame and save any call-preserved registers
mov ip, sp
- stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
+ stmdb sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
sub fp, ip, #4
#endif
.endm
diff --git a/gcc/config/arm/crtn.asm b/gcc/config/arm/crtn.asm
index 9ad75e3f2aa..714060ce60d 100644
--- a/gcc/config/arm/crtn.asm
+++ b/gcc/config/arm/crtn.asm
@@ -43,17 +43,19 @@
# sequences here, it is just not worth it. Instead keep things
# simple. Restore all the save resgisters, including the link
# register and then perform the correct function return instruction.
+ # We also save/restore r3 to ensure stack alignment.
.macro FUNC_END
#ifdef __thumb__
.thumb
- pop {r4, r5, r6, r7}
+ pop {r3, r4, r5, r6, r7}
pop {r3}
mov lr, r3
#else
.arm
- ldmdb fp, {r4, r5, r6, r7, r8, r9, sl, fp, sp, lr}
+ sub sp, fp, #40
+ ldmfd sp, {r4, r5, r6, r7, r8, r9, sl, fp, sp, lr}
#endif
#if defined __THUMB_INTERWORK__ || defined __thumb__
diff --git a/gcc/config/arm/freebsd.h b/gcc/config/arm/freebsd.h
index cfeb479a54a..cc3f72725b6 100644
--- a/gcc/config/arm/freebsd.h
+++ b/gcc/config/arm/freebsd.h
@@ -20,6 +20,7 @@
Boston, MA 02111-1307, USA. */
+#undef SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS \
{ "fbsd_dynamic_linker", FBSD_DYNAMIC_LINKER }
diff --git a/gcc/config/arm/iwmmxt.md b/gcc/config/arm/iwmmxt.md
index e1b00538c1f..758847fd547 100644
--- a/gcc/config/arm/iwmmxt.md
+++ b/gcc/config/arm/iwmmxt.md
@@ -64,8 +64,8 @@
[(set_attr "predicable" "yes")])
(define_insn "*iwmmxt_arm_movdi"
- [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, o<>,y,y,yr,y,yrm")
- (match_operand:DI 1 "di_operand" "rIK,mi,r ,y,yr,y,yrm,y"))]
+ [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, m,y,y,yr,y,yrUy")
+ (match_operand:DI 1 "di_operand" "rIK,mi,r,y,yr,y,yrUy,y"))]
"TARGET_REALLY_IWMMXT"
"*
{
diff --git a/gcc/config/arm/lib1funcs.asm b/gcc/config/arm/lib1funcs.asm
index cdf71151b58..7174ed343ad 100644
--- a/gcc/config/arm/lib1funcs.asm
+++ b/gcc/config/arm/lib1funcs.asm
@@ -74,11 +74,17 @@ Boston, MA 02111-1307, USA. */
#endif
#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
- || defined(__ARM_ARCH_5TE__)
+ || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
+ || defined(__ARM_ARCH_5TEJ__)
# undef __ARM_ARCH__
# define __ARM_ARCH__ 5
#endif
+#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__)
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 6
+#endif
+
/* How to return from a function call depends on the architecture variant. */
#ifdef __APCS_26__
@@ -876,7 +882,11 @@ LSYM(Lover12):
/* Do not build the interworking functions when the target architecture does
not support Thumb instructions. (This can be a multilib option). */
-#if defined L_call_via_rX && (defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__ || defined __ARM_ARCH_5TE__)
+#if defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__\
+ || defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__ \
+ || __ARM_ARCH__ >= 6
+
+#if defined L_call_via_rX
/* These labels & instructions are used by the Arm/Thumb interworking code.
The address of function to be called is loaded into a register and then
@@ -914,10 +924,8 @@ LSYM(Lover12):
call_via lr
#endif /* L_call_via_rX */
-/* ------------------------------------------------------------------------ */
-/* Do not build the interworking functions when the target architecture does
- not support Thumb instructions. (This can be a multilib option). */
-#if defined L_interwork_call_via_rX && (defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__ || defined __ARM_ARCH_5TE__)
+
+#if defined L_interwork_call_via_rX
/* These labels & instructions are used by the Arm/Thumb interworking code,
when the target address is in an unknown instruction set. The address
@@ -993,6 +1001,7 @@ LSYM(Lchange_\register):
SIZE (_interwork_call_via_lr)
#endif /* L_interwork_call_via_rX */
+#endif /* Arch supports thumb. */
#include "ieee754-df.S"
#include "ieee754-sf.S"
diff --git a/gcc/config/arm/linux-elf.h b/gcc/config/arm/linux-elf.h
index bbfcbeb3360..b4b389c1b7c 100644
--- a/gcc/config/arm/linux-elf.h
+++ b/gcc/config/arm/linux-elf.h
@@ -126,3 +126,8 @@
#define LINK_GCC_C_SEQUENCE_SPEC \
"%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
+
+/* Use --as-needed -lgcc_s for eh support. */
+#ifdef HAVE_LD_AS_NEEDED
+#define USE_LD_AS_NEEDED 1
+#endif
diff --git a/gcc/config/arm/t-xscale-coff b/gcc/config/arm/t-xscale-coff
index 89f371f4928..686fd9be7ce 100644
--- a/gcc/config/arm/t-xscale-coff
+++ b/gcc/config/arm/t-xscale-coff
@@ -20,19 +20,19 @@ dp-bit.c: $(srcdir)/config/fp-bit.c
echo '#endif' >> dp-bit.c
cat $(srcdir)/config/fp-bit.c >> dp-bit.c
-MULTILIB_OPTIONS = mlittle-endian/mbig-endian
-MULTILIB_DIRNAMES = le be
+MULTILIB_OPTIONS = mbig-endian
+MULTILIB_DIRNAMES = be
MULTILIB_EXCEPTIONS =
MULTILIB_MATCHES = mbig-endian=mbe mlittle-endian=mle
# Note XScale does not support 26 bit APCS.
# Note XScale does not support hard FP
-MULTILIB_OPTIONS += mno-thumb-interwork/mthumb-interwork
-MULTILIB_DIRNAMES += normal interwork
+MULTILIB_OPTIONS += mthumb-interwork
+MULTILIB_DIRNAMES += interwork
-MULTILIB_OPTIONS += marm/mthumb
-MULTILIB_DIRNAMES += arm thumb
+MULTILIB_OPTIONS += mthumb
+MULTILIB_DIRNAMES += thumb
MULTILIB_EXCEPTIONS += *mhard-float/*mthumb*
MULTILIB_REDUNDANT_DIRS = interwork/thumb=thumb
diff --git a/gcc/config/arm/t-xscale-elf b/gcc/config/arm/t-xscale-elf
index b72c21ce980..1b7119a9553 100644
--- a/gcc/config/arm/t-xscale-elf
+++ b/gcc/config/arm/t-xscale-elf
@@ -20,26 +20,32 @@ dp-bit.c: $(srcdir)/config/fp-bit.c
echo '#endif' >> dp-bit.c
cat $(srcdir)/config/fp-bit.c >> dp-bit.c
-MULTILIB_OPTIONS = mlittle-endian/mbig-endian
-MULTILIB_DIRNAMES = le be
+MULTILIB_OPTIONS = mbig-endian
+MULTILIB_DIRNAMES = be
MULTILIB_EXCEPTIONS =
MULTILIB_MATCHES = mbig-endian=mbe mlittle-endian=mle
# Note XScale does not support 26 bit APCS.
# Note XScale does not support hard FP
-MULTILIB_OPTIONS += mno-thumb-interwork/mthumb-interwork
-MULTILIB_DIRNAMES += normal interwork
+MULTILIB_OPTIONS += mthumb-interwork
+MULTILIB_DIRNAMES += interwork
-MULTILIB_OPTIONS += marm/mthumb
-MULTILIB_DIRNAMES += arm thumb
+MULTILIB_OPTIONS += mthumb
+MULTILIB_DIRNAMES += thumb
MULTILIB_EXCEPTIONS += *mhard-float/*mthumb*
MULTILIB_REDUNDANT_DIRS = interwork/thumb=thumb
-MULTILIB_OPTIONS += mcpu=iwmmxt
-MULTILIB_DIRNAMES += iwmmxt
-MULTILIB_REDUNDANT_DIRS += interwork/thumb/iwmmxt=thumb
+# The iWMMXt multilibs are suppressed for now because gcc only
+# supports generating them with the IWMMXT or AAPCS ABIs, neither of
+# which is the default. Until GCC can generate code for an iWMMXt
+# which will work with the default ABI it is not possible to safely
+# generate these multilibs.
+#
+# MULTILIB_OPTIONS += mcpu=iwmmxt
+# MULTILIB_DIRNAMES += iwmmxt
+# MULTILIB_REDUNDANT_DIRS += interwork/thumb/iwmmxt=thumb
EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o
diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
index dd313a9bdca..7008ab40c76 100644
--- a/gcc/config/arm/vfp.md
+++ b/gcc/config/arm/vfp.md
@@ -136,8 +136,8 @@
;; DImode moves
(define_insn "*arm_movdi_vfp"
- [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,o<>,w,r,w,w ,Uv")
- (match_operand:DI 1 "di_operand" "rIK,mi,r ,r,w,w,Uvi,w"))]
+ [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,m,w,r,w,w, Uv")
+ (match_operand:DI 1 "di_operand" "rIK,mi,r,r,w,w,Uvi,w"))]
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
"*
switch (which_alternative)
@@ -558,6 +558,26 @@
(set_attr "type" "farith")]
)
+
+(define_insn "fixuns_truncsfsi2"
+ [(set (match_operand:SI 0 "s_register_operand" "=w")
+ (unsigned_fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "w"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "ftouizs%?\\t%0, %1"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "farith")]
+)
+
+(define_insn "fixuns_truncdfsi2"
+ [(set (match_operand:SI 0 "s_register_operand" "=w")
+ (unsigned_fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "ftouizd%?\\t%0, %P1"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "farith")]
+)
+
+
(define_insn "*floatsisf2_vfp"
[(set (match_operand:SF 0 "s_register_operand" "=w")
(float:SF (match_operand:SI 1 "s_register_operand" "w")))]
@@ -577,6 +597,25 @@
)
+(define_insn "floatunssisf2"
+ [(set (match_operand:SF 0 "s_register_operand" "=w")
+ (unsigned_float:SF (match_operand:SI 1 "s_register_operand" "w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fuitos%?\\t%0, %1"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "farith")]
+)
+
+(define_insn "floatunssidf2"
+ [(set (match_operand:DF 0 "s_register_operand" "=w")
+ (unsigned_float:DF (match_operand:SI 1 "s_register_operand" "w")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
+ "fuitod%?\\t%P0, %1"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "farith")]
+)
+
+
;; Sqrt insns.
(define_insn "*sqrtsf2_vfp"
@@ -740,5 +779,3 @@
;; fmdhr et al (VFPv1)
;; Support for xD (single precision only) variants.
;; fmrrs, fmsrr
-;; fuito*
-;; ftoui*
diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h
index 79e3e585897..a78b42be449 100644
--- a/gcc/config/avr/avr.h
+++ b/gcc/config/avr/avr.h
@@ -765,9 +765,6 @@ extern int avr_case_values_threshold;
#define FUNCTION_MODE HImode
- /* 1 3 */
-#define INTEGRATE_THRESHOLD(DECL) (1 + (3 * list_length (DECL_ARGUMENTS (DECL)) / 2))
-
#define DOLLARS_IN_IDENTIFIERS 0
#define NO_DOLLAR_IN_LABEL 1
diff --git a/gcc/config/c4x/c4x.c b/gcc/config/c4x/c4x.c
index 7500526d435..850bcef44b9 100644
--- a/gcc/config/c4x/c4x.c
+++ b/gcc/config/c4x/c4x.c
@@ -1244,7 +1244,7 @@ c4x_emit_move_sequence (rtx *operands, enum machine_mode mode)
&& dp_reg_operand (XEXP (op1, 0), mode))
{
/* expand_increment will sometimes create a LO_SUM immediate
- address. Undo this sillyness. */
+ address. Undo this silliness. */
op1 = XEXP (op1, 1);
}
@@ -2940,9 +2940,6 @@ const_operand (register rtx op, register enum machine_mode mode)
case Pmode:
#endif
case QImode:
- if (GET_CODE (op) == CONSTANT_P_RTX)
- return 1;
-
if (GET_CODE (op) != CONST_INT
|| (GET_MODE (op) != VOIDmode && GET_MODE (op) != mode)
|| GET_MODE_CLASS (mode) != MODE_INT)
diff --git a/gcc/config/c4x/c4x.md b/gcc/config/c4x/c4x.md
index 0999adca406..1ea954abdd8 100644
--- a/gcc/config/c4x/c4x.md
+++ b/gcc/config/c4x/c4x.md
@@ -154,7 +154,7 @@
; not for 'c'.
; The 'f' constraint is only for float register operands---when
-; a register satisying the 'f' constraint is used as a dst operand,
+; a register satisfying the 'f' constraint is used as a dst operand,
; the CC gets clobbered (except for LDFcond).
; The ! in front of the 'b' constraint says to GCC to disparage the
@@ -190,7 +190,7 @@
; didn't allow it to move the CC around.
; Note that fundamental operations, such as moves, must not clobber the
-; CC. Thus movqi choses a move instruction that doesn't clobber the CC.
+; CC. Thus movqi chooses a move instruction that doesn't clobber the CC.
; If GCC wants to combine a move with a compare, it is smart enough to
; chose the move instruction that sets the CC.
diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c
index 86795af91ff..9ca9d2d3551 100644
--- a/gcc/config/cris/cris.c
+++ b/gcc/config/cris/cris.c
@@ -2488,7 +2488,6 @@ cris_symbol (rtx x)
case CONST_INT:
case CONST_DOUBLE:
- case CONSTANT_P_RTX:
return 0;
default:
@@ -2550,7 +2549,6 @@ cris_gotless_symbol (rtx x)
case CONST_INT:
case CONST_DOUBLE:
- case CONSTANT_P_RTX:
return 0;
default:
@@ -2595,7 +2593,6 @@ cris_got_symbol (rtx x)
case CONST_INT:
case CONST_DOUBLE:
- case CONSTANT_P_RTX:
return 0;
default:
@@ -2947,7 +2944,7 @@ cris_split_movdx (rtx *operands)
int reverse
= (refers_to_regno_p (dregno, dregno + 1, addr, NULL) != 0);
- /* The original code imples that we can't do
+ /* The original code implies that we can't do
move.x [rN+],rM move.x [rN],rM+1
when rN is dead, because of REG_NOTES damage. That is
consistent with what I've seen, so don't try it.
diff --git a/gcc/config/darwin-c.c b/gcc/config/darwin-c.c
index abe0a6b28b8..281d1668685 100644
--- a/gcc/config/darwin-c.c
+++ b/gcc/config/darwin-c.c
@@ -44,7 +44,8 @@ static void push_field_alignment (int);
static void pop_field_alignment (void);
static const char *find_subframework_file (const char *, const char *);
static void add_system_framework_path (char *);
-static const char *find_subframework_header (cpp_reader *pfile, const char *header);
+static const char *find_subframework_header (cpp_reader *pfile, const char *header,
+ cpp_dir **dirp);
typedef struct align_stack
{
@@ -166,11 +167,13 @@ static int max_frameworks = 0;
/* Remember which frameworks have been seen, so that we can ensure
that all uses of that framework come from the same framework. DIR
is the place where the named framework NAME, which is of length
- LEN, was found. */
+ LEN, was found. We copy the directory name from NAME, as it will be
+ freed by others. */
static void
add_framework (const char *name, size_t len, cpp_dir *dir)
{
+ char *dir_name;
int i;
for (i = 0; i < num_frameworks; ++i)
{
@@ -183,10 +186,14 @@ add_framework (const char *name, size_t len, cpp_dir *dir)
if (i >= max_frameworks)
{
max_frameworks = i*2;
+ max_frameworks += i == 0;
frameworks_in_use = xrealloc (frameworks_in_use,
max_frameworks*sizeof(*frameworks_in_use));
}
- frameworks_in_use[num_frameworks].name = name;
+ dir_name = xmalloc (len + 1);
+ memcpy (dir_name, name, len);
+ dir_name[len] = '\0';
+ frameworks_in_use[num_frameworks].name = dir_name;
frameworks_in_use[num_frameworks].len = len;
frameworks_in_use[num_frameworks].dir = dir;
++num_frameworks;
@@ -272,7 +279,8 @@ framework_construct_pathname (const char *fname, cpp_dir *dir)
if (stat (frname, &st) == 0)
{
- add_framework (fname, fname_len, dir);
+ if (fast_dir == 0)
+ add_framework (fname, fname_len, dir);
return frname;
}
}
@@ -445,7 +453,7 @@ darwin_register_frameworks (int stdinc)
returns non-zero. */
static const char*
-find_subframework_header (cpp_reader *pfile, const char *header)
+find_subframework_header (cpp_reader *pfile, const char *header, cpp_dir **dirp)
{
const char *fname = header;
struct cpp_buffer *b;
@@ -457,7 +465,14 @@ find_subframework_header (cpp_reader *pfile, const char *header)
{
n = find_subframework_file (fname, cpp_get_path (cpp_get_file (b)));
if (n)
- return n;
+ {
+ /* Logically, the place where we found the subframework is
+ the place where we found the Framework that contains the
+ subframework. This is useful for tracking wether or not
+ we are in a system header. */
+ *dirp = cpp_get_dir (cpp_get_file (b));
+ return n;
+ }
}
return 0;
diff --git a/gcc/config/darwin-crt2.c b/gcc/config/darwin-crt2.c
index 1ea2413c809..e225279bfa5 100644
--- a/gcc/config/darwin-crt2.c
+++ b/gcc/config/darwin-crt2.c
@@ -1,5 +1,5 @@
/* KeyMgr backwards-compatibility support for Darwin.
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -34,6 +34,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tconfig.h"
#include "tsystem.h"
+/* This file doesn't do anything useful on non-powerpc targets, since they
+ don't have backwards compatibility anyway. */
+
+#ifdef __ppc__
+
/* Homemade decls substituting for getsect.h and dyld.h, so cross
compilation works. */
struct mach_header;
@@ -149,3 +154,5 @@ __darwin_gcc3_preregister_frame_info (void)
_dyld_register_func_for_add_image (darwin_unwind_dyld_add_image_hook);
_dyld_register_func_for_remove_image (darwin_unwind_dyld_remove_image_hook);
}
+
+#endif /* __ppc__ */
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index b4d8b555e68..de8d0c419f0 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -41,9 +41,11 @@ Boston, MA 02111-1307, USA. */
/* Suppress g++ attempt to link in the math library automatically.
(Some Darwin versions have a libm, but they seem to cause problems
- for C++ executables.) */
-
+ for C++ executables.) This needs to be -lmx for Darwin 7.0 and
+ above. */
+#ifndef MATH_LIBRARY
#define MATH_LIBRARY ""
+#endif
/* We have atexit. */
@@ -287,11 +289,11 @@ Boston, MA 02111-1307, USA. */
%{!Zbundle:%{pg:%{static:-lgcrt0.o} \
%{!static:%{object:-lgcrt0.o} \
%{!object:%{preload:-lgcrt0.o} \
- %{!preload:-lgcrt1.o -lcrt2.o}}}} \
+ %{!preload:-lgcrt1.o crt2.o%s}}}} \
%{!pg:%{static:-lcrt0.o} \
%{!static:%{object:-lcrt0.o} \
%{!object:%{preload:-lcrt0.o} \
- %{!preload:-lcrt1.o -lcrt2.o}}}}}}"
+ %{!preload:-lcrt1.o crt2.o%s}}}}}}"
/* The native Darwin linker doesn't necessarily place files in the order
that they're specified on the link line. Thus, it is pointless
@@ -908,4 +910,9 @@ void add_framework_path (char *);
#define TARGET_HAS_F_SETLKW
+/* Darwin before 7.0 does not have C99 functions. */
+#ifndef TARGET_C99_FUNCTIONS
+#define TARGET_C99_FUNCTIONS 0
+#endif
+
#endif /* CONFIG_DARWIN_H */
diff --git a/gcc/config/darwin7.h b/gcc/config/darwin7.h
new file mode 100644
index 00000000000..0b215c2f6ab
--- /dev/null
+++ b/gcc/config/darwin7.h
@@ -0,0 +1,28 @@
+/* Target definitions for Darwin 7.0 and above (Mac OS X) systems.
+ Copyright (C) 2004
+ 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 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Darwin 7.0 and above have C99 functions. */
+#define TARGET_C99_FUNCTIONS 1
+
+/* But for some reason they are located in libmx so have it
+ be included when asked for and automatically when linking
+ with gfortran and g++. */
+#define MATH_LIBRARY "-lmx"
diff --git a/gcc/config/fr30/fr30.h b/gcc/config/fr30/fr30.h
index c7459f83205..81b5f1f9bc5 100644
--- a/gcc/config/fr30/fr30.h
+++ b/gcc/config/fr30/fr30.h
@@ -1208,7 +1208,7 @@ extern struct rtx_def * fr30_compare_op0;
extern struct rtx_def * fr30_compare_op1;
/*}}}*/
-/*{{{ PERDICATE_CODES. */
+/*{{{ PREDICATE_CODES. */
#define PREDICATE_CODES \
{ "stack_add_operand", { CONST_INT }}, \
diff --git a/gcc/config/frv/frv-protos.h b/gcc/config/frv/frv-protos.h
index 642635090d0..3a0e386d25d 100644
--- a/gcc/config/frv/frv-protos.h
+++ b/gcc/config/frv/frv-protos.h
@@ -53,7 +53,7 @@ extern frv_cpu_t frv_cpu_type; /* value of -mcpu= */
/* Define functions defined in frv.c */
extern void frv_expand_prologue (void);
-extern void frv_expand_epilogue (int);
+extern void frv_expand_epilogue (bool);
extern void frv_override_options (void);
extern void frv_optimization_options (int, int);
extern void frv_conditional_register_usage (void);
@@ -225,7 +225,7 @@ extern int even_acc_operand (rtx, enum machine_mode);
extern int quad_acc_operand (rtx, enum machine_mode);
extern int accg_operand (rtx, enum machine_mode);
extern rtx frv_matching_accg_for_acc (rtx);
-extern void frv_expand_fdpic_call (rtx *, int);
+extern void frv_expand_fdpic_call (rtx *, bool, bool);
extern rtx frv_gen_GPsym2reg (rtx, rtx);
#endif
diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c
index 242dfcde9ce..92e0dd213fa 100644
--- a/gcc/config/frv/frv.c
+++ b/gcc/config/frv/frv.c
@@ -285,6 +285,7 @@ static bool frv_cannot_force_const_mem (rtx);
static const char *unspec_got_name (int);
static void frv_output_const_unspec (FILE *,
const struct frv_unspec *);
+static bool frv_function_ok_for_sibcall (tree, tree);
static rtx frv_struct_value_rtx (tree, int);
/* Initialize the GCC target structure. */
@@ -319,6 +320,8 @@ static rtx frv_struct_value_rtx (tree, int);
#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE frv_use_dfa_pipeline_interface
+#undef TARGET_FUNCTION_OK_FOR_SIBCALL
+#define TARGET_FUNCTION_OK_FOR_SIBCALL frv_function_ok_for_sibcall
#undef TARGET_CANNOT_FORCE_CONST_MEM
#define TARGET_CANNOT_FORCE_CONST_MEM frv_cannot_force_const_mem
@@ -332,6 +335,16 @@ static rtx frv_struct_value_rtx (tree, int);
struct gcc_target targetm = TARGET_INITIALIZER;
+/* Any function call that satisfies the machine-independent
+ requirements is eligible on FR-V. */
+
+static bool
+frv_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
+ tree exp ATTRIBUTE_UNUSED)
+{
+ return true;
+}
+
/* Return true if SYMBOL is a small data symbol and relocation RELOC
can be used to access it directly in a load or store. */
@@ -1749,7 +1762,7 @@ frv_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
slots for arguments passed to the current function. */
void
-frv_expand_epilogue (int sibcall_p)
+frv_expand_epilogue (bool emit_return)
{
frv_stack_t *info = frv_stack_info ();
rtx fp = frame_pointer_rtx;
@@ -1769,9 +1782,7 @@ frv_expand_epilogue (int sibcall_p)
/* Set RETURN_ADDR to the address we should return to. Set it to NULL if
no return instruction should be emitted. */
- if (sibcall_p)
- return_addr = 0;
- else if (info->save_p[LR_REGNO])
+ if (info->save_p[LR_REGNO])
{
int lr_offset;
rtx mem;
@@ -1814,8 +1825,20 @@ frv_expand_epilogue (int sibcall_p)
if (current_function_calls_eh_return)
emit_insn (gen_stack_adjust (sp, sp, EH_RETURN_STACKADJ_RTX));
- if (return_addr)
+ if (emit_return)
emit_jump_insn (gen_epilogue_return (return_addr));
+ else
+ {
+ rtx lr = return_addr;
+
+ if (REGNO (return_addr) != LR_REGNO)
+ {
+ lr = gen_rtx_REG (Pmode, LR_REGNO);
+ emit_move_insn (lr, return_addr);
+ }
+
+ emit_insn (gen_rtx_USE (VOIDmode, lr));
+ }
}
@@ -3529,7 +3552,7 @@ frv_legitimate_memory_operand (rtx op, enum machine_mode mode, int condexec_p)
}
void
-frv_expand_fdpic_call (rtx *operands, int ret_value)
+frv_expand_fdpic_call (rtx *operands, bool ret_value, bool sibcall)
{
rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
rtx picreg = get_hard_reg_initial_val (SImode, FDPIC_REG);
@@ -3565,8 +3588,9 @@ frv_expand_fdpic_call (rtx *operands, int ret_value)
all external functions, so one would have to also mark function
declarations available in the same module with non-default
visibility, which is advantageous in itself. */
- if (GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (addr)
- && TARGET_INLINE_PLT)
+ if (GET_CODE (addr) == SYMBOL_REF
+ && ((!SYMBOL_REF_LOCAL_P (addr) && TARGET_INLINE_PLT)
+ || sibcall))
{
rtx x, dest;
dest = gen_reg_rtx (SImode);
@@ -3598,7 +3622,11 @@ frv_expand_fdpic_call (rtx *operands, int ret_value)
picreg = gen_reg_rtx (DImode);
emit_insn (gen_movdi_ldd (picreg, addr));
- if (ret_value)
+ if (sibcall && ret_value)
+ c = gen_sibcall_value_fdpicdi (rvrtx, picreg, const0_rtx);
+ else if (sibcall)
+ c = gen_sibcall_fdpicdi (picreg, const0_rtx);
+ else if (ret_value)
c = gen_call_value_fdpicdi (rvrtx, picreg, const0_rtx, lr);
else
c = gen_call_fdpicdi (picreg, const0_rtx, lr);
@@ -4766,6 +4794,21 @@ call_operand (rtx op, enum machine_mode mode)
return gpr_or_int12_operand (op, mode);
}
+/* Return true if operand is a memory reference suitable for a sibcall. */
+
+int
+sibcall_operand (rtx op, enum machine_mode mode)
+{
+ if (GET_MODE (op) != mode && mode != VOIDmode && GET_CODE (op) != CONST_INT)
+ return FALSE;
+
+ /* Note this doesn't allow reg+reg or reg+imm12 addressing (which should
+ never occur anyway), but prevents reload from not handling the case
+ properly of a call through a pointer on a function that calls
+ vfork/setjmp, etc. due to the need to flush all of the registers to stack. */
+ return gpr_or_int12_operand (op, mode);
+}
+
/* Return true if operator is a kind of relational operator. */
int
@@ -6627,7 +6670,7 @@ frv_ifcvt_init_extra_fields (ce_if_block_t *ce_info ATTRIBUTE_UNUSED)
}
-/* Internal function to add a potenial insn to the list of insns to be inserted
+/* Internal function to add a potential insn to the list of insns to be inserted
if the conditional execution conversion is successful. */
static void
diff --git a/gcc/config/frv/frv.h b/gcc/config/frv/frv.h
index d1f308282fa..9c62e36ed40 100644
--- a/gcc/config/frv/frv.h
+++ b/gcc/config/frv/frv.h
@@ -109,7 +109,7 @@
%{mmedia} %{mno-media} \
%{mmuladd} %{mno-muladd} \
%{mpack} %{mno-pack} \
- %{mfdpic} \
+ %{mno-fdpic:-mnopic} %{mfdpic} \
%{fpic|fpie: -mpic} %{fPIC|fPIE: -mPIC} %{mlibrary-pic}}"
/* Another C string constant used much like `LINK_SPEC'. The difference
@@ -151,7 +151,7 @@
%{mcpu=tomcat: %(cpp_fr500)} \
%{mcpu=simple: %(cpp_simple)} \
%{!mcpu*: %(cpp_cpu_default)} \
-%{mno-media: -D__FRV_ACC__=0 %{msoft-float: -D__FRV_FPR__=0}} \
+%{mno-media: -U__FRV_ACC__ -D__FRV_ACC__=0 %{msoft-float: -U__FRV_FPR__ -D__FRV_FPR__=0}} \
%{mhard-float: -D__FRV_HARD_FLOAT__} \
%{msoft-float: -U__FRV_HARD_FLOAT__} \
%{mgpr-32: -U__FRV_GPR__ -D__FRV_GPR__=32} \
@@ -203,7 +203,7 @@
-D__FRV_GPR__=32 \
-D__FRV_FPR__=0 \
-D__FRV_ACC__=0 \
-%{mmedia: -D__FRV_ACC__=8} \
+%{mmedia: -U__FRV_ACC__ -D__FRV_ACC__=8} \
%{mhard-float|mmedia: -D__FRV_FPR__=64}"
#define MASK_DEFAULT_FRV \
@@ -931,7 +931,7 @@ extern int target_flags;
#define LAST_ARG_REGNUM (FIRST_ARG_REGNUM + FRV_NUM_ARG_REGS - 1)
/* Registers used by the exception handling functions. These should be
- registers that are not otherwised used by the calling sequence. */
+ registers that are not otherwise used by the calling sequence. */
#define FIRST_EH_REGNUM 14
#define LAST_EH_REGNUM 15
@@ -2639,8 +2639,7 @@ fixup_section (void) \
( GET_CODE (X) == CONST_INT \
|| GET_CODE (X) == CONST_DOUBLE \
|| (GET_CODE (X) == HIGH && GET_CODE (XEXP (X, 0)) == CONST_INT) \
- || got12_operand (X, VOIDmode) \
- || GET_CODE (X) == CONSTANT_P_RTX)
+ || got12_operand (X, VOIDmode)) \
/* The Overall Framework of an Assembler File. */
@@ -3111,8 +3110,10 @@ do { \
{ "odd_fpr_operand", { REG, SUBREG }}, \
{ "dbl_memory_one_insn_operand", { MEM }}, \
{ "dbl_memory_two_insn_operand", { MEM }}, \
- { "call_operand", { REG, SUBREG, PLUS, CONST_INT, \
- SYMBOL_REF, LABEL_REF, CONST }}, \
+ { "call_operand", { REG, SUBREG, CONST_INT, \
+ CONST, SYMBOL_REF }}, \
+ { "sibcall_operand", { REG, SUBREG, CONST_INT, \
+ CONST }}, \
{ "upper_int16_operand", { CONST_INT }}, \
{ "uint16_operand", { CONST_INT }}, \
{ "relational_operator", { EQ, NE, LE, LT, GE, GT, \
diff --git a/gcc/config/frv/frv.md b/gcc/config/frv/frv.md
index ef2b49d128c..92329cc443d 100644
--- a/gcc/config/frv/frv.md
+++ b/gcc/config/frv/frv.md
@@ -2788,7 +2788,7 @@
[(set_attr "length" "8")
(set_attr "type" "multi")])
-;; Patterns for addsi3/subdi3 after spliting
+;; Patterns for addsi3/subdi3 after splitting
(define_insn "adddi3_lower"
[(set (match_operand:SI 0 "integer_register_operand" "=d")
(plus:SI (match_operand:SI 1 "integer_register_operand" "d")
@@ -5260,7 +5260,7 @@
operands[2] = const0_rtx;
if (TARGET_FDPIC)
- frv_expand_fdpic_call (operands, 0);
+ frv_expand_fdpic_call (operands, false, false);
else
emit_call_insn (gen_call_internal (addr, operands[1], operands[2], lr));
@@ -5308,7 +5308,7 @@
(match_operand 1 "" ""))
(clobber (match_operand:SI 2 "lr_operand" "=l"))]
"TARGET_FDPIC"
- "calll %M0"
+ "call%i0l %M0"
[(set_attr "length" "4")
(set_attr "type" "jumpl")])
@@ -5325,6 +5325,65 @@
[(set_attr "length" "4")
(set_attr "type" "call,jumpl")])
+(define_expand "sibcall"
+ [(use (match_operand:QI 0 "" ""))
+ (use (match_operand 1 "" ""))
+ (use (match_operand 2 "" ""))
+ (use (match_operand 3 "" ""))]
+ ""
+ "
+{
+ rtx addr;
+
+ if (GET_CODE (operands[0]) != MEM)
+ abort ();
+
+ addr = XEXP (operands[0], 0);
+ if (! sibcall_operand (addr, Pmode))
+ addr = force_reg (Pmode, addr);
+
+ if (! operands[2])
+ operands[2] = const0_rtx;
+
+ if (TARGET_FDPIC)
+ frv_expand_fdpic_call (operands, false, true);
+ else
+ emit_call_insn (gen_sibcall_internal (addr, operands[1], operands[2]));
+
+ DONE;
+}")
+
+;; It might seem that these sibcall patterns are missing references to
+;; LR, but they're not necessary because sibcall_epilogue will make
+;; sure LR is restored, and having LR here will set
+;; regs_ever_used[REG_LR], forcing it to be saved on the stack, and
+;; then restored in sibcalls and regular return code paths, even if
+;; the function becomes a leaf function after tail-call elimination.
+
+;; We must not use a call-saved register here. `W' limits ourselves
+;; to gr14 or gr15, but since we're almost running out of constraint
+;; letters, and most other call-clobbered registers are often used for
+;; argument-passing, this will do.
+(define_insn "sibcall_internal"
+ [(call (mem:QI (match_operand:SI 0 "sibcall_operand" "WNOP"))
+ (match_operand 1 "" ""))
+ (use (match_operand 2 "" ""))
+ (return)]
+ "! TARGET_FDPIC"
+ "jmp%i0l %M0"
+ [(set_attr "length" "4")
+ (set_attr "type" "jumpl")])
+
+(define_insn "sibcall_fdpicdi"
+ [(call (mem:QI (match_operand:DI 0 "fdpic_fptr_operand" "W"))
+ (match_operand 1 "" ""))
+ (return)]
+ "TARGET_FDPIC"
+ "jmp%i0l %M0"
+ [(set_attr "length" "4")
+ (set_attr "type" "jumpl")])
+
+
;; Subroutine call instruction returning a value. Operand 0 is the hard
;; register in which the value is returned. There are three more operands, the
;; same as the three operands of the `call' instruction (but with numbers
@@ -5355,7 +5414,7 @@
operands[3] = const0_rtx;
if (TARGET_FDPIC)
- frv_expand_fdpic_call (operands, 1);
+ frv_expand_fdpic_call (operands, true, false);
else
emit_call_insn (gen_call_value_internal (operands[0], addr, operands[2],
operands[3], lr));
@@ -5382,7 +5441,7 @@
(match_operand 2 "" "")))
(clobber (match_operand:SI 3 "lr_operand" "=l"))]
"TARGET_FDPIC"
- "calll %M1"
+ "call%i1l %M1"
[(set_attr "length" "4")
(set_attr "type" "jumpl")])
@@ -5400,6 +5459,56 @@
[(set_attr "length" "4")
(set_attr "type" "call,jumpl")])
+(define_expand "sibcall_value"
+ [(use (match_operand 0 "" ""))
+ (use (match_operand:QI 1 "" ""))
+ (use (match_operand 2 "" ""))
+ (use (match_operand 3 "" ""))
+ (use (match_operand 4 "" ""))]
+ ""
+ "
+{
+ rtx addr;
+
+ if (GET_CODE (operands[1]) != MEM)
+ abort ();
+
+ addr = XEXP (operands[1], 0);
+ if (! sibcall_operand (addr, Pmode))
+ addr = force_reg (Pmode, addr);
+
+ if (! operands[3])
+ operands[3] = const0_rtx;
+
+ if (TARGET_FDPIC)
+ frv_expand_fdpic_call (operands, true, true);
+ else
+ emit_call_insn (gen_sibcall_value_internal (operands[0], addr, operands[2],
+ operands[3]));
+ DONE;
+}")
+
+(define_insn "sibcall_value_internal"
+ [(set (match_operand 0 "register_operand" "=d")
+ (call (mem:QI (match_operand:SI 1 "sibcall_operand" "WNOP"))
+ (match_operand 2 "" "")))
+ (use (match_operand 3 "" ""))
+ (return)]
+ "! TARGET_FDPIC"
+ "jmp%i1l %M1"
+ [(set_attr "length" "4")
+ (set_attr "type" "jumpl")])
+
+(define_insn "sibcall_value_fdpicdi"
+ [(set (match_operand 0 "register_operand" "=d")
+ (call (mem:QI (match_operand:DI 1 "fdpic_fptr_operand" "W"))
+ (match_operand 2 "" "")))
+ (return)]
+ "TARGET_FDPIC"
+ "jmp%i1l %M1"
+ [(set_attr "length" "4")
+ (set_attr "type" "jumpl")])
+
;; return instruction generated instead of jmp to epilog
(define_expand "return"
[(parallel [(return)
@@ -5430,6 +5539,54 @@
[(set_attr "length" "4")
(set_attr "type" "jump,jumpl")])
+(define_insn "*return_true"
+ [(set (pc)
+ (if_then_else (match_operator:CC 0 "signed_relational_operator"
+ [(match_operand 1 "icc_operand" "t")
+ (const_int 0)])
+ (return)
+ (pc)))]
+ "direct_return_p ()"
+ "b%c0lr %1,%#"
+ [(set_attr "length" "4")
+ (set_attr "type" "jump")])
+
+(define_insn "*return_false"
+ [(set (pc)
+ (if_then_else (match_operator:CC 0 "signed_relational_operator"
+ [(match_operand 1 "icc_operand" "t")
+ (const_int 0)])
+ (pc)
+ (return)))]
+ "direct_return_p ()"
+ "b%C0lr %1,%#"
+ [(set_attr "length" "4")
+ (set_attr "type" "jump")])
+
+(define_insn "*return_unsigned_true"
+ [(set (pc)
+ (if_then_else (match_operator:CC_UNS 0 "unsigned_relational_operator"
+ [(match_operand 1 "icc_operand" "t")
+ (const_int 0)])
+ (return)
+ (pc)))]
+ "direct_return_p ()"
+ "b%c0lr %1,%#"
+ [(set_attr "length" "4")
+ (set_attr "type" "jump")])
+
+(define_insn "*return_unsigned_false"
+ [(set (pc)
+ (if_then_else (match_operator:CC_UNS 0 "unsigned_relational_operator"
+ [(match_operand 1 "icc_operand" "t")
+ (const_int 0)])
+ (pc)
+ (return)))]
+ "direct_return_p ()"
+ "b%C0lr %1,%#"
+ [(set_attr "length" "4")
+ (set_attr "type" "jump")])
+
;; A version of addsi3 for deallocating stack space at the end of the
;; epilogue. The addition is done in parallel with an (unspec_volatile),
;; which represents the clobbering of the deallocated space.
@@ -5634,7 +5791,7 @@
""
"
{
- frv_expand_epilogue (FALSE);
+ frv_expand_epilogue (true);
DONE;
}")
@@ -5650,7 +5807,7 @@
""
"
{
- frv_expand_epilogue (TRUE);
+ frv_expand_epilogue (false);
DONE;
}")
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index 6bf3bfcfa68..9efa140c23b 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -384,7 +384,7 @@ h8300_emit_stack_adjustment (int sign, unsigned int size)
if (TARGET_H8300
&& size > 4
&& !h8300_current_function_interrupt_function_p ()
- && !(current_function_needs_context && sign < 0))
+ && !(cfun->static_chain_decl != NULL && sign < 0))
{
rtx r3 = gen_rtx_REG (Pmode, 3);
emit_insn (gen_movhi (r3, GEN_INT (sign * size)));
@@ -4671,7 +4671,7 @@ same_cmp_following_p (rtx i1)
}
/* Return nonzero if OPERANDS are valid for stm (or ldm) that pushes
- (or pops) N registers. OPERANDS are asssumed to be an array of
+ (or pops) N registers. OPERANDS are assumed to be an array of
registers. */
int
diff --git a/gcc/config/host-linux.c b/gcc/config/host-linux.c
index 7302d381dbe..777cfa9f894 100644
--- a/gcc/config/host-linux.c
+++ b/gcc/config/host-linux.c
@@ -71,6 +71,10 @@
# define TRY_EMPTY_VM_SPACE 0x1000000000
#elif defined(__i386)
# define TRY_EMPTY_VM_SPACE 0x60000000
+#elif defined(__s390x__)
+# define TRY_EMPTY_VM_SPACE 0x8000000000
+#elif defined(__s390__)
+# define TRY_EMPTY_VM_SPACE 0x60000000
#else
# define TRY_EMPTY_VM_SPACE 0
#endif
diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h
index 85027925ec1..69d7f7920ae 100644
--- a/gcc/config/i386/cygming.h
+++ b/gcc/config/i386/cygming.h
@@ -25,6 +25,27 @@ Boston, MA 02111-1307, USA. */
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+#ifdef HAVE_GAS_PE_SECREL32_RELOC
+#define DWARF2_DEBUGGING_INFO 1
+
+#undef DBX_REGISTER_NUMBER
+#define DBX_REGISTER_NUMBER(n) (write_symbols == DWARF2_DEBUG \
+ ? svr4_dbx_register_map[n] \
+ : dbx_register_map[n])
+
+/* Use section relative relocations for debugging offsets. Unlike
+ other targets that fake this by putting the section VMA at 0, PE
+ won't allow it. */
+#define ASM_OUTPUT_DWARF_OFFSET(FILE, SIZE, LABEL) \
+ do { \
+ if (SIZE != 4) \
+ abort (); \
+ \
+ fputs ("\t.secrel32\t", FILE); \
+ assemble_name (FILE, LABEL); \
+ } while (0)
+#endif
+
#define TARGET_EXECUTABLE_SUFFIX ".exe"
#include <stdio.h>
diff --git a/gcc/config/i386/gthr-win32.c b/gcc/config/i386/gthr-win32.c
index 4e2b282251d..e4852afef80 100644
--- a/gcc/config/i386/gthr-win32.c
+++ b/gcc/config/i386/gthr-win32.c
@@ -61,10 +61,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
This may cause incorrect error return due to truncation values on
hw where sizeof (DWORD) > sizeof (int).
- 3. We might consider using Critical Sections instead of Windows32
- mutexes for better performance, but emulating __gthread_mutex_trylock
- interface becomes more complicated (Win9x does not support
- TryEnterCriticalSectioni, while NT does).
+ 3. We are currently using a special mutex instead of the Critical
+ Sections, since Win9x does not support TryEnterCriticalSection
+ (while NT does).
The basic framework should work well enough. In the long term, GCC
needs to use Structured Exception Handling on Windows32. */
@@ -145,23 +144,29 @@ __gthr_win32_setspecific (__gthread_key_t key, const void *ptr)
void
__gthr_win32_mutex_init_function (__gthread_mutex_t *mutex)
{
- /* Create unnamed mutex with default security attr and no initial owner. */
- *mutex = CreateMutex (NULL, 0, NULL);
+ mutex->counter = 0;
+ mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL);
}
int
__gthr_win32_mutex_lock (__gthread_mutex_t *mutex)
{
- if (WaitForSingleObject (*mutex, INFINITE) == WAIT_OBJECT_0)
+ if (InterlockedIncrement (&mutex->counter) == 1 ||
+ WaitForSingleObject (mutex->sema, INFINITE) == WAIT_OBJECT_0)
return 0;
else
- return 1;
+ {
+ // WaitForSingleObject returns WAIT_FAILED, and we can only do
+ // some best-effort cleanup here.
+ InterlockedDecrement (&mutex->counter);
+ return 1;
+ }
}
int
__gthr_win32_mutex_trylock (__gthread_mutex_t *mutex)
{
- if (WaitForSingleObject (*mutex, 0) == WAIT_OBJECT_0)
+ if (InterlockedCompareExchange (&mutex->counter, 1, 0 ) == 0)
return 0;
else
return 1;
@@ -170,5 +175,8 @@ __gthr_win32_mutex_trylock (__gthread_mutex_t *mutex)
int
__gthr_win32_mutex_unlock (__gthread_mutex_t *mutex)
{
- return (ReleaseMutex (*mutex) != 0) ? 0 : 1;
+ if (InterlockedDecrement (&mutex->counter))
+ return ReleaseSemaphore (mutex->sema, 1, NULL) ? 0 : 1;
+ else
+ return 0;
}
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index d95be60e23f..42771f95051 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -182,6 +182,9 @@ extern bool ix86_fp_jump_nontrivial_p (enum rtx_code);
extern void x86_order_regs_for_local_alloc (void);
extern void x86_function_profiler (FILE *, int);
extern void x86_emit_floatuns (rtx [2]);
+extern void ix86_emit_fp_unordered_jump (rtx);
+
+extern void ix86_emit_i387_log1p (rtx, rtx);
extern enum rtx_code ix86_reverse_condition (enum rtx_code, enum machine_mode);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 615f2eeec49..9e8fdf48d0e 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -10636,7 +10636,7 @@ ix86_split_to_parts (rtx operand, rtx *parts, enum machine_mode mode)
long l[3];
REAL_VALUE_FROM_CONST_DOUBLE (r, operand);
- REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
+ real_to_target (l, &r, mode);
/* Do not use shift by 32 to avoid warning on 32bit systems. */
if (HOST_BITS_PER_WIDE_INT >= 64)
parts[0]
@@ -15817,7 +15817,7 @@ ix86_expand_vector_init (rtx target, rtx vals)
}
/* ... values where only first field is non-constant are best loaded
- from the pool and overwriten via move later. */
+ from the pool and overwritten via move later. */
if (!i)
{
rtx op = simplify_gen_subreg (mode, XVECEXP (vals, 0, 0),
@@ -15928,4 +15928,67 @@ output_387_reg_move (rtx insn, rtx *operands)
return "fst\t%y0";
}
+/* Output code to perform a conditional jump to LABEL, if C2 flag in
+ FP status register is set. */
+
+void
+ix86_emit_fp_unordered_jump (rtx label)
+{
+ rtx reg = gen_reg_rtx (HImode);
+ rtx temp;
+
+ emit_insn (gen_x86_fnstsw_1 (reg));
+
+ if (TARGET_USE_SAHF)
+ {
+ emit_insn (gen_x86_sahf_1 (reg));
+
+ temp = gen_rtx_REG (CCmode, FLAGS_REG);
+ temp = gen_rtx_UNORDERED (VOIDmode, temp, const0_rtx);
+ }
+ else
+ {
+ emit_insn (gen_testqi_ext_ccno_0 (reg, GEN_INT (0x04)));
+
+ temp = gen_rtx_REG (CCNOmode, FLAGS_REG);
+ temp = gen_rtx_NE (VOIDmode, temp, const0_rtx);
+ }
+
+ temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
+ gen_rtx_LABEL_REF (VOIDmode, label),
+ pc_rtx);
+ temp = gen_rtx_SET (VOIDmode, pc_rtx, temp);
+ emit_jump_insn (temp);
+}
+
+/* Output code to perform a log1p XFmode calculation. */
+
+void ix86_emit_i387_log1p (rtx op0, rtx op1)
+{
+ rtx label1 = gen_label_rtx ();
+ rtx label2 = gen_label_rtx ();
+
+ rtx tmp = gen_reg_rtx (XFmode);
+ rtx tmp2 = gen_reg_rtx (XFmode);
+
+ emit_insn (gen_absxf2 (tmp, op1));
+ emit_insn (gen_cmpxf (tmp,
+ CONST_DOUBLE_FROM_REAL_VALUE (
+ REAL_VALUE_ATOF ("0.29289321881345247561810596348408353", XFmode),
+ XFmode)));
+ emit_jump_insn (gen_bge (label1));
+
+ emit_move_insn (tmp2, standard_80387_constant_rtx (4)); /* fldln2 */
+ emit_insn (gen_fyl2xp1_xf3 (op0, tmp2, op1));
+ emit_jump (label2);
+
+ emit_label (label1);
+ emit_move_insn (tmp, CONST1_RTX (XFmode));
+ emit_insn (gen_addxf3 (tmp, op1, tmp));
+ emit_move_insn (tmp2, standard_80387_constant_rtx (4)); /* fldln2 */
+ emit_insn (gen_fyl2x_xf3 (op0, tmp2, tmp));
+
+ emit_label (label2);
+}
+
#include "gt-i386.h"
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index c8590d55074..b1366799ba3 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -117,12 +117,23 @@
; x87 Floating point
(UNSPEC_FPATAN 65)
(UNSPEC_FYL2X 66)
- (UNSPEC_FSCALE 67)
+ (UNSPEC_FYL2XP1 67)
(UNSPEC_FRNDINT 68)
(UNSPEC_F2XM1 69)
+ ; x87 Double output FP
(UNSPEC_SINCOS_COS 80)
(UNSPEC_SINCOS_SIN 81)
+ (UNSPEC_TAN_ONE 82)
+ (UNSPEC_TAN_TAN 83)
+ (UNSPEC_XTRACT_FRACT 84)
+ (UNSPEC_XTRACT_EXP 85)
+ (UNSPEC_FSCALE_FRACT 86)
+ (UNSPEC_FSCALE_EXP 87)
+ (UNSPEC_FPREM_F 88)
+ (UNSPEC_FPREM_U 89)
+ (UNSPEC_FPREM1_F 90)
+ (UNSPEC_FPREM1_U 91)
; REP instruction
(UNSPEC_REP 75)
@@ -935,9 +946,9 @@
;; FP compares, step 2
;; Move the fpsw to ax.
-(define_insn "*x86_fnstsw_1"
+(define_insn "x86_fnstsw_1"
[(set (match_operand:HI 0 "register_operand" "=a")
- (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
+ (unspec:HI [(reg:CCFP 18)] UNSPEC_FNSTSW))]
"TARGET_80387"
"fnstsw\t%0"
[(set_attr "length" "2")
@@ -14852,6 +14863,172 @@
(set_attr "mode" "XF")
(set_attr "athlon_decode" "direct")])
+(define_insn "fpremxf4"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 2 "register_operand" "0")
+ (match_operand:XF 3 "register_operand" "1")]
+ UNSPEC_FPREM_F))
+ (set (match_operand:XF 1 "register_operand" "=u")
+ (unspec:XF [(match_dup 2) (match_dup 3)]
+ UNSPEC_FPREM_U))
+ (set (reg:CCFP 18)
+ (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fprem"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "XF")])
+
+(define_expand "fmodsf3"
+ [(use (match_operand:SF 0 "register_operand" ""))
+ (use (match_operand:SF 1 "register_operand" ""))
+ (use (match_operand:SF 2 "register_operand" ""))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx label = gen_label_rtx ();
+
+ rtx op1 = gen_reg_rtx (XFmode);
+ rtx op2 = gen_reg_rtx (XFmode);
+
+ emit_insn(gen_extendsfxf2 (op1, operands[1]));
+ emit_insn(gen_extendsfxf2 (op2, operands[2]));
+
+ emit_label (label);
+
+ emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
+ ix86_emit_fp_unordered_jump (label);
+
+ emit_insn (gen_truncxfsf2_noop (operands[0], op1));
+ DONE;
+})
+
+(define_expand "fmoddf3"
+ [(use (match_operand:DF 0 "register_operand" ""))
+ (use (match_operand:DF 1 "register_operand" ""))
+ (use (match_operand:DF 2 "register_operand" ""))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx label = gen_label_rtx ();
+
+ rtx op1 = gen_reg_rtx (XFmode);
+ rtx op2 = gen_reg_rtx (XFmode);
+
+ emit_insn (gen_extenddfxf2 (op1, operands[1]));
+ emit_insn (gen_extenddfxf2 (op2, operands[2]));
+
+ emit_label (label);
+
+ emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
+ ix86_emit_fp_unordered_jump (label);
+
+ emit_insn (gen_truncxfdf2_noop (operands[0], op1));
+ DONE;
+})
+
+(define_expand "fmodxf3"
+ [(use (match_operand:XF 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))
+ (use (match_operand:XF 2 "register_operand" ""))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx label = gen_label_rtx ();
+
+ emit_label (label);
+
+ emit_insn (gen_fpremxf4 (operands[1], operands[2],
+ operands[1], operands[2]));
+ ix86_emit_fp_unordered_jump (label);
+
+ emit_move_insn (operands[0], operands[1]);
+ DONE;
+})
+
+(define_insn "fprem1xf4"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 2 "register_operand" "0")
+ (match_operand:XF 3 "register_operand" "1")]
+ UNSPEC_FPREM1_F))
+ (set (match_operand:XF 1 "register_operand" "=u")
+ (unspec:XF [(match_dup 2) (match_dup 3)]
+ UNSPEC_FPREM1_U))
+ (set (reg:CCFP 18)
+ (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fprem1"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "XF")])
+
+(define_expand "dremsf3"
+ [(use (match_operand:SF 0 "register_operand" ""))
+ (use (match_operand:SF 1 "register_operand" ""))
+ (use (match_operand:SF 2 "register_operand" ""))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx label = gen_label_rtx ();
+
+ rtx op1 = gen_reg_rtx (XFmode);
+ rtx op2 = gen_reg_rtx (XFmode);
+
+ emit_insn(gen_extendsfxf2 (op1, operands[1]));
+ emit_insn(gen_extendsfxf2 (op2, operands[2]));
+
+ emit_label (label);
+
+ emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
+ ix86_emit_fp_unordered_jump (label);
+
+ emit_insn (gen_truncxfsf2_noop (operands[0], op1));
+ DONE;
+})
+
+(define_expand "dremdf3"
+ [(use (match_operand:DF 0 "register_operand" ""))
+ (use (match_operand:DF 1 "register_operand" ""))
+ (use (match_operand:DF 2 "register_operand" ""))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx label = gen_label_rtx ();
+
+ rtx op1 = gen_reg_rtx (XFmode);
+ rtx op2 = gen_reg_rtx (XFmode);
+
+ emit_insn (gen_extenddfxf2 (op1, operands[1]));
+ emit_insn (gen_extenddfxf2 (op2, operands[2]));
+
+ emit_label (label);
+
+ emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
+ ix86_emit_fp_unordered_jump (label);
+
+ emit_insn (gen_truncxfdf2_noop (operands[0], op1));
+ DONE;
+})
+
+(define_expand "dremxf3"
+ [(use (match_operand:XF 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))
+ (use (match_operand:XF 2 "register_operand" ""))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx label = gen_label_rtx ();
+
+ emit_label (label);
+
+ emit_insn (gen_fprem1xf4 (operands[1], operands[2],
+ operands[1], operands[2]));
+ ix86_emit_fp_unordered_jump (label);
+
+ emit_move_insn (operands[0], operands[1]);
+ DONE;
+})
+
(define_insn "*sindf2"
[(set (match_operand:DF 0 "register_operand" "=f")
(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
@@ -14931,7 +15108,7 @@
;; With sincos pattern defined, sin and cos builtin function will be
;; expanded to sincos pattern with one of its outputs left unused.
;; Cse pass will detected, if two sincos patterns can be combined,
-;; otherwise sincos pattern will be splitted back to sin or cos pattern,
+;; otherwise sincos pattern will be split back to sin or cos pattern,
;; depending on the unused output.
(define_insn "sincosdf3"
@@ -15078,6 +15255,132 @@
[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
"")
+(define_insn "*tandf3_1"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
+ UNSPEC_TAN_ONE))
+ (set (match_operand:DF 1 "register_operand" "=u")
+ (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fptan"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "DF")])
+
+;; optimize sequence: fptan
+;; fstp %st(0)
+;; fld1
+;; into fptan insn.
+
+(define_peephole2
+ [(parallel[(set (match_operand:DF 0 "register_operand" "")
+ (unspec:DF [(match_operand:DF 2 "register_operand" "")]
+ UNSPEC_TAN_ONE))
+ (set (match_operand:DF 1 "register_operand" "")
+ (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
+ (set (match_dup 0)
+ (match_operand:DF 3 "immediate_operand" ""))]
+ "standard_80387_constant_p (operands[3]) == 2"
+ [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
+ (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
+ "")
+
+(define_expand "tandf2"
+ [(parallel [(set (match_dup 2)
+ (unspec:DF [(match_operand:DF 1 "register_operand" "")]
+ UNSPEC_TAN_ONE))
+ (set (match_operand:DF 0 "register_operand" "")
+ (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (DFmode);
+})
+
+(define_insn "*tansf3_1"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
+ UNSPEC_TAN_ONE))
+ (set (match_operand:SF 1 "register_operand" "=u")
+ (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fptan"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "SF")])
+
+;; optimize sequence: fptan
+;; fstp %st(0)
+;; fld1
+;; into fptan insn.
+
+(define_peephole2
+ [(parallel[(set (match_operand:SF 0 "register_operand" "")
+ (unspec:SF [(match_operand:SF 2 "register_operand" "")]
+ UNSPEC_TAN_ONE))
+ (set (match_operand:SF 1 "register_operand" "")
+ (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
+ (set (match_dup 0)
+ (match_operand:SF 3 "immediate_operand" ""))]
+ "standard_80387_constant_p (operands[3]) == 2"
+ [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
+ (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
+ "")
+
+(define_expand "tansf2"
+ [(parallel [(set (match_dup 2)
+ (unspec:SF [(match_operand:SF 1 "register_operand" "")]
+ UNSPEC_TAN_ONE))
+ (set (match_operand:SF 0 "register_operand" "")
+ (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (SFmode);
+})
+
+(define_insn "*tanxf3_1"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
+ UNSPEC_TAN_ONE))
+ (set (match_operand:XF 1 "register_operand" "=u")
+ (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fptan"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "XF")])
+
+;; optimize sequence: fptan
+;; fstp %st(0)
+;; fld1
+;; into fptan insn.
+
+(define_peephole2
+ [(parallel[(set (match_operand:XF 0 "register_operand" "")
+ (unspec:XF [(match_operand:XF 2 "register_operand" "")]
+ UNSPEC_TAN_ONE))
+ (set (match_operand:XF 1 "register_operand" "")
+ (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
+ (set (match_dup 0)
+ (match_operand:XF 3 "immediate_operand" ""))]
+ "standard_80387_constant_p (operands[3]) == 2"
+ [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
+ (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
+ "")
+
+(define_expand "tanxf2"
+ [(parallel [(set (match_dup 2)
+ (unspec:XF [(match_operand:XF 1 "register_operand" "")]
+ UNSPEC_TAN_ONE))
+ (set (match_operand:XF 0 "register_operand" "")
+ (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (XFmode);
+})
+
(define_insn "atan2df3_1"
[(set (match_operand:DF 0 "register_operand" "=f")
(unspec:DF [(match_operand:DF 2 "register_operand" "0")
@@ -15103,6 +15406,19 @@
DONE;
})
+(define_expand "atandf2"
+ [(parallel [(set (match_operand:DF 0 "register_operand" "")
+ (unspec:DF [(match_dup 2)
+ (match_operand:DF 1 "register_operand" "")]
+ UNSPEC_FPATAN))
+ (clobber (match_scratch:DF 3 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (DFmode);
+ emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
+})
+
(define_insn "atan2sf3_1"
[(set (match_operand:SF 0 "register_operand" "=f")
(unspec:SF [(match_operand:SF 2 "register_operand" "0")
@@ -15128,6 +15444,19 @@
DONE;
})
+(define_expand "atansf2"
+ [(parallel [(set (match_operand:SF 0 "register_operand" "")
+ (unspec:SF [(match_dup 2)
+ (match_operand:SF 1 "register_operand" "")]
+ UNSPEC_FPATAN))
+ (clobber (match_scratch:SF 3 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (SFmode);
+ emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
+})
+
(define_insn "atan2xf3_1"
[(set (match_operand:XF 0 "register_operand" "=f")
(unspec:XF [(match_operand:XF 2 "register_operand" "0")
@@ -15153,31 +15482,154 @@
DONE;
})
-(define_insn "*fyl2x_sfxf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (unspec:SF [(match_operand:SF 2 "register_operand" "0")
- (match_operand:XF 1 "register_operand" "u")]
- UNSPEC_FYL2X))
- (clobber (match_scratch:SF 3 "=1"))]
+(define_expand "atanxf2"
+ [(parallel [(set (match_operand:XF 0 "register_operand" "")
+ (unspec:XF [(match_dup 2)
+ (match_operand:XF 1 "register_operand" "")]
+ UNSPEC_FPATAN))
+ (clobber (match_scratch:XF 3 ""))])]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
- "fyl2x"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "SF")])
+{
+ operands[2] = gen_reg_rtx (XFmode);
+ emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
+})
-(define_insn "*fyl2x_dfxf3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (unspec:DF [(match_operand:DF 2 "register_operand" "0")
- (match_operand:XF 1 "register_operand" "u")]
- UNSPEC_FYL2X))
- (clobber (match_scratch:DF 3 "=1"))]
+(define_expand "asindf2"
+ [(set (match_dup 2)
+ (float_extend:XF (match_operand:DF 1 "register_operand" "")))
+ (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
+ (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
+ (set (match_dup 6) (sqrt:XF (match_dup 5)))
+ (parallel [(set (match_dup 7)
+ (unspec:XF [(match_dup 6) (match_dup 2)]
+ UNSPEC_FPATAN))
+ (clobber (match_scratch:XF 8 ""))])
+ (set (match_operand:DF 0 "register_operand" "")
+ (float_truncate:DF (match_dup 7)))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
- "fyl2x"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "DF")])
+{
+ int i;
+
+ for (i=2; i<8; i++)
+ operands[i] = gen_reg_rtx (XFmode);
+
+ emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
+})
+
+(define_expand "asinsf2"
+ [(set (match_dup 2)
+ (float_extend:XF (match_operand:SF 1 "register_operand" "")))
+ (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
+ (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
+ (set (match_dup 6) (sqrt:XF (match_dup 5)))
+ (parallel [(set (match_dup 7)
+ (unspec:XF [(match_dup 6) (match_dup 2)]
+ UNSPEC_FPATAN))
+ (clobber (match_scratch:XF 8 ""))])
+ (set (match_operand:SF 0 "register_operand" "")
+ (float_truncate:SF (match_dup 7)))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ int i;
+
+ for (i=2; i<8; i++)
+ operands[i] = gen_reg_rtx (XFmode);
+
+ emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
+})
+
+(define_expand "asinxf2"
+ [(set (match_dup 2)
+ (mult:XF (match_operand:XF 1 "register_operand" "")
+ (match_dup 1)))
+ (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
+ (set (match_dup 5) (sqrt:XF (match_dup 4)))
+ (parallel [(set (match_operand:XF 0 "register_operand" "")
+ (unspec:XF [(match_dup 5) (match_dup 1)]
+ UNSPEC_FPATAN))
+ (clobber (match_scratch:XF 6 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ int i;
+
+ for (i=2; i<6; i++)
+ operands[i] = gen_reg_rtx (XFmode);
+
+ emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
+})
+
+(define_expand "acosdf2"
+ [(set (match_dup 2)
+ (float_extend:XF (match_operand:DF 1 "register_operand" "")))
+ (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
+ (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
+ (set (match_dup 6) (sqrt:XF (match_dup 5)))
+ (parallel [(set (match_dup 7)
+ (unspec:XF [(match_dup 2) (match_dup 6)]
+ UNSPEC_FPATAN))
+ (clobber (match_scratch:XF 8 ""))])
+ (set (match_operand:DF 0 "register_operand" "")
+ (float_truncate:DF (match_dup 7)))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ int i;
+
+ for (i=2; i<8; i++)
+ operands[i] = gen_reg_rtx (XFmode);
+
+ emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
+})
+
+(define_expand "acossf2"
+ [(set (match_dup 2)
+ (float_extend:XF (match_operand:SF 1 "register_operand" "")))
+ (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
+ (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
+ (set (match_dup 6) (sqrt:XF (match_dup 5)))
+ (parallel [(set (match_dup 7)
+ (unspec:XF [(match_dup 2) (match_dup 6)]
+ UNSPEC_FPATAN))
+ (clobber (match_scratch:XF 8 ""))])
+ (set (match_operand:SF 0 "register_operand" "")
+ (float_truncate:SF (match_dup 7)))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ int i;
+
+ for (i=2; i<8; i++)
+ operands[i] = gen_reg_rtx (XFmode);
+
+ emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
+})
+
+(define_expand "acosxf2"
+ [(set (match_dup 2)
+ (mult:XF (match_operand:XF 1 "register_operand" "")
+ (match_dup 1)))
+ (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
+ (set (match_dup 5) (sqrt:XF (match_dup 4)))
+ (parallel [(set (match_operand:XF 0 "register_operand" "")
+ (unspec:XF [(match_dup 1) (match_dup 5)]
+ UNSPEC_FPATAN))
+ (clobber (match_scratch:XF 6 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ int i;
+
+ for (i=2; i<6; i++)
+ operands[i] = gen_reg_rtx (XFmode);
-(define_insn "*fyl2x_xf3"
+ emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
+})
+
+(define_insn "fyl2x_xf3"
[(set (match_operand:XF 0 "register_operand" "=f")
(unspec:XF [(match_operand:XF 2 "register_operand" "0")
(match_operand:XF 1 "register_operand" "u")]
@@ -15190,33 +15642,47 @@
(set_attr "mode" "XF")])
(define_expand "logsf2"
- [(parallel [(set (match_operand:SF 0 "register_operand" "")
- (unspec:SF [(match_operand:SF 1 "register_operand" "")
- (match_dup 2)] UNSPEC_FYL2X))
- (clobber (match_scratch:SF 3 ""))])]
+ [(set (match_dup 2)
+ (float_extend:XF (match_operand:SF 1 "register_operand" "")))
+ (parallel [(set (match_dup 4)
+ (unspec:XF [(match_dup 2)
+ (match_dup 3)] UNSPEC_FYL2X))
+ (clobber (match_scratch:XF 5 ""))])
+ (set (match_operand:SF 0 "register_operand" "")
+ (float_truncate:SF (match_dup 4)))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
{
rtx temp;
operands[2] = gen_reg_rtx (XFmode);
+ operands[3] = gen_reg_rtx (XFmode);
+ operands[4] = gen_reg_rtx (XFmode);
+
temp = standard_80387_constant_rtx (4); /* fldln2 */
- emit_move_insn (operands[2], temp);
+ emit_move_insn (operands[3], temp);
})
(define_expand "logdf2"
- [(parallel [(set (match_operand:DF 0 "register_operand" "")
- (unspec:DF [(match_operand:DF 1 "register_operand" "")
- (match_dup 2)] UNSPEC_FYL2X))
- (clobber (match_scratch:DF 3 ""))])]
+ [(set (match_dup 2)
+ (float_extend:XF (match_operand:DF 1 "register_operand" "")))
+ (parallel [(set (match_dup 4)
+ (unspec:XF [(match_dup 2)
+ (match_dup 3)] UNSPEC_FYL2X))
+ (clobber (match_scratch:XF 5 ""))])
+ (set (match_operand:DF 0 "register_operand" "")
+ (float_truncate:DF (match_dup 4)))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
{
rtx temp;
operands[2] = gen_reg_rtx (XFmode);
+ operands[3] = gen_reg_rtx (XFmode);
+ operands[4] = gen_reg_rtx (XFmode);
+
temp = standard_80387_constant_rtx (4); /* fldln2 */
- emit_move_insn (operands[2], temp);
+ emit_move_insn (operands[3], temp);
})
(define_expand "logxf2"
@@ -15235,33 +15701,47 @@
})
(define_expand "log10sf2"
- [(parallel [(set (match_operand:SF 0 "register_operand" "")
- (unspec:SF [(match_operand:SF 1 "register_operand" "")
- (match_dup 2)] UNSPEC_FYL2X))
- (clobber (match_scratch:SF 3 ""))])]
+ [(set (match_dup 2)
+ (float_extend:XF (match_operand:SF 1 "register_operand" "")))
+ (parallel [(set (match_dup 4)
+ (unspec:XF [(match_dup 2)
+ (match_dup 3)] UNSPEC_FYL2X))
+ (clobber (match_scratch:XF 5 ""))])
+ (set (match_operand:SF 0 "register_operand" "")
+ (float_truncate:SF (match_dup 4)))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
{
rtx temp;
operands[2] = gen_reg_rtx (XFmode);
+ operands[3] = gen_reg_rtx (XFmode);
+ operands[4] = gen_reg_rtx (XFmode);
+
temp = standard_80387_constant_rtx (3); /* fldlg2 */
- emit_move_insn (operands[2], temp);
+ emit_move_insn (operands[3], temp);
})
(define_expand "log10df2"
- [(parallel [(set (match_operand:DF 0 "register_operand" "")
- (unspec:DF [(match_operand:DF 1 "register_operand" "")
- (match_dup 2)] UNSPEC_FYL2X))
- (clobber (match_scratch:DF 3 ""))])]
+ [(set (match_dup 2)
+ (float_extend:XF (match_operand:DF 1 "register_operand" "")))
+ (parallel [(set (match_dup 4)
+ (unspec:XF [(match_dup 2)
+ (match_dup 3)] UNSPEC_FYL2X))
+ (clobber (match_scratch:XF 5 ""))])
+ (set (match_operand:DF 0 "register_operand" "")
+ (float_truncate:DF (match_dup 4)))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
{
rtx temp;
operands[2] = gen_reg_rtx (XFmode);
+ operands[3] = gen_reg_rtx (XFmode);
+ operands[4] = gen_reg_rtx (XFmode);
+
temp = standard_80387_constant_rtx (3); /* fldlg2 */
- emit_move_insn (operands[2], temp);
+ emit_move_insn (operands[3], temp);
})
(define_expand "log10xf2"
@@ -15280,28 +15760,41 @@
})
(define_expand "log2sf2"
- [(parallel [(set (match_operand:SF 0 "register_operand" "")
- (unspec:SF [(match_operand:SF 1 "register_operand" "")
- (match_dup 2)] UNSPEC_FYL2X))
- (clobber (match_scratch:SF 3 ""))])]
+ [(set (match_dup 2)
+ (float_extend:XF (match_operand:SF 1 "register_operand" "")))
+ (parallel [(set (match_dup 4)
+ (unspec:XF [(match_dup 2)
+ (match_dup 3)] UNSPEC_FYL2X))
+ (clobber (match_scratch:XF 5 ""))])
+ (set (match_operand:SF 0 "register_operand" "")
+ (float_truncate:SF (match_dup 4)))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
{
operands[2] = gen_reg_rtx (XFmode);
- emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
+ operands[3] = gen_reg_rtx (XFmode);
+ operands[4] = gen_reg_rtx (XFmode);
+ emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
})
(define_expand "log2df2"
- [(parallel [(set (match_operand:DF 0 "register_operand" "")
- (unspec:DF [(match_operand:DF 1 "register_operand" "")
- (match_dup 2)] UNSPEC_FYL2X))
- (clobber (match_scratch:DF 3 ""))])]
+ [(set (match_dup 2)
+ (float_extend:XF (match_operand:DF 1 "register_operand" "")))
+ (parallel [(set (match_dup 4)
+ (unspec:XF [(match_dup 2)
+ (match_dup 3)] UNSPEC_FYL2X))
+ (clobber (match_scratch:XF 5 ""))])
+ (set (match_operand:DF 0 "register_operand" "")
+ (float_truncate:DF (match_dup 4)))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
{
operands[2] = gen_reg_rtx (XFmode);
- emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
+ operands[3] = gen_reg_rtx (XFmode);
+ operands[4] = gen_reg_rtx (XFmode);
+
+ emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
})
(define_expand "log2xf2"
@@ -15316,42 +15809,132 @@
emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
})
-(define_insn "*fscale_sfxf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (unspec:SF [(match_operand:XF 2 "register_operand" "0")
- (match_operand:XF 1 "register_operand" "u")]
- UNSPEC_FSCALE))
- (clobber (match_scratch:SF 3 "=1"))]
+(define_insn "fyl2xp1_xf3"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 2 "register_operand" "0")
+ (match_operand:XF 1 "register_operand" "u")]
+ UNSPEC_FYL2XP1))
+ (clobber (match_scratch:XF 3 "=1"))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
- "fscale\;fstp\t%y1"
+ "fyl2xp1"
[(set_attr "type" "fpspc")
- (set_attr "mode" "SF")])
+ (set_attr "mode" "XF")])
-(define_insn "*fscale_dfxf3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (unspec:DF [(match_operand:XF 2 "register_operand" "0")
- (match_operand:XF 1 "register_operand" "u")]
- UNSPEC_FSCALE))
- (clobber (match_scratch:DF 3 "=1"))]
+(define_expand "log1psf2"
+ [(use (match_operand:XF 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
- "fscale\;fstp\t%y1"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "DF")])
+{
+ rtx op0 = gen_reg_rtx (XFmode);
+ rtx op1 = gen_reg_rtx (XFmode);
-(define_insn "*fscale_xf3"
- [(set (match_operand:XF 0 "register_operand" "=f")
- (unspec:XF [(match_operand:XF 2 "register_operand" "0")
- (match_operand:XF 1 "register_operand" "u")]
- UNSPEC_FSCALE))
- (clobber (match_scratch:XF 3 "=1"))]
+ emit_insn (gen_extendsfxf2 (op1, operands[1]));
+ ix86_emit_i387_log1p (op0, op1);
+ emit_insn (gen_truncxfsf2_noop (operands[0], op0));
+ DONE;
+})
+
+(define_expand "log1pdf2"
+ [(use (match_operand:XF 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
- "fscale\;fstp\t%y1"
+{
+ rtx op0 = gen_reg_rtx (XFmode);
+ rtx op1 = gen_reg_rtx (XFmode);
+
+ emit_insn (gen_extenddfxf2 (op1, operands[1]));
+ ix86_emit_i387_log1p (op0, op1);
+ emit_insn (gen_truncxfdf2_noop (operands[0], op0));
+ DONE;
+})
+
+(define_expand "log1pxf2"
+ [(use (match_operand:XF 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ ix86_emit_i387_log1p (operands[0], operands[1]);
+ DONE;
+})
+
+(define_insn "*fxtractxf3"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
+ UNSPEC_XTRACT_FRACT))
+ (set (match_operand:XF 1 "register_operand" "=u")
+ (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fxtract"
[(set_attr "type" "fpspc")
(set_attr "mode" "XF")])
+(define_expand "logbsf2"
+ [(set (match_dup 2)
+ (float_extend:XF (match_operand:SF 1 "register_operand" "")))
+ (parallel [(set (match_dup 3)
+ (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
+ (set (match_dup 4)
+ (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
+ (set (match_operand:SF 0 "register_operand" "")
+ (float_truncate:SF (match_dup 4)))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (XFmode);
+ operands[3] = gen_reg_rtx (XFmode);
+ operands[4] = gen_reg_rtx (XFmode);
+})
+
+(define_expand "logbdf2"
+ [(set (match_dup 2)
+ (float_extend:XF (match_operand:DF 1 "register_operand" "")))
+ (parallel [(set (match_dup 3)
+ (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
+ (set (match_dup 4)
+ (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
+ (set (match_operand:DF 0 "register_operand" "")
+ (float_truncate:DF (match_dup 4)))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (XFmode);
+ operands[3] = gen_reg_rtx (XFmode);
+ operands[4] = gen_reg_rtx (XFmode);
+})
+
+(define_expand "logbxf2"
+ [(parallel [(set (match_dup 2)
+ (unspec:XF [(match_operand:XF 1 "register_operand" "")]
+ UNSPEC_XTRACT_FRACT))
+ (set (match_operand:XF 0 "register_operand" "")
+ (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (XFmode);
+})
+
+(define_expand "ilogbsi2"
+ [(parallel [(set (match_dup 2)
+ (unspec:XF [(match_operand:XF 1 "register_operand" "")]
+ UNSPEC_XTRACT_FRACT))
+ (set (match_operand:XF 3 "register_operand" "")
+ (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
+ (parallel [(set (match_operand:SI 0 "register_operand" "")
+ (fix:SI (match_dup 3)))
+ (clobber (reg:CC 17))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (XFmode);
+ operands[3] = gen_reg_rtx (XFmode);
+})
+
(define_insn "*frndintxf2"
[(set (match_operand:XF 0 "register_operand" "=f")
(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
@@ -15372,6 +15955,20 @@
[(set_attr "type" "fpspc")
(set_attr "mode" "XF")])
+(define_insn "*fscalexf4"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 2 "register_operand" "0")
+ (match_operand:XF 3 "register_operand" "1")]
+ UNSPEC_FSCALE_FRACT))
+ (set (match_operand:XF 1 "register_operand" "=u")
+ (unspec:XF [(match_dup 2) (match_dup 3)]
+ UNSPEC_FSCALE_EXP))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fscale"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "XF")])
+
(define_expand "expsf2"
[(set (match_dup 2)
(float_extend:XF (match_operand:SF 1 "register_operand" "")))
@@ -15380,16 +15977,21 @@
(set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
(set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
(set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
- (parallel [(set (match_operand:SF 0 "register_operand" "")
- (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
- (clobber (match_scratch:SF 5 ""))])]
+ (parallel [(set (match_dup 10)
+ (unspec:XF [(match_dup 9) (match_dup 5)]
+ UNSPEC_FSCALE_FRACT))
+ (set (match_dup 11)
+ (unspec:XF [(match_dup 9) (match_dup 5)]
+ UNSPEC_FSCALE_EXP))])
+ (set (match_operand:SF 0 "register_operand" "")
+ (float_truncate:SF (match_dup 10)))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
{
rtx temp;
int i;
- for (i=2; i<10; i++)
+ for (i=2; i<12; i++)
operands[i] = gen_reg_rtx (XFmode);
temp = standard_80387_constant_rtx (5); /* fldl2e */
emit_move_insn (operands[3], temp);
@@ -15402,19 +16004,23 @@
(set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
(set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
(set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
-
(set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
(set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
- (parallel [(set (match_operand:DF 0 "register_operand" "")
- (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
- (clobber (match_scratch:DF 5 ""))])]
+ (parallel [(set (match_dup 10)
+ (unspec:XF [(match_dup 9) (match_dup 5)]
+ UNSPEC_FSCALE_FRACT))
+ (set (match_dup 11)
+ (unspec:XF [(match_dup 9) (match_dup 5)]
+ UNSPEC_FSCALE_EXP))])
+ (set (match_operand:DF 0 "register_operand" "")
+ (float_truncate:DF (match_dup 10)))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
{
rtx temp;
int i;
- for (i=2; i<10; i++)
+ for (i=2; i<12; i++)
operands[i] = gen_reg_rtx (XFmode);
temp = standard_80387_constant_rtx (5); /* fldl2e */
emit_move_insn (operands[3], temp);
@@ -15429,15 +16035,18 @@
(set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
(set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
(parallel [(set (match_operand:XF 0 "register_operand" "")
- (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
- (clobber (match_scratch:XF 5 ""))])]
+ (unspec:XF [(match_dup 8) (match_dup 4)]
+ UNSPEC_FSCALE_FRACT))
+ (set (match_dup 9)
+ (unspec:XF [(match_dup 8) (match_dup 4)]
+ UNSPEC_FSCALE_EXP))])]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
{
rtx temp;
int i;
- for (i=2; i<9; i++)
+ for (i=2; i<10; i++)
operands[i] = gen_reg_rtx (XFmode);
temp = standard_80387_constant_rtx (5); /* fldl2e */
emit_move_insn (operands[2], temp);
@@ -15452,16 +16061,21 @@
(set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
(set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
(set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
- (parallel [(set (match_operand:SF 0 "register_operand" "")
- (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
- (clobber (match_scratch:SF 5 ""))])]
+ (parallel [(set (match_dup 10)
+ (unspec:XF [(match_dup 9) (match_dup 5)]
+ UNSPEC_FSCALE_FRACT))
+ (set (match_dup 11)
+ (unspec:XF [(match_dup 9) (match_dup 5)]
+ UNSPEC_FSCALE_EXP))])
+ (set (match_operand:SF 0 "register_operand" "")
+ (float_truncate:SF (match_dup 10)))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
{
rtx temp;
int i;
- for (i=2; i<10; i++)
+ for (i=2; i<12; i++)
operands[i] = gen_reg_rtx (XFmode);
temp = standard_80387_constant_rtx (6); /* fldl2t */
emit_move_insn (operands[3], temp);
@@ -15476,16 +16090,21 @@
(set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
(set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
(set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
- (parallel [(set (match_operand:DF 0 "register_operand" "")
- (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
- (clobber (match_scratch:DF 5 ""))])]
+ (parallel [(set (match_dup 10)
+ (unspec:XF [(match_dup 9) (match_dup 5)]
+ UNSPEC_FSCALE_FRACT))
+ (set (match_dup 11)
+ (unspec:XF [(match_dup 9) (match_dup 5)]
+ UNSPEC_FSCALE_EXP))])
+ (set (match_operand:DF 0 "register_operand" "")
+ (float_truncate:DF (match_dup 10)))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
{
rtx temp;
int i;
- for (i=2; i<10; i++)
+ for (i=2; i<12; i++)
operands[i] = gen_reg_rtx (XFmode);
temp = standard_80387_constant_rtx (6); /* fldl2t */
emit_move_insn (operands[3], temp);
@@ -15500,15 +16119,18 @@
(set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
(set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
(parallel [(set (match_operand:XF 0 "register_operand" "")
- (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
- (clobber (match_scratch:XF 5 ""))])]
+ (unspec:XF [(match_dup 8) (match_dup 4)]
+ UNSPEC_FSCALE_FRACT))
+ (set (match_dup 9)
+ (unspec:XF [(match_dup 8) (match_dup 4)]
+ UNSPEC_FSCALE_EXP))])]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
{
rtx temp;
int i;
- for (i=2; i<9; i++)
+ for (i=2; i<10; i++)
operands[i] = gen_reg_rtx (XFmode);
temp = standard_80387_constant_rtx (6); /* fldl2t */
emit_move_insn (operands[2], temp);
@@ -15522,15 +16144,20 @@
(set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
(set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
(set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
- (parallel [(set (match_operand:SF 0 "register_operand" "")
- (unspec:SF [(match_dup 7) (match_dup 3)] UNSPEC_FSCALE))
- (clobber (match_scratch:SF 3 ""))])]
+ (parallel [(set (match_dup 8)
+ (unspec:XF [(match_dup 7) (match_dup 3)]
+ UNSPEC_FSCALE_FRACT))
+ (set (match_dup 9)
+ (unspec:XF [(match_dup 7) (match_dup 3)]
+ UNSPEC_FSCALE_EXP))])
+ (set (match_operand:SF 0 "register_operand" "")
+ (float_truncate:SF (match_dup 8)))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
{
int i;
- for (i=2; i<8; i++)
+ for (i=2; i<10; i++)
operands[i] = gen_reg_rtx (XFmode);
emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
})
@@ -15542,15 +16169,20 @@
(set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
(set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
(set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
- (parallel [(set (match_operand:DF 0 "register_operand" "")
- (unspec:DF [(match_dup 7) (match_dup 3)] UNSPEC_FSCALE))
- (clobber (match_scratch:DF 3 ""))])]
+ (parallel [(set (match_dup 8)
+ (unspec:XF [(match_dup 7) (match_dup 3)]
+ UNSPEC_FSCALE_FRACT))
+ (set (match_dup 9)
+ (unspec:XF [(match_dup 7) (match_dup 3)]
+ UNSPEC_FSCALE_EXP))])
+ (set (match_operand:DF 0 "register_operand" "")
+ (float_truncate:DF (match_dup 8)))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
{
int i;
- for (i=2; i<8; i++)
+ for (i=2; i<10; i++)
operands[i] = gen_reg_rtx (XFmode);
emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
})
@@ -15562,55 +16194,125 @@
(set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
(set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
(parallel [(set (match_operand:XF 0 "register_operand" "")
- (unspec:XF [(match_dup 7) (match_dup 3)] UNSPEC_FSCALE))
- (clobber (match_scratch:XF 3 ""))])]
+ (unspec:XF [(match_dup 7) (match_dup 3)]
+ UNSPEC_FSCALE_FRACT))
+ (set (match_dup 8)
+ (unspec:XF [(match_dup 7) (match_dup 3)]
+ UNSPEC_FSCALE_EXP))])]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
{
int i;
- for (i=2; i<8; i++)
+ for (i=2; i<9; i++)
operands[i] = gen_reg_rtx (XFmode);
emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
})
-(define_expand "atansf2"
- [(parallel [(set (match_operand:SF 0 "register_operand" "")
- (unspec:SF [(match_dup 2)
- (match_operand:SF 1 "register_operand" "")]
- UNSPEC_FPATAN))
- (clobber (match_scratch:SF 3 ""))])]
+(define_expand "expm1df2"
+ [(set (match_dup 2)
+ (float_extend:XF (match_operand:DF 1 "register_operand" "")))
+ (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
+ (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
+ (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
+ (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
+ (parallel [(set (match_dup 8)
+ (unspec:XF [(match_dup 7) (match_dup 5)]
+ UNSPEC_FSCALE_FRACT))
+ (set (match_dup 9)
+ (unspec:XF [(match_dup 7) (match_dup 5)]
+ UNSPEC_FSCALE_EXP))])
+ (parallel [(set (match_dup 11)
+ (unspec:XF [(match_dup 10) (match_dup 9)]
+ UNSPEC_FSCALE_FRACT))
+ (set (match_dup 12)
+ (unspec:XF [(match_dup 10) (match_dup 9)]
+ UNSPEC_FSCALE_EXP))])
+ (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
+ (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
+ (set (match_operand:DF 0 "register_operand" "")
+ (float_truncate:DF (match_dup 14)))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
{
- operands[2] = gen_reg_rtx (SFmode);
- emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
+ rtx temp;
+ int i;
+
+ for (i=2; i<15; i++)
+ operands[i] = gen_reg_rtx (XFmode);
+ temp = standard_80387_constant_rtx (5); /* fldl2e */
+ emit_move_insn (operands[3], temp);
+ emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
})
-(define_expand "atandf2"
- [(parallel [(set (match_operand:DF 0 "register_operand" "")
- (unspec:DF [(match_dup 2)
- (match_operand:DF 1 "register_operand" "")]
- UNSPEC_FPATAN))
- (clobber (match_scratch:DF 3 ""))])]
+(define_expand "expm1sf2"
+ [(set (match_dup 2)
+ (float_extend:XF (match_operand:SF 1 "register_operand" "")))
+ (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
+ (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
+ (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
+ (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
+ (parallel [(set (match_dup 8)
+ (unspec:XF [(match_dup 7) (match_dup 5)]
+ UNSPEC_FSCALE_FRACT))
+ (set (match_dup 9)
+ (unspec:XF [(match_dup 7) (match_dup 5)]
+ UNSPEC_FSCALE_EXP))])
+ (parallel [(set (match_dup 11)
+ (unspec:XF [(match_dup 10) (match_dup 9)]
+ UNSPEC_FSCALE_FRACT))
+ (set (match_dup 12)
+ (unspec:XF [(match_dup 10) (match_dup 9)]
+ UNSPEC_FSCALE_EXP))])
+ (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
+ (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
+ (set (match_operand:SF 0 "register_operand" "")
+ (float_truncate:SF (match_dup 14)))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
{
- operands[2] = gen_reg_rtx (DFmode);
- emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
+ rtx temp;
+ int i;
+
+ for (i=2; i<15; i++)
+ operands[i] = gen_reg_rtx (XFmode);
+ temp = standard_80387_constant_rtx (5); /* fldl2e */
+ emit_move_insn (operands[3], temp);
+ emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
})
-(define_expand "atanxf2"
- [(parallel [(set (match_operand:XF 0 "register_operand" "")
- (unspec:XF [(match_dup 2)
- (match_operand:XF 1 "register_operand" "")]
- UNSPEC_FPATAN))
- (clobber (match_scratch:XF 3 ""))])]
+(define_expand "expm1xf2"
+ [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
+ (match_dup 2)))
+ (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
+ (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
+ (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
+ (parallel [(set (match_dup 7)
+ (unspec:XF [(match_dup 6) (match_dup 4)]
+ UNSPEC_FSCALE_FRACT))
+ (set (match_dup 8)
+ (unspec:XF [(match_dup 6) (match_dup 4)]
+ UNSPEC_FSCALE_EXP))])
+ (parallel [(set (match_dup 10)
+ (unspec:XF [(match_dup 9) (match_dup 8)]
+ UNSPEC_FSCALE_FRACT))
+ (set (match_dup 11)
+ (unspec:XF [(match_dup 9) (match_dup 8)]
+ UNSPEC_FSCALE_EXP))])
+ (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
+ (set (match_operand:XF 0 "register_operand" "")
+ (plus:XF (match_dup 12) (match_dup 7)))]
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
{
- operands[2] = gen_reg_rtx (XFmode);
- emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
+ rtx temp;
+ int i;
+
+ for (i=2; i<13; i++)
+ operands[i] = gen_reg_rtx (XFmode);
+ temp = standard_80387_constant_rtx (5); /* fldl2e */
+ emit_move_insn (operands[2], temp);
+ emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
})
;; Block operation instructions
diff --git a/gcc/config/i386/scodbx.h b/gcc/config/i386/scodbx.h
deleted file mode 100644
index 7da93053256..00000000000
--- a/gcc/config/i386/scodbx.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* Definitions for Intel 386 running SCO Unix System V,
- using dbx-in-coff encapsulation.
- Copyright (C) 1992, 1995, 1996, 1999 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC 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 2, or (at your option)
-any later version.
-
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#include "i386/svr3dbx.h"
-
-/* Overridden defines for SCO systems from sco.h. */
-
-/* By default, target has a 80387, uses IEEE compatible arithmetic,
- and returns float values in the 387, ie,
- (TARGET_80387 | TARGET_FLOAT_RETURNS_IN_80387)
-
- SCO's software emulation of a 387 fails to handle the `fucomp'
- opcode. fucomp is only used when generating IEEE compliant code.
- So don't make TARGET_IEEE_FP default for SCO. */
-
-#undef TARGET_SUBTARGET_DEFAULT
-#define TARGET_SUBTARGET_DEFAULT (MASK_80387 | MASK_FLOAT_RETURNS)
-
-/* Use crt1.o as a startup file and crtn.o as a closing file. */
-
-#undef STARTFILE_SPEC
-#define STARTFILE_SPEC \
- "%{!r:%{!z:svr3.ifile%s}%{z:svr3z.ifile%s}}\
- %{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}"
-
-/* Library spec, including SCO international language support. */
-
-#undef LIB_SPEC
-#define LIB_SPEC \
- "%{p:-L/usr/lib/libp}%{pg:-L/usr/lib/libp} %{scointl:libintl.a%s} -lc"
-
-/* Specify predefined symbols in preprocessor. */
-
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dunix -DM_UNIX -DM_I386 -DM_COFF -DM_WORDSWAP -Asystem=svr3"
-
-#undef CPP_SPEC
-#define CPP_SPEC "%(cpp_cpu) %{scointl:-DM_INTERNAT}"
-
-/* This spec is used for telling cpp whether char is signed or not. */
-
-#undef SIGNED_CHAR_SPEC
-#if DEFAULT_SIGNED_CHAR
-#define SIGNED_CHAR_SPEC \
- "%{funsigned-char:-D__CHAR_UNSIGNED__ -D_CHAR_UNSIGNED}"
-#else
-#define SIGNED_CHAR_SPEC \
- "%{!fsigned-char:-D__CHAR_UNSIGNED__ -D_CHAR_UNSIGNED}"
-#endif
-
-/* caller has to pop the extra argument passed to functions that return
- structures. */
-
-#undef RETURN_POPS_ARGS
-#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) \
- ((FUNDECL) && TREE_CODE (FUNDECL) == IDENTIFIER_NODE ? 0 \
- : (TARGET_RTD \
- && (TYPE_ARG_TYPES (FUNTYPE) == 0 \
- || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) \
- == void_type_node))) ? (SIZE) \
- : 0)
-/* On other 386 systems, the last line looks like this:
- : (aggregate_value_p (TREE_TYPE (FUNTYPE))) ? GET_MODE_SIZE (Pmode) : 0) */
-
-/* Handle #pragma pack. */
-#define HANDLE_SYSV_PRAGMA
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c
index c4326f01a28..6196d32aa6f 100644
--- a/gcc/config/i386/winnt.c
+++ b/gcc/config/i386/winnt.c
@@ -171,7 +171,8 @@ associated_type (tree decl)
dtor's are not affected by class status but virtual and
non-virtual thunks are. */
if (!DECL_ARTIFICIAL (decl) || DECL_COMDAT (decl))
- t = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))));
+ t = TYPE_MAIN_VARIANT
+ (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl)))));
}
else if (DECL_CONTEXT (decl)
&& TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (decl))) == 't')
@@ -672,7 +673,7 @@ i386_pe_section_type_flags (tree decl, const char *name, int reloc)
unsigned int **slot;
/* The names we put in the hashtable will always be the unique
- versions gived to us by the stringtable, so we can just use
+ versions given to us by the stringtable, so we can just use
their addresses as the keys. */
if (!htab)
htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL);
diff --git a/gcc/config/i386/xm-dgux.h b/gcc/config/i386/xm-dgux.h
deleted file mode 100644
index 881c5c7be9d..00000000000
--- a/gcc/config/i386/xm-dgux.h
+++ /dev/null
@@ -1,4 +0,0 @@
-/* Configuration for GCC for Intel i386 running DG/ux */
-
-/* looks just like sysv4 for now */
-#include "xm-svr4.h"
diff --git a/gcc/config/i386/xm-sun.h b/gcc/config/i386/xm-sun.h
deleted file mode 100644
index 6c0f0a25630..00000000000
--- a/gcc/config/i386/xm-sun.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Configuration for GNU C-compiler for Intel 80386 running SunOS 4.0.
- Copyright (C) 1988, 1997 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC 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 2, or (at your option)
-any later version.
-
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#define USG
diff --git a/gcc/config/i386/xm-sysv3.h b/gcc/config/i386/xm-sysv3.h
deleted file mode 100644
index 9a655443ff5..00000000000
--- a/gcc/config/i386/xm-sysv3.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* Configuration for GCC for Intel i386 running System V Release 3. */
-
-#include "xm-svr3.h"
diff --git a/gcc/config/ia64/crtbegin.asm b/gcc/config/ia64/crtbegin.asm
index 540cee2801f..494def7fd81 100644
--- a/gcc/config/ia64/crtbegin.asm
+++ b/gcc/config/ia64/crtbegin.asm
@@ -62,6 +62,7 @@ __dso_handle:
.section .init_array, "a"
data8 @fptr(__do_jv_register_classes)
+ data8 @fptr(__do_global_ctors_aux)
#else /* !HAVE_INITFINI_ARRAY */
/*
diff --git a/gcc/config/ia64/crtend.asm b/gcc/config/ia64/crtend.asm
index 885e0f946e5..8984d88f3d6 100644
--- a/gcc/config/ia64/crtend.asm
+++ b/gcc/config/ia64/crtend.asm
@@ -34,10 +34,8 @@ __JCR_END__:
data8 0
#ifdef HAVE_INITFINI_ARRAY
-
-.section .init_array, "a"
- data8 @fptr(__do_global_ctors_aux)
-
+ .global __do_global_ctors_aux
+ .hidden __do_global_ctors_aux
#else /* !HAVE_INITFINI_ARRAY */
/*
* Fragment of the ELF _init routine that invokes our dtor cleanup.
diff --git a/gcc/config/ia64/freebsd.h b/gcc/config/ia64/freebsd.h
index 60b79f0c715..d5977ff4661 100644
--- a/gcc/config/ia64/freebsd.h
+++ b/gcc/config/ia64/freebsd.h
@@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+#undef SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS \
{ "fbsd_dynamic_linker", FBSD_DYNAMIC_LINKER }
diff --git a/gcc/config/ia64/hpux.h b/gcc/config/ia64/hpux.h
index 2bd077efe3b..2f98ea86abe 100644
--- a/gcc/config/ia64/hpux.h
+++ b/gcc/config/ia64/hpux.h
@@ -46,6 +46,7 @@ do { \
{ \
builtin_define("_HPUX_SOURCE"); \
builtin_define("__STDC_EXT__"); \
+ builtin_define("__STDCPP__"); \
} \
if (TARGET_ILP32) \
builtin_define("_ILP32"); \
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index e27ca031fb4..e15a8a7c8d5 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -715,7 +715,6 @@ int
gr_reg_or_5bit_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && INTVAL (op) >= 0 && INTVAL (op) < 32)
- || GET_CODE (op) == CONSTANT_P_RTX
|| gr_register_operand (op, mode));
}
@@ -725,7 +724,6 @@ int
gr_reg_or_6bit_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_M (INTVAL (op)))
- || GET_CODE (op) == CONSTANT_P_RTX
|| gr_register_operand (op, mode));
}
@@ -735,7 +733,6 @@ int
gr_reg_or_8bit_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_K (INTVAL (op)))
- || GET_CODE (op) == CONSTANT_P_RTX
|| gr_register_operand (op, mode));
}
@@ -745,7 +742,6 @@ int
grfr_reg_or_8bit_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_K (INTVAL (op)))
- || GET_CODE (op) == CONSTANT_P_RTX
|| grfr_register_operand (op, mode));
}
@@ -756,7 +752,6 @@ int
gr_reg_or_8bit_adjusted_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_L (INTVAL (op)))
- || GET_CODE (op) == CONSTANT_P_RTX
|| gr_register_operand (op, mode));
}
@@ -770,7 +765,6 @@ gr_reg_or_8bit_and_adjusted_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_K (INTVAL (op))
&& CONST_OK_FOR_L (INTVAL (op)))
- || GET_CODE (op) == CONSTANT_P_RTX
|| gr_register_operand (op, mode));
}
@@ -780,7 +774,6 @@ int
gr_reg_or_14bit_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_I (INTVAL (op)))
- || GET_CODE (op) == CONSTANT_P_RTX
|| gr_register_operand (op, mode));
}
@@ -790,7 +783,6 @@ int
gr_reg_or_22bit_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_J (INTVAL (op)))
- || GET_CODE (op) == CONSTANT_P_RTX
|| gr_register_operand (op, mode));
}
@@ -799,8 +791,7 @@ gr_reg_or_22bit_operand (rtx op, enum machine_mode mode)
int
shift_count_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
- return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_M (INTVAL (op)))
- || GET_CODE (op) == CONSTANT_P_RTX);
+ return (GET_CODE (op) == CONST_INT && CONST_OK_FOR_M (INTVAL (op)));
}
/* Return 1 if OP is a 5 bit immediate operand. */
@@ -808,9 +799,8 @@ shift_count_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
int
shift_32bit_count_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
- return ((GET_CODE (op) == CONST_INT
- && (INTVAL (op) >= 0 && INTVAL (op) < 32))
- || GET_CODE (op) == CONSTANT_P_RTX);
+ return (GET_CODE (op) == CONST_INT
+ && (INTVAL (op) >= 0 && INTVAL (op) < 32));
}
/* Return 1 if OP is a 2, 4, 8, or 16 immediate operand. */
diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h
index 29f78c43a0e..b0f4dc64bce 100644
--- a/gcc/config/ia64/ia64.h
+++ b/gcc/config/ia64/ia64.h
@@ -2178,7 +2178,7 @@ do { \
{ "destination_operand", {SUBREG, REG, MEM}}, \
{ "not_postinc_memory_operand", {MEM}}, \
{ "move_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \
- CONSTANT_P_RTX, SYMBOL_REF, CONST, LABEL_REF}}, \
+ SYMBOL_REF, CONST, LABEL_REF}}, \
{ "gr_register_operand", {SUBREG, REG}}, \
{ "fr_register_operand", {SUBREG, REG}}, \
{ "grfr_register_operand", {SUBREG, REG}}, \
@@ -2186,19 +2186,16 @@ do { \
{ "fr_nonimmediate_operand", {SUBREG, REG, MEM}}, \
{ "grfr_nonimmediate_operand", {SUBREG, REG, MEM}}, \
{ "gr_reg_or_0_operand", {SUBREG, REG, CONST_INT}}, \
-{ "gr_reg_or_5bit_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
-{ "gr_reg_or_6bit_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
-{ "gr_reg_or_8bit_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
-{ "grfr_reg_or_8bit_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
-{ "gr_reg_or_8bit_adjusted_operand", {SUBREG, REG, CONST_INT, \
- CONSTANT_P_RTX}}, \
-{ "gr_reg_or_8bit_and_adjusted_operand", {SUBREG, REG, CONST_INT, \
- CONSTANT_P_RTX}}, \
-{ "gr_reg_or_14bit_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
-{ "gr_reg_or_22bit_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
-{ "shift_count_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
-{ "shift_32bit_count_operand", {SUBREG, REG, CONST_INT, \
- CONSTANT_P_RTX}}, \
+{ "gr_reg_or_5bit_operand", {SUBREG, REG, CONST_INT}}, \
+{ "gr_reg_or_6bit_operand", {SUBREG, REG, CONST_INT}}, \
+{ "gr_reg_or_8bit_operand", {SUBREG, REG, CONST_INT}}, \
+{ "grfr_reg_or_8bit_operand", {SUBREG, REG, CONST_INT}}, \
+{ "gr_reg_or_8bit_adjusted_operand", {SUBREG, REG, CONST_INT}}, \
+{ "gr_reg_or_8bit_and_adjusted_operand", {SUBREG, REG, CONST_INT}}, \
+{ "gr_reg_or_14bit_operand", {SUBREG, REG, CONST_INT}}, \
+{ "gr_reg_or_22bit_operand", {SUBREG, REG, CONST_INT}}, \
+{ "shift_count_operand", {SUBREG, REG, CONST_INT}}, \
+{ "shift_32bit_count_operand", {SUBREG, REG, CONST_INT}}, \
{ "shladd_operand", {CONST_INT}}, \
{ "fetchadd_operand", {CONST_INT}}, \
{ "fr_reg_or_fp01_operand", {SUBREG, REG, CONST_DOUBLE}}, \
diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md
index 87857047717..07b6a612aae 100644
--- a/gcc/config/ia64/ia64.md
+++ b/gcc/config/ia64/ia64.md
@@ -677,12 +677,17 @@
(match_operand:XF 1 "general_operand" ""))]
""
{
+ rtx op0 = operands[0];
+
+ if (GET_CODE (op0) == SUBREG)
+ op0 = SUBREG_REG (op0);
+
/* We must support XFmode loads into general registers for stdarg/vararg
and unprototyped calls. We split them into DImode loads for convenience.
We don't need XFmode stores from general regs, because a stdarg/vararg
routine does a block store to memory of unnamed arguments. */
- if (GET_CODE (operands[0]) == REG
- && GR_REGNO_P (REGNO (operands[0])))
+
+ if (GET_CODE (op0) == REG && GR_REGNO_P (REGNO (op0)))
{
/* We're hoping to transform everything that deals with XFmode
quantities and GR registers early in the compiler. */
@@ -695,16 +700,23 @@
|| (GET_CODE (operands[1]) == REG
&& GR_REGNO_P (REGNO (operands[1]))))
{
- emit_move_insn (gen_rtx_REG (TImode, REGNO (operands[0])),
- SUBREG_REG (operands[1]));
+ rtx op1 = operands[1];
+
+ if (GET_CODE (op1) == SUBREG)
+ op1 = SUBREG_REG (op1);
+ else
+ /* ??? Maybe we should make a SUBREG here? */
+ op1 = gen_rtx_REG (TImode, REGNO (op1));
+
+ emit_move_insn (gen_rtx_REG (TImode, REGNO (op0)), op1);
DONE;
}
if (GET_CODE (operands[1]) == CONST_DOUBLE)
{
- emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0])),
+ emit_move_insn (gen_rtx_REG (DImode, REGNO (op0)),
operand_subword (operands[1], 0, 0, XFmode));
- emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0]) + 1),
+ emit_move_insn (gen_rtx_REG (DImode, REGNO (op0) + 1),
operand_subword (operands[1], 1, 0, XFmode));
DONE;
}
@@ -717,8 +729,8 @@
{
rtx out[2];
- out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0]));
- out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0])+1);
+ out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (op0));
+ out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (op0) + 1);
emit_move_insn (out[0], adjust_address (operands[1], DImode, 0));
emit_move_insn (out[1], adjust_address (operands[1], DImode, 8));
@@ -5137,7 +5149,7 @@
[(set_attr "itanium_class" "br,scall")])
(define_insn "call_value_nogp"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0 "" "=X,X")
(call (mem:DI (match_operand:DI 1 "call_operand" "?b,i"))
(const_int 0)))
(clobber (match_operand:DI 2 "register_operand" "=b,b"))]
@@ -5193,7 +5205,7 @@
})
(define_insn "call_value_gp"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0 "" "=X,X")
(call (mem:DI (match_operand:DI 1 "call_operand" "?r,i"))
(const_int 1)))
(clobber (match_operand:DI 2 "register_operand" "=b,b"))
diff --git a/gcc/config/ia64/ia64intrin.h b/gcc/config/ia64/ia64intrin.h
index 262dc20e4d0..2397c4ccde8 100644
--- a/gcc/config/ia64/ia64intrin.h
+++ b/gcc/config/ia64/ia64intrin.h
@@ -14,114 +14,114 @@ extern long __sync_val_compare_and_swap_di (long *, long, long);
#define __sync_val_compare_and_swap(PTR, OLD, NEW) \
((sizeof (*(PTR)) == sizeof(int)) \
? (__typeof__(*(PTR))) \
- __sync_val_compare_and_swap_si((int *)(PTR),(int)(OLD),(int)(NEW)) \
+ __sync_val_compare_and_swap_si((int *)(void *)(PTR),(int)(OLD),(int)(NEW)) \
: (__typeof__(*(PTR))) \
- __sync_val_compare_and_swap_di((long *)(PTR),(long)(OLD),(long)(NEW)))
+ __sync_val_compare_and_swap_di((long *)(void *)(PTR),(long)(OLD),(long)(NEW)))
extern int __sync_bool_compare_and_swap_si (int *, int, int);
extern int __sync_bool_compare_and_swap_di (long *, long, long);
#define __sync_bool_compare_and_swap(PTR, OLD, NEW) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? __sync_bool_compare_and_swap_si((int *)(PTR),(int)(OLD),(int)(NEW)) \
- : __sync_bool_compare_and_swap_di((long *)(PTR),(long)(OLD),(long)(NEW)))
+ ? __sync_bool_compare_and_swap_si((int *)(void *)(PTR),(int)(OLD),(int)(NEW)) \
+ : __sync_bool_compare_and_swap_di((long *)(void *)(PTR),(long)(OLD),(long)(NEW)))
extern void __sync_lock_release_si (int *);
extern void __sync_lock_release_di (long *);
#define __sync_lock_release(PTR) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? __sync_lock_release_si((int *)(PTR)) \
- : __sync_lock_release_di((long *)(PTR)))
+ ? __sync_lock_release_si((int *)(void *)(PTR)) \
+ : __sync_lock_release_di((long *)(void *)(PTR)))
extern int __sync_lock_test_and_set_si (int *, int);
extern long __sync_lock_test_and_set_di (long *, long);
#define __sync_lock_test_and_set(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_lock_test_and_set_si((int *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_lock_test_and_set_di((long *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_lock_test_and_set_si((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_lock_test_and_set_di((long *)(void *)(PTR),(long)(VAL)))
extern int __sync_fetch_and_add_si (int *, int);
extern long __sync_fetch_and_add_di (long *, long);
#define __sync_fetch_and_add(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_fetch_and_add_si((int *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_fetch_and_add_di((long *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_fetch_and_add_si((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_fetch_and_add_di((long *)(void *)(PTR),(long)(VAL)))
extern int __sync_fetch_and_sub_si (int *, int);
extern long __sync_fetch_and_sub_di (long *, long);
#define __sync_fetch_and_sub(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_fetch_and_sub_si((int *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_fetch_and_sub_di((long *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_fetch_and_sub_si((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_fetch_and_sub_di((long *)(void *)(PTR),(long)(VAL)))
extern int __sync_fetch_and_and_si (int *, int);
extern long __sync_fetch_and_and_di (long *, long);
#define __sync_fetch_and_and(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_fetch_and_and_si((int *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_fetch_and_and_di((long *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_fetch_and_and_si((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_fetch_and_and_di((long *)(void *)(PTR),(long)(VAL)))
extern int __sync_fetch_and_or_si (int *, int);
extern long __sync_fetch_and_or_di (long *, long);
#define __sync_fetch_and_or(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_fetch_and_or_si((int *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_fetch_and_or_di((long *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_fetch_and_or_si((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_fetch_and_or_di((long *)(void *)(PTR),(long)(VAL)))
extern int __sync_fetch_and_xor_si (int *, int);
extern long __sync_fetch_and_xor_di (long *, long);
#define __sync_fetch_and_xor(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_fetch_and_xor_si((int *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_fetch_and_xor_di((long *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_fetch_and_xor_si((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_fetch_and_xor_di((long *)(void *)(PTR),(long)(VAL)))
extern int __sync_fetch_and_nand_si (int *, int);
extern long __sync_fetch_and_nand_di (long *, long);
#define __sync_fetch_and_nand(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_fetch_and_nand_si((int *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_fetch_and_nand_di((long *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_fetch_and_nand_si((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_fetch_and_nand_di((long *)(void *)(PTR),(long)(VAL)))
extern int __sync_add_and_fetch_si (int *, int);
extern long __sync_add_and_fetch_di (long *, long);
#define __sync_add_and_fetch(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_add_and_fetch_si((int *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_add_and_fetch_di((long *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_add_and_fetch_si((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_add_and_fetch_di((long *)(void *)(PTR),(long)(VAL)))
extern int __sync_sub_and_fetch_si (int *, int);
extern long __sync_sub_and_fetch_di (long *, long);
#define __sync_sub_and_fetch(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_sub_and_fetch_si((int *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_sub_and_fetch_di((long *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_sub_and_fetch_si((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_sub_and_fetch_di((long *)(void *)(PTR),(long)(VAL)))
extern int __sync_and_and_fetch_si (int *, int);
extern long __sync_and_and_fetch_di (long *, long);
#define __sync_and_and_fetch(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_and_and_fetch_si((int *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_and_and_fetch_di((long *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_and_and_fetch_si((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_and_and_fetch_di((long *)(void *)(PTR),(long)(VAL)))
extern int __sync_or_and_fetch_si (int *, int);
extern long __sync_or_and_fetch_di (long *, long);
#define __sync_or_and_fetch(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_or_and_fetch_si((int *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_or_and_fetch_di((long *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_or_and_fetch_si((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_or_and_fetch_di((long *)(void *)(PTR),(long)(VAL)))
extern int __sync_xor_and_fetch_si (int *, int);
extern long __sync_xor_and_fetch_di (long *, long);
#define __sync_xor_and_fetch(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_xor_and_fetch_si((int *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_xor_and_fetch_di((long *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_xor_and_fetch_si((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_xor_and_fetch_di((long *)(void *)(PTR),(long)(VAL)))
extern int __sync_nand_and_fetch_si (int *, int);
extern long __sync_nand_and_fetch_di (long *, long);
#define __sync_nand_and_fetch(PTR,VAL) \
((sizeof (*(PTR)) == sizeof(int)) \
- ? (__typeof__(*(PTR))) __sync_nand_and_fetch_si((int *)(PTR),(int)(VAL)) \
- : (__typeof__(*(PTR))) __sync_nand_and_fetch_di((long *)(PTR),(long)(VAL)))
+ ? (__typeof__(*(PTR))) __sync_nand_and_fetch_si((int *)(void *)(PTR),(int)(VAL)) \
+ : (__typeof__(*(PTR))) __sync_nand_and_fetch_di((long *)(void *)(PTR),(long)(VAL)))
#ifdef __cplusplus
}
diff --git a/gcc/config/ia64/itanium2.md b/gcc/config/ia64/itanium2.md
index 0cdb0701346..6e71f5b0f9a 100644
--- a/gcc/config/ia64/itanium2.md
+++ b/gcc/config/ia64/itanium2.md
@@ -484,7 +484,7 @@
(define_reservation "2_M_only_um01" "2_M0_only_um01|2_M1_only_um01")
;; I instruction is dispersed to the lowest numbered I unit
-;; not already in use. Remeber about possible splitting.
+;; not already in use. Remember about possible splitting.
(define_reservation "2_I0"
"2_0mi.i+2_ui0|2_0mii.+(2_ui0|2_ui1)|2_0mmi.+2_ui0\
|2_0mfi.+2_ui0|2_0mi.b+2_ui0|(2_1mi.i|2_1mi.b)+(2_ui0|2_ui1)\
@@ -1335,7 +1335,7 @@
+(2b_um2|2b_um3)")
;; I instruction is dispersed to the lowest numbered I unit
-;; not already in use. Remeber about possible splitting.
+;; not already in use. Remember about possible splitting.
(define_reservation "2b_I"
"2b_0mi.i+2_2+2b_ui0|2b_0mii.+2_3+(2b_ui0|2b_ui1)|2b_0mmi.+2_3+2b_ui0\
|2b_0mfi.+2_3+2b_ui0|2b_0mi.b+2_2+2b_ui0\
diff --git a/gcc/config/ia64/t-ia64 b/gcc/config/ia64/t-ia64
index 21d37a79a92..04cfc21592d 100644
--- a/gcc/config/ia64/t-ia64
+++ b/gcc/config/ia64/t-ia64
@@ -41,7 +41,7 @@ crtfastmath.o: $(srcdir)/config/ia64/crtfastmath.c $(GCC_PASSES)
$(srcdir)/config/ia64/crtfastmath.c
LIB2ADDEH = $(srcdir)/config/ia64/unwind-ia64.c $(srcdir)/unwind-sjlj.c \
- $(srcdir)/unwind-c.c $(srcdir)/gthr-gnat.c
+ $(srcdir)/unwind-c.c
ia64-c.o: $(srcdir)/config/ia64/ia64-c.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TREE_H) $(CPPLIB_H) $(C_COMMON_H) c-pragma.h toplev.h
diff --git a/gcc/config/ip2k/ip2k.c b/gcc/config/ip2k/ip2k.c
index c6fd0d1b968..05ccb614c4f 100644
--- a/gcc/config/ip2k/ip2k.c
+++ b/gcc/config/ip2k/ip2k.c
@@ -2730,7 +2730,7 @@ ip2k_gen_unsigned_comp_branch (rtx insn, enum rtx_code code, rtx label)
case GTU:
if (imm_sub)
{
- /* > 0xffffffffffffffff never suceeds! */
+ /* > 0xffffffffffffffff never succeeds! */
if (((const_high & 0xffffffff) != 0xffffffff)
|| ((const_low & 0xffffffff) != 0xffffffff))
{
@@ -2948,7 +2948,7 @@ ip2k_gen_unsigned_comp_branch (rtx insn, enum rtx_code code, rtx label)
if (((const_high & 0xffffffff) == 0xffffffff)
&& ((const_low & 0xffffffff) == 0xffffffff))
{
- /* <= 0xffffffffffffffff always suceeds. */
+ /* <= 0xffffffffffffffff always succeeds. */
OUT_AS1 (page, %2);
OUT_AS1 (jmp, %2);
}
diff --git a/gcc/config/ip2k/ip2k.h b/gcc/config/ip2k/ip2k.h
index 4685d030c1c..a069bf21d18 100644
--- a/gcc/config/ip2k/ip2k.h
+++ b/gcc/config/ip2k/ip2k.h
@@ -767,9 +767,6 @@ do { \
#define FUNCTION_MODE HImode
-#define INTEGRATE_THRESHOLD(DECL) \
- (1 + (3 * list_length (DECL_ARGUMENTS (DECL)) / 2))
-
#define DOLLARS_IN_IDENTIFIERS 0
extern int ip2k_reorg_in_progress;
diff --git a/gcc/config/linux.h b/gcc/config/linux.h
index 0f7ba1777e8..af7bf257ec4 100644
--- a/gcc/config/linux.h
+++ b/gcc/config/linux.h
@@ -1,5 +1,5 @@
/* Definitions for Linux-based GNU systems with ELF format
- Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2003
+ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2003, 2004
Free Software Foundation, Inc.
Contributed by Eric Youngdale.
Modified for stabs-in-ELF by H.J. Lu (hjl@lucon.org).
@@ -117,6 +117,11 @@ Boston, MA 02111-1307, USA. */
#define LINK_GCC_C_SEQUENCE_SPEC \
"%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
+/* Use --as-needed -lgcc_s for eh support. */
+#ifdef HAVE_LD_AS_NEEDED
+#define USE_LD_AS_NEEDED 1
+#endif
+
/* Determine whether the the entire c99 runtime
is present in the runtime library. */
#ifndef USE_GNULIBC_1
diff --git a/gcc/config/m32r/little.h b/gcc/config/m32r/little.h
index 793cf243863..9c1b0b5a72c 100644
--- a/gcc/config/m32r/little.h
+++ b/gcc/config/m32r/little.h
@@ -1,5 +1,5 @@
/* Definitions for Renesas little endian M32R cpu.
- Copyright (C) 2003
+ Copyright (C) 2003, 2004
Free Software Foundation, Inc.
This file is part of GCC.
@@ -19,7 +19,7 @@
Free Software Foundation, 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA. */
-#define TARGET_LITTLE_ENDIAN (!TARGET_BIG_ENDIAN)
+#define TARGET_ENDIAN_DEFAULT LITTLE_ENDIAN_BIT
#define CPP_ENDIAN_SPEC \
" %{mbe:-D__BIG_ENDIAN__} %{mbig-endian:-D__BIG_ENDIAN__}" \
diff --git a/gcc/config/m32r/m32r.c b/gcc/config/m32r/m32r.c
index 734d75743c1..fa898bcd189 100644
--- a/gcc/config/m32r/m32r.c
+++ b/gcc/config/m32r/m32r.c
@@ -771,8 +771,6 @@ move_src_operand (rtx op, enum machine_mode mode)
}
else
return 1;
- case CONSTANT_P_RTX:
- return 1;
case CONST_DOUBLE :
if (mode == SFmode)
return 1;
diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h
index f2574ac4dd3..add59b3c036 100644
--- a/gcc/config/m32r/m32r.h
+++ b/gcc/config/m32r/m32r.h
@@ -246,14 +246,19 @@ extern int target_flags;
#undef TARGET_M32R
#define TARGET_M32R (! TARGET_M32RX && ! TARGET_M32R2)
-/* Big Endian Flag. */
-#define BIG_ENDIAN_BIT (1 << 7)
-#define TARGET_BIG_ENDIAN (target_flags & BIG_ENDIAN_BIT)
-
/* Little Endian Flag. */
-#define LITTLE_ENDIAN_BIT (1 << 8)
-#ifndef TARGET_LITTLE_ENDIAN /* See little.h */
-#define TARGET_LITTLE_ENDIAN (target_flags & LITTLE_ENDIAN_BIT)
+#define LITTLE_ENDIAN_BIT (1 << 7)
+#define TARGET_LITTLE_ENDIAN (target_flags & LITTLE_ENDIAN_BIT)
+#define TARGET_BIG_ENDIAN (! TARGET_LITTLE_ENDIAN)
+
+/* This defaults us to big-endian. */
+#ifndef TARGET_ENDIAN_DEFAULT
+#define TARGET_ENDIAN_DEFAULT 0
+#endif
+
+/* This defaults us to m32r. */
+#ifndef TARGET_CPU_DEFAULT
+#define TARGET_CPU_DEFAULT 0
#endif
/* Macro to define tables used to set the flags.
@@ -267,7 +272,7 @@ extern int target_flags;
#endif
#ifndef TARGET_DEFAULT
-#define TARGET_DEFAULT 0
+#define TARGET_DEFAULT (TARGET_CPU_DEFAULT | TARGET_ENDIAN_DEFAULT)
#endif
#define TARGET_SWITCHES \
diff --git a/gcc/config/mips/4130.md b/gcc/config/mips/4130.md
new file mode 100644
index 00000000000..eddc405de34
--- /dev/null
+++ b/gcc/config/mips/4130.md
@@ -0,0 +1,136 @@
+;;
+;; Pipeline description for the VR4130 family.
+;;
+;; The processor issues each 8-byte aligned pair of instructions together,
+;; stalling the second instruction if it depends on the first. Thus, if we
+;; want two instructions to issue in parallel, we need to make sure that the
+;; first one is 8-byte aligned.
+;;
+;; For the purposes of this pipeline description, we treat the processor
+;; like a standard two-way superscalar architecture. If scheduling were
+;; the last pass to run, we could use the scheduler hooks to vary the
+;; issue rate depending on whether an instruction is at an aligned or
+;; unaligned address. Unfortunately, delayed branch scheduling and
+;; hazard avoidance are done after the final scheduling pass, and they
+;; can change the addresses of many instructions.
+;;
+;; We get around this in two ways:
+;;
+;; (1) By running an extra pass at the end of compilation. This pass goes
+;; through the function looking for pairs of instructions that could
+;; execute in parallel. It makes sure that the first instruction in
+;; each pair is suitably aligned, inserting nops if necessary. Doing
+;; this gives the same kind of pipeline behavior we would see on a
+;; normal superscalar target.
+;;
+;; This pass is generally a speed improvement, but the extra nops will
+;; obviously make the program bigger. It is therefore unsuitable for
+;; -Os (at the very least).
+;;
+;; (2) By modifying the scheduler hooks so that, where possible:
+;;
+;; (a) dependent instructions are separated by a non-dependent
+;; instruction;
+;;
+;; (b) instructions that use the multiplication unit are separated
+;; by non-multiplication instructions; and
+;;
+;; (c) memory access instructions are separated by non-memory
+;; instructions.
+;;
+;; The idea is to keep conflicting instructions apart wherever possible
+;; and thus make the schedule less dependent on alignment.
+
+(define_automaton "vr4130_main, vr4130_muldiv, vr4130_mulpre")
+
+(define_cpu_unit "vr4130_alu1, vr4130_alu2, vr4130_dcache" "vr4130_main")
+(define_cpu_unit "vr4130_muldiv" "vr4130_muldiv")
+
+;; This is a fake unit for pre-reload scheduling of multiplications.
+;; It enforces the true post-reload repeat rate.
+(define_cpu_unit "vr4130_mulpre" "vr4130_mulpre")
+
+;; The scheduling hooks use this attribute for (b) above.
+(define_attr "vr4130_class" "mul,mem,alu"
+ (cond [(eq_attr "type" "load,store")
+ (const_string "mem")
+
+ (eq_attr "type" "mfhilo,mthilo,imul,imadd,idiv")
+ (const_string "mul")]
+ (const_string "alu")))
+
+(define_insn_reservation "vr4130_multi" 1
+ (and (eq_attr "cpu" "r4130")
+ (eq_attr "type" "multi,unknown"))
+ "vr4130_alu1 + vr4130_alu2 + vr4130_dcache + vr4130_muldiv")
+
+(define_insn_reservation "vr4130_int" 1
+ (and (eq_attr "cpu" "r4130")
+ (eq_attr "type" "const,arith,shift,slt,nop"))
+ "vr4130_alu1 | vr4130_alu2")
+
+(define_insn_reservation "vr4130_load" 3
+ (and (eq_attr "cpu" "r4130")
+ (eq_attr "type" "load"))
+ "vr4130_dcache")
+
+(define_insn_reservation "vr4130_store" 1
+ (and (eq_attr "cpu" "r4130")
+ (eq_attr "type" "store"))
+ "vr4130_dcache")
+
+(define_insn_reservation "vr4130_mfhilo" 3
+ (and (eq_attr "cpu" "r4130")
+ (eq_attr "type" "mfhilo"))
+ "vr4130_muldiv")
+
+(define_insn_reservation "vr4130_mthilo" 1
+ (and (eq_attr "cpu" "r4130")
+ (eq_attr "type" "mthilo"))
+ "vr4130_muldiv")
+
+;; The product is available in LO & HI after one cycle. Moving the result
+;; into an integer register will take an additional three cycles, see mflo
+;; & mfhi above. Note that the same latencies and repeat rates apply if we
+;; use "mtlo; macc" instead of "mult; mflo".
+(define_insn_reservation "vr4130_mulsi" 4
+ (and (eq_attr "cpu" "r4130")
+ (and (eq_attr "type" "imul")
+ (eq_attr "mode" "SI")))
+ "vr4130_muldiv + (vr4130_mulpre * 2)")
+
+;; As for vr4130_mulsi, but the product is available in LO and HI
+;; after 3 cycles.
+(define_insn_reservation "vr4130_muldi" 6
+ (and (eq_attr "cpu" "r4130")
+ (and (eq_attr "type" "imul")
+ (eq_attr "mode" "DI")))
+ "(vr4130_muldiv * 3) + (vr4130_mulpre * 4)")
+
+;; maccs can execute in consecutive cycles without stalling, but it
+;; is 3 cycles before the integer destination can be read.
+(define_insn_reservation "vr4130_macc" 3
+ (and (eq_attr "cpu" "r4130")
+ (eq_attr "type" "imadd"))
+ "vr4130_muldiv")
+
+(define_bypass 1 "vr4130_mulsi,vr4130_macc" "vr4130_macc" "mips_linked_madd_p")
+(define_bypass 1 "vr4130_mulsi,vr4130_macc" "vr4130_mfhilo")
+(define_bypass 3 "vr4130_muldi" "vr4130_mfhilo")
+
+(define_insn_reservation "vr4130_divsi" 36
+ (and (eq_attr "cpu" "r4130")
+ (and (eq_attr "type" "idiv")
+ (eq_attr "mode" "SI")))
+ "vr4130_muldiv * 36")
+
+(define_insn_reservation "vr4130_divdi" 72
+ (and (eq_attr "cpu" "r4130")
+ (and (eq_attr "type" "idiv")
+ (eq_attr "mode" "DI")))
+ "vr4130_muldiv * 72")
+
+(define_insn_reservation "vr4130_branch" 0
+ (and (eq_attr "cpu" "r4130")
+ (eq_attr "type" "branch,jump,call"))
+ "vr4130_alu1 | vr4130_alu2")
diff --git a/gcc/config/mips/5500.md b/gcc/config/mips/5500.md
index d912f666ca6..d5344227d0a 100644
--- a/gcc/config/mips/5500.md
+++ b/gcc/config/mips/5500.md
@@ -31,7 +31,12 @@
(eq_attr "type" "load,fpload,fpidxload"))
"vr55_mem")
-(define_insn_reservation "ir_vr55_store" 1
+(define_bypass 4
+ "ir_vr55_load"
+ "ir_vr55_mthilo,ir_vr55_imul_si,ir_vr55_imul_di,ir_vr55_imadd,
+ ir_vr55_idiv_si,ir_vr55_idiv_di")
+
+(define_insn_reservation "ir_vr55_store" 0
(and (eq_attr "cpu" "r5500")
(eq_attr "type" "store,fpstore,fpidxstore"))
"vr55_mem")
@@ -49,33 +54,66 @@
(eq_attr "type" "xfer"))
"vr55_dp0|vr55_dp1")
-(define_insn_reservation "ir_vr55_hilo" 2
- (and (eq_attr "cpu" "r5500")
- (eq_attr "type" "mthilo,mfhilo"))
- "vr55_dp0|vr55_dp1")
-
(define_insn_reservation "ir_vr55_arith" 1
(and (eq_attr "cpu" "r5500")
(eq_attr "type" "arith,shift,slt,clz,const,nop,trap"))
"vr55_dp0|vr55_dp1")
-(define_insn_reservation "ir_vr55_imul_si" 3
+(define_bypass 2
+ "ir_vr55_arith"
+ "ir_vr55_mthilo,ir_vr55_imul_si,ir_vr55_imul_di,ir_vr55_imadd,
+ ir_vr55_idiv_si,ir_vr55_idiv_di")
+
+(define_insn_reservation "ir_vr55_mthilo" 1
+ (and (eq_attr "cpu" "r5500")
+ (eq_attr "type" "mthilo"))
+ "vr55_mac")
+
+(define_insn_reservation "ir_vr55_mfhilo" 5
+ (and (eq_attr "cpu" "r5500")
+ (eq_attr "type" "mfhilo"))
+ "vr55_mac")
+
+;; The default latency is for the GPR result of a mul. Bypasses handle the
+;; latency of {mul,mult}->{mfhi,mflo}.
+(define_insn_reservation "ir_vr55_imul_si" 5
(and (eq_attr "cpu" "r5500")
(and (eq_attr "type" "imul")
(eq_attr "mode" "SI")))
"vr55_mac")
-(define_insn_reservation "ir_vr55_imul_di" 4
+;; The default latency is for pre-reload scheduling and handles the case
+;; where a pseudo destination will be stored in a GPR (as it usually is).
+;; The delay includes the latency of the dmult itself and the anticipated
+;; mflo or mfhi.
+;;
+;; Once the mflo or mfhi has been created, bypasses handle the latency
+;; between it and the dmult.
+(define_insn_reservation "ir_vr55_imul_di" 9
(and (eq_attr "cpu" "r5500")
(and (eq_attr "type" "imul")
(eq_attr "mode" "DI")))
- "vr55_mac")
+ "vr55_mac*4")
-(define_insn_reservation "ir_vr55_imadd_si" 3
+;; The default latency is as for ir_vr55_imul_si.
+(define_insn_reservation "ir_vr55_imadd" 5
(and (eq_attr "cpu" "r5500")
- (eq_attr "type" "imul"))
+ (eq_attr "type" "imadd"))
"vr55_mac")
+(define_bypass 1
+ "ir_vr55_imul_si,ir_vr55_imadd"
+ "ir_vr55_imadd"
+ "mips_linked_madd_p")
+
+(define_bypass 2
+ "ir_vr55_imul_si,ir_vr55_imadd"
+ "ir_vr55_mfhilo")
+
+(define_bypass 4
+ "ir_vr55_imul_di"
+ "ir_vr55_mfhilo")
+
;; Divide algorithm is early out with best latency of 7 pcycles.
;; Use worst case for scheduling purposes.
(define_insn_reservation "ir_vr55_idiv_si" 42
diff --git a/gcc/config/mips/7000.md b/gcc/config/mips/7000.md
index 55402b95931..8917a6fa102 100644
--- a/gcc/config/mips/7000.md
+++ b/gcc/config/mips/7000.md
@@ -113,7 +113,7 @@
(and (eq_attr "cpu" "r7000")
(and (eq_attr "type" "imul,imadd")
(and (eq_attr "mode" "SI")
- (match_operand 0 "hilo_operand" ""))))
+ (match_operand 0 "hilo_operand"))))
"rm7_impydiv+(rm7_impydiv_iter*3)")
;; There are an additional 2 stall cycles.
@@ -121,7 +121,7 @@
(and (eq_attr "cpu" "r7000")
(and (eq_attr "type" "imul,imadd")
(and (eq_attr "mode" "SI")
- (not (match_operand 0 "hilo_operand" "")))))
+ (not (match_operand 0 "hilo_operand")))))
"rm7_impydiv")
(define_insn_reservation "rm7_impy_di" 9 (and (eq_attr "cpu" "r7000")
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 05a7983d106..f3b7bdbed77 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -93,6 +93,8 @@ extern int mips_address_insns (rtx, enum machine_mode);
extern int mips_const_insns (rtx);
extern int mips_fetch_insns (rtx);
extern int mips_idiv_insns (void);
+extern int fp_register_operand (rtx, enum machine_mode);
+extern int lo_operand (rtx, enum machine_mode);
extern bool mips_legitimate_address_p (enum machine_mode, rtx, int);
extern rtx mips_unspec_address (rtx, enum mips_symbol_type);
extern bool mips_legitimize_address (rtx *, enum machine_mode);
@@ -114,11 +116,7 @@ extern int m16_uimm8_4 (rtx, enum machine_mode);
extern int m16_nuimm8_4 (rtx, enum machine_mode);
extern int m16_simm8_8 (rtx, enum machine_mode);
extern int m16_nsimm8_8 (rtx, enum machine_mode);
-extern int m16_usym8_4 (rtx, enum machine_mode);
-extern int m16_usym5_4 (rtx, enum machine_mode);
-extern struct rtx_def *embedded_pic_fnaddr_reg (void);
-extern struct rtx_def *embedded_pic_offset (rtx);
extern rtx mips_subword (rtx, int);
extern bool mips_split_64bit_move_p (rtx, rtx);
extern void mips_split_64bit_move (rtx, rtx);
@@ -203,6 +201,7 @@ extern const char *mips_output_conditional_branch (rtx, rtx *, int, int,
int, int);
extern const char *mips_output_division (const char *, rtx *);
extern unsigned int mips_hard_regno_nregs (int, enum machine_mode);
+extern bool mips_linked_madd_p (rtx, rtx);
extern const char *mips_emit_prefetch (rtx *);
extern void irix_asm_output_align (FILE *, unsigned);
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index de0d9874f4a..5bcdbd938bc 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -54,6 +54,7 @@ Boston, MA 02111-1307, USA. */
#include "integrate.h"
#include "langhooks.h"
#include "cfglayout.h"
+#include "sched-int.h"
/* Enumeration for all of the relational tests, so that we can build
arrays indexed by the test type, and not worry about the order
@@ -107,6 +108,33 @@ enum internal_test {
multi-instruction addu sequence. Use 0x7fe0 to work around this. */
#define MIPS_MAX_FIRST_STACK_STEP (TARGET_MIPS16 ? 0x100 : 0x7fe0)
+/* True if INSN is a mips.md pattern or asm statement. */
+#define USEFUL_INSN_P(INSN) \
+ (INSN_P (INSN) \
+ && GET_CODE (PATTERN (INSN)) != USE \
+ && GET_CODE (PATTERN (INSN)) != CLOBBER \
+ && GET_CODE (PATTERN (INSN)) != ADDR_VEC \
+ && GET_CODE (PATTERN (INSN)) != ADDR_DIFF_VEC)
+
+/* If INSN is a delayed branch sequence, return the first instruction
+ in the sequence, otherwise return INSN itself. */
+#define SEQ_BEGIN(INSN) \
+ (INSN_P (INSN) && GET_CODE (PATTERN (INSN)) == SEQUENCE \
+ ? XVECEXP (PATTERN (INSN), 0, 0) \
+ : (INSN))
+
+/* Likewise for the last instruction in a delayed branch sequence. */
+#define SEQ_END(INSN) \
+ (INSN_P (INSN) && GET_CODE (PATTERN (INSN)) == SEQUENCE \
+ ? XVECEXP (PATTERN (INSN), 0, XVECLEN (PATTERN (INSN), 0) - 1) \
+ : (INSN))
+
+/* Execute the following loop body with SUBINSN set to each instruction
+ between SEQ_BEGIN (INSN) and SEQ_END (INSN) inclusive. */
+#define FOR_EACH_SUBINSN(SUBINSN, INSN) \
+ for ((SUBINSN) = SEQ_BEGIN (INSN); \
+ (SUBINSN) != NEXT_INSN (SEQ_END (INSN)); \
+ (SUBINSN) = NEXT_INSN (SUBINSN))
/* Classifies an address.
@@ -134,10 +162,11 @@ enum mips_address_type {
register and the second is the stack slot. */
typedef void (*mips_save_restore_fn) (rtx, rtx);
-struct constant;
+struct mips16_constant;
struct mips_arg_info;
struct mips_address_info;
struct mips_integer_op;
+struct mips_sim;
static enum mips_symbol_type mips_classify_symbol (rtx);
static void mips_split_const (rtx, rtx *, HOST_WIDE_INT *);
@@ -206,7 +235,6 @@ static void mips_select_rtx_section (enum machine_mode, rtx,
static void mips_select_section (tree, int, unsigned HOST_WIDE_INT)
ATTRIBUTE_UNUSED;
static bool mips_in_small_data_p (tree);
-static void mips_encode_section_info (tree, rtx, int);
static int mips_fpr_return_fields (tree, tree *);
static bool mips_return_in_msb (tree);
static rtx mips_return_fpr_pair (enum machine_mode mode,
@@ -215,10 +243,26 @@ static rtx mips_return_fpr_pair (enum machine_mode mode,
static rtx mips16_gp_pseudo_reg (void);
static void mips16_fp_args (FILE *, int, int);
static void build_mips16_function_stub (FILE *);
-static rtx add_constant (struct constant **, rtx, enum machine_mode);
-static void dump_constants (struct constant *, rtx);
-static rtx mips_find_symbol (rtx);
+static rtx dump_constants_1 (enum machine_mode, rtx, rtx);
+static void dump_constants (struct mips16_constant *, rtx);
+static int mips16_insn_length (rtx);
+static int mips16_rewrite_pool_refs (rtx *, void *);
static void mips16_lay_out_constants (void);
+static void mips_sim_reset (struct mips_sim *);
+static void mips_sim_init (struct mips_sim *, state_t);
+static void mips_sim_next_cycle (struct mips_sim *);
+static void mips_sim_wait_reg (struct mips_sim *, rtx, rtx);
+static int mips_sim_wait_regs_2 (rtx *, void *);
+static void mips_sim_wait_regs_1 (rtx *, void *);
+static void mips_sim_wait_regs (struct mips_sim *, rtx);
+static void mips_sim_wait_units (struct mips_sim *, rtx);
+static void mips_sim_wait_insn (struct mips_sim *, rtx);
+static void mips_sim_record_set (rtx, rtx, void *);
+static void mips_sim_issue_insn (struct mips_sim *, rtx);
+static void mips_sim_issue_nop (struct mips_sim *);
+static void mips_sim_finish_insn (struct mips_sim *, rtx);
+static void vr4130_avoid_branch_rt_conflict (rtx);
+static void vr4130_align_insns (void);
static void mips_avoid_hazard (rtx, rtx, int *, rtx *, rtx);
static void mips_avoid_hazards (void);
static void mips_reorg (void);
@@ -226,11 +270,21 @@ static bool mips_strict_matching_cpu_name_p (const char *, const char *);
static bool mips_matching_cpu_name_p (const char *, const char *);
static const struct mips_cpu_info *mips_parse_cpu (const char *, const char *);
static const struct mips_cpu_info *mips_cpu_info_from_isa (int);
-static int mips_adjust_cost (rtx, rtx, rtx, int);
static bool mips_return_in_memory (tree, tree);
static bool mips_strict_argument_naming (CUMULATIVE_ARGS *);
+static void mips_macc_chains_record (rtx);
+static void mips_macc_chains_reorder (rtx *, int);
+static void vr4130_true_reg_dependence_p_1 (rtx, rtx, void *);
+static bool vr4130_true_reg_dependence_p (rtx);
+static bool vr4130_swap_insns_p (rtx, rtx);
+static void vr4130_reorder (rtx *, int);
+static void mips_promote_ready (rtx *, int, int);
+static int mips_sched_reorder (FILE *, int, rtx *, int *, int);
+static int mips_variable_issue (FILE *, int, rtx, int);
+static int mips_adjust_cost (rtx, rtx, rtx, int);
static int mips_issue_rate (void);
static int mips_use_dfa_pipeline_interface (void);
+static int mips_multipass_dfa_lookahead (void);
static void mips_init_libfuncs (void);
static void mips_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
tree, int *, int);
@@ -272,10 +326,6 @@ struct mips_frame_info GTY(())
};
struct machine_function GTY(()) {
- /* Pseudo-reg holding the address of the current function when
- generating embedded PIC code. */
- rtx embedded_pic_fnaddr_rtx;
-
/* Pseudo-reg holding the value of $28 in a mips16 function which
refers to GP relative global variables. */
rtx mips16_gp_pseudo_rtx;
@@ -283,9 +333,6 @@ struct machine_function GTY(()) {
/* Current frame information, calculated by compute_frame_size. */
struct mips_frame_info frame;
- /* Length of instructions in function; mips16 only. */
- long insns_len;
-
/* The register to use as the global pointer within this function. */
unsigned int global_pointer;
@@ -462,28 +509,6 @@ static enum machine_mode gpr_mode;
can support a given mode. */
char mips_hard_regno_mode_ok[(int)MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER];
-/* The length of all strings seen when compiling for the mips16. This
- is used to tell how many strings are in the constant pool, so that
- we can see if we may have an overflow. This is reset each time the
- constant pool is output. */
-int mips_string_length;
-
-/* When generating mips16 code, a list of all strings that are to be
- output after the current function. */
-
-static GTY(()) rtx mips16_strings;
-
-/* In mips16 mode, we build a list of all the string constants we see
- in a particular function. */
-
-struct string_constant
-{
- struct string_constant *next;
- const char *label;
-};
-
-static struct string_constant *string_constants;
-
/* List of all MIPS punctuation characters used by print_operand. */
char mips_print_operand_punct[256];
@@ -698,12 +723,19 @@ const struct mips_cpu_info mips_cpu_info_table[] = {
#undef TARGET_ASM_SELECT_RTX_SECTION
#define TARGET_ASM_SELECT_RTX_SECTION mips_select_rtx_section
+#undef TARGET_SCHED_REORDER
+#define TARGET_SCHED_REORDER mips_sched_reorder
+#undef TARGET_SCHED_VARIABLE_ISSUE
+#define TARGET_SCHED_VARIABLE_ISSUE mips_variable_issue
#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST mips_adjust_cost
#undef TARGET_SCHED_ISSUE_RATE
#define TARGET_SCHED_ISSUE_RATE mips_issue_rate
#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE mips_use_dfa_pipeline_interface
+#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
+#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
+ mips_multipass_dfa_lookahead
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL mips_function_ok_for_sibcall
@@ -715,8 +747,6 @@ const struct mips_cpu_info mips_cpu_info_table[] = {
#undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST mips_address_cost
-#undef TARGET_ENCODE_SECTION_INFO
-#define TARGET_ENCODE_SECTION_INFO mips_encode_section_info
#undef TARGET_IN_SMALL_DATA_P
#define TARGET_IN_SMALL_DATA_P mips_in_small_data_p
@@ -776,7 +806,13 @@ static enum mips_symbol_type
mips_classify_symbol (rtx x)
{
if (GET_CODE (x) == LABEL_REF)
- return (TARGET_ABICALLS ? SYMBOL_GOT_LOCAL : SYMBOL_GENERAL);
+ {
+ if (TARGET_MIPS16)
+ return SYMBOL_CONSTANT_POOL;
+ if (TARGET_ABICALLS)
+ return SYMBOL_GOT_LOCAL;
+ return SYMBOL_GENERAL;
+ }
if (GET_CODE (x) != SYMBOL_REF)
abort ();
@@ -798,11 +834,6 @@ mips_classify_symbol (rtx x)
if (SYMBOL_REF_SMALL_P (x))
return SYMBOL_SMALL_DATA;
- /* When generating mips16 code, SYMBOL_REF_FLAG indicates a string
- in the current function's constant pool. */
- if (TARGET_MIPS16 && SYMBOL_REF_FLAG (x))
- return SYMBOL_CONSTANT_POOL;
-
if (TARGET_ABICALLS)
{
if (SYMBOL_REF_DECL (x) == 0)
@@ -919,8 +950,16 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type)
/* In other cases the relocations can handle any offset. */
return true;
- case SYMBOL_SMALL_DATA:
case SYMBOL_CONSTANT_POOL:
+ /* Allow constant pool references to be converted to LABEL+CONSTANT.
+ In this case, we no longer have access to the underlying constant,
+ but the original symbol-based access was known to be valid. */
+ if (GET_CODE (x) == LABEL_REF)
+ return true;
+
+ /* Fall through. */
+
+ case SYMBOL_SMALL_DATA:
/* Make sure that the offset refers to something within the
underlying object. This should guarantee that the final
PC- or GP-relative offset is within the 16-bit limit. */
@@ -1012,7 +1051,7 @@ mips_symbolic_address_p (enum mips_symbol_type symbol_type,
return true;
case SYMBOL_CONSTANT_POOL:
- /* PC-relative addressing is only available for lw, sw, ld and sd. */
+ /* PC-relative addressing is only available for lw and ld. */
return GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8;
case SYMBOL_GOT_LOCAL:
@@ -1238,9 +1277,6 @@ mips_const_insns (rtx x)
switch (GET_CODE (x))
{
- case CONSTANT_P_RTX:
- return 1;
-
case HIGH:
if (TARGET_MIPS16
|| !mips_symbolic_constant_p (XEXP (x, 0), &symbol_type)
@@ -1449,6 +1485,22 @@ extend_operator (rtx op, enum machine_mode mode)
&& (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND));
}
+/* Return true if X is the right hand side of a "macc" or "msac" instruction.
+ This predicate is intended for use in peephole optimizations. */
+
+int
+macc_msac_operand (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ if (ISA_HAS_MACC && GET_CODE (x) == PLUS && REG_P (XEXP (x, 1)))
+ x = XEXP (x, 0);
+ else if (ISA_HAS_MSAC && GET_CODE (x) == MINUS && REG_P (XEXP (x, 0)))
+ x = XEXP (x, 1);
+ else
+ return false;
+
+ return GET_CODE (x) == MULT && REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1));
+}
+
/* Return nonzero if the code of this rtx pattern is EQ or NE. */
int
@@ -1660,6 +1712,23 @@ stack_operand (rtx op, enum machine_mode mode)
&& addr.reg == stack_pointer_rtx);
}
+/* Helper function for DFA schedulers. Return true if OP is a floating
+ point register. */
+
+int
+fp_register_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return REG_P (op) && FP_REG_P (REGNO (op));
+}
+
+/* Helper function for DFA schedulers. Return true if OP is a LO reg. */
+
+int
+lo_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return REG_P (op) && REGNO (op) == LO_REGNUM;
+}
+
/* This function is used to implement GO_IF_LEGITIMATE_ADDRESS. It
returns a nonzero value if X is a legitimate address for a memory
@@ -1989,6 +2058,23 @@ mips_legitimize_move (enum machine_mode mode, rtx dest, rtx src)
return true;
}
+ /* Check for individual, fully-reloaded mflo and mfhi instructions. */
+ if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
+ && REG_P (src) && MD_REG_P (REGNO (src))
+ && REG_P (dest) && GP_REG_P (REGNO (dest)))
+ {
+ int other_regno = REGNO (src) == HI_REGNUM ? LO_REGNUM : HI_REGNUM;
+ if (GET_MODE_SIZE (mode) <= 4)
+ emit_insn (gen_mfhilo_si (gen_rtx_REG (SImode, REGNO (dest)),
+ gen_rtx_REG (SImode, REGNO (src)),
+ gen_rtx_REG (SImode, other_regno)));
+ else
+ emit_insn (gen_mfhilo_di (gen_rtx_REG (DImode, REGNO (dest)),
+ gen_rtx_REG (DImode, REGNO (src)),
+ gen_rtx_REG (DImode, other_regno)));
+ return true;
+ }
+
/* We need to deal with constants that would be legitimate
immediate_operands but not legitimate move_operands. */
if (CONSTANT_P (src) && !move_operand (src, mode))
@@ -2109,55 +2195,6 @@ m16_nsimm8_8 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return m16_check_op (op, (- 0x7f) << 3, 0x80 << 3, 7);
}
-
-/* References to the string table on the mips16 only use a small
- offset if the function is small. We can't check for LABEL_REF here,
- because the offset is always large if the label is before the
- referencing instruction. */
-
-int
-m16_usym8_4 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- if (GET_CODE (op) == SYMBOL_REF
- && SYMBOL_REF_FLAG (op)
- && cfun->machine->insns_len > 0
- && (cfun->machine->insns_len + get_pool_size () + mips_string_length
- < 4 * 0x100))
- {
- struct string_constant *l;
-
- /* Make sure this symbol is on thelist of string constants to be
- output for this function. It is possible that it has already
- been output, in which case this requires a large offset. */
- for (l = string_constants; l != NULL; l = l->next)
- if (strcmp (l->label, XSTR (op, 0)) == 0)
- return 1;
- }
-
- return 0;
-}
-
-int
-m16_usym5_4 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- if (GET_CODE (op) == SYMBOL_REF
- && SYMBOL_REF_FLAG (op)
- && cfun->machine->insns_len > 0
- && (cfun->machine->insns_len + get_pool_size () + mips_string_length
- < 4 * 0x20))
- {
- struct string_constant *l;
-
- /* Make sure this symbol is on thelist of string constants to be
- output for this function. It is possible that it has already
- been output, in which case this requires a large offset. */
- for (l = string_constants; l != NULL; l = l->next)
- if (strcmp (l->label, XSTR (op, 0)) == 0)
- return 1;
- }
-
- return 0;
-}
static bool
mips_rtx_costs (rtx x, int code, int outer_code, int *total)
@@ -2296,6 +2333,8 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total)
*total = COSTS_N_INSNS (2);
else if (TUNE_MIPS6000)
*total = COSTS_N_INSNS (3);
+ else if (TUNE_SB1)
+ *total = COSTS_N_INSNS (4);
else
*total = COSTS_N_INSNS (6);
return true;
@@ -2320,7 +2359,8 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total)
{
if (TUNE_MIPS3000
|| TUNE_MIPS3900
- || TUNE_MIPS5000)
+ || TUNE_MIPS5000
+ || TUNE_SB1)
*total = COSTS_N_INSNS (4);
else if (TUNE_MIPS6000
|| TUNE_MIPS5400
@@ -2333,7 +2373,9 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total)
if (mode == DFmode)
{
- if (TUNE_MIPS3000
+ if (TUNE_SB1)
+ *total = COSTS_N_INSNS (4);
+ else if (TUNE_MIPS3000
|| TUNE_MIPS3900
|| TUNE_MIPS5000)
*total = COSTS_N_INSNS (5);
@@ -2350,9 +2392,11 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total)
*total = COSTS_N_INSNS (12);
else if (TUNE_MIPS3900)
*total = COSTS_N_INSNS (2);
- else if (TUNE_MIPS5400 || TUNE_MIPS5500)
- *total = COSTS_N_INSNS ((mode == DImode) ? 4 : 3);
- else if (TUNE_MIPS7000)
+ else if (TUNE_MIPS4130)
+ *total = COSTS_N_INSNS (mode == DImode ? 6 : 4);
+ else if (TUNE_MIPS5400 || TUNE_SB1)
+ *total = COSTS_N_INSNS (mode == DImode ? 4 : 3);
+ else if (TUNE_MIPS5500 || TUNE_MIPS7000)
*total = COSTS_N_INSNS (mode == DImode ? 9 : 5);
else if (TUNE_MIPS9000)
*total = COSTS_N_INSNS (mode == DImode ? 8 : 3);
@@ -2373,6 +2417,8 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total)
*total = COSTS_N_INSNS (12);
else if (TUNE_MIPS6000)
*total = COSTS_N_INSNS (15);
+ else if (TUNE_SB1)
+ *total = COSTS_N_INSNS (24);
else if (TUNE_MIPS5400 || TUNE_MIPS5500)
*total = COSTS_N_INSNS (30);
else
@@ -2389,6 +2435,8 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total)
*total = COSTS_N_INSNS (59);
else if (TUNE_MIPS6000)
*total = COSTS_N_INSNS (16);
+ else if (TUNE_SB1)
+ *total = COSTS_N_INSNS (32);
else
*total = COSTS_N_INSNS (36);
return true;
@@ -2404,6 +2452,8 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total)
*total = COSTS_N_INSNS (38);
else if (TUNE_MIPS5000)
*total = COSTS_N_INSNS (36);
+ else if (TUNE_SB1)
+ *total = COSTS_N_INSNS ((mode == SImode) ? 36 : 68);
else if (TUNE_MIPS5400 || TUNE_MIPS5500)
*total = COSTS_N_INSNS ((mode == SImode) ? 42 : 74);
else
@@ -2443,55 +2493,6 @@ mips_address_cost (rtx addr)
return mips_address_insns (addr, SImode);
}
-/* Return a pseudo that points to the address of the current function.
- The first time it is called for a function, an initializer for the
- pseudo is emitted in the beginning of the function. */
-
-rtx
-embedded_pic_fnaddr_reg (void)
-{
- if (cfun->machine->embedded_pic_fnaddr_rtx == NULL)
- {
- rtx seq;
-
- cfun->machine->embedded_pic_fnaddr_rtx = gen_reg_rtx (Pmode);
-
- /* Output code at function start to initialize the pseudo-reg. */
- /* ??? We used to do this in FINALIZE_PIC, but that does not work for
- inline functions, because it is called after RTL for the function
- has been copied. The pseudo-reg in embedded_pic_fnaddr_rtx however
- does not get copied, and ends up not matching the rest of the RTL.
- This solution works, but means that we get unnecessary code to
- initialize this value every time a function is inlined into another
- function. */
- start_sequence ();
- emit_insn (gen_get_fnaddr (cfun->machine->embedded_pic_fnaddr_rtx,
- XEXP (DECL_RTL (current_function_decl), 0)));
- seq = get_insns ();
- end_sequence ();
- push_topmost_sequence ();
- emit_insn_after (seq, get_insns ());
- pop_topmost_sequence ();
- }
-
- return cfun->machine->embedded_pic_fnaddr_rtx;
-}
-
-/* Return RTL for the offset from the current function to the argument.
- X is the symbol whose offset from the current function we want. */
-
-rtx
-embedded_pic_offset (rtx x)
-{
- /* Make sure it is emitted. */
- embedded_pic_fnaddr_reg ();
-
- return
- gen_rtx_CONST (Pmode,
- gen_rtx_MINUS (Pmode, x,
- XEXP (DECL_RTL (current_function_decl), 0)));
-}
-
/* Return one word of double-word value OP, taking into account the fixed
endianness of certain registers. HIGH_P is true to select the high part,
false to select the low part. */
@@ -2648,9 +2649,6 @@ mips_output_move (rtx dest, rtx src)
{
if (src_code == REG)
{
- if (MD_REG_P (REGNO (src)))
- return "mf%1\t%0";
-
if (ST_REG_P (REGNO (src)) && ISA_HAS_8CC)
return "lui\t%0,0x3f80\n\tmovf\t%0,%.,%1";
@@ -4132,8 +4130,6 @@ mips_va_arg (tree valist, tree type)
rsize = UNITS_PER_WORD;
}
- addr_rtx = gen_reg_rtx (Pmode);
-
if (!EABI_FLOAT_VARARGS_P)
{
/* Case of all args in a merged stack. No need to check bounds,
@@ -4156,12 +4152,12 @@ mips_va_arg (tree valist, tree type)
/* Emit code to set addr_rtx to the valist, and postincrement
the valist by the size of the argument, rounded up to the
- next word. */
+ next word. Account for padding on big-endian targets. */
t = build (POSTINCREMENT_EXPR, TREE_TYPE (gpr), gpr,
size_int (rsize));
- r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
- if (r != addr_rtx)
- emit_move_insn (addr_rtx, r);
+ addr_rtx = expand_expr (t, 0, Pmode, EXPAND_NORMAL);
+ if (BYTES_BIG_ENDIAN)
+ addr_rtx = plus_constant (addr_rtx, rsize - size);
/* Flush the POSTINCREMENT. */
emit_queue();
@@ -4175,6 +4171,8 @@ mips_va_arg (tree valist, tree type)
rtx lab_over = NULL_RTX, lab_false;
HOST_WIDE_INT osize;
+ addr_rtx = gen_reg_rtx (Pmode);
+
f_ovfl = TYPE_FIELDS (va_list_type_node);
f_gtop = TREE_CHAIN (f_ovfl);
f_ftop = TREE_CHAIN (f_gtop);
@@ -4225,6 +4223,25 @@ mips_va_arg (tree valist, tree type)
each one will take up UNITS_PER_HWFPVALUE bytes, regardless
of the float's precision. */
rsize = UNITS_PER_HWFPVALUE;
+
+ /* Overflow arguments are padded to UNITS_PER_WORD bytes
+ (= PARM_BOUNDARY bits). This can be different from RSIZE
+ in two cases:
+
+ (1) On 32-bit targets when TYPE is a structure such as:
+
+ struct s { float f; };
+
+ Such structures are passed in paired FPRs, so RSIZE
+ will be 8 bytes. However, the structure only takes
+ up 4 bytes of memory, so OSIZE will only be 4.
+
+ (2) In combinations such as -mgp64 -msingle-float
+ -fshort-double. Doubles passed in registers
+ will then take up 4 (UNITS_PER_HWFPVALUE) bytes,
+ but those passed on the stack take up
+ UNITS_PER_WORD bytes. */
+ osize = MAX (GET_MODE_SIZE (TYPE_MODE (type)), UNITS_PER_WORD);
}
else
{
@@ -4238,14 +4255,8 @@ mips_va_arg (tree valist, tree type)
t = build (MODIFY_EXPR, TREE_TYPE (off), off, t);
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
+ osize = rsize;
}
- /* Every overflow argument must take up at least UNITS_PER_WORD
- bytes (= PARM_BOUNDARY bits). RSIZE can sometimes be smaller
- than that, such as in the combination -mgp64 -msingle-float
- -fshort-double. Doubles passed in registers will then take
- up UNITS_PER_HWFPVALUE bytes, but those passed on the stack
- take up UNITS_PER_WORD bytes. */
- osize = MAX (rsize, UNITS_PER_WORD);
/* [2] Emit code to branch if off == 0. */
r = expand_expr (off, NULL_RTX, TYPE_MODE (TREE_TYPE (off)),
@@ -4253,8 +4264,12 @@ mips_va_arg (tree valist, tree type)
emit_cmp_and_jump_insns (r, const0_rtx, EQ, const1_rtx, GET_MODE (r),
1, lab_false);
- /* [4] Emit code for: addr_rtx = top - off. */
+ /* [4] Emit code for: addr_rtx = top - off. On big endian machines,
+ the argument has RSIZE - SIZE bytes of leading padding. */
t = build (MINUS_EXPR, TREE_TYPE (top), top, off);
+ if (BYTES_BIG_ENDIAN && rsize > size)
+ t = build (PLUS_EXPR, TREE_TYPE (t), t,
+ build_int_2 (rsize - size, 0));
r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
if (r != addr_rtx)
emit_move_insn (addr_rtx, r);
@@ -4284,12 +4299,12 @@ mips_va_arg (tree valist, tree type)
/* [10, 11]. Emit code to store ovfl in addr_rtx, then
post-increment ovfl by osize. On big-endian machines,
- the argument has OSIZE - RSIZE bytes of leading padding. */
+ the argument has OSIZE - SIZE bytes of leading padding. */
t = build (POSTINCREMENT_EXPR, TREE_TYPE (ovfl), ovfl,
size_int (osize));
- if (BYTES_BIG_ENDIAN && osize > rsize)
+ if (BYTES_BIG_ENDIAN && osize > size)
t = build (PLUS_EXPR, TREE_TYPE (t), t,
- build_int_2 (osize - rsize, 0));
+ build_int_2 (osize - size, 0));
r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
if (r != addr_rtx)
emit_move_insn (addr_rtx, r);
@@ -4297,8 +4312,6 @@ mips_va_arg (tree valist, tree type)
emit_queue();
emit_label (lab_over);
}
- if (BYTES_BIG_ENDIAN && rsize != size)
- addr_rtx = plus_constant (addr_rtx, rsize - size);
if (indirect)
{
addr_rtx = force_reg (Pmode, addr_rtx);
@@ -4730,9 +4743,10 @@ override_options (void)
architecture.
By default, we enable use of Branch Likely instructions on
- all architectures which support them except for MIPS32 and MIPS64
- (i.e., the generic MIPS32 and MIPS64 ISAs, and processors which
- implement them).
+ all architectures which support them with the following
+ exceptions: when creating MIPS32 or MIPS64 code, and when
+ tuning for architectures where their use tends to hurt
+ performance.
The MIPS32 and MIPS64 architecture specifications say "Software
is strongly encouraged to avoid use of Branch Likely
@@ -4740,7 +4754,9 @@ override_options (void)
of the [MIPS32 and MIPS64] architecture." Therefore, we do not
issue those instructions unless instructed to do so by
-mbranch-likely. */
- if (ISA_HAS_BRANCHLIKELY && !(ISA_MIPS32 || ISA_MIPS32R2 || ISA_MIPS64))
+ if (ISA_HAS_BRANCHLIKELY
+ && !(ISA_MIPS32 || ISA_MIPS32R2 || ISA_MIPS64)
+ && !(TUNE_MIPS5500 || TUNE_SB1))
target_flags |= MASK_BRANCHLIKELY;
else
target_flags &= ~MASK_BRANCHLIKELY;
@@ -4780,30 +4796,6 @@ override_options (void)
if (!targetm.have_named_sections)
mips_section_threshold = 0;
- /* -membedded-pic is a form of PIC code suitable for embedded
- systems. All calls are made using PC relative addressing, and
- all data is addressed using the $gp register. This requires gas,
- which does most of the work, and GNU ld, which automatically
- expands PC relative calls which are out of range into a longer
- instruction sequence. All gcc really does differently is
- generate a different sequence for a switch. */
- if (TARGET_EMBEDDED_PIC)
- {
- flag_pic = 1;
- if (TARGET_ABICALLS)
- warning ("-membedded-pic and -mabicalls are incompatible");
-
- if (g_switch_set)
- warning ("-G and -membedded-pic are incompatible");
-
- /* Setting mips_section_threshold is not required, because gas
- will force everything to be GP addressable anyhow, but
- setting it will cause gcc to make better estimates of the
- number of instructions required to access a particular data
- item. */
- mips_section_threshold = 0x7fffffff;
- }
-
/* mips_split_addresses is a half-way house between explicit
relocations and the traditional assembler macros. It can
split absolute 32-bit symbolic constants into a high/lo_sum
@@ -4835,7 +4827,7 @@ override_options (void)
(1) The value of an R_MIPS_GOT16 relocation depends on whether
the symbol is local or global. We therefore need to know
- a symbol's binding before refering to it using %got().
+ a symbol's binding before referring to it using %got().
(2) R_MIPS_CALL16 can only be applied to global symbols.
@@ -4858,6 +4850,12 @@ override_options (void)
if (TARGET_NAME_REGS)
memcpy (mips_reg_names, mips_sw_reg_names, sizeof (mips_reg_names));
+ /* -mvr4130-align is a "speed over size" optimization: it usually produces
+ faster code, but at the expense of more nops. Enable it at -O3 and
+ above. */
+ if (optimize > 2 && (target_flags_explicit & MASK_VR4130_ALIGN) == 0)
+ target_flags |= MASK_VR4130_ALIGN;
+
/* When compiling for the mips16, we can not use floating point. We
record the original hard float value in mips16_hard_float. */
if (TARGET_MIPS16)
@@ -4984,7 +4982,7 @@ override_options (void)
|| (ISA_HAS_8CC && mode == TFmode));
else if (MD_REG_P (regno))
- temp = (class == MODE_INT
+ temp = (INTEGRAL_MODE_P (mode)
&& (size <= UNITS_PER_WORD
|| (regno == MD_REG_FIRST
&& size == 2 * UNITS_PER_WORD)));
@@ -5257,7 +5255,6 @@ mips_debugger_offset (rtx addr, HOST_WIDE_INT offset)
'F' print part of opcode for a floating-point branch condition.
'N' print part of opcode for a branch condition, inverted.
'W' print part of opcode for a floating-point branch condition, inverted.
- 'S' OP is CODE_LABEL, print with prefix of "LS" (for embedded switch).
'B' print 'z' for EQ, 'n' for NE
'b' print 'n' for EQ, 'z' for NE
'T' print 'f' for EQ, 't' for NE
@@ -5495,14 +5492,6 @@ print_operand (FILE *file, rtx op, int letter)
else if (letter == 'R')
print_operand_reloc (file, op, mips_lo_relocs);
- else if (letter == 'S')
- {
- char buffer[100];
-
- ASM_GENERATE_INTERNAL_LABEL (buffer, "LS", CODE_LABEL_NUMBER (op));
- assemble_name (file, buffer);
- }
-
else if (letter == 'Z')
{
register int regnum;
@@ -6871,8 +6860,6 @@ static void
mips_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{
- rtx string;
-
/* Reinstate the normal $gp. */
REGNO (pic_offset_table_rtx) = GLOBAL_POINTER_REGNUM;
mips_output_cplocal ();
@@ -6897,26 +6884,6 @@ mips_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
assemble_name (file, fnname);
fputs ("\n", file);
}
-
- while (string_constants != NULL)
- {
- struct string_constant *next;
-
- next = string_constants->next;
- free (string_constants);
- string_constants = next;
- }
-
- /* If any following function uses the same strings as this one, force
- them to refer those strings indirectly. Nearby functions could
- refer them using pc-relative addressing, but it isn't safe in
- general. For instance, some functions may be placed in sections
- other than .text, and we don't know whether they be close enough
- to this one. In large files, even other .text functions can be
- too far away. */
- for (string = mips16_strings; string != 0; string = XEXP (string, 1))
- SYMBOL_REF_FLAG (XEXP (string, 0)) = 0;
- free_EXPR_LIST_list (&mips16_strings);
}
/* Emit instructions to restore register REG from slot MEM. */
@@ -7202,6 +7169,8 @@ mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
insn = get_insns ();
insn_locators_initialize ();
split_all_insns_noflow ();
+ if (TARGET_MIPS16)
+ mips16_lay_out_constants ();
shorten_branches (insn);
final_start_function (insn, file, 1);
final (insn, file, 1, 0);
@@ -7282,14 +7251,7 @@ static void
mips_select_section (tree decl, int reloc,
unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
{
- if ((TARGET_EMBEDDED_PIC || TARGET_MIPS16)
- && TREE_CODE (decl) == STRING_CST)
- /* For embedded position independent code, put constant strings in the
- text section, because the data section is limited to 64K in size.
- For mips16 code, put strings in the text section so that a PC
- relative load instruction can be used to get their address. */
- text_section ();
- else if (targetm.have_named_sections)
+ if (targetm.have_named_sections)
default_elf_select_section (decl, reloc, align);
else
/* The native irix o32 assembler doesn't support named sections. */
@@ -7343,67 +7305,6 @@ mips_in_small_data_p (tree decl)
size = int_size_in_bytes (TREE_TYPE (decl));
return (size > 0 && size <= mips_section_threshold);
}
-
-
-/* When generating embedded PIC code, SYMBOL_REF_FLAG is set for
- symbols which are not in the .text section.
-
- When generating mips16 code, SYMBOL_REF_FLAG is set for string
- constants which are put in the .text section. We also record the
- total length of all such strings; this total is used to decide
- whether we need to split the constant table, and need not be
- precisely correct. */
-
-static void
-mips_encode_section_info (tree decl, rtx rtl, int first)
-{
- rtx symbol;
-
- if (GET_CODE (rtl) != MEM)
- return;
-
- symbol = XEXP (rtl, 0);
-
- if (GET_CODE (symbol) != SYMBOL_REF)
- return;
-
- if (TARGET_MIPS16)
- {
- if (first && TREE_CODE (decl) == STRING_CST
- /* If this string is from a function, and the function will
- go in a gnu linkonce section, then we can't directly
- access the string. This gets an assembler error
- "unsupported PC relative reference to different section".
- If we modify SELECT_SECTION to put it in function_section
- instead of text_section, it still fails because
- DECL_SECTION_NAME isn't set until assemble_start_function.
- If we fix that, it still fails because strings are shared
- among multiple functions, and we have cross section
- references again. We force it to work by putting string
- addresses in the constant pool and indirecting. */
- && (! current_function_decl
- || ! DECL_ONE_ONLY (current_function_decl)))
- {
- mips16_strings = alloc_EXPR_LIST (0, symbol, mips16_strings);
- SYMBOL_REF_FLAG (symbol) = 1;
- mips_string_length += TREE_STRING_LENGTH (decl);
- }
- }
-
- if (TARGET_EMBEDDED_PIC)
- {
- if (TREE_CODE (decl) == VAR_DECL)
- SYMBOL_REF_FLAG (symbol) = 1;
- else if (TREE_CODE (decl) == FUNCTION_DECL)
- SYMBOL_REF_FLAG (symbol) = 0;
- else if (TREE_CODE (decl) == STRING_CST)
- SYMBOL_REF_FLAG (symbol) = 0;
- else
- SYMBOL_REF_FLAG (symbol) = 1;
- }
-
- default_encode_section_info (decl, rtl, first);
-}
/* See whether VALTYPE is a record whose fields should be returned in
floating-point registers. If so, return the number of fields and
@@ -8303,332 +8204,604 @@ build_mips16_call_stub (rtx retval, rtx fn, rtx arg_size, int fp_code)
return 0;
}
-/* We keep a list of constants we which we have to add to internal
- constant tables in the middle of large functions. */
+/* An entry in the mips16 constant pool. VALUE is the pool constant,
+ MODE is its mode, and LABEL is the CODE_LABEL associated with it. */
-struct constant
-{
- struct constant *next;
+struct mips16_constant {
+ struct mips16_constant *next;
rtx value;
rtx label;
enum machine_mode mode;
};
-/* Add a constant to the list in *PCONSTANTS. */
+/* Information about an incomplete mips16 constant pool. FIRST is the
+ first constant, HIGHEST_ADDRESS is the highest address that the first
+ byte of the pool can have, and INSN_ADDRESS is the current instruction
+ address. */
+
+struct mips16_constant_pool {
+ struct mips16_constant *first;
+ int highest_address;
+ int insn_address;
+};
+
+/* Add constant VALUE to POOL and return its label. MODE is the
+ value's mode (used for CONST_INTs, etc.). */
static rtx
-add_constant (struct constant **pconstants, rtx val, enum machine_mode mode)
+add_constant (struct mips16_constant_pool *pool,
+ rtx value, enum machine_mode mode)
{
- struct constant *c;
+ struct mips16_constant **p, *c;
+ bool first_of_size_p;
- for (c = *pconstants; c != NULL; c = c->next)
- if (mode == c->mode && rtx_equal_p (val, c->value))
- return c->label;
+ /* See whether the constant is already in the pool. If so, return the
+ existing label, otherwise leave P pointing to the place where the
+ constant should be added.
- c = (struct constant *) xmalloc (sizeof *c);
- c->value = val;
+ Keep the pool sorted in increasing order of mode size so that we can
+ reduce the number of alignments needed. */
+ first_of_size_p = true;
+ for (p = &pool->first; *p != 0; p = &(*p)->next)
+ {
+ if (mode == (*p)->mode && rtx_equal_p (value, (*p)->value))
+ return (*p)->label;
+ if (GET_MODE_SIZE (mode) < GET_MODE_SIZE ((*p)->mode))
+ break;
+ if (GET_MODE_SIZE (mode) == GET_MODE_SIZE ((*p)->mode))
+ first_of_size_p = false;
+ }
+
+ /* In the worst case, the constant needed by the earliest instruction
+ will end up at the end of the pool. The entire pool must then be
+ accessible from that instruction.
+
+ When adding the first constant, set the pool's highest address to
+ the address of the first out-of-range byte. Adjust this address
+ downwards each time a new constant is added. */
+ if (pool->first == 0)
+ /* For pc-relative lw, addiu and daddiu instructions, the base PC value
+ is the address of the instruction with the lowest two bits clear.
+ The base PC value for ld has the lowest three bits clear. Assume
+ the worst case here. */
+ pool->highest_address = pool->insn_address - (UNITS_PER_WORD - 2) + 0x8000;
+ pool->highest_address -= GET_MODE_SIZE (mode);
+ if (first_of_size_p)
+ /* Take into account the worst possible padding due to alignment. */
+ pool->highest_address -= GET_MODE_SIZE (mode) - 1;
+
+ /* Create a new entry. */
+ c = (struct mips16_constant *) xmalloc (sizeof *c);
+ c->value = value;
c->mode = mode;
c->label = gen_label_rtx ();
- c->next = *pconstants;
- *pconstants = c;
+ c->next = *p;
+ *p = c;
+
return c->label;
}
+/* Output constant VALUE after instruction INSN and return the last
+ instruction emitted. MODE is the mode of the constant. */
+
+static rtx
+dump_constants_1 (enum machine_mode mode, rtx value, rtx insn)
+{
+ switch (GET_MODE_CLASS (mode))
+ {
+ case MODE_INT:
+ {
+ rtx size = GEN_INT (GET_MODE_SIZE (mode));
+ return emit_insn_after (gen_consttable_int (value, size), insn);
+ }
+
+ case MODE_FLOAT:
+ return emit_insn_after (gen_consttable_float (value), insn);
+
+ case MODE_VECTOR_FLOAT:
+ case MODE_VECTOR_INT:
+ {
+ int i;
+ for (i = 0; i < CONST_VECTOR_NUNITS (value); i++)
+ insn = dump_constants_1 (GET_MODE_INNER (mode),
+ CONST_VECTOR_ELT (value, i), insn);
+ return insn;
+ }
+
+ default:
+ abort ();
+ }
+}
+
+
/* Dump out the constants in CONSTANTS after INSN. */
static void
-dump_constants (struct constant *constants, rtx insn)
+dump_constants (struct mips16_constant *constants, rtx insn)
{
- struct constant *c;
+ struct mips16_constant *c, *next;
int align;
- c = constants;
align = 0;
- while (c != NULL)
+ for (c = constants; c != NULL; c = next)
{
- rtx r;
- struct constant *next;
-
- switch (GET_MODE_SIZE (c->mode))
+ /* If necessary, increase the alignment of PC. */
+ if (align < GET_MODE_SIZE (c->mode))
{
- case 1:
- align = 0;
- break;
- case 2:
- if (align < 1)
- insn = emit_insn_after (gen_align_2 (), insn);
- align = 1;
- break;
- case 4:
- if (align < 2)
- insn = emit_insn_after (gen_align_4 (), insn);
- align = 2;
- break;
- default:
- if (align < 3)
- insn = emit_insn_after (gen_align_8 (), insn);
- align = 3;
- break;
+ int align_log = floor_log2 (GET_MODE_SIZE (c->mode));
+ insn = emit_insn_after (gen_align (GEN_INT (align_log)), insn);
}
+ align = GET_MODE_SIZE (c->mode);
insn = emit_label_after (c->label, insn);
-
- switch (c->mode)
- {
- case QImode:
- r = gen_consttable_qi (c->value);
- break;
- case HImode:
- r = gen_consttable_hi (c->value);
- break;
- case SImode:
- r = gen_consttable_si (c->value);
- break;
- case SFmode:
- r = gen_consttable_sf (c->value);
- break;
- case DImode:
- r = gen_consttable_di (c->value);
- break;
- case DFmode:
- r = gen_consttable_df (c->value);
- break;
- default:
- abort ();
- }
-
- insn = emit_insn_after (r, insn);
+ insn = dump_constants_1 (c->mode, c->value, insn);
next = c->next;
free (c);
- c = next;
}
emit_barrier_after (insn);
}
-/* Find the symbol in an address expression. */
+/* Return the length of instruction INSN.
-static rtx
-mips_find_symbol (rtx addr)
+ ??? MIPS16 switch tables go in .text, but we don't define
+ JUMP_TABLES_IN_TEXT_SECTION, so get_attr_length will not
+ compute their lengths correctly. */
+
+static int
+mips16_insn_length (rtx insn)
{
- if (GET_CODE (addr) == MEM)
- addr = XEXP (addr, 0);
- while (GET_CODE (addr) == CONST)
- addr = XEXP (addr, 0);
- if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
- return addr;
- if (GET_CODE (addr) == PLUS)
+ if (GET_CODE (insn) == JUMP_INSN)
{
- rtx l1, l2;
-
- l1 = mips_find_symbol (XEXP (addr, 0));
- l2 = mips_find_symbol (XEXP (addr, 1));
- if (l1 != NULL_RTX && l2 == NULL_RTX)
- return l1;
- else if (l1 == NULL_RTX && l2 != NULL_RTX)
- return l2;
+ rtx body = PATTERN (insn);
+ if (GET_CODE (body) == ADDR_VEC)
+ return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, 0);
+ if (GET_CODE (body) == ADDR_DIFF_VEC)
+ return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, 1);
}
- return NULL_RTX;
+ return get_attr_length (insn);
}
-/* In mips16 mode, we need to look through the function to check for
- PC relative loads that are out of range. */
+/* Rewrite *X so that constant pool references refer to the constant's
+ label instead. DATA points to the constant pool structure. */
-static void
-mips16_lay_out_constants (void)
+static int
+mips16_rewrite_pool_refs (rtx *x, void *data)
{
- int insns_len, max_internal_pool_size, pool_size, addr, first_constant_ref;
- rtx first, insn;
- struct constant *constants;
+ struct mips16_constant_pool *pool = data;
+ if (GET_CODE (*x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (*x))
+ *x = gen_rtx_LABEL_REF (Pmode, add_constant (pool,
+ get_pool_constant (*x),
+ get_pool_mode (*x)));
+ return 0;
+}
- first = get_insns ();
+/* Build MIPS16 constant pools. */
- /* Scan the function looking for PC relative loads which may be out
- of range. All such loads will either be from the constant table,
- or be getting the address of a constant string. If the size of
- the function plus the size of the constant table is less than
- 0x8000, then all loads are in range. */
+static void
+mips16_lay_out_constants (void)
+{
+ struct mips16_constant_pool pool;
+ rtx insn, barrier;
- insns_len = 0;
- for (insn = first; insn; insn = NEXT_INSN (insn))
+ barrier = 0;
+ memset (&pool, 0, sizeof (pool));
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
- insns_len += get_attr_length (insn);
+ /* Rewrite constant pool references in INSN. */
+ if (INSN_P (insn))
+ for_each_rtx (&PATTERN (insn), mips16_rewrite_pool_refs, &pool);
+
+ pool.insn_address += mips16_insn_length (insn);
- /* ??? We put switch tables in .text, but we don't define
- JUMP_TABLES_IN_TEXT_SECTION, so get_attr_length will not
- compute their lengths correctly. */
- if (GET_CODE (insn) == JUMP_INSN)
+ if (pool.first != NULL)
{
- rtx body;
+ /* If there are no natural barriers between the first user of
+ the pool and the highest acceptable address, we'll need to
+ create a new instruction to jump around the constant pool.
+ In the worst case, this instruction will be 4 bytes long.
+
+ If it's too late to do this transformation after INSN,
+ do it immediately before INSN. */
+ if (barrier == 0 && pool.insn_address + 4 > pool.highest_address)
+ {
+ rtx label, jump;
+
+ label = gen_label_rtx ();
+
+ jump = emit_jump_insn_before (gen_jump (label), insn);
+ JUMP_LABEL (jump) = label;
+ LABEL_NUSES (label) = 1;
+ barrier = emit_barrier_after (jump);
+
+ emit_label_after (label, barrier);
+ pool.insn_address += 4;
+ }
- body = PATTERN (insn);
- if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC)
- insns_len += (XVECLEN (body, GET_CODE (body) == ADDR_DIFF_VEC)
- * GET_MODE_SIZE (GET_MODE (body)));
- insns_len += GET_MODE_SIZE (GET_MODE (body)) - 1;
+ /* See whether the constant pool is now out of range of the first
+ user. If so, output the constants after the previous barrier.
+ Note that any instructions between BARRIER and INSN (inclusive)
+ will use negative offsets to refer to the pool. */
+ if (pool.insn_address > pool.highest_address)
+ {
+ dump_constants (pool.first, barrier);
+ pool.first = NULL;
+ barrier = 0;
+ }
+ else if (BARRIER_P (insn))
+ barrier = insn;
}
}
+ dump_constants (pool.first, get_last_insn ());
+}
+
+/* A temporary variable used by for_each_rtx callbacks, etc. */
+static rtx mips_sim_insn;
+
+/* A structure representing the state of the processor pipeline.
+ Used by the mips_sim_* family of functions. */
+struct mips_sim {
+ /* The maximum number of instructions that can be issued in a cycle.
+ (Caches mips_issue_rate.) */
+ unsigned int issue_rate;
+
+ /* The current simulation time. */
+ unsigned int time;
+
+ /* How many more instructions can be issued in the current cycle. */
+ unsigned int insns_left;
+
+ /* LAST_SET[X].INSN is the last instruction to set register X.
+ LAST_SET[X].TIME is the time at which that instruction was issued.
+ INSN is null if no instruction has yet set register X. */
+ struct {
+ rtx insn;
+ unsigned int time;
+ } last_set[FIRST_PSEUDO_REGISTER];
+
+ /* The pipeline's current DFA state. */
+ state_t dfa_state;
+};
- /* Store the original value of insns_len in cfun->machine, so
- that m16_usym8_4 and m16_usym5_4 can look at it. */
- cfun->machine->insns_len = insns_len;
+/* Reset STATE to the initial simulation state. */
- pool_size = get_pool_size ();
- if (insns_len + pool_size + mips_string_length < 0x8000)
- return;
+static void
+mips_sim_reset (struct mips_sim *state)
+{
+ state->time = 0;
+ state->insns_left = state->issue_rate;
+ memset (&state->last_set, 0, sizeof (state->last_set));
+ state_reset (state->dfa_state);
+}
+
+/* Initialize STATE before its first use. DFA_STATE points to an
+ allocated but uninitialized DFA state. */
+
+static void
+mips_sim_init (struct mips_sim *state, state_t dfa_state)
+{
+ state->issue_rate = mips_issue_rate ();
+ state->dfa_state = dfa_state;
+ mips_sim_reset (state);
+}
- /* Loop over the insns and figure out what the maximum internal pool
- size could be. */
- max_internal_pool_size = 0;
- for (insn = first; insn; insn = NEXT_INSN (insn))
+/* Advance STATE by one clock cycle. */
+
+static void
+mips_sim_next_cycle (struct mips_sim *state)
+{
+ state->time++;
+ state->insns_left = state->issue_rate;
+ state_transition (state->dfa_state, 0);
+}
+
+/* Advance simulation state STATE until instruction INSN can read
+ register REG. */
+
+static void
+mips_sim_wait_reg (struct mips_sim *state, rtx insn, rtx reg)
+{
+ unsigned int i;
+
+ for (i = 0; i < HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg)); i++)
+ if (state->last_set[REGNO (reg) + i].insn != 0)
+ {
+ unsigned int t;
+
+ t = state->last_set[REGNO (reg) + i].time;
+ t += insn_latency (state->last_set[REGNO (reg) + i].insn, insn);
+ while (state->time < t)
+ mips_sim_next_cycle (state);
+ }
+}
+
+/* A for_each_rtx callback. If *X is a register, advance simulation state
+ DATA until mips_sim_insn can read the register's value. */
+
+static int
+mips_sim_wait_regs_2 (rtx *x, void *data)
+{
+ if (REG_P (*x))
+ mips_sim_wait_reg (data, mips_sim_insn, *x);
+ return 0;
+}
+
+/* Call mips_sim_wait_regs_2 (R, DATA) for each register R mentioned in *X. */
+
+static void
+mips_sim_wait_regs_1 (rtx *x, void *data)
+{
+ for_each_rtx (x, mips_sim_wait_regs_2, data);
+}
+
+/* Advance simulation state STATE until all of INSN's register
+ dependencies are satisfied. */
+
+static void
+mips_sim_wait_regs (struct mips_sim *state, rtx insn)
+{
+ mips_sim_insn = insn;
+ note_uses (&PATTERN (insn), mips_sim_wait_regs_1, state);
+}
+
+/* Advance simulation state STATE until the units required by
+ instruction INSN are available. */
+
+static void
+mips_sim_wait_units (struct mips_sim *state, rtx insn)
+{
+ state_t tmp_state;
+
+ tmp_state = alloca (state_size ());
+ while (state->insns_left == 0
+ || (memcpy (tmp_state, state->dfa_state, state_size ()),
+ state_transition (tmp_state, insn) >= 0))
+ mips_sim_next_cycle (state);
+}
+
+/* Advance simulation state STATE until INSN is ready to issue. */
+
+static void
+mips_sim_wait_insn (struct mips_sim *state, rtx insn)
+{
+ mips_sim_wait_regs (state, insn);
+ mips_sim_wait_units (state, insn);
+}
+
+/* mips_sim_insn has just set X. Update the LAST_SET array
+ in simulation state DATA. */
+
+static void
+mips_sim_record_set (rtx x, rtx pat ATTRIBUTE_UNUSED, void *data)
+{
+ struct mips_sim *state;
+ unsigned int i;
+
+ state = data;
+ if (REG_P (x))
+ for (i = 0; i < HARD_REGNO_NREGS (REGNO (x), GET_MODE (x)); i++)
+ {
+ state->last_set[REGNO (x) + i].insn = mips_sim_insn;
+ state->last_set[REGNO (x) + i].time = state->time;
+ }
+}
+
+/* Issue instruction INSN in scheduler state STATE. Assume that INSN
+ can issue immediately (i.e., that mips_sim_wait_insn has already
+ been called). */
+
+static void
+mips_sim_issue_insn (struct mips_sim *state, rtx insn)
+{
+ state_transition (state->dfa_state, insn);
+ state->insns_left--;
+
+ mips_sim_insn = insn;
+ note_stores (PATTERN (insn), mips_sim_record_set, state);
+}
+
+/* Simulate issuing a NOP in state STATE. */
+
+static void
+mips_sim_issue_nop (struct mips_sim *state)
+{
+ if (state->insns_left == 0)
+ mips_sim_next_cycle (state);
+ state->insns_left--;
+}
+
+/* Update simulation state STATE so that it's ready to accept the instruction
+ after INSN. INSN should be part of the main rtl chain, not a member of a
+ SEQUENCE. */
+
+static void
+mips_sim_finish_insn (struct mips_sim *state, rtx insn)
+{
+ /* If INSN is a jump with an implicit delay slot, simulate a nop. */
+ if (JUMP_P (insn))
+ mips_sim_issue_nop (state);
+
+ switch (GET_CODE (SEQ_BEGIN (insn)))
{
- if (GET_CODE (insn) == INSN
- && GET_CODE (PATTERN (insn)) == SET)
+ case CODE_LABEL:
+ case CALL_INSN:
+ /* We can't predict the processor state after a call or label. */
+ mips_sim_reset (state);
+ break;
+
+ case JUMP_INSN:
+ /* The delay slots of branch likely instructions are only executed
+ when the branch is taken. Therefore, if the caller has simulated
+ the delay slot instruction, STATE does not really reflect the state
+ of the pipeline for the instruction after the delay slot. Also,
+ branch likely instructions tend to incur a penalty when not taken,
+ so there will probably be an extra delay between the branch and
+ the instruction after the delay slot. */
+ if (INSN_ANNULLED_BRANCH_P (SEQ_BEGIN (insn)))
+ mips_sim_reset (state);
+ break;
+
+ default:
+ break;
+ }
+}
+
+/* The VR4130 pipeline issues aligned pairs of instructions together,
+ but it stalls the second instruction if it depends on the first.
+ In order to cut down the amount of logic required, this dependence
+ check is not based on a full instruction decode. Instead, any non-SPECIAL
+ instruction is assumed to modify the register specified by bits 20-16
+ (which is usually the "rt" field).
+
+ In beq, beql, bne and bnel instructions, the rt field is actually an
+ input, so we can end up with a false dependence between the branch
+ and its delay slot. If this situation occurs in instruction INSN,
+ try to avoid it by swapping rs and rt. */
+
+static void
+vr4130_avoid_branch_rt_conflict (rtx insn)
+{
+ rtx first, second;
+
+ first = SEQ_BEGIN (insn);
+ second = SEQ_END (insn);
+ if (GET_CODE (first) == JUMP_INSN
+ && GET_CODE (second) == INSN
+ && GET_CODE (PATTERN (first)) == SET
+ && GET_CODE (SET_DEST (PATTERN (first))) == PC
+ && GET_CODE (SET_SRC (PATTERN (first))) == IF_THEN_ELSE)
+ {
+ /* Check for the right kind of condition. */
+ rtx cond = XEXP (SET_SRC (PATTERN (first)), 0);
+ if ((GET_CODE (cond) == EQ || GET_CODE (cond) == NE)
+ && REG_P (XEXP (cond, 0))
+ && REG_P (XEXP (cond, 1))
+ && reg_referenced_p (XEXP (cond, 1), PATTERN (second))
+ && !reg_referenced_p (XEXP (cond, 0), PATTERN (second)))
{
- rtx src;
-
- src = mips_find_symbol (SET_SRC (PATTERN (insn)));
- if (src == NULL_RTX)
- continue;
- if (CONSTANT_POOL_ADDRESS_P (src))
- max_internal_pool_size += GET_MODE_SIZE (get_pool_mode (src));
- else if (SYMBOL_REF_FLAG (src))
- max_internal_pool_size += GET_MODE_SIZE (Pmode);
+ /* SECOND mentions the rt register but not the rs register. */
+ rtx tmp = XEXP (cond, 0);
+ XEXP (cond, 0) = XEXP (cond, 1);
+ XEXP (cond, 1) = tmp;
}
}
+}
- constants = NULL;
- addr = 0;
- first_constant_ref = -1;
+/* Implement -mvr4130-align. Go through each basic block and simulate the
+ processor pipeline. If we find that a pair of instructions could execute
+ in parallel, and the first of those instruction is not 8-byte aligned,
+ insert a nop to make it aligned. */
- for (insn = first; insn; insn = NEXT_INSN (insn))
- {
- if (GET_CODE (insn) == INSN
- && GET_CODE (PATTERN (insn)) == SET)
- {
- rtx val, src;
- enum machine_mode mode = VOIDmode;
+static void
+vr4130_align_insns (void)
+{
+ struct mips_sim state;
+ rtx insn, subinsn, last, last2, next;
+ bool aligned_p;
- val = NULL_RTX;
- src = mips_find_symbol (SET_SRC (PATTERN (insn)));
- if (src != NULL_RTX && CONSTANT_POOL_ADDRESS_P (src))
- {
- /* ??? This is very conservative, which means that we
- will generate too many copies of the constant table.
- The only solution would seem to be some form of
- relaxing. */
- if (((insns_len - addr)
- + max_internal_pool_size
- + get_pool_offset (src))
- >= 0x8000)
- {
- val = get_pool_constant (src);
- mode = get_pool_mode (src);
- }
- max_internal_pool_size -= GET_MODE_SIZE (get_pool_mode (src));
- }
- else if (src != NULL_RTX && SYMBOL_REF_FLAG (src))
- {
- /* Including all of mips_string_length is conservative,
- and so is including all of max_internal_pool_size. */
- if (((insns_len - addr)
- + max_internal_pool_size
- + pool_size
- + mips_string_length)
- >= 0x8000)
- {
- val = src;
- mode = Pmode;
- }
- max_internal_pool_size -= Pmode;
- }
+ dfa_start ();
- if (val != NULL_RTX)
- {
- rtx lab, newsrc;
-
- /* This PC relative load is out of range. ??? In the
- case of a string constant, we are only guessing that
- it is range, since we don't know the offset of a
- particular string constant. */
-
- lab = add_constant (&constants, val, mode);
- newsrc = gen_rtx_MEM (mode,
- gen_rtx_LABEL_REF (VOIDmode, lab));
- RTX_UNCHANGING_P (newsrc) = 1;
- PATTERN (insn) = gen_rtx_SET (VOIDmode,
- SET_DEST (PATTERN (insn)),
- newsrc);
- INSN_CODE (insn) = -1;
-
- if (first_constant_ref < 0)
- first_constant_ref = addr;
- }
- }
+ /* LAST is the last instruction before INSN to have a nonzero length.
+ LAST2 is the last such instruction before LAST. */
+ last = 0;
+ last2 = 0;
- addr += get_attr_length (insn);
+ /* ALIGNED_P is true if INSN is known to be at an aligned address. */
+ aligned_p = true;
- /* ??? We put switch tables in .text, but we don't define
- JUMP_TABLES_IN_TEXT_SECTION, so get_attr_length will not
- compute their lengths correctly. */
- if (GET_CODE (insn) == JUMP_INSN)
- {
- rtx body;
+ mips_sim_init (&state, alloca (state_size ()));
+ for (insn = get_insns (); insn != 0; insn = next)
+ {
+ unsigned int length;
- body = PATTERN (insn);
- if (GET_CODE (body) == ADDR_VEC || GET_CODE (body) == ADDR_DIFF_VEC)
- addr += (XVECLEN (body, GET_CODE (body) == ADDR_DIFF_VEC)
- * GET_MODE_SIZE (GET_MODE (body)));
- addr += GET_MODE_SIZE (GET_MODE (body)) - 1;
- }
+ next = NEXT_INSN (insn);
- if (GET_CODE (insn) == BARRIER)
- {
- /* Output any constants we have accumulated. Note that we
- don't need to change ADDR, since its only use is
- subtraction from INSNS_LEN, and both would be changed by
- the same amount.
- ??? If the instructions up to the next barrier reuse a
- constant, it would often be better to continue
- accumulating. */
- if (constants != NULL)
- dump_constants (constants, insn);
- constants = NULL;
- first_constant_ref = -1;
- }
+ /* See the comment above vr4130_avoid_branch_rt_conflict for details.
+ This isn't really related to the alignment pass, but we do it on
+ the fly to avoid a separate instruction walk. */
+ vr4130_avoid_branch_rt_conflict (insn);
+
+ if (USEFUL_INSN_P (insn))
+ FOR_EACH_SUBINSN (subinsn, insn)
+ {
+ mips_sim_wait_insn (&state, subinsn);
+
+ /* If we want this instruction to issue in parallel with the
+ previous one, make sure that the previous instruction is
+ aligned. There are several reasons why this isn't worthwhile
+ when the second instruction is a call:
+
+ - Calls are less likely to be performance critical,
+ - There's a good chance that the delay slot can execute
+ in parallel with the call.
+ - The return address would then be unaligned.
+
+ In general, if we're going to insert a nop between instructions
+ X and Y, it's better to insert it immediately after X. That
+ way, if the nop makes Y aligned, it will also align any labels
+ between X and Y. */
+ if (state.insns_left != state.issue_rate
+ && GET_CODE (subinsn) != CALL_INSN)
+ {
+ if (subinsn == SEQ_BEGIN (insn) && aligned_p)
+ {
+ /* SUBINSN is the first instruction in INSN and INSN is
+ aligned. We want to align the previous instruction
+ instead, so insert a nop between LAST2 and LAST.
+
+ Note that LAST could be either a single instruction
+ or a branch with a delay slot. In the latter case,
+ LAST, like INSN, is already aligned, but the delay
+ slot must have some extra delay that stops it from
+ issuing at the same time as the branch. We therefore
+ insert a nop before the branch in order to align its
+ delay slot. */
+ emit_insn_after (gen_nop (), last2);
+ aligned_p = false;
+ }
+ else if (subinsn != SEQ_BEGIN (insn) && !aligned_p)
+ {
+ /* SUBINSN is the delay slot of INSN, but INSN is
+ currently unaligned. Insert a nop between
+ LAST and INSN to align it. */
+ emit_insn_after (gen_nop (), last);
+ aligned_p = true;
+ }
+ }
+ mips_sim_issue_insn (&state, subinsn);
+ }
+ mips_sim_finish_insn (&state, insn);
- if (constants != NULL
- && (NEXT_INSN (insn) == NULL
- || (first_constant_ref >= 0
- && (((addr - first_constant_ref)
- + 2 /* for alignment */
- + 2 /* for a short jump insn */
- + pool_size)
- >= 0x8000))))
+ /* Update LAST, LAST2 and ALIGNED_P for the next instruction. */
+ length = get_attr_length (insn);
+ if (length > 0)
{
- /* If we haven't had a barrier within 0x8000 bytes of a
- constant reference or we are at the end of the function,
- emit a barrier now. */
-
- rtx label, jump, barrier;
-
- label = gen_label_rtx ();
- jump = emit_jump_insn_after (gen_jump (label), insn);
- JUMP_LABEL (jump) = label;
- LABEL_NUSES (label) = 1;
- barrier = emit_barrier_after (jump);
- emit_label_after (label, barrier);
- first_constant_ref = -1;
+ /* If the instruction is an asm statement or multi-instruction
+ mips.md patern, the length is only an estimate. Insert an
+ 8 byte alignment after it so that the following instructions
+ can be handled correctly. */
+ if (GET_CODE (SEQ_BEGIN (insn)) == INSN
+ && (recog_memoized (insn) < 0 || length >= 8))
+ {
+ next = emit_insn_after (gen_align (GEN_INT (3)), insn);
+ next = NEXT_INSN (next);
+ mips_sim_next_cycle (&state);
+ aligned_p = true;
+ }
+ else if (length & 4)
+ aligned_p = !aligned_p;
+ last2 = last;
+ last = insn;
}
- }
- /* ??? If we output all references to a constant in internal
- constants table, we don't need to output the constant in the real
- constant table, but we have no way to prevent that. */
+ /* See whether INSN is an aligned label. */
+ if (LABEL_P (insn) && label_to_alignment (insn) >= 3)
+ aligned_p = true;
+ }
+ dfa_finish ();
}
-
-
+
/* Subroutine of mips_reorg. If there is a hazard between INSN
and a previous instruction, avoid it by inserting nops after
instruction AFTER.
@@ -8721,10 +8894,10 @@ mips_avoid_hazards (void)
cfun->machine->ignore_hazard_length_p = true;
shorten_branches (get_insns ());
- /* The profiler code uses assembler macros. -mfix-vr4122-bugs
- relies on assembler nop insertion. */
+ /* The profiler code uses assembler macros. -mfix-vr4120 relies on
+ assembler nop insertion. */
cfun->machine->all_noreorder_p = (!current_function_profile
- && !TARGET_FIX_VR4122);
+ && !TARGET_FIX_VR4120);
last_insn = 0;
hilo_delay = 2;
@@ -8759,12 +8932,14 @@ mips_reorg (void)
if (mips_flag_delayed_branch)
dbr_schedule (get_insns (), dump_file);
mips_avoid_hazards ();
+ if (TUNE_MIPS4130 && TARGET_VR4130_ALIGN)
+ vr4130_align_insns ();
}
}
/* This function does three things:
- - Register the special divsi3 and modsi3 functions if -mfix-vr4122-bugs.
+ - Register the special divsi3 and modsi3 functions if -mfix-vr4120.
- Register the mips16 hardware floating point stubs.
- Register the gofast functions if selected using --enable-gofast. */
@@ -8773,10 +8948,10 @@ mips_reorg (void)
static void
mips_init_libfuncs (void)
{
- if (TARGET_FIX_VR4122)
+ if (TARGET_FIX_VR4120)
{
- set_optab_libfunc (sdiv_optab, SImode, "__vr4122_divsi3");
- set_optab_libfunc (smod_optab, SImode, "__vr4122_modsi3");
+ set_optab_libfunc (sdiv_optab, SImode, "__vr4120_divsi3");
+ set_optab_libfunc (smod_optab, SImode, "__vr4120_modsi3");
}
if (TARGET_MIPS16 && mips16_hard_float)
@@ -9124,7 +9299,7 @@ mips_output_conditional_branch (rtx insn, rtx *operands, int two_operands_p,
.set macro
.set reorder
- When generating non-embedded PIC, instead of:
+ When generating PIC, instead of:
j target
@@ -9424,20 +9599,6 @@ mips_cpu_info_from_isa (int isa)
return 0;
}
-/* Adjust the cost of INSN based on the relationship between INSN that
- is dependent on DEP_INSN through the dependence LINK. The default
- is to make no adjustment to COST.
-
- On the MIPS, ignore the cost of anti- and output-dependencies. */
-static int
-mips_adjust_cost (rtx insn ATTRIBUTE_UNUSED, rtx link,
- rtx dep ATTRIBUTE_UNUSED, int cost)
-{
- if (REG_NOTE_KIND (link) != 0)
- return 0; /* Anti or output dependence. */
- return cost;
-}
-
/* Implement HARD_REGNO_NREGS. The size of FP registers are controlled
by UNITS_PER_FPREG. All other registers are word sized. */
@@ -9471,18 +9632,268 @@ mips_strict_argument_naming (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED)
{
return !TARGET_OLDABI;
}
+
+/* Return true if INSN is a multiply-add or multiply-subtract
+ instruction and PREV assigns to the accumulator operand. */
+
+bool
+mips_linked_madd_p (rtx prev, rtx insn)
+{
+ rtx x;
+
+ x = single_set (insn);
+ if (x == 0)
+ return false;
+
+ x = SET_SRC (x);
+
+ if (GET_CODE (x) == PLUS
+ && GET_CODE (XEXP (x, 0)) == MULT
+ && reg_set_p (XEXP (x, 1), prev))
+ return true;
+
+ if (GET_CODE (x) == MINUS
+ && GET_CODE (XEXP (x, 1)) == MULT
+ && reg_set_p (XEXP (x, 0), prev))
+ return true;
+
+ return false;
+}
+
+/* Used by TUNE_MACC_CHAINS to record the last scheduled instruction
+ that may clobber hi or lo. */
+
+static rtx mips_macc_chains_last_hilo;
+
+/* A TUNE_MACC_CHAINS helper function. Record that instruction INSN has
+ been scheduled, updating mips_macc_chains_last_hilo appropriately. */
+
+static void
+mips_macc_chains_record (rtx insn)
+{
+ if (get_attr_may_clobber_hilo (insn))
+ mips_macc_chains_last_hilo = insn;
+}
+
+/* A TUNE_MACC_CHAINS helper function. Search ready queue READY, which
+ has NREADY elements, looking for a multiply-add or multiply-subtract
+ instruction that is cumulative with mips_macc_chains_last_hilo.
+ If there is one, promote it ahead of anything else that might
+ clobber hi or lo. */
+
+static void
+mips_macc_chains_reorder (rtx *ready, int nready)
+{
+ int i, j;
+
+ if (mips_macc_chains_last_hilo != 0)
+ for (i = nready - 1; i >= 0; i--)
+ if (mips_linked_madd_p (mips_macc_chains_last_hilo, ready[i]))
+ {
+ for (j = nready - 1; j > i; j--)
+ if (recog_memoized (ready[j]) >= 0
+ && get_attr_may_clobber_hilo (ready[j]))
+ {
+ mips_promote_ready (ready, i, j);
+ break;
+ }
+ break;
+ }
+}
+
+/* The last instruction to be scheduled. */
+
+static rtx vr4130_last_insn;
+
+/* A note_stores callback used by vr4130_true_reg_dependence_p. DATA
+ points to an rtx that is initially an instruction. Nullify the rtx
+ if the instruction uses the value of register X. */
+
+static void
+vr4130_true_reg_dependence_p_1 (rtx x, rtx pat ATTRIBUTE_UNUSED, void *data)
+{
+ rtx *insn_ptr = data;
+ if (REG_P (x)
+ && *insn_ptr != 0
+ && reg_referenced_p (x, PATTERN (*insn_ptr)))
+ *insn_ptr = 0;
+}
+
+/* Return true if there is true register dependence between vr4130_last_insn
+ and INSN. */
+
+static bool
+vr4130_true_reg_dependence_p (rtx insn)
+{
+ note_stores (PATTERN (vr4130_last_insn),
+ vr4130_true_reg_dependence_p_1, &insn);
+ return insn == 0;
+}
+
+/* A TUNE_MIPS4130 helper function. Given that INSN1 is at the head of
+ the ready queue and that INSN2 is the instruction after it, return
+ true if it is worth promoting INSN2 ahead of INSN1. Look for cases
+ in which INSN1 and INSN2 can probably issue in parallel, but for
+ which (INSN2, INSN1) should be less sensitive to instruction
+ alignment than (INSN1, INSN2). See 4130.md for more details. */
+
+static bool
+vr4130_swap_insns_p (rtx insn1, rtx insn2)
+{
+ rtx dep;
+
+ /* Check for the following case:
+
+ 1) there is some other instruction X with an anti dependence on INSN1;
+ 2) X has a higher priority than INSN2; and
+ 3) X is an arithmetic instruction (and thus has no unit restrictions).
+
+ If INSN1 is the last instruction blocking X, it would better to
+ choose (INSN1, X) over (INSN2, INSN1). */
+ for (dep = INSN_DEPEND (insn1); dep != 0; dep = XEXP (dep, 1))
+ if (REG_NOTE_KIND (dep) == REG_DEP_ANTI
+ && INSN_PRIORITY (XEXP (dep, 0)) > INSN_PRIORITY (insn2)
+ && recog_memoized (XEXP (dep, 0)) >= 0
+ && get_attr_vr4130_class (XEXP (dep, 0)) == VR4130_CLASS_ALU)
+ return false;
+
+ if (vr4130_last_insn != 0
+ && recog_memoized (insn1) >= 0
+ && recog_memoized (insn2) >= 0)
+ {
+ /* See whether INSN1 and INSN2 use different execution units,
+ or if they are both ALU-type instructions. If so, they can
+ probably execute in parallel. */
+ enum attr_vr4130_class class1 = get_attr_vr4130_class (insn1);
+ enum attr_vr4130_class class2 = get_attr_vr4130_class (insn2);
+ if (class1 != class2 || class1 == VR4130_CLASS_ALU)
+ {
+ /* If only one of the instructions has a dependence on
+ vr4130_last_insn, prefer to schedule the other one first. */
+ bool dep1 = vr4130_true_reg_dependence_p (insn1);
+ bool dep2 = vr4130_true_reg_dependence_p (insn2);
+ if (dep1 != dep2)
+ return dep1;
+
+ /* Prefer to schedule INSN2 ahead of INSN1 if vr4130_last_insn
+ is not an ALU-type instruction and if INSN1 uses the same
+ execution unit. (Note that if this condition holds, we already
+ know that INSN2 uses a different execution unit.) */
+ if (class1 != VR4130_CLASS_ALU
+ && recog_memoized (vr4130_last_insn) >= 0
+ && class1 == get_attr_vr4130_class (vr4130_last_insn))
+ return true;
+ }
+ }
+ return false;
+}
+
+/* A TUNE_MIPS4130 helper function. (READY, NREADY) describes a ready
+ queue with at least two instructions. Swap the first two if
+ vr4130_swap_insns_p says that it could be worthwhile. */
+
+static void
+vr4130_reorder (rtx *ready, int nready)
+{
+ if (vr4130_swap_insns_p (ready[nready - 1], ready[nready - 2]))
+ mips_promote_ready (ready, nready - 2, nready - 1);
+}
+
+/* Remove the instruction at index LOWER from ready queue READY and
+ reinsert it in front of the instruction at index HIGHER. LOWER must
+ be <= HIGHER. */
+
+static void
+mips_promote_ready (rtx *ready, int lower, int higher)
+{
+ rtx new_head;
+ int i;
+
+ new_head = ready[lower];
+ for (i = lower; i < higher; i++)
+ ready[i] = ready[i + 1];
+ ready[i] = new_head;
+}
+
+/* Implement TARGET_SCHED_REORDER. */
+
+static int
+mips_sched_reorder (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
+ rtx *ready, int *nreadyp, int cycle)
+{
+ if (!reload_completed && TUNE_MACC_CHAINS)
+ {
+ if (cycle == 0)
+ mips_macc_chains_last_hilo = 0;
+ if (*nreadyp > 0)
+ mips_macc_chains_reorder (ready, *nreadyp);
+ }
+ if (reload_completed && TUNE_MIPS4130 && !TARGET_VR4130_ALIGN)
+ {
+ if (cycle == 0)
+ vr4130_last_insn = 0;
+ if (*nreadyp > 1)
+ vr4130_reorder (ready, *nreadyp);
+ }
+ return mips_issue_rate ();
+}
+
+/* Implement TARGET_SCHED_VARIABLE_ISSUE. */
+
+static int
+mips_variable_issue (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
+ rtx insn, int more)
+{
+ switch (GET_CODE (PATTERN (insn)))
+ {
+ case USE:
+ case CLOBBER:
+ /* Don't count USEs and CLOBBERs against the issue rate. */
+ break;
+
+ default:
+ more--;
+ if (!reload_completed && TUNE_MACC_CHAINS)
+ mips_macc_chains_record (insn);
+ vr4130_last_insn = insn;
+ break;
+ }
+ return more;
+}
+
+/* Implement TARGET_SCHED_ADJUST_COST. We assume that anti and output
+ dependencies have no cost. */
+
+static int
+mips_adjust_cost (rtx insn ATTRIBUTE_UNUSED, rtx link,
+ rtx dep ATTRIBUTE_UNUSED, int cost)
+{
+ if (REG_NOTE_KIND (link) != 0)
+ return 0;
+ return cost;
+}
+
+/* Return the number of instructions that can be issued per cycle. */
static int
mips_issue_rate (void)
{
switch (mips_tune)
{
+ case PROCESSOR_R4130:
case PROCESSOR_R5400:
case PROCESSOR_R5500:
case PROCESSOR_R7000:
case PROCESSOR_R9000:
return 2;
+ case PROCESSOR_SB1:
+ /* This is actually 4, but we get better performance if we claim 3.
+ This is partly because of unwanted speculative code motion with the
+ larger number, and partly because in most common cases we can't
+ reach the theoretical max of 4. */
+ return 3;
+
default:
return 1;
}
@@ -9499,10 +9910,12 @@ mips_use_dfa_pipeline_interface (void)
{
switch (mips_tune)
{
+ case PROCESSOR_R4130:
case PROCESSOR_R5400:
case PROCESSOR_R5500:
case PROCESSOR_R7000:
case PROCESSOR_R9000:
+ case PROCESSOR_SB1:
case PROCESSOR_SR71000:
return true;
@@ -9511,6 +9924,19 @@ mips_use_dfa_pipeline_interface (void)
}
}
+/* Implements TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD. This should
+ be as wide as the scheduling freedom in the DFA. */
+
+static int
+mips_multipass_dfa_lookahead (void)
+{
+ /* Can schedule up to 4 of the 6 function units in any one cycle. */
+ if (mips_tune == PROCESSOR_SB1)
+ return 4;
+
+ return 0;
+}
+
const char *
mips_emit_prefetch (rtx *operands)
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 679a378d14c..cdde774673b 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -117,13 +117,11 @@ extern enum processor_type mips_tune; /* which cpu to schedule for */
extern int mips_isa; /* architectural level */
extern int mips_abi; /* which ABI to use */
extern int mips16_hard_float; /* mips16 without -msoft-float */
-extern int mips_entry; /* generate entry/exit for mips16 */
extern const char *mips_arch_string; /* for -march=<xxx> */
extern const char *mips_tune_string; /* for -mtune=<xxx> */
extern const char *mips_isa_string; /* for -mips{1,2,3,4} */
extern const char *mips_abi_string; /* for -mabi={32,n32,64} */
extern const char *mips_cache_flush_func;/* for -mflush-func= and -mno-flush-func */
-extern int mips_string_length; /* length of strings for mips16 */
extern const struct mips_cpu_info mips_cpu_info_table[];
extern const struct mips_cpu_info *mips_arch_info;
extern const struct mips_cpu_info *mips_tune_info;
@@ -156,24 +154,25 @@ extern const struct mips_cpu_info *mips_tune_info;
#define MASK_XGOT 0x00000800 /* emit big-got PIC */
#define MASK_LONG_CALLS 0x00001000 /* Always call through a register */
#define MASK_64BIT 0x00002000 /* Use 64 bit GP registers and insns */
-#define MASK_EMBEDDED_PIC 0x00004000 /* Generate embedded PIC code */
-#define MASK_EMBEDDED_DATA 0x00008000 /* Reduce RAM usage, not fast code */
-#define MASK_BIG_ENDIAN 0x00010000 /* Generate big endian code */
-#define MASK_SINGLE_FLOAT 0x00020000 /* Only single precision FPU. */
-#define MASK_MAD 0x00040000 /* Generate mad/madu as on 4650. */
-#define MASK_4300_MUL_FIX 0x00080000 /* Work-around early Vr4300 CPU bug */
-#define MASK_MIPS16 0x00100000 /* Generate mips16 code */
+#define MASK_EMBEDDED_DATA 0x00004000 /* Reduce RAM usage, not fast code */
+#define MASK_BIG_ENDIAN 0x00008000 /* Generate big endian code */
+#define MASK_SINGLE_FLOAT 0x00010000 /* Only single precision FPU. */
+#define MASK_MAD 0x00020000 /* Generate mad/madu as on 4650. */
+#define MASK_4300_MUL_FIX 0x00040000 /* Work-around early Vr4300 CPU bug */
+#define MASK_MIPS16 0x00080000 /* Generate mips16 code */
#define MASK_NO_CHECK_ZERO_DIV \
- 0x00200000 /* divide by zero checking */
-#define MASK_BRANCHLIKELY 0x00400000 /* Generate Branch Likely
+ 0x00100000 /* divide by zero checking */
+#define MASK_BRANCHLIKELY 0x00200000 /* Generate Branch Likely
instructions. */
#define MASK_UNINIT_CONST_IN_RODATA \
- 0x00800000 /* Store uninitialized
+ 0x00400000 /* Store uninitialized
consts in rodata */
-#define MASK_FIX_R4000 0x01000000 /* Work around R4000 errata. */
-#define MASK_FIX_R4400 0x02000000 /* Work around R4400 errata. */
-#define MASK_FIX_SB1 0x04000000 /* Work around SB-1 errata. */
-#define MASK_FIX_VR4122 0x08000000 /* Work-around VR4122 errata. */
+#define MASK_FIX_R4000 0x00800000 /* Work around R4000 errata. */
+#define MASK_FIX_R4400 0x01000000 /* Work around R4400 errata. */
+#define MASK_FIX_SB1 0x02000000 /* Work around SB-1 errata. */
+#define MASK_FIX_VR4120 0x04000000 /* Work around VR4120 errata. */
+#define MASK_VR4130_ALIGN 0x08000000 /* Perform VR4130 alignment opts. */
+#define MASK_FP_EXCEPTIONS 0x10000000 /* FP exceptions are enabled. */
/* Debug switches, not documented */
#define MASK_DEBUG 0 /* unused */
@@ -220,10 +219,6 @@ extern const struct mips_cpu_info *mips_tune_info;
/* always call through a register */
#define TARGET_LONG_CALLS (target_flags & MASK_LONG_CALLS)
- /* generate embedded PIC code;
- requires gas. */
-#define TARGET_EMBEDDED_PIC (target_flags & MASK_EMBEDDED_PIC)
-
/* for embedded systems, optimize for
reduced RAM space instead of for
fastest code. */
@@ -257,7 +252,10 @@ extern const struct mips_cpu_info *mips_tune_info;
/* Work around R4400 errata. */
#define TARGET_FIX_R4400 (target_flags & MASK_FIX_R4400)
-#define TARGET_FIX_VR4122 (target_flags & MASK_FIX_VR4122)
+#define TARGET_FIX_VR4120 (target_flags & MASK_FIX_VR4120)
+#define TARGET_VR4130_ALIGN (target_flags & MASK_VR4130_ALIGN)
+
+#define TARGET_FP_EXCEPTIONS (target_flags & MASK_FP_EXCEPTIONS)
/* True if we should use NewABI-style relocation operators for
symbolic addresses. This is never true for mips16 code,
@@ -335,12 +333,50 @@ extern const struct mips_cpu_info *mips_tune_info;
#define TUNE_MIPS3000 (mips_tune == PROCESSOR_R3000)
#define TUNE_MIPS3900 (mips_tune == PROCESSOR_R3900)
#define TUNE_MIPS4000 (mips_tune == PROCESSOR_R4000)
+#define TUNE_MIPS4120 (mips_tune == PROCESSOR_R4120)
+#define TUNE_MIPS4130 (mips_tune == PROCESSOR_R4130)
#define TUNE_MIPS5000 (mips_tune == PROCESSOR_R5000)
#define TUNE_MIPS5400 (mips_tune == PROCESSOR_R5400)
#define TUNE_MIPS5500 (mips_tune == PROCESSOR_R5500)
#define TUNE_MIPS6000 (mips_tune == PROCESSOR_R6000)
#define TUNE_MIPS7000 (mips_tune == PROCESSOR_R7000)
#define TUNE_MIPS9000 (mips_tune == PROCESSOR_R9000)
+#define TUNE_SB1 (mips_tune == PROCESSOR_SB1)
+
+/* True if the pre-reload scheduler should try to create chains of
+ multiply-add or multiply-subtract instructions. For example,
+ suppose we have:
+
+ t1 = a * b
+ t2 = t1 + c * d
+ t3 = e * f
+ t4 = t3 - g * h
+
+ t1 will have a higher priority than t2 and t3 will have a higher
+ priority than t4. However, before reload, there is no dependence
+ between t1 and t3, and they can often have similar priorities.
+ The scheduler will then tend to prefer:
+
+ t1 = a * b
+ t3 = e * f
+ t2 = t1 + c * d
+ t4 = t3 - g * h
+
+ which stops us from making full use of macc/madd-style instructions.
+ This sort of situation occurs frequently in Fourier transforms and
+ in unrolled loops.
+
+ To counter this, the TUNE_MACC_CHAINS code will reorder the ready
+ queue so that chained multiply-add and multiply-subtract instructions
+ appear ahead of any other instruction that is likely to clobber lo.
+ In the example above, if t2 and t3 become ready at the same time,
+ the code ensures that t2 is scheduled first.
+
+ Multiply-accumulate instructions are a bigger win for some targets
+ than others, so this macro is defined on an opt-in basis. */
+#define TUNE_MACC_CHAINS (TUNE_MIPS5500 \
+ || TUNE_MIPS4120 \
+ || TUNE_MIPS4130)
#define TARGET_OLDABI (mips_abi == ABI_32 || mips_abi == ABI_O64)
#define TARGET_NEWABI (mips_abi == ABI_N32 || mips_abi == ABI_64)
@@ -564,10 +600,6 @@ extern const struct mips_cpu_info *mips_tune_info;
N_("Use indirect calls")}, \
{"no-long-calls", -MASK_LONG_CALLS, \
N_("Don't use indirect calls")}, \
- {"embedded-pic", MASK_EMBEDDED_PIC, \
- N_("Use embedded PIC")}, \
- {"no-embedded-pic", -MASK_EMBEDDED_PIC, \
- N_("Don't use embedded PIC")}, \
{"embedded-data", MASK_EMBEDDED_DATA, \
N_("Use ROM instead of RAM")}, \
{"no-embedded-data", -MASK_EMBEDDED_DATA, \
@@ -592,6 +624,10 @@ extern const struct mips_cpu_info *mips_tune_info;
N_("Don't generate fused multiply/add instructions")}, \
{"fused-madd", -MASK_NO_FUSED_MADD, \
N_("Generate fused multiply/add instructions")}, \
+ {"vr4130-align", MASK_VR4130_ALIGN, \
+ N_("Perform VR4130-specific alignment optimizations")}, \
+ {"no-vr4130-align", -MASK_VR4130_ALIGN, \
+ N_("Don't perform VR4130-specific alignment optimizations")}, \
{"fix4300", MASK_4300_MUL_FIX, \
N_("Work around early 4300 hardware bug")}, \
{"no-fix4300", -MASK_4300_MUL_FIX, \
@@ -608,10 +644,10 @@ extern const struct mips_cpu_info *mips_tune_info;
N_("Work around R4400 errata")}, \
{"no-fix-r4400", -MASK_FIX_R4400, \
N_("Don't work around R4400 errata")}, \
- {"fix-vr4122-bugs", MASK_FIX_VR4122, \
- N_("Work around certain VR4122 errata")}, \
- {"no-fix-vr4122-bugs", -MASK_FIX_VR4122, \
- N_("Don't work around certain VR4122 errata")}, \
+ {"fix-vr4120", MASK_FIX_VR4120, \
+ N_("Work around certain VR4120 errata")}, \
+ {"no-fix-vr4120", -MASK_FIX_VR4120, \
+ N_("Don't work around certain VR4120 errata")}, \
{"check-zero-division",-MASK_NO_CHECK_ZERO_DIV, \
N_("Trap on integer divide by zero")}, \
{"no-check-zero-division", MASK_NO_CHECK_ZERO_DIV, \
@@ -632,6 +668,10 @@ extern const struct mips_cpu_info *mips_tune_info;
N_("Lift restrictions on GOT size") }, \
{"no-xgot", -MASK_XGOT, \
N_("Do not lift restrictions on GOT size") }, \
+ {"fp-exceptions", MASK_FP_EXCEPTIONS, \
+ N_("FP exceptions are enabled") }, \
+ {"no-fp-exceptions", -MASK_FP_EXCEPTIONS, \
+ N_("FP exceptions are not enabled") }, \
{"debug", MASK_DEBUG, \
NULL}, \
{"debugc", MASK_DEBUG_C, \
@@ -642,7 +682,8 @@ extern const struct mips_cpu_info *mips_tune_info;
NULL}, \
{"", (TARGET_DEFAULT \
| TARGET_CPU_DEFAULT \
- | TARGET_ENDIAN_DEFAULT), \
+ | TARGET_ENDIAN_DEFAULT \
+ | TARGET_FP_EXCEPTIONS_DEFAULT), \
NULL}, \
}
@@ -660,6 +701,10 @@ extern const struct mips_cpu_info *mips_tune_info;
#define TARGET_ENDIAN_DEFAULT MASK_BIG_ENDIAN
#endif
+#ifndef TARGET_FP_EXCEPTIONS_DEFAULT
+#define TARGET_FP_EXCEPTIONS_DEFAULT MASK_FP_EXCEPTIONS
+#endif
+
/* 'from-abi' makes a good default: you get whatever the ABI requires. */
#ifndef MIPS_ISA_DEFAULT
#ifndef MIPS_CPU_STRING_DEFAULT
@@ -813,8 +858,7 @@ extern const struct mips_cpu_info *mips_tune_info;
/* ISA has branch likely instructions (eg. mips2). */
/* Disable branchlikely for tx39 until compare rewrite. They haven't
been generated up to this point. */
-#define ISA_HAS_BRANCHLIKELY (!ISA_MIPS1 \
- && !TARGET_MIPS5500)
+#define ISA_HAS_BRANCHLIKELY (!ISA_MIPS1)
/* ISA has the conditional move instructions introduced in mips4. */
#define ISA_HAS_CONDMOVE ((ISA_MIPS4 \
@@ -1115,10 +1159,9 @@ extern const struct mips_cpu_info *mips_tune_info;
%{G*} %(endian_spec) %{mips1} %{mips2} %{mips3} %{mips4} \
%{mips32} %{mips32r2} %{mips64} \
%{mips16:%{!mno-mips16:-mips16}} %{mno-mips16:-no-mips16} \
-%{mfix-vr4122-bugs} \
+%{mfix-vr4120} \
%(subtarget_asm_optimizing_spec) \
%(subtarget_asm_debugging_spec) \
-%{membedded-pic} \
%{mabi=32:-32}%{mabi=n32:-n32}%{mabi=64:-64}%{mabi=n64:-64} \
%{mabi=eabi} %{mabi=o64} %{!mabi*: %(asm_abi_default_spec)} \
%{mgp32} %{mgp64} %{march=*} %{mxgot:-xgot} \
@@ -1214,6 +1257,8 @@ extern const struct mips_cpu_info *mips_tune_info;
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
#endif
+#define DWARF2_ADDR_SIZE (ABI_HAS_64BIT_SYMBOLS ? 8 : 4)
+
/* By default, turn on GDB extensions. */
#define DEFAULT_GDB_EXTENSIONS 1
@@ -2039,7 +2084,7 @@ extern enum reg_class mips_char_to_class[256];
`T' is for constant move_operands that cannot be safely loaded into $25.
`U' is for constant move_operands that can be safely loaded into $25.
`W' is for memory references that are based on a member of BASE_REG_CLASS.
- This is true for all non-mips16 references (although it can somtimes
+ This is true for all non-mips16 references (although it can sometimes
be indirect if !TARGET_EXPLICIT_RELOCS). For mips16, it excludes
stack and constant-pool references. */
@@ -2574,14 +2619,6 @@ typedef struct mips_args {
XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \
else \
asm_fprintf ((FILE), "%U%s", (NAME))
-
-/* The mips16 wants the constant pool to be after the function,
- because the PC relative load instructions use unsigned offsets. */
-
-#define CONSTANT_POOL_BEFORE_FUNCTION (! TARGET_MIPS16)
-
-#define ASM_OUTPUT_POOL_EPILOGUE(FILE, FNNAME, FNDECL, SIZE) \
- mips_string_length = 0;
/* Specify the machine mode that this machine uses
for the index in the tablejump instruction.
@@ -2682,7 +2719,7 @@ typedef struct mips_args {
/* ??? Fix this to be right for the R8000. */
#define BRANCH_COST \
((! TARGET_MIPS16 \
- && (TUNE_MIPS4000 || TUNE_MIPS6000)) \
+ && (TUNE_MIPS4000 || TUNE_MIPS6000)) \
? 2 : 1)
/* If defined, modifies the length assigned to instruction INSN as a
@@ -2742,6 +2779,7 @@ typedef struct mips_args {
CONST_DOUBLE, CONST }}, \
{"fcc_register_operand", { REG, SUBREG }}, \
{"hilo_operand", { REG }}, \
+ {"macc_msac_operand", { PLUS, MINUS }}, \
{"extend_operator", { ZERO_EXTEND, SIGN_EXTEND }},
/* A list of predicates that do special things with modes, and so
@@ -3206,19 +3244,15 @@ while (0)
LOCAL_LABEL_PREFIX, \
VALUE)
-/* This is how to output an element of a case-vector that is relative.
- This is used for pc-relative code (e.g. when TARGET_ABICALLS or
- TARGET_EMBEDDED_PIC). */
+/* This is how to output an element of a case-vector. We can make the
+ entries PC-relative in MIPS16 code and GP-relative when .gp(d)word
+ is supported. */
#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \
do { \
if (TARGET_MIPS16) \
fprintf (STREAM, "\t.half\t%sL%d-%sL%d\n", \
LOCAL_LABEL_PREFIX, VALUE, LOCAL_LABEL_PREFIX, REL); \
- else if (TARGET_EMBEDDED_PIC) \
- fprintf (STREAM, "\t%s\t%sL%d-%sLS%d\n", \
- ptr_mode == DImode ? ".dword" : ".word", \
- LOCAL_LABEL_PREFIX, VALUE, LOCAL_LABEL_PREFIX, REL); \
else if (TARGET_GPWORD) \
fprintf (STREAM, "\t%s\t%sL%d\n", \
ptr_mode == DImode ? ".gpdword" : ".gpword", \
@@ -3229,16 +3263,15 @@ do { \
LOCAL_LABEL_PREFIX, VALUE); \
} while (0)
-/* When generating embedded PIC or mips16 code we want to put the jump
- table in the .text section. In all other cases, we want to put the
- jump table in the .rdata section. Unfortunately, we can't use
- JUMP_TABLES_IN_TEXT_SECTION, because it is not conditional.
- Instead, we use ASM_OUTPUT_CASE_LABEL to switch back to the .text
- section if appropriate. */
+/* When generating mips16 code we want to put the jump table in the .text
+ section. In all other cases, we want to put the jump table in the .rdata
+ section. Unfortunately, we can't use JUMP_TABLES_IN_TEXT_SECTION, because
+ it is not conditional. Instead, we use ASM_OUTPUT_CASE_LABEL to switch back
+ to the .text section if appropriate. */
#undef ASM_OUTPUT_CASE_LABEL
#define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, INSN) \
do { \
- if (TARGET_EMBEDDED_PIC || TARGET_MIPS16) \
+ if (TARGET_MIPS16) \
function_section (current_function_decl); \
(*targetm.asm_out.internal_label) (FILE, PREFIX, NUM); \
} while (0)
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 21b8277af3f..c3e4ccd7372 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -35,15 +35,9 @@
(UNSPEC_CPRESTORE 5)
(UNSPEC_EH_RECEIVER 6)
(UNSPEC_EH_RETURN 7)
- (UNSPEC_CONSTTABLE_QI 8)
- (UNSPEC_CONSTTABLE_HI 9)
- (UNSPEC_CONSTTABLE_SI 10)
- (UNSPEC_CONSTTABLE_DI 11)
- (UNSPEC_CONSTTABLE_SF 12)
- (UNSPEC_CONSTTABLE_DF 13)
- (UNSPEC_ALIGN_2 14)
- (UNSPEC_ALIGN_4 15)
- (UNSPEC_ALIGN_8 16)
+ (UNSPEC_CONSTTABLE_INT 8)
+ (UNSPEC_CONSTTABLE_FLOAT 9)
+ (UNSPEC_ALIGN 14)
(UNSPEC_HIGH 17)
(UNSPEC_LWL 18)
(UNSPEC_LWR 19)
@@ -57,6 +51,7 @@
(UNSPEC_LOAD_CALL 27)
(UNSPEC_LOAD_GOT 28)
(UNSPEC_GP 29)
+ (UNSPEC_MFHILO 30)
(UNSPEC_ADDRESS_FIRST 100)
@@ -173,13 +168,13 @@
;; Note that this value does not account for the delay slot
;; instruction, whose length is added separately. If the RTL
;; pattern has no explicit delay slot, mips_adjust_insn_length
- ;; will add the length of the implicit nop.
+ ;; will add the length of the implicit nop. The values for
+ ;; forward and backward branches will be different as well.
(eq_attr "type" "branch")
- (cond [(lt (abs (minus (match_dup 1) (plus (pc) (const_int 4))))
- (const_int 131072))
- (const_int 4)
- (ne (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC")
- (const_int 0))
+ (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064))
+ (le (minus (pc) (match_dup 1)) (const_int 131068)))
+ (const_int 4)
+ (ne (symbol_ref "flag_pic") (const_int 0))
(const_int 24)
] (const_int 12))
@@ -212,19 +207,19 @@
(ne (symbol_ref "TARGET_MIPS16") (const_int 0)))
(const_int 8)
- ;; Various VR4122 errata require a nop to be inserted after a macc
+ ;; Various VR4120 errata require a nop to be inserted after a macc
;; instruction. The assembler does this for us, so account for
;; the worst-case length here.
(and (eq_attr "type" "imadd")
- (ne (symbol_ref "TARGET_FIX_VR4122") (const_int 0)))
+ (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))
(const_int 8)
- ;; VR4122 errata MD(4): if there are consecutive dmult instructions,
+ ;; VR4120 errata MD(4): if there are consecutive dmult instructions,
;; the result of the second one is missed. The assembler should work
;; around this by inserting a nop after the first dmult.
(and (eq_attr "type" "imul")
(and (eq_attr "mode" "DI")
- (ne (symbol_ref "TARGET_FIX_VR4122") (const_int 0))))
+ (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))))
(const_int 8)
(eq_attr "type" "idiv")
@@ -283,6 +278,13 @@
(const_string "yes")
(const_string "no"))))
+;; True if an instruction might assign to hi or lo when reloaded.
+;; This is used by the TUNE_MACC_CHAINS code.
+(define_attr "may_clobber_hilo" "no,yes"
+ (if_then_else (eq_attr "type" "imul,imadd,idiv,mthilo")
+ (const_string "yes")
+ (const_string "no")))
+
;; Describe a user's asm statement.
(define_asm_attributes
[(set_attr "type" "multi")])
@@ -629,10 +631,12 @@
;; Include scheduling descriptions.
+(include "4130.md")
(include "5400.md")
(include "5500.md")
(include "7000.md")
(include "9000.md")
+(include "sb1.md")
(include "sr71k.md")
;;
@@ -660,7 +664,7 @@
(define_expand "conditional_trap"
[(trap_if (match_operator 0 "cmp_op"
[(match_dup 2) (match_dup 3)])
- (match_operand 1 "const_int_operand" ""))]
+ (match_operand 1 "const_int_operand"))]
"ISA_HAS_COND_TRAP"
{
if (operands[1] == const0_rtx)
@@ -717,9 +721,9 @@
(set_attr "mode" "SF")])
(define_expand "addsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
- (match_operand:SI 2 "arith_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (plus:SI (match_operand:SI 1 "reg_or_0_operand")
+ (match_operand:SI 2 "arith_operand")))]
""
{
/* If a large stack adjustment was forced into a register, we may be
@@ -767,7 +771,7 @@
"addu\t%$,%$,%0"
[(set_attr "type" "arith")
(set_attr "mode" "SI")
- (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
+ (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8")
(const_int 4)
(const_int 8)))])
@@ -779,7 +783,7 @@
"addu\t%0,%$,%1"
[(set_attr "type" "arith")
(set_attr "mode" "SI")
- (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4" "")
+ (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_uimm8_4")
(const_int 4)
(const_int 8)))])
@@ -809,10 +813,10 @@
[(set_attr "type" "arith")
(set_attr "mode" "SI")
(set_attr_alternative "length"
- [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
+ [(if_then_else (match_operand:VOID 2 "m16_simm8_1")
(const_int 4)
(const_int 8))
- (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
+ (if_then_else (match_operand:VOID 2 "m16_simm4_1")
(const_int 4)
(const_int 8))
(const_int 4)])])
@@ -825,9 +829,9 @@
;; simply adding a constant to a register.
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
+ [(set (match_operand:SI 0 "register_operand")
(plus:SI (match_dup 0)
- (match_operand:SI 1 "const_int_operand" "")))]
+ (match_operand:SI 1 "const_int_operand")))]
"TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
&& GET_CODE (operands[0]) == REG
&& M16_REG_P (REGNO (operands[0]))
@@ -854,9 +858,9 @@
})
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (plus:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "const_int_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (plus:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "const_int_operand")))]
"TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
&& GET_CODE (operands[0]) == REG
&& M16_REG_P (REGNO (operands[0]))
@@ -886,9 +890,9 @@
})
(define_expand "adddi3"
- [(parallel [(set (match_operand:DI 0 "register_operand" "")
- (plus:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "arith_operand" "")))
+ [(parallel [(set (match_operand:DI 0 "register_operand")
+ (plus:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "arith_operand")))
(clobber (match_dup 3))])]
"TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
{
@@ -940,10 +944,10 @@
(set_attr "length" "16")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (plus:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "register_operand" "")))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (plus:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "register_operand")))
+ (clobber (match_operand:SI 3 "register_operand"))]
"reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
&& !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
&& GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
@@ -970,10 +974,10 @@
"")
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (plus:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "register_operand" "")))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (plus:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "register_operand")))
+ (clobber (match_operand:SI 3 "register_operand"))]
"reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
&& !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
&& GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
@@ -1014,10 +1018,10 @@
(set_attr "length" "12,8,16")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (plus:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "small_int" "")))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (plus:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "small_int")))
+ (clobber (match_operand:SI 3 "register_operand"))]
"reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
&& !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
&& GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
@@ -1038,10 +1042,10 @@
"")
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (plus:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "small_int" "")))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (plus:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "small_int")))
+ (clobber (match_operand:SI 3 "register_operand"))]
"reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
&& !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
&& GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
@@ -1084,7 +1088,7 @@
"daddu\t%$,%$,%0"
[(set_attr "type" "arith")
(set_attr "mode" "DI")
- (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8" "")
+ (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_simm8_8")
(const_int 4)
(const_int 8)))])
@@ -1096,7 +1100,7 @@
"daddu\t%0,%$,%1"
[(set_attr "type" "arith")
(set_attr "mode" "DI")
- (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4" "")
+ (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_uimm5_4")
(const_int 4)
(const_int 8)))])
@@ -1126,10 +1130,10 @@
[(set_attr "type" "arith")
(set_attr "mode" "DI")
(set_attr_alternative "length"
- [(if_then_else (match_operand:VOID 2 "m16_simm5_1" "")
+ [(if_then_else (match_operand:VOID 2 "m16_simm5_1")
(const_int 4)
(const_int 8))
- (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
+ (if_then_else (match_operand:VOID 2 "m16_simm4_1")
(const_int 4)
(const_int 8))
(const_int 4)])])
@@ -1142,9 +1146,9 @@
;; simply adding a constant to a register.
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(plus:DI (match_dup 0)
- (match_operand:DI 1 "const_int_operand" "")))]
+ (match_operand:DI 1 "const_int_operand")))]
"TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
&& GET_CODE (operands[0]) == REG
&& M16_REG_P (REGNO (operands[0]))
@@ -1171,9 +1175,9 @@
})
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (plus:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "const_int_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (plus:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "const_int_operand")))]
"TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE
&& GET_CODE (operands[0]) == REG
&& M16_REG_P (REGNO (operands[0]))
@@ -1227,10 +1231,10 @@
[(set_attr "type" "arith")
(set_attr "mode" "SI")
(set_attr_alternative "length"
- [(if_then_else (match_operand:VOID 2 "m16_simm8_1" "")
+ [(if_then_else (match_operand:VOID 2 "m16_simm8_1")
(const_int 4)
(const_int 8))
- (if_then_else (match_operand:VOID 2 "m16_simm4_1" "")
+ (if_then_else (match_operand:VOID 2 "m16_simm4_1")
(const_int 4)
(const_int 8))
(const_int 4)])])
@@ -1262,9 +1266,9 @@
(set_attr "mode" "SF")])
(define_expand "subsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (minus:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "register_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (minus:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "register_operand")))]
""
"")
@@ -1278,9 +1282,9 @@
(set_attr "mode" "SI")])
(define_expand "subdi3"
- [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
- (minus:DI (match_operand:DI 1 "register_operand" "d")
- (match_operand:DI 2 "register_operand" "d")))
+ [(parallel [(set (match_operand:DI 0 "register_operand")
+ (minus:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "register_operand")))
(clobber (match_dup 3))])]
"TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
{
@@ -1306,10 +1310,10 @@
(set_attr "length" "16")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (minus:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "register_operand" "")))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (minus:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "register_operand")))
+ (clobber (match_operand:SI 3 "register_operand"))]
"reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
&& !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
&& GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
@@ -1334,10 +1338,10 @@
"")
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (minus:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "register_operand" "")))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (minus:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "register_operand")))
+ (clobber (match_operand:SI 3 "register_operand"))]
"reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
&& !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
&& GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0]))
@@ -1389,9 +1393,9 @@
;;
(define_expand "muldf3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (mult:DF (match_operand:DF 1 "register_operand" "f")
- (match_operand:DF 2 "register_operand" "f")))]
+ [(set (match_operand:DF 0 "register_operand")
+ (mult:DF (match_operand:DF 1 "register_operand")
+ (match_operand:DF 2 "register_operand")))]
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
"")
@@ -1419,9 +1423,9 @@
(set_attr "length" "8")])
(define_expand "mulsf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (mult:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "register_operand" "f")))]
+ [(set (match_operand:SF 0 "register_operand")
+ (mult:SF (match_operand:SF 1 "register_operand")
+ (match_operand:SF 2 "register_operand")))]
"TARGET_HARD_FLOAT"
"")
@@ -1494,9 +1498,9 @@
;; respectively.
(define_expand "mulsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (mult:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "register_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (mult:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "register_operand")))]
""
{
if (GENERATE_MULT3_SI || TARGET_MAD)
@@ -1544,17 +1548,14 @@
;; Operand 4: GPR (destination)
(define_peephole2
[(parallel
- [(set (match_operand:SI 0 "register_operand" "")
- (mult:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "register_operand" "")))
- (clobber (match_operand:SI 3 "register_operand" ""))
+ [(set (match_operand:SI 0 "register_operand")
+ (mult:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "register_operand")))
+ (clobber (match_operand:SI 3 "register_operand"))
(clobber (scratch:SI))])
- (set (match_operand:SI 4 "register_operand" "")
- (match_dup 0))]
- "GENERATE_MULT3_SI
- && true_regnum (operands[0]) == LO_REGNUM
- && GP_REG_P (true_regnum (operands[4]))
- && peep2_reg_dead_p (2, operands[0])"
+ (set (match_operand:SI 4 "register_operand")
+ (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
+ "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"
[(parallel
[(set (match_dup 4)
(mult:SI (match_dup 1)
@@ -1584,6 +1585,37 @@
(set_attr "mode" "SI")
(set_attr "length" "8")])
+;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead
+;; of "mult; mflo". They have the same latency, but the first form gives
+;; us an extra cycle to compute the operands.
+
+;; Operand 0: LO
+;; Operand 1: GPR (1st multiplication operand)
+;; Operand 2: GPR (2nd multiplication operand)
+;; Operand 3: HI
+;; Operand 4: GPR (destination)
+(define_peephole2
+ [(parallel
+ [(set (match_operand:SI 0 "register_operand")
+ (mult:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "register_operand")))
+ (clobber (match_operand:SI 3 "register_operand"))])
+ (set (match_operand:SI 4 "register_operand")
+ (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]
+ "ISA_HAS_MACC && !GENERATE_MULT3_SI"
+ [(set (match_dup 0)
+ (const_int 0))
+ (parallel
+ [(set (match_dup 0)
+ (plus:SI (mult:SI (match_dup 1)
+ (match_dup 2))
+ (match_dup 0)))
+ (set (match_dup 4)
+ (plus:SI (mult:SI (match_dup 1)
+ (match_dup 2))
+ (match_dup 0)))
+ (clobber (match_dup 3))])])
+
;; Multiply-accumulate patterns
;; For processors that can copy the output to a general register:
@@ -1621,13 +1653,13 @@
;; Split the above insn if we failed to get LO allocated.
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "register_operand" ""))
- (match_operand:SI 3 "register_operand" "")))
- (clobber (match_scratch:SI 4 ""))
- (clobber (match_scratch:SI 5 ""))
- (clobber (match_scratch:SI 6 ""))]
+ [(set (match_operand:SI 0 "register_operand")
+ (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "register_operand"))
+ (match_operand:SI 3 "register_operand")))
+ (clobber (match_scratch:SI 4))
+ (clobber (match_scratch:SI 5))
+ (clobber (match_scratch:SI 6))]
"reload_completed && !TARGET_DEBUG_D_MODE
&& GP_REG_P (true_regnum (operands[0]))
&& GP_REG_P (true_regnum (operands[3]))"
@@ -1640,13 +1672,13 @@
;; Splitter to copy result of MADD to a general register
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "register_operand" ""))
- (match_operand:SI 3 "register_operand" "")))
- (clobber (match_scratch:SI 4 ""))
- (clobber (match_scratch:SI 5 ""))
- (clobber (match_scratch:SI 6 ""))]
+ [(set (match_operand:SI 0 "register_operand")
+ (plus:SI (mult:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "register_operand"))
+ (match_operand:SI 3 "register_operand")))
+ (clobber (match_scratch:SI 4))
+ (clobber (match_scratch:SI 5))
+ (clobber (match_scratch:SI 6))]
"reload_completed && !TARGET_DEBUG_D_MODE
&& GP_REG_P (true_regnum (operands[0]))
&& true_regnum (operands[3]) == LO_REGNUM"
@@ -1656,7 +1688,7 @@
(clobber (match_dup 4))
(clobber (match_dup 5))
(clobber (match_dup 6))])
- (set (match_dup 0) (match_dup 3))]
+ (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
"")
(define_insn "*macc"
@@ -1673,12 +1705,60 @@
else if (TARGET_MIPS5500)
return "madd\t%1,%2";
else
- return "macc\t%.,%1,%2";
+ /* The VR4130 assumes that there is a two-cycle latency between a macc
+ that "writes" to $0 and an instruction that reads from it. We avoid
+ this by assigning to $1 instead. */
+ return "%[macc\t%@,%1,%2%]";
}
[(set_attr "type" "imadd")
(set_attr "mode" "SI")])
-;; Pattern generated by define_peephole2 below
+(define_insn "*msac"
+ [(set (match_operand:SI 0 "register_operand" "=l,d")
+ (minus:SI (match_operand:SI 1 "register_operand" "0,l")
+ (mult:SI (match_operand:SI 2 "register_operand" "d,d")
+ (match_operand:SI 3 "register_operand" "d,d"))))
+ (clobber (match_scratch:SI 4 "=h,h"))
+ (clobber (match_scratch:SI 5 "=X,1"))]
+ "ISA_HAS_MSAC"
+{
+ if (which_alternative == 1)
+ return "msac\t%0,%2,%3";
+ else if (TARGET_MIPS5500)
+ return "msub\t%2,%3";
+ else
+ return "msac\t$0,%2,%3";
+}
+ [(set_attr "type" "imadd")
+ (set_attr "mode" "SI")])
+
+;; An msac-like instruction implemented using negation and a macc.
+(define_insn_and_split "*msac_using_macc"
+ [(set (match_operand:SI 0 "register_operand" "=l,d")
+ (minus:SI (match_operand:SI 1 "register_operand" "0,l")
+ (mult:SI (match_operand:SI 2 "register_operand" "d,d")
+ (match_operand:SI 3 "register_operand" "d,d"))))
+ (clobber (match_scratch:SI 4 "=h,h"))
+ (clobber (match_scratch:SI 5 "=X,1"))
+ (clobber (match_scratch:SI 6 "=d,d"))]
+ "ISA_HAS_MACC && !ISA_HAS_MSAC"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 6)
+ (neg:SI (match_dup 3)))
+ (parallel
+ [(set (match_dup 0)
+ (plus:SI (mult:SI (match_dup 2)
+ (match_dup 6))
+ (match_dup 1)))
+ (clobber (match_dup 4))
+ (clobber (match_dup 5))])]
+ ""
+ [(set_attr "type" "imadd")
+ (set_attr "length" "8")])
+
+;; Patterns generated by the define_peephole2 below.
+
(define_insn "*macc2"
[(set (match_operand:SI 0 "register_operand" "=l")
(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
@@ -1694,35 +1774,42 @@
[(set_attr "type" "imadd")
(set_attr "mode" "SI")])
+(define_insn "*msac2"
+ [(set (match_operand:SI 0 "register_operand" "=l")
+ (minus:SI (match_dup 0)
+ (mult:SI (match_operand:SI 1 "register_operand" "d")
+ (match_operand:SI 2 "register_operand" "d"))))
+ (set (match_operand:SI 3 "register_operand" "=d")
+ (minus:SI (match_dup 0)
+ (mult:SI (match_dup 1)
+ (match_dup 2))))
+ (clobber (match_scratch:SI 4 "=h"))]
+ "ISA_HAS_MSAC && reload_completed"
+ "msac\t%3,%1,%2"
+ [(set_attr "type" "imadd")
+ (set_attr "mode" "SI")])
+
;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
+;; Similarly msac.
;;
;; Operand 0: LO
-;; Operand 1: GPR (1st multiplication operand)
-;; Operand 2: GPR (2nd multiplication operand)
-;; Operand 3: HI
-;; Operand 4: GPR (destination)
+;; Operand 1: macc/msac
+;; Operand 2: HI
+;; Operand 3: GPR (destination)
(define_peephole2
[(parallel
- [(set (match_operand:SI 0 "register_operand" "")
- (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "register_operand" ""))
- (match_dup 0)))
- (clobber (match_operand:SI 3 "register_operand" ""))
+ [(set (match_operand:SI 0 "register_operand")
+ (match_operand:SI 1 "macc_msac_operand"))
+ (clobber (match_operand:SI 2 "register_operand"))
(clobber (scratch:SI))])
- (set (match_operand:SI 4 "register_operand" "")
- (match_dup 0))]
- "ISA_HAS_MACC
- && true_regnum (operands[0]) == LO_REGNUM
- && GP_REG_P (true_regnum (operands[4]))"
+ (set (match_operand:SI 3 "register_operand")
+ (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))]
+ ""
[(parallel [(set (match_dup 0)
- (plus:SI (mult:SI (match_dup 1)
- (match_dup 2))
- (match_dup 0)))
- (set (match_dup 4)
- (plus:SI (mult:SI (match_dup 1)
- (match_dup 2))
- (match_dup 0)))
- (clobber (match_dup 3))])]
+ (match_dup 1))
+ (set (match_dup 3)
+ (match_dup 1))
+ (clobber (match_dup 2))])]
"")
;; When we have a three-address multiplication instruction, it should
@@ -1736,72 +1823,71 @@
;; Operand 1: LO
;; Operand 2: GPR (addend)
;; Operand 3: GPR (destination)
-;; Operand 4: GPR (1st multiplication operand)
-;; Operand 5: GPR (2nd multiplication operand)
-;; Operand 6: HI
+;; Operand 4: macc/msac
+;; Operand 5: HI
+;; Operand 6: new multiplication
+;; Operand 7: new addition/subtraction
(define_peephole2
[(match_scratch:SI 0 "d")
- (set (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "register_operand" ""))
+ (set (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "register_operand"))
(match_dup 0)
(parallel
- [(set (match_operand:SI 3 "register_operand" "")
- (plus:SI (mult:SI (match_operand:SI 4 "register_operand" "")
- (match_operand:SI 5 "register_operand" ""))
- (match_dup 1)))
- (clobber (match_operand:SI 6 "register_operand" ""))
+ [(set (match_operand:SI 3 "register_operand")
+ (match_operand:SI 4 "macc_msac_operand"))
+ (clobber (match_operand:SI 5 "register_operand"))
(clobber (match_dup 1))])]
- "ISA_HAS_MACC && GENERATE_MULT3_SI
+ "GENERATE_MULT3_SI
&& true_regnum (operands[1]) == LO_REGNUM
&& peep2_reg_dead_p (2, operands[1])
&& GP_REG_P (true_regnum (operands[3]))"
[(parallel [(set (match_dup 0)
- (mult:SI (match_dup 4)
- (match_dup 5)))
- (clobber (match_dup 6))
+ (match_dup 6))
+ (clobber (match_dup 5))
(clobber (match_dup 1))])
(set (match_dup 3)
- (plus:SI (match_dup 0)
- (match_dup 2)))]
- "")
+ (match_dup 7))]
+{
+ operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
+ operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
+ operands[2], operands[0]);
+})
;; Same as above, except LO is the initial target of the macc.
;;
;; Operand 0: GPR (scratch)
;; Operand 1: LO
;; Operand 2: GPR (addend)
-;; Operand 3: GPR (1st multiplication operand)
-;; Operand 4: GPR (2nd multiplication operand)
-;; Operand 5: HI
-;; Operand 6: GPR (destination)
+;; Operand 3: macc/msac
+;; Operand 4: HI
+;; Operand 5: GPR (destination)
+;; Operand 6: new multiplication
+;; Operand 7: new addition/subtraction
(define_peephole2
[(match_scratch:SI 0 "d")
- (set (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "register_operand" ""))
+ (set (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "register_operand"))
(match_dup 0)
(parallel
[(set (match_dup 1)
- (plus:SI (mult:SI (match_operand:SI 3 "register_operand" "")
- (match_operand:SI 4 "register_operand" ""))
- (match_dup 1)))
- (clobber (match_operand:SI 5 "register_operand" ""))
+ (match_operand:SI 3 "macc_msac_operand"))
+ (clobber (match_operand:SI 4 "register_operand"))
(clobber (scratch:SI))])
(match_dup 0)
- (set (match_operand:SI 6 "register_operand" "")
- (match_dup 1))]
- "ISA_HAS_MACC && GENERATE_MULT3_SI
- && true_regnum (operands[1]) == LO_REGNUM
- && peep2_reg_dead_p (3, operands[1])
- && GP_REG_P (true_regnum (operands[6]))"
+ (set (match_operand:SI 5 "register_operand")
+ (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))]
+ "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])"
[(parallel [(set (match_dup 0)
- (mult:SI (match_dup 3)
- (match_dup 4)))
- (clobber (match_dup 5))
+ (match_dup 6))
+ (clobber (match_dup 4))
(clobber (match_dup 1))])
- (set (match_dup 6)
- (plus:SI (match_dup 0)
- (match_dup 2)))]
- "")
+ (set (match_dup 5)
+ (match_dup 7))]
+{
+ operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
+ operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
+ operands[2], operands[0]);
+})
(define_insn "*mul_sub_si"
[(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
@@ -1822,13 +1908,13 @@
;; Split the above insn if we failed to get LO allocated.
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (minus:SI (match_operand:SI 1 "register_operand" "")
- (mult:SI (match_operand:SI 2 "register_operand" "")
- (match_operand:SI 3 "register_operand" ""))))
- (clobber (match_scratch:SI 4 ""))
- (clobber (match_scratch:SI 5 ""))
- (clobber (match_scratch:SI 6 ""))]
+ [(set (match_operand:SI 0 "register_operand")
+ (minus:SI (match_operand:SI 1 "register_operand")
+ (mult:SI (match_operand:SI 2 "register_operand")
+ (match_operand:SI 3 "register_operand"))))
+ (clobber (match_scratch:SI 4))
+ (clobber (match_scratch:SI 5))
+ (clobber (match_scratch:SI 6))]
"reload_completed && !TARGET_DEBUG_D_MODE
&& GP_REG_P (true_regnum (operands[0]))
&& GP_REG_P (true_regnum (operands[1]))"
@@ -1841,13 +1927,13 @@
;; Splitter to copy result of MSUB to a general register
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (minus:SI (match_operand:SI 1 "register_operand" "")
- (mult:SI (match_operand:SI 2 "register_operand" "")
- (match_operand:SI 3 "register_operand" ""))))
- (clobber (match_scratch:SI 4 ""))
- (clobber (match_scratch:SI 5 ""))
- (clobber (match_scratch:SI 6 ""))]
+ [(set (match_operand:SI 0 "register_operand")
+ (minus:SI (match_operand:SI 1 "register_operand")
+ (mult:SI (match_operand:SI 2 "register_operand")
+ (match_operand:SI 3 "register_operand"))))
+ (clobber (match_scratch:SI 4))
+ (clobber (match_scratch:SI 5))
+ (clobber (match_scratch:SI 6))]
"reload_completed && !TARGET_DEBUG_D_MODE
&& GP_REG_P (true_regnum (operands[0]))
&& true_regnum (operands[1]) == LO_REGNUM"
@@ -1857,7 +1943,7 @@
(clobber (match_dup 4))
(clobber (match_dup 5))
(clobber (match_dup 6))])
- (set (match_dup 0) (match_dup 1))]
+ (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]
"")
(define_insn "*muls"
@@ -1873,29 +1959,10 @@
[(set_attr "type" "imul")
(set_attr "mode" "SI")])
-(define_insn "*msac"
- [(set (match_operand:SI 0 "register_operand" "=l,d")
- (minus:SI (match_operand:SI 1 "register_operand" "0,l")
- (mult:SI (match_operand:SI 2 "register_operand" "d,d")
- (match_operand:SI 3 "register_operand" "d,d"))))
- (clobber (match_scratch:SI 4 "=h,h"))
- (clobber (match_scratch:SI 5 "=X,1"))]
- "ISA_HAS_MSAC"
-{
- if (which_alternative == 1)
- return "msac\t%0,%2,%3";
- else if (TARGET_MIPS5500)
- return "msub\t%2,%3";
- else
- return "msac\t$0,%2,%3";
-}
- [(set_attr "type" "imadd")
- (set_attr "mode" "SI")])
-
(define_expand "muldi3"
- [(set (match_operand:DI 0 "register_operand" "")
- (mult:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "register_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (mult:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "register_operand")))]
"TARGET_64BIT"
{
if (GENERATE_MULT3_DI)
@@ -1944,10 +2011,10 @@
(define_expand "mulsidi3"
[(parallel
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(mult:DI
- (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
- (sign_extend:DI (match_operand:SI 2 "register_operand" ""))))
+ (sign_extend:DI (match_operand:SI 1 "register_operand"))
+ (sign_extend:DI (match_operand:SI 2 "register_operand"))))
(clobber (scratch:DI))
(clobber (scratch:DI))
(clobber (scratch:DI))])]
@@ -2013,8 +2080,8 @@
(const_int 32)))])
;; OP7 <- LO, OP0 <- HI
- (set (match_dup 7) (match_dup 5))
- (set (match_dup 0) (match_dup 6))
+ (set (match_dup 7) (unspec:DI [(match_dup 5) (match_dup 6)] UNSPEC_MFHILO))
+ (set (match_dup 0) (unspec:DI [(match_dup 6) (match_dup 5)] UNSPEC_MFHILO))
;; Zero-extend OP7.
(set (match_dup 7)
@@ -2062,10 +2129,10 @@
(define_expand "umulsidi3"
[(parallel
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(mult:DI
- (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
- (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
+ (zero_extend:DI (match_operand:SI 1 "register_operand"))
+ (zero_extend:DI (match_operand:SI 2 "register_operand"))))
(clobber (scratch:DI))
(clobber (scratch:DI))
(clobber (scratch:DI))])]
@@ -2169,11 +2236,11 @@
;; _highpart patterns
(define_expand "umulsi3_highpart"
- [(set (match_operand:SI 0 "register_operand" "")
+ [(set (match_operand:SI 0 "register_operand")
(truncate:SI
(lshiftrt:DI
- (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
- (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
+ (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"))
+ (zero_extend:DI (match_operand:SI 2 "register_operand")))
(const_int 32))))]
"ISA_HAS_MULHI || !TARGET_FIX_R4000"
{
@@ -2236,11 +2303,11 @@
(set_attr "length" "4")])
(define_expand "smulsi3_highpart"
- [(set (match_operand:SI 0 "register_operand" "")
+ [(set (match_operand:SI 0 "register_operand")
(truncate:SI
(lshiftrt:DI
- (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
- (sign_extend:DI (match_operand:SI 2 "register_operand" "")))
+ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand"))
+ (sign_extend:DI (match_operand:SI 2 "register_operand")))
(const_int 32))))]
"ISA_HAS_MULHI || !TARGET_FIX_R4000"
{
@@ -2315,8 +2382,8 @@
[(set_attr "type" "imul")
(set_attr "mode" "DI")])
-;; Disable this pattern for -mfix-vr4122-bugs. This is for VR4122 errata
-;; MD(0), which says that dmultu does not always produce the correct result.
+;; Disable this pattern for -mfix-vr4120. This is for VR4120 errata MD(0),
+;; which says that dmultu does not always produce the correct result.
(define_insn "umuldi3_highpart"
[(set (match_operand:DI 0 "register_operand" "=h")
(truncate:DI
@@ -2326,7 +2393,7 @@
(zero_extend:TI (match_operand:DI 2 "register_operand" "d")))
(const_int 64))))
(clobber (match_scratch:DI 3 "=l"))]
- "TARGET_64BIT && !TARGET_FIX_R4000 && !TARGET_FIX_VR4122"
+ "TARGET_64BIT && !TARGET_FIX_R4000 && !TARGET_FIX_VR4120"
"dmultu\t%1,%2"
[(set_attr "type" "imul")
(set_attr "mode" "DI")])
@@ -2360,7 +2427,8 @@
else if (TARGET_MIPS5500)
return "maddu\t%1,%2";
else
- return "maccu\t%.,%1,%2";
+ /* See comment in *macc. */
+ return "%[maccu\t%@,%1,%2%]";
}
[(set_attr "type" "imadd")
(set_attr "mode" "SI")])
@@ -2380,7 +2448,8 @@
else if (TARGET_MIPS5500)
return "madd\t%1,%2";
else
- return "macc\t%.,%1,%2";
+ /* See comment in *macc. */
+ return "%[macc\t%@,%1,%2%]";
}
[(set_attr "type" "imadd")
(set_attr "mode" "SI")])
@@ -2477,9 +2546,9 @@
;;
(define_expand "divdf3"
- [(set (match_operand:DF 0 "register_operand" "")
- (div:DF (match_operand:DF 1 "reg_or_const_float_1_operand" "")
- (match_operand:DF 2 "register_operand" "")))]
+ [(set (match_operand:DF 0 "register_operand")
+ (div:DF (match_operand:DF 1 "reg_or_const_float_1_operand")
+ (match_operand:DF 2 "register_operand")))]
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
{
if (const_float_1_operand (operands[1], DFmode))
@@ -2527,9 +2596,9 @@
;; errata, or if working around those errata and a slight loss of
;; precision is OK (i.e., flag_unsafe_math_optimizations is set).
(define_expand "divsf3"
- [(set (match_operand:SF 0 "register_operand" "")
- (div:SF (match_operand:SF 1 "reg_or_const_float_1_operand" "")
- (match_operand:SF 2 "register_operand" "")))]
+ [(set (match_operand:SF 0 "register_operand")
+ (div:SF (match_operand:SF 1 "reg_or_const_float_1_operand")
+ (match_operand:SF 2 "register_operand")))]
"TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
{
if (const_float_1_operand (operands[1], SFmode))
@@ -2600,7 +2669,7 @@
(const_int 8)
(const_int 4)))])
-;; VR4122 errata MD(A1): signed division instructions do not work correctly
+;; VR4120 errata MD(A1): signed division instructions do not work correctly
;; with negative operands. We use special libgcc functions instead.
(define_insn "divmodsi4"
[(set (match_operand:SI 0 "register_operand" "=l")
@@ -2609,7 +2678,7 @@
(set (match_operand:SI 3 "register_operand" "=h")
(mod:SI (match_dup 1)
(match_dup 2)))]
- "!TARGET_FIX_VR4122"
+ "!TARGET_FIX_VR4120"
{ return mips_output_division ("div\t$0,%1,%2", operands); }
[(set_attr "type" "idiv")
(set_attr "mode" "SI")])
@@ -2621,7 +2690,7 @@
(set (match_operand:DI 3 "register_operand" "=h")
(mod:DI (match_dup 1)
(match_dup 2)))]
- "TARGET_64BIT && !TARGET_FIX_VR4122"
+ "TARGET_64BIT && !TARGET_FIX_VR4120"
{ return mips_output_division ("ddiv\t$0,%1,%2", operands); }
[(set_attr "type" "idiv")
(set_attr "mode" "DI")])
@@ -2919,8 +2988,8 @@ dsrl\t%3,%3,1\n\
(set_attr "mode" "SI")])
(define_expand "negdi2"
- [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
- (neg:DI (match_operand:DI 1 "register_operand" "d")))
+ [(parallel [(set (match_operand:DI 0 "register_operand")
+ (neg:DI (match_operand:DI 1 "register_operand")))
(clobber (match_dup 2))])]
"(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16"
{
@@ -3005,9 +3074,9 @@ dsrl\t%3,%3,1\n\
;; want to use a different set of constraints when TARGET_MIPS16.
(define_expand "andsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (and:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
- (match_operand:SI 2 "uns_arith_operand" "d,K")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (and:SI (match_operand:SI 1 "uns_arith_operand")
+ (match_operand:SI 2 "uns_arith_operand")))]
""
{
if (TARGET_MIPS16)
@@ -3038,9 +3107,9 @@ dsrl\t%3,%3,1\n\
(set_attr "mode" "SI")])
(define_expand "anddi3"
- [(set (match_operand:DI 0 "register_operand" "")
- (and:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "uns_arith_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (and:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "uns_arith_operand")))]
"TARGET_64BIT"
{
if (TARGET_MIPS16)
@@ -3071,9 +3140,9 @@ dsrl\t%3,%3,1\n\
(set_attr "mode" "DI")])
(define_expand "iorsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
- (match_operand:SI 2 "uns_arith_operand" "d,K")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (ior:SI (match_operand:SI 1 "uns_arith_operand")
+ (match_operand:SI 2 "uns_arith_operand")))]
""
{
if (TARGET_MIPS16)
@@ -3104,9 +3173,9 @@ dsrl\t%3,%3,1\n\
(set_attr "mode" "SI")])
(define_expand "iordi3"
- [(set (match_operand:DI 0 "register_operand" "")
- (ior:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "uns_arith_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (ior:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "uns_arith_operand")))]
"TARGET_64BIT"
{
if (TARGET_MIPS16)
@@ -3137,9 +3206,9 @@ dsrl\t%3,%3,1\n\
(set_attr "mode" "DI")])
(define_expand "xorsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
- (match_operand:SI 2 "uns_arith_operand" "d,K")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (xor:SI (match_operand:SI 1 "uns_arith_operand")
+ (match_operand:SI 2 "uns_arith_operand")))]
""
"")
@@ -3167,15 +3236,15 @@ dsrl\t%3,%3,1\n\
(set_attr "mode" "SI")
(set_attr_alternative "length"
[(const_int 4)
- (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
+ (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
(const_int 4)
(const_int 8))
(const_int 4)])])
(define_expand "xordi3"
- [(set (match_operand:DI 0 "register_operand" "")
- (xor:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "uns_arith_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (xor:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "uns_arith_operand")))]
"TARGET_64BIT"
{
if (TARGET_MIPS16)
@@ -3209,7 +3278,7 @@ dsrl\t%3,%3,1\n\
(set_attr "mode" "DI")
(set_attr_alternative "length"
[(const_int 4)
- (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
+ (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
(const_int 4)
(const_int 8))
(const_int 4)])])
@@ -3413,8 +3482,8 @@ dsrl\t%3,%3,1\n\
(set_attr "mode" "DI")])
(define_expand "zero_extendhisi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
""
{
if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
@@ -3447,8 +3516,8 @@ dsrl\t%3,%3,1\n\
(set_attr "mode" "SI")])
(define_expand "zero_extendhidi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
"TARGET_64BIT"
{
if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
@@ -3481,8 +3550,8 @@ dsrl\t%3,%3,1\n\
(set_attr "mode" "DI")])
(define_expand "zero_extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "")
- (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
+ [(set (match_operand:HI 0 "register_operand")
+ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
""
{
if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
@@ -3516,8 +3585,8 @@ dsrl\t%3,%3,1\n\
(set_attr "mode" "HI")])
(define_expand "zero_extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
""
{
if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
@@ -3550,8 +3619,8 @@ dsrl\t%3,%3,1\n\
(set_attr "mode" "SI")])
(define_expand "zero_extendqidi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
"TARGET_64BIT"
{
if (TARGET_MIPS16 && GET_CODE (operands[1]) != MEM)
@@ -3612,8 +3681,8 @@ dsrl\t%3,%3,1\n\
;; all non-mem patterns after reload.
(define_expand "extendhidi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand")))]
"TARGET_64BIT"
"")
@@ -3624,8 +3693,8 @@ dsrl\t%3,%3,1\n\
"#")
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (sign_extend:DI (match_operand:HI 1 "register_operand")))]
"TARGET_64BIT && reload_completed"
[(set (match_dup 0)
(ashift:DI (match_dup 1) (const_int 48)))
@@ -3642,8 +3711,8 @@ dsrl\t%3,%3,1\n\
(set_attr "mode" "DI")])
(define_expand "extendhisi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
""
{
if (ISA_HAS_SEB_SEH)
@@ -3661,8 +3730,8 @@ dsrl\t%3,%3,1\n\
"#")
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (sign_extend:SI (match_operand:HI 1 "register_operand")))]
"reload_completed"
[(set (match_dup 0)
(ashift:SI (match_dup 1) (const_int 16)))
@@ -3687,8 +3756,8 @@ dsrl\t%3,%3,1\n\
(set_attr "mode" "SI")])
(define_expand "extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "")
- (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
+ [(set (match_operand:HI 0 "register_operand")
+ (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
""
"")
@@ -3699,8 +3768,8 @@ dsrl\t%3,%3,1\n\
"#")
(define_split
- [(set (match_operand:HI 0 "register_operand" "")
- (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
+ [(set (match_operand:HI 0 "register_operand")
+ (sign_extend:HI (match_operand:QI 1 "register_operand")))]
"reload_completed"
[(set (match_dup 0)
(ashift:SI (match_dup 1) (const_int 24)))
@@ -3719,8 +3788,8 @@ dsrl\t%3,%3,1\n\
(define_expand "extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
""
{
if (ISA_HAS_SEB_SEH)
@@ -3738,8 +3807,8 @@ dsrl\t%3,%3,1\n\
"#")
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (sign_extend:SI (match_operand:QI 1 "register_operand")))]
"reload_completed"
[(set (match_dup 0)
(ashift:SI (match_dup 1) (const_int 24)))
@@ -3764,8 +3833,8 @@ dsrl\t%3,%3,1\n\
(set_attr "mode" "SI")])
(define_expand "extendqidi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand")))]
"TARGET_64BIT"
"")
@@ -3776,8 +3845,8 @@ dsrl\t%3,%3,1\n\
"#")
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (sign_extend:DI (match_operand:QI 1 "register_operand")))]
"TARGET_64BIT && reload_completed"
[(set (match_dup 0)
(ashift:DI (match_dup 1) (const_int 56)))
@@ -3809,8 +3878,8 @@ dsrl\t%3,%3,1\n\
;; ....................
(define_expand "fix_truncdfsi2"
- [(set (match_operand:SI 0 "register_operand" "=f")
- (fix:SI (match_operand:DF 1 "register_operand" "f")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (fix:SI (match_operand:DF 1 "register_operand")))]
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
{
if (!ISA_HAS_TRUNC_W)
@@ -3845,8 +3914,8 @@ dsrl\t%3,%3,1\n\
(set_attr "length" "36")])
(define_expand "fix_truncsfsi2"
- [(set (match_operand:SI 0 "register_operand" "=f")
- (fix:SI (match_operand:SF 1 "register_operand" "f")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (fix:SI (match_operand:SF 1 "register_operand")))]
"TARGET_HARD_FLOAT"
{
if (!ISA_HAS_TRUNC_W)
@@ -3942,8 +4011,8 @@ dsrl\t%3,%3,1\n\
(define_expand "fixuns_truncdfsi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (unsigned_fix:SI (match_operand:DF 1 "register_operand")))]
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
{
rtx reg1 = gen_reg_rtx (DFmode);
@@ -3987,8 +4056,8 @@ dsrl\t%3,%3,1\n\
(define_expand "fixuns_truncdfdi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
"TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
{
rtx reg1 = gen_reg_rtx (DFmode);
@@ -4029,8 +4098,8 @@ dsrl\t%3,%3,1\n\
(define_expand "fixuns_truncsfsi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (unsigned_fix:SI (match_operand:SF 1 "register_operand")))]
"TARGET_HARD_FLOAT"
{
rtx reg1 = gen_reg_rtx (SFmode);
@@ -4071,8 +4140,8 @@ dsrl\t%3,%3,1\n\
(define_expand "fixuns_truncsfdi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
"TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT"
{
rtx reg1 = gen_reg_rtx (SFmode);
@@ -4121,10 +4190,10 @@ dsrl\t%3,%3,1\n\
;; Bit field extract patterns which use lwl/lwr or ldl/ldr.
(define_expand "extv"
- [(set (match_operand 0 "register_operand" "")
- (sign_extract (match_operand:QI 1 "memory_operand" "")
- (match_operand 2 "immediate_operand" "")
- (match_operand 3 "immediate_operand" "")))]
+ [(set (match_operand 0 "register_operand")
+ (sign_extract (match_operand:QI 1 "memory_operand")
+ (match_operand 2 "immediate_operand")
+ (match_operand 3 "immediate_operand")))]
"!TARGET_MIPS16"
{
if (mips_expand_unaligned_load (operands[0], operands[1],
@@ -4136,10 +4205,10 @@ dsrl\t%3,%3,1\n\
})
(define_expand "extzv"
- [(set (match_operand 0 "register_operand" "")
- (zero_extract (match_operand:QI 1 "memory_operand" "")
- (match_operand 2 "immediate_operand" "")
- (match_operand 3 "immediate_operand" "")))]
+ [(set (match_operand 0 "register_operand")
+ (zero_extract (match_operand:QI 1 "memory_operand")
+ (match_operand 2 "immediate_operand")
+ (match_operand 3 "immediate_operand")))]
"!TARGET_MIPS16"
{
if (mips_expand_unaligned_load (operands[0], operands[1],
@@ -4151,10 +4220,10 @@ dsrl\t%3,%3,1\n\
})
(define_expand "insv"
- [(set (zero_extract (match_operand:QI 0 "memory_operand" "")
- (match_operand 1 "immediate_operand" "")
- (match_operand 2 "immediate_operand" ""))
- (match_operand 3 "reg_or_0_operand" ""))]
+ [(set (zero_extract (match_operand:QI 0 "memory_operand")
+ (match_operand 1 "immediate_operand")
+ (match_operand 2 "immediate_operand"))
+ (match_operand 3 "reg_or_0_operand"))]
"!TARGET_MIPS16"
{
if (mips_expand_unaligned_store (operands[0], operands[3],
@@ -4513,29 +4582,12 @@ dsrl\t%3,%3,1\n\
;; the compiler, have memoized the insn number already.
(define_expand "movdi"
- [(set (match_operand:DI 0 "" "")
- (match_operand:DI 1 "" ""))]
+ [(set (match_operand:DI 0 "")
+ (match_operand:DI 1 ""))]
""
{
if (mips_legitimize_move (DImode, operands[0], operands[1]))
DONE;
-
- /* If we are generating embedded PIC code, and we are referring to a
- symbol in the .text section, we must use an offset from the start
- of the function. */
- if (TARGET_EMBEDDED_PIC
- && (GET_CODE (operands[1]) == LABEL_REF
- || (GET_CODE (operands[1]) == SYMBOL_REF
- && ! SYMBOL_REF_FLAG (operands[1]))))
- {
- rtx temp;
-
- temp = embedded_pic_offset (operands[1]);
- temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_reg (),
- force_reg (DImode, temp));
- emit_move_insn (operands[0], force_reg (DImode, temp));
- DONE;
- }
})
;; For mips16, we need a special case to handle storing $31 into
@@ -4551,15 +4603,15 @@ dsrl\t%3,%3,1\n\
(set_attr "mode" "DI")])
(define_insn "*movdi_32bit"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*x,*B*C*D,*B*C*D,*d,*m")
- (match_operand:DI 1 "move_operand" "d,i,m,d,J,*x,*d,*d,*m,*B*C*D,*B*C*D"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*B*C*D,*B*C*D,*d,*m")
+ (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*x,*d,*m,*B*C*D,*B*C*D"))]
"!TARGET_64BIT && !TARGET_MIPS16
&& (register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))"
{ return mips_output_move (operands[0], operands[1]); }
- [(set_attr "type" "arith,arith,load,store,mthilo,mfhilo,mthilo,xfer,load,xfer,store")
+ [(set_attr "type" "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store")
(set_attr "mode" "DI")
- (set_attr "length" "8,16,*,*,8,8,8,8,*,8,*")])
+ (set_attr "length" "8,16,*,*,8,8,8,*,8,*")])
(define_insn "*movdi_32bit_mips16"
[(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
@@ -4573,39 +4625,38 @@ dsrl\t%3,%3,1\n\
(set_attr "length" "8,8,8,8,12,*,*,8")])
(define_insn "*movdi_64bit"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*x,*d,*x,*B*C*D,*B*C*D,*d,*m")
- (match_operand:DI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*J,*x,*d,*d,*m,*B*C*D,*B*C*D"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*x,*B*C*D,*B*C*D,*d,*m")
+ (match_operand:DI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*J*d,*d,*m,*B*C*D,*B*C*D"))]
"TARGET_64BIT && !TARGET_MIPS16
&& (register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))"
{ return mips_output_move (operands[0], operands[1]); }
- [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,mfhilo,mthilo,xfer,load,xfer,store")
+ [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store")
(set_attr "mode" "DI")
- (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,8,*,8,*")])
+ (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")])
(define_insn "*movdi_64bit_mips16"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m,*d")
- (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d,*x"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
+ (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
"TARGET_64BIT && TARGET_MIPS16
&& (register_operand (operands[0], DImode)
|| register_operand (operands[1], DImode))"
{ return mips_output_move (operands[0], operands[1]); }
- [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store,mfhilo")
+ [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
(set_attr "mode" "DI")
(set_attr_alternative "length"
[(const_int 4)
(const_int 4)
(const_int 4)
- (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
+ (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
(const_int 4)
(const_int 8))
- (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
+ (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
(const_int 8)
(const_int 12))
(const_string "*")
(const_string "*")
- (const_string "*")
- (const_int 4)])])
+ (const_string "*")])])
;; On the mips16, we can split ld $r,N($r) into an add and a load,
@@ -4613,9 +4664,9 @@ dsrl\t%3,%3,1\n\
;; load are 2 2 byte instructions.
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(mem:DI (plus:DI (match_dup 0)
- (match_operand:DI 1 "const_int_operand" ""))))]
+ (match_operand:DI 1 "const_int_operand"))))]
"TARGET_64BIT && TARGET_MIPS16 && reload_completed
&& !TARGET_DEBUG_D_MODE
&& GET_CODE (operands[0]) == REG
@@ -4658,29 +4709,12 @@ dsrl\t%3,%3,1\n\
;; the compiler, have memoized the insn number already.
(define_expand "movsi"
- [(set (match_operand:SI 0 "" "")
- (match_operand:SI 1 "" ""))]
+ [(set (match_operand:SI 0 "")
+ (match_operand:SI 1 ""))]
""
{
if (mips_legitimize_move (SImode, operands[0], operands[1]))
DONE;
-
- /* If we are generating embedded PIC code, and we are referring to a
- symbol in the .text section, we must use an offset from the start
- of the function. */
- if (TARGET_EMBEDDED_PIC
- && (GET_CODE (operands[1]) == LABEL_REF
- || (GET_CODE (operands[1]) == SYMBOL_REF
- && ! SYMBOL_REF_FLAG (operands[1]))))
- {
- rtx temp;
-
- temp = embedded_pic_offset (operands[1]);
- temp = gen_rtx_PLUS (Pmode, embedded_pic_fnaddr_reg (),
- force_reg (SImode, temp));
- emit_move_insn (operands[0], force_reg (SImode, temp));
- DONE;
- }
})
;; We can only store $ra directly into a small sp offset.
@@ -4697,48 +4731,47 @@ dsrl\t%3,%3,1\n\
;; in FP registers (off by default, use -mdebugh to enable).
(define_insn "*movsi_internal"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*x,*d,*x,*B*C*D,*B*C*D,*d,*m")
- (match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,J,*x,*d,*d,*m,*B*C*D,*B*C*D"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*x,*B*C*D,*B*C*D,*d,*m")
+ (match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,*J*d,*d,*m,*B*C*D,*B*C*D"))]
"!TARGET_MIPS16
&& (register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))"
{ return mips_output_move (operands[0], operands[1]); }
- [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,mfhilo,mthilo,xfer,load,xfer,store")
+ [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,xfer,load,xfer,store")
(set_attr "mode" "SI")
- (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,4,*,4,*")])
+ (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,*,4,*")])
(define_insn "*movsi_mips16"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m,*d")
- (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d,*x"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
+ (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))]
"TARGET_MIPS16
&& (register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode))"
{ return mips_output_move (operands[0], operands[1]); }
- [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store,mfhilo")
+ [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store")
(set_attr "mode" "SI")
(set_attr_alternative "length"
[(const_int 4)
(const_int 4)
(const_int 4)
- (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
+ (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
(const_int 4)
(const_int 8))
- (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
+ (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
(const_int 8)
(const_int 12))
(const_string "*")
(const_string "*")
- (const_string "*")
- (const_int 4)])])
+ (const_string "*")])])
;; On the mips16, we can split lw $r,N($r) into an add and a load,
;; when the original load is a 4 byte instruction but the add and the
;; load are 2 2 byte instructions.
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
+ [(set (match_operand:SI 0 "register_operand")
(mem:SI (plus:SI (match_dup 0)
- (match_operand:SI 1 "const_int_operand" ""))))]
+ (match_operand:SI 1 "const_int_operand"))))]
"TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
&& GET_CODE (operands[0]) == REG
&& M16_REG_P (REGNO (operands[0]))
@@ -4778,8 +4811,8 @@ dsrl\t%3,%3,1\n\
;; instructions.
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "const_int_operand" ""))]
+ [(set (match_operand:SI 0 "register_operand")
+ (match_operand:SI 1 "const_int_operand"))]
"TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
&& GET_CODE (operands[0]) == REG
&& M16_REG_P (REGNO (operands[0]))
@@ -4799,8 +4832,8 @@ dsrl\t%3,%3,1\n\
;; load and a neg. That's what mips_output_move will generate anyhow.
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "const_int_operand" ""))]
+ [(set (match_operand:SI 0 "register_operand")
+ (match_operand:SI 1 "const_int_operand"))]
"TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
&& GET_CODE (operands[0]) == REG
&& M16_REG_P (REGNO (operands[0]))
@@ -4960,8 +4993,8 @@ dsrl\t%3,%3,1\n\
;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
(define_expand "movhi"
- [(set (match_operand:HI 0 "" "")
- (match_operand:HI 1 "" ""))]
+ [(set (match_operand:HI 0 "")
+ (match_operand:HI 1 ""))]
""
{
if (mips_legitimize_move (HImode, operands[0], operands[1]))
@@ -4969,8 +5002,8 @@ dsrl\t%3,%3,1\n\
})
(define_insn "*movhi_internal"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x,*d")
- (match_operand:HI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d,*x"))]
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
+ (match_operand:HI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
"!TARGET_MIPS16
&& (register_operand (operands[0], HImode)
|| reg_or_0_operand (operands[1], HImode))"
@@ -4982,15 +5015,14 @@ dsrl\t%3,%3,1\n\
mfc1\t%0,%1
mtc1\t%1,%0
mov.s\t%0,%1
- mt%0\t%1
- mf%1\t%0"
- [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo,mfhilo")
+ mt%0\t%1"
+ [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
(set_attr "mode" "HI")
- (set_attr "length" "4,4,*,*,4,4,4,4,4")])
+ (set_attr "length" "4,4,*,*,4,4,4,4")])
(define_insn "*movhi_mips16"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
- (match_operand:HI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
+ (match_operand:HI 1 "move_operand" "d,d,y,K,N,m,d"))]
"TARGET_MIPS16
&& (register_operand (operands[0], HImode)
|| register_operand (operands[1], HImode))"
@@ -5001,23 +5033,21 @@ dsrl\t%3,%3,1\n\
li\t%0,%1
li\t%0,%n1\;neg\t%0
lhu\t%0,%1
- sh\t%1,%0
- mf%1\t%0"
- [(set_attr "type" "arith,arith,arith,arith,arith,load,store,mfhilo")
+ sh\t%1,%0"
+ [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
(set_attr "mode" "HI")
(set_attr_alternative "length"
[(const_int 4)
(const_int 4)
(const_int 4)
- (if_then_else (match_operand:VOID 1 "m16_uimm8_1" "")
+ (if_then_else (match_operand:VOID 1 "m16_uimm8_1")
(const_int 4)
(const_int 8))
- (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
+ (if_then_else (match_operand:VOID 1 "m16_nuimm8_1")
(const_int 8)
(const_int 12))
(const_string "*")
- (const_string "*")
- (const_int 4)])])
+ (const_string "*")])])
;; On the mips16, we can split lh $r,N($r) into an add and a load,
@@ -5025,9 +5055,9 @@ dsrl\t%3,%3,1\n\
;; load are 2 2 byte instructions.
(define_split
- [(set (match_operand:HI 0 "register_operand" "")
+ [(set (match_operand:HI 0 "register_operand")
(mem:HI (plus:SI (match_dup 0)
- (match_operand:SI 1 "const_int_operand" ""))))]
+ (match_operand:SI 1 "const_int_operand"))))]
"TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
&& GET_CODE (operands[0]) == REG
&& M16_REG_P (REGNO (operands[0]))
@@ -5070,8 +5100,8 @@ dsrl\t%3,%3,1\n\
;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND.
(define_expand "movqi"
- [(set (match_operand:QI 0 "" "")
- (match_operand:QI 1 "" ""))]
+ [(set (match_operand:QI 0 "")
+ (match_operand:QI 1 ""))]
""
{
if (mips_legitimize_move (QImode, operands[0], operands[1]))
@@ -5079,8 +5109,8 @@ dsrl\t%3,%3,1\n\
})
(define_insn "*movqi_internal"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x,*d")
- (match_operand:QI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d,*x"))]
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x")
+ (match_operand:QI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))]
"!TARGET_MIPS16
&& (register_operand (operands[0], QImode)
|| reg_or_0_operand (operands[1], QImode))"
@@ -5092,15 +5122,14 @@ dsrl\t%3,%3,1\n\
mfc1\t%0,%1
mtc1\t%1,%0
mov.s\t%0,%1
- mt%0\t%1
- mf%1\t%0"
- [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo,mfhilo")
+ mt%0\t%1"
+ [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo")
(set_attr "mode" "QI")
- (set_attr "length" "4,4,*,*,4,4,4,4,4")])
+ (set_attr "length" "4,4,*,*,4,4,4,4")])
(define_insn "*movqi_mips16"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
- (match_operand:QI 1 "move_operand" "d,d,y,K,N,m,d,*x"))]
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m")
+ (match_operand:QI 1 "move_operand" "d,d,y,K,N,m,d"))]
"TARGET_MIPS16
&& (register_operand (operands[0], QImode)
|| register_operand (operands[1], QImode))"
@@ -5111,20 +5140,19 @@ dsrl\t%3,%3,1\n\
li\t%0,%1
li\t%0,%n1\;neg\t%0
lbu\t%0,%1
- sb\t%1,%0
- mf%1\t%0"
- [(set_attr "type" "arith,arith,arith,arith,arith,load,store,mfhilo")
+ sb\t%1,%0"
+ [(set_attr "type" "arith,arith,arith,arith,arith,load,store")
(set_attr "mode" "QI")
- (set_attr "length" "4,4,4,4,8,*,*,4")])
+ (set_attr "length" "4,4,4,4,8,*,*")])
;; On the mips16, we can split lb $r,N($r) into an add and a load,
;; when the original load is a 4 byte instruction but the add and the
;; load are 2 2 byte instructions.
(define_split
- [(set (match_operand:QI 0 "register_operand" "")
+ [(set (match_operand:QI 0 "register_operand")
(mem:QI (plus:SI (match_dup 0)
- (match_operand:SI 1 "const_int_operand" ""))))]
+ (match_operand:SI 1 "const_int_operand"))))]
"TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
&& GET_CODE (operands[0]) == REG
&& M16_REG_P (REGNO (operands[0]))
@@ -5150,8 +5178,8 @@ dsrl\t%3,%3,1\n\
;; 32-bit floating point moves
(define_expand "movsf"
- [(set (match_operand:SF 0 "" "")
- (match_operand:SF 1 "" ""))]
+ [(set (match_operand:SF 0 "")
+ (match_operand:SF 1 ""))]
""
{
if (mips_legitimize_move (SFmode, operands[0], operands[1]))
@@ -5195,8 +5223,8 @@ dsrl\t%3,%3,1\n\
;; 64-bit floating point moves
(define_expand "movdf"
- [(set (match_operand:DF 0 "" "")
- (match_operand:DF 1 "" ""))]
+ [(set (match_operand:DF 0 "")
+ (match_operand:DF 1 ""))]
""
{
if (mips_legitimize_move (DFmode, operands[0], operands[1]))
@@ -5248,8 +5276,8 @@ dsrl\t%3,%3,1\n\
(set_attr "length" "8,8,8,*,*")])
(define_split
- [(set (match_operand:DI 0 "nonimmediate_operand" "")
- (match_operand:DI 1 "move_operand" ""))]
+ [(set (match_operand:DI 0 "nonimmediate_operand")
+ (match_operand:DI 1 "move_operand"))]
"reload_completed && !TARGET_64BIT
&& mips_split_64bit_move_p (operands[0], operands[1])"
[(const_int 0)]
@@ -5259,8 +5287,8 @@ dsrl\t%3,%3,1\n\
})
(define_split
- [(set (match_operand:DF 0 "nonimmediate_operand" "")
- (match_operand:DF 1 "move_operand" ""))]
+ [(set (match_operand:DF 0 "nonimmediate_operand")
+ (match_operand:DF 1 "move_operand"))]
"reload_completed && !TARGET_64BIT
&& mips_split_64bit_move_p (operands[0], operands[1])"
[(const_int 0)]
@@ -5269,6 +5297,31 @@ dsrl\t%3,%3,1\n\
DONE;
})
+;; The HI and LO registers are not truly independent. If we move an mthi
+;; instruction before an mflo instruction, it will make the result of the
+;; mflo unpredictable. The same goes for mtlo and mfhi.
+;;
+;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
+;; Operand 1 is the register we want, operand 2 is the other one.
+
+(define_insn "mfhilo_di"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "h,l")
+ (match_operand:DI 2 "register_operand" "l,h")]
+ UNSPEC_MFHILO))]
+ "TARGET_64BIT"
+ "mf%1\t%0"
+ [(set_attr "type" "mfhilo")])
+
+(define_insn "mfhilo_si"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "h,l")
+ (match_operand:SI 2 "register_operand" "l,h")]
+ UNSPEC_MFHILO))]
+ ""
+ "mf%1\t%0"
+ [(set_attr "type" "mfhilo")])
+
;; Patterns for loading or storing part of a paired floating point
;; register. We need them because odd-numbered floating-point registers
;; are not fully independent: see mips_split_64bit_move.
@@ -5284,8 +5337,7 @@ dsrl\t%3,%3,1\n\
return mips_output_move (operands[0], operands[1]);
}
[(set_attr "type" "xfer,fpload")
- (set_attr "mode" "SF")
- (set_attr "length" "4")])
+ (set_attr "mode" "SF")])
;; Load the high word of operand 0 from operand 1, preserving the value
;; in the low word.
@@ -5300,8 +5352,7 @@ dsrl\t%3,%3,1\n\
return mips_output_move (operands[0], operands[1]);
}
[(set_attr "type" "xfer,fpload")
- (set_attr "mode" "SF")
- (set_attr "length" "4")])
+ (set_attr "mode" "SF")])
;; Store the high word of operand 1 in operand 0. The corresponding
;; low-word move is done in the normal way.
@@ -5315,8 +5366,7 @@ dsrl\t%3,%3,1\n\
return mips_output_move (operands[0], operands[1]);
}
[(set_attr "type" "xfer,fpstore")
- (set_attr "mode" "SF")
- (set_attr "length" "4")])
+ (set_attr "mode" "SF")])
;; Insn to initialize $gp for n32/n64 abicalls. Operand 0 is the offset
;; of _gp from the start of this function. Operand 1 is the incoming
@@ -5368,10 +5418,10 @@ dsrl\t%3,%3,1\n\
;; Argument 3 is the alignment
(define_expand "movstrsi"
- [(parallel [(set (match_operand:BLK 0 "general_operand" "")
- (match_operand:BLK 1 "general_operand" ""))
- (use (match_operand:SI 2 "" ""))
- (use (match_operand:SI 3 "const_int_operand" ""))])]
+ [(parallel [(set (match_operand:BLK 0 "general_operand")
+ (match_operand:BLK 1 "general_operand"))
+ (use (match_operand:SI 2 ""))
+ (use (match_operand:SI 3 "const_int_operand"))])]
"!TARGET_MIPS16 && !TARGET_MEMCPY"
{
if (mips_expand_block_move (operands[0], operands[1], operands[2]))
@@ -5391,9 +5441,9 @@ dsrl\t%3,%3,1\n\
;; want to use a different set of constraints when TARGET_MIPS16.
(define_expand "ashlsi3"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (ashift:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "arith_operand" "dI")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (ashift:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "arith_operand")))]
""
{
/* On the mips16, a shift of more than 8 is a four byte instruction,
@@ -5467,16 +5517,16 @@ dsrl\t%3,%3,1\n\
(set_attr "mode" "SI")
(set_attr_alternative "length"
[(const_int 4)
- (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
+ (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
(const_int 4)
(const_int 8))])])
;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (ashift:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "const_int_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (ashift:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "const_int_operand")))]
"TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
&& GET_CODE (operands[2]) == CONST_INT
&& INTVAL (operands[2]) > 8
@@ -5486,9 +5536,9 @@ dsrl\t%3,%3,1\n\
{ operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
(define_expand "ashldi3"
- [(parallel [(set (match_operand:DI 0 "register_operand" "")
- (ashift:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "arith_operand" "")))
+ [(parallel [(set (match_operand:DI 0 "register_operand")
+ (ashift:DI (match_operand:DI 1 "register_operand")
+ (match_operand:SI 2 "arith_operand")))
(clobber (match_dup 3))])]
"TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
{
@@ -5570,10 +5620,10 @@ sll\t%L0,%L1,%2\n\
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (ashift:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "small_int" "")))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (ashift:DI (match_operand:DI 1 "register_operand")
+ (match_operand:SI 2 "small_int")))
+ (clobber (match_operand:SI 3 "register_operand"))]
"reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
&& !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
&& GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
@@ -5587,10 +5637,10 @@ sll\t%L0,%L1,%2\n\
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (ashift:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "small_int" "")))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (ashift:DI (match_operand:DI 1 "register_operand")
+ (match_operand:SI 2 "small_int")))
+ (clobber (match_operand:SI 3 "register_operand"))]
"reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
&& !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
&& GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
@@ -5625,10 +5675,10 @@ sll\t%L0,%L1,%2\n\
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (ashift:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "small_int" "")))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (ashift:DI (match_operand:DI 1 "register_operand")
+ (match_operand:SI 2 "small_int")))
+ (clobber (match_operand:SI 3 "register_operand"))]
"reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
&& !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
&& GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
@@ -5659,10 +5709,10 @@ sll\t%L0,%L1,%2\n\
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (ashift:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "small_int" "")))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (ashift:DI (match_operand:DI 1 "register_operand")
+ (match_operand:SI 2 "small_int")))
+ (clobber (match_operand:SI 3 "register_operand"))]
"reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
&& !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
&& GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
@@ -5724,7 +5774,7 @@ sll\t%L0,%L1,%2\n\
(set_attr "mode" "DI")
(set_attr_alternative "length"
[(const_int 4)
- (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
+ (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
(const_int 4)
(const_int 8))])])
@@ -5732,9 +5782,9 @@ sll\t%L0,%L1,%2\n\
;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (ashift:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "const_int_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (ashift:DI (match_operand:DI 1 "register_operand")
+ (match_operand:SI 2 "const_int_operand")))]
"TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
&& reload_completed
&& GET_CODE (operands[2]) == CONST_INT
@@ -5745,9 +5795,9 @@ sll\t%L0,%L1,%2\n\
{ operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
(define_expand "ashrsi3"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "arith_operand" "dI")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (ashiftrt:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "arith_operand")))]
""
{
/* On the mips16, a shift of more than 8 is a four byte instruction,
@@ -5802,7 +5852,7 @@ sll\t%L0,%L1,%2\n\
(set_attr "mode" "SI")
(set_attr_alternative "length"
[(const_int 4)
- (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
+ (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
(const_int 4)
(const_int 8))])])
@@ -5810,9 +5860,9 @@ sll\t%L0,%L1,%2\n\
;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "const_int_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (ashiftrt:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "const_int_operand")))]
"TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
&& GET_CODE (operands[2]) == CONST_INT
&& INTVAL (operands[2]) > 8
@@ -5822,9 +5872,9 @@ sll\t%L0,%L1,%2\n\
{ operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
(define_expand "ashrdi3"
- [(parallel [(set (match_operand:DI 0 "register_operand" "")
- (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "arith_operand" "")))
+ [(parallel [(set (match_operand:DI 0 "register_operand")
+ (ashiftrt:DI (match_operand:DI 1 "register_operand")
+ (match_operand:SI 2 "arith_operand")))
(clobber (match_dup 3))])]
"TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
{
@@ -5901,10 +5951,10 @@ sra\t%M0,%M1,%2\n\
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "small_int" "")))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (ashiftrt:DI (match_operand:DI 1 "register_operand")
+ (match_operand:SI 2 "small_int")))
+ (clobber (match_operand:SI 3 "register_operand"))]
"reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
&& !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
&& GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
@@ -5918,10 +5968,10 @@ sra\t%M0,%M1,%2\n\
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "small_int" "")))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (ashiftrt:DI (match_operand:DI 1 "register_operand")
+ (match_operand:SI 2 "small_int")))
+ (clobber (match_operand:SI 3 "register_operand"))]
"reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
&& !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE
&& GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
@@ -5956,10 +6006,10 @@ sra\t%M0,%M1,%2\n\
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "small_int" "")))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (ashiftrt:DI (match_operand:DI 1 "register_operand")
+ (match_operand:SI 2 "small_int")))
+ (clobber (match_operand:SI 3 "register_operand"))]
"reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
&& !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
&& GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
@@ -5990,10 +6040,10 @@ sra\t%M0,%M1,%2\n\
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "small_int" "")))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (ashiftrt:DI (match_operand:DI 1 "register_operand")
+ (match_operand:SI 2 "small_int")))
+ (clobber (match_operand:SI 3 "register_operand"))]
"reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
&& !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
&& GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
@@ -6052,16 +6102,16 @@ sra\t%M0,%M1,%2\n\
(set_attr "mode" "DI")
(set_attr_alternative "length"
[(const_int 4)
- (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
+ (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
(const_int 4)
(const_int 8))])])
;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "const_int_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (ashiftrt:DI (match_operand:DI 1 "register_operand")
+ (match_operand:SI 2 "const_int_operand")))]
"TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
&& reload_completed
&& GET_CODE (operands[2]) == CONST_INT
@@ -6072,9 +6122,9 @@ sra\t%M0,%M1,%2\n\
{ operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
(define_expand "lshrsi3"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "arith_operand" "dI")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (lshiftrt:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "arith_operand")))]
""
{
/* On the mips16, a shift of more than 8 is a four byte instruction,
@@ -6129,7 +6179,7 @@ sra\t%M0,%M1,%2\n\
(set_attr "mode" "SI")
(set_attr_alternative "length"
[(const_int 4)
- (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
+ (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
(const_int 4)
(const_int 8))])])
@@ -6137,9 +6187,9 @@ sra\t%M0,%M1,%2\n\
;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "const_int_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (lshiftrt:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "const_int_operand")))]
"TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
&& GET_CODE (operands[2]) == CONST_INT
&& INTVAL (operands[2]) > 8
@@ -6156,7 +6206,7 @@ sra\t%M0,%M1,%2\n\
;; to make it simple enough for combine to understand.
;;
;; The length here is the worst case: the length of the split version
-;; will be more accurate.
+;; will be more accurate.
(define_insn_and_split ""
[(set (match_operand:SI 0 "register_operand" "=d")
(lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
@@ -6172,9 +6222,9 @@ sra\t%M0,%M1,%2\n\
(set_attr "length" "16")])
(define_expand "lshrdi3"
- [(parallel [(set (match_operand:DI 0 "register_operand" "")
- (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "arith_operand" "")))
+ [(parallel [(set (match_operand:DI 0 "register_operand")
+ (lshiftrt:DI (match_operand:DI 1 "register_operand")
+ (match_operand:SI 2 "arith_operand")))
(clobber (match_dup 3))])]
"TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)"
{
@@ -6252,10 +6302,10 @@ srl\t%M0,%M1,%2\n\
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "small_int" "")))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (lshiftrt:DI (match_operand:DI 1 "register_operand")
+ (match_operand:SI 2 "small_int")))
+ (clobber (match_operand:SI 3 "register_operand"))]
"reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
&& !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
&& GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
@@ -6269,10 +6319,10 @@ srl\t%M0,%M1,%2\n\
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "small_int" "")))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (lshiftrt:DI (match_operand:DI 1 "register_operand")
+ (match_operand:SI 2 "small_int")))
+ (clobber (match_operand:SI 3 "register_operand"))]
"reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
&& !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
&& GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
@@ -6307,10 +6357,10 @@ srl\t%M0,%M1,%2\n\
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "small_int" "")))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (lshiftrt:DI (match_operand:DI 1 "register_operand")
+ (match_operand:SI 2 "small_int")))
+ (clobber (match_operand:SI 3 "register_operand"))]
"reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT
&& !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
&& GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
@@ -6341,10 +6391,10 @@ srl\t%M0,%M1,%2\n\
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "small_int" "")))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (lshiftrt:DI (match_operand:DI 1 "register_operand")
+ (match_operand:SI 2 "small_int")))
+ (clobber (match_operand:SI 3 "register_operand"))]
"reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT
&& !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
&& GET_CODE (operands[0]) == REG && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
@@ -6403,7 +6453,7 @@ srl\t%M0,%M1,%2\n\
(set_attr "mode" "DI")
(set_attr_alternative "length"
[(const_int 4)
- (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
+ (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
(const_int 4)
(const_int 8))])])
@@ -6453,9 +6503,9 @@ srl\t%M0,%M1,%2\n\
;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "const_int_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (lshiftrt:DI (match_operand:DI 1 "register_operand")
+ (match_operand:SI 2 "const_int_operand")))]
"TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
&& GET_CODE (operands[2]) == CONST_INT
&& INTVAL (operands[2]) > 8
@@ -6489,8 +6539,8 @@ srl\t%M0,%M1,%2\n\
(define_expand "cmpsi"
[(set (cc0)
- (compare:CC (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "arith_operand" "")))]
+ (compare:CC (match_operand:SI 0 "register_operand")
+ (match_operand:SI 1 "arith_operand")))]
""
{
branch_cmp[0] = operands[0];
@@ -6501,8 +6551,8 @@ srl\t%M0,%M1,%2\n\
(define_expand "cmpdi"
[(set (cc0)
- (compare:CC (match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "arith_operand" "")))]
+ (compare:CC (match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "arith_operand")))]
"TARGET_64BIT"
{
branch_cmp[0] = operands[0];
@@ -6513,8 +6563,8 @@ srl\t%M0,%M1,%2\n\
(define_expand "cmpdf"
[(set (cc0)
- (compare:CC (match_operand:DF 0 "register_operand" "")
- (match_operand:DF 1 "register_operand" "")))]
+ (compare:CC (match_operand:DF 0 "register_operand")
+ (match_operand:DF 1 "register_operand")))]
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
{
branch_cmp[0] = operands[0];
@@ -6525,8 +6575,8 @@ srl\t%M0,%M1,%2\n\
(define_expand "cmpsf"
[(set (cc0)
- (compare:CC (match_operand:SF 0 "register_operand" "")
- (match_operand:SF 1 "register_operand" "")))]
+ (compare:CC (match_operand:SF 0 "register_operand")
+ (match_operand:SF 1 "register_operand")))]
"TARGET_HARD_FLOAT"
{
branch_cmp[0] = operands[0];
@@ -6810,7 +6860,7 @@ srl\t%M0,%M1,%2\n\
[(set (pc)
(if_then_else (unordered:CC (cc0)
(const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0 ""))
(pc)))]
""
{
@@ -6822,7 +6872,7 @@ srl\t%M0,%M1,%2\n\
[(set (pc)
(if_then_else (ordered:CC (cc0)
(const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0 ""))
(pc)))]
""
{
@@ -6834,7 +6884,7 @@ srl\t%M0,%M1,%2\n\
[(set (pc)
(if_then_else (unlt:CC (cc0)
(const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0 ""))
(pc)))]
""
{
@@ -6846,7 +6896,7 @@ srl\t%M0,%M1,%2\n\
[(set (pc)
(if_then_else (unge:CC (cc0)
(const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0 ""))
(pc)))]
""
{
@@ -6858,7 +6908,7 @@ srl\t%M0,%M1,%2\n\
[(set (pc)
(if_then_else (uneq:CC (cc0)
(const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0 ""))
(pc)))]
""
{
@@ -6870,7 +6920,7 @@ srl\t%M0,%M1,%2\n\
[(set (pc)
(if_then_else (ltgt:CC (cc0)
(const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0 ""))
(pc)))]
""
{
@@ -6882,7 +6932,7 @@ srl\t%M0,%M1,%2\n\
[(set (pc)
(if_then_else (unle:CC (cc0)
(const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0 ""))
(pc)))]
""
{
@@ -6894,7 +6944,7 @@ srl\t%M0,%M1,%2\n\
[(set (pc)
(if_then_else (ungt:CC (cc0)
(const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0 ""))
(pc)))]
""
{
@@ -6906,7 +6956,7 @@ srl\t%M0,%M1,%2\n\
[(set (pc)
(if_then_else (eq:CC (cc0)
(const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0 ""))
(pc)))]
""
{
@@ -6918,7 +6968,7 @@ srl\t%M0,%M1,%2\n\
[(set (pc)
(if_then_else (ne:CC (cc0)
(const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0 ""))
(pc)))]
""
{
@@ -6930,7 +6980,7 @@ srl\t%M0,%M1,%2\n\
[(set (pc)
(if_then_else (gt:CC (cc0)
(const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0 ""))
(pc)))]
""
{
@@ -6942,7 +6992,7 @@ srl\t%M0,%M1,%2\n\
[(set (pc)
(if_then_else (ge:CC (cc0)
(const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0 ""))
(pc)))]
""
{
@@ -6954,7 +7004,7 @@ srl\t%M0,%M1,%2\n\
[(set (pc)
(if_then_else (lt:CC (cc0)
(const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0 ""))
(pc)))]
""
{
@@ -6966,7 +7016,7 @@ srl\t%M0,%M1,%2\n\
[(set (pc)
(if_then_else (le:CC (cc0)
(const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0 ""))
(pc)))]
""
{
@@ -6978,7 +7028,7 @@ srl\t%M0,%M1,%2\n\
[(set (pc)
(if_then_else (gtu:CC (cc0)
(const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0 ""))
(pc)))]
""
{
@@ -6990,7 +7040,7 @@ srl\t%M0,%M1,%2\n\
[(set (pc)
(if_then_else (geu:CC (cc0)
(const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0 ""))
(pc)))]
""
{
@@ -7002,7 +7052,7 @@ srl\t%M0,%M1,%2\n\
[(set (pc)
(if_then_else (ltu:CC (cc0)
(const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0 ""))
(pc)))]
""
{
@@ -7014,7 +7064,7 @@ srl\t%M0,%M1,%2\n\
[(set (pc)
(if_then_else (leu:CC (cc0)
(const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0 ""))
(pc)))]
""
{
@@ -7030,7 +7080,7 @@ srl\t%M0,%M1,%2\n\
;; ....................
(define_expand "seq"
- [(set (match_operand:SI 0 "register_operand" "=d")
+ [(set (match_operand:SI 0 "register_operand")
(eq:SI (match_dup 1)
(match_dup 2)))]
""
@@ -7104,9 +7154,9 @@ srl\t%M0,%M1,%2\n\
(set_attr "length" "8")])
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (eq:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "uns_arith_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (eq:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "uns_arith_operand")))]
"TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
&& (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
[(set (match_dup 0)
@@ -7130,9 +7180,9 @@ srl\t%M0,%M1,%2\n\
(set_attr "length" "8")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (eq:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "uns_arith_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (eq:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "uns_arith_operand")))]
"TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
&& !TARGET_MIPS16
&& (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
@@ -7147,7 +7197,7 @@ srl\t%M0,%M1,%2\n\
;; On the mips16 the default code is better than using sltu.
(define_expand "sne"
- [(set (match_operand:SI 0 "register_operand" "=d")
+ [(set (match_operand:SI 0 "register_operand")
(ne:SI (match_dup 1)
(match_dup 2)))]
"!TARGET_MIPS16"
@@ -7202,9 +7252,9 @@ srl\t%M0,%M1,%2\n\
(set_attr "length" "8")])
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (ne:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "uns_arith_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (ne:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "uns_arith_operand")))]
"TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16
&& (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
[(set (match_dup 0)
@@ -7228,9 +7278,9 @@ srl\t%M0,%M1,%2\n\
(set_attr "length" "8")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (ne:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "uns_arith_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (ne:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "uns_arith_operand")))]
"TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
&& !TARGET_MIPS16
&& (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
@@ -7243,7 +7293,7 @@ srl\t%M0,%M1,%2\n\
"")
(define_expand "sgt"
- [(set (match_operand:SI 0 "register_operand" "=d")
+ [(set (match_operand:SI 0 "register_operand")
(gt:SI (match_dup 1)
(match_dup 2)))]
""
@@ -7304,7 +7354,7 @@ srl\t%M0,%M1,%2\n\
(set_attr "mode" "DI")])
(define_expand "sge"
- [(set (match_operand:SI 0 "register_operand" "=d")
+ [(set (match_operand:SI 0 "register_operand")
(ge:SI (match_dup 1)
(match_dup 2)))]
""
@@ -7336,9 +7386,9 @@ srl\t%M0,%M1,%2\n\
(set_attr "length" "8")])
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (ge:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "arith_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (ge:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "arith_operand")))]
"TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
[(set (match_dup 0)
(lt:SI (match_dup 1)
@@ -7359,9 +7409,9 @@ srl\t%M0,%M1,%2\n\
(set_attr "length" "8")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (ge:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "arith_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (ge:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "arith_operand")))]
"TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
&& !TARGET_MIPS16"
[(set (match_dup 0)
@@ -7373,7 +7423,7 @@ srl\t%M0,%M1,%2\n\
"")
(define_expand "slt"
- [(set (match_operand:SI 0 "register_operand" "=d")
+ [(set (match_operand:SI 0 "register_operand")
(lt:SI (match_dup 1)
(match_dup 2)))]
""
@@ -7413,7 +7463,7 @@ srl\t%M0,%M1,%2\n\
(set_attr "mode" "SI")
(set_attr_alternative "length"
[(const_int 4)
- (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
+ (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
(const_int 4)
(const_int 8))])])
@@ -7436,12 +7486,12 @@ srl\t%M0,%M1,%2\n\
(set_attr "mode" "DI")
(set_attr_alternative "length"
[(const_int 4)
- (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
+ (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
(const_int 4)
(const_int 8))])])
(define_expand "sle"
- [(set (match_operand:SI 0 "register_operand" "=d")
+ [(set (match_operand:SI 0 "register_operand")
(le:SI (match_dup 1)
(match_dup 2)))]
""
@@ -7488,7 +7538,7 @@ srl\t%M0,%M1,%2\n\
}
[(set_attr "type" "slt")
(set_attr "mode" "SI")
- (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
+ (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
(const_int 4)
(const_int 8)))])
@@ -7515,7 +7565,7 @@ srl\t%M0,%M1,%2\n\
}
[(set_attr "type" "slt")
(set_attr "mode" "DI")
- (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
+ (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
(const_int 4)
(const_int 8)))])
@@ -7530,9 +7580,9 @@ srl\t%M0,%M1,%2\n\
(set_attr "length" "8")])
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (le:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "register_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (le:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "register_operand")))]
"TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
[(set (match_dup 0)
(lt:SI (match_dup 2)
@@ -7553,9 +7603,9 @@ srl\t%M0,%M1,%2\n\
(set_attr "length" "8")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (le:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "register_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (le:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "register_operand")))]
"TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
&& !TARGET_MIPS16"
[(set (match_dup 0)
@@ -7567,7 +7617,7 @@ srl\t%M0,%M1,%2\n\
"")
(define_expand "sgtu"
- [(set (match_operand:SI 0 "register_operand" "=d")
+ [(set (match_operand:SI 0 "register_operand")
(gtu:SI (match_dup 1)
(match_dup 2)))]
""
@@ -7628,7 +7678,7 @@ srl\t%M0,%M1,%2\n\
(set_attr "mode" "DI")])
(define_expand "sgeu"
- [(set (match_operand:SI 0 "register_operand" "=d")
+ [(set (match_operand:SI 0 "register_operand")
(geu:SI (match_dup 1)
(match_dup 2)))]
""
@@ -7660,9 +7710,9 @@ srl\t%M0,%M1,%2\n\
(set_attr "length" "8")])
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (geu:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "arith_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (geu:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "arith_operand")))]
"TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
[(set (match_dup 0)
(ltu:SI (match_dup 1)
@@ -7683,9 +7733,9 @@ srl\t%M0,%M1,%2\n\
(set_attr "length" "8")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (geu:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "arith_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (geu:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "arith_operand")))]
"TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
&& !TARGET_MIPS16"
[(set (match_dup 0)
@@ -7697,7 +7747,7 @@ srl\t%M0,%M1,%2\n\
"")
(define_expand "sltu"
- [(set (match_operand:SI 0 "register_operand" "=d")
+ [(set (match_operand:SI 0 "register_operand")
(ltu:SI (match_dup 1)
(match_dup 2)))]
""
@@ -7737,7 +7787,7 @@ srl\t%M0,%M1,%2\n\
(set_attr "mode" "SI")
(set_attr_alternative "length"
[(const_int 4)
- (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
+ (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
(const_int 4)
(const_int 8))])])
@@ -7760,12 +7810,12 @@ srl\t%M0,%M1,%2\n\
(set_attr "mode" "DI")
(set_attr_alternative "length"
[(const_int 4)
- (if_then_else (match_operand:VOID 2 "m16_uimm8_1" "")
+ (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
(const_int 4)
(const_int 8))])])
(define_expand "sleu"
- [(set (match_operand:SI 0 "register_operand" "=d")
+ [(set (match_operand:SI 0 "register_operand")
(leu:SI (match_dup 1)
(match_dup 2)))]
""
@@ -7812,7 +7862,7 @@ srl\t%M0,%M1,%2\n\
}
[(set_attr "type" "slt")
(set_attr "mode" "SI")
- (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
+ (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
(const_int 4)
(const_int 8)))])
@@ -7839,7 +7889,7 @@ srl\t%M0,%M1,%2\n\
}
[(set_attr "type" "slt")
(set_attr "mode" "DI")
- (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1" "")
+ (set (attr "length") (if_then_else (match_operand:VOID 2 "m16_uimm8_m1_1")
(const_int 4)
(const_int 8)))])
@@ -7854,9 +7904,9 @@ srl\t%M0,%M1,%2\n\
(set_attr "length" "8")])
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (leu:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "register_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (leu:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "register_operand")))]
"TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
[(set (match_dup 0)
(ltu:SI (match_dup 2)
@@ -7877,9 +7927,9 @@ srl\t%M0,%M1,%2\n\
(set_attr "length" "8")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (leu:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "register_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (leu:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "register_operand")))]
"TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
&& !TARGET_MIPS16"
[(set (match_dup 0)
@@ -8073,7 +8123,7 @@ srl\t%M0,%M1,%2\n\
(label_ref (match_operand 0 "" "")))]
"!TARGET_MIPS16"
{
- if (flag_pic && ! TARGET_EMBEDDED_PIC)
+ if (flag_pic)
{
if (get_attr_length (insn) <= 8)
return "%*b\t%l0%/";
@@ -8089,12 +8139,11 @@ srl\t%M0,%M1,%2\n\
[(set_attr "type" "jump")
(set_attr "mode" "none")
(set (attr "length")
- ;; we can't use `j' when emitting non-embedded PIC, so we emit
- ;; branch, if it's in range, or load the address of the branch
- ;; target into $at in a PIC-compatible way and then jump to it.
+ ;; We can't use `j' when emitting PIC. Emit a branch if it's
+ ;; in range, otherwise load the address of the branch target into
+ ;; $at and then jump to it.
(if_then_else
- (ior (eq (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC")
- (const_int 0))
+ (ior (eq (symbol_ref "flag_pic") (const_int 0))
(lt (abs (minus (match_dup 0)
(plus (pc) (const_int 4))))
(const_int 131072)))
@@ -8113,7 +8162,7 @@ srl\t%M0,%M1,%2\n\
(set_attr "length" "8")])
(define_expand "indirect_jump"
- [(set (pc) (match_operand 0 "register_operand" "d"))]
+ [(set (pc) (match_operand 0 "register_operand"))]
""
{
rtx dest;
@@ -8146,8 +8195,8 @@ srl\t%M0,%M1,%2\n\
(define_expand "tablejump"
[(set (pc)
- (match_operand 0 "register_operand" "d"))
- (use (label_ref (match_operand 1 "" "")))]
+ (match_operand 0 "register_operand"))
+ (use (label_ref (match_operand 1 "")))]
""
{
if (TARGET_MIPS16)
@@ -8194,9 +8243,8 @@ srl\t%M0,%M1,%2\n\
(set_attr "mode" "none")])
(define_expand "tablejump_mips161"
- [(set (pc) (plus:SI (sign_extend:SI
- (match_operand:HI 0 "register_operand" "d"))
- (label_ref:SI (match_operand 1 "" ""))))]
+ [(set (pc) (plus:SI (sign_extend:SI (match_operand:HI 0 "register_operand"))
+ (label_ref:SI (match_operand 1 ""))))]
"TARGET_MIPS16 && !(Pmode == DImode)"
{
rtx t1, t2, t3;
@@ -8212,9 +8260,8 @@ srl\t%M0,%M1,%2\n\
})
(define_expand "tablejump_mips162"
- [(set (pc) (plus:DI (sign_extend:DI
- (match_operand:HI 0 "register_operand" "d"))
- (label_ref:DI (match_operand 1 "" ""))))]
+ [(set (pc) (plus:DI (sign_extend:DI (match_operand:HI 0 "register_operand"))
+ (label_ref:DI (match_operand 1 ""))))]
"TARGET_MIPS16 && Pmode == DImode"
{
rtx t1, t2, t3;
@@ -8229,114 +8276,13 @@ srl\t%M0,%M1,%2\n\
DONE;
})
-;; Implement a switch statement when generating embedded PIC code.
-;; Switches are implemented by `tablejump' when not using -membedded-pic.
-
-(define_expand "casesi"
- [(set (match_dup 5)
- (minus:SI (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "const_int_operand" "")))
- (set (cc0)
- (compare:CC (match_dup 5)
- (match_operand:SI 2 "arith_operand" "")))
- (set (pc)
- (if_then_else (gtu (cc0)
- (const_int 0))
- (label_ref (match_operand 4 "" ""))
- (pc)))
- (parallel
- [(set (pc)
- (mem:SI (plus:SI (mult:SI (match_dup 5)
- (const_int 4))
- (label_ref (match_operand 3 "" "")))))
- (clobber (match_scratch:SI 6 ""))
- (clobber (reg:SI 31))])]
- "TARGET_EMBEDDED_PIC"
-{
- rtx index;
-
- /* If the index is too large, go to the default label. */
- index = expand_binop (SImode, sub_optab, operands[0],
- operands[1], 0, 0, OPTAB_WIDEN);
- emit_insn (gen_cmpsi (index, operands[2]));
- emit_insn (gen_bgtu (operands[4]));
-
- /* Do the PIC jump. */
- if (Pmode != DImode)
- emit_jump_insn (gen_casesi_internal (index, operands[3],
- gen_reg_rtx (SImode)));
- else
- emit_jump_insn (gen_casesi_internal_di (index, operands[3],
- gen_reg_rtx (DImode)));
-
- DONE;
-})
-
-;; An embedded PIC switch statement looks like this:
-;; bal $LS1
-;; sll $reg,$index,2
-;; $LS1:
-;; addu $reg,$reg,$31
-;; lw $reg,$L1-$LS1($reg)
-;; addu $reg,$reg,$31
-;; j $reg
-;; $L1:
-;; .word case1-$LS1
-;; .word case2-$LS1
-;; ...
-
-(define_insn "casesi_internal"
- [(set (pc)
- (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
- (const_int 4))
- (label_ref (match_operand 1 "" "")))))
- (clobber (match_operand:SI 2 "register_operand" "=d"))
- (clobber (reg:SI 31))]
- "TARGET_EMBEDDED_PIC"
- {
- if (set_nomacro)
- return "%(bal\\t%S1\;sll\\t%2,%0,2\\n%~%S1:\;addu\\t%2,%2,$31%)\;\\
-.set macro\;lw\\t%2,%1-%S1(%2)\;.set nomacro\;addu\\t%2,%2,$31\\n\\t%*j\\t%2%/";
- return
- "%(bal\\t%S1\;sll\\t%2,%0,2\\n%~%S1:\;addu\\t%2,%2,$31%)\;\\
-lw\\t%2,%1-%S1(%2)\;addu\\t%2,%2,$31\\n\\t%*j\\t%2%/"
- ;
- }
- [(set_attr "type" "jump")
- (set_attr "mode" "none")
- (set_attr "length" "24")])
-
-;; This code assumes that the table index will never be >= 29 bits wide,
-;; which allows the 'sign extend' from SI to DI be a no-op.
-(define_insn "casesi_internal_di"
- [(set (pc)
- (mem:DI (plus:DI (sign_extend:DI
- (mult:SI (match_operand:SI 0 "register_operand" "d")
- (const_int 8)))
- (label_ref (match_operand 1 "" "")))))
- (clobber (match_operand:DI 2 "register_operand" "=d"))
- (clobber (reg:DI 31))]
- "TARGET_EMBEDDED_PIC"
- {
- if (set_nomacro)
- return "%(bal\\t%S1\;sll\\t%2,%0,3\\n%~%S1:\;daddu\\t%2,%2,$31%)\;\\
-.set macro\;ld\\t%2,%1-%S1(%2)\;.set nomacro\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/";
- return
- "%(bal\\t%S1\;sll\\t%2,%0,3\\n%~%S1:\;daddu\\t%2,%2,$31%)\;\\
-ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/"
- ;
- }
- [(set_attr "type" "jump")
- (set_attr "mode" "none")
- (set_attr "length" "24")])
-
;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well.
;; While it is possible to either pull it off the stack (in the
;; o32 case) or recalculate it given t9 and our target label,
;; it takes 3 or 4 insns to do so.
(define_expand "builtin_setjmp_setup"
- [(use (match_operand 0 "register_operand" ""))]
+ [(use (match_operand 0 "register_operand"))]
"TARGET_ABICALLS"
{
rtx addr;
@@ -8351,7 +8297,7 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/"
;; $25 for compatibility (we lose nothing by doing so).
(define_expand "builtin_longjmp"
- [(use (match_operand 0 "register_operand" "r"))]
+ [(use (match_operand 0 "register_operand"))]
"TARGET_ABICALLS"
{
/* The elements of the buffer are, in order: */
@@ -8443,23 +8389,9 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/"
[(set_attr "type" "jump")
(set_attr "mode" "none")])
-;; When generating embedded PIC code we need to get the address of the
-;; current function. This specialized instruction does just that.
-
-(define_insn "get_fnaddr"
- [(set (match_operand 0 "register_operand" "=d")
- (unspec [(match_operand 1 "" "")] UNSPEC_GET_FNADDR))
- (clobber (reg:SI 31))]
- "TARGET_EMBEDDED_PIC
- && GET_CODE (operands[1]) == SYMBOL_REF"
- "%($LF%= = . + 8\;bal\t$LF%=\;nop;la\t%0,%1-$LF%=%)\;addu\t%0,%0,$31"
- [(set_attr "type" "call")
- (set_attr "mode" "none")
- (set_attr "length" "20")])
-
;; This is used in compiling the unwind routines.
(define_expand "eh_return"
- [(use (match_operand 0 "general_operand" ""))]
+ [(use (match_operand 0 "general_operand"))]
""
{
enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode;
@@ -8490,8 +8422,8 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/"
"#")
(define_split
- [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
- (clobber (match_scratch 1 ""))]
+ [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
+ (clobber (match_scratch 1))]
"reload_completed && !TARGET_DEBUG_D_MODE"
[(const_int 0)]
{
@@ -8567,10 +8499,10 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/"
;; epilogue -- we might as well use it for !TARGET_ABICALLS as well.
(define_expand "sibcall"
- [(parallel [(call (match_operand 0 "" "")
- (match_operand 1 "" ""))
- (use (match_operand 2 "" "")) ;; next_arg_reg
- (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx
+ [(parallel [(call (match_operand 0 "")
+ (match_operand 1 ""))
+ (use (match_operand 2 "")) ;; next_arg_reg
+ (use (match_operand 3 ""))])] ;; struct_value_size_rtx
"TARGET_SIBCALLS"
{
mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
@@ -8587,10 +8519,10 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/"
[(set_attr "type" "call")])
(define_expand "sibcall_value"
- [(parallel [(set (match_operand 0 "" "")
- (call (match_operand 1 "" "")
- (match_operand 2 "" "")))
- (use (match_operand 3 "" ""))])] ;; next_arg_reg
+ [(parallel [(set (match_operand 0 "")
+ (call (match_operand 1 "")
+ (match_operand 2 "")))
+ (use (match_operand 3 ""))])] ;; next_arg_reg
"TARGET_SIBCALLS"
{
mips_expand_call (operands[0], XEXP (operands[1], 0),
@@ -8622,10 +8554,10 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/"
[(set_attr "type" "call")])
(define_expand "call"
- [(parallel [(call (match_operand 0 "" "")
- (match_operand 1 "" ""))
- (use (match_operand 2 "" "")) ;; next_arg_reg
- (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx
+ [(parallel [(call (match_operand 0 "")
+ (match_operand 1 ""))
+ (use (match_operand 2 "")) ;; next_arg_reg
+ (use (match_operand 3 ""))])] ;; struct_value_size_rtx
""
{
mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
@@ -8696,10 +8628,10 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/"
[(set_attr "type" "call")])
(define_expand "call_value"
- [(parallel [(set (match_operand 0 "" "")
- (call (match_operand 1 "" "")
- (match_operand 2 "" "")))
- (use (match_operand 3 "" ""))])] ;; next_arg_reg
+ [(parallel [(set (match_operand 0 "")
+ (call (match_operand 1 "")
+ (match_operand 2 "")))
+ (use (match_operand 3 ""))])] ;; next_arg_reg
""
{
mips_expand_call (operands[0], XEXP (operands[1], 0),
@@ -8776,10 +8708,10 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/"
;; Call subroutine returning any type.
(define_expand "untyped_call"
- [(parallel [(call (match_operand 0 "" "")
+ [(parallel [(call (match_operand 0 "")
(const_int 0))
- (match_operand 1 "" "")
- (match_operand 2 "" "")])]
+ (match_operand 1 "")
+ (match_operand 2 "")])]
""
{
int i;
@@ -8806,9 +8738,9 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/"
(define_expand "prefetch"
- [(prefetch (match_operand 0 "address_operand" "")
- (match_operand 1 "const_int_operand" "")
- (match_operand 2 "const_int_operand" ""))]
+ [(prefetch (match_operand 0 "address_operand")
+ (match_operand 1 "const_int_operand")
+ (match_operand 2 "const_int_operand"))]
"ISA_HAS_PREFETCH"
{
if (symbolic_operand (operands[0], GET_MODE (operands[0])))
@@ -9081,11 +9013,11 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/"
;; These are the main define_expand's used to make conditional moves.
(define_expand "movsicc"
- [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
- (set (match_operand:SI 0 "register_operand" "")
+ [(set (match_dup 4) (match_operand 1 "comparison_operator"))
+ (set (match_operand:SI 0 "register_operand")
(if_then_else:SI (match_dup 5)
- (match_operand:SI 2 "reg_or_0_operand" "")
- (match_operand:SI 3 "reg_or_0_operand" "")))]
+ (match_operand:SI 2 "reg_or_0_operand")
+ (match_operand:SI 3 "reg_or_0_operand")))]
"ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
{
gen_conditional_move (operands);
@@ -9093,11 +9025,11 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/"
})
(define_expand "movdicc"
- [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
- (set (match_operand:DI 0 "register_operand" "")
+ [(set (match_dup 4) (match_operand 1 "comparison_operator"))
+ (set (match_operand:DI 0 "register_operand")
(if_then_else:DI (match_dup 5)
- (match_operand:DI 2 "reg_or_0_operand" "")
- (match_operand:DI 3 "reg_or_0_operand" "")))]
+ (match_operand:DI 2 "reg_or_0_operand")
+ (match_operand:DI 3 "reg_or_0_operand")))]
"(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT"
{
gen_conditional_move (operands);
@@ -9105,11 +9037,11 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/"
})
(define_expand "movsfcc"
- [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
- (set (match_operand:SF 0 "register_operand" "")
+ [(set (match_dup 4) (match_operand 1 "comparison_operator"))
+ (set (match_operand:SF 0 "register_operand")
(if_then_else:SF (match_dup 5)
- (match_operand:SF 2 "register_operand" "")
- (match_operand:SF 3 "register_operand" "")))]
+ (match_operand:SF 2 "register_operand")
+ (match_operand:SF 3 "register_operand")))]
"ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT"
{
gen_conditional_move (operands);
@@ -9117,11 +9049,11 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/"
})
(define_expand "movdfcc"
- [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
- (set (match_operand:DF 0 "register_operand" "")
+ [(set (match_dup 4) (match_operand 1 "comparison_operator"))
+ (set (match_operand:DF 0 "register_operand")
(if_then_else:DF (match_dup 5)
- (match_operand:DF 2 "register_operand" "")
- (match_operand:DF 3 "register_operand" "")))]
+ (match_operand:DF 2 "register_operand")
+ (match_operand:DF 3 "register_operand")))]
"ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
{
gen_conditional_move (operands);
@@ -9136,74 +9068,21 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/"
;; ....................
;;
-(define_insn "consttable_qi"
- [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "=g")]
- UNSPEC_CONSTTABLE_QI)]
- "TARGET_MIPS16"
-{
- assemble_integer (operands[0], 1, BITS_PER_UNIT, 1);
- return "";
-}
- [(set_attr "type" "unknown")
- (set_attr "mode" "QI")
- (set_attr "length" "8")])
-
-(define_insn "consttable_hi"
- [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "=g")]
- UNSPEC_CONSTTABLE_HI)]
- "TARGET_MIPS16"
-{
- assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
- return "";
-}
- [(set_attr "type" "unknown")
- (set_attr "mode" "HI")
- (set_attr "length" "8")])
-
-(define_insn "consttable_si"
- [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "=g")]
- UNSPEC_CONSTTABLE_SI)]
- "TARGET_MIPS16"
-{
- assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
- return "";
-}
- [(set_attr "type" "unknown")
- (set_attr "mode" "SI")
- (set_attr "length" "8")])
-
-(define_insn "consttable_di"
- [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "=g")]
- UNSPEC_CONSTTABLE_DI)]
- "TARGET_MIPS16"
-{
- assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
- return "";
-}
- [(set_attr "type" "unknown")
- (set_attr "mode" "DI")
- (set_attr "length" "16")])
-
-(define_insn "consttable_sf"
- [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "=g")]
- UNSPEC_CONSTTABLE_SF)]
+(define_insn "consttable_int"
+ [(unspec_volatile [(match_operand 0 "consttable_operand" "")
+ (match_operand 1 "const_int_operand" "")]
+ UNSPEC_CONSTTABLE_INT)]
"TARGET_MIPS16"
{
- REAL_VALUE_TYPE d;
-
- if (GET_CODE (operands[0]) != CONST_DOUBLE)
- abort ();
- REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
- assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
+ assemble_integer (operands[0], INTVAL (operands[1]),
+ BITS_PER_UNIT * INTVAL (operands[1]), 1);
return "";
}
- [(set_attr "type" "unknown")
- (set_attr "mode" "SF")
- (set_attr "length" "8")])
+ [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))])
-(define_insn "consttable_df"
- [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "=g")]
- UNSPEC_CONSTTABLE_DF)]
+(define_insn "consttable_float"
+ [(unspec_volatile [(match_operand 0 "consttable_operand" "")]
+ UNSPEC_CONSTTABLE_FLOAT)]
"TARGET_MIPS16"
{
REAL_VALUE_TYPE d;
@@ -9211,36 +9090,18 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/"
if (GET_CODE (operands[0]) != CONST_DOUBLE)
abort ();
REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
- assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
+ assemble_real (d, GET_MODE (operands[0]),
+ GET_MODE_BITSIZE (GET_MODE (operands[0])));
return "";
}
- [(set_attr "type" "unknown")
- (set_attr "mode" "DF")
- (set_attr "length" "16")])
-
-(define_insn "align_2"
- [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_2)]
- "TARGET_MIPS16"
- ".align 1"
- [(set_attr "type" "unknown")
- (set_attr "mode" "HI")
- (set_attr "length" "8")])
-
-(define_insn "align_4"
- [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_4)]
- "TARGET_MIPS16"
- ".align 2"
- [(set_attr "type" "unknown")
- (set_attr "mode" "SI")
- (set_attr "length" "8")])
+ [(set (attr "length")
+ (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))])
-(define_insn "align_8"
- [(unspec_volatile [(const_int 0)] UNSPEC_ALIGN_8)]
- "TARGET_MIPS16"
- ".align 3"
- [(set_attr "type" "unknown")
- (set_attr "mode" "DI")
- (set_attr "length" "12")])
+(define_insn "align"
+ [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)]
+ ""
+ ".align\t%0"
+ [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))])
;;
;; ....................
@@ -9358,7 +9219,7 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/"
(set_attr "length" "8")])
(define_split
- [(match_operand 0 "small_data_pattern" "")]
+ [(match_operand 0 "small_data_pattern")]
"reload_completed"
[(match_dup 0)]
{ operands[0] = mips_rewrite_small_data (operands[0]); })
diff --git a/gcc/config/mips/sb1.md b/gcc/config/mips/sb1.md
new file mode 100644
index 00000000000..41cebedce4f
--- /dev/null
+++ b/gcc/config/mips/sb1.md
@@ -0,0 +1,504 @@
+;;
+;; DFA-based pipeline description for Broadcom SB-1
+;;
+
+;; The Broadcom SB-1 core is 4-way superscalar, in-order. It has 2 load/store
+;; pipes (one of which can support some ALU operations), 2 alu pipes, 2 FP
+;; pipes, and 1 MDMX pipes. It can issue 2 ls insns and 2 exe/fpu/mdmx insns
+;; each cycle.
+
+;; We model the 4-way issue by ordering unit choices. The possible choices are
+;; {ex1,fp1}|{ex0,fp0}|ls1|ls0. Instructions issue to the first eligible unit
+;; in the list in most cases. Non-indexed load/stores issue to ls0 first.
+;; simple alu operations issue to ls1 if it is still available, and their
+;; operands are ready (no co-issue with loads), otherwise to the first
+;; available ex unit.
+
+;; When exceptions are enabled, can only issue FP insns to fp1. This is
+;; to ensure that instructions complete in order. The -mfp-exceptions option
+;; can be used to specify whether the system has FP exceptions enabled or not.
+
+;; In 32-bit mode, dependent FP can't co-issue with load, and only one FP exe
+;; insn can issue per cycle (fp1).
+
+;; The A1 MDMX pipe is separate from the FP pipes, but uses the same register
+;; file. As a result, once an MDMX insn is issued, no FP insns can be issued
+;; for 3 cycles. When an FP insn is issued, no MDMX insn can be issued for
+;; 5 cycles. This is currently not handled because there is no MDMX insn
+;; support as yet.
+
+;;
+;; We use two automata. sb1_cpu_div is for the integer divides, which are
+;; not pipelined. sb1_cpu is for everything else.
+;;
+(define_automaton "sb1_cpu, sb1_cpu_div")
+
+;; Load/store function units.
+(define_cpu_unit "sb1_ls0" "sb1_cpu")
+(define_cpu_unit "sb1_ls1" "sb1_cpu")
+
+;; CPU function units.
+(define_cpu_unit "sb1_ex0" "sb1_cpu")
+(define_cpu_unit "sb1_ex1" "sb1_cpu")
+
+;; The divide unit is not pipelined, and blocks hi/lo reads and writes.
+(define_cpu_unit "sb1_div" "sb1_cpu_div")
+;; DMULT block any multiply from issuing in the next cycle.
+(define_cpu_unit "sb1_mul" "sb1_cpu")
+
+;; Floating-point units.
+(define_cpu_unit "sb1_fp0" "sb1_cpu")
+(define_cpu_unit "sb1_fp1" "sb1_cpu")
+
+;; Can only issue to one of the ex and fp pipes at a time.
+(exclusion_set "sb1_ex0" "sb1_fp0")
+(exclusion_set "sb1_ex1" "sb1_fp1")
+
+;; Define an SB-1 specific attribute to simplify some FP descriptions.
+;; We can use 2 FP pipes only if we have 64-bit FP code, and exceptions are
+;; disabled.
+
+(define_attr "sb1_fp_pipes" "one,two"
+ (cond [(and (ne (symbol_ref "TARGET_FLOAT64") (const_int 0))
+ (eq (symbol_ref "TARGET_FP_EXCEPTIONS") (const_int 0)))
+ (const_string "two")]
+ (const_string "one")))
+
+;; Define reservations for common combinations.
+
+;; For long cycle operations, the FPU has a 4 cycle pipeline that repeats,
+;; effectively re-issuing the operation every 4 cycles. This means that we
+;; can have at most 4 long-cycle operations per pipe.
+
+;; ??? The fdiv operations should be e.g.
+;; sb1_fp1_4cycles*7" | "sb1_fp0_4cycle*7
+;; but the DFA is too large when we do that. Perhaps have to use scheduler
+;; hooks here.
+
+;; ??? Try limiting scheduler to 2 long latency operations, and see if this
+;; results in a usable DFA, and whether it helps code performance.
+
+;;(define_reservation "sb1_fp0_4cycles" "sb1_fp0, nothing*3")
+;;(define_reservation "sb1_fp1_4cycles" "sb1_fp1, nothing*3")
+
+;;
+;; The ordering of the instruction-execution-path/resource-usage
+;; descriptions (also known as reservation RTL) is roughly ordered
+;; based on the define attribute RTL for the "type" classification.
+;; When modifying, remember that the first test that matches is the
+;; reservation used!
+;;
+
+(define_insn_reservation "ir_sb1_unknown" 1
+ (and (eq_attr "cpu" "sb1")
+ (eq_attr "type" "unknown,multi"))
+ "sb1_ls0+sb1_ls1+sb1_ex0+sb1_ex1+sb1_fp0+sb1_fp1")
+
+;; predicted taken branch causes 2 cycle ifetch bubble. predicted not
+;; taken branch causes 0 cycle ifetch bubble. mispredicted branch causes 8
+;; cycle ifetch bubble. We assume all branches predicted not taken.
+
+;; ??? This assumption that branches are predicated not taken should be
+;; investigated. Maybe using 2 here will give better results.
+
+(define_insn_reservation "ir_sb1_branch" 0
+ (and (eq_attr "cpu" "sb1")
+ (eq_attr "type" "branch,jump,call"))
+ "sb1_ex0")
+
+;; ??? This is 1 cycle for ldl/ldr to ldl/ldr when they use the same data
+;; register as destination.
+
+;; ??? Can co-issue a load with a dependent arith insn if it executes on an EX
+;; unit. Can not co-issue if the dependent insn executes on an LS unit.
+
+;; A load normally has a latency of zero cycles. In some cases, dependent
+;; insns can be issued in the same cycle. However, a value of 1 gives
+;; better performance in empirical testing.
+
+(define_insn_reservation "ir_sb1_load" 1
+ (and (eq_attr "cpu" "sb1")
+ (eq_attr "type" "load,prefetch"))
+ "sb1_ls0 | sb1_ls1")
+
+;; Can not co-issue fpload with fp exe when in 32-bit mode.
+
+(define_insn_reservation "ir_sb1_fpload" 0
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "fpload")
+ (ne (symbol_ref "TARGET_FLOAT64")
+ (const_int 0))))
+ "sb1_ls0 | sb1_ls1")
+
+(define_insn_reservation "ir_sb1_fpload_32bitfp" 1
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "fpload")
+ (eq (symbol_ref "TARGET_FLOAT64")
+ (const_int 0))))
+ "sb1_ls0 | sb1_ls1")
+
+;; Indexed loads can only execute on LS1 pipe.
+
+(define_insn_reservation "ir_sb1_fpidxload" 0
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "fpidxload")
+ (ne (symbol_ref "TARGET_FLOAT64")
+ (const_int 0))))
+ "sb1_ls1")
+
+(define_insn_reservation "ir_sb1_fpidxload_32bitfp" 1
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "fpidxload")
+ (eq (symbol_ref "TARGET_FLOAT64")
+ (const_int 0))))
+ "sb1_ls1")
+
+;; prefx can only execute on the ls1 pipe.
+
+(define_insn_reservation "ir_sb1_prefetchx" 0
+ (and (eq_attr "cpu" "sb1")
+ (eq_attr "type" "prefetchx"))
+ "sb1_ls1")
+
+;; ??? There is a 4.5 cycle latency if a store is followed by a load, and
+;; there is a RAW dependency.
+
+(define_insn_reservation "ir_sb1_store" 1
+ (and (eq_attr "cpu" "sb1")
+ (eq_attr "type" "store"))
+ "sb1_ls0+sb1_ex1 | sb1_ls0+sb1_ex0 | sb1_ls1+sb1_ex1 | sb1_ls1+sb1_ex0")
+
+(define_insn_reservation "ir_sb1_fpstore" 1
+ (and (eq_attr "cpu" "sb1")
+ (eq_attr "type" "fpstore"))
+ "sb1_ls0+sb1_fp1 | sb1_ls0+sb1_fp0 | sb1_ls1+sb1_fp1 | sb1_ls1+sb1_fp0")
+
+;; Indexed stores can only execute on LS1 pipe.
+
+(define_insn_reservation "ir_sb1_fpidxstore" 1
+ (and (eq_attr "cpu" "sb1")
+ (eq_attr "type" "fpidxstore"))
+ "sb1_ls1+sb1_fp1 | sb1_ls1+sb1_fp0")
+
+;; Load latencies are 3 cycles for one load to another load or store (address
+;; only). This is 0 cycles for one load to a store using it as the data
+;; written.
+
+;; This assumes that if a load is dependent on a previous insn, then it must
+;; be an address dependence.
+
+(define_bypass 3
+ "ir_sb1_load,ir_sb1_fpload,ir_sb1_fpload_32bitfp,ir_sb1_fpidxload,
+ ir_sb1_fpidxload_32bitfp"
+ "ir_sb1_load,ir_sb1_fpload,ir_sb1_fpload_32bitfp,ir_sb1_fpidxload,
+ ir_sb1_fpidxload_32bitfp,ir_sb1_prefetchx")
+
+(define_bypass 3
+ "ir_sb1_load,ir_sb1_fpload,ir_sb1_fpload_32bitfp,ir_sb1_fpidxload,
+ ir_sb1_fpidxload_32bitfp"
+ "ir_sb1_store,ir_sb1_fpstore,ir_sb1_fpidxstore"
+ "store_data_bypass_p")
+
+;; Simple alu instructions can execute on the LS1 unit.
+
+;; ??? A simple alu insn issued on an LS unit has 0 cycle latency to an EX
+;; insn, to a store (for data), and to an xfer insn. It has 1 cycle latency to
+;; another LS insn (excluding store data). A simple alu insn issued on an EX
+;; unit has a latency of 5 cycles when the results goes to a LS unit (excluding
+;; store data), otherwise a latency of 1 cycle.
+
+;; ??? We can not handle latencies properly for simple alu instructions
+;; within the DFA pipeline model. Latencies can be defined only from one
+;; insn reservation to another. We can't make them depend on which function
+;; unit was used. This isn't a DFA flaw. There is a conflict here, as we
+;; need to know the latency before we can determine which unit will be
+;; available, but we need to know which unit it is issued to before we can
+;; compute the latency. Perhaps this can be handled via scheduler hooks.
+;; This needs to be investigated.
+
+;; ??? Optimal scheduling taking the LS units into account seems to require
+;; a pre-scheduling pass. We need to determine which instructions feed results
+;; into store/load addresses, and thus benefit most from being issued to the
+;; LS unit. Also, we need to prune the list to ensure we don't overschedule
+;; insns to the LS unit, and that we don't conflict with insns that need LS1
+;; such as indexed loads. We then need to emit nops to ensure that simple
+;; alu instructions that are not supposed to be scheduled to LS1 don't
+;; accidentally end up there because LS1 is free when they are issued. This
+;; will be a lot of work, and it isn't clear how useful it will be.
+
+;; Empirical testing shows that 2 gives the best result.
+
+(define_insn_reservation "ir_sb1_simple_alu" 2
+ (and (eq_attr "cpu" "sb1")
+ (eq_attr "type" "const,arith"))
+ "sb1_ls1 | sb1_ex1 | sb1_ex0")
+
+;; ??? condmove also includes some FP instructions that execute on the FP
+;; units. This needs to be clarified.
+
+(define_insn_reservation "ir_sb1_alu" 1
+ (and (eq_attr "cpu" "sb1")
+ (eq_attr "type" "condmove,nop,shift"))
+ "sb1_ex1 | sb1_ex0")
+
+;; These are type arith/darith that only execute on the EX0 unit.
+
+(define_insn_reservation "ir_sb1_alu_0" 1
+ (and (eq_attr "cpu" "sb1")
+ (eq_attr "type" "slt,clz,trap"))
+ "sb1_ex0")
+
+;; An alu insn issued on an EX unit has a latency of 5 cycles when the
+;; result goes to a LS unit (excluding store data).
+
+;; This assumes that if a load is dependent on a previous insn, then it must
+;; be an address dependence.
+
+(define_bypass 5
+ "ir_sb1_alu,ir_sb1_alu_0,ir_sb1_mfhi,ir_sb1_mflo"
+ "ir_sb1_load,ir_sb1_fpload,ir_sb1_fpload_32bitfp,ir_sb1_fpidxload,
+ ir_sb1_fpidxload_32bitfp,ir_sb1_prefetchx")
+
+(define_bypass 5
+ "ir_sb1_alu,ir_sb1_alu_0,ir_sb1_mfhi,ir_sb1_mflo"
+ "ir_sb1_store,ir_sb1_fpstore,ir_sb1_fpidxstore"
+ "store_data_bypass_p")
+
+;; mf{hi,lo} is 1 cycle.
+
+(define_insn_reservation "ir_sb1_mfhi" 1
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "mfhilo")
+ (not (match_operand 1 "lo_operand"))))
+ "sb1_ex1")
+
+(define_insn_reservation "ir_sb1_mflo" 1
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "mfhilo")
+ (match_operand 1 "lo_operand")))
+ "sb1_ex1")
+
+;; mt{hi,lo} to mul/div is 4 cycles.
+
+(define_insn_reservation "ir_sb1_mthilo" 4
+ (and (eq_attr "cpu" "sb1")
+ (eq_attr "type" "mthilo"))
+ "sb1_ex1")
+
+;; mt{hi,lo} to mf{hi,lo} is 3 cycles.
+
+(define_bypass 3 "ir_sb1_mthilo" "ir_sb1_mfhi,ir_sb1_mflo")
+
+;; multiply latency to an EX operation is 3 cycles.
+
+;; ??? Should check whether we need to make multiply conflict with moves
+;; to/from hilo registers.
+
+(define_insn_reservation "ir_sb1_mulsi" 3
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "imul,imadd")
+ (eq_attr "mode" "SI")))
+ "sb1_ex1+sb1_mul")
+
+;; muldi to mfhi is 4 cycles.
+;; Blocks any other multiply insn issue for 1 cycle.
+
+(define_insn_reservation "ir_sb1_muldi" 4
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "imul")
+ (eq_attr "mode" "DI")))
+ "sb1_ex1+sb1_mul, sb1_mul")
+
+;; muldi to mflo is 3 cycles.
+
+(define_bypass 3 "ir_sb1_muldi" "ir_sb1_mflo")
+
+;; mul latency is 7 cycles if the result is used by any LS insn.
+
+;; This assumes that if a load is dependent on a previous insn, then it must
+;; be an address dependence.
+
+(define_bypass 7
+ "ir_sb1_mulsi,ir_sb1_muldi"
+ "ir_sb1_load,ir_sb1_fpload,ir_sb1_fpload_32bitfp,ir_sb1_fpidxload,
+ ir_sb1_fpidxload_32bitfp,ir_sb1_prefetchx")
+
+(define_bypass 7
+ "ir_sb1_mulsi,ir_sb1_muldi"
+ "ir_sb1_store,ir_sb1_fpstore,ir_sb1_fpidxstore"
+ "store_data_bypass_p")
+
+;; The divide unit is not pipelined. Divide busy is asserted in the 4th
+;; cycle, and then deasserted on the latency cycle. So only one divide at
+;; a time, but the first/last 4 cycles can overlap.
+
+;; ??? All divides block writes to hi/lo regs. hi/lo regs are written 4 cycles
+;; after the latency cycle for divides (e.g. 40/72). dmult writes lo in
+;; cycle 7, and hi in cycle 8. All other insns write hi/lo regs in cycle 7.
+;; Default for output dependencies is the difference in latencies, which is
+;; only 1 cycle off here, e.g. div to mtlo stalls for 32 cycles, but should
+;; stall for 33 cycles. This does not seem significant enough to worry about.
+
+(define_insn_reservation "ir_sb1_divsi" 36
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "idiv")
+ (eq_attr "mode" "SI")))
+ "sb1_ex1, nothing*3, sb1_div*32")
+
+(define_insn_reservation "ir_sb1_divdi" 68
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "idiv")
+ (eq_attr "mode" "DI")))
+ "sb1_ex1, nothing*3, sb1_div*64")
+
+(define_insn_reservation "ir_sb1_fpu_2pipes" 4
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "fmove,fadd,fmul,fabs,fneg,fcvt")
+ (eq_attr "sb1_fp_pipes" "two")))
+ "sb1_fp1 | sb1_fp0")
+
+(define_insn_reservation "ir_sb1_fpu_1pipe" 4
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "fmove,fadd,fmul,fabs,fneg,fcvt")
+ (eq_attr "sb1_fp_pipes" "one")))
+ "sb1_fp1")
+
+;; ??? madd/msub 4-cycle latency to itself (same fr?), but 8 cycle latency
+;; otherwise.
+
+;; ??? Blocks issue of another non-madd/msub after 4 cycles.
+
+(define_insn_reservation "ir_sb1_fmadd_2pipes" 8
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "fmadd")
+ (eq_attr "sb1_fp_pipes" "two")))
+ "sb1_fp1 | sb1_fp0")
+
+(define_insn_reservation "ir_sb1_fmadd_1pipe" 8
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "fmadd")
+ (eq_attr "sb1_fp_pipes" "one")))
+ "sb1_fp1")
+
+(define_insn_reservation "ir_sb1_fcmp" 4
+ (and (eq_attr "cpu" "sb1")
+ (eq_attr "type" "fcmp"))
+ "sb1_fp1")
+
+;; mtc1 latency 5 cycles.
+
+(define_insn_reservation "ir_sb1_mtxfer" 5
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "xfer")
+ (match_operand 0 "fp_register_operand")))
+ "sb1_fp0")
+
+;; mfc1 latency 1 cycle.
+
+(define_insn_reservation "ir_sb1_mfxfer" 1
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "xfer")
+ (not (match_operand 0 "fp_register_operand"))))
+ "sb1_fp0")
+
+;; ??? Can deliver at most 1 result per every 6 cycles because of issue
+;; restrictions.
+
+(define_insn_reservation "ir_sb1_divsf_2pipes" 24
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "fdiv")
+ (and (eq_attr "mode" "SF")
+ (eq_attr "sb1_fp_pipes" "two"))))
+ "sb1_fp1 | sb1_fp0")
+
+(define_insn_reservation "ir_sb1_divsf_1pipes" 24
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "fdiv")
+ (and (eq_attr "mode" "SF")
+ (eq_attr "sb1_fp_pipes" "one"))))
+ "sb1_fp1")
+
+;; ??? Can deliver at most 1 result per every 8 cycles because of issue
+;; restrictions.
+
+(define_insn_reservation "ir_sb1_divdf_2pipes" 32
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "fdiv")
+ (and (eq_attr "mode" "SF")
+ (eq_attr "sb1_fp_pipes" "two"))))
+ "sb1_fp1 | sb1_fp0")
+
+(define_insn_reservation "ir_sb1_divdf_1pipe" 32
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "fdiv")
+ (and (eq_attr "mode" "SF")
+ (eq_attr "sb1_fp_pipes" "one"))))
+ "sb1_fp1")
+
+;; ??? Can deliver at most 1 result per every 7 cycles because of issue
+;; restrictions.
+
+(define_insn_reservation "ir_sb1_sqrtsf_2pipes" 28
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "fsqrt")
+ (and (eq_attr "mode" "SF")
+ (eq_attr "sb1_fp_pipes" "two"))))
+ "sb1_fp1 | sb1_fp0")
+
+(define_insn_reservation "ir_sb1_sqrtsf_1pipe" 28
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "fsqrt")
+ (and (eq_attr "mode" "SF")
+ (eq_attr "sb1_fp_pipes" "one"))))
+ "sb1_fp1")
+
+;; ??? Can deliver at most 1 result per every 10 cycles because of issue
+;; restrictions.
+
+(define_insn_reservation "ir_sb1_sqrtdf_2pipes" 40
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "fsqrt")
+ (and (eq_attr "mode" "DF")
+ (eq_attr "sb1_fp_pipes" "two"))))
+ "sb1_fp1 | sb1_fp0")
+
+(define_insn_reservation "ir_sb1_sqrtdf_1pipe" 40
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "fsqrt")
+ (and (eq_attr "mode" "DF")
+ (eq_attr "sb1_fp_pipes" "one"))))
+ "sb1_fp1")
+
+;; ??? Can deliver at most 1 result per every 4 cycles because of issue
+;; restrictions.
+
+(define_insn_reservation "ir_sb1_rsqrtsf_2pipes" 16
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "frsqrt")
+ (and (eq_attr "mode" "SF")
+ (eq_attr "sb1_fp_pipes" "two"))))
+ "sb1_fp1 | sb1_fp0")
+
+(define_insn_reservation "ir_sb1_rsqrtsf_1pipe" 16
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "frsqrt")
+ (and (eq_attr "mode" "SF")
+ (eq_attr "sb1_fp_pipes" "one"))))
+ "sb1_fp1")
+
+;; ??? Can deliver at most 1 result per every 7 cycles because of issue
+;; restrictions.
+
+(define_insn_reservation "ir_sb1_rsqrtdf_2pipes" 28
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "frsqrt")
+ (and (eq_attr "mode" "DF")
+ (eq_attr "sb1_fp_pipes" "two"))))
+ "sb1_fp1 | sb1_fp0")
+
+(define_insn_reservation "ir_sb1_rsqrtdf_1pipe" 28
+ (and (eq_attr "cpu" "sb1")
+ (and (eq_attr "type" "frsqrt")
+ (and (eq_attr "mode" "DF")
+ (eq_attr "sb1_fp_pipes" "one"))))
+ "sb1_fp1")
diff --git a/gcc/config/mips/sr71k.md b/gcc/config/mips/sr71k.md
index ef7e650da77..f1ce973b335 100644
--- a/gcc/config/mips/sr71k.md
+++ b/gcc/config/mips/sr71k.md
@@ -17,7 +17,7 @@
;; contrived to support published timings.
;;
;; Reference:
-;; "SR3 Microporocessor Specification, System development information,"
+;; "SR3 Microprocessor Specification, System development information,"
;; Revision 1.0, 13 December 2000.
;;
;;
diff --git a/gcc/config/mips/t-elf b/gcc/config/mips/t-elf
index c36798c2765..7661ccb2d1a 100644
--- a/gcc/config/mips/t-elf
+++ b/gcc/config/mips/t-elf
@@ -31,10 +31,10 @@ TARGET_LIBGCC2_CFLAGS = -G 0
# Build the libraries for both hard and soft floating point
-#MULTILIB_OPTIONS = msoft-float EL/EB
-#MULTILIB_DIRNAMES = soft-float el eb
-#MULTILIB_MATCHES = EL=mel EB=meb
-#MULTILIB_MATCHES = msingle-float=m4650
+MULTILIB_OPTIONS = msoft-float EL/EB
+MULTILIB_DIRNAMES = soft-float el eb
+MULTILIB_MATCHES = EL=mel EB=meb
+MULTILIB_MATCHES = msingle-float=m4650
EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o
LIBGCC = stmp-multilib
diff --git a/gcc/config/mips/t-vr b/gcc/config/mips/t-vr
index e342641fc9b..dd4affe57e4 100644
--- a/gcc/config/mips/t-vr
+++ b/gcc/config/mips/t-vr
@@ -8,7 +8,7 @@ CRTSTUFF_T_CFLAGS = -G 0
TARGET_LIBGCC2_CFLAGS = -G 0
LIB2FUNCS_STATIC_EXTRA = $(srcdir)/config/mips/mips16.S \
- $(srcdir)/config/mips/vr4122-div.S
+ $(srcdir)/config/mips/vr4120-div.S
EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o
# Assemble startup files.
@@ -34,7 +34,7 @@ $(T)crtn.o: $(srcdir)/config/mips/crtn.asm $(GCC_PASSES)
# mabi=eabi/mgp32
# mabi=eabi/mgp32/mlong64
#
-# Architecture: march=vr4120 with -mfix-vr4122-bugs
+# Architecture: march=vr4120 with -mfix-vr4120
# march=vr4130 (default)
# march=vr5000
# march=vr5400
@@ -64,7 +64,7 @@ $(T)crtn.o: $(srcdir)/config/mips/crtn.asm $(GCC_PASSES)
# mabi=eabi/mlong32
# mabi=eabi/mgp32
#
-# Architecture: march=vr4120 with -mfix-vr4122-bugs
+# Architecture: march=vr4120 with -mfix-vr4120
# march=vr4130 (default)
#
# Total: 2 * 3 * 2 = 12 multilibs.
@@ -74,7 +74,7 @@ MULTILIB_OPTIONS = \
mgp32 \
mlong64 \
mips16 \
- mfix-vr4122-bugs/march=vr4130/march=vr4300/march=vr5000/march=vr5400/march=vr5500
+ mfix-vr4120/march=vr4130/march=vr4300/march=vr5000/march=vr5400/march=vr5500
MULTILIB_DIRNAMES = \
el eb \
@@ -84,7 +84,7 @@ MULTILIB_DIRNAMES = \
mips16 \
vr4120 vr4130 vr4300 vr5000 vr5400 vr5500
-MULTILIB_MATCHES = EL=mel EB=meb mfix-vr4122-bugs=march?vr4120
+MULTILIB_MATCHES = EL=mel EB=meb mfix-vr4120=march?vr4120
# Assume a 41xx-series is the default: we'd need a *mips16 entry if
# the default processor didn't support mips16. Also assume the
diff --git a/gcc/config/mips/vr.h b/gcc/config/mips/vr.h
index cbc73671c9e..38f7e129429 100644
--- a/gcc/config/mips/vr.h
+++ b/gcc/config/mips/vr.h
@@ -28,10 +28,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
"march=" DEFAULT_VR_ARCH }
#define DRIVER_SELF_SPECS \
- /* Make -mfix-vr4122-bugs imply -march=vr4120. This cuts down \
+ /* Make -mfix-vr4120 imply -march=vr4120. This cuts down \
on command-line tautology and makes it easier for t-vr to \
- provide a -mfix-vr4122-bugs multilib. */ \
- "%{mfix-vr4122-bugs:%{!march=*:-march=vr4120}}", \
+ provide a -mfix-vr4120 multilib. */ \
+ "%{mfix-vr4120:%{!march=*:-march=vr4120}}", \
\
/* Make -mabi=eabi -mlong32 the default. */ \
"%{!mabi=*:-mabi=eabi %{!mlong*:-mlong32}}", \
diff --git a/gcc/config/mips/vr4120-div.S b/gcc/config/mips/vr4120-div.S
new file mode 100644
index 00000000000..d7ee40e3043
--- /dev/null
+++ b/gcc/config/mips/vr4120-div.S
@@ -0,0 +1,75 @@
+/* Support file for -mfix-vr4120.
+ Copyright (C) 2002, 2004 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 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* This file contains functions which implement divsi3 and modsi3 for
+ -mfix-vr4120. div and ddiv do not give the correct result when one
+ of the operands is negative. */
+
+ .set nomips16
+
+#define DIV \
+ xor $3,$4,$5 /* t = x ^ y */ ; \
+ li $2,0x80000000; \
+ .set noreorder; \
+ bgez $4,1f /* x >= 0 */; \
+ and $3,$3,$2 /* t = (x ^ y) & 0x80000000 in delay slot */ ;\
+ .set reorder; \
+ subu $4,$0,$4 /* x = -x */ ; \
+1:; \
+ .set noreorder; \
+ bgez $5,2f /* y >= 0 */ ; \
+ nop; \
+ subu $5,$0,$5 /* y = -y */ ; \
+ .set reorder; \
+2:; \
+ divu $0,$4,$5; /* we use divu because of INT_MIN */ \
+ .set noreorder; \
+ bne $5,$0,3f; \
+ nop; \
+ break 7 /* division on zero y */ ; \
+3:; \
+ .set reorder; \
+ mflo $2 /* r = x / y */ ; \
+ .set noreorder; \
+ beq $3,$0,4f /* t == 0 */ ; \
+ nop; \
+ subu $2,$0,$2 /* r = -r */ ; \
+ .set reorder; \
+4:
+
+ .globl __vr4120_divsi3
+ .ent __vr4120_divsi3
+__vr4120_divsi3:
+ DIV
+ j $31
+ .end __vr4120_divsi3
+
+ .globl __vr4120_modsi3
+ .ent __vr4120_modsi3
+__vr4120_modsi3:
+ move $6,$4 # x1 = x
+ move $7,$5 # y1 = y
+ DIV
+ mult $2,$7 # r = r * y1
+ mflo $2
+ .set noreorder
+ j $31
+ subu $2,$6,$2 # r = x1 - r in delay slot
+ .end __vr4120_modsi3
diff --git a/gcc/config/mips/vxworks.h b/gcc/config/mips/vxworks.h
index fc4db447e34..ed4459829a4 100644
--- a/gcc/config/mips/vxworks.h
+++ b/gcc/config/mips/vxworks.h
@@ -45,7 +45,6 @@ Boston, MA 02111-1307, USA. */
%{mips16:%{!mno-mips16:-mips16}} %{mno-mips16:-no-mips16} \
%(subtarget_asm_optimizing_spec) \
%(subtarget_asm_debugging_spec) \
-%{membedded-pic} \
%{mabi=32:-32}%{mabi=n32:-n32}%{mabi=64:-64}%{mabi=n64:-64} \
%{mabi=eabi} %{mabi=o64} %{!mabi*: %(asm_abi_default_spec)} \
%{mgp32} %{mgp64} %{march=*} %{mxgot:-xgot} \
diff --git a/gcc/config/mips/windiss.h b/gcc/config/mips/windiss.h
index 0f8ef7e1663..156057f2de7 100644
--- a/gcc/config/mips/windiss.h
+++ b/gcc/config/mips/windiss.h
@@ -45,7 +45,6 @@ Boston, MA 02111-1307, USA. */
%{mips16:%{!mno-mips16:-mips16}} %{mno-mips16:-no-mips16} \
%(subtarget_asm_optimizing_spec) \
%(subtarget_asm_debugging_spec) \
-%{membedded-pic} \
%{mabi=32:-32}%{mabi=n32:-n32}%{mabi=64:-64}%{mabi=n64:-64} \
%{mabi=eabi} %{mabi=o64} %{!mabi*: %(asm_abi_default_spec)} \
%{mgp32} %{mgp64} %{march=*} %{mxgot:-xgot} \
diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c
index 8bf8e0eae5e..5c3014c4731 100644
--- a/gcc/config/mmix/mmix.c
+++ b/gcc/config/mmix/mmix.c
@@ -1008,7 +1008,6 @@ mmix_constant_address_p (rtx x)
case SYMBOL_REF:
return 1;
- case CONSTANT_P_RTX:
case HIGH:
/* FIXME: Don't know how to dissect these. Avoid them for now,
except we know they're constants. */
diff --git a/gcc/config/pa/pa-hpux10.h b/gcc/config/pa/pa-hpux10.h
index b9d06d5f642..d3b5d858474 100644
--- a/gcc/config/pa/pa-hpux10.h
+++ b/gcc/config/pa/pa-hpux10.h
@@ -25,7 +25,8 @@ Boston, MA 02111-1307, USA. */
we define __STDC_EXT__. A similar situation exists with respect to
the definition of __cplusplus. We define _INCLUDE_LONGLONG
to prevent nlist.h from defining __STDC_32_MODE__ (no longlong
- support). */
+ support). We define __STDCPP__ to get certain system headers
+ (notably assert.h) to assume standard preprocessor behavior in C++. */
#undef TARGET_OS_CPP_BUILTINS
#define TARGET_OS_CPP_BUILTINS() \
do \
@@ -43,6 +44,7 @@ Boston, MA 02111-1307, USA. */
builtin_define ("_HPUX_SOURCE"); \
builtin_define ("_INCLUDE_LONGLONG"); \
builtin_define ("__STDC_EXT__"); \
+ builtin_define ("__STDCPP__"); \
} \
else if (!flag_iso) \
{ \
diff --git a/gcc/config/pa/pa-hpux11.h b/gcc/config/pa/pa-hpux11.h
index e8865dfff7f..2aa31494600 100644
--- a/gcc/config/pa/pa-hpux11.h
+++ b/gcc/config/pa/pa-hpux11.h
@@ -23,7 +23,8 @@ Boston, MA 02111-1307, USA. */
we define __STDC_EXT__. A similar situation exists with respect to
the definition of __cplusplus. We define _INCLUDE_LONGLONG
to prevent nlist.h from defining __STDC_32_MODE__ (no longlong
- support). */
+ support). We define __STDCPP__ to get certain system headers
+ (notably assert.h) to assume standard preprocessor behavior in C++. */
#undef TARGET_OS_CPP_BUILTINS
#define TARGET_OS_CPP_BUILTINS() \
do \
@@ -41,6 +42,7 @@ Boston, MA 02111-1307, USA. */
builtin_define ("_HPUX_SOURCE"); \
builtin_define ("_INCLUDE_LONGLONG"); \
builtin_define ("__STDC_EXT__"); \
+ builtin_define ("__STDCPP__"); \
} \
else \
{ \
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index d9dea93304d..0cc1ed7eb99 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -592,9 +592,6 @@ move_src_operand (rtx op, enum machine_mode mode)
if (register_operand (op, mode))
return 1;
- if (GET_CODE (op) == CONSTANT_P_RTX)
- return 1;
-
if (GET_CODE (op) == CONST_INT)
return cint_ok_for_move (INTVAL (op));
@@ -8419,7 +8416,7 @@ pa_reorg (void)
markers disables output of the branch table to readonly memory,
and any alignment directives that might be needed. Possibly,
the begin_brtab insn should be output before the label for the
- table. This doesn matter at the moment since the tables are
+ table. This doesn't matter at the moment since the tables are
always output in the text section. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index 200936e8e49..b08021dd472 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -1987,7 +1987,7 @@ do { \
#define PREDICATE_CODES \
{"reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
{"call_operand_address", {LABEL_REF, SYMBOL_REF, CONST_INT, \
- CONST_DOUBLE, CONST, HIGH, CONSTANT_P_RTX}}, \
+ CONST_DOUBLE, CONST, HIGH}}, \
{"indexed_memory_operand", {SUBREG, MEM}}, \
{"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST}}, \
{"symbolic_memory_operand", {SUBREG, MEM}}, \
@@ -1995,7 +1995,7 @@ do { \
{"reg_or_0_or_nonsymb_mem_operand", {SUBREG, REG, MEM, CONST_INT, \
CONST_DOUBLE}}, \
{"move_dest_operand", {SUBREG, REG, MEM}}, \
- {"move_src_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, MEM}}, \
+ {"move_src_operand", {SUBREG, REG, CONST_INT, MEM}}, \
{"reg_or_cint_move_operand", {SUBREG, REG, CONST_INT}}, \
{"pic_label_operand", {LABEL_REF, CONST}}, \
{"fp_reg_operand", {REG}}, \
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index 96355248d22..1f3e2618eb2 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -2264,9 +2264,9 @@
(define_insn ""
[(set (match_operand:SI 0 "move_dest_operand"
- "=r,r,r,r,r,r,Q,!*q,!*f,*f,T")
+ "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
(match_operand:SI 1 "move_src_operand"
- "A,r,J,N,K,RQ,rM,!rM,!*fM,RT,*f"))]
+ "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
"(register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))
&& !TARGET_SOFT_FLOAT"
@@ -2279,12 +2279,13 @@
ldw%M1 %1,%0
stw%M0 %r1,%0
mtsar %r1
+ {mfctl|mfctl,w} %%sar,%0
fcpy,sgl %f1,%0
fldw%F1 %1,%0
fstw%F0 %1,%0"
- [(set_attr "type" "load,move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
+ [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
(set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4")])
+ (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
(define_insn ""
[(set (match_operand:SI 0 "indexed_memory_operand" "=R")
@@ -2433,9 +2434,9 @@
(define_insn ""
[(set (match_operand:SI 0 "move_dest_operand"
- "=r,r,r,r,r,r,Q,!*q")
+ "=r,r,r,r,r,r,Q,!*q,!r")
(match_operand:SI 1 "move_src_operand"
- "A,r,J,N,K,RQ,rM,!rM"))]
+ "A,r,J,N,K,RQ,rM,!rM,!*q"))]
"(register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))
&& TARGET_SOFT_FLOAT"
@@ -2447,10 +2448,11 @@
{zdepi|depwi,z} %Z1,%0
ldw%M1 %1,%0
stw%M0 %r1,%0
- mtsar %r1"
- [(set_attr "type" "load,move,move,move,move,load,store,move")
+ mtsar %r1
+ {mfctl|mfctl,w} %%sar,%0"
+ [(set_attr "type" "load,move,move,move,move,load,store,move,move")
(set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4,4,4")])
+ (set_attr "length" "4,4,4,4,4,4,4,4,4")])
;; Load or store with base-register modification.
(define_insn ""
@@ -2610,7 +2612,6 @@
"*
{
rtx xoperands[3];
- extern FILE *asm_out_file;
xoperands[0] = operands[0];
xoperands[1] = operands[1];
@@ -2644,7 +2645,6 @@
"*
{
rtx xoperands[3];
- extern FILE *asm_out_file;
xoperands[0] = operands[0];
xoperands[1] = operands[1];
@@ -2867,9 +2867,9 @@
(define_insn ""
[(set (match_operand:HI 0 "move_dest_operand"
- "=r,r,r,r,r,Q,!*q,!*f")
+ "=r,r,r,r,r,Q,!*q,!r,!*f")
(match_operand:HI 1 "move_src_operand"
- "r,J,N,K,RQ,rM,!rM,!*fM"))]
+ "r,J,N,K,RQ,rM,!rM,!*q,!*fM"))]
"register_operand (operands[0], HImode)
|| reg_or_0_operand (operands[1], HImode)"
"@
@@ -2880,10 +2880,11 @@
ldh%M1 %1,%0
sth%M0 %r1,%0
mtsar %r1
+ mfctr %sar,%0
fcpy,sgl %f1,%0"
- [(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
+ [(set_attr "type" "move,move,move,shift,load,store,move,move,fpalu")
(set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4,4,4")])
+ (set_attr "length" "4,4,4,4,4,4,4,4,4")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
@@ -2991,9 +2992,9 @@
(define_insn ""
[(set (match_operand:QI 0 "move_dest_operand"
- "=r,r,r,r,r,Q,!*q,!*f")
+ "=r,r,r,r,r,Q,!*q,!r,!*f")
(match_operand:QI 1 "move_src_operand"
- "r,J,N,K,RQ,rM,!rM,!*fM"))]
+ "r,J,N,K,RQ,rM,!rM,!*q,!*fM"))]
"register_operand (operands[0], QImode)
|| reg_or_0_operand (operands[1], QImode)"
"@
@@ -3004,10 +3005,11 @@
ldb%M1 %1,%0
stb%M0 %r1,%0
mtsar %r1
+ {mfctl|mfctl,w} %%sar,%0
fcpy,sgl %f1,%0"
- [(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
+ [(set_attr "type" "move,move,move,shift,load,store,move,move,fpalu")
(set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4,4,4")])
+ (set_attr "length" "4,4,4,4,4,4,4,4,4")])
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=r")
@@ -3958,9 +3960,9 @@
(define_insn ""
[(set (match_operand:DF 0 "move_dest_operand"
- "=!*r,*r,*r,*r,*r,Q,!*q,f,f,T")
+ "=!*r,*r,*r,*r,*r,Q,!*q,!r,f,f,T")
(match_operand:DF 1 "move_src_operand"
- "!*r,J,N,K,RQ,*rM,!*rM,fM,RT,f"))]
+ "!*r,J,N,K,RQ,*rM,!*rM,!*q,fM,RT,f"))]
"(register_operand (operands[0], DFmode)
|| reg_or_0_operand (operands[1], DFmode))
&& !TARGET_SOFT_FLOAT && TARGET_64BIT"
@@ -3972,12 +3974,13 @@
ldd%M1 %1,%0
std%M0 %r1,%0
mtsar %r1
+ {mfctl|mfctl,w} %%sar,%0
fcpy,dbl %f1,%0
fldd%F1 %1,%0
fstd%F0 %1,%0"
- [(set_attr "type" "move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
+ [(set_attr "type" "move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
(set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4,4,4,4,4")])
+ (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4")])
(define_expand "movdi"
@@ -4082,9 +4085,9 @@
(define_insn ""
[(set (match_operand:DI 0 "move_dest_operand"
- "=r,r,r,r,r,r,Q,!*q,!*f,*f,T")
+ "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
(match_operand:DI 1 "move_src_operand"
- "A,r,J,N,K,RQ,rM,!rM,!*fM,RT,*f"))]
+ "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
"(register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))
&& !TARGET_SOFT_FLOAT && TARGET_64BIT"
@@ -4097,12 +4100,13 @@
ldd%M1 %1,%0
std%M0 %r1,%0
mtsar %r1
+ {mfctl|mfctl,w} %%sar,%0
fcpy,dbl %f1,%0
fldd%F1 %1,%0
fstd%F0 %1,%0"
- [(set_attr "type" "load,move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
+ [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
(set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4")])
+ (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
(define_insn ""
[(set (match_operand:DI 0 "indexed_memory_operand" "=R")
diff --git a/gcc/config/pa/pa64-hpux.h b/gcc/config/pa/pa64-hpux.h
index 59288326243..2ae031dc278 100644
--- a/gcc/config/pa/pa64-hpux.h
+++ b/gcc/config/pa/pa64-hpux.h
@@ -63,6 +63,18 @@ Boston, MA 02111-1307, USA. */
isn't available. We also usually need to link with libdld and it's
only available in shared form. */
#undef LIB_SPEC
+#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_GNU_LD)
+#define LIB_SPEC \
+ "%{!shared:\
+ %{!p:%{!pg: -lc %{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\
+ %{p:%{!pg:%{static:%{!mhp-ld:-a shared}%{mhp-ld:-a archive_shared}}\
+ -lprof %{static:-a archive} -lc\
+ %{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\
+ %{pg:%{static:%{!mhp-ld:-a shared}%{mhp-ld:-a archive_shared}}\
+ -lgprof %{static:-a archive} -lc\
+ %{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\
+ /usr/lib/pa20_64/milli.a"
+#else
#define LIB_SPEC \
"%{!shared:\
%{!p:%{!pg: -lc %{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\
@@ -73,6 +85,7 @@ Boston, MA 02111-1307, USA. */
-lgprof %{static:-a archive} -lc\
%{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\
/usr/lib/pa20_64/milli.a"
+#endif
/* Under hpux11, the normal location of the `ld' and `as' programs is the
/usr/ccs/bin directory. */
diff --git a/gcc/config/pa/pa64-regs.h b/gcc/config/pa/pa64-regs.h
index 63f0206aeda..d2f4ace79be 100644
--- a/gcc/config/pa/pa64-regs.h
+++ b/gcc/config/pa/pa64-regs.h
@@ -169,13 +169,11 @@ Boston, MA 02111-1307, USA. */
Registers 0 - 31 remain unchanged.
- Registers 32 - 60 are mapped to 72, 74, 76 ...
-
- Register 88 is mapped to 32. */
+ Registers 32 - 59 are mapped to 72, 74, 76 ...
+ Register 60 is mapped to 32. */
#define DBX_REGISTER_NUMBER(REGNO) \
- ((REGNO) <= 31 ? (REGNO) : \
- ((REGNO) > 31 && (REGNO) <= 60 ? (REGNO - 32) * 2 + 72 : 32))
+ ((REGNO) <= 31 ? (REGNO) : ((REGNO) < 60 ? (REGNO - 32) * 2 + 72 : 32))
/* We must not use the DBX register numbers for the DWARF 2 CFA column
numbers because that maps to numbers beyond FIRST_PSEUDO_REGISTER.
@@ -292,7 +290,7 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
"%fr28", "%fr29", "%fr30", "%fr31", "SAR"}
#define ADDITIONAL_REGISTER_NAMES \
- {{"%cr11",88}}
+ {{"%cr11",60}}
#define FP_SAVED_REG_LAST 49
#define FP_SAVED_REG_FIRST 40
diff --git a/gcc/config/rs6000/aix.h b/gcc/config/rs6000/aix.h
index c530f988e25..88752079772 100644
--- a/gcc/config/rs6000/aix.h
+++ b/gcc/config/rs6000/aix.h
@@ -51,12 +51,37 @@
#define REAL_NM_FILE_NAME "/usr/ucb/nm"
#define USER_LABEL_PREFIX ""
+
/* Don't turn -B into -L if the argument specifies a relative file name. */
#define RELATIVE_PREFIX_NOT_LINKDIR
/* Because of the above, we must have gcc search itself to find libgcc.a. */
#define LINK_LIBGCC_SPECIAL_1
+#define MFWRAP_SPEC " %{static: %{fmudflap|fmudflapth: \
+ -brename:malloc,__wrap_malloc -brename:__real_malloc,malloc \
+ -brename:free,__wrap_free -brename:__real_free,free \
+ -brename:calloc,__wrap_calloc -brename:__real_calloc,calloc \
+ -brename:realloc,__wrap_realloc -brename:__real_realloc,realloc \
+ -brename:mmap,__wrap_mmap -brename:__real_mmap,mmap \
+ -brename:munmap,__wrap_munmap -brename:__real_munmap,munmap \
+ -brename:alloca,__wrap_alloca -brename:__real_alloca,alloca \
+} %{fmudflapth: \
+ -brename:pthread_create,__wrap_pthread_create \
+ -brename:__real_pthread_create,pthread_create \
+ -brename:pthread_join,__wrap_pthread_join \
+ -brename:__real_pthread_join,pthread_join \
+ -brename:pthread_exit,__wrap_pthread_exit \
+ -brename:__real_pthread_exit,pthread_exit \
+}} %{fmudflap|fmudflapth: \
+ -brename:main,__wrap_main -brename:__real_main,main \
+}"
+
+#define MFLIB_SPEC " %{fmudflap: -lmudflap \
+ %{static:%(link_gcc_c_sequence) -lmudflap}} \
+ %{fmudflapth: -lmudflapth -lpthread \
+ %{static:%(link_gcc_c_sequence) -lmudflapth}} "
+
/* Names to predefine in the preprocessor for this target machine. */
#define TARGET_OS_AIX_CPP_BUILTINS() \
do \
diff --git a/gcc/config/rs6000/altivec.h b/gcc/config/rs6000/altivec.h
index 632f03930ff..8b7edb0ece3 100644
--- a/gcc/config/rs6000/altivec.h
+++ b/gcc/config/rs6000/altivec.h
@@ -36,10 +36,17 @@
#error Use the "-maltivec" flag to enable PowerPC AltiVec support
#endif
+/* If __APPLE_ALTIVEC__ is defined, the compiler supports 'vector',
+ 'pixel' and 'bool' as context-sensitive AltiVec keywords (in
+ non-AltiVec contexts, they revert to their original meanings,
+ if any), so we do not need to define them as macros. */
+
+#if !defined(__APPLE_ALTIVEC__)
/* You are allowed to undef these for C++ compatibility. */
#define vector __vector
#define pixel __pixel
#define bool __bool
+#endif
/* Condition register codes for AltiVec predicates. */
@@ -193,11 +200,14 @@ inline void vec_dstt (const float *, int, const int) __attribute__ ((always_inli
inline vector float vec_sld (vector float, vector float, const int) __attribute__ ((always_inline));
inline vector signed int vec_sld (vector signed int, vector signed int, const int) __attribute__ ((always_inline));
inline vector unsigned int vec_sld (vector unsigned int, vector unsigned int, const int) __attribute__ ((always_inline));
+inline vector bool int vec_sld (vector bool int, vector bool int, const int) __attribute__ ((always_inline));
inline vector signed short vec_sld (vector signed short, vector signed short, const int) __attribute__ ((always_inline));
inline vector unsigned short vec_sld (vector unsigned short, vector unsigned short, const int) __attribute__ ((always_inline));
+inline vector bool short vec_sld (vector bool short, vector bool short, const int) __attribute__ ((always_inline));
inline vector pixel vec_sld (vector pixel, vector pixel, const int) __attribute__ ((always_inline));
inline vector signed char vec_sld (vector signed char, vector signed char, const int) __attribute__ ((always_inline));
inline vector unsigned char vec_sld (vector unsigned char, vector unsigned char, const int) __attribute__ ((always_inline));
+inline vector bool char vec_sld (vector bool char, vector bool char, const int) __attribute__ ((always_inline));
inline vector signed char vec_splat (vector signed char, const int) __attribute__ ((always_inline));
inline vector unsigned char vec_splat (vector unsigned char, const int) __attribute__ ((always_inline));
inline vector bool char vec_splat (vector bool char, const int) __attribute__ ((always_inline));
@@ -4189,6 +4199,12 @@ vec_sld (vector unsigned int a1, vector unsigned int a2, const int a3)
return (vector unsigned int) __builtin_altivec_vsldoi_4si ((vector signed int) a1, (vector signed int) a2, a3);
}
+inline vector bool int
+vec_sld (vector bool int a1, vector bool int a2, const int a3)
+{
+ return (vector bool int) __builtin_altivec_vsldoi_4si ((vector signed int) a1, (vector signed int) a2, a3);
+}
+
inline vector signed short
vec_sld (vector signed short a1, vector signed short a2, const int a3)
{
@@ -4201,6 +4217,12 @@ vec_sld (vector unsigned short a1, vector unsigned short a2, const int a3)
return (vector unsigned short) __builtin_altivec_vsldoi_4si ((vector signed int) a1, (vector signed int) a2, a3);
}
+inline vector bool short
+vec_sld (vector bool short a1, vector bool short a2, const int a3)
+{
+ return (vector bool short) __builtin_altivec_vsldoi_4si ((vector signed int) a1, (vector signed int) a2, a3);
+}
+
inline vector pixel
vec_sld (vector pixel a1, vector pixel a2, const int a3)
{
@@ -4219,6 +4241,12 @@ vec_sld (vector unsigned char a1, vector unsigned char a2, const int a3)
return (vector unsigned char) __builtin_altivec_vsldoi_4si ((vector signed int) a1, (vector signed int) a2, a3);
}
+inline vector bool char
+vec_sld (vector bool char a1, vector bool char a2, const int a3)
+{
+ return (vector bool char) __builtin_altivec_vsldoi_4si ((vector signed int) a1, (vector signed int) a2, a3);
+}
+
/* vec_sll */
inline vector signed int
@@ -5893,22 +5921,8 @@ vec_vsubuhs (vector unsigned short a1, vector signed short a2)
return (vector unsigned short) __builtin_altivec_vsubuhs ((vector signed short) a1, (vector signed short) a2);
}
-/* vec_vsubuhs */
-
-inline vector unsigned short
-vec_vsubsuhs (vector signed short a1, vector unsigned short a2)
-{
- return (vector unsigned short) __builtin_altivec_vsubuhs ((vector signed short) a1, (vector signed short) a2);
-}
-
inline vector unsigned short
-vec_vsubsuhs (vector unsigned short a1, vector signed short a2)
-{
- return (vector unsigned short) __builtin_altivec_vsubuhs ((vector signed short) a1, (vector signed short) a2);
-}
-
-inline vector unsigned short
-vec_vsubsuhs (vector unsigned short a1, vector unsigned short a2)
+vec_vsubuhs (vector unsigned short a1, vector unsigned short a2)
{
return (vector unsigned short) __builtin_altivec_vsubuhs ((vector signed short) a1, (vector signed short) a2);
}
@@ -5924,19 +5938,19 @@ vec_vsubsbs (vector signed char a1, vector signed char a2)
/* vec_vsububs */
inline vector unsigned char
-vec_vsubsubs (vector signed char a1, vector unsigned char a2)
+vec_vsububs (vector signed char a1, vector unsigned char a2)
{
return (vector unsigned char) __builtin_altivec_vsububs ((vector signed char) a1, (vector signed char) a2);
}
inline vector unsigned char
-vec_vsubsubs (vector unsigned char a1, vector signed char a2)
+vec_vsububs (vector unsigned char a1, vector signed char a2)
{
return (vector unsigned char) __builtin_altivec_vsububs ((vector signed char) a1, (vector signed char) a2);
}
inline vector unsigned char
-vec_vsubsubs (vector unsigned char a1, vector unsigned char a2)
+vec_vsububs (vector unsigned char a1, vector unsigned char a2)
{
return (vector unsigned char) __builtin_altivec_vsububs ((vector signed char) a1, (vector signed char) a2);
}
@@ -8902,7 +8916,7 @@ __ch (__bin_args_eq (vector unsigned int, (a1), vector unsigned int, (a2)), \
((vector unsigned int) __builtin_altivec_vmrghw ((vector signed int) (a1), (vector signed int) (a2))), \
__ch (__bin_args_eq (vector bool int, (a1), vector bool int, (a2)), \
((vector bool int) __builtin_altivec_vmrghw ((vector signed int) (a1), (vector signed int) (a2))), \
- __builtin_altivec_compiletime_error ("vec_mergeh")))))))))))
+ __builtin_altivec_compiletime_error ("vec_mergeh"))))))))))))
#define vec_vmrghw(a1, a2) \
__ch (__bin_args_eq (vector float, (a1), vector float, (a2)), \
@@ -8950,7 +8964,7 @@ __ch (__bin_args_eq (vector unsigned int, (a1), vector unsigned int, (a2)), \
((vector unsigned int) __builtin_altivec_vmrglw ((vector signed int) (a1), (vector signed int) (a2))), \
__ch (__bin_args_eq (vector bool int, (a1), vector bool int, (a2)), \
((vector bool int) __builtin_altivec_vmrglw ((vector signed int) (a1), (vector signed int) (a2))), \
- __builtin_altivec_compiletime_error ("vec_mergel"))))))))
+ __builtin_altivec_compiletime_error ("vec_mergel"))))))))))))
#define vec_vmrglw(a1, a2) \
__ch (__bin_args_eq (vector float, (a1), vector float, (a2)), \
@@ -9541,17 +9555,23 @@ __ch (__tern_args_eq (vector signed int, (a1), vector signed int, (a2), int, (a3
((vector signed int) __builtin_altivec_vsldoi_4si ((vector signed int) (a1), (vector signed int) (a2), (const int) (a3))), \
__ch (__tern_args_eq (vector unsigned int, (a1), vector unsigned int, (a2), int, (a3)), \
((vector unsigned int) __builtin_altivec_vsldoi_4si ((vector signed int) (a1), (vector signed int) (a2), (const int) (a3))), \
+__ch (__tern_args_eq (vector bool int, (a1), vector bool int, (a2), int, (a3)), \
+ ((vector bool int) __builtin_altivec_vsldoi_4si ((vector signed int) (a1), (vector signed int) (a2), (const int) (a3))), \
__ch (__tern_args_eq (vector signed short, (a1), vector signed short, (a2), int, (a3)), \
((vector signed short) __builtin_altivec_vsldoi_4si ((vector signed int) (a1), (vector signed int) (a2), (const int) (a3))), \
__ch (__tern_args_eq (vector unsigned short, (a1), vector unsigned short, (a2), int, (a3)), \
((vector unsigned short) __builtin_altivec_vsldoi_4si ((vector signed int) (a1), (vector signed int) (a2), (const int) (a3))), \
+__ch (__tern_args_eq (vector bool short, (a1), vector bool short, (a2), int, (a3)), \
+ ((vector bool short) __builtin_altivec_vsldoi_4si ((vector signed int) (a1), (vector signed int) (a2), (const int) (a3))), \
__ch (__tern_args_eq (vector pixel, (a1), vector pixel, (a2), int, (a3)), \
((vector pixel) __builtin_altivec_vsldoi_4si ((vector signed int) (a1), (vector signed int) (a2), (const int) (a3))), \
__ch (__tern_args_eq (vector signed char, (a1), vector signed char, (a2), int, (a3)), \
((vector signed char) __builtin_altivec_vsldoi_4si ((vector signed int) (a1), (vector signed int) (a2), (const int) (a3))), \
__ch (__tern_args_eq (vector unsigned char, (a1), vector unsigned char, (a2), int, (a3)), \
((vector unsigned char) __builtin_altivec_vsldoi_4si ((vector signed int) (a1), (vector signed int) (a2), (const int) (a3))), \
- __builtin_altivec_compiletime_error ("vec_sld")))))))))
+__ch (__tern_args_eq (vector bool char, (a1), vector bool char, (a2), int, (a3)), \
+ ((vector bool char) __builtin_altivec_vsldoi_4si ((vector signed int) (a1), (vector signed int) (a2), (const int) (a3))), \
+ __builtin_altivec_compiletime_error ("vec_sld"))))))))))))
#define vec_sll(a1, a2) \
__ch (__bin_args_eq (vector signed int, (a1), vector unsigned int, (a2)), \
@@ -10977,7 +10997,7 @@ __ch (__bin_args_eq (vector float, (a1), vector float, (a2)), \
__builtin_altivec_compiletime_error ("vec_any_nlt"))
#define vec_any_numeric(a1) \
-__ch (__unn_args_eq (vector float, (a1)), \
+__ch (__un_args_eq (vector float, (a1)), \
__builtin_altivec_vcmpeqfp_p (__CR6_EQ_REV, (a1), (a1)), \
__builtin_altivec_compiletime_error ("vec_any_numeric"))
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index 3e27a1b86c2..eee0d179321 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -999,21 +999,21 @@
[(set (match_operand:V16QI 0 "register_operand" "=v")
(not:V16QI (match_operand:V16QI 1 "register_operand" "v")))]
"TARGET_ALTIVEC"
- "vnot %0,%1"
+ "vnor %0,%1,%1"
[(set_attr "type" "vecsimple")])
(define_insn "one_cmplv8hi2"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(not:V8HI (match_operand:V8HI 1 "register_operand" "v")))]
"TARGET_ALTIVEC"
- "vnot %0,%1"
+ "vnor %0,%1,%1"
[(set_attr "type" "vecsimple")])
(define_insn "one_cmplv4si2"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(not:V4SI (match_operand:V4SI 1 "register_operand" "v")))]
"TARGET_ALTIVEC"
- "vnot %0,%1"
+ "vnor %0,%1,%1"
[(set_attr "type" "vecsimple")])
(define_insn "iorv16qi3"
@@ -1823,13 +1823,13 @@
[(set_attr "type" "vecsimple")])
(define_insn "altivec_dssall"
- [(unspec [(const_int 0)] 188)]
+ [(unspec_volatile [(const_int 0)] 188)]
"TARGET_ALTIVEC"
"dssall"
[(set_attr "type" "vecsimple")])
(define_insn "altivec_dss"
- [(unspec [(match_operand:QI 0 "immediate_operand" "i")] 189)]
+ [(unspec_volatile [(match_operand:QI 0 "immediate_operand" "i")] 189)]
"TARGET_ALTIVEC"
"dss %0"
[(set_attr "type" "vecsimple")])
diff --git a/gcc/config/rs6000/linux.h b/gcc/config/rs6000/linux.h
index 892785d666d..83aef83a387 100644
--- a/gcc/config/rs6000/linux.h
+++ b/gcc/config/rs6000/linux.h
@@ -66,6 +66,11 @@
#define LINK_GCC_C_SEQUENCE_SPEC \
"%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
+/* Use --as-needed -lgcc_s for eh support. */
+#ifdef HAVE_LD_AS_NEEDED
+#define USE_LD_AS_NEEDED 1
+#endif
+
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC GNU/Linux)");
diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
index 4fe419911c8..a63cb5fcff1 100644
--- a/gcc/config/rs6000/linux64.h
+++ b/gcc/config/rs6000/linux64.h
@@ -548,6 +548,11 @@ while (0)
#define LINK_GCC_C_SEQUENCE_SPEC \
"%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
+/* Use --as-needed -lgcc_s for eh support. */
+#ifdef HAVE_LD_AS_NEEDED
+#define USE_LD_AS_NEEDED 1
+#endif
+
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 95a506b4fcc..7078c16e084 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -102,7 +102,7 @@ extern int includes_rshift_p (rtx, rtx);
extern int includes_rldic_lshift_p (rtx, rtx);
extern int includes_rldicr_lshift_p (rtx, rtx);
extern int registers_ok_for_quad_peep (rtx, rtx);
-extern int addrs_ok_for_quad_peep (rtx, rtx);
+extern int mems_ok_for_quad_peep (rtx, rtx);
extern bool gpr_or_gpr_p (rtx, rtx);
extern enum reg_class secondary_reload_class (enum reg_class,
enum machine_mode, rtx);
@@ -116,6 +116,7 @@ extern enum rtx_code rs6000_reverse_condition (enum machine_mode,
extern void rs6000_emit_sCOND (enum rtx_code, rtx);
extern void rs6000_emit_cbranch (enum rtx_code, rtx);
extern char * output_cbranch (rtx, const char *, int, rtx);
+extern char * output_e500_flip_gt_bit (rtx, rtx);
extern rtx rs6000_emit_set_const (rtx, enum machine_mode, rtx, int);
extern int rs6000_emit_cmove (rtx, rtx, rtx, rtx);
extern void rs6000_emit_minmax (rtx, enum rtx_code, rtx, rtx);
@@ -200,6 +201,8 @@ extern int rs6000_memory_move_cost (enum machine_mode, enum reg_class, int);
extern bool rs6000_tls_referenced_p (rtx);
extern int rs6000_tls_symbol_ref (rtx, enum machine_mode);
extern void rs6000_output_dwarf_dtprel (FILE*, int, rtx);
+extern int rs6000_hard_regno_nregs (int, enum machine_mode);
+extern void rs6000_conditional_register_usage (void);
/* Declare functions in rs6000-c.c */
@@ -210,4 +213,5 @@ extern void rs6000_cpu_cpp_builtins (struct cpp_reader *);
char *output_call (rtx, rtx *, int, int);
#endif
+extern bool rs6000_hard_regno_mode_ok_p[][FIRST_PSEUDO_REGISTER];
#endif /* rs6000-protos.h */
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index b3a73648bd7..9f6301b3910 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -215,6 +215,9 @@ const char *rs6000_debug_name;
int rs6000_debug_stack; /* debug stack applications */
int rs6000_debug_arg; /* debug argument handling */
+/* Value is TRUE if register/mode pair is accepatable. */
+bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
+
/* Opaque types. */
static GTY(()) tree opaque_V2SI_type_node;
static GTY(()) tree opaque_V2SF_type_node;
@@ -381,6 +384,7 @@ static void rs6000_init_libfuncs (void);
static void enable_mask_for_builtins (struct builtin_description *, int,
enum rs6000_builtins,
enum rs6000_builtins);
+static tree build_opaque_vector_type (tree, int);
static void spe_init_builtins (void);
static rtx spe_expand_builtin (tree, rtx, bool *);
static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
@@ -644,6 +648,58 @@ static const char alt_reg_names[][8] =
struct gcc_target targetm = TARGET_INITIALIZER;
+
+/* Value is 1 if hard register REGNO can hold a value of machine-mode
+ MODE. */
+static int
+rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
+{
+ /* The GPRs can hold any mode, but values bigger than one register
+ cannot go past R31. */
+ if (INT_REGNO_P (regno))
+ return INT_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1);
+
+ /* The float registers can only hold floating modes and DImode. */
+ if (FP_REGNO_P (regno))
+ return
+ (GET_MODE_CLASS (mode) == MODE_FLOAT
+ && FP_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1))
+ || (GET_MODE_CLASS (mode) == MODE_INT
+ && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD);
+
+ /* The CR register can only hold CC modes. */
+ if (CR_REGNO_P (regno))
+ return GET_MODE_CLASS (mode) == MODE_CC;
+
+ if (XER_REGNO_P (regno))
+ return mode == PSImode;
+
+ /* AltiVec only in AldyVec registers. */
+ if (ALTIVEC_REGNO_P (regno))
+ return ALTIVEC_VECTOR_MODE (mode);
+
+ /* ...but GPRs can hold SIMD data on the SPE in one register. */
+ if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
+ return 1;
+
+ /* We cannot put TImode anywhere except general register and it must be
+ able to fit within the register set. */
+
+ return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
+}
+
+/* Initialize rs6000_hard_regno_mode_ok_p table. */
+static void
+rs6000_init_hard_regno_mode_ok (void)
+{
+ int r, m;
+
+ for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
+ for (m = 0; m < NUM_MACHINE_MODES; ++m)
+ if (rs6000_hard_regno_mode_ok (r, m))
+ rs6000_hard_regno_mode_ok_p[m][r] = true;
+}
+
/* Override command line options. Mostly we process the processor
type and sometimes adjust other TARGET_ options. */
@@ -746,6 +802,9 @@ rs6000_override_options (const char *default_cpu)
| MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
| MASK_MFCRF)
};
+
+ rs6000_init_hard_regno_mode_ok ();
+
set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
#ifdef OS_MISSING_POWERPC64
if (OS_MISSING_POWERPC64)
@@ -893,6 +952,9 @@ rs6000_override_options (const char *default_cpu)
if (TARGET_E500)
{
+ if (TARGET_ALTIVEC)
+ error ("AltiVec and E500 instructions cannot coexist");
+
/* The e500 does not have string instructions, and we set
MASK_STRING above when optimizing for size. */
if ((target_flags & MASK_STRING) != 0)
@@ -1675,7 +1737,7 @@ easy_fp_constant (rtx op, enum machine_mode mode)
abort ();
}
-/* Returns the constant for the splat instrunction, if exists. */
+/* Returns the constant for the splat instruction, if exists. */
static int
easy_vector_splat_const (int cst, enum machine_mode mode)
@@ -2315,23 +2377,6 @@ symbol_ref_operand (rtx op, enum machine_mode mode)
if (mode != VOIDmode && GET_MODE (op) != mode)
return 0;
-#if TARGET_MACHO
- if (GET_CODE (op) == SYMBOL_REF && TARGET_MACHO && MACHOPIC_INDIRECT)
- {
- /* Macho says it has to go through a stub or be local
- when indirect mode. Stubs are considered local. */
- const char *t = XSTR (op, 0);
- /* "&" means that it is it a local defined symbol
- so it is okay to call to. */
- if (t[0] == '&')
- return true;
-
- /* "!T" means that the function is local defined. */
- return (t[0] == '!' && t[1] == 'T');
- }
-#endif
-
-
return (GET_CODE (op) == SYMBOL_REF
&& (DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op)));
}
@@ -2374,10 +2419,6 @@ input_operand (rtx op, enum machine_mode mode)
if (memory_operand (op, mode))
return 1;
- /* Only a tiny bit of handling for CONSTANT_P_RTX is necessary. */
- if (GET_CODE (op) == CONSTANT_P_RTX)
- return 1;
-
/* For floating-point, easy constants are valid. */
if (GET_MODE_CLASS (mode) == MODE_FLOAT
&& CONSTANT_P (op)
@@ -3357,6 +3398,99 @@ rs6000_mode_dependent_address (rtx addr)
return false;
}
+
+/* Return number of consecutive hard regs needed starting at reg REGNO
+ to hold something of mode MODE.
+ This is ordinarily the length in words of a value of mode MODE
+ but can be less for certain modes in special long registers.
+
+ For the SPE, GPRs are 64 bits but only 32 bits are visible in
+ scalar instructions. The upper 32 bits are only available to the
+ SIMD instructions.
+
+ POWER and PowerPC GPRs hold 32 bits worth;
+ PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
+
+int
+rs6000_hard_regno_nregs (int regno, enum machine_mode mode)
+{
+ if (FP_REGNO_P (regno))
+ return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
+
+ if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
+ return (GET_MODE_SIZE (mode) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD;
+
+ if (ALTIVEC_REGNO_P (regno))
+ return
+ (GET_MODE_SIZE (mode) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD;
+
+ return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+}
+
+/* Change register usage conditional on target flags. */
+void
+rs6000_conditional_register_usage (void)
+{
+ int i;
+
+ /* Set MQ register fixed (already call_used) if not POWER
+ architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
+ be allocated. */
+ if (! TARGET_POWER)
+ fixed_regs[64] = 1;
+
+ /* 64-bit AIX reserves GPR13 for thread-private data. */
+ if (TARGET_64BIT)
+ fixed_regs[13] = call_used_regs[13]
+ = call_really_used_regs[13] = 1;
+
+ /* Conditionally disable FPRs. */
+ if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
+ for (i = 32; i < 64; i++)
+ fixed_regs[i] = call_used_regs[i]
+ = call_really_used_regs[i] = 1;
+
+ if (DEFAULT_ABI == ABI_V4
+ && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
+ && flag_pic == 2)
+ fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
+
+ if (DEFAULT_ABI == ABI_V4
+ && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
+ && flag_pic == 1)
+ fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
+ = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
+ = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
+
+ if (DEFAULT_ABI == ABI_DARWIN
+ && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
+ global_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
+ = fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
+ = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
+ = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
+
+ if (TARGET_ALTIVEC)
+ global_regs[VSCR_REGNO] = 1;
+
+ if (TARGET_SPE)
+ {
+ global_regs[SPEFSCR_REGNO] = 1;
+ fixed_regs[FIXED_SCRATCH]
+ = call_used_regs[FIXED_SCRATCH]
+ = call_really_used_regs[FIXED_SCRATCH] = 1;
+ }
+
+ if (! TARGET_ALTIVEC)
+ {
+ for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
+ fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
+ call_really_used_regs[VRSAVE_REGNO] = 1;
+ }
+
+ if (TARGET_ALTIVEC_ABI)
+ for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
+ call_used_regs[i] = call_really_used_regs[i] = 1;
+}
/* Try to output insns to set TARGET equal to the constant C if it can
be done in less than N insns. Do all computations in MODE.
@@ -3615,10 +3749,6 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
|| ! nonimmediate_operand (operands[0], mode)))
goto emit_set;
- /* Handle the case of CONSTANT_P_RTX. */
- if (GET_CODE (operands[1]) == CONSTANT_P_RTX)
- goto emit_set;
-
/* 128-bit constant floating-point values on Darwin should really be
loaded as two parts. */
if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
@@ -4050,11 +4180,11 @@ function_arg_padding (enum machine_mode mode, tree type)
int
function_arg_boundary (enum machine_mode mode, tree type ATTRIBUTE_UNUSED)
{
- if (DEFAULT_ABI == ABI_V4 && (mode == DImode || mode == DFmode))
+ if (DEFAULT_ABI == ABI_V4 && GET_MODE_SIZE (mode) == 8)
return 64;
- else if (SPE_VECTOR_MODE (mode))
- return 64;
- else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
+ else if (SPE_VECTOR_MODE (mode))
+ return 64;
+ else if (ALTIVEC_VECTOR_MODE (mode))
return 128;
else
return PARM_BOUNDARY;
@@ -4080,7 +4210,11 @@ rs6000_arg_size (enum machine_mode mode, tree type)
/* Update the data in CUM to advance over an argument
of mode MODE and data type TYPE.
- (TYPE is null for libcalls where that information may not be available.) */
+ (TYPE is null for libcalls where that information may not be available.)
+
+ Note that for args passed by reference, function_arg will be called
+ with MODE and TYPE set to that of the pointer to the arg, not the arg
+ itself. */
void
function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
@@ -4090,6 +4224,8 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
{
+ bool stack = false;
+
if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
{
cum->vregno++;
@@ -4097,12 +4233,18 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
error ("Cannot pass argument in vector register because"
" altivec instructions are disabled, use -maltivec"
" to enable them.");
+
+ /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
+ even if it is going to be passed in a vector register.
+ Darwin does the same for variable-argument functions. */
+ if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
+ || (cum->stdarg && DEFAULT_ABI != ABI_V4))
+ stack = true;
}
- /* PowerPC64 Linux and AIX allocates GPRs for a vector argument
- even if it is going to be passed in a vector register.
- Darwin does the same for variable-argument functions. */
- if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
- || (cum->stdarg && DEFAULT_ABI != ABI_V4))
+ else
+ stack = true;
+
+ if (stack)
{
int align;
@@ -4114,7 +4256,7 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
aligned. Space for GPRs is reserved even if the argument
will be passed in memory. */
if (TARGET_32BIT)
- align = ((6 - (cum->words & 3)) & 3);
+ align = (2 - cum->words) & 3;
else
align = cum->words & 1;
cum->words += align + rs6000_arg_size (mode, type);
@@ -4149,25 +4291,21 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
}
else
{
- int n_words;
+ int n_words = rs6000_arg_size (mode, type);
int gregno = cum->sysv_gregno;
- /* Aggregates and IEEE quad get passed by reference. */
- if ((type && AGGREGATE_TYPE_P (type))
- || mode == TFmode)
- n_words = 1;
- else
- n_words = rs6000_arg_size (mode, type);
-
- /* Long long and SPE vectors are put in odd registers. */
- if (n_words == 2 && (gregno & 1) == 0)
- gregno += 1;
+ /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
+ (r7,r8) or (r9,r10). As does any other 2 word item such
+ as complex int due to a historical mistake. */
+ if (n_words == 2)
+ gregno += (1 - gregno) & 1;
- /* Long long and SPE vectors are not split between registers
- and stack. */
+ /* Multi-reg args are not split between registers and stack. */
if (gregno + n_words - 1 > GP_ARG_MAX_REG)
{
- /* Long long is aligned on the stack. */
+ /* Long long and SPE vectors are aligned on the stack.
+ So are other 2 word items such as complex int due to
+ a historical mistake. */
if (n_words == 2)
cum->words += cum->words & 1;
cum->words += n_words;
@@ -4191,10 +4329,16 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
}
else
{
- int align = (TARGET_32BIT && (cum->words & 1) != 0
- && function_arg_boundary (mode, type) == 64) ? 1 : 0;
+ int n_words = rs6000_arg_size (mode, type);
+ int align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
- cum->words += align + rs6000_arg_size (mode, type);
+ /* The simple alignment calculation here works because
+ function_arg_boundary / PARM_BOUNDARY will only be 1 or 2.
+ If we ever want to handle alignments larger than 8 bytes for
+ 32-bit or 16 bytes for 64-bit, then we'll need to take into
+ account the offset to the start of the parm save area. */
+ align &= cum->words;
+ cum->words += align + n_words;
if (GET_MODE_CLASS (mode) == MODE_FLOAT
&& TARGET_HARD_FLOAT && TARGET_FPRS)
@@ -4329,8 +4473,28 @@ rs6000_mixed_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ align_words),
const0_rtx)));
}
- else if (mode == BLKmode && align_words <= (GP_ARG_NUM_REG - 1))
- {
+ else if (ALTIVEC_VECTOR_MODE (mode) && align_words == GP_ARG_NUM_REG - 2)
+ {
+ /* Varargs vector regs must be saved in R9-R10. */
+ return gen_rtx_PARALLEL (mode,
+ gen_rtvec (3,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ NULL_RTX, const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words),
+ const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words + 1),
+ GEN_INT (4))));
+ }
+ else if ((mode == BLKmode || ALTIVEC_VECTOR_MODE (mode))
+ && align_words <= (GP_ARG_NUM_REG - 1))
+ {
+ /* AltiVec vector regs are saved in R5-R8. */
int k;
int size = int_size_in_bytes (type);
int no_units = ((size - 1) / 4) + 1;
@@ -4347,9 +4511,8 @@ rs6000_mixed_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ align_words + k),
k == 0 ? const0_rtx : GEN_INT (k*4));
- return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k, rtlvec));
- }
-
+ return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rtlvec));
+ }
return NULL_RTX;
}
@@ -4374,7 +4537,11 @@ rs6000_mixed_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
both an FP and integer register (or possibly FP reg and stack). Library
functions (when CALL_LIBCALL is set) always have the proper types for args,
so we can pass the FP value just in one register. emit_library_function
- doesn't support PARALLEL anyway. */
+ doesn't support PARALLEL anyway.
+
+ Note that for args passed by reference, function_arg will be called
+ with MODE and TYPE set to that of the pointer to the arg, not the arg
+ itself. */
struct rtx_def *
function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
@@ -4450,7 +4617,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
they just have to start on an even word, since the parameter
save area is 16-byte aligned. */
if (TARGET_32BIT)
- align = ((6 - (cum->words & 3)) & 3);
+ align = (2 - cum->words) & 3;
else
align = cum->words & 1;
align_words = cum->words + align;
@@ -4467,7 +4634,11 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
is either wholly in GPRs or half in GPRs and half not. */
part_mode = DImode;
- return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
+ if (TARGET_32BIT
+ && (TARGET_POWERPC64 || (align_words == GP_ARG_NUM_REG - 2)))
+ return rs6000_mixed_function_arg (cum, part_mode, type, align_words);
+ else
+ return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
}
}
else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode))
@@ -4484,21 +4655,16 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
}
else
{
- int n_words;
+ int n_words = rs6000_arg_size (mode, type);
int gregno = cum->sysv_gregno;
- /* Aggregates and IEEE quad get passed by reference. */
- if ((type && AGGREGATE_TYPE_P (type))
- || mode == TFmode)
- n_words = 1;
- else
- n_words = rs6000_arg_size (mode, type);
-
- /* Long long and SPE vectors are put in odd registers. */
- if (n_words == 2 && (gregno & 1) == 0)
- gregno += 1;
+ /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
+ (r7,r8) or (r9,r10). As does any other 2 word item such
+ as complex int due to a historical mistake. */
+ if (n_words == 2)
+ gregno += (1 - gregno) & 1;
- /* Long long does not split between registers and stack. */
+ /* Multi-reg args are not split between registers and stack. */
if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
return gen_rtx_REG (mode, gregno);
else
@@ -4507,16 +4673,8 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
}
else
{
- int align = (TARGET_32BIT && (cum->words & 1) != 0
- && function_arg_boundary (mode, type) == 64) ? 1 : 0;
- int align_words = cum->words + align;
-
- if (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
- return NULL_RTX;
-
- if (TARGET_32BIT && TARGET_POWERPC64
- && (mode == DImode || mode == BLKmode))
- return rs6000_mixed_function_arg (cum, mode, type, align_words);
+ int align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
+ int align_words = cum->words + (cum->words & align);
if (USE_FP_FOR_ARG_P (cum, mode, type))
{
@@ -4585,7 +4743,13 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
return gen_rtx_PARALLEL (mode, gen_rtvec_v (n, r));
}
else if (align_words < GP_ARG_NUM_REG)
- return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
+ {
+ if (TARGET_32BIT && TARGET_POWERPC64
+ && (mode == DImode || mode == BLKmode))
+ return rs6000_mixed_function_arg (cum, mode, type, align_words);
+
+ return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
+ }
else
return NULL_RTX;
}
@@ -4632,7 +4796,10 @@ function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
the argument itself. The pointer is passed in whatever way is
appropriate for passing a pointer to that type.
- Under V.4, structures and unions are passed by reference.
+ Under V.4, aggregates and long double are passed by reference.
+
+ As an extension to all 32-bit ABIs, AltiVec vectors are passed by
+ reference unless the AltiVec vector extension ABI is in force.
As an extension to all ABIs, variable sized types are passed by
reference. */
@@ -4642,16 +4809,18 @@ function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
enum machine_mode mode ATTRIBUTE_UNUSED,
tree type, int named ATTRIBUTE_UNUSED)
{
- if (DEFAULT_ABI == ABI_V4
- && ((type && AGGREGATE_TYPE_P (type))
- || mode == TFmode))
+ if ((DEFAULT_ABI == ABI_V4
+ && ((type && AGGREGATE_TYPE_P (type))
+ || mode == TFmode))
+ || (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
+ || (type && int_size_in_bytes (type) < 0))
{
if (TARGET_DEBUG_ARG)
- fprintf (stderr, "function_arg_pass_by_reference: aggregate\n");
+ fprintf (stderr, "function_arg_pass_by_reference\n");
return 1;
}
- return type && int_size_in_bytes (type) < 0;
+ return 0;
}
static void
@@ -4898,11 +5067,16 @@ rs6000_va_arg (tree valist, tree type)
tree gpr, fpr, ovf, sav, reg, t, u;
int indirect_p, size, rsize, n_reg, sav_ofs, sav_scale;
rtx lab_false, lab_over, addr_rtx, r;
+ int align;
if (DEFAULT_ABI != ABI_V4)
{
- /* Variable sized types are passed by reference. */
- if (int_size_in_bytes (type) < 0)
+ /* Variable sized types are passed by reference, as are AltiVec
+ vectors when 32-bit and not using the AltiVec ABI extension. */
+ if (int_size_in_bytes (type) < 0
+ || (TARGET_32BIT
+ && !TARGET_ALTIVEC_ABI
+ && ALTIVEC_VECTOR_MODE (TYPE_MODE (type))))
{
u = build_pointer_type (type);
@@ -4971,10 +5145,14 @@ rs6000_va_arg (tree valist, tree type)
size = int_size_in_bytes (type);
rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+ align = 1;
- if (AGGREGATE_TYPE_P (type) || TYPE_MODE (type) == TFmode)
+ if (AGGREGATE_TYPE_P (type)
+ || TYPE_MODE (type) == TFmode
+ || (!TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type))))
{
- /* Aggregates and long doubles are passed by reference. */
+ /* Aggregates, long doubles, and AltiVec vectors are passed by
+ reference. */
indirect_p = 1;
reg = gpr;
n_reg = 1;
@@ -4983,7 +5161,8 @@ rs6000_va_arg (tree valist, tree type)
size = UNITS_PER_WORD;
rsize = 1;
}
- else if (FLOAT_TYPE_P (type) && TARGET_HARD_FLOAT && TARGET_FPRS)
+ else if (TARGET_HARD_FLOAT && TARGET_FPRS
+ && (TYPE_MODE (type) == SFmode || TYPE_MODE (type) == DFmode))
{
/* FP args go in FP registers, if present. */
indirect_p = 0;
@@ -4991,6 +5170,8 @@ rs6000_va_arg (tree valist, tree type)
n_reg = 1;
sav_ofs = 8*4;
sav_scale = 8;
+ if (TYPE_MODE (type) == DFmode)
+ align = 8;
}
else
{
@@ -5000,38 +5181,43 @@ rs6000_va_arg (tree valist, tree type)
n_reg = rsize;
sav_ofs = 0;
sav_scale = 4;
+ if (n_reg == 2)
+ align = 8;
}
/* Pull the value out of the saved registers.... */
- lab_false = gen_label_rtx ();
- lab_over = gen_label_rtx ();
+ lab_over = NULL_RTX;
addr_rtx = gen_reg_rtx (Pmode);
- /* AltiVec vectors never go in registers. */
- if (!TARGET_ALTIVEC || TREE_CODE (type) != VECTOR_TYPE)
+ /* AltiVec vectors never go in registers when -mabi=altivec. */
+ if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
+ align = 16;
+ else
{
- TREE_THIS_VOLATILE (reg) = 1;
- emit_cmp_and_jump_insns
- (expand_expr (reg, NULL_RTX, QImode, EXPAND_NORMAL),
- GEN_INT (8 - n_reg + 1), GE, const1_rtx, QImode, 1,
- lab_false);
+ lab_false = gen_label_rtx ();
+ lab_over = gen_label_rtx ();
- /* Long long is aligned in the registers. */
- if (n_reg > 1)
+ /* Long long and SPE vectors are aligned in the registers.
+ As are any other 2 gpr item such as complex int due to a
+ historical mistake. */
+ u = reg;
+ if (n_reg == 2)
{
u = build (BIT_AND_EXPR, TREE_TYPE (reg), reg,
build_int_2 (n_reg - 1, 0));
- u = build (PLUS_EXPR, TREE_TYPE (reg), reg, u);
- u = build (MODIFY_EXPR, TREE_TYPE (reg), reg, u);
+ u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, u);
TREE_SIDE_EFFECTS (u) = 1;
- expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
+ emit_cmp_and_jump_insns
+ (expand_expr (u, NULL_RTX, QImode, EXPAND_NORMAL),
+ GEN_INT (8 - n_reg + 1), GE, const1_rtx, QImode, 1,
+ lab_false);
+
+ t = sav;
if (sav_ofs)
t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
- else
- t = sav;
u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg,
build_int_2 (n_reg, 0));
@@ -5052,40 +5238,18 @@ rs6000_va_arg (tree valist, tree type)
emit_jump_insn (gen_jump (lab_over));
emit_barrier ();
- }
- emit_label (lab_false);
+ emit_label (lab_false);
+ }
/* ... otherwise out of the overflow area. */
- /* Make sure we don't find reg 7 for the next int arg.
-
- All AltiVec vectors go in the overflow area. So in the AltiVec
- case we need to get the vectors from the overflow area, but
- remember where the GPRs and FPRs are. */
- if (n_reg > 1 && (TREE_CODE (type) != VECTOR_TYPE
- || !TARGET_ALTIVEC))
- {
- t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, build_int_2 (8, 0));
- TREE_SIDE_EFFECTS (t) = 1;
- expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
- }
-
/* Care for on-stack alignment if needed. */
- if (rsize <= 1)
- t = ovf;
- else
+ t = ovf;
+ if (align != 1)
{
- int align;
-
- /* AltiVec vectors are 16 byte aligned. */
- if (TARGET_ALTIVEC && TREE_CODE (type) == VECTOR_TYPE)
- align = 15;
- else
- align = 7;
-
- t = build (PLUS_EXPR, TREE_TYPE (ovf), ovf, build_int_2 (align, 0));
- t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align-1, -1));
+ t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (align - 1, 0));
+ t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align, -1));
}
t = save_expr (t);
@@ -5098,7 +5262,8 @@ rs6000_va_arg (tree valist, tree type)
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
- emit_label (lab_over);
+ if (lab_over)
+ emit_label (lab_over);
if (indirect_p)
{
@@ -5546,7 +5711,7 @@ static struct builtin_description bdesc_1arg[] =
{ 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
{ 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
{ 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
- { 0, CODE_FOR_spe_evneg, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
+ { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
{ 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
{ 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
{ 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
@@ -6645,6 +6810,14 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
return NULL_RTX;
}
+static tree
+build_opaque_vector_type (tree node, int nunits)
+{
+ node = copy_node (node);
+ TYPE_MAIN_VARIANT (node) = node;
+ return build_vector_type (node, nunits);
+}
+
static void
rs6000_init_builtins (void)
{
@@ -6660,8 +6833,8 @@ rs6000_init_builtins (void)
unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
- opaque_V2SI_type_node = copy_node (V2SI_type_node);
- opaque_V2SF_type_node = copy_node (V2SF_type_node);
+ opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
+ opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
/* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
@@ -8608,10 +8781,7 @@ includes_rldicr_lshift_p (rtx shiftop, rtx andop)
}
/* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
- for lfq and stfq insns.
-
- Note reg1 and reg2 *must* be hard registers. To be sure we will
- abort if we are passed pseudo registers. */
+ for lfq and stfq insns iff the registers are hard registers. */
int
registers_ok_for_quad_peep (rtx reg1, rtx reg2)
@@ -8619,6 +8789,11 @@ registers_ok_for_quad_peep (rtx reg1, rtx reg2)
/* We might have been passed a SUBREG. */
if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
return 0;
+
+ /* We might have been passed non floating point registers. */
+ if (!FP_REGNO_P (REGNO (reg1))
+ || !FP_REGNO_P (REGNO (reg2)))
+ return 0;
return (REGNO (reg1) == REGNO (reg2) - 1);
}
@@ -8628,11 +8803,19 @@ registers_ok_for_quad_peep (rtx reg1, rtx reg2)
(addr2 == addr1 + 8). */
int
-addrs_ok_for_quad_peep (rtx addr1, rtx addr2)
+mems_ok_for_quad_peep (rtx mem1, rtx mem2)
{
+ rtx addr1, addr2;
unsigned int reg1;
int offset1;
+ /* The mems cannot be volatile. */
+ if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
+ return 0;
+
+ addr1 = XEXP (mem1, 0);
+ addr2 = XEXP (mem2, 0);
+
/* Extract an offset (if used) from the first addr. */
if (GET_CODE (addr1) == PLUS)
{
@@ -8798,14 +8981,8 @@ ccr_bit (rtx op, int scc_p)
switch (code)
{
case NE:
- if (TARGET_E500 && !TARGET_FPRS
- && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
- return base_bit + 1;
return scc_p ? base_bit + 3 : base_bit + 2;
case EQ:
- if (TARGET_E500 && !TARGET_FPRS
- && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
- return base_bit + 1;
return base_bit + 2;
case GT: case GTU: case UNLE:
return base_bit + 1;
@@ -9025,6 +9202,26 @@ print_operand (FILE *file, rtx x, int code)
/* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
output_operand. */
+ case 'c':
+ /* X is a CR register. Print the number of the GT bit of the CR. */
+ if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
+ output_operand_lossage ("invalid %%E value");
+ else
+ fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
+ return;
+
+ case 'D':
+ /* Like 'J' but get to the GT bit. */
+ if (GET_CODE (x) != REG)
+ abort ();
+
+ /* Bit 1 is GT bit. */
+ i = 4 * (REGNO (x) - CR0_REGNO) + 1;
+
+ /* If we want bit 31, write a shift count of zero, not 32. */
+ fprintf (file, "%d", i == 31 ? 0 : i + 1);
+ return;
+
case 'E':
/* X is a CR register. Print the number of the EQ bit of the CR */
if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
@@ -9493,7 +9690,17 @@ print_operand (FILE *file, rtx x, int code)
break;
}
}
- if (TARGET_AIX)
+ /* For macho, we need to check it see if we need a stub. */
+ if (TARGET_MACHO)
+ {
+ const char *name = XSTR (x, 0);
+#if TARGET_MACHO
+ if (machopic_classify_name (name) == MACHOPIC_UNDEFINED_FUNCTION)
+ name = machopic_stub_name (name);
+#endif
+ assemble_name (file, name);
+ }
+ else if (TARGET_AIX)
RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
else
assemble_name (file, XSTR (x, 0));
@@ -9812,36 +10019,26 @@ rs6000_generate_compare (enum rtx_code code)
{
rtx cmp, or1, or2, or_result, compare_result2;
+ /* Note: The E500 comparison instructions set the GT bit (x +
+ 1), on success. This explains the mess. */
+
switch (code)
{
- case EQ:
- case UNEQ:
- case NE:
- case LTGT:
+ case EQ: case UNEQ: case NE: case LTGT:
cmp = flag_finite_math_only
? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1)
: gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1);
break;
- case GT:
- case GTU:
- case UNGT:
- case UNGE:
- case GE:
- case GEU:
+ case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
cmp = flag_finite_math_only
? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1)
: gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1);
break;
- case LT:
- case LTU:
- case UNLT:
- case UNLE:
- case LE:
- case LEU:
+ case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
cmp = flag_finite_math_only
? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1)
@@ -9855,8 +10052,6 @@ rs6000_generate_compare (enum rtx_code code)
/* Synthesize LE and GE from LT/GT || EQ. */
if (code == LE || code == GE || code == LEU || code == GEU)
{
- /* Synthesize GE/LE frome GT/LT || EQ. */
-
emit_insn (cmp);
switch (code)
@@ -9881,23 +10076,8 @@ rs6000_generate_compare (enum rtx_code code)
rs6000_compare_op1);
emit_insn (cmp);
- /* The MC8540 FP compare instructions set the CR bits
- differently than other PPC compare instructions. For
- that matter, there is no generic test instruction, but a
- testgt, testlt, and testeq. For a true condition, bit 2
- is set (x1xx) in the CR. Following the traditional CR
- values:
-
- LT GT EQ OV
- bit3 bit2 bit1 bit0
-
- ... bit 2 would be a GT CR alias, so later on we
- look in the GT bits for the branch instructions.
- However, we must be careful to emit correct RTL in
- the meantime, so optimizations don't get confused. */
-
- or1 = gen_rtx_NE (SImode, compare_result, const0_rtx);
- or2 = gen_rtx_NE (SImode, compare_result2, const0_rtx);
+ or1 = gen_rtx_GT (SImode, compare_result, const0_rtx);
+ or2 = gen_rtx_GT (SImode, compare_result2, const0_rtx);
/* OR them together. */
cmp = gen_rtx_SET (VOIDmode, or_result,
@@ -9909,16 +10089,10 @@ rs6000_generate_compare (enum rtx_code code)
}
else
{
- /* We only care about 1 bit (x1xx), so map everything to NE to
- maintain rtl sanity. We'll get to the right bit (x1xx) at
- code output time. */
if (code == NE || code == LTGT)
- /* Do the inverse here because we have no cmpne
- instruction. We use the cmpeq instruction and expect
- to get a 0 instead. */
- code = EQ;
- else
code = NE;
+ else
+ code = EQ;
}
emit_insn (cmp);
@@ -9983,6 +10157,24 @@ rs6000_emit_sCOND (enum rtx_code code, rtx result)
condition_rtx = rs6000_generate_compare (code);
cond_code = GET_CODE (condition_rtx);
+ if (TARGET_E500 && rs6000_compare_fp_p
+ && !TARGET_FPRS && TARGET_HARD_FLOAT)
+ {
+ rtx t;
+
+ PUT_MODE (condition_rtx, SImode);
+ t = XEXP (condition_rtx, 0);
+
+ if (cond_code != NE && cond_code != EQ)
+ abort ();
+
+ if (cond_code == NE)
+ emit_insn (gen_e500_flip_gt_bit (t, t));
+
+ emit_insn (gen_move_from_CR_gt_bit (result, t));
+ return;
+ }
+
if (cond_code == NE
|| cond_code == GE || cond_code == LE
|| cond_code == GEU || cond_code == LEU
@@ -10079,9 +10271,9 @@ output_cbranch (rtx op, const char *label, int reversed, rtx insn)
to the GT bit. */
if (code == EQ)
/* Opposite of GT. */
- code = UNLE;
- else if (code == NE)
code = GT;
+ else if (code == NE)
+ code = UNLE;
else
abort ();
}
@@ -10160,6 +10352,25 @@ output_cbranch (rtx op, const char *label, int reversed, rtx insn)
return string;
}
+/* Return the string to flip the GT bit on a CR. */
+char *
+output_e500_flip_gt_bit (rtx dst, rtx src)
+{
+ static char string[64];
+ int a, b;
+
+ if (GET_CODE (dst) != REG || ! CR_REGNO_P (REGNO (dst))
+ || GET_CODE (src) != REG || ! CR_REGNO_P (REGNO (src)))
+ abort ();
+
+ /* GT bit. */
+ a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
+ b = 4 * (REGNO (src) - CR0_REGNO) + 1;
+
+ sprintf (string, "crnot %d,%d", a, b);
+ return string;
+}
+
/* Emit a conditional move: move TRUE_COND to DEST if OP of the
operands of the last comparison is nonzero/true, FALSE_COND if it
is zero/false. Return 0 if the hardware has no such operation. */
@@ -10748,7 +10959,7 @@ rs6000_stack_info (void)
rs6000_stack_t *info_ptr = &info;
int reg_size = TARGET_32BIT ? 4 : 8;
int ehrd_size;
- HOST_WIDE_INT total_raw_size;
+ HOST_WIDE_INT non_fixed_size;
/* Zero all fields portably. */
info = zero_info;
@@ -10858,7 +11069,7 @@ rs6000_stack_info (void)
info_ptr->varargs_size = RS6000_VARARGS_AREA;
info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size,
- 8);
+ TARGET_ALTIVEC ? 16 : 8);
if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
info_ptr->spe_gp_size = 8 * (32 - info_ptr->first_gp_reg_save);
@@ -10979,14 +11190,13 @@ rs6000_stack_info (void)
(TARGET_ALTIVEC_ABI || ABI_DARWIN)
? 16 : 8);
- total_raw_size = (info_ptr->vars_size
+ non_fixed_size = (info_ptr->vars_size
+ info_ptr->parm_size
+ info_ptr->save_size
- + info_ptr->varargs_size
- + info_ptr->fixed_size);
+ + info_ptr->varargs_size);
- info_ptr->total_size =
- RS6000_ALIGN (total_raw_size, ABI_STACK_BOUNDARY / BITS_PER_UNIT);
+ info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
+ ABI_STACK_BOUNDARY / BITS_PER_UNIT);
/* Determine if we need to allocate any stack frame:
@@ -11004,7 +11214,7 @@ rs6000_stack_info (void)
info_ptr->push_p = 1;
else if (DEFAULT_ABI == ABI_V4)
- info_ptr->push_p = total_raw_size > info_ptr->fixed_size;
+ info_ptr->push_p = non_fixed_size != 0;
else if (frame_pointer_needed)
info_ptr->push_p = 1;
@@ -11013,8 +11223,7 @@ rs6000_stack_info (void)
info_ptr->push_p = 1;
else
- info_ptr->push_p
- = total_raw_size - info_ptr->fixed_size > (TARGET_32BIT ? 220 : 288);
+ info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
/* Zero offsets if we're not saving those registers. */
if (info_ptr->fp_size == 0)
@@ -11850,7 +12059,7 @@ generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
need an unspec use/set of the register. */
for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
- if (info->vrsave_mask != 0 && ALTIVEC_REG_BIT (i) != 0)
+ if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
{
if (!epiloguep || call_used_regs [i])
clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
@@ -12495,7 +12704,7 @@ rs6000_emit_epilogue (int sibcall)
}
/* Restore VRSAVE if needed. */
- if (TARGET_ALTIVEC_ABI && TARGET_ALTIVEC_VRSAVE
+ if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
&& info->vrsave_mask != 0)
{
rtx addr, mem, reg;
@@ -12908,7 +13117,8 @@ rs6000_output_function_epilogue (FILE *file,
Java is 13. Objective-C is 14. */
if (! strcmp (language_string, "GNU C"))
i = 0;
- else if (! strcmp (language_string, "GNU F77"))
+ else if (! strcmp (language_string, "GNU F77")
+ || ! strcmp (language_string, "GNU F95"))
i = 1;
else if (! strcmp (language_string, "GNU Pascal"))
i = 2;
@@ -13903,7 +14113,7 @@ output_function_profiler (FILE *file, int labelno)
asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
- if (current_function_needs_context)
+ if (cfun->static_chain_decl != NULL)
{
asm_fprintf (file, "\tstd %s,24(%s)\n",
reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
@@ -14958,6 +15168,9 @@ rs6000_handle_altivec_attribute (tree *node, tree name, tree args,
default: break;
}
+ if (result && result != type && TYPE_READONLY (type))
+ result = build_qualified_type (result, TYPE_QUAL_CONST);
+
*no_add_attrs = true; /* No need to hang on to the attribute. */
if (!result)
@@ -16140,7 +16353,7 @@ rs6000_complex_function_value (enum machine_mode mode)
enum machine_mode inner = GET_MODE_INNER (mode);
unsigned int inner_bytes = GET_MODE_SIZE (inner);
- if (FLOAT_MODE_P (mode))
+ if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
regno = FP_ARG_RETURN;
else
{
@@ -16198,13 +16411,13 @@ rs6000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
else
mode = TYPE_MODE (valtype);
- if (TREE_CODE (valtype) == REAL_TYPE && TARGET_HARD_FLOAT && TARGET_FPRS)
+ if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS)
regno = FP_ARG_RETURN;
else if (TREE_CODE (valtype) == COMPLEX_TYPE
- && TARGET_HARD_FLOAT
&& targetm.calls.split_complex_arg)
return rs6000_complex_function_value (mode);
- else if (TREE_CODE (valtype) == VECTOR_TYPE && TARGET_ALTIVEC)
+ else if (TREE_CODE (valtype) == VECTOR_TYPE
+ && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
regno = ALTIVEC_ARG_RETURN;
else
regno = GP_ARG_RETURN;
@@ -16222,7 +16435,8 @@ rs6000_libcall_value (enum machine_mode mode)
if (GET_MODE_CLASS (mode) == MODE_FLOAT
&& TARGET_HARD_FLOAT && TARGET_FPRS)
regno = FP_ARG_RETURN;
- else if (ALTIVEC_VECTOR_MODE (mode))
+ else if (ALTIVEC_VECTOR_MODE (mode)
+ && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
regno = ALTIVEC_ARG_RETURN;
else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
return rs6000_complex_function_value (mode);
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 7590dfd8717..d08aca9b888 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -718,7 +718,8 @@ extern const char *rs6000_warn_altivec_long_switch;
#define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
/* Boundary (in *bits*) on which stack pointer should be aligned. */
-#define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
+#define STACK_BOUNDARY \
+ ((TARGET_32BIT && !TARGET_ALTIVEC && !TARGET_ALTIVEC_ABI) ? 64 : 128)
/* Allocation boundary (in *bits*) for the code of a function. */
#define FUNCTION_BOUNDARY 32
@@ -997,25 +998,9 @@ extern const char *rs6000_warn_altivec_long_switch;
#define ALTIVEC_REGNO_P(N) ((N) >= FIRST_ALTIVEC_REGNO && (N) <= LAST_ALTIVEC_REGNO)
/* Return number of consecutive hard regs needed starting at reg REGNO
- to hold something of mode MODE.
- This is ordinarily the length in words of a value of mode MODE
- but can be less for certain modes in special long registers.
-
- For the SPE, GPRs are 64 bits but only 32 bits are visible in
- scalar instructions. The upper 32 bits are only available to the
- SIMD instructions.
-
- POWER and PowerPC GPRs hold 32 bits worth;
- PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
-
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- (FP_REGNO_P (REGNO) \
- ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
- : (SPE_SIMD_REGNO_P (REGNO) && TARGET_SPE && SPE_VECTOR_MODE (MODE)) \
- ? ((GET_MODE_SIZE (MODE) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD) \
- : ALTIVEC_REGNO_P (REGNO) \
- ? ((GET_MODE_SIZE (MODE) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD) \
- : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+ to hold something of mode MODE. */
+
+#define HARD_REGNO_NREGS(REGNO, MODE) rs6000_hard_regno_nregs ((REGNO), (MODE))
#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \
((TARGET_32BIT && TARGET_POWERPC64 \
@@ -1042,26 +1027,10 @@ extern const char *rs6000_warn_altivec_long_switch;
((TARGET_SPE && SPE_VECTOR_MODE (MODE)) \
|| (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (MODE)))
-/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
- For POWER and PowerPC, the GPRs can hold any mode, but values bigger
- than one register cannot go past R31. The float
- registers only can hold floating modes and DImode, and CR register only
- can hold CC modes. We cannot put TImode anywhere except general
- register and it must be able to fit within the register set. */
-
-#define HARD_REGNO_MODE_OK(REGNO, MODE) \
- (INT_REGNO_P (REGNO) ? \
- INT_REGNO_P (REGNO + HARD_REGNO_NREGS (REGNO, MODE) - 1) \
- : FP_REGNO_P (REGNO) ? \
- ((GET_MODE_CLASS (MODE) == MODE_FLOAT \
- && FP_REGNO_P (REGNO + HARD_REGNO_NREGS (REGNO, MODE) - 1)) \
- || (GET_MODE_CLASS (MODE) == MODE_INT \
- && GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD)) \
- : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE) \
- : SPE_SIMD_REGNO_P (REGNO) && TARGET_SPE && SPE_VECTOR_MODE (MODE) ? 1 \
- : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC \
- : XER_REGNO_P (REGNO) ? (MODE) == PSImode \
- : GET_MODE_SIZE (MODE) <= UNITS_PER_WORD)
+/* Value is TRUE if hard register REGNO can hold a value of
+ machine-mode MODE. */
+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
+ rs6000_hard_regno_mode_ok_p[(int)(MODE)][REGNO]
/* Value is 1 if it is a good idea to tie two pseudo registers
when one has mode MODE1 and one has mode MODE2.
@@ -1128,59 +1097,10 @@ extern const char *rs6000_warn_altivec_long_switch;
#define FIXED_SCRATCH (TARGET_SPE ? 14 : 11)
-/* Define this macro to change register usage conditional on target flags.
- Set MQ register fixed (already call_used) if not POWER architecture
- (RIOS1, RIOS2, RSC, and PPC601) so that it will not be allocated.
- 64-bit AIX reserves GPR13 for thread-private data.
- Conditionally disable FPRs. */
+/* Define this macro to change register usage conditional on target
+ flags. */
-#define CONDITIONAL_REGISTER_USAGE \
-{ \
- int i; \
- if (! TARGET_POWER) \
- fixed_regs[64] = 1; \
- if (TARGET_64BIT) \
- fixed_regs[13] = call_used_regs[13] \
- = call_really_used_regs[13] = 1; \
- if (TARGET_SOFT_FLOAT || !TARGET_FPRS) \
- for (i = 32; i < 64; i++) \
- fixed_regs[i] = call_used_regs[i] \
- = call_really_used_regs[i] = 1; \
- if (DEFAULT_ABI == ABI_V4 \
- && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM \
- && flag_pic == 2) \
- fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; \
- if (DEFAULT_ABI == ABI_V4 \
- && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM \
- && flag_pic == 1) \
- fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] \
- = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] \
- = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; \
- if (DEFAULT_ABI == ABI_DARWIN \
- && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
- global_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] \
- = fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] \
- = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] \
- = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; \
- if (TARGET_ALTIVEC) \
- global_regs[VSCR_REGNO] = 1; \
- if (TARGET_SPE) \
- { \
- global_regs[SPEFSCR_REGNO] = 1; \
- fixed_regs[FIXED_SCRATCH] \
- = call_used_regs[FIXED_SCRATCH] \
- = call_really_used_regs[FIXED_SCRATCH] = 1; \
- } \
- if (! TARGET_ALTIVEC) \
- { \
- for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i) \
- fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1; \
- call_really_used_regs[VRSAVE_REGNO] = 1; \
- } \
- if (TARGET_ALTIVEC_ABI) \
- for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i) \
- call_used_regs[i] = call_really_used_regs[i] = 1; \
-}
+#define CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage ()
/* Specify the registers used for certain standard purposes.
The values of these macros are register numbers. */
@@ -1696,7 +1616,7 @@ extern enum rs6000_abi rs6000_current_abi; /* available for use by subtarget */
#define FUNCTION_VALUE_REGNO_P(N) \
((N) == GP_ARG_RETURN \
|| ((N) == FP_ARG_RETURN && TARGET_HARD_FLOAT) \
- || ((N) == ALTIVEC_ARG_RETURN && TARGET_ALTIVEC))
+ || ((N) == ALTIVEC_ARG_RETURN && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI))
/* 1 if N is a possible register number for function argument passing.
On RS/6000, these are r3-r10 and fp1-fp13.
@@ -1704,7 +1624,7 @@ extern enum rs6000_abi rs6000_current_abi; /* available for use by subtarget */
#define FUNCTION_ARG_REGNO_P(N) \
((unsigned) (N) - GP_ARG_MIN_REG < GP_ARG_NUM_REG \
|| ((unsigned) (N) - ALTIVEC_ARG_MIN_REG < ALTIVEC_ARG_NUM_REG \
- && TARGET_ALTIVEC) \
+ && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI) \
|| ((unsigned) (N) - FP_ARG_MIN_REG < FP_ARG_NUM_REG \
&& TARGET_HARD_FLOAT))
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 4e965487d7e..d93b80a8456 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -50,6 +50,7 @@
(UNSPEC_TLSGOTTPREL 28)
(UNSPEC_TLSTLS 29)
(UNSPEC_FIX_TRUNC_TF 30) ; fadd, rounding towards zero
+ (UNSPEC_MV_CR_GT 31) ; move_from_CR_gt_bit
])
;;
@@ -9607,29 +9608,48 @@
;; Peephole to convert two consecutive FP loads or stores into lfq/stfq.
-(define_peephole
- [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
+(define_insn "*lfq_power2"
+ [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
+ (match_operand:TF 1 "memory_operand" ""))]
+ "TARGET_POWER2
+ && TARGET_HARD_FLOAT && TARGET_FPRS"
+ "lfq%U1%X1 %0,%1")
+
+(define_peephole2
+ [(set (match_operand:DF 0 "gpc_reg_operand" "")
(match_operand:DF 1 "memory_operand" ""))
- (set (match_operand:DF 2 "gpc_reg_operand" "=f")
+ (set (match_operand:DF 2 "gpc_reg_operand" "")
(match_operand:DF 3 "memory_operand" ""))]
"TARGET_POWER2
&& TARGET_HARD_FLOAT && TARGET_FPRS
&& registers_ok_for_quad_peep (operands[0], operands[2])
- && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
- && addrs_ok_for_quad_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
- "lfq%U1%X1 %0,%1")
+ && mems_ok_for_quad_peep (operands[1], operands[3])"
+ [(set (match_dup 0)
+ (match_dup 1))]
+ "operands[1] = widen_memory_access (operands[1], TFmode, 0);
+ operands[0] = gen_rtx_REG (TFmode, REGNO (operands[0]));")
-(define_peephole
+(define_insn "*stfq_power2"
+ [(set (match_operand:TF 0 "memory_operand" "")
+ (match_operand:TF 1 "gpc_reg_operand" "f"))]
+ "TARGET_POWER2
+ && TARGET_HARD_FLOAT && TARGET_FPRS"
+ "stfq%U0%X0 %1,%0")
+
+
+(define_peephole2
[(set (match_operand:DF 0 "memory_operand" "")
- (match_operand:DF 1 "gpc_reg_operand" "f"))
+ (match_operand:DF 1 "gpc_reg_operand" ""))
(set (match_operand:DF 2 "memory_operand" "")
- (match_operand:DF 3 "gpc_reg_operand" "f"))]
+ (match_operand:DF 3 "gpc_reg_operand" ""))]
"TARGET_POWER2
&& TARGET_HARD_FLOAT && TARGET_FPRS
&& registers_ok_for_quad_peep (operands[1], operands[3])
- && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
- && addrs_ok_for_quad_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
- "stfq%U0%X0 %1,%0")
+ && mems_ok_for_quad_peep (operands[0], operands[2])"
+ [(set (match_dup 0)
+ (match_dup 1))]
+ "operands[0] = widen_memory_access (operands[0], TFmode, 0);
+ operands[1] = gen_rtx_REG (TFmode, REGNO (operands[1]));")
;; TLS support.
@@ -11290,6 +11310,15 @@
(const_string "mfcr")))
(set_attr "length" "12")])
+;; Same as above, but get the GT bit.
+(define_insn "move_from_CR_gt_bit"
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
+ "TARGET_E500"
+ "mfcr %0\;{rlinm|rlwinm} %0,%0,%D1,1"
+ [(set_attr "type" "mfcr")
+ (set_attr "length" "12")])
+
;; Same as above, but get the OV/ORDERED bit.
(define_insn "move_from_CR_ov_bit"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
@@ -13620,7 +13649,7 @@
; which are generated by the branch logic.
; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
-(define_insn ""
+(define_insn "*cceq_ior_compare"
[(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
(compare:CCEQ (match_operator:SI 1 "boolean_operator"
[(match_operator:SI 2
@@ -13634,7 +13663,7 @@
"cc_reg_operand" "0,y")
(const_int 0)])])
(const_int 1)))]
- ""
+ "!(TARGET_E500 && TARGET_HARD_FLOAT && !TARGET_FPRS)"
"cr%q1 %E0,%j2,%j4"
[(set_attr "type" "cr_logical,delayed_cr")])
@@ -13658,7 +13687,7 @@
"cr%q1 %E0,%j2,%j4"
[(set_attr "type" "cr_logical,delayed_cr")])
-(define_insn ""
+(define_insn "*cceq_rev_compare"
[(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
(compare:CCEQ (match_operator:SI 1
"branch_positive_comparison_operator"
@@ -13666,9 +13695,7 @@
"cc_reg_operand" "0,y")
(const_int 0)])
(const_int 0)))]
- ;; This pattern is not available to SPE because the CR bits on an FP
- ;; compare are different than traditional PPC.
- "!TARGET_SPE"
+ ""
"{crnor %E0,%j1,%j1|crnot %E0,%j1}"
[(set_attr "type" "cr_logical,delayed_cr")])
diff --git a/gcc/config/rs6000/spe.md b/gcc/config/rs6000/spe.md
index cd4771f6096..4b311c70fee 100644
--- a/gcc/config/rs6000/spe.md
+++ b/gcc/config/rs6000/spe.md
@@ -443,7 +443,7 @@
[(set_attr "type" "vecsimple")
(set_attr "length" "4")])
-(define_insn "spe_evneg"
+(define_insn "negv2si2"
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(neg:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r")))]
"TARGET_SPE"
@@ -2455,55 +2455,98 @@
"mfspefscr %0"
[(set_attr "type" "vecsimple")])
+;; FP comparison stuff.
+
+(define_insn "e500_cceq_ior_compare"
+ [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
+ (compare:CCEQ (match_operator:SI 1 "boolean_operator"
+ [(match_operator:SI 2
+ "branch_positive_comparison_operator"
+ [(match_operand 3
+ "cc_reg_operand" "y,y")
+ (const_int 0)])
+ (match_operator:SI 4
+ "branch_positive_comparison_operator"
+ [(match_operand 5
+ "cc_reg_operand" "0,y")
+ (const_int 0)])])
+ (const_int 1)))]
+ "TARGET_E500 && TARGET_HARD_FLOAT && !TARGET_FPRS"
+ "cr%q1 %c0,%j2,%j4"
+ [(set_attr "type" "cr_logical,delayed_cr")])
+
+;; Flip the GT bit.
+(define_insn "e500_flip_gt_bit"
+ [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+ (unspec:CCFP
+ [(match_operand:CCFP 1 "cc_reg_operand" "y")] 999))]
+ "!TARGET_FPRS && TARGET_HARD_FLOAT"
+ "*
+{
+ return output_e500_flip_gt_bit (operands[0], operands[1]);
+}"
+ [(set_attr "type" "cr_logical")])
+
;; MPC8540 single-precision FP instructions on GPRs.
;; We have 2 variants for each. One for IEEE compliant math and one
;; for non IEEE compliant math.
(define_insn "cmpsfeq_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
- (eq:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
- (match_operand:SF 2 "gpc_reg_operand" "r")))]
+ (unspec:CCFP
+ [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+ (match_operand:SF 2 "gpc_reg_operand" "r"))]
+ 1000))]
"TARGET_HARD_FLOAT && !TARGET_FPRS && !flag_unsafe_math_optimizations"
"efscmpeq %0,%1,%2"
[(set_attr "type" "veccmp")])
(define_insn "tstsfeq_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
- (eq:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
- (match_operand:SF 2 "gpc_reg_operand" "r")))]
+ (unspec:CCFP
+ [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+ (match_operand:SF 2 "gpc_reg_operand" "r"))]
+ 1001))]
"TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations"
"efststeq %0,%1,%2"
[(set_attr "type" "veccmpsimple")])
(define_insn "cmpsfgt_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
- (gt:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
- (match_operand:SF 2 "gpc_reg_operand" "r")))]
+ (unspec:CCFP
+ [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+ (match_operand:SF 2 "gpc_reg_operand" "r"))]
+ 1002))]
"TARGET_HARD_FLOAT && !TARGET_FPRS && !flag_unsafe_math_optimizations"
"efscmpgt %0,%1,%2"
[(set_attr "type" "veccmp")])
(define_insn "tstsfgt_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
- (gt:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
- (match_operand:SF 2 "gpc_reg_operand" "r")))]
+ (unspec:CCFP
+ [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+ (match_operand:SF 2 "gpc_reg_operand" "r"))]
+ 1003))]
"TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations"
"efststgt %0,%1,%2"
[(set_attr "type" "veccmpsimple")])
(define_insn "cmpsflt_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
- (lt:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
- (match_operand:SF 2 "gpc_reg_operand" "r")))]
+ (unspec:CCFP
+ [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+ (match_operand:SF 2 "gpc_reg_operand" "r"))]
+ 1004))]
"TARGET_HARD_FLOAT && !TARGET_FPRS && !flag_unsafe_math_optimizations"
"efscmplt %0,%1,%2"
[(set_attr "type" "veccmp")])
(define_insn "tstsflt_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
- (lt:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
- (match_operand:SF 2 "gpc_reg_operand" "r")))]
+ (unspec:CCFP
+ [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+ (match_operand:SF 2 "gpc_reg_operand" "r"))]
+ 1005))]
"TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations"
"efststlt %0,%1,%2"
[(set_attr "type" "veccmpsimple")])
-
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index 1e0ac3707f6..ea149f01a32 100644
--- a/gcc/config/rs6000/sysv4.h
+++ b/gcc/config/rs6000/sysv4.h
@@ -385,12 +385,6 @@ do { \
#undef STRICT_ALIGNMENT
#define STRICT_ALIGNMENT (TARGET_STRICT_ALIGN)
-/* Alignment in bits of the stack boundary. Note, in order to allow building
- one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
- versions, just use 64 as the stack boundary. */
-#undef STACK_BOUNDARY
-#define STACK_BOUNDARY (TARGET_ALTIVEC_ABI ? 128 : 64)
-
/* Define this macro if you wish to preserve a certain alignment for
the stack pointer, greater than what the hardware enforces. The
definition is a C expression for the desired alignment (measured
@@ -407,7 +401,8 @@ do { \
#define PREFERRED_STACK_BOUNDARY 128
/* Real stack boundary as mandated by the appropriate ABI. */
-#define ABI_STACK_BOUNDARY ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
+#define ABI_STACK_BOUNDARY \
+ ((TARGET_EABI && !TARGET_ALTIVEC && !TARGET_ALTIVEC_ABI) ? 64 : 128)
/* An expression for the alignment of a structure field FIELD if the
alignment computed in the usual way is COMPUTED. */
diff --git a/gcc/config/rs6000/t-rs6000 b/gcc/config/rs6000/t-rs6000
index caa07153ad3..9546461e57d 100644
--- a/gcc/config/rs6000/t-rs6000
+++ b/gcc/config/rs6000/t-rs6000
@@ -18,3 +18,23 @@ rs6000-c.o: $(srcdir)/config/rs6000/rs6000-c.c \
# The rs6000 backend doesn't cause warnings in these files.
insn-conditions.o-warn =
+# The files below trigger warnings in tree-ssa because of the gimplifier
+# emitting code that confuse the compiler into thinking that some variables
+# are used uninitialized.
+jump.o-warn = -Wno-error
+regmove.o-warn = -Wno-error
+c-typeck.o-warn = -Wno-error
+cfgrtl.o-warn = -Wno-error
+combine.o-warn = -Wno-error
+fold-const.o-warn = -Wno-error
+ifcvt.o-warn = -Wno-error
+reload1.o-warn = -Wno-error
+rtlanal.o-warn = -Wno-error
+cp/decl2.o-warn = -Wno-error
+cp/pt.o-warn = -Wno-error
+f/where.o-warn = -Wno-error
+java/expr.o-warn = -Wno-error
+objc/objc-act.o-warn = -Wno-error
+rs6000.o-warn = -Wno-error
+insn-emit.o-warn = -Wno-error
+simplify-rtx.o-warn = -Wno-error
diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index 49dad24b5e7..07295ec9369 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -26,8 +26,9 @@ extern void override_options (void);
extern HOST_WIDE_INT s390_arg_frame_offset (void);
extern void s390_load_got (int);
extern void s390_emit_prologue (void);
-extern void s390_emit_epilogue (void);
+extern void s390_emit_epilogue (bool);
extern void s390_function_profiler (FILE *, int);
+extern void s390_conditional_register_usage (void);
#ifdef RTX_CODE
extern int s390_extra_constraint_str (rtx, int, const char *);
@@ -53,7 +54,6 @@ extern int s390_alc_comparison (rtx op, enum machine_mode mode);
extern int s390_slb_comparison (rtx op, enum machine_mode mode);
extern int symbolic_reference_mentioned_p (rtx);
extern int tls_symbolic_reference_mentioned_p (rtx);
-extern rtx s390_tls_get_offset (void);
extern int legitimate_la_operand_p (rtx);
extern int preferred_la_operand_p (rtx);
extern int legitimate_pic_operand_p (rtx);
@@ -77,6 +77,7 @@ extern void s390_expand_movstr (rtx, rtx, rtx);
extern void s390_expand_clrstr (rtx, rtx);
extern void s390_expand_cmpmem (rtx, rtx, rtx, rtx);
extern rtx s390_return_addr_rtx (int, rtx);
+extern rtx s390_emit_call (rtx, rtx, rtx, rtx);
extern bool s390_output_addr_const_extra (FILE*, rtx);
extern void print_operand_address (FILE *, rtx);
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 63fc3e57c9a..9e786bfdf70 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -78,6 +78,8 @@ static int s390_address_cost (rtx);
static void s390_reorg (void);
static bool s390_valid_pointer_mode (enum machine_mode);
static tree s390_build_builtin_va_list (void);
+static bool s390_function_ok_for_sibcall (tree, tree);
+static bool s390_call_saved_register_used (tree);
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
@@ -151,6 +153,9 @@ static tree s390_build_builtin_va_list (void);
#undef TARGET_PROMOTE_FUNCTION_RETURN
#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
+#undef TARGET_FUNCTION_OK_FOR_SIBCALL
+#define TARGET_FUNCTION_OK_FOR_SIBCALL s390_function_ok_for_sibcall
+
struct gcc_target targetm = TARGET_INITIALIZER;
extern int reload_completed;
@@ -763,7 +768,7 @@ s390_branch_condition_mnemonic (rtx code, int inv)
/* Return the part of op which has a value different from def.
The size of the part is determined by mode.
- Use this function only if you already know that op really
+ Use this function only if you already know that op really
contains such a part. */
unsigned HOST_WIDE_INT
@@ -774,18 +779,18 @@ s390_extract_part (rtx op, enum machine_mode mode, int def)
int part_bits = GET_MODE_BITSIZE (mode);
unsigned HOST_WIDE_INT part_mask = (1 << part_bits) - 1;
int i;
-
+
for (i = 0; i < max_parts; i++)
{
if (i == 0)
value = (unsigned HOST_WIDE_INT) INTVAL (op);
else
value >>= part_bits;
-
+
if ((value & part_mask) != (def & part_mask))
return value & part_mask;
}
-
+
abort ();
}
@@ -794,8 +799,8 @@ s390_extract_part (rtx op, enum machine_mode mode, int def)
part. Otherwise, return -1. */
int
-s390_single_part (rtx op,
- enum machine_mode mode,
+s390_single_part (rtx op,
+ enum machine_mode mode,
enum machine_mode part_mode,
int def)
{
@@ -806,14 +811,14 @@ s390_single_part (rtx op,
if (GET_CODE (op) != CONST_INT)
return -1;
-
+
for (i = 0; i < n_parts; i++)
{
if (i == 0)
value = (unsigned HOST_WIDE_INT) INTVAL (op);
else
value >>= GET_MODE_BITSIZE (part_mode);
-
+
if ((value & part_mask) != (def & part_mask))
{
if (part != -1)
@@ -1118,10 +1123,10 @@ general_s_operand (register rtx op, enum machine_mode mode,
return 0;
if (addr.indx)
return 0;
- /* Do not allow literal pool references unless ALLOW_IMMEDIATE
- is true. This prevents compares between two literal pool
+ /* Do not allow literal pool references unless ALLOW_IMMEDIATE
+ is true. This prevents compares between two literal pool
entries from being accepted. */
- if (!allow_immediate
+ if (!allow_immediate
&& addr.base && REGNO (addr.base) == BASE_REGISTER)
return 0;
return 1;
@@ -1342,8 +1347,8 @@ s390_const_ok_for_constraint_p (HOST_WIDE_INT value,
return value >= -32768 && value < 32768;
case 'L':
- return (TARGET_LONG_DISPLACEMENT ?
- (value >= -524288 && value <= 524287)
+ return (TARGET_LONG_DISPLACEMENT ?
+ (value >= -524288 && value <= 524287)
: (value >= 0 && value <= 4095));
case 'M':
return value == 2147483647;
@@ -1357,7 +1362,7 @@ s390_const_ok_for_constraint_p (HOST_WIDE_INT value,
case 'Q': part_mode = QImode; break;
default: return 0;
}
-
+
switch (str[3])
{
case 'H': mode = HImode; break;
@@ -2610,16 +2615,29 @@ get_thread_pointer (void)
return tp;
}
-/* Construct the SYMBOL_REF for the tls_get_offset function. */
+/* Emit a tls call insn. The call target is the SYMBOL_REF stored
+ in s390_tls_symbol which always refers to __tls_get_offset.
+ The returned offset is written to RESULT_REG and an USE rtx is
+ generated for TLS_CALL. */
static GTY(()) rtx s390_tls_symbol;
-rtx
-s390_tls_get_offset (void)
+
+static void
+s390_emit_tls_call_insn (rtx result_reg, rtx tls_call)
{
+ rtx insn;
+
+ if (!flag_pic)
+ abort ();
+
if (!s390_tls_symbol)
s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset");
- return s390_tls_symbol;
+ insn = s390_emit_call (s390_tls_symbol, tls_call, result_reg,
+ gen_rtx_REG (Pmode, RETURN_REGNUM));
+
+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), result_reg);
+ CONST_OR_PURE_CALL_P (insn) = 1;
}
/* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
@@ -2640,7 +2658,7 @@ legitimize_tls_address (rtx addr, rtx reg)
new = gen_rtx_CONST (Pmode, tls_call);
new = force_const_mem (Pmode, new);
emit_move_insn (r2, new);
- emit_call_insn (gen_call_value_tls (r2, tls_call));
+ s390_emit_tls_call_insn (r2, tls_call);
insn = get_insns ();
end_sequence ();
@@ -2663,7 +2681,7 @@ legitimize_tls_address (rtx addr, rtx reg)
new = gen_rtx_CONST (Pmode, tls_call);
new = force_const_mem (Pmode, new);
emit_move_insn (r2, new);
- emit_call_insn (gen_call_value_tls (r2, tls_call));
+ s390_emit_tls_call_insn (r2, tls_call);
insn = get_insns ();
end_sequence ();
@@ -2938,18 +2956,14 @@ s390_expand_movstr (rtx dst, rtx src, rtx len)
else
{
rtx dst_addr, src_addr, count, blocks, temp;
+ rtx loop_end_label = gen_label_rtx ();
rtx end_label = gen_label_rtx ();
enum machine_mode mode;
- tree type;
mode = GET_MODE (len);
if (mode == VOIDmode)
mode = Pmode;
- type = lang_hooks.types.type_for_mode (mode, 1);
- if (!type)
- abort ();
-
dst_addr = gen_reg_rtx (Pmode);
src_addr = gen_reg_rtx (Pmode);
count = gen_reg_rtx (mode);
@@ -2972,10 +2986,9 @@ s390_expand_movstr (rtx dst, rtx src, rtx len)
if (temp != blocks)
emit_move_insn (blocks, temp);
+ emit_cmp_and_jump_insns (blocks, const0_rtx,
+ EQ, NULL_RTX, mode, 1, loop_end_label);
expand_start_loop (1);
- expand_exit_loop_top_cond (0, build (NE_EXPR, type,
- make_tree (type, blocks),
- make_tree (type, const0_rtx)));
emit_insn (gen_movstr_short (dst, src, GEN_INT (255)));
s390_load_address (dst_addr,
@@ -2987,9 +3000,12 @@ s390_expand_movstr (rtx dst, rtx src, rtx len)
if (temp != blocks)
emit_move_insn (blocks, temp);
+ emit_cmp_and_jump_insns (blocks, const0_rtx,
+ EQ, NULL_RTX, mode, 1, loop_end_label);
expand_end_loop ();
+ emit_label (loop_end_label);
- emit_insn (gen_movstr_short (dst, src,
+ emit_insn (gen_movstr_short (dst, src,
convert_to_mode (Pmode, count, 1)));
emit_label (end_label);
}
@@ -3014,18 +3030,14 @@ s390_expand_clrstr (rtx dst, rtx len)
else
{
rtx dst_addr, src_addr, count, blocks, temp;
+ rtx loop_end_label = gen_label_rtx ();
rtx end_label = gen_label_rtx ();
enum machine_mode mode;
- tree type;
mode = GET_MODE (len);
if (mode == VOIDmode)
mode = Pmode;
- type = lang_hooks.types.type_for_mode (mode, 1);
- if (!type)
- abort ();
-
dst_addr = gen_reg_rtx (Pmode);
src_addr = gen_reg_rtx (Pmode);
count = gen_reg_rtx (mode);
@@ -3046,10 +3058,9 @@ s390_expand_clrstr (rtx dst, rtx len)
if (temp != blocks)
emit_move_insn (blocks, temp);
+ emit_cmp_and_jump_insns (blocks, const0_rtx,
+ EQ, NULL_RTX, mode, 1, loop_end_label);
expand_start_loop (1);
- expand_exit_loop_top_cond (0, build (NE_EXPR, type,
- make_tree (type, blocks),
- make_tree (type, const0_rtx)));
emit_insn (gen_clrstr_short (dst, GEN_INT (255)));
s390_load_address (dst_addr,
@@ -3059,7 +3070,10 @@ s390_expand_clrstr (rtx dst, rtx len)
if (temp != blocks)
emit_move_insn (blocks, temp);
+ emit_cmp_and_jump_insns (blocks, const0_rtx,
+ EQ, NULL_RTX, mode, 1, loop_end_label);
expand_end_loop ();
+ emit_label (loop_end_label);
emit_insn (gen_clrstr_short (dst, convert_to_mode (Pmode, count, 1)));
emit_label (end_label);
@@ -3102,18 +3116,14 @@ s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
else
{
rtx addr0, addr1, count, blocks, temp;
+ rtx loop_end_label = gen_label_rtx ();
rtx end_label = gen_label_rtx ();
enum machine_mode mode;
- tree type;
mode = GET_MODE (len);
if (mode == VOIDmode)
mode = Pmode;
- type = lang_hooks.types.type_for_mode (mode, 1);
- if (!type)
- abort ();
-
addr0 = gen_reg_rtx (Pmode);
addr1 = gen_reg_rtx (Pmode);
count = gen_reg_rtx (mode);
@@ -3136,10 +3146,9 @@ s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
if (temp != blocks)
emit_move_insn (blocks, temp);
+ emit_cmp_and_jump_insns (blocks, const0_rtx,
+ EQ, NULL_RTX, mode, 1, loop_end_label);
expand_start_loop (1);
- expand_exit_loop_top_cond (0, build (NE_EXPR, type,
- make_tree (type, blocks),
- make_tree (type, const0_rtx)));
emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (255)));
temp = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCSmode, 33), const0_rtx);
@@ -3157,9 +3166,12 @@ s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
if (temp != blocks)
emit_move_insn (blocks, temp);
+ emit_cmp_and_jump_insns (blocks, const0_rtx,
+ EQ, NULL_RTX, mode, 1, loop_end_label);
expand_end_loop ();
+ emit_label (loop_end_label);
- emit_insn (gen_cmpmem_short (op0, op1,
+ emit_insn (gen_cmpmem_short (op0, op1,
convert_to_mode (Pmode, count, 1)));
emit_label (end_label);
@@ -3300,7 +3312,7 @@ get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
return 0;
}
-/* Output machine-dependent UNSPECs occurring in address constant X
+/* Output machine-dependent UNSPECs occurring in address constant X
in assembler syntax to stdio stream FILE. Returns true if the
constant X could be recognized, false otherwise. */
@@ -3518,11 +3530,11 @@ print_operand (FILE *file, rtx x, int code)
else if (code == 'h')
fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
else if (code == 'i')
- fprintf (file, HOST_WIDE_INT_PRINT_DEC,
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC,
s390_extract_part (x, HImode, 0));
else if (code == 'j')
- fprintf (file, HOST_WIDE_INT_PRINT_DEC,
- s390_extract_part (x, HImode, -1));
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC,
+ s390_extract_part (x, HImode, -1));
else
fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
break;
@@ -4264,7 +4276,7 @@ s390_dump_pool (struct constant_pool *pool, bool remote_label)
insn = emit_label_after (c->label, insn);
INSN_ADDRESSES_NEW (insn, -1);
- value = gen_rtx_UNSPEC_VOLATILE (constant_modes[i],
+ value = gen_rtx_UNSPEC_VOLATILE (constant_modes[i],
gen_rtvec (1, value),
UNSPECV_POOL_ENTRY);
insn = emit_insn_after (value, insn);
@@ -4412,8 +4424,8 @@ s390_mainpool_finish (struct constant_pool *pool, rtx base_reg)
insn = emit_insn_after (insn, pool->pool_insn);
INSN_ADDRESSES_NEW (insn, -1);
remove_insn (pool->pool_insn);
-
- insn = get_last_insn ();
+
+ insn = get_last_insn ();
pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
INSN_ADDRESSES_NEW (pool->pool_insn, -1);
@@ -5113,7 +5125,7 @@ s390_reorg (void)
/* Install the main literal pool and the associated base
register load insns.
- In addition, there are two problematic situations we need
+ In addition, there are two problematic situations we need
to correct:
- the literal pool might be > 4096 bytes in size, so that
@@ -5219,7 +5231,7 @@ s390_return_addr_rtx (int count, rtx frame)
return gen_rtx_MEM (Pmode, addr);
}
-/* Find first call clobbered register unsused in a function.
+/* Find first call clobbered register unused in a function.
This could be used as base register in a leaf function
or for holding the return address before epilogue. */
@@ -5665,18 +5677,8 @@ s390_emit_prologue (void)
{
/* Generate a BAS instruction to serve as a function
entry intercept to facilitate the use of tracing
- algorithms located at the branch target.
-
- This must use register 1. */
- rtx addr;
- rtx unkn;
- rtx link;
-
- addr = GEN_INT (0xfe0);
- unkn = CONST0_RTX (SImode);
- link = gen_rtx_REG (Pmode, 1);
-
- emit_call_insn (gen_call_exp (gen_rtx_MEM (QImode, addr), unkn, link));
+ algorithms located at the branch target. */
+ emit_insn (gen_prologue_tpf ());
/* Emit a blockage here so that all code
lies between the profiling mechanisms. */
@@ -5687,7 +5689,7 @@ s390_emit_prologue (void)
/* Expand the epilogue into a bunch of separate insns. */
void
-s390_emit_epilogue (void)
+s390_emit_epilogue (bool sibcall)
{
rtx frame_pointer, return_reg;
int area_bottom, area_top, offset = 0;
@@ -5699,23 +5701,13 @@ s390_emit_epilogue (void)
/* Generate a BAS instruction to serve as a function
entry intercept to facilitate the use of tracing
- algorithms located at the branch target.
-
- This must use register 1. */
-
- rtx addr;
- rtx unkn;
- rtx link;
-
- addr = GEN_INT (0xfe6);
- unkn = CONST0_RTX (SImode);
- link = gen_rtx_REG (Pmode, 1);
+ algorithms located at the branch target. */
/* Emit a blockage here so that all code
lies between the profiling mechanisms. */
emit_insn (gen_blockage ());
- emit_call_insn (gen_call_exp (gen_rtx_MEM (QImode, addr), unkn, link));
+ emit_insn (gen_epilogue_tpf ());
}
/* Check whether to use frame or stack pointer for restore. */
@@ -5755,7 +5747,7 @@ s390_emit_epilogue (void)
area_bottom = 16*UNITS_PER_WORD + 8*(i-16);
if (area_top < 16*UNITS_PER_WORD + 8*(i-16) + 8)
area_top = 16*UNITS_PER_WORD + 8*(i-16) + 8;
- }
+ }
}
/* Check whether we can access the register save area.
@@ -5807,7 +5799,7 @@ s390_emit_epilogue (void)
{
for (i = 18; i < 20; i++)
if (regs_ever_live[i] && !global_regs[i])
- restore_fpr (frame_pointer,
+ restore_fpr (frame_pointer,
offset + 16*UNITS_PER_WORD + 8*(i-16), i);
}
@@ -5847,23 +5839,26 @@ s390_emit_epilogue (void)
}
}
- /* Fetch return address from stack before load multiple,
- this will do good for scheduling. */
-
- if (cfun->machine->save_return_addr_p
- || (cfun->machine->first_restore_gpr < BASE_REGISTER
- && cfun->machine->last_save_gpr > RETURN_REGNUM))
+ if (! sibcall)
{
- int return_regnum = find_unused_clobbered_reg();
- if (!return_regnum)
- return_regnum = 4;
- return_reg = gen_rtx_REG (Pmode, return_regnum);
-
- addr = plus_constant (frame_pointer,
- offset + RETURN_REGNUM * UNITS_PER_WORD);
- addr = gen_rtx_MEM (Pmode, addr);
- set_mem_alias_set (addr, s390_sr_alias_set);
- emit_move_insn (return_reg, addr);
+ /* Fetch return address from stack before load multiple,
+ this will do good for scheduling. */
+
+ if (cfun->machine->save_return_addr_p
+ || (cfun->machine->first_restore_gpr < BASE_REGISTER
+ && cfun->machine->last_save_gpr > RETURN_REGNUM))
+ {
+ int return_regnum = find_unused_clobbered_reg();
+ if (!return_regnum)
+ return_regnum = 4;
+ return_reg = gen_rtx_REG (Pmode, return_regnum);
+
+ addr = plus_constant (frame_pointer,
+ offset + RETURN_REGNUM * UNITS_PER_WORD);
+ addr = gen_rtx_MEM (Pmode, addr);
+ set_mem_alias_set (addr, s390_sr_alias_set);
+ emit_move_insn (return_reg, addr);
+ }
}
/* ??? As references to the base register are not made
@@ -5878,13 +5873,17 @@ s390_emit_epilogue (void)
emit_insn (insn);
}
- /* Return to caller. */
+ if (! sibcall)
+ {
+
+ /* Return to caller. */
- p = rtvec_alloc (2);
+ p = rtvec_alloc (2);
- RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
- RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg);
- emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
+ RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
+ RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg);
+ emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
+ }
}
@@ -5968,13 +5967,13 @@ s390_function_arg_integer (enum machine_mode mode, tree type)
/* We accept small integral (and similar) types. */
if (INTEGRAL_TYPE_P (type)
- || POINTER_TYPE_P (type)
+ || POINTER_TYPE_P (type)
|| TREE_CODE (type) == OFFSET_TYPE
|| (TARGET_SOFT_FLOAT && TREE_CODE (type) == REAL_TYPE))
return true;
/* We also accept structs of size 1, 2, 4, 8 that are not
- passed in floating-point registers. */
+ passed in floating-point registers. */
if (AGGREGATE_TYPE_P (type)
&& exact_log2 (size) >= 0
&& !s390_function_arg_float (mode, type))
@@ -6100,7 +6099,7 @@ s390_return_in_memory (tree type, tree fundecl ATTRIBUTE_UNUSED)
{
/* We accept small integral (and similar) types. */
if (INTEGRAL_TYPE_P (type)
- || POINTER_TYPE_P (type)
+ || POINTER_TYPE_P (type)
|| TREE_CODE (type) == OFFSET_TYPE
|| TREE_CODE (type) == REAL_TYPE)
return int_size_in_bytes (type) > 8;
@@ -6131,7 +6130,7 @@ s390_function_value (tree type, enum machine_mode mode)
mode = promote_mode (type, TYPE_MODE (type), &unsignedp, 1);
}
- if (GET_MODE_CLASS (mode) != MODE_INT
+ if (GET_MODE_CLASS (mode) != MODE_INT
&& GET_MODE_CLASS (mode) != MODE_FLOAT)
abort ();
if (GET_MODE_SIZE (mode) > 8)
@@ -6999,4 +6998,209 @@ s390_init_machine_status (void)
return ggc_alloc_cleared (sizeof (struct machine_function));
}
+/* Checks whether the given ARGUMENT_LIST would use a caller
+ saved register. This is used to decide whether sibling call
+ optimization could be performed on the respective function
+ call. */
+
+static bool
+s390_call_saved_register_used (tree argument_list)
+{
+ CUMULATIVE_ARGS cum;
+ tree parameter;
+ enum machine_mode mode;
+ tree type;
+ rtx parm_rtx;
+ int reg;
+
+ INIT_CUMULATIVE_ARGS (cum, NULL, NULL, 0, 0);
+
+ while (argument_list)
+ {
+ parameter = TREE_VALUE (argument_list);
+ argument_list = TREE_CHAIN (argument_list);
+
+ if (!parameter)
+ abort();
+
+ /* For an undeclared variable passed as parameter we will get
+ an ERROR_MARK node here. */
+ if (TREE_CODE (parameter) == ERROR_MARK)
+ return true;
+
+ if (! (type = TREE_TYPE (parameter)))
+ abort();
+
+ if (! (mode = TYPE_MODE (TREE_TYPE (parameter))))
+ abort();
+
+ if (s390_function_arg_pass_by_reference (mode, type))
+ {
+ mode = Pmode;
+ type = build_pointer_type (type);
+ }
+
+ parm_rtx = s390_function_arg (&cum, mode, type, 0);
+
+ s390_function_arg_advance (&cum, mode, type, 0);
+
+ if (parm_rtx && REG_P (parm_rtx))
+ {
+ for (reg = 0;
+ reg < HARD_REGNO_NREGS (REGNO (parm_rtx), GET_MODE (parm_rtx));
+ reg++)
+ if (! call_used_regs[reg + REGNO (parm_rtx)])
+ return true;
+ }
+ }
+ return false;
+}
+
+/* Return true if the given call expression can be
+ turned into a sibling call.
+ DECL holds the declaration of the function to be called whereas
+ EXP is the call expression itself. */
+
+static bool
+s390_function_ok_for_sibcall (tree decl, tree exp)
+{
+ /* The TPF epilogue uses register 1. */
+ if (TARGET_TPF)
+ return false;
+
+ /* The 31 bit PLT code uses register 12 (GOT pointer - caller saved)
+ which would have to be restored before the sibcall. */
+ if (!TARGET_64BIT && flag_pic && decl && TREE_PUBLIC (decl))
+ return false;
+
+ /* Register 6 on s390 is available as an argument register but unfortunately
+ "caller saved". This makes functions needing this register for arguments
+ not suitable for sibcalls. */
+ if (TREE_OPERAND (exp, 1)
+ && s390_call_saved_register_used (TREE_OPERAND (exp, 1)))
+ return false;
+
+ return true;
+}
+
+/* This function is used by the call expanders of the machine description.
+ It emits the call insn itself together with the necessary operations
+ to adjust the target address and returns the emitted insn.
+ ADDR_LOCATION is the target address rtx
+ TLS_CALL the location of the thread-local symbol
+ RESULT_REG the register where the result of the call should be stored
+ RETADDR_REG the register where the return address should be stored
+ If this parameter is NULL_RTX the call is considered
+ to be a sibling call. */
+
+rtx
+s390_emit_call (rtx addr_location, rtx tls_call, rtx result_reg,
+ rtx retaddr_reg)
+{
+ bool plt_call = false;
+ rtx insn;
+ rtx call;
+ rtx clobber;
+ rtvec vec;
+
+ /* Direct function calls need special treatment. */
+ if (GET_CODE (addr_location) == SYMBOL_REF)
+ {
+ /* When calling a global routine in PIC mode, we must
+ replace the symbol itself with the PLT stub. */
+ if (flag_pic && !SYMBOL_REF_LOCAL_P (addr_location))
+ {
+ addr_location = gen_rtx_UNSPEC (Pmode,
+ gen_rtvec (1, addr_location),
+ UNSPEC_PLT);
+ addr_location = gen_rtx_CONST (Pmode, addr_location);
+ plt_call = true;
+ }
+
+ /* Unless we can use the bras(l) insn, force the
+ routine address into a register. */
+ if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
+ {
+ if (flag_pic)
+ addr_location = legitimize_pic_address (addr_location, 0);
+ else
+ addr_location = force_reg (Pmode, addr_location);
+ }
+ }
+
+ /* If it is already an indirect call or the code above moved the
+ SYMBOL_REF to somewhere else make sure the address can be found in
+ register 1. */
+ if (retaddr_reg == NULL_RTX
+ && GET_CODE (addr_location) != SYMBOL_REF
+ && !plt_call)
+ {
+ emit_move_insn (gen_rtx_REG (Pmode, SIBCALL_REGNUM), addr_location);
+ addr_location = gen_rtx_REG (Pmode, SIBCALL_REGNUM);
+ }
+
+ addr_location = gen_rtx_MEM (QImode, addr_location);
+ call = gen_rtx_CALL (VOIDmode, addr_location, const0_rtx);
+
+ if (result_reg != NULL_RTX)
+ call = gen_rtx_SET (VOIDmode, result_reg, call);
+
+ if (retaddr_reg != NULL_RTX)
+ {
+ clobber = gen_rtx_CLOBBER (VOIDmode, retaddr_reg);
+
+ if (tls_call != NULL_RTX)
+ vec = gen_rtvec (3, call, clobber,
+ gen_rtx_USE (VOIDmode, tls_call));
+ else
+ vec = gen_rtvec (2, call, clobber);
+
+ call = gen_rtx_PARALLEL (VOIDmode, vec);
+ }
+
+ insn = emit_call_insn (call);
+
+ /* 31-bit PLT stubs and tls calls use the GOT register implicitly. */
+ if ((!TARGET_64BIT && plt_call) || tls_call != NULL_RTX)
+ {
+ /* s390_function_ok_for_sibcall should
+ have denied sibcalls in this case. */
+ if (retaddr_reg == NULL_RTX)
+ abort ();
+
+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
+ }
+ return insn;
+}
+
+/* Implement CONDITIONAL_REGISTER_USAGE. */
+
+void
+s390_conditional_register_usage (void)
+{
+ int i;
+
+ if (flag_pic)
+ {
+ fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
+ call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
+ }
+ if (TARGET_CPU_ZARCH)
+ {
+ fixed_regs[RETURN_REGNUM] = 0;
+ call_used_regs[RETURN_REGNUM] = 0;
+ }
+ if (TARGET_64BIT)
+ {
+ for (i = 24; i < 32; i++)
+ call_used_regs[i] = call_really_used_regs[i] = 0;
+ }
+ else
+ {
+ for (i = 18; i < 20; i++)
+ call_used_regs[i] = call_really_used_regs[i] = 0;
+ }
+}
+
+
#include "gt-s390.h"
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index 3354f45beed..9c35632d8a5 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -299,6 +299,7 @@ if (INTEGRAL_MODE_P (MODE) && \
#define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X)))
#define FRAME_REG_P(X) (REG_P (X) && FRAME_REGNO_P (REGNO (X)))
+#define SIBCALL_REGNUM 1
#define BASE_REGISTER 13
#define RETURN_REGNUM 14
#define CC_REGNUM 33
@@ -350,32 +351,7 @@ if (INTEGRAL_MODE_P (MODE) && \
1, 1, 1, 1, \
1, 1, 1 }
-#define CONDITIONAL_REGISTER_USAGE \
-do \
- { \
- int i; \
- \
- if (flag_pic) \
- { \
- fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
- call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
- } \
- if (TARGET_CPU_ZARCH) \
- { \
- fixed_regs[RETURN_REGNUM] = 0; \
- call_used_regs[RETURN_REGNUM] = 0; \
- } \
- if (TARGET_64BIT) \
- { \
- for (i = 24; i < 32; i++) \
- call_used_regs[i] = call_really_used_regs[i] = 0; \
- } \
- else \
- { \
- for (i = 18; i < 20; i++) \
- call_used_regs[i] = call_really_used_regs[i] = 0; \
- } \
- } while (0)
+#define CONDITIONAL_REGISTER_USAGE s390_conditional_register_usage ()
/* Preferred register allocation order. */
#define REG_ALLOC_ORDER \
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 0c9af2a7839..151b5b48419 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -29,7 +29,7 @@
;; I -- An 8-bit constant (0..255).
;; J -- A 12-bit constant (0..4095).
;; K -- A 16-bit constant (-32768..32767).
-;; L -- Value appropriate as displacement.
+;; L -- Value appropriate as displacement.
;; (0..4095) for short displacement
;; (-524288..524287) for long displacement
;; M -- Constant integer with a value of 0x7fffffff.
@@ -38,7 +38,7 @@
;; H,Q: mode of the part
;; D,S,H: mode of the containing operand
;; 0,F: value of the other parts (F - all bits set)
-;;
+;;
;; The constraint matches if the specified part of a constant
;; has a value different from its other parts.
;; Q -- Memory reference without index register and with short displacement.
@@ -118,6 +118,10 @@
[; Blockage
(UNSPECV_BLOCKAGE 0)
+ ; TPF Support
+ (UNSPECV_TPF_PROLOGUE 20)
+ (UNSPECV_TPF_EPILOGUE 21)
+
; Literal pool
(UNSPECV_POOL 200)
(UNSPECV_POOL_START 201)
@@ -537,7 +541,7 @@
(define_insn "*tmdi_reg"
[(set (reg 33)
(compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d")
- (match_operand:DI 1 "immediate_operand"
+ (match_operand:DI 1 "immediate_operand"
"N0HD0,N1HD0,N2HD0,N3HD0"))
(match_operand:DI 2 "immediate_operand" "n,n,n,n")))]
"TARGET_64BIT
@@ -1082,9 +1086,9 @@
(set_attr "type" "larl")])
(define_insn "*movdi_64"
- [(set (match_operand:DI 0 "nonimmediate_operand"
+ [(set (match_operand:DI 0 "nonimmediate_operand"
"=d,d,d,d,d,d,d,d,m,!*f,!*f,!*f,!R,!T,?Q")
- (match_operand:DI 1 "general_operand"
+ (match_operand:DI 1 "general_operand"
"K,N0HD0,N1HD0,N2HD0,N3HD0,L,d,m,d,*f,R,T,*f,*f,?Q"))]
"TARGET_64BIT"
"@
@@ -1281,9 +1285,9 @@
(set_attr "type" "larl")])
(define_insn "*movsi_zarch"
- [(set (match_operand:SI 0 "nonimmediate_operand"
+ [(set (match_operand:SI 0 "nonimmediate_operand"
"=d,d,d,d,d,d,d,R,T,!*f,!*f,!*f,!R,!T,?Q")
- (match_operand:SI 1 "general_operand"
+ (match_operand:SI 1 "general_operand"
"K,N0HS0,N1HS0,L,d,R,T,d,d,*f,R,T,*f,*f,?Q"))]
"TARGET_ZARCH"
"@
@@ -1423,7 +1427,7 @@
(match_operand:HI 1 "general_operand" ""))]
""
{
- /* Make it explicit that loading a register from memory
+ /* Make it explicit that loading a register from memory
always sign-extends (at least) to SImode. */
if (optimize && !no_new_pseudos
&& register_operand (operands[0], VOIDmode)
@@ -1893,7 +1897,7 @@
(define_expand "strlendi"
[(set (reg:QI 0) (match_operand:QI 2 "immediate_operand" ""))
- (parallel
+ (parallel
[(set (match_dup 4)
(unspec:DI [(const_int 0)
(match_operand:BLK 1 "memory_operand" "")
@@ -1929,7 +1933,7 @@
(define_expand "strlensi"
[(set (reg:QI 0) (match_operand:QI 2 "immediate_operand" ""))
- (parallel
+ (parallel
[(set (match_dup 4)
(unspec:SI [(const_int 0)
(match_operand:BLK 1 "memory_operand" "")
@@ -1956,7 +1960,7 @@
(reg:QI 0)
(match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
(clobber (match_scratch:SI 1 "=a"))
- (clobber (reg:CC 33))]
+ (clobber (reg:CC 33))]
"!TARGET_64BIT"
"srst\t%0,%1\;jo\t.-4"
[(set_attr "op_type" "NN")
@@ -2746,14 +2750,14 @@
(define_insn_and_split "*llgt_sidi_split"
[(set (match_operand:DI 0 "register_operand" "=d")
- (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "m") 0)
+ (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "m") 0)
(const_int 2147483647)))
(clobber (reg:CC 33))]
"TARGET_64BIT"
"#"
"&& reload_completed"
[(set (match_dup 0)
- (and:DI (subreg:DI (match_dup 1) 0)
+ (and:DI (subreg:DI (match_dup 1) 0)
(const_int 2147483647)))]
"")
@@ -4282,7 +4286,7 @@
;
(define_insn "*adddi3_alc_cc"
- [(set (reg 33)
+ [(set (reg 33)
(compare
(plus:DI (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
(match_operand:DI 2 "general_operand" "d,m"))
@@ -4290,7 +4294,7 @@
(const_int 0)))
(set (match_operand:DI 0 "register_operand" "=d,d")
(plus:DI (plus:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
+ "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
"@
alcgr\\t%0,%2
alcg\\t%0,%2"
@@ -4301,15 +4305,15 @@
(plus:DI (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
(match_operand:DI 2 "general_operand" "d,m"))
(match_operand:DI 3 "s390_alc_comparison" "")))
- (clobber (reg:CC 33))]
- "TARGET_64BIT"
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
"@
alcgr\\t%0,%2
alcg\\t%0,%2"
[(set_attr "op_type" "RRE,RXY")])
(define_insn "*subdi3_slb_cc"
- [(set (reg 33)
+ [(set (reg 33)
(compare
(minus:DI (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
(match_operand:DI 2 "general_operand" "d,m"))
@@ -4317,7 +4321,7 @@
(const_int 0)))
(set (match_operand:DI 0 "register_operand" "=d,d")
(minus:DI (minus:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
+ "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
"@
slbgr\\t%0,%2
slbg\\t%0,%2"
@@ -4328,8 +4332,8 @@
(minus:DI (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
(match_operand:DI 2 "general_operand" "d,m"))
(match_operand:DI 3 "s390_slb_comparison" "")))
- (clobber (reg:CC 33))]
- "TARGET_64BIT"
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
"@
slbgr\\t%0,%2
slbg\\t%0,%2"
@@ -4340,7 +4344,7 @@
;
(define_insn "*addsi3_alc_cc"
- [(set (reg 33)
+ [(set (reg 33)
(compare
(plus:SI (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
(match_operand:SI 2 "general_operand" "d,m"))
@@ -4348,7 +4352,7 @@
(const_int 0)))
(set (match_operand:SI 0 "register_operand" "=d,d")
(plus:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
+ "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
"@
alcr\\t%0,%2
alc\\t%0,%2"
@@ -4360,14 +4364,14 @@
(match_operand:SI 2 "general_operand" "d,m"))
(match_operand:SI 3 "s390_alc_comparison" "")))
(clobber (reg:CC 33))]
- "TARGET_CPU_ZARCH"
+ "TARGET_CPU_ZARCH"
"@
alcr\\t%0,%2
alc\\t%0,%2"
[(set_attr "op_type" "RRE,RXY")])
(define_insn "*subsi3_slb_cc"
- [(set (reg 33)
+ [(set (reg 33)
(compare
(minus:SI (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
(match_operand:SI 2 "general_operand" "d,m"))
@@ -4375,7 +4379,7 @@
(const_int 0)))
(set (match_operand:SI 0 "register_operand" "=d,d")
(minus:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
+ "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
"@
slbr\\t%0,%2
slb\\t%0,%2"
@@ -4386,8 +4390,8 @@
(minus:SI (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
(match_operand:SI 2 "general_operand" "d,m"))
(match_operand:SI 3 "s390_slb_comparison" "")))
- (clobber (reg:CC 33))]
- "TARGET_CPU_ZARCH"
+ (clobber (reg:CC 33))]
+ "TARGET_CPU_ZARCH"
"@
slbr\\t%0,%2
slb\\t%0,%2"
@@ -4657,7 +4661,7 @@
(ashift:TI
(zero_extend:TI
(mod:DI (match_operand:DI 1 "register_operand" "0,0")
- (sign_extend:DI
+ (sign_extend:DI
(match_operand:SI 2 "nonimmediate_operand" "d,m"))))
(const_int 64))
(zero_extend:TI
@@ -4713,12 +4717,12 @@
(define_insn "udivmodtidi3"
[(set (match_operand:TI 0 "register_operand" "=d,d")
- (ior:TI
+ (ior:TI
(ashift:TI
(zero_extend:TI
(truncate:DI
- (umod:TI (match_operand:TI 1 "register_operand" "0,0")
- (zero_extend:TI
+ (umod:TI (match_operand:TI 1 "register_operand" "0,0")
+ (zero_extend:TI
(match_operand:DI 2 "nonimmediate_operand" "d,m")))))
(const_int 64))
(zero_extend:TI
@@ -4773,12 +4777,12 @@
(define_insn "divmoddisi3"
[(set (match_operand:DI 0 "register_operand" "=d,d")
- (ior:DI
+ (ior:DI
(ashift:DI
(zero_extend:DI
(truncate:SI
- (mod:DI (match_operand:DI 1 "register_operand" "0,0")
- (sign_extend:DI
+ (mod:DI (match_operand:DI 1 "register_operand" "0,0")
+ (sign_extend:DI
(match_operand:SI 2 "nonimmediate_operand" "d,R")))))
(const_int 32))
(zero_extend:DI
@@ -4835,12 +4839,12 @@
(define_insn "udivmoddisi3"
[(set (match_operand:DI 0 "register_operand" "=d,d")
- (ior:DI
+ (ior:DI
(ashift:DI
(zero_extend:DI
(truncate:SI
- (umod:DI (match_operand:DI 1 "register_operand" "0,0")
- (zero_extend:DI
+ (umod:DI (match_operand:DI 1 "register_operand" "0,0")
+ (zero_extend:DI
(match_operand:SI 2 "nonimmediate_operand" "d,m")))))
(const_int 32))
(zero_extend:DI
@@ -5138,7 +5142,7 @@
(define_insn "anddi3"
[(set (match_operand:DI 0 "register_operand" "=d,d,d,d,d,d,d,d")
(and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o,0,0,0,0,0,0")
- (match_operand:DI 2 "general_operand"
+ (match_operand:DI 2 "general_operand"
"M,M,N0HDF,N1HDF,N2HDF,N3HDF,d,m")))
(clobber (reg:CC 33))]
"TARGET_64BIT"
@@ -5203,7 +5207,7 @@
[(set_attr "op_type" "RR,RX,RXY")])
(define_expand "andsi3"
- [(parallel
+ [(parallel
[(set (match_operand:SI 0 "register_operand" "")
(and:SI (match_operand:SI 1 "nonimmediate_operand" "")
(match_operand:SI 2 "general_operand" "")))
@@ -5221,7 +5225,7 @@
#
#
nilh\t%0,%j2
- nill\t%0,%j2
+ nill\t%0,%j2
nr\t%0,%2
n\t%0,%2
ny\t%0,%2"
@@ -5445,7 +5449,7 @@
[(set_attr "op_type" "RR,RX,RXY")])
(define_expand "iorsi3"
- [(parallel
+ [(parallel
[(set (match_operand:SI 0 "register_operand" "")
(ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
(match_operand:SI 2 "general_operand" "")))
@@ -6912,6 +6916,8 @@
emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
index = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, base, index));
+ RTX_UNCHANGING_P (index) = 1;
+ MEM_NOTRAP_P (index) = 1;
emit_move_insn (target, index);
if (flag_pic)
@@ -6968,71 +6974,111 @@
[(set_attr "type" "none")
(set_attr "length" "0")])
-
-
;
-; call instruction pattern(s).
+; sibcall patterns
;
-(define_expand "call"
+(define_expand "sibcall"
[(call (match_operand 0 "" "")
- (match_operand 1 "" ""))
- (use (match_operand 2 "" ""))]
+ (match_operand 1 "" ""))]
""
{
- bool plt_call = false;
- rtx insn;
-
- /* Direct function calls need special treatment. */
- if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
- {
- rtx sym = XEXP (operands[0], 0);
+ s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX);
+ DONE;
+})
- /* When calling a global routine in PIC mode, we must
- replace the symbol itself with the PLT stub. */
- if (flag_pic && !SYMBOL_REF_LOCAL_P (sym))
- {
- sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), UNSPEC_PLT);
- sym = gen_rtx_CONST (Pmode, sym);
- plt_call = true;
- }
+(define_insn "*sibcall_br"
+ [(call (mem:QI (reg 1))
+ (match_operand 0 "const_int_operand" "n"))]
+ "SIBLING_CALL_P (insn)
+ && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode"
+ "br\t%%r1"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "branch")
+ (set_attr "atype" "agen")])
- /* Unless we can use the bras(l) insn, force the
- routine address into a register. */
- if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
- {
- if (flag_pic)
- sym = legitimize_pic_address (sym, 0);
- else
- sym = force_reg (Pmode, sym);
- }
+(define_insn "*sibcall_brc"
+ [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
+ (match_operand 1 "const_int_operand" "n"))]
+ "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
+ "j\t%0"
+ [(set_attr "op_type" "RI")
+ (set_attr "type" "branch")])
- operands[0] = gen_rtx_MEM (QImode, sym);
- }
+(define_insn "*sibcall_brcl"
+ [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
+ (match_operand 1 "const_int_operand" "n"))]
+ "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
+ "jg\t%0"
+ [(set_attr "op_type" "RIL")
+ (set_attr "type" "branch")])
- /* Emit insn. */
- insn = emit_call_insn (gen_call_exp (operands[0], operands[1],
- gen_rtx_REG (Pmode, RETURN_REGNUM)));
+;
+; sibcall_value patterns
+;
- /* 31-bit PLT stubs use the GOT register implicitly. */
- if (!TARGET_64BIT && plt_call)
- use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
-
+(define_expand "sibcall_value"
+ [(set (match_operand 0 "" "")
+ (call (match_operand 1 "" "")
+ (match_operand 2 "" "")))]
+ ""
+{
+ s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX);
DONE;
})
-(define_expand "call_exp"
- [(parallel [(call (match_operand 0 "" "")
- (match_operand 1 "" ""))
- (clobber (match_operand 2 "" ""))])]
+(define_insn "*sibcall_value_br"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (reg 1))
+ (match_operand 1 "const_int_operand" "n")))]
+ "SIBLING_CALL_P (insn)
+ && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode"
+ "br\t%%r1"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "branch")
+ (set_attr "atype" "agen")])
+
+(define_insn "*sibcall_value_brc"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
+ (match_operand 2 "const_int_operand" "n")))]
+ "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
+ "j\t%1"
+ [(set_attr "op_type" "RI")
+ (set_attr "type" "branch")])
+
+(define_insn "*sibcall_value_brcl"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
+ (match_operand 2 "const_int_operand" "n")))]
+ "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
+ "jg\t%1"
+ [(set_attr "op_type" "RIL")
+ (set_attr "type" "branch")])
+
+
+;
+; call instruction pattern(s).
+;
+
+(define_expand "call"
+ [(call (match_operand 0 "" "")
+ (match_operand 1 "" ""))
+ (use (match_operand 2 "" ""))]
""
- "")
+{
+ s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX,
+ gen_rtx_REG (Pmode, RETURN_REGNUM));
+ DONE;
+})
(define_insn "*bras"
[(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
(match_operand 1 "const_int_operand" "n"))
(clobber (match_operand 2 "register_operand" "=r"))]
- "TARGET_SMALL_EXEC && GET_MODE (operands[2]) == Pmode"
+ "!SIBLING_CALL_P (insn)
+ && TARGET_SMALL_EXEC
+ && GET_MODE (operands[2]) == Pmode"
"bras\t%2,%0"
[(set_attr "op_type" "RI")
(set_attr "type" "jsr")])
@@ -7041,7 +7087,9 @@
[(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
(match_operand 1 "const_int_operand" "n"))
(clobber (match_operand 2 "register_operand" "=r"))]
- "TARGET_CPU_ZARCH && GET_MODE (operands[2]) == Pmode"
+ "!SIBLING_CALL_P (insn)
+ && TARGET_CPU_ZARCH
+ && GET_MODE (operands[2]) == Pmode"
"brasl\t%2,%0"
[(set_attr "op_type" "RIL")
(set_attr "type" "jsr")])
@@ -7050,7 +7098,7 @@
[(call (mem:QI (match_operand 0 "address_operand" "U"))
(match_operand 1 "const_int_operand" "n"))
(clobber (match_operand 2 "register_operand" "=r"))]
- "GET_MODE (operands[2]) == Pmode"
+ "!SIBLING_CALL_P (insn) && GET_MODE (operands[2]) == Pmode"
{
if (get_attr_op_type (insn) == OP_TYPE_RR)
return "basr\t%2,%0";
@@ -7074,62 +7122,19 @@
(use (match_operand 3 "" ""))]
""
{
- bool plt_call = false;
- rtx insn;
-
- /* Direct function calls need special treatment. */
- if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
- {
- rtx sym = XEXP (operands[1], 0);
-
- /* When calling a global routine in PIC mode, we must
- replace the symbol itself with the PLT stub. */
- if (flag_pic && !SYMBOL_REF_LOCAL_P (sym))
- {
- sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), UNSPEC_PLT);
- sym = gen_rtx_CONST (Pmode, sym);
- plt_call = true;
- }
-
- /* Unless we can use the bras(l) insn, force the
- routine address into a register. */
- if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
- {
- if (flag_pic)
- sym = legitimize_pic_address (sym, 0);
- else
- sym = force_reg (Pmode, sym);
- }
-
- operands[1] = gen_rtx_MEM (QImode, sym);
- }
-
- /* Emit insn. */
- insn = emit_call_insn (
- gen_call_value_exp (operands[0], operands[1], operands[2],
- gen_rtx_REG (Pmode, RETURN_REGNUM)));
-
- /* 31-bit PLT stubs use the GOT register implicitly. */
- if (!TARGET_64BIT && plt_call)
- use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
-
+ s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0],
+ gen_rtx_REG (Pmode, RETURN_REGNUM));
DONE;
})
-(define_expand "call_value_exp"
- [(parallel [(set (match_operand 0 "" "")
- (call (match_operand 1 "" "")
- (match_operand 2 "" "")))
- (clobber (match_operand 3 "" ""))])]
- ""
- "")
-
(define_insn "*bras_r"
[(set (match_operand 0 "" "")
(call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
(match_operand:SI 2 "const_int_operand" "n")))
(clobber (match_operand 3 "register_operand" "=r"))]
- "TARGET_SMALL_EXEC && GET_MODE (operands[3]) == Pmode"
+ "!SIBLING_CALL_P (insn)
+ && TARGET_SMALL_EXEC
+ && GET_MODE (operands[3]) == Pmode"
"bras\t%3,%1"
[(set_attr "op_type" "RI")
(set_attr "type" "jsr")])
@@ -7139,7 +7144,9 @@
(call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
(match_operand 2 "const_int_operand" "n")))
(clobber (match_operand 3 "register_operand" "=r"))]
- "TARGET_CPU_ZARCH && GET_MODE (operands[3]) == Pmode"
+ "!SIBLING_CALL_P (insn)
+ && TARGET_CPU_ZARCH
+ && GET_MODE (operands[3]) == Pmode"
"brasl\t%3,%1"
[(set_attr "op_type" "RIL")
(set_attr "type" "jsr")])
@@ -7149,7 +7156,7 @@
(call (mem:QI (match_operand 1 "address_operand" "U"))
(match_operand 2 "const_int_operand" "n")))
(clobber (match_operand 3 "register_operand" "=r"))]
- "GET_MODE (operands[3]) == Pmode"
+ "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
{
if (get_attr_op_type (insn) == OP_TYPE_RR)
return "basr\t%3,%1";
@@ -7227,64 +7234,15 @@
ly\t%0,%1%J2"
[(set_attr "op_type" "RX,RXY")])
-(define_expand "call_value_tls"
- [(set (match_operand 0 "" "")
- (call (const_int 0) (const_int 0)))
- (use (match_operand 1 "" ""))]
- ""
-{
- rtx insn, sym;
-
- if (!flag_pic)
- abort ();
-
- sym = s390_tls_get_offset ();
- sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), UNSPEC_PLT);
- sym = gen_rtx_CONST (Pmode, sym);
-
- /* Unless we can use the bras(l) insn, force the
- routine address into a register. */
- if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
- {
- if (flag_pic)
- sym = legitimize_pic_address (sym, 0);
- else
- sym = force_reg (Pmode, sym);
- }
-
- sym = gen_rtx_MEM (QImode, sym);
-
- /* Emit insn. */
- insn = emit_call_insn (
- gen_call_value_tls_exp (operands[0], sym, const0_rtx,
- gen_rtx_REG (Pmode, RETURN_REGNUM),
- operands[1]));
-
- /* The calling convention of __tls_get_offset uses the
- GOT register implicitly. */
- use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
- use_reg (&CALL_INSN_FUNCTION_USAGE (insn), operands[0]);
- CONST_OR_PURE_CALL_P (insn) = 1;
-
- DONE;
-})
-
-(define_expand "call_value_tls_exp"
- [(parallel [(set (match_operand 0 "" "")
- (call (match_operand 1 "" "")
- (match_operand 2 "" "")))
- (clobber (match_operand 3 "" ""))
- (use (match_operand 4 "" ""))])]
- ""
- "")
-
(define_insn "*bras_tls"
[(set (match_operand 0 "" "")
(call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
(match_operand 2 "const_int_operand" "n")))
(clobber (match_operand 3 "register_operand" "=r"))
(use (match_operand 4 "" ""))]
- "TARGET_SMALL_EXEC && GET_MODE (operands[3]) == Pmode"
+ "!SIBLING_CALL_P (insn)
+ && TARGET_SMALL_EXEC
+ && GET_MODE (operands[3]) == Pmode"
"bras\t%3,%1%J4"
[(set_attr "op_type" "RI")
(set_attr "type" "jsr")])
@@ -7295,7 +7253,9 @@
(match_operand 2 "const_int_operand" "n")))
(clobber (match_operand 3 "register_operand" "=r"))
(use (match_operand 4 "" ""))]
- "TARGET_CPU_ZARCH && GET_MODE (operands[3]) == Pmode"
+ "!SIBLING_CALL_P (insn)
+ && TARGET_CPU_ZARCH
+ && GET_MODE (operands[3]) == Pmode"
"brasl\t%3,%1%J4"
[(set_attr "op_type" "RIL")
(set_attr "type" "jsr")])
@@ -7306,7 +7266,7 @@
(match_operand 2 "const_int_operand" "n")))
(clobber (match_operand 3 "register_operand" "=r"))
(use (match_operand 4 "" ""))]
- "GET_MODE (operands[3]) == Pmode"
+ "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
{
if (get_attr_op_type (insn) == OP_TYPE_RR)
return "basr\t%3,%1%J4";
@@ -7471,7 +7431,7 @@
return "";
}
[(set_attr "op_type" "NN")
- (set (attr "length")
+ (set (attr "length")
(symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
(define_insn "pool_start_31"
@@ -7566,10 +7526,32 @@
""
"s390_emit_prologue (); DONE;")
+(define_insn "prologue_tpf"
+ [(unspec_volatile [(const_int 0)] UNSPECV_TPF_PROLOGUE)
+ (clobber (reg:DI 1))]
+ "TARGET_TPF"
+ "bas\t%%r1,4064"
+ [(set_attr "type" "jsr")
+ (set_attr "op_type" "RX")])
+
(define_expand "epilogue"
[(use (const_int 1))]
""
- "s390_emit_epilogue (); DONE;")
+ "s390_emit_epilogue (false); DONE;")
+
+(define_insn "epilogue_tpf"
+ [(unspec_volatile [(const_int 0)] UNSPECV_TPF_EPILOGUE)
+ (clobber (reg:DI 1))]
+ "TARGET_TPF"
+ "bas\t%%r1,4070"
+ [(set_attr "type" "jsr")
+ (set_attr "op_type" "RX")])
+
+
+(define_expand "sibcall_epilogue"
+ [(use (const_int 0))]
+ ""
+ "s390_emit_epilogue (true); DONE;")
(define_insn "*return"
[(return)
diff --git a/gcc/config/s390/t-tpf b/gcc/config/s390/t-tpf
index c04d5622d6c..2a3421c479d 100644
--- a/gcc/config/s390/t-tpf
+++ b/gcc/config/s390/t-tpf
@@ -10,4 +10,4 @@ SHLIB_MAPFILES += $(srcdir)/config/s390/libgcc-glibc.ver
# Use unwind-dw2-fde-glibc
LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-glibc.c \
$(srcdir)/unwind-sjlj.c $(srcdir)/gthr-gnat.c $(srcdir)/unwind-c.c
-LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c gthr-gnat.c
+LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c
diff --git a/gcc/config/sh/elf.h b/gcc/config/sh/elf.h
index 964d88596c3..f5cfcb667b0 100644
--- a/gcc/config/sh/elf.h
+++ b/gcc/config/sh/elf.h
@@ -95,7 +95,7 @@ while (0)
#define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME) \
do { \
text_section (); \
- fprintf ((FILE), "\t.stabs \"\",%d,0,0,Letext\nLetext:\n", N_SO); \
+ asm_fprintf ((FILE), "\t.stabs \"\",%d,0,0,%LLetext\n%LLetext:\n", N_SO); \
} while (0)
#undef STARTFILE_SPEC
diff --git a/gcc/config/sh/linux.h b/gcc/config/sh/linux.h
index b2ad064f8b4..b01b52d28db 100644
--- a/gcc/config/sh/linux.h
+++ b/gcc/config/sh/linux.h
@@ -112,6 +112,11 @@ do { \
#define LINK_GCC_C_SEQUENCE_SPEC \
"%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
+/* Use --as-needed -lgcc_s for eh support. */
+#ifdef HAVE_LD_AS_NEEDED
+#define USE_LD_AS_NEEDED 1
+#endif
+
/* Output assembler code to STREAM to call the profiler. */
#undef FUNCTION_PROFILER
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index b00ebde2cb0..7abdac48922 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -109,7 +109,7 @@ extern int sh_handle_pragma (int (*)(void), void (*)(int), const char *);
extern struct rtx_def *get_fpscr_rtx (void);
extern int sh_media_register_for_return (void);
extern void sh_expand_prologue (void);
-extern void sh_expand_epilogue (void);
+extern void sh_expand_epilogue (bool);
extern int sh_need_epilogue (void);
extern void sh_set_return_address (rtx, rtx);
extern int initial_elimination_offset (int, int);
@@ -141,5 +141,6 @@ 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 const char *sh_pch_valid_p (const void *data_p, size_t sz);
+extern bool sh_promote_prototypes (tree);
#endif /* ! GCC_SH_PROTOS_H */
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index a790c43a043..30526c2e694 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -272,7 +272,6 @@ struct save_schedule_s;
static struct save_entry_s *sh5_schedule_saves (HARD_REG_SET *,
struct save_schedule_s *, int);
-static bool sh_promote_prototypes (tree);
static rtx sh_struct_value_rtx (tree, int);
static bool sh_return_in_memory (tree, tree);
static rtx sh_builtin_saveregs (void);
@@ -339,7 +338,7 @@ static tree sh_build_builtin_va_list (void);
TARGET_SCHED_INIT_GLOBAL: Added a new target hook in the generic
scheduler; it is called inside the sched_init function just after
find_insn_reg_weights function call. It is used to calculate the SImode
- and SFmode weights of insns of basic blocks; much similiar to what
+ and SFmode weights of insns of basic blocks; much similar to what
find_insn_reg_weights does.
TARGET_SCHED_FINISH_GLOBAL: Corresponding cleanup hook.
@@ -4631,8 +4630,9 @@ static int extra_push;
/* Adjust the stack by SIZE bytes. REG holds the rtl of the register to be
adjusted. If epilogue_p is zero, this is for a prologue; otherwise, it's
- for an epilogue. If LIVE_REGS_MASK is nonzero, it points to a HARD_REG_SET
- of all the registers that are about to be restored, and hence dead. */
+ for an epilogue and a negative value means that it's for a sibcall
+ epilogue. If LIVE_REGS_MASK is nonzero, it points to a HARD_REG_SET of
+ all the registers that are about to be restored, and hence dead. */
static void
output_stack_adjust (int size, rtx reg, int epilogue_p,
@@ -4667,17 +4667,27 @@ output_stack_adjust (int size, rtx reg, int epilogue_p,
/* If TEMP is invalid, we could temporarily save a general
register to MACL. However, there is currently no need
to handle this case, so just abort when we see it. */
- if (current_function_interrupt
+ if (epilogue_p < 0
+ || current_function_interrupt
|| ! call_used_regs[temp] || fixed_regs[temp])
temp = -1;
- if (temp < 0 && ! current_function_interrupt)
+ if (temp < 0 && ! current_function_interrupt
+ && (TARGET_SHMEDIA || epilogue_p >= 0))
{
HARD_REG_SET temps;
COPY_HARD_REG_SET (temps, call_used_reg_set);
AND_COMPL_HARD_REG_SET (temps, call_fixed_reg_set);
- if (epilogue_p)
+ if (epilogue_p > 0)
{
- for (i = 0; i < HARD_REGNO_NREGS (FIRST_RET_REG, DImode); i++)
+ int nreg = 0;
+ if (current_function_return_rtx)
+ {
+ enum machine_mode mode;
+ mode = GET_MODE (current_function_return_rtx);
+ if (BASE_RETURN_VALUE_REG (mode) == FIRST_RET_REG)
+ nreg = HARD_REGNO_NREGS (FIRST_RET_REG, mode);
+ }
+ for (i = 0; i < nreg; i++)
CLEAR_HARD_REG_BIT (temps, FIRST_RET_REG + i);
if (current_function_calls_eh_return)
{
@@ -4686,12 +4696,15 @@ output_stack_adjust (int size, rtx reg, int epilogue_p,
CLEAR_HARD_REG_BIT (temps, EH_RETURN_DATA_REGNO (i));
}
}
- else
+ if (TARGET_SHMEDIA && epilogue_p < 0)
+ for (i = FIRST_TARGET_REG; i <= LAST_TARGET_REG; i++)
+ CLEAR_HARD_REG_BIT (temps, i);
+ if (epilogue_p <= 0)
{
for (i = FIRST_PARM_REG;
i < FIRST_PARM_REG + NPARM_REGS (SImode); i++)
CLEAR_HARD_REG_BIT (temps, i);
- if (current_function_needs_context)
+ if (cfun->static_chain_decl != NULL)
CLEAR_HARD_REG_BIT (temps, STATIC_CHAIN_REGNUM);
}
temp = scavenge_reg (&temps);
@@ -4699,7 +4712,55 @@ output_stack_adjust (int size, rtx reg, int epilogue_p,
if (temp < 0 && live_regs_mask)
temp = scavenge_reg (live_regs_mask);
if (temp < 0)
- abort ();
+ {
+ /* If we reached here, the most likely case is the (sibcall)
+ epilogue for non SHmedia. Put a special push/pop sequence
+ for such case as the last resort. This looks lengthy but
+ would not be problem because it seems to be very rare. */
+ if (! TARGET_SHMEDIA && epilogue_p)
+ {
+ rtx adj_reg, tmp_reg, mem;
+
+ /* ??? There is still the slight possibility that r4 or r5
+ have been reserved as fixed registers or assigned as
+ global registers, and they change during an interrupt.
+ There are possible ways to handle this:
+ - If we are adjusting the frame pointer (r14), we can do
+ with a single temp register and an ordinary push / pop
+ on the stack.
+ - Grab any call-used or call-saved registers (i.e. not
+ fixed or globals) for the temps we need. We might
+ also grab r14 if we are adjusting the stack pointer.
+ If we can't find enough available registers, issue
+ a diagnostic and abort - the user must have reserved
+ way too many registers.
+ But since all this is rather unlikely to happen and
+ would require extra testing, we just abort if r4 / r5
+ are not available. */
+ if (fixed_regs[4] || fixed_regs[5]
+ || global_regs[4] || global_regs[5])
+ abort ();
+
+ adj_reg = gen_rtx_REG (GET_MODE (reg), 4);
+ tmp_reg = gen_rtx_REG (GET_MODE (reg), 5);
+ emit_move_insn (gen_rtx_MEM (Pmode, reg), adj_reg);
+ emit_insn (GEN_MOV (adj_reg, GEN_INT (size)));
+ emit_insn (GEN_ADD3 (adj_reg, adj_reg, reg));
+ mem = gen_rtx_MEM (Pmode, gen_rtx_PRE_DEC (Pmode, adj_reg));
+ emit_move_insn (mem, tmp_reg);
+ emit_move_insn (tmp_reg, gen_rtx_MEM (Pmode, reg));
+ mem = gen_rtx_MEM (Pmode, gen_rtx_PRE_DEC (Pmode, adj_reg));
+ emit_move_insn (mem, tmp_reg);
+ emit_move_insn (reg, adj_reg);
+ mem = gen_rtx_MEM (Pmode, gen_rtx_POST_INC (Pmode, reg));
+ emit_move_insn (adj_reg, mem);
+ mem = gen_rtx_MEM (Pmode, gen_rtx_POST_INC (Pmode, reg));
+ emit_move_insn (tmp_reg, mem);
+ return;
+ }
+ else
+ abort ();
+ }
const_reg = gen_rtx_REG (GET_MODE (reg), temp);
/* If SIZE is negative, subtract the positive value.
@@ -5100,7 +5161,7 @@ sh5_schedule_saves (HARD_REG_SET *live_regs_mask, save_schedule *schedule,
if (call_used_regs[i] && ! fixed_regs[i] && i != PR_MEDIA_REG
&& ! FUNCTION_ARG_REGNO_P (i)
&& i != FIRST_RET_REG
- && ! (current_function_needs_context && i == STATIC_CHAIN_REGNUM)
+ && ! (cfun->static_chain_decl != NULL && i == STATIC_CHAIN_REGNUM)
&& ! (current_function_calls_eh_return
&& (i == EH_RETURN_STACKADJ_REGNO
|| ((unsigned) i <= EH_RETURN_DATA_REGNO (0)
@@ -5539,7 +5600,7 @@ sh_expand_prologue (void)
}
void
-sh_expand_epilogue (void)
+sh_expand_epilogue (bool sibcall_p)
{
HARD_REG_SET live_regs_mask;
int d, i;
@@ -5548,6 +5609,7 @@ sh_expand_epilogue (void)
int save_flags = target_flags;
int frame_size, save_size;
int fpscr_deferred = 0;
+ int e = sibcall_p ? -1 : 1;
d = calc_live_regs (&live_regs_mask);
@@ -5582,7 +5644,7 @@ sh_expand_epilogue (void)
if (frame_pointer_needed)
{
- output_stack_adjust (frame_size, frame_pointer_rtx, 1, &live_regs_mask);
+ output_stack_adjust (frame_size, frame_pointer_rtx, e, &live_regs_mask);
/* We must avoid moving the stack pointer adjustment past code
which reads from the local frame, else an interrupt could
@@ -5598,7 +5660,7 @@ sh_expand_epilogue (void)
occur after the SP adjustment and clobber data in the local
frame. */
emit_insn (gen_blockage ());
- output_stack_adjust (frame_size, stack_pointer_rtx, 1, &live_regs_mask);
+ output_stack_adjust (frame_size, stack_pointer_rtx, e, &live_regs_mask);
}
if (SHMEDIA_REGS_STACK_ADJUST ())
@@ -5771,7 +5833,7 @@ sh_expand_epilogue (void)
output_stack_adjust (extra_push + current_function_pretend_args_size
+ save_size + d_rounding
+ current_function_args_info.stack_regs * 8,
- stack_pointer_rtx, 1, NULL);
+ stack_pointer_rtx, e, NULL);
if (current_function_calls_eh_return)
emit_insn (GEN_ADD3 (stack_pointer_rtx, stack_pointer_rtx,
@@ -5799,7 +5861,7 @@ sh_need_epilogue (void)
rtx epilogue;
start_sequence ();
- sh_expand_epilogue ();
+ sh_expand_epilogue (0);
epilogue = get_insns ();
end_sequence ();
sh_need_epilogue_known = (epilogue == NULL ? -1 : 1);
@@ -6352,7 +6414,7 @@ sh_va_arg (tree valist, tree type)
return result;
}
-static bool
+bool
sh_promote_prototypes (tree type)
{
if (TARGET_HITACHI)
@@ -9483,7 +9545,7 @@ sh_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
if (optimize > 0 && flag_schedule_insns_after_reload)
{
/* Release all memory allocated by flow. */
- free_basic_block_vars (0);
+ free_basic_block_vars ();
/* Release all memory held by regsets now. */
regset_release_memory ();
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 6bdfefe7932..32cbb2c2438 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -1644,6 +1644,7 @@ extern enum reg_class reg_class_from_letter[];
|| TREE_CODE (VALTYPE) == CHAR_TYPE \
|| TREE_CODE (VALTYPE) == REAL_TYPE \
|| TREE_CODE (VALTYPE) == OFFSET_TYPE)) \
+ && sh_promote_prototypes (VALTYPE) \
? (TARGET_SHMEDIA ? DImode : SImode) : TYPE_MODE (VALTYPE)), \
BASE_RETURN_VALUE_REG (TYPE_MODE (VALTYPE)))
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index a31e8b125c1..d3b4c9466ed 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -6467,7 +6467,7 @@
""
"
{
- sh_expand_epilogue ();
+ sh_expand_epilogue (1);
if (TARGET_SHCOMPACT)
{
rtx insn, set;
@@ -7348,7 +7348,7 @@ mov.l\\t1f,r0\\n\\
""
"
{
- sh_expand_epilogue ();
+ sh_expand_epilogue (0);
emit_jump_insn (gen_return ());
DONE;
}")
diff --git a/gcc/config/sparc/freebsd.h b/gcc/config/sparc/freebsd.h
index 7cc596d02c9..d8dfbf0ca47 100644
--- a/gcc/config/sparc/freebsd.h
+++ b/gcc/config/sparc/freebsd.h
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+#undef SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS \
{ "fbsd_dynamic_linker", FBSD_DYNAMIC_LINKER }
diff --git a/gcc/config/sparc/linux.h b/gcc/config/sparc/linux.h
index ecb473152ae..107880f401d 100644
--- a/gcc/config/sparc/linux.h
+++ b/gcc/config/sparc/linux.h
@@ -256,6 +256,11 @@ do { \
#define LINK_GCC_C_SEQUENCE_SPEC \
"%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
+/* Use --as-needed -lgcc_s for eh support. */
+#ifdef HAVE_LD_AS_NEEDED
+#define USE_LD_AS_NEEDED 1
+#endif
+
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
diff --git a/gcc/config/sparc/linux64.h b/gcc/config/sparc/linux64.h
index 9820156fd07..991975a26ad 100644
--- a/gcc/config/sparc/linux64.h
+++ b/gcc/config/sparc/linux64.h
@@ -39,7 +39,9 @@ Boston, MA 02111-1307, USA. */
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
-#if TARGET_CPU_DEFAULT == TARGET_CPU_v9 || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc
+#if TARGET_CPU_DEFAULT == TARGET_CPU_v9 \
+ || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc \
+ || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc3
/* A 64 bit v9 compiler with stack-bias,
in a Medium/Low code model environment. */
@@ -334,6 +336,11 @@ do { \
#define LINK_GCC_C_SEQUENCE_SPEC \
"%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
+/* Use --as-needed -lgcc_s for eh support. */
+#ifdef HAVE_LD_AS_NEEDED
+#define USE_LD_AS_NEEDED 1
+#endif
+
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
diff --git a/gcc/config/sparc/sol2-bi.h b/gcc/config/sparc/sol2-bi.h
index eab3a1abc5e..6371acc9d7e 100644
--- a/gcc/config/sparc/sol2-bi.h
+++ b/gcc/config/sparc/sol2-bi.h
@@ -215,10 +215,3 @@
#else
#define MULTILIB_DEFAULTS { "m64" }
#endif
-
-#undef PREFERRED_DEBUGGING_TYPE
-#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
-
-#if defined(HAVE_AS_GDWARF2_DEBUG_FLAG) && defined(HAVE_AS_GSTABS_DEBUG_FLAG)
-# define ASM_DEBUG_SPEC "%{gstabs*:--gstabs}%{!gstabs*:%{g*:--gdwarf2}}"
-#endif
diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h
index 0908aaa5ea5..4b1f9f0d3be 100644
--- a/gcc/config/sparc/sparc-protos.h
+++ b/gcc/config/sparc/sparc-protos.h
@@ -25,6 +25,7 @@ Boston, MA 02111-1307, USA. */
#define __SPARC_PROTOS_H__
extern bool sparc_emitting_epilogue;
+extern bool sparc_skip_caller_unimp;
#ifdef TREE_CODE
extern struct rtx_def *function_value (tree, enum machine_mode, int);
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 76ccb34eade..278ca9a26b0 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -48,17 +48,6 @@ Boston, MA 02111-1307, USA. */
#include "target-def.h"
#include "cfglayout.h"
-/* 1 if the caller has placed an "unimp" insn immediately after the call.
- This is used in v8 code when calling a function that returns a structure.
- v9 doesn't have this. Be careful to have this test be the same as that
- used on the call. */
-
-#define SKIP_CALLERS_UNIMP_P \
-(!TARGET_ARCH64 && current_function_returns_struct \
- && ! integer_zerop (DECL_SIZE (DECL_RESULT (current_function_decl))) \
- && (TREE_CODE (DECL_SIZE (DECL_RESULT (current_function_decl))) \
- == INTEGER_CST))
-
/* Global variables for machine-dependent things. */
/* Size of frame. Need to know this to emit return insns from leaf procedures.
@@ -81,6 +70,7 @@ rtx sparc_compare_op0, sparc_compare_op1;
/* Coordinate with the md file wrt special insns created by
sparc_function_epilogue. */
bool sparc_emitting_epilogue;
+bool sparc_skip_caller_unimp;
/* Vector to say how input registers are mapped to output registers.
HARD_FRAME_POINTER_REGNUM cannot be remapped by this function to
@@ -1290,10 +1280,6 @@ input_operand (rtx op, enum machine_mode mode)
if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
return 0;
- /* Accept CONSTANT_P_RTX, since it will be gone by CSE1 and result in 0/1. */
- if (GET_CODE (op) == CONSTANT_P_RTX)
- return 1;
-
/* Allow any one instruction integer constant, and all CONST_INT
variants when we are working in DImode and !arch64. */
if (GET_MODE_CLASS (mode) == MODE_INT
@@ -4498,6 +4484,17 @@ sparc_function_epilogue (FILE *file,
{
const char *ret;
+ /* True if the caller has placed an "unimp" insn immediately after the call.
+ This insn is used in the 32-bit ABI when calling a function that returns
+ a non zero-sized structure. The 64-bit ABI doesn't have it. Be careful
+ to have this test be the same as that used on the call. */
+ sparc_skip_caller_unimp =
+ ! TARGET_ARCH64
+ && current_function_returns_struct
+ && (TREE_CODE (DECL_SIZE (DECL_RESULT (current_function_decl)))
+ == INTEGER_CST)
+ && ! integer_zerop (DECL_SIZE (DECL_RESULT (current_function_decl)));
+
if (current_function_epilogue_delay_list == 0)
{
/* If code does not drop into the epilogue, we need
@@ -4532,9 +4529,9 @@ sparc_function_epilogue (FILE *file,
/* Work out how to skip the caller's unimp instruction if required. */
if (leaf_function)
- ret = (SKIP_CALLERS_UNIMP_P ? "jmp\t%o7+12" : "retl");
+ ret = (sparc_skip_caller_unimp ? "jmp\t%o7+12" : "retl");
else
- ret = (SKIP_CALLERS_UNIMP_P ? "jmp\t%i7+12" : "ret");
+ ret = (sparc_skip_caller_unimp ? "jmp\t%i7+12" : "ret");
if (! leaf_function)
{
@@ -4542,7 +4539,7 @@ sparc_function_epilogue (FILE *file,
{
if (current_function_epilogue_delay_list)
abort ();
- if (SKIP_CALLERS_UNIMP_P)
+ if (sparc_skip_caller_unimp)
abort ();
fputs ("\trestore\n\tretl\n\tadd\t%sp, %g1, %sp\n", file);
@@ -4555,7 +4552,7 @@ sparc_function_epilogue (FILE *file,
if (TARGET_V9 && ! epilogue_renumber (&delay, 1))
{
epilogue_renumber (&delay, 0);
- fputs (SKIP_CALLERS_UNIMP_P
+ fputs (sparc_skip_caller_unimp
? "\treturn\t%i7+12\n"
: "\treturn\t%i7+8\n", file);
final_scan_insn (XEXP (current_function_epilogue_delay_list, 0),
@@ -4588,7 +4585,7 @@ sparc_function_epilogue (FILE *file,
sparc_emitting_epilogue = false;
}
}
- else if (TARGET_V9 && ! SKIP_CALLERS_UNIMP_P)
+ else if (TARGET_V9 && ! sparc_skip_caller_unimp)
fputs ("\treturn\t%i7+8\n\tnop\n", file);
else
fprintf (file, "\t%s\n\trestore\n", ret);
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 2c388f99c8a..130d58c84f8 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -7321,9 +7321,12 @@
{
rtx fn_rtx;
- if (GET_MODE (operands[0]) != FUNCTION_MODE)
+ if (GET_MODE (operands[0]) != FUNCTION_MODE)
abort ();
+ if (GET_CODE (operands[3]) != CONST_INT)
+ abort();
+
if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
{
/* This is really a PIC sequence. We want to represent
@@ -7333,6 +7336,7 @@
call-clobbered registers? We lose this if it is a JUMP_INSN.
Why cannot we have delay slots filled if it were a CALL? */
+ /* We accept negative sizes for untyped calls. */
if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
emit_jump_insn
(gen_rtx_PARALLEL
@@ -7353,6 +7357,7 @@
fn_rtx = operands[0];
+ /* We accept negative sizes for untyped calls. */
if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
emit_call_insn
(gen_rtx_PARALLEL
@@ -7419,7 +7424,7 @@
(match_operand 2 "immediate_operand" "")
(clobber (reg:SI 15))]
;;- Do not use operand 1 for most machines.
- "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
+ "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
"call\t%a0, %1\n\tnop\n\tunimp\t%2"
[(set_attr "type" "call_no_delay_slot")
(set_attr "length" "3")])
@@ -7432,7 +7437,7 @@
(match_operand 2 "immediate_operand" "")
(clobber (reg:SI 15))]
;;- Do not use operand 1 for most machines.
- "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
+ "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
"call\t%a0, %1\n\tnop\n\tunimp\t%2"
[(set_attr "type" "call_no_delay_slot")
(set_attr "length" "3")])
@@ -7450,7 +7455,8 @@
[(set_attr "type" "call_no_delay_slot")
(set_attr "length" "3")])
-;; This is a call that wants a structure value.
+;; This is a call that may want a structure value. This is used for
+;; untyped_calls.
(define_insn "*call_symbolic_untyped_struct_value_sp32"
[(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
(match_operand 1 "" ""))
@@ -8083,7 +8089,7 @@
(return)]
"sparc_emitting_epilogue"
{
- if (! TARGET_ARCH64 && current_function_returns_struct)
+ if (sparc_skip_caller_unimp)
return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
|| IN_OR_GLOBAL_P (operands[1])))
@@ -8100,7 +8106,7 @@
(return)]
"sparc_emitting_epilogue"
{
- if (! TARGET_ARCH64 && current_function_returns_struct)
+ if (sparc_skip_caller_unimp)
return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
|| IN_OR_GLOBAL_P (operands[1])))
@@ -8117,7 +8123,7 @@
(return)]
"sparc_emitting_epilogue"
{
- if (! TARGET_ARCH64 && current_function_returns_struct)
+ if (sparc_skip_caller_unimp)
return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
|| IN_OR_GLOBAL_P (operands[1])))
@@ -8134,7 +8140,7 @@
(return)]
"sparc_emitting_epilogue"
{
- if (! TARGET_ARCH64 && current_function_returns_struct)
+ if (sparc_skip_caller_unimp)
return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
@@ -8165,7 +8171,7 @@
(return)]
"sparc_emitting_epilogue"
{
- if (! TARGET_ARCH64 && current_function_returns_struct)
+ if (sparc_skip_caller_unimp)
return "jmp\t%%i7+12\n\trestore %r1, %2, %Y0";
/* If operands are global or in registers, can use return */
else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
@@ -8185,7 +8191,7 @@
(return)]
"sparc_emitting_epilogue && ! TARGET_CM_MEDMID"
{
- if (! TARGET_ARCH64 && current_function_returns_struct)
+ if (sparc_skip_caller_unimp)
return "jmp\t%%i7+12\n\trestore %r1, %%lo(%a2), %Y0";
/* If operands are global or in registers, can use return */
else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
diff --git a/gcc/config/t-linux b/gcc/config/t-linux
index f25ab6430e9..f3e792bcc01 100644
--- a/gcc/config/t-linux
+++ b/gcc/config/t-linux
@@ -10,4 +10,4 @@ SHLIB_MAPFILES += $(srcdir)/config/libgcc-glibc.ver
# Use unwind-dw2-fde-glibc
LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-glibc.c \
$(srcdir)/unwind-sjlj.c $(srcdir)/gthr-gnat.c $(srcdir)/unwind-c.c
-LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c gthr-gnat.c
+LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c
diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c
index 83372624309..f9e54cc2df9 100644
--- a/gcc/config/v850/v850.c
+++ b/gcc/config/v850/v850.c
@@ -1136,7 +1136,6 @@ movsi_source_operand (rtx op, enum machine_mode mode)
must be done with HIGH & LO_SUM patterns. */
if (CONSTANT_P (op)
&& GET_CODE (op) != HIGH
- && GET_CODE (op) != CONSTANT_P_RTX
&& !(GET_CODE (op) == CONST_INT
&& (CONST_OK_FOR_J (INTVAL (op))
|| CONST_OK_FOR_K (INTVAL (op))
diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
index 6c059ff6999..89d8c9ddf3d 100644
--- a/gcc/config/xtensa/xtensa.c
+++ b/gcc/config/xtensa/xtensa.c
@@ -572,7 +572,8 @@ call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
tree callee, callee_sec, caller_sec;
- if (GET_CODE (op) != SYMBOL_REF || !SYMBOL_REF_LOCAL_P (op))
+ if (GET_CODE (op) != SYMBOL_REF
+ || !SYMBOL_REF_LOCAL_P (op) || SYMBOL_REF_EXTERNAL_P (op))
return FALSE;
/* Don't attempt a direct call if the callee is known to be in
@@ -626,11 +627,6 @@ move_operand (rtx op, enum machine_mode mode)
case HImode:
case QImode:
- /* Accept CONSTANT_P_RTX, since it will be gone by CSE1 and
- result in 0/1. */
- if (GET_CODE (op) == CONSTANT_P_RTX)
- return TRUE;
-
if (GET_CODE (op) == CONST_INT && xtensa_simm12b (INTVAL (op)))
return TRUE;
break;
@@ -1251,7 +1247,6 @@ int
xtensa_emit_move_sequence (rtx *operands, enum machine_mode mode)
{
if (CONSTANT_P (operands[1])
- && GET_CODE (operands[1]) != CONSTANT_P_RTX
&& (GET_CODE (operands[1]) != CONST_INT
|| !xtensa_simm12b (INTVAL (operands[1]))))
{
@@ -2228,7 +2223,7 @@ long
compute_frame_size (int size)
{
/* Add space for the incoming static chain value. */
- if (current_function_needs_context)
+ if (cfun->static_chain_decl != NULL)
size += (1 * UNITS_PER_WORD);
xtensa_current_frame_size =
diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h
index 3d2432be9e1..d04560b8c7c 100644
--- a/gcc/config/xtensa/xtensa.h
+++ b/gcc/config/xtensa/xtensa.h
@@ -1060,7 +1060,8 @@ typedef struct xtensa_args
operand on the target machine when generating position independent
code. */
#define LEGITIMATE_PIC_OPERAND_P(X) \
- ((GET_CODE (X) != SYMBOL_REF || SYMBOL_REF_LOCAL_P (X)) \
+ ((GET_CODE (X) != SYMBOL_REF \
+ || (SYMBOL_REF_LOCAL_P (X) && !SYMBOL_REF_EXTERNAL_P (X))) \
&& GET_CODE (X) != LABEL_REF \
&& GET_CODE (X) != CONST)
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 6e13568a651..0b557c12e8c 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -1999,7 +1999,8 @@
""
{
rtx addr = XEXP (operands[0], 0);
- if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (addr))
+ if (flag_pic && GET_CODE (addr) == SYMBOL_REF
+ && (!SYMBOL_REF_LOCAL_P (addr) || SYMBOL_REF_EXTERNAL_P (addr)))
addr = gen_sym_PLT (addr);
if (!call_insn_operand (addr, VOIDmode))
XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
@@ -2023,7 +2024,8 @@
""
{
rtx addr = XEXP (operands[1], 0);
- if (flag_pic && GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (addr))
+ if (flag_pic && GET_CODE (addr) == SYMBOL_REF
+ && (!SYMBOL_REF_LOCAL_P (addr) || SYMBOL_REF_EXTERNAL_P (addr)))
addr = gen_sym_PLT (addr);
if (!call_insn_operand (addr, VOIDmode))
XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
diff --git a/gcc/configure b/gcc/configure
index 27c0a6cba14..92d222c4276 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -309,7 +309,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os build_subdir host_subdir target_subdir GENINSRC CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT NO_MINUS_C_MINUS_O OUTPUT_OPTION CPP strict1_warn warn_cflags WERROR nocommon_flag EGREP valgrind_path valgrind_path_defines valgrind_command coverage_flags enable_multilib enable_shared TARGET_SYSTEM_ROOT TARGET_SYSTEM_ROOT_DEFINE CROSS_SYSTEM_HEADER_DIR onestep SET_MAKE AWK LN LN_S RANLIB ac_ct_RANLIB INSTALL INSTALL_PROGRAM INSTALL_DATA make_compare_target have_mktemp_command MAKEINFO BUILD_INFO GENERATED_MANPAGES FLEX BISON stage1_cflags COLLECT2_LIBS GNAT_LIBEXC LDEXP_LIB TARGET_GETGROUPS_T LIBICONV LIBICONV_DEP manext objext gthread_flags extra_modes_file FORBUILD PACKAGE VERSION USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS CROSS ALL SYSTEM_HEADER_DIR inhibit_libc BUILD_PREFIX BUILD_PREFIX_1 CC_FOR_BUILD BUILD_CFLAGS STMP_FIXINC STMP_FIXPROTO collect2 libgcc_visibility GGC zlibdir zlibinc MAINT gcc_tooldir dollar slibdir objdir subdirs srcdir all_boot_languages all_compilers all_gtfiles all_gtfiles_files_langs all_gtfiles_files_files all_lang_makefrags all_lang_makefiles all_languages all_stagestuff build_exeext build_install_headers_dir build_xm_file_list build_xm_include_list build_xm_defines check_languages cc_set_by_configure quoted_cc_set_by_configure cpp_install_dir xmake_file tmake_file extra_gcc_objs extra_headers_list extra_objs extra_parts extra_passes extra_programs float_h_file gcc_config_arguments gcc_gxx_include_dir libstdcxx_incdir gcc_version gcc_version_full gcc_version_trigger host_exeext host_xm_file_list host_xm_include_list host_xm_defines out_host_hook_obj install lang_opt_files lang_specs_files lang_tree_files local_prefix md_file objc_boehm_gc out_file out_object_file stage_prefix_set_by_configure quoted_stage_prefix_set_by_configure symbolic_link thread_file tm_file_list tm_include_list tm_defines tm_p_file_list tm_p_include_list xm_file_list xm_include_list xm_defines target_noncanonical c_target_objs cxx_target_objs target_cpu_default LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os build_subdir host_subdir target_subdir GENINSRC CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT NO_MINUS_C_MINUS_O OUTPUT_OPTION CPP strict1_warn warn_cflags WERROR nocommon_flag EGREP valgrind_path valgrind_path_defines valgrind_command coverage_flags TREEBROWSER enable_multilib enable_shared TARGET_SYSTEM_ROOT TARGET_SYSTEM_ROOT_DEFINE CROSS_SYSTEM_HEADER_DIR onestep SET_MAKE AWK LN LN_S RANLIB ac_ct_RANLIB INSTALL INSTALL_PROGRAM INSTALL_DATA make_compare_target have_mktemp_command MAKEINFO BUILD_INFO GENERATED_MANPAGES FLEX BISON stage1_cflags COLLECT2_LIBS GNAT_LIBEXC LDEXP_LIB TARGET_GETGROUPS_T LIBICONV LIBICONV_DEP manext objext gthread_flags extra_modes_file FORBUILD PACKAGE VERSION USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS CROSS ALL SYSTEM_HEADER_DIR inhibit_libc BUILD_PREFIX BUILD_PREFIX_1 CC_FOR_BUILD BUILD_CFLAGS STMP_FIXINC STMP_FIXPROTO collect2 libgcc_visibility GGC zlibdir zlibinc MAINT ANDER BANSHEEINC BANSHEELIB gcc_tooldir dollar slibdir objdir subdirs srcdir all_boot_languages all_compilers all_gtfiles all_gtfiles_files_langs all_gtfiles_files_files all_lang_makefrags all_lang_makefiles all_languages all_stagestuff build_exeext build_install_headers_dir build_xm_file_list build_xm_include_list build_xm_defines check_languages cc_set_by_configure quoted_cc_set_by_configure cpp_install_dir xmake_file tmake_file extra_gcc_objs extra_headers_list extra_objs extra_parts extra_passes extra_programs float_h_file gcc_config_arguments gcc_gxx_include_dir libstdcxx_incdir gcc_version gcc_version_full gcc_version_trigger host_exeext host_xm_file_list host_xm_include_list host_xm_defines out_host_hook_obj install lang_opt_files lang_specs_files lang_tree_files local_prefix md_file objc_boehm_gc out_file out_object_file stage_prefix_set_by_configure quoted_stage_prefix_set_by_configure symbolic_link thread_file tm_file_list tm_include_list tm_defines tm_p_file_list tm_p_include_list xm_file_list xm_include_list xm_defines target_noncanonical c_target_objs cxx_target_objs target_cpu_default GMPLIBS GMPINC LIBOBJS LTLIBOBJS'
ac_subst_files='language_hooks'
# Initialize some variables set by options.
@@ -770,6 +770,14 @@ ac_env_CPP_set=${CPP+set}
ac_env_CPP_value=$CPP
ac_cv_env_CPP_set=${CPP+set}
ac_cv_env_CPP_value=$CPP
+ac_env_GMPLIBS_set=${GMPLIBS+set}
+ac_env_GMPLIBS_value=$GMPLIBS
+ac_cv_env_GMPLIBS_set=${GMPLIBS+set}
+ac_cv_env_GMPLIBS_value=$GMPLIBS
+ac_env_GMPINC_set=${GMPINC+set}
+ac_env_GMPINC_value=$GMPINC
+ac_cv_env_GMPINC_set=${GMPINC+set}
+ac_cv_env_GMPINC_value=$GMPINC
#
# Report the --help message.
@@ -868,6 +876,7 @@ Optional Features:
optimization. Values are opt, noopt,
default is noopt
--enable-gather-detailed-mem-stats enable detailed memory allocation stats gathering
+ --enable-tree-browser enable the tree browsing routines for debugging
--enable-multilib enable library support for multiple ABIs
--enable-__cxa_atexit enable __cxa_atexit for C++
--enable-threads enable thread usage for target GCC
@@ -915,6 +924,7 @@ Optional Packages:
--with-gc={page,zone} choose the garbage collection mechanism to use
with the compiler
--with-system-zlib use installed libz
+ --with-libbanshee enable libbanshee
--with-slibdir=DIR shared libraries in DIR LIBDIR
Some influential environment variables:
@@ -925,6 +935,8 @@ Some influential environment variables:
CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
headers in a nonstandard directory <include dir>
CPP C preprocessor
+ GMPLIBS How to link GMP
+ GMPINC How to find GMP include files
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
@@ -1017,7 +1029,7 @@ esac
else
echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
fi
- cd "$ac_popdir"
+ cd $ac_popdir
done
fi
@@ -1694,8 +1706,9 @@ if test "${with_ld+set}" = set; then
fi;
if test x"${DEFAULT_LINKER+set}" = x"set"; then
if test ! -x "$DEFAULT_LINKER"; then
- { echo "$as_me:$LINENO: WARNING: cannot execute: $DEFAULT_LINKER: check --with-ld or env. var. DEFAULT_LINKER" >&5
-echo "$as_me: WARNING: cannot execute: $DEFAULT_LINKER: check --with-ld or env. var. DEFAULT_LINKER" >&2;}
+ { { echo "$as_me:$LINENO: error: cannot execute: $DEFAULT_LINKER: check --with-ld or env. var. DEFAULT_LINKER" >&5
+echo "$as_me: error: cannot execute: $DEFAULT_LINKER: check --with-ld or env. var. DEFAULT_LINKER" >&2;}
+ { (exit 1); exit 1; }; }
elif $DEFAULT_LINKER -v < /dev/null 2>&1 | grep GNU > /dev/null; then
gnu_ld_flag=yes
fi
@@ -1743,8 +1756,9 @@ if test "${with_as+set}" = set; then
fi;
if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then
if test ! -x "$DEFAULT_ASSEMBLER"; then
- { echo "$as_me:$LINENO: WARNING: cannot execute: $DEFAULT_ASSEMBLER: check --with-as or env. var. DEFAULT_ASSEMBLER" >&5
-echo "$as_me: WARNING: cannot execute: $DEFAULT_ASSEMBLER: check --with-as or env. var. DEFAULT_ASSEMBLER" >&2;}
+ { { echo "$as_me:$LINENO: error: cannot execute: $DEFAULT_ASSEMBLER: check --with-as or env. var. DEFAULT_ASSEMBLER" >&5
+echo "$as_me: error: cannot execute: $DEFAULT_ASSEMBLER: check --with-as or env. var. DEFAULT_ASSEMBLER" >&2;}
+ { (exit 1); exit 1; }; }
elif $DEFAULT_ASSEMBLER -v < /dev/null 2>&1 | grep GNU > /dev/null; then
gas_flag=yes
fi
@@ -2352,7 +2366,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2410,7 +2425,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2526,7 +2542,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2580,7 +2597,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2625,7 +2643,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2669,7 +2688,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3075,7 +3095,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3146,7 +3167,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3205,7 +3227,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3265,7 +3288,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3332,7 +3356,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3402,7 +3427,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3472,7 +3498,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3542,7 +3569,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3613,7 +3641,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3685,7 +3714,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3758,7 +3788,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3808,7 +3839,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3866,7 +3898,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -4076,7 +4109,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -4246,7 +4280,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -4309,7 +4344,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -4649,6 +4685,18 @@ _ACEOF
fi
+# Check whether --enable-tree-browser or --disable-tree-browser was given.
+if test "${enable_tree_browser+set}" = set; then
+ enableval="$enable_tree_browser"
+
+else
+ enable_tree_browser=no
+fi;
+if test x$enable_tree_browser = xyes ; then
+ TREEBROWSER=tree-browser.o
+fi
+
+
# -------------------------------
# Miscenalleous configure options
# -------------------------------
@@ -5259,7 +5307,7 @@ if test "${gcc_cv_prog_makeinfo_modern+set}" = set; then
else
ac_prog_version=`$MAKEINFO --version 2>&1 |
sed -n 's/^.*GNU texinfo.* \([0-9][0-9.]*\).*$/\1/p'`
- echo "configure:5262: version of makeinfo is $ac_prog_version" >&5
+ echo "configure:5310: version of makeinfo is $ac_prog_version" >&5
case $ac_prog_version in
'') gcc_cv_prog_makeinfo_modern=no;;
4.[2-9]*)
@@ -5302,7 +5350,7 @@ echo "${ECHO_T}no" >&6
fi
# How about lex?
-if test -f $srcdir/../flex/skel.c; then
+if test x${build} = x${host} && test -f $srcdir/../flex/skel.c; then
FLEX='$(objdir)/../flex/flex'
else
# Extract the first word of "flex", so it can be a program name with args.
@@ -5345,7 +5393,7 @@ fi
# Bison?
# The -L switch is so bison can find its skeleton file.
-if test -f $srcdir/../bison/bison.simple; then
+if test x${build} = x${host} && test -f $srcdir/../bison/bison.simple; then
BISON='$(objdir)/../bison/bison -L $(srcdir)/../bison/'
else
# Extract the first word of "bison", so it can be a program name with args.
@@ -5422,7 +5470,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5492,7 +5541,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5657,7 +5707,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5717,7 +5768,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5778,7 +5830,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5848,7 +5901,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -6122,7 +6176,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -6195,7 +6250,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -6236,7 +6292,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -6438,7 +6495,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -6512,7 +6570,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -6566,7 +6625,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -6644,7 +6704,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -6698,7 +6759,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -6766,7 +6828,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -6896,7 +6959,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -7017,7 +7081,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -7341,7 +7406,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -7453,7 +7519,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -7611,7 +7678,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -7980,7 +8048,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -8030,7 +8099,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -8105,7 +8175,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -8179,7 +8250,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -8257,7 +8329,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -8436,7 +8509,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -8519,7 +8593,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -8587,7 +8662,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -8675,7 +8751,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -8757,7 +8834,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -8823,7 +8901,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -8887,7 +8966,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -9023,7 +9103,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -9106,7 +9187,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -9396,7 +9478,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -9660,7 +9743,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -9714,7 +9798,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -11404,6 +11489,55 @@ fi
;;
i[34567]86-*-* | x86_64-*-*)
+ case $target_os in
+ cygwin* | pe | mingw32*)
+ # Used for DWARF 2 in PE
+ echo "$as_me:$LINENO: checking assembler for .secrel32 relocs" >&5
+echo $ECHO_N "checking assembler for .secrel32 relocs... $ECHO_C" >&6
+if test "${gcc_cv_as_ix86_pe_secrel32+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_ix86_pe_secrel32=no
+ if test $in_tree_gas = yes; then
+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 15 \) \* 1000 + 91`
+ then gcc_cv_as_ix86_pe_secrel32=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo '.text
+foo: nop
+.data
+ .secrel32 foo' > conftest.s
+ if { ac_try='$gcc_cv_as -o conftest.o conftest.s >&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }
+ then
+ if test x$gcc_cv_ld != x \
+ && $gcc_cv_ld -o conftest conftest.o > /dev/null 2>&1; then
+ gcc_cv_as_ix86_pe_secrel32=yes
+ fi
+ rm -f conftest
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_as_ix86_pe_secrel32" >&5
+echo "${ECHO_T}$gcc_cv_as_ix86_pe_secrel32" >&6
+if test $gcc_cv_as_ix86_pe_secrel32 = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GAS_PE_SECREL32_RELOC 1
+_ACEOF
+
+fi
+ ;;
+ esac
+
echo "$as_me:$LINENO: checking assembler for filds and fists mnemonics" >&5
echo $ECHO_N "checking assembler for filds and fists mnemonics... $ECHO_C" >&6
if test "${gcc_cv_as_ix86_filds_fists+set}" = set; then
@@ -11930,7 +12064,10 @@ echo "${ECHO_T}$gcc_cv_ld_pie" >&6
echo "$as_me:$LINENO: checking linker --as-needed support" >&5
echo $ECHO_N "checking linker --as-needed support... $ECHO_C" >&6
-gcc_cv_ld_as_needed=no
+if test "${gcc_cv_ld_as_needed+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_ld_as_needed=no
if test $in_tree_ld = yes ; then
if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2 \
&& test $in_tree_ld_is_elf = yes; then
@@ -11942,6 +12079,10 @@ elif test x$gcc_cv_ld != x; then
gcc_cv_ld_as_needed=yes
fi
fi
+
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_ld_as_needed" >&5
+echo "${ECHO_T}$gcc_cv_ld_as_needed" >&6
if test x"$gcc_cv_ld_as_needed" = xyes; then
cat >>confdefs.h <<\_ACEOF
@@ -11949,8 +12090,6 @@ cat >>confdefs.h <<\_ACEOF
_ACEOF
fi
-echo "$as_me:$LINENO: result: $gcc_cv_ld_as_needed" >&5
-echo "${ECHO_T}$gcc_cv_ld_as_needed" >&6
if test x$with_sysroot = x && test x$host = x$target \
&& test "$prefix" != "/usr" && test "x$prefix" != "x$local_prefix" ; then
@@ -12016,6 +12155,38 @@ else
MAINT='#'
fi
+echo "$as_me:$LINENO: checking whether to use libbanshee for points-to alias analysis" >&5
+echo $ECHO_N "checking whether to use libbanshee for points-to alias analysis... $ECHO_C" >&6
+
+# Check whether --with-libbanshee or --without-libbanshee was given.
+if test "${with_libbanshee+set}" = set; then
+ withval="$with_libbanshee"
+ libbanshee="$with_libbanshee"
+else
+ libbanshee=no
+fi;
+
+if test x"$libbanshee" = xyes; then
+ BANSHEELIB="../libbanshee/points-to/libandersen.a ../libbanshee/engine/libbansheeengine.a ../libbanshee/libcompat/libbansheecompat.a "
+ BANSHEEINC="-I\$(srcdir)/../libbanshee/libcompat -I\$(srcdir)/../libbanshee -I\$(srcdir)/../libbanshee/points-to"
+ ANDER="tree-alias-ander.o"
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_BANSHEE 1
+_ACEOF
+
+else
+ BANSHEELIB=""
+ BANSHEEINC=""
+ ANDER=""
+fi
+echo "$as_me:$LINENO: result: $with_libbanshee" >&5
+echo "${ECHO_T}$with_libbanshee" >&6
+
+
+
+
+
# --------------
# Language hooks
# --------------
@@ -12045,7 +12216,7 @@ all_languages=
all_boot_languages=
all_compilers=
all_stagestuff=
-all_outputs='Makefile fixinc/Makefile gccbug mklibgcc mkheaders'
+all_outputs='Makefile fixinc/Makefile gccbug mklibgcc mkheaders libada-mk'
# List of language makefile fragments.
all_lang_makefrags=
# List of language subdirectory makefiles. Deprecated.
@@ -12315,6 +12486,9 @@ else
fi
fi
+
+
+
# Configure the subdirectories
# AC_CONFIG_SUBDIRS($subdirs)
@@ -12984,6 +13158,7 @@ s,@valgrind_path@,$valgrind_path,;t t
s,@valgrind_path_defines@,$valgrind_path_defines,;t t
s,@valgrind_command@,$valgrind_command,;t t
s,@coverage_flags@,$coverage_flags,;t t
+s,@TREEBROWSER@,$TREEBROWSER,;t t
s,@enable_multilib@,$enable_multilib,;t t
s,@enable_shared@,$enable_shared,;t t
s,@TARGET_SYSTEM_ROOT@,$TARGET_SYSTEM_ROOT,;t t
@@ -13044,6 +13219,9 @@ s,@GGC@,$GGC,;t t
s,@zlibdir@,$zlibdir,;t t
s,@zlibinc@,$zlibinc,;t t
s,@MAINT@,$MAINT,;t t
+s,@ANDER@,$ANDER,;t t
+s,@BANSHEEINC@,$BANSHEEINC,;t t
+s,@BANSHEELIB@,$BANSHEELIB,;t t
s,@gcc_tooldir@,$gcc_tooldir,;t t
s,@dollar@,$dollar,;t t
s,@slibdir@,$slibdir,;t t
@@ -13113,6 +13291,8 @@ s,@target_noncanonical@,$target_noncanonical,;t t
s,@c_target_objs@,$c_target_objs,;t t
s,@cxx_target_objs@,$cxx_target_objs,;t t
s,@target_cpu_default@,$target_cpu_default,;t t
+s,@GMPLIBS@,$GMPLIBS,;t t
+s,@GMPINC@,$GMPINC,;t t
s,@LIBOBJS@,$LIBOBJS,;t t
s,@LTLIBOBJS@,$LTLIBOBJS,;t t
/@language_hooks@/r $language_hooks
@@ -13279,6 +13459,11 @@ esac
+ if test x"$ac_file" != x-; then
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ rm -f "$ac_file"
+ fi
# Let's still pretend it is `configure' which instantiates (i.e., don't
# use $as_me), people would be surprised to read:
# /* config.h. Generated by config.status. */
@@ -13317,12 +13502,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
fi;;
esac
done` || { (exit 1); exit 1; }
-
- if test x"$ac_file" != x-; then
- { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
- rm -f "$ac_file"
- fi
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
sed "$ac_vpsub
diff --git a/gcc/configure.ac b/gcc/configure.ac
index d0c88a70737..33a9f0bc0a0 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -192,7 +192,7 @@ AC_ARG_WITH(ld,
DEFAULT_LINKER="$with_ld")
if test x"${DEFAULT_LINKER+set}" = x"set"; then
if test ! -x "$DEFAULT_LINKER"; then
- AC_MSG_WARN([cannot execute: $DEFAULT_LINKER: check --with-ld or env. var. DEFAULT_LINKER])
+ AC_MSG_ERROR([cannot execute: $DEFAULT_LINKER: check --with-ld or env. var. DEFAULT_LINKER])
elif $DEFAULT_LINKER -v < /dev/null 2>&1 | grep GNU > /dev/null; then
gnu_ld_flag=yes
fi
@@ -226,7 +226,7 @@ AC_ARG_WITH(as,
DEFAULT_ASSEMBLER="$with_as")
if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then
if test ! -x "$DEFAULT_ASSEMBLER"; then
- AC_MSG_WARN([cannot execute: $DEFAULT_ASSEMBLER: check --with-as or env. var. DEFAULT_ASSEMBLER])
+ AC_MSG_ERROR([cannot execute: $DEFAULT_ASSEMBLER: check --with-as or env. var. DEFAULT_ASSEMBLER])
elif $DEFAULT_ASSEMBLER -v < /dev/null 2>&1 | grep GNU > /dev/null; then
gas_flag=yes
fi
@@ -544,6 +544,14 @@ if test x$enable_gather_detailed_mem_stats = xyes ; then
[Define to enable detailed memory allocation stats gathering.])
fi
+AC_ARG_ENABLE(tree-browser,
+[ --enable-tree-browser enable the tree browsing routines for debugging], [],
+[enable_tree_browser=no])
+if test x$enable_tree_browser = xyes ; then
+ TREEBROWSER=tree-browser.o
+fi
+AC_SUBST(TREEBROWSER)
+
# -------------------------------
# Miscenalleous configure options
# -------------------------------
@@ -760,7 +768,7 @@ fi
# How about lex?
dnl Don't use AC_PROG_LEX; we insist on flex.
dnl LEXLIB is not useful in gcc.
-if test -f $srcdir/../flex/skel.c; then
+if test x${build} = x${host} && test -f $srcdir/../flex/skel.c; then
FLEX='$(objdir)/../flex/flex'
else
AC_CHECK_PROG(FLEX, flex, flex, ${CONFIG_SHELL-/bin/sh} ${srcdir}/../missing flex)
@@ -768,7 +776,7 @@ fi
# Bison?
# The -L switch is so bison can find its skeleton file.
-if test -f $srcdir/../bison/bison.simple; then
+if test x${build} = x${host} && test -f $srcdir/../bison/bison.simple; then
BISON='$(objdir)/../bison/bison -L $(srcdir)/../bison/'
else
AC_CHECK_PROG(BISON, bison, bison, ${CONFIG_SHELL-/bin/sh} ${srcdir}/../missing bison)
@@ -2539,6 +2547,26 @@ foo:
changequote(,)dnl
i[34567]86-*-* | x86_64-*-*)
changequote([,])dnl
+ case $target_os in
+ cygwin* | pe | mingw32*)
+ # Used for DWARF 2 in PE
+ gcc_GAS_CHECK_FEATURE([.secrel32 relocs],
+ gcc_cv_as_ix86_pe_secrel32,
+ [2,15,91],,
+[.text
+foo: nop
+.data
+ .secrel32 foo],
+ [if test x$gcc_cv_ld != x \
+ && $gcc_cv_ld -o conftest conftest.o > /dev/null 2>&1; then
+ gcc_cv_as_ix86_pe_secrel32=yes
+ fi
+ rm -f conftest],
+ [AC_DEFINE(HAVE_GAS_PE_SECREL32_RELOC, 1,
+ [Define if your assembler and linker support 32-bit section relative relocs via '.secrel32 label'.])])
+ ;;
+ esac
+
gcc_GAS_CHECK_FEATURE([filds and fists mnemonics],
gcc_cv_as_ix86_filds_fists,
[2,9,0],, [filds mem; fists mem],,
@@ -2754,8 +2782,9 @@ AC_MSG_RESULT($gcc_cv_ld_pie)
# UNSORTED
# --------
-AC_MSG_CHECKING(linker --as-needed support)
-gcc_cv_ld_as_needed=no
+AC_CACHE_CHECK(linker --as-needed support,
+gcc_cv_ld_as_needed,
+[gcc_cv_ld_as_needed=no
if test $in_tree_ld = yes ; then
if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2 \
&& test $in_tree_ld_is_elf = yes; then
@@ -2767,11 +2796,11 @@ elif test x$gcc_cv_ld != x; then
gcc_cv_ld_as_needed=yes
fi
fi
+])
if test x"$gcc_cv_ld_as_needed" = xyes; then
AC_DEFINE(HAVE_LD_AS_NEEDED, 1,
[Define if your linker supports --as-needed and --no-as-needed options.])
fi
-AC_MSG_RESULT($gcc_cv_ld_as_needed)
if test x$with_sysroot = x && test x$host = x$target \
&& test "$prefix" != "/usr" && test "x$prefix" != "x$local_prefix" ; then
@@ -2826,6 +2855,28 @@ else
fi
AC_SUBST(MAINT)dnl
+AC_MSG_CHECKING([whether to use libbanshee for points-to alias analysis])
+AC_ARG_WITH(libbanshee,
+[ --with-libbanshee enable libbanshee],
+libbanshee="$with_libbanshee",
+libbanshee=no)
+
+if test x"$libbanshee" = xyes; then
+ BANSHEELIB="../libbanshee/points-to/libandersen.a ../libbanshee/engine/libbansheeengine.a ../libbanshee/libcompat/libbansheecompat.a "
+ BANSHEEINC="-I\$(srcdir)/../libbanshee/libcompat -I\$(srcdir)/../libbanshee -I\$(srcdir)/../libbanshee/points-to"
+ ANDER="tree-alias-ander.o"
+ AC_DEFINE(HAVE_BANSHEE, 1, [Define if BANSHEE is available])
+else
+ BANSHEELIB=""
+ BANSHEEINC=""
+ ANDER=""
+fi
+AC_MSG_RESULT($with_libbanshee)
+
+AC_SUBST(ANDER)
+AC_SUBST(BANSHEEINC)
+AC_SUBST(BANSHEELIB)
+
# --------------
# Language hooks
# --------------
@@ -2855,7 +2906,7 @@ all_languages=
all_boot_languages=
all_compilers=
all_stagestuff=
-all_outputs='Makefile fixinc/Makefile gccbug mklibgcc mkheaders'
+all_outputs='Makefile fixinc/Makefile gccbug mklibgcc mkheaders libada-mk'
# List of language makefile fragments.
all_lang_makefrags=
# List of language subdirectory makefiles. Deprecated.
@@ -3122,6 +3173,9 @@ else
fi
fi
+AC_ARG_VAR(GMPLIBS,[How to link GMP])
+AC_ARG_VAR(GMPINC,[How to find GMP include files])
+
# Configure the subdirectories
# AC_CONFIG_SUBDIRS($subdirs)
diff --git a/gcc/convert.c b/gcc/convert.c
index dcab84a9aa9..ef0d1f568cf 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -332,6 +332,53 @@ convert_to_integer (tree type, tree expr)
return error_mark_node;
}
+ /* Convert e.g. (long)round(d) -> lround(d). */
+ /* If we're converting to char, we may encounter differing behavior
+ between converting from double->char vs double->long->char.
+ We're in "undefined" territory but we prefer to be conservative,
+ so only proceed in "unsafe" math mode. */
+ if (optimize
+ && (flag_unsafe_math_optimizations
+ || (long_integer_type_node
+ && outprec >= TYPE_PRECISION (long_integer_type_node))))
+ {
+ tree s_expr = strip_float_extensions (expr);
+ tree s_intype = TREE_TYPE (s_expr);
+ const enum built_in_function fcode = builtin_mathfn_code (s_expr);
+ tree fn = 0;
+
+ switch (fcode)
+ {
+ case BUILT_IN_ROUND: case BUILT_IN_ROUNDF: case BUILT_IN_ROUNDL:
+ if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (long_long_integer_type_node))
+ fn = mathfn_built_in (s_intype, BUILT_IN_LLROUND);
+ else
+ fn = mathfn_built_in (s_intype, BUILT_IN_LROUND);
+ break;
+
+ case BUILT_IN_RINT: case BUILT_IN_RINTF: case BUILT_IN_RINTL:
+ /* Only convert rint* if we can ignore math exceptions. */
+ if (flag_trapping_math)
+ break;
+ /* ... Fall through ... */
+ case BUILT_IN_NEARBYINT: case BUILT_IN_NEARBYINTF: case BUILT_IN_NEARBYINTL:
+ if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (long_long_integer_type_node))
+ fn = mathfn_built_in (s_intype, BUILT_IN_LLRINT);
+ else
+ fn = mathfn_built_in (s_intype, BUILT_IN_LRINT);
+ break;
+ default:
+ break;
+ }
+
+ if (fn)
+ {
+ tree arglist = TREE_OPERAND (s_expr, 1);
+ tree newexpr = build_function_call_expr (fn, arglist);
+ return convert_to_integer (type, newexpr);
+ }
+ }
+
switch (TREE_CODE (intype))
{
case POINTER_TYPE:
@@ -618,7 +665,7 @@ convert_to_integer (tree type, tree expr)
break;
}
- return build1 (NOP_EXPR, type, expr);
+ return build1 (CONVERT_EXPR, type, expr);
case REAL_TYPE:
return build1 (FIX_TRUNC_EXPR, type, expr);
diff --git a/gcc/coverage.c b/gcc/coverage.c
index ccc8339cb5f..8e952831acb 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -96,7 +96,11 @@ static char *da_file_name;
/* Hash table of count data. */
static htab_t counts_hash = NULL;
-/* The names of the counter tables. */
+/* Trees representing the counter table arrays. */
+static GTY(()) tree tree_ctr_tables[GCOV_COUNTERS];
+
+/* The names of the counter tables. Not used if we're
+ generating counters at tree level. */
static GTY(()) rtx ctr_labels[GCOV_COUNTERS];
/* The names of merge functions for counters. */
@@ -172,8 +176,8 @@ read_counts_file (void)
GCOV_UNSIGNED2STRING (v, tag);
GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
- warning ("`%s' is version `%.4s', expected version `%.4s'",
- da_file_name, v, e);
+ warning ("`%s' is version `%.*s', expected version `%.*s'",
+ da_file_name, 4, v, 4, e);
gcov_close ();
return;
}
@@ -369,14 +373,22 @@ coverage_counter_alloc (unsigned counter, unsigned num)
if (!num)
return 1;
- if (!ctr_labels[counter])
+ if (!tree_ctr_tables[counter])
{
/* Generate and save a copy of this so it can be shared. */
+ /* We don't know the size yet; make it big enough that nobody
+ will make any clever transformation on it. */
char buf[20];
-
+ tree domain_tree
+ = build_index_type (build_int_2 (1000, 0)); /* replaced later */
+ tree gcov_type_array_type
+ = build_array_type (GCOV_TYPE_NODE, domain_tree);
+ tree_ctr_tables[counter]
+ = build_decl (VAR_DECL, NULL_TREE, gcov_type_array_type);
+ TREE_STATIC (tree_ctr_tables[counter]) = 1;
ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", counter + 1);
- ctr_labels[counter] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
- SYMBOL_REF_FLAGS (ctr_labels[counter]) = SYMBOL_FLAG_LOCAL;
+ DECL_NAME (tree_ctr_tables[counter]) = get_identifier (buf);
+ DECL_ALIGN (tree_ctr_tables[counter]) = TYPE_ALIGN (GCOV_TYPE_NODE);
}
fn_b_ctrs[counter] = fn_n_ctrs[counter];
fn_n_ctrs[counter] += num;
@@ -387,7 +399,7 @@ coverage_counter_alloc (unsigned counter, unsigned num)
/* Generate a MEM rtl to access COUNTER NO. */
rtx
-coverage_counter_ref (unsigned counter, unsigned no)
+rtl_coverage_counter_ref (unsigned counter, unsigned no)
{
unsigned gcov_size = tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE), 1);
enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
@@ -396,6 +408,13 @@ coverage_counter_ref (unsigned counter, unsigned no)
if (no >= fn_n_ctrs[counter] - fn_b_ctrs[counter])
abort ();
no += prg_n_ctrs[counter] + fn_b_ctrs[counter];
+ if (!ctr_labels[counter])
+ {
+ ctr_labels[counter] = gen_rtx_SYMBOL_REF (Pmode,
+ ggc_strdup (IDENTIFIER_POINTER (DECL_NAME
+ (tree_ctr_tables[counter]))));
+ SYMBOL_REF_FLAGS (ctr_labels[counter]) = SYMBOL_FLAG_LOCAL;
+ }
ref = plus_constant (ctr_labels[counter], gcov_size / BITS_PER_UNIT * no);
ref = gen_rtx_MEM (mode, ref);
set_mem_alias_set (ref, new_alias_set ());
@@ -403,6 +422,23 @@ coverage_counter_ref (unsigned counter, unsigned no)
return ref;
}
+
+/* Generate a tree to access COUNTER NO. */
+
+tree
+tree_coverage_counter_ref (unsigned counter, unsigned no)
+{
+ tree t;
+
+ if (no >= fn_n_ctrs[counter] - fn_b_ctrs[counter])
+ abort ();
+ no += prg_n_ctrs[counter] + fn_b_ctrs[counter];
+
+ /* "no" here is an array index, scaled to bytes later. */
+ t = build (ARRAY_REF, GCOV_TYPE_NODE, tree_ctr_tables[counter],
+ build_int_2 (no, 0));
+ return t;
+}
/* Generate a checksum for a string. CHKSUM is the current
checksum. */
@@ -684,19 +720,20 @@ build_ctr_info_value (unsigned int counter, tree type)
if (prg_n_ctrs[counter])
{
- tree array_type, array;
+ tree array_type;
array_type = build_index_type (build_int_2 (prg_n_ctrs[counter] - 1, 0));
array_type = build_array_type (TREE_TYPE (TREE_TYPE (fields)),
array_type);
- array = build_decl (VAR_DECL, NULL_TREE, array_type);
- TREE_STATIC (array) = 1;
- DECL_NAME (array) = get_identifier (XSTR (ctr_labels[counter], 0));
- assemble_variable (array, 0, 0, 0);
+ TREE_TYPE (tree_ctr_tables[counter]) = array_type;
+ DECL_SIZE (tree_ctr_tables[counter]) = TYPE_SIZE (array_type);
+ DECL_SIZE_UNIT (tree_ctr_tables[counter]) = TYPE_SIZE_UNIT (array_type);
+ assemble_variable (tree_ctr_tables[counter], 0, 0, 0);
value = tree_cons (fields,
- build1 (ADDR_EXPR, TREE_TYPE (fields), array),
+ build1 (ADDR_EXPR, TREE_TYPE (fields),
+ tree_ctr_tables[counter]),
value);
}
else
diff --git a/gcc/coverage.h b/gcc/coverage.h
index 9756bbaafa8..ec8134f1fe6 100644
--- a/gcc/coverage.h
+++ b/gcc/coverage.h
@@ -38,7 +38,9 @@ extern int coverage_begin_output (void);
/* Allocate some counters. Repeatable per function. */
extern int coverage_counter_alloc (unsigned /*counter*/, unsigned/*num*/);
/* Use a counter from the most recent allocation. */
-extern rtx coverage_counter_ref (unsigned /*counter*/, unsigned/*num*/);
+extern rtx rtl_coverage_counter_ref (unsigned /*counter*/, unsigned/*num*/);
+/* Use a counter from the most recent allocation. */
+extern tree tree_coverage_counter_ref (unsigned /*counter*/, unsigned/*num*/);
/* Get all the counters for the current function. */
extern gcov_type *get_coverage_counts (unsigned /*counter*/,
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 984d5de6154..25c72524de4 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,96 @@
+2004-05-13 Diego Novillo <dnovillo@redhat.com>
+
+ * cp-gimplify.c: Rename from cp-simplify.c.
+ * Make-lang.in, optimize.c: Update.
+
+2004-05-13 Diego Novillo <dnovillo@redhat.com>
+
+ Merge from tree-ssa-20020619-branch. See
+ ChangeLog.tree-ssa for details.
+
+ * Make-lang.in, call.c, class.c, cp-lang.c, cp-tree.def,
+ cp-tree.h, cvt.c, decl.c, decl2.c, error.c, except.c,
+ expr.c, init.c, name-lookup.h, optimize.c, parser.c,
+ pt.c, rtti.c, semantics.c, tree.c, typeck.c, typeck2.c:
+ Merged.
+ * cp-mudflap.c: New file.
+ * cp-simplify.c:: New file.
+
+2004-05-03 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/14389
+ * decl2.c (check_classfn): For member templates, compare also the
+ template parameters to match the declaration.
+ * cp-tree.h: Adjust declaration of check_classfn.
+ * decl.c (start_decl, grokfndecl): Adjust callers of check_classfn.
+ * friend.c (do_friend): Likewise.
+ * pt.c (tsubst_friend_function): Likewise.
+
+2004-05-01 Zack Weinberg <zack@codesourcery.com>
+
+ * decl.c (reshape_init): Do not apply TYPE_DOMAIN to a VECTOR_TYPE.
+ Instead, dig into the representation type to find the array bound.
+
+2004-04-30 Jason Merrill <jason@redhat.com>
+
+ Refer to base members using COMPONENT_REFs where possible.
+ * class.c (build_simple_base_path): New fn.
+ (build_base_path): Use it for non-virtual base references.
+ (layout_class_type): Change base fields to their real type
+ after layout is done.
+ * cp-tree.h (IS_FAKE_BASE_TYPE): New macro.
+ * cp-lang.c (cxx_get_alias_set): Use it.
+
+2004-04-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * class.c, cp-tree.h, decl.c, decl2.c, pt.c, rtti.c: Fix
+ comment typos.
+
+2004-04-23 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/15064
+ * parser.c (cp_parser_postfix_expression): typeid operator cannot be
+ used in integral constant expressions.
+
+2004-04-22 Mark Mitchell <mark@codesourcery.com>
+
+ * init.c (build_aggr_init): Fix accidental use of C99 construct in
+ previous change.
+
+ * class.c (initialize_array): Don't set TREE_HAS_CONSTRUCTOR on
+ braced initializer.
+ * cp-tree.h (BRACE_ENCLOSED_INITIALIZER_P): New macro.
+ * decl.c (reshape_init): Use it.
+ * init.c (perform_member_init): Remove redundant condition.
+ (build_aggr_init): Adjust to handle brace-enclosed initializers
+ correctly.
+ (expand_default_init): Use BRACE_ENCLOSED_INITIALIZER_P.
+
+ * parser.c (cp_parser_initializer_clause): Do not set
+ TREE_HAS_CONSTRUCTOR on the initializer.
+ * rtti.c (tinfo_base_init): Likewise.
+ (generic_initializer): Likewise.
+ (ptr_initializer): Likewise.
+ (ptm_initializer): Likewise.
+ (class_initializer): Likewise.
+ (get_pseudo_ti_init): Likewise.
+ * typeck2.c (digest_init): Use BRACE_ENCLOSED_INITIALIZER_P.
+
+2004-04-22 Alan Modra <amodra@bigpond.net.au>
+
+ * name-lookup.c (anonymous_namespace_name): Make static.
+
+2004-04-19 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/14531
+ * class.c (build_base_path): Call fold whilst building the NULL
+ pointer check expression trees.
+
+2004-04-15 Bryce McKinlay <mckinlay@redhat.com>
+
+ * init.c (build_new_1): Don't use type size argument for Java
+ _Jv_AllocObject call.
+
2004-04-09 Danny Smith <dannysmith@users.sourceforge.net>
* method.c (make_alias_for_thunk): Remove preprocessor guard on
@@ -96,12 +189,6 @@
* error.c (dump_function_name): If T's DECL_LANG_SPECIFIC
is null, just print the literal name and return.
-2004-03-25 Jason Merrill <jason@redhat.com>
-
- PR c++/13294
- * pt.c (maybe_process_partial_specialization): Remember the
- context of a specialization.
-
2004-03-25 Kazu Hirata <kazu@cs.umass.edu>
* cxx-pretty-print.c: Fix comment typos.
diff --git a/gcc/cp/ChangeLog.tree-ssa b/gcc/cp/ChangeLog.tree-ssa
new file mode 100644
index 00000000000..a52dea67450
--- /dev/null
+++ b/gcc/cp/ChangeLog.tree-ssa
@@ -0,0 +1,566 @@
+2004-04-19 Richard Henderson <rth@redhat.com>
+
+ * except.c (check_handlers_1): Use locus stored in master for warning.
+ * tree.c (cp_walk_subtrees): Save and restore input_location.
+
+2004-04-12 Diego Novillo <dnovillo@redhat.com>
+
+ * cp-lang.c (LANG_HOOKS_RTL_EXPAND_START): Remove.
+ (LANG_HOOKS_RTL_EXPAND_STMT): Remove.
+ * semantics.c (cxx_expand_function_start): Remove.
+
+2004-04-12 Richard Henderson <rth@redhat.com>
+
+ * except.c (check_handlers_1): Use EXPR_LOCUS instead of STMT_LINENO.
+ * semantics.c (finalize_nrv_r): Likewise.
+ * tree.c (cp_walk_subtrees): Likewise.
+ * parser.c (cp_parser_statement): Save and restore entire locus;
+ set EXPR_LOCUS.
+ * pt.c (tsubst_expr): Don't special-case LABEL_STMT.
+
+2004-04-01 Diego Novillo <dnovillo@redhat.com>
+
+ * name-lookup.c (innermost_nonclass_level): Check for
+ error_mark_node.
+
+2004-03-25 Diego Novillo <dnovillo@redhat.com>
+
+ * parser.c (cp_parser_class_specifier): Initialize
+ variable 'attributes'.
+
+2004-03-17 Richard Henderson <rth@redhat.com>
+
+ * cp-lang.c (cxx_types_compatible_p): Use
+ same_type_ignoring_top_level_qualifiers_p.
+
+2004-03-16 Dale Johannesen <dalej@apple.com>
+
+ * cp-lang.c (cxx_types_compatible_p): New.
+ LANG_HOOKS_TYPES_COMPATIBLE_P: New.
+
+2004-03-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/14452
+ * tree.c (stabilize_init): Return whether or not it worked.
+ * init.c (build_new_1): If not, use a sentry.
+ * cp-tree.h: Adjust prototype.
+
+2004-03-01 Jeff Law <law@redhat.com>
+
+ * init.c (build_vec_delete_1): Convert 2nd argument to NE_EXPR to
+ the proper type.
+
+2004-02-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/13944
+ * except.c (do_free_exception): Remove #if 0 wrapper.
+ (build_throw): Use it if we elide a copy into the exception object.
+
+ * tree.c (stabilize_call): Fix thinko.
+
+2004-02-19 Steven Bosscher <stevenb@suse.de>
+
+ * decl.c (poplevel): Don't output nested inline functions.
+
+2004-02-16 Richard Henderson <rth@redhat.com>
+
+ * call.c (build_call, build_over_call, build_new_method_call): Add
+ static chain operand to call_expr.
+ * decl.c (build_offset_ref_call_from_tree): Likewise.
+ * parser.c (cp_parser_postfix_expression): Likewise.
+ * semantics.c (finish_call_expr): Likewise.
+ * cp-lang.c (cp_expand_decl): Don't declare_nonlocal_label.
+
+2004-02-09 Richard Henderson <rth@redhat.com>
+
+ * cp-lang.c (LANG_HOOKS_FUNCTION_MISSING_NORETURN_OK_P): New.
+ * cp-tree.h (cp_missing_noreturn_ok_p): Declare.
+ * decl.c (cp_missing_noreturn_ok_p): Export.
+ (cxx_init_decl_processing): Don't set lang_missing_noreturn_ok_p.
+
+2004-02-06 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c/13863
+ * cp-lang.c (LANG_HOOKS_DECL_UNINIT): Remove.
+
+2004-02-03 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/13325
+ * call.c, cvt.c, init.c, typeck.c: Use TREE_NO_WARNING instead
+ of TREE_NO_UNUSED_WARNING.
+ * cvt.c (convert_to_void): Also use it for "has no effect" warning.
+
+2004-01-30 Frank Ch. Eigler <fche@redhat.com>
+
+ * cp-mudflap.c (mflang_flush_calls): Mark static ctor as TREE_USED.
+
+2004-01-12 Jason Merrill <jason@redhat.com>
+
+ * cp-lang.c (ok_to_generate_alias_set_for_type): Remove.
+ (cxx_get_alias_set): Allow all types.
+
+2004-01-08 Frank Ch. Eigler <fche@redhat.com>
+
+ * cp-mudflap.c (mflang_flush_calls): mf_mark synthetic function.
+
+2004-01-04 Richard Henderson <rth@redhat.com>
+
+ * call.c (build_over_call): Don't create a save_expr of an
+ aggregate, but rather its address.
+
+2004-01-01 Richard Henderson <rth@redhat.com>
+
+ * expr.c (cxx_expand_expr): Don't handle THROW_EXPR, or
+ MUST_NOT_THROW_EXPR.
+ * semantics.c (genrtl_try_block, genrtl_eh_spec_block,
+ genrtl_handler, cp_expand_stmt): Remove.
+ (init_cp_semantics): Don't set lang_expand_stmt.
+
+2003-12-31 Richard Henderson <rth@redhat.com>
+
+ * cp-mudflap.c (mflang_register_call): Remove.
+
+2003-12-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/12453
+ * cp-simplify.c (cp_gimplify_init_expr): Look inside STMT_EXPRs
+ and COMPOUND_EXPRs to find an AGGR_INIT_EXPR.
+
+2003-12-16 Jason Merrill <jason@redhat.com>
+
+ PR middle-end/12920
+ * decl.c (grokdeclarator): Immediately layout an
+ ARRAY_TYPE used in a pointer-to-array declarator.
+
+2003-12-16 Jan Hubicka <jh@suse.cz>
+
+ Revert until initializers are made language independent:
+ * cp-lang.c (LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR): Kill.
+ * cp-tree.h (cxx_callgraph_analyze_expr): Kill.
+ * decl2.c (cxx_callgraph_analyze_expr): Kill.
+
+2003-12-14 Jan Hubicka <jh@suse.cz>
+
+ * cp-lang.c (LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR): Kill.
+ * cp-tree.h (cxx_callgraph_analyze_expr): Kill.
+ * decl2.c (cxx_callgraph_analyze_expr): Kill.
+
+2003-11-24 Richard Henderson <rth@redhat.com>
+
+ * Make-lang.in (tree.o, typeck.o): Remove -Wno-error.
+
+2003-11-20 Richard Henderson <rth@redhat.com>
+
+ * call.c (build_java_interface_fn_ref): Use build_address+convert.
+ * except.c (build_eh_type_type): Likewise.
+ * class.c (build_base_path): Use convert+build_indirect_ref.
+ * init.c (expand_virtual_init): Likewise.
+ * rtti.c (get_tinfo_decl_dynamic): Use convert.
+
+2003-11-20 Frank Ch. Eigler <fche@redhat.com>
+
+ * cp-mudflap.c (mflang_flush_calls): Adapt to direct expansion of
+ synthetic function, bypassing callgraph code.
+ * cp-decl2.c (finish_file): Call mudflap after callgraph-based
+ expansion.
+
+2003-11-17 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_new_1): Preevaluate initializer. Simplify EH code.
+ (build_init): Call a constructor rather than call build_aggr_init
+ for classes.
+ * except.c (stabilize_throw_expr): Remove.
+ (build_throw): Use stabilize_init instead of stabilize_throw_expr.
+ * tree.c (stabilize_call, stabilize_init): New fns.
+ * call.c (build_over_call): A constructor no longer returns the
+ address of the object.
+
+2003-11-16 Richard Henderson <rth@redhat.com>
+
+ * typeck.c (pointer_diff): Remove unused variable.
+
+2003-11-16 Jason Merrill <jason@redhat.com>
+
+ PR optimization/11269
+ * semantics.c (finalize_nrv_r): Rename from nullify_returns_r.
+ Also replace uses of the nrv with our RESULT_DECL.
+ (cxx_expand_function_start): Don't mess with the nrv.
+ (finalize_nrv): New fn.
+ * cp-tree.h: Declare it.
+ * decl.c (finish_function): Call it.
+ * tree.c (cp_copy_res_decl_for_inlining): Don't mess with the nrv.
+
+2003-11-10 Richard Henderson <rth@redhat.com>
+
+ * cp-simplify.c (gimplify_must_not_throw_expr): Replace add_tree
+ with append_to_statement_list.
+
+2003-10-30 Richard Henderson <rth@redhat.com>
+
+ * decl.c (pop_switch): Call c_do_switch_warnings.
+
+2003-10-23 Richard Henderson <rth@redhat.com>
+
+ * cp-simplify.c (cp_gimplify_expr): Return gimplify_status.
+
+2003-10-16 Richard Henderson <rth@redhat.com>
+
+ * decl.c (finish_function): Don't check flag_disable_gimple.
+
+2003-10-14 Richard Henderson <rth@redhat.com>
+
+ * decl.c (finish_function): Always gimplify; call c_warn_unused_result.
+
+2003-10-13 Richard Henderson <rth@redhat.com>
+
+ * pt.c (push_tinst_level): Use annotate_with_locus.
+
+2003-10-12 Richard Henderson <rth@redhat.com>
+
+ * call.c (call_builtin_trap): Use implicit_built_in_decls.
+ * class.c (build_base_path): Set TREE_INVARIANT.
+ (build_vtbl_ref_1, build_vtbl_initializer): Likewise.
+ * decl.c (build_enumerator): Likewise.
+ * init.c (build_zero_init): Likewise.
+ * pt.c (push_inline_template_parms_recursive): Likewise.
+ (build_template_parm_index, reduce_template_parm_level): Likewise.
+ (process_template_parm): Likewise.
+ * rtti.c (tinfo_base_init, generic_initializer): Likewise.
+ (ptr_initializer, ptm_initializer, class_initializer): Likewise.
+ * typeck.c (build_ptrmemfunc1): Likewise.
+ * typeck2.c (process_init_constructor): Likewise.
+
+ * calls.c (dfs_accumulate_vtbl_inits): Rely on build to set
+ TREE_CONSTANT.
+ (build_vtbl_initializer): Likewise.
+ * init.c (build_vtbl_address): Likewise.
+ * rtti.c (tinfo_base_init): Likewise.
+ * tree.c (make_ptrmem_cst): Likewise.
+ * typeck.c (decay_conversion): Likewise.
+ (get_member_function_from_ptrfunc, build_binary_op): Likewise.
+ (pointer_diff, build_address, build_nop, build_unary_op): Likewise.
+
+2003-09-30 Richard Henderson <rth@redhat.com>
+
+ * decl.c (finish_function): Set cfun->function_end_locus.
+
+2003-09-24 Jason Merrill <jason@redhat.com>
+
+ * class.c, decl.c, decl2.c, error.c, init.c, lex.c, method.c,
+ pt.c, semantics.c, tree.c: Revert from TREE_LOCUS to
+ DECL_SOURCE_LOCATION.
+
+2003-09-17 Richard Henderson <rth@redhat.com>
+
+ * decl.c (cxx_init_decl_processing): Don't using_eh_for_cleanups
+ if exceptions are disabled.
+
+2003-09-03 Richard Henderson <rth@redhat.com>
+
+ * cp-lang.c (LANG_HOOKS_RTL_EXPAND_STMT): Use expand_stmt_toplev.
+
+2003-09-03 Richard Henderson <rth@redhat.com>
+
+ * decl.c (finish_function): Fix misapplied patch. Don't
+ free_after_parsing or free_after_compilation. For real this time.
+
+2003-08-22 Jason Merrill <jason@redhat.com>
+
+ * cp-simplify.c (cp_gimplify_init_expr): Update use of predicates.
+
+2003-08-21 Jason Merrill <jason@redhat.com>
+
+ * cp-simplify.c (cp_gimplify_expr): Use simplify_aggr_init_expr.
+ (cp_gimplify_init_expr): Don't call it here.
+ (gimplify_aggr_init_expr): Remove.
+
+2003-08-19 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (build_array_ref): Also build ARRAY_REFs from
+ INDIRECT_REFs of ARRAY_TYPE.
+
+ * semantics.c (finish_id_expression): Unshare aliases.
+
+2003-08-12 Diego Novillo <dnovillo@redhat.com>
+
+ * optimize.c (optimize_function): Do not call dump_function.
+
+2003-08-08 Jason Merrill <jason@redhat.com>
+
+ * optimize.c (optimize_function): Restore support for
+ !keep_function_tree_in_gimple_form.
+
+2003-07-27 Andreas Jaeger <aj@suse.de>
+
+ * cp-lang.c: Convert K&R prototypes to ISO C90.
+ * cp-simplify.c: Likewise.
+ * cp-mudflap.c: Likewise.
+
+2003-06-13 Frank Ch. Eigler <fche@redhat.com>
+
+ * semantics.c (expand_body): Call mudflap_c_function just before
+ rtl expansion of function body; don't interfere with inlining.
+ * optimize.c (optimize_function): Remove mudflap call.
+
+2003-06-13 Diego Novillo <dnovillo@redhat.com>
+
+ * cp-lang.c, cp-simplify.c, cp-tree.h, decl.c, optimize.c,
+ semantics.c, tree.c: Rename SIMPLE to GIMPLE everywhere.
+
+2003-06-05 Frank Ch. Eigler <fche@redhat.com>
+
+ * cp-mudflap.c (mflang_register_call): Give the synthetic decl
+ undefined (not zero) size.
+
+2003-06-05 Frank Ch. Eigler <fche@redhat.com>
+
+ * cp-mudflap.c (mx_flag): Remove. Update callers to use mf_mark.
+
+2003-05-24 Diego Novillo <dnovillo@redhat.com>
+
+ * Make-lang.in (optimize.o): Add dependency on tree-simple.h
+ * decl.c (grokdeclarator): Don't abort when the declarator is
+ ERROR_MARK_NODE.
+ * optimize.c (optimize_function): Unshare all trees after
+ optimizing inline calls.
+
+2003-05-12 Diego Novillo <dnovillo@redhat.com>
+
+ * class.c (dump_array): Call CONSTRUCTOR_ELTS to access
+ the operand of a CONSTRUCTOR node.
+
+2003-05-07 Diego Novillo <dnovillo@redhat.com>
+
+ * decl.c (grokdeclarator): Fix thinko in handling
+ ERROR_MARK declarators.
+
+2003-05-07 Diego Novillo <dnovillo@redhat.com>
+
+ * decl.c (grokdeclarator): Handle ERROR_MARK declarators.
+
+2003-05-07 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (expand_body): Call expand_stmt when
+ -fdisable-simple is given.
+
+2003-04-21 Jeff Law <law@redhat.com>
+
+ * optimize.c (optimize_function_tree): Do run the tree-ssa
+ optimizers.
+
+2003-04-16 Jeff Law <law@redhat.com>
+
+ * optimize.c (optimize_function): No longer check
+ flag_disable_simple.
+
+2003-04-15 Jeff Law <law@redhat.com>
+
+ * pt.c (instantiate_decl): If CFUN is null, then we will
+ need to push to the toplevel.
+
+ * Makefile.in (decl.o): Depends on tree-flow.h.
+ * decl.c (finish_function): Call set_has_hidden_use when
+ nullifying returns for named value return optimization.
+
+2003-04-02 Jason Merrill <jason@redhat.com>
+
+ * cp-simplify.c (cp_simplify_expr) <case EMPTY_CLASS_EXPR>:
+ Change type of constant to RECORD_TYPE.
+
+2003-03-10 Jeff Law <law@redhat.com>
+
+ * optimize.c (optimize_function): Avoid unnecessary
+ simplification of the function tree.
+
+2003-03-02 Diego Novillo <dnovillo@redhat.com>
+
+ * decl.c: Replace DECL_SOURCE_LOCATION with TREE_LOCUS
+ everywhere.
+
+2003-02-28 Frank Ch. Eigler <fche@redhat.com>
+
+ * decl2.c (finish_file): Adjust timing of mudflap_finish_file call
+ to account for unit-at-a-time compilation.
+
+2003-02-07 Jason Merrill <jason@redhat.com>
+
+ * cp-simplify.c (cp_simplify_expr): Handle BASELINK.
+
+ * parser.c (cp_parser_primary_expression): Unshare a COMPONENT_REF
+ from an ALIAS_DECL.
+
+2003-02-05 Jason Merrill <jason@redhat.com>
+
+ * cp-simplify.c (genericize_try_block): Do genericize catch blocks.
+
+2003-02-03 Diego Novillo <dnovillo@redhat.com>
+
+ * parser.c (cp_parser_asm_definition): Call finish_asm_stmt with
+ 'volatile_p' directly.
+ * typeck.c (build_binary_op): Initialize variable 'type'.
+ * Make-lang.in (cp/tree.o-warn): Add -Wno-error.
+
+2003-01-29 Frank Ch. Eigler <fche@redhat.com>
+
+ * cp-mudflap.c (mflang_register_call): Adapt to mf-runtime.h API
+ change.
+
+2003-01-15 Jeff Law <law@redhat.com>
+
+ * class.c: Use TREE_FILENAME and TREE_LINENO to extract
+ file/line information from tree nodes. Remove EXPR_WITH_FILE_LOCATION
+ nodes. Use annotate_with_file_line to attach file/line information
+ to tree nodes. Use TREE_LOCUS to copy file/line information
+ from one node to another.
+ * decl2.c, error.c, init.c, lex.c, method.c: Likewise.
+ * optimize.c: Likewise.
+ * cp-tree.def (TINST_LEVEL): New tree node.
+ * cp-tree.h (TINST_DECL): Update now that we no longer use
+ EXPR_WITH_FILE_LOCATION to represent the TINST_DECL information.
+ (TINST_FILE, TINST_LINE): Kill.
+ * decl.c: Use TREE_FILENAME and TREE_LINENO to extract
+ file/line information from tree nodes. Use annotate_witH_file_line
+ to add file/line information to tree nodes. Use TREE_LOCUS
+ to copy file/line information from one node to another.
+ (duplicate_decls): Make sure to copy TREE_LOCUS information
+ from the old decl to the new decl.
+ (finish_function): Save and restore file/line information
+ around genericizing the function tree.
+ * pt.c (lookup_template_class): Use TREE_LOCUS to copy file/line
+ information from one node to another.
+ (push_tinst_level): Generate a TINST_LEVEL node rather than
+ using EXPR_WITH_FILE_LOCATION nodes. Use annotate_with_file_line
+ to annotate the new node with file/line information.
+ (pop_tinst_level): Use TREE_LINENO and TREE_FILENAME to extract
+ file/line information from nodes.
+ (tsubst_friend_function, instantiate_class_template): Likewise.
+ (tsubst_decl, instantiate_decl, tsubst_enum): Likewise.
+ * semantics.c: Use annotate_with_file_line to annotate tree
+ nodes with file/line information. Use TREE_FILENAME and TREE_LINENO
+ to extract file/line information from tree nodes.
+ (expand_body): Restore file/line information slightly earlier.
+ tree.c (cp_walk_subtrees): Set lineno appropriately.
+ (cp_copy_res_decl_for_inlining): Use TREE_LOCUS to copy file/line
+ information from one node to another.
+
+2003-01-13 Frank Ch. Eigler <fche@redhat.com>
+
+ Prototype C++ mudflap support.
+ * Make-lang.in (CXX_OBJS): Add cp/cp-mudflap.o and dependencies.
+ * cp-mudflap.c: New file with C++ front-end mflang_* routines.
+ * decl2.c (finish_file): Divert to mudflap if appropriate.
+ * optimize.c (optimize_function): Ditto.
+
+2003-01-02 Jason Merrill <jason@redhat.com>
+
+ * Make-lang.in (CXX_C_OBJS): Replace old-tree-inline.o with
+ tree-inline.o.
+
+ * optimize.c (dump_function): Move to ../tree-dump.c.
+
+ * cp-simplify.c (cp_simplify_expr): Handle PTRMEM_CST, INIT_EXPR,
+ MODIFY_EXPR and EMPTY_CLASS_EXPR.
+ (cp_simplify_stmt): Handle USING_STMT.
+ (cp_simplify_init_expr): New fn.
+ * cvt.c (build_up_reference): Don't push the decl.
+ * class.c (build_vtable_entry_ref, build_vtbl_ref_1): Unshare the
+ vtable address.
+ * init.c (build_vtbl_address): Likewise.
+ * cp-lang.c (LANG_HOOKS_UNSAVE_EXPR_NOW): Remove.
+ * decl.c (lookup_name_real): Unshare the expansion of an ALIAS_DECL.
+ (finish_function): Don't genericize templates.
+ * parse.y (parse_asm_stmt): Fix prototype.
+ * semantics.c (expand_body): Don't expand if we saw errors.
+ Drop support for expanding non-GENERIC code.
+
+ * cp-simplify.c (cp_simplify_stmt): Handle HANDLER and EH_SPEC_BLOCK.
+ (genericize_try_block): Always build a TRY_CATCH_EXPR.
+ (genericize_catch_block): New fn.
+ (genericize_eh_spec_block): New fn.
+ (cp_simplify_expr): Handle THROW_EXPR and MUST_NOT_THROW_EXPR.
+ (simplify_must_not_throw_expr): New fn.
+ * except.c (wrap_cleanups_r): Make the MUST_NOT_THROW_EXPR void.
+ (build_throw): Likewise.
+
+2002-12-14 Jason Merrill <jason@redhat.com>
+
+ * optimize.c (dump_function): Use pretty dumpers.
+ (optimize_function): Don't do .original dump here.
+
+2002-12-03 Diego Novillo <dnovillo@redhat.com>
+
+ * cp-simplify.c: Include coretypes.h and tm.h.
+
+2002-11-24 Jason Merrill <jason@redhat.com>
+
+ Gimplify C++ cleanups.
+ * decl.c (finish_function): Call c_genericize.
+ * cp-simplify.c (cp_simplify_stmt): New fn.
+ (genericize_try_block): New fn.
+ (cp_simplify_expr): Move INIT_EXPR/TARGET_EXPR code
+ to ../gimplify.c. Handle AGGR_INIT_EXPR.
+ (simplify_target_expr): Move to ../gimplify.c.
+ (maybe_fixup_loop_cond): Remove.
+ (simplify_aggr_init_expr): Split out from...
+ * semantics.c (simplify_aggr_init_exprs_r): ...here.
+ (expand_body): Don't simplify AGGR_INIT_EXPRs here
+ if we're gimplifying. Handle expanding generic trees.
+ * tree.c (init_tree): Set lang_simplify_stmt.
+ * cp-tree.h: Declare the new fns.
+
+ * optimize.c (optimize_function): Do pretty dumps.
+
+2002-10-04 Jason Merrill <jason@redhat.com>
+
+ * Make-lang.in (CXX_C_OBJS): Add gimplify.o.
+
+2002-09-24 Jason Merrill <jason@redhat.com>
+
+ * parse.y (parse_asm_stmt): New fn.
+ (simple_stmt): Use it.
+ * semantics.c (finish_asm_stmt): Change cv_qualifier parm to
+ volatile_p.
+ * cp-tree.h: Adjust prototype.
+ * pt.c (tsubst_expr): Adjust call.
+
+2002-08-23 Diego Novillo <dnovillo@redhat.com>
+
+ * Make-lang.in (CXX_C_OBJS): Add tree-dchain.o
+
+2002-08-11 Jason Merrill <jason@redhat.com>
+
+ * cp-simplify.c (maybe_fixup_loop_cond): Move here.
+ (cp_simplify_expr): Call it.
+ (simplify_target_expr): Remove pre_p parm.
+
+2002-08-09 Jason Merrill <jason@redhat.com>
+
+ * cp-simplify.c (cp_simplify_expr): New fn.
+ (simplify_target_expr): New fn.
+ (cp_simplify_function_tree): Remove.
+ * cp-lang.c (LANG_HOOKS_SIMPLIFY_FUNCTION_TREE): Don't define.
+ (LANG_HOOKS_SIMPLIFY_EXPR): Define.
+ * optimize.c (optimize_function): De-hook simplify_function_tree.
+ * cp-tree.h: Declare cp_simplify_expr.
+
+2002-07-17 Daniel Berlin <dberlin@dberlin.org>
+
+ * Make-lang.in (CXX_C_OBJS): Add tree-alias-ecr.c,
+ tree-alias-type.o, tree-alias-steen.o, disjoint-set.o.
+
+2002-06-21 Andreas Jaeger <aj@suse.de>
+
+ * Make-lang.in (cp-simplify.o): New.
+
+2002-06-18 Jason Merrill <jason@redhat.com>
+
+ * cp-simplify.c: New file.
+ * Make-lang.in: Add it.
+ * cp-tree.h: Declare cp_simplify_function_tree.
+ * cp-lang.c (LANG_HOOKS_SIMPLIFY_FUNCTION_TREE): Define.
+ * optimize.c (optimize_function): Call tree optimizers (but not yet).
+
+Local Variables:
+mode: change-log
+change-log-default-name: "ChangeLog.tree-ssa"
+End:
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 0f934f225a3..12decae82f1 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -73,14 +73,16 @@ g++-cross$(exeext): g++$(exeext)
# Shared with C front end:
CXX_C_OBJS = attribs.o c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o \
c-dump.o $(CXX_TARGET_OBJS) c-pretty-print.o c-opts.o c-pch.o \
- c-incpath.o cppdefault.o c-ppoutput.o c-cppbuiltin.o prefix.o
+ c-incpath.o cppdefault.o c-ppoutput.o c-cppbuiltin.o prefix.o \
+ c-gimplify.o tree-inline.o
# Language-specific object files.
CXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \
cp/class.o cp/decl2.o cp/error.o cp/lex.o cp/parser.o cp/ptree.o cp/rtti.o \
cp/typeck.o cp/cvt.o cp/except.o cp/friend.o cp/init.o cp/method.o \
cp/search.o cp/semantics.o cp/tree.o cp/repo.o cp/dump.o cp/optimize.o \
- cp/mangle.o cp/cp-lang.o cp/name-lookup.o cp/cxx-pretty-print.o
+ cp/mangle.o cp/cp-lang.o cp/name-lookup.o cp/cxx-pretty-print.o \
+ cp/cp-gimplify.o tree-mudflap.o cp/cp-mudflap.o
# Use strict warnings for this front end.
cp-warn = $(STRICT_WARN) $(WERROR)
@@ -221,7 +223,7 @@ cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) $(TM_H) toplev.h langhooks.h \
cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_H) flags.h cp/lex.h cp/decl.h stack.h \
output.h $(EXPR_H) except.h toplev.h $(HASHTAB_H) $(RTL_H) \
cp/operators.def $(TM_P_H) tree-inline.h diagnostic.h c-pragma.h \
- debug.h gt-cp-decl.h gtype-cp.h timevar.h
+ debug.h gt-cp-decl.h gtype-cp.h timevar.h $(TREE_FLOW_H)
cp/decl2.o: cp/decl2.c $(CXX_TREE_H) $(TM_H) flags.h cp/lex.h cp/decl.h $(EXPR_H) \
output.h except.h toplev.h $(RTL_H) c-common.h gt-cp-decl2.h cgraph.h
cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h output.h $(TM_P_H) \
@@ -257,12 +259,16 @@ cp/semantics.o: cp/semantics.c $(CXX_TREE_H) $(TM_H) cp/lex.h except.h toplev.h
tree-inline.h cgraph.h
cp/dump.o: cp/dump.c $(CXX_TREE_H) $(TM_H) tree-dump.h
cp/optimize.o: cp/optimize.c $(CXX_TREE_H) $(TM_H) rtl.h integrate.h insn-config.h \
- input.h $(PARAMS_H) debug.h tree-inline.h
+ input.h $(PARAMS_H) debug.h tree-inline.h tree-gimple.h
cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h real.h gt-cp-mangle.h \
$(TARGET_H) $(TM_P_H)
cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) diagnostic.h gt-cp-parser.h \
output.h
+cp/cp-gimplify.o: cp/cp-gimplify.c $(CXX_TREE_H) toplev.h c-common.h \
+ $(TM_H) coretypes.h
+cp/cp-mudflap.o: cp/cp-mudflap.c $(CXX_TREE_H) toplev.h c-common.h \
+ $(TM_H) coretypes.h
cp/name-lookup.o: cp/name-lookup.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(CXX_TREE_H) timevar.h gt-cp-name-lookup.h toplev.h \
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 56e089dd2e4..c4892e949e4 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -346,7 +346,7 @@ build_call (tree function, tree parms)
TREE_VALUE (tmp), t);
}
- function = build (CALL_EXPR, result_type, function, parms);
+ function = build (CALL_EXPR, result_type, function, parms, NULL_TREE);
TREE_HAS_CONSTRUCTOR (function) = is_constructor;
TREE_NOTHROW (function) = nothrow;
@@ -660,8 +660,7 @@ standard_conversion (tree to, tree from, tree expr)
else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (to)) == VECTOR_TYPE
&& TREE_CODE (TREE_TYPE (from)) == VECTOR_TYPE
- && ((*targetm.vector_opaque_p) (TREE_TYPE (to))
- || (*targetm.vector_opaque_p) (TREE_TYPE (from))))
+ && vector_types_convertible_p (TREE_TYPE (to), TREE_TYPE (from)))
conv = build_conv (ck_std, to, conv);
else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE)
|| (tcode == POINTER_TYPE && fcode == INTEGER_TYPE))
@@ -820,8 +819,7 @@ standard_conversion (tree to, tree from, tree expr)
conv->rank = cr_promotion;
}
else if (fcode == VECTOR_TYPE && tcode == VECTOR_TYPE
- && ((*targetm.vector_opaque_p) (from)
- || (*targetm.vector_opaque_p) (to)))
+ && vector_types_convertible_p (from, to))
return build_conv (ck_std, to, conv);
else if (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
&& is_properly_derived_from (from, to))
@@ -4333,7 +4331,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
static tree
call_builtin_trap (tree type)
{
- tree fn = IDENTIFIER_GLOBAL_VALUE (get_identifier ("__builtin_trap"));
+ tree fn = implicit_built_in_decls[BUILT_IN_TRAP];
my_friendly_assert (fn != NULL, 20030927);
fn = build_call (fn, NULL_TREE);
@@ -4562,7 +4560,7 @@ build_over_call (struct z_candidate *cand, int flags)
tree expr;
tree return_type;
return_type = TREE_TYPE (TREE_TYPE (fn));
- expr = build (CALL_EXPR, return_type, fn, args);
+ expr = build (CALL_EXPR, return_type, fn, args, NULL_TREE);
if (!VOID_TYPE_P (return_type))
require_complete_type (return_type);
return convert_from_reference (expr);
@@ -4770,16 +4768,11 @@ build_over_call (struct z_candidate *cand, int flags)
else if (TREE_CODE (arg) == TARGET_EXPR
|| TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
{
- tree address;
tree to = stabilize_reference
(build_indirect_ref (TREE_VALUE (args), 0));
val = build (INIT_EXPR, DECL_CONTEXT (fn), to, arg);
- address = build_unary_op (ADDR_EXPR, val, 0);
- /* Avoid a warning about this expression, if the address is
- never used. */
- TREE_USED (address) = 1;
- return address;
+ return val;
}
}
else if (DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR
@@ -4815,7 +4808,7 @@ build_over_call (struct z_candidate *cand, int flags)
val = build (MODIFY_EXPR, as_base, to_as_base, arg_as_base);
val = convert_to_void (val, NULL);
val = build (COMPOUND_EXPR, type, val, save_to);
- TREE_NO_UNUSED_WARNING (val) = 1;
+ TREE_NO_WARNING (val) = 1;
}
return val;
@@ -4938,7 +4931,8 @@ build_java_interface_fn_ref (tree fn, tree instance)
iface);
return error_mark_node;
}
- iface_ref = build1 (ADDR_EXPR, build_pointer_type (iface), iface_ref);
+ iface_ref = build_address (iface_ref);
+ iface_ref = convert (build_pointer_type (iface), iface_ref);
/* Determine the itable index of FN. */
i = 1;
@@ -5362,7 +5356,7 @@ build_new_method_call (tree instance, tree fns, tree args,
call = (build_min_non_dep
(CALL_EXPR, call,
build_min_nt (COMPONENT_REF, orig_instance, orig_fns),
- orig_args));
+ orig_args, NULL_TREE));
/* Free all the conversions we allocated. */
obstack_free (&conversion_obstack, p);
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 6188f5e1cbf..6d2fef50205 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -129,6 +129,7 @@ static void add_implicitly_declared_members (tree, int, int, int);
static tree fixed_type_or_null (tree, int *, int *);
static tree resolve_address_of_overloaded_function (tree, tree, tsubst_flags_t,
bool, tree);
+static tree build_simple_base_path (tree expr, tree binfo);
static tree build_vtbl_ref_1 (tree, tree);
static tree build_vtbl_initializer (tree, tree, tree, tree, int *);
static int count_fields (tree);
@@ -253,6 +254,7 @@ build_base_path (enum tree_code code,
tree ptr_target_type;
int fixed_type_p;
int want_pointer = TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE;
+ bool has_empty = false;
if (expr == error_mark_node || binfo == error_mark_node || !binfo)
return error_mark_node;
@@ -260,6 +262,8 @@ build_base_path (enum tree_code code,
for (probe = binfo; probe; probe = BINFO_INHERITANCE_CHAIN (probe))
{
d_binfo = probe;
+ if (is_empty_class (BINFO_TYPE (probe)))
+ has_empty = true;
if (!v_binfo && TREE_VIA_VIRTUAL (probe))
v_binfo = probe;
}
@@ -267,13 +271,17 @@ build_base_path (enum tree_code code,
probe = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
if (want_pointer)
probe = TYPE_MAIN_VARIANT (TREE_TYPE (probe));
-
+
my_friendly_assert (code == MINUS_EXPR
? same_type_p (BINFO_TYPE (binfo), probe)
: code == PLUS_EXPR
? same_type_p (BINFO_TYPE (d_binfo), probe)
: false, 20010723);
+ if (binfo == d_binfo)
+ /* Nothing to do. */
+ return expr;
+
if (code == MINUS_EXPR && v_binfo)
{
error ("cannot convert from base `%T' to derived type `%T' via virtual base `%T'",
@@ -285,15 +293,36 @@ build_base_path (enum tree_code code,
/* This must happen before the call to save_expr. */
expr = build_unary_op (ADDR_EXPR, expr, 0);
+ offset = BINFO_OFFSET (binfo);
fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
- if (fixed_type_p <= 0 && TREE_SIDE_EFFECTS (expr))
+
+ if (want_pointer && !nonnull
+ && (!integer_zerop (offset) || (v_binfo && fixed_type_p <= 0)))
+ null_test = error_mark_node;
+
+ if (TREE_SIDE_EFFECTS (expr)
+ && (null_test || (v_binfo && fixed_type_p <= 0)))
expr = save_expr (expr);
- if (want_pointer && !nonnull)
- null_test = build (EQ_EXPR, boolean_type_node, expr, integer_zero_node);
-
- offset = BINFO_OFFSET (binfo);
-
+ if (null_test)
+ null_test = fold (build2 (NE_EXPR, boolean_type_node,
+ expr, integer_zero_node));
+
+ /* If this is a simple base reference, express it as a COMPONENT_REF. */
+ if (code == PLUS_EXPR
+ && (v_binfo == NULL_TREE || fixed_type_p > 0)
+ /* We don't build base fields for empty bases, and they aren't very
+ interesting to the optimizers anyway. */
+ && !has_empty)
+ {
+ expr = build_indirect_ref (expr, NULL);
+ expr = build_simple_base_path (expr, binfo);
+ if (want_pointer)
+ expr = build_unary_op (ADDR_EXPR, expr, 0);
+ target_type = TREE_TYPE (expr);
+ goto out;
+ }
+
if (v_binfo && fixed_type_p <= 0)
{
/* Going via virtual base V_BINFO. We need the static offset
@@ -306,14 +335,14 @@ build_base_path (enum tree_code code,
/* In a base member initializer, we cannot rely on
the vtable being set up. We have to use the vtt_parm. */
tree derived = BINFO_INHERITANCE_CHAIN (v_binfo);
-
- v_offset = build (PLUS_EXPR, TREE_TYPE (current_vtt_parm),
- current_vtt_parm, BINFO_VPTR_INDEX (derived));
-
- v_offset = build1 (INDIRECT_REF,
- TREE_TYPE (TYPE_VFIELD (BINFO_TYPE (derived))),
- v_offset);
-
+ tree t;
+
+ t = TREE_TYPE (TYPE_VFIELD (BINFO_TYPE (derived)));
+ t = build_pointer_type (t);
+ v_offset = convert (t, current_vtt_parm);
+ v_offset = build (PLUS_EXPR, t, v_offset,
+ BINFO_VPTR_INDEX (derived));
+ v_offset = build_indirect_ref (v_offset, NULL);
}
else
v_offset = build_vfield_ref (build_indirect_ref (expr, NULL),
@@ -325,6 +354,8 @@ build_base_path (enum tree_code code,
build_pointer_type (ptrdiff_type_node),
v_offset);
v_offset = build_indirect_ref (v_offset, NULL);
+ TREE_CONSTANT (v_offset) = 1;
+ TREE_INVARIANT (v_offset) = 1;
offset = convert_to_integer (ptrdiff_type_node,
size_diffop (offset,
@@ -364,14 +395,56 @@ build_base_path (enum tree_code code,
if (!want_pointer)
expr = build_indirect_ref (expr, NULL);
+ out:
if (null_test)
- expr = build (COND_EXPR, target_type, null_test,
- build1 (NOP_EXPR, target_type, integer_zero_node),
- expr);
+ expr = fold (build3 (COND_EXPR, target_type, null_test, expr,
+ fold (build1 (NOP_EXPR, target_type,
+ integer_zero_node))));
return expr;
}
+/* Subroutine of build_base_path; EXPR and BINFO are as in that function.
+ Perform a derived-to-base conversion by recursively building up a
+ sequence of COMPONENT_REFs to the appropriate base fields. */
+
+static tree
+build_simple_base_path (tree expr, tree binfo)
+{
+ tree type = BINFO_TYPE (binfo);
+ tree d_binfo;
+ tree field;
+
+ /* For primary virtual bases, we can't just follow
+ BINFO_INHERITANCE_CHAIN. */
+ d_binfo = BINFO_PRIMARY_BASE_OF (binfo);
+ if (d_binfo == NULL_TREE)
+ d_binfo = BINFO_INHERITANCE_CHAIN (binfo);
+
+ if (d_binfo == NULL_TREE)
+ {
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (expr)) != type)
+ abort ();
+ return expr;
+ }
+
+ /* Recurse. */
+ expr = build_simple_base_path (expr, d_binfo);
+
+ for (field = TYPE_FIELDS (BINFO_TYPE (d_binfo));
+ field; field = TREE_CHAIN (field))
+ /* Is this the base field created by build_base_field? */
+ if (TREE_CODE (field) == FIELD_DECL
+ && TREE_TYPE (field) == type
+ && DECL_ARTIFICIAL (field)
+ && DECL_IGNORED_P (field))
+ return build_class_member_access_expr (expr, field,
+ NULL_TREE, false);
+
+ /* Didn't find the base field?!? */
+ abort ();
+}
+
/* Convert OBJECT to the base TYPE. If CHECK_ACCESS is true, an error
message is emitted if TYPE is inaccessible. OBJECT is assumed to
be non-NULL. */
@@ -442,7 +515,7 @@ build_vtbl_ref_1 (tree instance, tree idx)
tree binfo = lookup_base (fixed_type, basetype,
ba_ignore|ba_quiet, NULL);
if (binfo)
- vtbl = BINFO_VTABLE (binfo);
+ vtbl = unshare_expr (BINFO_VTABLE (binfo));
}
if (!vtbl)
@@ -451,6 +524,8 @@ build_vtbl_ref_1 (tree instance, tree idx)
assemble_external (vtbl);
aref = build_array_ref (vtbl, idx);
+ TREE_CONSTANT (aref) |= TREE_CONSTANT (vtbl) && TREE_CONSTANT (idx);
+ TREE_INVARIANT (aref) = TREE_CONSTANT (aref);
return aref;
}
@@ -4177,7 +4252,7 @@ create_vtable_ptr (tree t, tree* virtuals_p)
{
/* We build this decl with vtbl_ptr_type_node, which is a
`vtable_entry_type*'. It might seem more precise to use
- `vtable_entry_type (*)[N]' where N is the number of firtual
+ `vtable_entry_type (*)[N]' where N is the number of virtual
functions. However, that would require the vtable pointer in
base classes to have a different type than the vtable pointer
in derived classes. We could make that happen, but that
@@ -4884,6 +4959,11 @@ layout_class_type (tree t, tree *virtuals_p)
/* Warn about bases that can't be talked about due to ambiguity. */
warn_about_ambiguous_bases (t);
+ /* Now that we're done with layout, give the base fields the real types. */
+ for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
+ if (DECL_ARTIFICIAL (field) && IS_FAKE_BASE_TYPE (TREE_TYPE (field)))
+ TREE_TYPE (field) = TYPE_CONTEXT (TREE_TYPE (field));
+
/* Clean up. */
splay_tree_delete (empty_base_offsets);
}
@@ -6728,7 +6808,6 @@ initialize_array (tree decl, tree inits)
context = DECL_CONTEXT (decl);
DECL_CONTEXT (decl) = NULL_TREE;
DECL_INITIAL (decl) = build_constructor (NULL_TREE, inits);
- TREE_HAS_CONSTRUCTOR (DECL_INITIAL (decl)) = 1;
cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0);
DECL_CONTEXT (decl) = context;
}
@@ -7202,10 +7281,7 @@ dfs_accumulate_vtbl_inits (tree binfo,
/* Figure out the position to which the VPTR should point. */
vtbl = TREE_PURPOSE (l);
- vtbl = build1 (ADDR_EXPR,
- vtbl_ptr_type_node,
- vtbl);
- TREE_CONSTANT (vtbl) = 1;
+ vtbl = build1 (ADDR_EXPR, vtbl_ptr_type_node, vtbl);
index = size_binop (PLUS_EXPR,
size_int (non_fn_entries),
size_int (list_length (TREE_VALUE (l))));
@@ -7213,7 +7289,6 @@ dfs_accumulate_vtbl_inits (tree binfo,
TYPE_SIZE_UNIT (vtable_entry_type),
index);
vtbl = build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, index);
- TREE_CONSTANT (vtbl) = 1;
}
if (ctor_vtbl_p)
@@ -7387,8 +7462,6 @@ build_vtbl_initializer (tree binfo,
/* Take the address of the function, considering it to be of an
appropriate generic type. */
init = build1 (ADDR_EXPR, vfunc_ptr_type_node, fn);
- /* The address of a function can't change. */
- TREE_CONSTANT (init) = 1;
}
/* And add it to the chain of initializers. */
@@ -7405,6 +7478,7 @@ build_vtbl_initializer (tree binfo,
TREE_OPERAND (init, 0),
build_int_2 (i, 0));
TREE_CONSTANT (fdesc) = 1;
+ TREE_INVARIANT (fdesc) = 1;
vfun_inits = tree_cons (NULL_TREE, fdesc, vfun_inits);
}
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
new file mode 100644
index 00000000000..f82ed61eb7a
--- /dev/null
+++ b/gcc/cp/cp-gimplify.c
@@ -0,0 +1,236 @@
+/* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c.
+
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Jason Merrill <jason@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "cp-tree.h"
+#include "c-common.h"
+#include "toplev.h"
+#include "tree-gimple.h"
+
+static void genericize_try_block (tree *);
+static void genericize_catch_block (tree *);
+static void genericize_eh_spec_block (tree *);
+static void gimplify_must_not_throw_expr (tree *, tree *);
+static void cp_gimplify_init_expr (tree *, tree *, tree *);
+
+/* Genericize a C++ _STMT. Called from c_gimplify_stmt. */
+
+int
+cp_gimplify_stmt (tree *stmt_p, tree *next_p ATTRIBUTE_UNUSED)
+{
+ tree stmt = *stmt_p;
+ switch (TREE_CODE (stmt))
+ {
+ case TRY_BLOCK:
+ genericize_try_block (stmt_p);
+ return 1;
+
+ case HANDLER:
+ genericize_catch_block (stmt_p);
+ return 1;
+
+ case EH_SPEC_BLOCK:
+ genericize_eh_spec_block (stmt_p);
+ return 1;
+
+ case USING_STMT:
+ /* Just ignore for now. Eventually we will want to pass this on to
+ the debugger. */
+ *stmt_p = build_empty_stmt ();
+ return 1;
+
+ default:
+ break;
+ }
+ return 0;
+}
+
+/* Genericize a TRY_BLOCK. */
+
+static void
+genericize_try_block (tree *stmt_p)
+{
+ tree body = TRY_STMTS (*stmt_p);
+ tree cleanup = TRY_HANDLERS (*stmt_p);
+
+ c_gimplify_stmt (&body);
+
+ if (CLEANUP_P (*stmt_p))
+ /* A cleanup is an expression, so it doesn't need to be genericized. */;
+ else
+ c_gimplify_stmt (&cleanup);
+
+ *stmt_p = build (TRY_CATCH_EXPR, void_type_node, body, cleanup);
+}
+
+/* Genericize a HANDLER by converting to a CATCH_EXPR. */
+
+static void
+genericize_catch_block (tree *stmt_p)
+{
+ tree type = HANDLER_TYPE (*stmt_p);
+ tree body = HANDLER_BODY (*stmt_p);
+
+ c_gimplify_stmt (&body);
+
+ /* FIXME should the caught type go in TREE_TYPE? */
+ *stmt_p = build (CATCH_EXPR, void_type_node, type, body);
+}
+
+/* Genericize an EH_SPEC_BLOCK by converting it to a
+ TRY_CATCH_EXPR/EH_FILTER_EXPR pair. */
+
+static void
+genericize_eh_spec_block (tree *stmt_p)
+{
+ tree body = EH_SPEC_STMTS (*stmt_p);
+ tree allowed = EH_SPEC_RAISES (*stmt_p);
+ tree failure = build_call (call_unexpected_node,
+ tree_cons (NULL_TREE, build_exc_ptr (),
+ NULL_TREE));
+ c_gimplify_stmt (&body);
+
+ *stmt_p = gimple_build_eh_filter (body, allowed, failure);
+}
+
+/* Do C++-specific gimplification. Args are as for gimplify_expr. */
+
+int
+cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
+{
+ switch (TREE_CODE (*expr_p))
+ {
+ case PTRMEM_CST:
+ *expr_p = cplus_expand_constant (*expr_p);
+ return GS_OK;
+
+ case AGGR_INIT_EXPR:
+ simplify_aggr_init_expr (expr_p);
+ return GS_OK;
+
+ case THROW_EXPR:
+ /* FIXME communicate throw type to backend, probably by moving
+ THROW_EXPR into ../tree.def. */
+ *expr_p = TREE_OPERAND (*expr_p, 0);
+ return GS_OK;
+
+ case MUST_NOT_THROW_EXPR:
+ gimplify_must_not_throw_expr (expr_p, pre_p);
+ return GS_OK;
+
+ case INIT_EXPR:
+ case MODIFY_EXPR:
+ cp_gimplify_init_expr (expr_p, pre_p, post_p);
+ return GS_OK;
+
+ case EMPTY_CLASS_EXPR:
+ {
+ /* Yes, an INTEGER_CST with RECORD_TYPE. */
+ tree i = build_int_2 (0, 0);
+ TREE_TYPE (i) = TREE_TYPE (*expr_p);
+ *expr_p = i;
+ }
+ return GS_OK;
+
+ case BASELINK:
+ *expr_p = BASELINK_FUNCTIONS (*expr_p);
+ return GS_OK;
+
+ default:
+ return c_gimplify_expr (expr_p, pre_p, post_p);
+ }
+}
+
+/* Gimplify initialization from an AGGR_INIT_EXPR. */
+
+static void
+cp_gimplify_init_expr (tree *expr_p, tree *pre_p, tree *post_p)
+{
+ tree from = TREE_OPERAND (*expr_p, 1);
+ tree to = TREE_OPERAND (*expr_p, 0);
+ tree sub;
+
+ /* If we are initializing something from a TARGET_EXPR, strip the
+ TARGET_EXPR and initialize it directly. */
+ /* What about code that pulls out the temp and uses it elsewhere? I
+ think that such code never uses the TARGET_EXPR as an initializer. If
+ I'm wrong, we'll abort because the temp won't have any RTL. In that
+ case, I guess we'll need to replace references somehow. */
+ if (TREE_CODE (from) == TARGET_EXPR)
+ from = TARGET_EXPR_INITIAL (from);
+
+ sub = from;
+
+ /* If we are initializing from a STMT_EXPR, extract the returned
+ expression. */
+ if (TREE_CODE (from) == STMT_EXPR)
+ sub = EXPR_STMT_EXPR (stmt_expr_last_stmt (from));
+
+ /* Look through any COMPOUND_EXPRs. */
+ while (TREE_CODE (sub) == COMPOUND_EXPR)
+ sub = TREE_OPERAND (sub, 1);
+
+ /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
+ replace the slot operand with our target.
+
+ Should we add a target parm to gimplify_expr instead? No, as in this
+ case we want to replace the INIT_EXPR. */
+ if (TREE_CODE (sub) == AGGR_INIT_EXPR)
+ {
+ gimplify_expr (&to, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
+ TREE_OPERAND (sub, 2) = to;
+ *expr_p = from;
+
+ /* The initialization is now a side-effect, so the container can
+ become void. This is important for a STMT_EXPR, so we don't try
+ to voidify it later by creating a temporary. */
+ if (from != sub)
+ TREE_TYPE (from) = void_type_node;
+ }
+}
+
+/* Gimplify a MUST_NOT_THROW_EXPR. */
+
+static void
+gimplify_must_not_throw_expr (tree *expr_p, tree *pre_p)
+{
+ tree stmt = *expr_p;
+ tree temp = voidify_wrapper_expr (stmt);
+ tree body = TREE_OPERAND (stmt, 0);
+
+ gimplify_stmt (&body);
+
+ stmt = gimple_build_eh_filter (body, NULL_TREE,
+ build_call (terminate_node, NULL_TREE));
+
+ if (temp)
+ {
+ append_to_statement_list (stmt, pre_p);
+ *expr_p = temp;
+ }
+ else
+ *expr_p = stmt;
+}
diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c
index bbe91707dd7..3d737ad502a 100644
--- a/gcc/cp/cp-lang.c
+++ b/gcc/cp/cp-lang.c
@@ -35,11 +35,12 @@ Boston, MA 02111-1307, USA. */
enum c_language_kind c_language = clk_cxx;
static HOST_WIDE_INT cxx_get_alias_set (tree);
-static bool ok_to_generate_alias_set_for_type (tree);
static bool cxx_warn_unused_global_decl (tree);
static tree cp_expr_size (tree);
static size_t cp_tree_size (enum tree_code);
static bool cp_var_mod_type_p (tree);
+static int cxx_types_compatible_p (tree, tree);
+static int cp_expand_decl (tree);
static void cxx_initialize_diagnostics (diagnostic_context *);
#undef LANG_HOOKS_NAME
@@ -70,14 +71,14 @@ static void cxx_initialize_diagnostics (diagnostic_context *);
#define LANG_HOOKS_EXPAND_CONSTANT cplus_expand_constant
#undef LANG_HOOKS_EXPAND_EXPR
#define LANG_HOOKS_EXPAND_EXPR cxx_expand_expr
+#undef LANG_HOOKS_EXPAND_DECL
+#define LANG_HOOKS_EXPAND_DECL cp_expand_decl
#undef LANG_HOOKS_SAFE_FROM_P
#define LANG_HOOKS_SAFE_FROM_P c_safe_from_p
#undef LANG_HOOKS_PARSE_FILE
#define LANG_HOOKS_PARSE_FILE c_common_parse_file
#undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL cxx_dup_lang_specific_decl
-#undef LANG_HOOKS_UNSAVE_EXPR_NOW
-#define LANG_HOOKS_UNSAVE_EXPR_NOW cxx_unsave_expr_now
#undef LANG_HOOKS_MAYBE_BUILD_CLEANUP
#define LANG_HOOKS_MAYBE_BUILD_CLEANUP cxx_maybe_build_cleanup
#undef LANG_HOOKS_TRUTHVALUE_CONVERSION
@@ -110,8 +111,6 @@ static void cxx_initialize_diagnostics (diagnostic_context *);
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL cxx_warn_unused_global_decl
#undef LANG_HOOKS_WRITE_GLOBALS
#define LANG_HOOKS_WRITE_GLOBALS lhd_do_nothing
-#undef LANG_HOOKS_DECL_UNINIT
-#define LANG_HOOKS_DECL_UNINIT c_decl_uninit
#undef LANG_HOOKS_UPDATE_DECL_AFTER_SAVING
#define LANG_HOOKS_UPDATE_DECL_AFTER_SAVING cp_update_decl_after_saving
@@ -120,11 +119,8 @@ static void cxx_initialize_diagnostics (diagnostic_context *);
#define LANG_HOOKS_FUNCTION_INIT cxx_push_function_context
#undef LANG_HOOKS_FUNCTION_FINAL
#define LANG_HOOKS_FUNCTION_FINAL cxx_pop_function_context
-
-#undef LANG_HOOKS_RTL_EXPAND_START
-#define LANG_HOOKS_RTL_EXPAND_START cxx_expand_function_start
-#undef LANG_HOOKS_RTL_EXPAND_STMT
-#define LANG_HOOKS_RTL_EXPAND_STMT expand_stmt
+#undef LANG_HOOKS_FUNCTION_MISSING_NORETURN_OK_P
+#define LANG_HOOKS_FUNCTION_MISSING_NORETURN_OK_P cp_missing_noreturn_ok_p
/* Attribute hooks. */
#undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
@@ -145,7 +141,7 @@ static void cxx_initialize_diagnostics (diagnostic_context *);
cp_add_pending_fn_decls
#undef LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P
#define LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P \
- cp_is_overload_p
+ cp_tree_chain_matters_p
#undef LANG_HOOKS_TREE_INLINING_AUTO_VAR_IN_FN_P
#define LANG_HOOKS_TREE_INLINING_AUTO_VAR_IN_FN_P \
cp_auto_var_in_fn_p
@@ -156,8 +152,6 @@ static void cxx_initialize_diagnostics (diagnostic_context *);
#define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P anon_aggr_type_p
#undef LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P
#define LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P cp_var_mod_type_p
-#undef LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS
-#define LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS c_estimate_num_insns
#undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
#define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN cp_dump_tree
#undef LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN
@@ -186,8 +180,12 @@ static void cxx_initialize_diagnostics (diagnostic_context *);
#define LANG_HOOKS_INCOMPLETE_TYPE_ERROR cxx_incomplete_type_error
#undef LANG_HOOKS_TYPE_PROMOTES_TO
#define LANG_HOOKS_TYPE_PROMOTES_TO cxx_type_promotes_to
+#undef LANG_HOOKS_TYPES_COMPATIBLE_P
+#define LANG_HOOKS_TYPES_COMPATIBLE_P cxx_types_compatible_p
#undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
#define LANG_HOOKS_REGISTER_BUILTIN_TYPE c_register_builtin_type
+#undef LANG_HOOKS_GIMPLIFY_EXPR
+#define LANG_HOOKS_GIMPLIFY_EXPR cp_gimplify_expr
/* Each front end provides its own hooks, for toplev.c. */
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
@@ -233,79 +231,18 @@ const char *const tree_code_name[] = {
};
#undef DEFTREECODE
-/* Check if a C++ type is safe for aliasing.
- Return TRUE if T safe for aliasing FALSE otherwise. */
-
-static bool
-ok_to_generate_alias_set_for_type (tree t)
-{
- if (TYPE_PTRMEMFUNC_P (t))
- return true;
- if (AGGREGATE_TYPE_P (t))
- {
- if ((TREE_CODE (t) == RECORD_TYPE) || (TREE_CODE (t) == UNION_TYPE))
- {
- tree fields;
- /* Backend-created structs are safe. */
- if (! CLASS_TYPE_P (t))
- return true;
- /* PODs are safe. */
- if (! CLASSTYPE_NON_POD_P(t))
- return true;
- /* Classes with virtual baseclasses are not. */
- if (TYPE_USES_VIRTUAL_BASECLASSES (t))
- return false;
- /* Recursively check the base classes. */
- if (TYPE_BINFO (t) != NULL && TYPE_BINFO_BASETYPES (t) != NULL)
- {
- int i;
- for (i = 0; i < TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (t)); i++)
- {
- tree binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), i);
- if (!ok_to_generate_alias_set_for_type (BINFO_TYPE (binfo)))
- return false;
- }
- }
- /* Check all the fields. */
- for (fields = TYPE_FIELDS (t); fields; fields = TREE_CHAIN (fields))
- {
- if (TREE_CODE (fields) != FIELD_DECL)
- continue;
- if (! ok_to_generate_alias_set_for_type (TREE_TYPE (fields)))
- return false;
- }
- return true;
- }
- else if (TREE_CODE (t) == ARRAY_TYPE)
- return ok_to_generate_alias_set_for_type (TREE_TYPE (t));
- else
- /* This should never happen, we dealt with all the aggregate
- types that can appear in C++ above. */
- abort ();
- }
- else
- return true;
-}
-
/* Special routine to get the alias set for C++. */
static HOST_WIDE_INT
cxx_get_alias_set (tree t)
{
- if (TREE_CODE (t) == RECORD_TYPE
- && TYPE_CONTEXT (t) && CLASS_TYPE_P (TYPE_CONTEXT (t))
- && CLASSTYPE_AS_BASE (TYPE_CONTEXT (t)) == t)
+ if (IS_FAKE_BASE_TYPE (t))
/* The base variant of a type must be in the same alias set as the
complete type. */
return get_alias_set (TYPE_CONTEXT (t));
- if (/* It's not yet safe to use alias sets for some classes in C++. */
- !ok_to_generate_alias_set_for_type (t)
- /* Nor is it safe to use alias sets for pointers-to-member
- functions, due to the fact that there may be more than one
- RECORD_TYPE type corresponding to the same pointer-to-member
- type. */
- || TYPE_PTRMEMFUNC_P (t))
+ /* Punt on PMFs until we canonicalize functions properly. */
+ if (TYPE_PTRMEMFUNC_P (t))
return 0;
return c_common_get_alias_set (t);
@@ -356,6 +293,35 @@ cp_expr_size (tree exp)
return lhd_expr_size (exp);
}
+/* Expand DECL if it declares an entity not handled by the
+ common code. */
+
+static int
+cp_expand_decl (tree decl)
+{
+ if (TREE_CODE (decl) == VAR_DECL && !TREE_STATIC (decl))
+ {
+ /* Let the back-end know about this variable. */
+ if (!anon_aggr_type_p (TREE_TYPE (decl)))
+ emit_local_var (decl);
+ else
+ expand_anon_union_decl (decl, NULL_TREE,
+ DECL_ANON_UNION_ELEMS (decl));
+ }
+ else if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
+ make_rtl_for_local_static (decl);
+ else
+ return 0;
+
+ return 1;
+}
+
+int
+cp_tree_chain_matters_p (tree t)
+{
+ return cp_is_overload_p (t) || c_tree_chain_matters_p (t);
+}
+
/* Langhook for tree_size: determine size of our 'x' and 'c' nodes. */
static size_t
cp_tree_size (enum tree_code code)
@@ -390,6 +356,11 @@ cp_var_mod_type_p (tree type)
return false;
}
+static int cxx_types_compatible_p (tree x, tree y)
+{
+ return same_type_ignoring_top_level_qualifiers_p (x, y);
+}
+
/* Construct a C++-aware pretty-printer for CONTEXT. It is assumed
that CONTEXT->printer is an already constructed basic pretty_printer. */
static void
diff --git a/gcc/cp/cp-mudflap.c b/gcc/cp/cp-mudflap.c
new file mode 100644
index 00000000000..878dc8a1c85
--- /dev/null
+++ b/gcc/cp/cp-mudflap.c
@@ -0,0 +1,108 @@
+/* Mudflap: narrow-pointer bounds-checking by tree rewriting:
+ C++ front-end interface.
+
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Frank Ch. Eigler <fche@redhat.com>
+ and Graydon Hoare <graydon@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#include "config.h"
+#include "errors.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "tree-inline.h"
+#include "cp-tree.h"
+#include "c-common.h"
+#include "diagnostic.h"
+#include "output.h"
+#include "varray.h"
+#include "tree-mudflap.h"
+#include "target.h"
+#include "flags.h"
+#include "rtl.h"
+#include "toplev.h"
+
+
+/* Initialize the global tree nodes that correspond to mf-runtime.h
+ declarations. */
+tree
+mflang_lookup_decl (const char* name)
+{
+ tree decl = lookup_name (get_identifier (name), 1);
+ if (decl == NULL_TREE)
+ internal_error ("mudflap: cannot find declaration of `%s' from mf-runtime.h",
+ name);
+
+ return decl;
+}
+
+
+/* Emit a synthetic CTOR function for the current file. Populate it from
+ the enqueued __mf_register calls. Register it with the constructors. */
+
+void
+mflang_flush_calls (tree enqueued_call_stmt_chain)
+{
+ tree fnname, fndecl, body;
+
+ /* Short-circuit! */
+ if (enqueued_call_stmt_chain == NULL_TREE)
+ return;
+
+ /* Create a ctor function declaration. */
+ fnname = get_identifier ("__static_initialization_and_destruction_mudflap");
+
+ start_function (void_list_node,
+ make_call_declarator (fnname, void_list_node, NULL_TREE,
+ NULL_TREE),
+ NULL_TREE, SF_DEFAULT);
+
+ TREE_PUBLIC (current_function_decl) = 0;
+ TREE_USED (current_function_decl) = 1;
+ DECL_ARTIFICIAL (current_function_decl) = 1;
+ mf_mark (current_function_decl);
+
+ /* Generate the body, one statement at a time. */
+ body = begin_compound_stmt (/*has_no_scope=*/false);
+
+ while (enqueued_call_stmt_chain)
+ {
+ tree next = TREE_CHAIN (enqueued_call_stmt_chain);
+ finish_expr_stmt (enqueued_call_stmt_chain);
+ enqueued_call_stmt_chain = next;
+ }
+
+ finish_compound_stmt (body);
+ fndecl = finish_function (0);
+
+ /* NB: We cannot call expand_or_defer_fn here, since that goes through
+ the callgraph queue. This queue will have already been processed by the
+ time this function is running. */
+ expand_body (fndecl);
+ if (targetm.have_ctors_dtors)
+ (* targetm.asm_out.constructor) (XEXP (DECL_RTL (fndecl), 0),
+ DEFAULT_INIT_PRIORITY);
+ else
+ /* By this time, it's too late to do this:
+ static_ctors = tree_cons (NULL_TREE, fndecl, static_ctors); */
+ abort ();
+}
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index d64752068a3..63a18af378e 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -257,6 +257,15 @@ DEFTREECODE (MUST_NOT_THROW_EXPR, "must_not_throw_expr", 'e', 1)
DEFTREECODE (TAG_DEFN, "tag_defn", 'e', 0)
+/* Template instantiation level node.
+
+ Operand 1 contains the original DECL node and can be accessed via TINST_DECL.
+
+ A stack of template instantiation nodes is kept through the TREE_CHAIN
+ fields of these nodes. */
+
+DEFTREECODE (TINST_LEVEL, "TINST_LEVEL", 'e', 1)
+
/*
Local variables:
mode:c
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 262c314051f..7efe55d8061 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1302,6 +1302,13 @@ struct lang_type GTY(())
#define CLASSTYPE_AS_BASE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->as_base)
+/* True iff NODE is the CLASSTYPE_AS_BASE version of some type. */
+
+#define IS_FAKE_BASE_TYPE(NODE) \
+ (TREE_CODE (NODE) == RECORD_TYPE \
+ && TYPE_CONTEXT (NODE) && CLASS_TYPE_P (TYPE_CONTEXT (NODE)) \
+ && CLASSTYPE_AS_BASE (TYPE_CONTEXT (NODE)) == (NODE))
+
/* These are the size and alignment of the type without its virtual
base classes, for when we use this type as a base itself. */
#define CLASSTYPE_SIZE(NODE) TYPE_SIZE (CLASSTYPE_AS_BASE (NODE))
@@ -1394,7 +1401,7 @@ struct lang_type GTY(())
way or the other. */
#define CLASSTYPE_INTERFACE_KNOWN(NODE) \
(LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown == 0)
-/* The opposite of CLASSTYPE_INTERFANCE_KNOWN. */
+/* The opposite of CLASSTYPE_INTERFACE_KNOWN. */
#define CLASSTYPE_INTERFACE_UNKNOWN(NODE) \
(LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown)
@@ -2408,13 +2415,17 @@ struct lang_decl GTY(())
When appearing in a SAVE_EXPR, it means that underneath
is a call to a constructor.
- When appearing in a CONSTRUCTOR, it means that it was
- a GNU C constructor expression.
+ When appearing in a CONSTRUCTOR, the expression is a
+ compound literal.
When appearing in a FIELD_DECL, it means that this field
has been duly initialized in its constructor. */
#define TREE_HAS_CONSTRUCTOR(NODE) (TREE_LANG_FLAG_4 (NODE))
+/* True if NODE is a brace-enclosed initializer. */
+#define BRACE_ENCLOSED_INITIALIZER_P(NODE) \
+ (TREE_CODE (NODE) == CONSTRUCTOR && !TREE_TYPE (NODE))
+
#define EMPTY_CONSTRUCTOR_P(NODE) (TREE_CODE (NODE) == CONSTRUCTOR \
&& CONSTRUCTOR_ELTS (NODE) == NULL_TREE \
&& ! TREE_HAS_CONSTRUCTOR (NODE))
@@ -3126,12 +3137,9 @@ typedef enum unification_kind_t {
DEDUCE_ORDER
} unification_kind_t;
-/* Macros for operating on a template instantiation level node, represented
- by an EXPR_WITH_FILE_LOCATION. */
+/* Macros for operating on a template instantiation level node. */
-#define TINST_DECL(NODE) EXPR_WFL_NODE (NODE)
-#define TINST_LINE(NODE) EXPR_WFL_LINENO (NODE)
-#define TINST_FILE(NODE) EXPR_WFL_FILENAME (NODE)
+#define TINST_DECL(NODE) TREE_OPERAND (NODE, 0)
/* in class.c */
@@ -3698,6 +3706,7 @@ extern tmpl_spec_kind current_tmpl_spec_kind (int);
extern tree cp_fname_init (const char *, tree *);
extern tree check_elaborated_type_specifier (enum tag_types, tree, bool);
extern void warn_extern_redeclared_static (tree, tree);
+extern bool cp_missing_noreturn_ok_p (tree);
extern bool have_extern_spec;
@@ -3710,7 +3719,7 @@ extern void maybe_make_one_only (tree);
extern void grokclassfn (tree, tree, enum overload_flags, tree);
extern tree grok_array_decl (tree, tree);
extern tree delete_sanity (tree, tree, bool, int);
-extern tree check_classfn (tree, tree, bool);
+extern tree check_classfn (tree, tree, tree);
extern void check_member_template (tree);
extern tree grokfield (tree, tree, tree, tree, tree);
extern tree grokbitfield (tree, tree, tree);
@@ -4036,7 +4045,7 @@ extern void finish_handler (tree);
extern void finish_cleanup (tree, tree);
extern tree begin_compound_stmt (bool);
extern tree finish_compound_stmt (tree);
-extern tree finish_asm_stmt (tree, tree, tree, tree, tree);
+extern tree finish_asm_stmt (int, tree, tree, tree, tree);
extern tree finish_label_stmt (tree);
extern void finish_label_decl (tree);
extern void finish_subobject (tree);
@@ -4076,7 +4085,6 @@ extern void finish_decl_cleanup (tree, tree);
extern void finish_eh_cleanup (tree);
extern void expand_body (tree);
extern void cxx_expand_function_start (void);
-extern tree nullify_returns_r (tree *, int *, void *);
extern void do_pushlevel (scope_kind);
extern tree do_poplevel (void);
extern void finish_mem_initializers (tree);
@@ -4087,11 +4095,14 @@ extern void expand_or_defer_fn (tree);
extern void check_accessibility_of_qualified_id (tree, tree, tree);
extern tree finish_qualified_id_expr (tree, tree, bool, bool);
extern void simplify_aggr_init_expr (tree *);
+extern void finalize_nrv (tree *, tree, tree);
/* in tree.c */
extern void lang_check_failed (const char *, int,
const char *);
extern tree stabilize_expr (tree, tree *);
+extern void stabilize_call (tree, tree *);
+extern bool stabilize_init (tree, tree *);
extern tree cxx_unsave_expr_now (tree);
extern tree cxx_maybe_build_cleanup (tree);
extern void init_tree (void);
@@ -4155,6 +4166,7 @@ extern tree find_tree (tree, tree);
extern linkage_kind decl_linkage (tree);
extern tree cp_walk_subtrees (tree*, int*, walk_tree_fn,
void*, void*);
+extern int cp_tree_chain_matters_p (tree);
extern int cp_cannot_inline_tree_fn (tree*);
extern tree cp_add_pending_fn_decls (void*,tree);
extern int cp_is_overload_p (tree);
@@ -4272,6 +4284,10 @@ extern tree mangle_ref_init_variable (tree);
/* in dump.c */
extern bool cp_dump_tree (void *, tree);
+/* in cp-simplify.c */
+extern int cp_gimplify_expr (tree *, tree *, tree *);
+extern int cp_gimplify_stmt (tree *, tree *);
+
/* -- end of C++ */
/* In order for the format checking to accept the C++ frontend
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index bf906fd969e..b22948106b2 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -810,7 +810,7 @@ convert_to_void (tree expr, const char *implicit)
/* The second part of a compound expr contains the value. */
tree op1 = TREE_OPERAND (expr,1);
tree new_op1 = convert_to_void
- (op1, (implicit && !TREE_NO_UNUSED_WARNING (expr)
+ (op1, (implicit && !TREE_NO_WARNING (expr)
? "right-hand operand of comma" : NULL));
if (new_op1 != op1)
@@ -887,7 +887,8 @@ convert_to_void (tree expr, const char *implicit)
if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr)))
{
- if (implicit && !TREE_SIDE_EFFECTS (expr) && warn_unused_value)
+ if (implicit && warn_unused_value
+ && !TREE_SIDE_EFFECTS (expr) && !TREE_NO_WARNING (expr))
warning ("%s has no effect", implicit);
expr = build1 (CONVERT_EXPR, void_type_node, expr);
}
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index b228cd07748..21f82548eaa 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -51,6 +51,7 @@ Boston, MA 02111-1307, USA. */
#include "diagnostic.h"
#include "debug.h"
#include "timevar.h"
+#include "tree-flow.h"
static tree grokparms (tree, tree *);
static const char *redeclaration_error_message (tree, tree);
@@ -114,7 +115,6 @@ static tree check_special_function_return_type
static tree push_cp_library_fn (enum tree_code, tree);
static tree build_cp_library_fn (tree, enum tree_code, tree);
static void store_parm_decls (tree);
-static int cp_missing_noreturn_ok_p (tree);
static void initialize_local_var (tree, tree);
static void expand_static_init (tree, tree);
static tree next_initializable_field (tree);
@@ -499,28 +499,6 @@ poplevel (int keep, int reverse, int functionbody)
else
decls = current_binding_level->names;
- /* Output any nested inline functions within this block
- if they weren't already output. */
- for (decl = decls; decl; decl = TREE_CHAIN (decl))
- if (TREE_CODE (decl) == FUNCTION_DECL
- && ! TREE_ASM_WRITTEN (decl)
- && DECL_INITIAL (decl) != NULL_TREE
- && TREE_ADDRESSABLE (decl)
- && decl_function_context (decl) == current_function_decl)
- {
- /* If this decl was copied from a file-scope decl
- on account of a block-scope extern decl,
- propagate TREE_ADDRESSABLE to the file-scope decl. */
- if (DECL_ABSTRACT_ORIGIN (decl) != NULL_TREE)
- TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
- else
- {
- push_function_context ();
- output_inline_function (decl);
- pop_function_context ();
- }
- }
-
/* When not in function-at-a-time mode, expand_end_bindings will
warn about unused variables. But, in function-at-a-time mode
expand_end_bindings is not passed the list of variables in the
@@ -2406,9 +2384,11 @@ push_switch (tree switch_stmt)
void
pop_switch (void)
{
- struct cp_switch *cs;
+ struct cp_switch *cs = switch_stack;
+
+ /* Emit warnings as needed. */
+ c_do_switch_warnings (cs->cases, cs->switch_stmt);
- cs = switch_stack;
splay_tree_delete (cs->cases);
switch_stack = switch_stack->next;
free (cs);
@@ -2878,9 +2858,6 @@ cxx_init_decl_processing (void)
/* Create all the identifiers we need. */
initialize_predefined_identifiers ();
- /* Fill in back-end hooks. */
- lang_missing_noreturn_ok_p = &cp_missing_noreturn_ok_p;
-
/* Create the global variables. */
push_to_top_level ();
@@ -3060,7 +3037,8 @@ cxx_init_decl_processing (void)
start_fname_decls ();
/* Show we use EH for cleanups. */
- using_eh_for_cleanups ();
+ if (flag_exceptions)
+ using_eh_for_cleanups ();
}
/* Generate an initializer for a function naming variable from
@@ -3099,7 +3077,7 @@ cp_fname_init (const char* name, tree *type_p)
decl, NAME is the initialization string and TYPE_DEP indicates whether
NAME depended on the type of the function. We make use of that to detect
__PRETTY_FUNCTION__ inside a template fn. This is being done
- lazily at the point of first use, so we musn't push the decl now. */
+ lazily at the point of first use, so we mustn't push the decl now. */
static tree
cp_make_fname_decl (tree id, int type_dep)
@@ -3727,8 +3705,10 @@ start_decl (tree declarator,
else
{
tree field = check_classfn (context, decl,
- processing_template_decl
- > template_class_depth (context));
+ (processing_template_decl
+ > template_class_depth (context))
+ ? current_template_parms
+ : NULL_TREE);
if (field && duplicate_decls (decl, field))
decl = field;
}
@@ -4151,8 +4131,7 @@ reshape_init (tree type, tree *initp)
enclosed elements. Advance past the brace-enclosed initializer
now. */
if (TREE_CODE (old_init_value) == CONSTRUCTOR
- && TREE_TYPE (old_init_value) == NULL_TREE
- && TREE_HAS_CONSTRUCTOR (old_init_value))
+ && BRACE_ENCLOSED_INITIALIZER_P (old_init_value))
{
*initp = TREE_CHAIN (old_init);
TREE_CHAIN (old_init) = NULL_TREE;
@@ -4222,8 +4201,7 @@ reshape_init (tree type, tree *initp)
else
{
/* Build a CONSTRUCTOR to hold the contents of the aggregate. */
- new_init = build_constructor (type, NULL_TREE);
- TREE_HAS_CONSTRUCTOR (new_init) = 1;
+ new_init = build_constructor (NULL_TREE, NULL_TREE);
if (CLASS_TYPE_P (type))
{
@@ -4283,15 +4261,30 @@ reshape_init (tree type, tree *initp)
}
}
}
- else if ((TREE_CODE (type) == ARRAY_TYPE)|| (TREE_CODE (type) == VECTOR_TYPE))
+ else if (TREE_CODE (type) == ARRAY_TYPE
+ || TREE_CODE (type) == VECTOR_TYPE)
{
tree index;
tree max_index;
/* If the bound of the array is known, take no more initializers
than are allowed. */
- max_index = ((TYPE_DOMAIN (type) && (TREE_CODE (type) == ARRAY_TYPE))
- ? array_type_nelts (type) : NULL_TREE);
+ max_index = NULL_TREE;
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ if (TYPE_DOMAIN (type))
+ max_index = array_type_nelts (type);
+ }
+ else
+ {
+ /* For a vector, the representation type is a struct
+ containing a single member which is an array of the
+ appropriate size. */
+ tree rtype = TYPE_DEBUG_REPRESENTATION_TYPE (type);
+ if (rtype && TYPE_DOMAIN (TREE_TYPE (TYPE_FIELDS (rtype))))
+ max_index = array_type_nelts (TREE_TYPE (TYPE_FIELDS (rtype)));
+ }
+
/* Loop through the array elements, gathering initializers. */
for (index = size_zero_node;
*initp && (!max_index || !tree_int_cst_lt (max_index, index));
@@ -4399,7 +4392,8 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
init = grok_reference_init (decl, type, init, cleanup);
else if (init)
{
- if (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init))
+ if (TREE_CODE (init) == CONSTRUCTOR
+ && BRACE_ENCLOSED_INITIALIZER_P (init))
{
/* [dcl.init] paragraph 13,
If T is a scalar type, then a declaration of the form
@@ -4424,15 +4418,13 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
array size from the initializer. */
maybe_deduce_size_from_array_init (decl, init);
type = TREE_TYPE (decl);
- if (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init))
- TREE_TYPE (init) = type;
if (TYPE_HAS_CONSTRUCTOR (type) || TYPE_NEEDS_CONSTRUCTING (type))
{
if (TREE_CODE (type) == ARRAY_TYPE)
goto initialize_aggr;
else if (TREE_CODE (init) == CONSTRUCTOR
- && TREE_HAS_CONSTRUCTOR (init))
+ && BRACE_ENCLOSED_INITIALIZER_P (init))
{
if (TYPE_NON_AGGREGATE_CLASS (type))
{
@@ -4530,7 +4522,7 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
asm-specification, indicates that the variable should be
placed in a particular register. */
if (DECL_REGISTER (decl))
- DECL_C_HARD_REGISTER (decl) = 1;
+ DECL_HARD_REGISTER (decl) = 1;
}
/* We don't create any RTL for local variables. */
@@ -5679,8 +5671,10 @@ grokfndecl (tree ctype,
tree old_decl;
old_decl = check_classfn (ctype, decl,
- processing_template_decl
- > template_class_depth (ctype));
+ (processing_template_decl
+ > template_class_depth (ctype))
+ ? current_template_parms
+ : NULL_TREE);
if (old_decl && TREE_CODE (old_decl) == TEMPLATE_DECL)
/* Because grokfndecl is always supposed to return a
@@ -7267,6 +7261,13 @@ grokdeclarator (tree declarator,
type = create_array_type_for_decl (dname, type, size);
+ if (declarator
+ && (TREE_CODE (declarator) == INDIRECT_REF
+ || TREE_CODE (declarator) == ADDR_EXPR))
+ /* We can never complete an array type which is the target of a
+ pointer, so go ahead and lay it out. */
+ layout_type (type);
+
ctype = NULL_TREE;
}
break;
@@ -7752,6 +7753,7 @@ grokdeclarator (tree declarator,
}
if (declarator == NULL_TREE
+ || TREE_CODE (declarator) == ERROR_MARK
|| TREE_CODE (declarator) == IDENTIFIER_NODE
|| (TREE_CODE (declarator) == TEMPLATE_ID_EXPR
&& (TREE_CODE (type) == FUNCTION_TYPE
@@ -9919,7 +9921,9 @@ build_enumerator (tree name, tree value, tree enumtype)
decl = build_decl (CONST_DECL, name, type);
DECL_CONTEXT (decl) = FROB_CONTEXT (context);
- TREE_CONSTANT (decl) = TREE_READONLY (decl) = 1;
+ TREE_CONSTANT (decl) = 1;
+ TREE_INVARIANT (decl) = 1;
+ TREE_READONLY (decl) = 1;
DECL_INITIAL (decl) = value;
if (context && context == current_class_type)
@@ -10714,10 +10718,8 @@ finish_function (int flags)
of curly braces for a function. */
my_friendly_assert (stmts_are_full_exprs_p (), 19990831);
- /* Set up the named return value optimization, if we can. Here, we
- eliminate the copy from the nrv into the RESULT_DECL and any cleanup
- for the nrv. genrtl_start_function and declare_return_variable
- handle making the nrv and RESULT_DECL share space. */
+ /* Set up the named return value optimization, if we can. Candidate
+ variables are selected in check_return_value. */
if (current_function_return_value)
{
tree r = current_function_return_value;
@@ -10734,16 +10736,9 @@ finish_function (int flags)
/* Skip the artificial function body block. */
&& (outer = BLOCK_SUBBLOCKS (BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl))),
chain_member (r, BLOCK_VARS (outer))))
- {
-
- DECL_ALIGN (r) = DECL_ALIGN (DECL_RESULT (fndecl));
- walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
- nullify_returns_r, r);
- }
- else
- /* Clear it so genrtl_start_function and declare_return_variable
- know we're not optimizing. */
- current_function_return_value = NULL_TREE;
+ finalize_nrv (&DECL_SAVED_TREE (fndecl), r, DECL_RESULT (fndecl));
+
+ current_function_return_value = NULL_TREE;
}
/* Remember that we were in class scope. */
@@ -10786,9 +10781,21 @@ finish_function (int flags)
&& (DECL_INLINE (fndecl) || processing_template_decl))
warning ("no return statement in function returning non-void");
- /* We're leaving the context of this function, so zap cfun.
- It's still in DECL_STRUCT_FUNCTION, and we'll restore it in
- tree_rest_of_compilation. */
+ /* Store the end of the function, so that we get good line number
+ info for the epilogue. */
+ cfun->function_end_locus = input_location;
+
+ /* Genericize before inlining. */
+ if (!processing_template_decl)
+ {
+ c_genericize (fndecl);
+
+ /* Handle attribute((warn_unused_result)). Relies on gimple input. */
+ c_warn_unused_result (&DECL_SAVED_TREE (fndecl));
+ }
+
+ /* We're leaving the context of this function, so zap cfun. It's still in
+ DECL_STRUCT_FUNCTION, and we'll restore it in tree_rest_of_compilation. */
cfun = NULL;
current_function_decl = NULL;
@@ -11162,7 +11169,7 @@ build_void_list_node (void)
return t;
}
-static int
+bool
cp_missing_noreturn_ok_p (tree decl)
{
/* A missing noreturn is ok for the `main' function. */
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index de09eb69261..4c36eb5549c 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -46,8 +46,10 @@ Boston, MA 02111-1307, USA. */
#include "cpplib.h"
#include "target.h"
#include "c-common.h"
+#include "tree-mudflap.h"
#include "cgraph.h"
#include "tree-inline.h"
+
extern cpp_reader *parse_in;
/* This structure contains information about the initializations
@@ -612,15 +614,19 @@ check_java_method (tree method)
/* Sanity check: report error if this function FUNCTION is not
really a member of the class (CTYPE) it is supposed to belong to.
- CNAME is the same here as it is for grokclassfn above.
- TEMPLATE_HEADER_P is true when this declaration comes with a
- template header. */
+ TEMPLATE_PARMS is used to specifiy the template parameters of a member
+ template passed as FUNCTION_DECL. If the member template is passed as a
+ TEMPLATE_DECL, it can be NULL since the parameters can be extracted
+ from the declaration. If the function is not a function template, it
+ must be NULL.
+ It returns the original declaration for the function, or NULL_TREE
+ if no declaration was found (and an error was emitted). */
tree
-check_classfn (tree ctype, tree function, bool template_header_p)
+check_classfn (tree ctype, tree function, tree template_parms)
{
int ix;
- int is_template;
+ bool is_template;
if (DECL_USE_TEMPLATE (function)
&& !(TREE_CODE (function) == TEMPLATE_DECL
@@ -638,9 +644,20 @@ check_classfn (tree ctype, tree function, bool template_header_p)
find the method, but we don't complain. */
return NULL_TREE;
+ /* Basic sanity check: for a template function, the template parameters
+ either were not passed, or they are the same of DECL_TEMPLATE_PARMS. */
+ if (TREE_CODE (function) == TEMPLATE_DECL)
+ {
+ my_friendly_assert (!template_parms
+ || comp_template_parms
+ (template_parms,
+ DECL_TEMPLATE_PARMS (function)),
+ 20040303);
+ template_parms = DECL_TEMPLATE_PARMS (function);
+ }
+
/* OK, is this a definition of a member template? */
- is_template = (TREE_CODE (function) == TEMPLATE_DECL
- || template_header_p);
+ is_template = (template_parms != NULL_TREE);
ix = lookup_fnfields_1 (complete_type (ctype),
DECL_CONSTRUCTOR_P (function) ? ctor_identifier :
@@ -684,6 +701,9 @@ check_classfn (tree ctype, tree function, bool template_header_p)
if (same_type_p (TREE_TYPE (TREE_TYPE (function)),
TREE_TYPE (TREE_TYPE (fndecl)))
&& compparms (p1, p2)
+ && (!is_template
+ || comp_template_parms (template_parms,
+ DECL_TEMPLATE_PARMS (fndecl)))
&& (DECL_TEMPLATE_SPECIALIZATION (function)
== DECL_TEMPLATE_SPECIALIZATION (fndecl))
&& (!DECL_TEMPLATE_SPECIALIZATION (function)
@@ -2292,7 +2312,7 @@ do_static_initialization (tree decl, tree init)
if (flag_use_cxa_atexit)
register_dtor_fn (decl);
- /* Finsh up. */
+ /* Finish up. */
finish_static_initialization_or_destruction (guard_if_stmt);
}
@@ -2569,7 +2589,7 @@ finish_file (void)
timevar_push (TV_VARCONST);
emit_support_tinfos ();
-
+
do
{
tree t;
@@ -2854,6 +2874,11 @@ finish_file (void)
cgraph_optimize ();
}
+ /* Emit mudflap static registration function. This must be done
+ after all the user functions have been expanded. */
+ if (flag_mudflap)
+ mudflap_finish_file ();
+
/* Now, issue warnings about static, but not defined, functions,
etc., and emit debugging information. */
walk_namespaces (wrapup_globals_for_namespace, /*data=*/&reconsider);
@@ -2867,12 +2892,12 @@ finish_file (void)
to a file. */
{
int flags;
- FILE *stream = dump_begin (TDI_all, &flags);
+ FILE *stream = dump_begin (TDI_tu, &flags);
if (stream)
{
dump_node (global_namespace, flags & ~TDF_SLIM, stream);
- dump_end (TDI_all, stream);
+ dump_end (TDI_tu, stream);
}
}
@@ -2914,7 +2939,7 @@ build_offset_ref_call_from_tree (tree fn, tree args)
20030708);
if (type_dependent_expression_p (fn)
|| any_type_dependent_arguments_p (args))
- return build_min_nt (CALL_EXPR, fn, args);
+ return build_min_nt (CALL_EXPR, fn, args, NULL_TREE);
/* Transform the arguments and add the implicit "this"
parameter. That must be done before the FN is transformed
@@ -2944,7 +2969,7 @@ build_offset_ref_call_from_tree (tree fn, tree args)
expr = build_function_call (fn, args);
if (processing_template_decl && expr != error_mark_node)
- return build_min_non_dep (CALL_EXPR, expr, orig_fn, orig_args);
+ return build_min_non_dep (CALL_EXPR, expr, orig_fn, orig_args, NULL_TREE);
return expr;
}
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index e313c16f39d..6e186503bad 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -47,7 +47,7 @@ static cxx_pretty_printer scratch_pretty_printer;
# define NEXT_CODE(T) (TREE_CODE (TREE_TYPE (T)))
#define reinit_global_formatting_buffer() \
- output_clear_message_text (scratch_buffer)
+ pp_clear_output_area (scratch_buffer)
static const char *args_to_string (tree, int);
static const char *assop_to_string (enum tree_code);
@@ -1604,10 +1604,6 @@ dump_expr (tree t, int flags)
break;
}
- case EXPR_WITH_FILE_LOCATION:
- dump_expr (EXPR_WFL_NODE (t), flags);
- break;
-
case CONSTRUCTOR:
if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
{
@@ -2191,8 +2187,7 @@ print_instantiation_full_context (diagnostic_context *context)
decl_as_string (TINST_DECL (p),
TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
- location.line = TINST_LINE (p);
- location.file = TINST_FILE (p);
+ location = *EXPR_LOCUS (p);
p = TREE_CHAIN (p);
}
}
@@ -2211,8 +2206,7 @@ print_instantiation_partial_context (diagnostic_context *context,
loc.file, loc.line,
decl_as_string (TINST_DECL (t),
TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
- loc.line = TINST_LINE (t);
- loc.file = TINST_FILE (t);
+ loc = *EXPR_LOCUS (t);
}
pp_verbatim (context->printer, "%s:%d: instantiated from here\n",
loc.file, loc.line);
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index 7e172d62e6b..79f1dfac0d9 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -47,7 +47,6 @@ static tree do_end_catch (tree);
static bool decl_is_java_type (tree decl, int err);
static void initialize_handler_parm (tree, tree);
static tree do_allocate_exception (tree);
-static tree stabilize_throw_expr (tree, tree *);
static tree wrap_cleanups_r (tree *, int *, void *);
static int complete_ptr_ref_or_void_ptr_p (tree, tree);
static bool is_admissible_throw_operand (tree);
@@ -145,7 +144,7 @@ build_eh_type_type (tree type)
mark_used (exp);
- return build1 (ADDR_EXPR, ptr_type_node, exp);
+ return convert (ptr_type_node, build_address (exp));
}
tree
@@ -507,7 +506,6 @@ do_allocate_exception (tree type)
NULL_TREE));
}
-#if 0
/* Call __cxa_free_exception from a cleanup. This is never invoked
directly, but see the comment for stabilize_throw_expr. */
@@ -526,7 +524,6 @@ do_free_exception (tree ptr)
return build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE));
}
-#endif
/* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR.
Called from build_throw via walk_tree_without_duplicates. */
@@ -558,58 +555,6 @@ wrap_cleanups_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
return NULL_TREE;
}
-/* Like stabilize_expr, but specifically for a thrown expression. When
- throwing a temporary class object, we want to construct it directly into
- the thrown exception, so we look past the TARGET_EXPR and stabilize the
- arguments of the call instead.
-
- The case where EXP is a call to a function returning a class is a bit of
- a grey area in the standard; it's unclear whether or not it should be
- allowed to throw. I'm going to say no, as that allows us to optimize
- this case without worrying about deallocating the exception object if it
- does. The alternatives would be either not optimizing this case, or
- wrapping the initialization in a TRY_CATCH_EXPR to call do_free_exception
- rather than in a MUST_NOT_THROW_EXPR, for this case only. */
-
-static tree
-stabilize_throw_expr (tree exp, tree *initp)
-{
- tree init_expr;
-
- if (TREE_CODE (exp) == TARGET_EXPR
- && TREE_CODE (TARGET_EXPR_INITIAL (exp)) == AGGR_INIT_EXPR
- && flag_elide_constructors)
- {
- tree aggr_init = AGGR_INIT_EXPR_CHECK (TARGET_EXPR_INITIAL (exp));
- tree args = TREE_OPERAND (aggr_init, 1);
- tree newargs = NULL_TREE;
- tree *p = &newargs;
-
- init_expr = void_zero_node;
- for (; args; args = TREE_CHAIN (args))
- {
- tree arg = TREE_VALUE (args);
- tree arg_init_expr;
-
- arg = stabilize_expr (arg, &arg_init_expr);
-
- if (TREE_SIDE_EFFECTS (arg_init_expr))
- init_expr = build (COMPOUND_EXPR, void_type_node, init_expr,
- arg_init_expr);
- *p = tree_cons (NULL_TREE, arg, NULL_TREE);
- p = &TREE_CHAIN (*p);
- }
- TREE_OPERAND (aggr_init, 1) = newargs;
- }
- else
- {
- exp = stabilize_expr (exp, &init_expr);
- }
-
- *initp = init_expr;
- return exp;
-}
-
/* Build a throw expression. */
tree
@@ -663,6 +608,7 @@ build_throw (tree exp)
tree object, ptr;
tree tmp;
tree temp_expr, allocate_expr;
+ bool elided;
fn = get_identifier ("__cxa_throw");
if (!get_global_value_if_present (fn, &fn))
@@ -703,11 +649,6 @@ build_throw (tree exp)
the call to __cxa_allocate_exception first (which doesn't
matter, since it can't throw). */
- /* Pre-evaluate the thrown expression first, since if we allocated
- the space first we would have to deal with cleaning it up if
- evaluating this expression throws. */
- exp = stabilize_throw_expr (exp, &temp_expr);
-
/* Allocate the space for the exception. */
allocate_expr = do_allocate_exception (TREE_TYPE (exp));
allocate_expr = get_target_expr (allocate_expr);
@@ -715,6 +656,8 @@ build_throw (tree exp)
object = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (exp)), ptr);
object = build_indirect_ref (object, NULL);
+ elided = (TREE_CODE (exp) == TARGET_EXPR);
+
/* And initialize the exception object. */
exp = build_init (object, exp, LOOKUP_ONLYCONVERTING);
if (exp == error_mark_node)
@@ -723,10 +666,35 @@ build_throw (tree exp)
return error_mark_node;
}
- exp = build1 (MUST_NOT_THROW_EXPR, void_type_node, exp);
+ /* Pre-evaluate the thrown expression first, since if we allocated
+ the space first we would have to deal with cleaning it up if
+ evaluating this expression throws.
+
+ The case where EXP the initializer is a call to a constructor or a
+ function returning a class is a bit of a grey area in the
+ standard; it's unclear whether or not it should be allowed to
+ throw. We used to say no, as that allowed us to optimize this
+ case without worrying about deallocating the exception object if
+ it does. But that conflicted with expectations (PR 13944) and the
+ EDG compiler; now we wrap the initialization in a TRY_CATCH_EXPR
+ to call do_free_exception rather than in a MUST_NOT_THROW_EXPR,
+ for this case only.
+
+ Note that we don't check the return value from stabilize_init
+ because it will only return false in cases where elided is true,
+ and therefore we don't need to work around the failure to
+ preevaluate. */
+ stabilize_init (exp, &temp_expr);
+
+ if (elided)
+ exp = build (TRY_CATCH_EXPR, void_type_node, exp,
+ do_free_exception (ptr));
+ else
+ exp = build1 (MUST_NOT_THROW_EXPR, void_type_node, exp);
+
/* Prepend the allocation. */
exp = build (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp);
- if (temp_expr != void_zero_node)
+ if (temp_expr)
{
/* Prepend the calculation of the throw expression. Also, force
any cleanups from the expression to be evaluated here so that
@@ -921,11 +889,10 @@ check_handlers_1 (tree master, tree handlers)
if (TREE_TYPE (handler)
&& can_convert_eh (type, TREE_TYPE (handler)))
{
- input_line = STMT_LINENO (handler);
- warning ("exception of type `%T' will be caught",
- TREE_TYPE (handler));
- input_line = STMT_LINENO (master);
- warning (" by earlier handler for `%T'", type);
+ warning ("%Hexception of type `%T' will be caught",
+ EXPR_LOCUS (handler), TREE_TYPE (handler));
+ warning ("%H by earlier handler for `%T'",
+ EXPR_LOCUS (master), type);
break;
}
}
@@ -943,11 +910,8 @@ check_handlers (tree handlers)
if (TREE_CHAIN (handler) == NULL_TREE)
/* No more handlers; nothing to shadow. */;
else if (TREE_TYPE (handler) == NULL_TREE)
- {
- input_line = STMT_LINENO (handler);
- pedwarn
- ("`...' handler must be the last handler for its try block");
- }
+ pedwarn ("%H`...' handler must be the last handler for"
+ " its try block", EXPR_LOCUS (handler));
else
check_handlers_1 (handler, TREE_CHAIN (handler));
}
diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c
index 00f8676e180..e12c6a4a64f 100644
--- a/gcc/cp/expr.c
+++ b/gcc/cp/expr.c
@@ -73,6 +73,9 @@ cplus_expand_constant (tree cst)
}
/* Hook used by expand_expr to expand language-specific tree codes. */
+/* ??? The only thing that should be here are things needed to expand
+ constant initializers; everything else should be handled by the
+ gimplification routines. Are EMPTY_CLASS_EXPR or BASELINK needed? */
rtx
cxx_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier,
@@ -81,7 +84,6 @@ cxx_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier,
tree type = TREE_TYPE (exp);
enum machine_mode mode = TYPE_MODE (type);
enum tree_code code = TREE_CODE (exp);
- rtx ret;
/* No sense saving up arithmetic to be done
if it's all in the wrong mode to form part of an address.
@@ -99,17 +101,6 @@ cxx_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier,
case OFFSET_REF:
/* Offset refs should not make it through to here. */
abort ();
- return const0_rtx;
-
- case THROW_EXPR:
- expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
- return const0_rtx;
-
- case MUST_NOT_THROW_EXPR:
- expand_eh_region_start ();
- ret = expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier);
- expand_eh_region_end_must_not_throw (build_call (terminate_node, 0));
- return ret;
case EMPTY_CLASS_EXPR:
/* We don't need to generate any code for an empty class. */
@@ -122,7 +113,4 @@ cxx_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier,
default:
return c_expand_expr (exp, target, tmode, modifier, alt_rtl);
}
- abort ();
- /* NOTREACHED */
- return NULL;
}
diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c
index c81bd934e0a..e55adaa8bc0 100644
--- a/gcc/cp/friend.c
+++ b/gcc/cp/friend.c
@@ -397,7 +397,10 @@ do_friend (tree ctype, tree declarator, tree decl,
validity of the declaration later. */
decl = push_template_decl_real (decl, /*is_friend=*/1);
else
- decl = check_classfn (ctype, decl, template_member_p);
+ decl = check_classfn (ctype, decl,
+ template_member_p
+ ? current_template_parms
+ : NULL_TREE);
if (template_member_p && decl && TREE_CODE (decl) == FUNCTION_DECL)
decl = DECL_TI_TEMPLATE (decl);
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index e9142b775e0..8cf0019cfab 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -248,7 +248,10 @@ build_zero_init (tree type, tree nelts, bool static_storage_p)
/* In all cases, the initializer is a constant. */
if (init)
- TREE_CONSTANT (init) = 1;
+ {
+ TREE_CONSTANT (init) = 1;
+ TREE_INVARIANT (init) = 1;
+ }
return init;
}
@@ -340,8 +343,7 @@ perform_member_init (tree member, tree init)
finish_expr_stmt (init);
}
}
- else if (TYPE_NEEDS_CONSTRUCTING (type)
- || (init && TYPE_HAS_CONSTRUCTOR (type)))
+ else if (TYPE_NEEDS_CONSTRUCTING (type))
{
if (explicit
&& TREE_CODE (type) == ARRAY_TYPE
@@ -729,12 +731,9 @@ build_vtbl_address (tree binfo)
TREE_USED (vtbl) = 1;
/* Now compute the address to use when initializing the vptr. */
- vtbl = BINFO_VTABLE (binfo_for);
+ vtbl = unshare_expr (BINFO_VTABLE (binfo_for));
if (TREE_CODE (vtbl) == VAR_DECL)
- {
- vtbl = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (vtbl)), vtbl);
- TREE_CONSTANT (vtbl) = 1;
- }
+ vtbl = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (vtbl)), vtbl);
return vtbl;
}
@@ -768,7 +767,8 @@ expand_virtual_init (tree binfo, tree decl)
TREE_TYPE (vtt_parm),
vtt_parm,
vtt_index);
- vtbl2 = build1 (INDIRECT_REF, TREE_TYPE (vtbl), vtbl2);
+ vtbl2 = build_indirect_ref (vtbl2, NULL);
+ vtbl2 = convert (TREE_TYPE (vtbl), vtbl2);
/* The actual initializer is the VTT value only in the subobject
constructor. In maybe_clone_body we'll substitute NULL for
@@ -1091,34 +1091,25 @@ build_aggr_init (tree exp, tree init, int flags)
if (TREE_CODE (type) == ARRAY_TYPE)
{
- /* Must arrange to initialize each element of EXP
- from elements of INIT. */
- tree itype = init ? TREE_TYPE (init) : NULL_TREE;
-
- if (init && !itype)
+ tree itype;
+
+ /* An array may not be initialized use the parenthesized
+ initialization form -- unless the initializer is "()". */
+ if (init && TREE_CODE (init) == TREE_LIST)
{
- /* Handle bad initializers like:
- class COMPLEX {
- public:
- double re, im;
- COMPLEX(double r = 0.0, double i = 0.0) {re = r; im = i;};
- ~COMPLEX() {};
- };
-
- int main(int argc, char **argv) {
- COMPLEX zees(1.0, 0.0)[10];
- }
- */
error ("bad array initializer");
return error_mark_node;
}
+ /* Must arrange to initialize each element of EXP
+ from elements of INIT. */
+ itype = init ? TREE_TYPE (init) : NULL_TREE;
if (cp_type_quals (type) != TYPE_UNQUALIFIED)
TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
if (itype && cp_type_quals (itype) != TYPE_UNQUALIFIED)
- TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype);
+ itype = TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype);
stmt_expr = build_vec_init (exp, NULL_TREE, init,
- init && same_type_p (TREE_TYPE (init),
- TREE_TYPE (exp)));
+ itype && same_type_p (itype,
+ TREE_TYPE (exp)));
TREE_READONLY (exp) = was_const;
TREE_THIS_VOLATILE (exp) = was_volatile;
TREE_TYPE (exp) = type;
@@ -1153,9 +1144,13 @@ build_init (tree decl, tree init, int flags)
{
tree expr;
- if (IS_AGGR_TYPE (TREE_TYPE (decl))
- || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
+ if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
expr = build_aggr_init (decl, init, flags);
+ else if (CLASS_TYPE_P (TREE_TYPE (decl)))
+ expr = build_special_member_call (decl, complete_ctor_identifier,
+ build_tree_list (NULL_TREE, init),
+ TYPE_BINFO (TREE_TYPE (decl)),
+ LOOKUP_NORMAL|flags);
else
expr = build (INIT_EXPR, TREE_TYPE (decl), decl, init);
@@ -1190,8 +1185,7 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags)
to run a new constructor; and catching an exception, where we
have already built up the constructor call so we could wrap it
in an exception region. */;
- else if (TREE_CODE (init) == CONSTRUCTOR
- && TREE_HAS_CONSTRUCTOR (init))
+ else if (BRACE_ENCLOSED_INITIALIZER_P (init))
{
/* A brace-enclosed initializer for an aggregate. */
my_friendly_assert (CP_AGGREGATE_TYPE_P (type), 20021016);
@@ -1836,7 +1830,7 @@ build_new (tree placement, tree decl, tree init, int use_global_new)
/* Wrap it in a NOP_EXPR so warn_if_unused_value doesn't complain. */
rval = build1 (NOP_EXPR, TREE_TYPE (rval), rval);
- TREE_NO_UNUSED_WARNING (rval) = 1;
+ TREE_NO_WARNING (rval) = 1;
return rval;
}
@@ -1919,7 +1913,7 @@ static tree
build_new_1 (tree exp)
{
tree placement, init;
- tree true_type, size, rval, t;
+ tree true_type, size, rval;
/* The type of the new-expression. (This type is always a pointer
type.) */
tree pointer_type;
@@ -1960,6 +1954,7 @@ build_new_1 (tree exp)
address of the first array element. This node is a VAR_DECL, and
is therefore reusable. */
tree data_addr;
+ tree init_preeval_expr = NULL_TREE;
placement = TREE_OPERAND (exp, 0);
type = TREE_OPERAND (exp, 1);
@@ -2019,9 +2014,10 @@ build_new_1 (tree exp)
{
tree class_addr, alloc_decl;
tree class_decl = build_java_class_ref (true_type);
- tree class_size = size_in_bytes (true_type);
static const char alloc_name[] = "_Jv_AllocObject";
+
use_java_new = 1;
+ alloc_decl = NULL;
if (!get_global_value_if_present (get_identifier (alloc_name),
&alloc_decl))
{
@@ -2037,8 +2033,7 @@ build_new_1 (tree exp)
class_addr = build1 (ADDR_EXPR, jclass_node, class_decl);
alloc_call = (build_function_call
(alloc_decl,
- tree_cons (NULL_TREE, class_addr,
- build_tree_list (NULL_TREE, class_size))));
+ build_tree_list (NULL_TREE, class_addr)));
}
else
{
@@ -2128,18 +2123,8 @@ build_new_1 (tree exp)
placement delete. */
if (placement_allocation_fn_p)
{
- tree inits = NULL_TREE;
- t = TREE_CHAIN (TREE_OPERAND (alloc_call, 1));
- for (; t; t = TREE_CHAIN (t))
- if (TREE_SIDE_EFFECTS (TREE_VALUE (t)))
- {
- tree init;
- TREE_VALUE (t) = stabilize_expr (TREE_VALUE (t), &init);
- if (inits)
- inits = build (COMPOUND_EXPR, void_type_node, inits, init);
- else
- inits = init;
- }
+ tree inits;
+ stabilize_call (alloc_call, &inits);
if (inits)
alloc_expr = build (COMPOUND_EXPR, TREE_TYPE (alloc_expr), inits,
alloc_expr);
@@ -2182,27 +2167,43 @@ build_new_1 (tree exp)
data_addr = alloc_node;
}
- /* Now initialize the allocated object. */
+ /* Now initialize the allocated object. Note that we preevaluate the
+ initialization expression, apart from the actual constructor call or
+ assignment--we do this because we want to delay the allocation as long
+ as possible in order to minimize the size of the exception region for
+ placement delete. */
if (is_initialized)
{
+ bool stable;
+
init_expr = build_indirect_ref (data_addr, NULL);
if (init == void_zero_node)
init = build_default_init (full_type, nelts);
- else if (init && pedantic && has_array)
+ else if (init && has_array)
pedwarn ("ISO C++ forbids initialization in array new");
if (has_array)
- init_expr
- = build_vec_init (init_expr,
- cp_build_binary_op (MINUS_EXPR, outer_nelts,
- integer_one_node),
- init, /*from_array=*/0);
+ {
+ init_expr
+ = build_vec_init (init_expr,
+ cp_build_binary_op (MINUS_EXPR, outer_nelts,
+ integer_one_node),
+ init, /*from_array=*/0);
+
+ /* An array initialization is stable because the initialization
+ of each element is a full-expression, so the temporaries don't
+ leak out. */
+ stable = true;
+ }
else if (TYPE_NEEDS_CONSTRUCTING (type))
- init_expr = build_special_member_call (init_expr,
- complete_ctor_identifier,
- init, TYPE_BINFO (true_type),
- LOOKUP_NORMAL);
+ {
+ init_expr = build_special_member_call (init_expr,
+ complete_ctor_identifier,
+ init, TYPE_BINFO (true_type),
+ LOOKUP_NORMAL);
+ stable = stabilize_init (init_expr, &init_preeval_expr);
+ }
else
{
/* We are processing something like `new int (10)', which
@@ -2210,15 +2211,13 @@ build_new_1 (tree exp)
if (TREE_CODE (init) == TREE_LIST)
init = build_x_compound_expr_from_list (init, "new initializer");
-
+
else if (TREE_CODE (init) == CONSTRUCTOR
&& TREE_TYPE (init) == NULL_TREE)
- {
- pedwarn ("ISO C++ forbids aggregate initializer to new");
- init = digest_init (type, init, 0);
- }
+ abort ();
init_expr = build_modify_expr (init_expr, INIT_EXPR, init);
+ stable = stabilize_init (init_expr, &init_preeval_expr);
}
if (init_expr == error_mark_node)
@@ -2245,31 +2244,24 @@ build_new_1 (tree exp)
(placement_allocation_fn_p
? alloc_call : NULL_TREE));
- /* Ack! First we allocate the memory. Then we set our sentry
- variable to true, and expand a cleanup that deletes the memory
- if sentry is true. Then we run the constructor, and finally
- clear the sentry.
-
- It would be nice to be able to handle this without the sentry
- variable, perhaps with a TRY_CATCH_EXPR, but this doesn't
- work. We allocate the space first, so if there are any
- temporaries with cleanups in the constructor args we need this
- EH region to extend until end of full-expression to preserve
- nesting.
-
- If the backend had some mechanism so that we could force the
- allocation to be expanded after all the other args to the
- constructor, that would fix the nesting problem and we could
- do away with this complexity. But that would complicate other
- things; in particular, it would make it difficult to bail out
- if the allocation function returns null. Er, no, it wouldn't;
- we just don't run the constructor. The standard says it's
- unspecified whether or not the args are evaluated.
-
- FIXME FIXME FIXME inline invisible refs as refs. That way we
- can preevaluate value parameters. */
-
- if (cleanup)
+ if (!cleanup)
+ /* We're done. */;
+ else if (stable)
+ /* This is much simpler if we were able to preevaluate all of
+ the arguments to the constructor call. */
+ init_expr = build (TRY_CATCH_EXPR, void_type_node,
+ init_expr, cleanup);
+ else
+ /* Ack! First we allocate the memory. Then we set our sentry
+ variable to true, and expand a cleanup that deletes the
+ memory if sentry is true. Then we run the constructor, and
+ finally clear the sentry.
+
+ We need to do this because we allocate the space first, so
+ if there are any temporaries with cleanups in the
+ constructor args and we weren't able to preevaluate them, we
+ need this EH region to extend until end of full-expression
+ to preserve nesting. */
{
tree end, sentry, begin;
@@ -2290,6 +2282,7 @@ build_new_1 (tree exp)
build (COMPOUND_EXPR, void_type_node, init_expr,
end));
}
+
}
}
else
@@ -2322,6 +2315,9 @@ build_new_1 (tree exp)
rval = build (COMPOUND_EXPR, TREE_TYPE (rval), alloc_expr, rval);
}
+ if (init_preeval_expr)
+ rval = build (COMPOUND_EXPR, TREE_TYPE (rval), init_preeval_expr, rval);
+
/* Convert to the final type. */
rval = build_nop (pointer_type, rval);
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 52d4d770ba8..7b1ff39ca91 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -50,7 +50,7 @@ tree global_namespace;
/* The name of the anonymous namespace, throughout this translation
unit. */
-GTY(()) tree anonymous_namespace_name;
+static GTY(()) tree anonymous_namespace_name;
/* Compute the chain index of a binding_entry given the HASH value of its
diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h
index 1ade1a91f3f..044f2895c0c 100644
--- a/gcc/cp/name-lookup.h
+++ b/gcc/cp/name-lookup.h
@@ -317,7 +317,6 @@ static inline bool
get_global_value_if_present (tree id, tree *decl)
{
tree global_value = namespace_binding (id, global_namespace);
-
if (global_value)
*decl = global_value;
return global_value != NULL;
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index 2fd10599151..7f45ae9123c 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -36,6 +36,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "hashtab.h"
#include "debug.h"
#include "tree-inline.h"
+#include "flags.h"
+#include "langhooks.h"
+#include "diagnostic.h"
+#include "tree-dump.h"
+#include "tree-gimple.h"
/* Prototypes. */
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index a7f49e0fa12..fdc171e041f 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -3594,7 +3594,10 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
/* Look for the `)' token. */
cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
}
-
+ /* `typeid' may not appear in an integral constant expression. */
+ if (cp_parser_non_integral_constant_expression(parser,
+ "`typeid' operator"))
+ return error_mark_node;
/* Restore the saved message. */
parser->type_definition_forbidden_message = saved_message;
}
@@ -3839,7 +3842,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
|| any_type_dependent_arguments_p (args)))
{
postfix_expression
- = build_min_nt (CALL_EXPR, postfix_expression, args);
+ = build_min_nt (CALL_EXPR, postfix_expression,
+ args, NULL_TREE);
break;
}
@@ -5470,14 +5474,14 @@ cp_parser_statement (cp_parser* parser, bool in_statement_expr_p)
{
tree statement;
cp_token *token;
- int statement_line_number;
+ location_t statement_locus;
/* There is no statement yet. */
statement = NULL_TREE;
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
- /* Remember the line number of the first token in the statement. */
- statement_line_number = token->location.line;
+ /* Remember the location of the first token in the statement. */
+ statement_locus = token->location;
/* If this is a keyword, then that will often determine what kind of
statement we have. */
if (token->type == CPP_KEYWORD)
@@ -5553,7 +5557,10 @@ cp_parser_statement (cp_parser* parser, bool in_statement_expr_p)
/* Set the line number for the statement. */
if (statement && STATEMENT_CODE_P (TREE_CODE (statement)))
- STMT_LINENO (statement) = statement_line_number;
+ {
+ SET_EXPR_LOCUS (statement, NULL);
+ annotate_with_locus (statement, statement_locus);
+ }
}
/* Parse a labeled-statement.
@@ -6349,6 +6356,8 @@ cp_parser_declaration (cp_parser* parser)
if (token1.type != CPP_EOF)
token2 = *cp_lexer_peek_nth_token (parser->lexer, 2);
+ c_lex_string_translate = true;
+
/* If the next token is `extern' and the following token is a string
literal, then we have a linkage specification. */
if (token1.keyword == RID_EXTERN
@@ -6398,8 +6407,6 @@ cp_parser_declaration (cp_parser* parser)
else
/* Try to parse a block-declaration, or a function-definition. */
cp_parser_block_declaration (parser, /*statement_p=*/false);
-
- c_lex_string_translate = true;
}
/* Parse a block-declaration.
@@ -9864,10 +9871,8 @@ cp_parser_asm_definition (cp_parser* parser)
/* Create the ASM_STMT. */
if (at_function_scope_p ())
{
- asm_stmt =
- finish_asm_stmt (volatile_p
- ? ridpointers[(int) RID_VOLATILE] : NULL_TREE,
- string, outputs, inputs, clobbers);
+ asm_stmt = finish_asm_stmt (volatile_p, string, outputs,
+ inputs, clobbers);
/* If the extended syntax was not used, mark the ASM_STMT. */
if (!extended_p)
ASM_INPUT_P (asm_stmt) = 1;
@@ -11541,10 +11546,6 @@ cp_parser_initializer_clause (cp_parser* parser, bool* non_constant_p)
cp_lexer_consume_token (parser->lexer);
/* Create a CONSTRUCTOR to represent the braced-initializer. */
initializer = make_node (CONSTRUCTOR);
- /* Mark it with TREE_HAS_CONSTRUCTOR. This should not be
- necessary, but check_initializer depends upon it, for
- now. */
- TREE_HAS_CONSTRUCTOR (initializer) = 1;
/* If it's not a `}', then there is a non-trivial initializer. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_BRACE))
{
@@ -11788,7 +11789,7 @@ cp_parser_class_specifier (cp_parser* parser)
{
cp_token *token;
tree type;
- tree attributes;
+ tree attributes = NULL_TREE;
int has_trailing_semicolon;
bool nested_name_specifier_p;
unsigned saved_num_template_parameter_lists;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index ca9a3ca27ab..043e3e467c2 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -375,7 +375,9 @@ push_inline_template_parms_recursive (tree parmlist, int levels)
tree decl = build_decl (CONST_DECL, DECL_NAME (parm),
TREE_TYPE (parm));
DECL_ARTIFICIAL (decl) = 1;
- TREE_CONSTANT (decl) = TREE_READONLY (decl) = 1;
+ TREE_CONSTANT (decl) = 1;
+ TREE_INVARIANT (decl) = 1;
+ TREE_READONLY (decl) = 1;
DECL_INITIAL (decl) = DECL_INITIAL (parm);
SET_DECL_TEMPLATE_PARM_P (decl);
pushdecl (decl);
@@ -733,15 +735,7 @@ maybe_process_partial_specialization (tree type)
{
tree tpl_ns = decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type));
if (is_associated_namespace (current_namespace, tpl_ns))
- /* Same or super-using namespace. */
- {
- if (DECL_NAMESPACE_SCOPE_P (CLASSTYPE_TI_TEMPLATE (type)))
- /* If this is a specialization of a namespace-scope class
- template, remember the context of the
- specialization. */
- TYPE_CONTEXT (type) = DECL_CONTEXT (TYPE_NAME (type))
- = FROB_CONTEXT (current_namespace);
- }
+ /* Same or super-using namespace. */;
else
{
pedwarn ("specializing `%#T' in different namespace", type);
@@ -2123,6 +2117,7 @@ build_template_parm_index (int index,
TEMPLATE_PARM_DECL (t) = decl;
TREE_TYPE (t) = type;
TREE_CONSTANT (t) = TREE_CONSTANT (decl);
+ TREE_INVARIANT (t) = TREE_INVARIANT (decl);
TREE_READONLY (t) = TREE_READONLY (decl);
return t;
@@ -2145,6 +2140,7 @@ reduce_template_parm_level (tree index, tree type, int levels)
decl = build_decl (TREE_CODE (orig_decl), DECL_NAME (orig_decl), type);
TREE_CONSTANT (decl) = TREE_CONSTANT (orig_decl);
+ TREE_INVARIANT (decl) = TREE_INVARIANT (orig_decl);
TREE_READONLY (decl) = TREE_READONLY (orig_decl);
DECL_ARTIFICIAL (decl) = 1;
SET_DECL_TEMPLATE_PARM_P (decl);
@@ -2208,11 +2204,15 @@ process_template_parm (tree list, tree next)
TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm));
/* A template parameter is not modifiable. */
- TREE_READONLY (parm) = TREE_CONSTANT (parm) = 1;
+ TREE_CONSTANT (parm) = 1;
+ TREE_INVARIANT (parm) = 1;
+ TREE_READONLY (parm) = 1;
if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1))
TREE_TYPE (parm) = void_type_node;
decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm));
- TREE_CONSTANT (decl) = TREE_READONLY (decl) = 1;
+ TREE_CONSTANT (decl) = 1;
+ TREE_INVARIANT (decl) = 1;
+ TREE_READONLY (decl) = 1;
DECL_INITIAL (parm) = DECL_INITIAL (decl)
= build_template_parm_index (idx, processing_template_decl,
processing_template_decl,
@@ -3016,7 +3016,7 @@ push_template_decl_real (tree decl, int is_friend)
}
}
- /* The DECL_TI_ARGS of DECL contains full set of arguments refering
+ /* The DECL_TI_ARGS of DECL contains full set of arguments referring
back to its most general template. If TMPL is a specialization,
ARGS may only have the innermost set of arguments. Add the missing
argument levels if necessary. */
@@ -4873,7 +4873,9 @@ push_tinst_level (tree d)
return 0;
}
- new = build_expr_wfl (d, input_filename, input_line, 0);
+ new = make_node (TINST_LEVEL);
+ annotate_with_locus (new, input_location);
+ TINST_DECL (new) = d;
TREE_CHAIN (new) = current_tinst_level;
current_tinst_level = new;
@@ -4897,8 +4899,7 @@ pop_tinst_level (void)
/* Restore the filename and line number stashed away when we started
this instantiation. */
- input_line = TINST_LINE (old);
- input_filename = TINST_FILE (old);
+ input_location = *EXPR_LOCUS (old);
extract_interface_info ();
current_tinst_level = TREE_CHAIN (old);
@@ -5150,8 +5151,8 @@ tsubst_friend_function (tree decl, tree args)
{
/* Check to see that the declaration is really present, and,
possibly obtain an improved declaration. */
- tree fn = check_classfn (DECL_CONTEXT (new_friend),
- new_friend, false);
+ tree fn = check_classfn (DECL_CONTEXT (new_friend),
+ new_friend, NULL_TREE);
if (fn)
new_friend = fn;
@@ -5656,7 +5657,7 @@ instantiate_class_template (tree type)
that would be used for non-template classes. */
typedecl = TYPE_MAIN_DECL (type);
input_location = DECL_SOURCE_LOCATION (typedecl);
-
+
unreverse_member_declarations (type);
finish_struct_1 (type);
@@ -7979,15 +7980,10 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
break;
case LABEL_STMT:
- input_line = STMT_LINENO (t);
+ prep_stmt (t);
finish_label_stmt (DECL_NAME (LABEL_STMT_LABEL (t)));
break;
- case FILE_STMT:
- input_filename = FILE_STMT_FILENAME (t);
- add_stmt (build_nt (FILE_STMT, FILE_STMT_FILENAME_NODE (t)));
- break;
-
case GOTO_STMT:
prep_stmt (t);
tmp = GOTO_DESTINATION (t);
@@ -8004,7 +8000,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
case ASM_STMT:
prep_stmt (t);
tmp = finish_asm_stmt
- (ASM_CV_QUAL (t),
+ (ASM_VOLATILE_P (t),
tsubst_expr (ASM_STRING (t), args, complain, in_decl),
tsubst_expr (ASM_OUTPUTS (t), args, complain, in_decl),
tsubst_expr (ASM_INPUTS (t), args, complain, in_decl),
@@ -11159,7 +11155,7 @@ instantiate_decl (tree d, int defer_ok)
goto out;
}
- need_push = !global_bindings_p ();
+ need_push = !cfun || !global_bindings_p ();
if (need_push)
push_to_top_level ();
@@ -11172,8 +11168,7 @@ instantiate_decl (tree d, int defer_ok)
regenerate_decl_from_template (d, td);
/* We already set the file and line above. Reset them now in case
- they changed as a result of calling
- regenerate_decl_from_template. */
+ they changed as a result of calling regenerate_decl_from_template. */
input_location = DECL_SOURCE_LOCATION (d);
if (TREE_CODE (d) == VAR_DECL)
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index e9c06160bbe..ac149c8c91b 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -231,7 +231,7 @@ get_tinfo_decl_dynamic (tree exp)
/* The RTTI information is at index -1. */
index = build_int_2 (-1 * TARGET_VTABLE_DATA_ENTRY_DISTANCE, -1);
t = build_vtbl_ref (exp, index);
- TREE_TYPE (t) = type_info_ptr_type;
+ t = convert (type_info_ptr_type, t);
}
else
/* Otherwise return the type_info for the static type of the expr. */
@@ -797,7 +797,6 @@ tinfo_base_init (tree desc, tree target)
size_binop (MULT_EXPR,
size_int (2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE),
TYPE_SIZE_UNIT (vtable_entry_type)));
- TREE_CONSTANT (vtable_ptr) = 1;
TINFO_VTABLE_DECL (desc) = vtable_ptr;
}
@@ -807,7 +806,9 @@ tinfo_base_init (tree desc, tree target)
init = tree_cons (NULL_TREE, decay_conversion (name_decl), init);
init = build_constructor (NULL_TREE, nreverse (init));
- TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
+ TREE_CONSTANT (init) = 1;
+ TREE_INVARIANT (init) = 1;
+ TREE_STATIC (init) = 1;
init = tree_cons (NULL_TREE, init, NULL_TREE);
return init;
@@ -823,7 +824,9 @@ generic_initializer (tree desc, tree target)
tree init = tinfo_base_init (desc, target);
init = build_constructor (NULL_TREE, init);
- TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
+ TREE_CONSTANT (init) = 1;
+ TREE_INVARIANT (init) = 1;
+ TREE_STATIC (init) = 1;
return init;
}
@@ -850,7 +853,9 @@ ptr_initializer (tree desc, tree target, bool *non_public_ptr)
init);
init = build_constructor (NULL_TREE, nreverse (init));
- TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
+ TREE_CONSTANT (init) = 1;
+ TREE_INVARIANT (init) = 1;
+ TREE_STATIC (init) = 1;
return init;
}
@@ -887,7 +892,9 @@ ptm_initializer (tree desc, tree target, bool *non_public_ptr)
init);
init = build_constructor (NULL_TREE, nreverse (init));
- TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
+ TREE_CONSTANT (init) = 1;
+ TREE_INVARIANT (init) = 1;
+ TREE_STATIC (init) = 1;
return init;
}
@@ -955,7 +962,9 @@ class_initializer (tree desc, tree target, tree trail)
TREE_CHAIN (init) = trail;
init = build_constructor (NULL_TREE, init);
- TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
+ TREE_CONSTANT (init) = 1;
+ TREE_INVARIANT (init) = 1;
+ TREE_STATIC (init) = 1;
return init;
}
@@ -1072,11 +1081,9 @@ get_pseudo_ti_init (tree type, tree var_desc, bool *non_public_p)
base_init = tree_cons (NULL_TREE, offset, base_init);
base_init = tree_cons (NULL_TREE, tinfo, base_init);
base_init = build_constructor (NULL_TREE, base_init);
- TREE_HAS_CONSTRUCTOR (base_init) = 1;
base_inits = tree_cons (NULL_TREE, base_init, base_inits);
}
base_inits = build_constructor (NULL_TREE, base_inits);
- TREE_HAS_CONSTRUCTOR (base_inits) = 1;
base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
/* Prepend the number of bases. */
base_inits = tree_cons (NULL_TREE,
@@ -1246,7 +1253,7 @@ get_pseudo_ti_desc (tree type)
}
/* Make sure the required builtin types exist for generating the type_info
- varable definitions. */
+ variable definitions. */
static void
create_tinfo_types (void)
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 6e15e611317..2fea1c8b86c 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -32,6 +32,7 @@
#include "tree.h"
#include "cp-tree.h"
#include "tree-inline.h"
+#include "tree-mudflap.h"
#include "except.h"
#include "lex.h"
#include "toplev.h"
@@ -41,6 +42,7 @@
#include "output.h"
#include "timevar.h"
#include "debug.h"
+#include "diagnostic.h"
#include "cgraph.h"
/* There routines provide a modular interface to perform many parsing
@@ -55,10 +57,7 @@
static tree maybe_convert_cond (tree);
static tree simplify_aggr_init_exprs_r (tree *, int *, void *);
static void emit_associated_thunks (tree);
-static void genrtl_try_block (tree);
-static void genrtl_eh_spec_block (tree);
-static void genrtl_handler (tree);
-static void cp_expand_stmt (tree);
+static tree finalize_nrv_r (tree *, int *, void *);
/* Finish processing the COND, the SUBSTMT condition for STMT. */
@@ -788,56 +787,6 @@ finish_switch_stmt (tree switch_stmt)
do_poplevel ();
}
-/* Generate the RTL for T, which is a TRY_BLOCK. */
-
-static void
-genrtl_try_block (tree t)
-{
- if (CLEANUP_P (t))
- {
- expand_eh_region_start ();
- expand_stmt (TRY_STMTS (t));
- expand_eh_region_end_cleanup (TRY_HANDLERS (t));
- }
- else
- {
- if (!FN_TRY_BLOCK_P (t))
- emit_line_note (input_location);
-
- expand_eh_region_start ();
- expand_stmt (TRY_STMTS (t));
-
- if (FN_TRY_BLOCK_P (t))
- {
- expand_start_all_catch ();
- in_function_try_handler = 1;
- expand_stmt (TRY_HANDLERS (t));
- in_function_try_handler = 0;
- expand_end_all_catch ();
- }
- else
- {
- expand_start_all_catch ();
- expand_stmt (TRY_HANDLERS (t));
- expand_end_all_catch ();
- }
- }
-}
-
-/* Generate the RTL for T, which is an EH_SPEC_BLOCK. */
-
-static void
-genrtl_eh_spec_block (tree t)
-{
- expand_eh_region_start ();
- expand_stmt (EH_SPEC_STMTS (t));
- expand_eh_region_end_allowed (EH_SPEC_RAISES (t),
- build_call (call_unexpected_node,
- tree_cons (NULL_TREE,
- build_exc_ptr (),
- NULL_TREE)));
-}
-
/* Begin a try-block. Returns a newly-created TRY_BLOCK if
appropriate. */
@@ -925,19 +874,6 @@ finish_function_handler_sequence (tree try_block)
check_handlers (TRY_HANDLERS (try_block));
}
-/* Generate the RTL for T, which is a HANDLER. */
-
-static void
-genrtl_handler (tree t)
-{
- genrtl_do_pushlevel ();
- if (!processing_template_decl)
- expand_start_catch (HANDLER_TYPE (t));
- expand_stmt (HANDLER_BODY (t));
- if (!processing_template_decl)
- expand_end_catch ();
-}
-
/* Begin a handler. Returns a HANDLER if appropriate. */
tree
@@ -1050,28 +986,17 @@ finish_compound_stmt (tree compound_stmt)
return r;
}
-/* Finish an asm-statement, whose components are a CV_QUALIFIER, a
- STRING, some OUTPUT_OPERANDS, some INPUT_OPERANDS, and some
- CLOBBERS. */
+/* Finish an asm-statement, whose components are a STRING, some
+ OUTPUT_OPERANDS, some INPUT_OPERANDS, and some CLOBBERS. Also note
+ whether the asm-statement should be considered volatile. */
tree
-finish_asm_stmt (tree cv_qualifier,
- tree string,
- tree output_operands,
- tree input_operands,
- tree clobbers)
+finish_asm_stmt (int volatile_p, tree string, tree output_operands,
+ tree input_operands, tree clobbers)
{
tree r;
tree t;
- if (cv_qualifier != NULL_TREE
- && cv_qualifier != ridpointers[(int) RID_VOLATILE])
- {
- warning ("%s qualifier ignored on asm",
- IDENTIFIER_POINTER (cv_qualifier));
- cv_qualifier = NULL_TREE;
- }
-
if (!processing_template_decl)
{
int i;
@@ -1133,9 +1058,10 @@ finish_asm_stmt (tree cv_qualifier,
}
}
- r = build_stmt (ASM_STMT, cv_qualifier, string,
+ r = build_stmt (ASM_STMT, string,
output_operands, input_operands,
clobbers);
+ ASM_VOLATILE_P (r) = volatile_p;
return add_stmt (r);
}
@@ -1629,7 +1555,7 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p)
if (type_dependent_expression_p (fn)
|| any_type_dependent_arguments_p (args))
{
- result = build_nt (CALL_EXPR, fn, args);
+ result = build_nt (CALL_EXPR, fn, args, NULL_TREE);
KOENIG_LOOKUP_P (result) = koenig_p;
return result;
}
@@ -1704,7 +1630,7 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p)
if (processing_template_decl)
{
if (type_dependent_expression_p (object))
- return build_nt (CALL_EXPR, orig_fn, orig_args);
+ return build_nt (CALL_EXPR, orig_fn, orig_args, NULL_TREE);
object = build_non_dependent_expr (object);
}
@@ -1737,7 +1663,8 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p)
if (processing_template_decl)
{
- result = build (CALL_EXPR, TREE_TYPE (result), orig_fn, orig_args);
+ result = build (CALL_EXPR, TREE_TYPE (result), orig_fn,
+ orig_args, NULL_TREE);
KOENIG_LOOKUP_P (result) = koenig_p;
}
return result;
@@ -2686,7 +2613,7 @@ finish_id_expression (tree id_expression,
/* Resolve references to variables of anonymous unions
into COMPONENT_REFs. */
if (TREE_CODE (decl) == ALIAS_DECL)
- decl = DECL_INITIAL (decl);
+ decl = unshare_expr (DECL_INITIAL (decl));
}
if (TREE_DEPRECATED (decl))
@@ -2722,37 +2649,8 @@ finish_typeof (tree expr)
return type;
}
-/* Generate RTL for the statement T, and its substatements, and any
- other statements at its nesting level. */
-
-static void
-cp_expand_stmt (tree t)
-{
- switch (TREE_CODE (t))
- {
- case TRY_BLOCK:
- genrtl_try_block (t);
- break;
-
- case EH_SPEC_BLOCK:
- genrtl_eh_spec_block (t);
- break;
-
- case HANDLER:
- genrtl_handler (t);
- break;
-
- case USING_STMT:
- break;
-
- default:
- abort ();
- break;
- }
-}
-
/* Called from expand_body via walk_tree. Replace all AGGR_INIT_EXPRs
- will equivalent CALL_EXPRs. */
+ with equivalent CALL_EXPRs. */
static tree
simplify_aggr_init_exprs_r (tree* tp,
@@ -2905,7 +2803,7 @@ void
expand_body (tree fn)
{
tree saved_function;
-
+
/* Compute the appropriate object-file linkage for inline
functions. */
if (DECL_DECLARED_INLINE_P (fn))
@@ -3013,37 +2911,94 @@ expand_or_defer_fn (tree fn)
function_depth--;
}
-/* Helper function for walk_tree, used by finish_function to override all
- the RETURN_STMTs and pertinent CLEANUP_STMTs for the named return
- value optimization. */
+struct nrv_data
+{
+ tree var;
+ tree result;
+ htab_t visited;
+};
-tree
-nullify_returns_r (tree* tp, int* walk_subtrees, void* data)
+/* Helper function for walk_tree, used by finalize_nrv below. */
+
+static tree
+finalize_nrv_r (tree* tp, int* walk_subtrees, void* data)
{
- tree nrv = (tree) data;
+ struct nrv_data *dp = (struct nrv_data *)data;
+ void **slot;
/* No need to walk into types. There wouldn't be any need to walk into
non-statements, except that we have to consider STMT_EXPRs. */
if (TYPE_P (*tp))
*walk_subtrees = 0;
+ /* Change all returns to just refer to the RESULT_DECL; this is a nop,
+ but differs from using NULL_TREE in that it indicates that we care
+ about the value of the RESULT_DECL. */
else if (TREE_CODE (*tp) == RETURN_STMT)
- RETURN_STMT_EXPR (*tp) = NULL_TREE;
+ RETURN_STMT_EXPR (*tp) = dp->result;
+ /* Change all cleanups for the NRV to only run when an exception is
+ thrown. */
else if (TREE_CODE (*tp) == CLEANUP_STMT
- && CLEANUP_DECL (*tp) == nrv)
+ && CLEANUP_DECL (*tp) == dp->var)
CLEANUP_EH_ONLY (*tp) = 1;
+ /* Replace the DECL_STMT for the NRV with an initialization of the
+ RESULT_DECL, if needed. */
+ else if (TREE_CODE (*tp) == DECL_STMT
+ && DECL_STMT_DECL (*tp) == dp->var)
+ {
+ tree init;
+ if (DECL_INITIAL (dp->var)
+ && DECL_INITIAL (dp->var) != error_mark_node)
+ {
+ init = build (INIT_EXPR, void_type_node, dp->result,
+ DECL_INITIAL (dp->var));
+ DECL_INITIAL (dp->var) = error_mark_node;
+ }
+ else
+ init = NULL_TREE;
+ init = build_stmt (EXPR_STMT, init);
+ SET_EXPR_LOCUS (init, EXPR_LOCUS (*tp));
+ TREE_CHAIN (init) = TREE_CHAIN (*tp);
+ *tp = init;
+ }
+ /* And replace all uses of the NRV with the RESULT_DECL. */
+ else if (*tp == dp->var)
+ *tp = dp->result;
+
+ /* Avoid walking into the same tree more than once. Unfortunately, we
+ can't just use walk_tree_without duplicates because it would only call
+ us for the first occurrence of dp->var in the function body. */
+ slot = htab_find_slot (dp->visited, *tp, INSERT);
+ if (*slot)
+ *walk_subtrees = 0;
+ else
+ *slot = *tp;
/* Keep iterating. */
return NULL_TREE;
}
-/* Start generating the RTL for FN. */
+/* Called from finish_function to implement the named return value
+ optimization by overriding all the RETURN_STMTs and pertinent
+ CLEANUP_STMTs and replacing all occurrences of VAR with RESULT, the
+ RESULT_DECL for the function. */
void
-cxx_expand_function_start (void)
+finalize_nrv (tree *tp, tree var, tree result)
{
- /* Give our named return value the same RTL as our RESULT_DECL. */
- if (current_function_return_value)
- COPY_DECL_RTL (DECL_RESULT (cfun->decl), current_function_return_value);
+ struct nrv_data data;
+
+ /* Copy debugging information from VAR to RESULT. */
+ DECL_NAME (result) = DECL_NAME (var);
+ DECL_SOURCE_LOCATION (result) = DECL_SOURCE_LOCATION (var);
+ DECL_ABSTRACT_ORIGIN (result) = DECL_ABSTRACT_ORIGIN (var);
+ /* Don't forget that we take its address. */
+ TREE_ADDRESSABLE (result) = TREE_ADDRESSABLE (var);
+
+ data.var = var;
+ data.result = result;
+ data.visited = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL);
+ walk_tree (tp, finalize_nrv_r, &data, 0);
+ htab_delete (data.visited);
}
/* Perform initialization related to this module. */
@@ -3051,7 +3006,6 @@ cxx_expand_function_start (void)
void
init_cp_semantics (void)
{
- lang_expand_stmt = cp_expand_stmt;
}
#include "gt-cp-semantics.h"
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 8dd85eae80d..1e470eb862d 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1933,9 +1933,6 @@ tree
make_ptrmem_cst (tree type, tree member)
{
tree ptrmem_cst = make_node (PTRMEM_CST);
- /* If would seem a great convenience if make_node would set
- TREE_CONSTANT for things of class `c', but it does not. */
- TREE_CONSTANT (ptrmem_cst) = 1;
TREE_TYPE (ptrmem_cst) = type;
PTRMEM_CST_MEMBER (ptrmem_cst) = member;
return ptrmem_cst;
@@ -1969,19 +1966,26 @@ cp_walk_subtrees (tree* tp,
void* htab)
{
enum tree_code code = TREE_CODE (*tp);
+ location_t save_locus;
tree result;
#define WALK_SUBTREE(NODE) \
do \
{ \
result = walk_tree (&(NODE), func, data, htab); \
- if (result) \
- return result; \
+ if (result) goto out; \
} \
while (0)
+ /* Set input_location here so we get the right instantiation context
+ if we call instantiate_decl from inlinable_function_p. */
+ save_locus = input_location;
+ if (EXPR_LOCUS (*tp))
+ input_location = *EXPR_LOCUS (*tp);
+
/* Not one of the easy cases. We must explicitly go through the
children. */
+ result = NULL_TREE;
switch (code)
{
case DEFAULT_ARG:
@@ -2019,11 +2023,14 @@ cp_walk_subtrees (tree* tp,
break;
default:
- break;
+ input_location = save_locus;
+ return c_walk_subtrees (tp, walk_subtrees_p, func, data, htab);
}
/* We didn't find what we were looking for. */
- return NULL_TREE;
+ out:
+ input_location = save_locus;
+ return result;
#undef WALK_SUBTREE
}
@@ -2132,11 +2139,10 @@ tree
cp_copy_res_decl_for_inlining (tree result,
tree fn,
tree caller,
- void* decl_map_,
+ void* decl_map_ ATTRIBUTE_UNUSED,
int* need_decl,
tree return_slot_addr)
{
- splay_tree decl_map = (splay_tree)decl_map_;
tree var;
/* If FN returns an aggregate then the caller will always pass the
@@ -2147,7 +2153,7 @@ cp_copy_res_decl_for_inlining (tree result,
references to the RESULT into references to the target. */
/* We should have an explicit return slot iff the return type is
- TREE_ADDRESSABLE. See simplify_aggr_init_expr. */
+ TREE_ADDRESSABLE. See gimplify_aggr_init_expr. */
if (TREE_ADDRESSABLE (TREE_TYPE (result))
!= (return_slot_addr != NULL_TREE))
abort ();
@@ -2164,34 +2170,6 @@ cp_copy_res_decl_for_inlining (tree result,
else
var = copy_decl_for_inlining (result, fn, caller);
- if (DECL_SAVED_FUNCTION_DATA (fn))
- {
- tree nrv = DECL_SAVED_FUNCTION_DATA (fn)->x_return_value;
- if (nrv)
- {
- /* We have a named return value; copy the name and source
- position so we can get reasonable debugging information, and
- register the return variable as its equivalent. */
- if (TREE_CODE (var) == VAR_DECL
- /* But not if we're initializing a variable from the
- enclosing function which already has its own name. */
- && DECL_NAME (var) == NULL_TREE)
- {
- DECL_NAME (var) = DECL_NAME (nrv);
- DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (nrv);
- DECL_ABSTRACT_ORIGIN (var) = DECL_ORIGIN (nrv);
- /* Don't lose initialization info. */
- DECL_INITIAL (var) = DECL_INITIAL (nrv);
- /* Don't forget that it needs to go in the stack. */
- TREE_ADDRESSABLE (var) = TREE_ADDRESSABLE (nrv);
- }
-
- splay_tree_insert (decl_map,
- (splay_tree_key) nrv,
- (splay_tree_value) var);
- }
- }
-
return var;
}
@@ -2214,6 +2192,7 @@ cp_update_decl_after_saving (tree fn,
void
init_tree (void)
{
+ lang_gimplify_stmt = cp_gimplify_stmt;
list_hash_table = htab_create_ggc (31, list_hash, list_hash_eq, NULL);
}
@@ -2431,7 +2410,7 @@ stabilize_expr (tree exp, tree* initp)
if (!TREE_SIDE_EFFECTS (exp))
{
- init_expr = void_zero_node;
+ init_expr = NULL_TREE;
}
else if (!real_lvalue_p (exp)
|| !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (exp)))
@@ -2450,6 +2429,80 @@ stabilize_expr (tree exp, tree* initp)
*initp = init_expr;
return exp;
}
+
+/* Like stabilize_expr, but for a call whose args we want to
+ pre-evaluate. */
+
+void
+stabilize_call (tree call, tree *initp)
+{
+ tree inits = NULL_TREE;
+ tree t;
+
+ if (call == error_mark_node)
+ return;
+
+ if (TREE_CODE (call) != CALL_EXPR
+ && TREE_CODE (call) != AGGR_INIT_EXPR)
+ abort ();
+
+ for (t = TREE_OPERAND (call, 1); t; t = TREE_CHAIN (t))
+ if (TREE_SIDE_EFFECTS (TREE_VALUE (t)))
+ {
+ tree init;
+ TREE_VALUE (t) = stabilize_expr (TREE_VALUE (t), &init);
+ if (!init)
+ /* Nothing. */;
+ else if (inits)
+ inits = build (COMPOUND_EXPR, void_type_node, inits, init);
+ else
+ inits = init;
+ }
+
+ *initp = inits;
+}
+
+/* Like stabilize_expr, but for an initialization. If we are initializing
+ an object of class type, we don't want to introduce an extra temporary,
+ so we look past the TARGET_EXPR and stabilize the arguments of the call
+ instead. */
+
+bool
+stabilize_init (tree init, tree *initp)
+{
+ tree t = init;
+
+ if (t == error_mark_node)
+ return true;
+
+ if (TREE_CODE (t) == INIT_EXPR
+ && TREE_CODE (TREE_OPERAND (t, 1)) != TARGET_EXPR)
+ TREE_OPERAND (t, 1) = stabilize_expr (TREE_OPERAND (t, 1), initp);
+ else
+ {
+ if (TREE_CODE (t) == INIT_EXPR)
+ t = TREE_OPERAND (t, 1);
+ if (TREE_CODE (t) == TARGET_EXPR)
+ t = TARGET_EXPR_INITIAL (t);
+ if (TREE_CODE (t) == CONSTRUCTOR
+ && CONSTRUCTOR_ELTS (t) == NULL_TREE)
+ {
+ /* Default-initialization. */
+ *initp = NULL_TREE;
+ return true;
+ }
+
+ /* If the initializer is a COND_EXPR, we can't preevaluate
+ anything. */
+ if (TREE_CODE (t) == COND_EXPR)
+ return false;
+
+ stabilize_call (t, initp);
+ }
+
+ return true;
+}
+
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
/* Complain that some language-specific thing hanging off a tree
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 5544f2259d6..2bfd743e090 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1058,6 +1058,11 @@ comptypes (tree t1, tree t2, int strict)
case COMPLEX_TYPE:
return same_type_p (TREE_TYPE (t1), TREE_TYPE (t2));
+ case VECTOR_TYPE:
+ return TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2)
+ && same_type_p (TREE_TYPE (t1), TREE_TYPE (t2));
+ break;
+
default:
break;
}
@@ -1374,7 +1379,6 @@ decay_conversion (tree exp)
if (!cxx_mark_addressable (exp))
return error_mark_node;
adr = build_nop (ptrtype, build_address (exp));
- TREE_SIDE_EFFECTS (adr) = 0; /* Default would be, same as EXP. */
return adr;
}
/* This way is better for a COMPONENT_REF since it can
@@ -2155,8 +2159,7 @@ build_array_ref (tree array, tree idx)
break;
}
- if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE
- && TREE_CODE (array) != INDIRECT_REF)
+ if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
{
tree rval, type;
@@ -2358,6 +2361,7 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function)
e2 = fold (build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, idx));
e2 = build_indirect_ref (e2, NULL);
TREE_CONSTANT (e2) = 1;
+ TREE_INVARIANT (e2) = 1;
/* When using function descriptors, the address of the
vtable entry is treated as a function pointer. */
@@ -3431,15 +3435,10 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
build_type = result_type;
{
- tree result = build (resultcode, build_type, op0, op1);
- tree folded;
-
- folded = fold (result);
- if (folded == result)
- TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1);
+ tree result = fold (build (resultcode, build_type, op0, op1));
if (final_type != 0)
- return cp_convert (final_type, folded);
- return folded;
+ result = cp_convert (final_type, result);
+ return result;
}
}
@@ -3467,7 +3466,7 @@ cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
static tree
pointer_diff (tree op0, tree op1, tree ptrtype)
{
- tree result, folded;
+ tree result;
tree restype = ptrdiff_type_node;
tree target_type = TREE_TYPE (ptrtype);
@@ -3502,11 +3501,7 @@ pointer_diff (tree op0, tree op1, tree ptrtype)
/* Do the division. */
result = build (EXACT_DIV_EXPR, restype, op0, cp_convert (restype, op1));
-
- folded = fold (result);
- if (folded == result)
- TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1);
- return folded;
+ return fold (result);
}
/* Construct and perhaps optimize a tree representation
@@ -3629,8 +3624,6 @@ build_address (tree t)
return error_mark_node;
addr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
- if (staticp (t))
- TREE_CONSTANT (addr) = 1;
return addr;
}
@@ -3640,16 +3633,9 @@ build_address (tree t)
tree
build_nop (tree type, tree expr)
{
- tree nop;
-
if (type == error_mark_node || error_operand_p (expr))
return expr;
-
- nop = build1 (NOP_EXPR, type, expr);
- if (TREE_CONSTANT (expr))
- TREE_CONSTANT (nop) = 1;
-
- return nop;
+ return build1 (NOP_EXPR, type, expr);
}
/* C++: Must handle pointers to members.
@@ -3685,9 +3671,8 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
else
{
if (!noconvert)
- arg = default_conversion (arg);
+ arg = default_conversion (arg);
arg = build1 (NON_LVALUE_EXPR, TREE_TYPE (arg), arg);
- TREE_CONSTANT (arg) = TREE_CONSTANT (TREE_OPERAND (arg, 0));
}
break;
@@ -3869,7 +3854,7 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
compound = build (COMPOUND_EXPR, TREE_TYPE (arg), modify, value);
/* Eliminate warning about unused result of + or -. */
- TREE_NO_UNUSED_WARNING (compound) = 1;
+ TREE_NO_WARNING (compound) = 1;
return compound;
}
@@ -3911,10 +3896,8 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
if (TREE_CODE (argtype) == REFERENCE_TYPE)
{
- arg = build1
- (CONVERT_EXPR,
- build_pointer_type (TREE_TYPE (argtype)), arg);
- TREE_CONSTANT (arg) = TREE_CONSTANT (TREE_OPERAND (arg, 0));
+ tree type = build_pointer_type (TREE_TYPE (argtype));
+ arg = build1 (CONVERT_EXPR, type, arg);
return arg;
}
else if (pedantic && DECL_MAIN_P (arg))
@@ -3932,10 +3915,8 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
arg = TREE_OPERAND (arg, 0);
if (TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE)
{
- arg = build1
- (CONVERT_EXPR,
- build_pointer_type (TREE_TYPE (TREE_TYPE (arg))), arg);
- TREE_CONSTANT (arg) = TREE_CONSTANT (TREE_OPERAND (arg, 0));
+ tree type = build_pointer_type (TREE_TYPE (TREE_TYPE (arg)));
+ arg = build1 (CONVERT_EXPR, type, arg);
}
else if (lvalue_p (arg))
/* Don't let this be an lvalue. */
@@ -4165,7 +4146,7 @@ unary_complex_lvalue (enum tree_code code, tree arg)
{
tree real_result = build_unary_op (code, TREE_OPERAND (arg, 0), 0);
arg = build (COMPOUND_EXPR, TREE_TYPE (real_result), arg, real_result);
- TREE_NO_UNUSED_WARNING (arg) = 1;
+ TREE_NO_WARNING (arg) = 1;
return arg;
}
@@ -5030,7 +5011,9 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
return cond;
/* Make sure the code to compute the rhs comes out
before the split. */
- return build (COMPOUND_EXPR, TREE_TYPE (lhs), preeval, cond);
+ if (preeval)
+ cond = build (COMPOUND_EXPR, TREE_TYPE (lhs), preeval, cond);
+ return cond;
}
default:
@@ -5231,7 +5214,7 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
if (olhs)
{
result = build (COMPOUND_EXPR, olhstype, result, olhs);
- TREE_NO_UNUSED_WARNING (result) = 1;
+ TREE_NO_WARNING (result) = 1;
return result;
}
return convert_for_assignment (olhstype, result, "assignment",
@@ -5343,7 +5326,8 @@ build_ptrmemfunc1 (tree type, tree delta, tree pfn)
u = tree_cons (pfn_field, pfn,
build_tree_list (delta_field, delta));
u = build_constructor (type, u);
- TREE_CONSTANT (u) = TREE_CONSTANT (pfn) && TREE_CONSTANT (delta);
+ TREE_CONSTANT (u) = TREE_CONSTANT (pfn) & TREE_CONSTANT (delta);
+ TREE_INVARIANT (u) = TREE_INVARIANT (pfn) & TREE_INVARIANT (delta);
TREE_STATIC (u) = (TREE_CONSTANT (u)
&& (initializer_constant_valid_p (pfn, TREE_TYPE (pfn))
!= NULL_TREE)
@@ -5600,8 +5584,7 @@ convert_for_assignment (tree type, tree rhs,
coder = TREE_CODE (rhstype);
if (TREE_CODE (type) == VECTOR_TYPE && coder == VECTOR_TYPE
- && ((*targetm.vector_opaque_p) (type)
- || (*targetm.vector_opaque_p) (rhstype)))
+ && vector_types_convertible_p (type, rhstype))
return convert (type, rhs);
if (rhs == error_mark_node || rhstype == error_mark_node)
@@ -5994,9 +5977,7 @@ check_return_expr (tree retval)
returned expression uses the chosen variable somehow. And people expect
this restriction, anyway. (jason 2000-11-19)
- See finish_function, cxx_expand_function_start, and
- cp_copy_res_decl_for_inlining for other pieces of this
- optimization. */
+ See finish_function and finalize_nrv for the rest of this optimization. */
if (fn_returns_value_p && flag_elide_constructors)
{
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 0a0fdbc0311..2c6b843a7f0 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -488,8 +488,6 @@ digest_init (tree type, tree init, tree* tail)
enum tree_code code = TREE_CODE (type);
tree element = NULL_TREE;
tree old_tail_contents = NULL_TREE;
- /* Nonzero if INIT is a braced grouping. */
- int raw_constructor;
/* By default, assume we use one element from a list.
We correct this later in the sole case where it is not true. */
@@ -519,10 +517,7 @@ digest_init (tree type, tree init, tree* tail)
if (TREE_CODE (init) == NON_LVALUE_EXPR)
init = TREE_OPERAND (init, 0);
- raw_constructor = (TREE_CODE (init) == CONSTRUCTOR
- && TREE_HAS_CONSTRUCTOR (init));
-
- if (raw_constructor
+ if (BRACE_ENCLOSED_INITIALIZER_P (init)
&& CONSTRUCTOR_ELTS (init) != 0
&& TREE_CHAIN (CONSTRUCTOR_ELTS (init)) == 0)
{
@@ -594,7 +589,7 @@ digest_init (tree type, tree init, tree* tail)
|| code == BOOLEAN_TYPE || code == COMPLEX_TYPE
|| TYPE_PTR_TO_MEMBER_P (type))
{
- if (raw_constructor)
+ if (BRACE_ENCLOSED_INITIALIZER_P (init))
{
if (element == 0)
{
@@ -603,7 +598,7 @@ digest_init (tree type, tree init, tree* tail)
}
init = element;
}
- while (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init))
+ while (BRACE_ENCLOSED_INITIALIZER_P (init))
{
pedwarn ("braces around scalar initializer for `%T'", type);
init = CONSTRUCTOR_ELTS (init);
@@ -627,15 +622,16 @@ digest_init (tree type, tree init, tree* tail)
if (code == ARRAY_TYPE || code == VECTOR_TYPE || IS_AGGR_TYPE_CODE (code))
{
- if (raw_constructor && TYPE_NON_AGGREGATE_CLASS (type)
- && TREE_HAS_CONSTRUCTOR (init))
+ if (BRACE_ENCLOSED_INITIALIZER_P (init))
{
- error ("subobject of type `%T' must be initialized by constructor, not by `%E'",
- type, init);
- return error_mark_node;
+ if (TYPE_NON_AGGREGATE_CLASS (type))
+ {
+ error ("subobject of type `%T' must be initialized by constructor, not by `%E'",
+ type, init);
+ return error_mark_node;
+ }
+ return process_init_constructor (type, init, (tree *)0);
}
- else if (raw_constructor)
- return process_init_constructor (type, init, (tree *)0);
else if (can_convert_arg (type, TREE_TYPE (init), init)
|| TYPE_NON_AGGREGATE_CLASS (type))
/* These are never initialized from multiple constructor elements. */;
@@ -877,7 +873,7 @@ process_init_constructor (tree type, tree init, tree* elts)
/* Warn when some struct elements are implicitly initialized. */
if (extra_warnings
- && (!init || TREE_HAS_CONSTRUCTOR (init)))
+ && (!init || BRACE_ENCLOSED_INITIALIZER_P (init)))
warning ("missing initializer for member `%D'", field);
}
else
@@ -893,7 +889,7 @@ process_init_constructor (tree type, tree init, tree* elts)
/* Warn when some struct elements are implicitly initialized
to zero. */
if (extra_warnings
- && (!init || TREE_HAS_CONSTRUCTOR (init)))
+ && (!init || BRACE_ENCLOSED_INITIALIZER_P (init)))
warning ("missing initializer for member `%D'", field);
if (! zero_init_p (TREE_TYPE (field)))
@@ -1001,8 +997,13 @@ process_init_constructor (tree type, tree init, tree* elts)
complete_array_type (type, result, /*do_default=*/0);
if (init)
TREE_HAS_CONSTRUCTOR (result) = TREE_HAS_CONSTRUCTOR (init);
- if (allconstant) TREE_CONSTANT (result) = 1;
- if (allconstant && allsimple) TREE_STATIC (result) = 1;
+ if (allconstant)
+ {
+ TREE_CONSTANT (result) = 1;
+ TREE_INVARIANT (result) = 1;
+ if (allsimple)
+ TREE_STATIC (result) = 1;
+ }
return result;
}
diff --git a/gcc/cpperror.c b/gcc/cpperror.c
index d57238069d6..362c1c5f2e0 100644
--- a/gcc/cpperror.c
+++ b/gcc/cpperror.c
@@ -144,7 +144,7 @@ cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
if (pfile->state.in_directive)
src_loc = pfile->directive_line;
else
- src_loc = pfile->line;
+ src_loc = pfile->line_table->highest_line;
}
else
{
diff --git a/gcc/cppexp.c b/gcc/cppexp.c
index 6b47dd7b06c..22d34b69416 100644
--- a/gcc/cppexp.c
+++ b/gcc/cppexp.c
@@ -408,6 +408,7 @@ append_digit (cpp_num num, int digit, int base, size_t precision)
result.high = num.high << shift;
result.low = num.low << shift;
result.high |= num.low >> (PART_PRECISION - shift);
+ result.unsignedp = num.unsignedp;
if (base == 10)
{
@@ -428,6 +429,7 @@ append_digit (cpp_num num, int digit, int base, size_t precision)
result.low += add_low;
result.high += add_high;
+ result.overflow = overflow;
/* The above code catches overflow of a cpp_num type. This catches
overflow of the (possibly shorter) target precision. */
@@ -435,10 +437,8 @@ append_digit (cpp_num num, int digit, int base, size_t precision)
num.high = result.high;
result = num_trim (result, precision);
if (!num_eq (result, num))
- overflow = true;
+ result.overflow = true;
- result.unsignedp = num.unsignedp;
- result.overflow = overflow;
return result;
}
@@ -520,6 +520,9 @@ eval_token (cpp_reader *pfile, const cpp_token *token)
unsigned int temp;
int unsignedp = 0;
+ result.unsignedp = false;
+ result.overflow = false;
+
switch (token->type)
{
case CPP_NUMBER:
@@ -591,7 +594,6 @@ eval_token (cpp_reader *pfile, const cpp_token *token)
}
result.unsignedp = !!unsignedp;
- result.overflow = false;
return result;
}
@@ -1166,8 +1168,9 @@ static cpp_num
num_rshift (cpp_num num, size_t precision, size_t n)
{
cpp_num_part sign_mask;
+ bool x = num_positive (num, precision);
- if (num.unsignedp || num_positive (num, precision))
+ if (num.unsignedp || x)
sign_mask = 0;
else
sign_mask = ~(cpp_num_part) 0;
@@ -1332,12 +1335,11 @@ num_binary_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op)
result.high = lhs.high + rhs.high;
if (result.low < lhs.low)
result.high++;
+ result.unsignedp = lhs.unsignedp || rhs.unsignedp;
+ result.overflow = false;
result = num_trim (result, precision);
- result.unsignedp = lhs.unsignedp || rhs.unsignedp;
- if (result.unsignedp)
- result.overflow = false;
- else
+ if (!result.unsignedp)
{
bool lhsp = num_positive (lhs, precision);
result.overflow = (lhsp == num_positive (rhs, precision)
@@ -1384,7 +1386,8 @@ num_part_mul (cpp_num_part lhs, cpp_num_part rhs)
result.high += HIGH_PART (middle[0]);
result.high += HIGH_PART (middle[1]);
- result.unsignedp = 1;
+ result.unsignedp = true;
+ result.overflow = false;
return result;
}
@@ -1516,9 +1519,8 @@ num_div_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op)
if (op == CPP_DIV)
{
result.unsignedp = unsignedp;
- if (unsignedp)
- result.overflow = false;
- else
+ result.overflow = false;
+ if (!unsignedp)
{
if (negate)
result = num_negate (result, precision);
diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c
index d31f61b7aee..65db6db5d57 100644
--- a/gcc/cppfiles.c
+++ b/gcc/cppfiles.c
@@ -362,7 +362,7 @@ search_path_exhausted (cpp_reader *pfile, const char *header, _cpp_file *file)
if (func
&& file->dir == NULL)
{
- if ((file->path = func (pfile, header)) != NULL)
+ if ((file->path = func (pfile, header, &file->dir)) != NULL)
{
if (open_file (file))
return true;
@@ -382,7 +382,7 @@ _cpp_find_failed (_cpp_file *file)
/* Given a filename FNAME search for such a file in the include path
starting from START_DIR. If FNAME is the empty string it is
- interpreted as STDIN if START_DIR is PFILE->no_seach_path.
+ interpreted as STDIN if START_DIR is PFILE->no_search_path.
If the file is not found in the file cache fall back to the O/S and
add the result to our cache.
@@ -806,7 +806,7 @@ _cpp_stack_include (cpp_reader *pfile, const char *fname, int angle_brackets,
static void
open_file_failed (cpp_reader *pfile, _cpp_file *file)
{
- int sysp = pfile->line > 1 && pfile->buffer ? pfile->buffer->sysp : 0;
+ int sysp = pfile->line_table->highest_line > 1 && pfile->buffer ? pfile->buffer->sysp : 0;
bool print_dep = CPP_OPTION (pfile, deps.style) > !!sysp;
errno = file->err_no;
@@ -987,14 +987,15 @@ void
cpp_make_system_header (cpp_reader *pfile, int syshdr, int externc)
{
int flags = 0;
- const struct line_map *map = linemap_lookup (pfile->line_table, pfile->line);
+ const struct line_maps *line_table = pfile->line_table;
+ const struct line_map *map = &line_table->maps[line_table->used-1];
/* 1 = system header, 2 = system header to be treated as C. */
if (syshdr)
flags = 1 + (externc != 0);
pfile->buffer->sysp = flags;
_cpp_do_file_change (pfile, LC_RENAME, map->to_file,
- SOURCE_LINE (map, pfile->line), flags);
+ SOURCE_LINE (map, pfile->line_table->highest_line), flags);
}
/* Allow the client to change the current file. Used by the front end
@@ -1315,6 +1316,14 @@ cpp_get_path (struct _cpp_file *f)
return f->path;
}
+/* Get the directory associated with the _cpp_file F. */
+
+cpp_dir *
+cpp_get_dir (struct _cpp_file *f)
+{
+ return f->dir;
+}
+
/* Get the cpp_buffer currently associated with the cpp_reader
PFILE. */
@@ -1341,7 +1350,7 @@ cpp_get_prev (cpp_buffer *b)
return b->prev;
}
-/* This datastructure holds the list of header files that were seen
+/* This data structure holds the list of header files that were seen
while the PCH was being built. The 'entries' field is kept sorted
in memcmp() order; yes, this means that on little-endian systems,
it's sorted initially by the least-significant byte of 'size', but
@@ -1397,7 +1406,8 @@ pchf_adder (void **slot, void *data)
return 1;
d->entries[count].once_only = f->once_only;
- d->have_once_only |= f->once_only;
+ /* |= is avoided in the next line because of an HP C compiler bug */
+ d->have_once_only = d->have_once_only | f->once_only;
if (f->buffer_valid)
md5_buffer ((const char *)f->buffer,
f->st.st_size, d->entries[count].sum);
diff --git a/gcc/cpphash.h b/gcc/cpphash.h
index 4e86bf37d5b..1c5015173e0 100644
--- a/gcc/cpphash.h
+++ b/gcc/cpphash.h
@@ -65,10 +65,10 @@ typedef unsigned char uchar;
#define CPP_BUF_COL(BUF) CPP_BUF_COLUMN(BUF, (BUF)->cur)
#define CPP_INCREMENT_LINE(PFILE, COLS_HINT) do { \
- const struct line_map *map \
- = linemap_lookup (PFILE->line_table, PFILE->line); \
- unsigned int line = SOURCE_LINE (map, PFILE->line) + 1; \
- PFILE->line = linemap_line_start (PFILE->line_table, line, COLS_HINT); \
+ const struct line_maps *line_table = PFILE->line_table; \
+ const struct line_map *map = &line_table->maps[line_table->used-1]; \
+ unsigned int line = SOURCE_LINE (map, line_table->highest_line); \
+ linemap_line_start (PFILE->line_table, line + 1, COLS_HINT); \
} while (0)
/* Maximum nesting of cpp_buffers. We use a static limit, partly for
@@ -344,7 +344,6 @@ struct cpp_reader
/* Source line tracking. */
struct line_maps *line_table;
- fileline line;
/* The line of the '#' of the current directive. */
fileline directive_line;
@@ -466,10 +465,6 @@ struct cpp_reader
/* Used for buffer overlays by cpptrad.c. */
const uchar *saved_cur, *saved_rlimit, *saved_line_base;
- /* Used to save the original line number during traditional
- preprocessing. */
- unsigned int saved_line;
-
/* A saved list of the defined macros, for dependency checking
of precompiled headers. */
struct cpp_savedstate *savedstate;
diff --git a/gcc/cppinit.c b/gcc/cppinit.c
index a6da0b69b6f..55323b4ea9b 100644
--- a/gcc/cppinit.c
+++ b/gcc/cppinit.c
@@ -172,10 +172,8 @@ cpp_create_reader (enum c_lang lang, hash_table *table,
other entries are correct zero-initialized. */
pfile->no_search_path.name = (char *) "";
- /* Initialize the line map. Start at logical line 1, so we can use
- a line number of zero for special states. */
+ /* Initialize the line map. */
pfile->line_table = line_table;
- pfile->line = 1;
/* Initialize lexer state. */
pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
@@ -471,7 +469,7 @@ cpp_read_main_file (cpp_reader *pfile, const char *fname)
pfile->main_file
= _cpp_find_file (pfile, fname, &pfile->no_search_path, false);
if (_cpp_find_failed (pfile->main_file))
- return false;
+ return NULL;
_cpp_stack_file (pfile, pfile->main_file, false);
diff --git a/gcc/cpplex.c b/gcc/cpplex.c
index 9912aac559c..d03096cdc63 100644
--- a/gcc/cpplex.c
+++ b/gcc/cpplex.c
@@ -270,12 +270,12 @@ _cpp_process_line_notes (cpp_reader *pfile, int in_comment)
if (note->type == '\\' || note->type == ' ')
{
if (note->type == ' ' && !in_comment)
- cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line, col,
+ cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line_table->highest_line, col,
"backslash and newline separated by space");
if (buffer->next_line > buffer->rlimit)
{
- cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line, col,
+ cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line_table->highest_line, col,
"backslash-newline at end of file");
/* Prevent "no newline at end of file" warning. */
buffer->next_line = buffer->rlimit;
@@ -290,14 +290,14 @@ _cpp_process_line_notes (cpp_reader *pfile, int in_comment)
&& (!in_comment || warn_in_comment (pfile, note)))
{
if (CPP_OPTION (pfile, trigraphs))
- cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line, col,
+ cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line_table->highest_line, col,
"trigraph ??%c converted to %c",
note->type,
(int) _cpp_trigraph_map[note->type]);
else
{
cpp_error_with_line
- (pfile, CPP_DL_WARNING, pfile->line, col,
+ (pfile, CPP_DL_WARNING, pfile->line_table->highest_line, col,
"trigraph ??%c ignored, use -trigraphs to enable",
note->type);
}
@@ -343,7 +343,7 @@ _cpp_skip_block_comment (cpp_reader *pfile)
{
buffer->cur = cur;
cpp_error_with_line (pfile, CPP_DL_WARNING,
- pfile->line, CPP_BUF_COL (buffer),
+ pfile->line_table->highest_line, CPP_BUF_COL (buffer),
"\"/*\" within comment");
}
}
@@ -375,13 +375,13 @@ static int
skip_line_comment (cpp_reader *pfile)
{
cpp_buffer *buffer = pfile->buffer;
- unsigned int orig_line = pfile->line;
+ unsigned int orig_line = pfile->line_table->highest_line;
while (*buffer->cur != '\n')
buffer->cur++;
_cpp_process_line_notes (pfile, true);
- return orig_line != pfile->line;
+ return orig_line != pfile->line_table->highest_line;
}
/* Skips whitespace, saving the next non-whitespace character. */
@@ -400,7 +400,7 @@ skip_whitespace (cpp_reader *pfile, cppchar_t c)
else if (c == '\0')
saw_NUL = true;
else if (pfile->state.in_directive && CPP_PEDANTIC (pfile))
- cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line,
+ cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line_table->highest_line,
CPP_BUF_COL (buffer),
"%s in preprocessing directive",
c == '\f' ? "form feed" : "vertical tab");
@@ -777,7 +777,7 @@ _cpp_get_fresh_line (cpp_reader *pfile)
{
/* Only warn once. */
buffer->next_line = buffer->rlimit;
- cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line,
+ cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line_table->highest_line,
CPP_BUF_COLUMN (buffer, buffer->cur),
"no newline at end of file");
}
@@ -828,7 +828,7 @@ _cpp_lex_direct (cpp_reader *pfile)
if (!pfile->state.in_directive)
{
/* Tell the compiler the line number of the EOF token. */
- result->src_loc = pfile->line;
+ result->src_loc = pfile->line_table->highest_line;
result->flags = BOL;
}
return result;
@@ -845,19 +845,19 @@ _cpp_lex_direct (cpp_reader *pfile)
}
buffer = pfile->buffer;
update_tokens_line:
- result->src_loc = pfile->line;
+ result->src_loc = pfile->line_table->highest_line;
skipped_white:
if (buffer->cur >= buffer->notes[buffer->cur_note].pos
&& !pfile->overlaid_buffer)
{
_cpp_process_line_notes (pfile, false);
- result->src_loc = pfile->line;
+ result->src_loc = pfile->line_table->highest_line;
}
c = *buffer->cur++;
- result->src_loc = linemap_position_for_column (pfile->line_table,
- CPP_BUF_COLUMN (buffer, buffer->cur));
+ LINEMAP_POSITION_FOR_COLUMN (result->src_loc, pfile->line_table,
+ CPP_BUF_COLUMN (buffer, buffer->cur));
switch (c)
{
diff --git a/gcc/cpplib.c b/gcc/cpplib.c
index 80adfb88444..808dcdaa2b1 100644
--- a/gcc/cpplib.c
+++ b/gcc/cpplib.c
@@ -228,7 +228,7 @@ start_directive (cpp_reader *pfile)
pfile->state.save_comments = 0;
/* Some handlers need the position of the # for diagnostics. */
- pfile->directive_line = pfile->line;
+ pfile->directive_line = pfile->line_table->highest_line;
}
/* Called when leaving a directive, _Pragma or command-line directive. */
@@ -777,7 +777,8 @@ strtoul_for_line (const uchar *str, unsigned int len, long unsigned int *nump)
static void
do_line (cpp_reader *pfile)
{
- const struct line_map *map = linemap_lookup (pfile->line_table, pfile->line);
+ const struct line_maps *line_table = pfile->line_table;
+ const struct line_map *map = &line_table->maps[line_table->used - 1];
const cpp_token *token;
const char *new_file = map->to_file;
unsigned long new_lineno;
@@ -827,7 +828,8 @@ do_line (cpp_reader *pfile)
static void
do_linemarker (cpp_reader *pfile)
{
- const struct line_map *map = linemap_lookup (pfile->line_table, pfile->line);
+ const struct line_maps *line_table = pfile->line_table;
+ const struct line_map *map = &line_table->maps[line_table->used - 1];
const cpp_token *token;
const char *new_file = map->to_file;
unsigned long new_lineno;
@@ -907,10 +909,8 @@ _cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason,
{
const struct line_map *map = linemap_add (pfile->line_table, reason, sysp,
to_file, file_line);
- if (map == NULL)
- pfile->line = 0;
- else
- pfile->line = linemap_line_start (pfile->line_table, map->to_line, 127);
+ if (map != NULL)
+ linemap_line_start (pfile->line_table, map->to_line, 127);
if (pfile->cb.file_change)
pfile->cb.file_change (pfile, map);
diff --git a/gcc/cpplib.h b/gcc/cpplib.h
index 905ca5d5e0e..5ac0a19bec9 100644
--- a/gcc/cpplib.h
+++ b/gcc/cpplib.h
@@ -385,7 +385,7 @@ struct cpp_options
The return value is the malloced name of a header to try and open,
if any, or NULL otherwise. This callback is called only if the
header is otherwise unfound. */
-typedef const char *(*missing_header_cb)(cpp_reader *, const char *header);
+typedef const char *(*missing_header_cb)(cpp_reader *, const char *header, cpp_dir **);
/* Call backs to cpplib client. */
struct cpp_callbacks
@@ -744,6 +744,7 @@ extern void cpp_make_system_header (cpp_reader *, int, int);
extern bool cpp_push_include (cpp_reader *, const char *);
extern void cpp_change_file (cpp_reader *, enum lc_reason, const char *);
extern const char *cpp_get_path (struct _cpp_file *);
+extern cpp_dir *cpp_get_dir (struct _cpp_file *);
extern cpp_buffer *cpp_get_buffer (cpp_reader *);
extern struct _cpp_file *cpp_get_file (cpp_buffer *);
extern cpp_buffer *cpp_get_prev (cpp_buffer *);
diff --git a/gcc/cppmacro.c b/gcc/cppmacro.c
index 065c3972016..e3d0dc37b29 100644
--- a/gcc/cppmacro.c
+++ b/gcc/cppmacro.c
@@ -133,7 +133,7 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
unsigned int len;
const char *name;
uchar *buf;
- map = linemap_lookup (pfile->line_table, pfile->line);
+ map = linemap_lookup (pfile->line_table, pfile->line_table->highest_line);
if (node->value.builtin == BT_BASE_FILE)
while (! MAIN_FILE_P (map))
@@ -158,12 +158,12 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
break;
case BT_SPECLINE:
- map = linemap_lookup (pfile->line_table, pfile->line);
+ map = &pfile->line_table->maps[pfile->line_table->used-1];
/* If __LINE__ is embedded in a macro, it must expand to the
line of the macro's invocation, not its definition.
Otherwise things like assert() will not work properly. */
if (CPP_OPTION (pfile, traditional))
- number = pfile->line;
+ number = pfile->line_table->highest_line;
else
number = pfile->cur_token[-1].src_loc;
number = SOURCE_LINE (map, number);
diff --git a/gcc/cpppch.c b/gcc/cpppch.c
index 8cb5bcff87a..815235c6c40 100644
--- a/gcc/cpppch.c
+++ b/gcc/cpppch.c
@@ -618,7 +618,6 @@ cpp_read_state (cpp_reader *r, const char *name, FILE *f,
struct lexer_state old_state;
struct save_macro_item *d;
size_t i, mac_count;
- int saved_line = r->line;
/* Restore spec_nodes, which will be full of references to the old
hashtable entries and so will now be invalid. */
@@ -707,7 +706,6 @@ cpp_read_state (cpp_reader *r, const char *name, FILE *f,
}
r->state = old_state;
- r->line = saved_line;
free (defn);
defn = NULL;
diff --git a/gcc/cpptrad.c b/gcc/cpptrad.c
index f6dc99d3fec..e2b11cb4115 100644
--- a/gcc/cpptrad.c
+++ b/gcc/cpptrad.c
@@ -148,7 +148,7 @@ static const uchar *
copy_comment (cpp_reader *pfile, const uchar *cur, int in_define)
{
bool unterminated, copy = false;
- source_location src_loc = pfile->line;
+ source_location src_loc = pfile->line_table->highest_line;
cpp_buffer *buffer = pfile->buffer;
buffer->cur = cur;
@@ -271,7 +271,6 @@ _cpp_overlay_buffer (cpp_reader *pfile, const uchar *start, size_t len)
pfile->saved_cur = buffer->cur;
pfile->saved_rlimit = buffer->rlimit;
pfile->saved_line_base = buffer->next_line;
- pfile->saved_line = pfile->line;
buffer->need_line = false;
buffer->cur = start;
@@ -360,7 +359,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro)
CUR (pfile->context) = pfile->buffer->cur;
RLIMIT (pfile->context) = pfile->buffer->rlimit;
pfile->out.cur = pfile->out.base;
- pfile->out.first_line = pfile->line;
+ pfile->out.first_line = pfile->line_table->highest_line;
/* start_of_input_line is needed to make sure that directives really,
really start at the first character of the line. */
start_of_input_line = pfile->buffer->cur;
@@ -488,7 +487,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro)
{
maybe_start_funlike (pfile, node, out_start, &fmacro);
lex_state = ls_fun_open;
- fmacro.line = pfile->line;
+ fmacro.line = pfile->line_table->highest_line;
continue;
}
else if (!recursive_macro (pfile, node))
diff --git a/gcc/cse.c b/gcc/cse.c
index 0a7281ecc42..6d3c53f7635 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -593,7 +593,7 @@ struct cse_basic_block_data
/* Whether it should be taken or not. AROUND is the same as taken
except that it is used when the destination label is not preceded
by a BARRIER. */
- enum taken {TAKEN, NOT_TAKEN, AROUND} status;
+ enum taken {PATH_TAKEN, PATH_NOT_TAKEN, PATH_AROUND} status;
} *path;
};
@@ -3924,21 +3924,11 @@ fold_rtx (rtx x, rtx insn)
}
}
- new = simplify_relational_operation (code, mode,
- (mode_arg0 != VOIDmode
- ? mode_arg0
- : (GET_MODE (const_arg0
- ? const_arg0
- : folded_arg0)
- != VOIDmode)
- ? GET_MODE (const_arg0
- ? const_arg0
- : folded_arg0)
- : GET_MODE (const_arg1
- ? const_arg1
- : folded_arg1)),
- const_arg0 ? const_arg0 : folded_arg0,
- const_arg1 ? const_arg1 : folded_arg1);
+ {
+ rtx op0 = const_arg0 ? const_arg0 : folded_arg0;
+ rtx op1 = const_arg1 ? const_arg1 : folded_arg1;
+ new = simplify_relational_operation (code, mode, mode_arg0, op0, op1);
+ }
break;
case RTX_BIN_ARITH:
@@ -4163,17 +4153,6 @@ fold_rtx (rtx x, rtx insn)
const_arg2 ? const_arg2 : XEXP (x, 2));
break;
- case RTX_EXTRA:
- /* Eliminate CONSTANT_P_RTX if its constant. */
- if (code == CONSTANT_P_RTX)
- {
- if (const_arg0)
- return const1_rtx;
- if (optimize == 0 || !flag_gcse)
- return const0_rtx;
- }
- break;
-
default:
break;
}
@@ -4266,7 +4245,7 @@ gen_lowpart_if_possible (enum machine_mode mode, rtx x)
return 0;
}
-/* Given INSN, a jump insn, TAKEN indicates if we are following the "taken"
+/* Given INSN, a jump insn, PATH_TAKEN indicates if we are following the "taken"
branch. It will be zero if not.
In certain cases, this can cause us to add an equivalence. For example,
@@ -5654,8 +5633,6 @@ cse_insn (rtx insn, rtx libcall_insn)
else
INSN_CODE (insn) = -1;
- never_reached_warning (insn, NULL);
-
/* Do not bother deleting any unreachable code,
let jump/flow do that. */
@@ -6683,14 +6660,15 @@ cse_end_of_basic_block (rtx insn, struct cse_basic_block_data *data,
int i;
/* Update the previous branch path, if any. If the last branch was
- previously TAKEN, mark it NOT_TAKEN. If it was previously NOT_TAKEN,
+ previously PATH_TAKEN, mark it PATH_NOT_TAKEN.
+ If it was previously PATH_NOT_TAKEN,
shorten the path by one and look at the previous branch. We know that
at least one branch must have been taken if PATH_SIZE is nonzero. */
while (path_size > 0)
{
- if (data->path[path_size - 1].status != NOT_TAKEN)
+ if (data->path[path_size - 1].status != PATH_NOT_TAKEN)
{
- data->path[path_size - 1].status = NOT_TAKEN;
+ data->path[path_size - 1].status = PATH_NOT_TAKEN;
break;
}
else
@@ -6752,7 +6730,7 @@ cse_end_of_basic_block (rtx insn, struct cse_basic_block_data *data,
take it, do so. */
if (path_entry < path_size && data->path[path_entry].branch == p)
{
- if (data->path[path_entry].status != NOT_TAKEN)
+ if (data->path[path_entry].status != PATH_NOT_TAKEN)
p = JUMP_LABEL (p);
/* Point to next entry in path, if any. */
@@ -6806,7 +6784,7 @@ cse_end_of_basic_block (rtx insn, struct cse_basic_block_data *data,
break;
data->path[path_entry].branch = p;
- data->path[path_entry++].status = TAKEN;
+ data->path[path_entry++].status = PATH_TAKEN;
/* This branch now ends our path. It was possible that we
didn't see this branch the last time around (when the
@@ -6845,7 +6823,7 @@ cse_end_of_basic_block (rtx insn, struct cse_basic_block_data *data,
if (tmp == q)
{
data->path[path_entry].branch = p;
- data->path[path_entry++].status = AROUND;
+ data->path[path_entry++].status = PATH_AROUND;
path_size = path_entry;
@@ -6866,7 +6844,7 @@ cse_end_of_basic_block (rtx insn, struct cse_basic_block_data *data,
/* If all jumps in the path are not taken, set our path length to zero
so a rescan won't be done. */
for (i = path_size - 1; i >= 0; i--)
- if (data->path[i].status != NOT_TAKEN)
+ if (data->path[i].status != PATH_NOT_TAKEN)
break;
if (i == -1)
@@ -7082,9 +7060,9 @@ cse_basic_block (rtx from, rtx to, struct branch_path *next_branch,
if (next_branch->branch == insn)
{
enum taken status = next_branch++->status;
- if (status != NOT_TAKEN)
+ if (status != PATH_NOT_TAKEN)
{
- if (status == TAKEN)
+ if (status == PATH_TAKEN)
record_jump_equiv (insn, 1);
else
invalidate_skipped_block (NEXT_INSN (insn));
diff --git a/gcc/cselib.c b/gcc/cselib.c
index 0dfb1a6c118..9d738df6e8d 100644
--- a/gcc/cselib.c
+++ b/gcc/cselib.c
@@ -157,7 +157,6 @@ new_elt_loc_list (struct elt_loc_list *next, rtx loc)
el = pool_alloc (elt_loc_list_pool);
el->next = next;
el->loc = loc;
- el->canon_loc = NULL;
el->setting_insn = cselib_current_insn;
el->in_libcall = cselib_current_insn_in_libcall;
return el;
@@ -1081,7 +1080,6 @@ cselib_invalidate_mem (rtx mem_rtx)
while (*p)
{
rtx x = (*p)->loc;
- rtx canon_x = (*p)->canon_loc;
cselib_val *addr;
struct elt_list **mem_chain;
@@ -1092,8 +1090,6 @@ cselib_invalidate_mem (rtx mem_rtx)
p = &(*p)->next;
continue;
}
- if (!canon_x)
- canon_x = (*p)->canon_loc = canon_rtx (x);
if (num_mems < PARAM_VALUE (PARAM_MAX_CSELIB_MEMORY_LOCATIONS)
&& ! canon_true_dependence (mem_rtx, GET_MODE (mem_rtx), mem_addr,
x, cselib_rtx_varies_p))
diff --git a/gcc/cselib.h b/gcc/cselib.h
index 1efbaa7b224..b529060dcd6 100644
--- a/gcc/cselib.h
+++ b/gcc/cselib.h
@@ -49,7 +49,6 @@ struct elt_loc_list GTY(())
struct elt_loc_list *next;
/* An rtl expression that holds the value. */
rtx loc;
- rtx canon_loc;
/* The insn that made the equivalence. */
rtx setting_insn;
/* True when setting insn is inside libcall. */
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index a93946d2ec7..9e3ffb4ea8b 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -2560,8 +2560,7 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home)
then it means the object is variable-sized and address through
that register or stack slot. DBX has no way to represent this
so all we can do is output the variable as a pointer.
- If it's not a parameter, ignore it.
- (VAR_DECLs like this can be made by integrate.c.) */
+ If it's not a parameter, ignore it. */
{
if (GET_CODE (XEXP (home, 0)) == REG)
{
diff --git a/gcc/defaults.h b/gcc/defaults.h
index 697ed8eca0c..220559798c0 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -39,12 +39,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#ifndef TARGET_BELL
# define TARGET_BELL 007
# define TARGET_BS 010
-# define TARGET_TAB 011
-# define TARGET_NEWLINE 012
-# define TARGET_VT 013
-# define TARGET_FF 014
# define TARGET_CR 015
+# define TARGET_DIGIT0 060
# define TARGET_ESC 033
+# define TARGET_FF 014
+# define TARGET_NEWLINE 012
+# define TARGET_TAB 011
+# define TARGET_VT 013
#endif
/* Store in OUTPUT a string (made with alloca) containing an
@@ -620,7 +621,7 @@ You Lose! You must define PREFERRED_DEBUGGING_TYPE!
#endif
#ifndef HOT_TEXT_SECTION_NAME
-#define HOT_TEXT_SECTION_NAME "text.hot"
+#define HOT_TEXT_SECTION_NAME ".text.hot"
#endif
#ifndef NORMAL_TEXT_SECTION_NAME
@@ -628,7 +629,7 @@ You Lose! You must define PREFERRED_DEBUGGING_TYPE!
#endif
#ifndef UNLIKELY_EXECUTED_TEXT_SECTION_NAME
-#define UNLIKELY_EXECUTED_TEXT_SECTION_NAME "text.unlikely"
+#define UNLIKELY_EXECUTED_TEXT_SECTION_NAME ".text.unlikely"
#endif
#ifndef HAS_LONG_COND_BRANCH
@@ -742,6 +743,11 @@ You Lose! You must define PREFERRED_DEBUGGING_TYPE!
#define CASE_VECTOR_PC_RELATIVE 0
#endif
+/* Assume that trampolines need function alignment. */
+#ifndef TRAMPOLINE_ALIGNMENT
+#define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY
+#endif
+
/* Register mappings for target machines without register windows. */
#ifndef INCOMING_REGNO
#define INCOMING_REGNO(N) (N)
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index b495d6451c3..16afddc1b4b 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -67,6 +67,7 @@ diagnostic_context *global_dc = &global_diagnostic_context;
with preprocessed source if appropriate.\n\
See %s for instructions.\n"
+int flag_fatal_errors = 0;
/* Return a malloc'd string containing MSG formatted a la printf. The
caller is responsible for freeing the memory. */
@@ -264,6 +265,11 @@ diagnostic_action_after_output (diagnostic_context *context,
case DK_SORRY:
if (context->abort_on_error)
real_abort ();
+ if (flag_fatal_errors)
+ {
+ fnotice (stderr, "compilation terminated due to -Wfatal-errors.\n");
+ exit (FATAL_EXIT_CODE);
+ }
break;
case DK_ICE:
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index daf24279d5e..782f5028025 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -182,4 +182,16 @@ extern char *diagnostic_build_prefix (diagnostic_info *);
extern void verbatim (const char *, ...);
extern char *file_name_as_prefix (const char *);
+extern void debug_output_buffer (pretty_printer *);
+
+/* In tree-pretty-print.c */
+extern int dump_generic_node (pretty_printer *, tree, int, int, bool);
+extern void print_generic_stmt (FILE *, tree, int);
+extern void print_generic_stmt_indented (FILE *, tree, int, int);
+extern void print_generic_expr (FILE *, tree, int);
+extern void print_generic_decl (FILE *, tree, int);
+
+extern void debug_generic_expr (tree);
+extern void debug_generic_stmt (tree);
+extern void debug_c_tree (tree);
#endif /* ! GCC_DIAGNOSTIC_H */
diff --git a/gcc/doc/c-tree.texi b/gcc/doc/c-tree.texi
index 8cd059e3e5c..d99c568380d 100644
--- a/gcc/doc/c-tree.texi
+++ b/gcc/doc/c-tree.texi
@@ -438,7 +438,7 @@ suppose that there were a 24-bit integer type, but that alignment
requirements for the ABI required 32-bit alignment. Then,
@code{TYPE_SIZE} would be an @code{INTEGER_CST} for 32, while
@code{TYPE_PRECISION} would be 24.) The integer type is unsigned if
-@code{TREE_UNSIGNED} holds; otherwise, it is signed.
+@code{TYPE_UNSIGNED} holds; otherwise, it is signed.
The @code{TYPE_MIN_VALUE} is an @code{INTEGER_CST} for the smallest
integer that may be represented by this type. Similarly, the
@@ -457,7 +457,7 @@ Used to represent GCC built-in @code{__complex__} data types. The
@item ENUMERAL_TYPE
Used to represent an enumeration type. The @code{TYPE_PRECISION} gives
(as an @code{int}), the number of bits used to represent the type. If
-there are no negative enumeration constants, @code{TREE_UNSIGNED} will
+there are no negative enumeration constants, @code{TYPE_UNSIGNED} will
hold. The minimum and maximum enumeration constants may be obtained
with @code{TYPE_MIN_VALUE} and @code{TYPE_MAX_VALUE}, respectively; each
of these macros returns an @code{INTEGER_CST}.
@@ -856,13 +856,13 @@ entity.
@item TREE_TYPE
This macro returns the type of the entity declared.
-@item DECL_SOURCE_FILE
+@item TREE_FILENAME
This macro returns the name of the file in which the entity was
declared, as a @code{char*}. For an entity declared implicitly by the
compiler (like @code{__builtin_memcpy}), this will be the string
@code{"<internal>"}.
-@item DECL_SOURCE_LINE
+@item TREE_LINENO
This macro returns the line number at which the entity was declared, as
an @code{int}.
@@ -1298,8 +1298,6 @@ This predicate holds if the function an overloaded
@findex FOR_COND
@findex FOR_EXPR
@findex FOR_BODY
-@tindex FILE_STMT
-@findex FILE_STMT_FILENAME
@tindex GOTO_STMT
@findex GOTO_DESTINATION
@findex GOTO_FAKE_P
@@ -1343,24 +1341,13 @@ the outermost block of the function, but it may also be a
@subsubsection Statements
-There are tree nodes corresponding to all of the source-level statement
-constructs. These are enumerated here, together with a list of the
-various macros that can be used to obtain information about them. There
-are a few macros that can be used with all statements:
+There are tree nodes corresponding to all of the source-level
+statement constructs, used within the C and C++ frontends. These are
+enumerated here, together with a list of the various macros that can
+be used to obtain information about them. There are a few macros that
+can be used with all statements:
@ftable @code
-@item STMT_LINENO
-This macro returns the line number for the statement. If the statement
-spans multiple lines, this value will be the number of the first line on
-which the statement occurs. Although we mention @code{CASE_LABEL} below
-as if it were a statement, they do not allow the use of
-@code{STMT_LINENO}. There is no way to obtain the line number for a
-@code{CASE_LABEL}.
-
-Statements do not contain information about
-the file from which they came; that information is implicit in the
-@code{FUNCTION_DECL} from which the statements originate.
-
@item STMT_IS_FULL_EXPR_P
In C++, statements normally constitute ``full expressions''; temporaries
created during a statement are destroyed when the statement is complete.
@@ -1523,11 +1510,6 @@ address is never taken. (All such objects are interchangeable.) The
Used to represent an expression statement. Use @code{EXPR_STMT_EXPR} to
obtain the expression.
-@item FILE_STMT
-
-Used to record a change in filename within the body of a function.
-Use @code{FILE_STMT_FILENAME} to obtain the new filename.
-
@item FOR_STMT
Used to represent a @code{for} statement. The @code{FOR_INIT_STMT} is
@@ -2213,9 +2195,9 @@ the @code{STMT_EXPR} does not yield a value, it's type will be
@item BIND_EXPR
These nodes represent local blocks. The first operand is a list of
-temporary variables, connected via their @code{TREE_CHAIN} field. These
-will never require cleanups. The scope of these variables is just the
-body of the @code{BIND_EXPR}. The body of the @code{BIND_EXPR} is the
+variables, connected via their @code{TREE_CHAIN} field. These will
+never require cleanups. The scope of these variables is just the body
+of the @code{BIND_EXPR}. The body of the @code{BIND_EXPR} is the
second operand.
@item LOOP_EXPR
diff --git a/gcc/doc/cfg.texi b/gcc/doc/cfg.texi
new file mode 100644
index 00000000000..58a890cc262
--- /dev/null
+++ b/gcc/doc/cfg.texi
@@ -0,0 +1,614 @@
+@c -*-texinfo-*-
+@c Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
+@c This is part of the GCC manual.
+@c For copying conditions, see the file gcc.texi.
+
+@c ---------------------------------------------------------------------
+@c Control Flow Graph
+@c ---------------------------------------------------------------------
+
+@node Control Flow
+@chapter Control Flow Graph
+@cindex CFG, Control Flow Graph
+@findex basic-block.h
+
+A control flow graph (CFG) is a data structure built on top of the
+intermediate code representation (the RTL or @code{tree} instruction
+stream) abstracting the control flow behavior of a function that is
+being compiled. The CFG is a directed graph where the vertices
+represent basic blocks and edges represent possible transfer of
+control flow from one basic block to another. The data structures
+used to represent the control flow graph are defined in
+@file{basic-block.h}.
+
+@menu
+* Basic Blocks:: The definition and representation of basic blocks.
+* Edges:: Types of edges and their representation.
+* Profile information:: Representation of frequencies and probabilities.
+* Maintaining the CFG:: Keeping the control flow graph and up to date.
+* Liveness information:: Using and maintaining liveness information.
+@end menu
+
+
+@node Basic Blocks
+@section Basic Blocks
+
+@cindex basic block
+@findex basic_block
+A basic block is a straight-line sequence of code with only one entry
+point and only one exit. In GCC, basic blocks are represented using
+the @code{basic_block} data type.
+
+@findex next_bb, prev_bb, FOR_EACH_BB
+Two pointer members of the @code{basic_block} structure are the
+pointers @code{next_bb} and @code{prev_bb}. These are used to keep
+doubly linked chain of basic blocks in the same order as the
+underlying instruction stream. The chain of basic blocks is updated
+transparently by the provided API for manipulating the CFG. The macro
+@code{FOR_EACH_BB} can be used to visit all the basic blocks in
+lexicographical order. Dominator traversals are also possible using
+@code{walk_dominator_tree}.
+
+@findex BASIC_BLOCK
+The @code{BASIC_BLOCK} array contains all basic blocks in an
+unspecified order. Each @code{basic_block} structure has a field
+that holds a unique integer identifier @code{index} that is the
+index of the block in the @code{BASIC_BLOCK} array.
+The total number of basic blocks in the function is
+@code{n_basic_blocks}. Both the basic block indices and
+the total number of basic blocks may vary during the compilation
+process, as passes reorder, create, duplicate, and destroy basic
+blocks. The index for any block should never be greater than
+@code{last_basic_block}.
+
+@findex ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR
+Special basic blocks represent possible entry and exit points of a
+function. These blocks are called @code{ENTRY_BLOCK_PTR} and
+@code{EXIT_BLOCK_PTR}. These blocks do not contain any code, and are
+not elements of the @code{BASIC_BLOCK} array. Therefore they have
+been assigned unique, negative index numbers.
+
+Each @code{basic_block} also contains pointers to the first
+instruction (the @dfn{head}) and the last instruction (the @dfn{tail})
+or @dfn{end} of the instruction stream contained in a basic block. In
+fact, since the @code{basic_block} data type is used to represent
+blocks in both major intermediate representations of GCC (@code{tree}
+and RTL), there are pointers to the head and end of a basic block for
+both representations.
+
+@findex NOTE_INSN_BASIC_BLOCK, CODE_LABEL, notes
+For RTL, these pointers are @code{rtx head, end}. In the RTL function
+representation, the head pointer always points either to a
+@code{NOTE_INSN_BASIC_BLOCK} or to a @code{CODE_LABEL}, if present.
+In the RTL representation of a function, the instruction stream
+contains not only the ``real'' instructions, but also @dfn{notes}.
+Any function that moves or duplicates the basic blocks needs
+to take care of updating of these notes. Many of these notes expect
+that the instruction stream consists of linear regions, making such
+updates difficult. The @code{NOTE_INSN_BASIC_BLOCK} note is the only
+kind of note that may appear in the instruction stream contained in a
+basic block. The instruction stream of a basic block always follows a
+@code{NOTE_INSN_BASIC_BLOCK}, but zero or more @code{CODE_LABEL}
+nodes can precede the block note. A basic block ends by control flow
+instruction or last instruction before following @code{CODE_LABEL} or
+@code{NOTE_INSN_BASIC_BLOCK}. A @code{CODE_LABEL} cannot appear in
+the instruction stream of a basic block.
+
+@findex can_fallthru
+@cindex table jump
+In addition to notes, the jump table vectors are also represented as
+``pseudo-instructions'' inside the insn stream. These vectors never
+appear in the basic block and should always be placed just after the
+table jump instructions referencing them. After removing the
+table-jump it is often difficult to eliminate the code computing the
+address and referencing the vector, so cleaning up these vectors is
+postponed until after liveness analysis. Thus the jump table vectors
+may appear in the insn stream unreferenced and without any purpose.
+Before any edge is made @dfn{fall-thru}, the existence of such
+construct in the way needs to be checked by calling
+@code{can_fallthru} function.
+
+@cindex block statement iterators
+For the @code{tree} representation, the head and end of the basic block
+are being pointed to by the @code{stmt_list} field, but this special
+@code{tree} should never be referenced directly. Instead, at the tree
+level abstract containers and iterators are used to access statements
+and expressions in basic blocks. These iterators are called
+@dfn{block statement iterators} (BSIs). Grep for @code{^bsi}
+in the various @file{tree-*} files.
+The following snippet will pretty-print all the statements of the
+program in the GIMPLE representation.
+
+@example
+FOR_EACH_BB (bb)
+ @{
+ block_stmt_iterator si;
+
+ for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ @{
+ tree stmt = bsi_stmt (si);
+ print_generic_stmt (stderr, stmt, 0);
+ @}
+ @}
+@end example
+
+
+@node Edges
+@section Edges
+
+@cindex edge in the flow graph
+@findex edge
+Edges represent possible control flow transfers from the end of some
+basic block A to the head of another basic block B. We say that A is
+a predecessor of B, and B is a successor of A. Edges are represented
+in GCC with the @code{edge} data type. Each @code{edge} acts as a
+link between two basic blocks: the @code{src} member of an edge
+points to the predecessor basic block of the @code{dest} basic block.
+The members @code{pred} and @code{succ} of the @code{basic_block} data
+type point to single linked lists of edges to the predecessors and
+successorts of the block. The edges are linked via the
+@code{succ_next} and @code{pred_next} members of the @code{edge} data
+type.
+
+@findex fall-thru
+There are various reasons why control flow may transfer from one block
+to another. One possibility is that some instruction, for example a
+@code{CODE_LABEL}, in a linearized instruction stream just always
+starts a new basic block. In this case a @dfn{fall-thru} edge links
+the basic block to the first following basic block. But there are
+several other reasons why edges may be created. The @code{flags}
+field of the @code{edge} data type is used to store information
+about the type of edge we are dealing with. Each edge is of one of
+the following types:
+
+@table @emph
+@item jump
+No type flags are set for edges corresponding to jump instructions.
+These edges are used for unconditional or conditional jumps and in
+RTL also for table jumps. They are the easiest to manipulate as they
+may be freely redirected when the flow graph is not in SSA form.
+
+@item fall-thru
+@findex EDGE_FALLTHRU, force_nonfallthru
+Fall-thru edges are present in case where the basic block may continue
+execution to the following one without branching. These edges have
+the @code{EDGE_FALLTHRU} flag set. Unlike other types of edges, these
+edges must come into the basic block immediately following in the
+instruction stream. The function @code{force_nonfallthru} is
+available to insert an unconditional jump in the case that redirection
+is needed. Note that this may require creation of a new basic block.
+
+@item exception handling
+@cindex exception handling
+@findex EDGE_ABNORMAL, EDGE_EH
+Exception handling edges represent possible control transfers from a
+trapping instruction to an exception handler. The definition of
+``trapping'' varies. In C++, only function calls can throw, but for
+Java, exceptions like division by zero or segmentation fault are
+defined and thus each instruction possibly throwing this kind of
+exception needs to be handled as control flow instruction. Exception
+edges have the @code{EDGE_ABNORMAL} and @code{EDGE_EH} flags set.
+
+@findex purge_dead_edges
+When updating the instruction stream it is easy to change possibly
+trapping instruction to non-trapping, by simply removing the exception
+edge. The opposite conversion is difficult, but should not happen
+anyway. The edges can be eliminated via @code{purge_dead_edges} call.
+
+@findex REG_EH_REGION, EDGE_ABNORMAL_CALL
+In the RTL representation, the destination of an exception edge is
+specified by @code{REG_EH_REGION} note attached to the insn.
+In case of a trapping call the @code{EDGE_ABNORMAL_CALL} flag is set
+too. In the @code{tree} representation, this extra flag is not set.
+
+@findex may_trap_p, tree_could_trap_p
+In the RTL representation, the predicate @code{may_trap_p} may be used
+to check whether instruction still may trap or not. For the tree
+representation, the @code{tree_could_trap_p} predicate is available,
+but this predicate only checks for possible memory traps, as in
+dereferencing an invalid pointer location.
+
+
+@item sibling calls
+@cindex sibling call
+@findex EDGE_ABNORMAL, EDGE_SIBCALL
+Sibling calls or tail calls terminate the function in a non-standard
+way and thus an edge to the exit must be present.
+@code{EDGE_SIBCALL} and @code{EDGE_ABNORMAL} are set in such case.
+These edges only exist in the RTL representation.
+
+@item computed jumps
+@cindex computed jump
+@findex EDGE_ABNORMAL
+Computed jumps contain edges to all labels in the function referenced
+from the code. All those edges have @code{EDGE_ABNORMAL} flag set.
+The edges used to represent computed jumps often cause compile time
+performance problems, since functions consisting of many taken labels
+and many computed jumps may have @emph{very} dense flow graphs, so
+these edges need to be handled with special care. During the earlier
+stages of the compilation process, GCC tries to avoid such dense flow
+graphs by factoring computed jumps. For example, given the following
+series of jumps,
+
+@example
+ goto *x;
+ [ ... ]
+
+ goto *x;
+ [ ... ]
+
+ goto *x;
+ [ ... ]
+@end example
+
+@noindent
+factoring the computed jumps results in the following code sequence
+which has a much simpler flow graph:
+
+@example
+ goto y;
+ [ ... ]
+
+ goto y;
+ [ ... ]
+
+ goto y;
+ [ ... ]
+
+y:
+ goto *x;
+@end example
+
+However, the classic problem with this transformation is that it has a
+runtime cost in there resulting code: An extra jump. Therefore, the
+computed jumps are un-factored in the later passes of the compiler.
+Be aware of that when you work on passes in that area. There have
+been numerous examples already where the compile time for code with
+unfactored computed jumps caused some serious headaches.
+
+@item nonlocal goto handlers
+@cindex nonlocal goto handler
+@findex EDGE_ABNORMAL, EDGE_ABNORMAL_CALL
+GCC allows nested functions to return into caller using a @code{goto}
+to a label passed to as an argument to the callee. The labels passed
+to nested functions contain special code to cleanup after function
+call. Such sections of code are referred to as ``nonlocal goto
+receivers''. If a function contains such nonlocal goto receivers, an
+edge from the call to the label is created with the
+@code{EDGE_ABNORMAL} and @code{EDGE_ABNORMAL_CALL} flags set.
+
+@item function entry points
+@cindex function entry point, alternate function entry point
+@findex LABEL_ALTERNATE_NAME
+By definition, execution of function starts at basic block 0, so there
+is always an edge from the @code{ENTRY_BLOCK_PTR} to basic block 0.
+There is no @code{tree} representation for alternate entry points at
+this moment. In RTL, alternate entry points are specified by
+@code{CODE_LABEL} with @code{LABEL_ALTERNATE_NAME} defined. This
+feature is currently used for multiple entry point prologues and is
+limited to post-reload passes only. This can be used by back-ends to
+emit alternate prologues for functions called from different contexts.
+In future full support for multiple entry functions defined by Fortran
+90 needs to be implemented.
+
+@item function exits
+In the pre-reload representation a function terminates after the last
+instruction in the insn chain and no explicit return instructions are
+used. This corresponds to the fall-thru edge into exit block. After
+reload, optimal RTL epilogues are used that use explicit (conditional)
+return instructions that are represented by edges with no flags set.
+
+@end table
+
+
+@node Profile information
+@section Profile information
+
+@cindex profile representation
+In many cases a compiler must make a choice whether to trade speed in
+one part of code for speed in another, or to trade code size for code
+speed. In such cases it is useful to know information about how often
+some given block will be executed. That is the purpose for
+maintaining profile within the flow graph.
+GCC can handle profile information obtained through @dfn{profile
+feedback}, but it can also estimate branch probabilities based on
+statics and heuristics.
+
+@cindex profile feedback
+The feedback based profile is produced by compiling the program with
+instrumentation, executing it on a train run and reading the numbers
+of executions of basic blocks and edges back to the compiler while
+re-compiling the program to produce the final executable. This method
+provides very accurate information about where a program spends most
+of its time on the train run. Whether it matches the average run of
+course depends on the choice of train data set, but several studies
+have shown that the behavior of a program usually changes just
+marginally over different data sets.
+
+@cindex Static profile estimation
+@cindex branch prediction
+@findex predict.def
+When profile feedback is not available, the compiler may be asked to
+attempt to predict the behavior of each branch in the program using a
+set of heuristics (see @file{predict.def} for details) and compute
+estimated frequencies of each basic block by propagating the
+probabilities over the graph.
+
+@findex frequency, count, BB_FREQ_BASE
+Each @code{basic_block} contains two integer fields to represent
+profile information: @code{frequency} and @code{count}. The
+@code{frequency} is an estimation how often is basic block executed
+within a function. It is represented as an integer scaled in the
+range from 0 to @code{BB_FREQ_BASE}. The most frequently executed
+basic block in function is initially set to @code{BB_FREQ_BASE} and
+the rest of frequencies are scaled accordingly. During optimization,
+the frequency of the most frequent basic block can both decrease (for
+instance by loop unrolling) or grow (for instance by cross-jumping
+optimization), so scaling sometimes has to be performed multiple
+times.
+
+@findex gcov_type
+The @code{count} contains hard-counted numbers of execution measured
+during training runs and is nonzero only when profile feedback is
+available. This value is represented as the host's widest integer
+(typically a 64 bit integer) of the special type @code{gcov_type}.
+
+Most optimization passes can use only the frequency information of a
+basic block, but a few passes may want to know hard execution counts.
+The frequencies should always match the counts after scaling, however
+during updating of the profile information numerical error may
+accumulate into quite large errors.
+
+@findex REG_BR_PROB_BASE, EDGE_FREQUENCY
+Each edge also contains a branch probability field: an integer in the
+range from 0 to @code{REG_BR_PROB_BASE}. It represents probability of
+passing control from the end of the @code{src} basic block to the
+@code{dest} basic block, i.e. the probability that control will flow
+along this edge. The @code{EDGE_FREQUENCY} macro is available to
+compute how frequently a given edge is taken. There is a @code{count}
+field for each edge as well, representing same information as for a
+basic block.
+
+The basic block frequencies are not represented in the instruction
+stream, but in the RTL representation the edge frequencies are
+represented for conditional jumps (via the @code{REG_BR_PROB}
+macro) since they are used when instructions are output to the
+assembly file and the flow graph is no longer maintained.
+
+@cindex reverse probability
+The probability that control flow arrives via a given edge to its
+destination basic block is called @dfn{reverse probability} and is not
+directly represented, but it may be easily computed from frequencies
+of basic blocks.
+
+@findex redirect_edge_and_branch
+Updating profile information is a delicate task that can unfortunately
+not be easily integrated with the CFG manipulation API. Many of the
+functions and hooks to modify the CFG, such as
+@code{redirect_edge_and_branch}, do not have enough information to
+easily update the profile, so updating it is in the majority of cases
+left up to the caller. It is difficult to uncover bugs in the profile
+updating code, because they manifest themselves only by producing
+worse code, and checking profile consistency is not possible because
+of numeric error accumulation. Hence special attention needs to be
+given to this issue in each pass that modifies the CFG.
+
+@findex REG_BR_PROB_BASE, BB_FREQ_BASE, count
+It is important to point out that @code{REG_BR_PROB_BASE} and
+@code{BB_FREQ_BASE} are both set low enough to be possible to compute
+second power of any frequency or probability in the flow graph, it is
+not possible to even square the @code{count} field, as modern CPUs are
+fast enough to execute $2^32$ operations quickly.
+
+
+@node Maintaining the CFG
+@section Maintaining the CFG
+@findex cfghooks.h
+
+An important task of each compiler pass is to keep both the control
+flow graph and all profile information up-to-date. Reconstruction of
+the control flow graph after each pass is not an option, since it may be
+very expensive and lost profile information cannot be reconstructed at
+all.
+
+GCC has two major intermediate representations, and both use the
+@code{basic_block} and @code{edge} data types to represent control
+flow. Both representations share as much of the CFG maintenance code
+as possible. For each representation, a set of @dfn{hooks} is defined
+so that each representation can provide its own implementation of CFG
+manipulation routines when necessary. These hooks are defined in
+@file{cfghooks.h}. There are hooks for almost all common CFG
+manipulations, including block splitting and merging, edge redirection
+and creating and deleting basic blocks. These hooks should provide
+everything you need to maintain and manipulate the CFG in both the RTL
+and @code{tree} representation.
+
+At the moment, the basic block boundaries are maintained transparently
+when modifying instructions, so there rarely is a need to move them
+manually (such as in case someone wants to output instruction outside
+basic block explicitly).
+Often the CFG may be better viewed as integral part of instruction
+chain, than structure built on the top of it. However, in principle
+the control flow graph for the @code{tree} representation is
+@emph{not} an integral part of the representation, in that a function
+tree may be expanded without first building a flow graph for the
+@code{tree} representation at all. This happens when compiling
+without any @code{tree} optimization enabled. When the @code{tree}
+optimizations are enabled and the instruction stream is rewritten in
+SSA form, the CFG is very tightly coupled with the instruction stream.
+In particular, statement insertion and removal has to be done with
+care. In fact, the whole @code{tree} representation can not be easily
+used or maintained without proper maintenance of the CFG
+simultaneously.
+
+@findex BLOCK_FOR_INSN, bb_for_stmt
+In the RTL representation, each instruction has a
+@code{BLOCK_FOR_INSN} value that represents pointer to the basic block
+that contains the instruction. In the @code{tree} representation, the
+function @code{bb_for_stmt} returns a pointer to the basic block
+containing the queried statement.
+
+@cindex block statement iterators
+When changes need to be applied to a function in its @code{tree}
+representation, @dfn{block statement iterators} should be used. These
+iterators provide an integrated abstraction of the flow graph and the
+instruction stream. Block statement iterators iterators are
+constructed using the @code{block_stmt_iterator} data structure and
+several modifier are available, including the following:
+
+@table @code
+@item bsi_start
+@findex bsi_start
+This function initializes a @code{block_stmt_iterator} that points to
+the first non-empty statement in a basic block.
+
+@item bsi_last
+@findex bsi_last
+This function initializes a @code{block_stmt_iterator} that points to
+the last statement in a basic block.
+
+@item bsi_end_p
+@findex bsi_end_p
+This predicate is @code{true} if a @code{block_stmt_iterator}
+represents the end of a basic block.
+
+@item bsi_next
+@findex bsi_next
+This function takes a @code{block_stmt_iterator} and makes it point to
+its successor.
+
+@item bsi_prev
+@item bsi_prev
+This function takes a @code{block_stmt_iterator} and makes it point to
+its predecessor.
+
+@item bsi_insert_after
+@findex bsi_insert_after
+This function inserts a statement after the @code{block_stmt_iterator}
+passed in. The final parameter determines whether the statement
+iterator is updated to point to the newly inserted statement, or left
+pointing to the original statement.
+
+@item bsi_insert_before
+@findex bsi_insert_before
+This function inserts a statement before the @code{block_stmt_iterator}
+passed in. The final parameter determines whether the statement
+iterator is updated to point to the newly inserted statement, or left
+pointing to the original statement.
+
+@item bsi_remove
+This function removes the @code{block_stmt_iterator} passed in and
+rechains the remaining statements in a basic block, if any.
+
+@end table
+
+@findex BB_HEAD, BB_END
+In the RTL representation, the macros @code{BB_HEAD} and @code{BB_END}
+may be used to get the head and end @code{rtx} of a basic block. No
+abstract iterators are defined for traversing the insn chain, but you
+can just use @code{NEXT_INSN} and @code{PREV_INSN} instead. See
+@xref{Insns}.
+
+@findex purge_dead_edges
+Usually a code manipulating pass simplifies the instruction stream and
+the flow of control, possibly eliminating some edges. This may for
+example happen when a conditional jump is replaced with an
+unconditional jump, but also when simplifying possibly trapping
+instruction to non-trapping while compiling Java. Updating of edges
+is not transparent and each optimization pass is required to do so
+manually. However only few cases occur in practice. The pass may
+call @code{purge_dead_edges} on a given basic block to remove
+superfluous edges, if any.
+
+@findex redirect_edge_and_branch, redirect_jump
+Another common scenario is redirection of branch instructions, but
+this is best modeled as redirection of edges in the control flow graph
+and thus use of @code{redirect_edge_and_branch} is preferred over more
+low level functions, such as @code{redirect_jump} that operate on RTL
+chain only. The CFG hooks defined in @file{cfghooks.h} should provide
+the complete API required for manipulating and maintaining the CFG.
+
+@findex find_sub_basic_blocks, split_block
+It is also possible that a pass has to insert control flow instruction
+into the middle of a basic block, thus creating an entry point in the
+middle of the basic block, which is impossible by definition: The
+block must be split to make sure it only has one entry point, i.e. the
+head of the basic block. In the RTL representation, the
+@code{find_sub_basic_blocks} may be used to split existing basic block
+and add necessary edges. The CFG hook @code{split_block} may be used
+when an instruction in the middle of a basic block has to become the
+target of a jump or branch instruction.
+
+@findex insert_insn_on_edge, commit_edge_insertions
+@findex bsi_insert_on_edge, bsi_commit_edge_inserts
+@cindex edge splitting
+For a global optimizer, a common operation is to split edges in the
+flow graph and insert instructions on them. In the RTL
+representation, this can be easily done using the
+@code{insert_insn_on_edge} function that emits an instruction
+``on the edge'', caching it for a later @code{commit_edge_insertions}
+call that will take care of moving the inserted instructions off the
+edge into the instruction stream contained in a basic block. This
+includes the creation of new basic blocks where needed. In the
+@code{tree} representation, the equivalent functions are
+@code{bsi_insert_on_edge} which inserts a block statement
+iterator on an edge, and @code{bsi_commit_edge_inserts} which flushes
+the instruction to actual instruction stream.
+
+While debugging the optimization pass, an @code{verify_flow_info}
+function may be useful to find bugs in the control flow graph updating
+code.
+
+Note that at present, the representation of control flow in the
+@code{tree} representation is discarded before expanding to RTL.
+Long term the CFG should be maintained and ``expanded'' to the
+RTL representation along with the function @code{tree} itself.
+
+
+@node Liveness information
+@section Liveness information
+@cindex Liveness representation
+Liveness information is useful to determine whether some register is
+``live'' at given point of program, i.e. that it contains a value that
+may be used at a later point in the program. This information is
+used, for instance, during register allocation, as the pseudo
+registers only need to be assigned to a unique hard register or to a
+stack slot if they are live. The hard registers and stack slots may
+be freely reused for other values when a register is dead.
+
+@findex REG_DEAD, REG_UNUSED
+The liveness information is stored partly in the RTL instruction
+stream and partly in the flow graph. Local information is stored in
+the instruction stream:
+Each instruction may contain @code{REG_DEAD} notes representing that
+the value of a given register is no longer needed, or
+@code{REG_UNUSED} notes representing that the value computed by the
+instruction is never used. The second is useful for instructions
+computing multiple values at once.
+
+@findex global_live_at_start, global_live_at_end
+Global liveness information is stored in the control flow graph.
+Each basic block contains two bitmaps, @code{global_live_at_start} and
+@code{global_live_at_end} representing liveness of each register at
+the entry and exit of the basic block. The file @code{flow.c}
+contains functions to compute liveness of each register at any given
+place in the instruction stream using this information.
+
+@findex BB_DIRTY, clear_bb_flags, update_life_info_in_dirty_blocks
+Liveness is expensive to compute and thus it is desirable to keep it
+up to date during code modifying passes. This can be easily
+accomplished using the @code{flags} field of a basic block. Functions
+modifying the instruction stream automatically set the @code{BB_DIRTY}
+flag of a modifies basic block, so the pass may simply
+use@code{clear_bb_flags} before doing any modifications and then ask
+the data flow module to have liveness updated via the
+@code{update_life_info_in_dirty_blocks} function.
+
+This scheme works reliably as long as no control flow graph
+transformations are done. The task of updating liveness after control
+flow graph changes is more difficult as normal iterative data flow
+analysis may produce invalid results or get into an infinite cycle
+when the initial solution is not below the desired one. Only simple
+transformations, like splitting basic blocks or inserting on edges,
+are safe, as functions to implement them already know how to update
+liveness information locally.
diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi
index 5d1cb9b3029..399658256d6 100644
--- a/gcc/doc/cpp.texi
+++ b/gcc/doc/cpp.texi
@@ -759,9 +759,11 @@ named @var{file} in a standard list of system directories. You can prepend
directories to this list with the @option{-I} option (@pxref{Invocation}).
@item #include "@var{file}"
-This variant is used for header files of your own program. It searches
-for a file named @var{file} first in the directory containing the
-current file, then in the same directories used for @code{<@var{file}>}.
+This variant is used for header files of your own program. It
+searches for a file named @var{file} first in the directory containing
+the current file, then in the quote directories and then the same
+directories used for @code{<@var{file}>}. You can prepend directories
+to the list of quote directories with the @option{-iquote} option.
@end table
The argument of @samp{#include}, whether delimited with quote marks or
@@ -883,9 +885,10 @@ standard C library facilities, or the standard C library itself.
@option{-nostdinc} is in effect.
GCC looks for headers requested with @code{@w{#include "@var{file}"}}
-first in the directory containing the current file, then in the same
-places it would have looked for a header requested with angle brackets.
-For example, if @file{/usr/include/sys/stat.h} contains
+first in the directory containing the current file, then in the
+directories as specified by @option{-iquote} options, then in the same
+places it would have looked for a header requested with angle
+brackets. For example, if @file{/usr/include/sys/stat.h} contains
@code{@w{#include "types.h"}}, GCC looks for @file{types.h} first in
@file{/usr/include/sys}, then in its usual search path.
@@ -898,7 +901,8 @@ This has two effects. First, directories appearing before the
quote marks. Directories after @option{-I-} are searched for all
headers. Second, the directory containing the current file is not
searched for anything, unless it happens to be one of the directories
-named by an @option{-I} switch.
+named by an @option{-I} switch. @option{-I-} is deprecated, -iquote
+should be used instead.
@option{-I. -I-} is not the same as no @option{-I} options at all, and does
not cause the same behavior for @samp{<>} includes that @samp{""}
@@ -4039,6 +4043,11 @@ they generally represent bugs in the snapshots.
@itemize @bullet
+@item -I- deprecated
+
+This option has been deprecated in 3.5. @option{-iquote} is meant to
+replace the need for this option.
+
@item Order of evaluation of @samp{#} and @samp{##} operators
The standard does not specify the order of evaluation of a chain of
@@ -4131,7 +4140,8 @@ without notice.
@ignore
@c man begin SYNOPSIS
cpp [@option{-D}@var{macro}[=@var{defn}]@dots{}] [@option{-U}@var{macro}]
- [@option{-I}@var{dir}@dots{}] [@option{-W}@var{warn}@dots{}]
+ [@option{-I}@var{dir}@dots{}] [@option{-iquote}@var{dir}@dots{}]
+ [@option{-W}@var{warn}@dots{}]
[@option{-M}|@option{-MM}] [@option{-MG}] [@option{-MF} @var{filename}]
[@option{-MP}] [@option{-MQ} @var{target}@dots{}]
[@option{-MT} @var{target}@dots{}]
diff --git a/gcc/doc/cppopts.texi b/gcc/doc/cppopts.texi
index 686de1dd2ad..468f17f13fc 100644
--- a/gcc/doc/cppopts.texi
+++ b/gcc/doc/cppopts.texi
@@ -400,6 +400,7 @@ file directory as the first search directory for @code{@w{#include
@ifset cppmanual
@xref{Search Path}.
@end ifset
+This option has been deprecated.
@item -nostdinc
@opindex nostdinc
@@ -466,6 +467,16 @@ is applied to the standard system directories.
@xref{System Headers}.
@end ifset
+@item -iquote @var{dir}
+@opindex iquote
+Search @var{dir} only for header files requested with
+@code{@w{#include "@var{file}"}}; they are not searched for
+@code{@w{#include <@var{file}>}}, before all directories specified by
+@option{-I} and before the standard system directories.
+@ifset cppmanual
+@xref{Search Path}.
+@end ifset
+
@item -fdollars-in-identifiers
@opindex fdollars-in-identifiers
@anchor{fdollars-in-identifiers}
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index c5509a8073f..dbab25c6dfc 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -8226,6 +8226,11 @@ See also @xref{Strong Using}.
@node Strong Using
@section Strong Using
+@strong{Caution:} The semantics of this extension are not fully
+defined. Users should refrain from using this extension as its
+semantics may change subtly over time. It is possible that this
+extension wil be removed in future versions of G++.
+
A using-directive with @code{__attribute ((strong))} is stronger
than a normal using-directive in two ways:
diff --git a/gcc/doc/gccint.texi b/gcc/doc/gccint.texi
index 7ce5dde73c6..5dbe1f79f43 100644
--- a/gcc/doc/gccint.texi
+++ b/gcc/doc/gccint.texi
@@ -140,6 +140,8 @@ Additional tutorial information is linked to from
* Passes:: Order of passes, what they do, and what each file is for.
* Trees:: The source representation used by the C and C++ front ends.
* RTL:: The intermediate representation that most passes work on.
+* Control Flow:: Maintaining and manipulating the control flow graph.
+* Tree SSA:: Analysis and optimization of the tree representation.
* Machine Desc:: How to write machine description instruction patterns.
* Target Macros:: How to write the machine description C macros and functions.
* Host Config:: Writing the @file{xm-@var{machine}.h} file.
@@ -168,7 +170,9 @@ Additional tutorial information is linked to from
@include sourcebuild.texi
@include passes.texi
@include c-tree.texi
+@include tree-ssa.texi
@include rtl.texi
+@include cfg.texi
@include md.texi
@include tm.texi
@include hostconfig.texi
diff --git a/gcc/doc/gty.texi b/gcc/doc/gty.texi
index 05d9b9e6699..d43feca7221 100644
--- a/gcc/doc/gty.texi
+++ b/gcc/doc/gty.texi
@@ -231,7 +231,7 @@ typedef struct GTY(()) @{
@end smallexample
and then declare variables like this:
@smallexample
- htab_t GTY ((param_is (union tree_node))) ict;
+ static htab_t GTY ((param_is (union tree_node))) ict;
@end smallexample
@findex param@var{n}_is
diff --git a/gcc/doc/hostconfig.texi b/gcc/doc/hostconfig.texi
index e5387e148a7..c97b41b7c2e 100644
--- a/gcc/doc/hostconfig.texi
+++ b/gcc/doc/hostconfig.texi
@@ -147,6 +147,15 @@ unique to each dump file kind, e.g. @samp{rtl}.
If you do not define this macro, GCC will use @samp{.%02d.}. You should
define this macro if using the default will create an invalid file name.
+
+@item DELETE_IF_ORDINARY
+Define this macro to be a C statement (sans semicolon) that performs
+host-dependent removal of ordinary temp files in the compilation driver.
+
+If you do not define this macro, GCC will use the default version. You
+should define this macro if the default version does not reliably remove
+the temp file as, for example, on VMS which allows multiple versions
+of a file.
@end ftable
@node Host Misc
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 96ee1850566..599b9172c77 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -429,11 +429,11 @@ components.
Please refer to our @uref{http://gcc.gnu.org/releases.html,,releases web page}
for information on how to obtain GCC@.
-The full distribution includes the C, C++, Objective-C, Fortran, Java,
-and Ada (in case of GCC 3.1 and later) compilers. The full distribution
-also includes runtime libraries for C++, Objective-C, Fortran, and Java.
-In GCC 3.0 and later versions, GNU compiler testsuites are also included
-in the full distribution.
+The full distribution includes the C, C++, Objective-C, Fortran 77, Fortran
+(in case of GCC 3.5 and later), Java, and Ada (in case of GCC 3.1 and later)
+compilers. The full distribution also includes runtime libraries for C++,
+Objective-C, Fortran 77, Fortran, and Java. In GCC 3.0 and later versions,
+GNU compiler testsuites are also included in the full distribution.
If you choose to download specific components, you must download the core
GCC distribution plus any language specific distributions you wish to
@@ -1029,7 +1029,8 @@ their runtime libraries should be built. For a list of valid values for
grep language= */config-lang.in
@end smallexample
Currently, you can use any of the following:
-@code{ada}, @code{c}, @code{c++}, @code{f77}, @code{java}, @code{objc}.
+@code{ada}, @code{c}, @code{c++}, @code{f77}, @code{f95}, @code{java},
+@code{objc}.
Building the Ada compiler has special requirements, see below.@*
If you do not pass this flag, all languages available in the @file{gcc}
sub-tree will be configured. Re-defining @code{LANGUAGES} when calling
@@ -2951,7 +2952,7 @@ The native AIX tools do interoperate with GCC@.
Building @file{libstdc++.a} requires a fix for an AIX Assembler bug
APAR IY26685 (AIX 4.3) or APAR IY25528 (AIX 5.1). It also requires a
fix for another AIX Assembler bug and a co-dependent AIX Archiver fix
-referenced as APAR IY53606 (AIX 5.2) or a APAR TBD (AIX 5.1)
+referenced as APAR IY53606 (AIX 5.2) or a APAR IY54774 (AIX 5.1)
@samp{libstdc++} in GCC 3.4 increments the major version number of the
shared object and GCC installation places the @file{libstdc++.a}
@@ -3156,52 +3157,27 @@ if you use the GNU assembler and linker.
@end html
@heading @anchor{mips-sgi-irix5}mips-sgi-irix5
-This configuration has considerable problems, which will be fixed in a
-future release.
-
-In order to compile GCC on an SGI running IRIX 5, the ``compiler_dev.hdr''
-subsystem must be installed from the IDO CD-ROM supplied by Silicon
-Graphics. It is also available for download from
-@uref{http://www.sgi.com/developers/devtools/apis/ido.html,,http://www.sgi.com/developers/devtools/apis/ido.html}.
-
-@samp{make compare} may fail on version 5 of IRIX unless you add
-@option{-save-temps} to @code{CFLAGS}. On these systems, the name of the
-assembler input file is stored in the object file, and that makes
-comparison fail if it differs between the @code{stage1} and
-@code{stage2} compilations. The option @option{-save-temps} forces a
-fixed name to be used for the assembler input file, instead of a
-randomly chosen name in @file{/tmp}. Do not add @option{-save-temps}
-unless the comparisons fail without that option. If you do you
-@option{-save-temps}, you will have to manually delete the @samp{.i} and
-@samp{.s} files after each series of compilations.
+In order to compile GCC on an SGI running IRIX 5, the @samp{compiler_dev.hdr}
+subsystem must be installed from the IDO CD-ROM supplied by SGI@.
+It is also available for download from
+@uref{ftp://ftp.sgi.com/sgi/IRIX5.3/iris-development-option-5.3.tardist}.
If you use the MIPS C compiler to bootstrap, it may be necessary
to increase its table size for switch statements with the
@option{-Wf,-XNg1500} option. If you use the @option{-O2}
optimization option, you also need to use @option{-Olimit 3000}.
-To enable debugging under IRIX 5, you must use GNU @command{as} 2.11.2
-or later,
-and use the @option{--with-gnu-as} configure option when configuring GCC.
-GNU @command{as} is distributed as part of the binutils package.
-When using release 2.11.2, you need to apply a patch
-@uref{http://sources.redhat.com/ml/binutils/2001-07/msg00352.html,,http://sources.redhat.com/ml/binutils/2001-07/msg00352.html}
-which will be included in the next release of binutils.
-
-When building GCC, the build process loops rebuilding @command{cc1} over
-and over again. This happens on @samp{mips-sgi-irix5.2}, and possibly
-other platforms. It has been reported that this is a known bug in the
-@command{make} shipped with IRIX 5.2. We recommend you use GNU
-@command{make} instead of the vendor supplied @command{make} program;
-however, you may have success with @command{smake} on IRIX 5.2 if you do
-not have GNU @command{make} available.
+To enable debugging under IRIX 5, you must use GNU binutils 2.15 or
+later, and use the @option{--with-gnu-as} and @option{--with-gnu-ld}
+@command{configure} options when configuring GCC@. You need to use GNU
+@command{ar} and @command{nm}, also distributed with GNU binutils.
@html
<hr />
@end html
@heading @anchor{mips-sgi-irix6}mips-sgi-irix6
-If you are using IRIX @command{cc} as your bootstrap compiler, you must
+If you are using SGI's MIPSpro @command{cc} as your bootstrap compiler, you must
ensure that the N32 ABI is in use. To test this, compile a simple C
file with @command{cc} and then run @command{file} on the
resulting object file. The output should look like:
@@ -3224,15 +3200,20 @@ test.o: ELF 64-bit MSB @dots{}
then your version of @command{cc} uses the O32 or N64 ABI by default. You
should set the environment variable @env{CC} to @samp{cc -n32}
-before configuring GCC@.
+before configuring GCC@. SGI's MIPSpro 7.2 assembler may misassemble
+parts of the compiler, causing bootstrap failures. MIPSpro 7.3 is
+known to work. MIPSpro C 7.4 may cause bootstrap failures, too, due
+to a bug when inlining @code{memcmp}. Either add @code{-U__INLINE_INTRINSICS}
+to the @env{CC} environment variable as a workaround or upgrade to
+MIPSpro C 7.4.1m.
If you want the resulting @command{gcc} to run on old 32-bit systems
-with the MIPS R4400 CPU, you need to ensure that only code for the mips3
+with the MIPS R4400 CPU, you need to ensure that only code for the @samp{mips3}
instruction set architecture (ISA) is generated. While GCC 3.x does
this correctly, both GCC 2.95 and SGI's MIPSpro @command{cc} may change
the ISA depending on the machine where GCC is built. Using one of them
-as the bootstrap compiler may result in mips4 code, which won't run at
-all on mips3-only systems. For the test program above, you should see:
+as the bootstrap compiler may result in @samp{mips4} code, which won't run at
+all on @samp{mips3}-only systems. For the test program above, you should see:
@smallexample
test.o: ELF N32 MSB mips-3 @dots{}
@@ -3247,52 +3228,29 @@ test.o: ELF N32 MSB mips-4 @dots{}
instead, you should set the environment variable @env{CC} to @samp{cc
-n32 -mips3} or @samp{gcc -mips3} respectively before configuring GCC@.
-GCC on IRIX 6 is usually built to support both the N32 and N64 ABIs. If
-you build GCC on a system that doesn't have the N64 libraries installed,
+GCC on IRIX 6 is usually built to support the N32, O32 and N64 ABIs. If
+you build GCC on a system that doesn't have the N64 libraries installed
+or cannot run 64-bit binaries,
you need to configure with @option{--disable-multilib} so GCC doesn't
-try to use them. Look for @file{/usr/lib64/libc.so.1} to see if you
+try to use them. This will disable building the O32 libraries, too.
+Look for @file{/usr/lib64/libc.so.1} to see if you
have the 64-bit libraries installed.
-You must @emph{not} use GNU @command{as} (which isn't built anyway as of
-binutils 2.11.2) on IRIX 6 platforms; doing so will only cause problems.
-
-GCC does not currently support generating O32 ABI binaries in the
-@samp{mips-sgi-irix6} configurations. It is possible to create a GCC
-with O32 ABI only support by configuring it for the @samp{mips-sgi-irix5}
-target and using a patched GNU @command{as} 2.11.2 as documented in the
-@uref{#mips-sgi-irix5,,@samp{mips-sgi-irix5}} section above. Using the
-native assembler requires patches to GCC which will be included in a
-future release. It is
-expected that O32 ABI support will be available again in a future release.
+To enable debugging for the O32 ABI, you must use GNU @command{as} from
+GNU binutils 2.15 or later. You may also use GNU @command{ld}, but
+this is not required and currently causes some problems with Ada.
The @option{--enable-threads} option doesn't currently work, a patch is
in preparation for a future release. The @option{--enable-libgcj}
option is disabled by default: IRIX 6 uses a very low default limit
-(20480) for the command line length. Although libtool contains a
+(20480) for the command line length. Although @command{libtool} contains a
workaround for this problem, at least the N64 @samp{libgcj} is known not
to build despite this, running into an internal error of the native
@command{ld}. A sure fix is to increase this limit (@samp{ncargs}) to
its maximum of 262144 bytes. If you have root access, you can use the
@command{systune} command to do this.
-GCC does not correctly pass/return structures which are
-smaller than 16 bytes and which are not 8 bytes. The problem is very
-involved and difficult to fix. It affects a number of other targets also,
-but IRIX 6 is affected the most, because it is a 64-bit target, and 4 byte
-structures are common. The exact problem is that structures are being padded
-at the wrong end, e.g.@: a 4 byte structure is loaded into the lower 4 bytes
-of the register when it should be loaded into the upper 4 bytes of the
-register.
-
-GCC is consistent with itself, but not consistent with the SGI C compiler
-(and the SGI supplied runtime libraries), so the only failures that can
-happen are when there are library functions that take/return such
-structures. There are very few such library functions. Currently this
-is known to affect @code{inet_ntoa}, @code{inet_lnaof},
-@code{inet_netof}, @code{inet_makeaddr}, and @code{semctl}. Until the
-bug is fixed, GCC contains workarounds for the known affected functions.
-
-See @uref{http://freeware.sgi.com/,,http://freeware.sgi.com/} for more
+See @uref{http://freeware.sgi.com/} for more
information about using GCC on IRIX platforms.
@html
@@ -3502,6 +3460,13 @@ that supports only 32-bit binaries, one must configure with
@option{--disable-multilib}, since we will not be able to build the
64-bit target libraries.
+GCC 3.3 and GCC 3.4 trigger code generation bugs in earlier versions of
+the GNU compiler (especially GCC 3.0.x versions), which lead to the
+miscompilation of the stage1 compiler and the subsequent failure of the
+bootstrap process. A workaround is to use GCC 3.2.3 as an intermediary
+stage, i.e. to bootstrap that compiler with the base compiler and then
+use it to bootstrap the final compiler.
+
GCC 3.4 triggers a code generation bug in versions 5.4 (Sun ONE Studio 7)
and 5.5 (Sun ONE Studio 8) of the Sun compiler, which causes a bootstrap
failure in form of a miscompilation of the stage1 compiler by the Sun
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 83845f0ea40..3144fd1fcb4 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -214,7 +214,7 @@ in the following sections.
-Wconversion -Wno-deprecated-declarations @gol
-Wdisabled-optimization -Wno-div-by-zero -Wendif-labels @gol
-Werror -Werror-implicit-function-declaration @gol
--Wfloat-equal -Wformat -Wformat=2 @gol
+-Wfatal-errors -Wfloat-equal -Wformat -Wformat=2 @gol
-Wno-format-extra-args -Wformat-nonliteral @gol
-Wformat-security -Wformat-y2k @gol
-Wimplicit -Wimplicit-function-declaration -Wimplicit-int @gol
@@ -245,11 +245,24 @@ in the following sections.
@gccoptlist{-d@var{letters} -dumpspecs -dumpmachine -dumpversion @gol
-fdump-unnumbered -fdump-translation-unit@r{[}-@var{n}@r{]} @gol
-fdump-class-hierarchy@r{[}-@var{n}@r{]} @gol
+-fdump-tree-all @gol
-fdump-tree-original@r{[}-@var{n}@r{]} @gol
-fdump-tree-optimized@r{[}-@var{n}@r{]} @gol
-fdump-tree-inlined@r{[}-@var{n}@r{]} @gol
+-fdump-tree-cfg -fdump-tree-vcg -fdump-tree-alias @gol
+-fdump-tree-ch @gol
+-fdump-tree-ssa@r{[}-@var{n}@r{]} -fdump-tree-pre@r{[}-@var{n}@r{]} @gol
+-fdump-tree-ccp@r{[}-@var{n}@r{]} -fdump-tree-dce@r{[}-@var{n}@r{]} @gol
+-fdump-tree-gimple@r{[}-raw@r{]} -fdump-tree-mudflap@r{[}-@var{n}@r{]} @gol
+-fdump-tree-dom@r{[}-@var{n}@r{]} @gol
+-fdump-tree-dse@r{[}-@var{n}@r{]} @gol
+-fdump-tree-phiopt@r{[}-@var{n}@r{]} @gol
+-fdump-tree-forwprop@r{[}-@var{n}@r{]} @gol
+-fdump-tree-copyrename@r{[}-@var{n}@r{]} @gol
+-fdump-tree-nrv @gol
+-fdump-tree-sra@r{[}-@var{n}@r{]} @gol
-feliminate-dwarf2-dups -feliminate-unused-debug-types @gol
--feliminate-unused-debug-symbols -fmem-report -fprofile-arcs @gol
+-feliminate-unused-debug-symbols -fmem-report -fprofile-arcs -ftree-based-profiling @gol
-frandom-seed=@var{string} -fsched-verbose=@var{n} @gol
-ftest-coverage -ftime-report -fvar-tracking @gol
-g -g@var{level} -gcoff -gdwarf-2 @gol
@@ -263,6 +276,7 @@ in the following sections.
@xref{Optimize Options,,Options that Control Optimization}.
@gccoptlist{-falign-functions=@var{n} -falign-jumps=@var{n} @gol
-falign-labels=@var{n} -falign-loops=@var{n} @gol
+-fbounds-check -fmudflap -fmudflapth -fmudflapir @gol
-fbranch-probabilities -fprofile-values -fvpt -fbranch-target-load-optimize @gol
-fbranch-target-load-optimize2 -fbtr-bb-exclusive @gol
-fcaller-saves -fcprop-registers @gol
@@ -270,8 +284,8 @@ in the following sections.
-fdelayed-branch -fdelete-null-pointer-checks @gol
-fexpensive-optimizations -ffast-math -ffloat-store @gol
-fforce-addr -fforce-mem -ffunction-sections @gol
--fgcse -fgcse-lm -fgcse-sm -fgcse-las -floop-optimize @gol
--fcrossjumping -fif-conversion -fif-conversion2 @gol
+-fgcse -fgcse-lm -fgcse-sm -fgcse-las -fgcse-after-reload @gol
+-floop-optimize -fcrossjumping -fif-conversion -fif-conversion2 @gol
-finline-functions -finline-limit=@var{n} -fkeep-inline-functions @gol
-fkeep-static-consts -fmerge-constants -fmerge-all-constants @gol
-fmove-all-movables -fnew-ra -fno-branch-count-reg @gol
@@ -296,6 +310,9 @@ in the following sections.
-fstrength-reduce -fstrict-aliasing -ftracer -fthread-jumps @gol
-funroll-all-loops -funroll-loops -fpeel-loops @gol
-funswitch-loops -fold-unroll-loops -fold-unroll-all-loops @gol
+-ftree-pre -ftree-ccp -ftree-dce @gol
+-ftree-dominator-opts -ftree-dse -ftree-copyrename @gol
+-ftree-ch -ftree-sra -ftree-ter -ftree-lrs @gol
--param @var{name}=@var{value}
-O -O0 -O1 -O2 -O3 -Os}
@@ -328,7 +345,7 @@ in the following sections.
@item Directory Options
@xref{Directory Options,,Options for Directory Search}.
-@gccoptlist{-B@var{prefix} -I@var{dir} -I- -L@var{dir} -specs=@var{file}}
+@gccoptlist{-B@var{prefix} -I@var{dir} -iquote@var{dir} -L@var{dir} -specs=@var{file} -I-}
@item Target Options
@c I wrote this xref this way to avoid overfull hbox. -- rms
@@ -462,15 +479,15 @@ in the following sections.
-single_module -static -sub_library -sub_umbrella @gol
-twolevel_namespace -umbrella -undefined @gol
-unexported_symbols_list -weak_reference_mismatches @gol
--whatsloaded}
+-whatsloaded -F}
@emph{MIPS Options}
@gccoptlist{-EL -EB -march=@var{arch} -mtune=@var{arch} @gol
-mips1 -mips2 -mips3 -mips4 -mips32 -mips32r2 -mips64 @gol
-mips16 -mno-mips16 -mabi=@var{abi} -mabicalls -mno-abicalls @gol
--mxgot -mno-xgot -membedded-pic -mno-embedded-pic @gol
--mgp32 -mgp64 -mfp32 -mfp64 -mhard-float -msoft-float @gol
--msingle-float -mdouble-float -mint64 -mlong64 -mlong32 @gol
+-mxgot -mno-xgot -mgp32 -mgp64 -mfp32 -mfp64 @gol
+-mhard-float -msoft-float -msingle-float -mdouble-float @gol
+-mint64 -mlong64 -mlong32 @gol
-G@var{num} -membedded-data -mno-embedded-data @gol
-muninit-const-in-rodata -mno-uninit-const-in-rodata @gol
-msplit-addresses -mno-split-addresses @gol
@@ -480,9 +497,11 @@ in the following sections.
-mmemcpy -mno-memcpy -mlong-calls -mno-long-calls @gol
-mmad -mno-mad -mfused-madd -mno-fused-madd -nocpp @gol
-mfix-r4000 -mno-fix-r4000 -mfix-r4400 -mno-fix-r4400 @gol
--mfix-vr4122-bugs -mno-fix-vr4122-bugs -mfix-sb1 -mno-fix-sb1 @gol
+-mfix-vr4120 -mno-fix-vr4120 -mfix-sb1 -mno-fix-sb1 @gol
-mflush-func=@var{func} -mno-flush-func @gol
--mbranch-likely -mno-branch-likely}
+-mbranch-likely -mno-branch-likely @gol
+-mfp-exceptions -mno-fp-exceptions @gol
+-mvr4130-align -mno-vr4130-align}
@emph{i386 and x86-64 Options}
@gccoptlist{-mtune=@var{cpu-type} -march=@var{cpu-type} @gol
@@ -752,6 +771,10 @@ preprocessor).
Fortran source code which must be preprocessed with a RATFOR
preprocessor (not included with GCC)@.
+@item @var{file}.f90
+@itemx @var{file}.f95
+Fortran 90/95 source code which should not be preprocessed.
+
@xref{Overall Options,,Options Controlling the Kind of Output, g77,
Using and Porting GNU Fortran}, for more details of the handling of
Fortran input files.
@@ -805,6 +828,7 @@ objective-c objective-c-header objc-cpp-output
assembler assembler-with-cpp
ada
f77 f77-cpp-input ratfor
+f95
java
treelang
@end smallexample
@@ -868,10 +892,12 @@ Place output in file @var{file}. This applies regardless to whatever
sort of output is being produced, whether it be an executable file,
an object file, an assembler file or preprocessed C code.
-If @option{-o} is not specified, the default is to put an executable file
-in @file{a.out}, the object file for @file{@var{source}.@var{suffix}} in
-@file{@var{source}.o}, its assembler file in @file{@var{source}.s}, and
-all preprocessed C source on standard output.
+If @option{-o} is not specified, the default is to put an executable
+file in @file{a.out}, the object file for
+@file{@var{source}.@var{suffix}} in @file{@var{source}.o}, its
+assembler file in @file{@var{source}.s}, a precompiled header file in
+@file{@var{source}.@var{suffix}.gch}, and all preprocessed C source on
+standard output.
@item -v
@opindex v
@@ -1761,7 +1787,7 @@ for NeXT-based systems, including Darwin and Mac OS X@. The macro
used.
@item -fno-nil-receivers
-@opindex -fno-nil-receivers
+@opindex fno-nil-receivers
Assume that all Objective-C message dispatches (e.g.,
@code{[receiver message:arg]}) in this translation unit ensure that the receiver
is not @code{nil}. This allows for more efficient entry points in the runtime to be
@@ -1769,7 +1795,7 @@ used. Currently, this option is only available in conjunction with
the NeXT runtime on Mac OS X 10.3 and later.
@item -fobjc-exceptions
-@opindex -fobjc-exceptions
+@opindex fobjc-exceptions
Enable syntactic support for structured exception handling in Objective-C,
similar to what is offered by C++ and Java. Currently, this option is only
available in conjunction with the NeXT runtime on Mac OS X 10.3 and later.
@@ -1861,7 +1887,7 @@ Unlike Java, Objective-C does not allow for entire methods to be marked
to be unlocked properly.
@item -freplace-objc-classes
-@opindex -freplace-objc-classes
+@opindex freplace-objc-classes
Emit a special marker instructing @command{ld(1)} not to statically link in
the resulting object file, and allow @command{dyld(1)} to load it in at
run time instead. This is used in conjunction with the Fix-and-Continue
@@ -1872,7 +1898,7 @@ is only available in conjunction with the NeXT runtime on Mac OS X 10.3
and later.
@item -fzero-link
-@opindex -fzero-link
+@opindex fzero-link
When compiling for the NeXT runtime, the compiler ordinarily replaces calls
to @code{objc_getClass("@dots{}")} (when the name of the class is known at
compile time) with static class references that get initialized at load time,
@@ -1923,7 +1949,7 @@ compilation. This also enforces the coding style convention
that methods and selectors must be declared before being used.
@item -print-objc-runtime-info
-@opindex -print-objc-runtime-info
+@opindex print-objc-runtime-info
Generate C header describing the largest structure that is passed by
value, if any.
@@ -2062,6 +2088,12 @@ machines.
Warn whenever a comment-start sequence @samp{/*} appears in a @samp{/*}
comment, or whenever a Backslash-Newline appears in a @samp{//} comment.
+@item -Wfatal-errors
+@opindex Wfatal-errors
+This option causes the compiler to abort compilation on the first error
+occurred rather than trying to keep going and printing further error
+messages.
+
@item -Wformat
@opindex Wformat
Check calls to @code{printf} and @code{scanf}, etc., to make sure that
@@ -3204,6 +3236,17 @@ executed. When an arc is the only exit or only entrance to a block, the
instrumentation code can be added to the block; otherwise, a new basic
block must be created to hold the instrumentation code.
+@item -ftree-based-profiling
+@opindex ftree-based-profiling
+This option is used in addition to @option{-fprofile-arcs} or
+@option{-fbranch-probabilities} to control whether those optimizations
+are performed on a tree-based or rtl-based internal representation.
+If you use this option when compiling with @option{-fprofile-arcs},
+you must also use it when compiling later with @option{-fbranch-probabilities}.
+Currently the tree-based optimization is in an early stage of
+development, and this option is recommended only for those people
+working on improving it.
+
@need 2000
@item -ftest-coverage
@opindex ftest-coverage
@@ -3399,8 +3442,8 @@ to the source file name. If the @samp{-@var{options}} form is used,
@var{options} controls the details of the dump as described for the
@option{-fdump-tree} options.
-@item -fdump-tree-@var{switch} @r{(C++ only)}
-@itemx -fdump-tree-@var{switch}-@var{options} @r{(C++ only)}
+@item -fdump-tree-@var{switch} @r{(C and C++ only)}
+@itemx -fdump-tree-@var{switch}-@var{options} @r{(C and C++ only)}
@opindex fdump-tree
Control the dumping at various stages of processing the intermediate
language tree to a file. The file name is generated by appending a switch
@@ -3417,20 +3460,133 @@ changes according to the environment and source file. Its primary use
is for tying up a dump file with a debug environment.
@item slim
Inhibit dumping of members of a scope or body of a function merely
-because that scope has been reached. Only dump such items when they
-are directly reachable by some other path.
+because that scope has been reached. Only dump such items when they
+are directly reachable by some other path. When dumping pretty-printed
+trees, this option inhibits dumping the bodies of control structures.
+@item raw
+Print a raw representation of the tree. By default, trees are
+pretty-printed into a C-like representation.
+@item details
+Enable more detailed dumps (not honored by every dump option).
+@item stats
+Enable dumping various statistics about the pass (not honored by every dump
+option).
+@item blocks
+Enable showing basic block boundaries (disabled in raw dumps).
+@item vops
+Enable showing virtual operands for every statement.
+@item lineno
+Enable showing line numbers for statements.
+@item uid
+Enable showing the unique ID (@code{DECL_UID}) for each variable.
@item all
-Turn on all options.
+Turn on all options, except @option{raw}, @option{slim} and @option{lineno}.
@end table
The following tree dumps are possible:
@table @samp
+
@item original
Dump before any tree based optimization, to @file{@var{file}.original}.
+
@item optimized
Dump after all tree based optimization, to @file{@var{file}.optimized}.
+
@item inlined
Dump after function inlining, to @file{@var{file}.inlined}.
+
+@item gimple
+@opindex fdump-tree-gimple
+Dump each function before and after the gimplification pass to a file. The
+file name is made by appending @file{.gimple} to the source file name.
+
+@item cfg
+@opindex fdump-tree-cfg
+Dump the control flow graph of each function to a file. The file name is
+made by appending @file{.cfg} to the source file name.
+
+@item vcg
+@opindex fdump-tree-vcg
+Dump the control flow graph of each function to a file in VCG format. The
+file name is made by appending @file{.vcg} to the source file name. Note
+that if the file contains more than one function, the generated file cannot
+be used directly by VCG. You will need to cut and paste each function's
+graph into its own separate file first.
+
+@item ch
+@opindex fdump-tree-ch
+Dump each function after copying loop headers. The file name is made by
+appending @file{.ch} to the source file name.
+
+@item ssa
+@opindex fdump-tree-ssa
+Dump SSA related information to a file. The file name is made by appending
+@file{.ssa} to the source file name.
+
+@item alias
+@opindex fdump-tree-alias
+Dump aliasing information for each function. The file name is made by
+appending @file{.alias} to the source file name.
+
+@item ccp
+@opindex fdump-tree-ccp
+Dump each function after CCP. The file name is made by appending
+@file{.ccp} to the source file name.
+
+@item pre
+@opindex fdump-tree-pre
+Dump trees after partial redundancy elimination. The file name is made
+by appending @file{.pre} to the source file name.
+
+@item dce
+@opindex fdump-tree-dce
+Dump each function after dead code elimination. The file name is made by
+appending @file{.dce} to the source file name.
+
+@item mudflap
+@opindex fdump-tree-mudflap
+Dump each function after adding mudflap instrumentation. The file name is
+made by appending @file{.mudflap} to the source file name.
+
+@item sra
+@opindex fdump-tree-sra
+Dump each function after performing scalar replacement of aggregates. The
+file name is made by appending @file{.sra} to the source file name.
+
+@item dom
+@opindex fdump-tree-dom
+Dump each function after applying dominator tree optimizations. The file
+name is made by appending @file{.dom} to the source file name.
+
+@item dse
+@opindex fdump-tree-dse
+Dump each function after applying dead store elimination. The file
+name is made by appending @file{.dse} to the source file name.
+
+@item phiopt
+@opindex fdump-tree-phiopt
+Dump each function after optimizing PHI nodes into straightline code. The file
+name is made by appending @file{.phiopt} to the source file name.
+
+@item forwprop
+@opindex fdump-tree-forwprop
+Dump each function after forward propagating single use variables. The file
+name is made by appending @file{.forwprop} to the source file name.
+
+@item copyrename
+@opindex fdump-tree-copyrename
+Dump each function after applying the copy rename optimization. The file
+name is made by appending @file{.copyrename} to the source file name.
+
+@item nrv
+@opindex fdump-tree-nrv
+Dump each function after applying the named return value optimization on
+generic trees. The file name is made by appending @file{.nrv} to the source
+file name.
+
+@item all
+@opindex fdump-tree-all
+Enable all the available tree dumps with the flags provided in this option.
@end table
@item -frandom-seed=@var{string}
@@ -3593,10 +3749,11 @@ the performance and/or code size at the expense of compilation time
and possibly the ability to debug the program.
The compiler performs optimization based on the knowledge it has of
-the program. Using the @option{-funit-at-a-time} flag will allow the
-compiler to consider information gained from later functions in the
-file when compiling a function. Compiling multiple files at once to a
-single output file (and using @option{-funit-at-a-time}) will allow
+the program. Optimization levels @option{-O2} and above, in
+particular, enable @emph{unit-at-a-time} mode, which allows the
+compiler to consider information gained from later functions in
+the file when compiling a function. Compiling multiple files at
+once to a single output file in @emph{unit-at-a-time} mode allows
the compiler to use information gained from all of the files when
compiling each of them.
@@ -3666,7 +3823,8 @@ invoking @option{-O2} on programs that use computed gotos.
@opindex O3
Optimize yet more. @option{-O3} turns on all optimizations specified by
@option{-O2} and also turns on the @option{-finline-functions},
-@option{-fweb} and @option{-frename-registers} options.
+@option{-fweb}, @option{-frename-registers}
+and @option{-fgcse-after-reload} options.
@item -O0
@opindex O0
@@ -3888,6 +4046,39 @@ assumptions based on that.
The default is @option{-fzero-initialized-in-bss}.
+@item -fbounds-check
+@opindex fbounds-check
+For front-ends that support it, generate additional code to check that
+indices used to access arrays are within the declared range. This is
+currently only supported by the Java and Fortran front-ends, where
+this option defaults to true and false respectively.
+
+@item -fmudflap -fmudflapth -fmudflapir
+@opindex fmudflap
+@opindex fmudflapth
+@opindex fmudflapir
+@cindex bounds checking
+@cindex mudflap
+For front-ends that support it (C and C++), instrument all risky
+pointer/array dereferencing operations, some standard library
+string/heap functions, and some other associated constructs with
+range/validity tests. Modules so instrumented should be immune to
+buffer overflows, invalid heap use, and some other classes of C/C++
+programming errors. The instrumentation relies on a separate runtime
+library (@file{libmudflap}), which will be linked into a program if
+@option{-fmudflap} is given at link time. Run-time behavior of the
+instrumented program is controlled by the @env{MUDFLAP_OPTIONS}
+environment variable. See @code{env MUDFLAP_OPTIONS=-help a.out}
+for its options.
+
+Use @option{-fmudflapth} instead of @option{-fmudflap} to compile and to
+link if your program is multi-threaded. Use @option{-fmudflapir}, in
+addition to @option{-fmudflap} or @option{-fmudflapth}, if
+instrumentation should ignore pointer reads. This produces less
+instrumentation (and therefore faster execution) and still provides
+some protection against outright memory corrupting writes, but allows
+erroneously read data to propagate within a program.
+
@item -fstrength-reduce
@opindex fstrength-reduce
Perform the optimizations of loop strength reduction and
@@ -3977,6 +4168,12 @@ same memory location (both partial and full redundancies).
Enabled by default when gcse is enabled.
+@item -fgcse-after-reload
+@opindex fgcse-after-reload
+When @option{-fgcse-after-reload} is enabled, a redundant load elimination
+pass is performed after reload. The purpose of this pass is to cleanup
+redundant spilling.
+
@item -floop-optimize
@opindex floop-optimize
Perform loop optimizations: move constant expressions out of loops, simplify
@@ -4141,6 +4338,76 @@ those which have no call-preserved registers to use instead.
Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
+@item -ftree-pre
+Perform Partial Redundancy Elimination (PRE) on trees. This flag is
+enabled by default at -O and higher.
+
+@item -ftree-ccp
+Perform sparse conditional constant propagation (CCP) on trees. This flag
+is enabled by default at -O and higher.
+
+@item -ftree-dce
+Perform dead code elimination (DCE) on trees. This flag is enabled by
+default at -O and higher.
+
+@item -ftree-dominator-opts
+Perform dead code elimination (DCE) on trees. This flag is enabled by
+default at -O and higher.
+
+@item -ftree-ch
+Perform loop header copying on trees. This is beneficial since it increases
+effectivity of code motion optimizations. It also saves one jump. This flag
+is enabled by default at -O and higher. It is not enabled for -Os, since it
+usually increases code size.
+
+@item -ftree-sra
+Perform scalar replacement of aggregates. This pass replaces structure
+references with scalars to prevent committing structures to memory too
+early. This flag is enabled by default at -O and higher.
+
+@item -ftree-copyrename
+Perform copy renaming on trees. This pass attempts to rename compiler
+temporaries to other variables at copy locations, usually resulting in
+variable names which more closely resemble the original variables. This flag
+is enabled by default at -O and higher.
+
+@item -ftree-ter
+Perform temporary expression replacement during the SSA->normal phase. Single
+use/single def temporaries are replaced at their use location with their
+defining expression. This results in non-GIMPLE code, but gives the expanders
+much more complex trees to work on resulting in better RTL generation. This is
+enabled by default at -O and higher.
+
+@item -ftree-lrs
+Perform live range splitting during the SSA->normal phase. Distinct live
+ranges of a variable are split into unique variables, allowing for better
+optimization later. This is enabled by default at -O and higher.
+
+@item -ftracer
+@opindex ftracer
+Perform tail duplication to enlarge superblock size. This transformation
+simplifies the control flow of the function allowing other optimizations to do
+better job.
+
+@item -funroll-loops
+@opindex funroll-loops
+Unroll loops whose number of iterations can be determined at compile
+time or upon entry to the loop. @option{-funroll-loops} implies both
+@option{-fstrength-reduce} and @option{-frerun-cse-after-loop}. This
+option makes code larger, and may or may not make it run faster.
+
+@item -funroll-all-loops
+@opindex funroll-all-loops
+Unroll all loops, even if their number of iterations is uncertain when
+the loop is entered. This usually makes programs run more slowly.
+@option{-funroll-all-loops} implies the same options as
+@option{-funroll-loops},
+
+@item -fprefetch-loop-arrays
+@opindex fprefetch-loop-arrays
+If supported by the target machine, generate instructions to prefetch
+memory to improve the performance of loops that access large arrays.
+
@item -fmove-all-movables
@opindex fmove-all-movables
Forces all invariant computations in loops to be moved
@@ -4217,8 +4484,8 @@ paging and cache locality performance.
@opindex freorder-functions
Reorder basic blocks in the compiled function in order to reduce number of
taken branches and improve code locality. This is implemented by using special
-subsections @code{text.hot} for most frequently executed functions and
-@code{text.unlikely} for unlikely executed functions. Reordering is done by
+subsections @code{.text.hot} for most frequently executed functions and
+@code{.text.unlikely} for unlikely executed functions. Reordering is done by
the linker so object file format must support named sections and linker must
place them in a reasonable way.
@@ -4342,15 +4609,39 @@ If @var{n} is not specified or is zero, use a machine-dependent default.
Enabled at levels @option{-O2}, @option{-O3}.
-@item -frename-registers
-@opindex frename-registers
-Attempt to avoid false dependencies in scheduled code by making use
-of registers left over after register allocation. This optimization
-will most benefit processors with lots of registers. It can, however,
-make debugging impossible, since variables will no longer stay in
-a ``home register''.
+@item -funit-at-a-time
+@opindex funit-at-a-time
+Parse the whole compilation unit before starting to produce code.
+This allows some extra optimizations to take place but consumes
+more memory (in general). There are some compatibility issues
+with @emph{unit-at-at-time} mode:
+@itemize @bullet
+@item
+enabling @emph{unit-at-a-time} mode may change the order
+in which functions, variables, and top-level @code{asm} statements
+are emitted, and will likely break code relying on some particular
+ordering. The majority of such top-level @code{asm} statements,
+though, can be replaced by @code{section} attributes.
-Enabled at levels @option{-O3}.
+@item
+@emph{unit-at-a-time} mode removes unreferenced static variables
+and functions are removed. This may result in undefined references
+when an @code{asm} statement refers directly to variables or functions
+that are otherwise unused. In that case either the variable/function
+shall be listed as an operand of the @code{asm} statement operand or,
+in the case of top-level @code{asm} statements the attribute @code{used}
+shall be used on the declaration.
+
+@item
+Static functions now can use non-standard passing conventions that
+may break @code{asm} statements calling functions directly. Again,
+attribute @code{used} will prevent this behavior.
+@end itemize
+
+As a temporary workaround, @option{-fno-unit-at-a-time} can be used,
+but this scheme may not be supported by future releases of GCC.
+
+Enabled at levels @option{-O2}, @option{-O3}.
@item -fweb
@opindex fweb
@@ -4361,7 +4652,9 @@ passes, such as CSE, loop optimizer and trivial dead code remover. It can,
however, make debugging impossible, since variables will no longer stay in a
``home register''.
-Enabled at levels @option{-O3}.
+Enabled at levels @option{-O2}, @option{-O3}, @option{-Os},
+on targets where the default format for debugging information supports
+variable tracking.
@item -fno-cprop-registers
@opindex fno-cprop-registers
@@ -4373,10 +4666,13 @@ Disabled at levels @option{-O}, @option{-O2}, @option{-O3}, @option{-Os}.
@item -fprofile-generate
@opindex fprofile-generate
-Enable options usually used for instrumenting application to produce profile usefull
-for later recompilation profile feedback based optimization.
-The following options are enabled: @code{-fprofile-arcs}, @code{-fprofile-values}, @code{-fvpt}
+Enable options usually used for instrumenting application to produce
+profile useful for later recompilation with profile feedback based
+optimization. You must use @code{-fprofile-generate} both when
+compiling and when linking your program.
+
+The following options are enabled: @code{-fprofile-arcs}, @code{-fprofile-values}, @code{-fvpt}.
@item -fprofile-use
@opindex fprofile-use
@@ -4553,7 +4849,7 @@ With @option{-fbranch-probabilities}, it reads back the data gathered
from profiling values of expressions and adds @samp{REG_VALUE_PROFILE}
notes to instructions for their later usage in optimizations.
-Enabled with @option{-profile-generate} and @option{-profile-use}.
+Enabled with @option{-fprofile-generate} and @option{-fprofile-use}.
@item -fvpt
@opindex fvpt
@@ -4565,7 +4861,18 @@ and actually performs the optimizations based on them.
Currently the optimizations include specialization of division operation
using the knowledge about the value of the denominator.
-Enabled with @option{-profile-generate} and @option{-profile-use}.
+Enabled with @option{-fprofile-generate} and @option{-fprofile-use}.
+
+@item -frename-registers
+@opindex frename-registers
+Attempt to avoid false dependencies in scheduled code by making use
+of registers left over after register allocation. This optimization
+will most benefit processors with lots of registers. Depending on the
+debug information format adopted by the target, however, it can
+make debugging impossible, since variables will no longer stay in
+a ``home register''.
+
+Not enabled by default at any level because it has known bugs.
@item -fnew-ra
@opindex fnew-ra
@@ -4579,15 +4886,7 @@ Perform tail duplication to enlarge superblock size. This transformation
simplifies the control flow of the function allowing other optimizations to do
better job.
-Enabled with @option{-profile-use}.
-
-@item -funit-at-a-time
-@opindex funit-at-a-time
-Parse the whole compilation unit before starting to produce code.
-This allows some extra optimizations to take place but consumes more
-memory.
-
-Enabled at levels @option{-O2}, @option{-O3}.
+Enabled with @option{-fprofile-use}.
@item -funroll-loops
@opindex funroll-loops
@@ -4597,7 +4896,7 @@ upon entry to the loop. @option{-funroll-loops} implies
(i.e. complete removal of loops with small constant number of iterations).
This option makes code larger, and may or may not make it run faster.
-Enabled with @option{-profile-use}.
+Enabled with @option{-fprofile-use}.
@item -funroll-all-loops
@opindex funroll-all-loops
@@ -4612,7 +4911,7 @@ Peels the loops for that there is enough information that they do not
roll much (from profile feedback). It also turns on complete loop peeling
(i.e. complete removal of loops with small constant number of iterations).
-Enabled with @option{-profile-use}.
+Enabled with @option{-fprofile-use}.
@item -funswitch-loops
@opindex funswitch-loops
@@ -4770,6 +5069,27 @@ Specifies maximal overall growth of the compilation unit caused by inlining.
This parameter is ignored when @option{-funit-at-a-time} is not used.
The default value is 150.
+@item max-inline-insns-recursive
+@itemx max-inline-insns-recursive-auto
+Specifies maximum number of instructions out-of-line copy of self recursive inline
+function can grow into by performing recursive inlining.
+
+For functions declared inline @option{--param max-inline-insns-recursive} is
+taken into acount. For function not declared inline, recursive inlining
+happens only when @option{-finline-functions} (included in @option{-O3}) is
+enabled and @option{--param max-inline-insns-recursive-auto} is used. The
+default value is 500.
+
+@item max-inline-recursive-depth
+@itemx max-inline-recursive-depth-auto
+Specifies maximum recursion depth used by the recursive inlining.
+
+For functions declared inline @option{--param max-inline-recursive-depth} is
+taken into acount. For function not declared inline, recursive inlining
+happens only when @option{-finline-functions} (included in @option{-O3}) is
+enabled and @option{--param max-inline-recursive-depth-auto} is used. The
+default value is 500.
+
@item max-inline-insns-rtl
For languages that use the RTL inliner (this happens at a later stage
than tree inlining), you can set the maximum allowable size (counted
@@ -4854,6 +5174,22 @@ order to make tracer effective.
Maximum number of basic blocks on path that cse considers. The default is 10.
+@item global-var-threshold
+
+Counts the number of function calls (N) and the number of
+call-clobbered variables (V). If NxV is larger than this limit, a
+single artificial variable will be created to represent all the
+call-clobbered variables at function call sites. This artificial
+variable will then be made to alias every call-clobbered variable.
+(done as int * size_t on the host machine; beware overflow).
+
+@item max-aliased-vops
+
+Maxiumum number of virtual operands allowed to represent aliases
+before triggering the alias grouping heuristic. Alias grouping
+reduces compile times and memory consumption needed for aliasing at
+the expense of precision loss in alias information.
+
@item ggc-min-expand
GCC uses a garbage collector to manage its own memory allocation. This
@@ -5221,28 +5557,12 @@ the ordering for the include_next directive are not inadvertently changed.
If you really need to change the search order for system directories,
use the @option{-nostdinc} and/or @option{-isystem} options.
-@item -I-
-@opindex I-
-Any directories you specify with @option{-I} options before the @option{-I-}
-option are searched only for the case of @samp{#include "@var{file}"};
-they are not searched for @samp{#include <@var{file}>}.
-
-If additional directories are specified with @option{-I} options after
-the @option{-I-}, these directories are searched for all @samp{#include}
-directives. (Ordinarily @emph{all} @option{-I} directories are used
-this way.)
-
-In addition, the @option{-I-} option inhibits the use of the current
-directory (where the current input file came from) as the first search
-directory for @samp{#include "@var{file}"}. There is no way to
-override this effect of @option{-I-}. With @option{-I.} you can specify
-searching the directory which was current when the compiler was
-invoked. That is not exactly the same as what the preprocessor does
-by default, but it is often satisfactory.
-
-@option{-I-} does not inhibit the use of the standard system directories
-for header files. Thus, @option{-I-} and @option{-nostdinc} are
-independent.
+@item -iquote@var{dir}
+@opindex iquote
+Add the directory @var{dir} to the head of the list of directories to
+be searched for header files only for the case of @samp{#include
+"@var{file}"}; they are not searched for @samp{#include <@var{file}>},
+otherwise just like @option{-I}.
@item -L@var{dir}
@opindex L
@@ -5300,6 +5620,31 @@ program uses when determining what switches to pass to @file{cc1},
@file{cc1plus}, @file{as}, @file{ld}, etc. More than one
@option{-specs=@var{file}} can be specified on the command line, and they
are processed in order, from left to right.
+
+@item -I-
+@opindex I-
+This option has been deprecated. Please use @option{-iquote} instead for
+@option{-I} directories before the @option{-I-} and remove the @option{-I-}.
+Any directories you specify with @option{-I} options before the @option{-I-}
+option are searched only for the case of @samp{#include "@var{file}"};
+they are not searched for @samp{#include <@var{file}>}.
+
+If additional directories are specified with @option{-I} options after
+the @option{-I-}, these directories are searched for all @samp{#include}
+directives. (Ordinarily @emph{all} @option{-I} directories are used
+this way.)
+
+In addition, the @option{-I-} option inhibits the use of the current
+directory (where the current input file came from) as the first search
+directory for @samp{#include "@var{file}"}. There is no way to
+override this effect of @option{-I-}. With @option{-I.} you can specify
+searching the directory which was current when the compiler was
+invoked. That is not exactly the same as what the preprocessor does
+by default, but it is often satisfactory.
+
+@option{-I-} does not inhibit the use of the standard system directories
+for header files. Thus, @option{-I-} and @option{-nostdinc} are
+independent.
@end table
@c man end
@@ -5633,13 +5978,6 @@ the last object files that will be passed to the linker.
Process the @code{cpp} spec. This is used to construct the arguments
to be passed to the C preprocessor.
-@item %c
-Process the @code{signed_char} spec. This is intended to be used
-to tell cpp whether a char is signed. It typically has the definition:
-@smallexample
-%@{funsigned-char:-D__CHAR_UNSIGNED__@}
-@end smallexample
-
@item %1
Process the @code{cc1} spec. This is used to construct the options to be
passed to the actual C compiler (@samp{cc1}).
@@ -6357,8 +6695,8 @@ that select a particular cpu implementation. Those are @samp{cypress},
@item -mv8plus
@itemx -mno-v8plus
-@opindex -mv8plus
-@opindex -mno-v8plus
+@opindex mv8plus
+@opindex mno-v8plus
With @option{-mv8plus}, GCC generates code for the SPARC-V8+ ABI. The
difference from the V8 ABI is that the global and out registers are
considered 64-bit wide. This is enabled by default on Solaris in 32-bit
@@ -6366,8 +6704,8 @@ mode for all SPARC-V9 processors.
@item -mvis
@itemx -mno-vis
-@opindex -mvis
-@opindex -mno-vis
+@opindex mvis
+@opindex mno-vis
With @option{-mvis}, GCC generates code that takes advantage of the UltraSPARC
Visual Instruction Set extensions. The default is @option{-mno-vis}.
@end table
@@ -6911,7 +7249,7 @@ doesn't the linker will give an error message---incorrect code will not be
generated.
@item -mdebug
-@opindex -mdebug
+@opindex mdebug
Makes the M32R specific code in the compiler display some statistics
that might help in debugging programs.
@@ -7612,6 +7950,34 @@ These options are defined for all architectures running the Darwin operating
system. They are useful for compatibility with other Mac OS compilers.
@table @gcctabopt
+@item -F@var{dir}
+@opindex F
+Add the framework directory @var{dir} to the head of the list of
+directories to be searched for header files. These directories are
+interleaved with those specified by @option{-I} options and are
+scanned in a left-to-right order.
+
+A framework directory is a directory with frameworks in it. A
+framework is a directory with a @samp{"Headers"} and/or
+@samp{"PrivateHeaders"} directory contained directly in it that ends
+in @samp{".framework"}. The name of a framework is the name of this
+directory excluding the @samp{".framework"}. Headers associated with
+the framework are found in one of those two directories, with
+@samp{"Headers"} being searched first. A subframework is a framework
+directory that is in a framework's @samp{"Frameworks"} directory.
+Includes of subframework headers can only appear in a header of a
+framework that contains the subframework, or in a sibling subframework
+header. Two subframeworks are siblings if they occur in the same
+framework. A subframework should not have the same name as a
+framework, a warning will be issued if this is violated. Currently a
+subframework cannot have subframeworks, in the future, the mechanism
+may be extended to support this. The standard frameworks can be found
+in @samp{"/System/Library/Frameworks"}, @samp{"/Library/Frameworks"}
+and @samp{"/Local/Library/Frameworks"}. An example include looks like
+@code{#include <Framework/header.h>}, where @samp{Framework} denotes
+the name of the framework and header.h is found in the
+@samp{"PrivateHeaders"} or @samp{"Headers"} directory.
+
@item -all_load
@opindex all_load
Loads all members of static archive libraries.
@@ -7917,16 +8283,6 @@ file accesses more than 64k's worth of GOT entries. Very few do.
These options have no effect unless GCC is generating position
independent code.
-@item -membedded-pic
-@itemx -mno-embedded-pic
-@opindex membedded-pic
-@opindex mno-embedded-pic
-Generate (do not generate) position-independent code suitable for some
-embedded systems. All calls are made using PC relative addresses, and
-all data is addressed using the $gp register. No more than 65536
-bytes of global data may be used. This requires GNU as and GNU ld,
-which do most of the work.
-
@item -mgp32
@opindex mgp32
Assume that general-purpose registers are 32 bits wide.
@@ -8125,10 +8481,10 @@ A double-word or a variable shift may give an incorrect result if executed
immediately after starting an integer division.
@end itemize
-@item -mfix-vr4122-bugs
-@itemx -mno-fix-vr4122-bugs
-@opindex mfix-vr4122-bugs
-Work around certain VR4122 errata:
+@item -mfix-vr4120
+@itemx -mno-fix-vr4120
+@opindex mfix-vr4120
+Work around certain VR4120 errata:
@itemize @minus
@item
@code{dmultu} does not always produce the correct result.
@@ -8140,7 +8496,7 @@ The workarounds for the division errata rely on special functions in
@file{libgcc.a}. At present, these functions are only provided by
the @code{mips64vr*-elf} configurations.
-Other VR4122 errata require a nop to be inserted between certain pairs of
+Other VR4120 errata require a nop to be inserted between certain pairs of
instructions. These errata are handled by the assembler, not by GCC itself.
@item -mfix-sb1
@@ -8172,6 +8528,29 @@ architecture. An exception is for the MIPS32 and MIPS64 architectures
and processors which implement those architectures; for those, Branch
Likely instructions will not be generated by default because the MIPS32
and MIPS64 architectures specifically deprecate their use.
+
+@item -mfp-exceptions
+@itemx -mno-fp-exceptions
+@opindex mfp-exceptions
+Specifies whether FP exceptions are enabled. This affects how we schedule
+FP instructions for some processors. The default is that FP exceptions are
+enabled.
+
+For instance, on the SB-1, if FP exceptions are disabled, and we are emitting
+64-bit code, then we can use both FP pipes. Otherwise, we can only use one
+FP pipe.
+
+@item -mvr4130-align
+@itemx -mno-vr4130-align
+@opindex mvr4130-align
+The VR4130 pipeline is two-way superscalar, but can only issue two
+instructions together if the first one is 8-byte aligned. When this
+option is enabled, GCC will align pairs of instructions that it
+thinks should execute in parallel.
+
+This option only has an effect when optimizing for the VR4130.
+It normally makes code faster, but at the expense of making it bigger.
+It is enabled by default at optimization level @option{-O3}.
@end table
@node i386 and x86-64 Options
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 5cff95bd2c2..6b9135f733e 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -1363,6 +1363,9 @@ A symbol in the text segment of the current file
@item Uv
A memory reference suitable for VFP load/store insns (reg+constant offset)
+@item Uy
+A memory reference suitable for iWMMXt load/store instructions.
+
@item Uq
A memory reference suitable for for the ARMv4 ldrsb instruction.
@@ -2477,7 +2480,7 @@ specify field index and operand 0 place to store value into.
@cindex @code{vec_init@var{m}} instruction pattern
@item @samp{vec_init@var{m}}
-Initialize the vector to given values. Operand 0 ise the vector to initialize
+Initialize the vector to given values. Operand 0 is the vector to initialize
and operand 1 is parallel containing values for individual fields.
@cindex @code{push@var{m}} instruction pattern
diff --git a/gcc/doc/passes.texi b/gcc/doc/passes.texi
index 5962c5378d5..b5a69d88633 100644
--- a/gcc/doc/passes.texi
+++ b/gcc/doc/passes.texi
@@ -1,3 +1,5 @@
+@c markers: CROSSREF BUG TODO
+
@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
@c 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@@ -9,131 +11,441 @@
@cindex files and passes of the compiler
@cindex compiler passes and files
-@cindex top level of compiler
-The overall control structure of the compiler is in @file{toplev.c}. This
-file is responsible for initialization, decoding arguments, opening and
-closing files, and sequencing the passes. Routines for emitting
-diagnostic messages are defined in @file{diagnostic.c}. The files
-@file{pretty-print.h} and @file{pretty-print.c} provide basic support
-for language-independent pretty-printing.
-
-@cindex parsing pass
-The parsing pass is invoked only once, to parse the entire input. A
-high level tree representation is then generated from the input,
-one function at a time. This tree code is then transformed into RTL
-intermediate code, and processed. The files involved in transforming
-the trees into RTL are @file{expr.c}, @file{expmed.c}, and
-@file{stmt.c}.
-@c Note, the above files aren't strictly the only files involved. It's
-@c all over the place (function.c, final.c,etc). However, those are
-@c the files that are supposed to be directly involved, and have
-@c their purpose listed as such, so i've only listed them.
-The order of trees that are processed, is not
-necessarily the same order they are generated from
-the input, due to deferred inlining, and other considerations.
-
-@findex rest_of_compilation
+This chapter is dedicated to giving an overview of the optimization and
+code generation passes of the compiler. In the process, it describes
+some of the language front end interface, though this description is no
+where near complete.
+
+@menu
+* Parsing pass:: The language front end turns text into bits.
+* Gimplification pass:: The bits are turned into something we can optimize.
+* Pass manager:: Sequencing the optimization passes.
+* Tree-SSA passes:: Optimizations on a high-level representation.
+* RTL passes:: Optimizations on a low-level representation.
+@end menu
+
+@node Parsing pass
+@section Parsing pass
+@cindex GENERIC
+@findex lang_hooks.parse_file
+The language front end is invoked only once, via
+@code{lang_hooks.parse_file}, to parse the entire input. The language
+front end may use any intermediate language representation deemed
+appropriate. The C front end uses GENERIC trees (CROSSREF), plus
+a double handful of language specific tree codes defined in
+@file{c-common.def}. The Fortran front end uses a completely different
+private representation.
+
+@cindex GIMPLE
+@cindex gimplification
+@cindex gimplifier
+@cindex language-independent intermediate representation
+@cindex intermediate representation lowering
+@cindex lowering, language-dependent intermediate representation
+At some point the front end must translate the representation used in the
+front end to a representation understood by the language-independent
+portions of the compiler. Current practice takes one of two forms.
+The C front end manually invokes the gimplifier (CROSSREF) on each function,
+and uses the gimplifier callbacks to convert the language-specific tree
+nodes directly to GIMPLE (CROSSREF) before passing the function off to
+be compiled.
+The Fortran front end converts from a private representation to GENERIC,
+which is later lowered to GIMPLE when the function is compiled. Which
+route to choose probably depends on how well GENERIC (plus extensions)
+can be made to match up with the source language and necessary parsing
+data structures.
+
+BUG: Gimplification must occur before nested function lowering,
+and nested function lowering must be done by the front end before
+passing the data off to cgraph.
+
+TODO: Cgraph should control nested function lowering. It would
+only be invoked when it is certain that the outer-most function
+is used.
+
+TODO: Cgraph needs a gimplify_function callback. It should be
+invoked when (1) it is certain that the function is used, (2)
+warning flags specified by the user require some amount of
+compilation in order to honor, (3) the language indicates that
+semantic analysis is not complete until gimplification occurs.
+Hum... this sounds overly complicated. Perhaps we should just
+have the front end gimplify always; in most cases it's only one
+function call.
+
+The front end needs to pass all function definitions and top level
+declarations off to the middle-end so that they can be compiled and
+emitted to the object file. For a simple procedural language, it is
+usually most convenient to do this as each top level declaration or
+definition is seen. There is also a distinction to be made between
+generating functional code and generating complete debug information.
+The only thing that is absolutely required for functional code is that
+function and data @emph{defintions} be passed to the middle-end. For
+complete debug information, function, data and type declarations
+should all be passed as well.
+
@findex rest_of_decl_compilation
-Each time the parsing pass reads a complete function definition or
-top-level declaration, it calls either the function
-@code{rest_of_compilation}, or the function
-@code{rest_of_decl_compilation} in @file{toplev.c}, which are
-responsible for all further processing necessary, ending with output of
-the assembler language. All other compiler passes run, in sequence,
-within @code{rest_of_compilation}. When that function returns from
-compiling a function definition, the storage used for that function
-definition's compilation is entirely freed, unless it is an inline
-function, or was deferred for some reason (this can occur in
-templates, for example).
-(@pxref{Inline,,An Inline Function is As Fast As a Macro,gcc,Using the
-GNU Compiler Collection (GCC)}).
-
-Here is a list of all the passes of the compiler and their source files.
-Also included is a description of where debugging dumps can be requested
-with @option{-d} options.
+@findex rest_of_type_compilation
+@findex cgraph_finalize_function
+In any case, the front end needs each complete top-level function or
+data declaration, and each data definition should be passed to
+@code{rest_of_decl_compilation}. Each complete type definition should
+be passed to @code{rest_of_type_compilation}. Each function definition
+should be passed to @code{cgraph_finalize_function}.
+
+TODO: I know rest_of_compilation currently has all sorts of
+rtl-generation semantics. I plan to move all code generation
+bits (both tree and rtl) to compile_function. Should we hide
+cgraph from the front ends and move back to rest_of_compilation
+as the official interface? Possibly we should rename all three
+interfaces such that the names match in some meaningful way and
+that is more descriptive than "rest_of".
+
+The middle-end will, at its option, emit the function and data
+definitions immediately or queue them for later processing.
+
+@node Gimplification pass
+@section Gimplification pass
+
+@cindex gimplification
+@cindex GIMPLE
+@dfn{Gimplification} is a whimsical term for the process of converting
+the intermediate representation of a function into the GIMPLE language
+(CROSSREF). The term stuck, and so words like ``gimplification,''
+``gimplify,'' ``gimplifier'' and the like are sprinkled throughout this
+section of code.
+
+@cindex GENERIC
+While a front end may certainly choose to generate GIMPLE directly if
+it chooses, this can be a moderately complex process unless the
+intermediate language used by the front end is already fairly simple.
+Usually it is easier to generate GENERIC trees plus extensions
+and let the language-independent gimplifier do most of the work.
+
+@findex gimplify_function_tree
+@findex gimplify_expr
+@findex lang_hooks.gimplify_expr
+The main entry point to this pass is @code{gimplify_function_tree}
+located in @file{gimplify.c}. From here we process the entire
+function gimplifying each statement in turn. The main workhorse
+for this pass is @code{gimplify_expr}. Approximately everything
+passes through here at least once, and it is from here that we
+invoke the @code{lang_hooks.gimplify_expr} callback.
+
+The callback should examine the expression in question and return
+@code{GS_UNHANDLED} if the expression is not a language specific
+construct that requires attention. Otherwise it should alter the
+expression in some way to such that forward progress is made toward
+producing valid GIMPLE. If the callback is certain that the
+transformation is complete and the expression is valid GIMPLE, it
+should return @code{GS_ALL_DONE}. Otherwise it should return
+@code{GS_OK}, which will cause the expression to be processed again.
+If the callback encounters an error during the transformation (because
+the front end is relying on the gimplification process to finish
+semantic checks), it should return @code{GS_ERROR}.
+
+@node Pass manager
+@section Pass manager
+
+The pass manager is located in @file{passes.c} and @file{passes.h}.
+Its job is to run all of the individual passes in the correct order,
+and take care of standard bookkeeping that applies to every pass.
+
+The theory of operation is that each pass defines a structure that
+represents everything we need to know about that pass --- when it
+should be run, how it should be run, what intermediate language
+form or on-the-side data structures it needs. We register the pass
+to be run in some particular order, and the pass manager arranges
+for everything to happen in the correct order.
+
+The actuality doesn't completely live up to the theory at present.
+Command-line switches and @code{timevar_id_t} enumerations must still
+be defined elsewhere. The pass manager validates constraints but does
+not attempt to (re-)generate data structures or lower intermediate
+language form based on the requirements of the next pass. Nevertheless,
+what is present is useful, and a far sight better than nothing at all.
+
+TODO: describe the global variables set up by the pass manager,
+and a brief description of how a new pass should use it.
+I need to look at what info rtl passes use first...
+
+@node Tree-SSA passes
+@section Tree-SSA passes
+
+The following briefly describes the tree optimization passes that are
+run after gimplification and what source files they are located in.
@itemize @bullet
-@item
-Parsing. This pass reads the entire text of a function definition,
-constructing a high level tree representation. (Because of the semantic
-analysis that takes place during this pass, it does more than is
-formally considered to be parsing.)
-
-The tree representation does not entirely follow C syntax, because it is
-intended to support other languages as well.
-
-Language-specific data type analysis is also done in this pass, and every
-tree node that represents an expression has a data type attached.
-Variables are represented as declaration nodes.
-
-The language-independent source files for parsing are
-@file{tree.c}, @file{fold-const.c}, and @file{stor-layout.c}.
-There are also header files @file{tree.h} and @file{tree.def}
-which define the format of the tree representation.
-
-C preprocessing, for language front ends, that want or require it, is
-performed by cpplib, which is covered in separate documentation. In
-particular, the internals are covered in @xref{Top, ,Cpplib internals,
-cppinternals, Cpplib Internals}.
-
-The source files to parse C are found in the toplevel directory, and
-by convention are named @file{c-*}. Some of these are also used by
-the other C-like languages: @file{c-common.c},
-@file{c-common.def},
-@file{c-format.c},
-@file{c-opts.c},
-@file{c-pragma.c},
-@file{c-semantics.c},
-@file{c-lex.c},
-@file{c-incpath.c},
-@file{c-ppoutput.c},
-@file{c-cppbuiltin.c},
-@file{c-common.h},
-@file{c-dump.h},
-@file{c.opt},
-@file{c-incpath.h}
-and
-@file{c-pragma.h},
-
-Files specific to each language are in subdirectories named after the
-language in question, like @file{ada}, @file{objc}, @file{cp} (for C++).
-
-@cindex Tree optimization
-@item
-Tree optimization. This is the optimization of the tree
-representation, before converting into RTL code.
-
-@cindex inline on trees, automatic
-Currently, the main optimization performed here is tree-based
-inlining.
-This is implemented in @file{tree-inline.c} and used by both C and C++.
-Note that tree based inlining turns off rtx based inlining (since it's more
-powerful, it would be a waste of time to do rtx based inlining in
-addition).
-
-@cindex constant folding
-@cindex arithmetic simplifications
-@cindex simplifications, arithmetic
-Constant folding and some arithmetic simplifications are also done
-during this pass, on the tree representation.
-The routines that perform these tasks are located in @file{fold-const.c}.
-
-@cindex RTL generation
-@item
-RTL generation. This is the conversion of syntax tree into RTL code.
+@item Remove useless statements
+
+This pass is an extremely simple sweep across the gimple code in which
+we identify obviously dead code and remove it. Here we do things like
+simplify @code{if} statements with constant conditions, remove
+exception handling constructs surrounding code that obviously cannot
+throw, remove lexical bindings that contain no variables, and other
+assorted simplistic cleanups. The idea is to get rid of the obvious
+stuff quickly rather than wait until later when it's more work to get
+rid of it. This pass is located in @file{tree-cfg.c} and described by
+@code{pass_remove_useless_stmts}.
+
+@item Mudflap declaration registration
+
+If mudflap (@pxref{Optimize Options,,-fmudflap -fmudflapth
+-fmudflapir,gcc.info,Using the GNU Compiler Collection (GCC)}) is
+enabled, we generate code to register some variable declarations with
+the mudflap runtime. Specifically, the runtime tracks the lifetimes of
+those variable declarations that have their addresses taken, or whose
+bounds are unknown at compile time (@code{extern}). This pass generates
+new exception handling constructs (@code{try}/@code{finally}), and so
+must run before those are lowered. In addition, the pass enqueues
+declarations of static variables whose lifetimes extend to the entire
+program. The pass is located in @file{tree-mudflap.c} and is described
+by @code{pass_mudflap_1}.
+
+@item Lower control flow
+
+This pass flattens @code{if} statements (@code{COND_EXPR}) and
+and moves lexical bindings (@code{BIND_EXPR}) out of line. After
+this pass, all @code{if} statements will have exactly two @code{goto}
+statements in its @code{then} and @code{else} arms. Lexical binding
+information for each statement will be found in @code{TREE_BLOCK} rather
+than being inferred from its position under a @code{BIND_EXPR}. This
+pass is found in @file{gimple-low.c} and is described by
+@code{pass_lower_cf}.
+
+@item Lower exception handling control flow
+
+This pass decomposes high-level exception handling constructs
+(@code{TRY_FINALLY_EXPR} and @code{TRY_CATCH_EXPR}) into a form
+that explicitly represents the control flow involved. After this
+pass, @code{lookup_stmt_eh_region} will return a non-negative
+number for any statement that may have EH control flow semantics;
+examine @code{tree_can_throw_internal} or @code{tree_can_throw_external}
+for exact semantics. Exact control flow may be extracted from
+@code{foreach_reachable_handler}. The EH region nesting tree is defined
+in @file{except.h} and built in @file{except.c}. The lowering pass
+itself is in @file{tree-eh.c} and is described by @code{pass_lower_eh}.
+
+@item Build the control flow graph
+
+This pass decomposes a function into basic blocks and creates all of
+the edges that connect them. It is located in @file{tree-cfg.c} and
+is described by @code{pass_build_cfg}.
+
+@item Find all referenced variables
+
+This pass walks the entire function and collects an array of all
+variables referenced in the function, @code{referenced_vars}. The
+index at which a variable is found in the array is used as a UID
+for the variable within this function. This data is needed by the
+SSA rewriting routines. The pass is located in @file{tree-dfa.c}
+and is described by @code{pass_referenced_vars}.
+
+@item Points-to analysis
+
+This pass constructs flow-insensitive alias analysis information.
+The pass is located in @file{tree-alias-common.c} and described by
+@code{pass_build_pta}.
+
+@item Enter static single assignment form
+
+This pass rewrites the function such that it is in SSA form. After
+this pass, all @code{is_gimple_reg} variables will be referenced by
+@code{SSA_NAME}, and all occurences of other variables will be
+annotated with @code{VDEFS} and @code{VUSES}; phi nodes will have
+been inserted as necessary for each basic block. This pass is
+located in @file{tree-ssa.c} and is described by @code{pass_build_ssa}.
+
+@item Warn for uninitialized variables
+
+This pass scans the function for uses of @code{SSA_NAME}s that
+are fed by default definition. For non-parameter variables, such
+uses are uninitialized. The pass is run twice, before and after
+optimization. In the first pass we only warn for uses that are
+positively uninitialized; in the second pass we warn for uses that
+are possibly uninitialized. The pass is located in @file{tree-ssa.c}
+and is defined by @code{pass_early_warn_uninitialized} and
+@code{pass_late_warn_uninitialized}.
+
+@item Dead code elimination
+
+This pass scans the function for statements without side effects whose
+result is unused. It does not do memory life analysis, so any value
+that is stored in memory is considered used. The pass is run multiple
+times throughout the optimization process. It is located in
+@file{tree-ssa-dce.c} and is described by @code{pass_dce}.
+
+@item Dominator optimizations
+
+This pass performs trivial dominator-based copy and constant propagation,
+expression simplification, and jump threading. It is run multiple times
+throughout the optimization process. It it located in @file{tree-ssa-dom.c}
+and is described by @code{pass_dominator}.
+
+@item Redundant phi elimination
+
+This pass removes phi nodes for which all of the arguments are the same
+value, excluding feedback. Such degenerate forms are typically created
+by removing unreachable code. The pass is run multiple times throughout
+the optimization process. It is located in @file{tree-ssa.c} and is
+described by @code{pass_redundant_phi}.o
+
+@item Forward propagation of single-use variables
+
+This pass attempts to remove redundant computation by substituting
+variables that are used once into the expression that uses them and
+seeing if the result can be simplified. It is located in
+@file{tree-ssa-forwprop.c} and is described by @code{pass_forwprop}.
+
+@item Copy Renaming
+
+This pass attempts to change the name of compiler temporaries involved in
+copy operations such that SSA->normal can coalesce the copy away. When compiler
+temporaries are copies of user variables, it also renames the compiler
+temporary to the user variable resulting in better use of user symbols. It is
+located in @file{tree-ssa-copyrename.c} and is described by
+@code{pass_copyrename}.
+
+@item PHI node optimizations
+
+This pass recognizes forms of phi inputs that can be represented as
+conditional expressions and rewrites them into straight line code.
+It is located in @file{tree-ssa-phiopt.c} and is described by
+@code{pass_phiopt}.
+
+@item May-alias optimization
+
+This pass performs a flow sensitive SSA-based points-to analysis.
+The resulting may-alias, must-alias, and escape analysis information
+is used to promote variables from in-memory addressable objects to
+non-aliased variables that can be renamed into SSA form. We also
+update the @code{VDEF}/@code{VUSE} memory tags for non-renamable
+aggregates so that we get fewer false kills. The pass is located
+in @file{tree-ssa-alias.c} and is described by @code{pass_may_alias}.
+
+@item Profiling
+
+This pass rewrites the function in order to collect runtime block
+and value profiling data. Such data may be fed back into the compiler
+on a subsequent run so as to allow optimization based on expected
+execution frequencies. The pass is located in @file{predict.c} and
+is described by @code{pass_profile}.
+
+@item Lower complex arithmetic
+
+This pass rewrites complex arithmetic operations into their component
+scalar arithmetic operations. The pass is located in @file{tree-complex.c}
+and is described by @code{pass_lower_complex}.
+
+@item Scalar replacement of aggregates
+
+This pass rewrites suitable non-aliased local aggregate variables into
+a set of scalar variables. The resulting scalar variables are
+rewritten into SSA form, which allows subsequent optimization passes
+to do a significantly better job with them. The pass is located in
+@file{tree-sra.c} and is described by @code{pass_sra}.
+
+@item Dead store elimination
+
+This pass eliminates stores to memory that are subsequently overwritten
+by another store, without any intervening loads. The pass is located
+in @file{tree-ssa-dse.c} and is described by @code{pass_dse}.
+
+@item Tail recursion elimination
+
+This pass transforms tail recursion into a loop. It is located in
+@file{tree-tailcall.c} and is described by @code{pass_tail_recursion}.
+
+@item Partial redundancy elimination
+
+This pass eliminates partially redundant computations, as well as
+performing load motion. The pass is located in @file{tree-ssa-pre.c}
+and is described by @code{pass_pre}.
+
+@item Loop optimization
+
+TODO: Presumably we're going to do something with loops here. At
+present we don't, and this is a placeholder. The pass is located
+in @file{tree-ssa-loop.c} and is described by @code{pass_loop}.
-@cindex target-parameter-dependent code
-This is where the bulk of target-parameter-dependent code is found,
-since often it is necessary for strategies to apply only when certain
-standard kinds of instructions are available. The purpose of named
-instruction patterns is to provide this information to the RTL
-generation pass.
+@item Conditional constant propagation
-@cindex tail recursion optimization
-Optimization is done in this pass for @code{if}-conditions that are
-comparisons, boolean operations or conditional expressions. Tail
-recursion is detected at this time also. Decisions are made about how
-best to arrange loops and how to output @code{switch} statements.
+This pass relaxes a lattice of values in order to identify those
+that must be constant even in the presence of conditional branches.
+The pass is located in @file{tree-ssa-ccp.c} and is described
+by @code{pass_ccp}.
+
+@item Folding builtin functions
+
+This pass simplifies builtin functions, as applicable, with constant
+arguments or with inferrable string lengths. It is located in
+@file{tree-ssa-ccp.c} and is described by @code{pass_fold_builtins}.
+
+@item Split critical edges
+
+This pass identifies critical edges and inserts empty basic blocks
+such that the edge is no longer critical. The pass is located in
+@file{tree-cfg.c} and is described by @code{pass_split_crit_edges}.
+
+@item Partial redundancy elimination
+
+This pass answers the question ``given a hypothetical temporary
+variable, what expressions could we eliminate?'' It is located
+in @file{tree-ssa-pre.c} and is described by @code{pass_pre}.
+
+@item Control dependence dead code elimination
+
+This pass is a stronger form of dead code elimination that can
+eliminate unnecessary control flow statements. It is located
+in @file{tree-ssa-dce.c} and is described by @code{pass_cd_dce}.
+
+@item Tail call elimination
+
+This pass identifies function calls that may be rewritten into
+jumps. No code transformation is actually applied here, but the
+data and control flow problem is solved. The code transformation
+requires target support, and so is delayed until RTL. In the
+meantime @code{CALL_EXPR_TAILCALL} is set indicating the possibility.
+The pass is located in @file{tree-tailcall.c} and is described by
+@code{pass_tail_calls}. The RTL transformation is handled by
+@code{fixup_tail_calls} in @file{calls.c}.
+
+@item Warn for function return without value
+
+For non-void functions, this pass locates return statements that do
+not specify a value and issues a warning. Such a statement may have
+been injected by falling off the end of the function. This pass is
+run last so that we have as much time as possible to prove that the
+statement is not reachable. It is located in @file{tree-cfg.c} and
+is described by @code{pass_warn_function_return}.
+
+@item Mudflap statement annotation
+
+If mudflap is enabled, we rewrite some memory accesses with code to
+validate that the memory access is correct. In particular, expressions
+involving pointer dereferences (@code{INDIRECT_REF}, @code{ARRAY_REF},
+etc.) are replaced by code that checks the selected address range
+against the mudflap runtime's database of valid regions. This check
+includes an inline lookup into a direct-mapped cache, based on
+shift/mask operations of the pointer value, with a fallback function
+call into the runtime. The pass is located in @file{tree-mudflap.c} and
+is described by @code{pass_mudflap_2}.
+
+@item Leave static single assignment form
+
+This pass rewrites the function such that it is in normal form. At
+the same time, we eliminate as many single-use temporaries as possible,
+so the intermediate language is no longer GIMPLE, but GENERIC. The
+pass is located in @file{tree-ssa.c} and is described by @code{pass_del_ssa}.
+@end itemize
+
+@node RTL passes
+@section RTL passes
+
+The following briefly describes the rtl generation and optimization
+passes that are run after tree optimization.
+
+@itemize @bullet
+@item RTL generation
@c Avoiding overfull is tricky here.
The source files for RTL generation include
@@ -157,105 +469,32 @@ generated from the machine description by the programs @code{genflags}
and @code{gencodes}, tell this pass which standard names are available
for use and which patterns correspond to them.
-Aside from debugging information output, none of the following passes
-refers to the tree structure representation of the function (only
-part of which is saved).
-
-@cindex inline on rtx, automatic
-The decision of whether the function can and should be expanded inline
-in its subsequent callers is made at the end of rtl generation. The
-function must meet certain criteria, currently related to the size of
-the function and the types and number of parameters it has. Note that
-this function may contain loops, recursive calls to itself
-(tail-recursive functions can be inlined!), gotos, in short, all
-constructs supported by GCC@. The file @file{integrate.c} contains
-the code to save a function's rtl for later inlining and to inline that
-rtl when the function is called. The header file @file{integrate.h}
-is also used for this purpose.
-
-@opindex dr
-The option @option{-dr} causes a debugging dump of the RTL code after
-this pass. This dump file's name is made by appending @samp{.rtl} to
-the input file name.
-
-@c Should the exception handling pass be talked about here?
-
-@cindex sibling call optimization
-@item
-Sibling call optimization. This pass performs tail recursion
-elimination, and tail and sibling call optimizations. The purpose of
-these optimizations is to reduce the overhead of function calls,
-whenever possible.
+@item Generate exception handling landing pads
-The source file of this pass is @file{sibcall.c}
+This pass generates the glue that handles communication between the
+exception handling library routines and the exception handlers within
+the function. Entry points in the function that are invoked by the
+exception handling library are called @dfn{landing pads}. The code
+for this pass is located within @file{except.c}.
-@opindex di
-The option @option{-di} causes a debugging dump of the RTL code after
-this pass is run. This dump file's name is made by appending
-@samp{.sibling} to the input file name.
+@item Cleanup control flow graph
-@cindex jump optimization
-@cindex unreachable code
-@cindex dead code
-@item
-Jump optimization. This pass simplifies jumps to the following
-instruction, jumps across jumps, and jumps to jumps. It deletes
-unreferenced labels and unreachable code, except that unreachable code
-that contains a loop is not recognized as unreachable in this pass.
-(Such loops are deleted later in the basic block analysis.) It also
-converts some code originally written with jumps into sequences of
-instructions that directly set values from the results of comparisons,
-if the machine has such instructions.
-
-Jump optimization is performed two or three times. The first time is
-immediately following RTL generation. The second time is after CSE,
-but only if CSE says repeated jump optimization is needed. The
-last time is right before the final pass. That time, cross-jumping
-and deletion of no-op move instructions are done together with the
-optimizations described above.
-
-The source file of this pass is @file{jump.c}.
-
-@opindex dj
-The option @option{-dj} causes a debugging dump of the RTL code after
-this pass is run for the first time. This dump file's name is made by
-appending @samp{.jump} to the input file name.
-
-
-@cindex register use analysis
-@item
-Register scan. This pass finds the first and last use of each
-register, as a guide for common subexpression elimination. Its source
-is in @file{regclass.c}.
+This pass removes unreachable code, simplifies jumps to next, jumps to
+jump, jumps across jumps, etc. The pass is run multiple times.
+For historical reasons, it is occasionally referred to as the ``jump
+optimization pass''. The bulk of the code for this pass is in
+@file{cfgcleanup.c}, and there are support routines in @file{cfgrtl.c}
+and @file{jump.c}.
-@cindex jump threading
-@item
-@opindex fthread-jumps
-Jump threading. This pass detects a condition jump that branches to an
-identical or inverse test. Such jumps can be @samp{threaded} through
-the second conditional test. The source code for this pass is in
-@file{jump.c}. This optimization is only performed if
-@option{-fthread-jumps} is enabled.
-
-@cindex common subexpression elimination
-@cindex constant propagation
-@item
-Common subexpression elimination. This pass also does constant
-propagation. Its source files are @file{cse.c}, and @file{cselib.c}.
-If constant propagation causes conditional jumps to become
-unconditional or to become no-ops, jump optimization is run again when
-CSE is finished.
-
-@opindex ds
-The option @option{-ds} causes a debugging dump of the RTL code after
-this pass. This dump file's name is made by appending @samp{.cse} to
-the input file name.
-
-@cindex global common subexpression elimination
-@cindex constant propagation
-@cindex copy propagation
-@item
-Global common subexpression elimination. This pass performs two
+@item Common subexpression elimination
+
+This pass removes redundant computation within basic blocks, and
+optimizes addressing modes based on cost. The pass is run twice.
+The source is located in @file{cse.c}.
+
+@item Global common subexpression elimination.
+
+This pass performs two
different types of GCSE depending on whether you are optimizing for
size or not (LCM based GCSE tends to increase code size for a gain in
speed, while Morel-Renvoise based GCSE does not).
@@ -270,193 +509,119 @@ based GCSE also does loop invariant code motion. We also perform load
and store motion when optimizing for speed.
Regardless of which type of GCSE is used, the GCSE pass also performs
global constant and copy propagation.
-
The source file for this pass is @file{gcse.c}, and the LCM routines
are in @file{lcm.c}.
-@opindex dG
-The option @option{-dG} causes a debugging dump of the RTL code after
-this pass. This dump file's name is made by appending @samp{.gcse} to
-the input file name.
+@item Loop optimization
-@cindex loop optimization
-@cindex code motion
-@cindex strength-reduction
-@item
-Loop optimization. This pass moves constant expressions out of loops,
+This pass moves constant expressions out of loops,
and optionally does strength-reduction and loop unrolling as well.
Its source files are @file{loop.c} and @file{unroll.c}, plus the header
@file{loop.h} used for communication between them. Loop unrolling uses
some functions in @file{integrate.c} and the header @file{integrate.h}.
Loop dependency analysis routines are contained in @file{dependence.c}.
-Second loop optimization pass takes care of basic block level optimizations --
-unrolling, peeling and unswitching loops. The source files are
-@file{cfgloopanal.c} and @file{cfgloopmanip.c} containing generic loop
-analysis and manipulation code, @file{loop-init.c} with initialization and
-finalization code, @file{loop-unswitch.c} for loop unswitching and
-@file{loop-unroll.c} for loop unrolling and peeling.
+A second loop optimization pass takes care of basic block level
+optimizations---unrolling, peeling and unswitching loops. The source
+files are @file{cfgloopanal.c} and @file{cfgloopmanip.c} containing
+generic loop analysis and manipulation code, @file{loop-init.c} with
+initialization and finalization code, @file{loop-unswitch.c} for loop
+unswitching and @file{loop-unroll.c} for loop unrolling and peeling.
-@opindex dL
-The option @option{-dL} causes a debugging dump of the RTL code after
-these passes. The dump file names are made by appending @samp{.loop} and
-@samp{.loop2} to the input file name.
+@item Jump bypassing
-@cindex jump bypassing
-@item
-Jump bypassing. This pass is an aggressive form of GCSE that transforms
-the control flow graph of a function by propagating constants into
-conditional branch instructions.
+This pass is an aggressive form of GCSE that transforms the control
+flow graph of a function by propagating constants into conditional
+branch instructions. The source file for this pass is @file{gcse.c}.
-The source file for this pass is @file{gcse.c}.
+@item If conversion
-@opindex dG
-The option @option{-dG} causes a debugging dump of the RTL code after
-this pass. This dump file's name is made by appending @samp{.bypass}
-to the input file name.
+This pass attempts to replace conditional branches and surrounding
+assignments with arithmetic, boolean value producing comparison
+instructions, and conditional move instructions. In the very last
+invocation after reload, it will generate predicated instructions
+when supported by the target. The pass is located in @file{ifcvt.c}.
-@cindex web construction
-@item
-Simple optimization pass that splits independent uses of each pseudo
-increasing effect of other optimizations. This can improve effect of the
-other transformation, such as CSE or register allocation.
-Its source files are @file{web.c}.
+@item Web construction
-@opindex dZ
-The option @option{-dZ} causes a debugging dump of the RTL code after
-this pass. This dump file's name is made by appending @samp{.web} to
-the input file name.
+This pass splits independent uses of each pseudo-register. This can
+improve effect of the other transformation, such as CSE or register
+allocation. Its source files are @file{web.c}.
-@item
-@opindex frerun-cse-after-loop
-If @option{-frerun-cse-after-loop} was enabled, a second common
-subexpression elimination pass is performed after the loop optimization
-pass. Jump threading is also done again at this time if it was specified.
-
-@opindex dt
-The option @option{-dt} causes a debugging dump of the RTL code after
-this pass. This dump file's name is made by appending @samp{.cse2} to
-the input file name.
-
-@cindex data flow analysis
-@cindex analysis, data flow
-@cindex basic blocks
-@item
-Data flow analysis (@file{flow.c}). This pass divides the program
-into basic blocks (and in the process deletes unreachable loops); then
-it computes which pseudo-registers are live at each point in the
-program, and makes the first instruction that uses a value point at
-the instruction that computed the value.
-
-@cindex autoincrement/decrement analysis
-This pass also deletes computations whose results are never used, and
-combines memory references with add or subtract instructions to make
-autoincrement or autodecrement addressing.
-
-@opindex df
-The option @option{-df} causes a debugging dump of the RTL code after
-this pass. This dump file's name is made by appending @samp{.flow} to
-the input file name. If stupid register allocation is in use, this
-dump file reflects the full results of such allocation.
-
-@cindex instruction combination
-@item
-Instruction combination (@file{combine.c}). This pass attempts to
-combine groups of two or three instructions that are related by data
-flow into single instructions. It combines the RTL expressions for
-the instructions by substitution, simplifies the result using algebra,
-and then attempts to match the result against the machine description.
-
-@opindex dc
-The option @option{-dc} causes a debugging dump of the RTL code after
-this pass. This dump file's name is made by appending @samp{.combine}
-to the input file name.
-
-@cindex if conversion
-@item
-If-conversion is a transformation that transforms control dependencies
-into data dependencies (IE it transforms conditional code into a
-single control stream).
-It is implemented in the file @file{ifcvt.c}.
+@item Life analysis
-@opindex dE
-The option @option{-dE} causes a debugging dump of the RTL code after
-this pass. This dump file's name is made by appending @samp{.ce} to
-the input file name.
+This pass computes which pseudo-registers are live at each point in
+the program, and makes the first instruction that uses a value point
+at the instruction that computed the value. It then deletes
+computations whose results are never used, and combines memory
+references with add or subtract instructions to make autoincrement or
+autodecrement addressing. The pass is located in @file{flow.c}.
-@cindex register movement
-@item
-Register movement (@file{regmove.c}). This pass looks for cases where
-matching constraints would force an instruction to need a reload, and
-this reload would be a register-to-register move. It then attempts
-to change the registers used by the instruction to avoid the move
-instruction.
-
-@opindex dN
-The option @option{-dN} causes a debugging dump of the RTL code after
-this pass. This dump file's name is made by appending @samp{.regmove}
-to the input file name.
-
-@cindex instruction scheduling
-@cindex scheduling, instruction
-@item
-Instruction scheduling (@file{sched.c}). This pass looks for
-instructions whose output will not be available by the time that it is
-used in subsequent instructions. (Memory loads and floating point
-instructions often have this behavior on RISC machines). It re-orders
-instructions within a basic block to try to separate the definition and
-use of items that otherwise would cause pipeline stalls.
-
-Instruction scheduling is performed twice. The first time is immediately
-after instruction combination and the second is immediately after reload.
-
-@opindex dS
-The option @option{-dS} causes a debugging dump of the RTL code after this
-pass is run for the first time. The dump file's name is made by
-appending @samp{.sched} to the input file name.
-
-@cindex register allocation
-@item
-Register allocation. These passes make sure that all occurrences of pseudo
-registers are eliminated, either by allocating them to a hard register,
-replacing them by an equivalent expression (e.g.@: a constant) or by placing
+@item Instruction combination
+
+This pass attempts to combine groups of two or three instructions that
+are related by data flow into single instructions. It combines the
+RTL expressions for the instructions by substitution, simplifies the
+result using algebra, and then attempts to match the result against
+the machine description. The pass is located in @file{combine.c}.
+
+@item Register movement
+
+This pass looks for cases where matching constraints would force an
+instruction to need a reload, and this reload would be a
+register-to-register move. It then attempts to change the registers
+used by the instruction to avoid the move instruction.
+The pass is located in @file{regmove.c}.
+
+@item Optimize mode switching
+
+This pass looks for instructions that require the processor to be in a
+specific ``mode'' and minimizes the number of mode changes required to
+satisfy all users. What these modes are, and what they apply to are
+completely target-specific. The source is located in @file{lcm.c}.
+
+@item Instruction scheduling
+
+This pass looks for instructions whose output will not be available by
+the time that it is used in subsequent instructions. Memory loads and
+floating point instructions often have this behavior on RISC machines.
+It re-orders instructions within a basic block to try to separate the
+definition and use of items that otherwise would cause pipeline
+stalls. This pass is performed twice, before and after register
+allocation. The pass is located in @file{haifa-sched.c},
+@file{sched-deps.c}, @file{sched-ebb.c}, @file{sched-rgn.c} and
+@file{sched-vis.c}.
+
+@item Register allocation
+
+These passes make sure that all occurrences of pseudo registers are
+eliminated, either by allocating them to a hard register, replacing
+them by an equivalent expression (e.g.@: a constant) or by placing
them on the stack. This is done in several subpasses:
@itemize @bullet
-@cindex register class preference pass
@item
Register class preferencing. The RTL code is scanned to find out
which register class is best for each pseudo register. The source
file is @file{regclass.c}.
-@cindex local register allocation
@item
-Local register allocation (@file{local-alloc.c}). This pass allocates
-hard registers to pseudo registers that are used only within one basic
-block. Because the basic block is linear, it can use fast and
-powerful techniques to do a very good job.
-
-@opindex dl
-The option @option{-dl} causes a debugging dump of the RTL code after
-this pass. This dump file's name is made by appending @samp{.lreg} to
-the input file name.
+Local register allocation. This pass allocates hard registers to
+pseudo registers that are used only within one basic block. Because
+the basic block is linear, it can use fast and powerful techniques to
+do a decent job. The source is located in @file{local-alloc.c}.
-@cindex global register allocation
@item
-Global register allocation (@file{global.c}). This pass
-allocates hard registers for the remaining pseudo registers (those
-whose life spans are not contained in one basic block).
+Global register allocation. This pass allocates hard registers for
+the remaining pseudo registers (those whose life spans are not
+contained in one basic block). The pass is located in @file{global.c}.
-@cindex graph coloring register allocation
-@opindex fnew-ra
-@opindex dl
@item
Graph coloring register allocator. The files @file{ra.c}, @file{ra-build.c},
@file{ra-colorize.c}, @file{ra-debug.c}, @file{ra-rewrite.c} together with
the header @file{ra.h} contain another register allocator, which is used
when the option @option{-fnew-ra} is given. In that case it is run instead
-of the above mentioned local and global register allocation passes, and the
-option @option{-dl} causes a debugging dump of its work.
+of the above mentioned local and global register allocation passes.
@cindex reloading
@item
@@ -474,165 +639,65 @@ instructions to save and restore call-clobbered registers around calls.
Source files are @file{reload.c} and @file{reload1.c}, plus the header
@file{reload.h} used for communication between them.
-
-@opindex dg
-The option @option{-dg} causes a debugging dump of the RTL code after
-this pass. This dump file's name is made by appending @samp{.greg} to
-the input file name.
@end itemize
-@cindex instruction scheduling
-@cindex scheduling, instruction
-@item
-Instruction scheduling is repeated here to try to avoid pipeline stalls
-due to memory loads generated for spilled pseudo registers.
+@item Basic block reordering
-@opindex dR
-The option @option{-dR} causes a debugging dump of the RTL code after
-this pass. This dump file's name is made by appending @samp{.sched2}
-to the input file name.
+This pass implements profile guided code positioning. If profile
+information is not available, various types of static analysis are
+performed to make the predictions normally coming from the profile
+feedback (IE execution frequency, branch probability, etc). It is
+implemented in the file @file{bb-reorder.c}, and the various
+prediction routines are in @file{predict.c}.
-@cindex basic block reordering
-@cindex reordering, block
-@item
-Basic block reordering. This pass implements profile guided code
-positioning. If profile information is not available, various types of
-static analysis are performed to make the predictions normally coming
-from the profile feedback (IE execution frequency, branch probability,
-etc). It is implemented in the file @file{bb-reorder.c}, and the
-various prediction routines are in @file{predict.c}.
-
-@opindex dB
-The option @option{-dB} causes a debugging dump of the RTL code after
-this pass. This dump file's name is made by appending @samp{.bbro} to
-the input file name.
-
-@cindex variable tracking
-@item
-Variable tracking. This pass computes where the variables are stored at each
+@item Variable tracking
+
+This pass computes where the variables are stored at each
position in code and generates notes describing the variable locations
to RTL code. The location lists are then generated according to these
notes to debug information if the debugging information format supports
location lists.
-@opindex dV
-The option @option{-dV} causes a debugging dump of the RTL code after
-this pass. This dump file's name is made by appending @samp{.vartrack}
-to the input file name.
+@item Delayed branch scheduling
-@cindex delayed branch scheduling
-@cindex scheduling, delayed branch
-@item
-Delayed branch scheduling. This optional pass attempts to find
-instructions that can go into the delay slots of other instructions,
-usually jumps and calls. The source file name is @file{reorg.c}.
+This optional pass attempts to find instructions that can go into the
+delay slots of other instructions, usually jumps and calls. The
+source file name is @file{reorg.c}.
-@opindex dd
-The option @option{-dd} causes a debugging dump of the RTL code after
-this pass. This dump file's name is made by appending @samp{.dbr}
-to the input file name.
+@item Branch shortening
+
+On many RISC machines, branch instructions have a limited range.
+Thus, longer sequences of instructions must be used for long branches.
+In this pass, the compiler figures out what how far each instruction
+will be from each other instruction, and therefore whether the usual
+instructions, or the longer sequences, must be used for each branch.
+
+@item Register-to-stack conversion
-@cindex branch shortening
-@item
-Branch shortening. On many RISC machines, branch instructions have a
-limited range. Thus, longer sequences of instructions must be used for
-long branches. In this pass, the compiler figures out what how far each
-instruction will be from each other instruction, and therefore whether
-the usual instructions, or the longer sequences, must be used for each
-branch.
-
-@cindex register-to-stack conversion
-@item
Conversion from usage of some hard registers to usage of a register
stack may be done at this point. Currently, this is supported only
for the floating-point registers of the Intel 80387 coprocessor. The
source file name is @file{reg-stack.c}.
-@opindex dk
-The options @option{-dk} causes a debugging dump of the RTL code after
-this pass. This dump file's name is made by appending @samp{.stack}
-to the input file name.
+@item Final
-@cindex final pass
-@cindex peephole optimization
-@item
-Final. This pass outputs the assembler code for the function. It is
-also responsible for identifying spurious test and compare
-instructions. Machine-specific peephole optimizations are performed
-at the same time. The function entry and exit sequences are generated
-directly as assembler code in this pass; they never exist as RTL@.
-
-The source files are @file{final.c} plus @file{insn-output.c}; the
-latter is generated automatically from the machine description by the
-tool @file{genoutput}. The header file @file{conditions.h} is used
-for communication between these files.
-
-@cindex debugging information generation
-@item
-Debugging information output. This is run after final because it must
-output the stack slot offsets for pseudo registers that did not get
-hard registers. Source files are @file{dbxout.c} for DBX symbol table
-format, @file{sdbout.c} for SDB symbol table format, @file{dwarfout.c}
-for DWARF symbol table format, files @file{dwarf2out.c} and
-@file{dwarf2asm.c} for DWARF2 symbol table format, and @file{vmsdbgout.c}
-for VMS debug symbol table format.
-@end itemize
+This pass outputs the assembler code for the function. The source files
+are @file{final.c} plus @file{insn-output.c}; the latter is generated
+automatically from the machine description by the tool @file{genoutput}.
+The header file @file{conditions.h} is used for communication between
+these files. If mudflap is enabled, the queue of deferred declarations
+and any addressed constants (e.g., string literals) is processed by
+@code{mudflap_finish_file} into a synthetic constructor function
+containing calls into the mudflap runtime.
-Some additional files are used by all or many passes:
+@item Debugging information output
-@itemize @bullet
-@item
-Every pass uses @file{machmode.def} and @file{machmode.h} which define
-the machine modes.
-
-@item
-Several passes use @file{real.h}, which defines the default
-representation of floating point constants and how to operate on them.
+This is run after final because it must output the stack slot offsets
+for pseudo registers that did not get hard registers. Source files
+are @file{dbxout.c} for DBX symbol table format, @file{sdbout.c} for
+SDB symbol table format, @file{dwarfout.c} for DWARF symbol table
+format, files @file{dwarf2out.c} and @file{dwarf2asm.c} for DWARF2
+symbol table format, and @file{vmsdbgout.c} for VMS debug symbol table
+format.
-@item
-All the passes that work with RTL use the header files @file{rtl.h}
-and @file{rtl.def}, and subroutines in file @file{rtl.c}. The tools
-@code{gen*} also use these files to read and work with the machine
-description RTL@.
-
-@item
-All the tools that read the machine description use support routines
-found in @file{gensupport.c}, @file{errors.c}, and @file{read-rtl.c}.
-
-@findex genconfig
-@item
-Several passes refer to the header file @file{insn-config.h} which
-contains a few parameters (C macro definitions) generated
-automatically from the machine description RTL by the tool
-@code{genconfig}.
-
-@cindex instruction recognizer
-@item
-Several passes use the instruction recognizer, which consists of
-@file{recog.c} and @file{recog.h}, plus the files @file{insn-recog.c}
-and @file{insn-extract.c} that are generated automatically from the
-machine description by the tools @file{genrecog} and
-@file{genextract}.
-
-@item
-Several passes use the header files @file{regs.h} which defines the
-information recorded about pseudo register usage, and @file{basic-block.h}
-which defines the information recorded about basic blocks.
-
-@item
-@file{hard-reg-set.h} defines the type @code{HARD_REG_SET}, a bit-vector
-with a bit for each hard register, and some macros to manipulate it.
-This type is just @code{int} if the machine has few enough hard registers;
-otherwise it is an array of @code{int} and some of the macros expand
-into loops.
-
-@item
-Several passes use instruction attributes. A definition of the
-attributes defined for a particular machine is in file
-@file{insn-attr.h}, which is generated from the machine description by
-the program @file{genattr}. The file @file{insn-attrtab.c} contains
-subroutines to obtain the attribute values for insns and information
-about processor pipeline characteristics for the instruction
-scheduler. It is generated from the machine description by the
-program @file{genattrtab}.
@end itemize
diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
index 746bca587bd..c5e8d33c15b 100644
--- a/gcc/doc/rtl.texi
+++ b/gcc/doc/rtl.texi
@@ -722,7 +722,6 @@ computation performed by this instruction, i.e., one that
This flag is required for exception handling support on targets with RTL
prologues.
-@findex RTX_INTEGRATED_P
@cindex @code{insn} and @samp{/i}
@cindex @code{call_insn} and @samp{/i}
@cindex @code{jump_insn} and @samp{/i}
@@ -732,8 +731,6 @@ prologues.
@cindex @code{const} and @samp{/i}
@cindex @code{note} and @samp{/i}
@cindex @code{integrated}, in @code{insn}, @code{call_insn}, @code{jump_insn}, @code{barrier}, @code{code_label}, @code{insn_list}, @code{const}, and @code{note}
-@item RTX_INTEGRATED_P (@var{x})
-Nonzero in an @code{insn}, @code{call_insn}, @code{jump_insn}, @code{barrier},
@code{code_label}, @code{insn_list}, @code{const}, or @code{note} if it
resulted from an in-line function call.
Stored in the @code{integrated} field and printed as @samp{/i}.
diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index 8868d193b88..d42ccbf6639 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -53,7 +53,13 @@ Headers for the @code{libiberty} library.
@item libada
The Ada runtime library.
+@item libbanshee
+The @code{libbanshee} library, used for Andersen-style points-to analysis.
+
@item libf2c
+The Fortran 77 runtime library.
+
+@item libgfortran
The Fortran runtime library.
@item libffi
@@ -68,6 +74,10 @@ about this library.
@item libjava
The Java runtime library.
+@item libmudflap
+The @code{libmudflap} library, used for instrumenting pointer and array
+dereferencing operations.
+
@item libobjc
The Objective-C runtime library.
@@ -700,6 +710,10 @@ If defined, a space-separated list of files that should be scanned by
gengtype.c to generate the garbage collection tables and routines for
this language. This excludes the files that are common to all front
ends. @xref{Type Information}.
+@item need_gmp
+If defined to @samp{yes}, this frontend requires the GMP library.
+Enables configure tests for GMP, which set @code{GMPLIBS} and
+@code{GMPINC} appropriately.
@end table
diff --git a/gcc/doc/standards.texi b/gcc/doc/standards.texi
index b8a44d40e69..df14c0f143d 100644
--- a/gcc/doc/standards.texi
+++ b/gcc/doc/standards.texi
@@ -186,7 +186,10 @@ GNAT Reference Manual}, for information on standard
conformance and compatibility of the Ada compiler.
@xref{Language,,The GNU Fortran Language, g77, Using and Porting GNU
-Fortran}, for details of the Fortran language supported by GCC@.
+Fortran}, for details of the Fortran language supported by @command{g77}.
+
+@xref{Standards,,Standards, gfortran, The GNU Fortran 95 Compiler}, for details
+of standards supported by @command{gfortran}.
@xref{Compatibility,,Compatibility with the Java Platform, gcj, GNU gcj},
for details of compatibility between @command{gcj} and the Java Platform.
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 39ddcc39130..a0f855d904e 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -1301,6 +1301,13 @@ Like @code{PCC_BITFIELD_TYPE_MATTERS} except that its effect is limited
to aligning a bit-field within the structure.
@end defmac
+@deftypefn {Target Hook} bool TARGET_ALIGN_ANON_BITFIELDS (void)
+When @code{PCC_BITFIELD_TYPE_MATTERS} is true this hook will determine
+whether unnamed bitfields affect the alignment of the containing
+structure. The hook should return true if the structure should inherit
+the alignment requirements of an unnamed bitfield's type.
+@end deftypefn
+
@defmac MEMBER_TYPE_FORCES_BLK (@var{field}, @var{mode})
Return 1 if a structure or array containing @var{field} should be accessed using
@code{BLKMODE}.
@@ -1787,13 +1794,16 @@ of words in each data entry.
@section Target Character Escape Sequences
@cindex escape sequences
-By default, GCC assumes that the C character escape sequences take on
-their ASCII values for the target. If this is not correct, you must
-explicitly define all of the macros below. All of them must evaluate
-to constants; they are used in @code{case} statements.
+By default, GCC assumes that the C character escape sequences and other
+characters take on their ASCII values for the target. If this is not
+correct, you must explicitly define all of the macros below. All of
+them must evaluate to constants; they are used in @code{case}
+statements.
@findex TARGET_BELL
+@findex TARGET_BS
@findex TARGET_CR
+@findex TARGET_DIGIT0
@findex TARGET_ESC
@findex TARGET_FF
@findex TARGET_NEWLINE
@@ -1802,7 +1812,9 @@ to constants; they are used in @code{case} statements.
@multitable {@code{TARGET_NEWLINE}} {Escape} {ASCII character}
@item Macro @tab Escape @tab ASCII character
@item @code{TARGET_BELL} @tab @kbd{\a} @tab @code{07}, @code{BEL}
+@item @code{TARGET_BS} @tab @kbd{\b} @tab @code{08}, @code{BS}
@item @code{TARGET_CR} @tab @kbd{\r} @tab @code{0D}, @code{CR}
+@item @code{TARGET_DIGIT0} @tab @kbd{0} @tab @code{30}, @code{ZERO}
@item @code{TARGET_ESC} @tab @kbd{\e}, @kbd{\E} @tab @code{1B}, @code{ESC}
@item @code{TARGET_FF} @tab @kbd{\f} @tab @code{0C}, @code{FF}
@item @code{TARGET_NEWLINE} @tab @kbd{\n} @tab @code{0A}, @code{LF}
@@ -8776,16 +8788,6 @@ being called, in @code{call} RTL expressions. On most machines this
should be @code{QImode}.
@end defmac
-@defmac INTEGRATE_THRESHOLD (@var{decl})
-A C expression for the maximum number of instructions above which the
-function @var{decl} should not be inlined. @var{decl} is a
-@code{FUNCTION_DECL} node.
-
-The default definition of this macro is 64 plus 8 times the number of
-arguments that the function accepts. Some people think a larger
-threshold should be used on RISC machines.
-@end defmac
-
@defmac STDC_0_IN_SYSTEM_HEADERS
In normal operation, the preprocessor expands @code{__STDC__} to the
constant 1, to signify that GCC conforms to ISO Standard C@. On some
diff --git a/gcc/doc/tree-ssa.texi b/gcc/doc/tree-ssa.texi
new file mode 100644
index 00000000000..56ccd6109c2
--- /dev/null
+++ b/gcc/doc/tree-ssa.texi
@@ -0,0 +1,1189 @@
+@c Copyright (c) 2004 Free Software Foundation, Inc.
+@c Free Software Foundation, Inc.
+@c This is part of the GCC manual.
+@c For copying conditions, see the file gcc.texi.
+
+@c ---------------------------------------------------------------------
+@c Tree SSA
+@c ---------------------------------------------------------------------
+
+@node Tree SSA
+@chapter Analysis and Optimization of GIMPLE Trees
+@cindex Tree SSA
+@cindex Optimization infrastructure for GIMPLE
+
+GCC uses three main intermediate languages to represent the program
+during compilation: GENERIC, GIMPLE and RTL@. GENERIC is a
+language-independent representation generated by each front end. It
+is used to serve as an interface between the parser and optimizer.
+GENERIC is a common representation that is able to represent programs
+written in all the languages supported by GCC@.
+
+GIMPLE and RTL are used to optimize the program. GIMPLE is used for
+target and language independent optimizations (e.g., inlining,
+constant propagation, tail call elimination, redundancy elimination,
+etc). Much like GENERIC, GIMPLE is a language independent, tree based
+representation. However, it differs from GENERIC in that the GIMPLE
+grammar is more restrictive: expressions contain no more than 3
+operands (except function calls), it has no control flow structures
+and expressions with side-effects are only allowed on the right hand
+side of assignments. See the chapter describing GENERIC and GIMPLE
+for more details.
+
+This chapter describes the data structures and functions used in the
+GIMPLE optimizers (also known as ``tree optimizers'' or ``middle
+end''). In particular, it focuses on all the macros, data structures,
+functions and programming constructs needed to implement optimization
+passes for GIMPLE@.
+
+@menu
+* GENERIC:: A high-level language-independent representation.
+* GIMPLE:: A lower-level factored tree representation.
+* Annotations:: Attributes for statements and variables.
+* Statement Operands:: Variables referenced by GIMPLE statements.
+* SSA:: Static Single Assignment representation.
+* Alias analysis:: Representing aliased loads and stores.
+@end menu
+
+@node GENERIC
+@section GENERIC
+@cindex GENERIC
+
+The purpose of GENERIC is simply to provide a language-independent way of
+representing an entire function in trees. To this end, it was necessary to
+add a few new tree codes to the back end, but most everything was already
+there. If you can express it with the codes in @code{gcc/tree.def}, it's
+GENERIC.
+
+Early on, there was a great deal of debate about how to think about
+statements in a tree IL. In GENERIC, a statement is defined as any
+expression whose value, if any, is ignored. A statement will always
+have @code{TREE_SIDE_EFFECTS} set (or it will be discarded), but a
+non-statement expression may also have side effects. A
+@code{CALL_EXPR}, for instance.
+
+It would be possible for some local optimizations to work on the
+GENERIC form of a function; indeed, the adapted tree inliner works
+fine on GENERIC, but the current compiler performs inlining after
+lowering to GIMPLE (a restricted form described in the next section).
+Indeed, currently the frontends perform this lowering before handing
+off to @code{tree_rest_of_compilation}, but this seems inelegant.
+
+If necessary, a front end can use some language-dependent tree codes
+in its GENERIC representation, so long as it provides a hook for
+converting them to GIMPLE and doesn't expect them to work with any
+(hypothetical) optimizers that run before the conversion to GIMPLE.
+The intermediate representation used while parsing C and C++ looks
+very little like GENERIC, but the C and C++ gimplifier hooks are
+perfectly happy to take it as input and spit out GIMPLE.
+
+@node GIMPLE
+@section GIMPLE
+@cindex GIMPLE
+
+GIMPLE is a simplified subset of GENERIC for use in optimization. The
+particular subset chosen (and the name) was heavily influenced by the
+SIMPLE IL used by the McCAT compiler project at McGill University,
+though we have made some different choices. For one thing, SIMPLE
+doesn't support @code{goto}; a production compiler can't afford that
+kind of restriction.
+
+GIMPLE retains much of the structure of the parse trees: lexical
+scopes are represented as containers, rather than markers. However,
+expressions are broken down into a 3-address form, using temporary
+variables to hold intermediate values. Also, control structures are
+lowered to gotos.
+
+In GIMPLE no container node is ever used for its value; if a
+@code{COND_EXPR} or @code{BIND_EXPR} has a value, it is stored into a
+temporary within the controlled blocks, and that temporary is used in
+place of the container.
+
+The compiler pass which lowers GENERIC to GIMPLE is referred to as the
+@samp{gimplifier}. The gimplifier works recursively, replacing complex
+statements with sequences of simple statements.
+
+@c Currently, the only way to
+@c tell whether or not an expression is in GIMPLE form is by recursively
+@c examining it; in the future there will probably be a flag to help avoid
+@c redundant work. FIXME FIXME
+
+@menu
+* Interfaces::
+* Temporaries::
+* GIMPLE Expressions::
+* Statements::
+* GIMPLE Example::
+* Rough GIMPLE Grammar::
+@end menu
+
+@node Interfaces
+@subsection Interfaces
+@cindex gimplification
+
+The tree representation of a function is stored in
+@code{DECL_SAVED_TREE}. It is lowered to GIMPLE by a call to
+@code{gimplify_function_tree}.
+
+If a front end wants to include language-specific tree codes in the tree
+representation which it provides to the back end, it must provide a
+definition of @code{LANG_HOOKS_GIMPLIFY_EXPR} which knows how to
+convert the front end trees to GIMPLE. Usually such a hook will involve
+much of the same code for expanding front end trees to RTL. This function
+can return fully lowered GIMPLE, or it can return GENERIC trees and let the
+main gimplifier lower them the rest of the way; this is often simpler.
+
+The C and C++ front ends currently convert directly from front end
+trees to GIMPLE, and hand that off to the back end rather than first
+converting to GENERIC. Their gimplifier hooks know about all the
+@code{_STMT} nodes and how to convert them to GENERIC forms. There
+was some work done on a genericization pass which would run first, but
+the existence of @code{STMT_EXPR} meant that in order to convert all
+of the C statements into GENERIC equivalents would involve walking the
+entire tree anyway, so it was simpler to lower all the way. This
+might change in the future if someone writes an optimization pass
+which would work better with higher-level trees, but currently the
+optimizers all expect GIMPLE.
+
+A front end which wants to use the tree optimizers (and already has
+some sort of whole-function tree representation) only needs to provide
+a definition of @code{LANG_HOOKS_GIMPLIFY_EXPR}, call
+@code{gimplify_function_tree} to lower to GIMPLE, and then hand off to
+@code{tree_rest_of_compilation} to compile and output the function.
+
+You can tell the compiler to dump a C-like representation of the GIMPLE
+form with the flag @code{-fdump-tree-gimple}.
+
+@node Temporaries
+@subsection Temporaries
+@cindex Temporaries
+
+When gimplification encounters a subexpression which is too complex, it
+creates a new temporary variable to hold the value of the subexpression,
+and adds a new statement to initialize it before the current statement.
+These special temporaries are known as @samp{expression temporaries}, and are
+allocated using @code{get_formal_tmp_var}. The compiler tries to
+always evaluate identical expressions into the same temporary, to simplify
+elimination of redundant calculations.
+
+We can only use expression temporaries when we know that it will not be
+reevaluated before its value is used, and that it will not be otherwise
+modified@footnote{These restrictions are derived from those in Morgan 4.8.}.
+Other temporaries can be allocated using
+@code{get_initialized_tmp_var} or @code{create_tmp_var}.
+
+Currently, an expression like @code{a = b + 5} is not reduced any
+further. We tried converting it to something like
+@smallexample
+ T1 = b + 5;
+ a = T1;
+@end smallexample
+but this bloated the representation for minimal benefit. However, a
+variable which must live in memory cannot appear in an expression; its
+value is explicitly loaded into a temporary first. Similarly, storing
+the value of an expression to a memory variable goes through a
+temporary.
+
+@node GIMPLE Expressions
+@subsection Expressions
+@cindex GIMPLE Expressions
+
+In general, expressions in GIMPLE consist of an operation and the
+appropriate number of simple operands; these operands must either be a
+GIMPLE rvalue (@code{is_gimple_val}), i.e. a constant or a register
+variable. More complex operands are factored out into temporaries, so
+that
+@smallexample
+ a = b + c + d
+@end smallexample
+becomes
+@smallexample
+ T1 = b + c;
+ a = T1 + d;
+@end smallexample
+
+The same rule holds for arguments to a @code{CALL_EXPR}.
+
+The target of an assignment is usually a variable, but can also be an
+@code{INDIRECT_REF} or a compound lvalue as described below.
+
+@menu
+* Compound Expressions::
+* Compound Lvalues::
+* Conditional Expressions::
+* Logical Operators::
+@end menu
+
+@node Compound Expressions
+@subsubsection Compound Expressions
+@cindex Compound Expressions
+
+The left-hand side of a C comma expression is simply moved into a separate
+statement.
+
+@node Compound Lvalues
+@subsubsection Compound Lvalues
+@cindex Compound Lvalues
+
+Currently compound lvalues involving array and structure field references
+are not broken down; an expression like @code{a.b[2] = 42} is not reduced
+any further (though complex array subscripts are). This restriction is a
+workaround for limitations in later optimizers; if we were to convert this
+to
+
+@smallexample
+ T1 = &a.b;
+ T1[2] = 42;
+@end smallexample
+
+alias analysis would not remember that the reference to @code{T1[2]} came
+by way of @code{a.b}, so it would think that the assignment could alias
+another member of @code{a}; this broke @code{struct-alias-1.c}. Future
+optimizer improvements may make this limitation unnecessary.
+
+@node Conditional Expressions
+@subsubsection Conditional Expressions
+@cindex Conditional Expressions
+
+A C @code{?:} expression is converted into an @code{if} statement with
+each branch assigning to the same temporary. So,
+
+@smallexample
+ a = b ? c : d;
+@end smallexample
+becomes
+@smallexample
+ if (b)
+ T1 = c;
+ else
+ T1 = d;
+ a = T1;
+@end smallexample
+
+Note that in GIMPLE, @code{if} statements are also represented using
+@code{COND_EXPR}, as described below.
+
+@node Logical Operators
+@subsubsection Logical Operators
+@cindex Logical Operators
+
+Except when they appear in the condition operand of a @code{COND_EXPR},
+logical `and' and `or' operators are simplified as follows:
+@code{a = b && c} becomes
+
+@smallexample
+ T1 = (bool)b;
+ if (T1)
+ T1 = (bool)c;
+ a = T1;
+@end smallexample
+
+Note that @code{T1} in this example cannot be an expression temporary,
+because it has two different assignments.
+
+@node Statements
+@subsection Statements
+@cindex Statements
+
+Most statements will be assignment statements, represented by
+@code{MODIFY_EXPR}. A @code{CALL_EXPR} whose value is ignored can
+also be a statement. No other C expressions can appear at statement level;
+a reference to a volatile object is converted into a @code{MODIFY_EXPR}.
+
+There are also several varieties of complex statements.
+
+@menu
+* Blocks::
+* Statement Sequences::
+* Empty Statements::
+* Loops::
+* Selection Statements::
+* Jumps::
+* Cleanups::
+* GIMPLE Exception Handling::
+@end menu
+
+@node Blocks
+@subsubsection Blocks
+@cindex Blocks
+
+Block scopes and the variables they declare in GENERIC and GIMPLE are
+expressed using the @code{BIND_EXPR} code, which in previous versions of
+GCC was primarily used for the C statement-expression extension.
+
+Variables in a block are collected into @code{BIND_EXPR_VARS} in
+declaration order. Any runtime initialization is moved out of
+@code{DECL_INITIAL} and into a statement in the controlled block. When
+gimplifying from C or C++, this initialization replaces the
+@code{DECL_STMT}.
+
+Variable-length arrays (VLAs) complicate this process, as their size often
+refers to variables initialized earlier in the block. To handle this, we
+currently split the block at that point, and move the VLA into a new, inner
+@code{BIND_EXPR}. This strategy may change in the future.
+
+@code{DECL_SAVED_TREE} for a GIMPLE function will always be a
+@code{BIND_EXPR} which contains declarations for the temporary variables
+used in the function.
+
+A C++ program will usually contain more @code{BIND_EXPR}s than there are
+syntactic blocks in the source code, since several C++ constructs have
+implicit scopes associated with them. On the other hand, although the C++
+front end uses pseudo-scopes to handle cleanups for objects with
+destructors, these don't translate into the GIMPLE form; multiple
+declarations at the same level use the same BIND_EXPR.
+
+@node Statement Sequences
+@subsubsection Statement Sequences
+@cindex Statement Sequences
+
+Multiple statements at the same nesting level are collected into a
+@code{STATEMENT_LIST}. Statement lists are modified and traversed
+using the interface in @samp{tree-iterator.h}.
+
+@node Empty Statements
+@subsubsection Empty Statements
+@cindex Empty Statements
+
+Whenever possible, statements with no effect are discarded. But if they
+are nested within another construct which cannot be discarded for some
+reason, they are instead replaced with an empty statement, generated by
+@code{build_empty_stmt}. Initially, all empty statements were shared,
+after the pattern of the Java front end, but this caused a lot of trouble in
+practice.
+
+An empty statement is represented as @code{(void)0}.
+
+@node Loops
+@subsubsection Loops
+@cindex Loops
+
+At one time loops were expressed in GIMPLE using @code{LOOP_EXPR}, but
+now they are lowered to explicit gotos.
+
+@node Selection Statements
+@subsubsection Selection Statements
+@cindex Selection Statements
+
+A simple selection statement, such as the C @code{if} statement, is
+expressed in GIMPLE using a void @code{COND_EXPR}. If only one branch is
+used, the other is filled with an empty statement.
+
+Normally, the condition expression is reduced to a simple comparison. If
+it is a shortcut (@code{&&} or @code{||}) expression, however, we try to
+break up the @code{if} into multiple @code{if}s so that the implied shortcut
+is taken directly, much like the transformation done by @code{do_jump} in
+the RTL expander.
+
+A @code{SWITCH_EXPR} in GIMPLE contains the condition and a
+@code{TREE_VEC} of @code{CASE_LABEL_EXPR}s describing the case values
+and corresponding @code{LABEL_DECL}s to jump to. The body of the
+@code{switch} is moved after the @code{SWITCH_EXPR}.
+
+@node Jumps
+@subsubsection Jumps
+@cindex Jumps
+
+Other jumps are expressed by either @code{GOTO_EXPR} or @code{RETURN_EXPR}.
+
+The operand of a @code{GOTO_EXPR} must be either a label or a variable
+containing the address to jump to.
+
+The operand of a @code{RETURN_EXPR} is either @code{NULL_TREE} or a
+@code{MODIFY_EXPR} which sets the return value. It would be nice to
+move the @code{MODIFY_EXPR} into a separate statement, but the special
+return semantics in @code{expand_return} make that difficult. It may
+still happen in the future, perhaps by moving most of that logic into
+@code{expand_assignment}.
+
+@node Cleanups
+@subsubsection Cleanups
+@cindex Cleanups
+
+Destructors for local C++ objects and similar dynamic cleanups are
+represented in GIMPLE by a @code{TRY_FINALLY_EXPR}. When the controlled
+block exits, the cleanup is run.
+
+@code{TRY_FINALLY_EXPR} complicates the flow graph, since the cleanup
+needs to appear on every edge out of the controlled block; this
+reduces our freedom to move code across these edges. Therefore, the
+EH lowering pass which runs before most of the optimization passes
+eliminates these expressions by explicitly adding the cleanup to each
+edge.
+
+@node GIMPLE Exception Handling
+@subsubsection Exception Handling
+@cindex GIMPLE Exception Handling
+
+Other exception handling constructs are represented using
+@code{TRY_CATCH_EXPR}. The handler operand of a @code{TRY_CATCH_EXPR}
+can be a normal statement to be executed if the controlled block throws an
+exception, or it can have one of two special forms:
+
+@enumerate
+@item A @code{CATCH_EXPR} executes its handler if the thrown exception
+ matches one of the allowed types. Multiple handlers can be
+ expressed by a sequence of @code{CATCH_EXPR} statements.
+@item An @code{EH_FILTER_EXPR} executes its handler if the thrown
+ exception does not match one of the allowed types.
+@end enumerate
+
+Currently throwing an exception is not directly represented in GIMPLE,
+since it is implemented by calling a function. At some point in the future
+we will want to add some way to express that the call will throw an
+exception of a known type.
+
+Just before running the optimizers, the compiler lowers the high-level
+EH constructs above into a set of @samp{goto}s, magic labels, and EH
+regions. Continuing to unwind at the end of a cleanup is represented
+with a @code{RESX_EXPR}.
+
+@node GIMPLE Example
+@subsection GIMPLE Example
+@cindex GIMPLE Example
+
+@smallexample
+struct A @{ A(); ~A(); @};
+
+int i;
+int g();
+void f()
+@{
+ A a;
+ int j = (--i, i ? 0 : 1);
+
+ for (int x = 42; x > 0; --x)
+ @{
+ i += g()*4 + 32;
+ @}
+@}
+@end smallexample
+
+becomes
+
+@smallexample
+void f()
+@{
+ int i.0;
+ int T.1;
+ int iftmp.2;
+ int T.3;
+ int T.4;
+ int T.5;
+ int T.6;
+
+ @{
+ struct A a;
+ int j;
+
+ __comp_ctor (&a);
+ try
+ @{
+ i.0 = i;
+ T.1 = i.0 - 1;
+ i = T.1;
+ i.0 = i;
+ if (i.0 == 0)
+ iftmp.2 = 1;
+ else
+ iftmp.2 = 0;
+ j = iftmp.2;
+ @{
+ int x;
+
+ x = 42;
+ goto test;
+ loop:;
+
+ T.3 = g ();
+ T.4 = T.3 * 4;
+ i.0 = i;
+ T.5 = T.4 + i.0;
+ T.6 = T.5 + 32;
+ i = T.6;
+ x = x - 1;
+
+ test:;
+ if (x > 0)
+ goto loop;
+ else
+ goto break_;
+ break_:;
+ @}
+ @}
+ finally
+ @{
+ __comp_dtor (&a);
+ @}
+ @}
+@}
+@end smallexample
+
+@node Rough GIMPLE Grammar
+@subsection Rough GIMPLE Grammar
+@cindex Rough GIMPLE Grammar
+
+@smallexample
+function:
+ FUNCTION_DECL
+ DECL_SAVED_TREE -> block
+block:
+ BIND_EXPR
+ BIND_EXPR_VARS -> DECL chain
+ BIND_EXPR_BLOCK -> BLOCK
+ BIND_EXPR_BODY
+ -> compound-stmt
+compound-stmt:
+ COMPOUND_EXPR
+ op0 -> non-compound-stmt
+ op1 -> stmt
+stmt: compound-stmt
+ | non-compound-stmt
+non-compound-stmt:
+ block
+ | if-stmt
+ | switch-stmt
+ | jump-stmt
+ | label-stmt
+ | try-stmt
+ | modify-stmt
+ | call-stmt
+if-stmt:
+ COND_EXPR
+ op0 -> condition
+ op1 -> stmt
+ op2 -> stmt
+switch-stmt:
+ SWITCH_EXPR
+ op0 -> val
+ op1 -> NULL_TREE
+ op2 -> TREE_VEC of CASE_LABEL_EXPRs
+jump-stmt:
+ GOTO_EXPR
+ op0 -> LABEL_DECL | '*' ID
+ | RETURN_EXPR
+ op0 -> modify-stmt
+ | NULL_TREE
+label-stmt:
+ LABEL_EXPR
+ op0 -> LABEL_DECL
+try-stmt:
+ TRY_CATCH_EXPR
+ op0 -> stmt
+ op1 -> handler
+ | TRY_FINALLY_EXPR
+ op0 -> stmt
+ op1 -> stmt
+handler:
+ catch-seq
+ | EH_FILTER_EXPR
+ | stmt
+catch-seq:
+ CATCH_EXPR
+ | COMPOUND_EXPR
+ op0 -> CATCH_EXPR
+ op1 -> catch-seq
+modify-stmt:
+ MODIFY_EXPR
+ op0 -> lhs
+ op1 -> rhs
+call-stmt: CALL_EXPR
+ op0 -> _DECL | '&' _DECL
+ op1 -> arglist
+arglist:
+ NULL_TREE
+ | TREE_LIST
+ op0 -> val
+ op1 -> arglist
+
+varname : compref | _DECL
+lhs: varname | '*' _DECL
+pseudo-lval: _DECL | '*' _DECL
+compref :
+ COMPONENT_REF
+ op0 -> compref | pseudo-lval
+ | ARRAY_REF
+ op0 -> compref | pseudo-lval
+ op1 -> val
+
+condition : val | val relop val
+val : _DECL | CONST
+
+rhs: varname | CONST
+ | '*' _DECL
+ | '&' varname
+ | call_expr
+ | unop val
+ | val binop val
+ | '(' cast ')' val
+
+unop: '+' | '-' | '!' | '~'
+
+binop: relop | '-' | '+' | '/' | '*'
+ | '%' | '&' | '|' | '<<' | '>>' | '^'
+
+relop: All tree codes of class '<'
+@end smallexample
+
+@node Annotations
+@section Annotations
+@cindex annotations
+
+The optimizers need to associate attributes with statements and
+variables during the optimization process. For instance, we need to
+know what basic block does a statement belong to or whether a variable
+has aliases. All these attributes are stored in data structures
+called annotations which are then linked to the field @code{ann} in
+@code{struct tree_common}.
+
+Presently, we define annotations for statements (@code{stmt_ann_t}),
+variables (@code{var_ann_t}) and SSA names (@code{ssa_name_ann_t}).
+Annotations are defined and documented in @file{tree-flow.h}.
+
+
+@node Statement Operands
+@section Statement Operands
+@cindex operands
+@cindex virtual operands
+@cindex real operands
+@findex get_stmt_operands
+@findex modify_stmt
+
+Almost every GIMPLE statement will contain a reference to a variable
+or memory location. Since statements come in different shapes and
+sizes, their operands are going to be located at various spots inside
+the statement's tree. To facilitate access to the statement's
+operands, they are organized into arrays associated inside each
+statement's annotation. Each element in an operand array is a pointer
+to a @code{VAR_DECL}, @code{PARM_DECL} or @code{SSA_NAME} tree node.
+This provides a very convenient way of examining and replacing
+operands.
+
+Data flow analysis and optimization is done on all tree nodes
+representing variables. Any node for which @code{SSA_VAR_P} returns
+nonzero is considered when scanning statement operands. However, not
+all @code{SSA_VAR_P} variables are processed in the same way. For the
+purposes of optimization, we need to distinguish between references to
+local scalar variables and references to globals, statics, structures,
+arrays, aliased variables, etc. The reason is simple, the compiler
+can gather complete data flow information for a local scalar. On the
+other hand, a global variable may be modified by a function call, it
+may not be possible to keep track of all the elements of an array or
+the fields of a structure, etc.
+
+The operand scanner gathers two kinds of operands: @dfn{real} and
+@dfn{virtual}. An operand for which @code{is_gimple_reg} returns true
+is considered real, otherwise it is a virtual operand. We also
+distinguish between uses and definitions. An operand is used if its
+value is loaded by the statement (e.g., the operand at the RHS of an
+assignment). If the statement assigns a new value to the operand, the
+operand is considered a definition (e.g., the operand at the LHS of
+an assignment).
+
+Virtual and real operands also have very different data flow
+properties. Real operands are unambiguous references to the
+full object that they represent. For instance, given
+
+@smallexample
+@{
+ int a, b;
+ a = b
+@}
+@end smallexample
+
+Since @code{a} and @code{b} are non-aliased locals, the statement
+@code{a = b} will have one real definition and one real use because
+variable @code{b} is completely modified with the contents of
+variable @code{a}. Real definition are also known as @dfn{killing
+definitions}. Similarly, the use of @code{a} reads all its bits.
+
+In contrast, virtual operands represent partial or ambiguous
+references to a variable. For instance, given
+
+@smallexample
+@{
+ int a, b, *p;
+
+ if (...)
+ p = &a;
+ else
+ p = &b;
+ *p = 5;
+ return *p;
+@}
+@end smallexample
+
+The assignment @code{*p = 5} may be a definition of @code{a} or
+@code{b}. If we cannot determine statically where @code{p} is
+pointing to at the time of the store operation, we create virtual
+definitions to mark that statement as a potential definition site for
+@code{a} and @code{b}. Memory loads are similarly marked with virtual
+use operands. Virtual operands are shown in tree dumps right before
+the statement that contains them. To request a tree dump with virtual
+operands, use the @option{-vops} option to @option{-fdump-tree}:
+
+@smallexample
+@{
+ int a, b, *p;
+
+ if (...)
+ p = &a;
+ else
+ p = &b;
+ # a = VDEF <a>
+ # b = VDEF <b>
+ *p = 5;
+
+ # VUSE <a>
+ # VUSE <b>
+ return *p;
+@}
+@end smallexample
+
+Notice that @code{VDEF} operands have two copies of the referenced
+variable. This indicates that this is not a killing definition of
+that variable. In this case we refer to it as a @dfn{may definition}
+or @dfn{aliased store}. The presence of the second copy of the
+variable in the @code{VDEF} operand will become important when the
+function is converted into SSA form. This will be used to link all
+the non-killing definitions to prevent optimizations from making
+incorrect assumptions about them.
+
+Operands are collected by @file{tree-ssa-operands.c}. They are stored
+inside each statement's annotation and can be accessed with
+@code{DEF_OPS}, @code{USE_OPS}, @code{VDEF_OPS} and @code{VUSE_OPS}.
+The following are all the accessor macros available to access USE
+operands. To access all the other operand arrays, just change the
+name accordingly:
+
+@defmac USE_OPS (@var{ann})
+Returns the array of operands used by the statement with annotation
+@var{ann}.
+@end defmac
+
+@defmac STMT_USE_OPS (@var{stmt})
+Alternate version of USE_OPS that takes the statement @var{stmt} as
+input.
+@end defmac
+
+@defmac NUM_USES (@var{ops})
+Return the number of USE operands in array @var{ops}.
+@end defmac
+
+@defmac USE_OP_PTR (@var{ops}, @var{i})
+Return a pointer to the @var{i}th operand in array @var{ops}.
+@end defmac
+
+@defmac USE_OP (@var{ops}, @var{i})
+Return the @var{i}th operand in array @var{ops}.
+@end defmac
+
+The following function shows how to print all the operands of a given
+statement:
+
+@smallexample
+void
+print_ops (tree stmt)
+@{
+ vuse_optype vuses;
+ vdef_optype vdefs;
+ def_optype defs;
+ use_optype uses;
+ stmt_ann_t ann;
+ size_t i;
+
+ get_stmt_operands (stmt);
+ ann = stmt_ann (stmt);
+
+ defs = DEF_OPS (ann);
+ for (i = 0; i < NUM_DEFS (defs); i++)
+ print_generic_expr (stderr, DEF_OP (defs, i), 0);
+
+ uses = USE_OPS (ann);
+ for (i = 0; i < NUM_USES (uses); i++)
+ print_generic_expr (stderr, USE_OP (uses, i), 0);
+
+ vdefs = VDEF_OPS (ann);
+ for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ print_generic_expr (stderr, VDEF_OP (vdefs, i), 0);
+
+ vuses = VUSE_OPS (ann);
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ print_generic_expr (stderr, VUSE_OP (vuses, i), 0);
+@}
+@end smallexample
+
+To collect the operands, you first need to call
+@code{get_stmt_operands}. Since that is a potentially expensive
+operation, statements are only scanned if they have been marked
+modified by a call to @code{modify_stmt}. So, if your pass replaces
+operands in a statement, make sure to call @code{modify_stmt}.
+
+
+@node SSA
+@section Static Single Assignment
+@cindex SSA
+@cindex static single assignment
+
+Most of the tree optimizers rely on the data flow information provided
+by the Static Single Assignment (SSA) form. We implement the SSA form
+as described in @cite{R. Cytron, J. Ferrante, B. Rosen, M. Wegman, and
+K. Zadeck. Efficiently Computing Static Single Assignment Form and the
+Control Dependence Graph. ACM Transactions on Programming Languages
+and Systems, 13(4):451-490, October 1991}.
+
+The SSA form is based on the premise that program variables are
+assigned in exactly one location in the program. Multiple assignments
+to the same variable create new versions of that variable. Naturally,
+actual programs are seldom in SSA form initially because variables
+tend to be assigned multiple times. The compiler modifies the program
+representation so that every time a variable is assigned in the code,
+a new version of the variable is created. Different versions of the
+same variable are distinguished by subscripting the variable name with
+its version number. Variables used in the right-hand side of
+expressions are renamed so that their version number matches that of
+the most recent assignment.
+
+We represent variable versions using @code{SSA_NAME} nodes. The
+renaming process in @file{tree-ssa.c} wraps every real and
+virtual operand with an @code{SSA_NAME} node which contains
+the version number and the statement that created the
+@code{SSA_NAME}. Only definitions and virtual definitions may
+create new @code{SSA_NAME} nodes.
+
+Sometimes, flow of control makes it impossible to determine what is the
+most recent version of a variable. In these cases, the compiler
+inserts an artificial definition for that variable called
+@dfn{PHI function} or @dfn{PHI node}. This new definition merges
+all the incoming versions of the variable to create a new name
+for it. For instance,
+
+@smallexample
+if (...)
+ a_1 = 5;
+else if (...)
+ a_2 = 2;
+else
+ a_3 = 13;
+
+# a_4 = PHI <a_1, a_2, a_3>
+return a_4;
+@end smallexample
+
+Since it is not possible to determine which of the three branches
+will be taken at runtime, we don't know which of @code{a_1},
+@code{a_2} or @code{a_3} to use at the return statement. So, the
+SSA renamer creates a new version @code{a_4} which is assigned
+the result of ``merging'' @code{a_1}, @code{a_2} and @code{a_3}.
+Hence, PHI nodes mean ``one of these operands. I don't know
+which''.
+
+The following macros can be used to examine PHI nodes
+
+@defmac PHI_RESULT (@var{phi})
+Returns the @code{SSA_NAME} created by PHI node @var{phi} (i.e.,
+@var{phi}'s LHS).
+@end defmac
+
+@defmac PHI_NUM_ARGS (@var{phi})
+Returns the number of arguments in @var{phi}. This number is exactly
+the number of incoming edges to the basic block holding @var{phi}@.
+@end defmac
+
+@defmac PHI_ARG_ELT (@var{phi}, @var{i})
+Returns a tuple representing the @var{i}th argument of @var{phi}@.
+Each element of this tuple contains an @code{SSA_NAME} @var{var} and
+the incoming edge through which @var{var} flows.
+@end defmac
+
+@defmac PHI_ARG_EDGE (@var{phi}, @var{i})
+Returns the incoming edge for the @var{i}th argument of @var{phi}.
+@end defmac
+
+@defmac PHI_ARG_DEF (@var{phi}, @var{i})
+Returns the @code{SSA_NAME} for the @var{i}th argument of @var{phi}.
+@end defmac
+
+
+@subsection Preserving the SSA form
+@findex vars_to_rename
+@cindex preserving SSA form
+Some optimization passes make changes to the function that
+invalidate the SSA property. This can happen when a pass has
+added new variables or changed the program so that variables that
+were previously aliased aren't anymore.
+
+Whenever something like this happens, the affected variables must
+be renamed into SSA form again. To do this, you should mark the
+new variables in the global bitmap @code{vars_to_rename}. Once
+your pass has finished, the pass manager will invoke the SSA
+renamer to put the program into SSA once more.
+
+@subsection Examining @code{SSA_NAME} nodes
+@cindex examining SSA_NAMEs
+
+The following macros can be used to examine @code{SSA_NAME} nodes
+
+@defmac SSA_NAME_DEF_STMT (@var{var})
+Returns the statement @var{s} that creates the @code{SSA_NAME}
+@var{var}. If @var{s} is an empty statement (i.e., @code{IS_EMPTY_STMT
+(@var{s})} returns @code{true}), it means that the first reference to
+this variable is a USE or a VUSE@.
+@end defmac
+
+@defmac SSA_NAME_VERSION (@var{var})
+Returns the version number of the @code{SSA_NAME} object @var{var}.
+@end defmac
+
+
+@subsection Walking use-def chains
+
+@deftypefn {Tree SSA function} void walk_use_def_chains (@var{var}, @var{fn}, @var{data})
+
+Walks use-def chains starting at the @code{SSA_NAME} node @var{var}.
+Calls function @var{fn} at each reaching definition found. Function
+@var{FN} takes three arguments: @var{var}, its defining statement
+(@var{def_stmt}) and a generic pointer to whatever state information
+that @var{fn} may want to maintain (@var{data}). Function @var{fn} is
+able to stop the walk by returning @code{true}, otherwise in order to
+continue the walk, @var{fn} should return @code{false}.
+
+Note, that if @var{def_stmt} is a @code{PHI} node, the semantics are
+slightly different. For each argument @var{arg} of the PHI node, this
+function will:
+
+@enumerate
+@item Walk the use-def chains for @var{arg}.
+@item Call @code{FN (@var{arg}, @var{phi}, @var{data})}.
+@end enumerate
+
+Note how the first argument to @var{fn} is no longer the original
+variable @var{var}, but the PHI argument currently being examined.
+If @var{fn} wants to get at @var{var}, it should call
+@code{PHI_RESULT} (@var{phi}).
+@end deftypefn
+
+@subsection Walking the dominator tree
+
+@deftypefn {Tree SSA function} void walk_dominator_tree (@var{walk_data}, @var{bb})
+
+This function walks the dominator tree for the current CFG calling a
+set of callback functions defined in @var{struct dom_walk_data} in
+@file{domwalk.h}. The call back functions you need to define give you
+hooks to execute custom code at various points during traversal:
+
+@enumerate
+@item Once to initialize any local data needed while processing
+ @var{bb} and its children. This local data is pushed into an
+ internal stack which is automatically pushed and popped as the
+ walker traverses the dominator tree.
+
+@item Once before traversing all the statements in the @var{bb}.
+
+@item Once for every statement inside @var{bb}.
+
+@item Once after traversing all the statements and before recursing
+ into @var{bb}'s dominator children.
+
+@item It then recurses into all the dominator children of @var{bb}.
+
+@item After recursing into all the dominator children of @var{bb} it
+ can, optionally, traverse every statement in @var{bb} again
+ (i.e., repeating steps 2 and 3).
+
+@item Once after walking the statements in @var{bb} and @var{bb}'s
+ dominator children. At this stage, the block local data stack
+ is popped.
+@end enumerate
+@end deftypefn
+
+@node Alias analysis
+@section Alias analysis
+@cindex alias
+@cindex flow-sensitive alias analysis
+@cindex flow-insensitive alias analysis
+
+Alias analysis proceeds in 3 main phases:
+
+@enumerate
+@item Points-to and escape analysis.
+
+This phase walks the use-def chains in the SSA web looking for
+three things:
+
+ @itemize @bullet
+ @item Assignments of the form @code{P_i = &VAR}
+ @item Assignments of the form P_i = malloc()
+ @item Pointers and ADDR_EXPR that escape the current function.
+ @end itemize
+
+The concept of `escaping' is the same one used in the Java world.
+When a pointer or an ADDR_EXPR escapes, it means that it has been
+exposed outside of the current function. So, assignment to
+global variables, function arguments and returning a pointer are
+all escape sites.
+
+This is where we are currently limited. Since not everything is
+renamed into SSA, we lose track of escape properties when a
+pointer is stashed inside a field in a structure, for instance.
+In those cases, we are assuming that the pointer does escape.
+
+We use escape analysis to determine whether a variable is
+call-clobbered. Simply put, if an ADDR_EXPR escapes, then the
+variable is call-clobbered. If a pointer P_i escapes, then all
+the variables pointed-to by P_i (and its memory tag) also escape.
+
+@item Compute flow-sensitive aliases
+
+We have two classes of memory tags. Memory tags associated with
+the pointed-to data type of the pointers in the program. These
+tags are called ``type memory tag'' (TMT). The other class are
+those associated with SSA_NAMEs, called ``name memory tag'' (NMT).
+The basic idea is that when adding operands for an INDIRECT_REF
+*P_i, we will first check whether P_i has a name tag, if it does
+we use it, because that will have more precise aliasing
+information. Otherwise, we use the standard type tag.
+
+In this phase, we go through all the pointers we found in
+points-to analysis and create alias sets for the name memory tags
+associated with each pointer P_i. If P_i escapes, we mark
+call-clobbered the variables it points to and its tag.
+
+
+@item Compute flow-insensitive aliases
+
+This pass will compare the alias set of every type memory tag and
+every addressable variable found in the program. Given a type
+memory tag TMT and an addressable variable V@. If the alias sets
+of TMT and V conflict (as computed by may_alias_p), then V is
+marked as an alias tag and added to the alias set of TMT@.
+@end enumerate
+
+For instance, consider the following function:
+
+@example
+foo (int i)
+@{
+ int *p, *q, a, b;
+
+ if (i > 10)
+ p = &a;
+ else
+ q = &b;
+
+ *p = 3;
+ *q = 5;
+ a = b + 2;
+ return *p;
+@}
+@end example
+
+After aliasing analysis has finished, the type memory tag for
+pointer @code{p} will have two aliases, namely variables @code{a} and
+@code{b}.
+Every time pointer @code{p} is dereferenced, we want to mark the
+operation as a potential reference to @code{a} and @code{b}.
+
+@example
+foo (int i)
+@{
+ int *p, a, b;
+
+ if (i_2 > 10)
+ p_4 = &a;
+ else
+ p_6 = &b;
+ # p_1 = PHI <p_4(1), p_6(2)>;
+
+ # a_7 = VDEF <a_3>;
+ # b_8 = VDEF <b_5>;
+ *p_1 = 3;
+
+ # a_9 = VDEF <a_7>
+ # VUSE <b_8>
+ a_9 = b_8 + 2;
+
+ # VUSE <a_9>;
+ # VUSE <b_8>;
+ return *p_1;
+@}
+@end example
+
+In certain cases, the list of may aliases for a pointer may grow
+too large. This may cause an explosion in the number of virtual
+operands inserted in the code. Resulting in increased memory
+consumption and compilation time.
+
+When the number of virtual operands needed to represent aliased
+loads and stores grows too large (configurable with @option{--param
+max-aliased-vops}), alias sets are grouped to avoid severe
+compile-time slow downs and memory consumption. The alias
+grouping heuristic proceeds as follows:
+
+@enumerate
+@item Sort the list of pointers in decreasing number of contributed
+virtual operands.
+
+@item Take the first pointer from the list and reverse the role
+of the memory tag and its aliases. Usually, whenever an
+aliased variable Vi is found to alias with a memory tag
+T, we add Vi to the may-aliases set for T@. Meaning that
+after alias analysis, we will have:
+
+@smallexample
+may-aliases(T) = @{ V1, V2, V3, ..., Vn @}
+@end smallexample
+
+This means that every statement that references T, will get
+@code{n} virtual operands for each of the Vi tags. But, when
+alias grouping is enabled, we make T an alias tag and add it
+to the alias set of all the Vi variables:
+
+@smallexample
+may-aliases(V1) = @{ T @}
+may-aliases(V2) = @{ T @}
+...
+may-aliases(Vn) = @{ T @}
+@end smallexample
+
+This has two effects: (a) statements referencing T will only get
+a single virtual operand, and, (b) all the variables Vi will now
+appear to alias each other. So, we lose alias precision to
+improve compile time. But, in theory, a program with such a high
+level of aliasing should not be very optimizable in the first
+place.
+
+@item Since variables may be in the alias set of more than one
+memory tag, the grouping done in step (2) needs to be extended
+to all the memory tags that have a non-empty intersection with
+the may-aliases set of tag T@. For instance, if we originally
+had these may-aliases sets:
+
+@smallexample
+may-aliases(T) = @{ V1, V2, V3 @}
+may-aliases(R) = @{ V2, V4 @}
+@end smallexample
+
+In step (2) we would have reverted the aliases for T as:
+
+@smallexample
+may-aliases(V1) = @{ T @}
+may-aliases(V2) = @{ T @}
+may-aliases(V3) = @{ T @}
+@end smallexample
+
+But note that now V2 is no longer aliased with R@. We could
+add R to may-aliases(V2), but we are in the process of
+grouping aliases to reduce virtual operands so what we do is
+add V4 to the grouping to obtain:
+
+@smallexample
+may-aliases(V1) = @{ T @}
+may-aliases(V2) = @{ T @}
+may-aliases(V3) = @{ T @}
+may-aliases(V4) = @{ T @}
+@end smallexample
+
+@item If the total number of virtual operands due to aliasing is
+still above the threshold set by max-alias-vops, go back to (2).
+@end enumerate
diff --git a/gcc/dojump.c b/gcc/dojump.c
index eb98e76e4a8..7f76c5e752f 100644
--- a/gcc/dojump.c
+++ b/gcc/dojump.c
@@ -820,7 +820,6 @@ rtx
compare_from_rtx (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
enum machine_mode mode, rtx size)
{
- enum rtx_code ucode;
rtx tem;
/* If one operand is constant, make it the second one. Only do this
@@ -842,32 +841,19 @@ compare_from_rtx (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
do_pending_stack_adjust ();
- ucode = unsignedp ? unsigned_condition (code) : code;
- tem = simplify_const_relational_operation (ucode, mode, op0, op1);
- if (tem != 0)
- return tem;
-
-#if 0
- /* There's no need to do this now that combine.c can eliminate lots of
- sign extensions. This can be less efficient in certain cases on other
- machines. */
-
- /* If this is a signed equality comparison, we can do it as an
- unsigned comparison since zero-extension is cheaper than sign
- extension and comparisons with zero are done as unsigned. This is
- the case even on machines that can do fast sign extension, since
- zero-extension is easier to combine with other operations than
- sign-extension is. If we are comparing against a constant, we must
- convert it to what it would look like unsigned. */
- if ((code == EQ || code == NE) && ! unsignedp
- && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT)
+ code = unsignedp ? unsigned_condition (code) : code;
+ if (0 != (tem = simplify_relational_operation (code, mode, VOIDmode,
+ op0, op1)))
{
- if (GET_CODE (op1) == CONST_INT
- && (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0))) != INTVAL (op1))
- op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0)));
- unsignedp = 1;
+ if (CONSTANT_P (tem))
+ return tem;
+
+ code = GET_CODE (tem);
+ mode = GET_MODE (tem);
+ op0 = XEXP (tem, 0);
+ op1 = XEXP (tem, 1);
+ unsignedp = (code == GTU || code == LTU || code == GEU || code == LEU);
}
-#endif
emit_cmp_insn (op0, op1, code, size, mode, unsignedp);
@@ -889,7 +875,6 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
enum machine_mode mode, rtx size, rtx if_false_label,
rtx if_true_label)
{
- enum rtx_code ucode;
rtx tem;
int dummy_true_label = 0;
@@ -921,44 +906,25 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
do_pending_stack_adjust ();
- ucode = unsignedp ? unsigned_condition (code) : code;
- tem = simplify_const_relational_operation (ucode, mode, op0, op1);
- if (tem != 0)
+ code = unsignedp ? unsigned_condition (code) : code;
+ if (0 != (tem = simplify_relational_operation (code, mode, VOIDmode,
+ op0, op1)))
{
- if (tem == const_true_rtx)
- {
- if (if_true_label)
- emit_jump (if_true_label);
- }
- else
- {
- if (if_false_label)
- emit_jump (if_false_label);
- }
- return;
- }
+ if (CONSTANT_P (tem))
+ {
+ rtx label = (tem == const0_rtx || tem == CONST0_RTX (mode))
+ ? if_false_label : if_true_label;
+ if (label)
+ emit_jump (label);
+ return;
+ }
-#if 0
- /* There's no need to do this now that combine.c can eliminate lots of
- sign extensions. This can be less efficient in certain cases on other
- machines. */
-
- /* If this is a signed equality comparison, we can do it as an
- unsigned comparison since zero-extension is cheaper than sign
- extension and comparisons with zero are done as unsigned. This is
- the case even on machines that can do fast sign extension, since
- zero-extension is easier to combine with other operations than
- sign-extension is. If we are comparing against a constant, we must
- convert it to what it would look like unsigned. */
- if ((code == EQ || code == NE) && ! unsignedp
- && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT)
- {
- if (GET_CODE (op1) == CONST_INT
- && (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0))) != INTVAL (op1))
- op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0)));
- unsignedp = 1;
+ code = GET_CODE (tem);
+ mode = GET_MODE (tem);
+ op0 = XEXP (tem, 0);
+ op1 = XEXP (tem, 1);
+ unsignedp = (code == GTU || code == LTU || code == GEU || code == LEU);
}
-#endif
if (! if_true_label)
{
diff --git a/gcc/dominance.c b/gcc/dominance.c
index 793820557fe..86f0191eb4f 100644
--- a/gcc/dominance.c
+++ b/gcc/dominance.c
@@ -118,6 +118,9 @@ static void link_roots (struct dom_info *, TBB, TBB);
static void calc_idoms (struct dom_info *, enum cdi_direction);
void debug_dominance_info (enum cdi_direction);
+/* Keeps track of the*/
+static unsigned n_bbs_in_dom_tree[2];
+
/* Helper macro for allocating and initializing an array,
for aesthetic reasons. */
#define init_ar(var, type, num, content) \
@@ -531,7 +534,7 @@ assign_dfs_numbers (struct et_node *node, int *num)
{
assign_dfs_numbers (node->son, num);
for (son = node->son->right; son != node->son; son = son->right)
- assign_dfs_numbers (son, num);
+ assign_dfs_numbers (son, num);
}
node->dfs_num_out = (*num)++;
@@ -555,7 +558,7 @@ compute_dom_fast_query (enum cdi_direction dir)
FOR_ALL_BB (bb)
{
if (!bb->dom[dir]->father)
- assign_dfs_numbers (bb->dom[dir], &num);
+ assign_dfs_numbers (bb->dom[dir], &num);
}
dom_computed[dir] = DOM_OK;
@@ -576,12 +579,16 @@ calculate_dominance_info (enum cdi_direction dir)
if (dom_computed[dir] != DOM_NO_FAST_QUERY)
{
if (dom_computed[dir] != DOM_NONE)
- free_dominance_info (dir);
+ free_dominance_info (dir);
+
+ if (n_bbs_in_dom_tree[dir])
+ abort ();
FOR_ALL_BB (b)
{
b->dom[dir] = et_new_tree (b);
}
+ n_bbs_in_dom_tree[dir] = n_basic_blocks + 2;
init_dom_info (&di);
calc_dfs_tree (&di, dir);
@@ -616,6 +623,10 @@ free_dominance_info (enum cdi_direction dir)
delete_from_dominance_info (dir, bb);
}
+ /* If there are any nodes left, something is wrong. */
+ if (n_bbs_in_dom_tree[dir])
+ abort ();
+
dom_computed[dir] = DOM_NONE;
}
@@ -631,7 +642,7 @@ get_immediate_dominator (enum cdi_direction dir, basic_block bb)
if (!node->father)
return NULL;
- return node->father->data;
+ return node->father->data;
}
/* Set the immediate dominator of the block possibly removing
@@ -648,7 +659,7 @@ set_immediate_dominator (enum cdi_direction dir, basic_block bb,
if (node->father)
{
if (node->father->data == dominated_by)
- return;
+ return;
et_split (node);
}
@@ -730,7 +741,7 @@ nearest_common_dominator (enum cdi_direction dir, basic_block bb1, basic_block b
/* Return TRUE in case BB1 is dominated by BB2. */
bool
dominated_by_p (enum cdi_direction dir, basic_block bb1, basic_block bb2)
-{
+{
struct et_node *n1 = bb1->dom[dir], *n2 = bb2->dom[dir];
if (!dom_computed[dir])
@@ -738,7 +749,7 @@ dominated_by_p (enum cdi_direction dir, basic_block bb1, basic_block bb2)
if (dom_computed[dir] == DOM_OK)
return (n1->dfs_num_in >= n2->dfs_num_in
- && n1->dfs_num_out <= n2->dfs_num_out);
+ && n1->dfs_num_out <= n2->dfs_num_out);
return et_below (n1, n2);
}
@@ -839,6 +850,8 @@ add_to_dominance_info (enum cdi_direction dir, basic_block bb)
if (bb->dom[dir])
abort ();
+ n_bbs_in_dom_tree[dir]++;
+
bb->dom[dir] = et_new_tree (bb);
if (dom_computed[dir] == DOM_OK)
@@ -853,6 +866,7 @@ delete_from_dominance_info (enum cdi_direction dir, basic_block bb)
et_free_tree (bb->dom[dir]);
bb->dom[dir] = NULL;
+ n_bbs_in_dom_tree[dir]--;
if (dom_computed[dir] == DOM_OK)
dom_computed[dir] = DOM_NO_FAST_QUERY;
diff --git a/gcc/domwalk.c b/gcc/domwalk.c
new file mode 100644
index 00000000000..ce0ccd113e4
--- /dev/null
+++ b/gcc/domwalk.c
@@ -0,0 +1,265 @@
+/* Generic dominator tree walker
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Diego Novillo <dnovillo@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "basic-block.h"
+#include "tree-flow.h"
+#include "domwalk.h"
+#include "ggc.h"
+
+/* This file implements a generic walker for dominator trees.
+
+ To understand the dominator walker one must first have a grasp of dominators,
+ immediate dominators and the dominator tree.
+
+ Dominators
+ A block B1 is said to dominate B2 if every path from the entry to B2 must
+ pass through B1. Given the dominance relationship, we can proceed to
+ compute immediate dominators. Note it is not important whether or not
+ our definition allows a block to dominate itself.
+
+ Immediate Dominators:
+ Every block in the CFG has no more than one immediate dominator. The
+ immediate dominator of block BB must dominate BB and must not dominate
+ any other dominator of BB and must not be BB itself.
+
+ Dominator tree:
+ If we then construct a tree where each node is a basic block and there
+ is an edge from each block's immediate dominator to the block itself, then
+ we have a dominator tree.
+
+
+ [ Note this walker can also walk the post-dominator tree, which is
+ defined in a similar manner. ie, block B1 is said to post-dominate
+ block B2 if all paths from B2 to the exit block must pass through
+ B1. ]
+
+ For example, given the CFG
+
+ 1
+ |
+ 2
+ / \
+ 3 4
+ / \
+ +---------->5 6
+ | / \ /
+ | +--->8 7
+ | | / |
+ | +--9 11
+ | / |
+ +--- 10 ---> 12
+
+
+ We have a dominator tree which looks like
+
+ 1
+ |
+ 2
+ / \
+ / \
+ 3 4
+ / / \ \
+ | | | |
+ 5 6 7 12
+ | |
+ 8 11
+ |
+ 9
+ |
+ 10
+
+
+
+ The dominator tree is the basis for a number of analysis, transformation
+ and optimization algorithms that operate on a semi-global basis.
+
+ The dominator walker is a generic routine which visits blocks in the CFG
+ via a depth first search of the dominator tree. In the example above
+ the dominator walker might visit blocks in the following order
+ 1, 2, 3, 4, 5, 8, 9, 10, 6, 7, 11, 12.
+
+ The dominator walker has a number of callbacks to perform actions
+ during the walk of the dominator tree. There are two callbacks
+ which walk statements, one before visiting the dominator children,
+ one after visiting the dominator children. There is a callback
+ before and after each statement walk callback. In addition, the
+ dominator walker manages allocation/deallocation of data structures
+ which are local to each block visited.
+
+ The dominator walker is meant to provide a generic means to build a pass
+ which can analyze or transform/optimize a function based on walking
+ the dominator tree. One simply fills in the dominator walker data
+ structure with the appropriate callbacks and calls the walker.
+
+ We currently use the dominator walker to prune the set of variables
+ which might need PHI nodes (which can greatly improve compile-time
+ performance in some cases).
+
+ We also use the dominator walker to rewrite the function into SSA form
+ which reduces code duplication since the rewriting phase is inherently
+ a walk of the dominator tree.
+
+ And (of course), we use the dominator walker to drive a our dominator
+ optimizer, which is a semi-global optimizer.
+
+ TODO:
+
+ Walking statements is based on the block statement iterator abstraction,
+ which is currently an abstraction over walking tree statements. Thus
+ the dominator walker is currently only useful for trees. */
+
+/* Recursively walk the dominator tree.
+
+ WALK_DATA contains a set of callbacks to perform pass-specific
+ actions during the dominator walk as well as a stack of block local
+ data maintained during the dominator walk.
+
+ BB is the basic block we are currently visiting. */
+
+void
+walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
+{
+ void *bd = NULL;
+ basic_block dest;
+ block_stmt_iterator bsi;
+
+ /* Callback to initialize the local data structure. */
+ if (walk_data->initialize_block_local_data)
+ {
+ bool recycled;
+
+ /* First get some local data, reusing any local data pointer we may
+ have saved. */
+ if (VARRAY_ACTIVE_SIZE (walk_data->free_block_data) > 0)
+ {
+ bd = VARRAY_TOP_GENERIC_PTR (walk_data->free_block_data);
+ VARRAY_POP (walk_data->free_block_data);
+ recycled = 1;
+ }
+ else
+ {
+ bd = xcalloc (1, walk_data->block_local_data_size);
+ recycled = 0;
+ }
+
+ /* Push the local data into the local data stack. */
+ VARRAY_PUSH_GENERIC_PTR (walk_data->block_data_stack, bd);
+
+ /* Call the initializer. */
+ walk_data->initialize_block_local_data (walk_data, bb, recycled);
+
+ }
+
+ /* Callback for operations to execute before we have walked the
+ dominator children, but before we walk statements. */
+ if (walk_data->before_dom_children_before_stmts)
+ (*walk_data->before_dom_children_before_stmts) (walk_data, bb);
+
+ /* Statement walk before walking dominator children. */
+ if (walk_data->before_dom_children_walk_stmts)
+ {
+ if (walk_data->walk_stmts_backward)
+ for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
+ (*walk_data->before_dom_children_walk_stmts) (walk_data, bb, bsi);
+ else
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ (*walk_data->before_dom_children_walk_stmts) (walk_data, bb, bsi);
+ }
+
+ /* Callback for operations to execute before we have walked the
+ dominator children, and after we walk statements. */
+ if (walk_data->before_dom_children_after_stmts)
+ (*walk_data->before_dom_children_after_stmts) (walk_data, bb);
+
+ /* Recursively call ourselves on the dominator children of BB. */
+ for (dest = first_dom_son (walk_data->dom_direction, bb);
+ dest;
+ dest = next_dom_son (walk_data->dom_direction, dest))
+ {
+ /* The destination block may have become unreachable, in
+ which case there's no point in optimizing it. */
+ if (dest->pred)
+ walk_dominator_tree (walk_data, dest);
+ }
+
+ /* Callback for operations to execute after we have walked the
+ dominator children, but before we walk statements. */
+ if (walk_data->after_dom_children_before_stmts)
+ (*walk_data->after_dom_children_before_stmts) (walk_data, bb);
+
+ /* Statement walk after walking dominator children. */
+ if (walk_data->after_dom_children_walk_stmts)
+ {
+ if (walk_data->walk_stmts_backward)
+ for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
+ (*walk_data->after_dom_children_walk_stmts) (walk_data, bb, bsi);
+ else
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ (*walk_data->after_dom_children_walk_stmts) (walk_data, bb, bsi);
+ }
+
+ /* Callback for operations to execute after we have walked the
+ dominator children and after we have walked statements. */
+ if (walk_data->after_dom_children_after_stmts)
+ (*walk_data->after_dom_children_after_stmts) (walk_data, bb);
+
+ if (walk_data->initialize_block_local_data)
+ {
+ /* And save the block data so that we can re-use it. */
+ VARRAY_PUSH_GENERIC_PTR (walk_data->free_block_data, bd);
+
+ /* And finally pop the record off the block local data stack. */
+ VARRAY_POP (walk_data->block_data_stack);
+ }
+}
+
+void
+init_walk_dominator_tree (struct dom_walk_data *walk_data)
+{
+ if (walk_data->initialize_block_local_data)
+ {
+ VARRAY_GENERIC_PTR_INIT (walk_data->free_block_data, 2, "freelist ");
+ VARRAY_GENERIC_PTR_INIT (walk_data->block_data_stack, 2, "block_data");
+ }
+ else
+ {
+ walk_data->free_block_data = NULL;
+ walk_data->block_data_stack = NULL;
+ }
+}
+
+void
+fini_walk_dominator_tree (struct dom_walk_data *walk_data)
+{
+ if (walk_data->initialize_block_local_data)
+ {
+ while (VARRAY_ACTIVE_SIZE (walk_data->free_block_data) > 0)
+ {
+ free (VARRAY_TOP_GENERIC_PTR (walk_data->free_block_data));
+ VARRAY_POP (walk_data->free_block_data);
+ }
+ }
+}
diff --git a/gcc/domwalk.h b/gcc/domwalk.h
new file mode 100644
index 00000000000..2c2138a9199
--- /dev/null
+++ b/gcc/domwalk.h
@@ -0,0 +1,112 @@
+/* Generic dominator tree walker
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Diego Novillo <dnovillo@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* This is the main data structure for the dominator walker. It provides
+ the callback hooks as well as a convenient place to hang block local
+ data and pass-global data. */
+
+struct dom_walk_data
+{
+ /* This is the direction of the dominator tree we want to walk. ie,
+ if it is set to CDI_DOMINATORS, then we walk the dominator tree,
+ if it is set to CDI_POST_DOMINATORS, then we walk the post
+ dominator tree. */
+ ENUM_BITFIELD (cdi_direction) dom_direction : 2;
+
+ /* Nonzero if the statement walker should walk the statements from
+ last to first within a basic block instead of first to last.
+
+ Note this affects both statement walkers. We haven't yet needed
+ to use the second statement walker for anything, so it's hard to
+ predict if we really need the ability to select their direction
+ independently. */
+ bool walk_stmts_backward : 1;
+
+ /* Function to initialize block local data.
+
+ Note that the dominator walker infrastructure may provide a new
+ fresh, and zero'd block local data structure, or it may re-use an
+ existing block local data structure.
+
+ If the block local structure has items such as virtual arrays, then
+ that allows your optimizer to re-use those arrays rather than
+ creating new ones. */
+ void (*initialize_block_local_data) (struct dom_walk_data *,
+ basic_block, bool);
+
+ /* Function to call before the statement walk occurring before the
+ recursive walk of the dominator children.
+
+ This typically initializes an block local data and pushes that
+ data onto BLOCK_DATA_STACK. */
+ void (*before_dom_children_before_stmts) (struct dom_walk_data *,
+ basic_block);
+
+ /* Function to call to walk statements before the recursive walk
+ of the dominator children. */
+ void (*before_dom_children_walk_stmts) (struct dom_walk_data *,
+ basic_block, block_stmt_iterator);
+
+ /* Function to call after the statement walk occurring before the
+ recursive walk of the dominator children. */
+ void (*before_dom_children_after_stmts) (struct dom_walk_data *,
+ basic_block);
+
+ /* Function to call before the statement walk occurring after the
+ recursive walk of the dominator children. */
+ void (*after_dom_children_before_stmts) (struct dom_walk_data *,
+ basic_block);
+
+ /* Function to call to walk statements after the recursive walk
+ of the dominator children. */
+ void (*after_dom_children_walk_stmts) (struct dom_walk_data *,
+ basic_block, block_stmt_iterator);
+
+ /* Function to call after the statement walk occurring after the
+ recursive walk of the dominator children.
+
+ This typically finalizes any block local data and pops
+ that data from BLOCK_DATA_STACK. */
+ void (*after_dom_children_after_stmts) (struct dom_walk_data *,
+ basic_block);
+
+ /* Global data for a walk through the dominator tree. */
+ void *global_data;
+
+ /* Stack of any data we need to keep on a per-block basis.
+
+ If you have no local data, then BLOCK_DATA_STACK will be NULL. */
+ varray_type block_data_stack;
+
+ /* Size of the block local data. If this is zero, then it is assumed
+ you have no local data and thus no BLOCK_DATA_STACK as well. */
+ size_t block_local_data_size;
+
+ /* From here below are private data. Please do not use this
+ information/data outside domwalk.c. */
+
+ /* Stack of available block local structures. */
+ varray_type free_block_data;
+};
+
+void walk_dominator_tree (struct dom_walk_data *, basic_block);
+void init_walk_dominator_tree (struct dom_walk_data *);
+void fini_walk_dominator_tree (struct dom_walk_data *);
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 86512a4f8f5..cfedd13bd28 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -3785,7 +3785,7 @@ static bool is_subrange_type (tree);
static dw_die_ref subrange_type_die (tree, dw_die_ref);
static dw_die_ref modified_type_die (tree, int, int, dw_die_ref);
static int type_is_enum (tree);
-static unsigned int reg_number (rtx);
+static unsigned int dbx_reg_number (rtx);
static dw_loc_descr_ref reg_loc_descriptor (rtx);
static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int);
static dw_loc_descr_ref multiple_reg_loc_descriptor (rtx, rtx);
@@ -5070,7 +5070,9 @@ is_fortran (void)
{
unsigned int lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
- return lang == DW_LANG_Fortran77 || lang == DW_LANG_Fortran90;
+ return (lang == DW_LANG_Fortran77
+ || lang == DW_LANG_Fortran90
+ || lang == DW_LANG_Fortran95);
}
/* Return TRUE if the language is Java. */
@@ -8240,10 +8242,10 @@ type_is_enum (tree type)
return TREE_CODE (type) == ENUMERAL_TYPE;
}
-/* Return the register number described by a given RTL node. */
+/* Return the DBX register number described by a given RTL node. */
static unsigned int
-reg_number (rtx rtl)
+dbx_reg_number (rtx rtl)
{
unsigned regno = REGNO (rtl);
@@ -8265,10 +8267,10 @@ reg_loc_descriptor (rtx rtl)
if (REGNO (rtl) >= FIRST_PSEUDO_REGISTER)
return 0;
- reg = reg_number (rtl);
+ reg = dbx_reg_number (rtl);
regs = targetm.dwarf_register_span (rtl);
- if (hard_regno_nregs[reg][GET_MODE (rtl)] > 1
+ if (hard_regno_nregs[REGNO (rtl)][GET_MODE (rtl)] > 1
|| regs)
return multiple_reg_loc_descriptor (rtl, regs);
else
@@ -8297,8 +8299,8 @@ multiple_reg_loc_descriptor (rtx rtl, rtx regs)
unsigned reg;
dw_loc_descr_ref loc_result = NULL;
- reg = reg_number (rtl);
- nregs = hard_regno_nregs[reg][GET_MODE (rtl)];
+ reg = dbx_reg_number (rtl);
+ nregs = hard_regno_nregs[REGNO (rtl)][GET_MODE (rtl)];
/* Simple, contiguous registers. */
if (regs == NULL_RTX)
@@ -8435,6 +8437,7 @@ static dw_loc_descr_ref
mem_loc_descriptor (rtx rtl, enum machine_mode mode, bool can_use_fbreg)
{
dw_loc_descr_ref mem_loc_result = NULL;
+ enum dwarf_location_atom op;
/* Note that for a dynamically sized array, the location we will generate a
description of here will be the lowest numbered location which is
@@ -8478,7 +8481,8 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode, bool can_use_fbreg)
memory) so DWARF consumers need to be aware of the subtle
distinction between OP_REG and OP_BASEREG. */
if (REGNO (rtl) < FIRST_PSEUDO_REGISTER)
- mem_loc_result = based_loc_descr (reg_number (rtl), 0, can_use_fbreg);
+ mem_loc_result = based_loc_descr (dbx_reg_number (rtl), 0,
+ can_use_fbreg);
break;
case MEM:
@@ -8549,7 +8553,7 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode, bool can_use_fbreg)
case PLUS:
plus:
if (is_based_loc (rtl))
- mem_loc_result = based_loc_descr (reg_number (XEXP (rtl, 0)),
+ mem_loc_result = based_loc_descr (dbx_reg_number (XEXP (rtl, 0)),
INTVAL (XEXP (rtl, 1)),
can_use_fbreg);
else
@@ -8575,10 +8579,26 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode, bool can_use_fbreg)
}
break;
+ /* If a pseudo-reg is optimized away, it is possible for it to
+ be replaced with a MEM containing a multiply or shift. */
case MULT:
+ op = DW_OP_mul;
+ goto do_binop;
+
+ case ASHIFT:
+ op = DW_OP_shl;
+ goto do_binop;
+
+ case ASHIFTRT:
+ op = DW_OP_shra;
+ goto do_binop;
+
+ case LSHIFTRT:
+ op = DW_OP_shr;
+ goto do_binop;
+
+ do_binop:
{
- /* If a pseudo-reg is optimized away, it is possible for it to
- be replaced with a MEM containing a multiply. */
dw_loc_descr_ref op0 = mem_loc_descriptor (XEXP (rtl, 0), mode,
can_use_fbreg);
dw_loc_descr_ref op1 = mem_loc_descriptor (XEXP (rtl, 1), mode,
@@ -8589,7 +8609,7 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode, bool can_use_fbreg)
mem_loc_result = op0;
add_loc_descr (&mem_loc_result, op1);
- add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_mul, 0, 0));
+ add_loc_descr (&mem_loc_result, new_loc_descr (op, 0, 0));
break;
}
@@ -8811,6 +8831,7 @@ loc_descriptor_from_tree (tree loc, int addressp)
/* Fall through. */
case PARM_DECL:
+ case RESULT_DECL:
{
rtx rtl = rtl_for_decl_location (loc);
@@ -9099,9 +9120,6 @@ loc_descriptor_from_tree (tree loc, int addressp)
}
break;
- case EXPR_WITH_FILE_LOCATION:
- return loc_descriptor_from_tree (EXPR_WFL_NODE (loc), addressp);
-
default:
/* Leave front-end specific codes as simply unknown. This comes
up, for instance, with the C STMT_EXPR. */
@@ -9678,10 +9696,7 @@ rtl_for_decl_location (tree decl)
This happens (for example) for inlined-instances of inline function formal
parameters which are never referenced. This really shouldn't be
happening. All PARM_DECL nodes should get valid non-NULL
- DECL_INCOMING_RTL values, but integrate.c doesn't currently generate these
- values for inlined instances of inline function parameters, so when we see
- such cases, we are just out-of-luck for the time being (until integrate.c
- gets fixed). */
+ DECL_INCOMING_RTL values. FIXME. */
/* Use DECL_RTL as the "location" unless we find something better. */
rtl = DECL_RTL_IF_SET (decl);
@@ -9756,6 +9771,25 @@ rtl_for_decl_location (tree decl)
plus_constant (XEXP (rtl, 0), offset));
}
}
+ else if (TREE_CODE (decl) == VAR_DECL
+ && rtl
+ && GET_CODE (rtl) == MEM
+ && GET_MODE (rtl) != TYPE_MODE (TREE_TYPE (decl))
+ && BYTES_BIG_ENDIAN)
+ {
+ int rsize = GET_MODE_SIZE (GET_MODE (rtl));
+ int dsize = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (decl)));
+
+ /* If a variable is declared "register" yet is smaller than
+ a register, then if we store the variable to memory, it
+ looks like we're storing a register-sized value, when in
+ fact we are not. We need to adjust the offset of the
+ storage location to reflect the actual value's bytes,
+ else gdb will not be able to display it. */
+ if (rsize > dsize)
+ rtl = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (decl)),
+ plus_constant (XEXP (rtl, 0), rsize-dsize));
+ }
if (rtl != NULL_RTX)
{
@@ -9838,7 +9872,8 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
if (TREE_CODE (decl) == ERROR_MARK)
return;
- else if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != PARM_DECL)
+ else if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != PARM_DECL
+ && TREE_CODE (decl) != RESULT_DECL)
abort ();
/* See if we possibly have multiple locations for this variable. */
@@ -10146,6 +10181,7 @@ add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, tree b
case VAR_DECL:
case PARM_DECL:
+ case RESULT_DECL:
{
dw_die_ref decl_die = lookup_decl_die (bound);
@@ -11306,13 +11342,9 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
add_AT_loc (subr_die, DW_AT_frame_base, reg_loc_descriptor (fp_reg));
}
-#if 0
- /* ??? This fails for nested inline functions, because context_display
- is not part of the state saved/restored for inline functions. */
- if (current_function_needs_context)
+ if (cfun->static_chain_decl)
add_AT_location_description (subr_die, DW_AT_static_link,
- loc_descriptor (lookup_static_chain (decl)));
-#endif
+ loc_descriptor_from_tree (cfun->static_chain_decl, 0));
}
/* Now output descriptions of the arguments for this function. This gets
@@ -11388,6 +11420,10 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
constructor function. */
if (! declaration && TREE_CODE (outer_scope) != ERROR_MARK)
{
+ /* Emit a DW_TAG_variable DIE for a named return value. */
+ if (DECL_NAME (DECL_RESULT (decl)))
+ gen_decl_die (DECL_RESULT (decl), subr_die);
+
current_function_has_inlines = 0;
decls_for_scope (outer_scope, subr_die, 0);
@@ -11732,6 +11768,8 @@ gen_compile_unit_die (const char *filename)
language = DW_LANG_Ada95;
else if (strcmp (language_string, "GNU F77") == 0)
language = DW_LANG_Fortran77;
+ else if (strcmp (language_string, "GNU F95") == 0)
+ language = DW_LANG_Fortran95;
else if (strcmp (language_string, "GNU Pascal") == 0)
language = DW_LANG_Pascal83;
else if (strcmp (language_string, "GNU Java") == 0)
@@ -12541,6 +12579,14 @@ gen_decl_die (tree decl, dw_die_ref context_die)
&& (current_function_decl == NULL_TREE || DECL_ARTIFICIAL (decl)))
break;
+#if 0
+ /* FIXME */
+ /* This doesn't work because the C frontend sets DECL_ABSTRACT_ORIGIN
+ on local redeclarations of global functions. That seems broken. */
+ if (current_function_decl != decl)
+ /* This is only a declaration. */;
+#endif
+
/* If we're emitting a clone, emit info for the abstract instance. */
if (DECL_ORIGIN (decl) != decl)
dwarf2out_abstract_function (DECL_ABSTRACT_ORIGIN (decl));
@@ -12614,6 +12660,7 @@ gen_decl_die (tree decl, dw_die_ref context_die)
break;
case VAR_DECL:
+ case RESULT_DECL:
/* If we are in terse mode, don't generate any DIEs to represent any
variable declarations or definitions. */
if (debug_info_level <= DINFO_LEVEL_TERSE)
@@ -12744,8 +12791,8 @@ dwarf2out_imported_module_or_decl (tree decl, tree context)
else
scope_die = force_decl_die (context);
- /* For TYPE_DECL, lookup TREE_TYPE. */
- if (TREE_CODE (decl) == TYPE_DECL)
+ /* For TYPE_DECL or CONST_DECL, lookup TREE_TYPE. */
+ if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == CONST_DECL)
at_import_die = force_type_die (TREE_TYPE (decl));
else
at_import_die = force_decl_die (decl);
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 9a5533ce14e..ba8a3d6cf24 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -929,6 +929,17 @@ get_first_label_num (void)
{
return first_label_num;
}
+
+/* If the rtx for label was created during the expansion of a nested
+ function, then first_label_num won't include this label number.
+ Fix this now so that array indicies work later. */
+
+void
+maybe_set_first_label_num (rtx x)
+{
+ if (CODE_LABEL_NUMBER (x) < first_label_num)
+ first_label_num = CODE_LABEL_NUMBER (x);
+}
/* Return the final regno of X, which is a SUBREG of a hard
register. */
@@ -2387,8 +2398,8 @@ copy_most_rtx (rtx orig, rtx may_share)
RTX_FLAG (copy, in_struct) = RTX_FLAG (orig, in_struct);
RTX_FLAG (copy, volatil) = RTX_FLAG (orig, volatil);
RTX_FLAG (copy, unchanging) = RTX_FLAG (orig, unchanging);
- RTX_FLAG (copy, integrated) = RTX_FLAG (orig, integrated);
RTX_FLAG (copy, frame_related) = RTX_FLAG (orig, frame_related);
+ RTX_FLAG (copy, return_val) = RTX_FLAG (orig, return_val);
format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
@@ -2960,8 +2971,7 @@ next_real_insn (rtx insn)
while (insn)
{
insn = NEXT_INSN (insn);
- if (insn == 0 || GET_CODE (insn) == INSN
- || GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN)
+ if (insn == 0 || INSN_P (insn))
break;
}
@@ -2978,8 +2988,7 @@ prev_real_insn (rtx insn)
while (insn)
{
insn = PREV_INSN (insn);
- if (insn == 0 || GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
- || GET_CODE (insn) == JUMP_INSN)
+ if (insn == 0 || INSN_P (insn))
break;
}
diff --git a/gcc/et-forest.c b/gcc/et-forest.c
index e65ccda6005..9b0997188bd 100644
--- a/gcc/et-forest.c
+++ b/gcc/et-forest.c
@@ -206,9 +206,13 @@ et_check_tree_sanity (struct et_occ *occ)
/* For recording the paths. */
+/* An ad-hoc constant; if the function has more blocks, this won't work,
+ but since it is used for debugging only, it does not matter. */
+#define MAX_NODES 100000
+
static int len;
-static void *datas[100000];
-static int depths[100000];
+static void *datas[MAX_NODES];
+static int depths[MAX_NODES];
/* Records the path represented by OCC, with depth incremented by DEPTH. */
@@ -228,6 +232,10 @@ record_path_before_1 (struct et_occ *occ, int depth)
}
fprintf (stderr, "%d (%d); ", ((basic_block) occ->of->data)->index, depth);
+
+ if (len >= MAX_NODES)
+ abort ();
+
depths[len] = depth;
datas[len] = occ->of;
len++;
diff --git a/gcc/except.c b/gcc/except.c
index 36e3f43dca0..2dfd073e70a 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -134,7 +134,7 @@ struct eh_region GTY(())
/* Each region does exactly one thing. */
enum eh_region_type
- {
+ {
ERT_UNKNOWN = 0,
ERT_CLEANUP,
ERT_TRY,
@@ -195,6 +195,7 @@ struct eh_region GTY(())
/* Entry point for this region's handler before landing pads are built. */
rtx label;
+ tree tree_label;
/* Entry point for this region's handler from the runtime eh library. */
rtx landing_pad;
@@ -264,9 +265,6 @@ static tree lookup_type_for_runtime (tree);
static struct eh_region *expand_eh_region_end (void);
-static rtx get_exception_filter (struct function *);
-
-static void collect_eh_region_array (void);
static void resolve_fixup_regions (void);
static void remove_fixup_regions (void);
static void remove_unreachable_regions (rtx);
@@ -302,8 +300,6 @@ static void remove_exception_handler_label (rtx);
static void remove_eh_handler (struct eh_region *);
static int for_each_eh_label_1 (void **, void *);
-struct reachable_info;
-
/* The return value of reachable_next_level. */
enum reachable_code
{
@@ -317,9 +313,7 @@ enum reachable_code
RNL_BLOCKED
};
-static int check_handled (tree, tree);
-static void add_reachable_handler (struct reachable_info *,
- struct eh_region *, struct eh_region *);
+struct reachable_info;
static enum reachable_code reachable_next_level (struct eh_region *, tree,
struct reachable_info *);
@@ -461,6 +455,128 @@ init_eh_for_function (void)
cfun->eh = ggc_alloc_cleared (sizeof (struct eh_status));
}
+/* Routines to generate the exception tree somewhat directly.
+ These are used from tree-eh.c when processing exception related
+ nodes during tree optimization. */
+
+static struct eh_region *
+gen_eh_region (enum eh_region_type type, struct eh_region *outer)
+{
+ struct eh_region *new;
+
+#ifdef ENABLE_CHECKING
+ if (! doing_eh (0))
+ abort ();
+#endif
+
+ /* Insert a new blank region as a leaf in the tree. */
+ new = ggc_alloc_cleared (sizeof (*new));
+ new->type = type;
+ new->outer = outer;
+ if (outer)
+ {
+ new->next_peer = outer->inner;
+ outer->inner = new;
+ }
+ else
+ {
+ new->next_peer = cfun->eh->region_tree;
+ cfun->eh->region_tree = new;
+ }
+
+ new->region_number = ++cfun->eh->last_region_number;
+
+ return new;
+}
+
+struct eh_region *
+gen_eh_region_cleanup (struct eh_region *outer, struct eh_region *prev_try)
+{
+ struct eh_region *cleanup = gen_eh_region (ERT_CLEANUP, outer);
+ cleanup->u.cleanup.prev_try = prev_try;
+ return cleanup;
+}
+
+struct eh_region *
+gen_eh_region_try (struct eh_region *outer)
+{
+ return gen_eh_region (ERT_TRY, outer);
+}
+
+struct eh_region *
+gen_eh_region_catch (struct eh_region *t, tree type_or_list)
+{
+ struct eh_region *c, *l;
+ tree type_list, type_node;
+
+ /* Ensure to always end up with a type list to normalize further
+ processing, then register each type against the runtime types map. */
+ type_list = type_or_list;
+ if (type_or_list)
+ {
+ if (TREE_CODE (type_or_list) != TREE_LIST)
+ type_list = tree_cons (NULL_TREE, type_or_list, NULL_TREE);
+
+ type_node = type_list;
+ for (; type_node; type_node = TREE_CHAIN (type_node))
+ add_type_for_runtime (TREE_VALUE (type_node));
+ }
+
+ c = gen_eh_region (ERT_CATCH, t->outer);
+ c->u.catch.type_list = type_list;
+ l = t->u.try.last_catch;
+ c->u.catch.prev_catch = l;
+ if (l)
+ l->u.catch.next_catch = c;
+ else
+ t->u.try.catch = c;
+ t->u.try.last_catch = c;
+
+ return c;
+}
+
+struct eh_region *
+gen_eh_region_allowed (struct eh_region *outer, tree allowed)
+{
+ struct eh_region *region = gen_eh_region (ERT_ALLOWED_EXCEPTIONS, outer);
+ region->u.allowed.type_list = allowed;
+
+ for (; allowed ; allowed = TREE_CHAIN (allowed))
+ add_type_for_runtime (TREE_VALUE (allowed));
+
+ return region;
+}
+
+struct eh_region *
+gen_eh_region_must_not_throw (struct eh_region *outer)
+{
+ return gen_eh_region (ERT_MUST_NOT_THROW, outer);
+}
+
+int
+get_eh_region_number (struct eh_region *region)
+{
+ return region->region_number;
+}
+
+bool
+get_eh_region_may_contain_throw (struct eh_region *region)
+{
+ return region->may_contain_throw;
+}
+
+tree
+get_eh_region_tree_label (struct eh_region *region)
+{
+ return region->tree_label;
+}
+
+void
+set_eh_region_tree_label (struct eh_region *region, tree lab)
+{
+ region->tree_label = lab;
+}
+
/* Start an exception handling region. All instructions emitted
after this point are considered to be part of the region until
expand_eh_region_end is invoked. */
@@ -468,33 +584,18 @@ init_eh_for_function (void)
void
expand_eh_region_start (void)
{
- struct eh_region *new_region;
- struct eh_region *cur_region;
+ struct eh_region *new;
rtx note;
if (! doing_eh (0))
return;
- /* Insert a new blank region as a leaf in the tree. */
- new_region = ggc_alloc_cleared (sizeof (*new_region));
- cur_region = cfun->eh->cur_region;
- new_region->outer = cur_region;
- if (cur_region)
- {
- new_region->next_peer = cur_region->inner;
- cur_region->inner = new_region;
- }
- else
- {
- new_region->next_peer = cfun->eh->region_tree;
- cfun->eh->region_tree = new_region;
- }
- cfun->eh->cur_region = new_region;
+ new = gen_eh_region (ERT_UNKNOWN, cfun->eh->cur_region);
+ cfun->eh->cur_region = new;
/* Create a note marking the start of this region. */
- new_region->region_number = ++cfun->eh->last_region_number;
note = emit_note (NOTE_INSN_EH_REGION_BEG);
- NOTE_EH_HANDLER (note) = new_region->region_number;
+ NOTE_EH_HANDLER (note) = new->region_number;
}
/* Common code to end a region. Returns the region just ended. */
@@ -515,6 +616,36 @@ expand_eh_region_end (void)
return cur_region;
}
+/* Expand HANDLER, which is the operand 1 of a TRY_CATCH_EXPR. Catch
+ blocks and C++ exception-specifications are handled specially. */
+
+void
+expand_eh_handler (tree handler)
+{
+ tree inner = expr_first (handler);
+
+ switch (TREE_CODE (inner))
+ {
+ case CATCH_EXPR:
+ expand_start_all_catch ();
+ expand_expr (handler, const0_rtx, VOIDmode, 0);
+ expand_end_all_catch ();
+ break;
+
+ case EH_FILTER_EXPR:
+ if (EH_FILTER_MUST_NOT_THROW (handler))
+ expand_eh_region_end_must_not_throw (EH_FILTER_FAILURE (handler));
+ else
+ expand_eh_region_end_allowed (EH_FILTER_TYPES (handler),
+ EH_FILTER_FAILURE (handler));
+ break;
+
+ default:
+ expand_eh_region_end_cleanup (handler);
+ break;
+ }
+}
+
/* End an exception handling region for a cleanup. HANDLER is an
expression to expand for the cleanup. */
@@ -581,6 +712,16 @@ expand_eh_region_end_cleanup (tree handler)
emit_label (around_label);
}
+void
+expand_resx_expr (tree exp)
+{
+ int region_nr = TREE_INT_CST_LOW (TREE_OPERAND (exp, 0));
+ struct eh_region *reg = cfun->eh->region_array[region_nr];
+
+ reg->resume = emit_jump_insn (gen_rtx_RESX (VOIDmode, region_nr));
+ emit_barrier ();
+}
+
/* End an exception handling region for a try block, and prepares
for subsequent calls to expand_start_catch. */
@@ -612,46 +753,20 @@ expand_start_all_catch (void)
void
expand_start_catch (tree type_or_list)
{
- struct eh_region *t, *c, *l;
- tree type_list;
+ struct eh_region *c;
+ rtx note;
if (! doing_eh (0))
return;
- type_list = type_or_list;
-
- if (type_or_list)
- {
- /* Ensure to always end up with a type list to normalize further
- processing, then register each type against the runtime types
- map. */
- tree type_node;
-
- if (TREE_CODE (type_or_list) != TREE_LIST)
- type_list = tree_cons (NULL_TREE, type_or_list, NULL_TREE);
-
- type_node = type_list;
- for (; type_node; type_node = TREE_CHAIN (type_node))
- add_type_for_runtime (TREE_VALUE (type_node));
- }
-
- expand_eh_region_start ();
+ c = gen_eh_region_catch (cfun->eh->try_region, type_or_list);
+ cfun->eh->cur_region = c;
- t = cfun->eh->try_region;
- c = cfun->eh->cur_region;
- c->type = ERT_CATCH;
- c->u.catch.type_list = type_list;
c->label = gen_label_rtx ();
-
- l = t->u.try.last_catch;
- c->u.catch.prev_catch = l;
- if (l)
- l->u.catch.next_catch = c;
- else
- t->u.try.catch = c;
- t->u.try.last_catch = c;
-
emit_label (c->label);
+
+ note = emit_note (NOTE_INSN_EH_REGION_BEG);
+ NOTE_EH_HANDLER (note) = c->region_number;
}
/* End a catch clause. Control will resume after the try/catch block. */
@@ -659,15 +774,11 @@ expand_start_catch (tree type_or_list)
void
expand_end_catch (void)
{
- struct eh_region *try_region;
-
if (! doing_eh (0))
return;
expand_eh_region_end ();
- try_region = cfun->eh->try_region;
-
- emit_jump (try_region->u.try.continue_label);
+ emit_jump (cfun->eh->try_region->u.try.continue_label);
}
/* End a sequence of catch handlers for a try block. */
@@ -806,11 +917,8 @@ expand_eh_region_end_fixup (tree handler)
call to a function which itself may contain a throw. */
void
-note_eh_region_may_contain_throw (void)
+note_eh_region_may_contain_throw (struct eh_region *region)
{
- struct eh_region *region;
-
- region = cfun->eh->cur_region;
while (region && !region->may_contain_throw)
{
region->may_contain_throw = 1;
@@ -818,6 +926,13 @@ note_eh_region_may_contain_throw (void)
}
}
+void
+note_current_region_may_contain_throw (void)
+{
+ note_eh_region_may_contain_throw (cfun->eh->cur_region);
+}
+
+
/* Return an rtl expression for a pointer to the exception object
within a handler. */
@@ -836,7 +951,7 @@ get_exception_pointer (struct function *fun)
/* Return an rtl expression for the exception dispatch filter
within a handler. */
-static rtx
+rtx
get_exception_filter (struct function *fun)
{
rtx filter = fun->eh->filter;
@@ -854,7 +969,7 @@ get_exception_filter (struct function *fun)
collect the regions this way as in expand_eh_region_start, but
without having to realloc memory. */
-static void
+void
collect_eh_region_array (void)
{
struct eh_region **array, *i;
@@ -1039,12 +1154,6 @@ remove_unreachable_regions (rtx insns)
abort ();
uid_region_num[INSN_UID (r->label)] = i;
}
- if (r->type == ERT_TRY && r->u.try.continue_label)
- {
- if (uid_region_num[INSN_UID (r->u.try.continue_label)])
- abort ();
- uid_region_num[INSN_UID (r->u.try.continue_label)] = i;
- }
}
for (insn = insns; insn; insn = NEXT_INSN (insn))
@@ -1066,14 +1175,43 @@ remove_unreachable_regions (rtx insns)
r = cfun->eh->region_array[i];
if (r && r->region_number == i && !reachable[i])
{
- /* Don't remove ERT_THROW regions if their outer region
- is reachable. */
- if (r->type == ERT_THROW
- && r->outer
- && reachable[r->outer->region_number])
- continue;
+ bool kill_it = true;
+ switch (r->type)
+ {
+ case ERT_THROW:
+ /* Don't remove ERT_THROW regions if their outer region
+ is reachable. */
+ if (r->outer && reachable[r->outer->region_number])
+ kill_it = false;
+ break;
+
+ case ERT_MUST_NOT_THROW:
+ /* MUST_NOT_THROW regions are implementable solely in the
+ runtime, but their existance continues to affect calls
+ within that region. Never delete them here. */
+ kill_it = false;
+ break;
+
+ case ERT_TRY:
+ {
+ /* TRY regions are reachable if any of its CATCH regions
+ are reachable. */
+ struct eh_region *c;
+ for (c = r->u.try.catch; c ; c = c->u.catch.next_catch)
+ if (reachable[c->region_number])
+ {
+ kill_it = false;
+ break;
+ }
+ break;
+ }
- remove_eh_handler (r);
+ default:
+ break;
+ }
+
+ if (kill_it)
+ remove_eh_handler (r);
}
}
@@ -1165,21 +1303,45 @@ convert_from_eh_region_ranges_1 (rtx *pinsns, int *orig_sp, int cur)
abort ();
}
+static void
+collect_rtl_labels_from_trees (void)
+{
+ int i, n = cfun->eh->last_region_number;
+ for (i = 1; i <= n; ++i)
+ {
+ struct eh_region *reg = cfun->eh->region_array[i];
+ if (reg && reg->tree_label)
+ reg->label = DECL_RTL_IF_SET (reg->tree_label);
+ }
+}
+
void
convert_from_eh_region_ranges (void)
{
- int *stack;
- rtx insns;
+ rtx insns = get_insns ();
+
+ if (cfun->eh->region_array)
+ {
+ /* If the region array already exists, assume we're coming from
+ optimize_function_tree. In this case all we need to do is
+ collect the rtl labels that correspond to the tree labels
+ that we allocated earlier. */
+ collect_rtl_labels_from_trees ();
+ }
+ else
+ {
+ int *stack;
- collect_eh_region_array ();
- resolve_fixup_regions ();
+ collect_eh_region_array ();
+ resolve_fixup_regions ();
- stack = xmalloc (sizeof (int) * (cfun->eh->last_region_number + 1));
- insns = get_insns ();
- convert_from_eh_region_ranges_1 (&insns, stack, 0);
- free (stack);
+ stack = xmalloc (sizeof (int) * (cfun->eh->last_region_number + 1));
+ convert_from_eh_region_ranges_1 (&insns, stack, 0);
+ free (stack);
+
+ remove_fixup_regions ();
+ }
- remove_fixup_regions ();
remove_unreachable_regions (insns);
}
@@ -1830,8 +1992,21 @@ connect_post_landing_pads (void)
e->count = src->count;
}
else
- emit_library_call (unwind_resume_libfunc, LCT_THROW,
- VOIDmode, 1, cfun->eh->exc_ptr, ptr_mode);
+ {
+ emit_library_call (unwind_resume_libfunc, LCT_THROW,
+ VOIDmode, 1, cfun->eh->exc_ptr, ptr_mode);
+
+ /* What we just emitted was a throwing libcall, so it got a
+ barrier automatically added after it. If the last insn in
+ the libcall sequence isn't the barrier, it's because the
+ target emits multiple insns for a call, and there are insns
+ after the actual call insn (which are redundant and would be
+ optimized away). The barrier is inserted exactly after the
+ call insn, so let's go get that and delete the insns after
+ it, because below we need the barrier to be the last insn in
+ the sequence. */
+ delete_insns_since (NEXT_INSN (last_call_insn ()));
+ }
seq = get_insns ();
end_sequence ();
@@ -1841,6 +2016,12 @@ connect_post_landing_pads (void)
abort ();
delete_insn (barrier);
delete_insn (region->resume);
+
+ /* ??? From tree-ssa we can wind up with catch regions whose
+ label is not instantiated, but whose resx is present. Now
+ that we've dealt with the resx, kill the region. */
+ if (region->label == NULL && region->type == ERT_CLEANUP)
+ remove_eh_handler (region);
}
}
@@ -1967,7 +2148,7 @@ sjlj_find_directly_reachable_regions (struct sjlj_lp_info *lp_info)
rc = RNL_NOT_CAUGHT;
for (; region; region = region->outer)
{
- rc = reachable_next_level (region, type_thrown, 0);
+ rc = reachable_next_level (region, type_thrown, NULL);
if (rc != RNL_NOT_CAUGHT)
break;
}
@@ -2393,7 +2574,7 @@ finish_eh_generation (void)
}
}
if (eh)
- make_eh_edge (NULL, bb, BB_END (bb));
+ rtl_make_eh_edge (NULL, bb, BB_END (bb));
}
cleanup_cfg (CLEANUP_PRE_LOOP | CLEANUP_NO_INSN_DEL);
}
@@ -2589,17 +2770,19 @@ for_each_eh_label_1 (void **pentry, void *data)
/* This section describes CFG exception edges for flow. */
/* For communicating between calls to reachable_next_level. */
-struct reachable_info GTY(())
+struct reachable_info
{
tree types_caught;
tree types_allowed;
- rtx handlers;
+ void (*callback) (struct eh_region *, void *);
+ void *callback_data;
+ bool saw_any_handlers;
};
/* A subroutine of reachable_next_level. Return true if TYPE, or a
base class of TYPE, is in HANDLED. */
-static int
+int
check_handled (tree handled, tree type)
{
tree t;
@@ -2630,18 +2813,18 @@ check_handled (tree handled, tree type)
LP_REGION contains the landing pad; REGION is the handler. */
static void
-add_reachable_handler (struct reachable_info *info, struct eh_region *lp_region, struct eh_region *region)
+add_reachable_handler (struct reachable_info *info,
+ struct eh_region *lp_region, struct eh_region *region)
{
if (! info)
return;
+ info->saw_any_handlers = true;
+
if (cfun->eh->built_landing_pads)
- {
- if (! info->handlers)
- info->handlers = alloc_INSN_LIST (lp_region->landing_pad, NULL_RTX);
- }
+ info->callback (lp_region, info->callback_data);
else
- info->handlers = alloc_INSN_LIST (region->label, info->handlers);
+ info->callback (region, info->callback_data);
}
/* Process one level of exception regions for reachability.
@@ -2790,7 +2973,7 @@ reachable_next_level (struct eh_region *region, tree type_thrown,
If we've touched down at some landing pad previous, then the
explicit function call we generated may be used. Otherwise
the call is made by the runtime. */
- if (info && info->handlers)
+ if (info && info->saw_any_handlers)
{
add_reachable_handler (info, region, region);
return RNL_CAUGHT;
@@ -2808,40 +2991,30 @@ reachable_next_level (struct eh_region *region, tree type_thrown,
abort ();
}
-/* Retrieve a list of labels of exception handlers which can be
- reached by a given insn. */
+/* Invoke CALLBACK on each region reachable from REGION_NUMBER. */
-rtx
-reachable_handlers (rtx insn)
+void
+foreach_reachable_handler (int region_number, bool is_resx,
+ void (*callback) (struct eh_region *, void *),
+ void *callback_data)
{
struct reachable_info info;
struct eh_region *region;
tree type_thrown;
- int region_number;
-
- if (GET_CODE (insn) == JUMP_INSN
- && GET_CODE (PATTERN (insn)) == RESX)
- region_number = XINT (PATTERN (insn), 0);
- else
- {
- rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
- if (!note || INTVAL (XEXP (note, 0)) <= 0)
- return NULL;
- region_number = INTVAL (XEXP (note, 0));
- }
memset (&info, 0, sizeof (info));
+ info.callback = callback;
+ info.callback_data = callback_data;
region = cfun->eh->region_array[region_number];
type_thrown = NULL_TREE;
- if (GET_CODE (insn) == JUMP_INSN
- && GET_CODE (PATTERN (insn)) == RESX)
+ if (is_resx)
{
/* A RESX leaves a region instead of entering it. Thus the
region itself may have been deleted out from under us. */
if (region == NULL)
- return NULL;
+ return;
region = region->outer;
}
else if (region->type == ERT_THROW)
@@ -2863,18 +3036,92 @@ reachable_handlers (rtx insn)
else
region = region->outer;
}
+}
+
+/* Retrieve a list of labels of exception handlers which can be
+ reached by a given insn. */
+
+static void
+arh_to_landing_pad (struct eh_region *region, void *data)
+{
+ rtx *p_handlers = data;
+ if (! *p_handlers)
+ *p_handlers = alloc_INSN_LIST (region->landing_pad, NULL_RTX);
+}
- return info.handlers;
+static void
+arh_to_label (struct eh_region *region, void *data)
+{
+ rtx *p_handlers = data;
+ *p_handlers = alloc_INSN_LIST (region->label, *p_handlers);
+}
+
+rtx
+reachable_handlers (rtx insn)
+{
+ bool is_resx = false;
+ rtx handlers = NULL;
+ int region_number;
+
+ if (GET_CODE (insn) == JUMP_INSN
+ && GET_CODE (PATTERN (insn)) == RESX)
+ {
+ region_number = XINT (PATTERN (insn), 0);
+ is_resx = true;
+ }
+ else
+ {
+ rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
+ if (!note || INTVAL (XEXP (note, 0)) <= 0)
+ return NULL;
+ region_number = INTVAL (XEXP (note, 0));
+ }
+
+ foreach_reachable_handler (region_number, is_resx,
+ (cfun->eh->built_landing_pads
+ ? arh_to_landing_pad
+ : arh_to_label),
+ &handlers);
+
+ return handlers;
}
/* Determine if the given INSN can throw an exception that is caught
within the function. */
bool
-can_throw_internal (rtx insn)
+can_throw_internal_1 (int region_number)
{
struct eh_region *region;
tree type_thrown;
+
+ region = cfun->eh->region_array[region_number];
+
+ type_thrown = NULL_TREE;
+ if (region->type == ERT_THROW)
+ {
+ type_thrown = region->u.throw.type;
+ region = region->outer;
+ }
+
+ /* If this exception is ignored by each and every containing region,
+ then control passes straight out. The runtime may handle some
+ regions, which also do not require processing internally. */
+ for (; region; region = region->outer)
+ {
+ enum reachable_code how = reachable_next_level (region, type_thrown, 0);
+ if (how == RNL_BLOCKED)
+ return false;
+ if (how != RNL_NOT_CAUGHT)
+ return true;
+ }
+
+ return false;
+}
+
+bool
+can_throw_internal (rtx insn)
+{
rtx note;
if (! INSN_P (insn))
@@ -2903,7 +3150,19 @@ can_throw_internal (rtx insn)
if (!note || INTVAL (XEXP (note, 0)) <= 0)
return false;
- region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
+ return can_throw_internal_1 (INTVAL (XEXP (note, 0)));
+}
+
+/* Determine if the given INSN can throw an exception that is
+ visible outside the function. */
+
+bool
+can_throw_external_1 (int region_number)
+{
+ struct eh_region *region;
+ tree type_thrown;
+
+ region = cfun->eh->region_array[region_number];
type_thrown = NULL_TREE;
if (region->type == ERT_THROW)
@@ -2912,29 +3171,18 @@ can_throw_internal (rtx insn)
region = region->outer;
}
- /* If this exception is ignored by each and every containing region,
- then control passes straight out. The runtime may handle some
- regions, which also do not require processing internally. */
- for (; region; region = region->outer)
- {
- enum reachable_code how = reachable_next_level (region, type_thrown, 0);
- if (how == RNL_BLOCKED)
- return false;
- if (how != RNL_NOT_CAUGHT)
- return true;
- }
+ /* If the exception is caught or blocked by any containing region,
+ then it is not seen by any calling function. */
+ for (; region ; region = region->outer)
+ if (reachable_next_level (region, type_thrown, NULL) >= RNL_CAUGHT)
+ return false;
- return false;
+ return true;
}
-/* Determine if the given INSN can throw an exception that is
- visible outside the function. */
-
bool
can_throw_external (rtx insn)
{
- struct eh_region *region;
- tree type_thrown;
rtx note;
if (! INSN_P (insn))
@@ -2973,22 +3221,7 @@ can_throw_external (rtx insn)
if (INTVAL (XEXP (note, 0)) <= 0)
return false;
- region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
-
- type_thrown = NULL_TREE;
- if (region->type == ERT_THROW)
- {
- type_thrown = region->u.throw.type;
- region = region->outer;
- }
-
- /* If the exception is caught or blocked by any containing region,
- then it is not seen by any calling function. */
- for (; region ; region = region->outer)
- if (reachable_next_level (region, type_thrown, NULL) >= RNL_CAUGHT)
- return false;
-
- return true;
+ return can_throw_external_1 (INTVAL (XEXP (note, 0)));
}
/* Set current_function_nothrow and cfun->all_throwers_are_sibcalls. */
@@ -3884,6 +4117,7 @@ output_function_exception_table (void)
/* Let cgraph know that the rtti decl is used. Not all of the
paths below go through assemble_integer, which would take
care of this for us. */
+ STRIP_NOPS (type);
if (TREE_CODE (type) == ADDR_EXPR)
{
type = TREE_OPERAND (type, 0);
diff --git a/gcc/except.h b/gcc/except.h
index a75b3d46d80..2fed79f30fb 100644
--- a/gcc/except.h
+++ b/gcc/except.h
@@ -78,16 +78,22 @@ extern void expand_eh_region_end_throw (tree);
destroying an object twice. */
extern void expand_eh_region_end_fixup (tree);
+/* End some sort of EH region, depending on the argument. */
+extern void expand_eh_handler (tree);
+
/* Note that the current EH region (if any) may contain a throw, or a
call to a function which itself may contain a throw. */
-extern void note_eh_region_may_contain_throw (void);
+extern void note_eh_region_may_contain_throw (struct eh_region *);
+extern void note_current_region_may_contain_throw (void);
/* Invokes CALLBACK for every exception handler label. Only used by old
loop hackery; should not be used by new code. */
extern void for_each_eh_label (void (*) (rtx));
/* Determine if the given INSN can throw an exception. */
+extern bool can_throw_internal_1 (int);
extern bool can_throw_internal (rtx);
+extern bool can_throw_external_1 (int);
extern bool can_throw_external (rtx);
/* Set current_function_nothrow and cfun->all_throwers_are_sibcalls. */
@@ -119,10 +125,32 @@ extern void expand_builtin_eh_return (tree, tree);
extern void expand_eh_return (void);
extern rtx expand_builtin_extend_pointer (tree);
extern rtx get_exception_pointer (struct function *);
+extern rtx get_exception_filter (struct function *);
extern int duplicate_eh_regions (struct function *, struct inline_remap *);
+extern int check_handled (tree, tree);
extern void sjlj_emit_function_exit_after (rtx);
+extern struct eh_region *gen_eh_region_cleanup (struct eh_region *,
+ struct eh_region *);
+extern struct eh_region *gen_eh_region_try (struct eh_region *);
+extern struct eh_region *gen_eh_region_catch (struct eh_region *, tree);
+extern struct eh_region *gen_eh_region_allowed (struct eh_region *, tree);
+extern struct eh_region *gen_eh_region_must_not_throw (struct eh_region *);
+extern int get_eh_region_number (struct eh_region *);
+extern bool get_eh_region_may_contain_throw (struct eh_region *);
+extern tree get_eh_region_tree_label (struct eh_region *);
+extern void set_eh_region_tree_label (struct eh_region *, tree);
+
+extern void foreach_reachable_handler (int, bool,
+ void (*) (struct eh_region *, void *),
+ void *);
+
+extern void collect_eh_region_array (void);
+extern void expand_resx_expr (tree);
+
+/* tree-eh.c */
+extern int lookup_stmt_eh_region (tree);
/* If non-NULL, this is a function that returns an expression to be
executed if an unhandled exception is propagated out of a cleanup
diff --git a/gcc/explow.c b/gcc/explow.c
index e6eacdcf0bf..155404dc0cf 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -998,11 +998,6 @@ emit_stack_save (enum save_level save_level, rtx *psave, rtx after)
*psave = sa = gen_reg_rtx (mode);
}
}
- else
- {
- if (mode == VOIDmode || GET_MODE (sa) != mode)
- abort ();
- }
if (after)
{
@@ -1089,6 +1084,27 @@ emit_stack_restore (enum save_level save_level, rtx sa, rtx after)
else
emit_insn (fcn (stack_pointer_rtx, sa));
}
+
+/* Invoke emit_stack_save on the nonlocal_goto_save_area for the current
+ function. This function should be called whenever we allocate or
+ deallocate dynamic stack space. */
+
+void
+update_nonlocal_goto_save_area (void)
+{
+ tree t_save;
+ rtx r_save;
+
+ /* The nonlocal_goto_save_area object is an array of N pointers. The
+ first one is used for the frame pointer save; the rest are sized by
+ STACK_SAVEAREA_MODE. Create a reference to array index 1, the first
+ of the stack save area slots. */
+ t_save = build (ARRAY_REF, ptr_type_node, cfun->nonlocal_goto_save_area,
+ integer_one_node);
+ r_save = expand_expr (t_save, NULL_RTX, VOIDmode, EXPAND_WRITE);
+
+ emit_stack_save (SAVE_NONLOCAL, &r_save, NULL_RTX);
+}
#ifdef SETJMP_VIA_SAVE_AREA
/* Optimize RTL generated by allocate_dynamic_stack_space for targets
@@ -1413,8 +1429,8 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align)
}
/* Record the new stack level for nonlocal gotos. */
- if (nonlocal_goto_handler_slots != 0)
- emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level, NULL_RTX);
+ if (cfun->nonlocal_goto_save_area != 0)
+ update_nonlocal_goto_save_area ();
return target;
}
@@ -1545,14 +1561,11 @@ probe_stack_range (HOST_WIDE_INT first, rtx size)
|| REGNO (test_addr) < FIRST_PSEUDO_REGISTER)
test_addr = force_reg (Pmode, test_addr);
- emit_note (NOTE_INSN_LOOP_BEG);
emit_jump (test_lab);
emit_label (loop_lab);
emit_stack_probe (test_addr);
- emit_note (NOTE_INSN_LOOP_CONT);
-
#ifdef STACK_GROWS_DOWNWARD
#define CMP_OPCODE GTU
temp = expand_binop (Pmode, sub_optab, test_addr, incr, test_addr,
@@ -1570,7 +1583,6 @@ probe_stack_range (HOST_WIDE_INT first, rtx size)
emit_cmp_and_jump_insns (test_addr, last_addr, CMP_OPCODE,
NULL_RTX, Pmode, 1, loop_lab);
emit_jump (end_lab);
- emit_note (NOTE_INSN_LOOP_END);
emit_label (end_lab);
emit_stack_probe (last_addr);
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 5d213c38b3d..a8cd617f859 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -1718,9 +1718,7 @@ extract_fixed_bit_field (enum machine_mode tmode, rtx op0,
tree amount = build_int_2 (bitpos, 0);
/* Maybe propagate the target for the shift. */
/* But not if we will return it--could confuse integrate.c. */
- rtx subtarget = (target != 0 && GET_CODE (target) == REG
- && !REG_FUNCTION_VALUE_P (target)
- ? target : 0);
+ rtx subtarget = (target != 0 && GET_CODE (target) == REG ? target : 0);
if (tmode != mode) subtarget = 0;
op0 = expand_shift (RSHIFT_EXPR, mode, op0, amount, subtarget, 1);
}
@@ -1759,10 +1757,7 @@ extract_fixed_bit_field (enum machine_mode tmode, rtx op0,
tree amount
= build_int_2 (GET_MODE_BITSIZE (mode) - (bitsize + bitpos), 0);
/* Maybe propagate the target for the shift. */
- /* But not if we will return the result--could confuse integrate.c. */
- rtx subtarget = (target != 0 && GET_CODE (target) == REG
- && ! REG_FUNCTION_VALUE_P (target)
- ? target : 0);
+ rtx subtarget = (target != 0 && GET_CODE (target) == REG ? target : 0);
op0 = expand_shift (LSHIFT_EXPR, mode, op0, amount, subtarget, 1);
}
@@ -2882,6 +2877,7 @@ static rtx
expand_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1,
rtx target, int unsignedp, int max_cost)
{
+ rtx narrow_op1 = gen_int_mode (INTVAL (op1), mode);
enum machine_mode wider_mode;
optab moptab;
rtx tem;
@@ -2895,7 +2891,7 @@ expand_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1,
if (mul_highpart_cost[(int) mode] < max_cost)
{
moptab = unsignedp ? umul_highpart_optab : smul_highpart_optab;
- tem = expand_binop (mode, moptab, op0, op1, target,
+ tem = expand_binop (mode, moptab, op0, narrow_op1, target,
unsignedp, OPTAB_DIRECT);
if (tem)
return tem;
@@ -2908,11 +2904,11 @@ expand_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1,
< max_cost))
{
moptab = unsignedp ? smul_highpart_optab : umul_highpart_optab;
- tem = expand_binop (mode, moptab, op0, op1, target,
+ tem = expand_binop (mode, moptab, op0, narrow_op1, target,
unsignedp, OPTAB_DIRECT);
if (tem)
/* We used the wrong signedness. Adjust the result. */
- return expand_mult_highpart_adjust (mode, tem, op0, op1,
+ return expand_mult_highpart_adjust (mode, tem, op0, narrow_op1,
tem, unsignedp);
}
@@ -2921,7 +2917,7 @@ expand_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1,
if (moptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
&& mul_widen_cost[(int) wider_mode] < max_cost)
{
- tem = expand_binop (wider_mode, moptab, op0, op1, 0,
+ tem = expand_binop (wider_mode, moptab, op0, narrow_op1, 0,
unsignedp, OPTAB_WIDEN);
if (tem)
return extract_high_half (mode, tem);
@@ -2946,14 +2942,13 @@ expand_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1,
&& (mul_widen_cost[(int) wider_mode]
+ 2 * shift_cost[size-1] + 4 * add_cost < max_cost))
{
- rtx regop1 = force_reg (mode, op1);
- tem = expand_binop (wider_mode, moptab, op0, regop1,
+ tem = expand_binop (wider_mode, moptab, op0, narrow_op1,
NULL_RTX, ! unsignedp, OPTAB_WIDEN);
if (tem != 0)
{
tem = extract_high_half (mode, tem);
/* We used the wrong signedness. Adjust the result. */
- return expand_mult_highpart_adjust (mode, tem, op0, op1,
+ return expand_mult_highpart_adjust (mode, tem, op0, narrow_op1,
target, unsignedp);
}
}
@@ -2987,7 +2982,7 @@ expand_mult_highpart (enum machine_mode mode, rtx op0,
if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
abort ();
- op1 = gen_int_mode (cnst1, mode);
+ op1 = gen_int_mode (cnst1, wider_mode);
cnst1 &= GET_MODE_MASK (mode);
/* We can't optimize modes wider than BITS_PER_WORD.
diff --git a/gcc/expr.c b/gcc/expr.c
index f884ad97747..23e128d4704 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -47,6 +47,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "langhooks.h"
#include "intl.h"
#include "tm_p.h"
+#include "tree-iterator.h"
#include "target.h"
/* Decide whether a function's arguments should be processed
@@ -143,7 +144,6 @@ static rtx clear_storage_via_libcall (rtx, rtx);
static tree clear_storage_libcall_fn (int);
static rtx compress_float_constant (rtx, rtx);
static rtx get_subtarget (rtx);
-static int is_zeros_p (tree);
static void store_constructor_field (rtx, unsigned HOST_WIDE_INT,
HOST_WIDE_INT, enum machine_mode,
tree, tree, int, int);
@@ -209,9 +209,6 @@ enum insn_code clrstr_optab[NUM_MACHINE_MODES];
enum insn_code cmpstr_optab[NUM_MACHINE_MODES];
enum insn_code cmpmem_optab[NUM_MACHINE_MODES];
-/* Stack of EXPR_WITH_FILE_LOCATION nested expressions. */
-struct file_stack *expr_wfl_stack;
-
/* SLOW_UNALIGNED_ACCESS is nonzero if unaligned accesses are very slow. */
#ifndef SLOW_UNALIGNED_ACCESS
@@ -554,6 +551,11 @@ convert_move (rtx to, rtx from, int unsignedp)
if (to_real != from_real)
abort ();
+ /* If the source and destination are already the same, then there's
+ nothing to do. */
+ if (to == from)
+ return;
+
/* If FROM is a SUBREG that indicates that we have already done at least
the required extension, strip it. We don't handle such SUBREGs as
TO here. */
@@ -1688,8 +1690,6 @@ emit_block_move_via_loop (rtx x, rtx y, rtx size,
y_addr = force_operand (XEXP (y, 0), NULL_RTX);
do_pending_stack_adjust ();
- emit_note (NOTE_INSN_LOOP_BEG);
-
emit_jump (cmp_label);
emit_label (top_label);
@@ -1706,13 +1706,10 @@ emit_block_move_via_loop (rtx x, rtx y, rtx size,
if (tmp != iter)
emit_move_insn (iter, tmp);
- emit_note (NOTE_INSN_LOOP_CONT);
emit_label (cmp_label);
emit_cmp_and_jump_insns (iter, size, LT, NULL_RTX, iter_mode,
true, top_label);
-
- emit_note (NOTE_INSN_LOOP_END);
}
/* Copy all or part of a value X into registers starting at REGNO.
@@ -2801,10 +2798,7 @@ emit_move_insn (rtx x, rtx y)
if (mode == BLKmode || (GET_MODE (y) != mode && GET_MODE (y) != VOIDmode))
abort ();
- /* Never force constant_p_rtx to memory. */
- if (GET_CODE (y) == CONSTANT_P_RTX)
- ;
- else if (CONSTANT_P (y))
+ if (CONSTANT_P (y))
{
if (optimize
&& SCALAR_FLOAT_MODE_P (GET_MODE (x))
@@ -2987,9 +2981,6 @@ emit_move_insn_1 (rtx x, rtx y)
GET_MODE_SIZE (mode), 0);
rtx cmem = adjust_address (mem, mode, 0);
- cfun->cannot_inline
- = N_("function using short complex types cannot be inline");
-
if (packed_dest_p)
{
rtx sreg = gen_rtx_SUBREG (reg_mode, x, 0);
@@ -4396,50 +4387,166 @@ store_expr (tree exp, rtx target, int want_value)
return target;
}
-/* Return 1 if EXP just contains zeros. FIXME merge with initializer_zerop. */
+/* Examine CTOR. Discover how many scalar fields are set to non-zero
+ values and place it in *P_NZ_ELTS. Discover how many scalar fields
+ are set to non-constant values and place it in *P_NC_ELTS. */
-static int
-is_zeros_p (tree exp)
+static void
+categorize_ctor_elements_1 (tree ctor, HOST_WIDE_INT *p_nz_elts,
+ HOST_WIDE_INT *p_nc_elts)
{
- tree elt;
+ HOST_WIDE_INT nz_elts, nc_elts;
+ tree list;
- switch (TREE_CODE (exp))
+ nz_elts = 0;
+ nc_elts = 0;
+
+ for (list = CONSTRUCTOR_ELTS (ctor); list; list = TREE_CHAIN (list))
{
- case CONVERT_EXPR:
- case NOP_EXPR:
- case NON_LVALUE_EXPR:
- case VIEW_CONVERT_EXPR:
- return is_zeros_p (TREE_OPERAND (exp, 0));
+ tree value = TREE_VALUE (list);
+ tree purpose = TREE_PURPOSE (list);
+ HOST_WIDE_INT mult;
- case INTEGER_CST:
- return integer_zerop (exp);
+ mult = 1;
+ if (TREE_CODE (purpose) == RANGE_EXPR)
+ {
+ tree lo_index = TREE_OPERAND (purpose, 0);
+ tree hi_index = TREE_OPERAND (purpose, 1);
- case COMPLEX_CST:
- return
- is_zeros_p (TREE_REALPART (exp)) && is_zeros_p (TREE_IMAGPART (exp));
+ if (host_integerp (lo_index, 1) && host_integerp (hi_index, 1))
+ mult = (tree_low_cst (hi_index, 1)
+ - tree_low_cst (lo_index, 1) + 1);
+ }
- case REAL_CST:
- return REAL_VALUES_IDENTICAL (TREE_REAL_CST (exp), dconst0);
+ switch (TREE_CODE (value))
+ {
+ case CONSTRUCTOR:
+ {
+ HOST_WIDE_INT nz = 0, nc = 0;
+ categorize_ctor_elements_1 (value, &nz, &nc);
+ nz_elts += mult * nz;
+ nc_elts += mult * nc;
+ }
+ break;
- case VECTOR_CST:
- for (elt = TREE_VECTOR_CST_ELTS (exp); elt;
- elt = TREE_CHAIN (elt))
- if (!is_zeros_p (TREE_VALUE (elt)))
- return 0;
+ case INTEGER_CST:
+ case REAL_CST:
+ if (!initializer_zerop (value))
+ nz_elts += mult;
+ break;
+ case COMPLEX_CST:
+ if (!initializer_zerop (TREE_REALPART (value)))
+ nz_elts += mult;
+ if (!initializer_zerop (TREE_IMAGPART (value)))
+ nz_elts += mult;
+ break;
+ case VECTOR_CST:
+ {
+ tree v;
+ for (v = TREE_VECTOR_CST_ELTS (value); v; v = TREE_CHAIN (v))
+ if (!initializer_zerop (TREE_VALUE (v)))
+ nz_elts += mult;
+ }
+ break;
- return 1;
+ default:
+ nz_elts += mult;
+ if (!initializer_constant_valid_p (value, TREE_TYPE (value)))
+ nc_elts += mult;
+ break;
+ }
+ }
- case CONSTRUCTOR:
- if (TREE_TYPE (exp) && TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
- return CONSTRUCTOR_ELTS (exp) == NULL_TREE;
- for (elt = CONSTRUCTOR_ELTS (exp); elt; elt = TREE_CHAIN (elt))
- if (! is_zeros_p (TREE_VALUE (elt)))
- return 0;
+ *p_nz_elts += nz_elts;
+ *p_nc_elts += nc_elts;
+}
+void
+categorize_ctor_elements (tree ctor, HOST_WIDE_INT *p_nz_elts,
+ HOST_WIDE_INT *p_nc_elts)
+{
+ *p_nz_elts = 0;
+ *p_nc_elts = 0;
+ categorize_ctor_elements_1 (ctor, p_nz_elts, p_nc_elts);
+}
+
+/* Count the number of scalars in TYPE. Return -1 on overflow or
+ variable-sized. */
+
+HOST_WIDE_INT
+count_type_elements (tree type)
+{
+ const HOST_WIDE_INT max = ~((HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT-1));
+ switch (TREE_CODE (type))
+ {
+ case ARRAY_TYPE:
+ {
+ tree telts = array_type_nelts (type);
+ if (telts && host_integerp (telts, 1))
+ {
+ HOST_WIDE_INT n = tree_low_cst (telts, 1);
+ HOST_WIDE_INT m = count_type_elements (TREE_TYPE (type));
+ if (n == 0)
+ return 0;
+ if (max / n < m)
+ return n * m;
+ }
+ return -1;
+ }
+
+ case RECORD_TYPE:
+ {
+ HOST_WIDE_INT n = 0, t;
+ tree f;
+
+ for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
+ if (TREE_CODE (f) == FIELD_DECL)
+ {
+ t = count_type_elements (TREE_TYPE (f));
+ if (t < 0)
+ return -1;
+ n += t;
+ }
+
+ return n;
+ }
+
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ {
+ /* Ho hum. How in the world do we guess here? Clearly it isn't
+ right to count the fields. Guess based on the number of words. */
+ HOST_WIDE_INT n = int_size_in_bytes (type);
+ if (n < 0)
+ return -1;
+ return n / UNITS_PER_WORD;
+ }
+
+ case COMPLEX_TYPE:
+ return 2;
+
+ case VECTOR_TYPE:
+ /* ??? This is broke. We should encode the vector width in the tree. */
+ return GET_MODE_NUNITS (TYPE_MODE (type));
+
+ case INTEGER_TYPE:
+ case REAL_TYPE:
+ case ENUMERAL_TYPE:
+ case BOOLEAN_TYPE:
+ case CHAR_TYPE:
+ case POINTER_TYPE:
+ case OFFSET_TYPE:
+ case REFERENCE_TYPE:
return 1;
+ case VOID_TYPE:
+ case METHOD_TYPE:
+ case FILE_TYPE:
+ case SET_TYPE:
+ case FUNCTION_TYPE:
+ case LANG_TYPE:
default:
- return 0;
+ abort ();
}
}
@@ -4449,30 +4556,21 @@ int
mostly_zeros_p (tree exp)
{
if (TREE_CODE (exp) == CONSTRUCTOR)
+
{
- int elts = 0, zeros = 0;
- tree elt = CONSTRUCTOR_ELTS (exp);
+ HOST_WIDE_INT nz_elts, nc_elts, elts;
+
+ /* If there are no ranges of true bits, it is all zero. */
if (TREE_TYPE (exp) && TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
- {
- /* If there are no ranges of true bits, it is all zero. */
- return elt == NULL_TREE;
- }
- for (; elt; elt = TREE_CHAIN (elt))
- {
- /* We do not handle the case where the index is a RANGE_EXPR,
- so the statistic will be somewhat inaccurate.
- We do make a more accurate count in store_constructor itself,
- so since this function is only used for nested array elements,
- this should be close enough. */
- if (mostly_zeros_p (TREE_VALUE (elt)))
- zeros++;
- elts++;
- }
+ return CONSTRUCTOR_ELTS (exp) == NULL_TREE;
- return 4 * zeros >= 3 * elts;
+ categorize_ctor_elements (exp, &nz_elts, &nc_elts);
+ elts = count_type_elements (TREE_TYPE (exp));
+
+ return nz_elts < elts / 4;
}
- return is_zeros_p (exp);
+ return initializer_zerop (exp);
}
/* Helper function for store_constructor.
@@ -4492,7 +4590,10 @@ store_constructor_field (rtx target, unsigned HOST_WIDE_INT bitsize,
tree exp, tree type, int cleared, int alias_set)
{
if (TREE_CODE (exp) == CONSTRUCTOR
+ /* We can only call store_constructor recursively if the size and
+ bit position are on a byte boundary. */
&& bitpos % BITS_PER_UNIT == 0
+ && (bitsize > 0 && bitsize % BITS_PER_UNIT == 0)
/* If we have a nonzero bitpos for a register target, then we just
let store_field do the bitfield handling. This is unlikely to
generate unnecessary clear instructions anyways. */
@@ -4612,7 +4713,7 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
if (field == 0)
continue;
- if (cleared && is_zeros_p (value))
+ if (cleared && initializer_zerop (value))
continue;
if (host_integerp (DECL_SIZE (field), 1))
@@ -4716,7 +4817,7 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
tree elt;
int i;
int need_to_clear;
- tree domain = TYPE_DOMAIN (type);
+ tree domain;
tree elttype = TREE_TYPE (type);
int const_bounds_p;
HOST_WIDE_INT minelt = 0;
@@ -4726,13 +4827,14 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
int elt_size = 0;
unsigned n_elts = 0;
- /* Vectors are like arrays, but the domain is stored via an array
- type indirectly. */
- if (TREE_CODE (type) == VECTOR_TYPE)
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ domain = TYPE_DOMAIN (type);
+ else
+ /* Vectors do not have domains; look up the domain of
+ the array embedded in the debug representation type.
+ FIXME Would probably be more efficient to treat vectors
+ separately from arrays. */
{
- /* Note that although TYPE_DEBUG_REPRESENTATION_TYPE uses
- the same field as TYPE_DOMAIN, we are not guaranteed that
- it always will. */
domain = TYPE_DEBUG_REPRESENTATION_TYPE (type);
domain = TYPE_DOMAIN (TREE_TYPE (TYPE_FIELDS (domain)));
if (REG_P (target) && VECTOR_MODE_P (GET_MODE (target)))
@@ -4845,7 +4947,7 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
tree index = TREE_PURPOSE (elt);
rtx xtarget = target;
- if (cleared && is_zeros_p (value))
+ if (cleared && initializer_zerop (value))
continue;
unsignedp = TYPE_UNSIGNED (elttype);
@@ -5267,7 +5369,7 @@ store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos,
if (bitpos != 0)
abort ();
- return store_expr (exp, target, 0);
+ return store_expr (exp, target, value_mode != VOIDmode);
}
/* If the structure is in a register or if the component
@@ -5510,7 +5612,7 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
index, low_bound));
/* If the index has a self-referential type, instantiate it with
- the object; likewise fkor the component size. */
+ the object; likewise for the component size. */
index = SUBSTITUTE_PLACEHOLDER_IN_EXPR (index, exp);
unit_size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (unit_size, array);
offset = size_binop (PLUS_EXPR, offset,
@@ -6078,6 +6180,70 @@ highest_pow2_factor_for_target (tree target, tree exp)
return MAX (factor, target_align);
}
+/* Expands variable VAR. */
+
+void
+expand_var (tree var)
+{
+ if (DECL_EXTERNAL (var))
+ return;
+
+ if (TREE_STATIC (var))
+ /* If this is an inlined copy of a static local variable,
+ look up the original decl. */
+ var = DECL_ORIGIN (var);
+
+ if (TREE_STATIC (var)
+ ? !TREE_ASM_WRITTEN (var)
+ : !DECL_RTL_SET_P (var))
+ {
+ if (TREE_CODE (var) == VAR_DECL && DECL_DEFER_OUTPUT (var))
+ {
+ /* Prepare a mem & address for the decl. */
+ rtx x;
+
+ if (TREE_STATIC (var))
+ abort ();
+
+ x = gen_rtx_MEM (DECL_MODE (var),
+ gen_reg_rtx (Pmode));
+
+ set_mem_attributes (x, var, 1);
+ SET_DECL_RTL (var, x);
+ }
+ else if ((*lang_hooks.expand_decl) (var))
+ /* OK. */;
+ else if (TREE_CODE (var) == VAR_DECL && !TREE_STATIC (var))
+ expand_decl (var);
+ else if (TREE_CODE (var) == VAR_DECL && TREE_STATIC (var))
+ rest_of_decl_compilation (var, NULL, 0, 0);
+ else if (TREE_CODE (var) == TYPE_DECL
+ || TREE_CODE (var) == CONST_DECL
+ || TREE_CODE (var) == FUNCTION_DECL
+ || TREE_CODE (var) == LABEL_DECL)
+ /* No expansion needed. */;
+ else
+ abort ();
+ }
+}
+
+/* Expands declarations of variables in list VARS. */
+
+static void
+expand_vars (tree vars)
+{
+ for (; vars; vars = TREE_CHAIN (vars))
+ {
+ tree var = vars;
+
+ if (DECL_EXTERNAL (var))
+ continue;
+
+ expand_var (var);
+ expand_decl_init (var);
+ }
+}
+
/* Subroutine of expand_expr. Expand the two operands of a binary
expression EXP0 and EXP1 placing the results in OP0 and OP1.
The value may be stored in TARGET if TARGET is nonzero. The
@@ -6154,10 +6320,88 @@ expand_operands (tree exp0, tree exp1, rtx target, rtx *op0, rtx *op1,
COMPOUND_EXPR whose second argument is such a VAR_DECL, and so on
recursively. */
+static rtx expand_expr_real_1 (tree, rtx, enum machine_mode,
+ enum expand_modifier, rtx *);
+
rtx
expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
enum expand_modifier modifier, rtx *alt_rtl)
{
+ int rn = -1;
+ rtx ret, last = NULL;
+
+ /* Handle ERROR_MARK before anybody tries to access its type. */
+ if (TREE_CODE (exp) == ERROR_MARK
+ || TREE_CODE (TREE_TYPE (exp)) == ERROR_MARK)
+ {
+ ret = CONST0_RTX (tmode);
+ return ret ? ret : const0_rtx;
+ }
+
+ if (flag_non_call_exceptions)
+ {
+ rn = lookup_stmt_eh_region (exp);
+ /* If rn < 0, then either (1) tree-ssa not used or (2) doesn't throw. */
+ if (rn >= 0)
+ last = get_last_insn ();
+ }
+
+ /* If this is an expression of some kind and it has an associated line
+ number, then emit the line number before expanding the expression.
+
+ We need to save and restore the file and line information so that
+ errors discovered during expansion are emitted with the right
+ information. It would be better of the diagnostic routines
+ used the file/line information embedded in the tree nodes rather
+ than globals. */
+ if (cfun && EXPR_HAS_LOCATION (exp))
+ {
+ location_t saved_location = input_location;
+ input_location = EXPR_LOCATION (exp);
+ emit_line_note (input_location);
+
+ /* Record where the insns produced belong. */
+ if (cfun->dont_emit_block_notes)
+ record_block_change (TREE_BLOCK (exp));
+
+ ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl);
+
+ input_location = saved_location;
+ }
+ else
+ {
+ ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl);
+ }
+
+ /* If using non-call exceptions, mark all insns that may trap.
+ expand_call() will mark CALL_INSNs before we get to this code,
+ but it doesn't handle libcalls, and these may trap. */
+ if (rn >= 0)
+ {
+ rtx insn;
+ for (insn = next_real_insn (last); insn;
+ insn = next_real_insn (insn))
+ {
+ if (! find_reg_note (insn, REG_EH_REGION, NULL_RTX)
+ /* If we want exceptions for non-call insns, any
+ may_trap_p instruction may throw. */
+ && GET_CODE (PATTERN (insn)) != CLOBBER
+ && GET_CODE (PATTERN (insn)) != USE
+ && (GET_CODE (insn) == CALL_INSN || may_trap_p (PATTERN (insn))))
+ {
+ REG_NOTES (insn) = alloc_EXPR_LIST (REG_EH_REGION, GEN_INT (rn),
+ REG_NOTES (insn));
+ }
+ }
+ }
+
+ return ret;
+}
+
+static rtx
+expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
+ enum expand_modifier modifier, rtx *alt_rtl)
+{
rtx op0, op1, temp;
tree type = TREE_TYPE (exp);
int unsignedp;
@@ -6168,15 +6412,6 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
int ignore;
tree context;
- /* Handle ERROR_MARK before anybody tries to access its type. */
- if (TREE_CODE (exp) == ERROR_MARK || TREE_CODE (type) == ERROR_MARK)
- {
- op0 = CONST0_RTX (tmode);
- if (op0 != 0)
- return op0;
- return const0_rtx;
- }
-
mode = TYPE_MODE (type);
unsignedp = TYPE_UNSIGNED (type);
@@ -6260,20 +6495,15 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
case LABEL_DECL:
{
tree function = decl_function_context (exp);
- /* Labels in containing functions, or labels used from initializers,
- must be forced. */
- if (modifier == EXPAND_INITIALIZER
- || (function != current_function_decl
- && function != inline_function_decl
- && function != 0))
- temp = force_label_rtx (exp);
- else
- temp = label_rtx (exp);
- temp = gen_rtx_MEM (FUNCTION_MODE, gen_rtx_LABEL_REF (Pmode, temp));
+ temp = label_rtx (exp);
+ temp = gen_rtx_LABEL_REF (Pmode, temp);
+
if (function != current_function_decl
- && function != inline_function_decl && function != 0)
- LABEL_REF_NONLOCAL_P (XEXP (temp, 0)) = 1;
+ && function != 0)
+ LABEL_REF_NONLOCAL_P (temp) = 1;
+
+ temp = gen_rtx_MEM (FUNCTION_MODE, temp);
return temp;
}
@@ -6316,13 +6546,7 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
/* Handle variables inherited from containing functions. */
context = decl_function_context (exp);
- /* We treat inline_function_decl as an alias for the current function
- because that is the inline function whose vars, types, etc.
- are being merged into the current function.
- See expand_inline_function. */
-
if (context != 0 && context != current_function_decl
- && context != inline_function_decl
/* If var is static, we don't need a static chain to access it. */
&& ! (GET_CODE (DECL_RTL (exp)) == MEM
&& CONSTANT_P (XEXP (DECL_RTL (exp), 0))))
@@ -6480,29 +6704,6 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
copy_rtx (XEXP (temp, 0)));
return temp;
- case EXPR_WITH_FILE_LOCATION:
- {
- rtx to_return;
- struct file_stack fs;
-
- fs.location = input_location;
- fs.next = expr_wfl_stack;
- input_filename = EXPR_WFL_FILENAME (exp);
- input_line = EXPR_WFL_LINENO (exp);
- expr_wfl_stack = &fs;
- if (EXPR_WFL_EMIT_LINE_NOTE (exp))
- emit_line_note (input_location);
- /* Possibly avoid switching back and forth here. */
- to_return = expand_expr (EXPR_WFL_NODE (exp),
- (ignore ? const0_rtx : target),
- tmode, modifier);
- if (expr_wfl_stack != &fs)
- abort ();
- input_location = fs.location;
- expr_wfl_stack = fs.next;
- return to_return;
- }
-
case SAVE_EXPR:
context = decl_function_context (exp);
@@ -6511,11 +6712,7 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
if (context == 0)
SAVE_EXPR_CONTEXT (exp) = current_function_decl;
- /* We treat inline_function_decl as an alias for the current function
- because that is the inline function whose vars, types, etc.
- are being merged into the current function.
- See expand_inline_function. */
- if (context == current_function_decl || context == inline_function_decl)
+ if (context == current_function_decl)
context = 0;
/* If this is non-local, handle it. */
@@ -6637,29 +6834,47 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
case BIND_EXPR:
{
- tree vars = TREE_OPERAND (exp, 0);
+ tree block = BIND_EXPR_BLOCK (exp);
+ int mark_ends;
- /* Need to open a binding contour here because
- if there are any cleanups they must be contained here. */
- expand_start_bindings (2);
+ if (TREE_CODE (BIND_EXPR_BODY (exp)) != RTL_EXPR)
+ {
+ /* If we're in functions-as-trees mode, this BIND_EXPR represents
+ the block, so we need to emit NOTE_INSN_BLOCK_* notes. */
+ mark_ends = (block != NULL_TREE);
+ expand_start_bindings_and_block (mark_ends ? 0 : 2, block);
+ }
+ else
+ {
+ /* If we're not in functions-as-trees mode, we've already emitted
+ those notes into our RTL_EXPR, so we just want to splice our BLOCK
+ into the enclosing one. */
+ mark_ends = 0;
- /* Mark the corresponding BLOCK for output in its proper place. */
- if (TREE_OPERAND (exp, 2) != 0
- && ! TREE_USED (TREE_OPERAND (exp, 2)))
- lang_hooks.decls.insert_block (TREE_OPERAND (exp, 2));
+ /* Need to open a binding contour here because
+ if there are any cleanups they must be contained here. */
+ expand_start_bindings_and_block (2, NULL_TREE);
- /* If VARS have not yet been expanded, expand them now. */
- while (vars)
- {
- if (!DECL_RTL_SET_P (vars))
- expand_decl (vars);
- expand_decl_init (vars);
- vars = TREE_CHAIN (vars);
+ /* Mark the corresponding BLOCK for output in its proper place. */
+ if (block)
+ {
+ if (TREE_USED (block))
+ abort ();
+ (*lang_hooks.decls.insert_block) (block);
+ }
}
- temp = expand_expr (TREE_OPERAND (exp, 1), target, tmode, modifier);
+ /* If VARS have not yet been expanded, expand them now. */
+ expand_vars (BIND_EXPR_VARS (exp));
+
+ /* TARGET was clobbered early in this function. The correct
+ indicator or whether or not we need the value of this
+ expression is the IGNORE variable. */
+ temp = expand_expr (BIND_EXPR_BODY (exp),
+ ignore ? const0_rtx : target,
+ tmode, modifier);
- expand_end_bindings (TREE_OPERAND (exp, 0), 0, 0);
+ expand_end_bindings (BIND_EXPR_VARS (exp), mark_ends, 0);
return temp;
}
@@ -6712,9 +6927,7 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
&& (! MOVE_BY_PIECES_P
(tree_low_cst (TYPE_SIZE_UNIT (type), 1),
TYPE_ALIGN (type)))
- && ((TREE_CODE (type) == VECTOR_TYPE
- && !is_zeros_p (exp))
- || ! mostly_zeros_p (exp)))))
+ && ! mostly_zeros_p (exp))))
|| ((modifier == EXPAND_INITIALIZER
|| modifier == EXPAND_CONST_ADDRESS)
&& TREE_CONSTANT (exp)))
@@ -6749,19 +6962,15 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
case INDIRECT_REF:
{
tree exp1 = TREE_OPERAND (exp, 0);
- tree index;
- tree string = string_constant (exp1, &index);
- /* Try to optimize reads from const strings. */
- if (string
- && TREE_CODE (string) == STRING_CST
- && TREE_CODE (index) == INTEGER_CST
- && compare_tree_int (index, TREE_STRING_LENGTH (string)) < 0
- && GET_MODE_CLASS (mode) == MODE_INT
- && GET_MODE_SIZE (mode) == 1
- && modifier != EXPAND_WRITE)
- return gen_int_mode (TREE_STRING_POINTER (string)
- [TREE_INT_CST_LOW (index)], mode);
+ if (modifier != EXPAND_WRITE)
+ {
+ tree t;
+
+ t = fold_read_from_constant_string (exp);
+ if (t)
+ return expand_expr (t, target, tmode, modifier);
+ }
op0 = expand_expr (exp1, NULL_RTX, VOIDmode, EXPAND_SUM);
op0 = memory_address (mode, op0);
@@ -6778,8 +6987,11 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
}
case ARRAY_REF:
+
+#ifdef ENABLE_CHECKING
if (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) != ARRAY_TYPE)
abort ();
+#endif
{
tree array = TREE_OPERAND (exp, 0);
@@ -6806,14 +7018,13 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
if (modifier != EXPAND_CONST_ADDRESS
&& modifier != EXPAND_INITIALIZER
- && modifier != EXPAND_MEMORY
- && TREE_CODE (array) == STRING_CST
- && TREE_CODE (index) == INTEGER_CST
- && compare_tree_int (index, TREE_STRING_LENGTH (array)) < 0
- && GET_MODE_CLASS (mode) == MODE_INT
- && GET_MODE_SIZE (mode) == 1)
- return gen_int_mode (TREE_STRING_POINTER (array)
- [TREE_INT_CST_LOW (index)], mode);
+ && modifier != EXPAND_MEMORY)
+ {
+ tree t = fold_read_from_constant_string (exp);
+
+ if (t)
+ return expand_expr (t, target, tmode, modifier);
+ }
/* If this is a constant index into a constant array,
just get the value from the array. Handle both the cases when
@@ -8183,7 +8394,77 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
(ignore ? const0_rtx : target),
VOIDmode, modifier, alt_rtl);
+ case STATEMENT_LIST:
+ {
+ tree_stmt_iterator iter;
+
+ if (!ignore)
+ abort ();
+
+ for (iter = tsi_start (exp); !tsi_end_p (iter); tsi_next (&iter))
+ expand_expr (tsi_stmt (iter), const0_rtx, VOIDmode, modifier);
+ }
+ return const0_rtx;
+
case COND_EXPR:
+ /* If it's void, we don't need to worry about computing a value. */
+ if (VOID_TYPE_P (TREE_TYPE (exp)))
+ {
+ tree pred = TREE_OPERAND (exp, 0);
+ tree then_ = TREE_OPERAND (exp, 1);
+ tree else_ = TREE_OPERAND (exp, 2);
+
+ /* If we do not have any pending cleanups or stack_levels
+ to restore, and at least one arm of the COND_EXPR is a
+ GOTO_EXPR to a local label, then we can emit more efficient
+ code by using jumpif/jumpifnot instead of the 'if' machinery. */
+ if (! optimize
+ || containing_blocks_have_cleanups_or_stack_level ())
+ ;
+ else if (TREE_CODE (then_) == GOTO_EXPR
+ && TREE_CODE (GOTO_DESTINATION (then_)) == LABEL_DECL)
+ {
+ jumpif (pred, label_rtx (GOTO_DESTINATION (then_)));
+ return expand_expr (else_, const0_rtx, VOIDmode, 0);
+ }
+ else if (TREE_CODE (else_) == GOTO_EXPR
+ && TREE_CODE (GOTO_DESTINATION (else_)) == LABEL_DECL)
+ {
+ jumpifnot (pred, label_rtx (GOTO_DESTINATION (else_)));
+ return expand_expr (then_, const0_rtx, VOIDmode, 0);
+ }
+
+ /* Just use the 'if' machinery. */
+ expand_start_cond (pred, 0);
+ start_cleanup_deferral ();
+ expand_expr (then_, const0_rtx, VOIDmode, 0);
+
+ exp = else_;
+
+ /* Iterate over 'else if's instead of recursing. */
+ for (; TREE_CODE (exp) == COND_EXPR; exp = TREE_OPERAND (exp, 2))
+ {
+ expand_start_else ();
+ if (EXPR_HAS_LOCATION (exp))
+ {
+ emit_line_note (EXPR_LOCATION (exp));
+ if (cfun->dont_emit_block_notes)
+ record_block_change (TREE_BLOCK (exp));
+ }
+ expand_elseif (TREE_OPERAND (exp, 0));
+ expand_expr (TREE_OPERAND (exp, 1), const0_rtx, VOIDmode, 0);
+ }
+ /* Don't emit the jump and label if there's no 'else' clause. */
+ if (TREE_SIDE_EFFECTS (exp))
+ {
+ expand_start_else ();
+ expand_expr (exp, const0_rtx, VOIDmode, 0);
+ }
+ end_cleanup_deferral ();
+ expand_end_cond ();
+ return const0_rtx;
+ }
+
/* If we would have a "singleton" (see below) were it not for a
conversion in each arm, bring that conversion back out. */
if (TREE_CODE (TREE_OPERAND (exp, 1)) == NOP_EXPR
@@ -8525,8 +8806,6 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
else
{
target = assign_temp (type, 2, 0, 1);
- /* All temp slots at this level must not conflict. */
- preserve_temp_slots (target);
SET_DECL_RTL (slot, target);
if (TREE_ADDRESSABLE (slot))
put_var_into_stack (slot, /*rescan=*/false);
@@ -8663,18 +8942,9 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
case ADDR_EXPR:
if (modifier == EXPAND_STACK_PARM)
target = 0;
- /* Are we taking the address of a nested function? */
- if (TREE_CODE (TREE_OPERAND (exp, 0)) == FUNCTION_DECL
- && decl_function_context (TREE_OPERAND (exp, 0)) != 0
- && ! DECL_NO_STATIC_CHAIN (TREE_OPERAND (exp, 0))
- && ! TREE_STATIC (exp))
- {
- op0 = trampoline_address (TREE_OPERAND (exp, 0));
- op0 = force_operand (op0, target);
- }
/* If we are taking the address of something erroneous, just
return a zero. */
- else if (TREE_CODE (TREE_OPERAND (exp, 0)) == ERROR_MARK)
+ if (TREE_CODE (TREE_OPERAND (exp, 0)) == ERROR_MARK)
return const0_rtx;
/* If we are taking the address of a constant and are at the
top level, we have to use output_constant_def since we can't
@@ -8901,25 +9171,38 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
return target;
}
+ case RESX_EXPR:
+ expand_resx_expr (exp);
+ return const0_rtx;
+
case TRY_CATCH_EXPR:
{
tree handler = TREE_OPERAND (exp, 1);
expand_eh_region_start ();
-
op0 = expand_expr (TREE_OPERAND (exp, 0), 0, VOIDmode, 0);
-
- expand_eh_region_end_cleanup (handler);
+ expand_eh_handler (handler);
return op0;
}
+ case CATCH_EXPR:
+ expand_start_catch (CATCH_TYPES (exp));
+ expand_expr (CATCH_BODY (exp), const0_rtx, VOIDmode, 0);
+ expand_end_catch ();
+ return const0_rtx;
+
+ case EH_FILTER_EXPR:
+ /* Should have been handled in expand_eh_handler. */
+ abort ();
+
case TRY_FINALLY_EXPR:
{
tree try_block = TREE_OPERAND (exp, 0);
tree finally_block = TREE_OPERAND (exp, 1);
- if (!optimize || unsafe_for_reeval (finally_block) > 1)
+ if ((!optimize && lang_protect_cleanup_actions == NULL)
+ || unsafe_for_reeval (finally_block) > 1)
{
/* In this case, wrapping FINALLY_BLOCK in an UNSAVE_EXPR
is not sufficient, so we cannot expand the block twice.
@@ -8988,11 +9271,99 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
case EXC_PTR_EXPR:
return get_exception_pointer (cfun);
+ case FILTER_EXPR:
+ return get_exception_filter (cfun);
+
case FDESC_EXPR:
/* Function descriptors are not valid except for as
initialization constants, and should not be expanded. */
abort ();
+ case SWITCH_EXPR:
+ expand_start_case (0, SWITCH_COND (exp), integer_type_node,
+ "switch");
+ if (SWITCH_BODY (exp))
+ expand_expr_stmt (SWITCH_BODY (exp));
+ if (SWITCH_LABELS (exp))
+ {
+ tree duplicate = 0;
+ tree vec = SWITCH_LABELS (exp);
+ size_t i, n = TREE_VEC_LENGTH (vec);
+
+ for (i = 0; i < n; ++i)
+ {
+ tree elt = TREE_VEC_ELT (vec, i);
+ tree controlling_expr_type = TREE_TYPE (SWITCH_COND (exp));
+ tree min_value = TYPE_MIN_VALUE (controlling_expr_type);
+ tree max_value = TYPE_MAX_VALUE (controlling_expr_type);
+
+ tree case_low = CASE_LOW (elt);
+ tree case_high = CASE_HIGH (elt) ? CASE_HIGH (elt) : case_low;
+ if (case_low && case_high)
+ {
+ /* Case label is less than minimum for type. */
+ if ((tree_int_cst_compare (case_low, min_value) < 0)
+ && (tree_int_cst_compare (case_high, min_value) < 0))
+ {
+ warning ("case label value %d is less than minimum value for type",
+ TREE_INT_CST (case_low));
+ continue;
+ }
+
+ /* Case value is greater than maximum for type. */
+ if ((tree_int_cst_compare (case_low, max_value) > 0)
+ && (tree_int_cst_compare (case_high, max_value) > 0))
+ {
+ warning ("case label value %d exceeds maximum value for type",
+ TREE_INT_CST (case_high));
+ continue;
+ }
+
+ /* Saturate lower case label value to minimum. */
+ if ((tree_int_cst_compare (case_high, min_value) >= 0)
+ && (tree_int_cst_compare (case_low, min_value) < 0))
+ {
+ warning ("lower value %d in case label range less than minimum value for type",
+ TREE_INT_CST (case_low));
+ case_low = min_value;
+ }
+
+ /* Saturate upper case label value to maximum. */
+ if ((tree_int_cst_compare (case_low, max_value) <= 0)
+ && (tree_int_cst_compare (case_high, max_value) > 0))
+ {
+ warning ("upper value %d in case label range exceeds maximum value for type",
+ TREE_INT_CST (case_high));
+ case_high = max_value;
+ }
+ }
+
+ add_case_node (case_low, case_high, CASE_LABEL (elt), &duplicate, true);
+ if (duplicate)
+ abort ();
+ }
+ }
+ expand_end_case_type (SWITCH_COND (exp), TREE_TYPE (exp));
+ return const0_rtx;
+
+ case LABEL_EXPR:
+ expand_label (TREE_OPERAND (exp, 0));
+ return const0_rtx;
+
+ case CASE_LABEL_EXPR:
+ {
+ tree duplicate = 0;
+ add_case_node (CASE_LOW (exp), CASE_HIGH (exp), CASE_LABEL (exp),
+ &duplicate, false);
+ if (duplicate)
+ abort ();
+ return const0_rtx;
+ }
+
+ case ASM_EXPR:
+ expand_asm_expr (exp);
+ return const0_rtx;
+
default:
/* ??? Use (*fun) form because expand_expr is a macro. */
return (*lang_hooks.expand_expr) (exp, original_target, tmode,
@@ -9073,6 +9444,13 @@ string_constant (tree arg, tree *ptr_offset)
*ptr_offset = size_zero_node;
return TREE_OPERAND (arg, 0);
}
+ if (TREE_CODE (arg) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (arg, 0)) == ARRAY_REF
+ && TREE_CODE (TREE_OPERAND (TREE_OPERAND (arg, 0), 0)) == STRING_CST)
+ {
+ *ptr_offset = convert (sizetype, TREE_OPERAND (TREE_OPERAND (arg, 0), 1));
+ return TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
+ }
else if (TREE_CODE (arg) == PLUS_EXPR)
{
tree arg0 = TREE_OPERAND (arg, 0);
@@ -9793,7 +10171,7 @@ const_vector_from_tree (tree exp)
mode = TYPE_MODE (TREE_TYPE (exp));
- if (is_zeros_p (exp))
+ if (initializer_zerop (exp))
return CONST0_RTX (mode);
units = GET_MODE_NUNITS (mode);
diff --git a/gcc/expr.h b/gcc/expr.h
index 5c7bbbe6c51..002bcfc892d 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -366,6 +366,9 @@ extern void record_base_value (unsigned int, rtx, int);
extern void record_alias_subset (HOST_WIDE_INT, HOST_WIDE_INT);
extern HOST_WIDE_INT new_alias_set (void);
extern int can_address_p (tree);
+extern tree simplify_builtin_fputs (tree, int, int, tree);
+extern tree simplify_builtin_strcpy (tree, tree);
+extern tree simplify_builtin_strncpy (tree, tree);
/* Functions from expr.c: */
@@ -513,6 +516,8 @@ extern rtx force_operand (rtx, rtx);
extern rtx expand_expr_real (tree, rtx, enum machine_mode,
enum expand_modifier, rtx *);
+extern void expand_var (tree);
+
/* At the start of a function, record that we have no previously-pushed
arguments waiting to be popped. */
extern void init_pending_stack_adjust (void);
@@ -561,8 +566,6 @@ extern rtx expr_size (tree);
if the size can vary or is larger than an integer. */
extern HOST_WIDE_INT int_expr_size (tree);
-extern rtx lookup_static_chain (tree);
-
/* Convert a stack slot address ADDR valid in function FNDECL
into an address valid in this function (using a static chain). */
extern rtx fix_lexical_addr (rtx, tree);
@@ -574,10 +577,12 @@ extern rtx trampoline_address (tree);
in its original home. This becomes invalid if any more code is emitted. */
extern rtx hard_function_value (tree, tree, int);
-extern rtx prepare_call_address (rtx, tree, rtx *, int, int);
+extern rtx prepare_call_address (rtx, rtx, rtx *, int, int);
extern rtx expand_call (tree, rtx, int);
+extern void fixup_tail_calls (void);
+
#ifdef TREE_CODE
extern rtx expand_shift (enum tree_code, enum machine_mode, rtx, tree, rtx,
int);
@@ -588,7 +593,6 @@ extern rtx expand_divmod (int, enum tree_code, enum machine_mode, rtx, rtx,
extern void locate_and_pad_parm (enum machine_mode, tree, int, int, tree,
struct args_size *,
struct locate_and_pad_arg_data *);
-extern rtx expand_inline_function (tree, tree, rtx, int, tree, rtx);
/* Return the CODE_LABEL rtx for a LABEL_DECL, creating it if necessary. */
extern rtx label_rtx (tree);
@@ -742,6 +746,9 @@ extern void emit_stack_save (enum save_level, rtx *, rtx);
/* Restore the stack pointer from a save area of the specified level. */
extern void emit_stack_restore (enum save_level, rtx, rtx);
+/* Invoke emit_stack_save for the nonlocal_goto_save_area. */
+extern void update_nonlocal_goto_save_area (void);
+
/* Allocate some space on the stack dynamically and return its address. An rtx
says how many bytes. */
extern rtx allocate_dynamic_stack_space (rtx, rtx, int);
@@ -796,6 +803,4 @@ extern void do_jump_by_parts_equality_rtx (rtx, rtx, rtx);
extern void do_jump_by_parts_greater_rtx (enum machine_mode, int, rtx, rtx,
rtx, rtx);
-extern void mark_seen_cases (tree, unsigned char *, HOST_WIDE_INT, int);
-
extern int vector_mode_valid_p (enum machine_mode);
diff --git a/gcc/f/ChangeLog b/gcc/f/ChangeLog
index 122e4906c46..0d3532e5da6 100644
--- a/gcc/f/ChangeLog
+++ b/gcc/f/ChangeLog
@@ -1,3 +1,14 @@
+2004-05-13 Diego Novillo <dnovillo@redhat.com>
+
+ Merge from tree-ssa-20020619-branch.
+
+ * config-lang.in (build_by_default): Set to no.
+
+2004-04-18 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * g77.texi (Floating-point Errors): Avoid referencing
+ http://www.linuxsupportline.com/~billm/ which as has been hijacked.
+
2004-04-02 Jan Hubicka <jh@suse.cz>
* Make-lang.in (com.o): Add dependnecy on function.h
diff --git a/gcc/f/ChangeLog.tree-ssa b/gcc/f/ChangeLog.tree-ssa
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/gcc/f/ChangeLog.tree-ssa
diff --git a/gcc/f/config-lang.in b/gcc/f/config-lang.in
index 92ba5cca73e..8ec70f7af8c 100644
--- a/gcc/f/config-lang.in
+++ b/gcc/f/config-lang.in
@@ -34,3 +34,5 @@ stagestuff="g77\$(exeext) g77-cross\$(exeext) f771\$(exeext)"
target_libs=target-libf2c
gtfiles="\$(srcdir)/f/com.c \$(srcdir)/f/com.h \$(srcdir)/f/ste.c \$(srcdir)/f/where.h \$(srcdir)/f/where.c \$(srcdir)/f/lex.c"
+
+build_by_default=no
diff --git a/gcc/f/g77.texi b/gcc/f/g77.texi
index b0d7805280e..d97f69c6b8c 100644
--- a/gcc/f/g77.texi
+++ b/gcc/f/g77.texi
@@ -8618,9 +8618,6 @@ floating-point standard by a leading light can be found at
@uref{http://http.cs.berkeley.edu/%7Ewkahan/ieee754status/};
see also slides from the short course referenced from
@uref{http://http.cs.berkeley.edu/%7Efateman/}.
-@uref{http://www.linuxsupportline.com/%7Ebillm/} has a brief
-guide to IEEE 754, a somewhat x86-GNU/Linux-specific FAQ,
-and library code for GNU/Linux x86 systems.
The supplement to the PostScript-formatted Goldberg document,
referenced above, is available in HTML format.
diff --git a/gcc/final.c b/gcc/final.c
index 9aa4657b068..281b161956f 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -767,6 +767,9 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
/* Compute maximum UID and allocate label_align / uid_shuid. */
max_uid = get_max_uid ();
+ /* Free uid_shuid before reallocating it. */
+ free (uid_shuid);
+
uid_shuid = xmalloc (max_uid * sizeof *uid_shuid);
if (max_labelno != max_label_num ())
@@ -1409,7 +1412,7 @@ profile_function (FILE *file ATTRIBUTE_UNUSED)
int sval = current_function_returns_struct;
rtx svrtx = targetm.calls.struct_value_rtx (TREE_TYPE (current_function_decl), 1);
#if defined(STATIC_CHAIN_INCOMING_REGNUM) || defined(STATIC_CHAIN_REGNUM)
- int cxt = current_function_needs_context;
+ int cxt = cfun->static_chain_decl != NULL;
#endif
#endif /* ASM_OUTPUT_REG_PUSH */
@@ -1516,11 +1519,9 @@ final (rtx first, FILE *file, int optimize, int prescan)
for (insn = first; insn; insn = NEXT_INSN (insn))
if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
{
- if ((RTX_INTEGRATED_P (insn)
- && strcmp (NOTE_SOURCE_FILE (insn), main_input_filename) != 0)
- || (last != 0
- && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last)
- && NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last)))
+ if (last != 0
+ && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last)
+ && NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last))
{
delete_insn (insn); /* Use delete_note. */
continue;
@@ -1713,7 +1714,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
case NOTE_INSN_BASIC_BLOCK:
- /* If we are performing the optimization that paritions
+ /* If we are performing the optimization that partitions
basic blocks into hot & cold sections of the .o file,
then at the start of each new basic block, before
beginning to write code for the basic block, we need to
diff --git a/gcc/fixinc/Makefile.in b/gcc/fixinc/Makefile.in
index 1329e8f09d7..22ea44ff9f2 100644
--- a/gcc/fixinc/Makefile.in
+++ b/gcc/fixinc/Makefile.in
@@ -29,7 +29,7 @@ SHELL=@SHELL@
# in the kernel. So, we use `echo' instead.
STAMP = echo timestamp >
-FL_LIST = $(CFLAGS) $(CPPFLAGS) $(WARN_CFLAGS)
+FL_LIST = $(CFLAGS) $(CPPFLAGS)
FIXINC_DEFS = -DIN_GCC -DHAVE_CONFIG_H $(FL_LIST) $(INCLUDES)
# Directory where sources are, from where we are.
@@ -94,9 +94,6 @@ test-stamp : $(TESTOBJ) $(LIBERTY)
$(AF): $(FIXOBJ) $(LIBERTY)
$(CC) $(FIXINC_DEFS) $(LDFLAGS) -o $@ $(FIXOBJ) $(LIBERTY)
-# String length warnings
-fixincl.o-warn = -Wno-error
-
$(ALLOBJ) : $(HDR)
fixincl.o : fixincl.c $(srcdir)/fixincl.x
fixtests.o : fixtests.c
diff --git a/gcc/fixinc/fixincl.x b/gcc/fixinc/fixincl.x
index f3a1149dce1..a1b650e5dc6 100644
--- a/gcc/fixinc/fixincl.x
+++ b/gcc/fixinc/fixincl.x
@@ -2,11 +2,11 @@
*
* DO NOT EDIT THIS FILE (fixincl.x)
*
- * It has been AutoGen-ed Wednesday April 7, 2004 at 10:23:41 PM UTC
+ * It has been AutoGen-ed Monday May 3, 2004 at 05:17:48 PM MEST
* From the definitions inclhack.def
* and the template file fixincl
*/
-/* DO NOT CVS-MERGE THIS FILE, EITHER Wed Apr 7 22:23:41 UTC 2004
+/* DO NOT CVS-MERGE THIS FILE, EITHER Mon May 3 17:17:49 MEST 2004
*
* You must regenerate it. Use the ./genfixes script.
*
@@ -15,7 +15,7 @@
* certain ANSI-incompatible system header files which are fixed to work
* correctly with ANSI C and placed in a directory that GNU C will search.
*
- * This file contains 174 fixup descriptions.
+ * This file contains 175 fixup descriptions.
*
* See README for more information.
*
@@ -649,6 +649,41 @@ static const char* apzAix_SyswaitPatch[] = {
/* * * * * * * * * * * * * * * * * * * * * * * * * *
*
+ * Description of Aix_Syswait_2 fix
+ */
+tSCC zAix_Syswait_2Name[] =
+ "aix_syswait_2";
+
+/*
+ * File name selection pattern
+ */
+tSCC zAix_Syswait_2List[] =
+ "|sys/wait.h|";
+/*
+ * Machine/OS name selection pattern
+ */
+#define apzAix_Syswait_2Machs (const char**)NULL
+
+/*
+ * content selection pattern - do fix if pattern found
+ */
+tSCC zAix_Syswait_2Select0[] =
+ "\\? (\\(\\(\\(\\(unsigned[^)]*\\)[^)]*\\) >> [^)]*\\) \\& 0xff\\) : -1)";
+
+#define AIX_SYSWAIT_2_TEST_CT 1
+static tTestDesc aAix_Syswait_2Tests[] = {
+ { TT_EGREP, zAix_Syswait_2Select0, (regex_t*)NULL }, };
+
+/*
+ * Fix Command Arguments for Aix_Syswait_2
+ */
+static const char* apzAix_Syswait_2Patch[] = {
+ "format",
+ "? (int)%1",
+ (char*)NULL };
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
* Description of Aix_Volatile fix
*/
tSCC zAix_VolatileName[] =
@@ -5347,8 +5382,15 @@ tSCC zSvr4_ProfilList[] =
tSCC zSvr4_ProfilSelect0[] =
"profil\\(unsigned short \\*, unsigned int, unsigned int, unsigned int\\)";
-#define SVR4_PROFIL_TEST_CT 1
+/*
+ * content bypass pattern - skip fix if pattern found
+ */
+tSCC zSvr4_ProfilBypass0[] =
+ "Silicon Graphics";
+
+#define SVR4_PROFIL_TEST_CT 2
static tTestDesc aSvr4_ProfilTests[] = {
+ { TT_NEGREP, zSvr4_ProfilBypass0, (regex_t*)NULL },
{ TT_EGREP, zSvr4_ProfilSelect0, (regex_t*)NULL }, };
/*
@@ -6894,9 +6936,9 @@ static const char* apzX11_SprintfPatch[] = {
*
* List of all fixes
*/
-#define REGEX_COUNT 195
+#define REGEX_COUNT 197
#define MACH_LIST_SIZE_LIMIT 261
-#define FIX_COUNT 174
+#define FIX_COUNT 175
/*
* Enumerate the fixes
@@ -6914,6 +6956,7 @@ typedef enum {
AIX_PTHREAD_FIXIDX,
AIX_SYSMACHINE_FIXIDX,
AIX_SYSWAIT_FIXIDX,
+ AIX_SYSWAIT_2_FIXIDX,
AIX_VOLATILE_FIXIDX,
ALPHA___ASSERT_FIXIDX,
ALPHA___EXTERN_PREFIX_FIXIDX,
@@ -7139,6 +7182,11 @@ tFixDesc fixDescList[ FIX_COUNT ] = {
AIX_SYSWAIT_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
aAix_SyswaitTests, apzAix_SyswaitPatch, 0 },
+ { zAix_Syswait_2Name, zAix_Syswait_2List,
+ apzAix_Syswait_2Machs,
+ AIX_SYSWAIT_2_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
+ aAix_Syswait_2Tests, apzAix_Syswait_2Patch, 0 },
+
{ zAix_VolatileName, zAix_VolatileList,
apzAix_VolatileMachs,
AIX_VOLATILE_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
diff --git a/gcc/fixinc/inclhack.def b/gcc/fixinc/inclhack.def
index 086b8c0d420..aa26ff7c013 100644
--- a/gcc/fixinc/inclhack.def
+++ b/gcc/fixinc/inclhack.def
@@ -494,6 +494,20 @@ fix = {
/*
+ * sys/wait.h on AIX 5.2 defines macros that have both signed and
+ * unsigned types in conditional expressions.
+ */
+fix = {
+ hackname = aix_syswait_2;
+ files = sys/wait.h;
+ select = '\? (\(\(\(\(unsigned[^)]*\)[^)]*\) >> [^)]*\) \& 0xff\) : -1)';
+ c_fix = format;
+ c_fix_arg = "? (int)%1";
+ test_text = "#define WSTOPSIG(__x) (int)(WIFSTOPPED(__x) ? ((((unsigned int)__x) >> 8) & 0xff) : -1)";
+};
+
+
+/*
* sys/signal.h on some versions of AIX uses volatile in the typedef of
* sig_atomic_t, which causes gcc to generate a warning about duplicate
* volatile when a sig_atomic_t variable is declared volatile, as
@@ -3147,6 +3161,9 @@ fix = {
select =
'profil\(unsigned short \*, unsigned int, unsigned int, unsigned int\)';
+ /* The fix is wrong on IRIX 5/6 and creates a conflict with another
+ prototype in <sys/profil.h>. */
+ bypass = 'Silicon Graphics';
c_fix = format;
c_fix_arg = 'profil(unsigned short *, size_t, int, unsigned int)';
diff --git a/gcc/fixinc/tests/base/sys/wait.h b/gcc/fixinc/tests/base/sys/wait.h
index c0edf05f1cd..a0311c65d0f 100644
--- a/gcc/fixinc/tests/base/sys/wait.h
+++ b/gcc/fixinc/tests/base/sys/wait.h
@@ -17,6 +17,11 @@ extern pid_t wait3();
#endif /* AIX_SYSWAIT_CHECK */
+#if defined( AIX_SYSWAIT_2_CHECK )
+#define WSTOPSIG(__x) (int)(WIFSTOPPED(__x) ? (int)((((unsigned int)__x) >> 8) & 0xff) : -1)
+#endif /* AIX_SYSWAIT_2_CHECK */
+
+
#if defined( NEXT_WAIT_UNION_CHECK )
extern pid_d wait(void*);
#endif /* NEXT_WAIT_UNION_CHECK */
diff --git a/gcc/flags.h b/gcc/flags.h
index 472df5426d6..8778b635392 100644
--- a/gcc/flags.h
+++ b/gcc/flags.h
@@ -244,7 +244,8 @@ extern int flag_print_asm_name;
extern int flag_signed_char;
-/* Nonzero means give an enum type only as many bytes as it needs. */
+/* Nonzero means give an enum type only as many bytes as it needs. A value
+ of 2 means it has not yet been initialized. */
extern int flag_short_enums;
@@ -407,6 +408,10 @@ extern int flag_really_no_inline;
extern int flag_syntax_only;
extern int rtl_dump_and_exit;
+/* Nonzero if we are exiting on the first error occurred. */
+
+extern int flag_fatal_errors;
+
/* Nonzero means we should save auxiliary info into a .X file. */
extern int flag_gen_aux_info;
@@ -715,6 +720,53 @@ extern int flag_detailed_statistics;
/* Nonzero means enable synchronous exceptions for non-call instructions. */
extern int flag_non_call_exceptions;
+/* Nonzero means enable mudflap bounds-checking transforms;
+ >1 means also to include multithreading locks. */
+extern int flag_mudflap;
+extern int flag_mudflap_threads;
+extern int flag_mudflap_ignore_reads;
+
+/* Enable SSA-PRE on trees. */
+extern int flag_tree_pre;
+
+/* Enable SSA-CCP on trees. */
+extern int flag_tree_ccp;
+
+/* Enable SSA-DCE on trees. */
+extern int flag_tree_dce;
+
+/* Enable SSA->normal pass memory location coalescing. */
+extern int flag_tree_combine_temps;
+
+/* Enable SSA->normal pass expression replacement. */
+extern int flag_tree_ter;
+
+/* Enable SSA_>normal live range splitting. */
+extern int flag_tree_live_range_split;
+
+/* Enable dominator optimizations. */
+extern int flag_tree_dom;
+
+/* Enable loop header copying on tree-ssa. */
+extern int flag_tree_ch;
+
+/* Enable dead store and redundant load elimination */
+extern int flag_tree_dse;
+
+/* Enable scalar replacement of aggregates. */
+extern int flag_tree_sra;
+
+/* Enable copy rename optimization. */
+extern int flag_tree_copyrename;
+
+/* Enable points-to analysis on trees. */
+enum pta_type
+ {
+ PTA_NONE,
+ PTA_ANDERSEN
+ };
+extern enum pta_type flag_tree_points_to;
+
/* Nonzero means put zero initialized data in the bss section. */
extern int flag_zero_initialized_in_bss;
diff --git a/gcc/flow.c b/gcc/flow.c
index 686292cf9ab..fa47f2d24a0 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -192,10 +192,6 @@ regset regs_live_at_setjmp;
are another pair, etc. */
rtx regs_may_share;
-/* Callback that determines if it's ok for a function to have no
- noreturn attribute. */
-int (*lang_missing_noreturn_ok_p) (tree);
-
/* Set of registers that may be eliminable. These are handled specially
in updating regs_ever_live. */
@@ -334,48 +330,6 @@ static void invalidate_mems_from_set (struct propagate_block_info *, rtx);
static void clear_log_links (sbitmap);
static int count_or_remove_death_notes_bb (basic_block, int);
-
-void
-check_function_return_warnings (void)
-{
- if (warn_missing_noreturn
- && !TREE_THIS_VOLATILE (cfun->decl)
- && EXIT_BLOCK_PTR->pred == NULL
- && (lang_missing_noreturn_ok_p
- && !lang_missing_noreturn_ok_p (cfun->decl)))
- warning ("function might be possible candidate for attribute `noreturn'");
-
- /* If we have a path to EXIT, then we do return. */
- if (TREE_THIS_VOLATILE (cfun->decl)
- && EXIT_BLOCK_PTR->pred != NULL)
- warning ("`noreturn' function does return");
-
- /* If the clobber_return_insn appears in some basic block, then we
- do reach the end without returning a value. */
- else if (warn_return_type
- && cfun->x_clobber_return_insn != NULL
- && EXIT_BLOCK_PTR->pred != NULL)
- {
- int max_uid = get_max_uid ();
-
- /* If clobber_return_insn was excised by jump1, then renumber_insns
- can make max_uid smaller than the number still recorded in our rtx.
- That's fine, since this is a quick way of verifying that the insn
- is no longer in the chain. */
- if (INSN_UID (cfun->x_clobber_return_insn) < max_uid)
- {
- rtx insn;
-
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- if (insn == cfun->x_clobber_return_insn)
- {
- warning ("control reaches end of non-void function");
- break;
- }
- }
- }
-}
-
/* Return the INSN immediately following the NOTE_INSN_BASIC_BLOCK
note associated with the BLOCK. */
@@ -488,8 +442,6 @@ life_analysis (rtx f, FILE *file, int flags)
if (file)
dump_flow_info (file);
- free_basic_block_vars (1);
-
/* Removing dead insns should have made jumptables really dead. */
delete_dead_jumptables ();
}
@@ -685,8 +637,7 @@ update_life_info (sbitmap blocks, enum update_life_extent extent, int prop_flags
/* Zap the life information from the last round. If we don't
do this, we can wind up with registers that no longer appear
- in the code being marked live at entry, which twiggs bogus
- warnings from regno_uninitialized. */
+ in the code being marked live at entry. */
FOR_EACH_BB (bb)
{
CLEAR_REG_SET (bb->global_live_at_start);
@@ -809,28 +760,23 @@ update_life_info_in_dirty_blocks (enum update_life_extent extent, int prop_flags
return retval;
}
-/* Free the variables allocated by find_basic_blocks.
-
- KEEP_HEAD_END_P is nonzero if basic_block_info is not to be freed. */
+/* Free the variables allocated by find_basic_blocks. */
void
-free_basic_block_vars (int keep_head_end_p)
+free_basic_block_vars (void)
{
- if (! keep_head_end_p)
+ if (basic_block_info)
{
- if (basic_block_info)
- {
- clear_edges ();
- VARRAY_FREE (basic_block_info);
- }
- n_basic_blocks = 0;
- last_basic_block = 0;
-
- ENTRY_BLOCK_PTR->aux = NULL;
- ENTRY_BLOCK_PTR->global_live_at_end = NULL;
- EXIT_BLOCK_PTR->aux = NULL;
- EXIT_BLOCK_PTR->global_live_at_start = NULL;
+ clear_edges ();
+ basic_block_info = NULL;
}
+ n_basic_blocks = 0;
+ last_basic_block = 0;
+
+ ENTRY_BLOCK_PTR->aux = NULL;
+ ENTRY_BLOCK_PTR->global_live_at_end = NULL;
+ EXIT_BLOCK_PTR->aux = NULL;
+ EXIT_BLOCK_PTR->global_live_at_start = NULL;
}
/* Delete any insns that copy a register to itself. */
@@ -1707,12 +1653,18 @@ propagate_one_insn (struct propagate_block_info *pbi, rtx insn)
&& GET_CODE (SET_SRC (PATTERN (insn))) == PLUS
&& XEXP (SET_SRC (PATTERN (insn)), 0) == stack_pointer_rtx
&& GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == CONST_INT)
- /* We have an insn to pop a constant amount off the stack.
- (Such insns use PLUS regardless of the direction of the stack,
- and any insn to adjust the stack by a constant is always a pop.)
- These insns, if not dead stores, have no effect on life, though
- they do have an effect on the memory stores we are tracking. */
- invalidate_mems_from_set (pbi, stack_pointer_rtx);
+ {
+ /* We have an insn to pop a constant amount off the stack.
+ (Such insns use PLUS regardless of the direction of the stack,
+ and any insn to adjust the stack by a constant is always a pop
+ or part of a push.)
+ These insns, if not dead stores, have no effect on life, though
+ they do have an effect on the memory stores we are tracking. */
+ invalidate_mems_from_set (pbi, stack_pointer_rtx);
+ /* Still, we need to update local_set, lest ifcvt.c:dead_or_predicable
+ concludes that the stack pointer is not modified. */
+ mark_set_regs (pbi, PATTERN (insn), insn);
+ }
else
{
rtx note;
@@ -2351,24 +2303,6 @@ libcall_dead_p (struct propagate_block_info *pbi, rtx note, rtx insn)
return 1;
}
-/* Return 1 if register REGNO was used before it was set, i.e. if it is
- live at function entry. Don't count global register variables, variables
- in registers that can be used for function arg passing, or variables in
- fixed hard registers. */
-
-int
-regno_uninitialized (unsigned int regno)
-{
- if (n_basic_blocks == 0
- || (regno < FIRST_PSEUDO_REGISTER
- && (global_regs[regno]
- || fixed_regs[regno]
- || FUNCTION_ARG_REGNO_P (regno))))
- return 0;
-
- return REGNO_REG_SET_P (ENTRY_BLOCK_PTR->global_live_at_end, regno);
-}
-
/* 1 if register REGNO was alive at a place where `setjmp' was called
and was set more than once or is an argument.
Such regs may be clobbered by `longjmp'. */
@@ -4286,7 +4220,6 @@ count_or_remove_death_notes (sbitmap blocks, int kill)
int i;
basic_block bb;
-
/* This used to be a loop over all the blocks with a membership test
inside the loop. That can be amazingly expensive on a large CFG
when only a small number of bits are set in BLOCKs (for example,
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 75ef65c1363..ed54ee93bb6 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -65,12 +65,10 @@ static bool negate_expr_p (tree);
static tree negate_expr (tree);
static tree split_tree (tree, enum tree_code, tree *, tree *, tree *, int);
static tree associate_trees (tree, tree, enum tree_code, tree);
-static tree int_const_binop (enum tree_code, tree, tree, int);
static tree const_binop (enum tree_code, tree, tree, int);
static hashval_t size_htab_hash (const void *);
static int size_htab_eq (const void *, const void *);
static tree fold_convert_const (enum tree_code, tree, tree);
-static tree fold_convert (tree, tree);
static enum tree_code invert_tree_comparison (enum tree_code);
static enum tree_code swap_tree_comparison (enum tree_code);
static int comparison_to_compcode (enum tree_code);
@@ -110,12 +108,14 @@ static bool fold_real_zero_addition_p (tree, tree, int);
static tree fold_mathfn_compare (enum built_in_function, enum tree_code,
tree, tree, tree);
static tree fold_inf_compare (enum tree_code, tree, tree, tree);
+static tree fold_div_compare (enum tree_code, tree, tree, tree);
static bool reorder_operands_p (tree, tree);
static bool tree_swap_operands_p (tree, tree, bool);
static tree fold_negate_const (tree, tree);
static tree fold_abs_const (tree, tree);
static tree fold_relational_const (enum tree_code, tree, tree, tree);
+static tree fold_relational_hi_lo (enum tree_code *, const tree, tree *, tree *);
/* The following constants represent a bit based encoding of GCC's
comparison operators. This encoding simplifies transformations
@@ -1230,7 +1230,7 @@ associate_trees (tree t1, tree t2, enum tree_code code, tree type)
If NOTRUNC is nonzero, do not truncate the result to fit the data type. */
-static tree
+tree
int_const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
{
unsigned HOST_WIDE_INT int1l, int2l;
@@ -1789,6 +1789,10 @@ fold_convert_const (enum tree_code code, tree type, tree arg1)
real_floor (&r, VOIDmode, &x);
break;
+ case FIX_ROUND_EXPR:
+ real_round (&r, VOIDmode, &x);
+ break;
+
default:
abort ();
}
@@ -1875,7 +1879,7 @@ fold_convert_const (enum tree_code code, tree type, tree arg1)
/* Convert expression ARG to type TYPE. Used by the middle-end for
simple conversions in preference to calling the front-end's convert. */
-static tree
+tree
fold_convert (tree type, tree arg)
{
tree orig = TREE_TYPE (arg);
@@ -1986,8 +1990,6 @@ fold_convert (tree type, tree arg)
tree
non_lvalue (tree x)
{
- tree result;
-
/* These things are certainly not lvalues. */
if (TREE_CODE (x) == NON_LVALUE_EXPR
|| TREE_CODE (x) == INTEGER_CST
@@ -1996,9 +1998,7 @@ non_lvalue (tree x)
|| TREE_CODE (x) == ADDR_EXPR)
return x;
- result = build1 (NON_LVALUE_EXPR, TREE_TYPE (x), x);
- TREE_CONSTANT (result) = TREE_CONSTANT (x);
- return result;
+ return build1 (NON_LVALUE_EXPR, TREE_TYPE (x), x);
}
/* Nonzero means lvalues are limited to those valid in pedantic ANSI C.
@@ -2134,16 +2134,16 @@ truth_value_p (enum tree_code code)
/* Return nonzero if two operands (typically of the same tree node)
are necessarily equal. If either argument has side-effects this
- function returns zero.
+ function returns zero. FLAGS modifies behaviour as follows:
- If ONLY_CONST is nonzero, only return nonzero for constants.
+ If OEP_ONLY_CONST is set, only return nonzero for constants.
This function tests whether the operands are indistinguishable;
it does not test whether they are equal using C's == operation.
The distinction is important for IEEE floating point, because
(1) -0.0 and 0.0 are distinguishable, but -0.0==0.0, and
(2) two NaNs may be indistinguishable, but NaN!=NaN.
- If ONLY_CONST is zero, a VAR_DECL is considered equal to itself
+ If OEP_ONLY_CONST is unset, a VAR_DECL is considered equal to itself
even though it may hold multiple values during a function.
This is because a GCC tree node guarantees that nothing else is
executed between the evaluation of its "operands" (which may often
@@ -2152,13 +2152,15 @@ truth_value_p (enum tree_code code)
same value in each operand/subexpression. Hence a zero value for
ONLY_CONST assumes isochronic (or instantaneous) tree equivalence.
If comparing arbitrary expression trees, such as from different
- statements, ONLY_CONST must usually be nonzero. */
+ statements, ONLY_CONST must usually be nonzero.
+
+ If OEP_PURE_SAME is set, then pure functions with identical arguments
+ are considered the same. It is used when the caller has other ways
+ to ensure that global memory is unchanged in between. */
int
-operand_equal_p (tree arg0, tree arg1, int only_const)
+operand_equal_p (tree arg0, tree arg1, unsigned int flags)
{
- tree fndecl;
-
/* If either is ERROR_MARK, they aren't equal. */
if (TREE_CODE (arg0) == ERROR_MARK || TREE_CODE (arg1) == ERROR_MARK)
return 0;
@@ -2187,7 +2189,7 @@ operand_equal_p (tree arg0, tree arg1, int only_const)
expressions with side effects that should be treated the same due
to the only side effects being identical SAVE_EXPR's, that will
be detected in the recursive calls below. */
- if (arg0 == arg1 && ! only_const
+ if (arg0 == arg1 && ! (flags & OEP_ONLY_CONST)
&& (TREE_CODE (arg0) == SAVE_EXPR
|| (! TREE_SIDE_EFFECTS (arg0) && ! TREE_SIDE_EFFECTS (arg1))))
return 1;
@@ -2221,7 +2223,7 @@ operand_equal_p (tree arg0, tree arg1, int only_const)
while (v1 && v2)
{
if (!operand_equal_p (TREE_VALUE (v1), TREE_VALUE (v2),
- only_const))
+ flags))
return 0;
v1 = TREE_CHAIN (v1);
v2 = TREE_CHAIN (v2);
@@ -2232,9 +2234,9 @@ operand_equal_p (tree arg0, tree arg1, int only_const)
case COMPLEX_CST:
return (operand_equal_p (TREE_REALPART (arg0), TREE_REALPART (arg1),
- only_const)
+ flags)
&& operand_equal_p (TREE_IMAGPART (arg0), TREE_IMAGPART (arg1),
- only_const));
+ flags));
case STRING_CST:
return (TREE_STRING_LENGTH (arg0) == TREE_STRING_LENGTH (arg1)
@@ -2249,7 +2251,7 @@ operand_equal_p (tree arg0, tree arg1, int only_const)
break;
}
- if (only_const)
+ if (flags & OEP_ONLY_CONST)
return 0;
switch (TREE_CODE_CLASS (TREE_CODE (arg0)))
@@ -2262,7 +2264,7 @@ operand_equal_p (tree arg0, tree arg1, int only_const)
return 0;
return operand_equal_p (TREE_OPERAND (arg0, 0),
- TREE_OPERAND (arg1, 0), 0);
+ TREE_OPERAND (arg1, 0), flags);
case '<':
case '2':
@@ -2274,9 +2276,9 @@ operand_equal_p (tree arg0, tree arg1, int only_const)
/* For commutative ops, allow the other order. */
return (commutative_tree_code (TREE_CODE (arg0))
&& operand_equal_p (TREE_OPERAND (arg0, 0),
- TREE_OPERAND (arg1, 1), 0)
+ TREE_OPERAND (arg1, 1), flags)
&& operand_equal_p (TREE_OPERAND (arg0, 1),
- TREE_OPERAND (arg1, 0), 0));
+ TREE_OPERAND (arg1, 0), flags));
case 'r':
/* If either of the pointer (or reference) expressions we are
@@ -2289,23 +2291,23 @@ operand_equal_p (tree arg0, tree arg1, int only_const)
{
case INDIRECT_REF:
return operand_equal_p (TREE_OPERAND (arg0, 0),
- TREE_OPERAND (arg1, 0), 0);
+ TREE_OPERAND (arg1, 0), flags);
case COMPONENT_REF:
case ARRAY_REF:
case ARRAY_RANGE_REF:
return (operand_equal_p (TREE_OPERAND (arg0, 0),
- TREE_OPERAND (arg1, 0), 0)
+ TREE_OPERAND (arg1, 0), flags)
&& operand_equal_p (TREE_OPERAND (arg0, 1),
- TREE_OPERAND (arg1, 1), 0));
+ TREE_OPERAND (arg1, 1), flags));
case BIT_FIELD_REF:
return (operand_equal_p (TREE_OPERAND (arg0, 0),
- TREE_OPERAND (arg1, 0), 0)
+ TREE_OPERAND (arg1, 0), flags)
&& operand_equal_p (TREE_OPERAND (arg0, 1),
- TREE_OPERAND (arg1, 1), 0)
+ TREE_OPERAND (arg1, 1), flags)
&& operand_equal_p (TREE_OPERAND (arg0, 2),
- TREE_OPERAND (arg1, 2), 0));
+ TREE_OPERAND (arg1, 2), flags));
default:
return 0;
}
@@ -2316,7 +2318,7 @@ operand_equal_p (tree arg0, tree arg1, int only_const)
case ADDR_EXPR:
case TRUTH_NOT_EXPR:
return operand_equal_p (TREE_OPERAND (arg0, 0),
- TREE_OPERAND (arg1, 0), 0);
+ TREE_OPERAND (arg1, 0), flags);
case RTL_EXPR:
return rtx_equal_p (RTL_EXPR_RTL (arg0), RTL_EXPR_RTL (arg1));
@@ -2325,14 +2327,18 @@ operand_equal_p (tree arg0, tree arg1, int only_const)
/* If the CALL_EXPRs call different functions, then they
clearly can not be equal. */
if (! operand_equal_p (TREE_OPERAND (arg0, 0),
- TREE_OPERAND (arg1, 0), 0))
+ TREE_OPERAND (arg1, 0), flags))
return 0;
- /* Only consider const functions equivalent. */
- fndecl = get_callee_fndecl (arg0);
- if (fndecl == NULL_TREE
- || ! (flags_from_decl_or_type (fndecl) & ECF_CONST))
- return 0;
+ {
+ unsigned int cef = call_expr_flags (arg0);
+ if (flags & OEP_PURE_SAME)
+ cef &= ECF_CONST | ECF_PURE;
+ else
+ cef &= ECF_CONST;
+ if (!cef)
+ return 0;
+ }
/* Now see if all the arguments are the same. operand_equal_p
does not handle TREE_LIST, so we walk the operands here
@@ -2341,7 +2347,8 @@ operand_equal_p (tree arg0, tree arg1, int only_const)
arg1 = TREE_OPERAND (arg1, 1);
while (arg0 && arg1)
{
- if (! operand_equal_p (TREE_VALUE (arg0), TREE_VALUE (arg1), 0))
+ if (! operand_equal_p (TREE_VALUE (arg0), TREE_VALUE (arg1),
+ flags))
return 0;
arg0 = TREE_CHAIN (arg0);
@@ -2357,11 +2364,11 @@ operand_equal_p (tree arg0, tree arg1, int only_const)
}
case 'd':
- /* Consider __builtin_sqrt equal to sqrt. */
- return TREE_CODE (arg0) == FUNCTION_DECL
- && DECL_BUILT_IN (arg0) && DECL_BUILT_IN (arg1)
- && DECL_BUILT_IN_CLASS (arg0) == DECL_BUILT_IN_CLASS (arg1)
- && DECL_FUNCTION_CODE (arg0) == DECL_FUNCTION_CODE (arg1);
+ /* Consider __builtin_sqrt equal to sqrt. */
+ return (TREE_CODE (arg0) == FUNCTION_DECL
+ && DECL_BUILT_IN (arg0) && DECL_BUILT_IN (arg1)
+ && DECL_BUILT_IN_CLASS (arg0) == DECL_BUILT_IN_CLASS (arg1)
+ && DECL_FUNCTION_CODE (arg0) == DECL_FUNCTION_CODE (arg1));
default:
return 0;
@@ -2726,6 +2733,9 @@ invert_truthvalue (tree arg)
return invert_truthvalue (TREE_OPERAND (arg, 0));
case NOP_EXPR:
+ if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
+ break;
+
case CONVERT_EXPR:
case FLOAT_EXPR:
return build1 (TREE_CODE (arg), type,
@@ -4807,7 +4817,7 @@ count_cond (tree expr, int lim)
expression, and ARG to `a'. If COND_FIRST_P is nonzero, then the
COND is the first argument to CODE; otherwise (as in the example
given here), it is the second argument. TYPE is the type of the
- original expression. Return NULL_TREE if no simplication is
+ original expression. Return NULL_TREE if no simplification is
possible. */
static tree
@@ -5212,6 +5222,156 @@ fold_inf_compare (enum tree_code code, tree type, tree arg0, tree arg1)
return NULL_TREE;
}
+/* Subroutine of fold() that optimizes comparisons of a division by
+ a non-zero integer constant against an integer constant, i.e.
+ X/C1 op C2.
+
+ CODE is the comparison operator: EQ_EXPR, NE_EXPR, GT_EXPR, LT_EXPR,
+ GE_EXPR or LE_EXPR. TYPE is the type of the result and ARG0 and ARG1
+ are the operands of the comparison. ARG1 must be a TREE_REAL_CST.
+
+ The function returns the constant folded tree if a simplification
+ can be made, and NULL_TREE otherwise. */
+
+static tree
+fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1)
+{
+ tree prod, tmp, hi, lo;
+ tree arg00 = TREE_OPERAND (arg0, 0);
+ tree arg01 = TREE_OPERAND (arg0, 1);
+ unsigned HOST_WIDE_INT lpart;
+ HOST_WIDE_INT hpart;
+ int overflow;
+
+ /* We have to do this the hard way to detect unsigned overflow.
+ prod = int_const_binop (MULT_EXPR, arg01, arg1, 0); */
+ overflow = mul_double (TREE_INT_CST_LOW (arg01),
+ TREE_INT_CST_HIGH (arg01),
+ TREE_INT_CST_LOW (arg1),
+ TREE_INT_CST_HIGH (arg1), &lpart, &hpart);
+ prod = build_int_2 (lpart, hpart);
+ TREE_TYPE (prod) = TREE_TYPE (arg00);
+ TREE_OVERFLOW (prod) = force_fit_type (prod, overflow)
+ || TREE_INT_CST_HIGH (prod) != hpart
+ || TREE_INT_CST_LOW (prod) != lpart;
+ TREE_CONSTANT_OVERFLOW (prod) = TREE_OVERFLOW (prod);
+
+ if (TYPE_UNSIGNED (TREE_TYPE (arg0)))
+ {
+ tmp = int_const_binop (MINUS_EXPR, arg01, integer_one_node, 0);
+ lo = prod;
+
+ /* Likewise hi = int_const_binop (PLUS_EXPR, prod, tmp, 0). */
+ overflow = add_double (TREE_INT_CST_LOW (prod),
+ TREE_INT_CST_HIGH (prod),
+ TREE_INT_CST_LOW (tmp),
+ TREE_INT_CST_HIGH (tmp),
+ &lpart, &hpart);
+ hi = build_int_2 (lpart, hpart);
+ TREE_TYPE (hi) = TREE_TYPE (arg00);
+ TREE_OVERFLOW (hi) = force_fit_type (hi, overflow)
+ || TREE_INT_CST_HIGH (hi) != hpart
+ || TREE_INT_CST_LOW (hi) != lpart
+ || TREE_OVERFLOW (prod);
+ TREE_CONSTANT_OVERFLOW (hi) = TREE_OVERFLOW (hi);
+ }
+ else if (tree_int_cst_sgn (arg01) >= 0)
+ {
+ tmp = int_const_binop (MINUS_EXPR, arg01, integer_one_node, 0);
+ switch (tree_int_cst_sgn (arg1))
+ {
+ case -1:
+ lo = int_const_binop (MINUS_EXPR, prod, tmp, 0);
+ hi = prod;
+ break;
+
+ case 0:
+ lo = fold_negate_const (tmp, TREE_TYPE (arg0));
+ hi = tmp;
+ break;
+
+ case 1:
+ hi = int_const_binop (PLUS_EXPR, prod, tmp, 0);
+ lo = prod;
+ break;
+
+ default:
+ abort ();
+ }
+ }
+ else
+ {
+ tmp = int_const_binop (PLUS_EXPR, arg01, integer_one_node, 0);
+ switch (tree_int_cst_sgn (arg1))
+ {
+ case -1:
+ hi = int_const_binop (MINUS_EXPR, prod, tmp, 0);
+ lo = prod;
+ break;
+
+ case 0:
+ hi = fold_negate_const (tmp, TREE_TYPE (arg0));
+ lo = tmp;
+ break;
+
+ case 1:
+ lo = int_const_binop (PLUS_EXPR, prod, tmp, 0);
+ hi = prod;
+ break;
+
+ default:
+ abort ();
+ }
+ }
+
+ switch (code)
+ {
+ case EQ_EXPR:
+ if (TREE_OVERFLOW (lo) && TREE_OVERFLOW (hi))
+ return omit_one_operand (type, integer_zero_node, arg00);
+ if (TREE_OVERFLOW (hi))
+ return fold (build2 (GE_EXPR, type, arg00, lo));
+ if (TREE_OVERFLOW (lo))
+ return fold (build2 (LE_EXPR, type, arg00, hi));
+ return build_range_check (type, arg00, 1, lo, hi);
+
+ case NE_EXPR:
+ if (TREE_OVERFLOW (lo) && TREE_OVERFLOW (hi))
+ return omit_one_operand (type, integer_one_node, arg00);
+ if (TREE_OVERFLOW (hi))
+ return fold (build2 (LT_EXPR, type, arg00, lo));
+ if (TREE_OVERFLOW (lo))
+ return fold (build2 (GT_EXPR, type, arg00, hi));
+ return build_range_check (type, arg00, 0, lo, hi);
+
+ case LT_EXPR:
+ if (TREE_OVERFLOW (lo))
+ return omit_one_operand (type, integer_zero_node, arg00);
+ return fold (build2 (LT_EXPR, type, arg00, lo));
+
+ case LE_EXPR:
+ if (TREE_OVERFLOW (hi))
+ return omit_one_operand (type, integer_one_node, arg00);
+ return fold (build2 (LE_EXPR, type, arg00, hi));
+
+ case GT_EXPR:
+ if (TREE_OVERFLOW (hi))
+ return omit_one_operand (type, integer_zero_node, arg00);
+ return fold (build2 (GT_EXPR, type, arg00, hi));
+
+ case GE_EXPR:
+ if (TREE_OVERFLOW (lo))
+ return omit_one_operand (type, integer_one_node, arg00);
+ return fold (build2 (GE_EXPR, type, arg00, lo));
+
+ default:
+ break;
+ }
+
+ return NULL_TREE;
+}
+
+
/* If CODE with arguments ARG0 and ARG1 represents a single bit
equality/inequality test, then return a simplified form of
the test using shifts and logical operations. Otherwise return
@@ -5373,6 +5533,15 @@ tree_swap_operands_p (tree arg0, tree arg1, bool reorder)
if (DECL_P (arg0))
return 1;
+ if (reorder && flag_evaluation_order
+ && (TREE_SIDE_EFFECTS (arg0) || TREE_SIDE_EFFECTS (arg1)))
+ return 0;
+
+ if (DECL_P (arg1))
+ return 0;
+ if (DECL_P (arg0))
+ return 1;
+
return 0;
}
@@ -5399,6 +5568,7 @@ fold (tree expr)
tree arg0 = NULL_TREE, arg1 = NULL_TREE;
enum tree_code code = TREE_CODE (t);
int kind = TREE_CODE_CLASS (code);
+
/* WINS will be nonzero when the switch is done
if all operands are constant. */
int wins = 1;
@@ -5519,9 +5689,10 @@ fold (tree expr)
&& integer_onep (TREE_OPERAND (arg0, 1)))))))
{
tem = fold (build (code == BIT_AND_EXPR ? TRUTH_AND_EXPR
- : code == BIT_IOR_EXPR ? TRUTH_OR_EXPR
- : TRUTH_XOR_EXPR,
- type, arg0, arg1));
+ : code == BIT_IOR_EXPR ? TRUTH_OR_EXPR
+ : TRUTH_XOR_EXPR,
+ type, fold_convert (boolean_type_node, arg0),
+ fold_convert (boolean_type_node, arg1)));
if (code == EQ_EXPR)
tem = invert_truthvalue (tem);
@@ -5577,9 +5748,18 @@ fold (tree expr)
return tem;
}
else if (TREE_CODE_CLASS (TREE_CODE (arg0)) == '<')
- return fold (build (COND_EXPR, type, arg0,
- fold (build1 (code, type, integer_one_node)),
- fold (build1 (code, type, integer_zero_node))));
+ {
+ if (TREE_CODE (type) == BOOLEAN_TYPE)
+ {
+ arg0 = copy_node (arg0);
+ TREE_TYPE (arg0) = type;
+ return arg0;
+ }
+ else if (TREE_CODE (type) != INTEGER_TYPE)
+ return fold (build (COND_EXPR, type, arg0,
+ fold (build1 (code, type, integer_one_node)),
+ fold (build1 (code, type, integer_zero_node))));
+ }
}
else if (TREE_CODE_CLASS (code) == '<'
&& TREE_CODE (arg0) == COMPOUND_EXPR)
@@ -5631,6 +5811,7 @@ fold (tree expr)
case FIX_TRUNC_EXPR:
case FIX_CEIL_EXPR:
case FIX_FLOOR_EXPR:
+ case FIX_ROUND_EXPR:
if (TREE_TYPE (TREE_OPERAND (t, 0)) == type)
return TREE_OPERAND (t, 0);
@@ -5729,7 +5910,7 @@ fold (tree expr)
TREE_OPERAND (tem, 0) = TREE_OPERAND (prev, 1);
/* First do the assignment, then return converted constant. */
tem = build (COMPOUND_EXPR, TREE_TYPE (tem), prev, fold (tem));
- TREE_NO_UNUSED_WARNING (tem) = 1;
+ TREE_NO_WARNING (tem) = 1;
TREE_USED (tem) = 1;
return tem;
}
@@ -5777,6 +5958,26 @@ fold (tree expr)
fold_convert (type, and1)));
}
+ /* Convert (T1)((T2)X op Y) into (T1)X op Y, for pointer types T1 and
+ T2 being pointers to types of the same size. */
+ if (POINTER_TYPE_P (TREE_TYPE (t))
+ && TREE_CODE_CLASS (TREE_CODE (arg0)) == '2'
+ && TREE_CODE (TREE_OPERAND (arg0, 0)) == NOP_EXPR
+ && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg0, 0))))
+ {
+ tree arg00 = TREE_OPERAND (arg0, 0);
+ tree t0 = TREE_TYPE (t);
+ tree t1 = TREE_TYPE (arg00);
+ tree tt0 = TREE_TYPE (t0);
+ tree tt1 = TREE_TYPE (t1);
+ tree s0 = TYPE_SIZE (tt0);
+ tree s1 = TYPE_SIZE (tt1);
+
+ if (s0 && s1 && operand_equal_p (s0, s1, OEP_ONLY_CONST))
+ return build (TREE_CODE (arg0), t0, convert (t0, arg00),
+ TREE_OPERAND (arg0, 1));
+ }
+
tem = fold_convert_const (code, type, arg0);
return tem ? tem : t;
@@ -5801,6 +6002,7 @@ fold (tree expr)
{
tem = copy_node (t);
TREE_CONSTANT (tem) = wins;
+ TREE_INVARIANT (tem) = wins;
return tem;
}
return t;
@@ -6413,7 +6615,7 @@ fold (tree expr)
/* Transform x * -1.0 into -x. */
if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
&& real_minus_onep (arg1))
- return fold (build1 (NEGATE_EXPR, type, arg0));
+ return fold_convert (type, negate_expr (arg0));
/* Convert (C1/X)*C2 into (C1*C2)/X. */
if (flag_unsafe_math_optimizations
@@ -6509,25 +6711,7 @@ fold (tree expr)
&& operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
TREE_VALUE (TREE_OPERAND (arg1, 1)), 0))
{
- tree sinfn;
-
- switch (fcode0)
- {
- case BUILT_IN_TAN:
- case BUILT_IN_COS:
- sinfn = implicit_built_in_decls[BUILT_IN_SIN];
- break;
- case BUILT_IN_TANF:
- case BUILT_IN_COSF:
- sinfn = implicit_built_in_decls[BUILT_IN_SINF];
- break;
- case BUILT_IN_TANL:
- case BUILT_IN_COSL:
- sinfn = implicit_built_in_decls[BUILT_IN_SINL];
- break;
- default:
- sinfn = NULL_TREE;
- }
+ tree sinfn = mathfn_built_in (type, BUILT_IN_SIN);
if (sinfn != NULL_TREE)
return build_function_call_expr (sinfn,
@@ -6588,16 +6772,7 @@ fold (tree expr)
if (! optimize_size
&& operand_equal_p (arg0, arg1, 0))
{
- tree powfn;
-
- if (type == double_type_node)
- powfn = implicit_built_in_decls[BUILT_IN_POW];
- else if (type == float_type_node)
- powfn = implicit_built_in_decls[BUILT_IN_POWF];
- else if (type == long_double_type_node)
- powfn = implicit_built_in_decls[BUILT_IN_POWL];
- else
- powfn = NULL_TREE;
+ tree powfn = mathfn_built_in (type, BUILT_IN_POW);
if (powfn)
{
@@ -6796,9 +6971,9 @@ fold (tree expr)
if (BUILTIN_EXPONENT_P (fcode))
{
tree expfn = TREE_OPERAND (TREE_OPERAND (arg1, 0), 0);
- tree arg = build1 (NEGATE_EXPR, type,
- TREE_VALUE (TREE_OPERAND (arg1, 1)));
- tree arglist = build_tree_list (NULL_TREE, fold (arg));
+ tree arg = negate_expr (TREE_VALUE (TREE_OPERAND (arg1, 1)));
+ tree arglist = build_tree_list (NULL_TREE,
+ fold_convert (type, arg));
arg1 = build_function_call_expr (expfn, arglist);
return fold (build (MULT_EXPR, type, arg0, arg1));
}
@@ -6811,7 +6986,7 @@ fold (tree expr)
tree powfn = TREE_OPERAND (TREE_OPERAND (arg1, 0), 0);
tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));
tree arg11 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg1, 1)));
- tree neg11 = fold (build1 (NEGATE_EXPR, type, arg11));
+ tree neg11 = fold_convert (type, negate_expr (arg11));
tree arglist = tree_cons(NULL_TREE, arg10,
build_tree_list (NULL_TREE, neg11));
arg1 = build_function_call_expr (powfn, arglist);
@@ -6831,16 +7006,7 @@ fold (tree expr)
&& operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
TREE_VALUE (TREE_OPERAND (arg1, 1)), 0))
{
- tree tanfn;
-
- if (fcode0 == BUILT_IN_SIN)
- tanfn = implicit_built_in_decls[BUILT_IN_TAN];
- else if (fcode0 == BUILT_IN_SINF)
- tanfn = implicit_built_in_decls[BUILT_IN_TANF];
- else if (fcode0 == BUILT_IN_SINL)
- tanfn = implicit_built_in_decls[BUILT_IN_TANL];
- else
- tanfn = NULL_TREE;
+ tree tanfn = mathfn_built_in (type, BUILT_IN_TAN);
if (tanfn != NULL_TREE)
return build_function_call_expr (tanfn,
@@ -6854,16 +7020,7 @@ fold (tree expr)
&& operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
TREE_VALUE (TREE_OPERAND (arg1, 1)), 0))
{
- tree tanfn;
-
- if (fcode0 == BUILT_IN_COS)
- tanfn = implicit_built_in_decls[BUILT_IN_TAN];
- else if (fcode0 == BUILT_IN_COSF)
- tanfn = implicit_built_in_decls[BUILT_IN_TANF];
- else if (fcode0 == BUILT_IN_COSL)
- tanfn = implicit_built_in_decls[BUILT_IN_TANL];
- else
- tanfn = NULL_TREE;
+ tree tanfn = mathfn_built_in (type, BUILT_IN_TAN);
if (tanfn != NULL_TREE)
{
@@ -6910,6 +7067,12 @@ fold (tree expr)
return non_lvalue (fold_convert (type, arg0));
if (integer_zerop (arg1))
return t;
+ /* X / -1 is -X. */
+ if (!TYPE_UNSIGNED (type)
+ && TREE_CODE (arg1) == INTEGER_CST
+ && TREE_INT_CST_LOW (arg1) == (unsigned HOST_WIDE_INT) -1
+ && TREE_INT_CST_HIGH (arg1) == -1)
+ return fold_convert (type, negate_expr (arg0));
/* If arg0 is a multiple of arg1, then rewrite to the fastest div
operation, EXACT_DIV_EXPR.
@@ -6936,6 +7099,12 @@ fold (tree expr)
return omit_one_operand (type, integer_zero_node, arg0);
if (integer_zerop (arg1))
return t;
+ /* X % -1 is zero. */
+ if (!TYPE_UNSIGNED (type)
+ && TREE_CODE (arg1) == INTEGER_CST
+ && TREE_INT_CST_LOW (arg1) == (unsigned HOST_WIDE_INT) -1
+ && TREE_INT_CST_HIGH (arg1) == -1)
+ return omit_one_operand (type, integer_zero_node, arg0);
if (TREE_CODE (arg1) == INTEGER_CST
&& 0 != (tem = extract_muldiv (TREE_OPERAND (t, 0), arg1,
@@ -7009,7 +7178,7 @@ fold (tree expr)
if (operand_equal_p (arg0, arg1, 0))
return omit_one_operand (type, arg0, arg1);
if (INTEGRAL_TYPE_P (type)
- && operand_equal_p (arg1, TYPE_MIN_VALUE (type), 1))
+ && operand_equal_p (arg1, TYPE_MIN_VALUE (type), OEP_ONLY_CONST))
return omit_one_operand (type, arg1, arg0);
goto associate;
@@ -7018,7 +7187,7 @@ fold (tree expr)
return omit_one_operand (type, arg0, arg1);
if (INTEGRAL_TYPE_P (type)
&& TYPE_MAX_VALUE (type)
- && operand_equal_p (arg1, TYPE_MAX_VALUE (type), 1))
+ && operand_equal_p (arg1, TYPE_MAX_VALUE (type), OEP_ONLY_CONST))
return omit_one_operand (type, arg1, arg0);
goto associate;
@@ -7162,6 +7331,9 @@ fold (tree expr)
return non_lvalue (fold_convert (type, invert_truthvalue (arg1)));
if (integer_onep (arg1))
return non_lvalue (fold_convert (type, invert_truthvalue (arg0)));
+ /* Identical arguments cancel to zero. */
+ if (operand_equal_p (arg0, arg1, 0))
+ return omit_one_operand (type, integer_zero_node, arg0);
return t;
case EQ_EXPR:
@@ -7398,7 +7570,11 @@ fold (tree expr)
}
/* Comparisons with the highest or lowest possible integer of
- the specified size will have known values. */
+ the specified size will have known values.
+
+ This is quite similar to fold_relational_hi_lo; however, my
+ attempts to share the code have been nothing but trouble.
+ I give up for now. */
{
int width = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg1)));
@@ -7500,7 +7676,8 @@ fold (tree expr)
break;
}
- else if (TREE_INT_CST_HIGH (arg1) == 0
+ else if (!in_gimple_form
+ && TREE_INT_CST_HIGH (arg1) == 0
&& TREE_INT_CST_LOW (arg1) == signed_max
&& TYPE_UNSIGNED (TREE_TYPE (arg1))
/* signed_type does not work on pointer types. */
@@ -7931,6 +8108,20 @@ fold (tree expr)
integer_zero_node));
}
+ /* We can fold X/C1 op C2 where C1 and C2 are integer constants
+ into a single range test. */
+ if (TREE_CODE (arg0) == TRUNC_DIV_EXPR
+ && TREE_CODE (arg1) == INTEGER_CST
+ && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
+ && !integer_zerop (TREE_OPERAND (arg0, 1))
+ && !TREE_OVERFLOW (TREE_OPERAND (arg0, 1))
+ && !TREE_OVERFLOW (arg1))
+ {
+ t1 = fold_div_compare (code, type, arg0, arg1);
+ if (t1 != NULL_TREE)
+ return t1;
+ }
+
/* Both ARG0 and ARG1 are known to be constants at this point. */
t1 = fold_relational_const (code, type, arg0, arg1);
return (t1 == NULL_TREE ? t : t1);
@@ -8126,40 +8317,48 @@ fold (tree expr)
case LT_EXPR:
/* If C1 is C2 + 1, this is min(A, C2). */
- if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type), 1)
+ if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type),
+ OEP_ONLY_CONST)
&& operand_equal_p (TREE_OPERAND (arg0, 1),
const_binop (PLUS_EXPR, arg2,
- integer_one_node, 0), 1))
+ integer_one_node, 0),
+ OEP_ONLY_CONST))
return pedantic_non_lvalue
(fold (build (MIN_EXPR, type, arg1, arg2)));
break;
case LE_EXPR:
/* If C1 is C2 - 1, this is min(A, C2). */
- if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type), 1)
+ if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type),
+ OEP_ONLY_CONST)
&& operand_equal_p (TREE_OPERAND (arg0, 1),
const_binop (MINUS_EXPR, arg2,
- integer_one_node, 0), 1))
+ integer_one_node, 0),
+ OEP_ONLY_CONST))
return pedantic_non_lvalue
(fold (build (MIN_EXPR, type, arg1, arg2)));
break;
case GT_EXPR:
/* If C1 is C2 - 1, this is max(A, C2). */
- if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type), 1)
+ if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type),
+ OEP_ONLY_CONST)
&& operand_equal_p (TREE_OPERAND (arg0, 1),
const_binop (MINUS_EXPR, arg2,
- integer_one_node, 0), 1))
+ integer_one_node, 0),
+ OEP_ONLY_CONST))
return pedantic_non_lvalue
(fold (build (MAX_EXPR, type, arg1, arg2)));
break;
case GE_EXPR:
/* If C1 is C2 + 1, this is max(A, C2). */
- if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type), 1)
+ if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type),
+ OEP_ONLY_CONST)
&& operand_equal_p (TREE_OPERAND (arg0, 1),
const_binop (PLUS_EXPR, arg2,
- integer_one_node, 0), 1))
+ integer_one_node, 0),
+ OEP_ONLY_CONST))
return pedantic_non_lvalue
(fold (build (MAX_EXPR, type, arg1, arg2)));
break;
@@ -8212,7 +8411,7 @@ fold (tree expr)
&& integer_pow2p (arg1)
&& TREE_CODE (TREE_OPERAND (arg0, 0)) == BIT_AND_EXPR
&& operand_equal_p (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1),
- arg1, 1))
+ arg1, OEP_ONLY_CONST))
return pedantic_non_lvalue (fold_convert (type,
TREE_OPERAND (arg0, 0)));
@@ -8909,7 +9108,7 @@ tree_expr_nonzero_p (tree t)
{
tree type = TREE_TYPE (t);
- /* Doing something usefull for floating point would need more work. */
+ /* Doing something useful for floating point would need more work. */
if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
return false;
@@ -9047,6 +9246,598 @@ rtl_expr_nonnegative_p (rtx r)
}
}
+
+/* See if we are applying CODE, a relational to the highest or lowest
+ possible integer of TYPE. If so, then the result is a compile
+ time constant. */
+
+static tree
+fold_relational_hi_lo (enum tree_code *code_p, const tree type, tree *op0_p,
+ tree *op1_p)
+{
+ tree op0 = *op0_p;
+ tree op1 = *op1_p;
+ enum tree_code code = *code_p;
+ int width = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (op1)));
+
+ if (TREE_CODE (op1) == INTEGER_CST
+ && ! TREE_CONSTANT_OVERFLOW (op1)
+ && width <= HOST_BITS_PER_WIDE_INT
+ && (INTEGRAL_TYPE_P (TREE_TYPE (op1))
+ || POINTER_TYPE_P (TREE_TYPE (op1))))
+ {
+ unsigned HOST_WIDE_INT signed_max;
+ unsigned HOST_WIDE_INT max, min;
+
+ signed_max = ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1;
+
+ if (TYPE_UNSIGNED (TREE_TYPE (op1)))
+ {
+ max = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1;
+ min = 0;
+ }
+ else
+ {
+ max = signed_max;
+ min = ((unsigned HOST_WIDE_INT) -1 << (width - 1));
+ }
+
+ if (TREE_INT_CST_HIGH (op1) == 0
+ && TREE_INT_CST_LOW (op1) == max)
+ switch (code)
+ {
+ case GT_EXPR:
+ return omit_one_operand (type,
+ convert (type, integer_zero_node),
+ op0);
+ case GE_EXPR:
+ *code_p = EQ_EXPR;
+ break;
+ case LE_EXPR:
+ return omit_one_operand (type,
+ convert (type, integer_one_node),
+ op0);
+ case LT_EXPR:
+ *code_p = NE_EXPR;
+ break;
+
+ /* The GE_EXPR and LT_EXPR cases above are not normally
+ reached because of previous transformations. */
+
+ default:
+ break;
+ }
+ else if (TREE_INT_CST_HIGH (op1) == 0
+ && TREE_INT_CST_LOW (op1) == max - 1)
+ switch (code)
+ {
+ case GT_EXPR:
+ *code_p = EQ_EXPR;
+ *op1_p = const_binop (PLUS_EXPR, op1, integer_one_node, 0);
+ break;
+ case LE_EXPR:
+ *code_p = NE_EXPR;
+ *op1_p = const_binop (PLUS_EXPR, op1, integer_one_node, 0);
+ break;
+ default:
+ break;
+ }
+ else if (TREE_INT_CST_HIGH (op1) == (min ? -1 : 0)
+ && TREE_INT_CST_LOW (op1) == min)
+ switch (code)
+ {
+ case LT_EXPR:
+ return omit_one_operand (type,
+ convert (type, integer_zero_node),
+ op0);
+ case LE_EXPR:
+ *code_p = EQ_EXPR;
+ break;
+
+ case GE_EXPR:
+ return omit_one_operand (type,
+ convert (type, integer_one_node),
+ op0);
+ case GT_EXPR:
+ *code_p = NE_EXPR;
+ break;
+
+ default:
+ break;
+ }
+ else if (TREE_INT_CST_HIGH (op1) == (min ? -1 : 0)
+ && TREE_INT_CST_LOW (op1) == min + 1)
+ switch (code)
+ {
+ case GE_EXPR:
+ *code_p = NE_EXPR;
+ *op1_p = const_binop (MINUS_EXPR, op1, integer_one_node, 0);
+ break;
+ case LT_EXPR:
+ *code_p = EQ_EXPR;
+ *op1_p = const_binop (MINUS_EXPR, op1, integer_one_node, 0);
+ break;
+ default:
+ break;
+ }
+
+ else if (TREE_INT_CST_HIGH (op1) == 0
+ && TREE_INT_CST_LOW (op1) == signed_max
+ && TYPE_UNSIGNED (TREE_TYPE (op1))
+ /* signed_type does not work on pointer types. */
+ && INTEGRAL_TYPE_P (TREE_TYPE (op1)))
+ {
+ /* The following case also applies to X < signed_max+1
+ and X >= signed_max+1 because previous transformations. */
+ if (code == LE_EXPR || code == GT_EXPR)
+ {
+ tree st0, st1, exp, retval;
+ st0 = (*lang_hooks.types.signed_type) (TREE_TYPE (op0));
+ st1 = (*lang_hooks.types.signed_type) (TREE_TYPE (op1));
+
+ exp = build (code == LE_EXPR ? GE_EXPR: LT_EXPR,
+ type,
+ convert (st0, op0),
+ convert (st1, integer_zero_node));
+
+ retval
+ = nondestructive_fold_binary_to_constant (TREE_CODE (exp),
+ TREE_TYPE (exp),
+ TREE_OPERAND (exp, 0),
+ TREE_OPERAND (exp, 1));
+
+ /* If we are in gimple form, then returning EXP would create
+ non-gimple expressions. Clearing it is safe and insures
+ we do not allow a non-gimple expression to escape. */
+ if (in_gimple_form)
+ exp = NULL;
+
+ return (retval ? retval : exp);
+ }
+ }
+ }
+
+ return NULL_TREE;
+}
+
+
+/* Given the components of a binary expression CODE, TYPE, OP0 and OP1,
+ attempt to fold the expression to a constant without modifying TYPE,
+ OP0 or OP1.
+
+ If the expression could be simplified to a constant, then return
+ the constant. If the expression would not be simplified to a
+ constant, then return NULL_TREE.
+
+ Note this is primarily designed to be called after gimplification
+ of the tree structures and when at least one operand is a constant.
+ As a result of those simplifying assumptions this routine is far
+ simpler than the generic fold routine. */
+
+tree
+nondestructive_fold_binary_to_constant (enum tree_code code, tree type,
+ tree op0, tree op1)
+{
+ int wins = 1;
+ tree subop0;
+ tree subop1;
+ tree tem;
+
+ /* If this is a commutative operation, and ARG0 is a constant, move it
+ to ARG1 to reduce the number of tests below. */
+ if (commutative_tree_code (code)
+ && (TREE_CODE (op0) == INTEGER_CST || TREE_CODE (op0) == REAL_CST))
+ {
+ tem = op0;
+ op0 = op1;
+ op1 = tem;
+ }
+
+ /* If either operand is a complex type, extract its real component. */
+ if (TREE_CODE (op0) == COMPLEX_CST)
+ subop0 = TREE_REALPART (op0);
+ else
+ subop0 = op0;
+
+ if (TREE_CODE (op1) == COMPLEX_CST)
+ subop1 = TREE_REALPART (op1);
+ else
+ subop1 = op1;
+
+ /* Note if either argument is not a real or integer constant.
+ With a few exceptions, simplification is limited to cases
+ where both arguments are constants. */
+ if ((TREE_CODE (subop0) != INTEGER_CST
+ && TREE_CODE (subop0) != REAL_CST)
+ || (TREE_CODE (subop1) != INTEGER_CST
+ && TREE_CODE (subop1) != REAL_CST))
+ wins = 0;
+
+ switch (code)
+ {
+ case PLUS_EXPR:
+ /* (plus (address) (const_int)) is a constant. */
+ if (TREE_CODE (op0) == PLUS_EXPR
+ && TREE_CODE (op1) == INTEGER_CST
+ && (TREE_CODE (TREE_OPERAND (op0, 0)) == ADDR_EXPR
+ || (TREE_CODE (TREE_OPERAND (op0, 0)) == NOP_EXPR
+ && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (op0, 0), 0))
+ == ADDR_EXPR)))
+ && TREE_CODE (TREE_OPERAND (op0, 1)) == INTEGER_CST)
+ {
+ return build (PLUS_EXPR, type, TREE_OPERAND (op0, 0),
+ const_binop (PLUS_EXPR, op1, TREE_OPERAND (op0, 1), 0));
+ }
+ case BIT_XOR_EXPR:
+
+ binary:
+ if (!wins)
+ return NULL_TREE;
+
+ /* Both arguments are constants. Simplify. */
+ tem = const_binop (code, op0, op1, 0);
+ if (tem != NULL_TREE)
+ {
+ /* The return value should always have the same type as
+ the original expression. */
+ if (TREE_TYPE (tem) != type)
+ tem = convert (type, tem);
+
+ return tem;
+ }
+ return NULL_TREE;
+
+ case MINUS_EXPR:
+ /* Fold &x - &x. This can happen from &x.foo - &x.
+ This is unsafe for certain floats even in non-IEEE formats.
+ In IEEE, it is unsafe because it does wrong for NaNs.
+ Also note that operand_equal_p is always false if an
+ operand is volatile. */
+ if (! FLOAT_TYPE_P (type) && operand_equal_p (op0, op1, 0))
+ return convert (type, integer_zero_node);
+
+ goto binary;
+
+ case MULT_EXPR:
+ case BIT_AND_EXPR:
+ /* Special case multiplication or bitwise AND where one argument
+ is zero. */
+ if (! FLOAT_TYPE_P (type) && integer_zerop (op1))
+ return omit_one_operand (type, op1, op0);
+ else
+ if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (op0)))
+ && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (op0)))
+ && real_zerop (op1))
+ return omit_one_operand (type, op1, op0);
+
+ goto binary;
+
+ case BIT_IOR_EXPR:
+ /* Special case when we know the result will be all ones. */
+ if (integer_all_onesp (op1))
+ return omit_one_operand (type, op1, op0);
+
+ goto binary;
+
+ case TRUNC_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case EXACT_DIV_EXPR:
+ case TRUNC_MOD_EXPR:
+ case ROUND_MOD_EXPR:
+ case FLOOR_MOD_EXPR:
+ case CEIL_MOD_EXPR:
+ case RDIV_EXPR:
+ /* Division by zero is undefined. */
+ if (integer_zerop (op1))
+ return NULL_TREE;
+
+ if (TREE_CODE (op1) == REAL_CST
+ && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (op1)))
+ && real_zerop (op1))
+ return NULL_TREE;
+
+ goto binary;
+
+ case MIN_EXPR:
+ if (INTEGRAL_TYPE_P (type)
+ && operand_equal_p (op1, TYPE_MIN_VALUE (type), OEP_ONLY_CONST))
+ return omit_one_operand (type, op1, op0);
+
+ goto binary;
+
+ case MAX_EXPR:
+ if (INTEGRAL_TYPE_P (type)
+ && TYPE_MAX_VALUE (type)
+ && operand_equal_p (op1, TYPE_MAX_VALUE (type), OEP_ONLY_CONST))
+ return omit_one_operand (type, op1, op0);
+
+ goto binary;
+
+ case RSHIFT_EXPR:
+ /* Optimize -1 >> x for arithmetic right shifts. */
+ if (integer_all_onesp (op0) && ! TYPE_UNSIGNED (type))
+ return omit_one_operand (type, op0, op1);
+ /* ... fall through ... */
+
+ case LSHIFT_EXPR:
+ if (integer_zerop (op0))
+ return omit_one_operand (type, op0, op1);
+
+ /* Since negative shift count is not well-defined, don't
+ try to compute it in the compiler. */
+ if (TREE_CODE (op1) == INTEGER_CST && tree_int_cst_sgn (op1) < 0)
+ return NULL_TREE;
+
+ goto binary;
+
+ case LROTATE_EXPR:
+ case RROTATE_EXPR:
+ /* -1 rotated either direction by any amount is still -1. */
+ if (integer_all_onesp (op0))
+ return omit_one_operand (type, op0, op1);
+
+ /* 0 rotated either direction by any amount is still zero. */
+ if (integer_zerop (op0))
+ return omit_one_operand (type, op0, op1);
+
+ goto binary;
+
+ case COMPLEX_EXPR:
+ if (wins)
+ return build_complex (type, op0, op1);
+ return NULL_TREE;
+
+ case LT_EXPR:
+ case LE_EXPR:
+ case GT_EXPR:
+ case GE_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ /* If one arg is a real or integer constant, put it last. */
+ if ((TREE_CODE (op0) == INTEGER_CST
+ && TREE_CODE (op1) != INTEGER_CST)
+ || (TREE_CODE (op0) == REAL_CST
+ && TREE_CODE (op0) != REAL_CST))
+ {
+ tree temp;
+
+ temp = op0;
+ op0 = op1;
+ op1 = temp;
+ code = swap_tree_comparison (code);
+ }
+
+ /* Change X >= C to X > (C - 1) and X < C to X <= (C - 1) if C > 0.
+ This transformation affects the cases which are handled in later
+ optimizations involving comparisons with non-negative constants. */
+ if (TREE_CODE (op1) == INTEGER_CST
+ && TREE_CODE (op0) != INTEGER_CST
+ && tree_int_cst_sgn (op1) > 0)
+ {
+ switch (code)
+ {
+ case GE_EXPR:
+ code = GT_EXPR;
+ op1 = const_binop (MINUS_EXPR, op1, integer_one_node, 0);
+ break;
+
+ case LT_EXPR:
+ code = LE_EXPR;
+ op1 = const_binop (MINUS_EXPR, op1, integer_one_node, 0);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ tem = fold_relational_hi_lo (&code, type, &op0, &op1);
+ if (tem)
+ return tem;
+
+ if (!wins)
+ return NULL_TREE;
+
+ return fold_relational_const (code, type, op0, op1);
+
+ case RANGE_EXPR:
+ /* This could probably be handled. */
+ return NULL_TREE;
+
+ case TRUTH_AND_EXPR:
+ /* If second arg is constant zero, result is zero, but first arg
+ must be evaluated. */
+ if (integer_zerop (op1))
+ return omit_one_operand (type, op1, op0);
+ /* Likewise for first arg, but note that only the TRUTH_AND_EXPR
+ case will be handled here. */
+ if (integer_zerop (op0))
+ return omit_one_operand (type, op0, op1);
+ if (TREE_CODE (op0) == INTEGER_CST && TREE_CODE (op1) == INTEGER_CST)
+ {
+ int x1 = ! integer_zerop (op0);
+ int x2 = ! integer_zerop (op1);
+
+ return ((x1 & x2) ? integer_one_node : integer_zero_node);
+ }
+ return NULL_TREE;
+
+ case TRUTH_OR_EXPR:
+ /* If second arg is constant true, result is true, but we must
+ evaluate first arg. */
+ if (TREE_CODE (op1) == INTEGER_CST && ! integer_zerop (op1))
+ return omit_one_operand (type, op1, op0);
+ /* Likewise for first arg, but note this only occurs here for
+ TRUTH_OR_EXPR. */
+ if (TREE_CODE (op0) == INTEGER_CST && ! integer_zerop (op0))
+ return omit_one_operand (type, op0, op1);
+ if (TREE_CODE (op0) == INTEGER_CST && TREE_CODE (op1) == INTEGER_CST)
+ {
+ int x1 = ! integer_zerop (op0);
+ int x2 = ! integer_zerop (op1);
+
+ return ((x1 | x2) ? integer_one_node : integer_zero_node);
+ }
+ return NULL_TREE;
+
+ case TRUTH_XOR_EXPR:
+ if (TREE_CODE (op0) == INTEGER_CST && TREE_CODE (op1) == INTEGER_CST)
+ {
+ int x1 = ! integer_zerop (op0);
+ int x2 = ! integer_zerop (op1);
+
+ return ((x1 ^ x2) ? integer_one_node : integer_zero_node);
+ }
+ return NULL_TREE;
+
+ default:
+ return NULL_TREE;
+ }
+}
+
+/* Given the components of a unary expression CODE, TYPE and OP0,
+ attempt to fold the expression to a constant without modifying
+ TYPE or OP0.
+
+ If the expression could be simplified to a constant, then return
+ the constant. If the expression would not be simplified to a
+ constant, then return NULL_TREE.
+
+ Note this is primarily designed to be called after gimplification
+ of the tree structures and when op0 is a constant. As a result
+ of those simplifying assumptions this routine is far simpler than
+ the generic fold routine. */
+
+tree
+nondestructive_fold_unary_to_constant (enum tree_code code, tree type,
+ tree op0)
+{
+ tree t;
+
+ /* Make sure we have a suitable constant argument. */
+ if (code == NOP_EXPR || code == FLOAT_EXPR || code == CONVERT_EXPR)
+ {
+ tree subop;
+
+ if (TREE_CODE (op0) == COMPLEX_CST)
+ subop = TREE_REALPART (op0);
+ else
+ subop = op0;
+
+ if (TREE_CODE (subop) != INTEGER_CST && TREE_CODE (subop) != REAL_CST)
+ return NULL_TREE;
+ }
+
+ switch (code)
+ {
+ case NOP_EXPR:
+ case FLOAT_EXPR:
+ case CONVERT_EXPR:
+ case FIX_TRUNC_EXPR:
+ case FIX_FLOOR_EXPR:
+ case FIX_CEIL_EXPR:
+ return fold_convert_const (code, type, op0);
+
+ case NEGATE_EXPR:
+ if (TREE_CODE (op0) == INTEGER_CST || TREE_CODE (op0) == REAL_CST)
+ return fold_negate_const (op0, type);
+ else
+ return NULL_TREE;
+
+ case ABS_EXPR:
+ if (TREE_CODE (op0) == INTEGER_CST || TREE_CODE (op0) == REAL_CST)
+ return fold_abs_const (op0, type);
+ else
+ return NULL_TREE;
+
+ case BIT_NOT_EXPR:
+ if (TREE_CODE (op0) == INTEGER_CST || TREE_CODE (op0) == REAL_CST)
+ {
+ t = build_int_2 (~ TREE_INT_CST_LOW (op0), ~ TREE_INT_CST_HIGH (op0));
+ TREE_TYPE (t) = type;
+ force_fit_type (t, 0);
+ TREE_OVERFLOW (t) = TREE_OVERFLOW (op0);
+ TREE_CONSTANT_OVERFLOW (t) = TREE_CONSTANT_OVERFLOW (op0);
+ return t;
+ }
+ else
+ return NULL_TREE;
+
+ case REALPART_EXPR:
+ if (TREE_CODE (op0) == COMPLEX_CST)
+ return TREE_REALPART (op0);
+ else
+ return NULL_TREE;
+
+ case IMAGPART_EXPR:
+ if (TREE_CODE (op0) == COMPLEX_CST)
+ return TREE_IMAGPART (op0);
+ else
+ return NULL_TREE;
+
+ case CONJ_EXPR:
+ if (TREE_CODE (op0) == COMPLEX_CST
+ && TREE_CODE (TREE_TYPE (op0)) == COMPLEX_TYPE)
+ return build_complex (type, TREE_REALPART (op0),
+ negate_expr (TREE_IMAGPART (op0)));
+ return NULL_TREE;
+
+ default:
+ return NULL_TREE;
+ }
+}
+
+/* If EXP represents referencing an element in a constant string
+ (either via pointer arithmetic or array indexing), return the
+ tree representing the value accessed, otherwise return NULL. */
+
+tree
+fold_read_from_constant_string (tree exp)
+{
+ if (TREE_CODE (exp) == INDIRECT_REF || TREE_CODE (exp) == ARRAY_REF)
+ {
+ tree exp1 = TREE_OPERAND (exp, 0);
+ tree index;
+ tree string;
+
+ if (TREE_CODE (exp) == INDIRECT_REF)
+ {
+ string = string_constant (exp1, &index);
+ }
+ else
+ {
+ tree domain = TYPE_DOMAIN (TREE_TYPE (exp1));
+ tree low_bound = domain ? TYPE_MIN_VALUE (domain) : integer_zero_node;
+ index = convert (sizetype, TREE_OPERAND (exp, 1));
+
+ /* Optimize the special-case of a zero lower bound.
+
+ We convert the low_bound to sizetype to avoid some problems
+ with constant folding. (E.g. suppose the lower bound is 1,
+ and its mode is QI. Without the conversion,l (ARRAY
+ +(INDEX-(unsigned char)1)) becomes ((ARRAY+(-(unsigned char)1))
+ +INDEX), which becomes (ARRAY+255+INDEX). Opps!) */
+ if (! integer_zerop (low_bound))
+ index = size_diffop (index, convert (sizetype, low_bound));
+
+ string = exp1;
+ }
+
+ if (string
+ && TREE_CODE (string) == STRING_CST
+ && TREE_CODE (index) == INTEGER_CST
+ && compare_tree_int (index, TREE_STRING_LENGTH (string)) < 0
+ && (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (TREE_TYPE (string))))
+ == MODE_INT)
+ && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (string)))) == 1))
+ return build_int_2 ((TREE_STRING_POINTER (string)
+ [TREE_INT_CST_LOW (index)]), 0);
+ }
+ return NULL;
+}
+
/* Return the tree for neg (ARG0) when ARG0 is known to be either
an integer constant or real constant.
diff --git a/gcc/fortran/.cvsignore b/gcc/fortran/.cvsignore
new file mode 100644
index 00000000000..da7ce896169
--- /dev/null
+++ b/gcc/fortran/.cvsignore
@@ -0,0 +1 @@
+gfortran.info*
diff --git a/gcc/fortran/CONTRIB b/gcc/fortran/CONTRIB
new file mode 100644
index 00000000000..765dfe62e3b
--- /dev/null
+++ b/gcc/fortran/CONTRIB
@@ -0,0 +1,33 @@
+Contributors to G95
+
+If we have left anyone out, please let us know:
+<gcc-g95-devel@lists.sourceforge.net>
+
+
+Major code contributors
+----------------------------------
+Andy Vaught
+Katherine Holcomb
+Steven Bosscher
+Paul Brook
+Arnaud Desitter
+Canqun Yang
+Xiaoqiang Zhang
+
+
+Small patches (no copyright assignment)
+----------------------------------
+Niels Kristian Bech Jensen
+Steven G. Johnson
+Tobias Schlüter
+
+
+Helpful comments
+----------------------------------
+Erik Schnetter
+Steven G. Kargl
+W. Clodius
+Claus Fischer
+Toon Moene
+Richard T. Henderson
+
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
new file mode 100644
index 00000000000..605a5726b05
--- /dev/null
+++ b/gcc/fortran/ChangeLog
@@ -0,0 +1,3142 @@
+2004-05-08 Tobias Schlüter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/15206
+ * trans-intrinsic.c (gfc_conv_intrinsic_rrspacing): Fixed to
+ handle zero correctly.
+
+2004-05-14 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * match.c (gfc_match): Eliminate dead code.
+
+2004-05-14 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * parse.c (gfc_statement_next_fixed): (Change from Andy's tree)
+ Detect bad continuation line in fixed form sources.
+
+2004-05-14 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/15205
+ * iresolve.c (gfc_resolve_nearest): Add new function.
+ * intrinsic.h: ... declare it here.
+ * intrinsic.c (add_functions): ... add it as resolving function
+ for NEAREST.
+
+2004-05-14 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/14066
+ * match.c (gfc_match_do): Allow infinite loops with
+ label-do-stmt. Do not enforce space after comma.
+
+2004-05-14 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/15051
+ * parse.c (parse_interface): Allow empty INTERFACE, remove
+ seen_body.
+
+2004-05-14 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * Make-lang.in, arith.c, arith.h, array.c, bbt.c, check.c,
+ decl.c, dependency.c, dependency.h, dump-parse-tree.c, error.c,
+ expr.c, f95-lang.c, gfortran.h, interface.c, intrinsic.c,
+ intrinsic.h, io.c, iresolve.c, lang-specs.h, match.c, match.h,
+ matchexp.c, misc.c, module.c, options.c, parse.c, parse.h,
+ primary.c, resolve.c, scanner.c, simplify.c, st.c, symbol.c,
+ trans-array.c, trans-array.h, trans-common.c, trans-const.c,
+ trans-const.h, trans-decl.c, trans-expr.c, trans-intrinsic.c,
+ trans-io.c, trans-stmt.c, trans-stmt.h, trans-types.c,
+ trans-types.h, trans.c, trans.h: Update copyright years and
+ boilerplate.
+ * data.c: Likewise, also removed two whitespace-only lines.
+ * gfortranspec.c, lang.opt: Update copyright years.
+
+2004-05-14 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/14568
+ * trans-decl.c (generate_local_decl): Don't warn for unused
+ variables which are in common blocks.
+
+2004-05-13 Diego Novillo <dnovillo@redhat.com>
+
+ * Make-lang.in, f95-lang.c, trans-array.c, trans-decl.c,
+ trans-expr.c, trans-intrinsic.c, trans-io.c, trans-stmt.c,
+ trans.c: Rename tree-simple.[ch] to tree-gimple.[ch].
+
+2004-05-13 Victor Leikehman <lei@haifasphere.co.il>
+
+ PR fortran/15314
+ * trans-expr.c (gfc_conv_structure): Use field type, not expr type.
+
+2004-05-13 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * gfortran.texi: Use @table @emph instead of @itemize @emph.
+ Remove "set DEVELOPMENT".
+ (Compiling GFORTRAN): Remove.
+
+2004-05-09 Tobias Schlüter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * array.c (match_subscript, match_array_ref): Add comments
+ explaining argument 'init'.
+ * decl.c, f95-lang.c, match.c, resolve.c, trans-array.c,
+ trans-expr.c, trans.c: Fix some typos in comments.
+ * dump-parse-tree.c (gfc_show_expr): Remove wrong comment.
+ * primary.c (match_digits, match_integer_constant): Add comment
+ explaining signflag.
+
+2004-05-01 Tobias Schlüter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/13940
+ * primary.c: Include system.h and flags.h, needed for pedantic.
+ (match_boz_constant): Allow "x" for hexadecimal constants, warn if
+ pedantic is set.
+
+2004-05-01 Tobias Schlüter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/13940
+ * match.c (match_data_constant): Handle case where
+ gfc_find_symbol sets sym to NULL
+
+2004-04-28 Tobias Schlüter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * Make-lang.in (f95-lang.o, trans-intrinsic.o): Add missing
+ dependency on mathbuiltins.def
+
+2004-04-24 Victor Leikehman <lei@il.ibm.com>
+
+ * trans-io.c (transfer_expr): Implemented recursive printing
+ of derived types.
+
+2004-04-24 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * gfortranspec.c: Do not include multilib.h.
+
+2004-04-24 Tobias Schlüter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * trans-intrinsic.c: Fix comment, this is not trans-expr.c. Add
+ 2004 to copyright years.
+ * trans-expr.c, trans-decl.c: Comment update, we now generate
+ GENERIC, not SIMPLE. Add 2004 to copyright years.
+
+2004-04-24 Paul Brook <paul@codesourcery.com>
+
+ * Make-lang.in (gfortranspec.o): Add dependency on $(TM_H).
+
+2004-04-24 Feng Wang <fengwang@nudt.edu.cn>
+
+ PR 14817
+ * arith.c (gfc_arith_divide): Fix complex divide.
+
+2004-04-23 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * gfortranspec.c: Include the target headers.
+
+2004-04-18 Feng Wang <fengwang@nudt.edu.cn>
+
+ PR fortran/14921
+ PR fortran/14540
+ * arith.c (arctangent2): New function.
+ * arith.h (arctangent2): Add function prototype.
+ * simplify.c (gfc_simplify_atan2): Use it.
+ (gfc_simplify_log): Use it.
+
+2004-04-12 Diego Novillo <dnovillo@redhat.com>
+
+ * fortran/f95-lang.c (gfc_expand_stmt): Remove.
+ (LANG_HOOKS_RTL_EXPAND_STMT): Remove.
+
+2004-04-11 Bud Davis <bdavis9659@comcast.net>
+
+ PR fortran/14872
+ * trans-io.c (build_dt): Change REC to value.
+
+2004-04-11 Feng Wang <fengwang@nudt.edu.cn>
+
+ PR 14394
+ * trans-const.c (gfc_conv_mpf_to_tree): Loosen the maximum digits of
+ the real value when converting mpf to string.
+
+2004-04-11 Feng Wang <fengwang@nudt.edu.cn>
+
+ PR 14395
+ * trans-intrinsic.c (gfc_conv_intrinsic_cmplx): Fix the imag part of
+ the result.
+
+2004-04-11 Feng Wang <fengwang@nudt.edu.cn>
+
+ PR fortran/14377
+ * simplify.c (simplify_min_max): Convert the type of the result.
+
+2004-04-11 Paul Brook <paul@codesourcery.com>
+
+ * gfortran.texi: Use full target triplet.
+
+2004-04-11 Paul Brook <paul@codesourcery.com>
+
+ * Make-lang.in (GFORTRAN_TEXI): Set it.
+ (fortran/dfortran.dvi): Use it. Add fortran to include paths.
+ (fortran/gfortran.info): Ditto.
+ * gfortran.texi: Major update.
+ * invoke.texi: New file.
+
+2004-04-10 Paul Brook <paul@codesourcery.com>
+
+ * trans-array.c (gfc_trans_allocate_temp_array,
+ gfc_conv_tmp_array_ref): Don't use GFC_DECL_STRING.
+ * trans-decl.c (gfc_build_dummy_array_decl,
+ gfc_get_symbol_decl, gfc_build_function_decl,
+ gfc_create_module_variable): Ditto.
+ * trans-expr.c (gfc_conv_variable): Ditto.
+ * trans-intrinsic.c (gfc_conv_intrinsic_len): Ditto.
+ * trans.h (GFC_DECL_STRING): Remove.
+ (GFC_DECL_PACKED_ARRAY, GFC_DECL_PARTIAL_PACKED_ARRAY,
+ GFC_DECL_ASSIGN): Renumber flags.
+
+2004-04-05 Paul Brook <paul@codesourcery.com>
+
+ PR 13252
+ PR 14081
+ * f95-lang.c (gfc_init_builtin_functions): Add stack_alloc, stack_save
+ and stack_restore.
+ * gfortran.h (struct gfc_charlen): Add backend_decl.
+ * trans-array.c (gfc_trans_allocate_temp_array,
+ gfc_conv_temp_array_ref, gfc_conv_resolve_dependencies,
+ (gfc_conv_loop_setup, gfc_array_allocate, gfc_conv_array_init_size):
+ Remove old, broken string handling.
+ (gfc_trans_auto_array_allocation, gfc_trans_g77_array,
+ gfc_trans_dummy_array_bias, gfc_conv_expr_descriptor,
+ gfc_trans_deferred_array): Handle character arrays.
+ * trans-const.c (gfc_conv_const_charlen): New function.
+ * trans-const.h (gfc_conv_const_charlen): Add prototype.
+ * trans-decl.c (gfc_finish_var_decl): Don't mark automatic variables
+ as static.
+ (gfc_build_dummy_array_decl): Handle arrays with unknown element size.
+ (gfc_create_string_length): New function.
+ (gfc_get_symbol_decl): Create lengths for character variables.
+ (gfc_get_fake_result_decl): Ditto.
+ (gfc_build_function_decl): Only set length for assumed length
+ character arguments.
+ (gfc_trans_dummy_character): New function.
+ (gfc_trans_auto_character_variable): Rewrite.
+ (gfc_trans_deferred_vars): Handle more types of character variable.
+ (gfc_create_module_variable): String lengths have moved.
+ (gfc_generate_function_code): Initialize deferred var chain earlier.
+ * trans-expr.c (gfc_conv_init_string_length): Rename ...
+ (gfc_trans_init_string_length): ... to this.
+ (gfc_conv_component_ref, gfc_conv_variable, gfc_conv_concat_op,
+ gfc_conv_function_call): Update to new format for character variables.
+ (gfc_conv_string_length): Remove.
+ (gfc_conv_string_parameter): Update assertion.
+ * trans-intrinsic.c (gfc_conv_intrinsic_len): Use new location.
+ * trans-io.c (set_string): Use new macro names.
+ * trans-stmt.c (gfc_trans_label_assign. gfc_trans_goto): Ditto.
+ * trans-types.c (gfc_get_character_type): Use existing length expr.
+ (gfc_is_nodesc_array): Make public.
+ (gfc_get_dtype_cst): Rename ...
+ (gfc_get_dtype): ... to this. Handle unknown size arrays.
+ (gfc_get_nodesc_array_type): Use new name.
+ (gfc_sym_type): New character variable code.
+ (gfc_get_derived_type): Ditto.
+ (gfc_get_function_type): Evaluate character variable lengths.
+ * trans-types.h (gfc_strlen_kind): Define.
+ (gfc_is_nodesc_array): Add prototype.
+ * trans.h: Update prototypes.
+ (struct lang_type): Update comments.
+ (GFC_DECL_STRING_LEN): New name for GFC_DECL_STRING_LENGTH.
+ (GFC_KNOWN_SIZE_STRING_TYPE): Remove.
+
+2004-04-04 Paul Brook <paul@codesourcery.com>
+
+ * gfortran.h (struct gfc_option_t): Remove flag_g77_calls.
+ * options.c (gfc_init.options, gfc_handle_option): Ditto.
+ * trans-expr.c (gfc_conv_function_call): Ditto.
+ * trans-types.c (gfc_is_nodesc_array): Ditto
+ * lang.opt (fg77-calls): Remove.
+
+2004-04-04 Paul Brook <paul@codesourcery.com>
+
+ * trans-array.c (OFFSET_FIELD): Rename from BASE_FIELD.
+ (gfc_conv_descriptor_base): Rename ...
+ (gfc_conv_descriptor_offset): ... to this.
+ (gfc_trans_allocate_array_storage): Set offset to zero.
+ (gfc_conv_array_base): Rename ...
+ (gfc_conv_array_offset): ... to this.
+ (gfc_conv_array_index_ref): Add offset parameter.
+ (gfc_conv_array_ref): Include offset.
+ (gfc_trans_preloop_setup): Use existing offset.
+ (gfc_trans_allocate_temp_array, gfc_array_allocate,
+ gfc_trans_auto_array_allocation, gfc_trans_g77_array,
+ gfc_trans_dummy_array_bias, gfc_conv_expr_descriptor,
+ gfc_conf_ss_descriptor): Set offset.
+ * trans-array.h: Rename prototypes.
+ * trans-const.h (gfc_index_zero_node): Define.
+ * trans-decl.c (gfc_build_qualified_array): Change base to offset.
+ * trans-types.c (gfc_get_array_type_bounds): Ditto.
+ (gfc_get_nodesc_array_type): Calculate offset before upper bound.
+
+2004-03-25 Diego Novillo <dnovillo@redhat.com>
+
+ * convert.c (convert): Don't handle WITH_RECORD_EXPR.
+
+2004-03-24 Bud Davis <bdavis9659@comcast.net>
+
+ PR 14055
+ * arith.c (gfc_convert_integer,gfc_convert_real): Removed leading '+'
+ before conversion by gmp library call.
+
+2004-03-24 Bud Davis <bdavis9659@comcast.net>
+
+ PR 12921
+ * trans-io.c (gfc_trans_open): Change RECL= to a value parameter.
+
+2004-02-24 Richard Henderson <rth@redhat.com>
+
+ * trans-array.c (gfc_trans_dummy_array_bias): Fix typo.
+
+2004-02-19 Loren J. Rittle <ljrittle@acm.org>
+
+ * Make-lang.in ($(srcdir)/fortran/gfortran.info): Move...
+ (fortran/gfortran.info): ... to here.
+ (f95.srcinfo): New.
+
+2004-02-16 Richard Henderson <rth@redhat.com>
+
+ * Make-lang.in (f95-lang.o, trans-decl.o): Depend on cgraph.h.
+ * f95-lang.c (LANG_HOOKS_EXPAND_DECL): Remove.
+ (LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION): New.
+ (gfc_expand_function): Rename from expand_function_body, make static,
+ don't do anything except invoke tree_rest_of_compilation.
+ (gfc_be_parse_file): Invoke cgraph.
+ (gfc_expand_decl): Remove.
+ (gfc_init_builtin_functions): Add __builtin_init_trampoline and
+ __builtin_adjust_trampoline.
+ * trans-decl.c (gfc_get_extern_function_decl): Don't set DECL_CONTEXT.
+ (gfc_finalize): New.
+ (gfc_generate_function_code): Use it. Lower nested functions.
+ * trans-expr.c (gfc_conv_function_call): Add static chain operand
+ to call_expr.
+ * trans.c (gfc_build_function_call): Likewise.
+ * trans.h (expand_function_body): Remove.
+
+2004-02-15 Victor Leikehman <lei@il.ibm.com>
+
+ PR gfortran/13433
+ * trans-decl.c (gfc_build_function_decl) For functions
+ returning CHARACTER pass an extra length argument,
+ following g77 calling conventions.
+ * trans-types.c (gfc_get_function_type) Ditto.
+ * trans-expr.c (gfc_conv_function_call) Ditto.
+
+2004-02-14 Paul Brook <paul@codesourcery.com>
+
+ * f95-lang.c (gfc_init_builtin_functions): Build chain properly.
+
+2004-02-12 Paul Brook <paul@nowt.org>
+
+ * BUGS: Remove.
+
+2004-02-08 Steve Kargl <sgk@troutmask.apl.washington.edu>
+
+ * gfortran.texi: Fix typos.
+
+2004-02-07 Bud Davis <bdavis9659@comcast.net>
+
+ PR gfortran/13909
+ * intrinsic.c (add_conversions) Use logical conversion instead
+ of real.
+ * trans-types.c (gfc_get_logical_type) implemented logical*1
+ and logical*2.
+
+2004-01-17 Paul Brook <paul@codesourcery.com>
+
+ * lang-specs.h: Remove %<fixed-form.
+
+2004-01-15 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * lang-specs.h: Enable preprocessing of source files
+ ending in .F, .fpp, .FPP, .F90 and .F95.
+
+2004-01-13 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ PR fortran/12912
+ * lang-specs.h: Enable compilation of files ending
+ in .f, .for and .FOR.
+
+2004-01-11 Paul Brook <paul@codesourcery.com>
+
+ * trans-stmt.c (gfc_trans_if_1): New function.
+ (gfc_trans_if): Use it.
+
+2004-01-11 Erik Schnetter <schnetter@uni-tuebingen.de>
+
+ * gfortran.h (GFC_MAX_SYMBOL_LEN): Increase.
+ (gfc_option_t): Add max_identifier_length.
+ * lang.opt: Add fmax-identifier-length.
+ * match.c (parse_name): Use limit.
+ * options.c (gfc_init_options): Set max_identifier_length.
+ (gfc_handle_option): Ditto.
+
+2004-01-11 Feng Wang <fengwang@nudt.edu.cn>
+
+ * intrinsic.c (add_functions): Add resolve function to dcmplx.
+ * intrinsic.h (gfc_resolve_dcmplx): Add prototype.
+ * iresolve.c (gfc_resolve_dcmplx): New function.
+
+2004-01-10 Paul Brook <paul@codesourcery.com>
+
+ * trans-decl.c (gfc_get_symbol_decl): Don't set subroutine attr.
+ * trans-types.c (gfc_sym_type): Handle external dummy procedures.
+ (gfc_return_by_reference): Correct condition.
+ (gfc_get_function_type): Ditto.
+
+2004-01-10 Paul Brook <paul@codesourcery.com>
+
+ * trans-intrinsic.c (gfc_conv_intrinsic_minmax): Convert mismatched
+ types.
+
+2004-01-10 Huang Chun <chunhuang73@hotmail.com>
+
+ * iresolve.c: Use correct kind.
+
+2004-01-10 Huang Chun <chunhuang73@hotmail.com>
+
+ PR fortran/13467
+ * trans-decl.c (gfc_create_module_variable): Output array valued
+ parameters.
+
+2004-01-10 Paul Brook <paul@codesourcery.com>
+
+ * resolve.c (resolve_branch): Get error message right way round.
+
+2004-01-10 Canqun Yang <canqun@nudt.edu.cn>
+
+ * trans-array (gfc_conv_loop_setup): Adjust comment to track
+ reality.
+ (gfc_array_allocate): Don't count size of element twice.
+
+2004-01-04 Paul Brook <paul@codesourcery.com>
+
+ * lang.opt (i8, r8, std=*): Remove RejectNegative.
+
+2004-01-04 Paul Brook <paul@codesourcery.com>
+
+ * error.c (gfc_notify_std): New function.
+ * gfortran.h (gfc_notify_std): Declare.
+ (GFC_STD_*): Define.
+ (gfc_option_t): Add warn_std and allow_std.
+ * intrinsic.c (gfc_init_expr_extensions): Fix logic.
+ (gfc_intrinsic_func_interface): Use gfc_notify_std.
+ * check.c (check_rest): Use gfc_notify_std.
+ * match.c (gfc_match_pause): Ditto.
+ (gfc_match_assign): Ditto.
+ (gfc_match_goto): Ditto.
+ * resolve.c (resolve_branch): Ditto.
+ * lang.opt: Add std=<foo> and w.
+ * options.c (gfc_init_options): Set allow_std and warn_std.
+ (gfc_handle_option): Handle OPT_std_* and OPT_w.
+
+2004-01-01 Paul Brook <paul@codesourcery.com>
+
+ * array.c (gfc_append_constructor): Take constructor, not expression.
+ * data.c (struct gfc_expr_stack): Remove.
+ (expr_stack): Remove.
+ (find_con_by_offset): Rename from find_expr_in_con.
+ (find_con_by_component): Rename from find_component_in_con.
+ (gfc_get_expr_stack): Remove.
+ (gfc_assign_data_value): Rewrite.
+ (gfc_expr_push): Remove.
+ (gfc_expr_pop): Remove.
+ (gfc_advance_section): Rename from
+ gfc_modify_index_and_calculate_offset. Handle unbounded sections.
+ (gfc_get_section_index): Handle unbounded sections.
+ * gfortran.h: Update prototypes.
+ * resolve.c (check_data_variable): Array section maight not be the
+ last ref.
+
+2004-01-01 Paul Brook <paul@codesourcery.com>
+
+ PR fortran/13432
+ * resolve.c (resolve_symbol): Allow assumed length function results.
+
+2004-01-01 Steve Kargl <sgk@troutmask.apl.washington.edu>
+
+ * match.c (gfc_match_pause): Fix spelling.
+
+2004-01-01 Steven Bosscher <stevenb@suse.de>
+
+ PR fortran/13251
+ * trans-expr.c (gfc_conv_variable): Take the type kind of a substring
+ reference from the expression.
+
+2003-12-26 Feng Wang <fengwang@nudt.edu.cn>
+
+ * dump-parse-tree.c (gfc_show_code_node): Add ASSIGN and ASSIGNED GOTO
+ dumping.
+ * gfortran.h (gfc_statement): New ST_LABEL_ASSIGNMENT.
+ (gfc_exec_op): New EXEC_LABEL_ASSIGN.
+ (symbol_attribute):New variable attribute: assign.
+ * io.c (resolve_tag):Integer variable is allowed.
+ (match_dt_format): Add ASSIGN statement. Set assign flag.
+ * match.c (gfc_match_if): Change ST_NONE to ST_LABEL_ASSIGNMENT.
+ (gfc_match_assign): Add ASSIGN statement. Set assign flag.
+ (gfc_match_goto): Add ASSIGNED GOTO statement. Set assign flag.
+ * parse.c (decode_statement): Add ST_LABEL_ASSIGNMENT.
+ (next_statement): Add ST_LABEL_ASSIGNMENT.
+ (gfc_ascii_statement): Add ST_LABEL_ASSIGNMENT.
+ * resolve.c (resolve_code): Resolve ASSIGN and ASSIGNED GOTO statement.
+ (resolve_blocks): Resolve ASSIGNED GOTO statement label list.
+ * st.c (gfc_free_statement): Add EXEC_LABEL_ASSIGN.
+ * trans-decl.c (gfc_get_symbol_decl): Create the shadow variable for
+ assign. Put them into the stuct lang_decl.
+ * trans-io.c (set_string): Add the assign statement.
+ * trans-stmt.c (gfc_trans_label_assign): New function.
+ (gfc_trans_goto): Translate ASSIGNED GOTO statement.
+ * trans-stmt.h (gfc_trans_label_assign): Added function prototype.
+ * trans.c (gfc_trans_code): Add EXEC_LABEL_ASSIGN.
+ * trans.h (lang_decl):Add shadow variable decl tree needed by assign.
+ (GFC_DECL_ASSIGN_ADDR(node)): New macro to access this.
+ (GFC_DECL_ASSIGN(node)): New macro to access flag.
+
+2003-12-31 Huang Chun <chunhuang73@hotmail.com>
+
+ PR fortran/13434
+ * trans-intrinsic.c (gfc_conv_intrinsic_minmaxval): Fixed bug in
+ minval/maxval.
+
+2003-12-22 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * options.c (gfc_init_options): Set flag_argument_noalias to 2, to indicate
+ that arguments to subroutines/functions can't alias themselves, nor global
+ memory.
+
+2003-12-20 Steven Bosscher <stevenb@suse.de>
+
+ * trans-expr.c (gfc_conv_expr_op): Fold the result expression.
+ * trans.c (gfc_add_modify_expr, gfc_add_expr_to_block): Likewise.
+
+2003-12-12 Huang Chun <chunhuang73@hotmail.com>
+
+ * primary.c (match_substring): Fix substring bug for start point
+ or end point is NULL.
+ * trans-expr.c (gfc_conv_substring): Ditto
+ * trans-types.c (gfc_sym_type): Get correct type of scalar
+ character variables.
+ * trans-intrinsic.c (gfc_conv_intrinsic_len): Handle character in
+ derived type.
+
+2003-12-10 Richard Henderson <rth@redhat.com>
+
+ * options.c (gfc_post_options): Don't ever use rtl inlining.
+
+2003-12-05 Canqun Yang <canqun@nudt.edu.cn>
+
+ * trans-common.c: Re-implement COMMON blocks and EQUIVALENCE lists.
+ * trans-equivalence.c: Remove.
+ * trans-decl.c (gfc_get_symbol_decl): Update to match.
+ (gfc_generate_function_code): Ditto.
+ * trans-array.c (gfc_conv_array_parameter): Ditto.
+ * Make-lang.in (F95_OBJS): Remove fortran/trans-equivalence.o
+ (F95_ADDITIONAL_OBJS): Add stor-layout.o
+ * trans.h (gfc_trans_equivalence): Remove.
+ * gfortran.h (struct gfc_equiv): Add used field.
+ (struct gfc_symbol): Remove addr_base, addr_offset, equiv_ring,
+ equiv_offset fields.
+
+2003-12-05 Richard Henderson <rth@redhat.com>
+
+ * trans.c (gfc_build_addr_expr): New.
+ (gfc_build_indirect_ref, gfc_build_array_ref): New.
+ * trans.h: Declare them.
+ * trans-array.c, trans-expr.c, trans-intrinsic.c, trans-io.c,
+ trans-stmt.c, trans.c (*): Use them.
+
+ * f95-lang.c (gfc_post_options): Remove dead prototype.
+ * trans-array.c (gfc_trans_deferred_vars): Remove unused variable.
+ * trans-stmt.c (gfc_evaluate_where_mask): Fix temporary_list
+ allocation size.
+
+2003-12-01 Feng Wang <fengwang@nudt.edu.cn>
+
+ * io.c (gfc_match_format): Check for missing format label.
+
+2003-11-30 Huang Chun <chunhuang73@hotmail.com>
+
+ PR fortran/13155
+ * trans-decl.c (gfc_sym_mangled_function_id): Don't mangle symbols
+ from interfaces in modules.
+
+2003-11-30 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (gfc_trans_g77_array): Make non-static.
+ (gfc_trans_assumed_size): Remove.
+ (gfc_trans_dummy_array_bias): Explicitly free temporary.
+ * trans-array.h (gfc_trans_g77_array): Add prototype.
+ (gfc_trans_assumed_size): Remove.
+ * trans-decls.c (gfor_fndecl_push_context): Remove.
+ (gfor_fndecl_pop_context): Remove.
+ (gfc_build_function)decls): Don't create them.
+ (gfc_trans_deferred_vars): Update to match. Remove dead code.
+ * trans-stmt.c (gfc_trans_pointer_assign_need_temp): Free temp.
+
+2003-11-30 Kejia Zhao <kejia_zh@nudt.edu.cn>
+
+ * trans-array.c (gfc_conv_array_parameter): Simplify
+ array argument passing for array name actual argument.
+ * trans-expr.c (gfc_conv_function_call): Ditto
+ * trans-types.c (gfc_is_nodesc_array):Ditto.
+
+2003-11-30 Paul Brook <paul@nowt.org>
+
+ * f95-lang.c (gfc_post_options): Move ...
+ * options.c (gfc_post_options): .. to here. Handle inlining options.
+ * gfortran.h (gfc_post_options): Add prototype.
+
+2003-11-28 Richard Henderson <rth@redhat.com>
+
+ * trans.c (gfc_create_var_np): Use create_tmp_var_raw.
+
+2003-11-28 Huang Chun <chunhuang73@hotmail.com>
+
+ * trans.h (has_alternate_specifier): New global variable.
+ * match.c (gfc_match_call): Handle actual arguments associated with
+ alternate return indicators.
+ * trans-expr.c (gfc_conv_function_call): Ditto
+ * trans-stmt.c (gfc_trans_call): Ditto
+ (gfc_trans_return): Handle return statement with value.
+ * trans-decl.c (gfc_generate_function_code): Handle functions with
+ asterisk dummy.
+ (gfc_get_fake_result_decl): Ditto
+ * trans-types.c (gfc_get_function_type): Ditto
+ * resolve.c (resolve_actual_arglist): Check alternate return indicators.
+ (resolve_formal_arglist): Check asterisk dummy.
+
+2003-11-27 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (gfc_tran_allocate_array_storage): Use new memory
+ allocation interface.
+ (gfc_conv_ array_parameter): Ditto.
+ (gfc_trans_auto_array_allocation): Ditto. Also free the memory.
+ * trans-array.c: Update prototype.
+ * trans-decl.c (gfc_build_builtin_function_decls): Update prototypes.
+ (gfc_trans_auto_character_variable): Use new memory alloc interface.
+ * trans-expr.c (gfc_conv_string_tmp): Ditto.
+ (gfc_conv_function_call): Use gfc_conv_string_tmp.
+ * trans-stmt.c (gfc_do_allocate): Use new memory alloc interface.
+ * trans-intrinsic.c (gfc_conv_intrinsic_trim): Ditto.
+ * trans.h (gfc_ss_info): Remove unused pdata field.
+ * trans.c (gfc_create_var_np): Change T to V.
+
+2003-11-26 Richard Henderson <rth@redhat.com>
+
+ * mathbuiltins.def: Move acos, asin, cosh, log10, sinh, tanh from ...
+ * trans-intrinsic.c (gfc_intrinsic_map): ... here. Add SCALE,
+ FRACTION, NEAREST, SET_EXPONENT.
+ (gfc_intrinsic_map_t): Add libm_name, complex_available, is_constant.
+ Fix GTY marking. Remove unnecessary const's.
+ (LIBM_FUNCTION): Rename from I_LIB.
+ (LIBF_FUNCTION): New.
+ (gfc_get_intrinsic_lib_fndecl): Handle libm and libgfortran naming
+ conventions. Assume the expr signature is correct. Mark const.
+ (gfc_conv_intrinsic_exponent): Use library functions.
+ (gfc_conv_intrinsic_set_exponent): Remove.
+ (gfc_conv_intrinsic_scale): Remove.
+ (gfc_conv_intrinsic_nearest): Remove.
+ (gfc_conv_intrinsic_fraction): Remove.
+ (gfc_conv_intrinsic_function): Update.
+ * trans-decl.c (gfor_fndecl_math_exponent4): New.
+ (gfor_fndecl_math_exponent8): New.
+ (gfc_build_intrinsic_function_decls): Set them.
+ * trans.h: Declare them.
+
+2003-11-25 Canqun Yang <canqun@nudt.edu.cn>
+
+ * trans-common.c (gfc_layout_global_equiv): Locate the error for
+ underflow COMMON block.
+ (gfc_trans_one_common): Fix bug for size of COMMON block containing
+ EQUIVALENCE object. Also fix typo in an error message.
+
+2003-11-25 Diego Novillo <dnovillo@redhat.com>
+
+ * Make-lang.in: Add check-gfortran to lang_checks.
+ (check-f95): Alias for check-gfortran.
+
+2003-11-25 Jason Merrill <jason@redhat.com>
+
+ * Make-lang.in (f95.tags): Create TAGS.sub files in each
+ directory and TAGS files that include them for each front end.
+
+2003-11-24 Paul Brook <paul@nowt.org>
+
+ PR fortran/13154
+ * trans-decl.c (gfc_greate_module_variable): Skip COMMON blocks.
+
+2003-11-24 Paul Brook <paul@nowt.org>
+
+ * expr.c (simplify_const_ref): Return SUCCESS for things we don't
+ handle.
+ * resolve.c (gfc_resolve_expr): Resolve contents before rank/shape.
+
+2003-11-24 Paul Brook <paul@nowt.org>
+
+ PR fortran/13105
+ * array.c (gfc_array_ref_shape): Handle elemental dimensions.
+ * trans-array.c (gfc_trans_preloop_setup): Use correct dim lookup.
+
+2003-11-20 Richard Henderson <rth@redhat.com>
+
+ * trans-array.c (gfc_trans_allocate_array_storage): Use convert.
+ (gfc_conv_array_base): Likewise.
+ * trans-decl.c (gfc_trans_auto_character_variable): Likewise.
+ * trans-expr.c (gfc_conv_string_tmp): Likewise.
+ * trans-intrinsic.c (gfc_conv_intrinsic_trim): Likewise.
+ * trans-stmt.c (gfc_trans_character_select): Likewise.
+
+2003-11-13 Paul Brook <paul@nowt.org>
+
+ * trans-decl.c (gfc_sym_mangled_function_id): Dont mangle externals.
+
+2003-11-13 Canqun Yang <canqun@nudt.edu.cn>
+
+ * resolve.c (gfc_resolve): Also resolve EQUIVALENCE objects.
+ (resolve_equivalence): New function.
+ (resolve_equivalence_derived): New function.
+
+2003-11-12 Richard Henderson <rth@redhat.com>
+
+ * trans.c (gfc_trans_code): Use annotate_with_locus instead of
+ annotate_all_with_locus.
+
+2003-11-11 Canqun Yang <canqun@nudt.edu.cn>
+
+ * options.c (gfc_init_options): Set flag_max_stack_var_size as 32768.
+ * trans-decl.c (gfc_finish_var_decl): Modified.
+
+2003-11-08 Paul Brook <paul@nowt.org>
+
+ PR fortran/12704
+ * trans-intrinsic.c (gfc_conv_intrinsics_minmaxloc): Handle zero-size
+ arrays.
+
+2003-11-06 Paul Brook <paul@nowt.org>
+
+ * trans-intrinsic.c (gfc_conv_intrinsics_minmaxloc): Initialize pos.
+
+2003-11-02 Canqun Yang <canqun@nudt.edu.cn>
+
+ * match.c (gfc_match_stopcode): Assign '0' to stop_code.
+
+2003-10-27 Anthony Green <green@redhat.com>
+
+ * Make-lang.in (f95.stageprofile): Use tabs, not spaces.
+ (f95.stagefeedback): Ditto.
+
+2003-10-27 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR fortran/12682
+ * Make-lang.in (f95.stageprofile): Add.
+ (f95.stagefeedback): Add.
+
+2003-10-23 Richard Henderson <rth@redhat.com>
+
+ * f96-lang.c (gfc_gimplify_expr): Remove.
+ (LANG_HOOKS_GIMPLIFY_EXPR): Remove.
+ (LANG_HOOKS_GIMPLE_BEFORE_INLINING): New.
+
+2003-10-23 Richard Henderson <rth@redhat.com>
+
+ * f95-lang.c (gfc_gimplify_expr): Return gimplify_status.
+
+2003-10-20 Paul Brook <paul@nowt.org>
+
+ * trans-expr.c (gfc_conv_integer_power): Use boolean_type_node.
+ * trans-stmt.c (gfc_trans_do_while): Ditto.
+
+2003-10-17 Paul Brook <paul@nowt.org>
+
+ * simplify.c (gfc_simplify_shape): Use gfc_array_dimen_size.
+
+2003-10-17 Paul Brook <paul@nowt.org>
+
+ * trans-io.c (gfc_build_io_library_fndecls): Set TREE_PUBLIC.
+
+2003-10-17 Feng Wang <wf_cs@yahoo.com>
+
+ * iresolve.c (gfc_resolve_maxloc): Change the result's kind and type.
+ (gfc_resolve_minloc): Ditto.
+ * trans-intrinsic.c (gfc_conv_intrinsic_minmaxloc): Use correct types.
+ Return the value after subtracting the lower bound.
+
+2003-10-16 Richard Henderson <rth@redhat.com>
+
+ * f95-lang.c (expand_function_body): Don't check flag_disable_gimple.
+
+2003-10-16 Steven Bosscher <steven@gcc.gnu.org>
+
+ * lang.c: Remove -M option for now, it's in the way for C.
+
+2003-10-14 Jason Merrill <jason@redhat.com>
+
+ * Make-lang.in (f95.tags): New rule.
+
+2003-10-13 Richard Henderson <rth@redhat.com>
+
+ * trans.c (gfc_trans_code): Use annotate_all_with_locus.
+
+2003-10-13 Paul Brook <paul@nowt.org>
+
+ * trans-decl.c (generate_local_decl): Don't create junk variables.
+
+2003-10-13 Paul Brook <paul@nowt.org>
+
+ * resolve.c (resolve_formal_arglist): Use function result decl in
+ preference to function decl.
+
+2003-10-12 Richard Henderson <rth@redhat.com>
+
+ * f95-lang.c (gfc_define_builtin): New const_p argument. Set
+ TREE_READONLY. Update all callers.
+
+2003-10-12 Feng Wang <wf_cs@yahoo.com>
+
+ * iresolve.c (gfc_resolve_cshift): Change to match implementation.
+ * trans-intrinsic.c (gfc_conv_intrinsic_function): Remove CSHIFT.
+ (gfc_is_intrinsic_libcall): Add CSHIFT.
+
+2003-10-12 Richard Henderson <rth@redhat.com>
+
+ * trans-array.c (gfc_trans_static_array_pointer): Set TREE_INVARIANT.
+ (gfc_trans_array_constructor_value): Likewise.
+ (gfc_conv_array_initializer): Likewise.
+ * trans-stmt.c (gfc_trans_character_select): Likewise.
+
+2003-11-12 Kejia Zhao <kejia_zh@yahoo.com.cn>
+
+ * trans-intrinsic.c (integer_kind_info, real_kind_info): Remove.
+
+2003-10-11 Huang Chun <jiwang@mail.edu.cn>
+
+ * check.c (gfc_check_repeat): Check arguments are scalar.
+ (gfc_check_trim): New function.
+ * intrinsic.h (gfc_check_trim): Add prototype.
+ * intrinsic.c (add_functions): Use it.
+ * trans.h (gfor_fndecl_string_trim, gfor_fndecl_string_repeat):
+ Decalare.
+ * trans-decl.c: Ditto.
+ (gfc_build_intrinsic_fucntion_decls): Set them.
+ * trans-intrinsic.c (gfc_conv_intrinsic_len): Handle result vars.
+ (gfc_conv_intrinsic_trim): New function.
+ (gfc_conv_intrinsic_repeat): New function.
+ (gfc_conv_intrinsic_function): Use them.
+
+2003-10-11 Huang Chun <jiwang@mail.edu.cn>
+
+ * trans-types.c (gfc_sym_type): Handle result variables.
+
+2003-10-11 Huang Chun <jiwang@mail.edu.cn>
+
+ * trans-intrinsic.c (gfc_conv_intrinsic_char): Don't use
+ gfc_get_character_type.
+
+2003-10-11 Feng Wang <wf_cs@yahoo.com>
+
+ * trans-expr.c (gfc_conv_variable): Check sym->ts, not the decl.
+
+2003-10-11 Paul Brook <paul@nowt.org>
+
+ * iresolve.c (gfc_resolve_dint, gfc_resolve_dnint): New functions.
+ (gfc_resolve_dprod): New function.
+ (gfc_resolve_aint, gfc_resolve_anint): Only base name on arg type.
+ * intrinsic.h (gfc_resolve_dint, gfc_resolve_dnint): Declare.
+ (gfc_resolve_dprod): Declare.
+ * intrinsic.c (add_functions): Use them.
+ * trans-decl.c (gfc_get_extern_function_decl): Only pass one arg.
+
+2003-10-06 Richard Henderson <rth@redhat.com>
+
+ * f95-lang.c (gfc_init_builtin_functions): Add clzll.
+ * trans-intrinsic.c (call_builtin_clz): Use it.
+
+2003-10-05 Paul Brook <paul@nowt.org>
+
+ * f95-lang.c (expand_function_body): Call (push|pop)_function_context.
+ * trans-decl.c (gfc_generate_function_code): Set
+ cfun->function_end_locus.
+
+2003-09-24 Jason Merrill <jason@redhat.com>
+
+ * f95-lang.c, trans-decl.c: Use DECL_SOURCE_LOCATION instead of
+ TREE_LOCUS.
+
+2003-09-21 Lifang Zeng <zlf605@hotmail.com>
+ Paul Brook <paul@nowt.org>
+
+ * Make-lang.in (F95_OBJS): Add fortran/data.o.
+ * array.c (gfc_inser_constructor): New function.
+ (gfc_get_constructor): New function.
+ (gfc_free_constructor): Initialize offset and repeat.
+ (iterator_stack): Remove.
+ (expand_info): Add offset, component and repeat fields.
+ (expand_constructor): Set them.
+ (expand): Set new fields.
+ (gfc_copy_constructor): Ditto. Avoid recursion.
+ * gfortran.h: Add prototypes for new functions.
+ (gfc_constructor): Add offset, component and repeat.
+ (iteratio_stack): Move to here.
+ * resolve.c (check_data_variable): Convert data values into variable
+ initializers.
+ (traverse_data_list): Build implicit loop chain.
+ (gfc_resolve): Ditto.
+ * trans-array.c (gfc_conv_array_intializer): Handle repeat count.
+ * trans-decl.c (gfc_get_symbol_decl): Use gfc_conv_structure.
+ * trans-expr.c (gfc_conv_structure): Handle array initializers.
+ (gfc_conv_expr): Update to match.
+ * trans.h (gfc_conv_structure): Declare.
+ * data.c: New file.
+
+2003-09-20 Kejia Zhao <kejia_zh@yahoo.com.cn>
+
+ * trans.h: Add declarations for gfor_fndecl_si_kind and
+ gfor_fndecl_sr_kind.
+ * trans-decl.c (g95_build_intrinsic_function_decls): Build them.
+ * trans-intrinsic.c (g95_conv_intrinsic_si_kind): New function.
+ (g95_conv_intrinsic_sr_kind): New function.
+ (g95_conv_intrinsic_function): Add SELECTED_INT_KIND and
+ SELECTED_REAL_KIND.
+
+2003-09-17 Lars Segerlund <Lars.Segerlund@comsys.se>
+
+ * iresolve.c (gfc_resolve_random_number): Generate _r4 & _r8
+ instead of _4 and _8 as postfix for libgfortran calls.
+
+2003-09-16 Paul Brook <paul@nowt.org>
+
+ * array.c (compare_bounds): New function.
+ (gfc_compare_array_spec): Use it.
+
+2003-09-14 Paul Brook <paul@nowt.org>
+
+ * primary.c (gfc_match_rvalue): Make sure sym->result is set.
+ * trans-expr.c (gfc_conv_string_parameter): Also allow PRAM_DECLs.
+
+2003-09-14 Paul Brook <paul@nowt.org>
+
+ * check.c (dim_rank_check): Allow assumed bounds if requested.
+ (gfc_check_lbound): Call it.
+ (gfc_check_ubound): Ditto.
+ (gfc_check_size): Change to match.
+ * simplify.c (gfc_simplify_bound): New function.
+ (gfc_simplify_lbound): New function.
+ (gfc_simplify_ubound): New function.
+ * intrinsic.h: Declare them.
+ * intrinsic.c (add_functions): Use them.
+
+2003-09-14 Paul Brook <paul@nowt.org>
+
+ * io.c (format_lex): Initialize negative_flag.
+ (check_format): Intialize repeat.
+ * trans-io.c (gfc_new_nml_name_expr): Declare static.
+ (gfc_new_var_expr): Ditto.
+
+2003-09-14 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (gfc_conv_array_initializer): Handle derived types.
+ * trans-decl.c (gfc_get_symbol_decl): Only do local scalar values.
+
+2003-09-12 Paul Brook <paul@nowt.org>
+
+ * trans-intrinsic.c (gfc_conv_intrinsic_sign): Call fold.
+
+2003-09-12 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * fortran/trans.c (gfc_finish_block): Call rationalize_compound_expr
+ for a correct expression.
+
+2003-09-10 Kejia Zhao <kejia_zh@yahoo.com.cn>
+
+ * trans-intrinsic.c (real_compnt_info): New struct.
+ (prepare_arg_info): New function.
+ (gfc_conv_intrinsic_set_exponent): New function.
+ (gfc_conv_intrinsic_scale): New function.
+ (gfc_conv_intrinsic_nearest): New function.
+ (gfc_conv_intrinsic_fraction): New function.
+ (gfc_conv_intrinsic_exponent): New function.
+ (gfc_conv_intrinsic_spacing): New function.
+ (gfc_conv_intrinsic_rrspacing): New function.
+ (gfc_conv_intrinsic_function): Use them.
+
+2003-08-24 XiaoQiang Zhang (zhangapache@yahoo.com>
+
+ * trans-const.c (gfc_conv_mpz_to_tree): Fix bug, parameter for
+ build_int_2 changed from (high, low) to (low, high).
+ * trans-io.c (ioparm_namelist_name, ioparm_namelist_name_len,
+ ioparm_namelist_read_mode, iocall_set_nml_val_int,
+ iocall_set_nml_val_float, iocall_set_nml_val_char,
+ iocall_set_nml_val_complex, iocall_set_nml_val_log): New declaration.
+ (gfc_build_io_library_fndecls): Add variable initialization.
+ (gfc_new_nml_name_expr, get_new_var_expr): New function.
+ (build_dt): Add namelist support.
+ * io.c (value): New variable.
+ (check_format): Support FMT_H now.
+
+2003-09-07 Paul Brook <paul@nowt.org>
+
+ * io.c (gfc_resolve_dt): Error if format label is not defined.
+
+2003-09-07 Kejia Zhao <kejia_zh@yahoo.com.cn>
+
+ * trans-intrinsic.c (gfc_conv_intrinsic_aint): Fix two bugs. One is
+ about case_switch's break. The other is about building the condition
+ statement tree, which judges the argument in the range of the
+ corresponding integer type.
+ * trans-intrinsic.c (gfc_conv_intrinsic_mod): MOD and MODULO can work
+ for the large values.
+
+2003-09-05 Paul Brook <paul@nowt.org>
+
+ * f95-lang.c (expand_function_body): Gimplify the function.
+
+2003-09-04 Jeff Law <law@redhat.com>
+
+ * f95-lang.c (DEFINE_MATH_BUILTIN): C arrays start at
+ index zero!
+
+2003-09-04 Paul Brook <paul@nowt.org>
+
+ * f95-lang.c (gfc_define_builtin): Also set implicit_built_in_decls.
+ (gfc_expand_stmt): New function.
+ (LANG_HOOKS_RTL_EXPAND_STMT): Define.
+ (expand_function_body): Use tree_rest_of_compilation.
+ * trans-decl.c (gfc_generate_function_code): Don't free cfun.
+
+2003-09-03 Jeff Law <law@redhat.com>
+
+ * f95-lang.c (gfc_init_builtin_functions): C arrays start at
+ index zero!
+
+2003-08-30 Paul Brook <paul@nowt.org>
+
+ * f95-lang.c (builtin_function): Remove #if 0 code.
+ (gfc_define_builtin): New function.
+ (gfc_init_builtin_functions): Use mathbuiltins.def not ../builtins.def.
+ * mathbuiltins.def: New file.
+ * trans-intrinsic.c (gfc_intrinsic_map_t): Add builtin code fields.
+ (gfc_intrinsic_map): Use mathbuiltins.def.
+ (gfc_intrinsic_builtin_t): Remove.
+ (gfc_build_intrinsic_lib_fndecls): Update.
+ * trans-types.c (gfc_init_types): Remove redundant initilaization of
+ signed_size_type_node.
+
+2003-08-29 Paul Brook <paul@nowt.org>
+
+ * arith.c (gfc_real_kinds): Use correct minimum exponents.
+
+2003-08-22 Kejia Zhao <kejia_zh@yahoo.com.cn>
+
+ * trans-instinsic.c (gfc_conv_intrinsic_mod): Also do MODULO.
+ (gfc_conv_intrinsic_function): Add MODULO.
+
+2003-08-22 Jason Merrill <jason@redhat.com>
+
+ * trans-array.c (gfc_conv_expr_descriptor): Update use of predicates.
+
+2003-08-22 Andreas Jaeger <aj@suse.de>
+
+ * Make-lang.in (f95.install-common): Add DESTDIR support.
+ * (f95.install-info): Likewise.
+ (f95.uninstall): Likewise.
+
+2003-08-19 Diego Novillo <dnovillo@redhat.com>
+
+ * trans-types.c (gfc_init_types): Initialize
+ signed_size_type_node with size_type_node.
+
+2003-08-18 Paul Brook <paul@nowt.org>
+
+ * dependency.c (gfc_dependency): New enum.
+ (check_another_array_ref): Remove.
+ (gfc_get_array_from_component): Remove.
+ (get_x): Remove.
+ (get_range): Remove.
+ (get_no_of_elements): Use mpz_t, not mpf_t.
+ (transform_sections): New function.
+ (gfc_check_range_range): Rename ...
+ (gfc_check_section_vs_section): ... to this. Use new function.
+ (gfc_is_inside_range): Rewrite to match.
+ (gfc_check_element_vs_section): Ditto.
+ (gfc_check_element_vs_element): Ditto.
+ (get_deps): Ditto.
+ (gfc_dep_resolver): Ditto. Remove unused parameter.
+ * Dependency.h (gfc_check_range_range, gfc_check_element_vs_section,
+ gfc_check_element_vs_element, gfc_is_inside_range,
+ gfc_get_array_from_component): Remove prototypes for static functions.
+ (gfc_dep_resolver): Update prototype.
+ * trans-array.c (gfc_conv_resolve_dependencies): Change to match.
+
+2003-08-15 Paul Brook <paul@nowt.org>
+
+ * trans-decl.c (gfc_build_qualified_array): Don't add symbols for
+ return values to parent scope.
+ (gfc_build_dummy_array_decl): Ditto.
+
+2003-08-14 Paul Brook <paul@nowt.org>
+
+ * trans-stmt.c (gfc_trans_allocate): Handle NULL refs. Allocate the
+ size of the type, not the pointer.
+ * resolve.c (resolve_symbol): Give more accurate error message.
+
+2003-08-10 Paul Brook <paul@nowt.org>
+
+ * trans-decl.c (gfc_build_function_decl): Only mangle global symbols.
+
+2003-08-10 Paul Brook <paul@nowt.org>
+
+ * trans-stmt.c (gfc_trans_allocate): Correctly handle non-array derived
+ type components.
+
+2003-08-10 Chun Huang <compiler@sohu.com>
+
+ * resolve.c (resolve_formal_arglist): Resolve STATEMENT function.
+ (resolve_symbol): Ditto.
+ * trans-expr.c (gfc_conv_statement_function): New function.
+ (gfc_conv_function_expr): Use it.
+
+2003-08-10 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (gfc_conv_ss_startstride): Handle functions.
+ (walk_function_expr): Set section rank.
+ * trans-intrinsic.c (gfc_walk_intrinsic_libfunc): Ditto.
+
+2003-08-10 Paul Brook <paul@nowt.org>
+
+ * intrinsic.c (add_sym): Prefix names with correct string.
+ (add_sym_0s): New function.
+ (add_subroutines): Register abort.
+
+2003-08-10 Erik Schnetter <schnetter@uni-tuebingen.de>
+
+ * gfortran.h: Introduce options to control the mangling.
+ * lang.opt: Likewise.
+ * options.c (gfc_init_options): Handle the options.
+ * trans-common.c (gfc_sym_mangled_common_id): New function.
+ (gfc_build_common_decl): Call it.
+ * trans-decl.c (gfc_sym_mangled_function_id): New function.
+ (gfc_get_extern_function_decl, gfc_build_function_decl): Call it.
+
+2003-08-09 Paul Brook <paul@nowt.org>
+
+ * module.c (mio_symbol): Always ouput a namespace for formal args.
+ (load_needed): Namespace now belong to their proper symbol.
+ (gfc_dump_module): Change G95=>GFORTRAN.
+
+2003-08-05 Paul Brook <paul@nowt.org>
+
+ * options.c: Force -fg77-calls.
+
+2003-08-02 Paul Brook <paul@nowt.org>
+
+ * Makelang.in: Rename G95_* to GFORTRAN_*.
+ * All sources: Rename G95_* to GFC_*.
+
+2003-08-01 Paul Brook <paul@nowt.org>
+
+ * fortran/Make-lang.in: Use GMPLIBS.
+ * fortran/config-lang.in: Set need_gmp.
+ * trans-expr.c (gfc_conv_variable): Remove incorrect assertion.
+
+2003-07-27 Andreas Jaeger <aj@suse.de>
+
+ * trans-decl.c (gfc_generate_constructors): Convert prototype to
+ ISO C90.
+ * trans-const.c (gfc_init_constants): Likewise.
+ * trans-intrinsic.c (gfc_build_intrinsic_lib_fndecls): Likewise.
+
+ * gfortranspec.c: Convert to ISO C90.
+ (lang_specific_driver): Correct copyright, remove ALT_LIBM usage.
+
+2003-07-26 Paul Brook <paul@nowt.org>
+
+ * lang.opt: Add -fdump-parse-tree.
+ * options.c (gfc_handle_option): Ditto.
+ * resolve.c (resolve_forall_iterators): Convert to proper type.
+ * trans-stmt.c (gfc_trans_forall_1): Create temp var with correct type.
+
+2003-07-26 Paul Brook <paul@nowt.org>
+
+ * Makefile.in: Add build dependencies on files common with rest of gcc.
+
+2003-07-26 Lifang Zeng <zlf605@hotmail.com>
+
+ * trans.h: Declare g95_trans_pointer_assignment.
+ * trans-expr.c (g95_trans_pointer_assignment): New function.
+ (g95_trans_pointer_assign): Use it.
+ * trans-stmt.c (g95_trans_forall_1): Handle pointer assignment.
+ (g95_trans_pointer_assign_need_temp): New function.
+
+2003-07-26 Paul Brook <paul@nowt.org>
+
+ * gfortran.texi: Replace references to g95.
+
+2003-07-26 Paul Brook <paul@nowt.org>
+
+ Rename g95_* to gfc_*.
+
+2003-07-25 Paul Brook <paul@nowt.org>
+
+ * gfortran.h: Rename from g95.h.
+ * trans-types.c (boolean_type_node, booelan_true_node,
+ boolean_false_node): Remove.
+ * trans-types.h: Ditto.
+
+2003-07-25 Chun Huang <compiler@sohu.com>
+
+ * parse.c (accept_statement): Implement BLOCK DATA statement.
+ * trans-expr.c (g95_conv_variable): Fix bug for dereference pointer
+ variables.
+
+2003-07-24 Lifang Zeng <zlf605@hotmail.com>
+
+ * trans-stmt.c (temporary_list): Define.
+ (g95_trans_assign_need_temp): New function.
+ (g95_trans_forall_1): Modified for WHERE.
+ (g95_trans_where_assign): Modified.
+ (g95_trans_where_2): Modified.
+ (g95_evaluate_where_mask): Modified.
+ (g95_trans_where): Modified.
+ (g95_get_temp_expr): Removed.
+ (g95_add_to_where_stmt_list): Removed.
+ (compute_overall_iter_number): Modified for WHERE.
+ * trans.h: Remove where_stmt_list.
+
+2003-07-24 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+
+ * lang.opt: Correct description of options -J and -M.
+
+2003-07-23 Steven Bosscher <steven@gcc.gnu.org>
+
+ * lang.opt: Move help text to here.
+ * lang-options.h: Remove.
+
+2003-07-23 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+ * iresolve.c (g95_resolve_transpose): Proper variable in switch.
+ * simplify.c (g95_simplify_nearest): Fix typo and use a correct test
+ on kind.
+
+2003-07-22 Steven Bosscher <steven@gcc.gnu.org>
+ Paul Brook <paul@nowt.org>
+
+ * check.c (check_rest): Use global pedantic flag.
+ * io.c (data_desc): Ditto.
+ * error.c (g95_warning, g95_warning_now): Use global flag.
+ * f95-lang.c (LANG_HOOKS_HANDLE_OPTION): Rename from DECODE.
+ (expand_function_body): Update to new prototypes.
+ (g95_init): Use new option names.
+ * g95.h (g95_option_t): Standardize names.
+ (g95_init_options, g95_handle_option): Update prototypes.
+ * interface.c: Use new option names.
+ * match.c: Ditto.
+ * module.c: Ditto.
+ * parse.c: Ditto.
+ * primary.c: Ditto.
+ * resolve.c: Ditto.
+ * scanner.c: Ditto.
+ * simplify.c: Ditto.
+ * symbol.c: Ditto.
+ * trans-array.c: Ditto.
+ * trans-expr.c: Ditto.
+ * trans-types.c: Ditto.
+ * trans-decl.c: Ditto.
+ (g95_build_library_function_decl): Remove obsolete VPARAMS.
+ * trans.h: Ditto.
+ * options.c (g95_display_help): Remove.
+ (g95_init_options): Convert to new scheme.
+ (set_Wall): Ditto
+ (g95module_option): Ditto, rename from g95_parse_arg.
+ (g95_handle_module_path_options): New function.
+ * trans-equivalence.c: Fix error message.
+ * lang.opt: Corrections.
+
+2003-07-21 Steven Bosscher <steven@gcc.gnu.org>
+
+ * lang.opt: New file.
+
+2003-07-21 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+
+ * decl.c (match_attr_spec): Set colon_seen.
+
+2003-07-14 Paul Brook <paul@nowt.org>
+
+ * trans-array.c: Update comment.
+ (g95_trans_array_constructor_subarray): Cleanup loopinfo data.
+ * trans-intrinsic.c (g95_conv_intrinsic_anyall,count,arith,
+ minmaxloc,minmaxval): Ditto.
+ * trans-io.c (g95_trans_transfer): Ditto.
+ * trans-stmt.c: Remove unneeded prototypes.
+ (generate_loop_for_lhs_to_rhs): Rename vars. Add loop post chain.
+ (generate_loop_for_rhs_to_temp): Rename vars. Don't share loopinfo.
+ (compute_inner_temp_size): Remove bits of dead code. Add comments.
+ Don't share loopinfo.
+ (compute_overall_iter_number): Declare as static.
+ (allocate_temp_for_forall_nest): Ditto.
+ (g95_trans_forall_1): Don't pass shared loopinfo.
+ * trans.c (g95_start_block): Expand comment.
+
+2003-07-12 Paul Brook <paul@nowt.org>
+
+ * arith.c (g95_index_integer_kind): Remove unused initializer.
+ * trans-stmt.c (generate_loop_for_temp_to_lhs): Don't multiply array
+ index by size of element.
+ (generate_loop_for_rhs_to_temp): Ditto.
+ (allocate_temp_for_forall_nest): Use element size, not index size.
+
+2003-07-11 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+
+ * arith.c (g95_index_integer_kind): Add a TODO.
+ * simplify.c (g95_simplify_nearest): Add a TODO.
+
+2003-07-09 Chun Huang <compiler@sohu.com>
+
+ * trans.h: Add declarations for gfor_fndecl_string_scan and
+ gfor_fndecl_string_verify.
+ * trans-decl.c (g95_build_intrinsic_function_decls): Build them.
+ * trans-intrinsic.c (g95_conv_intrinsic_scan): New function.
+ (g95_conv_intrinsic_verify): New function.
+ (g95_conv_intrinsic_function): Add SCAN and VERIFY.
+ * simplify.c (g95_simplify_scan, g95_simplify_verify): Fix bug in case
+ of parameter 'BACK=.TRUE.'
+
+2003-07-05 Lifang Zeng <zlf605@hotmail.com>
+
+ * trans-stmt.c (iter_info, forall_info): Define.
+ (g95_trans_forall_block): Remove.
+ (g95_trans_forall_loop): Use forall info blocks.
+ (g95_trans_nested_forall_loop): New function.
+ (g95_do_allocate): Handle things other than logical masks.
+ (generate_loop_for_temp_to_lhs): New function.
+ (generate_loop_for_rsh_to_temp): New function.
+ (compute_inner_temp_size): New function.
+ (compute_overall_iter_number): New function.
+ (allocate_temp_for_forall_nest): New function.
+ (g95_trans_forall): Move body ...
+ (g95_trans_forall_1): ... to here. Handle loops with temporaries.
+
+2003-07-02 Paul Brook <paul@nowt.org>
+
+ * trans-decl.c (create_index_var, g95_build_qualified_array): Put vars
+ in correct scope. Change callers to match.
+ * trans-types.c (g95_get_dtype_cst): Allow rank 7 arrays.
+ * iresolve.c (g95_resolve_reshape): Only use constant shapes.
+
+2003-07-02 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (g95_conv_loop_setup): Remove dead var. Use
+ expression shape for all expressions.
+ * trans-decl.c (g95_symbol_init): Allow adding at very end of list.
+
+2003-07-03 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+
+ * g95.h (g95_option_t), lang-options.h, options.c (g95_init_options,
+ g95_parse_arg), intrinsic.c (g95_convert_type): support of
+ -Wconversion.
+ * intrinsic.c, g95.h: Add g95_convert_type_warn,
+ * resolve.c (g95_resolve_index): Call it.
+
+2003-07-02 Paul Brook <paul@nowt.org>
+
+ * iresolve.c (g95_resolve_reshape): Set expression shape.
+ (g95_resolve_shape): Ditto.
+ * simplify.c (g95_simplify_shape): Move common code outside condition.
+ * trans-array.c (g95_conv_array_initializer): Teach it how to count.
+
+2003-07-01 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+
+ * array.c (g95_array_dimen_size): Deal with EXPR_ARRAY to improve
+ conformance checks.
+
+2003-06-29 Paul Brook <paul@nowt.org>
+
+ * array.c (g95_simplify_iterator_var): Don't bother with return value.
+ * expr.c (find_array_element, find_component_ref): New functions.
+ (remove_subobject_ref): New function.
+ (simplify_const_ref): Use them. Rename from simplify_component_ref.
+ (simplify_ref_chain): New function.
+ (g95_simplify_expr): Use it. Simplify parameter variable subobjects.
+ (g95_specification_expr): Simplify the expression.
+ * resolve.c (resolve_operator): Check simplifications return code.
+ (g95_resolve_expr): Ditto.
+
+2003-06-26 Paul Brook <paul@nowt.org>
+
+ * expr.c (simplify_component_ref): New function.
+ (g95_simplify_expr): Use it.
+ * resolve.c (resolve_structure_cons): Handle references.
+
+2003-06-25 Paul Brook <paul@nowt.org>
+
+ * trans-io.c (build_dt): Handle internal units.
+
+2003-06-25 Canqun Yang <canqun@yahoo.com.cn>
+
+ * trans-common.c (g95_build_common_decl): Array index range starts at 0.
+ (g95_build_common_decl, g95_layout_global_equiv, g95_trans_one_common):
+ Use g95_array_index_type instead of integer_type_node.
+ (g95_build_common_decl, g95_set_common_master_type): Use
+ g95_character1_type_node instead of char_type_node.
+ * trans-equivalence.c (g95_layout_local_equiv): As above.
+
+2003-06-24 Steven G. Kargl <kargls@attbi.com>
+
+ * g95.h (g95_option_t), options.c (g95_init_options, g95_parse_arg):
+ remove last remains of -fquiet.
+
+2003-06-22 Paul Brook <paul@nowt.org>
+
+ * resolve.c (resolve_operator): Don't fail if we can't simplify.
+ (g95_resolve_expr): Ditto.
+ (resolce_code): Mark as static.
+ * trans-stmt.c (g95_trans_chaaracter_select): Mark labels because the
+ gimplifer doesn't (yet).
+
+2003-06-20 Paul Brook <paul@nowt.org>
+
+ * g95.h: Add ST_PAUSE and EXEC_PAUSE.
+ * match.c (g95_match_if): Add ST_PAUSE.
+ (g95_match_stopcode): New function.
+ (g95_match_pause, g95_match_stop): Use it.
+ * parse.c (g95_ascii_statement): Handle ST_PAUSE.
+ (decode_stmt, next_statement, parse_executable): Ditto.
+ * resolve.c (resolve_code): Ditto.
+ * st.c (g95_free_statement): Ditto.
+ * trans-stmt.c (g95_trans_pause): New function.
+ * trans-stmt.h: Declare it.
+ * trans.c (g95_trans_code): Use it.
+ * trans-decl.c (gfor_fndecl_pause_numeric, gfor_fndecl_pause_string):
+ Declare.
+ (g95_build_builtin_function_decls): Initialize them.
+ * trans.h: Ditto.
+ * dump-parse-tree.c (g95_show_code_node): Handle EXEC_PAUSE.
+
+2003-06-18 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+
+ * io.c (g95_match_open , g95_match_close, g95_match_inquire,
+ match_filepos): Fix error handling.
+
+2003-06-18 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+
+ * array.c (spec_dimen_size, ref_dimen_size, g95_array_dimen_size):
+ Add assertions on arguments.
+ * resolve.c (expression_shape): Remove useless &.
+ * simplify.c (get_kind, g95_simplify_bit_size, g95_simplify_digits,
+ g95_simplify_ibclr, g95_simplify_ibits, g95_simplify_ibset,
+ g95_simplify_ishft,g95_simplify_ishftc, g95_simplify_maxexponent,
+ g95_simplify_minexponent, g95_simplify_radix, g95_simplify_range
+ g95_simplify_rrspacing, g95_simplify_scale, g95_simplify_spacing,
+ g95_simplify_tan, g95_simplify_tiny): Clean predicates and assertions.
+ (g95_simplify_not, g95_simplify_scale): Add assertions.
+
+2003-06-15 Paul Brook <paul@nowt.org>
+
+ Clean up stuff to work with the ssa optimizers.
+ * convert.c (convert): Handle BOOLEAN_TYPEs.
+ * f95-lang.c (g95_truthvalue_conversion): Implement.
+ * trans-array.c (g95_trans_array_constructor_value): Group multiple
+ scalar values.
+ * trans.h (g95_truthvalue_conversion): Declare.
+ * trans-intrinsic.c (g95_conv_intrinsic_anyall): Use bool constants.
+ * trans-stmt.c (g95_trans_character_select): Don't create array
+ assignments. Mark labels as indirect jump targets.
+ * trans-types.h (g95_init_types): Use BOOLEAN_TYPE nodes.
+ (g95_get_dtype_cst): Handle LOGICAL types.
+
+2003-06-14 Paul Brook <paul@nowt.org>
+
+ * f95-lang.c (g95_gimplify_expr): New function.
+ * trans-array.c (g95_trans_array_constructor_value): Don't create
+ array assignments.
+ (g95_conv_expr_descriptor): Rename simple->gimple.
+ * trans-expr.c (conv_expr_op): Use proper logical operators.
+ * trans-intrinsic.c (build_fixbound_expr): New function.
+ (build_fix_expr): Ditto.
+ (g95_conv_intinsic_aint): Use them. Use builtin functions.
+ (g95_conv_intrinsic_function): Add FLOOR and CEILING.
+
+2003-06-10 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+
+ * array.c (g95_compare_array_spec): Remove unreachable code.
+ * expr.c (g95_copy_expr): Likewise.
+ * intrinsic.c (g95_convert_type): Likewise.
+ * misc.c (g95_code2string): Likewise.
+ * simplify.c (g95_simplify_ishft, g95_simplify_real,
+ g95_simplify_reshape, g95_simplify_sign, g95_simplify_sqrt): Likewise.
+ * trans-stmt.c (g95_trans_select): Likewise.
+ * primary.c (extend_ref): Add an assertion.
+ * simplify.c (g95_convert_constant): Add const.
+ * intrinsic.h: Remove g95_check_x_ni.
+ * f95-lang.c (g95_finish): Call g95_release_include_path.
+
+2003-06-10 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+
+ * resolve.c (resolve_contained_functions): Fix typo introduced on
+ 2003-01-13.
+
+2003-06-09 Paul Brook <paul@nowt.org>
+
+ * g95.h: Include system.h not hwint.h.
+ * many: use safe-ctype.h not ctype.h. Change isalpha -> ISALPHA, etc.
+ * misc.c (g95_getmem): Use xmalloc/memset instead of calloc.
+
+2003-06-09 Paul Brook <paul@nowt.org>
+
+ * g95.h (g95_symbol): Add fields for COMMON and EQUIVALENCE variables.
+ * Make-lang.in (F95_OBJS): Add files for COMMON and EQUIVALENCE.
+ * trans-decl.c (g95_add_decl_to_functions): Make non-static.
+ (g95_get_symbol_decl): Handle COMMON and EQUIVALENCE objects.
+ (g95_generate_function_code): Translate COMMON and EQUIVALENCE
+ objects.
+ * trans.h (g95_trans_equivalence, g95_trans_common,
+ g95_add_decl_to_function): Declare.
+ * trans-common.c, trans-equivalence.c: New files.
+
+2003-06-08 Steven Bosscher <steven@gcc.gnu.org>
+
+ * intrinsic.c (g95_intrinsic_extension): Remove.
+ (add_functions): Substitute g95_check_x for g95_check_x_ni
+ everywhere.
+ (g95_init_expr_extensions): New function.
+ (g95_intrinsic_func_interface): Use it.
+ * intrinsic.h: Remove extern decl for g95_intrinsic_extension.
+ * check.c (g95_check_digit, g95_check_huge, g95_check_kind,
+ g95_check_precision, g95_check_present, g95_check_radix,
+ g95_check_range, g95_check_selected_real_kind): Do not set
+ g95_intrinsic_extension.
+ (g95_check_x_ni): Remove now duplicate of g95_check_x.
+
+ * expr.c (check_inquiry): Add FIXME, fixup some code style.
+
+2003-06-06 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+
+ * g95.h (ref_type): Name this type explicitly.
+ * module.c (MIO_NAME): Add specialisations of mio_name.
+ (mio_symbol_attribute, mio_typespec, mio_array_ref,
+ mio_array_spec, mio_ref, mio_expr, mio_symbol): Use them.
+ (ab_attribute): Name this type explicitly.
+ (mio_symbol_attribute, mio_expr): Add cast to call to find_enum.
+
+2003-06-05 Kejia Zhao <kejia_zh@yahoo.com.cn>
+
+ * trans-intrinsic.c (g95_conv_allocated): New function.
+ (g95_conv_intrinsic_function): Make G95_ISYM_ALLOCATED work.
+
+2003-06-05 Steven Bosscher <steven@gcc.gnu.org>
+
+ * f95-lang.c: Don't include g95-support.h
+ (g95_mark_addressable): Add prototype.
+ (g95_init_decl_processing): Remove C front end hack.
+ * f95-tree.c: Remove file.
+ * support.c: Remove file.
+ * g95-support.h: Remove file.
+ * trans-types.c (g95_init_types): Set up boolean
+ type related tree nodes.
+ * Make-lang.in: Remove rules for dead files and
+ dependencies on them.
+
+2003-06-05 Steven Bosscher <steven@gcc.gnu.org>
+
+ * Make-lang.in (F95_ADDITIONAL_OBJS): Remove the final
+ C front end dependency. Also, convert.c does not depend on
+ g95-support.h anymore.
+ * convert.c: Don't include c-common.h and g95-support.h
+ * f95-lang.c: Don't inlude c-common.h and c-common.def (3x).
+ (g95_stmt_tree, g95_scope_stmt_stack, anon_aggr_type_p,
+ stmts_are_full_exprs_p, current_stmt_tree,
+ current_scope_stmt_stack): Remove.
+ * g95-support.h (unsigned_conversion_warning): Kill proto.
+ (boolean_type_node, boolean_true_node, boolean_false_node):
+ Don't define here. Instead, make then true tree nodes in
+ trans-types.
+ * support.c (c_global_trees): Die, C front end, die!!!
+ (g95_init_c_decl_hacks): Don't touch intmax_type_node,
+ uintmax_type_node, string_type_node and const_string_type_node.
+ (decl_constant_value, overflow_warning): Make static functions.
+ They are in death row too, though.
+ (default_conversion, c_expand_asm_operands): Remove.
+ * trans-array.c, trans-expr.c, trans-intrinsic.c, trans-stmt.c,
+ trans.c: Don't include c-common.h.
+ * trans-types.c (boolean_type_node, boolean_true_node,
+ boolean_false_node): Make them real tree nodes.
+ * trans-types.h (intmax_type_node, string_type_node,
+ const_string_type_node): Hack to work around C dependencies
+ in builtin-types.def.
+
+2003-06-04 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+
+ * decl.c (decl_types): Add some iterators-like sentinels.
+ * decl.c (match_attr_spec): Use them.
+ Use "decl_types" instead of "int".
+ Add cast in call to g95_match_strings.
+ * dump-parse-tree.c (g95_show_namespace): Use "g95_intrinsic_op"
+ instead of "int".
+ * g95.h (g95_intrinsic_op): Add some iterators-like sentinels.
+ (g95_interface_info): Use "g95_intrinsic_op".
+ * dump-parse-tree.c (g95_show_namespace): Use them.
+ * interface.c (g95_check_interfaces): Use them.
+ * module.c (read_module, write_module): Use them.
+ * symbol.c (g95_get_namespace, g95_free_namespace): Use them.
+ Use "g95_intrinsic_op".
+ * interface.c (check_operator_interface): Use "g95_intrinsic_op".
+ Add a default case in switch statement.
+ * intrinsic.h (g95_generic_isym_id): Moved to...
+ * g95.h (g95_generic_isym_id): here.
+ (g95_intrinsic_sym): Use "g95_generic_isym_id".
+ * intrinsic.c (make_generic): Use "g95_generice_isym_id".
+ * trans-intrinsic.c (g95_intrinsic_map_t,
+ g95_conv_intrinsic_lib_funtion): Use "g95_generice_isym_id".
+ * match.c (g95_match_intrinsic_op): Add cast in call to
+ g95_match_strings.
+
+2003-06-03 Steven Bosscher <steven@gcc.gnu.org>
+
+ * support.c (skip_evaluation, warn_conversion, lvalue_p,
+ lvalue_or_else, pedantic_lvalue_warning, warn_for_assignment,
+ constant_fits_type_p, convert_and_check,
+ unsigned_conversion_warning): Remove these ugly remnants
+ we inherited from the C front end.
+ (function_types_compatible): Remove '#if 0'-edcode.
+ (build_modify_expr): Likewise.
+ (convert_for_assignment): Don't use the deceased functions.
+ The parameter fundecl is now unused.
+ (decl_constant_value): Always just return decl. In fact
+ this function is not used at present, but it might be in
+ the future, when we start using the tree inliner.
+ (overflow_warning, default_conversion, c_expand_asm_operands):
+ Abort when these are called, they are part of the C type
+ checking implementation and therefore poison to Fortran.
+
+2003-06-04 Steven Bosscher <steven@gcc.gnu.org>
+
+ * Make-lang.in (F95_ADDITIONAL_OBJS): Don't depend on
+ c-pretty-print.o and c-dump.o. Add a comment on why we
+ depend on c-semantics.c.
+ * f95-lang.c (LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN):
+ Don't use the C front end tree dumper hook to dump the
+ language specific tree representation -- we don't have
+ one. So instead, inherit the default langhook.
+
+2003-06-02 Paul Brook <paul@nowt.org>
+
+ * trans-expr.c (g95_conv_variable): Remove incorrent assertion.
+
+2003-06-02 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+
+ * check.c (g95_check_associated): Use proper types. Remove
+ extraneous argument in call to g95_error().
+
+2003-06-02 Kejia Zhao <kejia_zh@yahoo.com.cn>
+
+ * resolve.c (resolve_operator): Make logical operands convert to the
+ type with higher kind.
+
+2003-06-02 Kejia Zhao <kejia_zh@yahoo.com.cn>
+
+ * check.c (g95_check_associated): Make sure both pointer and target has
+ the same type and rank. Null pointer or array section with vector
+ subscript as target are not allowed.
+ * trans.h: Declare gfor_fndecl_associated.
+ * trans-decl.c: (g95_build_builtin_function_decls): Initialize
+ gfor_fndecl_associated.
+ * trans-intrinsic.c (g95_conv_associated): New function.
+ (g95_conv_intrinsic_function): Make G95_ISYM_ASSOCIATED work.
+
+2003-06-02 Kejia Zhao <kejia_zh@yahoo.com.cn>
+
+ * trans-array.c (g95_conv_expr_descriptor): Set the base of POINTER
+ according to POINTER itself rather than TARGET.
+ (g95_conv_expr_descriptor): Make lbound start at 1.
+ * trans-expr.c (g95_trans_pointer_assign): Fix a bug for Nullify.
+
+2003-06-01 Paul Brook <paul@nowt.org>
+
+ * expr.c (g95_type_convert_binary): Make it match the standard.
+ * g95.texi: Remove dead link.
+
+2003-06-01 Steven Bosscher <steven@gcc.gnu.org>
+
+ * g95.texi: Cleanup somewhat in preparation for inclusion
+ in GCC CVS.
+
+2003-05-23 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+ Canqun Yang <canqun@yahoo.com.cn>
+
+ * resolve.c (compare_bound_int, resolve_where_shape): Proper return
+ type.
+ (g95_find_forall_index): Return proper value.
+ (g95_resolve_assign_in_forall, g95_resolve_forall): Use proper type to
+ compare the return value from g95_find_forall_index.
+
+2003-05-23 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+ * g95.h, io.c (g95_st_label): Remove "length".
+ (g95_symtree): Remove "link".
+ (g95_case): Remove "code".
+ * arith.c, arith.h (g95_compare_string, g95_convert_integer,
+ g95_convert_real): Make an argument pointer to const.
+ * decl.c (colon_seen): Add a TODO.
+ * interface.c (g95_compare_types): Fix typo.
+ * interface.c (compare_interfaces): Preserve value of "p".
+ * intrinsic.c (sort_actual): Remove "i".
+ * match.c (g95_match_assign): Proper type in call to g95_match().
+ * parse.c (next_free): Avoid duplicate call due to macro.
+ * parse.c (check_statement_label): wrong type in call to g95_error.
+ * primary.c (match_real_constant): Add a TODO.
+ * resolve.c (resolve_select): Remove useless conditional.
+ * simplify.c (g95_simplify_repeat): Proper assignment to
+ "value.character.string".
+ * simplify.c (g95_simplify_reshape): Wrong variable in call to
+ g95_error.
+
+2003-05-20 Canqun Yang <canqun@yahoo.com.cn>
+
+ * trans-stmt.c: Remove unnecessary include file defaults.h.
+
+2003-05-19 Lifang Zeng <zlf605@hotmail.com>
+
+ * trans-stmt.c (g95_trans_forall_loop): Handle FORALL with negative
+ stride.
+ (g95_trans_forall): Allow arbitrary number of FORALL indexes and
+ actual variables used as FORALL indexes.
+
+2003-05-15 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (g95_trans_static_array_pointer): Use
+ null_pointer_node.
+ (g95_trans_deferred_array): Initialize static array pointers.
+ * trans-expr.c (g95_conv_function_call): Use formal arglist to
+ correctly pass POINTER and absent CHARACTER arguments.
+
+2003-05-14 Lifang Zeng <zlf605@hotmail.com>
+
+ * resolve.c (g95_resolve_forall): Resolve FORALL construct/statement.
+ (g95_resolve_forall_body): Resolve FORALL body.
+ (g95_resolve_where_code_in_forall): Resolve WHERE inside FORALL.
+ (g95_resolve_assign_in_forall): Resolve assignment inside FORALL.
+ (g95_find_forall_index): Check whether the FORALL index appears in
+ the expression or not.
+ (resolve_code): Modified.
+
+2003-05-14 Paul Brook <paul@nowt.org>
+
+ * iresolve.c (g95_resolve_spread): Convert ncopies to index_type.
+
+2003-05-13 Paul Brook <paul@nowt.org>
+
+ * trans-types.c (g95_max_array_element_size): Now a tree node.
+ (g95_init_types): Work out max size properly.
+ (g95_get_dtype_cst): Modify to match.
+
+2003-05-11 Paul Brook <paul@nowt.org>
+
+ * trans-io.c (add_case): Create a label decl for case labels.
+
+2003-05-11 Paul Brook <paul@nowt.org>
+
+ * arith.c (g95_integer_index_kind): New variable.
+ * f95-lang.c (g95_init): Move frontend initialization here ...
+ (g95_post_options): ... from here.
+ * g95.h (g95_index_integer_kind, g95_resolve_index): Declare.
+ * intrinsic.c (add_functions): Use index kinds.
+ * iresolve.c: Convert to index_kind where needed.
+ * resolve.c (g95_resolve_index): Make public, use index_kind.
+ (resolve_array_ref): Adjust to match.
+ * trans-array.c: Rename g95_array_index_kind to g95_index_integer_kind.
+ * trans-stmt.c: Ditto.
+ * trans-types.c: Ditto.
+ * trans-types.h (g95_array_index_kind): Remove declaration.
+ * trans-expr.c (g95_conv_expr_present): Use null_pointer_node.
+
+2003-05-07 Paul Brook <paul@nowt.org>
+
+ * trans-const.c (g95_conv_mpz_to_tree): Typecast constant.
+ * trans-intrinsic.c (g95_conv_intrinsic_bound): Convert type
+ of bound indices.
+
+2003-05-07 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (trans_static_array_pointer,
+ g95_trans_array_constructor_value, g95_conv_array_initializer,
+ g95_conv_structure): CONSTRUCTOR nodes only have one operand.
+ (g95_add_loop_ss_code): Convert subscripts to the correct type.
+ * trans-stmt.c (g95_trans_character_select): Ditto.
+ * trans-types.c (g95_init_types): Ditto.
+
+2003-05-07 Steven Bosscher <steven@gcc.gnu.org>
+
+ * f95-lang.c (expand_function_body): Use input_line, not lineno.
+ * trans-decl.c (g95_generate_function_code,
+ g95_generate_constructors): Likewise.
+ * trans.c (g95_trans_runtime_check, g95_add_block_to_block,
+ g95_get_backend_locus, g95_set_backend_locus, g95_trans_code):
+ Likewise.
+
+2003-05-07 Kejia Zhao <kejia_zh@yahoo.com.cn>
+ * trans-types.c (g95_get_derived_type): Fix bug for DERIVED type
+ with components point to the DERIVED type itself, and two DERIVED
+ type with components point to each other.
+ * trans-expr.c (g95_conv_componet_ref): Modified
+
+2003-05-07 Kejia Zhao <kejia_zh@yahoo.com.cn>
+ * trans-expr.c (g95_conv_expr): Translate EXPR_NULL into
+ null_pointer_node.
+ (g95_trans_pointer_assign): Implement Nullify.
+
+2003-05-01 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (g95_walk_function_expr): Cope with NULL esym.
+ * trans-decl.c (g95_get_symbol_decl): Don't mangle dummy functions.
+
+2003-05-01 Paul Brook <paul@nowr.org>
+
+ * trans-array.c, trans.c, trans-expr.c, trans-intrinsic.c,
+ trans-stmt.c: Replace empty_stmt_node with build_empty_stmt () and
+ IS_EMPTY_STMT.
+
+2003-05-01 Canqun Yang <canqun@yahoo.com.cn>
+
+ * trans-stmt.c (g95_trans_integer_select): Add a parameter to build
+ CASE_LABEL_EXPR.
+
+2003-04-28 Paul Brook <paul@nowt.org>
+
+ * iresolve.c (g95_resolve_transpose): COMPLEX types are twice as big
+ as their kind suggests.
+ (g95_resolve_reshape): Ditto.
+
+2003-04-28 Chun Huang <compiler@sohu.com>
+
+ * trans-expr.c (g95_conv_substring_expr): New function.
+ (g95_conv_expr): Use it.
+
+2003-04-28 Paul Brook <paul@nowt.org>
+
+ * iresolve.c (g95_resolve_transpose): Make it match the
+ implementation.
+ * trans-intrinsic.c (g95_is_intrinsic_libcall): Add TRANSPOSE.
+
+2003-04-18 Steven Bosscher <steven@gcc.gnu.org>
+
+ * trans-types.c (g95_add_field_to_struct): New function to
+ add a field to a UNION_TYPE or RECORD_TYPE.
+ * trans-types.h (g95_add_field_to_struct): Prototype.
+ (g95_get_derived_type): Use g95_add_field_to_struct to add
+ components.
+ * trans-io.c (g95_add_field): Remove.
+ (ADD_FIELD): Use new g95_add_field_to_struct function.
+ (ADD_STRING): Likewise.
+ * trans-stmt.c (g95_trans_select): Likewise.
+ (g95_add_field): Remove duplicated function.
+
+2003-04-18 Canqun Yang <canqun@yahoo.com.cn>
+
+ Port implementation for CHARACTER SELECT from Andy's tree.
+ * trans-stmt.c (g95_trans_character_select): Implement character
+ select. (g95_add_field): New function.
+ * trans-decl.c: Declare 'gfor_gndecl_select_string'.
+ (g95_build_builtin_function_decls): Add 'gfor_fndecl_select_string'.
+ * g95.h (struct g95_case): Add field 'int n'.
+ * trans.h: Declare 'gfor_fndecl_select_string'.
+
+2003-04-18 Steven Bosscher <steven@gcc.gnu.org>
+
+ * bbt.c (duplicate_key, g95_insert_bbt_with_overlap): Remove.
+ (g95_insert_bbd): Die on duplicates.
+ * g95.h (g95_insert_bbt_with_overlap): Delete prototype.
+
+2003-04-14 Steven Bosscher <steven@gcc.gnu.org>
+
+ * g95.texi: Require GMP 4.0 -- like we actually
+ do. Explain the testsuite and what-goes-where.
+ Don't use undefined texinfo symbol. Break very
+ long line. Remove finished item from the list
+ of open projects.
+
+2003-04-11 Canqun Yang <canqun@yahoo.com.cn>
+
+ * trans-stmt.c (g95_evaluate_where_mask): Give mask temporaries
+ LOGICAL type.
+
+2003-04-10 Canqun Yang <canqun@yahoo.com.cn>
+
+ * trans-stmt.c (g95_trans_forall): Implement WHERE inside FORALL.
+ (g95_trans_forall_body): New function.
+
+2003-04-10 Canqun Yang <canqun@yahoo.com.cn>
+
+ * resolve.c (resove_where): New function.
+ (resolve_where_shape): New function.
+ (resolve_code): Add call to 'resolve_where'
+ * trans-stmt.c (g95_trans_where): Modified.
+ (g95_trans_where_2): New function.
+ (g95_trans_where_assign): New function.
+ (g95_evaluate_where_mask): New function.
+ (g95_add_to_stmt_list): New function.
+ (g95_get_temp_expr): New function.
+ * trans.h (where_stmt_list): New structure.
+
+2003-04-10 Paul Brook <paul@nowt.org>
+
+ * g95spec.c (DEFAULT_SWITCH_TAKES_ARG): Remove.
+ (DEFAULT_WORD_SWITCH_TAKES_ARG): Ditto.
+
+2003-04-10 Steven Bosscher <steven@gcc.gnu.org>
+
+ Update after mainline -> tree-ssa-branch merge.
+ * f95-lang.c (g95_mark_addressable): Update put_var_into_stack
+ call.
+ (g95_init): Update for new lang_hooks definition.
+ (g95_post_options): New langhook.
+ (LANG_HOOK_POST_OPTIONS): Clear, then define to g95_post_options.
+ * scanner.c (g95_new_file): Comment update.
+
+2003-04-09 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+
+ * g95.h, lang-options.h: Add -Wimplicit-interface.
+ * options.c (g95_init_options, g95_parse_arg): Set it.
+ * interface.c (check_intents): Warn about call with implicit
+ interface.
+ * resolve.c (resolve_unknown_f, resolve_unknown_s): Call
+ g95_procedure_use.
+
+2003-04-05 Paul Brook <paul@nowt.org>
+
+ * iresolve.c (g95_resolve_spread): Don't resole based on type.
+ * trans-intrinsic.c (g95_is_intrinsic_libcall): Add G95_ISYM_SPREAD.
+
+2003-03-29 Paul Brook <paul@nowt.org>
+
+ * iresolve.c (g95_resolve_pack): Don't bother resolving based on type.
+ (g95_resolve_unpack): Ditto.
+ * trans-intrinsic.c (g95_conv_intrinsic_merge): New Function.
+ (g95_conv_intrinsic_function): Use it. Remove PACK and UNPACK.
+ (g95_is_intrinsic_libcall): Add PACK and UNPACK.
+
+2003-03-25 Paul Brook <paul@nowt.org>
+
+ * arith.c (g95_unary_user, g95_user): Remove dead functions.
+ * arith.h: Ditto.
+ * array.c (g95_free_array_ref): Ditto.
+ * g95.h: Ditto.
+ * symbol.c (g95_use_derived_tree): Ditto.
+ * intrinsic.c (add_functions): Use simplification for SCALE.
+ * primary.c (g95_match_rvalue): Test sym, not symtree.
+
+2003-03-25 Paul Brook <paul@nowt.org>
+
+ * trans-decl.c (build_function_decl): Add parameter before it gets
+ turned into a constant.
+ * iresolve.c (g95_resolve_eoshift): Resolve to a useful name.
+ * trans-intrinsic.c (g95_is_intrinsic_libcall): Add G95_ISYM_EOSHIFT.
+ * trans-decl.c (g95_create_module_variable): Don't pushdecl constants.
+
+2003-03-22 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (g95_conv_array_initializer): Allow scalar
+ expressions.
+ * trans-decl.c (g95_finish_var_decl): Result variables are not
+ module variables.
+ * trans-intrinsic.c (g95_conv_intrinsic_transfer): New function.
+ (g95_conv_intrinsic_function): Use it.
+ * trans-types.h (g95_type_spec): Remove dead declaration.
+
+2003-03-21 Paul Brook <paul@nowt.org>
+
+ * trans-decl.c (g95_build_function_decl): Mark string parameters.
+
+2003-03-20 Paul Brook <paul@nowt.org>
+
+ * trans-decl.c (g95_build_function_decl): Put character length
+ parameters at the end of the function declaration.
+ * trans-expr.c (g95_conv_function_call): Ditto.
+ * trans-types.c (g95_get_function_type): Ditto.
+
+2003-03-20 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+
+ * resolve.c (resolve_formal_arglist): Don't impose intent for
+ procedure arguments of pure functions.
+ (resolve_select): Remove redundant assignment.
+
+2003-03-19 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+
+ * arith.c (validate_logical), g95.h, options.c (g95_init_options):
+ Remove option l1.
+ * g95.h, intrinsic.c(g95_get_intrinsic_sub_symbol): Add const.
+ * iresolve.c(g95_resolve_cpu_time, g95_resolve_random_number): Add
+ const.
+ * lang-options.h: Remove -finline-repack-arrays. Add -fg77-calls.
+ Order list.
+ * symbol.c (g95_add_type): Fix typo in comment.
+
+
+2003-03-16 Paul Brook <paul@nowt.org>
+
+ * dump-parse-tree.c (g95_show_code_node): Print resolved sym name.
+ * expr.c (g95_build_call): Remove.
+ * f95-lang.c (puchdecl_top_level): New function.
+ * g95.h (g95_code): Store resolved symbol, not just the name.
+ * intrinsic.c (g95_intrinsic_namespace): New global namespace.
+ (g95_intirinsic_init_1, g95_intrinsic_done_1): Use it.
+ (g95_get_intrinsic_sub_symbol): New function.
+ * iresolve.c (g95_resolve_cpu_time): Use it.
+ (g95_resolve_random_number): Ditto.
+ * resolve.c: Set code->resolved_sym instead of code->sub_name.
+ * trans-decl.c (g95_get_extern_function_decl): Give external decls
+ the correct DECL_CONTEXT. Add global symbold to the global scope.
+ * trans-stmt.c (g95_trans_code): Remove hacks now the fronted is
+ fixed.
+
+2003-03-16 Paul Brook <paul@nowt.org>
+
+ * g95.h (g95_option_t): Add g77_calls. Remove inline_repack_arrays.
+ * options.c (g95_parse_arg): Ditto.
+ * module.c (mio_symbol_attribute): Handle the always_explicit bit.
+ * resolve.c (resolve_formal_arglist): The always_explicit sould be set
+ for the procedure, not the parameter.
+ * trans-array.c (g95_trans_g77_array): New function.
+ (g95_trans_assumed_size): Use it.
+ (g95_trans_dummy_array_bias): Ditto.
+ (g95_conv_array_parameter): Handle g77 arrays. Move existing body ...
+ (g95_conv_expr_descriptor): ... to here. Update callers.
+ * trans-decl.c (g95_build_dummy_array_decl): Handle g77 arrays.
+ (g95_get_symbol_decl): Avoid processing g77 arrays multiple times.
+ * trans-expr.c (g95_conv_function_call): Handle g77 arrays.
+ * trans-intrinsic.c (g95_get_symbol_for_expr): Never use g77 arrays.
+ * trans-types.c (g95_is_nodesc_array): Handle g77 arrays.
+ (g95_sym_type): Ditto.
+
+2003-03-15 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (g95_walk_elemental_function_args): Don't amputate the
+ first chain.
+ * trans-expr.c (g95_conv_function_call): Use the resolved symbol.
+
+2003-03-14 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (g95_array_is_packed): Remove.
+ (g95_conv_array_base): Correctly handle all descriptorless cases.
+ (g95_conv_array_stride): Use descriptorless strides.
+ (g95_trans_dummy_array_bias): Don't always repack the array.
+ (g95_build_dummy_array_decl): Automatic dummy arrays are only partial
+ packed.
+ * trans-types.c (g95_get_nodesc_array_type): Differentiate between
+ dummy and non-dummy arrays...
+ (g95_sym_type, g95_get_derived_type): ... like these.
+ (g95_get_array_type_bounds): Allow discontiguous arrays.
+
+2003-03-12 Paul Brook <paul@nowt.org>
+
+ * array.c (g95_resolve_array_spec): Fix comment.
+ * g95.h (symbol_attributes): New flag always_explicit.
+ * resolve.c (resolve_formal_arglist): Set it always_explicit.
+ * iresolve.c (g95_resolve_lbound, g95_resolve_ubound): Simplify.
+ * trans-array.c (g95_conv_descriptor_dimension): Remove dead assert.
+ (g95_trans_array_bounds): Allow assumed shape arrays.
+ (g95_trans_repack_array): Remove.
+ (g95_trans_dummy_array_bias): Rewite to use descriptorless arrays.
+ * trans-decl.c (g95_build_qualified_array): Only ignore absent
+ bounds for assumed size arrays.
+ (g95_build_dummy_array_decl): Use descriptorless arrays.
+ * trans-expr.c (g95_conv_expr_present): Allow descriptorless arrays.
+ (g95_trans_pointer_assign): Fix typo.
+ * trans-intrinsic.c (g95_conv_intrinsic_function_args): Remove dead
+ code.
+ (g95_conv_intrinsic_bound): Rewrite to handle descriptorless arrays.
+ * trans-types.c (g95_get_nodesc_array_type): Allow non-packed arrays.
+ Also modify callers.
+ * trans-types.h (g95_get_nodesc_array_type): Modify prototype.
+
+2003-03-08 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (g95_walk_elemental_functions): Don't reverse the SS.
+ (g95_conv_array_ubound): Provide dummy value for assumed size arrays.
+ * resolve.c (compare_spec_to_ref): Allow full array sections.
+
+2003-03-08 Paul Brook <paul@nowt.org>
+
+ * expr.c (g95_simplify_expr): Also simplify array index and
+ substring expressions.
+ * resolve.c (compare_spec_to_ref): Check for assumed size bounds.
+ * trans-array.c (g95_trans_array_bounds): New function.
+ (g95_trans_auto_array_allocation): Use it.
+ (g95_trans_assumed_size): Rewrite.
+ * trans-decl.c (gfor_fndecl_in_pack, gfor_fndecl_in_unpack): Declare.
+ (gfor_fndecl_repack): Remove.
+ (g95_build_qualified_array): Handle absent upper bounds.
+ (g95_build_dummy_array_decl): Assumed shape arrays are descriptorless.
+ (g95_get_symbol_decl): Update.
+ (g95_build_intrinsic_function_decls): Initialize new decls.
+ * trans.h (gfor_fndecl_in_pack, gfor_fndecl_in_unpack): Declare.
+ (gfor_fndecl_repack): Remove.
+ * trans-io.c (g95_build_io_library_fndecls): Correct prototypes.
+ * trans-types.c: (g95_build_array_type): Merge duplicated code..
+ (g95_get_nodesc_array_type): Handle absent bounds.
+ * trans-types.h (g95_get_nodesc_array_type): Declare.
+
+2003-03-04 Paul Brook <paul@nowt.org>
+
+ * f95-lang.c (DEF_FUNCTION_TYPE_VAR_3): Define before including
+ builtin-types.def.
+
+2003-03-02 Paul Brook <paul@nowt.org>
+
+ * options.c (g95_init_options): Drfault to 1.
+ (g95_pasrse_arg): Add -frepack-arrays, use strcmp.
+ * trans-array.c (g95_conv_array_data, g95_conv_array_base,
+ g95_conv_array_stride,g95_conv_array_lbound, g95_conv_array_ubound):
+ Handle non-constant size automatic arrays.
+ (g95_conv_section_upper_bound, g95_conv_section_startstride): Use
+ generic bound functions.
+ (g95_trans_auto_array_allocation): Don't create a descriptor.
+ (g95_trans_assumed_size): New function (broken).
+ (g95_trans_dummy_array_bias): Remove unused var.
+ * trans-array.h (g95_trans_assumed_size): Declare.
+ * trans-decl.c (create_index_var): New fuction.
+ (g95_build_qualified_array): New function.
+ (g95_get_symbol_decl): Use it.
+ (g95_trans_deferred_vars): Handle assumed shape seperately.
+ * trans-types.c (get_element_type): Handle heap allocated arrays.
+ (g95_is_nodesc_array): Include non-const size arrays.
+ (g95_get_nodesc_array_type): Ditto.
+
+2003-02-23 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (g95_array_init_size): Should use stride, not size of
+ last dimension.
+
+2003-02-18 Paul Brook <paul@nowt.org>
+
+ * trans-expr.c (g95_trans_arrayfunc_assign): Nove elemental check
+ after intrinsic function check.
+
+2003-02-18 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+
+ * io.c (match_io): Fix missing return value and remove useless
+ assignment.
+ * match.c (g95_match): Remove useless assignment.
+ * module.c (parse_string): Remove useless post increment.
+ * simplify.c (g95_simplify_verify): Remove useless assignment.
+
+2003-02-15 Paul Brook <paul@nowt.org>
+
+ * expr.c (restricted_intrinsic): Handle bad values gracefully.
+ * g95.h (symbol_attribute): Add referenced member.
+ (g95_symbol): Add dummy_order member.
+ (g95_set_sym_referenced): Declare.
+ * match.c (g95_match_assignment, g95_match_call): Use it
+ * primary.c (match_actual_arg, g95_match_rvalue,
+ g95_match_variable): Ditto.
+ * symbol.c (next_dummy_order): New variable.
+ (g95_set_sym_referenced): New function.
+ (check_done): New function.
+ (g95_add_*): Use it.
+ * trans-decl.c: Make formatting conform to GCC standards.
+ (g95_defer_symbol_init): Add dummy variables in the right order.
+ (g95_get_symbol_decl): Only accept referenced variables.
+ (g95_create_module_variable): Module variables are always required.
+ (generatr_local_decls): New function.
+ (generate_local_vars): New function.
+ (g95_generate_function_code): Use it.
+
+2003-02-13 Paul Brook <paul@nowt.org>
+
+ * trans-decl.c (g95_conv_struct_cons): Remove.
+ (g95_get_symbol_decl): Use g95_conv_expr for structure initializers.
+ * trans-expr.c (g95_conv_structure): New function.
+ (g95_conv_expr): Use it.
+
+2003-02-09 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (g95_array_init_size): Don't evaluate the linit
+ expressions multiple times.
+ (g95_trans_auto_arry_allocation): Use pointer not tmp.
+
+2003-02-08 Paul Brook <paul@nowt.org>
+
+ * module.c (mio_symtree_ref): Declare as static.
+ (mio_expr): Remove dead code.
+ (read_module): Set the symtree link for fixups.
+ * trans-intrinsic.c (g95_conv_intrinsic_round): Rename...
+ (build_round_expr): ... to this.
+ (g95_conv_intrinsic_aint): New function.
+ (g95_conv_intrinsic_function): Use it.
+
+2003-02-08 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (g95_trans_array_constructor_value): Use the acutal
+ offset after modificaton, not the increment expression.
+ * dependency.c: Kill excess whitespace.
+
+2003-02-07 Sanjiv Gupta <sanjivg@noida.hcltech.com>
+
+ * dependency.h: Remove some function declarations.
+ * dependency.c (get_no_of_elements): Change this function not to
+ return int.
+ * other: Add comments for all modified functions.
+
+2003-02-06 Paul Brook <paul@nowt.org>
+
+ * g95spec.c (lang_specific_functions): Fix initializer warning.
+ * dump-parse-tree.c (g95_show_expr): Use typespec instead of symtree
+ for structure type names.
+ * trans-decl.c (g95_cons_structure_cons): New function.
+ (g95_get_symbol_decl): Use it.
+ * trans-expr.c (g95_conv_component_ref): Remove duplicate pointer
+ referencing code.
+
+2003-02-06 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+
+ * resolve.c (compare_cases): Add const to casts.
+
+2003-01-30 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+
+ * g95.h (g95_check_f): Change a1 to f1m.
+ * intrinsic.c (add_sym_1m, check_specific,
+ g95_intrinsic_func_interface): Use it.
+
+ * module.c (init_pi_tree): Remove useless cast.
+ (fp2): Fix argument type.
+
+ * parse.c (parse_select_block): Add comment.
+
+2003-02-05 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * lang-options.h: Fix warning involving C90 concatenated
+ strings.
+
+2003-02-06 Steven Bosscher <s.bosscher@student.tudelft.nl>
+ Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+
+ * io.c (format_asterisk): Complete initializer to kill warning.
+ * arith.c (DEF_G95_INTEGER_KIND, DEF_G95_LOGICAL_KIND,
+ DEF_G95_REAL_KIND, MPZ_NULL, MPF_NULL): New #defines.
+ (g95_integer_kinds, g95_logical_kinds, g95_real_kinds): Use the
+ new defines to complete initializers. Kills all warnings.
+
+ * Make-lang.in: Comment cleanup.
+
+2003-02-05 Paul Brook <paul@nowt.org>
+
+ * array.c (g95_free_constructor): Handle NULL expressions.
+ * resolve.c (resolve_structure_cons): Ditto.
+ * decl.c (g95_match_null): New Function.
+ (variable_decl): Use it.
+ * module.c (mio_expr): Don't bother saving symtree for EXPR_STRUCTURE.
+ * primary.c (g95_match_runtime): Don't use symtree for EXPR_STRUCTURE.
+ * trans-types.c (g95_set_decl_attributes): Remove empty function.
+
+2003-02-05 Paul Brook <paul@nowt.org>
+
+ * trans.h (build1_v): New macro.
+ (build_v): Remove pointless and incorrect prototype.
+ * various: Use build1_v for GOTO_EXPR and LABEL_EXPRs.
+ * f95-lang.c (g95_init_builtin_decls): DEF_BUILTIN takes 10 args.
+
+2003-02-01 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * Make-lang.in (F95_OBJS): Remove one more dead file.
+
+2003-02-01 Paul Brook <paul@nowt.org>
+
+ * lang-specs.h: Don't pass -ffixed-form to the linker.
+ * trans-decl.c (g95_generate_function_code): Clear saved decl chain.
+
+2003-02-01 Paul Brook <paul@nowt.org>
+
+ * Make-lang.in (F95_OBJS): Remove dead files.
+ * trans-array.c (g95_array_init_size): Do the right thing when
+ ubound=NULL.
+ * trans-decl.c (g95_generate_function_code): Initialize deffered
+ symbol list before translating contained subroutines.
+ * trans-expr.c (g95_conv_expr, g95_conv_expr_reference): Substitute
+ scalar invariant values here...
+ (g95_conv_variable, g95_conv_function_call): ... instead of here ...
+ * trans-intrinsic.c (g95_conv_intrinsic_function_args): .. and here.
+
+2003-01-29 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (g95_add_loop_code): Put pre code in the right block.
+ (g95_walk_elemental_function_args): Reverse chains before adding.
+ (g95_reverse_ss): Move about a bit.
+ * trans-expr.c (g95_conv_function_call): Handle scalar intrinsic
+ function arguments.
+
+2003-01-28 Paul Brook <paul@nowt.org>
+
+ * intrinsic.c (resolve_intrinsic): Use correct union member.
+ * trans-array.c (g95_trans_dummy_array_bias): Don't touch absent
+ parameters.
+ * trans-decl.c (g95_get_symbol_decl): Don't translate initializers for
+ use associated variables.
+ * trans-intrinsic.c (g95_conv_intrinsic_present): Move body ...
+ * trans-expr.c (g95_conv_expr_present): ... to here.
+ * trans.h: Declare it.
+ * trans-types.c (g95_sym_type): Assume subroutine if not specified.
+
+2003-01-28 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+
+ * array.c (expand_iterator): Suppress useless assignment.
+ * decl.c (match_char_spec): Ditto.
+ * io.c (match_io_iterator): Ditto.
+ * primary.c (match_real_constant): Ditto.
+ * interface.c (fold_unary, g95_free_interface, g95_extend_expr):
+ Ditto. Also, use g95_intrinsic_op not int for intrinsic operators.
+ * matchexp.c (match_add_operand, match_level_5): Likewise.
+ * module.c (parse_atom, find_enum): Likewise.
+ * resolve.c: move #include <string.h>
+ (resolve_select): Fix serious typo.
+
+2003-01-28 Steven Bosscher <s.bosscher@student.tudelft.n>
+
+ * Make-lang.in: Don't build with broken tree-ssa-pre.
+
+2003-01-28 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * resolve.c (resolve_index): Add a TODO.
+ * symbol.c: Remove useless "#include <ctype.h>".
+
+2003-01-27 Paul Brook <paul@nowt.org>
+
+ * check.c (check_rest): Allow different type kinds as an extension.
+ * g95.h (g95_resolve_f): Add f1m.
+ * intrinsic.c (add_sym_1m, resolve_intrinsic): Use it.
+ * intrinsic.h: Chenge prototypes for MIN and MAX.
+ * iresolve.c (g95_resolve_minmax): New function.
+ (g95_resolve_min, g95_resolve_max): Use it.
+ * trans-intrinsic.c (g95_trans_intrinsic_minmax): Only evaluate
+ arguments once.
+ (g95_conv_intrinsic_present): Fix logic.
+
+2003-01-27 Steven Bossche <s.bosscher@student.tudelft.nl>
+
+ * g95.h (g95_case): Don't be a tree, be a double linked list.
+ * match.c (match_case_selector): Remove redundant semantics check.
+ Clean up a few goto's to make it a tiny little bit faster.
+ * resolve.c (case_tree): Die.
+ (compare_cases): Accept and compare unbounded cases too.
+ (check_case_overlap): Don't build a tree. Instead, merge-sort the
+ whole list of g95_cases passed from resolve_select.
+ (sane_logical_select): Die.
+ (check_case_expr): Return FAILURE if a CASE label is of the wrong
+ type kind.
+ (resolve_select): Fixup case expression for computed GOTOs, put it
+ in expr, not expr2, for easier handing in the parse tree dumper and
+ the code generator. Rewrite the rest of the function: Kill
+ unreachable case labels and unreachable case blocks.
+ * dump-parse-tree.c (g95_show_code_node): Always dump expr for
+ an EXEC_SELECT, not case2 anymore.
+ * trans-const.c (g95_conv_constant_to_tree): New function.
+ (g95_conv_constant): Use it.
+ * trans-const.h: Declare prototype for the new function.
+ * trans-stmt.c (g95_trans_integer_select, g95_trans_logical_select,
+ g95_trans_character_select): New static functions.
+ (g95_trans_select): Rewrite.
+
+2003-01-26 Paul Brook <paul@nowt.org>
+
+ * intrinsic.c (add_fnctions): Properly add dreal.
+ * trans-intrinsic.c (g95_conv_intrinsic_present): New function.
+ (g95_conv_intrinsic_function): Use it.
+ * trans-io.c (build_dt): Abort on internal files (unimplemented).
+
+2003-01-26 Paul Brook <paul@nowt.org>
+
+ Widespread changes to the handling of symbols in expressions. These
+ are now linked via g95_symtree nodes.
+ * parse.c (g95_fixup_sibling symbols): New function.
+ (parse_contained): Use it.
+ * g95.h (symbol_attribute): Add contained. Indicates a symbol is a
+ contained procedure that has bee correctly fixed up.
+ (g95_code, g95_expr): Point to a g95_symtree, not a g95_symbol.
+
+2003-01-24 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (g95_walk_expr): Function result attributes are in
+ sym->result.
+ * trans-expr.c (g95_conv_function_call,
+ g95_trans_arrayfunc_assign): Ditto.
+ * trans-decl.c (g95_get_symbol_for_expr): Set sym->result.
+
+2003-01-23 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * expr.c (check_restricted): Fix error message.
+ * symbol.c (free_st_labels): Plug memleak.
+
+2003-01-22 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * arith.c (reduce_unary, reduce_binary_ac, reduce_binary_ca,
+ reduce_binary_aa, reduce_binary, eval_intrinsic,
+ eval_intrinsic_f2): Use typesafe prototypes for eval functions.
+ * g95.h (g95_check_f, g95_simplify_f, g95_resolve_f): New unions
+ for typesafe intrinsics helper functions.
+ (g95_intrinsic_sym): Use them.
+ * intrinsic.c (do_check, add_sym, add_sym_0, add_sym_1,
+ add_sym_1s, add_sym_1m, add_sym_2, add_sym_3, add_sym_4,
+ add_sym_5, add_conv, resolve_intrinsic, do_simplify,
+ check_specific, g95_intrinsic_func_interface,
+ g95_intrinsic_sub_interface): Adjust all calls to intrinsics
+ helper functions.
+ * trans-decl.c (g95_get_extern_function_decl): Likewise.
+ * Make-lang.in: Don't disable warnings for strict prototypes
+ any longer, everything is typesafe now.
+
+2003-01-22 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * bbt.c (duplicate_node): Make static.
+ * module.c (module_name): Make static.
+ * scanner.c (include_dirs): Make static.
+
+2003-01-20 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ Hard coded _gfor_'s should not show up anymore.
+ * g95.h (PREFIX): New macro.
+ * iresolve.c (g95_resolve_cpu_time): Use PREFIX, not
+ hard-coded "_gfor".
+ (g95_resolve_random_number): Likewise.
+ * trans-decl.c (g95_build_intrinsic_function_decls): Likewise.
+ * trans-io.c: Remove 'prefix' macro. Replace all uses with
+ the new PREFIX macro from g95.h.
+
+2003-01-20 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ The troubles of forking... Andy implemented this just now too.
+ Let's stick to that and keep the trees close.
+ * g95.h (g95_st_label): 'format' member is now a g95_expr.
+ * io.c: Revert previous changes.
+ (g95_match_format): Match the format string as a character
+ literal expression.
+ * match.h (g95_statement_label): Declare external.
+ * parse.c: Revert previous changes.
+ * symbol.c (g95_free_st_label): Free a g95_expr instead
+ if a 'char *'.
+ * trans-io.c: Revert previous changes.
+ (build_dt): Use set_string to set the format string.
+
+2003-01-20 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * io.c (format_string): Make non-static.
+ (g95_match_format): Remember the format string.
+ (terminate_io): Add I/O termination for empty I/O lists.
+ * match.h: Declare external format_string.
+ * parse.c (check_statement_label): Attack the format string
+ to a format label for FORMAT statements.
+ * trans-io.c (g95_add_field): Define prefix macro. Replace
+ all uses of PREFIX define with a use of this macro.
+ (build_dt): Implement formatted I/O for format labels.
+
+2003-01-20 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * lang-options.h: Kill "-std=F".
+ * options.c: Remove unimplemented "-std=F". Modify
+ web address.
+ * misc.c (g95_terminal_width): New function.
+ * error.c (g95_error_init_1): Use g95_terminal_width.
+ * g95.h: Add prototype for g95_terminal_width, remove
+ fmode flag.
+
+2003-01-19 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * Make-lang.in: Fix typo.
+
+2003-01-18 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * g95.h (struct g95_case): Remove unused cruft, new member
+ 'where' to keep track of the locus of the default case.
+ * match.c (g95_match_case): Add locus to the current case.
+ (match_case_selector): Likewise.
+ * parse.c (parse_select_block): Move semantics check for
+ multiple DEFAULT cases out of here to...
+ * resolve.c (check_case_overlap): ...here. Return sooner
+ when possible.
+ (check_case_expr): Take two g95_cases now, use to sure the
+ expression kinds are the same.
+ (resolve_select): Cleanup.
+
+2003-01-18 Paul Brook <paul@nowt.org>
+
+ * trans-io.c: Fix typos in ported IO work (set_fla[tg]).
+ * trans-decl.c (g95_set_symbol_decl): Handle non-array result
+ variables.
+ (g95_get_extern_function_decl): Put decls in the correct context.
+
+2003-01-18 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * trans-io.c: Port changes from Andy to set ERR flag.
+
+2003-01-17 Paul Brook <paul@nowt.org>
+
+ * trans-array.c: Add various comments.
+ (g95_ss_terminator): Declare as const.
+ (g95_walk_expr): Remove first parameter and update all callers.
+ (g95_walk_op_expr): Initialize scalar SS properly.
+ * trans-array.h (g95_walk_expr): Update prototype.
+ * trans-expr.c: Update for new g95_walk_expr.
+ * trans-intrinsic.c: Ditto.
+ * trans-io.c: Ditto.
+ * trans.h: Various comments for SS chains.
+
+2003-01-17 Paul Brook <paul@nowt.org>
+
+ * intrinsic.h (g95_generic_isym_id): Add G95_ISYM_S?_KIND, SPACING
+ and RRSPACING.
+ * intrinsic.c (add_functions): Use them.
+ * trans-intrinsic.c (g95_conv_intrinsic_function): Ditto.
+ * trans-expr.c (g95_conv_expr_lhs): Abort on impossible error.
+
+2003-01-17 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ Fallout of a small merge conflict:
+ * intrinsic.c: Un-revert lost patch (G95_ISYM_SCALE).
+
+2003-01-17 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * initrinsic.c: New add_sym_* functions for strong typing.
+ (add_conv): Make prototype strict.
+ * dump-parse-tree.c, dependency.c: Include config.h
+ * resolve.c, trans-io.c: Fix typos.
+
+2003-01-17 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * dump-parse-tree.c (g95_show_code_node): Show the
+ condition for a computed GOTO that was transformed
+ to a SELECT CASE construct.
+ * resolve.c (check_case_overlap): Revert previous switch
+ to treaps, it was too slow and didn't catch all trouble.
+ (resolve_symbol): Be more flexible about module procedures.
+ * symbol.c (check_conflict): Point to relevant section in
+ the standard for dubious conflict. Allow procedure
+ dummy arguments to be optional again.
+ * trans-io (add_field): Rename to g95_add_field. Change
+ all callers.
+ * trans-stmt (trans_select): Handle unbounded cases for
+ integer SELECT CASE constructs. Fix/add more comment.
+
+2003-01-17 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * g95.h: Uses GCC's function attribute macros.
+ * error.c, module.c, parse.c, g95.h: More function attributes.
+
+2003-01-16 Steven Bosscher <s.bosscher@student.tudelft.nl>
+ Forgot a file...
+ * trans-decl.c (get_label_decl): Use TREE_LINENO instead
+ of DECL_SOURCE_LINE, and TREE_FILENAME instead of
+ DECL_SOURCE_FILE.
+
+2003-01-16 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * f95-lang.c (pushdecl): Use TREE_LINENO instead of
+ DECL_SOURCE_LINE.
+ * trans.c (g95_trans_code): Use annotate_all_with_file_line
+ instead of nowdead wrap_all_with_wfl.
+
+2003-01-14 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * parse.c (g95_parse_file): In verbose mode, dump the parse tree
+ before generating code, so we can still see it even if the code
+ generation phase dies.
+
+2003-01-14 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * decl.c (build_sym): Split out initialization expression parts...
+ (add_init_expr_to_sym): ...to here.
+ (variable_decl): Add the symbol following an attribute list to the
+ symbol tree before parsing the optional initialization expression
+ if the symbol is not of a derived type.
+ * primary.c (g95_match_rvalue): Don't assume a symbol always has
+ a value if it is a PARAMETER.
+
+2003-01-14 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * misc.c: Don't #include <mcheck.h>
+ * module.c: Ditto. Kill uses of mtrace, muntrace. If there
+ ever was a glibc bug, then either this was never reported to
+ glibc people, or it has been fixed for so long that there's
+ no information you can find about it, anywhere.
+
+2003-01-14 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ Fix warnings:
+ * module.c (attr_bits, bt_types, array_spec_types):
+ Switch 'const' and 'static'.
+ * iresolve.c (g95_resolve_reshape): Make __resolve0 non-'const'.
+
+ GNU'ify source code:
+ * trans-io.c: Numerous fixes, one fixed warning and a few
+ TODO markers so that we don't forget about them.
+
+2003-01-13 Paul Brook <paul@nowt.org>
+
+ * intrinsic.c (add_functions): Add G95_ISYM_SCALE.
+ * intrinsic.h (g95_generic_isym_id): Remove bogus G95_ISYM_ANINIT.
+ Add G95_ISYM_SCALE.
+ * trans-intrinsic.c (g95_conv_intrinsic_function): Ditto
+ * match.c (g95_match_stop): Fix dumb == -> != error.
+
+2003-01-13 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * dump-parse-tree.c (show_indent): Add line breaks. This
+ whole dumping process needs cleanups.
+ * f95-lang.c (g95_mark_addressable): Fix prototype to match
+ the langhook. Fix 'return's accordingly.
+ * g95-support.h: Adjust prototype.
+ * g95.h: Add 'no_backend' member to 'g95_option_t' struct.
+ * lang-options.h: Add '-fsyntax-only'.
+ * options.c (g95_init_options): Init 'no_backend'.
+ (g95_parse_arg): Deal with '-fsyntax-only'.
+ * parse.c (g95_parse_file): Do not generate code if 'no_backend'
+ is set.
+
+2003-01-13 Steven Bosscher <s.bosscher@student.tudelft.nl>
+ Patch from Arnaud
+ * resolve.c (resolve_symbol): Assumed shape arrays must be dummy
+ arguments. Also make sure that if a symbol is marked INTRINSIC,
+ an intrinsic with the symbol's name actually exists.
+ (check_conflict): Make EXTERNAL and DIMENSION attributes conflict.
+ Do not allow PROCEDURES to have the SAVE, POINTER, TARGET,
+ ALLOCATABLE, RESULT, IN_NAMESPACE, OPTIONAL or FUNCTION attribute.
+
+2003-01-13 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * resolve.c (resolve_contained_functions): Fix condition, don't
+ throw internal_error if a child namespace has no name. Apparently
+ this can be the case?
+
+2003-01-11 Paul Brook <paul@nowt.org>
+
+ Port changes from Andy's tree:
+ * g95.h (g95_code): Add stop_code.
+ * match.c (g95_match_stop): Detter syntax checking.
+ * resolve.c (resolve_generic_f0): Return match type.
+ (resolve_generic_f): Remove dead/duplicated code.
+ (resolve_specific_f): Ditto.
+ * dump-parse-tree.c (g95_show_code_node): Handle new STOP format.
+ * trans-decl.c (gfor_fndel_stop_*): New fndecl nodes.
+ * trans-stmt.c (g95_trans_stop): Handle new STOP format.
+
+2003-01-11 Paul Brook <paul@nowt.org>
+
+ * trans-array.c: Various documentation/comment changes.
+ * trans-stmt.c: Ditto.
+
+
+2003-01-10 Paul Brook <paul@nowt.org>
+
+ * options.c/h: Add -fdump-parse-tree as alias of -v.
+
+2003-01-10 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * dump-parse-tree.c (g95_show_namespace): Fixed another
+ typo. Sorry, it's Friday...
+
+2003-01-10 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ Spotted by Tobi:
+ * trans-array.c, trans-array.h, trans.c, trans-const.c,
+ trans-const.h, trans-decl.c, trans-expr.c, trans.h
+ trans-intrinsic.c, trans-io.c, trans-stmt.c, trans-stmt.h
+ trans-types.c: Fix bogus copyright years, add 2003.
+ * trans-types.h: Give copyright header.
+
+2003-01-10 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * dump-parse-tree.c (g95_show_namespace): Fixed typo.
+ * expr.c, options.c, scanner.c: Add some more 'const' markers.
+ * intrinsic.c: Some constant strings moved to read-only memory.
+ * io.c (format_asterisk): Move to...
+ * g95.h: ...here.
+
+2003-01-10 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * dump-parse-tree.c (g95_show_namespace): Dump implicit
+ types for ranges instead of per-letter. Indent the
+ 'CONTAINS' just like everything else.
+ * resolve.c (resolve_contained_functions): Clarify comment.
+ Explain non-obvious conditional expression. Improve
+ diagnostics if tyoe cannot be resolved.
+ Port semi-fix from Andy's tree:
+ (was_declared): Move up before first use.
+ (generic_sym, specific_sym): New functions. Code moved
+ out if procedure_kind.
+ (procedure_kind): Simplify using new functions.
+ (resolve_generic_f): Make sure the functions we find in
+ a parent namespace is generic.
+ (resolve_specific_f): Ditto for specific functions.
+
+2003-01-10 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * trans-stmt.c, trans.c: Fix some code style issues. Add
+ some more comment (but still not enough!).
+
+2003-01-10 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * symbol.c (flavors, procedures, intents, acces_types,
+ access_types, ifsrc_types): Make const.
+ * misc.c (g95_string2code): Make 'm' param 'const'.
+ * module.c (find_enum, write_atom, mio_name): Make
+ 'm' param 'const'.
+ (attr_bits, bt_types, array_spec_types, array_ref_types,
+ ref_types, expr_types): Make const.
+ * g95.h: Adjust external decls.
+
+2003-01-09 Paul Brook <paul@nowt.org>
+
+ * Testsuite: Add a load of new cases.
+
+2003-01-08 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * Make-file.in: Add dependency on back end header files;
+ a parallel build should work now.
+ * f95-lang-c (lang_identifier): Remove bogus comment.
+ (g95_be_parse_file): Fix prototype.
+ (g95_init): Make static.
+ (g95_finish): Make static.
+ * error.c (g95_syntax_error): Kill. Make define in...
+ * g95.h (g95_syntax_error): Define.
+ (g95.options): Make 'source' member 'const'.
+ * interface.c (g95_match_interface): Explain
+ hard-to-read condition.
+ (g95_match_end_interface): Ditto.
+ * trans_const.c (g95_build_string_const): Make 's' parameter
+ 'const'.
+ * trans_const.h: Adjust protoype accordingly.
+ * trans-decl.c: Include tree-dump.h
+ (g95_generate_function_code): Build fixes for recent changes
+ in the tree-ssa branch.
+
+2003-01-08 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * format.c: Kill, move code from here...
+ * io.c: ...to here.
+ * Make-lang.in: Adjust.
+ * MANIFEST: Ditto.
+ * match.h: Ditto.
+ * BUGS: Mention where to submit bugs. Move old content...
+ * TODO: ...to here. New file.
+
+2003-01-08 Steven Bosscher <s.bosscher@student.tudelft.nl>
+ Fix most warnings, and suppress the ones we can't fix for now.
+ * Make-lang.in: Suppress warnings about bad proto's in g95.h,
+ these warnings just clutter the screen and there's not much
+ we can do about them for now anyway.
+ * check.c, iresolve.c: Mark unused function parameters.
+ * dump-parse-tree.c (g95_show_array_spec): Punt on AS_UNKNOWN,
+ they should be resolved before they get here.
+ * error.c: Remove unused FILE *status_out.
+ * f95-lang.c (g95_init): Remove bogus cast.
+ * Many files: Make things 'const' where required.
+ * g95.h: Fix prototypes for all modified functions above.
+ (g95_options): Remove 'object' member.
+
+2003-01-07 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * Make-file.in: Cleanup bogus targets. Add more comment.
+ * lang-options.h: New option '-w'.
+ * g95.h: add no_options field to struct g95_options.
+ * options.c (g95_init_options): Default no_warnings to off.
+ (g95_parse_arg): Recognise the '-w' switch and its alias,
+ '-fno-warnings'.
+ * error.c (g95_warning, g95_warning_now): Don't emit warning if
+ no_warning option is set.
+ * iresolve.c (g95_resolve_shape): Fix warning.
+
+2003-01-07 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * primary.c (g95_next_string_char): Rename next_string_char, and
+ make static. Adjust callers accordingly.
+ * resolve.c (resolve_generic_f0): Return try, not match. Adjust
+ callers accordingly.
+ * g95.h: Split out all g95_match* functions to...
+ * match.h: ...here. New file.
+ * array.c, decl.c, expr.c, format.c, interface.c, io.c, match.c,
+ matchexp.c, module.c, parse.c, primary.c: Inlcude match.h
+
+2003-01-07 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * symbol.c (g95_clear_new_implicit, g95_add_new_implicit_range,
+ g95_merge_new_implicit): New functions.
+ (g95_match_implicit_none, g95_match_implicit): Move from here...
+ * match.c (g95_match_implicit_none, g95_match_implicit): ... to here.
+ Modify to use the new functions in symbol.c.
+ * g95.h: Add and move prototypes.
+
+2003-01-06 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * bbt.c (insert): Use a typedef'ed compare_fn prototype for the
+ node compare function.
+ (g95_insert_bbt): Likewise.
+ (g95_insert_bbt_with_overlap): Likewise.
+ (g95_delete_bbt): Likewise.
+ (delete_treap): Likewise. Also fix a potential bug when calling it.
+ * module.c (compare_pointers): Change proto to compare_fn.
+ (compare_integers): Likewise.
+ (compare_true_names): Likewise.
+ (find_true_name): Adjust call to compare_true_names to match proto.
+ (require_atom, write_atom, mio_name): Fix 'const' warnings.
+ (init_pi_tree): Make compare a compare_fn instead of (int *).
+ * resolve.c (compare_cases): Change proto to compare_fn.
+ * symbol.c (g95_compare_symtree): Change proto to compare_fn, make
+ it static, and rename to compare_symtree.
+ (delete_symtree, g95_undo_symbols, g95_new_symtree): Use renamed
+ function.
+ * g95.h: Kill g95_compare_symtree prototype. Adjust prototypes
+ of g95_insert_bbt, g95_insert_bbt_with_overlap, and g95_delete_bbt.
+
+2003-01-06 Steven Bosscher <s.bosscher@student.tudelft.nl>
+ * Make-lang.in: Fix spaces/tabs issues from previous patch.
+ * patch.options: Blow away Paul's checkin mistake :-)
+ * io.c (terminate_io): Fix memory leak (Arnaud).
+
+2003-01-06 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * Make-lang.in: Teach about building DVI, info manual.
+ * g95.texi: New file.
+
+2003-01-02 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (g95_reverse_ss): Make static and don't use.
+ (g95_conv_ss_descriptor): Don't use g95_loopinfo
+ (g95_conv_array_parameters): Modify for pointer assignments.
+ (g95_walk_subexpr): New function.
+ (g95_walk_expr*): Use it.
+ * trans-array.h (g95_reverse_ss): Remove prototype.
+ * trans-expr.c (g95_trans_pointer_assign): Implement.
+ (Many): Set se.want_pointer before calling g95_conv_array_parameter.
+ * trans-intrinsic.c: Sync with scalarizer changes.
+ * trans-io.c: Ditto.
+
+2002-12-29 Paul Brook <paul@nowt.org>
+
+ * trans-array.c: Document calling convention for arrays.
+
+2002-12-19 Paul Brook <paul@nowt.org>
+
+ * trans-intrinsic.c (g95_conv_intrsinsic_function): Remove incorrect
+ assertion. Remove intrinsic subroutine G95_ISYM_* cases. Always pass
+ optional parameters for some intrinsics.
+ (g95_is_intrinsic_libcall): Add G95_ISYM_RESHAPE.
+ * trans-expr.c (g95_conv_function_call): Pass NULL for absent
+ optional parameters.
+ * trans.h (g95_se): Add ignore_optional flag.
+
+2002-12-15 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (g95_conv_array_parameter): Fix partial rank sections.
+ * trans-decl.c (g95_generate_function_code): Use TDI_original.
+
+2002-12-14 Paul Brook <paul@nowt.org>
+
+ * trans-stmt.c (g95_trans_call): Use resolved symbol name.
+
+2002-12-12 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (g95_trans_array_constructor_subarray): Fully
+ initialize the scalarizer.
+ (various): Update to new format of g95_expr->value.constructor.
+
+2002-12-08 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (g95_put_offset_into_var): New function.
+ (g95_trans_array_constructor_subarray): New function.
+ (g95_trans_array_constructor_value): Use it.
+ (g95_array_cons_size): Don't abort() on array components.
+
+2002-12-08 Paul Brook <paul@nowt.org>
+
+ * Make-lang.in (F95_ADDITIONAL_OBJS): Remove tree-dchain.o.
+ * support.c: Update #includes.
+ (statement_code_p, c_size_in_bytes, s_size_type_node): Remove.
+ * trans-array.c: Update #includes.
+ * trans.c: Ditto.
+ * trans-const.c: Ditto.
+ * trans-io.c: Ditto.
+ * trans-types.c: Ditto.
+ (g95_init_types): Set size_type_node.
+ * trans-decl.c: Update #includes.
+ (gfor_fndecl_adjust{l,r}): Declare and initialize.
+ * trans-stmt.c: Update #includes.
+ (g95_trans_do_while): Generate LABEL_EXPR, not GOTO_EXPR.
+ (g95_trans_select): Fix check for unbounded ranges.
+ * trans-expr.c: Update #includes.
+ (g95_conv_string_tmp): New function.
+ (g95_conv_concat_op): Use it.
+ * trans.h (g95_conv_string_tmp, gfor_fndecl_adjust{l,r}): Declare.
+ * Trans-intrisic.c: Update #includes.
+ (g95_conv_intrinsic_strcmp): New function.
+ (g95_conv_intrinsic_adjust): Ditto.
+ (g95_conv_intrinsic_function: Use them.
+
+2002-11-30 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (g95_walk_function_expr): Handle non-array return by
+ reference.
+ * trans-dec.c (g95_build_function_decl): Handle character return
+ parammeters.
+ (g95_get_fake_result_decl): Ditto.
+ (g95_trans_deferred_vars): Ditto.
+ * trans-expr.c (g95_conv_function_call): Ditto.
+ (g95_trans_arrayfunc_assign) Limit to array valued functions.
+ * trans-intrinsic.c (g95_conv_intrinsic_char): New function.
+ (g95_conv_intrinsic_function): Use it.
+ * trans-types.c (g95_sym_type): Handle functions returning strings.
+ (g95_return_by_reference): Ditto.
+ (g95_get_function_type): Ditto.
+
+2002-11-18 Paul Brook <paul@nowt.org>
+
+ * trans-stmt.c (g95_trans_if): Fix IF statements when the condition
+ requires a temporary.
+ (g95_trans_select): Handle computed gotos.
+ * trans-types.c (g95_build_array_type): Warn about non-functional
+ assumed shape arrays.
+ * trans-expr.c (g95_trans_scalar_assign): Correctly handle post
+ blocks.
+ * trans-intrinsic.c (g95_conv_intrinsic_round): New function.
+ (g95_conv_intrinsic_int): New function.
+ (g95_conv_intrinsic_mod): New function.
+ (g95_conv_intrinsic_ichar): New function.
+ (g95_conv_intrinsic_function): Use them.
+ (g95_conv_intrinsic_dim): Use g95_evaluate_now.
+
+2002-11-17 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * trans-types.c (g95_build_array_type): Assumed
+ sized arrays can have rank > 1.
+ * trans.c (g95_trans_code): Remove erroneous
+ warning about CONTINUE.
+ * trans-expr.c (g95_conv_variable): Remove
+ erroneous assert.
+
+2002-11-15 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (g95_conv_array_parameter): Check for NULL stride.
+
+2002-10-31 Paul Brook <paul@nowt.org>
+
+ * f95-tree.c: Remove tree copying stuff that's now in gimple.c
+ * trans-expr.c (g95_conv_component_ref): Handle character string
+ components.
+ (g95_conv_string_parameter): Ditto.
+ * trans-types.c (g95_get_derived_type): Add length decl to caracter
+ string components.
+
+2002-10-10 Paul Brook <paul@nowt.org>
+
+ * trans-decl.c (gfor_fndecl_size?): Declare and initialize.
+ * trans-expr.c (g95_conv_function_call): Remove unreliable return value
+ check.
+ * trans-intrinsic.c (g95_conv_intrinsic_size): New function.
+ (g95_conv_intrinsic_function): Handle size and shape intrinsics.
+ (g95_is_intrinsic_libcall): Add G95_ISYM_SHAPE.
+ * trans-types.c (pvoid_type_node): Declare and initialize.
+ * trans-array.c: Fix typo COMPONENT_REF->REF_COMPONENT
+ (g95_array_allocate): Fix when base==data.
+ (g95_conv_array_parameter): Correctly handle reduced rank sections.
+ * trans-io.c (g95_trans_write): Correctly handle string modifiers.
+
+2002-10-09 Paul Brook <paul@nowt.org>
+
+ * (g95_conv_expr_reference): Handle character strings correctly.
+
+2002-10-07 Paul Brook <paul@nowt.org>
+
+ (g95_expand_decl): Rename from f95_expand_decl_stmt and use as
+ langhook.
+ * trans-array.c (g95_build_array_initializer): Remove.
+ (g95_conv_array_initializer): New Function.
+ (g95_trans_auto_arry_allocation): Cleanup.
+ (g95_trans_init_character_array): Remove.
+ * g95spec.c: Link in libgforbegin.
+ * trans.c (g95_generate_code): Rename main function to MAIN__.
+ (g95_create_var): New function.
+ (g95_create_var_np): New function.
+ (g95_evaluate_now): New function.
+ (g95_start_block): New function.
+ (g95_finish_block): New function.
+ (g95_add_expr_to_block): New function.
+ (g95_add_block_to_block): New function.
+ * trans-expr.c (g95_conv_componen_ref): New function.
+ * Make-lang.in (F95_ADDITIONAL_OBJS): Add gimplify.o.
+ (F95_OBJS): Add dependency.o.
+ * f95-lang.c (g95_is_simple_stmt): Remove.
+ * f95-tree.c (mark_not_simple): New function.
+ (unshare_all_trees): New function.
+ (create_tmp_var, create_tmp_alias_var): Remove.
+ * support.c (declare_tmp_vars, tree_last_decl): Remove.
+ * trans*: Convert to new IR using GENERIC trees. Don't bother about
+ SIMPLE/GIMPLE rules, this is now done by Lang-independant code.
+
+2002-10-01 Paul Brook <paul@nowt.org>
+
+ * trans-array.c: Add support for descriptorless arrays.
+ (g95_conv_array_data): New function.
+ (g95_conv_array_base): New function.
+ * trans-array.h: Declare these here.
+ * trans-decl.c(g95_create_mopdule_variable): Perform variable
+ initialization and creation here.
+ (g95_create_module_vars): Instead of here.
+ * trans.h (G95_TYPE_ARRAY_*: Rename from G95_TYPE_DESCRIPTOR_*.
+ * trans-intrinsic.c: Ditto.
+ * trans-types.c (g95_is_nodesc_array): New function.
+ (g95_get_nodesc_array_type): New function.
+ (g95_sym_type, g95_get_derived_type): Use them.
+ * trans-const.c (g95_conv_mpf_to_tree): Remove workaround.
+
+2002-09-28 Paul Brook <paul@nowt.org>
+
+ * trans-const.c (g95_conv_mpf_to_tree): Work around backend bug.
+ * trans-intrinsic.c (g95_conv_intrinsic_abs): Correctly detect complex
+ parameters.
+
+2002-09-24 Paul Brook <paul@nowt.org>
+
+ * f95-lang.c (listify): Remove declaration.
+ (expand_function_body): Use optimize >=1 instead of flag_tree_saa.
+ (listify)
+ * f95-tree.c (get_name): New function.
+ * trans.c (module_namespace): Remove.
+ * trans-decl.c: Use g95_chainon_list rather than chainon(listify()).
+ * trans-types.c: Ditto.
+
+2002-09-19 Paul Brook <paul@nowt.org>
+
+ * trans-array.c (g95_get_array_cons_size): New Function.
+ (g95_con_ss_startstride): Handle Array constructors.
+ (g95_conv_loop_setup): Ditto.
+ (g95_conv_array_parameter): Ditto.
+ * tras-decl.c (g95_finish_var_decl): Make initializes variables
+ static.
+
+2002-09-19 Paul Brook <paul@nowt.org>
+
+ * trans.c (g95_simple_fold_tmp): Detect variables inside
+ NON_LVALUE_EXPR.
+ * trans-stmt.c (g95_trans_arithmetic_if): Implement this.
+
+2002-09-18 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * Make-lang.in (F95_ADDITIONAL_OBJS): Add tree-ssa-dce.o
+
+2002-09-14 Paul Brook <paul@nowt.org>
+
+ * trans.c (g95_create_module_variable): Move to trans-decl.c.
+ * trans-const.c (g95_conv_string_init): New Function.
+ * trans-const.h: Declare it.
+ * trans-decl.c (g95_get_symbol_decl): Handle initializers for static
+ variables. Don't bail on intrinsic symbols.
+ (get_extern_function_decl): Handle specific intrinsic functions.
+ * trans-types.c (g95_sym_type): Dummy functions don't return
+ reference types.
+ * trans-array.c (g95_build_array_initializer): New Function.
+ (g95_trans_auto_array_allocation): Build initializer for static decls.
+ Don't use mpz_addmul, it's GMP4 only.
+
+2002-09-12 Paul Brook <paul@nowt.org>
+
+ * trans-decl.c (g95_generate_code): Fix thinko with return variable.
+ (g95_get_extern_function_decl, g95_build_function_decl): Mangle
+ assembler names for module procedures.
+
+2002-09-11 Tobias Schlueter <Tobias.Schlueter@physik.uni-muenchen.de>
+
+ * trans-array.c,h trans-expr.c, trans-stmt.c: Correct spelling of
+ dependency/
+
+2002-09-10 Paul Brook <paul@nowt.org>
+
+ * trans-array.c: Change format of G95_SS_TEMP strictures.
+ (g95_check_fncall_dependancy): New function.
+ (trans_dummy_array_bias): stride[n], not stride[n-1]. for calculating
+ offsets.
+ * trans-decl.c (g95_get_symbol_decl): move assertion after handling of
+ result variables.
+ (g95_build_function_decl): Don't assume result arrays are packed.
+ (g95_trans-deferred-vars): Handle array result variables.
+ (g95_generate_fuction_code): Clear saved_function_decls.
+ * trans-expr.c (g95_conv_fnction_call): Handle direct array return by
+ reference.
+ (g95_trans_arrayfunc_assign): New function.
+ (g95_trans_assignment): Use it.
+ * trans.h (g95_ss): Add temp struct for G95_SS_TEMP.
+ (g95_se): Add direct_byref.
+ * trans-types.c: Use sym->result rather than sym where appropriate.
+ * trans-intrinsic.c (g95_conv_intrinsic_funcall): New function.
+ Update other functions to use this.
+ (g95_is_intrinsic_libcall): New function.
+ (g95_conv_intrinsic_function): Add MATMUL and PRODUCT intrinsics.
+ (g95_walk_intrinsic_function): Ditto.
+
+2002-09-08 Paul Brook <paul@nowt.org>
+
+ * trans-types.c: Change rank field to dtype field in array descriptor.
+ * trans-array.c: Implement filling of dtype array descriptor field.
+ * trans-intrinsic.c: Fix broken LEN intrinsic.
+
+2002-09-07 Paul Brook <paul@nowt.org>
+
+ * trans-intrinsic.c: Remove outdated todo intrinsic list.
+ (g95_get_symbol_for_expr): Remove hack for fortran based intrinsics.
+ (g95_walk_intrinsic_function): Add MINLOC and MAXLOC.
+
+2002-09-06 Paul Brook <paul@nowt.org>
+
+ * Make-lang.in (F95_ADDITIONAL_OBJS): Add tree_alias_comon.o.
+ (gt-f95-trans-types.h): Add dependancy information.
+ * config-lang.in (gtfiles): Add trans-types.c
+ * f95-lang.c (g95_be_parse_file): Pass error and warning counts
+ back to top-level code.
+ * trans-array.c, trans-types.c: Change format of array descriptor.
+ (g95_conv_descriptor_dimension): New function.
+ * trans-types.h (g95_conv_descriptor_rank): define.
+ * trans-intrinsic.c: Implement PRODUCT, COUNT. MINLOC and MAXLOC
+ intrinsics.
+
+2002-09-02 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * trans-array.c, trans-types.c: Add rank information to descriptor.
+
+2002-09-06 Tobias Schlueter <Tobias.Schlueter@physik.uni-muenchen.de>
+
+ * trans-stmt.c (g95_trans_allocate): Fix when ref==NULL.
+
+2002-09-04 Paul Brook <paul@nowt.org>
+
+ * f95-lang.c (g95_create_decls): New function.
+ (g95_init): Move initialization of external decls to above, and call
+ from g95_be_parse_file.
+ * trans.c (g95_finish_stmt): Don't amputate the decl chain.
+ * trans-types.c (g95_init_types): Always name integer and char types.
+ (g95_get_array_type_bounds): TYPE_NAME may be a TYPE_DECL.
+
+2002-09-02 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * Make-lang.in: Add options.c to F95_PARSER_OBJS
+
+2002-09-02 Paul Brook <paul@nowt.org>
+
+ * g95_generate_code: Clear the attr for __fortran_main.
+ * trans-types.c (g95_finish_type): New function.
+ * g95_init_io_state_type: Use g95_finish_type.
+ * g95_conv_intrinsic_anyall: Fix thinko in result initialization.
+
+2002-09-01 Paul Brook <paul@nowt.org>
+
+ * README.backend: Warn about the dangers of extra config.h files.
+ Remove obsolete libgfor stuff.
+ * config-lang.in: Add target-libgfor dependancy.
+ * g95_conv_mpf_to_tree: Use & free allocated buffer p rather than buff.
+
+2002-09-01 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * g95_conv_mpz_to_tree: Free storage pointed to by q,
+ not by buff.
+
+2002-08-30 Paul Brook <paul@nowt.org>
+
+ * trans-intrinsic.c (g95_conv_intrinsic_function,
+ g95_walk_intrinsic_function): Added ANY and ALL.
+ (g95_conv_intrinsic_anyall): New function.
+ * iresolve.c (g95_resolve_any, g95_resolve_all): Include rank in
+ mangled name
+
diff --git a/gcc/fortran/Make-lang.in b/gcc/fortran/Make-lang.in
new file mode 100644
index 00000000000..f12c19c297a
--- /dev/null
+++ b/gcc/fortran/Make-lang.in
@@ -0,0 +1,300 @@
+# -*- makefile -*-
+# Top level makefile fragment for GNU gfortran, the GNU Fortran 95 compiler.
+# Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+# Contributed by Paul Brook <paul@nowt.org
+# and Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+#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 2, or (at your option)
+#any later version.
+
+#GCC is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+#GNU General Public License for more details.
+
+#You should have received a copy of the GNU General Public License
+#along with GCC; see the file COPYING. If not, write to
+#the Free Software Foundation, 59 Temple Place - Suite 330,
+#Boston, MA 02111-1307, USA.
+
+# This file provides the language dependent support in the main Makefile.
+# Each language makefile fragment must provide the following targets:
+#
+# foo.all.build, foo.all.cross, foo.start.encap, foo.rest.encap,
+# foo.info, foo.dvi,
+# foo.install-normal, foo.install-common, foo.install-info, foo.install-man,
+# foo.uninstall, foo.distdir,
+# foo.mostlyclean, foo.clean, foo.distclean, foo.extraclean,
+# foo.maintainer-clean, foo.stage1, foo.stage2, foo.stage3, foo.stage4
+#
+# where `foo' is the name of the language.
+#
+# It should also provide rules for:
+#
+# - making any compiler driver (eg: gfortran)
+# - the compiler proper (eg: f951)
+# - define the names for selecting the language in LANGUAGES.
+# $(srcdir) must be set to the gcc/ source directory (*not* gcc/fortran/).
+
+# Actual name to use when installing a native compiler.
+GFORTRAN_INSTALL_NAME = `echo gfortran|sed '$(program_transform_name)'`
+
+# Actual name to use when installing a cross-compiler.
+GFORTRAN_CROSS_NAME = `echo gfortran|sed '$(program_transform_cross_name)'`
+
+#^L
+
+# This is in addition to the warning flags defined by default.
+# You can use it to enable/disable warnings globally or for specific
+# files, e.g.
+# fortran-warn = -Wno-strict-prototypes
+# fortran/arith.o-warn = -Wno-error
+#
+# We don't need these cheats, everything builds fine with all warnings
+# enabled and -Werror.
+
+# These are the groups of object files we have. The F95_PARSER_OBJS are
+# all the front end files, the F95_OBJS are the files for the translation
+# from the parse tree to GENERIC, and F95_ADDITIONAL_OBJS are the files
+# from the middle end we depend on.
+
+F95_PARSER_OBJS = fortran/arith.o fortran/array.o fortran/bbt.o fortran/check.o\
+ fortran/decl.o fortran/error.o fortran/expr.o fortran/interface.o \
+ fortran/intrinsic.o fortran/io.o fortran/iresolve.o fortran/match.o \
+ fortran/matchexp.o fortran/misc.o fortran/module.o fortran/parse.o \
+ fortran/primary.o fortran/options.o fortran/resolve.o \
+ fortran/scanner.o fortran/simplify.o fortran/st.o fortran/symbol.o \
+ fortran/dump-parse-tree.o
+
+F95_OBJS = $(F95_PARSER_OBJS) \
+ fortran/f95-lang.o fortran/convert.o fortran/trans.o fortran/trans-decl.o \
+ fortran/trans-types.o fortran/trans-const.o fortran/trans-expr.o \
+ fortran/trans-stmt.o fortran/trans-io.o fortran/trans-array.o \
+ fortran/trans-intrinsic.o fortran/dependency.o fortran/trans-common.o \
+ fortran/data.o
+
+# FIXME:
+# We rely on c-semantics to expand from GIMPLE to RTL.
+# This should go away once a real GIMPLE expander is available.
+F95_ADDITIONAL_OBJS = \
+ tree-cfg.o tree-dfa.o tree-optimize.o tree-gimple.o \
+ tree-ssa.o tree-ssa-ccp.o tree-ssa-dce.o \
+ tree-alias-common.o tree-alias-type.o gimplify.o stor-layout.o
+
+# GFORTRAN uses GMP for its internal arithmetics.
+F95_LIBS = $(GMPLIBS) $(LIBS)
+
+#
+# Define the names for selecting gfortran in LANGUAGES.
+F95 f95: f951$(exeext)
+
+# Tell GNU make to ignore files by these names if they exist.
+.PHONY: F95 f95
+
+gfortranspec.o: $(srcdir)/fortran/gfortranspec.c $(SYSTEM_H) $(TM_H) $(GCC_H) $(CONFIG_H)
+ (SHLIB_LINK='$(SHLIB_LINK)' \
+ SHLIB_MULTILIB='$(SHLIB_MULTILIB)'; \
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(DRIVER_DEFINES) \
+ $(INCLUDES) $(srcdir)/fortran/gfortranspec.c)
+
+# Create the compiler driver gfortran.
+GFORTRAN_D_OBJS = gcc.o gfortranspec.o version.o prefix.o intl.o
+gfortran$(exeext): $(GFORTRAN_D_OBJS) $(EXTRA_GCC_OBJS) $(LIBDEPS)
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
+ $(GFORTRAN_D_OBJS) $(EXTRA_GCC_OBJS) $(LIBS)
+
+# Create a version of the gfortran driver which calls the cross-compiler.
+gfortran-cross$(exeext): gfortran$(exeext)
+ -rm -f gfortran-cross$(exeext)
+ cp gfortran$(exeext) gfortran-cross$(exeext)
+
+# The compiler itself is called f951.
+f951$(exeext): $(F95_OBJS) $(F95_ADDITIONAL_OBJS) \
+ $(BACKEND) $(LIBDEPS)
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
+ $(F95_OBJS) $(F95_ADDITIONAL_OBJS) $(BACKEND) $(F95_LIBS)
+
+gt-fortran-f95-lang.h gtype-fortran.h : s-gtype; @true
+gt-fortran-trans-decl.h gt-fortran-trans.h : s-gtype; @true
+gt-fortran-trans-io.h gt-fortran-trans-types.h: s-gtype; @true
+gt-fortran-trans-intrinsic.h : s-gtype; @true
+
+#
+# Build hooks:
+
+f95.all.build: gfortran$(exeext)
+f95.all.cross: gfortran-cross$(exeext)
+
+f95.start.encap: gfortran$(exeext)
+f95.rest.encap:
+
+f95.srcinfo: fortran/gfortran.info
+ -cp -p $^ $(srcdir)/fortran
+
+f95.tags: force
+ cd $(srcdir)/fortran; etags -o TAGS.sub *.c *.h; \
+ etags --include TAGS.sub --include ../TAGS.sub
+
+f95.info: fortran/gfortran.info
+f95.dvi: fortran/gfortran.dvi
+f95.generated-manpages:
+
+f95.man:
+f95.srcman:
+
+check-f95 : check-gfortran
+lang_checks += check-gfortran
+
+# GFORTRAN documentation.
+GFORTRAN_TEXI = \
+ $(srcdir)/fortran/gfortran.texi \
+ $(srcdir)/fortran/invoke.texi \
+ $(srcdir)/doc/include/fdl.texi \
+ $(srcdir)/doc/include/gpl.texi \
+ $(srcdir)/doc/include/funding.texi \
+ $(srcdir)/doc/include/gcc-common.texi
+
+fortran/gfortran.info: $(GFORTRAN_TEXI)
+ if [ x$(BUILD_INFO) = xinfo ]; then \
+ rm -f fortran/gfortran.info-*; \
+ $(MAKEINFO) -I$(srcdir)/doc/include -I$(srcdir)/fortran \
+ -o fortran/gfortran.info $(srcdir)/fortran/gfortran.texi; \
+ else true; fi
+
+fortran/gfortran.dvi: $(GFORTRAN_TEXI)
+ s=`cd $(srcdir); ${PWD}`; export s; \
+ cd fortran && $(TEXI2DVI) -I $$s/doc/include -I $$s/fortran \
+ $$s/fortran/gfortran.texi
+
+#
+# Install hooks:
+# f951 is installed elsewhere as part of $(COMPILERS).
+
+# Nothing to do here.
+f95.install-normal:
+
+# Install the driver program as $(target)-gfortran
+# and also as either gfortran (if native) or $(tooldir)/bin/gfortran.
+f95.install-common: installdirs
+ -if [ -f f951$(exeext) ] ; then \
+ if [ -f gfortran-cross$(exeext) ] ; then \
+ rm -f $(DESTDIR)$(bindir)/$(GFORTRAN_CROSS_NAME)$(exeext); \
+ $(INSTALL_PROGRAM) gfortran-cross$(exeext) $(DESTDIR)$(bindir)/$(GFORTRAN_CROSS_NAME)$(exeext); \
+ chmod a+x $(DESTDIR)$(bindir)/$(GFORTRAN_CROSS_NAME)$(exeext); \
+ if [ -d $(DESTDIR)$(gcc_tooldir)/bin/. ] ; then \
+ rm -f $(DESTDIR)$(gcc_tooldir)/bin/gfortran$(exeext); \
+ $(INSTALL_PROGRAM) gfortran-cross$(exeext) $(DESTDIR)$(gcc_tooldir)/bin/gfortran$(exeext); \
+ else true; fi; \
+ else \
+ rm -f $(DESTDIR)$(bindir)/$(GFORTRAN_INSTALL_NAME)$(exeext); \
+ $(INSTALL_PROGRAM) gfortran$(exeext) $(DESTDIR)$(bindir)/$(GFORTRAN_INSTALL_NAME)$(exeext); \
+ chmod a+x $(DESTDIR)$(bindir)/$(GFORTRAN_INSTALL_NAME)$(exeext); \
+ rm -f $(DESTDIR)$(bindir)/$(GFORTRAN_TARGET_INSTALL_NAME)$(exeext); \
+ $(LN) $(DESTDIR)$(bindir)/$(GFORTRAN_INSTALL_NAME)$(exeext) $(DESTDIR)$(bindir)/$(GFORTRAN_TARGET_INSTALL_NAME)$(exeext); \
+ fi ; \
+ fi
+
+# Install the info documentation in $(infodir).
+# Taken from G77 (but then, what is not...)
+f95.install-info: f95.info installdirs
+ if [ -f fortran/gfortran.info ] ; then \
+ rm -f $(DESTDIR)$(infodir)/gfortran.info*; \
+ for f in fortran/gfortran.info*; do \
+ realfile=`echo $$f | sed -e 's|.*/\([^/]*\)$$|\1|'`; \
+ $(INSTALL_DATA) $$f $(DESTDIR)$(infodir)/$$realfile; \
+ done; \
+ chmod a-x $(DESTDIR)$(infodir)/gfortran.info*; \
+ else true; fi
+ @if [ -f fortran/gfortran.info ] ; then \
+ if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
+ echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/gfortran.info"; \
+ install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/gfortran.info || : ; \
+ else : ; fi; \
+ else : ; fi
+
+f95.install-man: installdirs
+#TODO: write the gfortran man pages
+
+f95.uninstall:
+ if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
+ echo " install-info --delete --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/gfortran.info"; \
+ install-info --delete --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/gfortran.info || : ; \
+ else : ; fi; \
+ rm -rf $(DESTDIR)$(bindir)/$(GFORTRAN_INSTALL_NAME)$(exeext); \
+ rm -rf $(DESTDIR)$(bindir)/$(GFORTRAN_CROSS_NAME)$(exeext); \
+ rm -rf $(DESTDIR)$(infodir)/gfortran.info*
+
+#
+# Clean hooks:
+# A lot of the ancillary files are deleted by the main makefile.
+# We just have to delete files specific to us.
+
+f95.mostlyclean:
+ -rm -f f951$(exeext)
+ -rm -f fortran/*.o
+
+f95.clean:
+f95.distclean:
+ -rm -f fortran/config.status fortran/Makefile
+
+f95.extraclean:
+f95.maintainer-clean:
+ -rm -f fortran/gfortran.info* fortran/gfortran.*aux
+
+#
+# Stage hooks:
+# The toplevel makefile has already created stage?/fortran at this point.
+
+f95.stage1: stage1-start
+ -mv fortran/*$(objext) stage1/fortran
+f95.stage2: stage2-start
+ -mv fortran/*$(objext) stage2/fortran
+f95.stage3: stage3-start
+ -mv fortran/*$(objext) stage3/fortran
+f95.stage4: stage4-start
+ -mv fortran/*$(objext) stage4/fortran
+f95.stageprofile: stageprofile-start
+ -mv fortran/*$(objext) stageprofile/fortran
+f95.stagefeedback: stageprofile-start
+ -mv fortran/*$(objext) stagefeedback/fortran
+
+#
+# .o: .h dependencies.
+
+# Everything depends on gfortran.h, but only a few files depend on
+# the other headers. So at some point we'll have to split out
+# which objects depend on what. FIXME
+# TODO: Add dependencies on the backend/tree header files
+
+$(F95_PARSER_OBJS): fortran/gfortran.h fortran/intrinsic.h fortran/match.h \
+ fortran/parse.h \
+ $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(TM_P_H) coretypes.h \
+ $(RTL_H) $(TREE_H) $(TREE_DUMP_H) $(GGC_H) $(EXPR_H) \
+ flags.h output.h diagnostic.h errors.h function.h
+
+GFORTRAN_TRANS_DEPS = fortran/gfortran.h fortran/intrinsic.h fortran/trans-array.h \
+ fortran/trans-const.h fortran/trans-const.h fortran/trans.h \
+ fortran/trans-stmt.h fortran/trans-types.h \
+ $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TM_H) coretypes.h
+
+fortran/f95-lang.o: $(GFORTRAN_TRANS_DEPS) fortran/mathbuiltins.def \
+ gt-fortran-f95-lang.h gtype-fortran.h cgraph.h
+fortran/convert.o: $(GFORTRAN_TRANS_DEPS)
+fortran/trans.o: $(GFORTRAN_TRANS_DEPS)
+fortran/trans-decl.o: $(GFORTRAN_TRANS_DEPS) gt-fortran-trans-decl.h cgraph.h
+fortran/trans-types.o: $(GFORTRAN_TRANS_DEPS) gt-fortran-trans-types.h
+fortran/trans-const.o: $(GFORTRAN_TRANS_DEPS)
+fortran/trans-expr.o: $(GFORTRAN_TRANS_DEPS)
+fortran/trans-stmt.o: $(GFORTRAN_TRANS_DEPS)
+fortran/trans-io.o: $(GFORTRAN_TRANS_DEPS) gt-fortran-trans-io.h
+fortran/trans-array.o: $(GFORTRAN_TRANS_DEPS)
+fortran/trans-intrinsic.o: $(GFORTRAN_TRANS_DEPS) fortran/mathbuiltins.def \
+ gt-fortran-trans-intrinsic.h
+fortran/dependency.o: fortran/gfortran.h fortran/dependency.h
+fortran/trans-common.o: $(GFORTRAN_TRANS_DEPS) fortran/gfortran.h
+fortran/data.c: $(GFORTRAN_TRANS_DEPS)
+
diff --git a/gcc/fortran/NEWS b/gcc/fortran/NEWS
new file mode 100644
index 00000000000..ce466feef81
--- /dev/null
+++ b/gcc/fortran/NEWS
@@ -0,0 +1,7 @@
+2003-01-06
+This project is a fork of the original G95 project. The fork has the
+support of the GCC community. We still persue mostly the same goals
+as the original project, but we hope we can attrack more developers
+through better cooperation and communication, and we target quicker
+inclusion in GCC.
+
diff --git a/gcc/fortran/README b/gcc/fortran/README
new file mode 100644
index 00000000000..fc28c995200
--- /dev/null
+++ b/gcc/fortran/README
@@ -0,0 +1,18 @@
+The goal of the gcc-g95 project is to create a Free (as
+in speech) Fortran 95 compiler. The code has been donated
+to the Free Software Foundation for inclusion in GCC, thE
+GNU Compiler Collection.
+
+WARNING:
+
+G95 is still under development. Perusing the g77 source, we estimate
+that about 200,000 lines of code will be necessary to fully implement
+g95. Currently, G95 is about 70,000 lines long, making it about
+version 0.3.
+
+The current g95 can generate code for most legal Fortran 77 programs,
+and we're getting close to being able to compile most Fortran 95
+programs as well. The generated code may still be quite poor, however.
+Part of this is a back-end issue, since we're using the Work-In-Progress
+tree-ssa infrastructure.
+
diff --git a/gcc/fortran/TODO b/gcc/fortran/TODO
new file mode 100644
index 00000000000..023ac34b0a0
--- /dev/null
+++ b/gcc/fortran/TODO
@@ -0,0 +1,56 @@
+TODO
+
+Parser fixes:
+------------
+
+In a constant format string given to a data transfer statement, the
+locus of any problems in the string isn't guaranteed to come out
+right, because there is not a 1:1 correspondence between source
+characters and characters in the string. This scheme totally doesn't
+work for format strings that are longer than a physical line.
+
+Fix IMPLICIT to allow forward references of derived types.
+
+Array issues in expressions and intrinsics.
+
+Resolve scoping issues. Create symbols in correct namespaces.
+
+Finish resolution phase.
+
+Finish compiler side of intrinsic functions.
+
+Allow init exprs to be numbers raised to integer powers (negative too).
+
+See about making emacs-parsable error messages.
+
+
+Biggies:
+--------
+
+Interface to code generator.
+
+Complete runtime library.
+
+
+Known bugs:
+-----------
+
+Failure to set the expr_locus field in g95_expr structures.
+
+
+And for the really pedantic
+---------------------------
+
+Fix INCLUDE such that it only appears on a single line. The current
+code allows things like:
+
+ 0I
+ 1NCLUDE "filename"
+
+or its free form equivalent:
+
+I&
+NCLUDE "filename"
+
+This is explicitly forbidden by the F95 standard (ref. section 3.4).
+
diff --git a/gcc/fortran/arith.c b/gcc/fortran/arith.c
new file mode 100644
index 00000000000..b4041a61151
--- /dev/null
+++ b/gcc/fortran/arith.c
@@ -0,0 +1,2764 @@
+/* Compiler arithmetic
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation,
+ Inc.
+ Contributed by Andy Vaught
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Since target arithmetic must be done on the host, there has to
+ be some way of evaluating arithmetic expressions as the host
+ would evaluate them. We use the GNU MP library to do arithmetic,
+ and this file provides the interface. */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "gfortran.h"
+#include "arith.h"
+
+mpf_t pi, half_pi, two_pi, e;
+
+/* The gfc_(integer|real)_kinds[] structures have everything the front
+ end needs to know about integers and real numbers on the target.
+ Other entries of the structure are calculated from these values.
+ The first entry is the default kind, the second entry of the real
+ structure is the default double kind. */
+
+#define MPZ_NULL {{0,0,0}}
+#define MPF_NULL {{0,0,0,0}}
+
+#define DEF_GFC_INTEGER_KIND(KIND,RADIX,DIGITS,BIT_SIZE) \
+ {KIND, RADIX, DIGITS, BIT_SIZE, 0, MPZ_NULL, MPZ_NULL, MPZ_NULL}
+
+#define DEF_GFC_LOGICAL_KIND(KIND,BIT_SIZE) \
+ {KIND, BIT_SIZE}
+
+#define DEF_GFC_REAL_KIND(KIND,RADIX,DIGITS,MIN_EXP, MAX_EXP) \
+ {KIND, RADIX, DIGITS, MIN_EXP, MAX_EXP, \
+ 0, 0, MPF_NULL, MPF_NULL, MPF_NULL}
+
+gfc_integer_info gfc_integer_kinds[] = {
+ DEF_GFC_INTEGER_KIND (4, 2, 31, 32),
+ DEF_GFC_INTEGER_KIND (8, 2, 63, 64),
+ DEF_GFC_INTEGER_KIND (2, 2, 15, 16),
+ DEF_GFC_INTEGER_KIND (1, 2, 7, 8),
+ DEF_GFC_INTEGER_KIND (0, 0, 0, 0)
+};
+
+gfc_logical_info gfc_logical_kinds[] = {
+ DEF_GFC_LOGICAL_KIND (4, 32),
+ DEF_GFC_LOGICAL_KIND (8, 64),
+ DEF_GFC_LOGICAL_KIND (2, 16),
+ DEF_GFC_LOGICAL_KIND (1, 8),
+ DEF_GFC_LOGICAL_KIND (0, 0)
+};
+
+gfc_real_info gfc_real_kinds[] = {
+ DEF_GFC_REAL_KIND (4, 2, 24, -125, 128),
+ DEF_GFC_REAL_KIND (8, 2, 53, -1021, 1024),
+ DEF_GFC_REAL_KIND (0, 0, 0, 0, 0)
+};
+
+
+/* The integer kind to use for array indices. This will be set to the
+ proper value based on target information from the backend. */
+
+int gfc_index_integer_kind;
+
+
+/* Compute the natural log of arg.
+
+ We first get the argument into the range 0.5 to 1.5 by successive
+ multiplications or divisions by e. Then we use the series:
+
+ ln(x) = (x-1) - (x-1)^/2 + (x-1)^3/3 - (x-1)^4/4 + ...
+
+ Because we are expanding in powers of (x-1), and 0.5 < x < 1.5, we
+ have -0.5 < (x-1) < 0.5. Ignoring the harmonic term, this means
+ that each term is at most 1/(2^i), meaning one bit is gained per
+ iteration.
+
+ Not very efficient, but it doesn't have to be. */
+
+void
+natural_logarithm (mpf_t * arg, mpf_t * result)
+{
+ mpf_t x, xp, t, log;
+ int i, p;
+
+ mpf_init_set (x, *arg);
+ mpf_init (t);
+
+ p = 0;
+
+ mpf_set_str (t, "0.5", 10);
+ while (mpf_cmp (x, t) < 0)
+ {
+ mpf_mul (x, x, e);
+ p--;
+ }
+
+ mpf_set_str (t, "1.5", 10);
+ while (mpf_cmp (x, t) > 0)
+ {
+ mpf_div (x, x, e);
+ p++;
+ }
+
+ mpf_sub_ui (x, x, 1);
+ mpf_init_set_ui (log, 0);
+ mpf_init_set_ui (xp, 1);
+
+ for (i = 1; i < GFC_REAL_BITS; i++)
+ {
+ mpf_mul (xp, xp, x);
+ mpf_div_ui (t, xp, i);
+
+ if (i % 2 == 0)
+ mpf_sub (log, log, t);
+ else
+ mpf_add (log, log, t);
+ }
+
+ /* Add in the log (e^p) = p */
+
+ if (p < 0)
+ mpf_sub_ui (log, log, -p);
+ else
+ mpf_add_ui (log, log, p);
+
+ mpf_clear (x);
+ mpf_clear (xp);
+ mpf_clear (t);
+
+ mpf_set (*result, log);
+ mpf_clear (log);
+}
+
+
+/* Calculate the common logarithm of arg. We use the natural
+ logaritm of arg and of 10:
+
+ log10(arg) = log(arg)/log(10) */
+
+void
+common_logarithm (mpf_t * arg, mpf_t * result)
+{
+ mpf_t i10, log10;
+
+ natural_logarithm (arg, result);
+
+ mpf_init_set_ui (i10, 10);
+ mpf_init (log10);
+ natural_logarithm (&i10, &log10);
+
+ mpf_div (*result, *result, log10);
+ mpf_clear (i10);
+ mpf_clear (log10);
+}
+
+/* Calculate exp(arg).
+
+ We use a reduction of the form
+
+ x = Nln2 + r
+
+ Then we obtain exp(r) from the McLaurin series.
+ exp(x) is then recovered from the identity
+
+ exp(x) = 2^N*exp(r). */
+
+void
+exponential (mpf_t * arg, mpf_t * result)
+{
+ mpf_t two, ln2, power, q, r, num, denom, term, x, xp;
+ int i;
+ long n;
+ unsigned long p, mp;
+
+
+ mpf_init_set (x, *arg);
+
+ if (mpf_cmp_ui (x, 0) == 0)
+ {
+ mpf_set_ui (*result, 1);
+ }
+ else if (mpf_cmp_ui (x, 1) == 0)
+ {
+ mpf_set (*result, e);
+ }
+ else
+ {
+ mpf_init_set_ui (two, 2);
+ mpf_init (ln2);
+ mpf_init (q);
+ mpf_init (r);
+ mpf_init (power);
+ mpf_init (term);
+
+ natural_logarithm (&two, &ln2);
+
+ mpf_div (q, x, ln2);
+ mpf_floor (power, q);
+ mpf_mul (q, power, ln2);
+ mpf_sub (r, x, q);
+
+ mpf_init_set_ui (xp, 1);
+ mpf_init_set_ui (num, 1);
+ mpf_init_set_ui (denom, 1);
+
+ for (i = 1; i <= GFC_REAL_BITS + 10; i++)
+ {
+ mpf_mul (num, num, r);
+ mpf_mul_ui (denom, denom, i);
+ mpf_div (term, num, denom);
+ mpf_add (xp, xp, term);
+ }
+
+ /* Reconstruction step */
+ n = (long) mpf_get_d (power);
+
+ if (n > 0)
+ {
+ p = (unsigned int) n;
+ mpf_mul_2exp (*result, xp, p);
+ }
+ else
+ {
+ mp = (unsigned int) (-n);
+ mpf_div_2exp (*result, xp, mp);
+ }
+
+ mpf_clear (two);
+ mpf_clear (ln2);
+ mpf_clear (q);
+ mpf_clear (r);
+ mpf_clear (power);
+ mpf_clear (num);
+ mpf_clear (denom);
+ mpf_clear (term);
+ mpf_clear (xp);
+ }
+
+ mpf_clear (x);
+}
+
+
+/* Calculate sin(arg).
+
+ We use a reduction of the form
+
+ x= N*2pi + r
+
+ Then we obtain sin(r) from the McLaurin series. */
+
+void
+sine (mpf_t * arg, mpf_t * result)
+{
+ mpf_t factor, q, r, num, denom, term, x, xp;
+ int i, sign;
+
+ mpf_init_set (x, *arg);
+
+ /* Special case (we do not treat multiples of pi due to roundoff issues) */
+ if (mpf_cmp_ui (x, 0) == 0)
+ {
+ mpf_set_ui (*result, 0);
+ }
+ else
+ {
+ mpf_init (q);
+ mpf_init (r);
+ mpf_init (factor);
+ mpf_init (term);
+
+ mpf_div (q, x, two_pi);
+ mpf_floor (factor, q);
+ mpf_mul (q, factor, two_pi);
+ mpf_sub (r, x, q);
+
+ mpf_init_set_ui (xp, 0);
+ mpf_init_set_ui (num, 1);
+ mpf_init_set_ui (denom, 1);
+
+ sign = -1;
+ for (i = 1; i < GFC_REAL_BITS + 10; i++)
+ {
+ mpf_mul (num, num, r);
+ mpf_mul_ui (denom, denom, i);
+ if (i % 2 == 0)
+ continue;
+
+ sign = -sign;
+ mpf_div (term, num, denom);
+ if (sign > 0)
+ mpf_add (xp, xp, term);
+ else
+ mpf_sub (xp, xp, term);
+ }
+
+ mpf_set (*result, xp);
+
+ mpf_clear (q);
+ mpf_clear (r);
+ mpf_clear (factor);
+ mpf_clear (num);
+ mpf_clear (denom);
+ mpf_clear (term);
+ mpf_clear (xp);
+ }
+
+ mpf_clear (x);
+}
+
+
+/* Calculate cos(arg).
+
+ Similar to sine. */
+
+void
+cosine (mpf_t * arg, mpf_t * result)
+{
+ mpf_t factor, q, r, num, denom, term, x, xp;
+ int i, sign;
+
+ mpf_init_set (x, *arg);
+
+ /* Special case (we do not treat multiples of pi due to roundoff issues) */
+ if (mpf_cmp_ui (x, 0) == 0)
+ {
+ mpf_set_ui (*result, 1);
+ }
+ else
+ {
+ mpf_init (q);
+ mpf_init (r);
+ mpf_init (factor);
+ mpf_init (term);
+
+ mpf_div (q, x, two_pi);
+ mpf_floor (factor, q);
+ mpf_mul (q, factor, two_pi);
+ mpf_sub (r, x, q);
+
+ mpf_init_set_ui (xp, 1);
+ mpf_init_set_ui (num, 1);
+ mpf_init_set_ui (denom, 1);
+
+ sign = 1;
+ for (i = 1; i < GFC_REAL_BITS + 10; i++)
+ {
+ mpf_mul (num, num, r);
+ mpf_mul_ui (denom, denom, i);
+ if (i % 2 != 0)
+ continue;
+
+ sign = -sign;
+ mpf_div (term, num, denom);
+ if (sign > 0)
+ mpf_add (xp, xp, term);
+ else
+ mpf_sub (xp, xp, term);
+ }
+ mpf_set (*result, xp);
+
+ mpf_clear (q);
+ mpf_clear (r);
+ mpf_clear (factor);
+ mpf_clear (num);
+ mpf_clear (denom);
+ mpf_clear (term);
+ mpf_clear (xp);
+ }
+
+ mpf_clear (x);
+}
+
+
+/* Calculate atan(arg).
+
+ Similar to sine but requires special handling for x near 1. */
+
+void
+arctangent (mpf_t * arg, mpf_t * result)
+{
+ mpf_t absval, convgu, convgl, num, term, x, xp;
+ int i, sign;
+
+ mpf_init_set (x, *arg);
+
+ /* Special cases */
+ if (mpf_cmp_ui (x, 0) == 0)
+ {
+ mpf_set_ui (*result, 0);
+ }
+ else if (mpf_cmp_ui (x, 1) == 0)
+ {
+ mpf_init (num);
+ mpf_div_ui (num, half_pi, 2);
+ mpf_set (*result, num);
+ mpf_clear (num);
+ }
+ else if (mpf_cmp_si (x, -1) == 0)
+ {
+ mpf_init (num);
+ mpf_div_ui (num, half_pi, 2);
+ mpf_neg (*result, num);
+ mpf_clear (num);
+ }
+ else
+ { /* General cases */
+
+ mpf_init (absval);
+ mpf_abs (absval, x);
+
+ mpf_init_set_d (convgu, 1.5);
+ mpf_init_set_d (convgl, 0.5);
+ mpf_init_set_ui (num, 1);
+ mpf_init (term);
+
+ if (mpf_cmp (absval, convgl) < 0)
+ {
+ mpf_init_set_ui (xp, 0);
+ sign = -1;
+ for (i = 1; i < GFC_REAL_BITS + 10; i++)
+ {
+ mpf_mul (num, num, absval);
+ if (i % 2 == 0)
+ continue;
+
+ sign = -sign;
+ mpf_div_ui (term, num, i);
+ if (sign > 0)
+ mpf_add (xp, xp, term);
+ else
+ mpf_sub (xp, xp, term);
+ }
+ }
+ else if (mpf_cmp (absval, convgu) >= 0)
+ {
+ mpf_init_set (xp, half_pi);
+ sign = 1;
+ for (i = 1; i < GFC_REAL_BITS + 10; i++)
+ {
+ mpf_div (num, num, absval);
+ if (i % 2 == 0)
+ continue;
+
+ sign = -sign;
+ mpf_div_ui (term, num, i);
+ if (sign > 0)
+ mpf_add (xp, xp, term);
+ else
+ mpf_sub (xp, xp, term);
+ }
+ }
+ else
+ {
+ mpf_init_set_ui (xp, 0);
+
+ mpf_sub_ui (num, absval, 1);
+ mpf_add_ui (term, absval, 1);
+ mpf_div (absval, num, term);
+
+ mpf_set_ui (num, 1);
+
+ sign = -1;
+ for (i = 1; i < GFC_REAL_BITS + 10; i++)
+ {
+ mpf_mul (num, num, absval);
+ if (i % 2 == 0)
+ continue;
+ sign = -sign;
+ mpf_div_ui (term, num, i);
+ if (sign > 0)
+ mpf_add (xp, xp, term);
+ else
+ mpf_sub (xp, xp, term);
+ }
+
+ mpf_div_ui (term, half_pi, 2);
+ mpf_add (xp, term, xp);
+ }
+
+ /* This makes sure to preserve the identity arctan(-x) = -arctan(x)
+ and improves accuracy to boot. */
+
+ if (mpf_cmp_ui (x, 0) > 0)
+ mpf_set (*result, xp);
+ else
+ mpf_neg (*result, xp);
+
+ mpf_clear (absval);
+ mpf_clear (convgl);
+ mpf_clear (convgu);
+ mpf_clear (num);
+ mpf_clear (term);
+ mpf_clear (xp);
+ }
+ mpf_clear (x);
+}
+
+
+/* Calculate atan2 (y, x)
+
+atan2(y, x) = atan(y/x) if x > 0,
+ sign(y)*(pi - atan(|y/x|)) if x < 0,
+ 0 if x = 0 && y == 0,
+ sign(y)*pi/2 if x = 0 && y != 0.
+*/
+
+void
+arctangent2 (mpf_t * y, mpf_t * x, mpf_t * result)
+{
+ mpf_t t;
+
+ mpf_init (t);
+
+ switch (mpf_sgn (*x))
+ {
+ case 1:
+ mpf_div (t, *y, *x);
+ arctangent (&t, result);
+ break;
+ case -1:
+ mpf_div (t, *y, *x);
+ mpf_abs (t, t);
+ arctangent (&t, &t);
+ mpf_sub (*result, pi, t);
+ if (mpf_sgn (*y) == -1)
+ mpf_neg (*result, *result);
+ break;
+ case 0:
+ if (mpf_sgn (*y) == 0)
+ mpf_set_ui (*result, 0);
+ else
+ {
+ mpf_set (*result, half_pi);
+ if (mpf_sgn (*y) == -1)
+ mpf_neg (*result, *result);
+ }
+ break;
+ }
+ mpf_clear (t);
+}
+
+/* Calculate cosh(arg). */
+
+void
+hypercos (mpf_t * arg, mpf_t * result)
+{
+ mpf_t neg, term1, term2, x, xp;
+
+ mpf_init_set (x, *arg);
+
+ mpf_init (neg);
+ mpf_init (term1);
+ mpf_init (term2);
+ mpf_init (xp);
+
+ mpf_neg (neg, x);
+
+ exponential (&x, &term1);
+ exponential (&neg, &term2);
+
+ mpf_add (xp, term1, term2);
+ mpf_div_ui (*result, xp, 2);
+
+ mpf_clear (neg);
+ mpf_clear (term1);
+ mpf_clear (term2);
+ mpf_clear (x);
+ mpf_clear (xp);
+}
+
+
+/* Calculate sinh(arg). */
+
+void
+hypersine (mpf_t * arg, mpf_t * result)
+{
+ mpf_t neg, term1, term2, x, xp;
+
+ mpf_init_set (x, *arg);
+
+ mpf_init (neg);
+ mpf_init (term1);
+ mpf_init (term2);
+ mpf_init (xp);
+
+ mpf_neg (neg, x);
+
+ exponential (&x, &term1);
+ exponential (&neg, &term2);
+
+ mpf_sub (xp, term1, term2);
+ mpf_div_ui (*result, xp, 2);
+
+ mpf_clear (neg);
+ mpf_clear (term1);
+ mpf_clear (term2);
+ mpf_clear (x);
+ mpf_clear (xp);
+}
+
+
+/* Given an arithmetic error code, return a pointer to a string that
+ explains the error. */
+
+static const char *
+gfc_arith_error (arith code)
+{
+ const char *p;
+
+ switch (code)
+ {
+ case ARITH_OK:
+ p = "Arithmetic OK";
+ break;
+ case ARITH_OVERFLOW:
+ p = "Arithmetic overflow";
+ break;
+ case ARITH_UNDERFLOW:
+ p = "Arithmetic underflow";
+ break;
+ case ARITH_DIV0:
+ p = "Division by zero";
+ break;
+ case ARITH_0TO0:
+ p = "Indeterminate form 0 ** 0";
+ break;
+ case ARITH_INCOMMENSURATE:
+ p = "Array operands are incommensurate";
+ break;
+ default:
+ gfc_internal_error ("gfc_arith_error(): Bad error code");
+ }
+
+ return p;
+}
+
+
+/* Get things ready to do math. */
+
+void
+gfc_arith_init_1 (void)
+{
+ gfc_integer_info *int_info;
+ gfc_real_info *real_info;
+ mpf_t a, b;
+ mpz_t r;
+ int i, n, limit;
+
+ /* Set the default precision for GMP computations. */
+ mpf_set_default_prec (GFC_REAL_BITS + 30);
+
+ /* Calculate e, needed by the natural_logarithm() subroutine. */
+ mpf_init (b);
+ mpf_init_set_ui (e, 0);
+ mpf_init_set_ui (a, 1);
+
+ for (i = 1; i < 100; i++)
+ {
+ mpf_add (e, e, a);
+ mpf_div_ui (a, a, i); /* 1/(i!) */
+ }
+
+ /* Calculate pi, 2pi, pi/2, and -pi/2, needed for trigonometric
+ functions.
+
+ We use the Bailey, Borwein and Plouffe formula:
+
+ pi = \sum{n=0}^\infty (1/16)^n [4/(8n+1) - 2/(8n+4) - 1/(8n+5) - 1/(8n+6)]
+
+ which gives about four bits per iteration. */
+
+ mpf_init_set_ui (pi, 0);
+
+ mpf_init (two_pi);
+ mpf_init (half_pi);
+
+ limit = (GFC_REAL_BITS / 4) + 10; /* (1/16)^n gives 4 bits per iteration */
+
+ for (n = 0; n < limit; n++)
+ {
+ mpf_set_ui (b, 4);
+ mpf_div_ui (b, b, 8 * n + 1); /* 4/(8n+1) */
+
+ mpf_set_ui (a, 2);
+ mpf_div_ui (a, a, 8 * n + 4); /* 2/(8n+4) */
+ mpf_sub (b, b, a);
+
+ mpf_set_ui (a, 1);
+ mpf_div_ui (a, a, 8 * n + 5); /* 1/(8n+5) */
+ mpf_sub (b, b, a);
+
+ mpf_set_ui (a, 1);
+ mpf_div_ui (a, a, 8 * n + 6); /* 1/(8n+6) */
+ mpf_sub (b, b, a);
+
+ mpf_set_ui (a, 16);
+ mpf_pow_ui (a, a, n); /* 16^n */
+
+ mpf_div (b, b, a);
+
+ mpf_add (pi, pi, b);
+ }
+
+ mpf_mul_ui (two_pi, pi, 2);
+ mpf_div_ui (half_pi, pi, 2);
+
+ /* Convert the minimum/maximum values for each kind into their
+ GNU MP representation. */
+ mpz_init (r);
+
+ for (int_info = gfc_integer_kinds; int_info->kind != 0; int_info++)
+ {
+ /* Huge */
+ mpz_set_ui (r, int_info->radix);
+ mpz_pow_ui (r, r, int_info->digits);
+
+ mpz_init (int_info->huge);
+ mpz_sub_ui (int_info->huge, r, 1);
+
+ /* These are the numbers that are actually representable by the
+ target. For bases other than two, this needs to be changed. */
+ if (int_info->radix != 2)
+ gfc_internal_error ("Fix min_int, max_int calculation");
+
+ mpz_init (int_info->min_int);
+ mpz_neg (int_info->min_int, int_info->huge);
+ /* No -1 here, because the representation is symmetric. */
+
+ mpz_init (int_info->max_int);
+ mpz_add (int_info->max_int, int_info->huge, int_info->huge);
+ mpz_add_ui (int_info->max_int, int_info->max_int, 1);
+
+ /* Range */
+ mpf_set_z (a, int_info->huge);
+ common_logarithm (&a, &a);
+ mpf_trunc (a, a);
+ mpz_set_f (r, a);
+ int_info->range = mpz_get_si (r);
+ }
+
+ /* mpf_set_default_prec(GFC_REAL_BITS); */
+ for (real_info = gfc_real_kinds; real_info->kind != 0; real_info++)
+ {
+ /* Huge */
+ mpf_set_ui (a, real_info->radix);
+ mpf_set_ui (b, real_info->radix);
+
+ mpf_pow_ui (a, a, real_info->max_exponent);
+ mpf_pow_ui (b, b, real_info->max_exponent - real_info->digits);
+
+ mpf_init (real_info->huge);
+ mpf_sub (real_info->huge, a, b);
+
+ /* Tiny */
+ mpf_set_ui (b, real_info->radix);
+ mpf_pow_ui (b, b, 1 - real_info->min_exponent);
+
+ mpf_init (real_info->tiny);
+ mpf_ui_div (real_info->tiny, 1, b);
+
+ /* Epsilon */
+ mpf_set_ui (b, real_info->radix);
+ mpf_pow_ui (b, b, real_info->digits - 1);
+
+ mpf_init (real_info->epsilon);
+ mpf_ui_div (real_info->epsilon, 1, b);
+
+ /* Range */
+ common_logarithm (&real_info->huge, &a);
+ common_logarithm (&real_info->tiny, &b);
+ mpf_neg (b, b);
+
+ if (mpf_cmp (a, b) > 0)
+ mpf_set (a, b); /* a = min(a, b) */
+
+ mpf_trunc (a, a);
+ mpz_set_f (r, a);
+ real_info->range = mpz_get_si (r);
+
+ /* Precision */
+ mpf_set_ui (a, real_info->radix);
+ common_logarithm (&a, &a);
+
+ mpf_mul_ui (a, a, real_info->digits - 1);
+ mpf_trunc (a, a);
+ mpz_set_f (r, a);
+ real_info->precision = mpz_get_si (r);
+
+ /* If the radix is an integral power of 10, add one to the
+ precision. */
+ for (i = 10; i <= real_info->radix; i *= 10)
+ if (i == real_info->radix)
+ real_info->precision++;
+ }
+
+ mpz_clear (r);
+ mpf_clear (a);
+ mpf_clear (b);
+}
+
+
+/* Clean up, get rid of numeric constants. */
+
+void
+gfc_arith_done_1 (void)
+{
+ gfc_integer_info *ip;
+ gfc_real_info *rp;
+
+ mpf_clear (e);
+
+ mpf_clear (pi);
+ mpf_clear (half_pi);
+ mpf_clear (two_pi);
+
+ for (ip = gfc_integer_kinds; ip->kind; ip++)
+ {
+ mpz_clear (ip->min_int);
+ mpz_clear (ip->max_int);
+ mpz_clear (ip->huge);
+ }
+
+ for (rp = gfc_real_kinds; rp->kind; rp++)
+ {
+ mpf_clear (rp->epsilon);
+ mpf_clear (rp->huge);
+ mpf_clear (rp->tiny);
+ }
+}
+
+
+/* Return default kinds. */
+
+int
+gfc_default_integer_kind (void)
+{
+ return gfc_integer_kinds[gfc_option.i8 ? 1 : 0].kind;
+}
+
+int
+gfc_default_real_kind (void)
+{
+ return gfc_real_kinds[gfc_option.r8 ? 1 : 0].kind;
+}
+
+int
+gfc_default_double_kind (void)
+{
+ return gfc_real_kinds[1].kind;
+}
+
+int
+gfc_default_character_kind (void)
+{
+ return 1;
+}
+
+int
+gfc_default_logical_kind (void)
+{
+ return gfc_logical_kinds[gfc_option.i8 ? 1 : 0].kind;
+}
+
+int
+gfc_default_complex_kind (void)
+{
+ return gfc_default_real_kind ();
+}
+
+
+/* Make sure that a valid kind is present. Returns an index into the
+ gfc_integer_kinds array, -1 if the kind is not present. */
+
+static int
+validate_integer (int kind)
+{
+ int i;
+
+ for (i = 0;; i++)
+ {
+ if (gfc_integer_kinds[i].kind == 0)
+ {
+ i = -1;
+ break;
+ }
+ if (gfc_integer_kinds[i].kind == kind)
+ break;
+ }
+
+ return i;
+}
+
+
+static int
+validate_real (int kind)
+{
+ int i;
+
+ for (i = 0;; i++)
+ {
+ if (gfc_real_kinds[i].kind == 0)
+ {
+ i = -1;
+ break;
+ }
+ if (gfc_real_kinds[i].kind == kind)
+ break;
+ }
+
+ return i;
+}
+
+
+static int
+validate_logical (int kind)
+{
+ int i;
+
+ for (i = 0;; i++)
+ {
+ if (gfc_logical_kinds[i].kind == 0)
+ {
+ i = -1;
+ break;
+ }
+ if (gfc_logical_kinds[i].kind == kind)
+ break;
+ }
+
+ return i;
+}
+
+
+static int
+validate_character (int kind)
+{
+
+ if (kind == gfc_default_character_kind ())
+ return 0;
+ return -1;
+}
+
+
+/* Validate a kind given a basic type. The return value is the same
+ for the child functions, with -1 indicating nonexistence of the
+ type. */
+
+int
+gfc_validate_kind (bt type, int kind)
+{
+ int rc;
+
+ switch (type)
+ {
+ case BT_REAL: /* Fall through */
+ case BT_COMPLEX:
+ rc = validate_real (kind);
+ break;
+ case BT_INTEGER:
+ rc = validate_integer (kind);
+ break;
+ case BT_LOGICAL:
+ rc = validate_logical (kind);
+ break;
+ case BT_CHARACTER:
+ rc = validate_character (kind);
+ break;
+
+ default:
+ gfc_internal_error ("gfc_validate_kind(): Got bad type");
+ }
+
+ return rc;
+}
+
+
+/* Given an integer and a kind, make sure that the integer lies within
+ the range of the kind. Returns ARITH_OK or ARITH_OVERFLOW. */
+
+static arith
+gfc_check_integer_range (mpz_t p, int kind)
+{
+ arith result;
+ int i;
+
+ i = validate_integer (kind);
+ if (i == -1)
+ gfc_internal_error ("gfc_check_integer_range(): Bad kind");
+
+ result = ARITH_OK;
+
+ if (mpz_cmp (p, gfc_integer_kinds[i].min_int) < 0
+ || mpz_cmp (p, gfc_integer_kinds[i].max_int) > 0)
+ result = ARITH_OVERFLOW;
+
+ return result;
+}
+
+
+/* Given a real and a kind, make sure that the real lies within the
+ range of the kind. Returns ARITH_OK, ARITH_OVERFLOW or
+ ARITH_UNDERFLOW. */
+
+static arith
+gfc_check_real_range (mpf_t p, int kind)
+{
+ arith retval;
+ mpf_t q;
+ int i;
+
+ mpf_init (q);
+ mpf_abs (q, p);
+
+ i = validate_real (kind);
+ if (i == -1)
+ gfc_internal_error ("gfc_check_real_range(): Bad kind");
+
+ retval = ARITH_OK;
+ if (mpf_sgn (q) == 0)
+ goto done;
+
+ if (mpf_cmp (q, gfc_real_kinds[i].huge) == 1)
+ {
+ retval = ARITH_OVERFLOW;
+ goto done;
+ }
+
+ if (mpf_cmp (q, gfc_real_kinds[i].tiny) == -1)
+ retval = ARITH_UNDERFLOW;
+
+done:
+ mpf_clear (q);
+
+ return retval;
+}
+
+
+/* Function to return a constant expression node of a given type and
+ kind. */
+
+gfc_expr *
+gfc_constant_result (bt type, int kind, locus * where)
+{
+ gfc_expr *result;
+
+ if (!where)
+ gfc_internal_error
+ ("gfc_constant_result(): locus 'where' cannot be NULL");
+
+ result = gfc_get_expr ();
+
+ result->expr_type = EXPR_CONSTANT;
+ result->ts.type = type;
+ result->ts.kind = kind;
+ result->where = *where;
+
+ switch (type)
+ {
+ case BT_INTEGER:
+ mpz_init (result->value.integer);
+ break;
+
+ case BT_REAL:
+ mpf_init (result->value.real);
+ break;
+
+ case BT_COMPLEX:
+ mpf_init (result->value.complex.r);
+ mpf_init (result->value.complex.i);
+ break;
+
+ default:
+ break;
+ }
+
+ return result;
+}
+
+
+/* Low-level arithmetic functions. All of these subroutines assume
+ that all operands are of the same type and return an operand of the
+ same type. The other thing about these subroutines is that they
+ can fail in various ways -- overflow, underflow, division by zero,
+ zero raised to the zero, etc. */
+
+static arith
+gfc_arith_not (gfc_expr * op1, gfc_expr ** resultp)
+{
+ gfc_expr *result;
+
+ result = gfc_constant_result (BT_LOGICAL, op1->ts.kind, &op1->where);
+ result->value.logical = !op1->value.logical;
+ *resultp = result;
+
+ return ARITH_OK;
+}
+
+
+static arith
+gfc_arith_and (gfc_expr * op1, gfc_expr * op2, gfc_expr ** resultp)
+{
+ gfc_expr *result;
+
+ result = gfc_constant_result (BT_LOGICAL, gfc_kind_max (op1, op2),
+ &op1->where);
+ result->value.logical = op1->value.logical && op2->value.logical;
+ *resultp = result;
+
+ return ARITH_OK;
+}
+
+
+static arith
+gfc_arith_or (gfc_expr * op1, gfc_expr * op2, gfc_expr ** resultp)
+{
+ gfc_expr *result;
+
+ result = gfc_constant_result (BT_LOGICAL, gfc_kind_max (op1, op2),
+ &op1->where);
+ result->value.logical = op1->value.logical || op2->value.logical;
+ *resultp = result;
+
+ return ARITH_OK;
+}
+
+
+static arith
+gfc_arith_eqv (gfc_expr * op1, gfc_expr * op2, gfc_expr ** resultp)
+{
+ gfc_expr *result;
+
+ result = gfc_constant_result (BT_LOGICAL, gfc_kind_max (op1, op2),
+ &op1->where);
+ result->value.logical = op1->value.logical == op2->value.logical;
+ *resultp = result;
+
+ return ARITH_OK;
+}
+
+
+static arith
+gfc_arith_neqv (gfc_expr * op1, gfc_expr * op2, gfc_expr ** resultp)
+{
+ gfc_expr *result;
+
+ result = gfc_constant_result (BT_LOGICAL, gfc_kind_max (op1, op2),
+ &op1->where);
+ result->value.logical = op1->value.logical != op2->value.logical;
+ *resultp = result;
+
+ return ARITH_OK;
+}
+
+
+/* Make sure a constant numeric expression is within the range for
+ it's type and kind. Note that there's also a gfc_check_range(),
+ but that one deals with the intrinsic RANGE function. */
+
+arith
+gfc_range_check (gfc_expr * e)
+{
+ arith rc;
+
+ switch (e->ts.type)
+ {
+ case BT_INTEGER:
+ rc = gfc_check_integer_range (e->value.integer, e->ts.kind);
+ break;
+
+ case BT_REAL:
+ rc = gfc_check_real_range (e->value.real, e->ts.kind);
+ break;
+
+ case BT_COMPLEX:
+ rc = gfc_check_real_range (e->value.complex.r, e->ts.kind);
+ if (rc != ARITH_OK)
+ rc = gfc_check_real_range (e->value.complex.i, e->ts.kind);
+
+ break;
+
+ default:
+ gfc_internal_error ("gfc_range_check(): Bad type");
+ }
+
+ return rc;
+}
+
+
+/* It may seem silly to have a subroutine that actually computes the
+ unary plus of a constant, but it prevents us from making exceptions
+ in the code elsewhere. */
+
+static arith
+gfc_arith_uplus (gfc_expr * op1, gfc_expr ** resultp)
+{
+
+ *resultp = gfc_copy_expr (op1);
+ return ARITH_OK;
+}
+
+
+static arith
+gfc_arith_uminus (gfc_expr * op1, gfc_expr ** resultp)
+{
+ gfc_expr *result;
+ arith rc;
+
+ result = gfc_constant_result (op1->ts.type, op1->ts.kind, &op1->where);
+
+ switch (op1->ts.type)
+ {
+ case BT_INTEGER:
+ mpz_neg (result->value.integer, op1->value.integer);
+ break;
+
+ case BT_REAL:
+ mpf_neg (result->value.real, op1->value.real);
+ break;
+
+ case BT_COMPLEX:
+ mpf_neg (result->value.complex.r, op1->value.complex.r);
+ mpf_neg (result->value.complex.i, op1->value.complex.i);
+ break;
+
+ default:
+ gfc_internal_error ("gfc_arith_uminus(): Bad basic type");
+ }
+
+ rc = gfc_range_check (result);
+
+ if (rc != ARITH_OK)
+ gfc_free_expr (result);
+ else
+ *resultp = result;
+
+ return rc;
+}
+
+
+static arith
+gfc_arith_plus (gfc_expr * op1, gfc_expr * op2, gfc_expr ** resultp)
+{
+ gfc_expr *result;
+ arith rc;
+
+ result = gfc_constant_result (op1->ts.type, op1->ts.kind, &op1->where);
+
+ switch (op1->ts.type)
+ {
+ case BT_INTEGER:
+ mpz_add (result->value.integer, op1->value.integer, op2->value.integer);
+ break;
+
+ case BT_REAL:
+ mpf_add (result->value.real, op1->value.real, op2->value.real);
+ break;
+
+ case BT_COMPLEX:
+ mpf_add (result->value.complex.r, op1->value.complex.r,
+ op2->value.complex.r);
+
+ mpf_add (result->value.complex.i, op1->value.complex.i,
+ op2->value.complex.i);
+ break;
+
+ default:
+ gfc_internal_error ("gfc_arith_plus(): Bad basic type");
+ }
+
+ rc = gfc_range_check (result);
+
+ if (rc != ARITH_OK)
+ gfc_free_expr (result);
+ else
+ *resultp = result;
+
+ return rc;
+}
+
+
+static arith
+gfc_arith_minus (gfc_expr * op1, gfc_expr * op2, gfc_expr ** resultp)
+{
+ gfc_expr *result;
+ arith rc;
+
+ result = gfc_constant_result (op1->ts.type, op1->ts.kind, &op1->where);
+
+ switch (op1->ts.type)
+ {
+ case BT_INTEGER:
+ mpz_sub (result->value.integer, op1->value.integer, op2->value.integer);
+ break;
+
+ case BT_REAL:
+ mpf_sub (result->value.real, op1->value.real, op2->value.real);
+ break;
+
+ case BT_COMPLEX:
+ mpf_sub (result->value.complex.r, op1->value.complex.r,
+ op2->value.complex.r);
+
+ mpf_sub (result->value.complex.i, op1->value.complex.i,
+ op2->value.complex.i);
+
+ break;
+
+ default:
+ gfc_internal_error ("gfc_arith_minus(): Bad basic type");
+ }
+
+ rc = gfc_range_check (result);
+
+ if (rc != ARITH_OK)
+ gfc_free_expr (result);
+ else
+ *resultp = result;
+
+ return rc;
+}
+
+
+static arith
+gfc_arith_times (gfc_expr * op1, gfc_expr * op2, gfc_expr ** resultp)
+{
+ gfc_expr *result;
+ mpf_t x, y;
+ arith rc;
+
+ result = gfc_constant_result (op1->ts.type, op1->ts.kind, &op1->where);
+
+ switch (op1->ts.type)
+ {
+ case BT_INTEGER:
+ mpz_mul (result->value.integer, op1->value.integer, op2->value.integer);
+ break;
+
+ case BT_REAL:
+ mpf_mul (result->value.real, op1->value.real, op2->value.real);
+ break;
+
+ case BT_COMPLEX:
+ mpf_init (x);
+ mpf_init (y);
+
+ mpf_mul (x, op1->value.complex.r, op2->value.complex.r);
+ mpf_mul (y, op1->value.complex.i, op2->value.complex.i);
+ mpf_sub (result->value.complex.r, x, y);
+
+ mpf_mul (x, op1->value.complex.r, op2->value.complex.i);
+ mpf_mul (y, op1->value.complex.i, op2->value.complex.r);
+ mpf_add (result->value.complex.i, x, y);
+
+ mpf_clear (x);
+ mpf_clear (y);
+
+ break;
+
+ default:
+ gfc_internal_error ("gfc_arith_times(): Bad basic type");
+ }
+
+ rc = gfc_range_check (result);
+
+ if (rc != ARITH_OK)
+ gfc_free_expr (result);
+ else
+ *resultp = result;
+
+ return rc;
+}
+
+
+static arith
+gfc_arith_divide (gfc_expr * op1, gfc_expr * op2, gfc_expr ** resultp)
+{
+ gfc_expr *result;
+ mpf_t x, y, div;
+ arith rc;
+
+ rc = ARITH_OK;
+
+ result = gfc_constant_result (op1->ts.type, op1->ts.kind, &op1->where);
+
+ switch (op1->ts.type)
+ {
+ case BT_INTEGER:
+ if (mpz_sgn (op2->value.integer) == 0)
+ {
+ rc = ARITH_DIV0;
+ break;
+ }
+
+ mpz_tdiv_q (result->value.integer, op1->value.integer,
+ op2->value.integer);
+ break;
+
+ case BT_REAL:
+ if (mpf_sgn (op2->value.real) == 0)
+ {
+ rc = ARITH_DIV0;
+ break;
+ }
+
+ mpf_div (result->value.real, op1->value.real, op2->value.real);
+ break;
+
+ case BT_COMPLEX:
+ if (mpf_sgn (op2->value.complex.r) == 0
+ && mpf_sgn (op2->value.complex.i) == 0)
+ {
+ rc = ARITH_DIV0;
+ break;
+ }
+
+ mpf_init (x);
+ mpf_init (y);
+ mpf_init (div);
+
+ mpf_mul (x, op2->value.complex.r, op2->value.complex.r);
+ mpf_mul (y, op2->value.complex.i, op2->value.complex.i);
+ mpf_add (div, x, y);
+
+ mpf_mul (x, op1->value.complex.r, op2->value.complex.r);
+ mpf_mul (y, op1->value.complex.i, op2->value.complex.i);
+ mpf_add (result->value.complex.r, x, y);
+ mpf_div (result->value.complex.r, result->value.complex.r, div);
+
+ mpf_mul (x, op1->value.complex.i, op2->value.complex.r);
+ mpf_mul (y, op1->value.complex.r, op2->value.complex.i);
+ mpf_sub (result->value.complex.i, x, y);
+ mpf_div (result->value.complex.i, result->value.complex.i, div);
+
+ mpf_clear (x);
+ mpf_clear (y);
+ mpf_clear (div);
+
+ break;
+
+ default:
+ gfc_internal_error ("gfc_arith_divide(): Bad basic type");
+ }
+
+ if (rc == ARITH_OK)
+ rc = gfc_range_check (result);
+
+ if (rc != ARITH_OK)
+ gfc_free_expr (result);
+ else
+ *resultp = result;
+
+ return rc;
+}
+
+
+/* Compute the reciprocal of a complex number (guaranteed nonzero). */
+
+static void
+complex_reciprocal (gfc_expr * op)
+{
+ mpf_t mod, a, result_r, result_i;
+
+ mpf_init (mod);
+ mpf_init (a);
+
+ mpf_mul (mod, op->value.complex.r, op->value.complex.r);
+ mpf_mul (a, op->value.complex.i, op->value.complex.i);
+ mpf_add (mod, mod, a);
+
+ mpf_init (result_r);
+ mpf_div (result_r, op->value.complex.r, mod);
+
+ mpf_init (result_i);
+ mpf_neg (result_i, op->value.complex.i);
+ mpf_div (result_i, result_i, mod);
+
+ mpf_set (op->value.complex.r, result_r);
+ mpf_set (op->value.complex.i, result_i);
+
+ mpf_clear (result_r);
+ mpf_clear (result_i);
+
+ mpf_clear (mod);
+ mpf_clear (a);
+}
+
+
+/* Raise a complex number to positive power. */
+
+static void
+complex_pow_ui (gfc_expr * base, int power, gfc_expr * result)
+{
+ mpf_t temp_r, temp_i, a;
+
+ mpf_set_ui (result->value.complex.r, 1);
+ mpf_set_ui (result->value.complex.i, 0);
+
+ mpf_init (temp_r);
+ mpf_init (temp_i);
+ mpf_init (a);
+
+ for (; power > 0; power--)
+ {
+ mpf_mul (temp_r, base->value.complex.r, result->value.complex.r);
+ mpf_mul (a, base->value.complex.i, result->value.complex.i);
+ mpf_sub (temp_r, temp_r, a);
+
+ mpf_mul (temp_i, base->value.complex.r, result->value.complex.i);
+ mpf_mul (a, base->value.complex.i, result->value.complex.r);
+ mpf_add (temp_i, temp_i, a);
+
+ mpf_set (result->value.complex.r, temp_r);
+ mpf_set (result->value.complex.i, temp_i);
+ }
+
+ mpf_clear (temp_r);
+ mpf_clear (temp_i);
+ mpf_clear (a);
+}
+
+
+/* Raise a number to an integer power. */
+
+static arith
+gfc_arith_power (gfc_expr * op1, gfc_expr * op2, gfc_expr ** resultp)
+{
+ int power, apower;
+ gfc_expr *result;
+ mpz_t unity_z;
+ mpf_t unity_f;
+ arith rc;
+
+ rc = ARITH_OK;
+
+ if (gfc_extract_int (op2, &power) != NULL)
+ gfc_internal_error ("gfc_arith_power(): Bad exponent");
+
+ result = gfc_constant_result (op1->ts.type, op1->ts.kind, &op1->where);
+
+ if (power == 0)
+ { /* Handle something to the zeroth power */
+ switch (op1->ts.type)
+ {
+ case BT_INTEGER:
+ if (mpz_sgn (op1->value.integer) == 0)
+ rc = ARITH_0TO0;
+ else
+ mpz_set_ui (result->value.integer, 1);
+
+ break;
+
+ case BT_REAL:
+ if (mpf_sgn (op1->value.real) == 0)
+ rc = ARITH_0TO0;
+ else
+ mpf_set_ui (result->value.real, 1);
+
+ break;
+
+ case BT_COMPLEX:
+ if (mpf_sgn (op1->value.complex.r) == 0
+ && mpf_sgn (op1->value.complex.i) == 0)
+ rc = ARITH_0TO0;
+ else
+ {
+ mpf_set_ui (result->value.complex.r, 1);
+ mpf_set_ui (result->value.complex.r, 0);
+ }
+
+ break;
+
+ default:
+ gfc_internal_error ("gfc_arith_power(): Bad base");
+ }
+ }
+
+ if (power != 0)
+ {
+ apower = power;
+ if (power < 0)
+ apower = -power;
+
+ switch (op1->ts.type)
+ {
+ case BT_INTEGER:
+ mpz_pow_ui (result->value.integer, op1->value.integer, apower);
+
+ if (power < 0)
+ {
+ mpz_init_set_ui (unity_z, 1);
+ mpz_tdiv_q (result->value.integer, unity_z,
+ result->value.integer);
+ mpz_clear (unity_z);
+ }
+
+ break;
+
+ case BT_REAL:
+ mpf_pow_ui (result->value.real, op1->value.real, apower);
+
+ if (power < 0)
+ {
+ mpf_init_set_ui (unity_f, 1);
+ mpf_div (result->value.real, unity_f, result->value.real);
+ mpf_clear (unity_f);
+ }
+
+ break;
+
+ case BT_COMPLEX:
+ complex_pow_ui (op1, apower, result);
+ if (power < 0)
+ complex_reciprocal (result);
+
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (rc == ARITH_OK)
+ rc = gfc_range_check (result);
+
+ if (rc != ARITH_OK)
+ gfc_free_expr (result);
+ else
+ *resultp = result;
+
+ return rc;
+}
+
+
+/* Concatenate two string constants. */
+
+static arith
+gfc_arith_concat (gfc_expr * op1, gfc_expr * op2, gfc_expr ** resultp)
+{
+ gfc_expr *result;
+ int len;
+
+ result = gfc_constant_result (BT_CHARACTER, gfc_default_character_kind (),
+ &op1->where);
+
+ len = op1->value.character.length + op2->value.character.length;
+
+ result->value.character.string = gfc_getmem (len + 1);
+ result->value.character.length = len;
+
+ memcpy (result->value.character.string, op1->value.character.string,
+ op1->value.character.length);
+
+ memcpy (result->value.character.string + op1->value.character.length,
+ op2->value.character.string, op2->value.character.length);
+
+ result->value.character.string[len] = '\0';
+
+ *resultp = result;
+
+ return ARITH_OK;
+}
+
+
+/* Comparison operators. Assumes that the two expression nodes
+ contain two constants of the same type. */
+
+int
+gfc_compare_expr (gfc_expr * op1, gfc_expr * op2)
+{
+ int rc;
+
+ switch (op1->ts.type)
+ {
+ case BT_INTEGER:
+ rc = mpz_cmp (op1->value.integer, op2->value.integer);
+ break;
+
+ case BT_REAL:
+ rc = mpf_cmp (op1->value.real, op2->value.real);
+ break;
+
+ case BT_CHARACTER:
+ rc = gfc_compare_string (op1, op2, NULL);
+ break;
+
+ case BT_LOGICAL:
+ rc = ((!op1->value.logical && op2->value.logical)
+ || (op1->value.logical && !op2->value.logical));
+ break;
+
+ default:
+ gfc_internal_error ("gfc_compare_expr(): Bad basic type");
+ }
+
+ return rc;
+}
+
+
+/* Compare a pair of complex numbers. Naturally, this is only for
+ equality/nonequality. */
+
+static int
+compare_complex (gfc_expr * op1, gfc_expr * op2)
+{
+
+ return (mpf_cmp (op1->value.complex.r, op2->value.complex.r) == 0
+ && mpf_cmp (op1->value.complex.i, op2->value.complex.i) == 0);
+}
+
+
+/* Given two constant strings and the inverse collating sequence,
+ compare the strings. We return -1 for a<b, 0 for a==b and 1 for
+ a>b. If the xcoll_table is NULL, we use the processor's default
+ collating sequence. */
+
+int
+gfc_compare_string (gfc_expr * a, gfc_expr * b, const int *xcoll_table)
+{
+ int len, alen, blen, i, ac, bc;
+
+ alen = a->value.character.length;
+ blen = b->value.character.length;
+
+ len = (alen > blen) ? alen : blen;
+
+ for (i = 0; i < len; i++)
+ {
+ ac = (i < alen) ? a->value.character.string[i] : ' ';
+ bc = (i < blen) ? b->value.character.string[i] : ' ';
+
+ if (xcoll_table != NULL)
+ {
+ ac = xcoll_table[ac];
+ bc = xcoll_table[bc];
+ }
+
+ if (ac < bc)
+ return -1;
+ if (ac > bc)
+ return 1;
+ }
+
+ /* Strings are equal */
+
+ return 0;
+}
+
+
+/* Specific comparison subroutines. */
+
+static arith
+gfc_arith_eq (gfc_expr * op1, gfc_expr * op2, gfc_expr ** resultp)
+{
+ gfc_expr *result;
+
+ result = gfc_constant_result (BT_LOGICAL, gfc_default_logical_kind (),
+ &op1->where);
+ result->value.logical = (op1->ts.type == BT_COMPLEX) ?
+ compare_complex (op1, op2) : (gfc_compare_expr (op1, op2) == 0);
+
+ *resultp = result;
+ return ARITH_OK;
+}
+
+
+static arith
+gfc_arith_ne (gfc_expr * op1, gfc_expr * op2, gfc_expr ** resultp)
+{
+ gfc_expr *result;
+
+ result = gfc_constant_result (BT_LOGICAL, gfc_default_logical_kind (),
+ &op1->where);
+ result->value.logical = (op1->ts.type == BT_COMPLEX) ?
+ !compare_complex (op1, op2) : (gfc_compare_expr (op1, op2) != 0);
+
+ *resultp = result;
+ return ARITH_OK;
+}
+
+
+static arith
+gfc_arith_gt (gfc_expr * op1, gfc_expr * op2, gfc_expr ** resultp)
+{
+ gfc_expr *result;
+
+ result = gfc_constant_result (BT_LOGICAL, gfc_default_logical_kind (),
+ &op1->where);
+ result->value.logical = (gfc_compare_expr (op1, op2) > 0);
+ *resultp = result;
+
+ return ARITH_OK;
+}
+
+
+static arith
+gfc_arith_ge (gfc_expr * op1, gfc_expr * op2, gfc_expr ** resultp)
+{
+ gfc_expr *result;
+
+ result = gfc_constant_result (BT_LOGICAL, gfc_default_logical_kind (),
+ &op1->where);
+ result->value.logical = (gfc_compare_expr (op1, op2) >= 0);
+ *resultp = result;
+
+ return ARITH_OK;
+}
+
+
+static arith
+gfc_arith_lt (gfc_expr * op1, gfc_expr * op2, gfc_expr ** resultp)
+{
+ gfc_expr *result;
+
+ result = gfc_constant_result (BT_LOGICAL, gfc_default_logical_kind (),
+ &op1->where);
+ result->value.logical = (gfc_compare_expr (op1, op2) < 0);
+ *resultp = result;
+
+ return ARITH_OK;
+}
+
+
+static arith
+gfc_arith_le (gfc_expr * op1, gfc_expr * op2, gfc_expr ** resultp)
+{
+ gfc_expr *result;
+
+ result = gfc_constant_result (BT_LOGICAL, gfc_default_logical_kind (),
+ &op1->where);
+ result->value.logical = (gfc_compare_expr (op1, op2) <= 0);
+ *resultp = result;
+
+ return ARITH_OK;
+}
+
+
+static arith
+reduce_unary (arith (*eval) (gfc_expr *, gfc_expr **), gfc_expr * op,
+ gfc_expr ** result)
+{
+ gfc_constructor *c, *head;
+ gfc_expr *r;
+ arith rc;
+
+ if (op->expr_type == EXPR_CONSTANT)
+ return eval (op, result);
+
+ rc = ARITH_OK;
+ head = gfc_copy_constructor (op->value.constructor);
+
+ for (c = head; c; c = c->next)
+ {
+ rc = eval (c->expr, &r);
+ if (rc != ARITH_OK)
+ break;
+
+ gfc_replace_expr (c->expr, r);
+ }
+
+ if (rc != ARITH_OK)
+ gfc_free_constructor (head);
+ else
+ {
+ r = gfc_get_expr ();
+ r->expr_type = EXPR_ARRAY;
+ r->value.constructor = head;
+ r->shape = gfc_copy_shape (op->shape, op->rank);
+
+ r->ts = head->expr->ts;
+ r->where = op->where;
+ r->rank = op->rank;
+
+ *result = r;
+ }
+
+ return rc;
+}
+
+
+static arith
+reduce_binary_ac (arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **),
+ gfc_expr * op1, gfc_expr * op2,
+ gfc_expr ** result)
+{
+ gfc_constructor *c, *head;
+ gfc_expr *r;
+ arith rc;
+
+ head = gfc_copy_constructor (op1->value.constructor);
+ rc = ARITH_OK;
+
+ for (c = head; c; c = c->next)
+ {
+ rc = eval (c->expr, op2, &r);
+ if (rc != ARITH_OK)
+ break;
+
+ gfc_replace_expr (c->expr, r);
+ }
+
+ if (rc != ARITH_OK)
+ gfc_free_constructor (head);
+ else
+ {
+ r = gfc_get_expr ();
+ r->expr_type = EXPR_ARRAY;
+ r->value.constructor = head;
+ r->shape = gfc_copy_shape (op1->shape, op1->rank);
+
+ r->ts = head->expr->ts;
+ r->where = op1->where;
+ r->rank = op1->rank;
+
+ *result = r;
+ }
+
+ return rc;
+}
+
+
+static arith
+reduce_binary_ca (arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **),
+ gfc_expr * op1, gfc_expr * op2,
+ gfc_expr ** result)
+{
+ gfc_constructor *c, *head;
+ gfc_expr *r;
+ arith rc;
+
+ head = gfc_copy_constructor (op2->value.constructor);
+ rc = ARITH_OK;
+
+ for (c = head; c; c = c->next)
+ {
+ rc = eval (op1, c->expr, &r);
+ if (rc != ARITH_OK)
+ break;
+
+ gfc_replace_expr (c->expr, r);
+ }
+
+ if (rc != ARITH_OK)
+ gfc_free_constructor (head);
+ else
+ {
+ r = gfc_get_expr ();
+ r->expr_type = EXPR_ARRAY;
+ r->value.constructor = head;
+ r->shape = gfc_copy_shape (op2->shape, op2->rank);
+
+ r->ts = head->expr->ts;
+ r->where = op2->where;
+ r->rank = op2->rank;
+
+ *result = r;
+ }
+
+ return rc;
+}
+
+
+static arith
+reduce_binary_aa (arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **),
+ gfc_expr * op1, gfc_expr * op2,
+ gfc_expr ** result)
+{
+ gfc_constructor *c, *d, *head;
+ gfc_expr *r;
+ arith rc;
+
+ head = gfc_copy_constructor (op1->value.constructor);
+
+ rc = ARITH_OK;
+ d = op2->value.constructor;
+
+ if (gfc_check_conformance ("Elemental binary operation", op1, op2)
+ != SUCCESS)
+ rc = ARITH_INCOMMENSURATE;
+ else
+ {
+
+ for (c = head; c; c = c->next, d = d->next)
+ {
+ if (d == NULL)
+ {
+ rc = ARITH_INCOMMENSURATE;
+ break;
+ }
+
+ rc = eval (c->expr, d->expr, &r);
+ if (rc != ARITH_OK)
+ break;
+
+ gfc_replace_expr (c->expr, r);
+ }
+
+ if (d != NULL)
+ rc = ARITH_INCOMMENSURATE;
+ }
+
+ if (rc != ARITH_OK)
+ gfc_free_constructor (head);
+ else
+ {
+ r = gfc_get_expr ();
+ r->expr_type = EXPR_ARRAY;
+ r->value.constructor = head;
+ r->shape = gfc_copy_shape (op1->shape, op1->rank);
+
+ r->ts = head->expr->ts;
+ r->where = op1->where;
+ r->rank = op1->rank;
+
+ *result = r;
+ }
+
+ return rc;
+}
+
+
+static arith
+reduce_binary (arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **),
+ gfc_expr * op1, gfc_expr * op2,
+ gfc_expr ** result)
+{
+
+ if (op1->expr_type == EXPR_CONSTANT && op2->expr_type == EXPR_CONSTANT)
+ return eval (op1, op2, result);
+
+ if (op1->expr_type == EXPR_CONSTANT && op2->expr_type == EXPR_ARRAY)
+ return reduce_binary_ca (eval, op1, op2, result);
+
+ if (op1->expr_type == EXPR_ARRAY && op2->expr_type == EXPR_CONSTANT)
+ return reduce_binary_ac (eval, op1, op2, result);
+
+ return reduce_binary_aa (eval, op1, op2, result);
+}
+
+
+typedef union
+{
+ arith (*f2)(gfc_expr *, gfc_expr **);
+ arith (*f3)(gfc_expr *, gfc_expr *, gfc_expr **);
+}
+eval_f;
+
+/* High level arithmetic subroutines. These subroutines go into
+ eval_intrinsic(), which can do one of several things to its
+ operands. If the operands are incompatible with the intrinsic
+ operation, we return a node pointing to the operands and hope that
+ an operator interface is found during resolution.
+
+ If the operands are compatible and are constants, then we try doing
+ the arithmetic. We also handle the cases where either or both
+ operands are array constructors. */
+
+static gfc_expr *
+eval_intrinsic (gfc_intrinsic_op operator,
+ eval_f eval, gfc_expr * op1, gfc_expr * op2)
+{
+ gfc_expr temp, *result;
+ int unary;
+ arith rc;
+
+ gfc_clear_ts (&temp.ts);
+
+ switch (operator)
+ {
+ case INTRINSIC_NOT: /* Logical unary */
+ if (op1->ts.type != BT_LOGICAL)
+ goto runtime;
+
+ temp.ts.type = BT_LOGICAL;
+ temp.ts.kind = gfc_default_logical_kind ();
+
+ unary = 1;
+ break;
+
+ /* Logical binary operators */
+ case INTRINSIC_OR:
+ case INTRINSIC_AND:
+ case INTRINSIC_NEQV:
+ case INTRINSIC_EQV:
+ if (op1->ts.type != BT_LOGICAL || op2->ts.type != BT_LOGICAL)
+ goto runtime;
+
+ temp.ts.type = BT_LOGICAL;
+ temp.ts.kind = gfc_default_logical_kind ();
+
+ unary = 0;
+ break;
+
+ case INTRINSIC_UPLUS:
+ case INTRINSIC_UMINUS: /* Numeric unary */
+ if (!gfc_numeric_ts (&op1->ts))
+ goto runtime;
+
+ temp.ts = op1->ts;
+
+ unary = 1;
+ break;
+
+ case INTRINSIC_GE:
+ case INTRINSIC_LT: /* Additional restrictions */
+ case INTRINSIC_LE: /* for ordering relations. */
+ case INTRINSIC_GT:
+ if (op1->ts.type == BT_COMPLEX || op2->ts.type == BT_COMPLEX)
+ {
+ temp.ts.type = BT_LOGICAL;
+ temp.ts.kind = gfc_default_logical_kind();
+ goto runtime;
+ }
+
+ /* else fall through */
+
+ case INTRINSIC_EQ:
+ case INTRINSIC_NE:
+ if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER)
+ {
+ unary = 0;
+ temp.ts.type = BT_LOGICAL;
+ temp.ts.kind = gfc_default_logical_kind();
+ break;
+ }
+
+ /* else fall through */
+
+ case INTRINSIC_PLUS:
+ case INTRINSIC_MINUS:
+ case INTRINSIC_TIMES:
+ case INTRINSIC_DIVIDE:
+ case INTRINSIC_POWER: /* Numeric binary */
+ if (!gfc_numeric_ts (&op1->ts) || !gfc_numeric_ts (&op2->ts))
+ goto runtime;
+
+ /* Insert any necessary type conversions to make the operands compatible. */
+
+ temp.expr_type = EXPR_OP;
+ gfc_clear_ts (&temp.ts);
+ temp.operator = operator;
+
+ temp.op1 = op1;
+ temp.op2 = op2;
+
+ gfc_type_convert_binary (&temp);
+
+ if (operator == INTRINSIC_EQ || operator == INTRINSIC_NE
+ || operator == INTRINSIC_GE || operator == INTRINSIC_GT
+ || operator == INTRINSIC_LE || operator == INTRINSIC_LT)
+ {
+ temp.ts.type = BT_LOGICAL;
+ temp.ts.kind = gfc_default_logical_kind ();
+ }
+
+ unary = 0;
+ break;
+
+ case INTRINSIC_CONCAT: /* Character binary */
+ if (op1->ts.type != BT_CHARACTER || op2->ts.type != BT_CHARACTER)
+ goto runtime;
+
+ temp.ts.type = BT_CHARACTER;
+ temp.ts.kind = gfc_default_character_kind ();
+
+ unary = 0;
+ break;
+
+ case INTRINSIC_USER:
+ goto runtime;
+
+ default:
+ gfc_internal_error ("eval_intrinsic(): Bad operator");
+ }
+
+ /* Try to combine the operators. */
+ if (operator == INTRINSIC_POWER && op2->ts.type != BT_INTEGER)
+ goto runtime;
+
+ if (op1->expr_type != EXPR_CONSTANT
+ && (op1->expr_type != EXPR_ARRAY
+ || !gfc_is_constant_expr (op1)
+ || !gfc_expanded_ac (op1)))
+ goto runtime;
+
+ if (op2 != NULL
+ && op2->expr_type != EXPR_CONSTANT
+ && (op2->expr_type != EXPR_ARRAY
+ || !gfc_is_constant_expr (op2)
+ || !gfc_expanded_ac (op2)))
+ goto runtime;
+
+ if (unary)
+ rc = reduce_unary (eval.f2, op1, &result);
+ else
+ rc = reduce_binary (eval.f3, op1, op2, &result);
+
+ if (rc != ARITH_OK)
+ { /* Something went wrong */
+ gfc_error ("%s at %L", gfc_arith_error (rc), &op1->where);
+ return NULL;
+ }
+
+ gfc_free_expr (op1);
+ gfc_free_expr (op2);
+ return result;
+
+runtime:
+ /* Create a run-time expression */
+ result = gfc_get_expr ();
+ result->ts = temp.ts;
+
+ result->expr_type = EXPR_OP;
+ result->operator = operator;
+
+ result->op1 = op1;
+ result->op2 = op2;
+
+ result->where = op1->where;
+
+ return result;
+}
+
+
+/* Modify type of expression for zero size array. */
+static gfc_expr *
+eval_type_intrinsic0 (gfc_intrinsic_op operator, gfc_expr *op)
+{
+ if (op == NULL)
+ gfc_internal_error("eval_type_intrinsic0(): op NULL");
+
+ switch(operator)
+ {
+ case INTRINSIC_GE:
+ case INTRINSIC_LT:
+ case INTRINSIC_LE:
+ case INTRINSIC_GT:
+ case INTRINSIC_EQ:
+ case INTRINSIC_NE:
+ op->ts.type = BT_LOGICAL;
+ op->ts.kind = gfc_default_logical_kind();
+ break;
+
+ default:
+ break;
+ }
+
+ return op;
+}
+
+
+/* Return nonzero if the expression is a zero size array. */
+
+static int
+gfc_zero_size_array (gfc_expr * e)
+{
+
+ if (e->expr_type != EXPR_ARRAY)
+ return 0;
+
+ return e->value.constructor == NULL;
+}
+
+
+/* Reduce a binary expression where at least one of the operands
+ involves a zero-length array. Returns NULL if neither of the
+ operands is a zero-length array. */
+
+static gfc_expr *
+reduce_binary0 (gfc_expr * op1, gfc_expr * op2)
+{
+
+ if (gfc_zero_size_array (op1))
+ {
+ gfc_free_expr (op2);
+ return op1;
+ }
+
+ if (gfc_zero_size_array (op2))
+ {
+ gfc_free_expr (op1);
+ return op2;
+ }
+
+ return NULL;
+}
+
+
+static gfc_expr *
+eval_intrinsic_f2 (gfc_intrinsic_op operator,
+ arith (*eval) (gfc_expr *, gfc_expr **),
+ gfc_expr * op1, gfc_expr * op2)
+{
+ gfc_expr *result;
+ eval_f f;
+
+ if (op2 == NULL)
+ {
+ if (gfc_zero_size_array (op1))
+ return eval_type_intrinsic0(operator, op1);
+ }
+ else
+ {
+ result = reduce_binary0 (op1, op2);
+ if (result != NULL)
+ return eval_type_intrinsic0(operator, result);
+ }
+
+ f.f2 = eval;
+ return eval_intrinsic (operator, f, op1, op2);
+}
+
+
+static gfc_expr *
+eval_intrinsic_f3 (gfc_intrinsic_op operator,
+ arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **),
+ gfc_expr * op1, gfc_expr * op2)
+{
+ gfc_expr *result;
+ eval_f f;
+
+ result = reduce_binary0 (op1, op2);
+ if (result != NULL)
+ return eval_type_intrinsic0(operator, result);
+
+ f.f3 = eval;
+ return eval_intrinsic (operator, f, op1, op2);
+}
+
+
+
+gfc_expr *
+gfc_uplus (gfc_expr * op)
+{
+ return eval_intrinsic_f2 (INTRINSIC_UPLUS, gfc_arith_uplus, op, NULL);
+}
+
+gfc_expr *
+gfc_uminus (gfc_expr * op)
+{
+ return eval_intrinsic_f2 (INTRINSIC_UMINUS, gfc_arith_uminus, op, NULL);
+}
+
+gfc_expr *
+gfc_add (gfc_expr * op1, gfc_expr * op2)
+{
+ return eval_intrinsic_f3 (INTRINSIC_PLUS, gfc_arith_plus, op1, op2);
+}
+
+gfc_expr *
+gfc_subtract (gfc_expr * op1, gfc_expr * op2)
+{
+ return eval_intrinsic_f3 (INTRINSIC_MINUS, gfc_arith_minus, op1, op2);
+}
+
+gfc_expr *
+gfc_multiply (gfc_expr * op1, gfc_expr * op2)
+{
+ return eval_intrinsic_f3 (INTRINSIC_TIMES, gfc_arith_times, op1, op2);
+}
+
+gfc_expr *
+gfc_divide (gfc_expr * op1, gfc_expr * op2)
+{
+ return eval_intrinsic_f3 (INTRINSIC_DIVIDE, gfc_arith_divide, op1, op2);
+}
+
+gfc_expr *
+gfc_power (gfc_expr * op1, gfc_expr * op2)
+{
+ return eval_intrinsic_f3 (INTRINSIC_POWER, gfc_arith_power, op1, op2);
+}
+
+gfc_expr *
+gfc_concat (gfc_expr * op1, gfc_expr * op2)
+{
+ return eval_intrinsic_f3 (INTRINSIC_CONCAT, gfc_arith_concat, op1, op2);
+}
+
+gfc_expr *
+gfc_and (gfc_expr * op1, gfc_expr * op2)
+{
+ return eval_intrinsic_f3 (INTRINSIC_AND, gfc_arith_and, op1, op2);
+}
+
+gfc_expr *
+gfc_or (gfc_expr * op1, gfc_expr * op2)
+{
+ return eval_intrinsic_f3 (INTRINSIC_OR, gfc_arith_or, op1, op2);
+}
+
+gfc_expr *
+gfc_not (gfc_expr * op1)
+{
+ return eval_intrinsic_f2 (INTRINSIC_NOT, gfc_arith_not, op1, NULL);
+}
+
+gfc_expr *
+gfc_eqv (gfc_expr * op1, gfc_expr * op2)
+{
+ return eval_intrinsic_f3 (INTRINSIC_EQV, gfc_arith_eqv, op1, op2);
+}
+
+gfc_expr *
+gfc_neqv (gfc_expr * op1, gfc_expr * op2)
+{
+ return eval_intrinsic_f3 (INTRINSIC_NEQV, gfc_arith_neqv, op1, op2);
+}
+
+gfc_expr *
+gfc_eq (gfc_expr * op1, gfc_expr * op2)
+{
+ return eval_intrinsic_f3 (INTRINSIC_EQ, gfc_arith_eq, op1, op2);
+}
+
+gfc_expr *
+gfc_ne (gfc_expr * op1, gfc_expr * op2)
+{
+ return eval_intrinsic_f3 (INTRINSIC_NE, gfc_arith_ne, op1, op2);
+}
+
+gfc_expr *
+gfc_gt (gfc_expr * op1, gfc_expr * op2)
+{
+ return eval_intrinsic_f3 (INTRINSIC_GT, gfc_arith_gt, op1, op2);
+}
+
+gfc_expr *
+gfc_ge (gfc_expr * op1, gfc_expr * op2)
+{
+ return eval_intrinsic_f3 (INTRINSIC_GE, gfc_arith_ge, op1, op2);
+}
+
+gfc_expr *
+gfc_lt (gfc_expr * op1, gfc_expr * op2)
+{
+ return eval_intrinsic_f3 (INTRINSIC_LT, gfc_arith_lt, op1, op2);
+}
+
+gfc_expr *
+gfc_le (gfc_expr * op1, gfc_expr * op2)
+{
+ return eval_intrinsic_f3 (INTRINSIC_LE, gfc_arith_le, op1, op2);
+}
+
+
+/* Convert an integer string to an expression node. */
+
+gfc_expr *
+gfc_convert_integer (const char *buffer, int kind, int radix, locus * where)
+{
+ gfc_expr *e;
+ const char *t;
+
+ e = gfc_constant_result (BT_INTEGER, kind, where);
+ /* a leading plus is allowed, but not by mpz_set_str */
+ if (buffer[0] == '+')
+ t = buffer + 1;
+ else
+ t = buffer;
+ mpz_set_str (e->value.integer, t, radix);
+
+ return e;
+}
+
+
+/* Convert a real string to an expression node. */
+
+gfc_expr *
+gfc_convert_real (const char *buffer, int kind, locus * where)
+{
+ gfc_expr *e;
+ const char *t;
+
+ e = gfc_constant_result (BT_REAL, kind, where);
+ /* a leading plus is allowed, but not by mpf_set_str */
+ if (buffer[0] == '+')
+ t = buffer + 1;
+ else
+ t = buffer;
+ mpf_set_str (e->value.real, t, 10);
+
+ return e;
+}
+
+
+/* Convert a pair of real, constant expression nodes to a single
+ complex expression node. */
+
+gfc_expr *
+gfc_convert_complex (gfc_expr * real, gfc_expr * imag, int kind)
+{
+ gfc_expr *e;
+
+ e = gfc_constant_result (BT_COMPLEX, kind, &real->where);
+ mpf_set (e->value.complex.r, real->value.real);
+ mpf_set (e->value.complex.i, imag->value.real);
+
+ return e;
+}
+
+
+/******* Simplification of intrinsic functions with constant arguments *****/
+
+
+/* Deal with an arithmetic error. */
+
+static void
+arith_error (arith rc, gfc_typespec * from, gfc_typespec * to, locus * where)
+{
+
+ gfc_error ("%s converting %s to %s at %L", gfc_arith_error (rc),
+ gfc_typename (from), gfc_typename (to), where);
+
+ /* TODO: Do something about the error, ie underflow rounds to 0,
+ throw exception, return NaN, etc. */
+}
+
+/* Convert integers to integers. */
+
+gfc_expr *
+gfc_int2int (gfc_expr * src, int kind)
+{
+ gfc_expr *result;
+ arith rc;
+
+ result = gfc_constant_result (BT_INTEGER, kind, &src->where);
+
+ mpz_set (result->value.integer, src->value.integer);
+
+ if ((rc = gfc_check_integer_range (result->value.integer, kind))
+ != ARITH_OK)
+ {
+ arith_error (rc, &src->ts, &result->ts, &src->where);
+ gfc_free_expr (result);
+ return NULL;
+ }
+
+ return result;
+}
+
+
+/* Convert integers to reals. */
+
+gfc_expr *
+gfc_int2real (gfc_expr * src, int kind)
+{
+ gfc_expr *result;
+ arith rc;
+
+ result = gfc_constant_result (BT_REAL, kind, &src->where);
+
+ mpf_set_z (result->value.real, src->value.integer);
+
+ if ((rc = gfc_check_real_range (result->value.real, kind)) != ARITH_OK)
+ {
+ arith_error (rc, &src->ts, &result->ts, &src->where);
+ gfc_free_expr (result);
+ return NULL;
+ }
+
+ return result;
+}
+
+
+/* Convert default integer to default complex. */
+
+gfc_expr *
+gfc_int2complex (gfc_expr * src, int kind)
+{
+ gfc_expr *result;
+ arith rc;
+
+ result = gfc_constant_result (BT_COMPLEX, kind, &src->where);
+
+ mpf_set_z (result->value.complex.r, src->value.integer);
+ mpf_set_ui (result->value.complex.i, 0);
+
+ if ((rc = gfc_check_real_range (result->value.complex.i, kind)) != ARITH_OK)
+ {
+ arith_error (rc, &src->ts, &result->ts, &src->where);
+ gfc_free_expr (result);
+ return NULL;
+ }
+
+ return result;
+}
+
+
+/* Convert default real to default integer. */
+
+gfc_expr *
+gfc_real2int (gfc_expr * src, int kind)
+{
+ gfc_expr *result;
+ arith rc;
+
+ result = gfc_constant_result (BT_INTEGER, kind, &src->where);
+
+ mpz_set_f (result->value.integer, src->value.real);
+
+ if ((rc = gfc_check_integer_range (result->value.integer, kind))
+ != ARITH_OK)
+ {
+ arith_error (rc, &src->ts, &result->ts, &src->where);
+ gfc_free_expr (result);
+ return NULL;
+ }
+
+ return result;
+}
+
+
+/* Convert real to real. */
+
+gfc_expr *
+gfc_real2real (gfc_expr * src, int kind)
+{
+ gfc_expr *result;
+ arith rc;
+
+ result = gfc_constant_result (BT_REAL, kind, &src->where);
+
+ mpf_set (result->value.real, src->value.real);
+
+ if ((rc = gfc_check_real_range (result->value.real, kind)) != ARITH_OK)
+ {
+ arith_error (rc, &src->ts, &result->ts, &src->where);
+ gfc_free_expr (result);
+ return NULL;
+ }
+
+ return result;
+}
+
+
+/* Convert real to complex. */
+
+gfc_expr *
+gfc_real2complex (gfc_expr * src, int kind)
+{
+ gfc_expr *result;
+ arith rc;
+
+ result = gfc_constant_result (BT_COMPLEX, kind, &src->where);
+
+ mpf_set (result->value.complex.r, src->value.real);
+ mpf_set_ui (result->value.complex.i, 0);
+
+ if ((rc = gfc_check_real_range (result->value.complex.i, kind)) != ARITH_OK)
+ {
+ arith_error (rc, &src->ts, &result->ts, &src->where);
+ gfc_free_expr (result);
+ return NULL;
+ }
+
+ return result;
+}
+
+
+/* Convert complex to integer. */
+
+gfc_expr *
+gfc_complex2int (gfc_expr * src, int kind)
+{
+ gfc_expr *result;
+ arith rc;
+
+ result = gfc_constant_result (BT_INTEGER, kind, &src->where);
+
+ mpz_set_f (result->value.integer, src->value.complex.r);
+
+ if ((rc = gfc_check_integer_range (result->value.integer, kind))
+ != ARITH_OK)
+ {
+ arith_error (rc, &src->ts, &result->ts, &src->where);
+ gfc_free_expr (result);
+ return NULL;
+ }
+
+ return result;
+}
+
+
+/* Convert complex to real. */
+
+gfc_expr *
+gfc_complex2real (gfc_expr * src, int kind)
+{
+ gfc_expr *result;
+ arith rc;
+
+ result = gfc_constant_result (BT_REAL, kind, &src->where);
+
+ mpf_set (result->value.real, src->value.complex.r);
+
+ if ((rc = gfc_check_real_range (result->value.real, kind)) != ARITH_OK)
+ {
+ arith_error (rc, &src->ts, &result->ts, &src->where);
+ gfc_free_expr (result);
+ return NULL;
+ }
+
+ return result;
+}
+
+
+/* Convert complex to complex. */
+
+gfc_expr *
+gfc_complex2complex (gfc_expr * src, int kind)
+{
+ gfc_expr *result;
+ arith rc;
+
+ result = gfc_constant_result (BT_COMPLEX, kind, &src->where);
+
+ mpf_set (result->value.complex.r, src->value.complex.r);
+ mpf_set (result->value.complex.i, src->value.complex.i);
+
+ if ((rc = gfc_check_real_range (result->value.complex.r, kind)) != ARITH_OK
+ || (rc =
+ gfc_check_real_range (result->value.complex.i, kind)) != ARITH_OK)
+ {
+ arith_error (rc, &src->ts, &result->ts, &src->where);
+ gfc_free_expr (result);
+ return NULL;
+ }
+
+ return result;
+}
+
+
+/* Logical kind conversion. */
+
+gfc_expr *
+gfc_log2log (gfc_expr * src, int kind)
+{
+ gfc_expr *result;
+
+ result = gfc_constant_result (BT_LOGICAL, kind, &src->where);
+ result->value.logical = src->value.logical;
+
+ return result;
+}
diff --git a/gcc/fortran/arith.h b/gcc/fortran/arith.h
new file mode 100644
index 00000000000..a1fdb1afd6b
--- /dev/null
+++ b/gcc/fortran/arith.h
@@ -0,0 +1,90 @@
+/* Compiler arithmetic header.
+ Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+ Contributed by Steven Bosscher
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#ifndef GFC_ARITH_H
+#define GFC_ARITH_H
+
+#include "gfortran.h"
+
+/* Constants calculated during initialization. */
+extern mpf_t pi, half_pi, two_pi, e;
+
+/* Calculate mathematically interesting functions. */
+void natural_logarithm (mpf_t *, mpf_t *);
+void common_logarithm (mpf_t *, mpf_t *);
+void exponential (mpf_t *, mpf_t *);
+void sine (mpf_t *, mpf_t *);
+void cosine (mpf_t *, mpf_t *);
+void arctangent (mpf_t *, mpf_t *);
+void arctangent2 (mpf_t *, mpf_t *, mpf_t *);
+void hypercos (mpf_t *, mpf_t *);
+void hypersine (mpf_t *, mpf_t *);
+
+/* Return a constant result of a given type and kind, with locus. */
+gfc_expr *gfc_constant_result (bt, int, locus *);
+
+/* Make sure a gfc_expr expression is within its allowed range. Checks
+ for overflow and underflow. */
+arith gfc_range_check (gfc_expr *);
+
+int gfc_compare_expr (gfc_expr *, gfc_expr *);
+int gfc_compare_string (gfc_expr *, gfc_expr *, const int *);
+
+/* Constant folding for gfc_expr trees. */
+gfc_expr *gfc_uplus (gfc_expr * op);
+gfc_expr *gfc_uminus (gfc_expr * op);
+gfc_expr *gfc_add (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_subtract (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_multiply (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_divide (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_power (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_concat (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_and (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_or (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_not (gfc_expr *);
+gfc_expr *gfc_eqv (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_neqv (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_eq (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_ne (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_gt (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_ge (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_lt (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_le (gfc_expr *, gfc_expr *);
+
+/* Convert strings to literal constants. */
+gfc_expr *gfc_convert_integer (const char *, int, int, locus *);
+gfc_expr *gfc_convert_real (const char *, int, locus *);
+gfc_expr *gfc_convert_complex (gfc_expr *, gfc_expr *, int);
+
+/* Convert a constant of one kind to another kind. */
+gfc_expr *gfc_int2int (gfc_expr *, int);
+gfc_expr *gfc_int2real (gfc_expr *, int);
+gfc_expr *gfc_int2complex (gfc_expr *, int);
+gfc_expr *gfc_real2int (gfc_expr *, int);
+gfc_expr *gfc_real2real (gfc_expr *, int);
+gfc_expr *gfc_real2complex (gfc_expr *, int);
+gfc_expr *gfc_complex2int (gfc_expr *, int);
+gfc_expr *gfc_complex2real (gfc_expr *, int);
+gfc_expr *gfc_complex2complex (gfc_expr *, int);
+gfc_expr *gfc_log2log (gfc_expr *, int);
+
+#endif /* GFC_ARITH_H */
+
diff --git a/gcc/fortran/array.c b/gcc/fortran/array.c
new file mode 100644
index 00000000000..e2eac02cb76
--- /dev/null
+++ b/gcc/fortran/array.c
@@ -0,0 +1,1973 @@
+/* Array things
+ Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "gfortran.h"
+#include "match.h"
+
+#include <string.h>
+#include <assert.h>
+
+/* This parameter is the size of the largest array constructor that we
+ will expand to an array constructor without iterators.
+ Constructors larger than this will remain in the iterator form. */
+
+#define GFC_MAX_AC_EXPAND 100
+
+
+/**************** Array reference matching subroutines *****************/
+
+/* Copy an array reference structure. */
+
+gfc_array_ref *
+gfc_copy_array_ref (gfc_array_ref * src)
+{
+ gfc_array_ref *dest;
+ int i;
+
+ if (src == NULL)
+ return NULL;
+
+ dest = gfc_get_array_ref ();
+
+ *dest = *src;
+
+ for (i = 0; i < GFC_MAX_DIMENSIONS; i++)
+ {
+ dest->start[i] = gfc_copy_expr (src->start[i]);
+ dest->end[i] = gfc_copy_expr (src->end[i]);
+ dest->stride[i] = gfc_copy_expr (src->stride[i]);
+ }
+
+ dest->offset = gfc_copy_expr (src->offset);
+
+ return dest;
+}
+
+
+/* Match a single dimension of an array reference. This can be a
+ single element or an array section. Any modifications we've made
+ to the ar structure are cleaned up by the caller. If the init
+ is set, we require the subscript to be a valid initialization
+ expression. */
+
+static match
+match_subscript (gfc_array_ref * ar, int init)
+{
+ match m;
+ int i;
+
+ i = ar->dimen;
+
+ ar->c_where[i] = *gfc_current_locus ();
+ ar->start[i] = ar->end[i] = ar->stride[i] = NULL;
+
+ /* We can't be sure of the difference between DIMEN_ELEMENT and
+ DIMEN_VECTOR until we know the type of the element itself at
+ resolution time. */
+
+ ar->dimen_type[i] = DIMEN_UNKNOWN;
+
+ if (gfc_match_char (':') == MATCH_YES)
+ goto end_element;
+
+ /* Get start element. */
+ if (init)
+ m = gfc_match_init_expr (&ar->start[i]);
+ else
+ m = gfc_match_expr (&ar->start[i]);
+
+ if (m == MATCH_NO)
+ gfc_error ("Expected array subscript at %C");
+ if (m != MATCH_YES)
+ return MATCH_ERROR;
+
+ if (gfc_match_char (':') == MATCH_NO)
+ return MATCH_YES;
+
+ /* Get an optional end element. Because we've seen the colon, we
+ definitely have a range along this dimension. */
+end_element:
+ ar->dimen_type[i] = DIMEN_RANGE;
+
+ if (init)
+ m = gfc_match_init_expr (&ar->end[i]);
+ else
+ m = gfc_match_expr (&ar->end[i]);
+
+ if (m == MATCH_ERROR)
+ return MATCH_ERROR;
+
+ /* See if we have an optional stride. */
+ if (gfc_match_char (':') == MATCH_YES)
+ {
+ m = init ? gfc_match_init_expr (&ar->stride[i])
+ : gfc_match_expr (&ar->stride[i]);
+
+ if (m == MATCH_NO)
+ gfc_error ("Expected array subscript stride at %C");
+ if (m != MATCH_YES)
+ return MATCH_ERROR;
+ }
+
+ return MATCH_YES;
+}
+
+
+/* Match an array reference, whether it is the whole array or a
+ particular elements or a section. If init is set, the reference has
+ to consist of init expressions. */
+
+match
+gfc_match_array_ref (gfc_array_ref * ar, gfc_array_spec * as, int init)
+{
+ match m;
+
+ memset (ar, '\0', sizeof (ar));
+
+ ar->where = *gfc_current_locus ();
+ ar->as = as;
+
+ if (gfc_match_char ('(') != MATCH_YES)
+ {
+ ar->type = AR_FULL;
+ ar->dimen = 0;
+ return MATCH_YES;
+ }
+
+ ar->type = AR_UNKNOWN;
+
+ for (ar->dimen = 0; ar->dimen < GFC_MAX_DIMENSIONS; ar->dimen++)
+ {
+ m = match_subscript (ar, init);
+ if (m == MATCH_ERROR)
+ goto error;
+
+ if (gfc_match_char (')') == MATCH_YES)
+ goto matched;
+
+ if (gfc_match_char (',') != MATCH_YES)
+ {
+ gfc_error ("Invalid form of array reference at %C");
+ goto error;
+ }
+ }
+
+ gfc_error ("Array reference at %C cannot have more than "
+ stringize (GFC_MAX_DIMENSIONS) " dimensions");
+
+error:
+ return MATCH_ERROR;
+
+matched:
+ ar->dimen++;
+
+ return MATCH_YES;
+}
+
+
+/************** Array specification matching subroutines ***************/
+
+/* Free all of the expressions associated with array bounds
+ specifications. */
+
+void
+gfc_free_array_spec (gfc_array_spec * as)
+{
+ int i;
+
+ if (as == NULL)
+ return;
+
+ for (i = 0; i < as->rank; i++)
+ {
+ gfc_free_expr (as->lower[i]);
+ gfc_free_expr (as->upper[i]);
+ }
+
+ gfc_free (as);
+}
+
+
+/* Take an array bound, resolves the expression, that make up the
+ shape and check associated constraints. */
+
+static try
+resolve_array_bound (gfc_expr * e, int check_constant)
+{
+
+ if (e == NULL)
+ return SUCCESS;
+
+ if (gfc_resolve_expr (e) == FAILURE
+ || gfc_specification_expr (e) == FAILURE)
+ return FAILURE;
+
+ if (check_constant && gfc_is_constant_expr (e) == 0)
+ {
+ gfc_error ("Variable '%s' at %L in this context must be constant",
+ e->symtree->n.sym->name, &e->where);
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Takes an array specification, resolves the expressions that make up
+ the shape and make sure everything is integral. */
+
+try
+gfc_resolve_array_spec (gfc_array_spec * as, int check_constant)
+{
+ gfc_expr *e;
+ int i;
+
+ if (as == NULL)
+ return SUCCESS;
+
+ for (i = 0; i < as->rank; i++)
+ {
+ e = as->lower[i];
+ if (resolve_array_bound (e, check_constant) == FAILURE)
+ return FAILURE;
+
+ e = as->upper[i];
+ if (resolve_array_bound (e, check_constant) == FAILURE)
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Match a single array element specification. The return values as
+ well as the upper and lower bounds of the array spec are filled
+ in according to what we see on the input. The caller makes sure
+ individual specifications make sense as a whole.
+
+
+ Parsed Lower Upper Returned
+ ------------------------------------
+ : NULL NULL AS_DEFERRED (*)
+ x 1 x AS_EXPLICIT
+ x: x NULL AS_ASSUMED_SHAPE
+ x:y x y AS_EXPLICIT
+ x:* x NULL AS_ASSUMED_SIZE
+ * 1 NULL AS_ASSUMED_SIZE
+
+ (*) For non-pointer dummy arrays this is AS_ASSUMED_SHAPE. This
+ is fixed during the resolution of formal interfaces.
+
+ Anything else AS_UNKNOWN. */
+
+static array_type
+match_array_element_spec (gfc_array_spec * as)
+{
+ gfc_expr **upper, **lower;
+ match m;
+
+ lower = &as->lower[as->rank - 1];
+ upper = &as->upper[as->rank - 1];
+
+ if (gfc_match_char ('*') == MATCH_YES)
+ {
+ *lower = gfc_int_expr (1);
+ return AS_ASSUMED_SIZE;
+ }
+
+ if (gfc_match_char (':') == MATCH_YES)
+ return AS_DEFERRED;
+
+ m = gfc_match_expr (upper);
+ if (m == MATCH_NO)
+ gfc_error ("Expected expression in array specification at %C");
+ if (m != MATCH_YES)
+ return AS_UNKNOWN;
+
+ if (gfc_match_char (':') == MATCH_NO)
+ {
+ *lower = gfc_int_expr (1);
+ return AS_EXPLICIT;
+ }
+
+ *lower = *upper;
+ *upper = NULL;
+
+ if (gfc_match_char ('*') == MATCH_YES)
+ return AS_ASSUMED_SIZE;
+
+ m = gfc_match_expr (upper);
+ if (m == MATCH_ERROR)
+ return AS_UNKNOWN;
+ if (m == MATCH_NO)
+ return AS_ASSUMED_SHAPE;
+
+ return AS_EXPLICIT;
+}
+
+
+/* Matches an array specification, incidentally figuring out what sort
+ it is. */
+
+match
+gfc_match_array_spec (gfc_array_spec ** asp)
+{
+ array_type current_type;
+ gfc_array_spec *as;
+ int i;
+
+ if (gfc_match_char ('(') != MATCH_YES)
+ {
+ *asp = NULL;
+ return MATCH_NO;
+ }
+
+ as = gfc_get_array_spec ();
+
+ for (i = 0; i < GFC_MAX_DIMENSIONS; i++)
+ {
+ as->lower[i] = NULL;
+ as->upper[i] = NULL;
+ }
+
+ as->rank = 1;
+
+ for (;;)
+ {
+ current_type = match_array_element_spec (as);
+
+ if (as->rank == 1)
+ {
+ if (current_type == AS_UNKNOWN)
+ goto cleanup;
+ as->type = current_type;
+ }
+ else
+ switch (as->type)
+ { /* See how current spec meshes with the existing */
+ case AS_UNKNOWN:
+ goto cleanup;
+
+ case AS_EXPLICIT:
+ if (current_type == AS_ASSUMED_SIZE)
+ {
+ as->type = AS_ASSUMED_SIZE;
+ break;
+ }
+
+ if (current_type == AS_EXPLICIT)
+ break;
+
+ gfc_error
+ ("Bad array specification for an explicitly shaped array"
+ " at %C");
+
+ goto cleanup;
+
+ case AS_ASSUMED_SHAPE:
+ if ((current_type == AS_ASSUMED_SHAPE)
+ || (current_type == AS_DEFERRED))
+ break;
+
+ gfc_error
+ ("Bad array specification for assumed shape array at %C");
+ goto cleanup;
+
+ case AS_DEFERRED:
+ if (current_type == AS_DEFERRED)
+ break;
+
+ if (current_type == AS_ASSUMED_SHAPE)
+ {
+ as->type = AS_ASSUMED_SHAPE;
+ break;
+ }
+
+ gfc_error ("Bad specification for deferred shape array at %C");
+ goto cleanup;
+
+ case AS_ASSUMED_SIZE:
+ gfc_error ("Bad specification for assumed size array at %C");
+ goto cleanup;
+ }
+
+ if (gfc_match_char (')') == MATCH_YES)
+ break;
+
+ if (gfc_match_char (',') != MATCH_YES)
+ {
+ gfc_error ("Expected another dimension in array declaration at %C");
+ goto cleanup;
+ }
+
+ if (as->rank >= GFC_MAX_DIMENSIONS)
+ {
+ gfc_error ("Array specification at %C has more than "
+ stringize (GFC_MAX_DIMENSIONS) " dimensions");
+ goto cleanup;
+ }
+
+ as->rank++;
+ }
+
+ /* If a lower bounds of an assumed shape array is blank, put in one. */
+ if (as->type == AS_ASSUMED_SHAPE)
+ {
+ for (i = 0; i < as->rank; i++)
+ {
+ if (as->lower[i] == NULL)
+ as->lower[i] = gfc_int_expr (1);
+ }
+ }
+ *asp = as;
+ return MATCH_YES;
+
+cleanup:
+ /* Something went wrong. */
+ gfc_free_array_spec (as);
+ return MATCH_ERROR;
+}
+
+
+/* Given a symbol and an array specification, modify the symbol to
+ have that array specification. The error locus is needed in case
+ something goes wrong. On failure, the caller must free the spec. */
+
+try
+gfc_set_array_spec (gfc_symbol * sym, gfc_array_spec * as, locus * error_loc)
+{
+
+ if (as == NULL)
+ return SUCCESS;
+
+ if (gfc_add_dimension (&sym->attr, error_loc) == FAILURE)
+ return FAILURE;
+
+ sym->as = as;
+
+ return SUCCESS;
+}
+
+
+/* Copy an array specification. */
+
+gfc_array_spec *
+gfc_copy_array_spec (gfc_array_spec * src)
+{
+ gfc_array_spec *dest;
+ int i;
+
+ if (src == NULL)
+ return NULL;
+
+ dest = gfc_get_array_spec ();
+
+ *dest = *src;
+
+ for (i = 0; i < dest->rank; i++)
+ {
+ dest->lower[i] = gfc_copy_expr (dest->lower[i]);
+ dest->upper[i] = gfc_copy_expr (dest->upper[i]);
+ }
+
+ return dest;
+}
+
+/* Returns nonzero if the two expressions are equal. Only handles integer
+ constants. */
+
+static int
+compare_bounds (gfc_expr * bound1, gfc_expr * bound2)
+{
+ if (bound1 == NULL || bound2 == NULL
+ || bound1->expr_type != EXPR_CONSTANT
+ || bound2->expr_type != EXPR_CONSTANT
+ || bound1->ts.type != BT_INTEGER
+ || bound2->ts.type != BT_INTEGER)
+ gfc_internal_error ("gfc_compare_array_spec(): Array spec clobbered");
+
+ if (mpz_cmp (bound1->value.integer, bound2->value.integer) == 0)
+ return 1;
+ else
+ return 0;
+}
+
+/* Compares two array specifications. They must be constant or deferred
+ shape. */
+
+int
+gfc_compare_array_spec (gfc_array_spec * as1, gfc_array_spec * as2)
+{
+ int i;
+
+ if (as1 == NULL && as2 == NULL)
+ return 1;
+
+ if (as1 == NULL || as2 == NULL)
+ return 0;
+
+ if (as1->rank != as2->rank)
+ return 0;
+
+ if (as1->rank == 0)
+ return 1;
+
+ if (as1->type != as2->type)
+ return 0;
+
+ if (as1->type == AS_EXPLICIT)
+ for (i = 0; i < as1->rank; i++)
+ {
+ if (compare_bounds (as1->lower[i], as2->lower[i]) == 0)
+ return 0;
+
+ if (compare_bounds (as1->upper[i], as2->upper[i]) == 0)
+ return 0;
+ }
+
+ return 1;
+}
+
+
+/****************** Array constructor functions ******************/
+
+/* Start an array constructor. The constructor starts with zero
+ elements and should be appended to by gfc_append_constructor(). */
+
+gfc_expr *
+gfc_start_constructor (bt type, int kind, locus * where)
+{
+ gfc_expr *result;
+
+ result = gfc_get_expr ();
+
+ result->expr_type = EXPR_ARRAY;
+ result->rank = 1;
+
+ result->ts.type = type;
+ result->ts.kind = kind;
+ result->where = *where;
+ return result;
+}
+
+
+/* Given an array constructor expression, append the new expression
+ node onto the constructor. */
+
+void
+gfc_append_constructor (gfc_expr * base, gfc_expr * new)
+{
+ gfc_constructor *c;
+
+ if (base->value.constructor == NULL)
+ base->value.constructor = c = gfc_get_constructor ();
+ else
+ {
+ c = base->value.constructor;
+ while (c->next)
+ c = c->next;
+
+ c->next = gfc_get_constructor ();
+ c = c->next;
+ }
+
+ c->expr = new;
+
+ if (new->ts.type != base->ts.type || new->ts.kind != base->ts.kind)
+ gfc_internal_error ("gfc_append_constructor(): New node has wrong kind");
+}
+
+
+/* Given an array constructor expression, insert the new expression's
+ constructor onto the base's one according to the offset. */
+
+void
+gfc_insert_constructor (gfc_expr * base, gfc_constructor * c1)
+{
+ gfc_constructor *c, *pre;
+ expr_t type;
+
+ type = base->expr_type;
+
+ if (base->value.constructor == NULL)
+ base->value.constructor = c1;
+ else
+ {
+ c = pre = base->value.constructor;
+ while (c)
+ {
+ if (type == EXPR_ARRAY)
+ {
+ if (mpz_cmp (c->n.offset, c1->n.offset) < 0)
+ {
+ pre = c;
+ c = c->next;
+ }
+ else if (mpz_cmp (c->n.offset, c1->n.offset) == 0)
+ {
+ gfc_error ("duplicated initializer");
+ break;
+ }
+ else
+ break;
+ }
+ else
+ {
+ pre = c;
+ c = c->next;
+ }
+ }
+
+ if (pre != c)
+ {
+ pre->next = c1;
+ c1->next = c;
+ }
+ else
+ {
+ c1->next = c;
+ base->value.constructor = c1;
+ }
+ }
+}
+
+
+/* Get a new constructor. */
+
+gfc_constructor *
+gfc_get_constructor (void)
+{
+ gfc_constructor *c;
+
+ c = gfc_getmem (sizeof(gfc_constructor));
+ c->expr = NULL;
+ c->iterator = NULL;
+ c->next = NULL;
+ mpz_init_set_si (c->n.offset, 0);
+ mpz_init_set_si (c->repeat, 0);
+ return c;
+}
+
+
+/* Free chains of gfc_constructor structures. */
+
+void
+gfc_free_constructor (gfc_constructor * p)
+{
+ gfc_constructor *next;
+
+ if (p == NULL)
+ return;
+
+ for (; p; p = next)
+ {
+ next = p->next;
+
+ if (p->expr)
+ gfc_free_expr (p->expr);
+ if (p->iterator != NULL)
+ gfc_free_iterator (p->iterator, 1);
+ mpz_clear (p->n.offset);
+ mpz_clear (p->repeat);
+ gfc_free (p);
+ }
+}
+
+
+/* Given an expression node that might be an array constructor and a
+ symbol, make sure that no iterators in this or child constructors
+ use the symbol as an implied-DO iterator. Returns nonzero if a
+ duplicate was found. */
+
+static int
+check_duplicate_iterator (gfc_constructor * c, gfc_symbol * master)
+{
+ gfc_expr *e;
+
+ for (; c; c = c->next)
+ {
+ e = c->expr;
+
+ if (e->expr_type == EXPR_ARRAY
+ && check_duplicate_iterator (e->value.constructor, master))
+ return 1;
+
+ if (c->iterator == NULL)
+ continue;
+
+ if (c->iterator->var->symtree->n.sym == master)
+ {
+ gfc_error
+ ("DO-iterator '%s' at %L is inside iterator of the same name",
+ master->name, &c->where);
+
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+
+/* Forward declaration because these functions are mutually recursive. */
+static match match_array_cons_element (gfc_constructor **);
+
+/* Match a list of array elements. */
+
+static match
+match_array_list (gfc_constructor ** result)
+{
+ gfc_constructor *p, *head, *tail, *new;
+ gfc_iterator iter;
+ locus old_loc;
+ gfc_expr *e;
+ match m;
+ int n;
+
+ old_loc = *gfc_current_locus ();
+
+ if (gfc_match_char ('(') == MATCH_NO)
+ return MATCH_NO;
+
+ memset (&iter, '\0', sizeof (gfc_iterator));
+ head = NULL;
+
+ m = match_array_cons_element (&head);
+ if (m != MATCH_YES)
+ goto cleanup;
+
+ tail = head;
+
+ if (gfc_match_char (',') != MATCH_YES)
+ {
+ m = MATCH_NO;
+ goto cleanup;
+ }
+
+ for (n = 1;; n++)
+ {
+ m = gfc_match_iterator (&iter, 0);
+ if (m == MATCH_YES)
+ break;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ m = match_array_cons_element (&new);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ {
+ if (n > 2)
+ goto syntax;
+ m = MATCH_NO;
+ goto cleanup; /* Could be a complex constant */
+ }
+
+ tail->next = new;
+ tail = new;
+
+ if (gfc_match_char (',') != MATCH_YES)
+ {
+ if (n > 2)
+ goto syntax;
+ m = MATCH_NO;
+ goto cleanup;
+ }
+ }
+
+ if (gfc_match_char (')') != MATCH_YES)
+ goto syntax;
+
+ if (check_duplicate_iterator (head, iter.var->symtree->n.sym))
+ {
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ e = gfc_get_expr ();
+ e->expr_type = EXPR_ARRAY;
+ e->where = old_loc;
+ e->value.constructor = head;
+
+ p = gfc_get_constructor ();
+ p->where = *gfc_current_locus ();
+ p->iterator = gfc_get_iterator ();
+ *p->iterator = iter;
+
+ p->expr = e;
+ *result = p;
+
+ return MATCH_YES;
+
+syntax:
+ gfc_error ("Syntax error in array constructor at %C");
+ m = MATCH_ERROR;
+
+cleanup:
+ gfc_free_constructor (head);
+ gfc_free_iterator (&iter, 0);
+ gfc_set_locus (&old_loc);
+ return m;
+}
+
+
+/* Match a single element of an array constructor, which can be a
+ single expression or a list of elements. */
+
+static match
+match_array_cons_element (gfc_constructor ** result)
+{
+ gfc_constructor *p;
+ gfc_expr *expr;
+ match m;
+
+ m = match_array_list (result);
+ if (m != MATCH_NO)
+ return m;
+
+ m = gfc_match_expr (&expr);
+ if (m != MATCH_YES)
+ return m;
+
+ p = gfc_get_constructor ();
+ p->where = *gfc_current_locus ();
+ p->expr = expr;
+
+ *result = p;
+ return MATCH_YES;
+}
+
+
+/* Match an array constructor. */
+
+match
+gfc_match_array_constructor (gfc_expr ** result)
+{
+ gfc_constructor *head, *tail, *new;
+ gfc_expr *expr;
+ locus where;
+ match m;
+
+ if (gfc_match (" (/") == MATCH_NO)
+ return MATCH_NO;
+
+ where = *gfc_current_locus ();
+ head = tail = NULL;
+
+ if (gfc_match (" /)") == MATCH_YES)
+ goto empty; /* Special case */
+
+ for (;;)
+ {
+ m = match_array_cons_element (&new);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ goto syntax;
+
+ if (head == NULL)
+ head = new;
+ else
+ tail->next = new;
+
+ tail = new;
+
+ if (gfc_match_char (',') == MATCH_NO)
+ break;
+ }
+
+ if (gfc_match (" /)") == MATCH_NO)
+ goto syntax;
+
+empty:
+ expr = gfc_get_expr ();
+
+ expr->expr_type = EXPR_ARRAY;
+
+ expr->value.constructor = head;
+ /* Size must be calculated at resolution time. */
+
+ expr->where = where;
+ expr->rank = 1;
+
+ *result = expr;
+ return MATCH_YES;
+
+syntax:
+ gfc_error ("Syntax error in array constructor at %C");
+
+cleanup:
+ gfc_free_constructor (head);
+ return MATCH_ERROR;
+}
+
+
+
+/************** Check array constructors for correctness **************/
+
+/* Given an expression, compare it's type with the type of the current
+ constructor. Returns nonzero if an error was issued. The
+ cons_state variable keeps track of whether the type of the
+ constructor being read or resolved is known to be good, bad or just
+ starting out. */
+
+static gfc_typespec constructor_ts;
+static enum
+{ CONS_START, CONS_GOOD, CONS_BAD }
+cons_state;
+
+static int
+check_element_type (gfc_expr * expr)
+{
+
+ if (cons_state == CONS_BAD)
+ return 0; /* Supress further errors */
+
+ if (cons_state == CONS_START)
+ {
+ if (expr->ts.type == BT_UNKNOWN)
+ cons_state = CONS_BAD;
+ else
+ {
+ cons_state = CONS_GOOD;
+ constructor_ts = expr->ts;
+ }
+
+ return 0;
+ }
+
+ if (gfc_compare_types (&constructor_ts, &expr->ts))
+ return 0;
+
+ gfc_error ("Element in %s array constructor at %L is %s",
+ gfc_typename (&constructor_ts), &expr->where,
+ gfc_typename (&expr->ts));
+
+ cons_state = CONS_BAD;
+ return 1;
+}
+
+
+/* Recursive work function for gfc_check_constructor_type(). */
+
+static try
+check_constructor_type (gfc_constructor * c)
+{
+ gfc_expr *e;
+
+ for (; c; c = c->next)
+ {
+ e = c->expr;
+
+ if (e->expr_type == EXPR_ARRAY)
+ {
+ if (check_constructor_type (e->value.constructor) == FAILURE)
+ return FAILURE;
+
+ continue;
+ }
+
+ if (check_element_type (e))
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Check that all elements of an array constructor are the same type.
+ On FAILURE, an error has been generated. */
+
+try
+gfc_check_constructor_type (gfc_expr * e)
+{
+ try t;
+
+ cons_state = CONS_START;
+ gfc_clear_ts (&constructor_ts);
+
+ t = check_constructor_type (e->value.constructor);
+ if (t == SUCCESS && e->ts.type == BT_UNKNOWN)
+ e->ts = constructor_ts;
+
+ return t;
+}
+
+
+
+typedef struct cons_stack
+{
+ gfc_iterator *iterator;
+ struct cons_stack *previous;
+}
+cons_stack;
+
+static cons_stack *base;
+
+static try check_constructor (gfc_constructor *, try (*)(gfc_expr *));
+
+/* Check an EXPR_VARIABLE expression in a constructor to make sure
+ that that variable is an iteration variables. */
+
+try
+gfc_check_iter_variable (gfc_expr * expr)
+{
+
+ gfc_symbol *sym;
+ cons_stack *c;
+
+ sym = expr->symtree->n.sym;
+
+ for (c = base; c; c = c->previous)
+ if (sym == c->iterator->var->symtree->n.sym)
+ return SUCCESS;
+
+ return FAILURE;
+}
+
+
+/* Recursive work function for gfc_check_constructor(). This amounts
+ to calling the check function for each expression in the
+ constructor, giving variables with the names of iterators a pass. */
+
+static try
+check_constructor (gfc_constructor * c, try (*check_function) (gfc_expr *))
+{
+ cons_stack element;
+ gfc_expr *e;
+ try t;
+
+ for (; c; c = c->next)
+ {
+ e = c->expr;
+
+ if (e->expr_type != EXPR_ARRAY)
+ {
+ if ((*check_function) (e) == FAILURE)
+ return FAILURE;
+ continue;
+ }
+
+ element.previous = base;
+ element.iterator = c->iterator;
+
+ base = &element;
+ t = check_constructor (e->value.constructor, check_function);
+ base = element.previous;
+
+ if (t == FAILURE)
+ return FAILURE;
+ }
+
+ /* Nothing went wrong, so all OK. */
+ return SUCCESS;
+}
+
+
+/* Checks a constructor to see if it is a particular kind of
+ expression -- specification, restricted, or initialization as
+ determined by the check_function. */
+
+try
+gfc_check_constructor (gfc_expr * expr, try (*check_function) (gfc_expr *))
+{
+ cons_stack *base_save;
+ try t;
+
+ base_save = base;
+ base = NULL;
+
+ t = check_constructor (expr->value.constructor, check_function);
+ base = base_save;
+
+ return t;
+}
+
+
+
+/**************** Simplification of array constructors ****************/
+
+iterator_stack *iter_stack;
+
+typedef struct
+{
+ gfc_constructor *new_head, *new_tail;
+ int extract_count, extract_n;
+ gfc_expr *extracted;
+ mpz_t *count;
+
+ mpz_t *offset;
+ gfc_component *component;
+ mpz_t *repeat;
+
+ try (*expand_work_function) (gfc_expr *);
+}
+expand_info;
+
+static expand_info current_expand;
+
+static try expand_constructor (gfc_constructor *);
+
+
+/* Work function that counts the number of elements present in a
+ constructor. */
+
+static try
+count_elements (gfc_expr * e)
+{
+ mpz_t result;
+
+ if (e->rank == 0)
+ mpz_add_ui (*current_expand.count, *current_expand.count, 1);
+ else
+ {
+ if (gfc_array_size (e, &result) == FAILURE)
+ {
+ gfc_free_expr (e);
+ return FAILURE;
+ }
+
+ mpz_add (*current_expand.count, *current_expand.count, result);
+ mpz_clear (result);
+ }
+
+ gfc_free_expr (e);
+ return SUCCESS;
+}
+
+
+/* Work function that extracts a particular element from an array
+ constructor, freeing the rest. */
+
+static try
+extract_element (gfc_expr * e)
+{
+
+ if (e->rank != 0)
+ { /* Something unextractable */
+ gfc_free_expr (e);
+ return FAILURE;
+ }
+
+ if (current_expand.extract_count == current_expand.extract_n)
+ current_expand.extracted = e;
+ else
+ gfc_free_expr (e);
+
+ current_expand.extract_count++;
+ return SUCCESS;
+}
+
+
+/* Work function that constructs a new constructor out of the old one,
+ stringing new elements together. */
+
+static try
+expand (gfc_expr * e)
+{
+
+ if (current_expand.new_head == NULL)
+ current_expand.new_head = current_expand.new_tail =
+ gfc_get_constructor ();
+ else
+ {
+ current_expand.new_tail->next = gfc_get_constructor ();
+ current_expand.new_tail = current_expand.new_tail->next;
+ }
+
+ current_expand.new_tail->where = e->where;
+ current_expand.new_tail->expr = e;
+
+ mpz_set (current_expand.new_tail->n.offset, *current_expand.offset);
+ current_expand.new_tail->n.component = current_expand.component;
+ mpz_set (current_expand.new_tail->repeat, *current_expand.repeat);
+ return SUCCESS;
+}
+
+
+/* Given an initialization expression that is a variable reference,
+ substitute the current value of the iteration variable. */
+
+void
+gfc_simplify_iterator_var (gfc_expr * e)
+{
+ iterator_stack *p;
+
+ for (p = iter_stack; p; p = p->prev)
+ if (e->symtree == p->variable)
+ break;
+
+ if (p == NULL)
+ return; /* Variable not found */
+
+ gfc_replace_expr (e, gfc_int_expr (0));
+
+ mpz_set (e->value.integer, p->value);
+
+ return;
+}
+
+
+/* Expand an expression with that is inside of a constructor,
+ recursing into other constructors if present. */
+
+static try
+expand_expr (gfc_expr * e)
+{
+
+ if (e->expr_type == EXPR_ARRAY)
+ return expand_constructor (e->value.constructor);
+
+ e = gfc_copy_expr (e);
+
+ if (gfc_simplify_expr (e, 1) == FAILURE)
+ {
+ gfc_free_expr (e);
+ return FAILURE;
+ }
+
+ return current_expand.expand_work_function (e);
+}
+
+
+static try
+expand_iterator (gfc_constructor * c)
+{
+ gfc_expr *start, *end, *step;
+ iterator_stack frame;
+ mpz_t trip;
+ try t;
+
+ end = step = NULL;
+
+ t = FAILURE;
+
+ mpz_init (trip);
+ mpz_init (frame.value);
+
+ start = gfc_copy_expr (c->iterator->start);
+ if (gfc_simplify_expr (start, 1) == FAILURE)
+ goto cleanup;
+
+ if (start->expr_type != EXPR_CONSTANT || start->ts.type != BT_INTEGER)
+ goto cleanup;
+
+ end = gfc_copy_expr (c->iterator->end);
+ if (gfc_simplify_expr (end, 1) == FAILURE)
+ goto cleanup;
+
+ if (end->expr_type != EXPR_CONSTANT || end->ts.type != BT_INTEGER)
+ goto cleanup;
+
+ step = gfc_copy_expr (c->iterator->step);
+ if (gfc_simplify_expr (step, 1) == FAILURE)
+ goto cleanup;
+
+ if (step->expr_type != EXPR_CONSTANT || step->ts.type != BT_INTEGER)
+ goto cleanup;
+
+ if (mpz_sgn (step->value.integer) == 0)
+ {
+ gfc_error ("Iterator step at %L cannot be zero", &step->where);
+ goto cleanup;
+ }
+
+ /* Calculate the trip count of the loop. */
+ mpz_sub (trip, end->value.integer, start->value.integer);
+ mpz_add (trip, trip, step->value.integer);
+ mpz_tdiv_q (trip, trip, step->value.integer);
+
+ mpz_set (frame.value, start->value.integer);
+
+ frame.prev = iter_stack;
+ frame.variable = c->iterator->var->symtree;
+ iter_stack = &frame;
+
+ while (mpz_sgn (trip) > 0)
+ {
+ if (expand_expr (c->expr) == FAILURE)
+ goto cleanup;
+
+ mpz_add (frame.value, frame.value, step->value.integer);
+ mpz_sub_ui (trip, trip, 1);
+ }
+
+ t = SUCCESS;
+
+cleanup:
+ gfc_free_expr (start);
+ gfc_free_expr (end);
+ gfc_free_expr (step);
+
+ mpz_clear (trip);
+ mpz_clear (frame.value);
+
+ iter_stack = frame.prev;
+
+ return t;
+}
+
+
+/* Expand a constructor into constant constructors without any
+ iterators, calling the work function for each of the expanded
+ expressions. The work function needs to either save or free the
+ passed expression. */
+
+static try
+expand_constructor (gfc_constructor * c)
+{
+ gfc_expr *e;
+
+ for (; c; c = c->next)
+ {
+ if (c->iterator != NULL)
+ {
+ if (expand_iterator (c) == FAILURE)
+ return FAILURE;
+ continue;
+ }
+
+ e = c->expr;
+
+ if (e->expr_type == EXPR_ARRAY)
+ {
+ if (expand_constructor (e->value.constructor) == FAILURE)
+ return FAILURE;
+
+ continue;
+ }
+
+ e = gfc_copy_expr (e);
+ if (gfc_simplify_expr (e, 1) == FAILURE)
+ {
+ gfc_free_expr (e);
+ return FAILURE;
+ }
+ current_expand.offset = &c->n.offset;
+ current_expand.component = c->n.component;
+ current_expand.repeat = &c->repeat;
+ if (current_expand.expand_work_function (e) == FAILURE)
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+
+
+/* Top level subroutine for expanding constructors. We only expand
+ constructor if they are small enough. */
+
+try
+gfc_expand_constructor (gfc_expr * e)
+{
+ expand_info expand_save;
+ gfc_expr *f;
+ try rc;
+
+ f = gfc_get_array_element (e, GFC_MAX_AC_EXPAND);
+ if (f != NULL)
+ {
+ gfc_free_expr (f);
+ return SUCCESS;
+ }
+
+ expand_save = current_expand;
+ current_expand.new_head = current_expand.new_tail = NULL;
+
+ iter_stack = NULL;
+
+ current_expand.expand_work_function = expand;
+
+ if (expand_constructor (e->value.constructor) == FAILURE)
+ {
+ gfc_free_constructor (current_expand.new_head);
+ rc = FAILURE;
+ goto done;
+ }
+
+ gfc_free_constructor (e->value.constructor);
+ e->value.constructor = current_expand.new_head;
+
+ rc = SUCCESS;
+
+done:
+ current_expand = expand_save;
+
+ return rc;
+}
+
+
+/* Work function for checking that an element of a constructor is a
+ constant, after removal of any iteration variables. We return
+ FAILURE if not so. */
+
+static try
+constant_element (gfc_expr * e)
+{
+ int rv;
+
+ rv = gfc_is_constant_expr (e);
+ gfc_free_expr (e);
+
+ return rv ? SUCCESS : FAILURE;
+}
+
+
+/* Given an array constructor, determine if the constructor is
+ constant or not by expanding it and making sure that all elements
+ are constants. This is a bit of a hack since something like (/ (i,
+ i=1,100000000) /) will take a while as* opposed to a more clever
+ function that traverses the expression tree. FIXME. */
+
+int
+gfc_constant_ac (gfc_expr * e)
+{
+ expand_info expand_save;
+ try rc;
+
+ iter_stack = NULL;
+ expand_save = current_expand;
+ current_expand.expand_work_function = constant_element;
+
+ rc = expand_constructor (e->value.constructor);
+
+ current_expand = expand_save;
+ if (rc == FAILURE)
+ return 0;
+
+ return 1;
+}
+
+
+/* Returns nonzero if an array constructor has been completely
+ expanded (no iterators) and zero if iterators are present. */
+
+int
+gfc_expanded_ac (gfc_expr * e)
+{
+ gfc_constructor *p;
+
+ if (e->expr_type == EXPR_ARRAY)
+ for (p = e->value.constructor; p; p = p->next)
+ if (p->iterator != NULL || !gfc_expanded_ac (p->expr))
+ return 0;
+
+ return 1;
+}
+
+
+/*************** Type resolution of array constructors ***************/
+
+/* Recursive array list resolution function. All of the elements must
+ be of the same type. */
+
+static try
+resolve_array_list (gfc_constructor * p)
+{
+ try t;
+
+ t = SUCCESS;
+
+ for (; p; p = p->next)
+ {
+ if (p->iterator != NULL
+ && gfc_resolve_iterator (p->iterator) == FAILURE)
+ t = FAILURE;
+
+ if (gfc_resolve_expr (p->expr) == FAILURE)
+ t = FAILURE;
+ }
+
+ return t;
+}
+
+
+/* Resolve all of the expressions in an array list.
+ TODO: String lengths. */
+
+try
+gfc_resolve_array_constructor (gfc_expr * expr)
+{
+ try t;
+
+ t = resolve_array_list (expr->value.constructor);
+ if (t == SUCCESS)
+ t = gfc_check_constructor_type (expr);
+
+ return t;
+}
+
+
+/* Copy an iterator structure. */
+
+static gfc_iterator *
+copy_iterator (gfc_iterator * src)
+{
+ gfc_iterator *dest;
+
+ if (src == NULL)
+ return NULL;
+
+ dest = gfc_get_iterator ();
+
+ dest->var = gfc_copy_expr (src->var);
+ dest->start = gfc_copy_expr (src->start);
+ dest->end = gfc_copy_expr (src->end);
+ dest->step = gfc_copy_expr (src->step);
+
+ return dest;
+}
+
+
+/* Copy a constructor structure. */
+
+gfc_constructor *
+gfc_copy_constructor (gfc_constructor * src)
+{
+ gfc_constructor *dest;
+ gfc_constructor *tail;
+
+ if (src == NULL)
+ return NULL;
+
+ dest = tail = NULL;
+ while (src)
+ {
+ if (dest == NULL)
+ dest = tail = gfc_get_constructor ();
+ else
+ {
+ tail->next = gfc_get_constructor ();
+ tail = tail->next;
+ }
+ tail->where = src->where;
+ tail->expr = gfc_copy_expr (src->expr);
+ tail->iterator = copy_iterator (src->iterator);
+ mpz_set (tail->n.offset, src->n.offset);
+ tail->n.component = src->n.component;
+ mpz_set (tail->repeat, src->repeat);
+ src = src->next;
+ }
+
+ return dest;
+}
+
+
+/* Given an array expression and an element number (starting at zero),
+ return a pointer to the array element. NULL is returned if the
+ size of the array has been exceeded. The expression node returned
+ remains a part of the array and should not be freed. Access is not
+ efficient at all, but this is another place where things do not
+ have to be particularly fast. */
+
+gfc_expr *
+gfc_get_array_element (gfc_expr * array, int element)
+{
+ expand_info expand_save;
+ gfc_expr *e;
+ try rc;
+
+ expand_save = current_expand;
+ current_expand.extract_n = element;
+ current_expand.expand_work_function = extract_element;
+ current_expand.extracted = NULL;
+ current_expand.extract_count = 0;
+
+ iter_stack = NULL;
+
+ rc = expand_constructor (array->value.constructor);
+ e = current_expand.extracted;
+ current_expand = expand_save;
+
+ if (rc == FAILURE)
+ return NULL;
+
+ return e;
+}
+
+
+/********* Subroutines for determining the size of an array *********/
+
+/* These are needed just to accomodate RESHAPE(). There are no
+ diagnostics here, we just return a negative number if something
+ goes wrong. */
+
+
+/* Get the size of single dimension of an array specification. The
+ array is guaranteed to be one dimensional. */
+
+static try
+spec_dimen_size (gfc_array_spec * as, int dimen, mpz_t * result)
+{
+
+ if (as == NULL)
+ return FAILURE;
+
+ if (dimen < 0 || dimen > as->rank - 1)
+ gfc_internal_error ("spec_dimen_size(): Bad dimension");
+
+ if (as->type != AS_EXPLICIT
+ || as->lower[dimen]->expr_type != EXPR_CONSTANT
+ || as->upper[dimen]->expr_type != EXPR_CONSTANT)
+ return FAILURE;
+
+ mpz_init (*result);
+
+ mpz_sub (*result, as->upper[dimen]->value.integer,
+ as->lower[dimen]->value.integer);
+
+ mpz_add_ui (*result, *result, 1);
+
+ return SUCCESS;
+}
+
+
+try
+spec_size (gfc_array_spec * as, mpz_t * result)
+{
+ mpz_t size;
+ int d;
+
+ mpz_init_set_ui (*result, 1);
+
+ for (d = 0; d < as->rank; d++)
+ {
+ if (spec_dimen_size (as, d, &size) == FAILURE)
+ {
+ mpz_clear (*result);
+ return FAILURE;
+ }
+
+ mpz_mul (*result, *result, size);
+ mpz_clear (size);
+ }
+
+ return SUCCESS;
+}
+
+
+/* Get the number of elements in an array section. */
+
+static try
+ref_dimen_size (gfc_array_ref * ar, int dimen, mpz_t * result)
+{
+ mpz_t upper, lower, stride;
+ try t;
+
+ if (dimen < 0 || ar == NULL || dimen > ar->dimen - 1)
+ gfc_internal_error ("ref_dimen_size(): Bad dimension");
+
+ switch (ar->dimen_type[dimen])
+ {
+ case DIMEN_ELEMENT:
+ mpz_init (*result);
+ mpz_set_ui (*result, 1);
+ t = SUCCESS;
+ break;
+
+ case DIMEN_VECTOR:
+ t = gfc_array_size (ar->start[dimen], result); /* Recurse! */
+ break;
+
+ case DIMEN_RANGE:
+ mpz_init (upper);
+ mpz_init (lower);
+ mpz_init (stride);
+ t = FAILURE;
+
+ if (ar->start[dimen] == NULL)
+ {
+ if (ar->as->lower[dimen] == NULL
+ || ar->as->lower[dimen]->expr_type != EXPR_CONSTANT)
+ goto cleanup;
+ mpz_set (lower, ar->as->lower[dimen]->value.integer);
+ }
+ else
+ {
+ if (ar->start[dimen]->expr_type != EXPR_CONSTANT)
+ goto cleanup;
+ mpz_set (lower, ar->start[dimen]->value.integer);
+ }
+
+ if (ar->end[dimen] == NULL)
+ {
+ if (ar->as->upper[dimen] == NULL
+ || ar->as->upper[dimen]->expr_type != EXPR_CONSTANT)
+ goto cleanup;
+ mpz_set (upper, ar->as->upper[dimen]->value.integer);
+ }
+ else
+ {
+ if (ar->end[dimen]->expr_type != EXPR_CONSTANT)
+ goto cleanup;
+ mpz_set (upper, ar->end[dimen]->value.integer);
+ }
+
+ if (ar->stride[dimen] == NULL)
+ mpz_set_ui (stride, 1);
+ else
+ {
+ if (ar->stride[dimen]->expr_type != EXPR_CONSTANT)
+ goto cleanup;
+ mpz_set (stride, ar->stride[dimen]->value.integer);
+ }
+
+ mpz_init (*result);
+ mpz_sub (*result, upper, lower);
+ mpz_add (*result, *result, stride);
+ mpz_div (*result, *result, stride);
+
+ /* Zero stride caught earlier. */
+ if (mpz_cmp_ui (*result, 0) < 0)
+ mpz_set_ui (*result, 0);
+ t = SUCCESS;
+
+ cleanup:
+ mpz_clear (upper);
+ mpz_clear (lower);
+ mpz_clear (stride);
+ return t;
+
+ default:
+ gfc_internal_error ("ref_dimen_size(): Bad dimen_type");
+ }
+
+ return t;
+}
+
+
+static try
+ref_size (gfc_array_ref * ar, mpz_t * result)
+{
+ mpz_t size;
+ int d;
+
+ mpz_init_set_ui (*result, 1);
+
+ for (d = 0; d < ar->dimen; d++)
+ {
+ if (ref_dimen_size (ar, d, &size) == FAILURE)
+ {
+ mpz_clear (*result);
+ return FAILURE;
+ }
+
+ mpz_mul (*result, *result, size);
+ mpz_clear (size);
+ }
+
+ return SUCCESS;
+}
+
+
+/* Given an array expression and a dimension, figure out how many
+ elements it has along that dimension. Returns SUCCESS if we were
+ able to return a result in the 'result' variable, FAILURE
+ otherwise. */
+
+try
+gfc_array_dimen_size (gfc_expr * array, int dimen, mpz_t * result)
+{
+ gfc_ref *ref;
+ int i;
+
+ if (dimen < 0 || array == NULL || dimen > array->rank - 1)
+ gfc_internal_error ("gfc_array_dimen_size(): Bad dimension");
+
+ switch (array->expr_type)
+ {
+ case EXPR_VARIABLE:
+ case EXPR_FUNCTION:
+ for (ref = array->ref; ref; ref = ref->next)
+ {
+ if (ref->type != REF_ARRAY)
+ continue;
+
+ if (ref->u.ar.type == AR_FULL)
+ return spec_dimen_size (ref->u.ar.as, dimen, result);
+
+ if (ref->u.ar.type == AR_SECTION)
+ {
+ for (i = 0; dimen >= 0; i++)
+ if (ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
+ dimen--;
+
+ return ref_dimen_size (&ref->u.ar, i - 1, result);
+ }
+ }
+
+ if (spec_dimen_size (array->symtree->n.sym->as, dimen, result) == FAILURE)
+ return FAILURE;
+
+ break;
+
+ case EXPR_ARRAY:
+ if (array->shape == NULL) {
+ /* Expressions with rank > 1 should have "shape" properly set */
+ if ( array->rank != 1 )
+ gfc_internal_error ("gfc_array_dimen_size(): Bad EXPR_ARRAY expr");
+ return gfc_array_size(array, result);
+ }
+
+ /* Fall through */
+ default:
+ if (array->shape == NULL)
+ return FAILURE;
+
+ mpz_init_set (*result, array->shape[dimen]);
+
+ break;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Given an array expression, figure out how many elements are in the
+ array. Returns SUCCESS if this is possible, and sets the 'result'
+ variable. Otherwise returns FAILURE. */
+
+try
+gfc_array_size (gfc_expr * array, mpz_t * result)
+{
+ expand_info expand_save;
+ gfc_ref *ref;
+ int i, flag;
+ try t;
+
+ switch (array->expr_type)
+ {
+ case EXPR_ARRAY:
+ flag = gfc_suppress_error;
+ gfc_suppress_error = 1;
+
+ expand_save = current_expand;
+
+ current_expand.count = result;
+ mpz_init_set_ui (*result, 0);
+
+ current_expand.expand_work_function = count_elements;
+ iter_stack = NULL;
+
+ t = expand_constructor (array->value.constructor);
+ gfc_suppress_error = flag;
+
+ if (t == FAILURE)
+ mpz_clear (*result);
+ current_expand = expand_save;
+ return t;
+
+ case EXPR_VARIABLE:
+ for (ref = array->ref; ref; ref = ref->next)
+ {
+ if (ref->type != REF_ARRAY)
+ continue;
+
+ if (ref->u.ar.type == AR_FULL)
+ return spec_size (ref->u.ar.as, result);
+
+ if (ref->u.ar.type == AR_SECTION)
+ return ref_size (&ref->u.ar, result);
+ }
+
+ return spec_size (array->symtree->n.sym->as, result);
+
+
+ default:
+ if (array->rank == 0 || array->shape == NULL)
+ return FAILURE;
+
+ mpz_init_set_ui (*result, 1);
+
+ for (i = 0; i < array->rank; i++)
+ mpz_mul (*result, *result, array->shape[i]);
+
+ break;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Given an array reference, return the shape of the reference in an
+ array of mpz_t integers. */
+
+try
+gfc_array_ref_shape (gfc_array_ref * ar, mpz_t * shape)
+{
+ int d;
+ int i;
+
+ d = 0;
+
+ switch (ar->type)
+ {
+ case AR_FULL:
+ for (; d < ar->as->rank; d++)
+ if (spec_dimen_size (ar->as, d, &shape[d]) == FAILURE)
+ goto cleanup;
+
+ return SUCCESS;
+
+ case AR_SECTION:
+ for (i = 0; i < ar->dimen; i++)
+ {
+ if (ar->dimen_type[i] != DIMEN_ELEMENT)
+ {
+ if (ref_dimen_size (ar, i, &shape[d]) == FAILURE)
+ goto cleanup;
+ d++;
+ }
+ }
+
+ return SUCCESS;
+
+ default:
+ break;
+ }
+
+cleanup:
+ for (d--; d >= 0; d--)
+ mpz_clear (shape[d]);
+
+ return FAILURE;
+}
+
+
+/* Given an array expression, find the array reference structure that
+ characterizes the reference. */
+
+gfc_array_ref *
+gfc_find_array_ref (gfc_expr * e)
+{
+ gfc_ref *ref;
+
+ for (ref = e->ref; ref; ref = ref->next)
+ if (ref->type == REF_ARRAY
+ && (ref->u.ar.type == AR_FULL
+ || ref->u.ar.type == AR_SECTION))
+ break;
+
+ if (ref == NULL)
+ gfc_internal_error ("gfc_find_array_ref(): No ref found");
+
+ return &ref->u.ar;
+}
diff --git a/gcc/fortran/bbt.c b/gcc/fortran/bbt.c
new file mode 100644
index 00000000000..3f01e704212
--- /dev/null
+++ b/gcc/fortran/bbt.c
@@ -0,0 +1,201 @@
+/* Balanced binary trees using treaps.
+ Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* The idea is to balance the tree using pseudorandom numbers. The
+ main constraint on this implementation is that we have several
+ distinct structures that have to be arranged in a binary tree.
+ These structures all contain a BBT_HEADER() in front that gives the
+ treap-related information. The key and value are assumed to reside
+ in the rest of the structure.
+
+ When calling, we are also passed a comparison function that
+ compares two nodes. We don't implement a separate 'find' function
+ here, but rather use separate functions for each variety of tree.
+ We are also restricted to not copy treap structures, which most
+ implementations find convenient, because we otherwise would need to
+ know how long the structure is.
+
+ This implementation is based on Stefan Nilsson's article in the
+ July 1997 Doctor Dobb's Journal, "Treaps in Java". */
+
+#include "config.h"
+#include "gfortran.h"
+
+typedef struct gfc_treap
+{
+ BBT_HEADER (gfc_treap);
+}
+gfc_bbt;
+
+/* Simple linear congruential pseudorandom number generator. The
+ period of this generator is 44071, which is plenty for our
+ purposes. */
+
+static int
+pseudo_random (void)
+{
+ static int x0 = 5341;
+
+ x0 = (22611 * x0 + 10) % 44071;
+ return x0;
+}
+
+
+/* Rotate the treap left. */
+
+static gfc_bbt *
+rotate_left (gfc_bbt * t)
+{
+ gfc_bbt *temp;
+
+ temp = t->right;
+ t->right = t->right->left;
+ temp->left = t;
+
+ return temp;
+}
+
+
+/* Rotate the treap right. */
+
+static gfc_bbt *
+rotate_right (gfc_bbt * t)
+{
+ gfc_bbt *temp;
+
+ temp = t->left;
+ t->left = t->left->right;
+ temp->right = t;
+
+ return temp;
+}
+
+
+/* Recursive insertion function. Returns the updated treap, or
+ aborts if we find a duplicate key. */
+
+static gfc_bbt *
+insert (gfc_bbt * new, gfc_bbt * t, compare_fn compare)
+{
+ int c;
+
+ if (t == NULL)
+ return new;
+
+ c = (*compare) (new, t);
+
+ if (c < 0)
+ {
+ t->left = insert (new, t->left, compare);
+ if (t->priority < t->left->priority)
+ t = rotate_right (t);
+ }
+
+ else if (c > 0)
+ {
+ t->right = insert (new, t->right, compare);
+ if (t->priority < t->right->priority)
+ t = rotate_left (t);
+ }
+
+ else /* if (c == 0) */
+ gfc_internal_error("insert_bbt(): Duplicate key found!");
+
+ return t;
+}
+
+
+/* Given root pointer, a new node and a comparison function, insert
+ the new node into the treap. It is an error to insert a key that
+ already exists. */
+
+void
+gfc_insert_bbt (void *root, void *new, compare_fn compare)
+{
+ gfc_bbt **r, *n;
+
+ r = (gfc_bbt **) root;
+ n = (gfc_bbt *) new;
+
+ n->priority = pseudo_random ();
+ *r = insert (n, *r, compare);
+}
+
+static gfc_bbt *
+delete_root (gfc_bbt * t)
+{
+ gfc_bbt *temp;
+
+ if (t->left == NULL)
+ return t->right;
+ if (t->right == NULL)
+ return t->left;
+
+ if (t->left->priority > t->right->priority)
+ {
+ temp = rotate_right (t);
+ temp->right = delete_root (t);
+ }
+ else
+ {
+ temp = rotate_left (t);
+ temp->left = delete_root (t);
+ }
+
+ return temp;
+}
+
+
+/* Delete an element from a tree. The 'old' value does not
+ necessarily have to point to the element to be deleted, it must
+ just point to a treap structure with the key to be deleted.
+ Returns the new root node of the tree. */
+
+static gfc_bbt *
+delete_treap (gfc_bbt * old, gfc_bbt * t, compare_fn compare)
+{
+ int c;
+
+ if (t == NULL)
+ return NULL;
+
+ c = (*compare) (old, t);
+
+ if (c < 0)
+ t->left = delete_treap (old, t->left, compare);
+ if (c > 0)
+ t->right = delete_treap (old, t->right, compare);
+ if (c == 0)
+ t = delete_root (t);
+
+ return t;
+}
+
+
+void
+gfc_delete_bbt (void *root, void *old, compare_fn compare)
+{
+ gfc_bbt **t;
+
+ t = (gfc_bbt **) root;
+
+ *t = delete_treap ((gfc_bbt *) old, *t, compare);
+}
diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c
new file mode 100644
index 00000000000..703002f0fec
--- /dev/null
+++ b/gcc/fortran/check.c
@@ -0,0 +1,1866 @@
+/* Check functions
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Andy Vaught & Katherine Holcomb
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+/* These functions check to see if an argument list is compatible with
+ a particular intrinsic function or subroutine. Presence of
+ required arguments has already been established, the argument list
+ has been sorted into the right order and has NULL arguments in the
+ correct places for missing optional arguments. */
+
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "config.h"
+#include "system.h"
+#include "flags.h"
+#include "gfortran.h"
+#include "intrinsic.h"
+
+
+/* The fundamental complaint function of this source file. This
+ function can be called in all kinds of ways. */
+
+static void
+must_be (gfc_expr * e, int n, const char *thing)
+{
+
+ gfc_error ("'%s' argument of '%s' intrinsic at %L must be %s",
+ gfc_current_intrinsic_arg[n], gfc_current_intrinsic, &e->where,
+ thing);
+}
+
+
+/* Check the type of an expression. */
+
+static try
+type_check (gfc_expr * e, int n, bt type)
+{
+
+ if (e->ts.type == type)
+ return SUCCESS;
+
+ must_be (e, n, gfc_basic_typename (type));
+
+ return FAILURE;
+}
+
+
+/* Check that the expression is a numeric type. */
+
+static try
+numeric_check (gfc_expr * e, int n)
+{
+
+ if (gfc_numeric_ts (&e->ts))
+ return SUCCESS;
+
+ must_be (e, n, "a numeric type");
+
+ return FAILURE;
+}
+
+
+/* Check that an expression is integer or real. */
+
+static try
+int_or_real_check (gfc_expr * e, int n)
+{
+
+ if (e->ts.type != BT_INTEGER && e->ts.type != BT_REAL)
+ {
+ must_be (e, n, "INTEGER or REAL");
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Check that the expression is an optional constant integer
+ and that it specifies a valid kind for that type. */
+
+static try
+kind_check (gfc_expr * k, int n, bt type)
+{
+ int kind;
+
+ if (k == NULL)
+ return SUCCESS;
+
+ if (type_check (k, n, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (k->expr_type != EXPR_CONSTANT)
+ {
+ must_be (k, n, "a constant");
+ return FAILURE;
+ }
+
+ if (gfc_extract_int (k, &kind) != NULL
+ || gfc_validate_kind (type, kind) == -1)
+ {
+ gfc_error ("Invalid kind for %s at %L", gfc_basic_typename (type),
+ &k->where);
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Make sure the expression is a double precision real. */
+
+static try
+double_check (gfc_expr * d, int n)
+{
+
+ if (type_check (d, n, BT_REAL) == FAILURE)
+ return FAILURE;
+
+ if (d->ts.kind != gfc_default_double_kind ())
+ {
+ must_be (d, n, "double precision");
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Make sure the expression is a logical array. */
+
+static try
+logical_array_check (gfc_expr * array, int n)
+{
+
+ if (array->ts.type != BT_LOGICAL || array->rank == 0)
+ {
+ must_be (array, n, "a logical array");
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Make sure an expression is an array. */
+
+static try
+array_check (gfc_expr * e, int n)
+{
+
+ if (e->rank != 0)
+ return SUCCESS;
+
+ must_be (e, n, "an array");
+
+ return FAILURE;
+}
+
+
+/* Make sure an expression is a scalar. */
+
+static try
+scalar_check (gfc_expr * e, int n)
+{
+
+ if (e->rank == 0)
+ return SUCCESS;
+
+ must_be (e, n, "a scalar");
+
+ return FAILURE;
+}
+
+
+/* Make sure two expression have the same type. */
+
+static try
+same_type_check (gfc_expr * e, int n, gfc_expr * f, int m)
+{
+ char message[100];
+
+ if (gfc_compare_types (&e->ts, &f->ts))
+ return SUCCESS;
+
+ sprintf (message, "the same type and kind as '%s'",
+ gfc_current_intrinsic_arg[n]);
+
+ must_be (f, m, message);
+
+ return FAILURE;
+}
+
+
+/* Make sure that an expression has a certain (nonzero) rank. */
+
+static try
+rank_check (gfc_expr * e, int n, int rank)
+{
+ char message[100];
+
+ if (e->rank == rank)
+ return SUCCESS;
+
+ sprintf (message, "of rank %d", rank);
+
+ must_be (e, n, message);
+
+ return FAILURE;
+}
+
+
+/* Make sure a variable expression is not an optional dummy argument. */
+
+static try
+nonoptional_check (gfc_expr * e, int n)
+{
+
+ if (e->expr_type == EXPR_VARIABLE && e->symtree->n.sym->attr.optional)
+ {
+ gfc_error ("'%s' argument of '%s' intrinsic at %L must not be OPTIONAL",
+ gfc_current_intrinsic_arg[n], gfc_current_intrinsic,
+ &e->where);
+
+ }
+
+ /* TODO: Recursive check on nonoptional variables? */
+
+ return SUCCESS;
+}
+
+
+/* Check that an expression has a particular kind. */
+
+static try
+kind_value_check (gfc_expr * e, int n, int k)
+{
+ char message[100];
+
+ if (e->ts.kind == k)
+ return SUCCESS;
+
+ sprintf (message, "of kind %d", k);
+
+ must_be (e, n, message);
+ return FAILURE;
+}
+
+
+/* Make sure an expression is a variable. */
+
+static try
+variable_check (gfc_expr * e, int n)
+{
+
+ if ((e->expr_type == EXPR_VARIABLE
+ && e->symtree->n.sym->attr.flavor != FL_PARAMETER)
+ || (e->expr_type == EXPR_FUNCTION
+ && e->symtree->n.sym->result == e->symtree->n.sym))
+ return SUCCESS;
+
+ if (e->expr_type == EXPR_VARIABLE
+ && e->symtree->n.sym->attr.intent == INTENT_IN)
+ {
+ gfc_error ("'%s' argument of '%s' intrinsic at %L cannot be INTENT(IN)",
+ gfc_current_intrinsic_arg[n], gfc_current_intrinsic,
+ &e->where);
+ return FAILURE;
+ }
+
+ must_be (e, n, "a variable");
+
+ return FAILURE;
+}
+
+
+/* Check the common DIM parameter for correctness. */
+
+static try
+dim_check (gfc_expr * dim, int n, int optional)
+{
+
+ if (optional)
+ {
+ if (dim == NULL)
+ return SUCCESS;
+
+ if (nonoptional_check (dim, n) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+ }
+
+ if (dim == NULL)
+ {
+ gfc_error ("Missing DIM parameter in intrinsic '%s' at %L",
+ gfc_current_intrinsic, gfc_current_intrinsic_where);
+ return FAILURE;
+ }
+
+ if (type_check (dim, n, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (scalar_check (dim, n) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+/* If a DIM parameter is a constant, make sure that it is greater than
+ zero and less than or equal to the rank of the given array. If
+ allow_assumed is zero then dim must be less than the rank of the array
+ for assumed size arrays. */
+
+static try
+dim_rank_check (gfc_expr * dim, gfc_expr * array, int allow_assumed)
+{
+ gfc_array_ref *ar;
+ int rank;
+
+ if (dim->expr_type != EXPR_CONSTANT || array->expr_type != EXPR_VARIABLE)
+ return SUCCESS;
+
+ ar = gfc_find_array_ref (array);
+ rank = array->rank;
+ if (ar->as->type == AS_ASSUMED_SIZE && !allow_assumed)
+ rank--;
+
+ if (mpz_cmp_ui (dim->value.integer, 1) < 0
+ || mpz_cmp_ui (dim->value.integer, rank) > 0)
+ {
+ gfc_error ("'dim' argument of '%s' intrinsic at %L is not a valid "
+ "dimension index", gfc_current_intrinsic, &dim->where);
+
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+/***** Check functions *****/
+
+/* Check subroutine suitable for intrinsics taking a real argument and
+ a kind argument for the result. */
+
+static try
+check_a_kind (gfc_expr * a, gfc_expr * kind, bt type)
+{
+
+ if (type_check (a, 0, BT_REAL) == FAILURE)
+ return FAILURE;
+ if (kind_check (kind, 1, type) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+/* Check subroutine suitable for ceiling, floor and nint. */
+
+try
+gfc_check_a_ikind (gfc_expr * a, gfc_expr * kind)
+{
+
+ return check_a_kind (a, kind, BT_INTEGER);
+}
+
+/* Check subroutine suitable for aint, anint. */
+
+try
+gfc_check_a_xkind (gfc_expr * a, gfc_expr * kind)
+{
+
+ return check_a_kind (a, kind, BT_REAL);
+}
+
+try
+gfc_check_abs (gfc_expr * a)
+{
+
+ if (numeric_check (a, 0) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_all_any (gfc_expr * mask, gfc_expr * dim)
+{
+
+ if (logical_array_check (mask, 0) == FAILURE)
+ return FAILURE;
+
+ if (dim_check (dim, 1, 1) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_allocated (gfc_expr * array)
+{
+
+ if (variable_check (array, 0) == FAILURE)
+ return FAILURE;
+
+ if (array_check (array, 0) == FAILURE)
+ return FAILURE;
+
+ if (!array->symtree->n.sym->attr.allocatable)
+ {
+ must_be (array, 0, "ALLOCATABLE");
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Common check function where the first argument must be real or
+ integer and the second argument must be the same as the first. */
+
+try
+gfc_check_a_p (gfc_expr * a, gfc_expr * p)
+{
+
+ if (int_or_real_check (a, 0) == FAILURE)
+ return FAILURE;
+
+ if (same_type_check (a, 0, p, 1) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_associated (gfc_expr * pointer, gfc_expr * target)
+{
+ symbol_attribute attr;
+ int i;
+ try t;
+
+ if (variable_check (pointer, 0) == FAILURE)
+ return FAILURE;
+
+ attr = gfc_variable_attr (pointer, NULL);
+ if (!attr.pointer)
+ {
+ must_be (pointer, 0, "a POINTER");
+ return FAILURE;
+ }
+
+ if (target == NULL)
+ return SUCCESS;
+
+ /* Target argument is optional. */
+ if (target->expr_type == EXPR_NULL)
+ {
+ gfc_error ("NULL pointer at %L is not permitted as actual argument "
+ "of '%s' intrinsic function",
+ &target->where, gfc_current_intrinsic);
+ return FAILURE;
+ }
+
+ attr = gfc_variable_attr (target, NULL);
+ if (!attr.pointer && !attr.target)
+ {
+ must_be (target, 1, "a POINTER or a TARGET");
+ return FAILURE;
+ }
+
+ t = SUCCESS;
+ if (same_type_check (pointer, 0, target, 1) == FAILURE)
+ t = FAILURE;
+ if (rank_check (target, 0, pointer->rank) == FAILURE)
+ t = FAILURE;
+ if (target->rank > 0)
+ {
+ for (i = 0; i < target->rank; i++)
+ if (target->ref->u.ar.dimen_type[i] == DIMEN_VECTOR)
+ {
+ gfc_error ("Array section with a vector subscript at %L shall not "
+ "be the target of an pointer",
+ &target->where);
+ t = FAILURE;
+ break;
+ }
+ }
+ return t;
+}
+
+
+try
+gfc_check_btest (gfc_expr * i, gfc_expr * pos)
+{
+
+ if (type_check (i, 0, BT_INTEGER) == FAILURE)
+ return FAILURE;
+ if (type_check (pos, 1, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_char (gfc_expr * i, gfc_expr * kind)
+{
+
+ if (type_check (i, 0, BT_INTEGER) == FAILURE)
+ return FAILURE;
+ if (kind_check (kind, 1, BT_CHARACTER) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_cmplx (gfc_expr * x, gfc_expr * y, gfc_expr * kind)
+{
+
+ if (numeric_check (x, 0) == FAILURE)
+ return FAILURE;
+
+ if (y != NULL)
+ {
+ if (numeric_check (y, 1) == FAILURE)
+ return FAILURE;
+
+ if (x->ts.type == BT_COMPLEX)
+ {
+ must_be (y, 1, "not be present if 'x' is COMPLEX");
+ return FAILURE;
+ }
+ }
+
+ if (kind_check (kind, 2, BT_COMPLEX) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_count (gfc_expr * mask, gfc_expr * dim)
+{
+
+ if (logical_array_check (mask, 0) == FAILURE)
+ return FAILURE;
+ if (dim_check (dim, 1, 1) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_cshift (gfc_expr * array, gfc_expr * shift, gfc_expr * dim)
+{
+
+ if (array_check (array, 0) == FAILURE)
+ return FAILURE;
+
+ if (array->rank == 1)
+ {
+ if (scalar_check (shift, 1) == FAILURE)
+ return FAILURE;
+ }
+ else
+ {
+ /* TODO: more requirements on shift parameter. */
+ }
+
+ if (dim_check (dim, 2, 1) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_dcmplx (gfc_expr * x, gfc_expr * y)
+{
+
+ if (numeric_check (x, 0) == FAILURE)
+ return FAILURE;
+
+ if (y != NULL)
+ {
+ if (numeric_check (y, 1) == FAILURE)
+ return FAILURE;
+
+ if (x->ts.type == BT_COMPLEX)
+ {
+ must_be (y, 1, "not be present if 'x' is COMPLEX");
+ return FAILURE;
+ }
+ }
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_dble (gfc_expr * x)
+{
+
+ if (numeric_check (x, 0) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_digits (gfc_expr * x)
+{
+
+ if (int_or_real_check (x, 0) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_dot_product (gfc_expr * vector_a, gfc_expr * vector_b)
+{
+
+ switch (vector_a->ts.type)
+ {
+ case BT_LOGICAL:
+ if (type_check (vector_b, 1, BT_LOGICAL) == FAILURE)
+ return FAILURE;
+ break;
+
+ case BT_INTEGER:
+ case BT_REAL:
+ case BT_COMPLEX:
+ if (numeric_check (vector_b, 1) == FAILURE)
+ return FAILURE;
+ break;
+
+ default:
+ must_be (vector_a, 0, "numeric or LOGICAL");
+ return FAILURE;
+ }
+
+ if (rank_check (vector_a, 0, 1) == FAILURE)
+ return FAILURE;
+
+ if (rank_check (vector_b, 1, 1) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_eoshift (gfc_expr * array, gfc_expr * shift, gfc_expr * boundary,
+ gfc_expr * dim)
+{
+
+ if (array_check (array, 0) == FAILURE)
+ return FAILURE;
+
+ if (type_check (shift, 1, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (array->rank == 1)
+ {
+ if (scalar_check (shift, 2) == FAILURE)
+ return FAILURE;
+ }
+ else
+ {
+ /* TODO: more weird restrictions on shift. */
+ }
+
+ if (boundary != NULL)
+ {
+ if (same_type_check (array, 0, boundary, 2) == FAILURE)
+ return FAILURE;
+
+ /* TODO: more restrictions on boundary. */
+ }
+
+ if (dim_check (dim, 1, 1) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+
+try
+gfc_check_huge (gfc_expr * x)
+{
+
+ if (int_or_real_check (x, 0) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+/* Check that the single argument is an integer. */
+
+try
+gfc_check_i (gfc_expr * i)
+{
+
+ if (type_check (i, 0, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_iand (gfc_expr * i, gfc_expr * j)
+{
+
+ if (type_check (i, 0, BT_INTEGER) == FAILURE
+ || type_check (j, 1, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (same_type_check (i, 0, j, 1) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_ibclr (gfc_expr * i, gfc_expr * pos)
+{
+
+ if (type_check (i, 0, BT_INTEGER) == FAILURE
+ || type_check (pos, 1, BT_INTEGER) == FAILURE
+ || kind_value_check (pos, 1, gfc_default_integer_kind ()) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_ibits (gfc_expr * i, gfc_expr * pos, gfc_expr * len)
+{
+
+ if (type_check (i, 0, BT_INTEGER) == FAILURE
+ || type_check (pos, 1, BT_INTEGER) == FAILURE
+ || kind_value_check (pos, 1, gfc_default_integer_kind ()) == FAILURE
+ || type_check (len, 2, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_ibset (gfc_expr * i, gfc_expr * pos)
+{
+
+ if (type_check (i, 0, BT_INTEGER) == FAILURE
+ || type_check (pos, 1, BT_INTEGER) == FAILURE
+ || kind_value_check (pos, 1, gfc_default_integer_kind ()) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_idnint (gfc_expr * a)
+{
+
+ if (double_check (a, 0) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_ieor (gfc_expr * i, gfc_expr * j)
+{
+
+ if (type_check (i, 0, BT_INTEGER) == FAILURE
+ || type_check (j, 1, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (same_type_check (i, 0, j, 1) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_index (gfc_expr * string, gfc_expr * substring, gfc_expr * back)
+{
+
+ if (type_check (string, 0, BT_CHARACTER) == FAILURE
+ || type_check (substring, 1, BT_CHARACTER) == FAILURE)
+ return FAILURE;
+
+
+ if (back != NULL && type_check (back, 2, BT_LOGICAL) == FAILURE)
+ return FAILURE;
+
+ if (string->ts.kind != substring->ts.kind)
+ {
+ must_be (substring, 1, "the same kind as 'string'");
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_int (gfc_expr * x, gfc_expr * kind)
+{
+
+ if (numeric_check (x, 0) == FAILURE
+ || kind_check (kind, 1, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_ior (gfc_expr * i, gfc_expr * j)
+{
+
+ if (type_check (i, 0, BT_INTEGER) == FAILURE
+ || type_check (j, 1, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (same_type_check (i, 0, j, 1) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_ishft (gfc_expr * i, gfc_expr * shift)
+{
+
+ if (type_check (i, 0, BT_INTEGER) == FAILURE
+ || type_check (shift, 1, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_ishftc (gfc_expr * i, gfc_expr * shift, gfc_expr * size)
+{
+
+ if (type_check (i, 0, BT_INTEGER) == FAILURE
+ || type_check (shift, 1, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (size != NULL && type_check (size, 2, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_kind (gfc_expr * x)
+{
+
+ if (x->ts.type == BT_DERIVED)
+ {
+ must_be (x, 0, "a non-derived type");
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_lbound (gfc_expr * array, gfc_expr * dim)
+{
+
+ if (array_check (array, 0) == FAILURE)
+ return FAILURE;
+
+ if (dim != NULL)
+ {
+ if (dim_check (dim, 1, 1) == FAILURE)
+ return FAILURE;
+
+ if (dim_rank_check (dim, array, 1) == FAILURE)
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+
+
+try
+gfc_check_logical (gfc_expr * a, gfc_expr * kind)
+{
+
+ if (type_check (a, 0, BT_LOGICAL) == FAILURE)
+ return FAILURE;
+ if (kind_check (kind, 1, BT_LOGICAL) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+/* Min/max family. */
+
+static try
+min_max_args (gfc_actual_arglist * arg)
+{
+
+ if (arg == NULL || arg->next == NULL)
+ {
+ gfc_error ("Intrinsic '%s' at %L must have at least two arguments",
+ gfc_current_intrinsic, gfc_current_intrinsic_where);
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+static try
+check_rest (bt type, int kind, gfc_actual_arglist * arg)
+{
+ gfc_expr *x;
+ int n;
+
+ if (min_max_args (arg) == FAILURE)
+ return FAILURE;
+
+ n = 1;
+
+ for (; arg; arg = arg->next, n++)
+ {
+ x = arg->expr;
+ if (x->ts.type != type || x->ts.kind != kind)
+ {
+ if (x->ts.type == type)
+ {
+ if (gfc_notify_std (GFC_STD_GNU,
+ "Extension: Different type kinds at %L", &x->where)
+ == FAILURE)
+ return FAILURE;
+ }
+ else
+ {
+ gfc_error ("'a%d' argument of '%s' intrinsic at %L must be %s(%d)",
+ n, gfc_current_intrinsic, &x->where,
+ gfc_basic_typename (type), kind);
+ return FAILURE;
+ }
+ }
+ }
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_min_max (gfc_actual_arglist * arg)
+{
+ gfc_expr *x;
+
+ if (min_max_args (arg) == FAILURE)
+ return FAILURE;
+
+ x = arg->expr;
+
+ if (x->ts.type != BT_INTEGER && x->ts.type != BT_REAL)
+ {
+ gfc_error
+ ("'a1' argument of '%s' intrinsic at %L must be INTEGER or REAL",
+ gfc_current_intrinsic, &x->where);
+ return FAILURE;
+ }
+
+ return check_rest (x->ts.type, x->ts.kind, arg);
+}
+
+
+try
+gfc_check_min_max_integer (gfc_actual_arglist * arg)
+{
+
+ return check_rest (BT_INTEGER, gfc_default_integer_kind (), arg);
+}
+
+
+try
+gfc_check_min_max_real (gfc_actual_arglist * arg)
+{
+
+ return check_rest (BT_REAL, gfc_default_real_kind (), arg);
+}
+
+
+try
+gfc_check_min_max_double (gfc_actual_arglist * arg)
+{
+
+ return check_rest (BT_REAL, gfc_default_double_kind (), arg);
+}
+
+/* End of min/max family. */
+
+
+try
+gfc_check_matmul (gfc_expr * matrix_a, gfc_expr * matrix_b)
+{
+
+ if ((matrix_a->ts.type != BT_LOGICAL) && !gfc_numeric_ts (&matrix_b->ts))
+ {
+ must_be (matrix_a, 0, "numeric or LOGICAL");
+ return FAILURE;
+ }
+
+ if ((matrix_b->ts.type != BT_LOGICAL) && !gfc_numeric_ts (&matrix_a->ts))
+ {
+ must_be (matrix_b, 0, "numeric or LOGICAL");
+ return FAILURE;
+ }
+
+ switch (matrix_a->rank)
+ {
+ case 1:
+ if (rank_check (matrix_b, 1, 2) == FAILURE)
+ return FAILURE;
+ break;
+
+ case 2:
+ if (matrix_b->rank == 2)
+ break;
+ if (rank_check (matrix_b, 1, 1) == FAILURE)
+ return FAILURE;
+ break;
+
+ default:
+ must_be (matrix_a, 0, "of rank 1 or 2");
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Whoever came up with this interface was probably on something.
+ The possibilities for the occupation of the second and third
+ parameters are:
+
+ Arg #2 Arg #3
+ NULL NULL
+ DIM NULL
+ MASK NULL
+ NULL MASK minloc(array, mask=m)
+ DIM MASK
+*/
+
+try
+gfc_check_minloc_maxloc (gfc_expr * array, gfc_expr * a2, gfc_expr * a3)
+{
+
+ if (int_or_real_check (array, 0) == FAILURE)
+ return FAILURE;
+
+ if (array_check (array, 0) == FAILURE)
+ return FAILURE;
+
+ if (a3 != NULL)
+ {
+ if (logical_array_check (a3, 2) == FAILURE)
+ return FAILURE;
+
+ if (a2 != NULL)
+ {
+ if (scalar_check (a2, 1) == FAILURE)
+ return FAILURE;
+ if (type_check (a2, 1, BT_INTEGER) == FAILURE)
+ return FAILURE;
+ }
+ }
+ else
+ {
+ if (a2 != NULL)
+ {
+ switch (a2->ts.type)
+ {
+ case BT_INTEGER:
+ if (scalar_check (a2, 1) == FAILURE)
+ return FAILURE;
+ break;
+
+ case BT_LOGICAL: /* The '2' makes the error message correct */
+ if (logical_array_check (a2, 2) == FAILURE)
+ return FAILURE;
+ break;
+
+ default:
+ type_check (a2, 1, BT_INTEGER); /* Guaranteed to fail */
+ return FAILURE;
+ }
+ }
+ }
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_minval_maxval (gfc_expr * array, gfc_expr * dim, gfc_expr * mask)
+{
+
+ if (array_check (array, 0) == FAILURE)
+ return FAILURE;
+
+ if (int_or_real_check (array, 0) == FAILURE)
+ return FAILURE;
+
+ if (dim_check (dim, 1, 1) == FAILURE)
+ return FAILURE;
+
+ if (mask != NULL && logical_array_check (mask, 2) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_merge (gfc_expr * tsource, gfc_expr * fsource, gfc_expr * mask)
+{
+
+ if (same_type_check (tsource, 0, fsource, 1) == FAILURE)
+ return FAILURE;
+
+ if (type_check (mask, 2, BT_LOGICAL) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_nearest (gfc_expr * x, gfc_expr * s)
+{
+
+ if (type_check (x, 0, BT_REAL) == FAILURE)
+ return FAILURE;
+
+ if (type_check (s, 1, BT_REAL) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_null (gfc_expr * mold)
+{
+ symbol_attribute attr;
+
+ if (mold == NULL)
+ return SUCCESS;
+
+ if (variable_check (mold, 0) == FAILURE)
+ return FAILURE;
+
+ attr = gfc_variable_attr (mold, NULL);
+
+ if (!attr.pointer)
+ {
+ must_be (mold, 0, "a POINTER");
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_pack (gfc_expr * array, gfc_expr * mask, gfc_expr * vector)
+{
+
+ if (array_check (array, 0) == FAILURE)
+ return FAILURE;
+
+ if (type_check (mask, 1, BT_LOGICAL) == FAILURE)
+ return FAILURE;
+
+ if (mask->rank != 0 && mask->rank != array->rank)
+ {
+ must_be (array, 0, "conformable with 'mask' argument");
+ return FAILURE;
+ }
+
+ if (vector != NULL)
+ {
+ if (same_type_check (array, 0, vector, 2) == FAILURE)
+ return FAILURE;
+
+ if (rank_check (vector, 2, 1) == FAILURE)
+ return FAILURE;
+
+ /* TODO: More constraints here. */
+ }
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_precision (gfc_expr * x)
+{
+
+ if (x->ts.type != BT_REAL && x->ts.type != BT_COMPLEX)
+ {
+ must_be (x, 0, "of type REAL or COMPLEX");
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_present (gfc_expr * a)
+{
+ gfc_symbol *sym;
+
+ if (variable_check (a, 0) == FAILURE)
+ return FAILURE;
+
+ sym = a->symtree->n.sym;
+ if (!sym->attr.dummy)
+ {
+ must_be (a, 0, "a dummy variable");
+ return FAILURE;
+ }
+
+ if (!sym->attr.optional)
+ {
+ must_be (a, 0, "an OPTIONAL dummy variable");
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_product (gfc_expr * array, gfc_expr * dim, gfc_expr * mask)
+{
+
+ if (array_check (array, 0) == FAILURE)
+ return FAILURE;
+
+ if (numeric_check (array, 0) == FAILURE)
+ return FAILURE;
+
+ if (dim_check (dim, 1, 1) == FAILURE)
+ return FAILURE;
+
+ if (mask != NULL && logical_array_check (mask, 2) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_radix (gfc_expr * x)
+{
+
+ if (int_or_real_check (x, 0) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_range (gfc_expr * x)
+{
+
+ if (numeric_check (x, 0) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+/* real, float, sngl. */
+try
+gfc_check_real (gfc_expr * a, gfc_expr * kind)
+{
+
+ if (numeric_check (a, 0) == FAILURE)
+ return FAILURE;
+
+ if (kind_check (kind, 1, BT_REAL) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_repeat (gfc_expr * x, gfc_expr * y)
+{
+
+ if (type_check (x, 0, BT_CHARACTER) == FAILURE)
+ return FAILURE;
+
+ if (scalar_check (x, 0) == FAILURE)
+ return FAILURE;
+
+ if (type_check (y, 0, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (scalar_check (y, 1) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_reshape (gfc_expr * source, gfc_expr * shape,
+ gfc_expr * pad, gfc_expr * order)
+{
+ mpz_t size;
+ int m;
+
+ if (array_check (source, 0) == FAILURE)
+ return FAILURE;
+
+ if (rank_check (shape, 1, 1) == FAILURE)
+ return FAILURE;
+
+ if (type_check (shape, 1, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (gfc_array_size (shape, &size) != SUCCESS)
+ {
+ gfc_error ("'shape' argument of 'reshape' intrinsic at %L must be an "
+ "array of constant size", &shape->where);
+ return FAILURE;
+ }
+
+ m = mpz_cmp_ui (size, GFC_MAX_DIMENSIONS);
+ mpz_clear (size);
+
+ if (m > 0)
+ {
+ gfc_error
+ ("'shape' argument of 'reshape' intrinsic at %L has more than "
+ stringize (GFC_MAX_DIMENSIONS) " elements", &shape->where);
+ return FAILURE;
+ }
+
+ if (pad != NULL)
+ {
+ if (same_type_check (source, 0, pad, 2) == FAILURE)
+ return FAILURE;
+ if (array_check (pad, 2) == FAILURE)
+ return FAILURE;
+ }
+
+ if (order != NULL && array_check (order, 3) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_scale (gfc_expr * x, gfc_expr * i)
+{
+
+ if (type_check (x, 0, BT_REAL) == FAILURE)
+ return FAILURE;
+
+ if (type_check (i, 1, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_scan (gfc_expr * x, gfc_expr * y, gfc_expr * z)
+{
+
+ if (type_check (x, 0, BT_CHARACTER) == FAILURE)
+ return FAILURE;
+
+ if (type_check (y, 1, BT_CHARACTER) == FAILURE)
+ return FAILURE;
+
+ if (z != NULL && type_check (z, 2, BT_LOGICAL) == FAILURE)
+ return FAILURE;
+
+ if (same_type_check (x, 0, y, 1) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_selected_real_kind (gfc_expr * p, gfc_expr * r)
+{
+
+ if (p == NULL && r == NULL)
+ {
+ gfc_error ("Missing arguments to %s intrinsic at %L",
+ gfc_current_intrinsic, gfc_current_intrinsic_where);
+
+ return FAILURE;
+ }
+
+ if (p != NULL && type_check (p, 0, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (r != NULL && type_check (r, 1, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_set_exponent (gfc_expr * x, gfc_expr * i)
+{
+
+ if (type_check (x, 0, BT_REAL) == FAILURE)
+ return FAILURE;
+
+ if (type_check (i, 1, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_shape (gfc_expr * source)
+{
+ gfc_array_ref *ar;
+
+ if (source->rank == 0 || source->expr_type != EXPR_VARIABLE)
+ return SUCCESS;
+
+ ar = gfc_find_array_ref (source);
+
+ if (ar->as && ar->as->type == AS_ASSUMED_SIZE)
+ {
+ gfc_error ("'source' argument of 'shape' intrinsic at %L must not be "
+ "an assumed size array", &source->where);
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_size (gfc_expr * array, gfc_expr * dim)
+{
+
+ if (array_check (array, 0) == FAILURE)
+ return FAILURE;
+
+ if (dim != NULL)
+ {
+ if (type_check (dim, 1, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (kind_value_check (dim, 1, gfc_default_integer_kind ()) == FAILURE)
+ return FAILURE;
+
+ if (dim_rank_check (dim, array, 0) == FAILURE)
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_sign (gfc_expr * a, gfc_expr * b)
+{
+
+ if (int_or_real_check (a, 0) == FAILURE)
+ return FAILURE;
+
+ if (same_type_check (a, 0, b, 1) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_spread (gfc_expr * source, gfc_expr * dim, gfc_expr * ncopies)
+{
+
+ if (source->rank >= GFC_MAX_DIMENSIONS)
+ {
+ must_be (source, 0, "less than rank " stringize (GFC_MAX_DIMENSIONS));
+ return FAILURE;
+ }
+
+ if (dim_check (dim, 1, 0) == FAILURE)
+ return FAILURE;
+
+ if (type_check (ncopies, 2, BT_INTEGER) == FAILURE)
+ return FAILURE;
+ if (scalar_check (ncopies, 2) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_sum (gfc_expr * array, gfc_expr * dim, gfc_expr * mask)
+{
+
+ if (array_check (array, 0) == FAILURE)
+ return FAILURE;
+
+ if (numeric_check (array, 0) == FAILURE)
+ return FAILURE;
+
+ if (dim_check (dim, 1, 1) == FAILURE)
+ return FAILURE;
+
+ if (mask != NULL && logical_array_check (mask, 2) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_transfer (gfc_expr * source ATTRIBUTE_UNUSED,
+ gfc_expr * mold ATTRIBUTE_UNUSED,
+ gfc_expr * size)
+{
+
+ if (size != NULL)
+ {
+ if (type_check (size, 2, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (scalar_check (size, 2) == FAILURE)
+ return FAILURE;
+
+ if (nonoptional_check (size, 2) == FAILURE)
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_transpose (gfc_expr * matrix)
+{
+
+ if (rank_check (matrix, 0, 2) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_ubound (gfc_expr * array, gfc_expr * dim)
+{
+
+ if (array_check (array, 0) == FAILURE)
+ return FAILURE;
+
+ if (dim != NULL)
+ {
+ if (dim_check (dim, 1, 1) == FAILURE)
+ return FAILURE;
+
+ if (dim_rank_check (dim, array, 0) == FAILURE)
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+
+
+try
+gfc_check_unpack (gfc_expr * vector, gfc_expr * mask, gfc_expr * field)
+{
+
+ if (rank_check (vector, 0, 1) == FAILURE)
+ return FAILURE;
+
+ if (array_check (mask, 1) == FAILURE)
+ return FAILURE;
+
+ if (type_check (mask, 1, BT_LOGICAL) == FAILURE)
+ return FAILURE;
+
+ if (same_type_check (vector, 0, field, 2) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_verify (gfc_expr * x, gfc_expr * y, gfc_expr * z)
+{
+
+ if (type_check (x, 0, BT_CHARACTER) == FAILURE)
+ return FAILURE;
+
+ if (same_type_check (x, 0, y, 1) == FAILURE)
+ return FAILURE;
+
+ if (z != NULL && type_check (z, 2, BT_LOGICAL) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_trim (gfc_expr * x)
+{
+ if (type_check (x, 0, BT_CHARACTER) == FAILURE)
+ return FAILURE;
+
+ if (scalar_check (x, 0) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+/* Common check function for the half a dozen intrinsics that have a
+ single real argument. */
+
+try
+gfc_check_x (gfc_expr * x)
+{
+
+ if (type_check (x, 0, BT_REAL) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+/************* Check functions for intrinsic subroutines *************/
+
+try
+gfc_check_cpu_time (gfc_expr * time)
+{
+
+ if (scalar_check (time, 0) == FAILURE)
+ return FAILURE;
+
+ if (type_check (time, 0, BT_REAL) == FAILURE)
+ return FAILURE;
+
+ if (variable_check (time, 0) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_date_and_time (gfc_expr * date, gfc_expr * time,
+ gfc_expr * zone, gfc_expr * values)
+{
+
+ if (date != NULL)
+ {
+ if (type_check (date, 0, BT_CHARACTER) == FAILURE)
+ return FAILURE;
+ if (scalar_check (date, 0) == FAILURE)
+ return FAILURE;
+ if (variable_check (date, 0) == FAILURE)
+ return FAILURE;
+ }
+
+ if (time != NULL)
+ {
+ if (type_check (time, 1, BT_CHARACTER) == FAILURE)
+ return FAILURE;
+ if (scalar_check (time, 1) == FAILURE)
+ return FAILURE;
+ if (variable_check (time, 1) == FAILURE)
+ return FAILURE;
+ }
+
+ if (zone != NULL)
+ {
+ if (type_check (zone, 2, BT_CHARACTER) == FAILURE)
+ return FAILURE;
+ if (scalar_check (zone, 2) == FAILURE)
+ return FAILURE;
+ if (variable_check (zone, 2) == FAILURE)
+ return FAILURE;
+ }
+
+ if (values != NULL)
+ {
+ if (type_check (values, 3, BT_INTEGER) == FAILURE)
+ return FAILURE;
+ if (array_check (values, 3) == FAILURE)
+ return FAILURE;
+ if (rank_check (values, 3, 1) == FAILURE)
+ return FAILURE;
+ if (variable_check (values, 3) == FAILURE)
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_mvbits (gfc_expr * from, gfc_expr * frompos, gfc_expr * len,
+ gfc_expr * to, gfc_expr * topos)
+{
+
+ if (type_check (from, 0, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (type_check (frompos, 1, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (type_check (len, 2, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (same_type_check (from, 0, to, 3) == FAILURE)
+ return FAILURE;
+
+ if (variable_check (to, 3) == FAILURE)
+ return FAILURE;
+
+ if (type_check (topos, 4, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_random_number (gfc_expr * harvest)
+{
+
+ if (type_check (harvest, 0, BT_REAL) == FAILURE)
+ return FAILURE;
+
+ if (variable_check (harvest, 0) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+try
+gfc_check_random_seed (gfc_expr * size, gfc_expr * put, gfc_expr * get)
+{
+
+ if (size != NULL)
+ {
+ if (scalar_check (size, 0) == FAILURE)
+ return FAILURE;
+
+ if (type_check (size, 0, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (variable_check (size, 0) == FAILURE)
+ return FAILURE;
+
+ if (kind_value_check (size, 0, gfc_default_integer_kind ()) == FAILURE)
+ return FAILURE;
+ }
+
+ if (put != NULL)
+ {
+ if (array_check (put, 1) == FAILURE)
+ return FAILURE;
+ if (rank_check (put, 1, 1) == FAILURE)
+ return FAILURE;
+
+ if (type_check (put, 1, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (kind_value_check (put, 1, gfc_default_integer_kind ()) == FAILURE)
+ return FAILURE;
+ }
+
+ if (get != NULL)
+ {
+ if (array_check (get, 2) == FAILURE)
+ return FAILURE;
+ if (rank_check (get, 2, 1) == FAILURE)
+ return FAILURE;
+
+ if (type_check (get, 2, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (variable_check (get, 2) == FAILURE)
+ return FAILURE;
+
+ if (kind_value_check (get, 2, gfc_default_integer_kind ()) == FAILURE)
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
diff --git a/gcc/fortran/config-lang.in b/gcc/fortran/config-lang.in
new file mode 100644
index 00000000000..c638dcbaf48
--- /dev/null
+++ b/gcc/fortran/config-lang.in
@@ -0,0 +1,22 @@
+# Configure looks for the existence of this file to auto-config each language.
+# We define several parameters used by configure:
+#
+# language - name of language as it would appear in $(LANGUAGES)
+# compilers - value to add to $(COMPILERS)
+# stagestuff - files to add to $(STAGESTUFF)
+# diff_excludes - files to ignore when building diffs between two versions.
+
+language="f95"
+
+compilers="f951\$(exeext)"
+
+stagestuff="gfortran\$(exeext) f951\$(exeext)"
+
+target_libs=target-libgfortran
+
+gtfiles="\$(srcdir)/fortran/f95-lang.c \$(srcdir)/fortran/trans-decl.c \$(srcdir)/fortran/trans-intrinsic.c \$(srcdir)/fortran/trans-io.c \$(srcdir)/fortran/trans-types.c \$(srcdir)/fortran/trans-types.h \$(srcdir)/fortran/trans.h \$(srcdir)/fortran/trans-const.h"
+
+need_gmp="yes"
+
+#outputs=g95/Makefile
+
diff --git a/gcc/fortran/convert.c b/gcc/fortran/convert.c
new file mode 100644
index 00000000000..9759f057f50
--- /dev/null
+++ b/gcc/fortran/convert.c
@@ -0,0 +1,124 @@
+/* Language-level data type conversion for GNU C.
+ Copyright (C) 1987, 1988, 1991, 1998, 2002 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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+/* This file contains the functions for converting C expressions
+ to different data types. The only entry point is `convert'.
+ Every language front end must have a `convert' function
+ but what kind of conversions it does will depend on the language. */
+
+/* copied from the f77 frontend I think */
+
+/* copied from c-convert.c without significant modification*/
+/* Change of width--truncation and extension of integers or reals--
+ is represented with NOP_EXPR. Proper functioning of many things
+ assumes that no other conversions can be NOP_EXPRs.
+*/
+
+/* I've added support for WITH_RECORD_EXPR. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "flags.h"
+#include "convert.h"
+#include "toplev.h"
+#include "gfortran.h"
+#include "trans.h"
+
+/*
+ Conversion between integer and pointer is represented with CONVERT_EXPR.
+ Converting integer to real uses FLOAT_EXPR
+ and real to integer uses FIX_TRUNC_EXPR.
+
+ Here is a list of all the functions that assume that widening and
+ narrowing is always done with a NOP_EXPR:
+ In convert.c, convert_to_integer.
+ In c-typeck.c, build_binary_op (boolean ops), and
+ c_common_truthvalue_conversion.
+ In expr.c: expand_expr, for operands of a MULT_EXPR.
+ In fold-const.c: fold.
+ In tree.c: get_narrower and get_unwidened. */
+
+/* Subroutines of `convert'. */
+
+
+
+/* Create an expression whose value is that of EXPR,
+ converted to type TYPE. The TREE_TYPE of the value
+ is always TYPE. This function implements all reasonable
+ conversions; callers should filter out those that are
+ not permitted by the language being compiled. */
+/* We are assuming that given a SIMPLE val, the result will be a SIMPLE rhs.
+ If this is not the case, we will abort with an internal error. */
+tree
+convert (tree type, tree expr)
+{
+ tree e = expr;
+ enum tree_code code = TREE_CODE (type);
+
+ if (type == TREE_TYPE (expr)
+ || TREE_CODE (expr) == ERROR_MARK
+ || code == ERROR_MARK || TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
+ return expr;
+
+ if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
+ return fold (build1 (NOP_EXPR, type, expr));
+ if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
+ return error_mark_node;
+ if (TREE_CODE (TREE_TYPE (expr)) == VOID_TYPE)
+ {
+ error ("void value not ignored as it ought to be");
+ return error_mark_node;
+ }
+ if (code == VOID_TYPE)
+ return build1 (CONVERT_EXPR, type, e);
+#if 0
+ /* This is incorrect. A truncation can't be stripped this way.
+ Extensions will be stripped by the use of get_unwidened. */
+ if (TREE_CODE (expr) == NOP_EXPR)
+ return convert (type, TREE_OPERAND (expr, 0));
+#endif
+ if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
+ return fold (convert_to_integer (type, e));
+ if (code == BOOLEAN_TYPE)
+ {
+ e = gfc_truthvalue_conversion (e);
+
+ /* If we have a NOP_EXPR, we must fold it here to avoid
+ infinite recursion between fold () and convert (). */
+ if (TREE_CODE (e) == NOP_EXPR)
+ return fold (build1 (NOP_EXPR, type, TREE_OPERAND (e, 0)));
+ else
+ return fold (build1 (NOP_EXPR, type, e));
+ }
+ if (code == POINTER_TYPE || code == REFERENCE_TYPE)
+ return fold (convert_to_pointer (type, e));
+ if (code == REAL_TYPE)
+ return fold (convert_to_real (type, e));
+ if (code == COMPLEX_TYPE)
+ return fold (convert_to_complex (type, e));
+ if (code == VECTOR_TYPE)
+ return fold (convert_to_vector (type, e));
+
+ error ("conversion to non-scalar type requested");
+ return error_mark_node;
+}
diff --git a/gcc/fortran/data.c b/gcc/fortran/data.c
new file mode 100644
index 00000000000..5bec7103e51
--- /dev/null
+++ b/gcc/fortran/data.c
@@ -0,0 +1,457 @@
+/* Supporting functions for resolving DATA statement.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Lifang Zeng <zlf605@hotmail.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330,Boston, MA
+02111-1307, USA. */
+
+
+/* Notes for DATA statement implementation:
+
+ We first assign initial value to each symbol by gfc_assign_data_value
+ during resolveing DATA statement. Refer to check_data_variable and
+ traverse_data_list in resolve.c.
+
+ The complexity exists in the handleing of array section, implied do
+ and array of struct appeared in DATA statement.
+
+ We call gfc_conv_structure, gfc_con_array_array_initializer,
+ etc., to convert the initial value. Refer to trans-expr.c and
+ trans-array.c. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "toplev.h"
+#include "gfortran.h"
+#include "assert.h"
+#include "trans.h"
+
+static void formalize_init_expr (gfc_expr *);
+
+/* Calculate the array element offset. */
+
+static void
+get_array_index (gfc_array_ref * ar, mpz_t * offset)
+{
+ gfc_expr *e;
+ int i;
+ try re;
+ mpz_t delta;
+ mpz_t tmp;
+
+ mpz_init (tmp);
+ mpz_set_si (*offset, 0);
+ mpz_init_set_si (delta, 1);
+ for (i = 0; i < ar->dimen; i++)
+ {
+ e = gfc_copy_expr (ar->start[i]);
+ re = gfc_simplify_expr (e, 1);
+
+ if ((gfc_is_constant_expr (ar->as->lower[i]) == 0)
+ || (gfc_is_constant_expr (ar->as->upper[i]) == 0)
+ || (gfc_is_constant_expr (e) == 0))
+ gfc_error ("non-constant array in DATA statement %L.", &ar->where);
+ mpz_set (tmp, e->value.integer);
+ mpz_sub (tmp, tmp, ar->as->lower[i]->value.integer);
+ mpz_mul (tmp, tmp, delta);
+ mpz_add (*offset, tmp, *offset);
+
+ mpz_sub (tmp, ar->as->upper[i]->value.integer,
+ ar->as->lower[i]->value.integer);
+ mpz_add_ui (tmp, tmp, 1);
+ mpz_mul (delta, tmp, delta);
+ }
+ mpz_clear (delta);
+ mpz_clear (tmp);
+}
+
+
+/* Find if there is a constructor which offset is equal to OFFSET. */
+
+static gfc_constructor *
+find_con_by_offset (mpz_t offset, gfc_constructor *con)
+{
+ for (; con; con = con->next)
+ {
+ if (mpz_cmp (offset, con->n.offset) == 0)
+ return con;
+ }
+ return NULL;
+}
+
+
+/* Find if there is a constructor which component is equal to COM. */
+
+static gfc_constructor *
+find_con_by_component (gfc_component *com, gfc_constructor *con)
+{
+ for (; con; con = con->next)
+ {
+ if (com == con->n.component)
+ return con;
+ }
+ return NULL;
+}
+
+
+/* Assign the initial value RVALUE to LVALUE's symbol->value. */
+void
+gfc_assign_data_value (gfc_expr * lvalue, gfc_expr * rvalue, mpz_t index)
+{
+ gfc_ref *ref;
+ gfc_expr *init;
+ gfc_expr *expr;
+ gfc_constructor *con;
+ gfc_constructor *last_con;
+ gfc_symbol *symbol;
+ mpz_t offset;
+
+ ref = lvalue->ref;
+ symbol = lvalue->symtree->n.sym;
+ init = symbol->value;
+ last_con = NULL;
+ mpz_init_set_si (offset, 0);
+
+ for (ref = lvalue->ref; ref; ref = ref->next)
+ {
+ /* Use the existing initializer expression if it exists. Otherwise
+ create a new one. */
+ if (init == NULL)
+ expr = gfc_get_expr ();
+ else
+ expr = init;
+
+ /* Find or create this element. */
+ switch (ref->type)
+ {
+ case REF_ARRAY:
+ if (init == NULL)
+ {
+ /* Setup the expression to hold the constructor. */
+ expr->expr_type = EXPR_ARRAY;
+ if (ref->next)
+ {
+ assert (ref->next->type == REF_COMPONENT);
+ expr->ts.type = BT_DERIVED;
+ }
+ else
+ expr->ts = rvalue->ts;
+ expr->rank = ref->u.ar.as->rank;
+ }
+ else
+ assert (expr->expr_type == EXPR_ARRAY);
+
+ if (ref->u.ar.type == AR_ELEMENT)
+ get_array_index (&ref->u.ar, &offset);
+ else
+ mpz_set (offset, index);
+
+ /* Find the same element in the existing constructor. */
+ con = expr->value.constructor;
+ con = find_con_by_offset (offset, con);
+
+ if (con == NULL)
+ {
+ /* Create a new constructor. */
+ con = gfc_get_constructor();
+ mpz_set (con->n.offset, offset);
+ gfc_insert_constructor (expr, con);
+ }
+ break;
+
+ case REF_COMPONENT:
+ if (init == NULL)
+ {
+ /* Setup the expression to hold the constructor. */
+ expr->expr_type = EXPR_STRUCTURE;
+ expr->ts.type = BT_DERIVED;
+ expr->ts.derived = ref->u.c.sym;
+ }
+ else
+ assert (expr->expr_type == EXPR_STRUCTURE);
+
+ /* Find the same element in the existing constructor. */
+ con = expr->value.constructor;
+ con = find_con_by_component (ref->u.c.component, con);
+
+ if (con == NULL)
+ {
+ /* Create a new constructor. */
+ con = gfc_get_constructor ();
+ con->n.component = ref->u.c.component;
+ con->next = expr->value.constructor;
+ expr->value.constructor = con;
+ }
+ break;
+
+ case REF_SUBSTRING:
+ gfc_todo_error ("Substring reference in DATA statement");
+
+ default:
+ abort ();
+ }
+
+ if (init == NULL)
+ {
+ /* Point the container at the new expression. */
+ if (last_con == NULL)
+ symbol->value = expr;
+ else
+ last_con->expr = expr;
+ }
+ init = con->expr;
+ last_con = con;
+ }
+
+ expr = gfc_copy_expr (rvalue);
+ if (!gfc_compare_types (&lvalue->ts, &expr->ts))
+ gfc_convert_type (expr, &lvalue->ts, 0);
+
+ if (last_con == NULL)
+ symbol->value = expr;
+ else
+ {
+ assert (!last_con->expr);
+ last_con->expr = expr;
+ }
+}
+
+
+/* Modify the index of array section and re-calculate the array offset. */
+
+void
+gfc_advance_section (mpz_t *section_index, gfc_array_ref *ar,
+ mpz_t *offset_ret)
+{
+ int i;
+ mpz_t delta;
+ mpz_t tmp;
+ bool forwards;
+ int cmp;
+
+ for (i = 0; i < ar->dimen; i++)
+ {
+ if (ar->dimen_type[i] != DIMEN_RANGE)
+ continue;
+
+ if (ar->stride[i])
+ {
+ mpz_add (section_index[i], section_index[i],
+ ar->stride[i]->value.integer);
+ if (mpz_cmp_si (ar->stride[i]->value.integer, 0) >= 0)
+ forwards = true;
+ else
+ forwards = false;
+ }
+ else
+ {
+ mpz_add_ui (section_index[i], section_index[i], 1);
+ forwards = true;
+ }
+
+ if (ar->end[i])
+ cmp = mpz_cmp (section_index[i], ar->end[i]->value.integer);
+ else
+ cmp = mpz_cmp (section_index[i], ar->as->upper[i]->value.integer);
+
+ if ((cmp > 0 && forwards)
+ || (cmp < 0 && ! forwards))
+ {
+ /* Reset index to start, then loop to advance the next index. */
+ if (ar->start[i])
+ mpz_set (section_index[i], ar->start[i]->value.integer);
+ else
+ mpz_set (section_index[i], ar->as->lower[i]->value.integer);
+ }
+ else
+ break;
+ }
+
+ mpz_set_si (*offset_ret, 0);
+ mpz_init_set_si (delta, 1);
+ mpz_init (tmp);
+ for (i = 0; i < ar->dimen; i++)
+ {
+ mpz_sub (tmp, section_index[i], ar->as->lower[i]->value.integer);
+ mpz_mul (tmp, tmp, delta);
+ mpz_add (*offset_ret, tmp, *offset_ret);
+
+ mpz_sub (tmp, ar->as->upper[i]->value.integer,
+ ar->as->lower[i]->value.integer);
+ mpz_add_ui (tmp, tmp, 1);
+ mpz_mul (delta, tmp, delta);
+ }
+ mpz_clear (tmp);
+ mpz_clear (delta);
+}
+
+
+/* Rearrange a structure constructor so the elements are in the specified
+ order. Also insert NULL entries if neccessary. */
+
+static void
+formalize_structure_cons (gfc_expr * expr)
+{
+ gfc_constructor *head;
+ gfc_constructor *tail;
+ gfc_constructor *cur;
+ gfc_constructor *last;
+ gfc_constructor *c;
+ gfc_component *order;
+
+ c = expr->value.constructor;
+
+ /* Constructor is already fomalized. */
+ if (c->n.component == NULL)
+ return;
+
+ head = tail = NULL;
+ for (order = expr->ts.derived->components; order; order = order->next)
+ {
+ /* Find the next component. */
+ last = NULL;
+ cur = c;
+ while (cur != NULL && cur->n.component != order)
+ {
+ last = cur;
+ cur = cur->next;
+ }
+
+ if (cur == NULL)
+ {
+ /* Create a new one. */
+ cur = gfc_get_constructor ();
+ }
+ else
+ {
+ /* Remove it from the chain. */
+ if (last == NULL)
+ c = cur->next;
+ else
+ last->next = cur->next;
+ cur->next = NULL;
+
+ formalize_init_expr (cur->expr);
+ }
+
+ /* Add it to the new constructor. */
+ if (head == NULL)
+ head = tail = cur;
+ else
+ {
+ tail->next = cur;
+ tail = tail->next;
+ }
+ }
+ assert (c == NULL);
+ expr->value.constructor = head;
+}
+
+
+/* Make sure an initialization expression is in normalized form. Ie. all
+ elements of the constructors are in the correct order. */
+
+static void
+formalize_init_expr (gfc_expr * expr)
+{
+ expr_t type;
+ gfc_constructor *c;
+
+ if (expr == NULL)
+ return;
+
+ type = expr->expr_type;
+ switch (type)
+ {
+ case EXPR_ARRAY:
+ c = expr->value.constructor;
+ while (c)
+ {
+ formalize_init_expr (c->expr);
+ c = c->next;
+ }
+ break;
+
+ case EXPR_STRUCTURE:
+ formalize_structure_cons (expr);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/* Resolve symbol's initial value after all data statement. */
+
+void
+gfc_formalize_init_value (gfc_symbol *sym)
+{
+ formalize_init_expr (sym->value);
+}
+
+
+/* Get the integer value into RET_AS and SECTION from AS and AR, and return
+ offset. */
+
+void
+gfc_get_section_index (gfc_array_ref *ar, mpz_t *section_index, mpz_t *offset)
+{
+ int i;
+ mpz_t delta;
+ mpz_t tmp;
+
+ mpz_set_si (*offset, 0);
+ mpz_init (tmp);
+ mpz_init_set_si (delta, 1);
+ for (i = 0; i < ar->dimen; i++)
+ {
+ mpz_init (section_index[i]);
+ switch (ar->dimen_type[i])
+ {
+ case DIMEN_ELEMENT:
+ case DIMEN_RANGE:
+ if (ar->start[i])
+ {
+ mpz_sub (tmp, ar->start[i]->value.integer,
+ ar->as->lower[i]->value.integer);
+ mpz_mul (tmp, tmp, delta);
+ mpz_add (*offset, tmp, *offset);
+ mpz_set (section_index[i], ar->start[i]->value.integer);
+ }
+ else
+ mpz_set (section_index[i], ar->as->lower[i]->value.integer);
+ break;
+
+ case DIMEN_VECTOR:
+ gfc_todo_error ("Vectors sections in data statements");
+
+ default:
+ abort ();
+ }
+
+ mpz_sub (tmp, ar->as->upper[i]->value.integer,
+ ar->as->lower[i]->value.integer);
+ mpz_add_ui (tmp, tmp, 1);
+ mpz_mul (delta, tmp, delta);
+ }
+
+ mpz_clear (tmp);
+ mpz_clear (delta);
+}
+
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
new file mode 100644
index 00000000000..9d6bf948dd7
--- /dev/null
+++ b/gcc/fortran/decl.c
@@ -0,0 +1,2649 @@
+/* Declaration statement matcher
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#include "config.h"
+#include "gfortran.h"
+#include "match.h"
+#include "parse.h"
+#include <string.h>
+
+
+/* This flag is set if a an old-style length selector is matched
+ during a type-declaration statement. */
+
+static int old_char_selector;
+
+/* When variables aquire types and attributes from a declaration
+ statement, they get them from the following static variables. The
+ first part of a declaration sets these variables and the second
+ part copies these into symbol structures. */
+
+static gfc_typespec current_ts;
+
+static symbol_attribute current_attr;
+static gfc_array_spec *current_as;
+static int colon_seen;
+
+/* gfc_new_block points to the symbol of a newly matched block. */
+
+gfc_symbol *gfc_new_block;
+
+
+/* Match an intent specification. Since this can only happen after an
+ INTENT word, a legal intent-spec must follow. */
+
+static sym_intent
+match_intent_spec (void)
+{
+
+ if (gfc_match (" ( in out )") == MATCH_YES)
+ return INTENT_INOUT;
+ if (gfc_match (" ( in )") == MATCH_YES)
+ return INTENT_IN;
+ if (gfc_match (" ( out )") == MATCH_YES)
+ return INTENT_OUT;
+
+ gfc_error ("Bad INTENT specification at %C");
+ return INTENT_UNKNOWN;
+}
+
+
+/* Matches a character length specification, which is either a
+ specification expression or a '*'. */
+
+static match
+char_len_param_value (gfc_expr ** expr)
+{
+
+ if (gfc_match_char ('*') == MATCH_YES)
+ {
+ *expr = NULL;
+ return MATCH_YES;
+ }
+
+ return gfc_match_expr (expr);
+}
+
+
+/* A character length is a '*' followed by a literal integer or a
+ char_len_param_value in parenthesis. */
+
+static match
+match_char_length (gfc_expr ** expr)
+{
+ int length;
+ match m;
+
+ m = gfc_match_char ('*');
+ if (m != MATCH_YES)
+ return m;
+
+ m = gfc_match_small_literal_int (&length);
+ if (m == MATCH_ERROR)
+ return m;
+
+ if (m == MATCH_YES)
+ {
+ *expr = gfc_int_expr (length);
+ return m;
+ }
+
+ if (gfc_match_char ('(') == MATCH_NO)
+ goto syntax;
+
+ m = char_len_param_value (expr);
+ if (m == MATCH_ERROR)
+ return m;
+ if (m == MATCH_NO)
+ goto syntax;
+
+ if (gfc_match_char (')') == MATCH_NO)
+ {
+ gfc_free_expr (*expr);
+ *expr = NULL;
+ goto syntax;
+ }
+
+ return MATCH_YES;
+
+syntax:
+ gfc_error ("Syntax error in character length specification at %C");
+ return MATCH_ERROR;
+}
+
+
+/* Special subroutine for finding a symbol. If we're compiling a
+ function or subroutine and the parent compilation unit is an
+ interface, then check to see if the name we've been given is the
+ name of the interface (located in another namespace). If so,
+ return that symbol. If not, use gfc_get_symbol(). */
+
+static int
+find_special (const char *name, gfc_symbol ** result)
+{
+ gfc_state_data *s;
+
+ if (gfc_current_state () != COMP_SUBROUTINE
+ && gfc_current_state () != COMP_FUNCTION)
+ goto normal;
+
+ s = gfc_state_stack->previous;
+ if (s == NULL)
+ goto normal;
+
+ if (s->state != COMP_INTERFACE)
+ goto normal;
+ if (s->sym == NULL)
+ goto normal; /* Nameless interface */
+
+ if (strcmp (name, s->sym->name) == 0)
+ {
+ *result = s->sym;
+ return 0;
+ }
+
+normal:
+ return gfc_get_symbol (name, NULL, result);
+}
+
+
+/* Special subroutine for getting a symbol node associated with a
+ procedure name, used in SUBROUTINE and FUNCTION statements. The
+ symbol is created in the parent using with symtree node in the
+ child unit pointing to the symbol. If the current namespace has no
+ parent, then the symbol is just created in the current unit. */
+
+static int
+get_proc_name (const char *name, gfc_symbol ** result)
+{
+ gfc_symtree *st;
+ gfc_symbol *sym;
+ int rc;
+
+ if (gfc_current_ns->parent == NULL)
+ return gfc_get_symbol (name, NULL, result);
+
+ rc = gfc_get_symbol (name, gfc_current_ns->parent, result);
+ if (*result == NULL)
+ return rc;
+
+ /* Deal with ENTRY problem */
+
+ st = gfc_new_symtree (&gfc_current_ns->sym_root, name);
+
+ sym = *result;
+ st->n.sym = sym;
+ sym->refs++;
+
+ /* See if the procedure should be a module procedure */
+
+ if (sym->ns->proc_name != NULL
+ && sym->ns->proc_name->attr.flavor == FL_MODULE
+ && sym->attr.proc != PROC_MODULE
+ && gfc_add_procedure (&sym->attr, PROC_MODULE, NULL) == FAILURE)
+ rc = 2;
+
+ return rc;
+}
+
+
+/* Function called by variable_decl() that adds a name to the symbol
+ table. */
+
+static try
+build_sym (const char *name, gfc_charlen * cl,
+ gfc_array_spec ** as, locus * var_locus)
+{
+ symbol_attribute attr;
+ gfc_symbol *sym;
+
+ if (find_special (name, &sym))
+ return FAILURE;
+
+ /* Start updating the symbol table. Add basic type attribute
+ if present. */
+ if (current_ts.type != BT_UNKNOWN
+ &&(sym->attr.implicit_type == 0
+ || !gfc_compare_types (&sym->ts, &current_ts))
+ && gfc_add_type (sym, &current_ts, var_locus) == FAILURE)
+ return FAILURE;
+
+ if (sym->ts.type == BT_CHARACTER)
+ sym->ts.cl = cl;
+
+ /* Add dimension attribute if present. */
+ if (gfc_set_array_spec (sym, *as, var_locus) == FAILURE)
+ return FAILURE;
+ *as = NULL;
+
+ /* Add attribute to symbol. The copy is so that we can reset the
+ dimension attribute. */
+ attr = current_attr;
+ attr.dimension = 0;
+
+ if (gfc_copy_attr (&sym->attr, &attr, var_locus) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+/* Function called by variable_decl() that adds an initialization
+ expression to a symbol. */
+
+static try
+add_init_expr_to_sym (const char *name, gfc_expr ** initp,
+ locus * var_locus)
+{
+ symbol_attribute attr;
+ gfc_symbol *sym;
+ gfc_expr *init;
+
+ init = *initp;
+ if (find_special (name, &sym))
+ return FAILURE;
+
+ attr = sym->attr;
+
+ /* If this symbol is confirming an implicit parameter type,
+ then an initialization expression is not allowed. */
+ if (attr.flavor == FL_PARAMETER
+ && sym->value != NULL
+ && *initp != NULL)
+ {
+ gfc_error ("Initializer not allowed for PARAMETER '%s' at %C",
+ sym->name);
+ return FAILURE;
+ }
+
+ if (init == NULL)
+ {
+ /* An initializer is required for PARAMETER declarations. */
+ if (attr.flavor == FL_PARAMETER)
+ {
+ gfc_error ("PARAMETER at %L is missing an initializer", var_locus);
+ return FAILURE;
+ }
+ }
+ else
+ {
+ /* If a variable appears in a DATA block, it cannot have an
+ initializer. */
+ if (sym->attr.data)
+ {
+ gfc_error
+ ("Variable '%s' at %C with an initializer already appears "
+ "in a DATA statement", sym->name);
+ return FAILURE;
+ }
+
+ /* Checking a derived type parameter has to be put off until later. */
+ if (sym->ts.type != BT_DERIVED && init->ts.type != BT_DERIVED
+ && gfc_check_assign_symbol (sym, init) == FAILURE)
+ return FAILURE;
+
+ /* Add initializer. Make sure we keep the ranks sane. */
+ if (sym->attr.dimension && init->rank == 0)
+ init->rank = sym->as->rank;
+
+ sym->value = init;
+ *initp = NULL;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Function called by variable_decl() that adds a name to a structure
+ being built. */
+
+static try
+build_struct (const char *name, gfc_charlen * cl, gfc_expr ** init,
+ gfc_array_spec ** as)
+{
+ gfc_component *c;
+
+ /* If the current symbol is of the same derived type that we're
+ constructing, it must have the pointer attribute. */
+ if (current_ts.type == BT_DERIVED
+ && current_ts.derived == gfc_current_block ()
+ && current_attr.pointer == 0)
+ {
+ gfc_error ("Component at %C must have the POINTER attribute");
+ return FAILURE;
+ }
+
+ if (gfc_current_block ()->attr.pointer
+ && (*as)->rank != 0)
+ {
+ if ((*as)->type != AS_DEFERRED && (*as)->type != AS_EXPLICIT)
+ {
+ gfc_error ("Array component of structure at %C must have explicit "
+ "or deferred shape");
+ return FAILURE;
+ }
+ }
+
+ if (gfc_add_component (gfc_current_block (), name, &c) == FAILURE)
+ return FAILURE;
+
+ c->ts = current_ts;
+ c->ts.cl = cl;
+ gfc_set_component_attr (c, &current_attr);
+
+ c->initializer = *init;
+ *init = NULL;
+
+ c->as = *as;
+ if (c->as != NULL)
+ c->dimension = 1;
+ *as = NULL;
+
+ /* Check array components. */
+ if (!c->dimension)
+ return SUCCESS;
+
+ if (c->pointer)
+ {
+ if (c->as->type != AS_DEFERRED)
+ {
+ gfc_error ("Pointer array component of structure at %C "
+ "must have a deferred shape");
+ return FAILURE;
+ }
+ }
+ else
+ {
+ if (c->as->type != AS_EXPLICIT)
+ {
+ gfc_error
+ ("Array component of structure at %C must have an explicit "
+ "shape");
+ return FAILURE;
+ }
+ }
+
+ return SUCCESS;
+}
+
+
+/* Match a 'NULL()', and possibly take care of some side effects. */
+
+match
+gfc_match_null (gfc_expr ** result)
+{
+ gfc_symbol *sym;
+ gfc_expr *e;
+ match m;
+
+ m = gfc_match (" null ( )");
+ if (m != MATCH_YES)
+ return m;
+
+ /* The NULL symbol now has to be/become an intrinsic function. */
+ if (gfc_get_symbol ("null", NULL, &sym))
+ {
+ gfc_error ("NULL() initialization at %C is ambiguous");
+ return MATCH_ERROR;
+ }
+
+ gfc_intrinsic_symbol (sym);
+
+ if (sym->attr.proc != PROC_INTRINSIC
+ && (gfc_add_procedure (&sym->attr, PROC_INTRINSIC, NULL) == FAILURE
+ || gfc_add_function (&sym->attr, NULL) == FAILURE))
+ return MATCH_ERROR;
+
+ e = gfc_get_expr ();
+ e->where = *gfc_current_locus ();
+ e->expr_type = EXPR_NULL;
+ e->ts.type = BT_UNKNOWN;
+
+ *result = e;
+
+ return MATCH_YES;
+}
+
+
+/* Get an expression for a default initializer. */
+static gfc_expr *
+default_initializer (void)
+{
+ gfc_constructor *tail;
+ gfc_expr *init;
+ gfc_component *c;
+
+ init = NULL;
+
+ /* First see if we have a default initializer. */
+ for (c = current_ts.derived->components; c; c = c->next)
+ {
+ if (c->initializer && init == NULL)
+ init = gfc_get_expr ();
+ }
+
+ if (init == NULL)
+ return NULL;
+
+ init->expr_type = EXPR_STRUCTURE;
+ init->ts = current_ts;
+ init->where = current_ts.derived->declared_at;
+ tail = NULL;
+ for (c = current_ts.derived->components; c; c = c->next)
+ {
+ if (tail == NULL)
+ init->value.constructor = tail = gfc_get_constructor ();
+ else
+ {
+ tail->next = gfc_get_constructor ();
+ tail = tail->next;
+ }
+
+ if (c->initializer)
+ tail->expr = gfc_copy_expr (c->initializer);
+ }
+ return init;
+}
+
+
+/* Match a variable name with an optional initializer. When this
+ subroutine is called, a variable is expected to be parsed next.
+ Depending on what is happening at the moment, updates either the
+ symbol table or the current interface. */
+
+static match
+variable_decl (void)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_expr *initializer, *char_len;
+ gfc_array_spec *as;
+ gfc_charlen *cl;
+ locus var_locus;
+ match m;
+ try t;
+
+ initializer = NULL;
+ as = NULL;
+
+ /* When we get here, we've just matched a list of attributes and
+ maybe a type and a double colon. The next thing we expect to see
+ is the name of the symbol. */
+ m = gfc_match_name (name);
+ if (m != MATCH_YES)
+ goto cleanup;
+
+ var_locus = *gfc_current_locus ();
+
+ /* Now we could see the optional array spec. or character length. */
+ m = gfc_match_array_spec (&as);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ as = gfc_copy_array_spec (current_as);
+
+ char_len = NULL;
+ cl = NULL;
+
+ if (current_ts.type == BT_CHARACTER)
+ {
+ switch (match_char_length (&char_len))
+ {
+ case MATCH_YES:
+ cl = gfc_get_charlen ();
+ cl->next = gfc_current_ns->cl_list;
+ gfc_current_ns->cl_list = cl;
+
+ cl->length = char_len;
+ break;
+
+ case MATCH_NO:
+ cl = current_ts.cl;
+ break;
+
+ case MATCH_ERROR:
+ goto cleanup;
+ }
+ }
+
+ /* OK, we've successfully matched the declaration. Now put the
+ symbol in the current namespace, because it might be used in the
+ optional intialization expression for this symbol, e.g. this is
+ perfectly legal:
+
+ integer, parameter :: i = huge(i)
+
+ This is only true for parameters or variables of a basic type.
+ For components of derived types, it is not true, so we don't
+ create a symbol for those yet. If we fail to create the symbol,
+ bail out. */
+ if (gfc_current_state () != COMP_DERIVED
+ && build_sym (name, cl, &as, &var_locus) == FAILURE)
+ {
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ /* In functions that have a RESULT variable defined, the function
+ name always refers to function calls. Therefore, the name is
+ not allowed to appear in specification statements. */
+ if (gfc_current_state () == COMP_FUNCTION
+ && gfc_current_block () != NULL
+ && gfc_current_block ()->result != NULL
+ && gfc_current_block ()->result != gfc_current_block ()
+ && strcmp (gfc_current_block ()->name, name) == 0)
+ {
+ gfc_error ("Function name '%s' not allowed at %C", name);
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ /* The double colon must be present in order to have initializers.
+ Otherwise the statement is ambiguous with an assignment statement. */
+ if (colon_seen)
+ {
+ if (gfc_match (" =>") == MATCH_YES)
+ {
+
+ if (!current_attr.pointer)
+ {
+ gfc_error ("Initialization at %C isn't for a pointer variable");
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ m = gfc_match_null (&initializer);
+ if (m == MATCH_NO)
+ {
+ gfc_error ("Pointer initialization requires a NULL at %C");
+ m = MATCH_ERROR;
+ }
+
+ if (gfc_pure (NULL))
+ {
+ gfc_error
+ ("Initialization of pointer at %C is not allowed in a "
+ "PURE procedure");
+ m = MATCH_ERROR;
+ }
+
+ if (m != MATCH_YES)
+ goto cleanup;
+
+ initializer->ts = current_ts;
+
+ }
+ else if (gfc_match_char ('=') == MATCH_YES)
+ {
+ if (current_attr.pointer)
+ {
+ gfc_error
+ ("Pointer initialization at %C requires '=>', not '='");
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ m = gfc_match_init_expr (&initializer);
+ if (m == MATCH_NO)
+ {
+ gfc_error ("Expected an initialization expression at %C");
+ m = MATCH_ERROR;
+ }
+
+ if (current_attr.flavor != FL_PARAMETER && gfc_pure (NULL))
+ {
+ gfc_error
+ ("Initialization of variable at %C is not allowed in a "
+ "PURE procedure");
+ m = MATCH_ERROR;
+ }
+
+ if (m != MATCH_YES)
+ goto cleanup;
+ }
+ else if (current_ts.type == BT_DERIVED)
+ {
+ initializer = default_initializer ();
+ }
+ }
+
+ /* Add the initializer. Note that it is fine if &initializer is
+ NULL here, because we sometimes also need to check if a
+ declaration *must* have an initialization expression. */
+ if (gfc_current_state () != COMP_DERIVED)
+ t = add_init_expr_to_sym (name, &initializer, &var_locus);
+ else
+ t = build_struct (name, cl, &initializer, &as);
+
+ m = (t == SUCCESS) ? MATCH_YES : MATCH_ERROR;
+
+cleanup:
+ /* Free stuff up and return. */
+ gfc_free_expr (initializer);
+ gfc_free_array_spec (as);
+
+ return m;
+}
+
+
+/* Match an extended-f77 kind specification. */
+
+match
+gfc_match_old_kind_spec (gfc_typespec * ts)
+{
+ match m;
+
+ if (gfc_match_char ('*') != MATCH_YES)
+ return MATCH_NO;
+
+ m = gfc_match_small_literal_int (&ts->kind);
+ if (m != MATCH_YES)
+ return MATCH_ERROR;
+
+ /* Massage the kind numbers for complex types. */
+ if (ts->type == BT_COMPLEX && ts->kind == 8)
+ ts->kind = 4;
+ if (ts->type == BT_COMPLEX && ts->kind == 16)
+ ts->kind = 8;
+
+ if (gfc_validate_kind (ts->type, ts->kind) == -1)
+ {
+ gfc_error ("Old-style kind %d not supported for type %s at %C",
+ ts->kind, gfc_basic_typename (ts->type));
+
+ return MATCH_ERROR;
+ }
+
+ return MATCH_YES;
+}
+
+
+/* Match a kind specification. Since kinds are generally optional, we
+ usually return MATCH_NO if something goes wrong. If a "kind="
+ string is found, then we know we have an error. */
+
+match
+gfc_match_kind_spec (gfc_typespec * ts)
+{
+ locus where;
+ gfc_expr *e;
+ match m, n;
+ const char *msg;
+
+ m = MATCH_NO;
+ e = NULL;
+
+ where = *gfc_current_locus ();
+
+ if (gfc_match_char ('(') == MATCH_NO)
+ return MATCH_NO;
+
+ /* Also gobbles optional text. */
+ if (gfc_match (" kind = ") == MATCH_YES)
+ m = MATCH_ERROR;
+
+ n = gfc_match_init_expr (&e);
+ if (n == MATCH_NO)
+ gfc_error ("Expected initialization expression at %C");
+ if (n != MATCH_YES)
+ return MATCH_ERROR;
+
+ if (e->rank != 0)
+ {
+ gfc_error ("Expected scalar initialization expression at %C");
+ m = MATCH_ERROR;
+ goto no_match;
+ }
+
+ msg = gfc_extract_int (e, &ts->kind);
+ if (msg != NULL)
+ {
+ gfc_error (msg);
+ m = MATCH_ERROR;
+ goto no_match;
+ }
+
+ gfc_free_expr (e);
+ e = NULL;
+
+ if (gfc_validate_kind (ts->type, ts->kind) == -1)
+ {
+ gfc_error ("Kind %d not supported for type %s at %C", ts->kind,
+ gfc_basic_typename (ts->type));
+
+ m = MATCH_ERROR;
+ goto no_match;
+ }
+
+ if (gfc_match_char (')') != MATCH_YES)
+ {
+ gfc_error ("Missing right paren at %C");
+ goto no_match;
+ }
+
+ return MATCH_YES;
+
+no_match:
+ gfc_free_expr (e);
+ gfc_set_locus (&where);
+ return m;
+}
+
+
+/* Match the various kind/length specifications in a CHARACTER
+ declaration. We don't return MATCH_NO. */
+
+static match
+match_char_spec (gfc_typespec * ts)
+{
+ int i, kind, seen_length;
+ gfc_charlen *cl;
+ gfc_expr *len;
+ match m;
+
+ kind = gfc_default_character_kind ();
+ len = NULL;
+ seen_length = 0;
+
+ /* Try the old-style specification first. */
+ old_char_selector = 0;
+
+ m = match_char_length (&len);
+ if (m != MATCH_NO)
+ {
+ if (m == MATCH_YES)
+ old_char_selector = 1;
+ seen_length = 1;
+ goto done;
+ }
+
+ m = gfc_match_char ('(');
+ if (m != MATCH_YES)
+ {
+ m = MATCH_YES; /* character without length is a single char */
+ goto done;
+ }
+
+ /* Try the weird case: ( KIND = <int> [ , LEN = <len-param> ] ) */
+ if (gfc_match (" kind =") == MATCH_YES)
+ {
+ m = gfc_match_small_int (&kind);
+ if (m == MATCH_ERROR)
+ goto done;
+ if (m == MATCH_NO)
+ goto syntax;
+
+ if (gfc_match (" , len =") == MATCH_NO)
+ goto rparen;
+
+ m = char_len_param_value (&len);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto done;
+ seen_length = 1;
+
+ goto rparen;
+ }
+
+ /* Try to match ( LEN = <len-param> ) or ( LEN = <len-param>, KIND = <int> ) */
+ if (gfc_match (" len =") == MATCH_YES)
+ {
+ m = char_len_param_value (&len);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto done;
+ seen_length = 1;
+
+ if (gfc_match_char (')') == MATCH_YES)
+ goto done;
+
+ if (gfc_match (" , kind =") != MATCH_YES)
+ goto syntax;
+
+ gfc_match_small_int (&kind);
+
+ if (gfc_validate_kind (BT_CHARACTER, kind) == -1)
+ {
+ gfc_error ("Kind %d is not a CHARACTER kind at %C", kind);
+ return MATCH_YES;
+ }
+
+ goto rparen;
+ }
+
+ /* Try to match ( <len-param> ) or ( <len-param> , [ KIND = ] <int> ) */
+ m = char_len_param_value (&len);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto done;
+ seen_length = 1;
+
+ m = gfc_match_char (')');
+ if (m == MATCH_YES)
+ goto done;
+
+ if (gfc_match_char (',') != MATCH_YES)
+ goto syntax;
+
+ gfc_match (" kind ="); /* Gobble optional text */
+
+ m = gfc_match_small_int (&kind);
+ if (m == MATCH_ERROR)
+ goto done;
+ if (m == MATCH_NO)
+ goto syntax;
+
+rparen:
+ /* Require a right-paren at this point. */
+ m = gfc_match_char (')');
+ if (m == MATCH_YES)
+ goto done;
+
+syntax:
+ gfc_error ("Syntax error in CHARACTER declaration at %C");
+ m = MATCH_ERROR;
+
+done:
+ if (m == MATCH_YES && gfc_validate_kind (BT_CHARACTER, kind) == -1)
+ {
+ gfc_error ("Kind %d is not a CHARACTER kind at %C", kind);
+ m = MATCH_ERROR;
+ }
+
+ if (m != MATCH_YES)
+ {
+ gfc_free_expr (len);
+ return m;
+ }
+
+ /* Do some final massaging of the length values. */
+ cl = gfc_get_charlen ();
+ cl->next = gfc_current_ns->cl_list;
+ gfc_current_ns->cl_list = cl;
+
+ if (seen_length == 0)
+ cl->length = gfc_int_expr (1);
+ else
+ {
+ if (len == NULL || gfc_extract_int (len, &i) != NULL || i >= 0)
+ cl->length = len;
+ else
+ {
+ gfc_free_expr (len);
+ cl->length = gfc_int_expr (0);
+ }
+ }
+
+ ts->cl = cl;
+ ts->kind = kind;
+
+ return MATCH_YES;
+}
+
+
+/* Matches a type specification. If successful, sets the ts structure
+ to the matched specification. This is necessary for FUNCTION and
+ IMPLICIT statements.
+
+ If kind_flag is nonzero, then we check for the optional kind
+ specification. Not doing so is needed for matching an IMPLICIT
+ statement correctly. */
+
+match
+gfc_match_type_spec (gfc_typespec * ts, int kind_flag)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_symbol *sym;
+ match m;
+
+ gfc_clear_ts (ts);
+
+ if (gfc_match (" integer") == MATCH_YES)
+ {
+ ts->type = BT_INTEGER;
+ ts->kind = gfc_default_integer_kind ();
+ goto get_kind;
+ }
+
+ if (gfc_match (" character") == MATCH_YES)
+ {
+ ts->type = BT_CHARACTER;
+ return match_char_spec (ts);
+ }
+
+ if (gfc_match (" real") == MATCH_YES)
+ {
+ ts->type = BT_REAL;
+ ts->kind = gfc_default_real_kind ();
+ goto get_kind;
+ }
+
+ if (gfc_match (" double precision") == MATCH_YES)
+ {
+ ts->type = BT_REAL;
+ ts->kind = gfc_default_double_kind ();
+ return MATCH_YES;
+ }
+
+ if (gfc_match (" complex") == MATCH_YES)
+ {
+ ts->type = BT_COMPLEX;
+ ts->kind = gfc_default_complex_kind ();
+ goto get_kind;
+ }
+
+ if (gfc_match (" double complex") == MATCH_YES)
+ {
+ ts->type = BT_COMPLEX;
+ ts->kind = gfc_default_double_kind ();
+ return MATCH_YES;
+ }
+
+ if (gfc_match (" logical") == MATCH_YES)
+ {
+ ts->type = BT_LOGICAL;
+ ts->kind = gfc_default_logical_kind ();
+ goto get_kind;
+ }
+
+ m = gfc_match (" type ( %n )", name);
+ if (m != MATCH_YES)
+ return m;
+
+ /* Search for the name but allow the components to be defined later. */
+ if (gfc_get_ha_symbol (name, &sym))
+ {
+ gfc_error ("Type name '%s' at %C is ambiguous", name);
+ return MATCH_ERROR;
+ }
+
+ if (sym->attr.flavor != FL_DERIVED
+ && gfc_add_flavor (&sym->attr, FL_DERIVED, NULL) == FAILURE)
+ return MATCH_ERROR;
+
+ ts->type = BT_DERIVED;
+ ts->kind = 0;
+ ts->derived = sym;
+
+ return MATCH_YES;
+
+get_kind:
+ /* For all types except double, derived and character, look for an
+ optional kind specifier. MATCH_NO is actually OK at this point. */
+ if (kind_flag == 0)
+ return MATCH_YES;
+
+ m = gfc_match_kind_spec (ts);
+ if (m == MATCH_NO && ts->type != BT_CHARACTER)
+ m = gfc_match_old_kind_spec (ts);
+
+ if (m == MATCH_NO)
+ m = MATCH_YES; /* No kind specifier found. */
+
+ return m;
+}
+
+
+/* Matches an attribute specification including array specs. If
+ successful, leaves the variables current_attr and current_as
+ holding the specification. Also sets the colon_seen variable for
+ later use by matchers associated with initializations.
+
+ This subroutine is a little tricky in the sense that we don't know
+ if we really have an attr-spec until we hit the double colon.
+ Until that time, we can only return MATCH_NO. This forces us to
+ check for duplicate specification at this level. */
+
+static match
+match_attr_spec (void)
+{
+
+ /* Modifiers that can exist in a type statement. */
+ typedef enum
+ { GFC_DECL_BEGIN = 0,
+ DECL_ALLOCATABLE = GFC_DECL_BEGIN, DECL_DIMENSION, DECL_EXTERNAL,
+ DECL_IN, DECL_OUT, DECL_INOUT, DECL_INTRINSIC, DECL_OPTIONAL,
+ DECL_PARAMETER, DECL_POINTER, DECL_PRIVATE, DECL_PUBLIC, DECL_SAVE,
+ DECL_TARGET, DECL_COLON, DECL_NONE,
+ GFC_DECL_END /* Sentinel */
+ }
+ decl_types;
+
+/* GFC_DECL_END is the sentinel, index starts at 0. */
+#define NUM_DECL GFC_DECL_END
+
+ static mstring decls[] = {
+ minit (", allocatable", DECL_ALLOCATABLE),
+ minit (", dimension", DECL_DIMENSION),
+ minit (", external", DECL_EXTERNAL),
+ minit (", intent ( in )", DECL_IN),
+ minit (", intent ( out )", DECL_OUT),
+ minit (", intent ( in out )", DECL_INOUT),
+ minit (", intrinsic", DECL_INTRINSIC),
+ minit (", optional", DECL_OPTIONAL),
+ minit (", parameter", DECL_PARAMETER),
+ minit (", pointer", DECL_POINTER),
+ minit (", private", DECL_PRIVATE),
+ minit (", public", DECL_PUBLIC),
+ minit (", save", DECL_SAVE),
+ minit (", target", DECL_TARGET),
+ minit ("::", DECL_COLON),
+ minit (NULL, DECL_NONE)
+ };
+
+ locus start, seen_at[NUM_DECL];
+ int seen[NUM_DECL];
+ decl_types d;
+ const char *attr;
+ match m;
+ try t;
+
+ gfc_clear_attr (&current_attr);
+ start = *gfc_current_locus ();
+
+ current_as = NULL;
+ colon_seen = 0;
+
+ /* See if we get all of the keywords up to the final double colon. */
+ for (d = GFC_DECL_BEGIN; d != GFC_DECL_END; d++)
+ seen[d] = 0;
+
+ for (;;)
+ {
+ d = (decl_types) gfc_match_strings (decls);
+ if (d == DECL_NONE || d == DECL_COLON)
+ break;
+
+ seen[d]++;
+ seen_at[d] = *gfc_current_locus ();
+
+ if (d == DECL_DIMENSION)
+ {
+ m = gfc_match_array_spec (&current_as);
+
+ if (m == MATCH_NO)
+ {
+ gfc_error ("Missing dimension specification at %C");
+ m = MATCH_ERROR;
+ }
+
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ }
+ }
+
+ /* No double colon, so assume that we've been looking at something
+ else the whole time. */
+ if (d == DECL_NONE)
+ {
+ m = MATCH_NO;
+ goto cleanup;
+ }
+
+ /* Since we've seen a double colon, we have to be looking at an
+ attr-spec. This means that we can now issue errors. */
+ for (d = GFC_DECL_BEGIN; d != GFC_DECL_END; d++)
+ if (seen[d] > 1)
+ {
+ switch (d)
+ {
+ case DECL_ALLOCATABLE:
+ attr = "ALLOCATABLE";
+ break;
+ case DECL_DIMENSION:
+ attr = "DIMENSION";
+ break;
+ case DECL_EXTERNAL:
+ attr = "EXTERNAL";
+ break;
+ case DECL_IN:
+ attr = "INTENT (IN)";
+ break;
+ case DECL_OUT:
+ attr = "INTENT (OUT)";
+ break;
+ case DECL_INOUT:
+ attr = "INTENT (IN OUT)";
+ break;
+ case DECL_INTRINSIC:
+ attr = "INTRINSIC";
+ break;
+ case DECL_OPTIONAL:
+ attr = "OPTIONAL";
+ break;
+ case DECL_PARAMETER:
+ attr = "PARAMETER";
+ break;
+ case DECL_POINTER:
+ attr = "POINTER";
+ break;
+ case DECL_PRIVATE:
+ attr = "PRIVATE";
+ break;
+ case DECL_PUBLIC:
+ attr = "PUBLIC";
+ break;
+ case DECL_SAVE:
+ attr = "SAVE";
+ break;
+ case DECL_TARGET:
+ attr = "TARGET";
+ break;
+ default:
+ attr = NULL; /* This shouldn't happen */
+ }
+
+ gfc_error ("Duplicate %s attribute at %L", attr, &seen_at[d]);
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ /* Now that we've dealt with duplicate attributes, add the attributes
+ to the current attribute. */
+ for (d = GFC_DECL_BEGIN; d != GFC_DECL_END; d++)
+ {
+ if (seen[d] == 0)
+ continue;
+
+ if (gfc_current_state () == COMP_DERIVED
+ && d != DECL_DIMENSION && d != DECL_POINTER
+ && d != DECL_COLON && d != DECL_NONE)
+ {
+
+ gfc_error ("Attribute at %L is not allowed in a TYPE definition",
+ &seen_at[d]);
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ switch (d)
+ {
+ case DECL_ALLOCATABLE:
+ t = gfc_add_allocatable (&current_attr, &seen_at[d]);
+ break;
+
+ case DECL_DIMENSION:
+ t = gfc_add_dimension (&current_attr, &seen_at[d]);
+ break;
+
+ case DECL_EXTERNAL:
+ t = gfc_add_external (&current_attr, &seen_at[d]);
+ break;
+
+ case DECL_IN:
+ t = gfc_add_intent (&current_attr, INTENT_IN, &seen_at[d]);
+ break;
+
+ case DECL_OUT:
+ t = gfc_add_intent (&current_attr, INTENT_OUT, &seen_at[d]);
+ break;
+
+ case DECL_INOUT:
+ t = gfc_add_intent (&current_attr, INTENT_INOUT, &seen_at[d]);
+ break;
+
+ case DECL_INTRINSIC:
+ t = gfc_add_intrinsic (&current_attr, &seen_at[d]);
+ break;
+
+ case DECL_OPTIONAL:
+ t = gfc_add_optional (&current_attr, &seen_at[d]);
+ break;
+
+ case DECL_PARAMETER:
+ t = gfc_add_flavor (&current_attr, FL_PARAMETER, &seen_at[d]);
+ break;
+
+ case DECL_POINTER:
+ t = gfc_add_pointer (&current_attr, &seen_at[d]);
+ break;
+
+ case DECL_PRIVATE:
+ t = gfc_add_access (&current_attr, ACCESS_PRIVATE, &seen_at[d]);
+ break;
+
+ case DECL_PUBLIC:
+ t = gfc_add_access (&current_attr, ACCESS_PUBLIC, &seen_at[d]);
+ break;
+
+ case DECL_SAVE:
+ t = gfc_add_save (&current_attr, &seen_at[d]);
+ break;
+
+ case DECL_TARGET:
+ t = gfc_add_target (&current_attr, &seen_at[d]);
+ break;
+
+ default:
+ gfc_internal_error ("match_attr_spec(): Bad attribute");
+ }
+
+ if (t == FAILURE)
+ {
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+ }
+
+ colon_seen = 1;
+ return MATCH_YES;
+
+cleanup:
+ gfc_set_locus (&start);
+ gfc_free_array_spec (current_as);
+ current_as = NULL;
+ return m;
+}
+
+
+/* Match a data declaration statement. */
+
+match
+gfc_match_data_decl (void)
+{
+ gfc_symbol *sym;
+ match m;
+
+ m = gfc_match_type_spec (&current_ts, 1);
+ if (m != MATCH_YES)
+ return m;
+
+ if (current_ts.type == BT_DERIVED && gfc_current_state () != COMP_DERIVED)
+ {
+ sym = gfc_use_derived (current_ts.derived);
+
+ if (sym == NULL)
+ {
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ current_ts.derived = sym;
+ }
+
+ m = match_attr_spec ();
+ if (m == MATCH_ERROR)
+ {
+ m = MATCH_NO;
+ goto cleanup;
+ }
+
+ if (current_ts.type == BT_DERIVED && current_ts.derived->components == NULL)
+ {
+
+ if (current_attr.pointer && gfc_current_state () == COMP_DERIVED)
+ goto ok;
+
+ if (gfc_find_symbol (current_ts.derived->name,
+ current_ts.derived->ns->parent, 1, &sym) == 0)
+ goto ok;
+
+ /* Hope that an ambiguous symbol is itself masked by a type definition. */
+ if (sym != NULL && sym->attr.flavor == FL_DERIVED)
+ goto ok;
+
+ gfc_error ("Derived type at %C has not been previously defined");
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ok:
+ /* If we have an old-style character declaration, and no new-style
+ attribute specifications, then there a comma is optional between
+ the type specification and the variable list. */
+ if (m == MATCH_NO && current_ts.type == BT_CHARACTER && old_char_selector)
+ gfc_match_char (',');
+
+ /* Give the types/attributes to symbols that follow. */
+ for (;;)
+ {
+ m = variable_decl ();
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ break;
+
+ if (gfc_match_eos () == MATCH_YES)
+ goto cleanup;
+ if (gfc_match_char (',') != MATCH_YES)
+ break;
+ }
+
+ gfc_error ("Syntax error in data declaration at %C");
+ m = MATCH_ERROR;
+
+cleanup:
+ gfc_free_array_spec (current_as);
+ current_as = NULL;
+ return m;
+}
+
+
+/* Match a prefix associated with a function or subroutine
+ declaration. If the typespec pointer is nonnull, then a typespec
+ can be matched. Note that if nothing matches, MATCH_YES is
+ returned (the null string was matched). */
+
+static match
+match_prefix (gfc_typespec * ts)
+{
+ int seen_type;
+
+ gfc_clear_attr (&current_attr);
+ seen_type = 0;
+
+loop:
+ if (!seen_type && ts != NULL
+ && gfc_match_type_spec (ts, 1) == MATCH_YES
+ && gfc_match_space () == MATCH_YES)
+ {
+
+ seen_type = 1;
+ goto loop;
+ }
+
+ if (gfc_match ("elemental% ") == MATCH_YES)
+ {
+ if (gfc_add_elemental (&current_attr, NULL) == FAILURE)
+ return MATCH_ERROR;
+
+ goto loop;
+ }
+
+ if (gfc_match ("pure% ") == MATCH_YES)
+ {
+ if (gfc_add_pure (&current_attr, NULL) == FAILURE)
+ return MATCH_ERROR;
+
+ goto loop;
+ }
+
+ if (gfc_match ("recursive% ") == MATCH_YES)
+ {
+ if (gfc_add_recursive (&current_attr, NULL) == FAILURE)
+ return MATCH_ERROR;
+
+ goto loop;
+ }
+
+ /* At this point, the next item is not a prefix. */
+ return MATCH_YES;
+}
+
+
+/* Copy attributes matched by match_prefix() to attributes on a symbol. */
+
+static try
+copy_prefix (symbol_attribute * dest, locus * where)
+{
+
+ if (current_attr.pure && gfc_add_pure (dest, where) == FAILURE)
+ return FAILURE;
+
+ if (current_attr.elemental && gfc_add_elemental (dest, where) == FAILURE)
+ return FAILURE;
+
+ if (current_attr.recursive && gfc_add_recursive (dest, where) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+/* Match a formal argument list. */
+
+match
+gfc_match_formal_arglist (gfc_symbol * progname, int st_flag, int null_flag)
+{
+ gfc_formal_arglist *head, *tail, *p, *q;
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_symbol *sym;
+ match m;
+
+ head = tail = NULL;
+
+ if (gfc_match_char ('(') != MATCH_YES)
+ {
+ if (null_flag)
+ goto ok;
+ return MATCH_NO;
+ }
+
+ if (gfc_match_char (')') == MATCH_YES)
+ goto ok;
+
+ for (;;)
+ {
+ if (gfc_match_char ('*') == MATCH_YES)
+ sym = NULL;
+ else
+ {
+ m = gfc_match_name (name);
+ if (m != MATCH_YES)
+ goto cleanup;
+
+ if (gfc_get_symbol (name, NULL, &sym))
+ goto cleanup;
+ }
+
+ p = gfc_get_formal_arglist ();
+
+ if (head == NULL)
+ head = tail = p;
+ else
+ {
+ tail->next = p;
+ tail = p;
+ }
+
+ tail->sym = sym;
+
+ /* We don't add the VARIABLE flavor because the name could be a
+ dummy procedure. We don't apply these attributes to formal
+ arguments of statement functions. */
+ if (sym != NULL && !st_flag
+ && (gfc_add_dummy (&sym->attr, NULL) == FAILURE
+ || gfc_missing_attr (&sym->attr, NULL) == FAILURE))
+ {
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ /* The name of a program unit can be in a different namespace,
+ so check for it explicitly. After the statement is accepted,
+ the name is checked for especially in gfc_get_symbol(). */
+ if (gfc_new_block != NULL && sym != NULL
+ && strcmp (sym->name, gfc_new_block->name) == 0)
+ {
+ gfc_error ("Name '%s' at %C is the name of the procedure",
+ sym->name);
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ if (gfc_match_char (')') == MATCH_YES)
+ goto ok;
+
+ m = gfc_match_char (',');
+ if (m != MATCH_YES)
+ {
+ gfc_error ("Unexpected junk in formal argument list at %C");
+ goto cleanup;
+ }
+ }
+
+ok:
+ /* Check for duplicate symbols in the formal argument list. */
+ if (head != NULL)
+ {
+ for (p = head; p->next; p = p->next)
+ {
+ if (p->sym == NULL)
+ continue;
+
+ for (q = p->next; q; q = q->next)
+ if (p->sym == q->sym)
+ {
+ gfc_error
+ ("Duplicate symbol '%s' in formal argument list at %C",
+ p->sym->name);
+
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+ }
+ }
+
+ if (gfc_add_explicit_interface (progname, IFSRC_DECL, head, NULL) ==
+ FAILURE)
+ {
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ return MATCH_YES;
+
+cleanup:
+ gfc_free_formal_arglist (head);
+ return m;
+}
+
+
+/* Match a RESULT specification following a function declaration or
+ ENTRY statement. Also matches the end-of-statement. */
+
+static match
+match_result (gfc_symbol * function, gfc_symbol ** result)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_symbol *r;
+ match m;
+
+ if (gfc_match (" result (") != MATCH_YES)
+ return MATCH_NO;
+
+ m = gfc_match_name (name);
+ if (m != MATCH_YES)
+ return m;
+
+ if (gfc_match (" )%t") != MATCH_YES)
+ {
+ gfc_error ("Unexpected junk following RESULT variable at %C");
+ return MATCH_ERROR;
+ }
+
+ if (strcmp (function->name, name) == 0)
+ {
+ gfc_error
+ ("RESULT variable at %C must be different than function name");
+ return MATCH_ERROR;
+ }
+
+ if (gfc_get_symbol (name, NULL, &r))
+ return MATCH_ERROR;
+
+ if (gfc_add_flavor (&r->attr, FL_VARIABLE, NULL) == FAILURE
+ || gfc_add_result (&r->attr, NULL) == FAILURE)
+ return MATCH_ERROR;
+
+ *result = r;
+
+ return MATCH_YES;
+}
+
+
+/* Match a function declaration. */
+
+match
+gfc_match_function_decl (void)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_symbol *sym, *result;
+ locus old_loc;
+ match m;
+
+ if (gfc_current_state () != COMP_NONE
+ && gfc_current_state () != COMP_INTERFACE
+ && gfc_current_state () != COMP_CONTAINS)
+ return MATCH_NO;
+
+ gfc_clear_ts (&current_ts);
+
+ old_loc = *gfc_current_locus ();
+
+ m = match_prefix (&current_ts);
+ if (m != MATCH_YES)
+ {
+ gfc_set_locus (&old_loc);
+ return m;
+ }
+
+ if (gfc_match ("function% %n", name) != MATCH_YES)
+ {
+ gfc_set_locus (&old_loc);
+ return MATCH_NO;
+ }
+
+ if (get_proc_name (name, &sym))
+ return MATCH_ERROR;
+ gfc_new_block = sym;
+
+ m = gfc_match_formal_arglist (sym, 0, 0);
+ if (m == MATCH_NO)
+ gfc_error ("Expected formal argument list in function definition at %C");
+ else if (m == MATCH_ERROR)
+ goto cleanup;
+
+ result = NULL;
+
+ if (gfc_match_eos () != MATCH_YES)
+ {
+ /* See if a result variable is present. */
+ m = match_result (sym, &result);
+ if (m == MATCH_NO)
+ gfc_error ("Unexpected junk after function declaration at %C");
+
+ if (m != MATCH_YES)
+ {
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+ }
+
+ /* Make changes to the symbol. */
+ m = MATCH_ERROR;
+
+ if (gfc_add_function (&sym->attr, NULL) == FAILURE)
+ goto cleanup;
+
+ if (gfc_missing_attr (&sym->attr, NULL) == FAILURE
+ || copy_prefix (&sym->attr, &sym->declared_at) == FAILURE)
+ goto cleanup;
+
+ if (current_ts.type != BT_UNKNOWN && sym->ts.type != BT_UNKNOWN)
+ {
+ gfc_error ("Function '%s' at %C already has a type of %s", name,
+ gfc_basic_typename (sym->ts.type));
+ goto cleanup;
+ }
+
+ if (result == NULL)
+ {
+ sym->ts = current_ts;
+ sym->result = sym;
+ }
+ else
+ {
+ result->ts = current_ts;
+ sym->result = result;
+ }
+
+ return MATCH_YES;
+
+cleanup:
+ gfc_set_locus (&old_loc);
+ return m;
+}
+
+
+/* Match an ENTRY statement. */
+
+match
+gfc_match_entry (void)
+{
+ gfc_symbol *function, *result, *entry;
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_compile_state state;
+ match m;
+
+ m = gfc_match_name (name);
+ if (m != MATCH_YES)
+ return m;
+
+ if (get_proc_name (name, &entry))
+ return MATCH_ERROR;
+
+ gfc_enclosing_unit (&state);
+ switch (state)
+ {
+ case COMP_SUBROUTINE:
+ m = gfc_match_formal_arglist (entry, 0, 1);
+ if (m != MATCH_YES)
+ return MATCH_ERROR;
+
+ if (gfc_current_state () != COMP_SUBROUTINE)
+ goto exec_construct;
+
+ if (gfc_add_entry (&entry->attr, NULL) == FAILURE
+ || gfc_add_subroutine (&entry->attr, NULL) == FAILURE)
+ return MATCH_ERROR;
+
+ break;
+
+ case COMP_FUNCTION:
+ m = gfc_match_formal_arglist (entry, 0, 0);
+ if (m != MATCH_YES)
+ return MATCH_ERROR;
+
+ if (gfc_current_state () != COMP_FUNCTION)
+ goto exec_construct;
+ function = gfc_state_stack->sym;
+
+ result = NULL;
+
+ if (gfc_match_eos () == MATCH_YES)
+ {
+ if (gfc_add_entry (&entry->attr, NULL) == FAILURE
+ || gfc_add_function (&entry->attr, NULL) == FAILURE)
+ return MATCH_ERROR;
+
+ entry->result = function->result;
+
+ }
+ else
+ {
+ m = match_result (function, &result);
+ if (m == MATCH_NO)
+ gfc_syntax_error (ST_ENTRY);
+ if (m != MATCH_YES)
+ return MATCH_ERROR;
+
+ if (gfc_add_result (&result->attr, NULL) == FAILURE
+ || gfc_add_entry (&entry->attr, NULL) == FAILURE
+ || gfc_add_function (&entry->attr, NULL) == FAILURE)
+ return MATCH_ERROR;
+ }
+
+ if (function->attr.recursive && result == NULL)
+ {
+ gfc_error ("RESULT attribute required in ENTRY statement at %C");
+ return MATCH_ERROR;
+ }
+
+ break;
+
+ default:
+ goto exec_construct;
+ }
+
+ if (gfc_match_eos () != MATCH_YES)
+ {
+ gfc_syntax_error (ST_ENTRY);
+ return MATCH_ERROR;
+ }
+
+ return MATCH_YES;
+
+exec_construct:
+ gfc_error ("ENTRY statement at %C cannot appear within %s",
+ gfc_state_name (gfc_current_state ()));
+
+ return MATCH_ERROR;
+}
+
+
+/* Match a subroutine statement, including optional prefixes. */
+
+match
+gfc_match_subroutine (void)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_symbol *sym;
+ match m;
+
+ if (gfc_current_state () != COMP_NONE
+ && gfc_current_state () != COMP_INTERFACE
+ && gfc_current_state () != COMP_CONTAINS)
+ return MATCH_NO;
+
+ m = match_prefix (NULL);
+ if (m != MATCH_YES)
+ return m;
+
+ m = gfc_match ("subroutine% %n", name);
+ if (m != MATCH_YES)
+ return m;
+
+ if (get_proc_name (name, &sym))
+ return MATCH_ERROR;
+ gfc_new_block = sym;
+
+ if (gfc_add_subroutine (&sym->attr, NULL) == FAILURE)
+ return MATCH_ERROR;
+
+ if (gfc_match_formal_arglist (sym, 0, 1) != MATCH_YES)
+ return MATCH_ERROR;
+
+ if (gfc_match_eos () != MATCH_YES)
+ {
+ gfc_syntax_error (ST_SUBROUTINE);
+ return MATCH_ERROR;
+ }
+
+ if (copy_prefix (&sym->attr, &sym->declared_at) == FAILURE)
+ return MATCH_ERROR;
+
+ return MATCH_YES;
+}
+
+
+/* Match any of the various end-block statements. Returns the type of
+ END to the caller. The END INTERFACE, END IF, END DO and END
+ SELECT statements cannot be replaced by a single END statement. */
+
+match
+gfc_match_end (gfc_statement * st)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_compile_state state;
+ locus old_loc;
+ const char *block_name;
+ const char *target;
+ match m;
+
+ old_loc = *gfc_current_locus ();
+ if (gfc_match ("end") != MATCH_YES)
+ return MATCH_NO;
+
+ state = gfc_current_state ();
+ block_name =
+ gfc_current_block () == NULL ? NULL : gfc_current_block ()->name;
+
+ if (state == COMP_CONTAINS)
+ {
+ state = gfc_state_stack->previous->state;
+ block_name = gfc_state_stack->previous->sym == NULL ? NULL
+ : gfc_state_stack->previous->sym->name;
+ }
+
+ switch (state)
+ {
+ case COMP_NONE:
+ case COMP_PROGRAM:
+ *st = ST_END_PROGRAM;
+ target = " program";
+ break;
+
+ case COMP_SUBROUTINE:
+ *st = ST_END_SUBROUTINE;
+ target = " subroutine";
+ break;
+
+ case COMP_FUNCTION:
+ *st = ST_END_FUNCTION;
+ target = " function";
+ break;
+
+ case COMP_BLOCK_DATA:
+ *st = ST_END_BLOCK_DATA;
+ target = " block data";
+ break;
+
+ case COMP_MODULE:
+ *st = ST_END_MODULE;
+ target = " module";
+ break;
+
+ case COMP_INTERFACE:
+ *st = ST_END_INTERFACE;
+ target = " interface";
+ break;
+
+ case COMP_DERIVED:
+ *st = ST_END_TYPE;
+ target = " type";
+ break;
+
+ case COMP_IF:
+ *st = ST_ENDIF;
+ target = " if";
+ break;
+
+ case COMP_DO:
+ *st = ST_ENDDO;
+ target = " do";
+ break;
+
+ case COMP_SELECT:
+ *st = ST_END_SELECT;
+ target = " select";
+ break;
+
+ case COMP_FORALL:
+ *st = ST_END_FORALL;
+ target = " forall";
+ break;
+
+ case COMP_WHERE:
+ *st = ST_END_WHERE;
+ target = " where";
+ break;
+
+ default:
+ gfc_error ("Unexpected END statement at %C");
+ goto cleanup;
+ }
+
+ if (gfc_match_eos () == MATCH_YES)
+ {
+
+ if (*st == ST_ENDIF || *st == ST_ENDDO || *st == ST_END_SELECT
+ || *st == ST_END_INTERFACE || *st == ST_END_FORALL
+ || *st == ST_END_WHERE)
+ {
+
+ gfc_error ("%s statement expected at %C",
+ gfc_ascii_statement (*st));
+ goto cleanup;
+ }
+
+ return MATCH_YES;
+ }
+
+ /* Verify that we've got the sort of end-block that we're expecting. */
+ if (gfc_match (target) != MATCH_YES)
+ {
+ gfc_error ("Expecting %s statement at %C", gfc_ascii_statement (*st));
+ goto cleanup;
+ }
+
+ /* If we're at the end, make sure a block name wasn't required. */
+ if (gfc_match_eos () == MATCH_YES)
+ {
+
+ if (*st != ST_ENDDO && *st != ST_ENDIF && *st != ST_END_SELECT)
+ return MATCH_YES;
+
+ if (gfc_current_block () == NULL)
+ return MATCH_YES;
+
+ gfc_error ("Expected block name of '%s' in %s statement at %C",
+ block_name, gfc_ascii_statement (*st));
+
+ return MATCH_ERROR;
+ }
+
+ /* END INTERFACE has a special handler for its several possible endings. */
+ if (*st == ST_END_INTERFACE)
+ return gfc_match_end_interface ();
+
+ /* We haven't hit the end of statement, so what is left must be an end-name. */
+ m = gfc_match_space ();
+ if (m == MATCH_YES)
+ m = gfc_match_name (name);
+
+ if (m == MATCH_NO)
+ gfc_error ("Expected terminating name at %C");
+ if (m != MATCH_YES)
+ goto cleanup;
+
+ if (block_name == NULL)
+ goto syntax;
+
+ if (strcmp (name, block_name) != 0)
+ {
+ gfc_error ("Expected label '%s' for %s statement at %C", block_name,
+ gfc_ascii_statement (*st));
+ goto cleanup;
+ }
+
+ if (gfc_match_eos () == MATCH_YES)
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (*st);
+
+cleanup:
+ gfc_set_locus (&old_loc);
+ return MATCH_ERROR;
+}
+
+
+
+/***************** Attribute declaration statements ****************/
+
+/* Set the attribute of a single variable. */
+
+static match
+attr_decl1 (void)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_array_spec *as;
+ gfc_symbol *sym;
+ locus var_locus;
+ match m;
+
+ as = NULL;
+
+ m = gfc_match_name (name);
+ if (m != MATCH_YES)
+ goto cleanup;
+
+ if (find_special (name, &sym))
+ return MATCH_ERROR;
+
+ var_locus = *gfc_current_locus ();
+
+ /* Deal with possible array specification for certain attributes. */
+ if (current_attr.dimension
+ || current_attr.allocatable
+ || current_attr.pointer
+ || current_attr.target)
+ {
+ m = gfc_match_array_spec (&as);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ if (current_attr.dimension && m == MATCH_NO)
+ {
+ gfc_error
+ ("Missing array specification at %L in DIMENSION statement",
+ &var_locus);
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ if ((current_attr.allocatable || current_attr.pointer)
+ && (m == MATCH_YES) && (as->type != AS_DEFERRED))
+ {
+ gfc_error ("Array specification must be deferred at %L",
+ &var_locus);
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+ }
+
+ /* Update symbol table. DIMENSION attribute is set in gfc_set_array_spec(). */
+ if (current_attr.dimension == 0
+ && gfc_copy_attr (&sym->attr, &current_attr, NULL) == FAILURE)
+ {
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ if (gfc_set_array_spec (sym, as, &var_locus) == FAILURE)
+ {
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ if ((current_attr.external || current_attr.intrinsic)
+ && sym->attr.flavor != FL_PROCEDURE
+ && gfc_add_flavor (&sym->attr, FL_PROCEDURE, NULL) == FAILURE)
+ {
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ return MATCH_YES;
+
+cleanup:
+ gfc_free_array_spec (as);
+ return m;
+}
+
+
+/* Generic attribute declaration subroutine. Used for attributes that
+ just have a list of names. */
+
+static match
+attr_decl (void)
+{
+ match m;
+
+ /* Gobble the optional double colon, by simply ignoring the result
+ of gfc_match(). */
+ gfc_match (" ::");
+
+ for (;;)
+ {
+ m = attr_decl1 ();
+ if (m != MATCH_YES)
+ break;
+
+ if (gfc_match_eos () == MATCH_YES)
+ {
+ m = MATCH_YES;
+ break;
+ }
+
+ if (gfc_match_char (',') != MATCH_YES)
+ {
+ gfc_error ("Unexpected character in variable list at %C");
+ m = MATCH_ERROR;
+ break;
+ }
+ }
+
+ return m;
+}
+
+
+match
+gfc_match_external (void)
+{
+
+ gfc_clear_attr (&current_attr);
+ gfc_add_external (&current_attr, NULL);
+
+ return attr_decl ();
+}
+
+
+
+match
+gfc_match_intent (void)
+{
+ sym_intent intent;
+
+ intent = match_intent_spec ();
+ if (intent == INTENT_UNKNOWN)
+ return MATCH_ERROR;
+
+ gfc_clear_attr (&current_attr);
+ gfc_add_intent (&current_attr, intent, NULL); /* Can't fail */
+
+ return attr_decl ();
+}
+
+
+match
+gfc_match_intrinsic (void)
+{
+
+ gfc_clear_attr (&current_attr);
+ gfc_add_intrinsic (&current_attr, NULL);
+
+ return attr_decl ();
+}
+
+
+match
+gfc_match_optional (void)
+{
+
+ gfc_clear_attr (&current_attr);
+ gfc_add_optional (&current_attr, NULL);
+
+ return attr_decl ();
+}
+
+
+match
+gfc_match_pointer (void)
+{
+
+ gfc_clear_attr (&current_attr);
+ gfc_add_pointer (&current_attr, NULL);
+
+ return attr_decl ();
+}
+
+
+match
+gfc_match_allocatable (void)
+{
+
+ gfc_clear_attr (&current_attr);
+ gfc_add_allocatable (&current_attr, NULL);
+
+ return attr_decl ();
+}
+
+
+match
+gfc_match_dimension (void)
+{
+
+ gfc_clear_attr (&current_attr);
+ gfc_add_dimension (&current_attr, NULL);
+
+ return attr_decl ();
+}
+
+
+match
+gfc_match_target (void)
+{
+
+ gfc_clear_attr (&current_attr);
+ gfc_add_target (&current_attr, NULL);
+
+ return attr_decl ();
+}
+
+
+/* Match the list of entities being specified in a PUBLIC or PRIVATE
+ statement. */
+
+static match
+access_attr_decl (gfc_statement st)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ interface_type type;
+ gfc_user_op *uop;
+ gfc_symbol *sym;
+ gfc_intrinsic_op operator;
+ match m;
+
+ if (gfc_match (" ::") == MATCH_NO && gfc_match_space () == MATCH_NO)
+ goto done;
+
+ for (;;)
+ {
+ m = gfc_match_generic_spec (&type, name, &operator);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ return MATCH_ERROR;
+
+ switch (type)
+ {
+ case INTERFACE_NAMELESS:
+ goto syntax;
+
+ case INTERFACE_GENERIC:
+ if (gfc_get_symbol (name, NULL, &sym))
+ goto done;
+
+ if (gfc_add_access (&sym->attr,
+ (st ==
+ ST_PUBLIC) ? ACCESS_PUBLIC : ACCESS_PRIVATE,
+ NULL) == FAILURE)
+ return MATCH_ERROR;
+
+ break;
+
+ case INTERFACE_INTRINSIC_OP:
+ if (gfc_current_ns->operator_access[operator] == ACCESS_UNKNOWN)
+ {
+ gfc_current_ns->operator_access[operator] =
+ (st == ST_PUBLIC) ? ACCESS_PUBLIC : ACCESS_PRIVATE;
+ }
+ else
+ {
+ gfc_error ("Access specification of the %s operator at %C has "
+ "already been specified", gfc_op2string (operator));
+ goto done;
+ }
+
+ break;
+
+ case INTERFACE_USER_OP:
+ uop = gfc_get_uop (name);
+
+ if (uop->access == ACCESS_UNKNOWN)
+ {
+ uop->access =
+ (st == ST_PUBLIC) ? ACCESS_PUBLIC : ACCESS_PRIVATE;
+ }
+ else
+ {
+ gfc_error
+ ("Access specification of the .%s. operator at %C has "
+ "already been specified", sym->name);
+ goto done;
+ }
+
+ break;
+ }
+
+ if (gfc_match_char (',') == MATCH_NO)
+ break;
+ }
+
+ if (gfc_match_eos () != MATCH_YES)
+ goto syntax;
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (st);
+
+done:
+ return MATCH_ERROR;
+}
+
+
+/* The PRIVATE statement is a bit weird in that it can be a attribute
+ declaration, but also works as a standlone statement inside of a
+ type declaration or a module. */
+
+match
+gfc_match_private (gfc_statement * st)
+{
+
+ if (gfc_match ("private") != MATCH_YES)
+ return MATCH_NO;
+
+ if (gfc_current_state () == COMP_DERIVED)
+ {
+ if (gfc_match_eos () == MATCH_YES)
+ {
+ *st = ST_PRIVATE;
+ return MATCH_YES;
+ }
+
+ gfc_syntax_error (ST_PRIVATE);
+ return MATCH_ERROR;
+ }
+
+ if (gfc_match_eos () == MATCH_YES)
+ {
+ *st = ST_PRIVATE;
+ return MATCH_YES;
+ }
+
+ *st = ST_ATTR_DECL;
+ return access_attr_decl (ST_PRIVATE);
+}
+
+
+match
+gfc_match_public (gfc_statement * st)
+{
+
+ if (gfc_match ("public") != MATCH_YES)
+ return MATCH_NO;
+
+ if (gfc_match_eos () == MATCH_YES)
+ {
+ *st = ST_PUBLIC;
+ return MATCH_YES;
+ }
+
+ *st = ST_ATTR_DECL;
+ return access_attr_decl (ST_PUBLIC);
+}
+
+
+/* Workhorse for gfc_match_parameter. */
+
+static match
+do_parm (void)
+{
+ gfc_symbol *sym;
+ gfc_expr *init;
+ match m;
+
+ m = gfc_match_symbol (&sym, 0);
+ if (m == MATCH_NO)
+ gfc_error ("Expected variable name at %C in PARAMETER statement");
+
+ if (m != MATCH_YES)
+ return m;
+
+ if (gfc_match_char ('=') == MATCH_NO)
+ {
+ gfc_error ("Expected = sign in PARAMETER statement at %C");
+ return MATCH_ERROR;
+ }
+
+ m = gfc_match_init_expr (&init);
+ if (m == MATCH_NO)
+ gfc_error ("Expected expression at %C in PARAMETER statement");
+ if (m != MATCH_YES)
+ return m;
+
+ if (sym->ts.type == BT_UNKNOWN
+ && gfc_set_default_type (sym, 1, NULL) == FAILURE)
+ {
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ if (gfc_check_assign_symbol (sym, init) == FAILURE
+ || gfc_add_flavor (&sym->attr, FL_PARAMETER, NULL) == FAILURE)
+ {
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ sym->value = init;
+ return MATCH_YES;
+
+cleanup:
+ gfc_free_expr (init);
+ return m;
+}
+
+
+/* Match a parameter statement, with the weird syntax that these have. */
+
+match
+gfc_match_parameter (void)
+{
+ match m;
+
+ if (gfc_match_char ('(') == MATCH_NO)
+ return MATCH_NO;
+
+ for (;;)
+ {
+ m = do_parm ();
+ if (m != MATCH_YES)
+ break;
+
+ if (gfc_match (" )%t") == MATCH_YES)
+ break;
+
+ if (gfc_match_char (',') != MATCH_YES)
+ {
+ gfc_error ("Unexpected characters in PARAMETER statement at %C");
+ m = MATCH_ERROR;
+ break;
+ }
+ }
+
+ return m;
+}
+
+
+/* Save statements have a special syntax. */
+
+match
+gfc_match_save (void)
+{
+ gfc_symbol *sym;
+ match m;
+
+ if (gfc_match_eos () == MATCH_YES)
+ {
+ if (gfc_current_ns->seen_save)
+ {
+ gfc_error ("Blanket SAVE statement at %C follows previous "
+ "SAVE statement");
+
+ return MATCH_ERROR;
+ }
+
+ gfc_current_ns->save_all = gfc_current_ns->seen_save = 1;
+ return MATCH_YES;
+ }
+
+ if (gfc_current_ns->save_all)
+ {
+ gfc_error ("SAVE statement at %C follows blanket SAVE statement");
+ return MATCH_ERROR;
+ }
+
+ gfc_match (" ::");
+
+ for (;;)
+ {
+ m = gfc_match_symbol (&sym, 0);
+ switch (m)
+ {
+ case MATCH_YES:
+ if (gfc_add_save (&sym->attr, gfc_current_locus ()) == FAILURE)
+ return MATCH_ERROR;
+ goto next_item;
+
+ case MATCH_NO:
+ break;
+
+ case MATCH_ERROR:
+ return MATCH_ERROR;
+ }
+
+ m = gfc_match (" / %s /", &sym);
+ if (m == MATCH_ERROR)
+ return MATCH_ERROR;
+ if (m == MATCH_NO)
+ goto syntax;
+
+ if (gfc_add_saved_common (&sym->attr, NULL) == FAILURE)
+ return MATCH_ERROR;
+ gfc_current_ns->seen_save = 1;
+
+ next_item:
+ if (gfc_match_eos () == MATCH_YES)
+ break;
+ if (gfc_match_char (',') != MATCH_YES)
+ goto syntax;
+ }
+
+ return MATCH_YES;
+
+syntax:
+ gfc_error ("Syntax error in SAVE statement at %C");
+ return MATCH_ERROR;
+}
+
+
+/* Match a module procedure statement. Note that we have to modify
+ symbols in the parent's namespace because the current one was there
+ to receive symbols that are in a interface's formal argument list. */
+
+match
+gfc_match_modproc (void)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_symbol *sym;
+ match m;
+
+ if (gfc_state_stack->state != COMP_INTERFACE
+ || gfc_state_stack->previous == NULL
+ || current_interface.type == INTERFACE_NAMELESS)
+ {
+ gfc_error
+ ("MODULE PROCEDURE at %C must be in a generic module interface");
+ return MATCH_ERROR;
+ }
+
+ for (;;)
+ {
+ m = gfc_match_name (name);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m != MATCH_YES)
+ return MATCH_ERROR;
+
+ if (gfc_get_symbol (name, gfc_current_ns->parent, &sym))
+ return MATCH_ERROR;
+
+ if (sym->attr.proc != PROC_MODULE
+ && gfc_add_procedure (&sym->attr, PROC_MODULE, NULL) == FAILURE)
+ return MATCH_ERROR;
+
+ if (gfc_add_interface (sym) == FAILURE)
+ return MATCH_ERROR;
+
+ if (gfc_match_eos () == MATCH_YES)
+ break;
+ if (gfc_match_char (',') != MATCH_YES)
+ goto syntax;
+ }
+
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (ST_MODULE_PROC);
+ return MATCH_ERROR;
+}
+
+
+/* Match the beginning of a derived type declaration. If a type name
+ was the result of a function, then it is possible to have a symbol
+ already to be known as a derived type yet have no components. */
+
+match
+gfc_match_derived_decl (void)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ symbol_attribute attr;
+ gfc_symbol *sym;
+ match m;
+
+ if (gfc_current_state () == COMP_DERIVED)
+ return MATCH_NO;
+
+ gfc_clear_attr (&attr);
+
+loop:
+ if (gfc_match (" , private") == MATCH_YES)
+ {
+ if (gfc_find_state (COMP_MODULE) == FAILURE)
+ {
+ gfc_error
+ ("Derived type at %C can only be PRIVATE within a MODULE");
+ return MATCH_ERROR;
+ }
+
+ if (gfc_add_access (&attr, ACCESS_PRIVATE, NULL) == FAILURE)
+ return MATCH_ERROR;
+ goto loop;
+ }
+
+ if (gfc_match (" , public") == MATCH_YES)
+ {
+ if (gfc_find_state (COMP_MODULE) == FAILURE)
+ {
+ gfc_error ("Derived type at %C can only be PUBLIC within a MODULE");
+ return MATCH_ERROR;
+ }
+
+ if (gfc_add_access (&attr, ACCESS_PUBLIC, NULL) == FAILURE)
+ return MATCH_ERROR;
+ goto loop;
+ }
+
+ if (gfc_match (" ::") != MATCH_YES && attr.access != ACCESS_UNKNOWN)
+ {
+ gfc_error ("Expected :: in TYPE definition at %C");
+ return MATCH_ERROR;
+ }
+
+ m = gfc_match (" %n%t", name);
+ if (m != MATCH_YES)
+ return m;
+
+ /* Make sure the name isn't the name of an intrinsic type. The
+ 'double precision' type doesn't get past the name matcher. */
+ if (strcmp (name, "integer") == 0
+ || strcmp (name, "real") == 0
+ || strcmp (name, "character") == 0
+ || strcmp (name, "logical") == 0
+ || strcmp (name, "complex") == 0)
+ {
+ gfc_error
+ ("Type name '%s' at %C cannot be the same as an intrinsic type",
+ name);
+ return MATCH_ERROR;
+ }
+
+ if (gfc_get_symbol (name, NULL, &sym))
+ return MATCH_ERROR;
+
+ if (sym->ts.type != BT_UNKNOWN)
+ {
+ gfc_error ("Derived type name '%s' at %C already has a basic type "
+ "of %s", sym->name, gfc_typename (&sym->ts));
+ return MATCH_ERROR;
+ }
+
+ /* The symbol may already have the derived attribute without the
+ components. The ways this can happen is via a function
+ definition, an INTRINSIC statement or a subtype in another
+ derived type that is a pointer. The first part of the AND clause
+ is true if a the symbol is not the return value of a function. */
+ if (sym->attr.flavor != FL_DERIVED
+ && gfc_add_flavor (&sym->attr, FL_DERIVED, NULL) == FAILURE)
+ return MATCH_ERROR;
+
+ if (sym->components != NULL)
+ {
+ gfc_error
+ ("Derived type definition of '%s' at %C has already been defined",
+ sym->name);
+ return MATCH_ERROR;
+ }
+
+ if (attr.access != ACCESS_UNKNOWN
+ && gfc_add_access (&sym->attr, attr.access, NULL) == FAILURE)
+ return MATCH_ERROR;
+
+ gfc_new_block = sym;
+
+ return MATCH_YES;
+}
diff --git a/gcc/fortran/dependency.c b/gcc/fortran/dependency.c
new file mode 100644
index 00000000000..4dd076d8e3b
--- /dev/null
+++ b/gcc/fortran/dependency.c
@@ -0,0 +1,679 @@
+/* Dependency analysis
+ Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* dependency.c -- Expression dependency analysis code. */
+/* There's probably quite a bit of duplication in this file. We currently
+ have different dependency checking functions for different types
+ if dependencies. Ideally these would probably be merged. */
+
+
+#include "config.h"
+#include "gfortran.h"
+#include "dependency.h"
+#include <assert.h>
+
+/* static declarations */
+/* Enums */
+enum range {LHS, RHS, MID};
+
+/* Dependency types. These must be in reverse order of priority. */
+typedef enum
+{
+ GFC_DEP_ERROR,
+ GFC_DEP_EQUAL, /* Identical Ranges. */
+ GFC_DEP_FORWARD, /* eg. a(1:3), a(2:4). */
+ GFC_DEP_OVERLAP, /* May overlap in some other way. */
+ GFC_DEP_NODEP /* Distinct ranges. */
+}
+gfc_dependency;
+
+/* Macros */
+#define IS_ARRAY_EXPLICIT(as) ((as->type == AS_EXPLICIT ? 1 : 0))
+
+
+/* Returns 1 if the expr is an integer constant value 1, 0 if it is not or
+ def if the value could not be determined. */
+
+int
+gfc_expr_is_one (gfc_expr * expr, int def)
+{
+ assert (expr != NULL);
+
+ if (expr->expr_type != EXPR_CONSTANT)
+ return def;
+
+ if (expr->ts.type != BT_INTEGER)
+ return def;
+
+ return mpz_cmp_si (expr->value.integer, 1) == 0;
+}
+
+
+/* Compare two values. Returns 0 if e1 == e2, -1 if e1 < e2, +1 if e1 > e2,
+ and -2 if the relationship could not be determined. */
+
+int
+gfc_dep_compare_expr (gfc_expr * e1, gfc_expr * e2)
+{
+ int i;
+
+ if (e1->expr_type != e2->expr_type)
+ return -2;
+
+ switch (e1->expr_type)
+ {
+ case EXPR_CONSTANT:
+ if (e1->ts.type != BT_INTEGER || e2->ts.type != BT_INTEGER)
+ return -2;
+
+ i = mpz_cmp (e1->value.integer, e2->value.integer);
+ if (i == 0)
+ return 0;
+ else if (i < 0)
+ return -1;
+ return 1;
+
+ case EXPR_VARIABLE:
+ if (e1->ref || e2->ref)
+ return -2;
+ if (e1->symtree->n.sym == e2->symtree->n.sym)
+ return 0;
+ return -2;
+
+ default:
+ return -2;
+ }
+}
+
+
+/* Returns 1 if the two ranges are the same, 0 if they are not, and def
+ if the results are indeterminate. N is the dimension to compare. */
+
+int
+gfc_is_same_range (gfc_array_ref * ar1, gfc_array_ref * ar2, int n, int def)
+{
+ gfc_expr *e1;
+ gfc_expr *e2;
+ int i;
+
+ /* TODO: More sophisticated range comparison. */
+ assert (ar1 && ar2);
+
+ assert (ar1->dimen_type[n] == ar2->dimen_type[n]);
+
+ e1 = ar1->stride[n];
+ e2 = ar2->stride[n];
+ /* Check for mismatching strides. A NULL stride means a stride of 1. */
+ if (e1 && !e2)
+ {
+ i = gfc_expr_is_one (e1, -1);
+ if (i == -1)
+ return def;
+ else if (i == 0)
+ return 0;
+ }
+ else if (e2 && !e1)
+ {
+ i = gfc_expr_is_one (e2, -1);
+ if (i == -1)
+ return def;
+ else if (i == 0)
+ return 0;
+ }
+ else if (e1 && e2)
+ {
+ i = gfc_dep_compare_expr (e1, e2);
+ if (i == -2)
+ return def;
+ else if (i != 0)
+ return 0;
+ }
+ /* The strides match. */
+
+ /* Check the range start. */
+ e1 = ar1->start[n];
+ e2 = ar2->start[n];
+
+ if (!(e1 || e2))
+ return 1;
+
+ /* Use the bound of the array if no bound is specified. */
+ if (ar1->as && !e1)
+ e1 = ar1->as->lower[n];
+
+ if (ar2->as && !e2)
+ e2 = ar2->as->upper[n];
+
+ /* Check we have values for both. */
+ if (!(e1 && e2))
+ return def;
+
+ i = gfc_dep_compare_expr (e1, e2);
+
+ if (i == -2)
+ return def;
+ else if (i == 0)
+ return 1;
+ return 0;
+}
+
+
+/* Dependency checking for direct function return by reference.
+ Returns true if the arguments of the function depend on the
+ destination. This is considerably less conservative than other
+ dependencies because many function arguments will already be
+ copied into a temporary. */
+
+int
+gfc_check_fncall_dependency (gfc_expr * dest, gfc_expr * fncall)
+{
+ gfc_actual_arglist *actual;
+ gfc_ref *ref;
+ gfc_expr *expr;
+ int n;
+
+ assert (dest->expr_type == EXPR_VARIABLE
+ && fncall->expr_type == EXPR_FUNCTION);
+ assert (fncall->rank > 0);
+
+ for (actual = fncall->value.function.actual; actual; actual = actual->next)
+ {
+ expr = actual->expr;
+
+ /* Skip args which are not present. */
+ if (!expr)
+ continue;
+
+ /* Non-variable expressions will be allocated temporaries anyway. */
+ switch (expr->expr_type)
+ {
+ case EXPR_VARIABLE:
+ if (expr->rank > 1)
+ {
+ /* This is an array section. */
+ for (ref = expr->ref; ref; ref = ref->next)
+ {
+ if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT)
+ break;
+ }
+ assert (ref);
+ /* AR_FULL can't contain vector subscripts. */
+ if (ref->u.ar.type == AR_SECTION)
+ {
+ for (n = 0; n < ref->u.ar.dimen; n++)
+ {
+ if (ref->u.ar.dimen_type[n] == DIMEN_VECTOR)
+ break;
+ }
+ /* Vector subscript array sections will be copied to a
+ temporary. */
+ if (n != ref->u.ar.dimen)
+ continue;
+ }
+ }
+
+ if (gfc_check_dependency (dest, actual->expr, NULL, 0))
+ return 1;
+ break;
+
+ case EXPR_ARRAY:
+ if (gfc_check_dependency (dest, expr, NULL, 0))
+ return 1;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
+/* Return true if the statement body redefines the condition. Returns
+ true if expr2 depends on expr1. expr1 should be a single term
+ suitable for the lhs of an assignment. The symbols listed in VARS
+ must be considered to have all possible values. All other scalar
+ variables may be considered constant. Used for forall and where
+ statements. Also used with functions returning arrays without a
+ temporary. */
+
+int
+gfc_check_dependency (gfc_expr * expr1, gfc_expr * expr2, gfc_expr ** vars,
+ int nvars)
+{
+ gfc_ref *ref;
+ int n;
+ gfc_actual_arglist *actual;
+
+ assert (expr1->expr_type == EXPR_VARIABLE);
+
+ /* TODO: -fassume-no-pointer-aliasing */
+ if (expr1->symtree->n.sym->attr.pointer)
+ return 1;
+ for (ref = expr1->ref; ref; ref = ref->next)
+ {
+ if (ref->type == REF_COMPONENT && ref->u.c.component->pointer)
+ return 1;
+ }
+
+ switch (expr2->expr_type)
+ {
+ case EXPR_OP:
+ n = gfc_check_dependency (expr1, expr2->op1, vars, nvars);
+ if (n)
+ return n;
+ if (expr2->op2)
+ return gfc_check_dependency (expr1, expr2->op2, vars, nvars);
+ return 0;
+
+ case EXPR_VARIABLE:
+ if (expr2->symtree->n.sym->attr.pointer)
+ return 1;
+
+ for (ref = expr2->ref; ref; ref = ref->next)
+ {
+ if (ref->type == REF_COMPONENT && ref->u.c.component->pointer)
+ return 1;
+ }
+
+ if (expr1->symtree->n.sym != expr2->symtree->n.sym)
+ return 0;
+
+ for (ref = expr2->ref; ref; ref = ref->next)
+ {
+ /* Identical ranges return 0, overlapping ranges return 1. */
+ if (ref->type == REF_ARRAY)
+ return 1;
+ }
+ return 1;
+
+ case EXPR_FUNCTION:
+ /* Remember possible differences betweeen elemental and
+ transformational functions. All functions inside a FORALL
+ will be pure. */
+ for (actual = expr2->value.function.actual;
+ actual; actual = actual->next)
+ {
+ if (!actual->expr)
+ continue;
+ n = gfc_check_dependency (expr1, actual->expr, vars, nvars);
+ if (n)
+ return n;
+ }
+ return 0;
+
+ case EXPR_CONSTANT:
+ return 0;
+
+ case EXPR_ARRAY:
+ /* Probably ok in the majority of (constant) cases. */
+ return 1;
+
+ default:
+ return 1;
+ }
+}
+
+
+/* Calculates size of the array reference using lower bound, upper bound
+ and stride. */
+
+static void
+get_no_of_elements(mpz_t ele, gfc_expr * u1, gfc_expr * l1, gfc_expr * s1)
+{
+ /* nNoOfEle = (u1-l1)/s1 */
+
+ mpz_sub (ele, u1->value.integer, l1->value.integer);
+
+ if (s1 != NULL)
+ mpz_tdiv_q (ele, ele, s1->value.integer);
+}
+
+
+/* Returns if the ranges ((0..Y), (X1..X2)) overlap. */
+
+static gfc_dependency
+get_deps (mpz_t x1, mpz_t x2, mpz_t y)
+{
+ int start;
+ int end;
+
+ start = mpz_cmp_ui (x1, 0);
+ end = mpz_cmp (x2, y);
+
+ /* Both ranges the same. */
+ if (start == 0 && end == 0)
+ return GFC_DEP_EQUAL;
+
+ /* Distinct ranges. */
+ if ((start < 0 && mpz_cmp_ui (x2, 0) < 0)
+ || (mpz_cmp (x1, y) > 0 && end > 0))
+ return GFC_DEP_NODEP;
+
+ /* Overlapping, but with corresponding elements of the second range
+ greater than the first. */
+ if (start > 0 && end > 0)
+ return GFC_DEP_FORWARD;
+
+ /* Overlapping in some other way. */
+ return GFC_DEP_OVERLAP;
+}
+
+
+/* Transforms a sections l and r such that
+ (l_start:l_end:l_stride) -> (0:no_of_elements)
+ (r_start:r_end:r_stride) -> (X1:X2)
+ Where r_end is implicit as both sections must have the same number of
+ elelments.
+ Returns 0 on success, 1 of the transformation failed. */
+/* TODO: Should this be (0:no_of_elements-1) */
+
+static int
+transform_sections (mpz_t X1, mpz_t X2, mpz_t no_of_elements,
+ gfc_expr * l_start, gfc_expr * l_end, gfc_expr * l_stride,
+ gfc_expr * r_start, gfc_expr * r_stride)
+{
+ if (NULL == l_start || NULL == l_end || NULL == r_start)
+ return 1;
+
+ /* TODO : Currently we check the dependency only when start, end and stride
+ are constant. We could also check for equal (variable) values, and
+ common subexpressions, eg. x vs. x+1. */
+
+ if (l_end->expr_type != EXPR_CONSTANT
+ || l_start->expr_type != EXPR_CONSTANT
+ || r_start->expr_type != EXPR_CONSTANT
+ || ((NULL != l_stride) && (l_stride->expr_type != EXPR_CONSTANT))
+ || ((NULL != r_stride) && (r_stride->expr_type != EXPR_CONSTANT)))
+ {
+ return 1;
+ }
+
+
+ get_no_of_elements (no_of_elements, l_end, l_start, l_stride);
+
+ mpz_sub (X1, r_start->value.integer, l_start->value.integer);
+ if (l_stride != NULL)
+ mpz_cdiv_q (X1, X1, l_stride->value.integer);
+
+ if (r_stride == NULL)
+ mpz_set (X2, no_of_elements);
+ else
+ mpz_mul (X2, no_of_elements, r_stride->value.integer);
+
+ if (l_stride != NULL)
+ mpz_cdiv_q (X2, X2, r_stride->value.integer);
+ mpz_add (X2, X2, X1);
+
+ return 0;
+}
+
+
+/* Determines overlapping for two array sections. */
+
+static gfc_dependency
+gfc_check_section_vs_section (gfc_ref * lref, gfc_ref * rref, int n)
+{
+ gfc_expr *l_start;
+ gfc_expr *l_end;
+ gfc_expr *l_stride;
+
+ gfc_expr *r_start;
+ gfc_expr *r_stride;
+
+ gfc_array_ref l_ar;
+ gfc_array_ref r_ar;
+
+ mpz_t no_of_elements;
+ mpz_t X1, X2;
+ gfc_dependency dep;
+
+ l_ar = lref->u.ar;
+ r_ar = rref->u.ar;
+
+ l_start = l_ar.start[n];
+ l_end = l_ar.end[n];
+ l_stride = l_ar.stride[n];
+ r_start = r_ar.start[n];
+ r_stride = r_ar.stride[n];
+
+ /* if l_start is NULL take it from array specifier */
+ if (NULL == l_start && IS_ARRAY_EXPLICIT(l_ar.as))
+ l_start = l_ar.as->lower[n];
+
+ /* if l_end is NULL take it from array specifier */
+ if (NULL == l_end && IS_ARRAY_EXPLICIT(l_ar.as))
+ l_end = l_ar.as->upper[n];
+
+ /* if r_start is NULL take it from array specifier */
+ if (NULL == r_start && IS_ARRAY_EXPLICIT(r_ar.as))
+ r_start = r_ar.as->lower[n];
+
+ mpz_init (X1);
+ mpz_init (X2);
+ mpz_init (no_of_elements);
+
+ if (transform_sections (X1, X2, no_of_elements,
+ l_start, l_end, l_stride,
+ r_start, r_stride))
+ dep = GFC_DEP_OVERLAP;
+ else
+ dep = get_deps (X1, X2, no_of_elements);
+
+ mpz_clear (no_of_elements);
+ mpz_clear (X1);
+ mpz_clear (X2);
+ return dep;
+}
+
+
+/* Checks if the expr chk is inside the range left-right.
+ Returns GFC_DEP_NODEP if chk is outside the range,
+ GFC_DEP_OVERLAP otherwise.
+ Assumes left<=right. */
+
+static gfc_dependency
+gfc_is_inside_range (gfc_expr * chk, gfc_expr * left, gfc_expr * right)
+{
+ int l;
+ int r;
+ int s;
+
+ s = gfc_dep_compare_expr (left, right);
+ if (s == -2)
+ return GFC_DEP_OVERLAP;
+
+ l = gfc_dep_compare_expr (chk, left);
+ r = gfc_dep_compare_expr (chk, right);
+
+ /* Check for indeterminate relationships. */
+ if (l == -2 || r == -2 || s == -2)
+ return GFC_DEP_OVERLAP;
+
+ if (s == 1)
+ {
+ /* When left>right we want to check for right <= chk <= left. */
+ if (l <= 0 || r >= 0)
+ return GFC_DEP_OVERLAP;
+ }
+ else
+ {
+ /* Otherwise check for left <= chk <= right. */
+ if (l >= 0 || r <= 0)
+ return GFC_DEP_OVERLAP;
+ }
+
+ return GFC_DEP_NODEP;
+}
+
+
+/* Determines overlapping for a single element and a section. */
+
+static gfc_dependency
+gfc_check_element_vs_section( gfc_ref * lref, gfc_ref * rref, int n)
+{
+ gfc_array_ref l_ar;
+ gfc_array_ref r_ar;
+ gfc_expr *l_start;
+ gfc_expr *r_start;
+ gfc_expr *r_end;
+
+ l_ar = lref->u.ar;
+ r_ar = rref->u.ar;
+ l_start = l_ar.start[n] ;
+ r_start = r_ar.start[n] ;
+ r_end = r_ar.end[n] ;
+ if (NULL == r_start && IS_ARRAY_EXPLICIT (r_ar.as))
+ r_start = r_ar.as->lower[n];
+ if (NULL == r_end && IS_ARRAY_EXPLICIT (r_ar.as))
+ r_end = r_ar.as->upper[n];
+ if (NULL == r_start || NULL == r_end || l_start == NULL)
+ return GFC_DEP_OVERLAP;
+
+ return gfc_is_inside_range (l_start, r_end, r_start);
+}
+
+
+/* Determines overlapping for two single element array references. */
+
+static gfc_dependency
+gfc_check_element_vs_element (gfc_ref * lref, gfc_ref * rref, int n)
+{
+ gfc_array_ref l_ar;
+ gfc_array_ref r_ar;
+ gfc_expr *l_start;
+ gfc_expr *r_start;
+ gfc_dependency nIsDep;
+
+ if (lref->type == REF_ARRAY && rref->type == REF_ARRAY)
+ {
+ l_ar = lref->u.ar;
+ r_ar = rref->u.ar;
+ l_start = l_ar.start[n] ;
+ r_start = r_ar.start[n] ;
+ if (gfc_dep_compare_expr (r_start, l_start) == 0)
+ nIsDep = GFC_DEP_EQUAL;
+ else
+ nIsDep = GFC_DEP_NODEP;
+ }
+ else
+ nIsDep = GFC_DEP_NODEP;
+
+ return nIsDep;
+}
+
+
+/* Finds if two array references are overlapping or not.
+ Return value
+ 1 : array references are overlapping.
+ 0 : array references are not overlapping. */
+
+int
+gfc_dep_resolver (gfc_ref * lref, gfc_ref * rref)
+{
+ int n;
+ gfc_dependency fin_dep;
+ gfc_dependency this_dep;
+
+
+ fin_dep = GFC_DEP_ERROR;
+ /* Dependencies due to pointers should already have been identified.
+ We only need to check for overlapping array references. */
+
+ while (lref && rref)
+ {
+ /* We're resolving from the same base symbol, so both refs should be
+ the same type. We traverse the reference chain intil we find ranges
+ that are not equal. */
+ assert (lref->type == rref->type);
+ switch (lref->type)
+ {
+ case REF_COMPONENT:
+ /* The two ranges can't overlap if they are from different
+ components. */
+ if (lref->u.c.component != rref->u.c.component)
+ return 0;
+ break;
+
+ case REF_SUBSTRING:
+ /* Substring overlaps are handled by the string assignment code. */
+ return 0;
+
+ case REF_ARRAY:
+
+ for (n=0; n < lref->u.ar.dimen; n++)
+ {
+ /* Assume dependency when either of array reference is vector
+ subscript. */
+ if (lref->u.ar.dimen_type[n] == DIMEN_VECTOR
+ || rref->u.ar.dimen_type[n] == DIMEN_VECTOR)
+ return 1;
+ if (lref->u.ar.dimen_type[n] == DIMEN_RANGE
+ && rref->u.ar.dimen_type[n] == DIMEN_RANGE)
+ this_dep = gfc_check_section_vs_section (lref, rref, n);
+ else if (lref->u.ar.dimen_type[n] == DIMEN_ELEMENT
+ && rref->u.ar.dimen_type[n] == DIMEN_RANGE)
+ this_dep = gfc_check_element_vs_section (lref, rref, n);
+ else if (rref->u.ar.dimen_type[n] == DIMEN_ELEMENT
+ && lref->u.ar.dimen_type[n] == DIMEN_RANGE)
+ this_dep = gfc_check_element_vs_section (rref, lref, n);
+ else
+ {
+ assert (rref->u.ar.dimen_type[n] == DIMEN_ELEMENT
+ && lref->u.ar.dimen_type[n] == DIMEN_ELEMENT);
+ this_dep = gfc_check_element_vs_element (rref, lref, n);
+ }
+
+ /* If any dimension doesn't overlap, we have no dependency. */
+ if (this_dep == GFC_DEP_NODEP)
+ return 0;
+
+ /* Overlap codes are in order of priority. We only need to
+ know the worst one.*/
+ if (this_dep > fin_dep)
+ fin_dep = this_dep;
+ }
+ /* Exactly matching and forward overlapping ranges don't cause a
+ dependency. */
+ if (fin_dep < GFC_DEP_OVERLAP)
+ return 0;
+
+ /* Keep checking. We only have a dependency if
+ subsequent references also overlap. */
+ break;
+
+ default:
+ abort();
+ }
+ lref = lref->next;
+ rref = rref->next;
+ }
+
+ /* If we haven't seen any array refs then something went wrong. */
+ assert (fin_dep != GFC_DEP_ERROR);
+
+ if (fin_dep < GFC_DEP_OVERLAP)
+ return 0;
+ else
+ return 1;
+}
+
diff --git a/gcc/fortran/dependency.h b/gcc/fortran/dependency.h
new file mode 100644
index 00000000000..be406af441d
--- /dev/null
+++ b/gcc/fortran/dependency.h
@@ -0,0 +1,30 @@
+/* Header for dependency analysis
+ Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+
+int gfc_check_fncall_dependency (gfc_expr *, gfc_expr *);
+int gfc_check_dependency (gfc_expr *, gfc_expr *, gfc_expr **, int);
+int gfc_is_same_range (gfc_array_ref *, gfc_array_ref *, int, int);
+int gfc_dep_compare_expr (gfc_expr *, gfc_expr *);
+int gfc_expr_is_one (gfc_expr *, int);
+
+int gfc_dep_resolver(gfc_ref *, gfc_ref *);
diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c
new file mode 100644
index 00000000000..31fdf0ba121
--- /dev/null
+++ b/gcc/fortran/dump-parse-tree.c
@@ -0,0 +1,1459 @@
+/* Parse tree dumper
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Steven Bosscher
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+/* Actually this is just a collection of routines that used to be
+ scattered around the sources. Now that they are all in a single
+ file, almost all of them can be static, and the other files don't
+ have this mess in them.
+
+ As a nice side-effect, this file can act as documentation of the
+ gfc_code and gfc_expr structures and all their friends and
+ relatives.
+
+ TODO: Dump DATA. */
+
+#include "config.h"
+#include "gfortran.h"
+
+/* Keep track of indentation for symbol tree dumps. */
+static int show_level = 0;
+
+
+/* Forward declaration because this one needs all, and all need
+ this one. */
+static void gfc_show_expr (gfc_expr *);
+
+/* Do indentation for a specific level. */
+
+static inline void
+code_indent (int level, gfc_st_label * label)
+{
+ int i;
+
+ if (label != NULL)
+ gfc_status ("%-5d ", label->value);
+ else
+ gfc_status (" ");
+
+ for (i = 0; i < 2 * level; i++)
+ gfc_status_char (' ');
+}
+
+
+/* Simple indentation at the current level. This one
+ is used to show symbols. */
+static inline void
+show_indent (void)
+{
+ gfc_status ("\n");
+ code_indent (show_level, NULL);
+}
+
+
+/* Show type-specific information. */
+static void
+gfc_show_typespec (gfc_typespec * ts)
+{
+
+ gfc_status ("(%s ", gfc_basic_typename (ts->type));
+
+ switch (ts->type)
+ {
+ case BT_DERIVED:
+ gfc_status ("%s", ts->derived->name);
+ break;
+
+ case BT_CHARACTER:
+ gfc_show_expr (ts->cl->length);
+ break;
+
+ default:
+ gfc_status ("%d", ts->kind);
+ break;
+ }
+
+ gfc_status (")");
+}
+
+
+/* Show an actual argument list. */
+
+static void
+gfc_show_actual_arglist (gfc_actual_arglist * a)
+{
+
+ gfc_status ("(");
+
+ for (; a; a = a->next)
+ {
+ gfc_status_char ('(');
+ if (a->name[0] != '\0')
+ gfc_status ("%s = ", a->name);
+ if (a->expr != NULL)
+ gfc_show_expr (a->expr);
+ else
+ gfc_status ("(arg not-present)");
+
+ gfc_status_char (')');
+ if (a->next != NULL)
+ gfc_status (" ");
+ }
+
+ gfc_status (")");
+}
+
+
+/* Show an gfc_array_spec array specification structure. */
+
+static void
+gfc_show_array_spec (gfc_array_spec * as)
+{
+ const char *c;
+ int i;
+
+ if (as == NULL)
+ {
+ gfc_status ("()");
+ return;
+ }
+
+ gfc_status ("(%d", as->rank);
+
+ if (as->rank != 0)
+ {
+ switch (as->type)
+ {
+ case AS_EXPLICIT: c = "AS_EXPLICIT"; break;
+ case AS_DEFERRED: c = "AS_DEFERRED"; break;
+ case AS_ASSUMED_SIZE: c = "AS_ASSUMED_SIZE"; break;
+ case AS_ASSUMED_SHAPE: c = "AS_ASSUMED_SHAPE"; break;
+ default:
+ gfc_internal_error
+ ("gfc_show_array_spec(): Unhandled array shape type.");
+ }
+ gfc_status (" %s ", c);
+
+ for (i = 0; i < as->rank; i++)
+ {
+ gfc_show_expr (as->lower[i]);
+ gfc_status_char (' ');
+ gfc_show_expr (as->upper[i]);
+ gfc_status_char (' ');
+ }
+ }
+
+ gfc_status (")");
+}
+
+
+/* Show an gfc_array_ref array reference structure. */
+
+static void
+gfc_show_array_ref (gfc_array_ref * ar)
+{
+ int i;
+
+ gfc_status_char ('(');
+
+ switch (ar->type)
+ {
+ case AR_FULL:
+ gfc_status ("FULL");
+ break;
+
+ case AR_SECTION:
+ for (i = 0; i < ar->dimen; i++)
+ {
+ if (ar->start[i] != NULL)
+ gfc_show_expr (ar->start[i]);
+
+ gfc_status_char (':');
+
+ if (ar->end[i] != NULL)
+ gfc_show_expr (ar->end[i]);
+
+ if (ar->stride[i] != NULL)
+ {
+ gfc_status_char (':');
+ gfc_show_expr (ar->stride[i]);
+ }
+
+ if (i != ar->dimen - 1)
+ gfc_status (" , ");
+ }
+ break;
+
+ case AR_ELEMENT:
+ for (i = 0; i < ar->dimen; i++)
+ {
+ gfc_show_expr (ar->start[i]);
+ if (i != ar->dimen - 1)
+ gfc_status (" , ");
+ }
+ break;
+
+ case AR_UNKNOWN:
+ gfc_status ("UNKNOWN");
+ break;
+
+ default:
+ gfc_internal_error ("gfc_show_array_ref(): Unknown array reference");
+ }
+
+ gfc_status_char (')');
+}
+
+
+/* Show a list of gfc_ref structures. */
+
+static void
+gfc_show_ref (gfc_ref * p)
+{
+
+ for (; p; p = p->next)
+ switch (p->type)
+ {
+ case REF_ARRAY:
+ gfc_show_array_ref (&p->u.ar);
+ break;
+
+ case REF_COMPONENT:
+ gfc_status (" %% %s", p->u.c.component->name);
+ break;
+
+ case REF_SUBSTRING:
+ gfc_status_char ('(');
+ gfc_show_expr (p->u.ss.start);
+ gfc_status_char (':');
+ gfc_show_expr (p->u.ss.end);
+ gfc_status_char (')');
+ break;
+
+ default:
+ gfc_internal_error ("gfc_show_ref(): Bad component code");
+ }
+}
+
+
+/* Display a constructor. Works recursively for array constructors. */
+
+static void
+gfc_show_constructor (gfc_constructor * c)
+{
+
+ for (; c; c = c->next)
+ {
+ if (c->iterator == NULL)
+ gfc_show_expr (c->expr);
+ else
+ {
+ gfc_status_char ('(');
+ gfc_show_expr (c->expr);
+
+ gfc_status_char (' ');
+ gfc_show_expr (c->iterator->var);
+ gfc_status_char ('=');
+ gfc_show_expr (c->iterator->start);
+ gfc_status_char (',');
+ gfc_show_expr (c->iterator->end);
+ gfc_status_char (',');
+ gfc_show_expr (c->iterator->step);
+
+ gfc_status_char (')');
+ }
+
+ if (c->next != NULL)
+ gfc_status (" , ");
+ }
+}
+
+
+/* Show an expression. */
+
+static void
+gfc_show_expr (gfc_expr * p)
+{
+ const char *c;
+ int i;
+
+ if (p == NULL)
+ {
+ gfc_status ("()");
+ return;
+ }
+
+ switch (p->expr_type)
+ {
+ case EXPR_SUBSTRING:
+ c = p->value.character.string;
+
+ for (i = 0; i < p->value.character.length; i++, c++)
+ {
+ if (*c == '\'')
+ gfc_status ("''");
+ else
+ gfc_status ("%c", *c);
+ }
+
+ gfc_show_ref (p->ref);
+ break;
+
+ case EXPR_STRUCTURE:
+ gfc_status ("%s(", p->ts.derived->name);
+ gfc_show_constructor (p->value.constructor);
+ gfc_status_char (')');
+ break;
+
+ case EXPR_ARRAY:
+ gfc_status ("(/ ");
+ gfc_show_constructor (p->value.constructor);
+ gfc_status (" /)");
+
+ gfc_show_ref (p->ref);
+ break;
+
+ case EXPR_NULL:
+ gfc_status ("NULL()");
+ break;
+
+ case EXPR_CONSTANT:
+ switch (p->ts.type)
+ {
+ case BT_INTEGER:
+ mpz_out_str (stdout, 10, p->value.integer);
+
+ if (p->ts.kind != gfc_default_integer_kind ())
+ gfc_status ("_%d", p->ts.kind);
+ break;
+
+ case BT_LOGICAL:
+ if (p->value.logical)
+ gfc_status (".true.");
+ else
+ gfc_status (".false.");
+ break;
+
+ case BT_REAL:
+ mpf_out_str (stdout, 10, 0, p->value.real);
+ if (p->ts.kind != gfc_default_real_kind ())
+ gfc_status ("_%d", p->ts.kind);
+ break;
+
+ case BT_CHARACTER:
+ c = p->value.character.string;
+
+ gfc_status_char ('\'');
+
+ for (i = 0; i < p->value.character.length; i++, c++)
+ {
+ if (*c == '\'')
+ gfc_status ("''");
+ else
+ gfc_status_char (*c);
+ }
+
+ gfc_status_char ('\'');
+
+ break;
+
+ case BT_COMPLEX:
+ gfc_status ("(complex ");
+
+ mpf_out_str (stdout, 10, 0, p->value.complex.r);
+ if (p->ts.kind != gfc_default_complex_kind ())
+ gfc_status ("_%d", p->ts.kind);
+
+ gfc_status (" ");
+
+ mpf_out_str (stdout, 10, 0, p->value.complex.i);
+ if (p->ts.kind != gfc_default_complex_kind ())
+ gfc_status ("_%d", p->ts.kind);
+
+ gfc_status (")");
+ break;
+
+ default:
+ gfc_status ("???");
+ break;
+ }
+
+ break;
+
+ case EXPR_VARIABLE:
+ gfc_status ("%s", p->symtree->n.sym->name);
+ gfc_show_ref (p->ref);
+ break;
+
+ case EXPR_OP:
+ gfc_status ("(");
+ switch (p->operator)
+ {
+ case INTRINSIC_UPLUS:
+ gfc_status ("U+ ");
+ break;
+ case INTRINSIC_UMINUS:
+ gfc_status ("U- ");
+ break;
+ case INTRINSIC_PLUS:
+ gfc_status ("+ ");
+ break;
+ case INTRINSIC_MINUS:
+ gfc_status ("- ");
+ break;
+ case INTRINSIC_TIMES:
+ gfc_status ("* ");
+ break;
+ case INTRINSIC_DIVIDE:
+ gfc_status ("/ ");
+ break;
+ case INTRINSIC_POWER:
+ gfc_status ("** ");
+ break;
+ case INTRINSIC_CONCAT:
+ gfc_status ("// ");
+ break;
+ case INTRINSIC_AND:
+ gfc_status ("AND ");
+ break;
+ case INTRINSIC_OR:
+ gfc_status ("OR ");
+ break;
+ case INTRINSIC_EQV:
+ gfc_status ("EQV ");
+ break;
+ case INTRINSIC_NEQV:
+ gfc_status ("NEQV ");
+ break;
+ case INTRINSIC_EQ:
+ gfc_status ("= ");
+ break;
+ case INTRINSIC_NE:
+ gfc_status ("<> ");
+ break;
+ case INTRINSIC_GT:
+ gfc_status ("> ");
+ break;
+ case INTRINSIC_GE:
+ gfc_status (">= ");
+ break;
+ case INTRINSIC_LT:
+ gfc_status ("< ");
+ break;
+ case INTRINSIC_LE:
+ gfc_status ("<= ");
+ break;
+ case INTRINSIC_NOT:
+ gfc_status ("NOT ");
+ break;
+
+ default:
+ gfc_internal_error
+ ("gfc_show_expr(): Bad intrinsic in expression!");
+ }
+
+ gfc_show_expr (p->op1);
+
+ if (p->op2)
+ {
+ gfc_status (" ");
+ gfc_show_expr (p->op2);
+ }
+
+ gfc_status (")");
+ break;
+
+ case EXPR_FUNCTION:
+ if (p->value.function.name == NULL)
+ {
+ gfc_status ("%s[", p->symtree->n.sym->name);
+ gfc_show_actual_arglist (p->value.function.actual);
+ gfc_status_char (']');
+ }
+ else
+ {
+ gfc_status ("%s[[", p->value.function.name);
+ gfc_show_actual_arglist (p->value.function.actual);
+ gfc_status_char (']');
+ gfc_status_char (']');
+ }
+
+ break;
+
+ default:
+ gfc_internal_error ("gfc_show_expr(): Don't know how to show expr");
+ }
+}
+
+
+/* Show symbol attributes. The flavor and intent are followed by
+ whatever single bit attributes are present. */
+
+static void
+gfc_show_attr (symbol_attribute * attr)
+{
+
+ gfc_status ("(%s %s %s %s", gfc_code2string (flavors, attr->flavor),
+ gfc_intent_string (attr->intent),
+ gfc_code2string (access_types, attr->access),
+ gfc_code2string (procedures, attr->proc));
+
+ if (attr->allocatable)
+ gfc_status (" ALLOCATABLE");
+ if (attr->dimension)
+ gfc_status (" DIMENSION");
+ if (attr->external)
+ gfc_status (" EXTERNAL");
+ if (attr->intrinsic)
+ gfc_status (" INTRINSIC");
+ if (attr->optional)
+ gfc_status (" OPTIONAL");
+ if (attr->pointer)
+ gfc_status (" POINTER");
+ if (attr->save)
+ gfc_status (" SAVE");
+ if (attr->target)
+ gfc_status (" TARGET");
+ if (attr->dummy)
+ gfc_status (" DUMMY");
+ if (attr->common)
+ gfc_status (" COMMON");
+ if (attr->result)
+ gfc_status (" RESULT");
+ if (attr->entry)
+ gfc_status (" ENTRY");
+
+ if (attr->data)
+ gfc_status (" DATA");
+ if (attr->use_assoc)
+ gfc_status (" USE-ASSOC");
+ if (attr->in_namelist)
+ gfc_status (" IN-NAMELIST");
+ if (attr->in_common)
+ gfc_status (" IN-COMMON");
+ if (attr->saved_common)
+ gfc_status (" SAVED-COMMON");
+
+ if (attr->function)
+ gfc_status (" FUNCTION");
+ if (attr->subroutine)
+ gfc_status (" SUBROUTINE");
+ if (attr->implicit_type)
+ gfc_status (" IMPLICIT-TYPE");
+
+ if (attr->sequence)
+ gfc_status (" SEQUENCE");
+ if (attr->elemental)
+ gfc_status (" ELEMENTAL");
+ if (attr->pure)
+ gfc_status (" PURE");
+ if (attr->recursive)
+ gfc_status (" RECURSIVE");
+
+ gfc_status (")");
+}
+
+
+/* Show components of a derived type. */
+
+static void
+gfc_show_components (gfc_symbol * sym)
+{
+ gfc_component *c;
+
+ for (c = sym->components; c; c = c->next)
+ {
+ gfc_status ("(%s ", c->name);
+ gfc_show_typespec (&c->ts);
+ if (c->pointer)
+ gfc_status (" POINTER");
+ if (c->dimension)
+ gfc_status (" DIMENSION");
+ gfc_status_char (' ');
+ gfc_show_array_spec (c->as);
+ gfc_status (")");
+ if (c->next != NULL)
+ gfc_status_char (' ');
+ }
+}
+
+
+/* Show a symbol. If a symbol is an ENTRY, SUBROUTINE or FUNCTION, we
+ show the interface. Information needed to reconstruct the list of
+ specific interfaces associated with a generic symbol is done within
+ that symbol. */
+
+static void
+gfc_show_symbol (gfc_symbol * sym)
+{
+ gfc_formal_arglist *formal;
+ gfc_interface *intr;
+ gfc_symbol *s;
+
+ if (sym == NULL)
+ return;
+
+ show_indent ();
+
+ gfc_status ("symbol %s ", sym->name);
+ gfc_show_typespec (&sym->ts);
+ gfc_show_attr (&sym->attr);
+
+ if (sym->value)
+ {
+ show_indent ();
+ gfc_status ("value: ");
+ gfc_show_expr (sym->value);
+ }
+
+ if (sym->as)
+ {
+ show_indent ();
+ gfc_status ("Array spec:");
+ gfc_show_array_spec (sym->as);
+ }
+
+ if (sym->generic)
+ {
+ show_indent ();
+ gfc_status ("Generic interfaces:");
+ for (intr = sym->generic; intr; intr = intr->next)
+ gfc_status (" %s", intr->sym->name);
+ }
+
+ if (sym->common_head)
+ {
+ show_indent ();
+ gfc_status ("Common members:");
+ for (s = sym->common_head; s; s = s->common_next)
+ gfc_status (" %s", s->name);
+ }
+
+ if (sym->result)
+ {
+ show_indent ();
+ gfc_status ("result: %s", sym->result->name);
+ }
+
+ if (sym->components)
+ {
+ show_indent ();
+ gfc_status ("components: ");
+ gfc_show_components (sym);
+ }
+
+ if (sym->formal)
+ {
+ show_indent ();
+ gfc_status ("Formal arglist:");
+
+ for (formal = sym->formal; formal; formal = formal->next)
+ gfc_status (" %s", formal->sym->name);
+ }
+
+ if (sym->formal_ns)
+ {
+ show_indent ();
+ gfc_status ("Formal namespace");
+ gfc_show_namespace (sym->formal_ns);
+ }
+
+ gfc_status_char ('\n');
+}
+
+
+/* Show a user-defined operator. Just prints an operator
+ and the name of the associated subroutine, really. */
+static void
+show_uop (gfc_user_op * uop)
+{
+ gfc_interface *intr;
+
+ show_indent ();
+ gfc_status ("%s:", uop->name);
+
+ for (intr = uop->operator; intr; intr = intr->next)
+ gfc_status (" %s", intr->sym->name);
+}
+
+
+/* Workhorse function for traversing the user operator symtree. */
+
+static void
+traverse_uop (gfc_symtree * st, void (*func) (gfc_user_op *))
+{
+
+ if (st == NULL)
+ return;
+
+ (*func) (st->n.uop);
+
+ traverse_uop (st->left, func);
+ traverse_uop (st->right, func);
+}
+
+
+/* Traverse the tree of user operator nodes. */
+
+void
+gfc_traverse_user_op (gfc_namespace * ns, void (*func) (gfc_user_op *))
+{
+
+ traverse_uop (ns->uop_root, func);
+}
+
+
+/* Worker function to display the symbol tree. */
+
+static void
+show_symtree (gfc_symtree * st)
+{
+
+ show_indent ();
+ gfc_status ("symtree: %s Ambig %d", st->name, st->ambiguous);
+
+ if (st->n.sym->ns != gfc_current_ns)
+ gfc_status (" from namespace %s", st->n.sym->ns->proc_name->name);
+ else
+ gfc_show_symbol (st->n.sym);
+}
+
+
+/******************* Show gfc_code structures **************/
+
+
+
+static void gfc_show_code_node (int level, gfc_code * c);
+
+/* Show a list of code structures. Mutually recursive with
+ gfc_show_code_node(). */
+
+static void
+gfc_show_code (int level, gfc_code * c)
+{
+
+ for (; c; c = c->next)
+ gfc_show_code_node (level, c);
+}
+
+
+/* Show a single code node and everything underneath it if necessary. */
+
+static void
+gfc_show_code_node (int level, gfc_code * c)
+{
+ gfc_forall_iterator *fa;
+ gfc_open *open;
+ gfc_case *cp;
+ gfc_alloc *a;
+ gfc_code *d;
+ gfc_close *close;
+ gfc_filepos *fp;
+ gfc_inquire *i;
+ gfc_dt *dt;
+
+ code_indent (level, c->here);
+
+ switch (c->op)
+ {
+ case EXEC_NOP:
+ gfc_status ("NOP");
+ break;
+
+ case EXEC_CONTINUE:
+ gfc_status ("CONTINUE");
+ break;
+
+ case EXEC_ASSIGN:
+ gfc_status ("ASSIGN ");
+ gfc_show_expr (c->expr);
+ gfc_status_char (' ');
+ gfc_show_expr (c->expr2);
+ break;
+ case EXEC_LABEL_ASSIGN:
+ gfc_status ("LABEL ASSIGN ");
+ gfc_show_expr (c->expr);
+ gfc_status (" %d", c->label->value);
+ break;
+
+ case EXEC_POINTER_ASSIGN:
+ gfc_status ("POINTER ASSIGN ");
+ gfc_show_expr (c->expr);
+ gfc_status_char (' ');
+ gfc_show_expr (c->expr2);
+ break;
+
+ case EXEC_GOTO:
+ gfc_status ("GOTO ");
+ if (c->label)
+ gfc_status ("%d", c->label->value);
+ else
+ {
+ gfc_show_expr (c->expr);
+ d = c->block;
+ if (d != NULL)
+ {
+ gfc_status (", (");
+ for (; d; d = d ->block)
+ {
+ code_indent (level, d->label);
+ if (d->block != NULL)
+ gfc_status_char (',');
+ else
+ gfc_status_char (')');
+ }
+ }
+ }
+ break;
+
+ case EXEC_CALL:
+ gfc_status ("CALL %s ", c->resolved_sym->name);
+ gfc_show_actual_arglist (c->ext.actual);
+ break;
+
+ case EXEC_RETURN:
+ gfc_status ("RETURN ");
+ if (c->expr)
+ gfc_show_expr (c->expr);
+ break;
+
+ case EXEC_PAUSE:
+ gfc_status ("PAUSE ");
+
+ if (c->expr != NULL)
+ gfc_show_expr (c->expr);
+ else
+ gfc_status ("%d", c->ext.stop_code);
+
+ break;
+
+ case EXEC_STOP:
+ gfc_status ("STOP ");
+
+ if (c->expr != NULL)
+ gfc_show_expr (c->expr);
+ else
+ gfc_status ("%d", c->ext.stop_code);
+
+ break;
+
+ case EXEC_ARITHMETIC_IF:
+ gfc_status ("IF ");
+ gfc_show_expr (c->expr);
+ gfc_status (" %d, %d, %d",
+ c->label->value, c->label2->value, c->label3->value);
+ break;
+
+ case EXEC_IF:
+ d = c->block;
+ gfc_status ("IF ");
+ gfc_show_expr (d->expr);
+ gfc_status_char ('\n');
+ gfc_show_code (level + 1, d->next);
+
+ d = d->block;
+ for (; d; d = d->block)
+ {
+ code_indent (level, 0);
+
+ if (d->expr == NULL)
+ gfc_status ("ELSE\n");
+ else
+ {
+ gfc_status ("ELSE IF ");
+ gfc_show_expr (d->expr);
+ gfc_status_char ('\n');
+ }
+
+ gfc_show_code (level + 1, d->next);
+ }
+
+ code_indent (level, c->label);
+
+ gfc_status ("ENDIF");
+ break;
+
+ case EXEC_SELECT:
+ d = c->block;
+ gfc_status ("SELECT CASE ");
+ gfc_show_expr (c->expr);
+ gfc_status_char ('\n');
+
+ for (; d; d = d->block)
+ {
+ code_indent (level, 0);
+
+ gfc_status ("CASE ");
+ for (cp = d->ext.case_list; cp; cp = cp->next)
+ {
+ gfc_status_char ('(');
+ gfc_show_expr (cp->low);
+ gfc_status_char (' ');
+ gfc_show_expr (cp->high);
+ gfc_status_char (')');
+ gfc_status_char (' ');
+ }
+ gfc_status_char ('\n');
+
+ gfc_show_code (level + 1, d->next);
+ }
+
+ code_indent (level, c->label);
+ gfc_status ("END SELECT");
+ break;
+
+ case EXEC_WHERE:
+ gfc_status ("WHERE ");
+
+ d = c->block;
+ gfc_show_expr (d->expr);
+ gfc_status_char ('\n');
+
+ gfc_show_code (level + 1, d->next);
+
+ for (d = d->block; d; d = d->block)
+ {
+ code_indent (level, 0);
+ gfc_status ("ELSE WHERE ");
+ gfc_show_expr (d->expr);
+ gfc_status_char ('\n');
+ gfc_show_code (level + 1, d->next);
+ }
+
+ code_indent (level, 0);
+ gfc_status ("END WHERE");
+ break;
+
+
+ case EXEC_FORALL:
+ gfc_status ("FORALL ");
+ for (fa = c->ext.forall_iterator; fa; fa = fa->next)
+ {
+ gfc_show_expr (fa->var);
+ gfc_status_char (' ');
+ gfc_show_expr (fa->start);
+ gfc_status_char (':');
+ gfc_show_expr (fa->end);
+ gfc_status_char (':');
+ gfc_show_expr (fa->stride);
+
+ if (fa->next != NULL)
+ gfc_status_char (',');
+ }
+
+ if (c->expr != NULL)
+ {
+ gfc_status_char (',');
+ gfc_show_expr (c->expr);
+ }
+ gfc_status_char ('\n');
+
+ gfc_show_code (level + 1, c->block->next);
+
+ code_indent (level, 0);
+ gfc_status ("END FORALL");
+ break;
+
+ case EXEC_DO:
+ gfc_status ("DO ");
+
+ gfc_show_expr (c->ext.iterator->var);
+ gfc_status_char ('=');
+ gfc_show_expr (c->ext.iterator->start);
+ gfc_status_char (' ');
+ gfc_show_expr (c->ext.iterator->end);
+ gfc_status_char (' ');
+ gfc_show_expr (c->ext.iterator->step);
+ gfc_status_char ('\n');
+
+ gfc_show_code (level + 1, c->block->next);
+
+ code_indent (level, 0);
+ gfc_status ("END DO");
+ break;
+
+ case EXEC_DO_WHILE:
+ gfc_status ("DO WHILE ");
+ gfc_show_expr (c->expr);
+ gfc_status_char ('\n');
+
+ gfc_show_code (level + 1, c->block->next);
+
+ code_indent (level, c->label);
+ gfc_status ("END DO");
+ break;
+
+ case EXEC_CYCLE:
+ gfc_status ("CYCLE");
+ if (c->symtree)
+ gfc_status (" %s", c->symtree->n.sym->name);
+ break;
+
+ case EXEC_EXIT:
+ gfc_status ("EXIT");
+ if (c->symtree)
+ gfc_status (" %s", c->symtree->n.sym->name);
+ break;
+
+ case EXEC_ALLOCATE:
+ gfc_status ("ALLOCATE ");
+ if (c->expr)
+ {
+ gfc_status (" STAT=");
+ gfc_show_expr (c->expr);
+ }
+
+ for (a = c->ext.alloc_list; a; a = a->next)
+ {
+ gfc_status_char (' ');
+ gfc_show_expr (a->expr);
+ }
+
+ break;
+
+ case EXEC_DEALLOCATE:
+ gfc_status ("DEALLOCATE ");
+ if (c->expr)
+ {
+ gfc_status (" STAT=");
+ gfc_show_expr (c->expr);
+ }
+
+ for (a = c->ext.alloc_list; a; a = a->next)
+ {
+ gfc_status_char (' ');
+ gfc_show_expr (a->expr);
+ }
+
+ break;
+
+ case EXEC_OPEN:
+ gfc_status ("OPEN");
+ open = c->ext.open;
+
+ if (open->unit)
+ {
+ gfc_status (" UNIT=");
+ gfc_show_expr (open->unit);
+ }
+ if (open->iostat)
+ {
+ gfc_status (" IOSTAT=");
+ gfc_show_expr (open->iostat);
+ }
+ if (open->file)
+ {
+ gfc_status (" FILE=");
+ gfc_show_expr (open->file);
+ }
+ if (open->status)
+ {
+ gfc_status (" STATUS=");
+ gfc_show_expr (open->status);
+ }
+ if (open->access)
+ {
+ gfc_status (" ACCESS=");
+ gfc_show_expr (open->access);
+ }
+ if (open->form)
+ {
+ gfc_status (" FORM=");
+ gfc_show_expr (open->form);
+ }
+ if (open->recl)
+ {
+ gfc_status (" RECL=");
+ gfc_show_expr (open->recl);
+ }
+ if (open->blank)
+ {
+ gfc_status (" BLANK=");
+ gfc_show_expr (open->blank);
+ }
+ if (open->position)
+ {
+ gfc_status (" POSITION=");
+ gfc_show_expr (open->position);
+ }
+ if (open->action)
+ {
+ gfc_status (" ACTION=");
+ gfc_show_expr (open->action);
+ }
+ if (open->delim)
+ {
+ gfc_status (" DELIM=");
+ gfc_show_expr (open->delim);
+ }
+ if (open->pad)
+ {
+ gfc_status (" PAD=");
+ gfc_show_expr (open->pad);
+ }
+ if (open->err != NULL)
+ gfc_status (" ERR=%d", open->err->value);
+
+ break;
+
+ case EXEC_CLOSE:
+ gfc_status ("CLOSE");
+ close = c->ext.close;
+
+ if (close->unit)
+ {
+ gfc_status (" UNIT=");
+ gfc_show_expr (close->unit);
+ }
+ if (close->iostat)
+ {
+ gfc_status (" IOSTAT=");
+ gfc_show_expr (close->iostat);
+ }
+ if (close->status)
+ {
+ gfc_status (" STATUS=");
+ gfc_show_expr (close->status);
+ }
+ if (close->err != NULL)
+ gfc_status (" ERR=%d", close->err->value);
+ break;
+
+ case EXEC_BACKSPACE:
+ gfc_status ("BACKSPACE");
+ goto show_filepos;
+
+ case EXEC_ENDFILE:
+ gfc_status ("ENDFILE");
+ goto show_filepos;
+
+ case EXEC_REWIND:
+ gfc_status ("REWIND");
+
+ show_filepos:
+ fp = c->ext.filepos;
+
+ if (fp->unit)
+ {
+ gfc_status (" UNIT=");
+ gfc_show_expr (fp->unit);
+ }
+ if (fp->iostat)
+ {
+ gfc_status (" IOSTAT=");
+ gfc_show_expr (fp->iostat);
+ }
+ if (fp->err != NULL)
+ gfc_status (" ERR=%d", fp->err->value);
+ break;
+
+ case EXEC_INQUIRE:
+ gfc_status ("INQUIRE");
+ i = c->ext.inquire;
+
+ if (i->unit)
+ {
+ gfc_status (" UNIT=");
+ gfc_show_expr (i->unit);
+ }
+ if (i->file)
+ {
+ gfc_status (" FILE=");
+ gfc_show_expr (i->file);
+ }
+
+ if (i->iostat)
+ {
+ gfc_status (" IOSTAT=");
+ gfc_show_expr (i->iostat);
+ }
+ if (i->exist)
+ {
+ gfc_status (" EXIST=");
+ gfc_show_expr (i->exist);
+ }
+ if (i->opened)
+ {
+ gfc_status (" OPENED=");
+ gfc_show_expr (i->opened);
+ }
+ if (i->number)
+ {
+ gfc_status (" NUMBER=");
+ gfc_show_expr (i->number);
+ }
+ if (i->named)
+ {
+ gfc_status (" NAMED=");
+ gfc_show_expr (i->named);
+ }
+ if (i->name)
+ {
+ gfc_status (" NAME=");
+ gfc_show_expr (i->name);
+ }
+ if (i->access)
+ {
+ gfc_status (" ACCESS=");
+ gfc_show_expr (i->access);
+ }
+ if (i->sequential)
+ {
+ gfc_status (" SEQUENTIAL=");
+ gfc_show_expr (i->sequential);
+ }
+
+ if (i->direct)
+ {
+ gfc_status (" DIRECT=");
+ gfc_show_expr (i->direct);
+ }
+ if (i->form)
+ {
+ gfc_status (" FORM=");
+ gfc_show_expr (i->form);
+ }
+ if (i->formatted)
+ {
+ gfc_status (" FORMATTED");
+ gfc_show_expr (i->formatted);
+ }
+ if (i->unformatted)
+ {
+ gfc_status (" UNFORMATTED=");
+ gfc_show_expr (i->unformatted);
+ }
+ if (i->recl)
+ {
+ gfc_status (" RECL=");
+ gfc_show_expr (i->recl);
+ }
+ if (i->nextrec)
+ {
+ gfc_status (" NEXTREC=");
+ gfc_show_expr (i->nextrec);
+ }
+ if (i->blank)
+ {
+ gfc_status (" BLANK=");
+ gfc_show_expr (i->blank);
+ }
+ if (i->position)
+ {
+ gfc_status (" POSITION=");
+ gfc_show_expr (i->position);
+ }
+ if (i->action)
+ {
+ gfc_status (" ACTION=");
+ gfc_show_expr (i->action);
+ }
+ if (i->read)
+ {
+ gfc_status (" READ=");
+ gfc_show_expr (i->read);
+ }
+ if (i->write)
+ {
+ gfc_status (" WRITE=");
+ gfc_show_expr (i->write);
+ }
+ if (i->readwrite)
+ {
+ gfc_status (" READWRITE=");
+ gfc_show_expr (i->readwrite);
+ }
+ if (i->delim)
+ {
+ gfc_status (" DELIM=");
+ gfc_show_expr (i->delim);
+ }
+ if (i->pad)
+ {
+ gfc_status (" PAD=");
+ gfc_show_expr (i->pad);
+ }
+
+ if (i->err != NULL)
+ gfc_status (" ERR=%d", i->err->value);
+ break;
+
+ case EXEC_IOLENGTH:
+ gfc_status ("IOLENGTH ");
+ gfc_show_expr (c->expr);
+ break;
+
+ case EXEC_READ:
+ gfc_status ("READ");
+ goto show_dt;
+
+ case EXEC_WRITE:
+ gfc_status ("WRITE");
+
+ show_dt:
+ dt = c->ext.dt;
+ if (dt->io_unit)
+ {
+ gfc_status (" UNIT=");
+ gfc_show_expr (dt->io_unit);
+ }
+
+ if (dt->format_expr)
+ {
+ gfc_status (" FMT=");
+ gfc_show_expr (dt->format_expr);
+ }
+
+ if (dt->format_label != NULL)
+ gfc_status (" FMT=%d", dt->format_label->value);
+ if (dt->namelist)
+ gfc_status (" NML=%s", dt->namelist->name);
+ if (dt->iostat)
+ {
+ gfc_status (" IOSTAT=");
+ gfc_show_expr (dt->iostat);
+ }
+ if (dt->size)
+ {
+ gfc_status (" SIZE=");
+ gfc_show_expr (dt->size);
+ }
+ if (dt->rec)
+ {
+ gfc_status (" REC=");
+ gfc_show_expr (dt->rec);
+ }
+ if (dt->advance)
+ {
+ gfc_status (" ADVANCE=");
+ gfc_show_expr (dt->advance);
+ }
+
+ break;
+
+ case EXEC_TRANSFER:
+ gfc_status ("TRANSFER ");
+ gfc_show_expr (c->expr);
+ break;
+
+ case EXEC_DT_END:
+ gfc_status ("DT_END");
+ dt = c->ext.dt;
+
+ if (dt->err != NULL)
+ gfc_status (" ERR=%d", dt->err->value);
+ if (dt->end != NULL)
+ gfc_status (" END=%d", dt->end->value);
+ if (dt->eor != NULL)
+ gfc_status (" EOR=%d", dt->eor->value);
+ break;
+
+ default:
+ gfc_internal_error ("gfc_show_code_node(): Bad statement code");
+ }
+
+ gfc_status_char ('\n');
+}
+
+
+/* Show a freakin' whole namespace. */
+
+void
+gfc_show_namespace (gfc_namespace * ns)
+{
+ gfc_interface *intr;
+ gfc_namespace *save;
+ gfc_intrinsic_op op;
+ int i;
+
+ save = gfc_current_ns;
+ show_level++;
+
+ show_indent ();
+ gfc_status ("Namespace:");
+
+ if (ns != NULL)
+ {
+ i = 0;
+ do
+ {
+ int l = i;
+ while (i < GFC_LETTERS - 1
+ && gfc_compare_types(&ns->default_type[i+1],
+ &ns->default_type[l]))
+ i++;
+
+ if (i > l)
+ gfc_status(" %c-%c: ", l+'A', i+'A');
+ else
+ gfc_status(" %c: ", l+'A');
+
+ gfc_show_typespec(&ns->default_type[l]);
+ i++;
+ } while (i < GFC_LETTERS);
+
+ if (ns->proc_name != NULL)
+ {
+ show_indent ();
+ gfc_status ("procedure name = %s", ns->proc_name->name);
+ }
+
+ gfc_current_ns = ns;
+ gfc_traverse_symtree (ns, show_symtree);
+
+ for (op = GFC_INTRINSIC_BEGIN; op != GFC_INTRINSIC_END; op++)
+ {
+ /* User operator interfaces */
+ intr = ns->operator[op];
+ if (intr == NULL)
+ continue;
+
+ show_indent ();
+ gfc_status ("Operator interfaces for %s:", gfc_op2string (op));
+
+ for (; intr; intr = intr->next)
+ gfc_status (" %s", intr->sym->name);
+ }
+
+ if (ns->uop_root != NULL)
+ {
+ show_indent ();
+ gfc_status ("User operators:\n");
+ gfc_traverse_user_op (ns, show_uop);
+ }
+ }
+
+ gfc_status_char ('\n');
+ gfc_status_char ('\n');
+
+ gfc_show_code (0, ns->code);
+
+ for (ns = ns->contained; ns; ns = ns->sibling)
+ {
+ show_indent ();
+ gfc_status ("CONTAINS\n");
+ gfc_show_namespace (ns);
+ }
+
+ show_level--;
+ gfc_status_char ('\n');
+ gfc_current_ns = save;
+}
diff --git a/gcc/fortran/error.c b/gcc/fortran/error.c
new file mode 100644
index 00000000000..260733c8af4
--- /dev/null
+++ b/gcc/fortran/error.c
@@ -0,0 +1,751 @@
+/* Handle errors.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation,
+ Inc.
+ Contributed by Andy Vaught & Niels Kristian Bech Jensen
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Handle the inevitable errors. A major catch here is that things
+ flagged as errors in one match subroutine can conceivably be legal
+ elsewhere. This means that error messages are recorded and saved
+ for possible use later. If a line does not match a legal
+ construction, then the saved error message is reported. */
+
+#include "config.h"
+#include "system.h"
+
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "flags.h"
+#include "gfortran.h"
+
+int gfc_suppress_error = 0;
+
+static int terminal_width, buffer_flag, errors,
+ use_warning_buffer, warnings;
+
+static char *error_ptr, *warning_ptr;
+
+static gfc_error_buf error_buffer, warning_buffer;
+
+
+/* Per-file error initialization. */
+
+void
+gfc_error_init_1 (void)
+{
+
+ terminal_width = gfc_terminal_width();
+ errors = 0;
+ warnings = 0;
+ buffer_flag = 0;
+}
+
+
+/* Set the flag for buffering errors or not. */
+
+void
+gfc_buffer_error (int flag)
+{
+
+ buffer_flag = flag;
+}
+
+
+/* Add a single character to the error buffer or output depending on
+ buffer_flag. */
+
+static void
+error_char (char c)
+{
+
+ if (buffer_flag)
+ {
+ if (use_warning_buffer)
+ {
+ *warning_ptr++ = c;
+ if (warning_ptr - warning_buffer.message >= MAX_ERROR_MESSAGE)
+ gfc_internal_error ("error_char(): Warning buffer overflow");
+ }
+ else
+ {
+ *error_ptr++ = c;
+ if (error_ptr - error_buffer.message >= MAX_ERROR_MESSAGE)
+ gfc_internal_error ("error_char(): Error buffer overflow");
+ }
+ }
+ else
+ {
+ if (c != 0)
+ fputc (c, stderr);
+ }
+}
+
+
+/* Copy a string to wherever it needs to go. */
+
+static void
+error_string (const char *p)
+{
+
+ while (*p)
+ error_char (*p++);
+}
+
+
+/* Show the file, where it was included and the source line give a
+ locus. Calls error_printf() recursively, but the recursion is at
+ most one level deep. */
+
+static void error_printf (const char *, ...) ATTRIBUTE_PRINTF_1;
+
+static void
+show_locus (int offset, locus * l)
+{
+ gfc_file *f;
+ char c, *p;
+ int i, m;
+
+ /* TODO: Either limit the total length and number of included files
+ displayed or add buffering of arbitrary number of characters in
+ error messages. */
+ f = l->file;
+ error_printf ("In file %s:%d\n", f->filename, l->lp->start_line + l->line);
+
+ f = f->included_by;
+ while (f != NULL)
+ {
+ error_printf (" Included at %s:%d\n", f->filename,
+ f->loc.lp->start_line + f->loc.line);
+ f = f->included_by;
+ }
+
+ /* Show the line itself, taking care not to print more than what can
+ show up on the terminal. Tabs are converted to spaces. */
+ p = l->lp->line[l->line] + offset;
+ i = strlen (p);
+ if (i > terminal_width)
+ i = terminal_width - 1;
+
+ for (; i > 0; i--)
+ {
+ c = *p++;
+ if (c == '\t')
+ c = ' ';
+
+ if (ISPRINT (c))
+ error_char (c);
+ else
+ {
+ error_char ('\\');
+ error_char ('x');
+
+ m = ((c >> 4) & 0x0F) + '0';
+ if (m > '9')
+ m += 'A' - '9' - 1;
+ error_char (m);
+
+ m = (c & 0x0F) + '0';
+ if (m > '9')
+ m += 'A' - '9' - 1;
+ error_char (m);
+ }
+ }
+
+ error_char ('\n');
+}
+
+
+/* As part of printing an error, we show the source lines that caused
+ the problem. We show at least one, possibly two loci. If we're
+ showing two loci and they both refer to the same file and line, we
+ only print the line once. */
+
+static void
+show_loci (locus * l1, locus * l2)
+{
+ int offset, flag, i, m, c1, c2, cmax;
+
+ if (l1 == NULL)
+ {
+ error_printf ("<During initialization>\n");
+ return;
+ }
+
+ c1 = l1->nextc - l1->lp->line[l1->line];
+ c2 = 0;
+ if (l2 == NULL)
+ goto separate;
+
+ c2 = l2->nextc - l2->lp->line[l2->line];
+
+ if (c1 < c2)
+ m = c2 - c1;
+ else
+ m = c1 - c2;
+
+
+ if (l1->lp != l2->lp || l1->line != l2->line || m > terminal_width - 10)
+ goto separate;
+
+ offset = 0;
+ cmax = (c1 < c2) ? c2 : c1;
+ if (cmax > terminal_width - 5)
+ offset = cmax - terminal_width + 5;
+
+ if (offset < 0)
+ offset = 0;
+
+ c1 -= offset;
+ c2 -= offset;
+
+ show_locus (offset, l1);
+
+ /* Arrange that '1' and '2' will show up even if the two columns are equal. */
+ for (i = 1; i <= cmax; i++)
+ {
+ flag = 0;
+ if (i == c1)
+ {
+ error_char ('1');
+ flag = 1;
+ }
+ if (i == c2)
+ {
+ error_char ('2');
+ flag = 1;
+ }
+ if (flag == 0)
+ error_char (' ');
+ }
+
+ error_char ('\n');
+
+ return;
+
+separate:
+ offset = 0;
+
+ if (c1 > terminal_width - 5)
+ {
+ offset = c1 - 5;
+ if (offset < 0)
+ offset = 0;
+ c1 = c1 - offset;
+ }
+
+ show_locus (offset, l1);
+ for (i = 1; i < c1; i++)
+ error_char (' ');
+
+ error_char ('1');
+ error_char ('\n');
+
+ if (l2 != NULL)
+ {
+ offset = 0;
+
+ if (c2 > terminal_width - 20)
+ {
+ offset = c2 - 20;
+ if (offset < 0)
+ offset = 0;
+ c2 = c2 - offset;
+ }
+
+ show_locus (offset, l2);
+
+ for (i = 1; i < c2; i++)
+ error_char (' ');
+
+ error_char ('2');
+ error_char ('\n');
+ }
+}
+
+
+/* Workhorse for the error printing subroutines. This subroutine is
+ inspired by g77's error handling and is similar to printf() with
+ the following %-codes:
+
+ %c Character, %d Integer, %s String, %% Percent
+ %L Takes locus argument
+ %C Current locus (no argument)
+
+ If a locus pointer is given, the actual source line is printed out
+ and the column is indicated. Since we want the error message at
+ the bottom of any source file information, we must scan the
+ argument list twice. A maximum of two locus arguments are
+ permitted. */
+
+#define IBUF_LEN 30
+#define MAX_ARGS 10
+
+static void
+error_print (const char *type, const char *format0, va_list argp)
+{
+ char c, *p, int_buf[IBUF_LEN], c_arg[MAX_ARGS], *cp_arg[MAX_ARGS];
+ int i, n, have_l1, i_arg[MAX_ARGS];
+ locus *l1, *l2, *loc;
+ const char *format;
+
+ l1 = l2 = loc = NULL;
+
+ have_l1 = 0;
+
+ n = 0;
+ format = format0;
+
+ while (*format)
+ {
+ c = *format++;
+ if (c == '%')
+ {
+ c = *format++;
+
+ switch (c)
+ {
+ case '%':
+ break;
+
+ case 'L':
+ loc = va_arg (argp, locus *);
+ /* Fall through */
+
+ case 'C':
+ if (c == 'C')
+ loc = gfc_current_locus ();
+
+ if (have_l1)
+ {
+ l2 = loc;
+ }
+ else
+ {
+ l1 = loc;
+ have_l1 = 1;
+ }
+ break;
+
+ case 'd':
+ case 'i':
+ i_arg[n++] = va_arg (argp, int);
+ break;
+
+ case 'c':
+ c_arg[n++] = va_arg (argp, int);
+ break;
+
+ case 's':
+ cp_arg[n++] = va_arg (argp, char *);
+ break;
+ }
+ }
+ }
+
+ /* Show the current loci if we have to. */
+ if (have_l1)
+ show_loci (l1, l2);
+ error_string (type);
+ error_char (' ');
+
+ have_l1 = 0;
+ format = format0;
+ n = 0;
+
+ for (; *format; format++)
+ {
+ if (*format != '%')
+ {
+ error_char (*format);
+ continue;
+ }
+
+ format++;
+ switch (*format)
+ {
+ case '%':
+ error_char ('%');
+ break;
+
+ case 'c':
+ error_char (c_arg[n++]);
+ break;
+
+ case 's':
+ error_string (cp_arg[n++]);
+ break;
+
+ case 'i':
+ case 'd':
+ i = i_arg[n++];
+
+ if (i < 0)
+ {
+ i = -i;
+ error_char ('-');
+ }
+
+ p = int_buf + IBUF_LEN - 1;
+ *p-- = '\0';
+
+ if (i == 0)
+ *p-- = '0';
+
+ while (i > 0)
+ {
+ *p-- = i % 10 + '0';
+ i = i / 10;
+ }
+
+ error_string (p + 1);
+ break;
+
+ case 'C': /* Current locus */
+ case 'L': /* Specified locus */
+ error_string (have_l1 ? "(2)" : "(1)");
+ have_l1 = 1;
+ break;
+ }
+ }
+
+ error_char ('\n');
+}
+
+
+/* Wrapper for error_print(). */
+
+static void
+error_printf (const char *format, ...)
+{
+ va_list argp;
+
+ va_start (argp, format);
+ error_print ("", format, argp);
+ va_end (argp);
+}
+
+
+/* Issue a warning. */
+
+void
+gfc_warning (const char *format, ...)
+{
+ va_list argp;
+
+ if (inhibit_warnings)
+ return;
+
+ warning_buffer.flag = 1;
+ warning_ptr = warning_buffer.message;
+ use_warning_buffer = 1;
+
+ va_start (argp, format);
+ if (buffer_flag == 0)
+ warnings++;
+ error_print ("Warning:", format, argp);
+ va_end (argp);
+
+ error_char ('\0');
+}
+
+
+/* Possibly issue a warning/error about use of a nonstandard (or deleted)
+ feature. An error/warning will be issued if the currently selected
+ standard does not contain the requested bits. Return FAILURE if
+ and error is generated. */
+
+try
+gfc_notify_std (int std, const char *format, ...)
+{
+ va_list argp;
+ bool warning;
+
+ warning = ((gfc_option.warn_std & std) != 0)
+ && !inhibit_warnings;
+ if ((gfc_option.allow_std & std) != 0
+ && !warning)
+ return SUCCESS;
+
+ if (gfc_suppress_error)
+ return warning ? SUCCESS : FAILURE;
+
+ if (warning)
+ {
+ warning_buffer.flag = 1;
+ warning_ptr = warning_buffer.message;
+ use_warning_buffer = 1;
+ }
+ else
+ {
+ error_buffer.flag = 1;
+ error_ptr = error_buffer.message;
+ use_warning_buffer = 0;
+ }
+
+ if (buffer_flag == 0)
+ {
+ if (warning)
+ warnings++;
+ else
+ errors++;
+ }
+ va_start (argp, format);
+ if (warning)
+ error_print ("Warning:", format, argp);
+ else
+ error_print ("Error:", format, argp);
+ va_end (argp);
+
+ error_char ('\0');
+ return warning ? SUCCESS : FAILURE;
+}
+
+
+/* Immediate warning (i.e. do not buffer the warning). */
+
+void
+gfc_warning_now (const char *format, ...)
+{
+ va_list argp;
+ int i;
+
+ if (inhibit_warnings)
+ return;
+
+ i = buffer_flag;
+ buffer_flag = 0;
+ warnings++;
+
+ va_start (argp, format);
+ error_print ("Warning:", format, argp);
+ va_end (argp);
+
+ error_char ('\0');
+ buffer_flag = i;
+}
+
+
+/* Clear the warning flag. */
+
+void
+gfc_clear_warning (void)
+{
+
+ warning_buffer.flag = 0;
+}
+
+
+/* Check to see if any warnings have been saved.
+ If so, print the warning. */
+
+void
+gfc_warning_check (void)
+{
+
+ if (warning_buffer.flag)
+ {
+ warnings++;
+ fputs (warning_buffer.message, stderr);
+ warning_buffer.flag = 0;
+ }
+}
+
+
+/* Issue an error. */
+
+void
+gfc_error (const char *format, ...)
+{
+ va_list argp;
+
+ if (gfc_suppress_error)
+ return;
+
+ error_buffer.flag = 1;
+ error_ptr = error_buffer.message;
+ use_warning_buffer = 0;
+
+ va_start (argp, format);
+ if (buffer_flag == 0)
+ errors++;
+ error_print ("Error:", format, argp);
+ va_end (argp);
+
+ error_char ('\0');
+}
+
+
+/* Immediate error. */
+
+void
+gfc_error_now (const char *format, ...)
+{
+ va_list argp;
+ int i;
+
+ error_buffer.flag = 1;
+ error_ptr = error_buffer.message;
+
+ i = buffer_flag;
+ buffer_flag = 0;
+ errors++;
+
+ va_start (argp, format);
+ error_print ("Error:", format, argp);
+ va_end (argp);
+
+ error_char ('\0');
+ buffer_flag = i;
+}
+
+
+/* Fatal error, never returns. */
+
+void
+gfc_fatal_error (const char *format, ...)
+{
+ va_list argp;
+
+ buffer_flag = 0;
+
+ va_start (argp, format);
+ error_print ("Fatal Error:", format, argp);
+ va_end (argp);
+
+ exit (3);
+}
+
+
+/* This shouldn't happen... but sometimes does. */
+
+void
+gfc_internal_error (const char *format, ...)
+{
+ va_list argp;
+
+ buffer_flag = 0;
+
+ va_start (argp, format);
+
+ show_loci (gfc_current_locus (), NULL);
+ error_printf ("Internal Error at (1):");
+
+ error_print ("", format, argp);
+ va_end (argp);
+
+ exit (4);
+}
+
+
+/* Clear the error flag when we start to compile a source line. */
+
+void
+gfc_clear_error (void)
+{
+
+ error_buffer.flag = 0;
+}
+
+
+/* Check to see if any errors have been saved.
+ If so, print the error. Returns the state of error_flag. */
+
+int
+gfc_error_check (void)
+{
+ int rc;
+
+ rc = error_buffer.flag;
+
+ if (error_buffer.flag)
+ {
+ errors++;
+ fputs (error_buffer.message, stderr);
+ error_buffer.flag = 0;
+ }
+
+ return rc;
+}
+
+
+/* Save the existing error state. */
+
+void
+gfc_push_error (gfc_error_buf * err)
+{
+
+ err->flag = error_buffer.flag;
+ if (error_buffer.flag)
+ strcpy (err->message, error_buffer.message);
+
+ error_buffer.flag = 0;
+}
+
+
+/* Restore a previous pushed error state. */
+
+void
+gfc_pop_error (gfc_error_buf * err)
+{
+
+ error_buffer.flag = err->flag;
+ if (error_buffer.flag)
+ strcpy (error_buffer.message, err->message);
+}
+
+
+/* Debug wrapper for printf. */
+
+void
+gfc_status (const char *format, ...)
+{
+ va_list argp;
+
+ va_start (argp, format);
+
+ vprintf (format, argp);
+
+ va_end (argp);
+}
+
+
+/* Subroutine for outputting a single char so that we don't have to go
+ around creating a lot of 1-character strings. */
+
+void
+gfc_status_char (char c)
+{
+ putchar (c);
+}
+
+
+/* Report the number of warnings and errors that occored to the caller. */
+
+void
+gfc_get_errors (int *w, int *e)
+{
+
+ if (w != NULL)
+ *w = warnings;
+ if (e != NULL)
+ *e = errors;
+}
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
new file mode 100644
index 00000000000..8b3e391b06c
--- /dev/null
+++ b/gcc/fortran/expr.c
@@ -0,0 +1,1955 @@
+/* Routines for manipulation of expression nodes.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation,
+ Inc.
+ Contributed by Andy Vaught
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "gfortran.h"
+#include "arith.h"
+#include "match.h"
+
+/* Get a new expr node. */
+
+gfc_expr *
+gfc_get_expr (void)
+{
+ gfc_expr *e;
+
+ e = gfc_getmem (sizeof (gfc_expr));
+
+ gfc_clear_ts (&e->ts);
+ e->op1 = NULL;
+ e->op2 = NULL;
+ e->shape = NULL;
+ e->ref = NULL;
+ e->symtree = NULL;
+ e->uop = NULL;
+
+ return e;
+}
+
+
+/* Free an argument list and everything below it. */
+
+void
+gfc_free_actual_arglist (gfc_actual_arglist * a1)
+{
+ gfc_actual_arglist *a2;
+
+ while (a1)
+ {
+ a2 = a1->next;
+ gfc_free_expr (a1->expr);
+ gfc_free (a1);
+ a1 = a2;
+ }
+}
+
+
+/* Copy an arglist structure and all of the arguments. */
+
+gfc_actual_arglist *
+gfc_copy_actual_arglist (gfc_actual_arglist * p)
+{
+ gfc_actual_arglist *head, *tail, *new;
+
+ head = tail = NULL;
+
+ for (; p; p = p->next)
+ {
+ new = gfc_get_actual_arglist ();
+ *new = *p;
+
+ new->expr = gfc_copy_expr (p->expr);
+ new->next = NULL;
+
+ if (head == NULL)
+ head = new;
+ else
+ tail->next = new;
+
+ tail = new;
+ }
+
+ return head;
+}
+
+
+/* Free a list of reference structures. */
+
+void
+gfc_free_ref_list (gfc_ref * p)
+{
+ gfc_ref *q;
+ int i;
+
+ for (; p; p = q)
+ {
+ q = p->next;
+
+ switch (p->type)
+ {
+ case REF_ARRAY:
+ for (i = 0; i < GFC_MAX_DIMENSIONS; i++)
+ {
+ gfc_free_expr (p->u.ar.start[i]);
+ gfc_free_expr (p->u.ar.end[i]);
+ gfc_free_expr (p->u.ar.stride[i]);
+ }
+
+ break;
+
+ case REF_SUBSTRING:
+ gfc_free_expr (p->u.ss.start);
+ gfc_free_expr (p->u.ss.end);
+ break;
+
+ case REF_COMPONENT:
+ break;
+ }
+
+ gfc_free (p);
+ }
+}
+
+
+/* Workhorse function for gfc_free_expr() that frees everything
+ beneath an expression node, but not the node itself. This is
+ useful when we want to simplify a node and replace it with
+ something else or the expression node belongs to another structure. */
+
+static void
+free_expr0 (gfc_expr * e)
+{
+ int n;
+
+ switch (e->expr_type)
+ {
+ case EXPR_CONSTANT:
+ switch (e->ts.type)
+ {
+ case BT_INTEGER:
+ mpz_clear (e->value.integer);
+ break;
+
+ case BT_REAL:
+ mpf_clear (e->value.real);
+ break;
+
+ case BT_CHARACTER:
+ gfc_free (e->value.character.string);
+ break;
+
+ case BT_COMPLEX:
+ mpf_clear (e->value.complex.r);
+ mpf_clear (e->value.complex.i);
+ break;
+
+ default:
+ break;
+ }
+
+ break;
+
+ case EXPR_OP:
+ if (e->op1 != NULL)
+ gfc_free_expr (e->op1);
+ if (e->op2 != NULL)
+ gfc_free_expr (e->op2);
+ break;
+
+ case EXPR_FUNCTION:
+ gfc_free_actual_arglist (e->value.function.actual);
+ break;
+
+ case EXPR_VARIABLE:
+ break;
+
+ case EXPR_ARRAY:
+ case EXPR_STRUCTURE:
+ gfc_free_constructor (e->value.constructor);
+ break;
+
+ case EXPR_SUBSTRING:
+ gfc_free (e->value.character.string);
+ break;
+
+ case EXPR_NULL:
+ break;
+
+ default:
+ gfc_internal_error ("free_expr0(): Bad expr type");
+ }
+
+ /* Free a shape array. */
+ if (e->shape != NULL)
+ {
+ for (n = 0; n < e->rank; n++)
+ mpz_clear (e->shape[n]);
+
+ gfc_free (e->shape);
+ }
+
+ gfc_free_ref_list (e->ref);
+
+ memset (e, '\0', sizeof (gfc_expr));
+}
+
+
+/* Free an expression node and everything beneath it. */
+
+void
+gfc_free_expr (gfc_expr * e)
+{
+
+ if (e == NULL)
+ return;
+
+ free_expr0 (e);
+ gfc_free (e);
+}
+
+
+/* Graft the *src expression onto the *dest subexpression. */
+
+void
+gfc_replace_expr (gfc_expr * dest, gfc_expr * src)
+{
+
+ free_expr0 (dest);
+ *dest = *src;
+
+ gfc_free (src);
+}
+
+
+/* Try to extract an integer constant from the passed expression node.
+ Returns an error message or NULL if the result is set. It is
+ tempting to generate an error and return SUCCESS or FAILURE, but
+ failure is OK for some callers. */
+
+const char *
+gfc_extract_int (gfc_expr * expr, int *result)
+{
+
+ if (expr->expr_type != EXPR_CONSTANT)
+ return "Constant expression required at %C";
+
+ if (expr->ts.type != BT_INTEGER)
+ return "Integer expression required at %C";
+
+ if ((mpz_cmp_si (expr->value.integer, INT_MAX) > 0)
+ || (mpz_cmp_si (expr->value.integer, INT_MIN) < 0))
+ {
+ return "Integer value too large in expression at %C";
+ }
+
+ *result = (int) mpz_get_si (expr->value.integer);
+
+ return NULL;
+}
+
+
+/* Recursively copy a list of reference structures. */
+
+static gfc_ref *
+copy_ref (gfc_ref * src)
+{
+ gfc_array_ref *ar;
+ gfc_ref *dest;
+
+ if (src == NULL)
+ return NULL;
+
+ dest = gfc_get_ref ();
+ dest->type = src->type;
+
+ switch (src->type)
+ {
+ case REF_ARRAY:
+ ar = gfc_copy_array_ref (&src->u.ar);
+ dest->u.ar = *ar;
+ gfc_free (ar);
+ break;
+
+ case REF_COMPONENT:
+ dest->u.c = src->u.c;
+ break;
+
+ case REF_SUBSTRING:
+ dest->u.ss = src->u.ss;
+ dest->u.ss.start = gfc_copy_expr (src->u.ss.start);
+ dest->u.ss.end = gfc_copy_expr (src->u.ss.end);
+ break;
+ }
+
+ dest->next = copy_ref (src->next);
+
+ return dest;
+}
+
+
+/* Copy a shape array. */
+
+mpz_t *
+gfc_copy_shape (mpz_t * shape, int rank)
+{
+ mpz_t *new_shape;
+ int n;
+
+ if (shape == NULL)
+ return NULL;
+
+ new_shape = gfc_get_shape (rank);
+
+ for (n = 0; n < rank; n++)
+ mpz_init_set (new_shape[n], shape[n]);
+
+ return new_shape;
+}
+
+
+/* Given an expression pointer, return a copy of the expression. This
+ subroutine is recursive. */
+
+gfc_expr *
+gfc_copy_expr (gfc_expr * p)
+{
+ gfc_expr *q;
+ char *s;
+
+ if (p == NULL)
+ return NULL;
+
+ q = gfc_get_expr ();
+ *q = *p;
+
+ switch (q->expr_type)
+ {
+ case EXPR_SUBSTRING:
+ s = gfc_getmem (p->value.character.length + 1);
+ q->value.character.string = s;
+
+ memcpy (s, p->value.character.string, p->value.character.length + 1);
+
+ q->op1 = gfc_copy_expr (p->op1);
+ q->op2 = gfc_copy_expr (p->op2);
+ break;
+
+ case EXPR_CONSTANT:
+ switch (q->ts.type)
+ {
+ case BT_INTEGER:
+ mpz_init_set (q->value.integer, p->value.integer);
+ break;
+
+ case BT_REAL:
+ mpf_init_set (q->value.real, p->value.real);
+ break;
+
+ case BT_COMPLEX:
+ mpf_init_set (q->value.complex.r, p->value.complex.r);
+ mpf_init_set (q->value.complex.i, p->value.complex.i);
+ break;
+
+ case BT_CHARACTER:
+ s = gfc_getmem (p->value.character.length + 1);
+ q->value.character.string = s;
+
+ memcpy (s, p->value.character.string,
+ p->value.character.length + 1);
+ break;
+
+ case BT_LOGICAL:
+ case BT_DERIVED:
+ break; /* Already done */
+
+ case BT_PROCEDURE:
+ case BT_UNKNOWN:
+ gfc_internal_error ("gfc_copy_expr(): Bad expr node");
+ /* Not reached */
+ }
+
+ break;
+
+ case EXPR_OP:
+ switch (q->operator)
+ {
+ case INTRINSIC_NOT:
+ case INTRINSIC_UPLUS:
+ case INTRINSIC_UMINUS:
+ q->op1 = gfc_copy_expr (p->op1);
+ break;
+
+ default: /* Binary operators */
+ q->op1 = gfc_copy_expr (p->op1);
+ q->op2 = gfc_copy_expr (p->op2);
+ break;
+ }
+
+ break;
+
+ case EXPR_FUNCTION:
+ q->value.function.actual =
+ gfc_copy_actual_arglist (p->value.function.actual);
+ break;
+
+ case EXPR_STRUCTURE:
+ case EXPR_ARRAY:
+ q->value.constructor = gfc_copy_constructor (p->value.constructor);
+ break;
+
+ case EXPR_VARIABLE:
+ case EXPR_NULL:
+ break;
+ }
+
+ q->shape = gfc_copy_shape (p->shape, p->rank);
+
+ q->ref = copy_ref (p->ref);
+
+ return q;
+}
+
+
+/* Return the maximum kind of two expressions. In general, higher
+ kind numbers mean more precision for numeric types. */
+
+int
+gfc_kind_max (gfc_expr * e1, gfc_expr * e2)
+{
+
+ return (e1->ts.kind > e2->ts.kind) ? e1->ts.kind : e2->ts.kind;
+}
+
+
+/* Returns nonzero if the type is numeric, zero otherwise. */
+
+static int
+numeric_type (bt type)
+{
+
+ return type == BT_COMPLEX || type == BT_REAL || type == BT_INTEGER;
+}
+
+
+/* Returns nonzero if the typespec is a numeric type, zero otherwise. */
+
+int
+gfc_numeric_ts (gfc_typespec * ts)
+{
+
+ return numeric_type (ts->type);
+}
+
+
+/* Returns an expression node that is an integer constant. */
+
+gfc_expr *
+gfc_int_expr (int i)
+{
+ gfc_expr *p;
+
+ p = gfc_get_expr ();
+
+ p->expr_type = EXPR_CONSTANT;
+ p->ts.type = BT_INTEGER;
+ p->ts.kind = gfc_default_integer_kind ();
+
+ p->where = *gfc_current_locus ();
+ mpz_init_set_si (p->value.integer, i);
+
+ return p;
+}
+
+
+/* Returns an expression node that is a logical constant. */
+
+gfc_expr *
+gfc_logical_expr (int i, locus * where)
+{
+ gfc_expr *p;
+
+ p = gfc_get_expr ();
+
+ p->expr_type = EXPR_CONSTANT;
+ p->ts.type = BT_LOGICAL;
+ p->ts.kind = gfc_default_logical_kind ();
+
+ if (where == NULL)
+ where = gfc_current_locus ();
+ p->where = *where;
+ p->value.logical = i;
+
+ return p;
+}
+
+
+/* Return an expression node with an optional argument list attached.
+ A variable number of gfc_expr pointers are strung together in an
+ argument list with a NULL pointer terminating the list. */
+
+gfc_expr *
+gfc_build_conversion (gfc_expr * e)
+{
+ gfc_expr *p;
+
+ p = gfc_get_expr ();
+ p->expr_type = EXPR_FUNCTION;
+ p->symtree = NULL;
+ p->value.function.actual = NULL;
+
+ p->value.function.actual = gfc_get_actual_arglist ();
+ p->value.function.actual->expr = e;
+
+ return p;
+}
+
+
+/* Given an expression node with some sort of numeric binary
+ expression, insert type conversions required to make the operands
+ have the same type.
+
+ The exception is that the operands of an exponential don't have to
+ have the same type. If possible, the base is promoted to the type
+ of the exponent. For example, 1**2.3 becomes 1.0**2.3, but
+ 1.0**2 stays as it is. */
+
+void
+gfc_type_convert_binary (gfc_expr * e)
+{
+ gfc_expr *op1, *op2;
+
+ op1 = e->op1;
+ op2 = e->op2;
+
+ if (op1->ts.type == BT_UNKNOWN || op2->ts.type == BT_UNKNOWN)
+ {
+ gfc_clear_ts (&e->ts);
+ return;
+ }
+
+ /* Kind conversions of same type. */
+ if (op1->ts.type == op2->ts.type)
+ {
+
+ if (op1->ts.kind == op2->ts.kind)
+ {
+ /* No type conversions. */
+ e->ts = op1->ts;
+ goto done;
+ }
+
+ if (op1->ts.kind > op2->ts.kind)
+ gfc_convert_type (op2, &op1->ts, 2);
+ else
+ gfc_convert_type (op1, &op2->ts, 2);
+
+ e->ts = op1->ts;
+ goto done;
+ }
+
+ /* Integer combined with real or complex. */
+ if (op2->ts.type == BT_INTEGER)
+ {
+ e->ts = op1->ts;
+
+ /* Special cose for ** operator. */
+ if (e->operator == INTRINSIC_POWER)
+ goto done;
+
+ gfc_convert_type (e->op2, &e->ts, 2);
+ goto done;
+ }
+
+ if (op1->ts.type == BT_INTEGER)
+ {
+ e->ts = op2->ts;
+ gfc_convert_type (e->op1, &e->ts, 2);
+ goto done;
+ }
+
+ /* Real combined with complex. */
+ e->ts.type = BT_COMPLEX;
+ if (op1->ts.kind > op2->ts.kind)
+ e->ts.kind = op1->ts.kind;
+ else
+ e->ts.kind = op2->ts.kind;
+ if (op1->ts.type != BT_COMPLEX || op1->ts.kind != e->ts.kind)
+ gfc_convert_type (e->op1, &e->ts, 2);
+ if (op2->ts.type != BT_COMPLEX || op2->ts.kind != e->ts.kind)
+ gfc_convert_type (e->op2, &e->ts, 2);
+
+done:
+ return;
+}
+
+
+/* Function to determine if an expression is constant or not. This
+ function expects that the expression has already been simplified. */
+
+int
+gfc_is_constant_expr (gfc_expr * e)
+{
+ gfc_constructor *c;
+ gfc_actual_arglist *arg;
+ int rv;
+
+ if (e == NULL)
+ return 1;
+
+ switch (e->expr_type)
+ {
+ case EXPR_OP:
+ rv = (gfc_is_constant_expr (e->op1)
+ && (e->op2 == NULL
+ || gfc_is_constant_expr (e->op2)));
+
+ break;
+
+ case EXPR_VARIABLE:
+ rv = 0;
+ break;
+
+ case EXPR_FUNCTION:
+ /* Call to intrinsic with at least one argument. */
+ rv = 0;
+ if (e->value.function.isym && e->value.function.actual)
+ {
+ for (arg = e->value.function.actual; arg; arg = arg->next)
+ {
+ if (!gfc_is_constant_expr (arg->expr))
+ break;
+ }
+ if (arg == NULL)
+ rv = 1;
+ }
+ break;
+
+ case EXPR_CONSTANT:
+ case EXPR_NULL:
+ rv = 1;
+ break;
+
+ case EXPR_SUBSTRING:
+ rv = gfc_is_constant_expr (e->op1) && gfc_is_constant_expr (e->op2);
+ break;
+
+ case EXPR_STRUCTURE:
+ rv = 0;
+ for (c = e->value.constructor; c; c = c->next)
+ if (!gfc_is_constant_expr (c->expr))
+ break;
+
+ if (c == NULL)
+ rv = 1;
+ break;
+
+ case EXPR_ARRAY:
+ rv = gfc_constant_ac (e);
+ break;
+
+ default:
+ gfc_internal_error ("gfc_is_constant_expr(): Unknown expression type");
+ }
+
+ return rv;
+}
+
+
+/* Try to collapse intrinsic expressions. */
+
+static try
+simplify_intrinsic_op (gfc_expr * p, int type)
+{
+ gfc_expr *op1, *op2, *result;
+
+ if (p->operator == INTRINSIC_USER)
+ return SUCCESS;
+
+ op1 = p->op1;
+ op2 = p->op2;
+
+ if (gfc_simplify_expr (op1, type) == FAILURE)
+ return FAILURE;
+ if (gfc_simplify_expr (op2, type) == FAILURE)
+ return FAILURE;
+
+ if (!gfc_is_constant_expr (op1)
+ || (op2 != NULL && !gfc_is_constant_expr (op2)))
+ return SUCCESS;
+
+ /* Rip p apart */
+ p->op1 = NULL;
+ p->op2 = NULL;
+
+ switch (p->operator)
+ {
+ case INTRINSIC_UPLUS:
+ result = gfc_uplus (op1);
+ break;
+
+ case INTRINSIC_UMINUS:
+ result = gfc_uminus (op1);
+ break;
+
+ case INTRINSIC_PLUS:
+ result = gfc_add (op1, op2);
+ break;
+
+ case INTRINSIC_MINUS:
+ result = gfc_subtract (op1, op2);
+ break;
+
+ case INTRINSIC_TIMES:
+ result = gfc_multiply (op1, op2);
+ break;
+
+ case INTRINSIC_DIVIDE:
+ result = gfc_divide (op1, op2);
+ break;
+
+ case INTRINSIC_POWER:
+ result = gfc_power (op1, op2);
+ break;
+
+ case INTRINSIC_CONCAT:
+ result = gfc_concat (op1, op2);
+ break;
+
+ case INTRINSIC_EQ:
+ result = gfc_eq (op1, op2);
+ break;
+
+ case INTRINSIC_NE:
+ result = gfc_ne (op1, op2);
+ break;
+
+ case INTRINSIC_GT:
+ result = gfc_gt (op1, op2);
+ break;
+
+ case INTRINSIC_GE:
+ result = gfc_ge (op1, op2);
+ break;
+
+ case INTRINSIC_LT:
+ result = gfc_lt (op1, op2);
+ break;
+
+ case INTRINSIC_LE:
+ result = gfc_le (op1, op2);
+ break;
+
+ case INTRINSIC_NOT:
+ result = gfc_not (op1);
+ break;
+
+ case INTRINSIC_AND:
+ result = gfc_and (op1, op2);
+ break;
+
+ case INTRINSIC_OR:
+ result = gfc_or (op1, op2);
+ break;
+
+ case INTRINSIC_EQV:
+ result = gfc_eqv (op1, op2);
+ break;
+
+ case INTRINSIC_NEQV:
+ result = gfc_neqv (op1, op2);
+ break;
+
+ default:
+ gfc_internal_error ("simplify_intrinsic_op(): Bad operator");
+ }
+
+ if (result == NULL)
+ {
+ gfc_free_expr (op1);
+ gfc_free_expr (op2);
+ return FAILURE;
+ }
+
+ gfc_replace_expr (p, result);
+
+ return SUCCESS;
+}
+
+
+/* Subroutine to simplify constructor expressions. Mutually recursive
+ with gfc_simplify_expr(). */
+
+static try
+simplify_constructor (gfc_constructor * c, int type)
+{
+
+ for (; c; c = c->next)
+ {
+ if (c->iterator
+ && (gfc_simplify_expr (c->iterator->start, type) == FAILURE
+ || gfc_simplify_expr (c->iterator->end, type) == FAILURE
+ || gfc_simplify_expr (c->iterator->step, type) == FAILURE))
+ return FAILURE;
+
+ if (c->expr && gfc_simplify_expr (c->expr, type) == FAILURE)
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Pull a single array element out of an array constructor. */
+
+static gfc_constructor *
+find_array_element (gfc_constructor * cons, gfc_array_ref * ar)
+{
+ unsigned long nelemen;
+ int i;
+ mpz_t delta;
+ mpz_t offset;
+
+ mpz_init_set_ui (offset, 0);
+ mpz_init (delta);
+ for (i = 0; i < ar->dimen; i++)
+ {
+ if (ar->start[i]->expr_type != EXPR_CONSTANT)
+ {
+ cons = NULL;
+ break;
+ }
+ mpz_sub (delta, ar->start[i]->value.integer,
+ ar->as->lower[i]->value.integer);
+ mpz_add (offset, offset, delta);
+ }
+
+ if (cons)
+ {
+ if (mpz_fits_ulong_p (offset))
+ {
+ for (nelemen = mpz_get_ui (offset); nelemen > 0; nelemen--)
+ {
+ if (cons->iterator)
+ {
+ cons = NULL;
+ break;
+ }
+ cons = cons->next;
+ }
+ }
+ else
+ cons = NULL;
+ }
+
+ mpz_clear (delta);
+ mpz_clear (offset);
+
+ return cons;
+}
+
+
+/* Find a component of a structure constructor. */
+
+static gfc_constructor *
+find_component_ref (gfc_constructor * cons, gfc_ref * ref)
+{
+ gfc_component *comp;
+ gfc_component *pick;
+
+ comp = ref->u.c.sym->components;
+ pick = ref->u.c.component;
+ while (comp != pick)
+ {
+ comp = comp->next;
+ cons = cons->next;
+ }
+
+ return cons;
+}
+
+
+/* Replace an expression with the contents of a constructor, removing
+ the subobject reference in the process. */
+
+static void
+remove_subobject_ref (gfc_expr * p, gfc_constructor * cons)
+{
+ gfc_expr *e;
+
+ e = cons->expr;
+ cons->expr = NULL;
+ e->ref = p->ref->next;
+ p->ref->next = NULL;
+ gfc_replace_expr (p, e);
+}
+
+
+/* Simplify a subobject reference of a constructor. This occurs when
+ parameter variable values are substituted. */
+
+static try
+simplify_const_ref (gfc_expr * p)
+{
+ gfc_constructor *cons;
+
+ while (p->ref)
+ {
+ switch (p->ref->type)
+ {
+ case REF_ARRAY:
+ switch (p->ref->u.ar.type)
+ {
+ case AR_ELEMENT:
+ cons = find_array_element (p->value.constructor, &p->ref->u.ar);
+ if (!cons)
+ return SUCCESS;
+ remove_subobject_ref (p, cons);
+ break;
+
+ case AR_FULL:
+ if (p->ref->next != NULL)
+ {
+ /* TODO: Simplify array subobject references. */
+ return SUCCESS;
+ }
+ gfc_free_ref_list (p->ref);
+ p->ref = NULL;
+ break;
+
+ default:
+ /* TODO: Simplify array subsections. */
+ return SUCCESS;
+ }
+
+ break;
+
+ case REF_COMPONENT:
+ cons = find_component_ref (p->value.constructor, p->ref);
+ remove_subobject_ref (p, cons);
+ break;
+
+ case REF_SUBSTRING:
+ /* TODO: Constant substrings. */
+ return SUCCESS;
+ }
+ }
+
+ return SUCCESS;
+}
+
+
+/* Simplify a chain of references. */
+
+static try
+simplify_ref_chain (gfc_ref * ref, int type)
+{
+ int n;
+
+ for (; ref; ref = ref->next)
+ {
+ switch (ref->type)
+ {
+ case REF_ARRAY:
+ for (n = 0; n < ref->u.ar.dimen; n++)
+ {
+ if (gfc_simplify_expr (ref->u.ar.start[n], type)
+ == FAILURE)
+ return FAILURE;
+ if (gfc_simplify_expr (ref->u.ar.end[n], type)
+ == FAILURE)
+ return FAILURE;
+ if (gfc_simplify_expr (ref->u.ar.stride[n], type)
+ == FAILURE)
+ return FAILURE;
+ }
+ break;
+
+ case REF_SUBSTRING:
+ if (gfc_simplify_expr (ref->u.ss.start, type) == FAILURE)
+ return FAILURE;
+ if (gfc_simplify_expr (ref->u.ss.end, type) == FAILURE)
+ return FAILURE;
+ break;
+
+ default:
+ break;
+ }
+ }
+ return SUCCESS;
+}
+
+
+/* Try to substitute the value of a parameter variable. */
+static try
+simplify_parameter_variable (gfc_expr * p, int type)
+{
+ gfc_expr *e;
+ try t;
+
+ e = gfc_copy_expr (p->symtree->n.sym->value);
+ if (p->ref)
+ e->ref = copy_ref (p->ref);
+ t = gfc_simplify_expr (e, type);
+
+ /* Only use the simplification if it eliminated all subobject
+ references. */
+ if (t == SUCCESS && ! e->ref)
+ gfc_replace_expr (p, e);
+ else
+ gfc_free_expr (e);
+
+ return t;
+}
+
+/* Given an expression, simplify it by collapsing constant
+ expressions. Most simplification takes place when the expression
+ tree is being constructed. If an intrinsic function is simplified
+ at some point, we get called again to collapse the result against
+ other constants.
+
+ We work by recursively simplifying expression nodes, simplifying
+ intrinsic functions where possible, which can lead to further
+ constant collapsing. If an operator has constant operand(s), we
+ rip the expression apart, and rebuild it, hoping that it becomes
+ something simpler.
+
+ The expression type is defined for:
+ 0 Basic expression parsing
+ 1 Simplifying array constructors -- will substitute
+ iterator values.
+ Returns FAILURE on error, SUCCESS otherwise.
+ NOTE: Will return SUCCESS even if the expression can not be simplified. */
+
+try
+gfc_simplify_expr (gfc_expr * p, int type)
+{
+ gfc_actual_arglist *ap;
+
+ if (p == NULL)
+ return SUCCESS;
+
+ switch (p->expr_type)
+ {
+ case EXPR_CONSTANT:
+ case EXPR_NULL:
+ break;
+
+ case EXPR_FUNCTION:
+ for (ap = p->value.function.actual; ap; ap = ap->next)
+ if (gfc_simplify_expr (ap->expr, type) == FAILURE)
+ return FAILURE;
+
+ if (p->value.function.isym != NULL
+ && gfc_intrinsic_func_interface (p, 1) == MATCH_ERROR)
+ return FAILURE;
+
+ break;
+
+ case EXPR_SUBSTRING:
+ if (gfc_simplify_expr (p->op1, type) == FAILURE
+ || gfc_simplify_expr (p->op2, type) == FAILURE)
+ return FAILURE;
+
+ /* TODO: evaluate constant substrings. */
+
+ break;
+
+ case EXPR_OP:
+ if (simplify_intrinsic_op (p, type) == FAILURE)
+ return FAILURE;
+ break;
+
+ case EXPR_VARIABLE:
+ /* Only substitute array parameter variables if we are in an
+ initialization expression, or we want a subsection. */
+ if (p->symtree->n.sym->attr.flavor == FL_PARAMETER
+ && (gfc_init_expr || p->ref
+ || p->symtree->n.sym->value->expr_type != EXPR_ARRAY))
+ {
+ if (simplify_parameter_variable (p, type) == FAILURE)
+ return FAILURE;
+ break;
+ }
+
+ if (type == 1)
+ {
+ gfc_simplify_iterator_var (p);
+ }
+
+ /* Simplify subcomponent references. */
+ if (simplify_ref_chain (p->ref, type) == FAILURE)
+ return FAILURE;
+
+ break;
+
+ case EXPR_STRUCTURE:
+ case EXPR_ARRAY:
+ if (simplify_ref_chain (p->ref, type) == FAILURE)
+ return FAILURE;
+
+ if (simplify_constructor (p->value.constructor, type) == FAILURE)
+ return FAILURE;
+
+ if (p->expr_type == EXPR_ARRAY)
+ gfc_expand_constructor (p);
+
+ if (simplify_const_ref (p) == FAILURE)
+ return FAILURE;
+
+ break;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Returns the type of an expression with the exception that iterator
+ variables are automatically integers no matter what else they may
+ be declared as. */
+
+static bt
+et0 (gfc_expr * e)
+{
+
+ if (e->expr_type == EXPR_VARIABLE && gfc_check_iter_variable (e) == SUCCESS)
+ return BT_INTEGER;
+
+ return e->ts.type;
+}
+
+
+/* Check an intrinsic arithmetic operation to see if it is consistent
+ with some type of expression. */
+
+static try check_init_expr (gfc_expr *);
+
+static try
+check_intrinsic_op (gfc_expr * e, try (*check_function) (gfc_expr *))
+{
+
+ if ((*check_function) (e->op1) == FAILURE)
+ return FAILURE;
+
+ switch (e->operator)
+ {
+ case INTRINSIC_UPLUS:
+ case INTRINSIC_UMINUS:
+ if (!numeric_type (et0 (e->op1)))
+ goto not_numeric;
+ break;
+
+ case INTRINSIC_EQ:
+ case INTRINSIC_NE:
+ case INTRINSIC_GT:
+ case INTRINSIC_GE:
+ case INTRINSIC_LT:
+ case INTRINSIC_LE:
+
+ case INTRINSIC_PLUS:
+ case INTRINSIC_MINUS:
+ case INTRINSIC_TIMES:
+ case INTRINSIC_DIVIDE:
+ case INTRINSIC_POWER:
+ if ((*check_function) (e->op2) == FAILURE)
+ return FAILURE;
+
+ if (!numeric_type (et0 (e->op1)) || !numeric_type (et0 (e->op2)))
+ goto not_numeric;
+
+ if (e->operator != INTRINSIC_POWER)
+ break;
+
+ if (check_function == check_init_expr && et0 (e->op2) != BT_INTEGER)
+ {
+ gfc_error ("Exponent at %L must be INTEGER for an initialization "
+ "expression", &e->op2->where);
+ return FAILURE;
+ }
+
+ break;
+
+ case INTRINSIC_CONCAT:
+ if ((*check_function) (e->op2) == FAILURE)
+ return FAILURE;
+
+ if (et0 (e->op1) != BT_CHARACTER || et0 (e->op2) != BT_CHARACTER)
+ {
+ gfc_error ("Concatenation operator in expression at %L "
+ "must have two CHARACTER operands", &e->op1->where);
+ return FAILURE;
+ }
+
+ if (e->op1->ts.kind != e->op2->ts.kind)
+ {
+ gfc_error ("Concat operator at %L must concatenate strings of the "
+ "same kind", &e->where);
+ return FAILURE;
+ }
+
+ break;
+
+ case INTRINSIC_NOT:
+ if (et0 (e->op1) != BT_LOGICAL)
+ {
+ gfc_error (".NOT. operator in expression at %L must have a LOGICAL "
+ "operand", &e->op1->where);
+ return FAILURE;
+ }
+
+ break;
+
+ case INTRINSIC_AND:
+ case INTRINSIC_OR:
+ case INTRINSIC_EQV:
+ case INTRINSIC_NEQV:
+ if ((*check_function) (e->op2) == FAILURE)
+ return FAILURE;
+
+ if (et0 (e->op1) != BT_LOGICAL || et0 (e->op2) != BT_LOGICAL)
+ {
+ gfc_error ("LOGICAL operands are required in expression at %L",
+ &e->where);
+ return FAILURE;
+ }
+
+ break;
+
+ default:
+ gfc_error ("Only intrinsic operators can be used in expression at %L",
+ &e->where);
+ return FAILURE;
+ }
+
+ return SUCCESS;
+
+not_numeric:
+ gfc_error ("Numeric operands are required in expression at %L", &e->where);
+
+ return FAILURE;
+}
+
+
+
+/* Certain inquiry functions are specifically allowed to have variable
+ arguments, which is an exception to the normal requirement that an
+ initialization function have initialization arguments. We head off
+ this problem here. */
+
+static try
+check_inquiry (gfc_expr * e)
+{
+ const char *name;
+
+ /* FIXME: This should be moved into the intrinsic definitions,
+ to eliminate this ugly hack. */
+ static const char * const inquiry_function[] = {
+ "digits", "epsilon", "huge", "kind", "maxexponent", "minexponent",
+ "precision", "radix", "range", "tiny", "bit_size", "size", "shape",
+ "lbound", "ubound", NULL
+ };
+
+ int i;
+
+ /* These functions must have exactly one argument. */
+ if (e->value.function.actual == NULL
+ || e->value.function.actual->next != NULL)
+ return FAILURE;
+
+ if (e->value.function.name != NULL
+ && e->value.function.name[0] != '\0')
+ return FAILURE;
+
+ name = e->symtree->n.sym->name;
+
+ for (i = 0; inquiry_function[i]; i++)
+ if (strcmp (inquiry_function[i], name) == 0)
+ break;
+
+ if (inquiry_function[i] == NULL)
+ return FAILURE;
+
+ e = e->value.function.actual->expr;
+
+ if (e == NULL || e->expr_type != EXPR_VARIABLE)
+ return FAILURE;
+
+ /* At this point we have a numeric inquiry function with a variable
+ argument. The type of the variable might be undefined, but we
+ need it now, because the arguments of these functions are allowed
+ to be undefined. */
+
+ if (e->ts.type == BT_UNKNOWN)
+ {
+ if (e->symtree->n.sym->ts.type == BT_UNKNOWN
+ && gfc_set_default_type (e->symtree->n.sym, 0, gfc_current_ns)
+ == FAILURE)
+ return FAILURE;
+
+ e->ts = e->symtree->n.sym->ts;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Verify that an expression is an initialization expression. A side
+ effect is that the expression tree is reduced to a single constant
+ node if all goes well. This would normally happen when the
+ expression is constructed but function references are assumed to be
+ intrinsics in the context of initialization expressions. If
+ FAILURE is returned an error message has been generated. */
+
+static try
+check_init_expr (gfc_expr * e)
+{
+ gfc_actual_arglist *ap;
+ match m;
+ try t;
+
+ if (e == NULL)
+ return SUCCESS;
+
+ switch (e->expr_type)
+ {
+ case EXPR_OP:
+ t = check_intrinsic_op (e, check_init_expr);
+ if (t == SUCCESS)
+ t = gfc_simplify_expr (e, 0);
+
+ break;
+
+ case EXPR_FUNCTION:
+ t = SUCCESS;
+
+ if (check_inquiry (e) != SUCCESS)
+ {
+ t = SUCCESS;
+ for (ap = e->value.function.actual; ap; ap = ap->next)
+ if (check_init_expr (ap->expr) == FAILURE)
+ {
+ t = FAILURE;
+ break;
+ }
+ }
+
+ if (t == SUCCESS)
+ {
+ m = gfc_intrinsic_func_interface (e, 0);
+
+ if (m == MATCH_NO)
+ gfc_error ("Function '%s' in initialization expression at %L "
+ "must be an intrinsic function",
+ e->symtree->n.sym->name, &e->where);
+
+ if (m != MATCH_YES)
+ t = FAILURE;
+ }
+
+ break;
+
+ case EXPR_VARIABLE:
+ t = SUCCESS;
+
+ if (gfc_check_iter_variable (e) == SUCCESS)
+ break;
+
+ if (e->symtree->n.sym->attr.flavor == FL_PARAMETER)
+ {
+ t = simplify_parameter_variable (e, 0);
+ break;
+ }
+
+ gfc_error ("Variable '%s' at %L cannot appear in an initialization "
+ "expression", e->symtree->n.sym->name, &e->where);
+ t = FAILURE;
+ break;
+
+ case EXPR_CONSTANT:
+ case EXPR_NULL:
+ t = SUCCESS;
+ break;
+
+ case EXPR_SUBSTRING:
+ t = check_init_expr (e->op1);
+ if (t == FAILURE)
+ break;
+
+ t = check_init_expr (e->op2);
+ if (t == SUCCESS)
+ t = gfc_simplify_expr (e, 0);
+
+ break;
+
+ case EXPR_STRUCTURE:
+ t = gfc_check_constructor (e, check_init_expr);
+ break;
+
+ case EXPR_ARRAY:
+ t = gfc_check_constructor (e, check_init_expr);
+ if (t == FAILURE)
+ break;
+
+ t = gfc_expand_constructor (e);
+ if (t == FAILURE)
+ break;
+
+ t = gfc_check_constructor_type (e);
+ break;
+
+ default:
+ gfc_internal_error ("check_init_expr(): Unknown expression type");
+ }
+
+ return t;
+}
+
+
+/* Match an initialization expression. We work by first matching an
+ expression, then reducing it to a constant. */
+
+match
+gfc_match_init_expr (gfc_expr ** result)
+{
+ gfc_expr *expr;
+ match m;
+ try t;
+
+ m = gfc_match_expr (&expr);
+ if (m != MATCH_YES)
+ return m;
+
+ gfc_init_expr = 1;
+ t = gfc_resolve_expr (expr);
+ if (t == SUCCESS)
+ t = check_init_expr (expr);
+ gfc_init_expr = 0;
+
+ if (t == FAILURE)
+ {
+ gfc_free_expr (expr);
+ return MATCH_ERROR;
+ }
+
+ if (expr->expr_type == EXPR_ARRAY
+ && (gfc_check_constructor_type (expr) == FAILURE
+ || gfc_expand_constructor (expr) == FAILURE))
+ {
+ gfc_free_expr (expr);
+ return MATCH_ERROR;
+ }
+
+ if (!gfc_is_constant_expr (expr))
+ gfc_internal_error ("Initialization expression didn't reduce %C");
+
+ *result = expr;
+
+ return MATCH_YES;
+}
+
+
+
+static try check_restricted (gfc_expr *);
+
+/* Given an actual argument list, test to see that each argument is a
+ restricted expression and optionally if the expression type is
+ integer or character. */
+
+static try
+restricted_args (gfc_actual_arglist * a, int check_type)
+{
+ bt type;
+
+ for (; a; a = a->next)
+ {
+ if (check_restricted (a->expr) == FAILURE)
+ return FAILURE;
+
+ if (!check_type)
+ continue;
+
+ type = a->expr->ts.type;
+ if (type != BT_CHARACTER && type != BT_INTEGER)
+ {
+ gfc_error
+ ("Function argument at %L must be of type INTEGER or CHARACTER",
+ &a->expr->where);
+ return FAILURE;
+ }
+ }
+
+ return SUCCESS;
+}
+
+
+/************* Restricted/specification expressions *************/
+
+
+/* Make sure a non-intrinsic function is a specification function. */
+
+static try
+external_spec_function (gfc_expr * e)
+{
+ gfc_symbol *f;
+
+ f = e->value.function.esym;
+
+ if (f->attr.proc == PROC_ST_FUNCTION)
+ {
+ gfc_error ("Specification function '%s' at %L cannot be a statement "
+ "function", f->name, &e->where);
+ return FAILURE;
+ }
+
+ if (f->attr.proc == PROC_INTERNAL)
+ {
+ gfc_error ("Specification function '%s' at %L cannot be an internal "
+ "function", f->name, &e->where);
+ return FAILURE;
+ }
+
+ if (!f->attr.pure)
+ {
+ gfc_error ("Specification function '%s' at %L must be PURE", f->name,
+ &e->where);
+ return FAILURE;
+ }
+
+ if (f->attr.recursive)
+ {
+ gfc_error ("Specification function '%s' at %L cannot be RECURSIVE",
+ f->name, &e->where);
+ return FAILURE;
+ }
+
+ return restricted_args (e->value.function.actual, 0);
+}
+
+
+/* Check to see that a function reference to an intrinsic is a
+ restricted expression. Some functions required by the standard are
+ omitted because references to them have already been simplified.
+ Strictly speaking, a lot of these checks are redundant with other
+ checks. If a function is indeed a particular intrinsic, then the
+ type of its argument have already been checked and passed. */
+
+static try
+restricted_intrinsic (gfc_expr * e)
+{
+ gfc_intrinsic_sym *sym;
+
+ static struct
+ {
+ const char *name;
+ int case_number;
+ }
+ const *cp, cases[] =
+ {
+ {"repeat", 0},
+ {"reshape", 0},
+ {"selected_int_kind", 0},
+ {"selected_real_kind", 0},
+ {"transfer", 0},
+ {"trim", 0},
+ {"null", 1},
+ {"lbound", 2},
+ {"shape", 2},
+ {"size", 2},
+ {"ubound", 2},
+ /* bit_size() has already been reduced */
+ {"len", 0},
+ /* kind() has already been reduced */
+ /* Numeric inquiry functions have been reduced */
+ { NULL, 0}
+ };
+
+ try t;
+
+ sym = e->value.function.isym;
+ if (!sym)
+ return FAILURE;
+
+ if (sym->elemental)
+ return restricted_args (e->value.function.actual, 1);
+
+ for (cp = cases; cp->name; cp++)
+ if (strcmp (cp->name, sym->name) == 0)
+ break;
+
+ if (cp->name == NULL)
+ {
+ gfc_error ("Intrinsic function '%s' at %L is not a restricted function",
+ sym->name, &e->where);
+ return FAILURE;
+ }
+
+ switch (cp->case_number)
+ {
+ case 0:
+ /* Functions that are restricted if they have character/integer args. */
+ t = restricted_args (e->value.function.actual, 1);
+ break;
+
+ case 1: /* NULL() */
+ t = SUCCESS;
+ break;
+
+ case 2:
+ /* Functions that could be checking the bounds of an assumed-size array. */
+ t = SUCCESS;
+ /* TODO: implement checks from 7.1.6.2 (10) */
+ break;
+
+ default:
+ gfc_internal_error ("restricted_intrinsic(): Bad case");
+ }
+
+ return t;
+}
+
+
+/* Verify that an expression is a restricted expression. Like its
+ cousin check_init_expr(), an error message is generated if we
+ return FAILURE. */
+
+static try
+check_restricted (gfc_expr * e)
+{
+ gfc_symbol *sym;
+ try t;
+
+ if (e == NULL)
+ return SUCCESS;
+
+ switch (e->expr_type)
+ {
+ case EXPR_OP:
+ t = check_intrinsic_op (e, check_restricted);
+ if (t == SUCCESS)
+ t = gfc_simplify_expr (e, 0);
+
+ break;
+
+ case EXPR_FUNCTION:
+ t = e->value.function.esym ?
+ external_spec_function (e) : restricted_intrinsic (e);
+
+ break;
+
+ case EXPR_VARIABLE:
+ sym = e->symtree->n.sym;
+ t = FAILURE;
+
+ if (sym->attr.optional)
+ {
+ gfc_error ("Dummy argument '%s' at %L cannot be OPTIONAL",
+ sym->name, &e->where);
+ break;
+ }
+
+ if (sym->attr.intent == INTENT_OUT)
+ {
+ gfc_error ("Dummy argument '%s' at %L cannot be INTENT(OUT)",
+ sym->name, &e->where);
+ break;
+ }
+
+ if (sym->attr.in_common
+ || sym->attr.use_assoc
+ || sym->attr.dummy
+ || sym->ns != gfc_current_ns
+ || (sym->ns->proc_name != NULL
+ && sym->ns->proc_name->attr.flavor == FL_MODULE))
+ {
+ t = SUCCESS;
+ break;
+ }
+
+ gfc_error ("Variable '%s' cannot appear in the expression at %L",
+ sym->name, &e->where);
+
+ break;
+
+ case EXPR_NULL:
+ case EXPR_CONSTANT:
+ t = SUCCESS;
+ break;
+
+ case EXPR_SUBSTRING:
+ t = gfc_specification_expr (e->op1);
+ if (t == FAILURE)
+ break;
+
+ t = gfc_specification_expr (e->op2);
+ if (t == SUCCESS)
+ t = gfc_simplify_expr (e, 0);
+
+ break;
+
+ case EXPR_STRUCTURE:
+ t = gfc_check_constructor (e, check_restricted);
+ break;
+
+ case EXPR_ARRAY:
+ t = gfc_check_constructor (e, check_restricted);
+ break;
+
+ default:
+ gfc_internal_error ("check_restricted(): Unknown expression type");
+ }
+
+ return t;
+}
+
+
+/* Check to see that an expression is a specification expression. If
+ we return FAILURE, an error has been generated. */
+
+try
+gfc_specification_expr (gfc_expr * e)
+{
+
+ if (e->ts.type != BT_INTEGER)
+ {
+ gfc_error ("Expression at %L must be of INTEGER type", &e->where);
+ return FAILURE;
+ }
+
+ if (e->rank != 0)
+ {
+ gfc_error ("Expression at %L must be scalar", &e->where);
+ return FAILURE;
+ }
+
+ if (gfc_simplify_expr (e, 0) == FAILURE)
+ return FAILURE;
+
+ return check_restricted (e);
+}
+
+
+/************** Expression conformance checks. *************/
+
+/* Given two expressions, make sure that the arrays are conformable. */
+
+try
+gfc_check_conformance (const char *optype, gfc_expr * op1, gfc_expr * op2)
+{
+ int op1_flag, op2_flag, d;
+ mpz_t op1_size, op2_size;
+ try t;
+
+ if (op1->rank == 0 || op2->rank == 0)
+ return SUCCESS;
+
+ if (op1->rank != op2->rank)
+ {
+ gfc_error ("Incompatible ranks in %s at %L", optype, &op1->where);
+ return FAILURE;
+ }
+
+ t = SUCCESS;
+
+ for (d = 0; d < op1->rank; d++)
+ {
+ op1_flag = gfc_array_dimen_size (op1, d, &op1_size) == SUCCESS;
+ op2_flag = gfc_array_dimen_size (op2, d, &op2_size) == SUCCESS;
+
+ if (op1_flag && op2_flag && mpz_cmp (op1_size, op2_size) != 0)
+ {
+ gfc_error ("%s at %L has different shape on dimension %d (%d/%d)",
+ optype, &op1->where, d + 1, (int) mpz_get_si (op1_size),
+ (int) mpz_get_si (op2_size));
+
+ t = FAILURE;
+ }
+
+ if (op1_flag)
+ mpz_clear (op1_size);
+ if (op2_flag)
+ mpz_clear (op2_size);
+
+ if (t == FAILURE)
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Given an assignable expression and an arbitrary expression, make
+ sure that the assignment can take place. */
+
+try
+gfc_check_assign (gfc_expr * lvalue, gfc_expr * rvalue, int conform)
+{
+ gfc_symbol *sym;
+
+ sym = lvalue->symtree->n.sym;
+
+ if (sym->attr.intent == INTENT_IN)
+ {
+ gfc_error ("Can't assign to INTENT(IN) variable '%s' at %L",
+ sym->name, &lvalue->where);
+ return FAILURE;
+ }
+
+ if (rvalue->rank != 0 && lvalue->rank != rvalue->rank)
+ {
+ gfc_error ("Incompatible ranks in assignment at %L", &lvalue->where);
+ return FAILURE;
+ }
+
+ if (lvalue->ts.type == BT_UNKNOWN)
+ {
+ gfc_error ("Variable type is UNKNOWN in assignment at %L",
+ &lvalue->where);
+ return FAILURE;
+ }
+
+ /* Check size of array assignments. */
+ if (lvalue->rank != 0 && rvalue->rank != 0
+ && gfc_check_conformance ("Array assignment", lvalue, rvalue) != SUCCESS)
+ return FAILURE;
+
+ if (gfc_compare_types (&lvalue->ts, &rvalue->ts))
+ return SUCCESS;
+
+ if (!conform)
+ {
+ if (gfc_numeric_ts (&lvalue->ts) && gfc_numeric_ts (&rvalue->ts))
+ return SUCCESS;
+
+ gfc_error ("Incompatible types in assignment at %L, %s to %s",
+ &rvalue->where, gfc_typename (&rvalue->ts),
+ gfc_typename (&lvalue->ts));
+
+ return FAILURE;
+ }
+
+ return gfc_convert_type (rvalue, &lvalue->ts, 1);
+}
+
+
+/* Check that a pointer assignment is OK. We first check lvalue, and
+ we only check rvalue if it's not an assignment to NULL() or a
+ NULLIFY statement. */
+
+try
+gfc_check_pointer_assign (gfc_expr * lvalue, gfc_expr * rvalue)
+{
+ symbol_attribute attr;
+ int is_pure;
+
+ if (lvalue->symtree->n.sym->ts.type == BT_UNKNOWN)
+ {
+ gfc_error ("Pointer assignment target is not a POINTER at %L",
+ &lvalue->where);
+ return FAILURE;
+ }
+
+ attr = gfc_variable_attr (lvalue, NULL);
+ if (!attr.pointer)
+ {
+ gfc_error ("Pointer assignment to non-POINTER at %L", &lvalue->where);
+ return FAILURE;
+ }
+
+ is_pure = gfc_pure (NULL);
+
+ if (is_pure && gfc_impure_variable (lvalue->symtree->n.sym))
+ {
+ gfc_error ("Bad pointer object in PURE procedure at %L",
+ &lvalue->where);
+ return FAILURE;
+ }
+
+ /* If rvalue is a NULL() or NULLIFY, we're done. Otherwise the type,
+ kind, etc for lvalue and rvalue must match, and rvalue must be a
+ pure variable if we're in a pure function. */
+ if (rvalue->expr_type != EXPR_NULL)
+ {
+
+ if (!gfc_compare_types (&lvalue->ts, &rvalue->ts))
+ {
+ gfc_error ("Different types in pointer assignment at %L",
+ &lvalue->where);
+ return FAILURE;
+ }
+
+ if (lvalue->ts.kind != rvalue->ts.kind)
+ {
+ gfc_error
+ ("Different kind type parameters in pointer assignment at %L",
+ &lvalue->where);
+ return FAILURE;
+ }
+
+ attr = gfc_expr_attr (rvalue);
+ if (!attr.target && !attr.pointer)
+ {
+ gfc_error
+ ("Pointer assignment target is neither TARGET nor POINTER at "
+ "%L", &rvalue->where);
+ return FAILURE;
+ }
+
+ if (is_pure && gfc_impure_variable (rvalue->symtree->n.sym))
+ {
+ gfc_error
+ ("Bad target in pointer assignment in PURE procedure at %L",
+ &rvalue->where);
+ }
+ }
+
+ return SUCCESS;
+}
+
+
+/* Relative of gfc_check_assign() except that the lvalue is a single
+ symbol. */
+
+try
+gfc_check_assign_symbol (gfc_symbol * sym, gfc_expr * rvalue)
+{
+ gfc_expr lvalue;
+ try r;
+
+ memset (&lvalue, '\0', sizeof (gfc_expr));
+
+ lvalue.expr_type = EXPR_VARIABLE;
+ lvalue.ts = sym->ts;
+ if (sym->as)
+ lvalue.rank = sym->as->rank;
+ lvalue.symtree = (gfc_symtree *)gfc_getmem (sizeof (gfc_symtree));
+ lvalue.symtree->n.sym = sym;
+ lvalue.where = sym->declared_at;
+
+ r = gfc_check_assign (&lvalue, rvalue, 1);
+
+ gfc_free (lvalue.symtree);
+
+ return r;
+}
diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
new file mode 100644
index 00000000000..e4563d73fab
--- /dev/null
+++ b/gcc/fortran/f95-lang.c
@@ -0,0 +1,839 @@
+/* G95 Backend interface
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation,
+ Inc.
+ Contributed by Paul Brook.
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* f95-lang.c-- GCC backend interface stuff */
+
+/* declare required prototypes: */
+
+#include "config.h"
+#include "ansidecl.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "tree-gimple.h"
+#include "flags.h"
+#include "langhooks.h"
+#include "langhooks-def.h"
+#include "timevar.h"
+#include "tm.h"
+#include "function.h"
+#include "ggc.h"
+#include "toplev.h"
+#include "target.h"
+#include "debug.h"
+#include "diagnostic.h"
+#include "tree-dump.h"
+#include "cgraph.h"
+
+#include "gfortran.h"
+#include "trans.h"
+#include "trans-types.h"
+#include "trans-const.h"
+
+#include <assert.h>
+#include <stdio.h>
+
+/* Language-dependent contents of an identifier. */
+
+struct lang_identifier
+GTY(())
+{
+ struct tree_identifier common;
+};
+
+/* The resulting tree type. */
+
+union lang_tree_node
+GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE")))
+{
+ union tree_node GTY((tag ("0"),
+ desc ("tree_node_structure (&%h)"))) generic;
+ struct lang_identifier GTY((tag ("1"))) identifier;
+};
+
+/* Save and restore the variables in this file and elsewhere
+ that keep track of the progress of compilation of the current function.
+ Used for nested functions. */
+
+struct language_function
+GTY(())
+{
+ /* struct gfc_language_function base; */
+ tree named_labels;
+ tree shadowed_labels;
+ int returns_value;
+ int returns_abnormally;
+ int warn_about_return_type;
+ int extern_inline;
+ struct binding_level *binding_level;
+};
+
+/* We don't have a lex/yacc lexer/parser, but toplev expects these to
+ exist anyway. */
+void yyerror (const char *str);
+int yylex (void);
+
+static void gfc_init_decl_processing (void);
+static void gfc_init_builtin_functions (void);
+
+/* Each front end provides its own. */
+static bool gfc_init (void);
+static void gfc_finish (void);
+static void gfc_print_identifier (FILE *, tree, int);
+static bool gfc_mark_addressable (tree);
+void do_function_end (void);
+int global_bindings_p (void);
+void insert_block (tree);
+void set_block (tree);
+static void gfc_be_parse_file (int);
+static void gfc_expand_function (tree);
+
+#undef LANG_HOOKS_NAME
+#undef LANG_HOOKS_INIT
+#undef LANG_HOOKS_FINISH
+#undef LANG_HOOKS_INIT_OPTIONS
+#undef LANG_HOOKS_HANDLE_OPTION
+#undef LANG_HOOKS_POST_OPTIONS
+#undef LANG_HOOKS_PRINT_IDENTIFIER
+#undef LANG_HOOKS_PARSE_FILE
+#undef LANG_HOOKS_TRUTHVALUE_CONVERSION
+#undef LANG_HOOKS_MARK_ADDRESSABLE
+#undef LANG_HOOKS_TYPE_FOR_MODE
+#undef LANG_HOOKS_TYPE_FOR_SIZE
+#undef LANG_HOOKS_UNSIGNED_TYPE
+#undef LANG_HOOKS_SIGNED_TYPE
+#undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
+#undef LANG_HOOKS_GIMPLE_BEFORE_INLINING
+#undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
+
+/* Define lang hooks. */
+#define LANG_HOOKS_NAME "GNU F95"
+#define LANG_HOOKS_INIT gfc_init
+#define LANG_HOOKS_FINISH gfc_finish
+#define LANG_HOOKS_INIT_OPTIONS gfc_init_options
+#define LANG_HOOKS_HANDLE_OPTION gfc_handle_option
+#define LANG_HOOKS_POST_OPTIONS gfc_post_options
+#define LANG_HOOKS_PRINT_IDENTIFIER gfc_print_identifier
+#define LANG_HOOKS_PARSE_FILE gfc_be_parse_file
+#define LANG_HOOKS_TRUTHVALUE_CONVERSION gfc_truthvalue_conversion
+#define LANG_HOOKS_MARK_ADDRESSABLE gfc_mark_addressable
+#define LANG_HOOKS_TYPE_FOR_MODE gfc_type_for_mode
+#define LANG_HOOKS_TYPE_FOR_SIZE gfc_type_for_size
+#define LANG_HOOKS_UNSIGNED_TYPE gfc_unsigned_type
+#define LANG_HOOKS_SIGNED_TYPE gfc_signed_type
+#define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE gfc_signed_or_unsigned_type
+#define LANG_HOOKS_GIMPLE_BEFORE_INLINING false
+#define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION gfc_expand_function
+
+const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
+
+/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
+ that have names. Here so we can clear out their names' definitions
+ at the end of the function. */
+
+/* Tree code classes. */
+
+#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
+
+const char tree_code_type[] = {
+#include "tree.def"
+};
+#undef DEFTREECODE
+
+/* Table indexed by tree code giving number of expression
+ operands beyond the fixed part of the node structure.
+ Not used for types or decls. */
+
+#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
+
+const unsigned char tree_code_length[] = {
+#include "tree.def"
+};
+#undef DEFTREECODE
+
+/* Names of tree components.
+ Used for printing out the tree and error messages. */
+#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
+
+const char *const tree_code_name[] = {
+#include "tree.def"
+};
+#undef DEFTREECODE
+
+static tree named_labels;
+
+#define NULL_BINDING_LEVEL (struct binding_level *) NULL
+
+/* A chain of binding_level structures awaiting reuse. */
+
+static GTY(()) struct binding_level *free_binding_level;
+
+/* The elements of `ridpointers' are identifier nodes
+ for the reserved type names and storage classes.
+ It is indexed by a RID_... value. */
+tree *ridpointers = NULL;
+
+/* language-specific flags. */
+
+static void
+gfc_expand_function (tree fndecl)
+{
+ tree_rest_of_compilation (fndecl, 0);
+}
+
+
+/* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
+ or validate its data type for an `if' or `while' statement or ?..: exp.
+
+ This preparation consists of taking the ordinary
+ representation of an expression expr and producing a valid tree
+ boolean expression describing whether expr is nonzero. We could
+ simply always do build_binary_op (NE_EXPR, expr, boolean_false_node, 1),
+ but we optimize comparisons, &&, ||, and !.
+
+ The resulting type should always be `boolean_type_node'.
+ This is much simpler than the corresponding C version because we have a
+ distinct boolean type. */
+
+tree
+gfc_truthvalue_conversion (tree expr)
+{
+ switch (TREE_CODE (TREE_TYPE (expr)))
+ {
+ case BOOLEAN_TYPE:
+ if (TREE_TYPE (expr) == boolean_type_node)
+ return expr;
+ else if (TREE_CODE_CLASS (TREE_CODE (expr)) == '<')
+ {
+ TREE_TYPE (expr) = boolean_type_node;
+ return expr;
+ }
+ else if (TREE_CODE (expr) == NOP_EXPR)
+ return build1 (NOP_EXPR, boolean_type_node,
+ TREE_OPERAND (expr, 0));
+ else
+ return build1 (NOP_EXPR, boolean_type_node, expr);
+
+ case INTEGER_TYPE:
+ if (TREE_CODE (expr) == INTEGER_CST)
+ return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
+ else
+ return build (NE_EXPR, boolean_type_node, expr, integer_zero_node);
+
+ default:
+ internal_error ("Unexpected type in truthvalue_conversion");
+ }
+}
+
+static void
+gfc_create_decls (void)
+{
+ /* GCC builtins. */
+ gfc_init_builtin_functions ();
+
+ /* Runtime/IO library functions. */
+ gfc_build_builtin_function_decls ();
+
+ gfc_init_constants ();
+}
+
+static void
+gfc_be_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
+{
+ int errors;
+ int warnings;
+
+ gfc_create_decls ();
+ gfc_parse_file ();
+ gfc_generate_constructors ();
+
+ cgraph_finalize_compilation_unit ();
+ cgraph_optimize ();
+
+ /* Tell the frontent about any errors. */
+ gfc_get_errors (&warnings, &errors);
+ errorcount += errors;
+ warningcount += warnings;
+}
+
+/* Initialize everything. */
+
+static bool
+gfc_init (void)
+{
+ /* First initialize the backend. */
+ gfc_init_decl_processing ();
+ gfc_static_ctors = NULL_TREE;
+
+ /* Then the frontend. */
+ gfc_init_1 ();
+
+ if (gfc_new_file (gfc_option.source, gfc_option.source_form) != SUCCESS)
+ fatal_error ("can't open input file: %s", gfc_option.source);
+ return true;
+}
+
+
+static void
+gfc_finish (void)
+{
+ gfc_done_1 ();
+ gfc_release_include_path ();
+ return;
+}
+
+static void
+gfc_print_identifier (FILE * file ATTRIBUTE_UNUSED,
+ tree node ATTRIBUTE_UNUSED,
+ int indent ATTRIBUTE_UNUSED)
+{
+ return;
+}
+
+
+/* These functions and variables deal with binding contours. We only
+ need these functions for the list of PARM_DECLs, but we leave the
+ functions more general; these are a simplified version of the
+ functions from GNAT. */
+
+/* For each binding contour we allocate a binding_level structure which records
+ the entities defined or declared in that contour. Contours include:
+
+ the global one
+ one for each subprogram definition
+ one for each compound statement (declare block)
+
+ Binding contours are used to create GCC tree BLOCK nodes. */
+
+struct binding_level
+GTY(())
+{
+ /* A chain of ..._DECL nodes for all variables, constants, functions,
+ parameters and type declarations. These ..._DECL nodes are chained
+ through the TREE_CHAIN field. Note that these ..._DECL nodes are stored
+ in the reverse of the order supplied to be compatible with the
+ back-end. */
+ tree names;
+ /* For each level (except the global one), a chain of BLOCK nodes for all
+ the levels that were entered and exited one level down from this one. */
+ tree blocks;
+ /* The back end may need, for its own internal processing, to create a BLOCK
+ node. This field is set aside for this purpose. If this field is non-null
+ when the level is popped, i.e. when poplevel is invoked, we will use such
+ block instead of creating a new one from the 'names' field, that is the
+ ..._DECL nodes accumulated so far. Typically the routine 'pushlevel'
+ will be called before setting this field, so that if the front-end had
+ inserted ..._DECL nodes in the current block they will not be lost. */
+ tree block_created_by_back_end;
+ /* The binding level containing this one (the enclosing binding level). */
+ struct binding_level *level_chain;
+};
+
+/* The binding level currently in effect. */
+static GTY(()) struct binding_level *current_binding_level = NULL;
+
+/* The outermost binding level. This binding level is created when the
+ compiler is started and it will exist through the entire compilation. */
+static GTY(()) struct binding_level *global_binding_level;
+
+/* Binding level structures are initialized by copying this one. */
+static struct binding_level clear_binding_level = { NULL, NULL, NULL, NULL };
+
+/* Return non-zero if we are currently in the global binding level. */
+
+int
+global_bindings_p (void)
+{
+ return current_binding_level == global_binding_level ? -1 : 0;
+}
+
+tree
+getdecls (void)
+{
+ return current_binding_level->names;
+}
+
+/* Enter a new binding level. The input parameter is ignored, but has to be
+ specified for back-end compatibility. */
+
+void
+pushlevel (int ignore ATTRIBUTE_UNUSED)
+{
+ struct binding_level *newlevel
+ = (struct binding_level *) ggc_alloc (sizeof (struct binding_level));
+
+ *newlevel = clear_binding_level;
+
+ /* Add this level to the front of the chain (stack) of levels that are
+ active. */
+ newlevel->level_chain = current_binding_level;
+ current_binding_level = newlevel;
+}
+
+/* Exit a binding level.
+ Pop the level off, and restore the state of the identifier-decl mappings
+ that were in effect when this level was entered.
+
+ If KEEP is nonzero, this level had explicit declarations, so
+ and create a "block" (a BLOCK node) for the level
+ to record its declarations and subblocks for symbol table output.
+
+ If FUNCTIONBODY is nonzero, this level is the body of a function,
+ so create a block as if KEEP were set and also clear out all
+ label names.
+
+ If REVERSE is nonzero, reverse the order of decls before putting
+ them into the BLOCK. */
+
+tree
+poplevel (int keep, int reverse, int functionbody)
+{
+ /* Points to a BLOCK tree node. This is the BLOCK node construted for the
+ binding level that we are about to exit and which is returned by this
+ routine. */
+ tree block_node = NULL_TREE;
+ tree decl_chain;
+ tree subblock_chain = current_binding_level->blocks;
+ tree subblock_node;
+ tree block_created_by_back_end;
+
+ /* Reverse the list of XXXX_DECL nodes if desired. Note that the ..._DECL
+ nodes chained through the `names' field of current_binding_level are in
+ reverse order except for PARM_DECL node, which are explicitely stored in
+ the right order. */
+ decl_chain = (reverse) ? nreverse (current_binding_level->names)
+ : current_binding_level->names;
+
+ block_created_by_back_end =
+ current_binding_level->block_created_by_back_end;
+ if (block_created_by_back_end != 0)
+ {
+ block_node = block_created_by_back_end;
+
+ /* Check if we are about to discard some information that was gathered
+ by the front-end. Nameley check if the back-end created a new block
+ without calling pushlevel first. To understand why things are lost
+ just look at the next case (i.e. no block created by back-end. */
+ if ((keep || functionbody) && (decl_chain || subblock_chain))
+ abort ();
+ }
+
+ /* If there were any declarations in the current binding level, or if this
+ binding level is a function body, or if there are any nested blocks then
+ create a BLOCK node to record them for the life of this function. */
+ else if (keep || functionbody)
+ block_node = build_block (keep ? decl_chain : 0, 0, subblock_chain, 0, 0);
+
+ /* Record the BLOCK node just built as the subblock its enclosing scope. */
+ for (subblock_node = subblock_chain; subblock_node;
+ subblock_node = TREE_CHAIN (subblock_node))
+ BLOCK_SUPERCONTEXT (subblock_node) = block_node;
+
+ /* Clear out the meanings of the local variables of this level. */
+
+ for (subblock_node = decl_chain; subblock_node;
+ subblock_node = TREE_CHAIN (subblock_node))
+ if (DECL_NAME (subblock_node) != 0)
+ /* If the identifier was used or addressed via a local extern decl,
+ don't forget that fact. */
+ if (DECL_EXTERNAL (subblock_node))
+ {
+ if (TREE_USED (subblock_node))
+ TREE_USED (DECL_NAME (subblock_node)) = 1;
+ if (TREE_ADDRESSABLE (subblock_node))
+ TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (subblock_node)) = 1;
+ }
+
+ /* Pop the current level. */
+ current_binding_level = current_binding_level->level_chain;
+
+ if (functionbody)
+ {
+ /* This is the top level block of a function. The ..._DECL chain stored
+ in BLOCK_VARS are the function's parameters (PARM_DECL nodes). Don't
+ leave them in the BLOCK because they are found in the FUNCTION_DECL
+ instead. */
+ DECL_INITIAL (current_function_decl) = block_node;
+ BLOCK_VARS (block_node) = 0;
+ }
+ else if (block_node)
+ {
+ if (block_created_by_back_end == NULL)
+ current_binding_level->blocks
+ = chainon (current_binding_level->blocks, block_node);
+ }
+
+ /* If we did not make a block for the level just exited, any blocks made for
+ inner levels (since they cannot be recorded as subblocks in that level)
+ must be carried forward so they will later become subblocks of something
+ else. */
+ else if (subblock_chain)
+ current_binding_level->blocks
+ = chainon (current_binding_level->blocks, subblock_chain);
+ if (block_node)
+ TREE_USED (block_node) = 1;
+
+ return block_node;
+}
+
+/* Insert BLOCK at the end of the list of subblocks of the
+ current binding level. This is used when a BIND_EXPR is expanded,
+ to handle the BLOCK node inside the BIND_EXPR. */
+
+void
+insert_block (tree block)
+{
+ TREE_USED (block) = 1;
+ current_binding_level->blocks
+ = chainon (current_binding_level->blocks, block);
+}
+
+/* Set the BLOCK node for the innermost scope
+ (the one we are currently in). */
+
+void
+set_block (tree block)
+{
+ current_binding_level->block_created_by_back_end = block;
+}
+
+/* Records a ..._DECL node DECL as belonging to the current lexical scope.
+ Returns the ..._DECL node. */
+
+tree
+pushdecl (tree decl)
+{
+ /* External objects aren't nested, other objects may be. */
+ if ((DECL_EXTERNAL (decl)) || (decl == current_function_decl))
+ DECL_CONTEXT (decl) = 0;
+ else
+ DECL_CONTEXT (decl) = current_function_decl;
+
+ /* Put the declaration on the list. The list of declarations is in reverse
+ order. The list will be reversed later if necessary. This needs to be
+ this way for compatibility with the back-end. */
+
+ TREE_CHAIN (decl) = current_binding_level->names;
+ current_binding_level->names = decl;
+
+ /* For the declartion of a type, set its name if it is not already set. */
+
+ if (TREE_CODE (decl) == TYPE_DECL && TYPE_NAME (TREE_TYPE (decl)) == 0)
+ {
+ if (DECL_SOURCE_LINE (decl) == 0)
+ TYPE_NAME (TREE_TYPE (decl)) = decl;
+ else
+ TYPE_NAME (TREE_TYPE (decl)) = DECL_NAME (decl);
+ }
+
+ return decl;
+}
+
+
+/* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL. */
+
+tree
+pushdecl_top_level (tree x)
+{
+ tree t;
+ struct binding_level *b = current_binding_level;
+
+ current_binding_level = global_binding_level;
+ t = pushdecl (x);
+ current_binding_level = b;
+ return t;
+}
+
+
+#ifndef CHAR_TYPE_SIZE
+#define CHAR_TYPE_SIZE BITS_PER_UNIT
+#endif
+
+#ifndef INT_TYPE_SIZE
+#define INT_TYPE_SIZE BITS_PER_WORD
+#endif
+
+#undef SIZE_TYPE
+#define SIZE_TYPE "long unsigned int"
+
+/* Create tree nodes for the basic scalar types of Fortran 95,
+ and some nodes representing standard constants (0, 1, (void *) 0).
+ Initialize the global binding level.
+ Make definitions for built-in primitive functions. */
+static void
+gfc_init_decl_processing (void)
+{
+ current_function_decl = NULL;
+ named_labels = NULL;
+ current_binding_level = NULL_BINDING_LEVEL;
+ free_binding_level = NULL_BINDING_LEVEL;
+
+ /* Make the binding_level structure for global names. We move all
+ variables that are in a COMMON block to this binding level. */
+ pushlevel (0);
+ global_binding_level = current_binding_level;
+
+ /* Build common tree nodes. char_type_node is unsigned because we
+ only use it for actual characters, not for INTEGER(1). Also, we
+ want double_type_node to actually have double precision. */
+ build_common_tree_nodes (0);
+ set_sizetype (long_unsigned_type_node);
+ build_common_tree_nodes_2 (0);
+
+ /* Set up F95 type nodes. */
+ gfc_init_types ();
+}
+
+/* Mark EXP saying that we need to be able to take the
+ address of it; it should not be allocated in a register.
+ In Fortran 95 this is only the case for variables with
+ the TARGET attribute, but we implement it here for a
+ likely future Cray pointer extension.
+ Value is 1 if successful. */
+/* TODO: Check/fix mark_addressable. */
+bool
+gfc_mark_addressable (tree exp)
+{
+ register tree x = exp;
+ while (1)
+ switch (TREE_CODE (x))
+ {
+ case COMPONENT_REF:
+ case ADDR_EXPR:
+ case ARRAY_REF:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ x = TREE_OPERAND (x, 0);
+ break;
+
+ case CONSTRUCTOR:
+ TREE_ADDRESSABLE (x) = 1;
+ return true;
+
+ case VAR_DECL:
+ case CONST_DECL:
+ case PARM_DECL:
+ case RESULT_DECL:
+ if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x) && DECL_NONLOCAL (x))
+ {
+ if (TREE_PUBLIC (x))
+ {
+ error
+ ("global register variable `%s' used in nested function",
+ IDENTIFIER_POINTER (DECL_NAME (x)));
+ return false;
+ }
+ pedwarn ("register variable `%s' used in nested function",
+ IDENTIFIER_POINTER (DECL_NAME (x)));
+ }
+ else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
+ {
+ if (TREE_PUBLIC (x))
+ {
+ error ("address of global register variable `%s' requested",
+ IDENTIFIER_POINTER (DECL_NAME (x)));
+ return true;
+ }
+
+#if 0
+ /* If we are making this addressable due to its having
+ volatile components, give a different error message. Also
+ handle the case of an unnamed parameter by not trying
+ to give the name. */
+
+ else if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (x)))
+ {
+ error ("cannot put object with volatile field into register");
+ return false;
+ }
+#endif
+
+ pedwarn ("address of register variable `%s' requested",
+ IDENTIFIER_POINTER (DECL_NAME (x)));
+ }
+ put_var_into_stack (x, /*rescan=*/true);
+
+ /* drops in */
+ case FUNCTION_DECL:
+ TREE_ADDRESSABLE (x) = 1;
+
+ default:
+ return true;
+ }
+}
+
+/* press the big red button - garbage (ggc) collection is on */
+
+int ggc_p = 1;
+
+/* Builtin function initialisation. */
+
+/* Return a definition for a builtin function named NAME and whose data type
+ is TYPE. TYPE should be a function type with argument types.
+ FUNCTION_CODE tells later passes how to compile calls to this function.
+ See tree.h for its possible values.
+
+ If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
+ the name to be called if we can't opencode the function. If
+ ATTRS is nonzero, use that for the function's attribute list. */
+
+tree
+builtin_function (const char *name,
+ tree type,
+ int function_code,
+ enum built_in_class class,
+ const char *library_name,
+ tree attrs ATTRIBUTE_UNUSED)
+{
+ tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
+ DECL_EXTERNAL (decl) = 1;
+ TREE_PUBLIC (decl) = 1;
+ if (library_name)
+ SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
+ make_decl_rtl (decl, NULL);
+ pushdecl (decl);
+ DECL_BUILT_IN_CLASS (decl) = class;
+ DECL_FUNCTION_CODE (decl) = function_code;
+ return decl;
+}
+
+
+static void
+gfc_define_builtin (const char * name,
+ tree type,
+ int code,
+ const char * library_name,
+ bool const_p)
+{
+ tree decl;
+
+ decl = builtin_function (name, type, code, BUILT_IN_NORMAL,
+ library_name, NULL_TREE);
+ if (const_p)
+ TREE_READONLY (decl) = 1;
+
+ built_in_decls[code] = decl;
+ implicit_built_in_decls[code] = decl;
+}
+
+
+#define DEFINE_MATH_BUILTIN(code, name, nargs) \
+ gfc_define_builtin ("__builtin_" name, mfunc_double[nargs-1], \
+ BUILT_IN_ ## code, name, true); \
+ gfc_define_builtin ("__builtin_" name "f", mfunc_float[nargs-1], \
+ BUILT_IN_ ## code ## F, name "f", true);
+
+/* Initialisation of builtin function nodes. */
+static void
+gfc_init_builtin_functions (void)
+{
+ tree mfunc_float[2];
+ tree mfunc_double[2];
+ tree ftype;
+ tree tmp;
+ tree voidchain;
+
+ voidchain = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
+
+ tmp = tree_cons (NULL_TREE, float_type_node, voidchain);
+ mfunc_float[0] = build_function_type (float_type_node, tmp);
+ tmp = tree_cons (NULL_TREE, float_type_node, tmp);
+ mfunc_float[1] = build_function_type (float_type_node, tmp);
+
+ tmp = tree_cons (NULL_TREE, double_type_node, voidchain);
+ mfunc_double[0] = build_function_type (double_type_node, tmp);
+ tmp = tree_cons (NULL_TREE, double_type_node, tmp);
+ mfunc_double[1] = build_function_type (double_type_node, tmp);
+
+#include "mathbuiltins.def"
+
+ /* We define these seperately as the fortran versions have different
+ semantics (they return an integer type) */
+ gfc_define_builtin ("__builtin_floor", mfunc_double[0],
+ BUILT_IN_FLOOR, "floor", true);
+ gfc_define_builtin ("__builtin_floorf", mfunc_float[0],
+ BUILT_IN_FLOORF, "floorf", true);
+ gfc_define_builtin ("__builtin_round", mfunc_double[0],
+ BUILT_IN_ROUND, "round", true);
+ gfc_define_builtin ("__builtin_roundf", mfunc_float[0],
+ BUILT_IN_ROUNDF, "roundf", true);
+
+ /* Other builtin functions we use. */
+
+ tmp = tree_cons (NULL_TREE, long_integer_type_node, voidchain);
+ tmp = tree_cons (NULL_TREE, long_integer_type_node, tmp);
+ ftype = build_function_type (long_integer_type_node, tmp);
+ gfc_define_builtin ("__builtin_expect", ftype, BUILT_IN_EXPECT,
+ "__builtin_expect", true);
+
+ tmp = tree_cons (NULL_TREE, size_type_node, voidchain);
+ tmp = tree_cons (NULL_TREE, pvoid_type_node, tmp);
+ tmp = tree_cons (NULL_TREE, pvoid_type_node, tmp);
+ ftype = build_function_type (pvoid_type_node, tmp);
+ gfc_define_builtin ("__builtin_memcpy", ftype, BUILT_IN_MEMCPY,
+ "memcpy", false);
+
+ tmp = tree_cons (NULL_TREE, integer_type_node, voidchain);
+ ftype = build_function_type (integer_type_node, tmp);
+ gfc_define_builtin ("__builtin_clz", ftype, BUILT_IN_CLZ, "clz", true);
+
+ tmp = tree_cons (NULL_TREE, long_integer_type_node, voidchain);
+ ftype = build_function_type (integer_type_node, tmp);
+ gfc_define_builtin ("__builtin_clzl", ftype, BUILT_IN_CLZL, "clzl", true);
+
+ tmp = tree_cons (NULL_TREE, long_long_integer_type_node, voidchain);
+ ftype = build_function_type (integer_type_node, tmp);
+ gfc_define_builtin ("__builtin_clzll", ftype, BUILT_IN_CLZLL, "clzll", true);
+
+ tmp = tree_cons (NULL_TREE, pvoid_type_node, voidchain);
+ tmp = tree_cons (NULL_TREE, pvoid_type_node, tmp);
+ tmp = tree_cons (NULL_TREE, pvoid_type_node, tmp);
+ ftype = build_function_type (void_type_node, tmp);
+ gfc_define_builtin ("__builtin_init_trampoline", ftype,
+ BUILT_IN_INIT_TRAMPOLINE, "init_trampoline", false);
+
+ tmp = tree_cons (NULL_TREE, pvoid_type_node, voidchain);
+ ftype = build_function_type (pvoid_type_node, tmp);
+ gfc_define_builtin ("__builtin_adjust_trampoline", ftype,
+ BUILT_IN_ADJUST_TRAMPOLINE, "adjust_trampoline", true);
+
+ tmp = tree_cons (NULL_TREE, pvoid_type_node, voidchain);
+ tmp = tree_cons (NULL_TREE, size_type_node, voidchain);
+ ftype = build_function_type (pvoid_type_node, tmp);
+ gfc_define_builtin ("__builtin_stack_alloc", ftype, BUILT_IN_STACK_ALLOC,
+ "stack_alloc", false);
+
+ /* The stack_save and stack_restore builtins aren't used directly. They
+ are inserted during gimplification to implement stack_alloc calls. */
+ ftype = build_function_type (pvoid_type_node, voidchain);
+ gfc_define_builtin ("__builtin_stack_save", ftype, BUILT_IN_STACK_SAVE,
+ "stack_save", false);
+ tmp = tree_cons (NULL_TREE, pvoid_type_node, voidchain);
+ ftype = build_function_type (void_type_node, tmp);
+ gfc_define_builtin ("__builtin_stack_restore", ftype, BUILT_IN_STACK_RESTORE,
+ "stack_restore", false);
+}
+
+#undef DEFINE_MATH_BUILTIN
+
+#include "gt-fortran-f95-lang.h"
+#include "gtype-fortran.h"
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
new file mode 100644
index 00000000000..627eb8df96b
--- /dev/null
+++ b/gcc/fortran/gfortran.h
@@ -0,0 +1,1652 @@
+/* gfortran header file
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation,
+ Inc.
+ Contributed by Andy Vaught
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#ifndef GCC_GFORTRAN_H
+#define GCC_GFORTRAN_H
+
+/* It's probably insane to have this large of a header file, but it
+ seemed like everything had to be recompiled anyway when a change
+ was made to a header file, and there were ordering issues with
+ multiple header files. Besides, Microsoft's winnt.h was 250k last
+ time I looked, so by comparison this is perfectly reasonable. */
+
+/* We need system.h for HOST_WIDE_INT. Including hwint.h by itself doesn't
+ seem to be sufficient on some systems. */
+#include "system.h"
+#include "coretypes.h"
+
+/* The following ifdefs are recommended by the autoconf documentation
+ for any code using alloca. */
+
+/* AIX requires this to be the first thing in the file. */
+#ifdef __GNUC__
+#else /* not __GNUC__ */
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#else /* do not HAVE_ALLOCA_H */
+#ifdef _AIX
+#pragma alloca
+#else
+#ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+#endif /* not predefined */
+#endif /* not _AIX */
+#endif /* do not HAVE_ALLOCA_H */
+#endif /* not __GNUC__ */
+
+
+#include <stdio.h> /* need FILE * here */
+
+/* Major control parameters. */
+
+#define GFC_VERSION "0.23"
+#define GFC_MAX_SYMBOL_LEN 63
+#define GFC_REAL_BITS 100 /* Number of bits in g95's floating point numbers. */
+#define GFC_MAX_LINE 132 /* Characters beyond this are not seen. */
+#define GFC_MAX_DIMENSIONS 7 /* Maximum dimensions in an array. */
+#define GFC_LETTERS 26 /* Number of letters in the alphabet. */
+#define MAX_ERROR_MESSAGE 1000 /* Maximum length of an error message. */
+
+#define free(x) Use_gfc_free_instead_of_free()
+#define gfc_is_whitespace(c) ((c==' ') || (c=='\t'))
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+/* Stringization. */
+#define stringize(x) expand_macro(x)
+#define expand_macro(x) # x
+
+/* For a the runtime library, a standard prefix is a requirement to
+ avoid cluttering the namespace with things nobody asked for. It's
+ ugly to look at and a pain to type when you add the prefix by hand,
+ so we hide it behind a macro. */
+#define PREFIX(x) "_gfortran_" x
+
+/* Macro to initialize an mstring structure. */
+#define minit(s, t) { s, NULL, t }
+
+/* Structure for storing strings to be matched by gfc_match_string. */
+typedef struct
+{
+ const char *string;
+ const char *mp;
+ int tag;
+}
+mstring;
+
+
+/* Flags to specify which standardi/extension contains a feature. */
+#define GFC_STD_GNU (1<<5) /* GNU Fortran extension. */
+#define GFC_STD_F2003 (1<<4) /* New in F2003. */
+#define GFC_STD_F2003_DEL (1<<3) /* Deleted in F2003. */
+#define GFC_STD_F2003_OBS (1<<2) /* Obsoleted in F2003. */
+#define GFC_STD_F95_DEL (1<<1) /* Deleted in F95. */
+#define GFC_STD_F95_OBS (1<<0) /* Obsoleted in F95. */
+
+/*************************** Enums *****************************/
+
+/* The author remains confused to this day about the convention of
+ returning '0' for 'SUCCESS'... or was it the other way around? The
+ following enum makes things much more readable. We also start
+ values off at one instead of zero. */
+
+typedef enum
+{ SUCCESS = 1, FAILURE }
+try;
+
+/* Matchers return one of these three values. The difference between
+ MATCH_NO and MATCH_ERROR is that MATCH_ERROR means that a match was
+ successful, but that something non-syntactic is wrong and an error
+ has already been issued. */
+
+typedef enum
+{ MATCH_NO = 1, MATCH_YES, MATCH_ERROR }
+match;
+
+typedef enum
+{ FORM_FREE, FORM_FIXED, FORM_UNKNOWN }
+gfc_source_form;
+
+typedef enum
+{ BT_UNKNOWN = 1, BT_INTEGER, BT_REAL, BT_COMPLEX,
+ BT_LOGICAL, BT_CHARACTER, BT_DERIVED, BT_PROCEDURE
+}
+bt;
+
+/* Expression node types. */
+typedef enum
+{ EXPR_OP = 1, EXPR_FUNCTION, EXPR_CONSTANT, EXPR_VARIABLE,
+ EXPR_SUBSTRING, EXPR_STRUCTURE, EXPR_ARRAY, EXPR_NULL
+}
+expr_t;
+
+/* Array types. */
+typedef enum
+{ AS_EXPLICIT = 1, AS_ASSUMED_SHAPE, AS_DEFERRED,
+ AS_ASSUMED_SIZE, AS_UNKNOWN
+}
+array_type;
+
+typedef enum
+{ AR_FULL = 1, AR_ELEMENT, AR_SECTION, AR_UNKNOWN }
+ar_type;
+
+/* Statement label types. */
+typedef enum
+{ ST_LABEL_UNKNOWN = 1, ST_LABEL_TARGET,
+ ST_LABEL_BAD_TARGET, ST_LABEL_FORMAT
+}
+gfc_sl_type;
+
+/* Intrinsic operators. */
+typedef enum
+{ GFC_INTRINSIC_BEGIN = 0,
+ INTRINSIC_NONE = -1, INTRINSIC_UPLUS = GFC_INTRINSIC_BEGIN,
+ INTRINSIC_UMINUS, INTRINSIC_PLUS, INTRINSIC_MINUS, INTRINSIC_TIMES,
+ INTRINSIC_DIVIDE, INTRINSIC_POWER, INTRINSIC_CONCAT,
+ INTRINSIC_AND, INTRINSIC_OR, INTRINSIC_EQV, INTRINSIC_NEQV,
+ INTRINSIC_EQ, INTRINSIC_NE, INTRINSIC_GT, INTRINSIC_GE,
+ INTRINSIC_LT, INTRINSIC_LE, INTRINSIC_NOT, INTRINSIC_USER,
+ INTRINSIC_ASSIGN,
+ GFC_INTRINSIC_END /* Sentinel */
+}
+gfc_intrinsic_op;
+
+
+/* Strings for all intrinsic operators. */
+extern mstring intrinsic_operators[];
+
+
+/* This macro is the number of intrinsic operators that exist.
+ Assumptions are made about the numbering of the interface_op enums. */
+#define GFC_INTRINSIC_OPS GFC_INTRINSIC_END
+
+/* Arithmetic results. */
+typedef enum
+{ ARITH_OK = 1, ARITH_OVERFLOW, ARITH_UNDERFLOW,
+ ARITH_DIV0, ARITH_0TO0, ARITH_INCOMMENSURATE
+}
+arith;
+
+/* Statements. */
+typedef enum
+{
+ ST_ARITHMETIC_IF, ST_ALLOCATE, ST_ATTR_DECL, ST_BACKSPACE, ST_BLOCK_DATA,
+ ST_CALL, ST_CASE, ST_CLOSE, ST_COMMON, ST_CONTINUE, ST_CONTAINS, ST_CYCLE,
+ ST_DATA, ST_DATA_DECL, ST_DEALLOCATE, ST_DO, ST_ELSE, ST_ELSEIF,
+ ST_ELSEWHERE, ST_END_BLOCK_DATA, ST_ENDDO, ST_IMPLIED_ENDDO,
+ ST_END_FILE, ST_END_FORALL, ST_END_FUNCTION, ST_ENDIF, ST_END_INTERFACE,
+ ST_END_MODULE, ST_END_PROGRAM, ST_END_SELECT, ST_END_SUBROUTINE,
+ ST_END_WHERE, ST_END_TYPE, ST_ENTRY, ST_EQUIVALENCE, ST_EXIT, ST_FORALL,
+ ST_FORALL_BLOCK, ST_FORMAT, ST_FUNCTION, ST_GOTO, ST_IF_BLOCK, ST_IMPLICIT,
+ ST_IMPLICIT_NONE, ST_INQUIRE, ST_INTERFACE, ST_PARAMETER, ST_MODULE,
+ ST_MODULE_PROC, ST_NAMELIST, ST_NULLIFY, ST_OPEN, ST_PAUSE, ST_PRIVATE,
+ ST_PROGRAM, ST_PUBLIC, ST_READ, ST_RETURN, ST_REWIND, ST_STOP,
+ ST_SUBROUTINE,
+ ST_TYPE, ST_USE, ST_WHERE_BLOCK, ST_WHERE, ST_WRITE, ST_ASSIGNMENT,
+ ST_POINTER_ASSIGNMENT, ST_SELECT_CASE, ST_SEQUENCE, ST_SIMPLE_IF,
+ ST_STATEMENT_FUNCTION, ST_DERIVED_DECL, ST_LABEL_ASSIGNMENT, ST_NONE
+}
+gfc_statement;
+
+
+/* Types of interfaces that we can have. Assignment interfaces are
+ considered to be intrinsic operators. */
+typedef enum
+{
+ INTERFACE_NAMELESS = 1, INTERFACE_GENERIC,
+ INTERFACE_INTRINSIC_OP, INTERFACE_USER_OP
+}
+interface_type;
+
+/* Symbol flavors: these are all mutually exclusive.
+ 10 elements = 4 bits. */
+typedef enum
+{
+ FL_UNKNOWN = 0, FL_PROGRAM, FL_BLOCK_DATA, FL_MODULE, FL_VARIABLE,
+ FL_PARAMETER, FL_LABEL, FL_PROCEDURE, FL_DERIVED, FL_NAMELIST
+}
+sym_flavor;
+
+/* Procedure types. 7 elements = 3 bits. */
+typedef enum
+{ PROC_UNKNOWN, PROC_MODULE, PROC_INTERNAL, PROC_DUMMY,
+ PROC_INTRINSIC, PROC_ST_FUNCTION, PROC_EXTERNAL
+}
+procedure_type;
+
+/* Intent types. */
+typedef enum
+{ INTENT_UNKNOWN = 0, INTENT_IN, INTENT_OUT, INTENT_INOUT
+}
+sym_intent;
+
+/* Access types. */
+typedef enum
+{ ACCESS_PUBLIC = 1, ACCESS_PRIVATE, ACCESS_UNKNOWN
+}
+gfc_access;
+
+/* Flags to keep track of where an interface came from.
+ 4 elements = 2 bits. */
+typedef enum
+{ IFSRC_UNKNOWN = 0, IFSRC_DECL, IFSRC_IFBODY, IFSRC_USAGE
+}
+ifsrc;
+
+/* Strings for all symbol attributes. We use these for dumping the
+ parse tree, in error messages, and also when reading and writing
+ modules. In symbol.c. */
+extern const mstring flavors[];
+extern const mstring procedures[];
+extern const mstring intents[];
+extern const mstring access_types[];
+extern const mstring ifsrc_types[];
+
+/* Enumeration of all the generic intrinsic functions. Used by the
+ backend for identification of a function. */
+
+enum gfc_generic_isym_id
+{
+ /* GFC_ISYM_NONE is used for intrinsics which will never be seen by
+ the backend (eg. KIND). */
+ GFC_ISYM_NONE = 0,
+ GFC_ISYM_ABS,
+ GFC_ISYM_ACHAR,
+ GFC_ISYM_ACOS,
+ GFC_ISYM_ADJUSTL,
+ GFC_ISYM_ADJUSTR,
+ GFC_ISYM_AIMAG,
+ GFC_ISYM_AINT,
+ GFC_ISYM_ALL,
+ GFC_ISYM_ALLOCATED,
+ GFC_ISYM_ANINT,
+ GFC_ISYM_ANY,
+ GFC_ISYM_ASIN,
+ GFC_ISYM_ASSOCIATED,
+ GFC_ISYM_ATAN,
+ GFC_ISYM_ATAN2,
+ GFC_ISYM_BTEST,
+ GFC_ISYM_CEILING,
+ GFC_ISYM_CHAR,
+ GFC_ISYM_CMPLX,
+ GFC_ISYM_CONJG,
+ GFC_ISYM_COS,
+ GFC_ISYM_COSH,
+ GFC_ISYM_COUNT,
+ GFC_ISYM_CSHIFT,
+ GFC_ISYM_DBLE,
+ GFC_ISYM_DIM,
+ GFC_ISYM_DOT_PRODUCT,
+ GFC_ISYM_DPROD,
+ GFC_ISYM_EOSHIFT,
+ GFC_ISYM_EXP,
+ GFC_ISYM_EXPONENT,
+ GFC_ISYM_FLOOR,
+ GFC_ISYM_FRACTION,
+ GFC_ISYM_IACHAR,
+ GFC_ISYM_IAND,
+ GFC_ISYM_IBCLR,
+ GFC_ISYM_IBITS,
+ GFC_ISYM_IBSET,
+ GFC_ISYM_ICHAR,
+ GFC_ISYM_IEOR,
+ GFC_ISYM_INDEX,
+ GFC_ISYM_INT,
+ GFC_ISYM_IOR,
+ GFC_ISYM_ISHFT,
+ GFC_ISYM_ISHFTC,
+ GFC_ISYM_LBOUND,
+ GFC_ISYM_LEN,
+ GFC_ISYM_LEN_TRIM,
+ GFC_ISYM_LGE,
+ GFC_ISYM_LGT,
+ GFC_ISYM_LLE,
+ GFC_ISYM_LLT,
+ GFC_ISYM_LOG,
+ GFC_ISYM_LOG10,
+ GFC_ISYM_LOGICAL,
+ GFC_ISYM_MATMUL,
+ GFC_ISYM_MAX,
+ GFC_ISYM_MAXLOC,
+ GFC_ISYM_MAXVAL,
+ GFC_ISYM_MERGE,
+ GFC_ISYM_MIN,
+ GFC_ISYM_MINLOC,
+ GFC_ISYM_MINVAL,
+ GFC_ISYM_MOD,
+ GFC_ISYM_MODULO,
+ GFC_ISYM_NEAREST,
+ GFC_ISYM_NINT,
+ GFC_ISYM_NOT,
+ GFC_ISYM_PACK,
+ GFC_ISYM_PRESENT,
+ GFC_ISYM_PRODUCT,
+ GFC_ISYM_REAL,
+ GFC_ISYM_REPEAT,
+ GFC_ISYM_RESHAPE,
+ GFC_ISYM_RRSPACING,
+ GFC_ISYM_SCALE,
+ GFC_ISYM_SCAN,
+ GFC_ISYM_SET_EXPONENT,
+ GFC_ISYM_SHAPE,
+ GFC_ISYM_SI_KIND,
+ GFC_ISYM_SIGN,
+ GFC_ISYM_SIN,
+ GFC_ISYM_SINH,
+ GFC_ISYM_SIZE,
+ GFC_ISYM_SPACING,
+ GFC_ISYM_SPREAD,
+ GFC_ISYM_SQRT,
+ GFC_ISYM_SR_KIND,
+ GFC_ISYM_SUM,
+ GFC_ISYM_TAN,
+ GFC_ISYM_TANH,
+ GFC_ISYM_TRANSFER,
+ GFC_ISYM_TRANSPOSE,
+ GFC_ISYM_TRIM,
+ GFC_ISYM_UBOUND,
+ GFC_ISYM_UNPACK,
+ GFC_ISYM_VERIFY,
+ GFC_ISYM_CONVERSION
+};
+typedef enum gfc_generic_isym_id gfc_generic_isym_id;
+
+/************************* Structures *****************************/
+
+/* Symbol attribute structure. */
+typedef struct
+{
+ /* Variable attributes. */
+ unsigned allocatable:1, dimension:1, external:1, intrinsic:1,
+ optional:1, pointer:1, save:1, target:1,
+ dummy:1, common:1, result:1, entry:1, assign:1;
+
+ unsigned data:1, /* Symbol is named in a DATA statement. */
+ use_assoc:1; /* Symbol has been use-associated. */
+
+ unsigned in_namelist:1, in_common:1, saved_common:1;
+ unsigned function:1, subroutine:1, generic:1;
+ unsigned implicit_type:1; /* Type defined via implicit rules */
+
+ /* Function/subroutine attributes */
+ unsigned sequence:1, elemental:1, pure:1, recursive:1;
+ unsigned unmaskable:1, masked:1, contained:1;
+
+ /* Set if a function must always be referenced by an explicit interface. */
+ unsigned always_explicit:1;
+
+ /* Set if the symbol has been referenced in an expression. No further
+ modification of type or type parameters is permitted. */
+ unsigned referenced:1;
+
+ /* Mutually exclusive multibit attributes. */
+ gfc_access access:2;
+ sym_intent intent:2;
+ sym_flavor flavor:4;
+ ifsrc if_source:2;
+
+ procedure_type proc:3;
+
+}
+symbol_attribute;
+
+
+typedef struct
+{
+ char *nextc;
+ int line; /* line within the lp structure */
+ struct linebuf *lp;
+ struct gfc_file *file;
+}
+locus;
+
+/* The linebuf structure deserves some explanation. This is the
+ primary structure for holding lines. A source file is stored in a
+ singly linked list of these structures. Each structure holds an
+ integer number of lines. The line[] member is actually an array of
+ pointers that point to the NULL-terminated lines. This list grows
+ upwards, and the actual lines are stored at the top of the
+ structure and grow downward. Each structure is packed with as many
+ lines as it can hold, then another linebuf is allocated. */
+
+/* Chosen so that sizeof(linebuf) = 4096 on most machines */
+#define LINEBUF_SIZE 4080
+
+typedef struct linebuf
+{
+ int start_line, lines;
+ struct linebuf *next;
+ char *line[1];
+ char buf[LINEBUF_SIZE];
+}
+linebuf;
+
+
+#include <limits.h>
+#ifndef PATH_MAX
+# include <sys/param.h>
+# define PATH_MAX MAXPATHLEN
+#endif
+
+
+typedef struct gfc_file
+{
+ char filename[PATH_MAX + 1];
+ gfc_source_form form;
+ struct gfc_file *included_by, *next;
+ locus loc;
+ struct linebuf *start;
+}
+gfc_file;
+
+
+extern int gfc_suppress_error;
+
+
+/* Character length structures hold the expression that gives the
+ length of a character variable. We avoid putting these into
+ gfc_typespec because doing so prevents us from doing structure
+ copies and forces us to deallocate any typespecs we create, as well
+ as structures that contain typespecs. They also can have multiple
+ character typespecs pointing to them.
+
+ These structures form a singly linked list within the current
+ namespace and are deallocated with the namespace. It is possible to
+ end up with gfc_charlen structures that have nothing pointing to them. */
+
+typedef struct gfc_charlen
+{
+ struct gfc_expr *length;
+ struct gfc_charlen *next;
+ tree backend_decl;
+}
+gfc_charlen;
+
+#define gfc_get_charlen() gfc_getmem(sizeof(gfc_charlen))
+
+/* Type specification structure. FIXME: derived and cl could be union??? */
+typedef struct
+{
+ bt type;
+ int kind;
+ struct gfc_symbol *derived;
+ gfc_charlen *cl; /* For character types only. */
+}
+gfc_typespec;
+
+/* Array specification. */
+typedef struct
+{
+ int rank; /* A rank of zero means that a variable is a scalar. */
+ array_type type;
+ struct gfc_expr *lower[GFC_MAX_DIMENSIONS], *upper[GFC_MAX_DIMENSIONS];
+}
+gfc_array_spec;
+
+#define gfc_get_array_spec() gfc_getmem(sizeof(gfc_array_spec))
+
+
+/* Components of derived types. */
+typedef struct gfc_component
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_typespec ts;
+
+ int pointer, dimension;
+ gfc_array_spec *as;
+
+ tree backend_decl;
+ locus loc;
+ struct gfc_expr *initializer;
+ struct gfc_component *next;
+}
+gfc_component;
+
+#define gfc_get_component() gfc_getmem(sizeof(gfc_component))
+
+/* Formal argument lists are lists of symbols. */
+typedef struct gfc_formal_arglist
+{
+ struct gfc_symbol *sym;
+ struct gfc_formal_arglist *next;
+}
+gfc_formal_arglist;
+
+#define gfc_get_formal_arglist() gfc_getmem(sizeof(gfc_formal_arglist))
+
+
+/* The gfc_actual_arglist structure is for actual arguments. */
+typedef struct gfc_actual_arglist
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ /* Alternate return label when the expr member is null. */
+ struct gfc_st_label *label;
+
+ struct gfc_expr *expr;
+ struct gfc_actual_arglist *next;
+}
+gfc_actual_arglist;
+
+#define gfc_get_actual_arglist() gfc_getmem(sizeof(gfc_actual_arglist))
+
+
+/* Because a symbol can belong to multiple namelists, they must be
+ linked externally to the symbol itself. */
+typedef struct gfc_namelist
+{
+ struct gfc_symbol *sym;
+ struct gfc_namelist *next;
+}
+gfc_namelist;
+
+#define gfc_get_namelist() gfc_getmem(sizeof(gfc_namelist))
+
+
+/* The gfc_st_label structure is a doubly linked list attached to a
+ namespace that records the usage of statement labels within that
+ space. */
+/* TODO: Make format/statement specifics a union. */
+typedef struct gfc_st_label
+{
+ int value;
+
+ gfc_sl_type defined, referenced;
+
+ struct gfc_expr *format;
+
+ tree backend_decl;
+
+ locus where;
+
+ struct gfc_st_label *prev, *next;
+}
+gfc_st_label;
+
+
+/* gfc_interface()-- Interfaces are lists of symbols strung together. */
+typedef struct gfc_interface
+{
+ struct gfc_symbol *sym;
+ locus where;
+ struct gfc_interface *next;
+}
+gfc_interface;
+
+#define gfc_get_interface() gfc_getmem(sizeof(gfc_interface))
+
+
+/* User operator nodes. These are like stripped down symbols. */
+typedef struct
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+
+ gfc_interface *operator;
+ struct gfc_namespace *ns;
+ gfc_access access;
+}
+gfc_user_op;
+
+/* Symbol nodes. These are important things. They are what the
+ standard refers to as "entities". The possibly multiple names that
+ refer to the same entity are accomplished by a binary tree of
+ symtree structures that is balanced by the red-black method-- more
+ than one symtree node can point to any given symbol. */
+
+typedef struct gfc_symbol
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1]; /* Primary name, before renaming */
+ char module[GFC_MAX_SYMBOL_LEN + 1]; /* Module this symbol came from */
+ locus declared_at;
+
+ gfc_typespec ts;
+ symbol_attribute attr;
+
+ /* The interface member points to the formal argument list if the
+ symbol is a function or subroutine name. If the symbol is a
+ generic name, the generic member points to the list of
+ interfaces. */
+
+ gfc_interface *generic;
+ gfc_access component_access;
+
+ gfc_formal_arglist *formal;
+ struct gfc_namespace *formal_ns;
+
+ struct gfc_expr *value; /* Parameter/Initializer value */
+ gfc_array_spec *as;
+ struct gfc_symbol *result; /* function result symbol */
+ gfc_component *components; /* Derived type components */
+
+ /* TODO: These three fields are mutually exclusive. */
+ struct gfc_symbol *common_head, *common_next; /* Links for COMMON syms */
+ /* Make sure setup code for dummy arguments is generated in the correct
+ order. */
+ int dummy_order;
+
+ gfc_namelist *namelist, *namelist_tail;
+
+ /* Change management fields. Symbols that might be modified by the
+ current statement have the mark member nonzero and are kept in a
+ singly linked list through the tlink field. Of these symbols,
+ symbols with old_symbol equal to NULL are symbols created within
+ the current statement. Otherwise, old_symbol points to a copy of
+ the old symbol. */
+
+ struct gfc_symbol *old_symbol, *tlink;
+ unsigned mark:1, new:1;
+ int refs;
+ struct gfc_namespace *ns; /* namespace containing this symbol */
+
+ tree backend_decl;
+
+}
+gfc_symbol;
+
+
+/* Within a namespace, symbols are pointed to by symtree nodes that
+ are linked together in a balanced binary tree. There can be
+ several symtrees pointing to the same symbol node via USE
+ statements. */
+
+#define BBT_HEADER(self) int priority; struct self *left, *right
+
+typedef struct gfc_symtree
+{
+ BBT_HEADER (gfc_symtree);
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ int ambiguous;
+ union
+ {
+ gfc_symbol *sym; /* Symbol associated with this node */
+ gfc_user_op *uop;
+ }
+ n;
+
+}
+gfc_symtree;
+
+
+typedef struct gfc_namespace
+{
+ gfc_symtree *sym_root, *uop_root; /* Roots of the red/black symbol trees */
+
+ int set_flag[GFC_LETTERS];
+ gfc_typespec default_type[GFC_LETTERS]; /* IMPLICIT typespecs */
+
+ struct gfc_symbol *proc_name;
+ gfc_interface *operator[GFC_INTRINSIC_OPS];
+ struct gfc_namespace *parent, *contained, *sibling;
+ struct gfc_code *code;
+ gfc_symbol *blank_common;
+ struct gfc_equiv *equiv;
+ gfc_access default_access, operator_access[GFC_INTRINSIC_OPS];
+
+ gfc_st_label *st_labels;
+ struct gfc_data *data;
+
+ gfc_charlen *cl_list;
+
+ int save_all, seen_save;
+}
+gfc_namespace;
+
+extern gfc_namespace *gfc_current_ns;
+
+
+/* Information on interfaces being built. */
+typedef struct
+{
+ interface_type type;
+ gfc_symbol *sym;
+ gfc_namespace *ns;
+ gfc_user_op *uop;
+ gfc_intrinsic_op op;
+}
+gfc_interface_info;
+
+extern gfc_interface_info current_interface;
+
+
+/* Array reference. */
+typedef struct gfc_array_ref
+{
+ ar_type type;
+ int dimen; /* # of components in the reference */
+ locus where;
+ gfc_array_spec *as;
+
+ locus c_where[GFC_MAX_DIMENSIONS]; /* All expressions can be NULL */
+ struct gfc_expr *start[GFC_MAX_DIMENSIONS], *end[GFC_MAX_DIMENSIONS],
+ *stride[GFC_MAX_DIMENSIONS];
+
+ enum
+ { DIMEN_ELEMENT = 1, DIMEN_RANGE, DIMEN_VECTOR, DIMEN_UNKNOWN }
+ dimen_type[GFC_MAX_DIMENSIONS];
+
+ struct gfc_expr *offset;
+}
+gfc_array_ref;
+
+#define gfc_get_array_ref() gfc_getmem(sizeof(gfc_array_ref))
+
+
+/* Component reference nodes. A variable is stored as an expression
+ node that points to the base symbol. After that, a singly linked
+ list of component reference nodes gives the variable's complete
+ resolution. The array_ref component may be present and comes
+ before the component component. */
+
+typedef enum
+ { REF_ARRAY, REF_COMPONENT, REF_SUBSTRING }
+ref_type;
+
+typedef struct gfc_ref
+{
+ ref_type type;
+
+ union
+ {
+ struct gfc_array_ref ar;
+
+ struct
+ {
+ gfc_component *component;
+ gfc_symbol *sym;
+ }
+ c;
+
+ struct
+ {
+ struct gfc_expr *start, *end; /* Substring */
+ gfc_charlen *length;
+ }
+ ss;
+
+ }
+ u;
+
+ struct gfc_ref *next;
+}
+gfc_ref;
+
+#define gfc_get_ref() gfc_getmem(sizeof(gfc_ref))
+
+
+/* Structures representing intrinsic symbols and their arguments lists. */
+typedef struct gfc_intrinsic_arg
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+
+ gfc_typespec ts;
+ int optional;
+ gfc_actual_arglist *actual;
+
+ struct gfc_intrinsic_arg *next;
+
+}
+gfc_intrinsic_arg;
+
+
+typedef union
+{
+ try (*f1)(struct gfc_expr *);
+ try (*f1m)(gfc_actual_arglist *);
+ try (*f2)(struct gfc_expr *, struct gfc_expr *);
+ try (*f3)(struct gfc_expr *, struct gfc_expr *, struct gfc_expr *);
+ try (*f4)(struct gfc_expr *, struct gfc_expr *, struct gfc_expr *,
+ struct gfc_expr *);
+ try (*f5)(struct gfc_expr *, struct gfc_expr *, struct gfc_expr *,
+ struct gfc_expr *, struct gfc_expr *);
+}
+gfc_check_f;
+
+
+typedef union
+{
+ struct gfc_expr *(*f1)(struct gfc_expr *);
+ struct gfc_expr *(*f2)(struct gfc_expr *, struct gfc_expr *);
+ struct gfc_expr *(*f3)(struct gfc_expr *, struct gfc_expr *,
+ struct gfc_expr *);
+ struct gfc_expr *(*f4)(struct gfc_expr *, struct gfc_expr *,
+ struct gfc_expr *, struct gfc_expr *);
+ struct gfc_expr *(*f5)(struct gfc_expr *, struct gfc_expr *,
+ struct gfc_expr *, struct gfc_expr *,
+ struct gfc_expr *);
+ struct gfc_expr *(*cc)(struct gfc_expr *, bt, int);
+}
+gfc_simplify_f;
+
+
+typedef union
+{
+ void (*f0)(struct gfc_expr *);
+ void (*f1)(struct gfc_expr *, struct gfc_expr *);
+ void (*f1m)(struct gfc_expr *, struct gfc_actual_arglist *);
+ void (*f2)(struct gfc_expr *, struct gfc_expr *, struct gfc_expr *);
+ void (*f3)(struct gfc_expr *, struct gfc_expr *, struct gfc_expr *,
+ struct gfc_expr *);
+ void (*f4)(struct gfc_expr *, struct gfc_expr *, struct gfc_expr *,
+ struct gfc_expr *, struct gfc_expr *);
+ void (*f5)(struct gfc_expr *, struct gfc_expr *, struct gfc_expr *,
+ struct gfc_expr *, struct gfc_expr *, struct gfc_expr *);
+ void (*s1)(struct gfc_code *);
+}
+gfc_resolve_f;
+
+
+typedef struct gfc_intrinsic_sym
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1], lib_name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_intrinsic_arg *formal;
+ gfc_typespec ts;
+ int elemental, pure, generic, specific, actual_ok;
+
+ gfc_simplify_f simplify;
+ gfc_check_f check;
+ gfc_resolve_f resolve;
+ struct gfc_intrinsic_sym *specific_head, *next;
+ gfc_generic_isym_id generic_id;
+
+}
+gfc_intrinsic_sym;
+
+
+/* Expression nodes. The expression node types deserve explanations,
+ since the last couple can be easily misconstrued:
+
+ EXPR_OP Operator node pointing to one or two other nodes
+ EXPR_FUNCTION Function call, symbol points to function's name
+ EXPR_CONSTANT A scalar constant: Logical, String, Real, Int or Complex
+ EXPR_VARIABLE An Lvalue with a root symbol and possible reference list
+ which expresses structure, array and substring refs.
+ EXPR_NULL The NULL pointer value (which also has a basic type).
+ EXPR_SUBSTRING A substring of a constant string
+ EXPR_STRUCTURE A structure constructor
+ EXPR_ARRAY An array constructor. */
+
+#include <gmp.h>
+
+typedef struct gfc_expr
+{
+ expr_t expr_type;
+
+ gfc_typespec ts; /* These two refer to the overall expression */
+
+ int rank;
+ mpz_t *shape; /* Can be NULL if shape is unknown at compile time */
+
+ gfc_intrinsic_op operator;
+
+ /* Nonnull for functions and structure constructors */
+ gfc_symtree *symtree;
+
+ gfc_user_op *uop;
+ gfc_ref *ref;
+
+ struct gfc_expr *op1, *op2;
+ locus where;
+
+ union
+ {
+ mpz_t integer;
+ mpf_t real;
+ int logical;
+
+ struct
+ {
+ mpf_t r, i;
+ }
+ complex;
+
+ struct
+ {
+ gfc_actual_arglist *actual;
+ char *name; /* Points to the ultimate name of the function */
+ gfc_intrinsic_sym *isym;
+ gfc_symbol *esym;
+ }
+ function;
+
+ struct
+ {
+ int length;
+ char *string;
+ }
+ character;
+
+ struct gfc_constructor *constructor;
+ }
+ value;
+
+}
+gfc_expr;
+
+
+#define gfc_get_shape(rank) ((mpz_t *) gfc_getmem(rank*sizeof(mpz_t)))
+
+/* Structures for information associated with different kinds of
+ numbers. The first set of integer parameters define all there is
+ to know about a particular kind. The rest of the elements are
+ computed from the first elements. */
+
+typedef struct
+{
+ int kind, radix, digits, bit_size;
+
+ int range;
+ mpz_t huge;
+
+ mpz_t min_int, max_int; /* Values really representable by the target */
+}
+gfc_integer_info;
+
+extern gfc_integer_info gfc_integer_kinds[];
+
+
+typedef struct
+{
+ int kind, bit_size;
+
+}
+gfc_logical_info;
+
+extern gfc_logical_info gfc_logical_kinds[];
+
+
+typedef struct
+{
+ int kind, radix, digits, min_exponent, max_exponent;
+
+ int range, precision;
+ mpf_t epsilon, huge, tiny;
+}
+gfc_real_info;
+
+extern gfc_real_info gfc_real_kinds[];
+
+
+/* Equivalence structures. Equivalent lvalues are linked along the
+ *eq pointer, equivalence sets are strung along the *next node. */
+typedef struct gfc_equiv
+{
+ struct gfc_equiv *next, *eq;
+ gfc_expr *expr;
+ int used;
+}
+gfc_equiv;
+
+#define gfc_get_equiv() gfc_getmem(sizeof(gfc_equiv))
+
+
+/* gfc_case stores the selector list of a case statement. The *low
+ and *high pointers can point to the same expression in the case of
+ a single value. If *high is NULL, the selection is from *low
+ upwards, if *low is NULL the selection is *high downwards.
+
+ This structure has separate fields to allow singe and double linked
+ lists of CASEs the same time. The singe linked list along the NEXT
+ field is a list of cases for a single CASE label. The double linked
+ list along the LEFT/RIGHT fields is used to detect overlap and to
+ build a table of the cases for SELECT constructs with a CHARACTER
+ case expression. */
+
+typedef struct gfc_case
+{
+ /* Where we saw this case. */
+ locus where;
+ int n;
+
+ /* Case range values. If (low == high), it's a single value. If one of
+ the labels is NULL, it's an unbounded case. If both are NULL, this
+ represents the default case. */
+ gfc_expr *low, *high;
+
+ /* Next case label in the list of cases for a single CASE label. */
+ struct gfc_case *next;
+
+ /* Used for detecting overlap, and for code generation. */
+ struct gfc_case *left, *right;
+
+ /* True if this case label can never be matched. */
+ int unreachable;
+}
+gfc_case;
+
+#define gfc_get_case() gfc_getmem(sizeof(gfc_case))
+
+
+typedef struct
+{
+ gfc_expr *var, *start, *end, *step;
+}
+gfc_iterator;
+
+#define gfc_get_iterator() gfc_getmem(sizeof(gfc_iterator))
+
+
+/* Allocation structure for ALLOCATE, DEALLOCATE and NULLIFY statements. */
+
+typedef struct gfc_alloc
+{
+ gfc_expr *expr;
+ struct gfc_alloc *next;
+}
+gfc_alloc;
+
+#define gfc_get_alloc() gfc_getmem(sizeof(gfc_alloc))
+
+
+typedef struct
+{
+ gfc_expr *unit, *file, *status, *access, *form, *recl,
+ *blank, *position, *action, *delim, *pad, *iostat;
+ gfc_st_label *err;
+}
+gfc_open;
+
+
+typedef struct
+{
+ gfc_expr *unit, *status, *iostat;
+ gfc_st_label *err;
+}
+gfc_close;
+
+
+typedef struct
+{
+ gfc_expr *unit, *iostat;
+ gfc_st_label *err;
+}
+gfc_filepos;
+
+
+typedef struct
+{
+ gfc_expr *unit, *file, *iostat, *exist, *opened, *number, *named,
+ *name, *access, *sequential, *direct, *form, *formatted,
+ *unformatted, *recl, *nextrec, *blank, *position, *action, *read,
+ *write, *readwrite, *delim, *pad, *iolength;
+
+ gfc_st_label *err;
+
+}
+gfc_inquire;
+
+
+typedef struct
+{
+ gfc_expr *io_unit, *format_expr, *rec, *advance, *iostat, *size;
+
+ gfc_symbol *namelist;
+ /* A format_label of `format_asterisk' indicates the "*" format */
+ gfc_st_label *format_label;
+ gfc_st_label *err, *end, *eor;
+
+ locus eor_where, end_where;
+}
+gfc_dt;
+
+
+typedef struct gfc_forall_iterator
+{
+ gfc_expr *var, *start, *end, *stride;
+ struct gfc_forall_iterator *next;
+}
+gfc_forall_iterator;
+
+
+/* Executable statements that fill gfc_code structures. */
+typedef enum
+{
+ EXEC_NOP = 1, EXEC_ASSIGN, EXEC_LABEL_ASSIGN, EXEC_POINTER_ASSIGN,
+ EXEC_GOTO, EXEC_CALL, EXEC_RETURN, EXEC_PAUSE, EXEC_STOP, EXEC_CONTINUE,
+ EXEC_IF, EXEC_ARITHMETIC_IF, EXEC_DO, EXEC_DO_WHILE, EXEC_SELECT,
+ EXEC_FORALL, EXEC_WHERE, EXEC_CYCLE, EXEC_EXIT,
+ EXEC_ALLOCATE, EXEC_DEALLOCATE,
+ EXEC_OPEN, EXEC_CLOSE,
+ EXEC_READ, EXEC_WRITE, EXEC_IOLENGTH, EXEC_TRANSFER, EXEC_DT_END,
+ EXEC_BACKSPACE, EXEC_ENDFILE, EXEC_INQUIRE, EXEC_REWIND
+}
+gfc_exec_op;
+
+typedef struct gfc_code
+{
+ gfc_exec_op op;
+
+ struct gfc_code *block, *next;
+ locus loc;
+
+ gfc_st_label *here, *label, *label2, *label3;
+ gfc_symtree *symtree;
+ gfc_expr *expr, *expr2;
+ /* A name isn't sufficient to identify a subroutine, we need the actual
+ symbol for the interface definition.
+ const char *sub_name; */
+ gfc_symbol *resolved_sym;
+
+ union
+ {
+ gfc_actual_arglist *actual;
+ gfc_case *case_list;
+ gfc_iterator *iterator;
+ gfc_alloc *alloc_list;
+ gfc_open *open;
+ gfc_close *close;
+ gfc_filepos *filepos;
+ gfc_inquire *inquire;
+ gfc_dt *dt;
+ gfc_forall_iterator *forall_iterator;
+ struct gfc_code *whichloop;
+ int stop_code;
+ }
+ ext; /* Points to additional structures required by statement */
+
+ /* Backend_decl is used for cycle and break labels in do loops, and
+ * probably for other constructs as well, once we translate them. */
+ tree backend_decl;
+}
+gfc_code;
+
+
+/* Storage for DATA statements. */
+typedef struct gfc_data_variable
+{
+ gfc_expr *expr;
+ gfc_iterator iter;
+ struct gfc_data_variable *list, *next;
+}
+gfc_data_variable;
+
+
+typedef struct gfc_data_value
+{
+ int repeat;
+ gfc_expr *expr;
+
+ struct gfc_data_value *next;
+}
+gfc_data_value;
+
+
+typedef struct gfc_data
+{
+ gfc_data_variable *var;
+ gfc_data_value *value;
+ locus where;
+
+ struct gfc_data *next;
+}
+gfc_data;
+
+#define gfc_get_data_variable() gfc_getmem(sizeof(gfc_data_variable))
+#define gfc_get_data_value() gfc_getmem(sizeof(gfc_data_value))
+#define gfc_get_data() gfc_getmem(sizeof(gfc_data))
+
+
+/* Structure for holding compile options */
+typedef struct
+{
+ const char *source;
+ char *module_dir;
+ gfc_source_form source_form;
+ int fixed_line_length;
+ int max_identifier_length;
+ int verbose;
+
+ int warn_aliasing;
+ int warn_conversion;
+ int warn_implicit_interface;
+ int warn_line_truncation;
+ int warn_surprising;
+ int warn_unused_labels;
+
+ int flag_dollar_ok;
+ int flag_underscoring;
+ int flag_second_underscore;
+ int flag_implicit_none;
+ int flag_max_stack_var_size;
+ int flag_module_access_private;
+ int flag_no_backend;
+ int flag_pack_derived;
+ int flag_repack_arrays;
+
+ int q_kind;
+ int r8;
+ int i8;
+ int d8;
+ int warn_std;
+ int allow_std;
+}
+gfc_option_t;
+
+extern gfc_option_t gfc_option;
+
+
+/* Constructor nodes for array and structure constructors. */
+typedef struct gfc_constructor
+{
+ gfc_expr *expr;
+ gfc_iterator *iterator;
+ locus where;
+ struct gfc_constructor *next;
+ struct
+ {
+ mpz_t offset; /* Record the offset of array element which appears in
+ data statement like "data a(5)/4/". */
+ gfc_component *component; /* Record the component being initialized. */
+ }
+ n;
+ mpz_t repeat; /* Record the repeat number of initial values in data
+ statement like "data a/5*10/". */
+}
+gfc_constructor;
+
+
+typedef struct iterator_stack
+{
+ gfc_symtree *variable;
+ mpz_t value;
+ struct iterator_stack *prev;
+}
+iterator_stack;
+extern iterator_stack *iter_stack;
+
+/************************ Function prototypes *************************/
+
+/* data.c */
+void gfc_formalize_init_value (gfc_symbol *);
+void gfc_get_section_index (gfc_array_ref *, mpz_t *, mpz_t *);
+void gfc_assign_data_value (gfc_expr *, gfc_expr *, mpz_t);
+void gfc_advance_section (mpz_t *, gfc_array_ref *, mpz_t *);
+
+/* scanner.c */
+void gfc_scanner_done_1 (void);
+void gfc_scanner_init_1 (void);
+
+void gfc_add_include_path (const char *);
+void gfc_release_include_path (void);
+FILE *gfc_open_included_file (const char *);
+
+locus *gfc_current_locus (void);
+void gfc_set_locus (locus *);
+
+int gfc_at_end (void);
+int gfc_at_eof (void);
+int gfc_at_bol (void);
+int gfc_at_eol (void);
+void gfc_advance_line (void);
+int gfc_check_include (void);
+
+void gfc_skip_comments (void);
+int gfc_next_char_literal (int);
+int gfc_next_char (void);
+int gfc_peek_char (void);
+void gfc_error_recovery (void);
+void gfc_gobble_whitespace (void);
+try gfc_new_file (const char *, gfc_source_form);
+
+extern gfc_file *gfc_current_file;
+
+/* misc.c */
+void *gfc_getmem (size_t) ATTRIBUTE_MALLOC;
+void gfc_free (void *);
+int gfc_terminal_width(void);
+void gfc_clear_ts (gfc_typespec *);
+FILE *gfc_open_file (const char *);
+const char *gfc_article (const char *);
+const char *gfc_basic_typename (bt);
+const char *gfc_typename (gfc_typespec *);
+
+#define gfc_op2string(OP) (OP == INTRINSIC_ASSIGN ? \
+ "=" : gfc_code2string (intrinsic_operators, OP))
+
+const char *gfc_code2string (const mstring *, int);
+int gfc_string2code (const mstring *, const char *);
+const char *gfc_intent_string (sym_intent);
+
+void gfc_init_1 (void);
+void gfc_init_2 (void);
+void gfc_done_1 (void);
+void gfc_done_2 (void);
+
+/* options.c */
+unsigned int gfc_init_options (unsigned int, const char **);
+int gfc_handle_option (size_t, const char *, int);
+bool gfc_post_options (const char **);
+
+/* iresolve.c */
+char * gfc_get_string (const char *, ...) ATTRIBUTE_PRINTF_1;
+void gfc_iresolve_init_1 (void);
+void gfc_iresolve_done_1 (void);
+
+/* error.c */
+
+typedef struct gfc_error_buf
+{
+ int flag;
+ char message[MAX_ERROR_MESSAGE];
+} gfc_error_buf;
+
+void gfc_error_init_1 (void);
+void gfc_buffer_error (int);
+
+void gfc_warning (const char *, ...);
+void gfc_warning_now (const char *, ...);
+void gfc_clear_warning (void);
+void gfc_warning_check (void);
+
+void gfc_error (const char *, ...);
+void gfc_error_now (const char *, ...);
+void gfc_fatal_error (const char *, ...) ATTRIBUTE_NORETURN;
+void gfc_internal_error (const char *, ...) ATTRIBUTE_NORETURN;
+void gfc_clear_error (void);
+int gfc_error_check (void);
+
+try gfc_notify_std (int, const char *, ...);
+
+/* A general purpose syntax error. */
+#define gfc_syntax_error(ST) \
+ gfc_error ("Syntax error in %s statement at %C", gfc_ascii_statement (ST));
+
+void gfc_push_error (gfc_error_buf *);
+void gfc_pop_error (gfc_error_buf *);
+
+void gfc_status (const char *, ...) ATTRIBUTE_PRINTF_1;
+void gfc_status_char (char);
+
+void gfc_get_errors (int *, int *);
+
+/* arith.c */
+void gfc_arith_init_1 (void);
+void gfc_arith_done_1 (void);
+
+/* FIXME: These should go to symbol.c, really... */
+int gfc_default_integer_kind (void);
+int gfc_default_real_kind (void);
+int gfc_default_double_kind (void);
+int gfc_default_character_kind (void);
+int gfc_default_logical_kind (void);
+int gfc_default_complex_kind (void);
+int gfc_validate_kind (bt, int);
+extern int gfc_index_integer_kind;
+
+/* symbol.c */
+void gfc_clear_new_implicit (void);
+try gfc_add_new_implicit_range (int, int, gfc_typespec *);
+try gfc_merge_new_implicit (void);
+void gfc_set_implicit_none (void);
+void gfc_set_implicit (void);
+
+gfc_typespec *gfc_get_default_type (gfc_symbol *, gfc_namespace *);
+try gfc_set_default_type (gfc_symbol *, int, gfc_namespace *);
+
+void gfc_set_component_attr (gfc_component *, symbol_attribute *);
+void gfc_get_component_attr (symbol_attribute *, gfc_component *);
+
+void gfc_set_sym_referenced (gfc_symbol * sym);
+
+try gfc_add_allocatable (symbol_attribute *, locus *);
+try gfc_add_dimension (symbol_attribute *, locus *);
+try gfc_add_external (symbol_attribute *, locus *);
+try gfc_add_intrinsic (symbol_attribute *, locus *);
+try gfc_add_optional (symbol_attribute *, locus *);
+try gfc_add_pointer (symbol_attribute *, locus *);
+try gfc_add_result (symbol_attribute *, locus *);
+try gfc_add_save (symbol_attribute *, locus *);
+try gfc_add_saved_common (symbol_attribute *, locus *);
+try gfc_add_target (symbol_attribute *, locus *);
+try gfc_add_dummy (symbol_attribute *, locus *);
+try gfc_add_generic (symbol_attribute *, locus *);
+try gfc_add_common (symbol_attribute *, locus *);
+try gfc_add_in_common (symbol_attribute *, locus *);
+try gfc_add_in_namelist (symbol_attribute *, locus *);
+try gfc_add_sequence (symbol_attribute *, locus *);
+try gfc_add_elemental (symbol_attribute *, locus *);
+try gfc_add_pure (symbol_attribute *, locus *);
+try gfc_add_recursive (symbol_attribute *, locus *);
+try gfc_add_function (symbol_attribute *, locus *);
+try gfc_add_subroutine (symbol_attribute *, locus *);
+
+try gfc_add_access (symbol_attribute *, gfc_access, locus *);
+try gfc_add_flavor (symbol_attribute *, sym_flavor, locus *);
+try gfc_add_entry (symbol_attribute *, locus *);
+try gfc_add_procedure (symbol_attribute *, procedure_type, locus *);
+try gfc_add_intent (symbol_attribute *, sym_intent, locus *);
+try gfc_add_explicit_interface (gfc_symbol *, ifsrc,
+ gfc_formal_arglist *, locus *);
+try gfc_add_type (gfc_symbol *, gfc_typespec *, locus *);
+
+void gfc_clear_attr (symbol_attribute *);
+try gfc_missing_attr (symbol_attribute *, locus *);
+try gfc_copy_attr (symbol_attribute *, symbol_attribute *, locus *);
+
+try gfc_add_component (gfc_symbol *, const char *, gfc_component **);
+gfc_symbol *gfc_use_derived (gfc_symbol *);
+gfc_symtree *gfc_use_derived_tree (gfc_symtree *);
+gfc_component *gfc_find_component (gfc_symbol *, const char *);
+
+gfc_st_label *gfc_get_st_label (int);
+void gfc_free_st_label (gfc_st_label *);
+void gfc_define_st_label (gfc_st_label *, gfc_sl_type, locus *);
+try gfc_reference_st_label (gfc_st_label *, gfc_sl_type);
+
+gfc_namespace *gfc_get_namespace (gfc_namespace *);
+gfc_symtree *gfc_new_symtree (gfc_symtree **, const char *);
+gfc_symtree *gfc_find_symtree (gfc_symtree *, const char *);
+gfc_user_op *gfc_get_uop (const char *);
+gfc_user_op *gfc_find_uop (const char *, gfc_namespace *);
+void gfc_free_symbol (gfc_symbol *);
+gfc_symbol *gfc_new_symbol (const char *, gfc_namespace *);
+int gfc_find_symbol (const char *, gfc_namespace *, int, gfc_symbol **);
+int gfc_find_sym_tree (const char *, gfc_namespace *, int, gfc_symtree **);
+int gfc_get_symbol (const char *, gfc_namespace *, gfc_symbol **);
+int gfc_get_sym_tree (const char *, gfc_namespace *, gfc_symtree **);
+int gfc_get_ha_symbol (const char *, gfc_symbol **);
+int gfc_get_ha_sym_tree (const char *, gfc_symtree **);
+
+int gfc_symbols_could_alias (gfc_symbol *, gfc_symbol *);
+
+void gfc_undo_symbols (void);
+void gfc_commit_symbols (void);
+void gfc_free_namespace (gfc_namespace *);
+
+void gfc_symbol_init_2 (void);
+void gfc_symbol_done_2 (void);
+
+void gfc_traverse_symtree (gfc_namespace *, void (*)(gfc_symtree *));
+void gfc_traverse_ns (gfc_namespace *, void (*)(gfc_symbol *));
+void gfc_traverse_user_op (gfc_namespace *, void (*)(gfc_user_op *));
+void gfc_save_all (gfc_namespace *);
+
+void gfc_symbol_state (void);
+
+/* intrinsic.c */
+extern int gfc_init_expr;
+
+/* Given a symbol that we have decided is intrinsic, mark it as such
+ by placing it into a special module that is otherwise impossible to
+ read or write. */
+
+#define gfc_intrinsic_symbol(SYM) strcpy (SYM->module, "(intrinsic)")
+
+void gfc_intrinsic_init_1 (void);
+void gfc_intrinsic_done_1 (void);
+
+char gfc_type_letter (bt);
+gfc_symbol * gfc_get_intrinsic_sub_symbol (const char *);
+try gfc_convert_type (gfc_expr *, gfc_typespec *, int);
+try gfc_convert_type_warn (gfc_expr *, gfc_typespec *, int, int);
+int gfc_generic_intrinsic (const char *);
+int gfc_specific_intrinsic (const char *);
+int gfc_intrinsic_name (const char *, int);
+gfc_intrinsic_sym *gfc_find_function (const char *);
+
+match gfc_intrinsic_func_interface (gfc_expr *, int);
+match gfc_intrinsic_sub_interface (gfc_code *, int);
+
+/* simplify.c */
+void gfc_simplify_init_1 (void);
+void gfc_simplify_done_1 (void);
+
+/* match.c -- FIXME */
+void gfc_free_iterator (gfc_iterator *, int);
+void gfc_free_forall_iterator (gfc_forall_iterator *);
+void gfc_free_alloc_list (gfc_alloc *);
+void gfc_free_namelist (gfc_namelist *);
+void gfc_free_equiv (gfc_equiv *);
+void gfc_free_data (gfc_data *);
+void gfc_free_case_list (gfc_case *);
+
+/* expr.c */
+void gfc_free_actual_arglist (gfc_actual_arglist *);
+gfc_actual_arglist *gfc_copy_actual_arglist (gfc_actual_arglist *);
+const char *gfc_extract_int (gfc_expr *, int *);
+
+gfc_expr *gfc_build_conversion (gfc_expr *);
+void gfc_free_ref_list (gfc_ref *);
+void gfc_type_convert_binary (gfc_expr *);
+int gfc_is_constant_expr (gfc_expr *);
+try gfc_simplify_expr (gfc_expr *, int);
+
+gfc_expr *gfc_get_expr (void);
+void gfc_free_expr (gfc_expr *);
+void gfc_replace_expr (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_int_expr (int);
+gfc_expr *gfc_logical_expr (int, locus *);
+mpz_t *gfc_copy_shape (mpz_t *, int);
+gfc_expr *gfc_copy_expr (gfc_expr *);
+
+try gfc_specification_expr (gfc_expr *);
+
+int gfc_numeric_ts (gfc_typespec *);
+int gfc_kind_max (gfc_expr *, gfc_expr *);
+
+try gfc_check_conformance (const char *, gfc_expr *, gfc_expr *);
+try gfc_check_assign (gfc_expr *, gfc_expr *, int);
+try gfc_check_pointer_assign (gfc_expr *, gfc_expr *);
+try gfc_check_assign_symbol (gfc_symbol *, gfc_expr *);
+
+/* st.c */
+extern gfc_code new_st;
+
+void gfc_clear_new_st (void);
+gfc_code *gfc_get_code (void);
+gfc_code *gfc_append_code (gfc_code *, gfc_code *);
+void gfc_free_statement (gfc_code *);
+void gfc_free_statements (gfc_code *);
+
+/* resolve.c */
+try gfc_resolve_expr (gfc_expr *);
+void gfc_resolve (gfc_namespace *);
+int gfc_impure_variable (gfc_symbol *);
+int gfc_pure (gfc_symbol *);
+int gfc_elemental (gfc_symbol *);
+try gfc_resolve_iterator (gfc_iterator *);
+try gfc_resolve_index (gfc_expr *, int);
+
+/* array.c */
+void gfc_free_array_spec (gfc_array_spec *);
+gfc_array_ref *gfc_copy_array_ref (gfc_array_ref *);
+
+try gfc_set_array_spec (gfc_symbol *, gfc_array_spec *, locus *);
+gfc_array_spec *gfc_copy_array_spec (gfc_array_spec *);
+try gfc_resolve_array_spec (gfc_array_spec *, int);
+
+int gfc_compare_array_spec (gfc_array_spec *, gfc_array_spec *);
+
+gfc_expr *gfc_start_constructor (bt, int, locus *);
+void gfc_append_constructor (gfc_expr *, gfc_expr *);
+void gfc_free_constructor (gfc_constructor *);
+void gfc_simplify_iterator_var (gfc_expr *);
+try gfc_expand_constructor (gfc_expr *);
+int gfc_constant_ac (gfc_expr *);
+int gfc_expanded_ac (gfc_expr *);
+try gfc_resolve_array_constructor (gfc_expr *);
+try gfc_check_constructor_type (gfc_expr *);
+try gfc_check_iter_variable (gfc_expr *);
+try gfc_check_constructor (gfc_expr *, try (*)(gfc_expr *));
+gfc_constructor *gfc_copy_constructor (gfc_constructor * src);
+gfc_expr *gfc_get_array_element (gfc_expr *, int);
+try gfc_array_size (gfc_expr *, mpz_t *);
+try gfc_array_dimen_size (gfc_expr *, int, mpz_t *);
+try gfc_array_ref_shape (gfc_array_ref *, mpz_t *);
+gfc_array_ref *gfc_find_array_ref (gfc_expr *);
+void gfc_insert_constructor (gfc_expr *, gfc_constructor *);
+gfc_constructor *gfc_get_constructor (void);
+tree gfc_conv_array_initializer (tree type, gfc_expr * expr);
+try spec_size (gfc_array_spec *, mpz_t *);
+
+/* interface.c -- FIXME: some of these should be in symbol.c */
+void gfc_free_interface (gfc_interface *);
+int gfc_compare_types (gfc_typespec *, gfc_typespec *);
+void gfc_check_interfaces (gfc_namespace *);
+void gfc_procedure_use (gfc_symbol *, gfc_actual_arglist **, locus *);
+gfc_symbol *gfc_search_interface (gfc_interface *, int,
+ gfc_actual_arglist **);
+try gfc_extend_expr (gfc_expr *);
+void gfc_free_formal_arglist (gfc_formal_arglist *);
+try gfc_extend_assign (gfc_code *, gfc_namespace *);
+try gfc_add_interface (gfc_symbol * sym);
+
+/* io.c */
+extern gfc_st_label format_asterisk;
+
+void gfc_free_open (gfc_open *);
+try gfc_resolve_open (gfc_open *);
+void gfc_free_close (gfc_close *);
+try gfc_resolve_close (gfc_close *);
+void gfc_free_filepos (gfc_filepos *);
+try gfc_resolve_filepos (gfc_filepos *);
+void gfc_free_inquire (gfc_inquire *);
+try gfc_resolve_inquire (gfc_inquire *);
+void gfc_free_dt (gfc_dt *);
+try gfc_resolve_dt (gfc_dt *);
+
+/* module.c */
+void gfc_module_init_2 (void);
+void gfc_module_done_2 (void);
+void gfc_dump_module (const char *, int);
+
+/* primary.c */
+symbol_attribute gfc_variable_attr (gfc_expr *, gfc_typespec *);
+symbol_attribute gfc_expr_attr (gfc_expr *);
+
+/* trans.c */
+void gfc_generate_code (gfc_namespace *);
+void gfc_generate_module_code (gfc_namespace *);
+
+/* bbt.c */
+typedef int (*compare_fn) (void *, void *);
+void gfc_insert_bbt (void *, void *, compare_fn);
+void gfc_delete_bbt (void *, void *, compare_fn);
+
+/* dump-parse-tree.c */
+void gfc_show_namespace (gfc_namespace *);
+
+/* parse.c */
+try gfc_parse_file (void);
+
+#endif /* GFC_GFC_H */
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
new file mode 100644
index 00000000000..d23ecc01c6c
--- /dev/null
+++ b/gcc/fortran/gfortran.texi
@@ -0,0 +1,800 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename gfortran.info
+@set last-update 13 May 2004
+@set copyrights-gfortran 1999-2004
+@set version-gfortran 0.235
+
+@include gcc-common.texi
+
+@settitle The GNU Fortran 95 Compiler
+
+@c Create a separate index for command line options
+@defcodeindex op
+@c Merge the standard indexes into a single one.
+@syncodeindex fn cp
+@syncodeindex vr cp
+@syncodeindex ky cp
+@syncodeindex pg cp
+@syncodeindex tp cp
+
+@c %**end of header
+
+@c Use with @@smallbook.
+
+@c %** start of document
+
+@c Cause even numbered pages to be printed on the left hand side of
+@c the page and odd numbered pages to be printed on the right hand
+@c side of the page. Using this, you can print on both sides of a
+@c sheet of paper and have the text on the same part of the sheet.
+
+@c The text on right hand pages is pushed towards the right hand
+@c margin and the text on left hand pages is pushed toward the left
+@c hand margin.
+@c (To provide the reverse effect, set bindingoffset to -0.75in.)
+
+@c @tex
+@c \global\bindingoffset=0.75in
+@c \global\normaloffset =0.75in
+@c @end tex
+
+@copying
+Copyright @copyright{} @value{copyrights-gfortran} Free Software Foundation, Inc.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.1 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being ``GNU General Public License'' and ``Funding
+Free Software'', the Front-Cover
+texts being (a) (see below), and with the Back-Cover Texts being (b)
+(see below). A copy of the license is included in the section entitled
+``GNU Free Documentation License''.
+
+(a) The FSF's Front-Cover Text is:
+
+ A GNU Manual
+
+(b) The FSF's Back-Cover Text is:
+
+ You have freedom to copy and modify this GNU Manual, like GNU
+ software. Copies published by the Free Software Foundation raise
+ funds for GNU development.
+@end copying
+
+@ifinfo
+@dircategory Programming
+@direntry
+* gfortran: (gfortran). The GNU Fortran 95 Compiler.
+@end direntry
+This file documents the use and the internals of
+the GNU Fortran 95 compiler, (@command{gfortran}).
+
+Published by the Free Software Foundation
+59 Temple Place - Suite 330
+Boston, MA 02111-1307 USA
+
+@insertcopying
+@end ifinfo
+
+Contributed by Steven Bosscher (@email{s.bosscher@@gcc.gnu.org}).
+
+@setchapternewpage odd
+@titlepage
+@title Using GNU Fortran 95
+@sp 2
+@center Steven Bosscher
+@sp 3
+@center Last updated @value{last-update}
+@sp 1
+@center for version @value {version-gfortran}
+@page
+@vskip 0pt plus 1filll
+For the @value{version-gfortran} Version*
+@sp 1
+Published by the Free Software Foundation @*
+59 Temple Place - Suite 330@*
+Boston, MA 02111-1307, USA@*
+@c Last printed ??ber, 19??.@*
+@c Printed copies are available for $? each.@*
+@c ISBN ???
+@sp 1
+@insertcopying
+@end titlepage
+@summarycontents
+@contents
+@page
+
+@node Top, Copying,, (DIR)
+@top Introduction
+@cindex Introduction
+
+This manual documents the use of @command{gfortran},
+the GNU Fortran 95 compiler. You can find in this manual how to invoke
+@command{gfortran}, as well as its features and incompatibilities,
+and how to report bugs.
+
+@ifset DEVELOPMENT
+@emph{Warning:} This document, and the compiler it describes, are still
+under development. While efforts are made too keep it up-to-date it might
+not accurately reflect the status of the most recent @command{gfortran}.
+@end ifset
+
+@menu
+* Copying:: GNU General Public License says
+ how you can copy and share GNU Fortran.
+* GNU Free Documentation License::
+ How you can copy and share this manual.
+* Funding:: How to help assure continued work for free software.
+* Getting Started:: What you should know about @command{gfortran}.
+* GFORTRAN and GCC:: You can compile Fortran, C, or other programs.
+* GFORTRAN and G77:: Why we choose to start from scratch.
+* Invoking GFORTRAN:: Command options supported by @command{gfortran}.
+* Compiling and Testing::
+ Need-to-knows about compiling and testing.
+* Project Status:: Status of GFORTRAN, Roadmap, proposed extensions.
+* Contributing:: Helping you can help.
+* Standards:: Standards supported by GFORTRAN.
+* Index:: Index of this documentation.
+@end menu
+
+
+
+@c ---------------------------------------------------------------------
+@c GNU General Public License
+@c ---------------------------------------------------------------------
+
+@include gpl.texi
+
+
+
+@c ---------------------------------------------------------------------
+@c GNU Free Documentation License
+@c ---------------------------------------------------------------------
+
+@include fdl.texi
+
+
+
+@c ---------------------------------------------------------------------
+@c Funding Free Software
+@c ---------------------------------------------------------------------
+
+@include funding.texi
+
+
+
+@c ---------------------------------------------------------------------
+@c Getting Started
+@c ---------------------------------------------------------------------
+
+@node Getting Started
+@chapter Getting Started
+
+Gfortran is the GNU Fortran 95 compiler front end,
+designed initially as a free replacement for,
+or alternative to, the unix @command{f95} command;
+@command{gfortran} is command you'll use to invoke the compiler.
+
+Gfortran is still in an early state of development.
+@command{gfortran} can generate code for most constructs and expressions,
+but much work remains to be done.
+
+When @command{gfortran} is finished,
+it will do everything you expect from any decent compiler:
+
+@itemize @bullet
+@item
+Read a user's program,
+stored in a file and containing instructions written
+in Fortran 77, Fortran 90 or Fortran 95.
+This file contains @dfn{source code}.
+
+@item
+Translate the user's program into instructions a computer
+can carry out more quickly than it takes to translate the
+instructions in the first
+place. The result after compilation of a program is
+@dfn{machine code},
+code designed to be efficiently translated and processed
+by a machine such as your computer.
+Humans usually aren't as good writing machine code
+as they are at writing Fortran (or C++, Ada, or Java),
+because is easy to make tiny mistakes writing machine code.
+
+@item
+Provide the user with information about the reasons why
+the compiler is unable to create a binary from the source code.
+Usually this will be the case if the source code is flawed.
+When writing Fortran, it is easy to make big mistakes.
+The Fortran 90 requires that the compiler can point out
+mistakes to the user.
+An incorrect usage of the language causes an @dfn{error message}.
+
+The compiler will also attempt to diagnose cases where the
+user's program contains a correct usage of the language,
+but instructs the computer to do something questionable.
+This kind of diagnostics message is called a @dfn{warning message}.
+
+@item
+Provide optional information about the translation passes
+from the source code to machine code.
+This can help a user of the compiler to find the cause of
+certain bugs which may not be obvious in the source code,
+but may be more easily found at a lower level compiler output.
+It also helps developers to find bugs in the compiler itself.
+
+@item
+Provide information in the generated machine code that can
+make it easier to find bugs in the program (using a debugging tool,
+called a @dfn{debugger}, such as the GNU Debugger @command{gdb}).
+
+@item
+Locate and gather machine code already generated to
+perform actions requested by statements in the user's program.
+This machine code is organized into @dfn{modules} and is located
+and @dfn{linked} to the user program.
+@end itemize
+
+Gfortran consists of several components:
+
+@itemize @bullet
+@item
+A version of the @command{gcc} command
+(which also might be installed as the system's @command{cc} command)
+that also understands and accepts Fortran source code.
+The @command{gcc} command is the @dfn{driver} program for
+all the languages in the GNU Compiler Collection (GCC);
+With @command{gcc},
+you can compiler the source code of any language for
+which a front end is available in GCC.
+
+@item
+The @command{gfortran} command itself,
+which also might be installed as the
+system's @command{f95} command.
+@command{gfortran} is just another driver program,
+but specifically for the Fortran 95 compiler only.
+The difference with @command{gcc} is that @command{gfortran}
+will automatically link the correct libraries to your program.
+
+@item
+A collection of run-time libraries.
+These libraries contains the machine code needed to support
+capabilities of the Fortran language that are not directly
+provided by the machine code generated by the
+@command{gfortran} compilation phase,
+such as intrinsic functions and subroutines,
+and routines for interaction with files and the operating system.
+@c and mechanisms to spawn,
+@c unleash and pause threads in parallelized code.
+
+@item
+The Fortran compiler itself, (@command{f951}).
+This is the gfortran parser and code generator,
+linked to and interfaced with the GCC backend library.
+@command{f951} ``translates'' the source code to
+assembler code. You would typically not use this
+program directly;
+instead, the @command{gcc} or @command{gfortran} driver
+programs will call it for you.
+@end itemize
+
+
+
+@c ---------------------------------------------------------------------
+@c GFORTRAN and GCC
+@c ---------------------------------------------------------------------
+
+@node GFORTRAN and GCC
+@chapter GFORTRAN and GCC
+@cindex GNU Compiler Collection
+
+GCC used to be the GNU ``C'' Compiler,
+but is now known as the @dfn{GNU Compiler Collection}.
+GCC provides the GNU system with a very versatile
+compiler middle end (shared optimization passes),
+and with back ends (code generators) for many different
+computer architectures and operating systems.
+The code of the middle end and back end are shared by all
+compiler front ends that are in the GNU Compiler Collection.
+
+A GCC front end is essentially a source code parser
+and a pass to generate a representation of the semantics
+of the program in the source code in the GCC language
+independent intermediate language,
+called @dfn{GENERIC}.
+
+The parser takes a source file written in a
+particular computer language, reads and parses it,
+and tries to make sure that the source code conforms to
+the language rules.
+Once the correctness of a program has been established,
+the compiler will build a data structure known as the
+@dfn{Abstract Syntax tree},
+or just @dfn{AST} or ``tree'' for short.
+This data structure represents the whole program
+or a subroutine or a function.
+The ``tree'' is passed to the GCC middle end,
+which will perform optimization passes on it,
+pass the optimized AST and generate assembly
+for the program unit.
+
+Different phases in this translation process can be,
+and in fact @emph{are} merged in many compiler front ends.
+GNU Fortran 95 has a strict separation between the
+parser and code generator.
+
+The goal of the gfortran project is to build a new front end for GCC:
+A Fortran 95 front end.
+In a non-gfortran installation,
+@command{gcc} will not be able to compile Fortran 95 source code
+(only the ``C'' front end has to be compiled if you want to build GCC,
+all other languages are optional).
+If you build GCC with gfortran, @command{gcc} will recognize
+@file{.f/.f90/.f95} source files and accepts Fortran 95 specific
+command line options.
+
+
+
+@c ---------------------------------------------------------------------
+@c GFORTRAN and G77
+@c ---------------------------------------------------------------------
+
+@node GFORTRAN and G77
+@chapter GFORTRAN and G77
+@cindex Fortran 77
+@cindex G77
+
+Why do we write a compiler front end from scratch?
+There's a fine Fortran 77 compiler in the
+GNU Compiler Collection that accepts some features
+of the Fortran 90 standard as extensions.
+Why not start from there and revamp it?
+
+One of the reasons is that Craig Burley, the author of G77,
+has decided to stop working on the G77 front end.
+On @uref{http://world.std.com/~burley/g77-why.html,
+Craig explains the reasons for his decision to stop working on G77}
+in one of the pages in his homepage.
+Among the reasons is a lack of interest in improvements to
+@command{g77}.
+Users appear to be quite satisfied with @command{g77} as it is.
+While @command{g77} is still being maintained (by Toon Moene),
+it is unlikely that sufficient people will be willing
+to completely rewrite the existing code.
+
+But there are other reasons to start from scratch.
+Many people, including Craig Burley,
+no longer agreed with certain design decisions in the G77 front end.
+Also, the interface of @command{g77} to the back end is written in
+a style which is confusing and not up to date on recommended practice.
+In fact, a full rewrite had already been planned for GCC 3.0.
+
+When Craig decided to stop,
+it just seemed to be a better idea to start a new project from scratch,
+because it was expected to be easier to maintain code we
+develop ourselves than to do a major overhaul of @command{g77} first,
+and then build a Fortran 95 compiler out of it.
+
+
+@include invoke.texi
+
+@c ---------------------------------------------------------------------
+@c Compiling and Testing
+@c ---------------------------------------------------------------------
+
+@node Compiling and Testing
+@chapter Compiling and Testing
+
+@command{gfortran} is not yet part of an official GCC release, so it is
+unlikley that OS distributor will provide it.
+
+@menu
+* Precompiled Binaries::
+* General notes about compiling GFORTRAN::
+* Testing::
+@end menu
+
+@node Precompiled Binaries
+@section Precompiled Binaries
+
+Precompiled binaries for i686-pc-linux-gnu in rpm format are available from
+@uref{http://people.redhat.com/dnovillo/pub/tree-ssa/snapshot/}
+
+@node General notes about compiling GFORTRAN
+@section General notes about compiling GFORTRAN
+@cindex GMP
+@cindex Multiple Precision Library
+
+Compiling gfortran requires the presence of GMP,
+the GNU Multiple Precision library version 4.0
+or better in order to do its arithmetic.
+Download @code{gmp} from your favorite GNU mirror,
+configure and compile it. If your OS distributor provides prepackaged
+GMP libraries, you may also need the developent pacakges.
+
+If you do not have GMP installed in a standard system location, you may
+need to configure GCC with @option{--with-gmp} or @option{--with-gmp-dir}.
+
+Note: GMP is only required for the compiler itself. Compiled fortran programs
+do not depend on the GMP library.
+
+@node Testing
+@section Testing
+@cindex Test suite
+@cindex Testing
+
+The number of possible Fortran 95 programs is unlimited,
+and this means that gfortran has to correctly handle lots of possible inputs.
+Whenever you make any changes to the compiler,
+you should first test your change on a test program,
+then test your change against the gfortran test suite.
+In this way, we can be assured that once your fix has been made,
+the problem isn't re-introduced at some later time.
+
+The gfortran test suite is included in the gcc source distribution.
+
+We also encourage you to test gfortran on your own Fortran codes.
+
+@c ---------------------------------------------------------------------
+@c Project Status
+@c ---------------------------------------------------------------------
+
+@node Project Status
+@chapter Project Status
+
+@quotation
+As soon as gfortran can parse all of the statements correctly,
+it will be in the ``larva'' state.
+When we generate code, the ``puppa'' state.
+When gfortran is done,
+we'll see if it will be a beautiful butterfly,
+or just a big bug....
+
+--Andy Vaught, April 2000
+@end quotation
+
+The start of the GNU Fortran 95 project was announced on
+the GCC homepage in March 18, 2000
+(even though Andy had already been working on it for a while,
+or course).
+
+Gfortran is currently reaching the stage where is is able to compile real
+world programs. However it is still under development and has many rough
+edges.
+
+@menu
+* Compiler Status::
+* Library Status::
+* Proposed Extensions::
+@end menu
+
+@node Compiler Status
+@section Compiler Status
+
+@table @emph
+@item Front end
+This is the part of gfortran which parses a source file, verifies that it
+is valid Fortran 95, performs compile time replacement of constants
+(PARAMETER variables) and reads and generate module files. This is
+almost complete. Every Fortran 95 source should be accepted, and most
+none-Fortran 95 source should be rejected. If you find a source file where
+this is not true, please tell us. You can use the -fsyntax-only switch to
+make gfortran quit after running the front end, effectively reducing it to
+a syntax checker.
+
+@item Middle end interface
+These are the parts of gfortran that take the parse tree generated by the
+front end and translate it to the GENERIC form required by the GCC back
+end. Work is ongoing in these parts of gfortran, but a large part has
+already been completed.
+@end table
+
+@node Library Status
+@section Library Status
+
+Some intrinsic functions map directly to library functions, and in most
+cases the name of the library function used depends on the type of the
+arguments. For some intrinsics we generate inline code, and for others,
+such as sin, cos and sqrt, we rely on the backend to use special
+instructions in the floating point unit of the CPU if available, or to
+fall back to a call to libm if these are not available.
+
+Implementation of some non-elemental intrinsic functions (eg. DOT_PRODUCT,
+AVERAGE) is not yet optimal. This is hard because we have to make decisions
+whether to use inline code (good for small arrays as no function call
+overhead occurs) or generate function calls (good for large arrays as it
+allows use of hand-optimized assembly routines, SIMD instructions, etc.)
+
+The IO library is still under development. The following features should be
+usable for real programs:
+
+@itemize @minus
+@item List directed
+@item Unformatted sequential
+@end itemize
+
+Usable with bugs:
+
+@itemize @minus
+@item Formatted sequential ('T' edit descriptor, and others)
+@item Namelist (can read a namelist that it writes, but not free-form)
+@end itemize
+
+Not recommended:
+
+@itemize @minus
+@item Unformatted direct access
+@item Formatted direct access
+@end itemize
+
+Many Fortran programs only use a small subset of the available IO
+capabilities, so your milage may vary.
+
+@node Proposed Extensions
+@section Proposed Extensions
+
+Here's a list of proposed extensions for @command{gfortran}, in no particular
+order. Most of these are necessary to be fully compatible with
+existing Fortran compilers, but they are not part of the official
+J3 Fortran 95 standard.
+
+@subsection Compiler extensions:
+@itemize @bullet
+@item
+Flag for defining the kind number for default logicals.
+
+@item
+User-specified alignment rules for structures.
+@item
+Flag to generate a @code{Makefile} info.
+
+@item
+Automatically extend single precision constants to double.
+
+@item
+Cray pointers (this was high on the @command{g77} wishlist).
+
+@item
+Compile code that conserves memory by dynamically allocating common and
+module storage either on stack or heap.
+
+@item
+Flag to cause the compiler to distinguish between upper and lower case
+names. The Fortran 95 standard does not distinguish them.
+
+@item
+Compile switch for changing the interpretation of a backslash from a
+character to ``C''-style escape characters.
+
+@item
+Compile flag to generate code for array conformance checking (suggest -CC).
+
+@item
+User control of symbol names (underscores, etc).
+
+@item
+Compile setting for maximum size of stack frame size before spilling
+parts to static or heap.
+
+@item
+Flag to force local variables into static space.
+
+@item
+Flag to force local variables onto stack.
+
+@item
+Flag to compile lines beginning with ``D''.
+
+@item
+Flag to ignore lines beginning with ``D''.
+
+@item
+Flag for maximum errors before ending compile.
+
+@item
+Generate code to check for null pointer dereferences -- prints locus of
+dereference instead of segfaulting. There was some discussion about this
+option in the g95 development mailing list.
+
+@item
+Allow setting default unit number.
+
+@item
+Option to initialize of otherwise uninitialized integer and floating
+point variables.
+
+@item
+Support for OpenMP directives. This also requires support from the runtime
+library and the rest of the compiler.
+
+@item
+Support for Fortran 200x. This includes several new features including
+floating point exceptions, extended use of allocatable arrays, C
+interoperability, Parameterizer data types and function pointers.
+@end itemize
+
+
+@subsection Environment Options
+@itemize @bullet
+@item
+Pluggable library modules for random numbers, linear algebra.
+LA should use BLAS calling conventions.
+
+@item
+Environment variables controlling actions on arithmetic exceptions like
+overflow, underflow, precision loss -- Generate NaN, abort, default.
+action.
+
+@item
+Set precision for fp units that support it (i387).
+
+@item
+Variables for setting fp rounding mode.
+
+@item
+Support old style namelists ending in $end or &end.
+
+@item
+Variable to fill uninitialized variables with a user-defined bit
+pattern.
+
+@item
+Environment variable controlling filename that is opened for that unit
+number.
+
+@item
+Environment variable to clear/trash memory being freed.
+
+@item
+Environment variable to control tracing of allocations and frees.
+
+@item
+Environment variable to display allocated memory at normal program end.
+
+@item
+Environment variable for filename for * IO-unit.
+
+@item
+Environment variable for temporary file directory.
+
+@item
+Environment variable forcing standard output to be line buffered (unix).
+
+@item
+Variable for swapping endianness during unformatted read.
+
+@item
+Variable for swapping Endianness during unformatted write.
+@end itemize
+
+
+
+@c ---------------------------------------------------------------------
+@c Contributing
+@c ---------------------------------------------------------------------
+
+@node Contributing
+@chapter Contributing
+@cindex Contributing
+
+Free software is only possible if people contribute to efforts
+to create it.
+We're always in need of more people helping out with ideas
+and comments, writing documentation and contributing code.
+
+If you want to contribute to GNU Fortran 95,
+have a look at the long lists of projects you can take on.
+Some of these projects are small,
+some of them are large;
+some are completely orthogonal to the rest of what is
+happening on @command{gfortran},
+but others are ``mainstream'' projects in need of enthusiastic hackers.
+All of these projects are important!
+We'll eventually get around to the things here,
+but they are also things doable by someone who is willing and able.
+
+@menu
+* Contributors::
+* Projects::
+@end menu
+
+
+@node Contributors
+@section Contributors to GNU Fortran 95
+@cindex Contributors
+@cindex Credits
+@cindex Authors
+
+Most of the parser was hand-crafted by @emph{Andy Vaught}, who is
+also the initiator of the whole project. Thanks Andy!
+Most of the interface with GCC was written by @emph{Paul Brook}.
+
+The following individuals have contributed code and/or
+ideas and significant help to the gfortran project
+(in no particular order):
+
+@itemize @minus
+@item Andy Vaught
+@item Katherine Holcomb
+@item Tobias Schlüter
+@item Steven Bosscher
+@item Toon Moene
+@item Tim Prince
+@item Niels Kristian Bech Jensen
+@item Steven Johnson
+@item Paul Brook
+@item Feng Wang
+@item Bud Davis
+@end itemize
+
+The following people have contributed bug reports,
+smaller or larger patches,
+and much needed feedback and encouragement for the
+@command{gfortran} project:
+
+@itemize @minus
+@item Erik Schnetter
+@item Bill Clodius
+@item Kate Hedstrom
+@end itemize
+
+Many other individuals have helped debug,
+test and improve @command{gfortran} over the past two years,
+and we welcome you to do the same!
+If you already have done so,
+and you would like to see your name listed in the
+list above, please contact us.
+
+
+@node Projects
+@section Projects
+
+@table @emph
+
+@item Help build the test suite
+Solicit more code for donation to the test suite.
+We can keep code private on request.
+
+@item Bug hunting/squishing
+Find bugs and write more test cases!
+Test cases are especially very welcome,
+because it allows us to concentrate on fixing bugs
+instead of isolating them.
+
+@item Smaller projects (``bug'' fixes):
+ @itemize @minus
+ @item Allow init exprs to be numbers raised to integer powers.
+ @item Implement correct rounding.
+ @item Implement F restrictions on Fortran 95 syntax.
+ @item See about making Emacs-parsable error messages.
+ @end itemize
+@end table
+
+If you wish to work on the runtime libraries,
+please contact a project maintainer.
+@c TODO: email!
+
+
+@c ---------------------------------------------------------------------
+@c Standards
+@c ---------------------------------------------------------------------
+
+@node Standards
+@chapter Standards
+@cindex Standards
+
+The GNU Fortran 95 Compiler aims to be a conforming implementation of
+ISO/IEC 1539:1997 (Fortran 95).
+
+In the future it may also support other variants and extensions to the Fortran
+language. This includes ANSI Fortran 77, Fortran 90, Fortran 2000 (not yet
+finalized), and OpenMP.
+
+@node Index
+@unnumbered Index
+
+@printindex cp
+
+@bye
diff --git a/gcc/fortran/gfortranspec.c b/gcc/fortran/gfortranspec.c
new file mode 100644
index 00000000000..cbea36d0b96
--- /dev/null
+++ b/gcc/fortran/gfortranspec.c
@@ -0,0 +1,549 @@
+/* Specific flags and argument handling of the Fortran front-end.
+ Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
+ Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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 2, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+/* This file is copied more or less verbatim from g77. */
+/* This file contains a filter for the main `gcc' driver, which is
+ replicated for the `gfortran' driver by adding this filter. The purpose
+ of this filter is to be basically identical to gcc (in that
+ it faithfully passes all of the original arguments to gcc) but,
+ unless explicitly overridden by the user in certain ways, ensure
+ that the needs of the language supported by this wrapper are met.
+
+ For GNU Fortran 95(gfortran), we do the following to the argument list
+ before passing it to `gcc':
+
+ 1. Make sure `-lgfortran -lm' is at the end of the list.
+
+ 2. Make sure each time `-lgfortran' or `-lm' is seen, it forms
+ part of the series `-lgfortran -lm'.
+
+ #1 and #2 are not done if `-nostdlib' or any option that disables
+ the linking phase is present, or if `-xfoo' is in effect. Note that
+ a lack of source files or -l options disables linking.
+
+ This program was originally made out of gcc/cp/g++spec.c, but the
+ way it builds the new argument list was rewritten so it is much
+ easier to maintain, improve the way it decides to add or not add
+ extra arguments, etc. And several improvements were made in the
+ handling of arguments, primarily to make it more consistent with
+ `gcc' itself. */
+
+#include "config.h"
+#include "system.h"
+#include "gcc.h"
+
+#include "coretypes.h"
+#include "tm.h"
+
+#ifndef MATH_LIBRARY
+#define MATH_LIBRARY "-lm"
+#endif
+
+#ifndef FORTRAN_INIT
+#define FORTRAN_INIT "-lgfortranbegin"
+#endif
+
+#ifndef FORTRAN_LIBRARY
+#define FORTRAN_LIBRARY "-lgfortran"
+#endif
+
+/* Options this driver needs to recognize, not just know how to
+ skip over. */
+typedef enum
+{
+ OPTION_b, /* Aka --prefix. */
+ OPTION_B, /* Aka --target. */
+ OPTION_c, /* Aka --compile. */
+ OPTION_E, /* Aka --preprocess. */
+ OPTION_help, /* --help. */
+ OPTION_i, /* -imacros, -include, -include-*. */
+ OPTION_l,
+ OPTION_L, /* Aka --library-directory. */
+ OPTION_nostdlib, /* Aka --no-standard-libraries, or
+ -nodefaultlibs. */
+ OPTION_o, /* Aka --output. */
+ OPTION_S, /* Aka --assemble. */
+ OPTION_syntax_only, /* -fsyntax-only. */
+ OPTION_v, /* Aka --verbose. */
+ OPTION_version, /* --version. */
+ OPTION_V, /* Aka --use-version. */
+ OPTION_x, /* Aka --language. */
+ OPTION_ /* Unrecognized or unimportant. */
+}
+Option;
+
+/* The original argument list and related info is copied here. */
+static int g77_xargc;
+static const char *const *g77_xargv;
+static void lookup_option (Option *, int *, const char **, const char *);
+static void append_arg (const char *);
+
+/* The new argument list will be built here. */
+static int g77_newargc;
+static const char **g77_newargv;
+
+const struct spec_function lang_specific_spec_functions[] = {{0,0}};
+
+/* --- This comes from gcc.c (2.8.1) verbatim: */
+
+/* This defines which switch letters take arguments. */
+
+#ifndef SWITCH_TAKES_ARG
+#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR)
+#endif
+
+/* This defines which multi-letter switches take arguments. */
+
+#ifndef WORD_SWITCH_TAKES_ARG
+#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
+#endif
+
+/* --- End of verbatim. */
+
+/* Assumes text[0] == '-'. Returns number of argv items that belong to
+ (and follow) this one, an option id for options important to the
+ caller, and a pointer to the first char of the arg, if embedded (else
+ returns NULL, meaning no arg or it's the next argv).
+
+ Note that this also assumes gcc.c's pass converting long options
+ to short ones, where available, has already been run. */
+
+static void
+lookup_option (Option *xopt, int *xskip, const char **xarg, const char *text)
+{
+ Option opt = OPTION_;
+ int skip;
+ const char *arg = NULL;
+
+ if ((skip = SWITCH_TAKES_ARG (text[1])))
+ skip -= (text[2] != '\0'); /* See gcc.c. */
+
+ if (text[1] == 'B')
+ opt = OPTION_B, skip = (text[2] == '\0'), arg = text + 2;
+ else if (text[1] == 'b')
+ opt = OPTION_b, skip = (text[2] == '\0'), arg = text + 2;
+ else if ((text[1] == 'c') && (text[2] == '\0'))
+ opt = OPTION_c, skip = 0;
+ else if ((text[1] == 'E') && (text[2] == '\0'))
+ opt = OPTION_E, skip = 0;
+ else if (text[1] == 'i')
+ opt = OPTION_i, skip = 0;
+ else if (text[1] == 'l')
+ opt = OPTION_l;
+ else if (text[1] == 'L')
+ opt = OPTION_L, arg = text + 2;
+ else if (text[1] == 'o')
+ opt = OPTION_o;
+ else if ((text[1] == 'S') && (text[2] == '\0'))
+ opt = OPTION_S, skip = 0;
+ else if (text[1] == 'V')
+ opt = OPTION_V, skip = (text[2] == '\0');
+ else if ((text[1] == 'v') && (text[2] == '\0'))
+ opt = OPTION_v, skip = 0;
+ else if (text[1] == 'x')
+ opt = OPTION_x, arg = text + 2;
+ else
+ {
+ if ((skip = WORD_SWITCH_TAKES_ARG (text + 1)) != 0) /* See gcc.c. */
+ ;
+ else if (!strcmp (text, "-fhelp")) /* Really --help!! */
+ opt = OPTION_help;
+ else if (!strcmp (text, "-nostdlib")
+ || !strcmp (text, "-nodefaultlibs"))
+ opt = OPTION_nostdlib;
+ else if (!strcmp (text, "-fsyntax-only"))
+ opt = OPTION_syntax_only;
+ else if (!strcmp (text, "-dumpversion"))
+ opt = OPTION_version;
+ else if (!strcmp (text, "-fversion")) /* Really --version!! */
+ opt = OPTION_version;
+ else if (!strcmp (text, "-Xlinker") || !strcmp (text, "-specs"))
+ skip = 1;
+ else
+ skip = 0;
+ }
+
+ if (xopt != NULL)
+ *xopt = opt;
+ if (xskip != NULL)
+ *xskip = skip;
+ if (xarg != NULL)
+ {
+ if ((arg != NULL) && (arg[0] == '\0'))
+ *xarg = NULL;
+ else
+ *xarg = arg;
+ }
+}
+
+/* Append another argument to the list being built. As long as it is
+ identical to the corresponding arg in the original list, just increment
+ the new arg count. Otherwise allocate a new list, etc. */
+
+static void
+append_arg (const char *arg)
+{
+ static int newargsize;
+
+#if 0
+ fprintf (stderr, "`%s'\n", arg);
+#endif
+
+ if (g77_newargv == g77_xargv
+ && g77_newargc < g77_xargc
+ && (arg == g77_xargv[g77_newargc]
+ || !strcmp (arg, g77_xargv[g77_newargc])))
+ {
+ ++g77_newargc;
+ return; /* Nothing new here. */
+ }
+
+ if (g77_newargv == g77_xargv)
+ { /* Make new arglist. */
+ int i;
+
+ newargsize = (g77_xargc << 2) + 20; /* This should handle all. */
+ g77_newargv = (const char **) xmalloc (newargsize * sizeof (char *));
+
+ /* Copy what has been done so far. */
+ for (i = 0; i < g77_newargc; ++i)
+ g77_newargv[i] = g77_xargv[i];
+ }
+
+ if (g77_newargc == newargsize)
+ fatal ("overflowed output arg list for `%s'", arg);
+
+ g77_newargv[g77_newargc++] = arg;
+}
+
+void
+lang_specific_driver (int *in_argc, const char *const **in_argv,
+ int *in_added_libraries ATTRIBUTE_UNUSED)
+{
+ int argc = *in_argc;
+ const char *const *argv = *in_argv;
+ int i;
+ int verbose = 0;
+ Option opt;
+ int skip;
+ const char *arg;
+
+ /* This will be NULL if we encounter a situation where we should not
+ link in libf2c. */
+ const char *library = FORTRAN_LIBRARY;
+
+ /* 0 => -xnone in effect.
+ 1 => -xfoo in effect. */
+ int saw_speclang = 0;
+
+ /* 0 => initial/reset state
+ 1 => last arg was -l<library>
+ 2 => last two args were -l<library> -lm. */
+ int saw_library = 0;
+
+ /* 0 => initial/reset state
+ 1 => FORTRAN_INIT linked in */
+ int use_init = 0;
+
+ /* By default, we throw on the math library if we have one. */
+ int need_math = (MATH_LIBRARY[0] != '\0');
+
+ /* The number of input and output files in the incoming arg list. */
+ int n_infiles = 0;
+ int n_outfiles = 0;
+
+#if 0
+ fprintf (stderr, "Incoming:");
+ for (i = 0; i < argc; i++)
+ fprintf (stderr, " %s", argv[i]);
+ fprintf (stderr, "\n");
+#endif
+
+ g77_xargc = argc;
+ g77_xargv = argv;
+ g77_newargc = 0;
+ g77_newargv = (const char **) argv;
+
+ /* First pass through arglist.
+
+ If -nostdlib or a "turn-off-linking" option is anywhere in the
+ command line, don't do any library-option processing (except
+ relating to -x). Also, if -v is specified, but no other options
+ that do anything special (allowing -V version, etc.), remember
+ to add special stuff to make gcc command actually invoke all
+ the different phases of the compilation process so all the version
+ numbers can be seen.
+
+ Also, here is where all problems with missing arguments to options
+ are caught. If this loop is exited normally, it means all options
+ have the appropriate number of arguments as far as the rest of this
+ program is concerned. */
+
+ for (i = 1; i < argc; ++i)
+ {
+ if ((argv[i][0] == '+') && (argv[i][1] == 'e'))
+ {
+ continue;
+ }
+
+ if ((argv[i][0] != '-') || (argv[i][1] == '\0'))
+ {
+ ++n_infiles;
+ continue;
+ }
+
+ lookup_option (&opt, &skip, NULL, argv[i]);
+
+ switch (opt)
+ {
+ case OPTION_nostdlib:
+ case OPTION_c:
+ case OPTION_S:
+ case OPTION_syntax_only:
+ case OPTION_E:
+ /* These options disable linking entirely or linking of the
+ standard libraries. */
+ library = 0;
+ break;
+
+ case OPTION_l:
+ ++n_infiles;
+ break;
+
+ case OPTION_o:
+ ++n_outfiles;
+ break;
+
+ case OPTION_v:
+ verbose = 1;
+ break;
+
+ case OPTION_b:
+ case OPTION_B:
+ case OPTION_L:
+ case OPTION_i:
+ case OPTION_V:
+ /* These options are useful in conjunction with -v to get
+ appropriate version info. */
+ break;
+
+ case OPTION_version:
+ printf ("\
+GNU Fortran 95 (GCC %s)\n\
+Copyright (C) 2003 Free Software Foundation, Inc.\n\
+\n\
+GNU Fortran comes with NO WARRANTY, to the extent permitted by law.\n\
+You may redistribute copies of GNU Fortran\n\
+under the terms of the GNU General Public License.\n\
+For more information about these matters, see the file named COPYING\n\
+", version_string);
+ exit (0);
+ break;
+
+ case OPTION_help:
+ /* Let gcc.c handle this, as it has a really
+ cool facility for handling --help and --verbose --help. */
+ return;
+
+ default:
+ break;
+ }
+
+ /* This is the one place we check for missing arguments in the
+ program. */
+
+ if (i + skip < argc)
+ i += skip;
+ else
+ fatal ("argument to `%s' missing", argv[i]);
+ }
+
+ if ((n_outfiles != 0) && (n_infiles == 0))
+ fatal ("no input files; unwilling to write output files");
+
+ /* If there are no input files, no need for the library. */
+ if (n_infiles == 0)
+ library = 0;
+
+ /* Second pass through arglist, transforming arguments as appropriate. */
+
+ append_arg (argv[0]); /* Start with command name, of course. */
+
+ for (i = 1; i < argc; ++i)
+ {
+ if (argv[i][0] == '\0')
+ {
+ append_arg (argv[i]); /* Interesting. Just append as is. */
+ continue;
+ }
+
+ if ((argv[i][0] == '-') && (argv[i][1] == 'M'))
+ {
+ char *p;
+
+ if (argv[i][2] == '\0')
+ {
+ p = xmalloc (strlen (argv[i + 1]) + 2);
+ p[0] = '-';
+ p[1] = 'J';
+ strcpy (&p[2], argv[i + 1]);
+ i++;
+ }
+ else
+ {
+ p = xmalloc (strlen (argv[i]) + 1);
+ strcpy (p, argv[i]);
+ }
+ append_arg (p);
+ continue;
+ }
+
+ if ((argv[i][0] == '-') && (argv[i][1] != 'l'))
+ {
+ /* Not a filename or library. */
+
+ if (saw_library == 1 && need_math) /* -l<library>. */
+ append_arg (MATH_LIBRARY);
+
+ saw_library = 0;
+
+ lookup_option (&opt, &skip, &arg, argv[i]);
+
+ if (argv[i][1] == '\0')
+ {
+ append_arg (argv[i]); /* "-" == Standard input. */
+ continue;
+ }
+
+ if (opt == OPTION_x)
+ {
+ /* Track input language. */
+ const char *lang;
+
+ if (arg == NULL)
+ lang = argv[i + 1];
+ else
+ lang = arg;
+
+ saw_speclang = (strcmp (lang, "none") != 0);
+ }
+
+ append_arg (argv[i]);
+
+ for (; skip != 0; --skip)
+ append_arg (argv[++i]);
+
+ continue;
+ }
+
+ /* A filename/library, not an option. */
+
+ if (saw_speclang)
+ saw_library = 0; /* -xfoo currently active. */
+ else
+ { /* -lfoo or filename. */
+ if (strcmp (argv[i], MATH_LIBRARY) == 0)
+ {
+ if (saw_library == 1)
+ saw_library = 2; /* -l<library> -lm. */
+ else
+ {
+ if (0 == use_init)
+ {
+ append_arg (FORTRAN_INIT);
+ use_init = 1;
+ }
+ append_arg (FORTRAN_LIBRARY);
+ }
+ }
+ else if (strcmp (argv[i], FORTRAN_LIBRARY) == 0)
+ saw_library = 1; /* -l<library>. */
+ else
+ { /* Other library, or filename. */
+ if (saw_library == 1 && need_math)
+ append_arg (MATH_LIBRARY);
+ saw_library = 0;
+ }
+ }
+ append_arg (argv[i]);
+ }
+
+ /* Append `-lg2c -lm' as necessary. */
+
+ if (library)
+ { /* Doing a link and no -nostdlib. */
+ if (saw_speclang)
+ append_arg ("-xnone");
+
+ switch (saw_library)
+ {
+ case 0:
+ if (0 == use_init)
+ {
+ append_arg (FORTRAN_INIT);
+ use_init = 1;
+ }
+ append_arg (library);
+ case 1:
+ if (need_math)
+ append_arg (MATH_LIBRARY);
+ default:
+ break;
+ }
+ }
+
+#ifdef ENABLE_SHARED_LIBGCC
+ if (library)
+ {
+ int i;
+
+ for (i = 1; i < g77_newargc; i++)
+ if (g77_newargv[i][0] == '-')
+ if (strcmp (g77_newargv[i], "-static-libgcc") == 0
+ || strcmp (g77_newargv[i], "-static") == 0)
+ break;
+
+ if (i == g77_newargc)
+ append_arg ("-shared-libgcc");
+ }
+
+#endif
+
+ if (verbose && g77_newargv != g77_xargv)
+ {
+ fprintf (stderr, "Driving:");
+ for (i = 0; i < g77_newargc; i++)
+ fprintf (stderr, " %s", g77_newargv[i]);
+ fprintf (stderr, "\n");
+ }
+
+ *in_argc = g77_newargc;
+ *in_argv = g77_newargv;
+}
+
+/* Called before linking. Returns 0 on success and -1 on failure. */
+int
+lang_specific_pre_link (void) /* Not used for F77. */
+{
+ return 0;
+}
+
+/* Number of extra output files that lang_specific_pre_link may generate. */
+int lang_specific_extra_outfiles = 0; /* Not used for F77. */
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
new file mode 100644
index 00000000000..2610be59899
--- /dev/null
+++ b/gcc/fortran/interface.c
@@ -0,0 +1,1858 @@
+/* Deal with interfaces.
+ Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+/* Deal with interfaces. An explicit interface is represented as a
+ singly linked list of formal argument structures attached to the
+ relevant symbols. For an implicit interface, the arguments don't
+ point to symbols. Explicit interfaces point to namespaces that
+ contain the symbols within that interface.
+
+ Implicit interfaces are linked together in a singly linked list
+ along the next_if member of symbol nodes. Since a particular
+ symbol can only have a single explicit interface, the symbol cannot
+ be part of multiple lists and a single next-member suffices.
+
+ This is not the case for general classes, though. An operator
+ definition is independent of just about all other uses and has it's
+ own head pointer.
+
+ Nameless interfaces:
+ Nameless interfaces create symbols with explicit interfaces within
+ the current namespace. They are otherwise unlinked.
+
+ Generic interfaces:
+ The generic name points to a linked list of symbols. Each symbol
+ has an explicit interface. Each explicit interface has it's own
+ namespace containing the arguments. Module procedures are symbols in
+ which the interface is added later when the module procedure is parsed.
+
+ User operators:
+ User-defined operators are stored in a their own set of symtrees
+ separate from regular symbols. The symtrees point to gfc_user_op
+ structures which in turn head up a list of relevant interfaces.
+
+ Extended intrinsics and assignment:
+ The head of these interface lists are stored in the containing namespace.
+
+ Implicit interfaces:
+ An implicit interface is represented as a singly linked list of
+ formal argument list structures that don't point to any symbol
+ nodes -- they just contain types.
+
+
+ When a subprogram is defined, the program unit's name points to an
+ interface as usual, but the link to the namespace is NULL and the
+ formal argument list points to symbols within the same namespace as
+ the program unit name. */
+
+#include "config.h"
+#include <string.h>
+#include <stdlib.h>
+
+#include "gfortran.h"
+#include "match.h"
+
+
+/* The current_interface structure holds information about the
+ interface currently being parsed. This structure is saved and
+ restored during recursive interfaces. */
+
+gfc_interface_info current_interface;
+
+
+/* Free a singly linked list of gfc_interface structures. */
+
+void
+gfc_free_interface (gfc_interface * intr)
+{
+ gfc_interface *next;
+
+ for (; intr; intr = next)
+ {
+ next = intr->next;
+ gfc_free (intr);
+ }
+}
+
+
+/* Change the operators unary plus and minus into binary plus and
+ minus respectively, leaving the rest unchanged. */
+
+static gfc_intrinsic_op
+fold_unary (gfc_intrinsic_op operator)
+{
+
+ switch (operator)
+ {
+ case INTRINSIC_UPLUS:
+ operator = INTRINSIC_PLUS;
+ break;
+ case INTRINSIC_UMINUS:
+ operator = INTRINSIC_MINUS;
+ break;
+ default:
+ break;
+ }
+
+ return operator;
+}
+
+
+/* Match a generic specification. Depending on which type of
+ interface is found, the 'name' or 'operator' pointers may be set.
+ This subroutine doesn't return MATCH_NO. */
+
+match
+gfc_match_generic_spec (interface_type * type,
+ char *name,
+ gfc_intrinsic_op *operator)
+{
+ char buffer[GFC_MAX_SYMBOL_LEN + 1];
+ match m;
+ gfc_intrinsic_op i;
+
+ if (gfc_match (" assignment ( = )") == MATCH_YES)
+ {
+ *type = INTERFACE_INTRINSIC_OP;
+ *operator = INTRINSIC_ASSIGN;
+ return MATCH_YES;
+ }
+
+ if (gfc_match (" operator ( %o )", &i) == MATCH_YES)
+ { /* Operator i/f */
+ *type = INTERFACE_INTRINSIC_OP;
+ *operator = fold_unary (i);
+ return MATCH_YES;
+ }
+
+ if (gfc_match (" operator ( ") == MATCH_YES)
+ {
+ m = gfc_match_defined_op_name (buffer, 1);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m != MATCH_YES)
+ return MATCH_ERROR;
+
+ m = gfc_match_char (')');
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m != MATCH_YES)
+ return MATCH_ERROR;
+
+ strcpy (name, buffer);
+ *type = INTERFACE_USER_OP;
+ return MATCH_YES;
+ }
+
+ if (gfc_match_name (buffer) == MATCH_YES)
+ {
+ strcpy (name, buffer);
+ *type = INTERFACE_GENERIC;
+ return MATCH_YES;
+ }
+
+ *type = INTERFACE_NAMELESS;
+ return MATCH_YES;
+
+syntax:
+ gfc_error ("Syntax error in generic specification at %C");
+ return MATCH_ERROR;
+}
+
+
+/* Match one of the five forms of an interface statement. */
+
+match
+gfc_match_interface (void)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ interface_type type;
+ gfc_symbol *sym;
+ gfc_intrinsic_op operator;
+ match m;
+
+ m = gfc_match_space ();
+
+ if (gfc_match_generic_spec (&type, name, &operator) == MATCH_ERROR)
+ return MATCH_ERROR;
+
+
+ /* If we're not looking at the end of the statement now, or if this
+ is not a nameless interface but we did not see a space, punt. */
+ if (gfc_match_eos () != MATCH_YES
+ || (type != INTERFACE_NAMELESS
+ && m != MATCH_YES))
+ {
+ gfc_error
+ ("Syntax error: Trailing garbage in INTERFACE statement at %C");
+ return MATCH_ERROR;
+ }
+
+ current_interface.type = type;
+
+ switch (type)
+ {
+ case INTERFACE_GENERIC:
+ if (gfc_get_symbol (name, NULL, &sym))
+ return MATCH_ERROR;
+
+ if (!sym->attr.generic && gfc_add_generic (&sym->attr, NULL) == FAILURE)
+ return MATCH_ERROR;
+
+ current_interface.sym = gfc_new_block = sym;
+ break;
+
+ case INTERFACE_USER_OP:
+ current_interface.uop = gfc_get_uop (name);
+ break;
+
+ case INTERFACE_INTRINSIC_OP:
+ current_interface.op = operator;
+ break;
+
+ case INTERFACE_NAMELESS:
+ break;
+ }
+
+ return MATCH_YES;
+}
+
+
+/* Match the different sort of generic-specs that can be present after
+ the END INTERFACE itself. */
+
+match
+gfc_match_end_interface (void)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ interface_type type;
+ gfc_intrinsic_op operator;
+ match m;
+
+ m = gfc_match_space ();
+
+ if (gfc_match_generic_spec (&type, name, &operator) == MATCH_ERROR)
+ return MATCH_ERROR;
+
+ /* If we're not looking at the end of the statement now, or if this
+ is not a nameless interface but we did not see a space, punt. */
+ if (gfc_match_eos () != MATCH_YES
+ || (type != INTERFACE_NAMELESS
+ && m != MATCH_YES))
+ {
+ gfc_error
+ ("Syntax error: Trailing garbage in END INTERFACE statement at %C");
+ return MATCH_ERROR;
+ }
+
+ m = MATCH_YES;
+
+ switch (current_interface.type)
+ {
+ case INTERFACE_NAMELESS:
+ if (type != current_interface.type)
+ {
+ gfc_error ("Expected a nameless interface at %C");
+ m = MATCH_ERROR;
+ }
+
+ break;
+
+ case INTERFACE_INTRINSIC_OP:
+ if (type != current_interface.type || operator != current_interface.op)
+ {
+
+ if (current_interface.op == INTRINSIC_ASSIGN)
+ gfc_error ("Expected 'END INTERFACE ASSIGNMENT (=)' at %C");
+ else
+ gfc_error ("Expecting 'END INTERFACE OPERATOR (%s)' at %C",
+ gfc_op2string (current_interface.op));
+
+ m = MATCH_ERROR;
+ }
+
+ break;
+
+ case INTERFACE_USER_OP:
+ /* Comparing the symbol node names is OK because only use-associated
+ symbols can be renamed. */
+ if (type != current_interface.type
+ || strcmp (current_interface.sym->name, name) != 0)
+ {
+ gfc_error ("Expecting 'END INTERFACE OPERATOR (.%s.)' at %C",
+ current_interface.sym->name);
+ m = MATCH_ERROR;
+ }
+
+ break;
+
+ case INTERFACE_GENERIC:
+ if (type != current_interface.type
+ || strcmp (current_interface.sym->name, name) != 0)
+ {
+ gfc_error ("Expecting 'END INTERFACE %s' at %C",
+ current_interface.sym->name);
+ m = MATCH_ERROR;
+ }
+
+ break;
+ }
+
+ return m;
+}
+
+
+/* Compare two typespecs, recursively if necessary. */
+
+int
+gfc_compare_types (gfc_typespec * ts1, gfc_typespec * ts2)
+{
+ gfc_component *dt1, *dt2;
+
+ if (ts1->type != ts2->type)
+ return 0;
+ if (ts1->type != BT_DERIVED)
+ return (ts1->kind == ts2->kind);
+
+ /* Compare derived types. */
+ if (ts1->derived == ts2->derived)
+ return 1;
+
+ /* Special case for comparing derived types across namespaces. If the
+ true names and module names are the same and the module name is
+ nonnull, then they are equal. */
+ if (strcmp (ts1->derived->name, ts2->derived->name) == 0
+ && ts1->derived->module[0] != '\0'
+ && strcmp (ts1->derived->module, ts2->derived->module) == 0)
+ return 1;
+
+ /* Compare type via the rules of the standard. Both types must have
+ the SEQUENCE attribute to be equal. */
+
+ if (strcmp (ts1->derived->name, ts2->derived->name))
+ return 0;
+
+ dt1 = ts1->derived->components;
+ dt2 = ts2->derived->components;
+
+ if (ts1->derived->attr.sequence == 0 || ts2->derived->attr.sequence == 0)
+ return 0;
+
+ /* Since subtypes of SEQUENCE types must be SEQUENCE types as well, a
+ simple test can speed things up. Otherwise, lots of things have to
+ match. */
+ for (;;)
+ {
+ if (strcmp (dt1->name, dt2->name) != 0)
+ return 0;
+
+ if (dt1->pointer != dt2->pointer)
+ return 0;
+
+ if (dt1->dimension != dt2->dimension)
+ return 0;
+
+ if (dt1->dimension && gfc_compare_array_spec (dt1->as, dt2->as) == 0)
+ return 0;
+
+ if (gfc_compare_types (&dt1->ts, &dt2->ts) == 0)
+ return 0;
+
+ dt1 = dt1->next;
+ dt2 = dt2->next;
+
+ if (dt1 == NULL && dt2 == NULL)
+ break;
+ if (dt1 == NULL || dt2 == NULL)
+ return 0;
+ }
+
+ return 1;
+}
+
+
+/* Given two symbols that are formal arguments, compare their ranks
+ and types. Returns nonzero if they have the same rank and type,
+ zero otherwise. */
+
+static int
+compare_type_rank (gfc_symbol * s1, gfc_symbol * s2)
+{
+ int r1, r2;
+
+ r1 = (s1->as != NULL) ? s1->as->rank : 0;
+ r2 = (s2->as != NULL) ? s2->as->rank : 0;
+
+ if (r1 != r2)
+ return 0; /* Ranks differ */
+
+ return gfc_compare_types (&s1->ts, &s2->ts);
+}
+
+
+static int compare_interfaces (gfc_symbol *, gfc_symbol *, int);
+
+/* Given two symbols that are formal arguments, compare their types
+ and rank and their formal interfaces if they are both dummy
+ procedures. Returns nonzero if the same, zero if different. */
+
+static int
+compare_type_rank_if (gfc_symbol * s1, gfc_symbol * s2)
+{
+
+ if (s1->attr.flavor != FL_PROCEDURE && s2->attr.flavor != FL_PROCEDURE)
+ return compare_type_rank (s1, s2);
+
+ if (s1->attr.flavor != FL_PROCEDURE || s2->attr.flavor != FL_PROCEDURE)
+ return 0;
+
+ /* At this point, both symbols are procedures. */
+ if ((s1->attr.function == 0 && s1->attr.subroutine == 0)
+ || (s2->attr.function == 0 && s2->attr.subroutine == 0))
+ return 0;
+
+ if (s1->attr.function != s2->attr.function
+ || s1->attr.subroutine != s2->attr.subroutine)
+ return 0;
+
+ if (s1->attr.function && compare_type_rank (s1, s2) == 0)
+ return 0;
+
+ return compare_interfaces (s1, s2, 0); /* Recurse! */
+}
+
+
+/* Given a formal argument list and a keyword name, search the list
+ for that keyword. Returns the correct symbol node if found, NULL
+ if not found. */
+
+static gfc_symbol *
+find_keyword_arg (const char *name, gfc_formal_arglist * f)
+{
+
+ for (; f; f = f->next)
+ if (strcmp (f->sym->name, name) == 0)
+ return f->sym;
+
+ return NULL;
+}
+
+
+/******** Interface checking subroutines **********/
+
+
+/* Given an operator interface and the operator, make sure that all
+ interfaces for that operator are legal. */
+
+static void
+check_operator_interface (gfc_interface * intr, gfc_intrinsic_op operator)
+{
+ gfc_formal_arglist *formal;
+ sym_intent i1, i2;
+ gfc_symbol *sym;
+ bt t1, t2;
+ int args;
+
+ if (intr == NULL)
+ return;
+
+ args = 0;
+ t1 = t2 = BT_UNKNOWN;
+ i1 = i2 = INTENT_UNKNOWN;
+
+ for (formal = intr->sym->formal; formal; formal = formal->next)
+ {
+ sym = formal->sym;
+
+ if (args == 0)
+ {
+ t1 = sym->ts.type;
+ i1 = sym->attr.intent;
+ }
+ if (args == 1)
+ {
+ t2 = sym->ts.type;
+ i2 = sym->attr.intent;
+ }
+ args++;
+ }
+
+ if (args == 0 || args > 2)
+ goto num_args;
+
+ sym = intr->sym;
+
+ if (operator == INTRINSIC_ASSIGN)
+ {
+ if (!sym->attr.subroutine)
+ {
+ gfc_error
+ ("Assignment operator interface at %L must be a SUBROUTINE",
+ &intr->where);
+ return;
+ }
+ }
+ else
+ {
+ if (!sym->attr.function)
+ {
+ gfc_error ("Intrinsic operator interface at %L must be a FUNCTION",
+ &intr->where);
+ return;
+ }
+ }
+
+ switch (operator)
+ {
+ case INTRINSIC_PLUS: /* Numeric unary or binary */
+ case INTRINSIC_MINUS:
+ if ((args == 1)
+ && (t1 == BT_INTEGER
+ || t1 == BT_REAL
+ || t1 == BT_COMPLEX))
+ goto bad_repl;
+
+ if ((args == 2)
+ && (t1 == BT_INTEGER || t1 == BT_REAL || t1 == BT_COMPLEX)
+ && (t2 == BT_INTEGER || t2 == BT_REAL || t2 == BT_COMPLEX))
+ goto bad_repl;
+
+ break;
+
+ case INTRINSIC_POWER: /* Binary numeric */
+ case INTRINSIC_TIMES:
+ case INTRINSIC_DIVIDE:
+
+ case INTRINSIC_EQ:
+ case INTRINSIC_NE:
+ if (args == 1)
+ goto num_args;
+
+ if ((t1 == BT_INTEGER || t1 == BT_REAL || t1 == BT_COMPLEX)
+ && (t2 == BT_INTEGER || t2 == BT_REAL || t2 == BT_COMPLEX))
+ goto bad_repl;
+
+ break;
+
+ case INTRINSIC_GE: /* Binary numeric operators that do not support */
+ case INTRINSIC_LE: /* complex numbers */
+ case INTRINSIC_LT:
+ case INTRINSIC_GT:
+ if (args == 1)
+ goto num_args;
+
+ if ((t1 == BT_INTEGER || t1 == BT_REAL)
+ && (t2 == BT_INTEGER || t2 == BT_REAL))
+ goto bad_repl;
+
+ break;
+
+ case INTRINSIC_OR: /* Binary logical */
+ case INTRINSIC_AND:
+ case INTRINSIC_EQV:
+ case INTRINSIC_NEQV:
+ if (args == 1)
+ goto num_args;
+ if (t1 == BT_LOGICAL && t2 == BT_LOGICAL)
+ goto bad_repl;
+ break;
+
+ case INTRINSIC_NOT: /* Unary logical */
+ if (args != 1)
+ goto num_args;
+ if (t1 == BT_LOGICAL)
+ goto bad_repl;
+ break;
+
+ case INTRINSIC_CONCAT: /* Binary string */
+ if (args != 2)
+ goto num_args;
+ if (t1 == BT_CHARACTER && t2 == BT_CHARACTER)
+ goto bad_repl;
+ break;
+
+ case INTRINSIC_ASSIGN: /* Class by itself */
+ if (args != 2)
+ goto num_args;
+ break;
+ default:
+ gfc_internal_error ("check_operator_interface(): Bad operator");
+ }
+
+ /* Check intents on operator interfaces. */
+ if (operator == INTRINSIC_ASSIGN)
+ {
+ if (i1 != INTENT_OUT && i1 != INTENT_INOUT)
+ gfc_error ("First argument of defined assignment at %L must be "
+ "INTENT(IN) or INTENT(INOUT)", &intr->where);
+
+ if (i2 != INTENT_IN)
+ gfc_error ("Second argument of defined assignment at %L must be "
+ "INTENT(IN)", &intr->where);
+ }
+ else
+ {
+ if (i1 != INTENT_IN)
+ gfc_error ("First argument of operator interface at %L must be "
+ "INTENT(IN)", &intr->where);
+
+ if (args == 2 && i2 != INTENT_IN)
+ gfc_error ("Second argument of operator interface at %L must be "
+ "INTENT(IN)", &intr->where);
+ }
+
+ return;
+
+bad_repl:
+ gfc_error ("Operator interface at %L conflicts with intrinsic interface",
+ &intr->where);
+ return;
+
+num_args:
+ gfc_error ("Operator interface at %L has the wrong number of arguments",
+ &intr->where);
+ return;
+}
+
+
+/* Given a pair of formal argument lists, we see if the two lists can
+ be distinguished by counting the number of nonoptional arguments of
+ a given type/rank in f1 and seeing if there are less then that
+ number of those arguments in f2 (including optional arguments).
+ Since this test is asymmetric, it has to be called twice to make it
+ symmetric. Returns nonzero if the argument lists are incompatible
+ by this test. This subroutine implements rule 1 of section
+ 14.1.2.3. */
+
+static int
+count_types_test (gfc_formal_arglist * f1, gfc_formal_arglist * f2)
+{
+ int rc, ac1, ac2, i, j, k, n1;
+ gfc_formal_arglist *f;
+
+ typedef struct
+ {
+ int flag;
+ gfc_symbol *sym;
+ }
+ arginfo;
+
+ arginfo *arg;
+
+ n1 = 0;
+
+ for (f = f1; f; f = f->next)
+ n1++;
+
+ /* Build an array of integers that gives the same integer to
+ arguments of the same type/rank. */
+ arg = gfc_getmem (n1 * sizeof (arginfo));
+
+ f = f1;
+ for (i = 0; i < n1; i++, f = f->next)
+ {
+ arg[i].flag = -1;
+ arg[i].sym = f->sym;
+ }
+
+ k = 0;
+
+ for (i = 0; i < n1; i++)
+ {
+ if (arg[i].flag != -1)
+ continue;
+
+ if (arg[i].sym->attr.optional)
+ continue; /* Skip optional arguments */
+
+ arg[i].flag = k;
+
+ /* Find other nonoptional arguments of the same type/rank. */
+ for (j = i + 1; j < n1; j++)
+ if (!arg[j].sym->attr.optional
+ && compare_type_rank_if (arg[i].sym, arg[j].sym))
+ arg[j].flag = k;
+
+ k++;
+ }
+
+ /* Now loop over each distinct type found in f1. */
+ k = 0;
+ rc = 0;
+
+ for (i = 0; i < n1; i++)
+ {
+ if (arg[i].flag != k)
+ continue;
+
+ ac1 = 1;
+ for (j = i + 1; j < n1; j++)
+ if (arg[j].flag == k)
+ ac1++;
+
+ /* Count the number of arguments in f2 with that type, including
+ those that are optional. */
+ ac2 = 0;
+
+ for (f = f2; f; f = f->next)
+ if (compare_type_rank_if (arg[i].sym, f->sym))
+ ac2++;
+
+ if (ac1 > ac2)
+ {
+ rc = 1;
+ break;
+ }
+
+ k++;
+ }
+
+ gfc_free (arg);
+
+ return rc;
+}
+
+
+/* Perform the abbreviated correspondence test for operators. The
+ arguments cannot be optional and are always ordered correctly,
+ which makes this test much easier than that for generic tests.
+
+ This subroutine is also used when comparing a formal and actual
+ argument list when an actual parameter is a dummy procedure. At
+ that point, two formal interfaces must be compared for equality
+ which is what happens here. */
+
+static int
+operator_correspondence (gfc_formal_arglist * f1, gfc_formal_arglist * f2)
+{
+ for (;;)
+ {
+ if (f1 == NULL && f2 == NULL)
+ break;
+ if (f1 == NULL || f2 == NULL)
+ return 1;
+
+ if (!compare_type_rank (f1->sym, f2->sym))
+ return 1;
+
+ f1 = f1->next;
+ f2 = f2->next;
+ }
+
+ return 0;
+}
+
+
+/* Perform the correspondence test in rule 2 of section 14.1.2.3.
+ Returns zero if no argument is found that satisifes rule 2, nonzero
+ otherwise.
+
+ This test is also not symmetric in f1 and f2 and must be called
+ twice. This test finds problems caused by sorting the actual
+ argument list with keywords. For example:
+
+ INTERFACE FOO
+ SUBROUTINE F1(A, B)
+ INTEGER :: A ; REAL :: B
+ END SUBROUTINE F1
+
+ SUBROUTINE F2(B, A)
+ INTEGER :: A ; REAL :: B
+ END SUBROUTINE F1
+ END INTERFACE FOO
+
+ At this point, 'CALL FOO(A=1, B=1.0)' is ambiguous. */
+
+static int
+generic_correspondence (gfc_formal_arglist * f1, gfc_formal_arglist * f2)
+{
+
+ gfc_formal_arglist *f2_save, *g;
+ gfc_symbol *sym;
+
+ f2_save = f2;
+
+ while (f1)
+ {
+ if (f1->sym->attr.optional)
+ goto next;
+
+ if (f2 != NULL && compare_type_rank (f1->sym, f2->sym))
+ goto next;
+
+ /* Now search for a disambiguating keyword argument starting at
+ the current non-match. */
+ for (g = f1; g; g = g->next)
+ {
+ if (g->sym->attr.optional)
+ continue;
+
+ sym = find_keyword_arg (g->sym->name, f2_save);
+ if (sym == NULL || !compare_type_rank (g->sym, sym))
+ return 1;
+ }
+
+ next:
+ f1 = f1->next;
+ if (f2 != NULL)
+ f2 = f2->next;
+ }
+
+ return 0;
+}
+
+
+/* 'Compare' two formal interfaces associated with a pair of symbols.
+ We return nonzero if there exists an actual argument list that
+ would be ambiguous between the two interfaces, zero otherwise. */
+
+static int
+compare_interfaces (gfc_symbol * s1, gfc_symbol * s2, int generic_flag)
+{
+ gfc_formal_arglist *f1, *f2;
+
+ if (s1->attr.function != s2->attr.function
+ && s1->attr.subroutine != s2->attr.subroutine)
+ return 0; /* disagreement between function/subroutine */
+
+ f1 = s1->formal;
+ f2 = s2->formal;
+
+ if (f1 == NULL && f2 == NULL)
+ return 1; /* Special case */
+
+ if (count_types_test (f1, f2))
+ return 0;
+ if (count_types_test (f2, f1))
+ return 0;
+
+ if (generic_flag)
+ {
+ if (generic_correspondence (f1, f2))
+ return 0;
+ if (generic_correspondence (f2, f1))
+ return 0;
+ }
+ else
+ {
+ if (operator_correspondence (f1, f2))
+ return 0;
+ }
+
+ return 1;
+}
+
+
+/* Given a pointer to an interface pointer, remove duplicate
+ interfaces and make sure that all symbols are either functions or
+ subroutines. Returns nonzero if something goes wrong. */
+
+static int
+check_interface0 (gfc_interface * p, const char *interface_name)
+{
+ gfc_interface *psave, *q, *qlast;
+
+ psave = p;
+ /* Make sure all symbols in the interface have been defined as
+ functions or subroutines. */
+ for (; p; p = p->next)
+ if (!p->sym->attr.function && !p->sym->attr.subroutine)
+ {
+ gfc_error ("Procedure '%s' in %s at %L is neither function nor "
+ "subroutine", p->sym->name, interface_name,
+ &p->sym->declared_at);
+ return 1;
+ }
+ p = psave;
+
+ /* Remove duplicate interfaces in this interface list. */
+ for (; p; p = p->next)
+ {
+ qlast = p;
+
+ for (q = p->next; q;)
+ {
+ if (p->sym != q->sym)
+ {
+ qlast = q;
+ q = q->next;
+
+ }
+ else
+ {
+ /* Duplicate interface */
+ qlast->next = q->next;
+ gfc_free (q);
+ q = qlast->next;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+/* Check lists of interfaces to make sure that no two interfaces are
+ ambiguous. Duplicate interfaces (from the same symbol) are OK
+ here. */
+
+static int
+check_interface1 (gfc_interface * p, gfc_interface * q,
+ int generic_flag, const char *interface_name)
+{
+
+ for (; p; p = p->next)
+ for (; q; q = q->next)
+ {
+ if (p->sym == q->sym)
+ continue; /* Duplicates OK here */
+
+ if (strcmp (p->sym->name, q->sym->name) == 0
+ && strcmp (p->sym->module, q->sym->module) == 0)
+ continue;
+
+ if (compare_interfaces (p->sym, q->sym, generic_flag))
+ {
+ gfc_error ("Ambiguous interfaces '%s' and '%s' in %s at %L",
+ p->sym->name, q->sym->name, interface_name, &p->where);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+
+/* Check the generic and operator interfaces of symbols to make sure
+ that none of the interfaces conflict. The check has to be done
+ after all of the symbols are actually loaded. */
+
+static void
+check_sym_interfaces (gfc_symbol * sym)
+{
+ char interface_name[100];
+ gfc_symbol *s2;
+
+ if (sym->ns != gfc_current_ns)
+ return;
+
+ if (sym->generic != NULL)
+ {
+ sprintf (interface_name, "generic interface '%s'", sym->name);
+ if (check_interface0 (sym->generic, interface_name))
+ return;
+
+ s2 = sym;
+ while (s2 != NULL)
+ {
+ if (check_interface1 (sym->generic, s2->generic, 1, interface_name))
+ return;
+
+ if (s2->ns->parent == NULL)
+ break;
+ if (gfc_find_symbol (sym->name, s2->ns->parent, 1, &s2))
+ break;
+ }
+ }
+}
+
+
+static void
+check_uop_interfaces (gfc_user_op * uop)
+{
+ char interface_name[100];
+ gfc_user_op *uop2;
+ gfc_namespace *ns;
+
+ sprintf (interface_name, "operator interface '%s'", uop->name);
+ if (check_interface0 (uop->operator, interface_name))
+ return;
+
+ for (ns = gfc_current_ns; ns; ns = ns->parent)
+ {
+ uop2 = gfc_find_uop (uop->name, ns);
+ if (uop2 == NULL)
+ continue;
+
+ check_interface1 (uop->operator, uop2->operator, 0, interface_name);
+ }
+}
+
+
+/* For the namespace, check generic, user operator and intrinsic
+ operator interfaces for consistency and to remove duplicate
+ interfaces. We traverse the whole namespace, counting on the fact
+ that most symbols will not have generic or operator interfaces. */
+
+void
+gfc_check_interfaces (gfc_namespace * ns)
+{
+ gfc_namespace *old_ns, *ns2;
+ char interface_name[100];
+ gfc_intrinsic_op i;
+
+ old_ns = gfc_current_ns;
+ gfc_current_ns = ns;
+
+ gfc_traverse_ns (ns, check_sym_interfaces);
+
+ gfc_traverse_user_op (ns, check_uop_interfaces);
+
+ for (i = GFC_INTRINSIC_BEGIN; i != GFC_INTRINSIC_END; i++)
+ {
+ if (i == INTRINSIC_USER)
+ continue;
+
+ if (i == INTRINSIC_ASSIGN)
+ strcpy (interface_name, "intrinsic assignment operator");
+ else
+ sprintf (interface_name, "intrinsic '%s' operator",
+ gfc_op2string (i));
+
+ if (check_interface0 (ns->operator[i], interface_name))
+ continue;
+
+ check_operator_interface (ns->operator[i], i);
+
+ for (ns2 = ns->parent; ns2; ns2 = ns2->parent)
+ if (check_interface1 (ns->operator[i], ns2->operator[i], 0,
+ interface_name))
+ break;
+ }
+
+ gfc_current_ns = old_ns;
+}
+
+
+static int
+symbol_rank (gfc_symbol * sym)
+{
+
+ return (sym->as == NULL) ? 0 : sym->as->rank;
+}
+
+
+/* Given a symbol of a formal argument list and an expression, if the
+ formal argument is a pointer, see if the actual argument is a
+ pointer. Returns nonzero if compatible, zero if not compatible. */
+
+static int
+compare_pointer (gfc_symbol * formal, gfc_expr * actual)
+{
+ symbol_attribute attr;
+
+ if (formal->attr.pointer)
+ {
+ attr = gfc_expr_attr (actual);
+ if (!attr.pointer)
+ return 0;
+ }
+
+ return 1;
+}
+
+
+/* Given a symbol of a formal argument list and an expression, see if
+ the two are compatible as arguments. Returns nonzero if
+ compatible, zero if not compatible. */
+
+static int
+compare_parameter (gfc_symbol * formal, gfc_expr * actual,
+ int ranks_must_agree, int is_elemental)
+{
+ gfc_ref *ref;
+
+ if (actual->ts.type == BT_PROCEDURE)
+ {
+ if (formal->attr.flavor != FL_PROCEDURE)
+ return 0;
+
+ if (formal->attr.function
+ && !compare_type_rank (formal, actual->symtree->n.sym))
+ return 0;
+
+ if (formal->attr.if_source == IFSRC_UNKNOWN)
+ return 1; /* Assume match */
+
+ return compare_interfaces (formal, actual->symtree->n.sym, 0);
+ }
+
+ if (!gfc_compare_types (&formal->ts, &actual->ts))
+ return 0;
+
+ if (symbol_rank (formal) == actual->rank)
+ return 1;
+
+ /* At this point the ranks didn't agree. */
+ if (ranks_must_agree || formal->attr.pointer)
+ return 0;
+
+ if (actual->rank != 0)
+ return is_elemental || formal->attr.dimension;
+
+ /* At this point, we are considering a scalar passed to an array.
+ This is legal if the scalar is an array element of the right sort. */
+ if (formal->as->type == AS_ASSUMED_SHAPE)
+ return 0;
+
+ for (ref = actual->ref; ref; ref = ref->next)
+ if (ref->type == REF_SUBSTRING)
+ return 0;
+
+ for (ref = actual->ref; ref; ref = ref->next)
+ if (ref->type == REF_ARRAY && ref->u.ar.type == AR_ELEMENT)
+ break;
+
+ if (ref == NULL)
+ return 0; /* Not an array element */
+
+ return 1;
+}
+
+
+/* Given formal and actual argument lists, see if they are compatible.
+ If they are compatible, the actual argument list is sorted to
+ correspond with the formal list, and elements for missing optional
+ arguments are inserted. If WHERE pointer is nonnull, then we issue
+ errors when things don't match instead of just returning the status
+ code. */
+
+static int
+compare_actual_formal (gfc_actual_arglist ** ap,
+ gfc_formal_arglist * formal,
+ int ranks_must_agree, int is_elemental, locus * where)
+{
+ gfc_actual_arglist **new, *a, *actual, temp;
+ gfc_formal_arglist *f;
+ int i, n, na;
+
+ actual = *ap;
+
+ if (actual == NULL && formal == NULL)
+ return 1;
+
+ n = 0;
+ for (f = formal; f; f = f->next)
+ n++;
+
+ new = (gfc_actual_arglist **) alloca (n * sizeof (gfc_actual_arglist *));
+
+ for (i = 0; i < n; i++)
+ new[i] = NULL;
+
+ na = 0;
+ f = formal;
+ i = 0;
+
+ for (a = actual; a; a = a->next, f = f->next)
+ {
+ if (a->name[0] != '\0')
+ {
+ i = 0;
+ for (f = formal; f; f = f->next, i++)
+ {
+ if (f->sym == NULL)
+ continue;
+ if (strcmp (f->sym->name, a->name) == 0)
+ break;
+ }
+
+ if (f == NULL)
+ {
+ if (where)
+ gfc_error
+ ("Keyword argument '%s' at %L is not in the procedure",
+ a->name, &a->expr->where);
+ return 0;
+ }
+
+ if (new[i] != NULL)
+ {
+ if (where)
+ gfc_error
+ ("Keyword argument '%s' at %L is already associated "
+ "with another actual argument", a->name, &a->expr->where);
+ return 0;
+ }
+ }
+
+ if (f == NULL)
+ {
+ if (where)
+ gfc_error
+ ("More actual than formal arguments in procedure call at %L",
+ where);
+
+ return 0;
+ }
+
+ if (f->sym == NULL && a->expr == NULL)
+ goto match;
+
+ if (f->sym == NULL)
+ {
+ if (where)
+ gfc_error
+ ("Missing alternate return spec in subroutine call at %L",
+ where);
+ return 0;
+ }
+
+ if (a->expr == NULL)
+ {
+ if (where)
+ gfc_error
+ ("Unexpected alternate return spec in subroutine call at %L",
+ where);
+ return 0;
+ }
+
+ if (!compare_parameter
+ (f->sym, a->expr, ranks_must_agree, is_elemental))
+ {
+ if (where)
+ gfc_error ("Type/rank mismatch in argument '%s' at %L",
+ f->sym->name, &a->expr->where);
+ return 0;
+ }
+
+ if (compare_pointer (f->sym, a->expr) == 0)
+ {
+ if (where)
+ gfc_error ("Actual argument for '%s' must be a pointer at %L",
+ f->sym->name, &a->expr->where);
+ return 0;
+ }
+
+ match:
+ if (a == actual)
+ na = i;
+
+ new[i++] = a;
+ }
+
+ /* Make sure missing actual arguments are optional. */
+ i = 0;
+ for (f = formal; f; f = f->next, i++)
+ {
+ if (new[i] != NULL)
+ continue;
+ if (!f->sym->attr.optional)
+ {
+ if (where)
+ gfc_error ("Missing actual argument for argument '%s' at %L",
+ f->sym->name, where);
+ return 0;
+ }
+ }
+
+ /* The argument lists are compatible. We now relink a new actual
+ argument list with null arguments in the right places. The head
+ of the list remains the head. */
+ for (i = 0; i < n; i++)
+ if (new[i] == NULL)
+ new[i] = gfc_get_actual_arglist ();
+
+ if (na != 0)
+ {
+ temp = *new[0];
+ *new[0] = *actual;
+ *actual = temp;
+
+ a = new[0];
+ new[0] = new[na];
+ new[na] = a;
+ }
+
+ for (i = 0; i < n - 1; i++)
+ new[i]->next = new[i + 1];
+
+ new[i]->next = NULL;
+
+ if (*ap == NULL && n > 0)
+ *ap = new[0];
+
+ return 1;
+}
+
+
+typedef struct
+{
+ gfc_formal_arglist *f;
+ gfc_actual_arglist *a;
+}
+argpair;
+
+/* qsort comparison function for argument pairs, with the following
+ order:
+ - p->a->expr == NULL
+ - p->a->expr->expr_type != EXPR_VARIABLE
+ - growing p->a->expr->symbol. */
+
+static int
+pair_cmp (const void *p1, const void *p2)
+{
+ const gfc_actual_arglist *a1, *a2;
+
+ /* *p1 and *p2 are elements of the to-be-sorted array. */
+ a1 = ((const argpair *) p1)->a;
+ a2 = ((const argpair *) p2)->a;
+ if (!a1->expr)
+ {
+ if (!a2->expr)
+ return 0;
+ return -1;
+ }
+ if (!a2->expr)
+ return 1;
+ if (a1->expr->expr_type != EXPR_VARIABLE)
+ {
+ if (a2->expr->expr_type != EXPR_VARIABLE)
+ return 0;
+ return -1;
+ }
+ if (a2->expr->expr_type != EXPR_VARIABLE)
+ return 1;
+ return a1->expr->symtree->n.sym < a2->expr->symtree->n.sym;
+}
+
+
+/* Given two expressions from some actual arguments, test whether they
+ refer to the same expression. The analysis is conservative.
+ Returning FAILURE will produce no warning. */
+
+static try
+compare_actual_expr (gfc_expr * e1, gfc_expr * e2)
+{
+ const gfc_ref *r1, *r2;
+
+ if (!e1 || !e2
+ || e1->expr_type != EXPR_VARIABLE
+ || e2->expr_type != EXPR_VARIABLE
+ || e1->symtree->n.sym != e2->symtree->n.sym)
+ return FAILURE;
+
+ /* TODO: improve comparison, see expr.c:show_ref(). */
+ for (r1 = e1->ref, r2 = e2->ref; r1 && r2; r1 = r1->next, r2 = r2->next)
+ {
+ if (r1->type != r2->type)
+ return FAILURE;
+ switch (r1->type)
+ {
+ case REF_ARRAY:
+ if (r1->u.ar.type != r2->u.ar.type)
+ return FAILURE;
+ /* TODO: At the moment, consider only full arrays;
+ we could do better. */
+ if (r1->u.ar.type != AR_FULL || r2->u.ar.type != AR_FULL)
+ return FAILURE;
+ break;
+
+ case REF_COMPONENT:
+ if (r1->u.c.component != r2->u.c.component)
+ return FAILURE;
+ break;
+
+ case REF_SUBSTRING:
+ return FAILURE;
+
+ default:
+ gfc_internal_error ("compare_actual_expr(): Bad component code");
+ }
+ }
+ if (!r1 && !r2)
+ return SUCCESS;
+ return FAILURE;
+}
+
+/* Given formal and actual argument lists that correspond to one
+ another, check that identical actual arguments aren't not
+ associated with some incompatible INTENTs. */
+
+static try
+check_some_aliasing (gfc_formal_arglist * f, gfc_actual_arglist * a)
+{
+ sym_intent f1_intent, f2_intent;
+ gfc_formal_arglist *f1;
+ gfc_actual_arglist *a1;
+ size_t n, i, j;
+ argpair *p;
+ try t = SUCCESS;
+
+ n = 0;
+ for (f1 = f, a1 = a;; f1 = f1->next, a1 = a1->next)
+ {
+ if (f1 == NULL && a1 == NULL)
+ break;
+ if (f1 == NULL || a1 == NULL)
+ gfc_internal_error ("check_some_aliasing(): List mismatch");
+ n++;
+ }
+ if (n == 0)
+ return t;
+ p = (argpair *) alloca (n * sizeof (argpair));
+
+ for (i = 0, f1 = f, a1 = a; i < n; i++, f1 = f1->next, a1 = a1->next)
+ {
+ p[i].f = f1;
+ p[i].a = a1;
+ }
+
+ qsort (p, n, sizeof (argpair), pair_cmp);
+
+ for (i = 0; i < n; i++)
+ {
+ if (!p[i].a->expr
+ || p[i].a->expr->expr_type != EXPR_VARIABLE
+ || p[i].a->expr->ts.type == BT_PROCEDURE)
+ continue;
+ f1_intent = p[i].f->sym->attr.intent;
+ for (j = i + 1; j < n; j++)
+ {
+ /* Expected order after the sort. */
+ if (!p[j].a->expr || p[j].a->expr->expr_type != EXPR_VARIABLE)
+ gfc_internal_error ("check_some_aliasing(): corrupted data");
+
+ /* Are the expression the same? */
+ if (compare_actual_expr (p[i].a->expr, p[j].a->expr) == FAILURE)
+ break;
+ f2_intent = p[j].f->sym->attr.intent;
+ if ((f1_intent == INTENT_IN && f2_intent == INTENT_OUT)
+ || (f1_intent == INTENT_OUT && f2_intent == INTENT_IN))
+ {
+ gfc_warning ("Same actual argument associated with INTENT(%s) "
+ "argument '%s' and INTENT(%s) argument '%s' at %L",
+ gfc_intent_string (f1_intent), p[i].f->sym->name,
+ gfc_intent_string (f2_intent), p[j].f->sym->name,
+ &p[i].a->expr->where);
+ t = FAILURE;
+ }
+ }
+ }
+
+ return t;
+}
+
+
+/* Given formal and actual argument lists that correspond to one
+ another, check that they are compatible in the sense that intents
+ are not mismatched. */
+
+static try
+check_intents (gfc_formal_arglist * f, gfc_actual_arglist * a)
+{
+ sym_intent a_intent, f_intent;
+
+ for (;; f = f->next, a = a->next)
+ {
+ if (f == NULL && a == NULL)
+ break;
+ if (f == NULL || a == NULL)
+ gfc_internal_error ("check_intents(): List mismatch");
+
+ if (a->expr == NULL || a->expr->expr_type != EXPR_VARIABLE)
+ continue;
+
+ a_intent = a->expr->symtree->n.sym->attr.intent;
+ f_intent = f->sym->attr.intent;
+
+ if (a_intent == INTENT_IN
+ && (f_intent == INTENT_INOUT
+ || f_intent == INTENT_OUT))
+ {
+
+ gfc_error ("Procedure argument at %L is INTENT(IN) while interface "
+ "specifies INTENT(%s)", &a->expr->where,
+ gfc_intent_string (f_intent));
+ return FAILURE;
+ }
+
+ if (gfc_pure (NULL) && gfc_impure_variable (a->expr->symtree->n.sym))
+ {
+ if (f_intent == INTENT_INOUT || f_intent == INTENT_OUT)
+ {
+ gfc_error
+ ("Procedure argument at %L is local to a PURE procedure and "
+ "is passed to an INTENT(%s) argument", &a->expr->where,
+ gfc_intent_string (f_intent));
+ return FAILURE;
+ }
+
+ if (a->expr->symtree->n.sym->attr.pointer)
+ {
+ gfc_error
+ ("Procedure argument at %L is local to a PURE procedure and "
+ "has the POINTER attribute", &a->expr->where);
+ return FAILURE;
+ }
+ }
+ }
+
+ return SUCCESS;
+}
+
+
+/* Check how a procedure is used against its interface. If all goes
+ well, the actual argument list will also end up being properly
+ sorted. */
+
+void
+gfc_procedure_use (gfc_symbol * sym, gfc_actual_arglist ** ap, locus * where)
+{
+ /* Warn about calls with an implicit interface. */
+ if (gfc_option.warn_implicit_interface
+ && sym->attr.if_source == IFSRC_UNKNOWN)
+ gfc_warning ("Procedure '%s' called with an implicit interface at %L",
+ sym->name, where);
+
+ if (sym->attr.if_source == IFSRC_UNKNOWN
+ || !compare_actual_formal (ap, sym->formal, 0,
+ sym->attr.elemental, where))
+ return;
+
+ check_intents (sym->formal, *ap);
+ if (gfc_option.warn_aliasing)
+ check_some_aliasing (sym->formal, *ap);
+}
+
+
+/* Given an interface pointer and an actual argument list, search for
+ a formal argument list that matches the actual. If found, returns
+ a pointer to the symbol of the correct interface. Returns NULL if
+ not found. */
+
+gfc_symbol *
+gfc_search_interface (gfc_interface * intr, int sub_flag,
+ gfc_actual_arglist ** ap)
+{
+ int r;
+
+ for (; intr; intr = intr->next)
+ {
+ if (sub_flag && intr->sym->attr.function)
+ continue;
+ if (!sub_flag && intr->sym->attr.subroutine)
+ continue;
+
+ r = !intr->sym->attr.elemental;
+
+ if (compare_actual_formal (ap, intr->sym->formal, r, !r, NULL))
+ {
+ check_intents (intr->sym->formal, *ap);
+ if (gfc_option.warn_aliasing)
+ check_some_aliasing (intr->sym->formal, *ap);
+ return intr->sym;
+ }
+ }
+
+ return NULL;
+}
+
+
+/* Do a brute force recursive search for a symbol. */
+
+static gfc_symtree *
+find_symtree0 (gfc_symtree * root, gfc_symbol * sym)
+{
+ gfc_symtree * st;
+
+ if (root->n.sym == sym)
+ return root;
+
+ st = NULL;
+ if (root->left)
+ st = find_symtree0 (root->left, sym);
+ if (root->right && ! st)
+ st = find_symtree0 (root->right, sym);
+ return st;
+}
+
+
+/* Find a symtree for a symbol. */
+
+static gfc_symtree *
+find_sym_in_symtree (gfc_symbol * sym)
+{
+ gfc_symtree *st;
+ gfc_namespace *ns;
+
+ /* First try to find it by name. */
+ gfc_find_sym_tree (sym->name, gfc_current_ns, 1, &st);
+ if (st && st->n.sym == sym)
+ return st;
+
+ /* if it's been renamed, resort to a brute-force search. */
+ /* TODO: avoid having to do this search. If the symbol doesn't exist
+ in the symtree for the current namespace, it should probably be added. */
+ for (ns = gfc_current_ns; ns; ns = ns->parent)
+ {
+ st = find_symtree0 (ns->sym_root, sym);
+ if (st)
+ return st;
+ }
+ gfc_internal_error ("Unable to find symbol %s", sym->name);
+ /* Not reached */
+}
+
+
+/* This subroutine is called when an expression is being resolved.
+ The expression node in question is either a user defined operator
+ or an instrinsic operator with arguments that aren't compatible
+ with the operator. This subroutine builds an actual argument list
+ corresponding to the operands, then searches for a compatible
+ interface. If one is found, the expression node is replaced with
+ the appropriate function call. */
+
+try
+gfc_extend_expr (gfc_expr * e)
+{
+ gfc_actual_arglist *actual;
+ gfc_symbol *sym;
+ gfc_namespace *ns;
+ gfc_user_op *uop;
+ gfc_intrinsic_op i;
+
+ sym = NULL;
+
+ actual = gfc_get_actual_arglist ();
+ actual->expr = e->op1;
+
+ if (e->op2 != NULL)
+ {
+ actual->next = gfc_get_actual_arglist ();
+ actual->next->expr = e->op2;
+ }
+
+ i = fold_unary (e->operator);
+
+ if (i == INTRINSIC_USER)
+ {
+ for (ns = gfc_current_ns; ns; ns = ns->parent)
+ {
+ uop = gfc_find_uop (e->uop->name, ns);
+ if (uop == NULL)
+ continue;
+
+ sym = gfc_search_interface (uop->operator, 0, &actual);
+ if (sym != NULL)
+ break;
+ }
+ }
+ else
+ {
+ for (ns = gfc_current_ns; ns; ns = ns->parent)
+ {
+ sym = gfc_search_interface (ns->operator[i], 0, &actual);
+ if (sym != NULL)
+ break;
+ }
+ }
+
+ if (sym == NULL)
+ {
+ /* Don't use gfc_free_actual_arglist() */
+ if (actual->next != NULL)
+ gfc_free (actual->next);
+ gfc_free (actual);
+
+ return FAILURE;
+ }
+
+ /* Change the expression node to a function call. */
+ e->expr_type = EXPR_FUNCTION;
+ e->symtree = find_sym_in_symtree (sym);
+ e->value.function.actual = actual;
+
+ if (gfc_pure (NULL) && !gfc_pure (sym))
+ {
+ gfc_error
+ ("Function '%s' called in lieu of an operator at %L must be PURE",
+ sym->name, &e->where);
+ return FAILURE;
+ }
+
+ if (gfc_resolve_expr (e) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+/* Tries to replace an assignment code node with a subroutine call to
+ the subroutine associated with the assignment operator. Return
+ SUCCESS if the node was replaced. On FAILURE, no error is
+ generated. */
+
+try
+gfc_extend_assign (gfc_code * c, gfc_namespace * ns)
+{
+ gfc_actual_arglist *actual;
+ gfc_expr *lhs, *rhs;
+ gfc_symbol *sym;
+
+ lhs = c->expr;
+ rhs = c->expr2;
+
+ /* Don't allow an intrinsic assignment to be replaced. */
+ if (lhs->ts.type != BT_DERIVED && rhs->ts.type != BT_DERIVED
+ && (lhs->ts.type == rhs->ts.type
+ || (gfc_numeric_ts (&lhs->ts)
+ && gfc_numeric_ts (&rhs->ts))))
+ return FAILURE;
+
+ actual = gfc_get_actual_arglist ();
+ actual->expr = lhs;
+
+ actual->next = gfc_get_actual_arglist ();
+ actual->next->expr = rhs;
+
+ sym = NULL;
+
+ for (; ns; ns = ns->parent)
+ {
+ sym = gfc_search_interface (ns->operator[INTRINSIC_ASSIGN], 1, &actual);
+ if (sym != NULL)
+ break;
+ }
+
+ if (sym == NULL)
+ {
+ gfc_free (actual->next);
+ gfc_free (actual);
+ return FAILURE;
+ }
+
+ /* Replace the assignment with the call. */
+ c->op = EXEC_CALL;
+ c->symtree = find_sym_in_symtree (sym);
+ c->expr = NULL;
+ c->expr2 = NULL;
+ c->ext.actual = actual;
+
+ if (gfc_pure (NULL) && !gfc_pure (sym))
+ {
+ gfc_error ("Subroutine '%s' called in lieu of assignment at %L must be "
+ "PURE", sym->name, &c->loc);
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Make sure that the interface just parsed is not already present in
+ the given interface list. Ambiguity isn't checked yet since module
+ procedures can be present without interfaces. */
+
+static try
+check_new_interface (gfc_interface * base, gfc_symbol * new)
+{
+ gfc_interface *ip;
+
+ for (ip = base; ip; ip = ip->next)
+ {
+ if (ip->sym == new)
+ {
+ gfc_error ("Entity '%s' at %C is already present in the interface",
+ new->name);
+ return FAILURE;
+ }
+ }
+
+ return SUCCESS;
+}
+
+
+/* Add a symbol to the current interface. */
+
+try
+gfc_add_interface (gfc_symbol * new)
+{
+ gfc_interface **head, *intr;
+ gfc_namespace *ns;
+ gfc_symbol *sym;
+
+ switch (current_interface.type)
+ {
+ case INTERFACE_NAMELESS:
+ return SUCCESS;
+
+ case INTERFACE_INTRINSIC_OP:
+ for (ns = current_interface.ns; ns; ns = ns->parent)
+ if (check_new_interface (ns->operator[current_interface.op], new)
+ == FAILURE)
+ return FAILURE;
+
+ head = &current_interface.ns->operator[current_interface.op];
+ break;
+
+ case INTERFACE_GENERIC:
+ for (ns = current_interface.ns; ns; ns = ns->parent)
+ {
+ gfc_find_symbol (current_interface.sym->name, ns, 0, &sym);
+ if (sym == NULL)
+ continue;
+
+ if (check_new_interface (sym->generic, new) == FAILURE)
+ return FAILURE;
+ }
+
+ head = &current_interface.sym->generic;
+ break;
+
+ case INTERFACE_USER_OP:
+ if (check_new_interface (current_interface.uop->operator, new) ==
+ FAILURE)
+ return FAILURE;
+
+ head = &current_interface.uop->operator;
+ break;
+
+ default:
+ gfc_internal_error ("gfc_add_interface(): Bad interface type");
+ }
+
+ intr = gfc_get_interface ();
+ intr->sym = new;
+ intr->where = *gfc_current_locus ();
+
+ intr->next = *head;
+ *head = intr;
+
+ return SUCCESS;
+}
+
+
+/* Gets rid of a formal argument list. We do not free symbols.
+ Symbols are freed when a namespace is freed. */
+
+void
+gfc_free_formal_arglist (gfc_formal_arglist * p)
+{
+ gfc_formal_arglist *q;
+
+ for (; p; p = q)
+ {
+ q = p->next;
+ gfc_free (p);
+ }
+}
diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
new file mode 100644
index 00000000000..c787e227a4e
--- /dev/null
+++ b/gcc/fortran/intrinsic.c
@@ -0,0 +1,2561 @@
+/* Build up a list of intrinsic subroutines and functions for the
+ name-resolution stage.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation,
+ Inc.
+ Contributed by Andy Vaught & Katherine Holcomb
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#include "config.h"
+#include "system.h"
+#include "flags.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <gmp.h>
+
+#include "gfortran.h"
+#include "intrinsic.h"
+
+
+/* Nanespace to hold the resolved symbols for intrinsic subroutines. */
+static gfc_namespace *gfc_intrinsic_namespace;
+
+int gfc_init_expr = 0;
+
+/* Pointers to a intrinsic function and its argument names being
+ checked. */
+
+char *gfc_current_intrinsic, *gfc_current_intrinsic_arg[MAX_INTRINSIC_ARGS];
+locus *gfc_current_intrinsic_where;
+
+static gfc_intrinsic_sym *functions, *subroutines, *conversion, *next_sym;
+static gfc_intrinsic_arg *next_arg;
+
+static int nfunc, nsub, nargs, nconv;
+
+static enum
+{ SZ_NOTHING = 0, SZ_SUBS, SZ_FUNCS, SZ_CONVS }
+sizing;
+
+
+/* Return a letter based on the passed type. Used to construct the
+ name of a type-dependent subroutine. */
+
+char
+gfc_type_letter (bt type)
+{
+ char c;
+
+ switch (type)
+ {
+ case BT_LOGICAL:
+ c = 'l';
+ break;
+ case BT_CHARACTER:
+ c = 's';
+ break;
+ case BT_INTEGER:
+ c = 'i';
+ break;
+ case BT_REAL:
+ c = 'r';
+ break;
+ case BT_COMPLEX:
+ c = 'c';
+ break;
+
+ default:
+ c = 'u';
+ break;
+ }
+
+ return c;
+}
+
+
+/* Get a symbol for a resolved name. */
+
+gfc_symbol *
+gfc_get_intrinsic_sub_symbol (const char * name)
+{
+ gfc_symbol *sym;
+
+ gfc_get_symbol (name, gfc_intrinsic_namespace, &sym);
+ sym->attr.always_explicit = 1;
+ sym->attr.subroutine = 1;
+ sym->attr.flavor = FL_PROCEDURE;
+ sym->attr.proc = PROC_INTRINSIC;
+
+ return sym;
+}
+
+
+/* Return a pointer to the name of a conversion function given two
+ typespecs. */
+
+static char *
+conv_name (gfc_typespec * from, gfc_typespec * to)
+{
+ static char name[30];
+
+ sprintf (name, "__convert_%c%d_%c%d", gfc_type_letter (from->type),
+ from->kind, gfc_type_letter (to->type), to->kind);
+
+ return name;
+}
+
+
+/* Given a pair of typespecs, find the gfc_intrinsic_sym node that
+ corresponds to the conversion. Returns NULL if the conversion
+ isn't found. */
+
+static gfc_intrinsic_sym *
+find_conv (gfc_typespec * from, gfc_typespec * to)
+{
+ gfc_intrinsic_sym *sym;
+ char *target;
+ int i;
+
+ target = conv_name (from, to);
+ sym = conversion;
+
+ for (i = 0; i < nconv; i++, sym++)
+ if (strcmp (target, sym->name) == 0)
+ return sym;
+
+ return NULL;
+}
+
+
+/* Interface to the check functions. We break apart an argument list
+ and call the proper check function rather than forcing each
+ function to manipulate the argument list. */
+
+static try
+do_check (gfc_intrinsic_sym * specific, gfc_actual_arglist * arg)
+{
+ gfc_expr *a1, *a2, *a3, *a4, *a5;
+ try t;
+
+ a1 = arg->expr;
+ arg = arg->next;
+
+ if (arg == NULL)
+ t = (*specific->check.f1) (a1);
+ else
+ {
+ a2 = arg->expr;
+ arg = arg->next;
+
+ if (arg == NULL)
+ t = (*specific->check.f2) (a1, a2);
+ else
+ {
+ a3 = arg->expr;
+ arg = arg->next;
+
+ if (arg == NULL)
+ t = (*specific->check.f3) (a1, a2, a3);
+ else
+ {
+ a4 = arg->expr;
+ arg = arg->next;
+
+ if (arg == NULL)
+ t = (*specific->check.f4) (a1, a2, a3, a4);
+ else
+ {
+ a5 = arg->expr;
+ arg = arg->next;
+
+ if (arg == NULL)
+ t = (*specific->check.f5) (a1, a2, a3, a4, a5);
+ else
+ {
+ gfc_internal_error ("do_check(): too many args");
+ }
+ }
+ }
+ }
+ }
+
+ return t;
+}
+
+
+/*********** Subroutines to build the intrinsic list ****************/
+
+/* Add a single intrinsic symbol to the current list.
+
+ Argument list:
+ char * name of function
+ int whether function is elemental
+ int If the function can be used as an actual argument
+ bt return type of function
+ int kind of return type of function
+ check pointer to check function
+ simplify pointer to simplification function
+ resolve pointer to resolution function
+
+ Optional arguments come in multiples of four:
+ char * name of argument
+ bt type of argument
+ int kind of argument
+ int arg optional flag (1=optional, 0=required)
+
+ The sequence is terminated by a NULL name.
+
+ TODO: Are checks on actual_ok implemented elsewhere, or is that just
+ missing here? */
+
+static void
+add_sym (const char *name, int elemental, int actual_ok ATTRIBUTE_UNUSED,
+ bt type, int kind, gfc_check_f check, gfc_simplify_f simplify,
+ gfc_resolve_f resolve, ...)
+{
+
+ int optional, first_flag;
+ va_list argp;
+
+ switch (sizing)
+ {
+ case SZ_SUBS:
+ nsub++;
+ break;
+
+ case SZ_FUNCS:
+ nfunc++;
+ break;
+
+ case SZ_NOTHING:
+ strcpy (next_sym->name, name);
+
+ strcpy (next_sym->lib_name, "_gfortran_");
+ strcat (next_sym->lib_name, name);
+
+ next_sym->elemental = elemental;
+ next_sym->ts.type = type;
+ next_sym->ts.kind = kind;
+ next_sym->simplify = simplify;
+ next_sym->check = check;
+ next_sym->resolve = resolve;
+ next_sym->specific = 0;
+ next_sym->generic = 0;
+ break;
+
+ default:
+ gfc_internal_error ("add_sym(): Bad sizing mode");
+ }
+
+ va_start (argp, resolve);
+
+ first_flag = 1;
+
+ for (;;)
+ {
+ name = va_arg (argp, char *);
+ if (name == NULL)
+ break;
+
+ type = (bt) va_arg (argp, int);
+ kind = va_arg (argp, int);
+ optional = va_arg (argp, int);
+
+ if (sizing != SZ_NOTHING)
+ nargs++;
+ else
+ {
+ next_arg++;
+
+ if (first_flag)
+ next_sym->formal = next_arg;
+ else
+ (next_arg - 1)->next = next_arg;
+
+ first_flag = 0;
+
+ strcpy (next_arg->name, name);
+ next_arg->ts.type = type;
+ next_arg->ts.kind = kind;
+ next_arg->optional = optional;
+ }
+ }
+
+ va_end (argp);
+
+ next_sym++;
+}
+
+
+static void add_sym_0 (const char *name, int elemental, int actual_ok, bt type,
+ int kind,
+ try (*check)(gfc_expr *),
+ gfc_expr *(*simplify)(gfc_expr *),
+ void (*resolve)(gfc_expr *,gfc_expr *)
+ ) {
+ gfc_simplify_f sf;
+ gfc_check_f cf;
+ gfc_resolve_f rf;
+
+ cf.f1 = check;
+ sf.f1 = simplify;
+ rf.f1 = resolve;
+
+ add_sym (name, elemental, actual_ok, type, kind, cf, sf, rf,
+ (void*)0);
+}
+
+
+static void add_sym_1 (const char *name, int elemental, int actual_ok, bt type,
+ int kind,
+ try (*check)(gfc_expr *),
+ gfc_expr *(*simplify)(gfc_expr *),
+ void (*resolve)(gfc_expr *,gfc_expr *),
+ const char* a1, bt type1, int kind1, int optional1
+ ) {
+ gfc_check_f cf;
+ gfc_simplify_f sf;
+ gfc_resolve_f rf;
+
+ cf.f1 = check;
+ sf.f1 = simplify;
+ rf.f1 = resolve;
+
+ add_sym (name, elemental, actual_ok, type, kind, cf, sf, rf,
+ a1, type1, kind1, optional1,
+ (void*)0);
+}
+
+
+static void
+add_sym_0s (const char * name, int actual_ok,
+ void (*resolve)(gfc_code *))
+{
+ gfc_check_f cf;
+ gfc_simplify_f sf;
+ gfc_resolve_f rf;
+
+ cf.f1 = NULL;
+ sf.f1 = NULL;
+ rf.s1 = resolve;
+
+ add_sym (name, 1, actual_ok, BT_UNKNOWN, 0, cf, sf, rf,
+ (void*)0);
+}
+
+
+static void add_sym_1s (const char *name, int elemental, int actual_ok, bt type,
+ int kind,
+ try (*check)(gfc_expr *),
+ gfc_expr *(*simplify)(gfc_expr *),
+ void (*resolve)(gfc_code *),
+ const char* a1, bt type1, int kind1, int optional1
+ ) {
+ gfc_check_f cf;
+ gfc_simplify_f sf;
+ gfc_resolve_f rf;
+
+ cf.f1 = check;
+ sf.f1 = simplify;
+ rf.s1 = resolve;
+
+ add_sym (name, elemental, actual_ok, type, kind, cf, sf, rf,
+ a1, type1, kind1, optional1,
+ (void*)0);
+}
+
+
+static void add_sym_1m (const char *name, int elemental, int actual_ok, bt type,
+ int kind,
+ try (*check)(gfc_actual_arglist *),
+ gfc_expr *(*simplify)(gfc_expr *),
+ void (*resolve)(gfc_expr *,gfc_actual_arglist *),
+ const char* a1, bt type1, int kind1, int optional1,
+ const char* a2, bt type2, int kind2, int optional2
+ ) {
+ gfc_check_f cf;
+ gfc_simplify_f sf;
+ gfc_resolve_f rf;
+
+ cf.f1m = check;
+ sf.f1 = simplify;
+ rf.f1m = resolve;
+
+ add_sym (name, elemental, actual_ok, type, kind, cf, sf, rf,
+ a1, type1, kind1, optional1,
+ a2, type2, kind2, optional2,
+ (void*)0);
+}
+
+
+static void add_sym_2 (const char *name, int elemental, int actual_ok, bt type,
+ int kind,
+ try (*check)(gfc_expr *,gfc_expr *),
+ gfc_expr *(*simplify)(gfc_expr *,gfc_expr *),
+ void (*resolve)(gfc_expr *,gfc_expr *,gfc_expr *),
+ const char* a1, bt type1, int kind1, int optional1,
+ const char* a2, bt type2, int kind2, int optional2
+ ) {
+ gfc_check_f cf;
+ gfc_simplify_f sf;
+ gfc_resolve_f rf;
+
+ cf.f2 = check;
+ sf.f2 = simplify;
+ rf.f2 = resolve;
+
+ add_sym (name, elemental, actual_ok, type, kind, cf, sf, rf,
+ a1, type1, kind1, optional1,
+ a2, type2, kind2, optional2,
+ (void*)0);
+}
+
+
+static void add_sym_3 (const char *name, int elemental, int actual_ok, bt type,
+ int kind,
+ try (*check)(gfc_expr *,gfc_expr *,gfc_expr *),
+ gfc_expr *(*simplify)(gfc_expr *,gfc_expr *,gfc_expr *),
+ void (*resolve)(gfc_expr *,gfc_expr *,gfc_expr *,gfc_expr *),
+ const char* a1, bt type1, int kind1, int optional1,
+ const char* a2, bt type2, int kind2, int optional2,
+ const char* a3, bt type3, int kind3, int optional3
+ ) {
+ gfc_check_f cf;
+ gfc_simplify_f sf;
+ gfc_resolve_f rf;
+
+ cf.f3 = check;
+ sf.f3 = simplify;
+ rf.f3 = resolve;
+
+ add_sym (name, elemental, actual_ok, type, kind, cf, sf, rf,
+ a1, type1, kind1, optional1,
+ a2, type2, kind2, optional2,
+ a3, type3, kind3, optional3,
+ (void*)0);
+}
+
+
+static void add_sym_4 (const char *name, int elemental, int actual_ok, bt type,
+ int kind,
+ try (*check)(gfc_expr *,gfc_expr *,gfc_expr *,gfc_expr *),
+ gfc_expr *(*simplify)(gfc_expr *,gfc_expr *,gfc_expr *,gfc_expr *),
+ void (*resolve)(gfc_expr *,gfc_expr *,gfc_expr *,gfc_expr *,gfc_expr *),
+ const char* a1, bt type1, int kind1, int optional1,
+ const char* a2, bt type2, int kind2, int optional2,
+ const char* a3, bt type3, int kind3, int optional3,
+ const char* a4, bt type4, int kind4, int optional4
+ ) {
+ gfc_check_f cf;
+ gfc_simplify_f sf;
+ gfc_resolve_f rf;
+
+ cf.f4 = check;
+ sf.f4 = simplify;
+ rf.f4 = resolve;
+
+ add_sym (name, elemental, actual_ok, type, kind, cf, sf, rf,
+ a1, type1, kind1, optional1,
+ a2, type2, kind2, optional2,
+ a3, type3, kind3, optional3,
+ a4, type4, kind4, optional4,
+ (void*)0);
+}
+
+
+static void add_sym_5 (const char *name, int elemental, int actual_ok, bt type,
+ int kind,
+ try (*check)(gfc_expr *,gfc_expr *,gfc_expr *,gfc_expr *,gfc_expr *),
+ gfc_expr *(*simplify)(gfc_expr *,gfc_expr *,gfc_expr *,gfc_expr *,gfc_expr *),
+ void (*resolve)(gfc_expr *,gfc_expr *,gfc_expr *,gfc_expr *,gfc_expr *,gfc_expr *),
+ const char* a1, bt type1, int kind1, int optional1,
+ const char* a2, bt type2, int kind2, int optional2,
+ const char* a3, bt type3, int kind3, int optional3,
+ const char* a4, bt type4, int kind4, int optional4,
+ const char* a5, bt type5, int kind5, int optional5
+ ) {
+ gfc_check_f cf;
+ gfc_simplify_f sf;
+ gfc_resolve_f rf;
+
+ cf.f5 = check;
+ sf.f5 = simplify;
+ rf.f5 = resolve;
+
+ add_sym (name, elemental, actual_ok, type, kind, cf, sf, rf,
+ a1, type1, kind1, optional1,
+ a2, type2, kind2, optional2,
+ a3, type3, kind3, optional3,
+ a4, type4, kind4, optional4,
+ a5, type5, kind5, optional5,
+ (void*)0);
+}
+
+
+/* Locate an intrinsic symbol given a base pointer, number of elements
+ in the table and a pointer to a name. Returns the NULL pointer if
+ a name is not found. */
+
+static gfc_intrinsic_sym *
+find_sym (gfc_intrinsic_sym * start, int n, const char *name)
+{
+
+ while (n > 0)
+ {
+ if (strcmp (name, start->name) == 0)
+ return start;
+
+ start++;
+ n--;
+ }
+
+ return NULL;
+}
+
+
+/* Given a name, find a function in the intrinsic function table.
+ Returns NULL if not found. */
+
+gfc_intrinsic_sym *
+gfc_find_function (const char *name)
+{
+
+ return find_sym (functions, nfunc, name);
+}
+
+
+/* Given a name, find a function in the intrinsic subroutine table.
+ Returns NULL if not found. */
+
+static gfc_intrinsic_sym *
+find_subroutine (const char *name)
+{
+
+ return find_sym (subroutines, nsub, name);
+}
+
+
+/* Given a string, figure out if it is the name of a generic intrinsic
+ function or not. */
+
+int
+gfc_generic_intrinsic (const char *name)
+{
+ gfc_intrinsic_sym *sym;
+
+ sym = gfc_find_function (name);
+ return (sym == NULL) ? 0 : sym->generic;
+}
+
+
+/* Given a string, figure out if it is the name of a specific
+ intrinsic function or not. */
+
+int
+gfc_specific_intrinsic (const char *name)
+{
+ gfc_intrinsic_sym *sym;
+
+ sym = gfc_find_function (name);
+ return (sym == NULL) ? 0 : sym->specific;
+}
+
+
+/* Given a string, figure out if it is the name of an intrinsic
+ subroutine or function. There are no generic intrinsic
+ subroutines, they are all specific. */
+
+int
+gfc_intrinsic_name (const char *name, int subroutine_flag)
+{
+
+ return subroutine_flag ?
+ find_subroutine (name) != NULL : gfc_find_function (name) != NULL;
+}
+
+
+/* Collect a set of intrinsic functions into a generic collection.
+ The first argument is the name of the generic function, which is
+ also the name of a specific function. The rest of the specifics
+ currently in the table are placed into the list of specific
+ functions associated with that generic. */
+
+static void
+make_generic (const char *name, gfc_generic_isym_id generic_id)
+{
+ gfc_intrinsic_sym *g;
+
+ if (sizing != SZ_NOTHING)
+ return;
+
+ g = gfc_find_function (name);
+ if (g == NULL)
+ gfc_internal_error ("make_generic(): Can't find generic symbol '%s'",
+ name);
+
+ g->generic = 1;
+ g->specific = 1;
+ g->generic_id = generic_id;
+ if ((g + 1)->name[0] != '\0')
+ g->specific_head = g + 1;
+ g++;
+
+ while (g->name[0] != '\0')
+ {
+ g->next = g + 1;
+ g->specific = 1;
+ g->generic_id = generic_id;
+ g++;
+ }
+
+ g--;
+ g->next = NULL;
+}
+
+
+/* Create a duplicate intrinsic function entry for the current
+ function, the only difference being the alternate name. Note that
+ we use argument lists more than once, but all argument lists are
+ freed as a single block. */
+
+static void
+make_alias (const char *name)
+{
+
+ switch (sizing)
+ {
+ case SZ_FUNCS:
+ nfunc++;
+ break;
+
+ case SZ_SUBS:
+ nsub++;
+ break;
+
+ case SZ_NOTHING:
+ next_sym[0] = next_sym[-1];
+ strcpy (next_sym->name, name);
+ next_sym++;
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/* Add intrinsic functions. */
+
+static void
+add_functions (void)
+{
+
+ /* Argument names as in the standard (to be used as argument keywords). */
+ const char
+ *a = "a", *f = "field", *pt = "pointer", *tg = "target",
+ *b = "b", *m = "matrix", *ma = "matrix_a", *mb = "matrix_b",
+ *c = "c", *n = "ncopies", *pos = "pos", *bck = "back",
+ *i = "i", *v = "vector", *va = "vector_a", *vb = "vector_b",
+ *j = "j", *a1 = "a1", *fs = "fsource", *ts = "tsource",
+ *l = "l", *a2 = "a2", *mo = "mold", *ord = "order",
+ *p = "p", *ar = "array", *shp = "shape", *src = "source",
+ *r = "r", *bd = "boundary", *pad = "pad", *set = "set",
+ *s = "s", *dm = "dim", *kind = "kind", *msk = "mask",
+ *x = "x", *sh = "shift", *stg = "string", *ssg = "substring",
+ *y = "y", *sz = "size", *sta = "string_a", *stb = "string_b",
+ *z = "z", *ln = "len";
+
+ int di, dr, dd, dl, dc, dz, ii;
+
+ di = gfc_default_integer_kind ();
+ dr = gfc_default_real_kind ();
+ dd = gfc_default_double_kind ();
+ dl = gfc_default_logical_kind ();
+ dc = gfc_default_character_kind ();
+ dz = gfc_default_complex_kind ();
+ ii = gfc_index_integer_kind;
+
+ add_sym_1 ("abs", 1, 1, BT_REAL, dr,
+ gfc_check_abs, gfc_simplify_abs, gfc_resolve_abs,
+ a, BT_REAL, dr, 0);
+
+ add_sym_1 ("iabs", 1, 1, BT_INTEGER, di,
+ NULL, gfc_simplify_abs, gfc_resolve_abs,
+ a, BT_INTEGER, di, 0);
+
+ add_sym_1 ("dabs", 1, 1, BT_REAL, dd,
+ NULL, gfc_simplify_abs, gfc_resolve_abs, a, BT_REAL, dd, 0);
+
+ add_sym_1 ("cabs", 1, 1, BT_REAL, dr,
+ NULL, gfc_simplify_abs, gfc_resolve_abs,
+ a, BT_COMPLEX, dz, 0);
+
+ add_sym_1 ("zabs", 1, 1, BT_REAL, dd, NULL, gfc_simplify_abs, gfc_resolve_abs, a, BT_COMPLEX, dd, 0); /* Extension */
+
+ make_alias ("cdabs");
+
+ make_generic ("abs", GFC_ISYM_ABS);
+
+ add_sym_1 ("achar", 1, 1, BT_CHARACTER, dc,
+ NULL, gfc_simplify_achar, NULL, i, BT_INTEGER, di, 0);
+
+ make_generic ("achar", GFC_ISYM_ACHAR);
+
+ add_sym_1 ("acos", 1, 1, BT_REAL, dr,
+ NULL, gfc_simplify_acos, gfc_resolve_acos,
+ x, BT_REAL, dr, 0);
+
+ add_sym_1 ("dacos", 1, 1, BT_REAL, dd,
+ NULL, gfc_simplify_acos, gfc_resolve_acos,
+ x, BT_REAL, dd, 0);
+
+ make_generic ("acos", GFC_ISYM_ACOS);
+
+ add_sym_1 ("adjustl", 1, 1, BT_CHARACTER, dc,
+ NULL, gfc_simplify_adjustl, NULL, stg, BT_CHARACTER, dc, 0);
+
+ make_generic ("adjustl", GFC_ISYM_ADJUSTL);
+
+ add_sym_1 ("adjustr", 1, 1, BT_CHARACTER, dc,
+ NULL, gfc_simplify_adjustr, NULL, stg, BT_CHARACTER, dc, 0);
+
+ make_generic ("adjustr", GFC_ISYM_ADJUSTR);
+
+ add_sym_1 ("aimag", 1, 1, BT_REAL, dr,
+ NULL, gfc_simplify_aimag, gfc_resolve_aimag,
+ z, BT_COMPLEX, dz, 0);
+
+ add_sym_1 ("dimag", 1, 1, BT_REAL, dd, NULL, gfc_simplify_aimag, gfc_resolve_aimag, z, BT_COMPLEX, dd, 0); /* Extension */
+
+ make_generic ("aimag", GFC_ISYM_AIMAG);
+
+ add_sym_2 ("aint", 1, 1, BT_REAL, dr,
+ gfc_check_a_xkind, gfc_simplify_aint, gfc_resolve_aint,
+ a, BT_REAL, dr, 0, kind, BT_INTEGER, di, 1);
+
+ add_sym_1 ("dint", 1, 1, BT_REAL, dd,
+ NULL, gfc_simplify_dint, gfc_resolve_dint,
+ a, BT_REAL, dd, 0);
+
+ make_generic ("aint", GFC_ISYM_AINT);
+
+ add_sym_2 ("all", 0, 1, BT_UNKNOWN, 0,
+ gfc_check_all_any, NULL, gfc_resolve_all,
+ msk, BT_LOGICAL, dl, 0, dm, BT_INTEGER, ii, 1);
+
+ make_generic ("all", GFC_ISYM_ALL);
+
+ add_sym_1 ("allocated", 0, 1, BT_LOGICAL, dl,
+ gfc_check_allocated, NULL, NULL, ar, BT_UNKNOWN, 0, 0);
+
+ make_generic ("allocated", GFC_ISYM_ALLOCATED);
+
+ add_sym_2 ("anint", 1, 1, BT_REAL, dr,
+ gfc_check_a_xkind, gfc_simplify_anint, gfc_resolve_anint,
+ a, BT_REAL, dr, 0, kind, BT_INTEGER, di, 1);
+
+ add_sym_1 ("dnint", 1, 1, BT_REAL, dd,
+ NULL, gfc_simplify_dnint, gfc_resolve_dnint,
+ a, BT_REAL, dd, 0);
+
+ make_generic ("anint", GFC_ISYM_ANINT);
+
+ add_sym_2 ("any", 0, 1, BT_UNKNOWN, 0,
+ gfc_check_all_any, NULL, gfc_resolve_any,
+ msk, BT_LOGICAL, dl, 0, dm, BT_INTEGER, ii, 1);
+
+ make_generic ("any", GFC_ISYM_ANY);
+
+ add_sym_1 ("asin", 1, 1, BT_REAL, dr,
+ NULL, gfc_simplify_asin, gfc_resolve_asin,
+ x, BT_REAL, dr, 0);
+
+ add_sym_1 ("dasin", 1, 1, BT_REAL, dd,
+ NULL, gfc_simplify_asin, gfc_resolve_asin,
+ x, BT_REAL, dd, 0);
+
+ make_generic ("asin", GFC_ISYM_ASIN);
+
+ add_sym_2 ("associated", 0, 1, BT_LOGICAL, dl,
+ gfc_check_associated, NULL, NULL,
+ pt, BT_UNKNOWN, 0, 0, tg, BT_UNKNOWN, 0, 1);
+
+ make_generic ("associated", GFC_ISYM_ASSOCIATED);
+
+ add_sym_1 ("atan", 1, 1, BT_REAL, dr,
+ NULL, gfc_simplify_atan, gfc_resolve_atan,
+ x, BT_REAL, dr, 0);
+
+ add_sym_1 ("datan", 1, 1, BT_REAL, dd,
+ NULL, gfc_simplify_atan, gfc_resolve_atan,
+ x, BT_REAL, dd, 0);
+
+ make_generic ("atan", GFC_ISYM_ATAN);
+
+ add_sym_2 ("atan2", 1, 1, BT_REAL, dr,
+ NULL, gfc_simplify_atan2, gfc_resolve_atan2,
+ y, BT_REAL, dr, 0, x, BT_REAL, dr, 0);
+
+ add_sym_2 ("datan2", 1, 1, BT_REAL, dd,
+ NULL, gfc_simplify_atan2, gfc_resolve_atan2,
+ y, BT_REAL, dd, 0, x, BT_REAL, dd, 0);
+
+ make_generic ("atan2", GFC_ISYM_ATAN2);
+
+ add_sym_1 ("bit_size", 0, 1, BT_INTEGER, di,
+ gfc_check_i, gfc_simplify_bit_size, NULL,
+ i, BT_INTEGER, di, 0);
+
+ make_generic ("bit_size", GFC_ISYM_NONE);
+
+ add_sym_2 ("btest", 1, 1, BT_LOGICAL, dl,
+ gfc_check_btest, gfc_simplify_btest, gfc_resolve_btest,
+ i, BT_INTEGER, di, 0, pos, BT_INTEGER, di, 0);
+
+ make_generic ("btest", GFC_ISYM_BTEST);
+
+ add_sym_2 ("ceiling", 1, 1, BT_INTEGER, di,
+ gfc_check_a_ikind, gfc_simplify_ceiling, gfc_resolve_ceiling,
+ a, BT_REAL, dr, 0, kind, BT_INTEGER, di, 1);
+
+ make_generic ("ceiling", GFC_ISYM_CEILING);
+
+ add_sym_2 ("char", 1, 0, BT_CHARACTER, dc,
+ gfc_check_char, gfc_simplify_char, gfc_resolve_char,
+ i, BT_INTEGER, di, 0, kind, BT_INTEGER, di, 1);
+
+ make_generic ("char", GFC_ISYM_CHAR);
+
+ add_sym_3 ("cmplx", 1, 1, BT_COMPLEX, dz,
+ gfc_check_cmplx, gfc_simplify_cmplx, gfc_resolve_cmplx,
+ x, BT_UNKNOWN, dr, 0, y, BT_UNKNOWN, dr, 1,
+ kind, BT_INTEGER, di, 1);
+
+ make_generic ("cmplx", GFC_ISYM_CMPLX);
+
+ /* Making dcmplx a specific of cmplx causes cmplx to return a double
+ complex instead of the default complex. */
+
+ add_sym_2 ("dcmplx", 1, 1, BT_COMPLEX, dd,
+ gfc_check_dcmplx, gfc_simplify_dcmplx, gfc_resolve_dcmplx,
+ x, BT_REAL, dd, 0, y, BT_REAL, dd, 1); /* Extension */
+
+ make_generic ("dcmplx", GFC_ISYM_CMPLX);
+
+ add_sym_1 ("conjg", 1, 1, BT_COMPLEX, dz,
+ NULL, gfc_simplify_conjg, gfc_resolve_conjg,
+ z, BT_COMPLEX, dz, 0);
+
+ add_sym_1 ("dconjg", 1, 1, BT_COMPLEX, dd, NULL, gfc_simplify_conjg, gfc_resolve_conjg, z, BT_COMPLEX, dd, 0); /* Extension */
+
+ make_generic ("conjg", GFC_ISYM_CONJG);
+
+ add_sym_1 ("cos", 1, 1, BT_REAL, dr,
+ NULL, gfc_simplify_cos, gfc_resolve_cos, x, BT_REAL, dr, 0);
+
+ add_sym_1 ("dcos", 1, 1, BT_REAL, dd,
+ NULL, gfc_simplify_cos, gfc_resolve_cos, x, BT_REAL, dd, 0);
+
+ add_sym_1 ("ccos", 1, 1, BT_COMPLEX, dz,
+ NULL, gfc_simplify_cos, gfc_resolve_cos,
+ x, BT_COMPLEX, dz, 0);
+
+ add_sym_1 ("zcos", 1, 1, BT_COMPLEX, dd, NULL, gfc_simplify_cos, gfc_resolve_cos, x, BT_COMPLEX, dd, 0); /* Extension */
+
+ make_alias ("cdcos");
+
+ make_generic ("cos", GFC_ISYM_COS);
+
+ add_sym_1 ("cosh", 1, 1, BT_REAL, dr,
+ NULL, gfc_simplify_cosh, gfc_resolve_cosh,
+ x, BT_REAL, dr, 0);
+
+ add_sym_1 ("dcosh", 1, 1, BT_REAL, dd,
+ NULL, gfc_simplify_cosh, gfc_resolve_cosh,
+ x, BT_REAL, dd, 0);
+
+ make_generic ("cosh", GFC_ISYM_COSH);
+
+ add_sym_2 ("count", 0, 1, BT_INTEGER, di,
+ gfc_check_count, NULL, gfc_resolve_count,
+ msk, BT_LOGICAL, dl, 0, dm, BT_INTEGER, ii, 1);
+
+ make_generic ("count", GFC_ISYM_COUNT);
+
+ add_sym_3 ("cshift", 0, 1, BT_REAL, dr,
+ gfc_check_cshift, NULL, gfc_resolve_cshift,
+ ar, BT_REAL, dr, 0, sh, BT_INTEGER, di, 0,
+ dm, BT_INTEGER, ii, 1);
+
+ make_generic ("cshift", GFC_ISYM_CSHIFT);
+
+ add_sym_1 ("dble", 1, 1, BT_REAL, dd,
+ gfc_check_dble, gfc_simplify_dble, gfc_resolve_dble,
+ a, BT_REAL, dr, 0);
+
+ make_generic ("dble", GFC_ISYM_DBLE);
+
+ add_sym_1 ("digits", 0, 1, BT_INTEGER, di,
+ gfc_check_digits, gfc_simplify_digits, NULL,
+ x, BT_UNKNOWN, dr, 0);
+
+ make_generic ("digits", GFC_ISYM_NONE);
+
+ add_sym_2 ("dim", 1, 1, BT_REAL, dr,
+ gfc_check_a_p, gfc_simplify_dim, gfc_resolve_dim,
+ x, BT_UNKNOWN, dr, 0, y, BT_UNKNOWN, dr, 0);
+
+ add_sym_2 ("idim", 1, 1, BT_INTEGER, di,
+ NULL, gfc_simplify_dim, gfc_resolve_dim,
+ x, BT_INTEGER, di, 0, y, BT_INTEGER, di, 0);
+
+ add_sym_2 ("ddim", 1, 1, BT_REAL, dd,
+ NULL, gfc_simplify_dim, gfc_resolve_dim,
+ x, BT_REAL, dd, 0, y, BT_REAL, dd, 0);
+
+ make_generic ("dim", GFC_ISYM_DIM);
+
+ add_sym_2 ("dot_product", 0, 1, BT_UNKNOWN, 0,
+ gfc_check_dot_product, NULL, gfc_resolve_dot_product,
+ va, BT_REAL, dr, 0, vb, BT_REAL, dr, 0);
+
+ make_generic ("dot_product", GFC_ISYM_DOT_PRODUCT);
+
+ add_sym_2 ("dprod", 1, 1, BT_REAL, dd,
+ NULL, gfc_simplify_dprod, gfc_resolve_dprod,
+ x, BT_REAL, dr, 0, y, BT_REAL, dr, 0);
+
+ make_generic ("dprod", GFC_ISYM_DPROD);
+
+ add_sym_1 ("dreal", 1, 0, BT_REAL, dd, NULL, NULL, NULL, a, BT_COMPLEX, dd, 0); /* Extension */
+
+ make_generic ("dreal", GFC_ISYM_REAL);
+
+ add_sym_4 ("eoshift", 0, 1, BT_REAL, dr,
+ gfc_check_eoshift, NULL, gfc_resolve_eoshift,
+ ar, BT_REAL, dr, 0, sh, BT_INTEGER, ii, 0,
+ bd, BT_REAL, dr, 1, dm, BT_INTEGER, ii, 1);
+
+ make_generic ("eoshift", GFC_ISYM_EOSHIFT);
+
+ add_sym_1 ("epsilon", 0, 1, BT_REAL, dr,
+ gfc_check_x, gfc_simplify_epsilon, NULL,
+ x, BT_REAL, dr, 0);
+
+ make_generic ("epsilon", GFC_ISYM_NONE);
+
+ add_sym_1 ("exp", 1, 1, BT_REAL, dr,
+ NULL, gfc_simplify_exp, gfc_resolve_exp, x, BT_REAL, dr, 0);
+
+ add_sym_1 ("dexp", 1, 1, BT_REAL, dd,
+ NULL, gfc_simplify_exp, gfc_resolve_exp, x, BT_REAL, dd, 0);
+
+ add_sym_1 ("cexp", 1, 1, BT_COMPLEX, dz,
+ NULL, gfc_simplify_exp, gfc_resolve_exp,
+ x, BT_COMPLEX, dz, 0);
+
+ add_sym_1 ("zexp", 1, 1, BT_COMPLEX, dd, NULL, gfc_simplify_exp, gfc_resolve_exp, x, BT_COMPLEX, dd, 0); /* Extension */
+
+ make_alias ("cdexp");
+
+ make_generic ("exp", GFC_ISYM_EXP);
+
+ add_sym_1 ("exponent", 1, 1, BT_INTEGER, di,
+ gfc_check_x, gfc_simplify_exponent, gfc_resolve_exponent,
+ x, BT_REAL, dr, 0);
+
+ make_generic ("exponent", GFC_ISYM_EXPONENT);
+
+ add_sym_2 ("floor", 1, 1, BT_INTEGER, di,
+ gfc_check_a_ikind, gfc_simplify_floor, gfc_resolve_floor,
+ a, BT_REAL, dr, 0, kind, BT_INTEGER, di, 1);
+
+ make_generic ("floor", GFC_ISYM_FLOOR);
+
+ add_sym_1 ("fraction", 1, 1, BT_REAL, dr,
+ gfc_check_x, gfc_simplify_fraction, gfc_resolve_fraction,
+ x, BT_REAL, dr, 0);
+
+ make_generic ("fraction", GFC_ISYM_FRACTION);
+
+ add_sym_1 ("huge", 0, 1, BT_REAL, dr,
+ gfc_check_huge, gfc_simplify_huge, NULL,
+ x, BT_UNKNOWN, dr, 0);
+
+ make_generic ("huge", GFC_ISYM_NONE);
+
+ add_sym_1 ("iachar", 1, 1, BT_INTEGER, di,
+ NULL, gfc_simplify_iachar, NULL, c, BT_CHARACTER, dc, 0);
+
+ make_generic ("iachar", GFC_ISYM_IACHAR);
+
+ add_sym_2 ("iand", 1, 1, BT_INTEGER, di,
+ gfc_check_iand, gfc_simplify_iand, gfc_resolve_iand,
+ i, BT_INTEGER, di, 0, j, BT_INTEGER, di, 0);
+
+ make_generic ("iand", GFC_ISYM_IAND);
+
+ add_sym_0 ("iargc", 1, 1, BT_INTEGER, di, NULL, NULL, NULL); /* Extension, takes no arguments */
+
+ add_sym_2 ("ibclr", 1, 1, BT_INTEGER, di,
+ gfc_check_ibclr, gfc_simplify_ibclr, gfc_resolve_ibclr,
+ i, BT_INTEGER, di, 0, pos, BT_INTEGER, di, 0);
+
+ make_generic ("ibclr", GFC_ISYM_IBCLR);
+
+ add_sym_3 ("ibits", 1, 1, BT_INTEGER, di,
+ gfc_check_ibits, gfc_simplify_ibits, gfc_resolve_ibits,
+ i, BT_INTEGER, di, 0, pos, BT_INTEGER, di, 0,
+ ln, BT_INTEGER, di, 0);
+
+ make_generic ("ibits", GFC_ISYM_IBITS);
+
+ add_sym_2 ("ibset", 1, 1, BT_INTEGER, di,
+ gfc_check_ibset, gfc_simplify_ibset, gfc_resolve_ibset,
+ i, BT_INTEGER, di, 0, pos, BT_INTEGER, di, 0);
+
+ make_generic ("ibset", GFC_ISYM_IBSET);
+
+ add_sym_1 ("ichar", 1, 0, BT_INTEGER, di,
+ NULL, gfc_simplify_ichar, gfc_resolve_ichar,
+ c, BT_CHARACTER, dc, 0);
+
+ make_generic ("ichar", GFC_ISYM_ICHAR);
+
+ add_sym_2 ("ieor", 1, 1, BT_INTEGER, di,
+ gfc_check_ieor, gfc_simplify_ieor, gfc_resolve_ieor,
+ i, BT_INTEGER, di, 0, j, BT_INTEGER, di, 0);
+
+ make_generic ("ieor", GFC_ISYM_IEOR);
+
+ add_sym_3 ("index", 1, 1, BT_INTEGER, di,
+ gfc_check_index, gfc_simplify_index, NULL,
+ stg, BT_CHARACTER, dc, 0, ssg, BT_CHARACTER, dc, 0,
+ bck, BT_LOGICAL, dl, 1);
+
+ make_generic ("index", GFC_ISYM_INDEX);
+
+ add_sym_2 ("int", 1, 1, BT_INTEGER, di,
+ gfc_check_int, gfc_simplify_int, gfc_resolve_int,
+ a, BT_REAL, dr, 0, kind, BT_INTEGER, di, 1);
+
+ add_sym_1 ("ifix", 1, 0, BT_INTEGER, di,
+ NULL, gfc_simplify_ifix, NULL, a, BT_REAL, dr, 0);
+
+ add_sym_1 ("idint", 1, 0, BT_INTEGER, di,
+ NULL, gfc_simplify_idint, NULL, a, BT_REAL, dd, 0);
+
+ make_generic ("int", GFC_ISYM_INT);
+
+ add_sym_2 ("ior", 1, 1, BT_INTEGER, di,
+ gfc_check_ior, gfc_simplify_ior, gfc_resolve_ior,
+ i, BT_INTEGER, di, 0, j, BT_INTEGER, di, 0);
+
+ make_generic ("ior", GFC_ISYM_IOR);
+
+ add_sym_2 ("ishft", 1, 1, BT_INTEGER, di,
+ gfc_check_ishft, gfc_simplify_ishft, gfc_resolve_ishft,
+ i, BT_INTEGER, di, 0, sh, BT_INTEGER, di, 0);
+
+ make_generic ("ishft", GFC_ISYM_ISHFT);
+
+ add_sym_3 ("ishftc", 1, 1, BT_INTEGER, di,
+ gfc_check_ishftc, gfc_simplify_ishftc, gfc_resolve_ishftc,
+ i, BT_INTEGER, di, 0, sh, BT_INTEGER, di, 0,
+ sz, BT_INTEGER, di, 1);
+
+ make_generic ("ishftc", GFC_ISYM_ISHFTC);
+
+ add_sym_1 ("kind", 0, 1, BT_INTEGER, di,
+ gfc_check_kind, gfc_simplify_kind, NULL, x, BT_REAL, dr, 0);
+
+ make_generic ("kind", GFC_ISYM_NONE);
+
+ add_sym_2 ("lbound", 0, 1, BT_INTEGER, di,
+ gfc_check_lbound, gfc_simplify_lbound, gfc_resolve_lbound,
+ ar, BT_REAL, dr, 0, dm, BT_INTEGER, di, 1);
+
+ make_generic ("lbound", GFC_ISYM_LBOUND);
+
+ add_sym_1 ("len", 0, 1, BT_INTEGER, di,
+ NULL, gfc_simplify_len, gfc_resolve_len,
+ stg, BT_CHARACTER, dc, 0);
+
+ make_generic ("len", GFC_ISYM_LEN);
+
+ add_sym_1 ("len_trim", 1, 1, BT_INTEGER, di,
+ NULL, gfc_simplify_len_trim, gfc_resolve_len_trim,
+ stg, BT_CHARACTER, dc, 0);
+
+ make_generic ("len_trim", GFC_ISYM_LEN_TRIM);
+
+ add_sym_2 ("lge", 1, 0, BT_LOGICAL, dl,
+ NULL, gfc_simplify_lge, NULL,
+ sta, BT_CHARACTER, dc, 0, stb, BT_CHARACTER, dc, 0);
+
+ make_generic ("lge", GFC_ISYM_LGE);
+
+ add_sym_2 ("lgt", 1, 0, BT_LOGICAL, dl,
+ NULL, gfc_simplify_lgt, NULL,
+ sta, BT_CHARACTER, dc, 0, stb, BT_CHARACTER, dc, 0);
+
+ make_generic ("lgt", GFC_ISYM_LGT);
+
+ add_sym_2 ("lle", 1, 0, BT_LOGICAL, dl,
+ NULL, gfc_simplify_lle, NULL,
+ sta, BT_CHARACTER, dc, 0, stb, BT_CHARACTER, dc, 0);
+
+ make_generic ("lle", GFC_ISYM_LLE);
+
+ add_sym_2 ("llt", 1, 0, BT_LOGICAL, dl,
+ NULL, gfc_simplify_llt, NULL,
+ sta, BT_CHARACTER, dc, 0, stb, BT_CHARACTER, dc, 0);
+
+ make_generic ("llt", GFC_ISYM_LLT);
+
+ add_sym_1 ("log", 1, 1, BT_REAL, dr,
+ NULL, gfc_simplify_log, gfc_resolve_log, x, BT_REAL, dr, 0);
+
+ add_sym_1 ("alog", 1, 1, BT_REAL, dr,
+ NULL, gfc_simplify_log, gfc_resolve_log, x, BT_REAL, dr, 0);
+
+ add_sym_1 ("dlog", 1, 1, BT_REAL, dd,
+ NULL, gfc_simplify_log, gfc_resolve_log, x, BT_REAL, dd, 0);
+
+ add_sym_1 ("clog", 1, 1, BT_COMPLEX, dz,
+ NULL, gfc_simplify_log, gfc_resolve_log,
+ x, BT_COMPLEX, dz, 0);
+
+ add_sym_1 ("zlog", 1, 1, BT_COMPLEX, dd, NULL, gfc_simplify_log, gfc_resolve_log, x, BT_COMPLEX, dd, 0); /* Extension */
+
+ make_alias ("cdlog");
+
+ make_generic ("log", GFC_ISYM_LOG);
+
+ add_sym_1 ("log10", 1, 1, BT_REAL, dr,
+ NULL, gfc_simplify_log10, gfc_resolve_log10,
+ x, BT_REAL, dr, 0);
+
+ add_sym_1 ("alog10", 1, 1, BT_REAL, dr,
+ NULL, gfc_simplify_log10, gfc_resolve_log10,
+ x, BT_REAL, dr, 0);
+
+ add_sym_1 ("dlog10", 1, 1, BT_REAL, dd,
+ NULL, gfc_simplify_log10, gfc_resolve_log10,
+ x, BT_REAL, dd, 0);
+
+ make_generic ("log10", GFC_ISYM_LOG10);
+
+ add_sym_2 ("logical", 0, 1, BT_LOGICAL, dl,
+ gfc_check_logical, gfc_simplify_logical, gfc_resolve_logical,
+ l, BT_LOGICAL, dl, 0, kind, BT_INTEGER, di, 1);
+
+ make_generic ("logical", GFC_ISYM_LOGICAL);
+
+ add_sym_2 ("matmul", 0, 1, BT_REAL, dr,
+ gfc_check_matmul, NULL, gfc_resolve_matmul,
+ ma, BT_REAL, dr, 0, mb, BT_REAL, dr, 0);
+
+ make_generic ("matmul", GFC_ISYM_MATMUL);
+
+ /* Note: amax0 is equivalent to real(max), max1 is equivalent to
+ int(max). The max function must take at least two arguments. */
+
+ add_sym_1m ("max", 1, 0, BT_UNKNOWN, 0,
+ gfc_check_min_max, gfc_simplify_max, gfc_resolve_max,
+ a1, BT_UNKNOWN, dr, 0, a2, BT_UNKNOWN, dr, 0);
+
+ add_sym_1m ("max0", 1, 0, BT_INTEGER, di,
+ gfc_check_min_max_integer, gfc_simplify_max, NULL,
+ a1, BT_INTEGER, di, 0, a2, BT_INTEGER, di, 0);
+
+ add_sym_1m ("amax0", 1, 0, BT_REAL, dr,
+ gfc_check_min_max_integer, gfc_simplify_max, NULL,
+ a1, BT_INTEGER, di, 0, a2, BT_INTEGER, di, 0);
+
+ add_sym_1m ("amax1", 1, 0, BT_REAL, dr,
+ gfc_check_min_max_real, gfc_simplify_max, NULL,
+ a1, BT_REAL, dr, 0, a2, BT_REAL, dr, 0);
+
+ add_sym_1m ("max1", 1, 0, BT_INTEGER, di,
+ gfc_check_min_max_real, gfc_simplify_max, NULL,
+ a1, BT_REAL, dr, 0, a2, BT_REAL, dr, 0);
+
+ add_sym_1m ("dmax1", 1, 0, BT_REAL, dd,
+ gfc_check_min_max_double, gfc_simplify_max, NULL,
+ a1, BT_REAL, dd, 0, a2, BT_REAL, dd, 0);
+
+ make_generic ("max", GFC_ISYM_MAX);
+
+ add_sym_1 ("maxexponent", 0, 1, BT_INTEGER, di,
+ gfc_check_x, gfc_simplify_maxexponent, NULL,
+ x, BT_UNKNOWN, dr, 0);
+
+ make_generic ("maxexponent", GFC_ISYM_NONE);
+
+ add_sym_3 ("maxloc", 0, 1, BT_INTEGER, di,
+ gfc_check_minloc_maxloc, NULL, gfc_resolve_maxloc,
+ ar, BT_REAL, dr, 0, dm, BT_INTEGER, ii, 1,
+ msk, BT_LOGICAL, dl, 1);
+
+ make_generic ("maxloc", GFC_ISYM_MAXLOC);
+
+ add_sym_3 ("maxval", 0, 1, BT_REAL, dr,
+ gfc_check_minval_maxval, NULL, gfc_resolve_maxval,
+ ar, BT_REAL, dr, 0, dm, BT_INTEGER, ii, 1,
+ msk, BT_LOGICAL, dl, 1);
+
+ make_generic ("maxval", GFC_ISYM_MAXVAL);
+
+ add_sym_3 ("merge", 1, 1, BT_REAL, dr,
+ gfc_check_merge, NULL, gfc_resolve_merge,
+ ts, BT_REAL, dr, 0, fs, BT_REAL, dr, 0,
+ msk, BT_LOGICAL, dl, 0);
+
+ make_generic ("merge", GFC_ISYM_MERGE);
+
+ /* Note: amin0 is equivalent to real(min), min1 is equivalent to int(min). */
+
+ add_sym_1m ("min", 1, 0, BT_UNKNOWN, 0,
+ gfc_check_min_max, gfc_simplify_min, gfc_resolve_min,
+ a1, BT_REAL, dr, 0, a2, BT_REAL, dr, 0);
+
+ add_sym_1m ("min0", 1, 0, BT_INTEGER, di,
+ gfc_check_min_max_integer, gfc_simplify_min, NULL,
+ a1, BT_INTEGER, di, 0, a2, BT_INTEGER, di, 0);
+
+ add_sym_1m ("amin0", 1, 0, BT_REAL, dr,
+ gfc_check_min_max_integer, gfc_simplify_min, NULL,
+ a1, BT_INTEGER, di, 0, a2, BT_INTEGER, di, 0);
+
+ add_sym_1m ("amin1", 1, 0, BT_REAL, dr,
+ gfc_check_min_max_real, gfc_simplify_min, NULL,
+ a1, BT_REAL, dr, 0, a2, BT_REAL, dr, 0);
+
+ add_sym_1m ("min1", 1, 0, BT_INTEGER, di,
+ gfc_check_min_max_real, gfc_simplify_min, NULL,
+ a1, BT_REAL, dr, 0, a2, BT_REAL, dr, 0);
+
+ add_sym_1m ("dmin1", 1, 0, BT_REAL, dd,
+ gfc_check_min_max_double, gfc_simplify_min, NULL,
+ a1, BT_REAL, dd, 0, a2, BT_REAL, dd, 0);
+
+ make_generic ("min", GFC_ISYM_MIN);
+
+ add_sym_1 ("minexponent", 0, 1, BT_INTEGER, di,
+ gfc_check_x, gfc_simplify_minexponent, NULL,
+ x, BT_UNKNOWN, dr, 0);
+
+ make_generic ("minexponent", GFC_ISYM_NONE);
+
+ add_sym_3 ("minloc", 0, 1, BT_INTEGER, di,
+ gfc_check_minloc_maxloc, NULL, gfc_resolve_minloc,
+ ar, BT_REAL, dr, 0, dm, BT_INTEGER, ii, 1,
+ msk, BT_LOGICAL, dl, 1);
+
+ make_generic ("minloc", GFC_ISYM_MINLOC);
+
+ add_sym_3 ("minval", 0, 1, BT_REAL, dr,
+ gfc_check_minval_maxval, NULL, gfc_resolve_minval,
+ ar, BT_REAL, dr, 0, dm, BT_INTEGER, ii, 1,
+ msk, BT_LOGICAL, dl, 1);
+
+ make_generic ("minval", GFC_ISYM_MINVAL);
+
+ add_sym_2 ("mod", 1, 1, BT_INTEGER, di,
+ gfc_check_a_p, gfc_simplify_mod, gfc_resolve_mod,
+ a, BT_INTEGER, di, 0, p, BT_INTEGER, di, 0);
+
+ add_sym_2 ("amod", 1, 1, BT_REAL, dr,
+ NULL, gfc_simplify_mod, gfc_resolve_mod,
+ a, BT_REAL, dr, 0, p, BT_REAL, dr, 0);
+
+ add_sym_2 ("dmod", 1, 1, BT_REAL, dd,
+ NULL, gfc_simplify_mod, gfc_resolve_mod,
+ a, BT_REAL, dd, 0, p, BT_REAL, dd, 0);
+
+ make_generic ("mod", GFC_ISYM_MOD);
+
+ add_sym_2 ("modulo", 1, 1, BT_REAL, di,
+ gfc_check_a_p, gfc_simplify_modulo, gfc_resolve_modulo,
+ a, BT_REAL, di, 0, p, BT_REAL, di, 0);
+
+ make_generic ("modulo", GFC_ISYM_MODULO);
+
+ add_sym_2 ("nearest", 1, 1, BT_REAL, dr,
+ gfc_check_nearest, gfc_simplify_nearest, gfc_resolve_nearest,
+ x, BT_REAL, dr, 0, s, BT_REAL, dr, 0);
+
+ make_generic ("nearest", GFC_ISYM_NEAREST);
+
+ add_sym_2 ("nint", 1, 1, BT_INTEGER, di,
+ gfc_check_a_ikind, gfc_simplify_nint, gfc_resolve_nint,
+ a, BT_REAL, dr, 0, kind, BT_INTEGER, di, 1);
+
+ add_sym_1 ("idnint", 1, 1, BT_INTEGER, di,
+ gfc_check_idnint, gfc_simplify_idnint, gfc_resolve_idnint,
+ a, BT_REAL, dd, 0);
+
+ make_generic ("nint", GFC_ISYM_NINT);
+
+ add_sym_1 ("not", 1, 1, BT_INTEGER, di,
+ gfc_check_i, gfc_simplify_not, gfc_resolve_not,
+ i, BT_INTEGER, di, 0);
+
+ make_generic ("not", GFC_ISYM_NOT);
+
+ add_sym_1 ("null", 0, 1, BT_INTEGER, di,
+ gfc_check_null, gfc_simplify_null, NULL,
+ mo, BT_INTEGER, di, 1);
+
+ make_generic ("null", GFC_ISYM_NONE);
+
+ add_sym_3 ("pack", 0, 1, BT_REAL, dr,
+ gfc_check_pack, NULL, gfc_resolve_pack,
+ ar, BT_REAL, dr, 0, msk, BT_LOGICAL, dl, 0,
+ v, BT_REAL, dr, 1);
+
+ make_generic ("pack", GFC_ISYM_PACK);
+
+ add_sym_1 ("precision", 0, 1, BT_INTEGER, di,
+ gfc_check_precision, gfc_simplify_precision, NULL,
+ x, BT_UNKNOWN, 0, 0);
+
+ make_generic ("precision", GFC_ISYM_NONE);
+
+ add_sym_1 ("present", 0, 1, BT_LOGICAL, dl,
+ gfc_check_present, NULL, NULL, a, BT_REAL, dr, 0);
+
+ make_generic ("present", GFC_ISYM_PRESENT);
+
+ add_sym_3 ("product", 0, 1, BT_REAL, dr,
+ gfc_check_product, NULL, gfc_resolve_product,
+ ar, BT_REAL, dr, 0, dm, BT_INTEGER, ii, 1,
+ msk, BT_LOGICAL, dl, 1);
+
+ make_generic ("product", GFC_ISYM_PRODUCT);
+
+ add_sym_1 ("radix", 0, 1, BT_INTEGER, di,
+ gfc_check_radix, gfc_simplify_radix, NULL,
+ x, BT_UNKNOWN, 0, 0);
+
+ make_generic ("radix", GFC_ISYM_NONE);
+
+ add_sym_1 ("range", 0, 1, BT_INTEGER, di,
+ gfc_check_range, gfc_simplify_range, NULL,
+ x, BT_REAL, dr, 0);
+
+ make_generic ("range", GFC_ISYM_NONE);
+
+ add_sym_2 ("real", 1, 0, BT_REAL, dr,
+ gfc_check_real, gfc_simplify_real, gfc_resolve_real,
+ a, BT_UNKNOWN, dr, 0, kind, BT_INTEGER, di, 1);
+
+ add_sym_1 ("float", 1, 0, BT_REAL, dr,
+ NULL, gfc_simplify_float, NULL, a, BT_INTEGER, di, 0);
+
+ add_sym_1 ("sngl", 1, 0, BT_REAL, dr,
+ NULL, gfc_simplify_sngl, NULL, a, BT_REAL, dd, 0);
+
+ make_generic ("real", GFC_ISYM_REAL);
+
+ add_sym_2 ("repeat", 0, 1, BT_CHARACTER, dc,
+ gfc_check_repeat, gfc_simplify_repeat, gfc_resolve_repeat,
+ stg, BT_CHARACTER, dc, 0, n, BT_INTEGER, di, 0);
+
+ make_generic ("repeat", GFC_ISYM_REPEAT);
+
+ add_sym_4 ("reshape", 0, 1, BT_REAL, dr,
+ gfc_check_reshape, gfc_simplify_reshape, gfc_resolve_reshape,
+ src, BT_REAL, dr, 0, shp, BT_INTEGER, ii, 0,
+ pad, BT_REAL, dr, 1, ord, BT_INTEGER, ii, 1);
+
+ make_generic ("reshape", GFC_ISYM_RESHAPE);
+
+ add_sym_1 ("rrspacing", 1, 1, BT_REAL, dr,
+ gfc_check_x, gfc_simplify_rrspacing, gfc_resolve_rrspacing,
+ x, BT_REAL, dr, 0);
+
+ make_generic ("rrspacing", GFC_ISYM_RRSPACING);
+
+ add_sym_2 ("scale", 1, 1, BT_REAL, dr,
+ gfc_check_scale, gfc_simplify_scale, gfc_resolve_scale,
+ x, BT_REAL, dr, 0, i, BT_INTEGER, di, 0);
+
+ make_generic ("scale", GFC_ISYM_SCALE);
+
+ add_sym_3 ("scan", 1, 1, BT_INTEGER, di,
+ gfc_check_scan, gfc_simplify_scan, gfc_resolve_scan,
+ stg, BT_CHARACTER, dc, 0, set, BT_CHARACTER, dc, 0,
+ bck, BT_LOGICAL, dl, 1);
+
+ make_generic ("scan", GFC_ISYM_SCAN);
+
+ add_sym_1 ("selected_int_kind", 0, 1, BT_INTEGER, di,
+ NULL, gfc_simplify_selected_int_kind, NULL,
+ r, BT_INTEGER, di, 0);
+
+ make_generic ("selected_int_kind", GFC_ISYM_SI_KIND);
+
+ add_sym_2 ("selected_real_kind", 0, 1, BT_INTEGER, di,
+ gfc_check_selected_real_kind, gfc_simplify_selected_real_kind,
+ NULL, p, BT_INTEGER, di, 1, r, BT_INTEGER, di, 1);
+
+ make_generic ("selected_real_kind", GFC_ISYM_SR_KIND);
+
+ add_sym_2 ("set_exponent", 1, 1, BT_REAL, dr,
+ gfc_check_set_exponent, gfc_simplify_set_exponent,
+ gfc_resolve_set_exponent,
+ x, BT_REAL, dr, 0, i, BT_INTEGER, di, 0);
+
+ make_generic ("set_exponent", GFC_ISYM_SET_EXPONENT);
+
+ add_sym_1 ("shape", 0, 1, BT_INTEGER, di,
+ gfc_check_shape, gfc_simplify_shape, gfc_resolve_shape,
+ src, BT_REAL, dr, 0);
+
+ make_generic ("shape", GFC_ISYM_SHAPE);
+
+ add_sym_2 ("sign", 1, 1, BT_REAL, dr,
+ gfc_check_sign, gfc_simplify_sign, gfc_resolve_sign,
+ a, BT_REAL, dr, 0, b, BT_REAL, dr, 0);
+
+ add_sym_2 ("isign", 1, 1, BT_INTEGER, di,
+ NULL, gfc_simplify_sign, gfc_resolve_sign,
+ a, BT_INTEGER, di, 0, b, BT_INTEGER, di, 0);
+
+ add_sym_2 ("dsign", 1, 1, BT_REAL, dd,
+ NULL, gfc_simplify_sign, gfc_resolve_sign,
+ a, BT_REAL, dd, 0, b, BT_REAL, dd, 0);
+
+ make_generic ("sign", GFC_ISYM_SIGN);
+
+ add_sym_1 ("sin", 1, 1, BT_REAL, dr,
+ NULL, gfc_simplify_sin, gfc_resolve_sin, x, BT_REAL, dr, 0);
+
+ add_sym_1 ("dsin", 1, 1, BT_REAL, dd,
+ NULL, gfc_simplify_sin, gfc_resolve_sin, x, BT_REAL, dd, 0);
+
+ add_sym_1 ("csin", 1, 1, BT_COMPLEX, dz,
+ NULL, gfc_simplify_sin, gfc_resolve_sin,
+ x, BT_COMPLEX, dz, 0);
+
+ add_sym_1 ("zsin", 1, 1, BT_COMPLEX, dd, NULL, gfc_simplify_sin, gfc_resolve_sin, x, BT_COMPLEX, dd, 0); /* Extension */
+
+ make_alias ("cdsin");
+
+ make_generic ("sin", GFC_ISYM_SIN);
+
+ add_sym_1 ("sinh", 1, 1, BT_REAL, dr,
+ NULL, gfc_simplify_sinh, gfc_resolve_sinh,
+ x, BT_REAL, dr, 0);
+
+ add_sym_1 ("dsinh", 1, 1, BT_REAL, dd,
+ NULL, gfc_simplify_sinh, gfc_resolve_sinh,
+ x, BT_REAL, dd, 0);
+
+ make_generic ("sinh", GFC_ISYM_SINH);
+
+ add_sym_2 ("size", 0, 1, BT_INTEGER, di,
+ gfc_check_size, gfc_simplify_size, NULL,
+ ar, BT_REAL, dr, 0, dm, BT_INTEGER, ii, 1);
+
+ make_generic ("size", GFC_ISYM_SIZE);
+
+ add_sym_1 ("spacing", 1, 1, BT_REAL, dr,
+ gfc_check_x, gfc_simplify_spacing, gfc_resolve_spacing,
+ x, BT_REAL, dr, 0);
+
+ make_generic ("spacing", GFC_ISYM_SPACING);
+
+ add_sym_3 ("spread", 0, 1, BT_REAL, dr,
+ gfc_check_spread, NULL, gfc_resolve_spread,
+ src, BT_REAL, dr, 0, dm, BT_INTEGER, ii, 0,
+ n, BT_INTEGER, di, 0);
+
+ make_generic ("spread", GFC_ISYM_SPREAD);
+
+ add_sym_1 ("sqrt", 1, 1, BT_REAL, dr,
+ NULL, gfc_simplify_sqrt, gfc_resolve_sqrt,
+ x, BT_REAL, dr, 0);
+
+ add_sym_1 ("dsqrt", 1, 1, BT_REAL, dd,
+ NULL, gfc_simplify_sqrt, gfc_resolve_sqrt,
+ x, BT_REAL, dd, 0);
+
+ add_sym_1 ("csqrt", 1, 1, BT_COMPLEX, dz,
+ NULL, gfc_simplify_sqrt, gfc_resolve_sqrt,
+ x, BT_COMPLEX, dz, 0);
+
+ add_sym_1 ("zsqrt", 1, 1, BT_COMPLEX, dd, NULL, gfc_simplify_sqrt, gfc_resolve_sqrt, x, BT_COMPLEX, dd, 0); /* Extension */
+
+ make_alias ("cdsqrt");
+
+ make_generic ("sqrt", GFC_ISYM_SQRT);
+
+ add_sym_3 ("sum", 0, 1, BT_UNKNOWN, 0,
+ gfc_check_sum, NULL, gfc_resolve_sum,
+ ar, BT_REAL, dr, 0, dm, BT_INTEGER, ii, 1,
+ msk, BT_LOGICAL, dl, 1);
+
+ make_generic ("sum", GFC_ISYM_SUM);
+
+ add_sym_1 ("tan", 1, 1, BT_REAL, dr,
+ NULL, gfc_simplify_tan, gfc_resolve_tan, x, BT_REAL, dr, 0);
+
+ add_sym_1 ("dtan", 1, 1, BT_REAL, dd,
+ NULL, gfc_simplify_tan, gfc_resolve_tan, x, BT_REAL, dd, 0);
+
+ make_generic ("tan", GFC_ISYM_TAN);
+
+ add_sym_1 ("tanh", 1, 1, BT_REAL, dr,
+ NULL, gfc_simplify_tanh, gfc_resolve_tanh,
+ x, BT_REAL, dr, 0);
+
+ add_sym_1 ("dtanh", 1, 1, BT_REAL, dd,
+ NULL, gfc_simplify_tanh, gfc_resolve_tanh,
+ x, BT_REAL, dd, 0);
+
+ make_generic ("tanh", GFC_ISYM_TANH);
+
+ add_sym_1 ("tiny", 0, 1, BT_REAL, dr,
+ gfc_check_x, gfc_simplify_tiny, NULL, x, BT_REAL, dr, 0);
+
+ make_generic ("tiny", GFC_ISYM_NONE);
+
+ add_sym_3 ("transfer", 0, 1, BT_REAL, dr,
+ gfc_check_transfer, NULL, gfc_resolve_transfer,
+ src, BT_REAL, dr, 0, mo, BT_REAL, dr, 0,
+ sz, BT_INTEGER, di, 1);
+
+ make_generic ("transfer", GFC_ISYM_TRANSFER);
+
+ add_sym_1 ("transpose", 0, 1, BT_REAL, dr,
+ gfc_check_transpose, NULL, gfc_resolve_transpose,
+ m, BT_REAL, dr, 0);
+
+ make_generic ("transpose", GFC_ISYM_TRANSPOSE);
+
+ add_sym_1 ("trim", 0, 1, BT_CHARACTER, dc,
+ gfc_check_trim, gfc_simplify_trim, gfc_resolve_trim,
+ stg, BT_CHARACTER, dc, 0);
+
+ make_generic ("trim", GFC_ISYM_TRIM);
+
+ add_sym_2 ("ubound", 0, 1, BT_INTEGER, di,
+ gfc_check_ubound, gfc_simplify_ubound, gfc_resolve_ubound,
+ ar, BT_REAL, dr, 0, dm, BT_INTEGER, ii, 1);
+
+ make_generic ("ubound", GFC_ISYM_UBOUND);
+
+ add_sym_3 ("unpack", 0, 1, BT_REAL, dr,
+ gfc_check_unpack, NULL, gfc_resolve_unpack,
+ v, BT_REAL, dr, 0, msk, BT_LOGICAL, dl, 0,
+ f, BT_REAL, dr, 0);
+
+ make_generic ("unpack", GFC_ISYM_UNPACK);
+
+ add_sym_3 ("verify", 1, 1, BT_INTEGER, di,
+ gfc_check_verify, gfc_simplify_verify, gfc_resolve_verify,
+ stg, BT_CHARACTER, dc, 0, set, BT_CHARACTER, dc, 0,
+ bck, BT_LOGICAL, dl, 1);
+
+ make_generic ("verify", GFC_ISYM_VERIFY);
+}
+
+
+
+/* Add intrinsic subroutines. */
+
+static void
+add_subroutines (void)
+{
+ /* Argument names as in the standard (to be used as argument keywords). */
+ const char
+ *h = "harvest", *dt = "date", *vl = "values", *pt = "put",
+ *c = "count", *tm = "time", *tp = "topos", *gt = "get",
+ *t = "to", *zn = "zone", *fp = "frompos", *cm = "count_max",
+ *f = "from", *sz = "size", *ln = "len", *cr = "count_rate";
+
+ int di, dr, dc;
+
+ di = gfc_default_integer_kind ();
+ dr = gfc_default_real_kind ();
+ dc = gfc_default_character_kind ();
+
+ add_sym_0s ("abort", 1, NULL);
+
+ add_sym_1s ("cpu_time", 0, 1, BT_UNKNOWN, 0,
+ gfc_check_cpu_time, NULL, gfc_resolve_cpu_time,
+ tm, BT_REAL, dr, 0);
+
+ add_sym_4 ("date_and_time", 0, 1, BT_UNKNOWN, 0,
+ gfc_check_date_and_time, NULL, NULL,
+ dt, BT_CHARACTER, dc, 1, tm, BT_CHARACTER, dc, 1,
+ zn, BT_CHARACTER, dc, 1, vl, BT_INTEGER, di, 1);
+
+ add_sym_2 ("getarg", 0, 1, BT_UNKNOWN, 0,
+ NULL, NULL, NULL,
+ c, BT_INTEGER, di, 0, vl, BT_CHARACTER, dc, 0);
+ /* Extension */
+
+ add_sym_5 ("mvbits", 1, 1, BT_UNKNOWN, 0,
+ gfc_check_mvbits, gfc_simplify_mvbits, NULL,
+ f, BT_INTEGER, di, 0, fp, BT_INTEGER, di, 0,
+ ln, BT_INTEGER, di, 0, t, BT_INTEGER, di, 0,
+ tp, BT_INTEGER, di, 0);
+
+ add_sym_1s ("random_number", 0, 1, BT_UNKNOWN, 0,
+ gfc_check_random_number, NULL, gfc_resolve_random_number,
+ h, BT_REAL, dr, 0);
+
+ add_sym_3 ("random_seed", 0, 1, BT_UNKNOWN, 0,
+ gfc_check_random_seed, NULL, NULL,
+ sz, BT_INTEGER, di, 1, pt, BT_INTEGER, di, 1,
+ gt, BT_INTEGER, di, 1);
+
+ add_sym_3 ("system_clock", 0, 1, BT_UNKNOWN, 0,
+ NULL, NULL, NULL,
+ c, BT_INTEGER, di, 1, cr, BT_INTEGER, di, 1,
+ cm, BT_INTEGER, di, 1);
+}
+
+
+/* Add a function to the list of conversion symbols. */
+
+static void
+add_conv (bt from_type, int from_kind, bt to_type, int to_kind,
+ gfc_expr * (*simplify) (gfc_expr *, bt, int))
+{
+
+ gfc_typespec from, to;
+ gfc_intrinsic_sym *sym;
+
+ if (sizing == SZ_CONVS)
+ {
+ nconv++;
+ return;
+ }
+
+ gfc_clear_ts (&from);
+ from.type = from_type;
+ from.kind = from_kind;
+
+ gfc_clear_ts (&to);
+ to.type = to_type;
+ to.kind = to_kind;
+
+ sym = conversion + nconv;
+
+ strcpy (sym->name, conv_name (&from, &to));
+ strcpy (sym->lib_name, sym->name);
+ sym->simplify.cc = simplify;
+ sym->elemental = 1;
+ sym->ts = to;
+ sym->generic_id = GFC_ISYM_CONVERSION;
+
+ nconv++;
+}
+
+
+/* Create gfc_intrinsic_sym nodes for all intrinsic conversion
+ functions by looping over the kind tables. */
+
+static void
+add_conversions (void)
+{
+ int i, j;
+
+ /* Integer-Integer conversions. */
+ for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
+ for (j = 0; gfc_integer_kinds[j].kind != 0; j++)
+ {
+ if (i == j)
+ continue;
+
+ add_conv (BT_INTEGER, gfc_integer_kinds[i].kind,
+ BT_INTEGER, gfc_integer_kinds[j].kind, gfc_convert_constant);
+ }
+
+ /* Integer-Real/Complex conversions. */
+ for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
+ for (j = 0; gfc_real_kinds[j].kind != 0; j++)
+ {
+ add_conv (BT_INTEGER, gfc_integer_kinds[i].kind,
+ BT_REAL, gfc_real_kinds[j].kind, gfc_convert_constant);
+
+ add_conv (BT_REAL, gfc_real_kinds[j].kind,
+ BT_INTEGER, gfc_integer_kinds[i].kind, gfc_convert_constant);
+
+ add_conv (BT_INTEGER, gfc_integer_kinds[i].kind,
+ BT_COMPLEX, gfc_real_kinds[j].kind, gfc_convert_constant);
+
+ add_conv (BT_COMPLEX, gfc_real_kinds[j].kind,
+ BT_INTEGER, gfc_integer_kinds[i].kind, gfc_convert_constant);
+ }
+
+ /* Real/Complex - Real/Complex conversions. */
+ for (i = 0; gfc_real_kinds[i].kind != 0; i++)
+ for (j = 0; gfc_real_kinds[j].kind != 0; j++)
+ {
+ if (i != j)
+ {
+ add_conv (BT_REAL, gfc_real_kinds[i].kind,
+ BT_REAL, gfc_real_kinds[j].kind, gfc_convert_constant);
+
+ add_conv (BT_COMPLEX, gfc_real_kinds[i].kind,
+ BT_COMPLEX, gfc_real_kinds[j].kind, gfc_convert_constant);
+ }
+
+ add_conv (BT_REAL, gfc_real_kinds[i].kind,
+ BT_COMPLEX, gfc_real_kinds[j].kind, gfc_convert_constant);
+
+ add_conv (BT_COMPLEX, gfc_real_kinds[i].kind,
+ BT_REAL, gfc_real_kinds[j].kind, gfc_convert_constant);
+ }
+
+ /* Logical/Logical kind conversion. */
+ for (i = 0; gfc_logical_kinds[i].kind; i++)
+ for (j = 0; gfc_logical_kinds[j].kind; j++)
+ {
+ if (i == j)
+ continue;
+
+ add_conv (BT_LOGICAL, gfc_logical_kinds[i].kind,
+ BT_LOGICAL, gfc_logical_kinds[j].kind, gfc_convert_constant);
+ }
+}
+
+
+/* Initialize the table of intrinsics. */
+void
+gfc_intrinsic_init_1 (void)
+{
+ int i;
+
+ nargs = nfunc = nsub = nconv = 0;
+
+ /* Create a namespace to hold the resolved intrinsic symbols. */
+ gfc_intrinsic_namespace = gfc_get_namespace (NULL);
+
+ sizing = SZ_FUNCS;
+ add_functions ();
+ sizing = SZ_SUBS;
+ add_subroutines ();
+ sizing = SZ_CONVS;
+ add_conversions ();
+
+ functions = gfc_getmem (sizeof (gfc_intrinsic_sym) * (nfunc + nsub)
+ + sizeof (gfc_intrinsic_arg) * nargs);
+
+ next_sym = functions;
+ subroutines = functions + nfunc;
+
+ conversion = gfc_getmem (sizeof (gfc_intrinsic_sym) * nconv);
+
+ next_arg = ((gfc_intrinsic_arg *) (subroutines + nsub)) - 1;
+
+ sizing = SZ_NOTHING;
+ nconv = 0;
+
+ add_functions ();
+ add_subroutines ();
+ add_conversions ();
+
+ /* Set the pure flag. All intrinsic functions are pure, and
+ intrinsic subroutines are pure if they are elemental. */
+
+ for (i = 0; i < nfunc; i++)
+ functions[i].pure = 1;
+
+ for (i = 0; i < nsub; i++)
+ subroutines[i].pure = subroutines[i].elemental;
+}
+
+
+void
+gfc_intrinsic_done_1 (void)
+{
+ gfc_free (functions);
+ gfc_free (conversion);
+ gfc_free_namespace (gfc_intrinsic_namespace);
+}
+
+
+/******** Subroutines to check intrinsic interfaces ***********/
+
+/* Given a formal argument list, remove any NULL arguments that may
+ have been left behind by a sort against some formal argument list. */
+
+static void
+remove_nullargs (gfc_actual_arglist ** ap)
+{
+ gfc_actual_arglist *head, *tail, *next;
+
+ tail = NULL;
+
+ for (head = *ap; head; head = next)
+ {
+ next = head->next;
+
+ if (head->expr == NULL)
+ {
+ head->next = NULL;
+ gfc_free_actual_arglist (head);
+ }
+ else
+ {
+ if (tail == NULL)
+ *ap = head;
+ else
+ tail->next = head;
+
+ tail = head;
+ tail->next = NULL;
+ }
+ }
+
+ if (tail == NULL)
+ *ap = NULL;
+}
+
+
+/* Given an actual arglist and a formal arglist, sort the actual
+ arglist so that its arguments are in a one-to-one correspondence
+ with the format arglist. Arguments that are not present are given
+ a blank gfc_actual_arglist structure. If something is obviously
+ wrong (say, a missing required argument) we abort sorting and
+ return FAILURE. */
+
+static try
+sort_actual (const char *name, gfc_actual_arglist ** ap,
+ gfc_intrinsic_arg * formal, locus * where)
+{
+
+ gfc_actual_arglist *actual, *a;
+ gfc_intrinsic_arg *f;
+
+ remove_nullargs (ap);
+ actual = *ap;
+
+ for (f = formal; f; f = f->next)
+ f->actual = NULL;
+
+ f = formal;
+ a = actual;
+
+ if (f == NULL && a == NULL) /* No arguments */
+ return SUCCESS;
+
+ for (;;)
+ { /* Put the nonkeyword arguments in a 1:1 correspondence */
+ if (f == NULL)
+ break;
+ if (a == NULL)
+ goto optional;
+
+ if (a->name[0] != '\0')
+ goto keywords;
+
+ f->actual = a;
+
+ f = f->next;
+ a = a->next;
+ }
+
+ if (a == NULL)
+ goto do_sort;
+
+ gfc_error ("Too many arguments in call to '%s' at %L", name, where);
+ return FAILURE;
+
+keywords:
+ /* Associate the remaining actual arguments, all of which have
+ to be keyword arguments. */
+ for (; a; a = a->next)
+ {
+ for (f = formal; f; f = f->next)
+ if (strcmp (a->name, f->name) == 0)
+ break;
+
+ if (f == NULL)
+ {
+ gfc_error ("Can't find keyword named '%s' in call to '%s' at %L",
+ a->name, name, where);
+ return FAILURE;
+ }
+
+ if (f->actual != NULL)
+ {
+ gfc_error ("Argument '%s' is appears twice in call to '%s' at %L",
+ f->name, name, where);
+ return FAILURE;
+ }
+
+ f->actual = a;
+ }
+
+optional:
+ /* At this point, all unmatched formal args must be optional. */
+ for (f = formal; f; f = f->next)
+ {
+ if (f->actual == NULL && f->optional == 0)
+ {
+ gfc_error ("Missing actual argument '%s' in call to '%s' at %L",
+ f->name, name, where);
+ return FAILURE;
+ }
+ }
+
+do_sort:
+ /* Using the formal argument list, string the actual argument list
+ together in a way that corresponds with the formal list. */
+ actual = NULL;
+
+ for (f = formal; f; f = f->next)
+ {
+ a = (f->actual == NULL) ? gfc_get_actual_arglist () : f->actual;
+
+ if (actual == NULL)
+ *ap = a;
+ else
+ actual->next = a;
+
+ actual = a;
+ }
+ actual->next = NULL; /* End the sorted argument list. */
+
+ return SUCCESS;
+}
+
+
+/* Compare an actual argument list with an intrinsic's formal argument
+ list. The lists are checked for agreement of type. We don't check
+ for arrayness here. */
+
+static try
+check_arglist (gfc_actual_arglist ** ap, gfc_intrinsic_sym * sym,
+ int error_flag)
+{
+ gfc_actual_arglist *actual;
+ gfc_intrinsic_arg *formal;
+ int i;
+
+ formal = sym->formal;
+ actual = *ap;
+
+ i = 0;
+ for (; formal; formal = formal->next, actual = actual->next, i++)
+ {
+ if (actual->expr == NULL)
+ continue;
+
+ if (!gfc_compare_types (&formal->ts, &actual->expr->ts))
+ {
+ if (error_flag)
+ gfc_error
+ ("Type of argument '%s' in call to '%s' at %L should be "
+ "%s, not %s", gfc_current_intrinsic_arg[i],
+ gfc_current_intrinsic, &actual->expr->where,
+ gfc_typename (&formal->ts), gfc_typename (&actual->expr->ts));
+ return FAILURE;
+ }
+ }
+
+ return SUCCESS;
+}
+
+
+/* Given a pointer to an intrinsic symbol and an expression node that
+ represent the function call to that subroutine, figure out the type
+ of the result. This may involve calling a resolution subroutine. */
+
+static void
+resolve_intrinsic (gfc_intrinsic_sym * specific, gfc_expr * e)
+{
+ gfc_expr *a1, *a2, *a3, *a4, *a5;
+ gfc_actual_arglist *arg;
+
+ if (specific->resolve.f1 == NULL)
+ {
+ if (e->value.function.name == NULL)
+ e->value.function.name = specific->lib_name;
+
+ if (e->ts.type == BT_UNKNOWN)
+ e->ts = specific->ts;
+ return;
+ }
+
+ arg = e->value.function.actual;
+
+ /* At present only the iargc extension intrinsic takes no arguments,
+ and it doesn't need a resolution function, but this is here for
+ generality. */
+ if (arg == NULL)
+ {
+ (*specific->resolve.f0) (e);
+ return;
+ }
+
+ /* Special case hacks for MIN and MAX. */
+ if (specific->resolve.f1m == gfc_resolve_max
+ || specific->resolve.f1m == gfc_resolve_min)
+ {
+ (*specific->resolve.f1m) (e, arg);
+ return;
+ }
+
+ a1 = arg->expr;
+ arg = arg->next;
+
+ if (arg == NULL)
+ {
+ (*specific->resolve.f1) (e, a1);
+ return;
+ }
+
+ a2 = arg->expr;
+ arg = arg->next;
+
+ if (arg == NULL)
+ {
+ (*specific->resolve.f2) (e, a1, a2);
+ return;
+ }
+
+ a3 = arg->expr;
+ arg = arg->next;
+
+ if (arg == NULL)
+ {
+ (*specific->resolve.f3) (e, a1, a2, a3);
+ return;
+ }
+
+ a4 = arg->expr;
+ arg = arg->next;
+
+ if (arg == NULL)
+ {
+ (*specific->resolve.f4) (e, a1, a2, a3, a4);
+ return;
+ }
+
+ a5 = arg->expr;
+ arg = arg->next;
+
+ if (arg == NULL)
+ {
+ (*specific->resolve.f5) (e, a1, a2, a3, a4, a5);
+ return;
+ }
+
+ gfc_internal_error ("resolve_intrinsic(): Too many args for intrinsic");
+}
+
+
+/* Given an intrinsic symbol node and an expression node, call the
+ simplification function (if there is one), perhaps replacing the
+ expression with something simpler. We return FAILURE on an error
+ of the simplification, SUCCESS if the simplification worked, even
+ if nothing has changed in the expression itself. */
+
+static try
+do_simplify (gfc_intrinsic_sym * specific, gfc_expr * e)
+{
+ gfc_expr *result, *a1, *a2, *a3, *a4, *a5;
+ gfc_actual_arglist *arg;
+
+ /* Max and min require special handling due to the variable number
+ of args. */
+ if (specific->simplify.f1 == gfc_simplify_min)
+ {
+ result = gfc_simplify_min (e);
+ goto finish;
+ }
+
+ if (specific->simplify.f1 == gfc_simplify_max)
+ {
+ result = gfc_simplify_max (e);
+ goto finish;
+ }
+
+ if (specific->simplify.f1 == NULL)
+ {
+ result = NULL;
+ goto finish;
+ }
+
+ arg = e->value.function.actual;
+
+ a1 = arg->expr;
+ arg = arg->next;
+
+ if (specific->simplify.cc == gfc_convert_constant)
+ {
+ result = gfc_convert_constant (a1, specific->ts.type, specific->ts.kind);
+ goto finish;
+ }
+
+ /* TODO: Warn if -pedantic and initialization expression and arg
+ types not integer or character */
+
+ if (arg == NULL)
+ result = (*specific->simplify.f1) (a1);
+ else
+ {
+ a2 = arg->expr;
+ arg = arg->next;
+
+ if (arg == NULL)
+ result = (*specific->simplify.f2) (a1, a2);
+ else
+ {
+ a3 = arg->expr;
+ arg = arg->next;
+
+ if (arg == NULL)
+ result = (*specific->simplify.f3) (a1, a2, a3);
+ else
+ {
+ a4 = arg->expr;
+ arg = arg->next;
+
+ if (arg == NULL)
+ result = (*specific->simplify.f4) (a1, a2, a3, a4);
+ else
+ {
+ a5 = arg->expr;
+ arg = arg->next;
+
+ if (arg == NULL)
+ result = (*specific->simplify.f5) (a1, a2, a3, a4, a5);
+ else
+ gfc_internal_error
+ ("do_simplify(): Too many args for intrinsic");
+ }
+ }
+ }
+ }
+
+finish:
+ if (result == &gfc_bad_expr)
+ return FAILURE;
+
+ if (result == NULL)
+ resolve_intrinsic (specific, e); /* Must call at run-time */
+ else
+ {
+ result->where = e->where;
+ gfc_replace_expr (e, result);
+ }
+
+ return SUCCESS;
+}
+
+
+/* Initialize the gfc_current_intrinsic_arg[] array for the benefit of
+ error messages. This subroutine returns FAILURE if a subroutine
+ has more than MAX_INTRINSIC_ARGS, in which case the actual argument
+ list cannot match any intrinsic. */
+
+static void
+init_arglist (gfc_intrinsic_sym * isym)
+{
+ gfc_intrinsic_arg *formal;
+ int i;
+
+ gfc_current_intrinsic = isym->name;
+
+ i = 0;
+ for (formal = isym->formal; formal; formal = formal->next)
+ {
+ if (i >= MAX_INTRINSIC_ARGS)
+ gfc_internal_error ("init_arglist(): too many arguments");
+ gfc_current_intrinsic_arg[i++] = formal->name;
+ }
+}
+
+
+/* Given a pointer to an intrinsic symbol and an expression consisting
+ of a function call, see if the function call is consistent with the
+ intrinsic's formal argument list. Return SUCCESS if the expression
+ and intrinsic match, FAILURE otherwise. */
+
+static try
+check_specific (gfc_intrinsic_sym * specific, gfc_expr * expr, int error_flag)
+{
+ gfc_actual_arglist *arg, **ap;
+ int r;
+ try t;
+
+ ap = &expr->value.function.actual;
+
+ init_arglist (specific);
+
+ /* Don't attempt to sort the argument list for min or max. */
+ if (specific->check.f1m == gfc_check_min_max
+ || specific->check.f1m == gfc_check_min_max_integer
+ || specific->check.f1m == gfc_check_min_max_real
+ || specific->check.f1m == gfc_check_min_max_double)
+ return (*specific->check.f1m) (*ap);
+
+ if (sort_actual (specific->name, ap, specific->formal,
+ &expr->where) == FAILURE)
+ return FAILURE;
+
+ if (specific->check.f1 == NULL)
+ {
+ t = check_arglist (ap, specific, error_flag);
+ if (t == SUCCESS)
+ expr->ts = specific->ts;
+ }
+ else
+ t = do_check (specific, *ap);
+
+ /* Check ranks for elemental intrinsics. */
+ if (t == SUCCESS && specific->elemental)
+ {
+ r = 0;
+ for (arg = expr->value.function.actual; arg; arg = arg->next)
+ {
+ if (arg->expr == NULL || arg->expr->rank == 0)
+ continue;
+ if (r == 0)
+ {
+ r = arg->expr->rank;
+ continue;
+ }
+
+ if (arg->expr->rank != r)
+ {
+ gfc_error
+ ("Ranks of arguments to elemental intrinsic '%s' differ "
+ "at %L", specific->name, &arg->expr->where);
+ return FAILURE;
+ }
+ }
+ }
+
+ if (t == FAILURE)
+ remove_nullargs (ap);
+
+ return t;
+}
+
+
+/* See if an intrinsic is one of the intrinsics we evaluate
+ as an extension. */
+
+static int
+gfc_init_expr_extensions (gfc_intrinsic_sym *isym)
+{
+ /* FIXME: This should be moved into the intrinsic definitions. */
+ static const char * const init_expr_extensions[] = {
+ "digits", "epsilon", "huge", "kind", "maxexponent", "minexponent",
+ "precision", "present", "radix", "range", "selected_real_kind",
+ "tiny", NULL
+ };
+
+ int i;
+
+ for (i = 0; init_expr_extensions[i]; i++)
+ if (strcmp (init_expr_extensions[i], isym->name) == 0)
+ return 0;
+
+ return 1;
+}
+
+
+/* See if a function call corresponds to an intrinsic function call.
+ We return:
+
+ MATCH_YES if the call corresponds to an intrinsic, simplification
+ is done if possible.
+
+ MATCH_NO if the call does not correspond to an intrinsic
+
+ MATCH_ERROR if the call corresponds to an intrinsic but there was an
+ error during the simplification process.
+
+ The error_flag parameter enables an error reporting. */
+
+match
+gfc_intrinsic_func_interface (gfc_expr * expr, int error_flag)
+{
+ gfc_intrinsic_sym *isym, *specific;
+ gfc_actual_arglist *actual;
+ const char *name;
+ int flag;
+
+ if (expr->value.function.isym != NULL)
+ return (do_simplify (expr->value.function.isym, expr) == FAILURE)
+ ? MATCH_ERROR : MATCH_YES;
+
+ gfc_suppress_error = !error_flag;
+ flag = 0;
+
+ for (actual = expr->value.function.actual; actual; actual = actual->next)
+ if (actual->expr != NULL)
+ flag |= (actual->expr->ts.type != BT_INTEGER
+ && actual->expr->ts.type != BT_CHARACTER);
+
+ name = expr->symtree->n.sym->name;
+
+ isym = specific = gfc_find_function (name);
+ if (isym == NULL)
+ {
+ gfc_suppress_error = 0;
+ return MATCH_NO;
+ }
+
+ gfc_current_intrinsic_where = &expr->where;
+
+ /* Bypass the generic list for min and max. */
+ if (isym->check.f1m == gfc_check_min_max)
+ {
+ init_arglist (isym);
+
+ if (gfc_check_min_max (expr->value.function.actual) == SUCCESS)
+ goto got_specific;
+
+ gfc_suppress_error = 0;
+ return MATCH_NO;
+ }
+
+ /* If the function is generic, check all of its specific
+ incarnations. If the generic name is also a specific, we check
+ that name last, so that any error message will correspond to the
+ specific. */
+ gfc_suppress_error = 1;
+
+ if (isym->generic)
+ {
+ for (specific = isym->specific_head; specific;
+ specific = specific->next)
+ {
+ if (specific == isym)
+ continue;
+ if (check_specific (specific, expr, 0) == SUCCESS)
+ goto got_specific;
+ }
+ }
+
+ gfc_suppress_error = !error_flag;
+
+ if (check_specific (isym, expr, error_flag) == FAILURE)
+ {
+ gfc_suppress_error = 0;
+ return MATCH_NO;
+ }
+
+ specific = isym;
+
+got_specific:
+ expr->value.function.isym = specific;
+ gfc_intrinsic_symbol (expr->symtree->n.sym);
+
+ if (do_simplify (specific, expr) == FAILURE)
+ {
+ gfc_suppress_error = 0;
+ return MATCH_ERROR;
+ }
+
+ /* TODO: We should probably only allow elemental functions here. */
+ flag |= (expr->ts.type != BT_INTEGER && expr->ts.type != BT_CHARACTER);
+
+ gfc_suppress_error = 0;
+ if (pedantic && gfc_init_expr
+ && flag && gfc_init_expr_extensions (specific))
+ {
+ if (gfc_notify_std (GFC_STD_GNU, "Extension: Evaluation of "
+ "nonstandard initialization expression at %L", &expr->where)
+ == FAILURE)
+ {
+ return MATCH_ERROR;
+ }
+ }
+
+ return MATCH_YES;
+}
+
+
+/* See if a CALL statement corresponds to an intrinsic subroutine.
+ Returns MATCH_YES if the subroutine corresponds to an intrinsic,
+ MATCH_NO if not, and MATCH_ERROR if there was an error (but did
+ correspond). */
+
+match
+gfc_intrinsic_sub_interface (gfc_code * c, int error_flag)
+{
+ gfc_intrinsic_sym *isym;
+ const char *name;
+
+ name = c->symtree->n.sym->name;
+
+ isym = find_subroutine (name);
+ if (isym == NULL)
+ return MATCH_NO;
+
+ gfc_suppress_error = !error_flag;
+
+ init_arglist (isym);
+
+ if (sort_actual (name, &c->ext.actual, isym->formal, &c->loc) == FAILURE)
+ goto fail;
+
+ if (isym->check.f1 != NULL)
+ {
+ if (do_check (isym, c->ext.actual) == FAILURE)
+ goto fail;
+ }
+ else
+ {
+ if (check_arglist (&c->ext.actual, isym, 1) == FAILURE)
+ goto fail;
+ }
+
+ /* The subroutine corresponds to an intrinsic. Allow errors to be
+ seen at this point. */
+ gfc_suppress_error = 0;
+
+ if (isym->resolve.s1 != NULL)
+ isym->resolve.s1 (c);
+ else
+ c->resolved_sym = gfc_get_intrinsic_sub_symbol (isym->lib_name);
+
+ if (gfc_pure (NULL) && !isym->elemental)
+ {
+ gfc_error ("Subroutine call to intrinsic '%s' at %L is not PURE", name,
+ &c->loc);
+ return MATCH_ERROR;
+ }
+
+ return MATCH_YES;
+
+fail:
+ gfc_suppress_error = 0;
+ return MATCH_NO;
+}
+
+
+/* Call gfc_convert_type() with warning enabled. */
+
+try
+gfc_convert_type (gfc_expr * expr, gfc_typespec * ts, int eflag)
+{
+ return gfc_convert_type_warn (expr, ts, eflag, 1);
+}
+
+
+/* Try to convert an expression (in place) from one type to another.
+ 'eflag' controls the behavior on error.
+
+ The possible values are:
+
+ 1 Generate a gfc_error()
+ 2 Generate a gfc_internal_error().
+
+ 'wflag' controls the warning related to conversion. */
+
+try
+gfc_convert_type_warn (gfc_expr * expr, gfc_typespec * ts, int eflag,
+ int wflag)
+{
+ gfc_intrinsic_sym *sym;
+ gfc_typespec from_ts;
+ locus old_where;
+ gfc_expr *new;
+ int rank;
+
+ from_ts = expr->ts; /* expr->ts gets clobbered */
+
+ if (ts->type == BT_UNKNOWN)
+ goto bad;
+
+ /* NULL and zero size arrays get their type here. */
+ if (expr->expr_type == EXPR_NULL
+ || (expr->expr_type == EXPR_ARRAY
+ && expr->value.constructor == NULL))
+ {
+ /* Sometimes the RHS acquire the type. */
+ expr->ts = *ts;
+ return SUCCESS;
+ }
+
+ if (expr->ts.type == BT_UNKNOWN)
+ goto bad;
+
+ if (expr->ts.type == BT_DERIVED
+ && ts->type == BT_DERIVED
+ && gfc_compare_types (&expr->ts, ts))
+ return SUCCESS;
+
+ sym = find_conv (&expr->ts, ts);
+ if (sym == NULL)
+ goto bad;
+
+ /* At this point, a conversion is necessary. A warning may be needed. */
+ if (wflag && gfc_option.warn_conversion)
+ gfc_warning_now ("Conversion from %s to %s at %L",
+ gfc_typename (&from_ts), gfc_typename (ts), &expr->where);
+
+ /* Insert a pre-resolved function call to the right function. */
+ old_where = expr->where;
+ rank = expr->rank;
+ new = gfc_get_expr ();
+ *new = *expr;
+
+ new = gfc_build_conversion (new);
+ new->value.function.name = sym->lib_name;
+ new->value.function.isym = sym;
+ new->where = old_where;
+ new->rank = rank;
+
+ *expr = *new;
+
+ gfc_free (new);
+ expr->ts = *ts;
+
+ if (gfc_is_constant_expr (expr->value.function.actual->expr)
+ && do_simplify (sym, expr) == FAILURE)
+ {
+
+ if (eflag == 2)
+ goto bad;
+ return FAILURE; /* Error already generated in do_simplify() */
+ }
+
+ return SUCCESS;
+
+bad:
+ if (eflag == 1)
+ {
+ gfc_error ("Can't convert %s to %s at %L",
+ gfc_typename (&from_ts), gfc_typename (ts), &expr->where);
+ return FAILURE;
+ }
+
+ gfc_internal_error ("Can't convert %s to %s at %L",
+ gfc_typename (&from_ts), gfc_typename (ts),
+ &expr->where);
+ /* Not reached */
+}
diff --git a/gcc/fortran/intrinsic.h b/gcc/fortran/intrinsic.h
new file mode 100644
index 00000000000..fa39a3e4234
--- /dev/null
+++ b/gcc/fortran/intrinsic.h
@@ -0,0 +1,315 @@
+/* Header file for intrinsics check, resolve and simplify function
+ prototypes.
+ Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught & Katherine Holcomb
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Expression returned when simplification fails. */
+
+extern gfc_expr gfc_bad_expr;
+
+
+/* Check functions. */
+try gfc_check_a_ikind (gfc_expr *, gfc_expr *);
+try gfc_check_a_xkind (gfc_expr *, gfc_expr *);
+try gfc_check_a_p (gfc_expr *, gfc_expr *);
+
+try gfc_check_abs (gfc_expr *);
+try gfc_check_all_any (gfc_expr *, gfc_expr *);
+try gfc_check_allocated (gfc_expr *);
+try gfc_check_associated (gfc_expr *, gfc_expr *);
+try gfc_check_btest (gfc_expr *, gfc_expr *);
+try gfc_check_char (gfc_expr *, gfc_expr *);
+try gfc_check_cmplx (gfc_expr *, gfc_expr *, gfc_expr *);
+try gfc_check_count (gfc_expr *, gfc_expr *);
+try gfc_check_cshift (gfc_expr *, gfc_expr *, gfc_expr *);
+try gfc_check_dcmplx (gfc_expr *, gfc_expr *);
+try gfc_check_dble (gfc_expr *);
+try gfc_check_digits (gfc_expr *);
+try gfc_check_dot_product (gfc_expr *, gfc_expr *);
+try gfc_check_eoshift (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
+try gfc_check_huge (gfc_expr *);
+try gfc_check_i (gfc_expr *);
+try gfc_check_iand (gfc_expr *, gfc_expr *);
+try gfc_check_ibclr (gfc_expr *, gfc_expr *);
+try gfc_check_ibits (gfc_expr *, gfc_expr *, gfc_expr *);
+try gfc_check_ibset (gfc_expr *, gfc_expr *);
+try gfc_check_idnint (gfc_expr *);
+try gfc_check_ieor (gfc_expr *, gfc_expr *);
+try gfc_check_index (gfc_expr *, gfc_expr *, gfc_expr *);
+try gfc_check_int (gfc_expr *, gfc_expr *);
+try gfc_check_ior (gfc_expr *, gfc_expr *);
+try gfc_check_ishft (gfc_expr *, gfc_expr *);
+try gfc_check_ishftc (gfc_expr *, gfc_expr *, gfc_expr *);
+try gfc_check_kind (gfc_expr *);
+try gfc_check_lbound (gfc_expr *, gfc_expr *);
+try gfc_check_logical (gfc_expr *, gfc_expr *);
+try gfc_check_min_max (gfc_actual_arglist *);
+try gfc_check_min_max_integer (gfc_actual_arglist *);
+try gfc_check_min_max_real (gfc_actual_arglist *);
+try gfc_check_min_max_double (gfc_actual_arglist *);
+try gfc_check_matmul (gfc_expr *, gfc_expr *);
+try gfc_check_merge (gfc_expr *, gfc_expr *, gfc_expr *);
+try gfc_check_minloc_maxloc (gfc_expr *, gfc_expr *, gfc_expr *);
+try gfc_check_minval_maxval (gfc_expr *, gfc_expr *, gfc_expr *);
+try gfc_check_nearest (gfc_expr *, gfc_expr *);
+try gfc_check_null (gfc_expr *);
+try gfc_check_pack (gfc_expr *, gfc_expr *, gfc_expr *);
+try gfc_check_precision (gfc_expr *);
+try gfc_check_present (gfc_expr *);
+try gfc_check_product (gfc_expr *, gfc_expr *, gfc_expr *);
+try gfc_check_radix (gfc_expr *);
+try gfc_check_range (gfc_expr *);
+try gfc_check_real (gfc_expr *, gfc_expr *);
+try gfc_check_repeat (gfc_expr *, gfc_expr *);
+try gfc_check_reshape (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
+try gfc_check_scale (gfc_expr *, gfc_expr *);
+try gfc_check_scan (gfc_expr *, gfc_expr *, gfc_expr *);
+try gfc_check_selected_real_kind (gfc_expr *, gfc_expr *);
+try gfc_check_set_exponent (gfc_expr *, gfc_expr *);
+try gfc_check_shape (gfc_expr *);
+try gfc_check_size (gfc_expr *, gfc_expr *);
+try gfc_check_sign (gfc_expr *, gfc_expr *);
+try gfc_check_spread (gfc_expr *, gfc_expr *, gfc_expr *);
+try gfc_check_sum (gfc_expr *, gfc_expr *, gfc_expr *);
+try gfc_check_transfer (gfc_expr *, gfc_expr *, gfc_expr *);
+try gfc_check_transpose (gfc_expr *);
+try gfc_check_trim (gfc_expr *);
+try gfc_check_ubound (gfc_expr *, gfc_expr *);
+try gfc_check_unpack (gfc_expr *, gfc_expr *, gfc_expr *);
+try gfc_check_verify (gfc_expr *, gfc_expr *, gfc_expr *);
+try gfc_check_x (gfc_expr *);
+
+
+/* Intrinsic subroutines. */
+try gfc_check_cpu_time (gfc_expr *);
+try gfc_check_date_and_time (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
+try gfc_check_mvbits (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *,
+ gfc_expr *);
+try gfc_check_random_number (gfc_expr *);
+try gfc_check_random_seed (gfc_expr *, gfc_expr *, gfc_expr *);
+
+
+/* Simplification functions. */
+gfc_expr *gfc_simplify_abs (gfc_expr *);
+gfc_expr *gfc_simplify_achar (gfc_expr *);
+gfc_expr *gfc_simplify_acos (gfc_expr *);
+gfc_expr *gfc_simplify_adjustl (gfc_expr *);
+gfc_expr *gfc_simplify_adjustr (gfc_expr *);
+gfc_expr *gfc_simplify_aimag (gfc_expr *);
+gfc_expr *gfc_simplify_aint (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_dint (gfc_expr *);
+gfc_expr *gfc_simplify_anint (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_dnint (gfc_expr *);
+gfc_expr *gfc_simplify_asin (gfc_expr *);
+gfc_expr *gfc_simplify_atan (gfc_expr *);
+gfc_expr *gfc_simplify_atan2 (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_bit_size (gfc_expr *);
+gfc_expr *gfc_simplify_btest (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_ceiling (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_char (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_cmplx (gfc_expr *, gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_conjg (gfc_expr *);
+gfc_expr *gfc_simplify_cos (gfc_expr *);
+gfc_expr *gfc_simplify_cosh (gfc_expr *);
+gfc_expr *gfc_simplify_dcmplx (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_dble (gfc_expr *);
+gfc_expr *gfc_simplify_digits (gfc_expr *);
+gfc_expr *gfc_simplify_dim (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_dprod (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_epsilon (gfc_expr *);
+gfc_expr *gfc_simplify_exp (gfc_expr *);
+gfc_expr *gfc_simplify_exponent (gfc_expr *);
+gfc_expr *gfc_simplify_float (gfc_expr *);
+gfc_expr *gfc_simplify_floor (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_fraction (gfc_expr *);
+gfc_expr *gfc_simplify_huge (gfc_expr *);
+gfc_expr *gfc_simplify_iachar (gfc_expr *);
+gfc_expr *gfc_simplify_iand (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_ibclr (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_ibits (gfc_expr *, gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_ibset (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_ichar (gfc_expr *);
+gfc_expr *gfc_simplify_ieor (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_index (gfc_expr *, gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_int (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_ifix (gfc_expr *);
+gfc_expr *gfc_simplify_idint (gfc_expr *);
+gfc_expr *gfc_simplify_ior (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_ishft (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_ishftc (gfc_expr *, gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_kind (gfc_expr *);
+gfc_expr *gfc_simplify_lbound (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_len (gfc_expr *);
+gfc_expr *gfc_simplify_len_trim (gfc_expr *);
+gfc_expr *gfc_simplify_lge (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_lgt (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_lle (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_llt (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_log (gfc_expr *);
+gfc_expr *gfc_simplify_log10 (gfc_expr *);
+gfc_expr *gfc_simplify_logical (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_min (gfc_expr *);
+gfc_expr *gfc_simplify_max (gfc_expr *);
+gfc_expr *gfc_simplify_maxexponent (gfc_expr *);
+gfc_expr *gfc_simplify_minexponent (gfc_expr *);
+gfc_expr *gfc_simplify_mod (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_modulo (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_mvbits (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *,
+ gfc_expr *);
+gfc_expr *gfc_simplify_nearest (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_nint (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_null (gfc_expr *);
+gfc_expr *gfc_simplify_idnint (gfc_expr *);
+gfc_expr *gfc_simplify_not (gfc_expr *);
+gfc_expr *gfc_simplify_precision (gfc_expr *);
+gfc_expr *gfc_simplify_radix (gfc_expr *);
+gfc_expr *gfc_simplify_range (gfc_expr *);
+gfc_expr *gfc_simplify_real (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_repeat (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_reshape (gfc_expr *, gfc_expr *, gfc_expr *,
+ gfc_expr *);
+gfc_expr *gfc_simplify_rrspacing (gfc_expr *);
+gfc_expr *gfc_simplify_scale (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_scan (gfc_expr *, gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_selected_int_kind (gfc_expr *);
+gfc_expr *gfc_simplify_selected_real_kind (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_set_exponent (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_sign (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_shape (gfc_expr *);
+gfc_expr *gfc_simplify_sin (gfc_expr *);
+gfc_expr *gfc_simplify_sinh (gfc_expr *);
+gfc_expr *gfc_simplify_size (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_sngl (gfc_expr *);
+gfc_expr *gfc_simplify_spacing (gfc_expr *);
+gfc_expr *gfc_simplify_sqrt (gfc_expr *);
+gfc_expr *gfc_simplify_tan (gfc_expr *);
+gfc_expr *gfc_simplify_tanh (gfc_expr *);
+gfc_expr *gfc_simplify_tiny (gfc_expr *);
+gfc_expr *gfc_simplify_trim (gfc_expr *);
+gfc_expr *gfc_simplify_ubound (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_verify (gfc_expr *, gfc_expr *, gfc_expr *);
+
+/* Constant conversion simplification. */
+gfc_expr *gfc_convert_constant (gfc_expr *, bt, int);
+
+
+/* Resolution functions. */
+void gfc_resolve_abs (gfc_expr *, gfc_expr *);
+void gfc_resolve_acos (gfc_expr *, gfc_expr *);
+void gfc_resolve_aimag (gfc_expr *, gfc_expr *);
+void gfc_resolve_aint (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_dint (gfc_expr *, gfc_expr *);
+void gfc_resolve_all (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_anint (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_dnint (gfc_expr *, gfc_expr *);
+void gfc_resolve_any (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_asin (gfc_expr *, gfc_expr *);
+void gfc_resolve_atan (gfc_expr *, gfc_expr *);
+void gfc_resolve_atan2 (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_btest (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_ceiling (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_char (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_cmplx (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_dcmplx (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_conjg (gfc_expr *, gfc_expr *);
+void gfc_resolve_cos (gfc_expr *, gfc_expr *);
+void gfc_resolve_cosh (gfc_expr *, gfc_expr *);
+void gfc_resolve_count (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_cshift (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_dble (gfc_expr *, gfc_expr *);
+void gfc_resolve_dim (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_dot_product (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_dprod (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_eoshift (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *,
+ gfc_expr *);
+void gfc_resolve_exp (gfc_expr *, gfc_expr *);
+void gfc_resolve_exponent (gfc_expr *, gfc_expr *);
+void gfc_resolve_floor (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_fraction (gfc_expr *, gfc_expr *);
+void gfc_resolve_iand (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_ibclr (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_ibits (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_ibset (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_ieor (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_ichar (gfc_expr *, gfc_expr *);
+void gfc_resolve_idnint (gfc_expr *, gfc_expr *);
+void gfc_resolve_int (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_ior (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_ishft (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_ishftc (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_lbound (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_len (gfc_expr *, gfc_expr *);
+void gfc_resolve_len_trim (gfc_expr *, gfc_expr *);
+void gfc_resolve_log (gfc_expr *, gfc_expr *);
+void gfc_resolve_log10 (gfc_expr *, gfc_expr *);
+void gfc_resolve_logical (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_matmul (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_max (gfc_expr *, gfc_actual_arglist *);
+void gfc_resolve_maxloc (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_maxval (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_merge (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_min (gfc_expr *, gfc_actual_arglist *);
+void gfc_resolve_minloc (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_minval (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_mod (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_modulo (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_nearest (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_nint (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_not (gfc_expr *, gfc_expr *);
+void gfc_resolve_pack (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_product (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_real (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_repeat (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_reshape (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *,
+ gfc_expr *);
+void gfc_resolve_rrspacing (gfc_expr *, gfc_expr *);
+void gfc_resolve_scale (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_scan (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_set_exponent (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_shape (gfc_expr *, gfc_expr *);
+void gfc_resolve_sign (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_sin (gfc_expr *, gfc_expr *);
+void gfc_resolve_sinh (gfc_expr *, gfc_expr *);
+void gfc_resolve_spacing (gfc_expr *, gfc_expr *);
+void gfc_resolve_spread (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_sqrt (gfc_expr *, gfc_expr *);
+void gfc_resolve_sum (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_tan (gfc_expr *, gfc_expr *);
+void gfc_resolve_tanh (gfc_expr *, gfc_expr *);
+void gfc_resolve_transfer (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_transpose (gfc_expr *, gfc_expr *);
+void gfc_resolve_trim (gfc_expr *, gfc_expr *);
+void gfc_resolve_ubound (gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_unpack (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_verify (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
+
+
+/* Intrinsic subroutine resolution. */
+void gfc_resolve_cpu_time (gfc_code *);
+void gfc_resolve_random_number (gfc_code *);
+
+
+/* The mvbits() subroutine requires the most arguments: five. */
+
+#define MAX_INTRINSIC_ARGS 5
+
+extern char *gfc_current_intrinsic,
+ *gfc_current_intrinsic_arg[MAX_INTRINSIC_ARGS];
+extern locus *gfc_current_intrinsic_where;
diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi
new file mode 100644
index 00000000000..88330e1bda0
--- /dev/null
+++ b/gcc/fortran/invoke.texi
@@ -0,0 +1,656 @@
+@c Copyright (C) 2004
+@c Free Software Foundation, Inc.
+@c This is part of the GFORTRAN manual.
+@c For copying conditions, see the file gfortran.texi.
+
+@ignore
+@c man begin COPYRIGHT
+Copyright @copyright{} 2004
+Free Software Foundation, Inc.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.2 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being ``GNU General Public License'' and ``Funding
+Free Software'', the Front-Cover texts being (a) (see below), and with
+the Back-Cover Texts being (b) (see below). A copy of the license is
+included in the gfdl(7) man page.
+
+(a) The FSF's Front-Cover Text is:
+
+ A GNU Manual
+
+(b) The FSF's Back-Cover Text is:
+
+ You have freedom to copy and modify this GNU Manual, like GNU
+ software. Copies published by the Free Software Foundation raise
+ funds for GNU development.
+@c man end
+@c Set file name and title for the man page.
+@setfilename gfortran
+@settitle GNU Fortran 95 compiler.
+@c man begin SYNOPSIS
+gfortran [@option{-c}|@option{-S}|@option{-E}]
+ [@option{-g}] [@option{-pg}] [@option{-O}@var{level}]
+ [@option{-W}@var{warn}@dots{}] [@option{-pedantic}]
+ [@option{-I}@var{dir}@dots{}] [@option{-L}@var{dir}@dots{}]
+ [@option{-D}@var{macro}[=@var{defn}]@dots{}] [@option{-U}@var{macro}]
+ [@option{-f}@var{option}@dots{}]
+ [@option{-m}@var{machine-option}@dots{}]
+ [@option{-o} @var{outfile}] @var{infile}@dots{}
+
+Only the most useful options are listed here; see below for the
+remainder.
+@c man end
+@c man begin SEEALSO
+gpl(7), gfdl(7), fsf-funding(7),
+cpp(1), gcov(1), gcc(1), as(1), ld(1), gdb(1), adb(1), dbx(1), sdb(1)
+and the Info entries for @file{gcc}, @file{cpp}, @file{gfortran}, @file{as},
+@file{ld}, @file{binutils} and @file{gdb}.
+@c man end
+@c man begin BUGS
+For instructions on reporting bugs, see
+@w{@uref{http://gcc.gnu.org/bugs.html}}.
+@c man end
+@c man begin AUTHOR
+See the Info entry for @command{gfortran} for contributors to GCC and
+GFORTRAN@.
+@c man end
+@end ignore
+
+@node Invoking GFORTRAN
+@chapter GNU Fortran 95 Command Options
+@cindex GNU Fortran 95 command options
+@cindex command options
+@cindex options, GNU Fortran 95 command
+
+@c man begin DESCRIPTION
+
+The @command{gfortran} command supports all the options supported by the
+@command{gcc} command. Only options specific to gfortran are documented here.
+
+@xref{Invoking GCC,,GCC Command Options,gcc,Using the GNU Compiler
+Collection (GCC)}, for information
+on the non-Fortran-specific aspects of the @command{gcc} command (and,
+therefore, the @command{gfortran} command).
+
+@cindex options, negative forms
+@cindex negative forms of options
+All @command{gcc} and @command{gfortran} options
+are accepted both by @command{gfortran} and by @command{gcc}
+(as well as any other drivers built at the same time,
+such as @command{g++}),
+since adding @command{gfortran} to the @command{gcc} distribution
+enables acceptance of @command{gfortran} options
+by all of the relevant drivers.
+
+In some cases, options have positive and negative forms;
+the negative form of @option{-ffoo} would be @option{-fno-foo}.
+This manual documents only one of these two forms, whichever
+one is not the default.
+@c man end
+
+@menu
+* Option Summary:: Brief list of all @command{gfortran} options,
+ without explanations.
+* Fortran Dialect Options:: Controlling the variant of Fortran language
+ compiled.
+* Warning Options:: How picky should the compiler be?
+* Debugging Options:: Symbol tables, measurements, and debugging dumps.
+* Directory Options:: Where to find module files
+* Code Gen Options:: Specifying conventions for function calls, data layout
+ and register usage.
+* Environment Variables:: Env vars that affect GNU Fortran.
+@end menu
+
+@node Option Summary
+@section Option Summary
+
+@c man begin OPTIONS
+
+Here is a summary of all the options specific to GNU Fortran, grouped
+by type. Explanations are in the following sections.
+
+@table @emph
+@item Fortran Language Options
+@xref{Fortran Dialect Options,,Options Controlling Fortran Dialect}.
+@gccoptlist{
+-ffree-form -fno-fixed-form @gol
+-fdollar-ok -fimplicit-none -fmax-identifier-length @gol
+-std=@var{std}
+-ffixed-line-length-@var{n} -ffixed-line-length-none @gol
+-i8 -r8 -d8}
+
+@item Warning Options
+@xref{Warning Options,,Options to Request or Suppress Warnings}.
+@gccoptlist{
+-fsyntax-only -pedantic -pedantic-errors @gol
+-w -Wall -Waliasing -Wconversion @gol
+-Wimplicit-interface -Wsurprising -Wunused-labels @gol
+-Wline-truncation @gol
+-Werror -W}
+
+@item Debugging Options
+@xref{Debugging Options,,Options for Debugging Your Program or GCC}.
+@gccoptlist{
+-fdump-parse-tree}
+
+@item Directory Options
+@xref{Directory Options,,Options for Directory Search}.
+@gccoptlist{
+-I@var{dir} -M@var{dir}}
+
+@item Code Generation Options
+@xref{Code Gen Options,,Options for Code Generation Conventions}.
+@gccoptlist{
+-fno-underscoring -fno-second-underscore @gol
+-fbounds-check -fmax-stack-var-size=@var{n} @gol
+-fpackderived -frepack-arrays}
+@end table
+
+@c man end
+
+@menu
+* Fortran Dialect Options:: Controlling the variant of Fortran language
+ compiled.
+* Warning Options:: How picky should the compiler be?
+* Debugging Options:: Symbol tables, measurements, and debugging dumps.
+* Directory Options:: Where to find module files
+* Code Gen Options:: Specifying conventions for function calls, data layout
+ and register usage.
+@end menu
+
+@node Fortran Dialect Options
+@section Options Controlling Fortran Dialect
+@cindex dialect options
+@cindex language, dialect options
+@cindex options, dialect
+
+The following options control the dialect of Fortran
+that the compiler accepts:
+
+@table @gcctabopt
+@cindex -ffree-form option
+@cindex options, -ffree-form
+@cindex -fno-fixed-form option
+@cindex options, -fno-fixed-form
+@cindex source file format
+@cindex free form
+@cindex fixed form
+@cindex Source Form
+@cindex Fortran 90, features
+@item -ffree-form
+@item -ffixed-form
+Specify the layout used by the the source file. The tree form layout
+was introduced in Fortran 90. Fixed form was traditionally used in
+older Fortran programs.
+
+@cindex -fdollar-ok option
+@cindex options, -fdollar-ok
+@item -fdollar-ok
+@cindex dollar sign
+@cindex symbol names
+@cindex character set
+Allow @samp{$} as a valid character in a symbol name.
+
+@cindex -ffixed-line-length-@var{n} option
+@cindex options, -ffixed-line-length-@var{n}
+@item -ffixed-line-length-@var{n}
+@cindex source file format
+@cindex lines, length
+@cindex length of source lines
+@cindex fixed form
+@cindex limits, lengths of source lines
+Set column after which characters are ignored in typical fixed-form
+lines in the source file, and through which spaces are assumed (as
+if padded to that length) after the ends of short fixed-form lines.
+
+@cindex card image
+@cindex extended-source option
+Popular values for @var{n} include 72 (the
+standard and the default), 80 (card image), and 132 (corresponds
+to ``extended-source'' options in some popular compilers).
+@var{n} may be @samp{none}, meaning that the entire line is meaningful
+and that continued character constants never have implicit spaces appended
+to them to fill out the line.
+@option{-ffixed-line-length-0} means the same thing as
+@option{-ffixed-line-length-none}.
+
+@cindex -fmax-identifier-length=@var{n} option
+@cindex option -fmax-identifier-length=@var{n}
+@item -fmax-identifier-length=@var{n}
+Specify the maximum allowed identifier length. Typical values are
+31 (Fortran 95) and 63 (Fortran 200x).
+
+@cindex -fimpicit-none option
+@cindex options, -fimplicit-none
+@item -fimplicit-none
+Specify that no implicit typing is allowed, unless overridden by explicit
+@samp{IMPLICIT} statements. This is the equivalent of adding
+@samp{implicit none} to the start of every procedure.
+
+@cindex -std=@var{std} option
+@cindex option, -std=@var{std}
+@item -std=@var{std}
+Conform to the specified standard. Allowed values for @var{std} are
+@samp{gnu}, @samp{f95} and @samp{f90}.
+
+@cindex option, -i8
+@cindex -i8, option
+@cindex option, -r8
+@cindex -r8, option
+@cindex option, -d8
+@cindex -d8, option
+@item -i8
+@item -r8
+@item -d8
+The @option{-i8} and @option{-j8} options set the default INTEGER and REAL
+kinds to KIND=8. The @option{-d8} option is equivalent to specifying
+both @option{-i8} and @option{-r8}.
+
+@end table
+
+@node Warning Options
+@section Options to Request or Suppress Warnings
+@cindex options, warnings
+@cindex warnings, suppressing
+@cindex messages, warning
+@cindex suppressing warnings
+
+Warnings are diagnostic messages that report constructions which
+are not inherently erroneous but which are risky or suggest there
+might have been an error.
+
+You can request many specific warnings with options beginning @option{-W},
+for example @option{-Wimplicit} to request warnings on implicit
+declarations. Each of these specific warning options also has a
+negative form beginning @option{-Wno-} to turn off warnings;
+for example, @option{-Wno-implicit}. This manual lists only one of the
+two forms, whichever is not the default.
+
+These options control the amount and kinds of warnings produced by GNU
+Fortran:
+
+@table @gcctabopt
+@cindex syntax checking
+@cindex -fsyntax-only option
+@cindex options, -fsyntax-only
+@item -fsyntax-only
+Check the code for syntax errors, but don't do anything beyond that.
+
+@cindex -pedantic option
+@cindex options, -pedantic
+@item -pedantic
+Issue warnings for uses of extensions to FORTRAN 95.
+@option{-pedantic} also applies to C-language constructs where they
+occur in GNU Fortran source files, such as use of @samp{\e} in a
+character constant within a directive like @samp{#include}.
+
+Valid FORTRAN 95 programs should compile properly with or without
+this option.
+However, without this option, certain GNU extensions and traditional
+Fortran features are supported as well.
+With this option, many of them are rejected.
+
+Some users try to use @option{-pedantic} to check programs for conformance.
+They soon find that it does not do quite what they want---it finds some
+nonstandard practices, but not all.
+However, improvements to @command{gfortran} in this area are welcome.
+
+This should be used in conjunction with -std=@var{std}.
+
+@cindex -pedantic-errors option
+@cindex options, -pedantic-errors
+@item -pedantic-errors
+Like @option{-pedantic}, except that errors are produced rather than
+warnings.
+
+@cindex -w option
+@cindex options, -w
+@item -w
+Inhibit all warning messages.
+
+
+@cindex -Wall option
+@cindex options, -Wall
+@item -Wall
+@cindex all warnings
+@cindex warnings, all
+Enables commonly used warning options that which pertain to usage that
+we recommend avoiding and that we believe is easy to avoid.
+This currenly includes @option{-Wunused-labels}, @option{-Waliasing},
+@option{-Wsurprising} and @option{-Wline-truncation}.
+
+
+@cindex -Waliasing option
+@cindex options, -Waliasing
+@item -Waliasing
+@cindex aliasing
+Warn about possible aliasing of dummy arguments. The following example
+witll trigger teh warhing as it would be illegal to @code{bar} to
+modify either parameter.
+@smallexample
+ INTEGER A
+ CALL BAR(A,A)
+@end smallexample
+
+
+@cindex -Wconversion option
+@cindex options, -Wconversion
+@item -Wconversion
+@cindex conversion
+Warn about implicit conversions between different types.
+
+
+@cindex -Wimplicit-interface option
+@cindex options, -Wimplicit-interface
+@item -Wimplicit-interface
+Warn about when procedure are called without an explicit interface.
+Note this only checks that an explicit interface is present. It does not
+check that the declared interfaces are consistent across program units.
+
+
+@cindex -Wsurprising
+@cindex options, -Wsurprising
+@item -Wsurprising
+@cindex Suspicious
+Produce a warning when ``suspicous'' code constructs are encountered.
+While techically legal these usually indicate that an error has been made.
+
+This currently produces a warning under the following circumstances:
+
+@itemize @bullet
+@item
+An INTEGER SELECT construct has a CASE the can never be matched as it's
+lower value that is greater than its upper value.
+
+@item
+A LOGICAL SELECT construct has three CASE statements.
+@end itemize
+
+@cindex -Wunused-labels option
+@cindex options, -Wunused-labels
+@item -Wunused-labels
+@cindex unused labels
+@cindex labels, unused
+Warn whenever a label is defined but never referenced.
+
+
+@cindex -Werror
+@cindex options, -Werror
+@item -Werror
+Turns all warnings into errors.
+
+
+@cindex -W option
+@cindex options, -W
+@item -W
+@cindex extra warnings
+@cindex warnings, extra
+Turns on ``extra warnings'' and, if optimization is specified
+via @option{-O}, the @option{-Wuninitialized} option.
+(This might change in future versions of @command{gfortran}
+@end table
+
+@xref{Warning Options,,Options to Request or Suppress Warnings,
+gcc,Using the GNU Compiler Collection (GCC)}, for information on more
+options offered by the GBE shared by @command{gfortran}, @command{gcc} and
+other GNU compilers.
+
+Some of these have no effect when compiling programs written in Fortran.
+
+@node Debugging Options
+@section Options for Debugging Your Program or GNU Fortran
+@cindex options, debugging
+@cindex debugging information options
+
+GNU Fortran has various special options that are used for debugging
+either your program or @command{gfortran}
+
+@table @gcctabopt
+@cindex -fdump-parse-tree option
+@cindex option, -fdump-parse-tree
+@item -fdump-parse-tree
+Output the internal parse tree before starting code generation. Only
+really usedful for debugging gfortran itself.
+@end table
+
+@xref{Debugging Options,,Options for Debugging Your Program or GCC,
+gcc,Using the GNU Compiler Collection (GCC)}, for more information on
+debugging options.
+
+@node Directory Options
+@section Options for Directory Search
+@cindex directory, options
+@cindex options, directory search
+@cindex search path
+
+@cindex INCLUDE directive
+@cindex directive, INCLUDE
+There options affect how affect how @command{gfortran} searches
+for files specified via the @code{INCLUDE} directive, and where it searches
+for previously compiled modules.
+
+It also affects the search paths used by @command{cpp} when used to preprocess
+fortran source.
+
+@table @gcctabopt
+@cindex -Idir option
+@cindex options, -Idir
+@item -I@var{dir}
+@cindex directory, search paths for inclusion
+@cindex inclusion, directory search paths for
+@cindex search paths, for included files
+@cindex paths, search
+@cindex module search path
+These affect interpretation of the @code{INCLUDE} directive
+(as well as of the @code{#include} directive of the @command{cpp}
+preprocessor).
+
+Also note that the general behavior of @option{-I} and
+@code{INCLUDE} is pretty much the same as of @option{-I} with
+@code{#include} in the @command{cpp} preprocessor, with regard to
+looking for @file{header.gcc} files and other such things.
+
+This path is also used to search for @samp{.mod} files when previously
+compiled modules are required by a @code{USE} statement.
+
+@xref{Directory Options,,Options for Directory Search,
+gcc,Using the GNU Compiler Collection (GCC)}, for information on the
+@option{-I} option.
+
+@cindex -Mdir option
+@cindex option, -Mdir
+@item -M@var{dir}
+@item -J@var{dir}
+This option specifies where to put @samp{.mod} files for compiled modiles.
+It is also added to the list of directories to searhed by an @code{USE}
+statement.
+
+The default is the current directory.
+
+@option{-J} is an alias for @option{-M} to avoid conflicts with existing
+GCC options.
+@end table
+
+@node Code Gen Options
+@section Options for Code Generation Conventions
+@cindex code generation, conventions
+@cindex options, code generation
+@cindex run-time, options
+
+These machine-independent options control the interface conventions
+used in code generation.
+
+Most of them have both positive and negative forms; the negative form
+of @option{-ffoo} would be @option{-fno-foo}. In the table below, only
+one of the forms is listed---the one which is not the default. You
+can figure out the other form by either removing @option{no-} or adding
+it.
+
+
+@table @gcctabopt
+@cindex -fno-underscoring option
+@cindex options, -fno-underscoring
+@item -fno-underscoring
+@cindex underscore
+@cindex symbol names, underscores
+@cindex transforming symbol names
+@cindex symbol names, transforming
+Do not transform names of entities specified in the Fortran
+source file by appending underscores to them.
+
+With @option{-funderscoring} in effect, @command{gfortran} appends two
+underscores to names with underscores and one underscore to external names
+with no underscores. (@command{gfortran} also appends two underscores to
+internal names with underscores to avoid naming collisions with external
+names. The @option{-fno-second-underscore} option disables appending of the
+second underscore in all cases.)
+
+This is done to ensure compatibility with code produced by many
+UNIX Fortran compilers, including @command{f2c} which perform the
+same transformations.
+
+Use of @option{-fno-underscoring} is not recommended unless you are
+experimenting with issues such as integration of (GNU) Fortran into
+existing system environments (vis-a-vis existing libraries, tools, and
+so on).
+
+For example, with @option{-funderscoring}, and assuming other defaults like
+@option{-fcase-lower} and that @samp{j()} and @samp{max_count()} are
+external functions while @samp{my_var} and @samp{lvar} are local variables,
+a statement like
+
+@smallexample
+I = J() + MAX_COUNT (MY_VAR, LVAR)
+@end smallexample
+
+@noindent
+is implemented as something akin to:
+
+@smallexample
+i = j_() + max_count__(&my_var__, &lvar);
+@end smallexample
+
+With @option{-fno-underscoring}, the same statement is implemented as:
+
+@smallexample
+i = j() + max_count(&my_var, &lvar);
+@end smallexample
+
+Use of @option{-fno-underscoring} allows direct specification of
+user-defined names while debugging and when interfacing @command{gfortran}
+code with other languages.
+
+Note that just because the names match does @emph{not} mean that the
+interface implemented by @command{gfortran} for an external name matches the
+interface implemented by some other language for that same name.
+That is, getting code produced by @command{gfortran} to link to code produced
+by some other compiler using this or any other method can be only a
+small part of the overall solution---getting the code generated by
+both compilers to agree on issues other than naming can require
+significant effort, and, unlike naming disagreements, linkers normally
+cannot detect disagreements in these other areas.
+
+Also, note that with @option{-fno-underscoring}, the lack of appended
+underscores introduces the very real possibility that a user-defined
+external name will conflict with a name in a system library, which
+could make finding unresolved-reference bugs quite difficult in some
+cases---they might occur at program run time, and show up only as
+buggy behavior at run time.
+
+In future versions of @command{gfortran} we hope to improve naming and linking
+issues so that debugging always involves using the names as they appear
+in the source, even if the names as seen by the linker are mangled to
+prevent accidental linking between procedures with incompatible
+interfaces.
+
+@cindex -fno-second-underscore option
+@cindex options, -fno-second-underscore
+@item -fno-second-underscore
+@cindex underscore
+@cindex symbol names, underscores
+@cindex transforming symbol names
+@cindex symbol names, transforming
+Do not append a second underscore to names of entities specified
+in the Fortran source file.
+
+This option has no effect if @option{-fno-underscoring} is
+in effect.
+
+Otherwise, with this option, an external name such as @samp{MAX_COUNT}
+is implemented as a reference to the link-time external symbol
+@samp{max_count_}, instead of @samp{max_count__}.
+
+
+@cindex -fbounds-check option
+@cindex -ffortran-bounds-check option
+@item -fbounds-check
+@cindex bounds checking
+@cindex range checking
+@cindex array bounds checking
+@cindex subscript checking
+@cindex checking subscripts
+Enable generation of run-time checks for array subscripts
+and against the declared minimum and maximum values. It also
+checks array indices for assumed and deferred
+shape arrays against the actual allocated bounds.
+
+In the future this may also include other forms of checking, eg. checing
+substring references.
+
+
+@cindex -fmax-stack-var-size option
+@item -fmax-stack-var-size=@var{n}
+This option specifies the size in bytes of the largest array that will be put
+on the stack.
+
+This option currently only affects local arrays declared with constant
+bounds, and may not apply to all character variables.
+Future versions of @command{gfortran} may improve this behavior.
+
+The default value for @var{n} is 32768.
+
+@cindex -fpackderived
+@item -fpackderived
+@cindex Structure packing
+This option tells gfortran to pack derived type members as closely as
+possible. Code compiled with this option is likley to be incompatible
+with code compiled without this option, and may execute slower.
+
+@cindex -frepack-arrays option
+@item -frepack-arrays
+@cindex Repacking arrays
+In some circumstances @command{gfortran} may pass assumed shape array
+sections via a descriptor describing a discontiguous area of memory.
+This option adds code to the function prologue to repack the data into
+a contiguous block at runtime.
+
+This should result in faster accesses to the array. However it can introduce
+significant overhead to the function call, especially when the passed data
+is discontiguous.
+@end table
+
+@xref{Code Gen Options,,Options for Code Generation Conventions,
+gcc,Using the GNU Compiler Collection (GCC)}, for information on more options
+offered by the GBE
+shared by @command{gfortran} @command{gcc} and other GNU compilers.
+
+
+@c man end
+
+@node Environment Variables
+@section Environment Variables Affecting GNU Fortran
+@cindex environment variables
+
+@c man begin ENVIRONMENT
+
+GNU Fortran 95 currently does not make use of any environment
+variables to control its operation above and beyond those
+that affect the operation of @command{gcc}.
+
+@xref{Environment Variables,,Environment Variables Affecting GCC,
+gcc,Using the GNU Compiler Collection (GCC)}, for information on environment
+variables.
+
+@c man end
diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c
new file mode 100644
index 00000000000..e2fd33dc772
--- /dev/null
+++ b/gcc/fortran/io.c
@@ -0,0 +1,2409 @@
+/* Deal with I/O statements & related stuff.
+ Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "flags.h"
+
+#include <string.h>
+
+#include "gfortran.h"
+#include "match.h"
+#include "parse.h"
+
+gfc_st_label format_asterisk =
+ { -1, ST_LABEL_FORMAT, ST_LABEL_FORMAT, NULL, 0,
+ {NULL, 0, NULL, NULL}, NULL, NULL};
+
+typedef struct
+{
+ const char *name, *spec;
+ bt type;
+}
+io_tag;
+
+static const io_tag
+ tag_file = { "FILE", " file = %e", BT_CHARACTER },
+ tag_status = { "STATUS", " status = %e", BT_CHARACTER},
+ tag_e_access = {"ACCESS", " access = %e", BT_CHARACTER},
+ tag_e_form = {"FORM", " form = %e", BT_CHARACTER},
+ tag_e_recl = {"RECL", " recl = %e", BT_INTEGER},
+ tag_e_blank = {"BLANK", " blank = %e", BT_CHARACTER},
+ tag_e_position = {"POSITION", " position = %e", BT_CHARACTER},
+ tag_e_action = {"ACTION", " action = %e", BT_CHARACTER},
+ tag_e_delim = {"DELIM", " delim = %e", BT_CHARACTER},
+ tag_e_pad = {"PAD", " pad = %e", BT_CHARACTER},
+ tag_unit = {"UNIT", " unit = %e", BT_INTEGER},
+ tag_advance = {"ADVANCE", " advance = %e", BT_CHARACTER},
+ tag_rec = {"REC", " rec = %e", BT_INTEGER},
+ tag_format = {"FORMAT", NULL, BT_CHARACTER},
+ tag_iostat = {"IOSTAT", " iostat = %v", BT_INTEGER},
+ tag_size = {"SIZE", " size = %v", BT_INTEGER},
+ tag_exist = {"EXIST", " exist = %v", BT_LOGICAL},
+ tag_opened = {"OPENED", " opened = %v", BT_LOGICAL},
+ tag_named = {"NAMED", " named = %v", BT_LOGICAL},
+ tag_name = {"NAME", " name = %v", BT_CHARACTER},
+ tag_number = {"NUMBER", " number = %v", BT_INTEGER},
+ tag_s_access = {"ACCESS", " access = %v", BT_CHARACTER},
+ tag_sequential = {"SEQUENTIAL", " sequential = %v", BT_CHARACTER},
+ tag_direct = {"DIRECT", " direct = %v", BT_CHARACTER},
+ tag_s_form = {"FORM", " form = %v", BT_CHARACTER},
+ tag_formatted = {"FORMATTED", " formatted = %v", BT_CHARACTER},
+ tag_unformatted = {"UNFORMATTED", " unformatted = %v", BT_CHARACTER},
+ tag_s_recl = {"RECL", " recl = %v", BT_INTEGER},
+ tag_nextrec = {"NEXTREC", " nextrec = %v", BT_INTEGER},
+ tag_s_blank = {"BLANK", " blank = %v", BT_CHARACTER},
+ tag_s_position = {"POSITION", " position = %v", BT_CHARACTER},
+ tag_s_action = {"ACTION", " action = %v", BT_CHARACTER},
+ tag_read = {"READ", " read = %v", BT_CHARACTER},
+ tag_write = {"WRITE", " write = %v", BT_CHARACTER},
+ tag_readwrite = {"READWRITE", " readwrite = %v", BT_CHARACTER},
+ tag_s_delim = {"DELIM", " delim = %v", BT_CHARACTER},
+ tag_s_pad = {"PAD", " pad = %v", BT_CHARACTER},
+ tag_iolength = {"IOLENGTH", " iolength = %v", BT_INTEGER},
+ tag_err = {"ERR", " err = %l", BT_UNKNOWN},
+ tag_end = {"END", " end = %l", BT_UNKNOWN},
+ tag_eor = {"EOR", " eor = %l", BT_UNKNOWN};
+
+static gfc_dt *current_dt;
+
+#define RESOLVE_TAG(x, y) if (resolve_tag(x, y) == FAILURE) return FAILURE;
+
+
+/**************** Fortran 95 FORMAT parser *****************/
+
+/* FORMAT tokens returned by format_lex(). */
+typedef enum
+{
+ FMT_NONE, FMT_UNKNOWN, FMT_SIGNED_INT, FMT_ZERO, FMT_POSINT, FMT_PERIOD,
+ FMT_COMMA, FMT_COLON, FMT_SLASH, FMT_DOLLAR, FMT_POS, FMT_LPAREN,
+ FMT_RPAREN, FMT_X, FMT_SIGN, FMT_BLANK, FMT_CHAR, FMT_P, FMT_IBOZ, FMT_F,
+ FMT_E, FMT_EXT, FMT_G, FMT_L, FMT_A, FMT_D, FMT_H, FMT_END
+}
+format_token;
+
+/* Local variables for checking format strings. The saved_token is
+ used to back up by a single format token during the parsing
+ process. */
+static char *format_string;
+static int format_length, use_last_char;
+
+static format_token saved_token;
+
+static enum
+{ MODE_STRING, MODE_FORMAT, MODE_COPY }
+mode;
+
+
+/* Return the next character in the format string. */
+
+static char
+next_char (int in_string)
+{
+ static char c;
+
+ if (use_last_char)
+ {
+ use_last_char = 0;
+ return c;
+ }
+
+ format_length++;
+
+ if (mode == MODE_STRING)
+ c = *format_string++;
+ else
+ {
+ c = gfc_next_char_literal (in_string);
+ if (c == '\n')
+ c = '\0';
+
+ if (mode == MODE_COPY)
+ *format_string++ = c;
+ }
+
+ c = TOUPPER (c);
+ return c;
+}
+
+
+/* Back up one character position. Only works once. */
+
+static void
+unget_char (void)
+{
+
+ use_last_char = 1;
+}
+
+static int value = 0;
+
+/* Simple lexical analyzer for getting the next token in a FORMAT
+ statement. */
+
+static format_token
+format_lex (void)
+{
+ format_token token;
+ char c, delim;
+ int zflag;
+ int negative_flag;
+
+ if (saved_token != FMT_NONE)
+ {
+ token = saved_token;
+ saved_token = FMT_NONE;
+ return token;
+ }
+
+ do
+ {
+ c = next_char (0);
+ }
+ while (gfc_is_whitespace (c));
+
+ negative_flag = 0;
+ switch (c)
+ {
+ case '-':
+ negative_flag = 1;
+ case '+':
+ c = next_char (0);
+ if (!ISDIGIT (c))
+ {
+ token = FMT_UNKNOWN;
+ break;
+ }
+
+ value = c - '0';
+
+ do
+ {
+ c = next_char (0);
+ if(ISDIGIT (c))
+ value = 10 * value + c - '0';
+ }
+ while (ISDIGIT (c));
+
+ unget_char ();
+
+ if (negative_flag)
+ value = -value;
+
+ token = FMT_SIGNED_INT;
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ zflag = (c == '0');
+
+ value = c - '0';
+
+ do
+ {
+ c = next_char (0);
+ if (c != '0')
+ zflag = 0;
+ if (ISDIGIT (c))
+ value = 10 * value + c - '0';
+ }
+ while (ISDIGIT (c));
+
+ unget_char ();
+ token = zflag ? FMT_ZERO : FMT_POSINT;
+ break;
+
+ case '.':
+ token = FMT_PERIOD;
+ break;
+
+ case ',':
+ token = FMT_COMMA;
+ break;
+
+ case ':':
+ token = FMT_COLON;
+ break;
+
+ case '/':
+ token = FMT_SLASH;
+ break;
+
+ case '$':
+ token = FMT_DOLLAR;
+ break;
+
+ case 'T':
+ c = next_char (0);
+ if (c != 'L' && c != 'R')
+ unget_char ();
+
+ token = FMT_POS;
+ break;
+
+ case '(':
+ token = FMT_LPAREN;
+ break;
+
+ case ')':
+ token = FMT_RPAREN;
+ break;
+
+ case 'X':
+ token = FMT_X;
+ break;
+
+ case 'S':
+ c = next_char (0);
+ if (c != 'P' && c != 'S')
+ unget_char ();
+
+ token = FMT_SIGN;
+ break;
+
+ case 'B':
+ c = next_char (0);
+ if (c == 'N' || c == 'Z')
+ token = FMT_BLANK;
+ else
+ {
+ unget_char ();
+ token = FMT_IBOZ;
+ }
+
+ break;
+
+ case '\'':
+ case '"':
+ delim = c;
+
+ value = 0;
+
+ for (;;)
+ {
+ c = next_char (1);
+ if (c == '\0')
+ {
+ token = FMT_END;
+ break;
+ }
+
+ if (c == delim)
+ {
+ c = next_char (1);
+
+ if (c == '\0')
+ {
+ token = FMT_END;
+ break;
+ }
+
+ if (c != delim)
+ {
+ unget_char ();
+ token = FMT_CHAR;
+ break;
+ }
+ }
+ value++;
+ }
+ break;
+
+ case 'P':
+ token = FMT_P;
+ break;
+
+ case 'I':
+ case 'O':
+ case 'Z':
+ token = FMT_IBOZ;
+ break;
+
+ case 'F':
+ token = FMT_F;
+ break;
+
+ case 'E':
+ c = next_char (0);
+ if (c == 'N' || c == 'S')
+ token = FMT_EXT;
+ else
+ {
+ token = FMT_E;
+ unget_char ();
+ }
+
+ break;
+
+ case 'G':
+ token = FMT_G;
+ break;
+
+ case 'H':
+ token = FMT_H;
+ break;
+
+ case 'L':
+ token = FMT_L;
+ break;
+
+ case 'A':
+ token = FMT_A;
+ break;
+
+ case 'D':
+ token = FMT_D;
+ break;
+
+ case '\0':
+ token = FMT_END;
+ break;
+
+ default:
+ token = FMT_UNKNOWN;
+ break;
+ }
+
+ return token;
+}
+
+
+/* Check a format statement. The format string, either from a FORMAT
+ statement or a constant in an I/O statement has already been parsed
+ by itself, and we are checking it for validity. The dual origin
+ means that the warning message is a little less than great. */
+
+static try
+check_format (void)
+{
+ const char *posint_required = "Positive width required";
+ const char *period_required = "Period required";
+ const char *nonneg_required = "Nonnegative width required";
+ const char *unexpected_element = "Unexpected element";
+ const char *unexpected_end = "Unexpected end of format string";
+
+ const char *error;
+ format_token t, u;
+ int level;
+ int repeat;
+ try rv;
+
+ use_last_char = 0;
+ saved_token = FMT_NONE;
+ level = 0;
+ repeat = 0;
+ rv = SUCCESS;
+
+ t = format_lex ();
+ if (t != FMT_LPAREN)
+ {
+ error = "Missing leading left parenthesis";
+ goto syntax;
+ }
+
+ t = format_lex ();
+ if (t == FMT_RPAREN)
+ goto finished; /* Empty format is legal */
+ saved_token = t;
+
+format_item:
+ /* In this state, the next thing has to be a format item. */
+ t = format_lex ();
+ switch (t)
+ {
+ case FMT_POSINT:
+ repeat = value;
+ t = format_lex ();
+ if (t == FMT_LPAREN)
+ {
+ level++;
+ goto format_item;
+ }
+
+ if (t == FMT_SLASH)
+ goto optional_comma;
+
+ goto data_desc;
+
+ case FMT_LPAREN:
+ level++;
+ goto format_item;
+
+ case FMT_SIGNED_INT:
+ /* Signed integer can only precede a P format. */
+ t = format_lex ();
+ if (t != FMT_P)
+ {
+ error = "Expected P edit descriptor";
+ goto syntax;
+ }
+
+ goto data_desc;
+
+ case FMT_P:
+ /* P and X require a prior number. */
+ error = "P descriptor requires leading scale factor";
+ goto syntax;
+
+ case FMT_X:
+ error = "X descriptor requires leading space count";
+ goto syntax;
+
+ case FMT_SIGN:
+ case FMT_BLANK:
+ case FMT_CHAR:
+ goto between_desc;
+
+ case FMT_COLON:
+ case FMT_SLASH:
+ goto optional_comma;
+
+ case FMT_DOLLAR:
+ t = format_lex ();
+ if (t != FMT_RPAREN || level > 0)
+ {
+ error = "$ must the last specifier";
+ goto syntax;
+ }
+
+ goto finished;
+
+ case FMT_POS:
+ case FMT_IBOZ:
+ case FMT_F:
+ case FMT_E:
+ case FMT_EXT:
+ case FMT_G:
+ case FMT_L:
+ case FMT_A:
+ case FMT_D:
+ goto data_desc;
+
+ case FMT_H:
+ goto data_desc;
+
+ case FMT_END:
+ error = unexpected_end;
+ goto syntax;
+
+ default:
+ error = unexpected_element;
+ goto syntax;
+ }
+
+data_desc:
+ /* In this state, t must currently be a data descriptor.
+ Deal with things that can/must follow the descriptor. */
+ switch (t)
+ {
+ case FMT_SIGN:
+ case FMT_BLANK:
+ case FMT_X:
+ break;
+
+ case FMT_P:
+ if (pedantic)
+ {
+ t = format_lex ();
+ if (t == FMT_POSINT)
+ {
+ error = "Repeat count cannot follow P descriptor";
+ goto syntax;
+ }
+
+ saved_token = t;
+ }
+
+ goto optional_comma;
+
+ case FMT_POS:
+ case FMT_L:
+ t = format_lex ();
+ if (t == FMT_POSINT)
+ break;
+
+ error = posint_required;
+ goto syntax;
+
+ case FMT_A:
+ t = format_lex ();
+ if (t != FMT_POSINT)
+ saved_token = t;
+ break;
+
+ case FMT_D:
+ case FMT_E:
+ case FMT_G:
+ case FMT_EXT:
+ u = format_lex ();
+ if (u != FMT_POSINT)
+ {
+ error = posint_required;
+ goto syntax;
+ }
+
+ u = format_lex ();
+ if (u != FMT_PERIOD)
+ {
+ error = period_required;
+ goto syntax;
+ }
+
+ u = format_lex ();
+ if (u != FMT_ZERO && u != FMT_POSINT)
+ {
+ error = nonneg_required;
+ goto syntax;
+ }
+
+ if (t == FMT_D)
+ break;
+
+ /* Look for optional exponent. */
+ u = format_lex ();
+ if (u != FMT_E)
+ {
+ saved_token = u;
+ }
+ else
+ {
+ u = format_lex ();
+ if (u != FMT_POSINT)
+ {
+ error = "Positive exponent width required";
+ goto syntax;
+ }
+ }
+
+ break;
+
+ case FMT_F:
+ t = format_lex ();
+ if (t != FMT_ZERO && t != FMT_POSINT)
+ {
+ error = nonneg_required;
+ goto syntax;
+ }
+
+ t = format_lex ();
+ if (t != FMT_PERIOD)
+ {
+ error = period_required;
+ goto syntax;
+ }
+
+ t = format_lex ();
+ if (t != FMT_ZERO && t != FMT_POSINT)
+ {
+ error = nonneg_required;
+ goto syntax;
+ }
+
+ break;
+
+ case FMT_H:
+ if(mode == MODE_STRING)
+ {
+ format_string += value;
+ format_length -= value;
+ }
+ else
+ {
+ while(repeat >0)
+ {
+ next_char(0);
+ repeat -- ;
+ }
+ }
+ break;
+
+ case FMT_IBOZ:
+ t = format_lex ();
+ if (t != FMT_ZERO && t != FMT_POSINT)
+ {
+ error = nonneg_required;
+ goto syntax;
+ }
+
+ t = format_lex ();
+ if (t != FMT_PERIOD)
+ {
+ saved_token = t;
+ }
+ else
+ {
+ t = format_lex ();
+ if (t != FMT_ZERO && t != FMT_POSINT)
+ {
+ error = nonneg_required;
+ goto syntax;
+ }
+ }
+
+ break;
+
+ default:
+ error = unexpected_element;
+ goto syntax;
+ }
+
+between_desc:
+ /* Between a descriptor and what comes next. */
+ t = format_lex ();
+ switch (t)
+ {
+
+ case FMT_COMMA:
+ goto format_item;
+
+ case FMT_RPAREN:
+ level--;
+ if (level < 0)
+ goto finished;
+ goto between_desc;
+
+ case FMT_COLON:
+ case FMT_SLASH:
+ goto optional_comma;
+
+ case FMT_END:
+ error = unexpected_end;
+ goto syntax;
+
+ default:
+ error = "Missing comma";
+ goto syntax;
+ }
+
+optional_comma:
+ /* Optional comma is a weird between state where we've just finished
+ reading a colon, slash or P descriptor. */
+ t = format_lex ();
+ switch (t)
+ {
+ case FMT_COMMA:
+ break;
+
+ case FMT_RPAREN:
+ level--;
+ if (level < 0)
+ goto finished;
+ goto between_desc;
+
+ default:
+ /* Assume that we have another format item. */
+ saved_token = t;
+ break;
+ }
+
+ goto format_item;
+
+syntax:
+ /* Something went wrong. If the format we're checking is a string,
+ generate a warning, since the program is correct. If the format
+ is in a FORMAT statement, this messes up parsing, which is an
+ error. */
+ if (mode != MODE_STRING)
+ gfc_error ("%s in format string at %C", error);
+ else
+ {
+ gfc_warning ("%s in format string at %C", error);
+
+ /* TODO: More elaborate measures are needed to show where a problem
+ is within a format string that has been calculated. */
+ }
+
+ rv = FAILURE;
+
+finished:
+ return rv;
+}
+
+
+/* Given an expression node that is a constant string, see if it looks
+ like a format string. */
+
+static void
+check_format_string (gfc_expr * e)
+{
+
+ mode = MODE_STRING;
+ format_string = e->value.character.string;
+ check_format ();
+}
+
+
+/************ Fortran 95 I/O statement matchers *************/
+
+/* Match a FORMAT statement. This amounts to actually parsing the
+ format descriptors in order to correctly locate the end of the
+ format string. */
+
+match
+gfc_match_format (void)
+{
+ gfc_expr *e;
+ locus start;
+
+ if (gfc_statement_label == NULL)
+ {
+ gfc_error ("Missing format label at %C");
+ return MATCH_ERROR;
+ }
+ gfc_gobble_whitespace ();
+
+ mode = MODE_FORMAT;
+ format_length = 0;
+
+ start = *gfc_current_locus ();
+
+ if (check_format () == FAILURE)
+ return MATCH_ERROR;
+
+ if (gfc_match_eos () != MATCH_YES)
+ {
+ gfc_syntax_error (ST_FORMAT);
+ return MATCH_ERROR;
+ }
+
+ /* The label doesn't get created until after the statement is done
+ being matched, so we have to leave the string for later. */
+
+ gfc_set_locus (&start); /* Back to the beginning */
+
+ new_st.loc = start;
+ new_st.op = EXEC_NOP;
+
+ e = gfc_get_expr();
+ e->expr_type = EXPR_CONSTANT;
+ e->ts.type = BT_CHARACTER;
+ e->ts.kind = gfc_default_character_kind();
+ e->where = start;
+ e->value.character.string = format_string = gfc_getmem(format_length+1);
+ e->value.character.length = format_length;
+ gfc_statement_label->format = e;
+
+ mode = MODE_COPY;
+ check_format (); /* Guaranteed to succeed */
+ gfc_match_eos (); /* Guaranteed to succeed */
+
+ return MATCH_YES;
+}
+
+
+/* Match an expression I/O tag of some sort. */
+
+static match
+match_etag (const io_tag * tag, gfc_expr ** v)
+{
+ gfc_expr *result;
+ match m;
+
+ m = gfc_match (tag->spec, &result);
+ if (m != MATCH_YES)
+ return m;
+
+ if (*v != NULL)
+ {
+ gfc_error ("Duplicate %s specification at %C", tag->name);
+ gfc_free_expr (result);
+ return MATCH_ERROR;
+ }
+
+ *v = result;
+ return MATCH_YES;
+}
+
+
+/* Match a variable I/O tag of some sort. */
+
+static match
+match_vtag (const io_tag * tag, gfc_expr ** v)
+{
+ gfc_expr *result;
+ match m;
+
+ m = gfc_match (tag->spec, &result);
+ if (m != MATCH_YES)
+ return m;
+
+ if (*v != NULL)
+ {
+ gfc_error ("Duplicate %s specification at %C", tag->name);
+ gfc_free_expr (result);
+ return MATCH_ERROR;
+ }
+
+ if (result->symtree->n.sym->attr.intent == INTENT_IN)
+ {
+ gfc_error ("Variable tag cannot be INTENT(IN) at %C");
+ gfc_free_expr (result);
+ return MATCH_ERROR;
+ }
+
+ if (gfc_pure (NULL) && gfc_impure_variable (result->symtree->n.sym))
+ {
+ gfc_error ("Variable tag cannot be assigned in PURE procedure at %C");
+ gfc_free_expr (result);
+ return MATCH_ERROR;
+ }
+
+ *v = result;
+ return MATCH_YES;
+}
+
+
+/* Match a label I/O tag. */
+
+static match
+match_ltag (const io_tag * tag, gfc_st_label ** label)
+{
+ match m;
+ gfc_st_label *old;
+
+ old = *label;
+ m = gfc_match (tag->spec, label);
+ if (m == MATCH_YES && old != 0)
+ {
+ gfc_error ("Duplicate %s label specification at %C", tag->name);
+ return MATCH_ERROR;
+ }
+
+ return m;
+}
+
+
+/* Do expression resolution and type-checking on an expression tag. */
+
+static try
+resolve_tag (const io_tag * tag, gfc_expr * e)
+{
+
+ if (e == NULL)
+ return SUCCESS;
+
+ if (gfc_resolve_expr (e) == FAILURE)
+ return FAILURE;
+
+ if (e->ts.type != tag->type)
+ {
+ /* Format label can be integer varibale. */
+ if (tag != &tag_format)
+ {
+ gfc_error ("%s tag at %L must be of type %s", tag->name, &e->where,
+ gfc_basic_typename (tag->type));
+ return FAILURE;
+ }
+ }
+
+ if (tag == &tag_format)
+ {
+ if (e->rank != 1 && e->rank != 0)
+ {
+ gfc_error ("FORMAT tag at %L cannot be array of strings",
+ &e->where);
+ return FAILURE;
+ }
+ }
+ else
+ {
+ if (e->rank != 0)
+ {
+ gfc_error ("%s tag at %L must be scalar", tag->name, &e->where);
+ return FAILURE;
+ }
+ }
+
+ return SUCCESS;
+}
+
+
+/* Match a single tag of an OPEN statement. */
+
+static match
+match_open_element (gfc_open * open)
+{
+ match m;
+
+ m = match_etag (&tag_unit, &open->unit);
+ if (m != MATCH_NO)
+ return m;
+ m = match_vtag (&tag_iostat, &open->iostat);
+ if (m != MATCH_NO)
+ return m;
+ m = match_etag (&tag_file, &open->file);
+ if (m != MATCH_NO)
+ return m;
+ m = match_etag (&tag_status, &open->status);
+ if (m != MATCH_NO)
+ return m;
+ m = match_etag (&tag_e_access, &open->access);
+ if (m != MATCH_NO)
+ return m;
+ m = match_etag (&tag_e_form, &open->form);
+ if (m != MATCH_NO)
+ return m;
+ m = match_etag (&tag_e_recl, &open->recl);
+ if (m != MATCH_NO)
+ return m;
+ m = match_etag (&tag_e_blank, &open->blank);
+ if (m != MATCH_NO)
+ return m;
+ m = match_etag (&tag_e_position, &open->position);
+ if (m != MATCH_NO)
+ return m;
+ m = match_etag (&tag_e_action, &open->action);
+ if (m != MATCH_NO)
+ return m;
+ m = match_etag (&tag_e_delim, &open->delim);
+ if (m != MATCH_NO)
+ return m;
+ m = match_etag (&tag_e_pad, &open->pad);
+ if (m != MATCH_NO)
+ return m;
+ m = match_ltag (&tag_err, &open->err);
+ if (m != MATCH_NO)
+ return m;
+
+ return MATCH_NO;
+}
+
+
+/* Free the gfc_open structure and all the expressions it contains. */
+
+void
+gfc_free_open (gfc_open * open)
+{
+
+ if (open == NULL)
+ return;
+
+ gfc_free_expr (open->unit);
+ gfc_free_expr (open->iostat);
+ gfc_free_expr (open->file);
+ gfc_free_expr (open->status);
+ gfc_free_expr (open->access);
+ gfc_free_expr (open->form);
+ gfc_free_expr (open->recl);
+ gfc_free_expr (open->blank);
+ gfc_free_expr (open->position);
+ gfc_free_expr (open->action);
+ gfc_free_expr (open->delim);
+ gfc_free_expr (open->pad);
+
+ gfc_free (open);
+}
+
+
+/* Resolve everything in a gfc_open structure. */
+
+try
+gfc_resolve_open (gfc_open * open)
+{
+
+ RESOLVE_TAG (&tag_unit, open->unit);
+ RESOLVE_TAG (&tag_iostat, open->iostat);
+ RESOLVE_TAG (&tag_file, open->file);
+ RESOLVE_TAG (&tag_status, open->status);
+ RESOLVE_TAG (&tag_e_form, open->form);
+ RESOLVE_TAG (&tag_e_recl, open->recl);
+
+ RESOLVE_TAG (&tag_e_blank, open->blank);
+ RESOLVE_TAG (&tag_e_position, open->position);
+ RESOLVE_TAG (&tag_e_action, open->action);
+ RESOLVE_TAG (&tag_e_delim, open->delim);
+ RESOLVE_TAG (&tag_e_pad, open->pad);
+
+ if (gfc_reference_st_label (open->err, ST_LABEL_TARGET) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+/* Match an OPEN statmement. */
+
+match
+gfc_match_open (void)
+{
+ gfc_open *open;
+ match m;
+
+ m = gfc_match_char ('(');
+ if (m == MATCH_NO)
+ return m;
+
+ open = gfc_getmem (sizeof (gfc_open));
+
+ m = match_open_element (open);
+
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ {
+ m = gfc_match_expr (&open->unit);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ }
+
+ for (;;)
+ {
+ if (gfc_match_char (')') == MATCH_YES)
+ break;
+ if (gfc_match_char (',') != MATCH_YES)
+ goto syntax;
+
+ m = match_open_element (open);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ goto syntax;
+ }
+
+ if (gfc_match_eos () == MATCH_NO)
+ goto syntax;
+
+ if (gfc_pure (NULL))
+ {
+ gfc_error ("OPEN statement not allowed in PURE procedure at %C");
+ goto cleanup;
+ }
+
+ new_st.op = EXEC_OPEN;
+ new_st.ext.open = open;
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (ST_OPEN);
+
+cleanup:
+ gfc_free_open (open);
+ return MATCH_ERROR;
+}
+
+
+/* Free a gfc_close structure an all its expressions. */
+
+void
+gfc_free_close (gfc_close * close)
+{
+
+ if (close == NULL)
+ return;
+
+ gfc_free_expr (close->unit);
+ gfc_free_expr (close->iostat);
+ gfc_free_expr (close->status);
+
+ gfc_free (close);
+}
+
+
+/* Match elements of a CLOSE statment. */
+
+static match
+match_close_element (gfc_close * close)
+{
+ match m;
+
+ m = match_etag (&tag_unit, &close->unit);
+ if (m != MATCH_NO)
+ return m;
+ m = match_etag (&tag_status, &close->status);
+ if (m != MATCH_NO)
+ return m;
+ m = match_vtag (&tag_iostat, &close->iostat);
+ if (m != MATCH_NO)
+ return m;
+ m = match_ltag (&tag_err, &close->err);
+ if (m != MATCH_NO)
+ return m;
+
+ return MATCH_NO;
+}
+
+
+/* Match a CLOSE statement. */
+
+match
+gfc_match_close (void)
+{
+ gfc_close *close;
+ match m;
+
+ m = gfc_match_char ('(');
+ if (m == MATCH_NO)
+ return m;
+
+ close = gfc_getmem (sizeof (gfc_close));
+
+ m = match_close_element (close);
+
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ {
+ m = gfc_match_expr (&close->unit);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ }
+
+ for (;;)
+ {
+ if (gfc_match_char (')') == MATCH_YES)
+ break;
+ if (gfc_match_char (',') != MATCH_YES)
+ goto syntax;
+
+ m = match_close_element (close);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ goto syntax;
+ }
+
+ if (gfc_match_eos () == MATCH_NO)
+ goto syntax;
+
+ if (gfc_pure (NULL))
+ {
+ gfc_error ("CLOSE statement not allowed in PURE procedure at %C");
+ goto cleanup;
+ }
+
+ new_st.op = EXEC_CLOSE;
+ new_st.ext.close = close;
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (ST_CLOSE);
+
+cleanup:
+ gfc_free_close (close);
+ return MATCH_ERROR;
+}
+
+
+/* Resolve everything in a gfc_close structure. */
+
+try
+gfc_resolve_close (gfc_close * close)
+{
+
+ RESOLVE_TAG (&tag_unit, close->unit);
+ RESOLVE_TAG (&tag_iostat, close->iostat);
+ RESOLVE_TAG (&tag_status, close->status);
+
+ if (gfc_reference_st_label (close->err, ST_LABEL_TARGET) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+/* Free a gfc_filepos structure. */
+
+void
+gfc_free_filepos (gfc_filepos * fp)
+{
+
+ gfc_free_expr (fp->unit);
+ gfc_free_expr (fp->iostat);
+ gfc_free (fp);
+}
+
+
+/* Match elements of a REWIND, BACKSPACE or ENDFILE statement. */
+
+static match
+match_file_element (gfc_filepos * fp)
+{
+ match m;
+
+ m = match_etag (&tag_unit, &fp->unit);
+ if (m != MATCH_NO)
+ return m;
+ m = match_vtag (&tag_iostat, &fp->iostat);
+ if (m != MATCH_NO)
+ return m;
+ m = match_ltag (&tag_err, &fp->err);
+ if (m != MATCH_NO)
+ return m;
+
+ return MATCH_NO;
+}
+
+
+/* Match the second half of the file-positioning statements, REWIND,
+ BACKSPACE or ENDFILE. */
+
+static match
+match_filepos (gfc_statement st, gfc_exec_op op)
+{
+ gfc_filepos *fp;
+ match m;
+
+ fp = gfc_getmem (sizeof (gfc_filepos));
+
+ if (gfc_match_char ('(') == MATCH_NO)
+ {
+ m = gfc_match_expr (&fp->unit);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ goto syntax;
+
+ goto done;
+ }
+
+ m = match_file_element (fp);
+ if (m == MATCH_ERROR)
+ goto done;
+ if (m == MATCH_NO)
+ {
+ m = gfc_match_expr (&fp->unit);
+ if (m == MATCH_ERROR)
+ goto done;
+ if (m == MATCH_NO)
+ goto syntax;
+ }
+
+ for (;;)
+ {
+ if (gfc_match_char (')') == MATCH_YES)
+ break;
+ if (gfc_match_char (',') != MATCH_YES)
+ goto syntax;
+
+ m = match_file_element (fp);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ goto syntax;
+ }
+
+done:
+ if (gfc_match_eos () != MATCH_YES)
+ goto syntax;
+
+ if (gfc_pure (NULL))
+ {
+ gfc_error ("%s statement not allowed in PURE procedure at %C",
+ gfc_ascii_statement (st));
+
+ goto cleanup;
+ }
+
+ new_st.op = op;
+ new_st.ext.filepos = fp;
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (st);
+
+cleanup:
+ gfc_free_filepos (fp);
+ return MATCH_ERROR;
+}
+
+
+try
+gfc_resolve_filepos (gfc_filepos * fp)
+{
+
+ RESOLVE_TAG (&tag_unit, fp->unit);
+ if (gfc_reference_st_label (fp->err, ST_LABEL_TARGET) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+/* Match the file positioning statements: ENDFILE, BACKSPACE or
+ REWIND. */
+
+match
+gfc_match_endfile (void)
+{
+
+ return match_filepos (ST_END_FILE, EXEC_ENDFILE);
+}
+
+match
+gfc_match_backspace (void)
+{
+
+ return match_filepos (ST_BACKSPACE, EXEC_BACKSPACE);
+}
+
+match
+gfc_match_rewind (void)
+{
+
+ return match_filepos (ST_REWIND, EXEC_REWIND);
+}
+
+
+/******************** Data Transfer Statments *********************/
+
+typedef enum
+{ M_READ, M_WRITE, M_PRINT, M_INQUIRE }
+io_kind;
+
+
+/* Return a default unit number. */
+
+static gfc_expr *
+default_unit (io_kind k)
+{
+ int unit;
+
+ if (k == M_READ)
+ unit = 5;
+ else
+ unit = 6;
+
+ return gfc_int_expr (unit);
+}
+
+
+/* Match a unit specification for a data transfer statement. */
+
+static match
+match_dt_unit (io_kind k, gfc_dt * dt)
+{
+ gfc_expr *e;
+
+ if (gfc_match_char ('*') == MATCH_YES)
+ {
+ if (dt->io_unit != NULL)
+ goto conflict;
+
+ dt->io_unit = default_unit (k);
+ return MATCH_YES;
+ }
+
+ if (gfc_match_expr (&e) == MATCH_YES)
+ {
+ if (dt->io_unit != NULL)
+ {
+ gfc_free_expr (e);
+ goto conflict;
+ }
+
+ dt->io_unit = e;
+ return MATCH_YES;
+ }
+
+ return MATCH_NO;
+
+conflict:
+ gfc_error ("Duplicate UNIT specification at %C");
+ return MATCH_ERROR;
+}
+
+
+/* Match a format specification. */
+
+static match
+match_dt_format (gfc_dt * dt)
+{
+ locus where;
+ gfc_expr *e;
+ gfc_st_label *label;
+
+ where = *gfc_current_locus ();
+
+ if (gfc_match_char ('*') == MATCH_YES)
+ {
+ if (dt->format_expr != NULL || dt->format_label != NULL)
+ goto conflict;
+
+ dt->format_label = &format_asterisk;
+ return MATCH_YES;
+ }
+
+ if (gfc_match_st_label (&label, 0) == MATCH_YES)
+ {
+ if (dt->format_expr != NULL || dt->format_label != NULL)
+ {
+ gfc_free_st_label (label);
+ goto conflict;
+ }
+
+ if (gfc_reference_st_label (label, ST_LABEL_FORMAT) == FAILURE)
+ return MATCH_ERROR;
+
+ dt->format_label = label;
+ return MATCH_YES;
+ }
+
+ if (gfc_match_expr (&e) == MATCH_YES)
+ {
+ if (dt->format_expr != NULL || dt->format_label != NULL)
+ {
+ gfc_free_expr (e);
+ goto conflict;
+ }
+ if (e->ts.type == BT_INTEGER && e->rank == 0)
+ e->symtree->n.sym->attr.assign = 1;
+
+ dt->format_expr = e;
+ return MATCH_YES;
+ }
+
+ gfc_set_locus (&where); /* The only case where we have to restore */
+
+ return MATCH_NO;
+
+conflict:
+ gfc_error ("Duplicate format specification at %C");
+ return MATCH_ERROR;
+}
+
+
+/* Traverse a namelist that is part of a READ statement to make sure
+ that none of the variables in the namelist are INTENT(IN). Returns
+ nonzero if we find such a variable. */
+
+static int
+check_namelist (gfc_symbol * sym)
+{
+ gfc_namelist *p;
+
+ for (p = sym->namelist; p; p = p->next)
+ if (p->sym->attr.intent == INTENT_IN)
+ {
+ gfc_error ("Symbol '%s' in namelist '%s' is INTENT(IN) at %C",
+ p->sym->name, sym->name);
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/* Match a single data transfer element. */
+
+static match
+match_dt_element (io_kind k, gfc_dt * dt)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_symbol *sym;
+ match m;
+
+ if (gfc_match (" unit =") == MATCH_YES)
+ {
+ m = match_dt_unit (k, dt);
+ if (m != MATCH_NO)
+ return m;
+ }
+
+ if (gfc_match (" fmt =") == MATCH_YES)
+ {
+ m = match_dt_format (dt);
+ if (m != MATCH_NO)
+ return m;
+ }
+
+ if (gfc_match (" nml = %n", name) == MATCH_YES)
+ {
+ if (dt->namelist != NULL)
+ {
+ gfc_error ("Duplicate NML specification at %C");
+ return MATCH_ERROR;
+ }
+
+ if (gfc_find_symbol (name, NULL, 1, &sym))
+ return MATCH_ERROR;
+
+ if (sym == NULL || sym->attr.flavor != FL_NAMELIST)
+ {
+ gfc_error ("Symbol '%s' at %C must be a NAMELIST group name",
+ sym != NULL ? sym->name : name);
+ return MATCH_ERROR;
+ }
+
+ dt->namelist = sym;
+ if (k == M_READ && check_namelist (sym))
+ return MATCH_ERROR;
+
+ return MATCH_YES;
+ }
+
+ m = match_etag (&tag_rec, &dt->rec);
+ if (m != MATCH_NO)
+ return m;
+ m = match_vtag (&tag_iostat, &dt->iostat);
+ if (m != MATCH_NO)
+ return m;
+ m = match_ltag (&tag_err, &dt->err);
+ if (m != MATCH_NO)
+ return m;
+ m = match_etag (&tag_advance, &dt->advance);
+ if (m != MATCH_NO)
+ return m;
+ m = match_vtag (&tag_size, &dt->size);
+ if (m != MATCH_NO)
+ return m;
+
+ m = match_ltag (&tag_end, &dt->end);
+ if (m == MATCH_YES)
+ dt->end_where = *gfc_current_locus ();
+ if (m != MATCH_NO)
+ return m;
+
+ m = match_ltag (&tag_eor, &dt->eor);
+ if (m == MATCH_YES)
+ dt->eor_where = *gfc_current_locus ();
+ if (m != MATCH_NO)
+ return m;
+
+ return MATCH_NO;
+}
+
+
+/* Free a data transfer structure and everything below it. */
+
+void
+gfc_free_dt (gfc_dt * dt)
+{
+
+ if (dt == NULL)
+ return;
+
+ gfc_free_expr (dt->io_unit);
+ gfc_free_expr (dt->format_expr);
+ gfc_free_expr (dt->rec);
+ gfc_free_expr (dt->advance);
+ gfc_free_expr (dt->iostat);
+ gfc_free_expr (dt->size);
+
+ gfc_free (dt);
+}
+
+
+/* Resolve everything in a gfc_dt structure. */
+
+try
+gfc_resolve_dt (gfc_dt * dt)
+{
+ gfc_expr *e;
+
+ RESOLVE_TAG (&tag_format, dt->format_expr);
+ RESOLVE_TAG (&tag_rec, dt->rec);
+ RESOLVE_TAG (&tag_advance, dt->advance);
+ RESOLVE_TAG (&tag_iostat, dt->iostat);
+ RESOLVE_TAG (&tag_size, dt->size);
+
+ e = dt->io_unit;
+ if (gfc_resolve_expr (e) == SUCCESS
+ && (e->ts.type != BT_INTEGER
+ && (e->ts.type != BT_CHARACTER
+ || e->expr_type != EXPR_VARIABLE)))
+ {
+ gfc_error
+ ("UNIT specification at %L must be an INTEGER expression or a "
+ "CHARACTER variable", &e->where);
+ return FAILURE;
+ }
+
+ /* Sanity checks on data transfer statements. */
+ if (e->ts.type == BT_CHARACTER)
+ {
+ if (dt->rec != NULL)
+ {
+ gfc_error ("REC tag at %L is incompatible with internal file",
+ &dt->rec->where);
+ return FAILURE;
+ }
+
+ if (dt->namelist != NULL)
+ {
+ gfc_error ("Internal file at %L is incompatible with namelist",
+ &dt->io_unit->where);
+ return FAILURE;
+ }
+
+ if (dt->advance != NULL)
+ {
+ gfc_error ("ADVANCE tag at %L is incompatible with internal file",
+ &dt->advance->where);
+ return FAILURE;
+ }
+ }
+
+ if (dt->rec != NULL)
+ {
+ if (dt->end != NULL)
+ {
+ gfc_error ("REC tag at %L is incompatible with END tag",
+ &dt->rec->where);
+ return FAILURE;
+ }
+
+ if (dt->format_label == &format_asterisk)
+ {
+ gfc_error
+ ("END tag at %L is incompatible with list directed format (*)",
+ &dt->end_where);
+ return FAILURE;
+ }
+
+ if (dt->namelist != NULL)
+ {
+ gfc_error ("REC tag at %L is incompatible with namelist",
+ &dt->rec->where);
+ return FAILURE;
+ }
+ }
+
+ if (dt->advance != NULL && dt->format_label == &format_asterisk)
+ {
+ gfc_error ("ADVANCE tag at %L is incompatible with list directed "
+ "format (*)", &dt->advance->where);
+ return FAILURE;
+ }
+
+ if (dt->eor != 0 && dt->advance == NULL)
+ {
+ gfc_error ("EOR tag at %L requires an ADVANCE tag", &dt->eor_where);
+ return FAILURE;
+ }
+
+ if (dt->size != NULL && dt->advance == NULL)
+ {
+ gfc_error ("SIZE tag at %L requires an ADVANCE tag", &dt->size->where);
+ return FAILURE;
+ }
+
+ /* TODO: Make sure the ADVANCE tag is 'yes' or 'no' if it is a string
+ constant. */
+
+ if (gfc_reference_st_label (dt->err, ST_LABEL_TARGET) == FAILURE)
+ return FAILURE;
+
+ if (gfc_reference_st_label (dt->end, ST_LABEL_TARGET) == FAILURE)
+ return FAILURE;
+
+ if (gfc_reference_st_label (dt->eor, ST_LABEL_TARGET) == FAILURE)
+ return FAILURE;
+
+ /* Check the format label ectually exists. */
+ if (dt->format_label && dt->format_label != &format_asterisk
+ && dt->format_label->defined == ST_LABEL_UNKNOWN)
+ {
+ gfc_error ("FORMAT label %d at %L not defined", dt->format_label->value,
+ &dt->format_label->where);
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+
+
+/* Given an io_kind, return its name. */
+
+static const char *
+io_kind_name (io_kind k)
+{
+ const char *name;
+
+ switch (k)
+ {
+ case M_READ:
+ name = "READ";
+ break;
+ case M_WRITE:
+ name = "WRITE";
+ break;
+ case M_PRINT:
+ name = "PRINT";
+ break;
+ case M_INQUIRE:
+ name = "INQUIRE";
+ break;
+ default:
+ gfc_internal_error ("io_kind_name(): bad I/O-kind");
+ }
+
+ return name;
+}
+
+
+/* Match an IO iteration statement of the form:
+
+ ( [<IO element> ,] <IO element>, I = <expr>, <expr> [, <expr> ] )
+
+ which is equivalent to a single IO element. This function is
+ mutually recursive with match_io_element(). */
+
+static match match_io_element (io_kind k, gfc_code **);
+
+static match
+match_io_iterator (io_kind k, gfc_code ** result)
+{
+ gfc_code *head, *tail, *new;
+ gfc_iterator *iter;
+ locus old_loc;
+ match m;
+ int n;
+
+ iter = NULL;
+ head = NULL;
+ old_loc = *gfc_current_locus ();
+
+ if (gfc_match_char ('(') != MATCH_YES)
+ return MATCH_NO;
+
+ m = match_io_element (k, &head);
+ tail = head;
+
+ if (m != MATCH_YES || gfc_match_char (',') != MATCH_YES)
+ {
+ m = MATCH_NO;
+ goto cleanup;
+ }
+
+ /* Can't be anything but an IO iterator. Build a list. */
+ iter = gfc_get_iterator ();
+
+ for (n = 1;; n++)
+ {
+ m = gfc_match_iterator (iter, 0);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_YES)
+ break;
+
+ m = match_io_element (k, &new);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ {
+ if (n > 2)
+ goto syntax;
+ goto cleanup;
+ }
+
+ tail = gfc_append_code (tail, new);
+
+ if (gfc_match_char (',') != MATCH_YES)
+ {
+ if (n > 2)
+ goto syntax;
+ m = MATCH_NO;
+ goto cleanup;
+ }
+ }
+
+ if (gfc_match_char (')') != MATCH_YES)
+ goto syntax;
+
+ new = gfc_get_code ();
+ new->op = EXEC_DO;
+ new->ext.iterator = iter;
+
+ new->block = gfc_get_code ();
+ new->block->op = EXEC_DO;
+ new->block->next = head;
+
+ *result = new;
+ return MATCH_YES;
+
+syntax:
+ gfc_error ("Syntax error in I/O iterator at %C");
+ m = MATCH_ERROR;
+
+cleanup:
+ gfc_free_iterator (iter, 1);
+ gfc_free_statements (head);
+ gfc_set_locus (&old_loc);
+ return m;
+}
+
+
+/* Match a single element of an IO list, which is either a single
+ expression or an IO Iterator. */
+
+static match
+match_io_element (io_kind k, gfc_code ** cpp)
+{
+ gfc_expr *expr;
+ gfc_code *cp;
+ match m;
+
+ expr = NULL;
+
+ m = match_io_iterator (k, cpp);
+ if (m == MATCH_YES)
+ return MATCH_YES;
+
+ if (k == M_READ)
+ {
+ m = gfc_match_variable (&expr, 0);
+ if (m == MATCH_NO)
+ gfc_error ("Expected variable in READ statement at %C");
+ }
+ else
+ {
+ m = gfc_match_expr (&expr);
+ if (m == MATCH_NO)
+ gfc_error ("Expected expression in %s statement at %C",
+ io_kind_name (k));
+ }
+
+ if (m == MATCH_YES)
+ switch (k)
+ {
+ case M_READ:
+ if (expr->symtree->n.sym->attr.intent == INTENT_IN)
+ {
+ gfc_error
+ ("Variable '%s' in input list at %C cannot be INTENT(IN)",
+ expr->symtree->n.sym->name);
+ m = MATCH_ERROR;
+ }
+
+ if (gfc_pure (NULL)
+ && gfc_impure_variable (expr->symtree->n.sym)
+ && current_dt->io_unit->ts.type == BT_CHARACTER)
+ {
+ gfc_error ("Cannot read to variable '%s' in PURE procedure at %C",
+ expr->symtree->n.sym->name);
+ m = MATCH_ERROR;
+ }
+
+ break;
+
+ case M_WRITE:
+ if (current_dt->io_unit->ts.type == BT_CHARACTER
+ && gfc_pure (NULL)
+ && current_dt->io_unit->expr_type == EXPR_VARIABLE
+ && gfc_impure_variable (current_dt->io_unit->symtree->n.sym))
+ {
+ gfc_error
+ ("Cannot write to internal file unit '%s' at %C inside a "
+ "PURE procedure", current_dt->io_unit->symtree->n.sym->name);
+ m = MATCH_ERROR;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+
+ if (m != MATCH_YES)
+ {
+ gfc_free_expr (expr);
+ return MATCH_ERROR;
+ }
+
+ cp = gfc_get_code ();
+ cp->op = EXEC_TRANSFER;
+ cp->expr = expr;
+
+ *cpp = cp;
+ return MATCH_YES;
+}
+
+
+/* Match an I/O list, building gfc_code structures as we go. */
+
+static match
+match_io_list (io_kind k, gfc_code ** head_p)
+{
+ gfc_code *head, *tail, *new;
+ match m;
+
+ *head_p = head = tail = NULL;
+ if (gfc_match_eos () == MATCH_YES)
+ return MATCH_YES;
+
+ for (;;)
+ {
+ m = match_io_element (k, &new);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ goto syntax;
+
+ tail = gfc_append_code (tail, new);
+ if (head == NULL)
+ head = new;
+
+ if (gfc_match_eos () == MATCH_YES)
+ break;
+ if (gfc_match_char (',') != MATCH_YES)
+ goto syntax;
+ }
+
+ *head_p = head;
+ return MATCH_YES;
+
+syntax:
+ gfc_error ("Syntax error in %s statement at %C", io_kind_name (k));
+
+cleanup:
+ gfc_free_statements (head);
+ return MATCH_ERROR;
+}
+
+
+/* Attach the data transfer end node. */
+
+static void
+terminate_io (gfc_code * io_code)
+{
+ gfc_code *c;
+
+ if (io_code == NULL)
+ io_code = &new_st;
+
+ c = gfc_get_code ();
+ c->op = EXEC_DT_END;
+
+ /* Point to structure that is already there */
+ c->ext.dt = new_st.ext.dt;
+ gfc_append_code (io_code, c);
+}
+
+
+/* Match a READ, WRITE or PRINT statement. */
+
+static match
+match_io (io_kind k)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_code *io_code;
+ gfc_symbol *sym;
+ gfc_expr *expr;
+ int comma_flag;
+ locus where;
+ gfc_dt *dt;
+ match m;
+
+ comma_flag = 0;
+ current_dt = dt = gfc_getmem (sizeof (gfc_dt));
+
+ if (gfc_match_char ('(') == MATCH_NO)
+ {
+ if (k == M_WRITE)
+ goto syntax;
+
+ m = match_dt_format (dt);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ goto syntax;
+
+ comma_flag = 1;
+ dt->io_unit = default_unit (k);
+ goto get_io_list;
+ }
+
+ /* Match a control list */
+ if (match_dt_element (k, dt) == MATCH_YES)
+ goto next;
+ if (match_dt_unit (k, dt) != MATCH_YES)
+ goto loop;
+
+ if (gfc_match_char (')') == MATCH_YES)
+ goto get_io_list;
+ if (gfc_match_char (',') != MATCH_YES)
+ goto syntax;
+
+ m = match_dt_element (k, dt);
+ if (m == MATCH_YES)
+ goto next;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ m = match_dt_format (dt);
+ if (m == MATCH_YES)
+ goto next;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ where = *gfc_current_locus ();
+
+ if (gfc_match_name (name) == MATCH_YES
+ && !gfc_find_symbol (name, NULL, 1, &sym)
+ && sym->attr.flavor == FL_NAMELIST)
+ {
+ dt->namelist = sym;
+ if (k == M_READ && check_namelist (sym))
+ {
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+ goto next;
+ }
+
+ gfc_set_locus (&where);
+
+ goto loop; /* No matches, try regular elements */
+
+next:
+ if (gfc_match_char (')') == MATCH_YES)
+ goto get_io_list;
+ if (gfc_match_char (',') != MATCH_YES)
+ goto syntax;
+
+loop:
+ for (;;)
+ {
+ m = match_dt_element (k, dt);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ if (gfc_match_char (')') == MATCH_YES)
+ break;
+ if (gfc_match_char (',') != MATCH_YES)
+ goto syntax;
+ }
+
+get_io_list:
+ /* Optional leading comma (non-standard). */
+ if (!comma_flag)
+ gfc_match_char (',');
+
+ io_code = NULL;
+ if (gfc_match_eos () != MATCH_YES)
+ {
+ if (comma_flag && gfc_match_char (',') != MATCH_YES)
+ {
+ gfc_error ("Expected comma in I/O list at %C");
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ m = match_io_list (k, &io_code);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ goto syntax;
+ }
+
+ /* A full IO statement has been matched. */
+ if (dt->io_unit->expr_type == EXPR_VARIABLE
+ && k == M_WRITE
+ && dt->io_unit->ts.type == BT_CHARACTER
+ && dt->io_unit->symtree->n.sym->attr.intent == INTENT_IN)
+ {
+ gfc_error ("Internal file '%s' at %L is INTENT(IN)",
+ dt->io_unit->symtree->n.sym->name, &dt->io_unit->where);
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ expr = dt->format_expr;
+
+ if (expr != NULL && expr->expr_type == EXPR_CONSTANT)
+ check_format_string (expr);
+
+ if (gfc_pure (NULL)
+ && (k == M_READ || k == M_WRITE)
+ && dt->io_unit->ts.type != BT_CHARACTER)
+ {
+ gfc_error
+ ("io-unit in %s statement at %C must be an internal file in a "
+ "PURE procedure", io_kind_name (k));
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ new_st.op = (k == M_READ) ? EXEC_READ : EXEC_WRITE;
+ new_st.ext.dt = dt;
+ new_st.next = io_code;
+
+ terminate_io (io_code);
+
+ return MATCH_YES;
+
+syntax:
+ gfc_error ("Syntax error in %s statement at %C", io_kind_name (k));
+ m = MATCH_ERROR;
+
+cleanup:
+ gfc_free_dt (dt);
+ return m;
+}
+
+
+match
+gfc_match_read (void)
+{
+ return match_io (M_READ);
+}
+
+match
+gfc_match_write (void)
+{
+ return match_io (M_WRITE);
+}
+
+match
+gfc_match_print (void)
+{
+ match m;
+
+ m = match_io (M_PRINT);
+ if (m != MATCH_YES)
+ return m;
+
+ if (gfc_pure (NULL))
+ {
+ gfc_error ("PRINT statement at %C not allowed within PURE procedure");
+ return MATCH_ERROR;
+ }
+
+ return MATCH_YES;
+}
+
+
+/* Free a gfc_inquire structure. */
+
+void
+gfc_free_inquire (gfc_inquire * inquire)
+{
+
+ if (inquire == NULL)
+ return;
+
+ gfc_free_expr (inquire->unit);
+ gfc_free_expr (inquire->file);
+ gfc_free_expr (inquire->iostat);
+ gfc_free_expr (inquire->exist);
+ gfc_free_expr (inquire->opened);
+ gfc_free_expr (inquire->number);
+ gfc_free_expr (inquire->named);
+ gfc_free_expr (inquire->name);
+ gfc_free_expr (inquire->access);
+ gfc_free_expr (inquire->sequential);
+ gfc_free_expr (inquire->direct);
+ gfc_free_expr (inquire->form);
+ gfc_free_expr (inquire->formatted);
+ gfc_free_expr (inquire->unformatted);
+ gfc_free_expr (inquire->recl);
+ gfc_free_expr (inquire->nextrec);
+ gfc_free_expr (inquire->blank);
+ gfc_free_expr (inquire->position);
+ gfc_free_expr (inquire->action);
+ gfc_free_expr (inquire->read);
+ gfc_free_expr (inquire->write);
+ gfc_free_expr (inquire->readwrite);
+ gfc_free_expr (inquire->delim);
+ gfc_free_expr (inquire->pad);
+ gfc_free_expr (inquire->iolength);
+
+ gfc_free (inquire);
+}
+
+
+/* Match an element of an INQUIRE statement. */
+
+#define RETM if (m != MATCH_NO) return m;
+
+static match
+match_inquire_element (gfc_inquire * inquire)
+{
+ match m;
+
+ m = match_etag (&tag_unit, &inquire->unit);
+ RETM m = match_etag (&tag_file, &inquire->file);
+ RETM m = match_ltag (&tag_err, &inquire->err);
+ RETM m = match_vtag (&tag_iostat, &inquire->iostat);
+ RETM m = match_vtag (&tag_exist, &inquire->exist);
+ RETM m = match_vtag (&tag_opened, &inquire->opened);
+ RETM m = match_vtag (&tag_named, &inquire->named);
+ RETM m = match_vtag (&tag_name, &inquire->name);
+ RETM m = match_vtag (&tag_number, &inquire->number);
+ RETM m = match_vtag (&tag_s_access, &inquire->access);
+ RETM m = match_vtag (&tag_sequential, &inquire->sequential);
+ RETM m = match_vtag (&tag_direct, &inquire->direct);
+ RETM m = match_vtag (&tag_s_form, &inquire->form);
+ RETM m = match_vtag (&tag_formatted, &inquire->formatted);
+ RETM m = match_vtag (&tag_unformatted, &inquire->unformatted);
+ RETM m = match_vtag (&tag_s_recl, &inquire->recl);
+ RETM m = match_vtag (&tag_nextrec, &inquire->nextrec);
+ RETM m = match_vtag (&tag_s_blank, &inquire->blank);
+ RETM m = match_vtag (&tag_s_position, &inquire->position);
+ RETM m = match_vtag (&tag_s_action, &inquire->action);
+ RETM m = match_vtag (&tag_read, &inquire->read);
+ RETM m = match_vtag (&tag_write, &inquire->write);
+ RETM m = match_vtag (&tag_readwrite, &inquire->readwrite);
+ RETM m = match_vtag (&tag_s_delim, &inquire->delim);
+ RETM m = match_vtag (&tag_s_pad, &inquire->pad);
+ RETM m = match_vtag (&tag_iolength, &inquire->iolength);
+ RETM return MATCH_NO;
+}
+
+#undef RETM
+
+
+match
+gfc_match_inquire (void)
+{
+ gfc_inquire *inquire;
+ gfc_code *code;
+ match m;
+
+ m = gfc_match_char ('(');
+ if (m == MATCH_NO)
+ return m;
+
+ inquire = gfc_getmem (sizeof (gfc_inquire));
+
+ m = match_inquire_element (inquire);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ {
+ m = gfc_match_expr (&inquire->unit);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ goto syntax;
+ }
+
+ /* See if we have the IOLENGTH form of the inquire statement. */
+ if (inquire->iolength != NULL)
+ {
+ if (gfc_match_char (')') != MATCH_YES)
+ goto syntax;
+
+ m = match_io_list (M_INQUIRE, &code);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ goto syntax;
+
+ terminate_io (code);
+
+ new_st.op = EXEC_IOLENGTH;
+ new_st.expr = inquire->iolength;
+ gfc_free (inquire);
+
+ if (gfc_pure (NULL))
+ {
+ gfc_free_statements (code);
+ gfc_error ("INQUIRE statement not allowed in PURE procedure at %C");
+ return MATCH_ERROR;
+ }
+
+ new_st.next = code;
+ return MATCH_YES;
+ }
+
+ /* At this point, we have the non-IOLENGTH inquire statement. */
+ for (;;)
+ {
+ if (gfc_match_char (')') == MATCH_YES)
+ break;
+ if (gfc_match_char (',') != MATCH_YES)
+ goto syntax;
+
+ m = match_inquire_element (inquire);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ goto syntax;
+
+ if (inquire->iolength != NULL)
+ {
+ gfc_error ("IOLENGTH tag invalid in INQUIRE statement at %C");
+ goto cleanup;
+ }
+ }
+
+ if (gfc_match_eos () != MATCH_YES)
+ goto syntax;
+
+ if (gfc_pure (NULL))
+ {
+ gfc_error ("INQUIRE statement not allowed in PURE procedure at %C");
+ goto cleanup;
+ }
+
+ new_st.op = EXEC_INQUIRE;
+ new_st.ext.inquire = inquire;
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (ST_INQUIRE);
+
+cleanup:
+ gfc_free_inquire (inquire);
+ return MATCH_ERROR;
+}
+
+
+/* Resolve everything in a gfc_inquire structure. */
+
+try
+gfc_resolve_inquire (gfc_inquire * inquire)
+{
+
+ RESOLVE_TAG (&tag_unit, inquire->unit);
+ RESOLVE_TAG (&tag_file, inquire->file);
+ RESOLVE_TAG (&tag_iostat, inquire->iostat);
+ RESOLVE_TAG (&tag_exist, inquire->exist);
+ RESOLVE_TAG (&tag_opened, inquire->opened);
+ RESOLVE_TAG (&tag_number, inquire->number);
+ RESOLVE_TAG (&tag_named, inquire->named);
+ RESOLVE_TAG (&tag_name, inquire->name);
+ RESOLVE_TAG (&tag_s_access, inquire->access);
+ RESOLVE_TAG (&tag_sequential, inquire->sequential);
+ RESOLVE_TAG (&tag_direct, inquire->direct);
+ RESOLVE_TAG (&tag_s_form, inquire->form);
+ RESOLVE_TAG (&tag_formatted, inquire->formatted);
+ RESOLVE_TAG (&tag_unformatted, inquire->unformatted);
+ RESOLVE_TAG (&tag_s_recl, inquire->recl);
+ RESOLVE_TAG (&tag_nextrec, inquire->nextrec);
+ RESOLVE_TAG (&tag_s_blank, inquire->blank);
+ RESOLVE_TAG (&tag_s_position, inquire->position);
+ RESOLVE_TAG (&tag_s_action, inquire->action);
+ RESOLVE_TAG (&tag_read, inquire->read);
+ RESOLVE_TAG (&tag_write, inquire->write);
+ RESOLVE_TAG (&tag_readwrite, inquire->readwrite);
+ RESOLVE_TAG (&tag_s_delim, inquire->delim);
+ RESOLVE_TAG (&tag_s_pad, inquire->pad);
+
+ if (gfc_reference_st_label (inquire->err, ST_LABEL_TARGET) == FAILURE)
+ return FAILURE;
+
+ return FAILURE;
+}
diff --git a/gcc/fortran/iresolve.c b/gcc/fortran/iresolve.c
new file mode 100644
index 00000000000..e873f03f0dc
--- /dev/null
+++ b/gcc/fortran/iresolve.c
@@ -0,0 +1,1388 @@
+/* Intrinsic function resolution.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation,
+ Inc.
+ Contributed by Andy Vaught & Katherine Holcomb
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+/* Assign name and types to intrinsic procedures. For functions, the
+ first argument to a resolution function is an expression pointer to
+ the original function node and the rest are pointers to the
+ arguments of the function call. For subroutines, a pointer to the
+ code node is passed. The result type and library subroutine name
+ are generally set according to the function arguments. */
+
+#include "config.h"
+#include <string.h>
+#include <stdarg.h>
+
+#include "gfortran.h"
+#include "intrinsic.h"
+
+
+/* String pool subroutines. This are used to provide static locations
+ for the string constants that represent library function names. */
+
+typedef struct string_node
+{
+ struct string_node *next;
+ char string[1];
+}
+string_node;
+
+#define HASH_SIZE 13
+
+static string_node *string_head[HASH_SIZE];
+
+
+/* Return a hash code based on the name. */
+
+static int
+hash (const char *name)
+{
+ int h;
+
+ h = 1;
+ while (*name)
+ h = 5311966 * h + *name++;
+
+ if (h < 0)
+ h = -h;
+ return h % HASH_SIZE;
+}
+
+
+/* Given printf-like arguments, return a static address of the
+ resulting string. If the name is not in the table, it is added. */
+
+char *
+gfc_get_string (const char *format, ...)
+{
+ char temp_name[50];
+ string_node *p;
+ va_list ap;
+ int h;
+
+ va_start (ap, format);
+ vsprintf (temp_name, format, ap);
+ va_end (ap);
+
+ h = hash (temp_name);
+
+ /* Search */
+ for (p = string_head[h]; p; p = p->next)
+ if (strcmp (p->string, temp_name) == 0)
+ return p->string;
+
+ /* Add */
+ p = gfc_getmem (sizeof (string_node) + strlen (temp_name));
+
+ strcpy (p->string, temp_name);
+
+ p->next = string_head[h];
+ string_head[h] = p;
+
+ return p->string;
+}
+
+
+
+static void
+free_strings (void)
+{
+ string_node *p, *q;
+ int h;
+
+ for (h = 0; h < HASH_SIZE; h++)
+ {
+ for (p = string_head[h]; p; p = q)
+ {
+ q = p->next;
+ gfc_free (p);
+ }
+ }
+}
+
+
+/********************** Resolution functions **********************/
+
+
+void
+gfc_resolve_abs (gfc_expr * f, gfc_expr * a)
+{
+
+ f->ts = a->ts;
+ if (f->ts.type == BT_COMPLEX)
+ f->ts.type = BT_REAL;
+
+ f->value.function.name =
+ gfc_get_string ("__abs_%c%d", gfc_type_letter (a->ts.type), a->ts.kind);
+}
+
+
+void
+gfc_resolve_acos (gfc_expr * f, gfc_expr * x)
+{
+
+ f->ts = x->ts;
+ f->value.function.name =
+ gfc_get_string ("__acos_%c%d", gfc_type_letter (x->ts.type), x->ts.kind);
+}
+
+
+void
+gfc_resolve_aimag (gfc_expr * f, gfc_expr * x)
+{
+
+ f->ts.type = BT_REAL;
+ f->ts.kind = x->ts.kind;
+ f->value.function.name =
+ gfc_get_string ("__aimag_%c%d", gfc_type_letter (x->ts.type), x->ts.kind);
+}
+
+
+void
+gfc_resolve_aint (gfc_expr * f, gfc_expr * a, gfc_expr * kind)
+{
+
+ f->ts.type = a->ts.type;
+ f->ts.kind = (kind == NULL) ? a->ts.kind : mpz_get_si (kind->value.integer);
+
+ /* The resolved name is only used for specific intrinsics where
+ the return kind is the same as the arg kind. */
+ f->value.function.name =
+ gfc_get_string ("__aint_%c%d", gfc_type_letter (a->ts.type), a->ts.kind);
+}
+
+
+void
+gfc_resolve_dint (gfc_expr * f, gfc_expr * a)
+{
+ gfc_resolve_aint (f, a, NULL);
+}
+
+
+void
+gfc_resolve_all (gfc_expr * f, gfc_expr * mask, gfc_expr * dim)
+{
+
+ f->ts = mask->ts;
+
+ if (dim != NULL)
+ {
+ gfc_resolve_index (dim, 1);
+ f->rank = mask->rank - 1;
+ }
+
+ f->value.function.name =
+ gfc_get_string ("__all_%c%d", gfc_type_letter (mask->ts.type),
+ mask->ts.kind);
+}
+
+
+void
+gfc_resolve_anint (gfc_expr * f, gfc_expr * a, gfc_expr * kind)
+{
+
+ f->ts.type = a->ts.type;
+ f->ts.kind = (kind == NULL) ? a->ts.kind : mpz_get_si (kind->value.integer);
+
+ /* The resolved name is only used for specific intrinsics where
+ the return kind is the same as the arg kind. */
+ f->value.function.name =
+ gfc_get_string ("__anint_%c%d", gfc_type_letter (a->ts.type), a->ts.kind);
+}
+
+
+void
+gfc_resolve_dnint (gfc_expr * f, gfc_expr * a)
+{
+ gfc_resolve_anint (f, a, NULL);
+}
+
+
+void
+gfc_resolve_any (gfc_expr * f, gfc_expr * mask, gfc_expr * dim)
+{
+
+ f->ts = mask->ts;
+
+ if (dim != NULL)
+ {
+ gfc_resolve_index (dim, 1);
+ f->rank = mask->rank - 1;
+ }
+
+ f->value.function.name =
+ gfc_get_string ("__any_%c%d", gfc_type_letter (mask->ts.type),
+ mask->ts.kind);
+}
+
+
+void
+gfc_resolve_asin (gfc_expr * f, gfc_expr * x)
+{
+
+ f->ts = x->ts;
+ f->value.function.name =
+ gfc_get_string ("__asin_%c%d", gfc_type_letter (x->ts.type), x->ts.kind);
+}
+
+
+void
+gfc_resolve_atan (gfc_expr * f, gfc_expr * x)
+{
+
+ f->ts = x->ts;
+ f->value.function.name =
+ gfc_get_string ("__atan_%c%d", gfc_type_letter (x->ts.type), x->ts.kind);
+}
+
+
+void
+gfc_resolve_atan2 (gfc_expr * f, gfc_expr * x,
+ gfc_expr * y ATTRIBUTE_UNUSED)
+{
+
+ f->ts = x->ts;
+ f->value.function.name =
+ gfc_get_string ("__atan2_%c%d", gfc_type_letter (x->ts.type), x->ts.kind);
+}
+
+
+void
+gfc_resolve_btest (gfc_expr * f, gfc_expr * i, gfc_expr * pos)
+{
+
+ f->ts.type = BT_LOGICAL;
+ f->ts.kind = gfc_default_logical_kind ();
+
+ f->value.function.name = gfc_get_string ("__btest_%d_%d", i->ts.kind,
+ pos->ts.kind);
+}
+
+
+void
+gfc_resolve_ceiling (gfc_expr * f, gfc_expr * a, gfc_expr * kind)
+{
+
+ f->ts.type = BT_INTEGER;
+ f->ts.kind = (kind == NULL) ? gfc_default_integer_kind ()
+ : mpz_get_si (kind->value.integer);
+
+ f->value.function.name =
+ gfc_get_string ("__ceiling_%d_%c%d", f->ts.kind,
+ gfc_type_letter (a->ts.type), a->ts.kind);
+}
+
+
+void
+gfc_resolve_char (gfc_expr * f, gfc_expr * a, gfc_expr * kind)
+{
+
+ f->ts.type = BT_CHARACTER;
+ f->ts.kind = (kind == NULL) ? gfc_default_character_kind ()
+ : mpz_get_si (kind->value.integer);
+
+ f->value.function.name =
+ gfc_get_string ("__char_%d_%c%d", f->ts.kind,
+ gfc_type_letter (a->ts.type), a->ts.kind);
+}
+
+
+void
+gfc_resolve_cmplx (gfc_expr * f, gfc_expr * x, gfc_expr * y, gfc_expr * kind)
+{
+
+ f->ts.type = BT_COMPLEX;
+ f->ts.kind = (kind == NULL) ? gfc_default_real_kind ()
+ : mpz_get_si (kind->value.integer);
+
+ if (y == NULL)
+ f->value.function.name =
+ gfc_get_string ("__cmplx0_%d_%c%d", f->ts.kind,
+ gfc_type_letter (x->ts.type), x->ts.kind);
+ else
+ f->value.function.name =
+ gfc_get_string ("__cmplx1_%d_%c%d_%c%d", f->ts.kind,
+ gfc_type_letter (x->ts.type), x->ts.kind,
+ gfc_type_letter (y->ts.type), y->ts.kind);
+}
+
+void
+gfc_resolve_dcmplx (gfc_expr * f, gfc_expr * x, gfc_expr * y)
+{
+ gfc_resolve_cmplx (f, x, y, gfc_int_expr (gfc_default_double_kind ()));
+}
+
+void
+gfc_resolve_conjg (gfc_expr * f, gfc_expr * x)
+{
+
+ f->ts = x->ts;
+ f->value.function.name = gfc_get_string ("__conjg_%d", x->ts.kind);
+}
+
+
+void
+gfc_resolve_cos (gfc_expr * f, gfc_expr * x)
+{
+
+ f->ts = x->ts;
+ f->value.function.name =
+ gfc_get_string ("__cos_%c%d", gfc_type_letter (x->ts.type), x->ts.kind);
+}
+
+
+void
+gfc_resolve_cosh (gfc_expr * f, gfc_expr * x)
+{
+
+ f->ts = x->ts;
+ f->value.function.name =
+ gfc_get_string ("__cosh_%c%d", gfc_type_letter (x->ts.type), x->ts.kind);
+}
+
+
+void
+gfc_resolve_count (gfc_expr * f, gfc_expr * mask, gfc_expr * dim)
+{
+
+ f->ts.type = BT_INTEGER;
+ f->ts.kind = gfc_default_integer_kind ();
+
+ if (dim != NULL)
+ {
+ f->rank = mask->rank - 1;
+ gfc_resolve_index (dim, 1);
+ }
+
+ f->value.function.name =
+ gfc_get_string ("__count_%d_%c%d", f->ts.kind,
+ gfc_type_letter (mask->ts.type), mask->ts.kind);
+}
+
+
+void
+gfc_resolve_cshift (gfc_expr * f, gfc_expr * array,
+ gfc_expr * shift,
+ gfc_expr * dim)
+{
+ int n;
+
+ f->ts = array->ts;
+ f->rank = array->rank;
+
+ if (shift->rank > 0)
+ n = 1;
+ else
+ n = 0;
+
+ if (dim != NULL)
+ {
+ gfc_resolve_index (dim, 1);
+ /* Convert dim to shift's kind, so we don't need so many variations. */
+ if (dim->ts.kind != shift->ts.kind)
+ gfc_convert_type (dim, &shift->ts, 2);
+ }
+ f->value.function.name =
+ gfc_get_string ("__cshift%d_%d", n, shift->ts.kind);
+}
+
+
+void
+gfc_resolve_dble (gfc_expr * f, gfc_expr * a)
+{
+
+ f->ts.type = BT_REAL;
+ f->ts.kind = gfc_default_double_kind ();
+ f->value.function.name =
+ gfc_get_string ("__dble_%c%d", gfc_type_letter (a->ts.type), a->ts.kind);
+}
+
+
+void
+gfc_resolve_dim (gfc_expr * f, gfc_expr * x,
+ gfc_expr * y ATTRIBUTE_UNUSED)
+{
+
+ f->ts = x->ts;
+ f->value.function.name =
+ gfc_get_string ("__dim_%c%d", gfc_type_letter (x->ts.type), x->ts.kind);
+}
+
+
+void
+gfc_resolve_dot_product (gfc_expr * f, gfc_expr * a, gfc_expr * b)
+{
+ gfc_expr temp;
+
+ if (a->ts.type == BT_LOGICAL && b->ts.type == BT_LOGICAL)
+ {
+ f->ts.type = BT_LOGICAL;
+ f->ts.kind = gfc_default_logical_kind ();
+ }
+ else
+ {
+ temp.expr_type = EXPR_OP;
+ gfc_clear_ts (&temp.ts);
+ temp.operator = INTRINSIC_NONE;
+ temp.op1 = a;
+ temp.op2 = b;
+ gfc_type_convert_binary (&temp);
+ f->ts = temp.ts;
+ }
+
+ f->value.function.name =
+ gfc_get_string ("__dot_product_%c%d", gfc_type_letter (f->ts.type),
+ f->ts.kind);
+}
+
+
+void
+gfc_resolve_dprod (gfc_expr * f,
+ gfc_expr * a ATTRIBUTE_UNUSED,
+ gfc_expr * b ATTRIBUTE_UNUSED)
+{
+ f->ts.kind = gfc_default_double_kind ();
+ f->ts.type = BT_REAL;
+
+ f->value.function.name = gfc_get_string ("__dprod_r%d", f->ts.kind);
+}
+
+
+void
+gfc_resolve_eoshift (gfc_expr * f, gfc_expr * array,
+ gfc_expr * shift,
+ gfc_expr * boundary,
+ gfc_expr * dim)
+{
+ int n;
+
+ f->ts = array->ts;
+ f->rank = array->rank;
+
+ n = 0;
+ if (shift->rank > 0)
+ n = n | 1;
+ if (boundary && boundary->rank > 0)
+ n = n | 2;
+
+ /* Convert dim to the same type as shift, so we don't need quite so many
+ variations. */
+ if (dim != NULL && dim->ts.kind != shift->ts.kind)
+ gfc_convert_type (dim, &shift->ts, 2);
+
+ f->value.function.name =
+ gfc_get_string ("__eoshift%d_%d", n, shift->ts.kind);
+}
+
+
+void
+gfc_resolve_exp (gfc_expr * f, gfc_expr * x)
+{
+
+ f->ts = x->ts;
+ f->value.function.name =
+ gfc_get_string ("__exp_%c%d", gfc_type_letter (x->ts.type), x->ts.kind);
+}
+
+
+void
+gfc_resolve_exponent (gfc_expr * f, gfc_expr * x)
+{
+
+ f->ts.type = BT_INTEGER;
+ f->ts.kind = gfc_default_integer_kind ();
+
+ f->value.function.name = gfc_get_string ("__exponent_%d", x->ts.kind);
+}
+
+
+void
+gfc_resolve_floor (gfc_expr * f, gfc_expr * a, gfc_expr * kind)
+{
+
+ f->ts.type = BT_INTEGER;
+ f->ts.kind = (kind == NULL) ? gfc_default_integer_kind ()
+ : mpz_get_si (kind->value.integer);
+
+ f->value.function.name =
+ gfc_get_string ("__floor%d_%c%d", f->ts.kind,
+ gfc_type_letter (a->ts.type), a->ts.kind);
+}
+
+
+void
+gfc_resolve_fraction (gfc_expr * f, gfc_expr * x)
+{
+
+ f->ts = x->ts;
+ f->value.function.name = gfc_get_string ("__fraction_%d", x->ts.kind);
+}
+
+
+void
+gfc_resolve_iand (gfc_expr * f, gfc_expr * i, gfc_expr * j ATTRIBUTE_UNUSED)
+{
+
+ f->ts = i->ts;
+ f->value.function.name = gfc_get_string ("__iand_%d", i->ts.kind);
+}
+
+
+void
+gfc_resolve_ibclr (gfc_expr * f, gfc_expr * i, gfc_expr * pos ATTRIBUTE_UNUSED)
+{
+
+ f->ts = i->ts;
+ f->value.function.name = gfc_get_string ("__ibclr_%d", i->ts.kind);
+}
+
+
+void
+gfc_resolve_ibits (gfc_expr * f, gfc_expr * i,
+ gfc_expr * pos ATTRIBUTE_UNUSED,
+ gfc_expr * len ATTRIBUTE_UNUSED)
+{
+
+ f->ts = i->ts;
+ f->value.function.name = gfc_get_string ("__ibits_%d", i->ts.kind);
+}
+
+
+void
+gfc_resolve_ibset (gfc_expr * f, gfc_expr * i,
+ gfc_expr * pos ATTRIBUTE_UNUSED)
+{
+
+ f->ts = i->ts;
+ f->value.function.name = gfc_get_string ("__ibset_%d", i->ts.kind);
+}
+
+
+void
+gfc_resolve_ichar (gfc_expr * f, gfc_expr * c)
+{
+
+ f->ts.type = BT_INTEGER;
+ f->ts.kind = gfc_default_integer_kind ();
+
+ f->value.function.name = gfc_get_string ("__ichar_%d", c->ts.kind);
+}
+
+
+void
+gfc_resolve_idnint (gfc_expr * f, gfc_expr * a)
+{
+ gfc_resolve_nint (f, a, NULL);
+}
+
+
+void
+gfc_resolve_ieor (gfc_expr * f, gfc_expr * i,
+ gfc_expr * j ATTRIBUTE_UNUSED)
+{
+
+ f->ts = i->ts;
+ f->value.function.name = gfc_get_string ("__ieor_%d", i->ts.kind);
+}
+
+
+void
+gfc_resolve_ior (gfc_expr * f, gfc_expr * i,
+ gfc_expr * j ATTRIBUTE_UNUSED)
+{
+
+ f->ts = i->ts;
+ f->value.function.name = gfc_get_string ("__ior_%d", i->ts.kind);
+}
+
+
+void
+gfc_resolve_int (gfc_expr * f, gfc_expr * a, gfc_expr * kind)
+{
+
+ f->ts.type = BT_INTEGER;
+ f->ts.kind = (kind == NULL) ? gfc_default_integer_kind ()
+ : mpz_get_si (kind->value.integer);
+
+ f->value.function.name =
+ gfc_get_string ("__int_%d_%c%d", f->ts.kind, gfc_type_letter (a->ts.type),
+ a->ts.kind);
+}
+
+
+void
+gfc_resolve_ishft (gfc_expr * f, gfc_expr * i, gfc_expr * shift)
+{
+
+ f->ts = i->ts;
+ f->value.function.name =
+ gfc_get_string ("__ishft_%d_%d", i->ts.kind, shift->ts.kind);
+}
+
+
+void
+gfc_resolve_ishftc (gfc_expr * f, gfc_expr * i, gfc_expr * shift,
+ gfc_expr * size)
+{
+ int s_kind;
+
+ s_kind = (size == NULL) ? gfc_default_integer_kind () : shift->ts.kind;
+
+ f->ts = i->ts;
+ f->value.function.name =
+ gfc_get_string ("__ishftc_%d_%d_%d", i->ts.kind, shift->ts.kind, s_kind);
+}
+
+
+void
+gfc_resolve_lbound (gfc_expr * f, gfc_expr * array ATTRIBUTE_UNUSED,
+ gfc_expr * dim)
+{
+ static char lbound[] = "__lbound";
+
+ f->ts.type = BT_INTEGER;
+ f->ts.kind = gfc_default_integer_kind ();
+
+ f->rank = (dim == NULL) ? 1 : 0;
+ f->value.function.name = lbound;
+}
+
+
+void
+gfc_resolve_len (gfc_expr * f, gfc_expr * string)
+{
+
+ f->ts.type = BT_INTEGER;
+ f->ts.kind = gfc_default_integer_kind ();
+ f->value.function.name = gfc_get_string ("__len_%d", string->ts.kind);
+}
+
+
+void
+gfc_resolve_len_trim (gfc_expr * f, gfc_expr * string)
+{
+
+ f->ts.type = BT_INTEGER;
+ f->ts.kind = gfc_default_integer_kind ();
+ f->value.function.name = gfc_get_string ("__len_trim%d", string->ts.kind);
+}
+
+
+void
+gfc_resolve_log (gfc_expr * f, gfc_expr * x)
+{
+
+ f->ts = x->ts;
+ f->value.function.name =
+ gfc_get_string ("__log_%c%d", gfc_type_letter (x->ts.type), x->ts.kind);
+}
+
+
+void
+gfc_resolve_log10 (gfc_expr * f, gfc_expr * x)
+{
+
+ f->ts = x->ts;
+ f->value.function.name =
+ gfc_get_string ("__log10_%c%d", gfc_type_letter (x->ts.type), x->ts.kind);
+}
+
+
+void
+gfc_resolve_logical (gfc_expr * f, gfc_expr * a, gfc_expr * kind)
+{
+
+ f->ts.type = BT_LOGICAL;
+ f->ts.kind = (kind == NULL) ? gfc_default_logical_kind ()
+ : mpz_get_si (kind->value.integer);
+ f->rank = a->rank;
+
+ f->value.function.name =
+ gfc_get_string ("__logical_%d_%c%d", f->ts.kind,
+ gfc_type_letter (a->ts.type), a->ts.kind);
+}
+
+
+void
+gfc_resolve_matmul (gfc_expr * f, gfc_expr * a, gfc_expr * b)
+{
+ gfc_expr temp;
+
+ if (a->ts.type == BT_LOGICAL && b->ts.type == BT_LOGICAL)
+ {
+ f->ts.type = BT_LOGICAL;
+ f->ts.kind = gfc_default_logical_kind ();
+ }
+ else
+ {
+ temp.expr_type = EXPR_OP;
+ gfc_clear_ts (&temp.ts);
+ temp.operator = INTRINSIC_NONE;
+ temp.op1 = a;
+ temp.op2 = b;
+ gfc_type_convert_binary (&temp);
+ f->ts = temp.ts;
+ }
+
+ f->rank = (a->rank == 2 && b->rank == 2) ? 2 : 1;
+
+ f->value.function.name =
+ gfc_get_string ("__matmul_%c%d", gfc_type_letter (f->ts.type),
+ f->ts.kind);
+}
+
+
+static void
+gfc_resolve_minmax (const char * name, gfc_expr * f, gfc_actual_arglist * args)
+{
+ gfc_actual_arglist *a;
+
+ f->ts.type = args->expr->ts.type;
+ f->ts.kind = args->expr->ts.kind;
+ /* Find the largest type kind. */
+ for (a = args->next; a; a = a->next)
+ {
+ if (a->expr->ts.kind > f->ts.kind)
+ f->ts.kind = a->expr->ts.kind;
+ }
+
+ /* Convert all parameters to the required kind. */
+ for (a = args; a; a = a->next)
+ {
+ if (a->expr->ts.kind != f->ts.kind)
+ gfc_convert_type (a->expr, &f->ts, 2);
+ }
+
+ f->value.function.name =
+ gfc_get_string (name, gfc_type_letter (f->ts.type), f->ts.kind);
+}
+
+
+void
+gfc_resolve_max (gfc_expr * f, gfc_actual_arglist * args)
+{
+ gfc_resolve_minmax ("__max_%c%d", f, args);
+}
+
+
+void
+gfc_resolve_maxloc (gfc_expr * f, gfc_expr * array, gfc_expr * dim,
+ gfc_expr * mask)
+{
+ const char *name;
+
+ f->ts.type = BT_INTEGER;
+ f->ts.kind = gfc_default_integer_kind ();
+
+ if (dim == NULL)
+ f->rank = 1;
+ else
+ {
+ f->rank = array->rank - 1;
+ gfc_resolve_index (dim, 1);
+ }
+
+ name = mask ? "mmaxloc" : "maxloc";
+ f->value.function.name =
+ gfc_get_string ("__%s%d_%d_%c%d", name, dim != NULL, f->ts.kind,
+ gfc_type_letter (array->ts.type), array->ts.kind);
+}
+
+
+void
+gfc_resolve_maxval (gfc_expr * f, gfc_expr * array, gfc_expr * dim,
+ gfc_expr * mask)
+{
+
+ f->ts = array->ts;
+
+ if (dim != NULL)
+ {
+ f->rank = array->rank - 1;
+ gfc_resolve_index (dim, 1);
+ }
+
+ f->value.function.name =
+ gfc_get_string ("__%s_%c%d", mask ? "mmaxval" : "maxval",
+ gfc_type_letter (array->ts.type), array->ts.kind);
+}
+
+
+void
+gfc_resolve_merge (gfc_expr * f, gfc_expr * tsource,
+ gfc_expr * fsource ATTRIBUTE_UNUSED,
+ gfc_expr * mask ATTRIBUTE_UNUSED)
+{
+
+ f->ts = tsource->ts;
+ f->value.function.name =
+ gfc_get_string ("__merge_%c%d", gfc_type_letter (tsource->ts.type),
+ tsource->ts.kind);
+}
+
+
+void
+gfc_resolve_min (gfc_expr * f, gfc_actual_arglist * args)
+{
+ gfc_resolve_minmax ("__min_%c%d", f, args);
+}
+
+
+void
+gfc_resolve_minloc (gfc_expr * f, gfc_expr * array, gfc_expr * dim,
+ gfc_expr * mask)
+{
+ const char *name;
+
+ f->ts.type = BT_INTEGER;
+ f->ts.kind = gfc_default_integer_kind ();
+
+ if (dim == NULL)
+ f->rank = 1;
+ else
+ {
+ f->rank = array->rank - 1;
+ gfc_resolve_index (dim, 1);
+ }
+
+ name = mask ? "mminloc" : "minloc";
+ f->value.function.name =
+ gfc_get_string ("__%s%d_%d_%c%d", name, dim != NULL, f->ts.kind,
+ gfc_type_letter (array->ts.type), array->ts.kind);
+}
+
+void
+gfc_resolve_minval (gfc_expr * f, gfc_expr * array, gfc_expr * dim,
+ gfc_expr * mask)
+{
+
+ f->ts = array->ts;
+
+ if (dim != NULL)
+ {
+ f->rank = array->rank - 1;
+ gfc_resolve_index (dim, 1);
+ }
+
+ f->value.function.name =
+ gfc_get_string ("__%s_%c%d", mask ? "mminval" : "minval",
+ gfc_type_letter (array->ts.type), array->ts.kind);
+}
+
+
+void
+gfc_resolve_mod (gfc_expr * f, gfc_expr * a,
+ gfc_expr * p ATTRIBUTE_UNUSED)
+{
+
+ f->ts = a->ts;
+ f->value.function.name =
+ gfc_get_string ("__mod_%c%d", gfc_type_letter (a->ts.type), a->ts.kind);
+}
+
+
+void
+gfc_resolve_modulo (gfc_expr * f, gfc_expr * a,
+ gfc_expr * p ATTRIBUTE_UNUSED)
+{
+
+ f->ts = a->ts;
+ f->value.function.name =
+ gfc_get_string ("__modulo_%c%d", gfc_type_letter (a->ts.type),
+ a->ts.kind);
+}
+
+void
+gfc_resolve_nearest (gfc_expr * f, gfc_expr * a,
+ gfc_expr *p ATTRIBUTE_UNUSED)
+{
+
+ f->ts = a->ts;
+ f->value.function.name =
+ gfc_get_string ("__nearest_%c%d", gfc_type_letter (a->ts.type),
+ a->ts.kind);
+}
+
+void
+gfc_resolve_nint (gfc_expr * f, gfc_expr * a, gfc_expr * kind)
+{
+
+ f->ts.type = BT_INTEGER;
+ f->ts.kind = (kind == NULL) ? gfc_default_integer_kind ()
+ : mpz_get_si (kind->value.integer);
+
+ f->value.function.name =
+ gfc_get_string ("__nint_%d_%d", f->ts.kind, a->ts.kind);
+}
+
+
+void
+gfc_resolve_not (gfc_expr * f, gfc_expr * i)
+{
+
+ f->ts = i->ts;
+ f->value.function.name = gfc_get_string ("__not_%d", i->ts.kind);
+}
+
+
+void
+gfc_resolve_pack (gfc_expr * f,
+ gfc_expr * array ATTRIBUTE_UNUSED,
+ gfc_expr * mask ATTRIBUTE_UNUSED,
+ gfc_expr * vector ATTRIBUTE_UNUSED)
+{
+ static char pack[] = "__pack";
+
+ f->ts = array->ts;
+ f->rank = 1;
+
+ f->value.function.name = pack;
+}
+
+
+void
+gfc_resolve_product (gfc_expr * f, gfc_expr * array, gfc_expr * dim,
+ gfc_expr * mask)
+{
+
+ f->ts = array->ts;
+
+ if (dim != NULL)
+ {
+ f->rank = array->rank - 1;
+ gfc_resolve_index (dim, 1);
+ }
+
+ f->value.function.name =
+ gfc_get_string ("__%s_%c%d", mask ? "mproduct" : "product",
+ gfc_type_letter (array->ts.type), array->ts.kind);
+}
+
+
+void
+gfc_resolve_real (gfc_expr * f, gfc_expr * a, gfc_expr * kind)
+{
+
+ f->ts.type = BT_REAL;
+
+ if (kind != NULL)
+ f->ts.kind = mpz_get_si (kind->value.integer);
+ else
+ f->ts.kind = (a->ts.type == BT_COMPLEX) ?
+ a->ts.kind : gfc_default_real_kind ();
+
+ f->value.function.name =
+ gfc_get_string ("__real_%d_%c%d", f->ts.kind,
+ gfc_type_letter (a->ts.type), a->ts.kind);
+}
+
+
+void
+gfc_resolve_repeat (gfc_expr * f, gfc_expr * string,
+ gfc_expr * ncopies ATTRIBUTE_UNUSED)
+{
+
+ f->ts.type = BT_CHARACTER;
+ f->ts.kind = string->ts.kind;
+ f->value.function.name = gfc_get_string ("__repeat_%d", string->ts.kind);
+}
+
+
+void
+gfc_resolve_reshape (gfc_expr * f, gfc_expr * source, gfc_expr * shape,
+ gfc_expr * pad ATTRIBUTE_UNUSED,
+ gfc_expr * order ATTRIBUTE_UNUSED)
+{
+ static char reshape0[] = "__reshape";
+ mpz_t rank;
+ int kind;
+ int i;
+
+ f->ts = source->ts;
+
+ gfc_array_size (shape, &rank);
+ f->rank = mpz_get_si (rank);
+ mpz_clear (rank);
+ switch (source->ts.type)
+ {
+ case BT_COMPLEX:
+ kind = source->ts.kind * 2;
+ break;
+
+ case BT_REAL:
+ case BT_INTEGER:
+ case BT_LOGICAL:
+ kind = source->ts.kind;
+ break;
+
+ default:
+ kind = 0;
+ break;
+ }
+
+ switch (kind)
+ {
+ case 4:
+ case 8:
+ /* case 16: */
+ f->value.function.name =
+ gfc_get_string ("__reshape_%d", source->ts.kind);
+ break;
+
+ default:
+ f->value.function.name = reshape0;
+ break;
+ }
+
+ /* TODO: Make this work with a constant ORDER parameter. */
+ if (shape->expr_type == EXPR_ARRAY
+ && gfc_is_constant_expr (shape)
+ && order == NULL)
+ {
+ gfc_constructor *c;
+ f->shape = gfc_get_shape (f->rank);
+ c = shape->value.constructor;
+ for (i = 0; i < f->rank; i++)
+ {
+ mpz_init_set (f->shape[i], c->expr->value.integer);
+ c = c->next;
+ }
+ }
+}
+
+
+void
+gfc_resolve_rrspacing (gfc_expr * f, gfc_expr * x)
+{
+
+ f->ts = x->ts;
+ f->value.function.name = gfc_get_string ("__rrspacing_%d", x->ts.kind);
+}
+
+
+void
+gfc_resolve_scale (gfc_expr * f, gfc_expr * x,
+ gfc_expr * y ATTRIBUTE_UNUSED)
+{
+
+ f->ts = x->ts;
+ f->value.function.name = gfc_get_string ("__scale_%d_%d", x->ts.kind,
+ x->ts.kind);
+}
+
+
+void
+gfc_resolve_scan (gfc_expr * f, gfc_expr * string,
+ gfc_expr * set ATTRIBUTE_UNUSED,
+ gfc_expr * back ATTRIBUTE_UNUSED)
+{
+
+ f->ts.type = BT_INTEGER;
+ f->ts.kind = gfc_default_integer_kind ();
+ f->value.function.name = gfc_get_string ("__scan_%d", string->ts.kind);
+}
+
+
+void
+gfc_resolve_set_exponent (gfc_expr * f, gfc_expr * x, gfc_expr * i)
+{
+
+ f->ts = x->ts;
+ f->value.function.name =
+ gfc_get_string ("__set_exponent_%d_%d", x->ts.kind, i->ts.kind);
+}
+
+
+void
+gfc_resolve_shape (gfc_expr * f, gfc_expr * array)
+{
+
+ f->ts.type = BT_INTEGER;
+ f->ts.kind = gfc_default_integer_kind ();
+ f->rank = 1;
+ f->value.function.name = gfc_get_string ("__shape_%d", f->ts.kind);
+ f->shape = gfc_get_shape (1);
+ mpz_init_set_ui (f->shape[0], array->rank);
+}
+
+
+void
+gfc_resolve_sign (gfc_expr * f, gfc_expr * a, gfc_expr * b ATTRIBUTE_UNUSED)
+{
+
+ f->ts = a->ts;
+ f->value.function.name =
+ gfc_get_string ("__sign_%c%d", gfc_type_letter (a->ts.type), a->ts.kind);
+}
+
+
+void
+gfc_resolve_sin (gfc_expr * f, gfc_expr * x)
+{
+
+ f->ts = x->ts;
+ f->value.function.name =
+ gfc_get_string ("__sin_%c%d", gfc_type_letter (x->ts.type), x->ts.kind);
+}
+
+
+void
+gfc_resolve_sinh (gfc_expr * f, gfc_expr * x)
+{
+
+ f->ts = x->ts;
+ f->value.function.name =
+ gfc_get_string ("__sinh_%c%d", gfc_type_letter (x->ts.type), x->ts.kind);
+}
+
+
+void
+gfc_resolve_spacing (gfc_expr * f, gfc_expr * x)
+{
+
+ f->ts = x->ts;
+ f->value.function.name = gfc_get_string ("__spacing_%d", x->ts.kind);
+}
+
+
+void
+gfc_resolve_spread (gfc_expr * f, gfc_expr * source,
+ gfc_expr * dim,
+ gfc_expr * ncopies)
+{
+ static char spread[] = "__spread";
+
+ f->ts = source->ts;
+ f->rank = source->rank + 1;
+ f->value.function.name = spread;
+
+ gfc_resolve_index (dim, 1);
+ gfc_resolve_index (ncopies, 1);
+}
+
+
+void
+gfc_resolve_sqrt (gfc_expr * f, gfc_expr * x)
+{
+
+ f->ts = x->ts;
+ f->value.function.name =
+ gfc_get_string ("__sqrt_%c%d", gfc_type_letter (x->ts.type), x->ts.kind);
+}
+
+
+void
+gfc_resolve_sum (gfc_expr * f, gfc_expr * array, gfc_expr * dim,
+ gfc_expr * mask)
+{
+
+ f->ts = array->ts;
+
+ if (dim != NULL)
+ {
+ f->rank = array->rank - 1;
+ gfc_resolve_index (dim, 1);
+ }
+
+ f->value.function.name =
+ gfc_get_string ("__%s_%c%d", mask ? "msum" : "sum",
+ gfc_type_letter (array->ts.type), array->ts.kind);
+}
+
+
+void
+gfc_resolve_tan (gfc_expr * f, gfc_expr * x)
+{
+
+ f->ts = x->ts;
+ f->value.function.name =
+ gfc_get_string ("__tan_%c%d", gfc_type_letter (x->ts.type), x->ts.kind);
+}
+
+
+void
+gfc_resolve_tanh (gfc_expr * f, gfc_expr * x)
+{
+
+ f->ts = x->ts;
+ f->value.function.name =
+ gfc_get_string ("__tanh_%c%d", gfc_type_letter (x->ts.type), x->ts.kind);
+}
+
+
+void
+gfc_resolve_transfer (gfc_expr * f, gfc_expr * source ATTRIBUTE_UNUSED,
+ gfc_expr * mold, gfc_expr * size)
+{
+ /* TODO: Make this do something meaningful. */
+ static char transfer0[] = "__transfer0", transfer1[] = "__transfer1";
+
+ f->ts = mold->ts;
+
+ if (size == NULL && mold->rank == 0)
+ {
+ f->rank = 0;
+ f->value.function.name = transfer0;
+ }
+ else
+ {
+ f->rank = 1;
+ f->value.function.name = transfer1;
+ }
+}
+
+
+void
+gfc_resolve_transpose (gfc_expr * f, gfc_expr * matrix)
+{
+ static char transpose0[] = "__transpose";
+ int kind;
+
+ f->ts = matrix->ts;
+ f->rank = 2;
+
+ switch (matrix->ts.type)
+ {
+ case BT_COMPLEX:
+ kind = matrix->ts.kind * 2;
+ break;
+
+ case BT_REAL:
+ case BT_INTEGER:
+ case BT_LOGICAL:
+ kind = matrix->ts.kind;
+ break;
+
+ default:
+ kind = 0;
+ break;
+
+ }
+
+ switch (kind)
+ {
+ case 4:
+ case 8:
+ /* case 16: */
+ f->value.function.name =
+ gfc_get_string ("__transpose_%d", kind);
+ break;
+
+ default:
+ f->value.function.name = transpose0;
+ }
+}
+
+
+void
+gfc_resolve_trim (gfc_expr * f, gfc_expr * string)
+{
+
+ f->ts.type = BT_CHARACTER;
+ f->ts.kind = string->ts.kind;
+ f->value.function.name = gfc_get_string ("__trim_%d", string->ts.kind);
+}
+
+
+void
+gfc_resolve_ubound (gfc_expr * f, gfc_expr * array ATTRIBUTE_UNUSED,
+ gfc_expr * dim)
+{
+ static char ubound[] = "__ubound";
+
+ f->ts.type = BT_INTEGER;
+ f->ts.kind = gfc_default_integer_kind ();
+
+ f->rank = (dim == NULL) ? 1 : 0;
+ f->value.function.name = ubound;
+}
+
+
+void
+gfc_resolve_unpack (gfc_expr * f, gfc_expr * vector, gfc_expr * mask,
+ gfc_expr * field ATTRIBUTE_UNUSED)
+{
+
+ f->ts.type = vector->ts.type;
+ f->ts.kind = vector->ts.kind;
+ f->rank = mask->rank;
+
+ f->value.function.name =
+ gfc_get_string ("__unpack%d", field->rank > 0 ? 1 : 0);
+}
+
+
+void
+gfc_resolve_verify (gfc_expr * f, gfc_expr * string,
+ gfc_expr * set ATTRIBUTE_UNUSED,
+ gfc_expr * back ATTRIBUTE_UNUSED)
+{
+
+ f->ts.type = BT_INTEGER;
+ f->ts.kind = gfc_default_integer_kind ();
+ f->value.function.name = gfc_get_string ("__verify_%d", string->ts.kind);
+}
+
+
+/* Intrinsic subroutine resolution. */
+
+void
+gfc_resolve_cpu_time (gfc_code * c ATTRIBUTE_UNUSED)
+{
+ const char *name;
+
+ name = gfc_get_string (PREFIX("cpu_time_%d"),
+ c->ext.actual->expr->ts.kind);
+ c->resolved_sym = gfc_get_intrinsic_sub_symbol (name);
+}
+
+
+void
+gfc_resolve_random_number (gfc_code * c ATTRIBUTE_UNUSED)
+{
+ const char *name;
+ int kind;
+
+ kind = c->ext.actual->expr->ts.kind;
+ name = gfc_get_string ((c->ext.actual->expr->rank == 0) ?
+ PREFIX("random_r%d") : PREFIX("arandom_r%d"),
+ kind);
+ c->resolved_sym = gfc_get_intrinsic_sub_symbol (name);
+}
+
+
+void
+gfc_iresolve_init_1 (void)
+{
+ int i;
+
+ for (i = 0; i < HASH_SIZE; i++)
+ string_head[i] = NULL;
+}
+
+
+void
+gfc_iresolve_done_1 (void)
+{
+
+ free_strings ();
+}
diff --git a/gcc/fortran/lang-specs.h b/gcc/fortran/lang-specs.h
new file mode 100644
index 00000000000..f1828e2ad19
--- /dev/null
+++ b/gcc/fortran/lang-specs.h
@@ -0,0 +1,35 @@
+/* Contribution to the specs for the GNU Compiler Collection
+ from GNU Fortran 95 compiler.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+
+This file is licensed under the GPL. */
+
+/* This is the contribution to the `default_compilers' array in gcc.c
+ for the f95 language. */
+
+{".F", "@f77-cpp-input", 0},
+{".fpp", "@f77-cpp-input", 0},
+{".FPP", "@f77-cpp-input", 0},
+{"@f77-cpp-input",
+ "cc1 -P -E -traditional-cpp -D_LANGUAGE_FORTRAN %(cpp_options) \
+ %{E|M|MM:%(cpp_debug_options)}\
+ %{!M:%{!MM:%{!E: -o %|.f |\n\
+ f951 %|.f %{!ffree-form:-ffixed-form} %(cc1_options) %{J*} %{I*}\
+ %{!fsyntax-only:%(invoke_as)}}}}", 0},
+{".F90", "@f95-cpp-input", 0},
+{".F95", "@f95-cpp-input", 0},
+{"@f95-cpp-input",
+ "cc1 -P -E -traditional-cpp -D_LANGUAGE_FORTRAN %(cpp_options) \
+ %{E|M|MM:%(cpp_debug_options)}\
+ %{!M:%{!MM:%{!E: -o %|.f95 |\n\
+ f951 %|.f95 %(cc1_options) %{J*} %{I*}\
+ %{!fsyntax-only:%(invoke_as)}}}}", 0},
+{".f90", "@f95", 0},
+{".f95", "@f95", 0},
+{"@f95", "%{!E:f951 %i %(cc1_options) %{J*} %{I*}\
+ %{!fsyntax-only:%(invoke_as)}}", 0},
+{".f", "@f77", 0},
+{".for", "@f77", 0},
+{".FOR", "@f77", 0},
+{"@f77", "%{!E:f951 %i %{!ffree-form:-ffixed-form} %(cc1_options) %{J*} %{I*}\
+ %{!fsyntax-only:%(invoke_as)}}", 0},
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
new file mode 100644
index 00000000000..08065c474b9
--- /dev/null
+++ b/gcc/fortran/lang.opt
@@ -0,0 +1,152 @@
+; Options for the Fortran 95 front end.
+; Copyright (C) 2003, 2004 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 2, or (at your option) any later
+; version.
+;
+; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+; WARRANTY; without even the implied warranty of MERCHANTABILITY or
+; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+; for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with GCC; see the file COPYING. If not, write to the Free
+; Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+; 02111-1307, USA.
+
+; See c.opt for a description of this file's format.
+
+; Please try to keep this file in ASCII collating order.
+
+Language
+F95
+
+I
+F95 Joined
+-I<directory> Add a directory for INCLUDE and MODULE searching
+
+J
+F95 Joined
+-J<directory> Put MODULE files in 'directory'
+
+Wall
+F95 RejectNegative
+; Documented in C
+
+Waliasing
+F95
+Warn about possible aliasing of dummy arguments
+
+Wconversion
+F95
+Warn about implicit conversion
+
+Wimplicit-interface
+F95
+Warn about calls with implicit interface
+
+Wline-truncation
+F95
+Warn about truncated source lines
+
+Wsurprising
+F95
+Warn about \"suspicious\" constructs
+
+Wunused-labels
+F95
+Warn when a label is unused
+
+d8
+F95 RejectNegative
+Set the default real and integer kinds to double precision
+
+fdollar-ok
+F95
+Allow dollar signs in entity names
+
+fdump-parse-tree
+F95
+Display the code tree after parsing.
+
+ffixed-form
+F95
+Assume that the source file is fixed form
+
+ffree-form
+F95
+Assume that the source file is free form
+
+funderscoring
+F95
+Append underscores to externally visible names
+
+fsecond-underscore
+F95
+Append a second underscore if the name already contains an underscore
+
+fimplicit-none
+F95
+Specify that no implicit typing is allowed, unless overridden by explicit IMPLICIT statements
+
+ffixed-line-length-80
+F95 RejectNegative
+Use 80 character line width in fixed mode
+
+ffixed-line-length-132
+F95 RejectNegative
+Use 132 character line width in fixed mode
+
+fmax-identifier-length=
+F95 RejectNegative Joined UInteger
+-fmax-identifier-length=<n> Maximum identifier length.
+
+fmax-stack-var-size=
+F95 RejectNegative Joined UInteger
+-fmax-stack-var-size=<n> Size in bytes of the largest array that will be put on the stack
+
+fmodule-private
+F95
+Set default accessibility of module entities to PRIVATE
+
+fno-backend
+F95 RejectNegative
+Don't generate code, just do syntax and semantics checking
+
+fpack-derived
+F95
+Try to layout derived types as compact as possible
+
+frepack-arrays
+F95
+Copy array sections into a contiguous block on procedure entry
+
+i8
+F95
+Set the default integer kind to double precision
+
+qkind=
+F95 RejectNegative Joined UInteger
+-qkind=<n> Set the kind for a real with the 'q' exponent to 'n'
+
+r8
+F95
+Set the default real kind to double precision
+
+std=f95
+F95
+Conform to the ISO Fortran 95 standard.
+
+std=f2003
+F95
+Conform to the ISO Fortran 2003 standard.
+
+std=gnu
+F95
+Conform nothing in particular.
+
+; This comment is to ensure we retain the blank line above.
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
new file mode 100644
index 00000000000..c13e0579585
--- /dev/null
+++ b/gcc/fortran/match.c
@@ -0,0 +1,3550 @@
+/* Matching subroutines in all sizes, shapes and colors.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation,
+ Inc.
+ Contributed by Andy Vaught
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#include "config.h"
+#include "system.h"
+#include "flags.h"
+
+#include <stdarg.h>
+#include <string.h>
+
+#include "gfortran.h"
+#include "match.h"
+#include "parse.h"
+
+/* For matching and debugging purposes. Order matters here! The
+ unary operators /must/ precede the binary plus and minus, or
+ the expression parser breaks. */
+
+mstring intrinsic_operators[] = {
+ minit ("+", INTRINSIC_UPLUS),
+ minit ("-", INTRINSIC_UMINUS),
+ minit ("+", INTRINSIC_PLUS),
+ minit ("-", INTRINSIC_MINUS),
+ minit ("**", INTRINSIC_POWER),
+ minit ("//", INTRINSIC_CONCAT),
+ minit ("*", INTRINSIC_TIMES),
+ minit ("/", INTRINSIC_DIVIDE),
+ minit (".and.", INTRINSIC_AND),
+ minit (".or.", INTRINSIC_OR),
+ minit (".eqv.", INTRINSIC_EQV),
+ minit (".neqv.", INTRINSIC_NEQV),
+ minit (".eq.", INTRINSIC_EQ),
+ minit ("==", INTRINSIC_EQ),
+ minit (".ne.", INTRINSIC_NE),
+ minit ("/=", INTRINSIC_NE),
+ minit (".ge.", INTRINSIC_GE),
+ minit (">=", INTRINSIC_GE),
+ minit (".le.", INTRINSIC_LE),
+ minit ("<=", INTRINSIC_LE),
+ minit (".lt.", INTRINSIC_LT),
+ minit ("<", INTRINSIC_LT),
+ minit (".gt.", INTRINSIC_GT),
+ minit (">", INTRINSIC_GT),
+ minit (".not.", INTRINSIC_NOT),
+ minit (NULL, INTRINSIC_NONE)
+};
+
+
+/******************** Generic matching subroutines ************************/
+
+/* In free form, match at least one space. Always matches in fixed
+ form. */
+
+match
+gfc_match_space (void)
+{
+ locus old_loc;
+ int c;
+
+ if (gfc_current_file->form == FORM_FIXED)
+ return MATCH_YES;
+
+ old_loc = *gfc_current_locus ();
+
+ c = gfc_next_char ();
+ if (!gfc_is_whitespace (c))
+ {
+ gfc_set_locus (&old_loc);
+ return MATCH_NO;
+ }
+
+ gfc_gobble_whitespace ();
+
+ return MATCH_YES;
+}
+
+
+/* Match an end of statement. End of statement is optional
+ whitespace, followed by a ';' or '\n' or comment '!'. If a
+ semicolon is found, we continue to eat whitespace and semicolons. */
+
+match
+gfc_match_eos (void)
+{
+ locus old_loc;
+ int flag, c;
+
+ flag = 0;
+
+ for (;;)
+ {
+ old_loc = *gfc_current_locus ();
+ gfc_gobble_whitespace ();
+
+ c = gfc_next_char ();
+ switch (c)
+ {
+ case '!':
+ do
+ {
+ c = gfc_next_char ();
+ }
+ while (c != '\n');
+
+ /* Fall through */
+
+ case '\n':
+ return MATCH_YES;
+
+ case ';':
+ flag = 1;
+ continue;
+ }
+
+ break;
+ }
+
+ gfc_set_locus (&old_loc);
+ return (flag) ? MATCH_YES : MATCH_NO;
+}
+
+
+/* Match a literal integer on the input, setting the value on
+ MATCH_YES. Literal ints occur in kind-parameters as well as
+ old-style character length specifications. */
+
+match
+gfc_match_small_literal_int (int *value)
+{
+ locus old_loc;
+ char c;
+ int i;
+
+ old_loc = *gfc_current_locus ();
+
+ gfc_gobble_whitespace ();
+ c = gfc_next_char ();
+
+ if (!ISDIGIT (c))
+ {
+ gfc_set_locus (&old_loc);
+ return MATCH_NO;
+ }
+
+ i = c - '0';
+
+ for (;;)
+ {
+ old_loc = *gfc_current_locus ();
+ c = gfc_next_char ();
+
+ if (!ISDIGIT (c))
+ break;
+
+ i = 10 * i + c - '0';
+
+ if (i > 99999999)
+ {
+ gfc_error ("Integer too large at %C");
+ return MATCH_ERROR;
+ }
+ }
+
+ gfc_set_locus (&old_loc);
+
+ *value = i;
+ return MATCH_YES;
+}
+
+
+/* Match a small, constant integer expression, like in a kind
+ statement. On MATCH_YES, 'value' is set. */
+
+match
+gfc_match_small_int (int *value)
+{
+ gfc_expr *expr;
+ const char *p;
+ match m;
+ int i;
+
+ m = gfc_match_expr (&expr);
+ if (m != MATCH_YES)
+ return m;
+
+ p = gfc_extract_int (expr, &i);
+ gfc_free_expr (expr);
+
+ if (p != NULL)
+ {
+ gfc_error (p);
+ m = MATCH_ERROR;
+ }
+
+ *value = i;
+ return m;
+}
+
+
+/* Matches a statement label. Uses gfc_match_small_literal_int() to
+ do most of the work. */
+
+match
+gfc_match_st_label (gfc_st_label ** label, int allow_zero)
+{
+ locus old_loc;
+ match m;
+ int i;
+
+ old_loc = *gfc_current_locus ();
+
+ m = gfc_match_small_literal_int (&i);
+ if (m != MATCH_YES)
+ return m;
+
+ if (((i == 0) && allow_zero) || i <= 99999)
+ {
+ *label = gfc_get_st_label (i);
+ return MATCH_YES;
+ }
+
+ gfc_error ("Statement label at %C is out of range");
+ gfc_set_locus (&old_loc);
+ return MATCH_ERROR;
+}
+
+
+/* Match and validate a label associated with a named IF, DO or SELECT
+ statement. If the symbol does not have the label attribute, we add
+ it. We also make sure the symbol does not refer to another
+ (active) block. A matched label is pointed to by gfc_new_block. */
+
+match
+gfc_match_label (void)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_state_data *p;
+ match m;
+
+ gfc_new_block = NULL;
+
+ m = gfc_match (" %n :", name);
+ if (m != MATCH_YES)
+ return m;
+
+ if (gfc_get_symbol (name, NULL, &gfc_new_block))
+ {
+ gfc_error ("Label name '%s' at %C is ambiguous", name);
+ return MATCH_ERROR;
+ }
+
+ if (gfc_new_block->attr.flavor != FL_LABEL
+ && gfc_add_flavor (&gfc_new_block->attr, FL_LABEL, NULL) == FAILURE)
+ return MATCH_ERROR;
+
+ for (p = gfc_state_stack; p; p = p->previous)
+ if (p->sym == gfc_new_block)
+ {
+ gfc_error ("Label %s at %C already in use by a parent block",
+ gfc_new_block->name);
+ return MATCH_ERROR;
+ }
+
+ return MATCH_YES;
+}
+
+
+/* Try and match the input against an array of possibilities. If one
+ potential matching string is a substring of another, the longest
+ match takes precedence. Spaces in the target strings are optional
+ spaces that do not necessarily have to be found in the input
+ stream. In fixed mode, spaces never appear. If whitespace is
+ matched, it matches unlimited whitespace in the input. For this
+ reason, the 'mp' member of the mstring structure is used to track
+ the progress of each potential match.
+
+ If there is no match we return the tag associated with the
+ terminating NULL mstring structure and leave the locus pointer
+ where it started. If there is a match we return the tag member of
+ the matched mstring and leave the locus pointer after the matched
+ character.
+
+ A '%' character is a mandatory space. */
+
+int
+gfc_match_strings (mstring * a)
+{
+ mstring *p, *best_match;
+ int no_match, c, possibles;
+ locus match_loc;
+
+ possibles = 0;
+
+ for (p = a; p->string != NULL; p++)
+ {
+ p->mp = p->string;
+ possibles++;
+ }
+
+ no_match = p->tag;
+
+ best_match = NULL;
+ match_loc = *gfc_current_locus ();
+
+ gfc_gobble_whitespace ();
+
+ while (possibles > 0)
+ {
+ c = gfc_next_char ();
+
+ /* Apply the next character to the current possibilities. */
+ for (p = a; p->string != NULL; p++)
+ {
+ if (p->mp == NULL)
+ continue;
+
+ if (*p->mp == ' ')
+ {
+ /* Space matches 1+ whitespace(s). */
+ if ((gfc_current_file->form == FORM_FREE)
+ && gfc_is_whitespace (c))
+ continue;
+
+ p->mp++;
+ }
+
+ if (*p->mp != c)
+ {
+ /* Match failed. */
+ p->mp = NULL;
+ possibles--;
+ continue;
+ }
+
+ p->mp++;
+ if (*p->mp == '\0')
+ {
+ /* Found a match. */
+ match_loc = *gfc_current_locus ();
+ best_match = p;
+ possibles--;
+ p->mp = NULL;
+ }
+ }
+ }
+
+ gfc_set_locus (&match_loc);
+
+ return (best_match == NULL) ? no_match : best_match->tag;
+}
+
+
+/* See if the current input looks like a name of some sort. Modifies
+ the passed buffer which must be GFC_MAX_SYMBOL_LEN+1 bytes long. */
+
+match
+gfc_match_name (char *buffer)
+{
+ locus old_loc;
+ int i, c;
+
+ old_loc = *gfc_current_locus ();
+ gfc_gobble_whitespace ();
+
+ c = gfc_next_char ();
+ if (!ISALPHA (c))
+ {
+ gfc_set_locus (&old_loc);
+ return MATCH_NO;
+ }
+
+ i = 0;
+
+ do
+ {
+ buffer[i++] = c;
+
+ if (i > gfc_option.max_identifier_length)
+ {
+ gfc_error ("Name at %C is too long");
+ return MATCH_ERROR;
+ }
+
+ old_loc = *gfc_current_locus ();
+ c = gfc_next_char ();
+ }
+ while (ISALNUM (c)
+ || c == '_'
+ || (gfc_option.flag_dollar_ok && c == '$'));
+
+ buffer[i] = '\0';
+ gfc_set_locus (&old_loc);
+
+ return MATCH_YES;
+}
+
+
+/* Match a symbol on the input. Modifies the pointer to the symbol
+ pointer if successful. */
+
+match
+gfc_match_sym_tree (gfc_symtree ** matched_symbol, int host_assoc)
+{
+ char buffer[GFC_MAX_SYMBOL_LEN + 1];
+ match m;
+
+ m = gfc_match_name (buffer);
+ if (m != MATCH_YES)
+ return m;
+
+ if (host_assoc)
+ return (gfc_get_ha_sym_tree (buffer, matched_symbol))
+ ? MATCH_ERROR : MATCH_YES;
+
+ if (gfc_get_sym_tree (buffer, NULL, matched_symbol))
+ return MATCH_ERROR;
+
+ return MATCH_YES;
+}
+
+
+match
+gfc_match_symbol (gfc_symbol ** matched_symbol, int host_assoc)
+{
+ gfc_symtree *st;
+ match m;
+
+ m = gfc_match_sym_tree (&st, host_assoc);
+
+ if (m == MATCH_YES)
+ {
+ if (st)
+ *matched_symbol = st->n.sym;
+ else
+ *matched_symbol = NULL;
+ }
+ return m;
+}
+
+/* Match an intrinsic operator. Returns an INTRINSIC enum. While matching,
+ we always find INTRINSIC_PLUS before INTRINSIC_UPLUS. We work around this
+ in matchexp.c. */
+
+match
+gfc_match_intrinsic_op (gfc_intrinsic_op * result)
+{
+ gfc_intrinsic_op op;
+
+ op = (gfc_intrinsic_op) gfc_match_strings (intrinsic_operators);
+
+ if (op == INTRINSIC_NONE)
+ return MATCH_NO;
+
+ *result = op;
+ return MATCH_YES;
+}
+
+
+/* Match a loop control phrase:
+
+ <LVALUE> = <EXPR>, <EXPR> [, <EXPR> ]
+
+ If the final integer expression is not present, a constant unity
+ expression is returned. We don't return MATCH_ERROR until after
+ the equals sign is seen. */
+
+match
+gfc_match_iterator (gfc_iterator * iter, int init_flag)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_expr *var, *e1, *e2, *e3;
+ locus start;
+ match m;
+
+ /* Match the start of an iterator without affecting the symbol
+ table. */
+
+ start = *gfc_current_locus ();
+ m = gfc_match (" %n =", name);
+ gfc_set_locus (&start);
+
+ if (m != MATCH_YES)
+ return MATCH_NO;
+
+ m = gfc_match_variable (&var, 0);
+ if (m != MATCH_YES)
+ return MATCH_NO;
+
+ gfc_match_char ('=');
+
+ e1 = e2 = e3 = NULL;
+
+ if (var->ref != NULL)
+ {
+ gfc_error ("Loop variable at %C cannot be a sub-component");
+ goto cleanup;
+ }
+
+ if (var->symtree->n.sym->attr.intent == INTENT_IN)
+ {
+ gfc_error ("Loop variable '%s' at %C cannot be INTENT(IN)",
+ var->symtree->n.sym->name);
+ goto cleanup;
+ }
+
+ if (var->symtree->n.sym->attr.pointer)
+ {
+ gfc_error ("Loop variable at %C cannot have the POINTER attribute");
+ goto cleanup;
+ }
+
+ m = init_flag ? gfc_match_init_expr (&e1) : gfc_match_expr (&e1);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ if (gfc_match_char (',') != MATCH_YES)
+ goto syntax;
+
+ m = init_flag ? gfc_match_init_expr (&e2) : gfc_match_expr (&e2);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ if (gfc_match_char (',') != MATCH_YES)
+ {
+ e3 = gfc_int_expr (1);
+ goto done;
+ }
+
+ m = init_flag ? gfc_match_init_expr (&e3) : gfc_match_expr (&e3);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ {
+ gfc_error ("Expected a step value in iterator at %C");
+ goto cleanup;
+ }
+
+done:
+ iter->var = var;
+ iter->start = e1;
+ iter->end = e2;
+ iter->step = e3;
+ return MATCH_YES;
+
+syntax:
+ gfc_error ("Syntax error in iterator at %C");
+
+cleanup:
+ gfc_free_expr (e1);
+ gfc_free_expr (e2);
+ gfc_free_expr (e3);
+
+ return MATCH_ERROR;
+}
+
+
+/* Tries to match the next non-whitespace character on the input.
+ This subroutine does not return MATCH_ERROR. */
+
+match
+gfc_match_char (char c)
+{
+ locus where;
+
+ where = *gfc_current_locus ();
+ gfc_gobble_whitespace ();
+
+ if (gfc_next_char () == c)
+ return MATCH_YES;
+
+ gfc_set_locus (&where);
+ return MATCH_NO;
+}
+
+
+/* General purpose matching subroutine. The target string is a
+ scanf-like format string in which spaces correspond to arbitrary
+ whitespace (including no whitespace), characters correspond to
+ themselves. The %-codes are:
+
+ %% Literal percent sign
+ %e Expression, pointer to a pointer is set
+ %s Symbol, pointer to the symbol is set
+ %n Name, character buffer is set to name
+ %t Matches end of statement.
+ %o Matches an intrinsic operator, returned as an INTRINSIC enum.
+ %l Matches a statement label
+ %v Matches a variable expression (an lvalue)
+ % Matches a required space (in free form) and optional spaces. */
+
+match
+gfc_match (const char *target, ...)
+{
+ gfc_st_label **label;
+ int matches, *ip;
+ locus old_loc;
+ va_list argp;
+ char c, *np;
+ match m, n;
+ void **vp;
+ const char *p;
+
+ old_loc = *gfc_current_locus ();
+ va_start (argp, target);
+ m = MATCH_NO;
+ matches = 0;
+ p = target;
+
+loop:
+ c = *p++;
+ switch (c)
+ {
+ case ' ':
+ gfc_gobble_whitespace ();
+ goto loop;
+ case '\0':
+ m = MATCH_YES;
+ break;
+
+ case '%':
+ c = *p++;
+ switch (c)
+ {
+ case 'e':
+ vp = va_arg (argp, void **);
+ n = gfc_match_expr ((gfc_expr **) vp);
+ if (n != MATCH_YES)
+ {
+ m = n;
+ goto not_yes;
+ }
+
+ matches++;
+ goto loop;
+
+ case 'v':
+ vp = va_arg (argp, void **);
+ n = gfc_match_variable ((gfc_expr **) vp, 0);
+ if (n != MATCH_YES)
+ {
+ m = n;
+ goto not_yes;
+ }
+
+ matches++;
+ goto loop;
+
+ case 's':
+ vp = va_arg (argp, void **);
+ n = gfc_match_symbol ((gfc_symbol **) vp, 0);
+ if (n != MATCH_YES)
+ {
+ m = n;
+ goto not_yes;
+ }
+
+ matches++;
+ goto loop;
+
+ case 'n':
+ np = va_arg (argp, char *);
+ n = gfc_match_name (np);
+ if (n != MATCH_YES)
+ {
+ m = n;
+ goto not_yes;
+ }
+
+ matches++;
+ goto loop;
+
+ case 'l':
+ label = va_arg (argp, gfc_st_label **);
+ n = gfc_match_st_label (label, 0);
+ if (n != MATCH_YES)
+ {
+ m = n;
+ goto not_yes;
+ }
+
+ matches++;
+ goto loop;
+
+ case 'o':
+ ip = va_arg (argp, int *);
+ n = gfc_match_intrinsic_op ((gfc_intrinsic_op *) ip);
+ if (n != MATCH_YES)
+ {
+ m = n;
+ goto not_yes;
+ }
+
+ matches++;
+ goto loop;
+
+ case 't':
+ if (gfc_match_eos () != MATCH_YES)
+ {
+ m = MATCH_NO;
+ goto not_yes;
+ }
+ goto loop;
+
+ case ' ':
+ if (gfc_match_space () == MATCH_YES)
+ goto loop;
+ m = MATCH_NO;
+ goto not_yes;
+
+ case '%':
+ break; /* Fall through to character matcher */
+
+ default:
+ gfc_internal_error ("gfc_match(): Bad match code %c", c);
+ }
+
+ default:
+ if (c == gfc_next_char ())
+ goto loop;
+ break;
+ }
+
+not_yes:
+ va_end (argp);
+
+ if (m != MATCH_YES)
+ {
+ /* Clean up after a failed match. */
+ gfc_set_locus (&old_loc);
+ va_start (argp, target);
+
+ p = target;
+ for (; matches > 0; matches--)
+ {
+ while (*p++ != '%');
+
+ switch (*p++)
+ {
+ case '%':
+ matches++;
+ break; /* Skip */
+
+ /* Matches that don't have to be undone */
+ case 'o':
+ case 'l':
+ case 'n':
+ case 's':
+ (void)va_arg (argp, void **);
+ break;
+
+ case 'e':
+ case 'v':
+ vp = va_arg (argp, void **);
+ gfc_free_expr (*vp);
+ *vp = NULL;
+ break;
+ }
+ }
+
+ va_end (argp);
+ }
+
+ return m;
+}
+
+
+/*********************** Statement level matching **********************/
+
+/* Matches the start of a program unit, which is the program keyword
+ followed by an optional symbol. */
+
+match
+gfc_match_program (void)
+{
+ gfc_symbol *sym;
+ match m;
+
+ m = gfc_match_eos ();
+ if (m == MATCH_YES)
+ return m;
+
+ m = gfc_match ("% %s%t", &sym);
+
+ if (m == MATCH_NO)
+ {
+ gfc_error ("Invalid form of PROGRAM statement at %C");
+ m = MATCH_ERROR;
+ }
+
+ if (m == MATCH_ERROR)
+ return m;
+
+ if (gfc_add_flavor (&sym->attr, FL_PROGRAM, NULL) == FAILURE)
+ return MATCH_ERROR;
+
+ gfc_new_block = sym;
+
+ return MATCH_YES;
+}
+
+
+/* Match a simple assignment statement. */
+
+match
+gfc_match_assignment (void)
+{
+ gfc_expr *lvalue, *rvalue;
+ locus old_loc;
+ match m;
+
+ old_loc = *gfc_current_locus ();
+
+ lvalue = rvalue = NULL;
+ m = gfc_match (" %v =", &lvalue);
+ if (m != MATCH_YES)
+ goto cleanup;
+
+ m = gfc_match (" %e%t", &rvalue);
+ if (m != MATCH_YES)
+ goto cleanup;
+
+ gfc_set_sym_referenced (lvalue->symtree->n.sym);
+
+ new_st.op = EXEC_ASSIGN;
+ new_st.expr = lvalue;
+ new_st.expr2 = rvalue;
+
+ return MATCH_YES;
+
+cleanup:
+ gfc_set_locus (&old_loc);
+ gfc_free_expr (lvalue);
+ gfc_free_expr (rvalue);
+ return m;
+}
+
+
+/* Match a pointer assignment statement. */
+
+match
+gfc_match_pointer_assignment (void)
+{
+ gfc_expr *lvalue, *rvalue;
+ locus old_loc;
+ match m;
+
+ old_loc = *gfc_current_locus ();
+
+ lvalue = rvalue = NULL;
+
+ m = gfc_match (" %v =>", &lvalue);
+ if (m != MATCH_YES)
+ {
+ m = MATCH_NO;
+ goto cleanup;
+ }
+
+ m = gfc_match (" %e%t", &rvalue);
+ if (m != MATCH_YES)
+ goto cleanup;
+
+ new_st.op = EXEC_POINTER_ASSIGN;
+ new_st.expr = lvalue;
+ new_st.expr2 = rvalue;
+
+ return MATCH_YES;
+
+cleanup:
+ gfc_set_locus (&old_loc);
+ gfc_free_expr (lvalue);
+ gfc_free_expr (rvalue);
+ return m;
+}
+
+
+/* The IF statement is a bit of a pain. First of all, there are three
+ forms of it, the simple IF, the IF that starts a block and the
+ arithmetic IF.
+
+ There is a problem with the simple IF and that is the fact that we
+ only have a single level of undo information on symbols. What this
+ means is for a simple IF, we must re-match the whole IF statement
+ multiple times in order to guarantee that the symbol table ends up
+ in the proper state. */
+
+match
+gfc_match_if (gfc_statement * if_type)
+{
+ gfc_expr *expr;
+ gfc_st_label *l1, *l2, *l3;
+ locus old_loc;
+ gfc_code *p;
+ match m, n;
+
+ n = gfc_match_label ();
+ if (n == MATCH_ERROR)
+ return n;
+
+ old_loc = *gfc_current_locus ();
+
+ m = gfc_match (" if ( %e", &expr);
+ if (m != MATCH_YES)
+ return m;
+
+ if (gfc_match_char (')') != MATCH_YES)
+ {
+ gfc_error ("Syntax error in IF-expression at %C");
+ gfc_free_expr (expr);
+ return MATCH_ERROR;
+ }
+
+ m = gfc_match (" %l , %l , %l%t", &l1, &l2, &l3);
+
+ if (m == MATCH_YES)
+ {
+ if (n == MATCH_YES)
+ {
+ gfc_error
+ ("Block label not appropriate for arithmetic IF statement "
+ "at %C");
+
+ gfc_free_expr (expr);
+ return MATCH_ERROR;
+ }
+
+ if (gfc_reference_st_label (l1, ST_LABEL_TARGET) == FAILURE
+ || gfc_reference_st_label (l2, ST_LABEL_TARGET) == FAILURE
+ || gfc_reference_st_label (l3, ST_LABEL_TARGET) == FAILURE)
+ {
+
+ gfc_free_expr (expr);
+ return MATCH_ERROR;
+ }
+
+ new_st.op = EXEC_ARITHMETIC_IF;
+ new_st.expr = expr;
+ new_st.label = l1;
+ new_st.label2 = l2;
+ new_st.label3 = l3;
+
+ *if_type = ST_ARITHMETIC_IF;
+ return MATCH_YES;
+ }
+
+ if (gfc_match (" then %t") == MATCH_YES)
+ {
+ new_st.op = EXEC_IF;
+ new_st.expr = expr;
+
+ *if_type = ST_IF_BLOCK;
+ return MATCH_YES;
+ }
+
+ if (n == MATCH_YES)
+ {
+ gfc_error ("Block label is not appropriate IF statement at %C");
+
+ gfc_free_expr (expr);
+ return MATCH_ERROR;
+ }
+
+ /* At this point the only thing left is a simple IF statement. At
+ this point, n has to be MATCH_NO, so we don't have to worry about
+ re-matching a block label. From what we've got so far, try
+ matching an assignment. */
+
+ *if_type = ST_SIMPLE_IF;
+
+ m = gfc_match_assignment ();
+ if (m == MATCH_YES)
+ goto got_match;
+
+ gfc_free_expr (expr);
+ gfc_undo_symbols ();
+ gfc_set_locus (&old_loc);
+
+ gfc_match (" if ( %e ) ", &expr); /* Guaranteed to match */
+
+ m = gfc_match_pointer_assignment ();
+ if (m == MATCH_YES)
+ goto got_match;
+
+ gfc_free_expr (expr);
+ gfc_undo_symbols ();
+ gfc_set_locus (&old_loc);
+
+ gfc_match (" if ( %e ) ", &expr); /* Guaranteed to match */
+
+ /* Look at the next keyword to see which matcher to call. Matching
+ the keyword doesn't affect the symbol table, so we don't have to
+ restore between tries. */
+
+#define match(string, subr, statement) \
+ if (gfc_match(string) == MATCH_YES) { m = subr(); goto got_match; }
+
+ gfc_clear_error ();
+
+ match ("allocate", gfc_match_allocate, ST_ALLOCATE)
+ match ("backspace", gfc_match_backspace, ST_BACKSPACE)
+ match ("call", gfc_match_call, ST_CALL)
+ match ("close", gfc_match_close, ST_CLOSE)
+ match ("continue", gfc_match_continue, ST_CONTINUE)
+ match ("cycle", gfc_match_cycle, ST_CYCLE)
+ match ("deallocate", gfc_match_deallocate, ST_DEALLOCATE)
+ match ("end file", gfc_match_endfile, ST_END_FILE)
+ match ("exit", gfc_match_exit, ST_EXIT)
+ match ("assign", gfc_match_assign, ST_LABEL_ASSIGNMENT)
+ match ("go to", gfc_match_goto, ST_GOTO)
+ match ("inquire", gfc_match_inquire, ST_INQUIRE)
+ match ("nullify", gfc_match_nullify, ST_NULLIFY)
+ match ("open", gfc_match_open, ST_OPEN)
+ match ("pause", gfc_match_pause, ST_NONE)
+ match ("print", gfc_match_print, ST_WRITE)
+ match ("read", gfc_match_read, ST_READ)
+ match ("return", gfc_match_return, ST_RETURN)
+ match ("rewind", gfc_match_rewind, ST_REWIND)
+ match ("pause", gfc_match_stop, ST_PAUSE)
+ match ("stop", gfc_match_stop, ST_STOP)
+ match ("write", gfc_match_write, ST_WRITE)
+
+ /* All else has failed, so give up. See if any of the matchers has
+ stored an error message of some sort. */
+ if (gfc_error_check () == 0)
+ gfc_error ("Unclassifiable statement in IF-clause at %C");
+
+ gfc_free_expr (expr);
+ return MATCH_ERROR;
+
+got_match:
+ if (m == MATCH_NO)
+ gfc_error ("Syntax error in IF-clause at %C");
+ if (m != MATCH_YES)
+ {
+ gfc_free_expr (expr);
+ return MATCH_ERROR;
+ }
+
+ /* At this point, we've matched the single IF and the action clause
+ is in new_st. Rearrange things so that the IF statement appears
+ in new_st. */
+
+ p = gfc_get_code ();
+ p->next = gfc_get_code ();
+ *p->next = new_st;
+ p->next->loc = *gfc_current_locus ();
+
+ p->expr = expr;
+ p->op = EXEC_IF;
+
+ gfc_clear_new_st ();
+
+ new_st.op = EXEC_IF;
+ new_st.block = p;
+
+ return MATCH_YES;
+}
+
+#undef match
+
+
+/* Match an ELSE statement. */
+
+match
+gfc_match_else (void)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+
+ if (gfc_match_eos () == MATCH_YES)
+ return MATCH_YES;
+
+ if (gfc_match_name (name) != MATCH_YES
+ || gfc_current_block () == NULL
+ || gfc_match_eos () != MATCH_YES)
+ {
+ gfc_error ("Unexpected junk after ELSE statement at %C");
+ return MATCH_ERROR;
+ }
+
+ if (strcmp (name, gfc_current_block ()->name) != 0)
+ {
+ gfc_error ("Label '%s' at %C doesn't match IF label '%s'",
+ name, gfc_current_block ()->name);
+ return MATCH_ERROR;
+ }
+
+ return MATCH_YES;
+}
+
+
+/* Match an ELSE IF statement. */
+
+match
+gfc_match_elseif (void)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_expr *expr;
+ match m;
+
+ m = gfc_match (" ( %e ) then", &expr);
+ if (m != MATCH_YES)
+ return m;
+
+ if (gfc_match_eos () == MATCH_YES)
+ goto done;
+
+ if (gfc_match_name (name) != MATCH_YES
+ || gfc_current_block () == NULL
+ || gfc_match_eos () != MATCH_YES)
+ {
+ gfc_error ("Unexpected junk after ELSE IF statement at %C");
+ goto cleanup;
+ }
+
+ if (strcmp (name, gfc_current_block ()->name) != 0)
+ {
+ gfc_error ("Label '%s' at %C doesn't match IF label '%s'",
+ name, gfc_current_block ()->name);
+ goto cleanup;
+ }
+
+done:
+ new_st.op = EXEC_IF;
+ new_st.expr = expr;
+ return MATCH_YES;
+
+cleanup:
+ gfc_free_expr (expr);
+ return MATCH_ERROR;
+}
+
+
+/* Free a gfc_iterator structure. */
+
+void
+gfc_free_iterator (gfc_iterator * iter, int flag)
+{
+
+ if (iter == NULL)
+ return;
+
+ gfc_free_expr (iter->var);
+ gfc_free_expr (iter->start);
+ gfc_free_expr (iter->end);
+ gfc_free_expr (iter->step);
+
+ if (flag)
+ gfc_free (iter);
+}
+
+
+/* Match a DO statement. */
+
+match
+gfc_match_do (void)
+{
+ gfc_iterator iter, *ip;
+ locus old_loc;
+ gfc_st_label *label;
+ match m;
+
+ old_loc = *gfc_current_locus ();
+
+ label = NULL;
+ iter.var = iter.start = iter.end = iter.step = NULL;
+
+ m = gfc_match_label ();
+ if (m == MATCH_ERROR)
+ return m;
+
+ if (gfc_match (" do") != MATCH_YES)
+ return MATCH_NO;
+
+ m = gfc_match_st_label (&label, 0);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+/* Match an infinite DO, make it like a DO WHILE(.TRUE.) */
+
+ if (gfc_match_eos () == MATCH_YES)
+ {
+ iter.end = gfc_logical_expr (1, NULL);
+ new_st.op = EXEC_DO_WHILE;
+ goto done;
+ }
+
+ /* match an optional comma, if no comma is found a space is obligatory. */
+ if (gfc_match_char(',') != MATCH_YES
+ && gfc_match ("% ") != MATCH_YES)
+ return MATCH_NO;
+
+ /* See if we have a DO WHILE. */
+ if (gfc_match (" while ( %e )%t", &iter.end) == MATCH_YES)
+ {
+ new_st.op = EXEC_DO_WHILE;
+ goto done;
+ }
+
+ /* The abortive DO WHILE may have done something to the symbol
+ table, so we start over: */
+ gfc_undo_symbols ();
+ gfc_set_locus (&old_loc);
+
+ gfc_match_label (); /* This won't error */
+ gfc_match (" do "); /* This will work */
+
+ gfc_match_st_label (&label, 0); /* Can't error out */
+ gfc_match_char (','); /* Optional comma */
+
+ m = gfc_match_iterator (&iter, 0);
+ if (m == MATCH_NO)
+ return MATCH_NO;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ if (gfc_match_eos () != MATCH_YES)
+ {
+ gfc_syntax_error (ST_DO);
+ goto cleanup;
+ }
+
+ new_st.op = EXEC_DO;
+
+done:
+ if (label != NULL
+ && gfc_reference_st_label (label, ST_LABEL_TARGET) == FAILURE)
+ goto cleanup;
+
+ new_st.label = label;
+
+ if (new_st.op == EXEC_DO_WHILE)
+ new_st.expr = iter.end;
+ else
+ {
+ new_st.ext.iterator = ip = gfc_get_iterator ();
+ *ip = iter;
+ }
+
+ return MATCH_YES;
+
+cleanup:
+ gfc_free_iterator (&iter, 0);
+
+ return MATCH_ERROR;
+}
+
+
+/* Match an EXIT or CYCLE statement. */
+
+static match
+match_exit_cycle (gfc_statement st, gfc_exec_op op)
+{
+ gfc_state_data *p;
+ gfc_symbol *sym;
+ match m;
+
+ if (gfc_match_eos () == MATCH_YES)
+ sym = NULL;
+ else
+ {
+ m = gfc_match ("% %s%t", &sym);
+ if (m == MATCH_ERROR)
+ return MATCH_ERROR;
+ if (m == MATCH_NO)
+ {
+ gfc_syntax_error (st);
+ return MATCH_ERROR;
+ }
+
+ if (sym->attr.flavor != FL_LABEL)
+ {
+ gfc_error ("Name '%s' in %s statement at %C is not a loop name",
+ sym->name, gfc_ascii_statement (st));
+ return MATCH_ERROR;
+ }
+ }
+
+ /* Find the loop mentioned specified by the label (or lack of a
+ label). */
+ for (p = gfc_state_stack; p; p = p->previous)
+ if (p->state == COMP_DO && (sym == NULL || sym == p->sym))
+ break;
+
+ if (p == NULL)
+ {
+ if (sym == NULL)
+ gfc_error ("%s statement at %C is not within a loop",
+ gfc_ascii_statement (st));
+ else
+ gfc_error ("%s statement at %C is not within loop '%s'",
+ gfc_ascii_statement (st), sym->name);
+
+ return MATCH_ERROR;
+ }
+
+ /* Save the first statement in the loop - needed by the backend. */
+ new_st.ext.whichloop = p->head;
+
+ new_st.op = op;
+/* new_st.sym = sym;*/
+
+ return MATCH_YES;
+}
+
+
+/* Match the EXIT statement. */
+
+match
+gfc_match_exit (void)
+{
+
+ return match_exit_cycle (ST_EXIT, EXEC_EXIT);
+}
+
+
+/* Match the CYCLE statement. */
+
+match
+gfc_match_cycle (void)
+{
+
+ return match_exit_cycle (ST_CYCLE, EXEC_CYCLE);
+}
+
+
+/* Match a number or character constant after a STOP or PAUSE statement. */
+
+static match
+gfc_match_stopcode (gfc_statement st)
+{
+ int stop_code;
+ gfc_expr *e;
+ match m;
+
+ stop_code = 0;
+ e = NULL;
+
+ if (gfc_match_eos () != MATCH_YES)
+ {
+ m = gfc_match_small_literal_int (&stop_code);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ if (m == MATCH_YES && stop_code > 99999)
+ {
+ gfc_error ("STOP code out of range at %C");
+ goto cleanup;
+ }
+
+ if (m == MATCH_NO)
+ {
+ /* Try a character constant. */
+ m = gfc_match_expr (&e);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ goto syntax;
+ if (e->ts.type != BT_CHARACTER || e->expr_type != EXPR_CONSTANT)
+ goto syntax;
+ }
+
+ if (gfc_match_eos () != MATCH_YES)
+ goto syntax;
+ }
+
+ if (gfc_pure (NULL))
+ {
+ gfc_error ("%s statement not allowed in PURE procedure at %C",
+ gfc_ascii_statement (st));
+ goto cleanup;
+ }
+
+ new_st.op = st == ST_STOP ? EXEC_STOP : EXEC_PAUSE;
+ new_st.expr = e;
+ new_st.ext.stop_code = stop_code;
+
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (st);
+
+cleanup:
+
+ gfc_free_expr (e);
+ return MATCH_ERROR;
+}
+
+/* Match the (deprecated) PAUSE statement. */
+
+match
+gfc_match_pause (void)
+{
+ match m;
+
+ m = gfc_match_stopcode (ST_PAUSE);
+ if (m == MATCH_YES)
+ {
+ if (gfc_notify_std (GFC_STD_F95_DEL,
+ "Obsolete: PAUSE statement at %C")
+ == FAILURE)
+ m = MATCH_ERROR;
+ }
+ return m;
+}
+
+
+/* Match the STOP statement. */
+
+match
+gfc_match_stop (void)
+{
+ return gfc_match_stopcode (ST_STOP);
+}
+
+
+/* Match a CONTINUE statement. */
+
+match
+gfc_match_continue (void)
+{
+
+ if (gfc_match_eos () != MATCH_YES)
+ {
+ gfc_syntax_error (ST_CONTINUE);
+ return MATCH_ERROR;
+ }
+
+ new_st.op = EXEC_CONTINUE;
+ return MATCH_YES;
+}
+
+
+/* Match the (deprecated) ASSIGN statement. */
+
+match
+gfc_match_assign (void)
+{
+ gfc_expr *expr;
+ gfc_st_label *label;
+
+ if (gfc_match (" %l", &label) == MATCH_YES)
+ {
+ if (gfc_reference_st_label (label, ST_LABEL_UNKNOWN) == FAILURE)
+ return MATCH_ERROR;
+ if (gfc_match (" to %v%t", &expr) == MATCH_YES)
+ {
+ if (gfc_notify_std (GFC_STD_F95_DEL,
+ "Obsolete: ASSIGN statement at %C")
+ == FAILURE)
+ return MATCH_ERROR;
+
+ expr->symtree->n.sym->attr.assign = 1;
+
+ new_st.op = EXEC_LABEL_ASSIGN;
+ new_st.label = label;
+ new_st.expr = expr;
+ return MATCH_YES;
+ }
+ }
+ return MATCH_NO;
+}
+
+
+/* Match the GO TO statement. As a computed GOTO statement is
+ matched, it is transformed into an equivalent SELECT block. No
+ tree is necessary, and the resulting jumps-to-jumps are
+ specifically optimized away by the back end. */
+
+match
+gfc_match_goto (void)
+{
+ gfc_code *head, *tail;
+ gfc_expr *expr;
+ gfc_case *cp;
+ gfc_st_label *label;
+ int i;
+ match m;
+
+ if (gfc_match (" %l%t", &label) == MATCH_YES)
+ {
+ if (gfc_reference_st_label (label, ST_LABEL_TARGET) == FAILURE)
+ return MATCH_ERROR;
+
+ new_st.op = EXEC_GOTO;
+ new_st.label = label;
+ return MATCH_YES;
+ }
+
+ /* The assigned GO TO statement. */
+
+ if (gfc_match_variable (&expr, 0) == MATCH_YES)
+ {
+ if (gfc_notify_std (GFC_STD_F95_DEL,
+ "Obsolete: Assigned GOTO statement at %C")
+ == FAILURE)
+ return MATCH_ERROR;
+
+ expr->symtree->n.sym->attr.assign = 1;
+ new_st.op = EXEC_GOTO;
+ new_st.expr = expr;
+
+ if (gfc_match_eos () == MATCH_YES)
+ return MATCH_YES;
+
+ /* Match label list. */
+ gfc_match_char (',');
+ if (gfc_match_char ('(') != MATCH_YES)
+ {
+ gfc_syntax_error (ST_GOTO);
+ return MATCH_ERROR;
+ }
+ head = tail = NULL;
+
+ do
+ {
+ m = gfc_match_st_label (&label, 0);
+ if (m != MATCH_YES)
+ goto syntax;
+
+ if (gfc_reference_st_label (label, ST_LABEL_TARGET) == FAILURE)
+ goto cleanup;
+
+ if (head == NULL)
+ head = tail = gfc_get_code ();
+ else
+ {
+ tail->block = gfc_get_code ();
+ tail = tail->block;
+ }
+
+ tail->label = label;
+ tail->op = EXEC_GOTO;
+ }
+ while (gfc_match_char (',') == MATCH_YES);
+
+ if (gfc_match (")%t") != MATCH_YES)
+ goto syntax;
+
+ if (head == NULL)
+ {
+ gfc_error (
+ "Statement label list in GOTO at %C cannot be empty");
+ goto syntax;
+ }
+ new_st.block = head;
+
+ return MATCH_YES;
+ }
+
+ /* Last chance is a computed GO TO statement. */
+ if (gfc_match_char ('(') != MATCH_YES)
+ {
+ gfc_syntax_error (ST_GOTO);
+ return MATCH_ERROR;
+ }
+
+ head = tail = NULL;
+ i = 1;
+
+ do
+ {
+ m = gfc_match_st_label (&label, 0);
+ if (m != MATCH_YES)
+ goto syntax;
+
+ if (gfc_reference_st_label (label, ST_LABEL_TARGET) == FAILURE)
+ goto cleanup;
+
+ if (head == NULL)
+ head = tail = gfc_get_code ();
+ else
+ {
+ tail->block = gfc_get_code ();
+ tail = tail->block;
+ }
+
+ cp = gfc_get_case ();
+ cp->low = cp->high = gfc_int_expr (i++);
+
+ tail->op = EXEC_SELECT;
+ tail->ext.case_list = cp;
+
+ tail->next = gfc_get_code ();
+ tail->next->op = EXEC_GOTO;
+ tail->next->label = label;
+ }
+ while (gfc_match_char (',') == MATCH_YES);
+
+ if (gfc_match_char (')') != MATCH_YES)
+ goto syntax;
+
+ if (head == NULL)
+ {
+ gfc_error ("Statement label list in GOTO at %C cannot be empty");
+ goto syntax;
+ }
+
+ /* Get the rest of the statement. */
+ gfc_match_char (',');
+
+ if (gfc_match (" %e%t", &expr) != MATCH_YES)
+ goto syntax;
+
+ /* At this point, a computed GOTO has been fully matched and an
+ equivalent SELECT statement constructed. */
+
+ new_st.op = EXEC_SELECT;
+ new_st.expr = NULL;
+
+ /* Hack: For a "real" SELECT, the expression is in expr. We put
+ it in expr2 so we can distinguish then and produce the correct
+ diagnostics. */
+ new_st.expr2 = expr;
+ new_st.block = head;
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (ST_GOTO);
+cleanup:
+ gfc_free_statements (head);
+ return MATCH_ERROR;
+}
+
+
+/* Frees a list of gfc_alloc structures. */
+
+void
+gfc_free_alloc_list (gfc_alloc * p)
+{
+ gfc_alloc *q;
+
+ for (; p; p = q)
+ {
+ q = p->next;
+ gfc_free_expr (p->expr);
+ gfc_free (p);
+ }
+}
+
+
+/* Match an ALLOCATE statement. */
+
+match
+gfc_match_allocate (void)
+{
+ gfc_alloc *head, *tail;
+ gfc_expr *stat;
+ match m;
+
+ head = tail = NULL;
+ stat = NULL;
+
+ if (gfc_match_char ('(') != MATCH_YES)
+ goto syntax;
+
+ for (;;)
+ {
+ if (head == NULL)
+ head = tail = gfc_get_alloc ();
+ else
+ {
+ tail->next = gfc_get_alloc ();
+ tail = tail->next;
+ }
+
+ m = gfc_match_variable (&tail->expr, 0);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ if (gfc_pure (NULL)
+ && gfc_impure_variable (tail->expr->symtree->n.sym))
+ {
+ gfc_error ("Bad allocate-object in ALLOCATE statement at %C for a "
+ "PURE procedure");
+ goto cleanup;
+ }
+
+ if (gfc_match_char (',') != MATCH_YES)
+ break;
+
+ m = gfc_match (" stat = %v", &stat);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_YES)
+ break;
+ }
+
+ if (stat != NULL)
+ {
+ if (stat->symtree->n.sym->attr.intent == INTENT_IN)
+ {
+ gfc_error
+ ("STAT variable '%s' of ALLOCATE statement at %C cannot be "
+ "INTENT(IN)", stat->symtree->n.sym->name);
+ goto cleanup;
+ }
+
+ if (gfc_pure (NULL) && gfc_impure_variable (stat->symtree->n.sym))
+ {
+ gfc_error
+ ("Illegal STAT variable in ALLOCATE statement at %C for a PURE "
+ "procedure");
+ goto cleanup;
+ }
+ }
+
+ if (gfc_match (" )%t") != MATCH_YES)
+ goto syntax;
+
+ new_st.op = EXEC_ALLOCATE;
+ new_st.expr = stat;
+ new_st.ext.alloc_list = head;
+
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (ST_ALLOCATE);
+
+cleanup:
+ gfc_free_expr (stat);
+ gfc_free_alloc_list (head);
+ return MATCH_ERROR;
+}
+
+
+/* Match a NULLIFY statement. A NULLIFY statement is transformed into
+ a set of pointer assignments to intrinsic NULL(). */
+
+match
+gfc_match_nullify (void)
+{
+ gfc_code *tail;
+ gfc_expr *e, *p;
+ match m;
+
+ tail = NULL;
+
+ if (gfc_match_char ('(') != MATCH_YES)
+ goto syntax;
+
+ for (;;)
+ {
+ m = gfc_match_variable (&p, 0);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ goto syntax;
+
+ if (gfc_pure (NULL) && gfc_impure_variable (p->symtree->n.sym))
+ {
+ gfc_error
+ ("Illegal variable in NULLIFY at %C for a PURE procedure");
+ goto cleanup;
+ }
+
+ /* build ' => NULL() ' */
+ e = gfc_get_expr ();
+ e->where = *gfc_current_locus ();
+ e->expr_type = EXPR_NULL;
+ e->ts.type = BT_UNKNOWN;
+
+ /* Chain to list */
+ if (tail == NULL)
+ tail = &new_st;
+ else
+ {
+ tail->next = gfc_get_code ();
+ tail = tail->next;
+ }
+
+ tail->op = EXEC_POINTER_ASSIGN;
+ tail->expr = p;
+ tail->expr2 = e;
+
+ if (gfc_match_char (')') == MATCH_YES)
+ break;
+ if (gfc_match_char (',') != MATCH_YES)
+ goto syntax;
+ }
+
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (ST_NULLIFY);
+
+cleanup:
+ gfc_free_statements (tail);
+ return MATCH_ERROR;
+}
+
+
+/* Match a DEALLOCATE statement. */
+
+match
+gfc_match_deallocate (void)
+{
+ gfc_alloc *head, *tail;
+ gfc_expr *stat;
+ match m;
+
+ head = tail = NULL;
+ stat = NULL;
+
+ if (gfc_match_char ('(') != MATCH_YES)
+ goto syntax;
+
+ for (;;)
+ {
+ if (head == NULL)
+ head = tail = gfc_get_alloc ();
+ else
+ {
+ tail->next = gfc_get_alloc ();
+ tail = tail->next;
+ }
+
+ m = gfc_match_variable (&tail->expr, 0);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ goto syntax;
+
+ if (gfc_pure (NULL)
+ && gfc_impure_variable (tail->expr->symtree->n.sym))
+ {
+ gfc_error
+ ("Illegal deallocate-expression in DEALLOCATE at %C for a PURE "
+ "procedure");
+ goto cleanup;
+ }
+
+ if (gfc_match_char (',') != MATCH_YES)
+ break;
+
+ m = gfc_match (" stat = %v", &stat);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_YES)
+ break;
+ }
+
+ if (stat != NULL && stat->symtree->n.sym->attr.intent == INTENT_IN)
+ {
+ gfc_error ("STAT variable '%s' of DEALLOCATE statement at %C cannot be "
+ "INTENT(IN)", stat->symtree->n.sym->name);
+ goto cleanup;
+ }
+
+ if (gfc_match (" )%t") != MATCH_YES)
+ goto syntax;
+
+ new_st.op = EXEC_DEALLOCATE;
+ new_st.expr = stat;
+ new_st.ext.alloc_list = head;
+
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (ST_DEALLOCATE);
+
+cleanup:
+ gfc_free_expr (stat);
+ gfc_free_alloc_list (head);
+ return MATCH_ERROR;
+}
+
+
+/* Match a RETURN statement. */
+
+match
+gfc_match_return (void)
+{
+ gfc_expr *e;
+ match m;
+
+ e = NULL;
+ if (gfc_match_eos () == MATCH_YES)
+ goto done;
+
+ if (gfc_find_state (COMP_SUBROUTINE) == FAILURE)
+ {
+ gfc_error ("Alternate RETURN statement at %C is only allowed within "
+ "a SUBROUTINE");
+ goto cleanup;
+ }
+
+ m = gfc_match ("% %e%t", &e);
+ if (m == MATCH_YES)
+ goto done;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ gfc_syntax_error (ST_RETURN);
+
+cleanup:
+ gfc_free_expr (e);
+ return MATCH_ERROR;
+
+done:
+ new_st.op = EXEC_RETURN;
+ new_st.expr = e;
+
+ return MATCH_YES;
+}
+
+
+/* Match a CALL statement. The tricky part here are possible
+ alternate return specifiers. We handle these by having all
+ "subroutines" actually return an integer via a register that gives
+ the return number. If the call specifies alternate returns, we
+ generate code for a SELECT statement whose case clauses contain
+ GOTOs to the various labels. */
+
+match
+gfc_match_call (void)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_actual_arglist *a, *arglist;
+ gfc_case *new_case;
+ gfc_symbol *sym;
+ gfc_symtree *st;
+ gfc_code *c;
+ match m;
+ int i;
+
+ arglist = NULL;
+
+ m = gfc_match ("% %n", name);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m != MATCH_YES)
+ return m;
+
+ if (gfc_get_ha_sym_tree (name, &st))
+ return MATCH_ERROR;
+
+ sym = st->n.sym;
+ gfc_set_sym_referenced (sym);
+
+ if (!sym->attr.generic
+ && !sym->attr.subroutine
+ && gfc_add_subroutine (&sym->attr, NULL) == FAILURE)
+ return MATCH_ERROR;
+
+ if (gfc_match_eos () != MATCH_YES)
+ {
+ m = gfc_match_actual_arglist (1, &arglist);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ if (gfc_match_eos () != MATCH_YES)
+ goto syntax;
+ }
+
+ /* If any alternate return labels were found, construct a SELECT
+ statement that will jump to the right place. */
+
+ i = 0;
+ for (a = arglist; a; a = a->next)
+ if (a->expr == NULL)
+ i = 1;
+
+ if (i)
+ {
+ gfc_symtree *select_st;
+ gfc_symbol *select_sym;
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+
+ new_st.next = c = gfc_get_code ();
+ c->op = EXEC_SELECT;
+ sprintf (name, "_result_%s",sym->name);
+ gfc_get_ha_sym_tree (name, &select_st); /* Can't fail */
+
+ select_sym = select_st->n.sym;
+ select_sym->ts.type = BT_INTEGER;
+ select_sym->ts.kind = gfc_default_integer_kind ();
+ gfc_set_sym_referenced (select_sym);
+ c->expr = gfc_get_expr ();
+ c->expr->expr_type = EXPR_VARIABLE;
+ c->expr->symtree = select_st;
+ c->expr->ts = select_sym->ts;
+ c->expr->where = *gfc_current_locus ();
+
+ i = 0;
+ for (a = arglist; a; a = a->next)
+ {
+ if (a->expr != NULL)
+ continue;
+
+ if (gfc_reference_st_label (a->label, ST_LABEL_TARGET) == FAILURE)
+ continue;
+
+ i++;
+
+ c->block = gfc_get_code ();
+ c = c->block;
+ c->op = EXEC_SELECT;
+
+ new_case = gfc_get_case ();
+ new_case->high = new_case->low = gfc_int_expr (i);
+ c->ext.case_list = new_case;
+
+ c->next = gfc_get_code ();
+ c->next->op = EXEC_GOTO;
+ c->next->label = a->label;
+ }
+ }
+
+ new_st.op = EXEC_CALL;
+ new_st.symtree = st;
+ new_st.ext.actual = arglist;
+
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (ST_CALL);
+
+cleanup:
+ gfc_free_actual_arglist (arglist);
+ return MATCH_ERROR;
+}
+
+
+/* Match an IMPLICIT NONE statement. Actually, this statement is
+ already matched in parse.c, or we would not end up here in the
+ first place. So the only thing we need to check, is if there is
+ trailing garbage. If not, the match is successful. */
+
+match
+gfc_match_implicit_none (void)
+{
+
+ return (gfc_match_eos () == MATCH_YES) ? MATCH_YES : MATCH_NO;
+}
+
+
+/* Match the letter range(s) of an IMPLICIT statement. */
+
+static match
+match_implicit_range (gfc_typespec * ts)
+{
+ int c, c1, c2, inner;
+ locus cur_loc;
+
+ cur_loc = *gfc_current_locus ();
+
+ gfc_gobble_whitespace ();
+ c = gfc_next_char ();
+ if (c != '(')
+ {
+ gfc_error ("Missing character range in IMPLICIT at %C");
+ goto bad;
+ }
+
+ inner = 1;
+ while (inner)
+ {
+ gfc_gobble_whitespace ();
+ c1 = gfc_next_char ();
+ if (!ISALPHA (c1))
+ goto bad;
+
+ gfc_gobble_whitespace ();
+ c = gfc_next_char ();
+
+ switch (c)
+ {
+ case ')':
+ inner = 0; /* Fall through */
+
+ case ',':
+ c2 = c1;
+ break;
+
+ case '-':
+ gfc_gobble_whitespace ();
+ c2 = gfc_next_char ();
+ if (!ISALPHA (c2))
+ goto bad;
+
+ gfc_gobble_whitespace ();
+ c = gfc_next_char ();
+
+ if ((c != ',') && (c != ')'))
+ goto bad;
+ if (c == ')')
+ inner = 0;
+
+ break;
+
+ default:
+ goto bad;
+ }
+
+ if (c1 > c2)
+ {
+ gfc_error ("Letters must be in alphabetic order in "
+ "IMPLICIT statement at %C");
+ goto bad;
+ }
+
+ /* See if we can add the newly matched range to the pending
+ implicits from this IMPLICIT statement. We do not check for
+ conflicts with whatever earlier IMPLICIT statements may have
+ set. This is done when we've successfully finished matching
+ the current one. */
+ if (gfc_add_new_implicit_range (c1, c2, ts) != SUCCESS)
+ goto bad;
+ }
+
+ return MATCH_YES;
+
+bad:
+ gfc_syntax_error (ST_IMPLICIT);
+
+ gfc_set_locus (&cur_loc);
+ return MATCH_ERROR;
+}
+
+
+/* Match an IMPLICIT statement, storing the types for
+ gfc_set_implicit() if the statement is accepted by the parser.
+ There is a strange looking, but legal syntactic construction
+ possible. It looks like:
+
+ IMPLICIT INTEGER (a-b) (c-d)
+
+ This is legal if "a-b" is a constant expression that happens to
+ equal one of the legal kinds for integers. The real problem
+ happens with an implicit specification that looks like:
+
+ IMPLICIT INTEGER (a-b)
+
+ In this case, a typespec matcher that is "greedy" (as most of the
+ matchers are) gobbles the character range as a kindspec, leaving
+ nothing left. We therefore have to go a bit more slowly in the
+ matching process by inhibiting the kindspec checking during
+ typespec matching and checking for a kind later. */
+
+match
+gfc_match_implicit (void)
+{
+ gfc_typespec ts;
+ locus cur_loc;
+ int c;
+ match m;
+
+ /* We don't allow empty implicit statements. */
+ if (gfc_match_eos () == MATCH_YES)
+ {
+ gfc_error ("Empty IMPLICIT statement at %C");
+ return MATCH_ERROR;
+ }
+
+ /* First cleanup. */
+ gfc_clear_new_implicit ();
+
+ do
+ {
+ /* A basic type is mandatory here. */
+ m = gfc_match_type_spec (&ts, 0);
+ if (m == MATCH_ERROR)
+ goto error;
+ if (m == MATCH_NO)
+ goto syntax;
+
+ cur_loc = *gfc_current_locus ();
+ m = match_implicit_range (&ts);
+
+ if (m == MATCH_YES)
+ {
+ /* Looks like we have the <TYPE> (<RANGE>). */
+ gfc_gobble_whitespace ();
+ c = gfc_next_char ();
+ if ((c == '\n') || (c == ','))
+ continue;
+
+ gfc_set_locus (&cur_loc);
+ }
+
+ /* Last chance -- check <TYPE> (<KIND>) (<RANGE>). */
+ m = gfc_match_kind_spec (&ts);
+ if (m == MATCH_ERROR)
+ goto error;
+ if (m == MATCH_NO)
+ {
+ m = gfc_match_old_kind_spec (&ts);
+ if (m == MATCH_ERROR)
+ goto error;
+ if (m == MATCH_NO)
+ goto syntax;
+ }
+
+ m = match_implicit_range (&ts);
+ if (m == MATCH_ERROR)
+ goto error;
+ if (m == MATCH_NO)
+ goto syntax;
+
+ gfc_gobble_whitespace ();
+ c = gfc_next_char ();
+ if ((c != '\n') && (c != ','))
+ goto syntax;
+
+ }
+ while (c == ',');
+
+ /* All we need to now is try to merge the new implicit types back
+ into the existing types. This will fail if another implicit
+ type is already defined for a letter. */
+ return (gfc_merge_new_implicit () == SUCCESS) ?
+ MATCH_YES : MATCH_ERROR;
+
+syntax:
+ gfc_syntax_error (ST_IMPLICIT);
+
+error:
+ return MATCH_ERROR;
+}
+
+
+/* Match a common block name. */
+
+static match
+match_common_name (gfc_symbol ** sym)
+{
+ match m;
+
+ if (gfc_match_char ('/') == MATCH_NO)
+ return MATCH_NO;
+
+ if (gfc_match_char ('/') == MATCH_YES)
+ {
+ *sym = NULL;
+ return MATCH_YES;
+ }
+
+ m = gfc_match_symbol (sym, 0);
+
+ if (m == MATCH_ERROR)
+ return MATCH_ERROR;
+ if (m == MATCH_YES && gfc_match_char ('/') == MATCH_YES)
+ return MATCH_YES;
+
+ gfc_error ("Syntax error in common block name at %C");
+ return MATCH_ERROR;
+}
+
+
+/* Match a COMMON statement. */
+
+match
+gfc_match_common (void)
+{
+ gfc_symbol *sym, *common_name, **head, *tail, *old_blank_common;
+ gfc_array_spec *as;
+ match m;
+
+ old_blank_common = gfc_current_ns->blank_common;
+ if (old_blank_common)
+ {
+ while (old_blank_common->common_next)
+ old_blank_common = old_blank_common->common_next;
+ }
+
+ common_name = NULL;
+ as = NULL;
+
+ if (gfc_match_eos () == MATCH_YES)
+ goto syntax;
+
+ for (;;)
+ {
+ m = match_common_name (&common_name);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ if (common_name == NULL)
+ head = &gfc_current_ns->blank_common;
+ else
+ {
+ head = &common_name->common_head;
+
+ if (!common_name->attr.common
+ && gfc_add_common (&common_name->attr, NULL) == FAILURE)
+ goto cleanup;
+ }
+
+ if (*head == NULL)
+ tail = NULL;
+ else
+ {
+ tail = *head;
+ while (tail->common_next)
+ tail = tail->common_next;
+ }
+
+ /* Grab the list of symbols. */
+ for (;;)
+ {
+ m = gfc_match_symbol (&sym, 0);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ goto syntax;
+
+ if (sym->attr.in_common)
+ {
+ gfc_error ("Symbol '%s' at %C is already in a COMMON block",
+ sym->name);
+ goto cleanup;
+ }
+
+ if (gfc_add_in_common (&sym->attr, NULL) == FAILURE)
+ goto cleanup;
+
+ /* Derived type names must have the SEQUENCE attribute. */
+ if (sym->ts.type == BT_DERIVED && !sym->ts.derived->attr.sequence)
+ {
+ gfc_error
+ ("Derived type variable in COMMON at %C does not have the "
+ "SEQUENCE attribute");
+ goto cleanup;
+ }
+
+ if (tail != NULL)
+ tail->common_next = sym;
+ else
+ *head = sym;
+
+ tail = sym;
+
+ /* Deal with an optional array specification after the
+ symbol name. */
+ m = gfc_match_array_spec (&as);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ if (m == MATCH_YES)
+ {
+ if (as->type != AS_EXPLICIT)
+ {
+ gfc_error
+ ("Array specification for symbol '%s' in COMMON at %C "
+ "must be explicit", sym->name);
+ goto cleanup;
+ }
+
+ if (gfc_add_dimension (&sym->attr, NULL) == FAILURE)
+ goto cleanup;
+
+ if (sym->attr.pointer)
+ {
+ gfc_error
+ ("Symbol '%s' in COMMON at %C cannot be a POINTER array",
+ sym->name);
+ goto cleanup;
+ }
+
+ sym->as = as;
+ as = NULL;
+ }
+
+ if (gfc_match_eos () == MATCH_YES)
+ goto done;
+ if (gfc_peek_char () == '/')
+ break;
+ if (gfc_match_char (',') != MATCH_YES)
+ goto syntax;
+ if (gfc_peek_char () == '/')
+ break;
+ }
+ }
+
+done:
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (ST_COMMON);
+
+cleanup:
+ if (old_blank_common)
+ old_blank_common->common_next = NULL;
+ else
+ gfc_current_ns->blank_common = NULL;
+ gfc_free_array_spec (as);
+ return MATCH_ERROR;
+}
+
+
+/* Match a BLOCK DATA program unit. */
+
+match
+gfc_match_block_data (void)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_symbol *sym;
+ match m;
+
+ if (gfc_match_eos () == MATCH_YES)
+ {
+ gfc_new_block = NULL;
+ return MATCH_YES;
+ }
+
+ m = gfc_match (" %n%t", name);
+ if (m != MATCH_YES)
+ return MATCH_ERROR;
+
+ if (gfc_get_symbol (name, NULL, &sym))
+ return MATCH_ERROR;
+
+ if (gfc_add_flavor (&sym->attr, FL_BLOCK_DATA, NULL) == FAILURE)
+ return MATCH_ERROR;
+
+ gfc_new_block = sym;
+
+ return MATCH_YES;
+}
+
+
+/* Free a namelist structure. */
+
+void
+gfc_free_namelist (gfc_namelist * name)
+{
+ gfc_namelist *n;
+
+ for (; name; name = n)
+ {
+ n = name->next;
+ gfc_free (name);
+ }
+}
+
+
+/* Match a NAMELIST statement. */
+
+match
+gfc_match_namelist (void)
+{
+ gfc_symbol *group_name, *sym;
+ gfc_namelist *nl;
+ match m, m2;
+
+ m = gfc_match (" / %s /", &group_name);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto error;
+
+ for (;;)
+ {
+ if (group_name->ts.type != BT_UNKNOWN)
+ {
+ gfc_error
+ ("Namelist group name '%s' at %C already has a basic type "
+ "of %s", group_name->name, gfc_typename (&group_name->ts));
+ return MATCH_ERROR;
+ }
+
+ if (group_name->attr.flavor != FL_NAMELIST
+ && gfc_add_flavor (&group_name->attr, FL_NAMELIST, NULL) == FAILURE)
+ return MATCH_ERROR;
+
+ for (;;)
+ {
+ m = gfc_match_symbol (&sym, 1);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto error;
+
+ if (sym->attr.in_namelist == 0
+ && gfc_add_in_namelist (&sym->attr, NULL) == FAILURE)
+ goto error;
+
+ /* TODO: worry about PRIVATE members of a PUBLIC namelist
+ group. */
+
+ nl = gfc_get_namelist ();
+ nl->sym = sym;
+
+ if (group_name->namelist == NULL)
+ group_name->namelist = group_name->namelist_tail = nl;
+ else
+ {
+ group_name->namelist_tail->next = nl;
+ group_name->namelist_tail = nl;
+ }
+
+ if (gfc_match_eos () == MATCH_YES)
+ goto done;
+
+ m = gfc_match_char (',');
+
+ if (gfc_match_char ('/') == MATCH_YES)
+ {
+ m2 = gfc_match (" %s /", &group_name);
+ if (m2 == MATCH_YES)
+ break;
+ if (m2 == MATCH_ERROR)
+ goto error;
+ goto syntax;
+ }
+
+ if (m != MATCH_YES)
+ goto syntax;
+ }
+ }
+
+done:
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (ST_NAMELIST);
+
+error:
+ return MATCH_ERROR;
+}
+
+
+/* Match a MODULE statement. */
+
+match
+gfc_match_module (void)
+{
+ match m;
+
+ m = gfc_match (" %s%t", &gfc_new_block);
+ if (m != MATCH_YES)
+ return m;
+
+ if (gfc_add_flavor (&gfc_new_block->attr, FL_MODULE, NULL) == FAILURE)
+ return MATCH_ERROR;
+
+ return MATCH_YES;
+}
+
+
+/* Free equivalence sets and lists. Recursively is the easiest way to
+ do this. */
+
+void
+gfc_free_equiv (gfc_equiv * eq)
+{
+
+ if (eq == NULL)
+ return;
+
+ gfc_free_equiv (eq->eq);
+ gfc_free_equiv (eq->next);
+
+ gfc_free_expr (eq->expr);
+ gfc_free (eq);
+}
+
+
+/* Match an EQUIVALENCE statement. */
+
+match
+gfc_match_equivalence (void)
+{
+ gfc_equiv *eq, *set, *tail;
+ gfc_ref *ref;
+ match m;
+
+ tail = NULL;
+
+ for (;;)
+ {
+ eq = gfc_get_equiv ();
+ if (tail == NULL)
+ tail = eq;
+
+ eq->next = gfc_current_ns->equiv;
+ gfc_current_ns->equiv = eq;
+
+ if (gfc_match_char ('(') != MATCH_YES)
+ goto syntax;
+
+ set = eq;
+
+ for (;;)
+ {
+ m = gfc_match_variable (&set->expr, 1);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ goto syntax;
+
+ for (ref = set->expr->ref; ref; ref = ref->next)
+ if (ref->type == REF_ARRAY && ref->u.ar.type == AR_SECTION)
+ {
+ gfc_error
+ ("Array reference in EQUIVALENCE at %C cannot be an "
+ "array section");
+ goto cleanup;
+ }
+
+ if (gfc_match_char (')') == MATCH_YES)
+ break;
+ if (gfc_match_char (',') != MATCH_YES)
+ goto syntax;
+
+ set->eq = gfc_get_equiv ();
+ set = set->eq;
+ }
+
+ if (gfc_match_eos () == MATCH_YES)
+ break;
+ if (gfc_match_char (',') != MATCH_YES)
+ goto syntax;
+ }
+
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (ST_EQUIVALENCE);
+
+cleanup:
+ eq = tail->next;
+ tail->next = NULL;
+
+ gfc_free_equiv (gfc_current_ns->equiv);
+ gfc_current_ns->equiv = eq;
+
+ return MATCH_ERROR;
+}
+
+
+/* Match a statement function declaration. It is so easy to match
+ non-statement function statements with a MATCH_ERROR as opposed to
+ MATCH_NO that we suppress error message in most cases. */
+
+match
+gfc_match_st_function (void)
+{
+ gfc_error_buf old_error;
+ gfc_symbol *sym;
+ gfc_expr *expr;
+ match m;
+
+ m = gfc_match_symbol (&sym, 0);
+ if (m != MATCH_YES)
+ return m;
+
+ gfc_push_error (&old_error);
+
+ if (gfc_add_procedure (&sym->attr, PROC_ST_FUNCTION, NULL) == FAILURE)
+ goto undo_error;
+
+ if (gfc_match_formal_arglist (sym, 1, 0) != MATCH_YES)
+ goto undo_error;
+
+ m = gfc_match (" = %e%t", &expr);
+ if (m == MATCH_NO)
+ goto undo_error;
+ if (m == MATCH_ERROR)
+ return m;
+
+ sym->value = expr;
+
+ return MATCH_YES;
+
+undo_error:
+ gfc_pop_error (&old_error);
+ return MATCH_NO;
+}
+
+
+/********************* DATA statement subroutines *********************/
+
+/* Free a gfc_data_variable structure and everything beneath it. */
+
+static void
+free_variable (gfc_data_variable * p)
+{
+ gfc_data_variable *q;
+
+ for (; p; p = q)
+ {
+ q = p->next;
+ gfc_free_expr (p->expr);
+ gfc_free_iterator (&p->iter, 0);
+ free_variable (p->list);
+
+ gfc_free (p);
+ }
+}
+
+
+/* Free a gfc_data_value structure and everything beneath it. */
+
+static void
+free_value (gfc_data_value * p)
+{
+ gfc_data_value *q;
+
+ for (; p; p = q)
+ {
+ q = p->next;
+ gfc_free_expr (p->expr);
+ gfc_free (p);
+ }
+}
+
+
+/* Free a list of gfc_data structures. */
+
+void
+gfc_free_data (gfc_data * p)
+{
+ gfc_data *q;
+
+ for (; p; p = q)
+ {
+ q = p->next;
+
+ free_variable (p->var);
+ free_value (p->value);
+
+ gfc_free (p);
+ }
+}
+
+
+static match var_element (gfc_data_variable *);
+
+/* Match a list of variables terminated by an iterator and a right
+ parenthesis. */
+
+static match
+var_list (gfc_data_variable * parent)
+{
+ gfc_data_variable *tail, var;
+ match m;
+
+ m = var_element (&var);
+ if (m == MATCH_ERROR)
+ return MATCH_ERROR;
+ if (m == MATCH_NO)
+ goto syntax;
+
+ tail = gfc_get_data_variable ();
+ *tail = var;
+
+ parent->list = tail;
+
+ for (;;)
+ {
+ if (gfc_match_char (',') != MATCH_YES)
+ goto syntax;
+
+ m = gfc_match_iterator (&parent->iter, 1);
+ if (m == MATCH_YES)
+ break;
+ if (m == MATCH_ERROR)
+ return MATCH_ERROR;
+
+ m = var_element (&var);
+ if (m == MATCH_ERROR)
+ return MATCH_ERROR;
+ if (m == MATCH_NO)
+ goto syntax;
+
+ tail->next = gfc_get_data_variable ();
+ tail = tail->next;
+
+ *tail = var;
+ }
+
+ if (gfc_match_char (')') != MATCH_YES)
+ goto syntax;
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (ST_DATA);
+ return MATCH_ERROR;
+}
+
+
+/* Match a single element in a data variable list, which can be a
+ variable-iterator list. */
+
+static match
+var_element (gfc_data_variable * new)
+{
+ match m;
+
+ memset (new, '\0', sizeof (gfc_data_variable));
+
+ if (gfc_match_char ('(') == MATCH_YES)
+ return var_list (new);
+
+ m = gfc_match_variable (&new->expr, 0);
+ if (m != MATCH_YES)
+ return m;
+
+ if (new->expr->symtree->n.sym->value != NULL)
+ {
+ gfc_error ("Variable '%s' at %C already has an initialization",
+ new->expr->symtree->n.sym->name);
+ return MATCH_ERROR;
+ }
+
+ new->expr->symtree->n.sym->attr.data = 1;
+ return MATCH_YES;
+}
+
+
+/* Match the top-level list of data variables. */
+
+static match
+top_var_list (gfc_data * d)
+{
+ gfc_data_variable var, *tail, *new;
+ match m;
+
+ tail = NULL;
+
+ for (;;)
+ {
+ m = var_element (&var);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ return MATCH_ERROR;
+
+ new = gfc_get_data_variable ();
+ *new = var;
+
+ if (tail == NULL)
+ d->var = new;
+ else
+ tail->next = new;
+
+ tail = new;
+
+ if (gfc_match_char ('/') == MATCH_YES)
+ break;
+ if (gfc_match_char (',') != MATCH_YES)
+ goto syntax;
+ }
+
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (ST_DATA);
+ return MATCH_ERROR;
+}
+
+
+static match
+match_data_constant (gfc_expr ** result)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_symbol *sym;
+ gfc_expr *expr;
+ match m;
+
+ m = gfc_match_literal_constant (&expr, 1);
+ if (m == MATCH_YES)
+ {
+ *result = expr;
+ return MATCH_YES;
+ }
+
+ if (m == MATCH_ERROR)
+ return MATCH_ERROR;
+
+ m = gfc_match_null (result);
+ if (m != MATCH_NO)
+ return m;
+
+ m = gfc_match_name (name);
+ if (m != MATCH_YES)
+ return m;
+
+ if (gfc_find_symbol (name, NULL, 1, &sym))
+ return MATCH_ERROR;
+
+ if (sym == NULL || sym->attr.flavor != FL_PARAMETER)
+ {
+ gfc_error ("Symbol '%s' must be a PARAMETER in DATA statement at %C",
+ name);
+ return MATCH_ERROR;
+ }
+
+ *result = gfc_copy_expr (sym->value);
+ return MATCH_YES;
+}
+
+
+/* Match a list of values in a DATA statement. The leading '/' has
+ already been seen at this point. */
+
+static match
+top_val_list (gfc_data * data)
+{
+ gfc_data_value *new, *tail;
+ gfc_expr *expr;
+ const char *msg;
+ match m;
+
+ tail = NULL;
+
+ for (;;)
+ {
+ m = match_data_constant (&expr);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ return MATCH_ERROR;
+
+ new = gfc_get_data_value ();
+
+ if (tail == NULL)
+ data->value = new;
+ else
+ tail->next = new;
+
+ tail = new;
+
+ if (expr->ts.type != BT_INTEGER || gfc_match_char ('*') != MATCH_YES)
+ {
+ tail->expr = expr;
+ tail->repeat = 1;
+ }
+ else
+ {
+ msg = gfc_extract_int (expr, &tail->repeat);
+ gfc_free_expr (expr);
+ if (msg != NULL)
+ {
+ gfc_error (msg);
+ return MATCH_ERROR;
+ }
+
+ m = match_data_constant (&tail->expr);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ return MATCH_ERROR;
+ }
+
+ if (gfc_match_char ('/') == MATCH_YES)
+ break;
+ if (gfc_match_char (',') == MATCH_NO)
+ goto syntax;
+ }
+
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (ST_DATA);
+ return MATCH_ERROR;
+}
+
+
+/* Match a DATA statement. */
+
+match
+gfc_match_data (void)
+{
+ gfc_data *new;
+ match m;
+
+ for (;;)
+ {
+ new = gfc_get_data ();
+ new->where = *gfc_current_locus ();
+
+ m = top_var_list (new);
+ if (m != MATCH_YES)
+ goto cleanup;
+
+ m = top_val_list (new);
+ if (m != MATCH_YES)
+ goto cleanup;
+
+ new->next = gfc_current_ns->data;
+ gfc_current_ns->data = new;
+
+ if (gfc_match_eos () == MATCH_YES)
+ break;
+
+ gfc_match_char (','); /* Optional comma */
+ }
+
+ if (gfc_pure (NULL))
+ {
+ gfc_error ("DATA statement at %C is not allowed in a PURE procedure");
+ return MATCH_ERROR;
+ }
+
+ return MATCH_YES;
+
+cleanup:
+ gfc_free_data (new);
+ return MATCH_ERROR;
+}
+
+
+/***************** SELECT CASE subroutines ******************/
+
+/* Free a single case structure. */
+
+static void
+free_case (gfc_case * p)
+{
+ if (p->low == p->high)
+ p->high = NULL;
+ gfc_free_expr (p->low);
+ gfc_free_expr (p->high);
+ gfc_free (p);
+}
+
+
+/* Free a list of case structures. */
+
+void
+gfc_free_case_list (gfc_case * p)
+{
+ gfc_case *q;
+
+ for (; p; p = q)
+ {
+ q = p->next;
+ free_case (p);
+ }
+}
+
+
+/* Match a single case selector. */
+
+static match
+match_case_selector (gfc_case ** cp)
+{
+ gfc_case *c;
+ match m;
+
+ c = gfc_get_case ();
+ c->where = *gfc_current_locus ();
+
+ if (gfc_match_char (':') == MATCH_YES)
+ {
+ m = gfc_match_expr (&c->high);
+ if (m == MATCH_NO)
+ goto need_expr;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ }
+
+ else
+ {
+ m = gfc_match_expr (&c->low);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ goto need_expr;
+
+ /* If we're not looking at a ':' now, make a range out of a single
+ target. Else get the upper bound for the case range. */
+ if (gfc_match_char (':') != MATCH_YES)
+ c->high = c->low;
+ else
+ {
+ m = gfc_match_expr (&c->high);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ /* MATCH_NO is fine. It's OK if nothing is there! */
+ }
+ }
+
+ *cp = c;
+ return MATCH_YES;
+
+need_expr:
+ gfc_error ("Expected expression in CASE at %C");
+
+cleanup:
+ free_case (c);
+ return MATCH_ERROR;
+}
+
+
+/* Match the end of a case statement. */
+
+static match
+match_case_eos (void)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ match m;
+
+ if (gfc_match_eos () == MATCH_YES)
+ return MATCH_YES;
+
+ gfc_gobble_whitespace ();
+
+ m = gfc_match_name (name);
+ if (m != MATCH_YES)
+ return m;
+
+ if (strcmp (name, gfc_current_block ()->name) != 0)
+ {
+ gfc_error ("Expected case name of '%s' at %C",
+ gfc_current_block ()->name);
+ return MATCH_ERROR;
+ }
+
+ return gfc_match_eos ();
+}
+
+
+/* Match a SELECT statement. */
+
+match
+gfc_match_select (void)
+{
+ gfc_expr *expr;
+ match m;
+
+ m = gfc_match_label ();
+ if (m == MATCH_ERROR)
+ return m;
+
+ m = gfc_match (" select case ( %e )%t", &expr);
+ if (m != MATCH_YES)
+ return m;
+
+ new_st.op = EXEC_SELECT;
+ new_st.expr = expr;
+
+ return MATCH_YES;
+}
+
+
+/* Match a CASE statement. */
+
+match
+gfc_match_case (void)
+{
+ gfc_case *c, *head, *tail;
+ match m;
+
+ head = tail = NULL;
+
+ if (gfc_current_state () != COMP_SELECT)
+ {
+ gfc_error ("Unexpected CASE statement at %C");
+ return MATCH_ERROR;
+ }
+
+ if (gfc_match ("% default") == MATCH_YES)
+ {
+ m = match_case_eos ();
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ new_st.op = EXEC_SELECT;
+ c = gfc_get_case ();
+ c->where = *gfc_current_locus ();
+ new_st.ext.case_list = c;
+ return MATCH_YES;
+ }
+
+ if (gfc_match_char ('(') != MATCH_YES)
+ goto syntax;
+
+ for (;;)
+ {
+ if (match_case_selector (&c) == MATCH_ERROR)
+ goto cleanup;
+
+ if (head == NULL)
+ head = c;
+ else
+ tail->next = c;
+
+ tail = c;
+
+ if (gfc_match_char (')') == MATCH_YES)
+ break;
+ if (gfc_match_char (',') != MATCH_YES)
+ goto syntax;
+ }
+
+ m = match_case_eos ();
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ new_st.op = EXEC_SELECT;
+ new_st.ext.case_list = head;
+
+ return MATCH_YES;
+
+syntax:
+ gfc_error ("Syntax error in CASE-specification at %C");
+
+cleanup:
+ gfc_free_case_list (head); /* new_st is cleaned up in parse.c. */
+ return MATCH_ERROR;
+}
+
+/********************* WHERE subroutines ********************/
+
+/* Match a WHERE statement. */
+
+match
+gfc_match_where (gfc_statement * st)
+{
+ gfc_expr *expr;
+ match m0, m;
+ gfc_code *c;
+
+ m0 = gfc_match_label ();
+ if (m0 == MATCH_ERROR)
+ return m0;
+
+ m = gfc_match (" where ( %e )", &expr);
+ if (m != MATCH_YES)
+ return m;
+
+ if (gfc_match_eos () == MATCH_YES)
+ {
+ *st = ST_WHERE_BLOCK;
+
+ new_st.op = EXEC_WHERE;
+ new_st.expr = expr;
+ return MATCH_YES;
+ }
+
+ m = gfc_match_assignment ();
+ if (m == MATCH_NO)
+ gfc_syntax_error (ST_WHERE);
+
+ if (m != MATCH_YES)
+ {
+ gfc_free_expr (expr);
+ return MATCH_ERROR;
+ }
+
+ /* We've got a simple WHERE statement. */
+ *st = ST_WHERE;
+ c = gfc_get_code ();
+
+ c->op = EXEC_WHERE;
+ c->expr = expr;
+ c->next = gfc_get_code ();
+
+ *c->next = new_st;
+ gfc_clear_new_st ();
+
+ new_st.op = EXEC_WHERE;
+ new_st.block = c;
+
+ return MATCH_YES;
+}
+
+
+/* Match an ELSEWHERE statement. We leave behind a WHERE node in
+ new_st if successful. */
+
+match
+gfc_match_elsewhere (void)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_expr *expr;
+ match m;
+
+ if (gfc_current_state () != COMP_WHERE)
+ {
+ gfc_error ("ELSEWHERE statement at %C not enclosed in WHERE block");
+ return MATCH_ERROR;
+ }
+
+ expr = NULL;
+
+ if (gfc_match_char ('(') == MATCH_YES)
+ {
+ m = gfc_match_expr (&expr);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ return MATCH_ERROR;
+
+ if (gfc_match_char (')') != MATCH_YES)
+ goto syntax;
+ }
+
+ if (gfc_match_eos () != MATCH_YES)
+ { /* Better be a name at this point */
+ m = gfc_match_name (name);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ if (gfc_match_eos () != MATCH_YES)
+ goto syntax;
+
+ if (strcmp (name, gfc_current_block ()->name) != 0)
+ {
+ gfc_error ("Label '%s' at %C doesn't match WHERE label '%s'",
+ name, gfc_current_block ()->name);
+ goto cleanup;
+ }
+ }
+
+ new_st.op = EXEC_WHERE;
+ new_st.expr = expr;
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (ST_ELSEWHERE);
+
+cleanup:
+ gfc_free_expr (expr);
+ return MATCH_ERROR;
+}
+
+
+/******************** FORALL subroutines ********************/
+
+/* Free a list of FORALL iterators. */
+
+void
+gfc_free_forall_iterator (gfc_forall_iterator * iter)
+{
+ gfc_forall_iterator *next;
+
+ while (iter)
+ {
+ next = iter->next;
+
+ gfc_free_expr (iter->var);
+ gfc_free_expr (iter->start);
+ gfc_free_expr (iter->end);
+ gfc_free_expr (iter->stride);
+
+ gfc_free (iter);
+ iter = next;
+ }
+}
+
+
+/* Match an iterator as part of a FORALL statement. The format is:
+
+ <var> = <start>:<end>[:<stride>][, <scalar mask>] */
+
+static match
+match_forall_iterator (gfc_forall_iterator ** result)
+{
+ gfc_forall_iterator *iter;
+ locus where;
+ match m;
+
+ where = *gfc_current_locus ();
+ iter = gfc_getmem (sizeof (gfc_forall_iterator));
+
+ m = gfc_match_variable (&iter->var, 0);
+ if (m != MATCH_YES)
+ goto cleanup;
+
+ if (gfc_match_char ('=') != MATCH_YES)
+ {
+ m = MATCH_NO;
+ goto cleanup;
+ }
+
+ m = gfc_match_expr (&iter->start);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ if (gfc_match_char (':') != MATCH_YES)
+ goto syntax;
+
+ m = gfc_match_expr (&iter->end);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ if (gfc_match_char (':') == MATCH_NO)
+ iter->stride = gfc_int_expr (1);
+ else
+ {
+ m = gfc_match_expr (&iter->stride);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ }
+
+ *result = iter;
+ return MATCH_YES;
+
+syntax:
+ gfc_error ("Syntax error in FORALL iterator at %C");
+ m = MATCH_ERROR;
+
+cleanup:
+ gfc_set_locus (&where);
+ gfc_free_forall_iterator (iter);
+ return m;
+}
+
+
+/* Match a FORALL statement. */
+
+match
+gfc_match_forall (gfc_statement * st)
+{
+ gfc_forall_iterator *head, *tail, *new;
+ gfc_expr *mask;
+ gfc_code *c;
+ match m0, m;
+
+ head = tail = NULL;
+ mask = NULL;
+ c = NULL;
+
+ m0 = gfc_match_label ();
+ if (m0 == MATCH_ERROR)
+ return MATCH_ERROR;
+
+ m = gfc_match (" forall (");
+ if (m != MATCH_YES)
+ return m;
+
+ m = match_forall_iterator (&new);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ goto syntax;
+
+ head = tail = new;
+
+ for (;;)
+ {
+ if (gfc_match_char (',') != MATCH_YES)
+ break;
+
+ m = match_forall_iterator (&new);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_YES)
+ {
+ tail->next = new;
+ tail = new;
+ continue;
+ }
+
+ /* Have to have a mask expression. */
+ m = gfc_match_expr (&mask);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ break;
+ }
+
+ if (gfc_match_char (')') == MATCH_NO)
+ goto syntax;
+
+ if (gfc_match_eos () == MATCH_YES)
+ {
+ *st = ST_FORALL_BLOCK;
+
+ new_st.op = EXEC_FORALL;
+ new_st.expr = mask;
+ new_st.ext.forall_iterator = head;
+
+ return MATCH_YES;
+ }
+
+ m = gfc_match_assignment ();
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ {
+ m = gfc_match_pointer_assignment ();
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ goto syntax;
+ }
+
+ c = gfc_get_code ();
+ *c = new_st;
+
+ if (gfc_match_eos () != MATCH_YES)
+ goto syntax;
+
+ gfc_clear_new_st ();
+ new_st.op = EXEC_FORALL;
+ new_st.expr = mask;
+ new_st.ext.forall_iterator = head;
+ new_st.block = gfc_get_code ();
+
+ new_st.block->op = EXEC_FORALL;
+ new_st.block->next = c;
+
+ *st = ST_FORALL;
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (ST_FORALL);
+
+cleanup:
+ gfc_free_forall_iterator (head);
+ gfc_free_expr (mask);
+ gfc_free_statements (c);
+ return MATCH_NO;
+}
diff --git a/gcc/fortran/match.h b/gcc/fortran/match.h
new file mode 100644
index 00000000000..25e551caa6c
--- /dev/null
+++ b/gcc/fortran/match.h
@@ -0,0 +1,164 @@
+/* All matcher functions.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Contributed by Steven Bosscher
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#ifndef GFC_MATCH_H
+#define GFC_MATCH_H
+
+#include "gfortran.h"
+
+/* gfc_new_block points to the symbol of a newly matched block. */
+extern gfc_symbol *gfc_new_block;
+
+/* Current statement label. Zero means no statement label. Because
+ new_st can get wiped during statement matching, we have to keep it
+ separate. */
+extern gfc_st_label *gfc_statement_label;
+
+/****************** All gfc_match* routines *****************/
+
+/* match.c */
+
+/* Generic match subroutines */
+match gfc_match_space (void);
+match gfc_match_eos (void);
+match gfc_match_small_literal_int (int *);
+match gfc_match_st_label (gfc_st_label **, int);
+match gfc_match_label (void);
+match gfc_match_small_int (int *);
+int gfc_match_strings (mstring *);
+match gfc_match_name (char *);
+match gfc_match_symbol (gfc_symbol **, int);
+match gfc_match_sym_tree (gfc_symtree **, int);
+match gfc_match_intrinsic_op (gfc_intrinsic_op *);
+match gfc_match_char (char);
+match gfc_match (const char *, ...);
+match gfc_match_iterator (gfc_iterator *, int);
+
+/* Statement matchers */
+match gfc_match_program (void);
+match gfc_match_pointer_assignment (void);
+match gfc_match_assignment (void);
+match gfc_match_if (gfc_statement *);
+match gfc_match_else (void);
+match gfc_match_elseif (void);
+match gfc_match_do (void);
+match gfc_match_cycle (void);
+match gfc_match_exit (void);
+match gfc_match_pause (void);
+match gfc_match_stop (void);
+match gfc_match_continue (void);
+match gfc_match_assign (void);
+match gfc_match_goto (void);
+
+match gfc_match_allocate (void);
+match gfc_match_nullify (void);
+match gfc_match_deallocate (void);
+match gfc_match_return (void);
+match gfc_match_call (void);
+match gfc_match_common (void);
+match gfc_match_implicit_none (void);
+match gfc_match_implicit (void);
+match gfc_match_block_data (void);
+match gfc_match_namelist (void);
+match gfc_match_module (void);
+match gfc_match_equivalence (void);
+match gfc_match_st_function (void);
+match gfc_match_data (void);
+match gfc_match_case (void);
+match gfc_match_select (void);
+match gfc_match_where (gfc_statement *);
+match gfc_match_elsewhere (void);
+match gfc_match_forall (gfc_statement *);
+
+/* decl.c */
+
+match gfc_match_null (gfc_expr **);
+match gfc_match_kind_spec (gfc_typespec *);
+match gfc_match_old_kind_spec (gfc_typespec *);
+match gfc_match_type_spec (gfc_typespec *, int);
+
+match gfc_match_end (gfc_statement *);
+match gfc_match_data_decl (void);
+match gfc_match_formal_arglist (gfc_symbol *, int, int);
+match gfc_match_function_decl (void);
+match gfc_match_entry (void);
+match gfc_match_subroutine (void);
+match gfc_match_derived_decl (void);
+
+/* Matchers for attribute declarations */
+match gfc_match_allocatable (void);
+match gfc_match_dimension (void);
+match gfc_match_external (void);
+match gfc_match_intent (void);
+match gfc_match_intrinsic (void);
+match gfc_match_optional (void);
+match gfc_match_parameter (void);
+match gfc_match_pointer (void);
+match gfc_match_private (gfc_statement *);
+match gfc_match_public (gfc_statement *);
+match gfc_match_save (void);
+match gfc_match_modproc (void);
+match gfc_match_target (void);
+
+/* primary.c */
+match gfc_match_rvalue (gfc_expr **);
+match gfc_match_variable (gfc_expr **, int);
+match gfc_match_actual_arglist (int, gfc_actual_arglist **);
+match gfc_match_literal_constant (gfc_expr **, int);
+
+/* expr.c -- FIXME: this one should be eliminated by moving the
+ matcher to matchexp.c and a call to a new function in expr.c that
+ only makes sure the init expr. is valid. */
+match gfc_match_init_expr (gfc_expr **);
+
+/* array.c */
+match gfc_match_array_spec (gfc_array_spec **);
+match gfc_match_array_ref (gfc_array_ref *, gfc_array_spec *, int);
+match gfc_match_array_constructor (gfc_expr **);
+
+/* interface.c */
+match gfc_match_generic_spec (interface_type *, char *, gfc_intrinsic_op *);
+match gfc_match_interface (void);
+match gfc_match_end_interface (void);
+
+/* io.c */
+match gfc_match_format (void);
+match gfc_match_open (void);
+match gfc_match_close (void);
+match gfc_match_endfile (void);
+match gfc_match_backspace (void);
+match gfc_match_rewind (void);
+match gfc_match_inquire (void);
+match gfc_match_read (void);
+match gfc_match_write (void);
+match gfc_match_print (void);
+
+/* matchexp.c */
+match gfc_match_defined_op_name (char *, int);
+match gfc_match_expr (gfc_expr **);
+
+/* module.c */
+match gfc_match_use (void);
+void gfc_use_module (void);
+
+#endif /* GFC_MATCH_H */
+
diff --git a/gcc/fortran/matchexp.c b/gcc/fortran/matchexp.c
new file mode 100644
index 00000000000..f0c227f95b8
--- /dev/null
+++ b/gcc/fortran/matchexp.c
@@ -0,0 +1,776 @@
+/* Expression parser.
+ Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#include "config.h"
+#include <string.h>
+#include "gfortran.h"
+#include "arith.h"
+#include "match.h"
+
+static char expression_syntax[] = "Syntax error in expression at %C";
+
+
+/* Match a user-defined operator name. This is a normal name with a
+ few restrictions. The error_flag controls whether an error is
+ raised if 'true' or 'false' are used or not. */
+
+match
+gfc_match_defined_op_name (char *result, int error_flag)
+{
+ static const char * const badops[] = {
+ "and", "or", "not", "eqv", "neqv", "eq", "ne", "ge", "le", "lt", "gt",
+ NULL
+ };
+
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ locus old_loc;
+ match m;
+ int i;
+
+ old_loc = *gfc_current_locus ();
+
+ m = gfc_match (" . %n .", name);
+ if (m != MATCH_YES)
+ return m;
+
+ /* .true. and .false. have interpretations as constants. Trying to
+ use these as operators will fail at a later time. */
+
+ if (strcmp (name, "true") == 0 || strcmp (name, "false") == 0)
+ {
+ if (error_flag)
+ goto error;
+ gfc_set_locus (&old_loc);
+ return MATCH_NO;
+ }
+
+ for (i = 0; badops[i]; i++)
+ if (strcmp (badops[i], name) == 0)
+ goto error;
+
+ for (i = 0; name[i]; i++)
+ if (!ISALPHA (name[i]))
+ {
+ gfc_error ("Bad character '%c' in OPERATOR name at %C", name[i]);
+ return MATCH_ERROR;
+ }
+
+ strcpy (result, name);
+ return MATCH_YES;
+
+error:
+ gfc_error ("The name '%s' cannot be used as a defined operator at %C",
+ name);
+
+ gfc_set_locus (&old_loc);
+ return MATCH_ERROR;
+}
+
+
+/* Match a user defined operator. The symbol found must be an
+ operator already. */
+
+static match
+match_defined_operator (gfc_user_op ** result)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ match m;
+
+ m = gfc_match_defined_op_name (name, 0);
+ if (m != MATCH_YES)
+ return m;
+
+ *result = gfc_get_uop (name);
+ return MATCH_YES;
+}
+
+
+/* Check to see if the given operator is next on the input. If this
+ is not the case, the parse pointer remains where it was. */
+
+static int
+next_operator (gfc_intrinsic_op t)
+{
+ gfc_intrinsic_op u;
+ locus old_loc;
+
+ old_loc = *gfc_current_locus ();
+ if (gfc_match_intrinsic_op (&u) == MATCH_YES && t == u)
+ return 1;
+
+ gfc_set_locus (&old_loc);
+ return 0;
+}
+
+
+/* Match a primary expression. */
+
+static match
+match_primary (gfc_expr ** result)
+{
+ match m;
+
+ m = gfc_match_literal_constant (result, 0);
+ if (m != MATCH_NO)
+ return m;
+
+ m = gfc_match_array_constructor (result);
+ if (m != MATCH_NO)
+ return m;
+
+ m = gfc_match_rvalue (result);
+ if (m != MATCH_NO)
+ return m;
+
+ /* Match an expression in parenthesis. */
+ if (gfc_match_char ('(') != MATCH_YES)
+ return MATCH_NO;
+
+ m = gfc_match_expr (result);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ return m;
+
+ m = gfc_match_char (')');
+ if (m == MATCH_NO)
+ gfc_error ("Expected a right parenthesis in expression at %C");
+
+ if (m != MATCH_YES)
+ {
+ gfc_free_expr (*result);
+ return MATCH_ERROR;
+ }
+
+ return MATCH_YES;
+
+syntax:
+ gfc_error (expression_syntax);
+ return MATCH_ERROR;
+}
+
+
+/* Build an operator expression node. */
+
+static gfc_expr *
+build_node (gfc_intrinsic_op operator, locus * where,
+ gfc_expr * op1, gfc_expr * op2)
+{
+ gfc_expr *new;
+
+ new = gfc_get_expr ();
+ new->expr_type = EXPR_OP;
+ new->operator = operator;
+ new->where = *where;
+
+ new->op1 = op1;
+ new->op2 = op2;
+
+ return new;
+}
+
+
+/* Match a level 1 expression. */
+
+static match
+match_level_1 (gfc_expr ** result)
+{
+ gfc_user_op *uop;
+ gfc_expr *e, *f;
+ locus where;
+ match m;
+
+ where = *gfc_current_locus ();
+ uop = NULL;
+ m = match_defined_operator (&uop);
+ if (m == MATCH_ERROR)
+ return m;
+
+ m = match_primary (&e);
+ if (m != MATCH_YES)
+ return m;
+
+ if (uop == NULL)
+ *result = e;
+ else
+ {
+ f = build_node (INTRINSIC_USER, &where, e, NULL);
+ f->uop = uop;
+ *result = f;
+ }
+
+ return MATCH_YES;
+}
+
+
+static match
+match_mult_operand (gfc_expr ** result)
+{
+ gfc_expr *e, *exp, *r;
+ locus where;
+ match m;
+
+ m = match_level_1 (&e);
+ if (m != MATCH_YES)
+ return m;
+
+ if (!next_operator (INTRINSIC_POWER))
+ {
+ *result = e;
+ return MATCH_YES;
+ }
+
+ where = *gfc_current_locus ();
+
+ m = match_mult_operand (&exp);
+ if (m == MATCH_NO)
+ gfc_error ("Expected exponent in expression at %C");
+ if (m != MATCH_YES)
+ {
+ gfc_free_expr (e);
+ return MATCH_ERROR;
+ }
+
+ r = gfc_power (e, exp);
+ if (r == NULL)
+ {
+ gfc_free_expr (e);
+ gfc_free_expr (exp);
+ return MATCH_ERROR;
+ }
+
+ r->where = where;
+ *result = r;
+
+ return MATCH_YES;
+}
+
+
+static match
+match_add_operand (gfc_expr ** result)
+{
+ gfc_expr *all, *e, *total;
+ locus where, old_loc;
+ match m;
+ gfc_intrinsic_op i;
+
+ m = match_mult_operand (&all);
+ if (m != MATCH_YES)
+ return m;
+
+ for (;;)
+ {
+ /* Build up a string of products or quotients. */
+
+ old_loc = *gfc_current_locus ();
+
+ if (next_operator (INTRINSIC_TIMES))
+ i = INTRINSIC_TIMES;
+ else
+ {
+ if (next_operator (INTRINSIC_DIVIDE))
+ i = INTRINSIC_DIVIDE;
+ else
+ break;
+ }
+
+ where = *gfc_current_locus ();
+
+ m = match_mult_operand (&e);
+ if (m == MATCH_NO)
+ {
+ gfc_set_locus (&old_loc);
+ break;
+ }
+
+ if (m == MATCH_ERROR)
+ {
+ gfc_free_expr (all);
+ return MATCH_ERROR;
+ }
+
+ if (i == INTRINSIC_TIMES)
+ total = gfc_multiply (all, e);
+ else
+ total = gfc_divide (all, e);
+
+ if (total == NULL)
+ {
+ gfc_free_expr (all);
+ gfc_free_expr (e);
+ return MATCH_ERROR;
+ }
+
+ all = total;
+ all->where = where;
+ }
+
+ *result = all;
+ return MATCH_YES;
+}
+
+
+static int
+match_add_op (void)
+{
+
+ if (next_operator (INTRINSIC_MINUS))
+ return -1;
+ if (next_operator (INTRINSIC_PLUS))
+ return 1;
+ return 0;
+}
+
+
+/* Match a level 2 expression. */
+
+static match
+match_level_2 (gfc_expr ** result)
+{
+ gfc_expr *all, *e, *total;
+ locus where;
+ match m;
+ int i;
+
+ where = *gfc_current_locus ();
+ i = match_add_op ();
+
+ m = match_add_operand (&e);
+ if (i != 0 && m == MATCH_NO)
+ {
+ gfc_error (expression_syntax);
+ m = MATCH_ERROR;
+ }
+
+ if (m != MATCH_YES)
+ return m;
+
+ if (i == 0)
+ all = e;
+ else
+ {
+ if (i == -1)
+ all = gfc_uminus (e);
+ else
+ all = gfc_uplus (e);
+
+ if (all == NULL)
+ {
+ gfc_free_expr (e);
+ return MATCH_ERROR;
+ }
+ }
+
+ all->where = where;
+
+/* Append add-operands to the sum */
+
+ for (;;)
+ {
+ where = *gfc_current_locus ();
+ i = match_add_op ();
+ if (i == 0)
+ break;
+
+ m = match_add_operand (&e);
+ if (m == MATCH_NO)
+ gfc_error (expression_syntax);
+ if (m != MATCH_YES)
+ {
+ gfc_free_expr (all);
+ return MATCH_ERROR;
+ }
+
+ if (i == -1)
+ total = gfc_subtract (all, e);
+ else
+ total = gfc_add (all, e);
+
+ if (total == NULL)
+ {
+ gfc_free_expr (all);
+ gfc_free_expr (e);
+ return MATCH_ERROR;
+ }
+
+ all = total;
+ all->where = where;
+ }
+
+ *result = all;
+ return MATCH_YES;
+}
+
+
+/* Match a level three expression. */
+
+static match
+match_level_3 (gfc_expr ** result)
+{
+ gfc_expr *all, *e, *total;
+ locus where;
+ match m;
+
+ m = match_level_2 (&all);
+ if (m != MATCH_YES)
+ return m;
+
+ for (;;)
+ {
+ if (!next_operator (INTRINSIC_CONCAT))
+ break;
+
+ where = *gfc_current_locus ();
+
+ m = match_level_2 (&e);
+ if (m == MATCH_NO)
+ {
+ gfc_error (expression_syntax);
+ gfc_free_expr (all);
+ }
+ if (m != MATCH_YES)
+ return MATCH_ERROR;
+
+ total = gfc_concat (all, e);
+ if (total == NULL)
+ {
+ gfc_free_expr (all);
+ gfc_free_expr (e);
+ return MATCH_ERROR;
+ }
+
+ all = total;
+ all->where = where;
+ }
+
+ *result = all;
+ return MATCH_YES;
+}
+
+
+/* Match a level 4 expression. */
+
+static match
+match_level_4 (gfc_expr ** result)
+{
+ gfc_expr *left, *right, *r;
+ gfc_intrinsic_op i;
+ locus old_loc;
+ locus where;
+ match m;
+
+ m = match_level_3 (&left);
+ if (m != MATCH_YES)
+ return m;
+
+ old_loc = *gfc_current_locus ();
+
+ if (gfc_match_intrinsic_op (&i) != MATCH_YES)
+ {
+ *result = left;
+ return MATCH_YES;
+ }
+
+ if (i != INTRINSIC_EQ && i != INTRINSIC_NE && i != INTRINSIC_GE
+ && i != INTRINSIC_LE && i != INTRINSIC_LT && i != INTRINSIC_GT)
+ {
+ gfc_set_locus (&old_loc);
+ *result = left;
+ return MATCH_YES;
+ }
+
+ where = *gfc_current_locus ();
+
+ m = match_level_3 (&right);
+ if (m == MATCH_NO)
+ gfc_error (expression_syntax);
+ if (m != MATCH_YES)
+ {
+ gfc_free_expr (left);
+ return MATCH_ERROR;
+ }
+
+ switch (i)
+ {
+ case INTRINSIC_EQ:
+ r = gfc_eq (left, right);
+ break;
+
+ case INTRINSIC_NE:
+ r = gfc_ne (left, right);
+ break;
+
+ case INTRINSIC_LT:
+ r = gfc_lt (left, right);
+ break;
+
+ case INTRINSIC_LE:
+ r = gfc_le (left, right);
+ break;
+
+ case INTRINSIC_GT:
+ r = gfc_gt (left, right);
+ break;
+
+ case INTRINSIC_GE:
+ r = gfc_ge (left, right);
+ break;
+
+ default:
+ gfc_internal_error ("match_level_4(): Bad operator");
+ }
+
+ if (r == NULL)
+ {
+ gfc_free_expr (left);
+ gfc_free_expr (right);
+ return MATCH_ERROR;
+ }
+
+ r->where = where;
+ *result = r;
+
+ return MATCH_YES;
+}
+
+
+static match
+match_and_operand (gfc_expr ** result)
+{
+ gfc_expr *e, *r;
+ locus where;
+ match m;
+ int i;
+
+ i = next_operator (INTRINSIC_NOT);
+ where = *gfc_current_locus ();
+
+ m = match_level_4 (&e);
+ if (m != MATCH_YES)
+ return m;
+
+ r = e;
+ if (i)
+ {
+ r = gfc_not (e);
+ if (r == NULL)
+ {
+ gfc_free_expr (e);
+ return MATCH_ERROR;
+ }
+ }
+
+ r->where = where;
+ *result = r;
+
+ return MATCH_YES;
+}
+
+
+static match
+match_or_operand (gfc_expr ** result)
+{
+ gfc_expr *all, *e, *total;
+ locus where;
+ match m;
+
+ m = match_and_operand (&all);
+ if (m != MATCH_YES)
+ return m;
+
+ for (;;)
+ {
+ if (!next_operator (INTRINSIC_AND))
+ break;
+ where = *gfc_current_locus ();
+
+ m = match_and_operand (&e);
+ if (m == MATCH_NO)
+ gfc_error (expression_syntax);
+ if (m != MATCH_YES)
+ {
+ gfc_free_expr (all);
+ return MATCH_ERROR;
+ }
+
+ total = gfc_and (all, e);
+ if (total == NULL)
+ {
+ gfc_free_expr (all);
+ gfc_free_expr (e);
+ return MATCH_ERROR;
+ }
+
+ all = total;
+ all->where = where;
+ }
+
+ *result = all;
+ return MATCH_YES;
+}
+
+
+static match
+match_equiv_operand (gfc_expr ** result)
+{
+ gfc_expr *all, *e, *total;
+ locus where;
+ match m;
+
+ m = match_or_operand (&all);
+ if (m != MATCH_YES)
+ return m;
+
+ for (;;)
+ {
+ if (!next_operator (INTRINSIC_OR))
+ break;
+ where = *gfc_current_locus ();
+
+ m = match_or_operand (&e);
+ if (m == MATCH_NO)
+ gfc_error (expression_syntax);
+ if (m != MATCH_YES)
+ {
+ gfc_free_expr (all);
+ return MATCH_ERROR;
+ }
+
+ total = gfc_or (all, e);
+ if (total == NULL)
+ {
+ gfc_free_expr (all);
+ gfc_free_expr (e);
+ return MATCH_ERROR;
+ }
+
+ all = total;
+ all->where = where;
+ }
+
+ *result = all;
+ return MATCH_YES;
+}
+
+
+/* Match a level 5 expression. */
+
+static match
+match_level_5 (gfc_expr ** result)
+{
+ gfc_expr *all, *e, *total;
+ locus where;
+ match m;
+ gfc_intrinsic_op i;
+
+ m = match_equiv_operand (&all);
+ if (m != MATCH_YES)
+ return m;
+
+ for (;;)
+ {
+ if (next_operator (INTRINSIC_EQV))
+ i = INTRINSIC_EQV;
+ else
+ {
+ if (next_operator (INTRINSIC_NEQV))
+ i = INTRINSIC_NEQV;
+ else
+ break;
+ }
+
+ where = *gfc_current_locus ();
+
+ m = match_equiv_operand (&e);
+ if (m == MATCH_NO)
+ gfc_error (expression_syntax);
+ if (m != MATCH_YES)
+ {
+ gfc_free_expr (all);
+ return MATCH_ERROR;
+ }
+
+ if (i == INTRINSIC_EQV)
+ total = gfc_eqv (all, e);
+ else
+ total = gfc_neqv (all, e);
+
+ if (total == NULL)
+ {
+ gfc_free_expr (all);
+ gfc_free_expr (e);
+ return MATCH_ERROR;
+ }
+
+ all = total;
+ all->where = where;
+ }
+
+ *result = all;
+ return MATCH_YES;
+}
+
+
+/* Match an expression. At this level, we are stringing together
+ level 5 expressions separated by binary operators. */
+
+match
+gfc_match_expr (gfc_expr ** result)
+{
+ gfc_expr *all, *e;
+ gfc_user_op *uop;
+ locus where;
+ match m;
+
+ m = match_level_5 (&all);
+ if (m != MATCH_YES)
+ return m;
+
+ for (;;)
+ {
+ m = match_defined_operator (&uop);
+ if (m == MATCH_NO)
+ break;
+ if (m == MATCH_ERROR)
+ {
+ gfc_free_expr (all);
+ return MATCH_ERROR;
+ }
+
+ where = *gfc_current_locus ();
+
+ m = match_level_5 (&e);
+ if (m == MATCH_NO)
+ gfc_error (expression_syntax);
+ if (m != MATCH_YES)
+ {
+ gfc_free_expr (all);
+ return MATCH_ERROR;
+ }
+
+ all = build_node (INTRINSIC_USER, &where, all, e);
+ all->uop = uop;
+ }
+
+ *result = all;
+ return MATCH_YES;
+}
diff --git a/gcc/fortran/mathbuiltins.def b/gcc/fortran/mathbuiltins.def
new file mode 100644
index 00000000000..c46c1d523a5
--- /dev/null
+++ b/gcc/fortran/mathbuiltins.def
@@ -0,0 +1,14 @@
+DEFINE_MATH_BUILTIN (ACOS, "acos", 1)
+DEFINE_MATH_BUILTIN (ASIN, "asin", 1)
+DEFINE_MATH_BUILTIN (ATAN, "atan", 1)
+DEFINE_MATH_BUILTIN (ATAN2, "atan2", 2)
+DEFINE_MATH_BUILTIN (COS, "cos", 1)
+DEFINE_MATH_BUILTIN (COSH, "cosh", 1)
+DEFINE_MATH_BUILTIN (EXP, "exp", 1)
+DEFINE_MATH_BUILTIN (LOG, "log", 1)
+DEFINE_MATH_BUILTIN (LOG10, "log10", 1)
+DEFINE_MATH_BUILTIN (SIN, "sin", 1)
+DEFINE_MATH_BUILTIN (SINH, "sinh", 1)
+DEFINE_MATH_BUILTIN (SQRT, "sqrt", 1)
+DEFINE_MATH_BUILTIN (TAN, "tan", 1)
+DEFINE_MATH_BUILTIN (TANH, "tanh", 1)
diff --git a/gcc/fortran/misc.c b/gcc/fortran/misc.c
new file mode 100644
index 00000000000..3ef95db31e5
--- /dev/null
+++ b/gcc/fortran/misc.c
@@ -0,0 +1,327 @@
+/* Miscellaneous stuff that doesn't fit anywhere else.
+ Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#include "config.h"
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include "gfortran.h"
+
+
+/* Get a block of memory. Many callers assume that the memory we
+ return is zeroed. */
+
+void *
+gfc_getmem (size_t n)
+{
+ void *p;
+
+ if (n == 0)
+ return NULL;
+
+ p = xmalloc (n);
+ if (p == NULL)
+ gfc_fatal_error ("Out of memory-- malloc() failed");
+ memset (p, 0, n);
+ return p;
+}
+
+
+/* gfortran.h defines free to something that triggers a syntax error,
+ but we need free() here. */
+
+#define temp free
+#undef free
+
+void
+gfc_free (void *p)
+{
+
+ if (p != NULL)
+ free (p);
+}
+
+#define free temp
+#undef temp
+
+
+/* Get terminal width */
+
+int
+gfc_terminal_width(void)
+{
+ return 80;
+}
+
+
+/* Initialize a typespec to unknown. */
+
+void
+gfc_clear_ts (gfc_typespec * ts)
+{
+
+ ts->type = BT_UNKNOWN;
+ ts->kind = 0;
+ ts->derived = NULL;
+ ts->cl = NULL;
+}
+
+
+/* Open a file for reading. */
+
+FILE *
+gfc_open_file (const char *name)
+{
+ struct stat statbuf;
+
+ if (!*name)
+ return stdin;
+
+ if (stat (name, &statbuf) < 0)
+ return NULL;
+
+ if (!S_ISREG (statbuf.st_mode))
+ return NULL;
+
+ return fopen (name, "r");
+}
+
+
+/* Given a word, return the correct article. */
+
+const char *
+gfc_article (const char *word)
+{
+ const char *p;
+
+ switch (*word)
+ {
+ case 'a':
+ case 'A':
+ case 'e':
+ case 'E':
+ case 'i':
+ case 'I':
+ case 'o':
+ case 'O':
+ case 'u':
+ case 'U':
+ p = "an";
+ break;
+
+ default:
+ p = "a";
+ }
+
+ return p;
+}
+
+
+/* Return a string for each type. */
+
+const char *
+gfc_basic_typename (bt type)
+{
+ const char *p;
+
+ switch (type)
+ {
+ case BT_INTEGER:
+ p = "INTEGER";
+ break;
+ case BT_REAL:
+ p = "REAL";
+ break;
+ case BT_COMPLEX:
+ p = "COMPLEX";
+ break;
+ case BT_LOGICAL:
+ p = "LOGICAL";
+ break;
+ case BT_CHARACTER:
+ p = "CHARACTER";
+ break;
+ case BT_DERIVED:
+ p = "DERIVED";
+ break;
+ case BT_PROCEDURE:
+ p = "PROCEDURE";
+ break;
+ case BT_UNKNOWN:
+ p = "UNKNOWN";
+ break;
+ default:
+ gfc_internal_error ("gfc_basic_typename(): Undefined type");
+ }
+
+ return p;
+}
+
+
+/* Return a string descibing the type and kind of a typespec. Because
+ we return alternating buffers, this subroutine can appear twice in
+ the argument list of a single statement. */
+
+const char *
+gfc_typename (gfc_typespec * ts)
+{
+ static char buffer1[60], buffer2[60];
+ static int flag = 0;
+ char *buffer;
+
+ buffer = flag ? buffer1 : buffer2;
+ flag = !flag;
+
+ switch (ts->type)
+ {
+ case BT_INTEGER:
+ sprintf (buffer, "INTEGER(%d)", ts->kind);
+ break;
+ case BT_REAL:
+ sprintf (buffer, "REAL(%d)", ts->kind);
+ break;
+ case BT_COMPLEX:
+ sprintf (buffer, "COMPLEX(%d)", ts->kind);
+ break;
+ case BT_LOGICAL:
+ sprintf (buffer, "LOGICAL(%d)", ts->kind);
+ break;
+ case BT_CHARACTER:
+ sprintf (buffer, "CHARACTER(%d)", ts->kind);
+ break;
+ case BT_DERIVED:
+ sprintf (buffer, "TYPE(%s)", ts->derived->name);
+ break;
+ case BT_PROCEDURE:
+ strcpy (buffer, "PROCEDURE");
+ break;
+ case BT_UNKNOWN:
+ strcpy (buffer, "UNKNOWN");
+ break;
+ default:
+ gfc_internal_error ("gfc_typespec(): Undefined type");
+ }
+
+ return buffer;
+}
+
+
+/* Given an mstring array and a code, locate the code in the table,
+ returning a pointer to the string. */
+
+const char *
+gfc_code2string (const mstring * m, int code)
+{
+
+ while (m->string != NULL)
+ {
+ if (m->tag == code)
+ return m->string;
+ m++;
+ }
+
+ gfc_internal_error ("gfc_code2string(): Bad code");
+ /* Not reached */
+}
+
+
+/* Given an mstring array and a string, returns the value of the tag
+ field. Returns the final tag if no matches to the string are
+ found. */
+
+int
+gfc_string2code (const mstring * m, const char *string)
+{
+
+ for (; m->string != NULL; m++)
+ if (strcmp (m->string, string) == 0)
+ return m->tag;
+
+ return m->tag;
+}
+
+
+/* Convert an intent code to a string. */
+/* TODO: move to gfortran.h as define. */
+const char *
+gfc_intent_string (sym_intent i)
+{
+
+ return gfc_code2string (intents, i);
+}
+
+
+/***************** Initialization functions ****************/
+
+/* Top level initialization. */
+
+void
+gfc_init_1 (void)
+{
+
+ gfc_error_init_1 ();
+ gfc_scanner_init_1 ();
+ gfc_arith_init_1 ();
+ gfc_intrinsic_init_1 ();
+ gfc_iresolve_init_1 ();
+ gfc_simplify_init_1 ();
+}
+
+
+/* Per program unit initialization. */
+
+void
+gfc_init_2 (void)
+{
+
+ gfc_symbol_init_2 ();
+ gfc_module_init_2 ();
+}
+
+
+/******************* Destructor functions ******************/
+
+/* Call all of the top level destructors. */
+
+void
+gfc_done_1 (void)
+{
+
+ gfc_scanner_done_1 ();
+ gfc_intrinsic_done_1 ();
+ gfc_simplify_done_1 ();
+ gfc_iresolve_done_1 ();
+ gfc_arith_done_1 ();
+}
+
+
+/* Per program unit destructors. */
+
+void
+gfc_done_2 (void)
+{
+
+ gfc_symbol_done_2 ();
+ gfc_module_done_2 ();
+}
+
diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c
new file mode 100644
index 00000000000..566e3f330c7
--- /dev/null
+++ b/gcc/fortran/module.c
@@ -0,0 +1,3459 @@
+/* Handle modules, which amounts to loading and saving symbols and
+ their attendant structures.
+ Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* The syntax of g95 modules resembles that of lisp lists, ie a
+ sequence of atoms, which can be left or right parenthesis, names,
+ integers or strings. Parenthesis are always matched which allows
+ us to skip over sections at high speed without having to know
+ anything about the internal structure of the lists. A "name" is
+ usually a fortran 95 identifier, but can also start with '@' in
+ order to reference a hidden symbol.
+
+ The first line of a module is an informational message about what
+ created the module, the file it came from and when it was created.
+ The second line is a warning for people not to edit the module.
+ The rest of the module looks like:
+
+ ( ( <Interface info for UPLUS> )
+ ( <Interface info for UMINUS> )
+ ...
+ )
+ ( ( <name of operator interface> <module of op interface> <i/f1> ... )
+ ...
+ )
+ ( ( <name of generic interface> <module of generic interface> <i/f1> ... )
+ ...
+ )
+ ( <Symbol Number (in no particular order)>
+ <True name of symbol>
+ <Module name of symbol>
+ ( <symbol information> )
+ ...
+ )
+ ( <Symtree name>
+ <Ambiguous flag>
+ <Symbol number>
+ ...
+ )
+
+ In general, symbols refer to other symbols by their symbol number,
+ which are zero based. Symbols are written to the module in no
+ particular order. */
+
+#include "config.h"
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <time.h>
+
+#include "gfortran.h"
+#include "match.h"
+#include "parse.h" /* FIXME */
+
+#define MODULE_EXTENSION ".mod"
+
+
+/* Structure that descibes a position within a module file */
+
+typedef struct
+{
+ int column, line;
+ fpos_t pos;
+}
+module_locus;
+
+
+typedef enum
+{
+ P_UNKNOWN = 0, P_OTHER, P_NAMESPACE, P_COMPONENT, P_SYMBOL
+}
+pointer_t;
+
+/* The fixup structure lists pointers to pointers that have to
+ be updated when a pointer value becomes known. */
+
+typedef struct fixup_t
+{
+ void **pointer;
+ struct fixup_t *next;
+}
+fixup_t;
+
+
+/* Structure for holding extra info needed for pointers being read */
+
+typedef struct pointer_info
+{
+ BBT_HEADER (pointer_info);
+ int integer;
+ pointer_t type;
+
+ /* The first component of each member of the union is the pointer
+ being stored */
+
+ fixup_t *fixup;
+
+ union
+ {
+ void *pointer; /* Member for doing pointer searches */
+
+ struct
+ {
+ gfc_symbol *sym;
+ char true_name[GFC_MAX_SYMBOL_LEN + 1], module[GFC_MAX_SYMBOL_LEN + 1];
+ enum
+ { UNUSED, NEEDED, USED }
+ state;
+ int ns, referenced;
+ module_locus where;
+ fixup_t *stfixup;
+ gfc_symtree *symtree;
+ }
+ rsym;
+
+ struct
+ {
+ gfc_symbol *sym;
+ enum
+ { UNREFERENCED = 0, NEEDS_WRITE, WRITTEN }
+ state;
+ }
+ wsym;
+ }
+ u;
+
+}
+pointer_info;
+
+#define gfc_get_pointer_info() gfc_getmem(sizeof(pointer_info))
+
+
+/* Lists of rename info for the USE statement */
+
+typedef struct gfc_use_rename
+{
+ char local_name[GFC_MAX_SYMBOL_LEN + 1], use_name[GFC_MAX_SYMBOL_LEN + 1];
+ struct gfc_use_rename *next;
+ int found;
+ gfc_intrinsic_op operator;
+ locus where;
+}
+gfc_use_rename;
+
+#define gfc_get_use_rename() gfc_getmem(sizeof(gfc_use_rename))
+
+/* Local variables */
+
+/* The FILE for the module we're reading or writing. */
+static FILE *module_fp;
+
+/* The name of the module we're reading (USE'ing) or writing. */
+static char module_name[GFC_MAX_SYMBOL_LEN + 1];
+
+static int module_line, module_column, only_flag;
+static enum
+{ IO_INPUT, IO_OUTPUT }
+iomode;
+
+static gfc_use_rename *gfc_rename_list;
+static pointer_info *pi_root;
+static int symbol_number; /* Counter for assigning symbol numbers */
+
+
+
+/*****************************************************************/
+
+/* Pointer/integer conversion. Pointers between structures are stored
+ as integers in the module file. The next couple of subroutines
+ handle this translation for reading and writing. */
+
+/* Recursively free the tree of pointer structures. */
+
+static void
+free_pi_tree (pointer_info * p)
+{
+
+ if (p == NULL)
+ return;
+
+ if (p->fixup != NULL)
+ gfc_internal_error ("free_pi_tree(): Unresolved fixup");
+
+ free_pi_tree (p->left);
+ free_pi_tree (p->right);
+
+ gfc_free (p);
+}
+
+
+/* Compare pointers when searching by pointer. Used when writing a
+ module. */
+
+static int
+compare_pointers (void * _sn1, void * _sn2)
+{
+ pointer_info *sn1, *sn2;
+
+ sn1 = (pointer_info *) _sn1;
+ sn2 = (pointer_info *) _sn2;
+
+ if (sn1->u.pointer < sn2->u.pointer)
+ return -1;
+ if (sn1->u.pointer > sn2->u.pointer)
+ return 1;
+
+ return 0;
+}
+
+
+/* Compare integers when searching by integer. Used when reading a
+ module. */
+
+static int
+compare_integers (void * _sn1, void * _sn2)
+{
+ pointer_info *sn1, *sn2;
+
+ sn1 = (pointer_info *) _sn1;
+ sn2 = (pointer_info *) _sn2;
+
+ if (sn1->integer < sn2->integer)
+ return -1;
+ if (sn1->integer > sn2->integer)
+ return 1;
+
+ return 0;
+}
+
+
+/* Initialize the pointer_info tree. */
+
+static void
+init_pi_tree (void)
+{
+ compare_fn compare;
+ pointer_info *p;
+
+ pi_root = NULL;
+ compare = (iomode == IO_INPUT) ? compare_integers : compare_pointers;
+
+ /* Pointer 0 is the NULL pointer. */
+ p = gfc_get_pointer_info ();
+ p->u.pointer = NULL;
+ p->integer = 0;
+ p->type = P_OTHER;
+
+ gfc_insert_bbt (&pi_root, p, compare);
+
+ /* Pointer 1 is the current namespace. */
+ p = gfc_get_pointer_info ();
+ p->u.pointer = gfc_current_ns;
+ p->integer = 1;
+ p->type = P_NAMESPACE;
+
+ gfc_insert_bbt (&pi_root, p, compare);
+
+ symbol_number = 2;
+}
+
+
+/* During module writing, call here with a pointer to something,
+ returning the pointer_info node. */
+
+static pointer_info *
+find_pointer (void *gp)
+{
+ pointer_info *p;
+
+ p = pi_root;
+ while (p != NULL)
+ {
+ if (p->u.pointer == gp)
+ break;
+ p = (gp < p->u.pointer) ? p->left : p->right;
+ }
+
+ return p;
+}
+
+
+/* Given a pointer while writing, returns the pointer_info tree node,
+ creating it if it doesn't exist. */
+
+static pointer_info *
+get_pointer (void *gp)
+{
+ pointer_info *p;
+
+ p = find_pointer (gp);
+ if (p != NULL)
+ return p;
+
+ /* Pointer doesn't have an integer. Give it one. */
+ p = gfc_get_pointer_info ();
+
+ p->u.pointer = gp;
+ p->integer = symbol_number++;
+
+ gfc_insert_bbt (&pi_root, p, compare_pointers);
+
+ return p;
+}
+
+
+/* Given an integer during reading, find it in the pointer_info tree,
+ creating the node if not found. */
+
+static pointer_info *
+get_integer (int integer)
+{
+ pointer_info *p, t;
+ int c;
+
+ t.integer = integer;
+
+ p = pi_root;
+ while (p != NULL)
+ {
+ c = compare_integers (&t, p);
+ if (c == 0)
+ break;
+
+ p = (c < 0) ? p->left : p->right;
+ }
+
+ if (p != NULL)
+ return p;
+
+ p = gfc_get_pointer_info ();
+ p->integer = integer;
+ p->u.pointer = NULL;
+
+ gfc_insert_bbt (&pi_root, p, compare_integers);
+
+ return p;
+}
+
+
+/* Recursive function to find a pointer within a tree by brute force. */
+
+static pointer_info *
+fp2 (pointer_info * p, const void *target)
+{
+ pointer_info *q;
+
+ if (p == NULL)
+ return NULL;
+
+ if (p->u.pointer == target)
+ return p;
+
+ q = fp2 (p->left, target);
+ if (q != NULL)
+ return q;
+
+ return fp2 (p->right, target);
+}
+
+
+/* During reading, find a pointer_info node from the pointer value.
+ This amounts to a brute-force search. */
+
+static pointer_info *
+find_pointer2 (void *p)
+{
+
+ return fp2 (pi_root, p);
+}
+
+
+/* Resolve any fixups using a known pointer. */
+static void
+resolve_fixups (fixup_t *f, void * gp)
+{
+ fixup_t *next;
+
+ for (; f; f = next)
+ {
+ next = f->next;
+ *(f->pointer) = gp;
+ gfc_free (f);
+ }
+}
+
+/* Call here during module reading when we know what pointer to
+ associate with an integer. Any fixups that exist are resolved at
+ this time. */
+
+static void
+associate_integer_pointer (pointer_info * p, void *gp)
+{
+ if (p->u.pointer != NULL)
+ gfc_internal_error ("associate_integer_pointer(): Already associated");
+
+ p->u.pointer = gp;
+
+ resolve_fixups (p->fixup, gp);
+
+ p->fixup = NULL;
+}
+
+
+/* During module reading, given an integer and a pointer to a pointer,
+ either store the pointer from an already-known value or create a
+ fixup structure in order to store things later. Returns zero if
+ the reference has been actually stored, or nonzero if the reference
+ must be fixed later (ie associate_integer_pointer must be called
+ sometime later. Returns the pointer_info structure. */
+
+static pointer_info *
+add_fixup (int integer, void *gp)
+{
+ pointer_info *p;
+ fixup_t *f;
+ char **cp;
+
+ p = get_integer (integer);
+
+ if (p->integer == 0 || p->u.pointer != NULL)
+ {
+ cp = gp;
+ *cp = p->u.pointer;
+ }
+ else
+ {
+ f = gfc_getmem (sizeof (fixup_t));
+
+ f->next = p->fixup;
+ p->fixup = f;
+
+ f->pointer = gp;
+ }
+
+ return p;
+}
+
+
+/*****************************************************************/
+
+/* Parser related subroutines */
+
+/* Free the rename list left behind by a USE statement. */
+
+static void
+free_rename (void)
+{
+ gfc_use_rename *next;
+
+ for (; gfc_rename_list; gfc_rename_list = next)
+ {
+ next = gfc_rename_list->next;
+ gfc_free (gfc_rename_list);
+ }
+}
+
+
+/* Match a USE statement. */
+
+match
+gfc_match_use (void)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_use_rename *tail = NULL, *new;
+ interface_type type;
+ gfc_intrinsic_op operator;
+ match m;
+
+ m = gfc_match_name (module_name);
+ if (m != MATCH_YES)
+ return m;
+
+ free_rename ();
+ only_flag = 0;
+
+ if (gfc_match_eos () == MATCH_YES)
+ return MATCH_YES;
+ if (gfc_match_char (',') != MATCH_YES)
+ goto syntax;
+
+ if (gfc_match (" only :") == MATCH_YES)
+ only_flag = 1;
+
+ if (gfc_match_eos () == MATCH_YES)
+ return MATCH_YES;
+
+ for (;;)
+ {
+ /* Get a new rename struct and add it to the rename list. */
+ new = gfc_get_use_rename ();
+ new->where = *gfc_current_locus ();
+ new->found = 0;
+
+ if (gfc_rename_list == NULL)
+ gfc_rename_list = new;
+ else
+ tail->next = new;
+ tail = new;
+
+ /* See what kind of interface we're dealing with. Asusume it is
+ not an operator. */
+ new->operator = INTRINSIC_NONE;
+ if (gfc_match_generic_spec (&type, name, &operator) == MATCH_ERROR)
+ goto cleanup;
+
+ switch (type)
+ {
+ case INTERFACE_NAMELESS:
+ gfc_error ("Missing generic specification in USE statement at %C");
+ goto cleanup;
+
+ case INTERFACE_GENERIC:
+ m = gfc_match (" =>");
+
+ if (only_flag)
+ {
+ if (m != MATCH_YES)
+ strcpy (new->use_name, name);
+ else
+ {
+ strcpy (new->local_name, name);
+
+ m = gfc_match_name (new->use_name);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ }
+ }
+ else
+ {
+ if (m != MATCH_YES)
+ goto syntax;
+ strcpy (new->local_name, name);
+
+ m = gfc_match_name (new->use_name);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ }
+
+ break;
+
+ case INTERFACE_USER_OP:
+ strcpy (new->use_name, name);
+ /* Fall through */
+
+ case INTERFACE_INTRINSIC_OP:
+ new->operator = operator;
+ break;
+ }
+
+ if (gfc_match_eos () == MATCH_YES)
+ break;
+ if (gfc_match_char (',') != MATCH_YES)
+ goto syntax;
+ }
+
+ return MATCH_YES;
+
+syntax:
+ gfc_syntax_error (ST_USE);
+
+cleanup:
+ free_rename ();
+ return MATCH_ERROR;
+}
+
+
+/* Given a name, return the name under which to load this symbol.
+ Returns NULL if this symbol shouldn't be loaded. */
+
+static const char *
+find_use_name (const char *name)
+{
+ gfc_use_rename *u;
+
+ for (u = gfc_rename_list; u; u = u->next)
+ if (strcmp (u->use_name, name) == 0)
+ break;
+
+ if (u == NULL)
+ return only_flag ? NULL : name;
+
+ u->found = 1;
+
+ return (u->local_name[0] != '\0') ? u->local_name : name;
+}
+
+
+/* Try to find the operator in the current list. */
+
+static gfc_use_rename *
+find_use_operator (gfc_intrinsic_op operator)
+{
+ gfc_use_rename *u;
+
+ for (u = gfc_rename_list; u; u = u->next)
+ if (u->operator == operator)
+ return u;
+
+ return NULL;
+}
+
+
+/*****************************************************************/
+
+/* The next couple of subroutines maintain a tree used to avoid a
+ brute-force search for a combination of true name and module name.
+ While symtree names, the name that a particular symbol is known by
+ can changed with USE statements, we still have to keep track of the
+ true names to generate the correct reference, and also avoid
+ loading the same real symbol twice in a program unit.
+
+ When we start reading, the true name tree is built and maintained
+ as symbols are read. The tree is searched as we load new symbols
+ to see if it already exists someplace in the namespace. */
+
+typedef struct true_name
+{
+ BBT_HEADER (true_name);
+ gfc_symbol *sym;
+}
+true_name;
+
+static true_name *true_name_root;
+
+
+/* Compare two true_name structures. */
+
+static int
+compare_true_names (void * _t1, void * _t2)
+{
+ true_name *t1, *t2;
+ int c;
+
+ t1 = (true_name *) _t1;
+ t2 = (true_name *) _t2;
+
+ c = strcmp (t1->sym->module, t2->sym->module);
+ if (c != 0)
+ return c;
+
+ return strcmp (t1->sym->name, t2->sym->name);
+}
+
+
+/* Given a true name, search the true name tree to see if it exists
+ within the main namespace. */
+
+static gfc_symbol *
+find_true_name (const char *name, const char *module)
+{
+ true_name t, *p;
+ gfc_symbol sym;
+ int c;
+
+ strcpy (sym.name, name);
+ strcpy (sym.module, module);
+ t.sym = &sym;
+
+ p = true_name_root;
+ while (p != NULL)
+ {
+ c = compare_true_names ((void *)(&t), (void *) p);
+ if (c == 0)
+ return p->sym;
+
+ p = (c < 0) ? p->left : p->right;
+ }
+
+ return NULL;
+}
+
+
+/* Given a gfc_symbol pointer that is not in the true name tree, add
+ it. */
+
+static void
+add_true_name (gfc_symbol * sym)
+{
+ true_name *t;
+
+ t = gfc_getmem (sizeof (true_name));
+ t->sym = sym;
+
+ gfc_insert_bbt (&true_name_root, t, compare_true_names);
+}
+
+
+/* Recursive function to build the initial true name tree by
+ recursively traversing the current namespace. */
+
+static void
+build_tnt (gfc_symtree * st)
+{
+
+ if (st == NULL)
+ return;
+
+ build_tnt (st->left);
+ build_tnt (st->right);
+
+ if (find_true_name (st->n.sym->name, st->n.sym->module) != NULL)
+ return;
+
+ add_true_name (st->n.sym);
+}
+
+
+/* Initialize the true name tree with the current namespace. */
+
+static void
+init_true_name_tree (void)
+{
+ true_name_root = NULL;
+
+ build_tnt (gfc_current_ns->sym_root);
+}
+
+
+/* Recursively free a true name tree node. */
+
+static void
+free_true_name (true_name * t)
+{
+
+ if (t == NULL)
+ return;
+ free_true_name (t->left);
+ free_true_name (t->right);
+
+ gfc_free (t);
+}
+
+
+/*****************************************************************/
+
+/* Module reading and writing. */
+
+typedef enum
+{
+ ATOM_NAME, ATOM_LPAREN, ATOM_RPAREN, ATOM_INTEGER, ATOM_STRING
+}
+atom_type;
+
+static atom_type last_atom;
+
+
+/* The name buffer must be at least as long as a symbol name. Right
+ now it's not clear how we're going to store numeric constants--
+ probably as a hexadecimal string, since this will allow the exact
+ number to be preserved (this can't be done by a decimal
+ representation). Worry about that later. TODO! */
+
+#define MAX_ATOM_SIZE 100
+
+static int atom_int;
+static char *atom_string, atom_name[MAX_ATOM_SIZE];
+
+
+/* Report problems with a module. Error reporting is not very
+ elaborate, since this sorts of errors shouldn't really happen.
+ This subroutine never returns. */
+
+static void bad_module (const char *) ATTRIBUTE_NORETURN;
+
+static void
+bad_module (const char *message)
+{
+ const char *p;
+
+ switch (iomode)
+ {
+ case IO_INPUT:
+ p = "Reading";
+ break;
+ case IO_OUTPUT:
+ p = "Writing";
+ break;
+ default:
+ p = "???";
+ break;
+ }
+
+ fclose (module_fp);
+
+ gfc_fatal_error ("%s module %s at line %d column %d: %s", p,
+ module_name, module_line, module_column, message);
+}
+
+
+/* Set the module's input pointer. */
+
+static void
+set_module_locus (module_locus * m)
+{
+
+ module_column = m->column;
+ module_line = m->line;
+ fsetpos (module_fp, &m->pos);
+}
+
+
+/* Get the module's input pointer so that we can restore it later. */
+
+static void
+get_module_locus (module_locus * m)
+{
+
+ m->column = module_column;
+ m->line = module_line;
+ fgetpos (module_fp, &m->pos);
+}
+
+
+/* Get the next character in the module, updating our reckoning of
+ where we are. */
+
+static int
+module_char (void)
+{
+ int c;
+
+ c = fgetc (module_fp);
+
+ if (c == EOF)
+ bad_module ("Unexpected EOF");
+
+ if (c == '\n')
+ {
+ module_line++;
+ module_column = 0;
+ }
+
+ module_column++;
+ return c;
+}
+
+
+/* Parse a string constant. The delimiter is guaranteed to be a
+ single quote. */
+
+static void
+parse_string (void)
+{
+ module_locus start;
+ int len, c;
+ char *p;
+
+ get_module_locus (&start);
+
+ len = 0;
+
+ /* See how long the string is */
+ for ( ; ; )
+ {
+ c = module_char ();
+ if (c == EOF)
+ bad_module ("Unexpected end of module in string constant");
+
+ if (c != '\'')
+ {
+ len++;
+ continue;
+ }
+
+ c = module_char ();
+ if (c == '\'')
+ {
+ len++;
+ continue;
+ }
+
+ break;
+ }
+
+ set_module_locus (&start);
+
+ atom_string = p = gfc_getmem (len + 1);
+
+ for (; len > 0; len--)
+ {
+ c = module_char ();
+ if (c == '\'')
+ module_char (); /* Guaranteed to be another \' */
+ *p++ = c;
+ }
+
+ module_char (); /* Terminating \' */
+ *p = '\0'; /* C-style string for debug purposes */
+}
+
+
+/* Parse a small integer. */
+
+static void
+parse_integer (int c)
+{
+ module_locus m;
+
+ atom_int = c - '0';
+
+ for (;;)
+ {
+ get_module_locus (&m);
+
+ c = module_char ();
+ if (!ISDIGIT (c))
+ break;
+
+ atom_int = 10 * atom_int + c - '0';
+ if (atom_int > 99999999)
+ bad_module ("Integer overflow");
+ }
+
+ set_module_locus (&m);
+}
+
+
+/* Parse a name. */
+
+static void
+parse_name (int c)
+{
+ module_locus m;
+ char *p;
+ int len;
+
+ p = atom_name;
+
+ *p++ = c;
+ len = 1;
+
+ get_module_locus (&m);
+
+ for (;;)
+ {
+ c = module_char ();
+ if (!ISALNUM (c) && c != '_' && c != '-')
+ break;
+
+ *p++ = c;
+ if (++len > GFC_MAX_SYMBOL_LEN)
+ bad_module ("Name too long");
+ }
+
+ *p = '\0';
+
+ fseek (module_fp, -1, SEEK_CUR);
+ module_column = m.column + len - 1;
+
+ if (c == '\n')
+ module_line--;
+}
+
+
+/* Read the next atom in the module's input stream. */
+
+static atom_type
+parse_atom (void)
+{
+ int c;
+
+ do
+ {
+ c = module_char ();
+ }
+ while (c == ' ' || c == '\n');
+
+ switch (c)
+ {
+ case '(':
+ return ATOM_LPAREN;
+
+ case ')':
+ return ATOM_RPAREN;
+
+ case '\'':
+ parse_string ();
+ return ATOM_STRING;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ parse_integer (c);
+ return ATOM_INTEGER;
+
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ case 'g':
+ case 'h':
+ case 'i':
+ case 'j':
+ case 'k':
+ case 'l':
+ case 'm':
+ case 'n':
+ case 'o':
+ case 'p':
+ case 'q':
+ case 'r':
+ case 's':
+ case 't':
+ case 'u':
+ case 'v':
+ case 'w':
+ case 'x':
+ case 'y':
+ case 'z':
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ case 'G':
+ case 'H':
+ case 'I':
+ case 'J':
+ case 'K':
+ case 'L':
+ case 'M':
+ case 'N':
+ case 'O':
+ case 'P':
+ case 'Q':
+ case 'R':
+ case 'S':
+ case 'T':
+ case 'U':
+ case 'V':
+ case 'W':
+ case 'X':
+ case 'Y':
+ case 'Z':
+ parse_name (c);
+ return ATOM_NAME;
+
+ default:
+ bad_module ("Bad name");
+ }
+
+ /* Not reached */
+}
+
+
+/* Peek at the next atom on the input. */
+
+static atom_type
+peek_atom (void)
+{
+ module_locus m;
+ atom_type a;
+
+ get_module_locus (&m);
+
+ a = parse_atom ();
+ if (a == ATOM_STRING)
+ gfc_free (atom_string);
+
+ set_module_locus (&m);
+ return a;
+}
+
+
+/* Read the next atom from the input, requiring that it be a
+ particular kind. */
+
+static void
+require_atom (atom_type type)
+{
+ module_locus m;
+ atom_type t;
+ const char *p;
+
+ get_module_locus (&m);
+
+ t = parse_atom ();
+ if (t != type)
+ {
+ switch (type)
+ {
+ case ATOM_NAME:
+ p = "Expected name";
+ break;
+ case ATOM_LPAREN:
+ p = "Expected left parenthesis";
+ break;
+ case ATOM_RPAREN:
+ p = "Expected right parenthesis";
+ break;
+ case ATOM_INTEGER:
+ p = "Expected integer";
+ break;
+ case ATOM_STRING:
+ p = "Expected string";
+ break;
+ default:
+ gfc_internal_error ("require_atom(): bad atom type required");
+ }
+
+ set_module_locus (&m);
+ bad_module (p);
+ }
+}
+
+
+/* Given a pointer to an mstring array, require that the current input
+ be one of the strings in the array. We return the enum value. */
+
+static int
+find_enum (const mstring * m)
+{
+ int i;
+
+ i = gfc_string2code (m, atom_name);
+ if (i >= 0)
+ return i;
+
+ bad_module ("find_enum(): Enum not found");
+
+ /* Not reached */
+}
+
+
+/**************** Module output subroutines ***************************/
+
+/* Output a character to a module file. */
+
+static void
+write_char (char out)
+{
+
+ if (fputc (out, module_fp) == EOF)
+ gfc_fatal_error ("Error writing modules file: %s", strerror (errno));
+
+ if (out != '\n')
+ module_column++;
+ else
+ {
+ module_column = 1;
+ module_line++;
+ }
+}
+
+
+/* Write an atom to a module. The line wrapping isn't perfect, but it
+ should work most of the time. This isn't that big of a deal, since
+ the file really isn't meant to be read by people anyway. */
+
+static void
+write_atom (atom_type atom, const void *v)
+{
+ char buffer[20];
+ int i, len;
+ const char *p;
+
+ switch (atom)
+ {
+ case ATOM_STRING:
+ case ATOM_NAME:
+ p = v;
+ break;
+
+ case ATOM_LPAREN:
+ p = "(";
+ break;
+
+ case ATOM_RPAREN:
+ p = ")";
+ break;
+
+ case ATOM_INTEGER:
+ i = *((const int *) v);
+ if (i < 0)
+ gfc_internal_error ("write_atom(): Writing negative integer");
+
+ sprintf (buffer, "%d", i);
+ p = buffer;
+ break;
+
+ default:
+ gfc_internal_error ("write_atom(): Trying to write dab atom");
+
+ }
+
+ len = strlen (p);
+
+ if (atom != ATOM_RPAREN)
+ {
+ if (module_column + len > 72)
+ write_char ('\n');
+ else
+ {
+
+ if (last_atom != ATOM_LPAREN && module_column != 1)
+ write_char (' ');
+ }
+ }
+
+ if (atom == ATOM_STRING)
+ write_char ('\'');
+
+ while (*p)
+ {
+ if (atom == ATOM_STRING && *p == '\'')
+ write_char ('\'');
+ write_char (*p++);
+ }
+
+ if (atom == ATOM_STRING)
+ write_char ('\'');
+
+ last_atom = atom;
+}
+
+
+
+/***************** Mid-level I/O subroutines *****************/
+
+/* These subroutines let their caller read or write atoms without
+ caring about which of the two is actually happening. This lets a
+ subroutine concentrate on the actual format of the data being
+ written. */
+
+static void mio_expr (gfc_expr **);
+static void mio_symbol_ref (gfc_symbol **);
+static void mio_symtree_ref (gfc_symtree **);
+
+/* Read or write an enumerated value. On writing, we return the input
+ value for the convenience of callers. We avoid using an integer
+ pointer because enums are sometimes inside bitfields. */
+
+static int
+mio_name (int t, const mstring * m)
+{
+
+ if (iomode == IO_OUTPUT)
+ write_atom (ATOM_NAME, gfc_code2string (m, t));
+ else
+ {
+ require_atom (ATOM_NAME);
+ t = find_enum (m);
+ }
+
+ return t;
+}
+
+/* Specialisation of mio_name. */
+
+#define DECL_MIO_NAME(TYPE) \
+ static inline TYPE \
+ MIO_NAME(TYPE) (TYPE t, const mstring * m) \
+ { \
+ return (TYPE)mio_name ((int)t, m); \
+ }
+#define MIO_NAME(TYPE) mio_name_##TYPE
+
+static void
+mio_lparen (void)
+{
+
+ if (iomode == IO_OUTPUT)
+ write_atom (ATOM_LPAREN, NULL);
+ else
+ require_atom (ATOM_LPAREN);
+}
+
+
+static void
+mio_rparen (void)
+{
+
+ if (iomode == IO_OUTPUT)
+ write_atom (ATOM_RPAREN, NULL);
+ else
+ require_atom (ATOM_RPAREN);
+}
+
+
+static void
+mio_integer (int *ip)
+{
+
+ if (iomode == IO_OUTPUT)
+ write_atom (ATOM_INTEGER, ip);
+ else
+ {
+ require_atom (ATOM_INTEGER);
+ *ip = atom_int;
+ }
+}
+
+
+/* Read or write a character pointer that points to a string on the
+ heap. */
+
+static void
+mio_allocated_string (char **sp)
+{
+
+ if (iomode == IO_OUTPUT)
+ write_atom (ATOM_STRING, *sp);
+ else
+ {
+ require_atom (ATOM_STRING);
+ *sp = atom_string;
+ }
+}
+
+
+/* Read or write a string that is in static memory or inside of some
+ already-allocated structure. */
+
+static void
+mio_internal_string (char *string)
+{
+
+ if (iomode == IO_OUTPUT)
+ write_atom (ATOM_STRING, string);
+ else
+ {
+ require_atom (ATOM_STRING);
+ strcpy (string, atom_string);
+ gfc_free (atom_string);
+ }
+}
+
+
+
+typedef enum
+{ AB_ALLOCATABLE, AB_DIMENSION, AB_EXTERNAL, AB_INTRINSIC, AB_OPTIONAL,
+ AB_POINTER, AB_SAVE, AB_TARGET, AB_DUMMY, AB_COMMON, AB_RESULT,
+ AB_ENTRY, AB_DATA, AB_IN_NAMELIST, AB_IN_COMMON, AB_SAVED_COMMON,
+ AB_FUNCTION, AB_SUBROUTINE, AB_SEQUENCE, AB_ELEMENTAL, AB_PURE,
+ AB_RECURSIVE, AB_GENERIC, AB_ALWAYS_EXPLICIT
+}
+ab_attribute;
+
+static const mstring attr_bits[] =
+{
+ minit ("ALLOCATABLE", AB_ALLOCATABLE),
+ minit ("DIMENSION", AB_DIMENSION),
+ minit ("EXTERNAL", AB_EXTERNAL),
+ minit ("INTRINSIC", AB_INTRINSIC),
+ minit ("OPTIONAL", AB_OPTIONAL),
+ minit ("POINTER", AB_POINTER),
+ minit ("SAVE", AB_SAVE),
+ minit ("TARGET", AB_TARGET),
+ minit ("DUMMY", AB_DUMMY),
+ minit ("COMMON", AB_COMMON),
+ minit ("RESULT", AB_RESULT),
+ minit ("ENTRY", AB_ENTRY),
+ minit ("DATA", AB_DATA),
+ minit ("IN_NAMELIST", AB_IN_NAMELIST),
+ minit ("IN_COMMON", AB_IN_COMMON),
+ minit ("SAVED_COMMON", AB_SAVED_COMMON),
+ minit ("FUNCTION", AB_FUNCTION),
+ minit ("SUBROUTINE", AB_SUBROUTINE),
+ minit ("SEQUENCE", AB_SEQUENCE),
+ minit ("ELEMENTAL", AB_ELEMENTAL),
+ minit ("PURE", AB_PURE),
+ minit ("RECURSIVE", AB_RECURSIVE),
+ minit ("GENERIC", AB_GENERIC),
+ minit ("ALWAYS_EXPLICIT", AB_ALWAYS_EXPLICIT),
+ minit (NULL, -1)
+};
+
+/* Specialisation of mio_name. */
+DECL_MIO_NAME(ab_attribute)
+DECL_MIO_NAME(ar_type)
+DECL_MIO_NAME(array_type)
+DECL_MIO_NAME(bt)
+DECL_MIO_NAME(expr_t)
+DECL_MIO_NAME(gfc_access)
+DECL_MIO_NAME(gfc_intrinsic_op)
+DECL_MIO_NAME(ifsrc)
+DECL_MIO_NAME(procedure_type)
+DECL_MIO_NAME(ref_type)
+DECL_MIO_NAME(sym_flavor)
+DECL_MIO_NAME(sym_intent)
+#undef DECL_MIO_NAME
+
+/* Symbol attributes are stored in list with the first three elements
+ being the enumerated fields, while the remaining elements (if any)
+ indicate the individual attribute bits. The access field is not
+ saved-- it controls what symbols are exported when a module is
+ written. */
+
+static void
+mio_symbol_attribute (symbol_attribute * attr)
+{
+ atom_type t;
+
+ mio_lparen ();
+
+ attr->flavor = MIO_NAME(sym_flavor) (attr->flavor, flavors);
+ attr->intent = MIO_NAME(sym_intent) (attr->intent, intents);
+ attr->proc = MIO_NAME(procedure_type) (attr->proc, procedures);
+ attr->if_source = MIO_NAME(ifsrc) (attr->if_source, ifsrc_types);
+
+ if (iomode == IO_OUTPUT)
+ {
+ if (attr->allocatable)
+ MIO_NAME(ab_attribute) (AB_ALLOCATABLE, attr_bits);
+ if (attr->dimension)
+ MIO_NAME(ab_attribute) (AB_DIMENSION, attr_bits);
+ if (attr->external)
+ MIO_NAME(ab_attribute) (AB_EXTERNAL, attr_bits);
+ if (attr->intrinsic)
+ MIO_NAME(ab_attribute) (AB_INTRINSIC, attr_bits);
+ if (attr->optional)
+ MIO_NAME(ab_attribute) (AB_OPTIONAL, attr_bits);
+ if (attr->pointer)
+ MIO_NAME(ab_attribute) (AB_POINTER, attr_bits);
+ if (attr->save)
+ MIO_NAME(ab_attribute) (AB_SAVE, attr_bits);
+ if (attr->target)
+ MIO_NAME(ab_attribute) (AB_TARGET, attr_bits);
+ if (attr->dummy)
+ MIO_NAME(ab_attribute) (AB_DUMMY, attr_bits);
+ if (attr->common)
+ MIO_NAME(ab_attribute) (AB_COMMON, attr_bits);
+ if (attr->result)
+ MIO_NAME(ab_attribute) (AB_RESULT, attr_bits);
+ if (attr->entry)
+ MIO_NAME(ab_attribute) (AB_ENTRY, attr_bits);
+
+ if (attr->data)
+ MIO_NAME(ab_attribute) (AB_DATA, attr_bits);
+ if (attr->in_namelist)
+ MIO_NAME(ab_attribute) (AB_IN_NAMELIST, attr_bits);
+ if (attr->in_common)
+ MIO_NAME(ab_attribute) (AB_IN_COMMON, attr_bits);
+ if (attr->saved_common)
+ MIO_NAME(ab_attribute) (AB_SAVED_COMMON, attr_bits);
+
+ if (attr->function)
+ MIO_NAME(ab_attribute) (AB_FUNCTION, attr_bits);
+ if (attr->subroutine)
+ MIO_NAME(ab_attribute) (AB_SUBROUTINE, attr_bits);
+ if (attr->generic)
+ MIO_NAME(ab_attribute) (AB_GENERIC, attr_bits);
+
+ if (attr->sequence)
+ MIO_NAME(ab_attribute) (AB_SEQUENCE, attr_bits);
+ if (attr->elemental)
+ MIO_NAME(ab_attribute) (AB_ELEMENTAL, attr_bits);
+ if (attr->pure)
+ MIO_NAME(ab_attribute) (AB_PURE, attr_bits);
+ if (attr->recursive)
+ MIO_NAME(ab_attribute) (AB_RECURSIVE, attr_bits);
+ if (attr->always_explicit)
+ MIO_NAME(ab_attribute) (AB_ALWAYS_EXPLICIT, attr_bits);
+
+ mio_rparen ();
+
+ }
+ else
+ {
+
+ for (;;)
+ {
+ t = parse_atom ();
+ if (t == ATOM_RPAREN)
+ break;
+ if (t != ATOM_NAME)
+ bad_module ("Expected attribute bit name");
+
+ switch ((ab_attribute) find_enum (attr_bits))
+ {
+ case AB_ALLOCATABLE:
+ attr->allocatable = 1;
+ break;
+ case AB_DIMENSION:
+ attr->dimension = 1;
+ break;
+ case AB_EXTERNAL:
+ attr->external = 1;
+ break;
+ case AB_INTRINSIC:
+ attr->intrinsic = 1;
+ break;
+ case AB_OPTIONAL:
+ attr->optional = 1;
+ break;
+ case AB_POINTER:
+ attr->pointer = 1;
+ break;
+ case AB_SAVE:
+ attr->save = 1;
+ break;
+ case AB_TARGET:
+ attr->target = 1;
+ break;
+ case AB_DUMMY:
+ attr->dummy = 1;
+ break;
+ case AB_COMMON:
+ attr->common = 1;
+ break;
+ case AB_RESULT:
+ attr->result = 1;
+ break;
+ case AB_ENTRY:
+ attr->entry = 1;
+ break;
+ case AB_DATA:
+ attr->data = 1;
+ break;
+ case AB_IN_NAMELIST:
+ attr->in_namelist = 1;
+ break;
+ case AB_IN_COMMON:
+ attr->in_common = 1;
+ break;
+ case AB_SAVED_COMMON:
+ attr->saved_common = 1;
+ break;
+ case AB_FUNCTION:
+ attr->function = 1;
+ break;
+ case AB_SUBROUTINE:
+ attr->subroutine = 1;
+ break;
+ case AB_GENERIC:
+ attr->generic = 1;
+ break;
+ case AB_SEQUENCE:
+ attr->sequence = 1;
+ break;
+ case AB_ELEMENTAL:
+ attr->elemental = 1;
+ break;
+ case AB_PURE:
+ attr->pure = 1;
+ break;
+ case AB_RECURSIVE:
+ attr->recursive = 1;
+ break;
+ case AB_ALWAYS_EXPLICIT:
+ attr->always_explicit = 1;
+ break;
+ }
+ }
+ }
+}
+
+
+static const mstring bt_types[] = {
+ minit ("INTEGER", BT_INTEGER),
+ minit ("REAL", BT_REAL),
+ minit ("COMPLEX", BT_COMPLEX),
+ minit ("LOGICAL", BT_LOGICAL),
+ minit ("CHARACTER", BT_CHARACTER),
+ minit ("DERIVED", BT_DERIVED),
+ minit ("PROCEDURE", BT_PROCEDURE),
+ minit ("UNKNOWN", BT_UNKNOWN),
+ minit (NULL, -1)
+};
+
+
+static void
+mio_charlen (gfc_charlen ** clp)
+{
+ gfc_charlen *cl;
+
+ mio_lparen ();
+
+ if (iomode == IO_OUTPUT)
+ {
+ cl = *clp;
+ if (cl != NULL)
+ mio_expr (&cl->length);
+ }
+ else
+ {
+
+ if (peek_atom () != ATOM_RPAREN)
+ {
+ cl = gfc_get_charlen ();
+ mio_expr (&cl->length);
+
+ *clp = cl;
+
+ cl->next = gfc_current_ns->cl_list;
+ gfc_current_ns->cl_list = cl;
+ }
+ }
+
+ mio_rparen ();
+}
+
+
+/* Return a symtree node with a name that is guaranteed to be unique
+ within the namespace and corresponds to an illegal fortran name. */
+
+static gfc_symtree *
+get_unique_symtree (gfc_namespace * ns)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ static int serial = 0;
+
+ sprintf (name, "@%d", serial++);
+ return gfc_new_symtree (&ns->sym_root, name);
+}
+
+
+/* See if a name is a generated name. */
+
+static int
+check_unique_name (const char *name)
+{
+
+ return *name == '@';
+}
+
+
+static void
+mio_typespec (gfc_typespec * ts)
+{
+
+ mio_lparen ();
+
+ ts->type = MIO_NAME(bt) (ts->type, bt_types);
+
+ if (ts->type != BT_DERIVED)
+ mio_integer (&ts->kind);
+ else
+ mio_symbol_ref (&ts->derived);
+
+ mio_charlen (&ts->cl);
+
+ mio_rparen ();
+}
+
+
+static const mstring array_spec_types[] = {
+ minit ("EXPLICIT", AS_EXPLICIT),
+ minit ("ASSUMED_SHAPE", AS_ASSUMED_SHAPE),
+ minit ("DEFERRED", AS_DEFERRED),
+ minit ("ASSUMED_SIZE", AS_ASSUMED_SIZE),
+ minit (NULL, -1)
+};
+
+
+static void
+mio_array_spec (gfc_array_spec ** asp)
+{
+ gfc_array_spec *as;
+ int i;
+
+ mio_lparen ();
+
+ if (iomode == IO_OUTPUT)
+ {
+ if (*asp == NULL)
+ goto done;
+ as = *asp;
+ }
+ else
+ {
+ if (peek_atom () == ATOM_RPAREN)
+ {
+ *asp = NULL;
+ goto done;
+ }
+
+ *asp = as = gfc_get_array_spec ();
+ }
+
+ mio_integer (&as->rank);
+ as->type = MIO_NAME(array_type) (as->type, array_spec_types);
+
+ for (i = 0; i < as->rank; i++)
+ {
+ mio_expr (&as->lower[i]);
+ mio_expr (&as->upper[i]);
+ }
+
+done:
+ mio_rparen ();
+}
+
+
+/* Given a pointer to an array reference structure (which lives in a
+ gfc_ref structure), find the corresponding array specification
+ structure. Storing the pointer in the ref structure doesn't quite
+ work when loading from a module. Generating code for an array
+ reference also needs more infomation than just the array spec. */
+
+static const mstring array_ref_types[] = {
+ minit ("FULL", AR_FULL),
+ minit ("ELEMENT", AR_ELEMENT),
+ minit ("SECTION", AR_SECTION),
+ minit (NULL, -1)
+};
+
+static void
+mio_array_ref (gfc_array_ref * ar)
+{
+ int i;
+
+ mio_lparen ();
+ ar->type = MIO_NAME(ar_type) (ar->type, array_ref_types);
+ mio_integer (&ar->dimen);
+
+ switch (ar->type)
+ {
+ case AR_FULL:
+ break;
+
+ case AR_ELEMENT:
+ for (i = 0; i < ar->dimen; i++)
+ mio_expr (&ar->start[i]);
+
+ break;
+
+ case AR_SECTION:
+ for (i = 0; i < ar->dimen; i++)
+ {
+ mio_expr (&ar->start[i]);
+ mio_expr (&ar->end[i]);
+ mio_expr (&ar->stride[i]);
+ }
+
+ break;
+
+ case AR_UNKNOWN:
+ gfc_internal_error ("mio_array_ref(): Unknown array ref");
+ }
+
+ for (i = 0; i < ar->dimen; i++)
+ mio_integer ((int *) &ar->dimen_type[i]);
+
+ if (iomode == IO_INPUT)
+ {
+ ar->where = *gfc_current_locus ();
+
+ for (i = 0; i < ar->dimen; i++)
+ ar->c_where[i] = *gfc_current_locus ();
+ }
+
+ mio_rparen ();
+}
+
+
+/* Saves or restores a pointer. The pointer is converted back and
+ forth from an integer. We return the pointer_info pointer so that
+ the caller can take additional action based on the pointer type. */
+
+static pointer_info *
+mio_pointer_ref (void *gp)
+{
+ pointer_info *p;
+
+ if (iomode == IO_OUTPUT)
+ {
+ p = get_pointer (*((char **) gp));
+ write_atom (ATOM_INTEGER, &p->integer);
+ }
+ else
+ {
+ require_atom (ATOM_INTEGER);
+ p = add_fixup (atom_int, gp);
+ }
+
+ return p;
+}
+
+
+/* Save and load references to components that occur within
+ expressions. We have to describe these references by a number and
+ by name. The number is necessary for forward references during
+ reading, and the name is necessary if the symbol already exists in
+ the namespace and is not loaded again. */
+
+static void
+mio_component_ref (gfc_component ** cp, gfc_symbol * sym)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_component *q;
+ pointer_info *p;
+
+ p = mio_pointer_ref (cp);
+ if (p->type == P_UNKNOWN)
+ p->type = P_COMPONENT;
+
+ if (iomode == IO_OUTPUT)
+ mio_internal_string ((*cp)->name);
+ else
+ {
+ mio_internal_string (name);
+
+ if (sym->components != NULL && p->u.pointer == NULL)
+ {
+ /* Symbol already loaded, so search by name. */
+ for (q = sym->components; q; q = q->next)
+ if (strcmp (q->name, name) == 0)
+ break;
+
+ if (q == NULL)
+ gfc_internal_error ("mio_component_ref(): Component not found");
+
+ associate_integer_pointer (p, q);
+ }
+
+ /* Make sure this symbol will eventually be loaded. */
+ p = find_pointer2 (sym);
+ if (p->u.rsym.state == UNUSED)
+ p->u.rsym.state = NEEDED;
+ }
+}
+
+
+static void
+mio_component (gfc_component * c)
+{
+ pointer_info *p;
+ int n;
+
+ mio_lparen ();
+
+ if (iomode == IO_OUTPUT)
+ {
+ p = get_pointer (c);
+ mio_integer (&p->integer);
+ }
+ else
+ {
+ mio_integer (&n);
+ p = get_integer (n);
+ associate_integer_pointer (p, c);
+ }
+
+ if (p->type == P_UNKNOWN)
+ p->type = P_COMPONENT;
+
+ mio_internal_string (c->name);
+ mio_typespec (&c->ts);
+ mio_array_spec (&c->as);
+
+ mio_integer (&c->dimension);
+ mio_integer (&c->pointer);
+
+ mio_expr (&c->initializer);
+ mio_rparen ();
+}
+
+
+static void
+mio_component_list (gfc_component ** cp)
+{
+ gfc_component *c, *tail;
+
+ mio_lparen ();
+
+ if (iomode == IO_OUTPUT)
+ {
+ for (c = *cp; c; c = c->next)
+ mio_component (c);
+ }
+ else
+ {
+
+ *cp = NULL;
+ tail = NULL;
+
+ for (;;)
+ {
+ if (peek_atom () == ATOM_RPAREN)
+ break;
+
+ c = gfc_get_component ();
+ mio_component (c);
+
+ if (tail == NULL)
+ *cp = c;
+ else
+ tail->next = c;
+
+ tail = c;
+ }
+ }
+
+ mio_rparen ();
+}
+
+
+static void
+mio_actual_arg (gfc_actual_arglist * a)
+{
+
+ mio_lparen ();
+ mio_internal_string (a->name);
+ mio_expr (&a->expr);
+ mio_rparen ();
+}
+
+
+static void
+mio_actual_arglist (gfc_actual_arglist ** ap)
+{
+ gfc_actual_arglist *a, *tail;
+
+ mio_lparen ();
+
+ if (iomode == IO_OUTPUT)
+ {
+ for (a = *ap; a; a = a->next)
+ mio_actual_arg (a);
+
+ }
+ else
+ {
+ tail = NULL;
+
+ for (;;)
+ {
+ if (peek_atom () != ATOM_LPAREN)
+ break;
+
+ a = gfc_get_actual_arglist ();
+
+ if (tail == NULL)
+ *ap = a;
+ else
+ tail->next = a;
+
+ tail = a;
+ mio_actual_arg (a);
+ }
+ }
+
+ mio_rparen ();
+}
+
+
+/* Read and write formal argument lists. */
+
+static void
+mio_formal_arglist (gfc_symbol * sym)
+{
+ gfc_formal_arglist *f, *tail;
+
+ mio_lparen ();
+
+ if (iomode == IO_OUTPUT)
+ {
+ for (f = sym->formal; f; f = f->next)
+ mio_symbol_ref (&f->sym);
+
+ }
+ else
+ {
+ sym->formal = tail = NULL;
+
+ while (peek_atom () != ATOM_RPAREN)
+ {
+ f = gfc_get_formal_arglist ();
+ mio_symbol_ref (&f->sym);
+
+ if (sym->formal == NULL)
+ sym->formal = f;
+ else
+ tail->next = f;
+
+ tail = f;
+ }
+ }
+
+ mio_rparen ();
+}
+
+
+/* Save or restore a reference to a symbol node. */
+
+void
+mio_symbol_ref (gfc_symbol ** symp)
+{
+ pointer_info *p;
+
+ p = mio_pointer_ref (symp);
+ if (p->type == P_UNKNOWN)
+ p->type = P_SYMBOL;
+
+ if (iomode == IO_OUTPUT)
+ {
+ if (p->u.wsym.state == UNREFERENCED)
+ p->u.wsym.state = NEEDS_WRITE;
+ }
+ else
+ {
+ if (p->u.rsym.state == UNUSED)
+ p->u.rsym.state = NEEDED;
+ }
+}
+
+
+/* Save or restore a reference to a symtree node. */
+
+static void
+mio_symtree_ref (gfc_symtree ** stp)
+{
+ pointer_info *p;
+ fixup_t *f;
+
+ if (iomode == IO_OUTPUT)
+ {
+ mio_symbol_ref (&(*stp)->n.sym);
+ }
+ else
+ {
+ require_atom (ATOM_INTEGER);
+ p = get_integer (atom_int);
+ if (p->type == P_UNKNOWN)
+ p->type = P_SYMBOL;
+
+ if (p->u.rsym.state == UNUSED)
+ p->u.rsym.state = NEEDED;
+
+ if (p->u.rsym.symtree != NULL)
+ {
+ *stp = p->u.rsym.symtree;
+ }
+ else
+ {
+ f = gfc_getmem (sizeof (fixup_t));
+
+ f->next = p->u.rsym.stfixup;
+ p->u.rsym.stfixup = f;
+
+ f->pointer = (void **)stp;
+ }
+ }
+}
+
+static void
+mio_iterator (gfc_iterator ** ip)
+{
+ gfc_iterator *iter;
+
+ mio_lparen ();
+
+ if (iomode == IO_OUTPUT)
+ {
+ if (*ip == NULL)
+ goto done;
+ }
+ else
+ {
+ if (peek_atom () == ATOM_RPAREN)
+ {
+ *ip = NULL;
+ goto done;
+ }
+
+ *ip = gfc_get_iterator ();
+ }
+
+ iter = *ip;
+
+ mio_expr (&iter->var);
+ mio_expr (&iter->start);
+ mio_expr (&iter->end);
+ mio_expr (&iter->step);
+
+done:
+ mio_rparen ();
+}
+
+
+
+static void
+mio_constructor (gfc_constructor ** cp)
+{
+ gfc_constructor *c, *tail;
+
+ mio_lparen ();
+
+ if (iomode == IO_OUTPUT)
+ {
+ for (c = *cp; c; c = c->next)
+ {
+ mio_lparen ();
+ mio_expr (&c->expr);
+ mio_iterator (&c->iterator);
+ mio_rparen ();
+ }
+ }
+ else
+ {
+
+ *cp = NULL;
+ tail = NULL;
+
+ while (peek_atom () != ATOM_RPAREN)
+ {
+ c = gfc_get_constructor ();
+
+ if (tail == NULL)
+ *cp = c;
+ else
+ tail->next = c;
+
+ tail = c;
+
+ mio_lparen ();
+ mio_expr (&c->expr);
+ mio_iterator (&c->iterator);
+ mio_rparen ();
+ }
+ }
+
+ mio_rparen ();
+}
+
+
+
+static const mstring ref_types[] = {
+ minit ("ARRAY", REF_ARRAY),
+ minit ("COMPONENT", REF_COMPONENT),
+ minit ("SUBSTRING", REF_SUBSTRING),
+ minit (NULL, -1)
+};
+
+
+static void
+mio_ref (gfc_ref ** rp)
+{
+ gfc_ref *r;
+
+ mio_lparen ();
+
+ r = *rp;
+ r->type = MIO_NAME(ref_type) (r->type, ref_types);
+
+ switch (r->type)
+ {
+ case REF_ARRAY:
+ mio_array_ref (&r->u.ar);
+ break;
+
+ case REF_COMPONENT:
+ mio_symbol_ref (&r->u.c.sym);
+ mio_component_ref (&r->u.c.component, r->u.c.sym);
+ break;
+
+ case REF_SUBSTRING:
+ mio_expr (&r->u.ss.start);
+ mio_expr (&r->u.ss.end);
+ mio_charlen (&r->u.ss.length);
+ break;
+ }
+
+ mio_rparen ();
+}
+
+
+static void
+mio_ref_list (gfc_ref ** rp)
+{
+ gfc_ref *ref, *head, *tail;
+
+ mio_lparen ();
+
+ if (iomode == IO_OUTPUT)
+ {
+ for (ref = *rp; ref; ref = ref->next)
+ mio_ref (&ref);
+ }
+ else
+ {
+ head = tail = NULL;
+
+ while (peek_atom () != ATOM_RPAREN)
+ {
+ if (head == NULL)
+ head = tail = gfc_get_ref ();
+ else
+ {
+ tail->next = gfc_get_ref ();
+ tail = tail->next;
+ }
+
+ mio_ref (&tail);
+ }
+
+ *rp = head;
+ }
+
+ mio_rparen ();
+}
+
+
+/* Read and write an integer value. */
+
+static void
+mio_gmp_integer (mpz_t * integer)
+{
+ char *p;
+
+ if (iomode == IO_INPUT)
+ {
+ if (parse_atom () != ATOM_STRING)
+ bad_module ("Expected integer string");
+
+ mpz_init (*integer);
+ if (mpz_set_str (*integer, atom_string, 10))
+ bad_module ("Error converting integer");
+
+ gfc_free (atom_string);
+
+ }
+ else
+ {
+ p = mpz_get_str (NULL, 10, *integer);
+ write_atom (ATOM_STRING, p);
+ gfc_free (p);
+ }
+}
+
+
+static void
+mio_gmp_real (mpf_t * real)
+{
+ mp_exp_t exponent;
+ char *p;
+
+ if (iomode == IO_INPUT)
+ {
+ if (parse_atom () != ATOM_STRING)
+ bad_module ("Expected real string");
+
+ mpf_init (*real);
+ mpf_set_str (*real, atom_string, -16);
+ gfc_free (atom_string);
+
+ }
+ else
+ {
+ p = mpf_get_str (NULL, &exponent, 16, 0, *real);
+ atom_string = gfc_getmem (strlen (p) + 20);
+
+ sprintf (atom_string, "0.%s@%ld", p, exponent);
+ write_atom (ATOM_STRING, atom_string);
+
+ gfc_free (atom_string);
+ gfc_free (p);
+ }
+}
+
+
+/* Save and restore the shape of an array constructor. */
+
+static void
+mio_shape (mpz_t ** pshape, int rank)
+{
+ mpz_t *shape;
+ atom_type t;
+ int n;
+
+ /* A NULL shape is represented by (). */
+ mio_lparen ();
+
+ if (iomode == IO_OUTPUT)
+ {
+ shape = *pshape;
+ if (!shape)
+ {
+ mio_rparen ();
+ return;
+ }
+ }
+ else
+ {
+ t = peek_atom ();
+ if (t == ATOM_RPAREN)
+ {
+ *pshape = NULL;
+ mio_rparen ();
+ return;
+ }
+
+ shape = gfc_get_shape (rank);
+ *pshape = shape;
+ }
+
+ for (n = 0; n < rank; n++)
+ mio_gmp_integer (&shape[n]);
+
+ mio_rparen ();
+}
+
+
+static const mstring expr_types[] = {
+ minit ("OP", EXPR_OP),
+ minit ("FUNCTION", EXPR_FUNCTION),
+ minit ("CONSTANT", EXPR_CONSTANT),
+ minit ("VARIABLE", EXPR_VARIABLE),
+ minit ("SUBSTRING", EXPR_SUBSTRING),
+ minit ("STRUCTURE", EXPR_STRUCTURE),
+ minit ("ARRAY", EXPR_ARRAY),
+ minit ("NULL", EXPR_NULL),
+ minit (NULL, -1)
+};
+
+/* INTRINSIC_ASSIGN is missing because it is used as an index for
+ generic operators, not in expressions. INTRINSIC_USER is also
+ replaced by the correct function name by the time we see it. */
+
+static const mstring intrinsics[] =
+{
+ minit ("UPLUS", INTRINSIC_UPLUS),
+ minit ("UMINUS", INTRINSIC_UMINUS),
+ minit ("PLUS", INTRINSIC_PLUS),
+ minit ("MINUS", INTRINSIC_MINUS),
+ minit ("TIMES", INTRINSIC_TIMES),
+ minit ("DIVIDE", INTRINSIC_DIVIDE),
+ minit ("POWER", INTRINSIC_POWER),
+ minit ("CONCAT", INTRINSIC_CONCAT),
+ minit ("AND", INTRINSIC_AND),
+ minit ("OR", INTRINSIC_OR),
+ minit ("EQV", INTRINSIC_EQV),
+ minit ("NEQV", INTRINSIC_NEQV),
+ minit ("EQ", INTRINSIC_EQ),
+ minit ("NE", INTRINSIC_NE),
+ minit ("GT", INTRINSIC_GT),
+ minit ("GE", INTRINSIC_GE),
+ minit ("LT", INTRINSIC_LT),
+ minit ("LE", INTRINSIC_LE),
+ minit ("NOT", INTRINSIC_NOT),
+ minit (NULL, -1)
+};
+
+/* Read and write expressions. The form "()" is allowed to indicate a
+ NULL expression. */
+
+static void
+mio_expr (gfc_expr ** ep)
+{
+ gfc_expr *e;
+ atom_type t;
+ int flag;
+
+ mio_lparen ();
+
+ if (iomode == IO_OUTPUT)
+ {
+ if (*ep == NULL)
+ {
+ mio_rparen ();
+ return;
+ }
+
+ e = *ep;
+ MIO_NAME(expr_t) (e->expr_type, expr_types);
+
+ }
+ else
+ {
+ t = parse_atom ();
+ if (t == ATOM_RPAREN)
+ {
+ *ep = NULL;
+ return;
+ }
+
+ if (t != ATOM_NAME)
+ bad_module ("Expected expression type");
+
+ e = *ep = gfc_get_expr ();
+ e->where = *gfc_current_locus ();
+ e->expr_type = (expr_t) find_enum (expr_types);
+ }
+
+ mio_typespec (&e->ts);
+ mio_integer (&e->rank);
+
+ switch (e->expr_type)
+ {
+ case EXPR_OP:
+ e->operator = MIO_NAME(gfc_intrinsic_op) (e->operator, intrinsics);
+
+ switch (e->operator)
+ {
+ case INTRINSIC_UPLUS:
+ case INTRINSIC_UMINUS:
+ case INTRINSIC_NOT:
+ mio_expr (&e->op1);
+ break;
+
+ case INTRINSIC_PLUS:
+ case INTRINSIC_MINUS:
+ case INTRINSIC_TIMES:
+ case INTRINSIC_DIVIDE:
+ case INTRINSIC_POWER:
+ case INTRINSIC_CONCAT:
+ case INTRINSIC_AND:
+ case INTRINSIC_OR:
+ case INTRINSIC_EQV:
+ case INTRINSIC_NEQV:
+ case INTRINSIC_EQ:
+ case INTRINSIC_NE:
+ case INTRINSIC_GT:
+ case INTRINSIC_GE:
+ case INTRINSIC_LT:
+ case INTRINSIC_LE:
+ mio_expr (&e->op1);
+ mio_expr (&e->op2);
+ break;
+
+ default:
+ bad_module ("Bad operator");
+ }
+
+ break;
+
+ case EXPR_FUNCTION:
+ mio_symtree_ref (&e->symtree);
+ mio_actual_arglist (&e->value.function.actual);
+
+ if (iomode == IO_OUTPUT)
+ {
+ mio_allocated_string (&e->value.function.name);
+ flag = e->value.function.esym != NULL;
+ mio_integer (&flag);
+ if (flag)
+ mio_symbol_ref (&e->value.function.esym);
+ else
+ write_atom (ATOM_STRING, e->value.function.isym->name);
+
+ }
+ else
+ {
+ require_atom (ATOM_STRING);
+ e->value.function.name = gfc_get_string (atom_string);
+ gfc_free (atom_string);
+
+ mio_integer (&flag);
+ if (flag)
+ mio_symbol_ref (&e->value.function.esym);
+ else
+ {
+ require_atom (ATOM_STRING);
+ e->value.function.isym = gfc_find_function (atom_string);
+ gfc_free (atom_string);
+ }
+ }
+
+ break;
+
+ case EXPR_VARIABLE:
+ mio_symtree_ref (&e->symtree);
+ mio_ref_list (&e->ref);
+ break;
+
+ case EXPR_SUBSTRING:
+ mio_allocated_string (&e->value.character.string);
+ mio_expr (&e->op1);
+ mio_expr (&e->op2);
+ break;
+
+ case EXPR_STRUCTURE:
+ case EXPR_ARRAY:
+ mio_constructor (&e->value.constructor);
+ mio_shape (&e->shape, e->rank);
+ break;
+
+ case EXPR_CONSTANT:
+ switch (e->ts.type)
+ {
+ case BT_INTEGER:
+ mio_gmp_integer (&e->value.integer);
+ break;
+
+ case BT_REAL:
+ mio_gmp_real (&e->value.real);
+ break;
+
+ case BT_COMPLEX:
+ mio_gmp_real (&e->value.complex.r);
+ mio_gmp_real (&e->value.complex.i);
+ break;
+
+ case BT_LOGICAL:
+ mio_integer (&e->value.logical);
+ break;
+
+ case BT_CHARACTER:
+ mio_integer (&e->value.character.length);
+ mio_allocated_string (&e->value.character.string);
+ break;
+
+ default:
+ bad_module ("Bad type in constant expression");
+ }
+
+ break;
+
+ case EXPR_NULL:
+ break;
+ }
+
+ mio_rparen ();
+}
+
+
+/* Save/restore lists of gfc_interface stuctures. When loading an
+ interface, we are really appending to the existing list of
+ interfaces. Checking for duplicate and ambiguous interfaces has to
+ be done later when all symbols have been loaded. */
+
+static void
+mio_interface_rest (gfc_interface ** ip)
+{
+ gfc_interface *tail, *p;
+
+ if (iomode == IO_OUTPUT)
+ {
+ if (ip != NULL)
+ for (p = *ip; p; p = p->next)
+ mio_symbol_ref (&p->sym);
+ }
+ else
+ {
+
+ if (*ip == NULL)
+ tail = NULL;
+ else
+ {
+ tail = *ip;
+ while (tail->next)
+ tail = tail->next;
+ }
+
+ for (;;)
+ {
+ if (peek_atom () == ATOM_RPAREN)
+ break;
+
+ p = gfc_get_interface ();
+ mio_symbol_ref (&p->sym);
+
+ if (tail == NULL)
+ *ip = p;
+ else
+ tail->next = p;
+
+ tail = p;
+ }
+ }
+
+ mio_rparen ();
+}
+
+
+/* Save/restore a nameless operator interface. */
+
+static void
+mio_interface (gfc_interface ** ip)
+{
+
+ mio_lparen ();
+ mio_interface_rest (ip);
+}
+
+
+/* Save/restore a named operator interface. */
+
+static void
+mio_symbol_interface (char *name, char *module,
+ gfc_interface ** ip)
+{
+
+ mio_lparen ();
+
+ mio_internal_string (name);
+ mio_internal_string (module);
+
+ mio_interface_rest (ip);
+}
+
+
+static void
+mio_namespace_ref (gfc_namespace ** nsp)
+{
+ gfc_namespace *ns;
+ pointer_info *p;
+
+ p = mio_pointer_ref (nsp);
+
+ if (p->type == P_UNKNOWN)
+ p->type = P_NAMESPACE;
+
+ if (iomode == IO_INPUT && p->integer != 0 && p->u.pointer == NULL)
+ {
+ ns = gfc_get_namespace (NULL);
+ associate_integer_pointer (p, ns);
+ }
+}
+
+
+/* Unlike most other routines, the address of the symbol node is
+ already fixed on input and the name/module has already been filled
+ in. */
+
+static void
+mio_symbol (gfc_symbol * sym)
+{
+ gfc_formal_arglist *formal;
+
+ mio_lparen ();
+
+ mio_symbol_attribute (&sym->attr);
+ mio_typespec (&sym->ts);
+
+ /* Contained procedures don't have formal namespaces. Instead we output the
+ procedure namespace. The will contain the formal arguments. */
+ if (iomode == IO_OUTPUT)
+ {
+ formal = sym->formal;
+ while (formal && !formal->sym)
+ formal = formal->next;
+
+ if (formal)
+ mio_namespace_ref (&formal->sym->ns);
+ else
+ mio_namespace_ref (&sym->formal_ns);
+ }
+ else
+ {
+ mio_namespace_ref (&sym->formal_ns);
+ if (sym->formal_ns)
+ {
+ sym->formal_ns->proc_name = sym;
+ sym->refs++;
+ }
+ }
+
+ /* Save/restore common block links */
+ mio_symbol_ref (&sym->common_head);
+ mio_symbol_ref (&sym->common_next);
+
+ mio_formal_arglist (sym);
+
+ mio_expr (&sym->value);
+ mio_array_spec (&sym->as);
+
+ mio_symbol_ref (&sym->result);
+
+ /* Note that components are always saved, even if they are supposed
+ to be private. Component access is checked during searching. */
+
+ mio_component_list (&sym->components);
+
+ if (sym->components != NULL)
+ sym->component_access =
+ MIO_NAME(gfc_access) (sym->component_access, access_types);
+
+ mio_symbol_ref (&sym->common_head);
+ mio_symbol_ref (&sym->common_next);
+
+ mio_rparen ();
+}
+
+
+/************************* Top level subroutines *************************/
+
+/* Skip a list between balanced left and right parens. */
+
+static void
+skip_list (void)
+{
+ int level;
+
+ level = 0;
+ do
+ {
+ switch (parse_atom ())
+ {
+ case ATOM_LPAREN:
+ level++;
+ break;
+
+ case ATOM_RPAREN:
+ level--;
+ break;
+
+ case ATOM_STRING:
+ gfc_free (atom_string);
+ break;
+
+ case ATOM_NAME:
+ case ATOM_INTEGER:
+ break;
+ }
+ }
+ while (level > 0);
+}
+
+
+/* Load operator interfaces from the module. Interfaces are unusual
+ in that they attach themselves to existing symbols. */
+
+static void
+load_operator_interfaces (void)
+{
+ const char *p;
+ char name[GFC_MAX_SYMBOL_LEN + 1], module[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_user_op *uop;
+
+ mio_lparen ();
+
+ while (peek_atom () != ATOM_RPAREN)
+ {
+ mio_lparen ();
+
+ mio_internal_string (name);
+ mio_internal_string (module);
+
+ /* Decide if we need to load this one or not. */
+ p = find_use_name (name);
+ if (p == NULL)
+ {
+ while (parse_atom () != ATOM_RPAREN);
+ }
+ else
+ {
+ uop = gfc_get_uop (p);
+ mio_interface_rest (&uop->operator);
+ }
+ }
+
+ mio_rparen ();
+}
+
+
+/* Load interfaces from the module. Interfaces are unusual in that
+ they attach themselves to existing symbols. */
+
+static void
+load_generic_interfaces (void)
+{
+ const char *p;
+ char name[GFC_MAX_SYMBOL_LEN + 1], module[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_symbol *sym;
+
+ mio_lparen ();
+
+ while (peek_atom () != ATOM_RPAREN)
+ {
+ mio_lparen ();
+
+ mio_internal_string (name);
+ mio_internal_string (module);
+
+ /* Decide if we need to load this one or not. */
+ p = find_use_name (name);
+
+ if (p == NULL || gfc_find_symbol (p, NULL, 0, &sym))
+ {
+ while (parse_atom () != ATOM_RPAREN);
+ continue;
+ }
+
+ if (sym == NULL)
+ {
+ gfc_get_symbol (p, NULL, &sym);
+
+ sym->attr.flavor = FL_PROCEDURE;
+ sym->attr.generic = 1;
+ sym->attr.use_assoc = 1;
+ }
+
+ mio_interface_rest (&sym->generic);
+ }
+
+ mio_rparen ();
+}
+
+
+/* Recursive function to traverse the pointer_info tree and load a
+ needed symbol. We return nonzero if we load a symbol and stop the
+ traversal, because the act of loading can alter the tree. */
+
+static int
+load_needed (pointer_info * p)
+{
+ gfc_namespace *ns;
+ pointer_info *q;
+ gfc_symbol *sym;
+
+ if (p == NULL)
+ return 0;
+ if (load_needed (p->left))
+ return 1;
+ if (load_needed (p->right))
+ return 1;
+
+ if (p->type != P_SYMBOL || p->u.rsym.state != NEEDED)
+ return 0;
+
+ p->u.rsym.state = USED;
+
+ set_module_locus (&p->u.rsym.where);
+
+ sym = p->u.rsym.sym;
+ if (sym == NULL)
+ {
+ q = get_integer (p->u.rsym.ns);
+
+ ns = (gfc_namespace *) q->u.pointer;
+ if (ns == NULL)
+ {
+ /* Create an interface namespace if necessary. These are
+ the namespaces that hold the formal parameters of module
+ procedures. */
+
+ ns = gfc_get_namespace (NULL);
+ associate_integer_pointer (q, ns);
+ }
+
+ sym = gfc_new_symbol (p->u.rsym.true_name, ns);
+ strcpy (sym->module, p->u.rsym.module);
+
+ associate_integer_pointer (p, sym);
+ }
+
+ mio_symbol (sym);
+ sym->attr.use_assoc = 1;
+
+ return 1;
+}
+
+
+/* Recursive function for cleaning up things after a module has been
+ read. */
+
+static void
+read_cleanup (pointer_info * p)
+{
+ gfc_symtree *st;
+ pointer_info *q;
+
+ if (p == NULL)
+ return;
+
+ read_cleanup (p->left);
+ read_cleanup (p->right);
+
+ if (p->type == P_SYMBOL && p->u.rsym.state == USED && !p->u.rsym.referenced)
+ {
+ /* Add hidden symbols to the symtree. */
+ q = get_integer (p->u.rsym.ns);
+ st = get_unique_symtree ((gfc_namespace *) q->u.pointer);
+
+ st->n.sym = p->u.rsym.sym;
+ st->n.sym->refs++;
+
+ /* Fixup any symtree references. */
+ p->u.rsym.symtree = st;
+ resolve_fixups (p->u.rsym.stfixup, st);
+ p->u.rsym.stfixup = NULL;
+ }
+
+ /* Free unused symbols. */
+ if (p->type == P_SYMBOL && p->u.rsym.state == UNUSED)
+ gfc_free_symbol (p->u.rsym.sym);
+}
+
+
+/* Read a module file. */
+
+static void
+read_module (void)
+{
+ module_locus operator_interfaces, user_operators;
+ const char *p;
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_intrinsic_op i;
+ int ambiguous, symbol;
+ pointer_info *info;
+ gfc_use_rename *u;
+ gfc_symtree *st;
+ gfc_symbol *sym;
+
+ get_module_locus (&operator_interfaces); /* Skip these for now */
+ skip_list ();
+
+ get_module_locus (&user_operators);
+ skip_list ();
+ skip_list ();
+
+ mio_lparen ();
+
+ /* Create the fixup nodes for all the symbols. */
+
+ while (peek_atom () != ATOM_RPAREN)
+ {
+ require_atom (ATOM_INTEGER);
+ info = get_integer (atom_int);
+
+ info->type = P_SYMBOL;
+ info->u.rsym.state = UNUSED;
+
+ mio_internal_string (info->u.rsym.true_name);
+ mio_internal_string (info->u.rsym.module);
+
+ require_atom (ATOM_INTEGER);
+ info->u.rsym.ns = atom_int;
+
+ get_module_locus (&info->u.rsym.where);
+ skip_list ();
+
+ /* See if the symbol has already been loaded by a previous module.
+ If so, we reference the existing symbol and prevent it from
+ being loaded again. */
+
+ sym = find_true_name (info->u.rsym.true_name, info->u.rsym.module);
+ if (sym == NULL)
+ continue;
+
+ info->u.rsym.state = USED;
+ info->u.rsym.referenced = 1;
+ info->u.rsym.sym = sym;
+ }
+
+ mio_rparen ();
+
+ /* Parse the symtree lists. This lets us mark which symbols need to
+ be loaded. Renaming is also done at this point by replacing the
+ symtree name. */
+
+ mio_lparen ();
+
+ while (peek_atom () != ATOM_RPAREN)
+ {
+ mio_internal_string (name);
+ mio_integer (&ambiguous);
+ mio_integer (&symbol);
+
+ info = get_integer (symbol);
+
+ /* Get the local name for this symbol. */
+ p = find_use_name (name);
+
+ /* Skip symtree nodes not in an ONLY caluse. */
+ if (p == NULL)
+ continue;
+
+ /* Check for ambiguous symbols. */
+ st = gfc_find_symtree (gfc_current_ns->sym_root, p);
+
+ if (st != NULL)
+ {
+ if (st->n.sym != info->u.rsym.sym)
+ st->ambiguous = 1;
+ info->u.rsym.symtree = st;
+ }
+ else
+ {
+ /* Create a symtree node in the current namespace for this symbol. */
+ st = check_unique_name (p) ? get_unique_symtree (gfc_current_ns) :
+ gfc_new_symtree (&gfc_current_ns->sym_root, p);
+
+ st->ambiguous = ambiguous;
+
+ sym = info->u.rsym.sym;
+
+ /* Create a symbol node if it doesn't already exist. */
+ if (sym == NULL)
+ {
+ sym = info->u.rsym.sym =
+ gfc_new_symbol (info->u.rsym.true_name, gfc_current_ns);
+
+ strcpy (sym->module, info->u.rsym.module);
+ }
+
+ st->n.sym = sym;
+ st->n.sym->refs++;
+
+ /* Store the symtree pointing to this symbol. */
+ info->u.rsym.symtree = st;
+
+ if (info->u.rsym.state == UNUSED)
+ info->u.rsym.state = NEEDED;
+ info->u.rsym.referenced = 1;
+ }
+ }
+
+ mio_rparen ();
+
+ /* Load intrinsic operator interfaces. */
+ set_module_locus (&operator_interfaces);
+ mio_lparen ();
+
+ for (i = GFC_INTRINSIC_BEGIN; i != GFC_INTRINSIC_END; i++)
+ {
+ if (i == INTRINSIC_USER)
+ continue;
+
+ if (only_flag)
+ {
+ u = find_use_operator (i);
+
+ if (u == NULL)
+ {
+ skip_list ();
+ continue;
+ }
+
+ u->found = 1;
+ }
+
+ mio_interface (&gfc_current_ns->operator[i]);
+ }
+
+ mio_rparen ();
+
+ /* Load generic and user operator interfaces. These must follow the
+ loading of symtree because otherwise symbols can be marked as
+ ambiguous. */
+
+ set_module_locus (&user_operators);
+
+ load_operator_interfaces ();
+ load_generic_interfaces ();
+
+ /* At this point, we read those symbols that are needed but haven't
+ been loaded yet. If one symbol requires another, the other gets
+ marked as NEEDED if its previous state was UNUSED. */
+
+ while (load_needed (pi_root));
+
+ /* Make sure all elements of the rename-list were found in the
+ module. */
+
+ for (u = gfc_rename_list; u; u = u->next)
+ {
+ if (u->found)
+ continue;
+
+ if (u->operator == INTRINSIC_NONE)
+ {
+ gfc_error ("Symbol '%s' referenced at %L not found in module '%s'",
+ u->use_name, &u->where, module_name);
+ continue;
+ }
+
+ if (u->operator == INTRINSIC_USER)
+ {
+ gfc_error
+ ("User operator '%s' referenced at %L not found in module '%s'",
+ u->use_name, &u->where, module_name);
+ continue;
+ }
+
+ gfc_error
+ ("Intrinsic operator '%s' referenced at %L not found in module "
+ "'%s'", gfc_op2string (u->operator), &u->where, module_name);
+ }
+
+ gfc_check_interfaces (gfc_current_ns);
+
+ /* Clean up symbol nodes that were never loaded, create references
+ to hidden symbols. */
+
+ read_cleanup (pi_root);
+}
+
+
+/* Given an access type that is specific to an entity and the default
+ access, return nonzero if we should write the entity. */
+
+static int
+check_access (gfc_access specific_access, gfc_access default_access)
+{
+
+ if (specific_access == ACCESS_PUBLIC)
+ return 1;
+ if (specific_access == ACCESS_PRIVATE)
+ return 0;
+
+ if (gfc_option.flag_module_access_private)
+ {
+ if (default_access == ACCESS_PUBLIC)
+ return 1;
+ }
+ else
+ {
+ if (default_access != ACCESS_PRIVATE)
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/* Write a symbol to the module. */
+
+static void
+write_symbol (int n, gfc_symbol * sym)
+{
+
+ if (sym->attr.flavor == FL_UNKNOWN || sym->attr.flavor == FL_LABEL)
+ gfc_internal_error ("write_symbol(): bad module symbol '%s'", sym->name);
+
+ mio_integer (&n);
+ mio_internal_string (sym->name);
+
+ if (sym->module[0] == '\0')
+ strcpy (sym->module, module_name);
+
+ mio_internal_string (sym->module);
+ mio_pointer_ref (&sym->ns);
+
+ mio_symbol (sym);
+ write_char ('\n');
+}
+
+
+/* Recursive traversal function to write the initial set of symbols to
+ the module. We check to see if the symbol should be written
+ according to the access specification. */
+
+static void
+write_symbol0 (gfc_symtree * st)
+{
+ gfc_symbol *sym;
+ pointer_info *p;
+
+ if (st == NULL)
+ return;
+
+ write_symbol0 (st->left);
+ write_symbol0 (st->right);
+
+ sym = st->n.sym;
+
+ if (sym->attr.flavor == FL_PROCEDURE && sym->attr.generic
+ && !sym->attr.subroutine && !sym->attr.function)
+ return;
+
+ if (!check_access (sym->attr.access, sym->ns->default_access))
+ return;
+
+ p = get_pointer (sym);
+ if (p->type == P_UNKNOWN)
+ p->type = P_SYMBOL;
+
+ if (p->u.wsym.state == WRITTEN)
+ return;
+
+ write_symbol (p->integer, sym);
+ p->u.wsym.state = WRITTEN;
+
+ return;
+}
+
+
+/* Recursive traversal function to write the secondary set of symbols
+ to the module file. These are symbols that were not public yet are
+ needed by the public symbols or another dependent symbol. The act
+ of writing a symbol can modify the pointer_info tree, so we cease
+ traversal if we find a symbol to write. We return nonzero if a
+ symbol was written and pass that information upwards. */
+
+static int
+write_symbol1 (pointer_info * p)
+{
+
+ if (p == NULL)
+ return 0;
+
+ if (write_symbol1 (p->left))
+ return 1;
+ if (write_symbol1 (p->right))
+ return 1;
+
+ if (p->type != P_SYMBOL || p->u.wsym.state != NEEDS_WRITE)
+ return 0;
+
+ p->u.wsym.state = WRITTEN;
+ write_symbol (p->integer, p->u.wsym.sym);
+
+ return 1;
+}
+
+
+/* Write operator interfaces associated with a symbol. */
+
+static void
+write_operator (gfc_user_op * uop)
+{
+ static char nullstring[] = "";
+
+ if (uop->operator == NULL
+ || !check_access (uop->access, uop->ns->default_access))
+ return;
+
+ mio_symbol_interface (uop->name, nullstring, &uop->operator);
+}
+
+
+/* Write generic interfaces associated with a symbol. */
+
+static void
+write_generic (gfc_symbol * sym)
+{
+
+ if (sym->generic == NULL
+ || !check_access (sym->attr.access, sym->ns->default_access))
+ return;
+
+ mio_symbol_interface (sym->name, sym->module, &sym->generic);
+}
+
+
+static void
+write_symtree (gfc_symtree * st)
+{
+ gfc_symbol *sym;
+ pointer_info *p;
+
+ sym = st->n.sym;
+ if (!check_access (sym->attr.access, sym->ns->default_access)
+ || (sym->attr.flavor == FL_PROCEDURE && sym->attr.generic
+ && !sym->attr.subroutine && !sym->attr.function))
+ return;
+
+ if (check_unique_name (st->name))
+ return;
+
+ p = find_pointer (sym);
+ if (p == NULL)
+ gfc_internal_error ("write_symtree(): Symbol not written");
+
+ mio_internal_string (st->name);
+ mio_integer (&st->ambiguous);
+ mio_integer (&p->integer);
+}
+
+
+static void
+write_module (void)
+{
+ gfc_intrinsic_op i;
+
+ /* Write the operator interfaces. */
+ mio_lparen ();
+
+ for (i = GFC_INTRINSIC_BEGIN; i != GFC_INTRINSIC_END; i++)
+ {
+ if (i == INTRINSIC_USER)
+ continue;
+
+ mio_interface (check_access (gfc_current_ns->operator_access[i],
+ gfc_current_ns->default_access)
+ ? &gfc_current_ns->operator[i] : NULL);
+ }
+
+ mio_rparen ();
+ write_char ('\n');
+ write_char ('\n');
+
+ mio_lparen ();
+ gfc_traverse_user_op (gfc_current_ns, write_operator);
+ mio_rparen ();
+ write_char ('\n');
+ write_char ('\n');
+
+ mio_lparen ();
+ gfc_traverse_ns (gfc_current_ns, write_generic);
+ mio_rparen ();
+ write_char ('\n');
+ write_char ('\n');
+
+ /* Write symbol information. First we traverse all symbols in the
+ primary namespace, writing those that need to be written.
+ Sometimes writing one symbol will cause another to need to be
+ written. A list of these symbols ends up on the write stack, and
+ we end by popping the bottom of the stack and writing the symbol
+ until the stack is empty. */
+
+ mio_lparen ();
+
+ write_symbol0 (gfc_current_ns->sym_root);
+ while (write_symbol1 (pi_root));
+
+ mio_rparen ();
+
+ write_char ('\n');
+ write_char ('\n');
+
+ mio_lparen ();
+ gfc_traverse_symtree (gfc_current_ns, write_symtree);
+ mio_rparen ();
+}
+
+
+/* Given module, dump it to disk. If there was an error while
+ processing the module, dump_flag will be set to zero and we delete
+ the module file, even if it was already there. */
+
+void
+gfc_dump_module (const char *name, int dump_flag)
+{
+ char filename[PATH_MAX], *p;
+ gfc_file *g;
+ time_t now;
+
+ filename[0] = '\0';
+ if (gfc_option.module_dir != NULL)
+ strcpy (filename, gfc_option.module_dir);
+
+ strcat (filename, name);
+ strcat (filename, MODULE_EXTENSION);
+
+ if (!dump_flag)
+ {
+ unlink (filename);
+ return;
+ }
+
+ module_fp = fopen (filename, "w");
+ if (module_fp == NULL)
+ gfc_fatal_error ("Can't open module file '%s' for writing: %s",
+ filename, strerror (errno));
+
+ /* Find the top level filename. */
+ g = gfc_current_file;
+ while (g->next)
+ g = g->next;
+
+ now = time (NULL);
+ p = ctime (&now);
+
+ *strchr (p, '\n') = '\0';
+
+ fprintf (module_fp, "GFORTRAN module created from %s on %s\n", g->filename, p);
+ fputs ("If you edit this, you'll get what you deserve.\n\n", module_fp);
+
+ iomode = IO_OUTPUT;
+ strcpy (module_name, name);
+
+ init_pi_tree ();
+
+ write_module ();
+
+ free_pi_tree (pi_root);
+ pi_root = NULL;
+
+ write_char ('\n');
+
+ if (fclose (module_fp))
+ gfc_fatal_error ("Error writing module file '%s' for writing: %s",
+ filename, strerror (errno));
+}
+
+
+/* Process a USE directive. */
+
+void
+gfc_use_module (void)
+{
+ char filename[GFC_MAX_SYMBOL_LEN + 5];
+ gfc_state_data *p;
+ int c, line;
+
+ strcpy (filename, module_name);
+ strcat (filename, MODULE_EXTENSION);
+
+ module_fp = gfc_open_included_file (filename);
+ if (module_fp == NULL)
+ gfc_fatal_error ("Can't open module file '%s' for reading: %s",
+ filename, strerror (errno));
+
+ iomode = IO_INPUT;
+ module_line = 1;
+ module_column = 1;
+
+ /* Skip the first two lines of the module. */
+ /* FIXME: Could also check for valid two lines here, instead. */
+ line = 0;
+ while (line < 2)
+ {
+ c = module_char ();
+ if (c == EOF)
+ bad_module ("Unexpected end of module");
+ if (c == '\n')
+ line++;
+ }
+
+ /* Make sure we're not reading the same module that we may be building. */
+ for (p = gfc_state_stack; p; p = p->previous)
+ if (p->state == COMP_MODULE && strcmp (p->sym->name, module_name) == 0)
+ gfc_fatal_error ("Can't USE the same module we're building!");
+
+ init_pi_tree ();
+ init_true_name_tree ();
+
+ read_module ();
+
+ free_true_name (true_name_root);
+ true_name_root = NULL;
+
+ free_pi_tree (pi_root);
+ pi_root = NULL;
+
+ fclose (module_fp);
+}
+
+
+void
+gfc_module_init_2 (void)
+{
+
+ last_atom = ATOM_LPAREN;
+}
+
+
+void
+gfc_module_done_2 (void)
+{
+
+ free_rename ();
+}
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
new file mode 100644
index 00000000000..5fb874091e0
--- /dev/null
+++ b/gcc/fortran/options.c
@@ -0,0 +1,321 @@
+/* Parse and display command line options.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation,
+ Inc.
+ Contributed by Andy Vaught
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "flags.h"
+#include "intl.h"
+#include "opts.h"
+#include "options.h"
+#include "tree-inline.h"
+
+#include "gfortran.h"
+
+gfc_option_t gfc_option;
+
+
+/* Get ready for options handling. */
+
+unsigned int
+gfc_init_options (unsigned int argc ATTRIBUTE_UNUSED,
+ const char **argv ATTRIBUTE_UNUSED)
+{
+
+ gfc_option.source = NULL;
+ gfc_option.module_dir = NULL;
+ gfc_option.source_form = FORM_UNKNOWN;
+ gfc_option.fixed_line_length = 72;
+ gfc_option.max_identifier_length = GFC_MAX_SYMBOL_LEN;
+ gfc_option.verbose = 0;
+
+ gfc_option.warn_aliasing = 0;
+ gfc_option.warn_conversion = 0;
+ gfc_option.warn_implicit_interface = 0;
+ gfc_option.warn_line_truncation = 0;
+ gfc_option.warn_surprising = 0;
+ gfc_option.warn_unused_labels = 0;
+
+ gfc_option.flag_dollar_ok = 0;
+ gfc_option.flag_underscoring = 1;
+ gfc_option.flag_second_underscore = 1;
+ gfc_option.flag_implicit_none = 0;
+ gfc_option.flag_max_stack_var_size = 32768;
+ gfc_option.flag_module_access_private = 0;
+ gfc_option.flag_no_backend = 0;
+ gfc_option.flag_pack_derived = 0;
+ gfc_option.flag_repack_arrays = 0;
+
+ gfc_option.q_kind = gfc_default_double_kind ();
+ gfc_option.i8 = 0;
+ gfc_option.r8 = 0;
+ gfc_option.d8 = 0;
+
+ flag_argument_noalias = 2;
+
+ gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F95_DEL
+ | GFC_STD_F2003_OBS | GFC_STD_F2003_DEL | GFC_STD_F2003 | GFC_STD_GNU;
+ gfc_option.warn_std = GFC_STD_F95_OBS | GFC_STD_F95_DEL
+ | GFC_STD_F2003 | GFC_STD_GNU;
+
+ return CL_F95;
+}
+
+
+/* Finalize commandline options. */
+
+bool
+gfc_post_options (const char **pfilename)
+{
+ const char *filename = *pfilename;
+
+ /* Verify the input file name. */
+ if (!filename || strcmp (filename, "-") == 0)
+ {
+ filename = "";
+ }
+
+ gfc_option.source = filename;
+
+ flag_inline_trees = 1;
+
+ /* Use tree inlining. */
+ if (!flag_no_inline)
+ flag_no_inline = 1;
+ if (flag_inline_functions)
+ {
+ flag_inline_trees = 2;
+ flag_inline_functions = 0;
+ }
+
+ return false;
+}
+
+
+/* Set the options for -Wall. */
+
+static void
+set_Wall (void)
+{
+
+ gfc_option.warn_aliasing = 1;
+ gfc_option.warn_line_truncation = 1;
+ gfc_option.warn_surprising = 1;
+ gfc_option.warn_unused_labels = 1;
+
+ set_Wunused (1);
+ warn_return_type = 1;
+ warn_switch = 1;
+
+ /* We save the value of warn_uninitialized, since if they put
+ -Wuninitialized on the command line, we need to generate a
+ warning about not using it without also specifying -O. */
+
+ if (warn_uninitialized != 1)
+ warn_uninitialized = 2;
+}
+
+
+static void
+gfc_handle_module_path_options (const char *arg)
+{
+
+ if (gfc_option.module_dir != NULL)
+ {
+ gfc_status ("gfortran: Only one -M option allowed\n");
+ exit (3);
+ }
+
+ if (arg == NULL)
+ {
+ gfc_status ("gfortran: Directory required after -M\n");
+ exit (3);
+ }
+
+ gfc_option.module_dir = (char *) gfc_getmem (strlen (arg));
+ strcpy (gfc_option.module_dir, arg);
+ strcat (gfc_option.module_dir, "/");
+}
+
+/* Handle command-line options. Returns 0 if unrecognized, 1 if
+ recognized and handled. */
+int
+gfc_handle_option (size_t scode, const char *arg, int value)
+{
+ int result = 1;
+ enum opt_code code = (enum opt_code) scode;
+
+ /* Ignore file names. */
+ if (code == N_OPTS)
+ return 1;
+
+ switch (code)
+ {
+ default:
+ result = 0;
+ break;
+
+ case OPT_Wall:
+ set_Wall ();
+ break;
+
+ case OPT_Waliasing:
+ gfc_option.warn_aliasing = value;
+ break;
+
+ case OPT_Wconversion:
+ gfc_option.warn_conversion = value;
+ break;
+
+ case OPT_Wimplicit_interface:
+ gfc_option.warn_implicit_interface = value;
+ break;
+
+ case OPT_Wline_truncation:
+ gfc_option.warn_line_truncation = value;
+ break;
+
+ case OPT_Wsurprising:
+ gfc_option.warn_surprising = value;
+ break;
+
+ case OPT_Wunused_labels:
+ gfc_option.warn_unused_labels = value;
+ break;
+
+ case OPT_fdollar_ok:
+ gfc_option.flag_dollar_ok = value;
+ break;
+
+ case OPT_fdump_parse_tree:
+ gfc_option.verbose = value;
+ break;
+
+ case OPT_ffixed_form:
+ gfc_option.source_form = FORM_FIXED;
+ break;
+
+ case OPT_ffree_form:
+ gfc_option.source_form = FORM_FREE;
+ break;
+
+ case OPT_funderscoring:
+ gfc_option.flag_underscoring = value;
+ break;
+
+ case OPT_fsecond_underscore:
+ gfc_option.flag_second_underscore = value;
+ break;
+
+ case OPT_fimplicit_none:
+ gfc_option.flag_implicit_none = value;
+ break;
+
+ case OPT_fmax_stack_var_size_:
+ gfc_option.flag_max_stack_var_size = value;
+ break;
+
+ case OPT_fmodule_private:
+ gfc_option.flag_module_access_private = value;
+ break;
+
+ case OPT_fno_backend:
+ gfc_option.flag_no_backend = value;
+ break;
+
+ case OPT_fpack_derived:
+ gfc_option.flag_pack_derived = value;
+ break;
+
+ case OPT_frepack_arrays:
+ gfc_option.flag_repack_arrays = value;
+ break;
+
+ case OPT_ffixed_line_length_80:
+ gfc_option.fixed_line_length = 80;
+ break;
+
+ case OPT_ffixed_line_length_132:
+ gfc_option.fixed_line_length = 132;
+ break;
+
+ case OPT_fmax_identifier_length_:
+ if (value > GFC_MAX_SYMBOL_LEN)
+ gfc_fatal_error ("Maximum supported idenitifier length is %d",
+ GFC_MAX_SYMBOL_LEN);
+ gfc_option.max_identifier_length = value;
+ break;
+
+ case OPT_qkind_:
+ if (gfc_validate_kind (BT_REAL, value) < 0)
+ gfc_fatal_error ("Argument to -fqkind isn't a valid real kind");
+ gfc_option.q_kind = value;
+ break;
+
+ case OPT_i8:
+ gfc_option.i8 = value;
+ break;
+
+ case OPT_r8:
+ gfc_option.r8 = value;
+ break;
+
+ case OPT_d8:
+ gfc_option.d8 = value;
+ break;
+
+ case OPT_I:
+ gfc_add_include_path (arg);
+ break;
+
+ case OPT_J:
+ case OPT_M:
+ gfc_handle_module_path_options (arg);
+
+ case OPT_std_f95:
+ gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F2003_OBS
+ | GFC_STD_F2003_DEL;
+ gfc_option.warn_std = GFC_STD_F95_OBS;
+ gfc_option.max_identifier_length = 31;
+ break;
+
+ case OPT_std_f2003:
+ gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F2003_OBS
+ | GFC_STD_F2003;
+ gfc_option.warn_std = GFC_STD_F95_OBS | GFC_STD_F2003_OBS;
+ gfc_option.max_identifier_length = 63;
+ break;
+
+ case OPT_std_gnu:
+ gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F95_DEL
+ | GFC_STD_F2003_OBS | GFC_STD_F2003_DEL | GFC_STD_F2003 | GFC_STD_GNU;
+ gfc_option.warn_std = GFC_STD_F95_OBS | GFC_STD_F95_DEL
+ | GFC_STD_F2003_OBS | GFC_STD_F2003_DEL | GFC_STD_GNU;
+ break;
+ }
+
+ return result;
+}
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
new file mode 100644
index 00000000000..beec9d622ba
--- /dev/null
+++ b/gcc/fortran/parse.c
@@ -0,0 +1,2504 @@
+/* Main parser.
+ Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#include "config.h"
+#include <string.h>
+#include <setjmp.h>
+
+#include "gfortran.h"
+#include "match.h"
+#include "parse.h"
+
+/* Current statement label. Zero means no statement label. Because
+ new_st can get wiped during statement matching, we have to keep it
+ separate. */
+
+gfc_st_label *gfc_statement_label;
+
+static locus label_locus;
+static jmp_buf eof;
+
+gfc_state_data *gfc_state_stack;
+
+/* TODO: Re-order functions to kill these forward decls. */
+static void check_statement_label (gfc_statement);
+static void undo_new_statement (void);
+static void reject_statement (void);
+
+/* A sort of half-matching function. We try to match the word on the
+ input with the passed string. If this succeeds, we call the
+ keyword-dependent matching function that will match the rest of the
+ statement. For single keywords, the matching subroutine is
+ gfc_match_eos(). */
+
+static match
+match_word (const char *str, match (*subr) (void), locus * old_locus)
+{
+ match m;
+
+ if (str != NULL)
+ {
+ m = gfc_match (str);
+ if (m != MATCH_YES)
+ return m;
+ }
+
+ m = (*subr) ();
+
+ if (m != MATCH_YES)
+ {
+ gfc_set_locus (old_locus);
+ reject_statement ();
+ }
+
+ return m;
+}
+
+
+/* Figure out what the next statement is, (mostly) regardless of
+ proper ordering. */
+
+#define match(keyword, subr, st) \
+ if (match_word(keyword, subr, &old_locus) == MATCH_YES) \
+ return st; \
+ else \
+ undo_new_statement ();
+
+static gfc_statement
+decode_statement (void)
+{
+ gfc_statement st;
+ locus old_locus;
+ match m;
+ int c;
+
+#ifdef GFC_DEBUG
+ gfc_symbol_state ();
+#endif
+
+ gfc_clear_error (); /* Clear any pending errors. */
+ gfc_clear_warning (); /* Clear any pending warnings. */
+
+ if (gfc_match_eos () == MATCH_YES)
+ return ST_NONE;
+
+ old_locus = *gfc_current_locus ();
+
+ /* Try matching a data declaration or function declaration. The
+ input "REALFUNCTIONA(N)" can mean several things in different
+ contexts, so it (and its relatives) get special treatment. */
+
+ if (gfc_current_state () == COMP_NONE
+ || gfc_current_state () == COMP_INTERFACE
+ || gfc_current_state () == COMP_CONTAINS)
+ {
+ m = gfc_match_function_decl ();
+ if (m == MATCH_YES)
+ return ST_FUNCTION;
+ else if (m == MATCH_ERROR)
+ reject_statement ();
+
+ gfc_undo_symbols ();
+ gfc_set_locus (&old_locus);
+ }
+
+ /* Match statements whose error messages are meant to be overwritten
+ by something better. */
+
+ match (NULL, gfc_match_assignment, ST_ASSIGNMENT);
+ match (NULL, gfc_match_pointer_assignment, ST_POINTER_ASSIGNMENT);
+ match (NULL, gfc_match_st_function, ST_STATEMENT_FUNCTION);
+
+ match (NULL, gfc_match_data_decl, ST_DATA_DECL);
+
+ /* Try to match a subroutine statement, which has the same optional
+ prefixes that functions can have. */
+
+ if (gfc_match_subroutine () == MATCH_YES)
+ return ST_SUBROUTINE;
+ gfc_undo_symbols ();
+ gfc_set_locus (&old_locus);
+
+ /* Check for the IF, DO, SELECT, WHERE and FORALL statements, which
+ might begin with a block label. The match functions for these
+ statements are unusual in that their keyword is not seen before
+ the matcher is called. */
+
+ if (gfc_match_if (&st) == MATCH_YES)
+ return st;
+ gfc_undo_symbols ();
+ gfc_set_locus (&old_locus);
+
+ if (gfc_match_where (&st) == MATCH_YES)
+ return st;
+ gfc_undo_symbols ();
+ gfc_set_locus (&old_locus);
+
+ if (gfc_match_forall (&st) == MATCH_YES)
+ return st;
+ gfc_undo_symbols ();
+ gfc_set_locus (&old_locus);
+
+ match (NULL, gfc_match_do, ST_DO);
+ match (NULL, gfc_match_select, ST_SELECT_CASE);
+
+ /* General statement matching: Instead of testing every possible
+ statement, we eliminate most possibilities by peeking at the
+ first character. */
+
+ c = gfc_peek_char ();
+
+ switch (c)
+ {
+ case 'a':
+ match ("allocate", gfc_match_allocate, ST_ALLOCATE);
+ match ("allocatable", gfc_match_allocatable, ST_ATTR_DECL);
+ match ("assign", gfc_match_assign, ST_LABEL_ASSIGNMENT);
+ break;
+
+ case 'b':
+ match ("backspace", gfc_match_backspace, ST_BACKSPACE);
+ match ("block data", gfc_match_block_data, ST_BLOCK_DATA);
+ break;
+
+ case 'c':
+ match ("call", gfc_match_call, ST_CALL);
+ match ("close", gfc_match_close, ST_CLOSE);
+ match ("continue", gfc_match_continue, ST_CONTINUE);
+ match ("cycle", gfc_match_cycle, ST_CYCLE);
+ match ("case", gfc_match_case, ST_CASE);
+ match ("common", gfc_match_common, ST_COMMON);
+ match ("contains", gfc_match_eos, ST_CONTAINS);
+ break;
+
+ case 'd':
+ match ("deallocate", gfc_match_deallocate, ST_DEALLOCATE);
+ match ("data", gfc_match_data, ST_DATA);
+ match ("dimension", gfc_match_dimension, ST_ATTR_DECL);
+ break;
+
+ case 'e':
+ match ("end file", gfc_match_endfile, ST_END_FILE);
+ match ("exit", gfc_match_exit, ST_EXIT);
+ match ("else", gfc_match_else, ST_ELSE);
+ match ("else where", gfc_match_elsewhere, ST_ELSEWHERE);
+ match ("else if", gfc_match_elseif, ST_ELSEIF);
+
+ if (gfc_match_end (&st) == MATCH_YES)
+ return st;
+
+ match ("entry", gfc_match_entry, ST_ENTRY);
+ match ("equivalence", gfc_match_equivalence, ST_EQUIVALENCE);
+ match ("external", gfc_match_external, ST_ATTR_DECL);
+ break;
+
+ case 'f':
+ match ("format", gfc_match_format, ST_FORMAT);
+ break;
+
+ case 'g':
+ match ("go to", gfc_match_goto, ST_GOTO);
+ break;
+
+ case 'i':
+ match ("inquire", gfc_match_inquire, ST_INQUIRE);
+ match ("implicit", gfc_match_implicit, ST_IMPLICIT);
+ match ("implicit% none", gfc_match_implicit_none, ST_IMPLICIT_NONE);
+ match ("interface", gfc_match_interface, ST_INTERFACE);
+ match ("intent", gfc_match_intent, ST_ATTR_DECL);
+ match ("intrinsic", gfc_match_intrinsic, ST_ATTR_DECL);
+ break;
+
+ case 'm':
+ match ("module% procedure", gfc_match_modproc, ST_MODULE_PROC);
+ match ("module", gfc_match_module, ST_MODULE);
+ break;
+
+ case 'n':
+ match ("nullify", gfc_match_nullify, ST_NULLIFY);
+ match ("namelist", gfc_match_namelist, ST_NAMELIST);
+ break;
+
+ case 'o':
+ match ("open", gfc_match_open, ST_OPEN);
+ match ("optional", gfc_match_optional, ST_ATTR_DECL);
+ break;
+
+ case 'p':
+ match ("print", gfc_match_print, ST_WRITE);
+ match ("parameter", gfc_match_parameter, ST_PARAMETER);
+ match ("pause", gfc_match_pause, ST_PAUSE);
+ match ("pointer", gfc_match_pointer, ST_ATTR_DECL);
+ if (gfc_match_private (&st) == MATCH_YES)
+ return st;
+ match ("program", gfc_match_program, ST_PROGRAM);
+ if (gfc_match_public (&st) == MATCH_YES)
+ return st;
+ break;
+
+ case 'r':
+ match ("read", gfc_match_read, ST_READ);
+ match ("return", gfc_match_return, ST_RETURN);
+ match ("rewind", gfc_match_rewind, ST_REWIND);
+ break;
+
+ case 's':
+ match ("sequence", gfc_match_eos, ST_SEQUENCE);
+ match ("stop", gfc_match_stop, ST_STOP);
+ match ("save", gfc_match_save, ST_ATTR_DECL);
+ break;
+
+ case 't':
+ match ("target", gfc_match_target, ST_ATTR_DECL);
+ match ("type", gfc_match_derived_decl, ST_DERIVED_DECL);
+ break;
+
+ case 'u':
+ match ("use", gfc_match_use, ST_USE);
+ break;
+
+ case 'w':
+ match ("write", gfc_match_write, ST_WRITE);
+ break;
+ }
+
+ /* All else has failed, so give up. See if any of the matchers has
+ stored an error message of some sort. */
+
+ if (gfc_error_check () == 0)
+ gfc_error_now ("Unclassifiable statement at %C");
+
+ reject_statement ();
+
+ gfc_error_recovery ();
+
+ return ST_NONE;
+}
+
+#undef match
+
+
+/* Get the next statement in free form source. */
+
+static gfc_statement
+next_free (void)
+{
+ match m;
+ int c, d;
+
+ gfc_gobble_whitespace ();
+
+ c = gfc_peek_char ();
+
+ if (ISDIGIT (c))
+ {
+ /* Found a statement label? */
+ m = gfc_match_st_label (&gfc_statement_label, 0);
+
+ d = gfc_peek_char ();
+ if (m != MATCH_YES || !gfc_is_whitespace (d))
+ {
+ do
+ {
+ /* Skip the bad statement label. */
+ gfc_warning_now ("Ignoring bad statement label at %C");
+ c = gfc_next_char ();
+ }
+ while (ISDIGIT (c));
+ }
+ else
+ {
+ label_locus = *gfc_current_locus ();
+
+ if (gfc_statement_label->value == 0)
+ {
+ gfc_warning_now ("Ignoring statement label of zero at %C");
+ gfc_free_st_label (gfc_statement_label);
+ gfc_statement_label = NULL;
+ }
+
+ gfc_gobble_whitespace ();
+
+ if (gfc_match_eos () == MATCH_YES)
+ {
+ gfc_warning_now
+ ("Ignoring statement label in empty statement at %C");
+ gfc_free_st_label (gfc_statement_label);
+ gfc_statement_label = NULL;
+ return ST_NONE;
+ }
+ }
+ }
+
+ return decode_statement ();
+}
+
+
+/* Get the next statement in fixed-form source. */
+
+static gfc_statement
+next_fixed (void)
+{
+ int label, digit_flag, i;
+ locus loc;
+ char c;
+
+ if (!gfc_at_bol ())
+ return decode_statement ();
+
+ /* Skip past the current label field, parsing a statement label if
+ one is there. This is a weird number parser, since the number is
+ contained within five columns and can have any kind of embedded
+ spaces. We also check for characters that make the rest of the
+ line a comment. */
+
+ label = 0;
+ digit_flag = 0;
+
+ for (i = 0; i < 5; i++)
+ {
+ c = gfc_next_char_literal (0);
+
+ switch (c)
+ {
+ case ' ':
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ label = label * 10 + c - '0';
+ label_locus = *gfc_current_locus ();
+ digit_flag = 1;
+ break;
+
+ /* Comments have already been skipped by the time we get
+ here so don't bother checking for them. */
+
+ default:
+ gfc_buffer_error (0);
+ gfc_error ("Non-numeric character in statement label at %C");
+ return ST_NONE;
+ }
+ }
+
+ if (digit_flag)
+ {
+ if (label == 0)
+ gfc_warning_now ("Zero is not a valid statement label at %C");
+ else
+ {
+ /* We've found a valid statement label. */
+ gfc_statement_label = gfc_get_st_label (label);
+ }
+ }
+
+ /* Since this line starts a statement, it cannot be a continuation
+ of a previous statement. If we see something here besides a
+ space or zero, it must be a bad continuation line. */
+
+ c = gfc_next_char_literal (0);
+ if (c == '\n')
+ goto blank_line;
+
+ if (c != ' ' && c!= '0')
+ {
+ gfc_buffer_error (0);
+ gfc_error ("Bad continuation line at %C");
+ return ST_NONE;
+ }
+
+ /* Now that we've taken care of the statement label columns, we have
+ to make sure that the first nonblank character is not a '!'. If
+ it is, the rest of the line is a comment. */
+
+ do
+ {
+ loc = *gfc_current_locus ();
+ c = gfc_next_char_literal (0);
+ }
+ while (gfc_is_whitespace (c));
+
+ if (c == '!')
+ goto blank_line;
+ gfc_set_locus (&loc);
+
+ if (gfc_match_eos () == MATCH_YES)
+ goto blank_line;
+
+ /* At this point, we've got a nonblank statement to parse. */
+ return decode_statement ();
+
+blank_line:
+ if (digit_flag)
+ gfc_warning ("Statement label in blank line will be " "ignored at %C");
+ gfc_advance_line ();
+ return ST_NONE;
+}
+
+
+/* Return the next non-ST_NONE statement to the caller. We also worry
+ about including files and the ends of include files at this stage. */
+
+static gfc_statement
+next_statement (void)
+{
+ gfc_statement st;
+
+ gfc_new_block = NULL;
+
+ for (;;)
+ {
+ gfc_statement_label = NULL;
+ gfc_buffer_error (1);
+
+ if (gfc_at_eol ())
+ gfc_advance_line ();
+
+ gfc_skip_comments ();
+
+ if (gfc_at_bol () && gfc_check_include ())
+ continue;
+
+ if (gfc_at_eof () && gfc_current_file->included_by != NULL)
+ {
+ gfc_current_file = gfc_current_file->included_by;
+ gfc_advance_line ();
+ continue;
+ }
+
+ if (gfc_at_end ())
+ {
+ st = ST_NONE;
+ break;
+ }
+
+ st =
+ (gfc_current_file->form == FORM_FIXED) ? next_fixed () : next_free ();
+ if (st != ST_NONE)
+ break;
+ }
+
+ gfc_buffer_error (0);
+
+ if (st != ST_NONE)
+ check_statement_label (st);
+
+ return st;
+}
+
+
+/****************************** Parser ***********************************/
+
+/* The parser subroutines are of type 'try' that fail if the file ends
+ unexpectedly. */
+
+/* Macros that expand to case-labels for various classes of
+ statements. Start with executable statements that directly do
+ things. */
+
+#define case_executable case ST_ALLOCATE: case ST_BACKSPACE: case ST_CALL: \
+ case ST_CLOSE: case ST_CONTINUE: case ST_DEALLOCATE: case ST_END_FILE: \
+ case ST_GOTO: case ST_INQUIRE: case ST_NULLIFY: case ST_OPEN: \
+ case ST_READ: case ST_RETURN: case ST_REWIND: case ST_SIMPLE_IF: \
+ case ST_PAUSE: case ST_STOP: case ST_WRITE: case ST_ASSIGNMENT: \
+ case ST_POINTER_ASSIGNMENT: case ST_EXIT: case ST_CYCLE: \
+ case ST_ARITHMETIC_IF: case ST_WHERE: case ST_FORALL: case ST_LABEL_ASSIGNMENT
+
+/* Statements that mark other executable statements. */
+
+#define case_exec_markers case ST_DO: case ST_FORALL_BLOCK: case ST_IF_BLOCK: \
+ case ST_WHERE_BLOCK: case ST_SELECT_CASE
+
+/* Declaration statements */
+
+#define case_decl case ST_ATTR_DECL: case ST_COMMON: case ST_DATA_DECL: \
+ case ST_EQUIVALENCE: case ST_NAMELIST: case ST_STATEMENT_FUNCTION: \
+ case ST_TYPE: case ST_INTERFACE
+
+/* Block end statements. Errors associated with interchanging these
+ are detected in gfc_match_end(). */
+
+#define case_end case ST_END_BLOCK_DATA: case ST_END_FUNCTION: \
+ case ST_END_PROGRAM: case ST_END_SUBROUTINE
+
+
+/* Push a new state onto the stack. */
+
+static void
+push_state (gfc_state_data * p, gfc_compile_state new_state, gfc_symbol * sym)
+{
+
+ p->state = new_state;
+ p->previous = gfc_state_stack;
+ p->sym = sym;
+ p->head = p->tail = NULL;
+
+ gfc_state_stack = p;
+}
+
+
+/* Pop the current state. */
+
+static void
+pop_state (void)
+{
+
+ gfc_state_stack = gfc_state_stack->previous;
+}
+
+
+/* Try to find the given state in the state stack. */
+
+try
+gfc_find_state (gfc_compile_state state)
+{
+ gfc_state_data *p;
+
+ for (p = gfc_state_stack; p; p = p->previous)
+ if (p->state == state)
+ break;
+
+ return (p == NULL) ? FAILURE : SUCCESS;
+}
+
+
+/* Starts a new level in the statement list. */
+
+static gfc_code *
+new_level (gfc_code * q)
+{
+ gfc_code *p;
+
+ p = q->block = gfc_get_code ();
+
+ gfc_state_stack->head = gfc_state_stack->tail = p;
+
+ return p;
+}
+
+
+/* Add the current new_st code structure and adds it to the current
+ program unit. As a side-effect, it zeroes the new_st. */
+
+static gfc_code *
+add_statement (void)
+{
+ gfc_code *p;
+
+ p = gfc_get_code ();
+ *p = new_st;
+
+ p->loc = *gfc_current_locus ();
+
+ if (gfc_state_stack->head == NULL)
+ gfc_state_stack->head = p;
+ else
+ gfc_state_stack->tail->next = p;
+
+ while (p->next != NULL)
+ p = p->next;
+
+ gfc_state_stack->tail = p;
+
+ gfc_clear_new_st ();
+
+ return p;
+}
+
+
+/* Frees everything associated with the current statement. */
+
+static void
+undo_new_statement (void)
+{
+ gfc_free_statements (new_st.block);
+ gfc_free_statements (new_st.next);
+ gfc_free_statement (&new_st);
+ gfc_clear_new_st ();
+}
+
+
+/* If the current statement has a statement label, make sure that it
+ is allowed to, or should have one. */
+
+static void
+check_statement_label (gfc_statement st)
+{
+ gfc_sl_type type;
+
+ if (gfc_statement_label == NULL)
+ {
+ if (st == ST_FORMAT)
+ gfc_error ("FORMAT statement at %L does not have a statement label",
+ &new_st.loc);
+ return;
+ }
+
+ switch (st)
+ {
+ case ST_END_PROGRAM:
+ case ST_END_FUNCTION:
+ case ST_END_SUBROUTINE:
+ case ST_ENDDO:
+ case ST_ENDIF:
+ case ST_END_SELECT:
+ case_executable:
+ case_exec_markers:
+ type = ST_LABEL_TARGET;
+ break;
+
+ case ST_FORMAT:
+ type = ST_LABEL_FORMAT;
+ break;
+
+ /* Statement labels are not restricted from appearing on a
+ particular line. However, there are plenty of situations
+ where the resulting label can't be referenced. */
+
+ default:
+ type = ST_LABEL_BAD_TARGET;
+ break;
+ }
+
+ gfc_define_st_label (gfc_statement_label, type, &label_locus);
+
+ new_st.here = gfc_statement_label;
+}
+
+
+/* Figures out what the enclosing program unit is. This will be a
+ function, subroutine, program, block data or module. */
+
+gfc_state_data *
+gfc_enclosing_unit (gfc_compile_state * result)
+{
+ gfc_state_data *p;
+
+ for (p = gfc_state_stack; p; p = p->previous)
+ if (p->state == COMP_FUNCTION || p->state == COMP_SUBROUTINE
+ || p->state == COMP_MODULE || p->state == COMP_BLOCK_DATA
+ || p->state == COMP_PROGRAM)
+ {
+
+ if (result != NULL)
+ *result = p->state;
+ return p;
+ }
+
+ if (result != NULL)
+ *result = COMP_PROGRAM;
+ return NULL;
+}
+
+
+/* Translate a statement enum to a string. */
+
+const char *
+gfc_ascii_statement (gfc_statement st)
+{
+ const char *p;
+
+ switch (st)
+ {
+ case ST_ARITHMETIC_IF:
+ p = "arithmetic IF";
+ break;
+ case ST_ALLOCATE:
+ p = "ALLOCATE";
+ break;
+ case ST_ATTR_DECL:
+ p = "attribute declaration";
+ break;
+ case ST_BACKSPACE:
+ p = "BACKSPACE";
+ break;
+ case ST_BLOCK_DATA:
+ p = "BLOCK DATA";
+ break;
+ case ST_CALL:
+ p = "CALL";
+ break;
+ case ST_CASE:
+ p = "CASE";
+ break;
+ case ST_CLOSE:
+ p = "CLOSE";
+ break;
+ case ST_COMMON:
+ p = "COMMON";
+ break;
+ case ST_CONTINUE:
+ p = "CONTINUE";
+ break;
+ case ST_CONTAINS:
+ p = "CONTAINS";
+ break;
+ case ST_CYCLE:
+ p = "CYCLE";
+ break;
+ case ST_DATA_DECL:
+ p = "data declaration";
+ break;
+ case ST_DATA:
+ p = "DATA";
+ break;
+ case ST_DEALLOCATE:
+ p = "DEALLOCATE";
+ break;
+ case ST_DERIVED_DECL:
+ p = "Derived type declaration";
+ break;
+ case ST_DO:
+ p = "DO";
+ break;
+ case ST_ELSE:
+ p = "ELSE";
+ break;
+ case ST_ELSEIF:
+ p = "ELSE IF";
+ break;
+ case ST_ELSEWHERE:
+ p = "ELSEWHERE";
+ break;
+ case ST_END_BLOCK_DATA:
+ p = "END BLOCK DATA";
+ break;
+ case ST_ENDDO:
+ p = "END DO";
+ break;
+ case ST_END_FILE:
+ p = "END FILE";
+ break;
+ case ST_END_FORALL:
+ p = "END FORALL";
+ break;
+ case ST_END_FUNCTION:
+ p = "END FUNCTION";
+ break;
+ case ST_ENDIF:
+ p = "END IF";
+ break;
+ case ST_END_INTERFACE:
+ p = "END INTERFACE";
+ break;
+ case ST_END_MODULE:
+ p = "END MODULE";
+ break;
+ case ST_END_PROGRAM:
+ p = "END PROGRAM";
+ break;
+ case ST_END_SELECT:
+ p = "END SELECT";
+ break;
+ case ST_END_SUBROUTINE:
+ p = "END SUBROUTINE";
+ break;
+ case ST_END_WHERE:
+ p = "END WHERE";
+ break;
+ case ST_END_TYPE:
+ p = "END TYPE";
+ break;
+ case ST_ENTRY:
+ p = "ENTRY";
+ break;
+ case ST_EQUIVALENCE:
+ p = "EQUIVALENCE";
+ break;
+ case ST_EXIT:
+ p = "EXIT";
+ break;
+ case ST_FORALL_BLOCK: /* Fall through */
+ case ST_FORALL:
+ p = "FORALL";
+ break;
+ case ST_FORMAT:
+ p = "FORMAT";
+ break;
+ case ST_FUNCTION:
+ p = "FUNCTION";
+ break;
+ case ST_GOTO:
+ p = "GOTO";
+ break;
+ case ST_IF_BLOCK:
+ p = "block IF";
+ break;
+ case ST_IMPLICIT:
+ p = "IMPLICIT";
+ break;
+ case ST_IMPLICIT_NONE:
+ p = "IMPLICIT NONE";
+ break;
+ case ST_IMPLIED_ENDDO:
+ p = "implied END DO";
+ break;
+ case ST_INQUIRE:
+ p = "INQUIRE";
+ break;
+ case ST_INTERFACE:
+ p = "INTERFACE";
+ break;
+ case ST_PARAMETER:
+ p = "PARAMETER";
+ break;
+ case ST_PRIVATE:
+ p = "PRIVATE";
+ break;
+ case ST_PUBLIC:
+ p = "PUBLIC";
+ break;
+ case ST_MODULE:
+ p = "MODULE";
+ break;
+ case ST_PAUSE:
+ p = "PAUSE";
+ break;
+ case ST_MODULE_PROC:
+ p = "MODULE PROCEDURE";
+ break;
+ case ST_NAMELIST:
+ p = "NAMELIST";
+ break;
+ case ST_NULLIFY:
+ p = "NULLIFY";
+ break;
+ case ST_OPEN:
+ p = "OPEN";
+ break;
+ case ST_PROGRAM:
+ p = "PROGRAM";
+ break;
+ case ST_READ:
+ p = "READ";
+ break;
+ case ST_RETURN:
+ p = "RETURN";
+ break;
+ case ST_REWIND:
+ p = "REWIND";
+ break;
+ case ST_STOP:
+ p = "STOP";
+ break;
+ case ST_SUBROUTINE:
+ p = "SUBROUTINE";
+ break;
+ case ST_TYPE:
+ p = "TYPE";
+ break;
+ case ST_USE:
+ p = "USE";
+ break;
+ case ST_WHERE_BLOCK: /* Fall through */
+ case ST_WHERE:
+ p = "WHERE";
+ break;
+ case ST_WRITE:
+ p = "WRITE";
+ break;
+ case ST_ASSIGNMENT:
+ p = "assignment";
+ break;
+ case ST_POINTER_ASSIGNMENT:
+ p = "pointer assignment";
+ break;
+ case ST_SELECT_CASE:
+ p = "SELECT CASE";
+ break;
+ case ST_SEQUENCE:
+ p = "SEQUENCE";
+ break;
+ case ST_SIMPLE_IF:
+ p = "Simple IF";
+ break;
+ case ST_STATEMENT_FUNCTION:
+ p = "STATEMENT FUNCTION";
+ break;
+ case ST_LABEL_ASSIGNMENT:
+ p = "LABEL ASSIGNMENT";
+ break;
+ default:
+ gfc_internal_error ("gfc_ascii_statement(): Bad statement code");
+ }
+
+ return p;
+}
+
+
+/* Return the name of a compile state. */
+
+const char *
+gfc_state_name (gfc_compile_state state)
+{
+ const char *p;
+
+ switch (state)
+ {
+ case COMP_PROGRAM:
+ p = "a PROGRAM";
+ break;
+ case COMP_MODULE:
+ p = "a MODULE";
+ break;
+ case COMP_SUBROUTINE:
+ p = "a SUBROUTINE";
+ break;
+ case COMP_FUNCTION:
+ p = "a FUNCTION";
+ break;
+ case COMP_BLOCK_DATA:
+ p = "a BLOCK DATA";
+ break;
+ case COMP_INTERFACE:
+ p = "an INTERFACE";
+ break;
+ case COMP_DERIVED:
+ p = "a DERIVED TYPE block";
+ break;
+ case COMP_IF:
+ p = "an IF-THEN block";
+ break;
+ case COMP_DO:
+ p = "a DO block";
+ break;
+ case COMP_SELECT:
+ p = "a SELECT block";
+ break;
+ case COMP_FORALL:
+ p = "a FORALL block";
+ break;
+ case COMP_WHERE:
+ p = "a WHERE block";
+ break;
+ case COMP_CONTAINS:
+ p = "a contained subprogram";
+ break;
+
+ default:
+ gfc_internal_error ("gfc_state_name(): Bad state");
+ }
+
+ return p;
+}
+
+
+/* Do whatever is necessary to accept the last statement. */
+
+static void
+accept_statement (gfc_statement st)
+{
+
+ switch (st)
+ {
+ case ST_USE:
+ gfc_use_module ();
+ break;
+
+ case ST_IMPLICIT_NONE:
+ gfc_set_implicit_none ();
+ break;
+
+ case ST_IMPLICIT:
+ gfc_set_implicit ();
+ break;
+
+ case ST_FUNCTION:
+ case ST_SUBROUTINE:
+ case ST_MODULE:
+ gfc_current_ns->proc_name = gfc_new_block;
+ break;
+
+ /* If the statement is the end of a block, lay down a special code
+ that allows a branch to the end of the block from within the
+ construct. */
+
+ case ST_ENDIF:
+ case ST_ENDDO:
+ case ST_END_SELECT:
+ if (gfc_statement_label != NULL)
+ {
+ new_st.op = EXEC_NOP;
+ add_statement ();
+ }
+
+ break;
+
+ /* The end-of-program unit statements do not get the special
+ marker and require a statement of some sort if they are a
+ branch target. */
+
+ case ST_END_PROGRAM:
+ case ST_END_FUNCTION:
+ case ST_END_SUBROUTINE:
+ if (gfc_statement_label != NULL)
+ {
+ new_st.op = EXEC_RETURN;
+ add_statement ();
+ }
+
+ break;
+
+ case ST_BLOCK_DATA:
+ {
+ gfc_symbol *block_data = NULL;
+ symbol_attribute attr;
+
+ gfc_get_symbol ("_BLOCK_DATA__", gfc_current_ns, &block_data);
+ gfc_clear_attr (&attr);
+ attr.flavor = FL_PROCEDURE;
+ attr.proc = PROC_UNKNOWN;
+ attr.subroutine = 1;
+ attr.access = ACCESS_PUBLIC;
+ block_data->attr = attr;
+ gfc_current_ns->proc_name = block_data;
+ gfc_commit_symbols ();
+ }
+
+ break;
+
+ case_executable:
+ case_exec_markers:
+ add_statement ();
+ break;
+
+ default:
+ break;
+ }
+
+ gfc_commit_symbols ();
+ gfc_warning_check ();
+ gfc_clear_new_st ();
+}
+
+
+/* Undo anything tentative that has been built for the current
+ statement. */
+
+static void
+reject_statement (void)
+{
+
+ gfc_undo_symbols ();
+ gfc_clear_warning ();
+ undo_new_statement ();
+}
+
+
+/* Generic complaint about an out of order statement. We also do
+ whatever is necessary to clean up. */
+
+static void
+unexpected_statement (gfc_statement st)
+{
+
+ gfc_error ("Unexpected %s statement at %C", gfc_ascii_statement (st));
+
+ reject_statement ();
+}
+
+
+/* Given the next statement seen by the matcher, make sure that it is
+ in proper order with the last. This subroutine is initialized by
+ calling it with an argument of ST_NONE. If there is a problem, we
+ issue an error and return FAILURE. Otherwise we return SUCCESS.
+
+ Individual parsers need to verify that the statements seen are
+ valid before calling here, ie ENTRY statements are not allowed in
+ INTERFACE blocks. The following diagram is taken from the standard:
+
+ +---------------------------------------+
+ | program subroutine function module |
+ +---------------------------------------+
+ | use |
+ |---------------------------------------+
+ | | implicit none |
+ | +-----------+------------------+
+ | | parameter | implicit |
+ | +-----------+------------------+
+ | format | | derived type |
+ | entry | parameter | interface |
+ | | data | specification |
+ | | | statement func |
+ | +-----------+------------------+
+ | | data | executable |
+ +--------+-----------+------------------+
+ | contains |
+ +---------------------------------------+
+ | internal module/subprogram |
+ +---------------------------------------+
+ | end |
+ +---------------------------------------+
+
+*/
+
+typedef struct
+{
+ enum
+ { ORDER_START, ORDER_USE, ORDER_IMPLICIT_NONE, ORDER_IMPLICIT,
+ ORDER_SPEC, ORDER_EXEC
+ }
+ state;
+ gfc_statement last_statement;
+ locus where;
+}
+st_state;
+
+static try
+verify_st_order (st_state * p, gfc_statement st)
+{
+
+ switch (st)
+ {
+ case ST_NONE:
+ p->state = ORDER_START;
+ break;
+
+ case ST_USE:
+ if (p->state > ORDER_USE)
+ goto order;
+ p->state = ORDER_USE;
+ break;
+
+ case ST_IMPLICIT_NONE:
+ if (p->state > ORDER_IMPLICIT_NONE)
+ goto order;
+
+ /* The '>' sign cannot be a '>=', because a FORMAT or ENTRY
+ statement disqualifies a USE but not an IMPLICIT NONE.
+ Duplicate IMPLICIT NONEs are caught when the implicit types
+ are set. */
+
+ p->state = ORDER_IMPLICIT_NONE;
+ break;
+
+ case ST_IMPLICIT:
+ if (p->state > ORDER_IMPLICIT)
+ goto order;
+ p->state = ORDER_IMPLICIT;
+ break;
+
+ case ST_FORMAT:
+ case ST_ENTRY:
+ if (p->state < ORDER_IMPLICIT_NONE)
+ p->state = ORDER_IMPLICIT_NONE;
+ break;
+
+ case ST_PARAMETER:
+ if (p->state >= ORDER_EXEC)
+ goto order;
+ if (p->state < ORDER_IMPLICIT)
+ p->state = ORDER_IMPLICIT;
+ break;
+
+ case ST_DATA:
+ if (p->state < ORDER_SPEC)
+ p->state = ORDER_SPEC;
+ break;
+
+ case ST_PUBLIC:
+ case ST_PRIVATE:
+ case ST_DERIVED_DECL:
+ case_decl:
+ if (p->state >= ORDER_EXEC)
+ goto order;
+ if (p->state < ORDER_SPEC)
+ p->state = ORDER_SPEC;
+ break;
+
+ case_executable:
+ case_exec_markers:
+ if (p->state < ORDER_EXEC)
+ p->state = ORDER_EXEC;
+ break;
+
+ default:
+ gfc_internal_error
+ ("Unexpected %s statement in verify_st_order() at %C",
+ gfc_ascii_statement (st));
+ }
+
+ /* All is well, record the statement in case we need it next time. */
+ p->where = *gfc_current_locus ();
+ p->last_statement = st;
+ return SUCCESS;
+
+order:
+ gfc_error ("%s statement at %C cannot follow %s statement at %L",
+ gfc_ascii_statement (st),
+ gfc_ascii_statement (p->last_statement), &p->where);
+
+ return FAILURE;
+}
+
+
+/* Handle an unexpected end of file. This is a show-stopper... */
+
+static void unexpected_eof (void) ATTRIBUTE_NORETURN;
+
+static void
+unexpected_eof (void)
+{
+ gfc_state_data *p;
+
+ gfc_error ("Unexpected end of file in '%s'", gfc_current_file->filename);
+
+ /* Memory cleanup. Move to "second to last". */
+ for (p = gfc_state_stack; p && p->previous && p->previous->previous;
+ p = p->previous);
+
+ gfc_current_ns->code = (p && p->previous) ? p->head : NULL;
+ gfc_done_2 ();
+
+ longjmp (eof, 1);
+}
+
+
+/* Parse a derived type. */
+
+static void
+parse_derived (void)
+{
+ int compiling_type, seen_private, seen_sequence, seen_component, error_flag;
+ gfc_statement st;
+ gfc_component *c;
+ gfc_state_data s;
+
+ error_flag = 0;
+
+ accept_statement (ST_DERIVED_DECL);
+ push_state (&s, COMP_DERIVED, gfc_new_block);
+
+ gfc_new_block->component_access = ACCESS_PUBLIC;
+ seen_private = 0;
+ seen_sequence = 0;
+ seen_component = 0;
+
+ compiling_type = 1;
+
+ while (compiling_type)
+ {
+ st = next_statement ();
+ switch (st)
+ {
+ case ST_NONE:
+ unexpected_eof ();
+
+ case ST_DATA_DECL:
+ accept_statement (st);
+ seen_component = 1;
+ break;
+
+ case ST_END_TYPE:
+ compiling_type = 0;
+
+ if (!seen_component)
+ {
+ gfc_error ("Derived type definition at %C has no components");
+ error_flag = 1;
+ }
+
+ accept_statement (ST_END_TYPE);
+ break;
+
+ case ST_PRIVATE:
+ if (gfc_find_state (COMP_MODULE) == FAILURE)
+ {
+ gfc_error
+ ("PRIVATE statement in TYPE at %C must be inside a MODULE");
+ error_flag = 1;
+ break;
+ }
+
+ if (seen_component)
+ {
+ gfc_error ("PRIVATE statement at %C must precede "
+ "structure components");
+ error_flag = 1;
+ break;
+ }
+
+ if (seen_private)
+ {
+ gfc_error ("Duplicate PRIVATE statement at %C");
+ error_flag = 1;
+ }
+
+ s.sym->component_access = ACCESS_PRIVATE;
+ accept_statement (ST_PRIVATE);
+ seen_private = 1;
+ break;
+
+ case ST_SEQUENCE:
+ if (seen_component)
+ {
+ gfc_error ("SEQUENCE statement at %C must precede "
+ "structure components");
+ error_flag = 1;
+ break;
+ }
+
+ if (gfc_current_block ()->attr.sequence)
+ gfc_warning ("SEQUENCE attribute at %C already specified in "
+ "TYPE statement");
+
+ if (seen_sequence)
+ {
+ gfc_error ("Duplicate SEQUENCE statement at %C");
+ error_flag = 1;
+ }
+
+ seen_sequence = 1;
+ gfc_add_sequence (&gfc_current_block ()->attr, NULL);
+ break;
+
+ default:
+ unexpected_statement (st);
+ break;
+ }
+ }
+
+ /* Sanity checks on the structure. If the structure has the
+ SEQUENCE attribute, then all component structures must also have
+ SEQUENCE. */
+ if (error_flag == 0 && gfc_current_block ()->attr.sequence)
+ for (c = gfc_current_block ()->components; c; c = c->next)
+ {
+ if (c->ts.type == BT_DERIVED && c->ts.derived->attr.sequence == 0)
+ {
+ gfc_error
+ ("Component %s of SEQUENCE type declared at %C does not "
+ "have the SEQUENCE attribute", c->ts.derived->name);
+ }
+ }
+
+ pop_state ();
+}
+
+
+
+/* Parse an interface. We must be able to deal with the possibility
+ of recursive interfaces. The parse_spec() subroutine is mutually
+ recursive with parse_interface(). */
+
+static gfc_statement parse_spec (gfc_statement);
+
+static void
+parse_interface (void)
+{
+ gfc_compile_state new_state, current_state;
+ gfc_symbol *prog_unit, *sym;
+ gfc_interface_info save;
+ gfc_state_data s1, s2;
+ gfc_statement st;
+
+ accept_statement (ST_INTERFACE);
+
+ current_interface.ns = gfc_current_ns;
+ save = current_interface;
+
+ sym = (current_interface.type == INTERFACE_GENERIC
+ || current_interface.type == INTERFACE_USER_OP) ? gfc_new_block : NULL;
+
+ push_state (&s1, COMP_INTERFACE, sym);
+ current_state = COMP_NONE;
+
+loop:
+ gfc_current_ns = gfc_get_namespace (current_interface.ns);
+
+ st = next_statement ();
+ switch (st)
+ {
+ case ST_NONE:
+ unexpected_eof ();
+
+ case ST_SUBROUTINE:
+ new_state = COMP_SUBROUTINE;
+ gfc_add_explicit_interface (gfc_new_block, IFSRC_IFBODY,
+ gfc_new_block->formal, NULL);
+ break;
+
+ case ST_FUNCTION:
+ new_state = COMP_FUNCTION;
+ gfc_add_explicit_interface (gfc_new_block, IFSRC_IFBODY,
+ gfc_new_block->formal, NULL);
+ break;
+
+ case ST_MODULE_PROC: /* The module procedure matcher makes
+ sure the context is correct. */
+ accept_statement (st);
+ gfc_free_namespace (gfc_current_ns);
+ goto loop;
+
+ case ST_END_INTERFACE:
+ gfc_free_namespace (gfc_current_ns);
+ gfc_current_ns = current_interface.ns;
+ goto done;
+
+ default:
+ gfc_error ("Unexpected %s statement in INTERFACE block at %C",
+ gfc_ascii_statement (st));
+ reject_statement ();
+ gfc_free_namespace (gfc_current_ns);
+ goto loop;
+ }
+
+
+ /* Make sure that a generic interface has only subroutines or
+ functions and that the generic name has the right attribute. */
+ if (current_interface.type == INTERFACE_GENERIC)
+ {
+ if (current_state == COMP_NONE)
+ {
+ if (new_state == COMP_FUNCTION)
+ gfc_add_function (&sym->attr, NULL);
+ if (new_state == COMP_SUBROUTINE)
+ gfc_add_subroutine (&sym->attr, NULL);
+
+ current_state = new_state;
+ }
+ else
+ {
+ if (new_state != current_state)
+ {
+ if (new_state == COMP_SUBROUTINE)
+ gfc_error
+ ("SUBROUTINE at %C does not belong in a generic function "
+ "interface");
+
+ if (new_state == COMP_FUNCTION)
+ gfc_error
+ ("FUNCTION at %C does not belong in a generic subroutine "
+ "interface");
+ }
+ }
+ }
+
+ push_state (&s2, new_state, gfc_new_block);
+ accept_statement (st);
+ prog_unit = gfc_new_block;
+ prog_unit->formal_ns = gfc_current_ns;
+
+decl:
+ /* Read data declaration statements. */
+ st = parse_spec (ST_NONE);
+
+ if (st != ST_END_SUBROUTINE && st != ST_END_FUNCTION)
+ {
+ gfc_error ("Unexpected %s statement at %C in INTERFACE body",
+ gfc_ascii_statement (st));
+ reject_statement ();
+ goto decl;
+ }
+
+ current_interface = save;
+ gfc_add_interface (prog_unit);
+
+ pop_state ();
+ goto loop;
+
+done:
+ pop_state ();
+}
+
+
+/* Parse a set of specification statements. Returns the statement
+ that doesn't fit. */
+
+static gfc_statement
+parse_spec (gfc_statement st)
+{
+ st_state ss;
+
+ verify_st_order (&ss, ST_NONE);
+ if (st == ST_NONE)
+ st = next_statement ();
+
+loop:
+ switch (st)
+ {
+ case ST_NONE:
+ unexpected_eof ();
+
+ case ST_FORMAT:
+ case ST_ENTRY:
+ case ST_DATA: /* Not allowed in interfaces */
+ if (gfc_current_state () == COMP_INTERFACE)
+ break;
+
+ /* Fall through */
+
+ case ST_USE:
+ case ST_IMPLICIT_NONE:
+ case ST_IMPLICIT:
+ case ST_PARAMETER:
+ case ST_PUBLIC:
+ case ST_PRIVATE:
+ case ST_DERIVED_DECL:
+ case_decl:
+ if (verify_st_order (&ss, st) == FAILURE)
+ {
+ reject_statement ();
+ st = next_statement ();
+ goto loop;
+ }
+
+ switch (st)
+ {
+ case ST_INTERFACE:
+ parse_interface ();
+ break;
+
+ case ST_DERIVED_DECL:
+ parse_derived ();
+ break;
+
+ case ST_PUBLIC:
+ case ST_PRIVATE:
+ if (gfc_current_state () != COMP_MODULE)
+ {
+ gfc_error ("%s statement must appear in a MODULE",
+ gfc_ascii_statement (st));
+ break;
+ }
+
+ if (gfc_current_ns->default_access != ACCESS_UNKNOWN)
+ {
+ gfc_error ("%s statement at %C follows another accessibility "
+ "specification", gfc_ascii_statement (st));
+ break;
+ }
+
+ gfc_current_ns->default_access = (st == ST_PUBLIC)
+ ? ACCESS_PUBLIC : ACCESS_PRIVATE;
+
+ break;
+
+ default:
+ break;
+ }
+
+ accept_statement (st);
+ st = next_statement ();
+ goto loop;
+
+ default:
+ break;
+ }
+
+ return st;
+}
+
+
+/* Parse a WHERE block, (not a simple WHERE statement). */
+
+static void
+parse_where_block (void)
+{
+ int seen_empty_else;
+ gfc_code *top, *d;
+ gfc_state_data s;
+ gfc_statement st;
+
+ accept_statement (ST_WHERE_BLOCK);
+ top = gfc_state_stack->tail;
+
+ push_state (&s, COMP_WHERE, gfc_new_block);
+
+ d = add_statement ();
+ d->expr = top->expr;
+ d->op = EXEC_WHERE;
+
+ top->expr = NULL;
+ top->block = d;
+
+ seen_empty_else = 0;
+
+ do
+ {
+ st = next_statement ();
+ switch (st)
+ {
+ case ST_NONE:
+ unexpected_eof ();
+
+ case ST_WHERE_BLOCK:
+ parse_where_block ();
+ /* Fall through */
+
+ case ST_ASSIGNMENT:
+ case ST_WHERE:
+ accept_statement (st);
+ break;
+
+ case ST_ELSEWHERE:
+ if (seen_empty_else)
+ {
+ gfc_error
+ ("ELSEWHERE statement at %C follows previous unmasked "
+ "ELSEWHERE");
+ break;
+ }
+
+ if (new_st.expr == NULL)
+ seen_empty_else = 1;
+
+ d = new_level (gfc_state_stack->head);
+ d->op = EXEC_WHERE;
+ d->expr = new_st.expr;
+
+ accept_statement (st);
+
+ break;
+
+ case ST_END_WHERE:
+ accept_statement (st);
+ break;
+
+ default:
+ gfc_error ("Unexpected %s statement in WHERE block at %C",
+ gfc_ascii_statement (st));
+ reject_statement ();
+ break;
+ }
+
+ }
+ while (st != ST_END_WHERE);
+
+ pop_state ();
+}
+
+
+/* Parse a FORALL block (not a simple FORALL statement). */
+
+static void
+parse_forall_block (void)
+{
+ gfc_code *top, *d;
+ gfc_state_data s;
+ gfc_statement st;
+
+ accept_statement (ST_FORALL_BLOCK);
+ top = gfc_state_stack->tail;
+
+ push_state (&s, COMP_FORALL, gfc_new_block);
+
+ d = add_statement ();
+ d->op = EXEC_FORALL;
+ top->block = d;
+
+ do
+ {
+ st = next_statement ();
+ switch (st)
+ {
+
+ case ST_ASSIGNMENT:
+ case ST_POINTER_ASSIGNMENT:
+ case ST_WHERE:
+ case ST_FORALL:
+ accept_statement (st);
+ break;
+
+ case ST_WHERE_BLOCK:
+ parse_where_block ();
+ break;
+
+ case ST_FORALL_BLOCK:
+ parse_forall_block ();
+ break;
+
+ case ST_END_FORALL:
+ accept_statement (st);
+ break;
+
+ case ST_NONE:
+ unexpected_eof ();
+
+ default:
+ gfc_error ("Unexpected %s statement in FORALL block at %C",
+ gfc_ascii_statement (st));
+
+ reject_statement ();
+ break;
+ }
+ }
+ while (st != ST_END_FORALL);
+
+ pop_state ();
+}
+
+
+static gfc_statement parse_executable (gfc_statement);
+
+/* parse the statements of an IF-THEN-ELSEIF-ELSE-ENDIF block. */
+
+static void
+parse_if_block (void)
+{
+ gfc_code *top, *d;
+ gfc_statement st;
+ locus else_locus;
+ gfc_state_data s;
+ int seen_else;
+
+ seen_else = 0;
+ accept_statement (ST_IF_BLOCK);
+
+ top = gfc_state_stack->tail;
+ push_state (&s, COMP_IF, gfc_new_block);
+
+ new_st.op = EXEC_IF;
+ d = add_statement ();
+
+ d->expr = top->expr;
+ top->expr = NULL;
+ top->block = d;
+
+ do
+ {
+ st = parse_executable (ST_NONE);
+
+ switch (st)
+ {
+ case ST_NONE:
+ unexpected_eof ();
+
+ case ST_ELSEIF:
+ if (seen_else)
+ {
+ gfc_error
+ ("ELSE IF statement at %C cannot follow ELSE statement at %L",
+ &else_locus);
+
+ reject_statement ();
+ break;
+ }
+
+ d = new_level (gfc_state_stack->head);
+ d->op = EXEC_IF;
+ d->expr = new_st.expr;
+
+ accept_statement (st);
+
+ break;
+
+ case ST_ELSE:
+ if (seen_else)
+ {
+ gfc_error ("Duplicate ELSE statements at %L and %C",
+ &else_locus);
+ reject_statement ();
+ break;
+ }
+
+ seen_else = 1;
+ else_locus = *gfc_current_locus ();
+
+ d = new_level (gfc_state_stack->head);
+ d->op = EXEC_IF;
+
+ accept_statement (st);
+
+ break;
+
+ case ST_ENDIF:
+ break;
+
+ default:
+ unexpected_statement (st);
+ break;
+ }
+ }
+ while (st != ST_ENDIF);
+
+ pop_state ();
+ accept_statement (st);
+}
+
+
+/* Parse a SELECT block. */
+
+static void
+parse_select_block (void)
+{
+ gfc_statement st;
+ gfc_code *cp;
+ gfc_state_data s;
+
+ accept_statement (ST_SELECT_CASE);
+
+ cp = gfc_state_stack->tail;
+ push_state (&s, COMP_SELECT, gfc_new_block);
+
+ /* Make sure that the next statement is a CASE or END SELECT. */
+ for (;;)
+ {
+ st = next_statement ();
+ if (st == ST_NONE)
+ unexpected_eof ();
+ if (st == ST_END_SELECT)
+ {
+ /* Empty SELECT CASE is OK. */
+ accept_statement (st);
+ pop_state ();
+ return;
+ }
+ if (st == ST_CASE)
+ break;
+
+ gfc_error
+ ("Expected a CASE or END SELECT statement following SELECT CASE "
+ "at %C");
+
+ reject_statement ();
+ }
+
+ /* At this point, we're got a nonempty select block. */
+ cp = new_level (cp);
+ *cp = new_st;
+
+ accept_statement (st);
+
+ do
+ {
+ st = parse_executable (ST_NONE);
+ switch (st)
+ {
+ case ST_NONE:
+ unexpected_eof ();
+
+ case ST_CASE:
+ cp = new_level (gfc_state_stack->head);
+ *cp = new_st;
+ gfc_clear_new_st ();
+
+ accept_statement (st);
+ /* Fall through */
+
+ case ST_END_SELECT:
+ break;
+
+ /* Can't have an executable statement because of
+ parse_executable(). */
+ default:
+ unexpected_statement (st);
+ break;
+ }
+ }
+ while (st != ST_END_SELECT);
+
+ pop_state ();
+ accept_statement (st);
+}
+
+
+/* Checks to see if the current statement label closes an enddo.
+ Returns 0 if not, 1 if closes an ENDDO correctly, or 2 (and issues
+ an error) if it incorrectly closes an ENDDO. */
+
+static int
+check_do_closure (void)
+{
+ gfc_state_data *p;
+
+ if (gfc_statement_label == NULL)
+ return 0;
+
+ for (p = gfc_state_stack; p; p = p->previous)
+ if (p->state == COMP_DO)
+ break;
+
+ if (p == NULL)
+ return 0; /* No loops to close */
+
+ if (p->ext.end_do_label == gfc_statement_label)
+ {
+
+ if (p == gfc_state_stack)
+ return 1;
+
+ gfc_error
+ ("End of nonblock DO statement at %C is within another block");
+ return 2;
+ }
+
+ /* At this point, the label doesn't terminate the innermost loop.
+ Make sure it doesn't terminate another one. */
+ for (; p; p = p->previous)
+ if (p->state == COMP_DO && p->ext.end_do_label == gfc_statement_label)
+ {
+ gfc_error ("End of nonblock DO statement at %C is interwoven "
+ "with another DO loop");
+ return 2;
+ }
+
+ return 0;
+}
+
+
+/* Parse a DO loop. Note that the ST_CYCLE and ST_EXIT statements are
+ handled inside of parse_executable(), because they aren't really
+ loop statements. */
+
+static void
+parse_do_block (void)
+{
+ gfc_statement st;
+ gfc_code *top;
+ gfc_state_data s;
+
+ s.ext.end_do_label = new_st.label;
+
+ accept_statement (ST_DO);
+
+ top = gfc_state_stack->tail;
+ push_state (&s, COMP_DO, gfc_new_block);
+
+ top->block = new_level (top);
+ top->block->op = EXEC_DO;
+
+loop:
+ st = parse_executable (ST_NONE);
+
+ switch (st)
+ {
+ case ST_NONE:
+ unexpected_eof ();
+
+ case ST_ENDDO:
+ if (s.ext.end_do_label != NULL
+ && s.ext.end_do_label != gfc_statement_label)
+ gfc_error_now
+ ("Statement label in ENDDO at %C doesn't match DO label");
+ /* Fall through */
+
+ case ST_IMPLIED_ENDDO:
+ break;
+
+ default:
+ unexpected_statement (st);
+ goto loop;
+ }
+
+ pop_state ();
+ accept_statement (st);
+}
+
+
+/* Accept a series of executable statements. We return the first
+ statement that doesn't fit to the caller. Any block statements are
+ passed on to the correct handler, which usually passes the buck
+ right back here. */
+
+static gfc_statement
+parse_executable (gfc_statement st)
+{
+ int close_flag;
+
+ if (st == ST_NONE)
+ st = next_statement ();
+
+ for (;; st = next_statement ())
+ {
+
+ close_flag = check_do_closure ();
+ if (close_flag)
+ switch (st)
+ {
+ case ST_GOTO:
+ case ST_END_PROGRAM:
+ case ST_RETURN:
+ case ST_EXIT:
+ case ST_END_FUNCTION:
+ case ST_CYCLE:
+ case ST_PAUSE:
+ case ST_STOP:
+ case ST_END_SUBROUTINE:
+
+ case ST_DO:
+ case ST_FORALL:
+ case ST_WHERE:
+ case ST_SELECT_CASE:
+ gfc_error
+ ("%s statement at %C cannot terminate a non-block DO loop",
+ gfc_ascii_statement (st));
+ break;
+
+ default:
+ break;
+ }
+
+ switch (st)
+ {
+ case ST_NONE:
+ unexpected_eof ();
+
+ case ST_FORMAT:
+ case ST_DATA:
+ case ST_ENTRY:
+ case_executable:
+ accept_statement (st);
+ if (close_flag == 1)
+ return ST_IMPLIED_ENDDO;
+ continue;
+
+ case ST_IF_BLOCK:
+ parse_if_block ();
+ continue;
+
+ case ST_SELECT_CASE:
+ parse_select_block ();
+ continue;
+
+ case ST_DO:
+ parse_do_block ();
+ if (check_do_closure () == 1)
+ return ST_IMPLIED_ENDDO;
+ continue;
+
+ case ST_WHERE_BLOCK:
+ parse_where_block ();
+ continue;
+
+ case ST_FORALL_BLOCK:
+ parse_forall_block ();
+ continue;
+
+ default:
+ break;
+ }
+
+ break;
+ }
+
+ return st;
+}
+
+
+/* Parse a series of contained program units. */
+
+static void parse_progunit (gfc_statement);
+
+
+/* Fix the symbols for sibling functions. These are incorrectly added to
+ the child namespace as the parser didn't know about this procedure. */
+
+static void
+gfc_fixup_sibling_symbols (gfc_symbol * sym, gfc_namespace * siblings)
+{
+ gfc_namespace *ns;
+ gfc_symtree *st;
+ gfc_symbol *old_sym;
+
+ for (ns = siblings; ns; ns = ns->sibling)
+ {
+ gfc_find_sym_tree (sym->name, ns, 0, &st);
+ if (!st)
+ continue;
+
+ old_sym = st->n.sym;
+ if (old_sym->attr.flavor == FL_PROCEDURE && old_sym->ns == ns
+ && ! old_sym->attr.contained)
+ {
+ /* Replace it with the symbol from the parent namespace. */
+ st->n.sym = sym;
+ sym->refs++;
+
+ /* Free the old (local) symbol. */
+ old_sym->refs--;
+ if (old_sym->refs == 0)
+ gfc_free_symbol (old_sym);
+ }
+
+ /* Do the same for any contined procedures. */
+ gfc_fixup_sibling_symbols (sym, ns->contained);
+ }
+}
+
+static void
+parse_contained (int module)
+{
+ gfc_namespace *ns, *parent_ns;
+ gfc_state_data s1, s2;
+ gfc_statement st;
+ gfc_symbol *sym;
+
+ push_state (&s1, COMP_CONTAINS, NULL);
+ parent_ns = gfc_current_ns;
+
+ do
+ {
+ gfc_current_ns = gfc_get_namespace (parent_ns);
+
+ gfc_current_ns->sibling = parent_ns->contained;
+ parent_ns->contained = gfc_current_ns;
+
+ st = next_statement ();
+
+ switch (st)
+ {
+ case ST_NONE:
+ unexpected_eof ();
+
+ case ST_FUNCTION:
+ case ST_SUBROUTINE:
+ accept_statement (st);
+
+ push_state (&s2,
+ (st == ST_FUNCTION) ? COMP_FUNCTION : COMP_SUBROUTINE,
+ gfc_new_block);
+
+ /* For internal procedures, create/update the symbol in the
+ * parent namespace */
+
+ if (!module)
+ {
+ if (gfc_get_symbol (gfc_new_block->name, parent_ns, &sym))
+ gfc_error
+ ("Contained procedure '%s' at %C is already ambiguous",
+ gfc_new_block->name);
+ else
+ {
+ if (gfc_add_procedure (&sym->attr, PROC_INTERNAL,
+ &gfc_new_block->declared_at) ==
+ SUCCESS)
+ {
+ if (st == ST_FUNCTION)
+ gfc_add_function (&sym->attr,
+ &gfc_new_block->declared_at);
+ else
+ gfc_add_subroutine (&sym->attr,
+ &gfc_new_block->declared_at);
+ }
+ }
+
+ gfc_commit_symbols ();
+ }
+ else
+ sym = gfc_new_block;
+
+ /* Mark this as a contained function, so it isn't replaced
+ by other module functions. */
+ sym->attr.contained = 1;
+
+ /* Fix up any sibling functions that refer to this one. */
+ gfc_fixup_sibling_symbols (sym, gfc_current_ns);
+
+ parse_progunit (ST_NONE);
+
+ gfc_current_ns->code = s2.head;
+ gfc_current_ns = parent_ns;
+
+ pop_state ();
+ break;
+
+ /* These statements are associated with the end of the host
+ unit. */
+ case ST_END_FUNCTION:
+ case ST_END_MODULE:
+ case ST_END_PROGRAM:
+ case ST_END_SUBROUTINE:
+ accept_statement (st);
+ break;
+
+ default:
+ gfc_error ("Unexpected %s statement in CONTAINS section at %C",
+ gfc_ascii_statement (st));
+ reject_statement ();
+ break;
+ }
+ }
+ while (st != ST_END_FUNCTION && st != ST_END_SUBROUTINE
+ && st != ST_END_MODULE && st != ST_END_PROGRAM);
+
+ /* The first namespace in the list is guaranteed to not have
+ anything (worthwhile) in it. */
+
+ gfc_current_ns = parent_ns;
+
+ ns = gfc_current_ns->contained;
+ gfc_current_ns->contained = ns->sibling;
+ gfc_free_namespace (ns);
+
+ pop_state ();
+}
+
+
+/* Parse a PROGRAM, SUBROUTINE or FUNCTION unit. */
+
+static void
+parse_progunit (gfc_statement st)
+{
+ gfc_state_data *p;
+ int n;
+
+ st = parse_spec (st);
+ switch (st)
+ {
+ case ST_NONE:
+ unexpected_eof ();
+
+ case ST_CONTAINS:
+ goto contains;
+
+ case_end:
+ accept_statement (st);
+ goto done;
+
+ default:
+ break;
+ }
+
+loop:
+ for (;;)
+ {
+ st = parse_executable (st);
+
+ switch (st)
+ {
+ case ST_NONE:
+ unexpected_eof ();
+
+ case ST_CONTAINS:
+ goto contains;
+
+ case_end:
+ accept_statement (st);
+ goto done;
+
+ default:
+ break;
+ }
+
+ unexpected_statement (st);
+ reject_statement ();
+ st = next_statement ();
+ }
+
+contains:
+ n = 0;
+
+ for (p = gfc_state_stack; p; p = p->previous)
+ if (p->state == COMP_CONTAINS)
+ n++;
+
+ if (gfc_find_state (COMP_MODULE) == SUCCESS)
+ n--;
+
+ if (n > 0)
+ {
+ gfc_error ("CONTAINS statement at %C is already in a contained "
+ "program unit");
+ st = next_statement ();
+ goto loop;
+ }
+
+ parse_contained (0);
+
+done:
+ gfc_current_ns->code = gfc_state_stack->head;
+}
+
+
+/* Parse a block data program unit. */
+
+static void
+parse_block_data (void)
+{
+ gfc_statement st;
+
+ st = parse_spec (ST_NONE);
+
+ while (st != ST_END_BLOCK_DATA)
+ {
+ gfc_error ("Unexpected %s statement in BLOCK DATA at %C",
+ gfc_ascii_statement (st));
+ reject_statement ();
+ st = next_statement ();
+ }
+}
+
+
+/* Parse a module subprogram. */
+
+static void
+parse_module (void)
+{
+ gfc_statement st;
+
+ st = parse_spec (ST_NONE);
+
+loop:
+ switch (st)
+ {
+ case ST_NONE:
+ unexpected_eof ();
+
+ case ST_CONTAINS:
+ parse_contained (1);
+ break;
+
+ case ST_END_MODULE:
+ accept_statement (st);
+ break;
+
+ default:
+ gfc_error ("Unexpected %s statement in MODULE at %C",
+ gfc_ascii_statement (st));
+
+ reject_statement ();
+ st = next_statement ();
+ goto loop;
+ }
+}
+
+
+/* Top level parser. */
+
+try
+gfc_parse_file (void)
+{
+ int seen_program, errors_before, errors;
+ gfc_state_data top, s;
+ gfc_statement st;
+ locus prog_locus;
+
+ top.state = COMP_NONE;
+ top.sym = NULL;
+ top.previous = NULL;
+ top.head = top.tail = NULL;
+
+ gfc_state_stack = &top;
+
+ gfc_clear_new_st ();
+
+ gfc_statement_label = NULL;
+
+ if (setjmp (eof))
+ return FAILURE; /* Come here on unexpected EOF */
+
+ seen_program = 0;
+
+loop:
+ gfc_init_2 ();
+ st = next_statement ();
+ switch (st)
+ {
+ case ST_NONE:
+ gfc_done_2 ();
+ goto done;
+
+ case ST_PROGRAM:
+ if (seen_program)
+ goto duplicate_main;
+ seen_program = 1;
+ prog_locus = *gfc_current_locus ();
+
+ push_state (&s, COMP_PROGRAM, gfc_new_block);
+ accept_statement (st);
+ parse_progunit (ST_NONE);
+ break;
+
+ case ST_SUBROUTINE:
+ push_state (&s, COMP_SUBROUTINE, gfc_new_block);
+ accept_statement (st);
+ parse_progunit (ST_NONE);
+ break;
+
+ case ST_FUNCTION:
+ push_state (&s, COMP_FUNCTION, gfc_new_block);
+ accept_statement (st);
+ parse_progunit (ST_NONE);
+ break;
+
+ case ST_BLOCK_DATA:
+ push_state (&s, COMP_BLOCK_DATA, gfc_new_block);
+ accept_statement (st);
+ parse_block_data ();
+ break;
+
+ case ST_MODULE:
+ push_state (&s, COMP_MODULE, gfc_new_block);
+ accept_statement (st);
+
+ gfc_get_errors (NULL, &errors_before);
+ parse_module ();
+ break;
+
+ /* Anything else starts a nameless main program block. */
+ default:
+ if (seen_program)
+ goto duplicate_main;
+ seen_program = 1;
+ prog_locus = *gfc_current_locus ();
+
+ push_state (&s, COMP_PROGRAM, gfc_new_block);
+ parse_progunit (st);
+ break;
+ }
+
+ gfc_current_ns->code = s.head;
+
+ gfc_resolve (gfc_current_ns);
+
+ /* Dump the parse tree if requested. */
+ if (gfc_option.verbose)
+ gfc_show_namespace (gfc_current_ns);
+
+ gfc_get_errors (NULL, &errors);
+ if (s.state == COMP_MODULE)
+ {
+ gfc_dump_module (s.sym->name, errors_before == errors);
+ if (errors == 0 && ! gfc_option.flag_no_backend)
+ gfc_generate_module_code (gfc_current_ns);
+ }
+ else
+ {
+ if (errors == 0 && ! gfc_option.flag_no_backend)
+ gfc_generate_code (gfc_current_ns);
+ }
+
+ pop_state ();
+ gfc_done_2 ();
+ goto loop;
+
+done:
+ return SUCCESS;
+
+duplicate_main:
+ /* If we see a duplicate main program, shut down. If the second
+ instance is an implied main program, ie data decls or executable
+ statements, we're in for lots of errors. */
+ gfc_error ("Two main PROGRAMs at %L and %C", &prog_locus);
+ reject_statement ();
+ gfc_done_2 ();
+ return SUCCESS;
+}
diff --git a/gcc/fortran/parse.h b/gcc/fortran/parse.h
new file mode 100644
index 00000000000..a6bf12a1392
--- /dev/null
+++ b/gcc/fortran/parse.h
@@ -0,0 +1,65 @@
+/* Parser header
+ Copyright (C) 2003 Free Software Foundaton, Inc.
+ Contributed by Steven Bosscher
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#ifndef GFC_PARSE_H
+#define GFC_PARSE_H
+
+#include "gfortran.h"
+
+/* Enum for what the compiler is currently doing. */
+typedef enum
+{
+ COMP_NONE, COMP_PROGRAM, COMP_MODULE, COMP_SUBROUTINE, COMP_FUNCTION,
+ COMP_BLOCK_DATA, COMP_INTERFACE, COMP_DERIVED, COMP_IF, COMP_DO,
+ COMP_SELECT, COMP_FORALL, COMP_WHERE, COMP_CONTAINS
+}
+gfc_compile_state;
+
+/* Stack element for the current compilation state. These structures
+ are allocated as automatic variables. */
+typedef struct gfc_state_data
+{
+ gfc_compile_state state;
+ gfc_symbol *sym; /* Block name associated with this level */
+ struct gfc_code *head, *tail;
+ struct gfc_state_data *previous;
+
+ /* Block-specific state data. */
+ union
+ {
+ gfc_st_label *end_do_label;
+ }
+ ext;
+}
+gfc_state_data;
+
+extern gfc_state_data *gfc_state_stack;
+
+#define gfc_current_block() (gfc_state_stack->sym)
+#define gfc_current_state() (gfc_state_stack->state)
+
+try gfc_find_state (gfc_compile_state);
+gfc_state_data *gfc_enclosing_unit (gfc_compile_state *);
+const char *gfc_ascii_statement (gfc_statement);
+const char *gfc_state_name (gfc_compile_state);
+
+#endif /* GFC_PARSE_H */
diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c
new file mode 100644
index 00000000000..03e975776ea
--- /dev/null
+++ b/gcc/fortran/primary.c
@@ -0,0 +1,2214 @@
+/* Primary expression subroutines
+ Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+This file is part of GNU G95.
+
+GNU G95 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 2, or (at your option)
+any later version.
+
+GNU G95 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 GNU G95; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+#include "config.h"
+#include "system.h"
+#include "flags.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include "gfortran.h"
+#include "arith.h"
+#include "match.h"
+#include "parse.h"
+
+/* Matches a kind-parameter expression, which is either a named
+ symbolic constant or a nonnegative integer constant. If
+ successful, sets the kind value to the correct integer. */
+
+static match
+match_kind_param (int *kind)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_symbol *sym;
+ const char *p;
+ match m;
+
+ m = gfc_match_small_literal_int (kind);
+ if (m != MATCH_NO)
+ return m;
+
+ m = gfc_match_name (name);
+ if (m != MATCH_YES)
+ return m;
+
+ if (gfc_find_symbol (name, NULL, 1, &sym))
+ return MATCH_ERROR;
+
+ if (sym == NULL)
+ return MATCH_NO;
+
+ if (sym->attr.flavor != FL_PARAMETER)
+ return MATCH_NO;
+
+ p = gfc_extract_int (sym->value, kind);
+ if (p != NULL)
+ return MATCH_NO;
+
+ if (*kind < 0)
+ return MATCH_NO;
+
+ return MATCH_YES;
+}
+
+
+/* Get a trailing kind-specification for non-character variables.
+ Returns:
+ the integer kind value or:
+ -1 if an error was generated
+ -2 if no kind was found */
+
+static int
+get_kind (void)
+{
+ int kind;
+ match m;
+
+ if (gfc_match_char ('_') != MATCH_YES)
+ return -2;
+
+ m = match_kind_param (&kind);
+ if (m == MATCH_NO)
+ gfc_error ("Missing kind-parameter at %C");
+
+ return (m == MATCH_YES) ? kind : -1;
+}
+
+
+/* Given a character and a radix, see if the character is a valid
+ digit in that radix. */
+
+static int
+check_digit (int c, int radix)
+{
+ int r;
+
+ switch (radix)
+ {
+ case 2:
+ r = ('0' <= c && c <= '1');
+ break;
+
+ case 8:
+ r = ('0' <= c && c <= '7');
+ break;
+
+ case 10:
+ r = ('0' <= c && c <= '9');
+ break;
+
+ case 16:
+ r = ('0' <= c && c <= '9') || ('a' <= c && c <= 'f');
+ break;
+
+ default:
+ gfc_internal_error ("check_digit(): bad radix");
+ }
+
+ return r;
+}
+
+
+/* Match the digit string part of an integer if signflag is not set,
+ the signed digit string part if signflag is set. If the buffer
+ is NULL, we just count characters for the resolution pass. Returns
+ the number of characters matched, -1 for no match. */
+
+static int
+match_digits (int signflag, int radix, char *buffer)
+{
+ locus old_loc;
+ int length, c;
+
+ length = 0;
+ c = gfc_next_char ();
+
+ if (signflag && (c == '+' || c == '-'))
+ {
+ if (buffer != NULL)
+ *buffer++ = c;
+ c = gfc_next_char ();
+ length++;
+ }
+
+ if (!check_digit (c, radix))
+ return -1;
+
+ length++;
+ if (buffer != NULL)
+ *buffer++ = c;
+
+ for (;;)
+ {
+ old_loc = *gfc_current_locus ();
+ c = gfc_next_char ();
+
+ if (!check_digit (c, radix))
+ break;
+
+ if (buffer != NULL)
+ *buffer++ = c;
+ length++;
+ }
+
+ gfc_set_locus (&old_loc);
+
+ return length;
+}
+
+
+/* Match an integer (digit string and optional kind).
+ A sign will be accepted if signflag is set. */
+
+static match
+match_integer_constant (gfc_expr ** result, int signflag)
+{
+ int length, kind;
+ locus old_loc;
+ char *buffer;
+ gfc_expr *e;
+
+ old_loc = *gfc_current_locus ();
+ gfc_gobble_whitespace ();
+
+ length = match_digits (signflag, 10, NULL);
+ gfc_set_locus (&old_loc);
+ if (length == -1)
+ return MATCH_NO;
+
+ buffer = alloca (length + 1);
+ memset (buffer, '\0', length + 1);
+
+ gfc_gobble_whitespace ();
+
+ match_digits (signflag, 10, buffer);
+
+ kind = get_kind ();
+ if (kind == -2)
+ kind = gfc_default_integer_kind ();
+ if (kind == -1)
+ return MATCH_ERROR;
+
+ if (gfc_validate_kind (BT_INTEGER, kind) == -1)
+ {
+ gfc_error ("Integer kind %d at %C not available", kind);
+ return MATCH_ERROR;
+ }
+
+ e = gfc_convert_integer (buffer, kind, 10, gfc_current_locus ());
+
+ if (gfc_range_check (e) != ARITH_OK)
+ {
+ gfc_error ("Integer too big for its kind at %C");
+
+ gfc_free_expr (e);
+ return MATCH_ERROR;
+ }
+
+ *result = e;
+ return MATCH_YES;
+}
+
+
+/* Match a binary, octal or hexadecimal constant that can be found in
+ a DATA statement. */
+
+static match
+match_boz_constant (gfc_expr ** result)
+{
+ int radix, delim, length;
+ locus old_loc;
+ char *buffer;
+ gfc_expr *e;
+ const char *rname;
+
+ old_loc = *gfc_current_locus ();
+ gfc_gobble_whitespace ();
+
+ switch (gfc_next_char ())
+ {
+ case 'b':
+ radix = 2;
+ rname = "binary";
+ break;
+ case 'o':
+ radix = 8;
+ rname = "octal";
+ break;
+ case 'x':
+ if (pedantic)
+ gfc_warning_now ("Hexadecimal constant at %C uses non-standard "
+ "syntax. Use \"Z\" instead.");
+ /* Fall through. */
+ case 'z':
+ radix = 16;
+ rname = "hexadecimal";
+ break;
+ default:
+ goto backup;
+ }
+
+ /* No whitespace allowed here. */
+
+ delim = gfc_next_char ();
+ if (delim != '\'' && delim != '\"')
+ goto backup;
+
+ old_loc = *gfc_current_locus ();
+
+ length = match_digits (0, radix, NULL);
+ if (length == -1)
+ {
+ gfc_error ("Empty set of digits in %s constants at %C", rname);
+ return MATCH_ERROR;
+ }
+
+ if (gfc_next_char () != delim)
+ {
+ gfc_error ("Illegal character in %s constant at %C.", rname);
+ return MATCH_ERROR;
+ }
+
+ gfc_set_locus (&old_loc);
+
+ buffer = alloca (length + 1);
+ memset (buffer, '\0', length + 1);
+
+ match_digits (0, radix, buffer);
+ gfc_next_char ();
+
+ e = gfc_convert_integer (buffer, gfc_default_integer_kind (), radix,
+ gfc_current_locus ());
+
+ if (gfc_range_check (e) != ARITH_OK)
+ {
+ gfc_error ("Integer too big for default integer kind at %C");
+
+ gfc_free_expr (e);
+ return MATCH_ERROR;
+ }
+
+ *result = e;
+ return MATCH_YES;
+
+backup:
+ gfc_set_locus (&old_loc);
+ return MATCH_NO;
+}
+
+
+/* Match a real constant of some sort. */
+
+static match
+match_real_constant (gfc_expr ** result, int signflag)
+{
+ int kind, c, count, seen_dp, seen_digits, exp_char;
+ locus old_loc, temp_loc;
+ char *p, *buffer;
+ gfc_expr *e;
+
+ old_loc = *gfc_current_locus ();
+ gfc_gobble_whitespace ();
+
+ e = NULL;
+
+ count = 0;
+ seen_dp = 0;
+ seen_digits = 0;
+ exp_char = ' ';
+
+ c = gfc_next_char ();
+ if (signflag && (c == '+' || c == '-'))
+ {
+ c = gfc_next_char ();
+ count++;
+ }
+
+ /* Scan significand. */
+ for (;; c = gfc_next_char (), count++)
+ {
+ if (c == '.')
+ {
+ if (seen_dp)
+ goto done;
+
+ /* Check to see if "." goes with a following operator like ".eq.". */
+ temp_loc = *gfc_current_locus ();
+ c = gfc_next_char ();
+
+ if (c == 'e' || c == 'd' || c == 'q')
+ {
+ c = gfc_next_char ();
+ if (c == '.')
+ goto done; /* Operator named .e. or .d. */
+ }
+
+ if (ISALPHA (c))
+ goto done; /* Distinguish 1.e9 from 1.eq.2 */
+
+ gfc_set_locus (&temp_loc);
+ seen_dp = 1;
+ continue;
+ }
+
+ if (ISDIGIT (c))
+ {
+ seen_digits = 1;
+ continue;
+ }
+
+ break;
+ }
+
+ if (!seen_digits || (c != 'e' && c != 'd' && c != 'q'))
+ goto done;
+ exp_char = c;
+
+ /* Scan exponent. */
+ c = gfc_next_char ();
+ count++;
+
+ if (c == '+' || c == '-')
+ { /* optional sign */
+ c = gfc_next_char ();
+ count++;
+ }
+
+ if (!ISDIGIT (c))
+ {
+ /* TODO: seen_digits is always true at this point */
+ if (!seen_digits)
+ {
+ gfc_set_locus (&old_loc);
+ return MATCH_NO; /* ".e" can be something else */
+ }
+
+ gfc_error ("Missing exponent in real number at %C");
+ return MATCH_ERROR;
+ }
+
+ while (ISDIGIT (c))
+ {
+ c = gfc_next_char ();
+ count++;
+ }
+
+done:
+ /* See what we've got! */
+ if (!seen_digits || (!seen_dp && exp_char == ' '))
+ {
+ gfc_set_locus (&old_loc);
+ return MATCH_NO;
+ }
+
+ /* Convert the number. */
+ gfc_set_locus (&old_loc);
+ gfc_gobble_whitespace ();
+
+ buffer = alloca (count + 1);
+ memset (buffer, '\0', count + 1);
+
+ /* Hack for mpf_init_set_str(). */
+ p = buffer;
+ while (count > 0)
+ {
+ *p = gfc_next_char ();
+ if (*p == 'd' || *p == 'q')
+ *p = 'e';
+ p++;
+ count--;
+ }
+
+ kind = get_kind ();
+ if (kind == -1)
+ goto cleanup;
+
+ switch (exp_char)
+ {
+ case 'd':
+ if (kind != -2)
+ {
+ gfc_error
+ ("Real number at %C has a 'd' exponent and an explicit kind");
+ goto cleanup;
+ }
+ kind = gfc_default_double_kind ();
+ break;
+
+ case 'q':
+ if (kind != -2)
+ {
+ gfc_error
+ ("Real number at %C has a 'q' exponent and an explicit kind");
+ goto cleanup;
+ }
+ kind = gfc_option.q_kind;
+ break;
+
+ default:
+ if (kind == -2)
+ kind = gfc_default_real_kind ();
+
+ if (gfc_validate_kind (BT_REAL, kind) == -1)
+ {
+ gfc_error ("Invalid real kind %d at %C", kind);
+ goto cleanup;
+ }
+ }
+
+ e = gfc_convert_real (buffer, kind, gfc_current_locus ());
+
+ switch (gfc_range_check (e))
+ {
+ case ARITH_OK:
+ break;
+ case ARITH_OVERFLOW:
+ gfc_error ("Real constant overflows its kind at %C");
+ goto cleanup;
+
+ case ARITH_UNDERFLOW:
+ gfc_error ("Real constant underflows its kind at %C");
+ goto cleanup;
+
+ default:
+ gfc_internal_error ("gfc_range_check() returned bad value");
+ }
+
+ *result = e;
+ return MATCH_YES;
+
+cleanup:
+ gfc_free_expr (e);
+ return MATCH_ERROR;
+}
+
+
+/* Match a substring reference. */
+
+static match
+match_substring (gfc_charlen * cl, int init, gfc_ref ** result)
+{
+ gfc_expr *start, *end;
+ locus old_loc;
+ gfc_ref *ref;
+ match m;
+
+ start = NULL;
+ end = NULL;
+
+ old_loc = *gfc_current_locus ();
+
+ m = gfc_match_char ('(');
+ if (m != MATCH_YES)
+ return MATCH_NO;
+
+ if (gfc_match_char (':') != MATCH_YES)
+ {
+ if (init)
+ m = gfc_match_init_expr (&start);
+ else
+ m = gfc_match_expr (&start);
+
+ if (m != MATCH_YES)
+ {
+ m = MATCH_NO;
+ goto cleanup;
+ }
+
+ m = gfc_match_char (':');
+ if (m != MATCH_YES)
+ goto cleanup;
+ }
+
+ if (gfc_match_char (')') != MATCH_YES)
+ {
+ if (init)
+ m = gfc_match_init_expr (&end);
+ else
+ m = gfc_match_expr (&end);
+
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ m = gfc_match_char (')');
+ if (m == MATCH_NO)
+ goto syntax;
+ }
+
+ /* Optimize away the (:) reference. */
+ if (start == NULL && end == NULL)
+ ref = NULL;
+ else
+ {
+ ref = gfc_get_ref ();
+
+ ref->type = REF_SUBSTRING;
+ if (start == NULL)
+ start = gfc_int_expr (1);
+ ref->u.ss.start = start;
+ if (end == NULL && cl)
+ end = gfc_copy_expr (cl->length);
+ ref->u.ss.end = end;
+ ref->u.ss.length = cl;
+ }
+
+ *result = ref;
+ return MATCH_YES;
+
+syntax:
+ gfc_error ("Syntax error in SUBSTRING specification at %C");
+ m = MATCH_ERROR;
+
+cleanup:
+ gfc_free_expr (start);
+ gfc_free_expr (end);
+
+ gfc_set_locus (&old_loc);
+ return m;
+}
+
+
+/* Reads the next character of a string constant, taking care to
+ return doubled delimiters on the input as a single instance of
+ the delimiter.
+
+ Special return values are:
+ -1 End of the string, as determined by the delimiter
+ -2 Unterminated string detected
+
+ Backslash codes are also expanded at this time. */
+
+static int
+next_string_char (char delimiter)
+{
+ locus old_locus;
+ int c;
+
+ c = gfc_next_char_literal (1);
+
+ if (c == '\n')
+ return -2;
+
+ if (c == '\\')
+ {
+ old_locus = *gfc_current_locus ();
+
+ switch (gfc_next_char_literal (1))
+ {
+ case 'a':
+ c = '\a';
+ break;
+ case 'b':
+ c = '\b';
+ break;
+ case 't':
+ c = '\t';
+ break;
+ case 'f':
+ c = '\f';
+ break;
+ case 'n':
+ c = '\n';
+ break;
+ case 'r':
+ c = '\r';
+ break;
+ case 'v':
+ c = '\v';
+ break;
+ case '\\':
+ c = '\\';
+ break;
+
+ default:
+ /* Unknown backslash codes are simply not expanded */
+ gfc_set_locus (&old_locus);
+ break;
+ }
+ }
+
+ if (c != delimiter)
+ return c;
+
+ old_locus = *gfc_current_locus ();
+ c = gfc_next_char_literal (1);
+
+ if (c == delimiter)
+ return c;
+ gfc_set_locus (&old_locus);
+
+ return -1;
+}
+
+
+/* Special case of gfc_match_name() that matches a parameter kind name
+ before a string constant. This takes case of the weird but legal
+ case of: weird case of:
+
+ kind_____'string'
+
+ where kind____ is a parameter. gfc_match_name() will happily slurp
+ up all the underscores, which leads to problems. If we return
+ MATCH_YES, the parse pointer points to the final underscore, which
+ is not part of the name. We never return MATCH_ERROR-- errors in
+ the name will be detected later. */
+
+static match
+match_charkind_name (char *name)
+{
+ locus old_loc;
+ char c, peek;
+ int len;
+
+ gfc_gobble_whitespace ();
+ c = gfc_next_char ();
+ if (!ISALPHA (c))
+ return MATCH_NO;
+
+ *name++ = c;
+ len = 1;
+
+ for (;;)
+ {
+ old_loc = *gfc_current_locus ();
+ c = gfc_next_char ();
+
+ if (c == '_')
+ {
+ peek = gfc_peek_char ();
+
+ if (peek == '\'' || peek == '\"')
+ {
+ gfc_set_locus (&old_loc);
+ *name = '\0';
+ return MATCH_YES;
+ }
+ }
+
+ if (!ISALNUM (c)
+ && c != '_'
+ && (gfc_option.flag_dollar_ok && c != '$'))
+ break;
+
+ *name++ = c;
+ if (++len > GFC_MAX_SYMBOL_LEN)
+ break;
+ }
+
+ return MATCH_NO;
+}
+
+
+/* See if the current input matches a character constant. Lots of
+ contortions have to be done to match the kind parameter which comes
+ before the actual string. The main consideration is that we don't
+ want to error out too quickly. For example, we don't actually do
+ any validation of the kinds until we have actually seen a legal
+ delimiter. Using match_kind_param() generates errors too quickly. */
+
+static match
+match_string_constant (gfc_expr ** result)
+{
+ char *p, name[GFC_MAX_SYMBOL_LEN + 1];
+ int i, c, kind, length, delimiter;
+ locus old_locus, start_locus;
+ gfc_symbol *sym;
+ gfc_expr *e;
+ const char *q;
+ match m;
+
+ old_locus = *gfc_current_locus ();
+
+ gfc_gobble_whitespace ();
+
+ start_locus = *gfc_current_locus ();
+
+ c = gfc_next_char ();
+ if (c == '\'' || c == '"')
+ {
+ kind = gfc_default_character_kind ();
+ goto got_delim;
+ }
+
+ if (ISDIGIT (c))
+ {
+ kind = 0;
+
+ while (ISDIGIT (c))
+ {
+ kind = kind * 10 + c - '0';
+ if (kind > 9999999)
+ goto no_match;
+ c = gfc_next_char ();
+ }
+
+ }
+ else
+ {
+ gfc_set_locus (&old_locus);
+
+ m = match_charkind_name (name);
+ if (m != MATCH_YES)
+ goto no_match;
+
+ if (gfc_find_symbol (name, NULL, 1, &sym)
+ || sym == NULL
+ || sym->attr.flavor != FL_PARAMETER)
+ goto no_match;
+
+ kind = -1;
+ c = gfc_next_char ();
+ }
+
+ if (c == ' ')
+ {
+ gfc_gobble_whitespace ();
+ c = gfc_next_char ();
+ }
+
+ if (c != '_')
+ goto no_match;
+
+ gfc_gobble_whitespace ();
+ start_locus = *gfc_current_locus ();
+
+ c = gfc_next_char ();
+ if (c != '\'' && c != '"')
+ goto no_match;
+
+ if (kind == -1)
+ {
+ q = gfc_extract_int (sym->value, &kind);
+ if (q != NULL)
+ {
+ gfc_error (q);
+ return MATCH_ERROR;
+ }
+ }
+
+ if (gfc_validate_kind (BT_CHARACTER, kind) == -1)
+ {
+ gfc_error ("Invalid kind %d for CHARACTER constant at %C", kind);
+ return MATCH_ERROR;
+ }
+
+got_delim:
+ /* Scan the string into a block of memory by first figuring out how
+ long it is, allocating the structure, then re-reading it. This
+ isn't particularly efficient, but string constants aren't that
+ common in most code. TODO: Use obstacks? */
+
+ delimiter = c;
+ length = 0;
+
+ for (;;)
+ {
+ c = next_string_char (delimiter);
+ if (c == -1)
+ break;
+ if (c == -2)
+ {
+ gfc_set_locus (&start_locus);
+ gfc_error ("Unterminated character constant beginning at %C");
+ return MATCH_ERROR;
+ }
+
+ length++;
+ }
+
+ e = gfc_get_expr ();
+
+ e->expr_type = EXPR_CONSTANT;
+ e->ref = NULL;
+ e->ts.type = BT_CHARACTER;
+ e->ts.kind = kind;
+ e->where = start_locus;
+
+ e->value.character.string = p = gfc_getmem (length + 1);
+ e->value.character.length = length;
+
+ gfc_set_locus (&start_locus);
+ gfc_next_char (); /* Skip delimiter */
+
+ for (i = 0; i < length; i++)
+ *p++ = next_string_char (delimiter);
+
+ *p = '\0'; /* TODO: C-style string is for development/debug purposes. */
+
+ if (next_string_char (delimiter) != -1)
+ gfc_internal_error ("match_string_constant(): Delimiter not found");
+
+ if (match_substring (NULL, 0, &e->ref) != MATCH_NO)
+ e->expr_type = EXPR_SUBSTRING;
+
+ *result = e;
+
+ return MATCH_YES;
+
+no_match:
+ gfc_set_locus (&old_locus);
+ return MATCH_NO;
+}
+
+
+/* Match a .true. or .false. */
+
+static match
+match_logical_constant (gfc_expr ** result)
+{
+ static mstring logical_ops[] = {
+ minit (".false.", 0),
+ minit (".true.", 1),
+ minit (NULL, -1)
+ };
+
+ gfc_expr *e;
+ int i, kind;
+
+ i = gfc_match_strings (logical_ops);
+ if (i == -1)
+ return MATCH_NO;
+
+ kind = get_kind ();
+ if (kind == -1)
+ return MATCH_ERROR;
+ if (kind == -2)
+ kind = gfc_default_logical_kind ();
+
+ if (gfc_validate_kind (BT_LOGICAL, kind) == -1)
+ gfc_error ("Bad kind for logical constant at %C");
+
+ e = gfc_get_expr ();
+
+ e->expr_type = EXPR_CONSTANT;
+ e->value.logical = i;
+ e->ts.type = BT_LOGICAL;
+ e->ts.kind = kind;
+ e->where = *gfc_current_locus ();
+
+ *result = e;
+ return MATCH_YES;
+}
+
+
+/* Match a real or imaginary part of a complex constant that is a
+ symbolic constant. */
+
+static match
+match_sym_complex_part (gfc_expr ** result)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_symbol *sym;
+ gfc_expr *e;
+ match m;
+
+ m = gfc_match_name (name);
+ if (m != MATCH_YES)
+ return m;
+
+ if (gfc_find_symbol (name, NULL, 1, &sym) || sym == NULL)
+ return MATCH_NO;
+
+ if (sym->attr.flavor != FL_PARAMETER)
+ {
+ gfc_error ("Expected PARAMETER symbol in complex constant at %C");
+ return MATCH_ERROR;
+ }
+
+ if (!gfc_numeric_ts (&sym->value->ts))
+ {
+ gfc_error ("Numeric PARAMETER required in complex constant at %C");
+ return MATCH_ERROR;
+ }
+
+ if (sym->value->rank != 0)
+ {
+ gfc_error ("Scalar PARAMETER required in complex constant at %C");
+ return MATCH_ERROR;
+ }
+
+ switch (sym->value->ts.type)
+ {
+ case BT_REAL:
+ e = gfc_copy_expr (sym->value);
+ break;
+
+ case BT_COMPLEX:
+ e = gfc_complex2real (sym->value, sym->value->ts.kind);
+ if (e == NULL)
+ goto error;
+ break;
+
+ case BT_INTEGER:
+ e = gfc_int2real (sym->value, gfc_default_real_kind ());
+ if (e == NULL)
+ goto error;
+ break;
+
+ default:
+ gfc_internal_error ("gfc_match_sym_complex_part(): Bad type");
+ }
+
+ *result = e; /* e is a scalar, real, constant expression */
+ return MATCH_YES;
+
+error:
+ gfc_error ("Error converting PARAMETER constant in complex constant at %C");
+ return MATCH_ERROR;
+}
+
+
+/* Match the real and imaginary parts of a complex number. This
+ subroutine is essentially match_real_constant() modified in a
+ couple of ways: A sign is always allowed and numbers that would
+ look like an integer to match_real_constant() are automatically
+ created as floating point numbers. The messiness involved with
+ making sure a decimal point belongs to the number and not a
+ trailing operator is not necessary here either (Hooray!). */
+
+static match
+match_const_complex_part (gfc_expr ** result)
+{
+ int kind, seen_digits, seen_dp, count;
+ char *p, c, exp_char, *buffer;
+ locus old_loc;
+
+ old_loc = *gfc_current_locus ();
+ gfc_gobble_whitespace ();
+
+ seen_dp = 0;
+ seen_digits = 0;
+ count = 0;
+ exp_char = ' ';
+
+ c = gfc_next_char ();
+ if (c == '-' || c == '+')
+ {
+ c = gfc_next_char ();
+ count++;
+ }
+
+ for (;; c = gfc_next_char (), count++)
+ {
+ if (c == '.')
+ {
+ if (seen_dp)
+ goto no_match;
+ seen_dp = 1;
+ continue;
+ }
+
+ if (ISDIGIT (c))
+ {
+ seen_digits = 1;
+ continue;
+ }
+
+ break;
+ }
+
+ if (!seen_digits || (c != 'd' && c != 'e'))
+ goto done;
+ exp_char = c;
+
+ /* Scan exponent. */
+ c = gfc_next_char ();
+ count++;
+
+ if (c == '+' || c == '-')
+ { /* optional sign */
+ c = gfc_next_char ();
+ count++;
+ }
+
+ if (!ISDIGIT (c))
+ {
+ gfc_error ("Missing exponent in real number at %C");
+ return MATCH_ERROR;
+ }
+
+ while (ISDIGIT (c))
+ {
+ c = gfc_next_char ();
+ count++;
+ }
+
+done:
+ if (!seen_digits)
+ goto no_match;
+
+ /* Convert the number. */
+ gfc_set_locus (&old_loc);
+ gfc_gobble_whitespace ();
+
+ buffer = alloca (count + 1);
+ memset (buffer, '\0', count + 1);
+
+ /* Hack for mpf_init_set_str(). */
+ p = buffer;
+ while (count > 0)
+ {
+ c = gfc_next_char ();
+ if (c == 'd')
+ c = 'e';
+ *p++ = c;
+ count--;
+ }
+
+ *p = '\0';
+
+ kind = get_kind ();
+ if (kind == -1)
+ return MATCH_ERROR;
+
+ /* If the number looked like an integer, forget about a kind we may
+ have seen, otherwise validate the kind against real kinds. */
+ if (seen_dp == 0 && exp_char == ' ')
+ {
+ if (kind == -2)
+ kind = gfc_default_integer_kind ();
+
+ }
+ else
+ {
+ if (exp_char == 'd')
+ {
+ if (kind != -2)
+ {
+ gfc_error
+ ("Real number at %C has a 'd' exponent and an explicit kind");
+ return MATCH_ERROR;
+ }
+ kind = gfc_default_double_kind ();
+
+ }
+ else
+ {
+ if (kind == -2)
+ kind = gfc_default_real_kind ();
+ }
+
+ if (gfc_validate_kind (BT_REAL, kind) == -1)
+ {
+ gfc_error ("Invalid real kind %d at %C", kind);
+ return MATCH_ERROR;
+ }
+ }
+
+ *result = gfc_convert_real (buffer, kind, gfc_current_locus ());
+ return MATCH_YES;
+
+no_match:
+ gfc_set_locus (&old_loc);
+ return MATCH_NO;
+}
+
+
+/* Match a real or imaginary part of a complex number. */
+
+static match
+match_complex_part (gfc_expr ** result)
+{
+ match m;
+
+ m = match_sym_complex_part (result);
+ if (m != MATCH_NO)
+ return m;
+
+ return match_const_complex_part (result);
+}
+
+
+/* Try to match a complex constant. */
+
+static match
+match_complex_constant (gfc_expr ** result)
+{
+ gfc_expr *e, *real, *imag;
+ gfc_error_buf old_error;
+ gfc_typespec target;
+ locus old_loc;
+ int kind;
+ match m;
+
+ old_loc = *gfc_current_locus ();
+ real = imag = e = NULL;
+
+ m = gfc_match_char ('(');
+ if (m != MATCH_YES)
+ return m;
+
+ gfc_push_error (&old_error);
+
+ m = match_complex_part (&real);
+ if (m == MATCH_NO)
+ goto cleanup;
+
+ if (gfc_match_char (',') == MATCH_NO)
+ {
+ gfc_pop_error (&old_error);
+ m = MATCH_NO;
+ goto cleanup;
+ }
+
+ /* If m is error, then something was wrong with the real part and we
+ assume we have a complex constant because we've seen the ','. An
+ ambiguous case here is the start of an iterator list of some
+ sort. These sort of lists are matched prior to coming here. */
+
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ gfc_pop_error (&old_error);
+
+ m = match_complex_part (&imag);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ m = gfc_match_char (')');
+ if (m == MATCH_NO)
+ goto syntax;
+
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ /* Decide on the kind of this complex number. */
+ kind = gfc_kind_max (real, imag);
+ target.type = BT_REAL;
+ target.kind = kind;
+
+ if (kind != real->ts.kind)
+ gfc_convert_type (real, &target, 2);
+ if (kind != imag->ts.kind)
+ gfc_convert_type (imag, &target, 2);
+
+ e = gfc_convert_complex (real, imag, kind);
+ e->where = *gfc_current_locus ();
+
+ gfc_free_expr (real);
+ gfc_free_expr (imag);
+
+ *result = e;
+ return MATCH_YES;
+
+syntax:
+ gfc_error ("Syntax error in COMPLEX constant at %C");
+ m = MATCH_ERROR;
+
+cleanup:
+ gfc_free_expr (e);
+ gfc_free_expr (real);
+ gfc_free_expr (imag);
+ gfc_set_locus (&old_loc);
+
+ return m;
+}
+
+
+/* Match constants in any of several forms. Returns nonzero for a
+ match, zero for no match. */
+
+match
+gfc_match_literal_constant (gfc_expr ** result, int signflag)
+{
+ match m;
+
+ m = match_complex_constant (result);
+ if (m != MATCH_NO)
+ return m;
+
+ m = match_string_constant (result);
+ if (m != MATCH_NO)
+ return m;
+
+ m = match_boz_constant (result);
+ if (m != MATCH_NO)
+ return m;
+
+ m = match_real_constant (result, signflag);
+ if (m != MATCH_NO)
+ return m;
+
+ m = match_integer_constant (result, signflag);
+ if (m != MATCH_NO)
+ return m;
+
+ m = match_logical_constant (result);
+ if (m != MATCH_NO)
+ return m;
+
+ return MATCH_NO;
+}
+
+
+/* Match a single actual argument value. An actual argument is
+ usually an expression, but can also be a procedure name. If the
+ argument is a single name, it is not always possible to tell
+ whether the name is a dummy procedure or not. We treat these cases
+ by creating an argument that looks like a dummy procedure and
+ fixing things later during resolution. */
+
+static match
+match_actual_arg (gfc_expr ** result)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_symtree *symtree;
+ locus where, w;
+ gfc_expr *e;
+ int c;
+
+ where = *gfc_current_locus ();
+
+ switch (gfc_match_name (name))
+ {
+ case MATCH_ERROR:
+ return MATCH_ERROR;
+
+ case MATCH_NO:
+ break;
+
+ case MATCH_YES:
+ w = *gfc_current_locus ();
+ gfc_gobble_whitespace ();
+ c = gfc_next_char ();
+ gfc_set_locus (&w);
+
+ if (c != ',' && c != ')')
+ break;
+
+ if (gfc_find_sym_tree (name, NULL, 1, &symtree))
+ break;
+ /* Handle error elsewhere. */
+
+ /* Eliminate a couple of common cases where we know we don't
+ have a function argument. */
+ if (symtree == NULL)
+ {
+ gfc_get_sym_tree (name, NULL, &symtree);
+ gfc_set_sym_referenced (symtree->n.sym);
+ }
+ else
+ {
+ gfc_symbol *sym;
+
+ sym = symtree->n.sym;
+ gfc_set_sym_referenced (sym);
+ if (sym->attr.flavor != FL_PROCEDURE
+ && sym->attr.flavor != FL_UNKNOWN)
+ break;
+
+ /* If the symbol is a function with itself as the result and
+ is being defined, then we have a variable. */
+ if (sym->result == sym
+ && (gfc_current_ns->proc_name == sym
+ || (gfc_current_ns->parent != NULL
+ && gfc_current_ns->parent->proc_name == sym)))
+ break;
+ }
+
+ e = gfc_get_expr (); /* Leave it unknown for now */
+ e->symtree = symtree;
+ e->expr_type = EXPR_VARIABLE;
+ e->ts.type = BT_PROCEDURE;
+ e->where = where;
+
+ *result = e;
+ return MATCH_YES;
+ }
+
+ gfc_set_locus (&where);
+ return gfc_match_expr (result);
+}
+
+
+/* Match a keyword argument. */
+
+static match
+match_keyword_arg (gfc_actual_arglist * actual, gfc_actual_arglist * base)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_actual_arglist *a;
+ locus name_locus;
+ match m;
+
+ name_locus = *gfc_current_locus ();
+ m = gfc_match_name (name);
+
+ if (m != MATCH_YES)
+ goto cleanup;
+ if (gfc_match_char ('=') != MATCH_YES)
+ {
+ m = MATCH_NO;
+ goto cleanup;
+ }
+
+ m = match_actual_arg (&actual->expr);
+ if (m != MATCH_YES)
+ goto cleanup;
+
+ /* Make sure this name has not appeared yet. */
+
+ if (name[0] != '\0')
+ {
+ for (a = base; a; a = a->next)
+ if (strcmp (a->name, name) == 0)
+ {
+ gfc_error
+ ("Keyword '%s' at %C has already appeared in the current "
+ "argument list", name);
+ return MATCH_ERROR;
+ }
+ }
+
+ strcpy (actual->name, name);
+ return MATCH_YES;
+
+cleanup:
+ gfc_set_locus (&name_locus);
+ return m;
+}
+
+
+/* Matches an actual argument list of a function or subroutine, from
+ the opening parenthesis to the closing parenthesis. The argument
+ list is assumed to allow keyword arguments because we don't know if
+ the symbol associated with the procedure has an implicit interface
+ or not. We make sure keywords are unique. */
+
+match
+gfc_match_actual_arglist (int sub_flag, gfc_actual_arglist ** argp)
+{
+ gfc_actual_arglist *head, *tail;
+ int seen_keyword;
+ gfc_st_label *label;
+ locus old_loc;
+ match m;
+
+ *argp = tail = NULL;
+ old_loc = *gfc_current_locus ();
+
+ seen_keyword = 0;
+
+ if (gfc_match_char ('(') == MATCH_NO)
+ return (sub_flag) ? MATCH_YES : MATCH_NO;
+
+ if (gfc_match_char (')') == MATCH_YES)
+ return MATCH_YES;
+ head = NULL;
+
+ for (;;)
+ {
+ if (head == NULL)
+ head = tail = gfc_get_actual_arglist ();
+ else
+ {
+ tail->next = gfc_get_actual_arglist ();
+ tail = tail->next;
+ }
+
+ if (sub_flag && gfc_match_char ('*') == MATCH_YES)
+ {
+ m = gfc_match_st_label (&label, 0);
+ if (m == MATCH_NO)
+ gfc_error ("Expected alternate return label at %C");
+ if (m != MATCH_YES)
+ goto cleanup;
+
+ tail->label = label;
+ goto next;
+ }
+
+ /* After the first keyword argument is seen, the following
+ arguments must also have keywords. */
+ if (seen_keyword)
+ {
+ m = match_keyword_arg (tail, head);
+
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ {
+ gfc_error
+ ("Missing keyword name in actual argument list at %C");
+ goto cleanup;
+ }
+
+ }
+ else
+ {
+ /* See if we have the first keyword argument. */
+ m = match_keyword_arg (tail, head);
+ if (m == MATCH_YES)
+ seen_keyword = 1;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ if (m == MATCH_NO)
+ {
+ /* Try for a non-keyword argument. */
+ m = match_actual_arg (&tail->expr);
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO)
+ goto syntax;
+ }
+ }
+
+ next:
+ if (gfc_match_char (')') == MATCH_YES)
+ break;
+ if (gfc_match_char (',') != MATCH_YES)
+ goto syntax;
+ }
+
+ *argp = head;
+ return MATCH_YES;
+
+syntax:
+ gfc_error ("Syntax error in argument list at %C");
+
+cleanup:
+ gfc_free_actual_arglist (head);
+ gfc_set_locus (&old_loc);
+
+ return MATCH_ERROR;
+}
+
+
+/* Used by match_varspec() to extend the reference list by one
+ element. */
+
+static gfc_ref *
+extend_ref (gfc_expr * primary, gfc_ref * tail)
+{
+
+ if (primary->ref == NULL)
+ primary->ref = tail = gfc_get_ref ();
+ else
+ {
+ if (tail == NULL)
+ gfc_internal_error ("extend_ref(): Bad tail");
+ tail->next = gfc_get_ref ();
+ tail = tail->next;
+ }
+
+ return tail;
+}
+
+
+/* Match any additional specifications associated with the current
+ variable like member references or substrings. If equiv_flag is
+ set we only match stuff that is allowed inside an EQUIVALENCE
+ statement. */
+
+static match
+match_varspec (gfc_expr * primary, int equiv_flag)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_ref *substring, *tail;
+ gfc_component *component;
+ gfc_symbol *sym;
+ match m;
+
+ tail = NULL;
+
+ if (primary->symtree->n.sym->attr.dimension
+ || (equiv_flag
+ && gfc_peek_char () == '('))
+ {
+
+ tail = extend_ref (primary, tail);
+ tail->type = REF_ARRAY;
+
+ m = gfc_match_array_ref (&tail->u.ar, primary->symtree->n.sym->as,
+ equiv_flag);
+ if (m != MATCH_YES)
+ return m;
+ }
+
+ sym = primary->symtree->n.sym;
+ primary->ts = sym->ts;
+
+ if (sym->ts.type != BT_DERIVED || gfc_match_char ('%') != MATCH_YES)
+ goto check_substring;
+
+ sym = sym->ts.derived;
+
+ for (;;)
+ {
+ m = gfc_match_name (name);
+ if (m == MATCH_NO)
+ gfc_error ("Expected structure component name at %C");
+ if (m != MATCH_YES)
+ return MATCH_ERROR;
+
+ component = gfc_find_component (sym, name);
+ if (component == NULL)
+ return MATCH_ERROR;
+
+ tail = extend_ref (primary, tail);
+ tail->type = REF_COMPONENT;
+
+ tail->u.c.component = component;
+ tail->u.c.sym = sym;
+
+ primary->ts = component->ts;
+
+ if (component->as != NULL)
+ {
+ tail = extend_ref (primary, tail);
+ tail->type = REF_ARRAY;
+
+ m = gfc_match_array_ref (&tail->u.ar, component->as, equiv_flag);
+ if (m != MATCH_YES)
+ return m;
+ }
+
+ if (component->ts.type != BT_DERIVED
+ || gfc_match_char ('%') != MATCH_YES)
+ break;
+
+ sym = component->ts.derived;
+ }
+
+check_substring:
+ if (primary->ts.type == BT_CHARACTER)
+ {
+ switch (match_substring (primary->ts.cl, equiv_flag, &substring))
+ {
+ case MATCH_YES:
+ if (tail == NULL)
+ primary->ref = substring;
+ else
+ tail->next = substring;
+
+ if (primary->expr_type == EXPR_CONSTANT)
+ primary->expr_type = EXPR_SUBSTRING;
+
+ break;
+
+ case MATCH_NO:
+ break;
+
+ case MATCH_ERROR:
+ return MATCH_ERROR;
+ }
+ }
+
+ return MATCH_YES;
+}
+
+
+/* Given an expression that is a variable, figure out what the
+ ultimate variable's type and attribute is, traversing the reference
+ structures if necessary.
+
+ This subroutine is trickier than it looks. We start at the base
+ symbol and store the attribute. Component references load a
+ completely new attribute.
+
+ A couple of rules come into play. Subobjects of targets are always
+ targets themselves. If we see a component that goes through a
+ pointer, then the expression must also be a target, since the
+ pointer is associated with something (if it isn't core will soon be
+ dumped). If we see a full part or section of an array, the
+ expression is also an array.
+
+ We can have at most one full array reference. */
+
+symbol_attribute
+gfc_variable_attr (gfc_expr * expr, gfc_typespec * ts)
+{
+ int dimension, pointer, target;
+ symbol_attribute attr;
+ gfc_ref *ref;
+
+ if (expr->expr_type != EXPR_VARIABLE)
+ gfc_internal_error ("gfc_variable_attr(): Expression isn't a variable");
+
+ ref = expr->ref;
+ attr = expr->symtree->n.sym->attr;
+
+ dimension = attr.dimension;
+ pointer = attr.pointer;
+
+ target = attr.target;
+ if (pointer)
+ target = 1;
+
+ if (ts != NULL && expr->ts.type == BT_UNKNOWN)
+ *ts = expr->symtree->n.sym->ts;
+
+ for (; ref; ref = ref->next)
+ switch (ref->type)
+ {
+ case REF_ARRAY:
+
+ switch (ref->u.ar.type)
+ {
+ case AR_FULL:
+ dimension = 1;
+ break;
+
+ case AR_SECTION:
+ pointer = 0;
+ dimension = 1;
+ break;
+
+ case AR_ELEMENT:
+ pointer = 0;
+ break;
+
+ case AR_UNKNOWN:
+ gfc_internal_error ("gfc_variable_attr(): Bad array reference");
+ }
+
+ break;
+
+ case REF_COMPONENT:
+ gfc_get_component_attr (&attr, ref->u.c.component);
+ if (ts != NULL)
+ *ts = ref->u.c.component->ts;
+
+ pointer = ref->u.c.component->pointer;
+ if (pointer)
+ target = 1;
+
+ break;
+
+ case REF_SUBSTRING:
+ pointer = 0;
+ break;
+ }
+
+ attr.dimension = dimension;
+ attr.pointer = pointer;
+ attr.target = target;
+
+ return attr;
+}
+
+
+/* Return the attribute from a general expression. */
+
+symbol_attribute
+gfc_expr_attr (gfc_expr * e)
+{
+ symbol_attribute attr;
+
+ switch (e->expr_type)
+ {
+ case EXPR_VARIABLE:
+ attr = gfc_variable_attr (e, NULL);
+ break;
+
+ case EXPR_FUNCTION:
+ gfc_clear_attr (&attr);
+
+ if (e->value.function.esym != NULL)
+ attr = e->value.function.esym->result->attr;
+
+ /* TODO: NULL() returns pointers. May have to take care of this
+ here. */
+
+ break;
+
+ default:
+ gfc_clear_attr (&attr);
+ break;
+ }
+
+ return attr;
+}
+
+
+/* Match a structure constructor. The initial symbol has already been
+ seen. */
+
+static match
+match_structure_constructor (gfc_symbol * sym, gfc_expr ** result)
+{
+ gfc_constructor *head, *tail;
+ gfc_component *comp;
+ gfc_expr *e;
+ locus where;
+ match m;
+
+ head = tail = NULL;
+
+ if (gfc_match_char ('(') != MATCH_YES)
+ goto syntax;
+
+ where = *gfc_current_locus ();
+
+ gfc_find_component (sym, NULL);
+
+ for (comp = sym->components; comp; comp = comp->next)
+ {
+ if (head == NULL)
+ tail = head = gfc_get_constructor ();
+ else
+ {
+ tail->next = gfc_get_constructor ();
+ tail = tail->next;
+ }
+
+ m = gfc_match_expr (&tail->expr);
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ if (gfc_match_char (',') == MATCH_YES)
+ {
+ if (comp->next == NULL)
+ {
+ gfc_error
+ ("Too many components in structure constructor at %C");
+ goto cleanup;
+ }
+
+ continue;
+ }
+
+ break;
+ }
+
+ if (gfc_match_char (')') != MATCH_YES)
+ goto syntax;
+
+ if (comp->next != NULL)
+ {
+ gfc_error ("Too few components in structure constructor at %C");
+ goto cleanup;
+ }
+
+ e = gfc_get_expr ();
+
+ e->expr_type = EXPR_STRUCTURE;
+
+ e->ts.type = BT_DERIVED;
+ e->ts.derived = sym;
+ e->where = where;
+
+ e->value.constructor = head;
+
+ *result = e;
+ return MATCH_YES;
+
+syntax:
+ gfc_error ("Syntax error in structure constructor at %C");
+
+cleanup:
+ gfc_free_constructor (head);
+ return MATCH_ERROR;
+}
+
+
+/* Matches a variable name followed by anything that might follow it--
+ array reference, argument list of a function, etc. */
+
+match
+gfc_match_rvalue (gfc_expr ** result)
+{
+ gfc_actual_arglist *actual_arglist;
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_state_data *st;
+ gfc_symbol *sym;
+ gfc_symtree *symtree;
+ locus where;
+ gfc_expr *e;
+ match m;
+ int i;
+
+ m = gfc_match_name (name);
+ if (m != MATCH_YES)
+ return m;
+
+ if (gfc_find_state (COMP_INTERFACE) == SUCCESS)
+ i = gfc_get_sym_tree (name, NULL, &symtree);
+ else
+ i = gfc_get_ha_sym_tree (name, &symtree);
+
+ if (i)
+ return MATCH_ERROR;
+
+ sym = symtree->n.sym;
+ e = NULL;
+ where = *gfc_current_locus ();
+
+ gfc_set_sym_referenced (sym);
+
+ if (sym->attr.function && sym->result == sym
+ && (gfc_current_ns->proc_name == sym
+ || (gfc_current_ns->parent != NULL
+ && gfc_current_ns->parent->proc_name == sym)))
+ goto variable;
+
+ if (sym->attr.function || sym->attr.external || sym->attr.intrinsic)
+ goto function0;
+
+ if (sym->attr.generic)
+ goto generic_function;
+
+ switch (sym->attr.flavor)
+ {
+ case FL_VARIABLE:
+ variable:
+ if (sym->ts.type == BT_UNKNOWN && gfc_peek_char () == '%'
+ && gfc_get_default_type (sym, sym->ns)->type == BT_DERIVED)
+ gfc_set_default_type (sym, 0, sym->ns);
+
+ e = gfc_get_expr ();
+
+ e->expr_type = EXPR_VARIABLE;
+ e->symtree = symtree;
+
+ m = match_varspec (e, 0);
+ break;
+
+ case FL_PARAMETER:
+ if (sym->value
+ && sym->value->expr_type != EXPR_ARRAY)
+ e = gfc_copy_expr (sym->value);
+ else
+ {
+ e = gfc_get_expr ();
+ e->expr_type = EXPR_VARIABLE;
+ }
+
+ e->symtree = symtree;
+ m = match_varspec (e, 0);
+ break;
+
+ case FL_DERIVED:
+ sym = gfc_use_derived (sym);
+ if (sym == NULL)
+ m = MATCH_ERROR;
+ else
+ m = match_structure_constructor (sym, &e);
+ break;
+
+ /* If we're here, then the name is known to be the name of a
+ procedure, yet it is not sure to be the name of a function. */
+ case FL_PROCEDURE:
+ if (sym->attr.subroutine)
+ {
+ gfc_error ("Unexpected use of subroutine name '%s' at %C",
+ sym->name);
+ m = MATCH_ERROR;
+ break;
+ }
+
+ /* At this point, the name has to be a non-statement function.
+ If the name is the same as the current function being
+ compiled, then we have a variable reference (to the function
+ result) if the name is non-recursive. */
+
+ st = gfc_enclosing_unit (NULL);
+
+ if (st != NULL && st->state == COMP_FUNCTION
+ && st->sym == sym
+ && !sym->attr.recursive)
+ {
+ e = gfc_get_expr ();
+ e->symtree = symtree;
+ e->expr_type = EXPR_VARIABLE;
+
+ m = match_varspec (e, 0);
+ break;
+ }
+
+ /* Match a function reference. */
+ function0:
+ m = gfc_match_actual_arglist (0, &actual_arglist);
+ if (m == MATCH_NO)
+ {
+ if (sym->attr.proc == PROC_ST_FUNCTION)
+ gfc_error ("Statement function '%s' requires argument list at %C",
+ sym->name);
+ else
+ gfc_error ("Function '%s' requires an argument list at %C",
+ sym->name);
+
+ m = MATCH_ERROR;
+ break;
+ }
+
+ if (m != MATCH_YES)
+ {
+ m = MATCH_ERROR;
+ break;
+ }
+
+ gfc_get_ha_sym_tree (name, &symtree); /* Can't fail */
+ sym = symtree->n.sym;
+
+ e = gfc_get_expr ();
+ e->symtree = symtree;
+ e->expr_type = EXPR_FUNCTION;
+ e->value.function.actual = actual_arglist;
+ e->where = *gfc_current_locus ();
+
+ if (sym->as != NULL)
+ e->rank = sym->as->rank;
+
+ if (!sym->attr.function
+ && gfc_add_function (&sym->attr, NULL) == FAILURE)
+ {
+ m = MATCH_ERROR;
+ break;
+ }
+
+ if (sym->result == NULL)
+ sym->result = sym;
+
+ m = MATCH_YES;
+ break;
+
+ case FL_UNKNOWN:
+
+ /* Special case for derived type variables that get their types
+ via an IMPLICIT statement. This can't wait for the
+ resolution phase. */
+
+ if (gfc_peek_char () == '%'
+ && gfc_get_default_type (sym, sym->ns)->type == BT_DERIVED)
+ gfc_set_default_type (sym, 0, sym->ns);
+
+ /* If the symbol has a dimension attribute, the expression is a
+ variable. */
+
+ if (sym->attr.dimension)
+ {
+ if (gfc_add_flavor (&sym->attr, FL_VARIABLE, NULL) == FAILURE)
+ {
+ m = MATCH_ERROR;
+ break;
+ }
+
+ e = gfc_get_expr ();
+ e->symtree = symtree;
+ e->expr_type = EXPR_VARIABLE;
+ m = match_varspec (e, 0);
+ break;
+ }
+
+ /* Name is not an array, so we peek to see if a '(' implies a
+ function call or a substring reference. Otherwise the
+ variable is just a scalar. */
+
+ gfc_gobble_whitespace ();
+ if (gfc_peek_char () != '(')
+ {
+ /* Assume a scalar variable */
+ e = gfc_get_expr ();
+ e->symtree = symtree;
+ e->expr_type = EXPR_VARIABLE;
+
+ if (gfc_add_flavor (&sym->attr, FL_VARIABLE, NULL) == FAILURE)
+ {
+ m = MATCH_ERROR;
+ break;
+ }
+
+ e->ts = sym->ts;
+ m = match_varspec (e, 0);
+ break;
+ }
+
+ /* See if this could possibly be a substring reference of a name
+ that we're not sure is a variable yet. */
+
+ e = gfc_get_expr ();
+ e->symtree = symtree;
+
+ if ((sym->ts.type == BT_UNKNOWN || sym->ts.type == BT_CHARACTER)
+ && match_substring (sym->ts.cl, 0, &e->ref) == MATCH_YES)
+ {
+
+ e->expr_type = EXPR_VARIABLE;
+
+ if (sym->attr.flavor != FL_VARIABLE
+ && gfc_add_flavor (&sym->attr, FL_VARIABLE, NULL) == FAILURE)
+ {
+ m = MATCH_ERROR;
+ break;
+ }
+
+ if (sym->ts.type == BT_UNKNOWN
+ && gfc_set_default_type (sym, 1, NULL) == FAILURE)
+ {
+ m = MATCH_ERROR;
+ break;
+ }
+
+ e->ts = sym->ts;
+ m = MATCH_YES;
+ break;
+ }
+
+ /* Give up, assume we have a function. */
+
+ gfc_get_sym_tree (name, NULL, &symtree); /* Can't fail */
+ sym = symtree->n.sym;
+ e->expr_type = EXPR_FUNCTION;
+
+ if (!sym->attr.function
+ && gfc_add_function (&sym->attr, NULL) == FAILURE)
+ {
+ m = MATCH_ERROR;
+ break;
+ }
+
+ sym->result = sym;
+
+ m = gfc_match_actual_arglist (0, &e->value.function.actual);
+ if (m == MATCH_NO)
+ gfc_error ("Missing argument list in function '%s' at %C", sym->name);
+
+ if (m != MATCH_YES)
+ {
+ m = MATCH_ERROR;
+ break;
+ }
+
+ /* If our new function returns a character, array or structure
+ type, it might have subsequent references. */
+
+ m = match_varspec (e, 0);
+ if (m == MATCH_NO)
+ m = MATCH_YES;
+
+ break;
+
+ generic_function:
+ gfc_get_sym_tree (name, NULL, &symtree); /* Can't fail */
+
+ e = gfc_get_expr ();
+ e->symtree = symtree;
+ e->expr_type = EXPR_FUNCTION;
+
+ m = gfc_match_actual_arglist (0, &e->value.function.actual);
+ break;
+
+ default:
+ gfc_error ("Symbol at %C is not appropriate for an expression");
+ return MATCH_ERROR;
+ }
+
+ if (m == MATCH_YES)
+ {
+ e->where = where;
+ *result = e;
+ }
+ else
+ gfc_free_expr (e);
+
+ return m;
+}
+
+
+/* Match a variable, ie something that can be assigned to. This
+ starts as a symbol, can be a structure component or an array
+ reference. It can be a function if the function doesn't have a
+ separate RESULT variable. If the symbol has not been previously
+ seen, we assume it is a variable. */
+
+match
+gfc_match_variable (gfc_expr ** result, int equiv_flag)
+{
+ gfc_symbol *sym;
+ gfc_symtree *st;
+ gfc_expr *expr;
+ locus where;
+ match m;
+
+ m = gfc_match_sym_tree (&st, 1);
+ if (m != MATCH_YES)
+ return m;
+ where = *gfc_current_locus ();
+
+ sym = st->n.sym;
+ gfc_set_sym_referenced (sym);
+ switch (sym->attr.flavor)
+ {
+ case FL_VARIABLE:
+ break;
+
+ case FL_UNKNOWN:
+ if (gfc_add_flavor (&sym->attr, FL_VARIABLE, NULL) == FAILURE)
+ return MATCH_ERROR;
+
+ /* Special case for derived type variables that get their types
+ via an IMPLICIT statement. This can't wait for the
+ resolution phase. */
+
+ if (gfc_peek_char () == '%'
+ && gfc_get_default_type (sym, sym->ns)->type == BT_DERIVED)
+ gfc_set_default_type (sym, 0, sym->ns);
+
+ break;
+
+ case FL_PROCEDURE:
+ /* Check for a nonrecursive function result */
+ if (sym->attr.function && (sym->result == sym || sym->attr.entry))
+ {
+
+ /* If a function result is a derived type, then the derived
+ type may still have to be resolved. */
+
+ if (sym->ts.type == BT_DERIVED
+ && gfc_use_derived (sym->ts.derived) == NULL)
+ return MATCH_ERROR;
+
+ break;
+ }
+
+ /* Fall through to error */
+
+ default:
+ gfc_error ("Expected VARIABLE at %C");
+ return MATCH_ERROR;
+ }
+
+ expr = gfc_get_expr ();
+
+ expr->expr_type = EXPR_VARIABLE;
+ expr->symtree = st;
+ expr->ts = sym->ts;
+ expr->where = where;
+
+ /* Now see if we have to do more. */
+ m = match_varspec (expr, equiv_flag);
+ if (m != MATCH_YES)
+ {
+ gfc_free_expr (expr);
+ return m;
+ }
+
+ *result = expr;
+ return MATCH_YES;
+}
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
new file mode 100644
index 00000000000..3530ee1c07e
--- /dev/null
+++ b/gcc/fortran/resolve.c
@@ -0,0 +1,4435 @@
+/* Perform type resolution on the various stuctures.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330,Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "gfortran.h"
+#include "arith.h" /* For gfc_compare_expr(). */
+#include <assert.h>
+#include <string.h>
+
+/* Stack to push the current if we descend into a block during
+ resolution. See resolve_branch() and resolve_code(). */
+
+typedef struct code_stack
+{
+ struct gfc_code *head, *current;
+ struct code_stack *prev;
+}
+code_stack;
+
+static code_stack *cs_base = NULL;
+
+
+/* Nonzero if we're inside a FORALL block */
+
+static int forall_flag;
+
+/* Resolve types of formal argument lists. These have to be done early so that
+ the formal argument lists of module procedures can be copied to the
+ containing module before the individual procedures are resolved
+ individually. We also resolve argument lists of procedures in interface
+ blocks because they are self-contained scoping units.
+
+ Since a dummy argument cannot be a non-dummy procedure, the only
+ resort left for untyped names are the IMPLICIT types. */
+
+static void
+resolve_formal_arglist (gfc_symbol * proc)
+{
+ gfc_formal_arglist *f;
+ gfc_symbol *sym;
+ int i;
+
+ /* TODO: Procedures whose return character length parameter is not constant
+ or assumed must also have explicit interfaces. */
+ if (proc->result != NULL)
+ sym = proc->result;
+ else
+ sym = proc;
+
+ if (gfc_elemental (proc)
+ || sym->attr.pointer || sym->attr.allocatable
+ || (sym->as && sym->as->rank > 0))
+ proc->attr.always_explicit = 1;
+
+ for (f = proc->formal; f; f = f->next)
+ {
+ sym = f->sym;
+
+ if (sym == NULL)
+ {
+ /* Alternate return placeholder. */
+ if (gfc_elemental (proc))
+ gfc_error ("Alternate return specifier in elemental subroutine "
+ "'%s' at %L is not allowed", proc->name,
+ &proc->declared_at);
+ if (proc->attr.function)
+ gfc_error ("Alternate return specifier in function "
+ "'%s' at %L is not allowed", proc->name,
+ &proc->declared_at);
+ continue;
+ }
+
+ if (sym->attr.if_source != IFSRC_UNKNOWN)
+ resolve_formal_arglist (sym);
+
+ if (sym->attr.subroutine || sym->attr.external || sym->attr.intrinsic)
+ {
+ if (gfc_pure (proc) && !gfc_pure (sym))
+ {
+ gfc_error
+ ("Dummy procedure '%s' of PURE procedure at %L must also "
+ "be PURE", sym->name, &sym->declared_at);
+ continue;
+ }
+
+ if (gfc_elemental (proc))
+ {
+ gfc_error
+ ("Dummy procedure at %L not allowed in ELEMENTAL procedure",
+ &sym->declared_at);
+ continue;
+ }
+
+ continue;
+ }
+
+ if (sym->ts.type == BT_UNKNOWN)
+ {
+ if (!sym->attr.function || sym->result == sym)
+ gfc_set_default_type (sym, 1, sym->ns);
+ else
+ {
+ /* Set the type of the RESULT, then copy. */
+ if (sym->result->ts.type == BT_UNKNOWN)
+ gfc_set_default_type (sym->result, 1, sym->result->ns);
+
+ sym->ts = sym->result->ts;
+ if (sym->as == NULL)
+ sym->as = gfc_copy_array_spec (sym->result->as);
+ }
+ }
+
+ gfc_resolve_array_spec (sym->as, 0);
+
+ /* We can't tell if an array with dimension (:) is assumed or deferred
+ shape until we know if it has the pointer or allocatable attributes.
+ */
+ if (sym->as && sym->as->rank > 0 && sym->as->type == AS_DEFERRED
+ && !(sym->attr.pointer || sym->attr.allocatable))
+ {
+ sym->as->type = AS_ASSUMED_SHAPE;
+ for (i = 0; i < sym->as->rank; i++)
+ sym->as->lower[i] = gfc_int_expr (1);
+ }
+
+ if ((sym->as && sym->as->rank > 0 && sym->as->type == AS_ASSUMED_SHAPE)
+ || sym->attr.pointer || sym->attr.allocatable || sym->attr.target
+ || sym->attr.optional)
+ proc->attr.always_explicit = 1;
+
+ /* If the flavor is unknown at this point, it has to be a variable.
+ A procedure specification would have already set the type. */
+
+ if (sym->attr.flavor == FL_UNKNOWN)
+ gfc_add_flavor (&sym->attr, FL_VARIABLE, &sym->declared_at);
+
+ if (gfc_pure (proc))
+ {
+ if (proc->attr.function && !sym->attr.pointer
+ && sym->attr.flavor != FL_PROCEDURE
+ && sym->attr.intent != INTENT_IN)
+
+ gfc_error ("Argument '%s' of pure function '%s' at %L must be "
+ "INTENT(IN)", sym->name, proc->name,
+ &sym->declared_at);
+
+ if (proc->attr.subroutine && !sym->attr.pointer
+ && sym->attr.intent == INTENT_UNKNOWN)
+
+ gfc_error
+ ("Argument '%s' of pure subroutine '%s' at %L must have "
+ "its INTENT specified", sym->name, proc->name,
+ &sym->declared_at);
+ }
+
+
+ if (gfc_elemental (proc))
+ {
+ if (sym->as != NULL)
+ {
+ gfc_error
+ ("Argument '%s' of elemental procedure at %L must be scalar",
+ sym->name, &sym->declared_at);
+ continue;
+ }
+
+ if (sym->attr.pointer)
+ {
+ gfc_error
+ ("Argument '%s' of elemental procedure at %L cannot have "
+ "the POINTER attribute", sym->name, &sym->declared_at);
+ continue;
+ }
+ }
+
+ /* Each dummy shall be specified to be scalar. */
+ if (proc->attr.proc == PROC_ST_FUNCTION)
+ {
+ if (sym->as != NULL)
+ {
+ gfc_error
+ ("Argument '%s' of statement function at %L must be scalar",
+ sym->name, &sym->declared_at);
+ continue;
+ }
+
+ if (sym->ts.type == BT_CHARACTER)
+ {
+ gfc_charlen *cl = sym->ts.cl;
+ if (!cl || !cl->length || cl->length->expr_type != EXPR_CONSTANT)
+ {
+ gfc_error
+ ("Character-valued argument '%s' of statement function at "
+ "%L must has constant length",
+ sym->name, &sym->declared_at);
+ continue;
+ }
+ }
+ }
+ }
+}
+
+
+/* Work function called when searching for symbols that have argument lists
+ associated with them. */
+
+static void
+find_arglists (gfc_symbol * sym)
+{
+
+ if (sym->attr.if_source == IFSRC_UNKNOWN || sym->ns != gfc_current_ns)
+ return;
+
+ resolve_formal_arglist (sym);
+}
+
+
+/* Given a namespace, resolve all formal argument lists within the namespace.
+ */
+
+static void
+resolve_formal_arglists (gfc_namespace * ns)
+{
+
+ if (ns == NULL)
+ return;
+
+ gfc_traverse_ns (ns, find_arglists);
+}
+
+
+/* Resolve contained function types. Because contained functions can call one
+ another, they have to be worked out before any of the contained procedures
+ can be resolved.
+
+ The good news is that if a function doesn't already have a type, the only
+ way it can get one is through an IMPLICIT type or a RESULT variable, because
+ by definition contained functions are contained namespace they're contained
+ in, not in a sibling or parent namespace. */
+
+static void
+resolve_contained_functions (gfc_namespace * ns)
+{
+ gfc_symbol *contained_sym, *sym_lower;
+ gfc_namespace *child;
+ try t;
+
+ resolve_formal_arglists (ns);
+
+ for (child = ns->contained; child; child = child->sibling)
+ {
+ sym_lower = child->proc_name;
+
+ /* If this namespace is not a function, ignore it. */
+ if (! sym_lower
+ || !( sym_lower->attr.function
+ || sym_lower->attr.flavor == FL_VARIABLE))
+ continue;
+
+ /* Find the contained symbol in the current namespace. */
+ gfc_find_symbol (sym_lower->name, ns, 0, &contained_sym);
+
+ if (contained_sym == NULL)
+ gfc_internal_error ("resolve_contained_functions(): Contained "
+ "function not found in parent namespace");
+
+ /* Try to find out of what type the function is. If there was an
+ explicit RESULT clause, try to get the type from it. If the
+ function is never defined, set it to the implicit type. If
+ even that fails, give up. */
+ if (sym_lower->result != NULL)
+ sym_lower = sym_lower->result;
+
+ if (sym_lower->ts.type == BT_UNKNOWN)
+ {
+ /* Assume we can find an implicit type. */
+ t = SUCCESS;
+
+ if (sym_lower->result == NULL)
+ t = gfc_set_default_type (sym_lower, 0, child);
+ else
+ {
+ if (sym_lower->result->ts.type == BT_UNKNOWN)
+ t = gfc_set_default_type (sym_lower->result, 0, NULL);
+
+ sym_lower->ts = sym_lower->result->ts;
+ }
+
+ if (t == FAILURE)
+ gfc_error ("Contained function '%s' at %L has no IMPLICIT type",
+ sym_lower->name, &sym_lower->declared_at); /* FIXME */
+ }
+
+ /* If the symbol in the parent of the contained namespace is not
+ the same as the one in contained namespace itself, copy over
+ the type information. */
+ /* ??? Shouldn't we replace the symbol with the parent symbol instead? */
+ if (contained_sym != sym_lower)
+ {
+ contained_sym->ts = sym_lower->ts;
+ contained_sym->as = gfc_copy_array_spec (sym_lower->as);
+ }
+ }
+}
+
+
+/* Resolve all of the elements of a structure constructor and make sure that
+ the types are correct. */
+
+static try
+resolve_structure_cons (gfc_expr * expr)
+{
+ gfc_constructor *cons;
+ gfc_component *comp;
+ try t;
+
+ t = SUCCESS;
+ cons = expr->value.constructor;
+ /* A constructor may have references if it is the result of substituting a
+ parameter variable. In this case we just pull out the component we
+ want. */
+ if (expr->ref)
+ comp = expr->ref->u.c.sym->components;
+ else
+ comp = expr->ts.derived->components;
+
+ for (; comp; comp = comp->next, cons = cons->next)
+ {
+ if (! cons->expr)
+ {
+ t = FAILURE;
+ continue;
+ }
+
+ if (gfc_resolve_expr (cons->expr) == FAILURE)
+ {
+ t = FAILURE;
+ continue;
+ }
+
+ /* If we don't have the right type, try to convert it. */
+
+ if (!gfc_compare_types (&cons->expr->ts, &comp->ts)
+ && gfc_convert_type (cons->expr, &comp->ts, 1) == FAILURE)
+ t = FAILURE;
+ }
+
+ return t;
+}
+
+
+
+/****************** Expression name resolution ******************/
+
+/* Returns 0 if a symbol was not declared with a type or
+ or attribute declaration statement, nonzero otherwise. */
+
+static int
+was_declared (gfc_symbol * sym)
+{
+ symbol_attribute a;
+
+ a = sym->attr;
+
+ if (!a.implicit_type && sym->ts.type != BT_UNKNOWN)
+ return 1;
+
+ if (a.allocatable || a.dimension || a.external || a.intrinsic
+ || a.optional || a.pointer || a.save || a.target
+ || a.access != ACCESS_UNKNOWN || a.intent != INTENT_UNKNOWN)
+ return 1;
+
+ return 0;
+}
+
+
+/* Determine if a symbol is generic or not. */
+
+static int
+generic_sym (gfc_symbol * sym)
+{
+ gfc_symbol *s;
+
+ if (sym->attr.generic ||
+ (sym->attr.intrinsic && gfc_generic_intrinsic (sym->name)))
+ return 1;
+
+ if (was_declared (sym) || sym->ns->parent == NULL)
+ return 0;
+
+ gfc_find_symbol (sym->name, sym->ns->parent, 1, &s);
+
+ return (s == NULL) ? 0 : generic_sym (s);
+}
+
+
+/* Determine if a symbol is specific or not. */
+
+static int
+specific_sym (gfc_symbol * sym)
+{
+ gfc_symbol *s;
+
+ if (sym->attr.if_source == IFSRC_IFBODY
+ || sym->attr.proc == PROC_MODULE
+ || sym->attr.proc == PROC_INTERNAL
+ || sym->attr.proc == PROC_ST_FUNCTION
+ || (sym->attr.intrinsic &&
+ gfc_specific_intrinsic (sym->name))
+ || sym->attr.external)
+ return 1;
+
+ if (was_declared (sym) || sym->ns->parent == NULL)
+ return 0;
+
+ gfc_find_symbol (sym->name, sym->ns->parent, 1, &s);
+
+ return (s == NULL) ? 0 : specific_sym (s);
+}
+
+
+/* Figure out if the procedure is specific, generic or unknown. */
+
+typedef enum
+{ PTYPE_GENERIC = 1, PTYPE_SPECIFIC, PTYPE_UNKNOWN }
+proc_type;
+
+static proc_type
+procedure_kind (gfc_symbol * sym)
+{
+
+ if (generic_sym (sym))
+ return PTYPE_GENERIC;
+
+ if (specific_sym (sym))
+ return PTYPE_SPECIFIC;
+
+ return PTYPE_UNKNOWN;
+}
+
+
+/* Resolve an actual argument list. Most of the time, this is just
+ resolving the expressions in the list.
+ The exception is that we sometimes have to decide whether arguments
+ that look like procedure arguments are really simple variable
+ references. */
+
+static try
+resolve_actual_arglist (gfc_actual_arglist * arg)
+{
+ gfc_symbol *sym;
+ gfc_symtree *parent_st;
+ gfc_expr *e;
+
+ for (; arg; arg = arg->next)
+ {
+
+ e = arg->expr;
+ if (e == NULL)
+ {
+ /* Check the label is a valid branching target. */
+ if (arg->label)
+ {
+ if (arg->label->defined == ST_LABEL_UNKNOWN)
+ {
+ gfc_error ("Label %d referenced at %L is never defined",
+ arg->label->value, &arg->label->where);
+ return FAILURE;
+ }
+ }
+ continue;
+ }
+
+ if (e->ts.type != BT_PROCEDURE)
+ {
+ if (gfc_resolve_expr (e) != SUCCESS)
+ return FAILURE;
+ continue;
+ }
+
+ /* See if the expression node should really be a variable
+ reference. */
+
+ sym = e->symtree->n.sym;
+
+ if (sym->attr.flavor == FL_PROCEDURE
+ || sym->attr.intrinsic
+ || sym->attr.external)
+ {
+
+ /* If the symbol is the function that names the current (or
+ parent) scope, then we really have a variable reference. */
+
+ if (sym->attr.function && sym->result == sym
+ && (sym->ns->proc_name == sym
+ || (sym->ns->parent != NULL
+ && sym->ns->parent->proc_name == sym)))
+ goto got_variable;
+
+ continue;
+ }
+
+ /* See if the name is a module procedure in a parent unit. */
+
+ if (was_declared (sym) || sym->ns->parent == NULL)
+ goto got_variable;
+
+ if (gfc_find_sym_tree (sym->name, sym->ns->parent, 1, &parent_st))
+ {
+ gfc_error ("Symbol '%s' at %L is ambiguous", sym->name, &e->where);
+ return FAILURE;
+ }
+
+ if (parent_st == NULL)
+ goto got_variable;
+
+ sym = parent_st->n.sym;
+ e->symtree = parent_st; /* Point to the right thing. */
+
+ if (sym->attr.flavor == FL_PROCEDURE
+ || sym->attr.intrinsic
+ || sym->attr.external)
+ {
+ continue;
+ }
+
+ got_variable:
+ e->expr_type = EXPR_VARIABLE;
+ e->ts = sym->ts;
+ if (sym->as != NULL)
+ {
+ e->rank = sym->as->rank;
+ e->ref = gfc_get_ref ();
+ e->ref->type = REF_ARRAY;
+ e->ref->u.ar.type = AR_FULL;
+ e->ref->u.ar.as = sym->as;
+ }
+ }
+
+ return SUCCESS;
+}
+
+
+/************* Function resolution *************/
+
+/* Resolve a function call known to be generic.
+ Section 14.1.2.4.1. */
+
+static match
+resolve_generic_f0 (gfc_expr * expr, gfc_symbol * sym)
+{
+ gfc_symbol *s;
+
+ if (sym->attr.generic)
+ {
+ s =
+ gfc_search_interface (sym->generic, 0, &expr->value.function.actual);
+ if (s != NULL)
+ {
+ expr->value.function.name = s->name;
+ expr->value.function.esym = s;
+ expr->ts = s->ts;
+ if (s->as != NULL)
+ expr->rank = s->as->rank;
+ return MATCH_YES;
+ }
+
+ /* TODO: Need to search for elemental references in generic interface */
+ }
+
+ if (sym->attr.intrinsic)
+ return gfc_intrinsic_func_interface (expr, 0);
+
+ return MATCH_NO;
+}
+
+
+static try
+resolve_generic_f (gfc_expr * expr)
+{
+ gfc_symbol *sym;
+ match m;
+
+ sym = expr->symtree->n.sym;
+
+ for (;;)
+ {
+ m = resolve_generic_f0 (expr, sym);
+ if (m == MATCH_YES)
+ return SUCCESS;
+ else if (m == MATCH_ERROR)
+ return FAILURE;
+
+generic:
+ if (sym->ns->parent == NULL)
+ break;
+ gfc_find_symbol (sym->name, sym->ns->parent, 1, &sym);
+
+ if (sym == NULL)
+ break;
+ if (!generic_sym (sym))
+ goto generic;
+ }
+
+ /* Last ditch attempt. */
+
+ if (!gfc_generic_intrinsic (expr->symtree->n.sym->name))
+ {
+ gfc_error ("Generic function '%s' at %L is not an intrinsic function",
+ expr->symtree->n.sym->name, &expr->where);
+ return FAILURE;
+ }
+
+ m = gfc_intrinsic_func_interface (expr, 0);
+ if (m == MATCH_YES)
+ return SUCCESS;
+ if (m == MATCH_NO)
+ gfc_error
+ ("Generic function '%s' at %L is not consistent with a specific "
+ "intrinsic interface", expr->symtree->n.sym->name, &expr->where);
+
+ return FAILURE;
+}
+
+
+/* Resolve a function call known to be specific. */
+
+static match
+resolve_specific_f0 (gfc_symbol * sym, gfc_expr * expr)
+{
+ match m;
+
+ if (sym->attr.external || sym->attr.if_source == IFSRC_IFBODY)
+ {
+ if (sym->attr.dummy)
+ {
+ sym->attr.proc = PROC_DUMMY;
+ goto found;
+ }
+
+ sym->attr.proc = PROC_EXTERNAL;
+ goto found;
+ }
+
+ if (sym->attr.proc == PROC_MODULE
+ || sym->attr.proc == PROC_ST_FUNCTION
+ || sym->attr.proc == PROC_INTERNAL)
+ goto found;
+
+ if (sym->attr.intrinsic)
+ {
+ m = gfc_intrinsic_func_interface (expr, 1);
+ if (m == MATCH_YES)
+ return MATCH_YES;
+ if (m == MATCH_NO)
+ gfc_error
+ ("Function '%s' at %L is INTRINSIC but is not compatible with "
+ "an intrinsic", sym->name, &expr->where);
+
+ return MATCH_ERROR;
+ }
+
+ return MATCH_NO;
+
+found:
+ gfc_procedure_use (sym, &expr->value.function.actual, &expr->where);
+
+ expr->ts = sym->ts;
+ expr->value.function.name = sym->name;
+ expr->value.function.esym = sym;
+ if (sym->as != NULL)
+ expr->rank = sym->as->rank;
+
+ return MATCH_YES;
+}
+
+
+static try
+resolve_specific_f (gfc_expr * expr)
+{
+ gfc_symbol *sym;
+ match m;
+
+ sym = expr->symtree->n.sym;
+
+ for (;;)
+ {
+ m = resolve_specific_f0 (sym, expr);
+ if (m == MATCH_YES)
+ return SUCCESS;
+ if (m == MATCH_ERROR)
+ return FAILURE;
+
+ if (sym->ns->parent == NULL)
+ break;
+
+ gfc_find_symbol (sym->name, sym->ns->parent, 1, &sym);
+
+ if (sym == NULL)
+ break;
+ }
+
+ gfc_error ("Unable to resolve the specific function '%s' at %L",
+ expr->symtree->n.sym->name, &expr->where);
+
+ return SUCCESS;
+}
+
+
+/* Resolve a procedure call not known to be generic nor specific. */
+
+static try
+resolve_unknown_f (gfc_expr * expr)
+{
+ gfc_symbol *sym;
+ gfc_typespec *ts;
+
+ sym = expr->symtree->n.sym;
+
+ if (sym->attr.dummy)
+ {
+ sym->attr.proc = PROC_DUMMY;
+ expr->value.function.name = sym->name;
+ goto set_type;
+ }
+
+ /* See if we have an intrinsic function reference. */
+
+ if (gfc_intrinsic_name (sym->name, 0))
+ {
+ if (gfc_intrinsic_func_interface (expr, 1) == MATCH_YES)
+ return SUCCESS;
+ return FAILURE;
+ }
+
+ /* The reference is to an external name. */
+
+ sym->attr.proc = PROC_EXTERNAL;
+ expr->value.function.name = sym->name;
+ expr->value.function.esym = expr->symtree->n.sym;
+
+ if (sym->as != NULL)
+ expr->rank = sym->as->rank;
+
+ /* Type of the expression is either the type of the symbol or the
+ default type of the symbol. */
+
+set_type:
+ gfc_procedure_use (sym, &expr->value.function.actual, &expr->where);
+
+ if (sym->ts.type != BT_UNKNOWN)
+ expr->ts = sym->ts;
+ else
+ {
+ ts = gfc_get_default_type (sym, sym->ns);
+
+ if (ts->type == BT_UNKNOWN)
+ {
+ gfc_error ("Function '%s' at %L has no implicit type",
+ sym->name, &expr->where);
+ return FAILURE;
+ }
+ else
+ expr->ts = *ts;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Figure out if if a function reference is pure or not. Also sets the name
+ of the function for a potential error message. Returns nonzero if the
+ function is PURE, zero if not. */
+
+static int
+pure_function (gfc_expr * e, char **name)
+{
+ int pure;
+
+ if (e->value.function.esym)
+ {
+ pure = gfc_pure (e->value.function.esym);
+ *name = e->value.function.esym->name;
+ }
+ else if (e->value.function.isym)
+ {
+ pure = e->value.function.isym->pure
+ || e->value.function.isym->elemental;
+ *name = e->value.function.isym->name;
+ }
+ else
+ {
+ /* Implicit functions are not pure. */
+ pure = 0;
+ *name = e->value.function.name;
+ }
+
+ return pure;
+}
+
+
+/* Resolve a function call, which means resolving the arguments, then figuring
+ out which entity the name refers to. */
+/* TODO: Check procedure arguments so that an INTENT(IN) isn't passed
+ to INTENT(OUT) or INTENT(INOUT). */
+
+static try
+resolve_function (gfc_expr * expr)
+{
+ gfc_actual_arglist *arg;
+ char *name;
+ try t;
+
+ if (resolve_actual_arglist (expr->value.function.actual) == FAILURE)
+ return FAILURE;
+
+/* See if function is already resolved. */
+
+ if (expr->value.function.name != NULL)
+ {
+ if (expr->ts.type == BT_UNKNOWN)
+ expr->ts = expr->symtree->n.sym->ts;
+ t = SUCCESS;
+ }
+ else
+ {
+ /* Apply the rules of section 14.1.2. */
+
+ switch (procedure_kind (expr->symtree->n.sym))
+ {
+ case PTYPE_GENERIC:
+ t = resolve_generic_f (expr);
+ break;
+
+ case PTYPE_SPECIFIC:
+ t = resolve_specific_f (expr);
+ break;
+
+ case PTYPE_UNKNOWN:
+ t = resolve_unknown_f (expr);
+ break;
+
+ default:
+ gfc_internal_error ("resolve_function(): bad function type");
+ }
+ }
+
+ /* If the expression is still a function (it might have simplified),
+ then we check to see if we are calling an elemental function. */
+
+ if (expr->expr_type != EXPR_FUNCTION)
+ return t;
+
+ if (expr->value.function.actual != NULL
+ && ((expr->value.function.esym != NULL
+ && expr->value.function.esym->attr.elemental)
+ || (expr->value.function.isym != NULL
+ && expr->value.function.isym->elemental)))
+ {
+
+ /* The rank of an elemental is the rank of its array argument(s). */
+
+ for (arg = expr->value.function.actual; arg; arg = arg->next)
+ {
+ if (arg->expr != NULL && arg->expr->rank > 0)
+ {
+ expr->rank = arg->expr->rank;
+ break;
+ }
+ }
+ }
+
+ if (!pure_function (expr, &name))
+ {
+ if (forall_flag)
+ {
+ gfc_error
+ ("Function reference to '%s' at %L is inside a FORALL block",
+ name, &expr->where);
+ t = FAILURE;
+ }
+ else if (gfc_pure (NULL))
+ {
+ gfc_error ("Function reference to '%s' at %L is to a non-PURE "
+ "procedure within a PURE procedure", name, &expr->where);
+ t = FAILURE;
+ }
+ }
+
+ return t;
+}
+
+
+/************* Subroutine resolution *************/
+
+static void
+pure_subroutine (gfc_code * c, gfc_symbol * sym)
+{
+
+ if (gfc_pure (sym))
+ return;
+
+ if (forall_flag)
+ gfc_error ("Subroutine call to '%s' in FORALL block at %L is not PURE",
+ sym->name, &c->loc);
+ else if (gfc_pure (NULL))
+ gfc_error ("Subroutine call to '%s' at %L is not PURE", sym->name,
+ &c->loc);
+}
+
+
+static match
+resolve_generic_s0 (gfc_code * c, gfc_symbol * sym)
+{
+ gfc_symbol *s;
+
+ if (sym->attr.generic)
+ {
+ s = gfc_search_interface (sym->generic, 1, &c->ext.actual);
+ if (s != NULL)
+ {
+ c->resolved_sym = s;
+ pure_subroutine (c, s);
+ return MATCH_YES;
+ }
+
+ /* TODO: Need to search for elemental references in generic interface. */
+ }
+
+ if (sym->attr.intrinsic)
+ return gfc_intrinsic_sub_interface (c, 0);
+
+ return MATCH_NO;
+}
+
+
+static try
+resolve_generic_s (gfc_code * c)
+{
+ gfc_symbol *sym;
+ match m;
+
+ sym = c->symtree->n.sym;
+
+ m = resolve_generic_s0 (c, sym);
+ if (m == MATCH_YES)
+ return SUCCESS;
+ if (m == MATCH_ERROR)
+ return FAILURE;
+
+ if (sym->ns->parent != NULL)
+ {
+ gfc_find_symbol (sym->name, sym->ns->parent, 1, &sym);
+ if (sym != NULL)
+ {
+ m = resolve_generic_s0 (c, sym);
+ if (m == MATCH_YES)
+ return SUCCESS;
+ if (m == MATCH_ERROR)
+ return FAILURE;
+ }
+ }
+
+ /* Last ditch attempt. */
+
+ if (!gfc_generic_intrinsic (sym->name))
+ {
+ gfc_error
+ ("Generic subroutine '%s' at %L is not an intrinsic subroutine",
+ sym->name, &c->loc);
+ return FAILURE;
+ }
+
+ m = gfc_intrinsic_sub_interface (c, 0);
+ if (m == MATCH_YES)
+ return SUCCESS;
+ if (m == MATCH_NO)
+ gfc_error ("Generic subroutine '%s' at %L is not consistent with an "
+ "intrinsic subroutine interface", sym->name, &c->loc);
+
+ return FAILURE;
+}
+
+
+/* Resolve a subroutine call known to be specific. */
+
+static match
+resolve_specific_s0 (gfc_code * c, gfc_symbol * sym)
+{
+ match m;
+
+ if (sym->attr.external || sym->attr.if_source == IFSRC_IFBODY)
+ {
+ if (sym->attr.dummy)
+ {
+ sym->attr.proc = PROC_DUMMY;
+ goto found;
+ }
+
+ sym->attr.proc = PROC_EXTERNAL;
+ goto found;
+ }
+
+ if (sym->attr.proc == PROC_MODULE || sym->attr.proc == PROC_INTERNAL)
+ goto found;
+
+ if (sym->attr.intrinsic)
+ {
+ m = gfc_intrinsic_sub_interface (c, 1);
+ if (m == MATCH_YES)
+ return MATCH_YES;
+ if (m == MATCH_NO)
+ gfc_error ("Subroutine '%s' at %L is INTRINSIC but is not compatible "
+ "with an intrinsic", sym->name, &c->loc);
+
+ return MATCH_ERROR;
+ }
+
+ return MATCH_NO;
+
+found:
+ gfc_procedure_use (sym, &c->ext.actual, &c->loc);
+
+ c->resolved_sym = sym;
+ pure_subroutine (c, sym);
+
+ return MATCH_YES;
+}
+
+
+static try
+resolve_specific_s (gfc_code * c)
+{
+ gfc_symbol *sym;
+ match m;
+
+ sym = c->symtree->n.sym;
+
+ m = resolve_specific_s0 (c, sym);
+ if (m == MATCH_YES)
+ return SUCCESS;
+ if (m == MATCH_ERROR)
+ return FAILURE;
+
+ gfc_find_symbol (sym->name, sym->ns->parent, 1, &sym);
+
+ if (sym != NULL)
+ {
+ m = resolve_specific_s0 (c, sym);
+ if (m == MATCH_YES)
+ return SUCCESS;
+ if (m == MATCH_ERROR)
+ return FAILURE;
+ }
+
+ gfc_error ("Unable to resolve the specific subroutine '%s' at %L",
+ sym->name, &c->loc);
+
+ return FAILURE;
+}
+
+
+/* Resolve a subroutine call not known to be generic nor specific. */
+
+static try
+resolve_unknown_s (gfc_code * c)
+{
+ gfc_symbol *sym;
+
+ sym = c->symtree->n.sym;
+
+ if (sym->attr.dummy)
+ {
+ sym->attr.proc = PROC_DUMMY;
+ goto found;
+ }
+
+ /* See if we have an intrinsic function reference. */
+
+ if (gfc_intrinsic_name (sym->name, 1))
+ {
+ if (gfc_intrinsic_sub_interface (c, 1) == MATCH_YES)
+ return SUCCESS;
+ return FAILURE;
+ }
+
+ /* The reference is to an external name. */
+
+found:
+ gfc_procedure_use (sym, &c->ext.actual, &c->loc);
+
+ c->resolved_sym = sym;
+
+ pure_subroutine (c, sym);
+
+ return SUCCESS;
+}
+
+
+/* Resolve a subroutine call. Although it was tempting to use the same code
+ for functions, subroutines and functions are stored differently and this
+ makes things awkward. */
+
+static try
+resolve_call (gfc_code * c)
+{
+ try t;
+
+ if (resolve_actual_arglist (c->ext.actual) == FAILURE)
+ return FAILURE;
+
+ if (c->resolved_sym != NULL)
+ return SUCCESS;
+
+ switch (procedure_kind (c->symtree->n.sym))
+ {
+ case PTYPE_GENERIC:
+ t = resolve_generic_s (c);
+ break;
+
+ case PTYPE_SPECIFIC:
+ t = resolve_specific_s (c);
+ break;
+
+ case PTYPE_UNKNOWN:
+ t = resolve_unknown_s (c);
+ break;
+
+ default:
+ gfc_internal_error ("resolve_subroutine(): bad function type");
+ }
+
+ return t;
+}
+
+
+/* Resolve an operator expression node. This can involve replacing the
+ operation with a user defined function call. */
+
+static try
+resolve_operator (gfc_expr * e)
+{
+ gfc_expr *op1, *op2;
+ char msg[200];
+ try t;
+
+ /* Resolve all subnodes-- give them types. */
+
+ switch (e->operator)
+ {
+ default:
+ if (gfc_resolve_expr (e->op2) == FAILURE)
+ return FAILURE;
+
+ /* Fall through... */
+
+ case INTRINSIC_NOT:
+ case INTRINSIC_UPLUS:
+ case INTRINSIC_UMINUS:
+ if (gfc_resolve_expr (e->op1) == FAILURE)
+ return FAILURE;
+ break;
+ }
+
+ /* Typecheck the new node. */
+
+ op1 = e->op1;
+ op2 = e->op2;
+
+ switch (e->operator)
+ {
+ case INTRINSIC_UPLUS:
+ case INTRINSIC_UMINUS:
+ if (op1->ts.type == BT_INTEGER
+ || op1->ts.type == BT_REAL
+ || op1->ts.type == BT_COMPLEX)
+ {
+ e->ts = op1->ts;
+ break;
+ }
+
+ sprintf (msg, "Operand of unary numeric operator '%s' at %%L is %s",
+ gfc_op2string (e->operator), gfc_typename (&e->ts));
+ goto bad_op;
+
+ case INTRINSIC_PLUS:
+ case INTRINSIC_MINUS:
+ case INTRINSIC_TIMES:
+ case INTRINSIC_DIVIDE:
+ case INTRINSIC_POWER:
+ if (gfc_numeric_ts (&op1->ts) && gfc_numeric_ts (&op2->ts))
+ {
+ gfc_type_convert_binary (e);
+ break;
+ }
+
+ sprintf (msg,
+ "Operands of binary numeric operator '%s' at %%L are %s/%s",
+ gfc_op2string (e->operator), gfc_typename (&op1->ts),
+ gfc_typename (&op2->ts));
+ goto bad_op;
+
+ case INTRINSIC_CONCAT:
+ if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER)
+ {
+ e->ts.type = BT_CHARACTER;
+ e->ts.kind = op1->ts.kind;
+ break;
+ }
+
+ sprintf (msg,
+ "Operands of string concatenation operator at %%L are %s/%s",
+ gfc_typename (&op1->ts), gfc_typename (&op2->ts));
+ goto bad_op;
+
+ case INTRINSIC_AND:
+ case INTRINSIC_OR:
+ case INTRINSIC_EQV:
+ case INTRINSIC_NEQV:
+ if (op1->ts.type == BT_LOGICAL && op2->ts.type == BT_LOGICAL)
+ {
+ e->ts.type = BT_LOGICAL;
+ e->ts.kind = gfc_kind_max (op1, op2);
+ if (op1->ts.kind < e->ts.kind)
+ gfc_convert_type (op1, &e->ts, 2);
+ else if (op2->ts.kind < e->ts.kind)
+ gfc_convert_type (op2, &e->ts, 2);
+ break;
+ }
+
+ sprintf (msg, "Operands of logical operator '%s' at %%L are %s/%s",
+ gfc_op2string (e->operator), gfc_typename (&op1->ts),
+ gfc_typename (&op2->ts));
+
+ goto bad_op;
+
+ case INTRINSIC_NOT:
+ if (op1->ts.type == BT_LOGICAL)
+ {
+ e->ts.type = BT_LOGICAL;
+ e->ts.kind = op1->ts.kind;
+ break;
+ }
+
+ sprintf (msg, "Operand of .NOT. operator at %%L is %s",
+ gfc_typename (&op1->ts));
+ goto bad_op;
+
+ case INTRINSIC_GT:
+ case INTRINSIC_GE:
+ case INTRINSIC_LT:
+ case INTRINSIC_LE:
+ if (op1->ts.type == BT_COMPLEX || op2->ts.type == BT_COMPLEX)
+ {
+ strcpy (msg, "COMPLEX quantities cannot be compared at %L");
+ goto bad_op;
+ }
+
+ /* Fall through... */
+
+ case INTRINSIC_EQ:
+ case INTRINSIC_NE:
+ if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER)
+ {
+ e->ts.type = BT_LOGICAL;
+ e->ts.kind = gfc_default_logical_kind ();
+ break;
+ }
+
+ if (gfc_numeric_ts (&op1->ts) && gfc_numeric_ts (&op2->ts))
+ {
+ gfc_type_convert_binary (e);
+
+ e->ts.type = BT_LOGICAL;
+ e->ts.kind = gfc_default_logical_kind ();
+ break;
+ }
+
+ sprintf (msg, "Operands of comparison operator '%s' at %%L are %s/%s",
+ gfc_op2string (e->operator), gfc_typename (&op1->ts),
+ gfc_typename (&op2->ts));
+
+ goto bad_op;
+
+ case INTRINSIC_USER:
+ if (op2 == NULL)
+ sprintf (msg, "Operand of user operator '%s' at %%L is %s",
+ e->uop->ns->proc_name->name, gfc_typename (&op1->ts));
+ else
+ sprintf (msg, "Operands of user operator '%s' at %%L are %s/%s",
+ e->uop->ns->proc_name->name, gfc_typename (&op1->ts),
+ gfc_typename (&op2->ts));
+
+ goto bad_op;
+
+ default:
+ gfc_internal_error ("resolve_operator(): Bad intrinsic");
+ }
+
+ /* Deal with arrayness of an operand through an operator. */
+
+ t = SUCCESS;
+
+ switch (e->operator)
+ {
+ case INTRINSIC_PLUS:
+ case INTRINSIC_MINUS:
+ case INTRINSIC_TIMES:
+ case INTRINSIC_DIVIDE:
+ case INTRINSIC_POWER:
+ case INTRINSIC_CONCAT:
+ case INTRINSIC_AND:
+ case INTRINSIC_OR:
+ case INTRINSIC_EQV:
+ case INTRINSIC_NEQV:
+ case INTRINSIC_EQ:
+ case INTRINSIC_NE:
+ case INTRINSIC_GT:
+ case INTRINSIC_GE:
+ case INTRINSIC_LT:
+ case INTRINSIC_LE:
+
+ if (op1->rank == 0 && op2->rank == 0)
+ e->rank = 0;
+
+ if (op1->rank == 0 && op2->rank != 0)
+ {
+ e->rank = op2->rank;
+
+ if (e->shape == NULL)
+ e->shape = gfc_copy_shape (op2->shape, op2->rank);
+ }
+
+ if (op1->rank != 0 && op2->rank == 0)
+ {
+ e->rank = op1->rank;
+
+ if (e->shape == NULL)
+ e->shape = gfc_copy_shape (op1->shape, op1->rank);
+ }
+
+ if (op1->rank != 0 && op2->rank != 0)
+ {
+ if (op1->rank == op2->rank)
+ {
+ e->rank = op1->rank;
+
+ if (e->shape == NULL)
+ e->shape = gfc_copy_shape (op1->shape, op1->rank);
+
+ }
+ else
+ {
+ gfc_error ("Inconsistent ranks for operator at %L and %L",
+ &op1->where, &op2->where);
+ t = FAILURE;
+
+ /* Allow higher level expressions to work. */
+ e->rank = 0;
+ }
+ }
+
+ break;
+
+ case INTRINSIC_NOT:
+ case INTRINSIC_UPLUS:
+ case INTRINSIC_UMINUS:
+ e->rank = op1->rank;
+
+ if (e->shape == NULL)
+ e->shape = gfc_copy_shape (op1->shape, op1->rank);
+
+ /* Simply copy arrayness attribute */
+ break;
+
+ default:
+ break;
+ }
+
+ /* Attempt to simplify the expression. */
+ if (t == SUCCESS)
+ t = gfc_simplify_expr (e, 0);
+ return t;
+
+bad_op:
+ if (gfc_extend_expr (e) == SUCCESS)
+ return SUCCESS;
+
+ gfc_error (msg, &e->where);
+ return FAILURE;
+}
+
+
+/************** Array resolution subroutines **************/
+
+
+typedef enum
+{ CMP_LT, CMP_EQ, CMP_GT, CMP_UNKNOWN }
+comparison;
+
+/* Compare two integer expressions. */
+
+static comparison
+compare_bound (gfc_expr * a, gfc_expr * b)
+{
+ int i;
+
+ if (a == NULL || a->expr_type != EXPR_CONSTANT
+ || b == NULL || b->expr_type != EXPR_CONSTANT)
+ return CMP_UNKNOWN;
+
+ if (a->ts.type != BT_INTEGER || b->ts.type != BT_INTEGER)
+ gfc_internal_error ("compare_bound(): Bad expression");
+
+ i = mpz_cmp (a->value.integer, b->value.integer);
+
+ if (i < 0)
+ return CMP_LT;
+ if (i > 0)
+ return CMP_GT;
+ return CMP_EQ;
+}
+
+
+/* Compare an integer expression with an integer. */
+
+static comparison
+compare_bound_int (gfc_expr * a, int b)
+{
+ int i;
+
+ if (a == NULL || a->expr_type != EXPR_CONSTANT)
+ return CMP_UNKNOWN;
+
+ if (a->ts.type != BT_INTEGER)
+ gfc_internal_error ("compare_bound_int(): Bad expression");
+
+ i = mpz_cmp_si (a->value.integer, b);
+
+ if (i < 0)
+ return CMP_LT;
+ if (i > 0)
+ return CMP_GT;
+ return CMP_EQ;
+}
+
+
+/* Compare a single dimension of an array reference to the array
+ specification. */
+
+static try
+check_dimension (int i, gfc_array_ref * ar, gfc_array_spec * as)
+{
+
+/* Given start, end and stride values, calculate the minimum and
+ maximum referenced indexes. */
+
+ switch (ar->type)
+ {
+ case AR_FULL:
+ break;
+
+ case AR_ELEMENT:
+ if (compare_bound (ar->start[i], as->lower[i]) == CMP_LT)
+ goto bound;
+ if (compare_bound (ar->start[i], as->upper[i]) == CMP_GT)
+ goto bound;
+
+ break;
+
+ case AR_SECTION:
+ if (compare_bound_int (ar->stride[i], 0) == CMP_EQ)
+ {
+ gfc_error ("Illegal stride of zero at %L", &ar->c_where[i]);
+ return FAILURE;
+ }
+
+ if (compare_bound (ar->start[i], as->lower[i]) == CMP_LT)
+ goto bound;
+ if (compare_bound (ar->start[i], as->upper[i]) == CMP_GT)
+ goto bound;
+
+ /* TODO: Possibly, we could warn about end[i] being out-of-bound although
+ it is legal (see 6.2.2.3.1). */
+
+ break;
+
+ default:
+ gfc_internal_error ("check_dimension(): Bad array reference");
+ }
+
+ return SUCCESS;
+
+bound:
+ gfc_warning ("Array reference at %L is out of bounds", &ar->c_where[i]);
+ return SUCCESS;
+}
+
+
+/* Compare an array reference with an array specification. */
+
+static try
+compare_spec_to_ref (gfc_array_ref * ar)
+{
+ gfc_array_spec *as;
+ int i;
+
+ as = ar->as;
+ i = as->rank - 1;
+ /* TODO: Full array sections are only allowed as actual parameters. */
+ if (as->type == AS_ASSUMED_SIZE
+ && (/*ar->type == AR_FULL
+ ||*/ (ar->type == AR_SECTION
+ && ar->dimen_type[i] == DIMEN_RANGE && ar->end[i] == NULL)))
+ {
+ gfc_error ("Rightmost upper bound of assumed size array section"
+ " not specified at %L", &ar->where);
+ return FAILURE;
+ }
+
+ if (ar->type == AR_FULL)
+ return SUCCESS;
+
+ if (as->rank != ar->dimen)
+ {
+ gfc_error ("Rank mismatch in array reference at %L (%d/%d)",
+ &ar->where, ar->dimen, as->rank);
+ return FAILURE;
+ }
+
+ for (i = 0; i < as->rank; i++)
+ if (check_dimension (i, ar, as) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+/* Resolve one part of an array index. */
+
+try
+gfc_resolve_index (gfc_expr * index, int check_scalar)
+{
+ gfc_typespec ts;
+
+ if (index == NULL)
+ return SUCCESS;
+
+ if (gfc_resolve_expr (index) == FAILURE)
+ return FAILURE;
+
+ if (index->ts.type != BT_INTEGER)
+ {
+ gfc_error ("Array index at %L must be of INTEGER type", &index->where);
+ return FAILURE;
+ }
+
+ if (check_scalar && index->rank != 0)
+ {
+ gfc_error ("Array index at %L must be scalar", &index->where);
+ return FAILURE;
+ }
+
+ if (index->ts.kind != gfc_index_integer_kind)
+ {
+ ts.type = BT_INTEGER;
+ ts.kind = gfc_index_integer_kind;
+
+ gfc_convert_type_warn (index, &ts, 2, 0);
+ }
+
+ return SUCCESS;
+}
+
+
+/* Given an expression that contains array references, update those array
+ references to point to the right array specifications. While this is
+ filled in during matching, this information is difficult to save and load
+ in a module, so we take care of it here.
+
+ The idea here is that the original array reference comes from the
+ base symbol. We traverse the list of reference structures, setting
+ the stored reference to references. Component references can
+ provide an additional array specification. */
+
+static void
+find_array_spec (gfc_expr * e)
+{
+ gfc_array_spec *as;
+ gfc_component *c;
+ gfc_ref *ref;
+
+ as = e->symtree->n.sym->as;
+ c = e->symtree->n.sym->components;
+
+ for (ref = e->ref; ref; ref = ref->next)
+ switch (ref->type)
+ {
+ case REF_ARRAY:
+ if (as == NULL)
+ gfc_internal_error ("find_array_spec(): Missing spec");
+
+ ref->u.ar.as = as;
+ as = NULL;
+ break;
+
+ case REF_COMPONENT:
+ for (; c; c = c->next)
+ if (c == ref->u.c.component)
+ break;
+
+ if (c == NULL)
+ gfc_internal_error ("find_array_spec(): Component not found");
+
+ if (c->dimension)
+ {
+ if (as != NULL)
+ gfc_internal_error ("find_array_spec(): unused as(1)");
+ as = c->as;
+ }
+
+ c = c->ts.derived->components;
+ break;
+
+ case REF_SUBSTRING:
+ break;
+ }
+
+ if (as != NULL)
+ gfc_internal_error ("find_array_spec(): unused as(2)");
+}
+
+
+/* Resolve an array reference. */
+
+static try
+resolve_array_ref (gfc_array_ref * ar)
+{
+ int i, check_scalar;
+
+ for (i = 0; i < ar->dimen; i++)
+ {
+ check_scalar = ar->dimen_type[i] == DIMEN_RANGE;
+
+ if (gfc_resolve_index (ar->start[i], check_scalar) == FAILURE)
+ return FAILURE;
+ if (gfc_resolve_index (ar->end[i], check_scalar) == FAILURE)
+ return FAILURE;
+ if (gfc_resolve_index (ar->stride[i], check_scalar) == FAILURE)
+ return FAILURE;
+
+ if (ar->dimen_type[i] == DIMEN_UNKNOWN)
+ switch (ar->start[i]->rank)
+ {
+ case 0:
+ ar->dimen_type[i] = DIMEN_ELEMENT;
+ break;
+
+ case 1:
+ ar->dimen_type[i] = DIMEN_VECTOR;
+ break;
+
+ default:
+ gfc_error ("Array index at %L is an array of rank %d",
+ &ar->c_where[i], ar->start[i]->rank);
+ return FAILURE;
+ }
+ }
+
+ /* If the reference type is unknown, figure out what kind it is. */
+
+ if (ar->type == AR_UNKNOWN)
+ {
+ ar->type = AR_ELEMENT;
+ for (i = 0; i < ar->dimen; i++)
+ if (ar->dimen_type[i] == DIMEN_RANGE
+ || ar->dimen_type[i] == DIMEN_VECTOR)
+ {
+ ar->type = AR_SECTION;
+ break;
+ }
+ }
+
+ if (compare_spec_to_ref (ar) == FAILURE)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+static try
+resolve_substring (gfc_ref * ref)
+{
+
+ if (ref->u.ss.start != NULL)
+ {
+ if (gfc_resolve_expr (ref->u.ss.start) == FAILURE)
+ return FAILURE;
+
+ if (ref->u.ss.start->ts.type != BT_INTEGER)
+ {
+ gfc_error ("Substring start index at %L must be of type INTEGER",
+ &ref->u.ss.start->where);
+ return FAILURE;
+ }
+
+ if (ref->u.ss.start->rank != 0)
+ {
+ gfc_error ("Substring start index at %L must be scalar",
+ &ref->u.ss.start->where);
+ return FAILURE;
+ }
+
+ if (compare_bound_int (ref->u.ss.start, 1) == CMP_LT)
+ {
+ gfc_error ("Substring start index at %L is less than one",
+ &ref->u.ss.start->where);
+ return FAILURE;
+ }
+ }
+
+ if (ref->u.ss.end != NULL)
+ {
+ if (gfc_resolve_expr (ref->u.ss.end) == FAILURE)
+ return FAILURE;
+
+ if (ref->u.ss.end->ts.type != BT_INTEGER)
+ {
+ gfc_error ("Substring end index at %L must be of type INTEGER",
+ &ref->u.ss.end->where);
+ return FAILURE;
+ }
+
+ if (ref->u.ss.end->rank != 0)
+ {
+ gfc_error ("Substring end index at %L must be scalar",
+ &ref->u.ss.end->where);
+ return FAILURE;
+ }
+
+ if (ref->u.ss.length != NULL
+ && compare_bound (ref->u.ss.end, ref->u.ss.length->length) == CMP_GT)
+ {
+ gfc_error ("Substring end index at %L is out of bounds",
+ &ref->u.ss.start->where);
+ return FAILURE;
+ }
+ }
+
+ return SUCCESS;
+}
+
+
+/* Resolve subtype references. */
+
+static try
+resolve_ref (gfc_expr * expr)
+{
+ int current_part_dimension, n_components, seen_part_dimension;
+ gfc_ref *ref;
+
+ for (ref = expr->ref; ref; ref = ref->next)
+ if (ref->type == REF_ARRAY && ref->u.ar.as == NULL)
+ {
+ find_array_spec (expr);
+ break;
+ }
+
+ for (ref = expr->ref; ref; ref = ref->next)
+ switch (ref->type)
+ {
+ case REF_ARRAY:
+ if (resolve_array_ref (&ref->u.ar) == FAILURE)
+ return FAILURE;
+ break;
+
+ case REF_COMPONENT:
+ break;
+
+ case REF_SUBSTRING:
+ resolve_substring (ref);
+ break;
+ }
+
+ /* Check constraints on part references. */
+
+ current_part_dimension = 0;
+ seen_part_dimension = 0;
+ n_components = 0;
+
+ for (ref = expr->ref; ref; ref = ref->next)
+ {
+ switch (ref->type)
+ {
+ case REF_ARRAY:
+ switch (ref->u.ar.type)
+ {
+ case AR_FULL:
+ case AR_SECTION:
+ current_part_dimension = 1;
+ break;
+
+ case AR_ELEMENT:
+ current_part_dimension = 0;
+ break;
+
+ case AR_UNKNOWN:
+ gfc_internal_error ("resolve_ref(): Bad array reference");
+ }
+
+ break;
+
+ case REF_COMPONENT:
+ if ((current_part_dimension || seen_part_dimension)
+ && ref->u.c.component->pointer)
+ {
+ gfc_error
+ ("Component to the right of a part reference with nonzero "
+ "rank must not have the POINTER attribute at %L",
+ &expr->where);
+ return FAILURE;
+ }
+
+ n_components++;
+ break;
+
+ case REF_SUBSTRING:
+ break;
+ }
+
+ if (((ref->type == REF_COMPONENT && n_components > 1)
+ || ref->next == NULL)
+ && current_part_dimension
+ && seen_part_dimension)
+ {
+
+ gfc_error ("Two or more part references with nonzero rank must "
+ "not be specified at %L", &expr->where);
+ return FAILURE;
+ }
+
+ if (ref->type == REF_COMPONENT)
+ {
+ if (current_part_dimension)
+ seen_part_dimension = 1;
+
+ /* reset to make sure */
+ current_part_dimension = 0;
+ }
+ }
+
+ return SUCCESS;
+}
+
+
+/* Given an expression, determine its shape. This is easier than it sounds.
+ Leaves the shape array NULL if it is not possible to determine the shape. */
+
+static void
+expression_shape (gfc_expr * e)
+{
+ mpz_t array[GFC_MAX_DIMENSIONS];
+ int i;
+
+ if (e->rank == 0 || e->shape != NULL)
+ return;
+
+ for (i = 0; i < e->rank; i++)
+ if (gfc_array_dimen_size (e, i, &array[i]) == FAILURE)
+ goto fail;
+
+ e->shape = gfc_get_shape (e->rank);
+
+ memcpy (e->shape, array, e->rank * sizeof (mpz_t));
+
+ return;
+
+fail:
+ for (i--; i >= 0; i--)
+ mpz_clear (array[i]);
+}
+
+
+/* Given a variable expression node, compute the rank of the expression by
+ examining the base symbol and any reference structures it may have. */
+
+static void
+expression_rank (gfc_expr * e)
+{
+ gfc_ref *ref;
+ int i, rank;
+
+ if (e->ref == NULL)
+ {
+ if (e->expr_type == EXPR_ARRAY)
+ goto done;
+ /* Constructors can have a rank different from one via RESHAPE(). */
+
+ if (e->symtree == NULL)
+ {
+ e->rank = 0;
+ goto done;
+ }
+
+ e->rank = (e->symtree->n.sym->as == NULL)
+ ? 0 : e->symtree->n.sym->as->rank;
+ goto done;
+ }
+
+ rank = 0;
+
+ for (ref = e->ref; ref; ref = ref->next)
+ {
+ if (ref->type != REF_ARRAY)
+ continue;
+
+ if (ref->u.ar.type == AR_FULL)
+ {
+ rank = ref->u.ar.as->rank;
+ break;
+ }
+
+ if (ref->u.ar.type == AR_SECTION)
+ {
+ /* Figure out the rank of the section. */
+ if (rank != 0)
+ gfc_internal_error ("expression_rank(): Two array specs");
+
+ for (i = 0; i < ref->u.ar.dimen; i++)
+ if (ref->u.ar.dimen_type[i] == DIMEN_RANGE
+ || ref->u.ar.dimen_type[i] == DIMEN_VECTOR)
+ rank++;
+
+ break;
+ }
+ }
+
+ e->rank = rank;
+
+done:
+ expression_shape (e);
+}
+
+
+/* Resolve a variable expression. */
+
+static try
+resolve_variable (gfc_expr * e)
+{
+ gfc_symbol *sym;
+
+ if (e->ref && resolve_ref (e) == FAILURE)
+ return FAILURE;
+
+ sym = e->symtree->n.sym;
+ if (sym->attr.flavor == FL_PROCEDURE && !sym->attr.function)
+ {
+ e->ts.type = BT_PROCEDURE;
+ return SUCCESS;
+ }
+
+ if (sym->ts.type != BT_UNKNOWN)
+ gfc_variable_attr (e, &e->ts);
+ else
+ {
+ /* Must be a simple variable reference. */
+ if (gfc_set_default_type (sym, 1, NULL) == FAILURE)
+ return FAILURE;
+ e->ts = sym->ts;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Resolve an expression. That is, make sure that types of operands agree
+ with their operators, intrinsic operators are converted to function calls
+ for overloaded types and unresolved function references are resolved. */
+
+try
+gfc_resolve_expr (gfc_expr * e)
+{
+ try t;
+
+ if (e == NULL)
+ return SUCCESS;
+
+ switch (e->expr_type)
+ {
+ case EXPR_OP:
+ t = resolve_operator (e);
+ break;
+
+ case EXPR_FUNCTION:
+ t = resolve_function (e);
+ break;
+
+ case EXPR_VARIABLE:
+ t = resolve_variable (e);
+ if (t == SUCCESS)
+ expression_rank (e);
+ break;
+
+ case EXPR_SUBSTRING:
+ t = resolve_ref (e);
+ break;
+
+ case EXPR_CONSTANT:
+ case EXPR_NULL:
+ t = SUCCESS;
+ break;
+
+ case EXPR_ARRAY:
+ t = FAILURE;
+ if (resolve_ref (e) == FAILURE)
+ break;
+
+ t = gfc_resolve_array_constructor (e);
+ /* Also try to expand a constructor. */
+ if (t == SUCCESS)
+ {
+ expression_rank (e);
+ gfc_expand_constructor (e);
+ }
+
+ break;
+
+ case EXPR_STRUCTURE:
+ t = resolve_ref (e);
+ if (t == FAILURE)
+ break;
+
+ t = resolve_structure_cons (e);
+ if (t == FAILURE)
+ break;
+
+ t = gfc_simplify_expr (e, 0);
+ break;
+
+ default:
+ gfc_internal_error ("gfc_resolve_expr(): Bad expression type");
+ }
+
+ return t;
+}
+
+
+/* Resolve the expressions in an iterator structure and require that they all
+ be of integer type. */
+
+try
+gfc_resolve_iterator (gfc_iterator * iter)
+{
+
+ if (gfc_resolve_expr (iter->var) == FAILURE)
+ return FAILURE;
+
+ if (iter->var->ts.type != BT_INTEGER || iter->var->rank != 0)
+ {
+ gfc_error ("Loop variable at %L must be a scalar INTEGER",
+ &iter->var->where);
+ return FAILURE;
+ }
+
+ if (gfc_pure (NULL) && gfc_impure_variable (iter->var->symtree->n.sym))
+ {
+ gfc_error ("Cannot assign to loop variable in PURE procedure at %L",
+ &iter->var->where);
+ return FAILURE;
+ }
+
+ if (gfc_resolve_expr (iter->start) == FAILURE)
+ return FAILURE;
+
+ if (iter->start->ts.type != BT_INTEGER || iter->start->rank != 0)
+ {
+ gfc_error ("Start expression in DO loop at %L must be a scalar INTEGER",
+ &iter->start->where);
+ return FAILURE;
+ }
+
+ if (gfc_resolve_expr (iter->end) == FAILURE)
+ return FAILURE;
+
+ if (iter->end->ts.type != BT_INTEGER || iter->end->rank != 0)
+ {
+ gfc_error ("End expression in DO loop at %L must be a scalar INTEGER",
+ &iter->end->where);
+ return FAILURE;
+ }
+
+ if (gfc_resolve_expr (iter->step) == FAILURE)
+ return FAILURE;
+
+ if (iter->step->ts.type != BT_INTEGER || iter->step->rank != 0)
+ {
+ gfc_error ("Step expression in DO loop at %L must be a scalar INTEGER",
+ &iter->step->where);
+ return FAILURE;
+ }
+
+ if (iter->step->expr_type == EXPR_CONSTANT
+ && mpz_cmp_ui (iter->step->value.integer, 0) == 0)
+ {
+ gfc_error ("Step expression in DO loop at %L cannot be zero",
+ &iter->step->where);
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Resolve a list of FORALL iterators. */
+
+static void
+resolve_forall_iterators (gfc_forall_iterator * iter)
+{
+
+ while (iter)
+ {
+ if (gfc_resolve_expr (iter->var) == SUCCESS
+ && iter->var->ts.type != BT_INTEGER)
+ gfc_error ("FORALL Iteration variable at %L must be INTEGER",
+ &iter->var->where);
+
+ if (gfc_resolve_expr (iter->start) == SUCCESS
+ && iter->start->ts.type != BT_INTEGER)
+ gfc_error ("FORALL start expression at %L must be INTEGER",
+ &iter->start->where);
+ if (iter->var->ts.kind != iter->start->ts.kind)
+ gfc_convert_type (iter->start, &iter->var->ts, 2);
+
+ if (gfc_resolve_expr (iter->end) == SUCCESS
+ && iter->end->ts.type != BT_INTEGER)
+ gfc_error ("FORALL end expression at %L must be INTEGER",
+ &iter->end->where);
+ if (iter->var->ts.kind != iter->end->ts.kind)
+ gfc_convert_type (iter->end, &iter->var->ts, 2);
+
+ if (gfc_resolve_expr (iter->stride) == SUCCESS
+ && iter->stride->ts.type != BT_INTEGER)
+ gfc_error ("FORALL Stride expression at %L must be INTEGER",
+ &iter->stride->where);
+ if (iter->var->ts.kind != iter->stride->ts.kind)
+ gfc_convert_type (iter->stride, &iter->var->ts, 2);
+
+ iter = iter->next;
+ }
+}
+
+
+/* Given a pointer to a symbol that is a derived type, see if any components
+ have the POINTER attribute. The search is recursive if necessary.
+ Returns zero if no pointer components are found, nonzero otherwise. */
+
+static int
+derived_pointer (gfc_symbol * sym)
+{
+ gfc_component *c;
+
+ for (c = sym->components; c; c = c->next)
+ {
+ if (c->pointer)
+ return 1;
+
+ if (c->ts.type == BT_DERIVED && derived_pointer (c->ts.derived))
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/* Resolve the argument of a deallocate expression. The expression must be
+ a pointer or a full array. */
+
+static try
+resolve_deallocate_expr (gfc_expr * e)
+{
+ symbol_attribute attr;
+ int allocatable;
+ gfc_ref *ref;
+
+ if (gfc_resolve_expr (e) == FAILURE)
+ return FAILURE;
+
+ attr = gfc_expr_attr (e);
+ if (attr.pointer)
+ return SUCCESS;
+
+ if (e->expr_type != EXPR_VARIABLE)
+ goto bad;
+
+ allocatable = e->symtree->n.sym->attr.allocatable;
+ for (ref = e->ref; ref; ref = ref->next)
+ switch (ref->type)
+ {
+ case REF_ARRAY:
+ if (ref->u.ar.type != AR_FULL)
+ allocatable = 0;
+ break;
+
+ case REF_COMPONENT:
+ allocatable = (ref->u.c.component->as != NULL
+ && ref->u.c.component->as->type == AS_DEFERRED);
+ break;
+
+ case REF_SUBSTRING:
+ allocatable = 0;
+ break;
+ }
+
+ if (allocatable == 0)
+ {
+ bad:
+ gfc_error ("Expression in DEALLOCATE statement at %L must be "
+ "ALLOCATABLE or a POINTER", &e->where);
+ }
+
+ return SUCCESS;
+}
+
+
+/* Resolve the expression in an ALLOCATE statement, doing the additional
+ checks to see whether the expression is OK or not. The expression must
+ have a trailing array reference that gives the size of the array. */
+
+static try
+resolve_allocate_expr (gfc_expr * e)
+{
+ int i, pointer, allocatable, dimension;
+ symbol_attribute attr;
+ gfc_ref *ref, *ref2;
+ gfc_array_ref *ar;
+
+ if (gfc_resolve_expr (e) == FAILURE)
+ return FAILURE;
+
+ /* Make sure the expression is allocatable or a pointer. If it is
+ pointer, the next-to-last reference must be a pointer. */
+
+ ref2 = NULL;
+
+ if (e->expr_type != EXPR_VARIABLE)
+ {
+ allocatable = 0;
+
+ attr = gfc_expr_attr (e);
+ pointer = attr.pointer;
+ dimension = attr.dimension;
+
+ }
+ else
+ {
+ allocatable = e->symtree->n.sym->attr.allocatable;
+ pointer = e->symtree->n.sym->attr.pointer;
+ dimension = e->symtree->n.sym->attr.dimension;
+
+ for (ref = e->ref; ref; ref2 = ref, ref = ref->next)
+ switch (ref->type)
+ {
+ case REF_ARRAY:
+ if (ref->next != NULL)
+ pointer = 0;
+ break;
+
+ case REF_COMPONENT:
+ allocatable = (ref->u.c.component->as != NULL
+ && ref->u.c.component->as->type == AS_DEFERRED);
+
+ pointer = ref->u.c.component->pointer;
+ dimension = ref->u.c.component->dimension;
+ break;
+
+ case REF_SUBSTRING:
+ allocatable = 0;
+ pointer = 0;
+ break;
+ }
+ }
+
+ if (allocatable == 0 && pointer == 0)
+ {
+ gfc_error ("Expression in ALLOCATE statement at %L must be "
+ "ALLOCATABLE or a POINTER", &e->where);
+ return FAILURE;
+ }
+
+ if (pointer && dimension == 0)
+ return SUCCESS;
+
+ /* Make sure the next-to-last reference node is an array specification. */
+
+ if (ref2 == NULL || ref2->type != REF_ARRAY || ref2->u.ar.type == AR_FULL)
+ {
+ gfc_error ("Array specification required in ALLOCATE statement "
+ "at %L", &e->where);
+ return FAILURE;
+ }
+
+ if (ref2->u.ar.type == AR_ELEMENT)
+ return SUCCESS;
+
+ /* Make sure that the array section reference makes sense in the
+ context of an ALLOCATE specification. */
+
+ ar = &ref2->u.ar;
+
+ for (i = 0; i < ar->dimen; i++)
+ switch (ar->dimen_type[i])
+ {
+ case DIMEN_ELEMENT:
+ break;
+
+ case DIMEN_RANGE:
+ if (ar->start[i] != NULL
+ && ar->end[i] != NULL
+ && ar->stride[i] == NULL)
+ break;
+
+ /* Fall Through... */
+
+ case DIMEN_UNKNOWN:
+ case DIMEN_VECTOR:
+ gfc_error ("Bad array specification in ALLOCATE statement at %L",
+ &e->where);
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+/************ SELECT CASE resolution subroutines ************/
+
+/* Callback function for our mergesort variant. Determines interval
+ overlaps for CASEs. Return <0 if op1 < op2, 0 for overlap, >0 for
+ op1 > op2. Assumes we're not dealing with the default case. */
+
+static int
+compare_cases (const void * _op1, const void * _op2)
+{
+ const gfc_case *op1, *op2;
+
+ op1 = (const gfc_case *) _op1;
+ op2 = (const gfc_case *) _op2;
+
+ if (op1->low == NULL) /* op1 = (:N) */
+ {
+ if (op2->low == NULL) /* op2 = (:M), so overlap. */
+ return 0;
+
+ else if (op2->high == NULL) /* op2 = (M:) */
+ {
+ if (gfc_compare_expr (op1->high, op2->low) < 0)
+ return -1; /* N < M */
+ else
+ return 0;
+ }
+
+ else /* op2 = (L:M) */
+ {
+ if (gfc_compare_expr (op1->high, op2->low) < 0)
+ return -1; /* N < L */
+ else
+ return 0;
+ }
+ }
+
+ else if (op1->high == NULL) /* op1 = (N:) */
+ {
+ if (op2->low == NULL) /* op2 = (:M) */
+ {
+ if (gfc_compare_expr (op1->low, op2->high) > 0)
+ return 1; /* N > M */
+ else
+ return 0;
+ }
+
+ else if (op2->high == NULL) /* op2 = (M:), so overlap. */
+ return 0;
+
+ else /* op2 = (L:M) */
+ {
+ if (gfc_compare_expr (op1->low, op2->high) > 0)
+ return 1; /* N > M */
+ else
+ return 0;
+ }
+ }
+
+ else /* op1 = (N:P) */
+ {
+ if (op2->low == NULL) /* op2 = (:M) */
+ {
+ if (gfc_compare_expr (op1->low, op2->high) > 0)
+ return 1; /* N > M */
+ else
+ return 0;
+ }
+
+ else if (op2->high == NULL) /* op2 = (M:) */
+ {
+ if (gfc_compare_expr (op1->high, op2->low) < 0)
+ return -1; /* P < M */
+ else
+ return 0;
+ }
+
+ else /* op2 = (L:M) */
+ {
+ if (gfc_compare_expr (op1->high, op2->low) < 0)
+ return -1; /* P < L */
+
+ if (gfc_compare_expr (op1->low, op2->high) > 0)
+ return 1; /* N > M */
+
+ return 0;
+ }
+ }
+}
+
+
+/* Merge-sort a double linked case list, detecting overlap in the
+ process. LIST is the head of the double linked case list before it
+ is sorted. Returns the head of the sorted list if we don't see any
+ overlap, or NULL otherwise. */
+
+static gfc_case *
+check_case_overlap (gfc_case * list)
+{
+ gfc_case *p, *q, *e, *tail;
+ int insize, nmerges, psize, qsize, cmp, overlap_seen;
+
+ /* If the passed list was empty, return immediately. */
+ if (!list)
+ return NULL;
+
+ overlap_seen = 0;
+ insize = 1;
+
+ /* Loop unconditionally. The only exit from this loop is a return
+ statement, when we've finished sorting the case list. */
+ for (;;)
+ {
+ p = list;
+ list = NULL;
+ tail = NULL;
+
+ /* Count the number of merges we do in this pass. */
+ nmerges = 0;
+
+ /* Loop while there exists a merge to be done. */
+ while (p)
+ {
+ int i;
+
+ /* Count this merge. */
+ nmerges++;
+
+ /* Cut the list in two pieces by steppin INSIZE places
+ forward in the list, starting from P. */
+ psize = 0;
+ q = p;
+ for (i = 0; i < insize; i++)
+ {
+ psize++;
+ q = q->right;
+ if (!q)
+ break;
+ }
+ qsize = insize;
+
+ /* Now we have two lists. Merge them! */
+ while (psize > 0 || (qsize > 0 && q != NULL))
+ {
+
+ /* See from which the next case to merge comes from. */
+ if (psize == 0)
+ {
+ /* P is empty so the next case must come from Q. */
+ e = q;
+ q = q->right;
+ qsize--;
+ }
+ else if (qsize == 0 || q == NULL)
+ {
+ /* Q is empty. */
+ e = p;
+ p = p->right;
+ psize--;
+ }
+ else
+ {
+ cmp = compare_cases (p, q);
+ if (cmp < 0)
+ {
+ /* The whole case range for P is less than the
+ one for Q. */
+ e = p;
+ p = p->right;
+ psize--;
+ }
+ else if (cmp > 0)
+ {
+ /* The whole case range for Q is greater than
+ the case range for P. */
+ e = q;
+ q = q->right;
+ qsize--;
+ }
+ else
+ {
+ /* The cases overlap, or they are the same
+ element in the list. Either way, we must
+ issue an error and get the next case from P. */
+ /* FIXME: Sort P and Q by line number. */
+ gfc_error ("CASE label at %L overlaps with CASE "
+ "label at %L", &p->where, &q->where);
+ overlap_seen = 1;
+ e = p;
+ p = p->right;
+ psize--;
+ }
+ }
+
+ /* Add the next element to the merged list. */
+ if (tail)
+ tail->right = e;
+ else
+ list = e;
+ e->left = tail;
+ tail = e;
+ }
+
+ /* P has now stepped INSIZE places along, and so has Q. So
+ they're the same. */
+ p = q;
+ }
+ tail->right = NULL;
+
+ /* If we have done only one merge or none at all, we've
+ finished sorting the cases. */
+ if (nmerges <= 1)
+ {
+ if (!overlap_seen)
+ return list;
+ else
+ return NULL;
+ }
+
+ /* Otherwise repeat, merging lists twice the size. */
+ insize *= 2;
+ }
+}
+
+
+/* Check to see if an expression is suitable for use in a CASE
+ statement. Makes sure that all case expressions are scalar
+ constants of the same type/kind. Return FAILURE if anything
+ is wrong. */
+
+static try
+validate_case_label_expr (gfc_expr * e, gfc_expr * case_expr)
+{
+ gfc_typespec case_ts = case_expr->ts;
+
+ if (e == NULL) return SUCCESS;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ {
+ gfc_error ("Expression in CASE statement at %L must be a constant",
+ &e->where);
+ return FAILURE;
+ }
+
+ if (e->ts.type != case_ts.type)
+ {
+ gfc_error ("Expression in CASE statement at %L must be of type %s",
+ &e->where, gfc_basic_typename (case_ts.type));
+ return FAILURE;
+ }
+
+ if (e->ts.kind != case_ts.kind)
+ {
+ gfc_error("Expression in CASE statement at %L must be kind %d",
+ &e->where, case_ts.kind);
+ return FAILURE;
+ }
+
+ if (e->rank != 0)
+ {
+ gfc_error ("Expression in CASE statement at %L must be scalar",
+ &e->where);
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Given a completely parsed select statement, we:
+
+ - Validate all expressions and code within the SELECT.
+ - Make sure that the selection expression is not of the wrong type.
+ - Make sure that no case ranges overlap.
+ - Eliminate unreachable cases and unreachable code resulting from
+ removing case labels.
+
+ The standard does allow unreachable cases, e.g. CASE (5:3). But
+ they are a hassle for code generation, and to prevent that, we just
+ cut them out here. This is not necessary for overlapping cases
+ because they are illegal and we never even try to generate code.
+
+ We have the additional caveat that a SELECT construct could have
+ been a computed GOTO in the source code. Furtunately we can fairly
+ easily work around that here: The case_expr for a "real" SELECT CASE
+ is in code->expr1, but for a computed GOTO it is in code->expr2. All
+ we have to do is make sure that the case_expr is a scalar integer
+ expression. */
+
+static void
+resolve_select (gfc_code * code)
+{
+ gfc_code *body;
+ gfc_expr *case_expr;
+ gfc_case *cp, *default_case, *tail, *head;
+ int seen_unreachable;
+ int ncases;
+ bt type;
+ try t;
+
+ if (code->expr == NULL)
+ {
+ /* This was actually a computed GOTO statement. */
+ case_expr = code->expr2;
+ if (case_expr->ts.type != BT_INTEGER
+ || case_expr->rank != 0)
+ gfc_error ("Selection expression in computed GOTO statement "
+ "at %L must be a scalar integer expression",
+ &case_expr->where);
+
+ /* Further checking is not necessary because this SELECT was built
+ by the compiler, so it should always be OK. Just move the
+ case_expr from expr2 to expr so that we can handle computed
+ GOTOs as normal SELECTs from here on. */
+ code->expr = code->expr2;
+ code->expr2 = NULL;
+ return;
+ }
+
+ case_expr = code->expr;
+
+ type = case_expr->ts.type;
+ if (type != BT_LOGICAL && type != BT_INTEGER && type != BT_CHARACTER)
+ {
+ gfc_error ("Argument of SELECT statement at %L cannot be %s",
+ &case_expr->where, gfc_typename (&case_expr->ts));
+
+ /* Punt. Going on here just produce more garbage error messages. */
+ return;
+ }
+
+ if (case_expr->rank != 0)
+ {
+ gfc_error ("Argument of SELECT statement at %L must be a scalar "
+ "expression", &case_expr->where);
+
+ /* Punt. */
+ return;
+ }
+
+ /* Assume there is no DEFAULT case. */
+ default_case = NULL;
+ head = tail = NULL;
+ ncases = 0;
+
+ for (body = code->block; body; body = body->block)
+ {
+ /* Assume the CASE list is OK, and all CASE labels can be matched. */
+ t = SUCCESS;
+ seen_unreachable = 0;
+
+ /* Walk the case label list, making sure that all case labels
+ are legal. */
+ for (cp = body->ext.case_list; cp; cp = cp->next)
+ {
+ /* Count the number of cases in the whole construct. */
+ ncases++;
+
+ /* Intercept the DEFAULT case. */
+ if (cp->low == NULL && cp->high == NULL)
+ {
+ if (default_case != NULL)
+ {
+ gfc_error ("The DEFAULT CASE at %L cannot be followed "
+ "by a second DEFAULT CASE at %L",
+ &default_case->where, &cp->where);
+ t = FAILURE;
+ break;
+ }
+ else
+ {
+ default_case = cp;
+ continue;
+ }
+ }
+
+ /* Deal with single value cases and case ranges. Errors are
+ issued from the validation function. */
+ if(validate_case_label_expr (cp->low, case_expr) != SUCCESS
+ || validate_case_label_expr (cp->high, case_expr) != SUCCESS)
+ {
+ t = FAILURE;
+ break;
+ }
+
+ if (type == BT_LOGICAL
+ && ((cp->low == NULL || cp->high == NULL)
+ || cp->low != cp->high))
+ {
+ gfc_error
+ ("Logical range in CASE statement at %L is not allowed",
+ &cp->low->where);
+ t = FAILURE;
+ break;
+ }
+
+ if (cp->low != NULL && cp->high != NULL
+ && cp->low != cp->high
+ && gfc_compare_expr (cp->low, cp->high) > 0)
+ {
+ if (gfc_option.warn_surprising)
+ gfc_warning ("Range specification at %L can never "
+ "be matched", &cp->where);
+
+ cp->unreachable = 1;
+ seen_unreachable = 1;
+ }
+ else
+ {
+ /* If the case range can be matched, it can also overlap with
+ other cases. To make sure it does not, we put it in a
+ double linked list here. We sort that with a merge sort
+ later on to detect any overlapping cases. */
+ if (!head)
+ {
+ head = tail = cp;
+ head->right = head->left = NULL;
+ }
+ else
+ {
+ tail->right = cp;
+ tail->right->left = tail;
+ tail = tail->right;
+ tail->right = NULL;
+ }
+ }
+ }
+
+ /* It there was a failure in the previous case label, give up
+ for this case label list. Continue with the next block. */
+ if (t == FAILURE)
+ continue;
+
+ /* See if any case labels that are unreachable have been seen.
+ If so, we eliminate them. This is a bit of a kludge because
+ the case lists for a single case statement (label) is a
+ single forward linked lists. */
+ if (seen_unreachable)
+ {
+ /* Advance until the first case in the list is reachable. */
+ while (body->ext.case_list != NULL
+ && body->ext.case_list->unreachable)
+ {
+ gfc_case *n = body->ext.case_list;
+ body->ext.case_list = body->ext.case_list->next;
+ n->next = NULL;
+ gfc_free_case_list (n);
+ }
+
+ /* Strip all other unreachable cases. */
+ if (body->ext.case_list)
+ {
+ for (cp = body->ext.case_list; cp->next; cp = cp->next)
+ {
+ if (cp->next->unreachable)
+ {
+ gfc_case *n = cp->next;
+ cp->next = cp->next->next;
+ n->next = NULL;
+ gfc_free_case_list (n);
+ }
+ }
+ }
+ }
+ }
+
+ /* See if there were overlapping cases. If the check returns NULL,
+ there was overlap. In that case we don't do anything. If head
+ is non-NULL, we prepend the DEFAULT case. The sorted list can
+ then used during code generation for SELECT CASE constructs with
+ a case expression of a CHARACTER type. */
+ if (head)
+ {
+ head = check_case_overlap (head);
+
+ /* Prepend the default_case if it is there. */
+ if (head != NULL && default_case)
+ {
+ default_case->left = NULL;
+ default_case->right = head;
+ head->left = default_case;
+ }
+ }
+
+ /* Eliminate dead blocks that may be the result if we've seen
+ unreachable case labels for a block. */
+ for (body = code; body && body->block; body = body->block)
+ {
+ if (body->block->ext.case_list == NULL)
+ {
+ /* Cut the unreachable block from the code chain. */
+ gfc_code *c = body->block;
+ body->block = c->block;
+
+ /* Kill the dead block, but not the blocks below it. */
+ c->block = NULL;
+ gfc_free_statements (c);
+ }
+ }
+
+ /* More than two cases is legal but insane for logical selects.
+ Issue a warning for it. */
+ if (gfc_option.warn_surprising && type == BT_LOGICAL
+ && ncases > 2)
+ gfc_warning ("Logical SELECT CASE block at %L has more that two cases",
+ &code->loc);
+}
+
+
+/*********** Toplevel code resolution subroutines ***********/
+
+/* Given a branch to a label and a namespace, if the branch is conforming.
+ The code node described where the branch is located. */
+
+static void
+resolve_branch (gfc_st_label * label, gfc_code * code)
+{
+ gfc_code *block, *found;
+ code_stack *stack;
+ gfc_st_label *lp;
+
+ if (label == NULL)
+ return;
+ lp = label;
+
+ /* Step one: is this a valid branching target? */
+
+ if (lp->defined == ST_LABEL_UNKNOWN)
+ {
+ gfc_error ("Label %d referenced at %L is never defined", lp->value,
+ &lp->where);
+ return;
+ }
+
+ if (lp->defined != ST_LABEL_TARGET)
+ {
+ gfc_error ("Statement at %L is not a valid branch target statement "
+ "for the branch statement at %L", &lp->where, &code->loc);
+ return;
+ }
+
+ /* Step two: make sure this branch is not a branch to itself ;-) */
+
+ if (code->here == label)
+ {
+ gfc_warning ("Branch at %L causes an infinite loop", &code->loc);
+ return;
+ }
+
+ /* Step three: Try to find the label in the parse tree. To do this,
+ we traverse the tree block-by-block: first the block that
+ contains this GOTO, then the block that it is nested in, etc. We
+ can ignore other blocks because branching into another block is
+ not allowed. */
+
+ found = NULL;
+
+ for (stack = cs_base; stack; stack = stack->prev)
+ {
+ for (block = stack->head; block; block = block->next)
+ {
+ if (block->here == label)
+ {
+ found = block;
+ break;
+ }
+ }
+
+ if (found)
+ break;
+ }
+
+ if (found == NULL)
+ {
+ /* still nothing, so illegal. */
+ gfc_error_now ("Label at %L is not in the same block as the "
+ "GOTO statement at %L", &lp->where, &code->loc);
+ return;
+ }
+
+ /* Step four: Make sure that the branching target is legal if
+ the statement is an END {SELECT,DO,IF}. */
+
+ if (found->op == EXEC_NOP)
+ {
+ for (stack = cs_base; stack; stack = stack->prev)
+ if (stack->current->next == found)
+ break;
+
+ if (stack == NULL)
+ gfc_notify_std (GFC_STD_F95_DEL,
+ "Obsolete: GOTO at %L jumps to END of construct at %L",
+ &code->loc, &found->loc);
+ }
+}
+
+
+/* Check whether EXPR1 has the same shape as EXPR2. */
+
+static try
+resolve_where_shape (gfc_expr *expr1, gfc_expr *expr2)
+{
+ mpz_t shape[GFC_MAX_DIMENSIONS];
+ mpz_t shape2[GFC_MAX_DIMENSIONS];
+ try result = FAILURE;
+ int i;
+
+ /* Compare the rank. */
+ if (expr1->rank != expr2->rank)
+ return result;
+
+ /* Compare the size of each dimension. */
+ for (i=0; i<expr1->rank; i++)
+ {
+ if (gfc_array_dimen_size (expr1, i, &shape[i]) == FAILURE)
+ goto ignore;
+
+ if (gfc_array_dimen_size (expr2, i, &shape2[i]) == FAILURE)
+ goto ignore;
+
+ if (mpz_cmp (shape[i], shape2[i]))
+ goto over;
+ }
+
+ /* When either of the two expression is an assumed size array, we
+ ignore the comparison of dimension sizes. */
+ignore:
+ result = SUCCESS;
+
+over:
+ for (i--; i>=0; i--)
+ {
+ mpz_clear (shape[i]);
+ mpz_clear (shape2[i]);
+ }
+ return result;
+}
+
+
+/* Check whether a WHERE assignment target or a WHERE mask expression
+ has the same shape as the outmost WHERE mask expression. */
+
+static void
+resolve_where (gfc_code *code, gfc_expr *mask)
+{
+ gfc_code *cblock;
+ gfc_code *cnext;
+ gfc_expr *e = NULL;
+
+ cblock = code->block;
+
+ /* Store the first WHERE mask-expr of the WHERE statement or construct.
+ In case of nested WHERE, only the outmost one is stored. */
+ if (mask == NULL) /* outmost WHERE */
+ e = cblock->expr;
+ else /* inner WHERE */
+ e = mask;
+
+ while (cblock)
+ {
+ if (cblock->expr)
+ {
+ /* Check if the mask-expr has a consistent shape with the
+ outmost WHERE mask-expr. */
+ if (resolve_where_shape (cblock->expr, e) == FAILURE)
+ gfc_error ("WHERE mask at %L has inconsistent shape",
+ &cblock->expr->where);
+ }
+
+ /* the assignment statement of a WHERE statement, or the first
+ statement in where-body-construct of a WHERE construct */
+ cnext = cblock->next;
+ while (cnext)
+ {
+ switch (cnext->op)
+ {
+ /* WHERE assignment statement */
+ case EXEC_ASSIGN:
+
+ /* Check shape consistent for WHERE assignment target. */
+ if (e && resolve_where_shape (cnext->expr, e) == FAILURE)
+ gfc_error ("WHERE assignment target at %L has "
+ "inconsistent shape", &cnext->expr->where);
+ break;
+
+ /* WHERE or WHERE construct is part of a where-body-construct */
+ case EXEC_WHERE:
+ resolve_where (cnext, e);
+ break;
+
+ default:
+ gfc_error ("Unsupported statement inside WHERE at %L",
+ &cnext->loc);
+ }
+ /* the next statement within the same where-body-construct */
+ cnext = cnext->next;
+ }
+ /* the next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt */
+ cblock = cblock->block;
+ }
+}
+
+
+/* Check whether the FORALL index appears in the expression or not. */
+
+static try
+gfc_find_forall_index (gfc_expr *expr, gfc_symbol *symbol)
+{
+ gfc_array_ref ar;
+ gfc_ref *tmp;
+ gfc_actual_arglist *args;
+ int i;
+
+ switch (expr->expr_type)
+ {
+ case EXPR_VARIABLE:
+ assert (expr->symtree->n.sym);
+
+ /* A scalar assignment */
+ if (!expr->ref)
+ {
+ if (expr->symtree->n.sym == symbol)
+ return SUCCESS;
+ else
+ return FAILURE;
+ }
+
+ /* the expr is array ref, substring or struct component. */
+ tmp = expr->ref;
+ while (tmp != NULL)
+ {
+ switch (tmp->type)
+ {
+ case REF_ARRAY:
+ /* Check if the symbol appears in the array subscript. */
+ ar = tmp->u.ar;
+ for (i = 0; i < GFC_MAX_DIMENSIONS; i++)
+ {
+ if (ar.start[i])
+ if (gfc_find_forall_index (ar.start[i], symbol) == SUCCESS)
+ return SUCCESS;
+
+ if (ar.end[i])
+ if (gfc_find_forall_index (ar.end[i], symbol) == SUCCESS)
+ return SUCCESS;
+
+ if (ar.stride[i])
+ if (gfc_find_forall_index (ar.stride[i], symbol) == SUCCESS)
+ return SUCCESS;
+ } /* end for */
+ break;
+
+ case REF_SUBSTRING:
+ if (expr->symtree->n.sym == symbol)
+ return SUCCESS;
+ tmp = expr->ref;
+ /* Check if the symbol appears in the substring section. */
+ if (gfc_find_forall_index (tmp->u.ss.start, symbol) == SUCCESS)
+ return SUCCESS;
+ if (gfc_find_forall_index (tmp->u.ss.end, symbol) == SUCCESS)
+ return SUCCESS;
+ break;
+
+ case REF_COMPONENT:
+ break;
+
+ default:
+ gfc_error("expresion reference type error at %L", &expr->where);
+ }
+ tmp = tmp->next;
+ }
+ break;
+
+ /* If the expression is a function call, then check if the symbol
+ appears in the actual arglist of the function. */
+ case EXPR_FUNCTION:
+ for (args = expr->value.function.actual; args; args = args->next)
+ {
+ if (gfc_find_forall_index(args->expr,symbol) == SUCCESS)
+ return SUCCESS;
+ }
+ break;
+
+ /* It seems not to happen. */
+ case EXPR_SUBSTRING:
+ if (expr->ref)
+ {
+ tmp = expr->ref;
+ assert(expr->ref->type == REF_SUBSTRING);
+ if (gfc_find_forall_index (tmp->u.ss.start, symbol) == SUCCESS)
+ return SUCCESS;
+ if (gfc_find_forall_index (tmp->u.ss.end, symbol) == SUCCESS)
+ return SUCCESS;
+ }
+ break;
+
+ /* It seems not to happen. */
+ case EXPR_STRUCTURE:
+ case EXPR_ARRAY:
+ gfc_error ("Unsupported statement while finding forall index in "
+ "expression");
+ break;
+ default:
+ break;
+ }
+
+ /* Find the FORALL index in the first operand. */
+ if (expr->op1)
+ {
+ if (gfc_find_forall_index (expr->op1, symbol) == SUCCESS)
+ return SUCCESS;
+ }
+
+ /* Find the FORALL index in the second operand. */
+ if (expr->op2)
+ {
+ if (gfc_find_forall_index (expr->op2, symbol) == SUCCESS)
+ return SUCCESS;
+ }
+ return FAILURE;
+}
+
+
+/* Resolve assignment in FORALL construct.
+ NVAR is the number of FORALL index variables, and VAR_EXPR records the
+ FORALL index variables. */
+
+static void
+gfc_resolve_assign_in_forall (gfc_code *code, int nvar, gfc_expr **var_expr)
+{
+ int n;
+
+ for (n = 0; n < nvar; n++)
+ {
+ gfc_symbol *forall_index;
+
+ forall_index = var_expr[n]->symtree->n.sym;
+
+ /* Check whether the assignment target is one of the FORALL index
+ variable. */
+ if ((code->expr->expr_type == EXPR_VARIABLE)
+ && (code->expr->symtree->n.sym == forall_index))
+ gfc_error ("Assignment to a FORALL index variable at %L",
+ &code->expr->where);
+ else
+ {
+ /* If one of the FORALL index variables doesn't appear in the
+ assignment target, then there will be a many-to-one
+ assignment. */
+ if (gfc_find_forall_index (code->expr, forall_index) == FAILURE)
+ gfc_error ("The FORALL with index '%s' cause more than one "
+ "assignment to this object at %L",
+ var_expr[n]->symtree->name, &code->expr->where);
+ }
+ }
+}
+
+
+/* Resolve WHERE statement in FORALL construct. */
+
+static void
+gfc_resolve_where_code_in_forall (gfc_code *code, int nvar, gfc_expr **var_expr){
+ gfc_code *cblock;
+ gfc_code *cnext;
+
+ cblock = code->block;
+ while (cblock)
+ {
+ /* the assignment statement of a WHERE statement, or the first
+ statement in where-body-construct of a WHERE construct */
+ cnext = cblock->next;
+ while (cnext)
+ {
+ switch (cnext->op)
+ {
+ /* WHERE assignment statement */
+ case EXEC_ASSIGN:
+ gfc_resolve_assign_in_forall (cnext, nvar, var_expr);
+ break;
+
+ /* WHERE or WHERE construct is part of a where-body-construct */
+ case EXEC_WHERE:
+ gfc_resolve_where_code_in_forall (cnext, nvar, var_expr);
+ break;
+
+ default:
+ gfc_error ("Unsupported statement inside WHERE at %L",
+ &cnext->loc);
+ }
+ /* the next statement within the same where-body-construct */
+ cnext = cnext->next;
+ }
+ /* the next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt */
+ cblock = cblock->block;
+ }
+}
+
+
+/* Traverse the FORALL body to check whether the following errors exist:
+ 1. For assignment, check if a many-to-one assignment happens.
+ 2. For WHERE statement, check the WHERE body to see if there is any
+ many-to-one assignment. */
+
+static void
+gfc_resolve_forall_body (gfc_code *code, int nvar, gfc_expr **var_expr)
+{
+ gfc_code *c;
+
+ c = code->block->next;
+ while (c)
+ {
+ switch (c->op)
+ {
+ case EXEC_ASSIGN:
+ case EXEC_POINTER_ASSIGN:
+ gfc_resolve_assign_in_forall (c, nvar, var_expr);
+ break;
+
+ /* Because the resolve_blocks() will handle the nested FORALL,
+ there is no need to handle it here. */
+ case EXEC_FORALL:
+ break;
+ case EXEC_WHERE:
+ gfc_resolve_where_code_in_forall(c, nvar, var_expr);
+ break;
+ default:
+ break;
+ }
+ /* The next statement in the FORALL body. */
+ c = c->next;
+ }
+}
+
+
+/* Given a FORALL construct, first resolve the FORALL iterator, then call
+ gfc_resolve_forall_body to resolve the FORALL body. */
+
+static void resolve_blocks (gfc_code *, gfc_namespace *);
+
+static void
+gfc_resolve_forall (gfc_code *code, gfc_namespace *ns, int forall_save)
+{
+ static gfc_expr **var_expr;
+ static int total_var = 0;
+ static int nvar = 0;
+ gfc_forall_iterator *fa;
+ gfc_symbol *forall_index;
+ gfc_code *next;
+ int i;
+
+ /* Start to resolve a FORALL construct */
+ if (forall_save == 0)
+ {
+ /* Count the total number of FORALL index in the nested FORALL
+ construct in order to allocate the VAR_EXPR with proper size. */
+ next = code;
+ while ((next != NULL) && (next->op == EXEC_FORALL))
+ {
+ for (fa = next->ext.forall_iterator; fa; fa = fa->next)
+ total_var ++;
+ next = next->block->next;
+ }
+
+ /* allocate VAR_EXPR with NUMBER_OF_FORALL_INDEX elements. */
+ var_expr = (gfc_expr **) gfc_getmem (total_var * sizeof (gfc_expr *));
+ }
+
+ /* The information about FORALL iterator, including FORALL index start, end
+ and stride. The FORALL index can not appear in start, end or stride. */
+ for (fa = code->ext.forall_iterator; fa; fa = fa->next)
+ {
+ /* Check if any outer FORALL index name is the same as the current
+ one. */
+ for (i = 0; i < nvar; i++)
+ {
+ if (fa->var->symtree->n.sym == var_expr[i]->symtree->n.sym)
+ {
+ gfc_error ("An outer FORALL construct already has an index "
+ "with this name %L", &fa->var->where);
+ }
+ }
+
+ /* Record the current FORALL index. */
+ var_expr[nvar] = gfc_copy_expr (fa->var);
+
+ forall_index = fa->var->symtree->n.sym;
+
+ /* Check if the FORALL index appears in start, end or stride. */
+ if (gfc_find_forall_index (fa->start, forall_index) == SUCCESS)
+ gfc_error ("A FORALL index must not appear in a limit or stride "
+ "expression in the same FORALL at %L", &fa->start->where);
+ if (gfc_find_forall_index (fa->end, forall_index) == SUCCESS)
+ gfc_error ("A FORALL index must not appear in a limit or stride "
+ "expression in the same FORALL at %L", &fa->end->where);
+ if (gfc_find_forall_index (fa->stride, forall_index) == SUCCESS)
+ gfc_error ("A FORALL index must not appear in a limit or stride "
+ "expression in the same FORALL at %L", &fa->stride->where);
+ nvar++;
+ }
+
+ /* Resolve the FORALL body. */
+ gfc_resolve_forall_body (code, nvar, var_expr);
+
+ /* May call gfc_resolve_forall to resolve the inner FORALL loop. */
+ resolve_blocks (code->block, ns);
+
+ /* Free VAR_EXPR after the whole FORALL construct resolved. */
+ for (i = 0; i < total_var; i++)
+ gfc_free_expr (var_expr[i]);
+
+ /* Reset the counters. */
+ total_var = 0;
+ nvar = 0;
+}
+
+
+/* Resolve lists of blocks found in IF, SELECT CASE, WHERE, FORALL ,GOTO and
+ DO code nodes. */
+
+static void resolve_code (gfc_code *, gfc_namespace *);
+
+static void
+resolve_blocks (gfc_code * b, gfc_namespace * ns)
+{
+ try t;
+
+ for (; b; b = b->block)
+ {
+ t = gfc_resolve_expr (b->expr);
+ if (gfc_resolve_expr (b->expr2) == FAILURE)
+ t = FAILURE;
+
+ switch (b->op)
+ {
+ case EXEC_IF:
+ if (t == SUCCESS && b->expr != NULL
+ && (b->expr->ts.type != BT_LOGICAL || b->expr->rank != 0))
+ gfc_error
+ ("ELSE IF clause at %L requires a scalar LOGICAL expression",
+ &b->expr->where);
+ break;
+
+ case EXEC_WHERE:
+ if (t == SUCCESS
+ && b->expr != NULL
+ && (b->expr->ts.type != BT_LOGICAL
+ || b->expr->rank == 0))
+ gfc_error
+ ("WHERE/ELSEWHERE clause at %L requires a LOGICAL array",
+ &b->expr->where);
+ break;
+
+ case EXEC_GOTO:
+ resolve_branch (b->label, b);
+ break;
+
+ case EXEC_SELECT:
+ case EXEC_FORALL:
+ case EXEC_DO:
+ case EXEC_DO_WHILE:
+ break;
+
+ default:
+ gfc_internal_error ("resolve_block(): Bad block type");
+ }
+
+ resolve_code (b->next, ns);
+ }
+}
+
+
+/* Given a block of code, recursively resolve everything pointed to by this
+ code block. */
+
+static void
+resolve_code (gfc_code * code, gfc_namespace * ns)
+{
+ int forall_save = 0;
+ code_stack frame;
+ gfc_alloc *a;
+ try t;
+
+ frame.prev = cs_base;
+ frame.head = code;
+ cs_base = &frame;
+
+ for (; code; code = code->next)
+ {
+ frame.current = code;
+
+ if (code->op == EXEC_FORALL)
+ {
+ forall_save = forall_flag;
+ forall_flag = 1;
+ gfc_resolve_forall (code, ns, forall_save);
+ }
+ else
+ resolve_blocks (code->block, ns);
+
+ if (code->op == EXEC_FORALL)
+ forall_flag = forall_save;
+
+ t = gfc_resolve_expr (code->expr);
+ if (gfc_resolve_expr (code->expr2) == FAILURE)
+ t = FAILURE;
+
+ switch (code->op)
+ {
+ case EXEC_NOP:
+ case EXEC_CYCLE:
+ case EXEC_IOLENGTH:
+ case EXEC_PAUSE:
+ case EXEC_STOP:
+ case EXEC_EXIT:
+ case EXEC_CONTINUE:
+ case EXEC_DT_END:
+ case EXEC_TRANSFER:
+ break;
+
+ case EXEC_WHERE:
+ resolve_where (code, NULL);
+ break;
+
+ case EXEC_GOTO:
+ if (code->expr != NULL && code->expr->ts.type != BT_INTEGER)
+ gfc_error ("ASSIGNED GOTO statement at %L requires an INTEGER "
+ "variable", &code->expr->where);
+ else
+ resolve_branch (code->label, code);
+ break;
+
+ case EXEC_RETURN:
+ if (code->expr != NULL && code->expr->ts.type != BT_INTEGER)
+ gfc_error ("Alternate RETURN statement at %L requires an INTEGER "
+ "return specifier", &code->expr->where);
+ break;
+
+ case EXEC_ASSIGN:
+ if (t == FAILURE)
+ break;
+
+ if (gfc_extend_assign (code, ns) == SUCCESS)
+ goto call;
+
+ if (gfc_pure (NULL))
+ {
+ if (gfc_impure_variable (code->expr->symtree->n.sym))
+ {
+ gfc_error
+ ("Cannot assign to variable '%s' in PURE procedure at %L",
+ code->expr->symtree->n.sym->name, &code->expr->where);
+ break;
+ }
+
+ if (code->expr2->ts.type == BT_DERIVED
+ && derived_pointer (code->expr2->ts.derived))
+ {
+ gfc_error
+ ("Right side of assignment at %L is a derived type "
+ "containing a POINTER in a PURE procedure",
+ &code->expr2->where);
+ break;
+ }
+ }
+
+ gfc_check_assign (code->expr, code->expr2, 1);
+ break;
+
+ case EXEC_LABEL_ASSIGN:
+ if (code->label->defined == ST_LABEL_UNKNOWN)
+ gfc_error ("Label %d referenced at %L is never defined",
+ code->label->value, &code->label->where);
+ if (t == SUCCESS && code->expr->ts.type != BT_INTEGER)
+ gfc_error ("ASSIGN statement at %L requires an INTEGER "
+ "variable", &code->expr->where);
+ break;
+
+ case EXEC_POINTER_ASSIGN:
+ if (t == FAILURE)
+ break;
+
+ gfc_check_pointer_assign (code->expr, code->expr2);
+ break;
+
+ case EXEC_ARITHMETIC_IF:
+ if (t == SUCCESS
+ && code->expr->ts.type != BT_INTEGER
+ && code->expr->ts.type != BT_REAL)
+ gfc_error ("Arithmetic IF statement at %L requires a numeric "
+ "expression", &code->expr->where);
+
+ resolve_branch (code->label, code);
+ resolve_branch (code->label2, code);
+ resolve_branch (code->label3, code);
+ break;
+
+ case EXEC_IF:
+ if (t == SUCCESS && code->expr != NULL
+ && (code->expr->ts.type != BT_LOGICAL
+ || code->expr->rank != 0))
+ gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
+ &code->expr->where);
+ break;
+
+ case EXEC_CALL:
+ call:
+ resolve_call (code);
+ break;
+
+ case EXEC_SELECT:
+ /* Select is complicated. Also, a SELECT construct could be
+ a transformed computed GOTO. */
+ resolve_select (code);
+ break;
+
+ case EXEC_DO:
+ if (code->ext.iterator != NULL)
+ gfc_resolve_iterator (code->ext.iterator);
+ break;
+
+ case EXEC_DO_WHILE:
+ if (code->expr == NULL)
+ gfc_internal_error ("resolve_code(): No expression on DO WHILE");
+ if (t == SUCCESS
+ && (code->expr->rank != 0
+ || code->expr->ts.type != BT_LOGICAL))
+ gfc_error ("Exit condition of DO WHILE loop at %L must be "
+ "a scalar LOGICAL expression", &code->expr->where);
+ break;
+
+ case EXEC_ALLOCATE:
+ if (t == SUCCESS && code->expr != NULL
+ && code->expr->ts.type != BT_INTEGER)
+ gfc_error ("STAT tag in ALLOCATE statement at %L must be "
+ "of type INTEGER", &code->expr->where);
+
+ for (a = code->ext.alloc_list; a; a = a->next)
+ resolve_allocate_expr (a->expr);
+
+ break;
+
+ case EXEC_DEALLOCATE:
+ if (t == SUCCESS && code->expr != NULL
+ && code->expr->ts.type != BT_INTEGER)
+ gfc_error
+ ("STAT tag in DEALLOCATE statement at %L must be of type "
+ "INTEGER", &code->expr->where);
+
+ for (a = code->ext.alloc_list; a; a = a->next)
+ resolve_deallocate_expr (a->expr);
+
+ break;
+
+ case EXEC_OPEN:
+ if (gfc_resolve_open (code->ext.open) == FAILURE)
+ break;
+
+ resolve_branch (code->ext.open->err, code);
+ break;
+
+ case EXEC_CLOSE:
+ if (gfc_resolve_close (code->ext.close) == FAILURE)
+ break;
+
+ resolve_branch (code->ext.close->err, code);
+ break;
+
+ case EXEC_BACKSPACE:
+ case EXEC_ENDFILE:
+ case EXEC_REWIND:
+ if (gfc_resolve_filepos (code->ext.filepos) == FAILURE)
+ break;
+
+ resolve_branch (code->ext.filepos->err, code);
+ break;
+
+ case EXEC_INQUIRE:
+ if (gfc_resolve_inquire (code->ext.inquire) == FAILURE)
+ break;
+
+ resolve_branch (code->ext.inquire->err, code);
+ break;
+
+ case EXEC_READ:
+ case EXEC_WRITE:
+ if (gfc_resolve_dt (code->ext.dt) == FAILURE)
+ break;
+
+ resolve_branch (code->ext.dt->err, code);
+ resolve_branch (code->ext.dt->end, code);
+ resolve_branch (code->ext.dt->eor, code);
+ break;
+
+ case EXEC_FORALL:
+ resolve_forall_iterators (code->ext.forall_iterator);
+
+ if (code->expr != NULL && code->expr->ts.type != BT_LOGICAL)
+ gfc_error
+ ("FORALL mask clause at %L requires a LOGICAL expression",
+ &code->expr->where);
+ break;
+
+ default:
+ gfc_internal_error ("resolve_code(): Bad statement code");
+ }
+ }
+
+ cs_base = frame.prev;
+}
+
+
+/* Resolve initial values and make sure they are compatible with
+ the variable. */
+
+static void
+resolve_values (gfc_symbol * sym)
+{
+
+ if (sym->value == NULL)
+ return;
+
+ if (gfc_resolve_expr (sym->value) == FAILURE)
+ return;
+
+ gfc_check_assign_symbol (sym, sym->value);
+}
+
+
+/* Do anything necessary to resolve a symbol. Right now, we just
+ assume that an otherwise unknown symbol is a variable. This sort
+ of thing commonly happens for symbols in module. */
+
+static void
+resolve_symbol (gfc_symbol * sym)
+{
+ /* Zero if we are checking a formal namespace. */
+ static int formal_ns_flag = 1;
+ int formal_ns_save, check_constant, mp_flag;
+
+ if (sym->attr.flavor == FL_UNKNOWN)
+ {
+ if (sym->attr.external == 0 && sym->attr.intrinsic == 0)
+ sym->attr.flavor = FL_VARIABLE;
+ else
+ {
+ sym->attr.flavor = FL_PROCEDURE;
+ if (sym->attr.dimension)
+ sym->attr.function = 1;
+ }
+ }
+
+ /* Symbols that are module procedures with results (functions) have
+ the types and array specification copied for type checking in
+ procedures that call them, as well as for saving to a module
+ file. These symbols can't stand the scrutiny that their results
+ can. */
+ mp_flag = (sym->result != NULL && sym->result != sym);
+
+ /* Assign default type to symbols that need one and don't have one. */
+ if (sym->ts.type == BT_UNKNOWN)
+ {
+ if (sym->attr.flavor == FL_VARIABLE || sym->attr.flavor == FL_PARAMETER)
+ gfc_set_default_type (sym, 0, NULL);
+
+ if (sym->attr.flavor == FL_PROCEDURE && sym->attr.function)
+ {
+ if (!mp_flag)
+ gfc_set_default_type (sym, 0, NULL);
+ else
+ {
+ /* Result may be in another namespace. */
+ resolve_symbol (sym->result);
+
+ sym->ts = sym->result->ts;
+ sym->as = gfc_copy_array_spec (sym->result->as);
+ }
+ }
+ }
+
+ if (sym->as != NULL
+ && (sym->as->type == AS_ASSUMED_SIZE
+ || sym->as->type == AS_ASSUMED_SHAPE)
+ && sym->attr.dummy == 0)
+ {
+ gfc_error("Assumed %s array at %L must be a dummy argument",
+ sym->as->type == AS_ASSUMED_SIZE ? "size" : "shape",
+ &sym->declared_at);
+ return;
+ }
+
+ /* Make sure that character string variables with assumed length are
+ dummy argument. */
+
+ if (sym->attr.flavor == FL_VARIABLE && !sym->attr.result
+ && sym->ts.type == BT_CHARACTER
+ && sym->ts.cl->length == NULL && sym->attr.dummy == 0)
+ {
+ gfc_error ("Entity with assumed character length at %L must be a "
+ "dummy argument or a PARAMETER", &sym->declared_at);
+ return;
+ }
+
+ /* Make sure a parameter that has been implicitly typed still
+ matches the implicit type, since PARAMETER statements can precede
+ IMPLICIT statements. */
+
+ if (sym->attr.flavor == FL_PARAMETER
+ && sym->attr.implicit_type
+ && !gfc_compare_types (&sym->ts, gfc_get_default_type (sym, sym->ns)))
+ gfc_error ("Implicitly typed PARAMETER '%s' at %L doesn't match a "
+ "later IMPLICIT type", sym->name, &sym->declared_at);
+
+ /* Make sure the types of derived parameters are consistent. This
+ type checking is deferred until resolution because the type may
+ refer to a derived type from the host. */
+
+ if (sym->attr.flavor == FL_PARAMETER
+ && sym->ts.type == BT_DERIVED
+ && !gfc_compare_types (&sym->ts, &sym->value->ts))
+ gfc_error ("Incompatible derived type in PARAMETER at %L",
+ &sym->value->where);
+
+ /* Make sure symbols with known intent or optional are really dummy
+ variable. Because of ENTRY statement, this has to be deferred
+ until resolution time. */
+
+ if (! sym->attr.dummy
+ && (sym->attr.optional
+ || sym->attr.intent != INTENT_UNKNOWN))
+ {
+ gfc_error ("Symbol at %L is not a DUMMY variable", &sym->declared_at);
+ return;
+ }
+
+ if (sym->attr.proc == PROC_ST_FUNCTION)
+ {
+ if (sym->ts.type == BT_CHARACTER)
+ {
+ gfc_charlen *cl = sym->ts.cl;
+ if (!cl || !cl->length || cl->length->expr_type != EXPR_CONSTANT)
+ {
+ gfc_error ("Character-valued statement function '%s' at %L must "
+ "have constant length", sym->name, &sym->declared_at);
+ return;
+ }
+ }
+ }
+
+ /* Constraints on deferred shape variable. */
+ if (sym->attr.flavor == FL_VARIABLE
+ || (sym->attr.flavor == FL_PROCEDURE
+ && sym->attr.function))
+ {
+ if (sym->as == NULL || sym->as->type != AS_DEFERRED)
+ {
+ if (sym->attr.allocatable)
+ {
+ if (sym->attr.dimension)
+ gfc_error ("Allocatable array at %L must have a deferred shape",
+ &sym->declared_at);
+ else
+ gfc_error ("Object at %L may not be ALLOCATABLE",
+ &sym->declared_at);
+ return;
+ }
+
+ if (sym->attr.pointer && sym->attr.dimension)
+ {
+ gfc_error ("Pointer to array at %L must have a deferred shape",
+ &sym->declared_at);
+ return;
+ }
+
+ }
+ else
+ {
+ if (!mp_flag && !sym->attr.allocatable
+ && !sym->attr.pointer && !sym->attr.dummy)
+ {
+ gfc_error ("Array at %L cannot have a deferred shape",
+ &sym->declared_at);
+ return;
+ }
+ }
+ }
+
+ /* Make sure that intrinsic exist */
+ if (sym->attr.intrinsic
+ && ! gfc_intrinsic_name(sym->name, 0)
+ && ! gfc_intrinsic_name(sym->name, 1))
+ gfc_error("Intrinsic at %L does not exist", &sym->declared_at);
+
+ /* Resolve array specifier. Check as well some constraints
+ on COMMON blocks. */
+
+ check_constant = sym->attr.in_common && !sym->attr.pointer;
+ gfc_resolve_array_spec (sym->as, check_constant);
+
+ /* Resolve formal namespaces. */
+
+ if (formal_ns_flag && sym != NULL && sym->formal_ns != NULL)
+ {
+ formal_ns_save = formal_ns_flag;
+ formal_ns_flag = 0;
+ gfc_resolve (sym->formal_ns);
+ formal_ns_flag = formal_ns_save;
+ }
+}
+
+
+
+/************* Resolve DATA statements *************/
+
+static struct
+{
+ gfc_data_value *vnode;
+ int left;
+}
+values;
+
+
+/* Advance the values structure to point to the next value in the data list. */
+
+static try
+next_data_value (void)
+{
+
+ while (values.left == 0)
+ {
+ if (values.vnode->next == NULL)
+ return FAILURE;
+
+ values.vnode = values.vnode->next;
+ values.left = values.vnode->repeat;
+ }
+
+ values.left--;
+ return SUCCESS;
+}
+
+
+static try
+check_data_variable (gfc_data_variable * var, locus * where)
+{
+ gfc_expr *e;
+ mpz_t size;
+ mpz_t offset;
+ try t;
+ int mark = 0;
+ int i;
+ mpz_t section_index[GFC_MAX_DIMENSIONS];
+ gfc_ref *ref;
+ gfc_array_ref *ar;
+
+ if (gfc_resolve_expr (var->expr) == FAILURE)
+ return FAILURE;
+
+ ar = NULL;
+ mpz_init_set_si (offset, 0);
+ e = var->expr;
+
+ if (e->expr_type != EXPR_VARIABLE)
+ gfc_internal_error ("check_data_variable(): Bad expression");
+
+ if (e->rank == 0)
+ mpz_init_set_ui (size, 1);
+ else
+ {
+ ref = e->ref;
+
+ /* Find the array section reference. */
+ for (ref = e->ref; ref; ref = ref->next)
+ {
+ if (ref->type != REF_ARRAY)
+ continue;
+ if (ref->u.ar.type == AR_ELEMENT)
+ continue;
+ break;
+ }
+ assert (ref);
+
+ /* Set marks asscording to the reference pattern. */
+ switch (ref->u.ar.type)
+ {
+ case AR_FULL:
+ mark = 1;
+ break;
+
+ case AR_SECTION:
+ ar = &ref->u.ar;
+ /* Get the start position of array section. */
+ gfc_get_section_index (ar, section_index, &offset);
+ mark = 2;
+ break;
+
+ default:
+ abort();
+ }
+
+ if (gfc_array_size (e, &size) == FAILURE)
+ {
+ gfc_error ("Nonconstant array section at %L in DATA statement",
+ &e->where);
+ mpz_clear (offset);
+ return FAILURE;
+ }
+ }
+
+ t = SUCCESS;
+
+ while (mpz_cmp_ui (size, 0) > 0)
+ {
+ if (next_data_value () == FAILURE)
+ {
+ gfc_error ("DATA statement at %L has more variables than values",
+ where);
+ t = FAILURE;
+ break;
+ }
+
+ t = gfc_check_assign (var->expr, values.vnode->expr, 0);
+ if (t == FAILURE)
+ break;
+
+ /* Assign initial value to symbol. */
+ gfc_assign_data_value (var->expr, values.vnode->expr, offset);
+
+ if (mark == 1)
+ mpz_add_ui (offset, offset, 1);
+
+ /* Modify the array section indexes and recalculate the offset for
+ next element. */
+ else if (mark == 2)
+ gfc_advance_section (section_index, ar, &offset);
+
+ mpz_sub_ui (size, size, 1);
+ }
+ if (mark == 2)
+ {
+ for (i = 0; i < ar->dimen; i++)
+ mpz_clear (section_index[i]);
+ }
+
+ mpz_clear (size);
+ mpz_clear (offset);
+
+ return t;
+}
+
+
+static try traverse_data_var (gfc_data_variable *, locus *);
+
+/* Iterate over a list of elements in a DATA statement. */
+
+static try
+traverse_data_list (gfc_data_variable * var, locus * where)
+{
+ mpz_t trip;
+ iterator_stack frame;
+ gfc_expr *e;
+
+ mpz_init (frame.value);
+
+ mpz_init_set (trip, var->iter.end->value.integer);
+ mpz_sub (trip, trip, var->iter.start->value.integer);
+ mpz_add (trip, trip, var->iter.step->value.integer);
+
+ mpz_div (trip, trip, var->iter.step->value.integer);
+
+ mpz_set (frame.value, var->iter.start->value.integer);
+
+ frame.prev = iter_stack;
+ frame.variable = var->iter.var->symtree;
+ iter_stack = &frame;
+
+ while (mpz_cmp_ui (trip, 0) > 0)
+ {
+ if (traverse_data_var (var->list, where) == FAILURE)
+ {
+ mpz_clear (trip);
+ return FAILURE;
+ }
+
+ e = gfc_copy_expr (var->expr);
+ if (gfc_simplify_expr (e, 1) == FAILURE)
+ {
+ gfc_free_expr (e);
+ return FAILURE;
+ }
+
+ mpz_add (frame.value, frame.value, var->iter.step->value.integer);
+
+ mpz_sub_ui (trip, trip, 1);
+ }
+
+ mpz_clear (trip);
+ mpz_clear (frame.value);
+
+ iter_stack = frame.prev;
+ return SUCCESS;
+}
+
+
+/* Type resolve variables in the variable list of a DATA statement. */
+
+static try
+traverse_data_var (gfc_data_variable * var, locus * where)
+{
+ try t;
+
+ for (; var; var = var->next)
+ {
+ if (var->expr == NULL)
+ t = traverse_data_list (var, where);
+ else
+ t = check_data_variable (var, where);
+
+ if (t == FAILURE)
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Resolve the expressions and iterators associated with a data statement.
+ This is separate from the assignment checking because data lists should
+ only be resolved once. */
+
+static try
+resolve_data_variables (gfc_data_variable * d)
+{
+
+ for (; d; d = d->next)
+ {
+ if (d->list == NULL)
+ {
+ if (gfc_resolve_expr (d->expr) == FAILURE)
+ return FAILURE;
+ }
+ else
+ {
+ if (gfc_resolve_iterator (&d->iter) == FAILURE)
+ return FAILURE;
+
+ if (d->iter.start->expr_type != EXPR_CONSTANT
+ || d->iter.end->expr_type != EXPR_CONSTANT
+ || d->iter.step->expr_type != EXPR_CONSTANT)
+ gfc_internal_error ("resolve_data_variables(): Bad iterator");
+
+ if (resolve_data_variables (d->list) == FAILURE)
+ return FAILURE;
+ }
+ }
+
+ return SUCCESS;
+}
+
+
+/* Resolve a single DATA statement. We implement this by storing a pointer to
+ the value list into static variables, and then recursively traversing the
+ variables list, expanding iterators and such. */
+
+static void
+resolve_data (gfc_data * d)
+{
+
+ if (resolve_data_variables (d->var) == FAILURE)
+ return;
+
+ values.vnode = d->value;
+ values.left = (d->value == NULL) ? 0 : d->value->repeat;
+
+ if (traverse_data_var (d->var, &d->where) == FAILURE)
+ return;
+
+ /* At this point, we better not have any values left. */
+
+ if (next_data_value () == SUCCESS)
+ gfc_error ("DATA statement at %L has more values than variables",
+ &d->where);
+}
+
+
+/* Determines if a variable is not 'pure', ie not assignable within a pure
+ procedure. Returns zero if assignment is OK, nonzero if there is a problem.
+ */
+
+int
+gfc_impure_variable (gfc_symbol * sym)
+{
+
+ if (sym->attr.use_assoc || sym->attr.in_common)
+ return 1;
+
+ if (sym->ns != gfc_current_ns)
+ return !sym->attr.function;
+
+ /* TODO: Check storage association through EQUIVALENCE statements */
+
+ return 0;
+}
+
+
+/* Test whether a symbol is pure or not. For a NULL pointer, checks the
+ symbol of the current procedure. */
+
+int
+gfc_pure (gfc_symbol * sym)
+{
+ symbol_attribute attr;
+
+ if (sym == NULL)
+ sym = gfc_current_ns->proc_name;
+ if (sym == NULL)
+ return 0;
+
+ attr = sym->attr;
+
+ return attr.flavor == FL_PROCEDURE && (attr.pure || attr.elemental);
+}
+
+
+/* Test whether the current procedure is elemental or not. */
+
+int
+gfc_elemental (gfc_symbol * sym)
+{
+ symbol_attribute attr;
+
+ if (sym == NULL)
+ sym = gfc_current_ns->proc_name;
+ if (sym == NULL)
+ return 0;
+ attr = sym->attr;
+
+ return attr.flavor == FL_PROCEDURE && attr.elemental;
+}
+
+
+/* Warn about unused labels. */
+
+static void
+warn_unused_label (gfc_namespace * ns)
+{
+ gfc_st_label *l;
+
+ l = ns->st_labels;
+ if (l == NULL)
+ return;
+
+ while (l->next)
+ l = l->next;
+
+ for (; l; l = l->prev)
+ {
+ if (l->defined == ST_LABEL_UNKNOWN)
+ continue;
+
+ switch (l->referenced)
+ {
+ case ST_LABEL_UNKNOWN:
+ gfc_warning ("Label %d at %L defined but not used", l->value,
+ &l->where);
+ break;
+
+ case ST_LABEL_BAD_TARGET:
+ gfc_warning ("Label %d at %L defined but cannot be used", l->value,
+ &l->where);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+
+/* Resolve derived type EQUIVALENCE object. */
+
+static try
+resolve_equivalence_derived (gfc_symbol *derived, gfc_symbol *sym, gfc_expr *e)
+{
+ gfc_symbol *d;
+ gfc_component *c = derived->components;
+
+ if (!derived)
+ return SUCCESS;
+
+ /* Shall not be an object of nonsequence derived type. */
+ if (!derived->attr.sequence)
+ {
+ gfc_error ("Derived type variable '%s' at %L must have SEQUENCE "
+ "attribute to be an EQUIVALENCE object", sym->name, &e->where);
+ return FAILURE;
+ }
+
+ for (; c ; c = c->next)
+ {
+ d = c->ts.derived;
+ if (d && (resolve_equivalence_derived (c->ts.derived, sym, e) == FAILURE))
+ return FAILURE;
+
+ /* Shall not be an object of sequence derived type containing a pointer
+ in the structure. */
+ if (c->pointer)
+ {
+ gfc_error ("Derived type variable '%s' at %L has pointer componet(s) "
+ "cannot be an EQUIVALENCE object", sym->name, &e->where);
+ return FAILURE;
+ }
+ }
+ return SUCCESS;
+}
+
+
+/* Resolve equivalence object.
+ An EQUIVALENCE object shall not be a dummy argument, a pointer, an
+ allocatable array, an object of nonsequence derived type, an object of
+ sequence derived type containing a pointer at any level of component
+ selection, an automatic object, a function name, an entry name, a result
+ name, a named constant, a structure component, or a subobject of any of
+ the preceding objects. */
+
+static void
+resolve_equivalence (gfc_equiv *eq)
+{
+ gfc_symbol *sym;
+ gfc_symbol *derived;
+ gfc_expr *e;
+ gfc_ref *r;
+
+ for (; eq; eq = eq->eq)
+ {
+ e = eq->expr;
+ if (gfc_resolve_expr (e) == FAILURE)
+ continue;
+
+ sym = e->symtree->n.sym;
+
+ /* Shall not be a dummy argument. */
+ if (sym->attr.dummy)
+ {
+ gfc_error ("Dummy argument '%s' at %L cannot be an EQUIVALENCE "
+ "object", sym->name, &e->where);
+ continue;
+ }
+
+ /* Shall not be an allocatable array. */
+ if (sym->attr.allocatable)
+ {
+ gfc_error ("Allocatable array '%s' at %L cannot be an EQUIVALENCE "
+ "object", sym->name, &e->where);
+ continue;
+ }
+
+ /* Shall not be a pointer. */
+ if (sym->attr.pointer)
+ {
+ gfc_error ("Pointer '%s' at %L cannot be an EQUIVALENCE object",
+ sym->name, &e->where);
+ continue;
+ }
+
+ /* Shall not be a function name, ... */
+ if (sym->attr.function || sym->attr.result || sym->attr.entry
+ || sym->attr.subroutine)
+ {
+ gfc_error ("Entity '%s' at %L cannot be an EQUIVALENCE object",
+ sym->name, &e->where);
+ continue;
+ }
+
+ /* Shall not be a named constant. */
+ if (e->expr_type == EXPR_CONSTANT)
+ {
+ gfc_error ("Named constant '%s' at %L cannot be an EQUIVALENCE "
+ "object", sym->name, &e->where);
+ continue;
+ }
+
+ derived = e->ts.derived;
+ if (derived && resolve_equivalence_derived (derived, sym, e) == FAILURE)
+ continue;
+
+ if (!e->ref)
+ continue;
+
+ /* Shall not be an automatic array. */
+ if (e->ref->type == REF_ARRAY
+ && gfc_resolve_array_spec (e->ref->u.ar.as, 1) == FAILURE)
+ {
+ gfc_error ("Array '%s' at %L with non-constant bounds cannot be "
+ "an EQUIVALENCE object", sym->name, &e->where);
+ continue;
+ }
+
+ /* Shall not be a structure component. */
+ r = e->ref;
+ while (r)
+ {
+ if (r->type == REF_COMPONENT)
+ {
+ gfc_error ("Structure component '%s' at %L cannot be an "
+ "EQUIVALENCE object",
+ r->u.c.component->name, &e->where);
+ break;
+ }
+ r = r->next;
+ }
+ }
+}
+
+
+/* This function is called after a complete program unit has been compiled.
+ Its purpose is to examine all of the expressions associated with a program
+ unit, assign types to all intermediate expressions, make sure that all
+ assignments are to compatible types and figure out which names refer to
+ which functions or subroutines. */
+
+void
+gfc_resolve (gfc_namespace * ns)
+{
+ gfc_namespace *old_ns, *n;
+ gfc_charlen *cl;
+ gfc_data *d;
+ gfc_equiv *eq;
+
+ old_ns = gfc_current_ns;
+ gfc_current_ns = ns;
+
+ resolve_contained_functions (ns);
+
+ gfc_traverse_ns (ns, resolve_symbol);
+
+ for (n = ns->contained; n; n = n->sibling)
+ {
+ if (gfc_pure (ns->proc_name) && !gfc_pure (n->proc_name))
+ gfc_error ("Contained procedure '%s' at %L of a PURE procedure must "
+ "also be PURE", n->proc_name->name,
+ &n->proc_name->declared_at);
+
+ gfc_resolve (n);
+ }
+
+ forall_flag = 0;
+ gfc_check_interfaces (ns);
+
+ for (cl = ns->cl_list; cl; cl = cl->next)
+ {
+ if (cl->length == NULL || gfc_resolve_expr (cl->length) == FAILURE)
+ continue;
+
+ if (cl->length->ts.type != BT_INTEGER)
+ gfc_error
+ ("Character length specification at %L must be of type INTEGER",
+ &cl->length->where);
+ }
+
+ gfc_traverse_ns (ns, resolve_values);
+
+ if (ns->save_all)
+ gfc_save_all (ns);
+
+ iter_stack = NULL;
+ for (d = ns->data; d; d = d->next)
+ resolve_data (d);
+
+ iter_stack = NULL;
+ gfc_traverse_ns (ns, gfc_formalize_init_value);
+
+ for (eq = ns->equiv; eq; eq = eq->next)
+ resolve_equivalence (eq);
+
+ cs_base = NULL;
+ resolve_code (ns->code, ns);
+
+ /* Warn about unused labels. */
+ if (gfc_option.warn_unused_labels)
+ warn_unused_label (ns);
+
+ gfc_current_ns = old_ns;
+}
+
diff --git a/gcc/fortran/scanner.c b/gcc/fortran/scanner.c
new file mode 100644
index 00000000000..34959ab92fe
--- /dev/null
+++ b/gcc/fortran/scanner.c
@@ -0,0 +1,1073 @@
+/* Character scanner.
+ Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Set of subroutines to (ultimately) return the next character to the
+ various matching subroutines. This file's job is to read files and
+ build up lines that are parsed by the parser. This means that we
+ handle continuation lines and "include" lines.
+
+ The first thing the scanner does is to load an entire file into
+ memory. We load the entire file into memory for a couple reasons.
+ The first is that we want to be able to deal with nonseekable input
+ (pipes, stdin) and there is a lot of backing up involved during
+ parsing.
+
+ The second is that we want to be able to print the locus of errors,
+ and an error on line 999999 could conflict with something on line
+ one. Given nonseekable input, we've got to store the whole thing.
+
+ One thing that helps are the column truncation limits that give us
+ an upper bound on the size of individual lines. We don't store the
+ truncated stuff.
+
+ From the scanner's viewpoint, the higher level subroutines ask for
+ new characters and do a lot of jumping backwards. */
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+
+#include "gfortran.h"
+
+/* Structure for holding module and include file search path. */
+typedef struct gfc_directorylist
+{
+ char *path;
+ struct gfc_directorylist *next;
+}
+gfc_directorylist;
+
+/* List of include file search directories. */
+static gfc_directorylist *include_dirs;
+
+static gfc_file *first_file, *first_duplicated_file;
+static int continue_flag, end_flag;
+
+gfc_file *gfc_current_file;
+
+
+/* Main scanner initialization. */
+
+void
+gfc_scanner_init_1 (void)
+{
+
+ gfc_current_file = NULL;
+ first_file = NULL;
+ first_duplicated_file = NULL;
+ end_flag = 0;
+}
+
+
+/* Main scanner destructor. */
+
+void
+gfc_scanner_done_1 (void)
+{
+
+ linebuf *lp, *lp2;
+ gfc_file *fp, *fp2;
+
+ for (fp = first_file; fp; fp = fp2)
+ {
+
+ if (fp->start != NULL)
+ {
+ /* Free linebuf blocks */
+ for (fp2 = fp->next; fp2; fp2 = fp2->next)
+ if (fp->start == fp2->start)
+ fp2->start = NULL;
+
+ for (lp = fp->start; lp; lp = lp2)
+ {
+ lp2 = lp->next;
+ gfc_free (lp);
+ }
+ }
+
+ fp2 = fp->next;
+ gfc_free (fp);
+ }
+
+ for (fp = first_duplicated_file; fp; fp = fp2)
+ {
+ fp2 = fp->next;
+ gfc_free (fp);
+ }
+}
+
+
+/* Adds path to the list pointed to by list. */
+
+void
+gfc_add_include_path (const char *path)
+{
+ gfc_directorylist *dir;
+ const char *p;
+
+ p = path;
+ while (*p == ' ' || *p == '\t') /* someone might do 'gfortran "-I include"' */
+ if (*p++ == '\0')
+ return;
+
+ dir = include_dirs;
+ if (!dir)
+ {
+ dir = include_dirs = gfc_getmem (sizeof (gfc_directorylist));
+ }
+ else
+ {
+ while (dir->next)
+ dir = dir->next;
+
+ dir->next = gfc_getmem (sizeof (gfc_directorylist));
+ dir = dir->next;
+ }
+
+ dir->next = NULL;
+ dir->path = gfc_getmem (strlen (p) + 2);
+ strcpy (dir->path, p);
+ strcat (dir->path, "/"); /* make '/' last character */
+}
+
+
+/* Release resources allocated for options. */
+
+void
+gfc_release_include_path (void)
+{
+ gfc_directorylist *p;
+
+ gfc_free (gfc_option.module_dir);
+ while (include_dirs != NULL)
+ {
+ p = include_dirs;
+ include_dirs = include_dirs->next;
+ gfc_free (p->path);
+ gfc_free (p);
+ }
+}
+
+
+/* Opens file for reading, searching through the include directories
+ given if necessary. */
+
+FILE *
+gfc_open_included_file (const char *name)
+{
+ char fullname[PATH_MAX];
+ gfc_directorylist *p;
+ FILE *f;
+
+ f = gfc_open_file (name);
+ if (f != NULL)
+ return f;
+
+ for (p = include_dirs; p; p = p->next)
+ {
+ if (strlen (p->path) + strlen (name) + 1 > PATH_MAX)
+ continue;
+
+ strcpy (fullname, p->path);
+ strcat (fullname, name);
+
+ f = gfc_open_file (fullname);
+ if (f != NULL)
+ return f;
+ }
+
+ return NULL;
+}
+
+
+/* Return a pointer to the current locus. */
+
+locus *
+gfc_current_locus (void)
+{
+
+ if (gfc_current_file == NULL)
+ return NULL;
+ return &gfc_current_file->loc;
+}
+
+
+/* Let a caller move the current read pointer (backwards). */
+
+void
+gfc_set_locus (locus * lp)
+{
+
+ gfc_current_file->loc = *lp;
+}
+
+
+/* Test to see if we're at the end of the main source file. */
+
+int
+gfc_at_end (void)
+{
+
+ return end_flag;
+}
+
+
+/* Test to see if we're at the end of the current file. */
+
+int
+gfc_at_eof (void)
+{
+
+ if (gfc_at_end ())
+ return 1;
+
+ if (gfc_current_file->start->lines == 0)
+ return 1; /* Null file */
+
+ if (gfc_current_file->loc.lp == NULL)
+ return 1;
+
+ return 0;
+}
+
+
+/* Test to see if we're at the beginning of a new line. */
+
+int
+gfc_at_bol (void)
+{
+ int i;
+
+ if (gfc_at_eof ())
+ return 1;
+
+ i = gfc_current_file->loc.line;
+
+ return gfc_current_file->loc.nextc == gfc_current_file->loc.lp->line[i];
+}
+
+
+/* Test to see if we're at the end of a line. */
+
+int
+gfc_at_eol (void)
+{
+
+ if (gfc_at_eof ())
+ return 1;
+
+ return *gfc_current_file->loc.nextc == '\0';
+}
+
+
+/* Advance the current line pointer to the next line. */
+
+void
+gfc_advance_line (void)
+{
+ locus *locp;
+ linebuf *lp;
+
+ if (gfc_at_end ())
+ return;
+
+ locp = &gfc_current_file->loc;
+ lp = locp->lp;
+ if (lp == NULL)
+ return;
+
+ if (++locp->line >= lp->lines)
+ {
+ locp->lp = lp = lp->next;
+ if (lp == NULL)
+ return; /* End of this file */
+
+ locp->line = 0;
+ }
+
+ locp->nextc = lp->line[locp->line];
+}
+
+
+/* Get the next character from the input, advancing gfc_current_file's
+ locus. When we hit the end of the line or the end of the file, we
+ start returning a '\n' in order to complete the current statement.
+ No Fortran line conventions are implemented here.
+
+ Requiring explicit advances to the next line prevents the parse
+ pointer from being on the wrong line if the current statement ends
+ prematurely. */
+
+static int
+next_char (void)
+{
+ locus *locp;
+ int c;
+
+ /* End the current include level, but not if we're in the middle
+ of processing a continuation. */
+ if (gfc_at_eof ())
+ {
+ if (continue_flag != 0 || gfc_at_end ())
+ return '\n';
+
+ if (gfc_current_file->included_by == NULL)
+ end_flag = 1;
+
+ return '\n';
+ }
+
+ locp = &gfc_current_file->loc;
+ if (locp->nextc == NULL)
+ return '\n';
+
+ c = *locp->nextc++;
+ if (c == '\0')
+ {
+ locp->nextc--; /* Stay stuck on this line */
+ c = '\n';
+ }
+
+ return c;
+}
+
+
+/* Checks the current line buffer to see if it is an include line. If
+ so, we load the new file and prepare to read from it. Include
+ lines happen at a lower level than regular parsing because the
+ string-matching subroutine is far simpler than the normal one.
+
+ We never return a syntax error because a statement like "include = 5"
+ is perfectly legal. We return zero if no include was processed or
+ nonzero if we matched an include. */
+
+int
+gfc_check_include (void)
+{
+ char c, quote, path[PATH_MAX + 1];
+ const char *include;
+ locus start;
+ int i;
+
+ include = "include";
+
+ start = *gfc_current_locus ();
+ gfc_gobble_whitespace ();
+
+ /* Match the 'include' */
+ while (*include != '\0')
+ if (*include++ != gfc_next_char ())
+ goto no_include;
+
+ gfc_gobble_whitespace ();
+
+ quote = next_char ();
+ if (quote != '"' && quote != '\'')
+ goto no_include;
+
+ /* Copy the filename */
+ for (i = 0;;)
+ {
+ c = next_char ();
+ if (c == '\n')
+ goto no_include; /* No close quote */
+ if (c == quote)
+ break;
+
+ /* This shouldn't happen-- PATH_MAX should be way longer than the
+ max line length. */
+
+ if (i >= PATH_MAX)
+ gfc_internal_error ("Pathname of include file is too long at %C");
+
+ path[i++] = c;
+ }
+
+ path[i] = '\0';
+ if (i == 0)
+ goto no_include; /* No filename! */
+
+ /* At this point, we've got a filename to be included. The rest
+ of the include line is ignored */
+
+ gfc_new_file (path, gfc_current_file->form);
+ return 1;
+
+no_include:
+ gfc_set_locus (&start);
+ return 0;
+}
+
+
+/* Skip a comment. When we come here the parse pointer is positioned
+ immediately after the comment character. If we ever implement
+ compiler directives withing comments, here is where we parse the
+ directive. */
+
+static void
+skip_comment_line (void)
+{
+ char c;
+
+ do
+ {
+ c = next_char ();
+ }
+ while (c != '\n');
+
+ gfc_advance_line ();
+}
+
+
+/* Comment lines are null lines, lines containing only blanks or lines
+ on which the first nonblank line is a '!'. */
+
+static void
+skip_free_comments (void)
+{
+ locus start;
+ char c;
+
+ for (;;)
+ {
+ start = *gfc_current_locus ();
+ if (gfc_at_eof ())
+ break;
+
+ do
+ {
+ c = next_char ();
+ }
+ while (gfc_is_whitespace (c));
+
+ if (c == '\n')
+ {
+ gfc_advance_line ();
+ continue;
+ }
+
+ if (c == '!')
+ {
+ skip_comment_line ();
+ continue;
+ }
+
+ break;
+ }
+
+ gfc_set_locus (&start);
+}
+
+
+/* Skip comment lines in fixed source mode. We have the same rules as
+ in skip_free_comment(), except that we can have a 'c', 'C' or '*'
+ in column 1. and a '!' cannot be in* column 6. */
+
+static void
+skip_fixed_comments (void)
+{
+ locus start;
+ int col;
+ char c;
+
+ for (;;)
+ {
+ start = *gfc_current_locus ();
+ if (gfc_at_eof ())
+ break;
+
+ c = next_char ();
+ if (c == '\n')
+ {
+ gfc_advance_line ();
+ continue;
+ }
+
+ if (c == '!' || c == 'c' || c == 'C' || c == '*')
+ {
+ skip_comment_line ();
+ continue;
+ }
+
+ col = 1;
+ do
+ {
+ c = next_char ();
+ col++;
+ }
+ while (gfc_is_whitespace (c));
+
+ if (c == '\n')
+ {
+ gfc_advance_line ();
+ continue;
+ }
+
+ if (col != 6 && c == '!')
+ {
+ skip_comment_line ();
+ continue;
+ }
+
+ break;
+ }
+
+ gfc_set_locus (&start);
+}
+
+
+/* Skips the current line if it is a comment. Assumes that we are at
+ the start of the current line. */
+
+void
+gfc_skip_comments (void)
+{
+
+ if (!gfc_at_bol () || gfc_current_file->form == FORM_FREE)
+ skip_free_comments ();
+ else
+ skip_fixed_comments ();
+}
+
+
+/* Get the next character from the input, taking continuation lines
+ and end-of-line comments into account. This implies that comment
+ lines between continued lines must be eaten here. For higher-level
+ subroutines, this flattens continued lines into a single logical
+ line. The in_string flag denotes whether we're inside a character
+ context or not. */
+
+int
+gfc_next_char_literal (int in_string)
+{
+ locus old_loc;
+ int i, c;
+
+ continue_flag = 0;
+
+restart:
+ c = next_char ();
+ if (gfc_at_end ())
+ return c;
+
+ if (gfc_current_file->form == FORM_FREE)
+ {
+
+ if (!in_string && c == '!')
+ {
+ /* This line can't be continued */
+ do
+ {
+ c = next_char ();
+ }
+ while (c != '\n');
+
+ goto done;
+ }
+
+ if (c != '&')
+ goto done;
+
+ /* If the next nonblank character is a ! or \n, we've got a
+ continuation line. */
+ old_loc = gfc_current_file->loc;
+
+ c = next_char ();
+ while (gfc_is_whitespace (c))
+ c = next_char ();
+
+ /* Character constants to be continued cannot have commentary
+ after the '&'. */
+
+ if (in_string && c != '\n')
+ {
+ gfc_set_locus (&old_loc);
+ c = '&';
+ goto done;
+ }
+
+ if (c != '!' && c != '\n')
+ {
+ gfc_set_locus (&old_loc);
+ c = '&';
+ goto done;
+ }
+
+ continue_flag = 1;
+ if (c == '!')
+ skip_comment_line ();
+ else
+ gfc_advance_line ();
+
+ /* We've got a continuation line and need to find where it continues.
+ First eat any comment lines. */
+ gfc_skip_comments ();
+
+ /* Now that we have a non-comment line, probe ahead for the
+ first non-whitespace character. If it is another '&', then
+ reading starts at the next character, otherwise we must back
+ up to where the whitespace started and resume from there. */
+
+ old_loc = *gfc_current_locus ();
+
+ c = next_char ();
+ while (gfc_is_whitespace (c))
+ c = next_char ();
+
+ if (c != '&')
+ gfc_set_locus (&old_loc);
+
+ }
+ else
+ {
+ /* Fixed form continuation. */
+ if (!in_string && c == '!')
+ {
+ /* Skip comment at end of line. */
+ do
+ {
+ c = next_char ();
+ }
+ while (c != '\n');
+ }
+
+ if (c != '\n')
+ goto done;
+
+ continue_flag = 1;
+ old_loc = *gfc_current_locus ();
+
+ gfc_advance_line ();
+ gfc_skip_comments ();
+
+ /* See if this line is a continuation line. */
+ for (i = 0; i < 5; i++)
+ {
+ c = next_char ();
+ if (c != ' ')
+ goto not_continuation;
+ }
+
+ c = next_char ();
+ if (c == '0' || c == ' ')
+ goto not_continuation;
+ }
+
+ /* Ready to read first character of continuation line, which might
+ be another continuation line! */
+ goto restart;
+
+not_continuation:
+ c = '\n';
+ gfc_set_locus (&old_loc);
+
+done:
+ continue_flag = 0;
+ return c;
+}
+
+
+/* Get the next character of input, folded to lowercase. In fixed
+ form mode, we also ignore spaces. When matcher subroutines are
+ parsing character literals, they have to call
+ gfc_next_char_literal(). */
+
+int
+gfc_next_char (void)
+{
+ int c;
+
+ do
+ {
+ c = gfc_next_char_literal (0);
+ }
+ while (gfc_current_file->form == FORM_FIXED && gfc_is_whitespace (c));
+
+ return TOLOWER (c);
+}
+
+
+int
+gfc_peek_char (void)
+{
+ locus old_loc;
+ int c;
+
+ old_loc = *gfc_current_locus ();
+ c = gfc_next_char ();
+ gfc_set_locus (&old_loc);
+
+ return c;
+}
+
+
+/* Recover from an error. We try to get past the current statement
+ and get lined up for the next. The next statement follows a '\n'
+ or a ';'. We also assume that we are not within a character
+ constant, and deal with finding a '\'' or '"'. */
+
+void
+gfc_error_recovery (void)
+{
+ char c, delim;
+
+ if (gfc_at_eof ())
+ return;
+
+ for (;;)
+ {
+ c = gfc_next_char ();
+ if (c == '\n' || c == ';')
+ break;
+
+ if (c != '\'' && c != '"')
+ {
+ if (gfc_at_eof ())
+ break;
+ continue;
+ }
+ delim = c;
+
+ for (;;)
+ {
+ c = next_char ();
+
+ if (c == delim)
+ break;
+ if (c == '\n')
+ goto done;
+ if (c == '\\')
+ {
+ c = next_char ();
+ if (c == '\n')
+ goto done;
+ }
+ }
+ if (gfc_at_eof ())
+ break;
+ }
+
+done:
+ if (c == '\n')
+ gfc_advance_line ();
+}
+
+
+/* Read ahead until the next character to be read is not whitespace. */
+
+void
+gfc_gobble_whitespace (void)
+{
+ locus old_loc;
+ int c;
+
+ do
+ {
+ old_loc = *gfc_current_locus ();
+ c = gfc_next_char_literal (0);
+ }
+ while (gfc_is_whitespace (c));
+
+ gfc_set_locus (&old_loc);
+}
+
+
+/* Load a single line into the buffer. We truncate lines that are too
+ long. In fixed mode, we expand a tab that occurs within the
+ statement label region to expand to spaces that leave the next
+ character in the source region. */
+
+static void
+load_line (FILE * input, gfc_source_form form, char *buffer,
+ char *filename, int linenum)
+{
+ int c, maxlen, i, trunc_flag;
+
+ maxlen = (form == FORM_FREE) ? 132 : gfc_option.fixed_line_length;
+
+ i = 0;
+
+ for (;;)
+ {
+ c = fgetc (input);
+
+ if (c == EOF)
+ break;
+ if (c == '\n')
+ break;
+
+ if (c == '\r')
+ continue; /* Gobble characters */
+ if (c == '\0')
+ continue;
+
+ if (form == FORM_FIXED && c == '\t' && i <= 6)
+ { /* Tab expandsion */
+ while (i <= 6)
+ {
+ *buffer++ = ' ';
+ i++;
+ }
+
+ continue;
+ }
+
+ *buffer++ = c;
+ i++;
+
+ if (i >= maxlen)
+ { /* Truncate the rest of the line */
+ trunc_flag = 1;
+
+ for (;;)
+ {
+ c = fgetc (input);
+ if (c == '\n' || c == EOF)
+ break;
+
+ if (gfc_option.warn_line_truncation
+ && trunc_flag
+ && !gfc_is_whitespace (c))
+ {
+ gfc_warning_now ("Line %d of %s is being truncated",
+ linenum, filename);
+ trunc_flag = 0;
+ }
+ }
+
+ ungetc ('\n', input);
+ }
+ }
+
+ *buffer = '\0';
+}
+
+
+/* Load a file into memory by calling load_line until the file ends. */
+
+static void
+load_file (FILE * input, gfc_file * fp)
+{
+ char *linep, line[GFC_MAX_LINE + 1];
+ int len, linenum;
+ linebuf *lp;
+
+ fp->start = lp = gfc_getmem (sizeof (linebuf));
+
+ linenum = 1;
+ lp->lines = 0;
+ lp->start_line = 1;
+ lp->next = NULL;
+
+ linep = (char *) (lp + 1);
+
+ /* Load the file. */
+ for (;;)
+ {
+ load_line (input, fp->form, line, fp->filename, linenum);
+ linenum++;
+
+ len = strlen (line);
+
+ if (feof (input) && len == 0)
+ break;
+
+ /* See if we need another linebuf. */
+ if (((char *) &lp->line[lp->lines + 2]) > linep - len - 1)
+ {
+ lp->next = gfc_getmem (sizeof (linebuf));
+
+ lp->next->start_line = lp->start_line + lp->lines;
+ lp = lp->next;
+ lp->lines = 0;
+
+ linep = (char *) (lp + 1);
+ }
+
+ linep = linep - len - 1;
+ lp->line[lp->lines++] = linep;
+ strcpy (linep, line);
+ }
+}
+
+
+/* Determine the source form from the filename extension. We assume
+ case insensitivity. */
+
+static gfc_source_form
+form_from_filename (const char *filename)
+{
+
+ static const struct
+ {
+ const char *extension;
+ gfc_source_form form;
+ }
+ exttype[] =
+ {
+ {
+ ".f90", FORM_FREE}
+ ,
+ {
+ ".f95", FORM_FREE}
+ ,
+ {
+ ".f", FORM_FIXED}
+ ,
+ {
+ ".for", FORM_FIXED}
+ ,
+ {
+ "", FORM_UNKNOWN}
+ }; /* sentinel value */
+
+ gfc_source_form f_form;
+ const char *fileext;
+ int i;
+
+ /* Find end of file name. */
+ i = 0;
+ while ((i < PATH_MAX) && (filename[i] != '\0'))
+ i++;
+
+ /* Improperly terminated or too-long filename. */
+ if (i == PATH_MAX)
+ return FORM_UNKNOWN;
+
+ /* Find last period. */
+ while (i >= 0 && (filename[i] != '.'))
+ i--;
+
+ /* Did we see a file extension? */
+ if (i < 0)
+ return FORM_UNKNOWN; /* Nope */
+
+ /* Get file extension and compare it to others. */
+ fileext = &(filename[i]);
+
+ i = -1;
+ f_form = FORM_UNKNOWN;
+ do
+ {
+ i++;
+ if (strcasecmp (fileext, exttype[i].extension) == 0)
+ {
+ f_form = exttype[i].form;
+ break;
+ }
+ }
+ while (exttype[i].form != FORM_UNKNOWN);
+
+ return f_form;
+}
+
+
+/* Open a new file and start scanning from that file. Every new file
+ gets a gfc_file node, even if it is a duplicate file. Returns SUCCESS
+ if everything went OK, FAILURE otherwise. */
+
+try
+gfc_new_file (const char *filename, gfc_source_form form)
+{
+ gfc_file *fp, *fp2;
+ FILE *input;
+ int len;
+
+ len = strlen (filename);
+ if (len > PATH_MAX)
+ {
+ gfc_error_now ("Filename '%s' is too long- ignoring it", filename);
+ return FAILURE;
+ }
+
+ fp = gfc_getmem (sizeof (gfc_file));
+
+ /* Make sure this file isn't being included recursively. */
+ for (fp2 = gfc_current_file; fp2; fp2 = fp2->included_by)
+ if (strcmp (filename, fp2->filename) == 0)
+ {
+ gfc_error_now ("Recursive inclusion of file '%s' at %C- ignoring it",
+ filename);
+ gfc_free (fp);
+ return FAILURE;
+ }
+
+ /* See if the file has already been included. */
+ for (fp2 = first_file; fp2; fp2 = fp2->next)
+ if (strcmp (filename, fp2->filename) == 0)
+ {
+ *fp = *fp2;
+ fp->next = first_duplicated_file;
+ first_duplicated_file = fp;
+ goto init_fp;
+ }
+
+ strcpy (fp->filename, filename);
+
+ if (gfc_current_file == NULL)
+ input = gfc_open_file (filename);
+ else
+ input = gfc_open_included_file (filename);
+
+ if (input == NULL)
+ {
+ if (gfc_current_file == NULL)
+ gfc_error_now ("Can't open file '%s'", filename);
+ else
+ gfc_error_now ("Can't open file '%s' included at %C", filename);
+
+ gfc_free (fp);
+ return FAILURE;
+ }
+
+ /* Decide which form the file will be read in as. */
+ if (form != FORM_UNKNOWN)
+ fp->form = form;
+ else
+ {
+ fp->form = form_from_filename (filename);
+
+ if (fp->form == FORM_UNKNOWN)
+ {
+ fp->form = FORM_FREE;
+ gfc_warning_now ("Reading file %s as free form", filename);
+ }
+ }
+
+ fp->next = first_file;
+ first_file = fp;
+
+ load_file (input, fp);
+ fclose (input);
+
+init_fp:
+ fp->included_by = gfc_current_file;
+ gfc_current_file = fp;
+
+ fp->loc.line = 0;
+ fp->loc.lp = fp->start;
+ fp->loc.nextc = fp->start->line[0];
+ fp->loc.file = fp;
+
+ return SUCCESS;
+}
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
new file mode 100644
index 00000000000..2ce86a38e7e
--- /dev/null
+++ b/gcc/fortran/simplify.c
@@ -0,0 +1,4009 @@
+/* Simplify intrinsic functions at compile-time.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation,
+ Inc.
+ Contributed by Andy Vaught & Katherine Holcomb
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "flags.h"
+
+#include <string.h>
+
+#include "gfortran.h"
+#include "arith.h"
+#include "intrinsic.h"
+
+static mpf_t mpf_zero, mpf_half, mpf_one;
+static mpz_t mpz_zero;
+
+gfc_expr gfc_bad_expr;
+
+
+/* Note that 'simplification' is not just transforming expressions.
+ For functions that are not simplified at compile time, range
+ checking is done if possible.
+
+ The return convention is that each simplification function returns:
+
+ A new expression node corresponding to the simplified arguments.
+ The original arguments are destroyed by the caller, and must not
+ be a part of the new expression.
+
+ NULL pointer indicating that no simplification was possible and
+ the original expression should remain intact. If the
+ simplification function sets the type and/or the function name
+ via the pointer gfc_simple_expression, then this type is
+ retained.
+
+ An expression pointer to gfc_bad_expr (a static placeholder)
+ indicating that some error has prevented simplification. For
+ example, sqrt(-1.0). The error is generated within the function
+ and should be propagated upwards
+
+ By the time a simplification function gets control, it has been
+ decided that the function call is really supposed to be the
+ intrinsic. No type checking is strictly necessary, since only
+ valid types will be passed on. On the other hand, a simplification
+ subroutine may have to look at the type of an argument as part of
+ its processing.
+
+ Array arguments are never passed to these subroutines.
+
+ The functions in this file don't have much comment with them, but
+ everything is reasonably straight-forward. The Standard, chapter 13
+ is the best comment you'll find for this file anyway. */
+
+/* Static table for converting non-ascii character sets to ascii.
+ The xascii_table[] is the inverse table. */
+
+static int ascii_table[256] = {
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\b', '\t', '\n', '\v', '\0', '\r', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ ' ', '!', '\'', '#', '$', '%', '&', '\'',
+ '(', ')', '*', '+', ',', '-', '.', '/',
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', ':', ';', '<', '=', '>', '?',
+ '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
+ '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', '{', '|', '}', '~', '\?'
+};
+
+static int xascii_table[256];
+
+
+/* Range checks an expression node. If all goes well, returns the
+ node, otherwise returns &gfc_bad_expr and frees the node. */
+
+static gfc_expr *
+range_check (gfc_expr * result, const char *name)
+{
+
+ if (gfc_range_check (result) == ARITH_OK)
+ return result;
+
+ gfc_error ("Result of %s overflows its kind at %L", name, &result->where);
+ gfc_free_expr (result);
+ return &gfc_bad_expr;
+}
+
+
+/* A helper function that gets an optional and possibly missing
+ kind parameter. Returns the kind, -1 if something went wrong. */
+
+static int
+get_kind (bt type, gfc_expr * k, const char *name, int default_kind)
+{
+ int kind;
+
+ if (k == NULL)
+ return default_kind;
+
+ if (k->expr_type != EXPR_CONSTANT)
+ {
+ gfc_error ("KIND parameter of %s at %L must be an initialization "
+ "expression", name, &k->where);
+
+ return -1;
+ }
+
+ if (gfc_extract_int (k, &kind) != NULL
+ || gfc_validate_kind (type, kind) == -1)
+ {
+
+ gfc_error ("Invalid KIND parameter of %s at %L", name, &k->where);
+ return -1;
+ }
+
+ return kind;
+}
+
+
+/********************** Simplification functions *****************************/
+
+gfc_expr *
+gfc_simplify_abs (gfc_expr * e)
+{
+ gfc_expr *result;
+ mpf_t a, b;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ switch (e->ts.type)
+ {
+ case BT_INTEGER:
+ result = gfc_constant_result (BT_INTEGER, e->ts.kind, &e->where);
+
+ mpz_abs (result->value.integer, e->value.integer);
+
+ result = range_check (result, "IABS");
+ break;
+
+ case BT_REAL:
+ result = gfc_constant_result (BT_REAL, e->ts.kind, &e->where);
+
+ mpf_abs (result->value.real, e->value.real);
+
+ result = range_check (result, "ABS");
+ break;
+
+ case BT_COMPLEX:
+ result = gfc_constant_result (BT_REAL, e->ts.kind, &e->where);
+
+ mpf_init (a);
+ mpf_mul (a, e->value.complex.r, e->value.complex.r);
+
+ mpf_init (b);
+ mpf_mul (b, e->value.complex.i, e->value.complex.i);
+
+ mpf_add (a, a, b);
+ mpf_sqrt (result->value.real, a);
+
+ mpf_clear (a);
+ mpf_clear (b);
+
+ result = range_check (result, "CABS");
+ break;
+
+ default:
+ gfc_internal_error ("gfc_simplify_abs(): Bad type");
+ }
+
+ return result;
+}
+
+
+gfc_expr *
+gfc_simplify_achar (gfc_expr * e)
+{
+ gfc_expr *result;
+ int index;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ /* We cannot assume that the native character set is ASCII in this
+ function. */
+ if (gfc_extract_int (e, &index) != NULL || index < 0 || index > 127)
+ {
+ gfc_error ("Extended ASCII not implemented: argument of ACHAR at %L "
+ "must be between 0 and 127", &e->where);
+ return &gfc_bad_expr;
+ }
+
+ result = gfc_constant_result (BT_CHARACTER, gfc_default_character_kind (),
+ &e->where);
+
+ result->value.character.string = gfc_getmem (2);
+
+ result->value.character.length = 1;
+ result->value.character.string[0] = ascii_table[index];
+ result->value.character.string[1] = '\0'; /* For debugger */
+ return result;
+}
+
+
+gfc_expr *
+gfc_simplify_acos (gfc_expr * x)
+{
+ gfc_expr *result;
+ mpf_t negative, square, term;
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ if (mpf_cmp_si (x->value.real, 1) > 0 || mpf_cmp_si (x->value.real, -1) < 0)
+ {
+ gfc_error ("Argument of ACOS at %L must be between -1 and 1",
+ &x->where);
+ return &gfc_bad_expr;
+ }
+
+ result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+
+ if (mpf_cmp_si (x->value.real, 1) == 0)
+ {
+ mpf_set_ui (result->value.real, 0);
+ return range_check (result, "ACOS");
+ }
+
+ if (mpf_cmp_si (x->value.real, -1) == 0)
+ {
+ mpf_set (result->value.real, pi);
+ return range_check (result, "ACOS");
+ }
+
+ mpf_init (negative);
+ mpf_init (square);
+ mpf_init (term);
+
+ mpf_pow_ui (square, x->value.real, 2);
+ mpf_ui_sub (term, 1, square);
+ mpf_sqrt (term, term);
+ mpf_div (term, x->value.real, term);
+ mpf_neg (term, term);
+ arctangent (&term, &negative);
+ mpf_add (result->value.real, half_pi, negative);
+
+ mpf_clear (negative);
+ mpf_clear (square);
+ mpf_clear (term);
+
+ return range_check (result, "ACOS");
+}
+
+
+gfc_expr *
+gfc_simplify_adjustl (gfc_expr * e)
+{
+ gfc_expr *result;
+ int count, i, len;
+ char ch;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ len = e->value.character.length;
+
+ result = gfc_constant_result (BT_CHARACTER, e->ts.kind, &e->where);
+
+ result->value.character.length = len;
+ result->value.character.string = gfc_getmem (len + 1);
+
+ for (count = 0, i = 0; i < len; ++i)
+ {
+ ch = e->value.character.string[i];
+ if (ch != ' ')
+ break;
+ ++count;
+ }
+
+ for (i = 0; i < len - count; ++i)
+ {
+ result->value.character.string[i] =
+ e->value.character.string[count + i];
+ }
+
+ for (i = len - count; i < len; ++i)
+ {
+ result->value.character.string[i] = ' ';
+ }
+
+ result->value.character.string[len] = '\0'; /* For debugger */
+
+ return result;
+}
+
+
+gfc_expr *
+gfc_simplify_adjustr (gfc_expr * e)
+{
+ gfc_expr *result;
+ int count, i, len;
+ char ch;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ len = e->value.character.length;
+
+ result = gfc_constant_result (BT_CHARACTER, e->ts.kind, &e->where);
+
+ result->value.character.length = len;
+ result->value.character.string = gfc_getmem (len + 1);
+
+ for (count = 0, i = len - 1; i >= 0; --i)
+ {
+ ch = e->value.character.string[i];
+ if (ch != ' ')
+ break;
+ ++count;
+ }
+
+ for (i = 0; i < count; ++i)
+ {
+ result->value.character.string[i] = ' ';
+ }
+
+ for (i = count; i < len; ++i)
+ {
+ result->value.character.string[i] =
+ e->value.character.string[i - count];
+ }
+
+ result->value.character.string[len] = '\0'; /* For debugger */
+
+ return result;
+}
+
+
+gfc_expr *
+gfc_simplify_aimag (gfc_expr * e)
+{
+ gfc_expr *result;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (BT_REAL, e->ts.kind, &e->where);
+ mpf_set (result->value.real, e->value.complex.i);
+
+ return range_check (result, "AIMAG");
+}
+
+
+gfc_expr *
+gfc_simplify_aint (gfc_expr * e, gfc_expr * k)
+{
+ gfc_expr *rtrunc, *result;
+ int kind;
+
+ kind = get_kind (BT_REAL, k, "AINT", e->ts.kind);
+ if (kind == -1)
+ return &gfc_bad_expr;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ rtrunc = gfc_copy_expr (e);
+
+ mpf_trunc (rtrunc->value.real, e->value.real);
+
+ result = gfc_real2real (rtrunc, kind);
+ gfc_free_expr (rtrunc);
+
+ return range_check (result, "AINT");
+}
+
+
+gfc_expr *
+gfc_simplify_dint (gfc_expr * e)
+{
+ gfc_expr *rtrunc, *result;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ rtrunc = gfc_copy_expr (e);
+
+ mpf_trunc (rtrunc->value.real, e->value.real);
+
+ result = gfc_real2real (rtrunc, gfc_default_double_kind ());
+ gfc_free_expr (rtrunc);
+
+ return range_check (result, "DINT");
+
+}
+
+
+gfc_expr *
+gfc_simplify_anint (gfc_expr * e, gfc_expr * k)
+{
+ gfc_expr *rtrunc, *result;
+ int kind, cmp;
+
+ kind = get_kind (BT_REAL, k, "ANINT", e->ts.kind);
+ if (kind == -1)
+ return &gfc_bad_expr;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (e->ts.type, kind, &e->where);
+
+ rtrunc = gfc_copy_expr (e);
+
+ cmp = mpf_cmp_ui (e->value.real, 0);
+
+ if (cmp > 0)
+ {
+ mpf_add (rtrunc->value.real, e->value.real, mpf_half);
+ mpf_trunc (result->value.real, rtrunc->value.real);
+ }
+ else if (cmp < 0)
+ {
+ mpf_sub (rtrunc->value.real, e->value.real, mpf_half);
+ mpf_trunc (result->value.real, rtrunc->value.real);
+ }
+ else
+ mpf_set_ui (result->value.real, 0);
+
+ gfc_free_expr (rtrunc);
+
+ return range_check (result, "ANINT");
+}
+
+
+gfc_expr *
+gfc_simplify_dnint (gfc_expr * e)
+{
+ gfc_expr *rtrunc, *result;
+ int cmp;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result =
+ gfc_constant_result (BT_REAL, gfc_default_double_kind (), &e->where);
+
+ rtrunc = gfc_copy_expr (e);
+
+ cmp = mpf_cmp_ui (e->value.real, 0);
+
+ if (cmp > 0)
+ {
+ mpf_add (rtrunc->value.real, e->value.real, mpf_half);
+ mpf_trunc (result->value.real, rtrunc->value.real);
+ }
+ else if (cmp < 0)
+ {
+ mpf_sub (rtrunc->value.real, e->value.real, mpf_half);
+ mpf_trunc (result->value.real, rtrunc->value.real);
+ }
+ else
+ mpf_set_ui (result->value.real, 0);
+
+ gfc_free_expr (rtrunc);
+
+ return range_check (result, "DNINT");
+}
+
+
+gfc_expr *
+gfc_simplify_asin (gfc_expr * x)
+{
+ gfc_expr *result;
+ mpf_t negative, square, term;
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ if (mpf_cmp_si (x->value.real, 1) > 0 || mpf_cmp_si (x->value.real, -1) < 0)
+ {
+ gfc_error ("Argument of ASIN at %L must be between -1 and 1",
+ &x->where);
+ return &gfc_bad_expr;
+ }
+
+ result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+
+ if (mpf_cmp_si (x->value.real, 1) == 0)
+ {
+ mpf_set (result->value.real, half_pi);
+ return range_check (result, "ASIN");
+ }
+
+ if (mpf_cmp_si (x->value.real, -1) == 0)
+ {
+ mpf_init (negative);
+ mpf_neg (negative, half_pi);
+ mpf_set (result->value.real, negative);
+ mpf_clear (negative);
+ return range_check (result, "ASIN");
+ }
+
+ mpf_init (square);
+ mpf_init (term);
+
+ mpf_pow_ui (square, x->value.real, 2);
+ mpf_ui_sub (term, 1, square);
+ mpf_sqrt (term, term);
+ mpf_div (term, x->value.real, term);
+ arctangent (&term, &result->value.real);
+
+ mpf_clear (square);
+ mpf_clear (term);
+
+ return range_check (result, "ASIN");
+}
+
+
+gfc_expr *
+gfc_simplify_atan (gfc_expr * x)
+{
+ gfc_expr *result;
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+
+ arctangent (&x->value.real, &result->value.real);
+
+ return range_check (result, "ATAN");
+
+}
+
+
+gfc_expr *
+gfc_simplify_atan2 (gfc_expr * y, gfc_expr * x)
+{
+ gfc_expr *result;
+
+ if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+
+
+ if (mpf_sgn (y->value.real) == 0 && mpf_sgn (x->value.real) == 0)
+ {
+ gfc_error
+ ("If first argument of ATAN2 %L is zero, the second argument "
+ "must not be zero", &x->where);
+ gfc_free_expr (result);
+ return &gfc_bad_expr;
+ }
+
+ arctangent2 (&y->value.real, &x->value.real, &result->value.real);
+
+ return range_check (result, "ATAN2");
+
+}
+
+
+gfc_expr *
+gfc_simplify_bit_size (gfc_expr * e)
+{
+ gfc_expr *result;
+ int i;
+
+ i = gfc_validate_kind (e->ts.type, e->ts.kind);
+ if (i == -1)
+ gfc_internal_error ("In gfc_simplify_bit_size(): Bad kind");
+
+ result = gfc_constant_result (BT_INTEGER, e->ts.kind, &e->where);
+ mpz_set_ui (result->value.integer, gfc_integer_kinds[i].bit_size);
+
+ return result;
+}
+
+
+gfc_expr *
+gfc_simplify_btest (gfc_expr * e, gfc_expr * bit)
+{
+ int b;
+
+ if (e->expr_type != EXPR_CONSTANT || bit->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ if (gfc_extract_int (bit, &b) != NULL || b < 0)
+ return gfc_logical_expr (0, &e->where);
+
+ return gfc_logical_expr (mpz_tstbit (e->value.integer, b), &e->where);
+}
+
+
+gfc_expr *
+gfc_simplify_ceiling (gfc_expr * e, gfc_expr * k)
+{
+ gfc_expr *ceil, *result;
+ int kind;
+
+ kind = get_kind (BT_REAL, k, "CEILING", gfc_default_real_kind ());
+ if (kind == -1)
+ return &gfc_bad_expr;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (BT_INTEGER, kind, &e->where);
+
+ ceil = gfc_copy_expr (e);
+
+ mpf_ceil (ceil->value.real, e->value.real);
+ mpz_set_f (result->value.integer, ceil->value.real);
+
+ gfc_free_expr (ceil);
+
+ return range_check (result, "CEILING");
+}
+
+
+gfc_expr *
+gfc_simplify_char (gfc_expr * e, gfc_expr * k)
+{
+ gfc_expr *result;
+ int c, kind;
+
+ kind = get_kind (BT_CHARACTER, k, "CHAR", gfc_default_character_kind ());
+ if (kind == -1)
+ return &gfc_bad_expr;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ if (gfc_extract_int (e, &c) != NULL || c < 0 || c > 255)
+ {
+ gfc_error ("Bad character in CHAR function at %L", &e->where);
+ return &gfc_bad_expr;
+ }
+
+ result = gfc_constant_result (BT_CHARACTER, kind, &e->where);
+
+ result->value.character.length = 1;
+ result->value.character.string = gfc_getmem (2);
+
+ result->value.character.string[0] = c;
+ result->value.character.string[1] = '\0'; /* For debugger */
+
+ return result;
+}
+
+
+/* Common subroutine for simplifying CMPLX and DCMPLX. */
+
+static gfc_expr *
+simplify_cmplx (const char *name, gfc_expr * x, gfc_expr * y, int kind)
+{
+ gfc_expr *result;
+
+ result = gfc_constant_result (BT_COMPLEX, kind, &x->where);
+
+ mpf_set_ui (result->value.complex.i, 0);
+
+ switch (x->ts.type)
+ {
+ case BT_INTEGER:
+ mpf_set_z (result->value.complex.r, x->value.integer);
+ break;
+
+ case BT_REAL:
+ mpf_set (result->value.complex.r, x->value.real);
+ break;
+
+ case BT_COMPLEX:
+ mpf_set (result->value.complex.r, x->value.complex.r);
+ mpf_set (result->value.complex.i, x->value.complex.i);
+ break;
+
+ default:
+ gfc_internal_error ("gfc_simplify_dcmplx(): Bad type (x)");
+ }
+
+ if (y != NULL)
+ {
+ switch (y->ts.type)
+ {
+ case BT_INTEGER:
+ mpf_set_z (result->value.complex.i, y->value.integer);
+ break;
+
+ case BT_REAL:
+ mpf_set (result->value.complex.i, y->value.real);
+ break;
+
+ default:
+ gfc_internal_error ("gfc_simplify_dcmplx(): Bad type (y)");
+ }
+ }
+
+ return range_check (result, name);
+}
+
+
+gfc_expr *
+gfc_simplify_cmplx (gfc_expr * x, gfc_expr * y, gfc_expr * k)
+{
+ int kind;
+
+ if (x->expr_type != EXPR_CONSTANT
+ || (y != NULL && y->expr_type != EXPR_CONSTANT))
+ return NULL;
+
+ kind = get_kind (BT_REAL, k, "CMPLX", gfc_default_real_kind ());
+ if (kind == -1)
+ return &gfc_bad_expr;
+
+ return simplify_cmplx ("CMPLX", x, y, kind);
+}
+
+
+gfc_expr *
+gfc_simplify_conjg (gfc_expr * e)
+{
+ gfc_expr *result;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_copy_expr (e);
+ mpf_neg (result->value.complex.i, result->value.complex.i);
+
+ return range_check (result, "CONJG");
+}
+
+
+gfc_expr *
+gfc_simplify_cos (gfc_expr * x)
+{
+ gfc_expr *result;
+ mpf_t xp, xq;
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+
+ switch (x->ts.type)
+ {
+ case BT_REAL:
+ cosine (&x->value.real, &result->value.real);
+ break;
+ case BT_COMPLEX:
+ mpf_init (xp);
+ mpf_init (xq);
+
+ cosine (&x->value.complex.r, &xp);
+ hypercos (&x->value.complex.i, &xq);
+ mpf_mul (result->value.complex.r, xp, xq);
+
+ sine (&x->value.complex.r, &xp);
+ hypersine (&x->value.complex.i, &xq);
+ mpf_mul (xp, xp, xq);
+ mpf_neg (result->value.complex.i, xp);
+
+ mpf_clear (xp);
+ mpf_clear (xq);
+ break;
+ default:
+ gfc_internal_error ("in gfc_simplify_cos(): Bad type");
+ }
+
+ return range_check (result, "COS");
+
+}
+
+
+gfc_expr *
+gfc_simplify_cosh (gfc_expr * x)
+{
+ gfc_expr *result;
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+
+ hypercos (&x->value.real, &result->value.real);
+
+ return range_check (result, "COSH");
+}
+
+
+gfc_expr *
+gfc_simplify_dcmplx (gfc_expr * x, gfc_expr * y)
+{
+
+ if (x->expr_type != EXPR_CONSTANT
+ || (y != NULL && y->expr_type != EXPR_CONSTANT))
+ return NULL;
+
+ return simplify_cmplx ("DCMPLX", x, y, gfc_default_double_kind ());
+}
+
+
+gfc_expr *
+gfc_simplify_dble (gfc_expr * e)
+{
+ gfc_expr *result;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ switch (e->ts.type)
+ {
+ case BT_INTEGER:
+ result = gfc_int2real (e, gfc_default_double_kind ());
+ break;
+
+ case BT_REAL:
+ result = gfc_real2real (e, gfc_default_double_kind ());
+ break;
+
+ case BT_COMPLEX:
+ result = gfc_complex2real (e, gfc_default_double_kind ());
+ break;
+
+ default:
+ gfc_internal_error ("gfc_simplify_dble(): bad type at %L", &e->where);
+ }
+
+ return range_check (result, "DBLE");
+}
+
+
+gfc_expr *
+gfc_simplify_digits (gfc_expr * x)
+{
+ int i, digits;
+
+ i = gfc_validate_kind (x->ts.type, x->ts.kind);
+ if (i == -1)
+ goto bad;
+
+ switch (x->ts.type)
+ {
+ case BT_INTEGER:
+ digits = gfc_integer_kinds[i].digits;
+ break;
+
+ case BT_REAL:
+ case BT_COMPLEX:
+ digits = gfc_real_kinds[i].digits;
+ break;
+
+ default:
+ bad:
+ gfc_internal_error ("gfc_simplify_digits(): Bad type");
+ }
+
+ return gfc_int_expr (digits);
+}
+
+
+gfc_expr *
+gfc_simplify_dim (gfc_expr * x, gfc_expr * y)
+{
+ gfc_expr *result;
+
+ if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+
+ switch (x->ts.type)
+ {
+ case BT_INTEGER:
+ if (mpz_cmp (x->value.integer, y->value.integer) > 0)
+ mpz_sub (result->value.integer, x->value.integer, y->value.integer);
+ else
+ mpz_set (result->value.integer, mpz_zero);
+
+ break;
+
+ case BT_REAL:
+ if (mpf_cmp (x->value.real, y->value.real) > 0)
+ mpf_sub (result->value.real, x->value.real, y->value.real);
+ else
+ mpf_set (result->value.real, mpf_zero);
+
+ break;
+
+ default:
+ gfc_internal_error ("gfc_simplify_dim(): Bad type");
+ }
+
+ return range_check (result, "DIM");
+}
+
+
+gfc_expr *
+gfc_simplify_dprod (gfc_expr * x, gfc_expr * y)
+{
+ gfc_expr *mult1, *mult2, *result;
+
+ if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result =
+ gfc_constant_result (BT_REAL, gfc_default_double_kind (), &x->where);
+
+ mult1 = gfc_real2real (x, gfc_default_double_kind ());
+ mult2 = gfc_real2real (y, gfc_default_double_kind ());
+
+ mpf_mul (result->value.real, mult1->value.real, mult2->value.real);
+
+ gfc_free_expr (mult1);
+ gfc_free_expr (mult2);
+
+ return range_check (result, "DPROD");
+}
+
+
+gfc_expr *
+gfc_simplify_epsilon (gfc_expr * e)
+{
+ gfc_expr *result;
+ int i;
+
+ i = gfc_validate_kind (e->ts.type, e->ts.kind);
+ if (i == -1)
+ gfc_internal_error ("gfc_simplify_epsilon(): Bad kind");
+
+ result = gfc_constant_result (BT_REAL, e->ts.kind, &e->where);
+
+ mpf_set (result->value.real, gfc_real_kinds[i].epsilon);
+
+ return range_check (result, "EPSILON");
+}
+
+
+gfc_expr *
+gfc_simplify_exp (gfc_expr * x)
+{
+ gfc_expr *result;
+ mpf_t xp, xq;
+ double ln2, absval, rhuge;
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+
+ /* Exactitude doesn't matter here */
+ ln2 = .6931472;
+ rhuge = ln2 * mpz_get_d (gfc_integer_kinds[0].huge);
+
+ switch (x->ts.type)
+ {
+ case BT_REAL:
+ absval = mpf_get_d (x->value.real);
+ if (absval < 0)
+ absval = -absval;
+ if (absval > rhuge)
+ {
+ /* Underflow (set arg to zero) if x is negative and its
+ magnitude is greater than the maximum C long int times
+ ln2, because the exponential method in arith.c will fail
+ for such values. */
+ if (mpf_cmp_ui (x->value.real, 0) < 0)
+ {
+ if (pedantic == 1)
+ gfc_warning_now
+ ("Argument of EXP at %L is negative and too large, "
+ "setting result to zero", &x->where);
+ mpf_set_ui (result->value.real, 0);
+ return range_check (result, "EXP");
+ }
+ /* Overflow if magnitude of x is greater than C long int
+ huge times ln2. */
+ else
+ {
+ gfc_error ("Argument of EXP at %L too large", &x->where);
+ gfc_free_expr (result);
+ return &gfc_bad_expr;
+ }
+ }
+ exponential (&x->value.real, &result->value.real);
+ break;
+
+ case BT_COMPLEX:
+ /* Using Euler's formula. */
+ absval = mpf_get_d (x->value.complex.r);
+ if (absval < 0)
+ absval = -absval;
+ if (absval > rhuge)
+ {
+ if (mpf_cmp_ui (x->value.complex.r, 0) < 0)
+ {
+ if (pedantic == 1)
+ gfc_warning_now
+ ("Real part of argument of EXP at %L is negative "
+ "and too large, setting result to zero", &x->where);
+
+ mpf_set_ui (result->value.complex.r, 0);
+ mpf_set_ui (result->value.complex.i, 0);
+ return range_check (result, "EXP");
+ }
+ else
+ {
+ gfc_error ("Real part of argument of EXP at %L too large",
+ &x->where);
+ gfc_free_expr (result);
+ return &gfc_bad_expr;
+ }
+ }
+ mpf_init (xp);
+ mpf_init (xq);
+ exponential (&x->value.complex.r, &xq);
+ cosine (&x->value.complex.i, &xp);
+ mpf_mul (result->value.complex.r, xq, xp);
+ sine (&x->value.complex.i, &xp);
+ mpf_mul (result->value.complex.i, xq, xp);
+ mpf_clear (xp);
+ mpf_clear (xq);
+ break;
+
+ default:
+ gfc_internal_error ("in gfc_simplify_exp(): Bad type");
+ }
+
+ return range_check (result, "EXP");
+}
+
+
+gfc_expr *
+gfc_simplify_exponent (gfc_expr * x)
+{
+ mpf_t i2, absv, ln2, lnx;
+ gfc_expr *result;
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind (),
+ &x->where);
+
+ if (mpf_cmp (x->value.real, mpf_zero) == 0)
+ {
+ mpz_set_ui (result->value.integer, 0);
+ return result;
+ }
+
+ mpf_init_set_ui (i2, 2);
+ mpf_init (absv);
+ mpf_init (ln2);
+ mpf_init (lnx);
+
+ natural_logarithm (&i2, &ln2);
+
+ mpf_abs (absv, x->value.real);
+ natural_logarithm (&absv, &lnx);
+
+ mpf_div (lnx, lnx, ln2);
+ mpf_trunc (lnx, lnx);
+ mpf_add_ui (lnx, lnx, 1);
+ mpz_set_f (result->value.integer, lnx);
+
+ mpf_clear (i2);
+ mpf_clear (ln2);
+ mpf_clear (lnx);
+ mpf_clear (absv);
+
+ return range_check (result, "EXPONENT");
+}
+
+
+gfc_expr *
+gfc_simplify_float (gfc_expr * a)
+{
+ gfc_expr *result;
+
+ if (a->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_int2real (a, gfc_default_real_kind ());
+ return range_check (result, "FLOAT");
+}
+
+
+gfc_expr *
+gfc_simplify_floor (gfc_expr * e, gfc_expr * k)
+{
+ gfc_expr *result;
+ mpf_t floor;
+ int kind;
+
+ kind = get_kind (BT_REAL, k, "FLOOR", gfc_default_real_kind ());
+ if (kind == -1)
+ gfc_internal_error ("gfc_simplify_floor(): Bad kind");
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (BT_INTEGER, kind, &e->where);
+
+ mpf_init (floor);
+ mpf_floor (floor, e->value.real);
+ mpz_set_f (result->value.integer, floor);
+ mpf_clear (floor);
+
+ return range_check (result, "FLOOR");
+}
+
+
+gfc_expr *
+gfc_simplify_fraction (gfc_expr * x)
+{
+ gfc_expr *result;
+ mpf_t i2, absv, ln2, lnx, pow2;
+ unsigned long exp2;
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (BT_REAL, x->ts.kind, &x->where);
+
+ if (mpf_cmp (x->value.real, mpf_zero) == 0)
+ {
+ mpf_set (result->value.real, mpf_zero);
+ return result;
+ }
+
+ mpf_init_set_ui (i2, 2);
+ mpf_init (absv);
+ mpf_init (ln2);
+ mpf_init (lnx);
+ mpf_init (pow2);
+
+ natural_logarithm (&i2, &ln2);
+
+ mpf_abs (absv, x->value.real);
+ natural_logarithm (&absv, &lnx);
+
+ mpf_div (lnx, lnx, ln2);
+ mpf_trunc (lnx, lnx);
+ mpf_add_ui (lnx, lnx, 1);
+
+ exp2 = (unsigned long) mpf_get_d (lnx);
+ mpf_pow_ui (pow2, i2, exp2);
+
+ mpf_div (result->value.real, absv, pow2);
+
+ mpf_clear (i2);
+ mpf_clear (ln2);
+ mpf_clear (absv);
+ mpf_clear (lnx);
+ mpf_clear (pow2);
+
+ return range_check (result, "FRACTION");
+}
+
+
+gfc_expr *
+gfc_simplify_huge (gfc_expr * e)
+{
+ gfc_expr *result;
+ int i;
+
+ i = gfc_validate_kind (e->ts.type, e->ts.kind);
+ if (i == -1)
+ goto bad_type;
+
+ result = gfc_constant_result (e->ts.type, e->ts.kind, &e->where);
+
+ switch (e->ts.type)
+ {
+ case BT_INTEGER:
+ mpz_set (result->value.integer, gfc_integer_kinds[i].huge);
+ break;
+
+ case BT_REAL:
+ mpf_set (result->value.real, gfc_real_kinds[i].huge);
+ break;
+
+ bad_type:
+ default:
+ gfc_internal_error ("gfc_simplify_huge(): Bad type");
+ }
+
+ return result;
+}
+
+
+gfc_expr *
+gfc_simplify_iachar (gfc_expr * e)
+{
+ gfc_expr *result;
+ int index;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ if (e->value.character.length != 1)
+ {
+ gfc_error ("Argument of IACHAR at %L must be of length one", &e->where);
+ return &gfc_bad_expr;
+ }
+
+ index = xascii_table[(int) e->value.character.string[0] & 0xFF];
+
+ result = gfc_int_expr (index);
+ result->where = e->where;
+
+ return range_check (result, "IACHAR");
+}
+
+
+gfc_expr *
+gfc_simplify_iand (gfc_expr * x, gfc_expr * y)
+{
+ gfc_expr *result;
+
+ if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (BT_INTEGER, x->ts.kind, &x->where);
+
+ mpz_and (result->value.integer, x->value.integer, y->value.integer);
+
+ return range_check (result, "IAND");
+}
+
+
+gfc_expr *
+gfc_simplify_ibclr (gfc_expr * x, gfc_expr * y)
+{
+ gfc_expr *result;
+ int k, pos;
+
+ if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ if (gfc_extract_int (y, &pos) != NULL || pos < 0)
+ {
+ gfc_error ("Invalid second argument of IBCLR at %L", &y->where);
+ return &gfc_bad_expr;
+ }
+
+ k = gfc_validate_kind (x->ts.type, x->ts.kind);
+ if (k == -1)
+ gfc_internal_error ("gfc_simplify_ibclr(): Bad kind");
+
+ if (pos > gfc_integer_kinds[k].bit_size)
+ {
+ gfc_error ("Second argument of IBCLR exceeds bit size at %L",
+ &y->where);
+ return &gfc_bad_expr;
+ }
+
+ result = gfc_copy_expr (x);
+
+ mpz_clrbit (result->value.integer, pos);
+ return range_check (result, "IBCLR");
+}
+
+
+gfc_expr *
+gfc_simplify_ibits (gfc_expr * x, gfc_expr * y, gfc_expr * z)
+{
+ gfc_expr *result;
+ int pos, len;
+ int i, k, bitsize;
+ int *bits;
+
+ if (x->expr_type != EXPR_CONSTANT
+ || y->expr_type != EXPR_CONSTANT
+ || z->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ if (gfc_extract_int (y, &pos) != NULL || pos < 0)
+ {
+ gfc_error ("Invalid second argument of IBITS at %L", &y->where);
+ return &gfc_bad_expr;
+ }
+
+ if (gfc_extract_int (z, &len) != NULL || len < 0)
+ {
+ gfc_error ("Invalid third argument of IBITS at %L", &z->where);
+ return &gfc_bad_expr;
+ }
+
+ k = gfc_validate_kind (BT_INTEGER, x->ts.kind);
+ if (k == -1)
+ gfc_internal_error ("gfc_simplify_ibits(): Bad kind");
+
+ bitsize = gfc_integer_kinds[k].bit_size;
+
+ if (pos + len > bitsize)
+ {
+ gfc_error
+ ("Sum of second and third arguments of IBITS exceeds bit size "
+ "at %L", &y->where);
+ return &gfc_bad_expr;
+ }
+
+ result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+
+ bits = gfc_getmem (bitsize * sizeof (int));
+
+ for (i = 0; i < bitsize; i++)
+ bits[i] = 0;
+
+ for (i = 0; i < len; i++)
+ bits[i] = mpz_tstbit (x->value.integer, i + pos);
+
+ for (i = 0; i < bitsize; i++)
+ {
+ if (bits[i] == 0)
+ {
+ mpz_clrbit (result->value.integer, i);
+ }
+ else if (bits[i] == 1)
+ {
+ mpz_setbit (result->value.integer, i);
+ }
+ else
+ {
+ gfc_internal_error ("IBITS: Bad bit");
+ }
+ }
+
+ gfc_free (bits);
+
+ return range_check (result, "IBITS");
+}
+
+
+gfc_expr *
+gfc_simplify_ibset (gfc_expr * x, gfc_expr * y)
+{
+ gfc_expr *result;
+ int k, pos;
+
+ if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ if (gfc_extract_int (y, &pos) != NULL || pos < 0)
+ {
+ gfc_error ("Invalid second argument of IBSET at %L", &y->where);
+ return &gfc_bad_expr;
+ }
+
+ k = gfc_validate_kind (x->ts.type, x->ts.kind);
+ if (k == -1)
+ gfc_internal_error ("gfc_simplify_ibset(): Bad kind");
+
+ if (pos > gfc_integer_kinds[k].bit_size)
+ {
+ gfc_error ("Second argument of IBSET exceeds bit size at %L",
+ &y->where);
+ return &gfc_bad_expr;
+ }
+
+ result = gfc_copy_expr (x);
+
+ mpz_setbit (result->value.integer, pos);
+ return range_check (result, "IBSET");
+}
+
+
+gfc_expr *
+gfc_simplify_ichar (gfc_expr * e)
+{
+ gfc_expr *result;
+ int index;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ if (e->value.character.length != 1)
+ {
+ gfc_error ("Argument of ICHAR at %L must be of length one", &e->where);
+ return &gfc_bad_expr;
+ }
+
+ index = (int) e->value.character.string[0];
+
+ if (index < CHAR_MIN || index > CHAR_MAX)
+ {
+ gfc_error ("Argument of ICHAR at %L out of range of this processor",
+ &e->where);
+ return &gfc_bad_expr;
+ }
+
+ result = gfc_int_expr (index);
+ result->where = e->where;
+ return range_check (result, "ICHAR");
+}
+
+
+gfc_expr *
+gfc_simplify_ieor (gfc_expr * x, gfc_expr * y)
+{
+ gfc_expr *result;
+
+ if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (BT_INTEGER, x->ts.kind, &x->where);
+
+ mpz_xor (result->value.integer, x->value.integer, y->value.integer);
+
+ return range_check (result, "IEOR");
+}
+
+
+gfc_expr *
+gfc_simplify_index (gfc_expr * x, gfc_expr * y, gfc_expr * b)
+{
+ gfc_expr *result;
+ int back, len, lensub;
+ int i, j, k, count, index = 0, start;
+
+ if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ if (b != NULL && b->value.logical != 0)
+ back = 1;
+ else
+ back = 0;
+
+ result = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind (),
+ &x->where);
+
+ len = x->value.character.length;
+ lensub = y->value.character.length;
+
+ if (len < lensub)
+ {
+ mpz_set_si (result->value.integer, 0);
+ return result;
+ }
+
+ if (back == 0)
+ {
+
+ if (lensub == 0)
+ {
+ mpz_set_si (result->value.integer, 1);
+ return result;
+ }
+ else if (lensub == 1)
+ {
+ for (i = 0; i < len; i++)
+ {
+ for (j = 0; j < lensub; j++)
+ {
+ if (y->value.character.string[j] ==
+ x->value.character.string[i])
+ {
+ index = i + 1;
+ goto done;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (i = 0; i < len; i++)
+ {
+ for (j = 0; j < lensub; j++)
+ {
+ if (y->value.character.string[j] ==
+ x->value.character.string[i])
+ {
+ start = i;
+ count = 0;
+
+ for (k = 0; k < lensub; k++)
+ {
+ if (y->value.character.string[k] ==
+ x->value.character.string[k + start])
+ count++;
+ }
+
+ if (count == lensub)
+ {
+ index = start + 1;
+ goto done;
+ }
+ }
+ }
+ }
+ }
+
+ }
+ else
+ {
+
+ if (lensub == 0)
+ {
+ mpz_set_si (result->value.integer, len + 1);
+ return result;
+ }
+ else if (lensub == 1)
+ {
+ for (i = 0; i < len; i++)
+ {
+ for (j = 0; j < lensub; j++)
+ {
+ if (y->value.character.string[j] ==
+ x->value.character.string[len - i])
+ {
+ index = len - i + 1;
+ goto done;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (i = 0; i < len; i++)
+ {
+ for (j = 0; j < lensub; j++)
+ {
+ if (y->value.character.string[j] ==
+ x->value.character.string[len - i])
+ {
+ start = len - i;
+ if (start <= len - lensub)
+ {
+ count = 0;
+ for (k = 0; k < lensub; k++)
+ if (y->value.character.string[k] ==
+ x->value.character.string[k + start])
+ count++;
+
+ if (count == lensub)
+ {
+ index = start + 1;
+ goto done;
+ }
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+ }
+ }
+ }
+
+done:
+ mpz_set_si (result->value.integer, index);
+ return range_check (result, "INDEX");
+}
+
+
+gfc_expr *
+gfc_simplify_int (gfc_expr * e, gfc_expr * k)
+{
+ gfc_expr *rpart, *rtrunc, *result;
+ int kind;
+
+ kind = get_kind (BT_REAL, k, "INT", gfc_default_real_kind ());
+ if (kind == -1)
+ return &gfc_bad_expr;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (BT_INTEGER, kind, &e->where);
+
+ switch (e->ts.type)
+ {
+ case BT_INTEGER:
+ mpz_set (result->value.integer, e->value.integer);
+ break;
+
+ case BT_REAL:
+ rtrunc = gfc_copy_expr (e);
+ mpf_trunc (rtrunc->value.real, e->value.real);
+ mpz_set_f (result->value.integer, rtrunc->value.real);
+ gfc_free_expr (rtrunc);
+ break;
+
+ case BT_COMPLEX:
+ rpart = gfc_complex2real (e, kind);
+ rtrunc = gfc_copy_expr (rpart);
+ mpf_trunc (rtrunc->value.real, rpart->value.real);
+ mpz_set_f (result->value.integer, rtrunc->value.real);
+ gfc_free_expr (rpart);
+ gfc_free_expr (rtrunc);
+ break;
+
+ default:
+ gfc_error ("Argument of INT at %L is not a valid type", &e->where);
+ gfc_free_expr (result);
+ return &gfc_bad_expr;
+ }
+
+ return range_check (result, "INT");
+}
+
+
+gfc_expr *
+gfc_simplify_ifix (gfc_expr * e)
+{
+ gfc_expr *rtrunc, *result;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind (),
+ &e->where);
+
+ rtrunc = gfc_copy_expr (e);
+
+ mpf_trunc (rtrunc->value.real, e->value.real);
+ mpz_set_f (result->value.integer, rtrunc->value.real);
+
+ gfc_free_expr (rtrunc);
+ return range_check (result, "IFIX");
+}
+
+
+gfc_expr *
+gfc_simplify_idint (gfc_expr * e)
+{
+ gfc_expr *rtrunc, *result;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind (),
+ &e->where);
+
+ rtrunc = gfc_copy_expr (e);
+
+ mpf_trunc (rtrunc->value.real, e->value.real);
+ mpz_set_f (result->value.integer, rtrunc->value.real);
+
+ gfc_free_expr (rtrunc);
+ return range_check (result, "IDINT");
+}
+
+
+gfc_expr *
+gfc_simplify_ior (gfc_expr * x, gfc_expr * y)
+{
+ gfc_expr *result;
+
+ if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (BT_INTEGER, x->ts.kind, &x->where);
+
+ mpz_ior (result->value.integer, x->value.integer, y->value.integer);
+ return range_check (result, "IOR");
+}
+
+
+gfc_expr *
+gfc_simplify_ishft (gfc_expr * e, gfc_expr * s)
+{
+ gfc_expr *result;
+ int shift, ashift, isize, k;
+ long e_int;
+
+ if (e->expr_type != EXPR_CONSTANT || s->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ if (gfc_extract_int (s, &shift) != NULL)
+ {
+ gfc_error ("Invalid second argument of ISHFT at %L", &s->where);
+ return &gfc_bad_expr;
+ }
+
+ k = gfc_validate_kind (BT_INTEGER, e->ts.kind);
+ if (k == -1)
+ gfc_internal_error ("gfc_simplify_ishft(): Bad kind");
+
+ isize = gfc_integer_kinds[k].bit_size;
+
+ if (shift >= 0)
+ ashift = shift;
+ else
+ ashift = -shift;
+
+ if (ashift > isize)
+ {
+ gfc_error
+ ("Magnitude of second argument of ISHFT exceeds bit size at %L",
+ &s->where);
+ return &gfc_bad_expr;
+ }
+
+ e_int = mpz_get_si (e->value.integer);
+ if (e_int > INT_MAX || e_int < INT_MIN)
+ gfc_internal_error ("ISHFT: unable to extract integer");
+
+ result = gfc_constant_result (e->ts.type, e->ts.kind, &e->where);
+
+ if (shift == 0)
+ {
+ mpz_set (result->value.integer, e->value.integer);
+ return range_check (result, "ISHFT");
+ }
+
+ if (shift > 0)
+ mpz_set_si (result->value.integer, e_int << shift);
+ else
+ mpz_set_si (result->value.integer, e_int >> ashift);
+
+ return range_check (result, "ISHFT");
+}
+
+
+gfc_expr *
+gfc_simplify_ishftc (gfc_expr * e, gfc_expr * s, gfc_expr * sz)
+{
+ gfc_expr *result;
+ int shift, ashift, isize, delta, k;
+ int i, *bits;
+
+ if (e->expr_type != EXPR_CONSTANT || s->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ if (gfc_extract_int (s, &shift) != NULL)
+ {
+ gfc_error ("Invalid second argument of ISHFTC at %L", &s->where);
+ return &gfc_bad_expr;
+ }
+
+ k = gfc_validate_kind (e->ts.type, e->ts.kind);
+ if (k == -1)
+ gfc_internal_error ("gfc_simplify_ishftc(): Bad kind");
+
+ if (sz != NULL)
+ {
+ if (gfc_extract_int (sz, &isize) != NULL || isize < 0)
+ {
+ gfc_error ("Invalid third argument of ISHFTC at %L", &sz->where);
+ return &gfc_bad_expr;
+ }
+ }
+ else
+ isize = gfc_integer_kinds[k].bit_size;
+
+ if (shift >= 0)
+ ashift = shift;
+ else
+ ashift = -shift;
+
+ if (ashift > isize)
+ {
+ gfc_error
+ ("Magnitude of second argument of ISHFTC exceeds third argument "
+ "at %L", &s->where);
+ return &gfc_bad_expr;
+ }
+
+ result = gfc_constant_result (e->ts.type, e->ts.kind, &e->where);
+
+ bits = gfc_getmem (isize * sizeof (int));
+
+ for (i = 0; i < isize; i++)
+ bits[i] = mpz_tstbit (e->value.integer, i);
+
+ delta = isize - ashift;
+
+ if (shift == 0)
+ {
+ mpz_set (result->value.integer, e->value.integer);
+ gfc_free (bits);
+ return range_check (result, "ISHFTC");
+ }
+
+ else if (shift > 0)
+ {
+ for (i = 0; i < delta; i++)
+ {
+ if (bits[i] == 0)
+ mpz_clrbit (result->value.integer, i + shift);
+ if (bits[i] == 1)
+ mpz_setbit (result->value.integer, i + shift);
+ }
+
+ for (i = delta; i < isize; i++)
+ {
+ if (bits[i] == 0)
+ mpz_clrbit (result->value.integer, i - delta);
+ if (bits[i] == 1)
+ mpz_setbit (result->value.integer, i - delta);
+ }
+
+ gfc_free (bits);
+ return range_check (result, "ISHFTC");
+ }
+ else
+ {
+ for (i = 0; i < ashift; i++)
+ {
+ if (bits[i] == 0)
+ mpz_clrbit (result->value.integer, i + delta);
+ if (bits[i] == 1)
+ mpz_setbit (result->value.integer, i + delta);
+ }
+
+ for (i = ashift; i < isize; i++)
+ {
+ if (bits[i] == 0)
+ mpz_clrbit (result->value.integer, i + shift);
+ if (bits[i] == 1)
+ mpz_setbit (result->value.integer, i + shift);
+ }
+
+ gfc_free (bits);
+ return range_check (result, "ISHFTC");
+ }
+}
+
+
+gfc_expr *
+gfc_simplify_kind (gfc_expr * e)
+{
+
+ if (e->ts.type == BT_DERIVED)
+ {
+ gfc_error ("Argument of KIND at %L is a DERIVED type", &e->where);
+ return &gfc_bad_expr;
+ }
+
+ return gfc_int_expr (e->ts.kind);
+}
+
+
+static gfc_expr *
+gfc_simplify_bound (gfc_expr * array, gfc_expr * dim, int upper)
+{
+ gfc_ref *ref;
+ gfc_array_spec *as;
+ int i;
+
+ if (array->expr_type != EXPR_VARIABLE)
+ return NULL;
+
+ if (dim == NULL)
+ return NULL;
+
+ if (dim->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ /* Follow any component references. */
+ as = array->symtree->n.sym->as;
+ ref = array->ref;
+ while (ref->next != NULL)
+ {
+ if (ref->type == REF_COMPONENT)
+ as = ref->u.c.sym->as;
+ ref = ref->next;
+ }
+
+ if (ref->type != REF_ARRAY || ref->u.ar.type != AR_FULL)
+ return NULL;
+
+ i = mpz_get_si (dim->value.integer);
+ if (upper)
+ return as->upper[i-1];
+ else
+ return as->lower[i-1];
+}
+
+
+gfc_expr *
+gfc_simplify_lbound (gfc_expr * array, gfc_expr * dim)
+{
+ return gfc_simplify_bound (array, dim, 0);
+}
+
+
+gfc_expr *
+gfc_simplify_len (gfc_expr * e)
+{
+ gfc_expr *result;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind (),
+ &e->where);
+
+ mpz_set_si (result->value.integer, e->value.character.length);
+ return range_check (result, "LEN");
+}
+
+
+gfc_expr *
+gfc_simplify_len_trim (gfc_expr * e)
+{
+ gfc_expr *result;
+ int count, len, lentrim, i;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind (),
+ &e->where);
+
+ len = e->value.character.length;
+
+ for (count = 0, i = 1; i <= len; i++)
+ if (e->value.character.string[len - i] == ' ')
+ count++;
+ else
+ break;
+
+ lentrim = len - count;
+
+ mpz_set_si (result->value.integer, lentrim);
+ return range_check (result, "LEN_TRIM");
+}
+
+
+gfc_expr *
+gfc_simplify_lge (gfc_expr * a, gfc_expr * b)
+{
+
+ if (a->expr_type != EXPR_CONSTANT || b->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ return gfc_logical_expr (gfc_compare_string (a, b, xascii_table) >= 0,
+ &a->where);
+}
+
+
+gfc_expr *
+gfc_simplify_lgt (gfc_expr * a, gfc_expr * b)
+{
+
+ if (a->expr_type != EXPR_CONSTANT || b->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ return gfc_logical_expr (gfc_compare_string (a, b, xascii_table) > 0,
+ &a->where);
+}
+
+
+gfc_expr *
+gfc_simplify_lle (gfc_expr * a, gfc_expr * b)
+{
+
+ if (a->expr_type != EXPR_CONSTANT || b->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ return gfc_logical_expr (gfc_compare_string (a, b, xascii_table) <= 0,
+ &a->where);
+}
+
+
+gfc_expr *
+gfc_simplify_llt (gfc_expr * a, gfc_expr * b)
+{
+
+ if (a->expr_type != EXPR_CONSTANT || b->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ return gfc_logical_expr (gfc_compare_string (a, b, xascii_table) < 0,
+ &a->where);
+}
+
+
+gfc_expr *
+gfc_simplify_log (gfc_expr * x)
+{
+ gfc_expr *result;
+ mpf_t xr, xi;
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+
+ switch (x->ts.type)
+ {
+ case BT_REAL:
+ if (mpf_cmp (x->value.real, mpf_zero) <= 0)
+ {
+ gfc_error
+ ("Argument of LOG at %L cannot be less than or equal to zero",
+ &x->where);
+ gfc_free_expr (result);
+ return &gfc_bad_expr;
+ }
+
+ natural_logarithm (&x->value.real, &result->value.real);
+ break;
+
+ case BT_COMPLEX:
+ if ((mpf_cmp (x->value.complex.r, mpf_zero) == 0)
+ && (mpf_cmp (x->value.complex.i, mpf_zero) == 0))
+ {
+ gfc_error ("Complex argument of LOG at %L cannot be zero",
+ &x->where);
+ gfc_free_expr (result);
+ return &gfc_bad_expr;
+ }
+
+ mpf_init (xr);
+ mpf_init (xi);
+
+ mpf_div (xr, x->value.complex.i, x->value.complex.r);
+ arctangent2 (&x->value.complex.i, &x->value.complex.r,
+ &result->value.complex.i);
+
+ mpf_mul (xr, x->value.complex.r, x->value.complex.r);
+ mpf_mul (xi, x->value.complex.i, x->value.complex.i);
+ mpf_add (xr, xr, xi);
+ mpf_sqrt (xr, xr);
+ natural_logarithm (&xr, &result->value.complex.r);
+
+ mpf_clear (xr);
+ mpf_clear (xi);
+
+ break;
+
+ default:
+ gfc_internal_error ("gfc_simplify_log: bad type");
+ }
+
+ return range_check (result, "LOG");
+}
+
+
+gfc_expr *
+gfc_simplify_log10 (gfc_expr * x)
+{
+ gfc_expr *result;
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ if (mpf_cmp (x->value.real, mpf_zero) <= 0)
+ {
+ gfc_error
+ ("Argument of LOG10 at %L cannot be less than or equal to zero",
+ &x->where);
+ return &gfc_bad_expr;
+ }
+
+ result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+
+ common_logarithm (&x->value.real, &result->value.real);
+
+ return range_check (result, "LOG10");
+}
+
+
+gfc_expr *
+gfc_simplify_logical (gfc_expr * e, gfc_expr * k)
+{
+ gfc_expr *result;
+ int kind;
+
+ kind = get_kind (BT_LOGICAL, k, "LOGICAL", gfc_default_logical_kind ());
+ if (kind < 0)
+ return &gfc_bad_expr;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (BT_LOGICAL, kind, &e->where);
+
+ result->value.logical = e->value.logical;
+
+ return result;
+}
+
+
+/* This function is special since MAX() can take any number of
+ arguments. The simplified expression is a rewritten version of the
+ argument list containing at most one constant element. Other
+ constant elements are deleted. Because the argument list has
+ already been checked, this function always succeeds. sign is 1 for
+ MAX(), -1 for MIN(). */
+
+static gfc_expr *
+simplify_min_max (gfc_expr * expr, int sign)
+{
+ gfc_actual_arglist *arg, *last, *extremum;
+ gfc_intrinsic_sym * specific;
+
+ last = NULL;
+ extremum = NULL;
+ specific = expr->value.function.isym;
+
+ arg = expr->value.function.actual;
+
+ for (; arg; last = arg, arg = arg->next)
+ {
+ if (arg->expr->expr_type != EXPR_CONSTANT)
+ continue;
+
+ if (extremum == NULL)
+ {
+ extremum = arg;
+ continue;
+ }
+
+ switch (arg->expr->ts.type)
+ {
+ case BT_INTEGER:
+ if (mpz_cmp (arg->expr->value.integer,
+ extremum->expr->value.integer) * sign > 0)
+ mpz_set (extremum->expr->value.integer, arg->expr->value.integer);
+
+ break;
+
+ case BT_REAL:
+ if (mpf_cmp (arg->expr->value.real, extremum->expr->value.real) *
+ sign > 0)
+ mpf_set (extremum->expr->value.real, arg->expr->value.real);
+
+ break;
+
+ default:
+ gfc_internal_error ("gfc_simplify_max(): Bad type in arglist");
+ }
+
+ /* Delete the extra constant argument. */
+ if (last == NULL)
+ expr->value.function.actual = arg->next;
+ else
+ last->next = arg->next;
+
+ arg->next = NULL;
+ gfc_free_actual_arglist (arg);
+ arg = last;
+ }
+
+ /* If there is one value left, replace the function call with the
+ expression. */
+ if (expr->value.function.actual->next != NULL)
+ return NULL;
+
+ /* Convert to the correct type and kind. */
+ if (expr->ts.type != BT_UNKNOWN)
+ return gfc_convert_constant (expr->value.function.actual->expr,
+ expr->ts.type, expr->ts.kind);
+
+ if (specific->ts.type != BT_UNKNOWN)
+ return gfc_convert_constant (expr->value.function.actual->expr,
+ specific->ts.type, specific->ts.kind);
+
+ return gfc_copy_expr (expr->value.function.actual->expr);
+}
+
+
+gfc_expr *
+gfc_simplify_min (gfc_expr * e)
+{
+
+ return simplify_min_max (e, -1);
+}
+
+
+gfc_expr *
+gfc_simplify_max (gfc_expr * e)
+{
+
+ return simplify_min_max (e, 1);
+}
+
+
+gfc_expr *
+gfc_simplify_maxexponent (gfc_expr * x)
+{
+ gfc_expr *result;
+ int i;
+
+ i = gfc_validate_kind (BT_REAL, x->ts.kind);
+ if (i == -1)
+ gfc_internal_error ("gfc_simplify_maxexponent(): Bad kind");
+
+ result = gfc_int_expr (gfc_real_kinds[i].max_exponent);
+ result->where = x->where;
+
+ return result;
+}
+
+
+gfc_expr *
+gfc_simplify_minexponent (gfc_expr * x)
+{
+ gfc_expr *result;
+ int i;
+
+ i = gfc_validate_kind (BT_REAL, x->ts.kind);
+ if (i == -1)
+ gfc_internal_error ("gfc_simplify_minexponent(): Bad kind");
+
+ result = gfc_int_expr (gfc_real_kinds[i].min_exponent);
+ result->where = x->where;
+
+ return result;
+}
+
+
+gfc_expr *
+gfc_simplify_mod (gfc_expr * a, gfc_expr * p)
+{
+ gfc_expr *result;
+ mpf_t quot, iquot, term;
+
+ if (a->expr_type != EXPR_CONSTANT || p->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (a->ts.type, a->ts.kind, &a->where);
+
+ switch (a->ts.type)
+ {
+ case BT_INTEGER:
+ if (mpz_cmp_ui (p->value.integer, 0) == 0)
+ {
+ /* Result is processor-dependent. */
+ gfc_error ("Second argument MOD at %L is zero", &a->where);
+ gfc_free_expr (result);
+ return &gfc_bad_expr;
+ }
+ mpz_tdiv_r (result->value.integer, a->value.integer, p->value.integer);
+ break;
+
+ case BT_REAL:
+ if (mpf_cmp_ui (p->value.real, 0) == 0)
+ {
+ /* Result is processor-dependent. */
+ gfc_error ("Second argument of MOD at %L is zero", &p->where);
+ gfc_free_expr (result);
+ return &gfc_bad_expr;
+ }
+
+ mpf_init (quot);
+ mpf_init (iquot);
+ mpf_init (term);
+
+ mpf_div (quot, a->value.real, p->value.real);
+ mpf_trunc (iquot, quot);
+ mpf_mul (term, iquot, p->value.real);
+ mpf_sub (result->value.real, a->value.real, term);
+
+ mpf_clear (quot);
+ mpf_clear (iquot);
+ mpf_clear (term);
+ break;
+
+ default:
+ gfc_internal_error ("gfc_simplify_mod(): Bad arguments");
+ }
+
+ return range_check (result, "MOD");
+}
+
+
+gfc_expr *
+gfc_simplify_modulo (gfc_expr * a, gfc_expr * p)
+{
+ gfc_expr *result;
+ mpf_t quot, iquot, term;
+
+ if (a->expr_type != EXPR_CONSTANT || p->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (a->ts.type, a->ts.kind, &a->where);
+
+ switch (a->ts.type)
+ {
+ case BT_INTEGER:
+ if (mpz_cmp_ui (p->value.integer, 0) == 0)
+ {
+ /* Result is processor-dependent. This processor just opts
+ to not handle it at all. */
+ gfc_error ("Second argument of MODULO at %L is zero", &a->where);
+ gfc_free_expr (result);
+ return &gfc_bad_expr;
+ }
+ mpz_fdiv_r (result->value.integer, a->value.integer, p->value.integer);
+
+ break;
+
+ case BT_REAL:
+ if (mpf_cmp_ui (p->value.real, 0) == 0)
+ {
+ /* Result is processor-dependent. */
+ gfc_error ("Second argument of MODULO at %L is zero", &p->where);
+ gfc_free_expr (result);
+ return &gfc_bad_expr;
+ }
+
+ mpf_init (quot);
+ mpf_init (iquot);
+ mpf_init (term);
+
+ mpf_div (quot, a->value.real, p->value.real);
+ mpf_floor (iquot, quot);
+ mpf_mul (term, iquot, p->value.real);
+
+ mpf_clear (quot);
+ mpf_clear (iquot);
+ mpf_clear (term);
+
+ mpf_sub (result->value.real, a->value.real, term);
+ break;
+
+ default:
+ gfc_internal_error ("gfc_simplify_modulo(): Bad arguments");
+ }
+
+ return range_check (result, "MODULO");
+}
+
+
+/* Exists for the sole purpose of consistency with other intrinsics. */
+gfc_expr *
+gfc_simplify_mvbits (gfc_expr * f ATTRIBUTE_UNUSED,
+ gfc_expr * fp ATTRIBUTE_UNUSED,
+ gfc_expr * l ATTRIBUTE_UNUSED,
+ gfc_expr * to ATTRIBUTE_UNUSED,
+ gfc_expr * tp ATTRIBUTE_UNUSED)
+{
+ return NULL;
+}
+
+
+gfc_expr *
+gfc_simplify_nearest (gfc_expr * x, gfc_expr * s)
+{
+ gfc_expr *result;
+ float rval;
+ double val, eps;
+ int p, i, k, match_float;
+
+ /* FIXME: This implementation is dopey and probably not quite right,
+ but it's a start. */
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ k = gfc_validate_kind (x->ts.type, x->ts.kind);
+ if (k == -1)
+ gfc_internal_error ("gfc_simplify_precision(): Bad kind");
+
+ result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+
+ val = mpf_get_d (x->value.real);
+ p = gfc_real_kinds[k].digits;
+
+ eps = 1.;
+ for (i = 1; i < p; ++i)
+ {
+ eps = eps / 2.;
+ }
+
+ /* TODO we should make sure that 'float' matches kind 4 */
+ match_float = gfc_real_kinds[k].kind == 4;
+ if (mpf_cmp_ui (s->value.real, 0) > 0)
+ {
+ if (match_float)
+ {
+ rval = (float) val;
+ rval = rval + eps;
+ mpf_set_d (result->value.real, rval);
+ }
+ else
+ {
+ val = val + eps;
+ mpf_set_d (result->value.real, val);
+ }
+ }
+ else if (mpf_cmp_ui (s->value.real, 0) < 0)
+ {
+ if (match_float)
+ {
+ rval = (float) val;
+ rval = rval - eps;
+ mpf_set_d (result->value.real, rval);
+ }
+ else
+ {
+ val = val - eps;
+ mpf_set_d (result->value.real, val);
+ }
+ }
+ else
+ {
+ gfc_error ("Invalid second argument of NEAREST at %L", &s->where);
+ gfc_free (result);
+ return &gfc_bad_expr;
+ }
+
+ return range_check (result, "NEAREST");
+
+}
+
+
+static gfc_expr *
+simplify_nint (const char *name, gfc_expr * e, gfc_expr * k)
+{
+ gfc_expr *rtrunc, *itrunc, *result;
+ int kind, cmp;
+
+ kind = get_kind (BT_INTEGER, k, name, gfc_default_integer_kind ());
+ if (kind == -1)
+ return &gfc_bad_expr;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (BT_INTEGER, kind, &e->where);
+
+ rtrunc = gfc_copy_expr (e);
+ itrunc = gfc_copy_expr (e);
+
+ cmp = mpf_cmp_ui (e->value.real, 0);
+
+ if (cmp > 0)
+ {
+ mpf_add (rtrunc->value.real, e->value.real, mpf_half);
+ mpf_trunc (itrunc->value.real, rtrunc->value.real);
+ }
+ else if (cmp < 0)
+ {
+ mpf_sub (rtrunc->value.real, e->value.real, mpf_half);
+ mpf_trunc (itrunc->value.real, rtrunc->value.real);
+ }
+ else
+ mpf_set_ui (itrunc->value.real, 0);
+
+ mpz_set_f (result->value.integer, itrunc->value.real);
+
+ gfc_free_expr (itrunc);
+ gfc_free_expr (rtrunc);
+
+ return range_check (result, name);
+}
+
+
+gfc_expr *
+gfc_simplify_nint (gfc_expr * e, gfc_expr * k)
+{
+
+ return simplify_nint ("NINT", e, k);
+}
+
+
+gfc_expr *
+gfc_simplify_idnint (gfc_expr * e)
+{
+
+ return simplify_nint ("IDNINT", e, NULL);
+}
+
+
+gfc_expr *
+gfc_simplify_not (gfc_expr * e)
+{
+ gfc_expr *result;
+ int i;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (e->ts.type, e->ts.kind, &e->where);
+
+ mpz_com (result->value.integer, e->value.integer);
+
+ /* Because of how GMP handles numbers, the result must be ANDed with
+ the max_int mask. For radices <> 2, this will require change. */
+
+ i = gfc_validate_kind (BT_INTEGER, e->ts.kind);
+ if (i == -1)
+ gfc_internal_error ("gfc_simplify_not(): Bad kind");
+
+ mpz_and (result->value.integer, result->value.integer,
+ gfc_integer_kinds[i].max_int);
+
+ return range_check (result, "NOT");
+}
+
+
+gfc_expr *
+gfc_simplify_null (gfc_expr * mold)
+{
+ gfc_expr *result;
+
+ result = gfc_get_expr ();
+ result->expr_type = EXPR_NULL;
+
+ if (mold == NULL)
+ result->ts.type = BT_UNKNOWN;
+ else
+ {
+ result->ts = mold->ts;
+ result->where = mold->where;
+ }
+
+ return result;
+}
+
+
+gfc_expr *
+gfc_simplify_precision (gfc_expr * e)
+{
+ gfc_expr *result;
+ int i;
+
+ i = gfc_validate_kind (e->ts.type, e->ts.kind);
+ if (i == -1)
+ gfc_internal_error ("gfc_simplify_precision(): Bad kind");
+
+ result = gfc_int_expr (gfc_real_kinds[i].precision);
+ result->where = e->where;
+
+ return result;
+}
+
+
+gfc_expr *
+gfc_simplify_radix (gfc_expr * e)
+{
+ gfc_expr *result;
+ int i;
+
+ i = gfc_validate_kind (e->ts.type, e->ts.kind);
+ if (i == -1)
+ goto bad;
+
+ switch (e->ts.type)
+ {
+ case BT_INTEGER:
+ i = gfc_integer_kinds[i].radix;
+ break;
+
+ case BT_REAL:
+ i = gfc_real_kinds[i].radix;
+ break;
+
+ default:
+ bad:
+ gfc_internal_error ("gfc_simplify_radix(): Bad type");
+ }
+
+ result = gfc_int_expr (i);
+ result->where = e->where;
+
+ return result;
+}
+
+
+gfc_expr *
+gfc_simplify_range (gfc_expr * e)
+{
+ gfc_expr *result;
+ int i;
+ long j;
+
+ i = gfc_validate_kind (e->ts.type, e->ts.kind);
+ if (i == -1)
+ goto bad_type;
+
+ switch (e->ts.type)
+ {
+ case BT_INTEGER:
+ j = gfc_integer_kinds[i].range;
+ break;
+
+ case BT_REAL:
+ case BT_COMPLEX:
+ j = gfc_real_kinds[i].range;
+ break;
+
+ bad_type:
+ default:
+ gfc_internal_error ("gfc_simplify_range(): Bad kind");
+ }
+
+ result = gfc_int_expr (j);
+ result->where = e->where;
+
+ return result;
+}
+
+
+gfc_expr *
+gfc_simplify_real (gfc_expr * e, gfc_expr * k)
+{
+ gfc_expr *result;
+ int kind;
+
+ if (e->ts.type == BT_COMPLEX)
+ kind = get_kind (BT_REAL, k, "REAL", e->ts.kind);
+ else
+ kind = get_kind (BT_REAL, k, "REAL", gfc_default_real_kind ());
+
+ if (kind == -1)
+ return &gfc_bad_expr;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ switch (e->ts.type)
+ {
+ case BT_INTEGER:
+ result = gfc_int2real (e, kind);
+ break;
+
+ case BT_REAL:
+ result = gfc_real2real (e, kind);
+ break;
+
+ case BT_COMPLEX:
+ result = gfc_complex2real (e, kind);
+ break;
+
+ default:
+ gfc_internal_error ("bad type in REAL");
+ /* Not reached */
+ }
+
+ return range_check (result, "REAL");
+}
+
+gfc_expr *
+gfc_simplify_repeat (gfc_expr * e, gfc_expr * n)
+{
+ gfc_expr *result;
+ int i, j, len, ncopies, nlen;
+
+ if (e->expr_type != EXPR_CONSTANT || n->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ if (n != NULL && (gfc_extract_int (n, &ncopies) != NULL || ncopies < 0))
+ {
+ gfc_error ("Invalid second argument of REPEAT at %L", &n->where);
+ return &gfc_bad_expr;
+ }
+
+ len = e->value.character.length;
+ nlen = ncopies * len;
+
+ result = gfc_constant_result (BT_CHARACTER, e->ts.kind, &e->where);
+
+ if (ncopies == 0)
+ {
+ result->value.character.string = gfc_getmem (1);
+ result->value.character.length = 0;
+ result->value.character.string[0] = '\0';
+ return result;
+ }
+
+ result->value.character.length = nlen;
+ result->value.character.string = gfc_getmem (nlen + 1);
+
+ for (i = 0; i < ncopies; i++)
+ for (j = 0; j < len; j++)
+ result->value.character.string[j + i * len] =
+ e->value.character.string[j];
+
+ result->value.character.string[nlen] = '\0'; /* For debugger */
+ return result;
+}
+
+
+/* This one is a bear, but mainly has to do with shuffling elements. */
+
+gfc_expr *
+gfc_simplify_reshape (gfc_expr * source, gfc_expr * shape_exp,
+ gfc_expr * pad, gfc_expr * order_exp)
+{
+
+ int order[GFC_MAX_DIMENSIONS], shape[GFC_MAX_DIMENSIONS];
+ int i, rank, npad, x[GFC_MAX_DIMENSIONS];
+ gfc_constructor *head, *tail;
+ mpz_t index, size;
+ unsigned long j;
+ size_t nsource;
+ gfc_expr *e;
+
+ /* Unpack the shape array. */
+ if (source->expr_type != EXPR_ARRAY || !gfc_is_constant_expr (source))
+ return NULL;
+
+ if (shape_exp->expr_type != EXPR_ARRAY || !gfc_is_constant_expr (shape_exp))
+ return NULL;
+
+ if (pad != NULL
+ && (pad->expr_type != EXPR_ARRAY
+ || !gfc_is_constant_expr (pad)))
+ return NULL;
+
+ if (order_exp != NULL
+ && (order_exp->expr_type != EXPR_ARRAY
+ || !gfc_is_constant_expr (order_exp)))
+ return NULL;
+
+ mpz_init (index);
+ rank = 0;
+ head = tail = NULL;
+
+ for (;;)
+ {
+ e = gfc_get_array_element (shape_exp, rank);
+ if (e == NULL)
+ break;
+
+ if (gfc_extract_int (e, &shape[rank]) != NULL)
+ {
+ gfc_error ("Integer too large in shape specification at %L",
+ &e->where);
+ gfc_free_expr (e);
+ goto bad_reshape;
+ }
+
+ gfc_free_expr (e);
+
+ if (rank >= GFC_MAX_DIMENSIONS)
+ {
+ gfc_error ("Too many dimensions in shape specification for RESHAPE "
+ "at %L", &e->where);
+
+ goto bad_reshape;
+ }
+
+ if (shape[rank] < 0)
+ {
+ gfc_error ("Shape specification at %L cannot be negative",
+ &e->where);
+ goto bad_reshape;
+ }
+
+ rank++;
+ }
+
+ if (rank == 0)
+ {
+ gfc_error ("Shape specification at %L cannot be the null array",
+ &shape_exp->where);
+ goto bad_reshape;
+ }
+
+ /* Now unpack the order array if present. */
+ if (order_exp == NULL)
+ {
+ for (i = 0; i < rank; i++)
+ order[i] = i;
+
+ }
+ else
+ {
+
+ for (i = 0; i < rank; i++)
+ x[i] = 0;
+
+ for (i = 0; i < rank; i++)
+ {
+ e = gfc_get_array_element (order_exp, i);
+ if (e == NULL)
+ {
+ gfc_error
+ ("ORDER parameter of RESHAPE at %L is not the same size "
+ "as SHAPE parameter", &order_exp->where);
+ goto bad_reshape;
+ }
+
+ if (gfc_extract_int (e, &order[i]) != NULL)
+ {
+ gfc_error ("Error in ORDER parameter of RESHAPE at %L",
+ &e->where);
+ gfc_free_expr (e);
+ goto bad_reshape;
+ }
+
+ gfc_free_expr (e);
+
+ if (order[i] < 1 || order[i] > rank)
+ {
+ gfc_error ("ORDER parameter of RESHAPE at %L is out of range",
+ &e->where);
+ goto bad_reshape;
+ }
+
+ order[i]--;
+
+ if (x[order[i]])
+ {
+ gfc_error ("Invalid permutation in ORDER parameter at %L",
+ &e->where);
+ goto bad_reshape;
+ }
+
+ x[order[i]] = 1;
+ }
+ }
+
+ /* Count the elements in the source and padding arrays. */
+
+ npad = 0;
+ if (pad != NULL)
+ {
+ gfc_array_size (pad, &size);
+ npad = mpz_get_ui (size);
+ mpz_clear (size);
+ }
+
+ gfc_array_size (source, &size);
+ nsource = mpz_get_ui (size);
+ mpz_clear (size);
+
+ /* If it weren't for that pesky permutation we could just loop
+ through the source and round out any shortage with pad elements.
+ But no, someone just had to have the compiler do something the
+ user should be doing. */
+
+ for (i = 0; i < rank; i++)
+ x[i] = 0;
+
+ for (;;)
+ {
+ /* Figure out which element to extract. */
+ mpz_set_ui (index, 0);
+
+ for (i = rank - 1; i >= 0; i--)
+ {
+ mpz_add_ui (index, index, x[order[i]]);
+ if (i != 0)
+ mpz_mul_ui (index, index, shape[order[i - 1]]);
+ }
+
+ if (mpz_cmp_ui (index, INT_MAX) > 0)
+ gfc_internal_error ("Reshaped array too large at %L", &e->where);
+
+ j = mpz_get_ui (index);
+
+ if (j < nsource)
+ e = gfc_get_array_element (source, j);
+ else
+ {
+ j = j - nsource;
+
+ if (npad == 0)
+ {
+ gfc_error
+ ("PAD parameter required for short SOURCE parameter at %L",
+ &source->where);
+ goto bad_reshape;
+ }
+
+ j = j % npad;
+ e = gfc_get_array_element (pad, j);
+ }
+
+ if (head == NULL)
+ head = tail = gfc_get_constructor ();
+ else
+ {
+ tail->next = gfc_get_constructor ();
+ tail = tail->next;
+ }
+
+ if (e == NULL)
+ goto bad_reshape;
+
+ tail->where = e->where;
+ tail->expr = e;
+
+ /* Calculate the next element. */
+ i = 0;
+
+inc:
+ if (++x[i] < shape[i])
+ continue;
+ x[i++] = 0;
+ if (i < rank)
+ goto inc;
+
+ break;
+ }
+
+ mpz_clear (index);
+
+ e = gfc_get_expr ();
+ e->where = source->where;
+ e->expr_type = EXPR_ARRAY;
+ e->value.constructor = head;
+ e->shape = gfc_get_shape (rank);
+
+ for (i = 0; i < rank; i++)
+ mpz_init_set_ui (e->shape[i], shape[order[i]]);
+
+ e->ts = head->expr->ts;
+ e->rank = rank;
+
+ return e;
+
+bad_reshape:
+ gfc_free_constructor (head);
+ mpz_clear (index);
+ return &gfc_bad_expr;
+}
+
+
+gfc_expr *
+gfc_simplify_rrspacing (gfc_expr * x)
+{
+ gfc_expr *result;
+ mpf_t i2, absv, ln2, lnx, frac, pow2;
+ unsigned long exp2;
+ int i, p;
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ i = gfc_validate_kind (x->ts.type, x->ts.kind);
+ if (i == -1)
+ gfc_internal_error ("gfc_simplify_rrspacing(): Bad kind");
+
+ result = gfc_constant_result (BT_REAL, x->ts.kind, &x->where);
+
+ p = gfc_real_kinds[i].digits;
+
+ if (mpf_cmp (x->value.real, mpf_zero) == 0)
+ {
+ mpf_ui_div (result->value.real, 1, gfc_real_kinds[i].tiny);
+ return result;
+ }
+
+ mpf_init_set_ui (i2, 2);
+ mpf_init (ln2);
+ mpf_init (absv);
+ mpf_init (lnx);
+ mpf_init (frac);
+ mpf_init (pow2);
+
+ natural_logarithm (&i2, &ln2);
+
+ mpf_abs (absv, x->value.real);
+ natural_logarithm (&absv, &lnx);
+
+ mpf_div (lnx, lnx, ln2);
+ mpf_trunc (lnx, lnx);
+ mpf_add_ui (lnx, lnx, 1);
+
+ exp2 = (unsigned long) mpf_get_d (lnx);
+ mpf_pow_ui (pow2, i2, exp2);
+ mpf_div (frac, absv, pow2);
+
+ exp2 = (unsigned long) p;
+ mpf_mul_2exp (result->value.real, frac, exp2);
+
+ mpf_clear (i2);
+ mpf_clear (ln2);
+ mpf_clear (absv);
+ mpf_clear (lnx);
+ mpf_clear (frac);
+ mpf_clear (pow2);
+
+ return range_check (result, "RRSPACING");
+}
+
+
+gfc_expr *
+gfc_simplify_scale (gfc_expr * x, gfc_expr * i)
+{
+ int k, neg_flag, power, exp_range;
+ mpf_t scale, radix;
+ gfc_expr *result;
+
+ if (x->expr_type != EXPR_CONSTANT || i->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (BT_REAL, x->ts.kind, &x->where);
+
+ if (mpf_sgn (x->value.real) == 0)
+ {
+ mpf_set_ui (result->value.real, 0);
+ return result;
+ }
+
+ k = gfc_validate_kind (BT_REAL, x->ts.kind);
+ if (k == -1)
+ gfc_internal_error ("gfc_simplify_scale(): Bad kind");
+
+ exp_range = gfc_real_kinds[k].max_exponent - gfc_real_kinds[k].min_exponent;
+
+ /* This check filters out values of i that would overflow an int. */
+ if (mpz_cmp_si (i->value.integer, exp_range + 2) > 0
+ || mpz_cmp_si (i->value.integer, -exp_range - 2) < 0)
+ {
+ gfc_error ("Result of SCALE overflows its kind at %L", &result->where);
+ return &gfc_bad_expr;
+ }
+
+ /* Compute scale = radix ** power. */
+ power = mpz_get_si (i->value.integer);
+
+ if (power >= 0)
+ neg_flag = 0;
+ else
+ {
+ neg_flag = 1;
+ power = -power;
+ }
+
+ mpf_init_set_ui (radix, gfc_real_kinds[k].radix);
+ mpf_init (scale);
+ mpf_pow_ui (scale, radix, power);
+
+ if (neg_flag)
+ mpf_div (result->value.real, x->value.real, scale);
+ else
+ mpf_mul (result->value.real, x->value.real, scale);
+
+ mpf_clear (scale);
+ mpf_clear (radix);
+
+ return range_check (result, "SCALE");
+}
+
+
+gfc_expr *
+gfc_simplify_scan (gfc_expr * e, gfc_expr * c, gfc_expr * b)
+{
+ gfc_expr *result;
+ int back;
+ size_t i;
+ size_t indx, len, lenc;
+
+ if (e->expr_type != EXPR_CONSTANT || c->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ if (b != NULL && b->value.logical != 0)
+ back = 1;
+ else
+ back = 0;
+
+ result = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind (),
+ &e->where);
+
+ len = e->value.character.length;
+ lenc = c->value.character.length;
+
+ if (len == 0 || lenc == 0)
+ {
+ indx = 0;
+ }
+ else
+ {
+ if (back == 0)
+ {
+ indx =
+ strcspn (e->value.character.string, c->value.character.string) + 1;
+ if (indx > len)
+ indx = 0;
+ }
+ else
+ {
+ i = 0;
+ for (indx = len; indx > 0; indx--)
+ {
+ for (i = 0; i < lenc; i++)
+ {
+ if (c->value.character.string[i]
+ == e->value.character.string[indx - 1])
+ break;
+ }
+ if (i < lenc)
+ break;
+ }
+ }
+ }
+ mpz_set_ui (result->value.integer, indx);
+ return range_check (result, "SCAN");
+}
+
+
+gfc_expr *
+gfc_simplify_selected_int_kind (gfc_expr * e)
+{
+ int i, kind, range;
+ gfc_expr *result;
+
+ if (e->expr_type != EXPR_CONSTANT || gfc_extract_int (e, &range) != NULL)
+ return NULL;
+
+ kind = INT_MAX;
+
+ for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
+ if (gfc_integer_kinds[i].range >= range
+ && gfc_integer_kinds[i].kind < kind)
+ kind = gfc_integer_kinds[i].kind;
+
+ if (kind == INT_MAX)
+ kind = -1;
+
+ result = gfc_int_expr (kind);
+ result->where = e->where;
+
+ return result;
+}
+
+
+gfc_expr *
+gfc_simplify_selected_real_kind (gfc_expr * p, gfc_expr * q)
+{
+ int range, precision, i, kind, found_precision, found_range;
+ gfc_expr *result;
+
+ if (p == NULL)
+ precision = 0;
+ else
+ {
+ if (p->expr_type != EXPR_CONSTANT
+ || gfc_extract_int (p, &precision) != NULL)
+ return NULL;
+ }
+
+ if (q == NULL)
+ range = 0;
+ else
+ {
+ if (q->expr_type != EXPR_CONSTANT
+ || gfc_extract_int (q, &range) != NULL)
+ return NULL;
+ }
+
+ kind = INT_MAX;
+ found_precision = 0;
+ found_range = 0;
+
+ for (i = 0; gfc_real_kinds[i].kind != 0; i++)
+ {
+ if (gfc_real_kinds[i].precision >= precision)
+ found_precision = 1;
+
+ if (gfc_real_kinds[i].range >= range)
+ found_range = 1;
+
+ if (gfc_real_kinds[i].precision >= precision
+ && gfc_real_kinds[i].range >= range && gfc_real_kinds[i].kind < kind)
+ kind = gfc_real_kinds[i].kind;
+ }
+
+ if (kind == INT_MAX)
+ {
+ kind = 0;
+
+ if (!found_precision)
+ kind = -1;
+ if (!found_range)
+ kind -= 2;
+ }
+
+ result = gfc_int_expr (kind);
+ result->where = (p != NULL) ? p->where : q->where;
+
+ return result;
+}
+
+
+gfc_expr *
+gfc_simplify_set_exponent (gfc_expr * x, gfc_expr * i)
+{
+ gfc_expr *result;
+ mpf_t i2, ln2, absv, lnx, pow2, frac;
+ unsigned long exp2;
+
+ if (x->expr_type != EXPR_CONSTANT || i->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (BT_REAL, x->ts.kind, &x->where);
+
+ if (mpf_cmp (x->value.real, mpf_zero) == 0)
+ {
+ mpf_set (result->value.real, mpf_zero);
+ return result;
+ }
+
+ mpf_init_set_ui (i2, 2);
+ mpf_init (ln2);
+ mpf_init (absv);
+ mpf_init (lnx);
+ mpf_init (pow2);
+ mpf_init (frac);
+
+ natural_logarithm (&i2, &ln2);
+
+ mpf_abs (absv, x->value.real);
+ natural_logarithm (&absv, &lnx);
+
+ mpf_div (lnx, lnx, ln2);
+ mpf_trunc (lnx, lnx);
+ mpf_add_ui (lnx, lnx, 1);
+
+ /* Old exponent value, and fraction. */
+ exp2 = (unsigned long) mpf_get_d (lnx);
+ mpf_pow_ui (pow2, i2, exp2);
+
+ mpf_div (frac, absv, pow2);
+
+ /* New exponent. */
+ exp2 = (unsigned long) mpz_get_d (i->value.integer);
+ mpf_mul_2exp (result->value.real, frac, exp2);
+
+ mpf_clear (i2);
+ mpf_clear (ln2);
+ mpf_clear (absv);
+ mpf_clear (lnx);
+ mpf_clear (pow2);
+ mpf_clear (frac);
+
+ return range_check (result, "SET_EXPONENT");
+}
+
+
+gfc_expr *
+gfc_simplify_shape (gfc_expr * source)
+{
+ mpz_t shape[GFC_MAX_DIMENSIONS];
+ gfc_expr *result, *e, *f;
+ gfc_array_ref *ar;
+ int n;
+ try t;
+
+ result = gfc_start_constructor (BT_INTEGER, gfc_default_integer_kind (),
+ &source->where);
+
+ if (source->rank == 0 || source->expr_type != EXPR_VARIABLE)
+ return result;
+
+ ar = gfc_find_array_ref (source);
+
+ t = gfc_array_ref_shape (ar, shape);
+
+ for (n = 0; n < source->rank; n++)
+ {
+ e = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind (),
+ &source->where);
+
+ if (t == SUCCESS)
+ {
+ mpz_set (e->value.integer, shape[n]);
+ mpz_clear (shape[n]);
+ }
+ else
+ {
+ mpz_set_ui (e->value.integer, n + 1);
+
+ f = gfc_simplify_size (source, e);
+ gfc_free_expr (e);
+ if (f == NULL)
+ {
+ gfc_free_expr (result);
+ return NULL;
+ }
+ else
+ {
+ e = f;
+ }
+ }
+
+ gfc_append_constructor (result, e);
+ }
+
+ return result;
+}
+
+
+gfc_expr *
+gfc_simplify_size (gfc_expr * array, gfc_expr * dim)
+{
+ mpz_t size;
+ gfc_expr *result;
+ int d;
+
+ if (dim == NULL)
+ {
+ if (gfc_array_size (array, &size) == FAILURE)
+ return NULL;
+ }
+ else
+ {
+ if (dim->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ d = mpz_get_ui (dim->value.integer) - 1;
+ if (gfc_array_dimen_size (array, d, &size) == FAILURE)
+ return NULL;
+ }
+
+ result = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind (),
+ &array->where);
+
+ mpz_set (result->value.integer, size);
+
+ return result;
+}
+
+
+gfc_expr *
+gfc_simplify_sign (gfc_expr * x, gfc_expr * y)
+{
+ gfc_expr *result;
+
+ if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+
+ switch (x->ts.type)
+ {
+ case BT_INTEGER:
+ mpz_abs (result->value.integer, x->value.integer);
+ if (mpz_sgn (y->value.integer) < 0)
+ mpz_neg (result->value.integer, result->value.integer);
+
+ break;
+
+ case BT_REAL:
+ /* TODO: Handle -0.0 and +0.0 correctly on machines that support
+ it. */
+ mpf_abs (result->value.real, x->value.real);
+ if (mpf_sgn (y->value.integer) < 0)
+ mpf_neg (result->value.real, result->value.real);
+
+ break;
+
+ default:
+ gfc_internal_error ("Bad type in gfc_simplify_sign");
+ }
+
+ return result;
+}
+
+
+gfc_expr *
+gfc_simplify_sin (gfc_expr * x)
+{
+ gfc_expr *result;
+ mpf_t xp, xq;
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+
+ switch (x->ts.type)
+ {
+ case BT_REAL:
+ sine (&x->value.real, &result->value.real);
+ break;
+
+ case BT_COMPLEX:
+ mpf_init (xp);
+ mpf_init (xq);
+
+ sine (&x->value.complex.r, &xp);
+ hypercos (&x->value.complex.i, &xq);
+ mpf_mul (result->value.complex.r, xp, xq);
+
+ cosine (&x->value.complex.r, &xp);
+ hypersine (&x->value.complex.i, &xq);
+ mpf_mul (result->value.complex.i, xp, xq);
+
+ mpf_clear (xp);
+ mpf_clear (xq);
+ break;
+
+ default:
+ gfc_internal_error ("in gfc_simplify_sin(): Bad type");
+ }
+
+ return range_check (result, "SIN");
+}
+
+
+gfc_expr *
+gfc_simplify_sinh (gfc_expr * x)
+{
+ gfc_expr *result;
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+
+ hypersine (&x->value.real, &result->value.real);
+
+ return range_check (result, "SINH");
+}
+
+
+/* The argument is always a double precision real that is converted to
+ single precision. TODO: Rounding! */
+
+gfc_expr *
+gfc_simplify_sngl (gfc_expr * a)
+{
+ gfc_expr *result;
+
+ if (a->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_real2real (a, gfc_default_real_kind ());
+ return range_check (result, "SNGL");
+}
+
+
+gfc_expr *
+gfc_simplify_spacing (gfc_expr * x)
+{
+ gfc_expr *result;
+ mpf_t i1, i2, ln2, absv, lnx;
+ long diff;
+ unsigned long exp2;
+ int i, p;
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ i = gfc_validate_kind (x->ts.type, x->ts.kind);
+ if (i == -1)
+ gfc_internal_error ("gfc_simplify_spacing(): Bad kind");
+
+ p = gfc_real_kinds[i].digits;
+
+ result = gfc_constant_result (BT_REAL, x->ts.kind, &x->where);
+
+ if (mpf_cmp (x->value.real, mpf_zero) == 0)
+ {
+ mpf_set (result->value.real, gfc_real_kinds[i].tiny);
+ return result;
+ }
+
+ mpf_init_set_ui (i1, 1);
+ mpf_init_set_ui (i2, 2);
+ mpf_init (ln2);
+ mpf_init (absv);
+ mpf_init (lnx);
+
+ natural_logarithm (&i2, &ln2);
+
+ mpf_abs (absv, x->value.real);
+ natural_logarithm (&absv, &lnx);
+
+ mpf_div (lnx, lnx, ln2);
+ mpf_trunc (lnx, lnx);
+ mpf_add_ui (lnx, lnx, 1);
+
+ diff = (long) mpf_get_d (lnx) - (long) p;
+ if (diff >= 0)
+ {
+ exp2 = (unsigned) diff;
+ mpf_mul_2exp (result->value.real, i1, exp2);
+ }
+ else
+ {
+ diff = -diff;
+ exp2 = (unsigned) diff;
+ mpf_div_2exp (result->value.real, i1, exp2);
+ }
+
+ mpf_clear (i1);
+ mpf_clear (i2);
+ mpf_clear (ln2);
+ mpf_clear (absv);
+ mpf_clear (lnx);
+
+ if (mpf_cmp (result->value.real, gfc_real_kinds[i].tiny) < 0)
+ mpf_set (result->value.real, gfc_real_kinds[i].tiny);
+
+ return range_check (result, "SPACING");
+}
+
+
+gfc_expr *
+gfc_simplify_sqrt (gfc_expr * e)
+{
+ gfc_expr *result;
+ mpf_t ac, ad, s, t, w;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (e->ts.type, e->ts.kind, &e->where);
+
+ switch (e->ts.type)
+ {
+ case BT_REAL:
+ if (mpf_cmp_si (e->value.real, 0) < 0)
+ goto negative_arg;
+ mpf_sqrt (result->value.real, e->value.real);
+
+ break;
+
+ case BT_COMPLEX:
+ /* Formula taken from Numerical Recipes to avoid over- and
+ underflow. */
+
+ mpf_init (ac);
+ mpf_init (ad);
+ mpf_init (s);
+ mpf_init (t);
+ mpf_init (w);
+
+ if (mpf_cmp_ui (e->value.complex.r, 0) == 0
+ && mpf_cmp_ui (e->value.complex.i, 0) == 0)
+ {
+
+ mpf_set_ui (result->value.complex.r, 0);
+ mpf_set_ui (result->value.complex.i, 0);
+ break;
+ }
+
+ mpf_abs (ac, e->value.complex.r);
+ mpf_abs (ad, e->value.complex.i);
+
+ if (mpf_cmp (ac, ad) >= 0)
+ {
+ mpf_div (t, e->value.complex.i, e->value.complex.r);
+ mpf_mul (t, t, t);
+ mpf_add_ui (t, t, 1);
+ mpf_sqrt (t, t);
+ mpf_add_ui (t, t, 1);
+ mpf_div_ui (t, t, 2);
+ mpf_sqrt (t, t);
+ mpf_sqrt (s, ac);
+ mpf_mul (w, s, t);
+ }
+ else
+ {
+ mpf_div (s, e->value.complex.r, e->value.complex.i);
+ mpf_mul (t, s, s);
+ mpf_add_ui (t, t, 1);
+ mpf_sqrt (t, t);
+ mpf_abs (s, s);
+ mpf_add (t, t, s);
+ mpf_div_ui (t, t, 2);
+ mpf_sqrt (t, t);
+ mpf_sqrt (s, ad);
+ mpf_mul (w, s, t);
+ }
+
+ if (mpf_cmp_ui (w, 0) != 0 && mpf_cmp_ui (e->value.complex.r, 0) >= 0)
+ {
+ mpf_mul_ui (t, w, 2);
+ mpf_div (result->value.complex.i, e->value.complex.i, t);
+ mpf_set (result->value.complex.r, w);
+ }
+ else if (mpf_cmp_ui (w, 0) != 0
+ && mpf_cmp_ui (e->value.complex.r, 0) < 0
+ && mpf_cmp_ui (e->value.complex.i, 0) >= 0)
+ {
+ mpf_mul_ui (t, w, 2);
+ mpf_div (result->value.complex.r, e->value.complex.i, t);
+ mpf_set (result->value.complex.i, w);
+ }
+ else if (mpf_cmp_ui (w, 0) != 0
+ && mpf_cmp_ui (e->value.complex.r, 0) < 0
+ && mpf_cmp_ui (e->value.complex.i, 0) < 0)
+ {
+ mpf_mul_ui (t, w, 2);
+ mpf_div (result->value.complex.r, ad, t);
+ mpf_neg (w, w);
+ mpf_set (result->value.complex.i, w);
+ }
+ else
+ gfc_internal_error ("invalid complex argument of SQRT at %L",
+ &e->where);
+
+ mpf_clear (s);
+ mpf_clear (t);
+ mpf_clear (ac);
+ mpf_clear (ad);
+ mpf_clear (w);
+
+ break;
+
+ default:
+ gfc_internal_error ("invalid argument of SQRT at %L", &e->where);
+ }
+
+ return range_check (result, "SQRT");
+
+negative_arg:
+ gfc_free_expr (result);
+ gfc_error ("Argument of SQRT at %L has a negative value", &e->where);
+ return &gfc_bad_expr;
+}
+
+
+gfc_expr *
+gfc_simplify_tan (gfc_expr * x)
+{
+ gfc_expr *result;
+ mpf_t mpf_sin, mpf_cos, mag_cos;
+ int i;
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ i = gfc_validate_kind (BT_REAL, x->ts.kind);
+ if (i == -1)
+ gfc_internal_error ("gfc_simplify_tan(): Bad kind");
+
+ result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+
+ mpf_init (mpf_sin);
+ mpf_init (mpf_cos);
+ mpf_init (mag_cos);
+ sine (&x->value.real, &mpf_sin);
+ cosine (&x->value.real, &mpf_cos);
+ mpf_abs (mag_cos, mpf_cos);
+ if (mpf_cmp_ui (mag_cos, 0) == 0)
+ {
+ gfc_error ("Tangent undefined at %L", &x->where);
+ mpf_clear (mpf_sin);
+ mpf_clear (mpf_cos);
+ mpf_clear (mag_cos);
+ gfc_free_expr (result);
+ return &gfc_bad_expr;
+ }
+ else if (mpf_cmp (mag_cos, gfc_real_kinds[i].tiny) < 0)
+ {
+ gfc_error ("Tangent cannot be accurately evaluated at %L", &x->where);
+ mpf_clear (mpf_sin);
+ mpf_clear (mpf_cos);
+ mpf_clear (mag_cos);
+ gfc_free_expr (result);
+ return &gfc_bad_expr;
+ }
+ else
+ {
+ mpf_div (result->value.real, mpf_sin, mpf_cos);
+ mpf_clear (mpf_sin);
+ mpf_clear (mpf_cos);
+ mpf_clear (mag_cos);
+ }
+
+ return range_check (result, "TAN");
+}
+
+
+gfc_expr *
+gfc_simplify_tanh (gfc_expr * x)
+{
+ gfc_expr *result;
+ mpf_t xp, xq;
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+
+ mpf_init (xp);
+ mpf_init (xq);
+
+ hypersine (&x->value.real, &xq);
+ hypercos (&x->value.real, &xp);
+
+ mpf_div (result->value.real, xq, xp);
+
+ mpf_clear (xp);
+ mpf_clear (xq);
+
+ return range_check (result, "TANH");
+
+}
+
+
+gfc_expr *
+gfc_simplify_tiny (gfc_expr * e)
+{
+ gfc_expr *result;
+ int i;
+
+ i = gfc_validate_kind (BT_REAL, e->ts.kind);
+ if (i == -1)
+ gfc_internal_error ("gfc_simplify_error(): Bad kind");
+
+ result = gfc_constant_result (BT_REAL, e->ts.kind, &e->where);
+ mpf_set (result->value.real, gfc_real_kinds[i].tiny);
+
+ return result;
+}
+
+
+gfc_expr *
+gfc_simplify_trim (gfc_expr * e)
+{
+ gfc_expr *result;
+ int count, i, len, lentrim;
+
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ len = e->value.character.length;
+
+ result = gfc_constant_result (BT_CHARACTER, e->ts.kind, &e->where);
+
+ for (count = 0, i = 1; i <= len; ++i)
+ {
+ if (e->value.character.string[len - i] == ' ')
+ count++;
+ else
+ break;
+ }
+
+ lentrim = len - count;
+
+ result->value.character.length = lentrim;
+ result->value.character.string = gfc_getmem (lentrim + 1);
+
+ for (i = 0; i < lentrim; i++)
+ result->value.character.string[i] = e->value.character.string[i];
+
+ result->value.character.string[lentrim] = '\0'; /* For debugger */
+
+ return result;
+}
+
+
+gfc_expr *
+gfc_simplify_ubound (gfc_expr * array, gfc_expr * dim)
+{
+ return gfc_simplify_bound (array, dim, 1);
+}
+
+
+gfc_expr *
+gfc_simplify_verify (gfc_expr * s, gfc_expr * set, gfc_expr * b)
+{
+ gfc_expr *result;
+ int back;
+ size_t index, len, lenset;
+ size_t i;
+
+ if (s->expr_type != EXPR_CONSTANT || set->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ if (b != NULL && b->value.logical != 0)
+ back = 1;
+ else
+ back = 0;
+
+ result = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind (),
+ &s->where);
+
+ len = s->value.character.length;
+ lenset = set->value.character.length;
+
+ if (len == 0)
+ {
+ mpz_set_ui (result->value.integer, 0);
+ return result;
+ }
+
+ if (back == 0)
+ {
+ if (lenset == 0)
+ {
+ mpz_set_ui (result->value.integer, len);
+ return result;
+ }
+
+ index =
+ strspn (s->value.character.string, set->value.character.string) + 1;
+ if (index > len)
+ index = 0;
+
+ }
+ else
+ {
+ if (lenset == 0)
+ {
+ mpz_set_ui (result->value.integer, 1);
+ return result;
+ }
+ for (index = len; index > 0; index --)
+ {
+ for (i = 0; i < lenset; i++)
+ {
+ if (s->value.character.string[index - 1]
+ == set->value.character.string[i])
+ break;
+ }
+ if (i == lenset)
+ break;
+ }
+ }
+
+ mpz_set_ui (result->value.integer, index);
+ return result;
+}
+
+/****************** Constant simplification *****************/
+
+/* Master function to convert one constant to another. While this is
+ used as a simplification function, it requires the destination type
+ and kind information which is supplied by a special case in
+ do_simplify(). */
+
+gfc_expr *
+gfc_convert_constant (gfc_expr * e, bt type, int kind)
+{
+ gfc_expr *g, *result, *(*f) (gfc_expr *, int);
+ gfc_constructor *head, *c, *tail = NULL;
+
+ switch (e->ts.type)
+ {
+ case BT_INTEGER:
+ switch (type)
+ {
+ case BT_INTEGER:
+ f = gfc_int2int;
+ break;
+ case BT_REAL:
+ f = gfc_int2real;
+ break;
+ case BT_COMPLEX:
+ f = gfc_int2complex;
+ break;
+ default:
+ goto oops;
+ }
+ break;
+
+ case BT_REAL:
+ switch (type)
+ {
+ case BT_INTEGER:
+ f = gfc_real2int;
+ break;
+ case BT_REAL:
+ f = gfc_real2real;
+ break;
+ case BT_COMPLEX:
+ f = gfc_real2complex;
+ break;
+ default:
+ goto oops;
+ }
+ break;
+
+ case BT_COMPLEX:
+ switch (type)
+ {
+ case BT_INTEGER:
+ f = gfc_complex2int;
+ break;
+ case BT_REAL:
+ f = gfc_complex2real;
+ break;
+ case BT_COMPLEX:
+ f = gfc_complex2complex;
+ break;
+
+ default:
+ goto oops;
+ }
+ break;
+
+ case BT_LOGICAL:
+ if (type != BT_LOGICAL)
+ goto oops;
+ f = gfc_log2log;
+ break;
+
+ default:
+ oops:
+ gfc_internal_error ("gfc_convert_constant(): Unexpected type");
+ }
+
+ result = NULL;
+
+ switch (e->expr_type)
+ {
+ case EXPR_CONSTANT:
+ result = f (e, kind);
+ if (result == NULL)
+ return &gfc_bad_expr;
+ break;
+
+ case EXPR_ARRAY:
+ if (!gfc_is_constant_expr (e))
+ break;
+
+ head = NULL;
+
+ for (c = e->value.constructor; c; c = c->next)
+ {
+ if (head == NULL)
+ head = tail = gfc_get_constructor ();
+ else
+ {
+ tail->next = gfc_get_constructor ();
+ tail = tail->next;
+ }
+
+ tail->where = c->where;
+
+ if (c->iterator == NULL)
+ tail->expr = f (c->expr, kind);
+ else
+ {
+ g = gfc_convert_constant (c->expr, type, kind);
+ if (g == &gfc_bad_expr)
+ return g;
+ tail->expr = g;
+ }
+
+ if (tail->expr == NULL)
+ {
+ gfc_free_constructor (head);
+ return NULL;
+ }
+ }
+
+ result = gfc_get_expr ();
+ result->ts.type = type;
+ result->ts.kind = kind;
+ result->expr_type = EXPR_ARRAY;
+ result->value.constructor = head;
+ result->shape = gfc_copy_shape (e->shape, e->rank);
+ result->where = e->where;
+ result->rank = e->rank;
+ break;
+
+ default:
+ break;
+ }
+
+ return result;
+}
+
+
+/****************** Helper functions ***********************/
+
+/* Given a collating table, create the inverse table. */
+
+static void
+invert_table (const int *table, int *xtable)
+{
+ int i;
+
+ for (i = 0; i < 256; i++)
+ xtable[i] = 0;
+
+ for (i = 0; i < 256; i++)
+ xtable[table[i]] = i;
+}
+
+
+void
+gfc_simplify_init_1 (void)
+{
+
+ mpf_init_set_str (mpf_zero, "0.0", 10);
+ mpf_init_set_str (mpf_half, "0.5", 10);
+ mpf_init_set_str (mpf_one, "1.0", 10);
+ mpz_init_set_str (mpz_zero, "0", 10);
+
+ invert_table (ascii_table, xascii_table);
+}
+
+
+void
+gfc_simplify_done_1 (void)
+{
+
+ mpf_clear (mpf_zero);
+ mpf_clear (mpf_half);
+ mpf_clear (mpf_one);
+ mpz_clear (mpz_zero);
+}
diff --git a/gcc/fortran/st.c b/gcc/fortran/st.c
new file mode 100644
index 00000000000..2e0a9896564
--- /dev/null
+++ b/gcc/fortran/st.c
@@ -0,0 +1,186 @@
+/* Build executable statement trees.
+ Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Executable statements are strung together into a singly linked list
+ of code structures. These structures are later translated into GCC
+ GENERIC tree structures and from there to executable code for a
+ target. */
+
+#include "config.h"
+#include "gfortran.h"
+#include <string.h>
+
+gfc_code new_st;
+
+
+/* Zeroes out the new_st structure. */
+
+void
+gfc_clear_new_st (void)
+{
+
+ memset (&new_st, '\0', sizeof (new_st));
+ new_st.op = EXEC_NOP;
+}
+
+
+/* Get a gfc_code structure. */
+
+gfc_code *
+gfc_get_code (void)
+{
+ gfc_code *c;
+
+ c = gfc_getmem (sizeof (gfc_code));
+ c->loc = *gfc_current_locus ();
+ return c;
+}
+
+
+/* Given some part of a gfc_code structure, append a set of code to
+ its tail, returning a pointer to the new tail. */
+
+gfc_code *
+gfc_append_code (gfc_code * tail, gfc_code * new)
+{
+
+ if (tail != NULL)
+ {
+ while (tail->next != NULL)
+ tail = tail->next;
+
+ tail->next = new;
+ }
+
+ while (new->next != NULL)
+ new = new->next;
+
+ return new;
+}
+
+
+/* Free a single code structure, but not the actual structure itself. */
+
+void
+gfc_free_statement (gfc_code * p)
+{
+
+ if (p->expr)
+ gfc_free_expr (p->expr);
+ if (p->expr2)
+ gfc_free_expr (p->expr2);
+
+ switch (p->op)
+ {
+ case EXEC_NOP:
+ case EXEC_ASSIGN:
+ case EXEC_GOTO:
+ case EXEC_CYCLE:
+ case EXEC_RETURN:
+ case EXEC_IF:
+ case EXEC_PAUSE:
+ case EXEC_STOP:
+ case EXEC_EXIT:
+ case EXEC_WHERE:
+ case EXEC_IOLENGTH:
+ case EXEC_POINTER_ASSIGN:
+ case EXEC_DO_WHILE:
+ case EXEC_CONTINUE:
+ case EXEC_TRANSFER:
+ case EXEC_LABEL_ASSIGN:
+
+ case EXEC_ARITHMETIC_IF:
+ break;
+
+ case EXEC_CALL:
+ gfc_free_actual_arglist (p->ext.actual);
+ break;
+
+ case EXEC_SELECT:
+ if (p->ext.case_list)
+ gfc_free_case_list (p->ext.case_list);
+ break;
+
+ case EXEC_DO:
+ gfc_free_iterator (p->ext.iterator, 1);
+ break;
+
+ case EXEC_ALLOCATE:
+ case EXEC_DEALLOCATE:
+ gfc_free_alloc_list (p->ext.alloc_list);
+ break;
+
+ case EXEC_OPEN:
+ gfc_free_open (p->ext.open);
+ break;
+
+ case EXEC_CLOSE:
+ gfc_free_close (p->ext.close);
+ break;
+
+ case EXEC_BACKSPACE:
+ case EXEC_ENDFILE:
+ case EXEC_REWIND:
+ gfc_free_filepos (p->ext.filepos);
+ break;
+
+ case EXEC_INQUIRE:
+ gfc_free_inquire (p->ext.inquire);
+ break;
+
+ case EXEC_READ:
+ case EXEC_WRITE:
+ gfc_free_dt (p->ext.dt);
+ break;
+
+ case EXEC_DT_END:
+ /* The ext.dt member is a duplicate pointer and doesn't need to
+ be freed. */
+ break;
+
+ case EXEC_FORALL:
+ gfc_free_forall_iterator (p->ext.forall_iterator);
+ break;
+
+ default:
+ gfc_internal_error ("gfc_free_statement(): Bad statement");
+ }
+}
+
+
+/* Free a code statement and all other code structures linked to it. */
+
+void
+gfc_free_statements (gfc_code * p)
+{
+ gfc_code *q;
+
+ for (; p; p = q)
+ {
+ q = p->next;
+
+ if (p->block)
+ gfc_free_statements (p->block);
+ gfc_free_statement (p);
+ gfc_free (p);
+ }
+}
+
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
new file mode 100644
index 00000000000..e7ea279d507
--- /dev/null
+++ b/gcc/fortran/symbol.c
@@ -0,0 +1,2417 @@
+/* Maintain binary trees of symbols.
+ Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#include "config.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "gfortran.h"
+#include "parse.h"
+
+/* Strings for all symbol attributes. We use these for dumping the
+ parse tree, in error messages, and also when reading and writing
+ modules. */
+
+const mstring flavors[] =
+{
+ minit ("UNKNOWN-FL", FL_UNKNOWN), minit ("PROGRAM", FL_PROGRAM),
+ minit ("BLOCK-DATA", FL_BLOCK_DATA), minit ("MODULE", FL_MODULE),
+ minit ("VARIABLE", FL_VARIABLE), minit ("PARAMETER", FL_PARAMETER),
+ minit ("LABEL", FL_LABEL), minit ("PROCEDURE", FL_PROCEDURE),
+ minit ("DERIVED", FL_DERIVED), minit ("NAMELIST", FL_NAMELIST),
+ minit (NULL, -1)
+};
+
+const mstring procedures[] =
+{
+ minit ("UNKNOWN-PROC", PROC_UNKNOWN),
+ minit ("MODULE-PROC", PROC_MODULE),
+ minit ("INTERNAL-PROC", PROC_INTERNAL),
+ minit ("DUMMY-PROC", PROC_DUMMY),
+ minit ("INTRINSIC-PROC", PROC_INTRINSIC),
+ minit ("EXTERNAL-PROC", PROC_EXTERNAL),
+ minit ("STATEMENT-PROC", PROC_ST_FUNCTION),
+ minit (NULL, -1)
+};
+
+const mstring intents[] =
+{
+ minit ("UNKNOWN-INTENT", INTENT_UNKNOWN),
+ minit ("IN", INTENT_IN),
+ minit ("OUT", INTENT_OUT),
+ minit ("INOUT", INTENT_INOUT),
+ minit (NULL, -1)
+};
+
+const mstring access_types[] =
+{
+ minit ("UNKNOWN-ACCESS", ACCESS_UNKNOWN),
+ minit ("PUBLIC", ACCESS_PUBLIC),
+ minit ("PRIVATE", ACCESS_PRIVATE),
+ minit (NULL, -1)
+};
+
+const mstring ifsrc_types[] =
+{
+ minit ("UNKNOWN", IFSRC_UNKNOWN),
+ minit ("DECL", IFSRC_DECL),
+ minit ("BODY", IFSRC_IFBODY),
+ minit ("USAGE", IFSRC_USAGE)
+};
+
+
+/* This is to make sure the backend generates setup code in the correct
+ order. */
+
+static int next_dummy_order = 1;
+
+
+gfc_namespace *gfc_current_ns;
+
+static gfc_symbol *changed_syms = NULL;
+
+
+/*********** IMPLICIT NONE and IMPLICIT statement handlers ***********/
+
+/* The following static variables hold the default types set by
+ IMPLICIT statements. We have to store kind information because of
+ IMPLICIT DOUBLE PRECISION statements. IMPLICIT NONE stores a
+ BT_UNKNOWN into all elements. The arrays of flags indicate whether
+ a particular element has been explicitly set or not. */
+
+static gfc_typespec new_ts[GFC_LETTERS];
+static int new_flag[GFC_LETTERS];
+
+
+/* Handle a correctly parsed IMPLICIT NONE. */
+
+void
+gfc_set_implicit_none (void)
+{
+ int i;
+
+ for (i = 'a'; i <= 'z'; i++)
+ {
+ gfc_clear_ts (&gfc_current_ns->default_type[i - 'a']);
+ gfc_current_ns->set_flag[i - 'a'] = 1;
+ }
+}
+
+
+/* Sets the implicit types parsed by gfc_match_implicit(). */
+
+void
+gfc_set_implicit (void)
+{
+ int i;
+
+ for (i = 0; i < GFC_LETTERS; i++)
+ if (new_flag[i])
+ {
+ gfc_current_ns->default_type[i] = new_ts[i];
+ gfc_current_ns->set_flag[i] = 1;
+ }
+}
+
+
+/* Wipe anything a previous IMPLICIT statement may have tried to do. */
+void gfc_clear_new_implicit (void)
+{
+ int i;
+
+ for (i = 0; i < GFC_LETTERS; i++)
+ {
+ gfc_clear_ts (&new_ts[i]);
+ if (new_flag[i])
+ new_flag[i] = 0;
+ }
+}
+
+
+/* Prepare for a new implicit range. Sets flags in new_flag[] and
+ copies the typespec to new_ts[]. */
+
+try gfc_add_new_implicit_range (int c1, int c2, gfc_typespec * ts)
+{
+ int i;
+
+ c1 -= 'a';
+ c2 -= 'a';
+
+ for (i = c1; i <= c2; i++)
+ {
+ if (new_flag[i])
+ {
+ gfc_error ("Letter '%c' already set in IMPLICIT statement at %C",
+ i + 'A');
+ return FAILURE;
+ }
+
+ new_ts[i] = *ts;
+ new_flag[i] = 1;
+ }
+
+ return SUCCESS;
+}
+
+
+/* Add a matched implicit range for gfc_set_implicit(). An implicit
+ statement has been fully matched at this point. We now need to
+ check if merging the new implicit types back into the existing
+ types will work. */
+
+try
+gfc_merge_new_implicit (void)
+{
+ int i;
+
+ for (i = 0; i < GFC_LETTERS; i++)
+ if (new_flag[i])
+ {
+ if (gfc_current_ns->set_flag[i])
+ {
+ gfc_error ("Letter %c already has an IMPLICIT type at %C",
+ i + 'A');
+ return FAILURE;
+ }
+ }
+
+ return SUCCESS;
+}
+
+
+/* Given a symbol, return a pointer to the typespec for it's default
+ type. */
+
+gfc_typespec *
+gfc_get_default_type (gfc_symbol * sym, gfc_namespace * ns)
+{
+ char letter;
+
+ letter = sym->name[0];
+ if (letter < 'a' || letter > 'z')
+ gfc_internal_error ("gfc_get_default_type(): Bad symbol");
+
+ if (ns == NULL)
+ ns = gfc_current_ns;
+
+ return &ns->default_type[letter - 'a'];
+}
+
+
+/* Given a pointer to a symbol, set its type according to the first
+ letter of its name. Fails if the letter in question has no default
+ type. */
+
+try
+gfc_set_default_type (gfc_symbol * sym, int error_flag, gfc_namespace * ns)
+{
+ gfc_typespec *ts;
+
+ if (sym->ts.type != BT_UNKNOWN)
+ gfc_internal_error ("gfc_set_default_type(): symbol already has a type");
+
+ ts = gfc_get_default_type (sym, ns);
+
+ if (ts->type == BT_UNKNOWN)
+ {
+ if (error_flag)
+ gfc_error ("Symbol '%s' at %L has no IMPLICIT type", sym->name,
+ &sym->declared_at);
+
+ return FAILURE;
+ }
+
+ sym->ts = *ts;
+ sym->attr.implicit_type = 1;
+
+ return SUCCESS;
+}
+
+
+/******************** Symbol attribute stuff *********************/
+
+/* This is a generic conflict-checker. We do this to avoid having a
+ single conflict in two places. */
+
+#define conf(a, b) if (attr->a && attr->b) { a1 = a; a2 = b; goto conflict; }
+#define conf2(a) if (attr->a) { a2 = a; goto conflict; }
+
+static try
+check_conflict (symbol_attribute * attr, locus * where)
+{
+ static const char *dummy = "DUMMY", *save = "SAVE", *pointer = "POINTER",
+ *target = "TARGET", *external = "EXTERNAL", *intent = "INTENT",
+ *intrinsic = "INTRINSIC", *allocatable = "ALLOCATABLE",
+ *elemental = "ELEMENTAL", *private = "PRIVATE", *recursive = "RECURSIVE",
+ *in_common = "COMMON", *result = "RESULT", *in_namelist = "NAMELIST",
+ *public = "PUBLIC", *optional = "OPTIONAL", *entry = "ENTRY",
+ *function = "FUNCTION", *subroutine = "SUBROUTINE",
+ *dimension = "DIMENSION";
+
+ const char *a1, *a2;
+
+ if (where == NULL)
+ where = gfc_current_locus ();
+
+ if (attr->pointer && attr->intent != INTENT_UNKNOWN)
+ {
+ a1 = pointer;
+ a2 = intent;
+ goto conflict;
+ }
+
+ /* Check for attributes not allowed in a BLOCK DATA. */
+ if (gfc_current_state () == COMP_BLOCK_DATA)
+ {
+ a1 = NULL;
+
+ if (attr->allocatable)
+ a1 = allocatable;
+ if (attr->external)
+ a1 = external;
+ if (attr->optional)
+ a1 = optional;
+ if (attr->access == ACCESS_PRIVATE)
+ a1 = private;
+ if (attr->access == ACCESS_PUBLIC)
+ a1 = public;
+ if (attr->intent != INTENT_UNKNOWN)
+ a1 = intent;
+
+ if (a1 != NULL)
+ {
+ gfc_error
+ ("%s attribute not allowed in BLOCK DATA program unit at %L", a1,
+ where);
+ return FAILURE;
+ }
+ }
+
+ conf (dummy, save);
+ conf (pointer, target);
+ conf (pointer, external);
+ conf (pointer, intrinsic);
+ conf (target, external);
+ conf (target, intrinsic);
+ conf (external, dimension); /* See Fortran 95's R504. */
+
+ conf (external, intrinsic);
+ conf (allocatable, pointer);
+ conf (allocatable, dummy); /* TODO: Allowed in Fortran 200x. */
+ conf (allocatable, function); /* TODO: Allowed in Fortran 200x. */
+ conf (allocatable, result); /* TODO: Allowed in Fortran 200x. */
+ conf (elemental, recursive);
+
+ conf (in_common, dummy);
+ conf (in_common, allocatable);
+ conf (in_common, result);
+ conf (dummy, result);
+
+ conf (in_namelist, pointer);
+ conf (in_namelist, allocatable);
+
+ conf (entry, result);
+
+ conf (function, subroutine);
+
+ a1 = gfc_code2string (flavors, attr->flavor);
+
+ if (attr->in_namelist
+ && attr->flavor != FL_VARIABLE
+ && attr->flavor != FL_UNKNOWN)
+ {
+
+ a2 = in_namelist;
+ goto conflict;
+ }
+
+ switch (attr->flavor)
+ {
+ case FL_PROGRAM:
+ case FL_BLOCK_DATA:
+ case FL_MODULE:
+ case FL_LABEL:
+ conf2 (dummy);
+ conf2 (save);
+ conf2 (pointer);
+ conf2 (target);
+ conf2 (external);
+ conf2 (intrinsic);
+ conf2 (allocatable);
+ conf2 (result);
+ conf2 (in_namelist);
+ conf2 (optional);
+ conf2 (function);
+ conf2 (subroutine);
+ break;
+
+ case FL_VARIABLE:
+ case FL_NAMELIST:
+ break;
+
+ case FL_PROCEDURE:
+ conf2 (intent);
+
+ if (attr->subroutine)
+ {
+ conf2(save);
+ conf2(pointer);
+ conf2(target);
+ conf2(allocatable);
+ conf2(result);
+ conf2(in_namelist);
+ conf2(function);
+ }
+
+ switch (attr->proc)
+ {
+ case PROC_ST_FUNCTION:
+ conf2 (in_common);
+ break;
+
+ case PROC_MODULE:
+ conf2 (dummy);
+ break;
+
+ case PROC_DUMMY:
+ conf2 (result);
+ conf2 (in_common);
+ conf2 (save);
+ break;
+
+ default:
+ break;
+ }
+
+ break;
+
+ case FL_DERIVED:
+ conf2 (dummy);
+ conf2 (save);
+ conf2 (pointer);
+ conf2 (target);
+ conf2 (external);
+ conf2 (intrinsic);
+ conf2 (allocatable);
+ conf2 (optional);
+ conf2 (entry);
+ conf2 (function);
+ conf2 (subroutine);
+
+ if (attr->intent != INTENT_UNKNOWN)
+ {
+ a2 = intent;
+ goto conflict;
+ }
+ break;
+
+ case FL_PARAMETER:
+ conf2 (external);
+ conf2 (intrinsic);
+ conf2 (optional);
+ conf2 (allocatable);
+ conf2 (function);
+ conf2 (subroutine);
+ conf2 (entry);
+ conf2 (pointer);
+ conf2 (target);
+ conf2 (dummy);
+ conf2 (in_common);
+ break;
+
+ default:
+ break;
+ }
+
+ return SUCCESS;
+
+conflict:
+ gfc_error ("%s attribute conflicts with %s attribute at %L", a1, a2, where);
+ return FAILURE;
+}
+
+#undef conf
+#undef conf2
+
+
+/* Mark a symbol as referenced. */
+
+void
+gfc_set_sym_referenced (gfc_symbol * sym)
+{
+ if (sym->attr.referenced)
+ return;
+
+ sym->attr.referenced = 1;
+
+ /* Remember which order dummy variables are accessed in. */
+ if (sym->attr.dummy)
+ sym->dummy_order = next_dummy_order++;
+}
+
+
+/* Common subroutine called by attribute changing subroutines in order
+ to prevent them from changing a symbol that has been
+ use-associated. Returns zero if it is OK to change the symbol,
+ nonzero if not. */
+
+static int
+check_used (symbol_attribute * attr, locus * where)
+{
+
+ if (attr->use_assoc == 0)
+ return 0;
+
+ if (where == NULL)
+ where = gfc_current_locus ();
+
+ gfc_error ("Cannot change attributes of USE-associated symbol at %L",
+ where);
+
+ return 1;
+}
+
+
+/* Used to prevent changing the attributes of a symbol after it has been
+ used. This check is only done from dummy variable as only these can be
+ used in specification expressions. Applying this to all symbols causes
+ error when we reach the body of a contained function. */
+
+static int
+check_done (symbol_attribute * attr, locus * where)
+{
+
+ if (!(attr->dummy && attr->referenced))
+ return 0;
+
+ if (where == NULL)
+ where = gfc_current_locus ();
+
+ gfc_error ("Cannot change attributes of symbol at %L"
+ " after it has been used", where);
+
+ return 1;
+}
+
+
+/* Generate an error because of a duplicate attribute. */
+
+static void
+duplicate_attr (const char *attr, locus * where)
+{
+
+ if (where == NULL)
+ where = gfc_current_locus ();
+
+ gfc_error ("Duplicate %s attribute specified at %L", attr, where);
+}
+
+
+try
+gfc_add_allocatable (symbol_attribute * attr, locus * where)
+{
+
+ if (check_used (attr, where) || check_done (attr, where))
+ return FAILURE;
+
+ if (attr->allocatable)
+ {
+ duplicate_attr ("ALLOCATABLE", where);
+ return FAILURE;
+ }
+
+ attr->allocatable = 1;
+ return check_conflict (attr, where);
+}
+
+
+try
+gfc_add_dimension (symbol_attribute * attr, locus * where)
+{
+
+ if (check_used (attr, where) || check_done (attr, where))
+ return FAILURE;
+
+ if (attr->dimension)
+ {
+ duplicate_attr ("DIMENSION", where);
+ return FAILURE;
+ }
+
+ attr->dimension = 1;
+ return check_conflict (attr, where);
+}
+
+
+try
+gfc_add_external (symbol_attribute * attr, locus * where)
+{
+
+ if (check_used (attr, where) || check_done (attr, where))
+ return FAILURE;
+
+ if (attr->external)
+ {
+ duplicate_attr ("EXTERNAL", where);
+ return FAILURE;
+ }
+
+ attr->external = 1;
+
+ return check_conflict (attr, where);
+}
+
+
+try
+gfc_add_intrinsic (symbol_attribute * attr, locus * where)
+{
+
+ if (check_used (attr, where) || check_done (attr, where))
+ return FAILURE;
+
+ if (attr->intrinsic)
+ {
+ duplicate_attr ("INTRINSIC", where);
+ return FAILURE;
+ }
+
+ attr->intrinsic = 1;
+
+ return check_conflict (attr, where);
+}
+
+
+try
+gfc_add_optional (symbol_attribute * attr, locus * where)
+{
+
+ if (check_used (attr, where) || check_done (attr, where))
+ return FAILURE;
+
+ if (attr->optional)
+ {
+ duplicate_attr ("OPTIONAL", where);
+ return FAILURE;
+ }
+
+ attr->optional = 1;
+ return check_conflict (attr, where);
+}
+
+
+try
+gfc_add_pointer (symbol_attribute * attr, locus * where)
+{
+
+ if (check_used (attr, where) || check_done (attr, where))
+ return FAILURE;
+
+ attr->pointer = 1;
+ return check_conflict (attr, where);
+}
+
+
+try
+gfc_add_result (symbol_attribute * attr, locus * where)
+{
+
+ if (check_used (attr, where) || check_done (attr, where))
+ return FAILURE;
+
+ attr->result = 1;
+ return check_conflict (attr, where);
+}
+
+
+try
+gfc_add_save (symbol_attribute * attr, locus * where)
+{
+
+ if (check_used (attr, where))
+ return FAILURE;
+
+ if (gfc_pure (NULL))
+ {
+ gfc_error
+ ("SAVE attribute at %L cannot be specified in a PURE procedure",
+ where);
+ return FAILURE;
+ }
+
+ if (attr->save)
+ {
+ duplicate_attr ("SAVE", where);
+ return FAILURE;
+ }
+
+ attr->save = 1;
+ return check_conflict (attr, where);
+}
+
+
+try
+gfc_add_saved_common (symbol_attribute * attr, locus * where)
+{
+
+ if (check_used (attr, where))
+ return FAILURE;
+
+ if (attr->saved_common)
+ {
+ duplicate_attr ("SAVE", where);
+ return FAILURE;
+ }
+
+ attr->saved_common = 1;
+ return check_conflict (attr, where);
+}
+
+
+try
+gfc_add_target (symbol_attribute * attr, locus * where)
+{
+
+ if (check_used (attr, where) || check_done (attr, where))
+ return FAILURE;
+
+ if (attr->target)
+ {
+ duplicate_attr ("TARGET", where);
+ return FAILURE;
+ }
+
+ attr->target = 1;
+ return check_conflict (attr, where);
+}
+
+
+try
+gfc_add_dummy (symbol_attribute * attr, locus * where)
+{
+
+ if (check_used (attr, where))
+ return FAILURE;
+
+ /* Duplicate dummy arguments are allow due to ENTRY statements. */
+ attr->dummy = 1;
+ return check_conflict (attr, where);
+}
+
+
+try
+gfc_add_common (symbol_attribute * attr, locus * where)
+{
+
+ if (check_used (attr, where) || check_done (attr, where))
+ return FAILURE;
+
+ attr->common = 1;
+ return check_conflict (attr, where);
+}
+
+
+try
+gfc_add_in_common (symbol_attribute * attr, locus * where)
+{
+
+ if (check_used (attr, where) || check_done (attr, where))
+ return FAILURE;
+
+ /* Duplicate attribute already checked for. */
+ attr->in_common = 1;
+ if (check_conflict (attr, where) == FAILURE)
+ return FAILURE;
+
+ if (attr->flavor == FL_VARIABLE)
+ return SUCCESS;
+
+ return gfc_add_flavor (attr, FL_VARIABLE, where);
+}
+
+
+try
+gfc_add_in_namelist (symbol_attribute * attr, locus * where)
+{
+
+ attr->in_namelist = 1;
+ return check_conflict (attr, where);
+}
+
+
+try
+gfc_add_sequence (symbol_attribute * attr, locus * where)
+{
+
+ if (check_used (attr, where))
+ return FAILURE;
+
+ attr->sequence = 1;
+ return check_conflict (attr, where);
+}
+
+
+try
+gfc_add_elemental (symbol_attribute * attr, locus * where)
+{
+
+ if (check_used (attr, where) || check_done (attr, where))
+ return FAILURE;
+
+ attr->elemental = 1;
+ return check_conflict (attr, where);
+}
+
+
+try
+gfc_add_pure (symbol_attribute * attr, locus * where)
+{
+
+ if (check_used (attr, where) || check_done (attr, where))
+ return FAILURE;
+
+ attr->pure = 1;
+ return check_conflict (attr, where);
+}
+
+
+try
+gfc_add_recursive (symbol_attribute * attr, locus * where)
+{
+
+ if (check_used (attr, where) || check_done (attr, where))
+ return FAILURE;
+
+ attr->recursive = 1;
+ return check_conflict (attr, where);
+}
+
+
+try
+gfc_add_entry (symbol_attribute * attr, locus * where)
+{
+
+ if (check_used (attr, where))
+ return FAILURE;
+
+ if (attr->entry)
+ {
+ duplicate_attr ("ENTRY", where);
+ return FAILURE;
+ }
+
+ attr->entry = 1;
+ return check_conflict (attr, where);
+}
+
+
+try
+gfc_add_function (symbol_attribute * attr, locus * where)
+{
+
+ if (attr->flavor != FL_PROCEDURE
+ && gfc_add_flavor (attr, FL_PROCEDURE, where) == FAILURE)
+ return FAILURE;
+
+ attr->function = 1;
+ return check_conflict (attr, where);
+}
+
+
+try
+gfc_add_subroutine (symbol_attribute * attr, locus * where)
+{
+
+ if (attr->flavor != FL_PROCEDURE
+ && gfc_add_flavor (attr, FL_PROCEDURE, where) == FAILURE)
+ return FAILURE;
+
+ attr->subroutine = 1;
+ return check_conflict (attr, where);
+}
+
+
+try
+gfc_add_generic (symbol_attribute * attr, locus * where)
+{
+
+ if (attr->flavor != FL_PROCEDURE
+ && gfc_add_flavor (attr, FL_PROCEDURE, where) == FAILURE)
+ return FAILURE;
+
+ attr->generic = 1;
+ return check_conflict (attr, where);
+}
+
+
+/* Flavors are special because some flavors are not what fortran
+ considers attributes and can be reaffirmed multiple times. */
+
+try
+gfc_add_flavor (symbol_attribute * attr, sym_flavor f, locus * where)
+{
+
+ if ((f == FL_PROGRAM || f == FL_BLOCK_DATA || f == FL_MODULE
+ || f == FL_PARAMETER || f == FL_LABEL || f == FL_DERIVED
+ || f == FL_NAMELIST) && check_used (attr, where))
+ return FAILURE;
+
+ if (attr->flavor == f && f == FL_VARIABLE)
+ return SUCCESS;
+
+ if (attr->flavor != FL_UNKNOWN)
+ {
+ if (where == NULL)
+ where = gfc_current_locus ();
+
+ gfc_error ("%s attribute conflicts with %s attribute at %L",
+ gfc_code2string (flavors, attr->flavor),
+ gfc_code2string (flavors, f), where);
+
+ return FAILURE;
+ }
+
+ attr->flavor = f;
+
+ return check_conflict (attr, where);
+}
+
+
+try
+gfc_add_procedure (symbol_attribute * attr, procedure_type t, locus * where)
+{
+
+ if (check_used (attr, where) || check_done (attr, where))
+ return FAILURE;
+
+ if (attr->flavor != FL_PROCEDURE
+ && gfc_add_flavor (attr, FL_PROCEDURE, where) == FAILURE)
+ return FAILURE;
+
+ if (where == NULL)
+ where = gfc_current_locus ();
+
+ if (attr->proc != PROC_UNKNOWN)
+ {
+ gfc_error ("%s procedure at %L is already %s %s procedure",
+ gfc_code2string (procedures, t), where,
+ gfc_article (gfc_code2string (procedures, attr->proc)),
+ gfc_code2string (procedures, attr->proc));
+
+ return FAILURE;
+ }
+
+ attr->proc = t;
+
+ /* Statement functions are always scalar and functions. */
+ if (t == PROC_ST_FUNCTION
+ && ((!attr->function && gfc_add_function (attr, where) == FAILURE)
+ || attr->dimension))
+ return FAILURE;
+
+ return check_conflict (attr, where);
+}
+
+
+try
+gfc_add_intent (symbol_attribute * attr, sym_intent intent, locus * where)
+{
+
+ if (check_used (attr, where))
+ return FAILURE;
+
+ if (attr->intent == INTENT_UNKNOWN)
+ {
+ attr->intent = intent;
+ return check_conflict (attr, where);
+ }
+
+ if (where == NULL)
+ where = gfc_current_locus ();
+
+ gfc_error ("INTENT (%s) conflicts with INTENT(%s) at %L",
+ gfc_intent_string (attr->intent),
+ gfc_intent_string (intent), where);
+
+ return FAILURE;
+}
+
+
+/* No checks for use-association in public and private statements. */
+
+try
+gfc_add_access (symbol_attribute * attr, gfc_access access, locus * where)
+{
+
+ if (attr->access == ACCESS_UNKNOWN)
+ {
+ attr->access = access;
+ return check_conflict (attr, where);
+ }
+
+ if (where == NULL)
+ where = gfc_current_locus ();
+ gfc_error ("ACCESS specification at %L was already specified", where);
+
+ return FAILURE;
+}
+
+
+try
+gfc_add_explicit_interface (gfc_symbol * sym, ifsrc source,
+ gfc_formal_arglist * formal, locus * where)
+{
+
+ if (check_used (&sym->attr, where))
+ return FAILURE;
+
+ if (where == NULL)
+ where = gfc_current_locus ();
+
+ if (sym->attr.if_source != IFSRC_UNKNOWN
+ && sym->attr.if_source != IFSRC_DECL)
+ {
+ gfc_error ("Symbol '%s' at %L already has an explicit interface",
+ sym->name, where);
+ return FAILURE;
+ }
+
+ sym->formal = formal;
+ sym->attr.if_source = source;
+
+ return SUCCESS;
+}
+
+
+/* Add a type to a symbol. */
+
+try
+gfc_add_type (gfc_symbol * sym, gfc_typespec * ts, locus * where)
+{
+ sym_flavor flavor;
+
+/* TODO: This is legal if it is reaffirming an implicit type.
+ if (check_done (&sym->attr, where))
+ return FAILURE;*/
+
+ if (where == NULL)
+ where = gfc_current_locus ();
+
+ if (sym->ts.type != BT_UNKNOWN)
+ {
+ gfc_error ("Symbol '%s' at %L already has basic type of %s", sym->name,
+ where, gfc_basic_typename (sym->ts.type));
+ return FAILURE;
+ }
+
+ flavor = sym->attr.flavor;
+
+ if (flavor == FL_PROGRAM || flavor == FL_BLOCK_DATA || flavor == FL_MODULE
+ || flavor == FL_LABEL || (flavor == FL_PROCEDURE
+ && sym->attr.subroutine)
+ || flavor == FL_DERIVED || flavor == FL_NAMELIST)
+ {
+ gfc_error ("Symbol '%s' at %L cannot have a type", sym->name, where);
+ return FAILURE;
+ }
+
+ sym->ts = *ts;
+ return SUCCESS;
+}
+
+
+/* Clears all attributes. */
+
+void
+gfc_clear_attr (symbol_attribute * attr)
+{
+
+ attr->allocatable = 0;
+ attr->dimension = 0;
+ attr->external = 0;
+ attr->intrinsic = 0;
+ attr->optional = 0;
+ attr->pointer = 0;
+ attr->save = 0;
+ attr->target = 0;
+ attr->dummy = 0;
+ attr->common = 0;
+ attr->result = 0;
+ attr->entry = 0;
+ attr->data = 0;
+ attr->use_assoc = 0;
+ attr->in_namelist = 0;
+
+ attr->in_common = 0;
+ attr->saved_common = 0;
+ attr->function = 0;
+ attr->subroutine = 0;
+ attr->generic = 0;
+ attr->implicit_type = 0;
+ attr->sequence = 0;
+ attr->elemental = 0;
+ attr->pure = 0;
+ attr->recursive = 0;
+
+ attr->access = ACCESS_UNKNOWN;
+ attr->intent = INTENT_UNKNOWN;
+ attr->flavor = FL_UNKNOWN;
+ attr->proc = PROC_UNKNOWN;
+ attr->if_source = IFSRC_UNKNOWN;
+}
+
+
+/* Check for missing attributes in the new symbol. Currently does
+ nothing, but it's not clear that it is unnecessary yet. */
+
+try
+gfc_missing_attr (symbol_attribute * attr ATTRIBUTE_UNUSED,
+ locus * where ATTRIBUTE_UNUSED)
+{
+
+ return SUCCESS;
+}
+
+
+/* Copy an attribute to a symbol attribute, bit by bit. Some
+ attributes have a lot of side-effects but cannot be present given
+ where we are called from, so we ignore some bits. */
+
+try
+gfc_copy_attr (symbol_attribute * dest, symbol_attribute * src, locus * where)
+{
+
+ if (src->allocatable && gfc_add_allocatable (dest, where) == FAILURE)
+ goto fail;
+
+ if (src->dimension && gfc_add_dimension (dest, where) == FAILURE)
+ goto fail;
+ if (src->optional && gfc_add_optional (dest, where) == FAILURE)
+ goto fail;
+ if (src->pointer && gfc_add_pointer (dest, where) == FAILURE)
+ goto fail;
+ if (src->save && gfc_add_save (dest, where) == FAILURE)
+ goto fail;
+ if (src->target && gfc_add_target (dest, where) == FAILURE)
+ goto fail;
+ if (src->dummy && gfc_add_dummy (dest, where) == FAILURE)
+ goto fail;
+ if (src->common && gfc_add_common (dest, where) == FAILURE)
+ goto fail;
+ if (src->result && gfc_add_result (dest, where) == FAILURE)
+ goto fail;
+ if (src->entry)
+ dest->entry = 1;
+
+ if (src->in_namelist && gfc_add_in_namelist (dest, where) == FAILURE)
+ goto fail;
+
+ if (src->in_common && gfc_add_in_common (dest, where) == FAILURE)
+ goto fail;
+ if (src->saved_common && gfc_add_saved_common (dest, where) == FAILURE)
+ goto fail;
+
+ if (src->generic && gfc_add_generic (dest, where) == FAILURE)
+ goto fail;
+ if (src->function && gfc_add_function (dest, where) == FAILURE)
+ goto fail;
+ if (src->subroutine && gfc_add_subroutine (dest, where) == FAILURE)
+ goto fail;
+
+ if (src->sequence && gfc_add_sequence (dest, where) == FAILURE)
+ goto fail;
+ if (src->elemental && gfc_add_elemental (dest, where) == FAILURE)
+ goto fail;
+ if (src->pure && gfc_add_pure (dest, where) == FAILURE)
+ goto fail;
+ if (src->recursive && gfc_add_recursive (dest, where) == FAILURE)
+ goto fail;
+
+ if (src->flavor != FL_UNKNOWN
+ && gfc_add_flavor (dest, src->flavor, where) == FAILURE)
+ goto fail;
+
+ if (src->intent != INTENT_UNKNOWN
+ && gfc_add_intent (dest, src->intent, where) == FAILURE)
+ goto fail;
+
+ if (src->access != ACCESS_UNKNOWN
+ && gfc_add_access (dest, src->access, where) == FAILURE)
+ goto fail;
+
+ if (gfc_missing_attr (dest, where) == FAILURE)
+ goto fail;
+
+ /* The subroutines that set these bits also cause flavors to be set,
+ and that has already happened in the original, so don't let to
+ happen again. */
+ if (src->external)
+ dest->external = 1;
+ if (src->intrinsic)
+ dest->intrinsic = 1;
+
+ return SUCCESS;
+
+fail:
+ return FAILURE;
+}
+
+
+/************** Component name management ************/
+
+/* Component names of a derived type form their own little namespaces
+ that are separate from all other spaces. The space is composed of
+ a singly linked list of gfc_component structures whose head is
+ located in the parent symbol. */
+
+
+/* Add a component name to a symbol. The call fails if the name is
+ already present. On success, the component pointer is modified to
+ point to the additional component structure. */
+
+try
+gfc_add_component (gfc_symbol * sym, const char *name, gfc_component ** component)
+{
+ gfc_component *p, *tail;
+
+ tail = NULL;
+
+ for (p = sym->components; p; p = p->next)
+ {
+ if (strcmp (p->name, name) == 0)
+ {
+ gfc_error ("Component '%s' at %C already declared at %L",
+ name, &p->loc);
+ return FAILURE;
+ }
+
+ tail = p;
+ }
+
+ /* Allocate new component */
+ p = gfc_get_component ();
+
+ if (tail == NULL)
+ sym->components = p;
+ else
+ tail->next = p;
+
+ strcpy (p->name, name);
+ p->loc = *gfc_current_locus ();
+
+ *component = p;
+ return SUCCESS;
+}
+
+
+/* Recursive function to switch derived types of all symbol in a
+ namespace. */
+
+static void
+switch_types (gfc_symtree * st, gfc_symbol * from, gfc_symbol * to)
+{
+ gfc_symbol *sym;
+
+ if (st == NULL)
+ return;
+
+ sym = st->n.sym;
+ if (sym->ts.type == BT_DERIVED && sym->ts.derived == from)
+ sym->ts.derived = to;
+
+ switch_types (st->left, from, to);
+ switch_types (st->right, from, to);
+}
+
+
+/* This subroutine is called when a derived type is used in order to
+ make the final determination about which version to use. The
+ standard requires that a type be defined before it is 'used', but
+ such types can appear in IMPLICIT statements before the actual
+ definition. 'Using' in this context means declaring a variable to
+ be that type or using the type constructor.
+
+ If a type is used and the components haven't been defined, then we
+ have to have a derived type in a parent unit. We find the node in
+ the other namespace and point the symtree node in this namespace to
+ that node. Further reference to this name point to the correct
+ node. If we can't find the node in a parent namespace, then have
+ an error.
+
+ This subroutine takes a pointer to a symbol node and returns a
+ pointer to the translated node or NULL for an error. Usually there
+ is no translation and we return the node we were passed. */
+
+static gfc_symtree *
+gfc_use_ha_derived (gfc_symbol * sym)
+{
+ gfc_symbol *s, *p;
+ gfc_typespec *t;
+ gfc_symtree *st;
+ int i;
+
+ if (sym->ns->parent == NULL)
+ goto bad;
+
+ if (gfc_find_symbol (sym->name, sym->ns->parent, 1, &s))
+ {
+ gfc_error ("Symbol '%s' at %C is ambiguous", sym->name);
+ return NULL;
+ }
+
+ if (s == NULL || s->attr.flavor != FL_DERIVED)
+ goto bad;
+
+ /* Get rid of symbol sym, translating all references to s. */
+ for (i = 0; i < GFC_LETTERS; i++)
+ {
+ t = &sym->ns->default_type[i];
+ if (t->derived == sym)
+ t->derived = s;
+ }
+
+ st = gfc_find_symtree (sym->ns->sym_root, sym->name);
+ st->n.sym = s;
+
+ s->refs++;
+
+ /* Unlink from list of modified symbols. */
+ if (changed_syms == sym)
+ changed_syms = sym->tlink;
+ else
+ for (p = changed_syms; p; p = p->tlink)
+ if (p->tlink == sym)
+ {
+ p->tlink = sym->tlink;
+ break;
+ }
+
+ switch_types (sym->ns->sym_root, sym, s);
+
+ /* TODO: Also have to replace sym -> s in other lists like
+ namelists, common lists and interface lists. */
+ gfc_free_symbol (sym);
+
+ return st;
+
+bad:
+ gfc_error ("Derived type '%s' at %C is being used before it is defined",
+ sym->name);
+ return NULL;
+}
+
+
+gfc_symbol *
+gfc_use_derived (gfc_symbol * sym)
+{
+ gfc_symtree *st;
+
+ if (sym->components != NULL)
+ return sym; /* Already defined */
+
+ st = gfc_use_ha_derived (sym);
+ if (st)
+ return st->n.sym;
+ else
+ return NULL;
+}
+
+
+/* Given a derived type node and a component name, try to locate the
+ component structure. Returns the NULL pointer if the component is
+ not found or the components are private. */
+
+gfc_component *
+gfc_find_component (gfc_symbol * sym, const char *name)
+{
+ gfc_component *p;
+
+ if (name == NULL)
+ return NULL;
+
+ sym = gfc_use_derived (sym);
+
+ if (sym == NULL)
+ return NULL;
+
+ for (p = sym->components; p; p = p->next)
+ if (strcmp (p->name, name) == 0)
+ break;
+
+ if (p == NULL)
+ gfc_error ("'%s' at %C is not a member of the '%s' structure",
+ name, sym->name);
+ else
+ {
+ if (sym->attr.use_assoc && sym->component_access == ACCESS_PRIVATE)
+ {
+ gfc_error ("Component '%s' at %C is a PRIVATE component of '%s'",
+ name, sym->name);
+ p = NULL;
+ }
+ }
+
+ return p;
+}
+
+
+/* Given a symbol, free all of the component structures and everything
+ they point to. */
+
+static void
+free_components (gfc_component * p)
+{
+ gfc_component *q;
+
+ for (; p; p = q)
+ {
+ q = p->next;
+
+ gfc_free_array_spec (p->as);
+ gfc_free_expr (p->initializer);
+
+ gfc_free (p);
+ }
+}
+
+
+/* Set component attributes from a standard symbol attribute
+ structure. */
+
+void
+gfc_set_component_attr (gfc_component * c, symbol_attribute * attr)
+{
+
+ c->dimension = attr->dimension;
+ c->pointer = attr->pointer;
+}
+
+
+/* Get a standard symbol attribute structure given the component
+ structure. */
+
+void
+gfc_get_component_attr (symbol_attribute * attr, gfc_component * c)
+{
+
+ gfc_clear_attr (attr);
+ attr->dimension = c->dimension;
+ attr->pointer = c->pointer;
+}
+
+
+/******************** Statement label management ********************/
+
+/* Free a single gfc_st_label structure, making sure the list is not
+ messed up. This function is called only when some parse error
+ occurs. */
+
+void
+gfc_free_st_label (gfc_st_label * l)
+{
+
+ if (l == NULL)
+ return;
+
+ if (l->prev)
+ (l->prev->next = l->next);
+
+ if (l->next)
+ (l->next->prev = l->prev);
+
+ if (l->format != NULL)
+ gfc_free_expr (l->format);
+ gfc_free (l);
+}
+
+/* Free a whole list of gfc_st_label structures. */
+
+static void
+free_st_labels (gfc_st_label * l1)
+{
+ gfc_st_label *l2;
+
+ for (; l1; l1 = l2)
+ {
+ l2 = l1->next;
+ if (l1->format != NULL)
+ gfc_free_expr (l1->format);
+ gfc_free (l1);
+ }
+}
+
+
+/* Given a label number, search for and return a pointer to the label
+ structure, creating it if it does not exist. */
+
+gfc_st_label *
+gfc_get_st_label (int labelno)
+{
+ gfc_st_label *lp;
+
+ /* First see if the label is already in this namespace. */
+ for (lp = gfc_current_ns->st_labels; lp; lp = lp->next)
+ if (lp->value == labelno)
+ break;
+ if (lp != NULL)
+ return lp;
+
+ lp = gfc_getmem (sizeof (gfc_st_label));
+
+ lp->value = labelno;
+ lp->defined = ST_LABEL_UNKNOWN;
+ lp->referenced = ST_LABEL_UNKNOWN;
+
+ lp->prev = NULL;
+ lp->next = gfc_current_ns->st_labels;
+ if (gfc_current_ns->st_labels)
+ gfc_current_ns->st_labels->prev = lp;
+ gfc_current_ns->st_labels = lp;
+
+ return lp;
+}
+
+
+/* Called when a statement with a statement label is about to be
+ accepted. We add the label to the list of the current namespace,
+ making sure it hasn't been defined previously and referenced
+ correctly. */
+
+void
+gfc_define_st_label (gfc_st_label * lp, gfc_sl_type type, locus * label_locus)
+{
+ int labelno;
+
+ labelno = lp->value;
+
+ if (lp->defined != ST_LABEL_UNKNOWN)
+ gfc_error ("Duplicate statement label %d at %L and %L", labelno,
+ &lp->where, label_locus);
+ else
+ {
+ lp->where = *label_locus;
+
+ switch (type)
+ {
+ case ST_LABEL_FORMAT:
+ if (lp->referenced == ST_LABEL_TARGET)
+ gfc_error ("Label %d at %C already referenced as branch target",
+ labelno);
+ else
+ lp->defined = ST_LABEL_FORMAT;
+
+ break;
+
+ case ST_LABEL_TARGET:
+ if (lp->referenced == ST_LABEL_FORMAT)
+ gfc_error ("Label %d at %C already referenced as a format label",
+ labelno);
+ else
+ lp->defined = ST_LABEL_TARGET;
+
+ break;
+
+ default:
+ lp->defined = ST_LABEL_BAD_TARGET;
+ lp->referenced = ST_LABEL_BAD_TARGET;
+ }
+ }
+}
+
+
+/* Reference a label. Given a label and its type, see if that
+ reference is consistent with what is known about that label,
+ updating the unknown state. Returns FAILURE if something goes
+ wrong. */
+
+try
+gfc_reference_st_label (gfc_st_label * lp, gfc_sl_type type)
+{
+ gfc_sl_type label_type;
+ int labelno;
+ try rc;
+
+ if (lp == NULL)
+ return SUCCESS;
+
+ labelno = lp->value;
+
+ if (lp->defined != ST_LABEL_UNKNOWN)
+ label_type = lp->defined;
+ else
+ {
+ label_type = lp->referenced;
+ lp->where = *gfc_current_locus ();
+ }
+
+ if (label_type == ST_LABEL_FORMAT && type == ST_LABEL_TARGET)
+ {
+ gfc_error ("Label %d at %C previously used as a FORMAT label", labelno);
+ rc = FAILURE;
+ goto done;
+ }
+
+ if ((label_type == ST_LABEL_TARGET || label_type == ST_LABEL_BAD_TARGET)
+ && type == ST_LABEL_FORMAT)
+ {
+ gfc_error ("Label %d at %C previously used as branch target", labelno);
+ rc = FAILURE;
+ goto done;
+ }
+
+ lp->referenced = type;
+ rc = SUCCESS;
+
+done:
+ return rc;
+}
+
+
+/************** Symbol table management subroutines ****************/
+
+/* Basic details: Fortran 95 requires a potentially unlimited number
+ of distinct namespaces when compiling a program unit. This case
+ occurs during a compilation of internal subprograms because all of
+ the internal subprograms must be read before we can start
+ generating code for the host.
+
+ Given the tricky nature of the fortran grammar, we must be able to
+ undo changes made to a symbol table if the current interpretation
+ of a statement is found to be incorrect. Whenever a symbol is
+ looked up, we make a copy of it and link to it. All of these
+ symbols are kept in a singly linked list so that we can commit or
+ undo the changes at a later time.
+
+ A symtree may point to a symbol node outside of it's namespace. In
+ this case, that symbol has been used as a host associated variable
+ at some previous time. */
+
+/* Allocate a new namespace structure. */
+
+gfc_namespace *
+gfc_get_namespace (gfc_namespace * parent)
+{
+ gfc_namespace *ns;
+ gfc_typespec *ts;
+ gfc_intrinsic_op in;
+ int i;
+
+ ns = gfc_getmem (sizeof (gfc_namespace));
+ ns->sym_root = NULL;
+ ns->uop_root = NULL;
+ ns->default_access = ACCESS_UNKNOWN;
+ ns->parent = parent;
+
+ for (in = GFC_INTRINSIC_BEGIN; in != GFC_INTRINSIC_END; in++)
+ ns->operator_access[in] = ACCESS_UNKNOWN;
+
+ /* Initialize default implicit types. */
+ for (i = 'a'; i <= 'z'; i++)
+ {
+ ns->set_flag[i - 'a'] = 0;
+ ts = &ns->default_type[i - 'a'];
+
+ if (ns->parent != NULL)
+ {
+ /* Copy parent settings */
+ *ts = ns->parent->default_type[i - 'a'];
+ continue;
+ }
+
+ if (gfc_option.flag_implicit_none != 0)
+ {
+ gfc_clear_ts (ts);
+ continue;
+ }
+
+ if ('i' <= i && i <= 'n')
+ {
+ ts->type = BT_INTEGER;
+ ts->kind = gfc_default_integer_kind ();
+ }
+ else
+ {
+ ts->type = BT_REAL;
+ ts->kind = gfc_default_real_kind ();
+ }
+ }
+
+ return ns;
+}
+
+
+/* Comparison function for symtree nodes. */
+
+static int
+compare_symtree (void * _st1, void * _st2)
+{
+ gfc_symtree *st1, *st2;
+
+ st1 = (gfc_symtree *) _st1;
+ st2 = (gfc_symtree *) _st2;
+
+ return strcmp (st1->name, st2->name);
+}
+
+
+/* Allocate a new symtree node and associate it with the new symbol. */
+
+gfc_symtree *
+gfc_new_symtree (gfc_symtree ** root, const char *name)
+{
+ gfc_symtree *st;
+
+ st = gfc_getmem (sizeof (gfc_symtree));
+ strcpy (st->name, name);
+
+ gfc_insert_bbt (root, st, compare_symtree);
+ return st;
+}
+
+
+/* Delete a symbol from the tree. Does not free the symbol itself! */
+
+static void
+delete_symtree (gfc_symtree ** root, const char *name)
+{
+ gfc_symtree st, *st0;
+
+ st0 = gfc_find_symtree (*root, name);
+
+ strcpy (st.name, name);
+ gfc_delete_bbt (root, &st, compare_symtree);
+
+ gfc_free (st0);
+}
+
+
+/* Given a root symtree node and a name, try to find the symbol within
+ the namespace. Returns NULL if the symbol is not found. */
+
+gfc_symtree *
+gfc_find_symtree (gfc_symtree * st, const char *name)
+{
+ int c;
+
+ while (st != NULL)
+ {
+ c = strcmp (name, st->name);
+ if (c == 0)
+ return st;
+
+ st = (c < 0) ? st->left : st->right;
+ }
+
+ return NULL;
+}
+
+
+/* Given a name find a user operator node, creating it if it doesn't
+ exist. These are much simpler than symbols because they can't be
+ ambiguous with one another. */
+
+gfc_user_op *
+gfc_get_uop (const char *name)
+{
+ gfc_user_op *uop;
+ gfc_symtree *st;
+
+ st = gfc_find_symtree (gfc_current_ns->uop_root, name);
+ if (st != NULL)
+ return st->n.uop;
+
+ st = gfc_new_symtree (&gfc_current_ns->uop_root, name);
+
+ uop = st->n.uop = gfc_getmem (sizeof (gfc_user_op));
+ strcpy (uop->name, name);
+ uop->access = ACCESS_UNKNOWN;
+ uop->ns = gfc_current_ns;
+
+ return uop;
+}
+
+
+/* Given a name find the user operator node. Returns NULL if it does
+ not exist. */
+
+gfc_user_op *
+gfc_find_uop (const char *name, gfc_namespace * ns)
+{
+ gfc_symtree *st;
+
+ if (ns == NULL)
+ ns = gfc_current_ns;
+
+ st = gfc_find_symtree (ns->uop_root, name);
+ return (st == NULL) ? NULL : st->n.uop;
+}
+
+
+/* Remove a gfc_symbol structure and everything it points to. */
+
+void
+gfc_free_symbol (gfc_symbol * sym)
+{
+
+ if (sym == NULL)
+ return;
+
+ gfc_free_array_spec (sym->as);
+
+ free_components (sym->components);
+
+ gfc_free_expr (sym->value);
+
+ gfc_free_namelist (sym->namelist);
+
+ gfc_free_namespace (sym->formal_ns);
+
+ gfc_free_interface (sym->generic);
+
+ gfc_free_formal_arglist (sym->formal);
+
+ gfc_free (sym);
+}
+
+
+/* Allocate and initialize a new symbol node. */
+
+gfc_symbol *
+gfc_new_symbol (const char *name, gfc_namespace * ns)
+{
+ gfc_symbol *p;
+
+ p = gfc_getmem (sizeof (gfc_symbol));
+
+ gfc_clear_ts (&p->ts);
+ gfc_clear_attr (&p->attr);
+ p->ns = ns;
+
+ p->declared_at = *gfc_current_locus ();
+
+ if (strlen (name) > GFC_MAX_SYMBOL_LEN)
+ gfc_internal_error ("new_symbol(): Symbol name too long");
+
+ strcpy (p->name, name);
+ return p;
+}
+
+
+/* Generate an error if a symbol is ambiguous. */
+
+static void
+ambiguous_symbol (const char *name, gfc_symtree * st)
+{
+
+ if (st->n.sym->module[0])
+ gfc_error ("Name '%s' at %C is an ambiguous reference to '%s' "
+ "from module '%s'", name, st->n.sym->name, st->n.sym->module);
+ else
+ gfc_error ("Name '%s' at %C is an ambiguous reference to '%s' "
+ "from current program unit", name, st->n.sym->name);
+}
+
+
+/* Search for a symbol starting in the current namespace, resorting to
+ any parent namespaces if requested by a nonzero parent_flag.
+ Returns nonzero if the symbol is ambiguous. */
+
+int
+gfc_find_sym_tree (const char *name, gfc_namespace * ns, int parent_flag,
+ gfc_symtree ** result)
+{
+ gfc_symtree *st;
+
+ if (ns == NULL)
+ ns = gfc_current_ns;
+
+ do
+ {
+ st = gfc_find_symtree (ns->sym_root, name);
+ if (st != NULL)
+ {
+ *result = st;
+ if (st->ambiguous)
+ {
+ ambiguous_symbol (name, st);
+ return 1;
+ }
+
+ return 0;
+ }
+
+ if (!parent_flag)
+ break;
+
+ ns = ns->parent;
+ }
+ while (ns != NULL);
+
+ *result = NULL;
+ return 0;
+}
+
+
+int
+gfc_find_symbol (const char *name, gfc_namespace * ns, int parent_flag,
+ gfc_symbol ** result)
+{
+ gfc_symtree *st;
+ int i;
+
+ i = gfc_find_sym_tree (name, ns, parent_flag, &st);
+
+ if (st == NULL)
+ *result = NULL;
+ else
+ *result = st->n.sym;
+
+ return i;
+}
+
+
+/* Save symbol with the information necessary to back it out. */
+
+static void
+save_symbol_data (gfc_symbol * sym)
+{
+
+ if (sym->new || sym->old_symbol != NULL)
+ return;
+
+ sym->old_symbol = gfc_getmem (sizeof (gfc_symbol));
+ *(sym->old_symbol) = *sym;
+
+ sym->tlink = changed_syms;
+ changed_syms = sym;
+}
+
+
+/* Given a name, find a symbol, or create it if it does not exist yet
+ in the current namespace. If the symbol is found we make sure that
+ it's OK.
+
+ The integer return code indicates
+ 0 All OK
+ 1 The symbol name was ambiguous
+ 2 The name meant to be established was already host associated.
+
+ So if the return value is nonzero, then an error was issued. */
+
+int
+gfc_get_sym_tree (const char *name, gfc_namespace * ns, gfc_symtree ** result)
+{
+ gfc_symtree *st;
+ gfc_symbol *p;
+
+ /* This doesn't usually happen during resolution. */
+ if (ns == NULL)
+ ns = gfc_current_ns;
+
+ /* Try to find the symbol in ns. */
+ st = gfc_find_symtree (ns->sym_root, name);
+
+ if (st == NULL)
+ {
+ /* If not there, create a new symbol. */
+ p = gfc_new_symbol (name, ns);
+
+ /* Add to the list of tentative symbols. */
+ p->old_symbol = NULL;
+ p->tlink = changed_syms;
+ p->mark = 1;
+ p->new = 1;
+ changed_syms = p;
+
+ st = gfc_new_symtree (&ns->sym_root, name);
+ st->n.sym = p;
+ p->refs++;
+
+ }
+ else
+ {
+ /* Make sure the existing symbol is OK. */
+ if (st->ambiguous)
+ {
+ ambiguous_symbol (name, st);
+ return 1;
+ }
+
+ p = st->n.sym;
+
+ if (p->ns != ns && (!p->attr.function || ns->proc_name != p))
+ {
+ /* Symbol is from another namespace. */
+ gfc_error ("Symbol '%s' at %C has already been host associated",
+ name);
+ return 2;
+ }
+
+ p->mark = 1;
+
+ /* Copy in case this symbol is changed. */
+ save_symbol_data (p);
+ }
+
+ *result = st;
+ return 0;
+}
+
+
+int
+gfc_get_symbol (const char *name, gfc_namespace * ns, gfc_symbol ** result)
+{
+ gfc_symtree *st;
+ int i;
+
+
+ i = gfc_get_sym_tree (name, ns, &st);
+ if (i != 0)
+ return i;
+
+ if (st)
+ *result = st->n.sym;
+ else
+ *result = NULL;
+ return i;
+}
+
+
+/* Subroutine that searches for a symbol, creating it if it doesn't
+ exist, but tries to host-associate the symbol if possible. */
+
+int
+gfc_get_ha_sym_tree (const char *name, gfc_symtree ** result)
+{
+ gfc_symtree *st;
+ int i;
+
+ i = gfc_find_sym_tree (name, gfc_current_ns, 0, &st);
+ if (st != NULL)
+ {
+ save_symbol_data (st->n.sym);
+
+ *result = st;
+ return i;
+ }
+
+ if (gfc_current_ns->parent != NULL)
+ {
+ i = gfc_find_sym_tree (name, gfc_current_ns->parent, 1, &st);
+ if (i)
+ return i;
+
+ if (st != NULL)
+ {
+ *result = st;
+ return 0;
+ }
+ }
+
+ return gfc_get_sym_tree (name, gfc_current_ns, result);
+}
+
+
+int
+gfc_get_ha_symbol (const char *name, gfc_symbol ** result)
+{
+ int i;
+ gfc_symtree *st;
+
+ i = gfc_get_ha_sym_tree (name, &st);
+
+ if (st)
+ *result = st->n.sym;
+ else
+ *result = NULL;
+
+ return i;
+}
+
+/* Return true if both symbols could refer to the same data object. Does
+ not take account of aliasing due to equivalence statements. */
+
+int
+gfc_symbols_could_alias (gfc_symbol * lsym, gfc_symbol * rsym)
+{
+ /* Aliasing isn't possible if the symbols have different base types. */
+ if (gfc_compare_types (&lsym->ts, &rsym->ts) == 0)
+ return 0;
+
+ /* Pointers can point to other pointers, target objects and allocatable
+ objects. Two allocatable objects cannot share the same storage. */
+ if (lsym->attr.pointer
+ && (rsym->attr.pointer || rsym->attr.allocatable || rsym->attr.target))
+ return 1;
+ if (lsym->attr.target && rsym->attr.pointer)
+ return 1;
+ if (lsym->attr.allocatable && rsym->attr.pointer)
+ return 1;
+
+ return 0;
+}
+
+
+/* Undoes all the changes made to symbols in the current statement.
+ This subroutine is made simpler due to the fact that attributes are
+ never removed once added. */
+
+void
+gfc_undo_symbols (void)
+{
+ gfc_symbol *p, *q, *old;
+
+ for (p = changed_syms; p; p = q)
+ {
+ q = p->tlink;
+
+ if (p->new)
+ {
+ /* Symbol was new. */
+ delete_symtree (&p->ns->sym_root, p->name);
+
+ p->refs--;
+ if (p->refs < 0)
+ gfc_internal_error ("gfc_undo_symbols(): Negative refs");
+ if (p->refs == 0)
+ gfc_free_symbol (p);
+ continue;
+ }
+
+ /* Restore previous state of symbol. Just copy simple stuff. */
+ p->mark = 0;
+ old = p->old_symbol;
+
+ p->ts.type = old->ts.type;
+ p->ts.kind = old->ts.kind;
+
+ p->attr = old->attr;
+
+ if (p->value != old->value)
+ {
+ gfc_free_expr (old->value);
+ p->value = NULL;
+ }
+
+ if (p->as != old->as)
+ {
+ if (p->as)
+ gfc_free_array_spec (p->as);
+ p->as = old->as;
+ }
+
+ p->generic = old->generic;
+ p->component_access = old->component_access;
+
+ if (p->namelist != NULL && old->namelist == NULL)
+ {
+ gfc_free_namelist (p->namelist);
+ p->namelist = NULL;
+ }
+ else
+ {
+
+ if (p->namelist_tail != old->namelist_tail)
+ {
+ gfc_free_namelist (old->namelist_tail);
+ old->namelist_tail->next = NULL;
+ }
+ }
+
+ p->namelist_tail = old->namelist_tail;
+
+ if (p->formal != old->formal)
+ {
+ gfc_free_formal_arglist (p->formal);
+ p->formal = old->formal;
+ }
+
+ gfc_free (p->old_symbol);
+ p->old_symbol = NULL;
+ p->tlink = NULL;
+ }
+
+ changed_syms = NULL;
+}
+
+
+/* Makes the changes made in the current statement permanent-- gets
+ rid of undo information. */
+
+void
+gfc_commit_symbols (void)
+{
+ gfc_symbol *p, *q;
+
+ for (p = changed_syms; p; p = q)
+ {
+ q = p->tlink;
+ p->tlink = NULL;
+ p->mark = 0;
+ p->new = 0;
+
+ if (p->old_symbol != NULL)
+ {
+ gfc_free (p->old_symbol);
+ p->old_symbol = NULL;
+ }
+ }
+
+ changed_syms = NULL;
+}
+
+
+/* Recursive function that deletes an entire tree and all the user
+ operator nodes that it contains. */
+
+static void
+free_uop_tree (gfc_symtree * uop_tree)
+{
+
+ if (uop_tree == NULL)
+ return;
+
+ free_uop_tree (uop_tree->left);
+ free_uop_tree (uop_tree->right);
+
+ gfc_free_interface (uop_tree->n.uop->operator);
+
+ gfc_free (uop_tree->n.uop);
+ gfc_free (uop_tree);
+}
+
+
+/* Recursive function that deletes an entire tree and all the symbols
+ that it contains. */
+
+static void
+free_sym_tree (gfc_symtree * sym_tree)
+{
+ gfc_namespace *ns;
+ gfc_symbol *sym;
+
+ if (sym_tree == NULL)
+ return;
+
+ free_sym_tree (sym_tree->left);
+ free_sym_tree (sym_tree->right);
+
+ sym = sym_tree->n.sym;
+
+ sym->refs--;
+ if (sym->refs < 0)
+ gfc_internal_error ("free_sym_tree(): Negative refs");
+
+ if (sym->formal_ns != NULL && sym->refs == 1)
+ {
+ /* As formal_ns contains a reference to sym, delete formal_ns just
+ before the deletion of sym. */
+ ns = sym->formal_ns;
+ sym->formal_ns = NULL;
+ gfc_free_namespace (ns);
+ }
+ else if (sym->refs == 0)
+ {
+ /* Go ahead and delete the symbol. */
+ gfc_free_symbol (sym);
+ }
+
+ gfc_free (sym_tree);
+}
+
+
+/* Free a namespace structure and everything below it. Interface
+ lists associated with intrinsic operators are not freed. These are
+ taken care of when a specific name is freed. */
+
+void
+gfc_free_namespace (gfc_namespace * ns)
+{
+ gfc_charlen *cl, *cl2;
+ gfc_namespace *p, *q;
+ gfc_intrinsic_op i;
+
+ if (ns == NULL)
+ return;
+
+ gfc_free_statements (ns->code);
+
+ free_sym_tree (ns->sym_root);
+ free_uop_tree (ns->uop_root);
+
+ for (cl = ns->cl_list; cl; cl = cl2)
+ {
+ cl2 = cl->next;
+ gfc_free_expr (cl->length);
+ gfc_free (cl);
+ }
+
+ free_st_labels (ns->st_labels);
+
+ gfc_free_equiv (ns->equiv);
+
+ for (i = GFC_INTRINSIC_BEGIN; i != GFC_INTRINSIC_END; i++)
+ gfc_free_interface (ns->operator[i]);
+
+ gfc_free_data (ns->data);
+ p = ns->contained;
+ gfc_free (ns);
+
+ /* Recursively free any contained namespaces. */
+ while (p != NULL)
+ {
+ q = p;
+ p = p->sibling;
+
+ gfc_free_namespace (q);
+ }
+}
+
+
+void
+gfc_symbol_init_2 (void)
+{
+
+ gfc_current_ns = gfc_get_namespace (NULL);
+}
+
+
+void
+gfc_symbol_done_2 (void)
+{
+
+ gfc_free_namespace (gfc_current_ns);
+ gfc_current_ns = NULL;
+}
+
+
+/* Clear mark bits from symbol nodes associated with a symtree node. */
+
+static void
+clear_sym_mark (gfc_symtree * st)
+{
+
+ st->n.sym->mark = 0;
+}
+
+
+/* Recursively traverse the symtree nodes. */
+
+static void
+traverse_symtree (gfc_symtree * st, void (*func) (gfc_symtree *))
+{
+
+ if (st != NULL)
+ {
+ (*func) (st);
+
+ traverse_symtree (st->left, func);
+ traverse_symtree (st->right, func);
+ }
+}
+
+
+void
+gfc_traverse_symtree (gfc_namespace * ns, void (*func) (gfc_symtree *))
+{
+
+ traverse_symtree (ns->sym_root, func);
+}
+
+
+/* Recursive namespace traversal function. */
+
+static void
+traverse_ns (gfc_symtree * st, void (*func) (gfc_symbol *))
+{
+
+ if (st == NULL)
+ return;
+
+ if (st->n.sym->mark == 0)
+ (*func) (st->n.sym);
+ st->n.sym->mark = 1;
+
+ traverse_ns (st->left, func);
+ traverse_ns (st->right, func);
+}
+
+
+/* Call a given function for all symbols in the namespace. We take
+ care that each gfc_symbol node is called exactly once. */
+
+void
+gfc_traverse_ns (gfc_namespace * ns, void (*func) (gfc_symbol *))
+{
+
+ gfc_traverse_symtree (ns, clear_sym_mark);
+
+ traverse_ns (ns->sym_root, func);
+}
+
+
+/* Given a symbol, mark it as SAVEd if it is allowed. */
+
+static void
+save_symbol (gfc_symbol * sym)
+{
+
+ if (sym->attr.use_assoc)
+ return;
+
+ if (sym->attr.common)
+ {
+ gfc_add_saved_common (&sym->attr, &sym->declared_at);
+ return;
+ }
+
+ if (sym->attr.in_common
+ || sym->attr.dummy
+ || sym->attr.flavor != FL_VARIABLE)
+ return;
+
+ gfc_add_save (&sym->attr, &sym->declared_at);
+}
+
+
+/* Mark those symbols which can be SAVEd as such. */
+
+void
+gfc_save_all (gfc_namespace * ns)
+{
+
+ gfc_traverse_ns (ns, save_symbol);
+}
+
+
+#ifdef GFC_DEBUG
+/* Make sure that no changes to symbols are pending. */
+
+void
+gfc_symbol_state(void) {
+
+ if (changed_syms != NULL)
+ gfc_internal_error("Symbol changes still pending!");
+}
+#endif
+
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
new file mode 100644
index 00000000000..e1ed1e3421e
--- /dev/null
+++ b/gcc/fortran/trans-array.c
@@ -0,0 +1,4158 @@
+/* Array translation routines
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+ and Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* trans-array.c-- Various array related code, including scalarization,
+ allocation, initialization and other support routines. */
+
+/* How the scalarizer works.
+ In gfortran, array expressions use the same core routines as scalar
+ expressions.
+ First, a Scalarization State (SS) chain is built. This is done by walking
+ the expression tree, and building a linear list of the terms in the
+ expression. As the tree is walked, scalar subexpressions are translated.
+
+ The scalarization parameters are stored in a gfc_loopinfo structure.
+ First the start and stride of each term is calculated by
+ gfc_conv_ss_startstride. During this process the expressions for the array
+ descriptors and data pointers are also translated.
+
+ If the expression is an assignment, we must then resolve any dependencies.
+ In fortran all the rhs values of an assignment must be evaluated before
+ any assignments take place. This can require a temporary array to store the
+ values. We also require a temporary when we are passing array expressions
+ or vector subecripts as procedure parameters.
+
+ Array sections are passed without copying to a temporary. These use the
+ scalarizer to determine the shape of the section. The flag
+ loop->array_parameter tells the scalarizer that the actual values and loop
+ variables will not be required.
+
+ The function gfc_conv_loop_setup generates the scalarization setup code.
+ It determines the range of the scalarizing loop variables. If a temporary
+ is required, this is created and initialized. Code for scalar expressions
+ taken outside the loop is also generated at this time. Next the offset and
+ scaling required to translate from loop variables to array indices for each
+ term is calculated.
+
+ A call to gfc_start_scalarized_body marks the start of the scalarized
+ expression. This creates a scope and declares the loop variables. Before
+ calling this gfc_make_ss_chain_used must be used to indicate which terms
+ will be used inside this loop.
+
+ The scalar gfc_conv_* functions are then used to build the main body of the
+ scalarization loop. Scalarization loop variables and precalculated scalar
+ values are automaticaly substituted. Note that gfc_advance_se_ss_chain
+ must be used, rather than changing the se->ss directly.
+
+ For assignment expressions requiring a temporary two sub loops are
+ generated. The first stores the result of the expression in the temporary,
+ the second copies it to the result. A call to
+ gfc_trans_scalarized_loop_boundary marks the end of the main loop code and
+ the start of the copying loop. The temporary may be less than full rank.
+
+ Finally gfc_trans_scalarizing_loops is called to generate the implicit do
+ loops. The loops are added to the pre chain of the loopinfo. The post
+ chain may still contain cleanup code.
+
+ After the loop code has been added into its parent scope gfc_cleanup_loop
+ is called to free all the SS allocated by the scalarizer. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "tree-gimple.h"
+#include <stdio.h>
+#include "ggc.h"
+#include "toplev.h"
+#include "real.h"
+#include "flags.h"
+#include <assert.h>
+#include <gmp.h>
+#include "gfortran.h"
+#include "trans.h"
+#include "trans-stmt.h"
+#include "trans-types.h"
+#include "trans-array.h"
+#include "trans-const.h"
+#include "dependency.h"
+
+static gfc_ss *gfc_walk_subexpr (gfc_ss *, gfc_expr *);
+
+/* The contents of this structure aren't actualy used, just the address. */
+static gfc_ss gfc_ss_terminator_var;
+gfc_ss * const gfc_ss_terminator = &gfc_ss_terminator_var;
+
+unsigned HOST_WIDE_INT gfc_stack_space_left;
+
+
+/* Returns true if a variable of specified size should go on the stack. */
+
+int
+gfc_can_put_var_on_stack (tree size)
+{
+ unsigned HOST_WIDE_INT low;
+
+ if (!INTEGER_CST_P (size))
+ return 0;
+
+ if (gfc_option.flag_max_stack_var_size < 0)
+ return 1;
+
+ if (TREE_INT_CST_HIGH (size) != 0)
+ return 0;
+
+ low = TREE_INT_CST_LOW (size);
+ if (low > (unsigned HOST_WIDE_INT) gfc_option.flag_max_stack_var_size)
+ return 0;
+
+/* TODO: Set a per-function stack size limit. */
+#if 0
+ /* We should be a bit more clever with array temps. */
+ if (gfc_option.flag_max_function_vars_size >= 0)
+ {
+ if (low > gfc_stack_space_left)
+ return 0;
+
+ gfc_stack_space_left -= low;
+ }
+#endif
+
+ return 1;
+}
+
+static tree
+gfc_array_dataptr_type (tree desc)
+{
+ return (GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc)));
+}
+
+
+/* Build expressions to access the members of an array descriptor.
+ It's surprisingly easy to mess up here, so never access
+ an array descriptor by "brute force", always use these
+ functions. This also avoids problems if we change the format
+ of an array descriptor.
+
+ To understand these magic numbers, look at the comments
+ before gfc_build_array_type() in trans-types.c.
+
+ The code within these defines should be the only code which knows the format
+ of an array descriptor.
+
+ Any code just needing to read obtain the bounds of an array should use
+ gfc_conv_array_* rather than the following functions as these will return
+ know constant values, and work with arrays which do not have descriptors.
+
+ Don't forget to #undef these! */
+
+#define DATA_FIELD 0
+#define OFFSET_FIELD 1
+#define DTYPE_FIELD 2
+#define DIMENSION_FIELD 3
+
+#define STRIDE_SUBFIELD 0
+#define LBOUND_SUBFIELD 1
+#define UBOUND_SUBFIELD 2
+
+tree
+gfc_conv_descriptor_data (tree desc)
+{
+ tree field;
+ tree type;
+
+ type = TREE_TYPE (desc);
+ assert (GFC_DESCRIPTOR_TYPE_P (type));
+
+ field = TYPE_FIELDS (type);
+ assert (DATA_FIELD == 0);
+ assert (field != NULL_TREE
+ && TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == ARRAY_TYPE);
+
+ return build (COMPONENT_REF, TREE_TYPE (field), desc, field);
+}
+
+tree
+gfc_conv_descriptor_offset (tree desc)
+{
+ tree type;
+ tree field;
+
+ type = TREE_TYPE (desc);
+ assert (GFC_DESCRIPTOR_TYPE_P (type));
+
+ field = gfc_advance_chain (TYPE_FIELDS (type), OFFSET_FIELD);
+ assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
+
+ return build (COMPONENT_REF, TREE_TYPE (field), desc, field);
+}
+
+tree
+gfc_conv_descriptor_dtype (tree desc)
+{
+ tree field;
+ tree type;
+
+ type = TREE_TYPE (desc);
+ assert (GFC_DESCRIPTOR_TYPE_P (type));
+
+ field = gfc_advance_chain (TYPE_FIELDS (type), DTYPE_FIELD);
+ assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
+
+ return build (COMPONENT_REF, TREE_TYPE (field), desc, field);
+}
+
+static tree
+gfc_conv_descriptor_dimension (tree desc, tree dim)
+{
+ tree field;
+ tree type;
+ tree tmp;
+
+ type = TREE_TYPE (desc);
+ assert (GFC_DESCRIPTOR_TYPE_P (type));
+
+ field = gfc_advance_chain (TYPE_FIELDS (type), DIMENSION_FIELD);
+ assert (field != NULL_TREE
+ && TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == RECORD_TYPE);
+
+ tmp = build (COMPONENT_REF, TREE_TYPE (field), desc, field);
+ tmp = gfc_build_array_ref (tmp, dim);
+ return tmp;
+}
+
+tree
+gfc_conv_descriptor_stride (tree desc, tree dim)
+{
+ tree tmp;
+ tree field;
+
+ tmp = gfc_conv_descriptor_dimension (desc, dim);
+ field = TYPE_FIELDS (TREE_TYPE (tmp));
+ field = gfc_advance_chain (field, STRIDE_SUBFIELD);
+ assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
+
+ tmp = build (COMPONENT_REF, TREE_TYPE (field), tmp, field);
+ return tmp;
+}
+
+tree
+gfc_conv_descriptor_lbound (tree desc, tree dim)
+{
+ tree tmp;
+ tree field;
+
+ tmp = gfc_conv_descriptor_dimension (desc, dim);
+ field = TYPE_FIELDS (TREE_TYPE (tmp));
+ field = gfc_advance_chain (field, LBOUND_SUBFIELD);
+ assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
+
+ tmp = build (COMPONENT_REF, TREE_TYPE (field), tmp, field);
+ return tmp;
+}
+
+tree
+gfc_conv_descriptor_ubound (tree desc, tree dim)
+{
+ tree tmp;
+ tree field;
+
+ tmp = gfc_conv_descriptor_dimension (desc, dim);
+ field = TYPE_FIELDS (TREE_TYPE (tmp));
+ field = gfc_advance_chain (field, UBOUND_SUBFIELD);
+ assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
+
+ tmp = build (COMPONENT_REF, TREE_TYPE (field), tmp, field);
+ return tmp;
+}
+
+
+/* Generate an initializer for a static pointer or allocatable array. */
+
+void
+gfc_trans_static_array_pointer (gfc_symbol * sym)
+{
+ tree tmp;
+ tree field;
+ tree type;
+
+ assert (TREE_STATIC (sym->backend_decl));
+ /* Just zero the data member. */
+ type = TREE_TYPE (sym->backend_decl);
+ assert (GFC_DESCRIPTOR_TYPE_P (type));
+ assert (DATA_FIELD == 0);
+ field = TYPE_FIELDS (type);
+
+ tmp = tree_cons (field, null_pointer_node, NULL_TREE);
+ tmp = build1 (CONSTRUCTOR, type, tmp);
+ TREE_CONSTANT (tmp) = 1;
+ TREE_INVARIANT (tmp) = 1;
+ DECL_INITIAL (sym->backend_decl) = tmp;
+}
+
+
+/* Cleanup those #defines. */
+
+#undef DATA_FIELD
+#undef OFFSET_FIELD
+#undef DTYPE_FIELD
+#undef DIMENSION_FIELD
+#undef STRIDE_SUBFIELD
+#undef LBOUND_SUBFIELD
+#undef UBOUND_SUBFIELD
+
+
+/* Mark a SS chain as used. Flags specifies in which loops the SS is used.
+ flags & 1 = Main loop body.
+ flags & 2 = temp copy loop. */
+
+void
+gfc_mark_ss_chain_used (gfc_ss * ss, unsigned flags)
+{
+ for (; ss != gfc_ss_terminator; ss = ss->next)
+ ss->useflags = flags;
+}
+
+static void gfc_free_ss (gfc_ss *);
+
+
+/* Free a gfc_ss chain. */
+
+static void
+gfc_free_ss_chain (gfc_ss * ss)
+{
+ gfc_ss *next;
+
+ while (ss != gfc_ss_terminator)
+ {
+ assert (ss != NULL);
+ next = ss->next;
+ gfc_free_ss (ss);
+ ss = next;
+ }
+}
+
+
+/* Free a SS. */
+
+static void
+gfc_free_ss (gfc_ss * ss)
+{
+ int n;
+
+ switch (ss->type)
+ {
+ case GFC_SS_SECTION:
+ case GFC_SS_VECTOR:
+ for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
+ {
+ if (ss->data.info.subscript[n])
+ gfc_free_ss_chain (ss->data.info.subscript[n]);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ gfc_free (ss);
+}
+
+
+/* Free all the SS associated with a loop. */
+
+void
+gfc_cleanup_loop (gfc_loopinfo * loop)
+{
+ gfc_ss *ss;
+ gfc_ss *next;
+
+ ss = loop->ss;
+ while (ss != gfc_ss_terminator)
+ {
+ assert (ss != NULL);
+ next = ss->loop_chain;
+ gfc_free_ss (ss);
+ ss = next;
+ }
+}
+
+
+/* Associate a SS chain with a loop. */
+
+void
+gfc_add_ss_to_loop (gfc_loopinfo * loop, gfc_ss * head)
+{
+ gfc_ss *ss;
+
+ if (head == gfc_ss_terminator)
+ return;
+
+ ss = head;
+ for (; ss && ss != gfc_ss_terminator; ss = ss->next)
+ {
+ if (ss->next == gfc_ss_terminator)
+ ss->loop_chain = loop->ss;
+ else
+ ss->loop_chain = ss->next;
+ }
+ assert (ss == gfc_ss_terminator);
+ loop->ss = head;
+}
+
+
+/* Generate code to allocate an array temporary, or create a variable to
+ hold the data. */
+
+static void
+gfc_trans_allocate_array_storage (gfc_loopinfo * loop, gfc_ss_info * info,
+ tree size, tree nelem)
+{
+ tree tmp;
+ tree args;
+ tree desc;
+ tree data;
+ bool onstack;
+
+ desc = info->descriptor;
+ data = gfc_conv_descriptor_data (desc);
+ onstack = gfc_can_put_var_on_stack (size);
+ if (onstack)
+ {
+ /* Make a temporary variable to hold the data. */
+ tmp = fold (build (MINUS_EXPR, TREE_TYPE (nelem), nelem,
+ integer_one_node));
+ tmp = build_range_type (gfc_array_index_type, integer_zero_node, tmp);
+ tmp = build_array_type (gfc_get_element_type (TREE_TYPE (desc)), tmp);
+ tmp = gfc_create_var (tmp, "A");
+ tmp = gfc_build_addr_expr (TREE_TYPE (data), tmp);
+ gfc_add_modify_expr (&loop->pre, data, tmp);
+ info->data = data;
+ info->offset = gfc_index_zero_node;
+
+ }
+ else
+ {
+ /* Allocate memory to hold the data. */
+ args = gfc_chainon_list (NULL_TREE, size);
+
+ if (gfc_index_integer_kind == 4)
+ tmp = gfor_fndecl_internal_malloc;
+ else if (gfc_index_integer_kind == 8)
+ tmp = gfor_fndecl_internal_malloc64;
+ else
+ abort ();
+ tmp = gfc_build_function_call (tmp, args);
+ tmp = convert (TREE_TYPE (data), tmp);
+ gfc_add_modify_expr (&loop->pre, data, tmp);
+
+ info->data = data;
+ info->offset = gfc_index_zero_node;
+ }
+
+ /* The offset is zero because we create temporaries with a zero
+ lower bound. */
+ tmp = gfc_conv_descriptor_offset (desc);
+ gfc_add_modify_expr (&loop->pre, tmp, gfc_index_zero_node);
+
+ if (!onstack)
+ {
+ /* Free the temporary. */
+ tmp = convert (pvoid_type_node, info->data);
+ tmp = gfc_chainon_list (NULL_TREE, tmp);
+ tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
+ gfc_add_expr_to_block (&loop->post, tmp);
+ }
+}
+
+
+/* Generate code to allocate and initialize the descriptor for a temporary
+ array. Fills in the descriptor, data and offset fields of info. Also
+ adjusts the loop variables to be zero-based. Returns the size of the
+ array. */
+
+tree
+gfc_trans_allocate_temp_array (gfc_loopinfo * loop, gfc_ss_info * info,
+ tree eltype, tree string_length)
+{
+ tree type;
+ tree desc;
+ tree tmp;
+ tree size;
+ tree nelem;
+ int n;
+ int dim;
+
+ assert (info->dimen > 0);
+ /* Set the lower bound to zero. */
+ for (dim = 0; dim < info->dimen; dim++)
+ {
+ n = loop->order[dim];
+ if (n < loop->temp_dim)
+ assert (integer_zerop (loop->from[n]));
+ else
+ {
+ loop->to[n] = fold (build (MINUS_EXPR, gfc_array_index_type,
+ loop->to[n], loop->from[n]));
+ loop->from[n] = integer_zero_node;
+ }
+
+ info->delta[dim] = integer_zero_node;
+ info->start[dim] = integer_zero_node;
+ info->stride[dim] = integer_one_node;
+ info->dim[dim] = dim;
+ }
+
+ /* Initialise the descriptor. */
+ type =
+ gfc_get_array_type_bounds (eltype, info->dimen, loop->from, loop->to, 1);
+ desc = gfc_create_var (type, "atmp");
+ GFC_DECL_PACKED_ARRAY (desc) = 1;
+
+ info->descriptor = desc;
+ size = integer_one_node;
+
+ /* Fill in the array dtype. */
+ tmp = gfc_conv_descriptor_dtype (desc);
+ gfc_add_modify_expr (&loop->pre, tmp,
+ GFC_TYPE_ARRAY_DTYPE (TREE_TYPE (desc)));
+
+ /* Fill in the bounds and stride. This is a packed array, so:
+ size = 1;
+ for (n = 0; n < rank; n++)
+ {
+ stride[n] = size
+ delta = ubound[n] + 1 - lbound[n];
+ size = size * delta;
+ }
+ size = size * sizeof(element); */
+ for (n = 0; n < info->dimen; n++)
+ {
+ /* Store the stride and bound components in the descriptor. */
+ tmp = gfc_conv_descriptor_stride (desc, gfc_rank_cst[n]);
+ gfc_add_modify_expr (&loop->pre, tmp, size);
+
+ tmp = gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n]);
+ gfc_add_modify_expr (&loop->pre, tmp, integer_zero_node);
+
+ tmp = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]);
+ gfc_add_modify_expr (&loop->pre, tmp, loop->to[n]);
+
+ tmp = fold (build (PLUS_EXPR, gfc_array_index_type,
+ loop->to[n], integer_one_node));
+
+ size = fold (build (MULT_EXPR, gfc_array_index_type, size, tmp));
+ size = gfc_evaluate_now (size, &loop->pre);
+ }
+
+ /* TODO: Where does the string length go? */
+ if (string_length)
+ gfc_todo_error ("temporary arrays of strings");
+
+ /* Get the size of the array. */
+ nelem = size;
+ size = fold (build (MULT_EXPR, gfc_array_index_type, size,
+ TYPE_SIZE_UNIT (gfc_get_element_type (type))));
+
+ gfc_trans_allocate_array_storage (loop, info, size, nelem);
+
+ if (info->dimen > loop->temp_dim)
+ loop->temp_dim = info->dimen;
+
+ return size;
+}
+
+
+/* Make sure offset is a variable. */
+
+static void
+gfc_put_offset_into_var (stmtblock_t * pblock, tree * poffset,
+ tree * offsetvar)
+{
+ /* We should have already created the offset variable. We cannot
+ create it here because we may be in an inner scopde. */
+ assert (*offsetvar != NULL_TREE);
+ gfc_add_modify_expr (pblock, *offsetvar, *poffset);
+ *poffset = *offsetvar;
+ TREE_USED (*offsetvar) = 1;
+}
+
+
+/* Add the contents of an array to the constructor. */
+
+static void
+gfc_trans_array_constructor_subarray (stmtblock_t * pblock,
+ tree type ATTRIBUTE_UNUSED,
+ tree pointer, gfc_expr * expr,
+ tree * poffset, tree * offsetvar)
+{
+ gfc_se se;
+ gfc_ss *ss;
+ gfc_loopinfo loop;
+ stmtblock_t body;
+ tree tmp;
+
+ /* We need this to be a variable so we can increment it. */
+ gfc_put_offset_into_var (pblock, poffset, offsetvar);
+
+ gfc_init_se (&se, NULL);
+
+ /* Walk the array expression. */
+ ss = gfc_walk_expr (expr);
+ assert (ss != gfc_ss_terminator);
+
+ /* Initialize the scalarizer. */
+ gfc_init_loopinfo (&loop);
+ gfc_add_ss_to_loop (&loop, ss);
+
+ /* Initialize the loop. */
+ gfc_conv_ss_startstride (&loop);
+ gfc_conv_loop_setup (&loop);
+
+ /* Make the loop body. */
+ gfc_mark_ss_chain_used (ss, 1);
+ gfc_start_scalarized_body (&loop, &body);
+ gfc_copy_loopinfo_to_se (&se, &loop);
+ se.ss = ss;
+
+ gfc_conv_expr (&se, expr);
+ gfc_add_block_to_block (&body, &se.pre);
+
+ /* Store the value. */
+ tmp = gfc_build_indirect_ref (pointer);
+ tmp = gfc_build_array_ref (tmp, *poffset);
+ gfc_add_modify_expr (&body, tmp, se.expr);
+
+ /* Increment the offset. */
+ tmp = build (PLUS_EXPR, gfc_array_index_type, *poffset, integer_one_node);
+ gfc_add_modify_expr (&body, *poffset, tmp);
+
+ /* Finish the loop. */
+ gfc_add_block_to_block (&body, &se.post);
+ assert (se.ss == gfc_ss_terminator);
+ gfc_trans_scalarizing_loops (&loop, &body);
+ gfc_add_block_to_block (&loop.pre, &loop.post);
+ tmp = gfc_finish_block (&loop.pre);
+ gfc_add_expr_to_block (pblock, tmp);
+
+ gfc_cleanup_loop (&loop);
+}
+
+
+/* Assign the values to the elements of an array constructor. */
+
+static void
+gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
+ tree pointer, gfc_constructor * c,
+ tree * poffset, tree * offsetvar)
+{
+ tree tmp;
+ tree ref;
+ stmtblock_t body;
+ tree loopbody;
+ gfc_se se;
+
+ for (; c; c = c->next)
+ {
+ /* If this is an iterator or an array, the offset must be a variable. */
+ if ((c->iterator || c->expr->rank > 0) && INTEGER_CST_P (*poffset))
+ gfc_put_offset_into_var (pblock, poffset, offsetvar);
+
+ gfc_start_block (&body);
+
+ if (c->expr->expr_type == EXPR_ARRAY)
+ {
+ /* Array constructors can be nested. */
+ gfc_trans_array_constructor_value (&body, type, pointer,
+ c->expr->value.constructor,
+ poffset, offsetvar);
+ }
+ else if (c->expr->rank > 0)
+ {
+ gfc_trans_array_constructor_subarray (&body, type, pointer,
+ c->expr, poffset, offsetvar);
+ }
+ else
+ {
+ /* This code really upsets the gimplifier so don't bother for now. */
+ gfc_constructor *p;
+ HOST_WIDE_INT n;
+ HOST_WIDE_INT size;
+
+ p = c;
+ n = 0;
+ while (p && !(p->iterator || p->expr->expr_type != EXPR_CONSTANT))
+ {
+ p = p->next;
+ n++;
+ }
+ if (n < 4)
+ {
+ /* Scalar values. */
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr (&se, c->expr);
+ gfc_add_block_to_block (&body, &se.pre);
+
+ ref = gfc_build_indirect_ref (pointer);
+ ref = gfc_build_array_ref (ref, *poffset);
+ gfc_add_modify_expr (&body, ref, se.expr);
+ gfc_add_block_to_block (&body, &se.post);
+
+ *poffset = fold (build (PLUS_EXPR, gfc_array_index_type,
+ *poffset, integer_one_node));
+ }
+ else
+ {
+ /* Collect multiple scalar constants into a constructor. */
+ tree list;
+ tree init;
+ tree bound;
+ tree tmptype;
+
+ p = c;
+ list = NULL_TREE;
+ /* Count the number of consecutive scalar constants. */
+ while (p && !(p->iterator
+ || p->expr->expr_type != EXPR_CONSTANT))
+ {
+ gfc_init_se (&se, NULL);
+ gfc_conv_constant (&se, p->expr);
+ list = tree_cons (NULL_TREE, se.expr, list);
+ c = p;
+ p = p->next;
+ }
+
+ bound = build_int_2 (n - 1, 0);
+ /* Create an array type to hold them. */
+ tmptype = build_range_type (gfc_array_index_type,
+ integer_zero_node, bound);
+ tmptype = build_array_type (type, tmptype);
+
+ init = build1 (CONSTRUCTOR, tmptype, nreverse (list));
+ TREE_CONSTANT (init) = 1;
+ TREE_INVARIANT (init) = 1;
+ TREE_STATIC (init) = 1;
+ /* Create a static variable to hold the data. */
+ tmp = gfc_create_var (tmptype, "data");
+ TREE_STATIC (tmp) = 1;
+ TREE_CONSTANT (tmp) = 1;
+ TREE_INVARIANT (tmp) = 1;
+ DECL_INITIAL (tmp) = init;
+ init = tmp;
+
+ /* Use BUILTIN_MEMCPY to assign the values. */
+ tmp = gfc_build_indirect_ref (pointer);
+ tmp = gfc_build_array_ref (tmp, *poffset);
+ tmp = gfc_build_addr_expr (NULL, tmp);
+ init = gfc_build_addr_expr (NULL, init);
+
+ size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
+ bound = build_int_2 (n * size, 0);
+ tmp = gfc_chainon_list (NULL_TREE, tmp);
+ tmp = gfc_chainon_list (tmp, init);
+ tmp = gfc_chainon_list (tmp, bound);
+ tmp = gfc_build_function_call (built_in_decls[BUILT_IN_MEMCPY],
+ tmp);
+ gfc_add_expr_to_block (&body, tmp);
+
+ *poffset = fold (build (PLUS_EXPR, gfc_array_index_type,
+ *poffset, bound));
+ }
+ if (!INTEGER_CST_P (*poffset))
+ {
+ gfc_add_modify_expr (&body, *offsetvar, *poffset);
+ *poffset = *offsetvar;
+ }
+ }
+
+ /* The frontend should already have done any expansions. */
+ if (c->iterator)
+ {
+ tree end;
+ tree step;
+ tree loopvar;
+ tree exit_label;
+
+ loopbody = gfc_finish_block (&body);
+
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr (&se, c->iterator->var);
+ gfc_add_block_to_block (pblock, &se.pre);
+ loopvar = se.expr;
+
+ /* Initialize thie loop. */
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_val (&se, c->iterator->start);
+ gfc_add_block_to_block (pblock, &se.pre);
+ gfc_add_modify_expr (pblock, loopvar, se.expr);
+
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_val (&se, c->iterator->end);
+ gfc_add_block_to_block (pblock, &se.pre);
+ end = gfc_evaluate_now (se.expr, pblock);
+
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_val (&se, c->iterator->step);
+ gfc_add_block_to_block (pblock, &se.pre);
+ step = gfc_evaluate_now (se.expr, pblock);
+
+ /* Generate the loop body. */
+ exit_label = gfc_build_label_decl (NULL_TREE);
+ gfc_start_block (&body);
+
+ /* Generate the exit condition. */
+ end = build (GT_EXPR, boolean_type_node, loopvar, end);
+ tmp = build1_v (GOTO_EXPR, exit_label);
+ TREE_USED (exit_label) = 1;
+ tmp = build_v (COND_EXPR, end, tmp, build_empty_stmt ());
+ gfc_add_expr_to_block (&body, tmp);
+
+ /* The main loop body. */
+ gfc_add_expr_to_block (&body, loopbody);
+
+ /* Increment the loop variable. */
+ tmp = build (PLUS_EXPR, TREE_TYPE (loopvar), loopvar, step);
+ gfc_add_modify_expr (&body, loopvar, tmp);
+
+ /* Finish the loop. */
+ tmp = gfc_finish_block (&body);
+ tmp = build_v (LOOP_EXPR, tmp);
+ gfc_add_expr_to_block (pblock, tmp);
+
+ /* Add the exit label. */
+ tmp = build1_v (LABEL_EXPR, exit_label);
+ gfc_add_expr_to_block (pblock, tmp);
+ }
+ else
+ {
+ /* Pass the code as is. */
+ tmp = gfc_finish_block (&body);
+ gfc_add_expr_to_block (pblock, tmp);
+ }
+ }
+}
+
+
+/* Get the size of an expression. Returns -1 if the size isn't constant.
+ Implied do loops with non-constant bounds are tricky because we must only
+ evaluate the bounds once. */
+
+static void
+gfc_get_array_cons_size (mpz_t * size, gfc_constructor * c)
+{
+ gfc_iterator *i;
+ mpz_t val;
+ mpz_t len;
+
+ mpz_set_ui (*size, 0);
+ mpz_init (len);
+ mpz_init (val);
+
+ for (; c; c = c->next)
+ {
+ if (c->expr->expr_type == EXPR_ARRAY)
+ {
+ /* A nested array constructor. */
+ gfc_get_array_cons_size (&len, c->expr->value.constructor);
+ if (mpz_sgn (len) < 0)
+ {
+ mpz_set (*size, len);
+ mpz_clear (len);
+ mpz_clear (val);
+ return;
+ }
+ }
+ else
+ {
+ if (c->expr->rank > 0)
+ {
+ mpz_set_si (*size, -1);
+ mpz_clear (len);
+ mpz_clear (val);
+ return;
+ }
+ mpz_set_ui (len, 1);
+ }
+
+ if (c->iterator)
+ {
+ i = c->iterator;
+
+ if (i->start->expr_type != EXPR_CONSTANT
+ || i->end->expr_type != EXPR_CONSTANT
+ || i->step->expr_type != EXPR_CONSTANT)
+ {
+ mpz_set_si (*size, -1);
+ mpz_clear (len);
+ mpz_clear (val);
+ return;
+ }
+
+ mpz_add (val, i->end->value.integer, i->start->value.integer);
+ mpz_tdiv_q (val, val, i->step->value.integer);
+ mpz_add_ui (val, val, 1);
+ mpz_mul (len, len, val);
+ }
+ mpz_add (*size, *size, len);
+ }
+ mpz_clear (len);
+ mpz_clear (val);
+}
+
+
+/* Array constructors are handled by constructing a temporary, then using that
+ within the scalarization loop. This is not optimal, but seems by far the
+ simplest method. */
+
+static void
+gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss)
+{
+ tree offset;
+ tree offsetvar;
+ tree desc;
+ tree size;
+ tree type;
+
+ if (ss->expr->ts.type == BT_CHARACTER)
+ gfc_todo_error ("Character string array constructors");
+ type = gfc_typenode_for_spec (&ss->expr->ts);
+ ss->data.info.dimen = loop->dimen;
+ size =
+ gfc_trans_allocate_temp_array (loop, &ss->data.info, type, NULL_TREE);
+
+ desc = ss->data.info.descriptor;
+ offset = integer_zero_node;
+ offsetvar = gfc_create_var_np (gfc_array_index_type, "offset");
+ TREE_USED (offsetvar) = 0;
+ gfc_trans_array_constructor_value (&loop->pre, type,
+ ss->data.info.data,
+ ss->expr->value.constructor, &offset,
+ &offsetvar);
+
+ if (TREE_USED (offsetvar))
+ pushdecl (offsetvar);
+ else
+ assert (INTEGER_CST_P (offset));
+#if 0
+ /* Disable bound checking for now cos it's probably broken. */
+ if (flag_bounds_check)
+ {
+ abort ();
+ }
+#endif
+}
+
+
+/* Add the pre and post chains for all the scalar expressions in a SS chain
+ to loop. This is called after the loop parameters have been calculated,
+ but before the actual scalarizing loops. */
+/*GCC ARRAYS*/
+
+static void
+gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript)
+{
+ gfc_se se;
+ int n;
+
+ assert (ss != NULL);
+
+ for (; ss != gfc_ss_terminator; ss = ss->loop_chain)
+ {
+ assert (ss);
+
+ switch (ss->type)
+ {
+ case GFC_SS_SCALAR:
+ /* Scalar expression. Evaluate this now. This includes elemental
+ dimension indices, but not array section bounds. */
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr (&se, ss->expr);
+ gfc_add_block_to_block (&loop->pre, &se.pre);
+
+ if (ss->expr->ts.type != BT_CHARACTER)
+ {
+ /* Move the evaluation of scalar expressions outside the
+ scalarization loop. */
+ if (subscript)
+ se.expr = convert(gfc_array_index_type, se.expr);
+ se.expr = gfc_evaluate_now (se.expr, &loop->pre);
+ gfc_add_block_to_block (&loop->pre, &se.post);
+ }
+ else
+ gfc_add_block_to_block (&loop->post, &se.post);
+
+ ss->data.scalar.expr = se.expr;
+ ss->data.scalar.string_length = se.string_length;
+ break;
+
+ case GFC_SS_REFERENCE:
+ /* Scalar reference. Evaluate this now. */
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_reference (&se, ss->expr);
+ gfc_add_block_to_block (&loop->pre, &se.pre);
+ gfc_add_block_to_block (&loop->post, &se.post);
+
+ ss->data.scalar.expr = gfc_evaluate_now (se.expr, &loop->pre);
+ ss->data.scalar.string_length = se.string_length;
+ break;
+
+ case GFC_SS_SECTION:
+ case GFC_SS_VECTOR:
+ /* Scalarized expression. Evaluate any scalar subscripts. */
+ for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
+ {
+ /* Add the expressions for scalar subscripts. */
+ if (ss->data.info.subscript[n])
+ gfc_add_loop_ss_code (loop, ss->data.info.subscript[n], true);
+ }
+ break;
+
+ case GFC_SS_INTRINSIC:
+ gfc_add_intrinsic_ss_code (loop, ss);
+ break;
+
+ case GFC_SS_FUNCTION:
+ /* Array function return value. We call the function and save its
+ result in a temporary for use inside the loop. */
+ gfc_init_se (&se, NULL);
+ se.loop = loop;
+ se.ss = ss;
+ gfc_conv_expr (&se, ss->expr);
+ gfc_add_block_to_block (&loop->pre, &se.pre);
+ gfc_add_block_to_block (&loop->post, &se.post);
+ break;
+
+ case GFC_SS_CONSTRUCTOR:
+ gfc_trans_array_constructor (loop, ss);
+ break;
+
+ default:
+ abort ();
+ }
+ }
+}
+
+
+/* Translate expressions for the descriptor and data pointer of a SS. */
+/*GCC ARRAYS*/
+
+static void
+gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base)
+{
+ gfc_se se;
+ tree tmp;
+
+ /* Get the descriptor for the array to be scalarized. */
+ assert (ss->expr->expr_type == EXPR_VARIABLE);
+ gfc_init_se (&se, NULL);
+ se.descriptor_only = 1;
+ gfc_conv_expr_lhs (&se, ss->expr);
+ gfc_add_block_to_block (block, &se.pre);
+ ss->data.info.descriptor = se.expr;
+
+ if (base)
+ {
+ /* Also the data pointer. */
+ tmp = gfc_conv_array_data (se.expr);
+ /* If this is a variable or address of a variable we use it directly.
+ Otherwise we must evaluate it now to to avoid break dependency
+ analysis by pulling the expressions for elemental array indices
+ inside the loop. */
+ if (!(DECL_P (tmp)
+ || (TREE_CODE (tmp) == ADDR_EXPR
+ && DECL_P (TREE_OPERAND (tmp, 0)))))
+ tmp = gfc_evaluate_now (tmp, block);
+ ss->data.info.data = tmp;
+
+ tmp = gfc_conv_array_offset (se.expr);
+ ss->data.info.offset = gfc_evaluate_now (tmp, block);
+ }
+}
+
+
+/* Initialise a gfc_loopinfo structure. */
+
+void
+gfc_init_loopinfo (gfc_loopinfo * loop)
+{
+ int n;
+
+ memset (loop, 0, sizeof (gfc_loopinfo));
+ gfc_init_block (&loop->pre);
+ gfc_init_block (&loop->post);
+
+ /* Initialy scalarize in order. */
+ for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
+ loop->order[n] = n;
+
+ loop->ss = gfc_ss_terminator;
+}
+
+
+/* Copies the loop variable info to a gfc_se sructure. Does not copy the SS
+ chain. */
+
+void
+gfc_copy_loopinfo_to_se (gfc_se * se, gfc_loopinfo * loop)
+{
+ se->loop = loop;
+}
+
+
+/* Return an expression for the data pointer of an array. */
+
+tree
+gfc_conv_array_data (tree descriptor)
+{
+ tree type;
+
+ type = TREE_TYPE (descriptor);
+ if (GFC_ARRAY_TYPE_P (type))
+ {
+ if (TREE_CODE (type) == POINTER_TYPE)
+ return descriptor;
+ else
+ {
+ /* Descritporless arrays. */
+ return gfc_build_addr_expr (NULL, descriptor);
+ }
+ }
+ else
+ return gfc_conv_descriptor_data (descriptor);
+}
+
+
+/* Return an expression for the base offset of an array. */
+
+tree
+gfc_conv_array_offset (tree descriptor)
+{
+ tree type;
+
+ type = TREE_TYPE (descriptor);
+ if (GFC_ARRAY_TYPE_P (type))
+ return GFC_TYPE_ARRAY_OFFSET (type);
+ else
+ return gfc_conv_descriptor_offset (descriptor);
+}
+
+
+/* Get an expression for the array stride. */
+
+tree
+gfc_conv_array_stride (tree descriptor, int dim)
+{
+ tree tmp;
+ tree type;
+
+ type = TREE_TYPE (descriptor);
+
+ /* For descriptorless arrays use the array size. */
+ tmp = GFC_TYPE_ARRAY_STRIDE (type, dim);
+ if (tmp != NULL_TREE)
+ return tmp;
+
+ tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[dim]);
+ return tmp;
+}
+
+
+/* Like gfc_conv_array_stride, but for the lower bound. */
+
+tree
+gfc_conv_array_lbound (tree descriptor, int dim)
+{
+ tree tmp;
+ tree type;
+
+ type = TREE_TYPE (descriptor);
+
+ tmp = GFC_TYPE_ARRAY_LBOUND (type, dim);
+ if (tmp != NULL_TREE)
+ return tmp;
+
+ tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[dim]);
+ return tmp;
+}
+
+
+/* Like gfc_conv_array_stride, but for the upper bound. */
+
+tree
+gfc_conv_array_ubound (tree descriptor, int dim)
+{
+ tree tmp;
+ tree type;
+
+ type = TREE_TYPE (descriptor);
+
+ tmp = GFC_TYPE_ARRAY_UBOUND (type, dim);
+ if (tmp != NULL_TREE)
+ return tmp;
+
+ /* This should only ever happen when passing an assumed shape array
+ as an actual parameter. The value will never be used. */
+ if (GFC_ARRAY_TYPE_P (TREE_TYPE (descriptor)))
+ return integer_zero_node;
+
+ tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[dim]);
+ return tmp;
+}
+
+
+/* Translate an array reference. The descriptor should be in se->expr.
+ Do not use this function, it wil be removed soon. */
+/*GCC ARRAYS*/
+
+static void
+gfc_conv_array_index_ref (gfc_se * se, tree pointer, tree * indices,
+ tree offset, int dimen)
+{
+ tree array;
+ tree tmp;
+ tree index;
+ int n;
+
+ array = gfc_build_indirect_ref (pointer);
+
+ index = offset;
+ for (n = 0; n < dimen; n++)
+ {
+ /* index = index + stride[n]*indices[n] */
+ tmp = gfc_conv_array_stride (se->expr, n);
+ tmp = fold (build (MULT_EXPR, gfc_array_index_type, indices[n], tmp));
+
+ index = fold (build (PLUS_EXPR, gfc_array_index_type, index, tmp));
+ }
+
+ /* Result = data[index]. */
+ tmp = gfc_build_array_ref (array, index);
+
+ /* Check we've used the correct number of dimensions. */
+ assert (TREE_CODE (TREE_TYPE (tmp)) != ARRAY_TYPE);
+
+ se->expr = tmp;
+}
+
+
+/* Generate code to perform an array index bound check. */
+
+static tree
+gfc_trans_array_bound_check (gfc_se * se, tree descriptor, tree index, int n)
+{
+ tree cond;
+ tree fault;
+ tree tmp;
+
+ if (!flag_bounds_check)
+ return index;
+
+ index = gfc_evaluate_now (index, &se->pre);
+ /* Check lower bound. */
+ tmp = gfc_conv_array_lbound (descriptor, n);
+ fault = fold (build (LT_EXPR, boolean_type_node, index, tmp));
+ /* Check upper bound. */
+ tmp = gfc_conv_array_ubound (descriptor, n);
+ cond = fold (build (GT_EXPR, boolean_type_node, index, tmp));
+ fault = fold (build (TRUTH_OR_EXPR, boolean_type_node, fault, cond));
+
+ gfc_trans_runtime_check (fault, gfc_strconst_fault, &se->pre);
+
+ return index;
+}
+
+
+/* A reference to an array vector subscript. Uses recursion to handle nested
+ vector subscripts. */
+
+static tree
+gfc_conv_vector_array_index (gfc_se * se, tree index, gfc_ss * ss)
+{
+ tree descsave;
+ tree indices[GFC_MAX_DIMENSIONS];
+ gfc_array_ref *ar;
+ gfc_ss_info *info;
+ int n;
+
+ assert (ss && ss->type == GFC_SS_VECTOR);
+
+ /* Save the descriptor. */
+ descsave = se->expr;
+ info = &ss->data.info;
+ se->expr = info->descriptor;
+
+ ar = &info->ref->u.ar;
+ for (n = 0; n < ar->dimen; n++)
+ {
+ switch (ar->dimen_type[n])
+ {
+ case DIMEN_ELEMENT:
+ assert (info->subscript[n] != gfc_ss_terminator
+ && info->subscript[n]->type == GFC_SS_SCALAR);
+ indices[n] = info->subscript[n]->data.scalar.expr;
+ break;
+
+ case DIMEN_RANGE:
+ indices[n] = index;
+ break;
+
+ case DIMEN_VECTOR:
+ index = gfc_conv_vector_array_index (se, index, info->subscript[n]);
+
+ indices[n] =
+ gfc_trans_array_bound_check (se, info->descriptor, index, n);
+ break;
+
+ default:
+ abort ();
+ }
+ }
+ /* Get the index from the vector. */
+ gfc_conv_array_index_ref (se, info->data, indices, info->offset, ar->dimen);
+ index = se->expr;
+ /* Put the descriptor back. */
+ se->expr = descsave;
+
+ return index;
+}
+
+
+/* Return the offset for an index. Performs bound checking for elemental
+ dimensions. Single element references are processed seperately. */
+
+static tree
+gfc_conv_array_index_offset (gfc_se * se, gfc_ss_info * info, int dim, int i,
+ gfc_array_ref * ar, tree stride)
+{
+ tree index;
+
+ /* Get the index into the array for this dimension. */
+ if (ar)
+ {
+ assert (ar->type != AR_ELEMENT);
+ if (ar->dimen_type[dim] == DIMEN_ELEMENT)
+ {
+ assert (i == -1);
+ /* Elemental dimension. */
+ assert (info->subscript[dim]
+ && info->subscript[dim]->type == GFC_SS_SCALAR);
+ /* We've already translated this value outside the loop. */
+ index = info->subscript[dim]->data.scalar.expr;
+
+ index =
+ gfc_trans_array_bound_check (se, info->descriptor, index, dim);
+ }
+ else
+ {
+ /* Scalarized dimension. */
+ assert (info && se->loop);
+
+ /* Multiply the loop variable by the stride and dela. */
+ index = se->loop->loopvar[i];
+ index = fold (build (MULT_EXPR, gfc_array_index_type, index,
+ info->stride[i]));
+ index = fold (build (PLUS_EXPR, gfc_array_index_type, index,
+ info->delta[i]));
+
+ if (ar->dimen_type[dim] == DIMEN_VECTOR)
+ {
+ /* Handle vector subscripts. */
+ index = gfc_conv_vector_array_index (se, index,
+ info->subscript[dim]);
+ index =
+ gfc_trans_array_bound_check (se, info->descriptor, index,
+ dim);
+ }
+ else
+ assert (ar->dimen_type[dim] == DIMEN_RANGE);
+ }
+ }
+ else
+ {
+ /* Temporary array. */
+ assert (se->loop);
+ index = se->loop->loopvar[se->loop->order[i]];
+ }
+
+ /* Multiply by the stride. */
+ index = fold (build (MULT_EXPR, gfc_array_index_type, index, stride));
+
+ return index;
+}
+
+
+/* Build a scalarized reference to an array. */
+
+static void
+gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
+{
+ gfc_ss_info *info;
+ tree index;
+ tree tmp;
+ int n;
+
+ info = &se->ss->data.info;
+ if (ar)
+ n = se->loop->order[0];
+ else
+ n = 0;
+
+ index = gfc_conv_array_index_offset (se, info, info->dim[n], n, ar,
+ info->stride0);
+ /* Add the offset for this dimension to the stored offset for all other
+ dimensions. */
+ index = fold (build (PLUS_EXPR, gfc_array_index_type, index, info->offset));
+
+ tmp = gfc_build_indirect_ref (info->data);
+ se->expr = gfc_build_array_ref (tmp, index);
+}
+
+
+/* Translate access of temporary array. */
+
+void
+gfc_conv_tmp_array_ref (gfc_se * se)
+{
+ tree desc;
+
+ desc = se->ss->data.info.descriptor;
+ /* TODO: We need the string length for string variables. */
+
+ gfc_conv_scalarized_array_ref (se, NULL);
+}
+
+
+/* Build an array reference. se->expr already holds the array descriptor.
+ This should be either a variable, indirect variable reference or component
+ reference. For arrays which do not have a descriptor, se->expr will be
+ the data pointer.
+ a(i, j, k) = base[offset + i * stride[0] + j * stride[1] + k * stride[2]]*/
+
+void
+gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar)
+{
+ int n;
+ tree index;
+ tree tmp;
+ tree stride;
+ tree fault;
+ gfc_se indexse;
+
+ /* Handle scalarized references seperately. */
+ if (ar->type != AR_ELEMENT)
+ {
+ gfc_conv_scalarized_array_ref (se, ar);
+ return;
+ }
+
+ index = integer_zero_node;
+
+ fault = integer_zero_node;
+
+ /* Calculate the offsets from all the dimensions. */
+ for (n = 0; n < ar->dimen; n++)
+ {
+ /* Calculate the index for this demension. */
+ gfc_init_se (&indexse, NULL);
+ gfc_conv_expr_type (&indexse, ar->start[n], gfc_array_index_type);
+ gfc_add_block_to_block (&se->pre, &indexse.pre);
+
+ if (flag_bounds_check)
+ {
+ /* Check array bounds. */
+ tree cond;
+
+ indexse.expr = gfc_evaluate_now (indexse.expr, &se->pre);
+
+ tmp = gfc_conv_array_lbound (se->expr, n);
+ cond = fold (build (LT_EXPR, boolean_type_node, indexse.expr, tmp));
+ fault =
+ fold (build (TRUTH_OR_EXPR, boolean_type_node, fault, cond));
+
+ tmp = gfc_conv_array_ubound (se->expr, n);
+ cond = fold (build (GT_EXPR, boolean_type_node, indexse.expr, tmp));
+ fault =
+ fold (build (TRUTH_OR_EXPR, boolean_type_node, fault, cond));
+ }
+
+ /* Multiply the index by the stride. */
+ stride = gfc_conv_array_stride (se->expr, n);
+ tmp = fold (build (MULT_EXPR, gfc_array_index_type, indexse.expr,
+ stride));
+
+ /* And add it to the total. */
+ index = fold (build (PLUS_EXPR, gfc_array_index_type, index, tmp));
+ }
+
+ if (flag_bounds_check)
+ gfc_trans_runtime_check (fault, gfc_strconst_fault, &se->pre);
+
+ tmp = gfc_conv_array_offset (se->expr);
+ if (!integer_zerop (tmp))
+ index = fold (build (PLUS_EXPR, gfc_array_index_type, index, tmp));
+
+ /* Access the calculated element. */
+ tmp = gfc_conv_array_data (se->expr);
+ tmp = gfc_build_indirect_ref (tmp);
+ se->expr = gfc_build_array_ref (tmp, index);
+}
+
+
+/* Generate the code to be executed immediately before entering a
+ scalarization loop. */
+
+static void
+gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag,
+ stmtblock_t * pblock)
+{
+ tree index;
+ tree stride;
+ gfc_ss_info *info;
+ gfc_ss *ss;
+ gfc_se se;
+ int i;
+
+ /* This code will be executed before entering the scalarization loop
+ for this dimension. */
+ for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
+ {
+ if ((ss->useflags & flag) == 0)
+ continue;
+
+ if (ss->type != GFC_SS_SECTION
+ && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR)
+ continue;
+
+ info = &ss->data.info;
+
+ if (dim >= info->dimen)
+ continue;
+
+ if (dim == info->dimen - 1)
+ {
+ /* For the outermost loop calculate the offset due to any
+ elemental dimensions. It will have been initialized with the
+ base offset of the array. */
+ if (info->ref)
+ {
+ for (i = 0; i < info->ref->u.ar.dimen; i++)
+ {
+ if (info->ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
+ continue;
+
+ gfc_init_se (&se, NULL);
+ se.loop = loop;
+ se.expr = info->descriptor;
+ stride = gfc_conv_array_stride (info->descriptor, i);
+ index = gfc_conv_array_index_offset (&se, info, i, -1,
+ &info->ref->u.ar,
+ stride);
+ gfc_add_block_to_block (pblock, &se.pre);
+
+ info->offset = fold (build (PLUS_EXPR, gfc_array_index_type,
+ info->offset, index));
+ info->offset = gfc_evaluate_now (info->offset, pblock);
+ }
+
+ i = loop->order[0];
+ stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
+ }
+ else
+ stride = gfc_conv_array_stride (info->descriptor, 0);
+
+ /* Calculate the stride of the innermost loop. Hopefully this will
+ allow the backend optimizers to do their stuff more effectively.
+ */
+ info->stride0 = gfc_evaluate_now (stride, pblock);
+ }
+ else
+ {
+ /* Add the offset for the previous loop dimension. */
+ gfc_array_ref *ar;
+
+ if (info->ref)
+ {
+ ar = &info->ref->u.ar;
+ i = loop->order[dim + 1];
+ }
+ else
+ {
+ ar = NULL;
+ i = dim + 1;
+ }
+
+ gfc_init_se (&se, NULL);
+ se.loop = loop;
+ se.expr = info->descriptor;
+ stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);
+ index = gfc_conv_array_index_offset (&se, info, info->dim[i], i,
+ ar, stride);
+ gfc_add_block_to_block (pblock, &se.pre);
+ info->offset = fold (build (PLUS_EXPR, gfc_array_index_type,
+ info->offset, index));
+ info->offset = gfc_evaluate_now (info->offset, pblock);
+ }
+
+ /* Remeber this offset for the second loop. */
+ if (dim == loop->temp_dim - 1)
+ info->saved_offset = info->offset;
+ }
+}
+
+
+/* Start a scalarized expression. Creates a scope and declares loop
+ variables. */
+
+void
+gfc_start_scalarized_body (gfc_loopinfo * loop, stmtblock_t * pbody)
+{
+ int dim;
+ int n;
+ int flags;
+
+ assert (!loop->array_parameter);
+
+ for (dim = loop->dimen - 1; dim >= 0; dim--)
+ {
+ n = loop->order[dim];
+
+ gfc_start_block (&loop->code[n]);
+
+ /* Create the loop variable. */
+ loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "S");
+
+ if (dim < loop->temp_dim)
+ flags = 3;
+ else
+ flags = 1;
+ /* Calculate values that will be constant within this loop. */
+ gfc_trans_preloop_setup (loop, dim, flags, &loop->code[n]);
+ }
+ gfc_start_block (pbody);
+}
+
+
+/* Generates the actual loop code for a scalarization loop. */
+
+static void
+gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,
+ stmtblock_t * pbody)
+{
+ stmtblock_t block;
+ tree cond;
+ tree tmp;
+ tree loopbody;
+ tree exit_label;
+
+ loopbody = gfc_finish_block (pbody);
+
+ /* Initialize the loopvar. */
+ gfc_add_modify_expr (&loop->code[n], loop->loopvar[n], loop->from[n]);
+
+ exit_label = gfc_build_label_decl (NULL_TREE);
+
+ /* Generate the loop body. */
+ gfc_init_block (&block);
+
+ /* The exit condition. */
+ cond = build (GT_EXPR, boolean_type_node, loop->loopvar[n], loop->to[n]);
+ tmp = build1_v (GOTO_EXPR, exit_label);
+ TREE_USED (exit_label) = 1;
+ tmp = build_v (COND_EXPR, cond, tmp, build_empty_stmt ());
+ gfc_add_expr_to_block (&block, tmp);
+
+ /* The main body. */
+ gfc_add_expr_to_block (&block, loopbody);
+
+ /* Increment the loopvar. */
+ tmp = build (PLUS_EXPR, gfc_array_index_type,
+ loop->loopvar[n], integer_one_node);
+ gfc_add_modify_expr (&block, loop->loopvar[n], tmp);
+
+ /* Build the loop. */
+ tmp = gfc_finish_block (&block);
+ tmp = build_v (LOOP_EXPR, tmp);
+ gfc_add_expr_to_block (&loop->code[n], tmp);
+
+ /* Add the exit label. */
+ tmp = build1_v (LABEL_EXPR, exit_label);
+ gfc_add_expr_to_block (&loop->code[n], tmp);
+}
+
+
+/* Finishes and generates the loops for a scalarized expression. */
+
+void
+gfc_trans_scalarizing_loops (gfc_loopinfo * loop, stmtblock_t * body)
+{
+ int dim;
+ int n;
+ gfc_ss *ss;
+ stmtblock_t *pblock;
+ tree tmp;
+
+ pblock = body;
+ /* Generate the loops. */
+ for (dim = 0; dim < loop->dimen; dim++)
+ {
+ n = loop->order[dim];
+ gfc_trans_scalarized_loop_end (loop, n, pblock);
+ loop->loopvar[n] = NULL_TREE;
+ pblock = &loop->code[n];
+ }
+
+ tmp = gfc_finish_block (pblock);
+ gfc_add_expr_to_block (&loop->pre, tmp);
+
+ /* Clear all the used flags. */
+ for (ss = loop->ss; ss; ss = ss->loop_chain)
+ ss->useflags = 0;
+}
+
+
+/* Finish the main body of a scalarized expression, and start the secondary
+ copying body. */
+
+void
+gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body)
+{
+ int dim;
+ int n;
+ stmtblock_t *pblock;
+ gfc_ss *ss;
+
+ pblock = body;
+ /* We finish as many loops as are used by the temporary. */
+ for (dim = 0; dim < loop->temp_dim - 1; dim++)
+ {
+ n = loop->order[dim];
+ gfc_trans_scalarized_loop_end (loop, n, pblock);
+ loop->loopvar[n] = NULL_TREE;
+ pblock = &loop->code[n];
+ }
+
+ /* We don't want to finish the outermost loop entirely. */
+ n = loop->order[loop->temp_dim - 1];
+ gfc_trans_scalarized_loop_end (loop, n, pblock);
+
+ /* Restore the initial offsets. */
+ for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
+ {
+ if ((ss->useflags & 2) == 0)
+ continue;
+
+ if (ss->type != GFC_SS_SECTION
+ && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR)
+ continue;
+
+ ss->data.info.offset = ss->data.info.saved_offset;
+ }
+
+ /* Restart all the inner loops we just finished. */
+ for (dim = loop->temp_dim - 2; dim >= 0; dim--)
+ {
+ n = loop->order[dim];
+
+ gfc_start_block (&loop->code[n]);
+
+ loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "Q");
+
+ gfc_trans_preloop_setup (loop, dim, 2, &loop->code[n]);
+ }
+
+ /* Start a block for the secondary copying code. */
+ gfc_start_block (body);
+}
+
+
+/* Calculate the upper bound of an array section. */
+
+static tree
+gfc_conv_section_upper_bound (gfc_ss * ss, int n, stmtblock_t * pblock)
+{
+ int dim;
+ gfc_ss *vecss;
+ gfc_expr *end;
+ tree desc;
+ tree bound;
+ gfc_se se;
+
+ assert (ss->type == GFC_SS_SECTION);
+
+ /* For vector array subscripts we want the size of the vector. */
+ dim = ss->data.info.dim[n];
+ vecss = ss;
+ while (vecss->data.info.ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
+ {
+ vecss = vecss->data.info.subscript[dim];
+ assert (vecss && vecss->type == GFC_SS_VECTOR);
+ dim = vecss->data.info.dim[0];
+ }
+
+ assert (vecss->data.info.ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
+ end = vecss->data.info.ref->u.ar.end[dim];
+ desc = vecss->data.info.descriptor;
+
+ if (end)
+ {
+ /* The upper bound was specified. */
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_type (&se, end, gfc_array_index_type);
+ gfc_add_block_to_block (pblock, &se.pre);
+ bound = se.expr;
+ }
+ else
+ {
+ /* No upper bound was specified, so use the bound of the array. */
+ bound = gfc_conv_array_ubound (desc, dim);
+ }
+
+ return bound;
+}
+
+
+/* Calculate the lower bound of an array section. */
+
+static void
+gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int n)
+{
+ gfc_expr *start;
+ gfc_expr *stride;
+ gfc_ss *vecss;
+ tree desc;
+ gfc_se se;
+ gfc_ss_info *info;
+ int dim;
+
+ info = &ss->data.info;
+
+ dim = info->dim[n];
+
+ /* For vector array subscripts we want the size of the vector. */
+ vecss = ss;
+ while (vecss->data.info.ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
+ {
+ vecss = vecss->data.info.subscript[dim];
+ assert (vecss && vecss->type == GFC_SS_VECTOR);
+ /* Get the descriptors for the vector subscripts as well. */
+ if (!vecss->data.info.descriptor)
+ gfc_conv_ss_descriptor (&loop->pre, vecss, !loop->array_parameter);
+ dim = vecss->data.info.dim[0];
+ }
+
+ assert (vecss->data.info.ref->u.ar.dimen_type[dim] == DIMEN_RANGE);
+ start = vecss->data.info.ref->u.ar.start[dim];
+ stride = vecss->data.info.ref->u.ar.stride[dim];
+ desc = vecss->data.info.descriptor;
+
+ /* Calculate the start of the range. For vector subscripts this will
+ be the range of the vector. */
+ if (start)
+ {
+ /* Specified section start. */
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_type (&se, start, gfc_array_index_type);
+ gfc_add_block_to_block (&loop->pre, &se.pre);
+ info->start[n] = se.expr;
+ }
+ else
+ {
+ /* No lower bound specified so use the bound of the array. */
+ info->start[n] = gfc_conv_array_lbound (desc, dim);
+ }
+ info->start[n] = gfc_evaluate_now (info->start[n], &loop->pre);
+
+ /* Calculate the stride. */
+ if (stride == NULL)
+ info->stride[n] = integer_one_node;
+ else
+ {
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_type (&se, stride, gfc_array_index_type);
+ gfc_add_block_to_block (&loop->pre, &se.pre);
+ info->stride[n] = gfc_evaluate_now (se.expr, &loop->pre);
+ }
+}
+
+
+/* Calculates the range start and stride for a SS chain. Also gets the
+ descriptor and data pointer. The range of vector subscripts is the size
+ of the vector. Array bounds are also checked. */
+
+void
+gfc_conv_ss_startstride (gfc_loopinfo * loop)
+{
+ int n;
+ tree tmp;
+ gfc_ss *ss;
+ gfc_ss *vecss;
+ tree desc;
+
+ loop->dimen = 0;
+ /* Determine the rank of the loop. */
+ for (ss = loop->ss;
+ ss != gfc_ss_terminator && loop->dimen == 0; ss = ss->loop_chain)
+ {
+ switch (ss->type)
+ {
+ case GFC_SS_SECTION:
+ case GFC_SS_CONSTRUCTOR:
+ case GFC_SS_FUNCTION:
+ loop->dimen = ss->data.info.dimen;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (loop->dimen == 0)
+ gfc_todo_error ("Unable to determine rank of expression");
+
+
+ /* loop over all the SS in the chain. */
+ for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
+ {
+ switch (ss->type)
+ {
+ case GFC_SS_SECTION:
+ /* Get the descriptor for the array. */
+ gfc_conv_ss_descriptor (&loop->pre, ss, !loop->array_parameter);
+
+ for (n = 0; n < ss->data.info.dimen; n++)
+ gfc_conv_section_startstride (loop, ss, n);
+ break;
+
+ case GFC_SS_CONSTRUCTOR:
+ case GFC_SS_FUNCTION:
+ for (n = 0; n < ss->data.info.dimen; n++)
+ {
+ ss->data.info.start[n] = integer_zero_node;
+ ss->data.info.stride[n] = integer_one_node;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* The rest is just runtime bound checking. */
+ if (flag_bounds_check)
+ {
+ stmtblock_t block;
+ tree fault;
+ tree bound;
+ tree end;
+ tree size[GFC_MAX_DIMENSIONS];
+ gfc_ss_info *info;
+ int dim;
+
+ gfc_start_block (&block);
+
+ fault = integer_zero_node;
+ for (n = 0; n < loop->dimen; n++)
+ size[n] = NULL_TREE;
+
+ for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
+ {
+ if (ss->type != GFC_SS_SECTION)
+ continue;
+
+ /* TODO: range checking for mapped dimensions. */
+ info = &ss->data.info;
+
+ /* This only checks scalarized dimensions, elemental dimensions are
+ checked later. */
+ for (n = 0; n < loop->dimen; n++)
+ {
+ dim = info->dim[n];
+ vecss = ss;
+ while (vecss->data.info.ref->u.ar.dimen_type[dim]
+ == DIMEN_VECTOR)
+ {
+ vecss = vecss->data.info.subscript[dim];
+ assert (vecss && vecss->type == GFC_SS_VECTOR);
+ dim = vecss->data.info.dim[0];
+ }
+ assert (vecss->data.info.ref->u.ar.dimen_type[dim]
+ == DIMEN_RANGE);
+ desc = vecss->data.info.descriptor;
+
+ /* Check lower bound. */
+ bound = gfc_conv_array_lbound (desc, dim);
+ tmp = info->start[n];
+ tmp = fold (build (LT_EXPR, boolean_type_node, tmp, bound));
+ fault = fold (build (TRUTH_OR_EXPR, boolean_type_node, fault,
+ tmp));
+
+ /* Check the upper bound. */
+ bound = gfc_conv_array_ubound (desc, dim);
+ end = gfc_conv_section_upper_bound (ss, n, &block);
+ tmp = fold (build (GT_EXPR, boolean_type_node, end, bound));
+ fault = fold (build (TRUTH_OR_EXPR, boolean_type_node, fault,
+ tmp));
+
+ /* Check the section sizes match. */
+ tmp = fold (build (MINUS_EXPR, gfc_array_index_type, end,
+ info->start[n]));
+ tmp = fold (build (FLOOR_DIV_EXPR, gfc_array_index_type, tmp,
+ info->stride[n]));
+ /* We remember the size of the first section, and check all the
+ others against this. */
+ if (size[n])
+ {
+ tmp =
+ fold (build (NE_EXPR, boolean_type_node, tmp, size[n]));
+ fault =
+ build (TRUTH_OR_EXPR, boolean_type_node, fault, tmp);
+ }
+ else
+ size[n] = gfc_evaluate_now (tmp, &block);
+ }
+ }
+ gfc_trans_runtime_check (fault, gfc_strconst_bounds, &block);
+
+ tmp = gfc_finish_block (&block);
+ gfc_add_expr_to_block (&loop->pre, tmp);
+ }
+}
+
+
+/* Return true if the two SS could be aliased, ie. both point to the same data
+ object. */
+/* TODO: resolve aliases based on frontend expressions. */
+
+static int
+gfc_could_be_alias (gfc_ss * lss, gfc_ss * rss)
+{
+ gfc_ref *lref;
+ gfc_ref *rref;
+ gfc_symbol *lsym;
+ gfc_symbol *rsym;
+
+ lsym = lss->expr->symtree->n.sym;
+ rsym = rss->expr->symtree->n.sym;
+ if (gfc_symbols_could_alias (lsym, rsym))
+ return 1;
+
+ if (rsym->ts.type != BT_DERIVED
+ && lsym->ts.type != BT_DERIVED)
+ return 0;
+
+ /* For Derived types we must check all the component types. We can ignore
+ array references as these will have the same base type as the previous
+ component ref. */
+ for (lref = lss->expr->ref; lref != lss->data.info.ref; lref = lref->next)
+ {
+ if (lref->type != REF_COMPONENT)
+ continue;
+
+ if (gfc_symbols_could_alias (lref->u.c.sym, rsym))
+ return 1;
+
+ for (rref = rss->expr->ref; rref != rss->data.info.ref;
+ rref = rref->next)
+ {
+ if (rref->type != REF_COMPONENT)
+ continue;
+
+ if (gfc_symbols_could_alias (lref->u.c.sym, rref->u.c.sym))
+ return 1;
+ }
+ }
+
+ for (rref = rss->expr->ref; rref != rss->data.info.ref; rref = rref->next)
+ {
+ if (rref->type != REF_COMPONENT)
+ break;
+
+ if (gfc_symbols_could_alias (rref->u.c.sym, lsym))
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/* Resolve array data dependencies. Creates a temporary if required. */
+/* TODO: Calc dependencies with gfc_expr rather than gfc_ss, and move to
+ dependency.c. */
+
+void
+gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
+ gfc_ss * rss)
+{
+ gfc_ss *ss;
+ gfc_ref *lref;
+ gfc_ref *rref;
+ gfc_ref *aref;
+ int nDepend = 0;
+ int temp_dim = 0;
+
+ loop->temp_ss = NULL;
+ aref = dest->data.info.ref;
+ temp_dim = 0;
+
+ for (ss = rss; ss != gfc_ss_terminator; ss = ss->next)
+ {
+ if (ss->type != GFC_SS_SECTION)
+ continue;
+
+ if (gfc_could_be_alias (dest, ss))
+ {
+ nDepend = 1;
+ break;
+ }
+
+ if (dest->expr->symtree->n.sym == ss->expr->symtree->n.sym)
+ {
+ lref = dest->expr->ref;
+ rref = ss->expr->ref;
+
+ nDepend = gfc_dep_resolver (lref, rref);
+#if 0
+ /* TODO : loop shifting. */
+ if (nDepend == 1)
+ {
+ /* Mark the dimensions for LOOP SHIFTING */
+ for (n = 0; n < loop->dimen; n++)
+ {
+ int dim = dest->data.info.dim[n];
+
+ if (lref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
+ depends[n] = 2;
+ else if (! gfc_is_same_range (&lref->u.ar,
+ &rref->u.ar, dim, 0))
+ depends[n] = 1;
+ }
+
+ /* Put all the dimensions with dependancies in the
+ innermost loops. */
+ dim = 0;
+ for (n = 0; n < loop->dimen; n++)
+ {
+ assert (loop->order[n] == n);
+ if (depends[n])
+ loop->order[dim++] = n;
+ }
+ temp_dim = dim;
+ for (n = 0; n < loop->dimen; n++)
+ {
+ if (! depends[n])
+ loop->order[dim++] = n;
+ }
+
+ assert (dim == loop->dimen);
+ break;
+ }
+#endif
+ }
+ }
+
+ if (nDepend == 1)
+ {
+ loop->temp_ss = gfc_get_ss ();
+ loop->temp_ss->type = GFC_SS_TEMP;
+ loop->temp_ss->data.temp.type =
+ gfc_get_element_type (TREE_TYPE (dest->data.info.descriptor));
+ loop->temp_ss->data.temp.string_length = NULL_TREE;
+ loop->temp_ss->data.temp.dimen = loop->dimen;
+ loop->temp_ss->next = gfc_ss_terminator;
+ gfc_add_ss_to_loop (loop, loop->temp_ss);
+ }
+ else
+ loop->temp_ss = NULL;
+}
+
+
+/* Initialise the scalarization loop. Creates the loop variables. Determines
+ the range of the loop variables. Creates a temporary if required.
+ Calculates how to transform from loop variables to array indices for each
+ expression. Also generates code for scalar expressions which have been
+ moved outside the loop. */
+
+void
+gfc_conv_loop_setup (gfc_loopinfo * loop)
+{
+ int n;
+ int dim;
+ gfc_ss_info *info;
+ gfc_ss_info *specinfo;
+ gfc_ss *ss;
+ tree tmp;
+ tree len;
+ gfc_ss *loopspec[GFC_MAX_DIMENSIONS];
+ mpz_t *cshape;
+ mpz_t i;
+
+ mpz_init (i);
+ for (n = 0; n < loop->dimen; n++)
+ {
+ loopspec[n] = NULL;
+ /* We use one SS term, and use that to determine the bounds of the
+ loop for this dimension. We try to pick the simplest term. */
+ for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
+ {
+ if (ss->expr && ss->expr->shape)
+ {
+ /* The frontend has worked out the size for us. */
+ loopspec[n] = ss;
+ continue;
+ }
+
+ if (ss->type == GFC_SS_CONSTRUCTOR)
+ {
+ /* Try to figure out the size of the constructior. */
+ /* TODO: avoid this by making the prontend set the shape. */
+ gfc_get_array_cons_size (&i, ss->expr->value.constructor);
+ /* A negative value meens we failed. */
+ if (mpz_sgn (i) > 0)
+ {
+ mpz_sub_ui (i, i, 1);
+ loop->to[n] =
+ gfc_conv_mpz_to_tree (i, gfc_index_integer_kind);
+ loopspec[n] = ss;
+ }
+ continue;
+ }
+
+ /* We don't know how to handle functions yet.
+ This may not be possible in all cases. */
+ if (ss->type != GFC_SS_SECTION)
+ continue;
+
+ info = &ss->data.info;
+
+ if (loopspec[n])
+ specinfo = &loopspec[n]->data.info;
+ else
+ specinfo = NULL;
+ info = &ss->data.info;
+
+ /* Criteria for choosing a loop specifier (most important first):
+ stride of one
+ known stride
+ known lower bound
+ known upper bound
+ */
+ if (!specinfo)
+ loopspec[n] = ss;
+ else if (loopspec[n]->type != GFC_SS_CONSTRUCTOR)
+ {
+ if (integer_onep (info->stride[n])
+ && !integer_onep (specinfo->stride[n]))
+ loopspec[n] = ss;
+ else if (INTEGER_CST_P (info->stride[n])
+ && !INTEGER_CST_P (specinfo->stride[n]))
+ loopspec[n] = ss;
+ else if (INTEGER_CST_P (info->start[n])
+ && !INTEGER_CST_P (specinfo->start[n]))
+ loopspec[n] = ss;
+ /* We don't work out the upper bound.
+ else if (INTEGER_CST_P (info->finish[n])
+ && ! INTEGER_CST_P (specinfo->finish[n]))
+ loopspec[n] = ss; */
+ }
+ }
+
+ if (!loopspec[n])
+ gfc_todo_error ("Unable to find scalarization loop specifier");
+
+ info = &loopspec[n]->data.info;
+
+ /* Set the extents of this range. */
+ cshape = loopspec[n]->expr->shape;
+ if (cshape && INTEGER_CST_P (info->start[n])
+ && INTEGER_CST_P (info->stride[n]))
+ {
+ loop->from[n] = info->start[n];
+ mpz_set (i, cshape[n]);
+ mpz_sub_ui (i, i, 1);
+ /* To = from + (size - 1) * stride. */
+ tmp = gfc_conv_mpz_to_tree (i, gfc_index_integer_kind);
+ if (!integer_onep (info->stride[n]))
+ {
+ tmp = fold (build (MULT_EXPR, gfc_array_index_type,
+ tmp, info->stride[n]));
+ }
+ loop->to[n] = fold (build (PLUS_EXPR, gfc_array_index_type,
+ loop->from[n], tmp));
+ }
+ else
+ {
+ loop->from[n] = info->start[n];
+ switch (loopspec[n]->type)
+ {
+ case GFC_SS_CONSTRUCTOR:
+ assert (info->dimen == 1);
+ assert (loop->to[n]);
+ break;
+
+ case GFC_SS_SECTION:
+ loop->to[n] = gfc_conv_section_upper_bound (loopspec[n], n,
+ &loop->pre);
+ break;
+
+ default:
+ abort ();
+ }
+ }
+
+ /* Transform everything so we have a simple incrementing variable. */
+ if (integer_onep (info->stride[n]))
+ info->delta[n] = integer_zero_node;
+ else
+ {
+ /* Set the delta for this section. */
+ info->delta[n] = gfc_evaluate_now (loop->from[n], &loop->pre);
+ /* Number of iterations is (end - start + step) / step.
+ with start = 0, this simplifies to
+ last = end / step;
+ for (i = 0; i<=last; i++){...}; */
+ tmp = fold (build (MINUS_EXPR, gfc_array_index_type, loop->to[n],
+ loop->from[n]));
+ tmp = fold (build (TRUNC_DIV_EXPR, gfc_array_index_type, tmp,
+ info->stride[n]));
+ loop->to[n] = gfc_evaluate_now (tmp, &loop->pre);
+ /* Make the loop variable start at 0. */
+ loop->from[n] = integer_zero_node;
+ }
+ }
+
+ /* If we want a temporary then create it. */
+ if (loop->temp_ss != NULL)
+ {
+ assert (loop->temp_ss->type == GFC_SS_TEMP);
+ tmp = loop->temp_ss->data.temp.type;
+ len = loop->temp_ss->data.temp.string_length;
+ n = loop->temp_ss->data.temp.dimen;
+ memset (&loop->temp_ss->data.info, 0, sizeof (gfc_ss_info));
+ loop->temp_ss->type = GFC_SS_SECTION;
+ loop->temp_ss->data.info.dimen = n;
+ gfc_trans_allocate_temp_array (loop, &loop->temp_ss->data.info,
+ tmp, len);
+ }
+
+ /* Add all the scalar code that can be taken out of the loops. */
+ gfc_add_loop_ss_code (loop, loop->ss, false);
+
+ for (n = 0; n < loop->temp_dim; n++)
+ loopspec[loop->order[n]] = NULL;
+
+ mpz_clear (i);
+
+ /* For array parameters we don't have loop variables, so don't calculate the
+ translations. */
+ if (loop->array_parameter)
+ return;
+
+ /* Calculate the translation from loop variables to array indices. */
+ for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
+ {
+ if (ss->type != GFC_SS_SECTION)
+ continue;
+
+ info = &ss->data.info;
+
+ for (n = 0; n < info->dimen; n++)
+ {
+ dim = info->dim[n];
+
+ /* If we are specifying the range the delta may already be set. */
+ if (loopspec[n] != ss)
+ {
+ /* Calculate the offset relative to the loop variable.
+ First multiply by the stride. */
+ tmp = fold (build (MULT_EXPR, gfc_array_index_type,
+ loop->from[n], info->stride[n]));
+
+ /* Then subtract this from our starting value. */
+ tmp = fold (build (MINUS_EXPR, gfc_array_index_type,
+ info->start[n], tmp));
+
+ info->delta[n] = gfc_evaluate_now (tmp, &loop->pre);
+ }
+ }
+ }
+}
+
+
+/* Fills in an array descriptor, and returns the size of the array. The size
+ will be a simple_val, ie a variable or a constant. Also calculates the
+ offset of the base. Returns the size of the arrary.
+ {
+ stride = 1;
+ offset = 0;
+ for (n = 0; n < rank; n++)
+ {
+ a.lbound[n] = specified_lower_bound;
+ offset = offset + a.lbond[n] * stride;
+ size = 1 - lbound;
+ a.ubound[n] = specified_upper_bound;
+ a.stride[n] = stride;
+ size = ubound + size; //size = ubound + 1 - lbound
+ stride = stride * size;
+ }
+ return (stride);
+ } */
+/*GCC ARRAYS*/
+
+static tree
+gfc_array_init_size (tree descriptor, int rank, tree * poffset,
+ gfc_expr ** lower, gfc_expr ** upper,
+ stmtblock_t * pblock)
+{
+ tree type;
+ tree tmp;
+ tree size;
+ tree offset;
+ tree stride;
+ gfc_expr *ubound;
+ gfc_se se;
+ int n;
+
+ type = TREE_TYPE (descriptor);
+
+ stride = integer_one_node;
+ offset = integer_zero_node;
+
+ /* Set the dtype. */
+ tmp = gfc_conv_descriptor_dtype (descriptor);
+ gfc_add_modify_expr (pblock, tmp,
+ GFC_TYPE_ARRAY_DTYPE (TREE_TYPE (descriptor)));
+
+ for (n = 0; n < rank; n++)
+ {
+ /* We have 3 possibilities for determining the size of the array:
+ lower == NULL => lbound = 1, ubound = upper[n]
+ upper[n] = NULL => lbound = 1, ubound = lower[n]
+ upper[n] != NULL => lbound = lower[n], ubound = upper[n] */
+ ubound = upper[n];
+
+ /* Set lower bound. */
+ gfc_init_se (&se, NULL);
+ if (lower == NULL)
+ se.expr = integer_one_node;
+ else
+ {
+ assert (lower[n]);
+ if (ubound)
+ {
+ gfc_conv_expr_type (&se, lower[n], gfc_array_index_type);
+ gfc_add_block_to_block (pblock, &se.pre);
+ }
+ else
+ {
+ se.expr = integer_one_node;
+ ubound = lower[n];
+ }
+ }
+ tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[n]);
+ gfc_add_modify_expr (pblock, tmp, se.expr);
+
+ /* Work out the offset for this component. */
+ tmp = fold (build (MULT_EXPR, gfc_array_index_type, se.expr, stride));
+ offset = fold (build (MINUS_EXPR, gfc_array_index_type, offset, tmp));
+
+ /* Start the calculation for the size of this dimension. */
+ size = build (MINUS_EXPR, gfc_array_index_type,
+ integer_one_node, se.expr);
+
+ /* Set upper bound. */
+ gfc_init_se (&se, NULL);
+ assert (ubound);
+ gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
+ gfc_add_block_to_block (pblock, &se.pre);
+
+ tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[n]);
+ gfc_add_modify_expr (pblock, tmp, se.expr);
+
+ /* Store the stride. */
+ tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[n]);
+ gfc_add_modify_expr (pblock, tmp, stride);
+
+ /* Calculate the size of this dimension. */
+ size = fold (build (PLUS_EXPR, gfc_array_index_type, se.expr, size));
+
+ /* Multiply the stride by the number of elements in this dimension. */
+ stride = fold (build (MULT_EXPR, gfc_array_index_type, stride, size));
+ stride = gfc_evaluate_now (stride, pblock);
+ }
+
+ /* The stride is the number of elements in the array, so multiply by the
+ size of an element to get the total size. */
+ tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
+ size = fold (build (MULT_EXPR, gfc_array_index_type, stride, tmp));
+
+ if (poffset != NULL)
+ {
+ offset = gfc_evaluate_now (offset, pblock);
+ *poffset = offset;
+ }
+
+ size = gfc_evaluate_now (size, pblock);
+ return size;
+}
+
+
+/* Initialises the descriptor and generates a call to _gfor_allocate. Does
+ the work for an ALLOCATE statement. */
+/*GCC ARRAYS*/
+
+void
+gfc_array_allocate (gfc_se * se, gfc_ref * ref, tree pstat)
+{
+ tree tmp;
+ tree pointer;
+ tree allocate;
+ tree offset;
+ tree size;
+ gfc_expr **lower;
+ gfc_expr **upper;
+
+ /* Figure out the size of the array. */
+ switch (ref->u.ar.type)
+ {
+ case AR_ELEMENT:
+ lower = NULL;
+ upper = ref->u.ar.start;
+ break;
+
+ case AR_FULL:
+ assert (ref->u.ar.as->type == AS_EXPLICIT);
+
+ lower = ref->u.ar.as->lower;
+ upper = ref->u.ar.as->upper;
+ break;
+
+ case AR_SECTION:
+ lower = ref->u.ar.start;
+ upper = ref->u.ar.end;
+ break;
+
+ default:
+ abort ();
+ break;
+ }
+
+ size = gfc_array_init_size (se->expr, ref->u.ar.as->rank, &offset,
+ lower, upper, &se->pre);
+
+ /* Allocate memory to store the data. */
+ tmp = gfc_conv_descriptor_data (se->expr);
+ pointer = gfc_build_addr_expr (NULL, tmp);
+ pointer = gfc_evaluate_now (pointer, &se->pre);
+
+ if (gfc_array_index_type == gfc_int4_type_node)
+ allocate = gfor_fndecl_allocate;
+ else if (gfc_array_index_type == gfc_int8_type_node)
+ allocate = gfor_fndecl_allocate64;
+ else
+ abort ();
+
+ tmp = gfc_chainon_list (NULL_TREE, pointer);
+ tmp = gfc_chainon_list (tmp, size);
+ tmp = gfc_chainon_list (tmp, pstat);
+ tmp = gfc_build_function_call (allocate, tmp);
+ gfc_add_expr_to_block (&se->pre, tmp);
+
+ pointer = gfc_conv_descriptor_data (se->expr);
+
+ tmp = gfc_conv_descriptor_offset (se->expr);
+ gfc_add_modify_expr (&se->pre, tmp, offset);
+}
+
+
+/* Deallocate an array variable. Also used when an allocated variable goes
+ out of scope. */
+/*GCC ARRAYS*/
+
+tree
+gfc_array_deallocate (tree descriptor)
+{
+ tree var;
+ tree tmp;
+ stmtblock_t block;
+
+ gfc_start_block (&block);
+ /* Get a pointer to the data. */
+ tmp = gfc_conv_descriptor_data (descriptor);
+ tmp = gfc_build_addr_expr (NULL, tmp);
+ var = gfc_create_var (TREE_TYPE (tmp), "ptr");
+ gfc_add_modify_expr (&block, var, tmp);
+
+ /* Parameter is the address of the data component. */
+ tmp = gfc_chainon_list (NULL_TREE, var);
+ tmp = gfc_chainon_list (tmp, integer_zero_node);
+ tmp = gfc_build_function_call (gfor_fndecl_deallocate, tmp);
+ gfc_add_expr_to_block (&block, tmp);
+
+ return gfc_finish_block (&block);
+}
+
+
+/* Create an array constructor from an initialization expression.
+ We assume the frontend already did any expansions and conversions. */
+
+tree
+gfc_conv_array_initializer (tree type, gfc_expr * expr)
+{
+ gfc_constructor *c;
+ tree list;
+ tree tmp;
+ mpz_t maxval;
+ gfc_se se;
+ HOST_WIDE_INT hi;
+ unsigned HOST_WIDE_INT lo;
+ tree index, range;
+
+ list = NULL_TREE;
+ switch (expr->expr_type)
+ {
+ case EXPR_CONSTANT:
+ case EXPR_STRUCTURE:
+ /* A single scalar or derived type value. Create an array with all
+ elements equal to that value. */
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr (&se, expr);
+
+ tmp = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
+ assert (tmp && INTEGER_CST_P (tmp));
+ hi = TREE_INT_CST_HIGH (tmp);
+ lo = TREE_INT_CST_LOW (tmp);
+ lo++;
+ if (lo == 0)
+ hi++;
+ /* This will probably eat buckets of memory for large arrays. */
+ while (hi != 0 || lo != 0)
+ {
+ list = tree_cons (NULL_TREE, se.expr, list);
+ if (lo == 0)
+ hi--;
+ lo--;
+ }
+ break;
+
+ case EXPR_ARRAY:
+ /* Create a list of all the elements. */
+ for (c = expr->value.constructor; c; c = c->next)
+ {
+ if (c->iterator)
+ {
+ /* Problems occur when we get something like
+ integer :: a(lots) = (/(i, i=1,lots)/) */
+ /* TODO: Unexpanded array initializers. */
+ internal_error
+ ("Possible frontend bug: array constructor not expanded");
+ }
+ if (mpz_cmp_si (c->n.offset, 0) != 0)
+ index = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
+ else
+ index = NULL_TREE;
+ mpz_init (maxval);
+ if (mpz_cmp_si (c->repeat, 0) != 0)
+ {
+ tree tmp1, tmp2;
+
+ mpz_set (maxval, c->repeat);
+ mpz_add (maxval, c->n.offset, maxval);
+ mpz_sub_ui (maxval, maxval, 1);
+ tmp2 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
+ if (mpz_cmp_si (c->n.offset, 0) != 0)
+ {
+ mpz_add_ui (maxval, c->n.offset, 1);
+ tmp1 = gfc_conv_mpz_to_tree (maxval, gfc_index_integer_kind);
+ }
+ else
+ tmp1 = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
+
+ range = build (RANGE_EXPR, integer_type_node, tmp1, tmp2);
+ }
+ else
+ range = NULL;
+ mpz_clear (maxval);
+
+ gfc_init_se (&se, NULL);
+ switch (c->expr->expr_type)
+ {
+ case EXPR_CONSTANT:
+ gfc_conv_constant (&se, c->expr);
+ if (range == NULL_TREE)
+ list = tree_cons (index, se.expr, list);
+ else
+ {
+ if (index != NULL_TREE)
+ list = tree_cons (index, se.expr, list);
+ list = tree_cons (range, se.expr, list);
+ }
+ break;
+
+ case EXPR_STRUCTURE:
+ gfc_conv_structure (&se, c->expr, 1);
+ list = tree_cons (index, se.expr, list);
+ break;
+
+ default:
+ abort();
+ }
+ }
+ /* We created the list in reverse order. */
+ list = nreverse (list);
+ break;
+
+ default:
+ abort();
+ }
+
+ /* Create a constructor from the list of elements. */
+ tmp = build1 (CONSTRUCTOR, type, list);
+ TREE_CONSTANT (tmp) = 1;
+ TREE_INVARIANT (tmp) = 1;
+ return tmp;
+}
+
+
+/* Generate code to evaluate non-constant array bounds. Sets *poffset and
+ returns the size (in elements) of the array. */
+
+static tree
+gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
+ stmtblock_t * pblock)
+{
+ gfc_array_spec *as;
+ tree size;
+ tree stride;
+ tree offset;
+ tree ubound;
+ tree lbound;
+ tree tmp;
+ gfc_se se;
+
+ int dim;
+
+ as = sym->as;
+
+ size = integer_one_node;
+ offset = integer_zero_node;
+ for (dim = 0; dim < as->rank; dim++)
+ {
+ /* Evaluate non-constant array bound expressions. */
+ lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
+ if (as->lower[dim] && !INTEGER_CST_P (lbound))
+ {
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_type (&se, as->lower[dim], gfc_array_index_type);
+ gfc_add_block_to_block (pblock, &se.pre);
+ gfc_add_modify_expr (pblock, lbound, se.expr);
+ }
+ ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
+ if (as->upper[dim] && !INTEGER_CST_P (ubound))
+ {
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_type (&se, as->upper[dim], gfc_array_index_type);
+ gfc_add_block_to_block (pblock, &se.pre);
+ gfc_add_modify_expr (pblock, ubound, se.expr);
+ }
+ /* The offset of this dimension. offset = offset - lbound * stride. */
+ tmp = fold (build (MULT_EXPR, gfc_array_index_type, lbound, size));
+ offset = fold (build (MINUS_EXPR, gfc_array_index_type, offset, tmp));
+
+ /* The size of this dimension, and the stride of the next. */
+ if (dim + 1 < as->rank)
+ stride = GFC_TYPE_ARRAY_STRIDE (type, dim + 1);
+ else
+ stride = NULL_TREE;
+
+ if (ubound != NULL_TREE && !(stride && INTEGER_CST_P (stride)))
+ {
+ /* Calculate stride = size * (ubound + 1 - lbound). */
+ tmp = fold (build (MINUS_EXPR, gfc_array_index_type,
+ integer_one_node, lbound));
+ tmp = fold (build (PLUS_EXPR, gfc_array_index_type, ubound, tmp));
+ tmp = fold (build (MULT_EXPR, gfc_array_index_type, size, tmp));
+ if (stride)
+ gfc_add_modify_expr (pblock, stride, tmp);
+ else
+ stride = gfc_evaluate_now (tmp, pblock);
+ }
+
+ size = stride;
+ }
+
+ *poffset = offset;
+ return size;
+}
+
+
+/* Generate code to initialize/allocate an array variable. */
+
+tree
+gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, tree fnbody)
+{
+ stmtblock_t block;
+ tree type;
+ tree tmp;
+ tree fndecl;
+ tree size;
+ tree offset;
+ tree args;
+ bool onstack;
+
+ assert (!(sym->attr.pointer || sym->attr.allocatable));
+
+ /* Do nothing for USEd variables. */
+ if (sym->attr.use_assoc)
+ return fnbody;
+
+ type = TREE_TYPE (decl);
+ assert (GFC_ARRAY_TYPE_P (type));
+ onstack = TREE_CODE (type) != POINTER_TYPE;
+
+ /* We never generate initialization code of module variables. */
+ if (fnbody == NULL_TREE)
+ {
+ assert (onstack);
+
+ /* Generate static initializer. */
+ if (sym->value)
+ {
+ DECL_INITIAL (decl) =
+ gfc_conv_array_initializer (TREE_TYPE (decl), sym->value);
+ }
+ return fnbody;
+ }
+
+ gfc_start_block (&block);
+
+ /* Evaluate character string length. */
+ if (sym->ts.type == BT_CHARACTER
+ && onstack && !INTEGER_CST_P (sym->ts.cl->backend_decl))
+ {
+ gfc_trans_init_string_length (sym->ts.cl, &block);
+
+ DECL_DEFER_OUTPUT (decl) = 1;
+
+ /* Generate code to allocate the automatic variable. It will be
+ freed automatically. */
+ tmp = gfc_build_addr_expr (NULL, decl);
+ args = gfc_chainon_list (NULL_TREE, tmp);
+ args = gfc_chainon_list (args, sym->ts.cl->backend_decl);
+ tmp = gfc_build_function_call (built_in_decls[BUILT_IN_STACK_ALLOC],
+ args);
+ gfc_add_expr_to_block (&block, tmp);
+ }
+
+ if (onstack)
+ {
+ if (sym->value)
+ {
+ DECL_INITIAL (decl) =
+ gfc_conv_array_initializer (TREE_TYPE (decl), sym->value);
+ }
+
+ gfc_add_expr_to_block (&block, fnbody);
+ return gfc_finish_block (&block);
+ }
+
+ type = TREE_TYPE (type);
+
+ assert (!sym->attr.use_assoc);
+ assert (!TREE_STATIC (decl));
+ assert (!sym->module[0]);
+
+ if (sym->ts.type == BT_CHARACTER
+ && !INTEGER_CST_P (sym->ts.cl->backend_decl))
+ gfc_trans_init_string_length (sym->ts.cl, &block);
+
+ size = gfc_trans_array_bounds (type, sym, &offset, &block);
+
+ /* The size is the number of elements in the array, so multiply by the
+ size of an element to get the total size. */
+ tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
+ size = fold (build (MULT_EXPR, gfc_array_index_type, size, tmp));
+
+ /* Allocate memory to hold the data. */
+ tmp = gfc_chainon_list (NULL_TREE, size);
+
+ if (gfc_index_integer_kind == 4)
+ fndecl = gfor_fndecl_internal_malloc;
+ else if (gfc_index_integer_kind == 8)
+ fndecl = gfor_fndecl_internal_malloc64;
+ else
+ abort ();
+ tmp = gfc_build_function_call (fndecl, tmp);
+ tmp = fold (convert (TREE_TYPE (decl), tmp));
+ gfc_add_modify_expr (&block, decl, tmp);
+
+ /* Set offset of the array. */
+ if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
+ gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
+
+
+ /* Automatic arrays should not have initializers. */
+ assert (!sym->value);
+
+ gfc_add_expr_to_block (&block, fnbody);
+
+ /* Free the temporary. */
+ tmp = convert (pvoid_type_node, decl);
+ tmp = gfc_chainon_list (NULL_TREE, tmp);
+ tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
+ gfc_add_expr_to_block (&block, tmp);
+
+ return gfc_finish_block (&block);
+}
+
+
+/* Generate entry and exit code for g77 calling convention arrays. */
+
+tree
+gfc_trans_g77_array (gfc_symbol * sym, tree body)
+{
+ tree parm;
+ tree type;
+ locus loc;
+ tree offset;
+ tree tmp;
+ stmtblock_t block;
+
+ gfc_get_backend_locus (&loc);
+ gfc_set_backend_locus (&sym->declared_at);
+
+ /* Descriptor type. */
+ parm = sym->backend_decl;
+ type = TREE_TYPE (parm);
+ assert (GFC_ARRAY_TYPE_P (type));
+
+ gfc_start_block (&block);
+
+ if (sym->ts.type == BT_CHARACTER
+ && !INTEGER_CST_P (sym->ts.cl->backend_decl))
+ gfc_trans_init_string_length (sym->ts.cl, &block);
+
+ /* Evaluate the bounds of the array. */
+ gfc_trans_array_bounds (type, sym, &offset, &block);
+
+ /* Set the offset. */
+ if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
+ gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
+
+ /* Set the pointer itself if we aren't using the parameter dirtectly. */
+ if (TREE_CODE (parm) != PARM_DECL)
+ {
+ tmp = convert (TREE_TYPE (parm), GFC_DECL_SAVED_DESCRIPTOR (parm));
+ gfc_add_modify_expr (&block, parm, tmp);
+ }
+ tmp = gfc_finish_block (&block);
+
+ gfc_set_backend_locus (&loc);
+
+ gfc_start_block (&block);
+ /* Add the initialization code to the start of the function. */
+ gfc_add_expr_to_block (&block, tmp);
+ gfc_add_expr_to_block (&block, body);
+
+ return gfc_finish_block (&block);
+}
+
+
+/* Modify the descriptor of an array parameter so that it has the
+ correct lower bound. Also move the upper bound accordingly.
+ If the array is not packed, it will be copied into a temporary.
+ For each dimension we set the new lower and upper bounds. Then we copy the
+ stride and calculate the offset for this dimension. We also work out
+ what the stride of a packed array would be, and see it the two match.
+ If the array need repacking, we set the stride to the values we just
+ calculated, recalculate the offset and copy the array data.
+ Code is also added to copy the data back at the end of the function.
+ */
+
+tree
+gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
+{
+ tree size;
+ tree type;
+ tree offset;
+ locus loc;
+ stmtblock_t block;
+ stmtblock_t cleanup;
+ tree lbound;
+ tree ubound;
+ tree dubound;
+ tree dlbound;
+ tree dumdesc;
+ tree tmp;
+ tree stmt;
+ tree stride;
+ tree stmt_packed;
+ tree stmt_unpacked;
+ tree partial;
+ gfc_se se;
+ int n;
+ int checkparm;
+ int no_repack;
+
+ if (sym->attr.dummy && gfc_is_nodesc_array (sym))
+ return gfc_trans_g77_array (sym, body);
+
+ gfc_get_backend_locus (&loc);
+ gfc_set_backend_locus (&sym->declared_at);
+
+ /* Descriptor type. */
+ type = TREE_TYPE (tmpdesc);
+ assert (GFC_ARRAY_TYPE_P (type));
+ dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
+ dumdesc = gfc_build_indirect_ref (dumdesc);
+ gfc_start_block (&block);
+
+ if (sym->ts.type == BT_CHARACTER
+ && !INTEGER_CST_P (sym->ts.cl->backend_decl))
+ gfc_trans_init_string_length (sym->ts.cl, &block);
+
+ checkparm = (sym->as->type == AS_EXPLICIT && flag_bounds_check);
+
+ no_repack = !(GFC_DECL_PACKED_ARRAY (tmpdesc)
+ || GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc));
+
+ if (GFC_DECL_PARTIAL_PACKED_ARRAY (tmpdesc))
+ {
+ /* For non-constant shape arrays we only check if the first dimension
+ is contiguous. Repacking higher dimensions wouldn't gain us
+ anything as we still don't know the array stride. */
+ partial = gfc_create_var (boolean_type_node, "partial");
+ TREE_USED (partial) = 1;
+ tmp = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
+ tmp = fold (build (EQ_EXPR, boolean_type_node, tmp, integer_one_node));
+ gfc_add_modify_expr (&block, partial, tmp);
+ }
+ else
+ {
+ partial = NULL_TREE;
+ }
+
+ /* The naming of stmt_unpacked and stmt_packed may be counter-intuitive
+ here, however I think it does the right thing. */
+ if (no_repack)
+ {
+ /* Set the first stride. */
+ stride = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
+ stride = gfc_evaluate_now (stride, &block);
+
+ tmp = build (EQ_EXPR, boolean_type_node, stride, integer_zero_node);
+ tmp = build (COND_EXPR, gfc_array_index_type, tmp,
+ integer_one_node, stride);
+ stride = GFC_TYPE_ARRAY_STRIDE (type, 0);
+ gfc_add_modify_expr (&block, stride, tmp);
+
+ /* Allow the user to disable array repacking. */
+ stmt_unpacked = NULL_TREE;
+ }
+ else
+ {
+ assert (integer_onep (GFC_TYPE_ARRAY_STRIDE (type, 0)));
+ /* A library call to repack the array if neccessary. */
+ tmp = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
+ tmp = gfc_chainon_list (NULL_TREE, tmp);
+ stmt_unpacked = gfc_build_function_call (gfor_fndecl_in_pack, tmp);
+
+ stride = integer_one_node;
+ }
+
+ /* This is for the case where the array data is used directly without
+ calling the repack function. */
+ if (no_repack || partial != NULL_TREE)
+ stmt_packed = gfc_conv_descriptor_data (dumdesc);
+ else
+ stmt_packed = NULL_TREE;
+
+ /* Assign the data pointer. */
+ if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
+ {
+ /* Don't repack unknown shape arrays when the first stride is 1. */
+ tmp = build (COND_EXPR, TREE_TYPE (stmt_packed), partial,
+ stmt_packed, stmt_unpacked);
+ }
+ else
+ tmp = stmt_packed != NULL_TREE ? stmt_packed : stmt_unpacked;
+ gfc_add_modify_expr (&block, tmpdesc, tmp);
+
+ offset = integer_zero_node;
+ size = integer_one_node;
+
+ /* Evaluate the bounds of the array. */
+ for (n = 0; n < sym->as->rank; n++)
+ {
+ if (checkparm || !sym->as->upper[n])
+ {
+ /* Get the bounds of the actual parameter. */
+ dubound = gfc_conv_descriptor_ubound (dumdesc, gfc_rank_cst[n]);
+ dlbound = gfc_conv_descriptor_lbound (dumdesc, gfc_rank_cst[n]);
+ }
+ else
+ {
+ dubound = NULL_TREE;
+ dlbound = NULL_TREE;
+ }
+
+ lbound = GFC_TYPE_ARRAY_LBOUND (type, n);
+ if (!INTEGER_CST_P (lbound))
+ {
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_type (&se, sym->as->upper[n],
+ gfc_array_index_type);
+ gfc_add_block_to_block (&block, &se.pre);
+ gfc_add_modify_expr (&block, lbound, se.expr);
+ }
+
+ ubound = GFC_TYPE_ARRAY_UBOUND (type, n);
+ /* Set the desired upper bound. */
+ if (sym->as->upper[n])
+ {
+ /* We know what we want the upper bound to be. */
+ if (!INTEGER_CST_P (ubound))
+ {
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_type (&se, sym->as->upper[n],
+ gfc_array_index_type);
+ gfc_add_block_to_block (&block, &se.pre);
+ gfc_add_modify_expr (&block, ubound, se.expr);
+ }
+
+ /* Check the sizes match. */
+ if (checkparm)
+ {
+ /* Check (ubound(a) - lbound(a) == ubound(b) - lbound(b)). */
+
+ tmp = fold (build (MINUS_EXPR, gfc_array_index_type, ubound,
+ lbound));
+ stride = build (MINUS_EXPR, gfc_array_index_type, dubound,
+ dlbound);
+ tmp = fold (build (NE_EXPR, gfc_array_index_type, tmp, stride));
+ gfc_trans_runtime_check (tmp, gfc_strconst_bounds, &block);
+ }
+ }
+ else
+ {
+ /* For assumed shape arrays move the upper bound by the same amount
+ as the lower bound. */
+ tmp = build (MINUS_EXPR, gfc_array_index_type, dubound, dlbound);
+ tmp = fold (build (PLUS_EXPR, gfc_array_index_type, tmp, lbound));
+ gfc_add_modify_expr (&block, ubound, tmp);
+ }
+ /* The offset of this dimension. offset = offset - lbound * stride. */
+ tmp = fold (build (MULT_EXPR, gfc_array_index_type, lbound, stride));
+ offset = fold (build (MINUS_EXPR, gfc_array_index_type, offset, tmp));
+
+ /* The size of this dimension, and the stride of the next. */
+ if (n + 1 < sym->as->rank)
+ {
+ stride = GFC_TYPE_ARRAY_STRIDE (type, n + 1);
+
+ if (no_repack || partial != NULL_TREE)
+ {
+ stmt_unpacked =
+ gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[n+1]);
+ }
+
+ /* Figure out the stride if not a known constant. */
+ if (!INTEGER_CST_P (stride))
+ {
+ if (no_repack)
+ stmt_packed = NULL_TREE;
+ else
+ {
+ /* Calculate stride = size * (ubound + 1 - lbound). */
+ tmp = fold (build (MINUS_EXPR, gfc_array_index_type,
+ integer_one_node, lbound));
+ tmp = fold (build (PLUS_EXPR, gfc_array_index_type,
+ ubound, tmp));
+ size = fold (build (MULT_EXPR, gfc_array_index_type,
+ size, tmp));
+ stmt_packed = size;
+ }
+
+ /* Assign the stride. */
+ if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE)
+ {
+ tmp = build (COND_EXPR, gfc_array_index_type, partial,
+ stmt_unpacked, stmt_packed);
+ }
+ else
+ tmp = (stmt_packed != NULL_TREE) ? stmt_packed : stmt_unpacked;
+ gfc_add_modify_expr (&block, stride, tmp);
+ }
+ }
+ }
+
+ /* Set the offset. */
+ if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
+ gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
+
+ stmt = gfc_finish_block (&block);
+
+ gfc_start_block (&block);
+
+ /* Only do the entry/initialization code if the arg is present. */
+ dumdesc = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc);
+ if (sym->attr.optional)
+ {
+ tmp = gfc_conv_expr_present (sym);
+ stmt = build_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
+ }
+ gfc_add_expr_to_block (&block, stmt);
+
+ /* Add the main function body. */
+ gfc_add_expr_to_block (&block, body);
+
+ /* Cleanup code. */
+ if (!no_repack)
+ {
+ gfc_start_block (&cleanup);
+
+ if (sym->attr.intent != INTENT_IN)
+ {
+ /* Copy the data back. */
+ tmp = gfc_chainon_list (NULL_TREE, dumdesc);
+ tmp = gfc_chainon_list (tmp, tmpdesc);
+ tmp = gfc_build_function_call (gfor_fndecl_in_unpack, tmp);
+ gfc_add_expr_to_block (&cleanup, tmp);
+ }
+
+ /* Free the temporary. */
+ tmp = gfc_chainon_list (NULL_TREE, tmpdesc);
+ tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
+ gfc_add_expr_to_block (&cleanup, tmp);
+
+ stmt = gfc_finish_block (&cleanup);
+
+ /* Only do the cleanup if the array was repacked. */
+ tmp = gfc_build_indirect_ref (dumdesc);
+ tmp = gfc_conv_descriptor_data (tmp);
+ tmp = build (NE_EXPR, boolean_type_node, tmp, tmpdesc);
+ stmt = build_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
+
+ if (sym->attr.optional)
+ {
+ tmp = gfc_conv_expr_present (sym);
+ stmt = build_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
+ }
+ gfc_add_expr_to_block (&block, stmt);
+ }
+ /* We don't need to free any memory allocated by internal_pack as it will
+ be freed at the end of the function by pop_context. */
+ return gfc_finish_block (&block);
+}
+
+
+/* Convert an array for passing as an actual parameter. Expressions
+ and vector subscripts are evaluated and stored in a teporary, which is then
+ passed. For whole arrays the descriptor is passed. For array sections
+ a modified copy of the descriptor is passed, but using the original data.
+ Also used for array pointer assignments by setting se->direct_byref. */
+
+void
+gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
+{
+ gfc_loopinfo loop;
+ gfc_ss *secss;
+ gfc_ss_info *info;
+ int need_tmp;
+ int n;
+ tree tmp;
+ tree desc;
+ stmtblock_t block;
+ tree start;
+ tree offset;
+ int full;
+
+ assert (ss != gfc_ss_terminator);
+
+ /* TODO: Pass constant array constructors without a temporary. */
+ /* If we have a linear array section, we can pass it directly. Otherwise
+ we need to copy it into a temporary. */
+ if (expr->expr_type == EXPR_VARIABLE)
+ {
+ gfc_ss *vss;
+
+ /* Find the SS for the array section. */
+ secss = ss;
+ while (secss != gfc_ss_terminator && secss->type != GFC_SS_SECTION)
+ secss = secss->next;
+
+ assert (secss != gfc_ss_terminator);
+
+ need_tmp = 0;
+ for (n = 0; n < secss->data.info.dimen; n++)
+ {
+ vss = secss->data.info.subscript[secss->data.info.dim[n]];
+ if (vss && vss->type == GFC_SS_VECTOR)
+ need_tmp = 1;
+ }
+
+ info = &secss->data.info;
+
+ /* Get the descriptor for the array. */
+ gfc_conv_ss_descriptor (&se->pre, secss, 0);
+ desc = info->descriptor;
+ if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
+ {
+ /* Create a new descriptor if the array doesn't have one. */
+ full = 0;
+ }
+ else if (info->ref->u.ar.type == AR_FULL)
+ full = 1;
+ else if (se->direct_byref)
+ full = 0;
+ else
+ {
+ assert (info->ref->u.ar.type == AR_SECTION);
+
+ full = 1;
+ for (n = 0; n < info->ref->u.ar.dimen; n++)
+ {
+ /* Detect passing the full array as a section. This could do
+ even more checking, but it doesn't seem worth it. */
+ if (info->ref->u.ar.start[n]
+ || info->ref->u.ar.end[n]
+ || (info->ref->u.ar.stride[n]
+ && !gfc_expr_is_one (info->ref->u.ar.stride[n], 0)))
+ {
+ full = 0;
+ break;
+ }
+ }
+ }
+ if (full)
+ {
+ if (se->direct_byref)
+ {
+ /* Copy the descriptor for pointer assignments. */
+ gfc_add_modify_expr (&se->pre, se->expr, desc);
+ }
+ else if (se->want_pointer)
+ {
+ /* We pass full arrays directly. This means that pointers and
+ allocatable arrays should also work. */
+ se->expr = gfc_build_addr_expr (NULL, desc);
+ }
+ else
+ {
+ se->expr = desc;
+ }
+ return;
+ }
+ }
+ else
+ {
+ need_tmp = 1;
+ secss = NULL;
+ info = NULL;
+ }
+
+ gfc_init_loopinfo (&loop);
+
+ /* Associate the SS with the loop. */
+ gfc_add_ss_to_loop (&loop, ss);
+
+ /* Tell the scalarizer not to bother creating loop varliables, etc. */
+ if (!need_tmp)
+ loop.array_parameter = 1;
+ else
+ assert (se->want_pointer && !se->direct_byref);
+
+ /* Setup the scalarizing loops and bounds. */
+ gfc_conv_ss_startstride (&loop);
+
+ if (need_tmp)
+ {
+ /* Tell the scalarizer to make a temporary. */
+ loop.temp_ss = gfc_get_ss ();
+ loop.temp_ss->type = GFC_SS_TEMP;
+ loop.temp_ss->next = gfc_ss_terminator;
+ loop.temp_ss->data.temp.type = gfc_typenode_for_spec (&expr->ts);
+ loop.temp_ss->data.temp.string_length = NULL;
+ loop.temp_ss->data.temp.dimen = loop.dimen;
+ gfc_add_ss_to_loop (&loop, loop.temp_ss);
+ }
+
+ gfc_conv_loop_setup (&loop);
+
+ if (need_tmp)
+ {
+ /* Copy into a temporary and pass that. We don't need to copy the data
+ back because expressions and vector subscripts must be INTENT_IN. */
+ /* TODO: Optimize passing function return values. */
+ gfc_se lse;
+ gfc_se rse;
+
+ /* Start the copying loops. */
+ gfc_mark_ss_chain_used (loop.temp_ss, 1);
+ gfc_mark_ss_chain_used (ss, 1);
+ gfc_start_scalarized_body (&loop, &block);
+
+ /* Copy each data element. */
+ gfc_init_se (&lse, NULL);
+ gfc_copy_loopinfo_to_se (&lse, &loop);
+ gfc_init_se (&rse, NULL);
+ gfc_copy_loopinfo_to_se (&rse, &loop);
+
+ lse.ss = loop.temp_ss;
+ rse.ss = ss;
+
+ gfc_conv_scalarized_array_ref (&lse, NULL);
+ gfc_conv_expr_val (&rse, expr);
+
+ gfc_add_block_to_block (&block, &rse.pre);
+ gfc_add_block_to_block (&block, &lse.pre);
+
+ gfc_add_modify_expr (&block, lse.expr, rse.expr);
+
+ /* Finish the copying loops. */
+ gfc_trans_scalarizing_loops (&loop, &block);
+
+ /* Set the first stride component to zero to indicate a temporary. */
+ desc = loop.temp_ss->data.info.descriptor;
+ tmp = gfc_conv_descriptor_stride (desc, gfc_rank_cst[0]);
+ gfc_add_modify_expr (&loop.pre, tmp, integer_zero_node);
+
+ assert (is_gimple_lvalue (desc));
+ se->expr = gfc_build_addr_expr (NULL, desc);
+ }
+ else
+ {
+ /* We pass sections without copying to a temporary. A function may
+ decide to repack the array to speed up access, but we're not
+ bothered about that here. */
+ int dim;
+ tree parm;
+ tree parmtype;
+ tree stride;
+ tree from;
+ tree to;
+ tree base;
+
+ /* Otherwise make a new descriptor and point it at the section we
+ want. The loop variable limits will be the limits of the section.
+ */
+ desc = info->descriptor;
+ assert (secss && secss != gfc_ss_terminator);
+ if (se->direct_byref)
+ {
+ /* For pointer assignments we fill in the destination. */
+ parm = se->expr;
+ parmtype = TREE_TYPE (parm);
+ }
+ else
+ {
+ /* Otherwise make a new one. */
+ parmtype = gfc_get_element_type (TREE_TYPE (desc));
+ parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen,
+ loop.from, loop.to, 0);
+ parm = gfc_create_var (parmtype, "parm");
+ }
+
+ offset = integer_zero_node;
+ dim = 0;
+
+ /* The following can be somewhat confusing. We have two
+ descriptors, a new one and the original array.
+ {parm, parmtype, dim} refer to the new one.
+ {desc, type, n, secss, loop} refer to the original, which maybe
+ a descriptorless array.
+ The bounds of the scaralization are the bounds of the section.
+ We don't have to worry about numeric overflows when calculating
+ the offsets because all elements are within the array data. */
+
+ /* Set the dtype. */
+ tmp = gfc_conv_descriptor_dtype (parm);
+ gfc_add_modify_expr (&loop.pre, tmp, GFC_TYPE_ARRAY_DTYPE (parmtype));
+
+ if (se->direct_byref)
+ base = integer_zero_node;
+ else
+ base = NULL_TREE;
+
+ for (n = 0; n < info->ref->u.ar.dimen; n++)
+ {
+ stride = gfc_conv_array_stride (desc, n);
+
+ /* Work out the offset. */
+ if (info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
+ {
+ assert (info->subscript[n]
+ && info->subscript[n]->type == GFC_SS_SCALAR);
+ start = info->subscript[n]->data.scalar.expr;
+ }
+ else
+ {
+ /* Check we haven't somehow got out of sync. */
+ assert (info->dim[dim] == n);
+
+ /* Evaluate and remember the start of the section. */
+ start = info->start[dim];
+ stride = gfc_evaluate_now (stride, &loop.pre);
+ }
+
+ tmp = gfc_conv_array_lbound (desc, n);
+ tmp = fold (build (MINUS_EXPR, TREE_TYPE (tmp), start, tmp));
+
+ tmp = fold (build (MULT_EXPR, TREE_TYPE (tmp), tmp, stride));
+ offset = fold (build (PLUS_EXPR, TREE_TYPE (tmp), offset, tmp));
+
+ if (info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
+ {
+ /* For elemental dimensions, we only need the offset. */
+ continue;
+ }
+
+ /* Vector subscripts need copying and are handled elsewhere. */
+ assert (info->ref->u.ar.dimen_type[n] == DIMEN_RANGE);
+
+ /* Set the new lower bound. */
+ from = loop.from[dim];
+ to = loop.to[dim];
+ if (!integer_onep (from))
+ {
+ /* Make sure the new section starts at 1. */
+ tmp = fold (build (MINUS_EXPR, TREE_TYPE (from),
+ integer_one_node, from));
+ to = fold (build (PLUS_EXPR, TREE_TYPE (to), to, tmp));
+ from = integer_one_node;
+ }
+ tmp = gfc_conv_descriptor_lbound (parm, gfc_rank_cst[dim]);
+ gfc_add_modify_expr (&loop.pre, tmp, from);
+
+ /* Set the new upper bound. */
+ tmp = gfc_conv_descriptor_ubound (parm, gfc_rank_cst[dim]);
+ gfc_add_modify_expr (&loop.pre, tmp, to);
+
+ /* Multiply the stride by the section stride to get the
+ total stride. */
+ stride = fold (build (MULT_EXPR, gfc_array_index_type, stride,
+ info->stride[dim]));
+
+ if (se->direct_byref)
+ {
+ base = fold (build (MINUS_EXPR, TREE_TYPE (base),
+ base, stride));
+ }
+
+ /* Store the new stride. */
+ tmp = gfc_conv_descriptor_stride (parm, gfc_rank_cst[dim]);
+ gfc_add_modify_expr (&loop.pre, tmp, stride);
+
+ dim++;
+ }
+
+ /* Point the data pointer at the first element in the section. */
+ tmp = gfc_conv_array_data (desc);
+ tmp = gfc_build_indirect_ref (tmp);
+ tmp = gfc_build_array_ref (tmp, offset);
+ offset = gfc_build_addr_expr (gfc_array_dataptr_type (desc), tmp);
+
+ tmp = gfc_conv_descriptor_data (parm);
+ gfc_add_modify_expr (&loop.pre, tmp, offset);
+
+ if (se->direct_byref)
+ {
+ /* Set the offset. */
+ tmp = gfc_conv_descriptor_offset (parm);
+ gfc_add_modify_expr (&loop.pre, tmp, base);
+ }
+ else
+ {
+ /* Only the callee knows what the correct offset it, so just set
+ it to zero here. */
+ tmp = gfc_conv_descriptor_offset (parm);
+ gfc_add_modify_expr (&loop.pre, tmp, gfc_index_zero_node);
+ }
+
+ if (!se->direct_byref)
+ {
+ /* Get a pointer to the new descriptor. */
+ if (se->want_pointer)
+ se->expr = gfc_build_addr_expr (NULL, parm);
+ else
+ se->expr = parm;
+ }
+ }
+
+ gfc_add_block_to_block (&se->pre, &loop.pre);
+ gfc_add_block_to_block (&se->post, &loop.post);
+
+ /* Cleanup the scalarizer. */
+ gfc_cleanup_loop (&loop);
+}
+
+
+/* Convert an array for passing as an actual parameter. */
+/* TODO: Optimize passing g77 arrays. */
+
+void
+gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77)
+{
+ tree ptr;
+ tree desc;
+ tree tmp;
+ tree stmt;
+ gfc_symbol *sym;
+ stmtblock_t block;
+
+ /* Passing address of the array if it is not pointer or assumed-shape. */
+ if (expr->expr_type == EXPR_VARIABLE
+ && expr->ref->u.ar.type == AR_FULL && g77)
+ {
+ sym = expr->symtree->n.sym;
+ tmp = gfc_get_symbol_decl (sym);
+ if (!sym->attr.pointer && sym->as->type != AS_ASSUMED_SHAPE
+ && !sym->attr.allocatable)
+ {
+ if (!sym->attr.dummy)
+ se->expr = gfc_build_addr_expr (NULL, tmp);
+ else
+ se->expr = tmp;
+ return;
+ }
+ if (sym->attr.allocatable)
+ {
+ se->expr = gfc_conv_array_data (tmp);
+ return;
+ }
+ }
+
+ se->want_pointer = 1;
+ gfc_conv_expr_descriptor (se, expr, ss);
+
+ if (g77)
+ {
+ desc = se->expr;
+ /* Repack the array. */
+ tmp = gfc_chainon_list (NULL_TREE, desc);
+ ptr = gfc_build_function_call (gfor_fndecl_in_pack, tmp);
+ ptr = gfc_evaluate_now (ptr, &se->pre);
+ se->expr = ptr;
+
+ gfc_start_block (&block);
+
+ /* Copy the data back. */
+ tmp = gfc_chainon_list (NULL_TREE, desc);
+ tmp = gfc_chainon_list (tmp, ptr);
+ tmp = gfc_build_function_call (gfor_fndecl_in_unpack, tmp);
+ gfc_add_expr_to_block (&block, tmp);
+
+ /* Free the temporary. */
+ tmp = convert (pvoid_type_node, ptr);
+ tmp = gfc_chainon_list (NULL_TREE, tmp);
+ tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
+ gfc_add_expr_to_block (&block, tmp);
+
+ stmt = gfc_finish_block (&block);
+
+ gfc_init_block (&block);
+ /* Only if it was repacked. This code needs to be executed before the
+ loop cleanup code. */
+ tmp = gfc_build_indirect_ref (desc);
+ tmp = gfc_conv_array_data (tmp);
+ tmp = build (NE_EXPR, boolean_type_node, ptr, tmp);
+ tmp = build_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
+
+ gfc_add_expr_to_block (&block, tmp);
+ gfc_add_block_to_block (&block, &se->post);
+
+ gfc_init_block (&se->post);
+ gfc_add_block_to_block (&se->post, &block);
+ }
+}
+
+
+/* NULLIFY an allocated/pointer array on function entry, free it on exit. */
+
+tree
+gfc_trans_deferred_array (gfc_symbol * sym, tree body)
+{
+ tree type;
+ tree tmp;
+ tree descriptor;
+ tree deallocate;
+ stmtblock_t block;
+ stmtblock_t fnblock;
+ locus loc;
+
+ /* Make sure the frontend gets these right. */
+ if (!(sym->attr.pointer || sym->attr.allocatable))
+ fatal_error
+ ("Possible frontend bug: Deferred array size without pointer or allocatable attribute.");
+
+ gfc_init_block (&fnblock);
+
+ assert (TREE_CODE (sym->backend_decl) == VAR_DECL);
+ if (sym->ts.type == BT_CHARACTER
+ && !INTEGER_CST_P (sym->ts.cl->backend_decl))
+ gfc_trans_init_string_length (sym->ts.cl, &fnblock);
+
+ /* Parameter variables don't need anything special. */
+ if (sym->attr.dummy)
+ {
+ gfc_add_expr_to_block (&fnblock, body);
+
+ return gfc_finish_block (&fnblock);
+ }
+
+ gfc_get_backend_locus (&loc);
+ gfc_set_backend_locus (&sym->declared_at);
+ descriptor = sym->backend_decl;
+
+ if (TREE_STATIC (descriptor))
+ {
+ /* SAVEd variables are not freed on exit. */
+ gfc_trans_static_array_pointer (sym);
+ return body;
+ }
+
+ /* Get the descriptor type. */
+ type = TREE_TYPE (sym->backend_decl);
+ assert (GFC_DESCRIPTOR_TYPE_P (type));
+
+ /* NULLIFY the data pointer. */
+ tmp = gfc_conv_descriptor_data (descriptor);
+ gfc_add_modify_expr (&fnblock, tmp, integer_zero_node);
+
+ gfc_add_expr_to_block (&fnblock, body);
+
+ gfc_set_backend_locus (&loc);
+ /* Allocatable arrays need to be freed when they go out of scope. */
+ if (sym->attr.allocatable)
+ {
+ gfc_start_block (&block);
+
+ /* Deallocate if still allocated at the end of the procedure. */
+ deallocate = gfc_array_deallocate (descriptor);
+
+ tmp = gfc_conv_descriptor_data (descriptor);
+ tmp = build (NE_EXPR, boolean_type_node, tmp, integer_zero_node);
+ tmp = build_v (COND_EXPR, tmp, deallocate, build_empty_stmt ());
+ gfc_add_expr_to_block (&block, tmp);
+
+ tmp = gfc_finish_block (&block);
+ gfc_add_expr_to_block (&fnblock, tmp);
+ }
+
+ return gfc_finish_block (&fnblock);
+}
+
+/************ Expression Walking Functions ******************/
+
+/* Walk a variable reference.
+
+ Possible extension - multiple component subscripts.
+ x(:,:) = foo%a(:)%b(:)
+ Transforms to
+ forall (i=..., j=...)
+ x(i,j) = foo%a(j)%b(i)
+ end forall
+ This adds a fair amout of complexity because you need to deal with more
+ than one ref. Maybe handle in a similar manner to vector subscripts.
+ Maybe not worth the effort. */
+
+
+static gfc_ss *
+gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
+{
+ gfc_ref *ref;
+ gfc_array_ref *ar;
+ gfc_ss *newss;
+ gfc_ss *head;
+ int n;
+
+ for (ref = expr->ref; ref; ref = ref->next)
+ {
+ /* We're only interested in array sections. */
+ if (ref->type != REF_ARRAY)
+ continue;
+
+ ar = &ref->u.ar;
+ switch (ar->type)
+ {
+ case AR_ELEMENT:
+ /* TODO: Take elemental array references out of scalarization
+ loop. */
+ break;
+
+ case AR_FULL:
+ newss = gfc_get_ss ();
+ newss->type = GFC_SS_SECTION;
+ newss->expr = expr;
+ newss->next = ss;
+ newss->data.info.dimen = ar->as->rank;
+ newss->data.info.ref = ref;
+
+ /* Make sure array is the same as array(:,:), this way
+ we don't need to special case all the time. */
+ ar->dimen = ar->as->rank;
+ for (n = 0; n < ar->dimen; n++)
+ {
+ newss->data.info.dim[n] = n;
+ ar->dimen_type[n] = DIMEN_RANGE;
+
+ assert (ar->start[n] == NULL);
+ assert (ar->end[n] == NULL);
+ assert (ar->stride[n] == NULL);
+ }
+ return newss;
+
+ case AR_SECTION:
+ newss = gfc_get_ss ();
+ newss->type = GFC_SS_SECTION;
+ newss->expr = expr;
+ newss->next = ss;
+ newss->data.info.dimen = 0;
+ newss->data.info.ref = ref;
+
+ head = newss;
+
+ /* We add SS chains for all the subscripts in the section. */
+ for (n = 0; n < ar->dimen; n++)
+ {
+ gfc_ss *indexss;
+
+ switch (ar->dimen_type[n])
+ {
+ case DIMEN_ELEMENT:
+ /* Add SS for elemental (scalar) subscripts. */
+ assert (ar->start[n]);
+ indexss = gfc_get_ss ();
+ indexss->type = GFC_SS_SCALAR;
+ indexss->expr = ar->start[n];
+ indexss->next = gfc_ss_terminator;
+ indexss->loop_chain = gfc_ss_terminator;
+ newss->data.info.subscript[n] = indexss;
+ break;
+
+ case DIMEN_RANGE:
+ /* We don't add anything for sections, just remember this
+ dimension for later. */
+ newss->data.info.dim[newss->data.info.dimen] = n;
+ newss->data.info.dimen++;
+ break;
+
+ case DIMEN_VECTOR:
+ /* Get a SS for the vector. This will not be added to the
+ chain directly. */
+ indexss = gfc_walk_expr (ar->start[n]);
+ if (indexss == gfc_ss_terminator)
+ internal_error ("scalar vector subscript???");
+
+ /* We currently only handle really simple vector
+ subscripts. */
+ if (indexss->next != gfc_ss_terminator)
+ gfc_todo_error ("vector subscript expressions");
+ indexss->loop_chain = gfc_ss_terminator;
+
+ /* Mark this as a vector subscript. We don't add this
+ directly into the chain, but as a subscript of the
+ existing SS for this term. */
+ indexss->type = GFC_SS_VECTOR;
+ newss->data.info.subscript[n] = indexss;
+ /* Also remember this dimension. */
+ newss->data.info.dim[newss->data.info.dimen] = n;
+ newss->data.info.dimen++;
+ break;
+
+ default:
+ /* We should know what sort of section it is by now. */
+ abort ();
+ }
+ }
+ /* We should have at least one non-elemental dimension. */
+ assert (newss->data.info.dimen > 0);
+ return head;
+ break;
+
+ default:
+ /* We should know what sort of section it is by now. */
+ abort ();
+ }
+
+ }
+ return ss;
+}
+
+
+/* Walk an expression operator. If only one operand of a binary expression is
+ scalar, we must also add the scalar term to the SS chain. */
+
+static gfc_ss *
+gfc_walk_op_expr (gfc_ss * ss, gfc_expr * expr)
+{
+ gfc_ss *head;
+ gfc_ss *head2;
+ gfc_ss *newss;
+
+ head = gfc_walk_subexpr (ss, expr->op1);
+ if (expr->op2 == NULL)
+ head2 = head;
+ else
+ head2 = gfc_walk_subexpr (head, expr->op2);
+
+ /* All operands are scalar. Pass back and let the caller deal with it. */
+ if (head2 == ss)
+ return head2;
+
+ /* All operands require scalarization. */
+ if (head != ss && (expr->op2 == NULL || head2 != head))
+ return head2;
+
+ /* One of the operands needs scalarization, the other is scalar.
+ Create a gfc_ss for the scalar expression. */
+ newss = gfc_get_ss ();
+ newss->type = GFC_SS_SCALAR;
+ if (head == ss)
+ {
+ /* First operand is scalar. We build the chain in reverse order, so
+ add the scarar SS after the second operand. */
+ head = head2;
+ while (head && head->next != ss)
+ head = head->next;
+ /* Check we haven't somehow broken the chain. */
+ assert (head);
+ newss->next = ss;
+ head->next = newss;
+ newss->expr = expr->op1;
+ }
+ else /* head2 == head */
+ {
+ assert (head2 == head);
+ /* Second operand is scalar. */
+ newss->next = head2;
+ head2 = newss;
+ newss->expr = expr->op2;
+ }
+
+ return head2;
+}
+
+
+/* Reverse a SS chain. */
+
+static gfc_ss *
+gfc_reverse_ss (gfc_ss * ss)
+{
+ gfc_ss *next;
+ gfc_ss *head;
+
+ assert (ss != NULL);
+
+ head = gfc_ss_terminator;
+ while (ss != gfc_ss_terminator)
+ {
+ next = ss->next;
+ assert (next != NULL); /* Check we didn't somehow break the chain. */
+ ss->next = head;
+ head = ss;
+ ss = next;
+ }
+
+ return (head);
+}
+
+
+/* Walk the arguments of an elemental function. */
+
+gfc_ss *
+gfc_walk_elemental_function_args (gfc_ss * ss, gfc_expr * expr,
+ gfc_ss_type type)
+{
+ gfc_actual_arglist *arg;
+ int scalar;
+ gfc_ss *head;
+ gfc_ss *tail;
+ gfc_ss *newss;
+
+ head = gfc_ss_terminator;
+ tail = NULL;
+ scalar = 1;
+ for (arg = expr->value.function.actual; arg; arg = arg->next)
+ {
+ if (!arg->expr)
+ continue;
+
+ newss = gfc_walk_subexpr (head, arg->expr);
+ if (newss == head)
+ {
+ /* Scalar argumet. */
+ newss = gfc_get_ss ();
+ newss->type = type;
+ newss->expr = arg->expr;
+ newss->next = head;
+ }
+ else
+ scalar = 0;
+
+ head = newss;
+ if (!tail)
+ {
+ tail = head;
+ while (tail->next != gfc_ss_terminator)
+ tail = tail->next;
+ }
+ }
+
+ if (scalar)
+ {
+ /* If all the arguments are scalar we don't need the argument SS. */
+ gfc_free_ss_chain (head);
+ /* Pass it back. */
+ return ss;
+ }
+
+ /* Add it onto the existing chain. */
+ tail->next = ss;
+ return head;
+}
+
+
+/* Walk a function call. Scalar functions are passed back, and taken out of
+ scalarization loops. For elemental functions we walk their arguments.
+ The result of functions returning arrays is stored in a temporary outside
+ the loop, so that the function is only called once. Hence we do not need
+ to walk their arguments. */
+
+static gfc_ss *
+gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
+{
+ gfc_ss *newss;
+ gfc_intrinsic_sym *isym;
+ gfc_symbol *sym;
+
+ isym = expr->value.function.isym;
+
+ /* Handle intrinsic functions seperately. */
+ if (isym)
+ return gfc_walk_intrinsic_function (ss, expr, isym);
+
+ sym = expr->value.function.esym;
+ if (!sym)
+ sym = expr->symtree->n.sym;
+
+ /* A function that returns arrays. */
+ if (gfc_return_by_reference (sym) && sym->result->attr.dimension)
+ {
+ newss = gfc_get_ss ();
+ newss->type = GFC_SS_FUNCTION;
+ newss->expr = expr;
+ newss->next = ss;
+ newss->data.info.dimen = expr->rank;
+ return newss;
+ }
+
+ /* Walk the parameters of an elemental function. For now we always pass
+ by reference. */
+ if (sym->attr.elemental)
+ return gfc_walk_elemental_function_args (ss, expr, GFC_SS_REFERENCE);
+
+ /* Scalar functions are OK as these are evaluated outside the scalarisation
+ loop. Pass back and let the caller deal with it. */
+ return ss;
+}
+
+
+/* An array temporary is constructed for array constructors. */
+
+static gfc_ss *
+gfc_walk_array_constructor (gfc_ss * ss, gfc_expr * expr)
+{
+ gfc_ss *newss;
+ int n;
+
+ newss = gfc_get_ss ();
+ newss->type = GFC_SS_CONSTRUCTOR;
+ newss->expr = expr;
+ newss->next = ss;
+ newss->data.info.dimen = expr->rank;
+ for (n = 0; n < expr->rank; n++)
+ newss->data.info.dim[n] = n;
+
+ return newss;
+}
+
+
+/* Walk an expresson. Add walked expressions to the head of the SS chain.
+ A wholy scalar expression will not be added. */
+
+static gfc_ss *
+gfc_walk_subexpr (gfc_ss * ss, gfc_expr * expr)
+{
+ gfc_ss *head;
+
+ switch (expr->expr_type)
+ {
+ case EXPR_VARIABLE:
+ head = gfc_walk_variable_expr (ss, expr);
+ return head;
+
+ case EXPR_OP:
+ head = gfc_walk_op_expr (ss, expr);
+ return head;
+
+ case EXPR_FUNCTION:
+ head = gfc_walk_function_expr (ss, expr);
+ return head;
+
+ case EXPR_CONSTANT:
+ case EXPR_NULL:
+ case EXPR_STRUCTURE:
+ /* Pass back and let the caller deal with it. */
+ break;
+
+ case EXPR_ARRAY:
+ head = gfc_walk_array_constructor (ss, expr);
+ return head;
+
+ case EXPR_SUBSTRING:
+ /* Pass back and let the caller deal with it. */
+ break;
+
+ default:
+ internal_error ("bad expression type during walk (%d)",
+ expr->expr_type);
+ }
+ return ss;
+}
+
+
+/* Entry point for expression walking.
+ A return value equal to the passed chain means this is
+ a scalar expression. It is up to the caller to take whatever action is
+ neccessary to translate these. */
+
+gfc_ss *
+gfc_walk_expr (gfc_expr * expr)
+{
+ gfc_ss *res;
+
+ res = gfc_walk_subexpr (gfc_ss_terminator, expr);
+ return gfc_reverse_ss (res);
+}
+
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
new file mode 100644
index 00000000000..a78c04f4b04
--- /dev/null
+++ b/gcc/fortran/trans-array.h
@@ -0,0 +1,117 @@
+/* Header for array handling functions
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Paul Brook
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Generate code to free an array. */
+tree gfc_array_deallocate (tree);
+
+/* Generate code to initialise an allocate an array. Statements are added to
+ se, which should contain an expression for the array descriptor. */
+void gfc_array_allocate (gfc_se *, gfc_ref *, tree);
+
+/* Generate code to allocate a temporary array. */
+tree gfc_trans_allocate_temp_array (gfc_loopinfo *, gfc_ss_info *, tree,
+ tree);
+
+/* Generate function entry code for allocation of compiler allocated array
+ variables. */
+tree gfc_trans_auto_array_allocation (tree, gfc_symbol *, tree);
+/* Generate entry and exit code for dummy array parameters. */
+tree gfc_trans_dummy_array_bias (gfc_symbol *, tree, tree);
+/* Generate entry and exit code for g77 calling convention arrays. */
+tree gfc_trans_g77_array (gfc_symbol *, tree);
+/* Add initialisation for deferred arrays. */
+tree gfc_trans_deferred_array (gfc_symbol *, tree);
+/* Generate an initializer for a static pointer or allocatable array. */
+void gfc_trans_static_array_pointer (gfc_symbol *);
+
+/* Generate scalarization information for an expression. */
+gfc_ss *gfc_walk_expr (gfc_expr *);
+/* Walk the arguments of an intrinsic function. */
+gfc_ss *gfc_walk_elemental_function_args (gfc_ss *, gfc_expr *, gfc_ss_type);
+/* Walk an intrinsic function. */
+gfc_ss *gfc_walk_intrinsic_function (gfc_ss *, gfc_expr *,
+ gfc_intrinsic_sym *);
+
+/* Free the SS assocuated with a loop. */
+void gfc_cleanup_loop (gfc_loopinfo *);
+/* Associate a SS chain with a loop. */
+void gfc_add_ss_to_loop (gfc_loopinfo *, gfc_ss *);
+/* Mark a SS chain as used in this loop. */
+void gfc_mark_ss_chain_used (gfc_ss *, unsigned);
+
+/* Calculates the lower bound and stride of array sections. */
+void gfc_conv_ss_startstride (gfc_loopinfo *);
+
+void gfc_init_loopinfo (gfc_loopinfo *);
+void gfc_copy_loopinfo_to_se (gfc_se *, gfc_loopinfo *);
+
+/* Marks the start of a scalarized expression, and declares loop variables. */
+void gfc_start_scalarized_body (gfc_loopinfo *, stmtblock_t *);
+/* Generates the actual loops for a scalarized expression. */
+void gfc_trans_scalarizing_loops (gfc_loopinfo *, stmtblock_t *);
+/* Mark the end of the main loop body and the start of the copying loop. */
+void gfc_trans_scalarized_loop_boundary (gfc_loopinfo *, stmtblock_t *);
+/* Initialise the scalarization loop parameters. */
+void gfc_conv_loop_setup (gfc_loopinfo *);
+/* Resolve array assignment dependencies. */
+void gfc_conv_resolve_dependencies (gfc_loopinfo *, gfc_ss *, gfc_ss *);
+
+/* Get a single array element. */
+void gfc_conv_array_ref (gfc_se *, gfc_array_ref *);
+/* Translate a reference to a temporary array. */
+void gfc_conv_tmp_array_ref (gfc_se * se);
+/* Translate a reference to an array temporary. */
+void gfc_conv_tmp_ref (gfc_se *);
+
+/* Evaluate an array expression. */
+void gfc_conv_expr_descriptor (gfc_se *, gfc_expr *, gfc_ss *);
+/* Convert an array for passing as an actual function parameter. */
+void gfc_conv_array_parameter (gfc_se *, gfc_expr *, gfc_ss *, int);
+
+/* These work with both descriptors and descriptorless arrays. */
+tree gfc_conv_array_data (tree);
+tree gfc_conv_array_offset (tree);
+/* Return either an INT_CST or an expression for that part of the descriptor. */
+tree gfc_conv_array_stride (tree, int);
+tree gfc_conv_array_lbound (tree, int);
+tree gfc_conv_array_ubound (tree, int);
+
+/* The remaining space available for stack variables. */
+extern unsigned HOST_WIDE_INT gfc_stack_space_left;
+/* Returns true if a variable of specified size should go on the stack. */
+int gfc_can_put_var_on_stack (tree);
+
+/* Build expressions for accessing components of an array descriptor. */
+tree gfc_conv_descriptor_data (tree);
+tree gfc_conv_descriptor_offset (tree);
+tree gfc_conv_descriptor_dtype (tree);
+tree gfc_conv_descriptor_stride (tree, tree);
+tree gfc_conv_descriptor_lbound (tree, tree);
+tree gfc_conv_descriptor_ubound (tree, tree);
+
+/* Dependency checking for WHERE and FORALL. */
+int gfc_check_dependency (gfc_expr *, gfc_expr *, gfc_expr **, int);
+/* Dependency checking for function calls. */
+int gfc_check_fncall_dependency (gfc_expr *, gfc_expr *);
+
+/* Add pre-loop scalarization code for intrinsic functions which require
+ special handling. */
+void gfc_add_intrinsic_ss_code (gfc_loopinfo *, gfc_ss *);
diff --git a/gcc/fortran/trans-common.c b/gcc/fortran/trans-common.c
new file mode 100644
index 00000000000..c5ca3bd6d29
--- /dev/null
+++ b/gcc/fortran/trans-common.c
@@ -0,0 +1,756 @@
+/* Common block and equivalence list handling
+ Copyright (C) 2000, 2003 Free Software Foundation, Inc.
+ Contributed by Canqun Yang <canqun@nudt.edu.cn>
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* The core algorithm is based on Andy Vaught's g95 tree. Also the
+ way to build UNION_TYPE is borrowed from Richard Henderson.
+
+ Transform common blocks. An integral part of this is processing
+ equvalence variables. Equivalenced variables that are not in a
+ common block end up in a private block of their own.
+
+ Each common block or local equivalence list is declared as a union.
+ Variables within the block are represented as a field within the
+ block with the proper offset.
+
+ So if two variables are equivalenced, they just point to a common
+ area in memory.
+
+ Mathematically, laying out an equivalence block is equivalent to
+ solving a linear system of equations. The matrix is usually a
+ sparse matrix in which each row contains all zero elements except
+ for a +1 and a -1, a sort of a generalized Vandermonde matrix. The
+ matrix is usually block diagonal. The system can be
+ overdetermined, underdetermined or have a unique solution. If the
+ system is inconsistent, the program is not standard conforming.
+ The solution vector is integral, since all of the pivots are +1 or -1.
+
+ How we lay out an equivalence block is a little less complicated.
+ In an equivalence list with n elements, there are n-1 conditions to
+ be satisfied. The conditions partition the variables into what we
+ will call segments. If A and B are equivalenced then A and B are
+ in the same segment. If B and C are equivalenced as well, then A,
+ B and C are in a segment and so on. Each segment is a block of
+ memory that has one or more variables equivalenced in some way. A
+ common block is made up of a series of segments that are joined one
+ after the other. In the linear system, a segment is a block
+ diagonal.
+
+ To lay out a segment we first start with some variable and
+ determine its length. The first variable is assumed to start at
+ offset one and extends to however long it is. We then traverse the
+ list of equivalences to find an unused condition that involves at
+ least one of the variables currently in the segment.
+
+ Each equivalence condition amounts to the condition B+b=C+c where B
+ and C are the offsets of the B and C variables, and b and c are
+ constants which are nonzero for array elements, substrings or
+ structure components. So for
+
+ EQUIVALENCE(B(2), C(3))
+ we have
+ B + 2*size of B's elements = C + 3*size of C's elements.
+
+ If B and C are known we check to see if the condition already
+ holds. If B is known we can solve for C. Since we know the length
+ of C, we can see if the minimum and maximum extents of the segment
+ are affected. Eventually, we make a full pass through the
+ equivalence list without finding any new conditions and the segment
+ is fully specified.
+
+ At this point, the segment is added to the current common block.
+ Since we know the minimum extent of the segment, everything in the
+ segment is translated to its position in the common block. The
+ usual case here is that there are no equivalence statements and the
+ common block is series of segments with one variable each, which is
+ a diagonal matrix in the matrix formulation.
+
+ Once all common blocks have been created, the list of equivalences
+ is examined for still-unused equivalence conditions. We create a
+ block for each merged equivalence list. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "toplev.h"
+#include "tm.h"
+#include "gfortran.h"
+#include "trans.h"
+#include "trans-types.h"
+#include "trans-const.h"
+
+
+typedef struct segment_info
+{
+ gfc_symbol *sym;
+ int offset;
+ int length;
+ tree field;
+ struct segment_info *next;
+} segment_info;
+
+static segment_info *current_segment, *current_common;
+static int current_length, current_offset;
+static gfc_namespace *gfc_common_ns = NULL;
+
+#define get_segment_info() gfc_getmem (sizeof (segment_info))
+
+#define BLANK_COMMON_NAME "__BLNK__"
+
+
+/* Construct mangled common block name from symbol name. */
+
+static tree
+gfc_sym_mangled_common_id (gfc_symbol *sym)
+{
+ int has_underscore;
+ char name[GFC_MAX_MANGLED_SYMBOL_LEN + 1];
+
+ if (strcmp (sym->name, BLANK_COMMON_NAME) == 0)
+ return get_identifier (sym->name);
+ if (gfc_option.flag_underscoring)
+ {
+ has_underscore = strchr (sym->name, '_') != 0;
+ if (gfc_option.flag_second_underscore && has_underscore)
+ snprintf (name, sizeof name, "%s__", sym->name);
+ else
+ snprintf (name, sizeof name, "%s_", sym->name);
+ return get_identifier (name);
+ }
+ else
+ return get_identifier (sym->name);
+}
+
+
+/* Build a filed declaration for a common variable or a local equivalence
+ object. */
+
+static tree
+build_field (segment_info *h, tree union_type, record_layout_info rli)
+{
+ tree type = gfc_sym_type (h->sym);
+ tree name = get_identifier (h->sym->name);
+ tree field = build_decl (FIELD_DECL, name, type);
+ HOST_WIDE_INT offset = h->offset;
+ unsigned int desired_align, known_align;
+
+ known_align = (offset & -offset) * BITS_PER_UNIT;
+ if (known_align == 0 || known_align > BIGGEST_ALIGNMENT)
+ known_align = BIGGEST_ALIGNMENT;
+
+ desired_align = update_alignment_for_field (rli, field, known_align);
+ if (desired_align > known_align)
+ DECL_PACKED (field) = 1;
+
+ DECL_FIELD_CONTEXT (field) = union_type;
+ DECL_FIELD_OFFSET (field) = size_int (offset);
+ DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
+ SET_DECL_OFFSET_ALIGN (field, known_align);
+
+ rli->offset = size_binop (MAX_EXPR, rli->offset,
+ size_binop (PLUS_EXPR,
+ DECL_FIELD_OFFSET (field),
+ DECL_SIZE_UNIT (field)));
+ return field;
+}
+
+
+/* Get storage for local equivalence. */
+
+static tree
+build_equiv_decl (tree union_type, bool is_init)
+{
+ tree decl;
+ decl = build_decl (VAR_DECL, NULL, union_type);
+ DECL_ARTIFICIAL (decl) = 1;
+
+ if (is_init)
+ DECL_COMMON (decl) = 0;
+ else
+ DECL_COMMON (decl) = 1;
+
+ TREE_ADDRESSABLE (decl) = 1;
+ TREE_USED (decl) = 1;
+ gfc_add_decl_to_function (decl);
+
+ return decl;
+}
+
+
+/* Get storage for common block. */
+
+static tree
+build_common_decl (gfc_symbol *sym, tree union_type, bool is_init)
+{
+ gfc_symbol *common_sym;
+ tree decl;
+
+ /* Create a namespace to store symbols for common blocks. */
+ if (gfc_common_ns == NULL)
+ gfc_common_ns = gfc_get_namespace (NULL);
+
+ gfc_get_symbol (sym->name, gfc_common_ns, &common_sym);
+ decl = common_sym->backend_decl;
+
+ /* Update the size of this common block as needed. */
+ if (decl != NULL_TREE)
+ {
+ tree size = build_int_2 (current_length, 0);
+ if (tree_int_cst_lt (DECL_SIZE_UNIT (decl), size))
+ {
+ /* Named common blocks of the same name shall be of the same size
+ in all scoping units of a program in which they appear, but
+ blank common blocks may be of different sizes. */
+ if (strcmp (sym->name, BLANK_COMMON_NAME))
+ gfc_warning ("named COMMON block '%s' at %L shall be of the "
+ "same size", sym->name, &sym->declared_at);
+ DECL_SIZE_UNIT (decl) = size;
+ }
+ }
+
+ /* If this common block has been declared in a previous program unit,
+ and either it is already initialized or there is no new initialization
+ for it, just return. */
+ if ((decl != NULL_TREE) && (!is_init || DECL_INITIAL (decl)))
+ return decl;
+
+ /* If there is no backend_decl for the common block, build it. */
+ if (decl == NULL_TREE)
+ {
+ decl = build_decl (VAR_DECL, get_identifier (sym->name), union_type);
+ SET_DECL_ASSEMBLER_NAME (decl, gfc_sym_mangled_common_id (sym));
+ TREE_PUBLIC (decl) = 1;
+ TREE_STATIC (decl) = 1;
+ DECL_ALIGN (decl) = BIGGEST_ALIGNMENT;
+ DECL_USER_ALIGN (decl) = 0;
+ }
+
+ /* Has no initial values. */
+ if (!is_init)
+ {
+ DECL_INITIAL (decl) = NULL_TREE;
+ DECL_COMMON (decl) = 1;
+ DECL_DEFER_OUTPUT (decl) = 1;
+
+ /* Place the back end declaration for this common block in
+ GLOBAL_BINDING_LEVEL. */
+ common_sym->backend_decl = pushdecl_top_level (decl);
+ }
+ else
+ {
+ DECL_INITIAL (decl) = error_mark_node;
+ DECL_COMMON (decl) = 0;
+ DECL_DEFER_OUTPUT (decl) = 0;
+ common_sym->backend_decl = decl;
+ }
+ return decl;
+}
+
+
+/* Declare memory for the common block or local equivalence, and create
+ backend declarations for all of the elements. */
+
+static void
+create_common (gfc_symbol *sym)
+{
+ segment_info *h, *next_s;
+ tree union_type;
+ tree *field_link;
+ record_layout_info rli;
+ tree decl;
+ bool is_init = false;
+
+ /* Declare the variables inside the common block. */
+ union_type = make_node (UNION_TYPE);
+ rli = start_record_layout (union_type);
+ field_link = &TYPE_FIELDS (union_type);
+
+ for (h = current_common; h; h = next_s)
+ {
+ tree field;
+ field = build_field (h, union_type, rli);
+
+ /* Link the field into the type. */
+ *field_link = field;
+ field_link = &TREE_CHAIN (field);
+ h->field = field;
+ /* Has initial value. */
+ if (h->sym->value)
+ is_init = true;
+
+ next_s = h->next;
+ }
+ finish_record_layout (rli, true);
+
+ if (is_init)
+ gfc_todo_error ("initial values for COMMON or EQUIVALENCE");
+
+ if (sym)
+ decl = build_common_decl (sym, union_type, is_init);
+ else
+ decl = build_equiv_decl (union_type, is_init);
+
+ /* Build component reference for each variable. */
+ for (h = current_common; h; h = next_s)
+ {
+ h->sym->backend_decl = build (COMPONENT_REF, TREE_TYPE (h->field),
+ decl, h->field);
+
+ next_s = h->next;
+ gfc_free (h);
+ }
+}
+
+
+/* Given a symbol, find it in the current segment list. Returns NULL if
+ not found. */
+
+static segment_info *
+find_segment_info (gfc_symbol *symbol)
+{
+ segment_info *n;
+
+ for (n = current_segment; n; n = n->next)
+ if (n->sym == symbol) return n;
+
+ return NULL;
+}
+
+
+/* Given a variable symbol, calculate the total length in bytes of the
+ variable. */
+
+static int
+calculate_length (gfc_symbol *symbol)
+{
+ int j, element_size;
+ mpz_t elements;
+
+ if (symbol->ts.type == BT_CHARACTER)
+ gfc_conv_const_charlen (symbol->ts.cl);
+ element_size = int_size_in_bytes (gfc_typenode_for_spec (&symbol->ts));
+ if (symbol->as == NULL)
+ return element_size;
+
+ /* Calculate the number of elements in the array */
+ if (spec_size (symbol->as, &elements) == FAILURE)
+ gfc_internal_error ("calculate_length(): Unable to determine array size");
+ j = mpz_get_ui (elements);
+ mpz_clear (elements);
+
+ return j*element_size;;
+}
+
+
+/* Given an expression node, make sure it is a constant integer and return
+ the mpz_t value. */
+
+static mpz_t *
+get_mpz (gfc_expr *g)
+{
+ if (g->expr_type != EXPR_CONSTANT)
+ gfc_internal_error ("get_mpz(): Not an integer constant");
+
+ return &g->value.integer;
+}
+
+
+/* Given an array specification and an array reference, figure out the
+ array element number (zero based). Bounds and elements are guaranteed
+ to be constants. If something goes wrong we generate an error and
+ return zero. */
+
+static int
+element_number (gfc_array_ref *ar)
+{
+ mpz_t multiplier, offset, extent, l;
+ gfc_array_spec *as;
+ int b, rank;
+
+ as = ar->as;
+ rank = as->rank;
+ mpz_init_set_ui (multiplier, 1);
+ mpz_init_set_ui (offset, 0);
+ mpz_init (extent);
+ mpz_init (l);
+
+ for (b = 0; b < rank; b++)
+ {
+ if (ar->dimen_type[b] != DIMEN_ELEMENT)
+ gfc_internal_error ("element_number(): Bad dimension type");
+
+ mpz_sub (l, *get_mpz (ar->start[b]), *get_mpz (as->lower[b]));
+
+ mpz_mul (l, l, multiplier);
+ mpz_add (offset, offset, l);
+
+ mpz_sub (extent, *get_mpz (as->upper[b]), *get_mpz (as->lower[b]));
+ mpz_add_ui (extent, extent, 1);
+
+ if (mpz_sgn (extent) < 0)
+ mpz_set_ui (extent, 0);
+
+ mpz_mul (multiplier, multiplier, extent);
+ }
+
+ b = mpz_get_ui (offset);
+
+ mpz_clear (multiplier);
+ mpz_clear (offset);
+ mpz_clear (extent);
+ mpz_clear (l);
+
+ return b;
+}
+
+
+/* Given a single element of an equivalence list, figure out the offset
+ from the base symbol. For simple variables or full arrays, this is
+ simply zero. For an array element we have to calculate the array
+ element number and multiply by the element size. For a substring we
+ have to calculate the further reference. */
+
+static int
+calculate_offset (gfc_expr *s)
+{
+ int a, element_size, offset;
+ gfc_typespec *element_type;
+ gfc_ref *reference;
+
+ offset = 0;
+ element_type = &s->symtree->n.sym->ts;
+
+ for (reference = s->ref; reference; reference = reference->next)
+ switch (reference->type)
+ {
+ case REF_ARRAY:
+ switch (reference->u.ar.type)
+ {
+ case AR_FULL:
+ break;
+
+ case AR_ELEMENT:
+ a = element_number (&reference->u.ar);
+ if (element_type->type == BT_CHARACTER)
+ gfc_conv_const_charlen (element_type->cl);
+ element_size =
+ int_size_in_bytes (gfc_typenode_for_spec (element_type));
+ offset += a * element_size;
+ break;
+
+ default:
+ gfc_error ("bad array reference at %L", &s->where);
+ }
+ break;
+ case REF_SUBSTRING:
+ if (reference->u.ss.start != NULL)
+ offset += mpz_get_ui (*get_mpz (reference->u.ss.start)) - 1;
+ break;
+ default:
+ gfc_error ("illegal reference type at %L as EQUIVALENCE object",
+ &s->where);
+ }
+ return offset;
+}
+
+
+/* Add a new segment_info structure to the current eq1 is already in the
+ list at s1, eq2 is not. */
+
+static void
+new_condition (segment_info *v, gfc_equiv *eq1, gfc_equiv *eq2)
+{
+ int offset1, offset2;
+ segment_info *a;
+
+ offset1 = calculate_offset (eq1->expr);
+ offset2 = calculate_offset (eq2->expr);
+
+ a = get_segment_info ();
+
+ a->sym = eq2->expr->symtree->n.sym;
+ a->offset = v->offset + offset1 - offset2;
+ a->length = calculate_length (eq2->expr->symtree->n.sym);
+
+ a->next = current_segment;
+ current_segment = a;
+}
+
+
+/* Given two equivalence structures that are both already in the list, make
+ sure that this new condition is not violated, generating an error if it
+ is. */
+
+static void
+confirm_condition (segment_info *k, gfc_equiv *eq1, segment_info *e,
+ gfc_equiv *eq2)
+{
+ int offset1, offset2;
+
+ offset1 = calculate_offset (eq1->expr);
+ offset2 = calculate_offset (eq2->expr);
+
+ if (k->offset + offset1 != e->offset + offset2)
+ gfc_error ("inconsistent equivalence rules involving '%s' at %L and "
+ "'%s' at %L", k->sym->name, &k->sym->declared_at,
+ e->sym->name, &e->sym->declared_at);
+}
+
+
+/* At this point we have a new equivalence condition to process. If both
+ variables are already present, then we are confirming that the condition
+ holds. Otherwise we are adding a new variable to the segment list. */
+
+static void
+add_condition (gfc_equiv *eq1, gfc_equiv *eq2)
+{
+ segment_info *n, *t;
+
+ eq1->expr->symtree->n.sym->mark = 1;
+ eq2->expr->symtree->n.sym->mark = 1;
+
+ eq2->used = 1;
+
+ n = find_segment_info (eq1->expr->symtree->n.sym);
+ t = find_segment_info (eq2->expr->symtree->n.sym);
+
+ if (n == NULL && t == NULL)
+ abort ();
+ if (n != NULL && t == NULL)
+ new_condition (n, eq1, eq2);
+ if (n == NULL && t != NULL)
+ new_condition (t, eq2, eq1);
+ if (n != NULL && t != NULL)
+ confirm_condition (n, eq1, t, eq2);
+}
+
+
+/* Given a symbol, search through the equivalence lists for an unused
+ condition that involves the symbol. If a rule is found, we return
+ nonzero, the rule is marked as used and the eq1 and eq2 pointers point
+ to the rule. */
+
+static int
+find_equivalence (gfc_symbol *sym, gfc_equiv **eq1, gfc_equiv **eq2)
+{
+ gfc_equiv *c, *l;
+
+ for (c = sym->ns->equiv; c; c = c->next)
+ for (l = c->eq; l; l = l->eq)
+ {
+ if (l->used) continue;
+
+ if (c->expr->symtree->n.sym == sym || l->expr->symtree->n.sym == sym)
+ {
+ *eq1 = c;
+ *eq2 = l;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+/* Function for adding symbols to current segment. Returns zero if the
+ segment was modified. Equivalence rules are considered to be between
+ the first expression in the list and each of the other expressions in
+ the list. Symbols are scanned multiple times because a symbol can be
+ equivalenced more than once. */
+
+static int
+add_equivalences (void)
+{
+ int segment_modified;
+ gfc_equiv *eq1, *eq2;
+ segment_info *f;
+
+ segment_modified = 0;
+
+ for (f = current_segment; f; f = f->next)
+ if (find_equivalence (f->sym, &eq1, &eq2)) break;
+
+ if (f != NULL)
+ {
+ add_condition (eq1, eq2);
+ segment_modified = 1;
+ }
+
+ return segment_modified;
+}
+
+
+/* Given a seed symbol, create a new segment consisting of that symbol
+ and all of the symbols equivalenced with that symbol. */
+
+static void
+new_segment (gfc_symbol *common_sym, gfc_symbol *sym)
+{
+ segment_info *v;
+ int length;
+
+ current_segment = get_segment_info ();
+ current_segment->sym = sym;
+ current_segment->offset = current_offset;
+ length = calculate_length (sym);
+ current_segment->length = length;
+
+ sym->mark = 1;
+
+ /* Add all object directly or indirectly equivalenced with this common
+ variable. */
+ while (add_equivalences ());
+
+ /* Calculate the storage size to hold the common block. */
+ for (v = current_segment; v; v = v->next)
+ {
+ if (v->offset < 0)
+ gfc_error ("the equivalence set for '%s' cause an invalid extension "
+ "to COMMON '%s' at %L",
+ sym->name, common_sym->name, &common_sym->declared_at);
+ if (current_length < (v->offset + v->length))
+ current_length = v->offset + v->length;
+ }
+
+ /* The offset of the next common variable. */
+ current_offset += length;
+
+ /* Append the current segment to the current common. */
+ v = current_segment;
+ while (v->next != NULL)
+ v = v->next;
+
+ v->next = current_common;
+ current_common = current_segment;
+ current_segment = NULL;
+}
+
+
+/* Create a new block for each merged equivalence list. */
+
+static void
+finish_equivalences (gfc_namespace *ns)
+{
+ gfc_equiv *z, *y;
+ gfc_symbol *sym;
+ segment_info *v;
+ int min_offset;
+
+ for (z = ns->equiv; z; z = z->next)
+ for (y= z->eq; y; y = y->eq)
+ {
+ if (y->used) continue;
+ sym = z->expr->symtree->n.sym;
+ current_length = 0;
+ current_segment = get_segment_info ();
+ current_segment->sym = sym;
+ current_segment->offset = 0;
+ current_segment->length = calculate_length (sym);
+ sym->mark = 1;
+
+ /* All object directly or indrectly equivalenced with this symbol. */
+ while (add_equivalences ());
+
+ /* Calculate the minimal offset. */
+ min_offset = 0;
+ for (v = current_segment; v; v = v->next)
+ min_offset = (min_offset >= v->offset) ? v->offset : min_offset;
+
+ /* Adjust the offset of each equivalence object, and calculate the
+ maximal storage size to hold them. */
+ for (v = current_segment; v; v = v->next)
+ {
+ v->offset -= min_offset;
+ if (current_length < (v->offset + v->length))
+ current_length = v->offset + v->length;
+ }
+
+ current_common = current_segment;
+ create_common (NULL);
+ break;
+ }
+}
+
+
+/* Translate a single common block. */
+
+static void
+translate_common (gfc_symbol *common_sym, gfc_symbol *var_list)
+{
+ gfc_symbol *sym;
+
+ current_common = NULL;
+ current_length = 0;
+ current_offset = 0;
+
+ /* Mark bits indicate which symbols have already been placed in a
+ common area. */
+ for (sym = var_list; sym; sym = sym->common_next)
+ sym->mark = 0;
+
+ for (;;)
+ {
+ for (sym = var_list; sym; sym = sym->common_next)
+ if (!sym->mark) break;
+
+ /* All symbols have been placed in a common. */
+ if (sym == NULL) break;
+ new_segment (common_sym, sym);
+ }
+
+ create_common (common_sym);
+}
+
+
+/* Work function for translating a named common block. */
+
+static void
+named_common (gfc_symbol *s)
+{
+ if (s->attr.common)
+ translate_common (s, s->common_head);
+}
+
+
+/* Translate the common blocks in a namespace. Unlike other variables,
+ these have to be created before code, because the backend_decl depends
+ on the rest of the common block. */
+
+void
+gfc_trans_common (gfc_namespace *ns)
+{
+ gfc_symbol *sym;
+
+ /* Translate the blank common block. */
+ if (ns->blank_common != NULL)
+ {
+ gfc_get_symbol (BLANK_COMMON_NAME, ns, &sym);
+ translate_common (sym, ns->blank_common);
+ }
+
+ /* Translate all named common blocks. */
+ gfc_traverse_ns (ns, named_common);
+
+ /* Commit the newly created symbols for common blocks. */
+ gfc_commit_symbols ();
+
+ /* Translate local equivalence. */
+ finish_equivalences (ns);
+}
diff --git a/gcc/fortran/trans-const.c b/gcc/fortran/trans-const.c
new file mode 100644
index 00000000000..6e6865202e8
--- /dev/null
+++ b/gcc/fortran/trans-const.c
@@ -0,0 +1,375 @@
+/* Translation of constants
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Paul Brook
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* trans-const.c -- convert constant values */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include <stdio.h>
+#include "ggc.h"
+#include "toplev.h"
+#include "real.h"
+#include <gmp.h>
+#include <assert.h>
+#include <math.h>
+#include "gfortran.h"
+#include "trans.h"
+#include "trans-const.h"
+#include "trans-types.h"
+
+/* String constants. */
+tree gfc_strconst_bounds;
+tree gfc_strconst_fault;
+tree gfc_strconst_wrong_return;
+tree gfc_strconst_current_filename;
+
+tree gfc_rank_cst[GFC_MAX_DIMENSIONS + 1];
+
+/* Build a constant with given type from an int_cst. */
+tree
+gfc_build_const (tree type, tree intval)
+{
+ tree val;
+ tree zero;
+
+ switch (TREE_CODE (type))
+ {
+ case INTEGER_TYPE:
+ val = convert (type, intval);
+ break;
+
+ case REAL_TYPE:
+ val = build_real_from_int_cst (type, intval);
+ break;
+
+ case COMPLEX_TYPE:
+ val = build_real_from_int_cst (TREE_TYPE (type), intval);
+ zero = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
+ val = build_complex (type, val, zero);
+ break;
+
+ default:
+ abort ();
+ }
+ return val;
+}
+
+tree
+gfc_build_string_const (int length, const char *s)
+{
+ tree str;
+ tree len;
+
+ str = build_string (length, s);
+ len = build_int_2 (length, 0);
+ TREE_TYPE (str) =
+ build_array_type (gfc_character1_type_node,
+ build_range_type (gfc_strlen_type_node,
+ integer_one_node, len));
+ return str;
+}
+
+/* Return a string constant with the given length. Used for static
+ initializers. The constant will be padded to the full length. */
+tree
+gfc_conv_string_init (tree length, gfc_expr * expr)
+{
+ char *s;
+ HOST_WIDE_INT len;
+ int slen;
+ tree str;
+
+ assert (expr->expr_type == EXPR_CONSTANT);
+ assert (expr->ts.type == BT_CHARACTER && expr->ts.kind == 1);
+ assert (INTEGER_CST_P (length));
+ assert (TREE_INT_CST_HIGH (length) == 0);
+
+ len = TREE_INT_CST_LOW (length);
+ slen = expr->value.character.length;
+ assert (len >= slen);
+ if (len != slen)
+ {
+ s = gfc_getmem (len);
+ memcpy (s, expr->value.character.string, slen);
+ memset (&s[slen], ' ', len - slen);
+ str = gfc_build_string_const (len, s);
+ gfc_free (s);
+ }
+ else
+ str = gfc_build_string_const (len, expr->value.character.string);
+
+ return str;
+}
+
+
+/* Create a tree node for the string length if it is constant. */
+
+void
+gfc_conv_const_charlen (gfc_charlen * cl)
+{
+ if (cl->backend_decl)
+ return;
+
+ if (cl->length && cl->length->expr_type == EXPR_CONSTANT)
+ {
+ cl->backend_decl = gfc_conv_mpz_to_tree (cl->length->value.integer,
+ cl->length->ts.kind);
+ }
+}
+
+void
+gfc_init_constants (void)
+{
+ int n;
+
+ for (n = 0; n <= GFC_MAX_DIMENSIONS; n++)
+ {
+ gfc_rank_cst[n] = build_int_2 (n, 0);
+ TREE_TYPE (gfc_rank_cst[n]) = gfc_array_index_type;
+ }
+
+ gfc_strconst_bounds = gfc_build_string_const (21, "Array bound mismatch");
+
+ gfc_strconst_fault =
+ gfc_build_string_const (30, "Array reference out of bounds");
+
+ gfc_strconst_wrong_return =
+ gfc_build_string_const (32, "Incorrect function return value");
+
+ gfc_strconst_current_filename =
+ gfc_build_string_const (strlen (gfc_option.source) + 1,
+ gfc_option.source);
+}
+
+#define BITS_PER_HOST_WIDE_INT (8 * sizeof (HOST_WIDE_INT))
+/* Converts a GMP integer into a backend tree node. */
+tree
+gfc_conv_mpz_to_tree (mpz_t i, int kind)
+{
+ int val;
+ tree res;
+ HOST_WIDE_INT high;
+ unsigned HOST_WIDE_INT low;
+ int negate;
+ char buff[10];
+ char *p;
+ char *q;
+ int n;
+
+ /* TODO: could be wrong if sizeof(HOST_WIDE_INT) |= SIZEOF (int). */
+ if (mpz_fits_slong_p (i))
+ {
+ val = mpz_get_si (i);
+ res = build_int_2 (val, (val < 0) ? (HOST_WIDE_INT)-1 : 0);
+ TREE_TYPE (res) = gfc_get_int_type (kind);
+ return (res);
+ }
+
+ n = mpz_sizeinbase (i, 16);
+ if (n > 8)
+ q = gfc_getmem (n + 2);
+ else
+ q = buff;
+
+ low = 0;
+ high = 0;
+ p = mpz_get_str (q, 16, i);
+ if (p[0] == '-')
+ {
+ negate = 1;
+ p++;
+ }
+ else
+ negate = 0;
+
+ while (*p)
+ {
+ n = *(p++);
+ if (n >= '0' && n <= '9')
+ n = n - '0';
+ else if (n >= 'a' && n <= 'z')
+ n = n + 10 - 'a';
+ else if (n >= 'A' && n <= 'Z')
+ n = n + 10 - 'A';
+ else
+ abort ();
+
+ assert (n >= 0 && n < 16);
+ high = (high << 4) + (low >> (BITS_PER_HOST_WIDE_INT - 4));
+ low = (low << 4) + n;
+ }
+ res = build_int_2 (low, high);
+ TREE_TYPE (res) = gfc_get_int_type (kind);
+ if (negate)
+ res = fold (build1 (NEGATE_EXPR, TREE_TYPE (res), res));
+
+ if (q != buff)
+ gfc_free (q);
+
+ return res;
+}
+
+/* Converts a real constant into backend form. Uses an intermediate string
+ representation. */
+tree
+gfc_conv_mpf_to_tree (mpf_t f, int kind)
+{
+ tree res;
+ tree type;
+ mp_exp_t exp;
+ char *p;
+ char *q;
+ int n;
+ int edigits;
+
+ for (n = 0; gfc_real_kinds[n].kind != 0; n++)
+ {
+ if (gfc_real_kinds[n].kind == kind)
+ break;
+ }
+ assert (gfc_real_kinds[n].kind);
+
+ assert (gfc_real_kinds[n].radix == 2);
+
+ n = MAX (abs (gfc_real_kinds[n].min_exponent),
+ abs (gfc_real_kinds[n].min_exponent));
+#if 0
+ edigits = 2 + (int) (log (n) / log (gfc_real_kinds[n].radix));
+#endif
+ edigits = 1;
+ while (n > 0)
+ {
+ n = n / 10;
+ edigits += 3;
+ }
+
+
+ p = mpf_get_str (NULL, &exp, 10, 0, f);
+
+ /* We also have one minus sign, "e", "." and a null terminator. */
+ q = (char *) gfc_getmem (strlen (p) + edigits + 4);
+
+ if (p[0])
+ {
+ if (p[0] == '-')
+ {
+ strcpy (&q[2], &p[1]);
+ q[0] = '-';
+ q[1] = '.';
+ }
+ else
+ {
+ strcpy (&q[1], p);
+ q[0] = '.';
+ }
+ strcat (q, "e");
+ sprintf (&q[strlen (q)], "%d", (int) exp);
+ }
+ else
+ {
+ strcpy (q, "0");
+ }
+
+ type = gfc_get_real_type (kind);
+ res = build_real (type, REAL_VALUE_ATOF (q, TYPE_MODE (type)));
+ gfc_free (q);
+ gfc_free (p);
+
+ return res;
+}
+
+
+/* Translate any literal constant to a tree. Constants never have
+ pre or post chains. Character literal constants are special
+ special because they have a value and a length, so they cannot be
+ returned as a single tree. It is up to the caller to set the
+ length somewhere if necessary.
+
+ Returns the translated constant, or aborts if it gets a type it
+ can't handle. */
+
+tree
+gfc_conv_constant_to_tree (gfc_expr * expr)
+{
+ assert (expr->expr_type == EXPR_CONSTANT);
+
+ switch (expr->ts.type)
+ {
+ case BT_INTEGER:
+ return gfc_conv_mpz_to_tree (expr->value.integer, expr->ts.kind);
+
+ case BT_REAL:
+ return gfc_conv_mpf_to_tree (expr->value.real, expr->ts.kind);
+
+ case BT_LOGICAL:
+ return build_int_2 (expr->value.logical, 0);
+
+ case BT_COMPLEX:
+ {
+ tree real = gfc_conv_mpf_to_tree (expr->value.complex.r,
+ expr->ts.kind);
+ tree imag = gfc_conv_mpf_to_tree (expr->value.complex.i,
+ expr->ts.kind);
+
+ return build_complex (NULL_TREE, real, imag);
+ }
+
+ case BT_CHARACTER:
+ return gfc_build_string_const (expr->value.character.length,
+ expr->value.character.string);
+
+ default:
+ fatal_error ("gfc_conv_constant_to_tree(): invalid type: %s",
+ gfc_typename (&expr->ts));
+ }
+}
+
+
+/* Like gfc_conv_contrant_to_tree, but for a simplified expression.
+ We can handle character literal constants here as well. */
+
+void
+gfc_conv_constant (gfc_se * se, gfc_expr * expr)
+{
+ assert (expr->expr_type == EXPR_CONSTANT);
+
+ if (se->ss != NULL)
+ {
+ assert (se->ss != gfc_ss_terminator);
+ assert (se->ss->type == GFC_SS_SCALAR);
+ assert (se->ss->expr == expr);
+
+ se->expr = se->ss->data.scalar.expr;
+ se->string_length = se->ss->data.scalar.string_length;
+ gfc_advance_se_ss_chain (se);
+ return;
+ }
+
+ /* Translate the constant and put it in the simplifier structure. */
+ se->expr = gfc_conv_constant_to_tree (expr);
+
+ /* If this is a CHARACTER string, set it's length in the simplifier
+ structure, too. */
+ if (expr->ts.type == BT_CHARACTER)
+ se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
+}
diff --git a/gcc/fortran/trans-const.h b/gcc/fortran/trans-const.h
new file mode 100644
index 00000000000..91b3e84a424
--- /dev/null
+++ b/gcc/fortran/trans-const.h
@@ -0,0 +1,59 @@
+/* Header for code constant translation functions
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Paul Brook
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Returns an INT_CST. */
+tree gfc_conv_mpz_to_tree (mpz_t, int);
+
+/* Returns a REAL_CST. */
+tree gfc_conv_mpf_to_tree (mpf_t, int);
+
+/* Build a tree for a constant. Must be an EXPR_CONSTANT gfc_expr.
+ For CHARACTER literal constants, the caller still has to set the
+ string length as a separate operation. */
+tree gfc_conv_constant_to_tree (gfc_expr *);
+
+/* Like gfc_conv_noncharacter_constant, but works on simplified expression
+ structures. Also sets the length of CHARACTER strings in the gfc_se. */
+void gfc_conv_constant (gfc_se *, gfc_expr *);
+
+tree gfc_build_string_const (int, const char *);
+
+/* Translate a string constant for a static initializer. */
+tree gfc_conv_string_init (tree, gfc_expr *);
+
+/* Create a tree node for the string length if it is constant. */
+void gfc_conv_const_charlen (gfc_charlen *);
+
+/* Initialise the nodes for constants. */
+void gfc_init_constants (void);
+
+/* Build a constant with given type from an int_cst. */
+tree gfc_build_const (tree, tree);
+
+/* String constants. */
+extern GTY(()) tree gfc_strconst_current_filename;
+extern GTY(()) tree gfc_strconst_bounds;
+extern GTY(()) tree gfc_strconst_fault;
+extern GTY(()) tree gfc_strconst_wrong_return;
+
+/* Integer constants 0..GFC_MAX_DIMENSIONS. */
+extern GTY(()) tree gfc_rank_cst[GFC_MAX_DIMENSIONS + 1];
+#define gfc_index_zero_node gfc_rank_cst[0]
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
new file mode 100644
index 00000000000..b345ed99c8e
--- /dev/null
+++ b/gcc/fortran/trans-decl.c
@@ -0,0 +1,2139 @@
+/* Backend function setup
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Paul Brook
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* trans-decl.c -- Handling of backend function and variable decls, etc */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "tree-dump.h"
+#include "tree-gimple.h"
+#include "ggc.h"
+#include "toplev.h"
+#include "tm.h"
+#include "target.h"
+#include "function.h"
+#include "errors.h"
+#include "flags.h"
+#include "cgraph.h"
+#include <assert.h>
+#include "gfortran.h"
+#include "trans.h"
+#include "trans-types.h"
+#include "trans-array.h"
+#include "trans-const.h"
+/* Only for gfc_trans_code. Shouldn't need to include this. */
+#include "trans-stmt.h"
+
+#define MAX_LABEL_VALUE 99999
+
+
+/* Holds the result of the function if no result variable specified. */
+
+static GTY(()) tree current_fake_result_decl;
+
+static GTY(()) tree current_function_return_label;
+
+
+/* Holds the variable DECLs for the current function. */
+
+static GTY(()) tree saved_function_decls = NULL_TREE;
+static GTY(()) tree saved_parent_function_decls = NULL_TREE;
+
+
+/* The namespace of the module we're currently generating. Only used while
+ outputting decls for module variables. Do not rely on this being set. */
+
+static gfc_namespace *module_namespace;
+
+
+/* List of static constructor functions. */
+
+tree gfc_static_ctors;
+
+
+/* Function declarations for builtin library functions. */
+
+tree gfor_fndecl_internal_malloc;
+tree gfor_fndecl_internal_malloc64;
+tree gfor_fndecl_internal_free;
+tree gfor_fndecl_allocate;
+tree gfor_fndecl_allocate64;
+tree gfor_fndecl_deallocate;
+tree gfor_fndecl_pause_numeric;
+tree gfor_fndecl_pause_string;
+tree gfor_fndecl_stop_numeric;
+tree gfor_fndecl_stop_string;
+tree gfor_fndecl_select_string;
+tree gfor_fndecl_runtime_error;
+tree gfor_fndecl_in_pack;
+tree gfor_fndecl_in_unpack;
+tree gfor_fndecl_associated;
+
+
+/* Math functions. Many other math functions are handled in
+ trans-intrinsic.c. */
+
+tree gfor_fndecl_math_powf;
+tree gfor_fndecl_math_pow;
+tree gfor_fndecl_math_cpowf;
+tree gfor_fndecl_math_cpow;
+tree gfor_fndecl_math_cabsf;
+tree gfor_fndecl_math_cabs;
+tree gfor_fndecl_math_sign4;
+tree gfor_fndecl_math_sign8;
+tree gfor_fndecl_math_ishftc4;
+tree gfor_fndecl_math_ishftc8;
+tree gfor_fndecl_math_exponent4;
+tree gfor_fndecl_math_exponent8;
+
+
+/* String functions. */
+
+tree gfor_fndecl_copy_string;
+tree gfor_fndecl_compare_string;
+tree gfor_fndecl_concat_string;
+tree gfor_fndecl_string_len_trim;
+tree gfor_fndecl_string_index;
+tree gfor_fndecl_string_scan;
+tree gfor_fndecl_string_verify;
+tree gfor_fndecl_string_trim;
+tree gfor_fndecl_string_repeat;
+tree gfor_fndecl_adjustl;
+tree gfor_fndecl_adjustr;
+
+
+/* Other misc. runtime library functions. */
+
+tree gfor_fndecl_size0;
+tree gfor_fndecl_size1;
+
+/* Intrinsic functions implemented in FORTRAN. */
+tree gfor_fndecl_si_kind;
+tree gfor_fndecl_sr_kind;
+
+
+static void
+gfc_add_decl_to_parent_function (tree decl)
+{
+ assert (decl);
+ DECL_CONTEXT (decl) = DECL_CONTEXT (current_function_decl);
+ DECL_NONLOCAL (decl) = 1;
+ TREE_CHAIN (decl) = saved_parent_function_decls;
+ saved_parent_function_decls = decl;
+}
+
+void
+gfc_add_decl_to_function (tree decl)
+{
+ assert (decl);
+ TREE_USED (decl) = 1;
+ DECL_CONTEXT (decl) = current_function_decl;
+ TREE_CHAIN (decl) = saved_function_decls;
+ saved_function_decls = decl;
+}
+
+
+/* Build a backend label declaration.
+ Set TREE_USED for named lables. For artificial labels it's up to the
+ caller to mark the label as used. */
+
+tree
+gfc_build_label_decl (tree label_id)
+{
+ /* 2^32 temporaries should be enough. */
+ static unsigned int tmp_num = 1;
+ tree label_decl;
+ char *label_name;
+
+ if (label_id == NULL_TREE)
+ {
+ /* Build an internal label name. */
+ ASM_FORMAT_PRIVATE_NAME (label_name, "L", tmp_num++);
+ label_id = get_identifier (label_name);
+ }
+ else
+ label_name = NULL;
+
+ /* Build the LABEL_DECL node. Labels have no type. */
+ label_decl = build_decl (LABEL_DECL, label_id, void_type_node);
+ DECL_CONTEXT (label_decl) = current_function_decl;
+ DECL_MODE (label_decl) = VOIDmode;
+
+ if (label_name)
+ {
+ DECL_ARTIFICIAL (label_decl) = 1;
+ }
+ else
+ {
+ /* We always define the label as used, even if the original source
+ file never references the label. We don't want all kinds of
+ spurious warnings for old-style Fortran code with too many
+ labels. */
+ TREE_USED (label_decl) = 1;
+ }
+
+ return label_decl;
+}
+
+
+/* Returns the return label for the current function. */
+
+tree
+gfc_get_return_label (void)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 10];
+
+ if (current_function_return_label)
+ return current_function_return_label;
+
+ sprintf (name, "__return_%s",
+ IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
+
+ current_function_return_label =
+ gfc_build_label_decl (get_identifier (name));
+
+ DECL_ARTIFICIAL (current_function_return_label) = 1;
+
+ return current_function_return_label;
+}
+
+
+/* Return the backend label declaration for a given label structure,
+ or create it if it doesn't exist yet. */
+
+tree
+gfc_get_label_decl (gfc_st_label * lp)
+{
+
+ if (lp->backend_decl)
+ return lp->backend_decl;
+ else
+ {
+ char label_name[GFC_MAX_SYMBOL_LEN + 1];
+ tree label_decl;
+
+ /* Validate the label declaration from the front end. */
+ assert (lp != NULL && lp->value <= MAX_LABEL_VALUE);
+
+ /* Build a mangled name for the label. */
+ sprintf (label_name, "__label_%.6d", lp->value);
+
+ /* Build the LABEL_DECL node. */
+ label_decl = gfc_build_label_decl (get_identifier (label_name));
+
+ /* Tell the debugger where the label came from. */
+ if (lp->value <= MAX_LABEL_VALUE) /* An internal label */
+ {
+ DECL_SOURCE_LINE (label_decl) = lp->where.line;
+ DECL_SOURCE_FILE (label_decl) = lp->where.file->filename;
+ }
+ else
+ DECL_ARTIFICIAL (label_decl) = 1;
+
+ /* Store the label in the label list and return the LABEL_DECL. */
+ lp->backend_decl = label_decl;
+ return label_decl;
+ }
+}
+
+
+/* Convert a gfc_symbol to an identifier of the same name. */
+
+static tree
+gfc_sym_identifier (gfc_symbol * sym)
+{
+ return (get_identifier (sym->name));
+}
+
+
+/* Construct mangled name from symbol name. */
+
+static tree
+gfc_sym_mangled_identifier (gfc_symbol * sym)
+{
+ char name[GFC_MAX_MANGLED_SYMBOL_LEN + 1];
+
+ if (sym->module[0] == 0)
+ return gfc_sym_identifier (sym);
+ else
+ {
+ snprintf (name, sizeof name, "__%s__%s", sym->module, sym->name);
+ return get_identifier (name);
+ }
+}
+
+
+/* Construct mangled function name from symbol name. */
+
+static tree
+gfc_sym_mangled_function_id (gfc_symbol * sym)
+{
+ int has_underscore;
+ char name[GFC_MAX_MANGLED_SYMBOL_LEN + 1];
+
+ if (sym->module[0] == 0 || sym->attr.proc == PROC_EXTERNAL
+ || (sym->module[0] != 0 && sym->attr.if_source == IFSRC_IFBODY))
+ {
+ if (strcmp (sym->name, "MAIN__") == 0
+ || sym->attr.proc == PROC_INTRINSIC)
+ return get_identifier (sym->name);
+
+ if (gfc_option.flag_underscoring)
+ {
+ has_underscore = strchr (sym->name, '_') != 0;
+ if (gfc_option.flag_second_underscore && has_underscore)
+ snprintf (name, sizeof name, "%s__", sym->name);
+ else
+ snprintf (name, sizeof name, "%s_", sym->name);
+ return get_identifier (name);
+ }
+ else
+ return get_identifier (sym->name);
+ }
+ else
+ {
+ snprintf (name, sizeof name, "__%s__%s", sym->module, sym->name);
+ return get_identifier (name);
+ }
+}
+
+
+/* Finish processing of a declaration and install its initial value. */
+
+static void
+gfc_finish_decl (tree decl, tree init)
+{
+ if (TREE_CODE (decl) == PARM_DECL)
+ assert (init == NULL_TREE);
+ /* Remember that PARM_DECL doesn't have a DECL_INITIAL field per se
+ -- it overlaps DECL_ARG_TYPE. */
+ else if (init == NULL_TREE)
+ assert (DECL_INITIAL (decl) == NULL_TREE);
+ else
+ assert (DECL_INITIAL (decl) == error_mark_node);
+
+ if (init != NULL_TREE)
+ {
+ if (TREE_CODE (decl) != TYPE_DECL)
+ DECL_INITIAL (decl) = init;
+ else
+ {
+ /* typedef foo = bar; store the type of bar as the type of foo. */
+ TREE_TYPE (decl) = TREE_TYPE (init);
+ DECL_INITIAL (decl) = init = 0;
+ }
+ }
+
+ if (TREE_CODE (decl) == VAR_DECL)
+ {
+ if (DECL_SIZE (decl) == NULL_TREE
+ && TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE)
+ layout_decl (decl, 0);
+
+ /* A static variable with an incomplete type is an error if it is
+ initialized. Also if it is not file scope. Otherwise, let it
+ through, but if it is not `extern' then it may cause an error
+ message later. */
+ /* An automatic variable with an incomplete type is an error. */
+ if (DECL_SIZE (decl) == NULL_TREE
+ && (TREE_STATIC (decl) ? (DECL_INITIAL (decl) != 0
+ || DECL_CONTEXT (decl) != 0)
+ : !DECL_EXTERNAL (decl)))
+ {
+ gfc_fatal_error ("storage size not known");
+ }
+
+ if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
+ && (DECL_SIZE (decl) != 0)
+ && (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST))
+ {
+ gfc_fatal_error ("storage size not constant");
+ }
+ }
+
+}
+
+
+/* Apply symbol attributes to a variable, and add it to the function scope. */
+
+static void
+gfc_finish_var_decl (tree decl, gfc_symbol * sym)
+{
+ /* TREE_ADDRESSABLE means the address of this variable is acualy needed.
+ This is the equivalent of the TARGET variables.
+ We also need to set this if the variable is passed by reference in a
+ CALL statement. */
+ if (sym->attr.target)
+ TREE_ADDRESSABLE (decl) = 1;
+ /* If it wasn't used we wouldn't be getting it. */
+ TREE_USED (decl) = 1;
+
+ /* Chain this decl to the pending declarations. Don't do pushdecl()
+ because this would add them to the current scope rather than the
+ function scope. */
+ if (current_function_decl != NULL_TREE)
+ {
+ if (sym->ns->proc_name->backend_decl == current_function_decl)
+ gfc_add_decl_to_function (decl);
+ else
+ gfc_add_decl_to_parent_function (decl);
+ }
+
+ /* If a variable is USE associated, it's always external. */
+ if (sym->attr.use_assoc)
+ {
+ DECL_EXTERNAL (decl) = 1;
+ TREE_PUBLIC (decl) = 1;
+ }
+ else if (sym->module[0] && !sym->attr.result)
+ {
+ /* TODO: Don't set sym->module for result variables. */
+ assert (current_function_decl == NULL_TREE);
+ /* This is the declaration of a module variable. */
+ TREE_PUBLIC (decl) = 1;
+ TREE_STATIC (decl) = 1;
+ }
+
+ if ((sym->attr.save || sym->attr.data || sym->value)
+ && !sym->attr.use_assoc)
+ TREE_STATIC (decl) = 1;
+
+ /* Keep variables larger than max-stack-var-size off stack. */
+ if (!sym->ns->proc_name->attr.recursive
+ && INTEGER_CST_P (DECL_SIZE_UNIT (decl))
+ && !gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl)))
+ TREE_STATIC (decl) = 1;
+}
+
+
+/* Allocate the lang-specific part of a decl. */
+
+void
+gfc_allocate_lang_decl (tree decl)
+{
+ DECL_LANG_SPECIFIC (decl) = (struct lang_decl *)
+ ggc_alloc_cleared (sizeof (struct lang_decl));
+}
+
+/* Remember a symbol to generate initialization/cleanup code at function
+ entry/exit. */
+
+static void
+gfc_defer_symbol_init (gfc_symbol * sym)
+{
+ gfc_symbol *p;
+ gfc_symbol *last;
+ gfc_symbol *head;
+
+ /* Don't add a symbol twice. */
+ if (sym->tlink)
+ return;
+
+ last = head = sym->ns->proc_name;
+ p = last->tlink;
+
+ /* Make sure that setup code for dummy variables which are used in the
+ setup of other variables is generated first. */
+ if (sym->attr.dummy)
+ {
+ /* Find the first dummy arg seen after us, or the first non-dummy arg.
+ This is a circular list, so don't go past the head. */
+ while (p != head
+ && (!p->attr.dummy || p->dummy_order > sym->dummy_order))
+ {
+ last = p;
+ p = p->tlink;
+ }
+ }
+ /* Insert in between last and p. */
+ last->tlink = sym;
+ sym->tlink = p;
+}
+
+
+/* Create an array index type variable with function scope. */
+
+static tree
+create_index_var (const char * pfx, int nest)
+{
+ tree decl;
+
+ decl = gfc_create_var_np (gfc_array_index_type, pfx);
+ if (nest)
+ gfc_add_decl_to_parent_function (decl);
+ else
+ gfc_add_decl_to_function (decl);
+ return decl;
+}
+
+
+/* Create variables to hold all the non-constant bits of info for a
+ descriptorless array. Remember these in the lang-specific part of the
+ type. */
+
+static void
+gfc_build_qualified_array (tree decl, gfc_symbol * sym)
+{
+ tree type;
+ int dim;
+ int nest;
+
+ type = TREE_TYPE (decl);
+
+ /* We just use the descriptor, if there is one. */
+ if (GFC_DESCRIPTOR_TYPE_P (type))
+ return;
+
+ assert (GFC_ARRAY_TYPE_P (type));
+ nest = (sym->ns->proc_name->backend_decl != current_function_decl)
+ && !sym->attr.contained;
+
+ for (dim = 0; dim < GFC_TYPE_ARRAY_RANK (type); dim++)
+ {
+ if (GFC_TYPE_ARRAY_LBOUND (type, dim) == NULL_TREE)
+ GFC_TYPE_ARRAY_LBOUND (type, dim) = create_index_var ("lbound", nest);
+ /* Don't try to use the unkown bound for assumed shape arrays. */
+ if (GFC_TYPE_ARRAY_UBOUND (type, dim) == NULL_TREE
+ && (sym->as->type != AS_ASSUMED_SIZE
+ || dim < GFC_TYPE_ARRAY_RANK (type) - 1))
+ GFC_TYPE_ARRAY_UBOUND (type, dim) = create_index_var ("ubound", nest);
+
+ if (GFC_TYPE_ARRAY_STRIDE (type, dim) == NULL_TREE)
+ GFC_TYPE_ARRAY_STRIDE (type, dim) = create_index_var ("stride", nest);
+ }
+ if (GFC_TYPE_ARRAY_OFFSET (type) == NULL_TREE)
+ {
+ GFC_TYPE_ARRAY_OFFSET (type) = gfc_create_var_np (gfc_array_index_type,
+ "offset");
+ if (nest)
+ gfc_add_decl_to_parent_function (GFC_TYPE_ARRAY_OFFSET (type));
+ else
+ gfc_add_decl_to_function (GFC_TYPE_ARRAY_OFFSET (type));
+ }
+}
+
+
+/* For some dummy arguments we don't use the actual argument directly.
+ Instead we create a local decl and use that. This allows us to preform
+ initialization, and construct full type information. */
+
+static tree
+gfc_build_dummy_array_decl (gfc_symbol * sym, tree dummy)
+{
+ tree decl;
+ tree type;
+ gfc_array_spec *as;
+ char *name;
+ int packed;
+ int n;
+ bool known_size;
+
+ if (sym->attr.pointer || sym->attr.allocatable)
+ return dummy;
+
+ /* Add to list of variables if not a fake result variable. */
+ if (sym->attr.result || sym->attr.dummy)
+ gfc_defer_symbol_init (sym);
+
+ type = TREE_TYPE (dummy);
+ assert (TREE_CODE (dummy) == PARM_DECL
+ && POINTER_TYPE_P (type));
+
+ /* Do we know the element size. */
+ known_size = sym->ts.type != BT_CHARACTER
+ || INTEGER_CST_P (sym->ts.cl->backend_decl);
+
+ if (known_size && !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (type)))
+ {
+ /* For descriptorless arrays with known element size the actual
+ argument is sufficient. */
+ assert (GFC_ARRAY_TYPE_P (type));
+ gfc_build_qualified_array (dummy, sym);
+ return dummy;
+ }
+
+ type = TREE_TYPE (type);
+ if (GFC_DESCRIPTOR_TYPE_P (type))
+ {
+ /* Create a decriptorless array pointer. */
+ as = sym->as;
+ packed = 0;
+ if (!gfc_option.flag_repack_arrays)
+ {
+ if (as->type == AS_ASSUMED_SIZE)
+ packed = 2;
+ }
+ else
+ {
+ if (as->type == AS_EXPLICIT)
+ {
+ packed = 2;
+ for (n = 0; n < as->rank; n++)
+ {
+ if (!(as->upper[n]
+ && as->lower[n]
+ && as->upper[n]->expr_type == EXPR_CONSTANT
+ && as->lower[n]->expr_type == EXPR_CONSTANT))
+ packed = 1;
+ }
+ }
+ else
+ packed = 1;
+ }
+
+ type = gfc_typenode_for_spec (&sym->ts);
+ type = gfc_get_nodesc_array_type (type, sym->as, packed);
+ }
+ else
+ {
+ /* We now have an expression for the element size, so create a fully
+ qualified type. Reset sym->backend decl or this will just return the
+ old type. */
+ sym->backend_decl = NULL_TREE;
+ type = gfc_sym_type (sym);
+ packed = 2;
+ }
+
+ ASM_FORMAT_PRIVATE_NAME (name, IDENTIFIER_POINTER (DECL_NAME (dummy)), 0);
+ decl = build_decl (VAR_DECL, get_identifier (name), type);
+
+ DECL_ARTIFICIAL (decl) = 1;
+ TREE_PUBLIC (decl) = 0;
+ TREE_STATIC (decl) = 0;
+ DECL_EXTERNAL (decl) = 0;
+
+ /* We should never get deferred shape arrays here. We used to because of
+ frontend bugs. */
+ assert (sym->as->type != AS_DEFERRED);
+
+ switch (packed)
+ {
+ case 1:
+ GFC_DECL_PARTIAL_PACKED_ARRAY (decl) = 1;
+ break;
+
+ case 2:
+ GFC_DECL_PACKED_ARRAY (decl) = 1;
+ break;
+ }
+
+ gfc_build_qualified_array (decl, sym);
+
+ if (DECL_LANG_SPECIFIC (dummy))
+ DECL_LANG_SPECIFIC (decl) = DECL_LANG_SPECIFIC (dummy);
+ else
+ gfc_allocate_lang_decl (decl);
+
+ GFC_DECL_SAVED_DESCRIPTOR (decl) = dummy;
+
+ if (sym->ns->proc_name->backend_decl == current_function_decl
+ || sym->attr.contained)
+ gfc_add_decl_to_function (decl);
+ else
+ gfc_add_decl_to_parent_function (decl);
+
+ return decl;
+}
+
+
+/* Return a constant or a variable to use as a string length. Does not
+ add the decl to the current scope. */
+
+static tree
+gfc_create_string_length (gfc_symbol * sym)
+{
+ tree length;
+
+ assert (sym->ts.cl);
+ gfc_conv_const_charlen (sym->ts.cl);
+
+ if (sym->ts.cl->backend_decl == NULL_TREE)
+ {
+ char name[GFC_MAX_MANGLED_SYMBOL_LEN + 2];
+
+ /* Also prefix the mangled name. */
+ strcpy (&name[1], sym->name);
+ name[0] = '.';
+ length = build_decl (VAR_DECL, get_identifier (name),
+ gfc_strlen_type_node);
+ DECL_ARTIFICIAL (length) = 1;
+ TREE_USED (length) = 1;
+ gfc_defer_symbol_init (sym);
+ sym->ts.cl->backend_decl = length;
+ }
+
+ return sym->ts.cl->backend_decl;
+}
+
+
+/* Return the decl for a gfc_symbol, create it if it doesn't already
+ exist. */
+
+tree
+gfc_get_symbol_decl (gfc_symbol * sym)
+{
+ tree decl;
+ tree length = NULL_TREE;
+ gfc_se se;
+ int byref;
+
+ assert (sym->attr.referenced);
+
+ if (sym->ns && sym->ns->proc_name->attr.function)
+ byref = gfc_return_by_reference (sym->ns->proc_name);
+ else
+ byref = 0;
+
+ if ((sym->attr.dummy && ! sym->attr.function) || (sym->attr.result && byref))
+ {
+ /* Return via extra parameter. */
+ if (sym->attr.result && byref
+ && !sym->backend_decl)
+ {
+ sym->backend_decl =
+ DECL_ARGUMENTS (sym->ns->proc_name->backend_decl);
+ }
+
+ /* Dummy variables should already have been created. */
+ assert (sym->backend_decl);
+
+ /* Create a character length variable. */
+ if (sym->ts.type == BT_CHARACTER)
+ {
+ if (sym->ts.cl->backend_decl == NULL_TREE)
+ {
+ length = gfc_create_string_length (sym);
+ if (TREE_CODE (length) != INTEGER_CST)
+ {
+ gfc_finish_var_decl (length, sym);
+ gfc_defer_symbol_init (sym);
+ }
+ }
+ }
+
+ /* Use a copy of the descriptor for dummy arrays. */
+ if (sym->attr.dimension && !TREE_USED (sym->backend_decl))
+ {
+ sym->backend_decl =
+ gfc_build_dummy_array_decl (sym, sym->backend_decl);
+ }
+
+ TREE_USED (sym->backend_decl) = 1;
+ return sym->backend_decl;
+ }
+
+ if (sym->backend_decl)
+ return sym->backend_decl;
+
+ if (sym->attr.entry)
+ gfc_todo_error ("alternate entry");
+
+ /* Catch function declarations. Only used for actual parameters. */
+ if (sym->attr.flavor == FL_PROCEDURE)
+ {
+ decl = gfc_get_extern_function_decl (sym);
+ return decl;
+ }
+
+ if (sym->attr.intrinsic)
+ internal_error ("intrinsic variable which isn't a procedure");
+
+ /* Create string length decl first so that they can be used in the
+ type declaration. */
+ if (sym->ts.type == BT_CHARACTER)
+ length = gfc_create_string_length (sym);
+
+ /* Create the decl for the variable. */
+ decl = build_decl (VAR_DECL, gfc_sym_identifier (sym), gfc_sym_type (sym));
+
+ /* Symbols from modules have its assembler name should be mangled.
+ This is done here rather than in gfc_finish_var_decl because it
+ is different for string length variables. */
+ if (sym->module[0])
+ SET_DECL_ASSEMBLER_NAME (decl, gfc_sym_mangled_identifier (sym));
+
+ if (sym->attr.dimension)
+ {
+ /* Create variables to hold the non-constant bits of array info. */
+ gfc_build_qualified_array (decl, sym);
+
+ /* Remember this variable for allocation/cleanup. */
+ gfc_defer_symbol_init (sym);
+
+ if ((sym->attr.allocatable || !sym->attr.dummy) && !sym->attr.pointer)
+ GFC_DECL_PACKED_ARRAY (decl) = 1;
+ }
+
+ gfc_finish_var_decl (decl, sym);
+
+ if (sym->attr.assign)
+ {
+ gfc_allocate_lang_decl (decl);
+ GFC_DECL_ASSIGN (decl) = 1;
+ length = gfc_create_var (gfc_strlen_type_node, sym->name);
+ GFC_DECL_STRING_LEN (decl) = length;
+ GFC_DECL_ASSIGN_ADDR (decl) = gfc_create_var (pvoid_type_node, sym->name);
+ /* TODO: Need to check we don't change TREE_STATIC (decl) later. */
+ TREE_STATIC (length) = TREE_STATIC (decl);
+ /* STRING_LENGTH is also used as flag. Less than -1 means that
+ ASSIGN_ADDR can not be used. Equal -1 means that ASSIGN_ADDR is the
+ target label's address. Other value is the length of format string
+ and ASSIGN_ADDR is the address of format string. */
+ DECL_INITIAL (length) = build_int_2 (-2, -1);
+ }
+
+ /* TODO: Initialization of pointer variables. */
+ switch (sym->ts.type)
+ {
+ case BT_CHARACTER:
+ /* Character variables need special handling. */
+ gfc_allocate_lang_decl (decl);
+
+ if (TREE_CODE (length) == INTEGER_CST)
+ {
+ /* Static initializer for string scalars.
+ Initialization of string arrays is handled elsewhere. */
+ if (sym->value && sym->attr.dimension == 0)
+ {
+ assert (TREE_STATIC (decl));
+ if (sym->attr.pointer)
+ gfc_todo_error ("initialization of character pointers");
+ DECL_INITIAL (decl) = gfc_conv_string_init (length, sym->value);
+ }
+ }
+ else
+ {
+ char name[GFC_MAX_MANGLED_SYMBOL_LEN + 2];
+
+ if (sym->module[0])
+ {
+ /* Also prefix the mangled name for symbols from modules. */
+ strcpy (&name[1], sym->name);
+ name[0] = '.';
+ strcpy (&name[1],
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (length)));
+ SET_DECL_ASSEMBLER_NAME (decl, get_identifier (name));
+ }
+ gfc_finish_var_decl (length, sym);
+ assert (!sym->value);
+ }
+ break;
+
+ case BT_DERIVED:
+ if (sym->value && ! (sym->attr.use_assoc || sym->attr.dimension))
+ {
+ gfc_init_se (&se, NULL);
+ gfc_conv_structure (&se, sym->value, 1);
+ DECL_INITIAL (decl) = se.expr;
+ }
+ break;
+
+ default:
+ /* Static initializers for SAVEd variables. Arrays have already been
+ remembered. Module variables are initialized when the module is
+ loaded. */
+ if (sym->value && ! (sym->attr.use_assoc || sym->attr.dimension))
+ {
+ assert (TREE_STATIC (decl));
+ gfc_init_se (&se, NULL);
+ gfc_conv_constant (&se, sym->value);
+ DECL_INITIAL (decl) = se.expr;
+ }
+ break;
+ }
+ sym->backend_decl = decl;
+
+ return decl;
+}
+
+
+/* Get a basic decl for an external function. */
+
+tree
+gfc_get_extern_function_decl (gfc_symbol * sym)
+{
+ tree type;
+ tree fndecl;
+ gfc_expr e;
+ gfc_intrinsic_sym *isym;
+ gfc_expr argexpr;
+ char s[GFC_MAX_SYMBOL_LEN];
+ tree name;
+ tree mangled_name;
+
+ if (sym->backend_decl)
+ return sym->backend_decl;
+
+ if (sym->attr.intrinsic)
+ {
+ /* Call the resolution function to get the actual name. This is
+ a nasty hack which relies on the resolution functions only looking
+ at the first argument. We pass NULL for the second argument
+ otherwise things like AINT get confused. */
+ isym = gfc_find_function (sym->name);
+ assert (isym->resolve.f0 != NULL);
+
+ memset (&e, 0, sizeof (e));
+ e.expr_type = EXPR_FUNCTION;
+
+ memset (&argexpr, 0, sizeof (argexpr));
+ assert (isym->formal);
+ argexpr.ts = isym->formal->ts;
+
+ if (isym->formal->next == NULL)
+ isym->resolve.f1 (&e, &argexpr);
+ else
+ {
+ /* All specific intrinsics take one or two arguments. */
+ assert (isym->formal->next->next == NULL);
+ isym->resolve.f2 (&e, &argexpr, NULL);
+ }
+ sprintf (s, "specific%s", e.value.function.name);
+ name = get_identifier (s);
+ mangled_name = name;
+ }
+ else
+ {
+ name = gfc_sym_identifier (sym);
+ mangled_name = gfc_sym_mangled_function_id (sym);
+ }
+
+ type = gfc_get_function_type (sym);
+ fndecl = build_decl (FUNCTION_DECL, name, type);
+
+ SET_DECL_ASSEMBLER_NAME (fndecl, mangled_name);
+ /* If the return type is a pointer, avoid alias issues by setting
+ DECL_IS_MALLOC to nonzero. This means that the function should be
+ treated as if it were a malloc, meaning it returns a pointer that
+ is not an alias. */
+ if (POINTER_TYPE_P (type))
+ DECL_IS_MALLOC (fndecl) = 1;
+
+ /* Set the context of this decl. */
+ if (0 && sym->ns && sym->ns->proc_name)
+ {
+ /* TODO: Add external decls to the appropriate scope. */
+ DECL_CONTEXT (fndecl) = sym->ns->proc_name->backend_decl;
+ }
+ else
+ {
+ /* Global declaration, eg. intrinsic subroutine. */
+ DECL_CONTEXT (fndecl) = NULL_TREE;
+ }
+
+ DECL_EXTERNAL (fndecl) = 1;
+
+ /* This specifies if a function is globaly addressable, ie. it is
+ the opposite of declaring static in C. */
+ TREE_PUBLIC (fndecl) = 1;
+
+ /* Set attributes for PURE functions. A call to PURE function in the
+ Fortran 95 sense is both pure and without side effects in the C
+ sense. */
+ if (sym->attr.pure || sym->attr.elemental)
+ {
+ DECL_IS_PURE (fndecl) = 1;
+/* TODO: check if pure/elemental procedures can have INTENT(OUT) parameters.
+ TREE_SIDE_EFFECTS (fndecl) = 0;*/
+ }
+
+ sym->backend_decl = fndecl;
+
+ if (DECL_CONTEXT (fndecl) == NULL_TREE)
+ pushdecl_top_level (fndecl);
+
+ return fndecl;
+}
+
+
+/* Create a declaration for a procedure. For external functions (in the C
+ sense) use gfc_get_extern_function_decl. */
+
+void
+gfc_build_function_decl (gfc_symbol * sym)
+{
+ tree fndecl, type, result_decl, typelist, arglist;
+ tree length;
+ symbol_attribute attr;
+ gfc_formal_arglist *f;
+
+ assert (!sym->backend_decl);
+ assert (!sym->attr.external);
+
+ /* Allow only one nesting level. Allow public declarations. */
+ assert (current_function_decl == NULL_TREE
+ || DECL_CONTEXT (current_function_decl) == NULL_TREE);
+
+ type = gfc_get_function_type (sym);
+ fndecl = build_decl (FUNCTION_DECL, gfc_sym_identifier (sym), type);
+
+ /* Perform name mangling if this is a top level or module procedure. */
+ if (current_function_decl == NULL_TREE)
+ SET_DECL_ASSEMBLER_NAME (fndecl, gfc_sym_mangled_function_id (sym));
+
+ /* Figure out the return type of the declared function, and build a
+ RESULT_DECL for it. If this is subroutine with alternate
+ returns, build a RESULT_DECL for it. */
+ attr = sym->attr;
+
+ result_decl = NULL_TREE;
+ /* TODO: Shouldn't this just be TREE_TYPE (TREE_TYPE (fndecl)). */
+ if (attr.function)
+ {
+ if (gfc_return_by_reference (sym))
+ type = void_type_node;
+ else
+ {
+ if (sym->result != sym)
+ result_decl = gfc_sym_identifier (sym->result);
+
+ type = TREE_TYPE (TREE_TYPE (fndecl));
+ }
+ }
+ else
+ {
+ /* Look for alternate return placeholders. */
+ int has_alternate_returns = 0;
+ for (f = sym->formal; f; f = f->next)
+ {
+ if (f->sym == NULL)
+ {
+ has_alternate_returns = 1;
+ break;
+ }
+ }
+
+ if (has_alternate_returns)
+ type = integer_type_node;
+ else
+ type = void_type_node;
+ }
+
+ result_decl = build_decl (RESULT_DECL, result_decl, type);
+ DECL_CONTEXT (result_decl) = fndecl;
+ DECL_RESULT (fndecl) = result_decl;
+
+ /* Don't call layout_decl for a RESULT_DECL.
+ layout_decl (result_decl, 0); */
+
+ /* If the return type is a pointer, avoid alias issues by setting
+ DECL_IS_MALLOC to nonzero. This means that the function should be
+ treated as if it were a malloc, meaning it returns a pointer that
+ is not an alias. */
+ if (POINTER_TYPE_P (type))
+ DECL_IS_MALLOC (fndecl) = 1;
+
+ /* Set up all attributes for the function. */
+ DECL_CONTEXT (fndecl) = current_function_decl;
+ DECL_EXTERNAL (fndecl) = 0;
+
+ /* This specifies if a function is globaly addressable, ie. it is
+ the opposite of decalring static in C. */
+ if (DECL_CONTEXT (fndecl) == NULL_TREE || attr.external)
+ TREE_PUBLIC (fndecl) = 1;
+
+ /* TREE_STATIC means the function body is defined here. */
+ if (!attr.external)
+ TREE_STATIC (fndecl) = 1;
+
+ /* Set attributes for PURE functions. A call to PURE function in the
+ Fortran 95 sense is both pure and without side effects in the C
+ sense. */
+ if (attr.pure || attr.elemental)
+ {
+ DECL_IS_PURE (fndecl) = 1;
+ TREE_SIDE_EFFECTS (fndecl) = 0;
+ }
+
+ /* Layout the function declaration and put it in the binding level
+ of the current function. */
+ if (!attr.external)
+ {
+ tree parm;
+
+ pushdecl (fndecl);
+ /* Build formal argument list. Make sure that their TREE_CONTEXT is
+ the new FUNCTION_DECL node. */
+ current_function_decl = fndecl;
+ arglist = NULL_TREE;
+ typelist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
+ if (gfc_return_by_reference (sym))
+ {
+ type = TREE_VALUE (typelist);
+ parm = build_decl (PARM_DECL, get_identifier ("__result"), type);
+
+ DECL_CONTEXT (parm) = fndecl;
+ DECL_ARG_TYPE (parm) = type;
+ TREE_READONLY (parm) = 1;
+ gfc_finish_decl (parm, NULL_TREE);
+
+ arglist = chainon (arglist, parm);
+ typelist = TREE_CHAIN (typelist);
+
+ if (sym->ts.type == BT_CHARACTER)
+ {
+ gfc_allocate_lang_decl (parm);
+
+ /* Length of character result */
+ type = TREE_VALUE (typelist);
+ assert (type == gfc_strlen_type_node);
+
+ length = build_decl (PARM_DECL,
+ get_identifier (".__result"),
+ type);
+ if (!sym->ts.cl->length)
+ {
+ sym->ts.cl->backend_decl = length;
+ TREE_USED (length) = 1;
+ }
+ assert (TREE_CODE (length) == PARM_DECL);
+ arglist = chainon (arglist, length);
+ typelist = TREE_CHAIN (typelist);
+ DECL_CONTEXT (length) = fndecl;
+ DECL_ARG_TYPE (length) = type;
+ TREE_READONLY (length) = 1;
+ gfc_finish_decl (length, NULL_TREE);
+ }
+ }
+
+ for (f = sym->formal; f; f = f->next)
+ {
+ if (f->sym != NULL) /* ignore alternate returns. */
+ {
+ length = NULL_TREE;
+
+ type = TREE_VALUE (typelist);
+
+ /* Build a the argument declaration. */
+ parm = build_decl (PARM_DECL,
+ gfc_sym_identifier (f->sym), type);
+
+ /* Fill in arg stuff. */
+ DECL_CONTEXT (parm) = fndecl;
+ DECL_ARG_TYPE (parm) = type;
+ DECL_ARG_TYPE_AS_WRITTEN (parm) = type;
+ /* All implementation args are read-only. */
+ TREE_READONLY (parm) = 1;
+
+ gfc_finish_decl (parm, NULL_TREE);
+
+ f->sym->backend_decl = parm;
+
+ arglist = chainon (arglist, parm);
+ typelist = TREE_CHAIN (typelist);
+ }
+ }
+
+ /* Add the hidden string length parameters. */
+ parm = arglist;
+ for (f = sym->formal; f; f = f->next)
+ {
+ char name[GFC_MAX_SYMBOL_LEN + 2];
+ /* Ignore alternate returns. */
+ if (f->sym == NULL)
+ continue;
+
+ if (f->sym->ts.type != BT_CHARACTER)
+ continue;
+
+ parm = f->sym->backend_decl;
+ type = TREE_VALUE (typelist);
+ assert (type == gfc_strlen_type_node);
+
+ strcpy (&name[1], f->sym->name);
+ name[0] = '_';
+ length = build_decl (PARM_DECL, get_identifier (name), type);
+
+ arglist = chainon (arglist, length);
+ DECL_CONTEXT (length) = fndecl;
+ DECL_ARG_TYPE (length) = type;
+ TREE_READONLY (length) = 1;
+ gfc_finish_decl (length, NULL_TREE);
+
+ /* TODO: Check string lengths when -fbounds-check. */
+
+ /* Use the passed value for assumed length variables. */
+ if (!f->sym->ts.cl->length)
+ {
+ TREE_USED (length) = 1;
+ f->sym->ts.cl->backend_decl = length;
+ }
+
+ parm = TREE_CHAIN (parm);
+ typelist = TREE_CHAIN (typelist);
+ }
+
+ assert (TREE_VALUE (typelist) == void_type_node);
+ DECL_ARGUMENTS (fndecl) = arglist;
+
+ /* Restore the old context. */
+ current_function_decl = DECL_CONTEXT (fndecl);
+ }
+ sym->backend_decl = fndecl;
+}
+
+
+/* Return the decl used to hold the function return value. */
+
+tree
+gfc_get_fake_result_decl (gfc_symbol * sym)
+{
+ tree decl;
+ tree length;
+
+ char name[GFC_MAX_SYMBOL_LEN + 10];
+
+ if (current_fake_result_decl != NULL_TREE)
+ return current_fake_result_decl;
+
+ /* Only when gfc_get_fake_result_decl is called by gfc_trans_return,
+ sym is NULL. */
+ if (!sym)
+ return NULL_TREE;
+
+ if (sym->ts.type == BT_CHARACTER
+ && !sym->ts.cl->backend_decl)
+ {
+ length = gfc_create_string_length (sym);
+ gfc_finish_var_decl (length, sym);
+ }
+
+ if (gfc_return_by_reference (sym))
+ {
+ decl = DECL_ARGUMENTS (sym->backend_decl);
+
+ TREE_USED (decl) = 1;
+ if (sym->as)
+ decl = gfc_build_dummy_array_decl (sym, decl);
+ }
+ else
+ {
+ sprintf (name, "__result_%.20s",
+ IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
+
+ decl = build_decl (VAR_DECL, get_identifier (name),
+ TREE_TYPE (TREE_TYPE (current_function_decl)));
+
+ DECL_ARTIFICIAL (decl) = 1;
+ DECL_EXTERNAL (decl) = 0;
+ TREE_PUBLIC (decl) = 0;
+ TREE_USED (decl) = 1;
+
+ layout_decl (decl, 0);
+
+ gfc_add_decl_to_function (decl);
+ }
+
+ current_fake_result_decl = decl;
+
+ return decl;
+}
+
+
+/* Builds a function decl. The remaining parameters are the types of the
+ function arguments. Negative nargs indicates a varargs function. */
+
+tree
+gfc_build_library_function_decl (tree name, tree rettype, int nargs, ...)
+{
+ tree arglist;
+ tree argtype;
+ tree fntype;
+ tree fndecl;
+ va_list p;
+ int n;
+
+ /* Library functions must be declared with global scope. */
+ assert (current_function_decl == NULL_TREE);
+
+ va_start (p, nargs);
+
+
+ /* Create a list of the argument types. */
+ for (arglist = NULL_TREE, n = abs (nargs); n > 0; n--)
+ {
+ argtype = va_arg (p, tree);
+ arglist = gfc_chainon_list (arglist, argtype);
+ }
+
+ if (nargs >= 0)
+ {
+ /* Terminate the list. */
+ arglist = gfc_chainon_list (arglist, void_type_node);
+ }
+
+ /* Build the function type and decl. */
+ fntype = build_function_type (rettype, arglist);
+ fndecl = build_decl (FUNCTION_DECL, name, fntype);
+
+ /* Mark this decl as external. */
+ DECL_EXTERNAL (fndecl) = 1;
+ TREE_PUBLIC (fndecl) = 1;
+
+ va_end (p);
+
+ pushdecl (fndecl);
+
+ rest_of_decl_compilation (fndecl, NULL, 1, 0);
+
+ return fndecl;
+}
+
+static void
+gfc_build_intrinsic_function_decls (void)
+{
+ /* String functions. */
+ gfor_fndecl_copy_string =
+ gfc_build_library_function_decl (get_identifier (PREFIX("copy_string")),
+ void_type_node,
+ 4,
+ gfc_strlen_type_node, pchar_type_node,
+ gfc_strlen_type_node, pchar_type_node);
+
+ gfor_fndecl_compare_string =
+ gfc_build_library_function_decl (get_identifier (PREFIX("compare_string")),
+ gfc_int4_type_node,
+ 4,
+ gfc_strlen_type_node, pchar_type_node,
+ gfc_strlen_type_node, pchar_type_node);
+
+ gfor_fndecl_concat_string =
+ gfc_build_library_function_decl (get_identifier (PREFIX("concat_string")),
+ void_type_node,
+ 6,
+ gfc_strlen_type_node, pchar_type_node,
+ gfc_strlen_type_node, pchar_type_node,
+ gfc_strlen_type_node, pchar_type_node);
+
+ gfor_fndecl_string_len_trim =
+ gfc_build_library_function_decl (get_identifier (PREFIX("string_len_trim")),
+ gfc_int4_type_node,
+ 2, gfc_strlen_type_node,
+ pchar_type_node);
+
+ gfor_fndecl_string_index =
+ gfc_build_library_function_decl (get_identifier (PREFIX("string_index")),
+ gfc_int4_type_node,
+ 5, gfc_strlen_type_node, pchar_type_node,
+ gfc_strlen_type_node, pchar_type_node,
+ gfc_logical4_type_node);
+
+ gfor_fndecl_string_scan =
+ gfc_build_library_function_decl (get_identifier (PREFIX("string_scan")),
+ gfc_int4_type_node,
+ 5, gfc_strlen_type_node, pchar_type_node,
+ gfc_strlen_type_node, pchar_type_node,
+ gfc_logical4_type_node);
+
+ gfor_fndecl_string_verify =
+ gfc_build_library_function_decl (get_identifier (PREFIX("string_verify")),
+ gfc_int4_type_node,
+ 5, gfc_strlen_type_node, pchar_type_node,
+ gfc_strlen_type_node, pchar_type_node,
+ gfc_logical4_type_node);
+
+ gfor_fndecl_string_trim =
+ gfc_build_library_function_decl (get_identifier (PREFIX("string_trim")),
+ void_type_node,
+ 4,
+ build_pointer_type (gfc_strlen_type_node),
+ ppvoid_type_node,
+ gfc_strlen_type_node,
+ pchar_type_node);
+
+ gfor_fndecl_string_repeat =
+ gfc_build_library_function_decl (get_identifier (PREFIX("string_repeat")),
+ void_type_node,
+ 4,
+ pchar_type_node,
+ gfc_strlen_type_node,
+ pchar_type_node,
+ gfc_int4_type_node);
+
+ gfor_fndecl_adjustl =
+ gfc_build_library_function_decl (get_identifier (PREFIX("adjustl")),
+ void_type_node,
+ 3,
+ pchar_type_node,
+ gfc_strlen_type_node, pchar_type_node);
+
+ gfor_fndecl_adjustr =
+ gfc_build_library_function_decl (get_identifier (PREFIX("adjustr")),
+ void_type_node,
+ 3,
+ pchar_type_node,
+ gfc_strlen_type_node, pchar_type_node);
+
+ gfor_fndecl_si_kind =
+ gfc_build_library_function_decl (get_identifier ("selected_int_kind"),
+ gfc_int4_type_node,
+ 1,
+ pvoid_type_node);
+
+ gfor_fndecl_sr_kind =
+ gfc_build_library_function_decl (get_identifier ("selected_real_kind"),
+ gfc_int4_type_node,
+ 2, pvoid_type_node,
+ pvoid_type_node);
+
+
+ /* Power functions. */
+ gfor_fndecl_math_powf =
+ gfc_build_library_function_decl (get_identifier ("powf"),
+ gfc_real4_type_node,
+ 1, gfc_real4_type_node);
+ gfor_fndecl_math_pow =
+ gfc_build_library_function_decl (get_identifier ("pow"),
+ gfc_real8_type_node,
+ 1, gfc_real8_type_node);
+ gfor_fndecl_math_cpowf =
+ gfc_build_library_function_decl (get_identifier ("cpowf"),
+ gfc_complex4_type_node,
+ 1, gfc_complex4_type_node);
+ gfor_fndecl_math_cpow =
+ gfc_build_library_function_decl (get_identifier ("cpow"),
+ gfc_complex8_type_node,
+ 1, gfc_complex8_type_node);
+ gfor_fndecl_math_cabsf =
+ gfc_build_library_function_decl (get_identifier ("cabsf"),
+ gfc_real4_type_node,
+ 1, gfc_complex4_type_node);
+ gfor_fndecl_math_cabs =
+ gfc_build_library_function_decl (get_identifier ("cabs"),
+ gfc_real8_type_node,
+ 1, gfc_complex8_type_node);
+ gfor_fndecl_math_sign4 =
+ gfc_build_library_function_decl (get_identifier ("copysignf"),
+ gfc_real4_type_node,
+ 1, gfc_real4_type_node);
+ gfor_fndecl_math_sign8 =
+ gfc_build_library_function_decl (get_identifier ("copysign"),
+ gfc_real8_type_node,
+ 1, gfc_real8_type_node);
+ gfor_fndecl_math_ishftc4 =
+ gfc_build_library_function_decl (get_identifier (PREFIX("ishftc4")),
+ gfc_int4_type_node,
+ 3, gfc_int4_type_node,
+ gfc_int4_type_node, gfc_int4_type_node);
+ gfor_fndecl_math_ishftc8 =
+ gfc_build_library_function_decl (get_identifier (PREFIX("ishftc8")),
+ gfc_int8_type_node,
+ 3, gfc_int8_type_node,
+ gfc_int8_type_node, gfc_int8_type_node);
+ gfor_fndecl_math_exponent4 =
+ gfc_build_library_function_decl (get_identifier (PREFIX("exponent_r4")),
+ gfc_int4_type_node,
+ 1, gfc_real4_type_node);
+ gfor_fndecl_math_exponent8 =
+ gfc_build_library_function_decl (get_identifier (PREFIX("exponent_r8")),
+ gfc_int4_type_node,
+ 1, gfc_real8_type_node);
+
+ /* Other functions. */
+ gfor_fndecl_size0 =
+ gfc_build_library_function_decl (get_identifier (PREFIX("size0")),
+ gfc_array_index_type,
+ 1, pvoid_type_node);
+ gfor_fndecl_size1 =
+ gfc_build_library_function_decl (get_identifier (PREFIX("size1")),
+ gfc_array_index_type,
+ 2, pvoid_type_node,
+ gfc_array_index_type);
+}
+
+
+/* Make prototypes for runtime library functions. */
+
+void
+gfc_build_builtin_function_decls (void)
+{
+ gfor_fndecl_internal_malloc =
+ gfc_build_library_function_decl (get_identifier (PREFIX("internal_malloc")),
+ pvoid_type_node, 1, gfc_int4_type_node);
+
+ gfor_fndecl_internal_malloc64 =
+ gfc_build_library_function_decl (get_identifier
+ (PREFIX("internal_malloc64")),
+ pvoid_type_node, 1, gfc_int8_type_node);
+
+ gfor_fndecl_internal_free =
+ gfc_build_library_function_decl (get_identifier (PREFIX("internal_free")),
+ void_type_node, 1, pvoid_type_node);
+
+ gfor_fndecl_allocate =
+ gfc_build_library_function_decl (get_identifier (PREFIX("allocate")),
+ void_type_node, 2, ppvoid_type_node,
+ gfc_int4_type_node);
+
+ gfor_fndecl_allocate64 =
+ gfc_build_library_function_decl (get_identifier (PREFIX("allocate64")),
+ void_type_node, 2, ppvoid_type_node,
+ gfc_int8_type_node);
+
+ gfor_fndecl_deallocate =
+ gfc_build_library_function_decl (get_identifier (PREFIX("deallocate")),
+ void_type_node, 1, ppvoid_type_node);
+
+ gfor_fndecl_stop_numeric =
+ gfc_build_library_function_decl (get_identifier (PREFIX("stop_numeric")),
+ void_type_node, 1, gfc_int4_type_node);
+
+ gfor_fndecl_stop_string =
+ gfc_build_library_function_decl (get_identifier (PREFIX("stop_string")),
+ void_type_node, 2, pchar_type_node,
+ gfc_int4_type_node);
+
+ gfor_fndecl_pause_numeric =
+ gfc_build_library_function_decl (get_identifier (PREFIX("pause_numeric")),
+ void_type_node, 1, gfc_int4_type_node);
+
+ gfor_fndecl_pause_string =
+ gfc_build_library_function_decl (get_identifier (PREFIX("pause_string")),
+ void_type_node, 2, pchar_type_node,
+ gfc_int4_type_node);
+
+ gfor_fndecl_select_string =
+ gfc_build_library_function_decl (get_identifier (PREFIX("select_string")),
+ pvoid_type_node, 0);
+
+ gfor_fndecl_runtime_error =
+ gfc_build_library_function_decl (get_identifier (PREFIX("runtime_error")),
+ void_type_node,
+ 3,
+ pchar_type_node, pchar_type_node,
+ gfc_int4_type_node);
+
+ gfor_fndecl_in_pack = gfc_build_library_function_decl (
+ get_identifier (PREFIX("internal_pack")),
+ pvoid_type_node, 1, pvoid_type_node);
+
+ gfor_fndecl_in_unpack = gfc_build_library_function_decl (
+ get_identifier (PREFIX("internal_unpack")),
+ pvoid_type_node, 1, pvoid_type_node);
+
+ gfor_fndecl_associated =
+ gfc_build_library_function_decl (
+ get_identifier (PREFIX("associated")),
+ gfc_logical4_type_node,
+ 2,
+ ppvoid_type_node,
+ ppvoid_type_node);
+
+ gfc_build_intrinsic_function_decls ();
+ gfc_build_intrinsic_lib_fndecls ();
+ gfc_build_io_library_fndecls ();
+}
+
+
+/* Exaluate the length of dummy character variables. */
+
+static tree
+gfc_trans_dummy_character (gfc_charlen * cl, tree fnbody)
+{
+ stmtblock_t body;
+
+ gfc_finish_decl (cl->backend_decl, NULL_TREE);
+
+ gfc_start_block (&body);
+
+ /* Evaluate the string length expression. */
+ gfc_trans_init_string_length (cl, &body);
+
+ gfc_add_expr_to_block (&body, fnbody);
+ return gfc_finish_block (&body);
+}
+
+
+/* Allocate and cleanup an automatic character variable. */
+
+static tree
+gfc_trans_auto_character_variable (gfc_symbol * sym, tree fnbody)
+{
+ stmtblock_t body;
+ tree decl;
+ tree args;
+ tree tmp;
+
+ assert (sym->backend_decl);
+ assert (sym->ts.cl && sym->ts.cl->length);
+
+ gfc_start_block (&body);
+
+ /* Evaluate the string length expression. */
+ gfc_trans_init_string_length (sym->ts.cl, &body);
+
+ decl = sym->backend_decl;
+
+ DECL_DEFER_OUTPUT (decl) = 1;
+
+ /* Generate code to allocate the automatic variable. It will be freed
+ automatically. */
+ tmp = gfc_build_addr_expr (NULL, decl);
+ args = gfc_chainon_list (NULL_TREE, tmp);
+ args = gfc_chainon_list (args, sym->ts.cl->backend_decl);
+ tmp = gfc_build_function_call (built_in_decls[BUILT_IN_STACK_ALLOC], args);
+ gfc_add_expr_to_block (&body, tmp);
+ gfc_add_expr_to_block (&body, fnbody);
+ return gfc_finish_block (&body);
+}
+
+
+/* Generate function entry and exit code, and add it to the function body.
+ This includes:
+ Allocation and initialisation of array variables.
+ Allocation of character string variables.
+ Initialization and possibly repacking of dummy arrays. */
+
+static tree
+gfc_trans_deferred_vars (gfc_symbol * proc_sym, tree fnbody)
+{
+ locus loc;
+ gfc_symbol *sym;
+
+ /* Deal with implicit return variables. Explicit return variables will
+ already have been added. */
+ if (gfc_return_by_reference (proc_sym) && proc_sym->result == proc_sym)
+ {
+ if (!current_fake_result_decl)
+ {
+ warning ("Function does not return a value");
+ return fnbody;
+ }
+
+ if (proc_sym->as)
+ {
+ fnbody = gfc_trans_dummy_array_bias (proc_sym,
+ current_fake_result_decl,
+ fnbody);
+ }
+ else if (proc_sym->ts.type == BT_CHARACTER)
+ {
+ if (TREE_CODE (proc_sym->ts.cl->backend_decl) == VAR_DECL)
+ fnbody = gfc_trans_dummy_character (proc_sym->ts.cl, fnbody);
+ }
+ else
+ gfc_todo_error ("Deferred non-array return by reference");
+ }
+
+ for (sym = proc_sym->tlink; sym != proc_sym; sym = sym->tlink)
+ {
+ if (sym->attr.dimension)
+ {
+ switch (sym->as->type)
+ {
+ case AS_EXPLICIT:
+ if (sym->attr.dummy || sym->attr.result)
+ fnbody =
+ gfc_trans_dummy_array_bias (sym, sym->backend_decl, fnbody);
+ else if (sym->attr.pointer || sym->attr.allocatable)
+ {
+ if (TREE_STATIC (sym->backend_decl))
+ gfc_trans_static_array_pointer (sym);
+ else
+ fnbody = gfc_trans_deferred_array (sym, fnbody);
+ }
+ else
+ {
+ gfc_get_backend_locus (&loc);
+ gfc_set_backend_locus (&sym->declared_at);
+ fnbody = gfc_trans_auto_array_allocation (sym->backend_decl,
+ sym, fnbody);
+ gfc_set_backend_locus (&loc);
+ }
+ break;
+
+ case AS_ASSUMED_SIZE:
+ /* Must be a dummy parameter. */
+ assert (sym->attr.dummy);
+
+ /* We should always pass assumed size arrays the g77 way. */
+ assert (TREE_CODE (sym->backend_decl) == PARM_DECL);
+ fnbody = gfc_trans_g77_array (sym, fnbody);
+ break;
+
+ case AS_ASSUMED_SHAPE:
+ /* Must be a dummy parameter. */
+ assert (sym->attr.dummy);
+
+ fnbody = gfc_trans_dummy_array_bias (sym, sym->backend_decl,
+ fnbody);
+ break;
+
+ case AS_DEFERRED:
+ fnbody = gfc_trans_deferred_array (sym, fnbody);
+ break;
+
+ default:
+ abort ();
+ }
+ }
+ else if (sym->ts.type == BT_CHARACTER)
+ {
+ gfc_get_backend_locus (&loc);
+ gfc_set_backend_locus (&sym->declared_at);
+ if (sym->attr.dummy || sym->attr.result)
+ fnbody = gfc_trans_dummy_character (sym->ts.cl, fnbody);
+ else
+ fnbody = gfc_trans_auto_character_variable (sym, fnbody);
+ gfc_set_backend_locus (&loc);
+ }
+ else
+ abort ();
+ }
+
+ return fnbody;
+}
+
+
+/* Output an initialized decl for a module variable. */
+
+static void
+gfc_create_module_variable (gfc_symbol * sym)
+{
+ tree decl;
+ gfc_se se;
+
+ /* Only output symbols from this module. */
+ if (sym->ns != module_namespace)
+ {
+ /* I don't think this should ever happen. */
+ internal_error ("module symbol %s in wrong namespace", sym->name);
+ }
+
+ /* Don't ouptut symbols from common blocks. */
+ if (sym->attr.common)
+ return;
+
+ /* Only output variables and array valued parametes. */
+ if (sym->attr.flavor != FL_VARIABLE
+ && (sym->attr.flavor != FL_PARAMETER || sym->attr.dimension == 0))
+ return;
+
+ /* Don't generate variables from other modules. */
+ if (sym->attr.use_assoc)
+ return;
+
+ if (sym->backend_decl)
+ internal_error ("backend decl for module variable %s already exists",
+ sym->name);
+
+ /* We always want module variables to be created. */
+ sym->attr.referenced = 1;
+ /* Create the decl. */
+ decl = gfc_get_symbol_decl (sym);
+
+ /* We want to allocate storage for this variable. */
+ TREE_STATIC (decl) = 1;
+
+ if (sym->attr.dimension)
+ {
+ assert (sym->attr.pointer || sym->attr.allocatable
+ || GFC_ARRAY_TYPE_P (TREE_TYPE (sym->backend_decl)));
+ if (sym->attr.pointer || sym->attr.allocatable)
+ gfc_trans_static_array_pointer (sym);
+ else
+ gfc_trans_auto_array_allocation (sym->backend_decl, sym, NULL_TREE);
+ }
+ else if (sym->ts.type == BT_DERIVED)
+ {
+ if (sym->value)
+ gfc_todo_error ("Initialization of derived type module variables");
+ }
+ else
+ {
+ if (sym->value)
+ {
+ gfc_init_se (&se, NULL);
+ gfc_conv_constant (&se, sym->value);
+ DECL_INITIAL (decl) = se.expr;
+ }
+ }
+
+ /* Create the variable. */
+ pushdecl (decl);
+ rest_of_decl_compilation (decl, NULL, 1, 0);
+
+ /* Also add length of strings. */
+ if (sym->ts.type == BT_CHARACTER)
+ {
+ tree length;
+
+ length = sym->ts.cl->backend_decl;
+ if (!INTEGER_CST_P (length))
+ {
+ pushdecl (length);
+ rest_of_decl_compilation (length, NULL, 1, 0);
+ }
+ }
+}
+
+
+/* Generate all the required code for module variables. */
+
+void
+gfc_generate_module_vars (gfc_namespace * ns)
+{
+ module_namespace = ns;
+
+ /* Check the frontend left the namespace in a reasonable state. */
+ assert (ns->proc_name && !ns->proc_name->tlink);
+
+ /* Create decls for all the module varuiables. */
+ gfc_traverse_ns (ns, gfc_create_module_variable);
+}
+
+static void
+gfc_generate_contained_functions (gfc_namespace * parent)
+{
+ gfc_namespace *ns;
+
+ /* We create all the prototypes before generating any code. */
+ for (ns = parent->contained; ns; ns = ns->sibling)
+ {
+ /* Skip namespaces from used modules. */
+ if (ns->parent != parent)
+ continue;
+
+ gfc_build_function_decl (ns->proc_name);
+ }
+
+ for (ns = parent->contained; ns; ns = ns->sibling)
+ {
+ /* Skip namespaces from used modules. */
+ if (ns->parent != parent)
+ continue;
+
+ gfc_generate_function_code (ns);
+ }
+}
+
+
+/* Generate decls for all local variables. We do this to ensure correct
+ handling of expressions which only appear in the specification of
+ other functions. */
+
+static void
+generate_local_decl (gfc_symbol * sym)
+{
+ if (sym->attr.flavor == FL_VARIABLE)
+ {
+ /* TODO: The frontend sometimes creates symbols for things which don't
+ actually exist. E.g. common block names and the names of formal
+ arguments. The latter are created while attempting to parse
+ the argument list as a substring reference.
+
+ The proper fix is to avoid adding these symbols in the first place.
+ For now we hack round it by ignoring anything with an unknown type.
+ */
+ if (sym->ts.type == BT_UNKNOWN)
+ return;
+
+ if (sym->attr.referenced)
+ gfc_get_symbol_decl (sym);
+ else if (sym->attr.dummy)
+ {
+ if (warn_unused_parameter)
+ warning ("unused parameter `%s'", sym->name);
+ }
+ /* warn for unused variables, but not if they're inside a common
+ block. */
+ else if (warn_unused_variable && !sym->attr.in_common)
+ warning ("unused variable `%s'", sym->name);
+ }
+}
+
+static void
+generate_local_vars (gfc_namespace * ns)
+{
+ gfc_traverse_ns (ns, generate_local_decl);
+}
+
+
+/* Finalize DECL and all nested functions with cgraph. */
+
+static void
+gfc_finalize (tree decl)
+{
+ struct cgraph_node *cgn;
+
+ cgn = cgraph_node (decl);
+ for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
+ gfc_finalize (cgn->decl);
+
+ cgraph_finalize_function (decl, false);
+}
+
+/* Generate code for a function. */
+
+void
+gfc_generate_function_code (gfc_namespace * ns)
+{
+ tree fndecl;
+ tree old_context;
+ tree decl;
+ tree tmp;
+ stmtblock_t block;
+ stmtblock_t body;
+ tree result;
+ gfc_symbol *sym;
+
+ sym = ns->proc_name;
+ /* Check that the frontend isn't still using this. */
+ assert (sym->tlink == NULL);
+
+ sym->tlink = sym;
+
+ /* Create the declaration for functions with global scope. */
+ if (!sym->backend_decl)
+ gfc_build_function_decl (ns->proc_name);
+
+ fndecl = sym->backend_decl;
+ old_context = current_function_decl;
+
+ if (old_context)
+ {
+ push_function_context ();
+ saved_parent_function_decls = saved_function_decls;
+ saved_function_decls = NULL_TREE;
+ }
+
+ /* let GCC know the current scope is this function */
+ current_function_decl = fndecl;
+
+ /* print function name on the console at compile time
+ (unless this feature was switched of by command line option "-quiet" */
+ announce_function (fndecl);
+
+ if (DECL_CONTEXT (fndecl) == NULL_TREE)
+ {
+ /* create RTL for function declaration */
+ rest_of_decl_compilation (fndecl, NULL, 1, 0);
+ }
+
+ /* create RTL for function definition */
+ make_decl_rtl (fndecl, NULL);
+
+ /* Set the line and filename. sym->decalred_at seems to point to the last
+ statement for subroutines, but it'll do for now. */
+ gfc_set_backend_locus (&sym->declared_at);
+
+ /* line and file should not be 0 */
+ init_function_start (fndecl);
+
+ /* We're in function-at-a-time mode. */
+ cfun->x_whole_function_mode_p = 1;
+
+ /* Even though we're inside a function body, we still don't want to
+ call expand_expr to calculate the size of a variable-sized array.
+ We haven't necessarily assigned RTL to all variables yet, so it's
+ not safe to try to expand expressions involving them. */
+ immediate_size_expand = 0;
+ cfun->x_dont_save_pending_sizes_p = 1;
+
+ /* Will be created as needed. */
+ current_fake_result_decl = NULL_TREE;
+
+ /* function.c requires a push at the start of the function */
+ pushlevel (0);
+
+ gfc_start_block (&block);
+
+ gfc_generate_contained_functions (ns);
+
+ /* Translate COMMON blocks. */
+ gfc_trans_common (ns);
+
+ generate_local_vars (ns);
+
+ current_function_return_label = NULL;
+
+ /* Now generate the code for the body of this function. */
+ gfc_init_block (&body);
+
+ if (TREE_TYPE (DECL_RESULT (fndecl)) != void_type_node
+ && sym->attr.subroutine)
+ {
+ tree alternate_return;
+ alternate_return = gfc_get_fake_result_decl (sym);
+ gfc_add_modify_expr (&body, alternate_return, integer_zero_node);
+ }
+
+ tmp = gfc_trans_code (ns->code);
+ gfc_add_expr_to_block (&body, tmp);
+
+ /* Add a return label if needed. */
+ if (current_function_return_label)
+ {
+ tmp = build1_v (LABEL_EXPR, current_function_return_label);
+ gfc_add_expr_to_block (&body, tmp);
+ }
+
+ tmp = gfc_finish_block (&body);
+ /* Add code to create and cleanup arrays. */
+ tmp = gfc_trans_deferred_vars (sym, tmp);
+ gfc_add_expr_to_block (&block, tmp);
+
+ if (TREE_TYPE (DECL_RESULT (fndecl)) != void_type_node)
+ {
+ if (sym->attr.subroutine ||sym == sym->result)
+ {
+ result = current_fake_result_decl;
+ current_fake_result_decl = NULL_TREE;
+ }
+ else
+ result = sym->result->backend_decl;
+
+ if (result == NULL_TREE)
+ warning ("Function return value not set");
+ else
+ {
+ /* Set the return value to the the dummy result variable. */
+ tmp = build (MODIFY_EXPR, TREE_TYPE (result),
+ DECL_RESULT (fndecl), result);
+ tmp = build_v (RETURN_EXPR, tmp);
+ gfc_add_expr_to_block (&block, tmp);
+ }
+ }
+
+ /* Add all the decls we created during processing. */
+ decl = saved_function_decls;
+ while (decl)
+ {
+ tree next;
+
+ next = TREE_CHAIN (decl);
+ TREE_CHAIN (decl) = NULL_TREE;
+ pushdecl (decl);
+ decl = next;
+ }
+ saved_function_decls = NULL_TREE;
+
+ DECL_SAVED_TREE (fndecl) = gfc_finish_block (&block);
+
+ /* Finish off this function and send it for code generation. */
+ poplevel (1, 0, 1);
+ BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
+
+ /* Output the GENERIC tree. */
+ dump_function (TDI_original, fndecl);
+
+ /* Store the end of the function, so that we get good line number
+ info for the epilogue. */
+ cfun->function_end_locus = input_location;
+
+ /* We're leaving the context of this function, so zap cfun.
+ It's still in DECL_STRUCT_FUNCTION, and we'll restore it in
+ tree_rest_of_compilation. */
+ cfun = NULL;
+
+ if (old_context)
+ {
+ pop_function_context ();
+ saved_function_decls = saved_parent_function_decls;
+ }
+ current_function_decl = old_context;
+
+ if (decl_function_context (fndecl))
+ {
+ /* Register this function with cgraph just far enough to get it
+ added to our parent's nested function list. */
+ (void) cgraph_node (fndecl);
+
+ /* Lowering nested functions requires gimple input. */
+ gimplify_function_tree (fndecl);
+ }
+ else
+ {
+ if (cgraph_node (fndecl)->nested)
+ {
+ gimplify_function_tree (fndecl);
+ lower_nested_functions (fndecl);
+ }
+ gfc_finalize (fndecl);
+ }
+}
+
+
+void
+gfc_generate_constructors (void)
+{
+ if (gfc_static_ctors != NULL_TREE)
+ abort ();
+#if 0
+ tree fnname;
+ tree type;
+ tree fndecl;
+ tree decl;
+ tree tmp;
+
+ if (gfc_static_ctors == NULL_TREE)
+ return;
+
+ fnname = get_file_function_name ('I');
+ type = build_function_type (void_type_node,
+ gfc_chainon_list (NULL_TREE, void_type_node));
+
+ fndecl = build_decl (FUNCTION_DECL, fnname, type);
+ TREE_PUBLIC (fndecl) = 1;
+
+ decl = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
+ DECL_CONTEXT (decl) = fndecl;
+ DECL_RESULT (fndecl) = decl;
+
+ pushdecl (fndecl);
+
+ current_function_decl = fndecl;
+
+ rest_of_decl_compilation (fndecl, NULL, 1, 0);
+
+ make_decl_rtl (fndecl, NULL);
+
+ init_function_start (fndecl, input_filename, input_line);
+
+ cfun->x_whole_function_mode_p = 1;
+
+ immediate_size_expand = 0;
+
+ pushlevel (0);
+
+ for (; gfc_static_ctors; gfc_static_ctors = TREE_CHAIN (gfc_static_ctors))
+ {
+ tmp =
+ gfc_build_function_call (TREE_VALUE (gfc_static_ctors), NULL_TREE);
+ DECL_SAVED_TREE (fndecl) = build_stmt (EXPR_STMT, tmp);
+ }
+
+ poplevel (1, 0, 1);
+
+ BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
+
+ free_after_parsing (cfun);
+ free_after_compilation (cfun);
+
+ tree_rest_of_compilation (fndecl, 0);
+
+ current_function_decl = NULL_TREE;
+#endif
+}
+
+#include "gt-fortran-trans-decl.h"
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
new file mode 100644
index 00000000000..89c0c472807
--- /dev/null
+++ b/gcc/fortran/trans-expr.c
@@ -0,0 +1,1830 @@
+/* Expression translation
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+ and Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* trans-expr.c-- generate GENERIC trees for gfc_expr. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "convert.h"
+#include <stdio.h>
+#include "ggc.h"
+#include "toplev.h"
+#include "real.h"
+#include "tree-gimple.h"
+#include "flags.h"
+#include <gmp.h>
+#include <assert.h>
+#include "gfortran.h"
+#include "trans.h"
+#include "trans-const.h"
+#include "trans-types.h"
+#include "trans-array.h"
+/* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
+#include "trans-stmt.h"
+
+
+/* Copy the scalarization loop variables. */
+
+static void
+gfc_copy_se_loopvars (gfc_se * dest, gfc_se * src)
+{
+ dest->ss = src->ss;
+ dest->loop = src->loop;
+}
+
+
+/* Initialise a simple expression holder.
+
+ Care must be taken when multiple se are created with the same parent.
+ The child se must be kept in sync. The easiest way is to delay creation
+ of a child se until after after the previous se has been translated. */
+
+void
+gfc_init_se (gfc_se * se, gfc_se * parent)
+{
+ memset (se, 0, sizeof (gfc_se));
+ gfc_init_block (&se->pre);
+ gfc_init_block (&se->post);
+
+ se->parent = parent;
+
+ if (parent)
+ gfc_copy_se_loopvars (se, parent);
+}
+
+
+/* Advances to the next SS in the chain. Use this rather than setting
+ se->ss = se->ss->next because all the parent needs to be kept in sync.
+ See gfc_init_se. */
+
+void
+gfc_advance_se_ss_chain (gfc_se * se)
+{
+ gfc_se *p;
+
+ assert (se != NULL && se->ss != NULL && se->ss != gfc_ss_terminator);
+
+ p = se;
+ /* Walk down the parent chain. */
+ while (p != NULL)
+ {
+ /* Simple consistancy check. */
+ assert (p->parent == NULL || p->parent->ss == p->ss);
+
+ p->ss = p->ss->next;
+
+ p = p->parent;
+ }
+}
+
+
+/* Ensures the result of the expression as either a temporary variable
+ or a constant so that it can be used repeatedly. */
+
+void
+gfc_make_safe_expr (gfc_se * se)
+{
+ tree var;
+
+ if (TREE_CODE_CLASS (TREE_CODE (se->expr)) == 'c')
+ return;
+
+ /* we need a temporary for this result */
+ var = gfc_create_var (TREE_TYPE (se->expr), NULL);
+ gfc_add_modify_expr (&se->pre, var, se->expr);
+ se->expr = var;
+}
+
+
+/* Return an expression which determines if a dummy parameter is present. */
+
+tree
+gfc_conv_expr_present (gfc_symbol * sym)
+{
+ tree decl;
+
+ assert (sym->attr.dummy && sym->attr.optional);
+
+ decl = gfc_get_symbol_decl (sym);
+ if (TREE_CODE (decl) != PARM_DECL)
+ {
+ /* Array parameters use a temporary descriptor, we want the real
+ parameter. */
+ assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
+ || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
+ decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
+ }
+ return build (NE_EXPR, boolean_type_node, decl, null_pointer_node);
+}
+
+
+/* Generate code to initialize a string length variable. Returns the
+ value. */
+
+void
+gfc_trans_init_string_length (gfc_charlen * cl, stmtblock_t * pblock)
+{
+ gfc_se se;
+ tree tmp;
+
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_type (&se, cl->length, gfc_strlen_type_node);
+ gfc_add_block_to_block (pblock, &se.pre);
+
+ tmp = cl->backend_decl;
+ gfc_add_modify_expr (pblock, tmp, se.expr);
+}
+
+static void
+gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind)
+{
+ tree tmp;
+ tree type;
+ tree var;
+ gfc_se start;
+ gfc_se end;
+
+ type = gfc_get_character_type (kind, ref->u.ss.length);
+ type = build_pointer_type (type);
+
+ var = NULL_TREE;
+ gfc_init_se (&start, se);
+ gfc_conv_expr_type (&start, ref->u.ss.start, gfc_strlen_type_node);
+ gfc_add_block_to_block (&se->pre, &start.pre);
+
+ if (integer_onep (start.expr))
+ {
+ gfc_conv_string_parameter (se);
+ }
+ else
+ {
+ /* Change the start of the string. */
+ if (TYPE_STRING_FLAG (TREE_TYPE (se->expr)))
+ tmp = se->expr;
+ else
+ tmp = gfc_build_indirect_ref (se->expr);
+ tmp = gfc_build_array_ref (tmp, start.expr);
+ se->expr = gfc_build_addr_expr (type, tmp);
+ }
+
+ /* Length = end + 1 - start. */
+ gfc_init_se (&end, se);
+ if (ref->u.ss.end == NULL)
+ end.expr = se->string_length;
+ else
+ {
+ gfc_conv_expr_type (&end, ref->u.ss.end, gfc_strlen_type_node);
+ gfc_add_block_to_block (&se->pre, &end.pre);
+ }
+ tmp =
+ build (MINUS_EXPR, gfc_strlen_type_node, integer_one_node, start.expr);
+ tmp = build (PLUS_EXPR, gfc_strlen_type_node, end.expr, tmp);
+ se->string_length = fold (tmp);
+}
+
+
+/* Convert a derived type component reference. */
+
+static void
+gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
+{
+ gfc_component *c;
+ tree tmp;
+ tree decl;
+ tree field;
+
+ c = ref->u.c.component;
+
+ assert (c->backend_decl);
+
+ field = c->backend_decl;
+ assert (TREE_CODE (field) == FIELD_DECL);
+ decl = se->expr;
+ tmp = build (COMPONENT_REF, TREE_TYPE (field), decl, field);
+
+ se->expr = tmp;
+
+ if (c->ts.type == BT_CHARACTER)
+ {
+ tmp = c->ts.cl->backend_decl;
+ assert (tmp);
+ if (!INTEGER_CST_P (tmp))
+ gfc_todo_error ("Unknown length character component");
+ se->string_length = tmp;
+ }
+
+ if (c->pointer && c->dimension == 0)
+ se->expr = gfc_build_indirect_ref (se->expr);
+}
+
+
+/* Return the contents of a variable. Also handles reference/pointer
+ variables (all Fortran pointer references are implicit). */
+
+static void
+gfc_conv_variable (gfc_se * se, gfc_expr * expr)
+{
+ gfc_ref *ref;
+ gfc_symbol *sym;
+
+ sym = expr->symtree->n.sym;
+ if (se->ss != NULL)
+ {
+ /* Check that something hasn't gone horribly wrong. */
+ assert (se->ss != gfc_ss_terminator);
+ assert (se->ss->expr == expr);
+
+ /* A scalarized term. We already know the descriptor. */
+ se->expr = se->ss->data.info.descriptor;
+ ref = se->ss->data.info.ref;
+ }
+ else
+ {
+ se->expr = gfc_get_symbol_decl (sym);
+
+ /* Procedure actual arguments. */
+ if (sym->attr.flavor == FL_PROCEDURE
+ && se->expr != current_function_decl)
+ {
+ assert (se->want_pointer);
+ if (!sym->attr.dummy)
+ {
+ assert (TREE_CODE (se->expr) == FUNCTION_DECL);
+ se->expr = gfc_build_addr_expr (NULL, se->expr);
+ }
+ return;
+ }
+
+ /* Special case for assigning the return value of a function.
+ Self recursive functions must have an explicit return value. */
+ if (se->expr == current_function_decl && sym->attr.function
+ && (sym->result == sym))
+ {
+ se->expr = gfc_get_fake_result_decl (sym);
+ }
+
+ /* Dereference scalar dummy variables. */
+ if (sym->attr.dummy
+ && sym->ts.type != BT_CHARACTER
+ && !sym->attr.dimension)
+ se->expr = gfc_build_indirect_ref (se->expr);
+
+ /* Dereference pointer variables. */
+ if ((sym->attr.pointer || sym->attr.allocatable)
+ && (sym->attr.dummy
+ || sym->attr.result
+ || sym->attr.function
+ || !sym->attr.dimension)
+ && sym->ts.type != BT_CHARACTER)
+ se->expr = gfc_build_indirect_ref (se->expr);
+
+ ref = expr->ref;
+ }
+
+ /* For character variables, also get the length. */
+ if (sym->ts.type == BT_CHARACTER)
+ {
+ se->string_length = sym->ts.cl->backend_decl;
+ assert (se->string_length);
+ }
+
+ while (ref)
+ {
+ switch (ref->type)
+ {
+ case REF_ARRAY:
+ /* Return the descriptor if that's what we want and this is an array
+ section reference. */
+ if (se->descriptor_only && ref->u.ar.type != AR_ELEMENT)
+ return;
+/* TODO: Pointers to single elements of array sections, eg elemental subs. */
+ /* Return the descriptor for array pointers and allocations. */
+ if (se->want_pointer
+ && ref->next == NULL && (se->descriptor_only))
+ return;
+
+ gfc_conv_array_ref (se, &ref->u.ar);
+ /* Return a pointer to an element. */
+ break;
+
+ case REF_COMPONENT:
+ gfc_conv_component_ref (se, ref);
+ break;
+
+ case REF_SUBSTRING:
+ gfc_conv_substring (se, ref, expr->ts.kind);
+ break;
+
+ default:
+ abort ();
+ break;
+ }
+ ref = ref->next;
+ }
+ /* Pointer assignment, allocation or pass by reference. Arrays are handled
+ seperately. */
+ if (se->want_pointer)
+ {
+ if (expr->ts.type == BT_CHARACTER)
+ gfc_conv_string_parameter (se);
+ else
+ se->expr = gfc_build_addr_expr (NULL, se->expr);
+ }
+ if (se->ss != NULL)
+ gfc_advance_se_ss_chain (se);
+}
+
+
+/* Unary ops are easy... Or they would be if ! was a valid op. */
+
+static void
+gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
+{
+ gfc_se operand;
+ tree type;
+
+ assert (expr->ts.type != BT_CHARACTER);
+ /* Initialize the operand. */
+ gfc_init_se (&operand, se);
+ gfc_conv_expr_val (&operand, expr->op1);
+ gfc_add_block_to_block (&se->pre, &operand.pre);
+
+ type = gfc_typenode_for_spec (&expr->ts);
+
+ /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
+ We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
+ All other unary operators have an equivalent GIMPLE unary operator */
+ if (code == TRUTH_NOT_EXPR)
+ se->expr = build (EQ_EXPR, type, operand.expr, integer_zero_node);
+ else
+ se->expr = build1 (code, type, operand.expr);
+
+}
+
+
+/* For power op (lhs ** rhs) We generate:
+ m = lhs
+ if (rhs > 0)
+ count = rhs
+ else if (rhs == 0)
+ {
+ count = 0
+ m = 1
+ }
+ else // (rhs < 0)
+ {
+ count = -rhs
+ m = 1 / m;
+ }
+ // for constant rhs we do the above at compile time
+ val = m;
+ for (n = 1; n < count; n++)
+ val = val * m;
+ */
+
+static void
+gfc_conv_integer_power (gfc_se * se, tree lhs, tree rhs)
+{
+ tree count;
+ tree result;
+ tree cond;
+ tree neg_stmt;
+ tree pos_stmt;
+ tree tmp;
+ tree var;
+ tree type;
+ stmtblock_t block;
+ tree exit_label;
+
+ type = TREE_TYPE (lhs);
+
+ if (INTEGER_CST_P (rhs))
+ {
+ if (integer_zerop (rhs))
+ {
+ se->expr = gfc_build_const (type, integer_one_node);
+ return;
+ }
+ /* Special cases for constant values. */
+ if (TREE_INT_CST_HIGH (rhs) == -1)
+ {
+ /* x ** (-y) == 1 / (x ** y). */
+ if (TREE_CODE (type) == INTEGER_TYPE)
+ {
+ se->expr = integer_zero_node;
+ return;
+ }
+
+ tmp = gfc_build_const (type, integer_one_node);
+ lhs = fold (build (RDIV_EXPR, type, tmp, lhs));
+
+ rhs = fold (build1 (NEGATE_EXPR, TREE_TYPE (rhs), rhs));
+ assert (INTEGER_CST_P (rhs));
+ }
+ else
+ {
+ /* TODO: really big integer powers. */
+ assert (TREE_INT_CST_HIGH (rhs) == 0);
+ }
+
+ if (integer_onep (rhs))
+ {
+ se->expr = lhs;
+ return;
+ }
+ if (TREE_INT_CST_LOW (rhs) == 2)
+ {
+ se->expr = build (MULT_EXPR, type, lhs, lhs);
+ return;
+ }
+ if (TREE_INT_CST_LOW (rhs) == 3)
+ {
+ tmp = build (MULT_EXPR, type, lhs, lhs);
+ se->expr = fold (build (MULT_EXPR, type, tmp, lhs));
+ return;
+ }
+
+ /* Create the loop count variable. */
+ count = gfc_create_var (TREE_TYPE (rhs), "count");
+ gfc_add_modify_expr (&se->pre, count, rhs);
+ }
+ else
+ {
+ /* Put the lhs into a temporary variable. */
+ var = gfc_create_var (type, "val");
+ count = gfc_create_var (TREE_TYPE (rhs), "count");
+ gfc_add_modify_expr (&se->pre, var, lhs);
+ lhs = var;
+
+ /* Generate code for negative rhs. */
+ gfc_start_block (&block);
+
+ if (TREE_CODE (TREE_TYPE (lhs)) == INTEGER_TYPE)
+ {
+ gfc_add_modify_expr (&block, lhs, integer_zero_node);
+ gfc_add_modify_expr (&block, count, integer_zero_node);
+ }
+ else
+ {
+ tmp = gfc_build_const (type, integer_one_node);
+ tmp = build (RDIV_EXPR, type, tmp, lhs);
+ gfc_add_modify_expr (&block, var, tmp);
+
+ tmp = build1 (NEGATE_EXPR, TREE_TYPE (rhs), rhs);
+ gfc_add_modify_expr (&block, count, tmp);
+ }
+ neg_stmt = gfc_finish_block (&block);
+
+ pos_stmt = build_v (MODIFY_EXPR, count, rhs);
+
+ /* Code for rhs == 0. */
+ gfc_start_block (&block);
+
+ gfc_add_modify_expr (&block, count, integer_zero_node);
+ tmp = gfc_build_const (type, integer_one_node);
+ gfc_add_modify_expr (&block, lhs, tmp);
+
+ tmp = gfc_finish_block (&block);
+
+ /* Select the appropriate action. */
+ cond = build (EQ_EXPR, boolean_type_node, rhs, integer_zero_node);
+ tmp = build_v (COND_EXPR, cond, tmp, neg_stmt);
+
+ cond = build (GT_EXPR, boolean_type_node, rhs, integer_zero_node);
+ tmp = build_v (COND_EXPR, cond, pos_stmt, tmp);
+ gfc_add_expr_to_block (&se->pre, tmp);
+ }
+
+ /* Create a variable for the result. */
+ result = gfc_create_var (type, "pow");
+ gfc_add_modify_expr (&se->pre, result, lhs);
+
+ exit_label = gfc_build_label_decl (NULL_TREE);
+ TREE_USED (exit_label) = 1;
+
+ /* Create the loop body. */
+ gfc_start_block (&block);
+
+ /* First the exit condition (until count <= 1). */
+ tmp = build1_v (GOTO_EXPR, exit_label);
+ cond = build (LE_EXPR, TREE_TYPE (count), count, integer_one_node);
+ tmp = build_v (COND_EXPR, cond, tmp, build_empty_stmt ());
+ gfc_add_expr_to_block (&block, tmp);
+
+ /* Multiply by the lhs. */
+ tmp = build (MULT_EXPR, type, result, lhs);
+ gfc_add_modify_expr (&block, result, tmp);
+
+ /* Adjust the loop count. */
+ tmp = build (MINUS_EXPR, TREE_TYPE (count), count, integer_one_node);
+ gfc_add_modify_expr (&block, count, tmp);
+
+ tmp = gfc_finish_block (&block);
+
+ /* Create the the loop. */
+ tmp = build_v (LOOP_EXPR, tmp);
+ gfc_add_expr_to_block (&se->pre, tmp);
+
+ /* Add the exit label. */
+ tmp = build1_v (LABEL_EXPR, exit_label);
+ gfc_add_expr_to_block (&se->pre, tmp);
+
+ se->expr = result;
+}
+
+
+/* Power op (**). Integer rhs has special handling. */
+
+static void
+gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
+{
+ int kind;
+ gfc_se lse;
+ gfc_se rse;
+ tree fndecl;
+ tree tmp;
+ tree type;
+
+ gfc_init_se (&lse, se);
+ gfc_conv_expr_val (&lse, expr->op1);
+ gfc_add_block_to_block (&se->pre, &lse.pre);
+
+ gfc_init_se (&rse, se);
+ gfc_conv_expr_val (&rse, expr->op2);
+ gfc_add_block_to_block (&se->pre, &rse.pre);
+
+ type = TREE_TYPE (lse.expr);
+
+ kind = expr->op1->ts.kind;
+ switch (expr->op2->ts.type)
+ {
+ case BT_INTEGER:
+ /* Integer powers are expanded inline as multiplications. */
+ gfc_conv_integer_power (se, lse.expr, rse.expr);
+ return;
+
+ case BT_REAL:
+ switch (kind)
+ {
+ case 4:
+ fndecl = gfor_fndecl_math_powf;
+ break;
+ case 8:
+ fndecl = gfor_fndecl_math_pow;
+ break;
+ default:
+ abort ();
+ }
+ break;
+
+ case BT_COMPLEX:
+ switch (kind)
+ {
+ case 4:
+ fndecl = gfor_fndecl_math_cpowf;
+ break;
+ case 8:
+ fndecl = gfor_fndecl_math_cpow;
+ break;
+ default:
+ abort ();
+ }
+ break;
+
+ default:
+ abort ();
+ break;
+ }
+
+ tmp = gfc_chainon_list (NULL_TREE, lse.expr);
+ tmp = gfc_chainon_list (tmp, rse.expr);
+ se->expr = gfc_build_function_call (fndecl, tmp);
+}
+
+
+/* Generate code to allocate a string temporary. */
+
+tree
+gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
+{
+ tree var;
+ tree tmp;
+ tree args;
+
+ if (gfc_can_put_var_on_stack (len))
+ {
+ /* Create a temporary variable to hold the result. */
+ tmp = fold (build (MINUS_EXPR, TREE_TYPE (len), len, integer_one_node));
+ tmp = build_range_type (gfc_array_index_type, integer_zero_node, tmp);
+ tmp = build_array_type (gfc_character1_type_node, tmp);
+ var = gfc_create_var (tmp, "str");
+ var = gfc_build_addr_expr (type, var);
+ }
+ else
+ {
+ /* Allocate a temporary to hold the result. */
+ var = gfc_create_var (type, "pstr");
+ args = gfc_chainon_list (NULL_TREE, len);
+ tmp = gfc_build_function_call (gfor_fndecl_internal_malloc, args);
+ tmp = convert (type, tmp);
+ gfc_add_modify_expr (&se->pre, var, tmp);
+
+ /* Free the temporary afterwards. */
+ tmp = convert (pvoid_type_node, var);
+ args = gfc_chainon_list (NULL_TREE, tmp);
+ tmp = gfc_build_function_call (gfor_fndecl_internal_free, args);
+ gfc_add_expr_to_block (&se->post, tmp);
+ }
+
+ return var;
+}
+
+
+/* Handle a string concatenation operation. A temporary will be allocated to
+ hold the result. */
+
+static void
+gfc_conv_concat_op (gfc_se * se, gfc_expr * expr)
+{
+ gfc_se lse;
+ gfc_se rse;
+ tree len;
+ tree type;
+ tree var;
+ tree args;
+ tree tmp;
+
+ assert (expr->op1->ts.type == BT_CHARACTER
+ && expr->op2->ts.type == BT_CHARACTER);
+
+ gfc_init_se (&lse, se);
+ gfc_conv_expr (&lse, expr->op1);
+ gfc_conv_string_parameter (&lse);
+ gfc_init_se (&rse, se);
+ gfc_conv_expr (&rse, expr->op2);
+ gfc_conv_string_parameter (&rse);
+
+ gfc_add_block_to_block (&se->pre, &lse.pre);
+ gfc_add_block_to_block (&se->pre, &rse.pre);
+
+ type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
+ len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
+ if (len == NULL_TREE)
+ {
+ len = fold (build (PLUS_EXPR, TREE_TYPE (lse.string_length),
+ lse.string_length, rse.string_length));
+ }
+
+ type = build_pointer_type (type);
+
+ var = gfc_conv_string_tmp (se, type, len);
+
+ /* Do the actual concatenation. */
+ args = NULL_TREE;
+ args = gfc_chainon_list (args, len);
+ args = gfc_chainon_list (args, var);
+ args = gfc_chainon_list (args, lse.string_length);
+ args = gfc_chainon_list (args, lse.expr);
+ args = gfc_chainon_list (args, rse.string_length);
+ args = gfc_chainon_list (args, rse.expr);
+ tmp = gfc_build_function_call (gfor_fndecl_concat_string, args);
+ gfc_add_expr_to_block (&se->pre, tmp);
+
+ /* Add the cleanup for the operands. */
+ gfc_add_block_to_block (&se->pre, &rse.post);
+ gfc_add_block_to_block (&se->pre, &lse.post);
+
+ se->expr = var;
+ se->string_length = len;
+}
+
+
+/* Translates an op expression. Common (binary) cases are handled by this
+ function, others are passed on. Recursion is used in either case.
+ We use the fact that (op1.ts == op2.ts) (except for the power
+ operand **).
+ Operators need no special handling for scalarized expressions as long as
+ they call gfc_conv_siple_val to get their operands.
+ Character strings get special handling. */
+
+static void
+gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
+{
+ enum tree_code code;
+ gfc_se lse;
+ gfc_se rse;
+ tree type;
+ tree tmp;
+ int lop;
+ int checkstring;
+
+ checkstring = 0;
+ lop = 0;
+ switch (expr->operator)
+ {
+ case INTRINSIC_UPLUS:
+ gfc_conv_expr (se, expr->op1);
+ return;
+
+ case INTRINSIC_UMINUS:
+ gfc_conv_unary_op (NEGATE_EXPR, se, expr);
+ return;
+
+ case INTRINSIC_NOT:
+ gfc_conv_unary_op (TRUTH_NOT_EXPR, se, expr);
+ return;
+
+ case INTRINSIC_PLUS:
+ code = PLUS_EXPR;
+ break;
+
+ case INTRINSIC_MINUS:
+ code = MINUS_EXPR;
+ break;
+
+ case INTRINSIC_TIMES:
+ code = MULT_EXPR;
+ break;
+
+ case INTRINSIC_DIVIDE:
+ /* If expr is a real or complex expr, use an RDIV_EXPR. If op1 is
+ an integer, we must round towards zero, so we use a
+ TRUNC_DIV_EXPR. */
+ if (expr->ts.type == BT_INTEGER)
+ code = TRUNC_DIV_EXPR;
+ else
+ code = RDIV_EXPR;
+ break;
+
+ case INTRINSIC_POWER:
+ gfc_conv_power_op (se, expr);
+ return;
+
+ case INTRINSIC_CONCAT:
+ gfc_conv_concat_op (se, expr);
+ return;
+
+ case INTRINSIC_AND:
+ code = TRUTH_ANDIF_EXPR;
+ lop = 1;
+ break;
+
+ case INTRINSIC_OR:
+ code = TRUTH_ORIF_EXPR;
+ lop = 1;
+ break;
+
+ /* EQV and NEQV only work on logicals, but since we represent them
+ as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE. */
+ case INTRINSIC_EQ:
+ case INTRINSIC_EQV:
+ code = EQ_EXPR;
+ checkstring = 1;
+ lop = 1;
+ break;
+
+ case INTRINSIC_NE:
+ case INTRINSIC_NEQV:
+ code = NE_EXPR;
+ checkstring = 1;
+ lop = 1;
+ break;
+
+ case INTRINSIC_GT:
+ code = GT_EXPR;
+ checkstring = 1;
+ lop = 1;
+ break;
+
+ case INTRINSIC_GE:
+ code = GE_EXPR;
+ checkstring = 1;
+ lop = 1;
+ break;
+
+ case INTRINSIC_LT:
+ code = LT_EXPR;
+ checkstring = 1;
+ lop = 1;
+ break;
+
+ case INTRINSIC_LE:
+ code = LE_EXPR;
+ checkstring = 1;
+ lop = 1;
+ break;
+
+ case INTRINSIC_USER:
+ case INTRINSIC_ASSIGN:
+ /* These should be converted into function calls by the frontend. */
+ abort ();
+ return;
+
+ default:
+ fatal_error ("Unknown intrinsic op");
+ return;
+ }
+
+ /* The only exception to this is **, which is handled seperately anyway. */
+ assert (expr->op1->ts.type == expr->op2->ts.type);
+
+ if (checkstring && expr->op1->ts.type != BT_CHARACTER)
+ checkstring = 0;
+
+ /* lhs */
+ gfc_init_se (&lse, se);
+ gfc_conv_expr (&lse, expr->op1);
+ gfc_add_block_to_block (&se->pre, &lse.pre);
+
+ /* rhs */
+ gfc_init_se (&rse, se);
+ gfc_conv_expr (&rse, expr->op2);
+ gfc_add_block_to_block (&se->pre, &rse.pre);
+
+ /* For string comparisons we generate a library call, and compare the return
+ value with 0. */
+ if (checkstring)
+ {
+ gfc_conv_string_parameter (&lse);
+ gfc_conv_string_parameter (&rse);
+ tmp = NULL_TREE;
+ tmp = gfc_chainon_list (tmp, lse.string_length);
+ tmp = gfc_chainon_list (tmp, lse.expr);
+ tmp = gfc_chainon_list (tmp, rse.string_length);
+ tmp = gfc_chainon_list (tmp, rse.expr);
+
+ /* Build a call for the comparison. */
+ lse.expr = gfc_build_function_call (gfor_fndecl_compare_string, tmp);
+ gfc_add_block_to_block (&lse.post, &rse.post);
+
+ rse.expr = integer_zero_node;
+ }
+
+ type = gfc_typenode_for_spec (&expr->ts);
+
+ if (lop)
+ {
+ /* The result of logical ops is always boolean_type_node. */
+ tmp = fold (build (code, type, lse.expr, rse.expr));
+ se->expr = convert (type, tmp);
+ }
+ else
+ se->expr = fold (build (code, type, lse.expr, rse.expr));
+
+
+ /* Add the post blocks. */
+ gfc_add_block_to_block (&se->post, &rse.post);
+ gfc_add_block_to_block (&se->post, &lse.post);
+}
+
+static void
+gfc_conv_function_val (gfc_se * se, gfc_symbol * sym)
+{
+ tree tmp;
+
+ if (sym->attr.dummy)
+ {
+ tmp = gfc_get_symbol_decl (sym);
+ assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
+
+ se->expr = tmp;
+ }
+ else
+ {
+ if (!sym->backend_decl)
+ sym->backend_decl = gfc_get_extern_function_decl (sym);
+
+ tmp = sym->backend_decl;
+ assert (TREE_CODE (tmp) == FUNCTION_DECL);
+ se->expr = gfc_build_addr_expr (NULL, tmp);
+ }
+}
+
+
+/* Generate code for a procedure call. Note can return se->post != NULL.
+ If se->direct_byref is set then se->expr contains the return parameter. */
+
+void
+gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
+ gfc_actual_arglist * arg)
+{
+ tree arglist;
+ tree tmp;
+ tree fntype;
+ gfc_se parmse;
+ gfc_ss *argss;
+ gfc_ss_info *info;
+ int byref;
+ tree type;
+ tree var;
+ tree len;
+ tree stringargs;
+ gfc_formal_arglist *formal;
+
+ arglist = NULL_TREE;
+ stringargs = NULL_TREE;
+ var = NULL_TREE;
+ len = NULL_TREE;
+
+ if (se->ss != NULL)
+ {
+ if (!sym->attr.elemental)
+ {
+ assert (se->ss->type == GFC_SS_FUNCTION);
+ if (se->ss->useflags)
+ {
+ assert (gfc_return_by_reference (sym)
+ && sym->result->attr.dimension);
+ assert (se->loop != NULL);
+
+ /* Access the previously obtained result. */
+ gfc_conv_tmp_array_ref (se);
+ gfc_advance_se_ss_chain (se);
+ return;
+ }
+ }
+ info = &se->ss->data.info;
+ }
+ else
+ info = NULL;
+
+ byref = gfc_return_by_reference (sym);
+ if (byref)
+ {
+ if (se->direct_byref)
+ arglist = gfc_chainon_list (arglist, se->expr);
+ else if (sym->result->attr.dimension)
+ {
+ assert (se->loop && se->ss);
+ /* Set the type of the array. */
+ tmp = gfc_typenode_for_spec (&sym->ts);
+ info->dimen = se->loop->dimen;
+ /* Allocate a temporary to store the result. */
+ gfc_trans_allocate_temp_array (se->loop, info, tmp, NULL_TREE);
+
+ /* Zero the first stride to indicate a temporary. */
+ tmp =
+ gfc_conv_descriptor_stride (info->descriptor, gfc_rank_cst[0]);
+ gfc_add_modify_expr (&se->pre, tmp, integer_zero_node);
+ /* Pass the temporary as the first argument. */
+ tmp = info->descriptor;
+ tmp = gfc_build_addr_expr (NULL, tmp);
+ arglist = gfc_chainon_list (arglist, tmp);
+ }
+ else if (sym->ts.type == BT_CHARACTER)
+ {
+ assert (sym->ts.cl && sym->ts.cl->length
+ && sym->ts.cl->length->expr_type == EXPR_CONSTANT);
+ len = gfc_conv_mpz_to_tree
+ (sym->ts.cl->length->value.integer, sym->ts.cl->length->ts.kind);
+ sym->ts.cl->backend_decl = len;
+ type = gfc_get_character_type (sym->ts.kind, sym->ts.cl);
+ type = build_pointer_type (type);
+
+ var = gfc_conv_string_tmp (se, type, len);
+ arglist = gfc_chainon_list (arglist, var);
+ arglist = gfc_chainon_list (arglist, convert (gfc_strlen_type_node,
+ len));
+ }
+ else /* TODO: derived type function return values. */
+ abort ();
+ }
+
+ formal = sym->formal;
+ /* Evaluate the arguments. */
+ for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
+ {
+ if (arg->expr == NULL)
+ {
+
+ if (se->ignore_optional)
+ {
+ /* Some intrinsics have already been resolved to the correct
+ parameters. */
+ continue;
+ }
+ else if (arg->label)
+ {
+ has_alternate_specifier = 1;
+ continue;
+ }
+ else
+ {
+ /* Pass a NULL pointer for an absent arg. */
+ gfc_init_se (&parmse, NULL);
+ parmse.expr = null_pointer_node;
+ if (formal && formal->sym->ts.type == BT_CHARACTER)
+ {
+ stringargs = gfc_chainon_list (stringargs,
+ convert (gfc_strlen_type_node, integer_zero_node));
+ }
+ }
+ }
+ else if (se->ss && se->ss->useflags)
+ {
+ /* An elemental function inside a scalarized loop. */
+ gfc_init_se (&parmse, se);
+ gfc_conv_expr_reference (&parmse, arg->expr);
+ }
+ else
+ {
+ /* A scalar or transformational function. */
+ gfc_init_se (&parmse, NULL);
+ argss = gfc_walk_expr (arg->expr);
+
+ if (argss == gfc_ss_terminator)
+ {
+ gfc_conv_expr_reference (&parmse, arg->expr);
+ if (formal && formal->sym->attr.pointer)
+ {
+ /* Scalar pointer dummy args require an extra level of
+ indirection. */
+ parmse.expr = gfc_build_addr_expr (NULL, parmse.expr);
+ }
+ }
+ else
+ {
+ /* If the procedure requires explicit interface, actual argument
+ is passed according to corresponing formal argument. We
+ do not use g77 method and the address of array descriptor
+ is passed if corresponing formal is pointer or
+ assumed-shape, Otherwise use g77 method. */
+ int f;
+ f = (formal != NULL)
+ && !formal->sym->attr.pointer
+ && formal->sym->as->type != AS_ASSUMED_SHAPE;
+ f = f || !sym->attr.always_explicit;
+ gfc_conv_array_parameter (&parmse, arg->expr, argss, f);
+ }
+ }
+
+ gfc_add_block_to_block (&se->pre, &parmse.pre);
+ gfc_add_block_to_block (&se->post, &parmse.post);
+
+ /* Character strings are passed as two paramarers, a length and a
+ pointer. */
+ if (parmse.string_length != NULL_TREE)
+ stringargs = gfc_chainon_list (stringargs, parmse.string_length);
+
+ arglist = gfc_chainon_list (arglist, parmse.expr);
+ }
+
+ /* Add the hidden string length parameters to the arguments. */
+ arglist = chainon (arglist, stringargs);
+
+ /* Generate the actual call. */
+ gfc_conv_function_val (se, sym);
+ /* If there are alternate return labels, function type should be
+ integer. */
+ if (has_alternate_specifier)
+ TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr))) = integer_type_node;
+
+ fntype = TREE_TYPE (TREE_TYPE (se->expr));
+ se->expr = build (CALL_EXPR, TREE_TYPE (fntype), se->expr,
+ arglist, NULL_TREE);
+
+/* A pure function may still have side-effects - it may modify its
+ parameters. */
+ TREE_SIDE_EFFECTS (se->expr) = 1;
+#if 0
+ if (!sym->attr.pure)
+ TREE_SIDE_EFFECTS (se->expr) = 1;
+#endif
+
+ if (byref && !se->direct_byref)
+ {
+ gfc_add_expr_to_block (&se->pre, se->expr);
+
+ if (sym->result->attr.dimension)
+ {
+ if (flag_bounds_check)
+ {
+ /* Check the data pointer hasn't been modified. This would happen
+ in a function returning a pointer. */
+ tmp = gfc_conv_descriptor_data (info->descriptor);
+ tmp = build (NE_EXPR, boolean_type_node, tmp, info->data);
+ gfc_trans_runtime_check (tmp, gfc_strconst_fault, &se->pre);
+ }
+ se->expr = info->descriptor;
+ }
+ else if (sym->ts.type == BT_CHARACTER)
+ {
+ se->expr = var;
+ se->string_length = len;
+ }
+ else
+ abort ();
+ }
+}
+
+
+/* Translate a statement function.
+ The value of a statement function reference is obtained by evaluating the
+ expression using the values of the actual arguments for the values of the
+ corresponding dummy arguments. */
+
+static void
+gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
+{
+ gfc_symbol *sym;
+ gfc_symbol *fsym;
+ gfc_formal_arglist *fargs;
+ gfc_actual_arglist *args;
+ gfc_se lse;
+ gfc_se rse;
+
+ sym = expr->symtree->n.sym;
+ args = expr->value.function.actual;
+ gfc_init_se (&lse, NULL);
+ gfc_init_se (&rse, NULL);
+
+ for (fargs = sym->formal; fargs; fargs = fargs->next)
+ {
+ /* Each dummy shall be specified, explicitly or implicitly, to be
+ scalar. */
+ assert (fargs->sym->attr.dimension == 0);
+ fsym = fargs->sym;
+ assert (fsym->backend_decl);
+
+ /* Convert non-pointer string dummy. */
+ if (fsym->ts.type == BT_CHARACTER && !fsym->attr.pointer)
+ {
+ tree len1;
+ tree len2;
+ tree arg;
+ tree tmp;
+ tree type;
+ tree var;
+
+ assert (fsym->ts.cl && fsym->ts.cl->length
+ && fsym->ts.cl->length->expr_type == EXPR_CONSTANT);
+
+ type = gfc_get_character_type (fsym->ts.kind, fsym->ts.cl);
+ len1 = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
+ var = gfc_build_addr_expr (build_pointer_type (type),
+ fsym->backend_decl);
+
+ gfc_conv_expr (&rse, args->expr);
+ gfc_conv_string_parameter (&rse);
+ len2 = rse.string_length;
+ gfc_add_block_to_block (&se->pre, &lse.pre);
+ gfc_add_block_to_block (&se->pre, &rse.pre);
+
+ arg = NULL_TREE;
+ arg = gfc_chainon_list (arg, len1);
+ arg = gfc_chainon_list (arg, var);
+ arg = gfc_chainon_list (arg, len2);
+ arg = gfc_chainon_list (arg, rse.expr);
+ tmp = gfc_build_function_call (gfor_fndecl_copy_string, arg);
+ gfc_add_expr_to_block (&se->pre, tmp);
+ gfc_add_block_to_block (&se->pre, &lse.post);
+ gfc_add_block_to_block (&se->pre, &rse.post);
+ }
+ else
+ {
+ /* For everything else, just evaluate the expression. */
+ if (fsym->attr.pointer == 1)
+ lse.want_pointer = 1;
+
+ gfc_conv_expr (&lse, args->expr);
+
+ gfc_add_block_to_block (&se->pre, &lse.pre);
+ gfc_add_modify_expr (&se->pre, fsym->backend_decl, lse.expr);
+ gfc_add_block_to_block (&se->pre, &lse.post);
+ }
+ args = args->next;
+ }
+ gfc_conv_expr (se, sym->value);
+}
+
+
+/* Translate a function expression. */
+
+static void
+gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
+{
+ gfc_symbol *sym;
+
+ if (expr->value.function.isym)
+ {
+ gfc_conv_intrinsic_function (se, expr);
+ return;
+ }
+
+ /* We distinguish the statement function from general function to improve
+ runtime performance. */
+ if (expr->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
+ {
+ gfc_conv_statement_function (se, expr);
+ return;
+ }
+
+ /* expr.value.function.esym is the resolved (specific) function symbol for
+ most functions. However this isn't set for dummy procedures. */
+ sym = expr->value.function.esym;
+ if (!sym)
+ sym = expr->symtree->n.sym;
+ gfc_conv_function_call (se, sym, expr->value.function.actual);
+}
+
+static void
+gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
+{
+ assert (se->ss != NULL && se->ss != gfc_ss_terminator);
+ assert (se->ss->expr == expr && se->ss->type == GFC_SS_CONSTRUCTOR);
+
+ gfc_conv_tmp_array_ref (se);
+ gfc_advance_se_ss_chain (se);
+}
+
+
+
+/* Build an expression for a constructor. If init is nonzero then
+ this is part of a static variable initializer. */
+
+void
+gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
+{
+ gfc_constructor *c;
+ gfc_component *cm;
+ tree head;
+ tree tail;
+ tree val;
+ gfc_se cse;
+ tree type;
+ tree arraytype;
+
+ assert (expr->expr_type == EXPR_STRUCTURE);
+ type = gfc_typenode_for_spec (&expr->ts);
+ head = build1 (CONSTRUCTOR, type, NULL_TREE);
+ tail = NULL_TREE;
+
+ cm = expr->ts.derived->components;
+ for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
+ {
+ /* Skip absent members in default initializers. */
+ if (!c->expr)
+ continue;
+
+ gfc_init_se (&cse, se);
+ /* Evaluate the expression for this component. */
+ if (init)
+ {
+ if (cm->dimension)
+ {
+ arraytype = TREE_TYPE (cm->backend_decl);
+ cse.expr = gfc_conv_array_initializer (arraytype, c->expr);
+ }
+ else if (cm->ts.type == BT_DERIVED)
+ gfc_conv_structure (&cse, c->expr, 1);
+ else
+ gfc_conv_expr (&cse, c->expr);
+ }
+ else
+ {
+ gfc_conv_expr (&cse, c->expr);
+ gfc_add_block_to_block (&se->pre, &cse.pre);
+ gfc_add_block_to_block (&se->post, &cse.post);
+ }
+
+ /* Build a TREE_CHAIN to hold it. */
+ val = tree_cons (cm->backend_decl, cse.expr, NULL_TREE);
+
+ /* Add it to the list. */
+ if (tail == NULL_TREE)
+ TREE_OPERAND(head, 0) = tail = val;
+ else
+ {
+ TREE_CHAIN (tail) = val;
+ tail = val;
+ }
+ }
+ se->expr = head;
+}
+
+
+/*translate a substring expression */
+
+static void
+gfc_conv_substring_expr (gfc_se * se, gfc_expr * expr)
+{
+ gfc_ref *ref;
+
+ ref = expr->ref;
+
+ assert(ref->type == REF_SUBSTRING);
+
+ se->expr = gfc_build_string_const(expr->value.character.length,
+ expr->value.character.string);
+ se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));
+ TYPE_STRING_FLAG (TREE_TYPE (se->expr))=1;
+
+ gfc_conv_substring(se,ref,expr->ts.kind);
+}
+
+
+/* Entry point for expression translation. */
+
+void
+gfc_conv_expr (gfc_se * se, gfc_expr * expr)
+{
+ if (se->ss && se->ss->expr == expr
+ && (se->ss->type == GFC_SS_SCALAR || se->ss->type == GFC_SS_REFERENCE))
+ {
+ /* Substiture a scalar expression evaluated outside the scalarization
+ loop. */
+ se->expr = se->ss->data.scalar.expr;
+ se->string_length = se->ss->data.scalar.string_length;
+ gfc_advance_se_ss_chain (se);
+ return;
+ }
+
+ switch (expr->expr_type)
+ {
+ case EXPR_OP:
+ gfc_conv_expr_op (se, expr);
+ break;
+
+ case EXPR_FUNCTION:
+ gfc_conv_function_expr (se, expr);
+ break;
+
+ case EXPR_CONSTANT:
+ gfc_conv_constant (se, expr);
+ break;
+
+ case EXPR_VARIABLE:
+ gfc_conv_variable (se, expr);
+ break;
+
+ case EXPR_NULL:
+ se->expr = null_pointer_node;
+ break;
+
+ case EXPR_SUBSTRING:
+ gfc_conv_substring_expr (se, expr);
+ break;
+
+ case EXPR_STRUCTURE:
+ gfc_conv_structure (se, expr, 0);
+ break;
+
+ case EXPR_ARRAY:
+ gfc_conv_array_constructor_expr (se, expr);
+ break;
+
+ default:
+ abort ();
+ break;
+ }
+}
+
+void
+gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr)
+{
+ gfc_conv_expr (se, expr);
+ /* AFAICS all numeric lvalues have empty post chains. If not we need to
+ figure out a way of rewriting an lvalue so that it has no post chain. */
+ assert (expr->ts.type != BT_CHARACTER || !se->post.head);
+}
+
+void
+gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
+{
+ tree val;
+
+ assert (expr->ts.type != BT_CHARACTER);
+ gfc_conv_expr (se, expr);
+ if (se->post.head)
+ {
+ val = gfc_create_var (TREE_TYPE (se->expr), NULL);
+ gfc_add_modify_expr (&se->pre, val, se->expr);
+ }
+}
+
+void
+gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
+{
+ gfc_conv_expr_val (se, expr);
+ se->expr = convert (type, se->expr);
+}
+
+
+/* Converts an expression so that it can be passed by refernece. Scalar
+ values only. */
+
+void
+gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
+{
+ tree var;
+
+ if (se->ss && se->ss->expr == expr
+ && se->ss->type == GFC_SS_REFERENCE)
+ {
+ se->expr = se->ss->data.scalar.expr;
+ se->string_length = se->ss->data.scalar.string_length;
+ gfc_advance_se_ss_chain (se);
+ return;
+ }
+
+ if (expr->ts.type == BT_CHARACTER)
+ {
+ gfc_conv_expr (se, expr);
+ gfc_conv_string_parameter (se);
+ return;
+ }
+
+ if (expr->expr_type == EXPR_VARIABLE)
+ {
+ se->want_pointer = 1;
+ gfc_conv_expr (se, expr);
+ if (se->post.head)
+ {
+ var = gfc_create_var (TREE_TYPE (se->expr), NULL);
+ gfc_add_modify_expr (&se->pre, var, se->expr);
+ gfc_add_block_to_block (&se->pre, &se->post);
+ se->expr = var;
+ }
+ return;
+ }
+
+ gfc_conv_expr (se, expr);
+
+ /* Create a temporary var to hold the value. */
+ var = gfc_create_var (TREE_TYPE (se->expr), NULL);
+ gfc_add_modify_expr (&se->pre, var, se->expr);
+ gfc_add_block_to_block (&se->pre, &se->post);
+
+ /* Take the address of that value. */
+ se->expr = gfc_build_addr_expr (NULL, var);
+}
+
+
+tree
+gfc_trans_pointer_assign (gfc_code * code)
+{
+ return gfc_trans_pointer_assignment (code->expr, code->expr2);
+}
+
+
+tree
+gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
+{
+ gfc_se lse;
+ gfc_se rse;
+ gfc_ss *lss;
+ gfc_ss *rss;
+ stmtblock_t block;
+ tree tmp;
+
+ gfc_start_block (&block);
+
+ gfc_init_se (&lse, NULL);
+
+ lss = gfc_walk_expr (expr1);
+ rss = gfc_walk_expr (expr2);
+ if (lss == gfc_ss_terminator)
+ {
+ lse.want_pointer = 1;
+ gfc_conv_expr (&lse, expr1);
+ assert (rss == gfc_ss_terminator);
+ gfc_init_se (&rse, NULL);
+ rse.want_pointer = 1;
+ gfc_conv_expr (&rse, expr2);
+ gfc_add_block_to_block (&block, &lse.pre);
+ gfc_add_block_to_block (&block, &rse.pre);
+ gfc_add_modify_expr (&block, lse.expr, rse.expr);
+ gfc_add_block_to_block (&block, &rse.post);
+ gfc_add_block_to_block (&block, &lse.post);
+ }
+ else
+ {
+ gfc_conv_expr_descriptor (&lse, expr1, lss);
+ /* Implement Nullify. */
+ if (expr2->expr_type == EXPR_NULL)
+ {
+ lse.expr = gfc_conv_descriptor_data (lse.expr);
+ rse.expr = null_pointer_node;
+ tmp = build_v (MODIFY_EXPR, lse.expr, rse.expr);
+ gfc_add_expr_to_block (&block, tmp);
+ }
+ else
+ {
+ lse.direct_byref = 1;
+ gfc_conv_expr_descriptor (&lse, expr2, rss);
+ }
+ gfc_add_block_to_block (&block, &lse.pre);
+ gfc_add_block_to_block (&block, &lse.post);
+ }
+ return gfc_finish_block (&block);
+}
+
+
+/* Makes sure se is suitable for passing as a function string parameter. */
+/* TODO: Need to check all callers fo this function. It may be abused. */
+
+void
+gfc_conv_string_parameter (gfc_se * se)
+{
+ tree type;
+
+ if (TREE_CODE (se->expr) == STRING_CST)
+ {
+ se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
+ return;
+ }
+
+ type = TREE_TYPE (se->expr);
+ if (TYPE_STRING_FLAG (type))
+ {
+ assert (TREE_CODE (se->expr) != INDIRECT_REF);
+ se->expr = gfc_build_addr_expr (pchar_type_node, se->expr);
+ }
+
+ assert (POINTER_TYPE_P (TREE_TYPE (se->expr)));
+ assert (se->string_length
+ && TREE_CODE (TREE_TYPE (se->string_length)) == INTEGER_TYPE);
+}
+
+
+/* Generate code for assignment of scalar variables. Includes character
+ strings. */
+
+tree
+gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, bt type)
+{
+ tree tmp;
+ tree args;
+ stmtblock_t block;
+
+ gfc_init_block (&block);
+
+
+ if (type == BT_CHARACTER)
+ {
+ args = NULL_TREE;
+
+ assert (lse->string_length != NULL_TREE
+ && rse->string_length != NULL_TREE);
+
+ gfc_conv_string_parameter (lse);
+ gfc_conv_string_parameter (rse);
+
+ gfc_add_block_to_block (&block, &lse->pre);
+ gfc_add_block_to_block (&block, &rse->pre);
+
+ args = gfc_chainon_list (args, lse->string_length);
+ args = gfc_chainon_list (args, lse->expr);
+ args = gfc_chainon_list (args, rse->string_length);
+ args = gfc_chainon_list (args, rse->expr);
+
+ tmp = gfc_build_function_call (gfor_fndecl_copy_string, args);
+ gfc_add_expr_to_block (&block, tmp);
+ }
+ else
+ {
+ gfc_add_block_to_block (&block, &lse->pre);
+ gfc_add_block_to_block (&block, &rse->pre);
+
+ gfc_add_modify_expr (&block, lse->expr, rse->expr);
+ }
+
+ gfc_add_block_to_block (&block, &lse->post);
+ gfc_add_block_to_block (&block, &rse->post);
+
+ return gfc_finish_block (&block);
+}
+
+
+/* Try to translate array(:) = func (...), where func is a transformational
+ array function, without using a temporary. Returns NULL is this isn't the
+ case. */
+
+static tree
+gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
+{
+ gfc_se se;
+ gfc_ss *ss;
+
+ /* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
+ if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
+ return NULL;
+
+ /* Elemental functions don't need a temporary anyway. */
+ if (expr2->symtree->n.sym->attr.elemental)
+ return NULL;
+
+ /* Check for a dependency. */
+ if (gfc_check_fncall_dependency (expr1, expr2))
+ return NULL;
+
+ /* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
+ functions. */
+ assert (expr2->value.function.isym
+ || (gfc_return_by_reference (expr2->symtree->n.sym)
+ && expr2->symtree->n.sym->result->attr.dimension));
+
+ ss = gfc_walk_expr (expr1);
+ assert (ss != gfc_ss_terminator);
+ gfc_init_se (&se, NULL);
+ gfc_start_block (&se.pre);
+ se.want_pointer = 1;
+
+ gfc_conv_array_parameter (&se, expr1, ss, 0);
+
+ se.direct_byref = 1;
+ se.ss = gfc_walk_expr (expr2);
+ assert (se.ss != gfc_ss_terminator);
+ gfc_conv_function_expr (&se, expr2);
+ gfc_add_expr_to_block (&se.pre, se.expr);
+ gfc_add_block_to_block (&se.pre, &se.post);
+
+ return gfc_finish_block (&se.pre);
+}
+
+
+/* Translate an assignment. Most of the code is concerned with
+ setting up the scalarizer. */
+
+tree
+gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2)
+{
+ gfc_se lse;
+ gfc_se rse;
+ gfc_ss *lss;
+ gfc_ss *lss_section;
+ gfc_ss *rss;
+ gfc_loopinfo loop;
+ tree tmp;
+ stmtblock_t block;
+ stmtblock_t body;
+
+ /* Special case a single function returning an array. */
+ if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
+ {
+ tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
+ if (tmp)
+ return tmp;
+ }
+
+ /* Assignment of the form lhs = rhs. */
+ gfc_start_block (&block);
+
+ gfc_init_se (&lse, NULL);
+ gfc_init_se (&rse, NULL);
+
+ /* Walk the lhs. */
+ lss = gfc_walk_expr (expr1);
+ rss = NULL;
+ if (lss != gfc_ss_terminator)
+ {
+ /* The assignment needs scalarization. */
+ lss_section = lss;
+
+ /* Find a non-scalar SS from the lhs. */
+ while (lss_section != gfc_ss_terminator
+ && lss_section->type != GFC_SS_SECTION)
+ lss_section = lss_section->next;
+
+ assert (lss_section != gfc_ss_terminator);
+
+ /* Initialize the scalarizer. */
+ gfc_init_loopinfo (&loop);
+
+ /* Walk the rhs. */
+ rss = gfc_walk_expr (expr2);
+ if (rss == gfc_ss_terminator)
+ {
+ /* The rhs is scalar. Add a ss for the expression. */
+ rss = gfc_get_ss ();
+ rss->next = gfc_ss_terminator;
+ rss->type = GFC_SS_SCALAR;
+ rss->expr = expr2;
+ }
+ /* Associate the SS with the loop. */
+ gfc_add_ss_to_loop (&loop, lss);
+ gfc_add_ss_to_loop (&loop, rss);
+
+ /* Calculate the bounds of the scalarization. */
+ gfc_conv_ss_startstride (&loop);
+ /* Resolve any data dependencies in the statement. */
+ gfc_conv_resolve_dependencies (&loop, lss_section, rss);
+ /* Setup the scalarizing loops. */
+ gfc_conv_loop_setup (&loop);
+
+ /* Setup the gfc_se structures. */
+ gfc_copy_loopinfo_to_se (&lse, &loop);
+ gfc_copy_loopinfo_to_se (&rse, &loop);
+
+ rse.ss = rss;
+ gfc_mark_ss_chain_used (rss, 1);
+ if (loop.temp_ss == NULL)
+ {
+ lse.ss = lss;
+ gfc_mark_ss_chain_used (lss, 1);
+ }
+ else
+ {
+ lse.ss = loop.temp_ss;
+ gfc_mark_ss_chain_used (lss, 3);
+ gfc_mark_ss_chain_used (loop.temp_ss, 3);
+ }
+
+ /* Start the scalarized loop body. */
+ gfc_start_scalarized_body (&loop, &body);
+ }
+ else
+ gfc_init_block (&body);
+
+ /* Translate the expression. */
+ gfc_conv_expr (&rse, expr2);
+
+ if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
+ {
+ gfc_conv_tmp_array_ref (&lse);
+ gfc_advance_se_ss_chain (&lse);
+ }
+ else
+ gfc_conv_expr (&lse, expr1);
+
+ tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts.type);
+ gfc_add_expr_to_block (&body, tmp);
+
+ if (lss == gfc_ss_terminator)
+ {
+ /* Use the scalar assignment as is. */
+ gfc_add_block_to_block (&block, &body);
+ }
+ else
+ {
+ if (lse.ss != gfc_ss_terminator)
+ abort ();
+ if (rse.ss != gfc_ss_terminator)
+ abort ();
+
+ if (loop.temp_ss != NULL)
+ {
+ gfc_trans_scalarized_loop_boundary (&loop, &body);
+
+ /* We need to copy the temporary to the actual lhs. */
+ gfc_init_se (&lse, NULL);
+ gfc_init_se (&rse, NULL);
+ gfc_copy_loopinfo_to_se (&lse, &loop);
+ gfc_copy_loopinfo_to_se (&rse, &loop);
+
+ rse.ss = loop.temp_ss;
+ lse.ss = lss;
+
+ gfc_conv_tmp_array_ref (&rse);
+ gfc_advance_se_ss_chain (&rse);
+ gfc_conv_expr (&lse, expr1);
+
+ if (lse.ss != gfc_ss_terminator)
+ abort ();
+
+ if (rse.ss != gfc_ss_terminator)
+ abort ();
+
+ tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts.type);
+ gfc_add_expr_to_block (&body, tmp);
+ }
+ /* Generate the copying loops. */
+ gfc_trans_scalarizing_loops (&loop, &body);
+
+ /* Wrap the whole thing up. */
+ gfc_add_block_to_block (&block, &loop.pre);
+ gfc_add_block_to_block (&block, &loop.post);
+
+ gfc_cleanup_loop (&loop);
+ }
+
+ return gfc_finish_block (&block);
+}
+
+tree
+gfc_trans_assign (gfc_code * code)
+{
+ return gfc_trans_assignment (code->expr, code->expr2);
+}
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
new file mode 100644
index 00000000000..96eb306adc1
--- /dev/null
+++ b/gcc/fortran/trans-intrinsic.c
@@ -0,0 +1,3012 @@
+/* Intrinsic translation
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+ and Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* trans-intrinsic.c-- generate GENERIC trees for calls to intrinsics. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include <stdio.h>
+#include <string.h>
+#include "ggc.h"
+#include "toplev.h"
+#include "real.h"
+#include "tree-gimple.h"
+#include "flags.h"
+#include <gmp.h>
+#include <assert.h>
+#include "gfortran.h"
+#include "intrinsic.h"
+#include "trans.h"
+#include "trans-const.h"
+#include "trans-types.h"
+#include "trans-array.h"
+#include "defaults.h"
+/* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
+#include "trans-stmt.h"
+
+/* This maps fortran intrinsic math functions to external library or GCC
+ builtin functions. */
+typedef struct gfc_intrinsic_map_t GTY(())
+{
+ /* The explicit enum is required to work around inadequacies in the
+ garbage collection/gengtype parsing mechanism. */
+ enum gfc_generic_isym_id id;
+
+ /* Enum value from the "language-independent", aka C-centric, part
+ of gcc, or END_BUILTINS of no such value set. */
+ /* ??? There are now complex variants in builtins.def, though we
+ don't currently do anything with them. */
+ enum built_in_function code4;
+ enum built_in_function code8;
+
+ /* True if the naming pattern is to prepend "c" for complex and
+ append "f" for kind=4. False if the naming pattern is to
+ prepend "_gfortran_" and append "[rc][48]". */
+ bool libm_name;
+
+ /* True if a complex version of the function exists. */
+ bool complex_available;
+
+ /* True if the function should be marked const. */
+ bool is_constant;
+
+ /* The base library name of this function. */
+ const char *name;
+
+ /* Cache decls created for the various operand types. */
+ tree real4_decl;
+ tree real8_decl;
+ tree complex4_decl;
+ tree complex8_decl;
+}
+gfc_intrinsic_map_t;
+
+/* ??? The NARGS==1 hack here is based on the fact that (c99 at least)
+ defines complex variants of all of the entries in mathbuiltins.def
+ except for atan2. */
+#define DEFINE_MATH_BUILTIN(ID, NAME, NARGS) \
+ { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, true, \
+ NARGS == 1, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
+
+#define LIBM_FUNCTION(ID, NAME, HAVE_COMPLEX) \
+ { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, true, HAVE_COMPLEX, true, \
+ NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
+
+#define LIBF_FUNCTION(ID, NAME, HAVE_COMPLEX) \
+ { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, false, HAVE_COMPLEX, true, \
+ NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
+
+static GTY(()) gfc_intrinsic_map_t gfc_intrinsic_map[] =
+{
+ /* Functions built into gcc itself. */
+#include "mathbuiltins.def"
+
+ /* Functions in libm. */
+ /* ??? This does exist as BUILT_IN_SCALBN, but doesn't quite fit the
+ pattern for other mathbuiltins.def entries. At present we have no
+ optimizations for this in the common sources. */
+ LIBM_FUNCTION (SCALE, "scalbn", false),
+
+ /* Functions in libgfortran. */
+ LIBF_FUNCTION (FRACTION, "fraction", false),
+ LIBF_FUNCTION (NEAREST, "nearest", false),
+ LIBF_FUNCTION (SET_EXPONENT, "set_exponent", false),
+
+ /* End the list. */
+ LIBF_FUNCTION (NONE, NULL, false)
+};
+#undef DEFINE_MATH_BUILTIN
+#undef LIBM_FUNCTION
+#undef LIBF_FUNCTION
+
+/* Structure for storing components of a floating number to be used by
+ elemental functions to manipulate reals. */
+typedef struct
+{
+ tree arg; /* Variable tree to view convert to integer. */
+ tree expn; /* Variable tree to save exponent. */
+ tree frac; /* Variable tree to save fraction. */
+ tree smask; /* Constant tree of sign's mask. */
+ tree emask; /* Constant tree of exponent's mask. */
+ tree fmask; /* Constant tree of fraction's mask. */
+ tree edigits; /* Constant tree of bit numbers of exponent. */
+ tree fdigits; /* Constant tree of bit numbers of fraction. */
+ tree f1; /* Constant tree of the f1 defined in the real model. */
+ tree bias; /* Constant tree of the bias of exponent in the memory. */
+ tree type; /* Type tree of arg1. */
+ tree mtype; /* Type tree of integer type. Kind is that of arg1. */
+}
+real_compnt_info;
+
+
+/* Evaluate the arguments to an intrinsic function. */
+
+static tree
+gfc_conv_intrinsic_function_args (gfc_se * se, gfc_expr * expr)
+{
+ gfc_actual_arglist *actual;
+ tree args;
+ gfc_se argse;
+
+ args = NULL_TREE;
+ for (actual = expr->value.function.actual; actual; actual = actual->next)
+ {
+ /* Skip ommitted optional arguments. */
+ if (!actual->expr)
+ continue;
+
+ /* Evaluate the parameter. This will substitute scalarized
+ references automatically. */
+ gfc_init_se (&argse, se);
+
+ if (actual->expr->ts.type == BT_CHARACTER)
+ {
+ gfc_conv_expr (&argse, actual->expr);
+ gfc_conv_string_parameter (&argse);
+ args = gfc_chainon_list (args, argse.string_length);
+ }
+ else
+ gfc_conv_expr_val (&argse, actual->expr);
+
+ gfc_add_block_to_block (&se->pre, &argse.pre);
+ gfc_add_block_to_block (&se->post, &argse.post);
+ args = gfc_chainon_list (args, argse.expr);
+ }
+ return args;
+}
+
+
+/* Conversions between different types are output by the frontend as
+ intrinsic functions. We implement these directly with inline code. */
+
+static void
+gfc_conv_intrinsic_conversion (gfc_se * se, gfc_expr * expr)
+{
+ tree type;
+ tree arg;
+
+ /* Evaluate the argument. */
+ type = gfc_typenode_for_spec (&expr->ts);
+ assert (expr->value.function.actual->expr);
+ arg = gfc_conv_intrinsic_function_args (se, expr);
+ arg = TREE_VALUE (arg);
+
+ /* Conversion from complex to non-complex involves taking the real
+ component of the value. */
+ if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE
+ && expr->ts.type != BT_COMPLEX)
+ {
+ tree artype;
+
+ artype = TREE_TYPE (TREE_TYPE (arg));
+ arg = build1 (REALPART_EXPR, artype, arg);
+ }
+
+ se->expr = convert (type, arg);
+}
+
+
+/* This is needed because the gcc backend only implements FIX_TRUNC_EXPR
+ TRUNC(x) = INT(x) <= x ? INT(x) : INT(x) - 1
+ Similarly for CEILING. */
+
+static tree
+build_fixbound_expr (stmtblock_t * pblock, tree arg, tree type, int up)
+{
+ tree tmp;
+ tree cond;
+ tree argtype;
+ tree intval;
+
+ argtype = TREE_TYPE (arg);
+ arg = gfc_evaluate_now (arg, pblock);
+
+ intval = convert (type, arg);
+ intval = gfc_evaluate_now (intval, pblock);
+
+ tmp = convert (argtype, intval);
+ cond = build (up ? GE_EXPR : LE_EXPR, boolean_type_node, tmp, arg);
+
+ tmp = build (up ? PLUS_EXPR : MINUS_EXPR, type, intval, integer_one_node);
+ tmp = build (COND_EXPR, type, cond, intval, tmp);
+ return tmp;
+}
+
+
+/* This is needed because the gcc backend only implements FIX_TRUNC_EXPR
+ NINT(x) = INT(x + ((x > 0) ? 0.5 : -0.5)). */
+
+static tree
+build_round_expr (stmtblock_t * pblock, tree arg, tree type)
+{
+ tree tmp;
+ tree cond;
+ tree neg;
+ tree pos;
+ tree argtype;
+ REAL_VALUE_TYPE r;
+
+ argtype = TREE_TYPE (arg);
+ arg = gfc_evaluate_now (arg, pblock);
+
+ real_from_string (&r, "0.5");
+ pos = build_real (argtype, r);
+
+ real_from_string (&r, "-0.5");
+ neg = build_real (argtype, r);
+
+ tmp = gfc_build_const (argtype, integer_zero_node);
+ cond = fold (build (GT_EXPR, boolean_type_node, arg, tmp));
+
+ tmp = fold (build (COND_EXPR, argtype, cond, pos, neg));
+ tmp = fold (build (PLUS_EXPR, argtype, arg, tmp));
+ return fold (build1 (FIX_TRUNC_EXPR, type, tmp));
+}
+
+
+/* Convert a real to an integer using a specific rounding mode.
+ Ideally we would just build the corresponding GENERIC node,
+ however the RTL expander only actually supports FIX_TRUNC_EXPR. */
+
+static tree
+build_fix_expr (stmtblock_t * pblock, tree arg, tree type, int op)
+{
+ switch (op)
+ {
+ case FIX_FLOOR_EXPR:
+ return build_fixbound_expr (pblock, arg, type, 0);
+ break;
+
+ case FIX_CEIL_EXPR:
+ return build_fixbound_expr (pblock, arg, type, 1);
+ break;
+
+ case FIX_ROUND_EXPR:
+ return build_round_expr (pblock, arg, type);
+
+ default:
+ return build1 (op, type, arg);
+ }
+}
+
+
+/* Round a real value using the specified rounding mode.
+ We use a temporary integer of that same kind size as the result.
+ Values larger than can be represented by this kind are unchanged, as
+ will not be accurate enough to represent the rounding.
+ huge = HUGE (KIND (a))
+ aint (a) = ((a > huge) || (a < -huge)) ? a : (real)(int)a
+ */
+
+static void
+gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, int op)
+{
+ tree type;
+ tree itype;
+ tree arg;
+ tree tmp;
+ tree cond;
+ mpf_t huge;
+ int n;
+ int kind;
+
+ kind = expr->ts.kind;
+
+ n = END_BUILTINS;
+ /* We have builtin functions for some cases. */
+ switch (op)
+ {
+ case FIX_ROUND_EXPR:
+ switch (kind)
+ {
+ case 4:
+ n = BUILT_IN_ROUNDF;
+ break;
+
+ case 8:
+ n = BUILT_IN_ROUND;
+ break;
+ }
+ break;
+
+ case FIX_FLOOR_EXPR:
+ switch (kind)
+ {
+ case 4:
+ n = BUILT_IN_FLOORF;
+ break;
+
+ case 8:
+ n = BUILT_IN_FLOOR;
+ break;
+ }
+ }
+
+ /* Evaluate the argument. */
+ assert (expr->value.function.actual->expr);
+ arg = gfc_conv_intrinsic_function_args (se, expr);
+
+ /* Use a builtin function if one exists. */
+ if (n != END_BUILTINS)
+ {
+ tmp = built_in_decls[n];
+ se->expr = gfc_build_function_call (tmp, arg);
+ return;
+ }
+
+ /* This code is probably redundant, but we'll keep it lying around just
+ in case. */
+ type = gfc_typenode_for_spec (&expr->ts);
+ arg = TREE_VALUE (arg);
+ arg = gfc_evaluate_now (arg, &se->pre);
+
+ /* Test if the value is too large to handle sensibly. */
+ mpf_init (huge);
+ n = gfc_validate_kind (BT_INTEGER, kind);
+ mpf_set_z (huge, gfc_integer_kinds[n].huge);
+ tmp = gfc_conv_mpf_to_tree (huge, kind);
+ cond = build (LT_EXPR, boolean_type_node, arg, tmp);
+
+ mpf_neg (huge, huge);
+ tmp = gfc_conv_mpf_to_tree (huge, kind);
+ tmp = build (GT_EXPR, boolean_type_node, arg, tmp);
+ cond = build (TRUTH_AND_EXPR, boolean_type_node, cond, tmp);
+ itype = gfc_get_int_type (kind);
+
+ tmp = build_fix_expr (&se->pre, arg, itype, op);
+ tmp = convert (type, tmp);
+ se->expr = build (COND_EXPR, type, cond, tmp, arg);
+}
+
+
+/* Convert to an integer using the specified rounding mode. */
+
+static void
+gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, int op)
+{
+ tree type;
+ tree arg;
+
+ /* Evaluate the argument. */
+ type = gfc_typenode_for_spec (&expr->ts);
+ assert (expr->value.function.actual->expr);
+ arg = gfc_conv_intrinsic_function_args (se, expr);
+ arg = TREE_VALUE (arg);
+
+ if (TREE_CODE (TREE_TYPE (arg)) == INTEGER_TYPE)
+ {
+ /* Conversion to a different integer kind. */
+ se->expr = convert (type, arg);
+ }
+ else
+ {
+ /* Conversion from complex to non-complex involves taking the real
+ component of the value. */
+ if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE
+ && expr->ts.type != BT_COMPLEX)
+ {
+ tree artype;
+
+ artype = TREE_TYPE (TREE_TYPE (arg));
+ arg = build1 (REALPART_EXPR, artype, arg);
+ }
+
+ se->expr = build_fix_expr (&se->pre, arg, type, op);
+ }
+}
+
+
+/* Get the imaginary component of a value. */
+
+static void
+gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
+{
+ tree arg;
+
+ arg = gfc_conv_intrinsic_function_args (se, expr);
+ arg = TREE_VALUE (arg);
+ se->expr = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
+}
+
+
+/* Get the complex conjugate of a value. */
+
+static void
+gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
+{
+ tree arg;
+
+ arg = gfc_conv_intrinsic_function_args (se, expr);
+ arg = TREE_VALUE (arg);
+ se->expr = build1 (CONJ_EXPR, TREE_TYPE (arg), arg);
+}
+
+
+/* Initialize function decls for library functions. The external functions
+ are created as required. Builtin functions are added here. */
+
+void
+gfc_build_intrinsic_lib_fndecls (void)
+{
+ gfc_intrinsic_map_t *m;
+
+ /* Add GCC builtin functions. */
+ for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
+ {
+ if (m->code4 != END_BUILTINS)
+ m->real4_decl = built_in_decls[m->code4];
+ if (m->code8 != END_BUILTINS)
+ m->real8_decl = built_in_decls[m->code8];
+ }
+}
+
+
+/* Create a fndecl for a simple intrinsic library function. */
+
+static tree
+gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
+{
+ tree type;
+ tree argtypes;
+ tree fndecl;
+ gfc_actual_arglist *actual;
+ tree *pdecl;
+ gfc_typespec *ts;
+ char name[GFC_MAX_SYMBOL_LEN + 3];
+
+ ts = &expr->ts;
+ if (ts->type == BT_REAL)
+ {
+ switch (ts->kind)
+ {
+ case 4:
+ pdecl = &m->real4_decl;
+ break;
+ case 8:
+ pdecl = &m->real8_decl;
+ break;
+ default:
+ abort ();
+ }
+ }
+ else if (ts->type == BT_COMPLEX)
+ {
+ if (!m->complex_available)
+ abort ();
+
+ switch (ts->kind)
+ {
+ case 4:
+ pdecl = &m->complex4_decl;
+ break;
+ case 8:
+ pdecl = &m->complex8_decl;
+ break;
+ default:
+ abort ();
+ }
+ }
+ else
+ abort ();
+
+ if (*pdecl)
+ return *pdecl;
+
+ if (m->libm_name)
+ {
+ if (ts->kind != 4 && ts->kind != 8)
+ abort ();
+ snprintf (name, sizeof (name), "%s%s%s",
+ ts->type == BT_COMPLEX ? "c" : "",
+ m->name,
+ ts->kind == 4 ? "f" : "");
+ }
+ else
+ {
+ snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
+ ts->type == BT_COMPLEX ? 'c' : 'r',
+ ts->kind);
+ }
+
+ argtypes = NULL_TREE;
+ for (actual = expr->value.function.actual; actual; actual = actual->next)
+ {
+ type = gfc_typenode_for_spec (&actual->expr->ts);
+ argtypes = gfc_chainon_list (argtypes, type);
+ }
+ argtypes = gfc_chainon_list (argtypes, void_type_node);
+ type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
+ fndecl = build_decl (FUNCTION_DECL, get_identifier (name), type);
+
+ /* Mark the decl as external. */
+ DECL_EXTERNAL (fndecl) = 1;
+ TREE_PUBLIC (fndecl) = 1;
+
+ /* Mark it __attribute__((const)), if possible. */
+ TREE_READONLY (fndecl) = m->is_constant;
+
+ rest_of_decl_compilation (fndecl, NULL, 1, 0);
+
+ (*pdecl) = fndecl;
+ return fndecl;
+}
+
+
+/* Convert an intrinsic function into an external or builtin call. */
+
+static void
+gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
+{
+ gfc_intrinsic_map_t *m;
+ tree args;
+ tree fndecl;
+ gfc_generic_isym_id id;
+
+ id = expr->value.function.isym->generic_id;
+ /* Find the entry for this function. */
+ for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
+ {
+ if (id == m->id)
+ break;
+ }
+
+ if (m->id == GFC_ISYM_NONE)
+ {
+ internal_error ("Intrinsic function %s(%d) not recognized",
+ expr->value.function.name, id);
+ }
+
+ /* Get the decl and generate the call. */
+ args = gfc_conv_intrinsic_function_args (se, expr);
+ fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
+ se->expr = gfc_build_function_call (fndecl, args);
+}
+
+/* Generate code for EXPONENT(X) intrinsic function. */
+
+static void
+gfc_conv_intrinsic_exponent (gfc_se * se, gfc_expr * expr)
+{
+ tree args, fndecl;
+ gfc_expr *a1;
+
+ args = gfc_conv_intrinsic_function_args (se, expr);
+
+ a1 = expr->value.function.actual->expr;
+ switch (a1->ts.kind)
+ {
+ case 4:
+ fndecl = gfor_fndecl_math_exponent4;
+ break;
+ case 8:
+ fndecl = gfor_fndecl_math_exponent8;
+ break;
+ default:
+ abort ();
+ }
+
+ se->expr = gfc_build_function_call (fndecl, args);
+}
+
+/* Evaluate a single upper or lower bound. */
+/* TODO: bound intrinsic generates way too much unneccessary code. */
+
+static void
+gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
+{
+ gfc_actual_arglist *arg;
+ gfc_actual_arglist *arg2;
+ tree desc;
+ tree type;
+ tree bound;
+ tree tmp;
+ tree cond;
+ gfc_se argse;
+ gfc_ss *ss;
+ int i;
+
+ gfc_init_se (&argse, NULL);
+ arg = expr->value.function.actual;
+ arg2 = arg->next;
+
+ if (se->ss)
+ {
+ /* Create an implicit second parameter from the loop variable. */
+ assert (!arg2->expr);
+ assert (se->loop->dimen == 1);
+ assert (se->ss->expr == expr);
+ gfc_advance_se_ss_chain (se);
+ bound = se->loop->loopvar[0];
+ bound = fold (build (MINUS_EXPR, gfc_array_index_type, bound,
+ se->loop->from[0]));
+ }
+ else
+ {
+ /* use the passed argument. */
+ assert (arg->next->expr);
+ gfc_init_se (&argse, NULL);
+ gfc_conv_expr_type (&argse, arg->next->expr, gfc_array_index_type);
+ gfc_add_block_to_block (&se->pre, &argse.pre);
+ bound = argse.expr;
+ /* Convert from one based to zero based. */
+ bound = fold (build (MINUS_EXPR, gfc_array_index_type, bound,
+ integer_one_node));
+ }
+
+ /* TODO: don't re-evaluate the descriptor on each iteration. */
+ /* Get a descriptor for the first parameter. */
+ ss = gfc_walk_expr (arg->expr);
+ assert (ss != gfc_ss_terminator);
+ argse.want_pointer = 0;
+ gfc_conv_expr_descriptor (&argse, arg->expr, ss);
+ gfc_add_block_to_block (&se->pre, &argse.pre);
+ gfc_add_block_to_block (&se->post, &argse.post);
+
+ desc = argse.expr;
+
+ if (INTEGER_CST_P (bound))
+ {
+ assert (TREE_INT_CST_HIGH (bound) == 0);
+ i = TREE_INT_CST_LOW (bound);
+ assert (i >= 0 && i < GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc)));
+ }
+ else
+ {
+ if (flag_bounds_check)
+ {
+ bound = gfc_evaluate_now (bound, &se->pre);
+ cond = fold (build (LT_EXPR, boolean_type_node, bound,
+ integer_zero_node));
+ tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
+ tmp = fold (build (GE_EXPR, boolean_type_node, bound, tmp));
+ cond = fold(build (TRUTH_ORIF_EXPR, boolean_type_node, cond, tmp));
+ gfc_trans_runtime_check (cond, gfc_strconst_fault, &se->pre);
+ }
+ }
+
+ if (upper)
+ se->expr = gfc_conv_descriptor_ubound(desc, bound);
+ else
+ se->expr = gfc_conv_descriptor_lbound(desc, bound);
+
+ type = gfc_typenode_for_spec (&expr->ts);
+ se->expr = convert (type, se->expr);
+}
+
+
+static void
+gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
+{
+ tree args;
+ tree val;
+ tree fndecl;
+
+ args = gfc_conv_intrinsic_function_args (se, expr);
+ assert (args && TREE_CHAIN (args) == NULL_TREE);
+ val = TREE_VALUE (args);
+
+ switch (expr->value.function.actual->expr->ts.type)
+ {
+ case BT_INTEGER:
+ case BT_REAL:
+ se->expr = build1 (ABS_EXPR, TREE_TYPE (val), val);
+ break;
+
+ case BT_COMPLEX:
+ switch (expr->ts.kind)
+ {
+ case 4:
+ fndecl = gfor_fndecl_math_cabsf;
+ break;
+ case 8:
+ fndecl = gfor_fndecl_math_cabs;
+ break;
+ default:
+ abort ();
+ }
+ se->expr = gfc_build_function_call (fndecl, args);
+ break;
+
+ default:
+ abort ();
+ }
+}
+
+
+/* Create a complex value from one or two real components. */
+
+static void
+gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
+{
+ tree arg;
+ tree real;
+ tree imag;
+ tree type;
+
+ type = gfc_typenode_for_spec (&expr->ts);
+ arg = gfc_conv_intrinsic_function_args (se, expr);
+ real = convert (TREE_TYPE (type), TREE_VALUE (arg));
+ if (both)
+ imag = convert (TREE_TYPE (type), TREE_VALUE (TREE_CHAIN (arg)));
+ else if (TREE_CODE (TREE_TYPE (TREE_VALUE (arg))) == COMPLEX_TYPE)
+ {
+ arg = TREE_VALUE (arg);
+ imag = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
+ imag = convert (TREE_TYPE (type), imag);
+ }
+ else
+ imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
+
+ se->expr = fold (build (COMPLEX_EXPR, type, real, imag));
+}
+
+/* Remainder function MOD(A, P) = A - INT(A / P) * P.
+ MODULO(A, P) = (A==0 .or. !(A>0 .xor. P>0))? MOD(A,P):MOD(A,P)+P. */
+/* TODO: MOD(x, 0) */
+
+static void
+gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
+{
+ tree arg;
+ tree arg2;
+ tree type;
+ tree itype;
+ tree tmp;
+ tree zero;
+ tree test;
+ tree test2;
+ mpf_t huge;
+ int n;
+
+ arg = gfc_conv_intrinsic_function_args (se, expr);
+ arg2 = TREE_VALUE (TREE_CHAIN (arg));
+ arg = TREE_VALUE (arg);
+ type = TREE_TYPE (arg);
+
+ switch (expr->ts.type)
+ {
+ case BT_INTEGER:
+ /* Integer case is easy, we've got a builtin op. */
+ se->expr = build (TRUNC_MOD_EXPR, type, arg, arg2);
+ break;
+
+ case BT_REAL:
+ /* Real values we have to do the hard way. */
+ arg = gfc_evaluate_now (arg, &se->pre);
+ arg2 = gfc_evaluate_now (arg2, &se->pre);
+
+ tmp = build (RDIV_EXPR, type, arg, arg2);
+ /* Test if the value is too large to handle sensibly. */
+ mpf_init (huge);
+ n = gfc_validate_kind (BT_INTEGER, expr->ts.kind);
+ mpf_set_z (huge, gfc_integer_kinds[n].huge);
+ test = gfc_conv_mpf_to_tree (huge, expr->ts.kind);
+ test2 = build (LT_EXPR, boolean_type_node, tmp, test);
+
+ mpf_neg (huge, huge);
+ test = gfc_conv_mpf_to_tree (huge, expr->ts.kind);
+ test = build (GT_EXPR, boolean_type_node, tmp, test);
+ test2 = build (TRUTH_AND_EXPR, boolean_type_node, test, test2);
+
+ itype = gfc_get_int_type (expr->ts.kind);
+ tmp = build_fix_expr (&se->pre, tmp, itype, FIX_TRUNC_EXPR);
+ tmp = convert (type, tmp);
+ tmp = build (COND_EXPR, type, test2, tmp, arg);
+ tmp = build (MULT_EXPR, type, tmp, arg2);
+ se->expr = build (MINUS_EXPR, type, arg, tmp);
+ break;
+
+ default:
+ abort ();
+ }
+
+ if (modulo)
+ {
+ zero = gfc_build_const (type, integer_zero_node);
+ /* Build !(A > 0 .xor. P > 0). */
+ test = build (GT_EXPR, boolean_type_node, arg, zero);
+ test2 = build (GT_EXPR, boolean_type_node, arg2, zero);
+ test = build (TRUTH_XOR_EXPR, boolean_type_node, test, test2);
+ test = build1 (TRUTH_NOT_EXPR, boolean_type_node, test);
+ /* Build (A == 0) .or. !(A > 0 .xor. P > 0). */
+ test2 = build (EQ_EXPR, boolean_type_node, arg, zero);
+ test = build (TRUTH_OR_EXPR, boolean_type_node, test, test2);
+
+ se->expr = build (COND_EXPR, type, test, se->expr,
+ build (PLUS_EXPR, type, se->expr, arg2));
+ }
+}
+
+/* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
+
+static void
+gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
+{
+ tree arg;
+ tree arg2;
+ tree val;
+ tree tmp;
+ tree type;
+ tree zero;
+
+ arg = gfc_conv_intrinsic_function_args (se, expr);
+ arg2 = TREE_VALUE (TREE_CHAIN (arg));
+ arg = TREE_VALUE (arg);
+ type = TREE_TYPE (arg);
+
+ val = build (MINUS_EXPR, type, arg, arg2);
+ val = gfc_evaluate_now (val, &se->pre);
+
+ zero = gfc_build_const (type, integer_zero_node);
+ tmp = build (LE_EXPR, boolean_type_node, val, zero);
+ se->expr = build (COND_EXPR, type, tmp, zero, val);
+}
+
+
+/* SIGN(A, B) is absolute value of A times sign of B.
+ The real value versions use library functions to ensure the correct
+ handling of negative zero. Integer case implemented as:
+ SIGN(A, B) = ((a >= 0) .xor. (b >= 0)) ? a : -a
+ */
+
+static void
+gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
+{
+ tree tmp;
+ tree arg;
+ tree arg2;
+ tree type;
+ tree zero;
+ tree testa;
+ tree testb;
+
+
+ arg = gfc_conv_intrinsic_function_args (se, expr);
+ if (expr->ts.type == BT_REAL)
+ {
+ switch (expr->ts.kind)
+ {
+ case 4:
+ tmp = gfor_fndecl_math_sign4;
+ break;
+ case 8:
+ tmp = gfor_fndecl_math_sign8;
+ break;
+ default:
+ abort ();
+ }
+ se->expr = gfc_build_function_call (tmp, arg);
+ return;
+ }
+
+ arg2 = TREE_VALUE (TREE_CHAIN (arg));
+ arg = TREE_VALUE (arg);
+ type = TREE_TYPE (arg);
+ zero = gfc_build_const (type, integer_zero_node);
+
+ testa = fold (build (GE_EXPR, boolean_type_node, arg, zero));
+ testb = fold (build (GE_EXPR, boolean_type_node, arg2, zero));
+ tmp = fold (build (TRUTH_XOR_EXPR, boolean_type_node, testa, testb));
+ se->expr = fold (build (COND_EXPR, type, tmp,
+ build1 (NEGATE_EXPR, type, arg), arg));
+}
+
+
+/* Test for the presence of an optional argument. */
+
+static void
+gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
+{
+ gfc_expr *arg;
+
+ arg = expr->value.function.actual->expr;
+ assert (arg->expr_type == EXPR_VARIABLE);
+ se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
+ se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
+}
+
+
+/* Calculate the double precision product of two single precision values. */
+
+static void
+gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
+{
+ tree arg;
+ tree arg2;
+ tree type;
+
+ arg = gfc_conv_intrinsic_function_args (se, expr);
+ arg2 = TREE_VALUE (TREE_CHAIN (arg));
+ arg = TREE_VALUE (arg);
+
+ /* Convert the args to double precision before multiplying. */
+ type = gfc_typenode_for_spec (&expr->ts);
+ arg = convert (type, arg);
+ arg2 = convert (type, arg2);
+ se->expr = build (MULT_EXPR, type, arg, arg2);
+}
+
+
+/* Return a length one character string containing an ascii character. */
+
+static void
+gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
+{
+ tree arg;
+ tree var;
+ tree type;
+
+ arg = gfc_conv_intrinsic_function_args (se, expr);
+ arg = TREE_VALUE (arg);
+
+ /* We currently don't support character types != 1. */
+ assert (expr->ts.kind == 1);
+ type = gfc_character1_type_node;
+ var = gfc_create_var (type, "char");
+
+ arg = convert (type, arg);
+ gfc_add_modify_expr (&se->pre, var, arg);
+ se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
+ se->string_length = integer_one_node;
+}
+
+
+/* Get the minimum/maximum value of all the parameters.
+ minmax (a1, a2, a3, ...)
+ {
+ if (a2 .op. a1)
+ mvar = a2;
+ else
+ mvar = a1;
+ if (a3 .op. mvar)
+ mvar = a3;
+ ...
+ return mvar
+ }
+ */
+
+/* TODO: Mismatching types can occur when specific names are used.
+ These should be handled during resolution. */
+static void
+gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, int op)
+{
+ tree limit;
+ tree tmp;
+ tree mvar;
+ tree val;
+ tree thencase;
+ tree elsecase;
+ tree arg;
+ tree type;
+
+ arg = gfc_conv_intrinsic_function_args (se, expr);
+ type = gfc_typenode_for_spec (&expr->ts);
+
+ limit = TREE_VALUE (arg);
+ if (TREE_TYPE (limit) != type)
+ limit = convert (type, limit);
+ /* Only evaluate the argument once. */
+ if (TREE_CODE (limit) != VAR_DECL && !TREE_CONSTANT (limit))
+ limit = gfc_evaluate_now(limit, &se->pre);
+
+ mvar = gfc_create_var (type, "M");
+ elsecase = build_v (MODIFY_EXPR, mvar, limit);
+ for (arg = TREE_CHAIN (arg); arg != NULL_TREE; arg = TREE_CHAIN (arg))
+ {
+ val = TREE_VALUE (arg);
+ if (TREE_TYPE (val) != type)
+ val = convert (type, val);
+
+ /* Only evaluate the argument once. */
+ if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
+ val = gfc_evaluate_now(val, &se->pre);
+
+ thencase = build_v (MODIFY_EXPR, mvar, convert (type, val));
+
+ tmp = build (op, boolean_type_node, val, limit);
+ tmp = build_v (COND_EXPR, tmp, thencase, elsecase);
+ gfc_add_expr_to_block (&se->pre, tmp);
+ elsecase = build_empty_stmt ();
+ limit = mvar;
+ }
+ se->expr = mvar;
+}
+
+
+/* Create a symbol node for this intrinsic. The symbol form the frontend
+ is for the generic name. */
+
+static gfc_symbol *
+gfc_get_symbol_for_expr (gfc_expr * expr)
+{
+ gfc_symbol *sym;
+
+ /* TODO: Add symbols for intrinsic function to the global namespace. */
+ assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
+ sym = gfc_new_symbol (expr->value.function.name, NULL);
+
+ sym->ts = expr->ts;
+ sym->attr.external = 1;
+ sym->attr.function = 1;
+ sym->attr.always_explicit = 1;
+ sym->attr.proc = PROC_INTRINSIC;
+ sym->attr.flavor = FL_PROCEDURE;
+ sym->result = sym;
+ if (expr->rank > 0)
+ {
+ sym->attr.dimension = 1;
+ sym->as = gfc_get_array_spec ();
+ sym->as->type = AS_ASSUMED_SHAPE;
+ sym->as->rank = expr->rank;
+ }
+
+ /* TODO: proper argument lists for external intrinsics. */
+ return sym;
+}
+
+/* Generate a call to an external intrinsic function. */
+static void
+gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
+{
+ gfc_symbol *sym;
+
+ assert (!se->ss || se->ss->expr == expr);
+
+ if (se->ss)
+ assert (expr->rank > 0);
+ else
+ assert (expr->rank == 0);
+
+ sym = gfc_get_symbol_for_expr (expr);
+ gfc_conv_function_call (se, sym, expr->value.function.actual);
+ gfc_free (sym);
+}
+
+/* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
+ Implemented as
+ any(a)
+ {
+ forall (i=...)
+ if (a[i] != 0)
+ return 1
+ end forall
+ return 0
+ }
+ all(a)
+ {
+ forall (i=...)
+ if (a[i] == 0)
+ return 0
+ end forall
+ return 1
+ }
+ */
+static void
+gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, int op)
+{
+ tree resvar;
+ stmtblock_t block;
+ stmtblock_t body;
+ tree type;
+ tree tmp;
+ tree found;
+ gfc_loopinfo loop;
+ gfc_actual_arglist *actual;
+ gfc_ss *arrayss;
+ gfc_se arrayse;
+ tree exit_label;
+
+ if (se->ss)
+ {
+ gfc_conv_intrinsic_funcall (se, expr);
+ return;
+ }
+
+ actual = expr->value.function.actual;
+ type = gfc_typenode_for_spec (&expr->ts);
+ /* Initialize the result. */
+ resvar = gfc_create_var (type, "test");
+ if (op == EQ_EXPR)
+ tmp = convert (type, boolean_true_node);
+ else
+ tmp = convert (type, boolean_false_node);
+ gfc_add_modify_expr (&se->pre, resvar, tmp);
+
+ /* Walk the arguments. */
+ arrayss = gfc_walk_expr (actual->expr);
+ assert (arrayss != gfc_ss_terminator);
+
+ /* Initialize the scalarizer. */
+ gfc_init_loopinfo (&loop);
+ exit_label = gfc_build_label_decl (NULL_TREE);
+ TREE_USED (exit_label) = 1;
+ gfc_add_ss_to_loop (&loop, arrayss);
+
+ /* Initialize the loop. */
+ gfc_conv_ss_startstride (&loop);
+ gfc_conv_loop_setup (&loop);
+
+ gfc_mark_ss_chain_used (arrayss, 1);
+ /* Generate the loop body. */
+ gfc_start_scalarized_body (&loop, &body);
+
+ /* If the condition matches then set the return value. */
+ gfc_start_block (&block);
+ if (op == EQ_EXPR)
+ tmp = convert (type, boolean_false_node);
+ else
+ tmp = convert (type, boolean_true_node);
+ gfc_add_modify_expr (&block, resvar, tmp);
+
+ /* And break out of the loop. */
+ tmp = build1_v (GOTO_EXPR, exit_label);
+ gfc_add_expr_to_block (&block, tmp);
+
+ found = gfc_finish_block (&block);
+
+ /* Check this element. */
+ gfc_init_se (&arrayse, NULL);
+ gfc_copy_loopinfo_to_se (&arrayse, &loop);
+ arrayse.ss = arrayss;
+ gfc_conv_expr_val (&arrayse, actual->expr);
+
+ gfc_add_block_to_block (&body, &arrayse.pre);
+ tmp = build (op, boolean_type_node, arrayse.expr, integer_zero_node);
+ tmp = build_v (COND_EXPR, tmp, found, build_empty_stmt ());
+ gfc_add_expr_to_block (&body, tmp);
+ gfc_add_block_to_block (&body, &arrayse.post);
+
+ gfc_trans_scalarizing_loops (&loop, &body);
+
+ /* Add the exit label. */
+ tmp = build1_v (LABEL_EXPR, exit_label);
+ gfc_add_expr_to_block (&loop.pre, tmp);
+
+ gfc_add_block_to_block (&se->pre, &loop.pre);
+ gfc_add_block_to_block (&se->pre, &loop.post);
+ gfc_cleanup_loop (&loop);
+
+ se->expr = resvar;
+}
+
+/* COUNT(A) = Number of true elements in A. */
+static void
+gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
+{
+ tree resvar;
+ tree type;
+ stmtblock_t body;
+ tree tmp;
+ gfc_loopinfo loop;
+ gfc_actual_arglist *actual;
+ gfc_ss *arrayss;
+ gfc_se arrayse;
+
+ if (se->ss)
+ {
+ gfc_conv_intrinsic_funcall (se, expr);
+ return;
+ }
+
+ actual = expr->value.function.actual;
+
+ type = gfc_typenode_for_spec (&expr->ts);
+ /* Initialize the result. */
+ resvar = gfc_create_var (type, "count");
+ gfc_add_modify_expr (&se->pre, resvar, integer_zero_node);
+
+ /* Walk the arguments. */
+ arrayss = gfc_walk_expr (actual->expr);
+ assert (arrayss != gfc_ss_terminator);
+
+ /* Initialize the scalarizer. */
+ gfc_init_loopinfo (&loop);
+ gfc_add_ss_to_loop (&loop, arrayss);
+
+ /* Initialize the loop. */
+ gfc_conv_ss_startstride (&loop);
+ gfc_conv_loop_setup (&loop);
+
+ gfc_mark_ss_chain_used (arrayss, 1);
+ /* Generate the loop body. */
+ gfc_start_scalarized_body (&loop, &body);
+
+ tmp = build (PLUS_EXPR, TREE_TYPE (resvar), resvar, integer_one_node);
+ tmp = build_v (MODIFY_EXPR, resvar, tmp);
+
+ gfc_init_se (&arrayse, NULL);
+ gfc_copy_loopinfo_to_se (&arrayse, &loop);
+ arrayse.ss = arrayss;
+ gfc_conv_expr_val (&arrayse, actual->expr);
+ tmp = build_v (COND_EXPR, arrayse.expr, tmp, build_empty_stmt ());
+
+ gfc_add_block_to_block (&body, &arrayse.pre);
+ gfc_add_expr_to_block (&body, tmp);
+ gfc_add_block_to_block (&body, &arrayse.post);
+
+ gfc_trans_scalarizing_loops (&loop, &body);
+
+ gfc_add_block_to_block (&se->pre, &loop.pre);
+ gfc_add_block_to_block (&se->pre, &loop.post);
+ gfc_cleanup_loop (&loop);
+
+ se->expr = resvar;
+}
+
+/* Inline implementation of the sum and product intrinsics. */
+static void
+gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, int op)
+{
+ tree resvar;
+ tree type;
+ stmtblock_t body;
+ stmtblock_t block;
+ tree tmp;
+ gfc_loopinfo loop;
+ gfc_actual_arglist *actual;
+ gfc_ss *arrayss;
+ gfc_ss *maskss;
+ gfc_se arrayse;
+ gfc_se maskse;
+ gfc_expr *arrayexpr;
+ gfc_expr *maskexpr;
+
+ if (se->ss)
+ {
+ gfc_conv_intrinsic_funcall (se, expr);
+ return;
+ }
+
+ type = gfc_typenode_for_spec (&expr->ts);
+ /* Initialize the result. */
+ resvar = gfc_create_var (type, "val");
+ if (op == PLUS_EXPR)
+ tmp = gfc_build_const (type, integer_zero_node);
+ else
+ tmp = gfc_build_const (type, integer_one_node);
+
+ gfc_add_modify_expr (&se->pre, resvar, tmp);
+
+ /* Walk the arguments. */
+ actual = expr->value.function.actual;
+ arrayexpr = actual->expr;
+ arrayss = gfc_walk_expr (arrayexpr);
+ assert (arrayss != gfc_ss_terminator);
+
+ actual = actual->next->next;
+ assert (actual);
+ maskexpr = actual->expr;
+ if (maskexpr)
+ {
+ maskss = gfc_walk_expr (maskexpr);
+ assert (maskss != gfc_ss_terminator);
+ }
+ else
+ maskss = NULL;
+
+ /* Initialize the scalarizer. */
+ gfc_init_loopinfo (&loop);
+ gfc_add_ss_to_loop (&loop, arrayss);
+ if (maskss)
+ gfc_add_ss_to_loop (&loop, maskss);
+
+ /* Initialize the loop. */
+ gfc_conv_ss_startstride (&loop);
+ gfc_conv_loop_setup (&loop);
+
+ gfc_mark_ss_chain_used (arrayss, 1);
+ if (maskss)
+ gfc_mark_ss_chain_used (maskss, 1);
+ /* Generate the loop body. */
+ gfc_start_scalarized_body (&loop, &body);
+
+ /* If we have a mask, only add this element if the mask is set. */
+ if (maskss)
+ {
+ gfc_init_se (&maskse, NULL);
+ gfc_copy_loopinfo_to_se (&maskse, &loop);
+ maskse.ss = maskss;
+ gfc_conv_expr_val (&maskse, maskexpr);
+ gfc_add_block_to_block (&body, &maskse.pre);
+
+ gfc_start_block (&block);
+ }
+ else
+ gfc_init_block (&block);
+
+ /* Do the actual summation/product. */
+ gfc_init_se (&arrayse, NULL);
+ gfc_copy_loopinfo_to_se (&arrayse, &loop);
+ arrayse.ss = arrayss;
+ gfc_conv_expr_val (&arrayse, arrayexpr);
+ gfc_add_block_to_block (&block, &arrayse.pre);
+
+ tmp = build (op, type, resvar, arrayse.expr);
+ gfc_add_modify_expr (&block, resvar, tmp);
+ gfc_add_block_to_block (&block, &arrayse.post);
+
+ if (maskss)
+ {
+ /* We enclose the above in if (mask) {...} . */
+ tmp = gfc_finish_block (&block);
+
+ tmp = build_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
+ }
+ else
+ tmp = gfc_finish_block (&block);
+ gfc_add_expr_to_block (&body, tmp);
+
+ gfc_trans_scalarizing_loops (&loop, &body);
+ gfc_add_block_to_block (&se->pre, &loop.pre);
+ gfc_add_block_to_block (&se->pre, &loop.post);
+ gfc_cleanup_loop (&loop);
+
+ se->expr = resvar;
+}
+
+static void
+gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
+{
+ stmtblock_t body;
+ stmtblock_t block;
+ stmtblock_t ifblock;
+ tree limit;
+ tree type;
+ tree tmp;
+ tree ifbody;
+ tree cond;
+ gfc_loopinfo loop;
+ gfc_actual_arglist *actual;
+ gfc_ss *arrayss;
+ gfc_ss *maskss;
+ gfc_se arrayse;
+ gfc_se maskse;
+ gfc_expr *arrayexpr;
+ gfc_expr *maskexpr;
+ tree pos;
+ int n;
+
+ if (se->ss)
+ {
+ gfc_conv_intrinsic_funcall (se, expr);
+ return;
+ }
+
+ /* Initialize the result. */
+ pos = gfc_create_var (gfc_array_index_type, "pos");
+ type = gfc_typenode_for_spec (&expr->ts);
+
+ /* Walk the arguments. */
+ actual = expr->value.function.actual;
+ arrayexpr = actual->expr;
+ arrayss = gfc_walk_expr (arrayexpr);
+ assert (arrayss != gfc_ss_terminator);
+
+ actual = actual->next->next;
+ assert (actual);
+ maskexpr = actual->expr;
+ if (maskexpr)
+ {
+ maskss = gfc_walk_expr (maskexpr);
+ assert (maskss != gfc_ss_terminator);
+ }
+ else
+ maskss = NULL;
+
+ limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
+ n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind);
+ switch (arrayexpr->ts.type)
+ {
+ case BT_REAL:
+ tmp = gfc_conv_mpf_to_tree (gfc_real_kinds[n].huge, arrayexpr->ts.kind);
+ break;
+
+ case BT_INTEGER:
+ tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
+ arrayexpr->ts.kind);
+ break;
+
+ default:
+ abort ();
+ }
+
+ /* Most negative(+HUGE) for maxval, most negative (-HUGE) for minval. */
+ if (op == GT_EXPR)
+ tmp = fold (build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp));
+ gfc_add_modify_expr (&se->pre, limit, tmp);
+
+ /* Initialize the scalarizer. */
+ gfc_init_loopinfo (&loop);
+ gfc_add_ss_to_loop (&loop, arrayss);
+ if (maskss)
+ gfc_add_ss_to_loop (&loop, maskss);
+
+ /* Initialize the loop. */
+ gfc_conv_ss_startstride (&loop);
+ gfc_conv_loop_setup (&loop);
+
+ assert (loop.dimen == 1);
+
+ /* Initialize the position to the first element. If the array has zero
+ size we need to return zero. Otherwise use the first element of the
+ array, in case all elements are equal to the limit.
+ ie. pos = (ubound >= lbound) ? lbound, lbound - 1; */
+ tmp = fold (build (MINUS_EXPR, gfc_array_index_type,
+ loop.from[0], integer_one_node));
+ cond = fold (build (GE_EXPR, boolean_type_node,
+ loop.to[0], loop.from[0]));
+ tmp = fold (build (COND_EXPR, gfc_array_index_type, cond,
+ loop.from[0], tmp));
+ gfc_add_modify_expr (&loop.pre, pos, tmp);
+
+ gfc_mark_ss_chain_used (arrayss, 1);
+ if (maskss)
+ gfc_mark_ss_chain_used (maskss, 1);
+ /* Generate the loop body. */
+ gfc_start_scalarized_body (&loop, &body);
+
+ /* If we have a mask, only check this element if the mask is set. */
+ if (maskss)
+ {
+ gfc_init_se (&maskse, NULL);
+ gfc_copy_loopinfo_to_se (&maskse, &loop);
+ maskse.ss = maskss;
+ gfc_conv_expr_val (&maskse, maskexpr);
+ gfc_add_block_to_block (&body, &maskse.pre);
+
+ gfc_start_block (&block);
+ }
+ else
+ gfc_init_block (&block);
+
+ /* Compare with the current limit. */
+ gfc_init_se (&arrayse, NULL);
+ gfc_copy_loopinfo_to_se (&arrayse, &loop);
+ arrayse.ss = arrayss;
+ gfc_conv_expr_val (&arrayse, arrayexpr);
+ gfc_add_block_to_block (&block, &arrayse.pre);
+
+ /* We do the following if this is a more extreme value. */
+ gfc_start_block (&ifblock);
+
+ /* Assign the value to the limit... */
+ gfc_add_modify_expr (&ifblock, limit, arrayse.expr);
+
+ /* Remember where we are. */
+ gfc_add_modify_expr (&ifblock, pos, loop.loopvar[0]);
+
+ ifbody = gfc_finish_block (&ifblock);
+
+ /* If it is a more extreme value. */
+ tmp = build (op, boolean_type_node, arrayse.expr, limit);
+ tmp = build_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
+ gfc_add_expr_to_block (&block, tmp);
+
+ if (maskss)
+ {
+ /* We enclose the above in if (mask) {...}. */
+ tmp = gfc_finish_block (&block);
+
+ tmp = build_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
+ }
+ else
+ tmp = gfc_finish_block (&block);
+ gfc_add_expr_to_block (&body, tmp);
+
+ gfc_trans_scalarizing_loops (&loop, &body);
+
+ gfc_add_block_to_block (&se->pre, &loop.pre);
+ gfc_add_block_to_block (&se->pre, &loop.post);
+ gfc_cleanup_loop (&loop);
+
+ /* Return a value in the range 1..SIZE(array). */
+ tmp = fold (build (MINUS_EXPR, gfc_array_index_type, loop.from[0],
+ integer_one_node));
+ tmp = fold (build (MINUS_EXPR, gfc_array_index_type, pos, tmp));
+ /* And convert to the required type. */
+ se->expr = convert (type, tmp);
+}
+
+static void
+gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, int op)
+{
+ tree limit;
+ tree type;
+ tree tmp;
+ tree ifbody;
+ stmtblock_t body;
+ stmtblock_t block;
+ gfc_loopinfo loop;
+ gfc_actual_arglist *actual;
+ gfc_ss *arrayss;
+ gfc_ss *maskss;
+ gfc_se arrayse;
+ gfc_se maskse;
+ gfc_expr *arrayexpr;
+ gfc_expr *maskexpr;
+ int n;
+
+ if (se->ss)
+ {
+ gfc_conv_intrinsic_funcall (se, expr);
+ return;
+ }
+
+ type = gfc_typenode_for_spec (&expr->ts);
+ /* Initialize the result. */
+ limit = gfc_create_var (type, "limit");
+ n = gfc_validate_kind (expr->ts.type, expr->ts.kind);
+ switch (expr->ts.type)
+ {
+ case BT_REAL:
+ tmp = gfc_conv_mpf_to_tree (gfc_real_kinds[n].huge, expr->ts.kind);
+ break;
+
+ case BT_INTEGER:
+ tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
+ break;
+
+ default:
+ abort ();
+ }
+
+ /* Most negative(-HUGE) for maxval, most positive (-HUGE) for minval. */
+ if (op == GT_EXPR)
+ tmp = fold (build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp));
+ gfc_add_modify_expr (&se->pre, limit, tmp);
+
+ /* Walk the arguments. */
+ actual = expr->value.function.actual;
+ arrayexpr = actual->expr;
+ arrayss = gfc_walk_expr (arrayexpr);
+ assert (arrayss != gfc_ss_terminator);
+
+ actual = actual->next->next;
+ assert (actual);
+ maskexpr = actual->expr;
+ if (maskexpr)
+ {
+ maskss = gfc_walk_expr (maskexpr);
+ assert (maskss != gfc_ss_terminator);
+ }
+ else
+ maskss = NULL;
+
+ /* Initialize the scalarizer. */
+ gfc_init_loopinfo (&loop);
+ gfc_add_ss_to_loop (&loop, arrayss);
+ if (maskss)
+ gfc_add_ss_to_loop (&loop, maskss);
+
+ /* Initialize the loop. */
+ gfc_conv_ss_startstride (&loop);
+ gfc_conv_loop_setup (&loop);
+
+ gfc_mark_ss_chain_used (arrayss, 1);
+ if (maskss)
+ gfc_mark_ss_chain_used (maskss, 1);
+ /* Generate the loop body. */
+ gfc_start_scalarized_body (&loop, &body);
+
+ /* If we have a mask, only add this element if the mask is set. */
+ if (maskss)
+ {
+ gfc_init_se (&maskse, NULL);
+ gfc_copy_loopinfo_to_se (&maskse, &loop);
+ maskse.ss = maskss;
+ gfc_conv_expr_val (&maskse, maskexpr);
+ gfc_add_block_to_block (&body, &maskse.pre);
+
+ gfc_start_block (&block);
+ }
+ else
+ gfc_init_block (&block);
+
+ /* Compare with the current limit. */
+ gfc_init_se (&arrayse, NULL);
+ gfc_copy_loopinfo_to_se (&arrayse, &loop);
+ arrayse.ss = arrayss;
+ gfc_conv_expr_val (&arrayse, arrayexpr);
+ gfc_add_block_to_block (&block, &arrayse.pre);
+
+ /* Assign the value to the limit... */
+ ifbody = build_v (MODIFY_EXPR, limit, arrayse.expr);
+
+ /* If it is a more extreme value. */
+ tmp = build (op, boolean_type_node, arrayse.expr, limit);
+ tmp = build_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
+ gfc_add_expr_to_block (&block, tmp);
+ gfc_add_block_to_block (&block, &arrayse.post);
+
+ tmp = gfc_finish_block (&block);
+ if (maskss)
+ {
+ /* We enclose the above in if (mask) {...}. */
+ tmp = build_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
+ }
+ gfc_add_expr_to_block (&body, tmp);
+
+ gfc_trans_scalarizing_loops (&loop, &body);
+
+ gfc_add_block_to_block (&se->pre, &loop.pre);
+ gfc_add_block_to_block (&se->pre, &loop.post);
+ gfc_cleanup_loop (&loop);
+
+ se->expr = limit;
+}
+
+/* BTEST (i, pos) = (i & (1 << pos)) != 0. */
+static void
+gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
+{
+ tree arg;
+ tree arg2;
+ tree type;
+ tree tmp;
+
+ arg = gfc_conv_intrinsic_function_args (se, expr);
+ arg2 = TREE_VALUE (TREE_CHAIN (arg));
+ arg = TREE_VALUE (arg);
+ type = TREE_TYPE (arg);
+
+ tmp = build (LSHIFT_EXPR, type, integer_one_node, arg2);
+ tmp = build (BIT_AND_EXPR, type, arg, tmp);
+ tmp = fold (build (NE_EXPR, boolean_type_node, tmp, integer_zero_node));
+ type = gfc_typenode_for_spec (&expr->ts);
+ se->expr = convert (type, tmp);
+}
+
+/* Generate code to perform the specified operation. */
+static void
+gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, int op)
+{
+ tree arg;
+ tree arg2;
+ tree type;
+
+ arg = gfc_conv_intrinsic_function_args (se, expr);
+ arg2 = TREE_VALUE (TREE_CHAIN (arg));
+ arg = TREE_VALUE (arg);
+ type = TREE_TYPE (arg);
+
+ se->expr = fold (build (op, type, arg, arg2));
+}
+
+/* Bitwise not. */
+static void
+gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
+{
+ tree arg;
+
+ arg = gfc_conv_intrinsic_function_args (se, expr);
+ arg = TREE_VALUE (arg);
+
+ se->expr = build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
+}
+
+/* Set or clear a single bit. */
+static void
+gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
+{
+ tree arg;
+ tree arg2;
+ tree type;
+ tree tmp;
+ int op;
+
+ arg = gfc_conv_intrinsic_function_args (se, expr);
+ arg2 = TREE_VALUE (TREE_CHAIN (arg));
+ arg = TREE_VALUE (arg);
+ type = TREE_TYPE (arg);
+
+ tmp = fold (build (LSHIFT_EXPR, type, integer_one_node, arg2));
+ if (set)
+ op = BIT_IOR_EXPR;
+ else
+ {
+ op = BIT_AND_EXPR;
+ tmp = fold (build1 (BIT_NOT_EXPR, type, tmp));
+ }
+ se->expr = fold (build (op, type, arg, tmp));
+}
+
+/* Extract a sequence of bits.
+ IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
+static void
+gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
+{
+ tree arg;
+ tree arg2;
+ tree arg3;
+ tree type;
+ tree tmp;
+ tree mask;
+
+ arg = gfc_conv_intrinsic_function_args (se, expr);
+ arg2 = TREE_CHAIN (arg);
+ arg3 = TREE_VALUE (TREE_CHAIN (arg2));
+ arg = TREE_VALUE (arg);
+ arg2 = TREE_VALUE (arg2);
+ type = TREE_TYPE (arg);
+
+ mask = build_int_2 (-1, ~(unsigned HOST_WIDE_INT) 0);
+ mask = build (LSHIFT_EXPR, type, mask, arg3);
+ mask = build1 (BIT_NOT_EXPR, type, mask);
+
+ tmp = build (RSHIFT_EXPR, type, arg, arg2);
+
+ se->expr = fold (build (BIT_AND_EXPR, type, tmp, mask));
+}
+
+/* ISHFT (I, SHIFT) = (shift >= 0) ? i << shift : i >> -shift. */
+static void
+gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
+{
+ tree arg;
+ tree arg2;
+ tree type;
+ tree tmp;
+ tree lshift;
+ tree rshift;
+
+ arg = gfc_conv_intrinsic_function_args (se, expr);
+ arg2 = TREE_VALUE (TREE_CHAIN (arg));
+ arg = TREE_VALUE (arg);
+ type = TREE_TYPE (arg);
+
+ /* Left shift if positive. */
+ lshift = build (LSHIFT_EXPR, type, arg, arg2);
+
+ /* Right shift if negative. This will perform an arithmetic shift as
+ we are dealing with signed integers. Section 13.5.7 allows this. */
+ tmp = build1 (NEGATE_EXPR, TREE_TYPE (arg2), arg2);
+ rshift = build (RSHIFT_EXPR, type, arg, tmp);
+
+ tmp = build (GT_EXPR, boolean_type_node, arg2, integer_zero_node);
+ rshift = build (COND_EXPR, type, tmp, lshift, rshift);
+
+ /* Do nothing if shift == 0. */
+ tmp = build (EQ_EXPR, boolean_type_node, arg2, integer_zero_node);
+ se->expr = build (COND_EXPR, type, tmp, arg, rshift);
+}
+
+/* Circular shift. AKA rotate or barrel shift. */
+static void
+gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
+{
+ tree arg;
+ tree arg2;
+ tree arg3;
+ tree type;
+ tree tmp;
+ tree lrot;
+ tree rrot;
+
+ arg = gfc_conv_intrinsic_function_args (se, expr);
+ arg2 = TREE_CHAIN (arg);
+ arg3 = TREE_CHAIN (arg2);
+ if (arg3)
+ {
+ /* Use a library function for the 3 parameter version. */
+ type = TREE_TYPE (TREE_VALUE (arg));
+ /* Convert all args to the same type otherwise we need loads of library
+ functions. SIZE and SHIFT cannot have values > BIT_SIZE (I) so the
+ conversion is safe. */
+ tmp = convert (type, TREE_VALUE (arg2));
+ TREE_VALUE (arg2) = tmp;
+ tmp = convert (type, TREE_VALUE (arg3));
+ TREE_VALUE (arg3) = tmp;
+
+ switch (expr->ts.kind)
+ {
+ case 4:
+ tmp = gfor_fndecl_math_ishftc4;
+ break;
+ case 8:
+ tmp = gfor_fndecl_math_ishftc8;
+ break;
+ default:
+ abort ();
+ }
+ se->expr = gfc_build_function_call (tmp, arg);
+ return;
+ }
+ arg = TREE_VALUE (arg);
+ arg2 = TREE_VALUE (arg2);
+ type = TREE_TYPE (arg);
+
+ /* Rotate left if positive. */
+ lrot = build (LROTATE_EXPR, type, arg, arg2);
+
+ /* Rotate right if negative. */
+ tmp = build1 (NEGATE_EXPR, TREE_TYPE (arg2), arg2);
+ rrot = build (RROTATE_EXPR, type, arg, tmp);
+
+ tmp = build (GT_EXPR, boolean_type_node, arg2, integer_zero_node);
+ rrot = build (COND_EXPR, type, tmp, lrot, rrot);
+
+ /* Do nothing if shift == 0. */
+ tmp = build (EQ_EXPR, boolean_type_node, arg2, integer_zero_node);
+ se->expr = build (COND_EXPR, type, tmp, arg, rrot);
+}
+
+/* The length of a character string. */
+static void
+gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
+{
+ tree len;
+ tree type;
+ tree decl;
+ gfc_symbol *sym;
+ gfc_se argse;
+ gfc_expr *arg;
+
+ assert (!se->ss);
+
+ arg = expr->value.function.actual->expr;
+
+ type = gfc_typenode_for_spec (&expr->ts);
+ switch (arg->expr_type)
+ {
+ case EXPR_CONSTANT:
+ len = build_int_2 (arg->value.character.length, 0);
+ break;
+
+ default:
+ if (arg->expr_type == EXPR_VARIABLE && arg->ref == NULL)
+ {
+ sym = arg->symtree->n.sym;
+ decl = gfc_get_symbol_decl (sym);
+ if (decl == current_function_decl && sym->attr.function
+ && (sym->result == sym))
+ decl = gfc_get_fake_result_decl (sym);
+
+ len = sym->ts.cl->backend_decl;
+ assert (len);
+ }
+ else
+ {
+ /* Anybody stupid enough to do this deserves inefficient code. */
+ gfc_init_se (&argse, se);
+ gfc_conv_expr (&argse, arg);
+ gfc_add_block_to_block (&se->pre, &argse.pre);
+ gfc_add_block_to_block (&se->post, &argse.post);
+ len = argse.string_length;
+ }
+ break;
+ }
+ se->expr = convert (type, len);
+}
+
+/* The length of a character string not including trailing blanks. */
+static void
+gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
+{
+ tree args;
+ tree type;
+
+ args = gfc_conv_intrinsic_function_args (se, expr);
+ type = gfc_typenode_for_spec (&expr->ts);
+ se->expr = gfc_build_function_call (gfor_fndecl_string_len_trim, args);
+ se->expr = convert (type, se->expr);
+}
+
+
+/* Returns the starting position of a substring within a string. */
+
+static void
+gfc_conv_intrinsic_index (gfc_se * se, gfc_expr * expr)
+{
+ tree args;
+ tree back;
+ tree type;
+ tree tmp;
+
+ args = gfc_conv_intrinsic_function_args (se, expr);
+ type = gfc_typenode_for_spec (&expr->ts);
+ tmp = gfc_advance_chain (args, 3);
+ if (TREE_CHAIN (tmp) == NULL_TREE)
+ {
+ back = convert (gfc_logical4_type_node, integer_one_node);
+ back = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
+ TREE_CHAIN (tmp) = back;
+ }
+ else
+ {
+ back = TREE_CHAIN (tmp);
+ TREE_VALUE (back) = convert (gfc_logical4_type_node, TREE_VALUE (back));
+ }
+
+ se->expr = gfc_build_function_call (gfor_fndecl_string_index, args);
+ se->expr = convert (type, se->expr);
+}
+
+/* The ascii value for a single character. */
+static void
+gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
+{
+ tree arg;
+ tree type;
+
+ arg = gfc_conv_intrinsic_function_args (se, expr);
+ arg = TREE_VALUE (TREE_CHAIN (arg));
+ assert (POINTER_TYPE_P (TREE_TYPE (arg)));
+ arg = build1 (NOP_EXPR, pchar_type_node, arg);
+ type = gfc_typenode_for_spec (&expr->ts);
+
+ se->expr = gfc_build_indirect_ref (arg);
+ se->expr = convert (type, se->expr);
+}
+
+
+/* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
+
+static void
+gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
+{
+ tree arg;
+ tree tsource;
+ tree fsource;
+ tree mask;
+ tree type;
+
+ arg = gfc_conv_intrinsic_function_args (se, expr);
+ tsource = TREE_VALUE (arg);
+ arg = TREE_CHAIN (arg);
+ fsource = TREE_VALUE (arg);
+ arg = TREE_CHAIN (arg);
+ mask = TREE_VALUE (arg);
+
+ type = TREE_TYPE (tsource);
+ se->expr = fold (build (COND_EXPR, type, mask, tsource, fsource));
+}
+
+
+static void
+gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
+{
+ gfc_actual_arglist *actual;
+ tree args;
+ tree type;
+ tree fndecl;
+ gfc_se argse;
+ gfc_ss *ss;
+
+ gfc_init_se (&argse, NULL);
+ actual = expr->value.function.actual;
+
+ ss = gfc_walk_expr (actual->expr);
+ assert (ss != gfc_ss_terminator);
+ argse.want_pointer = 1;
+ gfc_conv_expr_descriptor (&argse, actual->expr, ss);
+ gfc_add_block_to_block (&se->pre, &argse.pre);
+ gfc_add_block_to_block (&se->post, &argse.post);
+ args = gfc_chainon_list (NULL_TREE, argse.expr);
+
+ actual = actual->next;
+ if (actual->expr)
+ {
+ gfc_init_se (&argse, NULL);
+ gfc_conv_expr_type (&argse, actual->expr, gfc_array_index_type);
+ gfc_add_block_to_block (&se->pre, &argse.pre);
+ args = gfc_chainon_list (args, argse.expr);
+ fndecl = gfor_fndecl_size1;
+ }
+ else
+ fndecl = gfor_fndecl_size0;
+
+ se->expr = gfc_build_function_call (fndecl, args);
+ type = gfc_typenode_for_spec (&expr->ts);
+ se->expr = convert (type, se->expr);
+}
+
+
+/* Intrinsic string comparison functions. */
+
+ static void
+gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, int op)
+{
+ tree type;
+ tree args;
+
+ args = gfc_conv_intrinsic_function_args (se, expr);
+ /* Build a call for the comparison. */
+ se->expr = gfc_build_function_call (gfor_fndecl_compare_string, args);
+
+ type = gfc_typenode_for_spec (&expr->ts);
+ se->expr = build (op, type, se->expr, integer_zero_node);
+}
+
+/* Generate a call to the adjustl/adjustr library function. */
+static void
+gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
+{
+ tree args;
+ tree len;
+ tree type;
+ tree var;
+ tree tmp;
+
+ args = gfc_conv_intrinsic_function_args (se, expr);
+ len = TREE_VALUE (args);
+
+ type = TREE_TYPE (TREE_VALUE (TREE_CHAIN (args)));
+ var = gfc_conv_string_tmp (se, type, len);
+ args = tree_cons (NULL_TREE, var, args);
+
+ tmp = gfc_build_function_call (fndecl, args);
+ gfc_add_expr_to_block (&se->pre, tmp);
+ se->expr = var;
+ se->string_length = len;
+}
+
+
+/* Scalar transfer statement.
+ TRANSFER (source, mold) = *(typeof<mould> *)&source */
+
+static void
+gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
+{
+ gfc_actual_arglist *arg;
+ gfc_se argse;
+ tree type;
+ tree ptr;
+ gfc_ss *ss;
+
+ assert (!se->ss);
+
+ /* Get a pointer to the source. */
+ arg = expr->value.function.actual;
+ ss = gfc_walk_expr (arg->expr);
+ gfc_init_se (&argse, NULL);
+ if (ss == gfc_ss_terminator)
+ gfc_conv_expr_reference (&argse, arg->expr);
+ else
+ gfc_conv_array_parameter (&argse, arg->expr, ss, 1);
+ gfc_add_block_to_block (&se->pre, &argse.pre);
+ gfc_add_block_to_block (&se->post, &argse.post);
+ ptr = argse.expr;
+
+ arg = arg->next;
+ type = gfc_typenode_for_spec (&expr->ts);
+ ptr = convert (build_pointer_type (type), ptr);
+ if (expr->ts.type == BT_CHARACTER)
+ {
+ gfc_init_se (&argse, NULL);
+ gfc_conv_expr (&argse, arg->expr);
+ gfc_add_block_to_block (&se->pre, &argse.pre);
+ gfc_add_block_to_block (&se->post, &argse.post);
+ se->expr = ptr;
+ se->string_length = argse.string_length;
+ }
+ else
+ {
+ se->expr = gfc_build_indirect_ref (ptr);
+ }
+}
+
+
+/* Generate code for the ALLOCATED intrinsic.
+ Generate inline code that directly check the address of the argument. */
+
+static void
+gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
+{
+ gfc_actual_arglist *arg1;
+ gfc_se arg1se;
+ gfc_ss *ss1;
+ tree tmp;
+
+ gfc_init_se (&arg1se, NULL);
+ arg1 = expr->value.function.actual;
+ ss1 = gfc_walk_expr (arg1->expr);
+ arg1se.descriptor_only = 1;
+ gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
+
+ tmp = gfc_conv_descriptor_data (arg1se.expr);
+ tmp = build (NE_EXPR, boolean_type_node, tmp, null_pointer_node);
+ se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
+}
+
+
+/* Generate code for the ASSOCIATED intrinsic.
+ If both POINTER and TARGET are arrays, generate a call to library function
+ _gfor_associated, and pass descriptors of POINTER and TARGET to it.
+ In other cases, generate inline code that directly compare the address of
+ POINTER with the address of TARGET. */
+
+static void
+gfc_conv_associated (gfc_se *se, gfc_expr *expr)
+{
+ gfc_actual_arglist *arg1;
+ gfc_actual_arglist *arg2;
+ gfc_se arg1se;
+ gfc_se arg2se;
+ tree tmp2;
+ tree tmp;
+ tree args, fndecl;
+ gfc_ss *ss1, *ss2;
+
+ gfc_init_se (&arg1se, NULL);
+ gfc_init_se (&arg2se, NULL);
+ arg1 = expr->value.function.actual;
+ arg2 = arg1->next;
+ ss1 = gfc_walk_expr (arg1->expr);
+
+ if (!arg2->expr)
+ {
+ /* No optional target. */
+ if (ss1 == gfc_ss_terminator)
+ {
+ /* A pointer to a scalar. */
+ arg1se.want_pointer = 1;
+ gfc_conv_expr (&arg1se, arg1->expr);
+ tmp2 = arg1se.expr;
+ }
+ else
+ {
+ /* A pointer to an array. */
+ arg1se.descriptor_only = 1;
+ gfc_conv_expr_lhs (&arg1se, arg1->expr);
+ tmp2 = gfc_conv_descriptor_data (arg1se.expr);
+ }
+ tmp = build (NE_EXPR, boolean_type_node, tmp2, null_pointer_node);
+ se->expr = tmp;
+ }
+ else
+ {
+ /* An optional target. */
+ ss2 = gfc_walk_expr (arg2->expr);
+ if (ss1 == gfc_ss_terminator)
+ {
+ /* A pointer to a scalar. */
+ assert (ss2 == gfc_ss_terminator);
+ arg1se.want_pointer = 1;
+ gfc_conv_expr (&arg1se, arg1->expr);
+ arg2se.want_pointer = 1;
+ gfc_conv_expr (&arg2se, arg2->expr);
+ tmp = build (EQ_EXPR, boolean_type_node, arg1se.expr, arg2se.expr);
+ se->expr = tmp;
+ }
+ else
+ {
+ /* A pointer to an array, call library function _gfor_associated. */
+ assert (ss2 != gfc_ss_terminator);
+ args = NULL_TREE;
+ arg1se.want_pointer = 1;
+ gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
+ args = gfc_chainon_list (args, arg1se.expr);
+ arg2se.want_pointer = 1;
+ gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
+ gfc_add_block_to_block (&se->pre, &arg2se.pre);
+ gfc_add_block_to_block (&se->post, &arg2se.post);
+ args = gfc_chainon_list (args, arg2se.expr);
+ fndecl = gfor_fndecl_associated;
+ se->expr = gfc_build_function_call (fndecl, args);
+ }
+ }
+ se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
+}
+
+
+/* Scan a string for any one of the characters in a set of characters. */
+
+static void
+gfc_conv_intrinsic_scan (gfc_se * se, gfc_expr * expr)
+{
+ tree args;
+ tree back;
+ tree type;
+ tree tmp;
+
+ args = gfc_conv_intrinsic_function_args (se, expr);
+ type = gfc_typenode_for_spec (&expr->ts);
+ tmp = gfc_advance_chain (args, 3);
+ if (TREE_CHAIN (tmp) == NULL_TREE)
+ {
+ back = convert (gfc_logical4_type_node, integer_one_node);
+ back = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
+ TREE_CHAIN (tmp) = back;
+ }
+ else
+ {
+ back = TREE_CHAIN (tmp);
+ TREE_VALUE (back) = convert (gfc_logical4_type_node, TREE_VALUE (back));
+ }
+
+ se->expr = gfc_build_function_call (gfor_fndecl_string_scan, args);
+ se->expr = convert (type, se->expr);
+}
+
+
+/* Verify that a set of characters contains all the characters in a string
+ by indentifying the position of the first character in a string of
+ characters that does not appear in a given set of characters. */
+
+static void
+gfc_conv_intrinsic_verify (gfc_se * se, gfc_expr * expr)
+{
+ tree args;
+ tree back;
+ tree type;
+ tree tmp;
+
+ args = gfc_conv_intrinsic_function_args (se, expr);
+ type = gfc_typenode_for_spec (&expr->ts);
+ tmp = gfc_advance_chain (args, 3);
+ if (TREE_CHAIN (tmp) == NULL_TREE)
+ {
+ back = convert (gfc_logical4_type_node, integer_one_node);
+ back = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
+ TREE_CHAIN (tmp) = back;
+ }
+ else
+ {
+ back = TREE_CHAIN (tmp);
+ TREE_VALUE (back) = convert (gfc_logical4_type_node, TREE_VALUE (back));
+ }
+
+ se->expr = gfc_build_function_call (gfor_fndecl_string_verify, args);
+ se->expr = convert (type, se->expr);
+}
+
+/* Prepare components and related information of a real number which is
+ the first argument of a elemental functions to manipulate reals. */
+
+static
+void prepare_arg_info (gfc_se * se, gfc_expr * expr,
+ real_compnt_info * rcs, int all)
+{
+ tree arg;
+ tree masktype;
+ tree tmp;
+ tree wbits;
+ tree one;
+ tree exponent, fraction;
+ int n;
+ gfc_expr *a1;
+
+ if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
+ gfc_todo_error ("Non-IEEE floating format");
+
+ assert (expr->expr_type == EXPR_FUNCTION);
+
+ arg = gfc_conv_intrinsic_function_args (se, expr);
+ arg = TREE_VALUE (arg);
+ rcs->type = TREE_TYPE (arg);
+
+ /* Force arg'type to integer by unaffected convert */
+ a1 = expr->value.function.actual->expr;
+ masktype = gfc_get_int_type (a1->ts.kind);
+ rcs->mtype = masktype;
+ tmp = build1 (VIEW_CONVERT_EXPR, masktype, arg);
+ arg = gfc_create_var (masktype, "arg");
+ gfc_add_modify_expr(&se->pre, arg, tmp);
+ rcs->arg = arg;
+
+ /* Caculate the numbers of bits of exponent, fraction and word */
+ n = gfc_validate_kind (a1->ts.type, a1->ts.kind);
+ tmp = build_int_2 (gfc_real_kinds[n].digits - 1, 0);
+ rcs->fdigits = convert (masktype, tmp);
+ wbits = build_int_2 (TYPE_PRECISION (rcs->type) - 1, 0);
+ wbits = convert (masktype, wbits);
+ rcs->edigits = fold (build (MINUS_EXPR, masktype, wbits, tmp));
+
+ /* Form masks for exponent/fraction/sign */
+ one = gfc_build_const (masktype, integer_one_node);
+ rcs->smask = fold (build (LSHIFT_EXPR, masktype, one, wbits));
+ rcs->f1 = fold (build (LSHIFT_EXPR, masktype, one, rcs->fdigits));
+ rcs->emask = fold (build (MINUS_EXPR, masktype, rcs->smask, rcs->f1));
+ rcs->fmask = fold (build (MINUS_EXPR, masktype, rcs->f1, one));
+ /* Form bias. */
+ tmp = fold (build (MINUS_EXPR, masktype, rcs->edigits, one));
+ tmp = fold (build (LSHIFT_EXPR, masktype, one, tmp));
+ rcs->bias = fold (build (MINUS_EXPR, masktype, tmp ,one));
+
+ if (all)
+ {
+ /* exponent, and fraction */
+ tmp = build (BIT_AND_EXPR, masktype, arg, rcs->emask);
+ tmp = build (RSHIFT_EXPR, masktype, tmp, rcs->fdigits);
+ exponent = gfc_create_var (masktype, "exponent");
+ gfc_add_modify_expr(&se->pre, exponent, tmp);
+ rcs->expn = exponent;
+
+ tmp = build (BIT_AND_EXPR, masktype, arg, rcs->fmask);
+ fraction = gfc_create_var (masktype, "fraction");
+ gfc_add_modify_expr(&se->pre, fraction, tmp);
+ rcs->frac = fraction;
+ }
+}
+
+/* Build a call to __builtin_clz. */
+
+static tree
+call_builtin_clz (tree result_type, tree op0)
+{
+ tree fn, parms, call;
+ enum machine_mode op0_mode = TYPE_MODE (TREE_TYPE (op0));
+
+ if (op0_mode == TYPE_MODE (integer_type_node))
+ fn = built_in_decls[BUILT_IN_CLZ];
+ else if (op0_mode == TYPE_MODE (long_integer_type_node))
+ fn = built_in_decls[BUILT_IN_CLZL];
+ else if (op0_mode == TYPE_MODE (long_long_integer_type_node))
+ fn = built_in_decls[BUILT_IN_CLZLL];
+ else
+ abort ();
+
+ parms = tree_cons (NULL, op0, NULL);
+ call = gfc_build_function_call (fn, parms);
+
+ return convert (result_type, call);
+}
+
+/* Generate code for SPACING (X) intrinsic function. We generate:
+
+ t = expn - (BITS_OF_FRACTION)
+ res = t << (BITS_OF_FRACTION)
+ if (t < 0)
+ res = tiny(X)
+*/
+
+static void
+gfc_conv_intrinsic_spacing (gfc_se * se, gfc_expr * expr)
+{
+ tree arg;
+ tree masktype;
+ tree tmp, t1, cond;
+ tree tiny, zero;
+ tree fdigits;
+ real_compnt_info rcs;
+
+ prepare_arg_info (se, expr, &rcs, 0);
+ arg = rcs.arg;
+ masktype = rcs.mtype;
+ fdigits = rcs.fdigits;
+ tiny = rcs.f1;
+ zero = gfc_build_const (masktype, integer_zero_node);
+ tmp = build (BIT_AND_EXPR, masktype, rcs.emask, arg);
+ tmp = build (RSHIFT_EXPR, masktype, tmp, fdigits);
+ tmp = build (MINUS_EXPR, masktype, tmp, fdigits);
+ cond = build (LE_EXPR, boolean_type_node, tmp, zero);
+ t1 = build (LSHIFT_EXPR, masktype, tmp, fdigits);
+ tmp = build (COND_EXPR, masktype, cond, tiny, t1);
+ tmp = build1 (VIEW_CONVERT_EXPR, rcs.type, tmp);
+
+ se->expr = tmp;
+}
+
+/* Generate code for RRSPACING (X) intrinsic function. We generate:
+
+ if (expn == 0 && frac == 0)
+ res = 0;
+ else
+ {
+ sedigits = edigits + 1;
+ if (expn == 0)
+ {
+ t1 = leadzero (frac);
+ frac = frac << (t1 + sedigits);
+ frac = frac >> (sedigits);
+ }
+ t = bias + BITS_OF_FRACTION_OF;
+ res = (t << BITS_OF_FRACTION_OF) | frac;
+*/
+
+static void
+gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
+{
+ tree masktype;
+ tree tmp, t1, t2, cond, cond2;
+ tree one, zero;
+ tree fdigits, fraction;
+ real_compnt_info rcs;
+
+ prepare_arg_info (se, expr, &rcs, 1);
+ masktype = rcs.mtype;
+ fdigits = rcs.fdigits;
+ fraction = rcs.frac;
+ one = gfc_build_const (masktype, integer_one_node);
+ zero = gfc_build_const (masktype, integer_zero_node);
+ t2 = build (PLUS_EXPR, masktype, rcs.edigits, one);
+
+ t1 = call_builtin_clz (masktype, fraction);
+ tmp = build (PLUS_EXPR, masktype, t1, one);
+ tmp = build (LSHIFT_EXPR, masktype, fraction, tmp);
+ tmp = build (RSHIFT_EXPR, masktype, tmp, t2);
+ cond = build (EQ_EXPR, boolean_type_node, rcs.expn, zero);
+ fraction = build (COND_EXPR, masktype, cond, tmp, fraction);
+
+ tmp = build (PLUS_EXPR, masktype, rcs.bias, fdigits);
+ tmp = build (LSHIFT_EXPR, masktype, tmp, fdigits);
+ tmp = build (BIT_IOR_EXPR, masktype, tmp, fraction);
+
+ cond2 = build (EQ_EXPR, boolean_type_node, rcs.frac, zero);
+ cond = build (TRUTH_ANDIF_EXPR, boolean_type_node, cond, cond2);
+ tmp = build (COND_EXPR, masktype, cond, integer_zero_node, tmp);
+
+ tmp = build1 (VIEW_CONVERT_EXPR, rcs.type, tmp);
+ se->expr = tmp;
+}
+
+/* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
+
+static void
+gfc_conv_intrinsic_si_kind (gfc_se * se, gfc_expr * expr)
+{
+ tree args;
+
+ args = gfc_conv_intrinsic_function_args (se, expr);
+ args = TREE_VALUE (args);
+ args = gfc_build_addr_expr (NULL, args);
+ args = tree_cons (NULL_TREE, args, NULL_TREE);
+ se->expr = gfc_build_function_call (gfor_fndecl_si_kind, args);
+}
+
+/* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
+
+static void
+gfc_conv_intrinsic_sr_kind (gfc_se * se, gfc_expr * expr)
+{
+ gfc_actual_arglist *actual;
+ tree args;
+ gfc_se argse;
+
+ args = NULL_TREE;
+ for (actual = expr->value.function.actual; actual; actual = actual->next)
+ {
+ gfc_init_se (&argse, se);
+
+ /* Pass a NULL pointer for an absent arg. */
+ if (actual->expr == NULL)
+ argse.expr = null_pointer_node;
+ else
+ gfc_conv_expr_reference (&argse, actual->expr);
+
+ gfc_add_block_to_block (&se->pre, &argse.pre);
+ gfc_add_block_to_block (&se->post, &argse.post);
+ args = gfc_chainon_list (args, argse.expr);
+ }
+ se->expr = gfc_build_function_call (gfor_fndecl_sr_kind, args);
+}
+
+
+/* Generate code for TRIM (A) intrinsic function. */
+
+static void
+gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
+{
+ tree var;
+ tree len;
+ tree addr;
+ tree tmp;
+ tree arglist;
+ tree type;
+ tree cond;
+
+ arglist = NULL_TREE;
+
+ type = build_pointer_type (gfc_character1_type_node);
+ var = gfc_create_var (type, "pstr");
+ addr = gfc_build_addr_expr (ppvoid_type_node, var);
+ len = gfc_create_var (gfc_int4_type_node, "len");
+
+ tmp = gfc_conv_intrinsic_function_args (se, expr);
+ arglist = gfc_chainon_list (arglist, gfc_build_addr_expr (NULL, len));
+ arglist = gfc_chainon_list (arglist, addr);
+ arglist = chainon (arglist, tmp);
+
+ tmp = gfc_build_function_call (gfor_fndecl_string_trim, arglist);
+ gfc_add_expr_to_block (&se->pre, tmp);
+
+ /* Free the temporary afterwards, if necessary. */
+ cond = build (GT_EXPR, boolean_type_node, len, integer_zero_node);
+ arglist = gfc_chainon_list (NULL_TREE, var);
+ tmp = gfc_build_function_call (gfor_fndecl_internal_free, arglist);
+ tmp = build_v (COND_EXPR, cond, tmp, build_empty_stmt ());
+ gfc_add_expr_to_block (&se->post, tmp);
+
+ se->expr = var;
+ se->string_length = len;
+}
+
+
+/* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
+
+static void
+gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
+{
+ tree tmp;
+ tree len;
+ tree args;
+ tree arglist;
+ tree ncopies;
+ tree var;
+ tree type;
+
+ args = gfc_conv_intrinsic_function_args (se, expr);
+ len = TREE_VALUE (args);
+ tmp = gfc_advance_chain (args, 2);
+ ncopies = TREE_VALUE (tmp);
+ len = fold (build (MULT_EXPR, gfc_int4_type_node, len, ncopies));
+ type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
+ var = gfc_conv_string_tmp (se, build_pointer_type (type), len);
+
+ arglist = NULL_TREE;
+ arglist = gfc_chainon_list (arglist, var);
+ arglist = chainon (arglist, args);
+ tmp = gfc_build_function_call (gfor_fndecl_string_repeat, arglist);
+ gfc_add_expr_to_block (&se->pre, tmp);
+
+ se->expr = var;
+ se->string_length = len;
+}
+
+
+/* Generate code for an intrinsic function. Some map directly to library
+ calls, others get special handling. In some cases the name of the function
+ used depends on the type specifiers. */
+
+void
+gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
+{
+ gfc_intrinsic_sym *isym;
+ char *name;
+ int lib;
+
+ isym = expr->value.function.isym;
+
+ name = &expr->value.function.name[2];
+
+ if (expr->rank > 0)
+ {
+ lib = gfc_is_intrinsic_libcall (expr);
+ if (lib != 0)
+ {
+ if (lib == 1)
+ se->ignore_optional = 1;
+ gfc_conv_intrinsic_funcall (se, expr);
+ return;
+ }
+ }
+
+ switch (expr->value.function.isym->generic_id)
+ {
+ case GFC_ISYM_NONE:
+ abort ();
+
+ case GFC_ISYM_REPEAT:
+ gfc_conv_intrinsic_repeat (se, expr);
+ break;
+
+ case GFC_ISYM_TRIM:
+ gfc_conv_intrinsic_trim (se, expr);
+ break;
+
+ case GFC_ISYM_SI_KIND:
+ gfc_conv_intrinsic_si_kind (se, expr);
+ break;
+
+ case GFC_ISYM_SR_KIND:
+ gfc_conv_intrinsic_sr_kind (se, expr);
+ break;
+
+ case GFC_ISYM_EXPONENT:
+ gfc_conv_intrinsic_exponent (se, expr);
+ break;
+
+ case GFC_ISYM_SPACING:
+ gfc_conv_intrinsic_spacing (se, expr);
+ break;
+
+ case GFC_ISYM_RRSPACING:
+ gfc_conv_intrinsic_rrspacing (se, expr);
+ break;
+
+ case GFC_ISYM_SCAN:
+ gfc_conv_intrinsic_scan (se, expr);
+ break;
+
+ case GFC_ISYM_VERIFY:
+ gfc_conv_intrinsic_verify (se, expr);
+ break;
+
+ case GFC_ISYM_ALLOCATED:
+ gfc_conv_allocated (se, expr);
+ break;
+
+ case GFC_ISYM_ASSOCIATED:
+ gfc_conv_associated(se, expr);
+ break;
+
+ case GFC_ISYM_ABS:
+ gfc_conv_intrinsic_abs (se, expr);
+ break;
+
+ case GFC_ISYM_ADJUSTL:
+ gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustl);
+ break;
+
+ case GFC_ISYM_ADJUSTR:
+ gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustr);
+ break;
+
+ case GFC_ISYM_AIMAG:
+ gfc_conv_intrinsic_imagpart (se, expr);
+ break;
+
+ case GFC_ISYM_AINT:
+ gfc_conv_intrinsic_aint (se, expr, FIX_TRUNC_EXPR);
+ break;
+
+ case GFC_ISYM_ALL:
+ gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
+ break;
+
+ case GFC_ISYM_ANINT:
+ gfc_conv_intrinsic_aint (se, expr, FIX_ROUND_EXPR);
+ break;
+
+ case GFC_ISYM_ANY:
+ gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
+ break;
+
+ case GFC_ISYM_BTEST:
+ gfc_conv_intrinsic_btest (se, expr);
+ break;
+
+ case GFC_ISYM_ACHAR:
+ case GFC_ISYM_CHAR:
+ gfc_conv_intrinsic_char (se, expr);
+ break;
+
+ case GFC_ISYM_CONVERSION:
+ case GFC_ISYM_REAL:
+ case GFC_ISYM_LOGICAL:
+ case GFC_ISYM_DBLE:
+ gfc_conv_intrinsic_conversion (se, expr);
+ break;
+
+ /* Integer conversions are handled seperately to make sure we get the
+ correct rounding mode. */
+ case GFC_ISYM_INT:
+ gfc_conv_intrinsic_int (se, expr, FIX_TRUNC_EXPR);
+ break;
+
+ case GFC_ISYM_NINT:
+ gfc_conv_intrinsic_int (se, expr, FIX_ROUND_EXPR);
+ break;
+
+ case GFC_ISYM_CEILING:
+ gfc_conv_intrinsic_int (se, expr, FIX_CEIL_EXPR);
+ break;
+
+ case GFC_ISYM_FLOOR:
+ gfc_conv_intrinsic_int (se, expr, FIX_FLOOR_EXPR);
+ break;
+
+ case GFC_ISYM_MOD:
+ gfc_conv_intrinsic_mod (se, expr, 0);
+ break;
+
+ case GFC_ISYM_MODULO:
+ gfc_conv_intrinsic_mod (se, expr, 1);
+ break;
+
+ case GFC_ISYM_CMPLX:
+ gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
+ break;
+
+ case GFC_ISYM_CONJG:
+ gfc_conv_intrinsic_conjg (se, expr);
+ break;
+
+ case GFC_ISYM_COUNT:
+ gfc_conv_intrinsic_count (se, expr);
+ break;
+
+ case GFC_ISYM_DIM:
+ gfc_conv_intrinsic_dim (se, expr);
+ break;
+
+ case GFC_ISYM_DPROD:
+ gfc_conv_intrinsic_dprod (se, expr);
+ break;
+
+ case GFC_ISYM_IAND:
+ gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
+ break;
+
+ case GFC_ISYM_IBCLR:
+ gfc_conv_intrinsic_singlebitop (se, expr, 0);
+ break;
+
+ case GFC_ISYM_IBITS:
+ gfc_conv_intrinsic_ibits (se, expr);
+ break;
+
+ case GFC_ISYM_IBSET:
+ gfc_conv_intrinsic_singlebitop (se, expr, 1);
+ break;
+
+ case GFC_ISYM_IACHAR:
+ case GFC_ISYM_ICHAR:
+ /* We assume ASCII character sequence. */
+ gfc_conv_intrinsic_ichar (se, expr);
+ break;
+
+ case GFC_ISYM_IEOR:
+ gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
+ break;
+
+ case GFC_ISYM_INDEX:
+ gfc_conv_intrinsic_index (se, expr);
+ break;
+
+ case GFC_ISYM_IOR:
+ gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
+ break;
+
+ case GFC_ISYM_ISHFT:
+ gfc_conv_intrinsic_ishft (se, expr);
+ break;
+
+ case GFC_ISYM_ISHFTC:
+ gfc_conv_intrinsic_ishftc (se, expr);
+ break;
+
+ case GFC_ISYM_LBOUND:
+ gfc_conv_intrinsic_bound (se, expr, 0);
+ break;
+
+ case GFC_ISYM_LEN:
+ gfc_conv_intrinsic_len (se, expr);
+ break;
+
+ case GFC_ISYM_LEN_TRIM:
+ gfc_conv_intrinsic_len_trim (se, expr);
+ break;
+
+ case GFC_ISYM_LGE:
+ gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
+ break;
+
+ case GFC_ISYM_LGT:
+ gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
+ break;
+
+ case GFC_ISYM_LLE:
+ gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
+ break;
+
+ case GFC_ISYM_LLT:
+ gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
+ break;
+
+ case GFC_ISYM_MAX:
+ gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
+ break;
+
+ case GFC_ISYM_MAXLOC:
+ gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
+ break;
+
+ case GFC_ISYM_MAXVAL:
+ gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
+ break;
+
+ case GFC_ISYM_MERGE:
+ gfc_conv_intrinsic_merge (se, expr);
+ break;
+
+ case GFC_ISYM_MIN:
+ gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
+ break;
+
+ case GFC_ISYM_MINLOC:
+ gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
+ break;
+
+ case GFC_ISYM_MINVAL:
+ gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
+ break;
+
+ case GFC_ISYM_NOT:
+ gfc_conv_intrinsic_not (se, expr);
+ break;
+
+ case GFC_ISYM_PRESENT:
+ gfc_conv_intrinsic_present (se, expr);
+ break;
+
+ case GFC_ISYM_PRODUCT:
+ gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
+ break;
+
+ case GFC_ISYM_SIGN:
+ gfc_conv_intrinsic_sign (se, expr);
+ break;
+
+ case GFC_ISYM_SIZE:
+ gfc_conv_intrinsic_size (se, expr);
+ break;
+
+ case GFC_ISYM_SUM:
+ gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
+ break;
+
+ case GFC_ISYM_TRANSFER:
+ gfc_conv_intrinsic_transfer (se, expr);
+ break;
+
+ case GFC_ISYM_UBOUND:
+ gfc_conv_intrinsic_bound (se, expr, 1);
+ break;
+
+ case GFC_ISYM_DOT_PRODUCT:
+ case GFC_ISYM_MATMUL:
+ gfc_conv_intrinsic_funcall (se, expr);
+ break;
+
+ default:
+ gfc_conv_intrinsic_lib_function (se, expr);
+ break;
+ }
+}
+
+
+/* This generates code to execute before entering the scalarization loop.
+ Currently does nothing. */
+
+void
+gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
+{
+ switch (ss->expr->value.function.isym->generic_id)
+ {
+ case GFC_ISYM_UBOUND:
+ case GFC_ISYM_LBOUND:
+ break;
+
+ default:
+ abort ();
+ break;
+ }
+}
+
+
+/* UBOUND and LBOUND intrinsics with one parameter are expanded into code
+ inside the scalarization loop. */
+
+static gfc_ss *
+gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
+{
+ gfc_ss *newss;
+
+ /* The two argument version returns a scalar. */
+ if (expr->value.function.actual->next->expr)
+ return ss;
+
+ newss = gfc_get_ss ();
+ newss->type = GFC_SS_INTRINSIC;
+ newss->expr = expr;
+ newss->next = ss;
+
+ return newss;
+}
+
+
+/* Walk an intrinsic array libcall. */
+
+static gfc_ss *
+gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
+{
+ gfc_ss *newss;
+
+ assert (expr->rank > 0);
+
+ newss = gfc_get_ss ();
+ newss->type = GFC_SS_FUNCTION;
+ newss->expr = expr;
+ newss->next = ss;
+ newss->data.info.dimen = expr->rank;
+
+ return newss;
+}
+
+
+/* Returns nonzero if the specified intrinsic function call maps directly to a
+ an external library call. Should only be used for functions that return
+ arrays. */
+
+int
+gfc_is_intrinsic_libcall (gfc_expr * expr)
+{
+ assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
+ assert (expr->rank > 0);
+
+ switch (expr->value.function.isym->generic_id)
+ {
+ case GFC_ISYM_ALL:
+ case GFC_ISYM_ANY:
+ case GFC_ISYM_COUNT:
+ case GFC_ISYM_MATMUL:
+ case GFC_ISYM_MAXLOC:
+ case GFC_ISYM_MAXVAL:
+ case GFC_ISYM_MINLOC:
+ case GFC_ISYM_MINVAL:
+ case GFC_ISYM_PRODUCT:
+ case GFC_ISYM_SUM:
+ case GFC_ISYM_SHAPE:
+ case GFC_ISYM_SPREAD:
+ case GFC_ISYM_TRANSPOSE:
+ /* Ignore absent optional parameters. */
+ return 1;
+
+ case GFC_ISYM_RESHAPE:
+ case GFC_ISYM_CSHIFT:
+ case GFC_ISYM_EOSHIFT:
+ case GFC_ISYM_PACK:
+ case GFC_ISYM_UNPACK:
+ /* Pass absent optional parameters. */
+ return 2;
+
+ default:
+ return 0;
+ }
+}
+
+/* Walk an intrinsic function. */
+gfc_ss *
+gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
+ gfc_intrinsic_sym * isym)
+{
+ assert (isym);
+
+ if (isym->elemental)
+ return gfc_walk_elemental_function_args (ss, expr, GFC_SS_SCALAR);
+
+ if (expr->rank == 0)
+ return ss;
+
+ if (gfc_is_intrinsic_libcall (expr))
+ return gfc_walk_intrinsic_libfunc (ss, expr);
+
+ /* Special cases. */
+ switch (isym->generic_id)
+ {
+ case GFC_ISYM_LBOUND:
+ case GFC_ISYM_UBOUND:
+ return gfc_walk_intrinsic_bound (ss, expr);
+
+ default:
+ /* This probably meant someone forgot to add an intrinsic to the above
+ list(s) when they implemented it, or something's gone horribly wrong.
+ */
+ gfc_todo_error ("Scalarization of non-elemental intrinsic: %s",
+ expr->value.function.name);
+ }
+}
+
+#include "gt-fortran-trans-intrinsic.h"
diff --git a/gcc/fortran/trans-io.c b/gcc/fortran/trans-io.c
new file mode 100644
index 00000000000..24f403d90b3
--- /dev/null
+++ b/gcc/fortran/trans-io.c
@@ -0,0 +1,1157 @@
+/* IO Code translation/library interface
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Paul Brook
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "tree-gimple.h"
+#include <stdio.h>
+#include "ggc.h"
+#include "toplev.h"
+#include "real.h"
+#include <assert.h>
+#include <gmp.h>
+#include "gfortran.h"
+#include "trans.h"
+#include "trans-stmt.h"
+#include "trans-array.h"
+#include "trans-types.h"
+#include "trans-const.h"
+
+
+static GTY(()) tree gfc_pint4_type_node;
+
+/* Members of the ioparm structure. */
+
+static GTY(()) tree ioparm_unit;
+static GTY(()) tree ioparm_err;
+static GTY(()) tree ioparm_end;
+static GTY(()) tree ioparm_eor;
+static GTY(()) tree ioparm_list_format;
+static GTY(()) tree ioparm_library_return;
+static GTY(()) tree ioparm_iostat;
+static GTY(()) tree ioparm_exist;
+static GTY(()) tree ioparm_opened;
+static GTY(()) tree ioparm_number;
+static GTY(()) tree ioparm_named;
+static GTY(()) tree ioparm_rec;
+static GTY(()) tree ioparm_nextrec;
+static GTY(()) tree ioparm_size;
+static GTY(()) tree ioparm_recl_in;
+static GTY(()) tree ioparm_recl_out;
+static GTY(()) tree ioparm_file;
+static GTY(()) tree ioparm_file_len;
+static GTY(()) tree ioparm_status;
+static GTY(()) tree ioparm_status_len;
+static GTY(()) tree ioparm_access;
+static GTY(()) tree ioparm_access_len;
+static GTY(()) tree ioparm_form;
+static GTY(()) tree ioparm_form_len;
+static GTY(()) tree ioparm_blank;
+static GTY(()) tree ioparm_blank_len;
+static GTY(()) tree ioparm_position;
+static GTY(()) tree ioparm_position_len;
+static GTY(()) tree ioparm_action;
+static GTY(()) tree ioparm_action_len;
+static GTY(()) tree ioparm_delim;
+static GTY(()) tree ioparm_delim_len;
+static GTY(()) tree ioparm_pad;
+static GTY(()) tree ioparm_pad_len;
+static GTY(()) tree ioparm_format;
+static GTY(()) tree ioparm_format_len;
+static GTY(()) tree ioparm_advance;
+static GTY(()) tree ioparm_advance_len;
+static GTY(()) tree ioparm_name;
+static GTY(()) tree ioparm_name_len;
+static GTY(()) tree ioparm_internal_unit;
+static GTY(()) tree ioparm_internal_unit_len;
+static GTY(()) tree ioparm_sequential;
+static GTY(()) tree ioparm_sequential_len;
+static GTY(()) tree ioparm_direct;
+static GTY(()) tree ioparm_direct_len;
+static GTY(()) tree ioparm_formatted;
+static GTY(()) tree ioparm_formatted_len;
+static GTY(()) tree ioparm_unformatted;
+static GTY(()) tree ioparm_unformatted_len;
+static GTY(()) tree ioparm_read;
+static GTY(()) tree ioparm_read_len;
+static GTY(()) tree ioparm_write;
+static GTY(()) tree ioparm_write_len;
+static GTY(()) tree ioparm_readwrite;
+static GTY(()) tree ioparm_readwrite_len;
+static GTY(()) tree ioparm_namelist_name;
+static GTY(()) tree ioparm_namelist_name_len;
+static GTY(()) tree ioparm_namelist_read_mode;
+
+/* The global I/O variables */
+
+static GTY(()) tree ioparm_var;
+static GTY(()) tree locus_file;
+static GTY(()) tree locus_line;
+
+
+/* Library I/O subroutines */
+
+static GTY(()) tree iocall_read;
+static GTY(()) tree iocall_read_done;
+static GTY(()) tree iocall_write;
+static GTY(()) tree iocall_write_done;
+static GTY(()) tree iocall_x_integer;
+static GTY(()) tree iocall_x_logical;
+static GTY(()) tree iocall_x_character;
+static GTY(()) tree iocall_x_real;
+static GTY(()) tree iocall_x_complex;
+static GTY(()) tree iocall_open;
+static GTY(()) tree iocall_close;
+static GTY(()) tree iocall_inquire;
+static GTY(()) tree iocall_rewind;
+static GTY(()) tree iocall_backspace;
+static GTY(()) tree iocall_endfile;
+static GTY(()) tree iocall_set_nml_val_int;
+static GTY(()) tree iocall_set_nml_val_float;
+static GTY(()) tree iocall_set_nml_val_char;
+static GTY(()) tree iocall_set_nml_val_complex;
+static GTY(()) tree iocall_set_nml_val_log;
+
+/* Variable for keeping track of what the last data transfer statement
+ was. Used for deciding which subroutine to call when the data
+ transfer is complete. */
+static enum { READ, WRITE } last_dt;
+
+#define ADD_FIELD(name, type) \
+ ioparm_ ## name = gfc_add_field_to_struct \
+ (&(TYPE_FIELDS (ioparm_type)), ioparm_type, \
+ get_identifier (stringize(name)), type)
+
+#define ADD_STRING(name) \
+ ioparm_ ## name = gfc_add_field_to_struct \
+ (&(TYPE_FIELDS (ioparm_type)), ioparm_type, \
+ get_identifier (stringize(name)), pchar_type_node); \
+ ioparm_ ## name ## _len = gfc_add_field_to_struct \
+ (&(TYPE_FIELDS (ioparm_type)), ioparm_type, \
+ get_identifier (stringize(name) "_len"), gfc_int4_type_node)
+
+
+/* Create function decls for IO library functions. */
+
+void
+gfc_build_io_library_fndecls (void)
+{
+ tree ioparm_type;
+
+ gfc_pint4_type_node = build_pointer_type (gfc_int4_type_node);
+
+/* Build the st_parameter structure. Information associated with I/O
+ calls are transferred here. This must match the one defined in the
+ library exactly. */
+
+ ioparm_type = make_node (RECORD_TYPE);
+ TYPE_NAME (ioparm_type) = get_identifier ("_gfc_ioparm");
+
+ ADD_FIELD (unit, gfc_int4_type_node);
+ ADD_FIELD (err, gfc_int4_type_node);
+ ADD_FIELD (end, gfc_int4_type_node);
+ ADD_FIELD (eor, gfc_int4_type_node);
+ ADD_FIELD (list_format, gfc_int4_type_node);
+ ADD_FIELD (library_return, gfc_int4_type_node);
+
+ ADD_FIELD (iostat, gfc_pint4_type_node);
+ ADD_FIELD (exist, gfc_pint4_type_node);
+ ADD_FIELD (opened, gfc_pint4_type_node);
+ ADD_FIELD (number, gfc_pint4_type_node);
+ ADD_FIELD (named, gfc_pint4_type_node);
+ ADD_FIELD (rec, gfc_pint4_type_node);
+ ADD_FIELD (nextrec, gfc_pint4_type_node);
+ ADD_FIELD (size, gfc_pint4_type_node);
+
+ ADD_FIELD (recl_in, gfc_pint4_type_node);
+ ADD_FIELD (recl_out, gfc_pint4_type_node);
+
+ ADD_STRING (file);
+ ADD_STRING (status);
+
+ ADD_STRING (access);
+ ADD_STRING (form);
+ ADD_STRING (blank);
+ ADD_STRING (position);
+ ADD_STRING (action);
+ ADD_STRING (delim);
+ ADD_STRING (pad);
+ ADD_STRING (format);
+ ADD_STRING (advance);
+ ADD_STRING (name);
+ ADD_STRING (internal_unit);
+ ADD_STRING (sequential);
+
+ ADD_STRING (direct);
+ ADD_STRING (formatted);
+ ADD_STRING (unformatted);
+ ADD_STRING (read);
+ ADD_STRING (write);
+ ADD_STRING (readwrite);
+
+ ADD_STRING (namelist_name);
+ ADD_FIELD (namelist_read_mode, gfc_int4_type_node);
+
+ gfc_finish_type (ioparm_type);
+
+ ioparm_var = build_decl (VAR_DECL, get_identifier (PREFIX("ioparm")),
+ ioparm_type);
+ DECL_EXTERNAL (ioparm_var) = 1;
+ TREE_PUBLIC (ioparm_var) = 1;
+
+ locus_line = build_decl (VAR_DECL, get_identifier (PREFIX("line")),
+ gfc_int4_type_node);
+ DECL_EXTERNAL (locus_line) = 1;
+ TREE_PUBLIC (locus_line) = 1;
+
+ locus_file = build_decl (VAR_DECL, get_identifier (PREFIX("filename")),
+ pchar_type_node);
+ DECL_EXTERNAL (locus_file) = 1;
+ TREE_PUBLIC (locus_file) = 1;
+
+ /* Define the transfer functions. */
+
+ iocall_x_integer =
+ gfc_build_library_function_decl (get_identifier
+ (PREFIX("transfer_integer")),
+ void_type_node, 2, pvoid_type_node,
+ gfc_int4_type_node);
+
+ iocall_x_logical =
+ gfc_build_library_function_decl (get_identifier
+ (PREFIX("transfer_logical")),
+ void_type_node, 2, pvoid_type_node,
+ gfc_int4_type_node);
+
+ iocall_x_character =
+ gfc_build_library_function_decl (get_identifier
+ (PREFIX("transfer_character")),
+ void_type_node, 2, pvoid_type_node,
+ gfc_int4_type_node);
+
+ iocall_x_real =
+ gfc_build_library_function_decl (get_identifier (PREFIX("transfer_real")),
+ void_type_node, 2,
+ pvoid_type_node, gfc_int4_type_node);
+
+ iocall_x_complex =
+ gfc_build_library_function_decl (get_identifier
+ (PREFIX("transfer_complex")),
+ void_type_node, 2, pvoid_type_node,
+ gfc_int4_type_node);
+
+ /* Library entry points */
+
+ iocall_read =
+ gfc_build_library_function_decl (get_identifier (PREFIX("st_read")),
+ void_type_node, 0);
+
+ iocall_write =
+ gfc_build_library_function_decl (get_identifier (PREFIX("st_write")),
+ void_type_node, 0);
+ iocall_open =
+ gfc_build_library_function_decl (get_identifier (PREFIX("st_open")),
+ void_type_node, 0);
+
+ iocall_close =
+ gfc_build_library_function_decl (get_identifier (PREFIX("st_close")),
+ void_type_node, 0);
+
+ iocall_inquire =
+ gfc_build_library_function_decl (get_identifier (PREFIX("st_inquire")),
+ gfc_int4_type_node, 0);
+
+ iocall_rewind =
+ gfc_build_library_function_decl (get_identifier (PREFIX("st_rewind")),
+ gfc_int4_type_node, 0);
+
+ iocall_backspace =
+ gfc_build_library_function_decl (get_identifier (PREFIX("st_backspace")),
+ gfc_int4_type_node, 0);
+
+ iocall_endfile =
+ gfc_build_library_function_decl (get_identifier (PREFIX("st_endfile")),
+ gfc_int4_type_node, 0);
+ /* Library helpers */
+
+ iocall_read_done =
+ gfc_build_library_function_decl (get_identifier (PREFIX("st_read_done")),
+ gfc_int4_type_node, 0);
+
+ iocall_write_done =
+ gfc_build_library_function_decl (get_identifier (PREFIX("st_write_done")),
+ gfc_int4_type_node, 0);
+ iocall_set_nml_val_int =
+ gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var_int")),
+ void_type_node, 4,
+ pvoid_type_node, pvoid_type_node,
+ gfc_int4_type_node,gfc_int4_type_node);
+
+ iocall_set_nml_val_float =
+ gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var_float")),
+ void_type_node, 4,
+ pvoid_type_node, pvoid_type_node,
+ gfc_int4_type_node,gfc_int4_type_node);
+ iocall_set_nml_val_char =
+ gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var_char")),
+ void_type_node, 4,
+ pvoid_type_node, pvoid_type_node,
+ gfc_int4_type_node,gfc_int4_type_node);
+ iocall_set_nml_val_complex =
+ gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var_complex")),
+ void_type_node, 4,
+ pvoid_type_node, pvoid_type_node,
+ gfc_int4_type_node,gfc_int4_type_node);
+ iocall_set_nml_val_log =
+ gfc_build_library_function_decl (get_identifier (PREFIX("st_set_nml_var_log")),
+ void_type_node, 4,
+ pvoid_type_node, pvoid_type_node,
+ gfc_int4_type_node,gfc_int4_type_node);
+
+}
+
+
+/* Generate code to store an non-string I/O parameter into the
+ ioparm structure. This is a pass by value. */
+
+static void
+set_parameter_value (stmtblock_t * block, tree var, gfc_expr * e)
+{
+ gfc_se se;
+ tree tmp;
+
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_type (&se, e, TREE_TYPE (var));
+ gfc_add_block_to_block (block, &se.pre);
+
+ tmp = build (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var);
+ gfc_add_modify_expr (block, tmp, se.expr);
+}
+
+
+/* Generate code to store an non-string I/O parameter into the
+ ioparm structure. This is pass by reference. */
+
+static void
+set_parameter_ref (stmtblock_t * block, tree var, gfc_expr * e)
+{
+ gfc_se se;
+ tree tmp;
+
+ gfc_init_se (&se, NULL);
+ se.want_pointer = 1;
+
+ gfc_conv_expr_type (&se, e, TREE_TYPE (var));
+ gfc_add_block_to_block (block, &se.pre);
+
+ tmp = build (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var);
+ gfc_add_modify_expr (block, tmp, se.expr);
+}
+
+
+/* Generate code to store a string and its length into the
+ ioparm structure. */
+
+static void
+set_string (stmtblock_t * block, stmtblock_t * postblock, tree var,
+ tree var_len, gfc_expr * e)
+{
+ gfc_se se;
+ tree tmp;
+ tree msg;
+ tree io;
+ tree len;
+
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr (&se, e);
+
+ io = build (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var);
+ len = build (COMPONENT_REF, TREE_TYPE (var_len), ioparm_var, var_len);
+
+ /* Integer variable assigned a format label. */
+ if (e->ts.type == BT_INTEGER && e->symtree->n.sym->attr.assign == 1)
+ {
+ msg =
+ gfc_build_string_const (37, "Assigned label is not a format label");
+ tmp = GFC_DECL_STRING_LEN (se.expr);
+ tmp = build (LE_EXPR, boolean_type_node, tmp, integer_minus_one_node);
+ gfc_trans_runtime_check (tmp, msg, &se.pre);
+ gfc_add_modify_expr (&se.pre, io, GFC_DECL_ASSIGN_ADDR (se.expr));
+ gfc_add_modify_expr (&se.pre, len, GFC_DECL_STRING_LEN (se.expr));
+ }
+ else
+ {
+ gfc_conv_string_parameter (&se);
+ gfc_add_modify_expr (&se.pre, io, se.expr);
+ gfc_add_modify_expr (&se.pre, len, se.string_length);
+ }
+
+ gfc_add_block_to_block (block, &se.pre);
+ gfc_add_block_to_block (postblock, &se.post);
+
+}
+
+
+/* Set a member of the ioparm structure to one. */
+static void
+set_flag (stmtblock_t *block, tree var)
+{
+ tree tmp;
+
+ tmp = build (COMPONENT_REF, TREE_TYPE(var), ioparm_var, var);
+ gfc_add_modify_expr (block, tmp, integer_one_node);
+}
+
+
+/* Add a case to a IO-result switch. */
+
+static void
+add_case (int label_value, gfc_st_label * label, stmtblock_t * body)
+{
+ tree tmp, value;
+
+ if (label == NULL)
+ return; /* No label, no case */
+
+ value = build_int_2 (label_value, 0);
+
+ /* Make a backend label for this case. */
+ tmp = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+ DECL_CONTEXT (tmp) = current_function_decl;
+
+ /* And the case itself. */
+ tmp = build_v (CASE_LABEL_EXPR, value, NULL_TREE, tmp);
+ gfc_add_expr_to_block (body, tmp);
+
+ /* Jump to the label. */
+ tmp = build1_v (GOTO_EXPR, gfc_get_label_decl (label));
+ gfc_add_expr_to_block (body, tmp);
+}
+
+
+/* Generate a switch statement that branches to the correct I/O
+ result label. The last statement of an I/O call stores the
+ result into a variable because there is often cleanup that
+ must be done before the switch, so a temporary would have to
+ be created anyway. */
+
+static void
+io_result (stmtblock_t * block, gfc_st_label * err_label,
+ gfc_st_label * end_label, gfc_st_label * eor_label)
+{
+ stmtblock_t body;
+ tree tmp, rc;
+
+ /* If no labels are specified, ignore the result instead
+ of building an empty switch. */
+ if (err_label == NULL
+ && end_label == NULL
+ && eor_label == NULL)
+ return;
+
+ /* Build a switch statement. */
+ gfc_start_block (&body);
+
+ /* The label values here must be the same as the values
+ in the library_return enum in the runtime library */
+ add_case (1, err_label, &body);
+ add_case (2, end_label, &body);
+ add_case (3, eor_label, &body);
+
+ tmp = gfc_finish_block (&body);
+
+ rc = build (COMPONENT_REF, TREE_TYPE (ioparm_library_return), ioparm_var,
+ ioparm_library_return);
+
+ tmp = build_v (SWITCH_EXPR, rc, tmp, NULL_TREE);
+
+ gfc_add_expr_to_block (block, tmp);
+}
+
+
+/* Store the current file and line number to variables so that if a
+ library call goes awry, we can tell the user where the problem is. */
+
+static void
+set_error_locus (stmtblock_t * block, locus * where)
+{
+ gfc_file *f;
+ tree tmp;
+ int line;
+
+ f = where->file;
+ tmp = gfc_build_string_const (strlen (f->filename) + 1, f->filename);
+
+ tmp = gfc_build_addr_expr (pchar_type_node, tmp);
+ gfc_add_modify_expr (block, locus_file, tmp);
+
+ line = where->lp->start_line + where->line;
+ gfc_add_modify_expr (block, locus_line, build_int_2 (line, 0));
+}
+
+
+/* Translate an OPEN statement. */
+
+tree
+gfc_trans_open (gfc_code * code)
+{
+ stmtblock_t block, post_block;
+ gfc_open *p;
+ tree tmp;
+
+ gfc_init_block (&block);
+ gfc_init_block (&post_block);
+
+ set_error_locus (&block, &code->loc);
+ p = code->ext.open;
+
+ if (p->unit)
+ set_parameter_value (&block, ioparm_unit, p->unit);
+
+ if (p->file)
+ set_string (&block, &post_block, ioparm_file, ioparm_file_len, p->file);
+
+ if (p->status)
+ set_string (&block, &post_block, ioparm_status,
+ ioparm_status_len, p->status);
+
+ if (p->access)
+ set_string (&block, &post_block, ioparm_access,
+ ioparm_access_len, p->access);
+
+ if (p->form)
+ set_string (&block, &post_block, ioparm_form, ioparm_form_len, p->form);
+
+ if (p->recl)
+ set_parameter_value (&block, ioparm_recl_in, p->recl);
+
+ if (p->blank)
+ set_string (&block, &post_block, ioparm_blank, ioparm_blank_len,
+ p->blank);
+
+ if (p->position)
+ set_string (&block, &post_block, ioparm_position,
+ ioparm_position_len, p->position);
+
+ if (p->action)
+ set_string (&block, &post_block, ioparm_action,
+ ioparm_action_len, p->action);
+
+ if (p->delim)
+ set_string (&block, &post_block, ioparm_delim, ioparm_delim_len,
+ p->delim);
+
+ if (p->pad)
+ set_string (&block, &post_block, ioparm_pad, ioparm_pad_len, p->pad);
+
+ if (p->iostat)
+ set_parameter_ref (&block, ioparm_iostat, p->iostat);
+
+ if (p->err)
+ set_flag (&block, ioparm_err);
+
+ tmp = gfc_build_function_call (iocall_open, NULL_TREE);
+ gfc_add_expr_to_block (&block, tmp);
+
+ gfc_add_block_to_block (&block, &post_block);
+
+ io_result (&block, p->err, NULL, NULL);
+
+ return gfc_finish_block (&block);
+}
+
+
+/* Translate a CLOSE statement. */
+
+tree
+gfc_trans_close (gfc_code * code)
+{
+ stmtblock_t block, post_block;
+ gfc_close *p;
+ tree tmp;
+
+ gfc_init_block (&block);
+ gfc_init_block (&post_block);
+
+ set_error_locus (&block, &code->loc);
+ p = code->ext.close;
+
+ if (p->unit)
+ set_parameter_value (&block, ioparm_unit, p->unit);
+
+ if (p->status)
+ set_string (&block, &post_block, ioparm_status,
+ ioparm_status_len, p->status);
+
+ if (p->iostat)
+ set_parameter_ref (&block, ioparm_iostat, p->iostat);
+
+ if (p->err)
+ set_flag (&block, ioparm_err);
+
+ tmp = gfc_build_function_call (iocall_close, NULL_TREE);
+ gfc_add_expr_to_block (&block, tmp);
+
+ gfc_add_block_to_block (&block, &post_block);
+
+ io_result (&block, p->err, NULL, NULL);
+
+ return gfc_finish_block (&block);
+}
+
+
+/* Common subroutine for building a file positioning statement. */
+
+static tree
+build_filepos (tree function, gfc_code * code)
+{
+ stmtblock_t block;
+ gfc_filepos *p;
+ tree tmp;
+
+ p = code->ext.filepos;
+
+ gfc_init_block (&block);
+
+ set_error_locus (&block, &code->loc);
+
+ if (p->unit)
+ set_parameter_value (&block, ioparm_unit, p->unit);
+
+ if (p->iostat)
+ set_parameter_ref (&block, ioparm_iostat, p->iostat);
+
+ if (p->err)
+ set_flag (&block, ioparm_err);
+
+ tmp = gfc_build_function_call (function, NULL);
+ gfc_add_expr_to_block (&block, tmp);
+
+ io_result (&block, p->err, NULL, NULL);
+
+ return gfc_finish_block (&block);
+}
+
+
+/* Translate a BACKSPACE statement. */
+
+tree
+gfc_trans_backspace (gfc_code * code)
+{
+
+ return build_filepos (iocall_backspace, code);
+}
+
+
+/* Translate an ENDFILE statement. */
+
+tree
+gfc_trans_endfile (gfc_code * code)
+{
+
+ return build_filepos (iocall_endfile, code);
+}
+
+
+/* Translate a REWIND statement. */
+
+tree
+gfc_trans_rewind (gfc_code * code)
+{
+
+ return build_filepos (iocall_rewind, code);
+}
+
+
+/* Translate the non-IOLENGTH form of an INQUIRE statement. */
+
+tree
+gfc_trans_inquire (gfc_code * code)
+{
+ stmtblock_t block, post_block;
+ gfc_inquire *p;
+ tree tmp;
+
+ gfc_init_block (&block);
+ gfc_init_block (&post_block);
+
+ set_error_locus (&block, &code->loc);
+ p = code->ext.inquire;
+
+ if (p->unit)
+ set_parameter_value (&block, ioparm_unit, p->unit);
+
+ if (p->file)
+ set_string (&block, &post_block, ioparm_file, ioparm_file_len, p->file);
+
+ if (p->iostat)
+ set_parameter_ref (&block, ioparm_iostat, p->iostat);
+
+ if (p->exist)
+ set_parameter_ref (&block, ioparm_exist, p->exist);
+
+ if (p->opened)
+ set_parameter_ref (&block, ioparm_opened, p->opened);
+
+ if (p->number)
+ set_parameter_ref (&block, ioparm_number, p->number);
+
+ if (p->named)
+ set_parameter_ref (&block, ioparm_named, p->named);
+
+ if (p->name)
+ set_string (&block, &post_block, ioparm_name, ioparm_name_len, p->name);
+
+ if (p->access)
+ set_string (&block, &post_block, ioparm_access,
+ ioparm_access_len, p->access);
+
+ if (p->sequential)
+ set_string (&block, &post_block, ioparm_sequential,
+ ioparm_sequential_len, p->sequential);
+
+ if (p->direct)
+ set_string (&block, &post_block, ioparm_direct,
+ ioparm_direct_len, p->direct);
+
+ if (p->form)
+ set_string (&block, &post_block, ioparm_form, ioparm_form_len, p->form);
+
+ if (p->formatted)
+ set_string (&block, &post_block, ioparm_formatted,
+ ioparm_formatted_len, p->formatted);
+
+ if (p->unformatted)
+ set_string (&block, &post_block, ioparm_unformatted,
+ ioparm_unformatted_len, p->unformatted);
+
+ if (p->recl)
+ set_parameter_ref (&block, ioparm_recl_out, p->recl);
+
+ if (p->nextrec)
+ set_parameter_ref (&block, ioparm_nextrec, p->nextrec);
+
+ if (p->blank)
+ set_string (&block, &post_block, ioparm_blank, ioparm_blank_len,
+ p->blank);
+
+ if (p->position)
+ set_string (&block, &post_block, ioparm_position,
+ ioparm_position_len, p->position);
+
+ if (p->action)
+ set_string (&block, &post_block, ioparm_action,
+ ioparm_action_len, p->action);
+
+ if (p->read)
+ set_string (&block, &post_block, ioparm_read, ioparm_read_len, p->read);
+
+ if (p->write)
+ set_string (&block, &post_block, ioparm_write,
+ ioparm_write_len, p->write);
+
+ if (p->readwrite)
+ set_string (&block, &post_block, ioparm_readwrite,
+ ioparm_readwrite_len, p->readwrite);
+
+ if (p->delim)
+ set_string (&block, &post_block, ioparm_delim, ioparm_delim_len,
+ p->delim);
+
+ if (p->err)
+ set_flag (&block, ioparm_err);
+
+ tmp = gfc_build_function_call (iocall_inquire, NULL);
+ gfc_add_expr_to_block (&block, tmp);
+
+ gfc_add_block_to_block (&block, &post_block);
+
+ io_result (&block, p->err, NULL, NULL);
+
+ return gfc_finish_block (&block);
+}
+
+
+/* Translate the IOLENGTH form of an INQUIRE statement. We treat
+ this as a third sort of data transfer statement, except that
+ lengths are summed instead of actually transfering any data. */
+
+tree
+gfc_trans_iolength (gfc_code * c ATTRIBUTE_UNUSED)
+{
+ gfc_todo_error ("IOLENGTH statement");
+}
+
+static gfc_expr *
+gfc_new_nml_name_expr (char * name)
+{
+ gfc_expr * nml_name;
+ nml_name = gfc_get_expr();
+ nml_name->ref = NULL;
+ nml_name->expr_type = EXPR_CONSTANT;
+ nml_name->ts.kind = gfc_default_character_kind ();
+ nml_name->ts.type = BT_CHARACTER;
+ nml_name->value.character.length = strlen(name);
+ nml_name->value.character.string = name;
+
+ return nml_name;
+}
+
+static gfc_expr *
+get_new_var_expr(gfc_symbol * sym)
+{
+ gfc_expr * nml_var;
+
+ nml_var = gfc_get_expr();
+ nml_var->expr_type = EXPR_VARIABLE;
+ nml_var->ts = sym->ts;
+ if (sym->as)
+ nml_var->rank = sym->as->rank;
+ nml_var->symtree = (gfc_symtree *)gfc_getmem (sizeof (gfc_symtree));
+ nml_var->symtree->n.sym = sym;
+ nml_var->where = sym->declared_at;
+ sym->attr.referenced = 1;
+
+ return nml_var;
+}
+
+
+/* Create a data transfer statement. Not all of the fields are valid
+ for both reading and writing, but improper use has been filtered
+ out by now. */
+
+static tree
+build_dt (tree * function, gfc_code * code)
+{
+ stmtblock_t block, post_block;
+ gfc_dt *dt;
+ tree tmp, args, arg2;
+ gfc_expr *nmlname, *nmlvar;
+ gfc_namelist *nml, *nml_tail;
+ gfc_se se,se2;
+ int ts_kind, ts_type, name_len;
+
+ gfc_init_block (&block);
+ gfc_init_block (&post_block);
+
+ set_error_locus (&block, &code->loc);
+ dt = code->ext.dt;
+
+ if (dt->io_unit)
+ {
+ if (dt->io_unit->ts.type == BT_CHARACTER)
+ {
+ set_string (&block, &post_block, ioparm_internal_unit,
+ ioparm_internal_unit_len, dt->io_unit);
+ }
+ else
+ set_parameter_value (&block, ioparm_unit, dt->io_unit);
+ }
+
+ if (dt->rec)
+ set_parameter_value (&block, ioparm_rec, dt->rec);
+
+ if (dt->advance)
+ set_string (&block, &post_block, ioparm_advance, ioparm_advance_len,
+ dt->advance);
+
+ if (dt->format_expr)
+ set_string (&block, &post_block, ioparm_format, ioparm_format_len,
+ dt->format_expr);
+
+ if (dt->format_label)
+ {
+ if (dt->format_label == &format_asterisk)
+ set_flag (&block, ioparm_list_format);
+ else
+ set_string (&block, &post_block, ioparm_format,
+ ioparm_format_len, dt->format_label->format);
+ }
+
+ if (dt->iostat)
+ set_parameter_ref (&block, ioparm_iostat, dt->iostat);
+
+ if (dt->size)
+ set_parameter_ref (&block, ioparm_size, dt->size);
+
+ if (dt->err)
+ set_flag (&block, ioparm_err);
+
+ if (dt->eor)
+ set_flag(&block, ioparm_eor);
+
+ if (dt->end)
+ set_flag(&block, ioparm_end);
+
+ if (dt->namelist)
+ {
+ if (dt->format_expr || dt->format_label)
+ fatal_error("A format cannot be specified with a namelist");
+
+ nmlname = gfc_new_nml_name_expr(dt->namelist->name);
+
+ set_string (&block, &post_block, ioparm_namelist_name,
+ ioparm_namelist_name_len, nmlname);
+
+ if (last_dt == READ)
+ set_flag (&block, ioparm_namelist_read_mode);
+
+ nml = dt->namelist->namelist;
+ nml_tail = dt->namelist->namelist_tail;
+
+ while(nml != NULL)
+ {
+ gfc_init_se (&se, NULL);
+ gfc_init_se (&se2, NULL);
+ nmlvar = get_new_var_expr(nml->sym);
+ nmlname = gfc_new_nml_name_expr(nml->sym->name);
+ name_len = strlen(nml->sym->name);
+ ts_kind = nml->sym->ts.kind;
+ ts_type = nml->sym->ts.type;
+
+ gfc_conv_expr_reference (&se2, nmlname);
+ gfc_conv_expr_reference (&se, nmlvar);
+ args = gfc_chainon_list (NULL_TREE, se.expr);
+ args = gfc_chainon_list (args, se2.expr);
+ args = gfc_chainon_list (args, se2.string_length);
+ arg2 = build_int_2 (ts_kind, 0);
+ args = gfc_chainon_list (args,arg2);
+ switch (ts_type)
+ {
+ case BT_INTEGER:
+ tmp = gfc_build_function_call (iocall_set_nml_val_int, args);
+ break;
+ case BT_CHARACTER:
+ tmp = gfc_build_function_call (iocall_set_nml_val_char, args);
+ break;
+ case BT_REAL:
+ tmp = gfc_build_function_call (iocall_set_nml_val_float, args);
+ break;
+ case BT_LOGICAL:
+ tmp = gfc_build_function_call (iocall_set_nml_val_log, args);
+ break;
+ case BT_COMPLEX:
+ tmp = gfc_build_function_call (iocall_set_nml_val_complex, args);
+ break;
+ default :
+ internal_error ("Bad namelist IO basetype (%d)", ts_type);
+ }
+
+ gfc_add_expr_to_block (&block, tmp);
+
+ nml = nml->next;
+ }
+ }
+
+ tmp = gfc_build_function_call (*function, NULL_TREE);
+ gfc_add_expr_to_block (&block, tmp);
+
+ gfc_add_block_to_block (&block, &post_block);
+
+ return gfc_finish_block (&block);
+}
+
+
+/* Translate a READ statement. */
+
+tree
+gfc_trans_read (gfc_code * code)
+{
+
+ last_dt = READ;
+ return build_dt (&iocall_read, code);
+}
+
+
+/* Translate a WRITE statement */
+
+tree
+gfc_trans_write (gfc_code * code)
+{
+
+ last_dt = WRITE;
+ return build_dt (&iocall_write, code);
+}
+
+
+/* Finish a data transfer statement. */
+
+tree
+gfc_trans_dt_end (gfc_code * code)
+{
+ tree function, tmp;
+ stmtblock_t block;
+
+ gfc_init_block (&block);
+
+ function = (last_dt == READ) ? iocall_read_done : iocall_write_done;
+
+ tmp = gfc_build_function_call (function, NULL);
+ gfc_add_expr_to_block (&block, tmp);
+
+ io_result (&block, code->ext.dt->err, code->ext.dt->end, code->ext.dt->eor);
+
+ return gfc_finish_block (&block);
+}
+
+
+/* Generate the call for a scalar transfer node. */
+
+static void
+transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr)
+{
+ tree args, tmp, function, arg2, field, expr;
+ gfc_component *c;
+ int kind;
+
+ kind = ts->kind;
+ function = NULL;
+ arg2 = NULL;
+
+ switch (ts->type)
+ {
+ case BT_INTEGER:
+ arg2 = build_int_2 (kind, 0);
+ function = iocall_x_integer;
+ break;
+
+ case BT_REAL:
+ arg2 = build_int_2 (kind, 0);
+ function = iocall_x_real;
+ break;
+
+ case BT_COMPLEX:
+ arg2 = build_int_2 (kind, 0);
+ function = iocall_x_complex;
+ break;
+
+ case BT_LOGICAL:
+ arg2 = build_int_2 (kind, 0);
+ function = iocall_x_logical;
+ break;
+
+ case BT_CHARACTER:
+ arg2 = se->string_length;
+ function = iocall_x_character;
+ break;
+
+ case BT_DERIVED:
+ expr = gfc_evaluate_now (addr_expr, &se->pre);
+ expr = gfc_build_indirect_ref (expr);
+
+ for (c = ts->derived->components; c; c = c->next)
+ {
+ field = c->backend_decl;
+ assert (field && TREE_CODE (field) == FIELD_DECL);
+
+ tmp = build (COMPONENT_REF, TREE_TYPE (field), expr, field);
+
+ if (c->ts.type == BT_CHARACTER)
+ {
+ assert (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE);
+ se->string_length =
+ TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (tmp)));
+ }
+ transfer_expr (se, &c->ts, gfc_build_addr_expr (NULL, tmp));
+ }
+ return;
+
+ default:
+ internal_error ("Bad IO basetype (%d)", ts->type);
+ }
+
+ args = gfc_chainon_list (NULL_TREE, addr_expr);
+ args = gfc_chainon_list (args, arg2);
+
+ tmp = gfc_build_function_call (function, args);
+ gfc_add_expr_to_block (&se->pre, tmp);
+ gfc_add_block_to_block (&se->pre, &se->post);
+}
+
+
+/* gfc_trans_transfer()-- Translate a TRANSFER code node */
+
+tree
+gfc_trans_transfer (gfc_code * code)
+{
+ stmtblock_t block, body;
+ gfc_loopinfo loop;
+ gfc_expr *expr;
+ gfc_ss *ss;
+ gfc_se se;
+ tree tmp;
+
+ gfc_start_block (&block);
+
+ expr = code->expr;
+ ss = gfc_walk_expr (expr);
+
+ gfc_init_se (&se, NULL);
+
+ if (ss == gfc_ss_terminator)
+ gfc_init_block (&body);
+ else
+ {
+ /* Initialize the scalarizer. */
+ gfc_init_loopinfo (&loop);
+ gfc_add_ss_to_loop (&loop, ss);
+
+ /* Initialize the loop. */
+ gfc_conv_ss_startstride (&loop);
+ gfc_conv_loop_setup (&loop);
+
+ /* The main loop body. */
+ gfc_mark_ss_chain_used (ss, 1);
+ gfc_start_scalarized_body (&loop, &body);
+
+ gfc_copy_loopinfo_to_se (&se, &loop);
+ se.ss = ss;
+ }
+
+ gfc_conv_expr_reference (&se, expr);
+
+ transfer_expr (&se, &expr->ts, se.expr);
+
+ gfc_add_block_to_block (&body, &se.pre);
+ gfc_add_block_to_block (&body, &se.post);
+
+ if (se.ss == NULL)
+ tmp = gfc_finish_block (&body);
+ else
+ {
+ assert (se.ss == gfc_ss_terminator);
+ gfc_trans_scalarizing_loops (&loop, &body);
+
+ gfc_add_block_to_block (&loop.pre, &loop.post);
+ tmp = gfc_finish_block (&loop.pre);
+ gfc_cleanup_loop (&loop);
+ }
+
+ gfc_add_expr_to_block (&block, tmp);
+
+ return gfc_finish_block (&block);;
+}
+
+#include "gt-fortran-trans-io.h"
+
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
new file mode 100644
index 00000000000..8df85d77e32
--- /dev/null
+++ b/gcc/fortran/trans-stmt.c
@@ -0,0 +1,3159 @@
+/* Statement translation -- generate GCC trees from gfc_code.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+ and Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "tree-gimple.h"
+#include <stdio.h>
+#include "ggc.h"
+#include "toplev.h"
+#include "real.h"
+#include <assert.h>
+#include <gmp.h>
+#include "gfortran.h"
+#include "trans.h"
+#include "trans-stmt.h"
+#include "trans-types.h"
+#include "trans-array.h"
+#include "trans-const.h"
+#include "arith.h"
+
+int has_alternate_specifier;
+
+typedef struct iter_info
+{
+ tree var;
+ tree start;
+ tree end;
+ tree step;
+ struct iter_info *next;
+}
+iter_info;
+
+typedef struct temporary_list
+{
+ tree temporary;
+ struct temporary_list *next;
+}
+temporary_list;
+
+typedef struct forall_info
+{
+ iter_info *this_loop;
+ tree mask;
+ tree pmask;
+ tree maskindex;
+ int nvar;
+ tree size;
+ struct forall_info *outer;
+ struct forall_info *next_nest;
+}
+forall_info;
+
+static void gfc_trans_where_2 (gfc_code *, tree, tree, forall_info *,
+ stmtblock_t *, temporary_list **temp);
+
+/* Translate a F95 label number to a LABEL_EXPR. */
+
+tree
+gfc_trans_label_here (gfc_code * code)
+{
+ return build1_v (LABEL_EXPR, gfc_get_label_decl (code->here));
+}
+
+/* Translate a label assignment statement. */
+tree
+gfc_trans_label_assign (gfc_code * code)
+{
+ tree label_tree;
+ gfc_se se;
+ tree len;
+ tree addr;
+ tree len_tree;
+ char *label_str;
+ int label_len;
+
+ /* Start a new block. */
+ gfc_init_se (&se, NULL);
+ gfc_start_block (&se.pre);
+ gfc_conv_expr (&se, code->expr);
+ len = GFC_DECL_STRING_LEN (se.expr);
+ addr = GFC_DECL_ASSIGN_ADDR (se.expr);
+
+ label_tree = gfc_get_label_decl (code->label);
+
+ if (code->label->defined == ST_LABEL_TARGET)
+ {
+ label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
+ len_tree = integer_minus_one_node;
+ }
+ else
+ {
+ label_str = code->label->format->value.character.string;
+ label_len = code->label->format->value.character.length;
+ len_tree = build_int_2 (label_len, 0);
+ label_tree = gfc_build_string_const (label_len + 1, label_str);
+ label_tree = gfc_build_addr_expr (pchar_type_node, label_tree);
+ }
+
+ gfc_add_modify_expr (&se.pre, len, len_tree);
+ gfc_add_modify_expr (&se.pre, addr, label_tree);
+
+ return gfc_finish_block (&se.pre);
+}
+
+/* Translate a GOTO statement. */
+
+tree
+gfc_trans_goto (gfc_code * code)
+{
+ tree assigned_goto;
+ tree target;
+ tree tmp;
+ tree assign_error;
+ tree range_error;
+ gfc_se se;
+
+
+ if (code->label != NULL)
+ return build1_v (GOTO_EXPR, gfc_get_label_decl (code->label));
+
+ /* ASSIGNED GOTO. */
+ gfc_init_se (&se, NULL);
+ gfc_start_block (&se.pre);
+ gfc_conv_expr (&se, code->expr);
+ assign_error =
+ gfc_build_string_const (37, "Assigned label is not a target label");
+ tmp = GFC_DECL_STRING_LEN (se.expr);
+ tmp = build (NE_EXPR, boolean_type_node, tmp, integer_minus_one_node);
+ gfc_trans_runtime_check (tmp, assign_error, &se.pre);
+
+ assigned_goto = GFC_DECL_ASSIGN_ADDR (se.expr);
+ target = build1 (GOTO_EXPR, void_type_node, assigned_goto);
+
+ code = code->block;
+ if (code == NULL)
+ {
+ gfc_add_expr_to_block (&se.pre, target);
+ return gfc_finish_block (&se.pre);
+ }
+
+ /* Check the label list. */
+ range_error =
+ gfc_build_string_const (34, "Assigned label is not in the list");
+
+ do
+ {
+ tmp = gfc_get_label_decl (code->label);
+ tmp = gfc_build_addr_expr (pvoid_type_node, tmp);
+ tmp = build (EQ_EXPR, boolean_type_node, tmp, assigned_goto);
+ tmp = build_v (COND_EXPR, tmp, target, build_empty_stmt ());
+ gfc_add_expr_to_block (&se.pre, tmp);
+ code = code->block;
+ }
+ while (code != NULL);
+ gfc_trans_runtime_check (boolean_true_node, range_error, &se.pre);
+ return gfc_finish_block (&se.pre);
+}
+
+
+/* Translate the CALL statement. Builds a call to an F95 subroutine. */
+
+tree
+gfc_trans_call (gfc_code * code)
+{
+ gfc_se se;
+
+ /* A CALL starts a new block because the actual arguments may have to
+ be evaluated first. */
+ gfc_init_se (&se, NULL);
+ gfc_start_block (&se.pre);
+
+ assert (code->resolved_sym);
+ has_alternate_specifier = 0;
+
+ /* Translate the call. */
+ gfc_conv_function_call (&se, code->resolved_sym, code->ext.actual);
+
+ /* A subroutine without side-effect, by definition, does nothing! */
+ TREE_SIDE_EFFECTS (se.expr) = 1;
+
+ /* Chain the pieces together and return the block. */
+ if (has_alternate_specifier)
+ {
+ gfc_code *select_code;
+ gfc_symbol *sym;
+ select_code = code->next;
+ assert(select_code->op == EXEC_SELECT);
+ sym = select_code->expr->symtree->n.sym;
+ se.expr = convert (gfc_typenode_for_spec (&sym->ts), se.expr);
+ gfc_add_modify_expr (&se.pre, sym->backend_decl, se.expr);
+ }
+ else
+ gfc_add_expr_to_block (&se.pre, se.expr);
+
+ gfc_add_block_to_block (&se.pre, &se.post);
+ return gfc_finish_block (&se.pre);
+}
+
+
+/* Translate the RETURN statement. */
+
+tree
+gfc_trans_return (gfc_code * code ATTRIBUTE_UNUSED)
+{
+ if (code->expr)
+ {
+ gfc_se se;
+ tree tmp;
+ tree result;
+
+ /* if code->expr is not NULL, this return statement must appear
+ in a subroutine and current_fake_result_decl has already
+ been generated. */
+
+ result = gfc_get_fake_result_decl (NULL);
+ if (!result)
+ {
+ gfc_warning ("An alternate return at %L without a * dummy argument",
+ &code->expr->where);
+ return build1_v (GOTO_EXPR, gfc_get_return_label ());
+ }
+
+ /* Start a new block for this statement. */
+ gfc_init_se (&se, NULL);
+ gfc_start_block (&se.pre);
+
+ gfc_conv_expr (&se, code->expr);
+
+ tmp = build (MODIFY_EXPR, TREE_TYPE (result), result, se.expr);
+ gfc_add_expr_to_block (&se.pre, tmp);
+
+ tmp = build1_v (GOTO_EXPR, gfc_get_return_label ());
+ gfc_add_expr_to_block (&se.pre, tmp);
+ gfc_add_block_to_block (&se.pre, &se.post);
+ return gfc_finish_block (&se.pre);
+ }
+ else
+ return build1_v (GOTO_EXPR, gfc_get_return_label ());
+}
+
+
+/* Translate the PAUSE statement. We have to translate this statement
+ to a runtime library call. */
+
+tree
+gfc_trans_pause (gfc_code * code)
+{
+ gfc_se se;
+ tree args;
+ tree tmp;
+ tree fndecl;
+
+ /* Start a new block for this statement. */
+ gfc_init_se (&se, NULL);
+ gfc_start_block (&se.pre);
+
+
+ if (code->expr == NULL)
+ {
+ tmp = build_int_2 (code->ext.stop_code, 0);
+ TREE_TYPE (tmp) = gfc_int4_type_node;
+ args = gfc_chainon_list (NULL_TREE, tmp);
+ fndecl = gfor_fndecl_pause_numeric;
+ }
+ else
+ {
+ gfc_conv_expr_reference (&se, code->expr);
+ args = gfc_chainon_list (NULL_TREE, se.expr);
+ args = gfc_chainon_list (args, se.string_length);
+ fndecl = gfor_fndecl_pause_string;
+ }
+
+ tmp = gfc_build_function_call (fndecl, args);
+ gfc_add_expr_to_block (&se.pre, tmp);
+
+ gfc_add_block_to_block (&se.pre, &se.post);
+
+ return gfc_finish_block (&se.pre);
+}
+
+
+/* Translate the STOP statement. We have to translate this statement
+ to a runtime library call. */
+
+tree
+gfc_trans_stop (gfc_code * code)
+{
+ gfc_se se;
+ tree args;
+ tree tmp;
+ tree fndecl;
+
+ /* Start a new block for this statement. */
+ gfc_init_se (&se, NULL);
+ gfc_start_block (&se.pre);
+
+
+ if (code->expr == NULL)
+ {
+ tmp = build_int_2 (code->ext.stop_code, 0);
+ TREE_TYPE (tmp) = gfc_int4_type_node;
+ args = gfc_chainon_list (NULL_TREE, tmp);
+ fndecl = gfor_fndecl_stop_numeric;
+ }
+ else
+ {
+ gfc_conv_expr_reference (&se, code->expr);
+ args = gfc_chainon_list (NULL_TREE, se.expr);
+ args = gfc_chainon_list (args, se.string_length);
+ fndecl = gfor_fndecl_stop_string;
+ }
+
+ tmp = gfc_build_function_call (fndecl, args);
+ gfc_add_expr_to_block (&se.pre, tmp);
+
+ gfc_add_block_to_block (&se.pre, &se.post);
+
+ return gfc_finish_block (&se.pre);
+}
+
+
+/* Generate GENERIC for the IF construct. This function also deals with
+ the simple IF statement, because the front end translates the IF
+ statement into an IF construct.
+
+ We translate:
+
+ IF (cond) THEN
+ then_clause
+ ELSEIF (cond2)
+ elseif_clause
+ ELSE
+ else_clause
+ ENDIF
+
+ into:
+
+ pre_cond_s;
+ if (cond_s)
+ {
+ then_clause;
+ }
+ else
+ {
+ pre_cond_s
+ if (cond_s)
+ {
+ elseif_clause
+ }
+ else
+ {
+ else_clause;
+ }
+ }
+
+ where COND_S is the simplified version of the predicate. PRE_COND_S
+ are the pre side-effects produced by the translation of the
+ conditional.
+ We need to build the chain recursively otherwise we run into
+ problems with folding incomplete statements. */
+
+static tree
+gfc_trans_if_1 (gfc_code * code)
+{
+ gfc_se if_se;
+ tree stmt, elsestmt;
+
+ /* Check for an unconditional ELSE clause. */
+ if (!code->expr)
+ return gfc_trans_code (code->next);
+
+ /* Initialize a statement builder for each block. Puts in NULL_TREEs. */
+ gfc_init_se (&if_se, NULL);
+ gfc_start_block (&if_se.pre);
+
+ /* Calculate the IF condition expression. */
+ gfc_conv_expr_val (&if_se, code->expr);
+
+ /* Translate the THEN clause. */
+ stmt = gfc_trans_code (code->next);
+
+ /* Translate the ELSE clause. */
+ if (code->block)
+ elsestmt = gfc_trans_if_1 (code->block);
+ else
+ elsestmt = build_empty_stmt ();
+
+ /* Build the condition expression and add it to the condition block. */
+ stmt = build_v (COND_EXPR, if_se.expr, stmt, elsestmt);
+
+ gfc_add_expr_to_block (&if_se.pre, stmt);
+
+ /* Finish off this statement. */
+ return gfc_finish_block (&if_se.pre);
+}
+
+tree
+gfc_trans_if (gfc_code * code)
+{
+ /* Ignore the top EXEC_IF, it only announces an IF construct. The
+ actual code we must translate is in code->block. */
+
+ return gfc_trans_if_1 (code->block);
+}
+
+
+/* Translage an arithmetic IF expression.
+
+ IF (cond) label1, label2, label3 translates to
+
+ if (cond <= 0)
+ {
+ if (cond < 0)
+ goto label1;
+ else // cond == 0
+ goto label2;
+ }
+ else // cond > 0
+ goto label3;
+*/
+
+tree
+gfc_trans_arithmetic_if (gfc_code * code)
+{
+ gfc_se se;
+ tree tmp;
+ tree branch1;
+ tree branch2;
+ tree zero;
+
+ /* Start a new block. */
+ gfc_init_se (&se, NULL);
+ gfc_start_block (&se.pre);
+
+ /* Pre-evaluate COND. */
+ gfc_conv_expr_val (&se, code->expr);
+
+ /* Build something to compare with. */
+ zero = gfc_build_const (TREE_TYPE (se.expr), integer_zero_node);
+
+ /* If (cond < 0) take branch1 else take branch2.
+ First build jumps to the COND .LT. 0 and the COND .EQ. 0 cases. */
+ branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label));
+ branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label2));
+
+ tmp = build (LT_EXPR, boolean_type_node, se.expr, zero);
+ branch1 = build_v (COND_EXPR, tmp, branch1, branch2);
+
+ /* if (cond <= 0) take branch1 else take branch2. */
+ branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label3));
+ tmp = build (LE_EXPR, boolean_type_node, se.expr, zero);
+ branch1 = build_v (COND_EXPR, tmp, branch1, branch2);
+
+ /* Append the COND_EXPR to the evaluation of COND, and return. */
+ gfc_add_expr_to_block (&se.pre, branch1);
+ return gfc_finish_block (&se.pre);
+}
+
+
+/* Translate the DO construct. This obviously is one of the most
+ important ones to get right with any compiler, but especially
+ so for Fortran.
+
+ Currently we calculate the loop count before entering the loop, but
+ it may be possible to optimize if step is a constant. The main
+ advantage is that the loop test is a single GENERIC node
+
+ We translate a do loop from:
+
+ DO dovar = from, to, step
+ body
+ END DO
+
+ to:
+
+ pre_dovar;
+ pre_from;
+ pre_to;
+ pre_step;
+ temp1=to_expr-from_expr;
+ step_temp=step_expr;
+ range_temp=step_tmp/range_temp;
+ for ( ; range_temp > 0 ; range_temp = range_temp - 1)
+ {
+ body;
+cycle_label:
+ dovar_temp = dovar
+ dovar=dovar_temp + step_temp;
+ }
+exit_label:
+
+ Some optimization is done for empty do loops. We can't just let
+ dovar=to because it's possible for from+range*loopcount!=to. Anyone
+ who writes empty DO deserves sub-optimal (but correct) code anyway.
+
+ TODO: Large loop counts
+ Does not work loop counts which do not fit into a signed integer kind,
+ ie. Does not work for loop counts > 2^31 for integer(kind=4) variables
+ We must support the full range. */
+
+tree
+gfc_trans_do (gfc_code * code)
+{
+ gfc_se se;
+ tree dovar;
+ tree from;
+ tree to;
+ tree step;
+ tree count;
+ tree type;
+ tree cond;
+ tree cycle_label;
+ tree exit_label;
+ tree tmp;
+ stmtblock_t block;
+ stmtblock_t body;
+
+ gfc_start_block (&block);
+
+ /* Create GIMPLE versions of all expressions in the iterator. */
+
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_lhs (&se, code->ext.iterator->var);
+ gfc_add_block_to_block (&block, &se.pre);
+ dovar = se.expr;
+ type = TREE_TYPE (dovar);
+
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_type (&se, code->ext.iterator->start, type);
+ gfc_add_block_to_block (&block, &se.pre);
+ from = se.expr;
+
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_type (&se, code->ext.iterator->end, type);
+ gfc_add_block_to_block (&block, &se.pre);
+ to = se.expr;
+
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_type (&se, code->ext.iterator->step, type);
+
+ /* We don't want this changing part way through. */
+ gfc_make_safe_expr (&se);
+ gfc_add_block_to_block (&block, &se.pre);
+ step = se.expr;
+
+ /* Initialise loop count. This code is executed before we enter the
+ loop body. We generate: count = (to + step - from) / step. */
+
+ tmp = fold (build (MINUS_EXPR, type, step, from));
+ tmp = fold (build (PLUS_EXPR, type, to, tmp));
+ tmp = fold (build (TRUNC_DIV_EXPR, type, tmp, step));
+
+ count = gfc_create_var (type, "count");
+ gfc_add_modify_expr (&block, count, tmp);
+
+ /* Initialise the DO variable: dovar = from. */
+ gfc_add_modify_expr (&block, dovar, from);
+
+ /* Loop body. */
+ gfc_start_block (&body);
+
+ /* Cycle and exit statements are implemented with gotos. */
+ cycle_label = gfc_build_label_decl (NULL_TREE);
+ exit_label = gfc_build_label_decl (NULL_TREE);
+
+ /* Start with the loop condition. Loop until count <= 0. */
+ cond = build (LE_EXPR, boolean_type_node, count, integer_zero_node);
+ tmp = build1_v (GOTO_EXPR, exit_label);
+ TREE_USED (exit_label) = 1;
+ tmp = build_v (COND_EXPR, cond, tmp, build_empty_stmt ());
+ gfc_add_expr_to_block (&body, tmp);
+
+ /* Put these labels where they can be found later. We put the
+ labels in a TREE_LIST node (because TREE_CHAIN is already
+ used). cycle_label goes in TREE_PURPOSE (backend_decl), exit
+ label in TREE_VALUE (backend_decl). */
+
+ code->block->backend_decl = tree_cons (cycle_label, exit_label, NULL);
+
+ /* Main loop body. */
+ tmp = gfc_trans_code (code->block->next);
+ gfc_add_expr_to_block (&body, tmp);
+
+ /* Label for cycle statements (if needed). */
+ if (TREE_USED (cycle_label))
+ {
+ tmp = build1_v (LABEL_EXPR, cycle_label);
+ gfc_add_expr_to_block (&body, tmp);
+ }
+
+ /* Increment the loop variable. */
+ tmp = build (PLUS_EXPR, type, dovar, step);
+ gfc_add_modify_expr (&body, dovar, tmp);
+
+ /* Decrement the loop count. */
+ tmp = build (MINUS_EXPR, type, count, integer_one_node);
+ gfc_add_modify_expr (&body, count, tmp);
+
+ /* End of loop body. */
+ tmp = gfc_finish_block (&body);
+
+ /* The for loop itself. */
+ tmp = build_v (LOOP_EXPR, tmp);
+ gfc_add_expr_to_block (&block, tmp);
+
+ /* Add the exit label. */
+ tmp = build1_v (LABEL_EXPR, exit_label);
+ gfc_add_expr_to_block (&block, tmp);
+
+ return gfc_finish_block (&block);
+}
+
+
+/* Translate the DO WHILE construct.
+
+ We translate
+
+ DO WHILE (cond)
+ body
+ END DO
+
+ to:
+
+ for ( ; ; )
+ {
+ pre_cond;
+ if (! cond) goto exit_label;
+ body;
+cycle_label:
+ }
+exit_label:
+
+ Because the evaluation of the exit condition `cond' may have side
+ effects, we can't do much for empty loop bodies. The backend optimizers
+ should be smart enough to eliminate any dead loops. */
+
+tree
+gfc_trans_do_while (gfc_code * code)
+{
+ gfc_se cond;
+ tree tmp;
+ tree cycle_label;
+ tree exit_label;
+ stmtblock_t block;
+
+ /* Everything we build here is part of the loop body. */
+ gfc_start_block (&block);
+
+ /* Cycle and exit statements are implemented with gotos. */
+ cycle_label = gfc_build_label_decl (NULL_TREE);
+ exit_label = gfc_build_label_decl (NULL_TREE);
+
+ /* Put the labels where they can be found later. See gfc_trans_do(). */
+ code->block->backend_decl = tree_cons (cycle_label, exit_label, NULL);
+
+ /* Create a GIMPLE version of the exit condition. */
+ gfc_init_se (&cond, NULL);
+ gfc_conv_expr_val (&cond, code->expr);
+ gfc_add_block_to_block (&block, &cond.pre);
+ cond.expr = fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, cond.expr));
+
+ /* Build "IF (! cond) GOTO exit_label". */
+ tmp = build1_v (GOTO_EXPR, exit_label);
+ TREE_USED (exit_label) = 1;
+ tmp = build_v (COND_EXPR, cond.expr, tmp, build_empty_stmt ());
+ gfc_add_expr_to_block (&block, tmp);
+
+ /* The main body of the loop. */
+ tmp = gfc_trans_code (code->block->next);
+ gfc_add_expr_to_block (&block, tmp);
+
+ /* Label for cycle statements (if needed). */
+ if (TREE_USED (cycle_label))
+ {
+ tmp = build1_v (LABEL_EXPR, cycle_label);
+ gfc_add_expr_to_block (&block, tmp);
+ }
+
+ /* End of loop body. */
+ tmp = gfc_finish_block (&block);
+
+ gfc_init_block (&block);
+ /* Build the loop. */
+ tmp = build_v (LOOP_EXPR, tmp);
+ gfc_add_expr_to_block (&block, tmp);
+
+ /* Add the exit label. */
+ tmp = build1_v (LABEL_EXPR, exit_label);
+ gfc_add_expr_to_block (&block, tmp);
+
+ return gfc_finish_block (&block);
+}
+
+
+/* Translate the SELECT CASE construct for INTEGER case expressions,
+ without killing all potential optimizations. The problem is that
+ Fortran allows unbounded cases, but the back-end does not, so we
+ need to intercept those before we enter the equivalent SWITCH_EXPR
+ we can build.
+
+ For example, we translate this,
+
+ SELECT CASE (expr)
+ CASE (:100,101,105:115)
+ block_1
+ CASE (190:199,200:)
+ block_2
+ CASE (300)
+ block_3
+ CASE DEFAULT
+ block_4
+ END SELECT
+
+ to the GENERIC equivalent,
+
+ switch (expr)
+ {
+ case (minimum value for typeof(expr) ... 100:
+ case 101:
+ case 105 ... 114:
+ block1:
+ goto end_label;
+
+ case 200 ... (maximum value for typeof(expr):
+ case 190 ... 199:
+ block2;
+ goto end_label;
+
+ case 300:
+ block_3;
+ goto end_label;
+
+ default:
+ block_4;
+ goto end_label;
+ }
+
+ end_label: */
+
+static tree
+gfc_trans_integer_select (gfc_code * code)
+{
+ gfc_code *c;
+ gfc_case *cp;
+ tree end_label;
+ tree tmp;
+ gfc_se se;
+ stmtblock_t block;
+ stmtblock_t body;
+
+ gfc_start_block (&block);
+
+ /* Calculate the switch expression. */
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_val (&se, code->expr);
+ gfc_add_block_to_block (&block, &se.pre);
+
+ end_label = gfc_build_label_decl (NULL_TREE);
+
+ gfc_init_block (&body);
+
+ for (c = code->block; c; c = c->block)
+ {
+ for (cp = c->ext.case_list; cp; cp = cp->next)
+ {
+ tree low, high;
+ tree label;
+
+ /* Assume it's the default case. */
+ low = high = NULL_TREE;
+
+ if (cp->low)
+ {
+ low = gfc_conv_constant_to_tree (cp->low);
+
+ /* If there's only a lower bound, set the high bound to the
+ maximum value of the case expression. */
+ if (!cp->high)
+ high = TYPE_MAX_VALUE (TREE_TYPE (se.expr));
+ }
+
+ if (cp->high)
+ {
+ /* Three cases are possible here:
+
+ 1) There is no lower bound, e.g. CASE (:N).
+ 2) There is a lower bound .NE. high bound, that is
+ a case range, e.g. CASE (N:M) where M>N (we make
+ sure that M>N during type resolution).
+ 3) There is a lower bound, and it has the same value
+ as the high bound, e.g. CASE (N:N). This is our
+ internal representation of CASE(N).
+
+ In the first and second case, we need to set a value for
+ high. In the thirth case, we don't because the GCC middle
+ end represents a single case value by just letting high be
+ a NULL_TREE. We can't do that because we need to be able
+ to represent unbounded cases. */
+
+ if (!cp->low
+ || (cp->low
+ && mpz_cmp (cp->low->value.integer,
+ cp->high->value.integer) != 0))
+ high = gfc_conv_constant_to_tree (cp->high);
+
+ /* Unbounded case. */
+ if (!cp->low)
+ low = TYPE_MIN_VALUE (TREE_TYPE (se.expr));
+ }
+
+ /* Build a label. */
+ label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+ DECL_CONTEXT (label) = current_function_decl;
+
+ /* Add this case label.
+ Add parameter 'label', make it match GCC backend. */
+ tmp = build (CASE_LABEL_EXPR, void_type_node, low, high, label);
+ gfc_add_expr_to_block (&body, tmp);
+ }
+
+ /* Add the statements for this case. */
+ tmp = gfc_trans_code (c->next);
+ gfc_add_expr_to_block (&body, tmp);
+
+ /* Break to the end of the construct. */
+ tmp = build1_v (GOTO_EXPR, end_label);
+ gfc_add_expr_to_block (&body, tmp);
+ }
+
+ tmp = gfc_finish_block (&body);
+ tmp = build_v (SWITCH_EXPR, se.expr, tmp, NULL_TREE);
+ gfc_add_expr_to_block (&block, tmp);
+
+ tmp = build1_v (LABEL_EXPR, end_label);
+ gfc_add_expr_to_block (&block, tmp);
+
+ return gfc_finish_block (&block);
+}
+
+
+/* Translate the SELECT CASE construct for LOGICAL case expressions.
+
+ There are only two cases possible here, even though the standard
+ does allow three cases in a LOGICAL SELECT CASE construct: .TRUE.,
+ .FALSE., and DEFAULT.
+
+ We never generate more than two blocks here. Instead, we always
+ try to eliminate the DEFAULT case. This way, we can translate this
+ kind of SELECT construct to a simple
+
+ if {} else {};
+
+ expression in GENERIC. */
+
+static tree
+gfc_trans_logical_select (gfc_code * code)
+{
+ gfc_code *c;
+ gfc_code *t, *f, *d;
+ gfc_case *cp;
+ gfc_se se;
+ stmtblock_t block;
+
+ /* Assume we don't have any cases at all. */
+ t = f = d = NULL;
+
+ /* Now see which ones we actually do have. We can have at most two
+ cases in a single case list: one for .TRUE. and one for .FALSE.
+ The default case is always separate. If the cases for .TRUE. and
+ .FALSE. are in the same case list, the block for that case list
+ always executed, and we don't generate code a COND_EXPR. */
+ for (c = code->block; c; c = c->block)
+ {
+ for (cp = c->ext.case_list; cp; cp = cp->next)
+ {
+ if (cp->low)
+ {
+ if (cp->low->value.logical == 0) /* .FALSE. */
+ f = c;
+ else /* if (cp->value.logical != 0), thus .TRUE. */
+ t = c;
+ }
+ else
+ d = c;
+ }
+ }
+
+ /* Start a new block. */
+ gfc_start_block (&block);
+
+ /* Calculate the switch expression. We always need to do this
+ because it may have side effects. */
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_val (&se, code->expr);
+ gfc_add_block_to_block (&block, &se.pre);
+
+ if (t == f && t != NULL)
+ {
+ /* Cases for .TRUE. and .FALSE. are in the same block. Just
+ translate the code for these cases, append it to the current
+ block. */
+ gfc_add_expr_to_block (&block, gfc_trans_code (t->next));
+ }
+ else
+ {
+ tree true_tree, false_tree;
+
+ true_tree = build_empty_stmt ();
+ false_tree = build_empty_stmt ();
+
+ /* If we have a case for .TRUE. and for .FALSE., discard the default case.
+ Otherwise, if .TRUE. or .FALSE. is missing and there is a default case,
+ make the missing case the default case. */
+ if (t != NULL && f != NULL)
+ d = NULL;
+ else if (d != NULL)
+ {
+ if (t == NULL)
+ t = d;
+ else
+ f = d;
+ }
+
+ /* Translate the code for each of these blocks, and append it to
+ the current block. */
+ if (t != NULL)
+ true_tree = gfc_trans_code (t->next);
+
+ if (f != NULL)
+ false_tree = gfc_trans_code (f->next);
+
+ gfc_add_expr_to_block (&block, build_v (COND_EXPR, se.expr,
+ true_tree, false_tree));
+ }
+
+ return gfc_finish_block (&block);
+}
+
+
+/* Translate the SELECT CASE construct for CHARACTER case expressions.
+ Instead of generating compares and jumps, it is far simpler to
+ generate a data structure describing the cases in order and call a
+ library subroutine that locates the right case.
+ This is particularly true because this is the only case where we
+ might have to dispose of a temporary.
+ The library subroutine returns a pointer to jump to or NULL if no
+ branches are to be taken. */
+
+static tree
+gfc_trans_character_select (gfc_code *code)
+{
+ tree init, node, end_label, tmp, type, args, *labels;
+ stmtblock_t block, body;
+ gfc_case *cp, *d;
+ gfc_code *c;
+ gfc_se se;
+ int i, n;
+
+ static tree select_struct;
+ static tree ss_string1, ss_string1_len;
+ static tree ss_string2, ss_string2_len;
+ static tree ss_target;
+
+ if (select_struct == NULL)
+ {
+ select_struct = make_node (RECORD_TYPE);
+ TYPE_NAME (select_struct) = get_identifier ("_jump_struct");
+
+#undef ADD_FIELD
+#define ADD_FIELD(NAME, TYPE) \
+ ss_##NAME = gfc_add_field_to_struct \
+ (&(TYPE_FIELDS (select_struct)), select_struct, \
+ get_identifier (stringize(NAME)), TYPE)
+
+ ADD_FIELD (string1, pchar_type_node);
+ ADD_FIELD (string1_len, gfc_int4_type_node);
+
+ ADD_FIELD (string2, pchar_type_node);
+ ADD_FIELD (string2_len, gfc_int4_type_node);
+
+ ADD_FIELD (target, pvoid_type_node);
+#undef ADD_FIELD
+
+ gfc_finish_type (select_struct);
+ }
+
+ cp = code->block->ext.case_list;
+ while (cp->left != NULL)
+ cp = cp->left;
+
+ n = 0;
+ for (d = cp; d; d = d->right)
+ d->n = n++;
+
+ if (n != 0)
+ labels = gfc_getmem (n * sizeof (tree));
+ else
+ labels = NULL;
+
+ for(i = 0; i < n; i++)
+ {
+ labels[i] = gfc_build_label_decl (NULL_TREE);
+ TREE_USED (labels[i]) = 1;
+ /* TODO: The gimplifier should do this for us, but it has
+ inadequacies when dealing with static initializers. */
+ FORCED_LABEL (labels[i]) = 1;
+ }
+
+ end_label = gfc_build_label_decl (NULL_TREE);
+
+ /* Generate the body */
+ gfc_start_block (&block);
+ gfc_init_block (&body);
+
+ for (c = code->block; c; c = c->block)
+ {
+ for (d = c->ext.case_list; d; d = d->next)
+ {
+ tmp = build_v (LABEL_EXPR, labels[d->n]);
+ gfc_add_expr_to_block (&body, tmp);
+ }
+
+ tmp = gfc_trans_code (c->next);
+ gfc_add_expr_to_block (&body, tmp);
+
+ tmp = build_v (GOTO_EXPR, end_label);
+ gfc_add_expr_to_block (&body, tmp);
+ }
+
+ /* Generate the structure describing the branches */
+ init = NULL_TREE;
+ i = 0;
+
+ for(d = cp; d; d = d->right, i++)
+ {
+ node = NULL_TREE;
+
+ gfc_init_se (&se, NULL);
+
+ if (d->low == NULL)
+ {
+ node = tree_cons (ss_string1, null_pointer_node, node);
+ node = tree_cons (ss_string1_len, integer_zero_node, node);
+ }
+ else
+ {
+ gfc_conv_expr_reference (&se, d->low);
+
+ node = tree_cons (ss_string1, se.expr, node);
+ node = tree_cons (ss_string1_len, se.string_length, node);
+ }
+
+ if (d->high == NULL)
+ {
+ node = tree_cons (ss_string2, null_pointer_node, node);
+ node = tree_cons (ss_string2_len, integer_zero_node, node);
+ }
+ else
+ {
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_reference (&se, d->high);
+
+ node = tree_cons (ss_string2, se.expr, node);
+ node = tree_cons (ss_string2_len, se.string_length, node);
+ }
+
+ tmp = gfc_build_addr_expr (pvoid_type_node, labels[i]);
+ node = tree_cons (ss_target, tmp, node);
+
+ tmp = build1 (CONSTRUCTOR, select_struct, nreverse (node));
+ init = tree_cons (NULL_TREE, tmp, init);
+ }
+
+ type = build_array_type (select_struct,
+ build_index_type (build_int_2(n - 1, 0)));
+
+ init = build1 (CONSTRUCTOR, type, nreverse(init));
+ TREE_CONSTANT (init) = 1;
+ TREE_INVARIANT (init) = 1;
+ TREE_STATIC (init) = 1;
+ /* Create a static variable to hold the jump table. */
+ tmp = gfc_create_var (type, "jumptable");
+ TREE_CONSTANT (tmp) = 1;
+ TREE_INVARIANT (tmp) = 1;
+ TREE_STATIC (tmp) = 1;
+ DECL_INITIAL (tmp) = init;
+ init = tmp;
+
+ /* Build an argument list for the library call */
+ init = gfc_build_addr_expr (pvoid_type_node, init);
+ args = gfc_chainon_list (NULL_TREE, init);
+
+ tmp = build_int_2 (n, 0);
+ args = gfc_chainon_list (args, tmp);
+
+ tmp = gfc_build_addr_expr (pvoid_type_node, end_label);
+ args = gfc_chainon_list (args, tmp);
+
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_reference (&se, code->expr);
+
+ args = gfc_chainon_list (args, se.expr);
+ args = gfc_chainon_list (args, se.string_length);
+
+ gfc_add_block_to_block (&block, &se.pre);
+
+ tmp = gfc_build_function_call (gfor_fndecl_select_string, args);
+ tmp = build1 (GOTO_EXPR, void_type_node, tmp);
+ gfc_add_expr_to_block (&block, tmp);
+
+ tmp = gfc_finish_block (&body);
+ gfc_add_expr_to_block (&block, tmp);
+ tmp = build_v (LABEL_EXPR, end_label);
+ gfc_add_expr_to_block (&block, tmp);
+
+ if (n != 0)
+ gfc_free (labels);
+
+ return gfc_finish_block (&block);
+}
+
+
+/* Translate the three variants of the SELECT CASE construct.
+
+ SELECT CASEs with INTEGER case expressions can be translated to an
+ equivalent GENERIC switch statement, and for LOGICAL case
+ expressions we build one or two if-else compares.
+
+ SELECT CASEs with CHARACTER case expressions are a whole different
+ story, because they don't exist in GENERIC. So we sort them and
+ do a binary search at runtime.
+
+ Fortran has no BREAK statement, and it does not allow jumps from
+ one case block to another. That makes things a lot easier for
+ the optimizers. */
+
+tree
+gfc_trans_select (gfc_code * code)
+{
+ assert (code && code->expr);
+
+ /* Empty SELECT constructs are legal. */
+ if (code->block == NULL)
+ return build_empty_stmt ();
+
+ /* Select the correct translation function. */
+ switch (code->expr->ts.type)
+ {
+ case BT_LOGICAL: return gfc_trans_logical_select (code);
+ case BT_INTEGER: return gfc_trans_integer_select (code);
+ case BT_CHARACTER: return gfc_trans_character_select (code);
+ default:
+ gfc_internal_error ("gfc_trans_select(): Bad type for case expr.");
+ /* Not reached */
+ }
+}
+
+
+/* Generate the loops for a FORALL block. The normal loop format:
+ count = (end - start + step) / step
+ loopvar = start
+ while (1)
+ {
+ if (count <=0 )
+ goto end_of_loop
+ <body>
+ loopvar += step
+ count --
+ }
+ end_of_loop: */
+
+static tree
+gfc_trans_forall_loop (forall_info *forall_tmp, int nvar, tree body, int mask_flag)
+{
+ int n;
+ tree tmp;
+ tree cond;
+ stmtblock_t block;
+ tree exit_label;
+ tree count;
+ tree var, start, end, step, mask, maskindex;
+ iter_info *iter;
+
+ iter = forall_tmp->this_loop;
+ for (n = 0; n < nvar; n++)
+ {
+ var = iter->var;
+ start = iter->start;
+ end = iter->end;
+ step = iter->step;
+
+ exit_label = gfc_build_label_decl (NULL_TREE);
+ TREE_USED (exit_label) = 1;
+
+ /* The loop counter. */
+ count = gfc_create_var (TREE_TYPE (var), "count");
+
+ /* The body of the loop. */
+ gfc_init_block (&block);
+
+ /* The exit condition. */
+ cond = build (LE_EXPR, boolean_type_node, count, integer_zero_node);
+ tmp = build1_v (GOTO_EXPR, exit_label);
+ tmp = build_v (COND_EXPR, cond, tmp, build_empty_stmt ());
+ gfc_add_expr_to_block (&block, tmp);
+
+ /* The main loop body. */
+ gfc_add_expr_to_block (&block, body);
+
+ /* Increment the loop variable. */
+ tmp = build (PLUS_EXPR, TREE_TYPE (var), var, step);
+ gfc_add_modify_expr (&block, var, tmp);
+
+ /* Advance to the next mask element. */
+ if (mask_flag)
+ {
+ mask = forall_tmp->mask;
+ maskindex = forall_tmp->maskindex;
+ if (mask)
+ {
+ tmp = build (PLUS_EXPR, gfc_array_index_type, maskindex,
+ integer_one_node);
+ gfc_add_modify_expr (&block, maskindex, tmp);
+ }
+ }
+ /* Decrement the loop counter. */
+ tmp = build (MINUS_EXPR, TREE_TYPE (var), count, integer_one_node);
+ gfc_add_modify_expr (&block, count, tmp);
+
+ body = gfc_finish_block (&block);
+
+ /* Loop var initialization. */
+ gfc_init_block (&block);
+ gfc_add_modify_expr (&block, var, start);
+
+ /* Initialize the loop counter. */
+ tmp = fold (build (MINUS_EXPR, TREE_TYPE (var), step, start));
+ tmp = fold (build (PLUS_EXPR, TREE_TYPE (var), end, tmp));
+ tmp = fold (build (TRUNC_DIV_EXPR, TREE_TYPE (var), tmp, step));
+ gfc_add_modify_expr (&block, count, tmp);
+
+ /* The loop expression. */
+ tmp = build_v (LOOP_EXPR, body);
+ gfc_add_expr_to_block (&block, tmp);
+
+ /* The exit label. */
+ tmp = build1_v (LABEL_EXPR, exit_label);
+ gfc_add_expr_to_block (&block, tmp);
+
+ body = gfc_finish_block (&block);
+ iter = iter->next;
+ }
+ return body;
+}
+
+
+/* Generate the body and loops according to MASK_FLAG and NEST_FLAG.
+ if MASK_FLAG is non-zero, the body is controlled by maskes in forall
+ nest, otherwise, the body is not controlled by maskes.
+ if NEST_FLAG is non-zero, generate loops for nested forall, otherwise,
+ only generate loops for the current forall level. */
+
+static tree
+gfc_trans_nested_forall_loop (forall_info * nested_forall_info, tree body,
+ int mask_flag, int nest_flag)
+{
+ tree tmp;
+ int nvar;
+ forall_info *forall_tmp;
+ tree pmask, mask, maskindex;
+
+ forall_tmp = nested_forall_info;
+ /* Generate loops for nested forall. */
+ if (nest_flag)
+ {
+ while (forall_tmp->next_nest != NULL)
+ forall_tmp = forall_tmp->next_nest;
+ while (forall_tmp != NULL)
+ {
+ /* Generate body with masks' control. */
+ if (mask_flag)
+ {
+ pmask = forall_tmp->pmask;
+ mask = forall_tmp->mask;
+ maskindex = forall_tmp->maskindex;
+
+ if (mask)
+ {
+ /* If a mask was specified make the assignment contitional. */
+ if (pmask)
+ tmp = gfc_build_indirect_ref (mask);
+ else
+ tmp = mask;
+ tmp = gfc_build_array_ref (tmp, maskindex);
+
+ body = build_v (COND_EXPR, tmp, body, build_empty_stmt ());
+ }
+ }
+ nvar = forall_tmp->nvar;
+ body = gfc_trans_forall_loop (forall_tmp, nvar, body, mask_flag);
+ forall_tmp = forall_tmp->outer;
+ }
+ }
+ else
+ {
+ nvar = forall_tmp->nvar;
+ body = gfc_trans_forall_loop (forall_tmp, nvar, body, mask_flag);
+ }
+
+ return body;
+}
+
+
+/* Allocate data for holding a temporary array. Returns either a local
+ temporary array or a pointer variable. */
+
+static tree
+gfc_do_allocate (tree bytesize, tree size, tree * pdata, stmtblock_t * pblock,
+ tree elem_type)
+{
+ tree tmpvar;
+ tree type;
+ tree tmp;
+ tree args;
+
+ if (INTEGER_CST_P (size))
+ {
+ tmp = fold (build (MINUS_EXPR, gfc_array_index_type, size,
+ integer_one_node));
+ }
+ else
+ tmp = NULL_TREE;
+
+ type = build_range_type (gfc_array_index_type, integer_zero_node, tmp);
+ type = build_array_type (elem_type, type);
+ if (gfc_can_put_var_on_stack (bytesize))
+ {
+ assert (INTEGER_CST_P (size));
+ tmpvar = gfc_create_var (type, "temp");
+ *pdata = NULL_TREE;
+ }
+ else
+ {
+ tmpvar = gfc_create_var (build_pointer_type (type), "temp");
+ *pdata = convert (pvoid_type_node, tmpvar);
+
+ args = gfc_chainon_list (NULL_TREE, bytesize);
+ if (gfc_index_integer_kind == 4)
+ tmp = gfor_fndecl_internal_malloc;
+ else if (gfc_index_integer_kind == 8)
+ tmp = gfor_fndecl_internal_malloc64;
+ else
+ abort ();
+ tmp = gfc_build_function_call (tmp, args);
+ tmp = convert (TREE_TYPE (tmpvar), tmp);
+ gfc_add_modify_expr (pblock, tmpvar, tmp);
+ }
+ return tmpvar;
+}
+
+
+/* Generate codes to copy the temporary to the actual lhs. */
+
+static tree
+generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree size,
+ tree count3, tree count1, tree count2, tree wheremask)
+{
+ gfc_ss *lss;
+ gfc_se lse, rse;
+ stmtblock_t block, body;
+ gfc_loopinfo loop1;
+ tree tmp, tmp2;
+ tree index;
+ tree wheremaskexpr;
+
+ /* Walk the lhs. */
+ lss = gfc_walk_expr (expr);
+
+ if (lss == gfc_ss_terminator)
+ {
+ gfc_start_block (&block);
+
+ gfc_init_se (&lse, NULL);
+
+ /* Translate the expression. */
+ gfc_conv_expr (&lse, expr);
+
+ /* Form the expression for the temporary. */
+ tmp = gfc_build_array_ref (tmp1, count1);
+
+ /* Use the scalar assignment as is. */
+ gfc_add_block_to_block (&block, &lse.pre);
+ gfc_add_modify_expr (&block, lse.expr, tmp);
+ gfc_add_block_to_block (&block, &lse.post);
+
+ /* Increment the count1. */
+ tmp = fold (build (PLUS_EXPR, TREE_TYPE (count1), count1, size));
+ gfc_add_modify_expr (&block, count1, tmp);
+ tmp = gfc_finish_block (&block);
+ }
+ else
+ {
+ gfc_start_block (&block);
+
+ gfc_init_loopinfo (&loop1);
+ gfc_init_se (&rse, NULL);
+ gfc_init_se (&lse, NULL);
+
+ /* Associate the lss with the loop. */
+ gfc_add_ss_to_loop (&loop1, lss);
+
+ /* Calculate the bounds of the scalarization. */
+ gfc_conv_ss_startstride (&loop1);
+ /* Setup the scalarizing loops. */
+ gfc_conv_loop_setup (&loop1);
+
+ gfc_mark_ss_chain_used (lss, 1);
+ /* Initialize count2. */
+ gfc_add_modify_expr (&block, count2, integer_zero_node);
+
+ /* Start the scalarized loop body. */
+ gfc_start_scalarized_body (&loop1, &body);
+
+ /* Setup the gfc_se structures. */
+ gfc_copy_loopinfo_to_se (&lse, &loop1);
+ lse.ss = lss;
+
+ /* Form the expression of the temporary. */
+ if (lss != gfc_ss_terminator)
+ {
+ index = fold (build (PLUS_EXPR, gfc_array_index_type,
+ count1, count2));
+ rse.expr = gfc_build_array_ref (tmp1, index);
+ }
+ /* Translate expr. */
+ gfc_conv_expr (&lse, expr);
+
+ /* Use the scalar assignment. */
+ tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts.type);
+
+ /* Form the mask expression according to the mask tree list. */
+ if (wheremask)
+ {
+ tmp2 = wheremask;
+ if (tmp2 != NULL)
+ wheremaskexpr = gfc_build_array_ref (tmp2, count3);
+ tmp2 = TREE_CHAIN (tmp2);
+ while (tmp2)
+ {
+ tmp1 = gfc_build_array_ref (tmp2, count3);
+ wheremaskexpr = build (TRUTH_AND_EXPR, TREE_TYPE (tmp1),
+ wheremaskexpr, tmp1);
+ tmp2 = TREE_CHAIN (tmp2);
+ }
+ tmp = build_v (COND_EXPR, wheremaskexpr, tmp, build_empty_stmt ());
+ }
+
+ gfc_add_expr_to_block (&body, tmp);
+
+ /* Increment count2. */
+ tmp = fold (build (PLUS_EXPR, TREE_TYPE (count2), count2,
+ integer_one_node));
+ gfc_add_modify_expr (&body, count2, tmp);
+
+ /* Increment count3. */
+ if (count3)
+ {
+ tmp = fold (build (PLUS_EXPR, TREE_TYPE (count3), count3,
+ integer_one_node));
+ gfc_add_modify_expr (&body, count3, tmp);
+ }
+
+ /* Generate the copying loops. */
+ gfc_trans_scalarizing_loops (&loop1, &body);
+ gfc_add_block_to_block (&block, &loop1.pre);
+ gfc_add_block_to_block (&block, &loop1.post);
+ gfc_cleanup_loop (&loop1);
+
+ /* Increment count1. */
+ tmp = fold (build (PLUS_EXPR, TREE_TYPE (count1), count1, size));
+ gfc_add_modify_expr (&block, count1, tmp);
+ tmp = gfc_finish_block (&block);
+ }
+ return tmp;
+}
+
+
+/* Generate codes to copy rhs to the temporary. TMP1 is the address of temporary
+ LSS and RSS are formed in function compute_inner_temp_size(), and should
+ not be freed. */
+
+static tree
+generate_loop_for_rhs_to_temp (gfc_expr *expr2, tree tmp1, tree size,
+ tree count3, tree count1, tree count2,
+ gfc_ss *lss, gfc_ss *rss, tree wheremask)
+{
+ stmtblock_t block, body1;
+ gfc_loopinfo loop;
+ gfc_se lse;
+ gfc_se rse;
+ tree tmp, tmp2, index;
+ tree wheremaskexpr;
+
+ gfc_start_block (&block);
+
+ gfc_init_se (&rse, NULL);
+ gfc_init_se (&lse, NULL);
+
+ if (lss == gfc_ss_terminator)
+ {
+ gfc_init_block (&body1);
+ gfc_conv_expr (&rse, expr2);
+ lse.expr = gfc_build_array_ref (tmp1, count1);
+ }
+ else
+ {
+ /* Initilize count2. */
+ gfc_add_modify_expr (&block, count2, integer_zero_node);
+
+ /* Initiliaze the loop. */
+ gfc_init_loopinfo (&loop);
+
+ /* We may need LSS to determine the shape of the expression. */
+ gfc_add_ss_to_loop (&loop, lss);
+ gfc_add_ss_to_loop (&loop, rss);
+
+ gfc_conv_ss_startstride (&loop);
+ gfc_conv_loop_setup (&loop);
+
+ gfc_mark_ss_chain_used (rss, 1);
+ /* Start the loop body. */
+ gfc_start_scalarized_body (&loop, &body1);
+
+ /* Translate the expression. */
+ gfc_copy_loopinfo_to_se (&rse, &loop);
+ rse.ss = rss;
+ gfc_conv_expr (&rse, expr2);
+
+ /* Form the expression of the temporary. */
+ index = fold (build (PLUS_EXPR, gfc_array_index_type, count1, count2));
+ lse.expr = gfc_build_array_ref (tmp1, index);
+ }
+
+ /* Use the scalar assignment. */
+ tmp = gfc_trans_scalar_assign (&lse, &rse, expr2->ts.type);
+
+ /* Form the mask expression according to the mask tree list. */
+ if (wheremask)
+ {
+ tmp2 = wheremask;
+ if (tmp2 != NULL)
+ wheremaskexpr = gfc_build_array_ref (tmp2, count3);
+ tmp2 = TREE_CHAIN (tmp2);
+ while (tmp2)
+ {
+ tmp1 = gfc_build_array_ref (tmp2, count3);
+ wheremaskexpr = build (TRUTH_AND_EXPR, TREE_TYPE (tmp1),
+ wheremaskexpr, tmp1);
+ tmp2 = TREE_CHAIN (tmp2);
+ }
+ tmp = build_v (COND_EXPR, wheremaskexpr, tmp, build_empty_stmt ());
+ }
+
+ gfc_add_expr_to_block (&body1, tmp);
+
+ if (lss == gfc_ss_terminator)
+ {
+ gfc_add_block_to_block (&block, &body1);
+ }
+ else
+ {
+ /* Increment count2. */
+ tmp = fold (build (PLUS_EXPR, gfc_array_index_type, count2,
+ integer_one_node));
+ gfc_add_modify_expr (&body1, count2, tmp);
+
+ /* Increment count3. */
+ if (count3)
+ {
+ tmp = fold (build (PLUS_EXPR, gfc_array_index_type, count3,
+ integer_one_node));
+ gfc_add_modify_expr (&body1, count3, tmp);
+ }
+
+ /* Generate the copying loops. */
+ gfc_trans_scalarizing_loops (&loop, &body1);
+
+ gfc_add_block_to_block (&block, &loop.pre);
+ gfc_add_block_to_block (&block, &loop.post);
+
+ gfc_cleanup_loop (&loop);
+ /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
+ as tree nodes in SS may not be valid in different scope. */
+ }
+ /* Increment count1. */
+ tmp = fold (build (PLUS_EXPR, TREE_TYPE (count1), count1, size));
+ gfc_add_modify_expr (&block, count1, tmp);
+
+ tmp = gfc_finish_block (&block);
+ return tmp;
+}
+
+
+/* Calculate the size of temporary needed in the assignment inside forall.
+ LSS and RSS are filled in this function. */
+
+static tree
+compute_inner_temp_size (gfc_expr *expr1, gfc_expr *expr2,
+ stmtblock_t * pblock,
+ gfc_ss **lss, gfc_ss **rss)
+{
+ gfc_loopinfo loop;
+ tree size;
+ int i;
+ tree tmp;
+
+ *lss = gfc_walk_expr (expr1);
+ *rss = NULL;
+
+ size = integer_one_node;
+ if (*lss != gfc_ss_terminator)
+ {
+ gfc_init_loopinfo (&loop);
+
+ /* Walk the RHS of the expression. */
+ *rss = gfc_walk_expr (expr2);
+ if (*rss == gfc_ss_terminator)
+ {
+ /* The rhs is scalar. Add a ss for the expression. */
+ *rss = gfc_get_ss ();
+ (*rss)->next = gfc_ss_terminator;
+ (*rss)->type = GFC_SS_SCALAR;
+ (*rss)->expr = expr2;
+ }
+
+ /* Associate the SS with the loop. */
+ gfc_add_ss_to_loop (&loop, *lss);
+ /* We don't actually need to add the rhs at this point, but it might
+ make guessing the loop bounds a bit easier. */
+ gfc_add_ss_to_loop (&loop, *rss);
+
+ /* We only want the shape of the expression, not rest of the junk
+ generated by the scalarizer. */
+ loop.array_parameter = 1;
+
+ /* Calculate the bounds of the scalarization. */
+ gfc_conv_ss_startstride (&loop);
+ gfc_conv_loop_setup (&loop);
+
+ /* Figure out how many elements we need. */
+ for (i = 0; i < loop.dimen; i++)
+ {
+ tmp = fold (build (MINUS_EXPR, TREE_TYPE (loop.from[i]),
+ integer_one_node, loop.from[i]));
+ tmp = fold (build (PLUS_EXPR, TREE_TYPE (tmp), tmp, loop.to[i]));
+ size = fold (build (MULT_EXPR, TREE_TYPE (size), size, tmp));
+ }
+ gfc_add_block_to_block (pblock, &loop.pre);
+ size = gfc_evaluate_now (size, pblock);
+ gfc_add_block_to_block (pblock, &loop.post);
+
+ /* TODO: write a function that cleans up a loopinfo without freeing
+ the SS chains. Currently a NOP. */
+ }
+
+ return size;
+}
+
+
+/* Calculate the overall iterator number of the nested forall construct. */
+
+static tree
+compute_overall_iter_number (forall_info *nested_forall_info, tree inner_size,
+ stmtblock_t *block)
+{
+ tree tmp, number;
+ stmtblock_t body;
+
+ /* TODO: optimizing the computing process. */
+ number = gfc_create_var (gfc_array_index_type, "num");
+ gfc_add_modify_expr (block, number, integer_zero_node);
+
+ gfc_start_block (&body);
+ if (nested_forall_info)
+ tmp = build (PLUS_EXPR, gfc_array_index_type, number,
+ inner_size);
+ else
+ tmp = inner_size;
+ gfc_add_modify_expr (&body, number, tmp);
+ tmp = gfc_finish_block (&body);
+
+ /* Generate loops. */
+ if (nested_forall_info != NULL)
+ tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 0, 1);
+
+ gfc_add_expr_to_block (block, tmp);
+
+ return number;
+}
+
+
+/* Allocate temporary for forall construct according to the information in
+ nested_forall_info. INNER_SIZE is the size of temporary needed in the
+ assignment inside forall. PTEMP1 is returned for space free. */
+
+static tree
+allocate_temp_for_forall_nest (forall_info * nested_forall_info, tree type,
+ tree inner_size, stmtblock_t * block,
+ tree * ptemp1)
+{
+ tree unit;
+ tree temp1;
+ tree tmp;
+ tree bytesize, size;
+
+ /* Calculate the total size of temporary needed in forall construct. */
+ size = compute_overall_iter_number (nested_forall_info, inner_size, block);
+
+ unit = TYPE_SIZE_UNIT (type);
+ bytesize = fold (build (MULT_EXPR, gfc_array_index_type, size, unit));
+
+ *ptemp1 = NULL;
+ temp1 = gfc_do_allocate (bytesize, size, ptemp1, block, type);
+
+ if (*ptemp1)
+ tmp = gfc_build_indirect_ref (temp1);
+ else
+ tmp = temp1;
+
+ return tmp;
+}
+
+
+/* Handle assignments inside forall which need temporary. */
+static void
+gfc_trans_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2, tree wheremask,
+ forall_info * nested_forall_info,
+ stmtblock_t * block)
+{
+ tree type;
+ tree inner_size;
+ gfc_ss *lss, *rss;
+ tree count, count1, count2;
+ tree tmp, tmp1;
+ tree ptemp1;
+ tree mask, maskindex;
+ forall_info *forall_tmp;
+
+ /* Create vars. count1 is the current iterator number of the nested forall.
+ count2 is the current iterator number of the inner loops needed in the
+ assignment. */
+ count1 = gfc_create_var (gfc_array_index_type, "count1");
+ count2 = gfc_create_var (gfc_array_index_type, "count2");
+
+ /* Count is the wheremask index. */
+ if (wheremask)
+ {
+ count = gfc_create_var (gfc_array_index_type, "count");
+ gfc_add_modify_expr (block, count, integer_zero_node);
+ }
+ else
+ count = NULL;
+
+ /* Initialize count1. */
+ gfc_add_modify_expr (block, count1, integer_zero_node);
+
+ /* Calculate the size of temporary needed in the assignment. Return loop, lss
+ and rss which are used in function generate_loop_for_rhs_to_temp(). */
+ inner_size = compute_inner_temp_size (expr1, expr2, block, &lss, &rss);
+
+ /* The type of LHS. Used in function allocate_temp_for_forall_nest */
+ type = gfc_typenode_for_spec (&expr1->ts);
+
+ /* Allocate temporary for nested forall construct according to the
+ information in nested_forall_info and inner_size. */
+ tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type,
+ inner_size, block, &ptemp1);
+
+ /* Initialize the maskindexes. */
+ forall_tmp = nested_forall_info;
+ while (forall_tmp != NULL)
+ {
+ mask = forall_tmp->mask;
+ maskindex = forall_tmp->maskindex;
+ if (mask)
+ gfc_add_modify_expr (block, maskindex, integer_zero_node);
+ forall_tmp = forall_tmp->next_nest;
+ }
+
+ /* Generate codes to copy rhs to the temporary . */
+ tmp = generate_loop_for_rhs_to_temp (expr2, tmp1, inner_size, count,
+ count1, count2, lss, rss, wheremask);
+
+ /* Generate body and loops according to the inforamtion in
+ nested_forall_info. */
+ tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
+ gfc_add_expr_to_block (block, tmp);
+
+ /* Reset count1. */
+ gfc_add_modify_expr (block, count1, integer_zero_node);
+
+ /* Reset maskindexed. */
+ forall_tmp = nested_forall_info;
+ while (forall_tmp != NULL)
+ {
+ mask = forall_tmp->mask;
+ maskindex = forall_tmp->maskindex;
+ if (mask)
+ gfc_add_modify_expr (block, maskindex, integer_zero_node);
+ forall_tmp = forall_tmp->next_nest;
+ }
+
+ /* Reset count. */
+ if (wheremask)
+ gfc_add_modify_expr (block, count, integer_zero_node);
+
+ /* Generate codes to copy the temporary to lhs. */
+ tmp = generate_loop_for_temp_to_lhs (expr1, tmp1, inner_size, count,
+ count1, count2, wheremask);
+
+ /* Generate body and loops according to the inforamtion in
+ nested_forall_info. */
+ tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
+ gfc_add_expr_to_block (block, tmp);
+
+ if (ptemp1)
+ {
+ /* Free the temporary. */
+ tmp = gfc_chainon_list (NULL_TREE, ptemp1);
+ tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
+ gfc_add_expr_to_block (block, tmp);
+ }
+}
+
+
+/* Translate pointer assignment inside FORALL which need temporary. */
+
+static void
+gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
+ forall_info * nested_forall_info,
+ stmtblock_t * block)
+{
+ tree type;
+ tree inner_size;
+ gfc_ss *lss, *rss;
+ gfc_se lse;
+ gfc_se rse;
+ gfc_ss_info *info;
+ gfc_loopinfo loop;
+ tree desc;
+ tree parm;
+ tree parmtype;
+ stmtblock_t body;
+ tree count;
+ tree tmp, tmp1, ptemp1;
+ tree mask, maskindex;
+ forall_info *forall_tmp;
+
+ count = gfc_create_var (gfc_array_index_type, "count");
+ gfc_add_modify_expr (block, count, integer_zero_node);
+
+ inner_size = integer_one_node;
+ lss = gfc_walk_expr (expr1);
+ rss = gfc_walk_expr (expr2);
+ if (lss == gfc_ss_terminator)
+ {
+ type = gfc_typenode_for_spec (&expr1->ts);
+ type = build_pointer_type (type);
+
+ /* Allocate temporary for nested forall construct according to the
+ information in nested_forall_info and inner_size. */
+ tmp1 = allocate_temp_for_forall_nest (nested_forall_info,
+ type, inner_size, block, &ptemp1);
+ gfc_start_block (&body);
+ gfc_init_se (&lse, NULL);
+ lse.expr = gfc_build_array_ref (tmp1, count);
+ gfc_init_se (&rse, NULL);
+ rse.want_pointer = 1;
+ gfc_conv_expr (&rse, expr2);
+ gfc_add_block_to_block (&body, &rse.pre);
+ gfc_add_modify_expr (&body, lse.expr, rse.expr);
+ gfc_add_block_to_block (&body, &rse.post);
+
+ /* Increment count. */
+ tmp = fold (build (PLUS_EXPR, TREE_TYPE (count), count,
+ integer_one_node));
+ gfc_add_modify_expr (&body, count, tmp);
+
+ tmp = gfc_finish_block (&body);
+
+ /* Initialize the maskindexes. */
+ forall_tmp = nested_forall_info;
+ while (forall_tmp != NULL)
+ {
+ mask = forall_tmp->mask;
+ maskindex = forall_tmp->maskindex;
+ if (mask)
+ gfc_add_modify_expr (block, maskindex, integer_zero_node);
+ forall_tmp = forall_tmp->next_nest;
+ }
+
+ /* Generate body and loops according to the inforamtion in
+ nested_forall_info. */
+ tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
+ gfc_add_expr_to_block (block, tmp);
+
+ /* Reset count. */
+ gfc_add_modify_expr (block, count, integer_zero_node);
+
+ /* Reset maskindexes. */
+ forall_tmp = nested_forall_info;
+ while (forall_tmp != NULL)
+ {
+ mask = forall_tmp->mask;
+ maskindex = forall_tmp->maskindex;
+ if (mask)
+ gfc_add_modify_expr (block, maskindex, integer_zero_node);
+ forall_tmp = forall_tmp->next_nest;
+ }
+ gfc_start_block (&body);
+ gfc_init_se (&lse, NULL);
+ gfc_init_se (&rse, NULL);
+ rse.expr = gfc_build_array_ref (tmp1, count);
+ lse.want_pointer = 1;
+ gfc_conv_expr (&lse, expr1);
+ gfc_add_block_to_block (&body, &lse.pre);
+ gfc_add_modify_expr (&body, lse.expr, rse.expr);
+ gfc_add_block_to_block (&body, &lse.post);
+ /* Increment count. */
+ tmp = fold (build (PLUS_EXPR, TREE_TYPE (count), count,
+ integer_one_node));
+ gfc_add_modify_expr (&body, count, tmp);
+ tmp = gfc_finish_block (&body);
+
+ /* Generate body and loops according to the inforamtion in
+ nested_forall_info. */
+ tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
+ gfc_add_expr_to_block (block, tmp);
+ }
+ else
+ {
+ gfc_init_loopinfo (&loop);
+
+ /* Associate the SS with the loop. */
+ gfc_add_ss_to_loop (&loop, rss);
+
+ /* Setup the scalarizing loops and bounds. */
+ gfc_conv_ss_startstride (&loop);
+
+ gfc_conv_loop_setup (&loop);
+
+ info = &rss->data.info;
+ desc = info->descriptor;
+
+ /* Make a new descriptor. */
+ parmtype = gfc_get_element_type (TREE_TYPE (desc));
+ parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen,
+ loop.from, loop.to, 1);
+
+ /* Allocate temporary for nested forall construct. */
+ tmp1 = allocate_temp_for_forall_nest (nested_forall_info, parmtype,
+ inner_size, block, &ptemp1);
+ gfc_start_block (&body);
+ gfc_init_se (&lse, NULL);
+ lse.expr = gfc_build_array_ref (tmp1, count);
+ lse.direct_byref = 1;
+ rss = gfc_walk_expr (expr2);
+ gfc_conv_expr_descriptor (&lse, expr2, rss);
+
+ gfc_add_block_to_block (&body, &lse.pre);
+ gfc_add_block_to_block (&body, &lse.post);
+
+ /* Increment count. */
+ tmp = fold (build (PLUS_EXPR, TREE_TYPE (count), count,
+ integer_one_node));
+ gfc_add_modify_expr (&body, count, tmp);
+
+ tmp = gfc_finish_block (&body);
+
+ /* Initialize the maskindexes. */
+ forall_tmp = nested_forall_info;
+ while (forall_tmp != NULL)
+ {
+ mask = forall_tmp->mask;
+ maskindex = forall_tmp->maskindex;
+ if (mask)
+ gfc_add_modify_expr (block, maskindex, integer_zero_node);
+ forall_tmp = forall_tmp->next_nest;
+ }
+
+ /* Generate body and loops according to the inforamtion in
+ nested_forall_info. */
+ tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
+ gfc_add_expr_to_block (block, tmp);
+
+ /* Reset count. */
+ gfc_add_modify_expr (block, count, integer_zero_node);
+
+ /* Reset maskindexes. */
+ forall_tmp = nested_forall_info;
+ while (forall_tmp != NULL)
+ {
+ mask = forall_tmp->mask;
+ maskindex = forall_tmp->maskindex;
+ if (mask)
+ gfc_add_modify_expr (block, maskindex, integer_zero_node);
+ forall_tmp = forall_tmp->next_nest;
+ }
+ parm = gfc_build_array_ref (tmp1, count);
+ lss = gfc_walk_expr (expr1);
+ gfc_init_se (&lse, NULL);
+ gfc_conv_expr_descriptor (&lse, expr1, lss);
+ gfc_add_modify_expr (&lse.pre, lse.expr, parm);
+ gfc_start_block (&body);
+ gfc_add_block_to_block (&body, &lse.pre);
+ gfc_add_block_to_block (&body, &lse.post);
+
+ /* Increment count. */
+ tmp = fold (build (PLUS_EXPR, TREE_TYPE (count), count,
+ integer_one_node));
+ gfc_add_modify_expr (&body, count, tmp);
+
+ tmp = gfc_finish_block (&body);
+
+ tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
+ gfc_add_expr_to_block (block, tmp);
+ }
+ /* Free the temporary. */
+ if (ptemp1)
+ {
+ tmp = gfc_chainon_list (NULL_TREE, ptemp1);
+ tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
+ gfc_add_expr_to_block (block, tmp);
+ }
+}
+
+
+/* FORALL and WHERE statements are really nasty, especially when you nest
+ them. All the rhs of a forall assignment must be evaluated before the
+ actual assignments are performed. Presumably this also applies to all the
+ assignments in an inner where statement. */
+
+/* Generate code for a FORALL statement. Any temporaries are allocated as a
+ linear array, relying on the fact that we process in the same order in all
+ loops.
+
+ forall (i=start:end:stride; maskexpr)
+ e<i> = f<i>
+ g<i> = h<i>
+ end forall
+ (where e,f,g,h<i> are arbitary expressions possibly involving i)
+ Translates to:
+ count = ((end + 1 - start) / staride)
+ masktmp(:) = maskexpr(:)
+
+ maskindex = 0;
+ for (i = start; i <= end; i += stride)
+ {
+ if (masktmp[maskindex++])
+ e<i> = f<i>
+ }
+ maskindex = 0;
+ for (i = start; i <= end; i += stride)
+ {
+ if (masktmp[maskindex++])
+ e<i> = f<i>
+ }
+
+ Note that this code only works when there are no dependencies.
+ Forall loop with array assignments and data dependencies are a real pain,
+ because the size of the temporary cannot always be determined before the
+ loop is executed. This problem is compouded by the presence of nested
+ FORALL constructs.
+ */
+
+static tree
+gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
+{
+ stmtblock_t block;
+ stmtblock_t body;
+ tree *var;
+ tree *start;
+ tree *end;
+ tree *step;
+ gfc_expr **varexpr;
+ tree tmp;
+ tree assign;
+ tree size;
+ tree bytesize;
+ tree tmpvar;
+ tree sizevar;
+ tree lenvar;
+ tree maskindex;
+ tree mask;
+ tree pmask;
+ int n;
+ int nvar;
+ int need_temp;
+ gfc_forall_iterator *fa;
+ gfc_se se;
+ gfc_code *c;
+ tree *saved_var_decl;
+ symbol_attribute *saved_var_attr;
+ iter_info *this_forall, *iter_tmp;
+ forall_info *info, *forall_tmp;
+ temporary_list *temp;
+
+ gfc_start_block (&block);
+
+ n = 0;
+ /* Count the FORALL index number. */
+ for (fa = code->ext.forall_iterator; fa; fa = fa->next)
+ n++;
+ nvar = n;
+
+ /* Allocate the space for var, start, end, step, varexpr. */
+ var = (tree *) gfc_getmem (nvar * sizeof (tree));
+ start = (tree *) gfc_getmem (nvar * sizeof (tree));
+ end = (tree *) gfc_getmem (nvar * sizeof (tree));
+ step = (tree *) gfc_getmem (nvar * sizeof (tree));
+ varexpr = (gfc_expr **) gfc_getmem (nvar * sizeof (gfc_expr *));
+ saved_var_decl = (tree *) gfc_getmem (nvar * sizeof (tree));
+ saved_var_attr = (symbol_attribute *)
+ gfc_getmem (nvar * sizeof (symbol_attribute));
+
+ /* Allocate the space for info. */
+ info = (forall_info *) gfc_getmem (sizeof (forall_info));
+ n = 0;
+ for (fa = code->ext.forall_iterator; fa; fa = fa->next)
+ {
+ gfc_symbol *sym = fa->var->symtree->n.sym;
+
+ /* allocate space for this_forall. */
+ this_forall = (iter_info *) gfc_getmem (sizeof (iter_info));
+
+ /* Save the FORALL index's backend_decl. */
+ saved_var_decl[n] = sym->backend_decl;
+
+ /* Save the attribute. */
+ saved_var_attr[n] = sym->attr;
+
+ /* Set the proper attributes. */
+ gfc_clear_attr (&sym->attr);
+ sym->attr.referenced = 1;
+ sym->attr.flavor = FL_VARIABLE;
+
+ /* Create a temporary variable for the FORALL index. */
+ tmp = gfc_typenode_for_spec (&sym->ts);
+ var[n] = gfc_create_var (tmp, sym->name);
+ /* Record it in this_forall. */
+ this_forall->var = var[n];
+
+ /* Replace the index symbol's backend_decl with the temporary decl. */
+ sym->backend_decl = var[n];
+
+ /* Work out the start, end and stride for the loop. */
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_val (&se, fa->start);
+ /* Record it in this_forall. */
+ this_forall->start = se.expr;
+ gfc_add_block_to_block (&block, &se.pre);
+ start[n] = se.expr;
+
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_val (&se, fa->end);
+ /* Record it in this_forall. */
+ this_forall->end = se.expr;
+ gfc_make_safe_expr (&se);
+ gfc_add_block_to_block (&block, &se.pre);
+ end[n] = se.expr;
+
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_val (&se, fa->stride);
+ /* Record it in this_forall. */
+ this_forall->step = se.expr;
+ gfc_make_safe_expr (&se);
+ gfc_add_block_to_block (&block, &se.pre);
+ step[n] = se.expr;
+
+ /* Set the NEXT field of this_forall to NULL. */
+ this_forall->next = NULL;
+ /* Link this_forall to the info construct. */
+ if (info->this_loop == NULL)
+ info->this_loop = this_forall;
+ else
+ {
+ iter_tmp = info->this_loop;
+ while (iter_tmp->next != NULL)
+ iter_tmp = iter_tmp->next;
+ iter_tmp->next = this_forall;
+ }
+
+ n++;
+ }
+ nvar = n;
+
+ /* Work out the number of elements in the mask array. */
+ tmpvar = NULL_TREE;
+ lenvar = NULL_TREE;
+ size = integer_one_node;
+ sizevar = NULL_TREE;
+
+ for (n = 0; n < nvar; n++)
+ {
+ if (lenvar && TREE_TYPE (lenvar) != TREE_TYPE (start[n]))
+ lenvar = NULL_TREE;
+
+ /* size = (end + step - start) / step. */
+ tmp = fold (build (MINUS_EXPR, TREE_TYPE (start[n]), step[n], start[n]));
+ tmp = fold (build (PLUS_EXPR, TREE_TYPE (end[n]), end[n], tmp));
+
+ tmp = fold (build (FLOOR_DIV_EXPR, TREE_TYPE (tmp), tmp, step[n]));
+ tmp = convert (gfc_array_index_type, tmp);
+
+ size = fold (build (MULT_EXPR, gfc_array_index_type, size, tmp));
+ }
+
+ /* Record the nvar and size of current forall level. */
+ info->nvar = nvar;
+ info->size = size;
+
+ /* Link the current forall level to nested_forall_info. */
+ forall_tmp = nested_forall_info;
+ if (forall_tmp == NULL)
+ nested_forall_info = info;
+ else
+ {
+ while (forall_tmp->next_nest != NULL)
+ forall_tmp = forall_tmp->next_nest;
+ info->outer = forall_tmp;
+ forall_tmp->next_nest = info;
+ }
+
+ /* Copy the mask into a temporary variable if required.
+ For now we assume a mask temporary is needed. */
+ if (code->expr)
+ {
+ /* Allocate the mask temporary. */
+ bytesize = fold (build (MULT_EXPR, gfc_array_index_type, size,
+ TYPE_SIZE_UNIT (boolean_type_node)));
+
+ mask = gfc_do_allocate (bytesize, size, &pmask, &block, boolean_type_node);
+
+ maskindex = gfc_create_var_np (gfc_array_index_type, "mi");
+ /* Record them in the info structure. */
+ info->pmask = pmask;
+ info->mask = mask;
+ info->maskindex = maskindex;
+
+ gfc_add_modify_expr (&block, maskindex, integer_zero_node);
+
+ /* Start of mask assignment loop body. */
+ gfc_start_block (&body);
+
+ /* Evaluate the mask expression. */
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_val (&se, code->expr);
+ gfc_add_block_to_block (&body, &se.pre);
+
+ /* Store the mask. */
+ se.expr = convert (boolean_type_node, se.expr);
+
+ if (pmask)
+ tmp = gfc_build_indirect_ref (mask);
+ else
+ tmp = mask;
+ tmp = gfc_build_array_ref (tmp, maskindex);
+ gfc_add_modify_expr (&body, tmp, se.expr);
+
+ /* Advance to the next mask element. */
+ tmp = build (PLUS_EXPR, gfc_array_index_type, maskindex,
+ integer_one_node);
+ gfc_add_modify_expr (&body, maskindex, tmp);
+
+ /* Generate the loops. */
+ tmp = gfc_finish_block (&body);
+ tmp = gfc_trans_nested_forall_loop (info, tmp, 0, 0);
+ gfc_add_expr_to_block (&block, tmp);
+ }
+ else
+ {
+ /* No mask was specified. */
+ maskindex = NULL_TREE;
+ mask = pmask = NULL_TREE;
+ }
+
+ c = code->block->next;
+
+ /* TODO: loop merging in FORALL statements. */
+ /* Now that we've got a copy of the mask, generate the assignment loops. */
+ while (c)
+ {
+ switch (c->op)
+ {
+ case EXEC_ASSIGN:
+ /* A scalar or array assingment. */
+ need_temp = gfc_check_dependency (c->expr, c->expr2, varexpr, nvar);
+ /* Teporaries due to array assignment data dependencies introduce
+ no end of problems. */
+ if (need_temp)
+ gfc_trans_assign_need_temp (c->expr, c->expr2, NULL,
+ nested_forall_info, &block);
+ else
+ {
+ /* Use the normal assignment copying routines. */
+ assign = gfc_trans_assignment (c->expr, c->expr2);
+
+ /* Reset the mask index. */
+ if (mask)
+ gfc_add_modify_expr (&block, maskindex, integer_zero_node);
+
+ /* Generate body and loops. */
+ tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign, 1, 1);
+ gfc_add_expr_to_block (&block, tmp);
+ }
+
+ break;
+
+ case EXEC_WHERE:
+
+ /* Translate WHERE or WHERE construct nested in FORALL. */
+ temp = NULL;
+ gfc_trans_where_2 (c, NULL, NULL, nested_forall_info, &block, &temp);
+
+ while (temp)
+ {
+ tree args;
+ temporary_list *p;
+
+ /* Free the temporary. */
+ args = gfc_chainon_list (NULL_TREE, temp->temporary);
+ tmp = gfc_build_function_call (gfor_fndecl_internal_free, args);
+ gfc_add_expr_to_block (&block, tmp);
+
+ p = temp;
+ temp = temp->next;
+ gfc_free (p);
+ }
+
+ break;
+
+ /* Pointer assignment inside FORALL. */
+ case EXEC_POINTER_ASSIGN:
+ need_temp = gfc_check_dependency (c->expr, c->expr2, varexpr, nvar);
+ if (need_temp)
+ gfc_trans_pointer_assign_need_temp (c->expr, c->expr2,
+ nested_forall_info, &block);
+ else
+ {
+ /* Use the normal assignment copying routines. */
+ assign = gfc_trans_pointer_assignment (c->expr, c->expr2);
+
+ /* Reset the mask index. */
+ if (mask)
+ gfc_add_modify_expr (&block, maskindex, integer_zero_node);
+
+ /* Generate body and loops. */
+ tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign,
+ 1, 1);
+ gfc_add_expr_to_block (&block, tmp);
+ }
+ break;
+
+ case EXEC_FORALL:
+ tmp = gfc_trans_forall_1 (c, nested_forall_info);
+ gfc_add_expr_to_block (&block, tmp);
+ break;
+
+ default:
+ abort ();
+ break;
+ }
+
+ c = c->next;
+ }
+
+ /* Restore the index original backend_decl and the attribute. */
+ for (fa = code->ext.forall_iterator, n=0; fa; fa = fa->next, n++)
+ {
+ gfc_symbol *sym = fa->var->symtree->n.sym;
+ sym->backend_decl = saved_var_decl[n];
+ sym->attr = saved_var_attr[n];
+ }
+
+ /* Free the space for var, start, end, step, varexpr. */
+ gfc_free (var);
+ gfc_free (start);
+ gfc_free (end);
+ gfc_free (step);
+ gfc_free (varexpr);
+ gfc_free (saved_var_decl);
+ gfc_free (saved_var_attr);
+
+ if (pmask)
+ {
+ /* Free the temporary for the mask. */
+ tmp = gfc_chainon_list (NULL_TREE, pmask);
+ tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
+ gfc_add_expr_to_block (&block, tmp);
+ }
+ if (maskindex)
+ pushdecl (maskindex);
+
+ return gfc_finish_block (&block);
+}
+
+
+/* Translate the FORALL statement or construct. */
+
+tree gfc_trans_forall (gfc_code * code)
+{
+ return gfc_trans_forall_1 (code, NULL);
+}
+
+
+/* Evaluate the WHERE mask expression, copy its value to a temporary.
+ If the WHERE construct is nested in FORALL, compute the overall temporary
+ needed by the WHERE mask expression multiplied by the iterator number of
+ the nested forall.
+ ME is the WHERE mask expression.
+ MASK is the temporary which value is mask's value.
+ NMASK is another temporary which value is !mask.
+ TEMP records the temporary's address allocated in this function in order to
+ free them outside this function.
+ MASK, NMASK and TEMP are all OUT arguments. */
+
+static tree
+gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
+ tree * mask, tree * nmask, temporary_list ** temp,
+ stmtblock_t * block)
+{
+ tree tmp, tmp1;
+ gfc_ss *lss, *rss;
+ gfc_loopinfo loop;
+ tree ptemp1, ntmp, ptemp2;
+ tree inner_size;
+ stmtblock_t body, body1;
+ gfc_se lse, rse;
+ tree count;
+ tree tmpexpr;
+
+ gfc_init_loopinfo (&loop);
+
+ /* Calculate the size of temporary needed by the mask-expr. */
+ inner_size = compute_inner_temp_size (me, me, block, &lss, &rss);
+
+ /* Allocate temporary for where mask. */
+ tmp = allocate_temp_for_forall_nest (nested_forall_info, boolean_type_node,
+ inner_size, block, &ptemp1);
+ /* Record the temporary address in order to free it later. */
+ if (ptemp1)
+ {
+ temporary_list *tempo;
+ tempo = (temporary_list *) gfc_getmem (sizeof (temporary_list));
+ tempo->temporary = ptemp1;
+ tempo->next = *temp;
+ *temp = tempo;
+ }
+
+ /* Allocate temporary for !mask. */
+ ntmp = allocate_temp_for_forall_nest (nested_forall_info, boolean_type_node,
+ inner_size, block, &ptemp2);
+ /* Record the temporary in order to free it later. */
+ if (ptemp2)
+ {
+ temporary_list *tempo;
+ tempo = (temporary_list *) gfc_getmem (sizeof (temporary_list));
+ tempo->temporary = ptemp2;
+ tempo->next = *temp;
+ *temp = tempo;
+ }
+
+ /* Variable to index the temporary. */
+ count = gfc_create_var (gfc_array_index_type, "count");
+ /* Initilize count. */
+ gfc_add_modify_expr (block, count, integer_zero_node);
+
+ gfc_start_block (&body);
+
+ gfc_init_se (&rse, NULL);
+ gfc_init_se (&lse, NULL);
+
+ if (lss == gfc_ss_terminator)
+ {
+ gfc_init_block (&body1);
+ }
+ else
+ {
+ /* Initiliaze the loop. */
+ gfc_init_loopinfo (&loop);
+
+ /* We may need LSS to determine the shape of the expression. */
+ gfc_add_ss_to_loop (&loop, lss);
+ gfc_add_ss_to_loop (&loop, rss);
+
+ gfc_conv_ss_startstride (&loop);
+ gfc_conv_loop_setup (&loop);
+
+ gfc_mark_ss_chain_used (rss, 1);
+ /* Start the loop body. */
+ gfc_start_scalarized_body (&loop, &body1);
+
+ /* Translate the expression. */
+ gfc_copy_loopinfo_to_se (&rse, &loop);
+ rse.ss = rss;
+ gfc_conv_expr (&rse, me);
+ }
+ /* Form the expression of the temporary. */
+ lse.expr = gfc_build_array_ref (tmp, count);
+ tmpexpr = gfc_build_array_ref (ntmp, count);
+
+ /* Use the scalar assignment to fill temporary TMP. */
+ tmp1 = gfc_trans_scalar_assign (&lse, &rse, me->ts.type);
+ gfc_add_expr_to_block (&body1, tmp1);
+
+ /* Fill temporary NTMP. */
+ tmp1 = build1 (TRUTH_NOT_EXPR, TREE_TYPE (lse.expr), lse.expr);
+ gfc_add_modify_expr (&body1, tmpexpr, tmp1);
+
+ if (lss == gfc_ss_terminator)
+ {
+ gfc_add_block_to_block (&body, &body1);
+ }
+ else
+ {
+ /* Increment count. */
+ tmp1 = fold (build (PLUS_EXPR, gfc_array_index_type, count,
+ integer_one_node));
+ gfc_add_modify_expr (&body1, count, tmp1);
+
+ /* Generate the copying loops. */
+ gfc_trans_scalarizing_loops (&loop, &body1);
+
+ gfc_add_block_to_block (&body, &loop.pre);
+ gfc_add_block_to_block (&body, &loop.post);
+
+ gfc_cleanup_loop (&loop);
+ /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
+ as tree nodes in SS may not be valid in different scope. */
+ }
+
+ tmp1 = gfc_finish_block (&body);
+ /* If the WHERE construct is inside FORALL, fill the full temporary. */
+ if (nested_forall_info != NULL)
+ tmp1 = gfc_trans_nested_forall_loop (nested_forall_info, tmp1, 1, 1);
+
+
+ gfc_add_expr_to_block (block, tmp1);
+
+ *mask = tmp;
+ *nmask = ntmp;
+
+ return tmp1;
+}
+
+
+/* Translate an assignment statement in a WHERE statement or construct
+ statement. The MASK expression is used to control which elements
+ of EXPR1 shall be assigned. */
+
+static tree
+gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2, tree mask,
+ tree count1, tree count2)
+{
+ gfc_se lse;
+ gfc_se rse;
+ gfc_ss *lss;
+ gfc_ss *lss_section;
+ gfc_ss *rss;
+
+ gfc_loopinfo loop;
+ tree tmp;
+ stmtblock_t block;
+ stmtblock_t body;
+ tree index, maskexpr, tmp1;
+
+#if 0
+ /* TODO: handle this special case.
+ Special case a single function returning an array. */
+ if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
+ {
+ tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
+ if (tmp)
+ return tmp;
+ }
+#endif
+
+ /* Assignment of the form lhs = rhs. */
+ gfc_start_block (&block);
+
+ gfc_init_se (&lse, NULL);
+ gfc_init_se (&rse, NULL);
+
+ /* Walk the lhs. */
+ lss = gfc_walk_expr (expr1);
+ rss = NULL;
+
+ /* In each where-assign-stmt, the mask-expr and the variable being
+ defined shall be arrays of the same shape. */
+ assert (lss != gfc_ss_terminator);
+
+ /* The assignment needs scalarization. */
+ lss_section = lss;
+
+ /* Find a non-scalar SS from the lhs. */
+ while (lss_section != gfc_ss_terminator
+ && lss_section->type != GFC_SS_SECTION)
+ lss_section = lss_section->next;
+
+ assert (lss_section != gfc_ss_terminator);
+
+ /* Initialize the scalarizer. */
+ gfc_init_loopinfo (&loop);
+
+ /* Walk the rhs. */
+ rss = gfc_walk_expr (expr2);
+ if (rss == gfc_ss_terminator)
+ {
+ /* The rhs is scalar. Add a ss for the expression. */
+ rss = gfc_get_ss ();
+ rss->next = gfc_ss_terminator;
+ rss->type = GFC_SS_SCALAR;
+ rss->expr = expr2;
+ }
+
+ /* Associate the SS with the loop. */
+ gfc_add_ss_to_loop (&loop, lss);
+ gfc_add_ss_to_loop (&loop, rss);
+
+ /* Calculate the bounds of the scalarization. */
+ gfc_conv_ss_startstride (&loop);
+
+ /* Resolve any data dependencies in the statement. */
+ gfc_conv_resolve_dependencies (&loop, lss_section, rss);
+
+ /* Setup the scalarizing loops. */
+ gfc_conv_loop_setup (&loop);
+
+ /* Setup the gfc_se structures. */
+ gfc_copy_loopinfo_to_se (&lse, &loop);
+ gfc_copy_loopinfo_to_se (&rse, &loop);
+
+ rse.ss = rss;
+ gfc_mark_ss_chain_used (rss, 1);
+ if (loop.temp_ss == NULL)
+ {
+ lse.ss = lss;
+ gfc_mark_ss_chain_used (lss, 1);
+ }
+ else
+ {
+ lse.ss = loop.temp_ss;
+ gfc_mark_ss_chain_used (lss, 3);
+ gfc_mark_ss_chain_used (loop.temp_ss, 3);
+ }
+
+ /* Start the scalarized loop body. */
+ gfc_start_scalarized_body (&loop, &body);
+
+ /* Translate the expression. */
+ gfc_conv_expr (&rse, expr2);
+ if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
+ {
+ gfc_conv_tmp_array_ref (&lse);
+ gfc_advance_se_ss_chain (&lse);
+ }
+ else
+ gfc_conv_expr (&lse, expr1);
+
+ /* Form the mask expression according to the mask tree list. */
+ index = count1;
+ tmp = mask;
+ if (tmp != NULL)
+ maskexpr = gfc_build_array_ref (tmp, index);
+ else
+ maskexpr = NULL;
+
+ tmp = TREE_CHAIN (tmp);
+ while (tmp)
+ {
+ tmp1 = gfc_build_array_ref (tmp, index);
+ maskexpr = build (TRUTH_AND_EXPR, TREE_TYPE (tmp1), maskexpr, tmp1);
+ tmp = TREE_CHAIN (tmp);
+ }
+ /* Use the scalar assignment as is. */
+ tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts.type);
+ tmp = build_v (COND_EXPR, maskexpr, tmp, build_empty_stmt ());
+
+ gfc_add_expr_to_block (&body, tmp);
+
+ if (lss == gfc_ss_terminator)
+ {
+ /* Increment count1. */
+ tmp = fold (build (PLUS_EXPR, TREE_TYPE (count1), count1,
+ integer_one_node));
+ gfc_add_modify_expr (&body, count1, tmp);
+
+ /* Use the scalar assignment as is. */
+ gfc_add_block_to_block (&block, &body);
+ }
+ else
+ {
+ if (lse.ss != gfc_ss_terminator)
+ abort ();
+ if (rse.ss != gfc_ss_terminator)
+ abort ();
+
+ if (loop.temp_ss != NULL)
+ {
+ /* Increment count1 before finish the main body of a scalarized
+ expression. */
+ tmp = fold (build (PLUS_EXPR, TREE_TYPE (count1), count1,
+ integer_one_node));
+ gfc_add_modify_expr (&body, count1, tmp);
+ gfc_trans_scalarized_loop_boundary (&loop, &body);
+
+ /* We need to copy the temporary to the actual lhs. */
+ gfc_init_se (&lse, NULL);
+ gfc_init_se (&rse, NULL);
+ gfc_copy_loopinfo_to_se (&lse, &loop);
+ gfc_copy_loopinfo_to_se (&rse, &loop);
+
+ rse.ss = loop.temp_ss;
+ lse.ss = lss;
+
+ gfc_conv_tmp_array_ref (&rse);
+ gfc_advance_se_ss_chain (&rse);
+ gfc_conv_expr (&lse, expr1);
+
+ if (lse.ss != gfc_ss_terminator)
+ abort ();
+
+ if (rse.ss != gfc_ss_terminator)
+ abort ();
+
+ /* Form the mask expression according to the mask tree list. */
+ index = count2;
+ tmp = mask;
+ if (tmp != NULL)
+ maskexpr = gfc_build_array_ref (tmp, index);
+ else
+ maskexpr = NULL;
+
+ tmp = TREE_CHAIN (tmp);
+ while (tmp)
+ {
+ tmp1 = gfc_build_array_ref (tmp, index);
+ maskexpr = build (TRUTH_AND_EXPR, TREE_TYPE (tmp1), maskexpr,
+ tmp1);
+ tmp = TREE_CHAIN (tmp);
+ }
+ /* Use the scalar assignment as is. */
+ tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts.type);
+ tmp = build_v (COND_EXPR, maskexpr, tmp, build_empty_stmt ());
+ gfc_add_expr_to_block (&body, tmp);
+ /* Increment count2. */
+ tmp = fold (build (PLUS_EXPR, TREE_TYPE (count2), count2,
+ integer_one_node));
+ gfc_add_modify_expr (&body, count2, tmp);
+ }
+ else
+ {
+ /* Increment count1. */
+ tmp = fold (build (PLUS_EXPR, TREE_TYPE (count1), count1,
+ integer_one_node));
+ gfc_add_modify_expr (&body, count1, tmp);
+ }
+
+ /* Generate the copying loops. */
+ gfc_trans_scalarizing_loops (&loop, &body);
+
+ /* Wrap the whole thing up. */
+ gfc_add_block_to_block (&block, &loop.pre);
+ gfc_add_block_to_block (&block, &loop.post);
+ gfc_cleanup_loop (&loop);
+ }
+
+ return gfc_finish_block (&block);
+}
+
+
+/* Translate the WHERE construct or statement.
+ This fuction can be called iteratelly to translate the nested WHERE
+ construct or statement.
+ MASK is the control mask, and PMASK is the pending control mask.
+ TEMP records the temporary address which must be freed later. */
+
+static void
+gfc_trans_where_2 (gfc_code * code, tree mask, tree pmask,
+ forall_info * nested_forall_info, stmtblock_t * block,
+ temporary_list ** temp)
+{
+ gfc_expr *expr1;
+ gfc_expr *expr2;
+ gfc_code *cblock;
+ gfc_code *cnext;
+ tree tmp, tmp1, tmp2;
+ tree count1, count2;
+ tree mask_copy;
+ int need_temp;
+
+ /* the WHERE statement or the WHERE construct statement. */
+ cblock = code->block;
+ while (cblock)
+ {
+ /* Has mask-expr. */
+ if (cblock->expr)
+ {
+ /* Ensure that the WHERE mask be evaluated only once. */
+ tmp2 = gfc_evaluate_where_mask (cblock->expr, nested_forall_info,
+ &tmp, &tmp1, temp, block);
+
+ /* Set the control mask and the pending control mask. */
+ /* It's a where-stmt. */
+ if (mask == NULL)
+ {
+ mask = tmp;
+ pmask = tmp1;
+ }
+ /* It's a nested where-stmt. */
+ else if (mask && pmask == NULL)
+ {
+ tree tmp2;
+ /* Use the TREE_CHAIN to list the masks. */
+ tmp2 = copy_list (mask);
+ pmask = chainon (mask, tmp1);
+ mask = chainon (tmp2, tmp);
+ }
+ /* It's a masked-elsewhere-stmt. */
+ else if (mask && cblock->expr)
+ {
+ tree tmp2;
+ tmp2 = copy_list (pmask);
+
+ mask = pmask;
+ tmp2 = chainon (tmp2, tmp);
+ pmask = chainon (mask, tmp1);
+ mask = tmp2;
+ }
+ }
+ /* It's a elsewhere-stmt. No mask-expr is present. */
+ else
+ mask = pmask;
+
+ /* Get the assignment statement of a WHERE statement, or the first
+ statement in where-body-construct of a WHERE construct. */
+ cnext = cblock->next;
+ while (cnext)
+ {
+ switch (cnext->op)
+ {
+ /* WHERE assignment statement. */
+ case EXEC_ASSIGN:
+ expr1 = cnext->expr;
+ expr2 = cnext->expr2;
+ if (nested_forall_info != NULL)
+ {
+ int nvar;
+ gfc_expr **varexpr;
+
+ nvar = nested_forall_info->nvar;
+ varexpr = (gfc_expr **)
+ gfc_getmem (nvar * sizeof (gfc_expr *));
+ need_temp = gfc_check_dependency (expr1, expr2, varexpr,
+ nvar);
+ if (need_temp)
+ gfc_trans_assign_need_temp (expr1, expr2, mask,
+ nested_forall_info, block);
+ else
+ {
+ /* Variables to control maskexpr. */
+ count1 = gfc_create_var (gfc_array_index_type, "count1");
+ count2 = gfc_create_var (gfc_array_index_type, "count2");
+ gfc_add_modify_expr (block, count1, integer_zero_node);
+ gfc_add_modify_expr (block, count2, integer_zero_node);
+
+ tmp = gfc_trans_where_assign (expr1, expr2, mask, count1,
+ count2);
+ tmp = gfc_trans_nested_forall_loop (nested_forall_info,
+ tmp, 1, 1);
+ gfc_add_expr_to_block (block, tmp);
+ }
+ }
+ else
+ {
+ /* Variables to control maskexpr. */
+ count1 = gfc_create_var (gfc_array_index_type, "count1");
+ count2 = gfc_create_var (gfc_array_index_type, "count2");
+ gfc_add_modify_expr (block, count1, integer_zero_node);
+ gfc_add_modify_expr (block, count2, integer_zero_node);
+
+ tmp = gfc_trans_where_assign (expr1, expr2, mask, count1,
+ count2);
+ gfc_add_expr_to_block (block, tmp);
+
+ }
+ break;
+
+ /* WHERE or WHERE construct is part of a where-body-construct. */
+ case EXEC_WHERE:
+ /* Ensure that MASK is not modified by next gfc_trans_where_2. */
+ mask_copy = copy_list (mask);
+ gfc_trans_where_2 (cnext, mask_copy, NULL, nested_forall_info,
+ block, temp);
+ break;
+
+ default:
+ abort ();
+ }
+
+ /* The next statement within the same where-body-construct. */
+ cnext = cnext->next;
+ }
+ /* The next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt. */
+ cblock = cblock->block;
+ }
+}
+
+
+/* As the WHERE or WHERE construct statement can be nested, we call
+ gfc_trans_where_2 to do the translation, and pass the initial
+ NULL values for both the control mask and the pending control mask. */
+
+tree
+gfc_trans_where (gfc_code * code)
+{
+ stmtblock_t block;
+ temporary_list *temp, *p;
+ tree args;
+ tree tmp;
+
+ gfc_start_block (&block);
+ temp = NULL;
+
+ gfc_trans_where_2 (code, NULL, NULL, NULL, &block, &temp);
+
+ /* Add calls to free temporaries which were dynamically allocated. */
+ while (temp)
+ {
+ args = gfc_chainon_list (NULL_TREE, temp->temporary);
+ tmp = gfc_build_function_call (gfor_fndecl_internal_free, args);
+ gfc_add_expr_to_block (&block, tmp);
+
+ p = temp;
+ temp = temp->next;
+ gfc_free (p);
+ }
+ return gfc_finish_block (&block);
+}
+
+
+/* CYCLE a DO loop. The label decl has already been created by
+ gfc_trans_do(), it's in TREE_PURPOSE (backend_decl) of the gfc_code
+ node at the head of the loop. We must mark the label as used. */
+
+tree
+gfc_trans_cycle (gfc_code * code)
+{
+ tree cycle_label;
+
+ cycle_label = TREE_PURPOSE (code->ext.whichloop->backend_decl);
+ TREE_USED (cycle_label) = 1;
+ return build1_v (GOTO_EXPR, cycle_label);
+}
+
+
+/* EXIT a DO loop. Similair to CYCLE, but now the label is in
+ TREE_VALUE (backend_decl) of the gfc_code node at the head of the
+ loop. */
+
+tree
+gfc_trans_exit (gfc_code * code)
+{
+ tree exit_label;
+
+ exit_label = TREE_VALUE (code->ext.whichloop->backend_decl);
+ TREE_USED (exit_label) = 1;
+ return build1_v (GOTO_EXPR, exit_label);
+}
+
+
+/* Translate the ALLOCATE statement. */
+
+tree
+gfc_trans_allocate (gfc_code * code)
+{
+ gfc_alloc *al;
+ gfc_expr *expr;
+ gfc_se se;
+ tree tmp;
+ tree parm;
+ gfc_ref *ref;
+ tree stat;
+ tree pstat;
+ tree error_label;
+ stmtblock_t block;
+
+ if (!code->ext.alloc_list)
+ return NULL_TREE;
+
+ gfc_start_block (&block);
+
+ if (code->expr)
+ {
+ stat = gfc_create_var (gfc_int4_type_node, "stat");
+ pstat = gfc_build_addr_expr (NULL, stat);
+
+ error_label = gfc_build_label_decl (NULL_TREE);
+ TREE_USED (error_label) = 1;
+ }
+ else
+ {
+ pstat = integer_zero_node;
+ stat = error_label = NULL_TREE;
+ }
+
+
+ for (al = code->ext.alloc_list; al != NULL; al = al->next)
+ {
+ expr = al->expr;
+
+ gfc_init_se (&se, NULL);
+ gfc_start_block (&se.pre);
+
+ se.want_pointer = 1;
+ se.descriptor_only = 1;
+ gfc_conv_expr (&se, expr);
+
+ ref = expr->ref;
+
+ /* Find the last reference in the chain. */
+ while (ref && ref->next != NULL)
+ {
+ assert (ref->type != REF_ARRAY || ref->u.ar.type == AR_ELEMENT);
+ ref = ref->next;
+ }
+
+ if (ref != NULL && ref->type == REF_ARRAY)
+ {
+ /* An array. */
+ gfc_array_allocate (&se, ref, pstat);
+ }
+ else
+ {
+ /* A scalar or derived type. */
+ tree val;
+
+ val = gfc_create_var (ppvoid_type_node, "ptr");
+ tmp = gfc_build_addr_expr (ppvoid_type_node, se.expr);
+ gfc_add_modify_expr (&se.pre, val, tmp);
+
+ tmp = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se.expr)));
+ parm = gfc_chainon_list (NULL_TREE, val);
+ parm = gfc_chainon_list (parm, tmp);
+ parm = gfc_chainon_list (parm, pstat);
+ tmp = gfc_build_function_call (gfor_fndecl_allocate, parm);
+ gfc_add_expr_to_block (&se.pre, tmp);
+
+ if (code->expr)
+ {
+ tmp = build1_v (GOTO_EXPR, error_label);
+ parm =
+ build (NE_EXPR, boolean_type_node, stat, integer_zero_node);
+ tmp = build_v (COND_EXPR, parm, tmp, build_empty_stmt ());
+ gfc_add_expr_to_block (&se.pre, tmp);
+ }
+ }
+
+ tmp = gfc_finish_block (&se.pre);
+ gfc_add_expr_to_block (&block, tmp);
+ }
+
+ /* Assign the value to the status variable. */
+ if (code->expr)
+ {
+ tmp = build1_v (LABEL_EXPR, error_label);
+ gfc_add_expr_to_block (&block, tmp);
+
+ gfc_init_se (&se, NULL);
+ gfc_conv_expr_lhs (&se, code->expr);
+ tmp = convert (TREE_TYPE (se.expr), stat);
+ gfc_add_modify_expr (&block, se.expr, tmp);
+ }
+
+ return gfc_finish_block (&block);
+}
+
+
+tree
+gfc_trans_deallocate (gfc_code * code)
+{
+ gfc_se se;
+ gfc_alloc *al;
+ gfc_expr *expr;
+ tree var;
+ tree tmp;
+ tree type;
+ stmtblock_t block;
+
+ gfc_start_block (&block);
+
+ for (al = code->ext.alloc_list; al != NULL; al = al->next)
+ {
+ expr = al->expr;
+ assert (expr->expr_type == EXPR_VARIABLE);
+
+ gfc_init_se (&se, NULL);
+ gfc_start_block (&se.pre);
+
+ se.want_pointer = 1;
+ se.descriptor_only = 1;
+ gfc_conv_expr (&se, expr);
+
+ if (expr->symtree->n.sym->attr.dimension)
+ {
+ tmp = gfc_array_deallocate (se.expr);
+ gfc_add_expr_to_block (&se.pre, tmp);
+ }
+ else
+ {
+ type = build_pointer_type (TREE_TYPE (se.expr));
+ var = gfc_create_var (type, "ptr");
+ tmp = gfc_build_addr_expr (type, se.expr);
+ gfc_add_modify_expr (&se.pre, var, tmp);
+
+ tmp = gfc_chainon_list (NULL_TREE, var);
+ tmp = gfc_chainon_list (tmp, integer_zero_node);
+ tmp = gfc_build_function_call (gfor_fndecl_deallocate, tmp);
+ gfc_add_expr_to_block (&se.pre, tmp);
+ }
+ tmp = gfc_finish_block (&se.pre);
+ gfc_add_expr_to_block (&block, tmp);
+ }
+
+ return gfc_finish_block (&block);
+}
+
diff --git a/gcc/fortran/trans-stmt.h b/gcc/fortran/trans-stmt.h
new file mode 100644
index 00000000000..e9d66e8c928
--- /dev/null
+++ b/gcc/fortran/trans-stmt.h
@@ -0,0 +1,65 @@
+/* Header for statement translation functions
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Paul Brook
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Statement translators (gfc_trans_*) return a fully translated tree.
+ Calls gfc_trans_*. */
+tree gfc_trans_code (gfc_code *);
+
+/* All other gfc_trans_* should only need be called by gfc_trans_code */
+
+/* trans-expr.c */
+tree gfc_trans_assign (gfc_code *);
+tree gfc_trans_pointer_assign (gfc_code *);
+
+/* trans-stmt.c */
+tree gfc_trans_cycle (gfc_code *);
+tree gfc_trans_exit (gfc_code *);
+tree gfc_trans_label_assign (gfc_code *);
+tree gfc_trans_label_here (gfc_code *);
+tree gfc_trans_goto (gfc_code *);
+tree gfc_trans_pause (gfc_code *);
+tree gfc_trans_stop (gfc_code *);
+tree gfc_trans_call (gfc_code *);
+tree gfc_trans_return (gfc_code *);
+tree gfc_trans_if (gfc_code *);
+tree gfc_trans_arithmetic_if (gfc_code *);
+tree gfc_trans_do (gfc_code *);
+tree gfc_trans_do_while (gfc_code *);
+tree gfc_trans_select (gfc_code *);
+tree gfc_trans_forall (gfc_code *);
+tree gfc_trans_where (gfc_code *);
+tree gfc_trans_allocate (gfc_code *);
+tree gfc_trans_deallocate (gfc_code *);
+tree gfc_trans_deallocate_array (tree);
+
+/* trans-io.c */
+tree gfc_trans_open (gfc_code *);
+tree gfc_trans_close (gfc_code *);
+tree gfc_trans_read (gfc_code *);
+tree gfc_trans_write (gfc_code *);
+tree gfc_trans_iolength (gfc_code *);
+tree gfc_trans_backspace (gfc_code *);
+tree gfc_trans_endfile (gfc_code *);
+tree gfc_trans_inquire (gfc_code *);
+tree gfc_trans_rewind (gfc_code *);
+
+tree gfc_trans_transfer (gfc_code *);
+tree gfc_trans_dt_end (gfc_code *);
diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c
new file mode 100644
index 00000000000..9e5aade1a58
--- /dev/null
+++ b/gcc/fortran/trans-types.c
@@ -0,0 +1,1485 @@
+/* Backend support for Fortran 95 basic types and derived types.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+ and Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* trans-types.c -- gfortran backend types */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include <stdio.h>
+#include "ggc.h"
+#include "toplev.h"
+#include <assert.h>
+#include "gfortran.h"
+#include "trans.h"
+#include "trans-types.h"
+#include "trans-const.h"
+
+
+#if (GFC_MAX_DIMENSIONS < 10)
+#define GFC_RANK_DIGITS 1
+#define GFC_RANK_PRINTF_FORMAT "%01d"
+#elif (GFC_MAX_DIMENSIONS < 100)
+#define GFC_RANK_DIGITS 2
+#define GFC_RANK_PRINTF_FORMAT "%02d"
+#else
+#error If you really need >99 dimensions, continue the sequence above...
+#endif
+
+static tree gfc_get_derived_type (gfc_symbol * derived);
+
+tree gfc_type_nodes[NUM_F95_TYPES];
+
+tree gfc_array_index_type;
+tree pvoid_type_node;
+tree ppvoid_type_node;
+tree pchar_type_node;
+
+static GTY(()) tree gfc_desc_dim_type = NULL;
+
+static GTY(()) tree gfc_max_array_element_size;
+
+/* Create the backend type nodes. We map them to their
+ equivalent C type, at least for now. We also give
+ names to the types here, and we push them in the
+ global binding level context.*/
+void
+gfc_init_types (void)
+{
+ unsigned n;
+ unsigned HOST_WIDE_INT hi;
+ unsigned HOST_WIDE_INT lo;
+
+ /* Name the types. */
+#define PUSH_TYPE(name, node) \
+ pushdecl (build_decl (TYPE_DECL, get_identifier (name), node))
+
+ gfc_int1_type_node = signed_char_type_node;
+ PUSH_TYPE ("int1", gfc_int1_type_node);
+ gfc_int2_type_node = short_integer_type_node;
+ PUSH_TYPE ("int2", gfc_int2_type_node);
+ gfc_int4_type_node = gfc_type_for_size (32, 0 /*unsigned */ );
+ PUSH_TYPE ("int4", gfc_int4_type_node);
+ gfc_int8_type_node = gfc_type_for_size (64, 0 /*unsigned */ );
+ PUSH_TYPE ("int8", gfc_int8_type_node);
+#if (GFC_USE_TYPES16 && (HOST_BITS_PER_WIDE_INT >= 64))
+ gfc_int16_type_node = gfc_type_for_size (128, 0 /*unsigned */ );
+ PUSH_TYPE ("int16", gfc_int16_type_node);
+#endif
+
+ gfc_real4_type_node = float_type_node;
+ PUSH_TYPE ("real4", gfc_real4_type_node);
+ gfc_real8_type_node = double_type_node;
+ PUSH_TYPE ("real8", gfc_real8_type_node);
+#if (GFC_USE_TYPES16 && (HOST_BITS_PER_WIDE_INT >= 64))
+ /* Hmm, this will not work. Ref. g77 */
+ gfc_real16_type_node = long_double_type_node;
+ PUSH_TYPE ("real16", gfc_real16_type_node);
+#endif
+
+ gfc_complex4_type_node = complex_float_type_node;
+ PUSH_TYPE ("complex4", gfc_complex4_type_node);
+ gfc_complex8_type_node = complex_double_type_node;
+ PUSH_TYPE ("complex8", gfc_complex8_type_node);
+#if (GFC_USE_TYPES16 && (HOST_BITS_PER_WIDE_INT >= 64))
+ /* Hmm, this will not work. Ref. g77 */
+ gfc_complex16_type_node = complex_long_double_type_node;
+ PUSH_TYPE ("complex16", gfc_complex16_type_node);
+#endif
+
+ gfc_logical1_type_node = make_node (BOOLEAN_TYPE);
+ TYPE_PRECISION (gfc_logical1_type_node) = 8;
+ fixup_unsigned_type (gfc_logical1_type_node);
+ PUSH_TYPE ("logical1", gfc_logical1_type_node);
+ gfc_logical2_type_node = make_node (BOOLEAN_TYPE);
+ TYPE_PRECISION (gfc_logical2_type_node) = 16;
+ fixup_unsigned_type (gfc_logical2_type_node);
+ PUSH_TYPE ("logical2", gfc_logical2_type_node);
+ gfc_logical4_type_node = make_node (BOOLEAN_TYPE);
+ TYPE_PRECISION (gfc_logical4_type_node) = 32;
+ fixup_unsigned_type (gfc_logical4_type_node);
+ PUSH_TYPE ("logical4", gfc_logical4_type_node);
+ gfc_logical8_type_node = make_node (BOOLEAN_TYPE);
+ TYPE_PRECISION (gfc_logical8_type_node) = 64;
+ fixup_unsigned_type (gfc_logical8_type_node);
+ PUSH_TYPE ("logical8", gfc_logical8_type_node);
+#if (GFC_USE_TYPES16 && (HOST_BITS_PER_WIDE_INT >= 64))
+ gfc_logical16_type_node = make_node (BOOLEAN_TYPE);
+ TYPE_PRECISION (gfc_logical16_type_node) = 128;
+ fixup_unsigned_type (gfc_logical16_type_node);
+ PUSH_TYPE ("logical16", gfc_logical16_type_node);
+#endif
+
+ gfc_character1_type_node = build_type_variant (signed_char_type_node, 0, 0);
+ PUSH_TYPE ("char", gfc_character1_type_node);
+
+ PUSH_TYPE ("byte", unsigned_char_type_node);
+ PUSH_TYPE ("void", void_type_node);
+
+ /* DBX debugging output gets upset if these aren't set. */
+ if (!TYPE_NAME (integer_type_node))
+ PUSH_TYPE ("c_integer", integer_type_node);
+ if (!TYPE_NAME (char_type_node))
+ PUSH_TYPE ("c_char", char_type_node);
+#undef PUSH_TYPE
+
+ pvoid_type_node = build_pointer_type (void_type_node);
+ ppvoid_type_node = build_pointer_type (pvoid_type_node);
+ pchar_type_node = build_pointer_type (gfc_character1_type_node);
+
+ gfc_index_integer_kind = TYPE_PRECISION (long_unsigned_type_node) / 8;
+ gfc_array_index_type = gfc_get_int_type (gfc_index_integer_kind);
+
+ /* The maximum array element size that can be handled is determined
+ by the number of bits available to store this field in the array
+ descriptor. */
+
+ n = TREE_INT_CST_LOW (TYPE_SIZE (gfc_array_index_type))
+ - GFC_DTYPE_SIZE_SHIFT;
+
+ if (n > sizeof (HOST_WIDE_INT) * 8)
+ {
+ lo = ~(unsigned HOST_WIDE_INT) 0;
+ hi = lo >> (sizeof (HOST_WIDE_INT) * 16 - n);
+ }
+ else
+ {
+ hi = 0;
+ lo = (~(unsigned HOST_WIDE_INT) 0) >> (sizeof (HOST_WIDE_INT) * 8 - n);
+ }
+ gfc_max_array_element_size = build_int_2 (lo, hi);
+ TREE_TYPE (gfc_max_array_element_size) = long_unsigned_type_node;
+
+ size_type_node = gfc_array_index_type;
+ boolean_type_node = gfc_get_logical_type (gfc_default_logical_kind ());
+
+ boolean_true_node = build_int_2 (1, 0);
+ TREE_TYPE (boolean_true_node) = boolean_type_node;
+ boolean_false_node = build_int_2 (0, 0);
+ TREE_TYPE (boolean_false_node) = boolean_type_node;
+}
+
+/* Get a type node for an integer kind */
+tree
+gfc_get_int_type (int kind)
+{
+ switch (kind)
+ {
+ case 1:
+ return (gfc_int1_type_node);
+ case 2:
+ return (gfc_int2_type_node);
+ case 4:
+ return (gfc_int4_type_node);
+ case 8:
+ return (gfc_int8_type_node);
+#if (GFC_USE_TYPES16 && (HOST_BITS_PER_WIDE_INT >= 64))
+ case 16:
+ return (95 _int16_type_node);
+#endif
+ default:
+ fatal_error ("integer kind=%d not available", kind);
+ }
+}
+
+/* Get a type node for a real kind */
+tree
+gfc_get_real_type (int kind)
+{
+ switch (kind)
+ {
+ case 4:
+ return (gfc_real4_type_node);
+ case 8:
+ return (gfc_real8_type_node);
+#if (GFC_USE_TYPES16 && (HOST_BITS_PER_WIDE_INT >= 64))
+ case 16:
+ return (gfc_real16_type_node);
+#endif
+ default:
+ fatal_error ("real kind=%d not available", kind);
+ }
+}
+
+/* Get a type node for a complex kind */
+tree
+gfc_get_complex_type (int kind)
+{
+ switch (kind)
+ {
+ case 4:
+ return (gfc_complex4_type_node);
+ case 8:
+ return (gfc_complex8_type_node);
+#if (GFC_USE_TYPES16 && (HOST_BITS_PER_WIDE_INT >= 64))
+ case 16:
+ return (gfc_complex16_type_node);
+#endif
+ default:
+ fatal_error ("complex kind=%d not available", kind);
+ }
+}
+
+/* Get a type node for a logical kind */
+tree
+gfc_get_logical_type (int kind)
+{
+ switch (kind)
+ {
+ case 1:
+ return (gfc_logical1_type_node);
+ case 2:
+ return (gfc_logical2_type_node);
+ case 4:
+ return (gfc_logical4_type_node);
+ case 8:
+ return (gfc_logical8_type_node);
+#if (GFC_USE_TYPES16 && (HOST_BITS_PER_WIDE_INT >= 64))
+ case 16:
+ return (gfc_logical16_type_node);
+#endif
+ default:
+ fatal_error ("logical kind=%d not available", kind);
+ }
+}
+
+/* Get a type node for a character kind. */
+tree
+gfc_get_character_type (int kind, gfc_charlen * cl)
+{
+ tree base;
+ tree type;
+ tree len;
+ tree bounds;
+
+ switch (kind)
+ {
+ case 1:
+ base = gfc_character1_type_node;
+ break;
+
+ default:
+ fatal_error ("character kind=%d not available", kind);
+ }
+
+ len = (cl == 0) ? NULL_TREE : cl->backend_decl;
+
+ bounds = build_range_type (gfc_array_index_type, integer_one_node, len);
+ type = build_array_type (base, bounds);
+ TYPE_STRING_FLAG (type) = 1;
+
+ return type;
+}
+
+/* Covert a basic type. This will be an array for character types. */
+tree
+gfc_typenode_for_spec (gfc_typespec * spec)
+{
+ tree basetype;
+
+ switch (spec->type)
+ {
+ case BT_UNKNOWN:
+ abort ();
+ break;
+
+ case BT_INTEGER:
+ basetype = gfc_get_int_type (spec->kind);
+ break;
+
+ case BT_REAL:
+ basetype = gfc_get_real_type (spec->kind);
+ break;
+
+ case BT_COMPLEX:
+ basetype = gfc_get_complex_type (spec->kind);
+ break;
+
+ case BT_LOGICAL:
+ basetype = gfc_get_logical_type (spec->kind);
+ break;
+
+ case BT_CHARACTER:
+ basetype = gfc_get_character_type (spec->kind, spec->cl);
+ break;
+
+ case BT_DERIVED:
+ basetype = gfc_get_derived_type (spec->derived);
+ break;
+
+ default:
+ abort ();
+ break;
+ }
+ return basetype;
+}
+
+/* Build an INT_CST for constant expressions, otherwise return NULL_TREE. */
+static tree
+gfc_conv_array_bound (gfc_expr * expr)
+{
+ /* If expr is an integer constant, return that. */
+ if (expr != NULL && expr->expr_type == EXPR_CONSTANT)
+ return gfc_conv_mpz_to_tree (expr->value.integer, gfc_index_integer_kind);
+
+ /* Otherwise return NULL. */
+ return NULL_TREE;
+}
+
+tree
+gfc_get_element_type (tree type)
+{
+ tree element;
+
+ if (GFC_ARRAY_TYPE_P (type))
+ {
+ if (TREE_CODE (type) == POINTER_TYPE)
+ type = TREE_TYPE (type);
+ assert (TREE_CODE (type) == ARRAY_TYPE);
+ element = TREE_TYPE (type);
+ }
+ else
+ {
+ assert (GFC_DESCRIPTOR_TYPE_P (type));
+ element = TREE_TYPE (TYPE_FIELDS (type));
+
+ assert (TREE_CODE (element) == POINTER_TYPE);
+ element = TREE_TYPE (element);
+
+ assert (TREE_CODE (element) == ARRAY_TYPE);
+ element = TREE_TYPE (element);
+ }
+
+ return element;
+}
+
+/* Build an array. This function is called from gfc_sym_type().
+ Actualy returns array descriptor type.
+
+ Format of array descriptors is as follows:
+
+ struct gfc_array_descriptor
+ {
+ array *data
+ index offset;
+ index dtype;
+ struct descriptor_dimension dimension[N_DIM];
+ }
+
+ struct descriptor_dimension
+ {
+ index stride;
+ index lbound;
+ index ubound;
+ }
+
+ Translation code should use gfc_conv_descriptor_* rather than accessing
+ the descriptor directly. Any changes to the array descriptor type will
+ require changes in gfc_conv_descriptor_* and gfc_build_array_initializer.
+
+ This is represented internaly as a RECORD_TYPE. The index nodes are
+ gfc_array_index_type and the data node is a pointer to the data. See below
+ for the handling of character types.
+
+ The dtype member is formatted as follows:
+ rank = dtype & GFC_DTYPE_RANK_MASK // 3 bits
+ type = (dtype & GFC_DTYPE_TYPE_MASK) >> GFC_DTYPE_TYPE_SHIFT // 3 bits
+ size = dtype >> GFC_DTYPE_SIZE_SHIFT
+
+ I originaly used nested ARRAY_TYPE nodes to represent arrays, but this
+ generated poor code for assumed/deferred size arrays. These require
+ use of PLACEHOLDER_EXPR/WITH_RECORD_EXPR, which isn't part of GIMPLE
+ grammar. Also, there is no way to explicitly set the array stride, so
+ all data must be packed(1). I've tried to mark all the functions which
+ would require modification with a GCC ARRAYS comment.
+
+ The data component points to the first element in the array.
+ The offset field is the position of the origin of the array
+ (ie element (0, 0 ...)). This may be outsite the bounds of the array.
+
+ An element is accessed by
+ data[offset + index0*stride0 + index1*stride1 + index2*stride2]
+ This gives good performance as it computation does not involve the
+ bounds of the array. For packed arrays, this is optimized further by
+ substituting the known strides.
+
+ This system has one problem: all array bounds must be withing 2^31 elements
+ of the origin (2^63 on 64-bit machines). For example
+ integer, dimension (80000:90000, 80000:90000, 2) :: array
+ may not work properly on 32-bit machines because 80000*80000 > 2^31, so
+ the calculation for stride02 would overflow. This may still work, but
+ I haven't checked, and it relies on the overflow doing the right thing.
+
+ The way to fix this problem is to access alements as follows:
+ data[(index0-lbound0)*stride0 + (index1-lbound1)*stride1]
+ Obviously this is much slower. I will make this a compile time option,
+ something like -fsmall-array-offsets. Mixing code compiled with and without
+ this switch will work.
+
+ (1) This can be worked around by modifying the upper bound of the previous
+ dimension. This requires extra fields in the descriptor (both real_ubound
+ and fake_ubound). In tree.def there is mention of TYPE_SEP, which
+ may allow us to do this. However I can't find mention of this anywhere
+ else.
+ */
+
+
+/* Returns true if the array sym does not require a descriptor. */
+
+int
+gfc_is_nodesc_array (gfc_symbol * sym)
+{
+ assert (sym->attr.dimension);
+
+ /* We only want local arrays. */
+ if (sym->attr.pointer || sym->attr.allocatable)
+ return 0;
+
+ if (sym->attr.dummy)
+ {
+ if (sym->as->type != AS_ASSUMED_SHAPE)
+ return 1;
+ else
+ return 0;
+ }
+
+ if (sym->attr.result || sym->attr.function)
+ return 0;
+
+ if (sym->attr.pointer || sym->attr.allocatable)
+ return 0;
+
+ assert (sym->as->type == AS_EXPLICIT);
+
+ return 1;
+}
+
+static tree
+gfc_build_array_type (tree type, gfc_array_spec * as)
+{
+ tree lbound[GFC_MAX_DIMENSIONS];
+ tree ubound[GFC_MAX_DIMENSIONS];
+ int n;
+
+ for (n = 0; n < as->rank; n++)
+ {
+ /* Create expressions for the known bounds of the array. */
+ if (as->type == AS_ASSUMED_SHAPE && as->lower[n] == NULL)
+ lbound[n] = integer_one_node;
+ else
+ lbound[n] = gfc_conv_array_bound (as->lower[n]);
+ ubound[n] = gfc_conv_array_bound (as->upper[n]);
+ }
+
+ return gfc_get_array_type_bounds (type, as->rank, lbound, ubound, 0);
+}
+
+/* Returns the struct descriptor_dimension type. */
+static tree
+gfc_get_desc_dim_type (void)
+{
+ tree type;
+ tree decl;
+ tree fieldlist;
+
+ if (gfc_desc_dim_type)
+ return gfc_desc_dim_type;
+
+ /* Build the type node. */
+ type = make_node (RECORD_TYPE);
+
+ TYPE_NAME (type) = get_identifier ("descriptor_dimension");
+ TYPE_PACKED (type) = 1;
+
+ /* Consists of the stride, lbound and ubound members. */
+ decl = build_decl (FIELD_DECL,
+ get_identifier ("stride"), gfc_array_index_type);
+ DECL_CONTEXT (decl) = type;
+ fieldlist = decl;
+
+ decl = build_decl (FIELD_DECL,
+ get_identifier ("lbound"), gfc_array_index_type);
+ DECL_CONTEXT (decl) = type;
+ fieldlist = chainon (fieldlist, decl);
+
+ decl = build_decl (FIELD_DECL,
+ get_identifier ("ubound"), gfc_array_index_type);
+ DECL_CONTEXT (decl) = type;
+ fieldlist = chainon (fieldlist, decl);
+
+ /* Finish off the type. */
+ TYPE_FIELDS (type) = fieldlist;
+
+ gfc_finish_type (type);
+
+ gfc_desc_dim_type = type;
+ return type;
+}
+
+static tree
+gfc_get_dtype (tree type, int rank)
+{
+ tree size;
+ int n;
+ HOST_WIDE_INT i;
+ tree tmp;
+ tree dtype;
+
+ if (GFC_DESCRIPTOR_TYPE_P (type) || GFC_ARRAY_TYPE_P (type))
+ return (GFC_TYPE_ARRAY_DTYPE (type));
+
+ /* TODO: Correctly identify LOGICAL types. */
+ switch (TREE_CODE (type))
+ {
+ case INTEGER_TYPE:
+ n = GFC_DTYPE_INTEGER;
+ break;
+
+ case BOOLEAN_TYPE:
+ n = GFC_DTYPE_LOGICAL;
+ break;
+
+ case REAL_TYPE:
+ n = GFC_DTYPE_REAL;
+ break;
+
+ case COMPLEX_TYPE:
+ n = GFC_DTYPE_COMPLEX;
+ break;
+
+ /* Arrays have already been dealt with. */
+ case RECORD_TYPE:
+ n = GFC_DTYPE_DERIVED;
+ break;
+
+ case ARRAY_TYPE:
+ n = GFC_DTYPE_CHARACTER;
+ break;
+
+ default:
+ abort ();
+ }
+
+ assert (rank <= GFC_DTYPE_RANK_MASK);
+ size = TYPE_SIZE_UNIT (type);
+
+ i = rank | (n << GFC_DTYPE_TYPE_SHIFT);
+ if (size && INTEGER_CST_P (size))
+ {
+ if (tree_int_cst_lt (gfc_max_array_element_size, size))
+ internal_error ("Array element size too big");
+
+ i += TREE_INT_CST_LOW (size) << GFC_DTYPE_SIZE_SHIFT;
+ }
+ dtype = build_int_2 (i, 0);
+ TREE_TYPE (dtype) = gfc_array_index_type;
+
+ if (size && !INTEGER_CST_P (size))
+ {
+ tmp = build_int_2 (GFC_DTYPE_SIZE_SHIFT, 0);
+ TREE_TYPE (tmp) = gfc_array_index_type;
+ tmp = fold (build (LSHIFT_EXPR, gfc_array_index_type, size, tmp));
+ dtype = fold (build (PLUS_EXPR, gfc_array_index_type, tmp, dtype));
+ }
+ /* If we don't know the size we leave it as zero. This should never happen
+ for anything that is actually used. */
+ /* TODO: Check this is actually true, particularly when repacking
+ assumed size parameters. */
+
+ return dtype;
+}
+
+
+/* Build an array type for use without a descriptor. Valid values of packed
+ are 0=no, 1=partial, 2=full, 3=static. */
+
+tree
+gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, int packed)
+{
+ tree range;
+ tree type;
+ tree tmp;
+ int n;
+ int known_stride;
+ int known_offset;
+ mpz_t offset;
+ mpz_t stride;
+ mpz_t delta;
+ gfc_expr *expr;
+
+ mpz_init_set_ui (offset, 0);
+ mpz_init_set_ui (stride, 1);
+ mpz_init (delta);
+
+ /* We don't use build_array_type because this does not include include
+ lang-specific information (ie. the bounds of the array) when checking
+ for duplicates. */
+ type = make_node (ARRAY_TYPE);
+
+ GFC_ARRAY_TYPE_P (type) = 1;
+ TYPE_LANG_SPECIFIC (type) = (struct lang_type *)
+ ggc_alloc_cleared (sizeof (struct lang_type));
+
+ known_stride = (packed != 0);
+ known_offset = 1;
+ for (n = 0; n < as->rank; n++)
+ {
+ /* Fill in the stride and bound components of the type. */
+ if (known_stride)
+ tmp = gfc_conv_mpz_to_tree (stride, gfc_index_integer_kind);
+ else
+ tmp = NULL_TREE;
+ GFC_TYPE_ARRAY_STRIDE (type, n) = tmp;
+
+ expr = as->lower[n];
+ if (expr->expr_type == EXPR_CONSTANT)
+ {
+ tmp = gfc_conv_mpz_to_tree (expr->value.integer,
+ gfc_index_integer_kind);
+ }
+ else
+ {
+ known_stride = 0;
+ tmp = NULL_TREE;
+ }
+ GFC_TYPE_ARRAY_LBOUND (type, n) = tmp;
+
+ if (known_stride)
+ {
+ /* Calculate the offset. */
+ mpz_mul (delta, stride, as->lower[n]->value.integer);
+ mpz_sub (offset, offset, delta);
+ }
+ else
+ known_offset = 0;
+
+ expr = as->upper[n];
+ if (expr && expr->expr_type == EXPR_CONSTANT)
+ {
+ tmp = gfc_conv_mpz_to_tree (expr->value.integer,
+ gfc_index_integer_kind);
+ }
+ else
+ {
+ tmp = NULL_TREE;
+ known_stride = 0;
+ }
+ GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
+
+ if (known_stride)
+ {
+ /* Calculate the stride. */
+ mpz_sub (delta, as->upper[n]->value.integer,
+ as->lower[n]->value.integer);
+ mpz_add_ui (delta, delta, 1);
+ mpz_mul (stride, stride, delta);
+ }
+
+ /* Only the first stride is known for partial packed arrays. */
+ if (packed < 2)
+ known_stride = 0;
+ }
+
+ if (known_offset)
+ {
+ GFC_TYPE_ARRAY_OFFSET (type) =
+ gfc_conv_mpz_to_tree (offset, gfc_index_integer_kind);
+ }
+ else
+ GFC_TYPE_ARRAY_OFFSET (type) = NULL_TREE;
+
+ if (known_stride)
+ {
+ GFC_TYPE_ARRAY_SIZE (type) =
+ gfc_conv_mpz_to_tree (stride, gfc_index_integer_kind);
+ }
+ else
+ GFC_TYPE_ARRAY_SIZE (type) = NULL_TREE;
+
+ GFC_TYPE_ARRAY_DTYPE (type) = gfc_get_dtype (etype, as->rank);
+ GFC_TYPE_ARRAY_RANK (type) = as->rank;
+ range = build_range_type (gfc_array_index_type, integer_zero_node,
+ NULL_TREE);
+ /* TODO: use main type if it is unbounded. */
+ GFC_TYPE_ARRAY_DATAPTR_TYPE (type) =
+ build_pointer_type (build_array_type (etype, range));
+
+ if (known_stride)
+ {
+ mpz_sub_ui (stride, stride, 1);
+ range = gfc_conv_mpz_to_tree (stride, gfc_index_integer_kind);
+ }
+ else
+ range = NULL_TREE;
+
+ range = build_range_type (gfc_array_index_type, integer_zero_node, range);
+ TYPE_DOMAIN (type) = range;
+
+ build_pointer_type (etype);
+ TREE_TYPE (type) = etype;
+
+ layout_type (type);
+
+ mpz_clear (offset);
+ mpz_clear (stride);
+ mpz_clear (delta);
+
+ if (packed < 3 || !known_stride)
+ {
+ type = build_pointer_type (type);
+ GFC_ARRAY_TYPE_P (type) = 1;
+ TYPE_LANG_SPECIFIC (type) = TYPE_LANG_SPECIFIC (TREE_TYPE (type));
+ }
+ return type;
+}
+
+
+/* Build an array (descriptor) type with given bounds. */
+
+tree
+gfc_get_array_type_bounds (tree etype, int dimen, tree * lbound,
+ tree * ubound, int packed)
+{
+ tree fat_type, fat_pointer_type;
+ tree fieldlist;
+ tree arraytype;
+ tree decl;
+ int n;
+ char name[8 + GFC_RANK_DIGITS + GFC_MAX_SYMBOL_LEN];
+ const char *typename;
+ tree lower;
+ tree upper;
+ tree stride;
+ tree tmp;
+
+ /* Build the type node. */
+ fat_type = make_node (RECORD_TYPE);
+ GFC_DESCRIPTOR_TYPE_P (fat_type) = 1;
+ TYPE_LANG_SPECIFIC (fat_type) = (struct lang_type *)
+ ggc_alloc_cleared (sizeof (struct lang_type));
+ GFC_TYPE_ARRAY_RANK (fat_type) = dimen;
+ GFC_TYPE_ARRAY_DTYPE (fat_type) = gfc_get_dtype (etype, dimen);
+
+ tmp = TYPE_NAME (etype);
+ if (tmp && TREE_CODE (tmp) == TYPE_DECL)
+ tmp = DECL_NAME (tmp);
+ if (tmp)
+ typename = IDENTIFIER_POINTER (tmp);
+ else
+ typename = "unknown";
+
+ sprintf (name, "array" GFC_RANK_PRINTF_FORMAT "_%.*s", dimen,
+ GFC_MAX_SYMBOL_LEN, typename);
+ TYPE_NAME (fat_type) = get_identifier (name);
+ TYPE_PACKED (fat_type) = 0;
+
+ fat_pointer_type = build_pointer_type (fat_type);
+
+ /* Build an array descriptor record type. */
+ if (packed != 0)
+ stride = integer_one_node;
+ else
+ stride = NULL_TREE;
+
+ for (n = 0; n < dimen; n++)
+ {
+ GFC_TYPE_ARRAY_STRIDE (fat_type, n) = stride;
+
+ if (lbound)
+ lower = lbound[n];
+ else
+ lower = NULL_TREE;
+
+ if (lower != NULL_TREE)
+ {
+ if (INTEGER_CST_P (lower))
+ GFC_TYPE_ARRAY_LBOUND (fat_type, n) = lower;
+ else
+ lower = NULL_TREE;
+ }
+
+ upper = ubound[n];
+ if (upper != NULL_TREE)
+ {
+ if (INTEGER_CST_P (upper))
+ GFC_TYPE_ARRAY_UBOUND (fat_type, n) = upper;
+ else
+ upper = NULL_TREE;
+ }
+
+ if (upper != NULL_TREE && lower != NULL_TREE && stride != NULL_TREE)
+ {
+ tmp = fold (build (MINUS_EXPR, gfc_array_index_type, upper, lower));
+ tmp = fold (build (PLUS_EXPR, gfc_array_index_type, tmp,
+ integer_one_node));
+ stride =
+ fold (build (MULT_EXPR, gfc_array_index_type, tmp, stride));
+ /* Check the folding worked. */
+ assert (INTEGER_CST_P (stride));
+ }
+ else
+ stride = NULL_TREE;
+ }
+ GFC_TYPE_ARRAY_SIZE (fat_type) = stride;
+ /* TODO: known offsets for descriptors. */
+ GFC_TYPE_ARRAY_OFFSET (fat_type) = NULL_TREE;
+
+ /* We define data as an unknown size array. Much better than doing
+ pointer arithmetic. */
+ arraytype =
+ build_array_type (etype,
+ build_range_type (gfc_array_index_type,
+ integer_zero_node, NULL_TREE));
+ arraytype = build_pointer_type (arraytype);
+ GFC_TYPE_ARRAY_DATAPTR_TYPE (fat_type) = arraytype;
+
+ /* The pointer to the array data. */
+ decl = build_decl (FIELD_DECL, get_identifier ("data"), arraytype);
+
+ DECL_CONTEXT (decl) = fat_type;
+ /* Add the data member as the first element of the descriptor. */
+ fieldlist = decl;
+
+ /* Add the base component. */
+ decl = build_decl (FIELD_DECL, get_identifier ("offset"),
+ gfc_array_index_type);
+ DECL_CONTEXT (decl) = fat_type;
+ fieldlist = chainon (fieldlist, decl);
+
+ /* Add the dtype component. */
+ decl = build_decl (FIELD_DECL, get_identifier ("dtype"),
+ gfc_array_index_type);
+ DECL_CONTEXT (decl) = fat_type;
+ fieldlist = chainon (fieldlist, decl);
+
+ /* Build the array type for the stride and bound components. */
+ arraytype =
+ build_array_type (gfc_get_desc_dim_type (),
+ build_range_type (gfc_array_index_type,
+ integer_zero_node,
+ gfc_rank_cst[dimen - 1]));
+
+ decl = build_decl (FIELD_DECL, get_identifier ("dim"), arraytype);
+ DECL_CONTEXT (decl) = fat_type;
+ DECL_INITIAL (decl) = NULL_TREE;
+ fieldlist = chainon (fieldlist, decl);
+
+ /* Finish off the type. */
+ TYPE_FIELDS (fat_type) = fieldlist;
+
+ gfc_finish_type (fat_type);
+
+ return fat_type;
+}
+
+/* Build a pointer type. This function is called from gfc_sym_type(). */
+static tree
+gfc_build_pointer_type (gfc_symbol * sym, tree type)
+{
+ /* Array pointer types aren't actualy pointers. */
+ if (sym->attr.dimension)
+ return type;
+ else
+ return build_pointer_type (type);
+}
+
+/* Return the type for a symbol. Special handling is required for character
+ types to get the correct level of indirection.
+ For functions return the return type.
+ For subroutines return void_type_node.
+ */
+tree
+gfc_sym_type (gfc_symbol * sym)
+{
+ tree type;
+ int byref;
+
+ if (sym->attr.flavor == FL_PROCEDURE && !sym->attr.function)
+ return void_type_node;
+
+ if (sym->backend_decl)
+ {
+ if (sym->attr.function)
+ return TREE_TYPE (TREE_TYPE (sym->backend_decl));
+ else
+ return TREE_TYPE (sym->backend_decl);
+ }
+
+ /* The frontend doesn't set all the attributes for a function with an
+ explicit result value, so we use that instead when present. */
+ if (sym->attr.function && sym->result)
+ sym = sym->result;
+
+ type = gfc_typenode_for_spec (&sym->ts);
+
+ if (sym->attr.dummy && !sym->attr.function)
+ byref = 1;
+ else
+ byref = 0;
+
+ if (sym->attr.dimension)
+ {
+ if (gfc_is_nodesc_array (sym))
+ {
+ /* If this is a character argument of unknown length, just use the
+ base type. */
+ if (sym->ts.type != BT_CHARACTER
+ || !(sym->attr.dummy || sym->attr.function || sym->attr.result)
+ || sym->ts.cl->backend_decl)
+ {
+ type = gfc_get_nodesc_array_type (type, sym->as,
+ byref ? 2 : 3);
+ byref = 0;
+ }
+ }
+ else
+ type = gfc_build_array_type (type, sym->as);
+ }
+ else
+ {
+ if (sym->attr.allocatable || sym->attr.pointer)
+ type = gfc_build_pointer_type (sym, type);
+ }
+
+ /* We currently pass all parameters by reference.
+ See f95_get_function_decl. For dummy function parameters return the
+ function type. */
+ if (byref)
+ type = build_reference_type (type);
+
+ return (type);
+}
+
+/* Layout and output debug info for a record type. */
+void
+gfc_finish_type (tree type)
+{
+ tree decl;
+
+ decl = build_decl (TYPE_DECL, NULL_TREE, type);
+ TYPE_STUB_DECL (type) = decl;
+ layout_type (type);
+ rest_of_type_compilation (type, 1);
+ rest_of_decl_compilation (decl, NULL, 1, 0);
+}
+
+/* Add a field of given NAME and TYPE to the context of a UNION_TYPE
+ or RECORD_TYPE pointed to by STYPE. The new field is chained
+ to the fieldlist pointed to by FIELDLIST.
+
+ Returns a pointer to the new field. */
+tree
+gfc_add_field_to_struct (tree *fieldlist, tree context,
+ tree name, tree type)
+{
+ tree decl;
+
+ decl = build_decl (FIELD_DECL, name, type);
+
+ DECL_CONTEXT (decl) = context;
+ DECL_INITIAL (decl) = 0;
+ DECL_ALIGN (decl) = 0;
+ DECL_USER_ALIGN (decl) = 0;
+ TREE_CHAIN (decl) = NULL_TREE;
+ *fieldlist = chainon (*fieldlist, decl);
+
+ return decl;
+}
+
+
+/* Build a tree node for a derived type. */
+static tree
+gfc_get_derived_type (gfc_symbol * derived)
+{
+ tree typenode, field, field_type, fieldlist;
+ gfc_component *c;
+
+ assert (derived && derived->attr.flavor == FL_DERIVED);
+
+ /* derived->backend_decl != 0 means we saw it before, but its
+ component's backend_decl may have not been built. */
+ if (derived->backend_decl)
+ {
+ /* Its component's backend_decl has been built. */
+ if (TYPE_FIELDS (derived->backend_decl))
+ return derived->backend_decl;
+ else
+ typenode = derived->backend_decl;
+ }
+ else
+ {
+ /* We see this derived type first time, so build the type node. */
+ typenode = make_node (RECORD_TYPE);
+ TYPE_NAME (typenode) = get_identifier (derived->name);
+ TYPE_PACKED (typenode) = gfc_option.flag_pack_derived;
+ derived->backend_decl = typenode;
+ }
+
+ /* Build the type member list. Install the newly created RECORD_TYPE
+ node as DECL_CONTEXT of each FIELD_DECL. */
+ fieldlist = NULL_TREE;
+ for (c = derived->components; c; c = c->next)
+ {
+ if (c->ts.type == BT_DERIVED && c->pointer)
+ {
+ if (c->ts.derived->backend_decl)
+ field_type = c->ts.derived->backend_decl;
+ else
+ {
+ /* Build the type node. */
+ field_type = make_node (RECORD_TYPE);
+ TYPE_NAME (field_type) = get_identifier (c->ts.derived->name);
+ TYPE_PACKED (field_type) = gfc_option.flag_pack_derived;
+ c->ts.derived->backend_decl = field_type;
+ }
+ }
+ else
+ {
+ if (c->ts.type == BT_CHARACTER)
+ {
+ /* Evaluate the string length. */
+ gfc_conv_const_charlen (c->ts.cl);
+ assert (c->ts.cl->backend_decl);
+ }
+
+ field_type = gfc_typenode_for_spec (&c->ts);
+ }
+
+ /* This returns an array descriptor type. Initialisation may be
+ required. */
+ if (c->dimension)
+ {
+ if (c->pointer)
+ {
+ /* Pointers to arrays aren't actualy pointer types. The
+ descriptors are seperate, but the data is common. */
+ field_type = gfc_build_array_type (field_type, c->as);
+ }
+ else
+ field_type = gfc_get_nodesc_array_type (field_type, c->as, 3);
+ }
+ else if (c->pointer)
+ field_type = build_pointer_type (field_type);
+
+ field = gfc_add_field_to_struct (&fieldlist, typenode,
+ get_identifier (c->name),
+ field_type);
+
+ DECL_PACKED (field) |= TYPE_PACKED (typenode);
+
+ assert (!c->backend_decl);
+ c->backend_decl = field;
+ }
+
+ /* Now we have the final fieldlist. Record it, then lay out the
+ derived type, including the fields. */
+ TYPE_FIELDS (typenode) = fieldlist;
+
+ gfc_finish_type (typenode);
+
+ derived->backend_decl = typenode;
+
+ return typenode;
+}
+
+int
+gfc_return_by_reference (gfc_symbol * sym)
+{
+ if (!sym->attr.function)
+ return 0;
+
+ assert (sym->attr.function);
+
+ if (sym->result)
+ sym = sym->result;
+
+ if (sym->attr.dimension)
+ return 1;
+
+ if (sym->ts.type == BT_CHARACTER)
+ return 1;
+
+ if (sym->ts.type == BT_DERIVED)
+ gfc_todo_error ("Returning derived types");
+ /* Possibly return derived types by reference. */
+ return 0;
+}
+
+tree
+gfc_get_function_type (gfc_symbol * sym)
+{
+ tree type;
+ tree typelist;
+ gfc_formal_arglist *f;
+ gfc_symbol *arg;
+ int nstr;
+ int alternate_return;
+
+ /* Make sure this symbol is a function or a subroutine. */
+ assert (sym->attr.flavor == FL_PROCEDURE);
+
+ if (sym->backend_decl)
+ return TREE_TYPE (sym->backend_decl);
+
+ nstr = 0;
+ alternate_return = 0;
+ typelist = NULL_TREE;
+ /* Some functions we use an extra parameter for the return value. */
+ if (gfc_return_by_reference (sym))
+ {
+ if (sym->result)
+ arg = sym->result;
+ else
+ arg = sym;
+
+ if (arg->ts.type == BT_CHARACTER)
+ gfc_conv_const_charlen (arg->ts.cl);
+
+ type = gfc_sym_type (arg);
+ if (arg->ts.type == BT_DERIVED
+ || arg->attr.dimension
+ || arg->ts.type == BT_CHARACTER)
+ type = build_reference_type (type);
+
+ typelist = gfc_chainon_list (typelist, type);
+ if (arg->ts.type == BT_CHARACTER)
+ typelist = gfc_chainon_list (typelist, gfc_strlen_type_node);
+ }
+
+ /* Build the argument types for the function */
+ for (f = sym->formal; f; f = f->next)
+ {
+ arg = f->sym;
+ if (arg)
+ {
+ /* Evaluate constant character lengths here so that they can be
+ included in the type. */
+ if (arg->ts.type == BT_CHARACTER)
+ gfc_conv_const_charlen (arg->ts.cl);
+
+ if (arg->attr.flavor == FL_PROCEDURE)
+ {
+ type = gfc_get_function_type (arg);
+ type = build_pointer_type (type);
+ }
+ else
+ type = gfc_sym_type (arg);
+
+ /* Parameter Passing Convention
+
+ We currently pass all parameters by reference.
+ Parameters with INTENT(IN) could be passed by value.
+ The problem arises if a function is called via an implicit
+ prototype. In this situation the INTENT is not known.
+ For this reason all parameters to global functions must be
+ passed by reference. Passing by value would potentialy
+ generate bad code. Worse there would be no way of telling that
+ this code wad bad, except that it would give incorrect results.
+
+ Contained procedures could pass by value as these are never
+ used without an explicit interface, and connot be passed as
+ actual parameters for a dummy procedure.
+ */
+ if (arg->ts.type == BT_CHARACTER)
+ nstr++;
+ typelist = gfc_chainon_list (typelist, type);
+ }
+ else
+ {
+ if (sym->attr.subroutine)
+ alternate_return = 1;
+ }
+ }
+
+ /* Add hidden string length parameters. */
+ while (nstr--)
+ typelist = gfc_chainon_list (typelist, gfc_strlen_type_node);
+
+ typelist = gfc_chainon_list (typelist, void_type_node);
+
+ if (alternate_return)
+ type = integer_type_node;
+ else if (!sym->attr.function || gfc_return_by_reference (sym))
+ type = void_type_node;
+ else
+ type = gfc_sym_type (sym);
+
+ type = build_function_type (type, typelist);
+
+ return type;
+}
+
+/* Routines for getting integer type nodes */
+
+
+/* Return an integer type with BITS bits of precision,
+ that is unsigned if UNSIGNEDP is nonzero, otherwise signed. */
+
+tree
+gfc_type_for_size (unsigned bits, int unsignedp)
+{
+ if (bits == TYPE_PRECISION (integer_type_node))
+ return unsignedp ? unsigned_type_node : integer_type_node;
+
+ if (bits == TYPE_PRECISION (signed_char_type_node))
+ return unsignedp ? unsigned_char_type_node : signed_char_type_node;
+
+ if (bits == TYPE_PRECISION (short_integer_type_node))
+ return unsignedp ? short_unsigned_type_node : short_integer_type_node;
+
+ if (bits == TYPE_PRECISION (long_integer_type_node))
+ return unsignedp ? long_unsigned_type_node : long_integer_type_node;
+
+ if (bits == TYPE_PRECISION (long_long_integer_type_node))
+ return (unsignedp ? long_long_unsigned_type_node
+ : long_long_integer_type_node);
+/*TODO: We currently don't initialise this...
+ if (bits == TYPE_PRECISION (widest_integer_literal_type_node))
+ return (unsignedp ? widest_unsigned_literal_type_node
+ : widest_integer_literal_type_node);*/
+
+ if (bits <= TYPE_PRECISION (intQI_type_node))
+ return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
+
+ if (bits <= TYPE_PRECISION (intHI_type_node))
+ return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
+
+ if (bits <= TYPE_PRECISION (intSI_type_node))
+ return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
+
+ if (bits <= TYPE_PRECISION (intDI_type_node))
+ return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
+
+ return 0;
+}
+
+/* Return a data type that has machine mode MODE.
+ If the mode is an integer,
+ then UNSIGNEDP selects between signed and unsigned types. */
+
+tree
+gfc_type_for_mode (enum machine_mode mode, int unsignedp)
+{
+ if (mode == TYPE_MODE (integer_type_node))
+ return unsignedp ? unsigned_type_node : integer_type_node;
+
+ if (mode == TYPE_MODE (signed_char_type_node))
+ return unsignedp ? unsigned_char_type_node : signed_char_type_node;
+
+ if (mode == TYPE_MODE (short_integer_type_node))
+ return unsignedp ? short_unsigned_type_node : short_integer_type_node;
+
+ if (mode == TYPE_MODE (long_integer_type_node))
+ return unsignedp ? long_unsigned_type_node : long_integer_type_node;
+
+ if (mode == TYPE_MODE (long_long_integer_type_node))
+ return unsignedp ? long_long_unsigned_type_node :
+ long_long_integer_type_node;
+
+/*TODO: see above
+ if (mode == TYPE_MODE (widest_integer_literal_type_node))
+ return unsignedp ? widest_unsigned_literal_type_node
+ : widest_integer_literal_type_node;
+*/
+
+ if (mode == QImode)
+ return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
+
+ if (mode == HImode)
+ return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
+
+ if (mode == SImode)
+ return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
+
+ if (mode == DImode)
+ return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
+
+#if HOST_BITS_PER_WIDE_INT >= 64
+ if (mode == TYPE_MODE (intTI_type_node))
+ return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
+#endif
+
+ if (mode == TYPE_MODE (float_type_node))
+ return float_type_node;
+
+ if (mode == TYPE_MODE (double_type_node))
+ return double_type_node;
+
+ if (mode == TYPE_MODE (long_double_type_node))
+ return long_double_type_node;
+
+ if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
+ return build_pointer_type (char_type_node);
+
+ if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
+ return build_pointer_type (integer_type_node);
+
+#ifdef VECTOR_MODE_SUPPORTED_P
+ if (VECTOR_MODE_SUPPORTED_P (mode))
+ {
+ switch (mode)
+ {
+ case V16QImode:
+ return unsignedp ? unsigned_V16QI_type_node : V16QI_type_node;
+ case V8HImode:
+ return unsignedp ? unsigned_V8HI_type_node : V8HI_type_node;
+ case V4SImode:
+ return unsignedp ? unsigned_V4SI_type_node : V4SI_type_node;
+ case V2DImode:
+ return unsignedp ? unsigned_V2DI_type_node : V2DI_type_node;
+ case V2SImode:
+ return unsignedp ? unsigned_V2SI_type_node : V2SI_type_node;
+ case V4HImode:
+ return unsignedp ? unsigned_V4HI_type_node : V4HI_type_node;
+ case V8QImode:
+ return unsignedp ? unsigned_V8QI_type_node : V8QI_type_node;
+ case V16SFmode:
+ return V16SF_type_node;
+ case V4SFmode:
+ return V4SF_type_node;
+ case V2SFmode:
+ return V2SF_type_node;
+ case V2DFmode:
+ return V2DF_type_node;
+ default:
+ break;
+ }
+ }
+#endif
+
+ return 0;
+}
+
+/* Return an unsigned type the same as TYPE in other respects. */
+tree
+gfc_unsigned_type (tree type)
+{
+ tree type1 = TYPE_MAIN_VARIANT (type);
+ if (type1 == signed_char_type_node || type1 == char_type_node)
+ return unsigned_char_type_node;
+ if (type1 == integer_type_node)
+ return unsigned_type_node;
+ if (type1 == short_integer_type_node)
+ return short_unsigned_type_node;
+ if (type1 == long_integer_type_node)
+ return long_unsigned_type_node;
+ if (type1 == long_long_integer_type_node)
+ return long_long_unsigned_type_node;
+/*TODO :see others
+ if (type1 == widest_integer_literal_type_node)
+ return widest_unsigned_literal_type_node;
+*/
+#if HOST_BITS_PER_WIDE_INT >= 64
+ if (type1 == intTI_type_node)
+ return unsigned_intTI_type_node;
+#endif
+ if (type1 == intDI_type_node)
+ return unsigned_intDI_type_node;
+ if (type1 == intSI_type_node)
+ return unsigned_intSI_type_node;
+ if (type1 == intHI_type_node)
+ return unsigned_intHI_type_node;
+ if (type1 == intQI_type_node)
+ return unsigned_intQI_type_node;
+
+ return gfc_signed_or_unsigned_type (1, type);
+}
+
+/* Return a signed type the same as TYPE in other respects. */
+
+tree
+gfc_signed_type (tree type)
+{
+ tree type1 = TYPE_MAIN_VARIANT (type);
+ if (type1 == unsigned_char_type_node || type1 == char_type_node)
+ return signed_char_type_node;
+ if (type1 == unsigned_type_node)
+ return integer_type_node;
+ if (type1 == short_unsigned_type_node)
+ return short_integer_type_node;
+ if (type1 == long_unsigned_type_node)
+ return long_integer_type_node;
+ if (type1 == long_long_unsigned_type_node)
+ return long_long_integer_type_node;
+/*TODO: see others
+ if (type1 == widest_unsigned_literal_type_node)
+ return widest_integer_literal_type_node;
+*/
+#if HOST_BITS_PER_WIDE_INT >= 64
+ if (type1 == unsigned_intTI_type_node)
+ return intTI_type_node;
+#endif
+ if (type1 == unsigned_intDI_type_node)
+ return intDI_type_node;
+ if (type1 == unsigned_intSI_type_node)
+ return intSI_type_node;
+ if (type1 == unsigned_intHI_type_node)
+ return intHI_type_node;
+ if (type1 == unsigned_intQI_type_node)
+ return intQI_type_node;
+
+ return gfc_signed_or_unsigned_type (0, type);
+}
+
+/* Return a type the same as TYPE except unsigned or
+ signed according to UNSIGNEDP. */
+
+tree
+gfc_signed_or_unsigned_type (int unsignedp, tree type)
+{
+ if (!INTEGRAL_TYPE_P (type) || TYPE_UNSIGNED (type) == unsignedp)
+ return type;
+
+ if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
+ return unsignedp ? unsigned_char_type_node : signed_char_type_node;
+ if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
+ return unsignedp ? unsigned_type_node : integer_type_node;
+ if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
+ return unsignedp ? short_unsigned_type_node : short_integer_type_node;
+ if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
+ return unsignedp ? long_unsigned_type_node : long_integer_type_node;
+ if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
+ return (unsignedp ? long_long_unsigned_type_node
+ : long_long_integer_type_node);
+/*TODO: see others
+ if (TYPE_PRECISION (type) == TYPE_PRECISION (widest_integer_literal_type_node))
+ return (unsignedp ? widest_unsigned_literal_type_node
+ : widest_integer_literal_type_node);
+*/
+#if HOST_BITS_PER_WIDE_INT >= 64
+ if (TYPE_PRECISION (type) == TYPE_PRECISION (intTI_type_node))
+ return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
+#endif
+ if (TYPE_PRECISION (type) == TYPE_PRECISION (intDI_type_node))
+ return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
+ if (TYPE_PRECISION (type) == TYPE_PRECISION (intSI_type_node))
+ return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
+ if (TYPE_PRECISION (type) == TYPE_PRECISION (intHI_type_node))
+ return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
+ if (TYPE_PRECISION (type) == TYPE_PRECISION (intQI_type_node))
+ return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
+
+ return type;
+}
+
+#include "gt-fortran-trans-types.h"
diff --git a/gcc/fortran/trans-types.h b/gcc/fortran/trans-types.h
new file mode 100644
index 00000000000..82eb8574caa
--- /dev/null
+++ b/gcc/fortran/trans-types.h
@@ -0,0 +1,143 @@
+/* Header for Fortran 95 types backend support.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+ and Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#ifndef GFC_BACKEND_H
+#define GFC_BACKEND_H
+
+enum
+{
+ F95_INT1_TYPE,
+ F95_INT2_TYPE,
+ F95_INT4_TYPE,
+ F95_INT8_TYPE,
+ F95_INT16_TYPE,
+ F95_REAL4_TYPE,
+ F95_REAL8_TYPE,
+ F95_REAl16_TYPE,
+ F95_COMPLEX4_TYPE,
+ F95_COMPLEX8_TYPE,
+ F95_COMPLEX16_TYPE,
+ F95_LOGICAL1_TYPE,
+ F95_LOGICAL2_TYPE,
+ F95_LOGICAL4_TYPE,
+ F95_LOGICAL8_TYPE,
+ F95_LOGICAL16_TYPE,
+ F95_CHARACTER1_TYPE,
+ NUM_F95_TYPES
+};
+
+#define GFC_DTYPE_RANK_MASK 0x07
+#define GFC_DTYPE_TYPE_SHIFT 3
+#define GFC_DTYPE_TYPE_MASK 0x38
+#define GFC_DTYPE_SIZE_SHIFT 6
+
+enum
+{
+ GFC_DTYPE_UNKNOWN = 0,
+ GFC_DTYPE_INTEGER,
+ GFC_DTYPE_LOGICAL,
+ GFC_DTYPE_REAL,
+ GFC_DTYPE_COMPLEX,
+ GFC_DTYPE_DERIVED,
+ GFC_DTYPE_CHARACTER
+};
+
+extern GTY(()) tree gfc_type_nodes[NUM_F95_TYPES];
+
+extern GTY(()) tree gfc_array_index_type;
+extern GTY(()) tree ppvoid_type_node;
+extern GTY(()) tree pvoid_type_node;
+extern GTY(()) tree pchar_type_node;
+
+#define gfc_int1_type_node gfc_type_nodes[F95_INT1_TYPE]
+#define gfc_int2_type_node gfc_type_nodes[F95_INT2_TYPE]
+#define gfc_int4_type_node gfc_type_nodes[F95_INT4_TYPE]
+#define gfc_int8_type_node gfc_type_nodes[F95_INT8_TYPE]
+#define gfc_int16_type_node gfc_type_nodes[F95_INT16_TYPE]
+
+#define gfc_real4_type_node gfc_type_nodes[F95_REAL4_TYPE]
+#define gfc_real8_type_node gfc_type_nodes[F95_REAL8_TYPE]
+#define gfc_real16_type_node gfc_type_nodes[F95_REAL16_TYPE]
+
+#define gfc_complex4_type_node gfc_type_nodes[F95_COMPLEX4_TYPE]
+#define gfc_complex8_type_node gfc_type_nodes[F95_COMPLEX8_TYPE]
+#define gfc_complex16_type_node gfc_type_nodes[F95_COMPLEX16_TYPE]
+
+#define gfc_logical1_type_node gfc_type_nodes[F95_LOGICAL1_TYPE]
+#define gfc_logical2_type_node gfc_type_nodes[F95_LOGICAL2_TYPE]
+#define gfc_logical4_type_node gfc_type_nodes[F95_LOGICAL4_TYPE]
+#define gfc_logical8_type_node gfc_type_nodes[F95_LOGICAL8_TYPE]
+#define gfc_logical16_type_node gfc_type_nodes[F95_LOGICAL16_TYPE]
+
+#define gfc_character1_type_node gfc_type_nodes[F95_CHARACTER1_TYPE]
+
+#define gfc_strlen_kind 4
+#define gfc_strlen_type_node gfc_int4_type_node
+
+/* These C-specific types are used while building builtin function decls.
+ For now it doesn't really matter what these are defined to as we don't
+ need any of the builtins that use them. */
+#define intmax_type_node gfc_int8_type_node
+#define string_type_node pchar_type_node
+#define const_string_type_node pchar_type_node
+
+/* be-function.c */
+void gfc_convert_function_code (gfc_namespace *);
+
+/* trans-types.c */
+void gfc_init_types (void);
+
+tree gfc_get_int_type (int);
+tree gfc_get_real_type (int);
+tree gfc_get_complex_type (int);
+tree gfc_get_logical_type (int);
+tree gfc_get_character_type (int, gfc_charlen *);
+
+tree gfc_sym_type (gfc_symbol *);
+tree gfc_typenode_for_spec (gfc_typespec *);
+
+tree gfc_get_function_type (gfc_symbol *);
+
+tree gfc_type_for_size (unsigned, int);
+tree gfc_type_for_mode (enum machine_mode, int);
+tree gfc_unsigned_type (tree);
+tree gfc_signed_type (tree);
+tree gfc_signed_or_unsigned_type (int, tree);
+
+tree gfc_get_element_type (tree);
+tree gfc_get_array_type_bounds (tree, int, tree *, tree *, int);
+tree gfc_get_nodesc_array_type (tree, gfc_array_spec *, int);
+
+/* Add a field of given name and type to a UNION_TYPE or RECORD_TYPE. */
+tree gfc_add_field_to_struct (tree *, tree, tree, tree);
+
+/* Layout and output debugging info for a type. */
+void gfc_finish_type (tree);
+
+/* Some functions have an extra parameter for the return value. */
+int gfc_return_by_reference (gfc_symbol *);
+
+/* Returns true if the array sym does not require a descriptor. */
+int gfc_is_nodesc_array (gfc_symbol *);
+
+#endif
diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c
new file mode 100644
index 00000000000..39a63415539
--- /dev/null
+++ b/gcc/fortran/trans.c
@@ -0,0 +1,662 @@
+/* Code translation -- generate GCC trees from gfc_code.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Paul Brook
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "tree-gimple.h"
+#include <stdio.h>
+#include "ggc.h"
+#include "toplev.h"
+#include "defaults.h"
+#include "real.h"
+#include <gmp.h>
+#include <assert.h>
+#include "gfortran.h"
+#include "trans.h"
+#include "trans-stmt.h"
+#include "trans-array.h"
+#include "trans-types.h"
+#include "trans-const.h"
+
+/* Naming convention for backend interface code:
+
+ gfc_trans_* translate gfc_code into STMT trees.
+
+ gfc_conv_* expression conversion
+
+ gfc_get_* get a backend tree representation of a decl or type */
+
+static gfc_file *gfc_current_backend_file;
+
+
+/* Advance along TREE_CHAIN n times. */
+
+tree
+gfc_advance_chain (tree t, int n)
+{
+ for (; n > 0; n--)
+ {
+ assert (t != NULL_TREE);
+ t = TREE_CHAIN (t);
+ }
+ return t;
+}
+
+
+/* Wrap a node in a TREE_LIST node and add it to the end of a list. */
+
+tree
+gfc_chainon_list (tree list, tree add)
+{
+ tree l;
+
+ l = tree_cons (NULL_TREE, add, NULL_TREE);
+
+ return chainon (list, l);
+}
+
+
+/* Strip off a legitimate source ending from the input
+ string NAME of length LEN. */
+
+static inline void
+remove_suffix (char *name, int len)
+{
+ int i;
+
+ for (i = 2; i < 8 && len > i; i++)
+ {
+ if (name[len - i] == '.')
+ {
+ name[len - i] = '\0';
+ break;
+ }
+ }
+}
+
+
+/* Creates a variable declaration with a given TYPE. */
+
+tree
+gfc_create_var_np (tree type, const char *prefix)
+{
+ return create_tmp_var_raw (type, prefix);
+}
+
+
+/* Like above, but also adds it to the current scope. */
+
+tree
+gfc_create_var (tree type, const char *prefix)
+{
+ tree tmp;
+
+ tmp = gfc_create_var_np (type, prefix);
+
+ pushdecl (tmp);
+
+ return tmp;
+}
+
+
+/* If the an expression is not constant, evaluate it now. We assign the
+ result of the expression to an artificially created variable VAR, and
+ return a pointer to the VAR_DECL node for this variable. */
+
+tree
+gfc_evaluate_now (tree expr, stmtblock_t * pblock)
+{
+ tree var;
+
+ if (TREE_CODE_CLASS (TREE_CODE (expr)) == 'c')
+ return expr;
+
+ var = gfc_create_var (TREE_TYPE (expr), NULL);
+ gfc_add_modify_expr (pblock, var, expr);
+
+ return var;
+}
+
+
+/* Build a MODIFY_EXPR node and add it to a given statement block PBLOCK.
+ A MODIFY_EXPR is an assignment: LHS <- RHS. */
+
+void
+gfc_add_modify_expr (stmtblock_t * pblock, tree lhs, tree rhs)
+{
+ tree tmp;
+
+ tmp = fold (build_v (MODIFY_EXPR, lhs, rhs));
+ gfc_add_expr_to_block (pblock, tmp);
+}
+
+
+/* Create a new scope/binding level and initialize a block. Care must be
+ taken when translating expessions as any temporaries will be placed in
+ the innermost scope. */
+
+void
+gfc_start_block (stmtblock_t * block)
+{
+ /* Start a new binding level. */
+ pushlevel (0);
+ block->has_scope = 1;
+
+ /* The block is empty. */
+ block->head = NULL_TREE;
+}
+
+
+/* Initialize a block without creating a new scope. */
+
+void
+gfc_init_block (stmtblock_t * block)
+{
+ block->head = NULL_TREE;
+ block->has_scope = 0;
+}
+
+
+/* Sometimes we create a scope but it turns out that we don't actually
+ need it. This function merges the scope of BLOCK with its parent.
+ Only variable decls will be merged, you still need to add the code. */
+
+void
+gfc_merge_block_scope (stmtblock_t * block)
+{
+ tree decl;
+ tree next;
+
+ assert (block->has_scope);
+ block->has_scope = 0;
+
+ /* Remember the decls in this scope. */
+ decl = getdecls ();
+ poplevel (0, 0, 0);
+
+ /* Add them to the parent scope. */
+ while (decl != NULL_TREE)
+ {
+ next = TREE_CHAIN (decl);
+ TREE_CHAIN (decl) = NULL_TREE;
+
+ pushdecl (decl);
+ decl = next;
+ }
+}
+
+
+/* Finish a scope containing a block of statements. */
+
+tree
+gfc_finish_block (stmtblock_t * stmtblock)
+{
+ tree decl;
+ tree expr;
+ tree block;
+
+ expr = rationalize_compound_expr (stmtblock->head);
+ stmtblock->head = NULL_TREE;
+
+ if (stmtblock->has_scope)
+ {
+ decl = getdecls ();
+
+ if (decl)
+ {
+ block = poplevel (1, 0, 0);
+ expr = build_v (BIND_EXPR, decl, expr, block);
+ }
+ else
+ poplevel (0, 0, 0);
+ }
+
+ return expr;
+}
+
+
+/* Build an ADDR_EXPR and cast the result to TYPE. If TYPE is NULL, the
+ natural type is used. */
+
+tree
+gfc_build_addr_expr (tree type, tree t)
+{
+ tree base_type = TREE_TYPE (t);
+ tree natural_type;
+
+ if (type && POINTER_TYPE_P (type)
+ && TREE_CODE (base_type) == ARRAY_TYPE
+ && TYPE_MAIN_VARIANT (TREE_TYPE (type))
+ == TYPE_MAIN_VARIANT (TREE_TYPE (base_type)))
+ natural_type = type;
+ else
+ natural_type = build_pointer_type (base_type);
+
+ if (TREE_CODE (t) == INDIRECT_REF)
+ {
+ if (!type)
+ type = natural_type;
+ t = TREE_OPERAND (t, 0);
+ natural_type = TREE_TYPE (t);
+ }
+ else
+ {
+ if (DECL_P (t))
+ TREE_ADDRESSABLE (t) = 1;
+ t = build1 (ADDR_EXPR, natural_type, t);
+ }
+
+ if (type && natural_type != type)
+ t = convert (type, t);
+
+ return t;
+}
+
+
+/* Build an INDIRECT_REF with its natural type. */
+
+tree
+gfc_build_indirect_ref (tree t)
+{
+ tree type = TREE_TYPE (t);
+ if (!POINTER_TYPE_P (type))
+ abort ();
+ type = TREE_TYPE (type);
+
+ if (TREE_CODE (t) == ADDR_EXPR)
+ return TREE_OPERAND (t, 0);
+ else
+ return build1 (INDIRECT_REF, type, t);
+}
+
+
+/* Build an ARRAY_REF with its natural type. */
+
+tree
+gfc_build_array_ref (tree base, tree offset)
+{
+ tree type = TREE_TYPE (base);
+ if (TREE_CODE (type) != ARRAY_TYPE)
+ abort ();
+ type = TREE_TYPE (type);
+
+ if (DECL_P (base))
+ TREE_ADDRESSABLE (base) = 1;
+
+ return build (ARRAY_REF, type, base, offset);
+}
+
+
+/* Given a funcion declaration FNDECL and an argument list ARGLIST,
+ build a CALL_EXPR. */
+
+tree
+gfc_build_function_call (tree fndecl, tree arglist)
+{
+ tree fn;
+ tree call;
+
+ fn = gfc_build_addr_expr (NULL, fndecl);
+ call = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), fn, arglist, NULL);
+ TREE_SIDE_EFFECTS (call) = 1;
+
+ return call;
+}
+
+
+/* Generate a runtime error if COND is true. */
+
+void
+gfc_trans_runtime_check (tree cond, tree msg, stmtblock_t * pblock)
+{
+ stmtblock_t block;
+ tree body;
+ tree tmp;
+ tree args;
+
+ cond = fold (cond);
+
+ if (integer_zerop (cond))
+ return;
+
+ /* The code to generate the error. */
+ gfc_start_block (&block);
+
+ assert (TREE_CODE (msg) == STRING_CST);
+
+ TREE_USED (msg) = 1;
+
+ tmp = gfc_build_addr_expr (pchar_type_node, msg);
+ args = gfc_chainon_list (NULL_TREE, tmp);
+
+ tmp = gfc_build_addr_expr (pchar_type_node, gfc_strconst_current_filename);
+ args = gfc_chainon_list (args, tmp);
+
+ tmp = build_int_2 (input_line, 0);
+ args = gfc_chainon_list (args, tmp);
+
+ tmp = gfc_build_function_call (gfor_fndecl_runtime_error, args);
+ gfc_add_expr_to_block (&block, tmp);
+
+ body = gfc_finish_block (&block);
+
+ if (integer_onep (cond))
+ {
+ gfc_add_expr_to_block (pblock, body);
+ }
+ else
+ {
+ /* Tell the compiler that this isn't likley. */
+ tmp = gfc_chainon_list (NULL_TREE, cond);
+ tmp = gfc_chainon_list (tmp, integer_zero_node);
+ cond = gfc_build_function_call (built_in_decls[BUILT_IN_EXPECT], tmp);
+
+ tmp = build_v (COND_EXPR, cond, body, build_empty_stmt ());
+ gfc_add_expr_to_block (pblock, tmp);
+ }
+}
+
+
+/* Add a statement to a bock. */
+
+void
+gfc_add_expr_to_block (stmtblock_t * block, tree expr)
+{
+ assert (block);
+
+ if (expr == NULL_TREE || IS_EMPTY_STMT (expr))
+ return;
+
+ expr = fold (expr);
+ if (block->head)
+ block->head = build_v (COMPOUND_EXPR, block->head, expr);
+ else
+ block->head = expr;
+}
+
+
+/* Add a block the end of a block. */
+
+void
+gfc_add_block_to_block (stmtblock_t * block, stmtblock_t * append)
+{
+ assert (append);
+ assert (!append->has_scope);
+
+ gfc_add_expr_to_block (block, append->head);
+ append->head = NULL_TREE;
+}
+
+
+/* Get the current locus. The structure may not be complete, and should
+ only be used with gfc_set_current_locus. */
+
+void
+gfc_get_backend_locus (locus * loc)
+{
+ loc->line = input_line - 1;
+ loc->file = gfc_current_backend_file;
+}
+
+
+/* Set the current locus. */
+
+void
+gfc_set_backend_locus (locus * loc)
+{
+ input_line = loc->line + 1;
+ gfc_current_backend_file = loc->file;
+ input_filename = loc->file->filename;
+}
+
+
+/* Translate an executable statement. */
+
+tree
+gfc_trans_code (gfc_code * code)
+{
+ stmtblock_t block;
+ tree res;
+
+ if (!code)
+ return build_empty_stmt ();
+
+ gfc_start_block (&block);
+
+ /* Translate statements one by one to GIMPLE trees until we reach
+ the end of this gfc_code branch. */
+ for (; code; code = code->next)
+ {
+ gfc_set_backend_locus (&code->loc);
+
+ if (code->here != 0)
+ {
+ res = gfc_trans_label_here (code);
+ gfc_add_expr_to_block (&block, res);
+ }
+
+ switch (code->op)
+ {
+ case EXEC_NOP:
+ res = NULL_TREE;
+ break;
+
+ case EXEC_ASSIGN:
+ res = gfc_trans_assign (code);
+ break;
+
+ case EXEC_LABEL_ASSIGN:
+ res = gfc_trans_label_assign (code);
+ break;
+
+ case EXEC_POINTER_ASSIGN:
+ res = gfc_trans_pointer_assign (code);
+ break;
+
+ case EXEC_CONTINUE:
+ res = NULL_TREE;
+ break;
+
+ case EXEC_CYCLE:
+ res = gfc_trans_cycle (code);
+ break;
+
+ case EXEC_EXIT:
+ res = gfc_trans_exit (code);
+ break;
+
+ case EXEC_GOTO:
+ res = gfc_trans_goto (code);
+ break;
+
+ case EXEC_PAUSE:
+ res = gfc_trans_pause (code);
+ break;
+
+ case EXEC_STOP:
+ res = gfc_trans_stop (code);
+ break;
+
+ case EXEC_CALL:
+ res = gfc_trans_call (code);
+ break;
+
+ case EXEC_RETURN:
+ res = gfc_trans_return (code);
+ break;
+
+ case EXEC_IF:
+ res = gfc_trans_if (code);
+ break;
+
+ case EXEC_ARITHMETIC_IF:
+ res = gfc_trans_arithmetic_if (code);
+ break;
+
+ case EXEC_DO:
+ res = gfc_trans_do (code);
+ break;
+
+ case EXEC_DO_WHILE:
+ res = gfc_trans_do_while (code);
+ break;
+
+ case EXEC_SELECT:
+ res = gfc_trans_select (code);
+ break;
+
+ case EXEC_FORALL:
+ res = gfc_trans_forall (code);
+ break;
+
+ case EXEC_WHERE:
+ res = gfc_trans_where (code);
+ break;
+
+ case EXEC_ALLOCATE:
+ res = gfc_trans_allocate (code);
+ break;
+
+ case EXEC_DEALLOCATE:
+ res = gfc_trans_deallocate (code);
+ break;
+
+ case EXEC_OPEN:
+ res = gfc_trans_open (code);
+ break;
+
+ case EXEC_CLOSE:
+ res = gfc_trans_close (code);
+ break;
+
+ case EXEC_READ:
+ res = gfc_trans_read (code);
+ break;
+
+ case EXEC_WRITE:
+ res = gfc_trans_write (code);
+ break;
+
+ case EXEC_IOLENGTH:
+ res = gfc_trans_iolength (code);
+ break;
+
+ case EXEC_BACKSPACE:
+ res = gfc_trans_backspace (code);
+ break;
+
+ case EXEC_ENDFILE:
+ res = gfc_trans_endfile (code);
+ break;
+
+ case EXEC_INQUIRE:
+ res = gfc_trans_inquire (code);
+ break;
+
+ case EXEC_REWIND:
+ res = gfc_trans_rewind (code);
+ break;
+
+ case EXEC_TRANSFER:
+ res = gfc_trans_transfer (code);
+ break;
+
+ case EXEC_DT_END:
+ res = gfc_trans_dt_end (code);
+ break;
+
+ default:
+ internal_error ("gfc_trans_code(): Bad statement code");
+ }
+
+ if (res != NULL_TREE && ! IS_EMPTY_STMT (res))
+ {
+ annotate_with_locus (res, input_location);
+ /* Add the new statemment to the block. */
+ gfc_add_expr_to_block (&block, res);
+ }
+ }
+
+ /* Return the finished block. */
+ return gfc_finish_block (&block);
+}
+
+
+/* This function is called after a complete program unit has been parsed
+ and resolved. */
+
+void
+gfc_generate_code (gfc_namespace * ns)
+{
+ gfc_symbol *main_program = NULL;
+ symbol_attribute attr;
+
+ /* Main program subroutine. */
+ if (!ns->proc_name)
+ {
+ /* Lots of things get upset if a subroutine doesn't have a symbol, so we
+ make one now. Hopefully we've set all the required fields. */
+ gfc_get_symbol ("MAIN__", ns, &main_program);
+ gfc_clear_attr (&attr);
+ attr.flavor = FL_PROCEDURE;
+ attr.proc = PROC_UNKNOWN;
+ attr.subroutine = 1;
+ attr.access = ACCESS_PUBLIC;
+ main_program->attr = attr;
+ ns->proc_name = main_program;
+ gfc_commit_symbols ();
+ }
+
+ gfc_generate_function_code (ns);
+}
+
+
+/* This function is called after a complete module has been parsed
+ and resolved. */
+
+void
+gfc_generate_module_code (gfc_namespace * ns)
+{
+ gfc_namespace *n;
+
+ gfc_generate_module_vars (ns);
+
+ /* We need to generate all module function prototypes first, to allow
+ sibling calls. */
+ for (n = ns->contained; n; n = n->sibling)
+ {
+ if (!n->proc_name)
+ continue;
+
+ gfc_build_function_decl (n->proc_name);
+ }
+
+ for (n = ns->contained; n; n = n->sibling)
+ {
+ if (!n->proc_name)
+ continue;
+
+ gfc_generate_function_code (n);
+ }
+}
+
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
new file mode 100644
index 00000000000..a9e2e7bca82
--- /dev/null
+++ b/gcc/fortran/trans.h
@@ -0,0 +1,534 @@
+/* Header for code translation functions
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Paul Brook
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#ifndef GFC_TRANS_H
+#define GFC_TRANS_H
+
+/* Mangled symbols take the form __module__name. */
+#define GFC_MAX_MANGLED_SYMBOL_LEN (GFC_MAX_SYMBOL_LEN*2+4)
+
+/* Struct for holding a block of statements. It should be treated as an
+ opaque entity and not modified directly. This allows us to change the
+ underlying representation of statement lists. */
+typedef struct
+{
+ tree head;
+ int has_scope:1;
+}
+stmtblock_t;
+
+/* a simplified expresson */
+typedef struct gfc_se
+{
+ /* Code blocks to be executed before and after using the value. */
+ stmtblock_t pre;
+ stmtblock_t post;
+
+ /* the result of the expression */
+ tree expr;
+
+ /* The length of a character string value. */
+ tree string_length;
+
+ /* If set gfc_conv_variable will return an expression for the array
+ descriptor. When set, want_pointer should also be set.
+ If not set scalarizing variables will be substituted. */
+ unsigned descriptor_only:1;
+
+ /* When this is set gfc_conv_expr returns the address of a variable. Only
+ applies to EXPR_VARIABLE nodes.
+ Also used by gfc_conv_array_parameter. When set this indicates a pointer
+ to the descriptor should be returned, rather than the descriptor itself.
+ */
+ unsigned want_pointer:1;
+
+ /* An array function call returning without a temporary. Also used for array
+ pointer assignments. */
+ unsigned direct_byref:1;
+
+ /* Ignore absent optional arguments. Used for some intrinsics. */
+ unsigned ignore_optional:1;
+
+ /* Scalarization parameters. */
+ struct gfc_se *parent;
+ struct gfc_ss *ss;
+ struct gfc_loopinfo *loop;
+}
+gfc_se;
+
+
+/* Scalarisation State chain. Created by walking an expression tree before
+ creating the scalarization loops. Then passed as part of a gfc_se structure
+ to translate the expression inside the loop. Note that these chains are
+ terminated by gfc_se_terminator, not NULL. A NULL pointer in a gfc_se
+ indicates to gfc_conv_* that this is a scalar expression.
+ Note that some member arrays correspond to scalarizer rank and others
+ are the variable rank. */
+
+typedef struct gfc_ss_info
+{
+ int dimen;
+ /* The ref that holds information on this section. */
+ gfc_ref *ref;
+ /* The descriptor of this array. */
+ tree descriptor;
+ /* holds the pointer to the data array. */
+ tree data;
+ /* To move some of the array index calculation out of the innermost loop. */
+ tree offset;
+ tree saved_offset;
+ tree stride0;
+ /* Holds the SS for a subscript. Indexed by actual dimension. */
+ struct gfc_ss *subscript[GFC_MAX_DIMENSIONS];
+
+ /* stride and delta are used to access this inside a scalarization loop.
+ start is used in the calculation of these. Indexed by scalarizer
+ dimension. */
+ tree start[GFC_MAX_DIMENSIONS];
+ tree stride[GFC_MAX_DIMENSIONS];
+ tree delta[GFC_MAX_DIMENSIONS];
+
+ /* Translation from scalariser dimensions to actual dimensions.
+ actual = dim[scalarizer] */
+ int dim[GFC_MAX_DIMENSIONS];
+}
+gfc_ss_info;
+
+typedef enum
+{
+ /* A scalar value. This will be evaluated before entering the
+ scalarization loop. */
+ GFC_SS_SCALAR,
+
+ /* Like GFC_SS_SCALAR except it evaluates a pointer the the expression.
+ Used for elemental function parameters. */
+ GFC_SS_REFERENCE,
+
+ /* An array section. Scalarization indices will be substituted during
+ expression translation. */
+ GFC_SS_SECTION,
+
+ /* A non-elemental function call returning an array. The call is executed
+ before entering the scalarization loop, storing the result in a
+ temporary. This temporary is then used inside the scalarization loop.
+ Simple assignments, eg. a(:) = fn() are handles without a temporary
+ as a special case. */
+ GFC_SS_FUNCTION,
+
+ /* An array constructor. The current implementation is sub-optimal in
+ many cases. It allocated a temporary, assigns the values to it, then
+ uses this temporary inside the scalarization loop. */
+ GFC_SS_CONSTRUCTOR,
+
+ /* A vector subscript. Only used as the SS chain for a subscript.
+ Similar int format to a GFC_SS_SECTION. */
+ GFC_SS_VECTOR,
+
+ /* A temporary array allocated by the scalarizer. Its rank can be less
+ than that of the assignment expression. */
+ GFC_SS_TEMP,
+
+ /* An intrinsic function call. Many intrinsic functions which map directly
+ to library calls are created as GFC_SS_FUNCTION nodes. */
+ GFC_SS_INTRINSIC
+}
+gfc_ss_type;
+
+/* SS structures can only belong to a single loopinfo. They must be added
+ otherwise they will not get freed. */
+typedef struct gfc_ss
+{
+ gfc_ss_type type;
+ gfc_expr *expr;
+ union
+ {
+ /* If type is GFC_SS_SCALAR or GFC_SS_REFERENCE. */
+ struct
+ {
+ tree expr;
+ tree string_length;
+ }
+ scalar;
+
+ /* GFC_SS_TEMP. */
+ struct
+ {
+ /* The rank of the temporary. May be less than the rank of the
+ assigned expression. */
+ int dimen;
+ tree type;
+ tree string_length;
+ }
+ temp;
+ /* All other types. */
+ gfc_ss_info info;
+ }
+ data;
+
+ /* All the SS in a loop and linked through loop_chain. The SS for an
+ expression are linked by the next pointer. */
+ struct gfc_ss *loop_chain;
+ struct gfc_ss *next;
+
+ /* This is used by assignments requiring teporaries. The bits specify which
+ loops the terms appear in. This will be 1 for the RHS expressions,
+ 2 for the LHS expressions, and 3(=1|2) for the temporary. */
+ unsigned useflags:2;
+}
+gfc_ss;
+#define gfc_get_ss() gfc_getmem(sizeof(gfc_ss))
+
+/* The contents of this aren't actualy used. A NULL SS chain indicates a
+ scalar expression, so this pointer is used to terminate SS chains. */
+extern gfc_ss * const gfc_ss_terminator;
+
+/* Holds information about an expression while it is being scalarized. */
+typedef struct gfc_loopinfo
+{
+ stmtblock_t pre;
+ stmtblock_t post;
+
+ int dimen;
+
+ /* All the SS involved with this loop. */
+ gfc_ss *ss;
+ /* The SS describing the teporary used in an assignment. */
+ gfc_ss *temp_ss;
+
+ /* The scalarization loop index variables. */
+ tree loopvar[GFC_MAX_DIMENSIONS];
+
+ /* The bounds of the scalarization loops. */
+ tree from[GFC_MAX_DIMENSIONS];
+ tree to[GFC_MAX_DIMENSIONS];
+ gfc_ss *specloop[GFC_MAX_DIMENSIONS];
+
+ /* The code member contains the code for the body of the next outer loop. */
+ stmtblock_t code[GFC_MAX_DIMENSIONS];
+
+ /* Order in which the dimensions should be looped, innermost first. */
+ int order[GFC_MAX_DIMENSIONS];
+
+ /* The number of dimensions for which a temporary is used. */
+ int temp_dim;
+
+ /* If set we don't need the loop variables. */
+ unsigned array_parameter:1;
+}
+gfc_loopinfo;
+
+/* Advance the SS chain to the next term. */
+void gfc_advance_se_ss_chain (gfc_se *);
+
+/* Call this to initialise a gfc_se structure before use
+ first parameter is structure to initialise, second is
+ parent to get scalarization data from, or NULL. */
+void gfc_init_se (gfc_se *, gfc_se *);
+
+/* Create an artificial variable decl and add it to the current scope. */
+tree gfc_create_var (tree, const char *);
+/* Like above but doesn't add it to the current scope. */
+tree gfc_create_var_np (tree, const char *);
+
+/* Store the result of an expression in a temp variable so it can be used
+ repeatedly even if the original changes */
+void gfc_make_safe_expr (gfc_se * se);
+
+/* Makes sure se is suitable for passing as a function string parameter. */
+void gfc_conv_string_parameter (gfc_se * se);
+
+/* Add an item to the end of TREE_LIST. */
+tree gfc_chainon_list (tree, tree);
+
+/* When using the gfc_conv_* make sure you understand what they do, ie.
+ when a POST chain may be created, and what the retured expression may be
+ used for. Note that character strings have special handling. This
+ should not be a problem as most statements/operations only deal with
+ numeric/logical types. */
+
+/* Entry point for expression translation. */
+void gfc_conv_expr (gfc_se * se, gfc_expr * expr);
+/* Like gfc_conv_expr, but the POST block is guaranteed to be empty for
+ numeric expressions. */
+void gfc_conv_expr_val (gfc_se * se, gfc_expr * expr);
+/* Like gfc_conv_expr_val, but the value is also suitable for use in the lhs of
+ an assignment. */
+void gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr);
+/* Converts an expression so that it can be passed be reference. */
+void gfc_conv_expr_reference (gfc_se * se, gfc_expr *);
+/* Equivalent to convert(type, gfc_conv_expr_val(se, expr)). */
+void gfc_conv_expr_type (gfc_se * se, gfc_expr *, tree);
+/* If the value is not constant, Create a temporary and copy the value. */
+tree gfc_evaluate_now (tree, stmtblock_t *);
+
+/* Intrinsic function handling. */
+void gfc_conv_intrinsic_function (gfc_se *, gfc_expr *);
+
+/* Does an intrinsic map directly to an external library call. */
+int gfc_is_intrinsic_libcall (gfc_expr *);
+
+/* Also used to CALL subroutines. */
+void gfc_conv_function_call (gfc_se *, gfc_symbol *, gfc_actual_arglist *);
+/* gfc_trans_* shouldn't call push/poplevel, use gfc_push/pop_scope */
+
+/* Generate code for a scalar assignment. */
+tree gfc_trans_scalar_assign (gfc_se *, gfc_se *, bt);
+
+/* Translate COMMON blocks. */
+void gfc_trans_common (gfc_namespace *);
+
+/* Translate a derived type constructor. */
+void gfc_conv_structure (gfc_se *, gfc_expr *, int);
+
+/* Return an expression which determines if a dummy parameter is present. */
+tree gfc_conv_expr_present (gfc_symbol *);
+
+/* Generate code to allocate a string temporary. */
+tree gfc_conv_string_tmp (gfc_se *, tree, tree);
+/* Initialize a string length variable. */
+void gfc_trans_init_string_length (gfc_charlen *, stmtblock_t *);
+
+/* Add an expression to the end of a block. */
+void gfc_add_expr_to_block (stmtblock_t *, tree);
+/* Add a block to the end of a block. */
+void gfc_add_block_to_block (stmtblock_t *, stmtblock_t *);
+/* Add a MODIFY_EXPR to a block. */
+void gfc_add_modify_expr (stmtblock_t *, tree, tree);
+
+/* Initialize a statement block. */
+void gfc_init_block (stmtblock_t *);
+/* Start a new satement block. Like gfc_init_block but also starts a new
+ variable scope. */
+void gfc_start_block (stmtblock_t *);
+/* Finish a statement block. Also closes the scope if the block was created
+ with gfc_start_block. */
+tree gfc_finish_block (stmtblock_t *);
+/* Merge the scope of a block with its parent. */
+void gfc_merge_block_scope (stmtblock_t * block);
+
+/* Return the backend label decl. */
+tree gfc_get_label_decl (gfc_st_label *);
+
+/* Return the decl for an external function. */
+tree gfc_get_extern_function_decl (gfc_symbol *);
+
+/* Return the decl for a function. */
+tree gfc_get_function_decl (gfc_symbol *);
+
+/* Build a CALL_EXPR. */
+tree gfc_build_function_call (tree, tree);
+
+/* Build an ADDR_EXPR. */
+tree gfc_build_addr_expr (tree, tree);
+
+/* Build an INDIRECT_REF. */
+tree gfc_build_indirect_ref (tree);
+
+/* Build an ARRAY_REF. */
+tree gfc_build_array_ref (tree, tree);
+
+/* Creates an label. Decl is artificial if label_id == NULL_TREE. */
+tree gfc_build_label_decl (tree);
+
+/* Return the decl used to hold the function return value.
+ Do not use if the function has an explicit result variable. */
+tree gfc_get_fake_result_decl (gfc_symbol *);
+
+/* Get the return label for the current function. */
+tree gfc_get_return_label (void);
+
+/* Add a decl to the binding level for the current function. */
+void gfc_add_decl_to_function (tree);
+
+/* Make prototypes for runtime library functions. */
+void gfc_build_builtin_function_decls (void);
+
+/* Return the variable decl for a symbol. */
+tree gfc_get_symbol_decl (gfc_symbol *);
+
+/* Allocate the lang-spcific part of a decl node. */
+void gfc_allocate_lang_decl (tree);
+
+/* Advance along a TREE_CHAIN. */
+tree gfc_advance_chain (tree, int);
+
+/* Create a decl for a function. */
+void gfc_build_function_decl (gfc_symbol *);
+/* Generate the code for a function. */
+void gfc_generate_function_code (gfc_namespace *);
+/* Output a decl for a module variable. */
+void gfc_generate_module_vars (gfc_namespace *);
+
+/* Get and set the current location. */
+void gfc_set_backend_locus (locus *);
+void gfc_get_backend_locus (locus *);
+
+/* Handle static constructor functions. */
+extern GTY(()) tree gfc_static_ctors;
+void gfc_generate_constructors (void);
+
+/* Generate a runtime error check. */
+void gfc_trans_runtime_check (tree, tree, stmtblock_t *);
+
+/* Generate code for an assigment, includes scalarization. */
+tree gfc_trans_assignment (gfc_expr *, gfc_expr *);
+
+/* Generate code for an pointer assignment. */
+tree gfc_trans_pointer_assignment (gfc_expr *, gfc_expr *);
+
+/* Initialize function decls for library functions. */
+void gfc_build_intrinsic_lib_fndecls (void);
+/* Create function decls for IO library functions. */
+void gfc_build_io_library_fndecls (void);
+/* Build a function decl for a library function. */
+tree gfc_build_library_function_decl (tree, tree, int, ...);
+
+/* somewhere! */
+tree pushdecl (tree);
+tree pushdecl_top_level (tree);
+void pushlevel (int);
+tree poplevel (int, int, int);
+tree getdecls (void);
+tree gfc_truthvalue_conversion (tree);
+
+/* Runtime library function decls. */
+extern GTY(()) tree gfor_fndecl_internal_malloc;
+extern GTY(()) tree gfor_fndecl_internal_malloc64;
+extern GTY(()) tree gfor_fndecl_internal_free;
+extern GTY(()) tree gfor_fndecl_allocate;
+extern GTY(()) tree gfor_fndecl_allocate64;
+extern GTY(()) tree gfor_fndecl_deallocate;
+extern GTY(()) tree gfor_fndecl_pause_numeric;
+extern GTY(()) tree gfor_fndecl_pause_string;
+extern GTY(()) tree gfor_fndecl_stop_numeric;
+extern GTY(()) tree gfor_fndecl_stop_string;
+extern GTY(()) tree gfor_fndecl_select_string;
+extern GTY(()) tree gfor_fndecl_runtime_error;
+extern GTY(()) tree gfor_fndecl_in_pack;
+extern GTY(()) tree gfor_fndecl_in_unpack;
+extern GTY(()) tree gfor_fndecl_associated;
+
+/* Math functions. Many other math functions are handled in
+ trans-intrinsic.c. */
+extern GTY(()) tree gfor_fndecl_math_powf;
+extern GTY(()) tree gfor_fndecl_math_pow;
+extern GTY(()) tree gfor_fndecl_math_cpowf;
+extern GTY(()) tree gfor_fndecl_math_cpow;
+extern GTY(()) tree gfor_fndecl_math_cabsf;
+extern GTY(()) tree gfor_fndecl_math_cabs;
+extern GTY(()) tree gfor_fndecl_math_sign4;
+extern GTY(()) tree gfor_fndecl_math_sign8;
+extern GTY(()) tree gfor_fndecl_math_ishftc4;
+extern GTY(()) tree gfor_fndecl_math_ishftc8;
+extern GTY(()) tree gfor_fndecl_math_exponent4;
+extern GTY(()) tree gfor_fndecl_math_exponent8;
+
+/* String functions. */
+extern GTY(()) tree gfor_fndecl_copy_string;
+extern GTY(()) tree gfor_fndecl_compare_string;
+extern GTY(()) tree gfor_fndecl_concat_string;
+extern GTY(()) tree gfor_fndecl_string_len_trim;
+extern GTY(()) tree gfor_fndecl_string_index;
+extern GTY(()) tree gfor_fndecl_string_scan;
+extern GTY(()) tree gfor_fndecl_string_verify;
+extern GTY(()) tree gfor_fndecl_string_trim;
+extern GTY(()) tree gfor_fndecl_string_repeat;
+extern GTY(()) tree gfor_fndecl_adjustl;
+extern GTY(()) tree gfor_fndecl_adjustr;
+
+/* Other misc. runtime library functions. */
+extern GTY(()) tree gfor_fndecl_size0;
+extern GTY(()) tree gfor_fndecl_size1;
+
+/* Implemented in FORTRAN. */
+extern GTY(()) tree gfor_fndecl_si_kind;
+extern GTY(()) tree gfor_fndecl_sr_kind;
+
+
+/* True if node is an integer constant. */
+#define INTEGER_CST_P(node) (TREE_CODE(node) == INTEGER_CST)
+
+/* G95-specific declaration information. */
+
+/* Array types only. */
+struct lang_type GTY(())
+{
+ int rank;
+ tree lbound[GFC_MAX_DIMENSIONS];
+ tree ubound[GFC_MAX_DIMENSIONS];
+ tree stride[GFC_MAX_DIMENSIONS];
+ tree size;
+ tree offset;
+ tree dtype;
+ tree dataptr_type;
+};
+
+struct lang_decl GTY(())
+{
+ /* Dummy variables. */
+ tree saved_descriptor;
+ /* Assigned integer nodes. Stringlength is the IO format string's length.
+ Addr is the address of the string or the target label. Stringlength is
+ initialized to -2 and assiged to -1 when addr is assigned to the
+ address of target label. */
+ tree stringlen;
+ tree addr;
+};
+
+
+#define GFC_DECL_ASSIGN_ADDR(node) DECL_LANG_SPECIFIC(node)->addr
+#define GFC_DECL_STRING_LEN(node) DECL_LANG_SPECIFIC(node)->stringlen
+#define GFC_DECL_SAVED_DESCRIPTOR(node) \
+ (DECL_LANG_SPECIFIC(node)->saved_descriptor)
+#define GFC_DECL_PACKED_ARRAY(node) DECL_LANG_FLAG_0(node)
+#define GFC_DECL_PARTIAL_PACKED_ARRAY(node) DECL_LANG_FLAG_1(node)
+#define GFC_DECL_ASSIGN(node) DECL_LANG_FLAG_2(node)
+
+/* An array descriptor. */
+#define GFC_DESCRIPTOR_TYPE_P(node) TYPE_LANG_FLAG_1(node)
+/* An array without a descriptor. */
+#define GFC_ARRAY_TYPE_P(node) TYPE_LANG_FLAG_2(node)
+/* The GFC_TYPE_ARRAY_* members are present in both descriptor and
+ descriptorless array types. */
+#define GFC_TYPE_ARRAY_LBOUND(node, dim) \
+ (TYPE_LANG_SPECIFIC(node)->lbound[dim])
+#define GFC_TYPE_ARRAY_UBOUND(node, dim) \
+ (TYPE_LANG_SPECIFIC(node)->ubound[dim])
+#define GFC_TYPE_ARRAY_STRIDE(node, dim) \
+ (TYPE_LANG_SPECIFIC(node)->stride[dim])
+#define GFC_TYPE_ARRAY_RANK(node) (TYPE_LANG_SPECIFIC(node)->rank)
+#define GFC_TYPE_ARRAY_SIZE(node) (TYPE_LANG_SPECIFIC(node)->size)
+#define GFC_TYPE_ARRAY_OFFSET(node) (TYPE_LANG_SPECIFIC(node)->offset)
+#define GFC_TYPE_ARRAY_DTYPE(node) (TYPE_LANG_SPECIFIC(node)->dtype)
+#define GFC_TYPE_ARRAY_DATAPTR_TYPE(node) \
+ (TYPE_LANG_SPECIFIC(node)->dataptr_type)
+
+/* I changed this from sorry(...) because it should not return. */
+/* TODO: Remove gfc_todo_error before releasing version 1.0. */
+#define gfc_todo_error(args...) fatal_error("gfc_todo: Not Implemented: " args)
+
+/* Build an expression with void type. */
+#define build1_v(code, arg) build(code, void_type_node, arg)
+#define build_v(code, args...) build(code, void_type_node, args)
+
+/* flag for alternative return labels. */
+extern int has_alternate_specifier; /* for caller */
+#endif /* GFC_TRANS_H */
diff --git a/gcc/function.c b/gcc/function.c
index e0308640335..322227bc495 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -64,10 +64,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "langhooks.h"
#include "target.h"
-#ifndef TRAMPOLINE_ALIGNMENT
-#define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY
-#endif
-
#ifndef LOCAL_ALIGNMENT
#define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT
#endif
@@ -132,9 +128,6 @@ int current_function_uses_only_leaf_regs;
post-instantiation libcalls. */
int virtuals_instantiated;
-/* Nonzero if at least one trampoline has been created. */
-int trampolines_created;
-
/* Assign unique numbers to labels generated for profiling, debugging, etc. */
static GTY(()) int funcdef_no;
@@ -142,9 +135,6 @@ static GTY(()) int funcdef_no;
target specific, per-function data structures. */
struct machine_function * (*init_machine_status) (void);
-/* The FUNCTION_DECL for an inline function currently being expanded. */
-tree inline_function_decl;
-
/* The currently compiled function. */
struct function *cfun = 0;
@@ -236,7 +226,7 @@ static rtx assign_stack_local_1 (enum machine_mode, HOST_WIDE_INT, int,
struct function *);
static struct temp_slot *find_temp_slot_from_address (rtx);
static void put_reg_into_stack (struct function *, rtx, tree, enum machine_mode,
- enum machine_mode, int, unsigned int, int, htab_t);
+ unsigned int, bool, bool, bool, htab_t);
static void schedule_fixup_var_refs (struct function *, rtx, tree, enum machine_mode,
htab_t);
static void fixup_var_refs (rtx, enum machine_mode, int, rtx, htab_t);
@@ -256,16 +246,11 @@ static void instantiate_decls_1 (tree, int);
static void instantiate_decl (rtx, HOST_WIDE_INT, int);
static rtx instantiate_new_reg (rtx, HOST_WIDE_INT *);
static int instantiate_virtual_regs_1 (rtx *, rtx, int);
-static void delete_handlers (void);
static void pad_to_arg_alignment (struct args_size *, int, struct args_size *);
static void pad_below (struct args_size *, enum machine_mode, tree);
-static rtx round_trampoline_addr (rtx);
-static rtx adjust_trampoline_addr (rtx);
static tree *identify_blocks_1 (rtx, tree *, tree *, tree *);
-static void reorder_blocks_0 (tree);
static void reorder_blocks_1 (rtx, tree, varray_type *);
static void reorder_fix_fragments (tree);
-static tree blocks_nreverse (tree);
static int all_blocks (tree, tree *);
static tree *get_block_vector (tree, int *);
extern tree debug_find_var_in_block_tree (tree, tree);
@@ -446,10 +431,7 @@ free_after_compilation (struct function *f)
f->arg_offset_rtx = NULL;
f->return_rtx = NULL;
f->internal_arg_pointer = NULL;
- f->x_nonlocal_labels = NULL;
- f->x_nonlocal_goto_handler_slots = NULL;
f->x_nonlocal_goto_handler_labels = NULL;
- f->x_nonlocal_goto_stack_level = NULL;
f->x_cleanup_label = NULL;
f->x_return_label = NULL;
f->x_naked_return_label = NULL;
@@ -461,9 +443,6 @@ free_after_compilation (struct function *f)
f->x_tail_recursion_label = NULL;
f->x_tail_recursion_reentry = NULL;
f->x_arg_pointer_save_area = NULL;
- f->x_clobber_return_insn = NULL;
- f->x_context_display = NULL;
- f->x_trampoline_list = NULL;
f->x_parm_birth_insn = NULL;
f->x_last_parm_insn = NULL;
f->x_parm_reg_stack_loc = NULL;
@@ -506,6 +485,7 @@ get_frame_size (void)
ALIGN controls the amount of alignment for the address of the slot:
0 means according to MODE,
-1 means use BIGGEST_ALIGNMENT and round size to multiple of that,
+ -2 means use BITS_PER_UNIT,
positive specifies alignment boundary in bits.
We do not round to stack_boundary here.
@@ -543,6 +523,8 @@ assign_stack_local_1 (enum machine_mode mode, HOST_WIDE_INT size, int align,
alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
size = CEIL_ROUND (size, alignment);
}
+ else if (align == -2)
+ alignment = 1; /* BITS_PER_UNIT / BITS_PER_UNIT */
else
alignment = align / BITS_PER_UNIT;
@@ -780,7 +762,7 @@ assign_stack_temp_for_type (enum machine_mode mode, HOST_WIDE_INT size, int keep
if (keep == 2)
{
p->level = target_temp_slot_level;
- p->keep = 0;
+ p->keep = 1;
}
else if (keep == 3)
{
@@ -841,7 +823,7 @@ assign_temp (tree type_or_decl, int keep, int memory_required,
{
tree type, decl;
enum machine_mode mode;
-#ifndef PROMOTE_FOR_CALL_ONLY
+#ifdef PROMOTE_MODE
int unsignedp;
#endif
@@ -851,7 +833,7 @@ assign_temp (tree type_or_decl, int keep, int memory_required,
decl = NULL, type = type_or_decl;
mode = TYPE_MODE (type);
-#ifndef PROMOTE_FOR_CALL_ONLY
+#ifdef PROMOTE_MODE
unsignedp = TYPE_UNSIGNED (type);
#endif
@@ -889,7 +871,7 @@ assign_temp (tree type_or_decl, int keep, int memory_required,
return tmp;
}
-#ifndef PROMOTE_FOR_CALL_ONLY
+#ifdef PROMOTE_MODE
if (! dont_promote)
mode = promote_mode (type, mode, &unsignedp, 0);
#endif
@@ -1291,9 +1273,9 @@ put_var_into_stack (tree decl, int rescan)
enum machine_mode promoted_mode, decl_mode;
struct function *function = 0;
tree context;
- int can_use_addressof;
- int volatilep = TREE_CODE (decl) != SAVE_EXPR && TREE_THIS_VOLATILE (decl);
- int usedp = (TREE_USED (decl)
+ bool can_use_addressof_p;
+ bool volatile_p = TREE_CODE (decl) != SAVE_EXPR && TREE_THIS_VOLATILE (decl);
+ bool used_p = (TREE_USED (decl)
|| (TREE_CODE (decl) != SAVE_EXPR && DECL_INITIAL (decl) != 0));
context = decl_function_context (decl);
@@ -1320,7 +1302,7 @@ put_var_into_stack (tree decl, int rescan)
because it might not be in any active function.
FIXME: Is that really supposed to happen?
It does in ObjC at least. */
- if (context != current_function_decl && context != inline_function_decl)
+ if (context != current_function_decl)
for (function = outer_function_chain; function; function = function->outer)
if (function->decl == context)
break;
@@ -1340,7 +1322,7 @@ put_var_into_stack (tree decl, int rescan)
/* If this variable lives in the current function and we don't need to put it
in the stack for the sake of setjmp or the non-locality, try to keep it in
a register until we know we actually need the address. */
- can_use_addressof
+ can_use_addressof_p
= (function == 0
&& ! (TREE_CODE (decl) != SAVE_EXPR && DECL_NONLOCAL (decl))
&& optimize > 0
@@ -1353,7 +1335,8 @@ put_var_into_stack (tree decl, int rescan)
/* If we can't use ADDRESSOF, make sure we see through one we already
generated. */
- if (! can_use_addressof && GET_CODE (reg) == MEM
+ if (! can_use_addressof_p
+ && GET_CODE (reg) == MEM
&& GET_CODE (XEXP (reg, 0)) == ADDRESSOF)
reg = XEXP (XEXP (reg, 0), 0);
@@ -1361,11 +1344,11 @@ put_var_into_stack (tree decl, int rescan)
if (GET_CODE (reg) == REG)
{
- if (can_use_addressof)
+ if (can_use_addressof_p)
gen_mem_addressof (reg, decl, rescan);
else
- put_reg_into_stack (function, reg, TREE_TYPE (decl), promoted_mode,
- decl_mode, volatilep, 0, usedp, 0);
+ put_reg_into_stack (function, reg, TREE_TYPE (decl), decl_mode,
+ 0, volatile_p, used_p, false, 0);
/* If this was previously a MEM but we've removed the ADDRESSOF,
set this address into that MEM so we always use the same
@@ -1387,14 +1370,14 @@ put_var_into_stack (tree decl, int rescan)
#ifdef FRAME_GROWS_DOWNWARD
/* Since part 0 should have a lower address, do it second. */
put_reg_into_stack (function, hipart, part_type, part_mode,
- part_mode, volatilep, 0, 0, 0);
+ 0, volatile_p, false, false, 0);
put_reg_into_stack (function, lopart, part_type, part_mode,
- part_mode, volatilep, 0, 0, 0);
+ 0, volatile_p, false, true, 0);
#else
put_reg_into_stack (function, lopart, part_type, part_mode,
- part_mode, volatilep, 0, 0, 0);
+ 0, volatile_p, false, false, 0);
put_reg_into_stack (function, hipart, part_type, part_mode,
- part_mode, volatilep, 0, 0, 0);
+ 0, volatile_p, false, true, 0);
#endif
/* Change the CONCAT into a combined MEM for both parts. */
@@ -1415,7 +1398,7 @@ put_var_into_stack (tree decl, int rescan)
/* Prevent sharing of rtl that might lose. */
if (GET_CODE (XEXP (reg, 0)) == PLUS)
XEXP (reg, 0) = copy_rtx (XEXP (reg, 0));
- if (usedp && rescan)
+ if (used_p && rescan)
{
schedule_fixup_var_refs (function, reg, TREE_TYPE (decl),
promoted_mode, 0);
@@ -1429,20 +1412,24 @@ put_var_into_stack (tree decl, int rescan)
/* Subroutine of put_var_into_stack. This puts a single pseudo reg REG
into the stack frame of FUNCTION (0 means the current function).
+ TYPE is the user-level data type of the value hold in the register.
DECL_MODE is the machine mode of the user-level data type.
- PROMOTED_MODE is the machine mode of the register.
- VOLATILE_P is nonzero if this is for a "volatile" decl.
- USED_P is nonzero if this reg might have already been used in an insn. */
+ ORIGINAL_REGNO must be set if the real regno is not visible in REG.
+ VOLATILE_P is true if this is for a "volatile" decl.
+ USED_P is true if this reg might have already been used in an insn.
+ CONSECUTIVE_P is true if the stack slot assigned to reg must be
+ consecutive with the previous stack slot. */
static void
put_reg_into_stack (struct function *function, rtx reg, tree type,
- enum machine_mode promoted_mode,
- enum machine_mode decl_mode, int volatile_p,
- unsigned int original_regno, int used_p, htab_t ht)
+ enum machine_mode decl_mode, unsigned int original_regno,
+ bool volatile_p, bool used_p, bool consecutive_p,
+ htab_t ht)
{
struct function *func = function ? function : cfun;
- rtx new = 0;
+ enum machine_mode mode = GET_MODE (reg);
unsigned int regno = original_regno;
+ rtx new = 0;
if (regno == 0)
regno = REGNO (reg);
@@ -1455,7 +1442,8 @@ put_reg_into_stack (struct function *function, rtx reg, tree type,
}
if (new == 0)
- new = assign_stack_local_1 (decl_mode, GET_MODE_SIZE (decl_mode), 0, func);
+ new = assign_stack_local_1 (decl_mode, GET_MODE_SIZE (decl_mode),
+ consecutive_p ? -2 : 0, func);
PUT_CODE (reg, MEM);
PUT_MODE (reg, decl_mode);
@@ -1477,7 +1465,7 @@ put_reg_into_stack (struct function *function, rtx reg, tree type,
}
if (used_p)
- schedule_fixup_var_refs (function, reg, type, promoted_mode, ht);
+ schedule_fixup_var_refs (function, reg, type, mode, ht);
}
/* Make sure that all refs to the variable, previously made
@@ -2918,7 +2906,7 @@ static void
put_addressof_into_stack (rtx r, htab_t ht)
{
tree decl, type;
- int volatile_p, used_p;
+ bool volatile_p, used_p;
rtx reg = XEXP (r, 0);
@@ -2937,12 +2925,12 @@ put_addressof_into_stack (rtx r, htab_t ht)
else
{
type = NULL_TREE;
- volatile_p = 0;
- used_p = 1;
+ volatile_p = false;
+ used_p = true;
}
- put_reg_into_stack (0, reg, type, GET_MODE (reg), GET_MODE (reg),
- volatile_p, ADDRESSOF_REGNO (r), used_p, ht);
+ put_reg_into_stack (0, reg, type, GET_MODE (reg), ADDRESSOF_REGNO (r),
+ volatile_p, used_p, false, ht);
}
/* List of replacements made below in purge_addressof_1 when creating
@@ -4159,59 +4147,6 @@ instantiate_virtual_regs_1 (rtx *loc, rtx object, int extra_insns)
return 1;
}
-/* Optimization: assuming this function does not receive nonlocal gotos,
- delete the handlers for such, as well as the insns to establish
- and disestablish them. */
-
-static void
-delete_handlers (void)
-{
- rtx insn;
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- {
- /* Delete the handler by turning off the flag that would
- prevent jump_optimize from deleting it.
- Also permit deletion of the nonlocal labels themselves
- if nothing local refers to them. */
- if (GET_CODE (insn) == CODE_LABEL)
- {
- tree t, last_t;
-
- LABEL_PRESERVE_P (insn) = 0;
-
- /* Remove it from the nonlocal_label list, to avoid confusing
- flow. */
- for (t = nonlocal_labels, last_t = 0; t;
- last_t = t, t = TREE_CHAIN (t))
- if (DECL_RTL (TREE_VALUE (t)) == insn)
- break;
- if (t)
- {
- if (! last_t)
- nonlocal_labels = TREE_CHAIN (nonlocal_labels);
- else
- TREE_CHAIN (last_t) = TREE_CHAIN (t);
- }
- }
- if (GET_CODE (insn) == INSN)
- {
- int can_delete = 0;
- rtx t;
- for (t = nonlocal_goto_handler_slots; t != 0; t = XEXP (t, 1))
- if (reg_mentioned_p (t, PATTERN (insn)))
- {
- can_delete = 1;
- break;
- }
- if (can_delete
- || (nonlocal_goto_stack_level != 0
- && reg_mentioned_p (nonlocal_goto_stack_level,
- PATTERN (insn))))
- delete_related_insns (insn);
- }
- }
-}
-
/* Return the first insn following those generated by `assign_parms'. */
rtx
@@ -4310,12 +4245,7 @@ assign_parms (tree fndecl)
/* Nonzero if function takes extra anonymous args.
This means the last named arg must be on the stack
right before the anonymous ones. */
- int stdarg
- = (TYPE_ARG_TYPES (fntype) != 0
- && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
- != void_type_node));
-
- current_function_stdarg = stdarg;
+ int stdarg = current_function_stdarg;
/* If the reg that the virtual arg pointer will be translated into is
not a fixed reg or is the stack pointer, make a copy of the virtual
@@ -5267,6 +5197,12 @@ assign_parms (tree fndecl)
{
SET_DECL_RTL (parm, DECL_RTL (fnargs));
set_decl_incoming_rtl (parm, DECL_INCOMING_RTL (fnargs));
+
+ /* Set MEM_EXPR to the original decl, i.e. to PARM,
+ instead of the copy of decl, i.e. FNARGS. */
+ if (DECL_INCOMING_RTL (parm)
+ && GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
+ set_mem_expr (DECL_INCOMING_RTL (parm), parm);
}
fnargs = TREE_CHAIN (fnargs);
}
@@ -5699,49 +5635,30 @@ pad_below (struct args_size *offset_ptr, enum machine_mode passed_mode, tree siz
}
/* Walk the tree of blocks describing the binding levels within a function
- and warn about uninitialized variables.
+ and warn about variables the might be killed by setjmp or vfork.
This is done after calling flow_analysis and before global_alloc
clobbers the pseudo-regs to hard regs. */
void
-uninitialized_vars_warning (tree block)
+setjmp_vars_warning (tree block)
{
tree decl, sub;
+
for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl))
{
- if (warn_uninitialized
- && TREE_CODE (decl) == VAR_DECL
- /* These warnings are unreliable for and aggregates
- because assigning the fields one by one can fail to convince
- flow.c that the entire aggregate was initialized.
- Unions are troublesome because members may be shorter. */
- && ! AGGREGATE_TYPE_P (TREE_TYPE (decl))
- && DECL_RTL_SET_P (decl)
- && GET_CODE (DECL_RTL (decl)) == REG
- /* Global optimizations can make it difficult to determine if a
- particular variable has been initialized. However, a VAR_DECL
- with a nonzero DECL_INITIAL had an initializer, so do not
- claim it is potentially uninitialized.
-
- When the DECL_INITIAL is NULL call the language hook to tell us
- if we want to warn. */
- && (DECL_INITIAL (decl) == NULL_TREE || lang_hooks.decl_uninit (decl))
- && regno_uninitialized (REGNO (DECL_RTL (decl))))
- warning ("%J'%D' might be used uninitialized in this function",
- decl, decl);
- if (extra_warnings
- && TREE_CODE (decl) == VAR_DECL
+ if (TREE_CODE (decl) == VAR_DECL
&& DECL_RTL_SET_P (decl)
&& GET_CODE (DECL_RTL (decl)) == REG
&& regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
warning ("%Jvariable '%D' might be clobbered by `longjmp' or `vfork'",
decl, decl);
}
+
for (sub = BLOCK_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub))
- uninitialized_vars_warning (sub);
+ setjmp_vars_warning (sub);
}
-/* Do the appropriate part of uninitialized_vars_warning
+/* Do the appropriate part of setjmp_vars_warning
but for arguments instead of local variables. */
void
@@ -5815,33 +5732,6 @@ setjmp_protect_args (void)
put_var_into_stack (decl, /*rescan=*/true);
}
-/* Return the context-pointer register corresponding to DECL,
- or 0 if it does not need one. */
-
-rtx
-lookup_static_chain (tree decl)
-{
- tree context = decl_function_context (decl);
- tree link;
-
- if (context == 0
- || (TREE_CODE (decl) == FUNCTION_DECL && DECL_NO_STATIC_CHAIN (decl)))
- return 0;
-
- /* We treat inline_function_decl as an alias for the current function
- because that is the inline function whose vars, types, etc.
- are being merged into the current function.
- See expand_inline_function. */
- if (context == current_function_decl || context == inline_function_decl)
- return virtual_stack_vars_rtx;
-
- for (link = context_display; link; link = TREE_CHAIN (link))
- if (TREE_PURPOSE (link) == context)
- return RTL_EXPR_RTL (TREE_VALUE (link));
-
- abort ();
-}
-
/* Convert a stack slot address ADDR for variable VAR
(from a containing function)
into an address valid in this function (using a static chain). */
@@ -5856,7 +5746,7 @@ fix_lexical_addr (rtx addr, tree var)
rtx base = 0;
/* If this is the present function, we need not do anything. */
- if (context == current_function_decl || context == inline_function_decl)
+ if (context == current_function_decl)
return addr;
fp = find_function_data (context);
@@ -5872,49 +5762,6 @@ fix_lexical_addr (rtx addr, tree var)
else
abort ();
- /* We accept vars reached via the containing function's
- incoming arg pointer and via its stack variables pointer. */
- if (basereg == fp->internal_arg_pointer)
- {
- /* If reached via arg pointer, get the arg pointer value
- out of that function's stack frame.
-
- There are two cases: If a separate ap is needed, allocate a
- slot in the outer function for it and dereference it that way.
- This is correct even if the real ap is actually a pseudo.
- Otherwise, just adjust the offset from the frame pointer to
- compensate. */
-
-#ifdef NEED_SEPARATE_AP
- rtx addr;
-
- addr = get_arg_pointer_save_area (fp);
- addr = fix_lexical_addr (XEXP (addr, 0), var);
- addr = memory_address (Pmode, addr);
-
- base = gen_rtx_MEM (Pmode, addr);
- set_mem_alias_set (base, get_frame_alias_set ());
- base = copy_to_reg (base);
-#else
- displacement += (FIRST_PARM_OFFSET (context) - STARTING_FRAME_OFFSET);
- base = lookup_static_chain (var);
-#endif
- }
-
- else if (basereg == virtual_stack_vars_rtx)
- {
- /* This is the same code as lookup_static_chain, duplicated here to
- avoid an extra call to decl_function_context. */
- tree link;
-
- for (link = context_display; link; link = TREE_CHAIN (link))
- if (TREE_PURPOSE (link) == context)
- {
- base = RTL_EXPR_RTL (TREE_VALUE (link));
- break;
- }
- }
-
if (base == 0)
abort ();
@@ -5923,106 +5770,6 @@ fix_lexical_addr (rtx addr, tree var)
return plus_constant (base, displacement);
}
-/* Return the address of the trampoline for entering nested fn FUNCTION.
- If necessary, allocate a trampoline (in the stack frame)
- and emit rtl to initialize its contents (at entry to this function). */
-
-rtx
-trampoline_address (tree function)
-{
- tree link;
- tree rtlexp;
- rtx tramp;
- struct function *fp;
- tree fn_context;
-
- /* Find an existing trampoline and return it. */
- for (link = trampoline_list; link; link = TREE_CHAIN (link))
- if (TREE_PURPOSE (link) == function)
- return
- adjust_trampoline_addr (XEXP (RTL_EXPR_RTL (TREE_VALUE (link)), 0));
-
- for (fp = outer_function_chain; fp; fp = fp->outer)
- for (link = fp->x_trampoline_list; link; link = TREE_CHAIN (link))
- if (TREE_PURPOSE (link) == function)
- {
- tramp = fix_lexical_addr (XEXP (RTL_EXPR_RTL (TREE_VALUE (link)), 0),
- function);
- return adjust_trampoline_addr (tramp);
- }
-
- /* None exists; we must make one. */
-
- /* Find the `struct function' for the function containing FUNCTION. */
- fp = 0;
- fn_context = decl_function_context (function);
- if (fn_context != current_function_decl
- && fn_context != inline_function_decl)
- fp = find_function_data (fn_context);
-
- /* Allocate run-time space for this trampoline. */
- /* If rounding needed, allocate extra space
- to ensure we have TRAMPOLINE_SIZE bytes left after rounding up. */
-#define TRAMPOLINE_REAL_SIZE \
- (TRAMPOLINE_SIZE + (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT) - 1)
- tramp = assign_stack_local_1 (BLKmode, TRAMPOLINE_REAL_SIZE, 0,
- fp ? fp : cfun);
- /* Record the trampoline for reuse and note it for later initialization
- by expand_function_end. */
- if (fp != 0)
- {
- rtlexp = make_node (RTL_EXPR);
- RTL_EXPR_RTL (rtlexp) = tramp;
- fp->x_trampoline_list = tree_cons (function, rtlexp,
- fp->x_trampoline_list);
- }
- else
- {
- /* Make the RTL_EXPR node temporary, not momentary, so that the
- trampoline_list doesn't become garbage. */
- rtlexp = make_node (RTL_EXPR);
-
- RTL_EXPR_RTL (rtlexp) = tramp;
- trampoline_list = tree_cons (function, rtlexp, trampoline_list);
- }
-
- tramp = fix_lexical_addr (XEXP (tramp, 0), function);
- return adjust_trampoline_addr (tramp);
-}
-
-/* Given a trampoline address,
- round it to multiple of TRAMPOLINE_ALIGNMENT. */
-
-static rtx
-round_trampoline_addr (rtx tramp)
-{
- /* Round address up to desired boundary. */
- rtx temp = gen_reg_rtx (Pmode);
- rtx addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
- rtx mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
-
- temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
- temp, 0, OPTAB_LIB_WIDEN);
- tramp = expand_simple_binop (Pmode, AND, temp, mask,
- temp, 0, OPTAB_LIB_WIDEN);
-
- return tramp;
-}
-
-/* Given a trampoline address, round it then apply any
- platform-specific adjustments so that the result can be used for a
- function call . */
-
-static rtx
-adjust_trampoline_addr (rtx tramp)
-{
- tramp = round_trampoline_addr (tramp);
-#ifdef TRAMPOLINE_ADJUST_ADDRESS
- TRAMPOLINE_ADJUST_ADDRESS (tramp);
-#endif
- return tramp;
-}
-
/* Put all this function's BLOCK nodes including those that are chained
onto the first block into a vector, and return it.
Also store in each NOTE for the beginning or end of a block
@@ -6142,7 +5889,7 @@ reorder_blocks (void)
VARRAY_TREE_INIT (block_stack, 10, "block_stack");
/* Reset the TREE_ASM_WRITTEN bit for all blocks. */
- reorder_blocks_0 (block);
+ clear_block_marks (block);
/* Prune the old trees away, so that they don't get in the way. */
BLOCK_SUBBLOCKS (block) = NULL_TREE;
@@ -6158,13 +5905,13 @@ reorder_blocks (void)
/* Helper function for reorder_blocks. Reset TREE_ASM_WRITTEN. */
-static void
-reorder_blocks_0 (tree block)
+void
+clear_block_marks (tree block)
{
while (block)
{
TREE_ASM_WRITTEN (block) = 0;
- reorder_blocks_0 (BLOCK_SUBBLOCKS (block));
+ clear_block_marks (BLOCK_SUBBLOCKS (block));
block = BLOCK_CHAIN (block);
}
}
@@ -6295,7 +6042,7 @@ reorder_fix_fragments (tree block)
/* Reverse the order of elements in the chain T of blocks,
and return the new head of the chain (old last element). */
-static tree
+tree
blocks_nreverse (tree t)
{
tree prev = 0, decl, next;
@@ -6413,6 +6160,7 @@ void
allocate_struct_function (tree fndecl)
{
tree result;
+ tree fntype = fndecl ? TREE_TYPE (fndecl) : NULL_TREE;
cfun = ggc_alloc_cleared (sizeof (struct function));
@@ -6449,9 +6197,11 @@ allocate_struct_function (tree fndecl)
current_function_returns_pointer = POINTER_TYPE_P (TREE_TYPE (result));
- current_function_needs_context
- = (decl_function_context (current_function_decl) != 0
- && ! DECL_NO_STATIC_CHAIN (current_function_decl));
+ current_function_stdarg
+ = (fntype
+ && TYPE_ARG_TYPES (fntype) != 0
+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
+ != void_type_node));
}
/* Reset cfun, and other non-struct-function variables to defaults as
@@ -6624,17 +6374,10 @@ expand_pending_sizes (tree pending_sizes)
void
expand_function_start (tree subr, int parms_have_cleanups)
{
- tree tem;
- rtx last_ptr = NULL_RTX;
-
/* Make sure volatile mem refs aren't considered
valid operands of arithmetic insns. */
init_recog_no_volatile ();
- current_function_instrument_entry_exit
- = (flag_instrument_function_entry_exit
- && ! DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (subr));
-
current_function_profile
= (profile_flag
&& ! DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (subr));
@@ -6642,19 +6385,6 @@ expand_function_start (tree subr, int parms_have_cleanups)
current_function_limit_stack
= (stack_limit_rtx != NULL_RTX && ! DECL_NO_LIMIT_STACK (subr));
- /* If function gets a static chain arg, store it in the stack frame.
- Do this first, so it gets the first stack slot offset. */
- if (current_function_needs_context)
- {
- last_ptr = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
-
- /* Delay copying static chain if it is not a register to avoid
- conflicts with regs used for parameters. */
- if (! SMALL_REGISTER_CLASSES
- || GET_CODE (static_chain_incoming_rtx) == REG)
- emit_move_insn (last_ptr, static_chain_incoming_rtx);
- }
-
/* If the parameters of this function need cleaning up, get a label
for the beginning of the code which executes those cleanups. This must
be done before doing anything with return_label. */
@@ -6735,15 +6465,37 @@ expand_function_start (tree subr, int parms_have_cleanups)
/* Initialize rtx for parameters and local variables.
In some cases this requires emitting insns. */
-
assign_parms (subr);
- /* Copy the static chain now if it wasn't a register. The delay is to
- avoid conflicts with the parameter passing registers. */
+ /* If function gets a static chain arg, store it. */
+ if (cfun->static_chain_decl)
+ {
+ rtx x;
+
+ expand_var (cfun->static_chain_decl);
+ x = expand_expr (cfun->static_chain_decl, NULL_RTX,
+ VOIDmode, EXPAND_WRITE);
+ emit_move_insn (x, static_chain_incoming_rtx);
+ }
+
+ /* If the function receives a non-local goto, then store the
+ bits we need to restore the frame pointer. */
+ if (cfun->nonlocal_goto_save_area)
+ {
+ tree t_save;
+ rtx r_save;
+
+ /* ??? We need to do this save early. Unfortunately here is
+ before the frame variable gets declared. Help out... */
+ expand_var (TREE_OPERAND (cfun->nonlocal_goto_save_area, 0));
- if (SMALL_REGISTER_CLASSES && current_function_needs_context)
- if (GET_CODE (static_chain_incoming_rtx) != REG)
- emit_move_insn (last_ptr, static_chain_incoming_rtx);
+ t_save = build (ARRAY_REF, ptr_type_node, cfun->nonlocal_goto_save_area,
+ integer_zero_node);
+ r_save = expand_expr (t_save, NULL_RTX, VOIDmode, EXPAND_WRITE);
+
+ emit_move_insn (r_save, virtual_stack_vars_rtx);
+ update_nonlocal_goto_save_area ();
+ }
/* The following was moved from init_function_start.
The move is supposed to make sdb output more accurate. */
@@ -6755,67 +6507,6 @@ expand_function_start (tree subr, int parms_have_cleanups)
emit_note (NOTE_INSN_DELETED);
parm_birth_insn = get_last_insn ();
- context_display = 0;
- if (current_function_needs_context)
- {
- /* Fetch static chain values for containing functions. */
- tem = decl_function_context (current_function_decl);
- /* Copy the static chain pointer into a pseudo. If we have
- small register classes, copy the value from memory if
- static_chain_incoming_rtx is a REG. */
- if (tem)
- {
- /* If the static chain originally came in a register, put it back
- there, then move it out in the next insn. The reason for
- this peculiar code is to satisfy function integration. */
- if (SMALL_REGISTER_CLASSES
- && GET_CODE (static_chain_incoming_rtx) == REG)
- emit_move_insn (static_chain_incoming_rtx, last_ptr);
- last_ptr = copy_to_reg (static_chain_incoming_rtx);
- }
-
- while (tem)
- {
- tree rtlexp = make_node (RTL_EXPR);
-
- RTL_EXPR_RTL (rtlexp) = last_ptr;
- context_display = tree_cons (tem, rtlexp, context_display);
- tem = decl_function_context (tem);
- if (tem == 0)
- break;
- /* Chain through stack frames, assuming pointer to next lexical frame
- is found at the place we always store it. */
-#ifdef FRAME_GROWS_DOWNWARD
- last_ptr = plus_constant (last_ptr,
- -(HOST_WIDE_INT) GET_MODE_SIZE (Pmode));
-#endif
- last_ptr = gen_rtx_MEM (Pmode, memory_address (Pmode, last_ptr));
- set_mem_alias_set (last_ptr, get_frame_alias_set ());
- last_ptr = copy_to_reg (last_ptr);
-
- /* If we are not optimizing, ensure that we know that this
- piece of context is live over the entire function. */
- if (! optimize)
- save_expr_regs = gen_rtx_EXPR_LIST (VOIDmode, last_ptr,
- save_expr_regs);
- }
- }
-
- if (current_function_instrument_entry_exit)
- {
- rtx fun = DECL_RTL (current_function_decl);
- if (GET_CODE (fun) == MEM)
- fun = XEXP (fun, 0);
- else
- abort ();
- emit_library_call (profile_function_entry_libfunc, LCT_NORMAL, VOIDmode,
- 2, fun, Pmode,
- expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
- 0,
- hard_frame_pointer_rtx),
- Pmode);
- }
-
if (current_function_profile)
{
#ifdef PROFILE_HOOK
@@ -6913,6 +6604,19 @@ use_return_register (void)
diddle_return_value (do_use_return_reg, NULL);
}
+/* Possibly warn about unused parameters. */
+void
+do_warn_unused_parameter (tree fn)
+{
+ tree decl;
+
+ for (decl = DECL_ARGUMENTS (fn);
+ decl; decl = TREE_CHAIN (decl))
+ if (!TREE_USED (decl) && TREE_CODE (decl) == PARM_DECL
+ && DECL_NAME (decl) && !DECL_ARTIFICIAL (decl))
+ warning ("%Junused parameter '%D'", decl, decl);
+}
+
static GTY(()) rtx initial_trampoline;
/* Generate RTL for the end of the current function. */
@@ -6920,7 +6624,6 @@ static GTY(()) rtx initial_trampoline;
void
expand_function_end (void)
{
- tree link;
rtx clobber_after;
finish_expr_for_function ();
@@ -6942,45 +6645,6 @@ expand_function_end (void)
}
#endif
- /* Initialize any trampolines required by this function. */
- for (link = trampoline_list; link; link = TREE_CHAIN (link))
- {
- tree function = TREE_PURPOSE (link);
- rtx context ATTRIBUTE_UNUSED = lookup_static_chain (function);
- rtx tramp = RTL_EXPR_RTL (TREE_VALUE (link));
-#ifdef TRAMPOLINE_TEMPLATE
- rtx blktramp;
-#endif
- rtx seq;
-
-#ifdef TRAMPOLINE_TEMPLATE
- /* First make sure this compilation has a template for
- initializing trampolines. */
- if (initial_trampoline == 0)
- {
- initial_trampoline
- = gen_rtx_MEM (BLKmode, assemble_trampoline_template ());
- set_mem_align (initial_trampoline, TRAMPOLINE_ALIGNMENT);
- }
-#endif
-
- /* Generate insns to initialize the trampoline. */
- start_sequence ();
- tramp = round_trampoline_addr (XEXP (tramp, 0));
-#ifdef TRAMPOLINE_TEMPLATE
- blktramp = replace_equiv_address (initial_trampoline, tramp);
- emit_block_move (blktramp, initial_trampoline,
- GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
-#endif
- trampolines_created = 1;
- INITIALIZE_TRAMPOLINE (tramp, XEXP (DECL_RTL (function), 0), context);
- seq = get_insns ();
- end_sequence ();
-
- /* Put those insns at entry to the containing function (this one). */
- emit_insn_before (seq, tail_recursion_reentry);
- }
-
/* If we are doing stack checking and this function makes calls,
do a stack probe at the start of the function to ensure we have enough
space for another stack frame. */
@@ -7001,22 +6665,12 @@ expand_function_end (void)
}
}
- /* Possibly warn about unused parameters. */
- if (warn_unused_parameter)
- {
- tree decl;
-
- for (decl = DECL_ARGUMENTS (current_function_decl);
- decl; decl = TREE_CHAIN (decl))
- if (! TREE_USED (decl) && TREE_CODE (decl) == PARM_DECL
- && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl))
- warning ("%Junused parameter '%D'", decl, decl);
- }
-
- /* Delete handlers for nonlocal gotos if nothing uses them. */
- if (nonlocal_goto_handler_slots != 0
- && ! current_function_has_nonlocal_label)
- delete_handlers ();
+ /* Possibly warn about unused parameters.
+ When frontend does unit-at-a-time, the warning is already
+ issued at finalization time. */
+ if (warn_unused_parameter
+ && !lang_hooks.callgraph.expand_function)
+ do_warn_unused_parameter (current_function_decl);
/* End any sequences that failed to be closed due to syntax errors. */
while (in_sequence_p ())
@@ -7073,21 +6727,6 @@ expand_function_end (void)
if (return_label)
emit_label (return_label);
- if (current_function_instrument_entry_exit)
- {
- rtx fun = DECL_RTL (current_function_decl);
- if (GET_CODE (fun) == MEM)
- fun = XEXP (fun, 0);
- else
- abort ();
- emit_library_call (profile_function_exit_libfunc, LCT_NORMAL, VOIDmode,
- 2, fun, Pmode,
- expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
- 0,
- hard_frame_pointer_rtx),
- Pmode);
- }
-
/* Let except.c know where it should emit the call to unregister
the function context for sjlj exceptions. */
if (flag_exceptions && USING_SJLJ_EXCEPTIONS)
@@ -7210,9 +6849,6 @@ expand_function_end (void)
end_sequence ();
after = emit_insn_after (seq, clobber_after);
-
- if (clobber_after != after)
- cfun->x_clobber_return_insn = after;
}
/* Output the label for the naked return from the function, if one is
@@ -8138,6 +7774,59 @@ init_function_once (void)
VARRAY_INT_INIT (sibcall_epilogue, 0, "sibcall_epilogue");
}
+/* Resets insn_block_boundaries array. */
+
+void
+reset_block_changes (void)
+{
+ VARRAY_TREE_INIT (cfun->ib_boundaries_block, 100, "ib_boundaries_block");
+ VARRAY_PUSH_TREE (cfun->ib_boundaries_block, NULL_TREE);
+}
+
+/* Record the boundary for BLOCK. */
+void
+record_block_change (tree block)
+{
+ int i, n;
+ tree last_block;
+
+ if (!block)
+ return;
+
+ last_block = VARRAY_TOP_TREE (cfun->ib_boundaries_block);
+ VARRAY_POP (cfun->ib_boundaries_block);
+ n = get_max_uid ();
+ for (i = VARRAY_ACTIVE_SIZE (cfun->ib_boundaries_block); i < n; i++)
+ VARRAY_PUSH_TREE (cfun->ib_boundaries_block, last_block);
+
+ VARRAY_PUSH_TREE (cfun->ib_boundaries_block, block);
+}
+
+/* Finishes record of boundaries. */
+void finalize_block_changes (void)
+{
+ record_block_change (DECL_INITIAL (current_function_decl));
+}
+
+/* For INSN return the BLOCK it belongs to. */
+void
+check_block_change (rtx insn, tree *block)
+{
+ unsigned uid = INSN_UID (insn);
+
+ if (uid >= VARRAY_ACTIVE_SIZE (cfun->ib_boundaries_block))
+ return;
+
+ *block = VARRAY_TREE (cfun->ib_boundaries_block, uid);
+}
+
+/* Releases the ib_boundaries_block records. */
+void
+free_block_changes (void)
+{
+ cfun->ib_boundaries_block = NULL;
+}
+
/* Returns the name of the current function. */
const char *
current_function_name (void)
diff --git a/gcc/function.h b/gcc/function.h
index 2c3a847cb58..4c7537eba6d 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -243,26 +243,10 @@ struct function GTY(())
/* Number of function calls seen so far in current function. */
int x_function_call_count;
- /* List (chain of TREE_LIST) of LABEL_DECLs for all nonlocal labels
- (labels to which there can be nonlocal gotos from nested functions)
- in this function. */
- tree x_nonlocal_labels;
-
- /* List (chain of EXPR_LIST) of stack slots that hold the current handlers
- for nonlocal gotos. There is one for every nonlocal label in the
- function; this list matches the one in nonlocal_labels.
- Zero when function does not have nonlocal labels. */
- rtx x_nonlocal_goto_handler_slots;
-
/* List (chain of EXPR_LIST) of labels heading the current handlers for
nonlocal gotos. */
rtx x_nonlocal_goto_handler_labels;
- /* RTX for stack slot that holds the stack pointer value to restore
- for a nonlocal goto.
- Zero when function does not have nonlocal labels. */
- rtx x_nonlocal_goto_stack_level;
-
/* Label that will go on parm cleanup code, if any.
Jumping to this label runs cleanup code for parameters, if
such code must be run. Following this code is the logical return
@@ -307,29 +291,19 @@ struct function GTY(())
needed by inner routines. */
rtx x_arg_pointer_save_area;
- /* If the function returns non-void, we will emit a clobber of the
- return registers just in case the user fell off the end without
- returning a proper value. This is that insn. */
- rtx x_clobber_return_insn;
-
/* Offset to end of allocated area of stack frame.
If stack grows down, this is the address of the last stack slot allocated.
If stack grows up, this is the address for the next slot. */
HOST_WIDE_INT x_frame_offset;
- /* List (chain of TREE_LISTs) of static chains for containing functions.
- Each link has a FUNCTION_DECL in the TREE_PURPOSE and a reg rtx
- in an RTL_EXPR in the TREE_VALUE. */
- tree x_context_display;
-
- /* List (chain of TREE_LISTs) of trampolines for nested functions.
- The trampoline sets up the static chain and jumps to the function.
- We supply the trampoline's address when the function's address is
- requested.
+ /* A VAR_DECL that should contain the static chain for this function.
+ It will be initialized at the beginning of the function. */
+ tree static_chain_decl;
- Each link has a FUNCTION_DECL in the TREE_PURPOSE and a reg rtx
- in an RTL_EXPR in the TREE_VALUE. */
- tree x_trampoline_list;
+ /* An expression that contains the non-local goto save area. The first
+ word is the saved frame pointer and the second is the saved stack
+ pointer. */
+ tree nonlocal_goto_save_area;
/* Insn after which register parms and SAVE_EXPRs are born, if nonopt. */
rtx x_parm_birth_insn;
@@ -391,6 +365,8 @@ struct function GTY(())
int preferred_stack_boundary;
/* Set when the call to function itself has been emit. */
bool recursive_call_emit;
+ /* Set when the tail call has been produced. */
+ bool tail_call_emit;
/* Language-specific code can use this to store whatever it likes. */
struct language_function * language;
@@ -401,6 +377,10 @@ struct function GTY(())
delay list for them is recorded here. */
rtx epilogue_delay_list;
+ /* Nonzero if NOTE_INSN_BLOCK_BEG / NOTE_INSN_BLOCK_END notes should not
+ be emitted. */
+ unsigned int dont_emit_block_notes : 1;
+
/* How commonly executed the function is. Initialized during branch
probabilities pass. */
enum function_frequency {
@@ -418,6 +398,18 @@ struct function GTY(())
final flowgraph size. */
int max_jumptable_ents;
+ /* UIDs for LABEL_DECLs. */
+ int last_label_uid;
+
+ /* Line number of the end of the function. */
+ location_t function_end_locus;
+
+ /* Array mapping insn uids to blocks. */
+ struct varray_head_tag *ib_boundaries_block;
+
+ /* The variables unexpanded so far. */
+ tree unexpanded_var_list;
+
/* Collected bit flags. */
/* Nonzero if function being compiled needs to be given an address
@@ -431,9 +423,6 @@ struct function GTY(())
/* Nonzero if the current function returns a pointer type. */
unsigned int returns_pointer : 1;
- /* Nonzero if function being compiled needs to be passed a static chain. */
- unsigned int needs_context : 1;
-
/* Nonzero if function being compiled can call setjmp. */
unsigned int calls_setjmp : 1;
@@ -447,9 +436,6 @@ struct function GTY(())
/* Nonzero if the function calls __builtin_eh_return. */
unsigned int calls_eh_return : 1;
- /* Nonzero if the function calls __builtin_constant_p. */
- unsigned int calls_constant_p : 1;
-
/* Nonzero if function being compiled receives nonlocal gotos
from nested functions. */
unsigned int has_nonlocal_label : 1;
@@ -517,13 +503,6 @@ struct function GTY(())
/* Nonzero if code to initialize arg_pointer_save_area has been emitted. */
unsigned int arg_pointer_save_area_init : 1;
-
- /* Flag for use by ther rtl inliner, to tell if the function has been
- processed at least once. */
- unsigned int rtl_inline_init : 1;
-
- /* Nonzero if the rtl inliner has saved the function for inlining. */
- unsigned int saved_for_inline : 1;
};
/* The function currently being compiled. */
@@ -543,12 +522,10 @@ extern int trampolines_created;
#define current_function_returns_struct (cfun->returns_struct)
#define current_function_returns_pcc_struct (cfun->returns_pcc_struct)
#define current_function_returns_pointer (cfun->returns_pointer)
-#define current_function_needs_context (cfun->needs_context)
#define current_function_calls_setjmp (cfun->calls_setjmp)
#define current_function_calls_alloca (cfun->calls_alloca)
#define current_function_calls_longjmp (cfun->calls_longjmp)
#define current_function_calls_eh_return (cfun->calls_eh_return)
-#define current_function_calls_constant_p (cfun->calls_constant_p)
#define current_function_has_computed_jump (cfun->has_computed_jump)
#define current_function_contains_functions (cfun->contains_functions)
#define current_function_is_thunk (cfun->is_thunk)
@@ -585,20 +562,13 @@ extern int trampolines_created;
#define arg_pointer_save_area (cfun->x_arg_pointer_save_area)
#define rtl_expr_chain (cfun->x_rtl_expr_chain)
#define last_parm_insn (cfun->x_last_parm_insn)
-#define context_display (cfun->x_context_display)
-#define trampoline_list (cfun->x_trampoline_list)
#define function_call_count (cfun->x_function_call_count)
#define temp_slots (cfun->x_temp_slots)
#define temp_slot_level (cfun->x_temp_slot_level)
#define target_temp_slot_level (cfun->x_target_temp_slot_level)
#define var_temp_slot_level (cfun->x_var_temp_slot_level)
#define nonlocal_labels (cfun->x_nonlocal_labels)
-#define nonlocal_goto_handler_slots (cfun->x_nonlocal_goto_handler_slots)
#define nonlocal_goto_handler_labels (cfun->x_nonlocal_goto_handler_labels)
-#define nonlocal_goto_stack_level (cfun->x_nonlocal_goto_stack_level)
-
-/* The FUNCTION_DECL for an inline function currently being expanded. */
-extern tree inline_function_decl;
/* Given a function decl for a containing function,
return the `struct function' for it. */
@@ -614,6 +584,14 @@ extern void reorder_blocks (void);
/* Set BLOCK_NUMBER for all the blocks in FN. */
extern void number_blocks (tree);
+extern void clear_block_marks (tree);
+extern tree blocks_nreverse (tree);
+extern void reset_block_changes (void);
+extern void record_block_change (tree);
+extern void finalize_block_changes (void);
+extern void check_block_change (rtx, tree *);
+extern void free_block_changes (void);
+
/* Return size needed for stack frame based on slots so far allocated.
This size counts from zero. It is not rounded to STACK_BOUNDARY;
the caller may have to do that. */
@@ -648,4 +626,6 @@ extern const char *current_function_name (void);
/* Called once, at initialization, to initialize function.c. */
extern void init_function_once (void);
+extern void do_warn_unused_parameter (tree);
+
#endif /* GCC_FUNCTION_H */
diff --git a/gcc/gcc.c b/gcc/gcc.c
index e004697431e..fcb9a49b564 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -599,6 +599,20 @@ proper position among the other output files. */
#define LIB_SPEC "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
#endif
+/* mudflap specs */
+#ifndef MFWRAP_SPEC
+/* XXX: valid only for GNU ld */
+/* XXX: should exactly match hooks provided by libmudflap.a */
+#define MFWRAP_SPEC " %{static: %{fmudflap|fmudflapth: \
+ --wrap=malloc --wrap=free --wrap=calloc --wrap=realloc\
+ --wrap=mmap --wrap=munmap --wrap=alloca\
+} %{fmudflapth: --wrap=pthread_create --wrap=pthread_join --wrap=pthread_exit\
+}} %{fmudflap|fmudflapth: --wrap=main}"
+#endif
+#ifndef MFLIB_SPEC
+#define MFLIB_SPEC " %{fmudflap: -export-dynamic -lmudflap %{static:%(link_gcc_c_sequence) -lmudflap}} %{fmudflapth: -export-dynamic -lmudflapth -lpthread %{static:%(link_gcc_c_sequence) -lmudflapth}} "
+#endif
+
/* config.h can define LIBGCC_SPEC to override how and when libgcc.a is
included. */
#ifndef LIBGCC_SPEC
@@ -683,7 +697,8 @@ proper position among the other output files. */
%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
%(linker) %l " LINK_PIE_SPEC "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\
%{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
- %{static:} %{L*} %(link_libgcc) %o %{fprofile-arcs|fprofile-generate:-lgcov}\
+ %{static:} %{L*} %(mfwrap) %(link_libgcc) %o %(mflib)\
+ %{fprofile-arcs|fprofile-generate:-lgcov}\
%{!nostdlib:%{!nodefaultlibs:%(link_gcc_c_sequence)}}\
%{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}"
#endif
@@ -719,6 +734,8 @@ static const char *asm_spec = ASM_SPEC;
static const char *asm_final_spec = ASM_FINAL_SPEC;
static const char *link_spec = LINK_SPEC;
static const char *lib_spec = LIB_SPEC;
+static const char *mfwrap_spec = MFWRAP_SPEC;
+static const char *mflib_spec = MFLIB_SPEC;
static const char *libgcc_spec = LIBGCC_SPEC;
static const char *endfile_spec = ENDFILE_SPEC;
static const char *startfile_spec = STARTFILE_SPEC;
@@ -753,6 +770,8 @@ static const char *cpp_unique_options =
%{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
%{!E:%{!M:%{!MM:%{MD|MMD:%{o*:-MQ %*}}}}}\
%{trigraphs} %{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i\
+ %{fmudflap:-D_MUDFLAP -include mf-runtime.h}\
+ %{fmudflapth:-D_MUDFLAP -D_MUDFLAPTH -include mf-runtime.h}\
%{E|M|MM:%W{o*}}";
/* This contains cpp options which are common with cc1_options and are passed
@@ -778,7 +797,8 @@ static const char *cc1_options =
%{Qn:-fno-ident} %{--help:--help}\
%{--target-help:--target-help}\
%{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}}\
- %{fsyntax-only:-o %j} %{-param*}";
+ %{fsyntax-only:-o %j} %{-param*}\
+ %{fmudflap|fmudflapth:-fno-builtin -fno-merge-constants}";
static const char *asm_options =
"%a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}";
@@ -901,6 +921,9 @@ static const struct compiler default_compilers[] =
{".CPP", "#C++", 0, 0, 0}, {".ii", "#C++", 0, 0, 0},
{".ads", "#Ada", 0, 0, 0}, {".adb", "#Ada", 0, 0, 0},
{".f", "#Fortran", 0, 0, 0}, {".for", "#Fortran", 0, 0, 0},
+ {".F", "#Fortran", 0, 0, 0}, {".FOR", "#Fortran", 0, 0, 0},
+ {".FPP", "#Fortran", 0, 0, 0},
+ {".f90", "#Fortran 95", 0, 0, 0}, {".f95", "#Fortran 95", 0, 0, 0},
{".fpp", "#Fortran", 0, 0, 0}, {".F", "#Fortran", 0, 0, 0},
{".FOR", "#Fortran", 0, 0, 0}, {".FPP", "#Fortran", 0, 0, 0},
{".r", "#Ratfor", 0, 0, 0},
@@ -1490,6 +1513,8 @@ static struct spec_list static_specs[] =
INIT_STATIC_SPEC ("endfile", &endfile_spec),
INIT_STATIC_SPEC ("link", &link_spec),
INIT_STATIC_SPEC ("lib", &lib_spec),
+ INIT_STATIC_SPEC ("mfwrap", &mfwrap_spec),
+ INIT_STATIC_SPEC ("mflib", &mflib_spec),
INIT_STATIC_SPEC ("libgcc", &libgcc_spec),
INIT_STATIC_SPEC ("startfile", &startfile_spec),
INIT_STATIC_SPEC ("switches_need_spaces", &switches_need_spaces),
@@ -1543,6 +1568,11 @@ static int processing_spec_function;
various permutations of -shared-libgcc, -shared, and such. */
#if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC)
+
+#ifndef USE_LD_AS_NEEDED
+#define USE_LD_AS_NEEDED 0
+#endif
+
static void
init_gcc_specs (struct obstack *obstack, const char *shared_name,
const char *static_name, const char *eh_name)
@@ -1551,7 +1581,7 @@ init_gcc_specs (struct obstack *obstack, const char *shared_name,
buf = concat ("%{static|static-libgcc:", static_name, " ", eh_name,
"}%{!static:%{!static-libgcc:",
-#ifdef HAVE_LD_AS_NEEDED
+#if USE_LD_AS_NEEDED
"%{!shared-libgcc:", static_name,
" --as-needed ", shared_name, " --no-as-needed}"
"%{shared-libgcc:", shared_name, "%{!shared: ", static_name,
@@ -2240,6 +2270,17 @@ record_temp_file (const char *filename, int always_delete, int fail_delete)
/* Delete all the temporary files whose names we previously recorded. */
+#ifndef DELETE_IF_ORDINARY
+#define DELETE_IF_ORDINARY(NAME,ST,VERBOSE_FLAG) \
+do \
+ { \
+ if (stat (NAME, &ST) >= 0 && S_ISREG (ST.st_mode)) \
+ if (unlink (NAME) < 0) \
+ if (VERBOSE_FLAG) \
+ perror_with_name (NAME); \
+ } while (0)
+#endif
+
static void
delete_if_ordinary (const char *name)
{
@@ -2256,10 +2297,7 @@ delete_if_ordinary (const char *name)
if (i == 'y' || i == 'Y')
#endif /* DEBUG */
- if (stat (name, &st) >= 0 && S_ISREG (st.st_mode))
- if (unlink (name) < 0)
- if (verbose_flag)
- perror_with_name (name);
+ DELETE_IF_ORDINARY (name, st, verbose_flag);
}
static void
@@ -6909,20 +6947,21 @@ used_arg (const char *p, int len)
= xmalloc (sizeof (struct mswitchstr)
* (n_mdswitches + (n_switches ? n_switches : 1)));
for (i = 0; i < n_switches; i++)
- {
- int xlen = strlen (switches[i].part1);
- for (j = 0; j < cnt; j++)
- if (xlen == matches[j].len
- && ! strncmp (switches[i].part1, matches[j].str, xlen))
- {
- mswitches[n_mswitches].str = matches[j].replace;
- mswitches[n_mswitches].len = matches[j].rep_len;
- mswitches[n_mswitches].replace = (char *) 0;
- mswitches[n_mswitches].rep_len = 0;
- n_mswitches++;
- break;
- }
- }
+ if (switches[i].live_cond != SWITCH_IGNORE)
+ {
+ int xlen = strlen (switches[i].part1);
+ for (j = 0; j < cnt; j++)
+ if (xlen == matches[j].len
+ && ! strncmp (switches[i].part1, matches[j].str, xlen))
+ {
+ mswitches[n_mswitches].str = matches[j].replace;
+ mswitches[n_mswitches].len = matches[j].rep_len;
+ mswitches[n_mswitches].replace = (char *) 0;
+ mswitches[n_mswitches].rep_len = 0;
+ n_mswitches++;
+ break;
+ }
+ }
/* Add MULTILIB_DEFAULTS switches too, as long as they were not present
on the command line nor any options mutually incompatible with
diff --git a/gcc/gcc.h b/gcc/gcc.h
index 9df9ffd1252..f5a04d3a136 100644
--- a/gcc/gcc.h
+++ b/gcc/gcc.h
@@ -48,8 +48,8 @@ struct spec_function
|| !strcmp (STR, "imacros") || !strcmp (STR, "aux-info") \
|| !strcmp (STR, "idirafter") || !strcmp (STR, "iprefix") \
|| !strcmp (STR, "iwithprefix") || !strcmp (STR, "iwithprefixbefore") \
- || !strcmp (STR, "isystem") || !strcmp (STR, "-param") \
- || !strcmp (STR, "specs") \
+ || !strcmp (STR, "iquote") || !strcmp (STR, "isystem") \
+ || !strcmp (STR, "-param") || !strcmp (STR, "specs") \
|| !strcmp (STR, "MF") || !strcmp (STR, "MT") || !strcmp (STR, "MQ"))
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index e83c5163c90..75abbea479b 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -447,6 +447,18 @@ extern void __gcov_merge_single (gcov_type *, unsigned);
/* The merge function to choose the most common difference between
consecutive values. */
extern void __gcov_merge_delta (gcov_type *, unsigned);
+
+#ifndef inhibit_libc
+/* The wrappers around some library functions.. */
+extern pid_t __gcov_fork (void);
+extern int __gcov_execl (const char *, const char *, ...);
+extern int __gcov_execlp (const char *, const char *, ...);
+extern int __gcov_execle (const char *, const char *, ...);
+extern int __gcov_execv (const char *, char *const []);
+extern int __gcov_execvp (const char *, char *const []);
+extern int __gcov_execve (const char *, char *const [], char *const []);
+#endif
+
#endif /* IN_LIBGCOV */
#if IN_LIBGCOV >= 0
diff --git a/gcc/gcse.c b/gcc/gcse.c
index 88f94f6802e..b6d0a6b4d4a 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -192,7 +192,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
3) Perform copy/constant propagation.
- 4) Perform global cse.
+ 4) Perform global cse using lazy code motion if not optimizing
+ for size, or code hoisting if we are.
5) Perform another pass of copy/constant propagation.
@@ -485,7 +486,7 @@ static struct ls_expr * pre_ldst_mems = NULL;
static regset reg_set_bitmap;
/* For each block, a bitmap of registers set in the block.
- This is used by expr_killed_p and compute_transp.
+ This is used by compute_transp.
It is computed during hash table computation and not by compute_sets
as it includes registers added since the last pass (or between cprop and
gcse) and it's currently not easy to realloc sbitmap vectors. */
@@ -515,25 +516,8 @@ static int const_prop_count;
/* Number of copys propagated. */
static int copy_prop_count;
-/* These variables are used by classic GCSE.
- Normally they'd be defined a bit later, but `rd_gen' needs to
- be declared sooner. */
-
-/* Each block has a bitmap of each type.
- The length of each blocks bitmap is:
-
- max_cuid - for reaching definitions
- n_exprs - for available expressions
-
- Thus we view the bitmaps as 2 dimensional arrays. i.e.
- rd_kill[block_num][cuid_num]
- ae_kill[block_num][expr_num] */
-
-/* For reaching defs */
-static sbitmap *rd_kill, *rd_gen, *reaching_defs, *rd_out;
-
-/* for available exprs */
-static sbitmap *ae_kill, *ae_gen, *ae_in, *ae_out;
+/* For available exprs */
+static sbitmap *ae_kill, *ae_gen;
/* Objects of this type are passed around by the null-pointer check
removal routines. */
@@ -558,7 +542,6 @@ static void alloc_gcse_mem (rtx);
static void free_gcse_mem (void);
static void alloc_reg_set_mem (int);
static void free_reg_set_mem (void);
-static int get_bitmap_width (int, int, int);
static void record_one_set (int, rtx);
static void replace_one_set (int, rtx, rtx);
static void record_set_info (rtx, rtx, void *);
@@ -640,31 +623,8 @@ static void compute_code_hoist_data (void);
static int hoist_expr_reaches_here_p (basic_block, int, basic_block, char *);
static void hoist_code (void);
static int one_code_hoisting_pass (void);
-static void alloc_rd_mem (int, int);
-static void free_rd_mem (void);
-static void handle_rd_kill_set (rtx, int, basic_block);
-static void compute_kill_rd (void);
-static void compute_rd (void);
-static void alloc_avail_expr_mem (int, int);
-static void free_avail_expr_mem (void);
-static void compute_ae_gen (struct hash_table *);
-static int expr_killed_p (rtx, basic_block);
-static void compute_ae_kill (sbitmap *, sbitmap *, struct hash_table *);
-static int expr_reaches_here_p (struct occr *, struct expr *, basic_block,
- int);
-static rtx computing_insn (struct expr *, rtx);
-static int def_reaches_here_p (rtx, rtx);
-static int can_disregard_other_sets (struct reg_set **, rtx, int);
-static int handle_avail_expr (rtx, struct expr *);
-static int classic_gcse (void);
-static int one_classic_gcse_pass (int);
-static void invalidate_nonnull_info (rtx, rtx, void *);
-static int delete_null_pointer_checks_1 (unsigned int *, sbitmap *, sbitmap *,
- struct null_pointer_info *);
static rtx process_insert_insn (struct expr *);
static int pre_edge_insert (struct edge_list *, struct expr **);
-static int expr_reaches_here_p_work (struct occr *, struct expr *,
- basic_block, int, char *);
static int pre_expr_reaches_here_p_work (basic_block, struct expr *,
basic_block, char *);
static struct ls_expr * ldst_entry (rtx);
@@ -790,7 +750,7 @@ gcse_main (rtx f, FILE *file)
changed = one_cprop_pass (pass + 1, 0, 0);
if (optimize_size)
- changed |= one_classic_gcse_pass (pass + 1);
+ /* Do nothing. */ ;
else
{
changed |= one_pre_gcse_pass (pass + 1);
@@ -821,8 +781,7 @@ gcse_main (rtx f, FILE *file)
/* It does not make sense to run code hoisting unless we are optimizing
for code size -- it rarely makes programs faster, and can make
them bigger if we did partial redundancy elimination (when optimizing
- for space, we use a classic gcse algorithm instead of partial
- redundancy algorithms). */
+ for space, we don't run the partial redundancy algorithms). */
if (optimize_size)
{
max_gcse_regno = max_reg_num ();
@@ -1025,46 +984,6 @@ free_gcse_mem (void)
BITMAP_XFREE (modify_mem_list_set);
BITMAP_XFREE (canon_modify_mem_list_set);
}
-
-/* Many of the global optimization algorithms work by solving dataflow
- equations for various expressions. Initially, some local value is
- computed for each expression in each block. Then, the values across the
- various blocks are combined (by following flow graph edges) to arrive at
- global values. Conceptually, each set of equations is independent. We
- may therefore solve all the equations in parallel, solve them one at a
- time, or pick any intermediate approach.
-
- When you're going to need N two-dimensional bitmaps, each X (say, the
- number of blocks) by Y (say, the number of expressions), call this
- function. It's not important what X and Y represent; only that Y
- correspond to the things that can be done in parallel. This function will
- return an appropriate chunking factor C; you should solve C sets of
- equations in parallel. By going through this function, we can easily
- trade space against time; by solving fewer equations in parallel we use
- less space. */
-
-static int
-get_bitmap_width (int n, int x, int y)
-{
- /* It's not really worth figuring out *exactly* how much memory will
- be used by a particular choice. The important thing is to get
- something approximately right. */
- size_t max_bitmap_memory = 10 * 1024 * 1024;
-
- /* The number of bytes we'd use for a single column of minimum
- width. */
- size_t column_size = n * x * sizeof (SBITMAP_ELT_TYPE);
-
- /* Often, it's reasonable just to solve all the equations in
- parallel. */
- if (column_size * SBITMAP_SET_SIZE (y) <= max_bitmap_memory)
- return y;
-
- /* Otherwise, pick the largest width we can, without going over the
- limit. */
- return SBITMAP_ELT_BITS * ((max_bitmap_memory + column_size - 1)
- / column_size);
-}
/* Compute the local properties of each recorded expression.
@@ -1281,7 +1200,6 @@ want_to_gcse_p (rtx x)
case CONST_DOUBLE:
case CONST_VECTOR:
case CALL:
- case CONSTANT_P_RTX:
return 0;
default:
@@ -2141,9 +2059,6 @@ gcse_constant_p (rtx x)
&& ! FLOAT_MODE_P (GET_MODE (XEXP (x, 1))))
return true;
- if (GET_CODE (x) == CONSTANT_P_RTX)
- return false;
-
return CONSTANT_P (x);
}
@@ -2882,761 +2797,6 @@ mark_oprs_set (rtx insn)
}
-/* Classic GCSE reaching definition support. */
-
-/* Allocate reaching def variables. */
-
-static void
-alloc_rd_mem (int n_blocks, int n_insns)
-{
- rd_kill = sbitmap_vector_alloc (n_blocks, n_insns);
- sbitmap_vector_zero (rd_kill, n_blocks);
-
- rd_gen = sbitmap_vector_alloc (n_blocks, n_insns);
- sbitmap_vector_zero (rd_gen, n_blocks);
-
- reaching_defs = sbitmap_vector_alloc (n_blocks, n_insns);
- sbitmap_vector_zero (reaching_defs, n_blocks);
-
- rd_out = sbitmap_vector_alloc (n_blocks, n_insns);
- sbitmap_vector_zero (rd_out, n_blocks);
-}
-
-/* Free reaching def variables. */
-
-static void
-free_rd_mem (void)
-{
- sbitmap_vector_free (rd_kill);
- sbitmap_vector_free (rd_gen);
- sbitmap_vector_free (reaching_defs);
- sbitmap_vector_free (rd_out);
-}
-
-/* Add INSN to the kills of BB. REGNO, set in BB, is killed by INSN. */
-
-static void
-handle_rd_kill_set (rtx insn, int regno, basic_block bb)
-{
- struct reg_set *this_reg;
-
- for (this_reg = reg_set_table[regno]; this_reg; this_reg = this_reg ->next)
- if (BLOCK_NUM (this_reg->insn) != BLOCK_NUM (insn))
- SET_BIT (rd_kill[bb->index], INSN_CUID (this_reg->insn));
-}
-
-/* Compute the set of kill's for reaching definitions. */
-
-static void
-compute_kill_rd (void)
-{
- int cuid;
- unsigned int regno;
- int i;
- basic_block bb;
-
- /* For each block
- For each set bit in `gen' of the block (i.e each insn which
- generates a definition in the block)
- Call the reg set by the insn corresponding to that bit regx
- Look at the linked list starting at reg_set_table[regx]
- For each setting of regx in the linked list, which is not in
- this block
- Set the bit in `kill' corresponding to that insn. */
- FOR_EACH_BB (bb)
- for (cuid = 0; cuid < max_cuid; cuid++)
- if (TEST_BIT (rd_gen[bb->index], cuid))
- {
- rtx insn = CUID_INSN (cuid);
- rtx pat = PATTERN (insn);
-
- if (GET_CODE (insn) == CALL_INSN)
- {
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
- handle_rd_kill_set (insn, regno, bb);
- }
-
- if (GET_CODE (pat) == PARALLEL)
- {
- for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
- {
- enum rtx_code code = GET_CODE (XVECEXP (pat, 0, i));
-
- if ((code == SET || code == CLOBBER)
- && GET_CODE (XEXP (XVECEXP (pat, 0, i), 0)) == REG)
- handle_rd_kill_set (insn,
- REGNO (XEXP (XVECEXP (pat, 0, i), 0)),
- bb);
- }
- }
- else if (GET_CODE (pat) == SET && GET_CODE (SET_DEST (pat)) == REG)
- /* Each setting of this register outside of this block
- must be marked in the set of kills in this block. */
- handle_rd_kill_set (insn, REGNO (SET_DEST (pat)), bb);
- }
-}
-
-/* Compute the reaching definitions as in
- Compilers Principles, Techniques, and Tools. Aho, Sethi, Ullman,
- Chapter 10. It is the same algorithm as used for computing available
- expressions but applied to the gens and kills of reaching definitions. */
-
-static void
-compute_rd (void)
-{
- int changed, passes;
- basic_block bb;
-
- FOR_EACH_BB (bb)
- sbitmap_copy (rd_out[bb->index] /*dst*/, rd_gen[bb->index] /*src*/);
-
- passes = 0;
- changed = 1;
- while (changed)
- {
- changed = 0;
- FOR_EACH_BB (bb)
- {
- sbitmap_union_of_preds (reaching_defs[bb->index], rd_out, bb->index);
- changed |= sbitmap_union_of_diff_cg (rd_out[bb->index], rd_gen[bb->index],
- reaching_defs[bb->index], rd_kill[bb->index]);
- }
- passes++;
- }
-
- if (gcse_file)
- fprintf (gcse_file, "reaching def computation: %d passes\n", passes);
-}
-
-/* Classic GCSE available expression support. */
-
-/* Allocate memory for available expression computation. */
-
-static void
-alloc_avail_expr_mem (int n_blocks, int n_exprs)
-{
- ae_kill = sbitmap_vector_alloc (n_blocks, n_exprs);
- sbitmap_vector_zero (ae_kill, n_blocks);
-
- ae_gen = sbitmap_vector_alloc (n_blocks, n_exprs);
- sbitmap_vector_zero (ae_gen, n_blocks);
-
- ae_in = sbitmap_vector_alloc (n_blocks, n_exprs);
- sbitmap_vector_zero (ae_in, n_blocks);
-
- ae_out = sbitmap_vector_alloc (n_blocks, n_exprs);
- sbitmap_vector_zero (ae_out, n_blocks);
-}
-
-static void
-free_avail_expr_mem (void)
-{
- sbitmap_vector_free (ae_kill);
- sbitmap_vector_free (ae_gen);
- sbitmap_vector_free (ae_in);
- sbitmap_vector_free (ae_out);
-}
-
-/* Compute the set of available expressions generated in each basic block. */
-
-static void
-compute_ae_gen (struct hash_table *expr_hash_table)
-{
- unsigned int i;
- struct expr *expr;
- struct occr *occr;
-
- /* For each recorded occurrence of each expression, set ae_gen[bb][expr].
- This is all we have to do because an expression is not recorded if it
- is not available, and the only expressions we want to work with are the
- ones that are recorded. */
- for (i = 0; i < expr_hash_table->size; i++)
- for (expr = expr_hash_table->table[i]; expr != 0; expr = expr->next_same_hash)
- for (occr = expr->avail_occr; occr != 0; occr = occr->next)
- SET_BIT (ae_gen[BLOCK_NUM (occr->insn)], expr->bitmap_index);
-}
-
-/* Return nonzero if expression X is killed in BB. */
-
-static int
-expr_killed_p (rtx x, basic_block bb)
-{
- int i, j;
- enum rtx_code code;
- const char *fmt;
-
- if (x == 0)
- return 1;
-
- code = GET_CODE (x);
- switch (code)
- {
- case REG:
- return TEST_BIT (reg_set_in_block[bb->index], REGNO (x));
-
- case MEM:
- if (load_killed_in_block_p (bb, get_max_uid () + 1, x, 0))
- return 1;
- else
- return expr_killed_p (XEXP (x, 0), bb);
-
- case PC:
- case CC0: /*FIXME*/
- case CONST:
- case CONST_INT:
- case CONST_DOUBLE:
- case CONST_VECTOR:
- case SYMBOL_REF:
- case LABEL_REF:
- case ADDR_VEC:
- case ADDR_DIFF_VEC:
- return 0;
-
- default:
- break;
- }
-
- for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--)
- {
- if (fmt[i] == 'e')
- {
- /* If we are about to do the last recursive call
- needed at this level, change it into iteration.
- This function is called enough to be worth it. */
- if (i == 0)
- return expr_killed_p (XEXP (x, i), bb);
- else if (expr_killed_p (XEXP (x, i), bb))
- return 1;
- }
- else if (fmt[i] == 'E')
- for (j = 0; j < XVECLEN (x, i); j++)
- if (expr_killed_p (XVECEXP (x, i, j), bb))
- return 1;
- }
-
- return 0;
-}
-
-/* Compute the set of available expressions killed in each basic block. */
-
-static void
-compute_ae_kill (sbitmap *ae_gen, sbitmap *ae_kill,
- struct hash_table *expr_hash_table)
-{
- basic_block bb;
- unsigned int i;
- struct expr *expr;
-
- FOR_EACH_BB (bb)
- for (i = 0; i < expr_hash_table->size; i++)
- for (expr = expr_hash_table->table[i]; expr; expr = expr->next_same_hash)
- {
- /* Skip EXPR if generated in this block. */
- if (TEST_BIT (ae_gen[bb->index], expr->bitmap_index))
- continue;
-
- if (expr_killed_p (expr->expr, bb))
- SET_BIT (ae_kill[bb->index], expr->bitmap_index);
- }
-}
-
-/* Actually perform the Classic GCSE optimizations. */
-
-/* Return nonzero if occurrence OCCR of expression EXPR reaches block BB.
-
- CHECK_SELF_LOOP is nonzero if we should consider a block reaching itself
- as a positive reach. We want to do this when there are two computations
- of the expression in the block.
-
- VISITED is a pointer to a working buffer for tracking which BB's have
- been visited. It is NULL for the top-level call.
-
- We treat reaching expressions that go through blocks containing the same
- reaching expression as "not reaching". E.g. if EXPR is generated in blocks
- 2 and 3, INSN is in block 4, and 2->3->4, we treat the expression in block
- 2 as not reaching. The intent is to improve the probability of finding
- only one reaching expression and to reduce register lifetimes by picking
- the closest such expression. */
-
-static int
-expr_reaches_here_p_work (struct occr *occr, struct expr *expr,
- basic_block bb, int check_self_loop, char *visited)
-{
- edge pred;
-
- for (pred = bb->pred; pred != NULL; pred = pred->pred_next)
- {
- basic_block pred_bb = pred->src;
-
- if (visited[pred_bb->index])
- /* This predecessor has already been visited. Nothing to do. */
- ;
- else if (pred_bb == bb)
- {
- /* BB loops on itself. */
- if (check_self_loop
- && TEST_BIT (ae_gen[pred_bb->index], expr->bitmap_index)
- && BLOCK_NUM (occr->insn) == pred_bb->index)
- return 1;
-
- visited[pred_bb->index] = 1;
- }
-
- /* Ignore this predecessor if it kills the expression. */
- else if (TEST_BIT (ae_kill[pred_bb->index], expr->bitmap_index))
- visited[pred_bb->index] = 1;
-
- /* Does this predecessor generate this expression? */
- else if (TEST_BIT (ae_gen[pred_bb->index], expr->bitmap_index))
- {
- /* Is this the occurrence we're looking for?
- Note that there's only one generating occurrence per block
- so we just need to check the block number. */
- if (BLOCK_NUM (occr->insn) == pred_bb->index)
- return 1;
-
- visited[pred_bb->index] = 1;
- }
-
- /* Neither gen nor kill. */
- else
- {
- visited[pred_bb->index] = 1;
- if (expr_reaches_here_p_work (occr, expr, pred_bb, check_self_loop,
- visited))
-
- return 1;
- }
- }
-
- /* All paths have been checked. */
- return 0;
-}
-
-/* This wrapper for expr_reaches_here_p_work() is to ensure that any
- memory allocated for that function is returned. */
-
-static int
-expr_reaches_here_p (struct occr *occr, struct expr *expr, basic_block bb,
- int check_self_loop)
-{
- int rval;
- char *visited = xcalloc (last_basic_block, 1);
-
- rval = expr_reaches_here_p_work (occr, expr, bb, check_self_loop, visited);
-
- free (visited);
- return rval;
-}
-
-/* Return the instruction that computes EXPR that reaches INSN's basic block.
- If there is more than one such instruction, return NULL.
-
- Called only by handle_avail_expr. */
-
-static rtx
-computing_insn (struct expr *expr, rtx insn)
-{
- basic_block bb = BLOCK_FOR_INSN (insn);
-
- if (expr->avail_occr->next == NULL)
- {
- if (BLOCK_FOR_INSN (expr->avail_occr->insn) == bb)
- /* The available expression is actually itself
- (i.e. a loop in the flow graph) so do nothing. */
- return NULL;
-
- /* (FIXME) Case that we found a pattern that was created by
- a substitution that took place. */
- return expr->avail_occr->insn;
- }
- else
- {
- /* Pattern is computed more than once.
- Search backwards from this insn to see how many of these
- computations actually reach this insn. */
- struct occr *occr;
- rtx insn_computes_expr = NULL;
- int can_reach = 0;
-
- for (occr = expr->avail_occr; occr != NULL; occr = occr->next)
- {
- if (BLOCK_FOR_INSN (occr->insn) == bb)
- {
- /* The expression is generated in this block.
- The only time we care about this is when the expression
- is generated later in the block [and thus there's a loop].
- We let the normal cse pass handle the other cases. */
- if (INSN_CUID (insn) < INSN_CUID (occr->insn)
- && expr_reaches_here_p (occr, expr, bb, 1))
- {
- can_reach++;
- if (can_reach > 1)
- return NULL;
-
- insn_computes_expr = occr->insn;
- }
- }
- else if (expr_reaches_here_p (occr, expr, bb, 0))
- {
- can_reach++;
- if (can_reach > 1)
- return NULL;
-
- insn_computes_expr = occr->insn;
- }
- }
-
- if (insn_computes_expr == NULL)
- abort ();
-
- return insn_computes_expr;
- }
-}
-
-/* Return nonzero if the definition in DEF_INSN can reach INSN.
- Only called by can_disregard_other_sets. */
-
-static int
-def_reaches_here_p (rtx insn, rtx def_insn)
-{
- rtx reg;
-
- if (TEST_BIT (reaching_defs[BLOCK_NUM (insn)], INSN_CUID (def_insn)))
- return 1;
-
- if (BLOCK_NUM (insn) == BLOCK_NUM (def_insn))
- {
- if (INSN_CUID (def_insn) < INSN_CUID (insn))
- {
- if (GET_CODE (PATTERN (def_insn)) == PARALLEL)
- return 1;
- else if (GET_CODE (PATTERN (def_insn)) == CLOBBER)
- reg = XEXP (PATTERN (def_insn), 0);
- else if (GET_CODE (PATTERN (def_insn)) == SET)
- reg = SET_DEST (PATTERN (def_insn));
- else
- abort ();
-
- return ! reg_set_between_p (reg, NEXT_INSN (def_insn), insn);
- }
- else
- return 0;
- }
-
- return 0;
-}
-
-/* Return nonzero if *ADDR_THIS_REG can only have one value at INSN. The
- value returned is the number of definitions that reach INSN. Returning a
- value of zero means that [maybe] more than one definition reaches INSN and
- the caller can't perform whatever optimization it is trying. i.e. it is
- always safe to return zero. */
-
-static int
-can_disregard_other_sets (struct reg_set **addr_this_reg, rtx insn, int for_combine)
-{
- int number_of_reaching_defs = 0;
- struct reg_set *this_reg;
-
- for (this_reg = *addr_this_reg; this_reg != 0; this_reg = this_reg->next)
- if (def_reaches_here_p (insn, this_reg->insn))
- {
- number_of_reaching_defs++;
- /* Ignore parallels for now. */
- if (GET_CODE (PATTERN (this_reg->insn)) == PARALLEL)
- return 0;
-
- if (!for_combine
- && (GET_CODE (PATTERN (this_reg->insn)) == CLOBBER
- || ! rtx_equal_p (SET_SRC (PATTERN (this_reg->insn)),
- SET_SRC (PATTERN (insn)))))
- /* A setting of the reg to a different value reaches INSN. */
- return 0;
-
- if (number_of_reaching_defs > 1)
- {
- /* If in this setting the value the register is being set to is
- equal to the previous value the register was set to and this
- setting reaches the insn we are trying to do the substitution
- on then we are ok. */
- if (GET_CODE (PATTERN (this_reg->insn)) == CLOBBER)
- return 0;
- else if (! rtx_equal_p (SET_SRC (PATTERN (this_reg->insn)),
- SET_SRC (PATTERN (insn))))
- return 0;
- }
-
- *addr_this_reg = this_reg;
- }
-
- return number_of_reaching_defs;
-}
-
-/* Expression computed by insn is available and the substitution is legal,
- so try to perform the substitution.
-
- The result is nonzero if any changes were made. */
-
-static int
-handle_avail_expr (rtx insn, struct expr *expr)
-{
- rtx pat, insn_computes_expr, expr_set;
- rtx to;
- struct reg_set *this_reg;
- int found_setting, use_src;
- int changed = 0;
-
- /* We only handle the case where one computation of the expression
- reaches this instruction. */
- insn_computes_expr = computing_insn (expr, insn);
- if (insn_computes_expr == NULL)
- return 0;
- expr_set = single_set (insn_computes_expr);
- /* The set might be in a parallel with multiple sets; we could
- probably handle that, but there's currently no easy way to find
- the relevant sub-expression. */
- if (!expr_set)
- return 0;
-
- found_setting = 0;
- use_src = 0;
-
- /* At this point we know only one computation of EXPR outside of this
- block reaches this insn. Now try to find a register that the
- expression is computed into. */
- if (GET_CODE (SET_SRC (expr_set)) == REG)
- {
- /* This is the case when the available expression that reaches
- here has already been handled as an available expression. */
- unsigned int regnum_for_replacing
- = REGNO (SET_SRC (expr_set));
-
- /* If the register was created by GCSE we can't use `reg_set_table',
- however we know it's set only once. */
- if (regnum_for_replacing >= max_gcse_regno
- /* If the register the expression is computed into is set only once,
- or only one set reaches this insn, we can use it. */
- || (((this_reg = reg_set_table[regnum_for_replacing]),
- this_reg->next == NULL)
- || can_disregard_other_sets (&this_reg, insn, 0)))
- {
- use_src = 1;
- found_setting = 1;
- }
- }
-
- if (!found_setting)
- {
- unsigned int regnum_for_replacing
- = REGNO (SET_DEST (expr_set));
-
- /* This shouldn't happen. */
- if (regnum_for_replacing >= max_gcse_regno)
- abort ();
-
- this_reg = reg_set_table[regnum_for_replacing];
-
- /* If the register the expression is computed into is set only once,
- or only one set reaches this insn, use it. */
- if (this_reg->next == NULL
- || can_disregard_other_sets (&this_reg, insn, 0))
- found_setting = 1;
- }
-
- if (found_setting)
- {
- pat = PATTERN (insn);
- if (use_src)
- to = SET_SRC (expr_set);
- else
- to = SET_DEST (expr_set);
- changed = validate_change (insn, &SET_SRC (pat), to, 0);
-
- /* We should be able to ignore the return code from validate_change but
- to play it safe we check. */
- if (changed)
- {
- gcse_subst_count++;
- if (gcse_file != NULL)
- {
- fprintf (gcse_file, "GCSE: Replacing the source in insn %d with",
- INSN_UID (insn));
- fprintf (gcse_file, " reg %d %s insn %d\n",
- REGNO (to), use_src ? "from" : "set in",
- INSN_UID (insn_computes_expr));
- }
- }
- }
-
- /* The register that the expr is computed into is set more than once. */
- else if (1 /*expensive_op(this_pattrn->op) && do_expensive_gcse)*/)
- {
- /* Insert an insn after insnx that copies the reg set in insnx
- into a new pseudo register call this new register REGN.
- From insnb until end of basic block or until REGB is set
- replace all uses of REGB with REGN. */
- rtx new_insn;
-
- to = gen_reg_rtx (GET_MODE (SET_DEST (expr_set)));
-
- /* Generate the new insn. */
- /* ??? If the change fails, we return 0, even though we created
- an insn. I think this is ok. */
- new_insn
- = emit_insn_after (gen_rtx_SET (VOIDmode, to,
- SET_DEST (expr_set)),
- insn_computes_expr);
-
- /* Keep register set table up to date. */
- record_one_set (REGNO (to), new_insn);
-
- gcse_create_count++;
- if (gcse_file != NULL)
- {
- fprintf (gcse_file, "GCSE: Creating insn %d to copy value of reg %d",
- INSN_UID (NEXT_INSN (insn_computes_expr)),
- REGNO (SET_SRC (PATTERN (NEXT_INSN (insn_computes_expr)))));
- fprintf (gcse_file, ", computed in insn %d,\n",
- INSN_UID (insn_computes_expr));
- fprintf (gcse_file, " into newly allocated reg %d\n",
- REGNO (to));
- }
-
- pat = PATTERN (insn);
-
- /* Do register replacement for INSN. */
- changed = validate_change (insn, &SET_SRC (pat),
- SET_DEST (PATTERN
- (NEXT_INSN (insn_computes_expr))),
- 0);
-
- /* We should be able to ignore the return code from validate_change but
- to play it safe we check. */
- if (changed)
- {
- gcse_subst_count++;
- if (gcse_file != NULL)
- {
- fprintf (gcse_file,
- "GCSE: Replacing the source in insn %d with reg %d ",
- INSN_UID (insn),
- REGNO (SET_DEST (PATTERN (NEXT_INSN
- (insn_computes_expr)))));
- fprintf (gcse_file, "set in insn %d\n",
- INSN_UID (insn_computes_expr));
- }
- }
- }
-
- return changed;
-}
-
-/* Perform classic GCSE. This is called by one_classic_gcse_pass after all
- the dataflow analysis has been done.
-
- The result is nonzero if a change was made. */
-
-static int
-classic_gcse (void)
-{
- int changed;
- rtx insn;
- basic_block bb;
-
- /* Note we start at block 1. */
-
- if (ENTRY_BLOCK_PTR->next_bb == EXIT_BLOCK_PTR)
- return 0;
-
- changed = 0;
- FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb->next_bb, EXIT_BLOCK_PTR, next_bb)
- {
- /* Reset tables used to keep track of what's still valid [since the
- start of the block]. */
- reset_opr_set_tables ();
-
- for (insn = BB_HEAD (bb);
- insn != NULL && insn != NEXT_INSN (BB_END (bb));
- insn = NEXT_INSN (insn))
- {
- /* Is insn of form (set (pseudo-reg) ...)? */
- if (GET_CODE (insn) == INSN
- && GET_CODE (PATTERN (insn)) == SET
- && GET_CODE (SET_DEST (PATTERN (insn))) == REG
- && REGNO (SET_DEST (PATTERN (insn))) >= FIRST_PSEUDO_REGISTER)
- {
- rtx pat = PATTERN (insn);
- rtx src = SET_SRC (pat);
- struct expr *expr;
-
- if (want_to_gcse_p (src)
- /* Is the expression recorded? */
- && ((expr = lookup_expr (src, &expr_hash_table)) != NULL)
- /* Is the expression available [at the start of the
- block]? */
- && TEST_BIT (ae_in[bb->index], expr->bitmap_index)
- /* Are the operands unchanged since the start of the
- block? */
- && oprs_not_set_p (src, insn))
- changed |= handle_avail_expr (insn, expr);
- }
-
- /* Keep track of everything modified by this insn. */
- /* ??? Need to be careful w.r.t. mods done to INSN. */
- if (INSN_P (insn))
- mark_oprs_set (insn);
- }
- }
-
- return changed;
-}
-
-/* Top level routine to perform one classic GCSE pass.
-
- Return nonzero if a change was made. */
-
-static int
-one_classic_gcse_pass (int pass)
-{
- int changed = 0;
-
- gcse_subst_count = 0;
- gcse_create_count = 0;
-
- alloc_hash_table (max_cuid, &expr_hash_table, 0);
- alloc_rd_mem (last_basic_block, max_cuid);
- compute_hash_table (&expr_hash_table);
- if (gcse_file)
- dump_hash_table (gcse_file, "Expression", &expr_hash_table);
-
- if (expr_hash_table.n_elems > 0)
- {
- compute_kill_rd ();
- compute_rd ();
- alloc_avail_expr_mem (last_basic_block, expr_hash_table.n_elems);
- compute_ae_gen (&expr_hash_table);
- compute_ae_kill (ae_gen, ae_kill, &expr_hash_table);
- compute_available (ae_gen, ae_kill, ae_out, ae_in);
- changed = classic_gcse ();
- free_avail_expr_mem ();
- }
-
- free_rd_mem ();
- free_hash_table (&expr_hash_table);
-
- if (gcse_file)
- {
- fprintf (gcse_file, "\n");
- fprintf (gcse_file, "GCSE of %s, pass %d: %d bytes needed, %d substs,",
- current_function_name (), pass, bytes_used, gcse_subst_count);
- fprintf (gcse_file, "%d insns created\n", gcse_create_count);
- }
-
- return changed;
-}
-
/* Compute copy/constant propagation working variables. */
/* Local properties of assignments. */
@@ -4773,7 +3933,7 @@ reg_killed_on_edge (rtx reg, edge e)
{
rtx insn;
- for (insn = e->insns; insn; insn = NEXT_INSN (insn))
+ for (insn = e->insns.r; insn; insn = NEXT_INSN (insn))
if (INSN_P (insn) && reg_set_p (reg, insn))
return true;
@@ -4850,7 +4010,7 @@ bypass_block (basic_block bb, rtx setcc, rtx jump)
continue;
/* Check the data flow is valid after edge insertions. */
- if (e->insns && reg_killed_on_edge (reg_used->reg_rtx, e))
+ if (e->insns.r && reg_killed_on_edge (reg_used->reg_rtx, e))
continue;
src = SET_SRC (pc_set (jump));
@@ -4871,14 +4031,14 @@ bypass_block (basic_block bb, rtx setcc, rtx jump)
if (new == pc_rtx)
{
edest = FALLTHRU_EDGE (bb);
- dest = edest->insns ? NULL : edest->dest;
+ dest = edest->insns.r ? NULL : edest->dest;
}
else if (GET_CODE (new) == LABEL_REF)
{
dest = BLOCK_FOR_INSN (XEXP (new, 0));
/* Don't bypass edges containing instructions. */
for (edest = bb->succ; edest; edest = edest->succ_next)
- if (edest->dest == dest && edest->insns)
+ if (edest->dest == dest && edest->insns.r)
{
dest = NULL;
break;
@@ -5050,8 +4210,6 @@ alloc_pre_mem (int n_blocks, int n_exprs)
pre_redundant = NULL;
pre_insert_map = NULL;
pre_delete_map = NULL;
- ae_in = NULL;
- ae_out = NULL;
ae_kill = sbitmap_vector_alloc (n_blocks, n_exprs);
/* pre_insert and pre_delete are allocated later. */
@@ -5075,14 +4233,9 @@ free_pre_mem (void)
sbitmap_vector_free (pre_insert_map);
if (pre_delete_map)
sbitmap_vector_free (pre_delete_map);
- if (ae_in)
- sbitmap_vector_free (ae_in);
- if (ae_out)
- sbitmap_vector_free (ae_out);
transp = comp = NULL;
pre_optimal = pre_redundant = pre_insert_map = pre_delete_map = NULL;
- ae_in = ae_out = NULL;
}
/* Top level routine to do the dataflow analysis needed by PRE. */
@@ -5111,8 +4264,7 @@ compute_pre_data (void)
/* Compute ae_kill for each basic block using:
~(TRANSP | COMP)
-
- This is significantly faster than compute_ae_kill. */
+ */
FOR_EACH_BB (bb)
{
@@ -5917,295 +5069,6 @@ compute_transpout (void)
}
}
-/* Removal of useless null pointer checks */
-
-/* Called via note_stores. X is set by SETTER. If X is a register we must
- invalidate nonnull_local and set nonnull_killed. DATA is really a
- `null_pointer_info *'.
-
- We ignore hard registers. */
-
-static void
-invalidate_nonnull_info (rtx x, rtx setter ATTRIBUTE_UNUSED, void *data)
-{
- unsigned int regno;
- struct null_pointer_info *npi = (struct null_pointer_info *) data;
-
- while (GET_CODE (x) == SUBREG)
- x = SUBREG_REG (x);
-
- /* Ignore anything that is not a register or is a hard register. */
- if (GET_CODE (x) != REG
- || REGNO (x) < npi->min_reg
- || REGNO (x) >= npi->max_reg)
- return;
-
- regno = REGNO (x) - npi->min_reg;
-
- RESET_BIT (npi->nonnull_local[npi->current_block->index], regno);
- SET_BIT (npi->nonnull_killed[npi->current_block->index], regno);
-}
-
-/* Do null-pointer check elimination for the registers indicated in
- NPI. NONNULL_AVIN and NONNULL_AVOUT are pre-allocated sbitmaps;
- they are not our responsibility to free. */
-
-static int
-delete_null_pointer_checks_1 (unsigned int *block_reg, sbitmap *nonnull_avin,
- sbitmap *nonnull_avout,
- struct null_pointer_info *npi)
-{
- basic_block bb, current_block;
- sbitmap *nonnull_local = npi->nonnull_local;
- sbitmap *nonnull_killed = npi->nonnull_killed;
- int something_changed = 0;
-
- /* Compute local properties, nonnull and killed. A register will have
- the nonnull property if at the end of the current block its value is
- known to be nonnull. The killed property indicates that somewhere in
- the block any information we had about the register is killed.
-
- Note that a register can have both properties in a single block. That
- indicates that it's killed, then later in the block a new value is
- computed. */
- sbitmap_vector_zero (nonnull_local, last_basic_block);
- sbitmap_vector_zero (nonnull_killed, last_basic_block);
-
- FOR_EACH_BB (current_block)
- {
- rtx insn, stop_insn;
-
- /* Set the current block for invalidate_nonnull_info. */
- npi->current_block = current_block;
-
- /* Scan each insn in the basic block looking for memory references and
- register sets. */
- stop_insn = NEXT_INSN (BB_END (current_block));
- for (insn = BB_HEAD (current_block);
- insn != stop_insn;
- insn = NEXT_INSN (insn))
- {
- rtx set;
- rtx reg;
-
- /* Ignore anything that is not a normal insn. */
- if (! INSN_P (insn))
- continue;
-
- /* Basically ignore anything that is not a simple SET. We do have
- to make sure to invalidate nonnull_local and set nonnull_killed
- for such insns though. */
- set = single_set (insn);
- if (!set)
- {
- note_stores (PATTERN (insn), invalidate_nonnull_info, npi);
- continue;
- }
-
- /* See if we've got a usable memory load. We handle it first
- in case it uses its address register as a dest (which kills
- the nonnull property). */
- if (GET_CODE (SET_SRC (set)) == MEM
- && GET_CODE ((reg = XEXP (SET_SRC (set), 0))) == REG
- && REGNO (reg) >= npi->min_reg
- && REGNO (reg) < npi->max_reg)
- SET_BIT (nonnull_local[current_block->index],
- REGNO (reg) - npi->min_reg);
-
- /* Now invalidate stuff clobbered by this insn. */
- note_stores (PATTERN (insn), invalidate_nonnull_info, npi);
-
- /* And handle stores, we do these last since any sets in INSN can
- not kill the nonnull property if it is derived from a MEM
- appearing in a SET_DEST. */
- if (GET_CODE (SET_DEST (set)) == MEM
- && GET_CODE ((reg = XEXP (SET_DEST (set), 0))) == REG
- && REGNO (reg) >= npi->min_reg
- && REGNO (reg) < npi->max_reg)
- SET_BIT (nonnull_local[current_block->index],
- REGNO (reg) - npi->min_reg);
- }
- }
-
- /* Now compute global properties based on the local properties. This
- is a classic global availability algorithm. */
- compute_available (nonnull_local, nonnull_killed,
- nonnull_avout, nonnull_avin);
-
- /* Now look at each bb and see if it ends with a compare of a value
- against zero. */
- FOR_EACH_BB (bb)
- {
- rtx last_insn = BB_END (bb);
- rtx condition, earliest;
- int compare_and_branch;
-
- /* Since MIN_REG is always at least FIRST_PSEUDO_REGISTER, and
- since BLOCK_REG[BB] is zero if this block did not end with a
- comparison against zero, this condition works. */
- if (block_reg[bb->index] < npi->min_reg
- || block_reg[bb->index] >= npi->max_reg)
- continue;
-
- /* LAST_INSN is a conditional jump. Get its condition. */
- condition = get_condition (last_insn, &earliest, false);
-
- /* If we can't determine the condition then skip. */
- if (! condition)
- continue;
-
- /* Is the register known to have a nonzero value? */
- if (!TEST_BIT (nonnull_avout[bb->index], block_reg[bb->index] - npi->min_reg))
- continue;
-
- /* Try to compute whether the compare/branch at the loop end is one or
- two instructions. */
- if (earliest == last_insn)
- compare_and_branch = 1;
- else if (earliest == prev_nonnote_insn (last_insn))
- compare_and_branch = 2;
- else
- continue;
-
- /* We know the register in this comparison is nonnull at exit from
- this block. We can optimize this comparison. */
- if (GET_CODE (condition) == NE)
- {
- rtx new_jump;
-
- new_jump = emit_jump_insn_after (gen_jump (JUMP_LABEL (last_insn)),
- last_insn);
- JUMP_LABEL (new_jump) = JUMP_LABEL (last_insn);
- LABEL_NUSES (JUMP_LABEL (new_jump))++;
- emit_barrier_after (new_jump);
- }
-
- something_changed = 1;
- delete_insn (last_insn);
-#ifdef HAVE_cc0
- if (compare_and_branch == 2)
- delete_insn (earliest);
-#endif
- purge_dead_edges (bb);
-
- /* Don't check this block again. (Note that BB_END is
- invalid here; we deleted the last instruction in the
- block.) */
- block_reg[bb->index] = 0;
- }
-
- return something_changed;
-}
-
-/* Find EQ/NE comparisons against zero which can be (indirectly) evaluated
- at compile time.
-
- This is conceptually similar to global constant/copy propagation and
- classic global CSE (it even uses the same dataflow equations as cprop).
-
- If a register is used as memory address with the form (mem (reg)), then we
- know that REG can not be zero at that point in the program. Any instruction
- which sets REG "kills" this property.
-
- So, if every path leading to a conditional branch has an available memory
- reference of that form, then we know the register can not have the value
- zero at the conditional branch.
-
- So we merely need to compute the local properties and propagate that data
- around the cfg, then optimize where possible.
-
- We run this pass two times. Once before CSE, then again after CSE. This
- has proven to be the most profitable approach. It is rare for new
- optimization opportunities of this nature to appear after the first CSE
- pass.
-
- This could probably be integrated with global cprop with a little work. */
-
-int
-delete_null_pointer_checks (rtx f ATTRIBUTE_UNUSED)
-{
- sbitmap *nonnull_avin, *nonnull_avout;
- unsigned int *block_reg;
- basic_block bb;
- int reg;
- int regs_per_pass;
- int max_reg = max_reg_num ();
- struct null_pointer_info npi;
- int something_changed = 0;
-
- /* If we have only a single block, or it is too expensive, give up. */
- if (n_basic_blocks <= 1
- || is_too_expensive (_ ("NULL pointer checks disabled")))
- return 0;
-
- /* We need four bitmaps, each with a bit for each register in each
- basic block. */
- regs_per_pass = get_bitmap_width (4, last_basic_block, max_reg);
-
- /* Allocate bitmaps to hold local and global properties. */
- npi.nonnull_local = sbitmap_vector_alloc (last_basic_block, regs_per_pass);
- npi.nonnull_killed = sbitmap_vector_alloc (last_basic_block, regs_per_pass);
- nonnull_avin = sbitmap_vector_alloc (last_basic_block, regs_per_pass);
- nonnull_avout = sbitmap_vector_alloc (last_basic_block, regs_per_pass);
-
- /* Go through the basic blocks, seeing whether or not each block
- ends with a conditional branch whose condition is a comparison
- against zero. Record the register compared in BLOCK_REG. */
- block_reg = xcalloc (last_basic_block, sizeof (int));
- FOR_EACH_BB (bb)
- {
- rtx last_insn = BB_END (bb);
- rtx condition, earliest, reg;
-
- /* We only want conditional branches. */
- if (GET_CODE (last_insn) != JUMP_INSN
- || !any_condjump_p (last_insn)
- || !onlyjump_p (last_insn))
- continue;
-
- /* LAST_INSN is a conditional jump. Get its condition. */
- condition = get_condition (last_insn, &earliest, false);
-
- /* If we were unable to get the condition, or it is not an equality
- comparison against zero then there's nothing we can do. */
- if (!condition
- || (GET_CODE (condition) != NE && GET_CODE (condition) != EQ)
- || GET_CODE (XEXP (condition, 1)) != CONST_INT
- || (XEXP (condition, 1)
- != CONST0_RTX (GET_MODE (XEXP (condition, 0)))))
- continue;
-
- /* We must be checking a register against zero. */
- reg = XEXP (condition, 0);
- if (GET_CODE (reg) != REG)
- continue;
-
- block_reg[bb->index] = REGNO (reg);
- }
-
- /* Go through the algorithm for each block of registers. */
- for (reg = FIRST_PSEUDO_REGISTER; reg < max_reg; reg += regs_per_pass)
- {
- npi.min_reg = reg;
- npi.max_reg = MIN (reg + regs_per_pass, max_reg);
- something_changed |= delete_null_pointer_checks_1 (block_reg,
- nonnull_avin,
- nonnull_avout,
- &npi);
- }
-
- /* Free the table of registers compared at the end of every block. */
- free (block_reg);
-
- /* Free bitmaps. */
- sbitmap_vector_free (npi.nonnull_local);
- sbitmap_vector_free (npi.nonnull_killed);
- sbitmap_vector_free (nonnull_avin);
- sbitmap_vector_free (nonnull_avout);
-
- return something_changed;
-}
-
/* Code Hoisting variables and subroutines. */
/* Very busy expressions. */
@@ -7175,6 +6038,11 @@ find_moveable_store (rtx insn, int *regs_set_before, int *regs_set_after)
if (flag_non_call_exceptions && may_trap_p (dest))
return;
+ /* Even if the destination cannot trap, the source may. In this case we'd
+ need to handle updating the REG_EH_REGION note. */
+ if (find_reg_note (insn, REG_EH_REGION, NULL_RTX))
+ return;
+
ptr = ldst_entry (dest);
if (!ptr->pattern_regs)
ptr->pattern_regs = extract_mentioned_regs (dest);
@@ -7792,8 +6660,7 @@ remove_reachable_equiv_notes (basic_block bb, struct ls_expr *smexpr)
bb = act->dest;
if (bb == EXIT_BLOCK_PTR
- || TEST_BIT (visited, bb->index)
- || TEST_BIT (ae_kill[bb->index], smexpr->index))
+ || TEST_BIT (visited, bb->index))
{
act = act->succ_next;
continue;
@@ -8146,7 +7013,7 @@ reg_used_on_edge (rtx reg, edge e)
{
rtx insn;
- for (insn = e->insns; insn; insn = NEXT_INSN (insn))
+ for (insn = e->insns.r; insn; insn = NEXT_INSN (insn))
if (INSN_P (insn) && reg_overlap_mentioned_p (reg, PATTERN (insn)))
return true;
@@ -8397,14 +7264,14 @@ eliminate_partially_redundant_loads (basic_block bb, rtx insn,
if (npred_ok == 0 /* No load can be replaced by copy. */
|| (optimize_size && npred_ok > 1)) /* Prevent exploding the code. */
- return;
+ goto cleanup;
/* Check if it's worth applying the partial redundancy elimination. */
if (ok_count < GCSE_AFTER_RELOAD_PARTIAL_FRACTION * not_ok_count)
- return;
+ goto cleanup;
if (ok_count < GCSE_AFTER_RELOAD_CRITICAL_FRACTION * critical_count)
- return;
+ goto cleanup;
/* Generate moves to the loaded register from where
the memory is available. */
@@ -8457,6 +7324,22 @@ eliminate_partially_redundant_loads (basic_block bb, rtx insn,
delete_insn (insn);
else
a_occr->deleted_p = 1;
+
+cleanup:
+
+ while (unavail_occrs)
+ {
+ struct unoccr *temp = unavail_occrs->next;
+ free (unavail_occrs);
+ unavail_occrs = temp;
+ }
+
+ while (avail_occrs)
+ {
+ struct unoccr *temp = avail_occrs->next;
+ free (avail_occrs);
+ avail_occrs = temp;
+ }
}
/* Performing the redundancy elimination as described before. */
diff --git a/gcc/gdbinit.in b/gcc/gdbinit.in
index ccc6504dda7..753cd9e73bc 100644
--- a/gcc/gdbinit.in
+++ b/gcc/gdbinit.in
@@ -40,6 +40,24 @@ Print the tree that is $ in C syntax.
Works only when an inferior is executing.
end
+define pgs
+set debug_generic_stmt ($)
+end
+
+document pgs
+Print the statement that is $ in C syntax.
+Works only when an inferior is executing.
+end
+
+define pge
+set debug_generic_expr ($)
+end
+
+document pge
+Print the expression that is $ in C syntax.
+Works only when an inferior is executing.
+end
+
define ptc
output (enum tree_code) $.common.code
echo \n
diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c
index a3c035f4ef7..245c65599b1 100644
--- a/gcc/genattrtab.c
+++ b/gcc/genattrtab.c
@@ -90,14 +90,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
independent of the insn code.
`in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
for the insn code currently being processed (see optimize_attrs).
- `integrated' (ATTR_PERMANENT_P): This rtx is permanent and unique
+ `return_val' (ATTR_PERMANENT_P): This rtx is permanent and unique
(see attr_rtx).
`volatil' (ATTR_EQ_ATTR_P): During simplify_by_exploding the value of an
EQ_ATTR rtx is true if !volatil and false if volatil. */
#define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), unchanging))
#define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), in_struct))
-#define ATTR_PERMANENT_P(RTX) (RTX_FLAG((RTX), integrated))
+#define ATTR_PERMANENT_P(RTX) (RTX_FLAG((RTX), return_val))
#define ATTR_EQ_ATTR_P(RTX) (RTX_FLAG((RTX), volatil))
#if 0
diff --git a/gcc/gengtype-lex.l b/gcc/gengtype-lex.l
index 2d0462beba5..19d7691f35e 100644
--- a/gcc/gengtype-lex.l
+++ b/gcc/gengtype-lex.l
@@ -47,7 +47,7 @@ update_lineno (const char *l, size_t len)
ID [[:alpha:]_][[:alnum:]_]*
WS [[:space:]]+
-IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|bool|size_t|BOOL_BITFIELD
+IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|HOST_WIDEST_INT|bool|size_t|BOOL_BITFIELD
ITYPE {IWORD}({WS}{IWORD})*
%x in_struct in_struct_comment in_comment in_yacc_escape
diff --git a/gcc/gengtype-yacc.y b/gcc/gengtype-yacc.y
index f6a9bac2e2e..02136dc0d29 100644
--- a/gcc/gengtype-yacc.y
+++ b/gcc/gengtype-yacc.y
@@ -212,11 +212,16 @@ struct_fields: { $$ = NULL; }
p->line = lexer_line;
$$ = p;
}
+ | type ':' bitfieldlen ';' struct_fields
+ { $$ = $5; }
;
bitfieldopt: /* empty */
- | ':' NUM
- | ':' ID
+ | ':' bitfieldlen
+ ;
+
+bitfieldlen: NUM | ID
+ { }
;
type: SCALAR
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index 1bad8e4e706..1b56a839fcc 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -1095,11 +1095,12 @@ open_base_files (void)
{
/* The order of files here matters very much. */
static const char *const ifiles [] = {
- "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
+ "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
"hashtab.h", "splay-tree.h", "bitmap.h", "tree.h", "rtl.h",
"function.h", "insn-config.h", "expr.h", "hard-reg-set.h",
"basic-block.h", "cselib.h", "insn-addr.h", "optabs.h",
"libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
+ "tree-alias-type.h", "tree-flow.h",
NULL
};
const char *const *ifp;
diff --git a/gcc/genopinit.c b/gcc/genopinit.c
index fad18793e50..a7c9f7e5628 100644
--- a/gcc/genopinit.c
+++ b/gcc/genopinit.c
@@ -91,6 +91,8 @@ static const char * const optabs[] =
"udivmod_optab->handlers[$A].insn_code = CODE_FOR_$(udivmod$a4$)",
"smod_optab->handlers[$A].insn_code = CODE_FOR_$(mod$a3$)",
"umod_optab->handlers[$A].insn_code = CODE_FOR_$(umod$a3$)",
+ "fmod_optab->handlers[$A].insn_code = CODE_FOR_$(fmod$a3$)",
+ "drem_optab->handlers[$A].insn_code = CODE_FOR_$(drem$a3$)",
"ftrunc_optab->handlers[$A].insn_code = CODE_FOR_$(ftrunc$F$a2$)",
"and_optab->handlers[$A].insn_code = CODE_FOR_$(and$a3$)",
"ior_optab->handlers[$A].insn_code = CODE_FOR_$(ior$a3$)",
@@ -124,13 +126,19 @@ static const char * const optabs[] =
"nearbyint_optab->handlers[$A].insn_code = CODE_FOR_$(nearbyint$a2$)",
"sincos_optab->handlers[$A].insn_code = CODE_FOR_$(sincos$a3$)",
"sin_optab->handlers[$A].insn_code = CODE_FOR_$(sin$a2$)",
+ "asin_optab->handlers[$A].insn_code = CODE_FOR_$(asin$a2$)",
"cos_optab->handlers[$A].insn_code = CODE_FOR_$(cos$a2$)",
+ "acos_optab->handlers[$A].insn_code = CODE_FOR_$(acos$a2$)",
"exp_optab->handlers[$A].insn_code = CODE_FOR_$(exp$a2$)",
"exp10_optab->handlers[$A].insn_code = CODE_FOR_$(exp10$a2$)",
"exp2_optab->handlers[$A].insn_code = CODE_FOR_$(exp2$a2$)",
+ "expm1_optab->handlers[$A].insn_code = CODE_FOR_$(expm1$a2$)",
+ "logb_optab->handlers[$A].insn_code = CODE_FOR_$(logb$a2$)",
+ "ilogb_optab->handlers[$A].insn_code = CODE_FOR_$(ilogb$a2$)",
"log_optab->handlers[$A].insn_code = CODE_FOR_$(log$a2$)",
"log10_optab->handlers[$A].insn_code = CODE_FOR_$(log10$a2$)",
"log2_optab->handlers[$A].insn_code = CODE_FOR_$(log2$a2$)",
+ "log1p_optab->handlers[$A].insn_code = CODE_FOR_$(log1p$a2$)",
"tan_optab->handlers[$A].insn_code = CODE_FOR_$(tan$a2$)",
"atan_optab->handlers[$A].insn_code = CODE_FOR_$(atan$a2$)",
"strlen_optab->handlers[$A].insn_code = CODE_FOR_$(strlen$a$)",
diff --git a/gcc/genrecog.c b/gcc/genrecog.c
index 2d4c0911cd9..c727fec97c5 100644
--- a/gcc/genrecog.c
+++ b/gcc/genrecog.c
@@ -513,8 +513,7 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int set_code)
&& c != CONST_INT
&& c != CONST_DOUBLE
&& c != CONST
- && c != HIGH
- && c != CONSTANT_P_RTX)
+ && c != HIGH)
allows_non_const = 1;
if (c != REG
diff --git a/gcc/ggc-zone.c b/gcc/ggc-zone.c
index 51fb1f938cf..da58116fabb 100644
--- a/gcc/ggc-zone.c
+++ b/gcc/ggc-zone.c
@@ -327,7 +327,7 @@ static void free_chunk (struct alloc_chunk *, size_t, struct alloc_zone *);
static void free_page (struct page_entry *);
static void release_pages (struct alloc_zone *);
static void sweep_pages (struct alloc_zone *);
-static void * ggc_alloc_zone_1 (size_t, struct alloc_zone *, short);
+static void * ggc_alloc_zone_1 (size_t, struct alloc_zone *, short MEM_STAT_DECL);
static bool ggc_collect_1 (struct alloc_zone *, bool);
static void check_cookies (void);
@@ -569,7 +569,8 @@ free_chunk (struct alloc_chunk *chunk, size_t size, struct alloc_zone *zone)
/* Allocate a chunk of memory of SIZE bytes. */
static void *
-ggc_alloc_zone_1 (size_t size, struct alloc_zone *zone, short type)
+ggc_alloc_zone_1 (size_t size, struct alloc_zone *zone, short type
+ MEM_STAT_DECL)
{
size_t bin = 0;
size_t lsize = 0;
@@ -659,7 +660,12 @@ ggc_alloc_zone_1 (size_t size, struct alloc_zone *zone, short type)
lchunk->size = lsize;
lchunk->large = 0;
free_chunk (lchunk, lsize, zone);
+ lsize = 0;
}
+#ifdef GATHER_STATISTICS
+ ggc_record_overhead (size, lsize PASS_MEM_STAT);
+#endif
+
/* Calculate the object's address. */
found:
#ifdef COOKIE_CHECKING
@@ -701,38 +707,39 @@ ggc_alloc_zone_1 (size_t size, struct alloc_zone *zone, short type)
for that type. */
void *
-ggc_alloc_typed (enum gt_types_enum gte, size_t size)
+ggc_alloc_typed_stat (enum gt_types_enum gte, size_t size
+ MEM_STAT_DECL)
{
switch (gte)
{
case gt_ggc_e_14lang_tree_node:
- return ggc_alloc_zone_1 (size, tree_zone, gte);
+ return ggc_alloc_zone_1 (size, tree_zone, gte PASS_MEM_STAT);
case gt_ggc_e_7rtx_def:
- return ggc_alloc_zone_1 (size, rtl_zone, gte);
+ return ggc_alloc_zone_1 (size, rtl_zone, gte PASS_MEM_STAT);
case gt_ggc_e_9rtvec_def:
- return ggc_alloc_zone_1 (size, rtl_zone, gte);
+ return ggc_alloc_zone_1 (size, rtl_zone, gte PASS_MEM_STAT);
default:
- return ggc_alloc_zone_1 (size, &main_zone, gte);
+ return ggc_alloc_zone_1 (size, &main_zone, gte PASS_MEM_STAT);
}
}
/* Normal ggc_alloc simply allocates into the main zone. */
void *
-ggc_alloc (size_t size)
+ggc_alloc_stat (size_t size MEM_STAT_DECL)
{
- return ggc_alloc_zone_1 (size, &main_zone, -1);
+ return ggc_alloc_zone_1 (size, &main_zone, -1 PASS_MEM_STAT);
}
/* Zone allocation allocates into the specified zone. */
void *
-ggc_alloc_zone (size_t size, struct alloc_zone *zone)
+ggc_alloc_zone_stat (size_t size, struct alloc_zone *zone MEM_STAT_DECL)
{
- return ggc_alloc_zone_1 (size, zone, -1);
+ return ggc_alloc_zone_1 (size, zone, -1 PASS_MEM_STAT);
}
/* Poison the chunk. */
@@ -1293,7 +1300,7 @@ struct ggc_pch_data
size_t written;
};
-/* Initialize the PCH datastructure. */
+/* Initialize the PCH data structure. */
struct ggc_pch_data *
init_ggc_pch (void)
diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c
new file mode 100644
index 00000000000..56f02b7a1ee
--- /dev/null
+++ b/gcc/gimple-low.c
@@ -0,0 +1,472 @@
+/* Tree lowering pass. Lowers GIMPLE into unstructured form.
+
+ Copyright (C) 2003 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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "rtl.h"
+#include "errors.h"
+#include "varray.h"
+#include "tree-gimple.h"
+#include "tree-inline.h"
+#include "diagnostic.h"
+#include "langhooks.h"
+#include "langhooks-def.h"
+#include "tree-flow.h"
+#include "timevar.h"
+#include "except.h"
+#include "hashtab.h"
+#include "flags.h"
+#include "function.h"
+#include "expr.h"
+#include "toplev.h"
+#include "tree-pass.h"
+
+struct lower_data
+{
+ /* Block the current statement belongs to. */
+ tree block;
+};
+
+static void lower_stmt (tree_stmt_iterator *, struct lower_data *);
+static void lower_bind_expr (tree_stmt_iterator *, struct lower_data *);
+static void lower_cond_expr (tree_stmt_iterator *, struct lower_data *);
+static bool expand_var_p (tree);
+
+/* Lowers the body of current_function_decl. */
+
+static void
+lower_function_body (void)
+{
+ struct lower_data data;
+ tree *body_p = &DECL_SAVED_TREE (current_function_decl);
+ tree bind = *body_p;
+ tree_stmt_iterator i;
+
+ if (TREE_CODE (bind) != BIND_EXPR)
+ abort ();
+
+ data.block = DECL_INITIAL (current_function_decl);
+ BLOCK_SUBBLOCKS (data.block) = NULL_TREE;
+ BLOCK_CHAIN (data.block) = NULL_TREE;
+ TREE_ASM_WRITTEN (data.block) = 1;
+
+ *body_p = alloc_stmt_list ();
+ i = tsi_start (*body_p);
+ tsi_link_after (&i, bind, TSI_NEW_STMT);
+ lower_bind_expr (&i, &data);
+
+ if (data.block != DECL_INITIAL (current_function_decl))
+ abort ();
+ BLOCK_SUBBLOCKS (data.block)
+ = blocks_nreverse (BLOCK_SUBBLOCKS (data.block));
+
+ clear_block_marks (data.block);
+
+ /* Avoid producing notes for blocks. */
+ cfun->dont_emit_block_notes = 1;
+ reset_block_changes ();
+}
+
+struct tree_opt_pass pass_lower_cf =
+{
+ "lower", /* name */
+ NULL, /* gate */
+ lower_function_body, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ PROP_gimple_any, /* properties_required */
+ PROP_gimple_lcf, /* properties_provided */
+ PROP_gimple_any, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func /* todo_flags_finish */
+};
+
+
+/* Lowers the EXPR. Unlike gimplification the statements are not relowered
+ when they are changed -- if this has to be done, the lowering routine must
+ do it explicitly. DATA is passed through the recursion. */
+
+void
+lower_stmt_body (tree expr, struct lower_data *data)
+{
+ tree_stmt_iterator tsi;
+
+ for (tsi = tsi_start (expr); !tsi_end_p (tsi); )
+ lower_stmt (&tsi, data);
+}
+
+/* Lowers statement TSI. DATA is passed through the recursion. */
+
+static void
+lower_stmt (tree_stmt_iterator *tsi, struct lower_data *data)
+{
+ tree stmt = tsi_stmt (*tsi);
+
+ if (EXPR_HAS_LOCATION (stmt) && data)
+ TREE_BLOCK (stmt) = data->block;
+
+ switch (TREE_CODE (stmt))
+ {
+ case BIND_EXPR:
+ lower_bind_expr (tsi, data);
+ return;
+ case COND_EXPR:
+ lower_cond_expr (tsi, data);
+ return;
+
+ case TRY_FINALLY_EXPR:
+ case TRY_CATCH_EXPR:
+ lower_stmt_body (TREE_OPERAND (stmt, 0), data);
+ lower_stmt_body (TREE_OPERAND (stmt, 1), data);
+ break;
+ case CATCH_EXPR:
+ lower_stmt_body (CATCH_BODY (stmt), data);
+ break;
+ case EH_FILTER_EXPR:
+ lower_stmt_body (EH_FILTER_FAILURE (stmt), data);
+ break;
+
+ case NOP_EXPR:
+ case ASM_EXPR:
+ case RETURN_EXPR:
+ case MODIFY_EXPR:
+ case CALL_EXPR:
+ case GOTO_EXPR:
+ case LABEL_EXPR:
+ case VA_ARG_EXPR:
+ case SWITCH_EXPR:
+ break;
+
+ default:
+ print_node_brief (stderr, "", stmt, 0);
+ case COMPOUND_EXPR:
+ abort ();
+ }
+
+ tsi_next (tsi);
+}
+
+/* Lowers a bind_expr TSI. DATA is passed through the recursion. */
+
+static void
+lower_bind_expr (tree_stmt_iterator *tsi, struct lower_data *data)
+{
+ tree old_block = data->block;
+ tree stmt = tsi_stmt (*tsi);
+ tree new_block = BIND_EXPR_BLOCK (stmt);
+
+ if (new_block)
+ {
+ if (new_block == old_block)
+ {
+ /* The outermost block of the original function may not be the
+ outermost statement chain of the gimplified function. So we
+ may see the outermost block just inside the function. */
+ if (new_block != DECL_INITIAL (current_function_decl))
+ abort ();
+ new_block = NULL;
+ }
+ else
+ {
+ /* We do not expect to handle duplicate blocks. */
+ if (TREE_ASM_WRITTEN (new_block))
+ abort ();
+ TREE_ASM_WRITTEN (new_block) = 1;
+
+ /* Block tree may get clobbered by inlining. Normally this would
+ be fixed in rest_of_decl_compilation using block notes, but
+ since we are not going to emit them, it is up to us. */
+ BLOCK_CHAIN (new_block) = BLOCK_SUBBLOCKS (old_block);
+ BLOCK_SUBBLOCKS (old_block) = new_block;
+ BLOCK_SUBBLOCKS (new_block) = NULL_TREE;
+ BLOCK_SUPERCONTEXT (new_block) = old_block;
+
+ data->block = new_block;
+ }
+ }
+
+ record_vars (BIND_EXPR_VARS (stmt));
+ lower_stmt_body (BIND_EXPR_BODY (stmt), data);
+
+ if (new_block)
+ {
+ if (data->block != new_block)
+ abort ();
+
+ BLOCK_SUBBLOCKS (new_block)
+ = blocks_nreverse (BLOCK_SUBBLOCKS (new_block));
+ data->block = old_block;
+ }
+
+ /* The BIND_EXPR no longer carries any useful information -- kill it. */
+ tsi_link_before (tsi, BIND_EXPR_BODY (stmt), TSI_SAME_STMT);
+ tsi_delink (tsi);
+}
+
+/* Try to determine if we can fall out of the bottom of BLOCK. This guess
+ need not be 100% accurate; simply be conservative and return true if we
+ don't know. This is used only to avoid stupidly generating extra code.
+ If we're wrong, we'll just delete the extra code later. */
+
+bool
+block_may_fallthru (tree block)
+{
+ tree stmt = expr_last (block);
+
+ switch (stmt ? TREE_CODE (stmt) : ERROR_MARK)
+ {
+ case GOTO_EXPR:
+ case RETURN_EXPR:
+ case RESX_EXPR:
+ case SWITCH_EXPR:
+ /* Easy cases. If the last statement of the block implies
+ control transfer, then we can't fall through. */
+ return false;
+
+ case COND_EXPR:
+ if (block_may_fallthru (COND_EXPR_THEN (stmt)))
+ return true;
+ return block_may_fallthru (COND_EXPR_ELSE (stmt));
+
+ case BIND_EXPR:
+ return block_may_fallthru (BIND_EXPR_BODY (stmt));
+
+ case TRY_FINALLY_EXPR:
+ return block_may_fallthru (TREE_OPERAND (stmt, 1));
+
+ case MODIFY_EXPR:
+ if (TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR)
+ stmt = TREE_OPERAND (stmt, 1);
+ else
+ return true;
+ /* FALLTHRU */
+
+ case CALL_EXPR:
+ /* Functions that do not return do not fall through. */
+ return (call_expr_flags (stmt) & ECF_NORETURN) == 0;
+
+ default:
+ return true;
+ }
+}
+
+/* Lowers a cond_expr TSI. DATA is passed through the recursion. */
+
+static void
+lower_cond_expr (tree_stmt_iterator *tsi, struct lower_data *data)
+{
+ tree stmt = tsi_stmt (*tsi);
+ bool then_is_goto, else_is_goto;
+ tree then_branch, else_branch;
+ tree then_goto, else_goto;
+
+ then_branch = COND_EXPR_THEN (stmt);
+ else_branch = COND_EXPR_ELSE (stmt);
+
+ lower_stmt_body (then_branch, data);
+ lower_stmt_body (else_branch, data);
+
+ then_goto = expr_only (then_branch);
+ then_is_goto = then_goto && simple_goto_p (then_goto);
+
+ else_goto = expr_only (else_branch);
+ else_is_goto = else_goto && simple_goto_p (else_goto);
+
+ if (!then_is_goto || !else_is_goto)
+ {
+ tree then_label, else_label, end_label, t;
+
+ then_label = NULL_TREE;
+ else_label = NULL_TREE;
+ end_label = NULL_TREE;
+
+ /* Replace the cond_expr with explicit gotos. */
+ if (!then_is_goto)
+ {
+ t = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
+ if (TREE_SIDE_EFFECTS (then_branch))
+ then_label = t;
+ else
+ end_label = t;
+ then_goto = build_and_jump (&LABEL_EXPR_LABEL (t));
+ }
+
+ if (!else_is_goto)
+ {
+ t = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
+ if (TREE_SIDE_EFFECTS (else_branch))
+ else_label = t;
+ else
+ {
+ /* Both THEN and ELSE can be no-ops if one or both contained an
+ empty BIND_EXPR that was associated with the toplevel block
+ of an inlined function. In that case remove_useless_stmts
+ can't have cleaned things up for us; kill the whole
+ conditional now. */
+ if (end_label)
+ {
+ tsi_delink (tsi);
+ return;
+ }
+ else
+ end_label = t;
+ }
+ else_goto = build_and_jump (&LABEL_EXPR_LABEL (t));
+ }
+
+ if (then_label)
+ {
+ bool may_fallthru = block_may_fallthru (then_branch);
+
+ tsi_link_after (tsi, then_label, TSI_CONTINUE_LINKING);
+ tsi_link_after (tsi, then_branch, TSI_CONTINUE_LINKING);
+
+ if (else_label && may_fallthru)
+ {
+ end_label = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
+ t = build_and_jump (&LABEL_EXPR_LABEL (end_label));
+ tsi_link_after (tsi, t, TSI_CONTINUE_LINKING);
+ }
+ }
+
+ if (else_label)
+ {
+ tsi_link_after (tsi, else_label, TSI_CONTINUE_LINKING);
+ tsi_link_after (tsi, else_branch, TSI_CONTINUE_LINKING);
+ }
+
+ if (end_label)
+ tsi_link_after (tsi, end_label, TSI_CONTINUE_LINKING);
+ }
+
+ COND_EXPR_THEN (stmt) = then_goto;
+ COND_EXPR_ELSE (stmt) = else_goto;
+
+ tsi_next (tsi);
+}
+
+
+/* Record the variables in VARS. */
+
+void
+record_vars (tree vars)
+{
+ for (; vars; vars = TREE_CHAIN (vars))
+ {
+ tree var = vars;
+
+ /* Nothing to do in this case. */
+ if (DECL_EXTERNAL (var))
+ continue;
+ if (TREE_CODE (var) == FUNCTION_DECL)
+ continue;
+
+ /* Record the variable. */
+ cfun->unexpanded_var_list = tree_cons (NULL_TREE, var,
+ cfun->unexpanded_var_list);
+ }
+}
+
+/* Check whether to expand a variable VAR. */
+
+static bool
+expand_var_p (tree var)
+{
+ struct var_ann_d *ann;
+
+ if (TREE_CODE (var) != VAR_DECL)
+ return true;
+
+ ann = var_ann (var);
+
+ /* Remove all unused, unaliased temporaries. Also remove unused, unaliased
+ local variables during highly optimizing compilations. */
+ ann = var_ann (var);
+ if (ann
+ && ! ann->may_aliases
+ && ! ann->used
+ && ! ann->has_hidden_use
+ && ! TREE_ADDRESSABLE (var)
+ && ! TREE_THIS_VOLATILE (var)
+ && (DECL_ARTIFICIAL (var) || optimize >= 2))
+ return false;
+
+ return true;
+}
+
+/* Throw away variables that are unused. */
+
+static void
+remove_useless_vars (void)
+{
+ tree var, *cell;
+
+ for (cell = &cfun->unexpanded_var_list; *cell; )
+ {
+ var = TREE_VALUE (*cell);
+
+ if (!expand_var_p (var))
+ {
+ *cell = TREE_CHAIN (*cell);
+ continue;
+ }
+
+ cell = &TREE_CHAIN (*cell);
+ }
+}
+
+/* Expand variables in the unexpanded_var_list. */
+
+void
+expand_used_vars (void)
+{
+ tree cell;
+
+ cfun->unexpanded_var_list = nreverse (cfun->unexpanded_var_list);
+
+ for (cell = cfun->unexpanded_var_list; cell; cell = TREE_CHAIN (cell))
+ expand_var (TREE_VALUE (cell));
+
+ cfun->unexpanded_var_list = NULL_TREE;
+}
+
+struct tree_opt_pass pass_remove_useless_vars =
+{
+ "vars", /* name */
+ NULL, /* gate */
+ remove_useless_vars, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func /* todo_flags_finish */
+};
+
+
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
new file mode 100644
index 00000000000..787dbc34999
--- /dev/null
+++ b/gcc/gimplify.c
@@ -0,0 +1,3754 @@
+/* Tree lowering pass. This pass converts the GENERIC functions-as-trees
+ tree representation into the GIMPLE form.
+
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Major work done by Sebastian Pop <s.pop@laposte.net>,
+ Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "rtl.h"
+#include "errors.h"
+#include "varray.h"
+#include "tree-gimple.h"
+#include "tree-inline.h"
+#include "diagnostic.h"
+#include "langhooks.h"
+#include "langhooks-def.h"
+#include "tree-flow.h"
+#include "timevar.h"
+#include "except.h"
+#include "hashtab.h"
+#include "flags.h"
+#include "real.h"
+#include "function.h"
+#include "output.h"
+#include "expr.h"
+#include "ggc.h"
+
+static struct gimplify_ctx
+{
+ tree current_bind_expr;
+ bool save_stack;
+ tree temps;
+ tree conditional_cleanups;
+ int conditions;
+ tree exit_label;
+ varray_type case_labels;
+ /* The formal temporary table. Should this be persistent? */
+ htab_t temp_htab;
+} *gimplify_ctxp;
+
+
+/* Formal (expression) temporary table handling: Multiple occurrences of
+ the same scalar expression are evaluated into the same temporary. */
+
+typedef struct gimple_temp_hash_elt
+{
+ tree val; /* Key */
+ tree temp; /* Value */
+} elt_t;
+
+/* Return a hash value for a formal temporary table entry. */
+
+static hashval_t
+gimple_tree_hash (const void *p)
+{
+ tree t = ((const elt_t *)p)->val;
+ return iterative_hash_expr (t, 0);
+}
+
+/* Compare two formal temporary table entries. */
+
+static int
+gimple_tree_eq (const void *p1, const void *p2)
+{
+ tree t1 = ((const elt_t *)p1)->val;
+ tree t2 = ((const elt_t *)p2)->val;
+ enum tree_code code = TREE_CODE (t1);
+
+ if (TREE_CODE (t2) != code
+ || TREE_TYPE (t1) != TREE_TYPE (t2))
+ return 0;
+
+ if (!operand_equal_p (t1, t2, 0))
+ return 0;
+
+ /* Only allow them to compare equal if they also hash equal; otherwise
+ results are nondeterminate, and we fail bootstrap comparison. */
+ if (gimple_tree_hash (p1) != gimple_tree_hash (p2))
+ abort ();
+
+ return 1;
+}
+
+/* Set up a context for the gimplifier. */
+
+void
+push_gimplify_context (void)
+{
+ if (gimplify_ctxp)
+ abort ();
+ gimplify_ctxp
+ = (struct gimplify_ctx *) xcalloc (1, sizeof (struct gimplify_ctx));
+ gimplify_ctxp->temp_htab
+ = htab_create (1000, gimple_tree_hash, gimple_tree_eq, free);
+}
+
+/* Tear down a context for the gimplifier. If BODY is non-null, then
+ put the temporaries into the outer BIND_EXPR. Otherwise, put them
+ in the unexpanded_var_list. */
+
+void
+pop_gimplify_context (tree body)
+{
+ if (!gimplify_ctxp || gimplify_ctxp->current_bind_expr)
+ abort ();
+
+ if (body)
+ declare_tmp_vars (gimplify_ctxp->temps, body);
+ else
+ record_vars (gimplify_ctxp->temps);
+
+#if 0
+ if (!quiet_flag)
+ fprintf (stderr, " collisions: %f ",
+ htab_collisions (gimplify_ctxp->temp_htab));
+#endif
+
+ htab_delete (gimplify_ctxp->temp_htab);
+ free (gimplify_ctxp);
+ gimplify_ctxp = NULL;
+}
+
+void
+gimple_push_bind_expr (tree bind)
+{
+ TREE_CHAIN (bind) = gimplify_ctxp->current_bind_expr;
+ gimplify_ctxp->current_bind_expr = bind;
+}
+
+void
+gimple_pop_bind_expr (void)
+{
+ gimplify_ctxp->current_bind_expr
+ = TREE_CHAIN (gimplify_ctxp->current_bind_expr);
+}
+
+tree
+gimple_current_bind_expr (void)
+{
+ return gimplify_ctxp->current_bind_expr;
+}
+
+/* Returns true iff there is a COND_EXPR between us and the innermost
+ CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
+
+static bool
+gimple_conditional_context (void)
+{
+ return gimplify_ctxp->conditions > 0;
+}
+
+/* Note that we've entered a COND_EXPR. */
+
+static void
+gimple_push_condition (void)
+{
+ ++(gimplify_ctxp->conditions);
+}
+
+/* Note that we've left a COND_EXPR. If we're back at unconditional scope
+ now, add any conditional cleanups we've seen to the prequeue. */
+
+static void
+gimple_pop_condition (tree *pre_p)
+{
+ int conds = --(gimplify_ctxp->conditions);
+ if (conds == 0)
+ {
+ append_to_statement_list (gimplify_ctxp->conditional_cleanups, pre_p);
+ gimplify_ctxp->conditional_cleanups = NULL_TREE;
+ }
+ else if (conds < 0)
+ abort ();
+}
+
+/* A subroutine of append_to_statement_list{,_force}. */
+
+static void
+append_to_statement_list_1 (tree t, tree *list_p, bool side_effects)
+{
+ tree list = *list_p;
+ tree_stmt_iterator i;
+
+ if (!list)
+ {
+ if (t && TREE_CODE (t) == STATEMENT_LIST)
+ {
+ *list_p = t;
+ return;
+ }
+ *list_p = list = alloc_stmt_list ();
+ }
+
+ if (!side_effects)
+ return;
+
+ i = tsi_last (list);
+ tsi_link_after (&i, t, TSI_CONTINUE_LINKING);
+}
+
+/* Add T to the end of the list container pointed by LIST_P.
+ If T is an expression with no effects, it is ignored. */
+
+void
+append_to_statement_list (tree t, tree *list_p)
+{
+ append_to_statement_list_1 (t, list_p, t ? TREE_SIDE_EFFECTS (t) : false);
+}
+
+/* Similar, but the statement is always added, regardless of side effects. */
+
+void
+append_to_statement_list_force (tree t, tree *list_p)
+{
+ append_to_statement_list_1 (t, list_p, t != NULL);
+}
+
+/* Add T to the end of a COMPOUND_EXPR pointed by LIST_P. The type
+ of the result is the type of T. */
+
+void
+append_to_compound_expr (tree t, tree *list_p)
+{
+ if (!t)
+ return;
+ if (!*list_p)
+ *list_p = t;
+ else
+ *list_p = build (COMPOUND_EXPR, TREE_TYPE (t), *list_p, t);
+}
+
+/* Strip off a legitimate source ending from the input string NAME of
+ length LEN. Rather than having to know the names used by all of
+ our front ends, we strip off an ending of a period followed by
+ up to five characters. (Java uses ".class".) */
+
+static inline void
+remove_suffix (char *name, int len)
+{
+ int i;
+
+ for (i = 2; i < 8 && len > i; i++)
+ {
+ if (name[len - i] == '.')
+ {
+ name[len - i] = '\0';
+ break;
+ }
+ }
+}
+
+/* Create a nameless artificial label and put it in the current function
+ context. Returns the newly created label. */
+
+tree
+create_artificial_label (void)
+{
+ tree lab = build_decl (LABEL_DECL, NULL_TREE, void_type_node);
+ DECL_ARTIFICIAL (lab) = 1;
+ DECL_CONTEXT (lab) = current_function_decl;
+ return lab;
+}
+
+/* Create a new temporary name with PREFIX. Returns an indentifier. */
+
+static GTY(()) unsigned int tmp_var_id_num;
+
+static tree
+create_tmp_var_name (const char *prefix)
+{
+ char *tmp_name;
+
+ if (prefix)
+ {
+ char *preftmp = ASTRDUP (prefix);
+ remove_suffix (preftmp, strlen (preftmp));
+ prefix = preftmp;
+ }
+
+ ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix ? prefix : "T", tmp_var_id_num++);
+ return get_identifier (tmp_name);
+}
+
+
+/* Create a new temporary variable declaration of type TYPE.
+ Does NOT push it into the current binding. */
+
+tree
+create_tmp_var_raw (tree type, const char *prefix)
+{
+ tree tmp_var;
+ tree new_type;
+
+ /* Make the type of the variable writable. */
+ new_type = build_type_variant (type, 0, 0);
+ TYPE_ATTRIBUTES (new_type) = TYPE_ATTRIBUTES (type);
+
+ tmp_var = build_decl (VAR_DECL, create_tmp_var_name (prefix), type);
+
+ /* The variable was declared by the compiler. */
+ DECL_ARTIFICIAL (tmp_var) = 1;
+ /* And we don't want debug info for it. */
+ DECL_IGNORED_P (tmp_var) = 1;
+
+ /* Make the variable writable. */
+ TREE_READONLY (tmp_var) = 0;
+
+ DECL_EXTERNAL (tmp_var) = 0;
+ TREE_STATIC (tmp_var) = 0;
+ TREE_USED (tmp_var) = 1;
+
+ return tmp_var;
+}
+
+/* Create a new temporary variable declaration of type TYPE. DOES push the
+ variable into the current binding. Further, assume that this is called
+ only from gimplification or optimization, at which point the creation of
+ certain types are bugs. */
+
+tree
+create_tmp_var (tree type, const char *prefix)
+{
+ tree tmp_var;
+
+#if defined ENABLE_CHECKING
+ /* If the type is an array or a type which must be created by the
+ frontend, something is wrong. */
+ if (TREE_CODE (type) == ARRAY_TYPE || TREE_ADDRESSABLE (type))
+ abort ();
+ if (!COMPLETE_TYPE_P (type))
+ abort ();
+ /* Variable sized types require lots of machinery to create; the
+ optimizers shouldn't be doing anything of the sort. */
+ if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
+ abort ();
+#endif
+
+ tmp_var = create_tmp_var_raw (type, prefix);
+ gimple_add_tmp_var (tmp_var);
+ return tmp_var;
+}
+
+/* Given a tree, try to return a useful variable name that we can use
+ to prefix a temporary that is being assigned the value of the tree.
+ I.E. given <temp> = &A, return A. */
+
+const char *
+get_name (tree t)
+{
+ tree stripped_decl;
+
+ stripped_decl = t;
+ STRIP_NOPS (stripped_decl);
+ if (DECL_P (stripped_decl) && DECL_NAME (stripped_decl))
+ return IDENTIFIER_POINTER (DECL_NAME (stripped_decl));
+ else
+ {
+ switch (TREE_CODE (stripped_decl))
+ {
+ case ADDR_EXPR:
+ return get_name (TREE_OPERAND (stripped_decl, 0));
+ break;
+ default:
+ return NULL;
+ }
+ }
+}
+
+/* Create a temporary with a name derived from VAL. Subroutine of
+ lookup_tmp_var; nobody else should call this function. */
+
+static inline tree
+create_tmp_from_val (tree val)
+{
+ return create_tmp_var (TREE_TYPE (val), get_name (val));
+}
+
+/* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
+ an existing expression temporary. */
+
+static tree
+lookup_tmp_var (tree val, bool is_formal)
+{
+ if (!is_formal || TREE_SIDE_EFFECTS (val))
+ return create_tmp_from_val (val);
+ else
+ {
+ elt_t elt, *elt_p;
+ void **slot;
+
+ elt.val = val;
+ slot = htab_find_slot (gimplify_ctxp->temp_htab, (void *)&elt, INSERT);
+ if (*slot == NULL)
+ {
+ elt_p = xmalloc (sizeof (*elt_p));
+ elt_p->val = val;
+ elt_p->temp = create_tmp_from_val (val);
+ *slot = (void *)elt_p;
+ }
+ else
+ elt_p = (elt_t *) *slot;
+
+ return elt_p->temp;
+ }
+}
+
+/* Returns a formal temporary variable initialized with VAL. PRE_P is as
+ in gimplify_expr. Only use this function if:
+
+ 1) The value of the unfactored expression represented by VAL will not
+ change between the initialization and use of the temporary, and
+ 2) The temporary will not be otherwise modified.
+
+ For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
+ and #2 means it is inappropriate for && temps.
+
+ For other cases, use get_initialized_tmp_var instead. */
+
+static tree
+internal_get_tmp_var (tree val, tree *pre_p, tree *post_p, bool is_formal)
+{
+ tree t, mod;
+ char class;
+
+ gimplify_expr (&val, pre_p, post_p, is_gimple_rhs, fb_rvalue);
+
+ t = lookup_tmp_var (val, is_formal);
+
+ mod = build (MODIFY_EXPR, TREE_TYPE (t), t, val);
+
+ class = TREE_CODE_CLASS (TREE_CODE (val));
+ if (EXPR_LOCUS (val))
+ SET_EXPR_LOCUS (mod, EXPR_LOCUS (val));
+ else
+ annotate_with_locus (mod, input_location);
+ /* gimplify_modify_expr might want to reduce this further. */
+ gimplify_stmt (&mod);
+ append_to_statement_list (mod, pre_p);
+
+ return t;
+}
+
+tree
+get_formal_tmp_var (tree val, tree *pre_p)
+{
+ return internal_get_tmp_var (val, pre_p, NULL, true);
+}
+
+/* Returns a temporary variable initialized with VAL. PRE_P and POST_P
+ are as in gimplify_expr. */
+
+tree
+get_initialized_tmp_var (tree val, tree *pre_p, tree *post_p)
+{
+ return internal_get_tmp_var (val, pre_p, post_p, false);
+}
+
+/* Returns true if T is a GIMPLE temporary variable, false otherwise. */
+
+bool
+is_gimple_tmp_var (tree t)
+{
+ /* FIXME this could trigger for other local artificials, too. */
+ return (TREE_CODE (t) == VAR_DECL && DECL_ARTIFICIAL (t)
+ && !TREE_STATIC (t) && !DECL_EXTERNAL (t));
+}
+
+/* Declares all the variables in VARS in SCOPE. Returns the last
+ DECL_STMT emitted. */
+
+void
+declare_tmp_vars (tree vars, tree scope)
+{
+ tree last = vars;
+ if (last)
+ {
+ tree temps;
+
+ /* C99 mode puts the default 'return 0;' for main() outside the outer
+ braces. So drill down until we find an actual scope. */
+ while (TREE_CODE (scope) == COMPOUND_EXPR)
+ scope = TREE_OPERAND (scope, 0);
+
+ if (TREE_CODE (scope) != BIND_EXPR)
+ abort ();
+
+ temps = nreverse (last);
+ TREE_CHAIN (last) = BIND_EXPR_VARS (scope);
+ BIND_EXPR_VARS (scope) = temps;
+
+ /* We don't add the temps to the block for this BIND_EXPR, as we're
+ not interested in debugging info for them. */
+ }
+}
+
+void
+gimple_add_tmp_var (tree tmp)
+{
+ if (TREE_CHAIN (tmp) || tmp->decl.seen_in_bind_expr)
+ abort ();
+
+ DECL_CONTEXT (tmp) = current_function_decl;
+ tmp->decl.seen_in_bind_expr = 1;
+
+ if (gimplify_ctxp)
+ {
+ TREE_CHAIN (tmp) = gimplify_ctxp->temps;
+ gimplify_ctxp->temps = tmp;
+ }
+ else if (cfun)
+ record_vars (tmp);
+ else
+ declare_tmp_vars (tmp, DECL_SAVED_TREE (current_function_decl));
+}
+
+/* Determines whether to assign a locus to the statement STMT. */
+
+static bool
+should_carry_locus_p (tree stmt)
+{
+ /* Don't emit a line note for a label. We particularly don't want to
+ emit one for the break label, since it doesn't actually correspond
+ to the beginning of the loop/switch. */
+ if (TREE_CODE (stmt) == LABEL_EXPR)
+ return false;
+
+ /* Do not annotate empty statements, since it confuses gcov. */
+ if (!TREE_SIDE_EFFECTS (stmt))
+ return false;
+
+ return true;
+}
+
+void
+annotate_all_with_locus (tree *stmt_p, location_t locus)
+{
+ tree_stmt_iterator i;
+
+ if (!*stmt_p)
+ return;
+
+ for (i = tsi_start (*stmt_p); !tsi_end_p (i); tsi_next (&i))
+ {
+ tree t = tsi_stmt (i);
+
+#ifdef ENABLE_CHECKING
+ /* Assuming we've already been gimplified, we shouldn't
+ see nested chaining constructs anymore. */
+ if (TREE_CODE (t) == STATEMENT_LIST
+ || TREE_CODE (t) == COMPOUND_EXPR)
+ abort ();
+#endif
+
+ if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (t)))
+ && ! EXPR_HAS_LOCATION (t)
+ && should_carry_locus_p (t))
+ annotate_with_locus (t, locus);
+ }
+}
+
+/* Similar to copy_tree_r() but do not copy SAVE_EXPR or TARGET_EXPR nodes.
+ These nodes model computations that should only be done once. If we
+ were to unshare something like SAVE_EXPR(i++), the gimplification
+ process would create wrong code. */
+
+static tree
+mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
+{
+ enum tree_code code = TREE_CODE (*tp);
+ /* Don't unshare types, constants and SAVE_EXPR nodes. */
+ if (TREE_CODE_CLASS (code) == 't'
+ || TREE_CODE_CLASS (code) == 'c'
+ || code == SAVE_EXPR || code == TARGET_EXPR
+ /* We can't do anything sensible with a BLOCK used as an expression,
+ but we also can't abort when we see it because of non-expression
+ uses. So just avert our eyes and cross our fingers. Silly Java. */
+ || code == BLOCK)
+ *walk_subtrees = 0;
+ else if (code == BIND_EXPR)
+ abort ();
+ else
+ copy_tree_r (tp, walk_subtrees, data);
+
+ return NULL_TREE;
+}
+
+/* Mark all the _DECL nodes under *TP as volatile. FIXME: This must die
+ after VA_ARG_EXPRs are properly lowered. */
+
+static tree
+mark_decls_volatile_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
+{
+ if (SSA_VAR_P (*tp))
+ TREE_THIS_VOLATILE (*tp) = 1;
+
+ return NULL_TREE;
+}
+
+
+/* Callback for walk_tree to unshare most of the shared trees rooted at
+ *TP. If *TP has been visited already (i.e., TREE_VISITED (*TP) == 1),
+ then *TP is deep copied by calling copy_tree_r.
+
+ This unshares the same trees as copy_tree_r with the exception of
+ SAVE_EXPR nodes. These nodes model computations that should only be
+ done once. If we were to unshare something like SAVE_EXPR(i++), the
+ gimplification process would create wrong code. */
+
+static tree
+copy_if_shared_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
+{
+ /* If this node has been visited already, unshare it and don't look
+ any deeper. */
+ if (TREE_VISITED (*tp))
+ {
+ walk_tree (tp, mostly_copy_tree_r, NULL, NULL);
+ *walk_subtrees = 0;
+ }
+ else
+ {
+ /* Otherwise, mark the tree as visited and keep looking. */
+ TREE_VISITED (*tp) = 1;
+ if (TREE_CODE (*tp) == VA_ARG_EXPR)
+ {
+ /* Mark any _DECL inside the operand as volatile to avoid the
+ optimizers messing around with it. FIXME: Remove this once
+ VA_ARG_EXPRs are properly lowered. */
+ walk_tree (&TREE_OPERAND (*tp, 0), mark_decls_volatile_r,
+ NULL, NULL);
+ }
+ }
+ return NULL_TREE;
+}
+
+static tree
+unmark_visited_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
+{
+ if (TREE_VISITED (*tp))
+ TREE_VISITED (*tp) = 0;
+ else
+ *walk_subtrees = 0;
+
+ return NULL_TREE;
+}
+
+/* Unshare T and all the trees reached from T via TREE_CHAIN. */
+
+void
+unshare_all_trees (tree t)
+{
+ walk_tree (&t, copy_if_shared_r, NULL, NULL);
+ walk_tree (&t, unmark_visited_r, NULL, NULL);
+}
+
+/* Unconditionally make an unshared copy of EXPR. This is used when using
+ stored expressions which span multiple functions, such as BINFO_VTABLE,
+ as the normal unsharing process can't tell that they're shared. */
+
+tree
+unshare_expr (tree expr)
+{
+ walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
+ return expr;
+}
+
+/* A terser interface for building a representation of a exception
+ specification. */
+
+tree
+gimple_build_eh_filter (tree body, tree allowed, tree failure)
+{
+ tree t;
+
+ /* FIXME should the allowed types go in TREE_TYPE? */
+ t = build (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE);
+ append_to_statement_list (failure, &EH_FILTER_FAILURE (t));
+
+ t = build (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t);
+ append_to_statement_list (body, &TREE_OPERAND (t, 0));
+
+ return t;
+}
+
+
+/* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
+ contain statements and have a value. Assign its value to a temporary
+ and give it void_type_node. Returns the temporary, or NULL_TREE if
+ WRAPPER was already void. */
+
+tree
+voidify_wrapper_expr (tree wrapper)
+{
+ if (!VOID_TYPE_P (TREE_TYPE (wrapper)))
+ {
+ tree *p;
+ tree temp;
+
+ /* Set p to point to the body of the wrapper. */
+ switch (TREE_CODE (wrapper))
+ {
+ case BIND_EXPR:
+ /* For a BIND_EXPR, the body is operand 1. */
+ p = &BIND_EXPR_BODY (wrapper);
+ break;
+
+ default:
+ p = &TREE_OPERAND (wrapper, 0);
+ break;
+ }
+
+ /* Advance to the last statement. Set all container types to void. */
+ if (TREE_CODE (*p) == STATEMENT_LIST)
+ {
+ tree_stmt_iterator i = tsi_last (*p);
+ p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
+ }
+ else
+ {
+ for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
+ {
+ TREE_SIDE_EFFECTS (*p) = 1;
+ TREE_TYPE (*p) = void_type_node;
+ }
+ }
+
+ if (p && TREE_CODE (*p) == INIT_EXPR)
+ {
+ /* The C++ frontend already did this for us. */;
+ temp = TREE_OPERAND (*p, 0);
+ }
+ else if (p && TREE_CODE (*p) == INDIRECT_REF)
+ {
+ /* If we're returning a dereference, move the dereference outside
+ the wrapper. */
+ tree ptr = TREE_OPERAND (*p, 0);
+ temp = create_tmp_var (TREE_TYPE (ptr), "retval");
+ *p = build (MODIFY_EXPR, TREE_TYPE (ptr), temp, ptr);
+ temp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (temp)), temp);
+ /* If this is a BIND_EXPR for a const inline function, it might not
+ have TREE_SIDE_EFFECTS set. That is no longer accurate. */
+ TREE_SIDE_EFFECTS (wrapper) = 1;
+ }
+ else
+ {
+ temp = create_tmp_var (TREE_TYPE (wrapper), "retval");
+ if (p && !IS_EMPTY_STMT (*p))
+ {
+ *p = build (MODIFY_EXPR, TREE_TYPE (temp), temp, *p);
+ TREE_SIDE_EFFECTS (wrapper) = 1;
+ }
+ }
+
+ TREE_TYPE (wrapper) = void_type_node;
+ return temp;
+ }
+
+ return NULL_TREE;
+}
+
+/* Prepare calls to builtins to SAVE and RESTORE the stack as well as
+ temporary through that they comunicate. */
+
+static void
+build_stack_save_restore (tree *save, tree *restore)
+{
+ tree save_call, tmp_var;
+
+ save_call =
+ build_function_call_expr (implicit_built_in_decls[BUILT_IN_STACK_SAVE],
+ NULL_TREE);
+ tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
+
+ *save = build (MODIFY_EXPR, ptr_type_node, tmp_var, save_call);
+ *restore =
+ build_function_call_expr (implicit_built_in_decls[BUILT_IN_STACK_RESTORE],
+ tree_cons (NULL_TREE, tmp_var, NULL_TREE));
+}
+
+/* Gimplify a BIND_EXPR. Just voidify and recurse. */
+
+static enum gimplify_status
+gimplify_bind_expr (tree *expr_p, tree *pre_p)
+{
+ tree bind_expr = *expr_p;
+ tree temp = voidify_wrapper_expr (bind_expr);
+ bool old_save_stack = gimplify_ctxp->save_stack;
+ tree t;
+
+ /* Mark variables seen in this bind expr. */
+ for (t = BIND_EXPR_VARS (bind_expr); t ; t = TREE_CHAIN (t))
+ t->decl.seen_in_bind_expr = 1;
+
+ gimple_push_bind_expr (bind_expr);
+ gimplify_ctxp->save_stack = false;
+
+ gimplify_to_stmt_list (&BIND_EXPR_BODY (bind_expr));
+
+ if (gimplify_ctxp->save_stack)
+ {
+ tree stack_save, stack_restore;
+
+ /* Save stack on entry and restore it on exit. Add a try_finally
+ block to achieve this. Note that mudflap depends on the
+ format of the emitted code: see mx_register_decls(). */
+ build_stack_save_restore (&stack_save, &stack_restore);
+
+ t = build (TRY_FINALLY_EXPR, void_type_node,
+ BIND_EXPR_BODY (bind_expr), NULL_TREE);
+ append_to_statement_list (stack_restore, &TREE_OPERAND (t, 1));
+
+ BIND_EXPR_BODY (bind_expr) = NULL_TREE;
+ append_to_statement_list (stack_save, &BIND_EXPR_BODY (bind_expr));
+ append_to_statement_list (t, &BIND_EXPR_BODY (bind_expr));
+ }
+
+ gimplify_ctxp->save_stack = old_save_stack;
+ gimple_pop_bind_expr ();
+
+ if (temp)
+ {
+ *expr_p = temp;
+ append_to_statement_list (bind_expr, pre_p);
+ return GS_OK;
+ }
+ else
+ return GS_ALL_DONE;
+}
+
+/* Gimplify a RETURN_EXPR. If the expression to be returned is not a
+ GIMPLE value, it is assigned to a new temporary and the statement is
+ re-written to return the temporary.
+
+ PRE_P points to the list where side effects that must happen before
+ STMT should be stored. */
+
+static enum gimplify_status
+gimplify_return_expr (tree stmt, tree *pre_p)
+{
+ tree ret_expr = TREE_OPERAND (stmt, 0);
+ tree result;
+
+ if (!ret_expr || TREE_CODE (ret_expr) == RESULT_DECL)
+ return GS_ALL_DONE;
+
+ if (ret_expr == error_mark_node)
+ return GS_ERROR;
+
+ if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
+ result = NULL_TREE;
+ else
+ {
+ result = TREE_OPERAND (ret_expr, 0);
+#ifdef ENABLE_CHECKING
+ if ((TREE_CODE (ret_expr) != MODIFY_EXPR
+ && TREE_CODE (ret_expr) != INIT_EXPR)
+ || TREE_CODE (result) != RESULT_DECL)
+ abort ();
+#endif
+ }
+
+ /* We need to pass the full MODIFY_EXPR down so that special handling
+ can replace it with something else. */
+ gimplify_stmt (&ret_expr);
+
+ if (result == NULL_TREE)
+ TREE_OPERAND (stmt, 0) = NULL_TREE;
+ else if (ret_expr == TREE_OPERAND (stmt, 0))
+ /* It was already GIMPLE. */
+ return GS_ALL_DONE;
+ else
+ {
+ /* If there's still a MODIFY_EXPR of the RESULT_DECL after
+ gimplification, find it so we can put it in the RETURN_EXPR. */
+ tree ret = NULL_TREE;
+
+ if (TREE_CODE (ret_expr) == STATEMENT_LIST)
+ {
+ tree_stmt_iterator si;
+ for (si = tsi_start (ret_expr); !tsi_end_p (si); tsi_next (&si))
+ {
+ tree sub = tsi_stmt (si);
+ if (TREE_CODE (sub) == MODIFY_EXPR
+ && TREE_OPERAND (sub, 0) == result)
+ {
+ ret = sub;
+ if (tsi_one_before_end_p (si))
+ tsi_delink (&si);
+ else
+ {
+ /* If there were posteffects after the MODIFY_EXPR,
+ we need a temporary. */
+ tree tmp = create_tmp_var (TREE_TYPE (result), "retval");
+ TREE_OPERAND (ret, 0) = tmp;
+ ret = build (MODIFY_EXPR, TREE_TYPE (result),
+ result, tmp);
+ }
+ break;
+ }
+ }
+ }
+
+ if (ret)
+ TREE_OPERAND (stmt, 0) = ret;
+ else
+ /* The return value must be set up some other way. Just tell
+ expand_return that we're returning the RESULT_DECL. */
+ TREE_OPERAND (stmt, 0) = result;
+ }
+
+ append_to_statement_list (ret_expr, pre_p);
+ return GS_ALL_DONE;
+}
+
+/* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
+ and replacing the LOOP_EXPR with goto, but if the loop contains an
+ EXIT_EXPR, we need to append a label for it to jump to. */
+
+static enum gimplify_status
+gimplify_loop_expr (tree *expr_p, tree *pre_p)
+{
+ tree saved_label = gimplify_ctxp->exit_label;
+ tree start_label = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
+ tree jump_stmt = build_and_jump (&LABEL_EXPR_LABEL (start_label));
+
+ append_to_statement_list (start_label, pre_p);
+
+ gimplify_ctxp->exit_label = NULL_TREE;
+
+ gimplify_stmt (&LOOP_EXPR_BODY (*expr_p));
+ append_to_statement_list (LOOP_EXPR_BODY (*expr_p), pre_p);
+
+ if (gimplify_ctxp->exit_label)
+ {
+ append_to_statement_list (jump_stmt, pre_p);
+ *expr_p = build1 (LABEL_EXPR, void_type_node, gimplify_ctxp->exit_label);
+ }
+ else
+ *expr_p = jump_stmt;
+
+ gimplify_ctxp->exit_label = saved_label;
+
+ return GS_ALL_DONE;
+}
+
+/* Gimplify a SWITCH_EXPR, and collect a TREE_VEC of the labels it can
+ branch to. */
+
+static enum gimplify_status
+gimplify_switch_expr (tree *expr_p, tree *pre_p)
+{
+ tree switch_expr = *expr_p;
+ enum gimplify_status ret;
+
+ ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL,
+ is_gimple_val, fb_rvalue);
+
+ if (SWITCH_BODY (switch_expr))
+ {
+ varray_type labels, saved_labels;
+ bool saw_default;
+ tree label_vec, t;
+ size_t i, len;
+
+ /* If someone can be bothered to fill in the labels, they can
+ be bothered to null out the body too. */
+ if (SWITCH_LABELS (switch_expr))
+ abort ();
+
+ saved_labels = gimplify_ctxp->case_labels;
+ VARRAY_TREE_INIT (gimplify_ctxp->case_labels, 8, "case_labels");
+
+ gimplify_to_stmt_list (&SWITCH_BODY (switch_expr));
+
+ labels = gimplify_ctxp->case_labels;
+ gimplify_ctxp->case_labels = saved_labels;
+
+ len = VARRAY_ACTIVE_SIZE (labels);
+ saw_default = false;
+
+ for (i = 0; i < len; ++i)
+ {
+ t = VARRAY_TREE (labels, i);
+ if (!CASE_LOW (t))
+ {
+ saw_default = true;
+ break;
+ }
+ }
+
+ label_vec = make_tree_vec (len + !saw_default);
+ SWITCH_LABELS (*expr_p) = label_vec;
+
+ for (i = 0; i < len; ++i)
+ TREE_VEC_ELT (label_vec, i) = VARRAY_TREE (labels, i);
+
+ append_to_statement_list (switch_expr, pre_p);
+
+ /* If the switch has no default label, add one, so that we jump
+ around the switch body. */
+ if (!saw_default)
+ {
+ t = build (CASE_LABEL_EXPR, void_type_node, NULL_TREE,
+ NULL_TREE, create_artificial_label ());
+ TREE_VEC_ELT (label_vec, len) = t;
+ append_to_statement_list (SWITCH_BODY (switch_expr), pre_p);
+ *expr_p = build (LABEL_EXPR, void_type_node, CASE_LABEL (t));
+ }
+ else
+ *expr_p = SWITCH_BODY (switch_expr);
+
+ SWITCH_BODY (switch_expr) = NULL;
+ }
+ else if (!SWITCH_LABELS (switch_expr))
+ abort ();
+
+ return ret;
+}
+
+static enum gimplify_status
+gimplify_case_label_expr (tree *expr_p)
+{
+ tree expr = *expr_p;
+ if (gimplify_ctxp->case_labels)
+ VARRAY_PUSH_TREE (gimplify_ctxp->case_labels, expr);
+ else
+ abort ();
+ *expr_p = build (LABEL_EXPR, void_type_node, CASE_LABEL (expr));
+ return GS_ALL_DONE;
+}
+
+/* Gimplify a LABELED_BLOCK_EXPR into a LABEL_EXPR following
+ a (possibly empty) body. */
+
+static enum gimplify_status
+gimplify_labeled_block_expr (tree *expr_p)
+{
+ tree body = LABELED_BLOCK_BODY (*expr_p);
+ tree label = LABELED_BLOCK_LABEL (*expr_p);
+ tree t;
+
+ DECL_CONTEXT (label) = current_function_decl;
+ t = build (LABEL_EXPR, void_type_node, label);
+ if (body != NULL_TREE)
+ t = build (COMPOUND_EXPR, void_type_node, body, t);
+ *expr_p = t;
+
+ return GS_OK;
+}
+
+/* Gimplify a EXIT_BLOCK_EXPR into a GOTO_EXPR. */
+
+static enum gimplify_status
+gimplify_exit_block_expr (tree *expr_p)
+{
+ tree labeled_block = TREE_OPERAND (*expr_p, 0);
+ tree label;
+
+ /* First operand must be a LABELED_BLOCK_EXPR, which should
+ already be lowered (or partially lowered) when we get here. */
+#if defined ENABLE_CHECKING
+ if (TREE_CODE (labeled_block) != LABELED_BLOCK_EXPR)
+ abort ();
+#endif
+
+ label = LABELED_BLOCK_LABEL (labeled_block);
+ *expr_p = build1 (GOTO_EXPR, void_type_node, label);
+
+ return GS_OK;
+}
+
+/* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
+ if necessary. */
+
+tree
+build_and_jump (tree *label_p)
+{
+ if (label_p == NULL)
+ /* If there's nowhere to jump, just fall through. */
+ return build_empty_stmt ();
+
+ if (*label_p == NULL_TREE)
+ {
+ tree label = create_artificial_label ();
+ *label_p = label;
+ }
+
+ return build1 (GOTO_EXPR, void_type_node, *label_p);
+}
+
+/* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
+ This also involves building a label to jump to and communicating it to
+ gimplify_loop_expr through gimplify_ctxp->exit_label. */
+
+static enum gimplify_status
+gimplify_exit_expr (tree *expr_p)
+{
+ tree cond = TREE_OPERAND (*expr_p, 0);
+ tree expr;
+
+ expr = build_and_jump (&gimplify_ctxp->exit_label);
+ expr = build (COND_EXPR, void_type_node, cond, expr, build_empty_stmt ());
+ *expr_p = expr;
+
+ return GS_OK;
+}
+
+/* A helper function to be called via walk_tree. Mark all labels under *TP
+ as being forced. To be called for DECL_INITIAL of static variables. */
+
+tree
+force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
+{
+ if (TYPE_P (*tp))
+ *walk_subtrees = 0;
+ if (TREE_CODE (*tp) == LABEL_DECL)
+ FORCED_LABEL (*tp) = 1;
+
+ return NULL_TREE;
+}
+
+/* Break out elements of a constructor used as an initializer into separate
+ MODIFY_EXPRs.
+
+ Note that we still need to clear any elements that don't have explicit
+ initializers, so if not all elements are initialized we keep the
+ original MODIFY_EXPR, we just remove all of the constructor elements. */
+
+static enum gimplify_status
+gimplify_init_constructor (tree *expr_p, tree *pre_p,
+ tree *post_p, int want_value)
+{
+ tree object = TREE_OPERAND (*expr_p, 0);
+ tree ctor = TREE_OPERAND (*expr_p, 1);
+ tree type = TREE_TYPE (ctor);
+ enum gimplify_status ret;
+ tree elt_list;
+
+ if (TREE_CODE (ctor) != CONSTRUCTOR)
+ return GS_UNHANDLED;
+
+ elt_list = CONSTRUCTOR_ELTS (ctor);
+
+ ret = GS_ALL_DONE;
+ switch (TREE_CODE (type))
+ {
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ case ARRAY_TYPE:
+ {
+ HOST_WIDE_INT i, num_elements, num_nonzero_elements;
+ HOST_WIDE_INT num_nonconstant_elements;
+ bool cleared;
+
+ /* Aggregate types must lower constructors to initialization of
+ individual elements. The exception is that a CONSTRUCTOR node
+ with no elements indicates zero-initialization of the whole. */
+ if (elt_list == NULL)
+ {
+ if (want_value)
+ {
+ *expr_p = object;
+ return GS_OK;
+ }
+ else
+ return GS_ALL_DONE;
+ }
+
+ categorize_ctor_elements (ctor, &num_nonzero_elements,
+ &num_nonconstant_elements);
+ num_elements = count_type_elements (TREE_TYPE (ctor));
+
+ /* If a const aggregate variable is being initialized, then it
+ should never be a lose to promote the variable to be static. */
+ if (num_nonconstant_elements == 0
+ && TREE_READONLY (object)
+ && TREE_CODE (object) == VAR_DECL)
+ {
+ DECL_INITIAL (object) = ctor;
+ TREE_STATIC (object) = 1;
+ if (!DECL_NAME (object))
+ DECL_NAME (object) = create_tmp_var_name ("C");
+ walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
+
+ /* ??? C++ doesn't automatically append a .<number> to the
+ assembler name, and even when it does, it looks a FE private
+ data structures to figure out what that number should be,
+ which are not set for this variable. I suppose this is
+ important for local statics for inline functions, which aren't
+ "local" in the object file sense. So in order to get a unique
+ TU-local symbol, we must invoke the lhd version now. */
+ lhd_set_decl_assembler_name (object);
+
+ *expr_p = build_empty_stmt ();
+ break;
+ }
+
+ /* If there are "lots" of initialized elements, and all of them
+ are valid address constants, then the entire initializer can
+ be dropped to memory, and then memcpy'd out. */
+ if (num_nonconstant_elements == 0)
+ {
+ HOST_WIDE_INT size = int_size_in_bytes (type);
+ unsigned int align;
+
+ /* ??? We can still get unbounded array types, at least
+ from the C++ front end. This seems wrong, but attempt
+ to work around it for now. */
+ if (size < 0)
+ {
+ size = int_size_in_bytes (TREE_TYPE (object));
+ if (size >= 0)
+ TREE_TYPE (ctor) = type = TREE_TYPE (object);
+ }
+
+ /* Find the maximum alignment we can assume for the object. */
+ /* ??? Make use of DECL_OFFSET_ALIGN. */
+ if (DECL_P (object))
+ align = DECL_ALIGN (object);
+ else
+ align = TYPE_ALIGN (type);
+
+ if (size > 0 && !can_move_by_pieces (size, align))
+ {
+ tree new = create_tmp_var_raw (type, "C");
+ gimple_add_tmp_var (new);
+ TREE_STATIC (new) = 1;
+ TREE_READONLY (new) = 1;
+ DECL_INITIAL (new) = ctor;
+ if (align > DECL_ALIGN (new))
+ {
+ DECL_ALIGN (new) = align;
+ DECL_USER_ALIGN (new) = 1;
+ }
+ walk_tree (&DECL_INITIAL (new), force_labels_r, NULL, NULL);
+
+ TREE_OPERAND (*expr_p, 1) = new;
+ break;
+ }
+ }
+
+ /* If there are "lots" of initialized elements, even discounting
+ those that are not address constants (and thus *must* be
+ computed at runtime), then partition the constructor into
+ constant and non-constant parts. Block copy the constant
+ parts in, then generate code for the non-constant parts. */
+ /* TODO. There's code in cp/typeck.c to do this. */
+
+ /* If there are "lots" of zeros, then block clear the object first. */
+ cleared = false;
+ if (num_elements - num_nonzero_elements > CLEAR_RATIO
+ && num_nonzero_elements < num_elements/4)
+ cleared = true;
+
+ /* ??? This bit ought not be needed. For any element not present
+ in the initializer, we should simply set them to zero. Except
+ we'd need to *find* the elements that are not present, and that
+ requires trickery to avoid quadratic compile-time behaviour in
+ large cases or excessive memory use in small cases. */
+ else
+ {
+ HOST_WIDE_INT len = list_length (elt_list);
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ tree nelts = array_type_nelts (type);
+ if (!host_integerp (nelts, 1)
+ || tree_low_cst (nelts, 1) != len)
+ cleared = 1;;
+ }
+ else if (len != fields_length (type))
+ cleared = 1;
+ }
+
+ if (cleared)
+ {
+ CONSTRUCTOR_ELTS (ctor) = NULL_TREE;
+ append_to_statement_list (*expr_p, pre_p);
+ }
+
+ for (i = 0; elt_list; i++, elt_list = TREE_CHAIN (elt_list))
+ {
+ tree purpose, value, cref, init;
+
+ purpose = TREE_PURPOSE (elt_list);
+ value = TREE_VALUE (elt_list);
+
+ if (cleared && initializer_zerop (value))
+ continue;
+
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ tree t = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
+
+ /* ??? Here's to hoping the front end fills in all of the
+ indicies, so we don't have to figure out what's missing
+ ourselves. */
+ if (!purpose)
+ abort ();
+ /* ??? Need to handle this. */
+ if (TREE_CODE (purpose) == RANGE_EXPR)
+ abort ();
+
+ cref = build (ARRAY_REF, t, object, purpose);
+ }
+ else
+ {
+ cref = build (COMPONENT_REF, TREE_TYPE (purpose),
+ object, purpose);
+ }
+
+ init = build (MODIFY_EXPR, TREE_TYPE (purpose), cref, value);
+ /* Each member initialization is a full-expression. */
+ gimplify_stmt (&init);
+ append_to_statement_list (init, pre_p);
+ }
+
+ *expr_p = build_empty_stmt ();
+ }
+ break;
+
+ case COMPLEX_TYPE:
+ {
+ tree r, i;
+
+ /* Extract the real and imaginary parts out of the ctor. */
+ r = i = NULL_TREE;
+ if (elt_list)
+ {
+ r = TREE_VALUE (elt_list);
+ elt_list = TREE_CHAIN (elt_list);
+ if (elt_list)
+ {
+ i = TREE_VALUE (elt_list);
+ if (TREE_CHAIN (elt_list))
+ abort ();
+ }
+ }
+ if (r == NULL || i == NULL)
+ {
+ tree zero = convert (TREE_TYPE (type), integer_zero_node);
+ if (r == NULL)
+ r = zero;
+ if (i == NULL)
+ i = zero;
+ }
+
+ /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
+ represent creation of a complex value. */
+ if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
+ {
+ ctor = build_complex (type, r, i);
+ TREE_OPERAND (*expr_p, 1) = ctor;
+ }
+ else
+ {
+ ctor = build (COMPLEX_EXPR, type, r, i);
+ TREE_OPERAND (*expr_p, 1) = ctor;
+ ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
+ is_gimple_rhs, fb_rvalue);
+ }
+ }
+ break;
+
+ case VECTOR_TYPE:
+ /* Go ahead and simplify constant constructors to VECTOR_CST. */
+ if (TREE_CONSTANT (ctor))
+ TREE_OPERAND (*expr_p, 1) = build_vector (type, elt_list);
+ else
+ {
+ /* Vector types use CONSTRUCTOR all the way through gimple
+ compilation as a general initializer. */
+ for (; elt_list; elt_list = TREE_CHAIN (elt_list))
+ {
+ enum gimplify_status tret;
+ tret = gimplify_expr (&TREE_VALUE (elt_list), pre_p, post_p,
+ is_gimple_constructor_elt, fb_rvalue);
+ if (tret == GS_ERROR)
+ ret = GS_ERROR;
+ }
+ }
+ break;
+
+ default:
+ /* So how did we get a CONSTRUCTOR for a scalar type? */
+ abort ();
+ }
+
+ if (ret == GS_ERROR)
+ return GS_ERROR;
+ else if (want_value)
+ {
+ append_to_statement_list (*expr_p, pre_p);
+ *expr_p = object;
+ return GS_OK;
+ }
+ else
+ return GS_ALL_DONE;
+}
+
+/* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
+ different from its canonical type, wrap the whole thing inside a
+ NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
+ type.
+
+ The canonical type of a COMPONENT_REF is the type of the field being
+ referenced--unless the field is a bit-field which can be read directly
+ in a smaller mode, in which case the canonical type is the
+ sign-appropriate type corresponding to that mode. */
+
+static void
+canonicalize_component_ref (tree *expr_p)
+{
+ tree expr = *expr_p;
+ tree type;
+
+ if (TREE_CODE (expr) != COMPONENT_REF)
+ abort ();
+
+ if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
+ type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
+ else
+ type = TREE_TYPE (TREE_OPERAND (expr, 1));
+
+ if (TREE_TYPE (expr) != type)
+ {
+ tree old_type = TREE_TYPE (expr);
+
+ /* Set the type of the COMPONENT_REF to the underlying type. */
+ TREE_TYPE (expr) = type;
+
+ /* And wrap the whole thing inside a NOP_EXPR. */
+ expr = build1 (NOP_EXPR, old_type, expr);
+
+ *expr_p = expr;
+ }
+}
+
+/* If a NOP conversion is changing a pointer to array of foo to a pointer
+ to foo, embed that change in the ADDR_EXPR. Lest we perturb the type
+ system too badly, we must take extra steps to ensure that the ADDR_EXPR
+ and the addressed object continue to agree on types. */
+/* ??? We might could do better if we recognize
+ T array[N][M];
+ (T *)&array
+ ==>
+ &array[0][0];
+*/
+
+static void
+canonicalize_addr_expr (tree* expr_p)
+{
+ tree expr = *expr_p;
+ tree ctype = TREE_TYPE (expr);
+ tree addr_expr = TREE_OPERAND (expr, 0);
+ tree atype = TREE_TYPE (addr_expr);
+ tree dctype, datype, ddatype, otype, obj_expr;
+
+ /* Both cast and addr_expr types should be pointers. */
+ if (!POINTER_TYPE_P (ctype) || !POINTER_TYPE_P (atype))
+ return;
+
+ /* The addr_expr type should be a pointer to an array. */
+ datype = TREE_TYPE (atype);
+ if (TREE_CODE (datype) != ARRAY_TYPE)
+ return;
+
+ /* Both cast and addr_expr types should address the same object type. */
+ dctype = TREE_TYPE (ctype);
+ ddatype = TREE_TYPE (datype);
+ if (!lang_hooks.types_compatible_p (ddatype, dctype))
+ return;
+
+ /* The addr_expr and the object type should match. */
+ obj_expr = TREE_OPERAND (addr_expr, 0);
+ otype = TREE_TYPE (obj_expr);
+ if (!lang_hooks.types_compatible_p (otype, datype))
+ return;
+
+ /* All checks succeeded. Build a new node to merge the cast. */
+ *expr_p = build1 (ADDR_EXPR, ctype, obj_expr);
+}
+
+/* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
+ underneath as appropriate. */
+
+static enum gimplify_status
+gimplify_conversion (tree *expr_p)
+{
+ /* Strip away as many useless type conversions as possible
+ at the toplevel. */
+ STRIP_USELESS_TYPE_CONVERSION (*expr_p);
+
+ /* If we still have a conversion at the toplevel, then strip
+ away all but the outermost conversion. */
+ if (TREE_CODE (*expr_p) == NOP_EXPR || TREE_CODE (*expr_p) == CONVERT_EXPR)
+ {
+ STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
+
+ /* And remove the outermost conversion if it's useless. */
+ if (tree_ssa_useless_type_conversion (*expr_p))
+ *expr_p = TREE_OPERAND (*expr_p, 0);
+ }
+
+ /* If we still have a conversion at the toplevel,
+ then canonicalize some constructs. */
+ if (TREE_CODE (*expr_p) == NOP_EXPR || TREE_CODE (*expr_p) == CONVERT_EXPR)
+ {
+ tree sub = TREE_OPERAND (*expr_p, 0);
+
+ /* If a NOP conversion is changing the type of a COMPONENT_REF
+ expression, then canonicalize its type now in order to expose more
+ redundant conversions. */
+ if (TREE_CODE (sub) == COMPONENT_REF)
+ canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
+
+ /* If a NOP conversion is changing a pointer to array of foo
+ to a pointer to foo, embed that change in the ADDR_EXPR. */
+ else if (TREE_CODE (sub) == ADDR_EXPR)
+ canonicalize_addr_expr (expr_p);
+ }
+
+ return GS_OK;
+}
+
+/* Reduce MIN/MAX_EXPR to a COND_EXPR for further gimplification. */
+
+static enum gimplify_status
+gimplify_minimax_expr (tree *expr_p, tree *pre_p, tree *post_p)
+{
+ tree op1 = TREE_OPERAND (*expr_p, 0);
+ tree op2 = TREE_OPERAND (*expr_p, 1);
+ enum tree_code code;
+ enum gimplify_status r0, r1;
+
+ if (TREE_CODE (*expr_p) == MIN_EXPR)
+ code = LE_EXPR;
+ else
+ code = GE_EXPR;
+
+ r0 = gimplify_expr (&op1, pre_p, post_p, is_gimple_val, fb_rvalue);
+ r1 = gimplify_expr (&op2, pre_p, post_p, is_gimple_val, fb_rvalue);
+
+ *expr_p = build (COND_EXPR, TREE_TYPE (*expr_p),
+ build (code, boolean_type_node, op1, op2),
+ op1, op2);
+
+ if (r0 == GS_ERROR || r1 == GS_ERROR)
+ return GS_ERROR;
+ else
+ return GS_OK;
+}
+
+/* Build an expression for the address of T. Folds away INDIRECT_REF to
+ avoid confusing the gimplify process. */
+
+static tree
+build_addr_expr_with_type (tree t, tree ptrtype)
+{
+ if (TREE_CODE (t) == INDIRECT_REF)
+ {
+ t = TREE_OPERAND (t, 0);
+ if (TREE_TYPE (t) != ptrtype)
+ t = build1 (NOP_EXPR, ptrtype, t);
+ }
+ else
+ {
+ tree base = t;
+ while (TREE_CODE (base) == COMPONENT_REF
+ || TREE_CODE (base) == ARRAY_REF)
+ base = TREE_OPERAND (base, 0);
+ if (DECL_P (base))
+ TREE_ADDRESSABLE (base) = 1;
+
+ t = build1 (ADDR_EXPR, ptrtype, t);
+ }
+
+ return t;
+}
+
+static tree
+build_addr_expr (tree t)
+{
+ return build_addr_expr_with_type (t, build_pointer_type (TREE_TYPE (t)));
+}
+
+/* Subroutine of gimplify_compound_lval and gimplify_array_ref.
+ Converts an ARRAY_REF to the equivalent *(&array + offset) form. */
+
+static enum gimplify_status
+gimplify_array_ref_to_plus (tree *expr_p, tree *pre_p, tree *post_p)
+{
+ tree array = TREE_OPERAND (*expr_p, 0);
+ tree arrtype = TREE_TYPE (array);
+ tree elttype = TREE_TYPE (arrtype);
+ tree size = size_in_bytes (elttype);
+ tree ptrtype = build_pointer_type (elttype);
+ enum tree_code add_code = PLUS_EXPR;
+ tree idx = TREE_OPERAND (*expr_p, 1);
+ tree minidx, offset, addr, result;
+ enum gimplify_status ret;
+
+ /* If the array domain does not start at zero, apply the offset. */
+ minidx = TYPE_DOMAIN (arrtype);
+ if (minidx)
+ {
+ minidx = TYPE_MIN_VALUE (minidx);
+ if (minidx && !integer_zerop (minidx))
+ {
+ idx = convert (TREE_TYPE (minidx), idx);
+ idx = fold (build (MINUS_EXPR, TREE_TYPE (minidx), idx, minidx));
+ }
+ }
+
+ /* If the index is negative -- a technically invalid situation now
+ that we've biased the index back to zero -- then casting it to
+ unsigned has ill effects. In particular, -1*4U/4U != -1.
+ Represent this as a subtraction of a positive rather than addition
+ of a negative. This will prevent any conversion back to ARRAY_REF
+ from getting the wrong results from the division. */
+ if (TREE_CODE (idx) == INTEGER_CST && tree_int_cst_sgn (idx) < 0)
+ {
+ idx = fold (build1 (NEGATE_EXPR, TREE_TYPE (idx), idx));
+ add_code = MINUS_EXPR;
+ }
+
+ /* Pointer arithmetic must be done in sizetype. */
+ idx = convert (sizetype, idx);
+
+ /* Convert the index to a byte offset. */
+ offset = size_binop (MULT_EXPR, size, idx);
+
+ ret = gimplify_expr (&array, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
+ if (ret == GS_ERROR)
+ return ret;
+
+ addr = build_addr_expr_with_type (array, ptrtype);
+ result = fold (build (add_code, ptrtype, addr, offset));
+ *expr_p = build1 (INDIRECT_REF, elttype, result);
+
+ return GS_OK;
+}
+
+/* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
+ node pointed by EXPR_P.
+
+ compound_lval
+ : min_lval '[' val ']'
+ | min_lval '.' ID
+ | compound_lval '[' val ']'
+ | compound_lval '.' ID
+
+ This is not part of the original SIMPLE definition, which separates
+ array and member references, but it seems reasonable to handle them
+ together. Also, this way we don't run into problems with union
+ aliasing; gcc requires that for accesses through a union to alias, the
+ union reference must be explicit, which was not always the case when we
+ were splitting up array and member refs.
+
+ PRE_P points to the list where side effects that must happen before
+ *EXPR_P should be stored.
+
+ POST_P points to the list where side effects that must happen after
+ *EXPR_P should be stored. */
+
+static enum gimplify_status
+gimplify_compound_lval (tree *expr_p, tree *pre_p,
+ tree *post_p, int want_lvalue)
+{
+ tree *p;
+ enum tree_code code;
+ varray_type stack;
+ enum gimplify_status ret;
+
+#if defined ENABLE_CHECKING
+ if (TREE_CODE (*expr_p) != ARRAY_REF
+ && TREE_CODE (*expr_p) != COMPONENT_REF
+ && TREE_CODE (*expr_p) != REALPART_EXPR
+ && TREE_CODE (*expr_p) != IMAGPART_EXPR)
+ abort ();
+#endif
+
+ code = ERROR_MARK; /* [GIMPLE] Avoid uninitialized use warning. */
+
+ /* Create a stack of the subexpressions so later we can walk them in
+ order from inner to outer. */
+ VARRAY_TREE_INIT (stack, 10, "stack");
+
+ for (p = expr_p;
+ TREE_CODE (*p) == ARRAY_REF
+ || TREE_CODE (*p) == COMPONENT_REF
+ || TREE_CODE (*p) == REALPART_EXPR
+ || TREE_CODE (*p) == IMAGPART_EXPR;
+ p = &TREE_OPERAND (*p, 0))
+ {
+ code = TREE_CODE (*p);
+ if (code == ARRAY_REF)
+ {
+ tree elttype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (*p, 0)));
+ if (!TREE_CONSTANT (TYPE_SIZE_UNIT (elttype)))
+ /* If the size of the array elements is not constant,
+ computing the offset is non-trivial, so expose it. */
+ break;
+ }
+ VARRAY_PUSH_TREE (stack, *p);
+ }
+
+ /* Now 'p' points to the first bit that isn't a ref, 'code' is the
+ TREE_CODE of the last bit that was, and 'stack' is a stack of pointers
+ to all the refs we've walked through.
+
+ Gimplify the base, and then process each of the outer nodes from left
+ to right. */
+ ret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
+ code != ARRAY_REF ? fb_either : fb_lvalue);
+
+ for (; VARRAY_ACTIVE_SIZE (stack) > 0; )
+ {
+ tree t = VARRAY_TOP_TREE (stack);
+ if (TREE_CODE (t) == ARRAY_REF)
+ {
+ /* Gimplify the dimension. */
+ enum gimplify_status tret;
+ /* Temporary fix for gcc.c-torture/execute/20040313-1.c.
+ Gimplify non-constant array indices into a temporary
+ variable.
+ FIXME - The real fix is to gimplify post-modify
+ expressions into a minimal gimple lvalue. However, that
+ exposes bugs in alias analysis. The alias analyzer does
+ not handle &PTR->FIELD very well. Will fix after the
+ branch is merged into mainline (dnovillo 2004-05-03). */
+ if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
+ {
+ tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
+ is_gimple_tmp_var, fb_rvalue);
+ if (tret == GS_ERROR)
+ ret = GS_ERROR;
+ }
+ }
+ recalculate_side_effects (t);
+ VARRAY_POP (stack);
+ }
+
+ /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
+ if (!want_lvalue && TREE_CODE (*expr_p) == COMPONENT_REF)
+ {
+ canonicalize_component_ref (expr_p);
+ ret = MIN (ret, GS_OK);
+ }
+
+ return ret;
+}
+
+/* Re-write the ARRAY_REF node pointed by EXPR_P.
+
+ PRE_P points to the list where side effects that must happen before
+ *EXPR_P should be stored.
+
+ POST_P points to the list where side effects that must happen after
+ *EXPR_P should be stored.
+
+ FIXME: ARRAY_REF currently doesn't accept a pointer as the array
+ argument, so this gimplification uses an INDIRECT_REF of ARRAY_TYPE.
+ ARRAY_REF should be extended. */
+
+static enum gimplify_status
+gimplify_array_ref (tree *expr_p, tree *pre_p,
+ tree *post_p, int want_lvalue)
+{
+ tree elttype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (*expr_p, 0)));
+ if (!TREE_CONSTANT (TYPE_SIZE_UNIT (elttype)))
+ /* If the size of the array elements is not constant,
+ computing the offset is non-trivial, so expose it. */
+ return gimplify_array_ref_to_plus (expr_p, pre_p, post_p);
+ else
+ /* Handle array and member refs together for now. When alias analysis
+ improves, we may want to go back to handling them separately. */
+ return gimplify_compound_lval (expr_p, pre_p, post_p, want_lvalue);
+}
+
+/* Gimplify the self modifying expression pointed by EXPR_P (++, --, +=, -=).
+
+ PRE_P points to the list where side effects that must happen before
+ *EXPR_P should be stored.
+
+ POST_P points to the list where side effects that must happen after
+ *EXPR_P should be stored.
+
+ WANT_VALUE is nonzero iff we want to use the value of this expression
+ in another expression. */
+
+static enum gimplify_status
+gimplify_self_mod_expr (tree *expr_p, tree *pre_p, tree *post_p,
+ int want_value)
+{
+ enum tree_code code;
+ tree lhs, lvalue, rhs, t1;
+ bool postfix;
+ enum tree_code arith_code;
+ enum gimplify_status ret;
+
+ code = TREE_CODE (*expr_p);
+
+#if defined ENABLE_CHECKING
+ if (code != POSTINCREMENT_EXPR
+ && code != POSTDECREMENT_EXPR
+ && code != PREINCREMENT_EXPR
+ && code != PREDECREMENT_EXPR)
+ abort ();
+#endif
+
+ /* Prefix or postfix? */
+ if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
+ /* Faster to treat as prefix if result is not used. */
+ postfix = want_value;
+ else
+ postfix = false;
+
+ /* Add or subtract? */
+ if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
+ arith_code = PLUS_EXPR;
+ else
+ arith_code = MINUS_EXPR;
+
+ /* Gimplify the LHS into a GIMPLE lvalue. */
+ lvalue = TREE_OPERAND (*expr_p, 0);
+ ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
+ if (ret == GS_ERROR)
+ return ret;
+
+ /* Extract the operands to the arithmetic operation. */
+ lhs = lvalue;
+ rhs = TREE_OPERAND (*expr_p, 1);
+
+ /* For postfix operator, we evaluate the LHS to an rvalue and then use
+ that as the result value and in the postqueue operation. */
+ if (postfix)
+ {
+ ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
+ if (ret == GS_ERROR)
+ return ret;
+ }
+
+ t1 = build (arith_code, TREE_TYPE (*expr_p), lhs, rhs);
+ t1 = build (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
+
+ if (postfix)
+ {
+ gimplify_stmt (&t1);
+ append_to_statement_list (t1, post_p);
+ *expr_p = lhs;
+ return GS_ALL_DONE;
+ }
+ else
+ {
+ *expr_p = t1;
+ return GS_OK;
+ }
+}
+
+/* Gimplify the CALL_EXPR node pointed by EXPR_P.
+
+ call_expr
+ : ID '(' arglist ')'
+
+ arglist
+ : arglist ',' val
+ | val
+
+ PRE_P points to the list where side effects that must happen before
+ *EXPR_P should be stored. */
+
+static enum gimplify_status
+gimplify_call_expr (tree *expr_p, tree *pre_p, bool (*gimple_test_f) (tree))
+{
+ tree decl;
+ tree arglist;
+ enum gimplify_status ret;
+
+#if defined ENABLE_CHECKING
+ if (TREE_CODE (*expr_p) != CALL_EXPR)
+ abort ();
+#endif
+
+ /* For reliable diagnostics during inlining, it is necessary that
+ every call_expr be annotated with file and line. */
+ if (!EXPR_LOCUS (*expr_p))
+ annotate_with_locus (*expr_p, input_location);
+
+ /* This may be a call to a builtin function.
+
+ Builtin function calls may be transformed into different
+ (and more efficient) builtin function calls under certain
+ circumstances. Unfortunately, gimplification can muck things
+ up enough that the builtin expanders are not aware that certain
+ transformations are still valid.
+
+ So we attempt transformation/gimplification of the call before
+ we gimplify the CALL_EXPR. At this time we do not manage to
+ transform all calls in the same manner as the expanders do, but
+ we do transform most of them. */
+ decl = get_callee_fndecl (*expr_p);
+ if (decl && DECL_BUILT_IN (decl))
+ {
+ tree new;
+
+ /* If it is allocation of stack, record the need to restore the memory
+ when the enclosing bind_expr is exited. */
+ if (DECL_FUNCTION_CODE (decl) == BUILT_IN_STACK_ALLOC)
+ gimplify_ctxp->save_stack = true;
+
+ /* If it is restore of the stack, reset it, since it means we are
+ regimplifying the bind_expr. Note that we use the fact that
+ for try_finally_expr, try part is processed first. */
+ if (DECL_FUNCTION_CODE (decl) == BUILT_IN_STACK_RESTORE)
+ gimplify_ctxp->save_stack = false;
+
+ new = simplify_builtin (*expr_p, gimple_test_f == is_gimple_stmt);
+
+ if (new && new != *expr_p)
+ {
+ /* There was a transformation of this call which computes the
+ same value, but in a more efficient way. Return and try
+ again. */
+ *expr_p = new;
+ return GS_OK;
+ }
+ }
+
+ /* There is a sequence point before the call, so any side effects in
+ the calling expression must occur before the actual call. Force
+ gimplify_expr to use an internal post queue. */
+ ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, NULL,
+ is_gimple_val, fb_rvalue);
+
+ if (PUSH_ARGS_REVERSED)
+ TREE_OPERAND (*expr_p, 1) = nreverse (TREE_OPERAND (*expr_p, 1));
+ for (arglist = TREE_OPERAND (*expr_p, 1); arglist;
+ arglist = TREE_CHAIN (arglist))
+ {
+ enum gimplify_status t;
+
+ /* There is a sequence point before a function call. Side effects in
+ the argument list must occur before the actual call. So, when
+ gimplifying arguments, force gimplify_expr to use an internal
+ post queue which is then appended to the end of PRE_P. */
+ t = gimplify_expr (&TREE_VALUE (arglist), pre_p, NULL, is_gimple_val,
+ fb_rvalue);
+
+ if (t == GS_ERROR)
+ ret = GS_ERROR;
+ }
+ if (PUSH_ARGS_REVERSED)
+ TREE_OPERAND (*expr_p, 1) = nreverse (TREE_OPERAND (*expr_p, 1));
+
+ /* Try this again in case gimplification exposed something. */
+ if (ret != GS_ERROR && decl && DECL_BUILT_IN (decl))
+ {
+ tree new = simplify_builtin (*expr_p, gimple_test_f == is_gimple_stmt);
+
+ if (new && new != *expr_p)
+ {
+ /* There was a transformation of this call which computes the
+ same value, but in a more efficient way. Return and try
+ again. */
+ *expr_p = new;
+ return GS_OK;
+ }
+ }
+
+ /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
+ decl. This allows us to eliminate redundant or useless
+ calls to "const" functions. */
+ if (TREE_CODE (*expr_p) == CALL_EXPR
+ && (call_expr_flags (*expr_p) & (ECF_CONST | ECF_PURE)))
+ TREE_SIDE_EFFECTS (*expr_p) = 0;
+
+ return ret;
+}
+
+/* Handle shortcut semantics in the predicate operand of a COND_EXPR by
+ rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
+
+ TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
+ condition is true or false, respectively. If null, we should generate
+ our own to skip over the evaluation of this specific expression.
+
+ This function is the tree equivalent of do_jump.
+
+ shortcut_cond_r should only be called by shortcut_cond_expr. */
+
+static tree
+shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p)
+{
+ tree local_label = NULL_TREE;
+ tree t, expr = NULL;
+
+ /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
+ retain the shortcut semantics. Just insert the gotos here;
+ shortcut_cond_expr will append the real blocks later. */
+ if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
+ {
+ /* Turn if (a && b) into
+
+ if (a); else goto no;
+ if (b) goto yes; else goto no;
+ (no:) */
+
+ if (false_label_p == NULL)
+ false_label_p = &local_label;
+
+ t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p);
+ append_to_statement_list (t, &expr);
+
+ t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
+ false_label_p);
+ append_to_statement_list (t, &expr);
+ }
+ else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
+ {
+ /* Turn if (a || b) into
+
+ if (a) goto yes;
+ if (b) goto yes; else goto no;
+ (yes:) */
+
+ if (true_label_p == NULL)
+ true_label_p = &local_label;
+
+ t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL);
+ append_to_statement_list (t, &expr);
+
+ t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
+ false_label_p);
+ append_to_statement_list (t, &expr);
+ }
+ else if (TREE_CODE (pred) == COND_EXPR)
+ {
+ /* As long as we're messing with gotos, turn if (a ? b : c) into
+ if (a)
+ if (b) goto yes; else goto no;
+ else
+ if (c) goto yes; else goto no; */
+ expr = build (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
+ shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
+ false_label_p),
+ shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
+ false_label_p));
+ }
+ else
+ {
+ expr = build (COND_EXPR, void_type_node, pred,
+ build_and_jump (true_label_p),
+ build_and_jump (false_label_p));
+ }
+
+ if (local_label)
+ {
+ t = build1 (LABEL_EXPR, void_type_node, local_label);
+ append_to_statement_list (t, &expr);
+ }
+
+ return expr;
+}
+
+static tree
+shortcut_cond_expr (tree expr)
+{
+ tree pred = TREE_OPERAND (expr, 0);
+ tree then_ = TREE_OPERAND (expr, 1);
+ tree else_ = TREE_OPERAND (expr, 2);
+ tree true_label, false_label, end_label, t;
+ tree *true_label_p;
+ tree *false_label_p;
+ bool emit_end, emit_false;
+
+ /* First do simple transformations. */
+ if (!TREE_SIDE_EFFECTS (else_))
+ {
+ /* If there is no 'else', turn (a && b) into if (a) if (b). */
+ while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
+ {
+ TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
+ then_ = shortcut_cond_expr (expr);
+ pred = TREE_OPERAND (pred, 0);
+ expr = build (COND_EXPR, void_type_node, pred, then_,
+ build_empty_stmt ());
+ }
+ }
+ if (!TREE_SIDE_EFFECTS (then_))
+ {
+ /* If there is no 'then', turn
+ if (a || b); else d
+ into
+ if (a); else if (b); else d. */
+ while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
+ {
+ TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
+ else_ = shortcut_cond_expr (expr);
+ pred = TREE_OPERAND (pred, 0);
+ expr = build (COND_EXPR, void_type_node, pred,
+ build_empty_stmt (), else_);
+ }
+ }
+
+ /* If we're done, great. */
+ if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
+ && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
+ return expr;
+
+ /* Otherwise we need to mess with gotos. Change
+ if (a) c; else d;
+ to
+ if (a); else goto no;
+ c; goto end;
+ no: d; end:
+ and recursively gimplify the condition. */
+
+ true_label = false_label = end_label = NULL_TREE;
+
+ /* If our arms just jump somewhere, hijack those labels so we don't
+ generate jumps to jumps. */
+
+ if (TREE_CODE (then_) == GOTO_EXPR
+ && TREE_CODE (GOTO_DESTINATION (then_)) == LABEL_DECL)
+ {
+ true_label = GOTO_DESTINATION (then_);
+ then_ = build_empty_stmt ();
+ }
+
+ if (TREE_CODE (else_) == GOTO_EXPR
+ && TREE_CODE (GOTO_DESTINATION (else_)) == LABEL_DECL)
+ {
+ false_label = GOTO_DESTINATION (else_);
+ else_ = build_empty_stmt ();
+ }
+
+ /* If we aren't hijacking a label for the 'then' branch, it falls through. */
+ if (true_label)
+ true_label_p = &true_label;
+ else
+ true_label_p = NULL;
+
+ /* The 'else' branch also needs a label if it contains interesting code. */
+ if (false_label || TREE_SIDE_EFFECTS (else_))
+ false_label_p = &false_label;
+ else
+ false_label_p = NULL;
+
+ /* If there was nothing else in our arms, just forward the label(s). */
+ if (!TREE_SIDE_EFFECTS (then_) && !TREE_SIDE_EFFECTS (else_))
+ return shortcut_cond_r (pred, true_label_p, false_label_p);
+
+ /* If our last subexpression already has a terminal label, reuse it. */
+ if (TREE_SIDE_EFFECTS (else_))
+ expr = expr_last (else_);
+ else
+ expr = expr_last (then_);
+ if (TREE_CODE (expr) == LABEL_EXPR)
+ end_label = LABEL_EXPR_LABEL (expr);
+
+ /* If we don't care about jumping to the 'else' branch, jump to the end
+ if the condition is false. */
+ if (!false_label_p)
+ false_label_p = &end_label;
+
+ /* We only want to emit these labels if we aren't hijacking them. */
+ emit_end = (end_label == NULL_TREE);
+ emit_false = (false_label == NULL_TREE);
+
+ pred = shortcut_cond_r (pred, true_label_p, false_label_p);
+
+ expr = NULL;
+ append_to_statement_list (pred, &expr);
+
+ append_to_statement_list (then_, &expr);
+ if (TREE_SIDE_EFFECTS (else_))
+ {
+ t = build_and_jump (&end_label);
+ append_to_statement_list (t, &expr);
+ if (emit_false)
+ {
+ t = build1 (LABEL_EXPR, void_type_node, false_label);
+ append_to_statement_list (t, &expr);
+ }
+ append_to_statement_list (else_, &expr);
+ }
+ if (emit_end && end_label)
+ {
+ t = build1 (LABEL_EXPR, void_type_node, end_label);
+ append_to_statement_list (t, &expr);
+ }
+
+ return expr;
+}
+
+/* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
+
+static tree
+gimple_boolify (tree expr)
+{
+ tree type = TREE_TYPE (expr);
+
+ if (TREE_CODE (type) == BOOLEAN_TYPE)
+ return expr;
+
+ /* If this is the predicate of a COND_EXPR, it might not even be a
+ truthvalue yet. */
+ expr = (*lang_hooks.truthvalue_conversion) (expr);
+
+ switch (TREE_CODE (expr))
+ {
+ case TRUTH_AND_EXPR:
+ case TRUTH_OR_EXPR:
+ case TRUTH_XOR_EXPR:
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_ORIF_EXPR:
+ /* Also boolify the arguments of truth exprs. */
+ TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
+ /* FALLTHRU */
+
+ case TRUTH_NOT_EXPR:
+ TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
+ /* FALLTHRU */
+
+ case EQ_EXPR: case NE_EXPR:
+ case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
+ /* These expressions always produce boolean results. */
+ TREE_TYPE (expr) = boolean_type_node;
+ return expr;
+
+ default:
+ /* Other expressions that get here must have boolean values, but
+ might need to be converted to the appropriate mode. */
+ return convert (boolean_type_node, expr);
+ }
+}
+
+/* Convert the conditional expression pointed by EXPR_P '(p) ? a : b;'
+ into
+
+ if (p) if (p)
+ t1 = a; a;
+ else or else
+ t1 = b; b;
+ t1;
+
+ The second form is used when *EXPR_P is of type void.
+
+ PRE_P points to the list where side effects that must happen before
+ *EXPR_P should be stored. */
+
+static enum gimplify_status
+gimplify_cond_expr (tree *expr_p, tree *pre_p, tree target)
+{
+ tree expr = *expr_p;
+ tree tmp;
+ enum gimplify_status ret;
+
+ /* If this COND_EXPR has a value, copy the values into a temporary within
+ the arms. */
+ if (! VOID_TYPE_P (TREE_TYPE (expr)))
+ {
+ if (target)
+ {
+ tmp = target;
+ ret = GS_OK;
+ }
+ else
+ {
+ tmp = create_tmp_var (TREE_TYPE (expr), "iftmp");
+ ret = GS_ALL_DONE;
+ }
+
+ /* Build the then clause, 't1 = a;'. But don't build an assignment
+ if this branch is void; in C++ it can be, if it's a throw. */
+ if (TREE_TYPE (TREE_OPERAND (expr, 1)) != void_type_node)
+ TREE_OPERAND (expr, 1)
+ = build (MODIFY_EXPR, void_type_node, tmp, TREE_OPERAND (expr, 1));
+
+ /* Build the else clause, 't1 = b;'. */
+ if (TREE_TYPE (TREE_OPERAND (expr, 2)) != void_type_node)
+ TREE_OPERAND (expr, 2)
+ = build (MODIFY_EXPR, void_type_node, tmp, TREE_OPERAND (expr, 2));
+
+ TREE_TYPE (expr) = void_type_node;
+ recalculate_side_effects (expr);
+
+ /* Move the COND_EXPR to the prequeue and use the temp in its place. */
+ gimplify_stmt (&expr);
+ append_to_statement_list (expr, pre_p);
+ *expr_p = tmp;
+
+ return ret;
+ }
+
+ /* Make sure the condition has BOOLEAN_TYPE. */
+ TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
+
+ /* Break apart && and || conditions. */
+ if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
+ || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
+ {
+ expr = shortcut_cond_expr (expr);
+
+ if (expr != *expr_p)
+ {
+ *expr_p = expr;
+
+ /* We can't rely on gimplify_expr to re-gimplify the expanded
+ form properly, as cleanups might cause the target labels to be
+ wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
+ set up a conditional context. */
+ gimple_push_condition ();
+ gimplify_stmt (expr_p);
+ gimple_pop_condition (pre_p);
+
+ return GS_ALL_DONE;
+ }
+ }
+
+ /* Now do the normal gimplification. */
+ ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
+ is_gimple_condexpr, fb_rvalue);
+
+ gimple_push_condition ();
+
+ gimplify_to_stmt_list (&TREE_OPERAND (expr, 1));
+ gimplify_to_stmt_list (&TREE_OPERAND (expr, 2));
+ recalculate_side_effects (expr);
+
+ gimple_pop_condition (pre_p);
+
+ if (ret == GS_ERROR)
+ ;
+ else if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
+ ret = GS_ALL_DONE;
+ else if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 2)))
+ /* Rewrite "if (a); else b" to "if (!a) b" */
+ {
+ TREE_OPERAND (expr, 0) = invert_truthvalue (TREE_OPERAND (expr, 0));
+ ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
+ is_gimple_condexpr, fb_rvalue);
+
+ tmp = TREE_OPERAND (expr, 1);
+ TREE_OPERAND (expr, 1) = TREE_OPERAND (expr, 2);
+ TREE_OPERAND (expr, 2) = tmp;
+ }
+ else
+ /* Both arms are empty; replace the COND_EXPR with its predicate. */
+ expr = TREE_OPERAND (expr, 0);
+
+ *expr_p = expr;
+ return ret;
+}
+
+/* Gimplify the MODIFY_EXPR node pointed by EXPR_P.
+
+ modify_expr
+ : varname '=' rhs
+ | '*' ID '=' rhs
+
+ PRE_P points to the list where side effects that must happen before
+ *EXPR_P should be stored.
+
+ POST_P points to the list where side effects that must happen after
+ *EXPR_P should be stored.
+
+ WANT_VALUE is nonzero iff we want to use the value of this expression
+ in another expression. */
+
+static enum gimplify_status
+gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value)
+{
+ tree *from_p = &TREE_OPERAND (*expr_p, 1);
+ tree *to_p = &TREE_OPERAND (*expr_p, 0);
+ enum gimplify_status ret;
+
+#if defined ENABLE_CHECKING
+ if (TREE_CODE (*expr_p) != MODIFY_EXPR && TREE_CODE (*expr_p) != INIT_EXPR)
+ abort ();
+#endif
+
+ /* The distinction between MODIFY_EXPR and INIT_EXPR is no longer useful. */
+ if (TREE_CODE (*expr_p) == INIT_EXPR)
+ TREE_SET_CODE (*expr_p, MODIFY_EXPR);
+
+ ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
+ if (ret == GS_ERROR)
+ return ret;
+
+ /* If we are initializing something from a TARGET_EXPR, strip the
+ TARGET_EXPR and initialize it directly. */
+ /* What about code that pulls out the temp and uses it elsewhere? I
+ think that such code never uses the TARGET_EXPR as an initializer. If
+ I'm wrong, we'll abort because the temp won't have any RTL. In that
+ case, I guess we'll need to replace references somehow. */
+ if (TREE_CODE (*from_p) == TARGET_EXPR)
+ *from_p = TARGET_EXPR_INITIAL (*from_p);
+
+ /* If we're assigning from a ?: expression with ADDRESSABLE type, push
+ the assignment down into the branches, since we can't generate a
+ temporary of such a type. */
+ if (TREE_CODE (*from_p) == COND_EXPR
+ && TREE_ADDRESSABLE (TREE_TYPE (*from_p)))
+ {
+ *expr_p = *from_p;
+ return gimplify_cond_expr (expr_p, pre_p, *to_p);
+ }
+
+ ret = gimplify_expr (from_p, pre_p, post_p, is_gimple_rhs, fb_rvalue);
+ if (ret == GS_ERROR)
+ return ret;
+
+ ret = gimplify_init_constructor (expr_p, pre_p, post_p, want_value);
+ if (ret != GS_UNHANDLED)
+ return ret;
+
+ /* If the destination is already simple, nothing else needed. */
+ if (is_gimple_tmp_var (*to_p))
+ ret = GS_ALL_DONE;
+ else
+ {
+ /* If the RHS of the MODIFY_EXPR may throw or make a nonlocal goto and
+ the LHS is a user variable, then we need to introduce a temporary.
+ ie temp = RHS; LHS = temp.
+
+ This way the optimizers can determine that the user variable is
+ only modified if evaluation of the RHS does not throw.
+
+ FIXME this should be handled by the is_gimple_rhs predicate. */
+
+ if (TREE_CODE (*from_p) == CALL_EXPR
+ || (flag_non_call_exceptions && tree_could_trap_p (*from_p))
+ /* If we're dealing with a renamable type, either source or dest
+ must be a renamed variable. */
+ || (is_gimple_reg_type (TREE_TYPE (*from_p))
+ && !is_gimple_reg (*to_p)))
+ gimplify_expr (from_p, pre_p, post_p, is_gimple_val, fb_rvalue);
+
+ /* If the value being copied is of variable width, expose the length
+ if the copy by converting the whole thing to a memcpy. */
+ /* ??? Except that we can't manage this with VA_ARG_EXPR. Yes, this
+ does leave us with an edge condition that doesn't work. The only
+ way out is to rearrange how VA_ARG_EXPR works. */
+ if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p))) != INTEGER_CST
+ && TREE_CODE (*from_p) != VA_ARG_EXPR)
+ {
+ tree args, t, dest;
+
+ t = TYPE_SIZE_UNIT (TREE_TYPE (*to_p));
+ args = tree_cons (NULL, t, NULL);
+ t = build_addr_expr (*from_p);
+ args = tree_cons (NULL, t, args);
+ dest = build_addr_expr (*to_p);
+ args = tree_cons (NULL, dest, args);
+ t = implicit_built_in_decls[BUILT_IN_MEMCPY];
+ t = build_function_call_expr (t, args);
+ if (want_value)
+ {
+ t = build1 (NOP_EXPR, TREE_TYPE (dest), t);
+ t = build1 (INDIRECT_REF, TREE_TYPE (*to_p), t);
+ }
+ *expr_p = t;
+
+ return GS_OK;
+ }
+
+ ret = want_value ? GS_OK : GS_ALL_DONE;
+ }
+
+ if (want_value)
+ {
+ append_to_statement_list (*expr_p, pre_p);
+ *expr_p = *to_p;
+ }
+
+ return ret;
+}
+
+/* Gimplify TRUTH_ANDIF_EXPR and TRUTH_ORIF_EXPR expressions. EXPR_P
+ points to the expression to gimplify.
+
+ Expressions of the form 'a && b' are gimplified to:
+
+ a && b ? true : false
+
+ gimplify_cond_expr will do the rest.
+
+ PRE_P points to the list where side effects that must happen before
+ *EXPR_P should be stored. */
+
+static enum gimplify_status
+gimplify_boolean_expr (tree *expr_p)
+{
+ /* Preserve the original type of the expression. */
+ tree type = TREE_TYPE (*expr_p);
+
+ *expr_p = build (COND_EXPR, type, *expr_p,
+ convert (type, boolean_true_node),
+ convert (type, boolean_false_node));
+
+ return GS_OK;
+}
+
+/* Gimplifies an expression sequence. This function gimplifies each
+ expression and re-writes the original expression with the last
+ expression of the sequence in GIMPLE form.
+
+ PRE_P points to the list where the side effects for all the
+ expressions in the sequence will be emitted.
+
+ WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
+/* ??? Should rearrange to share the pre-queue with all the indirect
+ invocations of gimplify_expr. Would probably save on creations
+ of statement_list nodes. */
+
+static enum gimplify_status
+gimplify_compound_expr (tree *expr_p, tree *pre_p, bool want_value)
+{
+ tree t = *expr_p;
+
+ do
+ {
+ tree *sub_p = &TREE_OPERAND (t, 0);
+
+ if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
+ gimplify_compound_expr (sub_p, pre_p, false);
+ else
+ gimplify_stmt (sub_p);
+ append_to_statement_list (*sub_p, pre_p);
+
+ t = TREE_OPERAND (t, 1);
+ }
+ while (TREE_CODE (t) == COMPOUND_EXPR);
+
+ *expr_p = t;
+ if (want_value)
+ return GS_OK;
+ else
+ {
+ gimplify_stmt (expr_p);
+ return GS_ALL_DONE;
+ }
+}
+
+/* Gimplifies a statement list. These may be created either by an
+ enlightend front-end, or by shortcut_cond_expr. */
+
+static enum gimplify_status
+gimplify_statement_list (tree *expr_p)
+{
+ tree_stmt_iterator i = tsi_start (*expr_p);
+
+ while (!tsi_end_p (i))
+ {
+ tree t;
+
+ gimplify_stmt (tsi_stmt_ptr (i));
+
+ t = tsi_stmt (i);
+ if (TREE_CODE (t) == STATEMENT_LIST)
+ {
+ tsi_link_before (&i, t, TSI_SAME_STMT);
+ tsi_delink (&i);
+ }
+ else
+ tsi_next (&i);
+ }
+
+ return GS_ALL_DONE;
+}
+
+/* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
+ gimplify. After gimplification, EXPR_P will point to a new temporary
+ that holds the original value of the SAVE_EXPR node.
+
+ PRE_P points to the list where side effects that must happen before
+ *EXPR_P should be stored. */
+
+static enum gimplify_status
+gimplify_save_expr (tree *expr_p, tree *pre_p, tree *post_p)
+{
+ enum gimplify_status ret = GS_ALL_DONE;
+ tree val;
+
+#if defined ENABLE_CHECKING
+ if (TREE_CODE (*expr_p) != SAVE_EXPR)
+ abort ();
+#endif
+
+ val = TREE_OPERAND (*expr_p, 0);
+
+ /* If the operand is already a GIMPLE temporary, just re-write the
+ SAVE_EXPR node. */
+ if (is_gimple_tmp_var (val))
+ *expr_p = val;
+ /* The operand may be a void-valued expression such as SAVE_EXPRs
+ generated by the Java frontend for class initialization. It is
+ being executed only for its side-effects. */
+ else if (TREE_TYPE (val) == void_type_node)
+ {
+ tree body = TREE_OPERAND (*expr_p, 0);
+ ret = gimplify_expr (& body, pre_p, post_p, is_gimple_stmt, fb_none);
+ append_to_statement_list (body, pre_p);
+ *expr_p = build_empty_stmt ();
+ }
+ else
+ *expr_p = TREE_OPERAND (*expr_p, 0)
+ = get_initialized_tmp_var (val, pre_p, post_p);
+
+ return ret;
+}
+
+/* Re-write the ADDR_EXPR node pointed by EXPR_P
+
+ unary_expr
+ : ...
+ | '&' varname
+ ...
+
+ PRE_P points to the list where side effects that must happen before
+ *EXPR_P should be stored.
+
+ POST_P points to the list where side effects that must happen after
+ *EXPR_P should be stored. */
+
+static enum gimplify_status
+gimplify_addr_expr (tree *expr_p, tree *pre_p, tree *post_p)
+{
+ tree expr = *expr_p;
+ tree op0 = TREE_OPERAND (expr, 0);
+ enum gimplify_status ret;
+
+ switch (TREE_CODE (op0))
+ {
+ case INDIRECT_REF:
+ /* Check if we are dealing with an expression of the form '&*ptr'.
+ While the front end folds away '&*ptr' into 'ptr', these
+ expressions may be generated internally by the compiler (e.g.,
+ builtins like __builtin_va_end). */
+ *expr_p = TREE_OPERAND (op0, 0);
+ ret = GS_OK;
+ break;
+
+ case ARRAY_REF:
+ /* Fold &a[6] to (&a + 6). */
+ ret = gimplify_array_ref_to_plus (&TREE_OPERAND (expr, 0),
+ pre_p, post_p);
+
+ /* This added an INDIRECT_REF. Fold it away. */
+ op0 = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
+
+ *expr_p = op0;
+ break;
+
+ default:
+ /* We use fb_either here because the C frontend sometimes takes
+ the address of a call that returns a struct. */
+ ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
+ is_gimple_addr_expr_arg, fb_either);
+ if (ret != GS_ERROR)
+ {
+ /* At this point, the argument of the ADDR_EXPR should be
+ sufficiently simple that there are never side effects. */
+ /* ??? Could split out the decision code from build1 to verify. */
+ TREE_SIDE_EFFECTS (expr) = 0;
+
+ /* Make sure TREE_INVARIANT/TREE_CONSTANT is set properly. */
+ recompute_tree_invarant_for_addr_expr (expr);
+
+ /* Mark the RHS addressable. */
+ (*lang_hooks.mark_addressable) (TREE_OPERAND (expr, 0));
+ }
+ break;
+ }
+
+ /* If the operand is gimplified into a _DECL, mark the address expression
+ as TREE_INVARIANT. */
+ if (DECL_P (TREE_OPERAND (expr, 0)))
+ TREE_INVARIANT (expr) = 1;
+
+ return ret;
+}
+
+/* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
+ value; output operands should be a gimple lvalue. */
+
+static enum gimplify_status
+gimplify_asm_expr (tree *expr_p, tree *pre_p, tree *post_p)
+{
+ tree expr = *expr_p;
+ int noutputs = list_length (ASM_OUTPUTS (expr));
+ const char **oconstraints
+ = (const char **) alloca ((noutputs) * sizeof (const char *));
+ int i;
+ tree link;
+ const char *constraint;
+ bool allows_mem, allows_reg, is_inout;
+ enum gimplify_status ret, tret;
+
+ ASM_STRING (expr)
+ = resolve_asm_operand_names (ASM_STRING (expr), ASM_OUTPUTS (expr),
+ ASM_INPUTS (expr));
+
+ ret = GS_ALL_DONE;
+ for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = TREE_CHAIN (link))
+ {
+ oconstraints[i] = constraint
+ = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
+
+ parse_output_constraint (&constraint, i, 0, 0,
+ &allows_mem, &allows_reg, &is_inout);
+
+ if (!allows_reg && allows_mem)
+ (*lang_hooks.mark_addressable) (TREE_VALUE (link));
+
+ tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
+ is_inout ? is_gimple_min_lval : is_gimple_lvalue,
+ fb_lvalue | fb_mayfail);
+ if (tret == GS_ERROR)
+ {
+ error ("invalid lvalue in asm output %d", i);
+ ret = tret;
+ }
+
+ if (is_inout)
+ {
+ /* An input/output operand. To give the optimizers more
+ flexibility, split it into separate input and output
+ operands. */
+ tree input;
+ char buf[10];
+ size_t constraint_len = strlen (constraint);
+
+ /* Turn the in/out constraint into an output constraint. */
+ char *p = xstrdup (constraint);
+ p[0] = '=';
+ TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
+ free (p);
+
+ /* And add a matching input constraint. */
+ if (allows_reg)
+ {
+ sprintf (buf, "%d", i);
+ input = build_string (strlen (buf), buf);
+ }
+ else
+ input = build_string (constraint_len - 1, constraint + 1);
+ input = build_tree_list (build_tree_list (NULL_TREE, input),
+ unshare_expr (TREE_VALUE (link)));
+ ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
+ }
+ }
+
+ for (link = ASM_INPUTS (expr); link; ++i, link = TREE_CHAIN (link))
+ {
+ constraint
+ = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
+ parse_input_constraint (&constraint, 0, 0, noutputs, 0,
+ oconstraints, &allows_mem, &allows_reg);
+
+ /* If the operand is a memory input, it should be an lvalue. */
+ if (!allows_reg && allows_mem)
+ {
+ (*lang_hooks.mark_addressable) (TREE_VALUE (link));
+ tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
+ is_gimple_lvalue, fb_lvalue | fb_mayfail);
+ if (tret == GS_ERROR)
+ {
+ error ("memory input %d is not directly addressable", i);
+ ret = tret;
+ }
+ }
+ else
+ {
+ tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
+ is_gimple_val, fb_rvalue);
+ if (tret == GS_ERROR)
+ ret = tret;
+ }
+ }
+
+ return ret;
+}
+
+/* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
+ WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
+ gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
+ return to this function.
+
+ FIXME should we complexify the prequeue handling instead? Or use flags
+ for all the cleanups and let the optimizer tighten them up? The current
+ code seems pretty fragile; it will break on a cleanup within any
+ non-conditional nesting. But any such nesting would be broken, anyway;
+ we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
+ and continues out of it. We can do that at the RTL level, though, so
+ having an optimizer to tighten up try/finally regions would be a Good
+ Thing. */
+
+static enum gimplify_status
+gimplify_cleanup_point_expr (tree *expr_p, tree *pre_p)
+{
+ tree_stmt_iterator iter;
+ tree body;
+
+ tree temp = voidify_wrapper_expr (*expr_p);
+
+ /* We only care about the number of conditions between the innermost
+ CLEANUP_POINT_EXPR and the cleanup. So save and reset the count. */
+ int old_conds = gimplify_ctxp->conditions;
+ gimplify_ctxp->conditions = 0;
+
+ body = TREE_OPERAND (*expr_p, 0);
+ gimplify_to_stmt_list (&body);
+
+ gimplify_ctxp->conditions = old_conds;
+
+ for (iter = tsi_start (body); !tsi_end_p (iter); )
+ {
+ tree *wce_p = tsi_stmt_ptr (iter);
+ tree wce = *wce_p;
+
+ if (TREE_CODE (wce) == WITH_CLEANUP_EXPR)
+ {
+ if (tsi_one_before_end_p (iter))
+ {
+ tsi_link_before (&iter, TREE_OPERAND (wce, 1), TSI_SAME_STMT);
+ tsi_delink (&iter);
+ break;
+ }
+ else
+ {
+ tree sl, tfe;
+
+ sl = tsi_split_statement_list_after (&iter);
+ tfe = build (TRY_FINALLY_EXPR, void_type_node, sl, NULL_TREE);
+ append_to_statement_list (TREE_OPERAND (wce, 1),
+ &TREE_OPERAND (tfe, 1));
+ *wce_p = tfe;
+ iter = tsi_start (sl);
+ }
+ }
+ else
+ tsi_next (&iter);
+ }
+
+ if (temp)
+ {
+ *expr_p = temp;
+ append_to_statement_list (body, pre_p);
+ return GS_OK;
+ }
+ else
+ {
+ *expr_p = body;
+ return GS_ALL_DONE;
+ }
+}
+
+/* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
+ is the cleanup action required. */
+
+static void
+gimple_push_cleanup (tree var, tree cleanup, tree *pre_p)
+{
+ tree wce;
+
+ /* Errors can result in improperly nested cleanups. Which results in
+ confusion when trying to resolve the WITH_CLEANUP_EXPR. */
+ if (errorcount || sorrycount)
+ return;
+
+ if (gimple_conditional_context ())
+ {
+ /* If we're in a conditional context, this is more complex. We only
+ want to run the cleanup if we actually ran the initialization that
+ necessitates it, but we want to run it after the end of the
+ conditional context. So we wrap the try/finally around the
+ condition and use a flag to determine whether or not to actually
+ run the destructor. Thus
+
+ test ? f(A()) : 0
+
+ becomes (approximately)
+
+ flag = 0;
+ try {
+ if (test) { A::A(temp); flag = 1; val = f(temp); }
+ else { val = 0; }
+ } finally {
+ if (flag) A::~A(temp);
+ }
+ val
+ */
+
+ tree flag = create_tmp_var (boolean_type_node, "cleanup");
+ tree ffalse = build (MODIFY_EXPR, void_type_node, flag,
+ boolean_false_node);
+ tree ftrue = build (MODIFY_EXPR, void_type_node, flag,
+ boolean_true_node);
+ cleanup = build (COND_EXPR, void_type_node, flag, cleanup,
+ build_empty_stmt ());
+ wce = build (WITH_CLEANUP_EXPR, void_type_node, NULL_TREE,
+ cleanup, NULL_TREE);
+ append_to_statement_list (ffalse, &gimplify_ctxp->conditional_cleanups);
+ append_to_statement_list (wce, &gimplify_ctxp->conditional_cleanups);
+ append_to_statement_list (ftrue, pre_p);
+
+ /* Because of this manipulation, and the EH edges that jump
+ threading cannot redirect, the temporary (VAR) will appear
+ to be used uninitialized. Don't warn. */
+ TREE_NO_WARNING (var) = 1;
+ }
+ else
+ {
+ wce = build (WITH_CLEANUP_EXPR, void_type_node, NULL_TREE,
+ cleanup, NULL_TREE);
+ append_to_statement_list (wce, pre_p);
+ }
+
+ gimplify_stmt (&TREE_OPERAND (wce, 1));
+}
+
+/* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
+
+static enum gimplify_status
+gimplify_target_expr (tree *expr_p, tree *pre_p, tree *post_p)
+{
+ tree targ = *expr_p;
+ tree temp = TARGET_EXPR_SLOT (targ);
+ tree init = TARGET_EXPR_INITIAL (targ);
+ enum gimplify_status ret;
+
+ if (init)
+ {
+ /* TARGET_EXPR temps aren't part of the enclosing block, so add it to the
+ temps list. */
+ gimple_add_tmp_var (temp);
+
+ /* Build up the initialization and add it to pre_p. */
+ init = build (MODIFY_EXPR, void_type_node, temp, init);
+ ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
+ if (ret == GS_ERROR)
+ return GS_ERROR;
+
+ append_to_statement_list (init, pre_p);
+
+ /* If needed, push the cleanup for the temp. */
+ if (TARGET_EXPR_CLEANUP (targ))
+ {
+ gimplify_stmt (&TARGET_EXPR_CLEANUP (targ));
+ gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ), pre_p);
+ }
+
+ /* Only expand this once. */
+ TREE_OPERAND (targ, 3) = init;
+ TARGET_EXPR_INITIAL (targ) = NULL_TREE;
+ }
+ else if (!temp->decl.seen_in_bind_expr)
+ /* We should have expanded this before. */
+ abort ();
+
+ *expr_p = temp;
+ return GS_OK;
+}
+
+/* Gimplification of expression trees. */
+
+/* Gimplify an expression which appears at statement context; usually, this
+ means replacing it with a suitably gimple COMPOUND_EXPR. */
+
+void
+gimplify_stmt (tree *stmt_p)
+{
+ gimplify_expr (stmt_p, NULL, NULL, is_gimple_stmt, fb_none);
+ if (!*stmt_p)
+ *stmt_p = alloc_stmt_list ();
+}
+
+/* Similarly, but force the result to be a STATEMENT_LIST. */
+
+void
+gimplify_to_stmt_list (tree *stmt_p)
+{
+ gimplify_stmt (stmt_p);
+ if (TREE_CODE (*stmt_p) != STATEMENT_LIST)
+ {
+ tree t = *stmt_p;
+ *stmt_p = NULL;
+ append_to_statement_list (t, stmt_p);
+ }
+}
+
+
+/* Gimplifies the expression tree pointed by EXPR_P. Return 0 if
+ gimplification failed.
+
+ PRE_P points to the list where side effects that must happen before
+ EXPR should be stored.
+
+ POST_P points to the list where side effects that must happen after
+ EXPR should be stored, or NULL if there is no suitable list. In
+ that case, we copy the result to a temporary, emit the
+ post-effects, and then return the temporary.
+
+ GIMPLE_TEST_F points to a function that takes a tree T and
+ returns nonzero if T is in the GIMPLE form requested by the
+ caller. The GIMPLE predicates are in tree-gimple.c.
+
+ This test is used twice. Before gimplification, the test is
+ invoked to determine whether *EXPR_P is already gimple enough. If
+ that fails, *EXPR_P is gimplified according to its code and
+ GIMPLE_TEST_F is called again. If the test still fails, then a new
+ temporary variable is created and assigned the value of the
+ gimplified expression.
+
+ FALLBACK tells the function what sort of a temporary we want. If the 1
+ bit is set, an rvalue is OK. If the 2 bit is set, an lvalue is OK.
+ If both are set, either is OK, but an lvalue is preferable.
+
+ The return value is either GS_ERROR or GS_ALL_DONE, since this function
+ iterates until solution. */
+
+enum gimplify_status
+gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
+ bool (* gimple_test_f) (tree), fallback_t fallback)
+{
+ tree tmp;
+ tree internal_pre = NULL_TREE;
+ tree internal_post = NULL_TREE;
+ tree save_expr;
+ int is_statement = (pre_p == NULL);
+ location_t *locus;
+ location_t saved_location;
+ enum gimplify_status ret;
+
+ save_expr = *expr_p;
+ if (save_expr == NULL_TREE)
+ return GS_ALL_DONE;
+
+ /* We used to check the predicate here and return immediately if it
+ succeeds. This is wrong; the design is for gimplification to be
+ idempotent, and for the predicates to only test for valid forms, not
+ whether they are fully simplified. */
+
+ /* Set up our internal queues if needed. */
+ if (pre_p == NULL)
+ pre_p = &internal_pre;
+ if (post_p == NULL)
+ post_p = &internal_post;
+
+ saved_location = input_location;
+ if (save_expr == error_mark_node)
+ locus = NULL;
+ else
+ locus = EXPR_LOCUS (save_expr);
+ if (locus)
+ input_location = *locus;
+
+ /* Loop over the specific gimplifiers until the toplevel node
+ remains the same. */
+ do
+ {
+ /* Strip any uselessness. */
+ STRIP_MAIN_TYPE_NOPS (*expr_p);
+
+ /* Remember the expr. */
+ save_expr = *expr_p;
+
+ /* Die, die, die, my darling. */
+ if (save_expr == error_mark_node
+ || TREE_TYPE (save_expr) == error_mark_node)
+ {
+ ret = GS_ERROR;
+ break;
+ }
+
+ /* Do any language-specific gimplification. */
+ ret = (*lang_hooks.gimplify_expr) (expr_p, pre_p, post_p);
+ if (ret == GS_OK)
+ {
+ if (*expr_p == NULL_TREE)
+ break;
+ if (*expr_p != save_expr)
+ continue;
+ }
+ else if (ret != GS_UNHANDLED)
+ break;
+
+ ret = GS_OK;
+ switch (TREE_CODE (*expr_p))
+ {
+ /* First deal with the special cases. */
+
+ case POSTINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ case PREINCREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
+ fallback != fb_none);
+ break;
+
+ case ARRAY_REF:
+ ret = gimplify_array_ref (expr_p, pre_p, post_p,
+ fallback & fb_lvalue);
+ break;
+
+ case COMPONENT_REF:
+ ret = gimplify_compound_lval (expr_p, pre_p, post_p,
+ fallback & fb_lvalue);
+ break;
+
+ case COND_EXPR:
+ ret = gimplify_cond_expr (expr_p, pre_p, NULL_TREE);
+ break;
+
+ case CALL_EXPR:
+ ret = gimplify_call_expr (expr_p, pre_p, gimple_test_f);
+ break;
+
+ case TREE_LIST:
+ abort ();
+
+ case COMPOUND_EXPR:
+ ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
+ break;
+
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ ret = gimplify_compound_lval (expr_p, pre_p, post_p,
+ fallback & fb_lvalue);
+ break;
+
+ case MODIFY_EXPR:
+ case INIT_EXPR:
+ ret = gimplify_modify_expr (expr_p, pre_p, post_p,
+ fallback != fb_none);
+ break;
+
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_ORIF_EXPR:
+ ret = gimplify_boolean_expr (expr_p);
+ break;
+
+ case TRUTH_NOT_EXPR:
+ TREE_OPERAND (*expr_p, 0)
+ = gimple_boolify (TREE_OPERAND (*expr_p, 0));
+ ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
+ is_gimple_val, fb_rvalue);
+ recalculate_side_effects (*expr_p);
+ break;
+
+ case ADDR_EXPR:
+ ret = gimplify_addr_expr (expr_p, pre_p, post_p);
+ break;
+
+ case VA_ARG_EXPR:
+ /* Mark any _DECL inside the operand as volatile to avoid the
+ optimizers messing around with it. FIXME: Remove this once
+ VA_ARG_EXPRs are properly lowered. */
+ walk_tree (&TREE_OPERAND (*expr_p, 0), mark_decls_volatile_r,
+ NULL, NULL);
+
+ /* va_arg expressions are in GIMPLE form already. */
+ ret = GS_ALL_DONE;
+ break;
+
+ case CONVERT_EXPR:
+ case NOP_EXPR:
+ if (IS_EMPTY_STMT (*expr_p))
+ {
+ ret = GS_ALL_DONE;
+ break;
+ }
+
+ if (VOID_TYPE_P (TREE_TYPE (*expr_p))
+ || fallback == fb_none)
+ {
+ /* Just strip a conversion to void (or in void context) and
+ try again. */
+ *expr_p = TREE_OPERAND (*expr_p, 0);
+ break;
+ }
+
+ ret = gimplify_conversion (expr_p);
+ if (ret == GS_ERROR)
+ break;
+ if (*expr_p != save_expr)
+ break;
+ /* FALLTHRU */
+
+ case FIX_TRUNC_EXPR:
+ case FIX_CEIL_EXPR:
+ case FIX_FLOOR_EXPR:
+ case FIX_ROUND_EXPR:
+ /* unary_expr: ... | '(' cast ')' val | ... */
+ ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
+ is_gimple_val, fb_rvalue);
+ recalculate_side_effects (*expr_p);
+ break;
+
+ case INDIRECT_REF:
+ ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
+ is_gimple_reg, fb_rvalue);
+ recalculate_side_effects (*expr_p);
+ break;
+
+ /* Constants need not be gimplified. */
+ case INTEGER_CST:
+ case REAL_CST:
+ case STRING_CST:
+ case COMPLEX_CST:
+ case VECTOR_CST:
+ ret = GS_ALL_DONE;
+ break;
+
+ case CONST_DECL:
+ *expr_p = DECL_INITIAL (*expr_p);
+ break;
+
+ case EXC_PTR_EXPR:
+ /* FIXME make this a decl. */
+ ret = GS_ALL_DONE;
+ break;
+
+ case BIND_EXPR:
+ ret = gimplify_bind_expr (expr_p, pre_p);
+ break;
+
+ case LOOP_EXPR:
+ ret = gimplify_loop_expr (expr_p, pre_p);
+ break;
+
+ case SWITCH_EXPR:
+ ret = gimplify_switch_expr (expr_p, pre_p);
+ break;
+
+ case LABELED_BLOCK_EXPR:
+ ret = gimplify_labeled_block_expr (expr_p);
+ break;
+
+ case EXIT_BLOCK_EXPR:
+ ret = gimplify_exit_block_expr (expr_p);
+ break;
+
+ case EXIT_EXPR:
+ ret = gimplify_exit_expr (expr_p);
+ break;
+
+ case GOTO_EXPR:
+ /* If the target is not LABEL, then it is a computed jump
+ and the target needs to be gimplified. */
+ if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
+ ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
+ NULL, is_gimple_val, fb_rvalue);
+ break;
+
+ case LABEL_EXPR:
+ ret = GS_ALL_DONE;
+#ifdef ENABLE_CHECKING
+ if (decl_function_context (LABEL_EXPR_LABEL (*expr_p)) != current_function_decl)
+ abort ();
+#endif
+ break;
+
+ case CASE_LABEL_EXPR:
+ ret = gimplify_case_label_expr (expr_p);
+ break;
+
+ case RETURN_EXPR:
+ ret = gimplify_return_expr (*expr_p, pre_p);
+ break;
+
+ case CONSTRUCTOR:
+ /* Don't reduce this in place; let gimplify_init_constructor work
+ its magic. */
+ ret = GS_ALL_DONE;
+ break;
+
+ /* The following are special cases that are not handled by the
+ original GIMPLE grammar. */
+
+ /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
+ eliminated. */
+ case SAVE_EXPR:
+ ret = gimplify_save_expr (expr_p, pre_p, post_p);
+ break;
+
+ case BIT_FIELD_REF:
+ {
+ enum gimplify_status r0, r1, r2;
+
+ r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
+ is_gimple_min_lval, fb_either);
+ r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
+ is_gimple_val, fb_rvalue);
+ r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p, post_p,
+ is_gimple_val, fb_rvalue);
+ recalculate_side_effects (*expr_p);
+
+ ret = MIN (r0, MIN (r1, r2));
+ }
+ break;
+
+ case NON_LVALUE_EXPR:
+ /* This should have been stripped above. */
+ abort ();
+ break;
+
+ case ASM_EXPR:
+ ret = gimplify_asm_expr (expr_p, pre_p, post_p);
+ break;
+
+ case TRY_FINALLY_EXPR:
+ case TRY_CATCH_EXPR:
+ gimplify_to_stmt_list (&TREE_OPERAND (*expr_p, 0));
+ gimplify_to_stmt_list (&TREE_OPERAND (*expr_p, 1));
+ ret = GS_ALL_DONE;
+ break;
+
+ case CLEANUP_POINT_EXPR:
+ ret = gimplify_cleanup_point_expr (expr_p, pre_p);
+ break;
+
+ case TARGET_EXPR:
+ ret = gimplify_target_expr (expr_p, pre_p, post_p);
+ break;
+
+ case CATCH_EXPR:
+ gimplify_to_stmt_list (&CATCH_BODY (*expr_p));
+ ret = GS_ALL_DONE;
+ break;
+
+ case EH_FILTER_EXPR:
+ gimplify_to_stmt_list (&EH_FILTER_FAILURE (*expr_p));
+ ret = GS_ALL_DONE;
+ break;
+
+ case VTABLE_REF:
+ /* This moves much of the actual computation out of the
+ VTABLE_REF. Perhaps this should be revisited once we want to
+ do clever things with VTABLE_REFs. */
+ ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
+ is_gimple_min_lval, fb_lvalue);
+ break;
+
+ case MIN_EXPR:
+ case MAX_EXPR:
+ ret = gimplify_minimax_expr (expr_p, pre_p, post_p);
+ break;
+
+ case LABEL_DECL:
+ /* We get here when taking the address of a label. We mark
+ the label as "forced"; meaning it can never be removed and
+ it is a potential target for any computed goto. */
+ FORCED_LABEL (*expr_p) = 1;
+ ret = GS_ALL_DONE;
+ break;
+
+ case STATEMENT_LIST:
+ ret = gimplify_statement_list (expr_p);
+ break;
+
+ case VAR_DECL:
+ /* ??? If this is a local variable, and it has not been seen in any
+ outer BIND_EXPR, then it's probably the result of a duplicate
+ declaration, for which we've already issued an error. It would
+ be really nice if the front end wouldn't leak these at all.
+ Currently the only known culprit is C++ destructors, as seen
+ in g++.old-deja/g++.jason/binding.C. */
+ tmp = *expr_p;
+ if (!TREE_STATIC (tmp) && !DECL_EXTERNAL (tmp)
+ && decl_function_context (tmp) == current_function_decl
+ && !tmp->decl.seen_in_bind_expr)
+ {
+#ifdef ENABLE_CHECKING
+ if (!errorcount && !sorrycount)
+ abort ();
+#endif
+ ret = GS_ERROR;
+ }
+ else
+ ret = GS_ALL_DONE;
+ break;
+
+ default:
+ /* If *EXPR_P does not need to be special-cased, handle it
+ according to its class. */
+ if (TREE_CODE_CLASS (TREE_CODE (*expr_p)) == '1')
+ ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
+ post_p, is_gimple_val, fb_rvalue);
+ else if (TREE_CODE_CLASS (TREE_CODE (*expr_p)) == '2'
+ || TREE_CODE_CLASS (TREE_CODE (*expr_p)) == '<'
+ || TREE_CODE (*expr_p) == TRUTH_AND_EXPR
+ || TREE_CODE (*expr_p) == TRUTH_OR_EXPR
+ || TREE_CODE (*expr_p) == TRUTH_XOR_EXPR)
+ {
+ enum gimplify_status r0, r1;
+
+ r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
+ post_p, is_gimple_val, fb_rvalue);
+ r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
+ post_p, is_gimple_val, fb_rvalue);
+
+ ret = MIN (r0, r1);
+ }
+ else if (TREE_CODE_CLASS (TREE_CODE (*expr_p)) == 'd'
+ || TREE_CODE_CLASS (TREE_CODE (*expr_p)) == 'c')
+ {
+ ret = GS_ALL_DONE;
+ break;
+ }
+ else
+ /* Fail if we don't know how to handle this tree code. */
+ abort ();
+
+ recalculate_side_effects (*expr_p);
+ break;
+ }
+
+ /* If we replaced *expr_p, gimplify again. */
+ if (ret == GS_OK && (*expr_p == NULL || *expr_p == save_expr))
+ ret = GS_ALL_DONE;
+ }
+ while (ret == GS_OK);
+
+ /* If we encountered an error_mark somewhere nested inside, either
+ stub out the statement or propagate the error back out. */
+ if (ret == GS_ERROR)
+ {
+ if (is_statement)
+ *expr_p = build_empty_stmt ();
+ goto out;
+ }
+
+#ifdef ENABLE_CHECKING
+ /* This was only valid as a return value from the langhook, which
+ we handled. Make sure it doesn't escape from any other context. */
+ if (ret == GS_UNHANDLED)
+ abort ();
+#endif
+
+ if (!*expr_p)
+ *expr_p = build_empty_stmt ();
+ if (fallback == fb_none && !is_gimple_stmt (*expr_p))
+ {
+ /* We aren't looking for a value, and we don't have a valid
+ statement. If it doesn't have side-effects, throw it away. */
+ if (!TREE_SIDE_EFFECTS (*expr_p))
+ *expr_p = build_empty_stmt ();
+ else if (!TREE_THIS_VOLATILE (*expr_p))
+ /* We only handle volatiles here; anything else with side-effects
+ must be converted to a valid statement before we get here. */
+ abort ();
+ else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p)))
+ {
+ /* Historically, the compiler has treated a bare
+ reference to a volatile lvalue as forcing a load. */
+ tree tmp = create_tmp_var (TREE_TYPE (*expr_p), "vol");
+ *expr_p = build (MODIFY_EXPR, TREE_TYPE (tmp), tmp, *expr_p);
+ }
+ else
+ /* We can't do anything useful with a volatile reference to
+ incomplete type, so just throw it away. */
+ *expr_p = build_empty_stmt ();
+ }
+
+ /* If we are gimplifying at the statement level, we're done. Tack
+ everything together and replace the original statement with the
+ gimplified form. */
+ if (is_statement)
+ {
+ append_to_statement_list (*expr_p, &internal_pre);
+ append_to_statement_list (internal_post, &internal_pre);
+ annotate_all_with_locus (&internal_pre, input_location);
+ *expr_p = internal_pre;
+ goto out;
+ }
+
+ /* Otherwise we're gimplifying a subexpression, so the resulting value is
+ interesting. */
+
+ /* If it's sufficiently simple already, we're done. Unless we are
+ handling some post-effects internally; if that's the case, we need to
+ copy into a temp before adding the post-effects to the tree. */
+ if (!internal_post && (*gimple_test_f) (*expr_p))
+ goto out;
+
+ /* Otherwise, we need to create a new temporary for the gimplified
+ expression. */
+
+ /* We can't return an lvalue if we have an internal postqueue. The
+ object the lvalue refers to would (probably) be modified by the
+ postqueue; we need to copy the value out first, which means an
+ rvalue. */
+ if ((fallback & fb_lvalue) && !internal_post
+ && is_gimple_addr_expr_arg (*expr_p))
+ {
+ /* An lvalue will do. Take the address of the expression, store it
+ in a temporary, and replace the expression with an INDIRECT_REF of
+ that temporary. */
+ tmp = build_addr_expr (*expr_p);
+ gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
+ *expr_p = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (tmp)), tmp);
+ }
+ else if ((fallback & fb_rvalue) && is_gimple_rhs (*expr_p))
+ {
+#if defined ENABLE_CHECKING
+ if (VOID_TYPE_P (TREE_TYPE (*expr_p)))
+ abort ();
+#endif
+
+ /* An rvalue will do. Assign the gimplified expression into a new
+ temporary TMP and replace the original expression with TMP. */
+
+ if (internal_post || (fallback & fb_lvalue))
+ /* The postqueue might change the value of the expression between
+ the initialization and use of the temporary, so we can't use a
+ formal temp. FIXME do we care? */
+ *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
+ else
+ *expr_p = get_formal_tmp_var (*expr_p, pre_p);
+ }
+ else if (fallback & fb_mayfail)
+ {
+ /* If this is an asm statement, and the user asked for the impossible,
+ don't abort. Fail and let gimplify_asm_expr issue an error. */
+ ret = GS_ERROR;
+ goto out;
+ }
+ else
+ {
+ fprintf (stderr, "gimplification failed:\n");
+ print_generic_expr (stderr, *expr_p, 0);
+ debug_tree (*expr_p);
+ abort ();
+ }
+
+#if defined ENABLE_CHECKING
+ /* Make sure the temporary matches our predicate. */
+ if (!(*gimple_test_f) (*expr_p))
+ abort ();
+#endif
+
+ if (internal_post)
+ {
+ annotate_all_with_locus (&internal_post, input_location);
+ append_to_statement_list (internal_post, pre_p);
+ }
+
+ out:
+ input_location = saved_location;
+ return ret;
+}
+
+#ifdef ENABLE_CHECKING
+/* Compare types A and B for a "close enough" match. */
+
+static bool
+cpt_same_type (tree a, tree b)
+{
+ if (lang_hooks.types_compatible_p (a, b))
+ return true;
+
+ /* ??? The C++ FE decomposes METHOD_TYPES to FUNCTION_TYPES and doesn't
+ link them together. This routine is intended to catch type errors
+ that will affect the optimizers, and the optimizers don't add new
+ dereferences of function pointers, so ignore it. */
+ if ((TREE_CODE (a) == FUNCTION_TYPE || TREE_CODE (a) == METHOD_TYPE)
+ && (TREE_CODE (b) == FUNCTION_TYPE || TREE_CODE (b) == METHOD_TYPE))
+ return true;
+
+ /* ??? The C FE pushes type qualifiers after the fact into the type of
+ the element from the type of the array. See build_unary_op's handling
+ of ADDR_EXPR. This seems wrong -- if we were going to do this, we
+ should have done it when creating the variable in the first place.
+ Alternately, why aren't the two array types made variants? */
+ if (TREE_CODE (a) == ARRAY_TYPE && TREE_CODE (b) == ARRAY_TYPE)
+ return cpt_same_type (TREE_TYPE (a), TREE_TYPE (b));
+
+ /* And because of those, we have to recurse down through pointers. */
+ if (POINTER_TYPE_P (a) && POINTER_TYPE_P (b))
+ return cpt_same_type (TREE_TYPE (a), TREE_TYPE (b));
+
+ return false;
+}
+
+/* Check for some cases of the front end missing cast expressions.
+ The type of a dereference should correspond to the pointer type;
+ similarly the type of an address should match its object. */
+
+static tree
+check_pointer_types_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
+{
+ tree t = *tp;
+ tree ptype, otype, dtype;
+
+ switch (TREE_CODE (t))
+ {
+ case INDIRECT_REF:
+ case ARRAY_REF:
+ otype = TREE_TYPE (t);
+ ptype = TREE_TYPE (TREE_OPERAND (t, 0));
+ dtype = TREE_TYPE (ptype);
+ if (!cpt_same_type (otype, dtype))
+ abort ();
+ break;
+
+ case ADDR_EXPR:
+ ptype = TREE_TYPE (t);
+ otype = TREE_TYPE (TREE_OPERAND (t, 0));
+ dtype = TREE_TYPE (ptype);
+ if (!cpt_same_type (otype, dtype))
+ {
+ /* &array is allowed to produce a pointer to the element,
+ rather than a pointer to the array type. */
+ if (TREE_CODE (otype) == ARRAY_TYPE
+ && POINTER_TYPE_P (ptype)
+ && cpt_same_type (TREE_TYPE (otype), dtype))
+ break;
+ abort ();
+ }
+ break;
+
+ default:
+ return NULL_TREE;
+ }
+
+
+ return NULL_TREE;
+}
+#endif
+
+/* Gimplify the body of statements pointed by BODY_P. FNDECL is the
+ function decl containing BODY. */
+
+void
+gimplify_body (tree *body_p, tree fndecl)
+{
+ location_t saved_location = input_location;
+ tree body;
+
+ timevar_push (TV_TREE_GIMPLIFY);
+ push_gimplify_context ();
+
+ /* Unshare most shared trees in the body. */
+ unshare_all_trees (*body_p);
+
+ /* Make sure input_location isn't set to something wierd. */
+ input_location = DECL_SOURCE_LOCATION (fndecl);
+
+ /* Gimplify the function's body. */
+ gimplify_stmt (body_p);
+ body = *body_p;
+
+ /* Unshare again, in case gimplification was sloppy. */
+ unshare_all_trees (body);
+
+ /* If there isn't an outer BIND_EXPR, add one. */
+ if (TREE_CODE (body) == STATEMENT_LIST)
+ {
+ tree t = expr_only (*body_p);
+ if (t)
+ body = t;
+ }
+ if (TREE_CODE (body) != BIND_EXPR)
+ {
+ tree b = build (BIND_EXPR, void_type_node, NULL_TREE,
+ NULL_TREE, NULL_TREE);
+ TREE_SIDE_EFFECTS (b) = 1;
+ append_to_statement_list (body, &BIND_EXPR_BODY (b));
+ body = b;
+ }
+ *body_p = body;
+
+ pop_gimplify_context (body);
+
+#ifdef ENABLE_CHECKING
+ walk_tree (body_p, check_pointer_types_r, NULL, NULL);
+#endif
+
+ timevar_pop (TV_TREE_GIMPLIFY);
+ input_location = saved_location;
+}
+
+/* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
+ node for the function we want to gimplify. */
+
+void
+gimplify_function_tree (tree fndecl)
+{
+ tree oldfn;
+
+ oldfn = current_function_decl;
+ current_function_decl = fndecl;
+
+ gimplify_body (&DECL_SAVED_TREE (fndecl), fndecl);
+
+ /* If we're instrumenting function entry/exit, then prepend the call to
+ the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
+ catch the exit hook. */
+ /* ??? Add some way to ignore exceptions for this TFE. */
+ if (flag_instrument_function_entry_exit
+ && ! DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl))
+ {
+ tree tf, x, bind;
+
+ tf = build (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
+ TREE_SIDE_EFFECTS (tf) = 1;
+ x = DECL_SAVED_TREE (fndecl);
+ append_to_statement_list (x, &TREE_OPERAND (tf, 0));
+ x = implicit_built_in_decls[BUILT_IN_PROFILE_FUNC_EXIT];
+ x = build_function_call_expr (x, NULL);
+ append_to_statement_list (x, &TREE_OPERAND (tf, 1));
+
+ bind = build (BIND_EXPR, void_type_node, NULL, NULL, NULL);
+ TREE_SIDE_EFFECTS (bind) = 1;
+ x = implicit_built_in_decls[BUILT_IN_PROFILE_FUNC_ENTER];
+ x = build_function_call_expr (x, NULL);
+ append_to_statement_list (x, &BIND_EXPR_BODY (bind));
+ append_to_statement_list (tf, &BIND_EXPR_BODY (bind));
+
+ DECL_SAVED_TREE (fndecl) = bind;
+ }
+
+ current_function_decl = oldfn;
+}
+
+#include "gt-gimplify.h"
diff --git a/gcc/gthr-win32.h b/gcc/gthr-win32.h
index 93f157481a3..e399047e485 100644
--- a/gcc/gthr-win32.h
+++ b/gcc/gthr-win32.h
@@ -1,6 +1,6 @@
/* Threads compatibility routines for libgcc2 and libobjc. */
/* Compile this one with gcc. */
-/* Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Mumit Khan <khan@xraylith.wisc.edu>.
This file is part of GCC.
@@ -54,10 +54,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
This may cause incorrect error return due to truncation values on
hw where sizeof (DWORD) > sizeof (int).
- 3. We might consider using Critical Sections instead of Windows32
- mutexes for better performance, but emulating __gthread_mutex_trylock
- interface becomes more complicated (Win9x does not support
- TryEnterCriticalSectioni, while NT does).
+ 3. We are currently using a special mutex instead of the Critical
+ Sections, since Win9x does not support TryEnterCriticalSection
+ (while NT does).
The basic framework should work well enough. In the long term, GCC
needs to use Structured Exception Handling on Windows32. */
@@ -339,11 +338,14 @@ typedef struct {
long started;
} __gthread_once_t;
-typedef void* __gthread_mutex_t;
+typedef struct {
+ long counter;
+ void *sema;
+} __gthread_mutex_t;
#define __GTHREAD_ONCE_INIT {0, -1}
#define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
-#define __GTHREAD_MUTEX_INIT_DEFAULT 0
+#define __GTHREAD_MUTEX_INIT_DEFAULT {0, 0}
#if __MINGW32_MAJOR_VERSION >= 1 || \
(__MINGW32_MAJOR_VERSION == 0 && __MINGW32_MINOR_VERSION > 2)
@@ -534,8 +536,8 @@ __gthread_setspecific (__gthread_key_t key, const void *ptr)
static inline void
__gthread_mutex_init_function (__gthread_mutex_t *mutex)
{
- /* Create unnamed mutex with default security attr and no initial owner. */
- *mutex = CreateMutex (NULL, 0, NULL);
+ mutex->counter = 0;
+ mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL);
}
static inline int
@@ -545,10 +547,16 @@ __gthread_mutex_lock (__gthread_mutex_t *mutex)
if (__gthread_active_p ())
{
- if (WaitForSingleObject (*mutex, INFINITE) == WAIT_OBJECT_0)
+ if (InterlockedIncrement (&mutex->counter) == 1 ||
+ WaitForSingleObject (mutex->sema, INFINITE) == WAIT_OBJECT_0)
status = 0;
else
- status = 1;
+ {
+ // WaitForSingleObject returns WAIT_FAILED, and we can only do
+ // some best-effort cleanup here.
+ InterlockedDecrement (&mutex->counter);
+ status = 1;
+ }
}
return status;
}
@@ -560,7 +568,7 @@ __gthread_mutex_trylock (__gthread_mutex_t *mutex)
if (__gthread_active_p ())
{
- if (WaitForSingleObject (*mutex, 0) == WAIT_OBJECT_0)
+ if (InterlockedCompareExchange (&mutex->counter, 1, 0 ) == 0)
status = 0;
else
status = 1;
@@ -572,9 +580,11 @@ static inline int
__gthread_mutex_unlock (__gthread_mutex_t *mutex)
{
if (__gthread_active_p ())
- return (ReleaseMutex (*mutex) != 0) ? 0 : 1;
- else
- return 0;
+ {
+ if (InterlockedDecrement (&mutex->counter))
+ return ReleaseSemaphore (mutex->sema, 1, NULL) ? 0 : 1;
+ }
+ return 0;
}
#endif /* __GTHREAD_HIDE_WIN32API */
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index a87d7ad2097..6a212f1ccc2 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -950,9 +950,6 @@ priority (rtx insn)
rtx next;
int next_priority;
- if (RTX_INTEGRATED_P (link))
- continue;
-
next = XEXP (link, 0);
/* Critical path is meaningful in block boundaries only. */
@@ -1581,7 +1578,6 @@ restore_line_notes (rtx head, rtx tail)
added_notes++;
new = emit_note_after (NOTE_LINE_NUMBER (note), prev);
NOTE_SOURCE_FILE (new) = NOTE_SOURCE_FILE (note);
- RTX_INTEGRATED_P (new) = RTX_INTEGRATED_P (note);
}
}
if (sched_verbose && added_notes)
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index f0802372f7b..a6066da2151 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -3023,7 +3023,7 @@ static int
dead_or_predicable (basic_block test_bb, basic_block merge_bb,
basic_block other_bb, basic_block new_dest, int reversep)
{
- rtx head, end, jump, earliest, old_dest, new_label = NULL_RTX;
+ rtx head, end, jump, earliest = NULL_RTX, old_dest, new_label = NULL_RTX;
jump = BB_END (test_bb);
@@ -3291,10 +3291,6 @@ if_convert (int x_life_data_ok)
&& (!flag_reorder_blocks_and_partition || !no_new_pseudos))
mark_loop_exit_edges ();
- /* Free up basic_block_for_insn so that we don't have to keep it
- up to date, either here or in merge_blocks. */
- free_basic_block_vars (1);
-
/* Compute postdominators if we think we'll use them. */
if (HAVE_conditional_execution || life_data_ok)
calculate_dominance_info (CDI_POST_DOMINATORS);
diff --git a/gcc/input.h b/gcc/input.h
index 45fee91d040..6e11023a900 100644
--- a/gcc/input.h
+++ b/gcc/input.h
@@ -53,9 +53,6 @@ extern location_t input_location;
The line member is not accurate for the innermost file on the stack. */
extern struct file_stack *input_file_stack;
-/* Stack of EXPR_WITH_FILE_LOCATION nested expressions. */
-extern struct file_stack *expr_wfl_stack;
-
/* Incremented on each change to input_file_stack. */
extern int input_file_stack_tick;
diff --git a/gcc/integrate.c b/gcc/integrate.c
index 567cd9317ca..de897176ea0 100644
--- a/gcc/integrate.c
+++ b/gcc/integrate.c
@@ -41,26 +41,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "function.h"
#include "toplev.h"
#include "intl.h"
-#include "loop.h"
#include "params.h"
#include "ggc.h"
#include "target.h"
#include "langhooks.h"
-/* Similar, but round to the next highest integer that meets the
- alignment. */
+/* Round to the next highest integer that meets the alignment. */
#define CEIL_ROUND(VALUE,ALIGN) (((VALUE) + (ALIGN) - 1) & ~((ALIGN)- 1))
-
-/* Default max number of insns a function can have and still be inline.
- This is overridden on RISC machines. */
-#ifndef INTEGRATE_THRESHOLD
-/* Inlining small functions might save more space then not inlining at
- all. Assume 1 instruction for the call and 1.5 insns per argument. */
-#define INTEGRATE_THRESHOLD(DECL) \
- (optimize_size \
- ? (1 + (3 * list_length (DECL_ARGUMENTS (DECL))) / 2) \
- : (8 * (8 + list_length (DECL_ARGUMENTS (DECL)))))
-#endif
/* Private type used by {get/has}_func_hard_reg_initial_val. */
@@ -74,29 +61,10 @@ typedef struct initial_value_struct GTY(()) {
initial_value_pair * GTY ((length ("%h.num_entries"))) entries;
} initial_value_struct;
-static void setup_initial_hard_reg_value_integration (struct function *,
- struct inline_remap *);
-
-static rtvec initialize_for_inline (tree);
-static void note_modified_parmregs (rtx, rtx, void *);
-static void integrate_parm_decls (tree, struct inline_remap *, rtvec);
-static tree integrate_decl_tree (tree, struct inline_remap *);
static void subst_constants (rtx *, rtx, struct inline_remap *, int);
static void set_block_origin_self (tree);
static void set_block_abstract_flags (tree, int);
-static void process_reg_param (struct inline_remap *, rtx, rtx);
static void mark_stores (rtx, rtx, void *);
-static void save_parm_insns (rtx, rtx);
-static void copy_insn_list (rtx, struct inline_remap *, rtx);
-static void copy_insn_notes (rtx, struct inline_remap *, int);
-static int compare_blocks (const void *, const void *);
-static int find_block (const void *, const void *);
-
-/* Used by copy_rtx_and_substitute; this indicates whether the function is
- called for the purpose of inlining or some other purpose (i.e. loop
- unrolling). This affects how constant pool references are handled.
- This variable contains the FUNCTION_DECL for the inlined function. */
-static struct function *inlining = 0;
/* Returns the Ith entry in the label_map contained in MAP. If the
Ith entry has not yet been set, return a fresh label. This function
@@ -136,195 +104,7 @@ function_attribute_inlinable_p (tree fndecl)
return true;
}
-
-/* Zero if the current function (whose FUNCTION_DECL is FNDECL)
- is safe and reasonable to integrate into other functions.
- Nonzero means value is a warning msgid with a single %s
- for the function's name. */
-
-const char *
-function_cannot_inline_p (tree fndecl)
-{
- rtx insn;
- tree last = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
-
- /* For functions marked as inline increase the maximum size to
- MAX_INLINE_INSNS_RTL (--param max-inline-insn-rtl=<n>). For
- regular functions use the limit given by INTEGRATE_THRESHOLD.
- Note that the RTL inliner is not used by the languages that use
- the tree inliner (C, C++). */
-
- int max_insns = (DECL_INLINE (fndecl))
- ? (MAX_INLINE_INSNS_RTL
- + 8 * list_length (DECL_ARGUMENTS (fndecl)))
- : INTEGRATE_THRESHOLD (fndecl);
-
- int ninsns = 0;
- tree parms;
-
- if (DECL_UNINLINABLE (fndecl))
- return N_("function cannot be inline");
-
- /* No inlines with varargs. */
- if (last && TREE_VALUE (last) != void_type_node)
- return N_("varargs function cannot be inline");
-
- if (current_function_calls_alloca)
- return N_("function using alloca cannot be inline");
-
- if (current_function_calls_longjmp)
- return N_("function using longjmp cannot be inline");
-
- if (current_function_calls_setjmp)
- return N_("function using setjmp cannot be inline");
-
- if (current_function_calls_eh_return)
- return N_("function uses __builtin_eh_return");
-
- if (current_function_contains_functions)
- return N_("function with nested functions cannot be inline");
-
- if (forced_labels)
- return
- N_("function with label addresses used in initializers cannot inline");
-
- if (current_function_cannot_inline)
- return current_function_cannot_inline;
-
- /* If it's not even close, don't even look. */
- if (get_max_uid () > 3 * max_insns)
- return N_("function too large to be inline");
-
-#if 0
- /* Don't inline functions which do not specify a function prototype and
- have BLKmode argument or take the address of a parameter. */
- for (parms = DECL_ARGUMENTS (fndecl); parms; parms = TREE_CHAIN (parms))
- {
- if (TYPE_MODE (TREE_TYPE (parms)) == BLKmode)
- TREE_ADDRESSABLE (parms) = 1;
- if (last == NULL_TREE && TREE_ADDRESSABLE (parms))
- return N_("no prototype, and parameter address used; cannot be inline");
- }
-#endif
-
- /* We can't inline functions that return structures
- the old-fashioned PCC way, copying into a static block. */
- if (current_function_returns_pcc_struct)
- return N_("inline functions not supported for this return value type");
-
- /* We can't inline functions that return structures of varying size. */
- if (TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE
- && int_size_in_bytes (TREE_TYPE (TREE_TYPE (fndecl))) < 0)
- return N_("function with varying-size return value cannot be inline");
-
- /* Cannot inline a function with a varying size argument or one that
- receives a transparent union. */
- for (parms = DECL_ARGUMENTS (fndecl); parms; parms = TREE_CHAIN (parms))
- {
- if (int_size_in_bytes (TREE_TYPE (parms)) < 0)
- return N_("function with varying-size parameter cannot be inline");
- else if (TREE_CODE (TREE_TYPE (parms)) == UNION_TYPE
- && TYPE_TRANSPARENT_UNION (TREE_TYPE (parms)))
- return N_("function with transparent unit parameter cannot be inline");
- }
-
- if (get_max_uid () > max_insns)
- {
- for (ninsns = 0, insn = get_first_nonparm_insn ();
- insn && ninsns < max_insns;
- insn = NEXT_INSN (insn))
- if (INSN_P (insn))
- ninsns++;
-
- if (ninsns >= max_insns)
- return N_("function too large to be inline");
- }
-
- /* We will not inline a function which uses computed goto. The addresses of
- its local labels, which may be tucked into global storage, are of course
- not constant across instantiations, which causes unexpected behavior. */
- if (current_function_has_computed_jump)
- return N_("function with computed jump cannot inline");
-
- /* We cannot inline a nested function that jumps to a nonlocal label. */
- if (current_function_has_nonlocal_goto)
- return N_("function with nonlocal goto cannot be inline");
-
- /* We can't inline functions that return a PARALLEL rtx. */
- if (DECL_RTL_SET_P (DECL_RESULT (fndecl)))
- {
- rtx result = DECL_RTL (DECL_RESULT (fndecl));
- if (GET_CODE (result) == PARALLEL)
- return N_("inline functions not supported for this return value type");
- }
-
- /* If the function has a target specific attribute attached to it,
- then we assume that we should not inline it. This can be overridden
- by the target if it defines TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P. */
- if (!function_attribute_inlinable_p (fndecl))
- return N_("function with target specific attribute(s) cannot be inlined");
-
- return NULL;
-}
-/* Map pseudo reg number into the PARM_DECL for the parm living in the reg.
- Zero for a reg that isn't a parm's home.
- Only reg numbers less than max_parm_reg are mapped here. */
-static tree *parmdecl_map;
-
-/* In save_for_inline, nonzero if past the parm-initialization insns. */
-static int in_nonparm_insns;
-
-/* Subroutine for `save_for_inline'. Performs initialization
- needed to save FNDECL's insns and info for future inline expansion. */
-
-static rtvec
-initialize_for_inline (tree fndecl)
-{
- int i;
- rtvec arg_vector;
- tree parms;
-
- /* Clear out PARMDECL_MAP. It was allocated in the caller's frame. */
- memset (parmdecl_map, 0, max_parm_reg * sizeof (tree));
- arg_vector = rtvec_alloc (list_length (DECL_ARGUMENTS (fndecl)));
-
- for (parms = DECL_ARGUMENTS (fndecl), i = 0;
- parms;
- parms = TREE_CHAIN (parms), i++)
- {
- rtx p = DECL_RTL (parms);
-
- /* If we have (mem (addressof (mem ...))), use the inner MEM since
- otherwise the copy_rtx call below will not unshare the MEM since
- it shares ADDRESSOF. */
- if (GET_CODE (p) == MEM && GET_CODE (XEXP (p, 0)) == ADDRESSOF
- && GET_CODE (XEXP (XEXP (p, 0), 0)) == MEM)
- p = XEXP (XEXP (p, 0), 0);
-
- RTVEC_ELT (arg_vector, i) = p;
-
- if (GET_CODE (p) == REG)
- parmdecl_map[REGNO (p)] = parms;
- else if (GET_CODE (p) == CONCAT)
- {
- rtx preal = gen_realpart (GET_MODE (XEXP (p, 0)), p);
- rtx pimag = gen_imagpart (GET_MODE (preal), p);
-
- if (GET_CODE (preal) == REG)
- parmdecl_map[REGNO (preal)] = parms;
- if (GET_CODE (pimag) == REG)
- parmdecl_map[REGNO (pimag)] = parms;
- }
-
- /* This flag is cleared later
- if the function ever modifies the value of the parm. */
- TREE_READONLY (parms) = 1;
- }
-
- return arg_vector;
-}
-
/* Copy NODE (which must be a DECL, but not a PARM_DECL). The DECL
originally was in the FROM_FN, but now it will be in the
TO_FN. */
@@ -379,7 +159,10 @@ copy_decl_for_inlining (tree decl, tree from_fn, tree to_fn)
address has been taken; it's for internal bookkeeping in
expand_goto_internal. */
if (TREE_CODE (copy) == LABEL_DECL)
- TREE_ADDRESSABLE (copy) = 0;
+ {
+ TREE_ADDRESSABLE (copy) = 0;
+ DECL_TOO_LATE (copy) = 0;
+ }
}
/* Set the DECL_ABSTRACT_ORIGIN so the debugging routines know what
@@ -412,1439 +195,13 @@ copy_decl_for_inlining (tree decl, tree from_fn, tree to_fn)
return copy;
}
-
-/* Make the insns and PARM_DECLs of the current function permanent
- and record other information in DECL_STRUCT_FUNCTION to allow
- inlining of this function in subsequent calls.
-
- This routine need not copy any insns because we are not going
- to immediately compile the insns in the insn chain. There
- are two cases when we would compile the insns for FNDECL:
- (1) when FNDECL is expanded inline, and (2) when FNDECL needs to
- be output at the end of other compilation, because somebody took
- its address. In the first case, the insns of FNDECL are copied
- as it is expanded inline, so FNDECL's saved insns are not
- modified. In the second case, FNDECL is used for the last time,
- so modifying the rtl is not a problem.
-
- We don't have to worry about FNDECL being inline expanded by
- other functions which are written at the end of compilation
- because flag_no_inline is turned on when we begin writing
- functions at the end of compilation. */
-
-void
-save_for_inline (tree fndecl)
-{
- rtx insn;
- rtvec argvec;
- rtx first_nonparm_insn;
-
- /* Set up PARMDECL_MAP which maps pseudo-reg number to its PARM_DECL.
- Later we set TREE_READONLY to 0 if the parm is modified inside the fn.
- Also set up ARG_VECTOR, which holds the unmodified DECL_RTX values
- for the parms, prior to elimination of virtual registers.
- These values are needed for substituting parms properly. */
- if (! flag_no_inline)
- parmdecl_map = xmalloc (max_parm_reg * sizeof (tree));
-
- /* Make and emit a return-label if we have not already done so. */
-
- if (return_label == 0)
- {
- return_label = gen_label_rtx ();
- emit_label (return_label);
- }
-
- if (! flag_no_inline)
- argvec = initialize_for_inline (fndecl);
- else
- argvec = NULL;
-
- /* Delete basic block notes created by early run of find_basic_block.
- The notes would be later used by find_basic_blocks to reuse the memory
- for basic_block structures on already freed obstack. */
- for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
- if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BASIC_BLOCK)
- delete_related_insns (insn);
-
- /* If there are insns that copy parms from the stack into pseudo registers,
- those insns are not copied. `expand_inline_function' must
- emit the correct code to handle such things. */
-
- insn = get_insns ();
- if (GET_CODE (insn) != NOTE)
- abort ();
-
- if (! flag_no_inline)
- {
- /* Get the insn which signals the end of parameter setup code. */
- first_nonparm_insn = get_first_nonparm_insn ();
-
- /* Now just scan the chain of insns to see what happens to our
- PARM_DECLs. If a PARM_DECL is used but never modified, we
- can substitute its rtl directly when expanding inline (and
- perform constant folding when its incoming value is
- constant). Otherwise, we have to copy its value into a new
- register and track the new register's life. */
- in_nonparm_insns = 0;
- save_parm_insns (insn, first_nonparm_insn);
-
- cfun->inl_max_label_num = max_label_num ();
- cfun->inl_last_parm_insn = cfun->x_last_parm_insn;
- cfun->original_arg_vector = argvec;
- }
- cfun->original_decl_initial = DECL_INITIAL (fndecl);
- cfun->no_debugging_symbols = (write_symbols == NO_DEBUG);
- cfun->saved_for_inline = 1;
-
- /* Clean up. */
- if (! flag_no_inline)
- free (parmdecl_map);
-}
-
-/* Scan the chain of insns to see what happens to our PARM_DECLs. If a
- PARM_DECL is used but never modified, we can substitute its rtl directly
- when expanding inline (and perform constant folding when its incoming
- value is constant). Otherwise, we have to copy its value into a new
- register and track the new register's life. */
-
-static void
-save_parm_insns (rtx insn, rtx first_nonparm_insn)
-{
- if (insn == NULL_RTX)
- return;
-
- for (insn = NEXT_INSN (insn); insn; insn = NEXT_INSN (insn))
- {
- if (insn == first_nonparm_insn)
- in_nonparm_insns = 1;
-
- if (INSN_P (insn))
- {
- /* Record what interesting things happen to our parameters. */
- note_stores (PATTERN (insn), note_modified_parmregs, NULL);
-
- /* If this is a CALL_PLACEHOLDER insn then we need to look into the
- three attached sequences: normal call, sibling call and tail
- recursion. */
- if (GET_CODE (insn) == CALL_INSN
- && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
- {
- int i;
-
- for (i = 0; i < 3; i++)
- save_parm_insns (XEXP (PATTERN (insn), i),
- first_nonparm_insn);
- }
- }
- }
-}
-/* Note whether a parameter is modified or not. */
-
-static void
-note_modified_parmregs (rtx reg, rtx x ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED)
-{
- if (GET_CODE (reg) == REG && in_nonparm_insns
- && REGNO (reg) < max_parm_reg
- && REGNO (reg) >= FIRST_PSEUDO_REGISTER
- && parmdecl_map[REGNO (reg)] != 0)
- TREE_READONLY (parmdecl_map[REGNO (reg)]) = 0;
-}
-
/* Unfortunately, we need a global copy of const_equiv map for communication
with a function called from note_stores. Be *very* careful that this
is used properly in the presence of recursion. */
varray_type global_const_equiv_varray;
-
-#define FIXED_BASE_PLUS_P(X) \
- (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
- && GET_CODE (XEXP (X, 0)) == REG \
- && REGNO (XEXP (X, 0)) >= FIRST_VIRTUAL_REGISTER \
- && REGNO (XEXP (X, 0)) <= LAST_VIRTUAL_REGISTER)
-
-/* Called to set up a mapping for the case where a parameter is in a
- register. If it is read-only and our argument is a constant, set up the
- constant equivalence.
-
- If LOC is REG_USERVAR_P, the usual case, COPY must also have that flag set
- if it is a register.
-
- Also, don't allow hard registers here; they might not be valid when
- substituted into insns. */
-static void
-process_reg_param (struct inline_remap *map, rtx loc, rtx copy)
-{
- if ((GET_CODE (copy) != REG && GET_CODE (copy) != SUBREG)
- || (GET_CODE (copy) == REG && REG_USERVAR_P (loc)
- && ! REG_USERVAR_P (copy))
- || (GET_CODE (copy) == REG
- && REGNO (copy) < FIRST_PSEUDO_REGISTER))
- {
- rtx temp = copy_to_mode_reg (GET_MODE (loc), copy);
- REG_USERVAR_P (temp) = REG_USERVAR_P (loc);
- if (CONSTANT_P (copy) || FIXED_BASE_PLUS_P (copy))
- SET_CONST_EQUIV_DATA (map, temp, copy, CONST_AGE_PARM);
- copy = temp;
- }
- map->reg_map[REGNO (loc)] = copy;
-}
-
-/* Compare two BLOCKs for qsort. The key we sort on is the
- BLOCK_ABSTRACT_ORIGIN of the blocks. We cannot just subtract the
- two pointers, because it may overflow sizeof(int). */
-
-static int
-compare_blocks (const void *v1, const void *v2)
-{
- tree b1 = *((const tree *) v1);
- tree b2 = *((const tree *) v2);
- char *p1 = (char *) BLOCK_ABSTRACT_ORIGIN (b1);
- char *p2 = (char *) BLOCK_ABSTRACT_ORIGIN (b2);
-
- if (p1 == p2)
- return 0;
- return p1 < p2 ? -1 : 1;
-}
-
-/* Compare two BLOCKs for bsearch. The first pointer corresponds to
- an original block; the second to a remapped equivalent. */
-
-static int
-find_block (const void *v1, const void *v2)
-{
- const union tree_node *b1 = (const union tree_node *) v1;
- tree b2 = *((const tree *) v2);
- char *p1 = (char *) b1;
- char *p2 = (char *) BLOCK_ABSTRACT_ORIGIN (b2);
-
- if (p1 == p2)
- return 0;
- return p1 < p2 ? -1 : 1;
-}
-
-/* Integrate the procedure defined by FNDECL. Note that this function
- may wind up calling itself. Since the static variables are not
- reentrant, we do not assign them until after the possibility
- of recursion is eliminated.
-
- If IGNORE is nonzero, do not produce a value.
- Otherwise store the value in TARGET if it is nonzero and that is convenient.
-
- Value is:
- (rtx)-1 if we could not substitute the function
- 0 if we substituted it and it does not produce a value
- else an rtx for where the value is stored. */
-
-rtx
-expand_inline_function (tree fndecl, tree parms, rtx target, int ignore,
- tree type, rtx structure_value_addr)
-{
- struct function *inlining_previous;
- struct function *inl_f = DECL_STRUCT_FUNCTION (fndecl);
- tree formal, actual, block;
- rtx parm_insns = inl_f->emit->x_first_insn;
- rtx insns = (inl_f->inl_last_parm_insn
- ? NEXT_INSN (inl_f->inl_last_parm_insn)
- : parm_insns);
- tree *arg_trees;
- rtx *arg_vals;
- int max_regno;
- int i;
- int min_labelno = inl_f->emit->x_first_label_num;
- int max_labelno = inl_f->inl_max_label_num;
- int nargs;
- rtx loc;
- rtx stack_save = 0;
- rtx temp;
- struct inline_remap *map = 0;
- rtvec arg_vector = inl_f->original_arg_vector;
- rtx static_chain_value = 0;
- int inl_max_uid;
- int eh_region_offset;
-
- /* The pointer used to track the true location of the memory used
- for MAP->LABEL_MAP. */
- rtx *real_label_map = 0;
-
- /* Allow for equivalences of the pseudos we make for virtual fp and ap. */
- max_regno = inl_f->emit->x_reg_rtx_no + 3;
- if (max_regno < FIRST_PSEUDO_REGISTER)
- abort ();
-
- /* Pull out the decl for the function definition; fndecl may be a
- local declaration, which would break DECL_ABSTRACT_ORIGIN. */
- fndecl = inl_f->decl;
-
- nargs = list_length (DECL_ARGUMENTS (fndecl));
-
- if (cfun->preferred_stack_boundary < inl_f->preferred_stack_boundary)
- cfun->preferred_stack_boundary = inl_f->preferred_stack_boundary;
-
- /* Check that the parms type match and that sufficient arguments were
- passed. Since the appropriate conversions or default promotions have
- already been applied, the machine modes should match exactly. */
-
- for (formal = DECL_ARGUMENTS (fndecl), actual = parms;
- formal;
- formal = TREE_CHAIN (formal), actual = TREE_CHAIN (actual))
- {
- tree arg;
- enum machine_mode mode;
-
- if (actual == 0)
- return (rtx) (size_t) -1;
-
- arg = TREE_VALUE (actual);
- mode = TYPE_MODE (DECL_ARG_TYPE (formal));
-
- if (arg == error_mark_node
- || mode != TYPE_MODE (TREE_TYPE (arg))
- /* If they are block mode, the types should match exactly.
- They don't match exactly if TREE_TYPE (FORMAL) == ERROR_MARK_NODE,
- which could happen if the parameter has incomplete type. */
- || (mode == BLKmode
- && (TYPE_MAIN_VARIANT (TREE_TYPE (arg))
- != TYPE_MAIN_VARIANT (TREE_TYPE (formal)))))
- return (rtx) (size_t) -1;
- }
-
- /* If there is a TARGET which is a readonly BLKmode MEM and DECL_RESULT
- is also a mem, we are going to lose the readonly on the stores, so don't
- inline. */
- if (target != 0 && GET_CODE (target) == MEM && GET_MODE (target) == BLKmode
- && RTX_UNCHANGING_P (target) && DECL_RTL_SET_P (DECL_RESULT (fndecl))
- && GET_CODE (DECL_RTL (DECL_RESULT (fndecl))) == MEM)
- return (rtx) (size_t) -1;
-
- /* Extra arguments are valid, but will be ignored below, so we must
- evaluate them here for side-effects. */
- for (; actual; actual = TREE_CHAIN (actual))
- expand_expr (TREE_VALUE (actual), const0_rtx,
- TYPE_MODE (TREE_TYPE (TREE_VALUE (actual))), 0);
-
- /* Expand the function arguments. Do this first so that any
- new registers get created before we allocate the maps. */
-
- arg_vals = xmalloc (nargs * sizeof (rtx));
- arg_trees = xmalloc (nargs * sizeof (tree));
-
- for (formal = DECL_ARGUMENTS (fndecl), actual = parms, i = 0;
- formal;
- formal = TREE_CHAIN (formal), actual = TREE_CHAIN (actual), i++)
- {
- /* Actual parameter, converted to the type of the argument within the
- function. */
- tree arg = convert (TREE_TYPE (formal), TREE_VALUE (actual));
- /* Mode of the variable used within the function. */
- enum machine_mode mode = TYPE_MODE (TREE_TYPE (formal));
- int invisiref = 0;
-
- arg_trees[i] = arg;
- loc = RTVEC_ELT (arg_vector, i);
-
- /* If this is an object passed by invisible reference, we copy the
- object into a stack slot and save its address. If this will go
- into memory, we do nothing now. Otherwise, we just expand the
- argument. */
- if (GET_CODE (loc) == MEM && GET_CODE (XEXP (loc, 0)) == REG
- && REGNO (XEXP (loc, 0)) > LAST_VIRTUAL_REGISTER)
- {
- rtx stack_slot = assign_temp (TREE_TYPE (arg), 1, 1, 1);
-
- store_expr (arg, stack_slot, 0);
- arg_vals[i] = XEXP (stack_slot, 0);
- invisiref = 1;
- }
- else if (GET_CODE (loc) != MEM)
- {
- if (GET_MODE (loc) != TYPE_MODE (TREE_TYPE (arg)))
- {
- int unsignedp = TYPE_UNSIGNED (TREE_TYPE (formal));
- enum machine_mode pmode = TYPE_MODE (TREE_TYPE (formal));
-
- pmode = promote_mode (TREE_TYPE (formal), pmode,
- &unsignedp, 0);
-
- if (GET_MODE (loc) != pmode)
- abort ();
-
- /* The mode if LOC and ARG can differ if LOC was a variable
- that had its mode promoted. */
- arg_vals[i] = convert_modes (pmode,
- TYPE_MODE (TREE_TYPE (arg)),
- expand_expr (arg, NULL_RTX, mode,
- EXPAND_SUM),
- unsignedp);
- }
- else
- arg_vals[i] = expand_expr (arg, NULL_RTX, mode, EXPAND_SUM);
- }
- else
- arg_vals[i] = 0;
-
- /* If the formal type was const but the actual was not, we might
- end up here with an rtx wrongly tagged unchanging in the caller's
- context. Fix that. */
- if (arg_vals[i] != 0
- && (GET_CODE (arg_vals[i]) == REG || GET_CODE (arg_vals[i]) == MEM)
- && ! TREE_READONLY (TREE_VALUE (actual)))
- RTX_UNCHANGING_P (arg_vals[i]) = 0;
-
- if (arg_vals[i] != 0
- && (! TREE_READONLY (formal)
- /* If the parameter is not read-only, copy our argument through
- a register. Also, we cannot use ARG_VALS[I] if it overlaps
- TARGET in any way. In the inline function, they will likely
- be two different pseudos, and `safe_from_p' will make all
- sorts of smart assumptions about their not conflicting.
- But if ARG_VALS[I] overlaps TARGET, these assumptions are
- wrong, so put ARG_VALS[I] into a fresh register.
- Don't worry about invisible references, since their stack
- temps will never overlap the target. */
- || (target != 0
- && ! invisiref
- && (GET_CODE (arg_vals[i]) == REG
- || GET_CODE (arg_vals[i]) == SUBREG
- || GET_CODE (arg_vals[i]) == MEM)
- && reg_overlap_mentioned_p (arg_vals[i], target))
- /* ??? We must always copy a SUBREG into a REG, because it might
- get substituted into an address, and not all ports correctly
- handle SUBREGs in addresses. */
- || (GET_CODE (arg_vals[i]) == SUBREG)))
- arg_vals[i] = copy_to_mode_reg (GET_MODE (loc), arg_vals[i]);
-
- if (arg_vals[i] != 0 && GET_CODE (arg_vals[i]) == REG
- && POINTER_TYPE_P (TREE_TYPE (formal)))
- mark_reg_pointer (arg_vals[i],
- TYPE_ALIGN (TREE_TYPE (TREE_TYPE (formal))));
- }
-
- /* Allocate the structures we use to remap things. */
-
- map = xcalloc (1, sizeof (struct inline_remap));
- map->fndecl = fndecl;
-
- VARRAY_TREE_INIT (map->block_map, 10, "block_map");
- map->reg_map = xcalloc (max_regno, sizeof (rtx));
-
- /* We used to use alloca here, but the size of what it would try to
- allocate would occasionally cause it to exceed the stack limit and
- cause unpredictable core dumps. */
- real_label_map = xmalloc ((max_labelno) * sizeof (rtx));
- map->label_map = real_label_map;
- map->local_return_label = NULL_RTX;
-
- inl_max_uid = (inl_f->emit->x_cur_insn_uid + 1);
- map->insn_map = xcalloc (inl_max_uid, sizeof (rtx));
- map->min_insnno = 0;
- map->max_insnno = inl_max_uid;
-
- map->integrating = 1;
- map->compare_src = NULL_RTX;
- map->compare_mode = VOIDmode;
-
- /* const_equiv_varray maps pseudos in our routine to constants, so
- it needs to be large enough for all our pseudos. This is the
- number we are currently using plus the number in the called
- routine, plus 15 for each arg, five to compute the virtual frame
- pointer, and five for the return value. This should be enough
- for most cases. We do not reference entries outside the range of
- the map.
-
- ??? These numbers are quite arbitrary and were obtained by
- experimentation. At some point, we should try to allocate the
- table after all the parameters are set up so we can more accurately
- estimate the number of pseudos we will need. */
-
- VARRAY_CONST_EQUIV_INIT (map->const_equiv_varray,
- (max_reg_num ()
- + (max_regno - FIRST_PSEUDO_REGISTER)
- + 15 * nargs
- + 10),
- "expand_inline_function");
- map->const_age = 0;
-
- /* Record the current insn in case we have to set up pointers to frame
- and argument memory blocks. If there are no insns yet, add a dummy
- insn that can be used as an insertion point. */
- map->insns_at_start = get_last_insn ();
- if (map->insns_at_start == 0)
- map->insns_at_start = emit_note (NOTE_INSN_DELETED);
-
- map->regno_pointer_align = inl_f->emit->regno_pointer_align;
- map->x_regno_reg_rtx = inl_f->emit->x_regno_reg_rtx;
-
- /* Update the outgoing argument size to allow for those in the inlined
- function. */
- if (inl_f->outgoing_args_size > current_function_outgoing_args_size)
- current_function_outgoing_args_size = inl_f->outgoing_args_size;
-
- /* If the inline function needs to make PIC references, that means
- that this function's PIC offset table must be used. */
- if (inl_f->uses_pic_offset_table)
- current_function_uses_pic_offset_table = 1;
-
- /* If this function needs a context, set it up. */
- if (inl_f->needs_context)
- static_chain_value = lookup_static_chain (fndecl);
-
- /* If the inlined function calls __builtin_constant_p, then we'll
- need to call purge_builtin_constant_p on this function. */
- if (inl_f->calls_constant_p)
- current_function_calls_constant_p = 1;
-
- if (GET_CODE (parm_insns) == NOTE
- && NOTE_LINE_NUMBER (parm_insns) > 0)
- {
- rtx note = emit_note_copy (parm_insns);
-
- if (note)
- RTX_INTEGRATED_P (note) = 1;
- }
-
- /* Process each argument. For each, set up things so that the function's
- reference to the argument will refer to the argument being passed.
- We only replace REG with REG here. Any simplifications are done
- via const_equiv_map.
-
- We make two passes: In the first, we deal with parameters that will
- be placed into registers, since we need to ensure that the allocated
- register number fits in const_equiv_map. Then we store all non-register
- parameters into their memory location. */
-
- /* Don't try to free temp stack slots here, because we may put one of the
- parameters into a temp stack slot. */
-
- for (i = 0; i < nargs; i++)
- {
- rtx copy = arg_vals[i];
- loc = RTVEC_ELT (arg_vector, i);
-
- /* There are three cases, each handled separately. */
- if (GET_CODE (loc) == MEM && GET_CODE (XEXP (loc, 0)) == REG
- && REGNO (XEXP (loc, 0)) > LAST_VIRTUAL_REGISTER)
- {
- /* This must be an object passed by invisible reference (it could
- also be a variable-sized object, but we forbid inlining functions
- with variable-sized arguments). COPY is the address of the
- actual value (this computation will cause it to be copied). We
- map that address for the register, noting the actual address as
- an equivalent in case it can be substituted into the insns. */
-
- if (GET_CODE (copy) != REG)
- {
- temp = copy_addr_to_reg (copy);
- if (CONSTANT_P (copy) || FIXED_BASE_PLUS_P (copy))
- SET_CONST_EQUIV_DATA (map, temp, copy, CONST_AGE_PARM);
- copy = temp;
- }
- map->reg_map[REGNO (XEXP (loc, 0))] = copy;
- }
- else if (GET_CODE (loc) == MEM)
- {
- /* This is the case of a parameter that lives in memory. It
- will live in the block we allocate in the called routine's
- frame that simulates the incoming argument area. Do nothing
- with the parameter now; we will call store_expr later. In
- this case, however, we must ensure that the virtual stack and
- incoming arg rtx values are expanded now so that we can be
- sure we have enough slots in the const equiv map since the
- store_expr call can easily blow the size estimate. */
- if (DECL_STRUCT_FUNCTION (fndecl)->args_size != 0)
- copy_rtx_and_substitute (virtual_incoming_args_rtx, map, 0);
- }
- else if (GET_CODE (loc) == REG)
- process_reg_param (map, loc, copy);
- else if (GET_CODE (loc) == CONCAT)
- {
- rtx locreal = gen_realpart (GET_MODE (XEXP (loc, 0)), loc);
- rtx locimag = gen_imagpart (GET_MODE (XEXP (loc, 0)), loc);
- rtx copyreal = gen_realpart (GET_MODE (locreal), copy);
- rtx copyimag = gen_imagpart (GET_MODE (locimag), copy);
-
- process_reg_param (map, locreal, copyreal);
- process_reg_param (map, locimag, copyimag);
- }
- else
- abort ();
- }
-
- /* Tell copy_rtx_and_substitute to handle constant pool SYMBOL_REFs
- specially. This function can be called recursively, so we need to
- save the previous value. */
- inlining_previous = inlining;
- inlining = inl_f;
-
- /* Now do the parameters that will be placed in memory. */
-
- for (formal = DECL_ARGUMENTS (fndecl), i = 0;
- formal; formal = TREE_CHAIN (formal), i++)
- {
- loc = RTVEC_ELT (arg_vector, i);
-
- if (GET_CODE (loc) == MEM
- /* Exclude case handled above. */
- && ! (GET_CODE (XEXP (loc, 0)) == REG
- && REGNO (XEXP (loc, 0)) > LAST_VIRTUAL_REGISTER))
- {
- rtx note = emit_line_note (DECL_SOURCE_LOCATION (formal));
-
- if (note)
- RTX_INTEGRATED_P (note) = 1;
-
- /* Compute the address in the area we reserved and store the
- value there. */
- temp = copy_rtx_and_substitute (loc, map, 1);
- subst_constants (&temp, NULL_RTX, map, 1);
- apply_change_group ();
- if (! memory_address_p (GET_MODE (temp), XEXP (temp, 0)))
- temp = change_address (temp, VOIDmode, XEXP (temp, 0));
- store_expr (arg_trees[i], temp, 0);
- }
- }
-
- /* Deal with the places that the function puts its result.
- We are driven by what is placed into DECL_RESULT.
-
- Initially, we assume that we don't have anything special handling for
- REG_FUNCTION_RETURN_VALUE_P. */
-
- map->inline_target = 0;
- loc = (DECL_RTL_SET_P (DECL_RESULT (fndecl))
- ? DECL_RTL (DECL_RESULT (fndecl)) : NULL_RTX);
-
- if (TYPE_MODE (type) == VOIDmode)
- /* There is no return value to worry about. */
- ;
- else if (GET_CODE (loc) == MEM)
- {
- if (GET_CODE (XEXP (loc, 0)) == ADDRESSOF)
- {
- temp = copy_rtx_and_substitute (loc, map, 1);
- subst_constants (&temp, NULL_RTX, map, 1);
- apply_change_group ();
- target = temp;
- }
- else
- {
- if (! structure_value_addr
- || ! aggregate_value_p (DECL_RESULT (fndecl), fndecl))
- abort ();
-
- /* Pass the function the address in which to return a structure
- value. Note that a constructor can cause someone to call us
- with STRUCTURE_VALUE_ADDR, but the initialization takes place
- via the first parameter, rather than the struct return address.
-
- We have two cases: If the address is a simple register
- indirect, use the mapping mechanism to point that register to
- our structure return address. Otherwise, store the structure
- return value into the place that it will be referenced from. */
-
- if (GET_CODE (XEXP (loc, 0)) == REG)
- {
- temp = force_operand (structure_value_addr, NULL_RTX);
- temp = force_reg (Pmode, temp);
- /* A virtual register might be invalid in an insn, because
- it can cause trouble in reload. Since we don't have access
- to the expanders at map translation time, make sure we have
- a proper register now.
- If a virtual register is actually valid, cse or combine
- can put it into the mapped insns. */
- if (REGNO (temp) >= FIRST_VIRTUAL_REGISTER
- && REGNO (temp) <= LAST_VIRTUAL_REGISTER)
- temp = copy_to_mode_reg (Pmode, temp);
- map->reg_map[REGNO (XEXP (loc, 0))] = temp;
-
- if (CONSTANT_P (structure_value_addr)
- || GET_CODE (structure_value_addr) == ADDRESSOF
- || (GET_CODE (structure_value_addr) == PLUS
- && (XEXP (structure_value_addr, 0)
- == virtual_stack_vars_rtx)
- && (GET_CODE (XEXP (structure_value_addr, 1))
- == CONST_INT)))
- {
- SET_CONST_EQUIV_DATA (map, temp, structure_value_addr,
- CONST_AGE_PARM);
- }
- }
- else
- {
- temp = copy_rtx_and_substitute (loc, map, 1);
- subst_constants (&temp, NULL_RTX, map, 0);
- apply_change_group ();
- emit_move_insn (temp, structure_value_addr);
- }
- }
- }
- else if (ignore)
- /* We will ignore the result value, so don't look at its structure.
- Note that preparations for an aggregate return value
- do need to be made (above) even if it will be ignored. */
- ;
- else if (GET_CODE (loc) == REG)
- {
- /* The function returns an object in a register and we use the return
- value. Set up our target for remapping. */
-
- /* Machine mode function was declared to return. */
- enum machine_mode departing_mode = TYPE_MODE (type);
- /* (Possibly wider) machine mode it actually computes
- (for the sake of callers that fail to declare it right).
- We have to use the mode of the result's RTL, rather than
- its type, since expand_function_start may have promoted it. */
- enum machine_mode arriving_mode
- = GET_MODE (DECL_RTL (DECL_RESULT (fndecl)));
- rtx reg_to_map;
-
- /* Don't use MEMs as direct targets because on some machines
- substituting a MEM for a REG makes invalid insns.
- Let the combiner substitute the MEM if that is valid. */
- if (target == 0 || GET_CODE (target) != REG
- || GET_MODE (target) != departing_mode)
- {
- /* Don't make BLKmode registers. If this looks like
- a BLKmode object being returned in a register, get
- the mode from that, otherwise abort. */
- if (departing_mode == BLKmode)
- {
- if (REG == GET_CODE (DECL_RTL (DECL_RESULT (fndecl))))
- {
- departing_mode = GET_MODE (DECL_RTL (DECL_RESULT (fndecl)));
- arriving_mode = departing_mode;
- }
- else
- abort ();
- }
-
- target = gen_reg_rtx (departing_mode);
- }
-
- /* If function's value was promoted before return,
- avoid machine mode mismatch when we substitute INLINE_TARGET.
- But TARGET is what we will return to the caller. */
- if (arriving_mode != departing_mode)
- {
- /* Avoid creating a paradoxical subreg wider than
- BITS_PER_WORD, since that is illegal. */
- if (GET_MODE_BITSIZE (arriving_mode) > BITS_PER_WORD)
- {
- if (!TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (departing_mode),
- GET_MODE_BITSIZE (arriving_mode)))
- /* Maybe could be handled by using convert_move () ? */
- abort ();
- reg_to_map = gen_reg_rtx (arriving_mode);
- target = gen_lowpart (departing_mode, reg_to_map);
- }
- else
- reg_to_map = gen_rtx_SUBREG (arriving_mode, target, 0);
- }
- else
- reg_to_map = target;
-
- /* Usually, the result value is the machine's return register.
- Sometimes it may be a pseudo. Handle both cases. */
- if (REG_FUNCTION_VALUE_P (loc))
- map->inline_target = reg_to_map;
- else
- map->reg_map[REGNO (loc)] = reg_to_map;
- }
- else if (GET_CODE (loc) == CONCAT)
- {
- enum machine_mode departing_mode = TYPE_MODE (type);
- enum machine_mode arriving_mode
- = GET_MODE (DECL_RTL (DECL_RESULT (fndecl)));
-
- if (departing_mode != arriving_mode)
- abort ();
- if (GET_CODE (XEXP (loc, 0)) != REG
- || GET_CODE (XEXP (loc, 1)) != REG)
- abort ();
-
- /* Don't use MEMs as direct targets because on some machines
- substituting a MEM for a REG makes invalid insns.
- Let the combiner substitute the MEM if that is valid. */
- if (target == 0 || GET_CODE (target) != REG
- || GET_MODE (target) != departing_mode)
- target = gen_reg_rtx (departing_mode);
-
- if (GET_CODE (target) != CONCAT)
- abort ();
-
- map->reg_map[REGNO (XEXP (loc, 0))] = XEXP (target, 0);
- map->reg_map[REGNO (XEXP (loc, 1))] = XEXP (target, 1);
- }
- else
- abort ();
-
- /* Remap the exception handler data pointer from one to the other. */
- temp = get_exception_pointer (inl_f);
- if (temp)
- map->reg_map[REGNO (temp)] = get_exception_pointer (cfun);
-
- /* Initialize label_map. get_label_from_map will actually make
- the labels. */
- memset (&map->label_map[min_labelno], 0,
- (max_labelno - min_labelno) * sizeof (rtx));
-
- /* Make copies of the decls of the symbols in the inline function, so that
- the copies of the variables get declared in the current function. Set
- up things so that lookup_static_chain knows that to interpret registers
- in SAVE_EXPRs for TYPE_SIZEs as local. */
- inline_function_decl = fndecl;
- integrate_parm_decls (DECL_ARGUMENTS (fndecl), map, arg_vector);
- block = integrate_decl_tree (inl_f->original_decl_initial, map);
- BLOCK_ABSTRACT_ORIGIN (block) = DECL_ORIGIN (fndecl);
- inline_function_decl = 0;
-
- /* Make a fresh binding contour that we can easily remove. Do this after
- expanding our arguments so cleanups are properly scoped. */
- expand_start_bindings_and_block (0, block);
-
- /* Sort the block-map so that it will be easy to find remapped
- blocks later. */
- qsort (&VARRAY_TREE (map->block_map, 0),
- map->block_map->elements_used,
- sizeof (tree),
- compare_blocks);
-
- /* Perform postincrements before actually calling the function. */
- emit_queue ();
-
- /* Clean up stack so that variables might have smaller offsets. */
- do_pending_stack_adjust ();
-
- /* Save a copy of the location of const_equiv_varray for
- mark_stores, called via note_stores. */
- global_const_equiv_varray = map->const_equiv_varray;
-
- /* If the called function does an alloca, save and restore the
- stack pointer around the call. This saves stack space, but
- also is required if this inline is being done between two
- pushes. */
- if (inl_f->calls_alloca)
- emit_stack_save (SAVE_BLOCK, &stack_save, NULL_RTX);
-
- /* Map pseudos used for initial hard reg values. */
- setup_initial_hard_reg_value_integration (inl_f, map);
-
- /* Now copy the insns one by one. */
- copy_insn_list (insns, map, static_chain_value);
-
- /* Duplicate the EH regions. This will create an offset from the
- region numbers in the function we're inlining to the region
- numbers in the calling function. This must wait until after
- copy_insn_list, as we need the insn map to be complete. */
- eh_region_offset = duplicate_eh_regions (inl_f, map);
-
- /* Now copy the REG_NOTES for those insns. */
- copy_insn_notes (insns, map, eh_region_offset);
-
- /* If the insn sequence required one, emit the return label. */
- if (map->local_return_label)
- emit_label (map->local_return_label);
-
- /* Restore the stack pointer if we saved it above. */
- if (inl_f->calls_alloca)
- emit_stack_restore (SAVE_BLOCK, stack_save, NULL_RTX);
-
- if (! cfun->x_whole_function_mode_p)
- /* In statement-at-a-time mode, we just tell the front-end to add
- this block to the list of blocks at this binding level. We
- can't do it the way it's done for function-at-a-time mode the
- superblocks have not been created yet. */
- lang_hooks.decls.insert_block (block);
- else
- {
- BLOCK_CHAIN (block)
- = BLOCK_CHAIN (DECL_INITIAL (current_function_decl));
- BLOCK_CHAIN (DECL_INITIAL (current_function_decl)) = block;
- }
-
- /* End the scope containing the copied formal parameter variables
- and copied LABEL_DECLs. We pass NULL_TREE for the variables list
- here so that expand_end_bindings will not check for unused
- variables. That's already been checked for when the inlined
- function was defined. */
- expand_end_bindings (NULL_TREE, 1, 1);
-
- /* Must mark the line number note after inlined functions as a repeat, so
- that the test coverage code can avoid counting the call twice. This
- just tells the code to ignore the immediately following line note, since
- there already exists a copy of this note before the expanded inline call.
- This line number note is still needed for debugging though, so we can't
- delete it. */
- if (flag_test_coverage)
- emit_note (NOTE_INSN_REPEATED_LINE_NUMBER);
-
- emit_line_note (input_location);
-
- /* If the function returns a BLKmode object in a register, copy it
- out of the temp register into a BLKmode memory object. */
- if (target
- && TYPE_MODE (TREE_TYPE (TREE_TYPE (fndecl))) == BLKmode
- && ! aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl)), fndecl))
- target = copy_blkmode_from_reg (0, target, TREE_TYPE (TREE_TYPE (fndecl)));
-
- if (structure_value_addr)
- {
- target = gen_rtx_MEM (TYPE_MODE (type),
- memory_address (TYPE_MODE (type),
- structure_value_addr));
- set_mem_attributes (target, type, 1);
- }
-
- /* Make sure we free the things we explicitly allocated with xmalloc. */
- if (real_label_map)
- free (real_label_map);
- VARRAY_FREE (map->const_equiv_varray);
- free (map->reg_map);
- free (map->insn_map);
- free (map);
- free (arg_vals);
- free (arg_trees);
-
- inlining = inlining_previous;
-
- return target;
-}
-
-/* Make copies of each insn in the given list using the mapping
- computed in expand_inline_function. This function may call itself for
- insns containing sequences.
-
- Copying is done in two passes, first the insns and then their REG_NOTES.
-
- If static_chain_value is nonzero, it represents the context-pointer
- register for the function. */
-
-static void
-copy_insn_list (rtx insns, struct inline_remap *map, rtx static_chain_value)
-{
- int i;
- rtx insn;
- rtx temp;
-#ifdef HAVE_cc0
- rtx cc0_insn = 0;
-#endif
- rtx static_chain_mem = 0;
-
- /* Copy the insns one by one. Do this in two passes, first the insns and
- then their REG_NOTES. */
-
- /* This loop is very similar to the loop in copy_loop_body in unroll.c. */
-
- for (insn = insns; insn; insn = NEXT_INSN (insn))
- {
- rtx copy, pattern, set;
-
- map->orig_asm_operands_vector = 0;
-
- switch (GET_CODE (insn))
- {
- case INSN:
- pattern = PATTERN (insn);
- set = single_set (insn);
- copy = 0;
- if (GET_CODE (pattern) == USE
- && GET_CODE (XEXP (pattern, 0)) == REG
- && REG_FUNCTION_VALUE_P (XEXP (pattern, 0)))
- /* The (USE (REG n)) at return from the function should
- be ignored since we are changing (REG n) into
- inline_target. */
- break;
-
- /* Ignore setting a function value that we don't want to use. */
- if (map->inline_target == 0
- && set != 0
- && GET_CODE (SET_DEST (set)) == REG
- && REG_FUNCTION_VALUE_P (SET_DEST (set)))
- {
- if (volatile_refs_p (SET_SRC (set)))
- {
- rtx new_set;
-
- /* If we must not delete the source,
- load it into a new temporary. */
- copy = emit_insn (copy_rtx_and_substitute (pattern, map, 0));
-
- new_set = single_set (copy);
- if (new_set == 0)
- abort ();
-
- SET_DEST (new_set)
- = gen_reg_rtx (GET_MODE (SET_DEST (new_set)));
- }
- /* If the source and destination are the same and it
- has a note on it, keep the insn. */
- else if (rtx_equal_p (SET_DEST (set), SET_SRC (set))
- && REG_NOTES (insn) != 0)
- copy = emit_insn (copy_rtx_and_substitute (pattern, map, 0));
- else
- break;
- }
-
- /* Similarly if an ignored return value is clobbered. */
- else if (map->inline_target == 0
- && GET_CODE (pattern) == CLOBBER
- && GET_CODE (XEXP (pattern, 0)) == REG
- && REG_FUNCTION_VALUE_P (XEXP (pattern, 0)))
- break;
-
- /* Look for the address of the static chain slot. The
- rtx_equal_p comparisons against the
- static_chain_incoming_rtx below may fail if the static
- chain is in memory and the address specified is not
- "legitimate". This happens on Xtensa where the static
- chain is at a negative offset from argp and where only
- positive offsets are legitimate. When the RTL is
- generated, the address is "legitimized" by copying it
- into a register, causing the rtx_equal_p comparisons to
- fail. This workaround looks for code that sets a
- register to the address of the static chain. Subsequent
- memory references via that register can then be
- identified as static chain references. We assume that
- the register is only assigned once, and that the static
- chain address is only live in one register at a time. */
-
- else if (static_chain_value != 0
- && set != 0
- && GET_CODE (static_chain_incoming_rtx) == MEM
- && GET_CODE (SET_DEST (set)) == REG
- && rtx_equal_p (SET_SRC (set),
- XEXP (static_chain_incoming_rtx, 0)))
- {
- static_chain_mem =
- gen_rtx_MEM (GET_MODE (static_chain_incoming_rtx),
- SET_DEST (set));
-
- /* Emit the instruction in case it is used for something
- other than setting the static chain; if it's not used,
- it can always be removed as dead code */
- copy = emit_insn (copy_rtx_and_substitute (pattern, map, 0));
- }
-
- /* If this is setting the static chain rtx, omit it. */
- else if (static_chain_value != 0
- && set != 0
- && (rtx_equal_p (SET_DEST (set),
- static_chain_incoming_rtx)
- || (static_chain_mem
- && rtx_equal_p (SET_DEST (set), static_chain_mem))))
- break;
-
- /* If this is setting the static chain pseudo, set it from
- the value we want to give it instead. */
- else if (static_chain_value != 0
- && set != 0
- && (rtx_equal_p (SET_SRC (set),
- static_chain_incoming_rtx)
- || (static_chain_mem
- && rtx_equal_p (SET_SRC (set), static_chain_mem))))
- {
- rtx newdest = copy_rtx_and_substitute (SET_DEST (set), map, 1);
-
- copy = emit_move_insn (newdest, static_chain_value);
- if (GET_CODE (static_chain_incoming_rtx) != MEM)
- static_chain_value = 0;
- }
-
- /* If this is setting the virtual stack vars register, this must
- be the code at the handler for a builtin longjmp. The value
- saved in the setjmp buffer will be the address of the frame
- we've made for this inlined instance within our frame. But we
- know the offset of that value so we can use it to reconstruct
- our virtual stack vars register from that value. If we are
- copying it from the stack pointer, leave it unchanged. */
- else if (set != 0
- && rtx_equal_p (SET_DEST (set), virtual_stack_vars_rtx))
- {
- HOST_WIDE_INT offset;
- temp = map->reg_map[REGNO (SET_DEST (set))];
- temp = VARRAY_CONST_EQUIV (map->const_equiv_varray,
- REGNO (temp)).rtx;
-
- if (rtx_equal_p (temp, virtual_stack_vars_rtx))
- offset = 0;
- else if (GET_CODE (temp) == PLUS
- && rtx_equal_p (XEXP (temp, 0), virtual_stack_vars_rtx)
- && GET_CODE (XEXP (temp, 1)) == CONST_INT)
- offset = INTVAL (XEXP (temp, 1));
- else
- abort ();
-
- if (rtx_equal_p (SET_SRC (set), stack_pointer_rtx))
- temp = SET_SRC (set);
- else
- temp = force_operand (plus_constant (SET_SRC (set),
- - offset),
- NULL_RTX);
-
- copy = emit_move_insn (virtual_stack_vars_rtx, temp);
- }
-
- else
- copy = emit_insn (copy_rtx_and_substitute (pattern, map, 0));
- /* REG_NOTES will be copied later. */
-
-#ifdef HAVE_cc0
- /* If this insn is setting CC0, it may need to look at
- the insn that uses CC0 to see what type of insn it is.
- In that case, the call to recog via validate_change will
- fail. So don't substitute constants here. Instead,
- do it when we emit the following insn.
-
- For example, see the pyr.md file. That machine has signed and
- unsigned compares. The compare patterns must check the
- following branch insn to see which what kind of compare to
- emit.
-
- If the previous insn set CC0, substitute constants on it as
- well. */
- if (sets_cc0_p (PATTERN (copy)) != 0)
- cc0_insn = copy;
- else
- {
- if (cc0_insn)
- try_constants (cc0_insn, map);
- cc0_insn = 0;
- try_constants (copy, map);
- }
-#else
- try_constants (copy, map);
-#endif
- INSN_LOCATOR (copy) = INSN_LOCATOR (insn);
- break;
-
- case JUMP_INSN:
- if (map->integrating && returnjump_p (insn))
- {
- if (map->local_return_label == 0)
- map->local_return_label = gen_label_rtx ();
- pattern = gen_jump (map->local_return_label);
- }
- else
- pattern = copy_rtx_and_substitute (PATTERN (insn), map, 0);
-
- copy = emit_jump_insn (pattern);
-
-#ifdef HAVE_cc0
- if (cc0_insn)
- try_constants (cc0_insn, map);
- cc0_insn = 0;
-#endif
- try_constants (copy, map);
- INSN_LOCATOR (copy) = INSN_LOCATOR (insn);
-
- /* If this used to be a conditional jump insn but whose branch
- direction is now know, we must do something special. */
- if (any_condjump_p (insn) && onlyjump_p (insn) && map->last_pc_value)
- {
-#ifdef HAVE_cc0
- /* If the previous insn set cc0 for us, delete it. */
- if (only_sets_cc0_p (PREV_INSN (copy)))
- delete_related_insns (PREV_INSN (copy));
-#endif
-
- /* If this is now a no-op, delete it. */
- if (map->last_pc_value == pc_rtx)
- {
- delete_related_insns (copy);
- copy = 0;
- }
- else
- /* Otherwise, this is unconditional jump so we must put a
- BARRIER after it. We could do some dead code elimination
- here, but jump.c will do it just as well. */
- emit_barrier ();
- }
- break;
-
- case CALL_INSN:
- /* If this is a CALL_PLACEHOLDER insn then we need to copy the
- three attached sequences: normal call, sibling call and tail
- recursion. */
- if (GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
- {
- rtx sequence[3];
- rtx tail_label;
-
- for (i = 0; i < 3; i++)
- {
- rtx seq;
-
- sequence[i] = NULL_RTX;
- seq = XEXP (PATTERN (insn), i);
- if (seq)
- {
- start_sequence ();
- copy_insn_list (seq, map, static_chain_value);
- sequence[i] = get_insns ();
- end_sequence ();
- }
- }
-
- /* Find the new tail recursion label.
- It will already be substituted into sequence[2]. */
- tail_label = copy_rtx_and_substitute (XEXP (PATTERN (insn), 3),
- map, 0);
-
- copy = emit_call_insn (gen_rtx_CALL_PLACEHOLDER (VOIDmode,
- sequence[0],
- sequence[1],
- sequence[2],
- tail_label));
- break;
- }
-
- pattern = copy_rtx_and_substitute (PATTERN (insn), map, 0);
- copy = emit_call_insn (pattern);
-
- SIBLING_CALL_P (copy) = SIBLING_CALL_P (insn);
- CONST_OR_PURE_CALL_P (copy) = CONST_OR_PURE_CALL_P (insn);
- INSN_LOCATOR (copy) = INSN_LOCATOR (insn);
-
- /* Because the USAGE information potentially contains objects other
- than hard registers, we need to copy it. */
-
- CALL_INSN_FUNCTION_USAGE (copy)
- = copy_rtx_and_substitute (CALL_INSN_FUNCTION_USAGE (insn),
- map, 0);
-
-#ifdef HAVE_cc0
- if (cc0_insn)
- try_constants (cc0_insn, map);
- cc0_insn = 0;
-#endif
- try_constants (copy, map);
-
- /* Be lazy and assume CALL_INSNs clobber all hard registers. */
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- VARRAY_CONST_EQUIV (map->const_equiv_varray, i).rtx = 0;
- break;
-
- case CODE_LABEL:
- copy = emit_label (get_label_from_map (map,
- CODE_LABEL_NUMBER (insn)));
- LABEL_NAME (copy) = LABEL_NAME (insn);
- map->const_age++;
- break;
-
- case BARRIER:
- copy = emit_barrier ();
- break;
-
- case NOTE:
- if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL)
- {
- copy = emit_label (get_label_from_map (map,
- CODE_LABEL_NUMBER (insn)));
- LABEL_NAME (copy) = NOTE_SOURCE_FILE (insn);
- map->const_age++;
- break;
- }
-
- /* NOTE_INSN_FUNCTION_END and NOTE_INSN_FUNCTION_BEG are
- discarded because it is important to have only one of
- each in the current function.
-
- NOTE_INSN_DELETED notes aren't useful. */
-
- if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END
- && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_BEG
- && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED)
- {
- copy = emit_note_copy (insn);
- if (!copy)
- /*Copied a line note, but line numbering is off*/;
- else if ((NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_BEG
- || NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_END)
- && NOTE_BLOCK (insn))
- {
- tree *mapped_block_p;
-
- mapped_block_p
- = bsearch (NOTE_BLOCK (insn),
- &VARRAY_TREE (map->block_map, 0),
- map->block_map->elements_used,
- sizeof (tree),
- find_block);
-
- if (!mapped_block_p)
- abort ();
- else
- NOTE_BLOCK (copy) = *mapped_block_p;
- }
- else if (NOTE_LINE_NUMBER (copy) == NOTE_INSN_EXPECTED_VALUE)
- NOTE_EXPECTED_VALUE (copy)
- = copy_rtx_and_substitute (NOTE_EXPECTED_VALUE (insn),
- map, 0);
- }
- else
- copy = 0;
- break;
-
- default:
- abort ();
- }
-
- if (copy)
- RTX_INTEGRATED_P (copy) = 1;
-
- map->insn_map[INSN_UID (insn)] = copy;
- }
-}
-
-/* Copy the REG_NOTES. Increment const_age, so that only constants
- from parameters can be substituted in. These are the only ones
- that are valid across the entire function. */
-
-static void
-copy_insn_notes (rtx insns, struct inline_remap *map, int eh_region_offset)
-{
- rtx insn, new_insn;
-
- map->const_age++;
- for (insn = insns; insn; insn = NEXT_INSN (insn))
- {
- if (! INSN_P (insn))
- continue;
-
- new_insn = map->insn_map[INSN_UID (insn)];
- if (! new_insn)
- continue;
-
- if (REG_NOTES (insn))
- {
- rtx next, note = copy_rtx_and_substitute (REG_NOTES (insn), map, 0);
-
- /* We must also do subst_constants, in case one of our parameters
- has const type and constant value. */
- subst_constants (&note, NULL_RTX, map, 0);
- apply_change_group ();
- REG_NOTES (new_insn) = note;
-
- /* Delete any REG_LABEL notes from the chain. Remap any
- REG_EH_REGION notes. */
- for (; note; note = next)
- {
- next = XEXP (note, 1);
- if (REG_NOTE_KIND (note) == REG_LABEL)
- remove_note (new_insn, note);
- else if (REG_NOTE_KIND (note) == REG_EH_REGION
- && INTVAL (XEXP (note, 0)) > 0)
- XEXP (note, 0) = GEN_INT (INTVAL (XEXP (note, 0))
- + eh_region_offset);
- }
- }
-
- if (GET_CODE (insn) == CALL_INSN
- && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
- {
- int i;
- for (i = 0; i < 3; i++)
- copy_insn_notes (XEXP (PATTERN (insn), i), map, eh_region_offset);
- }
-
- if (GET_CODE (insn) == JUMP_INSN
- && GET_CODE (PATTERN (insn)) == RESX)
- XINT (PATTERN (new_insn), 0) += eh_region_offset;
- }
-}
-
-/* Given a chain of PARM_DECLs, ARGS, copy each decl into a VAR_DECL,
- push all of those decls and give each one the corresponding home. */
-
-static void
-integrate_parm_decls (tree args, struct inline_remap *map, rtvec arg_vector)
-{
- tree tail;
- int i;
-
- for (tail = args, i = 0; tail; tail = TREE_CHAIN (tail), i++)
- {
- tree decl = copy_decl_for_inlining (tail, map->fndecl,
- current_function_decl);
- rtx new_decl_rtl
- = copy_rtx_and_substitute (RTVEC_ELT (arg_vector, i), map, 1);
-
- /* We really should be setting DECL_INCOMING_RTL to something reasonable
- here, but that's going to require some more work. */
- /* DECL_INCOMING_RTL (decl) = ?; */
- /* Fully instantiate the address with the equivalent form so that the
- debugging information contains the actual register, instead of the
- virtual register. Do this by not passing an insn to
- subst_constants. */
- subst_constants (&new_decl_rtl, NULL_RTX, map, 1);
- apply_change_group ();
- SET_DECL_RTL (decl, new_decl_rtl);
- }
-}
-
-/* Given a BLOCK node LET, push decls and levels so as to construct in the
- current function a tree of contexts isomorphic to the one that is given.
-
- MAP, if nonzero, is a pointer to an inline_remap map which indicates how
- registers used in the DECL_RTL field should be remapped. If it is zero,
- no mapping is necessary. */
-
-static tree
-integrate_decl_tree (tree let, struct inline_remap *map)
-{
- tree t;
- tree new_block;
- tree *next;
-
- new_block = make_node (BLOCK);
- VARRAY_PUSH_TREE (map->block_map, new_block);
- next = &BLOCK_VARS (new_block);
-
- for (t = BLOCK_VARS (let); t; t = TREE_CHAIN (t))
- {
- tree d;
-
- d = copy_decl_for_inlining (t, map->fndecl, current_function_decl);
-
- if (DECL_RTL_SET_P (t))
- {
- rtx r;
-
- SET_DECL_RTL (d, copy_rtx_and_substitute (DECL_RTL (t), map, 1));
-
- /* Fully instantiate the address with the equivalent form so that the
- debugging information contains the actual register, instead of the
- virtual register. Do this by not passing an insn to
- subst_constants. */
- r = DECL_RTL (d);
- subst_constants (&r, NULL_RTX, map, 1);
- SET_DECL_RTL (d, r);
-
- apply_change_group ();
- }
-
- /* Add this declaration to the list of variables in the new
- block. */
- *next = d;
- next = &TREE_CHAIN (d);
- }
-
- next = &BLOCK_SUBBLOCKS (new_block);
- for (t = BLOCK_SUBBLOCKS (let); t; t = BLOCK_CHAIN (t))
- {
- *next = integrate_decl_tree (t, map);
- BLOCK_SUPERCONTEXT (*next) = new_block;
- next = &BLOCK_CHAIN (*next);
- }
-
- TREE_USED (new_block) = TREE_USED (let);
- BLOCK_ABSTRACT_ORIGIN (new_block) = let;
-
- return new_block;
-}
-
/* Create a new copy of an rtx. Recursively copies the operands of the rtx,
except for those few rtx codes that are sharable.
@@ -1884,10 +241,7 @@ copy_rtx_and_substitute (rtx orig, struct inline_remap *map, int for_lhs)
Small hard registers are returned as-is. Pseudo-registers
go through their `reg_map'. */
regno = REGNO (orig);
- if (regno <= LAST_VIRTUAL_REGISTER
- || (map->integrating
- && DECL_STRUCT_FUNCTION (map->fndecl)->internal_arg_pointer
- == orig))
+ if (regno <= LAST_VIRTUAL_REGISTER)
{
/* Some hard registers are also mapped,
but others are not translated. */
@@ -1942,10 +296,7 @@ copy_rtx_and_substitute (rtx orig, struct inline_remap *map, int for_lhs)
emit_insn_after (seq, map->insns_at_start);
return temp;
}
- else if (regno == VIRTUAL_INCOMING_ARGS_REGNUM
- || (map->integrating
- && (DECL_STRUCT_FUNCTION (map->fndecl)->internal_arg_pointer
- == orig)))
+ else if (regno == VIRTUAL_INCOMING_ARGS_REGNUM)
{
/* Do the same for a block to contain any arguments referenced
in memory. */
@@ -1977,44 +328,17 @@ copy_rtx_and_substitute (rtx orig, struct inline_remap *map, int for_lhs)
}
else if (REG_FUNCTION_VALUE_P (orig))
{
- /* This is a reference to the function return value. If
- the function doesn't have a return value, error. If the
- mode doesn't agree, and it ain't BLKmode, make a SUBREG. */
- if (map->inline_target == 0)
- {
- if (rtx_equal_function_value_matters)
- /* This is an ignored return value. We must not
- leave it in with REG_FUNCTION_VALUE_P set, since
- that would confuse subsequent inlining of the
- current function into a later function. */
- return gen_rtx_REG (GET_MODE (orig), regno);
- else
- /* Must be unrolling loops or replicating code if we
- reach here, so return the register unchanged. */
- return orig;
- }
- else if (GET_MODE (map->inline_target) != BLKmode
- && mode != GET_MODE (map->inline_target))
- return gen_lowpart (mode, map->inline_target);
+ if (rtx_equal_function_value_matters)
+ /* This is an ignored return value. We must not
+ leave it in with REG_FUNCTION_VALUE_P set, since
+ that would confuse subsequent inlining of the
+ current function into a later function. */
+ return gen_rtx_REG (GET_MODE (orig), regno);
else
- return map->inline_target;
+ /* Must be unrolling loops or replicating code if we
+ reach here, so return the register unchanged. */
+ return orig;
}
-#if defined (LEAF_REGISTERS) && defined (LEAF_REG_REMAP)
- /* If leaf_renumber_regs_insn() might remap this register to
- some other number, make sure we don't share it with the
- inlined function, otherwise delayed optimization of the
- inlined function may change it in place, breaking our
- reference to it. We may still shared it within the
- function, so create an entry for this register in the
- reg_map. */
- if (map->integrating && regno < FIRST_PSEUDO_REGISTER
- && LEAF_REGISTERS[regno] && LEAF_REG_REMAP (regno) != regno)
- {
- if (!map->leaf_reg_map[regno][mode])
- map->leaf_reg_map[regno][mode] = gen_rtx_REG (mode, regno);
- return map->leaf_reg_map[regno][mode];
- }
-#endif
else
return orig;
@@ -2136,44 +460,14 @@ copy_rtx_and_substitute (rtx orig, struct inline_remap *map, int for_lhs)
remapped label. Otherwise, symbols are returned unchanged. */
if (CONSTANT_POOL_ADDRESS_P (orig))
{
- struct function *f = inlining ? inlining : cfun;
+ struct function *f = cfun;
rtx constant = get_pool_constant_for_function (f, orig);
- enum machine_mode const_mode = get_pool_mode_for_function (f, orig);
- if (inlining)
- {
- rtx temp = force_const_mem (const_mode,
- copy_rtx_and_substitute (constant,
- map, 0));
-
-#if 0
- /* Legitimizing the address here is incorrect.
-
- Since we had a SYMBOL_REF before, we can assume it is valid
- to have one in this position in the insn.
-
- Also, change_address may create new registers. These
- registers will not have valid reg_map entries. This can
- cause try_constants() to fail because assumes that all
- registers in the rtx have valid reg_map entries, and it may
- end up replacing one of these new registers with junk. */
-
- if (! memory_address_p (GET_MODE (temp), XEXP (temp, 0)))
- temp = change_address (temp, GET_MODE (temp), XEXP (temp, 0));
-#endif
-
- temp = XEXP (temp, 0);
- temp = convert_memory_address (GET_MODE (orig), temp);
- return temp;
- }
- else if (GET_CODE (constant) == LABEL_REF)
+ if (GET_CODE (constant) == LABEL_REF)
return XEXP (force_const_mem
(GET_MODE (orig),
copy_rtx_and_substitute (constant, map, for_lhs)),
0);
}
- else if (TREE_CONSTANT_POOL_ADDRESS_P (orig) && inlining)
- notice_rtl_inlining_of_deferred_constant ();
-
return orig;
case CONST_DOUBLE:
@@ -2192,10 +486,6 @@ copy_rtx_and_substitute (rtx orig, struct inline_remap *map, int for_lhs)
CONST_DOUBLE_HIGH (orig), VOIDmode);
case CONST:
- /* Make new constant pool entry for a constant
- that was in the pool of the inline function. */
- if (RTX_INTEGRATED_P (orig))
- abort ();
break;
case ASM_OPERANDS:
@@ -2244,7 +534,8 @@ copy_rtx_and_substitute (rtx orig, struct inline_remap *map, int for_lhs)
break;
#if 0
- /* Must be ifdefed out for loop unrolling to work. */
+ /* Must be ifdefed out for loop unrolling to work. */
+ /* ??? Is this for the old or the new unroller? */
case RETURN:
abort ();
#endif
@@ -2284,46 +575,9 @@ copy_rtx_and_substitute (rtx orig, struct inline_remap *map, int for_lhs)
break;
case MEM:
- if (inlining
- && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
- && CONSTANT_POOL_ADDRESS_P (XEXP (orig, 0)))
- {
- enum machine_mode const_mode
- = get_pool_mode_for_function (inlining, XEXP (orig, 0));
- rtx constant
- = get_pool_constant_for_function (inlining, XEXP (orig, 0));
-
- constant = copy_rtx_and_substitute (constant, map, 0);
-
- /* If this was an address of a constant pool entry that itself
- had to be placed in the constant pool, it might not be a
- valid address. So the recursive call might have turned it
- into a register. In that case, it isn't a constant any
- more, so return it. This has the potential of changing a
- MEM into a REG, but we'll assume that it safe. */
- if (! CONSTANT_P (constant))
- return constant;
-
- return validize_mem (force_const_mem (const_mode, constant));
- }
-
copy = gen_rtx_MEM (mode, copy_rtx_and_substitute (XEXP (orig, 0),
map, 0));
MEM_COPY_ATTRIBUTES (copy, orig);
-
- /* If inlining and this is not for the LHS, turn off RTX_UNCHANGING_P
- since this may be an indirect reference to a parameter and the
- actual may not be readonly. */
- if (inlining && !for_lhs)
- RTX_UNCHANGING_P (copy) = 0;
-
- /* If inlining, squish aliasing data that references the subroutine's
- parameter list, since that's no longer applicable. */
- if (inlining && MEM_EXPR (copy)
- && TREE_CODE (MEM_EXPR (copy)) == INDIRECT_REF
- && TREE_CODE (TREE_OPERAND (MEM_EXPR (copy), 0)) == PARM_DECL)
- set_mem_expr (copy, NULL_TREE);
-
return copy;
default:
@@ -2738,6 +992,7 @@ subst_constants (rtx *loc, rtx insn, struct inline_remap *map, int memonly)
if (op_mode == VOIDmode)
op_mode = GET_MODE (XEXP (x, 1));
+
new = simplify_relational_operation (code, GET_MODE (x), op_mode,
XEXP (x, 0), XEXP (x, 1));
break;
@@ -2766,15 +1021,18 @@ subst_constants (rtx *loc, rtx insn, struct inline_remap *map, int memonly)
{
/* We have compare of two VOIDmode constants for which
we recorded the comparison mode. */
- rtx temp =
- simplify_const_relational_operation (GET_CODE (op0),
- map->compare_mode,
- XEXP (op0, 0),
- XEXP (op0, 1));
-
- if (temp == const0_rtx)
+ rtx tem =
+ simplify_gen_relational (GET_CODE (op0), GET_MODE (op0),
+ map->compare_mode, XEXP (op0, 0),
+ XEXP (op0, 1));
+
+ if (GET_CODE (tem) != CONST_INT)
+ new = simplify_ternary_operation (code, GET_MODE (x),
+ op0_mode, tem, XEXP (x, 1),
+ XEXP (x, 2));
+ else if (tem == const0_rtx)
new = XEXP (x, 2);
- else if (temp == const1_rtx)
+ else
new = XEXP (x, 1);
}
}
@@ -2947,52 +1205,6 @@ set_decl_abstract_flags (tree decl, int setting)
}
}
-/* Output the assembly language code for the function FNDECL from
- its DECL_STRUCT_FUNCTION. Used for inline functions that are output
- at end of compilation instead of where they came in the source. */
-
-static GTY(()) struct function *old_cfun;
-
-void
-output_inline_function (tree fndecl)
-{
- enum debug_info_type old_write_symbols = write_symbols;
- const struct gcc_debug_hooks *const old_debug_hooks = debug_hooks;
- struct function *f = DECL_STRUCT_FUNCTION (fndecl);
-
- old_cfun = cfun;
- cfun = f;
- current_function_decl = fndecl;
-
- set_new_last_label_num (f->inl_max_label_num);
-
- /* We're not deferring this any longer. */
- DECL_DEFER_OUTPUT (fndecl) = 0;
-
- /* If requested, suppress debugging information. */
- if (f->no_debugging_symbols)
- {
- write_symbols = NO_DEBUG;
- debug_hooks = &do_nothing_debug_hooks;
- }
-
- /* Make sure warnings emitted by the optimizers (e.g. control reaches
- end of non-void function) is not wildly incorrect. */
- input_location = DECL_SOURCE_LOCATION (fndecl);
-
- /* Compile this function all the way down to assembly code. As a
- side effect this destroys the saved RTL representation, but
- that's okay, because we don't need to inline this anymore. */
- rest_of_compilation (fndecl);
- DECL_INLINE (fndecl) = 0;
-
- cfun = old_cfun;
- current_function_decl = old_cfun ? old_cfun->decl : 0;
- write_symbols = old_write_symbols;
- debug_hooks = old_debug_hooks;
-}
-
-
/* Functions to keep track of the values hard regs had at the start of
the function. */
@@ -3072,21 +1284,6 @@ has_hard_reg_initial_val (enum machine_mode mode, int regno)
return has_func_hard_reg_initial_val (cfun, gen_rtx_REG (mode, regno));
}
-static void
-setup_initial_hard_reg_value_integration (struct function *inl_f, struct inline_remap *remap)
-{
- struct initial_value_struct *ivs = inl_f->hard_reg_initial_vals;
- int i;
-
- if (ivs == 0)
- return;
-
- for (i = 0; i < ivs->num_entries; i ++)
- remap->reg_map[REGNO (ivs->entries[i].pseudo)]
- = get_func_hard_reg_initial_val (cfun, ivs->entries[i].hard_reg);
-}
-
-
void
emit_initial_value_sets (void)
{
diff --git a/gcc/integrate.h b/gcc/integrate.h
index 94bf2e738d4..88a4f5ddeb7 100644
--- a/gcc/integrate.h
+++ b/gcc/integrate.h
@@ -35,23 +35,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
struct inline_remap
{
- /* True if we are doing function integration, false otherwise.
- Used to control whether RTX_UNCHANGING bits are copied by
- copy_rtx_and_substitute. */
- int integrating;
/* Definition of function be inlined. */
tree fndecl;
/* Place to put insns needed at start of function. */
rtx insns_at_start;
- /* Mapping from old BLOCKs to new BLOCKs. */
- varray_type block_map;
/* Mapping from old registers to new registers.
It is allocated and deallocated in `expand_inline_function' */
rtx *reg_map;
-#if defined (LEAF_REGISTERS) && defined (LEAF_REG_REMAP)
- /* Mapping from old leaf registers to new leaf registers. */
- rtx leaf_reg_map[FIRST_PSEUDO_REGISTER][NUM_MACHINE_MODES];
-#endif
/* Mapping from old code-labels to new code-labels.
The first element of this map is label_map[min_labelno]. */
rtx *label_map;
@@ -85,8 +75,6 @@ struct inline_remap
#define CONST_AGE_PARM (-1)
unsigned int const_age;
- /* Target of the inline function being expanded, or NULL if none. */
- rtx inline_target;
/* When an insn is being copied by copy_rtx_and_substitute,
this is nonzero if we have copied an ASM_OPERANDS.
In that case, it is the original input-operand vector. */
@@ -98,9 +86,6 @@ struct inline_remap
/* Likewise, this is the copied constraints vector. */
rtvec copy_asm_constraints_vector;
- /* Target of a return insn, if needed and inlining. */
- rtx local_return_label;
-
/* Indications for regs being pointers and their alignment. */
unsigned char *regno_pointer_align;
rtx *x_regno_reg_rtx;
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index b63afb35923..bdd1ba6ac8a 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,431 @@
+2004-10-06 Bryce McKinlay <mckinlay@redhat.com>
+
+ * Make-lang.in (verify.o): Re-enabled this target.
+ * verify-glue.c (vfy_get_interface_count): Add ATTRIBUTE_UNUSED.
+ (vfy_get_interface): Likewise.
+ (verify_jvm_instructions_new): Renamed from verify_jvm_instructions.
+ * verify.h (verify_jvm_instructions_new): Declare.
+ * verify-impl.c (free_state): Temporarily comment out unused
+ function.
+
+2004-10-06 Tom Tromey <tromey@redhat.com>
+
+ * java-tree.h (JV_STATE_READ): New enum value.
+
+2004-10-06 Bryce McKinlay <mckinlay@redhat.com>
+
+ * verify.h: New file.
+
+2004-10-05 Bryce McKinlay <mckinlay@redhat.com>
+
+ * verify-impl.c, verify-glue.c, verify.h: New files.
+ * Make-lang.in: Add rules for verify-impl.o and verify-glue.o.
+
+2004-09-24 Andrew Haley <aph@redhat.com>
+
+ * decl.c (check_local_unnamed_variable): Always use the PARM_DECL
+ for a slot if it's of pointer type.
+
+2004-09-14 Tom Tromey <tromey@redhat.com>
+
+ * class.c (make_class_data): Correctly initialize "state" field.
+ Initialize "engine" field.
+ * decl.c (java_init_decl_processing): Add "engine" field.
+
+2004-09-10 Andrew Haley <aph@redhat.com>
+
+ PR java/12760
+ * expr.c (build_invokeinterface): Use fast method for interface
+ dispatch.
+ * java-tree.h (enum java_tree_index): Add JTI_ITABLE_TYPE,
+ JTI_ITABLE_PTR_TYPE.
+ (struct lang_type): Add itable_methods, itable_decl, itable_syms_decl.
+ (emit_symbol_table): Add new arg, element_size.
+ * decl.c (java_init_decl_processing): Initialize Class.itable.
+ * class.c (GEN_TABLE): New macro.
+ (gen_indirect_dispatch_tables): Use it. Add itable.
+ (make_class_data): Add new arg for emit_symbol_table().
+ Emit itable.
+ (add_miranda_methods): Make sure search_class has been parsed.
+ (emit_symbol_table): Add new arg, element_size.
+
+2004-09-06 Andrew Haley <aph@redhat.com>
+
+ * verify.c (merge_types): Return Object for all merges of
+ interfaces.
+ * expr.c (add_type_assertion): Don't generate assertions when
+ source type is array of Object.
+
+2004-09-03 Andrew Haley <aph@redhat.com>
+
+ * class.c (finish_class): Nullify TYPE_VERIFY_METHOD.
+
+ * lang.c (java_post_options): Force flag_verify_invocations if
+ we're not using indirect dispatch.
+
+ * expr.c (pop_type_0): Move test for interfaces before call to
+ can_widen_reference_to().
+ (build_signature_for_libgcj): Remove generation of canonical array
+ type.
+ (add_type_assertion): Canonicalize both arrays.
+ Don't assert that type X can be assigned to Object.
+ Don't assert that type X an be assigned to type X.
+ Don't assert that Object can be assigned to type X.
+ (can_widen_reference_to): Warn whenever we generate an assertion.
+ (process_jvm_instruction): Use throwable_type_node for the type of
+ an exception class.
+
+2004-09-01 Andrew Haley <aph@redhat.com>
+
+ * decl.c (java_init_decl_processing): Change
+ verify_identifier_node to "__verify".
+ * expr.c (add_type_assertion): Use verify_identifier_node for name.
+ * java-tree.h (verify_identifier_node): Change to "__verify".
+
+ * expr.c (build_signature_for_libgcj): New function.
+ (add_type_assertion): Use it to construct signatures for
+ source_type and target_type.
+
+2004-08-27 Andrew Haley <aph@redhat.com>
+
+ * java-tree.h (enum java_tree_index): Add JTI_VERIFY_IDENTIFIER_NODE.
+ (verify_identifier_node): New.
+ (TYPE_VERIFY_METHOD): New.
+ (struct type_assertion): New type.
+ * expr.c (type_assertion_eq): New function.
+ (type_assertion_hash): New function.
+ (add_type_assertion): New function.
+ (can_widen_reference_to): Call add_type_assertion().
+ * decl.c (java_init_decl_processing): Add verify_identifier_node.
+ * class.c (make_class_data): Initialize TYPE_VERIFY_METHOD (type).
+ (finish_class): Output TYPE_VERIFY_METHOD (type).
+
+ * decl.c (end_java_method): Nullify unused fields.
+
+2004-08-17 Andrew Haley <aph@redhat.com>
+
+ * verify.c (defer_merging): Quieten.
+ * jcf-parse.c (load_class): Only try to open a class file if it's
+ java.lang.Object or if it's part of the current compilation.
+ Check that the class we just tried to load is the class we just
+ loaded. Quieten.
+ (java_parse_file): Set flag_verify_invocations off if we're
+ compiling from .class.
+ (parse_zip_file_entries): Abort if we try to read a dummy class.
+ * expr.c (can_widen_reference_to): Quieten.
+ (build_invokevirtual): Abort if we try to invokevirtual an
+ interface.
+ (expand_invoke): Don't build a non-interface call to an interface.
+ (build_instanceof): Don't do premature optimization if
+ flag_verify_invocations is not set.
+ * class.c (set_super_info): Disable code that inherits TYPE_DUMMY
+ from superclass.
+ (build_static_field_ref): Add correct type conversion for
+ field_address.
+ (add_miranda_methods): Disable generation of Miranda methods for
+ dummy classes.
+ (layout_class_method): Don't complain about non-static method
+ overrides static method with dummy classes.
+
+2004-08-13 Tom Tromey <tromey@redhat.com>
+
+ * class.c (build_static_field_ref): Re-enable atable lookups for
+ static fields.
+
+ * parse.y (strip_out_static_field_access_decl): Indentation fix.
+
+2004-08-11 Tom Tromey <tromey@redhat.com>
+
+ * gcj.texi (libgcj Runtime Properties): Document new properties.
+
+2004-08-06 Andrew Haley <aph@redhat.com>
+
+ * jcf-parse.c (load_class): Check that we really have loaded the
+ class we're looking for.
+
+2004-07-19 Andrew Haley <aph@redhat.com>
+
+ * verify.c (verify_jvm_instructions): Comment change only.
+
+ * typeck.c (build_java_array_type): Add size field to array name.
+
+ * java-tree.h (LOCAL_SLOT_P): New.
+ (update_aliases): Add PC argument.
+ (pushdecl_function_level): New function.
+
+ * java-gimplify.c (java_gimplify_expr): Handle VAR_DECL,
+ MODIFY_EXPR, and SAVE_EXPR.
+ (java_gimplify_modify_expr): New function.
+
+ * expr.c (push_type_0): Call find_stack_slot() to create temporary.
+ (expand_iinc): Pass PC to update_aliases().
+ (STORE_INTERNAL): Likewise.
+ (process_jvm_instruction): Likewise.
+
+ * decl.c (base_decl_map): New variable.
+ (uniq): New variable.
+ (update_aliases): Rewrite with more thorough checking.
+ (debug_variable_p): New function.
+ (push_jvm_slot): Don't initialize local variable. Don't pushdecl.
+ (check_local_named_variable): Delete whole function.
+ (initialize_local_variable): New function.
+ (check_local_unnamed_variable): Add checks and comments.
+ (find_local_variable): Rewrite.
+ (java_replace_reference): New function.
+ (function_binding_level): New variable.
+ (pushdecl_function_level): New function.
+ (maybe_pushlevels): Set DECL_LOCAL_END_PC.
+ (maybe_pushlevels): Call pushdecl() on each of the new decls.
+ (start_java_method): Reset uniq. Create base_decl_map. Set
+ function_binding_level.
+ (end_java_method): Null unused fields to save memory.
+
+2004-06-29 Andrew Haley <aph@redhat.com>
+
+ * except.c (expand_start_java_handler): Push a new binding level.
+ Don't build a TRY_CATCH_EXPR now, we'll do it later. Call
+ register_exception_range() to register where we'll do it.
+ (expand_end_java_handler): Remove old bogus code. Replace with
+ new logic that simply builds TRY_CATCH_EXPRs and inserts them at
+ the top of the expression we're curently building.
+ (maybe_end_try): Delete.
+ * decl.c (binding_level.exception_range): New field.
+ (clear_binding_level): Add field exception_range. Reformat.
+ (poplevel): Call expand_end_java_handler().
+ (poplevel): Call java_add_stmt only if functionbody is false.
+ (maybe_poplevels): Don't call maybe_end_try() from here.
+ (end_java_method): Clear no longer used trees in function decl.
+ (register_exception_range): New function.
+ * java-tree.h (register_exception_range, struct eh_range): Declare.
+
+2004-06-22 Andrew Haley <aph@redhat.com>
+
+ * class.c (gen_indirect_dispatch_tables): Set the DECL_OWNER of
+ the otable.
+ * check-init.c (get_variable_decl): Teach check-init about
+ FIELD_DECLs addressed via the otable.
+ * jcf-parse.c (load_class): Check CLASS_LOADED_P, not
+ CLASS_PARSED_P.
+
+2004-05-28 Andrew Haley <aph@redhat.com>
+
+ * jcf-parse.c (load_class): Don't try to read a class that we've
+ already read.
+
+ * expr.c (build_invokeinterface): Use the old-fashioned way of
+ doing indirect dispatch: look up interfaces by name.
+ * java-tree.h (enum java_tree_index): Add
+ JTI_SOFT_LOOKUPINTERFACEMETHODBYNAME_NODE
+ * decl.c (java_init_decl_processing): Add
+ soft_lookupinterfacemethodbyname_node.
+
+ * gjavah.c (print_method_info): Final methods have vtable entries,
+ so gjavah needs to output them.
+ * class.c (layout_class_method): Generate vtable entries for final
+ methods.
+ * parse.y (invocation_mode): Use INVOKE_VIRTUAL for indirect
+ dispatch, even if a method is final.
+
+2004-05-25 Andrew Haley <aph@redhat.com>
+
+ * class.c (build_symbol_entry): Convert the names of constructors
+ to init_identifier_node when generating an entry for the indirect
+ dispatch table.
+
+ * expr.c (build_known_method_ref): Generate indirect calls for
+ all methods marked DECL_EXTERNAL or TREE_PUBLIC.
+
+2004-05-24 Andrew Haley <aph@redhat.com>
+
+ * expr.c (build_known_method_ref): Make sure ARRAY_REF access to
+ atable element is of the right type.
+
+ * class.c (build_static_field_ref): Cast pointer to correct type
+ for field.
+
+2004-04-20 Bryce McKinlay <mckinlay@redhat.com>
+
+ * Merged with HEAD as of 20040514. Diff against
+ gcj-abi-2-merge-20040514.
+
+2004-04-16 Andrew Haley <aph@redhat.com>
+
+ * verify.c (check_pending_block): Disable subroutine checks.
+ (defer_merging): New function.
+ (merge_types): If types are dummy, use defer_merging to combine them.
+ (verify_jvm_instructions): If invocation is invokeinterface and
+ target is dummy, assume target really is an interface.
+
+ * parse.y (patch_invoke): Break out call to java_create_object.
+
+ * lang.c (flag_verify_invocations): New.
+
+ * jcf-parse.c (load_class): If we've already failed to load a
+ class, don't try again.
+ (load_class): If we can't find a .class file, don't fail, but emit
+ a warning.
+ (parse_class_file): Don't act on dummy methods.
+
+ * java-tree.h (flag_verify_invocations): New.
+ (TYPE_DUMMY): New.
+ (lang_type.dummy_class): New field.
+ (java_create_object): New function.
+ (METHOD_DUMMY): New.
+
+ * expr.c (build_field_ref): Widen field offset.
+ (pop_type_0): If the type in stack_type_map is a TREE_LIST, check
+ that each of its elements is compatible with the one we're
+ popping.
+ (pop_type_0): Issue a warning to say that we need to generate a
+ runtime check.
+ (java_create_object): New function.
+ (build_field_ref): Only generate hard refs if we're not using
+ indirect dispatch.
+ (expand_java_field_op): If we're using !verify_invocations and we
+ see a missing field, generate a decl for it.
+
+ (expand_invoke): If a class doesn't have the method we seek and
+ we're using !flag_verify_invocations, generate a decl for the
+ method now.
+
+ (build_known_method_ref): Always use indirect dispatch via the
+ atable for static methods.
+
+ (expand_java_NEW): Break out object creation into new function,
+ java_create_object.
+
+ (can_widen_reference_to): Issue a warning to say that we need to
+ generate a runtime check.
+
+ * class.c (set_super_info): Inherit TYPE_DUMMY from sureclass.
+ (make_method_value): Also use index for interfaces.
+ (make_class_data): Skip dummy field for inherited data.
+ Don't build method array for dummy methods.
+ Set size_in_byte to -1 when using inirect dispatch
+ Don't build a hard class ref if we don't have a hard ref to our
+ superclass, or if we're using inirect dispatch.
+ Null out dispatch tables.
+
+ (layout_class_method): Don't complain about non-static method
+ overrides static method is method is artificial.
+
+ (build_static_field_ref): Disable atable references to static
+ fields for the time being.
+
+ (layout_class_methods): Check for CLASS_INTERFACE as
+ well as CLASS_ABSTRACT.
+
+2004-05-13 Diego Novillo <dnovillo@redhat.com>
+
+ * Make-lang.in, expr.c, java-gimplify.c: Rename
+ tree-simple.[ch] to tree-gimple.[ch].
+
+2004-05-14 Ranjit Mathew <rmathew@hotmail.com>
+
+ * java-gimplify.c (java_gimplify_expr): Correct minor typos.
+
+2004-05-13 Diego Novillo <dnovillo@redhat.com>
+
+ Merge from tree-ssa-20020619-branch. See
+ ChangeLog.tree-ssa for details.
+
+ * Make-lang.in, builtins.c, check-init.c, class.c,
+ constants.c, decl.c, except.c, expr.c, java-except.h,
+ java-tree.def, java-tree.h, jcf-parse.c, jcf-write.c,
+ lang.c, lang.opt, parse.y, resource.c: Merged.
+ * java-gimplify.c: New file.
+
+2004-05-10 Andrew Haley <aph@redhat.com>
+
+ * parse.y (create_class): Set TYPE_VFIELD.
+ * decl.c (java_init_decl_processing): Likewise.
+
+ * expr.c (build_invokevirtual): Remove DECL_VINDEX offset adjustment.
+ * class.c (make_method_value): Replace DECL_VINDEX with call to
+ get_method_index().
+ (get_dispatch_vector): Likewise.
+ (layout_class_method): Likewise.
+ Replace set of DECL_VINDEX with call to set_method_index().
+ (set_method_index): New function.
+ (get_method_index): New function.
+ * java-tree.h (set_method_index): New function decl.
+ (get_method_index): New function decl.
+
+2004-05-10 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * parse.y (check_pkg_class_access): Add new argument
+ and use it when cl is NULL to call lookup_cl on it.
+ (parser_check_super_interface): Do not call lookup_cl.
+ Pass this_decl to check_pkg_class_access and NULL
+ instead of lookup_cl.
+ (parser_check_super): Update for change in
+ check_pkg_class_access.
+ (do_resolve_class): Likewise.
+ (process_imports): Likewise.
+ (find_in_imports_on_demand): Likewise.
+ (resolve_qualified_expression_name): Likewise.
+
+2004-05-06 Ranjit Mathew <rmathew@hotmail.com>
+
+ Fixes PR java/9685, PR java/15073
+ * parse.y (accessibility_string): New method.
+ (not_accessible_field_error): Use accessibility_string()
+ instead of java_accstring_lookup().
+ (resolve_qualified_expression_name): Check with
+ check_pkg_class_access() before allowing access using
+ qualified names.
+ Fix comment typo.
+ Use check_pkg_class_access() instead of not_accessible_p()
+ for unqualified types.
+ (not_accessible_p): Use DECL_CONTEXT (member) instead of
+ REFERENCE for package-private access checking.
+ (patch_method_invocation): Use accessibility_string() instead
+ of java_accstring_lookup().
+
+2004-04-30 Ranjit Mathew <rmathew@hotmail.com>
+
+ Fixes PR java/15133
+ * gjavah.c (struct method_name): Add member is_native.
+ (overloaded_jni_method_exists_p): Match candidate method only if
+ it is native.
+ (print_method_info): Initialise is_native flag from the method's
+ access flags.
+
+2004-04-30 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (java_builtins): Add acos, asin, ceil and floor.
+ (initialize_builtins): Likewise, define acos, asin, ceil and floor.
+
+2004-04-22 Roger Sayle <roger@eyesopen.com>
+
+ * resource.c (write_resource_constructor): Guard call to possibly
+ NULL targetm.asm_out.constructor with targetm.have_ctors_dtors.
+
+2004-04-19 Bryce McKinlay <mckinlay@redhat.com>
+
+ * class.c (make_class_data): Add new field aux_info.
+ * decl.c (java_init_decl_processing): Push type and decl for
+ `aux_info'.
+
+2004-04-15 Bryce McKinlay <mckinlay@redhat.com>
+
+ * expr.c (expand_java_NEW): Don't use size argument for
+ _Jv_AllocObject calls.
+ * parse.y (patch_invoke): Likewise.
+
+2004-04-12 Bryce McKinlay <mckinlay@redhat.com>
+
+ * expr.c (build_invokeinterface): Remove unused variables to
+ fix warnings.
+
+2004-04-12 Bryce McKinlay <mckinlay@redhat.com>
+
+ * class.c (get_interface_method_index): New function. Return dispatch
+ index for interface method.
+ (make_method_value): For interface methods, set index field to
+ iface dispatch index, not DECL_VINDEX.
+ * expr.c (build_invokeinterface): Use get_interface_method_index.
+
2004-03-31 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* jcf-write.c (generate_bytecode_insns): Use TYPE_UNSIGNED.
diff --git a/gcc/java/ChangeLog.tree-ssa b/gcc/java/ChangeLog.tree-ssa
new file mode 100644
index 00000000000..81081a52860
--- /dev/null
+++ b/gcc/java/ChangeLog.tree-ssa
@@ -0,0 +1,360 @@
+2004-05-10 Andrew Haley <aph@redhat.com>
+
+ * java-gimplify.c (java_gimplify_expr): Copy the LHS of a binary
+ expression into a temporary variable.
+
+ (java_gimplify_new_array_init): Set the DECL_CONTEXT of array and
+ tmp to current_function_decl.
+
+2004-04-13 Diego Novillo <dnovillo@redhat.com>
+
+ * expr.c (build_expr_wfl): Don't check type nodes for
+ side effects.
+
+2004-04-12 Diego Novillo <dnovillo@redhat.com>
+
+ * decl.c (java_expand_stmt): Remove.
+ * lang.c (LANG_HOOKS_RTL_EXPAND_STMT): Remove.
+
+2004-02-24 Richard Henderson <rth@redhat.com>
+
+ * java-gimplify.c (java_gimplify_new_array_init): Remove extra
+ argument building BLOCK.
+
+2004-02-19 Steven Bosscher <stevenb@suse.de>
+
+ * decl.c (poplevel): Don't output nested inline functions.
+
+2004-02-16 Richard Henderson <rth@redhat.com>
+
+ * builtins.c (java_build_function_call_expr): Add static chain
+ operand to call_expr.
+
+2004-01-29 Richard Henderson <rth@redhat.com>
+
+ PR java/12906
+ * decl.c (maybe_pushlevels): Careful with TREE_CHAIN when
+ registering decls with push_jvm_slot.
+
+2003-12-10 Diego Novillo <dnovillo@redhat.com>
+
+ * parse.y (resolve_field_access): Remove superfluous
+ initialization of decl.
+
+2003-12-10 Richard Henderson <rth@redhat.com>
+
+ * lang.c (java_post_options): Don't ever use rtl inlining.
+
+2003-12-06 Jan Hubicka <jh@suse.cz>
+
+ * parse.y (resolve_field_access): Initialize decl.
+
+2003-11-31 Richard Henderson <rth@redhat.com>
+
+ * lang.c (java_start_inlining): Remove.
+ (LANG_HOOKS_TREE_INLINING_START_INLINING): Remove.
+
+2003-11-31 Richard Henderson <rth@redhat.com>
+
+ * jcf-parse.c (java_parse_file): Finalize cgraph after emitting
+ class tables.
+
+2003-11-24 Richard Henderson <rth@redhat.com>
+
+ * Make-lang.in (parse.o): Remove -Wno-error.
+
+2003-11-20 Richard Henderson <rth@redhat.com>
+
+ * constants.c (build_constant_data_ref): Lay out the array type.
+
+2003-11-20 Richard Henderson <rth@redhat.com>
+
+ * class.c (build_indirect_class_ref): Use convert.
+ * constants.c (build_constant_data_ref): Fix type on the decl
+ and return that directly.
+ (build_constants_constructor): Remove kruft to match.
+ (build_ref_from_constant_pool): Use ARRAY_REF.
+ * expr.c (build_java_indirect_ref): Use convert.
+ (build_known_method_ref): Likewise.
+ * parse.y (patch_string_cst): Likewise.
+
+ * class.c (finish_class): Kill code to output_inline_function.
+
+2003-11-12 Jason Merrill <jason@redhat.com>
+
+ PR optimization/12547
+ * lang.c (java_tree_inlining_walk_subtrees): Restore.
+ (LANG_HOOKS_TREE_INLINING_WALK_SUBTREES): Restore.
+
+2003-11-12 Richard Henderson <rth@redhat.com>
+
+ * java-gimplify.c (java_gimplify_expr): Use annotate_with_locus
+ instead of annotate_all_with_locus.
+
+2003-11-10 Richard Henderson <rth@redhat.com>
+
+ * expr.c: Use append_to_statement_list instead of add_tree.
+
+2003-10-30 Richard Henderson <rth@redhat.com>
+
+ * java-gimplify.c (cleanup_compound_expr): Remove.
+ (cleanup_try_finally_expr): Remove.
+ (java_gimplify_expr): Don't call them.
+ (java_gimplify_case_expr): Use create_artificial_label.
+ (java_gimplify_default_expr): Likewise.
+
+2003-10-30 Richard Henderson <rth@redhat.com>
+
+ * expr.c (expand_java_switch, expand_java_add_case): New.
+ (LOOKUP_SWITCH, TABLE_SWITCH): Use them.
+
+2003-10-23 Richard Henderson <rth@redhat.com>
+
+ * java-gimplify.c (java_gimplify_expr): Return gimplify_status.
+
+2003-10-14 Richard Henderson <rth@redhat.com>
+
+ * decl.c (finish_method): Set cfun->function_end_locus.
+ * java-gimplify.c (java_gimplify_expr): Set input_location
+ for EXPR_WITH_FILE_LOCATION. Use annotate_all_with_locus.
+ * parse.h (DECL_SOURCE_LINE_MERGE): Remove.
+ (DECL_SOURCE_LINE_FIRST, DECL_SOURCE_LINE_LAST): Remove.
+ * parse.y (missing_return_error): Use DECL_FUNCTION_LAST_LINE.
+ (finish_method_declaration): Likewise.
+ (start_artificial_method_body): Likewise.
+ (lookup_cl): Use DECL_SOURCE_LINE.
+ (start_complete_expand_method): Likewise.
+ (java_complete_lhs): Fix IS_EXPR_CODE_CLASS check.
+
+2003-10-13 Richard Henderson <rth@redhat.com>
+
+ * decl.c (java_add_stmt): Use annotate_with_locus.
+
+2003-10-13 Richard Henderson <rth@redhat.com>
+
+ * expr.c (build_java_jsr): Don't emit LABEL_EXPR or
+ load_type_state here.
+
+2003-10-12 Richard Henderson <rth@redhat.com>
+
+ * class.c (build_utf8_ref, get_dispatch_table): Set TREE_INVARIANT.
+ (make_class_data, build_symbol_entry, emit_symbol_table): Likewise.
+ * decl.c (java_init_decl_processing): Likewise.
+ * except.c (prepare_eh_table_type): Likewise.
+ * parse.y (patch_assignment, patch_binop): Likewise.
+ (patch_string_cst, patch_new_array_init): Likewise.
+ * resource.c (compile_resource_data): Likewise.
+
+2003-10-08 Jeff Sturm <jsturm@one-point.com>
+
+ * decl.c (cgraph.h): Include.
+ (tree-inline.h, tree-dump.h, tree-flow.h): Remove includes.
+ (complete_start_java_method): Remove.
+ (start_java_method): Combine with complete_start_java_method.
+ Remove dead code.
+ (end_java_method): Don't patch or expand tree.
+ Use finish_method.
+ (finish_method): New function.
+ (java_expand_body): Use tree_rest_of_compilation.
+ (java_expand_stmt): New function.
+
+ * java-gimplify.c (tree-dump.h): Include.
+ (java_genericize): New function.
+ (dump_java_tree): Declare. New function.
+
+ * java-tree.h (start_complete_expand_method): Remove declaration.
+ (complete_start_java_method): Remove declaration.
+ (finish_method, java_expand_stmt, java_genericize): Declare.
+
+ * lang.c (LANG_HOOKS_RTL_EXPAND_STMT): Define.
+
+ * parse.y (tree-inline.h, tree-dump.h, tree-flow.h,
+ cgraph.h): Remove includes.
+ (start_complete_expand_method): Declare.
+ (source_end_java_method): Don't expand tree. Use finish_method.
+ Reset current_function_decl.
+ (java_expand_method_bodies): Don't patch tree for class
+ initialization or method synchronization.
+
+2003-10-01 Richard Henderson <rth@redhat.com>
+
+ * decl.c (end_java_method): Invoke remove_useless_stmts_and_vars
+ and lower_eh_constructs.
+ * parse.y (source_end_java_method): Likewise.
+
+2003-09-24 Jason Merrill <jason@redhat.com>
+
+ * decl.c, jcf-parse.c, jcf-write.c, parse.h, parse.y, resource.c:
+ Revert from TREE_LOCUS to DECL_SOURCE_LOCATION.
+
+2003-09-18 Richard Henderson <rth@redhat.com>
+
+ * lang.c (java_estimate_num_insns): Take an expr, not a decl.
+
+2003-08-12 Diego Novillo <dnovillo@redhat.com>
+
+ * java-gimplify.c (java_gimplify_block): If the body is a
+ NULL_TREE, return an empty statement.
+
+2003-08-08 Jason Merrill <jason@redhat.com>
+
+ * parse.y (source_end_java_method): Support
+ !keep_function_tree_in_gimple_form.
+ Do TDI_generic dump.
+
+2003-07-31 Andrew Haley <aph@redhat.com>
+
+ * java-tree.h: (add_stmt_to_compound): New function.
+ (java_add_stmt): New function.
+ (java_add_local_var): New function.
+ (get_stmts): New function.
+ * java-gimplify.c (java_gimplify_block): Allow for null body.
+ * except.c (link_handler): Set h->stmt.
+ (expand_start_java_handler): Build a TRY_CATCH_EXPR for this
+ range; don't expand_eh_region_start.
+ (expand_end_java_handler): Rewrite.
+ * java-except.h (stmt): New field.
+ * expr.c (flush_quick_stack): Replace expand_assignment with
+ java_add_stmt.
+ (java_stack_dup): Replace emit_move_insn with java_add_stmt.
+ (build_java_athrow): Replace expand_expr_stmt with java_add_stmt.
+ (build_java_jsr): Replace emit_jump with java_add_stmt (build (GOTO_EXPR))
+ (build_java_ret): Replace expand_computed_goto with
+ java_add_stmt (build (GOTO_EXPR))
+ (expand_java_arraystore): Replace expand_assignment with
+ java_add_stmt.
+ (expand_java_return): Replace expand_return with
+ java_add_stmt (build (RETURN_EXPR))
+ (expand_load_internal): Remove layout_decl, DECL_REGISTER,
+ expand_decl, and expand_decl_init. Instead, add the local
+ variable and a MODIFY_EXPR to the current tree.
+ (expand_iinc): Replace expand_assignment with
+ java_add_stmt.
+ (expand_compare): Replace expand_cond with
+ java_add_stmt(build (COND_EXPR))
+ (expand_java_goto): Replace expand_goto with
+ java_add_stmt (build (GOTO_EXPR))
+ (expand_invoke): Replace expand_expr_stmt with java_add_stmt.
+ (build_jni_stub): Generate a BIND_EXPR to hold the block we've
+ created. Don't distinguish between source and byte compiler.
+ (expand_java_field_op): Replace expand_assignment with
+ java_add_stmt.
+ (java_expand_expr): Abort. No-one should call this function any
+ more.
+ (expand_byte_code): Replace expand_label with
+ java_add_stmt (build (LABEL_EXPR))
+ (process_jvm_instruction): Replace build (JAVA_EXC_OBJ_EXPR) with
+ build_exception_object_ref. Replace expand_assignment with
+ java_add_stmt.
+ * except.c (link_handler): Null stmt field.
+ (expand_start_java_handler): Don't expand_eh_region_start.
+ Instead, generate a TRY_CATCH_EXPR and insert it into the tree
+ we're building.
+ (expand_end_java_handler): Don't expand_start_all_catch. Instead,
+ build a TRY_FINALLY_EXPR and wrap the catch block with it.
+ Don't expand_end_all_catch.
+ * decl.c (push_jvm_slot): Call pushdecl().
+ (find_local_variable): Give symbolic names to unnamed local
+ variables.
+ (struct binding_level: stmts): New field.
+ (poplevel): If any statements have been generated at this level,
+ create a BIND_EXPR to hold them and copy the variables to it. If
+ we are at the outermost level, save this BIND_EXPR in the
+ DECL_SAVED_TREE of this function.
+ (maybe_pushlevels): Don't expand_start_bindings.
+ (maybe_poplevels): Don't expand_end_bindings.
+ (complete_start_java_method): Reorganize static initialization and
+ synchronization logic for source compiler. Remove pushlevel and
+ expand_start_bindings for byte compiler.
+ (end_java_method): Don't expand_end_bindings. Add static
+ initialization and synchronization logic for byte compiler.
+ Set cfun->x_whole_function_mode_p.
+ Call gimplify_function_tree and optimize_function_tree and
+ expand_expr_stmt.
+ (add_stmt_to_compound): New.
+ (java_add_stmt): New.
+ (java_add_local_var): New.
+ (get_stmts): New.
+ * parse.y (add_stmt_to_compound): Remove.
+ * jcf-parse.c (parse_class_file): Don't call expand_expr_stmt for
+ a native method -- we'll do that later.
+
+2003-07-27 Andreas Jaeger <aj@suse.de>
+
+ * expr.c (build_expr_wfl): Convert remaining K&R prototypes
+ to ISO C90.
+
+2003-06-28 Jeff Sturm <jsturm@one-point.com>
+
+ * java-gimplify.c (java_gimplify_block): Rebuild BLOCK_SUBBLOCKS.
+ * lang.c (flag_disable_gimple): Remove initialization.
+
+2003-06-23 Jeff Law <law@redhat.com>
+
+ * Make-lang.in (java-gimplify.o): Add dependencies.
+
+2003-06-22 Jeff Sturm <jsturm@one-point.com>
+
+ * parse.y (source_end_java_method): Don't attempt to inline
+ or optimize trees if flag_disable_gimple.
+
+ * Make-lang.in (JAVA_OBJS): Remove java-tree-inline.o.
+
+2003-06-21 Jeff Sturm <jsturm@one-point.com>
+
+ * Make-lang.in (JAVA_OBJS): Add java-gimplify.o.
+
+ * decl.c (java_init_decl_processing): Initialize size_type_node.
+ (complete_start_java_method): Update DECL_SAVED_TREE.
+ (dump_function): Remove.
+ (java_optimize_inline): Remove.
+
+ * expr.c (always_initialize_class_p): Initialize to 1.
+ (build_instanceof): Build proper boolean condition.
+ (build_class_init): Set DECL_INITIAL for init_test_decl.
+ (force_evaluation_order): Don't save_expr a void expr node.
+
+ * java-gimplify.c: New file.
+
+ * java-tree.h (java_gimplify_expr): Declare.
+
+ * lang.c (java_tree_inlining_walk_subtrees): Remove declaration.
+ (flag_optimize_sci): Initialize to 0.
+ (LANG_HOOKS_TREE_INLINING_WALK_SUBTREES): Remove define.
+ (LANG_HOOKS_SIMPLIFY_EXPR): Add define.
+ (java_tree_inlining_walk_subtrees): Remove function.
+ (java_init): Set flag_disable_gimple to 1.
+
+ * parse.y (source_end_java_method): Set cfun->x_whole_function_mode_p.
+ Gimplify. Optimize tree before expanding. Update comments.
+ (java_expand_method_bodies): Always save DECL_SAVED_TREE.
+ (patch_invoke): Don't save_expr force_evaluation_order result.
+ (patch_assignment): Use simpler compound expression.
+ (patch_if_else_statement): Don't optimize constant condition nodes.
+
+2003-03-02 Diego Novillo <dnovillo@redhat.com>
+
+ * class.c: Replace DECL_SOURCE_FILE with TREE_FILENAME and
+ DECL_SOURCE_LINE with TREE_LINENO everywhere.
+
+2003-02-03 Diego Novillo <dnovillo@redhat.com>
+
+ * parse.y (qualify_ambiguous_name): Initialize variable 'decl'.
+
+2003-01-15 Jeff Law <law@redhat.com>
+
+ * class.c: Use TREE_FILENAME and TREE_LINENO to extract file/line
+ information from tree nodes. Use annotate_with_file_line to
+ annotate tree nodes with file/line information.
+ * decl.c, jcf-parse.c, jcf-write.c, parse.h: Likewise.
+ * parse.y: Likewise.
+ * expr.c (java_expand_expr): Handle EXPR_WITH_FILE_LOCATION nodes.
+ (build_expr_wfl): New function.
+ * java-tree.def (EXPR_WITH_FILE_LOCATION): New node.
+ * java-tree.h (EXPR_WFL_*): New macros.
+ (build_expr_wfl): Declare.
+
+Local Variables:
+mode: change-log
+change-log-default-name: "ChangeLog.tree-ssa"
+End:
diff --git a/gcc/java/Make-lang.in b/gcc/java/Make-lang.in
index fad423ae255..e29c750e40d 100644
--- a/gcc/java/Make-lang.in
+++ b/gcc/java/Make-lang.in
@@ -102,10 +102,11 @@ gt-java-builtins.h gtype-java.h gt-java-resource.h : s-gtype ; @true
# Executables built by this Makefile:
JAVA_OBJS = java/parse.o java/class.o java/decl.o java/expr.o \
java/constants.o java/lang.o java/typeck.o java/except.o java/verify.o \
+ java/verify-glue.o java/verify-impl.o \
java/zextract.o java/jcf-io.o java/win32-host.o java/jcf-parse.o java/mangle.o \
java/mangle_name.o java/builtins.o java/resource.o \
java/jcf-write.o java/buffer.o java/check-init.o java/jcf-depend.o \
- java/jcf-path.o java/xref.o java/boehm.o java/java-tree-inline.o mkdeps.o
+ java/jcf-path.o java/xref.o java/boehm.o java/java-gimplify.o mkdeps.o
GCJH_OBJS = java/gjavah.o java/jcf-io.o java/jcf-depend.o java/jcf-path.o \
java/win32-host.o java/zextract.o version.o mkdeps.o errors.o ggc-none.o \
@@ -329,10 +330,17 @@ java/win32-host.o: java/win32-host.c $(CONFIG_H) $(SYSTEM_H) java/jcf.h
java/verify.o: java/verify.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h \
java/javaop.h java/java-opcodes.h java/java-except.h toplev.h $(SYSTEM_H) \
coretypes.h $(TM_H)
+java/verify-glue.o: java/verify-glue.c $(CONFIG_H) $(SYSTEM_H) $(JAVA_TREE_H) \
+ coretypes.h $(TM_H) java/verify.h
+java/verify-impl.o: java/verify-impl.c $(CONFIG_H) java/verify.h $(SYSTEM_H) \
+ coretypes.h java/jcf.h $(JAVA_TREE_H)
java/xref.o: java/xref.c java/xref.h $(CONFIG_H) $(JAVA_TREE_H) toplev.h \
$(SYSTEM_H) coretypes.h $(TM_H)
java/zextract.o: java/zextract.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
java/zipfile.h
+java/java-gimplify.o: java/java-gimplify.c $(CONFIG_H) $(SYSTEM_H) \
+ coretypes.h $(TM_H) $(JAVA_TREE_H) tree-gimple.h toplev.h
+
java/parse-scan.o: java/parse-scan.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) toplev.h $(JAVA_LEX_C) java/parse.h java/lex.h input.h
java/parse.o: java/parse.c java/jcf-reader.c $(CONFIG_H) $(SYSTEM_H) \
diff --git a/gcc/java/builtins.c b/gcc/java/builtins.c
index 563bd8daad2..77f0c582105 100644
--- a/gcc/java/builtins.c
+++ b/gcc/java/builtins.c
@@ -74,10 +74,14 @@ static GTY(()) struct builtin_record java_builtins[] =
{ { "java.lang.Math" }, { "min" }, min_builtin, 0 },
{ { "java.lang.Math" }, { "max" }, max_builtin, 0 },
{ { "java.lang.Math" }, { "abs" }, abs_builtin, 0 },
+ { { "java.lang.Math" }, { "acos" }, NULL, BUILT_IN_ACOS },
+ { { "java.lang.Math" }, { "asin" }, NULL, BUILT_IN_ASIN },
{ { "java.lang.Math" }, { "atan" }, NULL, BUILT_IN_ATAN },
{ { "java.lang.Math" }, { "atan2" }, NULL, BUILT_IN_ATAN2 },
+ { { "java.lang.Math" }, { "ceil" }, NULL, BUILT_IN_CEIL },
{ { "java.lang.Math" }, { "cos" }, NULL, BUILT_IN_COS },
{ { "java.lang.Math" }, { "exp" }, NULL, BUILT_IN_EXP },
+ { { "java.lang.Math" }, { "floor" }, NULL, BUILT_IN_FLOOR },
{ { "java.lang.Math" }, { "log" }, NULL, BUILT_IN_LOG },
{ { "java.lang.Math" }, { "pow" }, NULL, BUILT_IN_POW },
{ { "java.lang.Math" }, { "sin" }, NULL, BUILT_IN_SIN },
@@ -120,7 +124,7 @@ java_build_function_call_expr (tree fn, tree arglist)
call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
- call_expr, arglist);
+ call_expr, arglist, NULL_TREE);
TREE_SIDE_EFFECTS (call_expr) = 1;
return fold (call_expr);
}
@@ -186,14 +190,22 @@ initialize_builtins (void)
define_builtin (BUILT_IN_FMODF, "__builtin_fmodf",
float_ftype_float_float, "fmodf");
+ define_builtin (BUILT_IN_ACOS, "__builtin_acos",
+ double_ftype_double, "_ZN4java4lang4Math4acosEd");
+ define_builtin (BUILT_IN_ASIN, "__builtin_asin",
+ double_ftype_double, "_ZN4java4lang4Math4asinEd");
define_builtin (BUILT_IN_ATAN, "__builtin_atan",
double_ftype_double, "_ZN4java4lang4Math4atanEd");
define_builtin (BUILT_IN_ATAN2, "__builtin_atan2",
double_ftype_double_double, "_ZN4java4lang4Math5atan2Edd");
+ define_builtin (BUILT_IN_CEIL, "__builtin_ceil",
+ double_ftype_double, "_ZN4java4lang4Math4ceilEd");
define_builtin (BUILT_IN_COS, "__builtin_cos",
double_ftype_double, "_ZN4java4lang4Math3cosEd");
define_builtin (BUILT_IN_EXP, "__builtin_exp",
double_ftype_double, "_ZN4java4lang4Math3expEd");
+ define_builtin (BUILT_IN_FLOOR, "__builtin_floor",
+ double_ftype_double, "_ZN4java4lang4Math5floorEd");
define_builtin (BUILT_IN_LOG, "__builtin_log",
double_ftype_double, "_ZN4java4lang4Math3logEd");
define_builtin (BUILT_IN_POW, "__builtin_pow",
diff --git a/gcc/java/check-init.c b/gcc/java/check-init.c
index c4e39484410..87c4c35b95b 100644
--- a/gcc/java/check-init.c
+++ b/gcc/java/check-init.c
@@ -191,6 +191,50 @@ get_variable_decl (tree exp)
return op1;
}
}
+ else if (TREE_CODE (exp) == INDIRECT_REF)
+ {
+ /* For indirect dispatch, look for an expression of the form
+ (indirect_ref (+ (array_ref otable <N>) this)).
+ FIXME: it would probably be better to generate a JAVA_FIELD_REF
+ expression that gets converted to OTABLE access at
+ gimplification time. */
+ exp = TREE_OPERAND (exp, 0);
+ if (TREE_CODE (exp) == PLUS_EXPR)
+ {
+ tree op0 = TREE_OPERAND (exp, 0);
+ STRIP_NOPS (op0);
+ if (TREE_CODE (op0) == ARRAY_REF)
+ {
+ tree table = TREE_OPERAND (op0, 0);
+ if (TREE_CODE (table) == VAR_DECL
+ && DECL_LANG_SPECIFIC (table)
+ && DECL_OWNER (table)
+ && TYPE_OTABLE_DECL (DECL_OWNER (table)) == table)
+ {
+ HOST_WIDE_INT index
+ = TREE_INT_CST_LOW (TREE_OPERAND (op0, 1));
+ tree otable_methods
+ = TYPE_OTABLE_METHODS (DECL_OWNER (table));
+ tree element;
+ for (element = otable_methods;
+ element;
+ element = TREE_CHAIN (element))
+ {
+ if (index == 1)
+ {
+ tree purpose = TREE_PURPOSE (element);
+ if (TREE_CODE (purpose) == FIELD_DECL)
+ return purpose;
+ else
+ return NULL_TREE;
+ }
+ --index;
+ }
+ }
+ }
+ }
+ }
+
return NULL_TREE;
}
@@ -770,7 +814,7 @@ check_init (tree exp, words before)
break;
case NOP_EXPR:
- if (exp == empty_stmt_node)
+ if (IS_EMPTY_STMT (exp))
break;
/* ... else fall through ... */
case UNARY_PLUS_EXPR:
@@ -889,7 +933,7 @@ check_init (tree exp, words before)
location_t saved_location = input_location;
tree saved_wfl = wfl;
tree body = EXPR_WFL_NODE (exp);
- if (body == empty_stmt_node)
+ if (IS_EMPTY_STMT (body))
break;
wfl = exp;
input_filename = EXPR_WFL_FILENAME (exp);
diff --git a/gcc/java/class.c b/gcc/java/class.c
index 66bdeb934fd..b045bdcd79b 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -43,6 +43,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "stdio.h"
#include "target.h"
#include "except.h"
+#include "cgraph.h"
/* DOS brain-damage */
#ifndef O_BINARY
@@ -348,8 +349,38 @@ unmangle_classname (const char *name, int name_length)
return to_return;
}
-
-/* Given a class, create the DECLs for all its associated indirect dispatch tables. */
+#define GEN_TABLE(TABLE, NAME, TABLE_TYPE, TYPE) \
+do \
+{ \
+ const char *typename = IDENTIFIER_POINTER (mangled_classname ("", TYPE)); \
+ char *buf = alloca (strlen (typename) + strlen (#NAME "_syms_") + 1); \
+ tree decl; \
+ \
+ sprintf (buf, #NAME "_%s", typename); \
+ TYPE_## TABLE ##_DECL (type) = decl = \
+ build_decl (VAR_DECL, get_identifier (buf), TABLE_TYPE); \
+ DECL_EXTERNAL (decl) = 1; \
+ TREE_STATIC (decl) = 1; \
+ TREE_READONLY (decl) = 1; \
+ TREE_CONSTANT (decl) = 1; \
+ DECL_IGNORED_P (decl) = 1; \
+ /* Mark the table as belonging to this class. */ \
+ pushdecl (decl); \
+ MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl); \
+ DECL_OWNER (decl) = TYPE; \
+ sprintf (buf, #NAME "_syms_%s", typename); \
+ TYPE_## TABLE ##_SYMS_DECL (TYPE) = \
+ build_decl (VAR_DECL, get_identifier (buf), symbols_array_type); \
+ TREE_STATIC (TYPE_## TABLE ##_SYMS_DECL (TYPE)) = 1; \
+ TREE_CONSTANT (TYPE_## TABLE ##_SYMS_DECL (TYPE)) = 1; \
+ DECL_IGNORED_P (TYPE_## TABLE ##_SYMS_DECL (TYPE)) = 1; \
+ pushdecl (TYPE_## TABLE ##_SYMS_DECL (TYPE)); \
+} \
+while (0)
+
+
+/* Given a class, create the DECLs for all its associated indirect
+ dispatch tables. */
void
gen_indirect_dispatch_tables (tree type)
{
@@ -377,54 +408,14 @@ gen_indirect_dispatch_tables (tree type)
if (flag_indirect_dispatch)
{
- {
- char *buf = alloca (strlen (typename) + strlen ("_otable_syms_") + 1);
-
- sprintf (buf, "_otable_%s", typename);
- TYPE_OTABLE_DECL (type) =
- build_decl (VAR_DECL, get_identifier (buf), otable_type);
- DECL_EXTERNAL (TYPE_OTABLE_DECL (type)) = 1;
- TREE_STATIC (TYPE_OTABLE_DECL (type)) = 1;
- TREE_READONLY (TYPE_OTABLE_DECL (type)) = 1;
- TREE_CONSTANT (TYPE_OTABLE_DECL (type)) = 1;
- DECL_IGNORED_P (TYPE_OTABLE_DECL (type)) = 1;
- pushdecl (TYPE_OTABLE_DECL (type));
- sprintf (buf, "_otable_syms_%s", typename);
- TYPE_OTABLE_SYMS_DECL (type) =
- build_decl (VAR_DECL, get_identifier (buf), symbols_array_type);
- TREE_STATIC (TYPE_OTABLE_SYMS_DECL (type)) = 1;
- TREE_CONSTANT (TYPE_OTABLE_SYMS_DECL (type)) = 1;
- DECL_IGNORED_P(TYPE_OTABLE_SYMS_DECL (type)) = 1;
- pushdecl (TYPE_OTABLE_SYMS_DECL (type));
- }
-
- {
- char *buf = alloca (strlen (typename) + strlen ("_atable_syms_") + 1);
- tree decl;
-
- sprintf (buf, "_atable_%s", typename);
- TYPE_ATABLE_DECL (type) = decl =
- build_decl (VAR_DECL, get_identifier (buf), atable_type);
- DECL_EXTERNAL (decl) = 1;
- TREE_STATIC (decl) = 1;
- TREE_READONLY (decl) = 1;
- TREE_CONSTANT (decl) = 1;
- DECL_IGNORED_P (decl) = 1;
- /* Mark the atable as belonging to this class. */
- pushdecl (decl);
- MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
- DECL_OWNER (decl) = type;
- sprintf (buf, "_atable_syms_%s", typename);
- TYPE_ATABLE_SYMS_DECL (type) =
- build_decl (VAR_DECL, get_identifier (buf), symbols_array_type);
- TREE_STATIC (TYPE_ATABLE_SYMS_DECL (type)) = 1;
- TREE_CONSTANT (TYPE_ATABLE_SYMS_DECL (type)) = 1;
- DECL_IGNORED_P (TYPE_ATABLE_SYMS_DECL (type)) = 1;
- pushdecl (TYPE_ATABLE_SYMS_DECL (type));
- }
+ GEN_TABLE (ATABLE, _atable, atable_type, type);
+ GEN_TABLE (OTABLE, _otable, otable_type, type);
+ GEN_TABLE (ITABLE, _itable, itable_type, type);
}
}
+#undef GEN_TABLE
+
tree
push_class (tree class_type, tree class_name)
{
@@ -476,6 +467,7 @@ set_super_info (int access_flags, tree this_class,
if (super_class)
total_supers++;
+ TYPE_VFIELD (this_class) = TYPE_VFIELD (object_type_node);
TYPE_BINFO_BASETYPES (this_class) = make_tree_vec (total_supers);
if (super_class)
{
@@ -485,6 +477,12 @@ set_super_info (int access_flags, tree this_class,
TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (this_class)), 0)
= super_binfo;
CLASS_HAS_SUPER (this_class) = 1;
+#if 0
+ /* FIXME: This is wrong. */
+ if (TYPE_LANG_SPECIFIC (this_class)
+ && TYPE_LANG_SPECIFIC (super_class))
+ TYPE_DUMMY (this_class) = TYPE_DUMMY (super_class);
+#endif
}
set_class_decl_access_flags (access_flags, class_decl);
@@ -889,6 +887,7 @@ build_utf8_ref (tree name)
PUSH_FIELD_VALUE (cinit, "data", string);
FINISH_RECORD_CONSTRUCTOR (cinit);
TREE_CONSTANT (cinit) = 1;
+ TREE_INVARIANT (cinit) = 1;
/* Generate a unique-enough identifier. */
sprintf(buf, "_Utf%d", ++utf8_count);
@@ -939,8 +938,7 @@ build_indirect_class_ref (tree type)
tree cl;
index = alloc_class_constant (type);
cl = build_ref_from_constant_pool (index);
- TREE_TYPE (cl) = promote_type (class_ptr_type);
- return cl;
+ return convert (promote_type (class_ptr_type), cl);
}
/* Build a reference to the class TYPE.
@@ -962,7 +960,7 @@ build_class_ref (tree type)
we always emit this hard superclass reference. */
if (flag_indirect_dispatch
&& type != output_class
- && type != CLASSTYPE_SUPER (output_class)
+// && type != CLASSTYPE_SUPER (output_class)
&& TREE_CODE (type) == RECORD_TYPE)
return build_indirect_class_ref (type);
@@ -1086,15 +1084,18 @@ build_static_field_ref (tree fdecl)
= build_int_2 (get_symbol_table_index
(fdecl, &TYPE_ATABLE_METHODS (output_class)), 0);
tree field_address
- = build (ARRAY_REF, build_pointer_type (TREE_TYPE (fdecl)),
+ = build (ARRAY_REF, TREE_TYPE (TREE_TYPE (TYPE_ATABLE_DECL (output_class))),
TYPE_ATABLE_DECL (output_class), table_index);
+
+ field_address = convert (build_pointer_type (TREE_TYPE (fdecl)),
+ field_address);
return fold (build1 (INDIRECT_REF, TREE_TYPE (fdecl),
field_address));
}
else
{
/* Compile as:
- * *(FTYPE*)build_class_ref(FCLASS)->fields[INDEX].info.addr */
+ *(FTYPE*)build_class_ref(FCLASS)->fields[INDEX].info.addr */
tree ref = build_class_ref (fclass);
tree fld;
int field_index = 0;
@@ -1120,6 +1121,7 @@ build_static_field_ref (tree fdecl)
ref, lookup_field (&field_type_node, info_ident));
ref = build (COMPONENT_REF, ptr_type_node,
ref, TREE_CHAIN (TYPE_FIELDS (field_info_union_node)));
+ ref = convert (build_pointer_type (TREE_TYPE (fdecl)), ref);
return fold (build1 (INDIRECT_REF, TREE_TYPE(fdecl), ref));
}
}
@@ -1246,11 +1248,16 @@ make_method_value (tree mdecl)
tree minit;
tree index;
tree code;
+ tree class_decl;
#define ACC_TRANSLATED 0x4000
int accflags = get_access_flags_from_decl (mdecl) | ACC_TRANSLATED;
- if (!flag_indirect_dispatch && DECL_VINDEX (mdecl) != NULL_TREE)
- index = DECL_VINDEX (mdecl);
+ class_decl = DECL_CONTEXT (mdecl);
+ /* For interfaces, the index field contains the dispatch index. */
+ if (CLASS_INTERFACE (TYPE_NAME (class_decl)))
+ index = build_int_2 (get_interface_method_index (mdecl, class_decl), 0);
+ else if (!flag_indirect_dispatch && get_method_index (mdecl) != NULL_TREE)
+ index = get_method_index (mdecl);
else
index = integer_minus_one_node;
@@ -1338,10 +1345,12 @@ get_dispatch_vector (tree type)
for (method = TYPE_METHODS (type); method != NULL_TREE;
method = TREE_CHAIN (method))
- if (DECL_VINDEX (method) != NULL_TREE
- && host_integerp (DECL_VINDEX (method), 0))
- TREE_VEC_ELT (vtable, tree_low_cst (DECL_VINDEX (method), 0))
- = method;
+ {
+ tree method_index = get_method_index (method);
+ if (method_index != NULL_TREE
+ && host_integerp (method_index, 0))
+ TREE_VEC_ELT (vtable, tree_low_cst (method_index, 0)) = method;
+ }
}
return vtable;
@@ -1383,6 +1392,7 @@ get_dispatch_table (tree type, tree this_class_addr)
tree fdesc = build (FDESC_EXPR, nativecode_ptr_type_node,
method, build_int_2 (j, 0));
TREE_CONSTANT (fdesc) = 1;
+ TREE_INVARIANT (fdesc) = 1;
list = tree_cons (NULL_TREE, fdesc, list);
}
else
@@ -1420,6 +1430,42 @@ get_dispatch_table (tree type, tree this_class_addr)
arraysize), list);
}
+
+/* Set the method_index for a method decl. */
+void
+set_method_index (tree decl, tree method_index)
+{
+ method_index = fold (convert (sizetype, method_index));
+
+ if (TARGET_VTABLE_USES_DESCRIPTORS)
+ /* Add one to skip bogus descriptor for class and GC descriptor. */
+ method_index = size_binop (PLUS_EXPR, method_index, size_int (1));
+ else
+ /* Add 1 to skip "class" field of dtable, and 1 to skip GC descriptor. */
+ method_index = size_binop (PLUS_EXPR, method_index, size_int (2));
+
+ DECL_VINDEX (decl) = method_index;
+}
+
+/* Get the method_index for a method decl. */
+tree
+get_method_index (tree decl)
+{
+ tree method_index = DECL_VINDEX (decl);
+
+ if (! method_index)
+ return NULL;
+
+ if (TARGET_VTABLE_USES_DESCRIPTORS)
+ /* Sub one to skip bogus descriptor for class and GC descriptor. */
+ method_index = size_binop (MINUS_EXPR, method_index, size_int (1));
+ else
+ /* Sub 1 to skip "class" field of dtable, and 1 to skip GC descriptor. */
+ method_index = size_binop (MINUS_EXPR, method_index, size_int (2));
+
+ return method_index;
+}
+
static int
supers_all_compiled (tree type)
{
@@ -1464,7 +1510,9 @@ make_class_data (tree type)
/* Build Field array. */
field = TYPE_FIELDS (type);
- if (DECL_NAME (field) == NULL_TREE)
+ while (field && DECL_ARTIFICIAL (field))
+ field = TREE_CHAIN (field); /* Skip dummy fields. */
+ if (field && DECL_NAME (field) == NULL_TREE)
field = TREE_CHAIN (field); /* Skip dummy field for inherited data. */
for ( ; field != NULL_TREE; field = TREE_CHAIN (field))
{
@@ -1519,6 +1567,11 @@ make_class_data (tree type)
&& ! flag_keep_inline_functions
&& (flag_inline_functions || optimize))
continue;
+ /* Even if we have a decl, we don't necessaily have the code.
+ This can happen if we inherit a method from a superclass for
+ which we don't have a .class file. */
+ if (METHOD_DUMMY (method))
+ continue;
init = make_method_value (method);
method_count++;
methods = tree_cons (NULL_TREE, init, methods);
@@ -1562,10 +1615,8 @@ make_class_data (tree type)
super = CLASSTYPE_SUPER (type);
if (super == NULL_TREE)
super = null_pointer_node;
- else if (/* FIXME: we should also test for (!
- flag_indirect_dispatch) here, but libgcj can't cope with
- a symbolic reference a superclass in the class data. */
- assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl)))
+ else if (! flag_indirect_dispatch
+ && assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl)))
&& assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (super)))))
super = build_class_ref (super);
else
@@ -1620,13 +1671,19 @@ make_class_data (tree type)
= emit_symbol_table
(DECL_NAME (TYPE_OTABLE_DECL (type)),
TYPE_OTABLE_DECL (type), TYPE_OTABLE_METHODS (type),
- TYPE_OTABLE_SYMS_DECL (type), integer_type_node);
+ TYPE_OTABLE_SYMS_DECL (type), integer_type_node, 1);
TYPE_ATABLE_DECL (type)
= emit_symbol_table
(DECL_NAME (TYPE_ATABLE_DECL (type)),
TYPE_ATABLE_DECL (type), TYPE_ATABLE_METHODS (type),
- TYPE_ATABLE_SYMS_DECL (type), ptr_type_node);
+ TYPE_ATABLE_SYMS_DECL (type), ptr_type_node, 1);
+
+ TYPE_ITABLE_DECL (type)
+ = emit_symbol_table
+ (DECL_NAME (TYPE_ITABLE_DECL (type)),
+ TYPE_ITABLE_DECL (type), TYPE_ITABLE_METHODS (type),
+ TYPE_ITABLE_SYMS_DECL (type), ptr_type_node, 2);
}
TYPE_CTABLE_DECL (type) = emit_catch_table (type);
@@ -1661,8 +1718,14 @@ make_class_data (tree type)
PUSH_FIELD_VALUE (cons, "fields",
fields_decl == NULL_TREE ? null_pointer_node
: build1 (ADDR_EXPR, field_ptr_type_node, fields_decl));
- PUSH_FIELD_VALUE (cons, "size_in_bytes", size_in_bytes (type));
- PUSH_FIELD_VALUE (cons, "field_count", build_int_2 (field_count, 0));
+ /* If we're using the binary compatibility ABI we don't know the
+ size until load time. */
+ PUSH_FIELD_VALUE (cons, "size_in_bytes",
+ (flag_indirect_dispatch
+ ? integer_minus_one_node
+ : size_in_bytes (type)));
+ PUSH_FIELD_VALUE (cons, "field_count",
+ build_int_2 (field_count, 0));
PUSH_FIELD_VALUE (cons, "static_field_count",
build_int_2 (static_field_count, 0));
@@ -1687,7 +1750,8 @@ make_class_data (tree type)
build1 (ADDR_EXPR, symbols_array_ptr_type,
TYPE_OTABLE_SYMS_DECL (type)));
TREE_CONSTANT (TYPE_OTABLE_DECL (type)) = 1;
- }
+ TREE_INVARIANT (TYPE_OTABLE_DECL (type)) = 1;
+ }
if (TYPE_ATABLE_METHODS(type) == NULL_TREE)
{
PUSH_FIELD_VALUE (cons, "atable", null_pointer_node);
@@ -1701,6 +1765,22 @@ make_class_data (tree type)
build1 (ADDR_EXPR, symbols_array_ptr_type,
TYPE_ATABLE_SYMS_DECL (type)));
TREE_CONSTANT (TYPE_ATABLE_DECL (type)) = 1;
+ TREE_INVARIANT (TYPE_ATABLE_DECL (type)) = 1;
+ }
+ if (TYPE_ITABLE_METHODS(type) == NULL_TREE)
+ {
+ PUSH_FIELD_VALUE (cons, "itable", null_pointer_node);
+ PUSH_FIELD_VALUE (cons, "itable_syms", null_pointer_node);
+ }
+ else
+ {
+ PUSH_FIELD_VALUE (cons, "itable",
+ build1 (ADDR_EXPR, itable_ptr_type, TYPE_ITABLE_DECL (type)));
+ PUSH_FIELD_VALUE (cons, "itable_syms",
+ build1 (ADDR_EXPR, symbols_array_ptr_type,
+ TYPE_ITABLE_SYMS_DECL (type)));
+ TREE_CONSTANT (TYPE_ITABLE_DECL (type)) = 1;
+ TREE_INVARIANT (TYPE_ITABLE_DECL (type)) = 1;
}
PUSH_FIELD_VALUE (cons, "catch_classes",
@@ -1708,7 +1788,12 @@ make_class_data (tree type)
PUSH_FIELD_VALUE (cons, "interfaces", interfaces);
PUSH_FIELD_VALUE (cons, "loader", null_pointer_node);
PUSH_FIELD_VALUE (cons, "interface_count", build_int_2 (interface_len, 0));
- PUSH_FIELD_VALUE (cons, "state", integer_zero_node);
+ PUSH_FIELD_VALUE (cons, "state",
+ convert (byte_type_node,
+ build_int_2 (flag_indirect_dispatch
+ ? JV_STATE_PRELOADING
+ : JV_STATE_COMPILED,
+ 0)));
PUSH_FIELD_VALUE (cons, "thread", null_pointer_node);
PUSH_FIELD_VALUE (cons, "depth", integer_zero_node);
@@ -1716,8 +1801,20 @@ make_class_data (tree type)
PUSH_FIELD_VALUE (cons, "idt", null_pointer_node);
PUSH_FIELD_VALUE (cons, "arrayclass", null_pointer_node);
PUSH_FIELD_VALUE (cons, "protectionDomain", null_pointer_node);
+ {
+ tree verify_method = TYPE_VERIFY_METHOD (type);
+ tree verify_method_ref
+ = (verify_method
+ ? build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (verify_method)),
+ verify_method)
+ : null_pointer_node);
+ PUSH_FIELD_VALUE (cons, "verify" , verify_method_ref);
+ TYPE_VERIFY_METHOD (type) = NULL;
+ }
PUSH_FIELD_VALUE (cons, "hack_signers", null_pointer_node);
PUSH_FIELD_VALUE (cons, "chain", null_pointer_node);
+ PUSH_FIELD_VALUE (cons, "aux_info", null_pointer_node);
+ PUSH_FIELD_VALUE (cons, "engine", null_pointer_node);
FINISH_RECORD_CONSTRUCTOR (cons);
@@ -1728,40 +1825,20 @@ make_class_data (tree type)
DECL_ALIGN (decl) = 64;
rest_of_decl_compilation (decl, (char*) 0, 1, 0);
+
+ TYPE_OTABLE_DECL (type) = NULL_TREE;
+ TYPE_ATABLE_DECL (type) = NULL_TREE;
+ TYPE_CTABLE_DECL (type) = NULL_TREE;
}
void
finish_class (void)
{
- tree method;
- tree type_methods = TYPE_METHODS (current_class);
- int saw_native_method = 0;
-
- /* Find out if we have any native methods. We use this information
- later. */
- for (method = type_methods;
- method != NULL_TREE;
- method = TREE_CHAIN (method))
+ if (TYPE_VERIFY_METHOD (output_class))
{
- if (METHOD_NATIVE (method))
- {
- saw_native_method = 1;
- break;
- }
- }
-
- /* Emit deferred inline methods. */
- for (method = type_methods; method != NULL_TREE; )
- {
- if (! TREE_ASM_WRITTEN (method) && DECL_STRUCT_FUNCTION (method) != 0)
- {
- output_inline_function (method);
- /* Scan the list again to see if there are any earlier
- methods to emit. */
- method = type_methods;
- continue;
- }
- method = TREE_CHAIN (method);
+ java_genericize (TYPE_VERIFY_METHOD (current_class));
+ cgraph_finalize_function (TYPE_VERIFY_METHOD (current_class), false);
+ TYPE_ASSERTIONS (current_class) = NULL;
}
java_expand_catch_classes (current_class);
@@ -2046,8 +2123,12 @@ layout_class (tree this_class)
static void
add_miranda_methods (tree base_class, tree search_class)
{
- tree basetype_vec = TYPE_BINFO_BASETYPES (search_class);
- int i, n = TREE_VEC_LENGTH (basetype_vec);
+ tree basetype_vec;
+ int i, n;
+ if (!CLASS_PARSED_P (search_class))
+ load_class (search_class, 1);
+ basetype_vec = TYPE_BINFO_BASETYPES (search_class);
+ n = TREE_VEC_LENGTH (basetype_vec);
for (i = 1; i < n; ++i)
{
tree method_decl;
@@ -2056,6 +2137,11 @@ add_miranda_methods (tree base_class, tree search_class)
break;
elt = BINFO_TYPE (elt);
+ /* FIXME: This is totally bogus. We should not be handling
+ Miranda methods at all if we're using the BC ABI. */
+ if (TYPE_DUMMY (elt))
+ continue;
+
/* Ensure that interface methods are seen in declared order. */
layout_class_methods (elt);
@@ -2133,6 +2219,23 @@ layout_class_methods (tree this_class)
TYPE_NVIRTUALS (this_class) = dtable_count;
}
+/* Return the index of METHOD in INTERFACE. This index begins at 1 and is used as an
+ argument for _Jv_LookupInterfaceMethodIdx(). */
+int
+get_interface_method_index (tree method, tree interface)
+{
+ tree meth;
+ int i = 1;
+
+ for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
+ {
+ if (meth == method)
+ return i;
+ if (meth == NULL_TREE)
+ abort ();
+ }
+}
+
/* Lay METHOD_DECL out, returning a possibly new value of
DTABLE_COUNT. Also mangle the method's name. */
@@ -2176,20 +2279,31 @@ layout_class_method (tree this_class, tree super_class,
build_java_argument_signature (TREE_TYPE (method_decl));
tree super_method = lookup_argument_method (super_class, method_name,
method_sig);
- if (super_method != NULL_TREE && ! METHOD_PRIVATE (super_method))
+ if (super_method != NULL_TREE && ! METHOD_PRIVATE (super_method)
+ && ! METHOD_DUMMY (super_method)
+ && ! DECL_ARTIFICIAL (super_method))
{
- DECL_VINDEX (method_decl) = DECL_VINDEX (super_method);
- if (DECL_VINDEX (method_decl) == NULL_TREE
+ tree method_index = get_method_index (super_method);
+ set_method_index (method_decl, method_index);
+ if (method_index == NULL_TREE
&& !CLASS_FROM_SOURCE_P (this_class))
error ("%Jnon-static method '%D' overrides static method",
method_decl, method_decl);
}
- else if (! METHOD_FINAL (method_decl)
- && ! METHOD_PRIVATE (method_decl)
- && ! CLASS_FINAL (TYPE_NAME (this_class))
+ else if (this_class == object_type_node
+ && (METHOD_FINAL (method_decl)
+ || METHOD_PRIVATE (method_decl)))
+ {
+ /* We don't generate vtable entries for final Object
+ methods. This is simply to save space, since every
+ object would otherwise have to define them. */
+ }
+ else if (! METHOD_PRIVATE (method_decl)
&& dtable_count)
{
- DECL_VINDEX (method_decl) = dtable_count;
+ /* We generate vtable entries for final methods because they
+ may one day be changed to non-final. */
+ set_method_index (method_decl, dtable_count);
dtable_count = fold (build (PLUS_EXPR, integer_type_node,
dtable_count, integer_one_node));
}
@@ -2299,29 +2413,37 @@ static tree
build_symbol_entry (tree decl)
{
tree clname, name, signature, sym;
-
clname = build_utf8_ref (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl))));
- name = build_utf8_ref (DECL_NAME (decl));
+ /* ??? Constructors are given the name foo.foo all the way through
+ the compiler, but in the method table they're all renamed
+ foo.<init>. So, we have to do the same here unless we want an
+ unresolved reference at runtime. */
+ name = build_utf8_ref ((TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_CONSTRUCTOR_P (decl))
+ ? init_identifier_node
+ : DECL_NAME (decl));
signature = build_java_signature (TREE_TYPE (decl));
signature = build_utf8_ref (unmangle_classname
(IDENTIFIER_POINTER (signature),
IDENTIFIER_LENGTH (signature)));
-
+
START_RECORD_CONSTRUCTOR (sym, symbol_type);
PUSH_FIELD_VALUE (sym, "clname", clname);
PUSH_FIELD_VALUE (sym, "name", name);
PUSH_FIELD_VALUE (sym, "signature", signature);
FINISH_RECORD_CONSTRUCTOR (sym);
TREE_CONSTANT (sym) = 1;
+ TREE_INVARIANT (sym) = 1;
return sym;
}
-/* Emit a symbol table: used by -findirect-dispatch. */
+/* Emit a symbol table: used by -findirect-dispatch. ELEMENT_SIZE is
+ the number of elements per symbol. */
tree
emit_symbol_table (tree name, tree the_table, tree decl_list, tree the_syms_decl,
- tree the_array_element_type)
+ tree the_array_element_type, int element_size)
{
tree method_list, method, table, list, null_symbol;
tree table_size, the_array_type;
@@ -2351,6 +2473,7 @@ emit_symbol_table (tree name, tree the_table, tree decl_list, tree the_syms_decl
PUSH_FIELD_VALUE (null_symbol, "signature", null_pointer_node);
FINISH_RECORD_CONSTRUCTOR (null_symbol);
TREE_CONSTANT (null_symbol) = 1;
+ TREE_INVARIANT (null_symbol) = 1;
list = tree_cons (NULL_TREE, null_symbol, list);
/* Put the list in the right order and make it a constructor. */
@@ -2367,7 +2490,7 @@ emit_symbol_table (tree name, tree the_table, tree decl_list, tree the_syms_decl
uninitialized static array of INDEX + 1 elements. The extra entry
is used by the runtime to track whether the table has been
initialized. */
- table_size = build_index_type (build_int_2 (index, 0));
+ table_size = build_index_type (build_int_2 (index * element_size + 1, 0));
the_array_type = build_array_type (the_array_element_type, table_size);
the_table = build_decl (VAR_DECL, name, the_array_type);
TREE_STATIC (the_table) = 1;
diff --git a/gcc/java/constants.c b/gcc/java/constants.c
index d97e8c07e80..32fc854c9db 100644
--- a/gcc/java/constants.c
+++ b/gcc/java/constants.c
@@ -386,29 +386,35 @@ alloc_class_constant (tree clas)
IDENTIFIER_LENGTH(class_name))));
}
-/* Return a reference to the data array of the current constant pool. */
+/* Return the decl of the data array of the current constant pool. */
static tree
build_constant_data_ref (void)
{
- tree cpool_data_ref = NULL_TREE;
+ tree decl = TYPE_CPOOL_DATA_REF (output_class);
- if (TYPE_CPOOL_DATA_REF (output_class))
- cpool_data_ref = TYPE_CPOOL_DATA_REF (output_class);
-
- if (cpool_data_ref == NULL_TREE)
+ if (decl == NULL_TREE)
{
- tree decl;
+ tree type;
tree decl_name = mangled_classname ("_CD_", output_class);
- decl = build_decl (VAR_DECL, decl_name,
- build_array_type (ptr_type_node,
- one_elt_array_domain_type));
+
+ /* Build a type with unspecified bounds. The will make sure
+ that targets do the right thing with whatever size we end
+ up with at the end. Using bounds that are too small risks
+ assuming the data is in the small data section. */
+ type = build_array_type (ptr_type_node, NULL_TREE);
+
+ /* We need to lay out the type ourselves, since build_array_type
+ thinks the type is incomplete. */
+ layout_type (type);
+
+ decl = build_decl (VAR_DECL, decl_name, type);
TREE_STATIC (decl) = 1;
make_decl_rtl (decl, NULL);
- TYPE_CPOOL_DATA_REF (output_class) = cpool_data_ref
- = build1 (ADDR_EXPR, ptr_type_node, decl);
+ TYPE_CPOOL_DATA_REF (output_class) = decl;
}
- return cpool_data_ref;
+
+ return decl;
}
/* Get the pointer value at the INDEX'th element of the constant pool. */
@@ -416,11 +422,9 @@ build_constant_data_ref (void)
tree
build_ref_from_constant_pool (int index)
{
- tree t = build_constant_data_ref ();
- index *= int_size_in_bytes (ptr_type_node);
- t = fold (build (PLUS_EXPR, ptr_type_node,
- t, build_int_2 (index, 0)));
- return build1 (INDIRECT_REF, ptr_type_node, t);
+ tree d = build_constant_data_ref ();
+ tree i = build_int_2 (index, 0);
+ return build (ARRAY_REF, TREE_TYPE (TREE_TYPE (d)), d, i);
}
/* Build an initializer for the constants field of the current constant pool.
@@ -456,7 +460,7 @@ build_constants_constructor (void)
tags_list = tree_cons (NULL_TREE, get_tag_node (0), tags_list);
data_list = tree_cons (NULL_TREE, null_pointer_node, data_list);
- data_decl = TREE_OPERAND (build_constant_data_ref (), 0);
+ data_decl = build_constant_data_ref ();
TREE_TYPE (data_decl) = build_array_type (ptr_type_node, index_type),
DECL_INITIAL (data_decl) = build_constructor (TREE_TYPE (data_decl),
data_list);
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index e0dd852927e..6c1313ea455 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -44,6 +44,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "java-except.h"
#include "ggc.h"
#include "timevar.h"
+#include "cgraph.h"
#include "tree-inline.h"
#include "target.h"
@@ -56,7 +57,6 @@ static tree lookup_name_current_level (tree);
static tree push_promoted_type (const char *, tree);
static struct binding_level *make_binding_level (void);
static tree create_primitive_vtable (const char *);
-static tree check_local_named_variable (tree, tree, int, int *);
static tree check_local_unnamed_variable (tree, tree, tree);
/* Name of the Cloneable class. */
@@ -75,14 +75,20 @@ tree java_io_serializable_identifier_node;
static GTY(()) tree decl_map;
+/* The base_decl_map is contains one variable of ptr_type: this is
+ used to contain every variable of reference type that is ever
+ stored in a local variable slot. */
+
+static GTY(()) tree base_decl_map;
+
+/* An index used to make temporary identifiers unique. */
+static int uniq;
+
/* A list of local variables VAR_DECLs for this method that we have seen
debug information, but we have not reached their starting (byte) PC yet. */
static GTY(()) tree pending_local_decls;
-/* Push a local variable or stack slot into the decl_map,
- and assign it an rtl. */
-
#if defined(DEBUG_JAVA_BINDING_LEVELS)
int binding_depth = 0;
int is_class_level = 0;
@@ -91,43 +97,73 @@ int current_pc;
void
indent (void)
{
- unsigned i;
+ int i;
for (i = 0; i < binding_depth*2; i++)
putc (' ', stderr);
}
#endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */
-static tree
-push_jvm_slot (int index, tree decl)
+/* True if decl is a named local variable, i.e. if it is an alias
+ that's used only for debugging purposes. */
+
+static bool
+debug_variable_p (tree decl)
{
- struct rtx_def *rtl = NULL;
- tree type = TREE_TYPE (decl);
+ if (TREE_CODE (decl) == PARM_DECL)
+ return false;
+
+ if (LOCAL_SLOT_P (decl))
+ return false;
+
+ return true;
+}
+
+/* Copy the value in decl into every live alias in the same local
+ variable slot. Some of these will be dead stores removed by the
+ optimizer. */
+
+void
+update_aliases (tree decl, int index, int pc)
+{
+ tree decl_type = TREE_TYPE (decl);
tree tmp;
- DECL_CONTEXT (decl) = current_function_decl;
- layout_decl (decl, 0);
+ if (debug_variable_p (decl))
+ abort ();
- /* See if we have an appropriate rtl (i.e. same mode) at this index.
- If so, we must use it. */
- tmp = TREE_VEC_ELT (decl_map, index);
- while (tmp != NULL_TREE)
- {
- if (TYPE_MODE (type) == TYPE_MODE (TREE_TYPE (tmp))
- && ! LOCAL_VAR_OUT_OF_SCOPE_P (tmp))
- rtl = DECL_RTL_IF_SET (tmp);
- if (rtl != NULL)
- break;
- tmp = DECL_LOCAL_SLOT_CHAIN (tmp);
- }
- if (rtl != NULL)
- SET_DECL_RTL (decl, rtl);
- else
+ for (tmp = TREE_VEC_ELT (decl_map, index);
+ tmp != NULL_TREE;
+ tmp = DECL_LOCAL_SLOT_CHAIN (tmp))
{
- if (index >= DECL_MAX_LOCALS (current_function_decl))
- DECL_REGISTER (decl) = 1;
- expand_decl (decl);
+ tree tmp_type = TREE_TYPE (tmp);
+ if (tmp != decl
+ && LOCAL_SLOT_P (tmp) == 0
+ && (pc == -1
+ || (pc >= DECL_LOCAL_START_PC (tmp)
+ && pc <= DECL_LOCAL_END_PC (tmp)))
+ && (tmp_type == decl_type
+ || (INTEGRAL_TYPE_P (tmp_type)
+ && INTEGRAL_TYPE_P (decl_type)
+ && TYPE_PRECISION (decl_type) <= 32
+ && TYPE_PRECISION (tmp_type) <= 32)
+ || (TREE_CODE (tmp_type) == POINTER_TYPE
+ && TREE_CODE (decl_type) == POINTER_TYPE)))
+ {
+ tree src = build1 (NOP_EXPR, tmp_type, decl);
+ if (LOCAL_VAR_OUT_OF_SCOPE_P (tmp))
+ abort ();
+ java_add_stmt
+ (build (MODIFY_EXPR, tmp_type, tmp, src));
+ }
}
+}
+
+static tree
+push_jvm_slot (int index, tree decl)
+{
+ DECL_CONTEXT (decl) = current_function_decl;
+ layout_decl (decl, 0);
/* Now link the decl into the decl_map. */
if (DECL_LANG_SPECIFIC (decl) == NULL)
@@ -139,29 +175,55 @@ push_jvm_slot (int index, tree decl)
}
DECL_LOCAL_SLOT_CHAIN (decl) = TREE_VEC_ELT (decl_map, index);
TREE_VEC_ELT (decl_map, index) = decl;
+
return decl;
}
-/* Find out if 'decl' passed in fits the defined PC location better than
- 'best'. Return decl if it does, return best if it doesn't. If decl
- is returned, then updated is set to true. */
+/* At the point of its creation a local variable decl inherits
+ whatever is already in the same slot. In the case of a local
+ variable that is declared but unused, we won't find anything. */
-static tree
-check_local_named_variable (tree best, tree decl, int pc, int *updated)
+static void
+initialize_local_variable (tree decl, int index)
{
- if (pc >= DECL_LOCAL_START_PC (decl)
- && pc < DECL_LOCAL_END_PC (decl))
+ tree decl_type = TREE_TYPE (decl);
+ if (TREE_CODE (decl_type) == POINTER_TYPE)
{
- if (best == NULL_TREE
- || (DECL_LOCAL_START_PC (decl) > DECL_LOCAL_START_PC (best)
- && DECL_LOCAL_END_PC (decl) < DECL_LOCAL_END_PC (best)))
+ tree tmp = TREE_VEC_ELT (base_decl_map, index);
+
+ if (tmp)
{
- *updated = 1;
- return decl;
+ /* At the point of its creation this decl inherits whatever
+ is in the slot. */
+ tree src = build1 (NOP_EXPR, decl_type, tmp);
+ java_add_stmt
+ (build (MODIFY_EXPR, decl_type, decl, src));
}
}
+ else
+ {
+ tree tmp;
- return best;
+ for (tmp = TREE_VEC_ELT (decl_map, index);
+ tmp != NULL_TREE;
+ tmp = DECL_LOCAL_SLOT_CHAIN (tmp))
+ {
+ tree tmp_type = TREE_TYPE (tmp);
+ if (tmp != decl
+ && ! debug_variable_p (tmp)
+ && (tmp_type == decl_type
+ || (INTEGRAL_TYPE_P (tmp_type)
+ && INTEGRAL_TYPE_P (decl_type)
+ && TYPE_PRECISION (decl_type) <= 32
+ && TYPE_PRECISION (tmp_type) <= 32
+ && TYPE_PRECISION (tmp_type) >= TYPE_PRECISION (decl_type))))
+ {
+ java_add_stmt
+ (build (MODIFY_EXPR, decl_type, decl, tmp));
+ return;
+ }
+ }
+ }
}
/* Find the best declaration based upon type. If 'decl' fits 'type' better
@@ -170,16 +232,36 @@ check_local_named_variable (tree best, tree decl, int pc, int *updated)
static tree
check_local_unnamed_variable (tree best, tree decl, tree type)
{
- if (TREE_TYPE (decl) == type
- || (TREE_CODE (TREE_TYPE (decl)) == TREE_CODE (type)
- && TYPE_PRECISION (TREE_TYPE (decl)) <= 32
- && TYPE_PRECISION (type) <= 32
- && TREE_CODE (type) != POINTER_TYPE)
- || (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
- && type == ptr_type_node))
+ tree decl_type = TREE_TYPE (decl);
+
+ if (LOCAL_VAR_OUT_OF_SCOPE_P (decl))
+ abort ();
+
+ /* Use the same decl for all integer types <= 32 bits. This is
+ necessary because sometimes a value is stored as (for example)
+ boolean but loaded as int. */
+ if (decl_type == type
+ || (INTEGRAL_TYPE_P (decl_type)
+ && INTEGRAL_TYPE_P (type)
+ && TYPE_PRECISION (decl_type) <= 32
+ && TYPE_PRECISION (type) <= 32
+ && TYPE_PRECISION (decl_type) >= TYPE_PRECISION (type))
+ /* ptr_type_node is used for null pointers, which are
+ assignment compatible with everything. */
+ || (TREE_CODE (decl_type) == POINTER_TYPE
+ && type == ptr_type_node)
+ /* Whenever anyone wants to use a slot that is initially
+ occupied by a PARM_DECL of pointer type they must get that
+ decl, even if they asked for a pointer to a different type.
+ However, if someone wants a scalar variable in a slot that
+ initially held a pointer arg -- or vice versa -- we create a
+ new VAR_DECL. */
+ || (TREE_CODE (decl_type) == POINTER_TYPE
+ && TREE_CODE (decl) == PARM_DECL
+ && TREE_CODE (type) == POINTER_TYPE))
{
if (best == NULL_TREE
- || (TREE_TYPE (decl) == type && TREE_TYPE (best) != type))
+ || (decl_type == type && TREE_TYPE (best) != type))
return decl;
}
@@ -192,46 +274,103 @@ check_local_unnamed_variable (tree best, tree decl, tree type)
If there is no existing matching decl, allocate one. */
tree
-find_local_variable (int index, tree type, int pc)
+find_local_variable (int index, tree type, int pc ATTRIBUTE_UNUSED)
{
- tree decl = TREE_VEC_ELT (decl_map, index);
- tree best = NULL_TREE;
- int found_scoped_var = 0;
+ tree tmp = TREE_VEC_ELT (decl_map, index);
+ tree decl = NULL_TREE;
- /* Scan through every declaration that has been created in this slot. */
- while (decl != NULL_TREE)
+ /* Scan through every declaration that has been created in this
+ slot. We're only looking for variables that correspond to local
+ index declarations and PARM_DECLs, not named variables: such
+ local variables are used only for debugging information. */
+ while (tmp != NULL_TREE)
{
- /* Variables created in give_name_to_locals() have a name and have
- a specified scope, so we can handle them specifically. We want
- to use the specific decls created for those so they are assigned
- the right variables in the debugging information. */
- if (DECL_NAME (decl) != NULL_TREE)
- {
- /* This is a variable we have a name for, so it has a scope
- supplied in the class file. But it only matters when we
- actually have a PC to use. If pc<0, then we are asking
- for a stack slot and this decl won't be one of those. */
- if (pc >= 0)
- best = check_local_named_variable (best, decl, pc,
- &found_scoped_var);
- }
- /* We scan for type information unless we found a variable in the
- proper scope already. */
- else if (!found_scoped_var)
- {
- /* If we don't have scoping information for a variable, we use
- a different method to look it up. */
- best = check_local_unnamed_variable (best, decl, type);
- }
-
- decl = DECL_LOCAL_SLOT_CHAIN (decl);
+ if (! debug_variable_p (tmp))
+ decl = check_local_unnamed_variable (decl, tmp, type);
+ tmp = DECL_LOCAL_SLOT_CHAIN (tmp);
}
- if (best != NULL_TREE)
- return best;
+ /* If we don't find a match, create one with the type passed in.
+ The name of the variable is #n#m, which n is the variable index
+ in the local variable area and m is a dummy identifier for
+ uniqueness -- multiple variables may share the same local
+ variable index. We don't call pushdecl() to push pointer types
+ into a binding expr because they'll all be replaced by a single
+ variable that is used for every reference in that local variable
+ slot. */
+ if (! decl)
+ {
+ char buf[64];
+ tree name;
+ sprintf (buf, "#slot#%d#%d", index, uniq++);
+ name = get_identifier (buf);
+ decl = build_decl (VAR_DECL, name, type);
+ DECL_IGNORED_P (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+ decl = push_jvm_slot (index, decl);
+ LOCAL_SLOT_P (decl) = 1;
+
+ if (TREE_CODE (type) != POINTER_TYPE)
+ pushdecl_function_level (decl);
+ }
+
+ /* As well as creating a local variable that matches the type, we
+ also create a base variable (of ptr_type) that will hold all its
+ aliases. */
+ if (TREE_CODE (type) == POINTER_TYPE
+ && ! TREE_VEC_ELT (base_decl_map, index))
+ {
+ char buf[64];
+ tree name;
+ tree base_decl;
+ sprintf (buf, "#ref#%d#%d", index, uniq++);
+ name = get_identifier (buf);
+ base_decl
+ = TREE_VEC_ELT (base_decl_map, index)
+ = build_decl (VAR_DECL, name, ptr_type_node);
+ pushdecl_function_level (base_decl);
+ DECL_IGNORED_P (base_decl) = 1;
+ DECL_ARTIFICIAL (base_decl) = 1;
+ }
- /* If we don't find a match, create one with the type passed in. */
- return push_jvm_slot (index, build_decl (VAR_DECL, NULL_TREE, type));
+ return decl;
+}
+
+/* Called during gimplification for every variable. If the variable
+ is a temporary of pointer type, replace it with a common variable
+ thath is used to hold all pointer types that are ever stored in
+ that slot. Set WANT_LVALUE if you want a variable that is to be
+ written to. */
+
+tree
+java_replace_reference (tree var_decl, bool want_lvalue)
+{
+ tree decl_type;
+
+ if (! base_decl_map)
+ return var_decl;
+
+ decl_type = TREE_TYPE (var_decl);
+
+ if (TREE_CODE (decl_type) == POINTER_TYPE)
+ {
+ if (DECL_LANG_SPECIFIC (var_decl)
+ && LOCAL_SLOT_P (var_decl))
+ {
+ int index = DECL_LOCAL_SLOT_NUMBER (var_decl);
+ tree base_decl = TREE_VEC_ELT (base_decl_map, index);
+
+ if (! base_decl)
+ abort ();
+
+ if (! want_lvalue)
+ base_decl = build1 (NOP_EXPR, decl_type, base_decl);
+
+ return base_decl;
+ }
+ }
+
+ return var_decl;
}
@@ -274,6 +413,12 @@ struct binding_level
/* The bytecode PC that marks the start of this level. */
int start_pc;
+ /* The statements in this binding level. */
+ tree stmts;
+
+ /* An exception range associated with this binding level. */
+ struct eh_range *exception_range;
+
#if defined(DEBUG_JAVA_BINDING_LEVELS)
/* Binding depth at which this level began. */
unsigned binding_depth;
@@ -296,6 +441,11 @@ static struct binding_level *free_binding_level;
static struct binding_level *global_binding_level;
+/* The binding level that holds variables declared at the outermost
+ level within a function body. */
+
+static struct binding_level *function_binding_level;
+
/* A PC value bigger than any PC value we may ever may encounter. */
#define LARGEST_PC (( (unsigned int)1 << (HOST_BITS_PER_INT - 1)) - 1)
@@ -303,8 +453,19 @@ static struct binding_level *global_binding_level;
/* Binding level structures are initialized by copying this one. */
static const struct binding_level clear_binding_level
- = {NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE,
- NULL_BINDING_LEVEL, LARGEST_PC, 0};
+ = {NULL_TREE, /* names */
+ NULL_TREE, /* shadowed */
+ NULL_TREE, /* blocks */
+ NULL_TREE, /* this_lock */
+ NULL_BINDING_LEVEL, /* level_chain */
+ LARGEST_PC, /* end_pc */
+ 0, /* start_pc */
+ NULL, /* stmts */
+ NULL, /* exception_range */
+#if defined(DEBUG_JAVA_BINDING_LEVELS)
+ 0, /* binding_depth */
+#endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */
+};
#if 0
/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
@@ -439,7 +600,10 @@ java_init_decl_processing (void)
pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned long"),
unsigned_long_type_node));
- set_sizetype (make_unsigned_type (POINTER_SIZE));
+ /* This is not a java type, however tree-dfa requires a definition for
+ size_type_node. */
+ size_type_node = make_unsigned_type (POINTER_SIZE);
+ set_sizetype (size_type_node);
/* Define these next since types below may used them. */
integer_type_node = java_type_for_size (INT_TYPE_SIZE, 0);
@@ -483,10 +647,6 @@ java_init_decl_processing (void)
null_pointer_node = build_int_2 (0, 0);
TREE_TYPE (null_pointer_node) = ptr_type_node;
- /* Used by the parser to represent empty statements and blocks. */
- empty_stmt_node = build1 (NOP_EXPR, void_type_node, size_zero_node);
- CAN_COMPLETE_NORMALLY (empty_stmt_node) = 1;
-
#if 0
/* Make a type to be the domain of a few array types
whose domains don't really matter.
@@ -554,6 +714,11 @@ java_init_decl_processing (void)
TYPE_NONALIASED_COMPONENT (atable_type) = 1;
atable_ptr_type = build_pointer_type (atable_type);
+ itable_type = build_array_type (ptr_type_node,
+ one_elt_array_domain_type);
+ TYPE_NONALIASED_COMPONENT (itable_type) = 1;
+ itable_ptr_type = build_pointer_type (itable_type);
+
symbol_type = make_node (RECORD_TYPE);
PUSH_FIELD (symbol_type, field, "clname", utf8const_ptr_type);
PUSH_FIELD (symbol_type, field, "name", utf8const_ptr_type);
@@ -604,6 +769,7 @@ java_init_decl_processing (void)
clinit_identifier_node = get_identifier ("<clinit>");
finit_identifier_node = get_identifier ("finit$");
instinit_identifier_node = get_identifier ("instinit$");
+ verify_identifier_node = get_identifier ("__verify");
void_signature_node = get_identifier ("()V");
length_identifier_node = get_identifier ("length");
finalize_identifier_node = get_identifier ("finalize");
@@ -638,6 +804,9 @@ java_init_decl_processing (void)
otable_ptr_type = build_pointer_type (otable_type);
PUSH_FIELD (object_type_node, field, "vtable", dtable_ptr_type);
+ DECL_FCONTEXT (field) = object_type_node;
+ TYPE_VFIELD (object_type_node) = field;
+
/* This isn't exactly true, but it is what we have in the source.
There is an unresolved issue here, which is whether the vtable
should be marked by the GC. */
@@ -676,6 +845,9 @@ java_init_decl_processing (void)
PUSH_FIELD (class_type_node, field, "atable", atable_ptr_type);
PUSH_FIELD (class_type_node, field, "atable_syms",
symbols_array_ptr_type);
+ PUSH_FIELD (class_type_node, field, "itable", itable_ptr_type);
+ PUSH_FIELD (class_type_node, field, "itable_syms",
+ symbols_array_ptr_type);
PUSH_FIELD (class_type_node, field, "catch_classes", ptr_type_node);
PUSH_FIELD (class_type_node, field, "interfaces",
build_pointer_type (class_ptr_type));
@@ -688,8 +860,11 @@ java_init_decl_processing (void)
PUSH_FIELD (class_type_node, field, "idt", ptr_type_node);
PUSH_FIELD (class_type_node, field, "arrayclass", ptr_type_node);
PUSH_FIELD (class_type_node, field, "protectionDomain", ptr_type_node);
+ PUSH_FIELD (class_type_node, field, "verify", ptr_type_node);
PUSH_FIELD (class_type_node, field, "hack_signers", ptr_type_node);
PUSH_FIELD (class_type_node, field, "chain", ptr_type_node);
+ PUSH_FIELD (class_type_node, field, "aux_info", ptr_type_node);
+ PUSH_FIELD (class_type_node, field, "engine", ptr_type_node);
for (t = TYPE_FIELDS (class_type_node); t != NULL_TREE; t = TREE_CHAIN (t))
FIELD_PRIVATE (t) = 1;
push_super_field (class_type_node, object_type_node);
@@ -848,6 +1023,12 @@ java_init_decl_processing (void)
= builtin_function ("_Jv_IsInstanceOf",
build_function_type (boolean_type_node, t),
0, NOT_BUILT_IN, NULL, NULL_TREE);
+ t = tree_cons (NULL_TREE, ptr_type_node,
+ tree_cons (NULL_TREE, ptr_type_node, endlink));
+ soft_check_assignment_node
+ = builtin_function ("_Jv_CheckAssignment",
+ build_function_type (void_type_node, t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
t = tree_cons (NULL_TREE, object_ptr_type_node,
tree_cons (NULL_TREE, object_ptr_type_node, endlink));
soft_checkarraystore_node
@@ -861,7 +1042,14 @@ java_init_decl_processing (void)
= builtin_function ("_Jv_LookupInterfaceMethodIdx",
build_function_type (ptr_type_node, t),
0, NOT_BUILT_IN, NULL, NULL_TREE);
-
+
+ t = tree_cons (NULL_TREE, ptr_type_node,
+ tree_cons (NULL_TREE, ptr_type_node,
+ tree_cons (NULL_TREE, ptr_type_node, endlink)));
+ soft_lookupinterfacemethodbyname_node
+ = builtin_function ("_Jv_LookupInterfaceMethod",
+ build_function_type (ptr_type_node, t),
+ 0, NOT_BUILT_IN, NULL, NULL_TREE);
t = tree_cons (NULL_TREE, object_ptr_type_node,
tree_cons (NULL_TREE, ptr_type_node,
tree_cons (NULL_TREE, ptr_type_node,
@@ -1128,6 +1316,20 @@ pushdecl_top_level (tree x)
return t;
}
+/* Like pushdecl, only it places X in FUNCTION_BINDING_LEVEL, if appropriate. */
+
+tree
+pushdecl_function_level (tree x)
+{
+ tree t;
+ struct binding_level *b = current_binding_level;
+
+ current_binding_level = function_binding_level;
+ t = pushdecl (x);
+ current_binding_level = b;
+ return t;
+}
+
/* Nonzero if we are currently in the global binding level. */
int
@@ -1190,7 +1392,7 @@ pushlevel (int unused ATTRIBUTE_UNUSED)
#if defined(DEBUG_JAVA_BINDING_LEVELS)
newlevel->binding_depth = binding_depth;
indent ();
- fprintf (stderr, "push %s level 0x%08x pc %d\n",
+ fprintf (stderr, "push %s level %p pc %d\n",
(is_class_level) ? "class" : "block", newlevel, current_pc);
is_class_level = 0;
binding_depth++;
@@ -1222,18 +1424,18 @@ poplevel (int keep, int reverse, int functionbody)
tree subblocks = current_binding_level->blocks;
tree block = 0;
tree decl;
+ tree bind = 0;
int block_previously_created;
- {
#if defined(DEBUG_JAVA_BINDING_LEVELS)
binding_depth--;
indent ();
if (current_binding_level->end_pc != LARGEST_PC)
- fprintf (stderr, "pop %s level 0x%08x pc %d (end pc %d)\n",
+ fprintf (stderr, "pop %s level %p pc %d (end pc %d)\n",
(is_class_level) ? "class" : "block", current_binding_level, current_pc,
current_binding_level->end_pc);
else
- fprintf (stderr, "pop %s level 0x%08x pc %d\n",
+ fprintf (stderr, "pop %s level %p pc %d\n",
(is_class_level) ? "class" : "block", current_binding_level, current_pc);
#if 0
if (is_class_level != (current_binding_level == class_binding_level))
@@ -1255,37 +1457,11 @@ poplevel (int keep, int reverse, int functionbody)
else
decls = current_binding_level->names;
- /* Output any nested inline functions within this block
- if they weren't already output. */
-
for (decl = decls; decl; decl = TREE_CHAIN (decl))
- if (TREE_CODE (decl) == FUNCTION_DECL
- && ! TREE_ASM_WRITTEN (decl)
- && DECL_INITIAL (decl) != 0
- && TREE_ADDRESSABLE (decl))
- {
- /* If this decl was copied from a file-scope decl on account
- of a block-scope extern decl, propagate TREE_ADDRESSABLE
- to the file-scope decl.
-
- DECL_ABSTRACT_ORIGIN can be set to itself if
- warn_return_type is true, since then the decl goes
- through save_for_inline_copying. */
- if (DECL_ABSTRACT_ORIGIN (decl) != 0
- && DECL_ABSTRACT_ORIGIN (decl) != decl)
- TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
- else
- {
- push_function_context ();
- output_inline_function (decl);
- pop_function_context ();
- }
- }
- else if (TREE_CODE (decl) == VAR_DECL
- && DECL_LANG_SPECIFIC (decl) != NULL
- && DECL_LOCAL_SLOT_NUMBER (decl))
- LOCAL_VAR_OUT_OF_SCOPE_P (decl) = 1;
- }
+ if (TREE_CODE (decl) == VAR_DECL
+ && DECL_LANG_SPECIFIC (decl) != NULL
+ && DECL_LOCAL_SLOT_NUMBER (decl))
+ LOCAL_VAR_OUT_OF_SCOPE_P (decl) = 1;
/* If there were any declarations in that level,
or if this level is a function body,
@@ -1296,12 +1472,57 @@ poplevel (int keep, int reverse, int functionbody)
if (block_previously_created)
block = current_binding_level->this_block;
else if (keep || functionbody)
- block = make_node (BLOCK);
+ {
+ block = make_node (BLOCK);
+ TREE_TYPE (block) = void_type_node;
+ }
+
+ if (current_binding_level->exception_range)
+ expand_end_java_handler (current_binding_level->exception_range);
+
if (block != 0)
{
- BLOCK_VARS (block) = decls;
+ /* If any statements have been generated at this level, create a
+ BIND_EXPR to hold them and copy the variables to it. This
+ only applies to the bytecode compiler. */
+ if (current_binding_level->stmts)
+ {
+ tree decl = decls;
+ tree *var = &BLOCK_VARS (block);
+
+ /* Copy decls from names list, ignoring labels. */
+ while (decl)
+ {
+ tree next = TREE_CHAIN (decl);
+ if (TREE_CODE (decl) != LABEL_DECL)
+ {
+ *var = decl;
+ var = &TREE_CHAIN (decl);
+ }
+ decl = next;
+ }
+ *var = NULL;
+
+ bind = build (BIND_EXPR, TREE_TYPE (block), BLOCK_VARS (block),
+ BLOCK_EXPR_BODY (block), block);
+ BIND_EXPR_BODY (bind) = current_binding_level->stmts;
+
+ if (BIND_EXPR_BODY (bind)
+ && TREE_SIDE_EFFECTS (BIND_EXPR_BODY (bind)))
+ TREE_SIDE_EFFECTS (bind) = 1;
+
+ /* FIXME: gimplifier brain damage. */
+ if (BIND_EXPR_BODY (bind) == NULL)
+ BIND_EXPR_BODY (bind) = build_java_empty_stmt ();
+
+ current_binding_level->stmts = NULL;
+ }
+ else
+ {
+ BLOCK_VARS (block) = decls;
+ }
BLOCK_SUBBLOCKS (block) = subblocks;
- }
+ }
/* In each subblock, record that this is its superior. */
@@ -1386,36 +1607,30 @@ poplevel (int keep, int reverse, int functionbody)
/* Dispose of the block that we just made inside some higher level. */
if (functionbody)
- DECL_INITIAL (current_function_decl) = block;
- else if (block)
{
- if (!block_previously_created)
- current_binding_level->blocks
- = chainon (current_binding_level->blocks, block);
+ DECL_INITIAL (current_function_decl) = block;
+ DECL_SAVED_TREE (current_function_decl) = bind;
+ }
+ else
+ {
+ if (block)
+ {
+ if (!block_previously_created)
+ current_binding_level->blocks
+ = chainon (current_binding_level->blocks, block);
+ }
+ /* If we did not make a block for the level just exited,
+ any blocks made for inner levels
+ (since they cannot be recorded as subblocks in that level)
+ must be carried forward so they will later become subblocks
+ of something else. */
+ else if (subblocks)
+ current_binding_level->blocks
+ = chainon (current_binding_level->blocks, subblocks);
+
+ if (bind)
+ java_add_stmt (bind);
}
- /* If we did not make a block for the level just exited,
- any blocks made for inner levels
- (since they cannot be recorded as subblocks in that level)
- must be carried forward so they will later become subblocks
- of something else. */
- else if (subblocks)
- current_binding_level->blocks
- = chainon (current_binding_level->blocks, subblocks);
-
- /* Set the TYPE_CONTEXTs for all of the tagged types belonging to this
- binding contour so that they point to the appropriate construct, i.e.
- either to the current FUNCTION_DECL node, or else to the BLOCK node
- we just constructed.
-
- Note that for tagged types whose scope is just the formal parameter
- list for some function type specification, we can't properly set
- their TYPE_CONTEXTs here, because we don't have a pointer to the
- appropriate FUNCTION_TYPE node readily available to us. For those
- cases, the TYPE_CONTEXTs of the relevant tagged type nodes get set
- in `grokdeclarator' as soon as we have created the FUNCTION_TYPE
- node which will represent the "scope" for these "parameter list local"
- tagged types.
- */
if (block)
TREE_USED (block) = 1;
@@ -1433,7 +1648,7 @@ maybe_pushlevels (int pc)
DECL_LOCAL_START_PC (pending_local_decls) <= pc)
{
tree *ptr = &pending_local_decls;
- tree decl = *ptr;
+ tree decl = *ptr, next;
int end_pc = DECL_LOCAL_END_PC (decl);
while (*ptr != NULL_TREE
@@ -1443,21 +1658,27 @@ maybe_pushlevels (int pc)
pending_local_decls = *ptr;
*ptr = NULL_TREE;
- /* Force non-nested range to be nested in current range. */
+ /* Force non-nested range to be nested in current range by
+ truncating variable lifetimes. */
if (end_pc > current_binding_level->end_pc)
- end_pc = current_binding_level->end_pc;
+ {
+ end_pc = current_binding_level->end_pc;
+ DECL_LOCAL_END_PC (decl) = end_pc;
+ }
maybe_start_try (pc, end_pc);
pushlevel (1);
- expand_start_bindings (0);
current_binding_level->end_pc = end_pc;
current_binding_level->start_pc = pc;
- current_binding_level->names = decl;
- for ( ; decl != NULL_TREE; decl = TREE_CHAIN (decl))
+ current_binding_level->names = NULL;
+ for ( ; decl != NULL_TREE; decl = next)
{
+ next = TREE_CHAIN (decl);
push_jvm_slot (DECL_LOCAL_SLOT_NUMBER (decl), decl);
+ pushdecl (decl);
+ initialize_local_variable (decl, DECL_LOCAL_SLOT_NUMBER (decl));
}
}
@@ -1473,11 +1694,8 @@ maybe_poplevels (int pc)
while (current_binding_level->end_pc <= pc)
{
- expand_end_bindings (getdecls (), 1, 0);
- maybe_end_try (current_binding_level->start_pc, pc);
poplevel (1, 0, 0);
}
- maybe_end_try (0, pc);
}
/* Terminate any binding which began during the range beginning at
@@ -1494,7 +1712,6 @@ force_poplevels (int start_pc)
warning ("%JIn %D: overlapped variable and exception ranges at %d",
current_function_decl, current_function_decl,
current_binding_level->start_pc);
- expand_end_bindings (getdecls (), 1, 0);
poplevel (1, 0, 0);
}
}
@@ -1579,7 +1796,7 @@ give_name_to_locals (JCF *jcf)
if (end_pc > DECL_CODE_LENGTH (current_function_decl))
{
warning ("%Jbad PC range for debug info for local '%D'",
- decl, decl);
+ decl, decl);
end_pc = DECL_CODE_LENGTH (current_function_decl);
}
@@ -1658,88 +1875,19 @@ build_result_decl (tree fndecl)
}
void
-complete_start_java_method (tree fndecl)
-{
- if (! flag_emit_class_files)
- {
- /* Initialize the RTL code for the function. */
- init_function_start (fndecl);
-
- /* Set up parameters and prepare for return, for the function. */
- expand_function_start (fndecl, 0);
- }
-
-#if 0
- /* If this fcn was already referenced via a block-scope `extern' decl (or
- an implicit decl), propagate certain information about the usage. */
- if (TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (current_function_decl)))
- TREE_ADDRESSABLE (current_function_decl) = 1;
-
-#endif
-
- if (METHOD_STATIC (fndecl) && ! METHOD_PRIVATE (fndecl)
- && ! flag_emit_class_files
- && ! DECL_CLINIT_P (fndecl)
- && ! CLASS_INTERFACE (TYPE_NAME (current_class)))
- {
- tree clas = DECL_CONTEXT (fndecl);
- tree init = build (CALL_EXPR, void_type_node,
- build_address_of (soft_initclass_node),
- build_tree_list (NULL_TREE, build_class_ref (clas)),
- NULL_TREE);
- TREE_SIDE_EFFECTS (init) = 1;
- expand_expr_stmt (init);
- }
-
- /* Push local variables. Function compiled from source code are
- using a different local variables management, and for them,
- pushlevel shouldn't be called from here. */
- if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (fndecl)))
- {
- pushlevel (2);
- if (! flag_emit_class_files)
- expand_start_bindings (1);
- }
-
- if (METHOD_SYNCHRONIZED (fndecl) && ! flag_emit_class_files)
- {
- /* Wrap function body with a monitorenter plus monitorexit cleanup. */
- tree enter, exit, lock;
- if (METHOD_STATIC (fndecl))
- lock = build_class_ref (DECL_CONTEXT (fndecl));
- else
- lock = DECL_ARGUMENTS (fndecl);
- BUILD_MONITOR_ENTER (enter, lock);
- BUILD_MONITOR_EXIT (exit, lock);
- if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (fndecl)))
- {
- expand_expr_stmt (enter);
- expand_decl_cleanup (NULL_TREE, exit);
- }
- else
- {
- tree function_body = DECL_FUNCTION_BODY (fndecl);
- tree body = BLOCK_EXPR_BODY (function_body);
- lock = build (COMPOUND_EXPR, void_type_node,
- enter,
- build (TRY_FINALLY_EXPR, void_type_node, body, exit));
- TREE_SIDE_EFFECTS (lock) = 1;
- BLOCK_EXPR_BODY (function_body) = lock;
- }
- }
-}
-
-void
start_java_method (tree fndecl)
{
tree tem, *ptr;
int i;
+ uniq = 0;
+
current_function_decl = fndecl;
announce_function (fndecl);
i = DECL_MAX_LOCALS(fndecl) + DECL_MAX_STACK(fndecl);
decl_map = make_tree_vec (i);
+ base_decl_map = make_tree_vec (i);
type_map = xrealloc (type_map, i * sizeof (tree));
#if defined(DEBUG_JAVA_BINDING_LEVELS)
@@ -1785,7 +1933,11 @@ start_java_method (tree fndecl)
type_map[i++] = NULL_TREE;
build_result_decl (fndecl);
- complete_start_java_method (fndecl);
+
+ /* Push local variables. */
+ pushlevel (2);
+
+ function_binding_level = current_binding_level;
}
void
@@ -1793,7 +1945,6 @@ end_java_method (void)
{
tree fndecl = current_function_decl;
- expand_end_bindings (getdecls (), 1, 0);
/* pop out of function */
poplevel (1, 1, 0);
@@ -1802,64 +1953,80 @@ end_java_method (void)
BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
- /* Generate rtl for function exit. */
- expand_function_end ();
+ flag_unit_at_a_time = 0;
+ finish_method (fndecl);
- /* Run the optimizers and output assembler code for this function. */
- rest_of_compilation (fndecl);
+ if (! flag_unit_at_a_time)
+ {
+ /* Nulling these fields when we no longer need them saves
+ memory. */
+ DECL_SAVED_TREE (fndecl) = NULL;
+ DECL_STRUCT_FUNCTION (fndecl) = NULL;
+ DECL_INITIAL (fndecl) = NULL_TREE;
+ }
current_function_decl = NULL_TREE;
}
-/* Expand a function's body. */
+/* Prepare a method for expansion. */
void
-java_expand_body (tree fndecl)
+finish_method (tree fndecl)
{
- location_t saved_location = input_location;
-
- current_function_decl = fndecl;
- input_location = DECL_SOURCE_LOCATION (fndecl);
- output_class = current_class = DECL_CONTEXT (fndecl);
+ tree *tp = &DECL_SAVED_TREE (fndecl);
- timevar_push (TV_EXPAND);
-
- /* Prepare the function for tree completion. */
- start_complete_expand_method (fndecl);
-
- if (! flag_emit_class_files && ! flag_emit_xref)
+ /* Wrap body of synchronized methods in a monitorenter,
+ plus monitorexit cleanup. */
+ if (METHOD_SYNCHRONIZED (fndecl))
{
- /* Initialize the RTL code for the function. */
- init_function_start (fndecl);
-
- /* Set up parameters and prepare for return, for the function. */
- expand_function_start (fndecl, 0);
-
- /* Generate the RTL for this function. */
- expand_expr_stmt_value (DECL_SAVED_TREE (fndecl), 0, 1);
+ tree enter, exit, lock;
+ if (METHOD_STATIC (fndecl))
+ lock = build_class_ref (DECL_CONTEXT (fndecl));
+ else
+ lock = DECL_ARGUMENTS (fndecl);
+ BUILD_MONITOR_ENTER (enter, lock);
+ BUILD_MONITOR_EXIT (exit, lock);
+ *tp = build (COMPOUND_EXPR, void_type_node,
+ enter,
+ build (TRY_FINALLY_EXPR, void_type_node, *tp, exit));
}
- /* Pop out of its parameters. */
- pushdecl_force_head (DECL_ARGUMENTS (fndecl));
- poplevel (1, 0, 1);
- BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
-
- if (! flag_emit_class_files && ! flag_emit_xref)
+ /* Prepend class initialization for static methods reachable from
+ other classes. */
+ if (METHOD_STATIC (fndecl) && ! METHOD_PRIVATE (fndecl)
+ && ! DECL_CLINIT_P (fndecl)
+ && ! CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (fndecl))))
{
- /* Generate RTL for function exit. */
- input_line = DECL_FUNCTION_LAST_LINE (fndecl);
- expand_function_end ();
-
- /* Run the optimizers and output the assembler code
- for this function. */
- rest_of_compilation (fndecl);
+ tree clas = DECL_CONTEXT (fndecl);
+ tree init = build (CALL_EXPR, void_type_node,
+ build_address_of (soft_initclass_node),
+ build_tree_list (NULL_TREE, build_class_ref (clas)),
+ NULL_TREE);
+ *tp = build (COMPOUND_EXPR, TREE_TYPE (*tp), init, *tp);
}
- timevar_pop (TV_EXPAND);
+ /* Convert function tree to GENERIC prior to inlining. */
+ java_genericize (fndecl);
- input_location = saved_location;
+ /* Store the end of the function, so that we get good line number
+ info for the epilogue. */
+ if (DECL_STRUCT_FUNCTION (fndecl))
+ cfun = DECL_STRUCT_FUNCTION (fndecl);
+ else
+ allocate_struct_function (fndecl);
+ cfun->function_end_locus.file = DECL_SOURCE_FILE (fndecl);
+ cfun->function_end_locus.line = DECL_FUNCTION_LAST_LINE (fndecl);
- current_function_decl = NULL_TREE;
+ /* Defer inlining and expansion to the cgraph optimizers. */
+ cgraph_finalize_function (fndecl, false);
+}
+
+/* Optimize and expand a function's entire body. */
+
+void
+java_expand_body (tree fndecl)
+{
+ tree_rest_of_compilation (fndecl, 0);
}
/* We pessimistically marked all methods and fields external until we
@@ -1891,4 +2058,76 @@ java_mark_class_local (tree class)
java_mark_decl_local (t);
}
+/* Add a statement to a compound_expr. */
+
+tree
+add_stmt_to_compound (existing, type, stmt)
+ tree existing, type, stmt;
+{
+ if (!stmt)
+ return existing;
+ else if (existing)
+ {
+ tree expr = build (COMPOUND_EXPR, type, existing, stmt);
+ TREE_SIDE_EFFECTS (expr)
+ = TREE_SIDE_EFFECTS (existing) | TREE_SIDE_EFFECTS (stmt);
+ return expr;
+ }
+ else
+ return stmt;
+}
+
+/* Add a statement to the compound_expr currently being
+ constructed. */
+
+tree
+java_add_stmt (stmt)
+ tree stmt;
+{
+ if (input_filename)
+ annotate_with_locus (stmt, input_location);
+
+ return current_binding_level->stmts
+ = add_stmt_to_compound (current_binding_level->stmts,
+ TREE_TYPE (stmt), stmt);
+}
+
+/* Add a variable to the current scope. */
+
+tree
+java_add_local_var (tree decl)
+{
+ tree *vars = &current_binding_level->names;
+ tree next = *vars;
+ TREE_CHAIN (decl) = next;
+ *vars = decl;
+ DECL_CONTEXT (decl) = current_function_decl;
+ MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
+ return decl;
+}
+
+/* Return a pointer to the compound_expr currently being
+ constructed. */
+
+tree *
+get_stmts (void)
+{
+ return &current_binding_level->stmts;
+}
+
+/* Register an exception range as belongling to the current binding
+ level. There may only be one: if there are more, we'll create more
+ binding levels. However, each range can have multiple handlers,
+ and these are expanded when we call expand_end_java_handler(). */
+
+void
+register_exception_range (struct eh_range *range, int pc, int end_pc)
+{
+ if (current_binding_level->exception_range)
+ abort ();
+ current_binding_level->exception_range = range;
+ current_binding_level->end_pc = end_pc;
+ current_binding_level->start_pc = pc;
+}
+
#include "gt-java-decl.h"
diff --git a/gcc/java/except.c b/gcc/java/except.c
index c5c7dcf27f4..91f741f63d0 100644
--- a/gcc/java/except.c
+++ b/gcc/java/except.c
@@ -40,7 +40,6 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "toplev.h"
static void expand_start_java_handler (struct eh_range *);
-static void expand_end_java_handler (struct eh_range *);
static struct eh_range *find_handler_in_range (int, struct eh_range *,
struct eh_range *);
static void link_handler (struct eh_range *, struct eh_range *);
@@ -170,6 +169,7 @@ link_handler (struct eh_range *range, struct eh_range *outer)
TREE_VALUE (range->handlers));
h->next_sibling = NULL;
h->expanded = 0;
+ h->stmt = NULL;
/* Restart both from the top to avoid having to make this
function smart about reentrancy. */
link_handler (h, &whole_range);
@@ -287,6 +287,7 @@ add_handler (int start_pc, int end_pc, tree handler, tree type)
h->handlers = build_tree_list (type, handler);
h->next_sibling = NULL;
h->expanded = 0;
+ h->stmt = NULL;
if (prev == NULL)
whole_range.first_child = h;
@@ -294,7 +295,6 @@ add_handler (int start_pc, int end_pc, tree handler, tree type)
prev->next_sibling = h;
}
-
/* if there are any handlers for this range, issue start of region */
static void
expand_start_java_handler (struct eh_range *range)
@@ -304,8 +304,9 @@ expand_start_java_handler (struct eh_range *range)
fprintf (stderr, "expand start handler pc %d --> %d\n",
current_pc, range->end_pc);
#endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */
+ pushlevel (0);
+ register_exception_range (range, range->start_pc, range->end_pc);
range->expanded = 1;
- expand_eh_region_start ();
}
tree
@@ -348,7 +349,7 @@ prepare_eh_table_type (tree type)
DECL_INITIAL (decl) = build_class_ref (type);
layout_decl (decl, 0);
pushdecl (decl);
- exp = build1 (ADDR_EXPR, ptr_type_node, decl);
+ exp = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (decl)), decl);
}
else
{
@@ -370,6 +371,8 @@ prepare_eh_table_type (tree type)
TYPE_CATCH_CLASSES (output_class));
}
+ exp = convert (ptr_type_node, exp);
+
*slot = tree_cons (type, exp, NULL_TREE);
return exp;
@@ -379,7 +382,10 @@ static int
expand_catch_class (void **entry, void *x ATTRIBUTE_UNUSED)
{
struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
- tree decl = TREE_OPERAND (TREE_VALUE ((tree)ite->value), 0);
+ tree addr = TREE_VALUE ((tree)ite->value);
+ tree decl;
+ STRIP_NOPS (addr);
+ decl = TREE_OPERAND (addr, 0);
rest_of_decl_compilation (decl, (char*) 0, global_bindings_p (), 0);
return true;
}
@@ -416,12 +422,11 @@ build_exception_object_ref (tree type)
/* If there are any handlers for this range, isssue end of range,
and then all handler blocks */
-static void
+void
expand_end_java_handler (struct eh_range *range)
{
tree handler = range->handlers;
- force_poplevels (range->start_pc);
- expand_start_all_catch ();
+
for ( ; handler != NULL_TREE; handler = TREE_CHAIN (handler))
{
/* For bytecode we treat exceptions a little unusually. A
@@ -433,12 +438,17 @@ expand_end_java_handler (struct eh_range *range)
tree type = TREE_PURPOSE (handler);
if (type == NULL)
type = throwable_type_node;
+ type = prepare_eh_table_type (type);
- expand_start_catch (prepare_eh_table_type (type));
- expand_goto (TREE_VALUE (handler));
- expand_end_catch ();
+ {
+ tree catch_expr
+ = build (CATCH_EXPR, void_type_node, type,
+ build (GOTO_EXPR, void_type_node, TREE_VALUE (handler)));
+ tree try_catch_expr = build (TRY_CATCH_EXPR, void_type_node,
+ *get_stmts (), catch_expr);
+ *get_stmts () = try_catch_expr;
+ }
}
- expand_end_all_catch ();
#if defined(DEBUG_JAVA_BINDING_LEVELS)
indent ();
fprintf (stderr, "expand end handler pc %d <-- %d\n",
@@ -481,19 +491,3 @@ maybe_start_try (int start_pc, int end_pc)
check_start_handlers (range, start_pc);
}
-/* Emit any end-of-try-range ending at end_pc and starting before
- start_pc. */
-
-void
-maybe_end_try (int start_pc, int end_pc)
-{
- if (! doing_eh (1))
- return;
-
- while (current_range != NULL_EH_RANGE && current_range->end_pc <= end_pc
- && current_range->start_pc >= start_pc)
- {
- expand_end_java_handler (current_range);
- current_range = current_range->outer;
- }
-}
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index 95c3b69d7d9..daa02063b86 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -43,6 +43,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "toplev.h"
#include "except.h"
#include "ggc.h"
+#include "tree-gimple.h"
#include "target.h"
static void flush_quick_stack (void);
@@ -71,6 +72,8 @@ static void expand_compare (enum tree_code, tree, tree, int);
static void expand_test (enum tree_code, tree, int);
static void expand_cond (enum tree_code, tree, int);
static void expand_java_goto (int);
+static tree expand_java_switch (tree, int);
+static void expand_java_add_case (tree, int, int);
#if 0
static void expand_java_call (int, int);
static void expand_java_ret (tree);
@@ -94,7 +97,8 @@ tree dtable_ident = NULL_TREE;
/* Set to nonzero value in order to emit class initialization code
before static field references. */
-int always_initialize_class_p;
+/* FIXME: Make this work with gimplify. */
+int always_initialize_class_p = 1;
/* We store the stack state in two places:
Within a basic block, we use the quick_stack, which is a
@@ -231,7 +235,7 @@ flush_quick_stack (void)
decl = find_stack_slot (stack_index, type);
if (decl != node)
- expand_assignment (decl, node, 0);
+ java_add_stmt (build (MODIFY_EXPR, TREE_TYPE (node), decl, node));
stack_index += 1 + TYPE_IS_WIDE (type);
}
}
@@ -247,6 +251,9 @@ push_type_0 (tree type)
n_words = 1 + TYPE_IS_WIDE (type);
if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
return 0;
+ /* Allocate decl for this variable now, so we get a temporary that
+ survives the whole method. */
+ find_stack_slot (stack_pointer, type);
stack_type_map[stack_pointer++] = type;
n_words--;
while (--n_words >= 0)
@@ -313,6 +320,21 @@ pop_type_0 (tree type, char **messagep)
t = stack_type_map[--stack_pointer];
if (type == NULL_TREE || t == type)
return t;
+ if (TREE_CODE (t) == TREE_LIST)
+ {
+ do
+ {
+ tree tt = TREE_PURPOSE (t);
+ if (! can_widen_reference_to (tt, type))
+ {
+ t = tt;
+ goto fail;
+ }
+ t = TREE_CHAIN (t);
+ }
+ while (t);
+ return t;
+ }
if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
&& TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
return t;
@@ -322,17 +344,27 @@ pop_type_0 (tree type, char **messagep)
return t;
else if (t == ptr_type_node) /* Special case for null reference. */
return type;
- else if (can_widen_reference_to (t, type))
- return t;
/* This is a kludge, but matches what Sun's verifier does.
It can be tricked, but is safe as long as type errors
(i.e. interface method calls) are caught at run-time. */
else if (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (type))))
return object_ptr_type_node;
+ else if (can_widen_reference_to (t, type))
+ return t;
+ }
+
+ if (! flag_verify_invocations && flag_indirect_dispatch
+ && t == object_ptr_type_node)
+ {
+ if (type != ptr_type_node)
+ warning ("need to insert runtime check for %s",
+ xstrdup (lang_printable_name (type, 0)));
+ return type;
}
/* lang_printable_name uses a static buffer, so we must save the result
from calling it the first time. */
+ fail:
{
char *temp = xstrdup (lang_printable_name (type, 0));
*messagep = concat ("expected type '", temp,
@@ -351,7 +383,7 @@ tree
pop_type (tree type)
{
char *message = NULL;
- type = pop_type_0 (type, &message);
+ type = pop_type_0 (type, &message);
if (message != NULL)
{
error ("%s", message);
@@ -360,7 +392,131 @@ pop_type (tree type)
return type;
}
-/* Return 1f if SOURCE_TYPE can be safely widened to TARGET_TYPE.
+
+/* Return true if two type assertions are equal. */
+
+static int
+type_assertion_eq (const void * k1_p, const void * k2_p)
+{
+ type_assertion k1 = *(type_assertion *)k1_p;
+ type_assertion k2 = *(type_assertion *)k2_p;
+ return (k1.source_type == k2.source_type
+ && k1.target_type == k2.target_type);
+}
+
+/* Hash a type assertion. */
+
+static hashval_t
+type_assertion_hash (const void *p)
+{
+ const type_assertion *k_p = p;
+ hashval_t hash = iterative_hash (&k_p->target_type, sizeof k_p->target_type, 0);
+ return iterative_hash (&k_p->source_type, sizeof k_p->source_type, hash);
+}
+
+/* Given a type, return the signature used by
+ _Jv_FindClassFromSignature() in libgcj. This isn't exactly the
+ same as build_java_signature() because we want the canonical array
+ type. */
+
+static tree
+build_signature_for_libgcj (tree type)
+{
+ tree sig, ref;
+
+ sig = build_java_signature (type);
+ ref = build_utf8_ref (unmangle_classname (IDENTIFIER_POINTER (sig),
+ IDENTIFIER_LENGTH (sig)));
+ return ref;
+}
+
+/* Add an assertion of the form "source_type is a subclass/
+ subinterface of target_type" to the "__verify" function of the
+ current class. */
+
+static void
+add_type_assertion (tree source_type, tree target_type)
+{
+ tree verify_method = TYPE_VERIFY_METHOD (output_class);
+ tree itype = TREE_TYPE (TREE_TYPE (soft_instanceof_node));
+ tree arg;
+
+ if (TYPE_ARRAY_P (source_type))
+ {
+ // FIXME: This is just a placeholder for merged types. We need to
+ // do something more real than this.
+ if (TYPE_ARRAY_ELEMENT (source_type) == object_type_node)
+ return;
+ source_type = build_java_array_type (TYPE_ARRAY_ELEMENT (source_type), -1);
+ }
+ if (TYPE_ARRAY_P (target_type))
+ target_type = build_java_array_type (TYPE_ARRAY_ELEMENT (target_type), -1);
+
+ if (target_type == object_type_node)
+ return;
+
+ if (source_type == target_type)
+ return;
+
+ // FIXME: This is just a placeholder for merged types. We need to
+ // do something more real than this.
+ if (source_type == object_type_node)
+ return;
+
+ if (! verify_method)
+ {
+ arg = build_decl (PARM_DECL, get_identifier ("classLoader"), ptr_type_node);
+ DECL_CONTEXT (arg) = verify_method;
+ DECL_ARG_TYPE (arg) = ptr_type_node;
+ verify_method
+ = build_decl (FUNCTION_DECL, verify_identifier_node,
+ build_function_type (ptr_type_node, end_params_node));
+ DECL_ARGUMENTS (verify_method) = arg;
+ DECL_ARTIFICIAL (verify_method) = 1;
+ TREE_PUBLIC (verify_method) = 0;
+ DECL_EXTERNAL (verify_method) = 0;
+ TREE_PRIVATE (verify_method) = 1;
+ TREE_STATIC (verify_method) = 1;
+ TYPE_VERIFY_METHOD (output_class) = verify_method;
+ build_result_decl (verify_method);
+ DECL_INITIAL (verify_method) = build (BLOCK, void_type_node);
+ DECL_CONTEXT (verify_method) = output_class;
+ TYPE_ASSERTIONS (output_class)
+ = htab_create_ggc (42, type_assertion_hash, type_assertion_eq, NULL);
+ }
+
+ {
+ /* Don't emit the same type assertion twice. */
+ type_assertion as;
+ void **as_pp;
+ as.source_type = source_type;
+ as.target_type = target_type;
+ as_pp = htab_find_slot (TYPE_ASSERTIONS (output_class), &as, true);
+ if (*as_pp)
+ return;
+ *as_pp = ggc_alloc (sizeof (type_assertion));
+ **(type_assertion **)as_pp = as;
+ }
+
+ {
+ tree source_ref = build_signature_for_libgcj (source_type);
+ tree target_ref = build_signature_for_libgcj (target_type);
+ tree args, expr;
+
+ args = tree_cons (NULL_TREE, source_ref,
+ build_tree_list (NULL_TREE, target_ref));
+ args = chainon (build_tree_list (NULL_TREE, DECL_ARGUMENTS (verify_method)), args);
+ expr = build (CALL_EXPR, itype,
+ build_address_of (soft_check_assignment_node),
+ args, NULL_TREE);
+ DECL_SAVED_TREE (verify_method)
+ = add_stmt_to_compound (DECL_SAVED_TREE (verify_method), itype, expr);
+ }
+}
+
+
+
+/* Return 1 if SOURCE_TYPE can be safely widened to TARGET_TYPE.
Handles array types and interfaces. */
int
@@ -377,6 +533,27 @@ can_widen_reference_to (tree source_type, tree target_type)
if (source_type == target_type)
return 1;
+
+ /* FIXME: This is very pessimistic, in that it checks everything,
+ even if we already know that the types are compatible. If we're
+ to support full Java class loader semantics, we need this.
+ However, we could do something more optimal. */
+ if (! flag_verify_invocations)
+ {
+ add_type_assertion (source_type, target_type);
+
+ if (!quiet_flag)
+ warning ("assert: %s is assign compatible with %s",
+ xstrdup (lang_printable_name (target_type, 0)),
+ xstrdup (lang_printable_name (source_type, 0)));
+ /* Punt everything to runtime. */
+ return 1;
+ }
+
+ if (TYPE_DUMMY (source_type) || TYPE_DUMMY (target_type))
+ {
+ return 1;
+ }
else
{
if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
@@ -410,7 +587,16 @@ can_widen_reference_to (tree source_type, tree target_type)
int source_depth = class_depth (source_type);
int target_depth = class_depth (target_type);
- /* class_depth can return a negative depth if an error occurred */
+ if (TYPE_DUMMY (source_type) || TYPE_DUMMY (target_type))
+ {
+ if (! quiet_flag)
+ warning ("assert: %s is assign compatible with %s",
+ xstrdup (lang_printable_name (target_type, 0)),
+ xstrdup (lang_printable_name (source_type, 0)));
+ return 1;
+ }
+
+ /* class_depth can return a negative depth if an error occurred */
if (source_depth < 0 || target_depth < 0)
return 0;
@@ -489,7 +675,7 @@ static void
java_stack_swap (void)
{
tree type1, type2;
- rtx temp;
+ tree temp;
tree decl1, decl2;
if (stack_pointer < 2
@@ -503,10 +689,15 @@ java_stack_swap (void)
flush_quick_stack ();
decl1 = find_stack_slot (stack_pointer - 1, type1);
decl2 = find_stack_slot (stack_pointer - 2, type2);
- temp = copy_to_reg (DECL_RTL (decl1));
- emit_move_insn (DECL_RTL (find_stack_slot (stack_pointer - 1, type2)),
- DECL_RTL (decl2));
- emit_move_insn (DECL_RTL (find_stack_slot (stack_pointer - 2, type1)), temp);
+ temp = build_decl (VAR_DECL, NULL_TREE, type1);
+ java_add_local_var (temp);
+ java_add_stmt (build (MODIFY_EXPR, type1, temp, decl1));
+ java_add_stmt (build (MODIFY_EXPR, type2,
+ find_stack_slot (stack_pointer - 1, type2),
+ decl2));
+ java_add_stmt (build (MODIFY_EXPR, type1,
+ find_stack_slot (stack_pointer - 2, type1),
+ temp));
stack_type_map[stack_pointer - 1] = type2;
stack_type_map[stack_pointer - 2] = type1;
}
@@ -550,7 +741,9 @@ java_stack_dup (int size, int offset)
{
tree src_decl = find_stack_slot (src_index, type);
tree dst_decl = find_stack_slot (dst_index, type);
- emit_move_insn (DECL_RTL (dst_decl), DECL_RTL (src_decl));
+
+ java_add_stmt
+ (build (MODIFY_EXPR, TREE_TYPE (dst_decl), dst_decl, src_decl));
stack_type_map[dst_index] = type;
}
}
@@ -570,7 +763,7 @@ build_java_athrow (tree node)
build_tree_list (NULL_TREE, node),
NULL_TREE);
TREE_SIDE_EFFECTS (call) = 1;
- expand_expr_stmt (call);
+ java_add_stmt (call);
java_stack_pop (stack_pointer);
}
@@ -584,16 +777,17 @@ build_java_jsr (int target_pc, int return_pc)
tree ret_label = fold (build1 (ADDR_EXPR, return_address_type_node, ret));
push_value (ret_label);
flush_quick_stack ();
- emit_jump (label_rtx (where));
- expand_label (ret);
- if (instruction_bits [return_pc] & BCODE_VERIFIED)
- load_type_state (ret);
+ java_add_stmt (build (GOTO_EXPR, void_type_node, where));
+
+ /* Do not need to emit the label here. We noted the existance of the
+ label as a jump target in note_instructions; we'll emit the label
+ for real at the beginning of the expand_byte_code loop. */
}
static void
build_java_ret (tree location)
{
- expand_computed_goto (location);
+ java_add_stmt (build (GOTO_EXPR, void_type_node, location));
}
/* Implementation of operations on array: new, load, store, length */
@@ -713,7 +907,10 @@ java_check_reference (tree expr, int check)
tree
build_java_indirect_ref (tree type, tree expr, int check)
{
- return build1 (INDIRECT_REF, type, java_check_reference (expr, check));
+ tree t;
+ t = java_check_reference (expr, check);
+ t = convert (build_pointer_type (type), t);
+ return build1 (INDIRECT_REF, type, t);
}
/* Implement array indexing (either as l-value or r-value).
@@ -978,13 +1175,11 @@ expand_java_arraystore (tree rhs_type_node)
if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
{
tree check = build_java_arraystore_check (array, rhs_node);
- expand_expr_stmt (check);
+ java_add_stmt (check);
}
- expand_assignment (build_java_arrayaccess (array,
- rhs_type_node,
- index),
- rhs_node, 0);
+ array = build_java_arrayaccess (array, rhs_type_node, index);
+ java_add_stmt (build (MODIFY_EXPR, TREE_TYPE (array), array, rhs_node));
}
/* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes
@@ -1077,7 +1272,7 @@ static void
expand_java_return (tree type)
{
if (type == void_type_node)
- expand_null_return ();
+ java_add_stmt (build (RETURN_EXPR, void_type_node, NULL));
else
{
tree retval = pop_value (type);
@@ -1094,7 +1289,7 @@ expand_java_return (tree type)
retval = build1(NOP_EXPR, TREE_TYPE(res), retval);
TREE_SIDE_EFFECTS (retval) = 1;
- expand_return (retval);
+ java_add_stmt (build (RETURN_EXPR, TREE_TYPE (retval), retval));
}
}
@@ -1111,13 +1306,9 @@ expand_load_internal (int index, tree type, int pc)
value into it. Then we push this new local on the stack.
Hopefully this all gets optimized out. */
copy = build_decl (VAR_DECL, NULL_TREE, type);
- DECL_CONTEXT (copy) = current_function_decl;
- layout_decl (copy, 0);
- DECL_REGISTER (copy) = 1;
- expand_decl (copy);
- MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (copy);
- DECL_INITIAL (copy) = var;
- expand_decl_init (copy);
+ java_add_local_var (copy);
+ java_add_stmt (build (MODIFY_EXPR, TREE_TYPE (var), copy, var));
+
push_value (copy);
}
@@ -1138,6 +1329,19 @@ bool class_has_finalize_method (tree type)
return HAS_FINALIZER_P (type) || class_has_finalize_method (super);
}
+tree
+java_create_object (tree type)
+{
+ tree alloc_node = (class_has_finalize_method (type)
+ ? alloc_object_node
+ : alloc_no_finalizer_node);
+
+ return build (CALL_EXPR, promote_type (type),
+ build_address_of (alloc_node),
+ build_tree_list (NULL_TREE, build_class_ref (type)),
+ NULL_TREE);
+}
+
static void
expand_java_NEW (tree type)
{
@@ -1148,12 +1352,7 @@ expand_java_NEW (tree type)
if (! CLASS_LOADED_P (type))
load_class (type, 1);
safe_layout_class (type);
- push_value (build (CALL_EXPR, promote_type (type),
- build_address_of (alloc_node),
- tree_cons (NULL_TREE, build_class_ref (type),
- build_tree_list (NULL_TREE,
- size_in_bytes (type))),
- NULL_TREE));
+ push_value (java_create_object (type));
}
/* This returns an expression which will extract the class of an
@@ -1205,7 +1404,8 @@ build_instanceof (tree value, tree type)
we only need to check for `null'. */
expr = build (NE_EXPR, itype, value, null_pointer_node);
}
- else if (! TYPE_ARRAY_P (type)
+ else if (flag_verify_invocations
+ && ! TYPE_ARRAY_P (type)
&& ! TYPE_ARRAY_P (valtype)
&& DECL_P (klass) && DECL_P (valclass)
&& ! CLASS_INTERFACE (valclass)
@@ -1222,7 +1422,8 @@ build_instanceof (tree value, tree type)
{
tree save = save_expr (value);
expr = build (COND_EXPR, itype,
- save,
+ build (NE_EXPR, boolean_type_node,
+ save, null_pointer_node),
build (EQ_EXPR, itype,
build_get_class (save),
build_class_ref (type)),
@@ -1271,10 +1472,11 @@ expand_iinc (unsigned int local_var_index, int ival, int pc)
local_var = find_local_variable (local_var_index, int_type_node, pc);
constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
- expand_assignment (local_var, res, 0);
+ java_add_stmt (build (MODIFY_EXPR, TREE_TYPE (local_var), local_var, res));
+ update_aliases (local_var, local_var_index, pc);
}
-
+
tree
build_java_soft_divmod (enum tree_code op, tree type, tree op1, tree op2)
{
@@ -1511,12 +1713,13 @@ build_field_ref (tree self_value, tree self_class, tree name)
tree base_type = promote_type (base_class);
if (base_type != TREE_TYPE (self_value))
self_value = fold (build1 (NOP_EXPR, base_type, self_value));
- if (flag_indirect_dispatch
- && output_class != self_class)
- /* FIXME: output_class != self_class is not exactly the right
- test. What we really want to know is whether self_class is
- in the same translation unit as output_class. If it is,
- we can make a direct reference. */
+ if (! flag_syntax_only
+ && (flag_indirect_dispatch
+ /* DECL_FIELD_OFFSET == 0 if we have no reference for
+ the field, perhaps because we couldn't find the class
+ in which the field is defined.
+ FIXME: We should investigate this. */
+ || DECL_FIELD_OFFSET (field_decl) == 0))
{
tree otable_index =
build_int_2 (get_symbol_table_index
@@ -1554,7 +1757,6 @@ lookup_label (int pc)
/* The type of the address of a label is return_address_type_node. */
tree decl = create_label_decl (name);
LABEL_PC (decl) = pc;
- label_rtx (decl);
return pushdecl (decl);
}
}
@@ -1602,9 +1804,10 @@ expand_compare (enum tree_code condition, tree value1, tree value2,
{
tree target = lookup_label (target_pc);
tree cond = fold (build (condition, boolean_type_node, value1, value2));
- expand_start_cond (java_truthvalue_conversion (cond), 0);
- expand_goto (target);
- expand_end_cond ();
+ java_add_stmt
+ (build (COND_EXPR, void_type_node, java_truthvalue_conversion (cond),
+ build (GOTO_EXPR, void_type_node, target),
+ build_java_empty_stmt ()));
}
/* Emit code for a TEST-type opcode. */
@@ -1638,32 +1841,44 @@ expand_java_goto (int target_pc)
{
tree target_label = lookup_label (target_pc);
flush_quick_stack ();
- expand_goto (target_label);
+ java_add_stmt (build (GOTO_EXPR, void_type_node, target_label));
}
-#if 0
-static void
-expand_java_call (int target_pc, int return_address)
- int target_pc, return_address;
+static tree
+expand_java_switch (tree selector, int default_pc)
{
- tree target_label = lookup_label (target_pc);
- tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
- push_value (value);
+ tree switch_expr, x;
+
flush_quick_stack ();
- expand_goto (target_label);
+ switch_expr = build (SWITCH_EXPR, TREE_TYPE (selector), selector,
+ NULL_TREE, NULL_TREE);
+ java_add_stmt (switch_expr);
+
+ x = build (CASE_LABEL_EXPR, void_type_node, NULL_TREE, NULL_TREE,
+ create_artificial_label ());
+ append_to_statement_list (x, &SWITCH_BODY (switch_expr));
+
+ x = build (GOTO_EXPR, void_type_node, lookup_label (default_pc));
+ append_to_statement_list (x, &SWITCH_BODY (switch_expr));
+
+ return switch_expr;
}
static void
-expand_java_ret (tree return_address ATTRIBUTE_UNUSED)
+expand_java_add_case (tree switch_expr, int match, int target_pc)
{
- warning ("ret instruction not implemented");
-#if 0
- tree target_label = lookup_label (target_pc);
- flush_quick_stack ();
- expand_goto (target_label);
-#endif
+ tree value, x;
+
+ value = build_int_2 (match, match < 0 ? -1 : 0);
+ TREE_TYPE (value) = TREE_TYPE (switch_expr);
+
+ x = build (CASE_LABEL_EXPR, void_type_node, value, NULL_TREE,
+ create_artificial_label ());
+ append_to_statement_list (x, &SWITCH_BODY (switch_expr));
+
+ x = build (GOTO_EXPR, void_type_node, lookup_label (target_pc));
+ append_to_statement_list (x, &SWITCH_BODY (switch_expr));
}
-#endif
static tree
pop_arguments (tree arg_types)
@@ -1730,6 +1945,7 @@ build_class_init (tree clas, tree expr)
optimizing class initialization. */
if (!STATIC_CLASS_INIT_OPT_P ())
DECL_BIT_INDEX(*init_test_decl) = -1;
+ DECL_INITIAL (*init_test_decl) = integer_zero_node;
/* Don't emit any symbolic debugging info for this decl. */
DECL_IGNORED_P (*init_test_decl) = 1;
}
@@ -1767,11 +1983,16 @@ build_known_method_ref (tree method, tree method_type ATTRIBUTE_UNUSED,
tree func;
if (is_compiled_class (self_type))
{
- if (!flag_indirect_dispatch
- || (!TREE_PUBLIC (method) && DECL_CONTEXT (method)))
+ /* With indirect dispatch we have to use indirect calls for all
+ publically visible methods or gcc will use PLT indirections
+ to reach them. We also have to use indirect dispatch for all
+ external methods. */
+ if (! flag_indirect_dispatch
+ || (! DECL_EXTERNAL (method) && ! TREE_PUBLIC (method)))
{
make_decl_rtl (method, NULL);
- func = build1 (ADDR_EXPR, method_ptr_type_node, method);
+ func = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (method)),
+ method);
}
else
{
@@ -1779,9 +2000,11 @@ build_known_method_ref (tree method, tree method_type ATTRIBUTE_UNUSED,
build_int_2 (get_symbol_table_index
(method, &TYPE_ATABLE_METHODS (output_class)), 0);
func =
- build (ARRAY_REF, method_ptr_type_node,
+ build (ARRAY_REF,
+ TREE_TYPE (TREE_TYPE (TYPE_ATABLE_DECL (output_class))),
TYPE_ATABLE_DECL (output_class), table_index);
}
+ func = convert (method_ptr_type_node, func);
}
else
{
@@ -1854,8 +2077,8 @@ invoke_build_dtable (int is_invoke_interface, tree arg_list)
/* Determine the index in SYMBOL_TABLE for a reference to the decl
T. If this decl has not been seen before, it will be added to the
- otable_methods. If it has, the existing table slot will be
- reused. */
+ [oa]table_methods. If it has, the existing table slot will be
+ reused. */
int
get_symbol_table_index (tree t, tree *symbol_table)
@@ -1875,7 +2098,7 @@ get_symbol_table_index (tree t, tree *symbol_table)
{
tree value = TREE_VALUE (method_list);
if (value == t)
- return i;
+ return i;
i++;
if (TREE_CHAIN (method_list) == NULL_TREE)
break;
@@ -1898,6 +2121,9 @@ build_invokevirtual (tree dtable, tree method)
if (flag_indirect_dispatch)
{
+ if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
+ abort ();
+
otable_index
= build_int_2 (get_symbol_table_index
(method, &TYPE_OTABLE_METHODS (output_class)), 0);
@@ -1907,18 +2133,13 @@ build_invokevirtual (tree dtable, tree method)
}
else
{
- method_index = convert (sizetype, DECL_VINDEX (method));
-
- if (TARGET_VTABLE_USES_DESCRIPTORS)
- /* Add one to skip bogus descriptor for class and GC descriptor. */
- method_index = size_binop (PLUS_EXPR, method_index, size_int (1));
- else
- /* Add 1 to skip "class" field of dtable, and 1 to skip GC descriptor. */
- method_index = size_binop (PLUS_EXPR, method_index, size_int (2));
-
+ /* We fetch the DECL_VINDEX field directly here, rather than
+ using get_method_index(). DECL_VINDEX is the true offset
+ from the vtable base to a method, regrdless of any extra
+ words inserted at the start of the vtable. */
+ method_index = DECL_VINDEX (method);
method_index = size_binop (MULT_EXPR, method_index,
TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
-
if (TARGET_VTABLE_USES_DESCRIPTORS)
method_index = size_binop (MULT_EXPR, method_index,
size_int (TARGET_VTABLE_USES_DESCRIPTORS));
@@ -1942,13 +2163,8 @@ build_invokeinterface (tree dtable, tree method)
tree lookup_arg;
tree interface;
tree idx;
- tree meth;
- tree otable_index;
- int i;
- /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
- ensure that the selected method exists, is public and not
- abstract nor static. */
+ /* We expand invokeinterface here. */
if (class_ident == NULL_TREE)
class_ident = get_identifier ("class");
@@ -1965,39 +2181,39 @@ build_invokeinterface (tree dtable, tree method)
if (flag_indirect_dispatch)
{
- otable_index =
- build_int_2 (get_symbol_table_index
- (method, &TYPE_OTABLE_METHODS (output_class)), 0);
- idx =
- build (ARRAY_REF, integer_type_node, TYPE_OTABLE_DECL (output_class),
- otable_index);
+ int itable_index
+ = 2 * (get_symbol_table_index
+ (method, &TYPE_ITABLE_METHODS (output_class)));
+ interface
+ = build (ARRAY_REF,
+ TREE_TYPE (TREE_TYPE (TYPE_ITABLE_DECL (output_class))),
+ TYPE_ITABLE_DECL (output_class),
+ build_int_2 (itable_index-1, 0));
+ idx
+ = build (ARRAY_REF,
+ TREE_TYPE (TREE_TYPE (TYPE_ITABLE_DECL (output_class))),
+ TYPE_ITABLE_DECL (output_class),
+ build_int_2 (itable_index, 0));
+ interface = convert (class_ptr_type, interface);
+ idx = convert (integer_type_node, idx);
}
else
{
- i = 1;
- for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
- {
- if (meth == method)
- {
- idx = build_int_2 (i, 0);
- break;
- }
- if (meth == NULL_TREE)
- abort ();
- }
+ idx = build_int_2 (get_interface_method_index (method, interface), 0);
+ interface = build_class_ref (interface);
}
-
- lookup_arg = tree_cons (NULL_TREE, dtable,
- tree_cons (NULL_TREE, build_class_ref (interface),
- build_tree_list (NULL_TREE, idx)));
+ lookup_arg = tree_cons (NULL_TREE, dtable,
+ tree_cons (NULL_TREE, interface,
+ build_tree_list (NULL_TREE, idx)));
+
return build (CALL_EXPR, ptr_type_node,
build_address_of (soft_lookupinterfacemethod_node),
lookup_arg, NULL_TREE);
}
/* Expand one of the invoke_* opcodes.
- OCPODE is the specific opcode.
+ OPCODE is the specific opcode.
METHOD_REF_INDEX is an index into the constant pool.
NARGS is the number of arguments, or -1 if not specified. */
@@ -2026,33 +2242,63 @@ expand_invoke (int opcode, int method_ref_index, int nargs ATTRIBUTE_UNUSED)
method = lookup_java_constructor (self_type, method_signature);
else
method = lookup_java_method (self_type, method_name, method_signature);
+
+ /* We've found a method in an interface, but this isn't an interface call. */
+ if (opcode != OPCODE_invokeinterface
+ && method
+ && (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method)))))
+ method = NULL_TREE;
+
if (method == NULL_TREE)
{
- error ("class '%s' has no method named '%s' matching signature '%s'",
- self_name,
- IDENTIFIER_POINTER (method_name),
- IDENTIFIER_POINTER (method_signature));
- }
- /* Invoke static can't invoke static/abstract method */
- else if (opcode == OPCODE_invokestatic)
- {
- if (!METHOD_STATIC (method))
+ if (flag_verify_invocations || ! flag_indirect_dispatch)
{
- error ("invokestatic on non static method");
- method = NULL_TREE;
+ error ("class '%s' has no method named '%s' matching signature '%s'",
+ self_name,
+ IDENTIFIER_POINTER (method_name),
+ IDENTIFIER_POINTER (method_signature));
}
- else if (METHOD_ABSTRACT (method))
+ else
{
- error ("invokestatic on abstract method");
- method = NULL_TREE;
+ int flags = ACC_PUBLIC;
+ if (opcode == OPCODE_invokestatic)
+ flags |= ACC_STATIC;
+ if (opcode == OPCODE_invokeinterface)
+ {
+ flags |= ACC_INTERFACE;
+ CLASS_INTERFACE (TYPE_NAME (self_type)) = 1;
+ }
+ method = add_method (self_type, flags, method_name, method_signature);
+ DECL_ARTIFICIAL (method) = 1;
+ METHOD_DUMMY (method) = 1;
+ layout_class_method (self_type, NULL,
+ method, NULL);
}
}
- else
+
+ /* Invoke static can't invoke static/abstract method */
+ if (method != NULL_TREE)
{
- if (METHOD_STATIC (method))
+ if (opcode == OPCODE_invokestatic)
{
- error ("invoke[non-static] on static method");
- method = NULL_TREE;
+ if (!METHOD_STATIC (method))
+ {
+ error ("invokestatic on non static method");
+ method = NULL_TREE;
+ }
+ else if (METHOD_ABSTRACT (method))
+ {
+ error ("invokestatic on abstract method");
+ method = NULL_TREE;
+ }
+ }
+ else
+ {
+ if (METHOD_STATIC (method))
+ {
+ error ("invoke[non-static] on static method");
+ method = NULL_TREE;
+ }
}
}
@@ -2105,7 +2351,11 @@ expand_invoke (int opcode, int method_ref_index, int nargs ATTRIBUTE_UNUSED)
else
func = build_invokeinterface (dtable, method);
}
- func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
+
+ if (TREE_CODE (func) == ADDR_EXPR)
+ TREE_TYPE (func) = build_pointer_type (method_type);
+ else
+ func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
TREE_SIDE_EFFECTS (call) = 1;
@@ -2118,7 +2368,7 @@ expand_invoke (int opcode, int method_ref_index, int nargs ATTRIBUTE_UNUSED)
}
if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
- expand_expr_stmt (call);
+ java_add_stmt (call);
else
{
push_value (call);
@@ -2137,6 +2387,7 @@ build_jni_stub (tree method)
tree env_var, res_var = NULL_TREE, block;
tree method_args, res_type;
tree meth_var;
+ tree bind;
int args_size = 0;
@@ -2170,9 +2421,7 @@ build_jni_stub (tree method)
DECL_INITIAL (meth_var) = null_pointer_node;
TREE_USED (meth_var) = 1;
chainon (env_var, meth_var);
- layout_decl (meth_var, 0);
- make_decl_rtl (meth_var, NULL);
- rest_of_decl_compilation (meth_var, NULL, 0, 0);
+ build_result_decl (method);
/* One strange way that the front ends are different is that they
store arguments differently. */
@@ -2288,39 +2537,31 @@ build_jni_stub (tree method)
body = build (COMPOUND_EXPR, void_type_node, body, call);
TREE_SIDE_EFFECTS (body) = 1;
- /* Finally, do the return. When compiling from source we rely on
- patch_return to patch the return value -- because DECL_RESULT is
- not set at the time this function is called. */
- if (from_class)
- {
- res_type = void_type_node;
- if (res_var != NULL_TREE)
- {
- tree drt;
- if (! DECL_RESULT (method))
- abort ();
- /* Make sure we copy the result variable to the actual
- result. We use the type of the DECL_RESULT because it
- might be different from the return type of the function:
- it might be promoted. */
- drt = TREE_TYPE (DECL_RESULT (method));
- if (drt != TREE_TYPE (res_var))
- res_var = build1 (CONVERT_EXPR, drt, res_var);
- res_var = build (MODIFY_EXPR, drt, DECL_RESULT (method), res_var);
- TREE_SIDE_EFFECTS (res_var) = 1;
- }
- }
- else
+ /* Finally, do the return. */
+ res_type = void_type_node;
+ if (res_var != NULL_TREE)
{
- /* This is necessary to get patch_return to run. */
- res_type = NULL_TREE;
+ tree drt;
+ if (! DECL_RESULT (method))
+ abort ();
+ /* Make sure we copy the result variable to the actual
+ result. We use the type of the DECL_RESULT because it
+ might be different from the return type of the function:
+ it might be promoted. */
+ drt = TREE_TYPE (DECL_RESULT (method));
+ if (drt != TREE_TYPE (res_var))
+ res_var = build1 (CONVERT_EXPR, drt, res_var);
+ res_var = build (MODIFY_EXPR, drt, DECL_RESULT (method), res_var);
+ TREE_SIDE_EFFECTS (res_var) = 1;
}
+
body = build (COMPOUND_EXPR, void_type_node, body,
build1 (RETURN_EXPR, res_type, res_var));
TREE_SIDE_EFFECTS (body) = 1;
-
- BLOCK_EXPR_BODY (block) = body;
- return block;
+
+ bind = build (BIND_EXPR, void_type_node, BLOCK_VARS (block),
+ body, block);
+ return bind;
}
/* Expand an operation to extract from or store into a field.
@@ -2332,10 +2573,11 @@ static void
expand_java_field_op (int is_static, int is_putting, int field_ref_index)
{
tree self_type =
- get_class_constant (current_jcf,
- COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
- field_ref_index));
- const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
+ get_class_constant (current_jcf,
+ COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
+ field_ref_index));
+ const char *self_name =
+ IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);
tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool,
field_ref_index);
@@ -2343,6 +2585,7 @@ expand_java_field_op (int is_static, int is_putting, int field_ref_index)
tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
tree field_ref;
int is_error = 0;
+ tree original_self_type = self_type;
tree field_decl = lookup_field (&self_type, field_name);
if (field_decl == error_mark_node)
{
@@ -2350,9 +2593,23 @@ expand_java_field_op (int is_static, int is_putting, int field_ref_index)
}
else if (field_decl == NULL_TREE)
{
- error ("missing field '%s' in '%s'",
- IDENTIFIER_POINTER (field_name), self_name);
- is_error = 1;
+ if (! flag_verify_invocations)
+ {
+ int flags = ACC_PUBLIC;
+ if (is_static)
+ flags |= ACC_STATIC;
+ self_type = original_self_type;
+ field_decl = add_field (original_self_type, field_name,
+ field_type, flags);
+ DECL_ARTIFICIAL (field_decl) = 1;
+ DECL_IGNORED_P (field_decl) = 1;
+ }
+ else
+ {
+ error ("missing field '%s' in '%s'",
+ IDENTIFIER_POINTER (field_name), self_name);
+ is_error = 1;
+ }
}
else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
{
@@ -2379,12 +2636,13 @@ expand_java_field_op (int is_static, int is_putting, int field_ref_index)
{
if (DECL_CONTEXT (field_decl) != current_class)
error ("%Jassignment to final field '%D' not in field's class",
- field_decl, field_decl);
+ field_decl, field_decl);
else if (FIELD_STATIC (field_decl))
{
if (!DECL_CLINIT_P (current_function_decl))
warning ("%Jassignment to final static field `%D' not in "
- "class initializer", field_decl, field_decl);
+ "class initializer",
+ field_decl, field_decl);
}
else
{
@@ -2395,7 +2653,8 @@ expand_java_field_op (int is_static, int is_putting, int field_ref_index)
field_decl, field_decl);
}
}
- expand_assignment (field_ref, new_value, 0);
+ java_add_stmt (build (MODIFY_EXPR,
+ TREE_TYPE (field_ref), field_ref, new_value));
}
else
push_value (field_ref);
@@ -2456,8 +2715,27 @@ java_expand_expr (tree exp, rtx target, enum machine_mode tmode,
{
tree current;
+ abort ();
+
switch (TREE_CODE (exp))
{
+
+ case EXPR_WITH_FILE_LOCATION:
+ {
+ rtx to_return;
+ const char *saved_input_filename = input_filename;
+ int saved_lineno = input_line;
+ input_filename = EXPR_WFL_FILENAME (exp);
+ input_line = EXPR_WFL_LINENO (exp);
+ if (EXPR_WFL_EMIT_LINE_NOTE (exp))
+ emit_line_note (input_location);
+ /* Possibly avoid switching back and forth here. */
+ to_return = expand_expr (EXPR_WFL_NODE (exp), target, tmode, modifier);
+ input_filename = saved_input_filename;
+ input_line = saved_lineno;
+ return to_return;
+ }
+
case NEW_ARRAY_INIT:
{
rtx tmp;
@@ -2595,12 +2873,6 @@ java_expand_expr (tree exp, rtx target, enum machine_mode tmode,
build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
return const0_rtx;
- case SWITCH_EXPR:
- expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
- expand_expr_stmt (TREE_OPERAND (exp, 1));
- expand_end_case (TREE_OPERAND (exp, 0));
- return const0_rtx;
-
case TRY_EXPR:
/* We expand a try[-catch] block */
@@ -2628,11 +2900,6 @@ java_expand_expr (tree exp, rtx target, enum machine_mode tmode,
return expand_expr (build_exception_object_ref (TREE_TYPE (exp)),
target, tmode, modifier);
- case LABEL_EXPR:
- /* Used only by expanded inline functions. */
- expand_label (TREE_OPERAND (exp, 0));
- return const0_rtx;
-
default:
internal_error ("can't expand %s", tree_code_name [TREE_CODE (exp)]);
}
@@ -2818,7 +3085,7 @@ expand_byte_code (JCF *jcf, tree method)
if (! verify_jvm_instructions (jcf, byte_ops, length))
return;
- /* Translate bytecodes to rtl instructions. */
+ /* Translate bytecodes. */
linenumber_pointer = linenumber_table;
for (PC = 0; PC < length;)
{
@@ -2827,7 +3094,7 @@ expand_byte_code (JCF *jcf, tree method)
tree label = lookup_label (PC);
flush_quick_stack ();
if ((instruction_bits [PC] & BCODE_TARGET) != 0)
- expand_label (label);
+ java_add_stmt (build (LABEL_EXPR, void_type_node, label));
if (LABEL_VERIFIED (label) || PC == 0)
load_type_state (label);
}
@@ -2874,8 +3141,7 @@ expand_byte_code (JCF *jcf, tree method)
linenumber_pointer += 4;
if (pc == PC)
{
- input_line = GET_u2 (linenumber_pointer - 2);
- emit_line_note (input_location);
+ input_location.line = GET_u2 (linenumber_pointer - 2);
if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
break;
}
@@ -2905,7 +3171,7 @@ java_push_constant_from_pool (JCF *jcf, int index)
name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
index = alloc_name_constant (CONSTANT_String, name);
c = build_ref_from_constant_pool (index);
- TREE_TYPE (c) = promote_type (string_type_node);
+ c = convert (promote_type (string_type_node), c);
}
else
c = get_constant (jcf, index);
@@ -2923,8 +3189,8 @@ process_jvm_instruction (int PC, const unsigned char* byte_ops,
replace the top of the stack with the thrown object reference */
if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
{
- tree type = pop_type (ptr_type_node);
- push_value (build (JAVA_EXC_OBJ_EXPR, type));
+ tree type = pop_type (promote_type (throwable_type_node));
+ push_value (build_exception_object_ref (type));
}
switch (byte_ops[PC++])
@@ -2939,7 +3205,8 @@ process_jvm_instruction (int PC, const unsigned char* byte_ops,
{ \
int saw_index = 0; \
int index = OPERAND_VALUE; \
- build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
+ build_java_ret \
+ (find_local_variable (index, return_address_type_node, oldpc)); \
}
#define JSR(OPERAND_TYPE, OPERAND_VALUE) \
@@ -3026,46 +3293,24 @@ process_jvm_instruction (int PC, const unsigned char* byte_ops,
#define LOOKUP_SWITCH \
{ jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
tree selector = pop_value (INT_type_node); \
- tree duplicate, label; \
- tree type = TREE_TYPE (selector); \
- flush_quick_stack (); \
- expand_start_case (0, selector, type, "switch statement");\
+ tree switch_expr = expand_java_switch (selector, oldpc + default_offset); \
while (--npairs >= 0) \
{ \
jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
- tree value = build_int_2 (match, match < 0 ? -1 : 0); \
- TREE_TYPE (value) = type; \
- label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
- pushcase (value, convert, label, &duplicate); \
- expand_java_goto (oldpc + offset); \
+ expand_java_add_case (switch_expr, match, oldpc + offset); \
} \
- label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
- pushcase (NULL_TREE, 0, label, &duplicate); \
- expand_java_goto (oldpc + default_offset); \
- expand_end_case (selector); \
}
#define TABLE_SWITCH \
{ jint default_offset = IMMEDIATE_s4; \
jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
tree selector = pop_value (INT_type_node); \
- tree duplicate, label; \
- tree type = TREE_TYPE (selector); \
- flush_quick_stack (); \
- expand_start_case (0, selector, type, "switch statement");\
+ tree switch_expr = expand_java_switch (selector, oldpc + default_offset); \
for (; low <= high; low++) \
{ \
jint offset = IMMEDIATE_s4; \
- tree value = build_int_2 (low, low < 0 ? -1 : 0); \
- TREE_TYPE (value) = type; \
- label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
- pushcase (value, convert, label, &duplicate); \
- expand_java_goto (oldpc + offset); \
+ expand_java_add_case (switch_expr, low, oldpc + offset); \
} \
- label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
- pushcase (NULL_TREE, 0, label, &duplicate); \
- expand_java_goto (oldpc + default_offset); \
- expand_end_case (selector); \
}
#define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
@@ -3130,16 +3375,17 @@ process_jvm_instruction (int PC, const unsigned char* byte_ops,
/* internal macro added for use by the WIDE case
Added TREE_TYPE (decl) assignment, apbianco */
-#define STORE_INTERNAL(OPTYPE, OPVALUE) \
- { \
- tree decl, value; \
- int var = OPVALUE; \
- tree type = OPTYPE; \
- value = pop_value (type); \
- type = TREE_TYPE (value); \
- decl = find_local_variable (var, type, oldpc); \
- set_local_type (var, type ); \
- expand_assignment (decl, value, 0); \
+#define STORE_INTERNAL(OPTYPE, OPVALUE) \
+ { \
+ tree decl, value; \
+ int index = OPVALUE; \
+ tree type = OPTYPE; \
+ value = pop_value (type); \
+ type = TREE_TYPE (value); \
+ decl = find_local_variable (index, type, oldpc); \
+ set_local_type (index, type); \
+ java_add_stmt (build (MODIFY_EXPR, type, decl, value)); \
+ update_aliases (decl, index, PC); \
}
#define STORE(OPERAND_TYPE, OPERAND_VALUE) \
@@ -3162,7 +3408,7 @@ process_jvm_instruction (int PC, const unsigned char* byte_ops,
flush_quick_stack (); \
c = build_java_monitor (call, o); \
TREE_SIDE_EFFECTS (c) = 1; \
- expand_expr_stmt (c); \
+ java_add_stmt (c); \
}
#define SPECIAL_IINC(IGNORED) \
@@ -3407,7 +3653,9 @@ force_evaluation_order (tree node)
if (cmp)
{
- cmp = save_expr (build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node));
+ cmp = build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node);
+ if (TREE_TYPE (cmp) != void_type_node)
+ cmp = save_expr (cmp);
CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
TREE_SIDE_EFFECTS (cmp) = 1;
node = cmp;
@@ -3448,5 +3696,46 @@ emit_init_test_initialization (void **entry, void *x ATTRIBUTE_UNUSED)
return true;
}
-#include "gt-java-expr.h"
+/* EXPR_WITH_FILE_LOCATION are used to keep track of the exact
+ location where an expression or an identifier were encountered. It
+ is necessary for languages where the frontend parser will handle
+ recursively more than one file (Java is one of them). */
+
+tree
+build_expr_wfl (tree node, const char *file, int line, int col)
+{
+ static const char *last_file = 0;
+ static tree last_filenode = NULL_TREE;
+ tree wfl = make_node (EXPR_WITH_FILE_LOCATION);
+
+ EXPR_WFL_NODE (wfl) = node;
+ EXPR_WFL_SET_LINECOL (wfl, line, col);
+ if (file != last_file)
+ {
+ last_file = file;
+ last_filenode = file ? get_identifier (file) : NULL_TREE;
+ }
+ EXPR_WFL_FILENAME_NODE (wfl) = last_filenode;
+ if (node)
+ {
+ if (IS_NON_TYPE_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (node))))
+ TREE_SIDE_EFFECTS (wfl) = TREE_SIDE_EFFECTS (node);
+ TREE_TYPE (wfl) = TREE_TYPE (node);
+ }
+
+ return wfl;
+}
+
+
+/* Build a node to represent empty statements and blocks. */
+
+tree
+build_java_empty_stmt (void)
+{
+ tree t = build_empty_stmt ();
+ CAN_COMPLETE_NORMALLY (t) = 1;
+ return t;
+}
+
+#include "gt-java-expr.h"
diff --git a/gcc/java/gcj.texi b/gcc/java/gcj.texi
index b71568a3d6f..98ac2909dd4 100644
--- a/gcc/java/gcj.texi
+++ b/gcc/java/gcj.texi
@@ -2310,6 +2310,24 @@ property is set to @samp{cache}, then any failed lookups are cached
and not tried again. If this property is set to @samp{never}, then
lookups are never done. For more information, @xref{Extensions}.
+@item gnu.gcj.jit.compiler
+@c FIXME we should probably have a whole node on this...
+This is the full path to @command{gcj} executable which should be
+used to compile classes just-in-time when
+@code{ClassLoader.defineClass} is called. If not set, @command{gcj}
+will not be invoked by the runtime; this can also be controlled via
+@code{Compiler.disable}.
+
+@item gnu.gcj.jit.options
+This is a space-separated string of options which should be passed to
+@command{gcj} when in JIT mode. If not set, a sensible default is
+chosen.
+
+@item gnu.gcj.jit.cachedir
+This is the directory where cached shared library files are
+stored. If not set, JIT compilation is disabled. This should never
+be set to a directory that is writable by any other user.
+
@end table
diff --git a/gcc/java/gjavah.c b/gcc/java/gjavah.c
index 0a09ab6c137..f29daa547ea 100644
--- a/gcc/java/gjavah.c
+++ b/gcc/java/gjavah.c
@@ -111,6 +111,9 @@ static JCF_u2 last_access;
#define METHOD_IS_NATIVE(Method) \
((Method) & ACC_NATIVE)
+#define METHOD_IS_PRIVATE(Class, Method) \
+ (((Method) & ACC_PRIVATE) != 0)
+
/* We keep a linked list of all method names we have seen. This lets
us determine if a method name and a field name are in conflict. */
struct method_name
@@ -119,6 +122,7 @@ struct method_name
int length;
unsigned char *signature;
int sig_length;
+ int is_native;
struct method_name *next;
};
@@ -634,7 +638,7 @@ name_is_method_p (const unsigned char *name, int length)
return 0;
}
-/* If there is already a method named NAME, whose signature is not
+/* If there is already a native method named NAME, whose signature is not
SIGNATURE, then return true. Otherwise return false. */
static int
overloaded_jni_method_exists_p (const unsigned char *name, int length,
@@ -644,7 +648,8 @@ overloaded_jni_method_exists_p (const unsigned char *name, int length,
for (p = method_name_list; p != NULL; p = p->next)
{
- if (p->length == length
+ if (p->is_native
+ && p->length == length
&& ! memcmp (p->name, name, length)
&& (p->sig_length != sig_length
|| memcmp (p->signature, signature, sig_length)))
@@ -851,6 +856,7 @@ print_method_info (FILE *stream, JCF* jcf, int name_index, int sig_index,
nn->next = method_name_list;
nn->sig_length = JPOOL_UTF_LENGTH (jcf, sig_index);
nn->signature = xmalloc (nn->sig_length);
+ nn->is_native = METHOD_IS_NATIVE (flags);
memcpy (nn->signature, JPOOL_UTF_DATA (jcf, sig_index),
nn->sig_length);
method_name_list = nn;
@@ -879,7 +885,7 @@ print_method_info (FILE *stream, JCF* jcf, int name_index, int sig_index,
fputs (" ", out);
if ((flags & ACC_STATIC))
fputs ("static ", out);
- else if (! METHOD_IS_FINAL (jcf->access_flags, flags))
+ else if (! METHOD_IS_PRIVATE (jcf->access_flags, flags))
{
/* Don't print `virtual' if we have a constructor. */
if (! is_init)
diff --git a/gcc/java/java-except.h b/gcc/java/java-except.h
index b536ce0623e..c5214122754 100644
--- a/gcc/java/java-except.h
+++ b/gcc/java/java-except.h
@@ -50,6 +50,11 @@ struct eh_range
/* True if this range has already been expanded. */
int expanded;
+
+ /* The TRY_CATCH_EXPR for this EH range. */
+ tree stmt;
+
+ tree handler;
};
/* A dummy range that represents the entire method. */
@@ -65,3 +70,4 @@ extern void maybe_end_try (int, int);
extern void add_handler (int, int, tree, tree);
extern void handle_nested_ranges (void);
extern void expand_resume_after_catch (void);
+extern void expand_end_java_handler (struct eh_range *);
diff --git a/gcc/java/java-gimplify.c b/gcc/java/java-gimplify.c
new file mode 100644
index 00000000000..d06abbf2530
--- /dev/null
+++ b/gcc/java/java-gimplify.c
@@ -0,0 +1,320 @@
+/* Java(TM) language-specific gimplification routines.
+
+ Copyright (C) 2003, 2004 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 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+
+Java and all Java-based marks are trademarks or registered trademarks
+of Sun Microsystems, Inc. in the United States and other countries.
+The Free Software Foundation is independent of Sun Microsystems, Inc. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "java-tree.h"
+#include "tree-dump.h"
+#include "tree-gimple.h"
+#include "toplev.h"
+
+static tree java_gimplify_case_expr (tree);
+static tree java_gimplify_default_expr (tree);
+static tree java_gimplify_block (tree);
+static tree java_gimplify_new_array_init (tree);
+static tree java_gimplify_try_expr (tree);
+static tree java_gimplify_modify_expr (tree);
+
+static void dump_java_tree (enum tree_dump_index, tree);
+
+/* Convert a Java tree to GENERIC. */
+
+void
+java_genericize (tree fndecl)
+{
+ dump_java_tree (TDI_original, fndecl);
+
+ /* Genericize with the gimplifier. */
+ gimplify_function_tree (fndecl);
+
+ dump_function (TDI_generic, fndecl);
+}
+
+/* Gimplify a Java tree. */
+
+int
+java_gimplify_expr (tree *expr_p, tree *pre_p ATTRIBUTE_UNUSED,
+ tree *post_p ATTRIBUTE_UNUSED)
+{
+ char code_class = TREE_CODE_CLASS(TREE_CODE (*expr_p));
+
+ /* Java insists on strict left-to-right evaluation of expressions.
+ A problem may arise if a variable used in the LHS of a binary
+ operation is altered by an assignment to that value in the RHS
+ before we've performed the operation. So, we always copy every
+ LHS to a temporary variable.
+
+ FIXME: Are there any other cases where we should do this?
+ Parameter lists, maybe? Or perhaps that's unnecessary because
+ the front end already generates SAVE_EXPRs. */
+ if (code_class == '2')
+ {
+ tree lhs = TREE_OPERAND (*expr_p, 0);
+ enum gimplify_status stat
+ = gimplify_expr (&lhs, pre_p, post_p, is_gimple_tmp_var, fb_rvalue);
+ if (stat == GS_ERROR)
+ return stat;
+ TREE_OPERAND (*expr_p, 0) = lhs;
+ }
+
+ switch (TREE_CODE (*expr_p))
+ {
+ case BLOCK:
+ *expr_p = java_gimplify_block (*expr_p);
+ break;
+
+ case EXPR_WITH_FILE_LOCATION:
+ input_location.file = EXPR_WFL_FILENAME (*expr_p);
+ input_location.line = EXPR_WFL_LINENO (*expr_p);
+ *expr_p = EXPR_WFL_NODE (*expr_p);
+ annotate_with_locus (*expr_p, input_location);
+ break;
+
+ case CASE_EXPR:
+ *expr_p = java_gimplify_case_expr (*expr_p);
+ break;
+
+ case DEFAULT_EXPR:
+ *expr_p = java_gimplify_default_expr (*expr_p);
+ break;
+
+ case NEW_ARRAY_INIT:
+ *expr_p = java_gimplify_new_array_init (*expr_p);
+ break;
+
+ case TRY_EXPR:
+ *expr_p = java_gimplify_try_expr (*expr_p);
+ break;
+
+ case JAVA_CATCH_EXPR:
+ *expr_p = TREE_OPERAND (*expr_p, 0);
+ break;
+
+ case JAVA_EXC_OBJ_EXPR:
+ *expr_p = build_exception_object_ref (TREE_TYPE (*expr_p));
+ break;
+
+ case VAR_DECL:
+ *expr_p = java_replace_reference (*expr_p, /* want_lvalue */ false);
+ return GS_UNHANDLED;
+
+ case MODIFY_EXPR:
+ *expr_p = java_gimplify_modify_expr (*expr_p);
+ return GS_UNHANDLED;
+
+ case SAVE_EXPR:
+ if (TREE_CODE (TREE_OPERAND (*expr_p, 0)) == VAR_DECL)
+ TREE_OPERAND (*expr_p, 0)
+ = java_replace_reference (TREE_OPERAND (*expr_p, 0),
+ /* want_lvalue */ false);
+ return GS_UNHANDLED;
+
+ /* These should already be lowered before we get here. */
+ case URSHIFT_EXPR:
+ case COMPARE_EXPR:
+ case COMPARE_L_EXPR:
+ case COMPARE_G_EXPR:
+ case UNARY_PLUS_EXPR:
+ case NEW_ARRAY_EXPR:
+ case NEW_ANONYMOUS_ARRAY_EXPR:
+ case NEW_CLASS_EXPR:
+ case THIS_EXPR:
+ case SYNCHRONIZED_EXPR:
+ case CONDITIONAL_EXPR:
+ case INSTANCEOF_EXPR:
+ case CLASS_LITERAL:
+ abort ();
+
+ default:
+ return GS_UNHANDLED;
+ }
+
+ return GS_OK;
+}
+
+/* This is specific to the bytecode compiler. If a variable has
+ LOCAL_SLOT_P set, replace an assignment to it with an assignment to
+ the corresponding variable that holds all its aliases. */
+
+static tree
+java_gimplify_modify_expr (tree modify_expr)
+{
+ tree lhs = TREE_OPERAND (modify_expr, 0);
+ tree rhs = TREE_OPERAND (modify_expr, 1);
+ tree lhs_type = TREE_TYPE (lhs);
+
+ if (TREE_CODE (lhs) == VAR_DECL
+ && DECL_LANG_SPECIFIC (lhs)
+ && LOCAL_SLOT_P (lhs)
+ && TREE_CODE (lhs_type) == POINTER_TYPE)
+ {
+ tree new_lhs = java_replace_reference (lhs, /* want_lvalue */ true);
+ tree new_rhs = build1 (NOP_EXPR, TREE_TYPE (new_lhs), rhs);
+ modify_expr = build (MODIFY_EXPR, TREE_TYPE (new_lhs),
+ new_lhs, new_rhs);
+ modify_expr = build1 (NOP_EXPR, lhs_type, modify_expr);
+ }
+
+ return modify_expr;
+}
+
+
+static tree
+java_gimplify_case_expr (tree expr)
+{
+ tree label = create_artificial_label ();
+ return build (CASE_LABEL_EXPR, void_type_node,
+ TREE_OPERAND (expr, 0), NULL_TREE, label);
+}
+
+static tree
+java_gimplify_default_expr (tree expr ATTRIBUTE_UNUSED)
+{
+ tree label = create_artificial_label ();
+ return build (CASE_LABEL_EXPR, void_type_node, NULL_TREE, NULL_TREE, label);
+}
+
+/* Gimplify BLOCK into a BIND_EXPR. */
+
+static tree
+java_gimplify_block (tree java_block)
+{
+ tree decls = BLOCK_VARS (java_block);
+ tree body = BLOCK_EXPR_BODY (java_block);
+ tree outer = gimple_current_bind_expr ();
+ tree block;
+
+ /* Don't bother with empty blocks. */
+ if (! body)
+ return build_empty_stmt ();
+
+ if (IS_EMPTY_STMT (body))
+ return body;
+
+ /* Make a proper block. Java blocks are unsuitable for BIND_EXPR
+ because they use BLOCK_SUBBLOCKS for another purpose. */
+ block = make_node (BLOCK);
+ BLOCK_VARS (block) = decls;
+ if (outer != NULL_TREE)
+ {
+ outer = BIND_EXPR_BLOCK (outer);
+ BLOCK_SUBBLOCKS (outer) = chainon (BLOCK_SUBBLOCKS (outer), block);
+ }
+
+ return build (BIND_EXPR, TREE_TYPE (java_block), decls, body, block);
+}
+
+/* Gimplify a NEW_ARRAY_INIT node into array/element assignments. */
+
+static tree
+java_gimplify_new_array_init (tree exp)
+{
+ tree array_type = TREE_TYPE (TREE_TYPE (exp));
+ tree data_field = lookup_field (&array_type, get_identifier ("data"));
+ tree element_type = TYPE_ARRAY_ELEMENT (array_type);
+ HOST_WIDE_INT ilength = java_array_type_length (array_type);
+ tree length = build_int_2 (ilength, 0);
+ tree init = TREE_OPERAND (exp, 0);
+ tree values = CONSTRUCTOR_ELTS (init);
+
+ tree array_ptr_type = build_pointer_type (array_type);
+ tree block = build (BLOCK, array_ptr_type);
+ tree tmp = build_decl (VAR_DECL, get_identifier ("<tmp>"), array_ptr_type);
+ tree array = build_decl (VAR_DECL, get_identifier ("<array>"), array_ptr_type);
+ tree body = build (MODIFY_EXPR, array_ptr_type, tmp,
+ build_new_array (element_type, length));
+
+ int index = 0;
+
+ DECL_CONTEXT (array) = current_function_decl;
+ DECL_CONTEXT (tmp) = current_function_decl;
+
+ /* FIXME: try to allocate array statically? */
+ while (values != NULL_TREE)
+ {
+ /* FIXME: Should use build_java_arrayaccess here, but avoid
+ bounds checking. */
+ tree lhs = build (COMPONENT_REF, TREE_TYPE (data_field),
+ build_java_indirect_ref (array_type, tmp, 0),
+ data_field);
+ tree assignment = build (MODIFY_EXPR, element_type,
+ build (ARRAY_REF, element_type, lhs,
+ build_int_2 (index++, 0)),
+ TREE_VALUE (values));
+ body = build (COMPOUND_EXPR, element_type, body, assignment);
+ values = TREE_CHAIN (values);
+ }
+
+ body = build (COMPOUND_EXPR, array_ptr_type, body,
+ build (MODIFY_EXPR, array_ptr_type, array, tmp));
+ TREE_CHAIN (tmp) = array;
+ BLOCK_VARS (block) = tmp;
+ BLOCK_EXPR_BODY (block) = body;
+ return java_gimplify_block (block);
+}
+
+static tree
+java_gimplify_try_expr (tree try_expr)
+{
+ tree body = TREE_OPERAND (try_expr, 0);
+ tree handler = TREE_OPERAND (try_expr, 1);
+ tree catch = NULL_TREE;
+
+ /* Build a CATCH_EXPR for each handler. */
+ while (handler)
+ {
+ tree java_catch = TREE_OPERAND (handler, 0);
+ tree catch_type = TREE_TYPE (TREE_TYPE (BLOCK_EXPR_DECLS (java_catch)));
+ tree expr = build (CATCH_EXPR, void_type_node,
+ prepare_eh_table_type (catch_type),
+ handler);
+ if (catch)
+ catch = build (COMPOUND_EXPR, void_type_node, catch, expr);
+ else
+ catch = expr;
+ handler = TREE_CHAIN (handler);
+ }
+ return build (TRY_CATCH_EXPR, void_type_node, body, catch);
+}
+
+/* Dump a tree of some kind. This is a convenience wrapper for the
+ dump_* functions in tree-dump.c. */
+static void
+dump_java_tree (enum tree_dump_index phase, tree t)
+{
+ FILE *stream;
+ int flags;
+
+ stream = dump_begin (phase, &flags);
+ flags |= TDF_SLIM;
+ if (stream)
+ {
+ dump_node (t, flags, stream);
+ dump_end (phase, stream);
+ }
+}
diff --git a/gcc/java/java-tree.def b/gcc/java/java-tree.def
index f15bc38701f..25ee5386205 100644
--- a/gcc/java/java-tree.def
+++ b/gcc/java/java-tree.def
@@ -55,7 +55,7 @@ DEFTREECODE (TRY_EXPR, "try-catch", 'e', 2)
/* Catch clause.
Operand 0 is the catch clause block, which contains the declaration of
the catch clause parameter. */
-DEFTREECODE (CATCH_EXPR, "catch", '1', 1)
+DEFTREECODE (JAVA_CATCH_EXPR, "catch", '1', 1)
/* Synchronized statement.
Operand 0 is the expression on which we wish to synchronize,
@@ -91,6 +91,13 @@ DEFTREECODE (CLASS_LITERAL, "class_literal", '1', 1)
/* The Java object within the exception object from the runtime. */
DEFTREECODE (JAVA_EXC_OBJ_EXPR, "java_exc_obj_expr", 'e', 0)
+/* Annotates a tree node (usually an expression) with source location
+ information: a file name (EXPR_WFL_FILENAME); a line number
+ (EXPR_WFL_LINENO); and column number (EXPR_WFL_COLNO). It is
+ expanded as the contained node (EXPR_WFL_NODE); a line note should
+ be emitted first if EXPR_WFL_EMIT_LINE_NOTE. */
+DEFTREECODE (EXPR_WITH_FILE_LOCATION, "expr_with_file_location", 'e', 3)
+
/*
Local variables:
mode:c
diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h
index 169f0ad4007..e35723d028d 100644
--- a/gcc/java/java-tree.h
+++ b/gcc/java/java-tree.h
@@ -244,6 +244,8 @@ extern GTY(()) struct JCF * current_jcf;
before static field references. */
extern int always_initialize_class_p;
+extern int flag_verify_invocations;
+
typedef struct CPool constant_pool;
#define CONSTANT_ResolvedFlag 16
@@ -332,6 +334,7 @@ enum java_tree_index
JTI_CLINIT_IDENTIFIER_NODE,
JTI_FINIT_IDENTIFIER_NODE,
JTI_INSTINIT_IDENTIFIER_NODE,
+ JTI_VERIFY_IDENTIFIER_NODE,
JTI_VOID_SIGNATURE_NODE,
JTI_LENGTH_IDENTIFIER_NODE,
JTI_FINALIZE_IDENTIFIER_NODE,
@@ -349,7 +352,6 @@ enum java_tree_index
JTI_DOUBLE_ZERO_NODE,
JTI_INTEGER_TWO_NODE,
JTI_INTEGER_FOUR_NODE,
- JTI_EMPTY_STMT_NODE,
JTI_METHODTABLE_TYPE,
JTI_METHODTABLE_PTR_TYPE,
@@ -375,6 +377,8 @@ enum java_tree_index
JTI_OTABLE_PTR_TYPE,
JTI_ATABLE_TYPE,
JTI_ATABLE_PTR_TYPE,
+ JTI_ITABLE_TYPE,
+ JTI_ITABLE_PTR_TYPE,
JTI_SYMBOL_TYPE,
JTI_SYMBOLS_ARRAY_TYPE,
JTI_SYMBOLS_ARRAY_PTR_TYPE,
@@ -386,6 +390,7 @@ enum java_tree_index
JTI_ALLOC_NO_FINALIZER_NODE,
JTI_SOFT_INSTANCEOF_NODE,
JTI_SOFT_CHECKCAST_NODE,
+ JTI_SOFT_CHECK_ASSIGNMENT_NODE,
JTI_SOFT_INITCLASS_NODE,
JTI_SOFT_NEWARRAY_NODE,
JTI_SOFT_ANEWARRAY_NODE,
@@ -396,6 +401,7 @@ enum java_tree_index
JTI_SOFT_MONITORENTER_NODE,
JTI_SOFT_MONITOREXIT_NODE,
JTI_SOFT_LOOKUPINTERFACEMETHOD_NODE,
+ JTI_SOFT_LOOKUPINTERFACEMETHODBYNAME_NODE,
JTI_SOFT_LOOKUPJNIMETHOD_NODE,
JTI_SOFT_GETJNIENVNEWFRAME_NODE,
JTI_SOFT_JNIPOPSYSTEMFRAME_NODE,
@@ -529,6 +535,8 @@ extern GTY(()) tree java_global_trees[JTI_MAX];
/* FIXME "instinit$" and "finit$" should be merged */
#define instinit_identifier_node \
java_global_trees[JTI_INSTINIT_IDENTIFIER_NODE] /* "instinit$" */
+#define verify_identifier_node \
+ java_global_trees[JTI_VERIFY_IDENTIFIER_NODE] /* "__verify" */
#define void_signature_node \
java_global_trees[JTI_VOID_SIGNATURE_NODE] /* "()V" */
#define length_identifier_node \
@@ -562,8 +570,6 @@ extern GTY(()) tree java_global_trees[JTI_MAX];
java_global_trees[JTI_INTEGER_TWO_NODE]
#define integer_four_node \
java_global_trees[JTI_INTEGER_FOUR_NODE]
-#define empty_stmt_node \
- java_global_trees[JTI_EMPTY_STMT_NODE]
/* The type for struct methodtable. */
#define methodtable_type \
@@ -608,10 +614,14 @@ extern GTY(()) tree java_global_trees[JTI_MAX];
java_global_trees[JTI_OTABLE_TYPE]
#define atable_type \
java_global_trees[JTI_ATABLE_TYPE]
+#define itable_type \
+ java_global_trees[JTI_ITABLE_TYPE]
#define otable_ptr_type \
java_global_trees[JTI_OTABLE_PTR_TYPE]
#define atable_ptr_type \
java_global_trees[JTI_ATABLE_PTR_TYPE]
+#define itable_ptr_type \
+ java_global_trees[JTI_ITABLE_PTR_TYPE]
#define symbol_type \
java_global_trees[JTI_SYMBOL_TYPE]
#define symbols_array_type \
@@ -633,6 +643,8 @@ extern GTY(()) tree java_global_trees[JTI_MAX];
java_global_trees[JTI_ALLOC_NO_FINALIZER_NODE]
#define soft_instanceof_node \
java_global_trees[JTI_SOFT_INSTANCEOF_NODE]
+#define soft_check_assignment_node \
+ java_global_trees[JTI_SOFT_CHECK_ASSIGNMENT_NODE]
#define soft_checkcast_node \
java_global_trees[JTI_SOFT_CHECKCAST_NODE]
#define soft_initclass_node \
@@ -655,6 +667,8 @@ extern GTY(()) tree java_global_trees[JTI_MAX];
java_global_trees[JTI_SOFT_MONITOREXIT_NODE]
#define soft_lookupinterfacemethod_node \
java_global_trees[JTI_SOFT_LOOKUPINTERFACEMETHOD_NODE]
+#define soft_lookupinterfacemethodbyname_node \
+ java_global_trees[JTI_SOFT_LOOKUPINTERFACEMETHODBYNAME_NODE]
#define soft_lookupjnimethod_node \
java_global_trees[JTI_SOFT_LOOKUPJNIMETHOD_NODE]
#define soft_getjnienvnewframe_node \
@@ -929,6 +943,8 @@ union lang_tree_node
/* True if NODE is a variable that is out of scope. */
#define LOCAL_VAR_OUT_OF_SCOPE_P(NODE) \
(DECL_LANG_SPECIFIC (NODE)->u.v.freed)
+#define LOCAL_SLOT_P(NODE) \
+ (DECL_LANG_SPECIFIC (NODE)->u.v.local_slot)
/* Create a DECL_LANG_SPECIFIC if necessary. */
#define MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC(T) \
if (DECL_LANG_SPECIFIC (T) == NULL) \
@@ -989,6 +1005,7 @@ struct lang_decl_func GTY(())
unsigned int invisible : 1; /* Set for methods we generate
internally but which shouldn't be
written to the .class file. */
+ unsigned int dummy:1;
};
struct treetreehash_entry GTY(())
@@ -997,6 +1014,12 @@ struct treetreehash_entry GTY(())
tree value;
};
+typedef struct type_assertion GTY(())
+{
+ tree source_type;
+ tree target_type;
+} type_assertion;
+
extern tree java_treetreehash_find (htab_t, tree);
extern tree * java_treetreehash_new (htab_t, tree);
extern htab_t java_treetreehash_create (size_t size, int ggc);
@@ -1014,7 +1037,8 @@ struct lang_decl_var GTY(())
tree owner;
unsigned int final_iud : 1; /* Final initialized upon declaration */
unsigned int cif : 1; /* True: decl is a class initialization flag */
- unsigned int freed; /* Decl is no longer in scope. */
+ unsigned int freed : 1; /* Decl is no longer in scope. */
+ unsigned int local_slot : 1; /* Decl is a temporary in the stack frame. */
};
/* This is what 'lang_decl' really points to. */
@@ -1047,6 +1071,9 @@ struct lang_decl GTY(())
#define TYPE_II_STMT_LIST(T) (TYPE_LANG_SPECIFIC (T)->ii_block)
/* The decl of the synthetic method `class$' used to handle `.class'
for non primitive types when compiling to bytecode. */
+
+#define TYPE_DUMMY(T) (TYPE_LANG_SPECIFIC(T)->dummy_class)
+
#define TYPE_DOT_CLASS(T) (TYPE_LANG_SPECIFIC (T)->dot_class)
#define TYPE_PACKAGE_LIST(T) (TYPE_LANG_SPECIFIC (T)->package_list)
#define TYPE_IMPORT_LIST(T) (TYPE_LANG_SPECIFIC (T)->import_list)
@@ -1064,10 +1091,16 @@ struct lang_decl GTY(())
#define TYPE_OTABLE_SYMS_DECL(T) (TYPE_LANG_SPECIFIC (T)->otable_syms_decl)
#define TYPE_OTABLE_DECL(T) (TYPE_LANG_SPECIFIC (T)->otable_decl)
+#define TYPE_ITABLE_METHODS(T) (TYPE_LANG_SPECIFIC (T)->itable_methods)
+#define TYPE_ITABLE_SYMS_DECL(T) (TYPE_LANG_SPECIFIC (T)->itable_syms_decl)
+#define TYPE_ITABLE_DECL(T) (TYPE_LANG_SPECIFIC (T)->itable_decl)
+
#define TYPE_CTABLE_DECL(T) (TYPE_LANG_SPECIFIC (T)->ctable_decl)
#define TYPE_CATCH_CLASSES(T) (TYPE_LANG_SPECIFIC (T)->catch_classes)
+#define TYPE_VERIFY_METHOD(T) (TYPE_LANG_SPECIFIC (T)->verify_method)
#define TYPE_TO_RUNTIME_MAP(T) (TYPE_LANG_SPECIFIC (T)->type_to_runtime_map)
+#define TYPE_ASSERTIONS(T) (TYPE_LANG_SPECIFIC (T)->type_assertions)
struct lang_type GTY(())
{
@@ -1096,18 +1129,29 @@ struct lang_type GTY(())
tree atable_decl; /* The static address table. */
tree atable_syms_decl;
+ tree itable_methods; /* List of interfaces methods referred
+ to by this class. */
+ tree itable_decl; /* The interfaces table. */
+ tree itable_syms_decl;
+
tree ctable_decl; /* The table of classes for the runtime
type matcher. */
tree catch_classes;
+ tree verify_method; /* The verify method for this class.
+ Used in split verification. */
+
htab_t GTY ((param_is (struct treetreehash_entry))) type_to_runtime_map;
/* The mapping of classes to exception region
markers. */
+ htab_t GTY ((param_is (struct type_assertion))) type_assertions;
+
unsigned pic:1; /* Private Inner Class. */
unsigned poic:1; /* Protected Inner Class. */
unsigned strictfp:1; /* `strictfp' class. */
unsigned assertions:1; /* Any method uses `assert'. */
+ unsigned dummy_class:1; /* Not a real class, just a placeholder. */
};
#define JCF_u4 unsigned long
@@ -1118,6 +1162,9 @@ struct lang_type GTY(())
#define SEARCH_SUPER 2
#define SEARCH_VISIBLE 4
+/* Defined in java-except.h */
+struct eh_range;
+
extern void java_parse_file (int);
extern bool java_mark_addressable (tree);
extern tree java_type_for_mode (enum machine_mode, int);
@@ -1149,6 +1196,7 @@ extern tree unmangle_classname (const char *name, int name_length);
extern tree parse_signature_string (const unsigned char *, int);
extern tree get_type_from_signature (tree);
extern void layout_class (tree);
+extern int get_interface_method_index (tree, tree);
extern tree layout_class_method (tree, tree, tree, tree);
extern void layout_class_methods (tree);
extern tree build_class_ref (tree);
@@ -1177,6 +1225,7 @@ extern void set_java_signature (tree, tree);
extern tree build_static_field_ref (tree);
extern tree build_address_of (tree);
extern tree find_local_variable (int index, tree type, int pc);
+extern void update_aliases (tree decl, int index, int pc);
extern tree find_stack_slot (int index, tree type);
extern tree build_prim_array_type (tree, HOST_WIDE_INT);
extern tree build_java_array_type (tree, HOST_WIDE_INT);
@@ -1234,14 +1283,15 @@ extern int interface_of_p (tree, tree);
extern int inherits_from_p (tree, tree);
extern int common_enclosing_context_p (tree, tree);
extern int enclosing_context_p (tree, tree);
-extern void complete_start_java_method (tree);
extern tree build_result_decl (tree);
extern void emit_handlers (void);
+extern void set_method_index (tree decl, tree method_index);
+extern tree get_method_index (tree decl);
extern void make_class_data (tree);
extern void register_class (void);
extern int alloc_name_constant (int, tree);
extern void emit_register_classes (void);
-extern tree emit_symbol_table (tree, tree, tree, tree, tree);
+extern tree emit_symbol_table (tree, tree, tree, tree, tree, int);
extern void lang_init_source (int);
extern void write_classfile (tree);
extern char *print_int_node (tree);
@@ -1252,6 +1302,8 @@ extern void java_layout_seen_class_methods (void);
extern void check_for_initialization (tree, tree);
extern tree pushdecl_top_level (tree);
+extern tree pushdecl_function_level (tree);
+extern tree java_replace_reference (tree, bool);
extern int alloc_class_constant (tree);
extern void init_expr_processing (void);
extern void push_super_field (tree, tree);
@@ -1271,6 +1323,7 @@ extern void push_type (tree);
extern void load_type_state (tree);
extern void add_interface (tree, tree);
extern tree force_evaluation_order (tree);
+extern tree java_create_object (tree);
extern int verify_constant_pool (struct JCF *);
extern void start_java_method (tree);
extern void end_java_method (void);
@@ -1338,8 +1391,13 @@ extern void compile_resource_data (const char *name, const char *buffer, int);
extern void compile_resource_file (const char *, const char *);
extern void write_resource_constructor (void);
extern void init_resource_processing (void);
-
-extern void start_complete_expand_method (tree);
+extern tree build_java_empty_stmt (void);
+extern tree add_stmt_to_compound (tree, tree, tree);
+extern tree java_add_stmt (tree);
+extern tree java_add_local_var (tree decl);
+extern tree *get_stmts (void);
+extern void register_exception_range(struct eh_range *, int, int);
+extern void finish_method (tree);
extern void java_expand_body (tree);
extern int get_symbol_table_index (tree, tree *);
@@ -1353,6 +1411,8 @@ extern void gen_indirect_dispatch_tables (tree type);
/* Access flags etc for a method (a FUNCTION_DECL): */
+#define METHOD_DUMMY(DECL) (DECL_LANG_SPECIFIC (DECL)->u.f.dummy)
+
#define METHOD_PUBLIC(DECL) DECL_LANG_FLAG_1 (FUNCTION_DECL_CHECK (DECL))
#define METHOD_PRIVATE(DECL) TREE_PRIVATE (FUNCTION_DECL_CHECK (DECL))
#define METHOD_PROTECTED(DECL) TREE_PROTECTED (FUNCTION_DECL_CHECK (DECL))
@@ -1802,7 +1862,8 @@ enum
JV_STATE_PRELOADING = 1, /* Can do _Jv_FindClass. */
JV_STATE_LOADING = 3, /* Has super installed. */
- JV_STATE_LOADED = 5, /* Is complete. */
+ JV_STATE_READ = 4, /* Has been completely defined. */
+ JV_STATE_LOADED = 5, /* Has Miranda methods defined. */
JV_STATE_COMPILED = 6, /* This was a compiled class. */
@@ -1816,4 +1877,28 @@ enum
};
#undef DEBUG_JAVA_BINDING_LEVELS
+
+/* In an EXPR_WITH_FILE_LOCATION node. */
+#define EXPR_WFL_EMIT_LINE_NOTE(NODE) \
+ (EXPR_WITH_FILE_LOCATION_CHECK (NODE)->common.public_flag)
+#undef EXPR_WFL_NODE
+#define EXPR_WFL_NODE(NODE) \
+ TREE_OPERAND (EXPR_WITH_FILE_LOCATION_CHECK (NODE), 0)
+#undef EXPR_WFL_FILENAME_NODE
+#define EXPR_WFL_FILENAME_NODE(NODE) \
+ TREE_OPERAND (EXPR_WITH_FILE_LOCATION_CHECK (NODE), 1)
+#define EXPR_WFL_FILENAME(NODE) \
+ IDENTIFIER_POINTER (EXPR_WFL_FILENAME_NODE (NODE))
+/* ??? Java uses this in all expressions. */
+#define EXPR_WFL_LINECOL(NODE) (EXPR_CHECK (NODE)->exp.complexity)
+#define EXPR_WFL_LINENO(NODE) (EXPR_WFL_LINECOL (NODE) >> 12)
+#define EXPR_WFL_COLNO(NODE) (EXPR_WFL_LINECOL (NODE) & 0xfff)
+#define EXPR_WFL_SET_LINECOL(NODE, LINE, COL) \
+ (EXPR_WFL_LINECOL(NODE) = ((LINE) << 12) | ((COL) & 0xfff))
+
+extern tree build_expr_wfl PARAMS ((tree, const char *, int, int));
+
+extern void java_genericize PARAMS ((tree));
+extern int java_gimplify_expr PARAMS ((tree *, tree *, tree *));
+
#endif /* ! GCC_JAVA_TREE_H */
diff --git a/gcc/java/jcf-parse.c b/gcc/java/jcf-parse.c
index e8fd413e01a..839ed811130 100644
--- a/gcc/java/jcf-parse.c
+++ b/gcc/java/jcf-parse.c
@@ -564,7 +564,14 @@ void
load_class (tree class_or_name, int verbose)
{
tree name, saved;
- int class_loaded;
+ int class_loaded = 0;
+ tree class_decl = NULL_TREE;
+ bool is_compiled_class = false;
+
+ /* We've already failed, don't try again. */
+ if (TREE_CODE (class_or_name) == RECORD_TYPE
+ && TYPE_DUMMY (class_or_name))
+ return;
/* class_or_name can be the name of the class we want to load */
if (TREE_CODE (class_or_name) == IDENTIFIER_NODE)
@@ -577,31 +584,88 @@ load_class (tree class_or_name, int verbose)
else
name = DECL_NAME (TYPE_NAME (class_or_name));
+ class_decl = IDENTIFIER_CLASS_VALUE (name);
+ if (class_decl != NULL_TREE)
+ {
+ tree type = TREE_TYPE (class_decl);
+ is_compiled_class
+ = ((TYPE_JCF (type) && JCF_SEEN_IN_ZIP (TYPE_JCF (type)))
+ || CLASS_FROM_CURRENTLY_COMPILED_P (type));
+ }
+
saved = name;
- while (1)
+
+ /* If flag_verify_invocations is unset, we don't try to load a class
+ unless we're looking for Object (which is fixed by the ABI) or
+ it's a class that we're going to compile. */
+ if (flag_verify_invocations
+ || class_or_name == object_type_node
+ || is_compiled_class
+ || TREE_CODE (class_or_name) == IDENTIFIER_NODE)
{
- char *separator;
+ while (1)
+ {
+ char *separator;
- if ((class_loaded = read_class (name)))
- break;
+ /* We've already loaded it. */
+ if (IDENTIFIER_CLASS_VALUE (name) != NULL_TREE)
+ {
+ tree tmp_decl = IDENTIFIER_CLASS_VALUE (name);
+ if (CLASS_PARSED_P (TREE_TYPE (tmp_decl)))
+ break;
+ }
+
+ if (read_class (name))
+ break;
+
+ /* We failed loading name. Now consider that we might be looking
+ for a inner class. */
+ if ((separator = strrchr (IDENTIFIER_POINTER (name), '$'))
+ || (separator = strrchr (IDENTIFIER_POINTER (name), '.')))
+ {
+ int c = *separator;
+ *separator = '\0';
+ name = get_identifier (IDENTIFIER_POINTER (name));
+ *separator = c;
+ }
+ /* Otherwise, we failed, we bail. */
+ else
+ break;
+ }
- /* We failed loading name. Now consider that we might be looking
- for a inner class. */
- if ((separator = strrchr (IDENTIFIER_POINTER (name), '$'))
- || (separator = strrchr (IDENTIFIER_POINTER (name), '.')))
+ {
+ /* have we found the class we're looking for? */
+ tree type_decl = IDENTIFIER_CLASS_VALUE (saved);
+ tree type = type_decl ? TREE_TYPE (type_decl) : NULL;
+ class_loaded = type && CLASS_PARSED_P (type);
+ }
+ }
+
+ if (!class_loaded)
+ {
+ if (flag_verify_invocations || ! flag_indirect_dispatch
+ || flag_emit_class_files)
{
- int c = *separator;
- *separator = '\0';
- name = get_identifier (IDENTIFIER_POINTER (name));
- *separator = c;
+ if (verbose)
+ error ("cannot find file for class %s", IDENTIFIER_POINTER (saved));
+ }
+ else if (verbose)
+ {
+ /* This is just a diagnostic during testing, not a real problem. */
+ if (!quiet_flag)
+ warning("cannot find file for class %s",
+ IDENTIFIER_POINTER (saved));
+
+ /* Fake it. */
+ if (TREE_CODE (class_or_name) == RECORD_TYPE)
+ {
+ set_super_info (0, class_or_name, object_type_node, 0);
+ TYPE_DUMMY (class_or_name) = 1;
+ /* We won't be able to output any debug info for this class. */
+ DECL_IGNORED_P (TYPE_NAME (class_or_name)) = 1;
+ }
}
- /* Otherwise, we failed, we bail. */
- else
- break;
}
-
- if (!class_loaded && verbose)
- error ("cannot find file for class %s", IDENTIFIER_POINTER (saved));
}
/* Parse the .class file JCF. */
@@ -716,7 +780,7 @@ parse_class_file (void)
{
JCF *jcf = current_jcf;
- if (METHOD_ABSTRACT (method))
+ if (METHOD_ABSTRACT (method) || METHOD_DUMMY (method))
continue;
if (METHOD_NATIVE (method))
@@ -738,7 +802,7 @@ parse_class_file (void)
DECL_MAX_LOCALS (method) = decl_max_locals;
start_java_method (method);
give_name_to_locals (jcf);
- expand_expr_stmt (build_jni_stub (method));
+ *get_stmts () = build_jni_stub (method);
end_java_method ();
continue;
}
@@ -762,7 +826,7 @@ parse_class_file (void)
for (ptr += 2; --i >= 0; ptr += 4)
{
int line = GET_u2 (ptr);
- /* Set initial lineno lineno to smallest linenumber.
+ /* Set initial input_line to smallest linenumber.
* Needs to be set before init_function_start. */
if (input_line == 0 || line < input_line)
input_line = line;
@@ -780,7 +844,7 @@ parse_class_file (void)
give_name_to_locals (jcf);
- /* Actually generate code. */
+ /* Convert bytecode to trees. */
expand_byte_code (jcf, method);
end_java_method ();
@@ -833,6 +897,7 @@ static void
parse_source_file_2 (void)
{
int save_error_count = java_error_count;
+ flag_verify_invocations = true;
java_complete_class (); /* Parse unsatisfied class decl. */
java_parse_abort_on_error ();
}
@@ -1098,6 +1163,10 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
input_filename = IDENTIFIER_POINTER (TREE_VALUE (node));
if (CLASS_FILE_P (node))
{
+ /* FIXME: These two flags really should be independent. We
+ should be able to compile fully binary compatible, but
+ with flag_verify_invocations on. */
+ flag_verify_invocations = ! flag_indirect_dispatch;
output_class = current_class = TREE_PURPOSE (node);
current_jcf = TYPE_JCF (current_class);
layout_class (current_class);
@@ -1111,13 +1180,16 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
java_expand_classes ();
if (!java_report_errors () && !flag_syntax_only)
{
- /* Optimize and expand all classes compiled from source. */
- cgraph_finalize_compilation_unit ();
- cgraph_optimize ();
+ /* Expand all classes compiled from source. */
java_finish_classes ();
/* Emit the .jcf section. */
emit_register_classes ();
+
+ /* Only finalize the compilation unit after we've told cgraph which
+ functions have their addresses stored. */
+ cgraph_finalize_compilation_unit ();
+ cgraph_optimize ();
}
write_resource_constructor ();
@@ -1190,6 +1262,14 @@ parse_zip_file_entries (void)
current_jcf = TYPE_JCF (class);
output_class = current_class = class;
+ if (TYPE_DUMMY (class))
+ {
+ /* This is a dummy class, and now we're compiling it
+ for real. Forget everything we thought we knew
+ about its structure. */
+ abort ();
+ }
+
if (! CLASS_LOADED_P (class))
{
if (! CLASS_PARSED_P (class))
diff --git a/gcc/java/jcf-write.c b/gcc/java/jcf-write.c
index 36a21d3f740..c715a2c1ed8 100644
--- a/gcc/java/jcf-write.c
+++ b/gcc/java/jcf-write.c
@@ -1428,7 +1428,7 @@ generate_bytecode_insns (tree exp, int target, struct jcf_partial *state)
{
location_t saved_location = input_location;
tree body = EXPR_WFL_NODE (exp);
- if (body == empty_stmt_node)
+ if (IS_EMPTY_STMT (body))
break;
input_filename = EXPR_WFL_FILENAME (exp);
input_line = EXPR_WFL_LINENO (exp);
@@ -1773,7 +1773,7 @@ generate_bytecode_insns (tree exp, int target, struct jcf_partial *state)
case RETURN_EXPR:
exp = TREE_OPERAND (exp, 0);
if (exp == NULL_TREE)
- exp = empty_stmt_node;
+ exp = build_java_empty_stmt ();
else if (TREE_CODE (exp) != MODIFY_EXPR)
abort ();
else
diff --git a/gcc/java/lang.c b/gcc/java/lang.c
index 4856e5f9c6e..9d686d00f5d 100644
--- a/gcc/java/lang.c
+++ b/gcc/java/lang.c
@@ -66,8 +66,6 @@ static bool java_can_use_bit_fields_p (void);
static bool java_dump_tree (void *, tree);
static void dump_compound_expr (dump_info_p, tree);
static bool java_decl_ok_for_sibcall (tree);
-static int java_estimate_num_insns (tree);
-static int java_start_inlining (tree);
static tree java_get_callee_fndecl (tree);
#ifndef TARGET_OBJECT_SUFFIX
@@ -174,12 +172,16 @@ int flag_force_classes_archive_check;
/* When zero, don't optimize static class initialization. This flag shouldn't
be tested alone, use STATIC_CLASS_INITIALIZATION_OPTIMIZATION_P instead. */
-int flag_optimize_sci = 1;
+/* FIXME: Make this work with gimplify. */
+int flag_optimize_sci = 0;
/* When nonzero, use offset tables for virtual method calls
in order to improve binary compatibility. */
int flag_indirect_dispatch = 0;
+/* Don't attempt to verify invocations. */
+int flag_verify_invocations = 0;
+
/* When zero, don't generate runtime array store checks. */
int flag_store_check = 1;
@@ -249,18 +251,15 @@ struct language_function GTY(())
#undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
#define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE java_signed_or_unsigned_type
-#undef LANG_HOOKS_TREE_INLINING_WALK_SUBTREES
-#define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES java_tree_inlining_walk_subtrees
-
-#undef LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS
-#define LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS java_estimate_num_insns
-
-#undef LANG_HOOKS_TREE_INLINING_START_INLINING
-#define LANG_HOOKS_TREE_INLINING_START_INLINING java_start_inlining
-
#undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
#define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN java_dump_tree
+#undef LANG_HOOKS_GIMPLIFY_EXPR
+#define LANG_HOOKS_GIMPLIFY_EXPR java_gimplify_expr
+
+#undef LANG_HOOKS_TREE_INLINING_WALK_SUBTREES
+#define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES java_tree_inlining_walk_subtrees
+
#undef LANG_HOOKS_DECL_OK_FOR_SIBCALL
#define LANG_HOOKS_DECL_OK_FOR_SIBCALL java_decl_ok_for_sibcall
@@ -732,19 +731,20 @@ java_post_options (const char **pfilename)
{
const char *filename = *pfilename;
- /* Use tree inlining if possible. Function instrumentation is only
- done in the RTL level, so we disable tree inlining. */
- if (! flag_instrument_function_entry_exit)
+ /* Use tree inlining. */
+ if (!flag_no_inline)
+ flag_no_inline = 1;
+ if (flag_inline_functions)
{
- if (!flag_no_inline)
- flag_no_inline = 1;
- if (flag_inline_functions)
- {
- flag_inline_trees = 2;
- flag_inline_functions = 0;
- }
+ flag_inline_trees = 2;
+ flag_inline_functions = 0;
}
+ /* An absolute requirement: if we're not using indirect dispatch, we
+ must always verify everything. */
+ if (! flag_indirect_dispatch)
+ flag_verify_invocations = true;
+
/* Open input file. */
if (filename == 0 || !strcmp (filename, "-"))
@@ -1124,122 +1124,6 @@ java_decl_ok_for_sibcall (tree decl)
return decl != NULL && DECL_CONTEXT (decl) == output_class;
}
-/* Used by estimate_num_insns. Estimate number of instructions seen
- by given statement. */
-static tree
-java_estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
-{
- int *count = data;
- tree x = *tp;
-
- if (TYPE_P (x) || DECL_P (x))
- {
- *walk_subtrees = 0;
- return NULL;
- }
- /* Assume that constants and references counts nothing. These should
- be majorized by amount of operations among them we count later
- and are common target of CSE and similar optimizations. */
- if (TREE_CODE_CLASS (TREE_CODE (x)) == 'c'
- || TREE_CODE_CLASS (TREE_CODE (x)) == 'r')
- return NULL;
- switch (TREE_CODE (x))
- {
- /* Recognize assignments of large structures and constructors of
- big arrays. */
- case MODIFY_EXPR:
- case CONSTRUCTOR:
- {
- HOST_WIDE_INT size;
-
- size = int_size_in_bytes (TREE_TYPE (x));
-
- if (size < 0 || size > MOVE_MAX_PIECES * MOVE_RATIO)
- *count += 10;
- else
- *count += ((size + MOVE_MAX_PIECES - 1) / MOVE_MAX_PIECES);
- }
- break;
- /* Few special cases of expensive operations. This is usefull
- to avoid inlining on functions having too many of these. */
- case TRUNC_DIV_EXPR:
- case CEIL_DIV_EXPR:
- case FLOOR_DIV_EXPR:
- case ROUND_DIV_EXPR:
- case TRUNC_MOD_EXPR:
- case CEIL_MOD_EXPR:
- case FLOOR_MOD_EXPR:
- case ROUND_MOD_EXPR:
- case RDIV_EXPR:
- case CALL_EXPR:
-
- case NEW_ARRAY_EXPR:
- case NEW_ANONYMOUS_ARRAY_EXPR:
- case NEW_CLASS_EXPR:
- *count += 10;
- break;
- /* Various containers that will produce no code themselves. */
- case INIT_EXPR:
- case TARGET_EXPR:
- case BIND_EXPR:
- case BLOCK:
- case TREE_LIST:
- case TREE_VEC:
- case IDENTIFIER_NODE:
- case PLACEHOLDER_EXPR:
- case WITH_CLEANUP_EXPR:
- case CLEANUP_POINT_EXPR:
- case NOP_EXPR:
- case VIEW_CONVERT_EXPR:
- case SAVE_EXPR:
- case UNSAVE_EXPR:
- case COMPLEX_EXPR:
- case REALPART_EXPR:
- case IMAGPART_EXPR:
- case TRY_CATCH_EXPR:
- case TRY_FINALLY_EXPR:
- case LABEL_EXPR:
- case EXIT_EXPR:
- case LABELED_BLOCK_EXPR:
- case EXIT_BLOCK_EXPR:
- case EXPR_WITH_FILE_LOCATION:
- case UNARY_PLUS_EXPR:
- case THIS_EXPR:
- case DEFAULT_EXPR:
- case TRY_EXPR:
-
- break;
- case CLASS_LITERAL:
- *walk_subtrees = 0;
- break;
- default:
- (*count)++;
- }
- return NULL;
-}
-
-/* Estimate number of instructions that will be created by expanding the body. */
-static int
-java_estimate_num_insns (tree decl)
-{
- int num = 0;
- walk_tree_without_duplicates (&DECL_SAVED_TREE (decl),
- java_estimate_num_insns_1, &num);
- return num;
-}
-
-/* Start inlining fn. Called by the tree inliner via
- lang_hooks.tree_inlining.cannot_inline_tree_fn. */
-
-static int
-java_start_inlining (tree fn)
-{
- /* A java function's body doesn't have a BLOCK structure suitable
- for debug output until it is expanded. Prevent inlining functions
- that are not yet expanded. */
- return TREE_ASM_WRITTEN (fn) ? 1 : 0;
-}
-
/* Given a call_expr, try to figure out what its target might be. In
the case of an indirection via the atable, search for the decl. If
the decl is external, we return NULL. If we don't, the optimizer
@@ -1252,6 +1136,10 @@ java_get_callee_fndecl (tree call_expr)
HOST_WIDE_INT index;
+ /* FIXME: This is disabled because we end up passing calls through
+ the PLT, and we do NOT want to do that. */
+ return NULL;
+
if (TREE_CODE (call_expr) != CALL_EXPR)
return NULL;
method = TREE_OPERAND (call_expr, 0);
diff --git a/gcc/java/lang.opt b/gcc/java/lang.opt
index 3e9cdf1250a..ae367a718a5 100644
--- a/gcc/java/lang.opt
+++ b/gcc/java/lang.opt
@@ -116,9 +116,6 @@ Java JoinedOrMissing RejectNegative
fcompile-resource=
Java Joined RejectNegative
-fdump-
-Java Joined RejectNegative
-
femit-class-file
Java
diff --git a/gcc/java/parse.y b/gcc/java/parse.y
index a21fc2a0919..88e633c690b 100644
--- a/gcc/java/parse.y
+++ b/gcc/java/parse.y
@@ -76,6 +76,7 @@ definitions and other extensions. */
/* Local function prototypes */
static char *java_accstring_lookup (int);
+static const char *accessibility_string (int);
static void classitf_redefinition_error (const char *,tree, tree, tree);
static void variable_redefinition_error (tree, tree, tree, int);
static tree create_class (int, tree, tree, tree);
@@ -106,7 +107,7 @@ static void read_import_dir (tree);
static int find_in_imports_on_demand (tree, tree);
static void find_in_imports (tree, tree);
static void check_inner_class_access (tree, tree, tree);
-static int check_pkg_class_access (tree, tree, bool);
+static int check_pkg_class_access (tree, tree, bool, tree);
static void register_package (tree);
static tree resolve_package (tree, tree *, tree *);
static tree resolve_class (tree, tree, tree, tree);
@@ -143,6 +144,7 @@ static tree java_complete_tree (tree);
static tree maybe_generate_pre_expand_clinit (tree);
static int analyze_clinit_body (tree, tree);
static int maybe_yank_clinit (tree);
+static void start_complete_expand_method (tree);
static void java_complete_expand_method (tree);
static void java_expand_method_bodies (tree);
static int unresolved_type_p (tree, tree *);
@@ -196,7 +198,6 @@ static void check_deprecation (tree, tree);
static int class_in_current_package (tree);
static tree build_if_else_statement (int, tree, tree, tree);
static tree patch_if_else_statement (tree);
-static tree add_stmt_to_compound (tree, tree, tree);
static tree add_stmt_to_block (tree, tree, tree);
static tree patch_exit_expr (tree);
static tree build_labeled_block (int, tree);
@@ -909,7 +910,7 @@ class_body_declaration:
| constructor_declaration
| block /* Added, JDK1.1, instance initializer */
{
- if ($1 != empty_stmt_node)
+ if (!IS_EMPTY_STMT ($1))
{
TREE_CHAIN ($1) = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
SET_CPC_INSTANCE_INITIALIZER_STMT (ctxp, $1);
@@ -1197,7 +1198,7 @@ constructor_body:
addition (super invocation and field initialization) */
block_begin constructor_block_end
{
- BLOCK_EXPR_BODY ($2) = empty_stmt_node;
+ BLOCK_EXPR_BODY ($2) = build_java_empty_stmt ();
$$ = $2;
}
| block_begin explicit_constructor_invocation constructor_block_end
@@ -1375,7 +1376,7 @@ block_end:
EXPR_WFL_ADD_COL ($1.location, 1);
$$ = exit_block ();
if (!BLOCK_SUBBLOCKS ($$))
- BLOCK_SUBBLOCKS ($$) = empty_stmt_node;
+ BLOCK_SUBBLOCKS ($$) = build_java_empty_stmt ();
}
;
@@ -1454,7 +1455,7 @@ empty_statement:
EXPR_WFL_SET_LINECOL (wfl_operator, input_line, -1);
parse_warning_context (wfl_operator, "An empty declaration is a deprecated feature that should not be used");
}
- $$ = empty_stmt_node;
+ $$ = build_java_empty_stmt ();
}
;
@@ -1587,7 +1588,7 @@ switch_statement:
switch_expression:
SWITCH_TK OP_TK expression CP_TK
{
- $$ = build (SWITCH_EXPR, NULL_TREE, $3, NULL_TREE);
+ $$ = build (SWITCH_EXPR, NULL_TREE, $3, NULL_TREE, NULL_TREE);
EXPR_WFL_LINECOL ($$) = $2.location;
}
| SWITCH_TK error
@@ -1697,7 +1698,7 @@ for_statement:
$$ = finish_for_loop (0, NULL_TREE, $4, $6);
/* We have not condition, so we get rid of the EXIT_EXPR */
LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) =
- empty_stmt_node;
+ build_java_empty_stmt ();
}
| for_begin SC_TK error
{yyerror ("Invalid control expression"); RECOVER;}
@@ -1715,7 +1716,7 @@ for_statement_nsi:
$$ = finish_for_loop (0, NULL_TREE, $4, $6);
/* We have not condition, so we get rid of the EXIT_EXPR */
LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) =
- empty_stmt_node;
+ build_java_empty_stmt ();
}
;
@@ -1746,7 +1747,7 @@ for_begin:
}
;
for_init: /* Can be empty */
- { $$ = empty_stmt_node; }
+ { $$ = build_java_empty_stmt (); }
| statement_expression_list
{
/* Init statement recorded within the previously
@@ -1764,7 +1765,7 @@ for_init: /* Can be empty */
;
for_update: /* Can be empty */
- {$$ = empty_stmt_node;}
+ {$$ = build_java_empty_stmt ();}
| statement_expression_list
{ $$ = build_debugable_stmt (BUILD_LOCATION (), $1); }
;
@@ -1917,7 +1918,7 @@ catch_clause_parameter:
declare_local_variables (0, TREE_VALUE ($3),
build_tree_list
(TREE_PURPOSE ($3), init));
- $$ = build1 (CATCH_EXPR, NULL_TREE, ccpb);
+ $$ = build1 (JAVA_CATCH_EXPR, NULL_TREE, ccpb);
EXPR_WFL_LINECOL ($$) = $1.location;
}
else
@@ -2987,7 +2988,7 @@ parse_jdk1_1_error (const char *msg)
{
sorry (": `%s' JDK1.1(TM) feature", msg);
java_error_count++;
- return empty_stmt_node;
+ return build_java_empty_stmt ();
}
static int do_warning = 0;
@@ -3182,7 +3183,7 @@ not_accessible_field_error (tree wfl, tree decl)
{
parse_error_context
(wfl, "Can't access %s field `%s.%s' from `%s'",
- java_accstring_lookup (get_access_flags_from_decl (decl)),
+ accessibility_string (get_access_flags_from_decl (decl)),
GET_TYPE_NAME (DECL_CONTEXT (decl)),
IDENTIFIER_POINTER (DECL_NAME (decl)),
IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
@@ -3228,6 +3229,22 @@ java_accstring_lookup (int flags)
#undef COPY_RETURN
}
+/* Returns a string denoting the accessibility of a class or a member as
+ indicated by FLAGS. We need a separate function from
+ java_accstring_lookup, as the latter can return spurious "static", etc.
+ if package-private access is defined (in which case none of the
+ relevant access control bits in FLAGS is set). */
+
+static const char *
+accessibility_string (int flags)
+{
+ if (flags & ACC_PRIVATE) return "private";
+ if (flags & ACC_PROTECTED) return "protected";
+ if (flags & ACC_PUBLIC) return "public";
+
+ return "package-private";
+}
+
/* Issuing error messages upon redefinition of classes, interfaces or
variables. */
@@ -4020,6 +4037,11 @@ create_class (int flags, tree id, tree super, tree interfaces)
CLASS_COMPLETE_P (decl) = 1;
add_superinterfaces (decl, interfaces);
+ /* TYPE_VFIELD' is a compiler-generated field used to point to
+ virtual function tables. In gcj, every class has a common base
+ virtual function table in java.lang.object. */
+ TYPE_VFIELD (TREE_TYPE (decl)) = TYPE_VFIELD (object_type_node);
+
/* Add the private this$<n> field, Replicate final locals still in
scope as private final fields mangled like val$<local_name>.
This doesn't not occur for top level (static) inner classes. */
@@ -4317,7 +4339,7 @@ register_fields (int flags, tree type, tree variable_list)
if (duplicate_declaration_error_p (current_name, real_type, cl))
continue;
- /* Set lineno to the line the field was found and create a
+ /* Set input_line to the line the field was found and create a
declaration for it. Eventually sets the @deprecated tag flag. */
if (flag_emit_xref)
input_line = EXPR_WFL_LINECOL (cl);
@@ -5062,7 +5084,7 @@ parser_check_super_interface (tree super_decl, tree this_decl, tree this_wfl)
access rules (6.6.1). */
if (! INNER_CLASS_P (super_type)
&& check_pkg_class_access (DECL_NAME (super_decl),
- lookup_cl (this_decl), true))
+ NULL_TREE, true, this_decl))
return 1;
SOURCE_FRONTEND_DEBUG (("Completing interface %s with %s",
@@ -5100,7 +5122,7 @@ parser_check_super (tree super_decl, tree this_decl, tree wfl)
/* Check top-level class scope. Inner classes are subject to member access
rules (6.6.1). */
if (! INNER_CLASS_P (super_type)
- && (check_pkg_class_access (DECL_NAME (super_decl), wfl, true)))
+ && (check_pkg_class_access (DECL_NAME (super_decl), wfl, true, NULL_TREE)))
return 1;
SOURCE_FRONTEND_DEBUG (("Completing class %s with %s",
@@ -5469,7 +5491,7 @@ java_fix_constructors (void)
}
/* safe_layout_class just makes sure that we can load a class without
- disrupting the current_class, input_file, lineno, etc, information
+ disrupting the current_class, input_file, input_line, etc, information
about the class processed currently. */
void
@@ -5840,7 +5862,7 @@ do_resolve_class (tree enclosing, tree class_type, tree decl, tree cl)
by the caller. */
if (cl)
{
- if (check_pkg_class_access (TYPE_NAME (class_type), cl, true))
+ if (check_pkg_class_access (TYPE_NAME (class_type), cl, true, NULL_TREE))
return NULL_TREE;
}
@@ -6800,7 +6822,7 @@ process_imports (void)
QUALIFIED_P (to_be_found) = 1;
load_class (to_be_found, 0);
error_found =
- check_pkg_class_access (to_be_found, TREE_PURPOSE (import), true);
+ check_pkg_class_access (to_be_found, TREE_PURPOSE (import), true, NULL_TREE);
/* We found it, we can bail out */
if (IDENTIFIER_CLASS_VALUE (to_be_found))
@@ -7025,7 +7047,7 @@ find_in_imports_on_demand (tree enclosing_type, tree class_type)
if (! (node = maybe_get_identifier (id_name)))
continue;
- /* Setup lineno so that it refers to the line of the import (in
+ /* Setup input_line so that it refers to the line of the import (in
case we parse a class file and encounter errors */
input_line = EXPR_WFL_LINENO (TREE_PURPOSE (import));
@@ -7044,7 +7066,7 @@ find_in_imports_on_demand (tree enclosing_type, tree class_type)
}
if (decl && ! INNER_CLASS_P (TREE_TYPE (decl)))
access_check = check_pkg_class_access (node, TREE_PURPOSE (import),
- false);
+ false, NULL_TREE);
else
/* 6.6.1: Inner classes are subject to member access rules. */
access_check = 0;
@@ -7230,10 +7252,11 @@ check_inner_class_access (tree decl, tree enclosing_decl, tree cl)
/* Accessibility check for top-level classes. If CLASS_NAME is in a
foreign package, it must be PUBLIC. Return 0 if no access
violations were found, 1 otherwise. If VERBOSE is true and an error
- was found, it is reported and accounted for. */
+ was found, it is reported and accounted for. If CL is NULL then
+ look it up with THIS_DECL. */
static int
-check_pkg_class_access (tree class_name, tree cl, bool verbose)
+check_pkg_class_access (tree class_name, tree cl, bool verbose, tree this_decl)
{
tree type;
@@ -7258,7 +7281,8 @@ check_pkg_class_access (tree class_name, tree cl, bool verbose)
if (verbose)
parse_error_context
- (cl, "Can't access %s `%s'. Only public classes and interfaces in other packages can be accessed",
+ (cl == NULL ? lookup_cl (this_decl): cl,
+ "Can't access %s `%s'. Only public classes and interfaces in other packages can be accessed",
(CLASS_INTERFACE (TYPE_NAME (type)) ? "interface" : "class"),
IDENTIFIER_POINTER (class_name));
return 1;
@@ -7503,19 +7527,17 @@ source_end_java_method (void)
/* Turn function bodies with only a NOP expr null, so they don't get
generated at all and we won't get warnings when using the -W
-Wall flags. */
- if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) == empty_stmt_node)
+ if (IS_EMPTY_STMT (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))))
BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) = NULL_TREE;
- /* We've generated all the trees for this function, and it has been
- patched. Dump it to a file if the user requested it. */
- dump_java_tree (TDI_original, fndecl);
-
- /* Defer expanding the method until cgraph analysis is complete. */
- if (DECL_SAVED_TREE (fndecl))
- cgraph_finalize_function (fndecl, false);
+ if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
+ && ! flag_emit_class_files
+ && ! flag_emit_xref)
+ finish_method (fndecl);
current_function_decl = NULL_TREE;
java_parser_context_restore_global ();
+ current_function_decl = NULL_TREE;
}
/* Record EXPR in the current function block. Complements compound
@@ -7545,18 +7567,6 @@ add_stmt_to_block (tree b, tree type, tree stmt)
return c;
}
-/* Add STMT to EXISTING if possible, otherwise create a new
- COMPOUND_EXPR and add STMT to it. */
-
-static tree
-add_stmt_to_compound (tree existing, tree type, tree stmt)
-{
- if (existing)
- return build (COMPOUND_EXPR, type, existing, stmt);
- else
- return stmt;
-}
-
void java_layout_seen_class_methods (void)
{
tree previous_list = all_class_list;
@@ -7829,7 +7839,7 @@ maybe_generate_pre_expand_clinit (tree class_type)
/* We build the assignment expression that will initialize the
field to its value. There are strict rules on static
initializers (8.5). FIXME */
- if (TREE_CODE (stmt) != BLOCK && stmt != empty_stmt_node)
+ if (TREE_CODE (stmt) != BLOCK && !IS_EMPTY_STMT (stmt))
stmt = build_debugable_stmt (EXPR_WFL_LINECOL (stmt), stmt);
java_method_add_stmt (mdecl, stmt);
}
@@ -7923,7 +7933,7 @@ maybe_yank_clinit (tree mdecl)
bbody = BLOCK_EXPR_BODY (bbody);
else
return 0;
- if (bbody && ! flag_emit_class_files && bbody != empty_stmt_node)
+ if (bbody && ! flag_emit_class_files && !IS_EMPTY_STMT (bbody))
return 0;
type = DECL_CONTEXT (mdecl);
@@ -7957,7 +7967,7 @@ maybe_yank_clinit (tree mdecl)
/* Now we analyze the method body and look for something that
isn't a MODIFY_EXPR */
- if (bbody != empty_stmt_node && analyze_clinit_body (type, bbody))
+ if (!IS_EMPTY_STMT (bbody) && analyze_clinit_body (type, bbody))
return 0;
/* Get rid of <clinit> in the class' list of methods */
@@ -8122,7 +8132,6 @@ java_expand_method_bodies (tree class)
for (decl = TYPE_METHODS (class); decl; decl = TREE_CHAIN (decl))
{
tree block;
- tree body;
if (! DECL_FUNCTION_BODY (decl))
continue;
@@ -8131,17 +8140,9 @@ java_expand_method_bodies (tree class)
block = BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl));
- if (TREE_CODE (block) != BLOCK)
- abort ();
-
- /* Save the function body for inlining. */
+ /* Save the function body for gimplify and inlining. */
DECL_SAVED_TREE (decl) = block;
- body = BLOCK_EXPR_BODY (block);
-
- if (TREE_TYPE (body) == NULL_TREE)
- abort ();
-
/* It's time to assign the variable flagging static class
initialization based on which classes invoked static methods
are definitely initializing. This should be flagged. */
@@ -8173,41 +8174,7 @@ java_expand_method_bodies (tree class)
}
}
- /* Prepend class initialization to static methods. */
- if (METHOD_STATIC (decl) && ! METHOD_PRIVATE (decl)
- && ! flag_emit_class_files
- && ! DECL_CLINIT_P (decl)
- && ! CLASS_INTERFACE (TYPE_NAME (class)))
- {
- tree init = build (CALL_EXPR, void_type_node,
- build_address_of (soft_initclass_node),
- build_tree_list (NULL_TREE,
- build_class_ref (class)),
- NULL_TREE);
- TREE_SIDE_EFFECTS (init) = 1;
- body = build (COMPOUND_EXPR, TREE_TYPE (body), init, body);
- BLOCK_EXPR_BODY (block) = body;
- }
-
- /* Wrap synchronized method bodies in a monitorenter
- plus monitorexit cleanup. */
- if (METHOD_SYNCHRONIZED (decl) && ! flag_emit_class_files)
- {
- tree enter, exit, lock;
- if (METHOD_STATIC (decl))
- lock = build_class_ref (class);
- else
- lock = DECL_ARGUMENTS (decl);
- BUILD_MONITOR_ENTER (enter, lock);
- BUILD_MONITOR_EXIT (exit, lock);
-
- body = build (COMPOUND_EXPR, void_type_node,
- enter,
- build (TRY_FINALLY_EXPR, void_type_node, body, exit));
- BLOCK_EXPR_BODY (block) = body;
- }
-
- /* Expand the the function body. */
+ /* Expand the function body. */
source_end_java_method ();
}
}
@@ -8939,7 +8906,7 @@ fix_constructors (tree mdecl)
{
compound = add_stmt_to_compound (compound, NULL_TREE,
TREE_OPERAND (found_call, 0));
- TREE_OPERAND (found_call, 0) = empty_stmt_node;
+ TREE_OPERAND (found_call, 0) = build_java_empty_stmt ();
}
DECL_INIT_CALLS_THIS (mdecl) = invokes_this;
@@ -9446,7 +9413,7 @@ resolve_field_access (tree qual_wfl, tree *field_decl, tree *field_type)
{
int is_static = 0;
tree field_ref;
- tree decl, where_found, type_found;
+ tree decl = NULL_TREE, where_found, type_found;
if (resolve_qualified_expression_name (qual_wfl, &decl,
&where_found, &type_found))
@@ -9528,8 +9495,8 @@ strip_out_static_field_access_decl (tree node)
tree call = TREE_OPERAND (op1, 0);
if (TREE_CODE (call) == CALL_EXPR
&& TREE_CODE (TREE_OPERAND (call, 0)) == ADDR_EXPR
- && TREE_OPERAND (TREE_OPERAND (call, 0), 0)
- == soft_initclass_node)
+ && (TREE_OPERAND (TREE_OPERAND (call, 0), 0)
+ == soft_initclass_node))
return TREE_OPERAND (op1, 1);
}
else if (JDECL_P (op1))
@@ -9819,6 +9786,8 @@ resolve_qualified_expression_name (tree wfl, tree *found_decl,
tree list;
*where_found = decl;
+ check_pkg_class_access (DECL_NAME (decl), qual_wfl, true, NULL);
+
/* We want to be absolutely sure that the class is laid
out. We're going to search something inside it. */
*type_found = type = TREE_TYPE (decl);
@@ -9859,8 +9828,8 @@ resolve_qualified_expression_name (tree wfl, tree *found_decl,
decl = QUAL_RESOLUTION (q);
/* Sneak preview. If next we see a `new', we're facing a
- qualification with resulted in a type being selected
- instead of a field. Report the error */
+ qualification which resulted in a type being selected
+ instead of a field. Report the error. */
if(TREE_CHAIN (q)
&& TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR)
{
@@ -9869,15 +9838,8 @@ resolve_qualified_expression_name (tree wfl, tree *found_decl,
return 1;
}
- if (not_accessible_p (TREE_TYPE (decl), decl, type, 0))
- {
- parse_error_context
- (qual_wfl, "Can't access %s class '%s' from '%s'",
- java_accstring_lookup (get_access_flags_from_decl (decl)),
- IDENTIFIER_POINTER (DECL_NAME (decl)),
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
- return 1;
- }
+ check_pkg_class_access (DECL_NAME (decl), qual_wfl, true, NULL);
+
check_deprecation (qual_wfl, decl);
type = TREE_TYPE (decl);
@@ -10140,14 +10102,9 @@ not_accessible_p (tree reference, tree member, tree where, int from_super)
return 1;
}
- /* Default access are permitted only when occurring within the
- package in which the type (REFERENCE) is declared. In other words,
- REFERENCE is defined in the current package */
- if (ctxp->package)
- return !class_in_current_package (reference);
-
- /* Otherwise, access is granted */
- return 0;
+ /* Default access is permitted only when occurring from within the
+ package in which the context (MEMBER) is declared. */
+ return !class_in_current_package (DECL_CONTEXT (member));
}
/* Test deprecated decl access. */
@@ -10540,7 +10497,7 @@ patch_method_invocation (tree patch, tree primary, tree where, int from_super,
{
const char *const fct_name = IDENTIFIER_POINTER (DECL_NAME (list));
const char *const access =
- java_accstring_lookup (get_access_flags_from_decl (list));
+ accessibility_string (get_access_flags_from_decl (list));
const char *const klass =
IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (list))));
const char *const refklass =
@@ -10848,8 +10805,7 @@ patch_invoke (tree patch, tree method, tree args)
if (TREE_CODE (original_call) == NEW_CLASS_EXPR)
{
tree class = DECL_CONTEXT (method);
- tree c1, saved_new, size, new;
- tree alloc_node;
+ tree c1, saved_new, new;
if (flag_emit_class_files || flag_emit_xref)
{
@@ -10858,16 +10814,7 @@ patch_invoke (tree patch, tree method, tree args)
}
if (!TYPE_SIZE (class))
safe_layout_class (class);
- size = size_in_bytes (class);
- alloc_node =
- (class_has_finalize_method (class) ? alloc_object_node
- : alloc_no_finalizer_node);
- new = build (CALL_EXPR, promote_type (class),
- build_address_of (alloc_node),
- tree_cons (NULL_TREE, build_class_ref (class),
- build_tree_list (NULL_TREE,
- size_in_bytes (class))),
- NULL_TREE);
+ new = java_create_object (class);
saved_new = save_expr (new);
c1 = build_tree_list (NULL_TREE, saved_new);
TREE_CHAIN (c1) = TREE_OPERAND (original_call, 1);
@@ -10903,10 +10850,10 @@ patch_invoke (tree patch, tree method, tree args)
/* We have to call force_evaluation_order now because creating a
COMPOUND_EXPR wraps the arg list in a way that makes it
unrecognizable by force_evaluation_order later. Yuk. */
- tree save = save_expr (force_evaluation_order (patch));
+ tree save = force_evaluation_order (patch);
tree type = TREE_TYPE (patch);
- patch = build (COMPOUND_EXPR, type, save, empty_stmt_node);
+ patch = build (COMPOUND_EXPR, type, save, build_java_empty_stmt ());
list = tree_cons (method, patch,
DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (fndecl));
@@ -10934,11 +10881,20 @@ invocation_mode (tree method, int super)
if (DECL_CONSTRUCTOR_P (method))
return INVOKE_STATIC;
- if (access & ACC_FINAL || access & ACC_PRIVATE)
+ if (access & ACC_PRIVATE)
return INVOKE_NONVIRTUAL;
- if (CLASS_FINAL (TYPE_NAME (DECL_CONTEXT (method))))
- return INVOKE_NONVIRTUAL;
+ /* Binary compatibility: just because it's final today, that doesn't
+ mean it'll be final tomorrow. */
+ if (! flag_indirect_dispatch
+ || DECL_CONTEXT (method) == object_type_node)
+ {
+ if (access & ACC_FINAL)
+ return INVOKE_NONVIRTUAL;
+
+ if (CLASS_FINAL (TYPE_NAME (DECL_CONTEXT (method))))
+ return INVOKE_NONVIRTUAL;
+ }
if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
return INVOKE_INTERFACE;
@@ -11535,12 +11491,12 @@ java_complete_lhs (tree node)
long blocks. */
ptr = &BLOCK_EXPR_BODY (node);
while (TREE_CODE (*ptr) == COMPOUND_EXPR
- && TREE_OPERAND (*ptr, 1) != empty_stmt_node)
+ && !IS_EMPTY_STMT (TREE_OPERAND (*ptr, 1)))
{
tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
tree *next = &TREE_OPERAND (*ptr, 1);
TREE_OPERAND (*ptr, 0) = cur;
- if (cur == empty_stmt_node)
+ if (IS_EMPTY_STMT (cur))
{
/* Optimization; makes it easier to detect empty bodies.
Most useful for <clinit> with all-constant initializer. */
@@ -11601,13 +11557,11 @@ java_complete_lhs (tree node)
case TRY_FINALLY_EXPR:
COMPLETE_CHECK_OP_0 (node);
COMPLETE_CHECK_OP_1 (node);
- /* Reduce try/finally nodes with an empty try block. */
- if (TREE_OPERAND (node, 0) == empty_stmt_node
- || BLOCK_EMPTY_P (TREE_OPERAND (node, 0)))
+ if (IS_EMPTY_STMT (TREE_OPERAND (node, 0)))
+ /* Reduce try/finally nodes with an empty try block. */
return TREE_OPERAND (node, 1);
- /* Likewise for an empty finally block. */
- if (TREE_OPERAND (node, 1) == empty_stmt_node
- || BLOCK_EMPTY_P (TREE_OPERAND (node, 1)))
+ if (IS_EMPTY_STMT (TREE_OPERAND (node, 1)))
+ /* Likewise for an empty finally block. */
return TREE_OPERAND (node, 0);
CAN_COMPLETE_NORMALLY (node)
= (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
@@ -11622,7 +11576,7 @@ java_complete_lhs (tree node)
TREE_TYPE (node) = void_type_node;
POP_LABELED_BLOCK ();
- if (LABELED_BLOCK_BODY (node) == empty_stmt_node)
+ if (IS_EMPTY_STMT (LABELED_BLOCK_BODY (node)))
{
LABELED_BLOCK_BODY (node) = NULL_TREE;
CAN_COMPLETE_NORMALLY (node) = 1;
@@ -11779,7 +11733,7 @@ java_complete_lhs (tree node)
wfl_op2 = TREE_OPERAND (node, 1);
TREE_OPERAND (node, 0) = nn =
java_complete_tree (TREE_OPERAND (node, 0));
- if (wfl_op2 == empty_stmt_node)
+ if (IS_EMPTY_STMT (wfl_op2))
CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
else
{
@@ -11852,7 +11806,7 @@ java_complete_lhs (tree node)
EXPR_WFL_NODE (node) = body;
TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
- if (body == empty_stmt_node || TREE_CONSTANT (body))
+ if (IS_EMPTY_STMT (body) || TREE_CONSTANT (body))
{
/* Makes it easier to constant fold, detect empty bodies. */
return body;
@@ -11988,7 +11942,7 @@ java_complete_lhs (tree node)
else
DECL_INITIAL (nn) = TREE_OPERAND (node, 1);
DECL_FIELD_FINAL_IUD (nn) = 1;
- return empty_stmt_node;
+ return build_java_empty_stmt ();
}
}
if (! flag_emit_class_files)
@@ -12432,14 +12386,14 @@ build_wfl_wrap (tree node, int location)
return wfl;
}
-/* Build a super() constructor invocation. Returns empty_stmt_node if
+/* Build a super() constructor invocation. Returns an empty statement if
we're currently dealing with the class java.lang.Object. */
static tree
build_super_invocation (tree mdecl)
{
if (DECL_CONTEXT (mdecl) == object_type_node)
- return empty_stmt_node;
+ return build_java_empty_stmt ();
else
{
tree super_wfl = build_wfl_node (super_identifier_node);
@@ -12774,6 +12728,7 @@ patch_assignment (tree node, tree wfl_op1)
)
{
TREE_CONSTANT (lvalue) = 1;
+ TREE_INVARIANT (lvalue) = 1;
DECL_INITIAL (lvalue) = new_rhs;
}
@@ -12786,7 +12741,7 @@ patch_assignment (tree node, tree wfl_op1)
case INDIRECT_REF:
case COMPONENT_REF:
/* Transform a = foo.bar
- into a = { int tmp; tmp = foo.bar; tmp; ).
+ into a = ({int tmp; tmp = foo.bar;}).
We need to ensure that if a read from memory fails
because of a NullPointerException, a destination variable
will remain unchanged. An explicit temporary does what
@@ -12805,8 +12760,7 @@ patch_assignment (tree node, tree wfl_op1)
DECL_CONTEXT (tmp) = current_function_decl;
TREE_TYPE (block) = TREE_TYPE (new_rhs);
BLOCK_VARS (block) = tmp;
- BLOCK_EXPR_BODY (block)
- = build (COMPOUND_EXPR, TREE_TYPE (new_rhs), assignment, tmp);
+ BLOCK_EXPR_BODY (block) = assignment;
TREE_SIDE_EFFECTS (block) = 1;
new_rhs = block;
}
@@ -13328,6 +13282,7 @@ patch_binop (tree node, tree wfl_op1, tree wfl_op2)
{
parse_warning_context (wfl_operator, "Evaluating this expression will result in an arithmetic exception being thrown");
TREE_CONSTANT (node) = 0;
+ TREE_INVARIANT (node) = 0;
}
/* Change the division operator if necessary */
@@ -13914,8 +13869,15 @@ patch_string_cst (tree node)
location = alloc_name_constant (CONSTANT_String, node);
node = build_ref_from_constant_pool (location);
}
- TREE_TYPE (node) = string_ptr_type_node;
TREE_CONSTANT (node) = 1;
+ TREE_INVARIANT (node) = 1;
+
+ /* ??? Guessing that the class file code can't handle casts. */
+ if (! flag_emit_class_files)
+ node = convert (string_ptr_type_node, node);
+ else
+ TREE_TYPE (node) = string_ptr_type_node;
+
return node;
}
@@ -14633,7 +14595,9 @@ patch_new_array_init (tree type, tree node)
TREE_TYPE (init) = TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (type))));
TREE_TYPE (node) = promote_type (type);
TREE_CONSTANT (init) = all_constant;
+ TREE_INVARIANT (init) = all_constant;
TREE_CONSTANT (node) = all_constant;
+ TREE_INVARIANT (node) = all_constant;
return node;
}
@@ -14802,7 +14766,7 @@ build_if_else_statement (int location, tree expression, tree if_body,
{
tree node;
if (!else_body)
- else_body = empty_stmt_node;
+ else_body = build_java_empty_stmt ();
node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body);
EXPR_WFL_LINECOL (node) = location;
node = build_debugable_stmt (location, node);
@@ -14831,19 +14795,6 @@ patch_if_else_statement (tree node)
return error_mark_node;
}
- if (TREE_CODE (expression) == INTEGER_CST)
- {
- if (integer_zerop (expression))
- node = TREE_OPERAND (node, 2);
- else
- node = TREE_OPERAND (node, 1);
- if (CAN_COMPLETE_NORMALLY (node) != can_complete_normally)
- {
- node = build (COMPOUND_EXPR, void_type_node, node, empty_stmt_node);
- CAN_COMPLETE_NORMALLY (node) = can_complete_normally;
- }
- return node;
- }
TREE_TYPE (node) = void_type_node;
TREE_SIDE_EFFECTS (node) = 1;
CAN_COMPLETE_NORMALLY (node) = can_complete_normally;
@@ -14952,7 +14903,8 @@ build_loop_body (int location, tree condition, int reversed)
second = (reversed ? condition : body);
return
build (COMPOUND_EXPR, NULL_TREE,
- build (COMPOUND_EXPR, NULL_TREE, first, second), empty_stmt_node);
+ build (COMPOUND_EXPR, NULL_TREE, first, second),
+ build_java_empty_stmt ());
}
/* Install CONDITION (if any) and loop BODY (using REVERSED to tell
@@ -14992,14 +14944,14 @@ finish_for_loop (int location, tree condition, tree update, tree body)
this because the (current interpretation of the) JLS requires
that the update expression be considered reachable even if the
for loop's body doesn't complete normally. */
- if (update != NULL_TREE && update != empty_stmt_node)
+ if (update != NULL_TREE && !IS_EMPTY_STMT (update))
{
tree up2 = update;
if (TREE_CODE (up2) == EXPR_WITH_FILE_LOCATION)
up2 = EXPR_WFL_NODE (up2);
/* It is possible for the update expression to be an
EXPR_WFL_NODE wrapping nothing. */
- if (up2 != NULL_TREE && up2 != empty_stmt_node)
+ if (up2 != NULL_TREE && !IS_EMPTY_STMT (up2))
{
/* Try to detect constraint violations. These would be
programming errors somewhere. */
@@ -15311,7 +15263,7 @@ build_assertion (int location, tree condition, tree value)
condition = build (TRUTH_ANDIF_EXPR, NULL_TREE,
boolean_false_node, condition);
if (value == NULL_TREE)
- value = empty_stmt_node;
+ value = build_java_empty_stmt ();
return build_if_else_statement (location, condition,
value, NULL_TREE);
}
@@ -15420,8 +15372,8 @@ encapsulate_with_try_catch (int location, tree type_or_name, tree try_stmts,
/* Add the catch statements */
add_stmt_to_block (catch_block, NULL_TREE, catch_stmts);
- /* Now we can build a CATCH_EXPR */
- catch_block = build1 (CATCH_EXPR, NULL_TREE, catch_block);
+ /* Now we can build a JAVA_CATCH_EXPR */
+ catch_block = build1 (JAVA_CATCH_EXPR, NULL_TREE, catch_block);
return build_try_statement (location, try_block, catch_block);
}
@@ -15462,7 +15414,7 @@ patch_try_statement (tree node)
int unreachable;
/* At this point, the structure of the catch clause is
- CATCH_EXPR (catch node)
+ JAVA_CATCH_EXPR (catch node)
BLOCK (with the decl of the parameter)
COMPOUND_EXPR
MODIFY_EXPR (assignment of the catch parameter)
diff --git a/gcc/java/resource.c b/gcc/java/resource.c
index 5d4b72a13ae..dc42a6f6e7e 100644
--- a/gcc/java/resource.c
+++ b/gcc/java/resource.c
@@ -79,6 +79,7 @@ compile_resource_data (const char *name, const char *buffer, int length)
PUSH_FIELD_VALUE (rinit, "data", data);
FINISH_RECORD_CONSTRUCTOR (rinit);
TREE_CONSTANT (rinit) = 1;
+ TREE_INVARIANT (rinit) = 1;
/* Generate a unique-enough identifier. */
sprintf (buf, "_Jr%d", ++Jr_count);
@@ -129,6 +130,9 @@ write_resource_constructor (void)
to scan the object file to find its ctor/dtor routine. */
TREE_PUBLIC (init_decl) = ! targetm.have_ctors_dtors;
+ /* Suppress spurious warnings. */
+ TREE_USED (init_decl) = 1;
+
pushlevel (0);
make_decl_rtl (init_decl, NULL);
init_function_start (init_decl);
@@ -156,8 +160,9 @@ write_resource_constructor (void)
flag_inline_functions = saved_flag;
}
current_function_decl = NULL_TREE;
- (* targetm.asm_out.constructor) (XEXP (DECL_RTL (init_decl), 0),
- DEFAULT_INIT_PRIORITY);
+ if (targetm.have_ctors_dtors)
+ targetm.asm_out.constructor (XEXP (DECL_RTL (init_decl), 0),
+ DEFAULT_INIT_PRIORITY);
input_location = saved_loc;
}
diff --git a/gcc/java/typeck.c b/gcc/java/typeck.c
index d52afd23562..6984bede010 100644
--- a/gcc/java/typeck.c
+++ b/gcc/java/typeck.c
@@ -391,9 +391,17 @@ build_java_array_type (tree element_type, HOST_WIDE_INT length)
el_name = TYPE_NAME (el_name);
if (TREE_CODE (el_name) == TYPE_DECL)
el_name = DECL_NAME (el_name);
- TYPE_NAME (t) = build_decl (TYPE_DECL,
- identifier_subst (el_name, "", '.', '.', "[]"),
+ {
+ char suffix[12];
+ if (length >= 0)
+ sprintf (suffix, "[%d]", (int)length);
+ else
+ strcpy (suffix, "[]");
+ TYPE_NAME (t)
+ = build_decl (TYPE_DECL,
+ identifier_subst (el_name, "", '.', '.', suffix),
t);
+ }
set_java_signature (t, sig);
set_super_info (0, t, object_type_node, 0);
diff --git a/gcc/java/verify-glue.c b/gcc/java/verify-glue.c
new file mode 100644
index 00000000000..cd46416f80c
--- /dev/null
+++ b/gcc/java/verify-glue.c
@@ -0,0 +1,434 @@
+/* Glue to interface gcj with bytecode verifier.
+ Copyright (C) 2003 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 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+
+Java and all Java-based marks are trademarks or registered trademarks
+of Sun Microsystems, Inc. in the United States and other countries.
+The Free Software Foundation is independent of Sun Microsystems, Inc. */
+
+/* Written by Tom Tromey <tromey@redhat.com>. */
+
+#include "config.h"
+
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "errors.h"
+#include "parse.h"
+
+#include "verify.h"
+#include "java-tree.h"
+
+void *
+vfy_alloc (size_t bytes)
+{
+ return xmalloc (bytes);
+}
+
+void
+vfy_free (void *mem)
+{
+ free (mem);
+}
+
+bool
+vfy_strings_equal (vfy_string one, vfy_string two)
+{
+ return one == two;
+}
+
+const char *
+vfy_string_bytes (vfy_string str)
+{
+ return IDENTIFIER_POINTER (str);
+}
+
+int
+vfy_string_length (vfy_string str)
+{
+ return IDENTIFIER_LENGTH (str);
+}
+
+vfy_string
+vfy_init_name ()
+{
+ return init_identifier_node;
+}
+
+vfy_string
+vfy_clinit_name ()
+{
+ return clinit_identifier_node;
+}
+
+static const char*
+skip_one_type (const char* ptr)
+{
+ int ch = *ptr++;
+
+ while (ch == '[')
+ {
+ ch = *ptr++;
+ }
+
+ if (ch == 'L')
+ {
+ do { ch = *ptr++; } while (ch != ';');
+ }
+
+ return ptr;
+}
+
+int
+vfy_count_arguments (vfy_string signature)
+{
+ const char *ptr = IDENTIFIER_POINTER (signature);
+ int arg_count = 0;
+
+ /* Skip '('. */
+ ptr++;
+
+ /* Count args. */
+ while (*ptr != ')')
+ {
+ ptr = skip_one_type (ptr);
+ arg_count += 1;
+ }
+
+ return arg_count;
+}
+
+vfy_string
+vfy_get_string (const char *s, int len)
+{
+ return get_identifier_with_length (s, len);
+}
+
+vfy_string
+vfy_get_signature (vfy_method *method)
+{
+ return method->signature;
+}
+
+vfy_string
+vfy_get_method_name (vfy_method *method)
+{
+ return method->name;
+}
+
+bool
+vfy_is_static (vfy_method *method)
+{
+ return METHOD_STATIC (method->method);
+}
+
+const unsigned char *
+vfy_get_bytecode (vfy_method *method)
+{
+ return method->bytes;
+}
+
+vfy_exception *
+vfy_get_exceptions (vfy_method *method)
+{
+ return method->exceptions;
+}
+
+void
+vfy_get_exception (vfy_exception *exceptions, int index, int *handler,
+ int *start, int *end, int *handler_type)
+{
+ *handler = exceptions[index].handler;
+ *start = exceptions[index].start;
+ *end = exceptions[index].end;
+ *handler_type = exceptions[index].type;
+}
+
+int
+vfy_tag (vfy_constants *pool, int index)
+{
+ return JPOOL_TAG (pool, index);
+}
+
+void
+vfy_load_indexes (vfy_constants *pool, int index,
+ vfy_uint_16 *index0, vfy_uint_16 *index1)
+{
+ *index0 = JPOOL_USHORT1 (pool, index);
+ *index1 = JPOOL_USHORT2 (pool, index);
+}
+
+vfy_constants *
+vfy_get_constants (vfy_jclass klass)
+{
+ return TYPE_JCF (klass);
+}
+
+int
+vfy_get_constants_size (vfy_jclass klass)
+{
+ return JPOOL_SIZE (TYPE_JCF (klass));
+}
+
+vfy_string
+vfy_get_pool_string (vfy_constants *pool, int index)
+{
+ return get_name_constant (pool, index);
+}
+
+vfy_jclass
+vfy_get_pool_class (vfy_constants *pool, int index)
+{
+ vfy_jclass k;
+ k = get_class_constant (pool, index);
+ return k;
+}
+
+vfy_string
+vfy_make_string (const char *s, int len)
+{
+ tree result;
+ char *s2 = (char *) s;
+ char save = s2[len];
+ s2[len] = '\0';
+ result = get_identifier (s2);
+ s2[len] = save;
+ return result;
+}
+
+vfy_string
+vfy_get_class_name (vfy_jclass klass)
+{
+ return TYPE_NAME (klass);
+}
+
+char
+vfy_get_primitive_char (vfy_jclass klass)
+{
+ tree sig;
+ if (! vfy_is_primitive (klass))
+ abort ();
+ sig = build_java_signature (klass);
+ return (IDENTIFIER_POINTER (sig))[0];
+}
+
+int
+vfy_get_interface_count (vfy_jclass klass ATTRIBUTE_UNUSED)
+{
+ /* FIXME: Need to merge from mainline to get this. */
+ #if 0
+ return BINFO_N_BASE_BINFOS (klass);
+ #endif
+ return -1;
+}
+
+vfy_jclass
+vfy_get_interface (vfy_jclass klass ATTRIBUTE_UNUSED, int index ATTRIBUTE_UNUSED)
+{
+ /* FIXME: Need to merge from mainline to get this. */
+ #if 0
+ vfy_jclass k;
+ k = BINFO_BASE_BINFO (klass, index);
+ return k;
+ #endif
+ return NULL;
+}
+
+bool
+vfy_is_array (vfy_jclass klass)
+{
+ return TYPE_ARRAY_P (klass);
+}
+
+bool
+vfy_is_interface (vfy_jclass klass)
+{
+ return CLASS_INTERFACE (TYPE_NAME (klass));
+}
+
+bool
+vfy_is_primitive (vfy_jclass klass)
+{
+ printf ("debug: vfy_is_primitive()\n");
+ return JPRIMITIVE_TYPE_P (klass);
+}
+
+vfy_jclass
+vfy_get_superclass (vfy_jclass klass)
+{
+ vfy_jclass k;
+ k = CLASSTYPE_SUPER (klass);
+ return k;
+}
+
+vfy_jclass
+vfy_get_array_class (vfy_jclass klass)
+{
+ vfy_jclass k;
+ k = build_java_array_type (klass, -1);
+ return k;
+}
+
+vfy_jclass
+vfy_get_component_type (vfy_jclass klass)
+{
+ vfy_jclass k;
+ if (! vfy_is_array (klass))
+ abort ();
+ k = TYPE_ARRAY_ELEMENT (klass);
+ return k;
+}
+
+bool
+vfy_is_abstract (vfy_jclass klass)
+{
+ return CLASS_ABSTRACT (TYPE_NAME (klass));
+}
+
+vfy_jclass
+vfy_find_class (vfy_jclass ignore ATTRIBUTE_UNUSED, vfy_string name)
+{
+ vfy_jclass k;
+ k = lookup_class (name);
+ return k;
+}
+
+vfy_jclass
+vfy_object_type ()
+{
+ vfy_jclass k;
+ k = object_type_node;
+ return k;
+}
+
+vfy_jclass
+vfy_string_type ()
+{
+ vfy_jclass k;
+ k = string_type_node;
+ return k;
+}
+
+vfy_jclass
+vfy_throwable_type ()
+{
+ vfy_jclass k;
+ k = throwable_type_node;
+ return k;
+}
+
+int
+vfy_fail (const char *message, int pc, vfy_jclass ignore1 ATTRIBUTE_UNUSED,
+ vfy_method *ignore2 ATTRIBUTE_UNUSED)
+{
+ if (pc == -1)
+ error ("verification failed: %s", message);
+ else
+ error ("verification failed at PC=%d: %s", pc, message);
+ /* We have to return a value for the verifier to throw. */
+ return 1;
+}
+
+void
+vfy_notify_verified (int pc)
+{
+ instruction_bits[pc] |= BCODE_VERIFIED;
+}
+
+vfy_jclass
+vfy_get_primitive_type (int type)
+{
+ vfy_jclass k;
+ k = decode_newarray_type (type);
+ return k;
+}
+
+void
+vfy_note_stack_depth (int pc, int depth)
+{
+ tree label = lookup_label (pc);
+ LABEL_TYPE_STATE (label) = make_tree_vec (depth);
+}
+
+void
+vfy_note_type (int pc, int slot, vfy_jclass type)
+{
+ tree label = lookup_label (pc);
+ tree vec = LABEL_TYPE_STATE (label);
+ TREE_VEC_ELT (vec, slot) = type;
+}
+
+
+/* Verify the bytecodes of the current method.
+ Return 1 on success, 0 on failure. */
+int
+verify_jvm_instructions_new (JCF *jcf, const unsigned char *byte_ops,
+ long length)
+{
+ vfy_method method;
+ int i, result, eh_count;
+ vfy_exception *exceptions;
+
+ /*method_init_exceptions ();*/
+ JCF_SEEK (jcf, DECL_CODE_OFFSET (current_function_decl) + length);
+ eh_count = JCF_readu2 (jcf);
+
+ exceptions = (vfy_exception *) xmalloc (eh_count * sizeof (vfy_exception));
+ for (i = 0; i < eh_count; ++i)
+ {
+ int start_pc, end_pc, handler_pc, catch_type;
+ unsigned char *p = jcf->read_ptr + 8 * i;
+ start_pc = GET_u2 (p);
+ end_pc = GET_u2 (p+2);
+ handler_pc = GET_u2 (p+4);
+ catch_type = GET_u2 (p+6);
+
+ if (start_pc < 0 || start_pc >= length
+ || end_pc < 0 || end_pc > length || start_pc >= end_pc
+ || handler_pc < 0 || handler_pc >= length)
+ {
+ error ("bad pc in exception_table");
+ free (exceptions);
+ return 0;
+ }
+
+ exceptions[i].handler = handler_pc;
+ exceptions[i].start = start_pc;
+ exceptions[i].end = end_pc;
+ exceptions[i].type = catch_type;
+ }
+
+ method.method = current_function_decl;
+ method.signature = build_java_signature (TREE_TYPE (current_function_decl));
+ method.name = DECL_NAME (current_function_decl);
+ method.bytes = byte_ops;
+ method.exceptions = exceptions;
+ method.defining_class = DECL_CONTEXT (current_function_decl);
+ method.max_stack = DECL_MAX_STACK (current_function_decl);
+ method.max_locals = DECL_MAX_LOCALS (current_function_decl);
+ method.code_length = length;
+ method.exc_count = eh_count;
+
+ result = verify_method (&method);
+
+ free (exceptions);
+
+ return result;
+}
diff --git a/gcc/java/verify-impl.c b/gcc/java/verify-impl.c
new file mode 100644
index 00000000000..d63c8e46d33
--- /dev/null
+++ b/gcc/java/verify-impl.c
@@ -0,0 +1,3336 @@
+/* Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+/* Written by Tom Tromey <tromey@redhat.com> */
+
+/* Uncomment this to enable debugging output. */
+/* #define VERIFY_DEBUG */
+
+#include "config.h"
+
+#include "verify.h"
+
+#ifdef VERIFY_DEBUG
+#include <stdio.h>
+#endif /* VERIFY_DEBUG */
+
+/* This is used to mark states which are not scheduled for
+ verification. */
+#define INVALID_STATE ((state *) -1)
+
+#ifdef VERIFY_DEBUG
+static void
+debug_print (const char *fmt, ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ vfprintf (stderr, fmt, ap);
+ va_end (ap);
+}
+#else
+static void
+debug_print (const char *fmt ATTRIBUTE_UNUSED, ...)
+{
+}
+#endif /* VERIFY_DEBUG */
+
+#if 0
+static void debug_print (const char *fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
+
+static void
+debug_print (const char *fmt, ...)
+{
+#ifdef VERIFY_DEBUG
+ va_list ap;
+ va_start (ap, fmt);
+ vfprintf (stderr, fmt, ap);
+ va_end (ap);
+#endif /* VERIFY_DEBUG */
+}
+#endif
+
+/* This started as a fairly ordinary verifier, and for the most part
+ it remains so. It works in the obvious way, by modeling the effect
+ of each opcode as it is encountered. For most opcodes, this is a
+ straightforward operation.
+
+ This verifier does not do type merging. It used to, but this
+ results in difficulty verifying some relatively simple code
+ involving interfaces, and it pushed some verification work into the
+ interpreter.
+
+ Instead of merging reference types, when we reach a point where two
+ flows of control merge, we simply keep the union of reference types
+ from each branch. Then, when we need to verify a fact about a
+ reference on the stack (e.g., that it is compatible with the
+ argument type of a method), we check to ensure that all possible
+ types satisfy the requirement.
+
+ Another area this verifier differs from the norm is in its handling
+ of subroutines. The JVM specification has some confusing things to
+ say about subroutines. For instance, it makes claims about not
+ allowing subroutines to merge and it rejects recursive subroutines.
+ For the most part these are red herrings; we used to try to follow
+ these things but they lead to problems. For example, the notion of
+ "being in a subroutine" is not well-defined: is an exception
+ handler in a subroutine? If you never execute the `ret' but
+ instead `goto 1' do you remain in the subroutine?
+
+ For clarity on what is really required for type safety, read
+ "Simple Verification Technique for Complex Java Bytecode
+ Subroutines" by Alessandro Coglio. Among other things this paper
+ shows that recursive subroutines are not harmful to type safety.
+ We implement something similar to what he proposes. Note that this
+ means that this verifier will accept code that is rejected by some
+ other verifiers.
+
+ For those not wanting to read the paper, the basic observation is
+ that we can maintain split states in subroutines. We maintain one
+ state for each calling `jsr'. In other words, we re-verify a
+ subroutine once for each caller, using the exact types held by the
+ callers (as opposed to the old approach of merging types and
+ keeping a bitmap registering what did or did not change). This
+ approach lets us continue to verify correctly even when a
+ subroutine is exited via `goto' or `athrow' and not `ret'.
+
+ In some other areas the JVM specification is (mildly) incorrect,
+ but we still implement what is specified. For instance, you cannot
+ violate type safety by allocating an object with `new' and then
+ failing to initialize it, no matter how one branches or where one
+ stores the uninitialized reference. See "Improving the official
+ specification of Java bytecode verification" by Alessandro Coglio.
+ Similarly, there's no real point in enforcing that padding bytes or
+ the mystery byte of invokeinterface must be 0, but we do that too.
+
+ The verifier is currently neither completely lazy nor eager when it
+ comes to loading classes. It tries to represent types by name when
+ possible, and then loads them when it needs to verify a fact about
+ the type. Checking types by name is valid because we only use
+ names which come from the current class' constant pool. Since all
+ such names are looked up using the same class loader, there is no
+ danger that we might be fooled into comparing different types with
+ the same name.
+
+ In the future we plan to allow for a completely lazy mode of
+ operation, where the verifier will construct a list of type
+ assertions to be checked later.
+
+ Some test cases for the verifier live in the "verify" module of the
+ Mauve test suite. However, some of these are presently
+ (2004-01-20) believed to be incorrect. (More precisely the notion
+ of "correct" is not well-defined, and this verifier differs from
+ others while remaining type-safe.) Some other tests live in the
+ libgcj test suite.
+
+ This verifier is also written to be pluggable. This means that it
+ is intended for use in a variety of environments, not just libgcj.
+ As a result the verifier expects a number of type and method
+ declarations to be declared in "verify.h". The intent is that you
+ recompile the verifier for your particular environment. This
+ approach was chosen so that operations could be inlined in verify.h
+ as much as possible.
+
+ See the verify.h that accompanies this copy of the verifier to see
+ what types, preprocessor defines, and functions must be declared.
+ The interface is ad hoc, but was defined so that it could be
+ implemented to connect to a pure C program.
+*/
+
+#define FLAG_INSN_START 1
+#define FLAG_BRANCH_TARGET 2
+
+struct state;
+struct type;
+struct ref_intersection;
+
+typedef struct state state;
+typedef struct type type;
+typedef struct ref_intersection ref_intersection;
+
+/*typedef struct state_list state_list;*/
+
+typedef struct state_list
+{
+ state *val;
+ struct state_list *next;
+} state_list;
+
+typedef struct vfy_string_list
+{
+ vfy_string val;
+ struct vfy_string_list *next;
+} vfy_string_list;
+
+typedef struct verifier_context
+{
+ // The current PC.
+ int PC;
+ // The PC corresponding to the start of the current instruction.
+ int start_PC;
+
+ // The current state of the stack, locals, etc.
+ state *current_state;
+
+ // At each branch target we keep a linked list of all the states we
+ // can process at that point. We'll only have multiple states at a
+ // given PC if they both have different return-address types in the
+ // same stack or local slot. This array is indexed by PC and holds
+ // the list of all such states.
+ state_list **states;
+
+ // We keep a linked list of all the states which we must reverify.
+ // This is the head of the list.
+ state *next_verify_state;
+
+ // We keep some flags for each instruction. The values are the
+ // FLAG_* constants defined above. This is an array indexed by PC.
+ char *flags;
+
+ // The bytecode itself.
+ unsigned char *bytecode;
+ // The exceptions.
+ vfy_exception *exception;
+
+ // Defining class.
+ vfy_jclass current_class;
+ // This method.
+ vfy_method *current_method;
+
+ // A linked list of utf8 objects we allocate.
+ vfy_string_list *utf8_list;
+
+ // A linked list of all ref_intersection objects we allocate.
+ ref_intersection *isect_list;
+} verifier_context;
+
+/* The current verifier's state data. This is maintained by
+{push/pop}_verifier_context to provide a shorthand form to access the
+verification state. */
+static GTY(()) verifier_context *vfr;
+
+/* Local function declarations. */
+bool is_assignable_from_slow (vfy_jclass target, vfy_jclass source);
+bool type_initialized (type *t);
+int ref_count_dimensions (ref_intersection *ref);
+
+#if 0
+ // Create a new Utf-8 constant and return it. We do this to avoid
+ // having our Utf-8 constants prematurely collected.
+ static vfy_string
+ make_utf8_const (const char *s, int len)
+ {
+ vfy_string val = vfy_make_string (s, len);
+ vfy_string_list *lu = vfy_alloc (sizeof (vfy_string_list));
+ lu->val = val;
+ lu->next = vfr->utf8_list;
+ vfr->utf8_list = lu;
+
+ return val;
+ }
+#endif
+
+ static void
+ verify_fail_pc (const char *s, int pc)
+ {
+ if (pc == -1)
+ pc = vfr->start_PC;
+ vfy_fail (s, pc, vfr->current_class, vfr->current_method);
+ }
+
+ static void
+ verify_fail (const char *s)
+ {
+ verify_fail_pc (s, -1);
+ }
+
+ // This enum holds a list of tags for all the different types we
+ // need to handle. Reference types are treated specially by the
+ // type class.
+ typedef enum type_val
+ {
+ void_type,
+
+ // The values for primitive types are chosen to correspond to values
+ // specified to newarray.
+ boolean_type = 4,
+ char_type = 5,
+ float_type = 6,
+ double_type = 7,
+ byte_type = 8,
+ short_type = 9,
+ int_type = 10,
+ long_type = 11,
+
+ // Used when overwriting second word of a double or long in the
+ // local variables. Also used after merging local variable states
+ // to indicate an unusable value.
+ unsuitable_type,
+ return_address_type,
+ // This is the second word of a two-word value, i.e., a double or
+ // a long.
+ continuation_type,
+
+ // Everything after `reference_type' must be a reference type.
+ reference_type,
+ null_type,
+ uninitialized_reference_type
+ } type_val;
+
+ // This represents a merged class type. Some verifiers (including
+ // earlier versions of this one) will compute the intersection of
+ // two class types when merging states. However, this loses
+ // critical information about interfaces implemented by the various
+ // classes. So instead we keep track of all the actual classes that
+ // have been merged.
+ struct ref_intersection
+ {
+ // Whether or not this type has been resolved.
+ bool is_resolved;
+
+ // Actual type data.
+ union
+ {
+ // For a resolved reference type, this is a pointer to the class.
+ vfy_jclass klass;
+ // For other reference types, this it the name of the class.
+ vfy_string name;
+ } data;
+
+ // Link to the next reference in the intersection.
+ ref_intersection *ref_next;
+
+ // This is used to keep track of all the allocated
+ // ref_intersection objects, so we can free them.
+ // FIXME: we should allocate these in chunks.
+ ref_intersection *alloc_next;
+ };
+
+static ref_intersection *
+make_ref (void)
+{
+ ref_intersection *new_ref =
+ (ref_intersection *) vfy_alloc (sizeof (ref_intersection));
+
+ new_ref->alloc_next = vfr->isect_list;
+ vfr->isect_list = new_ref;
+ return new_ref;
+}
+
+static ref_intersection *
+clone_ref (ref_intersection *dup)
+{
+ ref_intersection *new_ref = make_ref ();
+
+ new_ref->is_resolved = dup->is_resolved;
+ new_ref->data = dup->data;
+ return new_ref;
+}
+
+static void
+resolve_ref (ref_intersection *ref)
+{
+ if (ref->is_resolved)
+ return;
+ ref->data.klass = vfy_find_class (vfr->current_class, ref->data.name);
+ ref->is_resolved = true;
+}
+
+static bool
+refs_equal (ref_intersection *ref1, ref_intersection *ref2)
+{
+ if (! ref1->is_resolved && ! ref2->is_resolved
+ && vfy_strings_equal (ref1->data.name, ref2->data.name))
+ return true;
+ if (! ref1->is_resolved)
+ resolve_ref (ref1);
+ if (! ref2->is_resolved)
+ resolve_ref (ref2);
+ return ref1->data.klass == ref2->data.klass;
+}
+
+/* Merge REF1 type into REF2, returning the result. This will
+ return REF2 if all the classes in THIS already appear in
+ REF2. */
+static ref_intersection *
+merge_refs (ref_intersection *ref1, ref_intersection *ref2)
+{
+ ref_intersection *tail = ref2;
+ for (; ref1 != NULL; ref1 = ref1->ref_next)
+ {
+ bool add = true;
+ ref_intersection *iter;
+ for (iter = ref2; iter != NULL; iter = iter->ref_next)
+ {
+ if (refs_equal (ref1, ref2))
+ {
+ add = false;
+ break;
+ }
+ }
+
+ if (add)
+ {
+ ref_intersection *new_tail = clone_ref (ref1);
+ new_tail->ref_next = tail;
+ tail = new_tail;
+ }
+ }
+ return tail;
+}
+
+/* See if an object of type OTHER can be assigned to an object of
+ type *THIS. This might resolve classes in one chain or the other. */
+static bool
+ref_compatible (ref_intersection *ref1, ref_intersection *ref2)
+{
+ for (; ref1 != NULL; ref1 = ref1->ref_next)
+ {
+ ref_intersection *ref2_iter = ref2;
+
+ for (; ref2_iter != NULL; ref2_iter = ref2_iter->ref_next)
+ {
+ // Avoid resolving if possible.
+ if (! ref1->is_resolved
+ && ! ref2_iter->is_resolved
+ && vfy_strings_equal (ref1->data.name,
+ ref2_iter->data.name))
+ continue;
+
+ if (! ref1->is_resolved)
+ resolve_ref (ref1);
+ if (! ref2_iter->is_resolved)
+ resolve_ref (ref2_iter);
+
+ if (! is_assignable_from_slow (ref1->data.klass,
+ ref2_iter->data.klass))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool
+ref_isarray (ref_intersection *ref)
+{
+ // assert (ref_next == NULL);
+ if (ref->is_resolved)
+ return vfy_is_array (ref->data.klass);
+ else
+ return vfy_string_bytes (ref->data.name)[0] == '[';
+}
+
+static bool
+ref_isinterface (ref_intersection *ref)
+{
+ // assert (ref_next == NULL);
+ if (! ref->is_resolved)
+ resolve_ref (ref);
+ return vfy_is_interface (ref->data.klass);
+}
+
+static bool
+ref_isabstract (ref_intersection *ref)
+{
+ // assert (ref_next == NULL);
+ if (! ref->is_resolved)
+ resolve_ref (ref);
+ return vfy_is_abstract (ref->data.klass);
+}
+
+static vfy_jclass
+ref_getclass (ref_intersection *ref)
+{
+ if (! ref->is_resolved)
+ resolve_ref (ref);
+ return ref->data.klass;
+}
+
+int
+ref_count_dimensions (ref_intersection *ref)
+{
+ int ndims = 0;
+ if (ref->is_resolved)
+ {
+ vfy_jclass k = ref->data.klass;
+ while (vfy_is_array (k))
+ {
+ k = vfy_get_component_type (k);
+ ++ndims;
+ }
+ }
+ else
+ {
+ const char *p = vfy_string_bytes (ref->data.name);
+ while (*p++ == '[')
+ ++ndims;
+ }
+ return ndims;
+}
+
+// Return the type_val corresponding to a primitive signature
+// character. For instance `I' returns `int.class'.
+static type_val
+get_type_val_for_signature (char sig)
+{
+ type_val rt;
+ switch (sig)
+ {
+ case 'Z':
+ rt = boolean_type;
+ break;
+ case 'B':
+ rt = byte_type;
+ break;
+ case 'C':
+ rt = char_type;
+ break;
+ case 'S':
+ rt = short_type;
+ break;
+ case 'I':
+ rt = int_type;
+ break;
+ case 'J':
+ rt = long_type;
+ break;
+ case 'F':
+ rt = float_type;
+ break;
+ case 'D':
+ rt = double_type;
+ break;
+ case 'V':
+ rt = void_type;
+ break;
+ default:
+ verify_fail ("invalid signature");
+ return null_type;
+ }
+ return rt;
+}
+
+// Return the type_val corresponding to a primitive class.
+static type_val
+get_type_val_for_primtype (vfy_jclass k)
+{
+ return get_type_val_for_signature (vfy_get_primitive_char (k));
+}
+
+// This is like _Jv_IsAssignableFrom, but it works even if SOURCE or
+// TARGET haven't been prepared.
+bool
+is_assignable_from_slow (vfy_jclass target, vfy_jclass source)
+{
+ // First, strip arrays.
+ while (vfy_is_array (target))
+ {
+ // If target is array, source must be as well.
+ if (! vfy_is_array (source))
+ return false;
+ target = vfy_get_component_type (target);
+ source = vfy_get_component_type (source);
+ }
+
+ // Quick success.
+ if (target == vfy_object_type ())
+ return true;
+
+ do
+ {
+ int i;
+ if (source == target)
+ return true;
+
+ if (vfy_is_primitive (target) || vfy_is_primitive (source))
+ return false;
+
+ if (vfy_is_interface (target))
+ {
+ for (i = 0; i < vfy_get_interface_count (source); ++i)
+ {
+ // We use a recursive call because we also need to
+ // check superinterfaces.
+ if (is_assignable_from_slow (target,
+ vfy_get_interface (source, i)))
+ return true;
+ }
+ }
+ source = vfy_get_superclass (source);
+ }
+ while (source != NULL);
+
+ return false;
+}
+
+// The `type' class is used to represent a single type in the
+// verifier.
+struct type
+{
+ // The type key.
+ type_val key;
+
+ // For reference types, the representation of the type.
+ ref_intersection *klass;
+
+ // This is used in two situations.
+ //
+ // First, when constructing a new object, it is the PC of the
+ // `new' instruction which created the object. We use the special
+ // value UNINIT to mean that this is uninitialized, and the
+ // special value SELF for the case where the current method is
+ // itself the <init> method.
+ //
+ // Second, when the key is return_address_type, this holds the PC
+ // of the instruction following the `jsr'.
+ int pc;
+
+ #define UNINIT -2
+ #define SELF -1
+};
+
+#if 0
+// Basic constructor.
+static void
+init_type (type *t)
+{
+ t->key = unsuitable_type;
+ t->klass = NULL;
+ t->pc = UNINIT;
+}
+#endif
+
+// Make a new instance given the type tag. We assume a generic
+// `reference_type' means Object.
+static void
+init_type_from_tag (type *t, type_val k)
+{
+ t->key = k;
+ // For reference_type, if KLASS==NULL then that means we are
+ // looking for a generic object of any kind, including an
+ // uninitialized reference.
+ t->klass = NULL;
+ t->pc = UNINIT;
+}
+
+/* Make a type for the given type_val tag K. */
+static type
+make_type (type_val k)
+{
+ type t;
+ init_type_from_tag (&t, k);
+ return t;
+}
+
+// Make a new instance given a class.
+static void
+init_type_from_class (type *t, vfy_jclass k)
+{
+ t->key = reference_type;
+ t->klass = make_ref ();
+ t->klass->data.klass = k;
+ t->pc = UNINIT;
+}
+
+static type
+make_type_from_class (vfy_jclass k)
+{
+ type t;
+ init_type_from_class (&t, k);
+ return t;
+}
+
+static void
+init_type_from_string (type *t, vfy_string n)
+{
+ t->key = reference_type;
+ t->klass = make_ref ();
+ t->klass->data.name = n;
+ t->pc = UNINIT;
+}
+
+static type
+make_type_from_string (vfy_string n)
+{
+ type t;
+ init_type_from_string (&t, n);
+ return t;
+}
+
+#if 0
+ // Make a new instance given the name of a class.
+ type (vfy_string n)
+ {
+ key = reference_type;
+ klass = new ref_intersection (n, verifier);
+ pc = UNINIT;
+ }
+
+ // Copy constructor.
+ static type copy_type (type *t)
+ {
+ type copy;
+ copy.key = t->key;
+ copy.klass = t->klass;
+ copy.pc = t->pc;
+ return copy;
+ }
+#endif
+
+/* Promote a numeric type. */
+static void
+vfy_promote_type (type *t)
+{
+ if (t->key == boolean_type || t->key == char_type
+ || t->key == byte_type || t->key == short_type)
+ t->key = int_type;
+}
+#define promote_type vfy_promote_type
+
+// Mark this type as the uninitialized result of `new'.
+static void
+type_set_uninitialized (type *t, int npc)
+{
+ if (t->key == reference_type)
+ t->key = uninitialized_reference_type;
+ else
+ verify_fail ("internal error in type::uninitialized");
+ t->pc = npc;
+}
+
+// Mark this type as now initialized.
+static void
+type_set_initialized (type *t, int npc)
+{
+ if (npc != UNINIT && t->pc == npc && t->key == uninitialized_reference_type)
+ {
+ t->key = reference_type;
+ t->pc = UNINIT;
+ }
+}
+
+// Mark this type as a particular return address.
+static void type_set_return_address (type *t, int npc)
+{
+ t->pc = npc;
+}
+
+// Return true if this type and type OTHER are considered
+// mergeable for the purposes of state merging. This is related
+// to subroutine handling. For this purpose two types are
+// considered unmergeable if they are both return-addresses but
+// have different PCs.
+static bool
+type_state_mergeable_p (type *t1, type *t2)
+{
+ return (t1->key != return_address_type
+ || t2->key != return_address_type
+ || t1->pc == t2->pc);
+}
+
+// Return true if an object of type K can be assigned to a variable
+// of type T. Handle various special cases too. Might modify
+// T or K. Note however that this does not perform numeric
+// promotion.
+static bool
+types_compatible (type *t, type *k)
+{
+ // Any type is compatible with the unsuitable type.
+ if (k->key == unsuitable_type)
+ return true;
+
+ if (t->key < reference_type || k->key < reference_type)
+ return t->key == k->key;
+
+ // The `null' type is convertible to any initialized reference
+ // type.
+ if (t->key == null_type)
+ return k->key != uninitialized_reference_type;
+ if (k->key == null_type)
+ return t->key != uninitialized_reference_type;
+
+ // A special case for a generic reference.
+ if (t->klass == NULL)
+ return true;
+ if (k->klass == NULL)
+ verify_fail ("programmer error in type::compatible");
+
+ // An initialized type and an uninitialized type are not
+ // compatible.
+ if (type_initialized (t) != type_initialized (k))
+ return false;
+
+ // Two uninitialized objects are compatible if either:
+ // * The PCs are identical, or
+ // * One PC is UNINIT.
+ if (type_initialized (t))
+ {
+ if (t->pc != k->pc && t->pc != UNINIT && k->pc != UNINIT)
+ return false;
+ }
+
+ return ref_compatible (t->klass, k->klass);
+}
+
+static bool
+type_isvoid (type *t)
+{
+ return t->key == void_type;
+}
+
+static bool
+type_iswide (type *t)
+{
+ return t->key == long_type || t->key == double_type;
+}
+
+/* Return number of stack or local variable slots taken by this type. */
+static int
+type_depth (type *t)
+{
+ return type_iswide (t) ? 2 : 1;
+}
+
+static bool
+type_isarray (type *t)
+{
+ /* We treat null_type as not an array. This is ok based on the
+ current uses of this method. */
+ if (t->key == reference_type)
+ return ref_isarray (t->klass);
+ return false;
+}
+
+static bool
+type_isnull (type *t)
+{
+ return t->key == null_type;
+}
+
+static bool
+type_isinterface (type *t)
+{
+ if (t->key != reference_type)
+ return false;
+ return ref_isinterface (t->klass);
+}
+
+static bool
+type_isabstract (type *t)
+{
+ if (t->key != reference_type)
+ return false;
+ return ref_isabstract (t->klass);
+}
+
+// Return the element type of an array.
+static type
+type_array_element (type *t)
+{
+ type et;
+
+ if (t->key != reference_type)
+ verify_fail ("programmer error in type::element_type()");
+
+ vfy_jclass k = vfy_get_component_type (ref_getclass (t->klass));
+ if (vfy_is_primitive (k))
+ init_type_from_tag (&et, get_type_val_for_primtype (k));
+ else
+ init_type_from_class (&et, k);
+ return et;
+}
+
+// Return the array type corresponding to an initialized
+// reference. We could expand this to work for other kinds of
+// types, but currently we don't need to.
+static type
+type_to_array (type *t)
+{
+ type at;
+ vfy_jclass k;
+
+ if (t->key != reference_type)
+ verify_fail ("internal error in type::to_array()");
+
+ k = ref_getclass (t->klass);
+ init_type_from_class (&at, vfy_get_array_class (k));
+ return at;
+}
+
+static bool
+type_isreference (type *t)
+{
+ return t->key >= reference_type;
+}
+
+static int
+type_get_pc (type *t)
+{
+ return t->pc;
+}
+
+bool
+type_initialized (type *t)
+{
+ return t->key == reference_type || t->key == null_type;
+}
+
+#if 0
+static bool
+type_isresolved (type *t)
+{
+ return (t->key == reference_type
+ || t->key == null_type
+ || t->key == uninitialized_reference_type);
+}
+#endif
+
+static void
+type_verify_dimensions (type *t, int ndims)
+{
+ // The way this is written, we don't need to check isarray().
+ if (t->key != reference_type)
+ verify_fail ("internal error in verify_dimensions:"
+ " not a reference type");
+
+ if (ref_count_dimensions (t->klass) < ndims)
+ verify_fail ("array type has fewer dimensions"
+ " than required");
+}
+
+// Merge OLD_TYPE into this. On error throw exception. Return
+// true if the merge caused a type change.
+static bool
+merge_types (type *t, type *old_type, bool local_semantics)
+{
+ bool changed = false;
+ bool refo = type_isreference (old_type);
+ bool refn = type_isreference (t);
+ if (refo && refn)
+ {
+ if (old_type->key == null_type)
+ ;
+ else if (t->key == null_type)
+ {
+ t = old_type;
+ changed = true;
+ }
+ else if (type_initialized (t) != type_initialized (old_type))
+ verify_fail ("merging initialized and uninitialized types");
+ else
+ {
+ if (! type_initialized (t))
+ {
+ if (t->pc == UNINIT)
+ t->pc = old_type->pc;
+ else if (old_type->pc == UNINIT)
+ ;
+ else if (t->pc != old_type->pc)
+ verify_fail ("merging different uninitialized types");
+ }
+
+ ref_intersection *merged = merge_refs (old_type->klass, t->klass);
+ if (merged != t->klass)
+ {
+ t->klass = merged;
+ changed = true;
+ }
+ }
+ }
+ else if (refo || refn || t->key != old_type->key)
+ {
+ if (local_semantics)
+ {
+ // If we already have an `unsuitable' type, then we
+ // don't need to change again.
+ if (t->key != unsuitable_type)
+ {
+ t->key = unsuitable_type;
+ changed = true;
+ }
+ }
+ else
+ verify_fail ("unmergeable type");
+ }
+ return changed;
+}
+
+#ifdef VERIFY_DEBUG
+void
+print (void)
+{
+ char c = '?';
+ switch (key)
+ {
+ case boolean_type: c = 'Z'; break;
+ case byte_type: c = 'B'; break;
+ case char_type: c = 'C'; break;
+ case short_type: c = 'S'; break;
+ case int_type: c = 'I'; break;
+ case long_type: c = 'J'; break;
+ case float_type: c = 'F'; break;
+ case double_type: c = 'D'; break;
+ case void_type: c = 'V'; break;
+ case unsuitable_type: c = '-'; break;
+ case return_address_type: c = 'r'; break;
+ case continuation_type: c = '+'; break;
+ case reference_type: c = 'L'; break;
+ case null_type: c = '@'; break;
+ case uninitialized_reference_type: c = 'U'; break;
+ }
+ debug_print ("%c", c);
+}
+#endif /* VERIFY_DEBUG */
+
+// This class holds all the state information we need for a given
+// location.
+struct state
+{
+ // The current top of the stack, in terms of slots.
+ int stacktop;
+ // The current depth of the stack. This will be larger than
+ // STACKTOP when wide types are on the stack.
+ int stackdepth;
+ // The stack.
+ type *stack;
+ // The local variables.
+ type *locals;
+ // We keep track of the type of `this' specially. This is used to
+ // ensure that an instance initializer invokes another initializer
+ // on `this' before returning. We must keep track of this
+ // specially because otherwise we might be confused by code which
+ // assigns to locals[0] (overwriting `this') and then returns
+ // without really initializing.
+ type this_type;
+
+ // The PC for this state. This is only valid on states which are
+ // permanently attached to a given PC. For an object like
+ // `current_state', which is used transiently, this has no
+ // meaning.
+ int pc;
+ // We keep a linked list of all states requiring reverification.
+ // If this is the special value INVALID_STATE then this state is
+ // not on the list. NULL marks the end of the linked list.
+ state *next;
+};
+
+// NO_NEXT is the PC value meaning that a new state must be
+// acquired from the verification list.
+#define NO_NEXT -1
+
+#if 0
+static void
+init_state (state *s)
+{
+ s->stack = NULL;
+ s->locals = NULL;
+ s->next = INVALID_STATE;
+}
+#endif
+
+static void
+init_state_with_stack (state *s, int max_stack, int max_locals)
+{
+ int i;
+ s->stacktop = 0;
+ s->stackdepth = 0;
+ s->stack = (type *) vfy_alloc (max_stack * sizeof (type));
+ for (i = 0; i < max_stack; ++i)
+ init_type_from_tag (&s->stack[i], unsuitable_type);
+ s->locals = (type *) vfy_alloc (max_locals * sizeof (type));
+ for (i = 0; i < max_locals; ++i)
+ init_type_from_tag (&s->locals[i], unsuitable_type);
+ s->pc = NO_NEXT;
+ s->next = INVALID_STATE;
+}
+
+static void
+copy_state (state *s, state *copy, int max_stack, int max_locals)
+{
+ int i;
+ s->stacktop = copy->stacktop;
+ s->stackdepth = copy->stackdepth;
+ for (i = 0; i < max_stack; ++i)
+ s->stack[i] = copy->stack[i];
+ for (i = 0; i < max_locals; ++i)
+ s->locals[i] = copy->locals[i];
+
+ s->this_type = copy->this_type;
+ /* Don't modify `next' or `pc'. */
+}
+
+static void
+copy_state_with_stack (state *s, state *orig, int max_stack, int max_locals)
+{
+ init_state_with_stack (s, max_stack, max_locals);
+ copy_state (s, orig, max_stack, max_locals);
+}
+
+/* Allocate a new state, copying ORIG. */
+static state *
+make_state_copy (state *orig, int max_stack, int max_locals)
+{
+ state *s = vfy_alloc (sizeof (state));
+ copy_state_with_stack (s, orig, max_stack, max_locals);
+ return s;
+}
+
+static state *
+make_state (int max_stack, int max_locals)
+{
+ state *s = vfy_alloc (sizeof (state));
+ init_state_with_stack (s, max_stack, max_locals);
+ return s;
+}
+
+#if 0
+static void
+free_state (state *s)
+{
+ if (s->stack != NULL)
+ vfy_free (s->stack);
+ if (s->locals != NULL)
+ vfy_free (s->locals);
+}
+#endif
+
+#if 0
+ void *operator new[] (size_t bytes)
+ {
+ return vfy_alloc (bytes);
+ }
+
+ void operator delete[] (void *mem)
+ {
+ vfy_free (mem);
+ }
+
+ void *operator new (size_t bytes)
+ {
+ return vfy_alloc (bytes);
+ }
+
+ void operator delete (void *mem)
+ {
+ vfy_free (mem);
+ }
+#endif
+
+// Modify this state to reflect entry to an exception handler.
+static void
+state_set_exception (state *s, type *t, int max_stack)
+{
+ int i;
+ s->stackdepth = 1;
+ s->stacktop = 1;
+ s->stack[0] = *t;
+ for (i = s->stacktop; i < max_stack; ++i)
+ init_type_from_tag (&s->stack[i], unsuitable_type);
+}
+
+static int
+state_get_pc (state *s)
+{
+ return s->pc;
+}
+
+#if 0
+static void
+set_pc (state *s, int npc)
+{
+ s->pc = npc;
+}
+#endif
+
+// Merge STATE_OLD into this state. Destructively modifies this
+// state. Returns true if the new state was in fact changed.
+// Will throw an exception if the states are not mergeable.
+static bool
+merge_states (state *s, state *state_old, int max_locals)
+{
+ int i;
+ bool changed = false;
+
+ // Special handling for `this'. If one or the other is
+ // uninitialized, then the merge is uninitialized.
+ if (type_initialized (&s->this_type))
+ s->this_type = state_old->this_type;
+
+ // Merge stacks.
+ if (state_old->stacktop != s->stacktop) // FIXME stackdepth instead?
+ verify_fail ("stack sizes differ");
+ for (i = 0; i < state_old->stacktop; ++i)
+ {
+ if (merge_types (&s->stack[i], &state_old->stack[i], false))
+ changed = true;
+ }
+
+ // Merge local variables.
+ for (i = 0; i < max_locals; ++i)
+ {
+ if (merge_types (&s->locals[i], &state_old->locals[i], true))
+ changed = true;
+ }
+
+ return changed;
+}
+
+// Ensure that `this' has been initialized.
+static void
+state_check_this_initialized (state *s)
+{
+ if (type_isreference (&s->this_type) && ! type_initialized (&s->this_type))
+ verify_fail ("`this' is uninitialized");
+}
+
+// Throw an exception if there is an uninitialized object on the
+// stack or in a local variable. EXCEPTION_SEMANTICS controls
+// whether we're using backwards-branch or exception-handing
+// semantics.
+static void
+state_check_no_uninitialized_objects (state *s, int max_locals,
+ bool exception_semantics)
+{
+ int i;
+ if (! exception_semantics)
+ {
+ for (i = 0; i < s->stacktop; ++i)
+ if (type_isreference (&s->stack[i])
+ && ! type_initialized (&s->stack[i]))
+ verify_fail ("uninitialized object on stack");
+ }
+
+ for (i = 0; i < max_locals; ++i)
+ if (type_isreference (&s->locals[i])
+ && ! type_initialized (&s->locals[i]))
+ verify_fail ("uninitialized object in local variable");
+
+ state_check_this_initialized (s);
+}
+
+// Set type of `this'.
+static void
+state_set_this_type (state *s, type *k)
+{
+ s->this_type = *k;
+}
+
+// Mark each `new'd object we know of that was allocated at PC as
+// initialized.
+static void
+state_set_initialized (state *s, int pc, int max_locals)
+{
+ int i;
+ for (i = 0; i < s->stacktop; ++i)
+ type_set_initialized (&s->stack[i], pc);
+ for (i = 0; i < max_locals; ++i)
+ type_set_initialized (&s->locals[i], pc);
+ type_set_initialized (&s->this_type, pc);
+}
+
+// This tests to see whether two states can be considered "merge
+// compatible". If both states have a return-address in the same
+// slot, and the return addresses are different, then they are not
+// compatible and we must not try to merge them.
+static bool
+state_mergeable_p (state *s, state *other, int max_locals)
+
+{
+ int i;
+
+ // This is tricky: if the stack sizes differ, then not only are
+ // these not mergeable, but in fact we should give an error, as
+ // we've found two execution paths that reach a branch target
+ // with different stack depths. FIXME stackdepth instead?
+ if (s->stacktop != other->stacktop)
+ verify_fail ("stack sizes differ");
+
+ for (i = 0; i < s->stacktop; ++i)
+ if (! type_state_mergeable_p (&s->stack[i], &other->stack[i]))
+ return false;
+ for (i = 0; i < max_locals; ++i)
+ if (! type_state_mergeable_p (&s->locals[i], &other->locals[i]))
+ return false;
+ return true;
+}
+
+static void
+state_reverify (state *s)
+{
+ if (s->next == INVALID_STATE)
+ {
+ s->next = vfr->next_verify_state;
+ vfr->next_verify_state = s;
+ }
+}
+
+#ifdef VERIFY_DEBUG
+static void
+debug_print_state (state *s, const char *leader, int pc, int max_stack,
+ int max_locals)
+{
+ debug_print ("%s [%4d]: [stack] ", leader, pc);
+ int i;
+ for (i = 0; i < s->stacktop; ++i)
+ s->stack[i].print ();
+ for (; i < max_stack; ++i)
+ debug_print (".");
+ debug_print (" [local] ");
+ for (i = 0; i < max_locals; ++i)
+ s->locals[i].print ();
+ debug_print (" | %p\n", this);
+}
+#else
+static void
+debug_print_state (state *s ATTRIBUTE_UNUSED,
+ const char *leader ATTRIBUTE_UNUSED,
+ int pc ATTRIBUTE_UNUSED, int max_stack ATTRIBUTE_UNUSED,
+ int max_locals ATTRIBUTE_UNUSED)
+{
+}
+#endif /* VERIFY_DEBUG */
+
+static type
+pop_raw (void)
+{
+ state *s = vfr->current_state;
+ if (s->stacktop <= 0)
+ verify_fail ("stack empty");
+ type r = s->stack[--s->stacktop];
+ s->stackdepth -= type_depth (&r);
+ if (s->stackdepth < 0)
+ verify_fail_pc ("stack empty", vfr->start_PC);
+ return r;
+}
+
+static type
+pop32 (void)
+{
+ type r = pop_raw ();
+ if (type_iswide (&r))
+ verify_fail ("narrow pop of wide type");
+ return r;
+}
+
+static type
+vfy_pop_type_t (type match)
+{
+ vfy_promote_type (&match);
+ type t = pop_raw ();
+ if (! types_compatible (&match, &t))
+ verify_fail ("incompatible type on stack");
+ return t;
+}
+
+static type
+vfy_pop_type (type_val match)
+{
+ type t = make_type (match);
+ return vfy_pop_type_t (t);
+}
+
+#define pop_type vfy_pop_type
+#define pop_type_t vfy_pop_type_t
+
+// Pop a reference which is guaranteed to be initialized. MATCH
+// doesn't have to be a reference type; in this case this acts like
+// pop_type.
+static type
+pop_init_ref_t (type match)
+{
+ type t = pop_raw ();
+ if (type_isreference (&t) && ! type_initialized (&t))
+ verify_fail ("initialized reference required");
+ else if (! types_compatible (&match, &t))
+ verify_fail ("incompatible type on stack");
+ return t;
+}
+
+static type
+pop_init_ref (type_val match)
+{
+ type t = make_type (match);
+ return pop_init_ref_t (t);
+}
+
+// Pop a reference type or a return address.
+static type
+pop_ref_or_return (void)
+{
+ type t = pop_raw ();
+ if (! type_isreference (&t) && t.key != return_address_type)
+ verify_fail ("expected reference or return address on stack");
+ return t;
+}
+
+static void
+vfy_push_type_t (type t)
+{
+ state *s = vfr->current_state;
+ // If T is a numeric type like short, promote it to int.
+ promote_type (&t);
+
+ int depth = type_depth (&t);
+
+ if (s->stackdepth + depth > vfr->current_method->max_stack)
+ verify_fail ("stack overflow");
+ s->stack[s->stacktop++] = t;
+ s->stackdepth += depth;
+}
+
+static void
+vfy_push_type (type_val tval)
+{
+ type t = make_type (tval);
+ return vfy_push_type_t (t);
+}
+
+#define push_type vfy_push_type
+#define push_type_t vfy_push_type_t
+
+static void
+set_variable (int index, type t)
+{
+ state *s = vfr->current_state;
+ // If T is a numeric type like short, promote it to int.
+ promote_type (&t);
+
+ int depth = type_depth (&t);
+ if (index > vfr->current_method->max_locals - depth)
+ verify_fail ("invalid local variable");
+ s->locals[index] = t;
+
+ if (depth == 2)
+ init_type_from_tag (&s->locals[index + 1], continuation_type);
+ if (index > 0 && type_iswide (&s->locals[index - 1]))
+ init_type_from_tag (&s->locals[index - 1], unsuitable_type);
+}
+
+static type
+get_variable_t (int index, type *t)
+{
+ state *s = vfr->current_state;
+ int depth = type_depth (t);
+ if (index > vfr->current_method->max_locals - depth)
+ verify_fail ("invalid local variable");
+ if (! types_compatible (t, &s->locals[index]))
+ verify_fail ("incompatible type in local variable");
+ if (depth == 2)
+ {
+ type cont = make_type (continuation_type);
+ if (! types_compatible (&s->locals[index + 1], &cont))
+ verify_fail ("invalid local variable");
+ }
+ return s->locals[index];
+}
+
+static type
+get_variable (int index, type_val v)
+{
+ type t = make_type (v);
+ return get_variable_t (index, &t);
+}
+
+// Make sure ARRAY is an array type and that its elements are
+// compatible with type ELEMENT. Returns the actual element type.
+static type
+require_array_type_t (type array, type element)
+{
+ type t;
+ // An odd case. Here we just pretend that everything went ok. If
+ // the requested element type is some kind of reference, return
+ // the null type instead.
+ if (type_isnull (&array))
+ return type_isreference (&element) ? make_type (null_type) : element;
+
+ if (! type_isarray (&array))
+ verify_fail ("array required");
+
+ t = type_array_element (&array);
+ if (! types_compatible (&element, &t))
+ {
+ // Special case for byte arrays, which must also be boolean
+ // arrays.
+ bool ok = true;
+ if (element.key == byte_type)
+ {
+ type e2 = make_type (boolean_type);
+ ok = types_compatible (&e2, &t);
+ }
+ if (! ok)
+ verify_fail ("incompatible array element type");
+ }
+
+ // Return T and not ELEMENT, because T might be specialized.
+ return t;
+}
+
+static type
+require_array_type (type array, type_val element)
+{
+ type t = make_type (element);
+ return require_array_type_t (array, t);
+}
+
+static jint
+get_byte (void)
+{
+ if (vfr->PC >= vfr->current_method->code_length)
+ verify_fail ("premature end of bytecode");
+ return (jint) vfr->bytecode[vfr->PC++] & 0xff;
+}
+
+static jint
+get_ushort (void)
+{
+ jint b1 = get_byte ();
+ jint b2 = get_byte ();
+ return (jint) ((b1 << 8) | b2) & 0xffff;
+}
+
+static jint
+get_short (void)
+{
+ jint b1 = get_byte ();
+ jint b2 = get_byte ();
+ jshort s = (b1 << 8) | b2;
+ return (jint) s;
+}
+
+static jint
+get_int (void)
+{
+ jint b1 = get_byte ();
+ jint b2 = get_byte ();
+ jint b3 = get_byte ();
+ jint b4 = get_byte ();
+ return (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
+}
+
+static int
+compute_jump (int offset)
+{
+ int npc = vfr->start_PC + offset;
+ if (npc < 0 || npc >= vfr->current_method->code_length)
+ verify_fail_pc ("branch out of range", vfr->start_PC);
+ return npc;
+}
+
+// Add a new state to the state list at NPC.
+static state *
+add_new_state (int npc, state *old_state)
+{
+ vfy_method *current_method = vfr->current_method;
+ state *new_state = make_state_copy (old_state, current_method->max_stack,
+ current_method->max_locals);
+ debug_print ("== New state in add_new_state\n");
+ debug_print_state (new_state, "New", npc, current_method->max_stack,
+ current_method->max_locals);
+
+ state_list *nlink = vfy_alloc (sizeof (state_list));
+ nlink->val = new_state;
+ nlink->next = vfr->states[npc];
+ vfr->states[npc] = nlink;
+ new_state->pc = npc;
+ return new_state;
+}
+
+// Merge the indicated state into the state at the branch target and
+// schedule a new PC if there is a change. NPC is the PC of the
+// branch target, and FROM_STATE is the state at the source of the
+// branch. This method returns true if the destination state
+// changed and requires reverification, false otherwise.
+static void
+merge_into (int npc, state *from_state)
+{
+ // Iterate over all target states and merge our state into each,
+ // if applicable. FIXME one improvement we could make here is
+ // "state destruction". Merging a new state into an existing one
+ // might cause a return_address_type to be merged to
+ // unsuitable_type. In this case the resulting state may now be
+ // mergeable with other states currently held in parallel at this
+ // location. So in this situation we could pairwise compare and
+ // reduce the number of parallel states.
+ state_list *iter;
+ bool applicable = false;
+ for (iter = vfr->states[npc]; iter != NULL; iter = iter->next)
+ {
+ state *new_state = iter->val;
+ vfy_method *current_method = vfr->current_method;
+
+ if (state_mergeable_p (new_state, from_state,
+ current_method->max_locals))
+ {
+ applicable = true;
+
+ debug_print ("== Merge states in merge_into\n");
+ debug_print_state (from_state, "Frm", vfr->start_PC, current_method->max_stack,
+ current_method->max_locals);
+ debug_print_state (new_state, " To", npc, current_method->max_stack,
+ current_method->max_locals);
+ bool changed = merge_states (new_state, from_state,
+ current_method->max_locals);
+ debug_print_state (new_state, "New", npc, current_method->max_stack,
+ current_method->max_locals);
+
+ if (changed)
+ state_reverify (new_state);
+ }
+ }
+
+ if (! applicable)
+ {
+ // Either we don't yet have a state at NPC, or we have a
+ // return-address type that is in conflict with all existing
+ // state. So, we need to create a new entry.
+ state *new_state = add_new_state (npc, from_state);
+ // A new state added in this way must always be reverified.
+ state_reverify (new_state);
+ }
+}
+
+static void
+push_jump (int offset)
+{
+ int npc = compute_jump (offset);
+ if (npc < vfr->PC)
+ state_check_no_uninitialized_objects (vfr->current_state,
+ vfr->current_method->max_locals, false);
+ merge_into (npc, vfr->current_state);
+}
+
+static void
+push_exception_jump (type t, int pc)
+{
+ state s;
+ state_check_no_uninitialized_objects (vfr->current_state,
+ vfr->current_method->max_locals, true);
+ copy_state_with_stack (&s, vfr->current_state,
+ vfr->current_method->max_stack,
+ vfr->current_method->max_locals);
+ if (vfr->current_method->max_stack < 1)
+ verify_fail ("stack overflow at exception handler");
+ state_set_exception (&s, &t, vfr->current_method->max_stack);
+ merge_into (pc, &s);
+ /* FIXME: leak.. need free_state or GC */
+}
+
+static state *
+pop_jump (void)
+{
+ state *new_state = vfr->next_verify_state;
+ if (new_state == INVALID_STATE)
+ verify_fail ("programmer error in pop_jump");
+ if (new_state != NULL)
+ {
+ vfr->next_verify_state = new_state->next;
+ new_state->next = INVALID_STATE;
+ }
+ return new_state;
+}
+
+static void
+invalidate_pc (void)
+{
+ vfr->PC = NO_NEXT;
+}
+
+static void
+note_branch_target (int pc)
+{
+ // Don't check `pc <= PC', because we've advanced PC after
+ // fetching the target and we haven't yet checked the next
+ // instruction.
+ if (pc < vfr->PC && ! (vfr->flags[pc] & FLAG_INSN_START))
+ verify_fail_pc ("branch not to instruction start", vfr->start_PC);
+ vfr->flags[pc] |= FLAG_BRANCH_TARGET;
+}
+
+static void
+skip_padding (void)
+{
+ while ((vfr->PC % 4) > 0)
+ if (get_byte () != 0)
+ verify_fail ("found nonzero padding byte");
+}
+
+// Do the work for a `ret' instruction. INDEX is the index into the
+// local variables.
+static void
+handle_ret_insn (int index)
+{
+ type ret = make_type (return_address_type);
+ type ret_addr = get_variable_t (index, &ret);
+ // It would be nice if we could do this. However, the JVM Spec
+ // doesn't say that this is what happens. It is implied that
+ // reusing a return address is invalid, but there's no actual
+ // prohibition against it.
+ // set_variable (index, unsuitable_type);
+
+ int npc = type_get_pc (&ret_addr);
+ // We might be returning to a `jsr' that is at the end of the
+ // bytecode. This is ok if we never return from the called
+ // subroutine, but if we see this here it is an error.
+ if (npc >= vfr->current_method->code_length)
+ verify_fail ("fell off end");
+
+ if (npc < vfr->PC)
+ state_check_no_uninitialized_objects (vfr->current_state,
+ vfr->current_method->max_locals, false);
+ merge_into (npc, vfr->current_state);
+ invalidate_pc ();
+}
+
+static void handle_jsr_insn (int offset)
+{
+ int npc = compute_jump (offset);
+
+ if (npc < vfr->PC)
+ state_check_no_uninitialized_objects (vfr->current_state,
+ vfr->current_method->max_locals,
+ false);
+
+ // Modify our state as appropriate for entry into a subroutine.
+ type ret_addr = make_type (return_address_type);
+ type_set_return_address (&ret_addr, vfr->PC);
+ vfy_push_type_t (ret_addr);
+ merge_into (npc, vfr->current_state);
+ invalidate_pc ();
+}
+
+static vfy_jclass
+construct_primitive_array_type (type_val prim)
+{
+ vfy_jclass k = NULL;
+ switch (prim)
+ {
+ case boolean_type:
+ case char_type:
+ case float_type:
+ case double_type:
+ case byte_type:
+ case short_type:
+ case int_type:
+ case long_type:
+ k = vfy_get_primitive_type ((int) prim);
+ break;
+
+ // These aren't used here but we call them out to avoid
+ // warnings.
+ case void_type:
+ case unsuitable_type:
+ case return_address_type:
+ case continuation_type:
+ case reference_type:
+ case null_type:
+ case uninitialized_reference_type:
+ default:
+ verify_fail ("unknown type in construct_primitive_array_type");
+ }
+ k = vfy_get_array_class (k);
+ return k;
+}
+
+// This pass computes the location of branch targets and also
+// instruction starts.
+static void
+branch_prepass (void)
+{
+ int i, pc;
+ vfr->flags = (char *) vfy_alloc (vfr->current_method->code_length);
+
+ for (i = 0; i < vfr->current_method->code_length; ++i)
+ vfr->flags[i] = 0;
+
+ vfr->PC = 0;
+ while (vfr->PC < vfr->current_method->code_length)
+ {
+ // Set `start_PC' early so that error checking can have the
+ // correct value.
+ vfr->start_PC = vfr->PC;
+ vfr->flags[vfr->PC] |= FLAG_INSN_START;
+
+ java_opcode opcode = (java_opcode) vfr->bytecode[vfr->PC++];
+ switch (opcode)
+ {
+ case op_nop:
+ case op_aconst_null:
+ case op_iconst_m1:
+ case op_iconst_0:
+ case op_iconst_1:
+ case op_iconst_2:
+ case op_iconst_3:
+ case op_iconst_4:
+ case op_iconst_5:
+ case op_lconst_0:
+ case op_lconst_1:
+ case op_fconst_0:
+ case op_fconst_1:
+ case op_fconst_2:
+ case op_dconst_0:
+ case op_dconst_1:
+ case op_iload_0:
+ case op_iload_1:
+ case op_iload_2:
+ case op_iload_3:
+ case op_lload_0:
+ case op_lload_1:
+ case op_lload_2:
+ case op_lload_3:
+ case op_fload_0:
+ case op_fload_1:
+ case op_fload_2:
+ case op_fload_3:
+ case op_dload_0:
+ case op_dload_1:
+ case op_dload_2:
+ case op_dload_3:
+ case op_aload_0:
+ case op_aload_1:
+ case op_aload_2:
+ case op_aload_3:
+ case op_iaload:
+ case op_laload:
+ case op_faload:
+ case op_daload:
+ case op_aaload:
+ case op_baload:
+ case op_caload:
+ case op_saload:
+ case op_istore_0:
+ case op_istore_1:
+ case op_istore_2:
+ case op_istore_3:
+ case op_lstore_0:
+ case op_lstore_1:
+ case op_lstore_2:
+ case op_lstore_3:
+ case op_fstore_0:
+ case op_fstore_1:
+ case op_fstore_2:
+ case op_fstore_3:
+ case op_dstore_0:
+ case op_dstore_1:
+ case op_dstore_2:
+ case op_dstore_3:
+ case op_astore_0:
+ case op_astore_1:
+ case op_astore_2:
+ case op_astore_3:
+ case op_iastore:
+ case op_lastore:
+ case op_fastore:
+ case op_dastore:
+ case op_aastore:
+ case op_bastore:
+ case op_castore:
+ case op_sastore:
+ case op_pop:
+ case op_pop2:
+ case op_dup:
+ case op_dup_x1:
+ case op_dup_x2:
+ case op_dup2:
+ case op_dup2_x1:
+ case op_dup2_x2:
+ case op_swap:
+ case op_iadd:
+ case op_isub:
+ case op_imul:
+ case op_idiv:
+ case op_irem:
+ case op_ishl:
+ case op_ishr:
+ case op_iushr:
+ case op_iand:
+ case op_ior:
+ case op_ixor:
+ case op_ladd:
+ case op_lsub:
+ case op_lmul:
+ case op_ldiv:
+ case op_lrem:
+ case op_lshl:
+ case op_lshr:
+ case op_lushr:
+ case op_land:
+ case op_lor:
+ case op_lxor:
+ case op_fadd:
+ case op_fsub:
+ case op_fmul:
+ case op_fdiv:
+ case op_frem:
+ case op_dadd:
+ case op_dsub:
+ case op_dmul:
+ case op_ddiv:
+ case op_drem:
+ case op_ineg:
+ case op_i2b:
+ case op_i2c:
+ case op_i2s:
+ case op_lneg:
+ case op_fneg:
+ case op_dneg:
+ case op_i2l:
+ case op_i2f:
+ case op_i2d:
+ case op_l2i:
+ case op_l2f:
+ case op_l2d:
+ case op_f2i:
+ case op_f2l:
+ case op_f2d:
+ case op_d2i:
+ case op_d2l:
+ case op_d2f:
+ case op_lcmp:
+ case op_fcmpl:
+ case op_fcmpg:
+ case op_dcmpl:
+ case op_dcmpg:
+ case op_monitorenter:
+ case op_monitorexit:
+ case op_ireturn:
+ case op_lreturn:
+ case op_freturn:
+ case op_dreturn:
+ case op_areturn:
+ case op_return:
+ case op_athrow:
+ case op_arraylength:
+ break;
+
+ case op_bipush:
+ case op_ldc:
+ case op_iload:
+ case op_lload:
+ case op_fload:
+ case op_dload:
+ case op_aload:
+ case op_istore:
+ case op_lstore:
+ case op_fstore:
+ case op_dstore:
+ case op_astore:
+ case op_ret:
+ case op_newarray:
+ get_byte ();
+ break;
+
+ case op_iinc:
+ case op_sipush:
+ case op_ldc_w:
+ case op_ldc2_w:
+ case op_getstatic:
+ case op_getfield:
+ case op_putfield:
+ case op_putstatic:
+ case op_new:
+ case op_anewarray:
+ case op_instanceof:
+ case op_checkcast:
+ case op_invokespecial:
+ case op_invokestatic:
+ case op_invokevirtual:
+ get_short ();
+ break;
+
+ case op_multianewarray:
+ get_short ();
+ get_byte ();
+ break;
+
+ case op_jsr:
+ case op_ifeq:
+ case op_ifne:
+ case op_iflt:
+ case op_ifge:
+ case op_ifgt:
+ case op_ifle:
+ case op_if_icmpeq:
+ case op_if_icmpne:
+ case op_if_icmplt:
+ case op_if_icmpge:
+ case op_if_icmpgt:
+ case op_if_icmple:
+ case op_if_acmpeq:
+ case op_if_acmpne:
+ case op_ifnull:
+ case op_ifnonnull:
+ case op_goto:
+ note_branch_target (compute_jump (get_short ()));
+ break;
+
+ case op_tableswitch:
+ {
+ skip_padding ();
+ note_branch_target (compute_jump (get_int ()));
+ jint low = get_int ();
+ jint hi = get_int ();
+ if (low > hi)
+ verify_fail_pc ("invalid tableswitch", vfr->start_PC);
+ for (i = low; i <= hi; ++i)
+ note_branch_target (compute_jump (get_int ()));
+ }
+ break;
+
+ case op_lookupswitch:
+ {
+ skip_padding ();
+ note_branch_target (compute_jump (get_int ()));
+ int npairs = get_int ();
+ if (npairs < 0)
+ verify_fail_pc ("too few pairs in lookupswitch", vfr->start_PC);
+ while (npairs-- > 0)
+ {
+ get_int ();
+ note_branch_target (compute_jump (get_int ()));
+ }
+ }
+ break;
+
+ case op_invokeinterface:
+ get_short ();
+ get_byte ();
+ get_byte ();
+ break;
+
+ case op_wide:
+ {
+ opcode = (java_opcode) get_byte ();
+ get_short ();
+ if (opcode == op_iinc)
+ get_short ();
+ }
+ break;
+
+ case op_jsr_w:
+ case op_goto_w:
+ note_branch_target (compute_jump (get_int ()));
+ break;
+
+#if 0
+ // These are unused here, but we call them out explicitly
+ // so that -Wswitch-enum doesn't complain.
+ case op_putfield_1:
+ case op_putfield_2:
+ case op_putfield_4:
+ case op_putfield_8:
+ case op_putfield_a:
+ case op_putstatic_1:
+ case op_putstatic_2:
+ case op_putstatic_4:
+ case op_putstatic_8:
+ case op_putstatic_a:
+ case op_getfield_1:
+ case op_getfield_2s:
+ case op_getfield_2u:
+ case op_getfield_4:
+ case op_getfield_8:
+ case op_getfield_a:
+ case op_getstatic_1:
+ case op_getstatic_2s:
+ case op_getstatic_2u:
+ case op_getstatic_4:
+ case op_getstatic_8:
+ case op_getstatic_a:
+#endif // VFY_FAST_OPCODES
+ default:
+ verify_fail_pc ("unrecognized instruction in branch_prepass",
+ vfr->start_PC);
+ }
+
+ // See if any previous branch tried to branch to the middle of
+ // this instruction.
+ for (pc = vfr->start_PC + 1; pc < vfr->PC; ++pc)
+ {
+ if ((vfr->flags[pc] & FLAG_BRANCH_TARGET))
+ verify_fail_pc ("branch to middle of instruction", pc);
+ }
+ }
+
+ // Verify exception handlers.
+ for (i = 0; i < vfr->current_method->exc_count; ++i)
+ {
+ int handler, start, end, htype;
+ vfy_get_exception (vfr->exception, i, &handler, &start, &end, &htype);
+ if (! (vfr->flags[handler] & FLAG_INSN_START))
+ verify_fail_pc ("exception handler not at instruction start",
+ handler);
+ if (! (vfr->flags[start] & FLAG_INSN_START))
+ verify_fail_pc ("exception start not at instruction start", start);
+ if (end != vfr->current_method->code_length
+ && ! (vfr->flags[end] & FLAG_INSN_START))
+ verify_fail_pc ("exception end not at instruction start", end);
+
+ vfr->flags[handler] |= FLAG_BRANCH_TARGET;
+ }
+}
+
+static void
+check_pool_index (int index)
+{
+ if (index < 0 || index >= vfy_get_constants_size (vfr->current_class))
+ verify_fail_pc ("constant pool index out of range", vfr->start_PC);
+}
+
+static type
+check_class_constant (int index)
+{
+ type t;
+ check_pool_index (index);
+ vfy_constants *pool = vfy_get_constants (vfr->current_class);
+ if (vfy_tag (pool, index) == JV_CONSTANT_ResolvedClass)
+ init_type_from_class (&t, vfy_get_pool_class (pool, index));
+ else if (vfy_tag (pool, index) == JV_CONSTANT_Class)
+ init_type_from_string (&t, vfy_get_pool_string (pool, index));
+ else
+ verify_fail_pc ("expected class constant", vfr->start_PC);
+ return t;
+}
+
+static type
+check_constant (int index)
+{
+ type t;
+ check_pool_index (index);
+ vfy_constants *pool = vfy_get_constants (current_class);
+ if (vfy_tag (pool, index) == JV_CONSTANT_ResolvedString
+ || vfy_tag (pool, index) == JV_CONSTANT_String)
+ init_type_from_class (&t, vfy_string_type ());
+ else if (vfy_tag (pool, index) == JV_CONSTANT_Integer)
+ init_type_from_tag (&t, int_type);
+ else if (vfy_tag (pool, index) == JV_CONSTANT_Float)
+ init_type_from_tag (&t, float_type);
+ else
+ verify_fail_pc ("String, int, or float constant expected", vfr->start_PC);
+ return t;
+}
+
+static type
+check_wide_constant (int index)
+{
+ type t;
+ check_pool_index (index);
+ vfy_constants *pool = vfy_get_constants (current_class);
+ if (vfy_tag (pool, index) == JV_CONSTANT_Long)
+ init_type_from_tag (&t, long_type);
+ else if (vfy_tag (pool, index) == JV_CONSTANT_Double)
+ init_type_from_tag (&t, double_type);
+ else
+ verify_fail_pc ("long or double constant expected", vfr->start_PC);
+ return t;
+}
+
+// Helper for both field and method. These are laid out the same in
+// the constant pool.
+static type
+handle_field_or_method (int index, int expected,
+ vfy_string *name, vfy_string *fmtype)
+{
+ check_pool_index (index);
+ vfy_constants *pool = vfy_get_constants (current_class);
+ if (vfy_tag (pool, index) != expected)
+ verify_fail_pc ("didn't see expected constant", vfr->start_PC);
+ // Once we know we have a Fieldref or Methodref we assume that it
+ // is correctly laid out in the constant pool. I think the code
+ // in defineclass.cc guarantees this.
+ vfy_uint_16 class_index, name_and_type_index;
+ vfy_load_indexes (pool, index, &class_index, &name_and_type_index);
+ vfy_uint_16 name_index, desc_index;
+ vfy_load_indexes (pool, name_and_type_index, &name_index, &desc_index);
+
+ *name = vfy_get_pool_string (pool, name_index);
+ *fmtype = vfy_get_pool_string (pool, desc_index);
+
+ return check_class_constant (class_index);
+}
+
+// Return field's type, compute class' type if requested.
+static type
+check_field_constant (int index, type *class_type)
+{
+ vfy_string name, field_type;
+ const char *typec;
+ int len;
+ type t;
+
+ type ct = handle_field_or_method (index,
+ JV_CONSTANT_Fieldref,
+ &name, &field_type);
+ if (class_type)
+ *class_type = ct;
+ typec = vfy_string_bytes (field_type);
+ len = vfy_string_length (field_type);
+ if (typec[0] == '[' || typec[len - 1] == 'L')
+ init_type_from_string (&t, field_type);
+ else
+ init_type_from_tag (&t, get_type_val_for_signature (typec[0]));
+ return t;
+}
+
+static type
+check_method_constant (int index, bool is_interface,
+ vfy_string *method_name,
+ vfy_string *method_signature)
+{
+ return handle_field_or_method (index,
+ (is_interface
+ ? JV_CONSTANT_InterfaceMethodref
+ : JV_CONSTANT_Methodref),
+ method_name, method_signature);
+}
+
+static type
+get_one_type (const char *p)
+{
+ const char *start = p;
+
+ int arraycount = 0;
+ while (*p == '[')
+ {
+ ++arraycount;
+ ++p;
+ }
+
+ char v = *p++;
+
+ if (v == 'L')
+ {
+ while (*p != ';')
+ ++p;
+ ++p;
+ vfy_string name = vfy_get_string (start, p - start);
+ return make_type_from_string (name);
+ }
+
+ // Casting to jchar here is ok since we are looking at an ASCII
+ // character.
+ type_val rt = get_type_val_for_signature (v);
+
+ if (arraycount == 0)
+ {
+ // Callers of this function eventually push their arguments on
+ // the stack. So, promote them here.
+ type t = make_type (rt);
+ vfy_promote_type (&t);
+ return t;
+ }
+
+ vfy_jclass k = construct_primitive_array_type (rt);
+ while (--arraycount > 0)
+ k = vfy_get_array_class (k);
+ return make_type_from_class (k);
+}
+
+static void
+compute_argument_types (vfy_string signature, type *types)
+{
+ char *p = (char *) vfy_string_bytes (signature);
+
+ // Skip `('.
+ ++p;
+
+ int i = 0;
+ while (*p != ')')
+ types[i++] = get_one_type (p);
+}
+
+static type
+compute_return_type (vfy_string signature)
+{
+ char *p = (char *) vfy_string_bytes (signature);
+ while (*p != ')')
+ ++p;
+ ++p;
+ return get_one_type (p);
+}
+
+static void
+check_return_type (type onstack)
+{
+ type rt = compute_return_type (vfy_get_signature (vfr->current_method));
+ if (! types_compatible (&rt, &onstack))
+ verify_fail ("incompatible return type");
+}
+
+// Initialize the stack for the new method. Returns true if this
+// method is an instance initializer.
+static bool
+initialize_stack (void)
+{
+ int arg_count, i;
+ int var = 0;
+ bool is_init = vfy_strings_equal (vfy_get_method_name (vfr->current_method),
+ vfy_init_name());
+ bool is_clinit = vfy_strings_equal (vfy_get_method_name (vfr->current_method),
+ vfy_clinit_name());
+
+ if (! vfy_is_static (vfr->current_method))
+ {
+ type kurr = make_type_from_class (vfr->current_class);
+ if (is_init)
+ {
+ type_set_uninitialized (&kurr, SELF);
+ is_init = true;
+ }
+ else if (is_clinit)
+ verify_fail ("<clinit> method must be static");
+ set_variable (0, kurr);
+ state_set_this_type (vfr->current_state, &kurr);
+ ++var;
+ }
+ else
+ {
+ if (is_init)
+ verify_fail ("<init> method must be non-static");
+ }
+
+ // We have to handle wide arguments specially here.
+ arg_count = vfy_count_arguments (vfy_get_signature (vfr->current_method));
+ type arg_types[arg_count];
+ compute_argument_types (vfy_get_signature (vfr->current_method), arg_types);
+ for (i = 0; i < arg_count; ++i)
+ {
+ set_variable (var, arg_types[i]);
+ ++var;
+ if (type_iswide (&arg_types[i]))
+ ++var;
+ }
+
+ return is_init;
+}
+
+static void
+verify_instructions_0 (void)
+{
+ int i;
+
+ vfr->current_state = make_state (vfr->current_method->max_stack,
+ vfr->current_method->max_locals);
+
+ vfr->PC = 0;
+ vfr->start_PC = 0;
+
+ // True if we are verifying an instance initializer.
+ bool this_is_init = initialize_stack ();
+
+ vfr->states = (state_list **) vfy_alloc (sizeof (state_list *)
+ * vfr->current_method->code_length);
+
+ for (i = 0; i < vfr->current_method->code_length; ++i)
+ vfr->states[i] = NULL;
+
+ vfr->next_verify_state = NULL;
+
+ while (true)
+ {
+ // If the PC was invalidated, get a new one from the work list.
+ if (vfr->PC == NO_NEXT)
+ {
+ state *new_state = pop_jump ();
+ // If it is null, we're done.
+ if (new_state == NULL)
+ break;
+
+ vfr->PC = state_get_pc (new_state);
+ debug_print ("== State pop from pending list\n");
+ // Set up the current state.
+ copy_state (vfr->current_state, new_state,
+ vfr->current_method->max_stack, vfr->current_method->max_locals);
+ }
+ else
+ {
+ // We only have to do this checking in the situation where
+ // control flow falls through from the previous
+ // instruction. Otherwise merging is done at the time we
+ // push the branch.
+ if (vfr->states[vfr->PC] != NULL)
+ {
+ // We've already visited this instruction. So merge
+ // the states together. It is simplest, but not most
+ // efficient, to just always invalidate the PC here.
+ merge_into (vfr->PC, vfr->current_state);
+ invalidate_pc ();
+ continue;
+ }
+ }
+
+ // Control can't fall off the end of the bytecode. We need to
+ // check this in both cases, not just the fall-through case,
+ // because we don't check to see whether a `jsr' appears at
+ // the end of the bytecode until we process a `ret'.
+ if (vfr->PC >= vfr->current_method->code_length)
+ verify_fail ("fell off end");
+
+ // We only have to keep saved state at branch targets. If
+ // we're at a branch target and the state here hasn't been set
+ // yet, we set it now. You might notice that `ret' targets
+ // won't necessarily have FLAG_BRANCH_TARGET set. This
+ // doesn't matter, since those states will be filled in by
+ // merge_into.
+ if (vfr->states[vfr->PC] == NULL && (vfr->flags[vfr->PC] & FLAG_BRANCH_TARGET))
+ add_new_state (vfr->PC, vfr->current_state);
+
+ // Set this before handling exceptions so that debug output is
+ // sane.
+ vfr->start_PC = vfr->PC;
+
+ // Update states for all active exception handlers. Ordinarily
+ // there are not many exception handlers. So we simply run
+ // through them all.
+ for (i = 0; i < vfr->current_method->exc_count; ++i)
+ {
+ int hpc, start, end, htype;
+ vfy_get_exception (vfr->exception, i, &hpc, &start, &end, &htype);
+ if (vfr->PC >= start && vfr->PC < end)
+ {
+ type handler = make_type_from_class (vfy_throwable_type ());
+ if (htype != 0)
+ handler = check_class_constant (htype);
+ push_exception_jump (handler, hpc);
+ }
+ }
+
+
+ debug_print_state (vfr->current_state, " ", vfr->PC,
+ vfr->current_method->max_stack,
+ vfr->current_method->max_locals);
+ java_opcode opcode = (java_opcode) vfr->bytecode[vfr->PC++];
+ switch (opcode)
+ {
+ case op_nop:
+ break;
+
+ case op_aconst_null:
+ push_type (null_type);
+ break;
+
+ case op_iconst_m1:
+ case op_iconst_0:
+ case op_iconst_1:
+ case op_iconst_2:
+ case op_iconst_3:
+ case op_iconst_4:
+ case op_iconst_5:
+ push_type (int_type);
+ break;
+
+ case op_lconst_0:
+ case op_lconst_1:
+ push_type (long_type);
+ break;
+
+ case op_fconst_0:
+ case op_fconst_1:
+ case op_fconst_2:
+ push_type (float_type);
+ break;
+
+ case op_dconst_0:
+ case op_dconst_1:
+ push_type (double_type);
+ break;
+
+ case op_bipush:
+ get_byte ();
+ push_type (int_type);
+ break;
+
+ case op_sipush:
+ get_short ();
+ push_type (int_type);
+ break;
+
+ case op_ldc:
+ push_type_t (check_constant (get_byte ()));
+ break;
+ case op_ldc_w:
+ push_type_t (check_constant (get_ushort ()));
+ break;
+ case op_ldc2_w:
+ push_type_t (check_wide_constant (get_ushort ()));
+ break;
+
+ case op_iload:
+ push_type_t (get_variable (get_byte (), int_type));
+ break;
+ case op_lload:
+ push_type_t (get_variable (get_byte (), long_type));
+ break;
+ case op_fload:
+ push_type_t (get_variable (get_byte (), float_type));
+ break;
+ case op_dload:
+ push_type_t (get_variable (get_byte (), double_type));
+ break;
+ case op_aload:
+ push_type_t (get_variable (get_byte (), reference_type));
+ break;
+
+ case op_iload_0:
+ case op_iload_1:
+ case op_iload_2:
+ case op_iload_3:
+ push_type_t (get_variable (opcode - op_iload_0, int_type));
+ break;
+ case op_lload_0:
+ case op_lload_1:
+ case op_lload_2:
+ case op_lload_3:
+ push_type_t (get_variable (opcode - op_lload_0, long_type));
+ break;
+ case op_fload_0:
+ case op_fload_1:
+ case op_fload_2:
+ case op_fload_3:
+ push_type_t (get_variable (opcode - op_fload_0, float_type));
+ break;
+ case op_dload_0:
+ case op_dload_1:
+ case op_dload_2:
+ case op_dload_3:
+ push_type_t (get_variable (opcode - op_dload_0, double_type));
+ break;
+ case op_aload_0:
+ case op_aload_1:
+ case op_aload_2:
+ case op_aload_3:
+ push_type_t (get_variable (opcode - op_aload_0, reference_type));
+ break;
+ case op_iaload:
+ pop_type (int_type);
+ push_type_t (require_array_type (pop_init_ref (reference_type),
+ int_type));
+ break;
+ case op_laload:
+ pop_type (int_type);
+ push_type_t (require_array_type (pop_init_ref (reference_type),
+ long_type));
+ break;
+ case op_faload:
+ pop_type (int_type);
+ push_type_t (require_array_type (pop_init_ref (reference_type),
+ float_type));
+ break;
+ case op_daload:
+ pop_type (int_type);
+ push_type_t (require_array_type (pop_init_ref (reference_type),
+ double_type));
+ break;
+ case op_aaload:
+ pop_type (int_type);
+ push_type_t (require_array_type (pop_init_ref (reference_type),
+ reference_type));
+ break;
+ case op_baload:
+ pop_type (int_type);
+ require_array_type (pop_init_ref (reference_type), byte_type);
+ push_type (int_type);
+ break;
+ case op_caload:
+ pop_type (int_type);
+ require_array_type (pop_init_ref (reference_type), char_type);
+ push_type (int_type);
+ break;
+ case op_saload:
+ pop_type (int_type);
+ require_array_type (pop_init_ref (reference_type), short_type);
+ push_type (int_type);
+ break;
+ case op_istore:
+ set_variable (get_byte (), pop_type (int_type));
+ break;
+ case op_lstore:
+ set_variable (get_byte (), pop_type (long_type));
+ break;
+ case op_fstore:
+ set_variable (get_byte (), pop_type (float_type));
+ break;
+ case op_dstore:
+ set_variable (get_byte (), pop_type (double_type));
+ break;
+ case op_astore:
+ set_variable (get_byte (), pop_ref_or_return ());
+ break;
+ case op_istore_0:
+ case op_istore_1:
+ case op_istore_2:
+ case op_istore_3:
+ set_variable (opcode - op_istore_0, pop_type (int_type));
+ break;
+ case op_lstore_0:
+ case op_lstore_1:
+ case op_lstore_2:
+ case op_lstore_3:
+ set_variable (opcode - op_lstore_0, pop_type (long_type));
+ break;
+ case op_fstore_0:
+ case op_fstore_1:
+ case op_fstore_2:
+ case op_fstore_3:
+ set_variable (opcode - op_fstore_0, pop_type (float_type));
+ break;
+ case op_dstore_0:
+ case op_dstore_1:
+ case op_dstore_2:
+ case op_dstore_3:
+ set_variable (opcode - op_dstore_0, pop_type (double_type));
+ break;
+ case op_astore_0:
+ case op_astore_1:
+ case op_astore_2:
+ case op_astore_3:
+ set_variable (opcode - op_astore_0, pop_ref_or_return ());
+ break;
+ case op_iastore:
+ pop_type (int_type);
+ pop_type (int_type);
+ require_array_type (pop_init_ref (reference_type), int_type);
+ break;
+ case op_lastore:
+ pop_type (long_type);
+ pop_type (int_type);
+ require_array_type (pop_init_ref (reference_type), long_type);
+ break;
+ case op_fastore:
+ pop_type (float_type);
+ pop_type (int_type);
+ require_array_type (pop_init_ref (reference_type), float_type);
+ break;
+ case op_dastore:
+ pop_type (double_type);
+ pop_type (int_type);
+ require_array_type (pop_init_ref (reference_type), double_type);
+ break;
+ case op_aastore:
+ pop_type (reference_type);
+ pop_type (int_type);
+ require_array_type (pop_init_ref (reference_type), reference_type);
+ break;
+ case op_bastore:
+ pop_type (int_type);
+ pop_type (int_type);
+ require_array_type (pop_init_ref (reference_type), byte_type);
+ break;
+ case op_castore:
+ pop_type (int_type);
+ pop_type (int_type);
+ require_array_type (pop_init_ref (reference_type), char_type);
+ break;
+ case op_sastore:
+ pop_type (int_type);
+ pop_type (int_type);
+ require_array_type (pop_init_ref (reference_type), short_type);
+ break;
+ case op_pop:
+ pop32 ();
+ break;
+ case op_pop2:
+ {
+ type t = pop_raw ();
+ if (! type_iswide (&t))
+ pop32 ();
+ }
+ break;
+ case op_dup:
+ {
+ type t = pop32 ();
+ push_type_t (t);
+ push_type_t (t);
+ }
+ break;
+ case op_dup_x1:
+ {
+ type t1 = pop32 ();
+ type t2 = pop32 ();
+ push_type_t (t1);
+ push_type_t (t2);
+ push_type_t (t1);
+ }
+ break;
+ case op_dup_x2:
+ {
+ type t1 = pop32 ();
+ type t2 = pop_raw ();
+ if (! type_iswide (&t2))
+ {
+ type t3 = pop32 ();
+ push_type_t (t1);
+ push_type_t (t3);
+ }
+ else
+ push_type_t (t1);
+ push_type_t (t2);
+ push_type_t (t1);
+ }
+ break;
+ case op_dup2:
+ {
+ type t = pop_raw ();
+ if (! type_iswide (&t))
+ {
+ type t2 = pop32 ();
+ push_type_t (t2);
+ push_type_t (t);
+ push_type_t (t2);
+ }
+ else
+ push_type_t (t);
+ push_type_t (t);
+ }
+ break;
+ case op_dup2_x1:
+ {
+ type t1 = pop_raw ();
+ type t2 = pop32 ();
+ if (! type_iswide (&t1))
+ {
+ type t3 = pop32 ();
+ push_type_t (t2);
+ push_type_t (t1);
+ push_type_t (t3);
+ }
+ else
+ push_type_t (t1);
+ push_type_t (t2);
+ push_type_t (t1);
+ }
+ break;
+ case op_dup2_x2:
+ {
+ type t1 = pop_raw ();
+ if (type_iswide (&t1))
+ {
+ type t2 = pop_raw ();
+ if (type_iswide (&t2))
+ {
+ push_type_t (t1);
+ push_type_t (t2);
+ }
+ else
+ {
+ type t3 = pop32 ();
+ push_type_t (t1);
+ push_type_t (t3);
+ push_type_t (t2);
+ }
+ push_type_t (t1);
+ }
+ else
+ {
+ type t2 = pop32 ();
+ type t3 = pop_raw ();
+ if (type_iswide (&t3))
+ {
+ push_type_t (t2);
+ push_type_t (t1);
+ }
+ else
+ {
+ type t4 = pop32 ();
+ push_type_t (t2);
+ push_type_t (t1);
+ push_type_t (t4);
+ }
+ push_type_t (t3);
+ push_type_t (t2);
+ push_type_t (t1);
+ }
+ }
+ break;
+ case op_swap:
+ {
+ type t1 = pop32 ();
+ type t2 = pop32 ();
+ push_type_t (t1);
+ push_type_t (t2);
+ }
+ break;
+ case op_iadd:
+ case op_isub:
+ case op_imul:
+ case op_idiv:
+ case op_irem:
+ case op_ishl:
+ case op_ishr:
+ case op_iushr:
+ case op_iand:
+ case op_ior:
+ case op_ixor:
+ pop_type (int_type);
+ push_type_t (pop_type (int_type));
+ break;
+ case op_ladd:
+ case op_lsub:
+ case op_lmul:
+ case op_ldiv:
+ case op_lrem:
+ case op_land:
+ case op_lor:
+ case op_lxor:
+ pop_type (long_type);
+ push_type_t (pop_type (long_type));
+ break;
+ case op_lshl:
+ case op_lshr:
+ case op_lushr:
+ pop_type (int_type);
+ push_type_t (pop_type (long_type));
+ break;
+ case op_fadd:
+ case op_fsub:
+ case op_fmul:
+ case op_fdiv:
+ case op_frem:
+ pop_type (float_type);
+ push_type_t (pop_type (float_type));
+ break;
+ case op_dadd:
+ case op_dsub:
+ case op_dmul:
+ case op_ddiv:
+ case op_drem:
+ pop_type (double_type);
+ push_type_t (pop_type (double_type));
+ break;
+ case op_ineg:
+ case op_i2b:
+ case op_i2c:
+ case op_i2s:
+ push_type_t (pop_type (int_type));
+ break;
+ case op_lneg:
+ push_type_t (pop_type (long_type));
+ break;
+ case op_fneg:
+ push_type_t (pop_type (float_type));
+ break;
+ case op_dneg:
+ push_type_t (pop_type (double_type));
+ break;
+ case op_iinc:
+ get_variable (get_byte (), int_type);
+ get_byte ();
+ break;
+ case op_i2l:
+ pop_type (int_type);
+ push_type (long_type);
+ break;
+ case op_i2f:
+ pop_type (int_type);
+ push_type (float_type);
+ break;
+ case op_i2d:
+ pop_type (int_type);
+ push_type (double_type);
+ break;
+ case op_l2i:
+ pop_type (long_type);
+ push_type (int_type);
+ break;
+ case op_l2f:
+ pop_type (long_type);
+ push_type (float_type);
+ break;
+ case op_l2d:
+ pop_type (long_type);
+ push_type (double_type);
+ break;
+ case op_f2i:
+ pop_type (float_type);
+ push_type (int_type);
+ break;
+ case op_f2l:
+ pop_type (float_type);
+ push_type (long_type);
+ break;
+ case op_f2d:
+ pop_type (float_type);
+ push_type (double_type);
+ break;
+ case op_d2i:
+ pop_type (double_type);
+ push_type (int_type);
+ break;
+ case op_d2l:
+ pop_type (double_type);
+ push_type (long_type);
+ break;
+ case op_d2f:
+ pop_type (double_type);
+ push_type (float_type);
+ break;
+ case op_lcmp:
+ pop_type (long_type);
+ pop_type (long_type);
+ push_type (int_type);
+ break;
+ case op_fcmpl:
+ case op_fcmpg:
+ pop_type (float_type);
+ pop_type (float_type);
+ push_type (int_type);
+ break;
+ case op_dcmpl:
+ case op_dcmpg:
+ pop_type (double_type);
+ pop_type (double_type);
+ push_type (int_type);
+ break;
+ case op_ifeq:
+ case op_ifne:
+ case op_iflt:
+ case op_ifge:
+ case op_ifgt:
+ case op_ifle:
+ pop_type (int_type);
+ push_jump (get_short ());
+ break;
+ case op_if_icmpeq:
+ case op_if_icmpne:
+ case op_if_icmplt:
+ case op_if_icmpge:
+ case op_if_icmpgt:
+ case op_if_icmple:
+ pop_type (int_type);
+ pop_type (int_type);
+ push_jump (get_short ());
+ break;
+ case op_if_acmpeq:
+ case op_if_acmpne:
+ pop_type (reference_type);
+ pop_type (reference_type);
+ push_jump (get_short ());
+ break;
+ case op_goto:
+ push_jump (get_short ());
+ invalidate_pc ();
+ break;
+ case op_jsr:
+ handle_jsr_insn (get_short ());
+ break;
+ case op_ret:
+ handle_ret_insn (get_byte ());
+ break;
+ case op_tableswitch:
+ {
+ int i;
+ pop_type (int_type);
+ skip_padding ();
+ push_jump (get_int ());
+ jint low = get_int ();
+ jint high = get_int ();
+ // Already checked LOW -vs- HIGH.
+ for (i = low; i <= high; ++i)
+ push_jump (get_int ());
+ invalidate_pc ();
+ }
+ break;
+
+ case op_lookupswitch:
+ {
+ int i;
+ pop_type (int_type);
+ skip_padding ();
+ push_jump (get_int ());
+ jint npairs = get_int ();
+ // Already checked NPAIRS >= 0.
+ jint lastkey = 0;
+ for (i = 0; i < npairs; ++i)
+ {
+ jint key = get_int ();
+ if (i > 0 && key <= lastkey)
+ verify_fail_pc ("lookupswitch pairs unsorted", vfr->start_PC);
+ lastkey = key;
+ push_jump (get_int ());
+ }
+ invalidate_pc ();
+ }
+ break;
+ case op_ireturn:
+ check_return_type (pop_type (int_type));
+ invalidate_pc ();
+ break;
+ case op_lreturn:
+ check_return_type (pop_type (long_type));
+ invalidate_pc ();
+ break;
+ case op_freturn:
+ check_return_type (pop_type (float_type));
+ invalidate_pc ();
+ break;
+ case op_dreturn:
+ check_return_type (pop_type (double_type));
+ invalidate_pc ();
+ break;
+ case op_areturn:
+ check_return_type (pop_init_ref (reference_type));
+ invalidate_pc ();
+ break;
+ case op_return:
+ // We only need to check this when the return type is
+ // void, because all instance initializers return void.
+ if (this_is_init)
+ state_check_this_initialized (vfr->current_state);
+ check_return_type (make_type (void_type));
+ invalidate_pc ();
+ break;
+ case op_getstatic:
+ push_type_t (check_field_constant (get_ushort (), NULL));
+ break;
+ case op_putstatic:
+ pop_type_t (check_field_constant (get_ushort (), NULL));
+ break;
+ case op_getfield:
+ {
+ type klass;
+ type field = check_field_constant (get_ushort (), &klass);
+ pop_type_t (klass);
+ push_type_t (field);
+ }
+ break;
+ case op_putfield:
+ {
+ type klass;
+ type field = check_field_constant (get_ushort (), &klass);
+ pop_type_t (field);
+
+ // We have an obscure special case here: we can use
+ // `putfield' on a field declared in this class, even if
+ // `this' has not yet been initialized.
+ if (! type_initialized (&vfr->current_state->this_type)
+ && vfr->current_state->this_type.pc == SELF)
+ type_set_uninitialized (&klass, SELF);
+ pop_type_t (klass);
+ }
+ break;
+
+ case op_invokevirtual:
+ case op_invokespecial:
+ case op_invokestatic:
+ case op_invokeinterface:
+ {
+ vfy_string method_name, method_signature;
+ const char *namec;
+ int i;
+
+ type class_type
+ = check_method_constant (get_ushort (),
+ opcode == op_invokeinterface,
+ &method_name,
+ &method_signature);
+ // NARGS is only used when we're processing
+ // invokeinterface. It is simplest for us to compute it
+ // here and then verify it later.
+ int nargs = 0;
+ if (opcode == op_invokeinterface)
+ {
+ nargs = get_byte ();
+ if (get_byte () != 0)
+ verify_fail ("invokeinterface dummy byte is wrong");
+ }
+
+ bool is_init = false;
+ namec = vfy_string_bytes (method_name);
+
+ if (vfy_strings_equal (method_name, vfy_init_name()))
+ {
+ is_init = true;
+ if (opcode != op_invokespecial)
+ verify_fail ("can't invoke <init>");
+ }
+ else if (namec[0] == '<')
+ verify_fail ("can't invoke method starting with `<'");
+
+ // Pop arguments and check types.
+ int arg_count = vfy_count_arguments (method_signature);
+ type arg_types[arg_count];
+ compute_argument_types (method_signature, arg_types);
+ for (i = arg_count - 1; i >= 0; --i)
+ {
+ // This is only used for verifying the byte for
+ // invokeinterface.
+ nargs -= type_depth (&arg_types[i]);
+ pop_init_ref_t (arg_types[i]);
+ }
+
+ if (opcode == op_invokeinterface
+ && nargs != 1)
+ verify_fail ("wrong argument count for invokeinterface");
+
+ if (opcode != op_invokestatic)
+ {
+ type t = class_type;
+ if (is_init)
+ {
+ // In this case the PC doesn't matter.
+ type_set_uninitialized (&t, UNINIT);
+ // FIXME: check to make sure that the <init>
+ // call is to the right class.
+ // It must either be super or an exact class
+ // match.
+ }
+ type raw = pop_raw ();
+ if (! types_compatible (&t, &raw))
+ verify_fail ("incompatible type on stack");
+
+ if (is_init)
+ state_set_initialized (vfr->current_state,
+ type_get_pc (&raw), vfr->current_method->max_locals);
+ }
+
+ type rt = compute_return_type (method_signature);
+ if (! type_isvoid (&rt))
+ push_type_t (rt);
+ }
+ break;
+
+ case op_new:
+ {
+ type t = check_class_constant (get_ushort ());
+ if (type_isarray (&t) || type_isinterface (&t) \
+ || type_isabstract (&t))
+ verify_fail ("type is array, interface, or abstract");
+ type_set_uninitialized (&t, vfr->start_PC);
+ push_type_t (t);
+ }
+ break;
+
+ case op_newarray:
+ {
+ int atype = get_byte ();
+ type t;
+ // We intentionally have chosen constants to make this
+ // valid.
+ if (atype < boolean_type || atype > long_type)
+ verify_fail_pc ("type not primitive", vfr->start_PC);
+ pop_type (int_type);
+ init_type_from_class (&t, construct_primitive_array_type (atype));
+ push_type_t (t);
+ }
+ break;
+ case op_anewarray:
+ {
+ type t;
+ pop_type (int_type);
+ t = check_class_constant (get_ushort ());
+ push_type_t (type_to_array (&t));
+ }
+ break;
+ case op_arraylength:
+ {
+ type t = pop_init_ref (reference_type);
+ if (! type_isarray (&t) && ! type_isnull (&t))
+ verify_fail ("array type expected");
+ push_type (int_type);
+ }
+ break;
+ case op_athrow:
+ pop_type_t (make_type_from_class (vfy_throwable_type ()));
+ invalidate_pc ();
+ break;
+ case op_checkcast:
+ pop_init_ref (reference_type);
+ push_type_t (check_class_constant (get_ushort ()));
+ break;
+ case op_instanceof:
+ pop_init_ref (reference_type);
+ check_class_constant (get_ushort ());
+ push_type (int_type);
+ break;
+ case op_monitorenter:
+ pop_init_ref (reference_type);
+ break;
+ case op_monitorexit:
+ pop_init_ref (reference_type);
+ break;
+ case op_wide:
+ {
+ switch (get_byte ())
+ {
+ case op_iload:
+ push_type_t (get_variable (get_ushort (), int_type));
+ break;
+ case op_lload:
+ push_type_t (get_variable (get_ushort (), long_type));
+ break;
+ case op_fload:
+ push_type_t (get_variable (get_ushort (), float_type));
+ break;
+ case op_dload:
+ push_type_t (get_variable (get_ushort (), double_type));
+ break;
+ case op_aload:
+ push_type_t (get_variable (get_ushort (), reference_type));
+ break;
+ case op_istore:
+ set_variable (get_ushort (), pop_type (int_type));
+ break;
+ case op_lstore:
+ set_variable (get_ushort (), pop_type (long_type));
+ break;
+ case op_fstore:
+ set_variable (get_ushort (), pop_type (float_type));
+ break;
+ case op_dstore:
+ set_variable (get_ushort (), pop_type (double_type));
+ break;
+ case op_astore:
+ set_variable (get_ushort (), pop_init_ref (reference_type));
+ break;
+ case op_ret:
+ handle_ret_insn (get_short ());
+ break;
+ case op_iinc:
+ get_variable (get_ushort (), int_type);
+ get_short ();
+ break;
+ default:
+ verify_fail_pc ("unrecognized wide instruction", vfr->start_PC);
+ }
+ }
+ break;
+ case op_multianewarray:
+ {
+ int i;
+ type atype = check_class_constant (get_ushort ());
+ int dim = get_byte ();
+ if (dim < 1)
+ verify_fail_pc ("too few dimensions to multianewarray", vfr->start_PC);
+ type_verify_dimensions (&atype, dim);
+ for (i = 0; i < dim; ++i)
+ pop_type (int_type);
+ push_type_t (atype);
+ }
+ break;
+ case op_ifnull:
+ case op_ifnonnull:
+ pop_type (reference_type);
+ push_jump (get_short ());
+ break;
+ case op_goto_w:
+ push_jump (get_int ());
+ invalidate_pc ();
+ break;
+ case op_jsr_w:
+ handle_jsr_insn (get_int ());
+ break;
+
+#if 0
+ // These are unused here, but we call them out explicitly
+ // so that -Wswitch-enum doesn't complain.
+ case op_putfield_1:
+ case op_putfield_2:
+ case op_putfield_4:
+ case op_putfield_8:
+ case op_putfield_a:
+ case op_putstatic_1:
+ case op_putstatic_2:
+ case op_putstatic_4:
+ case op_putstatic_8:
+ case op_putstatic_a:
+ case op_getfield_1:
+ case op_getfield_2s:
+ case op_getfield_2u:
+ case op_getfield_4:
+ case op_getfield_8:
+ case op_getfield_a:
+ case op_getstatic_1:
+ case op_getstatic_2s:
+ case op_getstatic_2u:
+ case op_getstatic_4:
+ case op_getstatic_8:
+ case op_getstatic_a:
+#endif
+ default:
+ // Unrecognized opcode.
+ verify_fail_pc ("unrecognized instruction in verify_instructions_0",
+ vfr->start_PC);
+ }
+ }
+}
+
+static void verify_instructions (void)
+{
+ branch_prepass ();
+ verify_instructions_0 ();
+}
+
+#if 0
+_Jv_BytecodeVerifier (_Jv_InterpMethod *m)
+{
+ // We just print the text as utf-8. This is just for debugging
+ // anyway.
+ debug_print ("--------------------------------\n");
+ debug_print ("-- Verifying method `%s'\n", m->self->name->chars());
+
+ vfr->current_method = m;
+ bytecode = m->bytecode ();
+ exception = m->exceptions ();
+ vfr->current_class = m->defining_class;
+
+ vfr->states = NULL;
+ vfr->flags = NULL;
+ vfr->utf8_list = NULL;
+ vfr->isect_list = NULL;
+}
+
+~_Jv_BytecodeVerifier ()
+{
+ if (flags)
+ _Jv_Free (flags);
+
+ while (utf8_list != NULL)
+ {
+ linked<_Jv_Utf8Const> *n = utf8_list->next;
+ _Jv_Free (utf8_list);
+ utf8_list = n;
+ }
+
+ while (isect_list != NULL)
+ {
+ ref_intersection *next = isect_list->alloc_next;
+ delete isect_list;
+ isect_list = next;
+ }
+
+ if (vfr->states)
+ {
+ for (int i = 0; i < vfr->current_method->code_length; ++i)
+ {
+ linked<state *> *iter = vfr->states[i];
+ while (iter != NULL)
+ {
+ linked<state *> *next = iter->next;
+ delete iter->val;
+ vfy_free (iter);
+ iter = next;
+ }
+ }
+ vfy_free (states);
+ }
+}
+
+#endif
+
+int
+verify_method (vfy_method *meth ATTRIBUTE_UNUSED)
+{
+ /* static verifier initialization .. init type_int etc */
+
+ /* push_verifier_context () */
+ /* _Jv_BytecodeVerifier v (meth); */
+ /* init_verifier_context () */
+ verify_instructions ();
+ /* pop_verifier_context () */
+ return 0;
+}
diff --git a/gcc/java/verify.c b/gcc/java/verify.c
index abcdac8c4d8..3dd3b807a00 100644
--- a/gcc/java/verify.c
+++ b/gcc/java/verify.c
@@ -84,23 +84,23 @@ check_pending_block (tree target_label)
if (current_subr == NULL)
{
- if (LABEL_IN_SUBR (target_label))
- return "might transfer control into subroutine";
+/* if (LABEL_IN_SUBR (target_label)) */
+/* return "might transfer control into subroutine"; */
}
else
{
if (LABEL_IN_SUBR (target_label))
{
- if (LABEL_SUBR_START (target_label) != current_subr)
- return "transfer out of subroutine";
+/* if (LABEL_SUBR_START (target_label) != current_subr) */
+/* return "transfer out of subroutine"; */
}
else if (! LABEL_VERIFIED (target_label))
{
LABEL_IN_SUBR (target_label) = 1;
LABEL_SUBR_START (target_label) = current_subr;
}
- else
- return "transfer out of subroutine";
+/* else */
+/* return "transfer out of subroutine"; */
}
return NULL;
}
@@ -121,6 +121,54 @@ subroutine_nesting (tree label)
return nesting;
}
+static tree
+defer_merging (tree type1, tree type2)
+{
+ // FIXME: This is just a placeholder until we replace the verifier
+ // altogether. We really need to ouput a type assertion for all of
+ // the types, every time they are used.
+ return object_ptr_type_node;
+
+ if (TREE_CODE (type1) == POINTER_TYPE)
+ type1 = TREE_TYPE (type1);
+ if (TREE_CODE (type2) == POINTER_TYPE)
+ type2 = TREE_TYPE (type2);
+
+ if (TREE_CODE (type1) == RECORD_TYPE && TREE_CODE (type2) == RECORD_TYPE)
+ {
+ tree list = build_tree_list (type1, NULL_TREE);
+ list = tree_cons (type2, NULL_TREE, list);
+ return list;
+ }
+
+ if (TREE_CODE (type1) == TREE_LIST && TREE_CODE (type2) == TREE_LIST)
+ {
+ return chainon (copy_list (type1), copy_list (type2));
+ }
+
+ if (TREE_CODE (type1) == TREE_LIST && TREE_CODE (type2) == RECORD_TYPE)
+ {
+ tree tmp = type1;
+ do
+ {
+ if (TREE_PURPOSE (tmp) == type2)
+ return type1;
+ tmp = TREE_CHAIN (tmp);
+ }
+ while (tmp);
+
+ return tree_cons (type2, NULL_TREE, copy_list (type1));
+ }
+
+ if (TREE_CODE (type2) == TREE_LIST && TREE_CODE (type1) == RECORD_TYPE)
+ {
+ return defer_merging (type2, type1);
+ }
+
+ abort ();
+}
+
+
/* Return the "merged" types of TYPE1 and TYPE2.
If either is primitive, the other must match (after promotion to int).
For reference types, return the common super-class.
@@ -133,7 +181,11 @@ merge_types (tree type1, tree type2)
return type1;
if (type1 == TYPE_UNKNOWN || type2 == TYPE_UNKNOWN
|| type1 == TYPE_RETURN_ADDR || type2 == TYPE_RETURN_ADDR)
- return TYPE_UNKNOWN;
+ return TYPE_UNKNOWN;
+
+ if (TREE_CODE (type1) == TREE_LIST || TREE_CODE (type2) == TREE_LIST)
+ return defer_merging (type1, type2);
+
if (TREE_CODE (type1) == POINTER_TYPE && TREE_CODE (type2) == POINTER_TYPE)
{
int depth1, depth2;
@@ -148,6 +200,9 @@ merge_types (tree type1, tree type2)
tt1 = TREE_TYPE (type1);
tt2 = TREE_TYPE (type2);
+ if (TYPE_DUMMY (tt1) || TYPE_DUMMY (tt2))
+ return defer_merging (tt1, tt2);
+
/* If tt{1,2} haven't been properly loaded, now is a good time
to do it. */
if (!TYPE_SIZE (tt1))
@@ -188,31 +243,10 @@ merge_types (tree type1, tree type2)
return object_ptr_type_node;
}
- if (CLASS_INTERFACE (TYPE_NAME (tt1)))
- {
- /* FIXME: should see if two interfaces have a common
- superinterface. */
- if (CLASS_INTERFACE (TYPE_NAME (tt2)))
- {
- /* This is a kludge, but matches what Sun's verifier does.
- It can be tricked, but is safe as long as type errors
- (i.e. interface method calls) are caught at run-time. */
- return object_ptr_type_node;
- }
- else
- {
- if (can_widen_reference_to (tt2, tt1))
- return type1;
- else
- return object_ptr_type_node;
- }
- }
- else if (CLASS_INTERFACE (TYPE_NAME (tt2)))
+ if (CLASS_INTERFACE (TYPE_NAME (tt1))
+ || (CLASS_INTERFACE (TYPE_NAME (tt2))))
{
- if (can_widen_reference_to (tt1, tt2))
- return type2;
- else
- return object_ptr_type_node;
+ return object_ptr_type_node;
}
type1 = tt1;
@@ -650,6 +684,8 @@ verify_jvm_instructions (JCF* jcf, const unsigned char *byte_ops, long length)
VERIFICATION_ERROR_WITH_INDEX
("invalid local variable index %d in load");
tmp = type_map[index];
+ if (TREE_CODE (tmp) != TREE_LIST)
+ {
if (tmp == TYPE_UNKNOWN)
VERIFICATION_ERROR_WITH_INDEX
("loading local variable %d which has unknown type");
@@ -663,6 +699,7 @@ verify_jvm_instructions (JCF* jcf, const unsigned char *byte_ops, long length)
: type != tmp))
VERIFICATION_ERROR_WITH_INDEX
("loading local variable %d which has invalid type");
+ }
PUSH_TYPE (tmp);
goto note_used;
case OPCODE_istore: type = int_type_node; goto general_store;
@@ -709,8 +746,8 @@ verify_jvm_instructions (JCF* jcf, const unsigned char *byte_ops, long length)
/* If local variable changed, we need to reconsider eh handlers. */
prev_eh_ranges = NULL_EH_RANGE;
- /* Allocate decl and rtx for this variable now, so if we're not
- optimizing, we get a temporary that survives the whole method. */
+ /* Allocate decl for this variable now, so we get a temporary
+ that survives the whole method. */
find_local_variable (index, type, oldpc);
if (TYPE_IS_WIDE (type))
@@ -1023,6 +1060,11 @@ verify_jvm_instructions (JCF* jcf, const unsigned char *byte_ops, long length)
index));
if (! CLASS_LOADED_P (self_type))
load_class (self_type, 1);
+
+ if (TYPE_DUMMY (self_type) && op_code == OPCODE_invokeinterface)
+ /* Assume we are an interface. */
+ CLASS_INTERFACE (TYPE_NAME (self_type)) = 1;
+
self_is_interface = CLASS_INTERFACE (TYPE_NAME (self_type));
method_name = COMPONENT_REF_NAME (&current_jcf->cpool, index);
method_type = parse_signature_string (IDENTIFIER_POINTER (sig),
@@ -1057,6 +1099,7 @@ verify_jvm_instructions (JCF* jcf, const unsigned char *byte_ops, long length)
if (!nargs || notZero)
VERIFICATION_ERROR
("invalid argument number in invokeinterface");
+
/* If we verify/resolve the constant pool, as we should,
this test (and the one just following) are redundant. */
if (! self_is_interface)
diff --git a/gcc/java/verify.h b/gcc/java/verify.h
new file mode 100644
index 00000000000..0585c049249
--- /dev/null
+++ b/gcc/java/verify.h
@@ -0,0 +1,155 @@
+/* Declarations to interface gcj with bytecode verifier.
+ Copyright (C) 2003 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 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+
+Java and all Java-based marks are trademarks or registered trademarks
+of Sun Microsystems, Inc. in the United States and other countries.
+The Free Software Foundation is independent of Sun Microsystems, Inc. */
+
+/* Written by Tom Tromey <tromey@redhat.com>. */
+
+#ifndef GCC_VERIFY_H
+#define GCC_VERIFY_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "system.h"
+#include "coretypes.h"
+#include "jcf.h"
+#include "tree.h"
+#include "java-tree.h"
+
+#define VFY_IN_GCC
+#define VFY_WANT_TYPEMAP
+
+typedef JCF vfy_constants;
+
+/* For our purposes a string is the same as an identifier. */
+typedef tree vfy_string;
+
+/* The TYPE_DECL for a class or primitive type. */
+typedef tree vfy_jclass;
+
+/* An unsigned jshort. */
+typedef uint16 vfy_uint_16;
+
+typedef struct
+{
+ int handler, start, end, type;
+} vfy_exception;
+
+typedef struct
+{
+ tree method;
+ vfy_string signature;
+ vfy_string name;
+ const unsigned char *bytes;
+ vfy_exception *exceptions;
+
+ /* These fields are referred to directly by the verifier. */
+ vfy_jclass defining_class;
+ int max_stack;
+ int max_locals;
+ int code_length;
+ int exc_count;
+} vfy_method;
+
+/* Entry point to the verifier. */
+int verify_jvm_instructions_new (JCF *jcf, const unsigned char *byte_ops,
+ long length);
+
+void *vfy_alloc (size_t bytes);
+void vfy_free (void *mem);
+bool vfy_strings_equal (vfy_string one, vfy_string two);
+const char *vfy_string_bytes (vfy_string str);
+int vfy_string_length (vfy_string str);
+vfy_string vfy_get_string (const char *chars, int length);
+vfy_string vfy_init_name (void);
+vfy_string vfy_clinit_name (void);
+int vfy_count_arguments (vfy_string signature);
+vfy_string vfy_get_signature (vfy_method *method);
+vfy_string vfy_get_method_name (vfy_method *method);
+bool vfy_is_static (vfy_method *method);
+const unsigned char *vfy_get_bytecode (vfy_method *method);
+vfy_exception *vfy_get_exceptions (vfy_method *method);
+void vfy_get_exception (vfy_exception *, int index, int *handler,
+ int *start, int *end, int *handler_type);
+int vfy_tag (vfy_constants *pool, int index);
+void vfy_load_indexes (vfy_constants *pool, int index,
+ vfy_uint_16 *index0, vfy_uint_16 *index1);
+vfy_constants *vfy_get_constants (vfy_jclass klass);
+int vfy_get_constants_size (vfy_jclass klass);
+vfy_string vfy_get_pool_string (vfy_constants *pool, int index);
+vfy_jclass vfy_get_pool_class (vfy_constants *pool, int index);
+vfy_string vfy_make_string (const char *s, int len);
+vfy_string vfy_get_class_name (vfy_jclass klass);
+char vfy_get_primitive_char (vfy_jclass klass);
+int vfy_get_interface_count (vfy_jclass klass);
+vfy_jclass vfy_get_interface (vfy_jclass klass, int index);
+bool vfy_is_array (vfy_jclass klass);
+bool vfy_is_interface (vfy_jclass klass);
+bool vfy_is_primitive (vfy_jclass klass);
+vfy_jclass vfy_get_superclass (vfy_jclass klass);
+vfy_jclass vfy_get_array_class (vfy_jclass klass);
+vfy_jclass vfy_get_component_type (vfy_jclass klass);
+bool vfy_is_abstract (vfy_jclass klass);
+vfy_jclass vfy_find_class (vfy_jclass klass, vfy_string name);
+vfy_jclass vfy_object_type (void);
+vfy_jclass vfy_string_type (void);
+vfy_jclass vfy_throwable_type (void);
+int vfy_fail (const char *message, int pc, vfy_jclass ignore1, vfy_method *method);
+void vfy_notify_verified (int pc);
+vfy_jclass vfy_get_primitive_type (int type);
+void vfy_note_stack_depth (int pc, int depth);
+void vfy_note_type (int pc, int slot, vfy_jclass type);
+
+#define GLOM(name, stuff) name ## stuff
+#define VFY_PRIMITIVE_CLASS(name) \
+ vfy_get_primitive_type ((int) (GLOM (name, _type)))
+
+typedef enum
+{
+#define JAVAOP(name, num, ignore1, ignore2, ignore3) \
+ GLOM (op_, name) = num,
+#include "javaop.def"
+} java_opcode;
+
+
+#define JV_CONSTANT_Class CONSTANT_Class
+#define JV_CONSTANT_ResolvedClass CONSTANT_ResolvedClass
+#define JV_CONSTANT_String CONSTANT_String
+#define JV_CONSTANT_ResolvedString CONSTANT_ResolvedString
+#define JV_CONSTANT_Integer CONSTANT_Integer
+#define JV_CONSTANT_Float CONSTANT_Float
+#define JV_CONSTANT_Long CONSTANT_Long
+#define JV_CONSTANT_Double CONSTANT_Double
+#define JV_CONSTANT_Fieldref CONSTANT_Fieldref
+#define JV_CONSTANT_InterfaceMethodref CONSTANT_InterfaceMethodref
+#define JV_CONSTANT_Methodref CONSTANT_Methodref
+
+int verify_method (vfy_method *meth);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! GCC_VERIFY_H */
diff --git a/gcc/jump.c b/gcc/jump.c
index 643a714c7ad..2b46f7bc991 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -63,10 +63,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
or even change what is live at any point.
So perhaps let combiner do it. */
-static rtx next_nonnote_insn_in_loop (rtx);
static void init_label_info (rtx);
static void mark_all_labels (rtx);
-static int duplicate_loop_exit_test (rtx);
static void delete_computation (rtx);
static void redirect_exp_1 (rtx *, rtx, rtx, rtx);
static int redirect_exp (rtx, rtx, rtx);
@@ -122,55 +120,6 @@ cleanup_barriers (void)
}
}
}
-
-/* Return the next insn after INSN that is not a NOTE and is in the loop,
- i.e. when there is no such INSN before NOTE_INSN_LOOP_END return NULL_RTX.
- This routine does not look inside SEQUENCEs. */
-
-static rtx
-next_nonnote_insn_in_loop (rtx insn)
-{
- while (insn)
- {
- insn = NEXT_INSN (insn);
- if (insn == 0 || GET_CODE (insn) != NOTE)
- break;
- if (GET_CODE (insn) == NOTE
- && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
- return NULL_RTX;
- }
-
- return insn;
-}
-
-void
-copy_loop_headers (rtx f)
-{
- rtx insn, next;
- /* Now iterate optimizing jumps until nothing changes over one pass. */
- for (insn = f; insn; insn = next)
- {
- rtx temp, temp1;
-
- next = NEXT_INSN (insn);
-
- /* See if this is a NOTE_INSN_LOOP_BEG followed by an unconditional
- jump. Try to optimize by duplicating the loop exit test if so.
- This is only safe immediately after regscan, because it uses
- the values of regno_first_uid and regno_last_uid. */
- if (GET_CODE (insn) == NOTE
- && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
- && (temp1 = next_nonnote_insn_in_loop (insn)) != 0
- && any_uncondjump_p (temp1) && onlyjump_p (temp1))
- {
- temp = PREV_INSN (insn);
- if (duplicate_loop_exit_test (insn))
- {
- next = NEXT_INSN (temp);
- }
- }
- }
-}
void
purge_line_number_notes (rtx f)
@@ -287,245 +236,6 @@ mark_all_labels (rtx f)
}
}
}
-
-/* LOOP_START is a NOTE_INSN_LOOP_BEG note that is followed by an unconditional
- jump. Assume that this unconditional jump is to the exit test code. If
- the code is sufficiently simple, make a copy of it before INSN,
- followed by a jump to the exit of the loop. Then delete the unconditional
- jump after INSN.
-
- Return 1 if we made the change, else 0.
-
- This is only safe immediately after a regscan pass because it uses the
- values of regno_first_uid and regno_last_uid. */
-
-static int
-duplicate_loop_exit_test (rtx loop_start)
-{
- rtx insn, set, reg, p, link;
- rtx copy = 0, first_copy = 0;
- int num_insns = 0;
- rtx exitcode
- = NEXT_INSN (JUMP_LABEL (next_nonnote_insn_in_loop (loop_start)));
- rtx lastexit;
- int max_reg = max_reg_num ();
- rtx *reg_map = 0;
- rtx loop_pre_header_label;
-
- /* Scan the exit code. We do not perform this optimization if any insn:
-
- is a CALL_INSN
- is a CODE_LABEL
- has a REG_RETVAL or REG_LIBCALL note (hard to adjust)
- is a NOTE_INSN_LOOP_BEG because this means we have a nested loop
-
- We also do not do this if we find an insn with ASM_OPERANDS. While
- this restriction should not be necessary, copying an insn with
- ASM_OPERANDS can confuse asm_noperands in some cases.
-
- Also, don't do this if the exit code is more than 20 insns. */
-
- for (insn = exitcode;
- insn
- && ! (GET_CODE (insn) == NOTE
- && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END);
- insn = NEXT_INSN (insn))
- {
- switch (GET_CODE (insn))
- {
- case CODE_LABEL:
- case CALL_INSN:
- return 0;
- case NOTE:
-
- if (optimize < 2
- && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG
- || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END))
- /* If we were to duplicate this code, we would not move
- the BLOCK notes, and so debugging the moved code would
- be difficult. Thus, we only move the code with -O2 or
- higher. */
- return 0;
-
- break;
- case JUMP_INSN:
- case INSN:
- if (++num_insns > 20
- || find_reg_note (insn, REG_RETVAL, NULL_RTX)
- || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
- return 0;
- break;
- default:
- break;
- }
- }
-
- /* Unless INSN is zero, we can do the optimization. */
- if (insn == 0)
- return 0;
-
- lastexit = insn;
-
- /* See if any insn sets a register only used in the loop exit code and
- not a user variable. If so, replace it with a new register. */
- for (insn = exitcode; insn != lastexit; insn = NEXT_INSN (insn))
- if (GET_CODE (insn) == INSN
- && (set = single_set (insn)) != 0
- && ((reg = SET_DEST (set), GET_CODE (reg) == REG)
- || (GET_CODE (reg) == SUBREG
- && (reg = SUBREG_REG (reg), GET_CODE (reg) == REG)))
- && REGNO (reg) >= FIRST_PSEUDO_REGISTER
- && REGNO_FIRST_UID (REGNO (reg)) == INSN_UID (insn))
- {
- for (p = NEXT_INSN (insn); p != lastexit; p = NEXT_INSN (p))
- if (REGNO_LAST_UID (REGNO (reg)) == INSN_UID (p))
- break;
-
- if (p != lastexit)
- {
- /* We can do the replacement. Allocate reg_map if this is the
- first replacement we found. */
- if (reg_map == 0)
- reg_map = xcalloc (max_reg, sizeof (rtx));
-
- REG_LOOP_TEST_P (reg) = 1;
-
- reg_map[REGNO (reg)] = gen_reg_rtx (GET_MODE (reg));
- }
- }
- loop_pre_header_label = gen_label_rtx ();
-
- /* Now copy each insn. */
- for (insn = exitcode; insn != lastexit; insn = NEXT_INSN (insn))
- {
- switch (GET_CODE (insn))
- {
- case BARRIER:
- copy = emit_barrier_before (loop_start);
- break;
- case NOTE:
- /* Only copy line-number notes. */
- if (NOTE_LINE_NUMBER (insn) >= 0)
- {
- copy = emit_note_before (NOTE_LINE_NUMBER (insn), loop_start);
- NOTE_SOURCE_FILE (copy) = NOTE_SOURCE_FILE (insn);
- }
- break;
-
- case INSN:
- copy = emit_insn_before (copy_insn (PATTERN (insn)), loop_start);
- if (reg_map)
- replace_regs (PATTERN (copy), reg_map, max_reg, 1);
-
- mark_jump_label (PATTERN (copy), copy, 0);
- INSN_LOCATOR (copy) = INSN_LOCATOR (insn);
-
- /* Copy all REG_NOTES except REG_LABEL since mark_jump_label will
- make them. */
- for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
- if (REG_NOTE_KIND (link) != REG_LABEL)
- {
- if (GET_CODE (link) == EXPR_LIST)
- REG_NOTES (copy)
- = copy_insn_1 (gen_rtx_EXPR_LIST (REG_NOTE_KIND (link),
- XEXP (link, 0),
- REG_NOTES (copy)));
- else
- REG_NOTES (copy)
- = copy_insn_1 (gen_rtx_INSN_LIST (REG_NOTE_KIND (link),
- XEXP (link, 0),
- REG_NOTES (copy)));
- }
-
- if (reg_map && REG_NOTES (copy))
- replace_regs (REG_NOTES (copy), reg_map, max_reg, 1);
- break;
-
- case JUMP_INSN:
- copy = emit_jump_insn_before (copy_insn (PATTERN (insn)),
- loop_start);
- INSN_LOCATOR (copy) = INSN_LOCATOR (insn);
- if (reg_map)
- replace_regs (PATTERN (copy), reg_map, max_reg, 1);
- mark_jump_label (PATTERN (copy), copy, 0);
- if (REG_NOTES (insn))
- {
- REG_NOTES (copy) = copy_insn_1 (REG_NOTES (insn));
- if (reg_map)
- replace_regs (REG_NOTES (copy), reg_map, max_reg, 1);
- }
-
- /* Predict conditional jump that do make loop looping as taken.
- Other jumps are probably exit conditions, so predict
- them as untaken. */
- if (any_condjump_p (copy))
- {
- rtx label = JUMP_LABEL (copy);
- if (label)
- {
- /* The jump_insn after loop_start should be followed
- by barrier and loopback label. */
- if (prev_nonnote_insn (label)
- && (prev_nonnote_insn (prev_nonnote_insn (label))
- == next_nonnote_insn (loop_start)))
- {
- predict_insn_def (copy, PRED_LOOP_HEADER, TAKEN);
- /* To keep pre-header, we need to redirect all loop
- entrances before the LOOP_BEG note. */
- redirect_jump (copy, loop_pre_header_label, 0);
- }
- else
- predict_insn_def (copy, PRED_LOOP_HEADER, NOT_TAKEN);
- }
- }
- break;
-
- default:
- abort ();
- }
-
- /* Record the first insn we copied. We need it so that we can
- scan the copied insns for new pseudo registers. */
- if (! first_copy)
- first_copy = copy;
- }
-
- /* Now clean up by emitting a jump to the end label and deleting the jump
- at the start of the loop. */
- if (! copy || GET_CODE (copy) != BARRIER)
- {
- copy = emit_jump_insn_before (gen_jump (get_label_after (insn)),
- loop_start);
-
- /* Record the first insn we copied. We need it so that we can
- scan the copied insns for new pseudo registers. This may not
- be strictly necessary since we should have copied at least one
- insn above. But I am going to be safe. */
- if (! first_copy)
- first_copy = copy;
-
- mark_jump_label (PATTERN (copy), copy, 0);
- emit_barrier_before (loop_start);
- }
-
- emit_label_before (loop_pre_header_label, loop_start);
-
- /* Now scan from the first insn we copied to the last insn we copied
- (copy) for new pseudo registers. Do this after the code to jump to
- the end label since that might create a new pseudo too. */
- reg_scan_update (first_copy, copy, max_reg);
-
- /* Mark the exit code as the virtual top of the converted loop. */
- emit_note_before (NOTE_INSN_LOOP_VTOP, exitcode);
-
- delete_related_insns (next_nonnote_insn (loop_start));
-
- /* Clean up. */
- if (reg_map)
- free (reg_map);
-
- return 1;
-}
/* Move all block-beg, block-end, loop-beg, loop-cont, loop-vtop, loop-end,
notes between START and END out before START. START and END may be such
@@ -1143,6 +853,8 @@ any_uncondjump_p (rtx insn)
return 0;
if (GET_CODE (SET_SRC (x)) != LABEL_REF)
return 0;
+ if (find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX))
+ return 0;
return 1;
}
@@ -1827,75 +1539,6 @@ delete_for_peephole (rtx from, rtx to)
is also an unconditional jump in that case. */
}
-/* We have determined that AVOIDED_INSN is never reached, and are
- about to delete it. If the insn chain between AVOIDED_INSN and
- FINISH contains more than one line from the current function, and
- contains at least one operation, print a warning if the user asked
- for it. If FINISH is NULL, look between AVOIDED_INSN and a LABEL.
-
- CSE and inlining can duplicate insns, so it's possible to get
- spurious warnings from this. */
-
-void
-never_reached_warning (rtx avoided_insn, rtx finish)
-{
- rtx insn;
- rtx a_line_note = NULL;
- int two_avoided_lines = 0, contains_insn = 0, reached_end = 0;
-
- if (!warn_notreached)
- return;
-
- /* Back up to the first of any NOTEs preceding avoided_insn; flow passes
- us the head of a block, a NOTE_INSN_BASIC_BLOCK, which often follows
- the line note. */
- insn = avoided_insn;
- while (1)
- {
- rtx prev = PREV_INSN (insn);
- if (prev == NULL_RTX
- || GET_CODE (prev) != NOTE)
- break;
- insn = prev;
- }
-
- /* Scan forwards, looking at LINE_NUMBER notes, until we hit a LABEL
- in case FINISH is NULL, otherwise until we run out of insns. */
-
- for (; insn != NULL; insn = NEXT_INSN (insn))
- {
- if ((finish == NULL && GET_CODE (insn) == CODE_LABEL)
- || GET_CODE (insn) == BARRIER)
- break;
-
- if (GET_CODE (insn) == NOTE /* A line number note? */
- && NOTE_LINE_NUMBER (insn) >= 0)
- {
- if (a_line_note == NULL)
- a_line_note = insn;
- else
- two_avoided_lines |= (NOTE_LINE_NUMBER (a_line_note)
- != NOTE_LINE_NUMBER (insn));
- }
- else if (INSN_P (insn))
- {
- if (reached_end)
- break;
- contains_insn = 1;
- }
-
- if (insn == finish)
- reached_end = 1;
- }
- if (two_avoided_lines && contains_insn)
- {
- location_t locus;
- locus.file = NOTE_SOURCE_FILE (a_line_note);
- locus.line = NOTE_LINE_NUMBER (a_line_note);
- warning ("%Hwill never be executed", &locus);
- }
-}
-
/* Throughout LOC, redirect OLABEL to NLABEL. Treat null OLABEL or
NLABEL as a return. Accrue modifications into the change group. */
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index 5af66da7223..594103e1292 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -55,7 +55,9 @@ extern int lhd_unsafe_for_reeval (tree);
extern void lhd_clear_binding_stack (void);
extern void lhd_print_tree_nothing (FILE *, tree, int);
extern const char *lhd_decl_printable_name (tree, int);
+extern int lhd_types_compatible_p (tree, tree);
extern rtx lhd_expand_expr (tree, rtx, enum machine_mode, int, rtx *);
+extern int lhd_expand_decl (tree);
extern void lhd_print_error_function (struct diagnostic_context *,
const char *);
extern void lhd_set_decl_assembler_name (tree);
@@ -88,6 +90,9 @@ extern void lhd_initialize_diagnostics (struct diagnostic_context *);
extern tree lhd_callgraph_analyze_expr (tree *, int *, tree);
+/* Declarations for tree gimplification hooks. */
+extern int lhd_gimplify_expr (tree *, tree *, tree *);
+
#define LANG_HOOKS_NAME "GNU unknown"
#define LANG_HOOKS_IDENTIFIER_SIZE sizeof (struct lang_identifier)
#define LANG_HOOKS_INIT hook_bool_void_false
@@ -102,6 +107,7 @@ extern tree lhd_callgraph_analyze_expr (tree *, int *, tree);
#define LANG_HOOKS_GET_ALIAS_SET lhd_get_alias_set
#define LANG_HOOKS_EXPAND_CONSTANT lhd_return_tree
#define LANG_HOOKS_EXPAND_EXPR lhd_expand_expr
+#define LANG_HOOKS_EXPAND_DECL lhd_expand_decl
#define LANG_HOOKS_SAFE_FROM_P lhd_safe_from_p
#define LANG_HOOKS_FINISH_INCOMPLETE_DECL lhd_do_nothing_t
#define LANG_HOOKS_UNSAFE_FOR_REEVAL lhd_unsafe_for_reeval
@@ -122,18 +128,15 @@ extern tree lhd_callgraph_analyze_expr (tree *, int *, tree);
#define LANG_HOOKS_DECL_PRINTABLE_NAME lhd_decl_printable_name
#define LANG_HOOKS_GET_CALLEE_FNDECL lhd_return_null_tree
#define LANG_HOOKS_EXPR_SIZE lhd_expr_size
-#define LANG_HOOKS_DECL_UNINIT lhd_decl_uninit
#define LANG_HOOKS_TREE_SIZE lhd_tree_size
+#define LANG_HOOKS_TYPES_COMPATIBLE_P lhd_types_compatible_p
#define LANG_HOOKS_UPDATE_DECL_AFTER_SAVING NULL
#define LANG_HOOKS_FUNCTION_INIT lhd_do_nothing_f
#define LANG_HOOKS_FUNCTION_FINAL lhd_do_nothing_f
#define LANG_HOOKS_FUNCTION_ENTER_NESTED lhd_do_nothing_f
#define LANG_HOOKS_FUNCTION_LEAVE_NESTED lhd_do_nothing_f
-
-#define LANG_HOOKS_RTL_EXPAND_START lhd_do_nothing
-#define LANG_HOOKS_RTL_EXPAND_STMT (void (*) (tree)) abort
-#define LANG_HOOKS_RTL_EXPAND_END lhd_do_nothing
+#define LANG_HOOKS_FUNCTION_MISSING_NORETURN_OK_P hook_bool_tree_true
/* Attribute hooks. */
#define LANG_HOOKS_ATTRIBUTE_TABLE NULL
@@ -195,14 +198,13 @@ extern tree lhd_callgraph_analyze_expr (tree *, int *, tree);
LANG_HOOKS_FUNCTION_INIT, \
LANG_HOOKS_FUNCTION_FINAL, \
LANG_HOOKS_FUNCTION_ENTER_NESTED, \
- LANG_HOOKS_FUNCTION_LEAVE_NESTED \
+ LANG_HOOKS_FUNCTION_LEAVE_NESTED, \
+ LANG_HOOKS_FUNCTION_MISSING_NORETURN_OK_P \
}
-#define LANG_HOOKS_RTL_EXPAND_INITIALIZER { \
- LANG_HOOKS_RTL_EXPAND_START, \
- LANG_HOOKS_RTL_EXPAND_STMT, \
- LANG_HOOKS_RTL_EXPAND_END \
-}
+/* Hooks for tree gimplification. */
+#define LANG_HOOKS_GIMPLIFY_EXPR lhd_gimplify_expr
+#define LANG_HOOKS_GIMPLE_BEFORE_INLINING true
/* Tree dump hooks. */
extern bool lhd_tree_dump_dump_tree (void *, tree);
@@ -282,6 +284,7 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_GET_ALIAS_SET, \
LANG_HOOKS_EXPAND_CONSTANT, \
LANG_HOOKS_EXPAND_EXPR, \
+ LANG_HOOKS_EXPAND_DECL, \
LANG_HOOKS_TRUTHVALUE_CONVERSION, \
LANG_HOOKS_SAFE_FROM_P, \
LANG_HOOKS_FINISH_INCOMPLETE_DECL, \
@@ -301,10 +304,10 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_PRINT_TYPE, \
LANG_HOOKS_PRINT_IDENTIFIER, \
LANG_HOOKS_DECL_PRINTABLE_NAME, \
+ LANG_HOOKS_TYPES_COMPATIBLE_P, \
LANG_HOOKS_GET_CALLEE_FNDECL, \
LANG_HOOKS_PRINT_ERROR_FUNCTION, \
LANG_HOOKS_EXPR_SIZE, \
- LANG_HOOKS_DECL_UNINIT, \
LANG_HOOKS_UPDATE_DECL_AFTER_SAVING, \
LANG_HOOKS_ATTRIBUTE_TABLE, \
LANG_HOOKS_COMMON_ATTRIBUTE_TABLE, \
@@ -315,7 +318,8 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_TREE_DUMP_INITIALIZER, \
LANG_HOOKS_DECLS, \
LANG_HOOKS_FOR_TYPES_INITIALIZER, \
- LANG_HOOKS_RTL_EXPAND_INITIALIZER \
+ LANG_HOOKS_GIMPLIFY_EXPR, \
+ LANG_HOOKS_GIMPLE_BEFORE_INLINING \
}
#endif /* GCC_LANG_HOOKS_DEF_H */
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 3e15a359333..c82b5fd4f3f 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -26,6 +26,7 @@ Boston, MA 02111-1307, USA. */
#include "toplev.h"
#include "tree.h"
#include "tree-inline.h"
+#include "tree-gimple.h"
#include "rtl.h"
#include "insn-config.h"
#include "integrate.h"
@@ -272,6 +273,19 @@ lhd_expand_expr (tree t ATTRIBUTE_UNUSED, rtx r ATTRIBUTE_UNUSED,
abort ();
}
+/* This is the default expand_decl function. */
+/* The default language-specific function for expanding a DECL_STMT. After
+ the language-independent cases are handled, this function will be
+ called. If this function is not defined, it is assumed that
+ declarations other than those for variables and labels do not require
+ any RTL generation. */
+
+int
+lhd_expand_decl (tree t ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
/* This is the default decl_printable_name function. */
const char *
@@ -280,6 +294,16 @@ lhd_decl_printable_name (tree decl, int verbosity ATTRIBUTE_UNUSED)
return IDENTIFIER_POINTER (DECL_NAME (decl));
}
+/* This compares two types for equivalence ("compatible" in C-based languages).
+ This routine should only return 1 if it is sure. It should not be used
+ in contexts where erroneously returning 0 causes problems. */
+
+int
+lhd_types_compatible_p (tree x, tree y)
+{
+ return TYPE_MAIN_VARIANT (x) == TYPE_MAIN_VARIANT (y);
+}
+
/* lang_hooks.tree_inlining.walk_subtrees is called by walk_tree()
after handling common cases, but before walking code-specific
sub-trees. If this hook is overridden for a language, it should
@@ -458,13 +482,14 @@ lhd_expr_size (tree exp)
else
return size_in_bytes (TREE_TYPE (exp));
}
-/* lang_hooks.decl_uninit: Find out if a variable is uninitialized based
- on DECL_INITIAL. */
-bool
-lhd_decl_uninit (tree t ATTRIBUTE_UNUSED)
+/* lang_hooks.gimplify_expr re-writes *EXPR_P into GIMPLE form. */
+
+int
+lhd_gimplify_expr (tree *expr_p ATTRIBUTE_UNUSED, tree *pre_p ATTRIBUTE_UNUSED,
+ tree *post_p ATTRIBUTE_UNUSED)
{
- return false;
+ return GS_UNHANDLED;
}
/* lang_hooks.tree_size: Determine the size of a tree with code C,
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index 8ad1c477575..92bf00b61c2 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -76,19 +76,9 @@ struct lang_hooks_for_functions
/* Called when leaving a nested function. */
void (*leave_nested) (struct function *);
-};
-
-/* Lang hooks for rtl code generation. */
-struct lang_hooks_for_rtl_expansion
-{
- /* Called after expand_function_start, but before expanding the body. */
- void (*start) (void);
-
- /* Called to expand each statement. */
- void (*stmt) (tree);
- /* Called after expanding the body but before expand_function_end. */
- void (*end) (void);
+ /* Determines if it's ok for a function to have no noreturn attribute. */
+ bool (*missing_noreturn_ok_p) (tree);
};
/* The following hooks are used by tree-dump.c. */
@@ -287,6 +277,10 @@ struct lang_hooks
Fourth argument is actually an enum expand_modifier. */
rtx (*expand_expr) (tree, rtx, enum machine_mode, int, rtx *);
+ /* Called by expand_expr to generate the definition of a decl. Returns
+ 1 if handled, 0 otherwise. */
+ int (*expand_decl) (tree);
+
/* Prepare expr to be an argument of a TRUTH_NOT_EXPR or other logical
operation.
@@ -380,6 +374,11 @@ struct lang_hooks
types in C++. */
const char *(*decl_printable_name) (tree decl, int verbosity);
+ /* This compares two types for equivalence ("compatible" in C-based languages).
+ This routine should only return 1 if it is sure. It should not be used
+ in contexts where erroneously returning 0 causes problems. */
+ int (*types_compatible_p) (tree x, tree y);
+
/* Given a CALL_EXPR, return a function decl that is its target. */
tree (*lang_get_callee_fndecl) (tree);
@@ -392,10 +391,6 @@ struct lang_hooks
semantics in cases that it doesn't want to handle specially. */
tree (*expr_size) (tree);
- /* Called from uninitialized_vars_warning to find out if a variable is
- uninitialized based on DECL_INITIAL. */
- bool (*decl_uninit) (tree);
-
/* Update lang specific fields after duplicating function body. */
void (*update_decl_after_saving) (tree, void *);
@@ -421,7 +416,13 @@ struct lang_hooks
struct lang_hooks_for_types types;
- struct lang_hooks_for_rtl_expansion rtl_expand;
+ /* Perform language-specific gimplification on the argument. Returns an
+ enum gimplify_status, though we can't see that type here. */
+ int (*gimplify_expr) (tree *, tree *, tree *);
+
+ /* True if the front end has gimplified the function before running the
+ inliner, false if the front end generates GENERIC directly. */
+ bool gimple_before_inlining;
/* Whenever you add entries here, make sure you adjust langhooks-def.h
and langhooks.c accordingly. */
diff --git a/gcc/libada-mk.in b/gcc/libada-mk.in
new file mode 100644
index 00000000000..2dd85c9fd54
--- /dev/null
+++ b/gcc/libada-mk.in
@@ -0,0 +1,34 @@
+# Copyright 2004 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 2, or (at your option)
+#any later version.
+
+#GCC is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+#GNU General Public License for more details.
+
+#You should have received a copy of the GNU General Public License
+#along with GCC; see the file COPYING. If not, write to
+#the Free Software Foundation, 59 Temple Place - Suite 330,
+#Boston MA 02111-1307, USA.
+
+# GCC's Makefile fragment for libada.
+# libada needs some information from the GCC configure file at the moment,
+# and this exists to transfer that information in as clean a way as possible.
+
+exeext=@host_exeext@
+libdir=@libdir@
+gcc_version=@gcc_version@
+NOCOMMON_FLAG=@nocommon_flag@
+WARN_CFLAGS=@warn_cflags@
+cc_set_by_configure=@cc_set_by_configure@
+gcc_tmake_file=@tmake_file@
+gcc_xmake_file=@xmake_file@
+
+# This really shouldn't be needed, but for now...
+CC=@CC@
diff --git a/gcc/libgcov.c b/gcc/libgcov.c
index d3345024bcb..0731ed01e5f 100644
--- a/gcc/libgcov.c
+++ b/gcc/libgcov.c
@@ -580,4 +580,146 @@ __gcov_merge_delta (gcov_type *counters, unsigned n_counters)
}
#endif /* L_gcov_merge_delta */
+#ifdef L_gcov_fork
+/* A wrapper for the fork function. Flushes the accumulated profiling data, so
+ that they are not counted twice. */
+
+pid_t
+__gcov_fork (void)
+{
+ __gcov_flush ();
+ return fork ();
+}
+#endif
+
+#ifdef L_gcov_execl
+/* A wrapper for the execl function. Flushes the accumulated profiling data, so
+ that they are not lost. */
+
+int
+__gcov_execl (const char *path, const char *arg, ...)
+{
+ va_list ap, aq;
+ unsigned i, length;
+ char **args;
+
+ __gcov_flush ();
+
+ va_start (ap, arg);
+ va_copy (aq, ap);
+
+ length = 2;
+ while (va_arg (ap, char *))
+ length++;
+ va_end (ap);
+
+ args = alloca (length * sizeof (void *));
+ args[0] = (char *) arg;
+ for (i = 1; i < length; i++)
+ args[i] = va_arg (aq, char *);
+ va_end (aq);
+
+ return execv (path, args);
+}
+#endif
+
+#ifdef L_gcov_execlp
+/* A wrapper for the execlp function. Flushes the accumulated profiling data, so
+ that they are not lost. */
+
+int
+__gcov_execlp (const char *path, const char *arg, ...)
+{
+ va_list ap, aq;
+ unsigned i, length;
+ char **args;
+
+ __gcov_flush ();
+
+ va_start (ap, arg);
+ va_copy (aq, ap);
+
+ length = 2;
+ while (va_arg (ap, char *))
+ length++;
+ va_end (ap);
+
+ args = alloca (length * sizeof (void *));
+ args[0] = (char *) arg;
+ for (i = 1; i < length; i++)
+ args[i] = va_arg (aq, char *);
+ va_end (aq);
+
+ return execvp (path, args);
+}
+#endif
+
+#ifdef L_gcov_execle
+/* A wrapper for the execle function. Flushes the accumulated profiling data, so
+ that they are not lost. */
+
+int
+__gcov_execle (const char *path, const char *arg, ...)
+{
+ va_list ap, aq;
+ unsigned i, length;
+ char **args;
+ char **envp;
+
+ __gcov_flush ();
+
+ va_start (ap, arg);
+ va_copy (aq, ap);
+
+ length = 2;
+ while (va_arg (ap, char *))
+ length++;
+ va_end (ap);
+
+ args = alloca (length * sizeof (void *));
+ args[0] = (char *) arg;
+ for (i = 1; i < length; i++)
+ args[i] = va_arg (aq, char *);
+ envp = va_arg (aq, char **);
+ va_end (aq);
+
+ return execve (path, args, envp);
+}
+#endif
+
+#ifdef L_gcov_execv
+/* A wrapper for the execv function. Flushes the accumulated profiling data, so
+ that they are not lost. */
+
+int
+__gcov_execv (const char *path, char *const argv[])
+{
+ __gcov_flush ();
+ return execv (path, argv);
+}
+#endif
+
+#ifdef L_gcov_execvp
+/* A wrapper for the execvp function. Flushes the accumulated profiling data, so
+ that they are not lost. */
+
+int
+__gcov_execvp (const char *path, char *const argv[])
+{
+ __gcov_flush ();
+ return execvp (path, argv);
+}
+#endif
+
+#ifdef L_gcov_execve
+/* A wrapper for the execve function. Flushes the accumulated profiling data, so
+ that they are not lost. */
+
+int
+__gcov_execve (const char *path, char *const argv[], char *const envp[])
+{
+ __gcov_flush ();
+ return execve (path, argv, envp);
+}
+#endif
#endif /* inhibit_libc */
diff --git a/gcc/line-map.c b/gcc/line-map.c
index ceb57d45e21..e7d41b652e0 100644
--- a/gcc/line-map.c
+++ b/gcc/line-map.c
@@ -40,6 +40,7 @@ linemap_init (struct line_maps *set)
set->depth = 0;
set->cache = 0;
set->highest_location = 0;
+ set->highest_line = 0;
set->max_column_hint = 0;
}
@@ -154,6 +155,7 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
set->cache = set->used++;
map->column_bits = 0;
set->highest_location = start_location;
+ set->highest_line = start_location;
set->max_column_hint = 0;
if (reason == LC_ENTER)
@@ -181,7 +183,7 @@ linemap_line_start (struct line_maps *set, unsigned int to_line,
struct line_map *map = &set->maps[set->used - 1];
source_location highest = set->highest_location;
source_location r;
- unsigned int last_line = SOURCE_LINE (map, highest);
+ unsigned int last_line = SOURCE_LINE (map, set->highest_line);
int line_delta = to_line - last_line;
bool add_map = false;
if (line_delta < 0
@@ -196,7 +198,7 @@ linemap_line_start (struct line_maps *set, unsigned int to_line,
if (add_map)
{
int column_bits;
- if (max_column_hint > 1000000 || highest > 0xC0000000)
+ if (max_column_hint > 100000 || highest > 0xC0000000)
{
max_column_hint = 0;
if (highest >0xF0000000)
@@ -221,12 +223,36 @@ linemap_line_start (struct line_maps *set, unsigned int to_line,
else
r = highest - SOURCE_COLUMN (map, highest)
+ (line_delta << map->column_bits);
+ set->highest_line = r;
if (r > set->highest_location)
set->highest_location = r;
set->max_column_hint = max_column_hint;
return r;
}
+source_location
+linemap_position_for_column (struct line_maps *set, unsigned int to_column)
+{
+ source_location r = set->highest_line;
+ if (to_column >= set->max_column_hint)
+ {
+ if (r >= 0xC000000 || to_column > 100000)
+ {
+ /* Running low on source_locations - disable column numbers. */
+ return r;
+ }
+ else
+ {
+ struct line_map *map = &set->maps[set->used - 1];
+ r = linemap_line_start (set, SOURCE_LINE (map, r), to_column + 50);
+ }
+ }
+ r = r + to_column;
+ if (r >= set->highest_location)
+ set->highest_location = r;
+ return r;
+}
+
/* Given a logical line, returns the map from which the corresponding
(source file, line) pair can be deduced. Since the set is built
chronologically, the logical lines are monotonic increasing, and so
diff --git a/gcc/line-map.h b/gcc/line-map.h
index a3933a349e2..73631be229f 100644
--- a/gcc/line-map.h
+++ b/gcc/line-map.h
@@ -84,6 +84,9 @@ struct line_maps
/* Highest source_location "given out". */
source_location highest_location;
+ /* Start of line of highest source_location "given out". */
+ source_location highest_line;
+
/* The maximum column number we can quickly allocate. Higher numbers
may require allocating a new line_map. */
unsigned int max_column_hint;
@@ -157,32 +160,23 @@ extern void linemap_print_containing_files (struct line_maps *,
/* Nonzero if the map is at the bottom of the include stack. */
#define MAIN_FILE_P(MAP) ((MAP)->included_from < 0)
-/* Get a source position that for the same line as the most recent
+/* Set LOC to a source position that is the same line as the most recent
linemap_line_start, but with the specified TO_COLUMN column number. */
-static inline source_location
-linemap_position_for_column (struct line_maps *set, unsigned int to_column)
-{
- struct line_map *map = &set->maps[set->used - 1];
- source_location r = set->highest_location;
- if (__builtin_expect (to_column > set->max_column_hint, 0))
- {
- if (r >= 0xC000000 || to_column > 1000000) /* FIXME */
- {
- /* Running low on source_locations - disable column numbers. */
- return r - SOURCE_COLUMN (map, r);
- }
- else
- {
- r = linemap_line_start (set, SOURCE_LINE (map, r), to_column + 50);
- map = &set->maps[set->used - 1];
- r = set->highest_location;
- }
- }
- r = r - SOURCE_COLUMN (map, r) + to_column;
- if (r >= set->highest_location)
- set->highest_location = r;
- return r;
-}
-
+#define LINEMAP_POSITION_FOR_COLUMN(LOC, SET, TO_COLUMN) { \
+ unsigned int to_column = (TO_COLUMN); \
+ struct line_maps *set = (SET); \
+ if (__builtin_expect (to_column >= set->max_column_hint, 0)) \
+ (LOC) = linemap_position_for_column (set, to_column); \
+ else { \
+ source_location r = set->highest_line; \
+ r = r + to_column; \
+ if (r >= set->highest_location) \
+ set->highest_location = r; \
+ (LOC) = r; \
+ }}
+
+
+extern source_location
+linemap_position_for_column (struct line_maps *set, unsigned int to_column);
#endif /* !GCC_LINE_MAP_H */
diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c
index 0396957c0f1..d8d3edf500e 100644
--- a/gcc/loop-doloop.c
+++ b/gcc/loop-doloop.c
@@ -129,7 +129,7 @@ doloop_condition_get (rtx pattern)
return condition;
/* ??? If a machine uses a funny comparison, we could return a
- canonicalised form here. */
+ canonicalized form here. */
return 0;
}
@@ -144,6 +144,7 @@ doloop_valid_p (struct loop *loop, struct niter_desc *desc)
basic_block *body = get_loop_body (loop), bb;
rtx insn;
unsigned i;
+ bool result = true;
/* Check for loops that may not terminate under special conditions. */
if (!desc->simple_p
@@ -174,7 +175,8 @@ doloop_valid_p (struct loop *loop, struct niter_desc *desc)
enable count-register loops in this case. */
if (dump_file)
fprintf (dump_file, "Doloop: Possible infinite iteration case.\n");
- return false;
+ result = false;
+ goto cleanup;
}
for (i = 0; i < loop->num_nodes; i++)
@@ -191,7 +193,8 @@ doloop_valid_p (struct loop *loop, struct niter_desc *desc)
{
if (dump_file)
fprintf (dump_file, "Doloop: Function call in loop.\n");
- return false;
+ result = false;
+ goto cleanup;
}
/* Some targets (eg, PPC) use the count register for branch on table
@@ -202,13 +205,17 @@ doloop_valid_p (struct loop *loop, struct niter_desc *desc)
{
if (dump_file)
fprintf (dump_file, "Doloop: Computed branch in the loop.\n");
- return false;
+ result = false;
+ goto cleanup;
}
}
}
+ result = true;
+
+cleanup:
free (body);
- return true;
+ return result;
}
/* Adds test of COND jumping to DEST to the end of BB. */
diff --git a/gcc/loop-unswitch.c b/gcc/loop-unswitch.c
index a056841ef8a..bedf5f8ce7c 100644
--- a/gcc/loop-unswitch.c
+++ b/gcc/loop-unswitch.c
@@ -379,6 +379,8 @@ unswitch_single_loop (struct loops *loops, struct loop *loop,
free_EXPR_LIST_node (conds);
if (rcond)
free_EXPR_LIST_node (rconds);
+
+ free (bbs);
}
/* Unswitch a LOOP w.r. to given basic block UNSWITCH_ON. We only support
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 1d89ad61034..bec59c061ae 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -1381,6 +1381,7 @@ build_objc_string_object (tree string)
{
tree initlist, constructor, constant_string_class;
int length;
+ tree fields;
string = fix_string_type (string);
@@ -1410,6 +1411,7 @@ build_objc_string_object (tree string)
}
add_class_reference (constant_string_id);
}
+ fields = TYPE_FIELDS (constant_string_type);
/* & ((NXConstantString) { NULL, string, length }) */
@@ -1425,18 +1427,23 @@ build_objc_string_object (tree string)
return error_mark_node;
}
initlist = build_tree_list
- (NULL_TREE,
+ (fields,
copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
}
else
{
- initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
+ initlist = build_tree_list (fields, build_int_2 (0, 0));
}
+ fields = TREE_CHAIN (fields);
+
initlist
- = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
+ = tree_cons (fields, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
initlist);
- initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
+
+ fields = TREE_CHAIN (fields);
+
+ initlist = tree_cons (fields, build_int_2 (length, 0), initlist);
constructor = objc_build_constructor (constant_string_type,
nreverse (initlist));
@@ -5965,7 +5972,9 @@ build_protocol_expr (tree protoname)
expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
- TREE_TYPE (expr) = protocol_type;
+ /* ??? Ideally we'd build the reference with protocol_type directly,
+ if we have it, rather than converting it here. */
+ expr = convert (protocol_type, expr);
/* The @protocol() expression is being compiled into a pointer to a
statically allocated instance of the Protocol class. To become
diff --git a/gcc/objc/objc-lang.c b/gcc/objc/objc-lang.c
index 2853ded31c8..cdc5453687c 100644
--- a/gcc/objc/objc-lang.c
+++ b/gcc/objc/objc-lang.c
@@ -61,6 +61,8 @@ enum c_language_kind c_language = clk_objc;
#define LANG_HOOKS_CLEAR_BINDING_STACK lhd_do_nothing
#undef LANG_HOOKS_EXPAND_EXPR
#define LANG_HOOKS_EXPAND_EXPR c_expand_expr
+#undef LANG_HOOKS_EXPAND_DECL
+#define LANG_HOOKS_EXPAND_DECL c_expand_decl
#undef LANG_HOOKS_MARK_ADDRESSABLE
#define LANG_HOOKS_MARK_ADDRESSABLE c_mark_addressable
#undef LANG_HOOKS_TRUTHVALUE_CONVERSION
@@ -83,16 +85,13 @@ enum c_language_kind c_language = clk_objc;
#define LANG_HOOKS_DECL_PRINTABLE_NAME objc_printable_name
#undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL c_warn_unused_global_decl
-#undef LANG_HOOKS_DECL_UNINIT
-#define LANG_HOOKS_DECL_UNINIT c_decl_uninit
#undef LANG_HOOKS_FUNCTION_ENTER_NESTED
#define LANG_HOOKS_FUNCTION_ENTER_NESTED c_push_function_context
#undef LANG_HOOKS_FUNCTION_LEAVE_NESTED
#define LANG_HOOKS_FUNCTION_LEAVE_NESTED c_pop_function_context
-
-#undef LANG_HOOKS_RTL_EXPAND_STMT
-#define LANG_HOOKS_RTL_EXPAND_STMT expand_stmt
+#undef LANG_HOOKS_FUNCTION_MISSING_NORETURN_OK_P
+#define LANG_HOOKS_FUNCTION_MISSING_NORETURN_OK_P c_missing_noreturn_ok_p
/* Attribute hooks. */
#undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
@@ -113,8 +112,9 @@ enum c_language_kind c_language = clk_objc;
#undef LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING
#define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
c_convert_parm_for_inlining
-#undef LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS
-#define LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS c_estimate_num_insns
+#undef LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P
+#define LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P \
+ c_tree_chain_matters_p
#undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
#define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION c_expand_body
@@ -133,6 +133,8 @@ enum c_language_kind c_language = clk_objc;
#define LANG_HOOKS_INCOMPLETE_TYPE_ERROR c_incomplete_type_error
#undef LANG_HOOKS_TYPE_PROMOTES_TO
#define LANG_HOOKS_TYPE_PROMOTES_TO c_type_promotes_to
+#undef LANG_HOOKS_GIMPLIFY_EXPR
+#define LANG_HOOKS_GIMPLIFY_EXPR c_gimplify_expr
/* The C front end's scoping structure is very different from
that expected by the language-independent code; it is best
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 5fe24b7d1fb..f89e053c456 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -1089,7 +1089,7 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
/* If TARGET is the same as one of the operands, the REG_EQUAL note
won't be accurate, so use a new target. Do this also if target is not
a REG, first because having a register instead may open optimization
- oportunities, and second because if target and op0 happen to be MEMs
+ opportunities, and second because if target and op0 happen to be MEMs
designating the same location, we would risk clobbering it too early
in the code sequence we generate below. */
if (target == 0 || target == op0 || target == op1 || ! REG_P (target))
@@ -2159,7 +2159,7 @@ sign_expand_binop (enum machine_mode mode, optab uoptab, optab soptab,
Returns 1 if this operation can be performed; 0 if not. */
int
-expand_twoval_unop (optab unoptab, rtx targ0, rtx targ1, rtx op0,
+expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
int unsignedp)
{
enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
@@ -2234,7 +2234,7 @@ expand_twoval_unop (optab unoptab, rtx targ0, rtx targ1, rtx op0,
rtx t1 = gen_reg_rtx (wider_mode);
rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
- if (expand_twoval_unop (unoptab, t0, t1, cop0, unsignedp))
+ if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
{
convert_move (targ0, t0, unsignedp);
convert_move (targ1, t1, unsignedp);
@@ -5328,6 +5328,8 @@ init_optabs (void)
udivmod_optab = init_optab (UNKNOWN);
smod_optab = init_optab (MOD);
umod_optab = init_optab (UMOD);
+ fmod_optab = init_optab (UNKNOWN);
+ drem_optab = init_optab (UNKNOWN);
ftrunc_optab = init_optab (UNKNOWN);
and_optab = init_optab (AND);
ior_optab = init_optab (IOR);
@@ -5380,13 +5382,19 @@ init_optabs (void)
nearbyint_optab = init_optab (UNKNOWN);
sincos_optab = init_optab (UNKNOWN);
sin_optab = init_optab (UNKNOWN);
+ asin_optab = init_optab (UNKNOWN);
cos_optab = init_optab (UNKNOWN);
+ acos_optab = init_optab (UNKNOWN);
exp_optab = init_optab (UNKNOWN);
exp10_optab = init_optab (UNKNOWN);
exp2_optab = init_optab (UNKNOWN);
+ expm1_optab = init_optab (UNKNOWN);
+ logb_optab = init_optab (UNKNOWN);
+ ilogb_optab = init_optab (UNKNOWN);
log_optab = init_optab (UNKNOWN);
log10_optab = init_optab (UNKNOWN);
log2_optab = init_optab (UNKNOWN);
+ log1p_optab = init_optab (UNKNOWN);
tan_optab = init_optab (UNKNOWN);
atan_optab = init_optab (UNKNOWN);
strlen_optab = init_optab (UNKNOWN);
diff --git a/gcc/optabs.h b/gcc/optabs.h
index 524cb678200..6fc6c1779e1 100644
--- a/gcc/optabs.h
+++ b/gcc/optabs.h
@@ -93,6 +93,9 @@ enum optab_index
/* Signed remainder */
OTI_smod,
OTI_umod,
+ /* Floating point remainder functions */
+ OTI_fmod,
+ OTI_drem,
/* Convert float to integer in float fmt */
OTI_ftrunc,
@@ -152,20 +155,31 @@ enum optab_index
OTI_sincos,
/* Sine */
OTI_sin,
+ /* Inverse sine */
+ OTI_asin,
/* Cosine */
OTI_cos,
+ /* Inverse cosine */
+ OTI_acos,
/* Exponential */
OTI_exp,
/* Base-10 Exponential */
OTI_exp10,
/* Base-2 Exponential */
OTI_exp2,
+ /* Exponential - 1*/
+ OTI_expm1,
+ /* Radix-independent exponent */
+ OTI_logb,
+ OTI_ilogb,
/* Natural Logarithm */
OTI_log,
/* Base-10 Logarithm */
OTI_log10,
/* Base-2 Logarithm */
OTI_log2,
+ /* logarithm of 1 plus argument */
+ OTI_log1p,
/* Rounding functions */
OTI_floor,
OTI_ceil,
@@ -236,6 +250,8 @@ extern GTY(()) optab optab_table[OTI_MAX];
#define udivmod_optab (optab_table[OTI_udivmod])
#define smod_optab (optab_table[OTI_smod])
#define umod_optab (optab_table[OTI_umod])
+#define fmod_optab (optab_table[OTI_fmod])
+#define drem_optab (optab_table[OTI_drem])
#define ftrunc_optab (optab_table[OTI_ftrunc])
#define and_optab (optab_table[OTI_and])
#define ior_optab (optab_table[OTI_ior])
@@ -268,13 +284,19 @@ extern GTY(()) optab optab_table[OTI_MAX];
#define sqrt_optab (optab_table[OTI_sqrt])
#define sincos_optab (optab_table[OTI_sincos])
#define sin_optab (optab_table[OTI_sin])
+#define asin_optab (optab_table[OTI_asin])
#define cos_optab (optab_table[OTI_cos])
+#define acos_optab (optab_table[OTI_acos])
#define exp_optab (optab_table[OTI_exp])
#define exp10_optab (optab_table[OTI_exp10])
#define exp2_optab (optab_table[OTI_exp2])
+#define expm1_optab (optab_table[OTI_expm1])
+#define logb_optab (optab_table[OTI_logb])
+#define ilogb_optab (optab_table[OTI_ilogb])
#define log_optab (optab_table[OTI_log])
#define log10_optab (optab_table[OTI_log10])
#define log2_optab (optab_table[OTI_log2])
+#define log1p_optab (optab_table[OTI_log1p])
#define floor_optab (optab_table[OTI_floor])
#define ceil_optab (optab_table[OTI_ceil])
#define btrunc_optab (optab_table[OTI_trunc])
diff --git a/gcc/opts.c b/gcc/opts.c
index a2df41a489a..c8a488f5d45 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -540,6 +540,24 @@ decode_options (unsigned int argc, const char **argv)
flag_loop_optimize = 1;
flag_if_conversion = 1;
flag_if_conversion2 = 1;
+ flag_tree_ccp = 1;
+ flag_tree_dce = 1;
+ flag_tree_dom = 1;
+ flag_tree_dse = 1;
+ flag_tree_pre = 1;
+ flag_tree_ter = 1;
+ flag_tree_live_range_split = 1;
+ flag_tree_sra = 1;
+ flag_tree_copyrename = 1;
+
+ if (!optimize_size)
+ {
+ /* Loop header copying usually increases size of the code. This used
+ not to be true, since quite often it is possible to verify that
+ the condition is satisfied in the first iteration and therefore
+ to eliminate it. Jump threading handles these cases now. */
+ flag_tree_ch = 1;
+ }
}
if (optimize >= 2)
@@ -571,9 +589,7 @@ decode_options (unsigned int argc, const char **argv)
if (optimize >= 3)
{
flag_inline_functions = 1;
- flag_rename_registers = 1;
flag_unswitch_loops = 1;
- flag_web = 1;
flag_gcse_after_reload = 1;
}
@@ -606,8 +622,9 @@ decode_options (unsigned int argc, const char **argv)
/* Initialize whether `char' is signed. */
flag_signed_char = DEFAULT_SIGNED_CHAR;
- /* Initialize how much space enums occupy, by default. */
- flag_short_enums = targetm.default_short_enums ();
+ /* Set this to a special "uninitialized" value. The actual default is set
+ after target options have been processed. */
+ flag_short_enums = 2;
/* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can
modify it. */
@@ -744,6 +761,10 @@ common_handle_option (size_t scode, const char *arg,
set_Wextra (value);
break;
+ case OPT_Wfatal_errors:
+ flag_fatal_errors = value;
+ break;
+
case OPT_Winline:
warn_inline = value;
break;
@@ -992,6 +1013,11 @@ common_handle_option (size_t scode, const char *arg,
return 0;
break;
+ case OPT_fdump_:
+ if (!dump_switch_p (arg))
+ return 0;
+ break;
+
case OPT_fdump_unnumbered:
flag_dump_unnumbered = value;
break;
@@ -1147,6 +1173,19 @@ common_handle_option (size_t scode, const char *arg,
flag_move_all_movables = value;
break;
+ case OPT_fmudflap:
+ flag_mudflap = value;
+ break;
+
+ case OPT_fmudflapth:
+ flag_mudflap = value;
+ flag_mudflap_threads = value;
+ break;
+
+ case OPT_fmudflapir:
+ flag_mudflap_ignore_reads = value;
+ break;
+
case OPT_fnew_ra:
flag_new_regalloc = value;
break;
@@ -1447,6 +1486,70 @@ common_handle_option (size_t scode, const char *arg,
flag_trapv = value;
break;
+ case OPT_ftree_based_profiling:
+ flag_tree_based_profiling = value;
+ break;
+
+ case OPT_ftree_ccp:
+ flag_tree_ccp = value;
+ break;
+
+ case OPT_ftree_dce:
+ flag_tree_dce = value;
+ break;
+
+ case OPT_ftree_combine_temps:
+ flag_tree_combine_temps = value;
+ break;
+
+ case OPT_ftree_ter:
+ flag_tree_ter = value;
+ break;
+
+ case OPT_ftree_lrs:
+ flag_tree_live_range_split = value;
+ break;
+
+ case OPT_ftree_dominator_opts:
+ flag_tree_dom = value;
+ break;
+
+ case OPT_ftree_copyrename:
+ flag_tree_copyrename = value;
+ break;
+
+ case OPT_ftree_ch:
+ flag_tree_ch = value;
+ break;
+
+ case OPT_ftree_dse:
+ flag_tree_dse = value;
+ break;
+
+ case OPT_ftree_sra:
+ flag_tree_sra = value;
+ break;
+
+ case OPT_ftree_points_to_:
+ if (!strcmp (arg, "andersen"))
+#ifdef HAVE_BANSHEE
+ flag_tree_points_to = PTA_ANDERSEN;
+#else
+ warning ("Andersen's PTA not available - libbanshee not compiled.");
+#endif
+ else if (!strcmp (arg, "none"))
+ flag_tree_points_to = PTA_NONE;
+ else
+ {
+ warning ("`%s`: unknown points-to analysis algorithm", arg);
+ return 0;
+ }
+ break;
+
+ case OPT_ftree_pre:
+ flag_tree_pre = value;
+ break;
+
case OPT_funit_at_a_time:
flag_unit_at_a_time = value;
break;
diff --git a/gcc/output.h b/gcc/output.h
index 9040327879c..945dace71d2 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -150,12 +150,7 @@ extern int add_weak (tree, const char *, const char *);
/* Functions in flow.c */
extern void allocate_for_life_analysis (void);
-extern int regno_uninitialized (unsigned int);
extern int regno_clobbered_at_setjmp (int);
-extern void find_basic_blocks (rtx, int, FILE *);
-extern bool cleanup_cfg (int);
-extern bool delete_unreachable_blocks (void);
-extern void check_function_return_warnings (void);
/* Functions in varasm.c. */
diff --git a/gcc/params.def b/gcc/params.def
index c406ab87ae9..ff77eb488ce 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -65,6 +65,26 @@ DEFPARAM (PARAM_MAX_INLINE_INSNS_AUTO,
"The maximum number of instructions when automatically inlining",
120)
+DEFPARAM (PARAM_MAX_INLINE_INSNS_RECURSIVE,
+ "max-inline-insns-recursive",
+ "The maximum number of instructions inline function can grow to via recursive inlining",
+ 500)
+
+DEFPARAM (PARAM_MAX_INLINE_INSNS_RECURSIVE_AUTO,
+ "max-inline-insns-recursive-auto",
+ "The maximum number of instructions non-inline function can grow to via recursive inlining",
+ 500)
+
+DEFPARAM (PARAM_MAX_INLINE_RECURSIVE_DEPTH,
+ "max-inline-recursive-depth",
+ "The maximum depth of recursive inlining for inline functions",
+ 8)
+
+DEFPARAM (PARAM_MAX_INLINE_RECURSIVE_DEPTH_AUTO,
+ "max-inline-recursive-depth-auto",
+ "The maximum depth of recursive inlining for non-inline functions",
+ 8)
+
/* For languages that (still) use the RTL inliner, we can specify
limits for the RTL inliner separately.
The parameter here defines the maximum number of RTL instructions
@@ -261,6 +281,13 @@ DEFPARAM(PARAM_MAX_CSE_PATH_LENGTH,
"The maximum length of path considered in cse",
10)
+/* The product of the next two is used to decide whether or not to
+ use .GLOBAL_VAR. See tree-dfa.c. */
+DEFPARAM(PARAM_GLOBAL_VAR_THRESHOLD,
+ "global-var-threshold",
+ "Given N calls and V call-clobbered vars in a function. Use .GLOBAL_VAR if NxV is larger than this limit",
+ 500000)
+
DEFPARAM(PARAM_MAX_CSELIB_MEMORY_LOCATIONS,
"max-cselib-memory-locations",
"The maximum memory locations recorded by cselib",
@@ -293,6 +320,11 @@ DEFPARAM(PARAM_MAX_RELOAD_SEARCH_INSNS,
"The maximum number of instructions to search backward when looking for equivalent reload",
100)
+DEFPARAM(PARAM_MAX_ALIASED_VOPS,
+ "max-aliased-vops",
+ "The maximum number of virtual operands allowed to represent aliases before triggering alias grouping.",
+ 500)
+
DEFPARAM(PARAM_MAX_SCHED_REGION_BLOCKS,
"max-sched-region-blocks",
"The maximum number of blocks in a region to be considered for interblock scheduling",
diff --git a/gcc/params.h b/gcc/params.h
index fbdb63490c5..996f7a0b77e 100644
--- a/gcc/params.h
+++ b/gcc/params.h
@@ -110,4 +110,8 @@ typedef enum compiler_param
PARAM_VALUE (PARAM_GCSE_AFTER_RELOAD_CRITICAL_FRACTION)
#define MAX_UNROLLED_INSNS \
PARAM_VALUE (PARAM_MAX_UNROLLED_INSNS)
+#define GLOBAL_VAR_THRESHOLD \
+ PARAM_VALUE (PARAM_GLOBAL_VAR_THRESHOLD)
+#define MAX_ALIASED_VOPS \
+ PARAM_VALUE (PARAM_MAX_ALIASED_VOPS)
#endif /* ! GCC_PARAMS_H */
diff --git a/gcc/passes.c b/gcc/passes.c
index 2453c748dc3..5c8e5a6fd0f 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -394,7 +394,8 @@ rest_of_decl_compilation (tree decl,
}
else
{
- error ("invalid register name `%s' for register variable", asmspec);
+ error ("%Hinvalid register name `%s' for register variable",
+ &DECL_SOURCE_LOCATION (decl), asmspec);
DECL_REGISTER (decl) = 0;
if (!top_level)
expand_decl (decl);
@@ -465,7 +466,7 @@ rest_of_handle_final (tree decl, rtx insns)
fflush (asm_out_file);
/* Release all memory allocated by flow. */
- free_basic_block_vars (0);
+ free_basic_block_vars ();
/* Release all memory held by regsets now. */
regset_release_memory ();
@@ -976,34 +977,6 @@ rest_of_handle_addressof (tree decl, rtx insns)
close_dump_file (DFI_addressof, print_rtl, insns);
}
-/* We may have potential sibling or tail recursion sites. Select one
- (of possibly multiple) methods of performing the call. */
-static void
-rest_of_handle_sibling_calls (rtx insns)
-{
- rtx insn;
- optimize_sibling_and_tail_recursive_calls ();
-
- /* Recompute the CFG as sibling optimization clobbers it randomly. */
- free_bb_for_insn ();
- find_exception_handler_labels ();
- rebuild_jump_labels (insns);
- find_basic_blocks (insns, max_reg_num (), dump_file);
-
- /* There is pass ordering problem - we must lower NOTE_INSN_PREDICTION
- notes before simplifying cfg and we must do lowering after sibcall
- that unhides parts of RTL chain and cleans up the CFG.
-
- Until sibcall is replaced by tree-level optimizer, lets just
- sweep away the NOTE_INSN_PREDICTION notes that leaked out. */
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- if (GET_CODE (insn) == NOTE
- && NOTE_LINE_NUMBER (insn) == NOTE_INSN_PREDICTION)
- delete_insn (insn);
-
- close_dump_file (DFI_sibling, print_rtl, get_insns ());
-}
-
/* Perform jump bypassing and control flow optimizations. */
static void
rest_of_handle_jump_bypass (tree decl, rtx insns)
@@ -1031,169 +1004,6 @@ rest_of_handle_jump_bypass (tree decl, rtx insns)
#endif
}
-/* Handle inlining of functions in rest_of_compilation. Return TRUE
- if we must exit rest_of_compilation upon return. */
-static bool
-rest_of_handle_inlining (tree decl)
-{
- rtx insns;
- int inlinable = 0;
- tree parent;
- const char *lose;
-
- /* If we are reconsidering an inline function at the end of
- compilation, skip the stuff for making it inline. */
- if (cfun->rtl_inline_init)
- return 0;
- cfun->rtl_inline_init = 1;
-
- /* If this is nested inside an inlined external function, pretend
- it was only declared. Since we cannot inline such functions,
- generating code for this one is not only not necessary but will
- confuse some debugging output writers. */
- for (parent = DECL_CONTEXT (current_function_decl);
- parent != NULL_TREE;
- parent = get_containing_scope (parent))
- if (TREE_CODE (parent) == FUNCTION_DECL
- && DECL_INLINE (parent) && DECL_EXTERNAL (parent))
- {
- DECL_INITIAL (decl) = 0;
- return true;
- }
- else if (TYPE_P (parent))
- /* A function in a local class should be treated normally. */
- break;
-
- /* If requested, consider whether to make this function inline. */
- if ((DECL_INLINE (decl) && !flag_no_inline)
- || flag_inline_functions)
- {
- timevar_push (TV_INTEGRATION);
- lose = function_cannot_inline_p (decl);
- timevar_pop (TV_INTEGRATION);
- if (lose || ! optimize)
- {
- if (warn_inline && lose && DECL_INLINE (decl))
- {
- char *msg = concat ("%J", lose, NULL);
- warning (msg, decl);
- free (msg);
- }
- DECL_ABSTRACT_ORIGIN (decl) = 0;
- /* Don't really compile an extern inline function.
- If we can't make it inline, pretend
- it was only declared. */
- if (DECL_EXTERNAL (decl))
- {
- DECL_INITIAL (decl) = 0;
- return true;
- }
- }
- else
- inlinable = DECL_INLINE (decl) = 1;
- }
-
- insns = get_insns ();
-
- /* Dump the rtl code if we are dumping rtl. */
-
- if (open_dump_file (DFI_rtl, decl))
- {
- if (DECL_STRUCT_FUNCTION (decl)
- && DECL_STRUCT_FUNCTION (decl)->saved_for_inline)
- fprintf (dump_file, ";; (integrable)\n\n");
- close_dump_file (DFI_rtl, print_rtl, insns);
- }
-
- /* Convert from NOTE_INSN_EH_REGION style notes, and do other
- sorts of eh initialization. Delay this until after the
- initial rtl dump so that we can see the original nesting. */
- convert_from_eh_region_ranges ();
-
- /* If function is inline, and we don't yet know whether to
- compile it by itself, defer decision till end of compilation.
- wrapup_global_declarations will (indirectly) call
- rest_of_compilation again for those functions that need to
- be output. Also defer those functions that we are supposed
- to defer. */
-
- if (inlinable
- || (DECL_INLINE (decl)
- /* Egad. This RTL deferral test conflicts with Fortran assumptions
- for unreferenced symbols. See g77.f-torture/execute/980520-1.f.
- But removing this line from the check breaks all languages that
- use the call graph to output symbols. This hard-coded check is
- the least invasive work-around. */
- && (flag_inline_functions
- || strcmp (lang_hooks.name, "GNU F77") == 0)
- && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl)
- && ! TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
- && ! flag_keep_inline_functions)
- || DECL_EXTERNAL (decl))))
- DECL_DEFER_OUTPUT (decl) = 1;
-
- if (DECL_INLINE (decl))
- /* DWARF wants separate debugging info for abstract and
- concrete instances of all inline functions, including those
- declared inline but not inlined, and those inlined even
- though they weren't declared inline. Conveniently, that's
- what DECL_INLINE means at this point. */
- (*debug_hooks->deferred_inline_function) (decl);
-
- if (DECL_DEFER_OUTPUT (decl))
- {
- /* If -Wreturn-type, we have to do a bit of compilation. We just
- want to call cleanup the cfg to figure out whether or not we can
- fall off the end of the function; we do the minimum amount of
- work necessary to make that safe. */
- if (warn_return_type)
- {
- int saved_optimize = optimize;
-
- optimize = 0;
- rebuild_jump_labels (insns);
- find_exception_handler_labels ();
- find_basic_blocks (insns, max_reg_num (), dump_file);
- cleanup_cfg (CLEANUP_PRE_SIBCALL | CLEANUP_PRE_LOOP);
- optimize = saved_optimize;
-
- /* CFG is no longer maintained up-to-date. */
- free_bb_for_insn ();
- }
-
- set_nothrow_function_flags ();
- if (current_function_nothrow)
- /* Now we know that this can't throw; set the flag for the benefit
- of other functions later in this translation unit. */
- TREE_NOTHROW (current_function_decl) = 1;
-
- timevar_push (TV_INTEGRATION);
- save_for_inline (decl);
- timevar_pop (TV_INTEGRATION);
- DECL_STRUCT_FUNCTION (decl)->inlinable = inlinable;
- return true;
- }
-
- /* If specified extern inline but we aren't inlining it, we are
- done. This goes for anything that gets here with DECL_EXTERNAL
- set, not just things with DECL_INLINE. */
- return (bool) DECL_EXTERNAL (decl);
-}
-
-/* Try to identify useless null pointer tests and delete them. */
-static void
-rest_of_handle_null_pointer (tree decl, rtx insns)
-{
- open_dump_file (DFI_null, decl);
- if (dump_file)
- dump_flow_info (dump_file);
-
- if (delete_null_pointer_checks (insns))
- cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
-
- close_dump_file (DFI_null, print_rtl_with_bb, insns);
-}
-
/* Try combining insns through substitution. */
static void
rest_of_handle_combine (tree decl, rtx insns)
@@ -1241,11 +1051,10 @@ rest_of_handle_life (tree decl, rtx insns)
| (flag_thread_jumps ? CLEANUP_THREADING : 0));
timevar_pop (TV_FLOW);
- if (warn_uninitialized)
+ if (extra_warnings)
{
- uninitialized_vars_warning (DECL_INITIAL (decl));
- if (extra_warnings)
- setjmp_args_warning ();
+ setjmp_vars_warning (DECL_INITIAL (decl));
+ setjmp_args_warning ();
}
if (optimize)
@@ -1297,19 +1106,6 @@ rest_of_handle_cse (tree decl, rtx insns)
if (tem || optimize > 1)
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
- /* Try to identify useless null pointer tests and delete them. */
- if (flag_delete_null_pointer_checks)
- {
- timevar_push (TV_JUMP);
-
- if (delete_null_pointer_checks (insns))
- cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
- timevar_pop (TV_JUMP);
- }
-
- /* The second pass of jump optimization is likely to have
- removed a bunch more instructions. */
- renumber_insns (dump_file);
timevar_pop (TV_CSE);
close_dump_file (DFI_cse, print_rtl_with_bb, insns);
@@ -1368,10 +1164,6 @@ rest_of_handle_gcse (tree decl, rtx insns)
save_cfj = flag_cse_follow_jumps;
flag_cse_skip_blocks = flag_cse_follow_jumps = 0;
- /* Instantiate any remaining CONSTANT_P_RTX nodes. */
- if (current_function_calls_constant_p)
- purge_builtin_constant_p ();
-
/* If -fexpensive-optimizations, re-run CSE to clean up things done
by gcse. */
if (flag_expensive_optimizations)
@@ -1552,20 +1344,31 @@ rest_of_compilation (tree decl)
have been run to re-initialize it. */
cse_not_expected = ! optimize;
- /* First, make sure that NOTE_BLOCK is set correctly for each
- NOTE_INSN_BLOCK_BEG/NOTE_INSN_BLOCK_END note. */
- if (!cfun->x_whole_function_mode_p)
- identify_blocks ();
-
- /* In function-at-a-time mode, we do not attempt to keep the BLOCK
- tree in sensible shape. So, we just recalculate it here. */
- if (cfun->x_whole_function_mode_p)
- reorder_blocks ();
+ if (!cfun->dont_emit_block_notes)
+ {
+ /* First, make sure that NOTE_BLOCK is set correctly for each
+ NOTE_INSN_BLOCK_BEG/NOTE_INSN_BLOCK_END note. */
+ if (!cfun->x_whole_function_mode_p)
+ identify_blocks ();
+
+ /* In function-at-a-time mode, we do not attempt to keep the BLOCK
+ tree in sensible shape. So, we just recalculate it here. */
+ if (cfun->x_whole_function_mode_p)
+ reorder_blocks ();
+ }
+ else
+ finalize_block_changes ();
init_flow ();
- if (rest_of_handle_inlining (decl))
- goto exit_rest_of_compilation;
+ /* Dump the rtl code if we are dumping rtl. */
+ if (open_dump_file (DFI_rtl, decl))
+ close_dump_file (DFI_rtl, print_rtl, get_insns ());
+
+ /* Convert from NOTE_INSN_EH_REGION style notes, and do other
+ sorts of eh initialization. Delay this until after the
+ initial rtl dump so that we can see the original nesting. */
+ convert_from_eh_region_ranges ();
/* If we're emitting a nested function, make sure its parent gets
emitted as well. Doing otherwise confuses debug info. */
@@ -1588,7 +1391,8 @@ rest_of_compilation (tree decl)
over the instruction sequence faster, and allow the garbage
collector to reclaim the memory used by the notes. */
remove_unnecessary_notes ();
- reorder_blocks ();
+ if (!cfun->dont_emit_block_notes)
+ reorder_blocks ();
ggc_collect ();
@@ -1631,19 +1435,11 @@ rest_of_compilation (tree decl)
timevar_pop (TV_BRANCH_PROB);
}
- if (flag_optimize_sibling_calls)
- rest_of_handle_sibling_calls (insns);
-
- /* We have to issue these warnings now already, because CFG cleanups
- further down may destroy the required information. However, this
- must be done after the sibcall optimization pass because the barrier
- emitted for noreturn calls that are candidate for the optimization
- is folded into the CALL_PLACEHOLDER until after this pass, so the
- CFG is inaccurate. */
- check_function_return_warnings ();
-
timevar_pop (TV_JUMP);
+ if (cfun->tail_call_emit)
+ fixup_tail_calls ();
+
insn_locators_initialize ();
/* Complete generation of exception handling code. */
if (doing_eh (0))
@@ -1708,12 +1504,8 @@ rest_of_compilation (tree decl)
cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP
| (flag_thread_jumps ? CLEANUP_THREADING : 0));
- if (optimize)
- {
- free_bb_for_insn ();
- copy_loop_headers (insns);
- find_basic_blocks (insns, max_reg_num (), dump_file);
- }
+ create_loop_notes ();
+
purge_line_number_notes (insns);
timevar_pop (TV_JUMP);
@@ -1728,9 +1520,6 @@ rest_of_compilation (tree decl)
if (optimize)
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
- if (flag_delete_null_pointer_checks)
- rest_of_handle_null_pointer (decl, insns);
-
/* Jump optimization, and the removal of NULL pointer checks, may
have reduced the number of instructions substantially. CSE, and
future passes, allocate arrays whose dimensions involve the
@@ -1766,9 +1555,12 @@ rest_of_compilation (tree decl)
rest_of_handle_cfg (decl, insns);
- if (optimize > 0
- || profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
+ if (!flag_tree_based_profiling
+ && (optimize > 0 || profile_arc_flag
+ || flag_test_coverage || flag_branch_probabilities))
{
+ rtl_register_profile_hooks ();
+ rtl_register_value_prof_hooks ();
rest_of_handle_branch_prob (decl, insns);
if (flag_branch_probabilities
@@ -2095,7 +1887,7 @@ rest_of_compilation (tree decl)
/* Show no temporary slots allocated. */
init_temp_slots ();
- free_basic_block_vars (0);
+ free_basic_block_vars ();
free_bb_for_insn ();
timevar_pop (TV_FINAL);
diff --git a/gcc/predict.c b/gcc/predict.c
index 669760bf41f..271698bd2d1 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -53,6 +53,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "target.h"
#include "loop.h"
#include "cfgloop.h"
+#include "tree-flow.h"
+#include "ggc.h"
+#include "tree-dump.h"
+#include "tree-pass.h"
+#include "timevar.h"
/* real constants: 0, 1, 1-1/REG_BR_PROB_BASE, REG_BR_PROB_BASE,
1/REG_BR_PROB_BASE, 0.5, BB_FREQ_MAX. */
@@ -65,9 +70,8 @@ static sreal real_zero, real_one, real_almost_one, real_br_prob_base,
#define PROB_VERY_LIKELY (REG_BR_PROB_BASE - PROB_VERY_UNLIKELY)
#define PROB_ALWAYS (REG_BR_PROB_BASE)
-static bool predicted_by_p (basic_block, enum br_predictor);
static void combine_predictions_for_insn (rtx, basic_block);
-static void dump_prediction (enum br_predictor, int, basic_block, int);
+static void dump_prediction (FILE *, enum br_predictor, int, basic_block, int);
static void estimate_loops_at_level (struct loop *loop);
static void propagate_freq (struct loop *);
static void estimate_bb_frequencies (struct loops *);
@@ -148,8 +152,8 @@ probably_never_executed_bb_p (basic_block bb)
/* Return true if the one of outgoing edges is already predicted by
PREDICTOR. */
-static bool
-predicted_by_p (basic_block bb, enum br_predictor predictor)
+bool
+rtl_predicted_by_p (basic_block bb, enum br_predictor predictor)
{
rtx note;
if (!INSN_P (BB_END (bb)))
@@ -161,6 +165,19 @@ predicted_by_p (basic_block bb, enum br_predictor predictor)
return false;
}
+/* Return true if the one of outgoing edges is already predicted by
+ PREDICTOR. */
+
+bool
+tree_predicted_by_p (basic_block bb, enum br_predictor predictor)
+{
+ struct edge_prediction *i = bb_ann (bb)->predictions;
+ for (i = bb_ann (bb)->predictions; i; i = i->next)
+ if (i->predictor == predictor)
+ return true;
+ return false;
+}
+
void
predict_insn (rtx insn, enum br_predictor predictor, int probability)
{
@@ -194,7 +211,7 @@ predict_insn_def (rtx insn, enum br_predictor predictor,
/* Predict edge E with given probability if possible. */
void
-predict_edge (edge e, enum br_predictor predictor, int probability)
+rtl_predict_edge (edge e, enum br_predictor predictor, int probability)
{
rtx last_insn;
last_insn = BB_END (e->src);
@@ -211,6 +228,19 @@ predict_edge (edge e, enum br_predictor predictor, int probability)
predict_insn (last_insn, predictor, probability);
}
+/* Predict edge E with the given PROBABILITY. */
+void
+tree_predict_edge (edge e, enum br_predictor predictor, int probability)
+{
+ struct edge_prediction *i = ggc_alloc (sizeof (struct edge_prediction));
+
+ i->next = bb_ann (e->src)->predictions;
+ bb_ann (e->src)->predictions = i;
+ i->probability = probability;
+ i->predictor = predictor;
+ i->edge = e;
+}
+
/* Return true when we can store prediction on insn INSN.
At the moment we represent predictions only on conditional
jumps, not at computed jump or other complicated cases. */
@@ -255,34 +285,34 @@ invert_br_probabilities (rtx insn)
/* Dump information about the branch prediction to the output file. */
static void
-dump_prediction (enum br_predictor predictor, int probability,
+dump_prediction (FILE *file, enum br_predictor predictor, int probability,
basic_block bb, int used)
{
edge e = bb->succ;
- if (!dump_file)
+ if (!file)
return;
while (e && (e->flags & EDGE_FALLTHRU))
e = e->succ_next;
- fprintf (dump_file, " %s heuristics%s: %.1f%%",
+ fprintf (file, " %s heuristics%s: %.1f%%",
predictor_info[predictor].name,
used ? "" : " (ignored)", probability * 100.0 / REG_BR_PROB_BASE);
if (bb->count)
{
- fprintf (dump_file, " exec ");
- fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, bb->count);
+ fprintf (file, " exec ");
+ fprintf (file, HOST_WIDEST_INT_PRINT_DEC, bb->count);
if (e)
{
- fprintf (dump_file, " hit ");
- fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, e->count);
- fprintf (dump_file, " (%.1f%%)", e->count * 100.0 / bb->count);
+ fprintf (file, " hit ");
+ fprintf (file, HOST_WIDEST_INT_PRINT_DEC, e->count);
+ fprintf (file, " (%.1f%%)", e->count * 100.0 / bb->count);
}
}
- fprintf (dump_file, "\n");
+ fprintf (file, "\n");
}
/* Combine all REG_BR_PRED notes into single probability and attach REG_BR_PROB
@@ -306,8 +336,7 @@ combine_predictions_for_insn (rtx insn, basic_block bb)
bb->index);
/* We implement "first match" heuristics and use probability guessed
- by predictor with smallest index. In the future we will use better
- probability combination techniques. */
+ by predictor with smallest index. */
for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
if (REG_NOTE_KIND (note) == REG_BR_PRED)
{
@@ -339,16 +368,19 @@ combine_predictions_for_insn (rtx insn, basic_block bb)
first_match = true;
if (!found)
- dump_prediction (PRED_NO_PREDICTION, combined_probability, bb, true);
+ dump_prediction (dump_file, PRED_NO_PREDICTION,
+ combined_probability, bb, true);
else
{
- dump_prediction (PRED_DS_THEORY, combined_probability, bb, !first_match);
- dump_prediction (PRED_FIRST_MATCH, best_probability, bb, first_match);
+ dump_prediction (dump_file, PRED_DS_THEORY, combined_probability,
+ bb, !first_match);
+ dump_prediction (dump_file, PRED_FIRST_MATCH, best_probability,
+ bb, first_match);
}
if (first_match)
combined_probability = best_probability;
- dump_prediction (PRED_COMBINED, combined_probability, bb, true);
+ dump_prediction (dump_file, PRED_COMBINED, combined_probability, bb, true);
while (*pnote)
{
@@ -357,7 +389,7 @@ combine_predictions_for_insn (rtx insn, basic_block bb)
int predictor = INTVAL (XEXP (XEXP (*pnote, 0), 0));
int probability = INTVAL (XEXP (XEXP (*pnote, 0), 1));
- dump_prediction (predictor, probability, bb,
+ dump_prediction (dump_file, predictor, probability, bb,
!first_match || best_predictor == predictor);
*pnote = XEXP (*pnote, 1);
}
@@ -382,21 +414,126 @@ combine_predictions_for_insn (rtx insn, basic_block bb)
}
}
-/* Statically estimate the probability that a branch will be taken.
- ??? In the next revision there will be a number of other predictors added
- from the above references. Further, each heuristic will be factored out
- into its own function for clarity (and to facilitate the combination of
- predictions). */
+/* Combine predictions into single probability and store them into CFG.
+ Remove now useless prediction entries. */
-void
-estimate_probability (struct loops *loops_info)
+static void
+combine_predictions_for_bb (FILE *file, basic_block bb)
{
- basic_block bb;
- unsigned i;
+ int best_probability = PROB_EVEN;
+ int best_predictor = END_PREDICTORS;
+ int combined_probability = REG_BR_PROB_BASE / 2;
+ int d;
+ bool first_match = false;
+ bool found = false;
+ struct edge_prediction *pred;
+ int nedges = 0;
+ edge e, first = NULL, second = NULL;
- connect_infinite_loops_to_exit ();
- calculate_dominance_info (CDI_DOMINATORS);
- calculate_dominance_info (CDI_POST_DOMINATORS);
+ for (e = bb->succ; e; e = e->succ_next)
+ if (!(e->flags & (EDGE_EH | EDGE_FAKE)))
+ {
+ nedges ++;
+ if (first && !second)
+ second = e;
+ if (!first)
+ first = e;
+ }
+
+ /* When there is no successor or only one choice, prediction is easy.
+
+ We are lazy for now and predict only basic blocks with two outgoing
+ edges. It is possible to predict generic case too, but we have to
+ ignore first match heuristics and do more involved combining. Implement
+ this later. */
+ if (nedges != 2)
+ {
+ for (e = bb->succ; e; e = e->succ_next)
+ if (!(e->flags & (EDGE_EH | EDGE_FAKE)))
+ e->probability = (REG_BR_PROB_BASE + nedges / 2) / nedges;
+ else
+ e->probability = 0;
+ bb_ann (bb)->predictions = NULL;
+ if (file)
+ fprintf (file, "%i edges in bb %i predicted to even probabilities\n",
+ nedges, bb->index);
+ return;
+ }
+
+ if (file)
+ fprintf (file, "Predictions for bb %i\n", bb->index);
+
+ /* We implement "first match" heuristics and use probability guessed
+ by predictor with smallest index. */
+ for (pred = bb_ann (bb)->predictions; pred; pred = pred->next)
+ {
+ int predictor = pred->predictor;
+ int probability = pred->probability;
+
+ if (pred->edge != first)
+ probability = REG_BR_PROB_BASE - probability;
+
+ found = true;
+ if (best_predictor > predictor)
+ best_probability = probability, best_predictor = predictor;
+
+ d = (combined_probability * probability
+ + (REG_BR_PROB_BASE - combined_probability)
+ * (REG_BR_PROB_BASE - probability));
+
+ /* Use FP math to avoid overflows of 32bit integers. */
+ if (d == 0)
+ /* If one probability is 0% and one 100%, avoid division by zero. */
+ combined_probability = REG_BR_PROB_BASE / 2;
+ else
+ combined_probability = (((double) combined_probability) * probability
+ * REG_BR_PROB_BASE / d + 0.5);
+ }
+
+ /* Decide which heuristic to use. In case we didn't match anything,
+ use no_prediction heuristic, in case we did match, use either
+ first match or Dempster-Shaffer theory depending on the flags. */
+
+ if (predictor_info [best_predictor].flags & PRED_FLAG_FIRST_MATCH)
+ first_match = true;
+
+ if (!found)
+ dump_prediction (file, PRED_NO_PREDICTION, combined_probability, bb, true);
+ else
+ {
+ dump_prediction (file, PRED_DS_THEORY, combined_probability, bb,
+ !first_match);
+ dump_prediction (file, PRED_FIRST_MATCH, best_probability, bb,
+ first_match);
+ }
+
+ if (first_match)
+ combined_probability = best_probability;
+ dump_prediction (file, PRED_COMBINED, combined_probability, bb, true);
+
+ for (pred = bb_ann (bb)->predictions; pred; pred = pred->next)
+ {
+ int predictor = pred->predictor;
+ int probability = pred->probability;
+
+ if (pred->edge != bb->succ)
+ probability = REG_BR_PROB_BASE - probability;
+ dump_prediction (file, predictor, probability, bb,
+ !first_match || best_predictor == predictor);
+ }
+ bb_ann (bb)->predictions = NULL;
+
+ first->probability = combined_probability;
+ second->probability = REG_BR_PROB_BASE - combined_probability;
+}
+
+/* Predict edge probabilities by exploiting loop structure.
+ When SIMPLELOOPS is set, attempt to count number of iterations by analyzing
+ RTL. */
+static void
+predict_loops (struct loops *loops_info, bool simpleloops)
+{
+ unsigned i;
/* Try to predict out blocks in a loop that are not part of a
natural loop. */
@@ -412,27 +549,31 @@ estimate_probability (struct loops *loops_info)
flow_loop_scan (loop, LOOP_EXIT_EDGES);
exits = loop->num_exits;
- iv_analysis_loop_init (loop);
- find_simple_exit (loop, &desc);
-
- if (desc.simple_p && desc.const_iter)
+ if (simpleloops)
{
- int prob;
- niter = desc.niter + 1;
- if (niter == 0) /* We might overflow here. */
- niter = desc.niter;
-
- prob = (REG_BR_PROB_BASE
- - (REG_BR_PROB_BASE + niter /2) / niter);
- /* Branch prediction algorithm gives 0 frequency for everything
- after the end of loop for loop having 0 probability to finish. */
- if (prob == REG_BR_PROB_BASE)
- prob = REG_BR_PROB_BASE - 1;
- predict_edge (desc.in_edge, PRED_LOOP_ITERATIONS,
- prob);
+ iv_analysis_loop_init (loop);
+ find_simple_exit (loop, &desc);
+
+ if (desc.simple_p && desc.const_iter)
+ {
+ int prob;
+ niter = desc.niter + 1;
+ if (niter == 0) /* We might overflow here. */
+ niter = desc.niter;
+
+ prob = (REG_BR_PROB_BASE
+ - (REG_BR_PROB_BASE + niter /2) / niter);
+ /* Branch prediction algorithm gives 0 frequency for everything
+ after the end of loop for loop having 0 probability to finish. */
+ if (prob == REG_BR_PROB_BASE)
+ prob = REG_BR_PROB_BASE - 1;
+ predict_edge (desc.in_edge, PRED_LOOP_ITERATIONS,
+ prob);
+ }
}
bbs = get_loop_body (loop);
+
for (j = 0; j < loop->num_nodes; j++)
{
int header_found = 0;
@@ -444,7 +585,7 @@ estimate_probability (struct loops *loops_info)
statements construct loops via "non-loop" constructs
in the source language and are better to be handled
separately. */
- if (!can_predict_insn_p (BB_END (bb))
+ if ((simpleloops && !can_predict_insn_p (BB_END (bb)))
|| predicted_by_p (bb, PRED_CONTINUE))
continue;
@@ -474,6 +615,22 @@ estimate_probability (struct loops *loops_info)
/* Free basic blocks from get_loop_body. */
free (bbs);
}
+}
+
+/* Statically estimate the probability that a branch will be taken and produce
+ estimated profile. When profile feedback is present never executed portions
+ of function gets estimated. */
+
+void
+estimate_probability (struct loops *loops_info)
+{
+ basic_block bb;
+
+ connect_infinite_loops_to_exit ();
+ calculate_dominance_info (CDI_DOMINATORS);
+ calculate_dominance_info (CDI_POST_DOMINATORS);
+
+ predict_loops (loops_info, true);
iv_analysis_done ();
@@ -622,10 +779,216 @@ estimate_probability (struct loops *loops_info)
&& bb->succ->succ_next != NULL)
combine_predictions_for_insn (BB_END (bb), bb);
+ remove_fake_edges ();
+ /* Fill in the probability values in flowgraph based on the REG_BR_PROB
+ notes. */
+ FOR_EACH_BB (bb)
+ {
+ rtx last_insn = BB_END (bb);
+
+ if (!can_predict_insn_p (last_insn))
+ {
+ /* We can predict only conditional jumps at the moment.
+ Expect each edge to be equally probable.
+ ?? In the future we want to make abnormal edges improbable. */
+ int nedges = 0;
+ edge e;
+
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ nedges++;
+ if (e->probability != 0)
+ break;
+ }
+ if (!e)
+ for (e = bb->succ; e; e = e->succ_next)
+ e->probability = (REG_BR_PROB_BASE + nedges / 2) / nedges;
+ }
+ }
+ estimate_bb_frequencies (loops_info);
free_dominance_info (CDI_POST_DOMINATORS);
+}
+
+
+/* Predict using opcode of the last statement in basic block. */
+static void
+tree_predict_by_opcode (basic_block bb)
+{
+ tree stmt = last_stmt (bb);
+ edge then_edge;
+ tree cond;
+ tree op0;
+ tree type;
+
+ if (!stmt || TREE_CODE (stmt) != COND_EXPR)
+ return;
+ for (then_edge = bb->succ; then_edge; then_edge = then_edge->succ_next)
+ if (then_edge->flags & EDGE_TRUE_VALUE)
+ break;
+ cond = TREE_OPERAND (stmt, 0);
+ if (TREE_CODE_CLASS (TREE_CODE (cond)) != '<')
+ return;
+ op0 = TREE_OPERAND (cond, 0);
+ type = TREE_TYPE (op0);
+ /* Try "pointer heuristic."
+ A comparison ptr == 0 is predicted as false.
+ Similarly, a comparison ptr1 == ptr2 is predicted as false. */
+ if (POINTER_TYPE_P (type))
+ {
+ if (TREE_CODE (cond) == EQ_EXPR)
+ predict_edge_def (then_edge, PRED_TREE_POINTER, NOT_TAKEN);
+ else if (TREE_CODE (cond) == NE_EXPR)
+ predict_edge_def (then_edge, PRED_TREE_POINTER, TAKEN);
+ }
+ else
+
+ /* Try "opcode heuristic."
+ EQ tests are usually false and NE tests are usually true. Also,
+ most quantities are positive, so we can make the appropriate guesses
+ about signed comparisons against zero. */
+ switch (TREE_CODE (cond))
+ {
+ case EQ_EXPR:
+ case UNEQ_EXPR:
+ /* Floating point comparisons appears to behave in a very
+ unpredictable way because of special role of = tests in
+ FP code. */
+ if (FLOAT_TYPE_P (type))
+ ;
+ /* Comparisons with 0 are often used for booleans and there is
+ nothing useful to predict about them. */
+ else if (integer_zerop (op0)
+ || integer_zerop (TREE_OPERAND (cond, 1)))
+ ;
+ else
+ predict_edge_def (then_edge, PRED_TREE_OPCODE_NONEQUAL, NOT_TAKEN);
+ break;
+
+ case NE_EXPR:
+ /* Floating point comparisons appears to behave in a very
+ unpredictable way because of special role of = tests in
+ FP code. */
+ if (FLOAT_TYPE_P (type))
+ ;
+ /* Comparisons with 0 are often used for booleans and there is
+ nothing useful to predict about them. */
+ else if (integer_zerop (op0)
+ || integer_zerop (TREE_OPERAND (cond, 1)))
+ ;
+ else
+ predict_edge_def (then_edge, PRED_TREE_OPCODE_NONEQUAL, TAKEN);
+ break;
+
+ case ORDERED_EXPR:
+ predict_edge_def (then_edge, PRED_TREE_FPOPCODE, TAKEN);
+ break;
+
+ case UNORDERED_EXPR:
+ predict_edge_def (then_edge, PRED_TREE_FPOPCODE, NOT_TAKEN);
+ break;
+
+ case LE_EXPR:
+ case LT_EXPR:
+ if (integer_zerop (TREE_OPERAND (cond, 1))
+ || integer_onep (TREE_OPERAND (cond, 1))
+ || integer_all_onesp (TREE_OPERAND (cond, 1))
+ || real_zerop (TREE_OPERAND (cond, 1))
+ || real_onep (TREE_OPERAND (cond, 1))
+ || real_minus_onep (TREE_OPERAND (cond, 1)))
+ predict_edge_def (then_edge, PRED_TREE_OPCODE_POSITIVE, NOT_TAKEN);
+ break;
+
+ case GE_EXPR:
+ case GT_EXPR:
+ if (integer_zerop (TREE_OPERAND (cond, 1))
+ || integer_onep (TREE_OPERAND (cond, 1))
+ || integer_all_onesp (TREE_OPERAND (cond, 1))
+ || real_zerop (TREE_OPERAND (cond, 1))
+ || real_onep (TREE_OPERAND (cond, 1))
+ || real_minus_onep (TREE_OPERAND (cond, 1)))
+ predict_edge_def (then_edge, PRED_TREE_OPCODE_POSITIVE, TAKEN);
+ break;
+
+ default:
+ break;
+ }
+}
+
+/* Predict branch probabilities and estimate profile of the tree CFG. */
+static void
+tree_estimate_probability (void)
+{
+ basic_block bb;
+ struct loops loops_info;
+
+ flow_loops_find (&loops_info, LOOP_TREE);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ flow_loops_dump (&loops_info, dump_file, NULL, 0);
+
+ connect_infinite_loops_to_exit ();
+ calculate_dominance_info (CDI_DOMINATORS);
+ calculate_dominance_info (CDI_POST_DOMINATORS);
+
+ predict_loops (&loops_info, false);
+
+ FOR_EACH_BB (bb)
+ {
+ edge e;
+
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ /* Predict early returns to be probable, as we've already taken
+ care for error returns and other are often used for fast paths
+ trought function. */
+ if ((e->dest == EXIT_BLOCK_PTR
+ || (e->dest->succ && !e->dest->succ->succ_next
+ && e->dest->succ->dest == EXIT_BLOCK_PTR))
+ && !predicted_by_p (bb, PRED_NULL_RETURN)
+ && !predicted_by_p (bb, PRED_CONST_RETURN)
+ && !predicted_by_p (bb, PRED_NEGATIVE_RETURN)
+ && !last_basic_block_p (e->dest))
+ predict_edge_def (e, PRED_EARLY_RETURN, TAKEN);
+
+ /* Look for block we are guarding (ie we dominate it,
+ but it doesn't postdominate us). */
+ if (e->dest != EXIT_BLOCK_PTR && e->dest != bb
+ && dominated_by_p (CDI_DOMINATORS, e->dest, e->src)
+ && !dominated_by_p (CDI_POST_DOMINATORS, e->src, e->dest))
+ {
+ block_stmt_iterator bi;
+
+ /* The call heuristic claims that a guarded function call
+ is improbable. This is because such calls are often used
+ to signal exceptional situations such as printing error
+ messages. */
+ for (bi = bsi_start (e->dest); !bsi_end_p (bi);
+ bsi_next (&bi))
+ {
+ tree stmt = bsi_stmt (bi);
+ if ((TREE_CODE (stmt) == CALL_EXPR
+ || (TREE_CODE (stmt) == MODIFY_EXPR
+ && TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR))
+ /* Constant and pure calls are hardly used to signalize
+ something exceptional. */
+ && TREE_SIDE_EFFECTS (stmt))
+ {
+ predict_edge_def (e, PRED_CALL, NOT_TAKEN);
+ break;
+ }
+ }
+ }
+ }
+ tree_predict_by_opcode (bb);
+ }
+ FOR_EACH_BB (bb)
+ combine_predictions_for_bb (dump_file, bb);
+ estimate_bb_frequencies (&loops_info);
+ free_dominance_info (CDI_POST_DOMINATORS);
remove_fake_edges ();
- estimate_bb_frequencies (loops_info);
+ flow_loops_free (&loops_info);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ dump_tree_cfg (dump_file, dump_flags);
}
/* __builtin_expect dropped tokens into the insn stream describing expected
@@ -1138,31 +1501,6 @@ estimate_bb_frequencies (struct loops *loops)
}
mark_dfs_back_edges ();
- /* Fill in the probability values in flowgraph based on the REG_BR_PROB
- notes. */
- FOR_EACH_BB (bb)
- {
- rtx last_insn = BB_END (bb);
-
- if (!can_predict_insn_p (last_insn))
- {
- /* We can predict only conditional jumps at the moment.
- Expect each edge to be equally probable.
- ?? In the future we want to make abnormal edges improbable. */
- int nedges = 0;
- edge e;
-
- for (e = bb->succ; e; e = e->succ_next)
- {
- nedges++;
- if (e->probability != 0)
- break;
- }
- if (!e)
- for (e = bb->succ; e; e = e->succ_next)
- e->probability = (REG_BR_PROB_BASE + nedges / 2) / nedges;
- }
- }
ENTRY_BLOCK_PTR->succ->probability = REG_BR_PROB_BASE;
@@ -1251,3 +1589,20 @@ choose_function_section (void)
build_string (strlen (UNLIKELY_EXECUTED_TEXT_SECTION_NAME),
UNLIKELY_EXECUTED_TEXT_SECTION_NAME);
}
+
+
+struct tree_opt_pass pass_profile =
+{
+ "profile", /* name */
+ NULL, /* gate */
+ tree_estimate_probability, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_BRANCH_PROB, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */
+};
diff --git a/gcc/predict.def b/gcc/predict.def
index 25c51025e31..836d853b379 100644
--- a/gcc/predict.def
+++ b/gcc/predict.def
@@ -89,11 +89,15 @@ DEF_PREDICTOR (PRED_LOOP_HEADER, "loop header", HITRATE (64), 0)
/* Pointers are usually not NULL. */
DEF_PREDICTOR (PRED_POINTER, "pointer", HITRATE (81), 0)
+DEF_PREDICTOR (PRED_TREE_POINTER, "pointer (on trees)", HITRATE (81), 0)
/* NE is probable, EQ not etc... */
DEF_PREDICTOR (PRED_OPCODE_POSITIVE, "opcode values positive", HITRATE (79), 0)
DEF_PREDICTOR (PRED_OPCODE_NONEQUAL, "opcode values nonequal", HITRATE (71), 0)
DEF_PREDICTOR (PRED_FPOPCODE, "fp_opcode", HITRATE (90), 0)
+DEF_PREDICTOR (PRED_TREE_OPCODE_POSITIVE, "opcode values positive (on trees)", HITRATE (79), 0)
+DEF_PREDICTOR (PRED_TREE_OPCODE_NONEQUAL, "opcode values nonequal (on trees)", HITRATE (71), 0)
+DEF_PREDICTOR (PRED_TREE_FPOPCODE, "fp_opcode (on trees)", HITRATE (90), 0)
/* Branch guarding call is probably taken. */
DEF_PREDICTOR (PRED_CALL, "call", HITRATE (70), 0)
diff --git a/gcc/predict.h b/gcc/predict.h
index d0741dc704d..16817f9b5b6 100644
--- a/gcc/predict.h
+++ b/gcc/predict.h
@@ -18,6 +18,9 @@ along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
+#ifndef GCC_PREDICT_H
+#define GCC_PREDICT_H
+
#define DEF_PREDICTOR(ENUM, NAME, HITRATE, FLAGS) ENUM,
enum br_predictor
{
@@ -39,8 +42,4 @@ enum prediction
extern void predict_insn_def (rtx, enum br_predictor, enum prediction);
extern void predict_insn (rtx, enum br_predictor, int);
-/* Avoid unneeded dependency on basic_block.h. */
-#ifdef BASIC_BLOCK
-extern void predict_edge (edge, enum br_predictor, int);
-extern void predict_edge_def (edge, enum br_predictor, enum prediction);
-#endif
+#endif /* GCC_PREDICT_H */
diff --git a/gcc/pretty-print.c b/gcc/pretty-print.c
index 86d4cb82e6b..46cae27504c 100644
--- a/gcc/pretty-print.c
+++ b/gcc/pretty-print.c
@@ -91,7 +91,7 @@ pp_clear_state (pretty_printer *pp)
}
/* Flush the formatted text of PRETTY-PRINTER onto the attached stream. */
-static inline void
+void
pp_write_text_to_stream (pretty_printer *pp)
{
const char *text = pp_formatted_text (pp);
@@ -178,7 +178,7 @@ pp_base_indent (pretty_printer *pp)
%p: pointer.
%m: strerror(text->err_no) - does not consume a value from args_ptr.
%%: `%'.
- %*.s: a substring the length of which is specified by an integer.
+ %.*s: a substring the length of which is specified by an integer.
%H: location_t. */
void
pp_base_format_text (pretty_printer *pp, text_info *text)
diff --git a/gcc/pretty-print.h b/gcc/pretty-print.h
index 28179381314..8c568a42f4d 100644
--- a/gcc/pretty-print.h
+++ b/gcc/pretty-print.h
@@ -258,6 +258,7 @@ extern void pp_base_indent (pretty_printer *);
extern void pp_base_newline (pretty_printer *);
extern void pp_base_character (pretty_printer *, int);
extern void pp_base_string (pretty_printer *, const char *);
+extern void pp_write_text_to_stream (pretty_printer *pp);
extern void pp_base_maybe_space (pretty_printer *);
#endif /* GCC_PRETTY_PRINT_H */
diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c
index 6562afcc524..66f0a01f063 100644
--- a/gcc/print-rtl.c
+++ b/gcc/print-rtl.c
@@ -153,9 +153,6 @@ print_rtx (rtx in_rtx)
if (RTX_FLAG (in_rtx, unchanging))
fputs ("/u", outfile);
- if (RTX_FLAG (in_rtx, integrated))
- fputs ("/i", outfile);
-
if (RTX_FLAG (in_rtx, frame_related))
fputs ("/f", outfile);
@@ -165,6 +162,9 @@ print_rtx (rtx in_rtx)
if (RTX_FLAG (in_rtx, call))
fputs ("/c", outfile);
+ if (RTX_FLAG (in_rtx, return_val))
+ fputs ("/i", outfile);
+
if (GET_MODE (in_rtx) != VOIDmode)
{
/* Print REG_NOTE names for EXPR_LIST and INSN_LIST. */
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index 9dd9aaa2cd6..1d8ca961831 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -252,6 +252,8 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
fputs (" readonly", file);
if (!TYPE_P (node) && TREE_CONSTANT (node))
fputs (" constant", file);
+ if (TREE_INVARIANT (node))
+ fputs (" invariant", file);
if (TREE_ADDRESSABLE (node))
fputs (" addressable", file);
if (TREE_THIS_VOLATILE (node))
@@ -272,6 +274,8 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
fputs (" static", file);
if (TREE_DEPRECATED (node))
fputs (" deprecated", file);
+ if (TREE_VISITED (node))
+ fputs (" visited", file);
if (TREE_LANG_FLAG_0 (node))
fputs (" tree_0", file);
if (TREE_LANG_FLAG_1 (node))
@@ -565,15 +569,6 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
print_node_brief (file, "chain", TREE_CHAIN (node), indent + 4);
break;
- case 'b':
- print_node (file, "vars", BLOCK_VARS (node), indent + 4);
- print_node (file, "supercontext", BLOCK_SUPERCONTEXT (node), indent + 4);
- print_node (file, "subblocks", BLOCK_SUBBLOCKS (node), indent + 4);
- print_node (file, "chain", BLOCK_CHAIN (node), indent + 4);
- print_node (file, "abstract_origin",
- BLOCK_ABSTRACT_ORIGIN (node), indent + 4);
- break;
-
case 'e':
case '<':
case '1':
@@ -619,14 +614,6 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
}
}
- if (TREE_CODE (node) == EXPR_WITH_FILE_LOCATION)
- {
- indent_to (file, indent+4);
- fprintf (file, "%s:%d:%d",
- (EXPR_WFL_FILENAME_NODE (node ) ?
- EXPR_WFL_FILENAME (node) : "(no file info)"),
- EXPR_WFL_LINENO (node), EXPR_WFL_COLNO (node));
- }
print_node (file, "chain", TREE_CHAIN (node), indent + 4);
break;
@@ -737,6 +724,16 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
}
break;
+ case BLOCK:
+ print_node (file, "vars", BLOCK_VARS (node), indent + 4);
+ print_node (file, "supercontext", BLOCK_SUPERCONTEXT (node),
+ indent + 4);
+ print_node (file, "subblocks", BLOCK_SUBBLOCKS (node), indent + 4);
+ print_node (file, "chain", BLOCK_CHAIN (node), indent + 4);
+ print_node (file, "abstract_origin",
+ BLOCK_ABSTRACT_ORIGIN (node), indent + 4);
+ break;
+
default:
if (TREE_CODE_CLASS (TREE_CODE (node)) == 'x')
lang_hooks.print_xnode (file, node, indent);
@@ -746,5 +743,13 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
break;
}
+ if (EXPR_HAS_LOCATION (node))
+ {
+ indent_to (file, indent+4);
+ fprintf (file, "%s:%d",
+ EXPR_FILENAME (node),
+ EXPR_LINENO (node));
+ }
+
fprintf (file, ">");
}
diff --git a/gcc/profile.c b/gcc/profile.c
index 7095d1bcc43..0468a0f8284 100644
--- a/gcc/profile.c
+++ b/gcc/profile.c
@@ -39,7 +39,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
edges must be on the spanning tree. We also attempt to place
EDGE_CRITICAL edges on the spanning tree.
- The auxiliary file generated is <dumpbase>.bbg. The format is
+ The auxiliary files generated are <dumpbase>.gcno (at compile time)
+ and <dumpbase>.gcda (at run time). The format is
described in full in gcov-io.h. */
/* ??? Register allocation should use basic block execution counts to
@@ -62,6 +63,17 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "coverage.h"
#include "value-prof.h"
#include "tree.h"
+#include "cfghooks.h"
+#include "tree-flow.h"
+
+/* Hooks for profiling. */
+static struct profile_hooks* profile_hooks;
+
+/* File for profiling debug output. */
+static inline FILE*
+profile_dump_file (void) {
+ return profile_hooks->profile_dump_file ();
+}
/* Additional information about the edges we need. */
struct edge_info {
@@ -106,14 +118,6 @@ static int total_num_branches;
/* Forward declarations. */
static void find_spanning_tree (struct edge_list *);
-static rtx gen_edge_profiler (int);
-static rtx gen_interval_profiler (struct histogram_value *, unsigned,
- unsigned);
-static rtx gen_pow2_profiler (struct histogram_value *, unsigned, unsigned);
-static rtx gen_one_value_profiler (struct histogram_value *, unsigned,
- unsigned);
-static rtx gen_const_delta_profiler (struct histogram_value *, unsigned,
- unsigned);
static unsigned instrument_edges (struct edge_list *);
static void instrument_values (unsigned, struct histogram_value *);
static void compute_branch_probabilities (void);
@@ -147,17 +151,13 @@ instrument_edges (struct edge_list *el)
if (!inf->ignore && !inf->on_tree)
{
- rtx edge_profile;
-
if (e->flags & EDGE_ABNORMAL)
abort ();
if (dump_file)
fprintf (dump_file, "Edge %d to %d instrumented%s\n",
e->src->index, e->dest->index,
EDGE_CRITICAL_P (e) ? " (and split)" : "");
- edge_profile = gen_edge_profiler (num_instr_edges++);
- insert_insn_on_edge (edge_profile, e);
- rebuild_jump_labels (e->insns);
+ (profile_hooks->gen_edge_profiler) (num_instr_edges++, e);
}
}
}
@@ -172,16 +172,12 @@ instrument_edges (struct edge_list *el)
static void
instrument_values (unsigned n_values, struct histogram_value *values)
{
- rtx sequence;
unsigned i, t;
- edge e;
/* Emit code to generate the histograms before the insns. */
for (i = 0; i < n_values; i++)
{
- e = split_block (BLOCK_FOR_INSN (values[i].insn),
- PREV_INSN (values[i].insn));
switch (values[i].type)
{
case HIST_TYPE_INTERVAL:
@@ -209,26 +205,24 @@ instrument_values (unsigned n_values, struct histogram_value *values)
switch (values[i].type)
{
case HIST_TYPE_INTERVAL:
- sequence = gen_interval_profiler (values + i, t, 0);
+ (profile_hooks->gen_interval_profiler) (values + i, t, 0);
break;
case HIST_TYPE_POW2:
- sequence = gen_pow2_profiler (values + i, t, 0);
+ (profile_hooks->gen_pow2_profiler) (values + i, t, 0);
break;
case HIST_TYPE_SINGLE_VALUE:
- sequence = gen_one_value_profiler (values + i, t, 0);
+ (profile_hooks->gen_one_value_profiler) (values + i, t, 0);
break;
case HIST_TYPE_CONST_DELTA:
- sequence = gen_const_delta_profiler (values + i, t, 0);
+ (profile_hooks->gen_const_delta_profiler) (values + i, t, 0);
break;
default:
abort ();
}
-
- safe_insert_insn_on_edge (sequence, e);
}
}
@@ -512,13 +506,7 @@ compute_branch_probabilities (void)
|| (e->count > bb->count
&& e->dest != EXIT_BLOCK_PTR))
{
- rtx insn = BB_END (bb);
-
- while (GET_CODE (insn) != CALL_INSN
- && insn != BB_HEAD (bb)
- && keep_with_call_p (insn))
- insn = PREV_INSN (insn);
- if (GET_CODE (insn) == CALL_INSN)
+ if (block_ends_with_call_p (bb))
e->count = e->count < 0 ? 0 : bb->count;
}
if (e->count < 0 || e->count > bb->count)
@@ -534,7 +522,7 @@ compute_branch_probabilities (void)
for (e = bb->succ; e; e = e->succ_next)
e->probability = (e->count * REG_BR_PROB_BASE + bb->count / 2) / bb->count;
if (bb->index >= 0
- && any_condjump_p (BB_END (bb))
+ && block_ends_with_condjump_p (bb)
&& bb->succ->succ_next)
{
int prob;
@@ -554,15 +542,19 @@ compute_branch_probabilities (void)
index = 19;
hist_br_prob[index]++;
- note = find_reg_note (BB_END (bb), REG_BR_PROB, 0);
- /* There may be already note put by some other pass, such
- as builtin_expect expander. */
- if (note)
- XEXP (note, 0) = GEN_INT (prob);
- else
- REG_NOTES (BB_END (bb))
- = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
- REG_NOTES (BB_END (bb)));
+ /* Do this for RTL only. */
+ if (!ir_type ())
+ {
+ note = find_reg_note (BB_END (bb), REG_BR_PROB, 0);
+ /* There may be already note put by some other pass, such
+ as builtin_expect expander. */
+ if (note)
+ XEXP (note, 0) = GEN_INT (prob);
+ else
+ REG_NOTES (BB_END (bb))
+ = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
+ REG_NOTES (BB_END (bb)));
+ }
num_branches++;
}
}
@@ -594,7 +586,7 @@ compute_branch_probabilities (void)
e->probability = REG_BR_PROB_BASE / total;
}
if (bb->index >= 0
- && any_condjump_p (BB_END (bb))
+ && block_ends_with_condjump_p (bb)
&& bb->succ->succ_next)
num_branches++, num_never_executed;
}
@@ -664,15 +656,21 @@ compute_value_histograms (unsigned n_values, struct histogram_value *values)
rtx hist_list = NULL_RTX;
t = (int) (values[i].type);
- aact_count = act_count[t];
- act_count[t] += values[i].n_counters;
- for (j = values[i].n_counters; j > 0; j--)
- hist_list = alloc_EXPR_LIST (0, GEN_INT (aact_count[j - 1]), hist_list);
- hist_list = alloc_EXPR_LIST (0, copy_rtx (values[i].value), hist_list);
- hist_list = alloc_EXPR_LIST (0, GEN_INT (values[i].type), hist_list);
- REG_NOTES (values[i].insn) =
- alloc_EXPR_LIST (REG_VALUE_PROFILE, hist_list,
- REG_NOTES (values[i].insn));
+ /* FIXME: make this work for trees. */
+ if (!ir_type ())
+ {
+ aact_count = act_count[t];
+ act_count[t] += values[i].n_counters;
+ for (j = values[i].n_counters; j > 0; j--)
+ hist_list = alloc_EXPR_LIST (0, GEN_INT (aact_count[j - 1]),
+ hist_list);
+ hist_list = alloc_EXPR_LIST (0,
+ copy_rtx ((rtx)values[i].value), hist_list);
+ hist_list = alloc_EXPR_LIST (0, GEN_INT (values[i].type), hist_list);
+ REG_NOTES ((rtx)values[i].insn) =
+ alloc_EXPR_LIST (REG_VALUE_PROFILE, hist_list,
+ REG_NOTES ((rtx)values[i].insn));
+ }
}
for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
@@ -885,7 +883,9 @@ branch_prob (void)
}
/* Line numbers. */
- if (coverage_begin_output ())
+ /* FIXME: make this work for trees. (Line numbers are in location_t
+ objects, but aren't always attached to the obvious tree...) */
+ if (coverage_begin_output () && !ir_type ())
{
char const *prev_file_name = NULL;
gcov_position_t offset;
@@ -953,16 +953,13 @@ branch_prob (void)
}
}
}
+
ENTRY_BLOCK_PTR->index = ENTRY_BLOCK;
EXIT_BLOCK_PTR->index = EXIT_BLOCK;
#undef BB_TO_GCOV_INDEX
if (flag_profile_values)
- {
- life_analysis (get_insns (), NULL, PROP_DEATH_NOTES);
- find_values_to_profile (&n_values, &values);
- allocate_reg_info (max_reg_num (), FALSE, FALSE);
- }
+ find_values_to_profile (&n_values, &values);
if (flag_branch_probabilities)
{
@@ -971,7 +968,7 @@ branch_prob (void)
compute_value_histograms (n_values, values);
}
- /* For each edge not on the spanning tree, add counting code as rtl. */
+ /* For each edge not on the spanning tree, add counting code. */
if (profile_arc_flag
&& coverage_counter_alloc (GCOV_COUNTER_ARCS, num_instrumented))
{
@@ -984,17 +981,26 @@ branch_prob (void)
instrument_values (n_values, values);
/* Commit changes done by instrumentation. */
- commit_edge_insertions_watch_calls ();
- allocate_reg_info (max_reg_num (), FALSE, FALSE);
+ if (ir_type ())
+ bsi_commit_edge_inserts ((int *)NULL);
+ else
+ {
+ commit_edge_insertions_watch_calls ();
+ allocate_reg_info (max_reg_num (), FALSE, FALSE);
+ }
}
remove_fake_edges ();
free_aux_for_edges ();
- /* Re-merge split basic blocks and the mess introduced by
- insert_insn_on_edge. */
- cleanup_cfg (profile_arc_flag ? CLEANUP_EXPENSIVE : 0);
- if (dump_file)
- dump_flow_info (dump_file);
+
+ if (!ir_type ())
+ {
+ /* Re-merge split basic blocks and the mess introduced by
+ insert_insn_on_edge. */
+ cleanup_cfg (profile_arc_flag ? CLEANUP_EXPENSIVE : 0);
+ if (profile_dump_file())
+ dump_flow_info (profile_dump_file());
+ }
free_edge_list (el);
}
@@ -1168,324 +1174,22 @@ end_branch_prob (void)
}
}
-
-/* Output instructions as RTL to increment the edge execution count. */
-
-static rtx
-gen_edge_profiler (int edgeno)
-{
- rtx ref = coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
- rtx tmp;
- enum machine_mode mode = GET_MODE (ref);
- rtx sequence;
-
- start_sequence ();
- ref = validize_mem (ref);
-
- tmp = expand_simple_binop (mode, PLUS, ref, const1_rtx,
- ref, 0, OPTAB_WIDEN);
-
- if (tmp != ref)
- emit_move_insn (copy_rtx (ref), tmp);
+/* Set up hooks to enable tree-based profiling. */
- sequence = get_insns ();
- end_sequence ();
- return sequence;
-}
-
-/* Output instructions as RTL to increment the interval histogram counter.
- VALUE is the expression whose value is profiled. TAG is the tag of the
- section for counters, BASE is offset of the counter position. */
-
-static rtx
-gen_interval_profiler (struct histogram_value *value, unsigned tag,
- unsigned base)
-{
- unsigned gcov_size = tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE), 1);
- enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
- rtx mem_ref, tmp, tmp1, mr, val;
- rtx sequence;
- rtx more_label = gen_label_rtx ();
- rtx less_label = gen_label_rtx ();
- rtx end_of_code_label = gen_label_rtx ();
- int per_counter = gcov_size / BITS_PER_UNIT;
-
- start_sequence ();
-
- if (value->seq)
- emit_insn (value->seq);
-
- mr = gen_reg_rtx (Pmode);
-
- tmp = coverage_counter_ref (tag, base);
- tmp = force_reg (Pmode, XEXP (tmp, 0));
-
- val = expand_simple_binop (value->mode, MINUS,
- copy_rtx (value->value),
- GEN_INT (value->hdata.intvl.int_start),
- NULL_RTX, 0, OPTAB_WIDEN);
-
- if (value->hdata.intvl.may_be_more)
- do_compare_rtx_and_jump (copy_rtx (val), GEN_INT (value->hdata.intvl.steps),
- GE, 0, value->mode, NULL_RTX, NULL_RTX, more_label);
- if (value->hdata.intvl.may_be_less)
- do_compare_rtx_and_jump (copy_rtx (val), const0_rtx, LT, 0, value->mode,
- NULL_RTX, NULL_RTX, less_label);
-
- /* We are in range. */
- tmp1 = expand_simple_binop (value->mode, MULT,
- copy_rtx (val), GEN_INT (per_counter),
- NULL_RTX, 0, OPTAB_WIDEN);
- tmp1 = expand_simple_binop (Pmode, PLUS, copy_rtx (tmp), tmp1, mr,
- 0, OPTAB_WIDEN);
- if (tmp1 != mr)
- emit_move_insn (copy_rtx (mr), tmp1);
-
- if (value->hdata.intvl.may_be_more
- || value->hdata.intvl.may_be_less)
- {
- emit_jump_insn (gen_jump (end_of_code_label));
- emit_barrier ();
- }
-
- /* Above the interval. */
- if (value->hdata.intvl.may_be_more)
- {
- emit_label (more_label);
- tmp1 = expand_simple_binop (Pmode, PLUS, copy_rtx (tmp),
- GEN_INT (per_counter * value->hdata.intvl.steps),
- mr, 0, OPTAB_WIDEN);
- if (tmp1 != mr)
- emit_move_insn (copy_rtx (mr), tmp1);
- if (value->hdata.intvl.may_be_less)
- {
- emit_jump_insn (gen_jump (end_of_code_label));
- emit_barrier ();
- }
- }
-
- /* Below the interval. */
- if (value->hdata.intvl.may_be_less)
- {
- emit_label (less_label);
- tmp1 = expand_simple_binop (Pmode, PLUS, copy_rtx (tmp),
- GEN_INT (per_counter * (value->hdata.intvl.steps
- + (value->hdata.intvl.may_be_more ? 1 : 0))),
- mr, 0, OPTAB_WIDEN);
- if (tmp1 != mr)
- emit_move_insn (copy_rtx (mr), tmp1);
- }
-
- if (value->hdata.intvl.may_be_more
- || value->hdata.intvl.may_be_less)
- emit_label (end_of_code_label);
-
- mem_ref = validize_mem (gen_rtx_MEM (mode, mr));
-
- tmp = expand_simple_binop (mode, PLUS, copy_rtx (mem_ref), const1_rtx,
- mem_ref, 0, OPTAB_WIDEN);
-
- if (tmp != mem_ref)
- emit_move_insn (copy_rtx (mem_ref), tmp);
-
- sequence = get_insns ();
- end_sequence ();
- rebuild_jump_labels (sequence);
- return sequence;
-}
-
-/* Output instructions as RTL to increment the power of two histogram counter.
- VALUE is the expression whose value is profiled. TAG is the tag of the
- section for counters, BASE is offset of the counter position. */
-
-static rtx
-gen_pow2_profiler (struct histogram_value *value, unsigned tag, unsigned base)
-{
- unsigned gcov_size = tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE), 1);
- enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
- rtx mem_ref, tmp, mr, uval;
- rtx sequence;
- rtx end_of_code_label = gen_label_rtx ();
- rtx loop_label = gen_label_rtx ();
- int per_counter = gcov_size / BITS_PER_UNIT;
-
- start_sequence ();
-
- if (value->seq)
- emit_insn (value->seq);
-
- mr = gen_reg_rtx (Pmode);
- tmp = coverage_counter_ref (tag, base);
- tmp = force_reg (Pmode, XEXP (tmp, 0));
- emit_move_insn (mr, tmp);
-
- uval = gen_reg_rtx (value->mode);
- emit_move_insn (uval, copy_rtx (value->value));
-
- /* Check for non-power of 2. */
- if (value->hdata.pow2.may_be_other)
- {
- do_compare_rtx_and_jump (copy_rtx (uval), const0_rtx, LE, 0, value->mode,
- NULL_RTX, NULL_RTX, end_of_code_label);
- tmp = expand_simple_binop (value->mode, PLUS, copy_rtx (uval),
- constm1_rtx, NULL_RTX, 0, OPTAB_WIDEN);
- tmp = expand_simple_binop (value->mode, AND, copy_rtx (uval), tmp,
- NULL_RTX, 0, OPTAB_WIDEN);
- do_compare_rtx_and_jump (tmp, const0_rtx, NE, 0, value->mode, NULL_RTX,
- NULL_RTX, end_of_code_label);
- }
-
- /* Count log_2(value). */
- emit_label (loop_label);
-
- tmp = expand_simple_binop (Pmode, PLUS, copy_rtx (mr), GEN_INT (per_counter), mr, 0, OPTAB_WIDEN);
- if (tmp != mr)
- emit_move_insn (copy_rtx (mr), tmp);
-
- tmp = expand_simple_binop (value->mode, ASHIFTRT, copy_rtx (uval), const1_rtx,
- uval, 0, OPTAB_WIDEN);
- if (tmp != uval)
- emit_move_insn (copy_rtx (uval), tmp);
-
- do_compare_rtx_and_jump (copy_rtx (uval), const0_rtx, NE, 0, value->mode,
- NULL_RTX, NULL_RTX, loop_label);
-
- /* Increase the counter. */
- emit_label (end_of_code_label);
-
- mem_ref = validize_mem (gen_rtx_MEM (mode, mr));
-
- tmp = expand_simple_binop (mode, PLUS, copy_rtx (mem_ref), const1_rtx,
- mem_ref, 0, OPTAB_WIDEN);
-
- if (tmp != mem_ref)
- emit_move_insn (copy_rtx (mem_ref), tmp);
-
- sequence = get_insns ();
- end_sequence ();
- rebuild_jump_labels (sequence);
- return sequence;
-}
-
-/* Output instructions as RTL for code to find the most common value.
- VALUE is the expression whose value is profiled. TAG is the tag of the
- section for counters, BASE is offset of the counter position. */
-
-static rtx
-gen_one_value_profiler (struct histogram_value *value, unsigned tag,
- unsigned base)
+void
+tree_register_profile_hooks (void)
{
- unsigned gcov_size = tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE), 1);
- enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
- rtx stored_value_ref, counter_ref, all_ref, stored_value, counter, all;
- rtx tmp, uval;
- rtx sequence;
- rtx same_label = gen_label_rtx ();
- rtx zero_label = gen_label_rtx ();
- rtx end_of_code_label = gen_label_rtx ();
-
- start_sequence ();
-
- if (value->seq)
- emit_insn (value->seq);
-
- stored_value_ref = coverage_counter_ref (tag, base);
- counter_ref = coverage_counter_ref (tag, base + 1);
- all_ref = coverage_counter_ref (tag, base + 2);
- stored_value = validize_mem (stored_value_ref);
- counter = validize_mem (counter_ref);
- all = validize_mem (all_ref);
-
- uval = gen_reg_rtx (mode);
- convert_move (uval, copy_rtx (value->value), 0);
-
- /* Check if the stored value matches. */
- do_compare_rtx_and_jump (copy_rtx (uval), copy_rtx (stored_value), EQ,
- 0, mode, NULL_RTX, NULL_RTX, same_label);
-
- /* Does not match; check whether the counter is zero. */
- do_compare_rtx_and_jump (copy_rtx (counter), const0_rtx, EQ, 0, mode,
- NULL_RTX, NULL_RTX, zero_label);
-
- /* The counter is not zero yet. */
- tmp = expand_simple_binop (mode, PLUS, copy_rtx (counter), constm1_rtx,
- counter, 0, OPTAB_WIDEN);
-
- if (tmp != counter)
- emit_move_insn (copy_rtx (counter), tmp);
-
- emit_jump_insn (gen_jump (end_of_code_label));
- emit_barrier ();
-
- emit_label (zero_label);
- /* Set new value. */
- emit_move_insn (copy_rtx (stored_value), copy_rtx (uval));
-
- emit_label (same_label);
- /* Increase the counter. */
- tmp = expand_simple_binop (mode, PLUS, copy_rtx (counter), const1_rtx,
- counter, 0, OPTAB_WIDEN);
-
- if (tmp != counter)
- emit_move_insn (copy_rtx (counter), tmp);
-
- emit_label (end_of_code_label);
-
- /* Increase the counter of all executions; this seems redundant given
- that ve have counts for edges in cfg, but it may happen that some
- optimization will change the counts for the block (either because
- it is unable to update them correctly, or because it will duplicate
- the block or its part). */
- tmp = expand_simple_binop (mode, PLUS, copy_rtx (all), const1_rtx,
- all, 0, OPTAB_WIDEN);
-
- if (tmp != all)
- emit_move_insn (copy_rtx (all), tmp);
- sequence = get_insns ();
- end_sequence ();
- rebuild_jump_labels (sequence);
- return sequence;
+ profile_hooks = &tree_profile_hooks;
+ if (!ir_type ())
+ abort ();
}
-/* Output instructions as RTL for code to find the most common value of
- a difference between two evaluations of an expression.
- VALUE is the expression whose value is profiled. TAG is the tag of the
- section for counters, BASE is offset of the counter position. */
+/* Set up hooks to enable RTL-based profiling. */
-static rtx
-gen_const_delta_profiler (struct histogram_value *value, unsigned tag,
- unsigned base)
+void
+rtl_register_profile_hooks (void)
{
- struct histogram_value one_value_delta;
- unsigned gcov_size = tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE), 1);
- enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
- rtx stored_value_ref, stored_value, tmp, uval;
- rtx sequence;
-
- start_sequence ();
-
- if (value->seq)
- emit_insn (value->seq);
-
- stored_value_ref = coverage_counter_ref (tag, base);
- stored_value = validize_mem (stored_value_ref);
-
- uval = gen_reg_rtx (mode);
- convert_move (uval, copy_rtx (value->value), 0);
- tmp = expand_simple_binop (mode, MINUS,
- copy_rtx (uval), copy_rtx (stored_value),
- NULL_RTX, 0, OPTAB_WIDEN);
-
- one_value_delta.value = tmp;
- one_value_delta.mode = mode;
- one_value_delta.seq = NULL_RTX;
- one_value_delta.insn = value->insn;
- one_value_delta.type = HIST_TYPE_SINGLE_VALUE;
- emit_insn (gen_one_value_profiler (&one_value_delta, tag, base + 1));
-
- emit_move_insn (copy_rtx (stored_value), uval);
- sequence = get_insns ();
- end_sequence ();
- rebuild_jump_labels (sequence);
- return sequence;
+ profile_hooks = &rtl_profile_hooks;
+ if (ir_type ())
+ abort ();
}
diff --git a/gcc/ra-debug.c b/gcc/ra-debug.c
index 4936898ae8b..16d2a589617 100644
--- a/gcc/ra-debug.c
+++ b/gcc/ra-debug.c
@@ -495,20 +495,25 @@ ra_print_rtx (FILE *file, rtx x, int with_pn)
switch (GET_RTX_CLASS (code))
{
case RTX_UNARY:
- ra_print_rtx_1op (file, x);
+ ra_print_rtx_1op (file, x);
+ break;
case RTX_BIN_ARITH:
case RTX_COMM_ARITH:
case RTX_COMPARE:
case RTX_COMM_COMPARE:
- ra_print_rtx_2op (file, x);
+ ra_print_rtx_2op (file, x);
+ break;
case RTX_TERNARY:
case RTX_BITFIELD_OPS:
- ra_print_rtx_3op (file, x);
+ ra_print_rtx_3op (file, x);
+ break;
case RTX_OBJ:
case RTX_CONST_OBJ:
- ra_print_rtx_object (file, x);
+ ra_print_rtx_object (file, x);
+ break;
default:
- print_inline_rtx (file, x, 0);
+ print_inline_rtx (file, x, 0);
+ break;
}
}
diff --git a/gcc/ra-rewrite.c b/gcc/ra-rewrite.c
index 6c6a53d27b6..7479860798e 100644
--- a/gcc/ra-rewrite.c
+++ b/gcc/ra-rewrite.c
@@ -1130,6 +1130,8 @@ rewrite_program2 (bitmap new_deaths)
struct ra_insn_info info;
unsigned int n;
+ memset (&info, 0, sizeof info);
+
if (INSN_P (insn) && BLOCK_FOR_INSN (insn) != last_bb)
{
int index = BLOCK_FOR_INSN (insn)->index + 2;
diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c
index 21ad6dea418..d17235f5f61 100644
--- a/gcc/read-rtl.c
+++ b/gcc/read-rtl.c
@@ -651,26 +651,28 @@ again:
break;
case 'S':
- /* 'S' is an optional string: if a closeparen follows,
- just store NULL for this element. */
- c = read_skip_spaces (infile);
- ungetc (c, infile);
- if (c == ')')
- {
- XSTR (return_rtx, i) = 0;
- break;
- }
-
case 'T':
case 's':
{
char *stringbuf;
+ int star_if_braced;
+
+ c = read_skip_spaces (infile);
+ ungetc (c, infile);
+ if (c == ')')
+ {
+ /* 'S' fields are optional and should be NULL if no string
+ was given. Also allow normal 's' and 'T' strings to be
+ omitted, treating them in the same way as empty strings. */
+ XSTR (return_rtx, i) = (format_ptr[-1] == 'S' ? NULL : "");
+ break;
+ }
/* The output template slot of a DEFINE_INSN,
DEFINE_INSN_AND_SPLIT, or DEFINE_PEEPHOLE automatically
gets a star inserted as its first character, if it is
written with a brace block instead of a string constant. */
- int star_if_braced = (format_ptr[-1] == 'T');
+ star_if_braced = (format_ptr[-1] == 'T');
stringbuf = read_string (&rtl_obstack, infile, star_if_braced);
diff --git a/gcc/recog.c b/gcc/recog.c
index 6d6135a5658..d7c95072400 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -1114,12 +1114,6 @@ immediate_operand (rtx op, enum machine_mode mode)
&& trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
return 0;
- /* Accept CONSTANT_P_RTX, since it will be gone by CSE1 and
- result in 0/1. It seems a safe assumption that this is
- in range for everyone. */
- if (GET_CODE (op) == CONSTANT_P_RTX)
- return 1;
-
return (CONSTANT_P (op)
&& (GET_MODE (op) == mode || mode == VOIDmode
|| GET_MODE (op) == VOIDmode)
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index f238267987a..8314b21ce35 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -249,6 +249,7 @@ static void remove_regno_note (rtx, enum reg_note, unsigned int);
static int get_hard_regnum (stack, rtx);
static rtx emit_pop_insn (rtx, stack, rtx, enum emit_where);
static void emit_swap_insn (rtx, stack, rtx);
+static void swap_to_top(rtx, stack, rtx, rtx);
static bool move_for_stack_reg (rtx, stack, rtx);
static int swap_rtx_condition_1 (rtx);
static int swap_rtx_condition (rtx);
@@ -1034,6 +1035,54 @@ emit_swap_insn (rtx insn, stack regstack, rtx reg)
emit_insn_before (swap_rtx, insn);
}
+/* Emit an insns before INSN to swap virtual register SRC1 with
+ the top of stack and virtual register SRC2 with second stack
+ slot. REGSTACK is the stack state before the swaps, and
+ is updated to reflect the swaps. A swap insn is represented as a
+ PARALLEL of two patterns: each pattern moves one reg to the other.
+
+ If SRC1 and/or SRC2 are already at the right place, no swap insn
+ is emitted. */
+
+static void
+swap_to_top (rtx insn, stack regstack, rtx src1, rtx src2)
+{
+ struct stack_def temp_stack;
+ int regno, j, k, temp;
+
+ temp_stack = *regstack;
+
+ /* Place operand 1 at the top of stack. */
+ regno = get_hard_regnum (&temp_stack, src1);
+ if (regno < 0)
+ abort ();
+ if (regno != FIRST_STACK_REG)
+ {
+ k = temp_stack.top - (regno - FIRST_STACK_REG);
+ j = temp_stack.top;
+
+ temp = temp_stack.reg[k];
+ temp_stack.reg[k] = temp_stack.reg[j];
+ temp_stack.reg[j] = temp;
+ }
+
+ /* Place operand 2 next on the stack. */
+ regno = get_hard_regnum (&temp_stack, src2);
+ if (regno < 0)
+ abort ();
+ if (regno != FIRST_STACK_REG + 1)
+ {
+ k = temp_stack.top - (regno - FIRST_STACK_REG);
+ j = temp_stack.top - 1;
+
+ temp = temp_stack.reg[k];
+ temp_stack.reg[k] = temp_stack.reg[j];
+ temp_stack.reg[j] = temp;
+ }
+
+ change_stack (insn, regstack, &temp_stack, EMIT_BEFORE);
+}
+
/* Handle a move to or from a stack register in PAT, which is in INSN.
REGSTACK is the current stack. Return whether a control flow insn
was deleted in the process. */
@@ -1684,24 +1733,21 @@ subst_stack_regs_pat (rtx insn, stack regstack, rtx pat)
emit_swap_insn (insn, regstack, *src1);
+ /* Input should never die, it is
+ replaced with output. */
src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
+ if (src1_note)
+ abort();
if (STACK_REG_P (*dest))
replace_reg (dest, FIRST_STACK_REG);
- if (src1_note)
- {
- replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
- regstack->top--;
- CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1));
- }
-
replace_reg (src1, FIRST_STACK_REG);
break;
case UNSPEC_FPATAN:
case UNSPEC_FYL2X:
- case UNSPEC_FSCALE:
+ case UNSPEC_FYL2XP1:
/* These insns operate on the top two stack slots. */
src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
@@ -1710,42 +1756,7 @@ subst_stack_regs_pat (rtx insn, stack regstack, rtx pat)
src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
- {
- struct stack_def temp_stack;
- int regno, j, k, temp;
-
- temp_stack = *regstack;
-
- /* Place operand 1 at the top of stack. */
- regno = get_hard_regnum (&temp_stack, *src1);
- if (regno < 0)
- abort ();
- if (regno != FIRST_STACK_REG)
- {
- k = temp_stack.top - (regno - FIRST_STACK_REG);
- j = temp_stack.top;
-
- temp = temp_stack.reg[k];
- temp_stack.reg[k] = temp_stack.reg[j];
- temp_stack.reg[j] = temp;
- }
-
- /* Place operand 2 next on the stack. */
- regno = get_hard_regnum (&temp_stack, *src2);
- if (regno < 0)
- abort ();
- if (regno != FIRST_STACK_REG + 1)
- {
- k = temp_stack.top - (regno - FIRST_STACK_REG);
- j = temp_stack.top - 1;
-
- temp = temp_stack.reg[k];
- temp_stack.reg[k] = temp_stack.reg[j];
- temp_stack.reg[j] = temp;
- }
-
- change_stack (insn, regstack, &temp_stack, EMIT_BEFORE);
- }
+ swap_to_top (insn, regstack, *src1, *src2);
replace_reg (src1, FIRST_STACK_REG);
replace_reg (src2, FIRST_STACK_REG + 1);
@@ -1768,7 +1779,71 @@ subst_stack_regs_pat (rtx insn, stack regstack, rtx pat)
replace_reg (dest, FIRST_STACK_REG);
break;
+ case UNSPEC_FSCALE_FRACT:
+ case UNSPEC_FPREM_F:
+ case UNSPEC_FPREM1_F:
+ /* These insns operate on the top two stack slots.
+ first part of double input, double output insn. */
+
+ src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
+ src2 = get_true_reg (&XVECEXP (pat_src, 0, 1));
+
+ src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
+ src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
+
+ /* Inputs should never die, they are
+ replaced with outputs. */
+ if ((src1_note) || (src2_note))
+ abort();
+
+ swap_to_top (insn, regstack, *src1, *src2);
+
+ /* Push the result back onto stack. Empty stack slot
+ will be filled in second part of insn. */
+ if (STACK_REG_P (*dest)) {
+ regstack->reg[regstack->top] = REGNO (*dest);
+ SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
+ replace_reg (dest, FIRST_STACK_REG);
+ }
+
+ replace_reg (src1, FIRST_STACK_REG);
+ replace_reg (src2, FIRST_STACK_REG + 1);
+ break;
+
+ case UNSPEC_FSCALE_EXP:
+ case UNSPEC_FPREM_U:
+ case UNSPEC_FPREM1_U:
+ /* These insns operate on the top two stack slots./
+ second part of double input, double output insn. */
+
+ src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
+ src2 = get_true_reg (&XVECEXP (pat_src, 0, 1));
+
+ src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
+ src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
+
+ /* Inputs should never die, they are
+ replaced with outputs. */
+ if ((src1_note) || (src2_note))
+ abort();
+
+ swap_to_top (insn, regstack, *src1, *src2);
+
+ /* Push the result back onto stack. Fill empty slot from
+ first part of insn and fix top of stack pointer. */
+ if (STACK_REG_P (*dest)) {
+ regstack->reg[regstack->top - 1] = REGNO (*dest);
+ SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
+ replace_reg (dest, FIRST_STACK_REG + 1);
+ }
+
+ replace_reg (src1, FIRST_STACK_REG);
+ replace_reg (src2, FIRST_STACK_REG + 1);
+ break;
+
case UNSPEC_SINCOS_COS:
+ case UNSPEC_TAN_ONE:
+ case UNSPEC_XTRACT_FRACT:
/* These insns operate on the top two stack slots,
first part of one input, double output insn. */
@@ -1776,7 +1851,11 @@ subst_stack_regs_pat (rtx insn, stack regstack, rtx pat)
emit_swap_insn (insn, regstack, *src1);
+ /* Input should never die, it is
+ replaced with output. */
src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
+ if (src1_note)
+ abort();
/* Push the result back onto stack. Empty stack slot
will be filled in second part of insn. */
@@ -1786,21 +1865,24 @@ subst_stack_regs_pat (rtx insn, stack regstack, rtx pat)
replace_reg (dest, FIRST_STACK_REG);
}
- if (src1_note)
- {
- replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
- regstack->top--;
- CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1));
- }
replace_reg (src1, FIRST_STACK_REG);
break;
case UNSPEC_SINCOS_SIN:
+ case UNSPEC_TAN_TAN:
+ case UNSPEC_XTRACT_EXP:
+ /* These insns operate on the top two stack slots,
+ second part of one input, double output insn. */
+
src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
emit_swap_insn (insn, regstack, *src1);
+ /* Input should never die, it is
+ replaced with output. */
src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
+ if (src1_note)
+ abort();
/* Push the result back onto stack. Fill empty slot from
first part of insn and fix top of stack pointer. */
@@ -1812,13 +1894,6 @@ subst_stack_regs_pat (rtx insn, stack regstack, rtx pat)
regstack->top++;
}
- if (src1_note)
- {
- replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
- regstack->top--;
- CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1));
- }
-
replace_reg (src1, FIRST_STACK_REG);
break;
@@ -2975,7 +3050,7 @@ convert_regs (FILE *file)
/* ??? Future: process inner loops first, and give them arbitrary
initial stacks which emit_swap_insn can modify. This ought to
- prevent double fxch that aften appears at the head of a loop. */
+ prevent double fxch that often appears at the head of a loop. */
/* Process all blocks reachable from all entry points. */
for (e = ENTRY_BLOCK_PTR->succ; e ; e = e->succ_next)
diff --git a/gcc/regs.h b/gcc/regs.h
index e4b78c7531d..c100bdeabac 100644
--- a/gcc/regs.h
+++ b/gcc/regs.h
@@ -19,6 +19,8 @@ along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
+#ifndef GCC_REGS_H
+#define GCC_REGS_H
#include "varray.h"
#include "hard-reg-set.h"
@@ -227,3 +229,5 @@ extern void allocate_reg_info (size_t, int, int);
/* Specify number of hard registers given machine mode occupy. */
extern unsigned char hard_regno_nregs[FIRST_PSEUDO_REGISTER][MAX_MACHINE_MODE];
+
+#endif /* GCC_REGS_H */
diff --git a/gcc/reload.c b/gcc/reload.c
index f1682f73aee..ae211302efa 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -2265,9 +2265,8 @@ decompose (rtx x)
struct decomposition val;
int all_const = 0;
- val.reg_flag = 0;
- val.safe = 0;
- val.base = 0;
+ memset (&val, 0, sizeof (val));
+
if (GET_CODE (x) == MEM)
{
rtx base = NULL_RTX, offset = 0;
diff --git a/gcc/reload1.c b/gcc/reload1.c
index ce7bf83526e..c848ce67101 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -417,6 +417,7 @@ static void emit_output_reload_insns (struct insn_chain *, struct reload *,
int);
static void do_input_reload (struct insn_chain *, struct reload *, int);
static void do_output_reload (struct insn_chain *, struct reload *, int);
+static bool inherit_piecemeal_p (int, int);
static void emit_reload_insns (struct insn_chain *);
static void delete_output_reload (rtx, int, int);
static void delete_address_reloads (rtx, rtx);
@@ -6956,6 +6957,27 @@ do_output_reload (struct insn_chain *chain, struct reload *rl, int j)
emit_output_reload_insns (chain, rld + j, j);
}
+/* Reload number R reloads from or to a group of hard registers starting at
+ register REGNO. Return true if it can be treated for inheritance purposes
+ like a group of reloads, each one reloading a single hard register.
+ The caller has already checked that the spill register and REGNO use
+ the same number of registers to store the reload value. */
+
+static bool
+inherit_piecemeal_p (int r ATTRIBUTE_UNUSED, int regno ATTRIBUTE_UNUSED)
+{
+#ifdef CANNOT_CHANGE_MODE_CLASS
+ return (!REG_CANNOT_CHANGE_MODE_P (reload_spill_index[r],
+ GET_MODE (rld[r].reg_rtx),
+ reg_raw_mode[reload_spill_index[r]])
+ && !REG_CANNOT_CHANGE_MODE_P (regno,
+ GET_MODE (rld[r].reg_rtx),
+ reg_raw_mode[regno]));
+#else
+ return true;
+#endif
+}
+
/* Output insns to reload values in and out of the chosen reload regs. */
static void
@@ -7137,11 +7159,16 @@ emit_reload_insns (struct insn_chain *chain)
int nnr = (nregno >= FIRST_PSEUDO_REGISTER ? 1
: hard_regno_nregs[nregno]
[GET_MODE (rld[r].reg_rtx)]);
+ bool piecemeal;
spill_reg_store[i] = new_spill_reg_store[i];
spill_reg_stored_to[i] = out;
reg_last_reload_reg[nregno] = rld[r].reg_rtx;
+ piecemeal = (nregno < FIRST_PSEUDO_REGISTER
+ && nr == nnr
+ && inherit_piecemeal_p (r, nregno));
+
/* If NREGNO is a hard register, it may occupy more than
one register. If it does, say what is in the
rest of the registers assuming that both registers
@@ -7151,7 +7178,7 @@ emit_reload_insns (struct insn_chain *chain)
if (nregno < FIRST_PSEUDO_REGISTER)
for (k = 1; k < nnr; k++)
reg_last_reload_reg[nregno + k]
- = (nr == nnr
+ = (piecemeal
? regno_reg_rtx[REGNO (rld[r].reg_rtx) + k]
: 0);
@@ -7160,7 +7187,7 @@ emit_reload_insns (struct insn_chain *chain)
{
CLEAR_HARD_REG_BIT (reg_reloaded_dead, i + k);
reg_reloaded_contents[i + k]
- = (nregno >= FIRST_PSEUDO_REGISTER || nr != nnr
+ = (nregno >= FIRST_PSEUDO_REGISTER || !piecemeal
? nregno
: nregno + k);
reg_reloaded_insn[i + k] = insn;
@@ -7185,6 +7212,7 @@ emit_reload_insns (struct insn_chain *chain)
int nregno;
int nnr;
rtx in;
+ bool piecemeal;
if (GET_CODE (rld[r].in) == REG
&& REGNO (rld[r].in) >= FIRST_PSEUDO_REGISTER)
@@ -7201,10 +7229,14 @@ emit_reload_insns (struct insn_chain *chain)
reg_last_reload_reg[nregno] = rld[r].reg_rtx;
+ piecemeal = (nregno < FIRST_PSEUDO_REGISTER
+ && nr == nnr
+ && inherit_piecemeal_p (r, nregno));
+
if (nregno < FIRST_PSEUDO_REGISTER)
for (k = 1; k < nnr; k++)
reg_last_reload_reg[nregno + k]
- = (nr == nnr
+ = (piecemeal
? regno_reg_rtx[REGNO (rld[r].reg_rtx) + k]
: 0);
@@ -7220,7 +7252,7 @@ emit_reload_insns (struct insn_chain *chain)
{
CLEAR_HARD_REG_BIT (reg_reloaded_dead, i + k);
reg_reloaded_contents[i + k]
- = (nregno >= FIRST_PSEUDO_REGISTER || nr != nnr
+ = (nregno >= FIRST_PSEUDO_REGISTER || !piecemeal
? nregno
: nregno + k);
reg_reloaded_insn[i + k] = insn;
@@ -7324,6 +7356,10 @@ emit_reload_insns (struct insn_chain *chain)
CLEAR_HARD_REG_BIT (reg_reloaded_died, src_regno);
}
reg_last_reload_reg[nregno] = src_reg;
+ /* We have to set reg_has_output_reload here, or else
+ forget_old_reloads_1 will clear reg_last_reload_reg
+ right away. */
+ reg_has_output_reload[nregno] = 1;
}
}
else
diff --git a/gcc/reorg.c b/gcc/reorg.c
index 9a58d34b29f..2ae0a8f2259 100644
--- a/gcc/reorg.c
+++ b/gcc/reorg.c
@@ -2349,7 +2349,9 @@ fill_simple_delay_slots (int non_jumps_p)
&& eligible_for_delay (insn, slots_filled, next_trial, flags)
&& ! can_throw_internal (trial))
{
- rtx new_label = next_active_insn (next_trial);
+ /* See comment in relax_delay_slots about necessity of using
+ next_real_insn here. */
+ rtx new_label = next_real_insn (next_trial);
if (new_label != 0)
new_label = get_label_before (new_label);
@@ -3074,7 +3076,9 @@ relax_delay_slots (rtx first)
&& (target_label = JUMP_LABEL (insn)) != 0)
{
target_label = follow_jumps (target_label);
- target_label = prev_label (next_active_insn (target_label));
+ /* See comment further down why we must use next_real_insn here,
+ instead of next_active_insn. */
+ target_label = prev_label (next_real_insn (target_label));
if (target_label == 0)
target_label = find_end_label ();
diff --git a/gcc/rtl-profile.c b/gcc/rtl-profile.c
new file mode 100644
index 00000000000..a53a00464a9
--- /dev/null
+++ b/gcc/rtl-profile.c
@@ -0,0 +1,424 @@
+/* Calculate branch probabilities, and basic block execution counts.
+ Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
+ based on some ideas from Dain Samples of UC Berkeley.
+ Further mangling by Bob Manson, Cygnus Support.
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Generate basic block profile instrumentation and auxiliary files.
+ Profile generation is optimized, so that not all arcs in the basic
+ block graph need instrumenting. First, the BB graph is closed with
+ one entry (function start), and one exit (function exit). Any
+ ABNORMAL_EDGE cannot be instrumented (because there is no control
+ path to place the code). We close the graph by inserting fake
+ EDGE_FAKE edges to the EXIT_BLOCK, from the sources of abnormal
+ edges that do not go to the exit_block. We ignore such abnormal
+ edges. Naturally these fake edges are never directly traversed,
+ and so *cannot* be directly instrumented. Some other graph
+ massaging is done. To optimize the instrumentation we generate the
+ BB minimal span tree, only edges that are not on the span tree
+ (plus the entry point) need instrumenting. From that information
+ all other edge counts can be deduced. By construction all fake
+ edges must be on the spanning tree. We also attempt to place
+ EDGE_CRITICAL edges on the spanning tree.
+
+ The auxiliary file generated is <dumpbase>.bbg. The format is
+ described in full in gcov-io.h. */
+
+/* ??? Register allocation should use basic block execution counts to
+ give preference to the most commonly executed blocks. */
+
+/* ??? Should calculate branch probabilities before instrumenting code, since
+ then we can use arc counts to help decide which arcs to instrument. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "flags.h"
+#include "output.h"
+#include "regs.h"
+#include "expr.h"
+#include "function.h"
+#include "toplev.h"
+#include "coverage.h"
+#include "value-prof.h"
+#include "tree.h"
+
+/* Output instructions as RTL to increment the edge execution count. */
+
+static void
+rtl_gen_edge_profiler (int edgeno, edge e)
+{
+ rtx ref = rtl_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
+ rtx tmp;
+ enum machine_mode mode = GET_MODE (ref);
+ rtx sequence;
+
+ start_sequence ();
+ ref = validize_mem (ref);
+
+ tmp = expand_simple_binop (mode, PLUS, ref, const1_rtx,
+ ref, 0, OPTAB_WIDEN);
+
+ if (tmp != ref)
+ emit_move_insn (copy_rtx (ref), tmp);
+
+ sequence = get_insns ();
+ end_sequence ();
+ insert_insn_on_edge (sequence, e);
+ rebuild_jump_labels (e->insns.r);
+}
+
+/* Output instructions as RTL to increment the interval histogram counter.
+ VALUE is the expression whose value is profiled. TAG is the tag of the
+ section for counters, BASE is offset of the counter position. */
+
+static void
+rtl_gen_interval_profiler (struct histogram_value *value, unsigned tag,
+ unsigned base)
+{
+ unsigned gcov_size = tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE), 1);
+ enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
+ rtx mem_ref, tmp, tmp1, mr, val;
+ rtx sequence;
+ rtx more_label = gen_label_rtx ();
+ rtx less_label = gen_label_rtx ();
+ rtx end_of_code_label = gen_label_rtx ();
+ int per_counter = gcov_size / BITS_PER_UNIT;
+ edge e = split_block (BLOCK_FOR_INSN ((rtx)value->insn),
+ PREV_INSN ((rtx)value->insn));
+
+ start_sequence ();
+
+ if (value->seq)
+ emit_insn (value->seq);
+
+ mr = gen_reg_rtx (Pmode);
+
+ tmp = rtl_coverage_counter_ref (tag, base);
+ tmp = force_reg (Pmode, XEXP (tmp, 0));
+
+ val = expand_simple_binop (value->mode, MINUS,
+ copy_rtx (value->value),
+ GEN_INT (value->hdata.intvl.int_start),
+ NULL_RTX, 0, OPTAB_WIDEN);
+
+ if (value->hdata.intvl.may_be_more)
+ do_compare_rtx_and_jump (copy_rtx (val), GEN_INT (value->hdata.intvl.steps),
+ GE, 0, value->mode, NULL_RTX, NULL_RTX, more_label);
+ if (value->hdata.intvl.may_be_less)
+ do_compare_rtx_and_jump (copy_rtx (val), const0_rtx, LT, 0, value->mode,
+ NULL_RTX, NULL_RTX, less_label);
+
+ /* We are in range. */
+ tmp1 = expand_simple_binop (value->mode, MULT,
+ copy_rtx (val), GEN_INT (per_counter),
+ NULL_RTX, 0, OPTAB_WIDEN);
+ tmp1 = expand_simple_binop (Pmode, PLUS, copy_rtx (tmp), tmp1, mr,
+ 0, OPTAB_WIDEN);
+ if (tmp1 != mr)
+ emit_move_insn (copy_rtx (mr), tmp1);
+
+ if (value->hdata.intvl.may_be_more
+ || value->hdata.intvl.may_be_less)
+ {
+ emit_jump_insn (gen_jump (end_of_code_label));
+ emit_barrier ();
+ }
+
+ /* Above the interval. */
+ if (value->hdata.intvl.may_be_more)
+ {
+ emit_label (more_label);
+ tmp1 = expand_simple_binop (Pmode, PLUS, copy_rtx (tmp),
+ GEN_INT (per_counter * value->hdata.intvl.steps),
+ mr, 0, OPTAB_WIDEN);
+ if (tmp1 != mr)
+ emit_move_insn (copy_rtx (mr), tmp1);
+ if (value->hdata.intvl.may_be_less)
+ {
+ emit_jump_insn (gen_jump (end_of_code_label));
+ emit_barrier ();
+ }
+ }
+
+ /* Below the interval. */
+ if (value->hdata.intvl.may_be_less)
+ {
+ emit_label (less_label);
+ tmp1 = expand_simple_binop (Pmode, PLUS, copy_rtx (tmp),
+ GEN_INT (per_counter * (value->hdata.intvl.steps
+ + (value->hdata.intvl.may_be_more ? 1 : 0))),
+ mr, 0, OPTAB_WIDEN);
+ if (tmp1 != mr)
+ emit_move_insn (copy_rtx (mr), tmp1);
+ }
+
+ if (value->hdata.intvl.may_be_more
+ || value->hdata.intvl.may_be_less)
+ emit_label (end_of_code_label);
+
+ mem_ref = validize_mem (gen_rtx_MEM (mode, mr));
+
+ tmp = expand_simple_binop (mode, PLUS, copy_rtx (mem_ref), const1_rtx,
+ mem_ref, 0, OPTAB_WIDEN);
+
+ if (tmp != mem_ref)
+ emit_move_insn (copy_rtx (mem_ref), tmp);
+
+ sequence = get_insns ();
+ end_sequence ();
+ rebuild_jump_labels (sequence);
+ safe_insert_insn_on_edge (sequence, e);
+}
+
+/* Output instructions as RTL to increment the power of two histogram counter.
+ VALUE is the expression whose value is profiled. TAG is the tag of the
+ section for counters, BASE is offset of the counter position. */
+
+static void
+rtl_gen_pow2_profiler (struct histogram_value *value, unsigned tag,
+ unsigned base)
+{
+ unsigned gcov_size = tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE), 1);
+ enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
+ rtx mem_ref, tmp, mr, uval;
+ rtx sequence;
+ rtx end_of_code_label = gen_label_rtx ();
+ rtx loop_label = gen_label_rtx ();
+ int per_counter = gcov_size / BITS_PER_UNIT;
+ edge e = split_block (BLOCK_FOR_INSN ((rtx)value->insn),
+ PREV_INSN ((rtx)value->insn));
+
+ start_sequence ();
+
+ if (value->seq)
+ emit_insn (value->seq);
+
+ mr = gen_reg_rtx (Pmode);
+ tmp = rtl_coverage_counter_ref (tag, base);
+ tmp = force_reg (Pmode, XEXP (tmp, 0));
+ emit_move_insn (mr, tmp);
+
+ uval = gen_reg_rtx (value->mode);
+ emit_move_insn (uval, copy_rtx (value->value));
+
+ /* Check for non-power of 2. */
+ if (value->hdata.pow2.may_be_other)
+ {
+ do_compare_rtx_and_jump (copy_rtx (uval), const0_rtx, LE, 0, value->mode,
+ NULL_RTX, NULL_RTX, end_of_code_label);
+ tmp = expand_simple_binop (value->mode, PLUS, copy_rtx (uval),
+ constm1_rtx, NULL_RTX, 0, OPTAB_WIDEN);
+ tmp = expand_simple_binop (value->mode, AND, copy_rtx (uval), tmp,
+ NULL_RTX, 0, OPTAB_WIDEN);
+ do_compare_rtx_and_jump (tmp, const0_rtx, NE, 0, value->mode, NULL_RTX,
+ NULL_RTX, end_of_code_label);
+ }
+
+ /* Count log_2(value). */
+ emit_label (loop_label);
+
+ tmp = expand_simple_binop (Pmode, PLUS, copy_rtx (mr), GEN_INT (per_counter), mr, 0, OPTAB_WIDEN);
+ if (tmp != mr)
+ emit_move_insn (copy_rtx (mr), tmp);
+
+ tmp = expand_simple_binop (value->mode, ASHIFTRT, copy_rtx (uval), const1_rtx,
+ uval, 0, OPTAB_WIDEN);
+ if (tmp != uval)
+ emit_move_insn (copy_rtx (uval), tmp);
+
+ do_compare_rtx_and_jump (copy_rtx (uval), const0_rtx, NE, 0, value->mode,
+ NULL_RTX, NULL_RTX, loop_label);
+
+ /* Increase the counter. */
+ emit_label (end_of_code_label);
+
+ mem_ref = validize_mem (gen_rtx_MEM (mode, mr));
+
+ tmp = expand_simple_binop (mode, PLUS, copy_rtx (mem_ref), const1_rtx,
+ mem_ref, 0, OPTAB_WIDEN);
+
+ if (tmp != mem_ref)
+ emit_move_insn (copy_rtx (mem_ref), tmp);
+
+ sequence = get_insns ();
+ end_sequence ();
+ rebuild_jump_labels (sequence);
+ safe_insert_insn_on_edge (sequence, e);
+}
+
+/* Output instructions as RTL for code to find the most common value.
+ VALUE is the expression whose value is profiled. TAG is the tag of the
+ section for counters, BASE is offset of the counter position. */
+
+static rtx
+rtl_gen_one_value_profiler_no_edge_manipulation (struct histogram_value *value,
+ unsigned tag, unsigned base)
+{
+ unsigned gcov_size = tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE), 1);
+ enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
+ rtx stored_value_ref, counter_ref, all_ref, stored_value, counter, all;
+ rtx tmp, uval;
+ rtx sequence;
+ rtx same_label = gen_label_rtx ();
+ rtx zero_label = gen_label_rtx ();
+ rtx end_of_code_label = gen_label_rtx ();
+
+ start_sequence ();
+
+ if (value->seq)
+ emit_insn (value->seq);
+
+ stored_value_ref = rtl_coverage_counter_ref (tag, base);
+ counter_ref = rtl_coverage_counter_ref (tag, base + 1);
+ all_ref = rtl_coverage_counter_ref (tag, base + 2);
+ stored_value = validize_mem (stored_value_ref);
+ counter = validize_mem (counter_ref);
+ all = validize_mem (all_ref);
+
+ uval = gen_reg_rtx (mode);
+ convert_move (uval, copy_rtx (value->value), 0);
+
+ /* Check if the stored value matches. */
+ do_compare_rtx_and_jump (copy_rtx (uval), copy_rtx (stored_value), EQ,
+ 0, mode, NULL_RTX, NULL_RTX, same_label);
+
+ /* Does not match; check whether the counter is zero. */
+ do_compare_rtx_and_jump (copy_rtx (counter), const0_rtx, EQ, 0, mode,
+ NULL_RTX, NULL_RTX, zero_label);
+
+ /* The counter is not zero yet. */
+ tmp = expand_simple_binop (mode, PLUS, copy_rtx (counter), constm1_rtx,
+ counter, 0, OPTAB_WIDEN);
+
+ if (tmp != counter)
+ emit_move_insn (copy_rtx (counter), tmp);
+
+ emit_jump_insn (gen_jump (end_of_code_label));
+ emit_barrier ();
+
+ emit_label (zero_label);
+ /* Set new value. */
+ emit_move_insn (copy_rtx (stored_value), copy_rtx (uval));
+
+ emit_label (same_label);
+ /* Increase the counter. */
+ tmp = expand_simple_binop (mode, PLUS, copy_rtx (counter), const1_rtx,
+ counter, 0, OPTAB_WIDEN);
+
+ if (tmp != counter)
+ emit_move_insn (copy_rtx (counter), tmp);
+
+ emit_label (end_of_code_label);
+
+ /* Increase the counter of all executions; this seems redundant given
+ that ve have counts for edges in cfg, but it may happen that some
+ optimization will change the counts for the block (either because
+ it is unable to update them correctly, or because it will duplicate
+ the block or its part). */
+ tmp = expand_simple_binop (mode, PLUS, copy_rtx (all), const1_rtx,
+ all, 0, OPTAB_WIDEN);
+
+ if (tmp != all)
+ emit_move_insn (copy_rtx (all), tmp);
+ sequence = get_insns ();
+ end_sequence ();
+ return sequence;
+}
+
+/* Output instructions as RTL for code to find the most common value.
+ VALUE is the expression whose value is profiled. TAG is the tag of the
+ section for counters, BASE is offset of the counter position. */
+
+static void
+rtl_gen_one_value_profiler (struct histogram_value *value, unsigned tag,
+ unsigned base)
+{
+ edge e = split_block (BLOCK_FOR_INSN ((rtx)value->insn),
+ PREV_INSN ((rtx)value->insn));
+ rtx sequence = rtl_gen_one_value_profiler_no_edge_manipulation (value,
+ tag, base);
+ rebuild_jump_labels (sequence);
+ safe_insert_insn_on_edge (sequence, e);
+}
+
+/* Output instructions as RTL for code to find the most common value of
+ a difference between two evaluations of an expression.
+ VALUE is the expression whose value is profiled. TAG is the tag of the
+ section for counters, BASE is offset of the counter position. */
+
+static void
+rtl_gen_const_delta_profiler (struct histogram_value *value, unsigned tag,
+ unsigned base)
+{
+ struct histogram_value one_value_delta;
+ unsigned gcov_size = tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE), 1);
+ enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
+ rtx stored_value_ref, stored_value, tmp, uval;
+ rtx sequence;
+ edge e = split_block (BLOCK_FOR_INSN ((rtx)value->insn),
+ PREV_INSN ((rtx)value->insn));
+
+ start_sequence ();
+
+ if (value->seq)
+ emit_insn (value->seq);
+
+ stored_value_ref = rtl_coverage_counter_ref (tag, base);
+ stored_value = validize_mem (stored_value_ref);
+
+ uval = gen_reg_rtx (mode);
+ convert_move (uval, copy_rtx (value->value), 0);
+ tmp = expand_simple_binop (mode, MINUS,
+ copy_rtx (uval), copy_rtx (stored_value),
+ NULL_RTX, 0, OPTAB_WIDEN);
+
+ one_value_delta.value = tmp;
+ one_value_delta.mode = mode;
+ one_value_delta.seq = NULL_RTX;
+ one_value_delta.insn = value->insn;
+ one_value_delta.type = HIST_TYPE_SINGLE_VALUE;
+ emit_insn (rtl_gen_one_value_profiler_no_edge_manipulation (&one_value_delta,
+ tag, base + 1));
+ emit_move_insn (copy_rtx (stored_value), uval);
+ sequence = get_insns ();
+ end_sequence ();
+ rebuild_jump_labels (sequence);
+ safe_insert_insn_on_edge (sequence, e);
+}
+
+/* Return the file on which profile dump output goes, if any. */
+
+static FILE *rtl_profile_dump_file (void) {
+ return dump_file;
+}
+
+struct profile_hooks rtl_profile_hooks =
+{
+ rtl_gen_edge_profiler,
+ rtl_gen_interval_profiler,
+ rtl_gen_pow2_profiler,
+ rtl_gen_one_value_profiler,
+ rtl_gen_const_delta_profiler,
+ rtl_profile_dump_file
+};
diff --git a/gcc/rtl.def b/gcc/rtl.def
index c3653f49dfe..3eecf1fb79e 100644
--- a/gcc/rtl.def
+++ b/gcc/rtl.def
@@ -1153,11 +1153,6 @@ DEF_RTL_EXPR(RANGE_VAR, "range_var", "eti", RTX_EXTRA)
0 is the live bitmap. Operand 1 is the original block number. */
DEF_RTL_EXPR(RANGE_LIVE, "range_live", "bi", RTX_EXTRA)
-/* A unary `__builtin_constant_p' expression. These are only emitted
- during RTL generation, and then only if optimize > 0. They are
- eliminated by the first CSE pass. */
-DEF_RTL_EXPR(CONSTANT_P_RTX, "constant_p_rtx", "e", RTX_EXTRA)
-
/* A placeholder for a CALL_INSN which may be turned into a normal call,
a sibling (tail) call or tail recursion.
diff --git a/gcc/rtl.h b/gcc/rtl.h
index f6ebe34caa4..1041d020e1a 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -240,12 +240,9 @@ struct rtx_def GTY((chain_next ("RTX_NEXT (&%h)"),
1 in a SYMBOL_REF, means that emit_library_call
has used it as the function. */
unsigned int used : 1;
- /* Nonzero if this rtx came from procedure integration.
- 1 in a REG or PARALLEL means this rtx refers to the return value
- of the current function.
- 1 in a SYMBOL_REF if the symbol is weak.
- 1 in a MEM if the MEM refers to a scalar, rather than a member of
- an aggregate. */
+ /* FIXME. This should be unused now that we do inlinining on trees,
+ but it is now being used for MEM_SCALAR_P. It should be renamed,
+ or some other field should be overloaded. */
unsigned integrated : 1;
/* 1 in an INSN or a SET if this rtx is related to the call frame,
either changing how we compute the frame address or saving and
@@ -254,6 +251,9 @@ struct rtx_def GTY((chain_next ("RTX_NEXT (&%h)"),
1 in a SYMBOL_REF if it addresses something in the per-function
constant string pool. */
unsigned frame_related : 1;
+ /* 1 in a REG or PARALLEL that is the current function's return value.
+ 1 in a SYMBOL_REF for a weak symbol. */
+ unsigned return_val : 1;
/* The first element of the operands of this rtx.
The number of operands and their types are controlled
@@ -387,8 +387,7 @@ struct rtvec_def GTY(()) {
#define CONSTANT_P(X) \
(GET_RTX_CLASS (GET_CODE (X)) == RTX_CONST_OBJ \
- || GET_CODE (X) == CONST_VECTOR \
- || GET_CODE (X) == CONSTANT_P_RTX)
+ || GET_CODE (X) == CONST_VECTOR)
/* 1 if X can be used to represent an object. */
#define OBJECT_P(X) \
@@ -593,11 +592,11 @@ do { \
_rtx->call = 0; \
_rtx->frame_related = 0; \
_rtx->in_struct = 0; \
- _rtx->integrated = 0; \
_rtx->jump = 0; \
_rtx->unchanging = 0; \
_rtx->used = 0; \
_rtx->volatil = 0; \
+ _rtx->unused_flag = 0; \
} while (0)
#define XINT(RTX, N) (RTL_CHECK2 (RTX, N, 'i', 'n').rtint)
@@ -676,10 +675,6 @@ do { \
They are always in the same basic block as this insn. */
#define LOG_LINKS(INSN) XEXP(INSN, 7)
-#define RTX_INTEGRATED_P(RTX) \
- (RTL_FLAG_CHECK8("RTX_INTEGRATED_P", (RTX), INSN, CALL_INSN, \
- JUMP_INSN, INSN_LIST, BARRIER, CODE_LABEL, CONST, \
- NOTE)->integrated)
#define RTX_UNCHANGING_P(RTX) \
(RTL_FLAG_CHECK3("RTX_UNCHANGING_P", (RTX), REG, MEM, CONCAT)->unchanging)
#define RTX_FRAME_RELATED_P(RTX) \
@@ -1135,7 +1130,7 @@ enum label_kind
/* 1 if RTX is a reg or parallel that is the current function's return
value. */
#define REG_FUNCTION_VALUE_P(RTX) \
- (RTL_FLAG_CHECK2("REG_FUNCTION_VALUE_P", (RTX), REG, PARALLEL)->integrated)
+ (RTL_FLAG_CHECK2("REG_FUNCTION_VALUE_P", (RTX), REG, PARALLEL)->return_val)
/* 1 if RTX is a reg that corresponds to a variable declared by the user. */
#define REG_USERVAR_P(RTX) \
@@ -1408,7 +1403,7 @@ do { \
/* 1 if RTX is a symbol_ref for a weak symbol. */
#define SYMBOL_REF_WEAK(RTX) \
- (RTL_FLAG_CHECK1("SYMBOL_REF_WEAK", (RTX), SYMBOL_REF)->integrated)
+ (RTL_FLAG_CHECK1("SYMBOL_REF_WEAK", (RTX), SYMBOL_REF)->return_val)
/* The tree (decl or constant) associated with the symbol, or null. */
#define SYMBOL_REF_DECL(RTX) X0TREE ((RTX), 2)
@@ -1538,17 +1533,12 @@ do { \
#ifndef USE_STORE_PRE_DECREMENT
#define USE_STORE_PRE_DECREMENT(MODE) HAVE_PRE_DECREMENT
#endif
-
-/* Determine if the insn is a PHI node. */
-#define PHI_NODE_P(X) \
- ((X) && GET_CODE (X) == INSN \
- && GET_CODE (PATTERN (X)) == SET \
- && GET_CODE (SET_SRC (PATTERN (X))) == PHI)
/* Nonzero if we need to distinguish between the return value of this function
and the return value of a function called by this function. This helps
integrate.c.
- This is 1 until after the rtl generation pass. */
+ This is 1 until after the rtl generation pass.
+ ??? It appears that this is 1 only when expanding trees to RTL. */
extern int rtx_equal_function_value_matters;
/* Nonzero when we are generating CONCATs. */
@@ -1844,7 +1834,6 @@ extern int reg_overlap_mentioned_p (rtx, rtx);
extern rtx set_of (rtx, rtx);
extern void note_stores (rtx, void (*) (rtx, rtx, void *), void *);
extern void note_uses (rtx *, void (*) (rtx *, void *), void *);
-extern rtx reg_set_last (rtx, rtx);
extern int dead_or_set_p (rtx, rtx);
extern int dead_or_set_regno_p (rtx, unsigned int);
extern rtx find_reg_note (rtx, enum reg_note, rtx);
@@ -2087,9 +2076,6 @@ extern rtx gen_rtx_MEM (enum machine_mode, rtx);
extern rtx output_constant_def (tree, int);
extern rtx lookup_constant_def (tree);
-/* Called from integrate.c when a deferred constant is inlined. */
-extern void notice_rtl_inlining_of_deferred_constant (void);
-
/* Nonzero after the second flow pass has completed.
Set to 1 or 0 by toplev.c */
extern int flow2_completed;
@@ -2158,14 +2144,13 @@ extern enum rtx_code reversed_comparison_code_parts (enum rtx_code,
rtx, rtx, rtx);
extern void delete_for_peephole (rtx, rtx);
extern int condjump_in_parallel_p (rtx);
-extern void never_reached_warning (rtx, rtx);
extern void purge_line_number_notes (rtx);
-extern void copy_loop_headers (rtx);
/* In emit-rtl.c. */
extern int max_reg_num (void);
extern int max_label_num (void);
extern int get_first_label_num (void);
+extern void maybe_set_first_label_num (rtx);
extern void delete_insns_since (rtx);
extern void mark_reg_pointer (rtx, int);
extern void mark_user_reg (rtx);
@@ -2335,8 +2320,6 @@ extern void cannot_change_mode_set_regs (HARD_REG_SET *,
extern bool invalid_mode_change_p (unsigned int, enum reg_class,
enum machine_mode);
-extern int delete_null_pointer_checks (rtx);
-
/* In regmove.c */
#ifdef BUFSIZ
extern void regmove_optimize (rtx, int, FILE *);
@@ -2354,11 +2337,6 @@ extern void dump_local_alloc (FILE *);
#endif
extern int local_alloc (void);
-/* In profile.c */
-extern void init_branch_prob (void);
-extern void branch_prob (void);
-extern void end_branch_prob (void);
-
/* In reg-stack.c */
#ifdef BUFSIZ
extern bool reg_to_stack (rtx, FILE *);
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index c66cc9adc8c..a52f614b878 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -452,8 +452,8 @@ get_related_value (rtx x)
rtx
get_jump_table_offset (rtx insn, rtx *earliest)
{
- rtx label;
- rtx table;
+ rtx label = NULL;
+ rtx table = NULL;
rtx set;
rtx old_insn;
rtx x;
@@ -1598,54 +1598,6 @@ reg_overlap_mentioned_p (rtx x, rtx in)
}
}
-/* Return the last value to which REG was set prior to INSN. If we can't
- find it easily, return 0.
-
- We only return a REG, SUBREG, or constant because it is too hard to
- check if a MEM remains unchanged. */
-
-rtx
-reg_set_last (rtx x, rtx insn)
-{
- rtx orig_insn = insn;
-
- /* Scan backwards until reg_set_last_1 changed one of the above flags.
- Stop when we reach a label or X is a hard reg and we reach a
- CALL_INSN (if reg_set_last_last_regno is a hard reg).
-
- If we find a set of X, ensure that its SET_SRC remains unchanged. */
-
- /* We compare with <= here, because reg_set_last_last_regno
- is actually the number of the first reg *not* in X. */
- for (;
- insn && GET_CODE (insn) != CODE_LABEL
- && ! (GET_CODE (insn) == CALL_INSN
- && REGNO (x) <= FIRST_PSEUDO_REGISTER);
- insn = PREV_INSN (insn))
- if (INSN_P (insn))
- {
- rtx set = set_of (x, insn);
- /* OK, this function modify our register. See if we understand it. */
- if (set)
- {
- rtx last_value;
- if (GET_CODE (set) != SET || SET_DEST (set) != x)
- return 0;
- last_value = SET_SRC (x);
- if (CONSTANT_P (last_value)
- || ((GET_CODE (last_value) == REG
- || GET_CODE (last_value) == SUBREG)
- && ! reg_set_between_p (last_value,
- insn, orig_insn)))
- return last_value;
- else
- return 0;
- }
- }
-
- return 0;
-}
-
/* Call FUN on each register or MEM that is stored into or clobbered by X.
(X would be the pattern of an insn).
FUN receives two arguments:
@@ -3750,18 +3702,18 @@ hoist_insn_to_edge (rtx insn, edge e, rtx val, rtx new)
abort ();
/* Do not use emit_insn_on_edge as we want to preserve notes and similar
- stuff. We also emit CALL_INSNS and friends. */
- if (e->insns == NULL_RTX)
+ stuff. We also emit CALL_INSNS and firends. */
+ if (e->insns.r == NULL_RTX)
{
start_sequence ();
emit_note (NOTE_INSN_DELETED);
}
else
- push_to_sequence (e->insns);
+ push_to_sequence (e->insns.r);
new_insn = hoist_insn_after (insn, get_last_insn (), val, new);
- e->insns = get_insns ();
+ e->insns.r = get_insns ();
end_sequence ();
return new_insn;
}
diff --git a/gcc/sbitmap.c b/gcc/sbitmap.c
index 1d27a871097..dfd764528cb 100644
--- a/gcc/sbitmap.c
+++ b/gcc/sbitmap.c
@@ -103,6 +103,32 @@ sbitmap_resize (sbitmap bmap, unsigned int n_elms, int def)
return bmap;
}
+/* Re-allocate a simple bitmap of N_ELMS bits. New storage is uninitialized. */
+
+sbitmap
+sbitmap_realloc (sbitmap src, unsigned int n_elms)
+{
+ unsigned int bytes, size, amt;
+ sbitmap bmap;
+
+ size = SBITMAP_SET_SIZE (n_elms);
+ bytes = size * sizeof (SBITMAP_ELT_TYPE);
+ amt = (sizeof (struct simple_bitmap_def)
+ + bytes - sizeof (SBITMAP_ELT_TYPE));
+
+ if (src->bytes >= bytes)
+ {
+ src->n_bits = n_elms;
+ return src;
+ }
+
+ bmap = (sbitmap) xrealloc (src, amt);
+ bmap->n_bits = n_elms;
+ bmap->size = size;
+ bmap->bytes = bytes;
+ return bmap;
+}
+
/* Allocate a vector of N_VECS bitmaps of N_ELMS bits. */
sbitmap *
diff --git a/gcc/sbitmap.h b/gcc/sbitmap.h
index fecc4915083..0ddc0d051c6 100644
--- a/gcc/sbitmap.h
+++ b/gcc/sbitmap.h
@@ -170,4 +170,5 @@ extern void sbitmap_union_of_succs (sbitmap, sbitmap *, int);
extern void sbitmap_union_of_preds (sbitmap, sbitmap *, int);
extern void debug_sbitmap (sbitmap);
+extern sbitmap sbitmap_realloc (sbitmap, unsigned int);
#endif /* ! GCC_SBITMAP_H */
diff --git a/gcc/sdbout.c b/gcc/sdbout.c
index a6dda215685..b93ab779712 100644
--- a/gcc/sdbout.c
+++ b/gcc/sdbout.c
@@ -1186,7 +1186,7 @@ sdbout_one_type (tree type)
if (TREE_CODE (type) == ENUMERAL_TYPE)
{
- for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
+ for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem))
if (host_integerp (TREE_VALUE (tem), 0))
{
PUT_SDB_DEF (IDENTIFIER_POINTER (TREE_PURPOSE (tem)));
@@ -1479,8 +1479,6 @@ sdbout_finish (const char *main_filename ATTRIBUTE_UNUSED)
for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_global_decls); i++)
sdbout_symbol (VARRAY_TREE (deferred_global_decls, i), 0);
-
- VARRAY_FREE (deferred_global_decls);
}
/* Describe the beginning of an internal block within a function.
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index b6340e54c8b..680ecafc21a 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -58,6 +58,8 @@ static rtx simplify_immed_subreg (enum machine_mode, rtx, enum machine_mode,
unsigned int);
static rtx simplify_associative_operation (enum rtx_code, enum machine_mode,
rtx, rtx);
+static rtx simplify_relational_operation_1 (enum rtx_code, enum machine_mode,
+ enum machine_mode, rtx, rtx);
/* Negate a CONST_INT rtx, truncating (because a conversion from a
maximally negative number can overflow). */
@@ -221,10 +223,9 @@ simplify_gen_ternary (enum rtx_code code, enum machine_mode mode,
return gen_rtx_fmt_eee (code, mode, op0, op1, op2);
}
-
+
/* Likewise, for relational operations.
- CMP_MODE specifies mode comparison is done in.
- */
+ CMP_MODE specifies mode comparison is done in. */
rtx
simplify_gen_relational (enum rtx_code code, enum machine_mode mode,
@@ -232,46 +233,9 @@ simplify_gen_relational (enum rtx_code code, enum machine_mode mode,
{
rtx tem;
- if (cmp_mode == VOIDmode)
- cmp_mode = GET_MODE (op0);
- if (cmp_mode == VOIDmode)
- cmp_mode = GET_MODE (op1);
-
- if (cmp_mode != VOIDmode)
- {
- tem = simplify_relational_operation (code, mode, cmp_mode, op0, op1);
- if (tem)
- return tem;
- }
-
- /* For the following tests, ensure const0_rtx is op1. */
- if (swap_commutative_operands_p (op0, op1)
- || (op0 == const0_rtx && op1 != const0_rtx))
- tem = op0, op0 = op1, op1 = tem, code = swap_condition (code);
-
- /* If op0 is a compare, extract the comparison arguments from it. */
- if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
- return simplify_gen_relational (code, mode, VOIDmode,
- XEXP (op0, 0), XEXP (op0, 1));
-
- /* If op0 is a comparison, extract the comparison arguments form it. */
- if (COMPARISON_P (op0) && op1 == const0_rtx)
- {
- if (code == NE)
- {
- if (GET_MODE (op0) == mode)
- return op0;
- return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
- XEXP (op0, 0), XEXP (op0, 1));
- }
- else if (code == EQ)
- {
- enum rtx_code new = reversed_comparison_code (op0, NULL_RTX);
- if (new != UNKNOWN)
- return simplify_gen_relational (new, mode, VOIDmode,
- XEXP (op0, 0), XEXP (op0, 1));
- }
- }
+ if (0 != (tem = simplify_relational_operation (code, mode, cmp_mode,
+ op0, op1)))
+ return tem;
return gen_rtx_fmt_ee (code, mode, op0, op1);
}
@@ -1201,7 +1165,6 @@ simplify_associative_operation (enum rtx_code code, enum machine_mode mode,
Don't use this for relational operations such as EQ or LT.
Use simplify_relational_operation instead. */
-
rtx
simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
rtx op0, rtx op1)
@@ -2662,10 +2625,102 @@ simplify_plus_minus (enum rtx_code code, enum machine_mode mode, rtx op0,
}
/* Like simplify_binary_operation except used for relational operators.
- MODE is the mode of the operands, not that of the result. If MODE
- is VOIDmode, both operands must also be VOIDmode and we compare the
- operands in "infinite precision".
+ MODE is the mode of the result. If MODE is VOIDmode, both operands must
+ also be VOIDmode.
+
+ CMP_MODE specifies in which mode the comparison is done in, so it is
+ the mode of the operands. If CMP_MODE is VOIDmode, it is taken from
+ the operands or, if both are VOIDmode, the operands are compared in
+ "infinite precision". */
+rtx
+simplify_relational_operation (enum rtx_code code, enum machine_mode mode,
+ enum machine_mode cmp_mode, rtx op0, rtx op1)
+{
+ rtx tem, trueop0, trueop1;
+
+ if (cmp_mode == VOIDmode)
+ cmp_mode = GET_MODE (op0);
+ if (cmp_mode == VOIDmode)
+ cmp_mode = GET_MODE (op1);
+
+ tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
+ if (tem)
+ {
+#ifdef FLOAT_STORE_FLAG_VALUE
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT)
+ {
+ if (tem == const0_rtx)
+ return CONST0_RTX (mode);
+ else if (GET_MODE_CLASS (mode) == MODE_FLOAT)
+ {
+ REAL_VALUE_TYPE val;
+ val = FLOAT_STORE_FLAG_VALUE (mode);
+ return CONST_DOUBLE_FROM_REAL_VALUE (val, mode);
+ }
+ }
+#endif
+
+ return tem;
+ }
+
+ /* For the following tests, ensure const0_rtx is op1. */
+ if (swap_commutative_operands_p (op0, op1)
+ || (op0 == const0_rtx && op1 != const0_rtx))
+ tem = op0, op0 = op1, op1 = tem, code = swap_condition (code);
+
+ /* If op0 is a compare, extract the comparison arguments from it. */
+ if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
+ return simplify_relational_operation (code, mode, VOIDmode,
+ XEXP (op0, 0), XEXP (op0, 1));
+ if (mode == VOIDmode
+ || GET_MODE_CLASS (cmp_mode) == MODE_CC
+ || CC0_P (op0))
+ return NULL_RTX;
+
+ trueop0 = avoid_constant_pool_reference (op0);
+ trueop1 = avoid_constant_pool_reference (op1);
+ return simplify_relational_operation_1 (code, mode, cmp_mode,
+ trueop0, trueop1);
+}
+
+/* This part of simplify_relational_operation is only used when CMP_MODE
+ is not in class MODE_CC (i.e. it is a real comparison).
+
+ MODE is the mode of the result, while CMP_MODE specifies in which
+ mode the comparison is done in, so it is the mode of the operands. */
+rtx
+simplify_relational_operation_1 (enum rtx_code code, enum machine_mode mode,
+ enum machine_mode cmp_mode, rtx op0, rtx op1)
+{
+ if (GET_CODE (op1) == CONST_INT)
+ {
+ if (INTVAL (op1) == 0 && COMPARISON_P (op0))
+ {
+ /* If op0 is a comparison, extract the comparison arguments form it. */
+ if (code == NE)
+ {
+ if (GET_MODE (op0) == cmp_mode)
+ return simplify_rtx (op0);
+ else
+ return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
+ XEXP (op0, 0), XEXP (op0, 1));
+ }
+ else if (code == EQ)
+ {
+ enum rtx_code new = reversed_comparison_code (op0, NULL_RTX);
+ if (new != UNKNOWN)
+ return simplify_gen_relational (new, mode, VOIDmode,
+ XEXP (op0, 0), XEXP (op0, 1));
+ }
+ }
+ }
+
+ return NULL_RTX;
+}
+
+/* Check if the given comparison (done in the given MODE) is actually a
+ tautology or a contradiction.
If no simplification is possible, this function returns zero.
Otherwise, it returns either const_true_rtx or const0_rtx. */
@@ -2954,36 +3009,6 @@ simplify_const_relational_operation (enum rtx_code code,
abort ();
}
}
-
-/* Like simplify_binary_operation except used for relational operators.
- MODE is the mode of the result, and CMP_MODE is the mode of the operands.
- If CMP_MODE is VOIDmode, both operands must also be VOIDmode and we
- compare the operands in "infinite precision". */
-
-rtx
-simplify_relational_operation (enum rtx_code code,
- enum machine_mode mode ATTRIBUTE_UNUSED,
- enum machine_mode cmp_mode, rtx op0, rtx op1)
-{
- rtx tmp;
-
- tmp = simplify_const_relational_operation (code, cmp_mode, op0, op1);
- if (tmp)
- {
-#ifdef FLOAT_STORE_FLAG_VALUE
- if (GET_MODE_CLASS (mode) == MODE_FLOAT)
- {
- if (tmp == const0_rtx)
- return CONST0_RTX (mode);
- return CONST_DOUBLE_FROM_REAL_VALUE (FLOAT_STORE_FLAG_VALUE (mode),
- mode);
- }
-#endif
- return tmp;
- }
-
- return NULL_RTX;
-}
/* Simplify CODE, an operation with result mode MODE and three operands,
OP0, OP1, and OP2. OP0_MODE was the mode of OP0 before it became
@@ -3078,20 +3103,6 @@ simplify_ternary_operation (enum rtx_code code, enum machine_mode mode,
? GET_MODE (XEXP (op0, 1))
: GET_MODE (XEXP (op0, 0)));
rtx temp;
- if (cmp_mode == VOIDmode)
- cmp_mode = op0_mode;
- temp = simplify_const_relational_operation (GET_CODE (op0),
- cmp_mode,
- XEXP (op0, 0),
- XEXP (op0, 1));
-
- /* See if any simplifications were possible. */
- if (temp == const0_rtx)
- return op2;
- else if (temp == const_true_rtx)
- return op1;
- else if (temp)
- abort ();
/* Look for happy constants in op1 and op2. */
if (GET_CODE (op1) == CONST_INT && GET_CODE (op2) == CONST_INT)
@@ -3112,7 +3123,23 @@ simplify_ternary_operation (enum rtx_code code, enum machine_mode mode,
else
break;
- return gen_rtx_fmt_ee (code, mode, XEXP (op0, 0), XEXP (op0, 1));
+ return simplify_gen_relational (code, mode, cmp_mode,
+ XEXP (op0, 0), XEXP (op0, 1));
+ }
+
+ if (cmp_mode == VOIDmode)
+ cmp_mode = op0_mode;
+ temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
+ cmp_mode, XEXP (op0, 0),
+ XEXP (op0, 1));
+
+ /* See if any simplifications were possible. */
+ if (temp)
+ {
+ if (GET_CODE (temp) == CONST_INT)
+ return temp == const0_rtx ? op2 : op1;
+ else if (temp)
+ return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
}
}
break;
@@ -3721,7 +3748,6 @@ simplify_rtx (rtx x)
{
enum rtx_code code = GET_CODE (x);
enum machine_mode mode = GET_MODE (x);
- rtx temp;
switch (GET_RTX_CLASS (code))
{
@@ -3745,24 +3771,19 @@ simplify_rtx (rtx x)
case RTX_COMPARE:
case RTX_COMM_COMPARE:
- temp = simplify_relational_operation (code, mode,
- ((GET_MODE (XEXP (x, 0))
- != VOIDmode)
- ? GET_MODE (XEXP (x, 0))
- : GET_MODE (XEXP (x, 1))),
- XEXP (x, 0), XEXP (x, 1));
- return temp;
+ return simplify_relational_operation (code, mode,
+ ((GET_MODE (XEXP (x, 0))
+ != VOIDmode)
+ ? GET_MODE (XEXP (x, 0))
+ : GET_MODE (XEXP (x, 1))),
+ XEXP (x, 0),
+ XEXP (x, 1));
case RTX_EXTRA:
if (code == SUBREG)
return simplify_gen_subreg (mode, SUBREG_REG (x),
GET_MODE (SUBREG_REG (x)),
SUBREG_BYTE (x));
- if (code == CONSTANT_P_RTX)
- {
- if (CONSTANT_P (XEXP (x, 0)))
- return const1_rtx;
- }
break;
case RTX_OBJ:
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 422fd054491..0baeb8ce272 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -385,15 +385,13 @@ struct stmt_status GTY(())
#define goto_fixup_chain (cfun->stmt->x_goto_fixup_chain)
/* Nonzero if we are using EH to handle cleanups. */
-static int using_eh_for_cleanups_p = 0;
+int using_eh_for_cleanups_p = 0;
static int n_occurrences (int, const char *);
static bool decl_conflicts_with_clobbers_p (tree, const HARD_REG_SET);
static void expand_goto_internal (tree, rtx, rtx);
static int expand_fixup (tree, rtx, rtx);
-static rtx expand_nl_handler_label (rtx, rtx);
static void expand_nl_goto_receiver (void);
-static void expand_nl_goto_receivers (struct nesting *);
static void fixup_gotos (struct nesting *, rtx, tree, rtx, int);
static bool check_operand_nalternatives (tree, tree);
static bool check_unique_operand_names (tree, tree);
@@ -470,7 +468,12 @@ label_rtx (tree label)
abort ();
if (!DECL_RTL_SET_P (label))
- SET_DECL_RTL (label, gen_label_rtx ());
+ {
+ rtx r = gen_label_rtx ();
+ SET_DECL_RTL (label, r);
+ if (FORCED_LABEL (label) || DECL_NONLOCAL (label))
+ LABEL_PRESERVE_P (r) = 1;
+ }
return DECL_RTL (label);
}
@@ -487,8 +490,7 @@ force_label_rtx (tree label)
if (!function)
abort ();
- if (function != current_function_decl
- && function != inline_function_decl)
+ if (function != current_function_decl)
p = find_function_data (function);
else
p = cfun;
@@ -555,12 +557,27 @@ void
expand_label (tree label)
{
struct label_chain *p;
+ rtx label_r = label_rtx (label);
do_pending_stack_adjust ();
- emit_label (label_rtx (label));
+ emit_label (label_r);
if (DECL_NAME (label))
LABEL_NAME (DECL_RTL (label)) = IDENTIFIER_POINTER (DECL_NAME (label));
+ if (DECL_NONLOCAL (label))
+ {
+ expand_nl_goto_receiver ();
+ nonlocal_goto_handler_labels
+ = gen_rtx_EXPR_LIST (VOIDmode, label_r,
+ nonlocal_goto_handler_labels);
+ }
+
+ if (FORCED_LABEL (label))
+ forced_labels = gen_rtx_EXPR_LIST (VOIDmode, label_r, forced_labels);
+
+ if (DECL_NONLOCAL (label) || FORCED_LABEL (label))
+ maybe_set_first_label_num (label_r);
+
if (stack_block_stack != 0)
{
p = ggc_alloc (sizeof (struct label_chain));
@@ -570,26 +587,6 @@ expand_label (tree label)
}
}
-/* Declare that LABEL (a LABEL_DECL) may be used for nonlocal gotos
- from nested functions. */
-
-void
-declare_nonlocal_label (tree label)
-{
- rtx slot = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
-
- nonlocal_labels = tree_cons (NULL_TREE, label, nonlocal_labels);
- LABEL_PRESERVE_P (label_rtx (label)) = 1;
- if (nonlocal_goto_handler_slots == 0)
- {
- emit_stack_save (SAVE_NONLOCAL,
- &nonlocal_goto_stack_level,
- PREV_INSN (tail_recursion_reentry));
- }
- nonlocal_goto_handler_slots
- = gen_rtx_EXPR_LIST (VOIDmode, slot, nonlocal_goto_handler_slots);
-}
-
/* Generate RTL code for a `goto' statement with target label LABEL.
LABEL should be a LABEL_DECL tree node that was or will later be
defined with `expand_label'. */
@@ -597,91 +594,15 @@ declare_nonlocal_label (tree label)
void
expand_goto (tree label)
{
- tree context;
-
- /* Check for a nonlocal goto to a containing function. */
- context = decl_function_context (label);
+#ifdef ENABLE_CHECKING
+ /* Check for a nonlocal goto to a containing function. Should have
+ gotten translated to __builtin_nonlocal_goto. */
+ tree context = decl_function_context (label);
if (context != 0 && context != current_function_decl)
- {
- struct function *p = find_function_data (context);
- rtx label_ref = gen_rtx_LABEL_REF (Pmode, label_rtx (label));
- rtx handler_slot, static_chain, save_area, insn;
- tree link;
-
- /* Find the corresponding handler slot for this label. */
- handler_slot = p->x_nonlocal_goto_handler_slots;
- for (link = p->x_nonlocal_labels; TREE_VALUE (link) != label;
- link = TREE_CHAIN (link))
- handler_slot = XEXP (handler_slot, 1);
- handler_slot = XEXP (handler_slot, 0);
-
- p->has_nonlocal_label = 1;
- current_function_has_nonlocal_goto = 1;
- LABEL_REF_NONLOCAL_P (label_ref) = 1;
-
- /* Copy the rtl for the slots so that they won't be shared in
- case the virtual stack vars register gets instantiated differently
- in the parent than in the child. */
-
- static_chain = copy_to_reg (lookup_static_chain (label));
-
- /* Get addr of containing function's current nonlocal goto handler,
- which will do any cleanups and then jump to the label. */
- handler_slot = copy_to_reg (replace_rtx (copy_rtx (handler_slot),
- virtual_stack_vars_rtx,
- static_chain));
-
- /* Get addr of containing function's nonlocal save area. */
- save_area = p->x_nonlocal_goto_stack_level;
- if (save_area)
- save_area = replace_rtx (copy_rtx (save_area),
- virtual_stack_vars_rtx, static_chain);
-
-#if HAVE_nonlocal_goto
- if (HAVE_nonlocal_goto)
- emit_insn (gen_nonlocal_goto (static_chain, handler_slot,
- save_area, label_ref));
- else
+ abort ();
#endif
- {
- emit_insn (gen_rtx_CLOBBER (VOIDmode,
- gen_rtx_MEM (BLKmode,
- gen_rtx_SCRATCH (VOIDmode))));
- emit_insn (gen_rtx_CLOBBER (VOIDmode,
- gen_rtx_MEM (BLKmode,
- hard_frame_pointer_rtx)));
-
- /* Restore frame pointer for containing function.
- This sets the actual hard register used for the frame pointer
- to the location of the function's incoming static chain info.
- The non-local goto handler will then adjust it to contain the
- proper value and reload the argument pointer, if needed. */
- emit_move_insn (hard_frame_pointer_rtx, static_chain);
- emit_stack_restore (SAVE_NONLOCAL, save_area, NULL_RTX);
-
- /* USE of hard_frame_pointer_rtx added for consistency;
- not clear if really needed. */
- emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
- emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
- emit_indirect_jump (handler_slot);
- }
- /* Search backwards to the jump insn and mark it as a
- non-local goto. */
- for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
- {
- if (GET_CODE (insn) == JUMP_INSN)
- {
- REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
- const0_rtx, REG_NOTES (insn));
- break;
- }
- else if (GET_CODE (insn) == CALL_INSN)
- break;
- }
- }
- else
- expand_goto_internal (label, label_rtx (label), NULL_RTX);
+ expand_goto_internal (label, label_rtx (label), NULL_RTX);
}
/* Generate RTL code for a `goto' statement with target label BODY.
@@ -1251,9 +1172,6 @@ parse_output_constraint (const char **constraint_p, int operand_num,
break;
}
- if (*is_inout && !*allows_reg)
- warning ("read-write constraint does not allow a register");
-
return true;
}
@@ -1393,6 +1311,33 @@ parse_input_constraint (const char **constraint_p, int input_num,
return true;
}
+/* INPUT is one of the input operands from EXPR, an ASM_EXPR. Returns true
+ if it is an operand which must be passed in memory (i.e. an "m"
+ constraint), false otherwise. */
+
+bool
+asm_op_is_mem_input (tree input, tree expr)
+{
+ const char *constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (input)));
+ tree outputs = ASM_OUTPUTS (expr);
+ int noutputs = list_length (outputs);
+ const char **constraints
+ = (const char **) alloca ((noutputs) * sizeof (const char *));
+ int i = 0;
+ bool allows_mem, allows_reg;
+ tree t;
+
+ /* Collect output constraints. */
+ for (t = outputs; t ; t = TREE_CHAIN (t), i++)
+ constraints[i] = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
+
+ /* We pass 0 for input_num, ninputs and ninout; they are only used for
+ error checking which will be done at expand time. */
+ parse_input_constraint (&constraint, 0, 0, noutputs, 0, constraints,
+ &allows_mem, &allows_reg);
+ return (!allows_reg && allows_mem);
+}
+
/* Check for overlap between registers marked in CLOBBERED_REGS and
anything inappropriate in DECL. Emit error and return TRUE for error,
FALSE for ok. */
@@ -1889,6 +1834,52 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
free_temp_slots ();
}
+void
+expand_asm_expr (tree exp)
+{
+ int noutputs, i;
+ tree outputs, tail;
+ tree *o;
+
+ if (ASM_INPUT_P (exp))
+ {
+ expand_asm (ASM_STRING (exp), ASM_VOLATILE_P (exp));
+ return;
+ }
+
+ outputs = ASM_OUTPUTS (exp);
+ noutputs = list_length (outputs);
+ /* o[I] is the place that output number I should be written. */
+ o = (tree *) alloca (noutputs * sizeof (tree));
+
+ /* Record the contents of OUTPUTS before it is modified. */
+ for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
+ o[i] = TREE_VALUE (tail);
+
+ /* Generate the ASM_OPERANDS insn; store into the TREE_VALUEs of
+ OUTPUTS some trees for where the values were actually stored. */
+ expand_asm_operands (ASM_STRING (exp), outputs, ASM_INPUTS (exp),
+ ASM_CLOBBERS (exp), ASM_VOLATILE_P (exp),
+ input_location);
+
+ /* Copy all the intermediate outputs into the specified outputs. */
+ for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
+ {
+ if (o[i] != TREE_VALUE (tail))
+ {
+ expand_assignment (o[i], TREE_VALUE (tail), 0);
+ free_temp_slots ();
+
+ /* Restore the original value so that it's correct the next
+ time we expand this function. */
+ TREE_VALUE (tail) = o[i];
+ }
+ }
+
+ /* Those MODIFY_EXPRs could do autoincrements. */
+ emit_queue ();
+}
+
/* A subroutine of expand_asm_operands. Check that all operands have
the same number of alternatives. Return true if so. */
@@ -2150,7 +2141,7 @@ expand_expr_stmt_value (tree exp, int want_value, int maybe_last)
{
if (TREE_SIDE_EFFECTS (exp))
warn_if_unused_value (exp);
- else if (!VOID_TYPE_P (TREE_TYPE (exp)))
+ else if (!VOID_TYPE_P (TREE_TYPE (exp)) && !TREE_NO_WARNING (exp))
warning ("%Hstatement with no effect", &emit_locus);
}
@@ -2242,7 +2233,7 @@ warn_if_unused_value (tree exp)
return warn_if_unused_value (TREE_OPERAND (exp, 1));
case SAVE_EXPR:
- return warn_if_unused_value (TREE_OPERAND (exp, 1));
+ return warn_if_unused_value (TREE_OPERAND (exp, 0));
case TRUTH_ORIF_EXPR:
case TRUTH_ANDIF_EXPR:
@@ -2250,7 +2241,7 @@ warn_if_unused_value (tree exp)
return warn_if_unused_value (TREE_OPERAND (exp, 1));
case COMPOUND_EXPR:
- if (TREE_NO_UNUSED_WARNING (exp))
+ if (TREE_NO_WARNING (exp))
return 0;
if (warn_if_unused_value (TREE_OPERAND (exp, 0)))
return 1;
@@ -2263,7 +2254,7 @@ warn_if_unused_value (tree exp)
case CONVERT_EXPR:
case NON_LVALUE_EXPR:
/* Don't warn about conversions not explicit in the user's program. */
- if (TREE_NO_UNUSED_WARNING (exp))
+ if (TREE_NO_WARNING (exp))
return 0;
/* Assignment to a cast usually results in a cast of a modify.
Don't complain about that. There can be an arbitrary number of
@@ -2508,7 +2499,6 @@ expand_start_loop (int exit_flag)
do_pending_stack_adjust ();
emit_queue ();
- emit_note (NOTE_INSN_LOOP_BEG);
emit_label (thisloop->data.loop.start_label);
return thisloop;
@@ -2558,7 +2548,6 @@ void
expand_loop_continue_here (void)
{
do_pending_stack_adjust ();
- emit_note (NOTE_INSN_LOOP_CONT);
emit_label (loop_stack->data.loop.continue_label);
}
@@ -2573,10 +2562,6 @@ expand_end_loop (void)
int eh_regions, debug_blocks;
bool empty_test;
- /* Mark the continue-point at the top of the loop if none elsewhere. */
- if (start_label == loop_stack->data.loop.continue_label)
- emit_note_before (NOTE_INSN_LOOP_CONT, start_label);
-
do_pending_stack_adjust ();
/* If the loop starts with a loop exit, roll that to the end where
@@ -2584,7 +2569,6 @@ expand_end_loop (void)
If the loop presently looks like this (in pseudo-C):
- LOOP_BEG
start_label:
if (test) goto end_label;
LOOP_END_TOP_COND
@@ -2594,7 +2578,6 @@ expand_end_loop (void)
transform it to look like:
- LOOP_BEG
goto start_label;
top_label:
body;
@@ -2623,16 +2606,12 @@ expand_end_loop (void)
if (NOTE_LINE_NUMBER (etc_note) == NOTE_INSN_LOOP_END_TOP_COND)
break;
- /* We must not walk into a nested loop. */
- else if (NOTE_LINE_NUMBER (etc_note) == NOTE_INSN_LOOP_BEG)
- {
- etc_note = NULL_RTX;
- break;
- }
+ if (NOTE_LINE_NUMBER (etc_note) == NOTE_INSN_LOOP_BEG)
+ abort ();
/* At the same time, scan for EH region notes, as we don't want
to scrog region nesting. This shouldn't happen, but... */
- else if (NOTE_LINE_NUMBER (etc_note) == NOTE_INSN_EH_REGION_BEG)
+ if (NOTE_LINE_NUMBER (etc_note) == NOTE_INSN_EH_REGION_BEG)
eh_regions++;
else if (NOTE_LINE_NUMBER (etc_note) == NOTE_INSN_EH_REGION_END)
{
@@ -2672,12 +2651,6 @@ expand_end_loop (void)
rtx top_label = gen_label_rtx ();
rtx start_move = start_label;
- /* If the start label is preceded by a NOTE_INSN_LOOP_CONT note,
- then we want to move this note also. */
- if (GET_CODE (PREV_INSN (start_move)) == NOTE
- && NOTE_LINE_NUMBER (PREV_INSN (start_move)) == NOTE_INSN_LOOP_CONT)
- start_move = PREV_INSN (start_move);
-
emit_label_before (top_label, start_move);
/* Actually move the insns. If the debug scopes are nested, we
@@ -2709,8 +2682,10 @@ expand_end_loop (void)
start_label = top_label;
}
+ if (etc_note)
+ delete_insn (etc_note);
+
emit_jump (start_label);
- emit_note (NOTE_INSN_LOOP_END);
emit_label (loop_stack->data.loop.end_label);
POPSTACK (loop_stack);
@@ -3077,11 +3052,8 @@ expand_return (tree retval)
else if ((TREE_CODE (retval) == MODIFY_EXPR || TREE_CODE (retval) == INIT_EXPR)
&& TREE_CODE (TREE_OPERAND (retval, 0)) == RESULT_DECL)
retval_rhs = TREE_OPERAND (retval, 1);
- else if (VOID_TYPE_P (TREE_TYPE (retval)))
- /* Recognize tail-recursive call to void function. */
- retval_rhs = retval;
else
- retval_rhs = NULL_TREE;
+ retval_rhs = retval;
last_insn = get_last_insn ();
@@ -3316,8 +3288,8 @@ tail_recursion_args (tree actuals, tree formals)
for (a = actuals, f = formals, i = 0; a && f; a = TREE_CHAIN (a), f = TREE_CHAIN (f), i++)
{
- if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (a)))
- != TYPE_MAIN_VARIANT (TREE_TYPE (f)))
+ if (!lang_hooks.types_compatible_p (TREE_TYPE (TREE_VALUE (a)),
+ TREE_TYPE (f)))
return 0;
if (GET_CODE (DECL_RTL (f)) != REG || DECL_MODE (f) == BLKmode)
return 0;
@@ -3409,7 +3381,7 @@ expand_start_bindings_and_block (int flags, tree block)
abort ();
/* Create a note to mark the beginning of the block. */
- if (block_flag)
+ if (block_flag && !cfun->dont_emit_block_notes)
{
note = emit_note (NOTE_INSN_BLOCK_BEG);
NOTE_BLOCK (note) = block;
@@ -3539,35 +3511,12 @@ current_nesting_level (void)
return cfun ? block_stack : 0;
}
-/* Emit a handler label for a nonlocal goto handler.
- Also emit code to store the handler label in SLOT before BEFORE_INSN. */
-
-static rtx
-expand_nl_handler_label (rtx slot, rtx before_insn)
-{
- rtx insns;
- rtx handler_label = gen_label_rtx ();
-
- /* Don't let cleanup_cfg delete the handler. */
- LABEL_PRESERVE_P (handler_label) = 1;
-
- start_sequence ();
- emit_move_insn (slot, gen_rtx_LABEL_REF (Pmode, handler_label));
- insns = get_insns ();
- end_sequence ();
- emit_insn_before (insns, before_insn);
-
- emit_label (handler_label);
-
- return handler_label;
-}
-
/* Emit code to restore vital registers at the beginning of a nonlocal goto
handler. */
static void
expand_nl_goto_receiver (void)
{
- /* Clobber the FP when we get here, so we have to make sure it's
+ /* Clobber the FP when we get here, so we have to make sure it's
marked as used by this function. */
emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
@@ -3632,82 +3581,6 @@ expand_nl_goto_receiver (void)
emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
}
-/* Make handlers for nonlocal gotos taking place in the function calls in
- block THISBLOCK. */
-
-static void
-expand_nl_goto_receivers (struct nesting *thisblock)
-{
- tree link;
- rtx afterward = gen_label_rtx ();
- rtx insns, slot;
- rtx label_list;
- int any_invalid;
-
- /* Record the handler address in the stack slot for that purpose,
- during this block, saving and restoring the outer value. */
- if (thisblock->next != 0)
- for (slot = nonlocal_goto_handler_slots; slot; slot = XEXP (slot, 1))
- {
- rtx save_receiver = gen_reg_rtx (Pmode);
- emit_move_insn (XEXP (slot, 0), save_receiver);
-
- start_sequence ();
- emit_move_insn (save_receiver, XEXP (slot, 0));
- insns = get_insns ();
- end_sequence ();
- emit_insn_before (insns, thisblock->data.block.first_insn);
- }
-
- /* Jump around the handlers; they run only when specially invoked. */
- emit_jump (afterward);
-
- /* Make a separate handler for each label. */
- link = nonlocal_labels;
- slot = nonlocal_goto_handler_slots;
- label_list = NULL_RTX;
- for (; link; link = TREE_CHAIN (link), slot = XEXP (slot, 1))
- /* Skip any labels we shouldn't be able to jump to from here,
- we generate one special handler for all of them below which just calls
- abort. */
- if (! DECL_TOO_LATE (TREE_VALUE (link)))
- {
- rtx lab;
- lab = expand_nl_handler_label (XEXP (slot, 0),
- thisblock->data.block.first_insn);
- label_list = gen_rtx_EXPR_LIST (VOIDmode, lab, label_list);
-
- expand_nl_goto_receiver ();
-
- /* Jump to the "real" nonlocal label. */
- expand_goto (TREE_VALUE (link));
- }
-
- /* A second pass over all nonlocal labels; this time we handle those
- we should not be able to jump to at this point. */
- link = nonlocal_labels;
- slot = nonlocal_goto_handler_slots;
- any_invalid = 0;
- for (; link; link = TREE_CHAIN (link), slot = XEXP (slot, 1))
- if (DECL_TOO_LATE (TREE_VALUE (link)))
- {
- rtx lab;
- lab = expand_nl_handler_label (XEXP (slot, 0),
- thisblock->data.block.first_insn);
- label_list = gen_rtx_EXPR_LIST (VOIDmode, lab, label_list);
- any_invalid = 1;
- }
-
- if (any_invalid)
- {
- expand_nl_goto_receiver ();
- expand_builtin_trap ();
- }
-
- nonlocal_goto_handler_labels = label_list;
- emit_label (afterward);
-}
-
/* Warn about any unused VARS (which may contain nodes other than
VAR_DECLs, but such nodes are ignored). The nodes are connected
via the TREE_CHAIN field. */
@@ -3755,18 +3628,6 @@ expand_end_bindings (tree vars, int mark_ends, int dont_jump_in)
emit_label (thisblock->exit_label);
}
- /* If necessary, make handlers for nonlocal gotos taking
- place in the function calls in this block. */
- if (function_call_count != 0 && nonlocal_labels
- /* Make handler for outermost block
- if there were any nonlocal gotos to this function. */
- && (thisblock->next == 0 ? current_function_has_nonlocal_label
- /* Make handler for inner block if it has something
- special to do when you jump out of it. */
- : (thisblock->data.block.cleanups != 0
- || thisblock->data.block.stack_level != 0)))
- expand_nl_goto_receivers (thisblock);
-
/* Don't allow jumping into a block that has a stack level.
Cleanups are allowed, though. */
if (dont_jump_in > 0
@@ -3827,9 +3688,8 @@ expand_end_bindings (tree vars, int mark_ends, int dont_jump_in)
{
emit_stack_restore (thisblock->next ? SAVE_BLOCK : SAVE_FUNCTION,
thisblock->data.block.stack_level, NULL_RTX);
- if (nonlocal_goto_handler_slots != 0)
- emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level,
- NULL_RTX);
+ if (cfun->nonlocal_goto_save_area)
+ update_nonlocal_goto_save_area ();
}
/* Any gotos out of this block must also do these things.
@@ -3846,7 +3706,7 @@ expand_end_bindings (tree vars, int mark_ends, int dont_jump_in)
We do this now, after running cleanups on the variables
just going out of scope, so they are in scope for their cleanups. */
- if (mark_ends)
+ if (mark_ends && !cfun->dont_emit_block_notes)
{
rtx note = emit_note (NOTE_INSN_BLOCK_END);
NOTE_BLOCK (note) = NOTE_BLOCK (thisblock->data.block.first_insn);
@@ -4041,6 +3901,66 @@ expand_decl (tree decl)
}
}
+/* Emit code to allocate T_SIZE bytes of dynamic stack space for ALLOC. */
+void
+expand_stack_alloc (tree alloc, tree t_size)
+{
+ rtx address, dest, size;
+ tree var, type;
+
+ if (TREE_CODE (alloc) != ADDR_EXPR)
+ abort ();
+ var = TREE_OPERAND (alloc, 0);
+ if (TREE_CODE (var) != VAR_DECL)
+ abort ();
+
+ type = TREE_TYPE (var);
+
+ /* In function-at-a-time mode, variable_size doesn't expand this,
+ so do it now. */
+ if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
+ expand_expr (TYPE_MAX_VALUE (TYPE_DOMAIN (type)),
+ const0_rtx, VOIDmode, 0);
+
+ /* Compute the variable's size, in bytes. */
+ size = expand_expr (t_size, NULL_RTX, VOIDmode, 0);
+ free_temp_slots ();
+
+ /* Allocate space on the stack for the variable. */
+ address = XEXP (DECL_RTL (var), 0);
+ dest = allocate_dynamic_stack_space (size, address, TYPE_ALIGN (type));
+ if (dest != address)
+ emit_move_insn (address, dest);
+
+ /* Indicate the alignment we actually gave this variable. */
+#ifdef STACK_BOUNDARY
+ DECL_ALIGN (var) = STACK_BOUNDARY;
+#else
+ DECL_ALIGN (var) = BIGGEST_ALIGNMENT;
+#endif
+ DECL_USER_ALIGN (var) = 0;
+}
+
+/* Emit code to save the current value of stack. */
+rtx
+expand_stack_save (void)
+{
+ rtx ret = NULL_RTX;
+
+ do_pending_stack_adjust ();
+ emit_stack_save (SAVE_BLOCK, &ret, NULL_RTX);
+ return ret;
+}
+
+/* Emit code to restore the current value of stack. */
+void
+expand_stack_restore (tree var)
+{
+ rtx sa = DECL_RTL (var);
+
+ emit_stack_restore (SAVE_BLOCK, sa, NULL_RTX);
+}
+
/* Emit code to perform the initialization of a declaration DECL. */
void
@@ -4364,6 +4284,23 @@ last_cleanup_this_contour (void)
return block_stack->data.block.cleanups;
}
+
+/* Return nonzero if any containing block has a stack level or
+ cleanups. */
+
+int
+containing_blocks_have_cleanups_or_stack_level (void)
+{
+ struct nesting *block;
+
+ for (block = block_stack; block; block = block->next)
+ if (block->data.block.stack_level != 0
+ || block->data.block.cleanups != 0)
+ return 1;
+
+ return 0;
+}
+
/* Return 1 if there are any pending cleanups at this point.
Check the current contour as well as contours that enclose
the current contour. */
@@ -4526,7 +4463,7 @@ pushcase (tree value, tree (*converter) (tree, tree), tree label,
|| ! int_fits_type_p (value, index_type)))
return 3;
- return add_case_node (value, value, label, duplicate);
+ return add_case_node (value, value, label, duplicate, false);
}
/* Like pushcase but this case applies to all values between VALUE1 and
@@ -4592,7 +4529,7 @@ pushcase_range (tree value1, tree value2, tree (*converter) (tree, tree),
|| ! int_fits_type_p (value2, index_type))
return 3;
- return add_case_node (value1, value2, label, duplicate);
+ return add_case_node (value1, value2, label, duplicate, false);
}
/* Do the actual insertion of a case label for pushcase and pushcase_range
@@ -4600,7 +4537,8 @@ pushcase_range (tree value1, tree value2, tree (*converter) (tree, tree),
slowdown for large switch statements. */
int
-add_case_node (tree low, tree high, tree label, tree *duplicate)
+add_case_node (tree low, tree high, tree label, tree *duplicate,
+ bool dont_expand_label)
{
struct case_node *p, **q, *r;
@@ -4619,7 +4557,8 @@ add_case_node (tree low, tree high, tree label, tree *duplicate)
return 2;
}
case_stack->data.case_stmt.default_label = label;
- expand_label (label);
+ if (!dont_expand_label)
+ expand_label (label);
return 0;
}
@@ -4658,7 +4597,8 @@ add_case_node (tree low, tree high, tree label, tree *duplicate)
r->high = high;
r->code_label = label;
- expand_label (label);
+ if (!dont_expand_label)
+ expand_label (label);
*q = r;
r->parent = p;
@@ -4835,326 +4775,6 @@ add_case_node (tree low, tree high, tree label, tree *duplicate)
return 0;
}
-/* Returns the number of possible values of TYPE.
- Returns -1 if the number is unknown, variable, or if the number does not
- fit in a HOST_WIDE_INT.
- Sets *SPARSENESS to 2 if TYPE is an ENUMERAL_TYPE whose values
- do not increase monotonically (there may be duplicates);
- to 1 if the values increase monotonically, but not always by 1;
- otherwise sets it to 0. */
-
-HOST_WIDE_INT
-all_cases_count (tree type, int *sparseness)
-{
- tree t;
- HOST_WIDE_INT count, minval, lastval;
-
- *sparseness = 0;
-
- switch (TREE_CODE (type))
- {
- case BOOLEAN_TYPE:
- count = 2;
- break;
-
- case CHAR_TYPE:
- count = 1 << BITS_PER_UNIT;
- break;
-
- default:
- case INTEGER_TYPE:
- if (TYPE_MAX_VALUE (type) != 0
- && 0 != (t = fold (build (MINUS_EXPR, type, TYPE_MAX_VALUE (type),
- TYPE_MIN_VALUE (type))))
- && 0 != (t = fold (build (PLUS_EXPR, type, t,
- convert (type, integer_zero_node))))
- && host_integerp (t, 1))
- count = tree_low_cst (t, 1);
- else
- return -1;
- break;
-
- case ENUMERAL_TYPE:
- /* Don't waste time with enumeral types with huge values. */
- if (! host_integerp (TYPE_MIN_VALUE (type), 0)
- || TYPE_MAX_VALUE (type) == 0
- || ! host_integerp (TYPE_MAX_VALUE (type), 0))
- return -1;
-
- lastval = minval = tree_low_cst (TYPE_MIN_VALUE (type), 0);
- count = 0;
-
- for (t = TYPE_VALUES (type); t != NULL_TREE; t = TREE_CHAIN (t))
- {
- HOST_WIDE_INT thisval = tree_low_cst (TREE_VALUE (t), 0);
-
- if (*sparseness == 2 || thisval <= lastval)
- *sparseness = 2;
- else if (thisval != minval + count)
- *sparseness = 1;
-
- lastval = thisval;
- count++;
- }
- }
-
- return count;
-}
-
-#define BITARRAY_TEST(ARRAY, INDEX) \
- ((ARRAY)[(unsigned) (INDEX) / HOST_BITS_PER_CHAR]\
- & (1 << ((unsigned) (INDEX) % HOST_BITS_PER_CHAR)))
-#define BITARRAY_SET(ARRAY, INDEX) \
- ((ARRAY)[(unsigned) (INDEX) / HOST_BITS_PER_CHAR]\
- |= 1 << ((unsigned) (INDEX) % HOST_BITS_PER_CHAR))
-
-/* Set the elements of the bitstring CASES_SEEN (which has length COUNT),
- with the case values we have seen, assuming the case expression
- has the given TYPE.
- SPARSENESS is as determined by all_cases_count.
-
- The time needed is proportional to COUNT, unless
- SPARSENESS is 2, in which case quadratic time is needed. */
-
-void
-mark_seen_cases (tree type, unsigned char *cases_seen, HOST_WIDE_INT count,
- int sparseness)
-{
- tree next_node_to_try = NULL_TREE;
- HOST_WIDE_INT next_node_offset = 0;
-
- struct case_node *n, *root = case_stack->data.case_stmt.case_list;
- tree val = make_node (INTEGER_CST);
-
- TREE_TYPE (val) = type;
- if (! root)
- /* Do nothing. */
- ;
- else if (sparseness == 2)
- {
- tree t;
- unsigned HOST_WIDE_INT xlo;
-
- /* This less efficient loop is only needed to handle
- duplicate case values (multiple enum constants
- with the same value). */
- TREE_TYPE (val) = TREE_TYPE (root->low);
- for (t = TYPE_VALUES (type), xlo = 0; t != NULL_TREE;
- t = TREE_CHAIN (t), xlo++)
- {
- TREE_INT_CST_LOW (val) = TREE_INT_CST_LOW (TREE_VALUE (t));
- TREE_INT_CST_HIGH (val) = TREE_INT_CST_HIGH (TREE_VALUE (t));
- n = root;
- do
- {
- /* Keep going past elements distinctly greater than VAL. */
- if (tree_int_cst_lt (val, n->low))
- n = n->left;
-
- /* or distinctly less than VAL. */
- else if (tree_int_cst_lt (n->high, val))
- n = n->right;
-
- else
- {
- /* We have found a matching range. */
- BITARRAY_SET (cases_seen, xlo);
- break;
- }
- }
- while (n);
- }
- }
- else
- {
- if (root->left)
- case_stack->data.case_stmt.case_list = root = case_tree2list (root, 0);
-
- for (n = root; n; n = n->right)
- {
- TREE_INT_CST_LOW (val) = TREE_INT_CST_LOW (n->low);
- TREE_INT_CST_HIGH (val) = TREE_INT_CST_HIGH (n->low);
- while (! tree_int_cst_lt (n->high, val))
- {
- /* Calculate (into xlo) the "offset" of the integer (val).
- The element with lowest value has offset 0, the next smallest
- element has offset 1, etc. */
-
- unsigned HOST_WIDE_INT xlo;
- HOST_WIDE_INT xhi;
- tree t;
-
- if (sparseness && TYPE_VALUES (type) != NULL_TREE)
- {
- /* The TYPE_VALUES will be in increasing order, so
- starting searching where we last ended. */
- t = next_node_to_try;
- xlo = next_node_offset;
- xhi = 0;
- for (;;)
- {
- if (t == NULL_TREE)
- {
- t = TYPE_VALUES (type);
- xlo = 0;
- }
- if (tree_int_cst_equal (val, TREE_VALUE (t)))
- {
- next_node_to_try = TREE_CHAIN (t);
- next_node_offset = xlo + 1;
- break;
- }
- xlo++;
- t = TREE_CHAIN (t);
- if (t == next_node_to_try)
- {
- xlo = -1;
- break;
- }
- }
- }
- else
- {
- t = TYPE_MIN_VALUE (type);
- if (t)
- neg_double (TREE_INT_CST_LOW (t), TREE_INT_CST_HIGH (t),
- &xlo, &xhi);
- else
- xlo = xhi = 0;
- add_double (xlo, xhi,
- TREE_INT_CST_LOW (val), TREE_INT_CST_HIGH (val),
- &xlo, &xhi);
- }
-
- if (xhi == 0 && xlo < (unsigned HOST_WIDE_INT) count)
- BITARRAY_SET (cases_seen, xlo);
-
- add_double (TREE_INT_CST_LOW (val), TREE_INT_CST_HIGH (val),
- 1, 0,
- &TREE_INT_CST_LOW (val), &TREE_INT_CST_HIGH (val));
- }
- }
- }
-}
-
-/* Given a switch statement with an expression that is an enumeration
- type, warn if any of the enumeration type's literals are not
- covered by the case expressions of the switch. Also, warn if there
- are any extra switch cases that are *not* elements of the
- enumerated type.
-
- Historical note:
-
- At one stage this function would: ``If all enumeration literals
- were covered by the case expressions, turn one of the expressions
- into the default expression since it should not be possible to fall
- through such a switch.''
-
- That code has since been removed as: ``This optimization is
- disabled because it causes valid programs to fail. ANSI C does not
- guarantee that an expression with enum type will have a value that
- is the same as one of the enumeration literals.'' */
-
-void
-check_for_full_enumeration_handling (tree type)
-{
- struct case_node *n;
- tree chain;
-
- /* True iff the selector type is a numbered set mode. */
- int sparseness = 0;
-
- /* The number of possible selector values. */
- HOST_WIDE_INT size;
-
- /* For each possible selector value. a one iff it has been matched
- by a case value alternative. */
- unsigned char *cases_seen;
-
- /* The allocated size of cases_seen, in chars. */
- HOST_WIDE_INT bytes_needed;
-
- size = all_cases_count (type, &sparseness);
- bytes_needed = (size + HOST_BITS_PER_CHAR) / HOST_BITS_PER_CHAR;
-
- if (size > 0 && size < 600000
- /* We deliberately use calloc here, not cmalloc, so that we can suppress
- this optimization if we don't have enough memory rather than
- aborting, as xmalloc would do. */
- && (cases_seen = really_call_calloc (bytes_needed, 1)) != NULL)
- {
- HOST_WIDE_INT i;
- tree v = TYPE_VALUES (type);
-
- /* The time complexity of this code is normally O(N), where
- N being the number of members in the enumerated type.
- However, if type is an ENUMERAL_TYPE whose values do not
- increase monotonically, O(N*log(N)) time may be needed. */
-
- mark_seen_cases (type, cases_seen, size, sparseness);
-
- for (i = 0; v != NULL_TREE && i < size; i++, v = TREE_CHAIN (v))
- if (BITARRAY_TEST (cases_seen, i) == 0)
- warning ("enumeration value `%s' not handled in switch",
- IDENTIFIER_POINTER (TREE_PURPOSE (v)));
-
- free (cases_seen);
- }
-
- /* Now we go the other way around; we warn if there are case
- expressions that don't correspond to enumerators. This can
- occur since C and C++ don't enforce type-checking of
- assignments to enumeration variables. */
-
- if (case_stack->data.case_stmt.case_list
- && case_stack->data.case_stmt.case_list->left)
- case_stack->data.case_stmt.case_list
- = case_tree2list (case_stack->data.case_stmt.case_list, 0);
- for (n = case_stack->data.case_stmt.case_list; n; n = n->right)
- {
- for (chain = TYPE_VALUES (type);
- chain && !tree_int_cst_equal (n->low, TREE_VALUE (chain));
- chain = TREE_CHAIN (chain))
- ;
-
- if (!chain)
- {
- if (TYPE_NAME (type) == 0)
- warning ("case value `%ld' not in enumerated type",
- (long) TREE_INT_CST_LOW (n->low));
- else
- warning ("case value `%ld' not in enumerated type `%s'",
- (long) TREE_INT_CST_LOW (n->low),
- IDENTIFIER_POINTER ((TREE_CODE (TYPE_NAME (type))
- == IDENTIFIER_NODE)
- ? TYPE_NAME (type)
- : DECL_NAME (TYPE_NAME (type))));
- }
- if (!tree_int_cst_equal (n->low, n->high))
- {
- for (chain = TYPE_VALUES (type);
- chain && !tree_int_cst_equal (n->high, TREE_VALUE (chain));
- chain = TREE_CHAIN (chain))
- ;
-
- if (!chain)
- {
- if (TYPE_NAME (type) == 0)
- warning ("case value `%ld' not in enumerated type",
- (long) TREE_INT_CST_LOW (n->high));
- else
- warning ("case value `%ld' not in enumerated type `%s'",
- (long) TREE_INT_CST_LOW (n->high),
- IDENTIFIER_POINTER ((TREE_CODE (TYPE_NAME (type))
- == IDENTIFIER_NODE)
- ? TYPE_NAME (type)
- : DECL_NAME (TYPE_NAME (type))));
- }
- }
- }
-}
-
-
/* Maximum number of case bit tests. */
#define MAX_CASE_BIT_TESTS 3
@@ -5357,19 +4977,6 @@ expand_end_case_type (tree orig_index, tree orig_type)
/* An ERROR_MARK occurs for various reasons including invalid data type. */
if (index_type != error_mark_node)
{
- /* If the switch expression was an enumerated type, check that
- exactly all enumeration literals are covered by the cases.
- The check is made when -Wswitch was specified and there is no
- default case, or when -Wswitch-enum was specified. */
- if (((warn_switch && !thiscase->data.case_stmt.default_label)
- || warn_switch_enum)
- && TREE_CODE (orig_type) == ENUMERAL_TYPE
- && TREE_CODE (index_expr) != INTEGER_CST)
- check_for_full_enumeration_handling (orig_type);
-
- if (warn_switch_default && !thiscase->data.case_stmt.default_label)
- warning ("switch missing default case");
-
/* If we don't have a default-label, create one here,
after the body of the switch. */
if (thiscase->data.case_stmt.default_label == 0)
@@ -5796,6 +5403,7 @@ estimate_case_costs (case_node_ptr node)
static bool
same_case_target_p (rtx l1, rtx l2)
{
+#if 0
rtx i1, i2;
if (l1 == l2)
@@ -5815,6 +5423,11 @@ same_case_target_p (rtx l1, rtx l2)
{
l2 = XEXP (SET_SRC (PATTERN (i2)), 0);
}
+#endif
+ /* When coming from gimple, we usually won't have emitted either
+ the labels or the body of the switch statement. The job being
+ done here should be done via jump threading at the tree level.
+ Cases that go the same place should have the same label. */
return l1 == l2;
}
@@ -5848,9 +5461,11 @@ group_case_nodes (case_node_ptr head)
while (node)
{
- rtx lab = label_rtx (node->code_label);
+ rtx lab;
case_node_ptr np = node;
+ lab = label_rtx (node->code_label);
+
/* Try to group the successors of NODE with NODE. */
while (((np = np->right) != 0)
/* Do they jump to the same place? */
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index d19fc9fdf3f..5c87a638376 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -67,8 +67,6 @@ static int excess_unit_span (HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT,
HOST_WIDE_INT, tree);
#endif
static void force_type_save_exprs_1 (tree);
-static unsigned int update_alignment_for_field (record_layout_info, tree,
- unsigned int);
extern void debug_rli (record_layout_info);
/* SAVE_EXPRs for sizes of types and decls, waiting to be expanded. */
@@ -161,6 +159,11 @@ variable_size (tree size)
if (TREE_CODE (save) == SAVE_EXPR)
SAVE_EXPR_PERSISTENT_P (save) = 1;
+ if (!immediate_size_expand && cfun && cfun->x_dont_save_pending_sizes_p)
+ /* The front-end doesn't want us to keep a list of the expressions
+ that determine sizes for variable size objects. Trust it. */
+ return size;
+
if (lang_hooks.decls.global_bindings_p ())
{
if (TREE_CONSTANT (size))
@@ -173,10 +176,6 @@ variable_size (tree size)
if (immediate_size_expand)
expand_expr (save, const0_rtx, VOIDmode, 0);
- else if (cfun != 0 && cfun->x_dont_save_pending_sizes_p)
- /* The front-end doesn't want us to keep a list of the expressions
- that determine sizes for variable size objects. */
- ;
else
put_pending_size (save);
@@ -512,10 +511,7 @@ layout_decl (tree decl, unsigned int known_align)
|| TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST))
DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT);
- /* Should this be controlled by DECL_USER_ALIGN, too? */
- if (maximum_field_alignment != 0)
- DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment);
- if (! DECL_USER_ALIGN (decl))
+ if (! DECL_USER_ALIGN (decl) && ! DECL_PACKED (decl))
{
/* Some targets (i.e. i386, VMS) limit struct field alignment
to a lower boundary than alignment of variables unless
@@ -528,6 +524,10 @@ layout_decl (tree decl, unsigned int known_align)
DECL_ALIGN (decl) = ADJUST_FIELD_ALIGN (decl, DECL_ALIGN (decl));
#endif
}
+
+ /* Should this be controlled by DECL_USER_ALIGN, too? */
+ if (maximum_field_alignment != 0)
+ DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment);
}
/* Evaluate nonconstant size only once, either now or as soon as safe. */
@@ -721,7 +721,7 @@ rli_size_so_far (record_layout_info rli)
variable alignment fields in RLI, and return the alignment to give
the FIELD. */
-static unsigned int
+unsigned int
update_alignment_for_field (record_layout_info rli, tree field,
unsigned int known_align)
{
@@ -771,8 +771,10 @@ update_alignment_for_field (record_layout_info rli, tree field,
else if (is_bitfield && PCC_BITFIELD_TYPE_MATTERS)
{
/* Named bit-fields cause the entire structure to have the
- alignment implied by their type. */
- if (DECL_NAME (field) != 0)
+ alignment implied by their type. Some targets also apply the same
+ rules to unnamed bitfields. */
+ if (DECL_NAME (field) != 0
+ || targetm.align_anon_bitfield ())
{
unsigned int type_align = TYPE_ALIGN (type);
@@ -1558,6 +1560,9 @@ layout_type (tree type)
if (type == 0)
abort ();
+ if (type == error_mark_node)
+ return;
+
/* Do nothing if type has been laid out before. */
if (TYPE_SIZE (type))
return;
diff --git a/gcc/system.h b/gcc/system.h
index 32d4a425d51..56aeb25fa0b 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -638,10 +638,11 @@ typedef char _Bool;
LINKER_DOES_NOT_WORK_WITH_DWARF2 FUNCTION_ARG_KEEP_AS_REFERENCE \
GIV_SORT_CRITERION MAX_LONG_TYPE_SIZE MAX_LONG_DOUBLE_TYPE_SIZE \
MAX_WCHAR_TYPE_SIZE GCOV_TYPE_SIZE SHARED_SECTION_ASM_OP \
+ INTEGRATE_THRESHOLD \
FINAL_REG_PARM_STACK_SPACE MAYBE_REG_PARM_STACK_SPACE \
TRADITIONAL_PIPELINE_INTERFACE DFA_PIPELINE_INTERFACE \
DBX_OUTPUT_STANDARD_TYPES BUILTIN_SETJMP_FRAME_VALUE \
- SUNOS4_SHARED_LIBRARIES
+ SUNOS4_SHARED_LIBRARIES PROMOTE_FOR_CALL_ONLY
/* Hooks that are no longer used. */
#pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE \
diff --git a/gcc/target-def.h b/gcc/target-def.h
index 62060abebf2..f8c832a251e 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -310,6 +310,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define TARGET_INSERT_ATTRIBUTES hook_void_tree_treeptr
#define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_tree_false
#define TARGET_MS_BITFIELD_LAYOUT_P hook_bool_tree_false
+#define TARGET_ALIGN_ANON_BITFIELD hook_bool_void_false
#define TARGET_RTX_COSTS hook_bool_rtx_int_int_intp_false
#define TARGET_MANGLE_FUNDAMENTAL_TYPE hook_constcharptr_tree_null
@@ -384,6 +385,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
TARGET_INSERT_ATTRIBUTES, \
TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P, \
TARGET_MS_BITFIELD_LAYOUT_P, \
+ TARGET_ALIGN_ANON_BITFIELD, \
TARGET_INIT_BUILTINS, \
TARGET_EXPAND_BUILTIN, \
TARGET_MANGLE_FUNDAMENTAL_TYPE, \
diff --git a/gcc/target.h b/gcc/target.h
index c122adbcdfa..6e288104559 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -307,6 +307,9 @@ struct gcc_target
Microsoft Visual C++ bitfield layout rules. */
bool (* ms_bitfield_layout_p) (tree record_type);
+ /* Return true if anonymous bitfields affect structure alignment. */
+ bool (* align_anon_bitfield) (void);
+
/* Set up target-specific built-in functions. */
void (* init_builtins) (void);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 80be5049347..77a80bad099 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,6 +1,475 @@
+2004-05-14 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20040514-2.c: New test.
+
+2004-05-14 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * gfortran.fortran-torture/compile/noncontinuation_1.f90: Rename
+ this ...
+ * gfortran.fortran-torture/compile/noncontinuation_1.f: ... to
+ this.
+
+2004-05-14 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * gcc.dg/tree-ssa/20040514-1.c: New test.
+
+2004-05-14 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * gfortran.fortran-torture/compile/noncontinuation_1.f90: New
+ test.
+
+2004-05-14 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/14066
+ * gfortran.fortran-torture/compile/do_1.f90: New test.
+
+2004-05-14 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ PR fortran/15051
+ * gfortran.fortran-torture/compile/empty_interface_1.f90: New
+ test.
+
+2004-05-14 Bud Davis <bdavis9659@comcast.net>
+
+ PR fortran/15149
+ * gfortran.fortran-torture/execute/random_init.f90: New test.
+
+2004-05-13 Paul Brook <paul@codesourcery.com>
+
+ PR fortran/15314
+ * gfortran.fortran-torture/execute/der_init_s.f90: New test.
+
+2004-05-13 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * gcc.dg/uninit-H.c: Test for __PPC__ and __ppc__
+ for the powerpc case.
+
+2004-05-13 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20040513-1.c: New test.
+ * gcc.dg/tree-ssa/20040513-2.c: New test.
+
+2004-05-13 Paul Brook <paul@codesourcery.com>
+
+ * gcc.dg/tree-ssa/20030808-1.c: Force enum size.
+ * gcc.dg/tree-ssa/20030714-1.c: Ditto.
+ * gcc.dg/tree-ssa/20030708-1.c: Ditto.
+
+2004-05-13 Andreas Schwab <schwab@suse.de>
+
+ PR other/10819
+ * lib/gfortran.exp (gfortran_version): Do not match NL/CR
+ characters.
+
+2004-05-13 Bud Davis <bdavis9659@comcast.net>
+
+ PR fortran/15294
+ * gfortran.fortran-torture/execute/adjustr.f90: New file.
+
+2004-05-13 Diego Novillo <dnovillo@redhat.com>
+
+ Merge from tree-ssa-20020619-branch. See
+ ChangeLog.tree-ssa for details.
+
+2004-05-11 Ziemowit Laski <zlaski@apple.com>
+
+ * g++.dg/ext/altivec-8.C: Use '-maltivec' instead of '-faltivec';
+ include <altivec.h> explicitly.
+ * gcc.dg/altivec-13.c: Likewise.
+
+2004-05-11 Paul Brook <paul@codesourcery.com>
+
+ * gcc.c-torture/compile/20010518-1.c: Force enum size.
+
+2004-05-10 Eric Christopher <echristo@redhat.com>
+
+ * gcc.dg/sibcall-3.c: Remove xfail for mips*-*-elf.
+ * gcc.dg/sibcall-4.c: Ditto.
+
+2004-05-10 Ziemowit Laski <zlaski@apple.com>
+
+ * g++.dg/ext/altivec-8.C: New test case.
+ * gcc.dg/altivec-13.c: New test case.
+
+2004-05-08 Roger Sayle <roger@eyesopen.com>
+
+ * gcc.c-torture/execute/divcmp-1.c: New test case.
+ * gcc.c-torture/execute/divcmp-2.c: New test case.
+ * gcc.c-torture/execute/divcmp-3.c: New test case.
+
+2004-05-07 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * g++.dg/other/pragma-re-2.C: New test.
+
+2004-05-07 Uros Bizjak <uros@kss-loka.si>
+
+ * gcc.dg/i386-387-1.c: Add new test for __builtin_fmod.
+ * gcc.dg/i386-387-2.c: Likewise.
+
+ * gcc.dg/i386-387-5.c: Add new tests for __builtin_log1p and
+ __builtin_drem.
+ * gcc.dg/i386-387-6.c: Likewise.
+
+2004-05-07 Uros Bizjak <uros@kss-loka.si>
+
+ * gcc.dg/builtins-33.c: Also check log1p*.
+
+2004-05-07 Hans-Peter Nilsson <hp@axis.com>
+
+ PR optimization/15296
+ * gcc.c-torture/execute/pr15296.c: New test.
+
+2004-05-05 Uros Bizjak <uros@kss-loka.si>
+
+ * gcc.dg/builtins-40.c: New test.
+
+2004-05-05 Richard Sandiford <rsandifo@redhat.com>
+
+ * gcc.dg/torture/mips-hilo-2.c: Provide dummy __mips16 version.
+
+2004-05-04 Paolo Bonzini <bonzini@gnu.org>
+
+ * g++.dg/ext/spe1.C: New testcase.
+
+2004-05-04 Ziemowit Laski <zlaski@apple.com>
+
+ * objc.dg/image-info.m: Allow additional attributes
+ for __image_info section.
+
+2004-05-04 Richard Sandiford <rsandifo@redhat.com>
+
+ * gcc.dg/torture/mips-hilo-2.c: New test.
+
+2004-05-03 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/14389
+ * g++.dg/template/member5.C: New test.
+
+2004-05-03 Uros Bizjak <uros@kss-loka.si>
+
+ * gcc.dg/builtins-34.c: Also check expm1*.
+
+2004-05-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gcc.dg/torture/builtin-integral-1.c: Reorg and add more cases.
+ * gcc.dg/torture/builtin-convert-3.c: New test.
+
+2004-05-01 Ulrich Weigand <uweigand@de.ibm.com>
+
+ PR middle-end/15054
+ * g++.dg/opt/pr15054.C: New test.
+
+2004-04-30 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gcc.dg/torture/builtin-rounding-1.c: New test.
+ * gcc.dg/builtins-25.c: Delete.
+ * gcc.dg/builtins-29.c: Delete.
+
+2004-04-29 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * gcc.dg/sibcall-3.c: Delete s390 from expected fail list.
+ * gcc.dg/sibcall-4.c: Likewise.
+ * gcc.dg/sibcall-6.c: Enable s390 as test platform.
+
+2004-04-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * gcc.c-torture/execute/20040331-1.c: Don't use too wide a
+ bit-field on 16-bit targets.
+
+2004-04-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * gcc.c-torture/execute/20040409-2.c: Fix constants used on
+ 16-bit targets.
+
+2004-04-30 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * gcc.dg/rs6000-power2-1.c: Change to compile only.
+ * gcc.dg/rs6000-power2-2.c: Likewise.
+
+2004-04-29 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * gcc.dg/rs6000-power2-1.c: Change the options to be more correct.
+ * gcc.dg/rs6000-power2-2.c: Change the options to be more correct.
+ Change the asm registers to be in form of frN instead of fN.
+
+2004-04-28 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gcc.dg/torture/builtin-convert-2.c: New test.
+
+2004-04-28 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * gcc.dg/rs6000-power2-1.c: New test.
+ * gcc.dg/rs6000-power2-2.c: New test.
+
+2004-04-28 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/unused-6.c: New test.
+
+2004-04-24 Laurent GUERBY <laurent@guerby.net>
+ Ulrich Weigand <uweigand@de.ibm.com>
+
+ * ada/acats/run_all.sh: Define $target variable.
+
+2004-04-26 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/15119
+ * g++.dg/other/vararg-1.C: New test.
+
+ PR c++/4794
+ * g++.dg/eh/cleanup3.C: New test.
+
+2004-04-24 Laurent GUERBY <laurent@guerby.net>
+
+ * ada/acats/run_all.sh: Handle cd2a83c, cd2a91c (target_bit)
+ and ad8011a (target_insn).
+ * ada/acats/support/macro.dfs: Likewise.
+ * ada/acats/support/impbit.adb: New file.
+
+2004-04-23 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * gcc.dg/const-elim-1.c: XFAIL on s390*-*-*.
+
+2004-04-23 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * gcc.dg/loop-3.c: New test.
+
+2004-04-23 Daniel Jacobowitz <drow@mvista.com>
+
+ * gcc.c-torture/execute/simd-5.c: New test.
+
+2004-04-23 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/15064
+ * g++.dg/template/crash18.C: New test.
+
+2004-04-22 Mark Mitchell <mark@codesourcery.com>
+
+ * g++.dg/ext/complit3.C: New test.
+
+2004-04-21 Aldy Hernandez <aldyh@redhat.com>
+
+ * gcc.dg/altivec-1.c: XFAIL for powerpc-eabispe.
+ * gcc.dg/altivec-3.c: Same.
+ * gcc.dg/altivec-varargs-1.c: Same.
+
+2004-04-21 Aldy Hernandez <aldyh@redhat.com>
+
+ * lib/target-supports.exp (check_profiling_available): Assume
+ profiling is not available on powerpc-eabi targets.
+
+2004-04-21 Janis Johnson <janis187@us.ibm.com>
+
+ * gcc.dg/vmx/1c-01.c: Use ptrdiff_t for casts of pointers.
+ * gcc.dg/vmx/bug-1.c: Ditto.
+
+2004-04-20 Eric Christopher <echristo@redhat.com>
+
+ * gcc.dg/charset/extern.c: New test.
+ * g++.dg/charset/extern3.cc: Ditto.
+
+2004-04-20 Uros Bizjak <uros@kss-loka.si>
+
+ * gcc.dg/builtins-39.c: New test.
+
+2004-04-20 Aldy Hernandez <aldyh@redhat.com>
+
+ * gcc.dg/vmx/vmx.exp: Change DEFAULT_CFLAGS to DEFAULT_VMXCFLAGS.
+
+2004-04-20 Richard Sandiford <rsandifo@redhat.com>
+
+ * gcc.dg/torture/mips-hilo-1.c: New test.
+
+2004-04-19 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * gcc.c-torture/compile/20040419-1.c: New test.
+
+2004-04-18 Aldy Hernandez <aldyh@redhat.com>
+
+ * gcc.dg/vmx/varargs-1.c: Handle when printf outputs \r\n.
+
+2004-04-18 Zack Weinberg <zack@codesourcery.com>
+ Aldy Hernandez <aldyh@redhat.com>
+
+ * gcc.c-torture/execute/va-arg-24.c: New.
+
+2004-04-17 Zack Weinberg <zack@codesourcery.com>
+ Aldy Hernandez <aldyh@redhat.com>
+
+ * gcc.dg/vmx/1b-01.c: New.
+ * gcc.dg/vmx/1b-02.c: New.
+ * gcc.dg/vmx/1b-03.c: New.
+ * gcc.dg/vmx/1b-04.c: New.
+ * gcc.dg/vmx/1b-05.c: New.
+ * gcc.dg/vmx/1b-06.c: New.
+ * gcc.dg/vmx/1b-07.c: New.
+ * gcc.dg/vmx/1c-01.c: New.
+ * gcc.dg/vmx/1c-02.c: New.
+ * gcc.dg/vmx/3a-01a.c: New.
+ * gcc.dg/vmx/3a-01.c: New.
+ * gcc.dg/vmx/3a-01m.c: New.
+ * gcc.dg/vmx/3a-03.c: New.
+ * gcc.dg/vmx/3a-03m.c: New.
+ * gcc.dg/vmx/3a-04.c: New.
+ * gcc.dg/vmx/3a-04m.c: New.
+ * gcc.dg/vmx/3a-05.c: New.
+ * gcc.dg/vmx/3a-06.c: New.
+ * gcc.dg/vmx/3a-06m.c: New.
+ * gcc.dg/vmx/3a-07.c: New.
+ * gcc.dg/vmx/3b-01.c: New.
+ * gcc.dg/vmx/3b-02.c: New.
+ * gcc.dg/vmx/3b-10.c: New.
+ * gcc.dg/vmx/3b-13.c: New.
+ * gcc.dg/vmx/3b-14.c: New.
+ * gcc.dg/vmx/3b-15.c: New.
+ * gcc.dg/vmx/3c-01a.c: New.
+ * gcc.dg/vmx/3c-01.c: New.
+ * gcc.dg/vmx/3c-02.c: New.
+ * gcc.dg/vmx/3c-03.c: New.
+ * gcc.dg/vmx/3d-01.c: New.
+ * gcc.dg/vmx/4-01.c: New.
+ * gcc.dg/vmx/4-03.c: New.
+ * gcc.dg/vmx/5-01.c: New.
+ * gcc.dg/vmx/5-02.c: New.
+ * gcc.dg/vmx/5-03.c: New.
+ * gcc.dg/vmx/5-04.c: New.
+ * gcc.dg/vmx/5-05.c: New.
+ * gcc.dg/vmx/5-06.c: New.
+ * gcc.dg/vmx/5-07.c: New.
+ * gcc.dg/vmx/5-07t.c: New.
+ * gcc.dg/vmx/5-08.c: New.
+ * gcc.dg/vmx/5-10.c: New.
+ * gcc.dg/vmx/5-11.c: New.
+ * gcc.dg/vmx/7-01a.c: New.
+ * gcc.dg/vmx/7-01.c: New.
+ * gcc.dg/vmx/7c-01.c: New.
+ * gcc.dg/vmx/7d-01.c: New.
+ * gcc.dg/vmx/7d-02.c: New.
+ * gcc.dg/vmx/8-01.c: New.
+ * gcc.dg/vmx/8-02a.c: New.
+ * gcc.dg/vmx/8-02.c: New.
+ * gcc.dg/vmx/brode-1.c: New.
+ * gcc.dg/vmx/bug-1.c: New.
+ * gcc.dg/vmx/bug-2.c: New.
+ * gcc.dg/vmx/bug-3.c: New.
+ * gcc.dg/vmx/cw-bug-1.c: New.
+ * gcc.dg/vmx/cw-bug-2.c: New.
+ * gcc.dg/vmx/cw-bug-3.c: New.
+ * gcc.dg/vmx/dct.c: New.
+ * gcc.dg/vmx/debug-1.c: New.
+ * gcc.dg/vmx/debug-2.c: New.
+ * gcc.dg/vmx/debug-3.c: New.
+ * gcc.dg/vmx/debug-4.c: New.
+ * gcc.dg/vmx/dos-bug-1-gdb.c: New.
+ * gcc.dg/vmx/dos-bug-2-gdb.c: New.
+ * gcc.dg/vmx/eg-5.c: New.
+ * gcc.dg/vmx/fft.c: New.
+ * gcc.dg/vmx/gcc-bug-1.c: New.
+ * gcc.dg/vmx/gcc-bug-2.c: New.
+ * gcc.dg/vmx/gcc-bug-3.c: New.
+ * gcc.dg/vmx/gcc-bug-4.c: New.
+ * gcc.dg/vmx/gcc-bug-5.c: New.
+ * gcc.dg/vmx/gcc-bug-6.c: New.
+ * gcc.dg/vmx/gcc-bug-7.c: New.
+ * gcc.dg/vmx/gcc-bug-8.c: New.
+ * gcc.dg/vmx/gcc-bug-9.c: New.
+ * gcc.dg/vmx/gcc-bug-b.c: New.
+ * gcc.dg/vmx/gcc-bug-c.c: New.
+ * gcc.dg/vmx/gcc-bug-d.c: New.
+ * gcc.dg/vmx/gcc-bug-e.c: New.
+ * gcc.dg/vmx/gcc-bug-f.c: New.
+ * gcc.dg/vmx/gcc-bug-g.c: New.
+ * gcc.dg/vmx/gcc-bug-i.c: New.
+ * gcc.dg/vmx/harness.h: New.
+ * gcc.dg/vmx/ira1.c: New.
+ * gcc.dg/vmx/ira2a.c: New.
+ * gcc.dg/vmx/ira2b.c: New.
+ * gcc.dg/vmx/ira2.c: New.
+ * gcc.dg/vmx/ira2c.c: New.
+ * gcc.dg/vmx/mem.c: New.
+ * gcc.dg/vmx/newton-1.c: New.
+ * gcc.dg/vmx/ops.c: New.
+ * gcc.dg/vmx/sn7153.c: New.
+ * gcc.dg/vmx/spill2.c: New.
+ * gcc.dg/vmx/spill3.c: New.
+ * gcc.dg/vmx/spill.c: New.
+ * gcc.dg/vmx/t.c: New.
+ * gcc.dg/vmx/varargs-1.c: New.
+ * gcc.dg/vmx/varargs-2.c: New.
+ * gcc.dg/vmx/varargs-3.c: New.
+ * gcc.dg/vmx/varargs-4.c: New.
+ * gcc.dg/vmx/varargs-5.c: New.
+ * gcc.dg/vmx/varargs-6.c: New.
+ * gcc.dg/vmx/varargs-7.c: New.
+ * gcc.dg/vmx/vmx.exp: New.
+ * gcc.dg/vmx/vprint-1.c: New.
+ * gcc.dg/vmx/vscan-1.c: New.
+ * gcc.dg/vmx/x-01.c: New.
+ * gcc.dg/vmx/x-02.c: New.
+ * gcc.dg/vmx/x-03.c: New.
+ * gcc.dg/vmx/x-04.c: New.
+ * gcc.dg/vmx/x-05.c: New.
+ * gcc.dg/vmx/yousufi-1.c: New.
+ * gcc.dg/vmx/zero-1.c: New.
+ * gcc.dg/vmx/zero.c: New.
+
+2004-04-17 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * g++.dg/lookup/java1.C: Update for chage of
+ _Jv_AllocObject.
+ * g++.dg/lookup/java2.C: Likewise.
+
+2004-04-17 Laurent GUERBY <laurent@guerby.net>
+
+ * ada/acats/run_all.sh: use -O2 by default.
+
+2004-04-17 Richard Sandiford <rsandifo@redhat.com>
+
+ * gcc.dg/vr-mult-[12].c: New tests.
+
+2004-04-16 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * gcc.dg/funcorder.c: XFAIL hppa*64*-*-*.
+
+ * gcc.dg/const-elim-1.c: XFAIL hppa-*-*.
+
+2004-04-15 Richard Sandiford <rsandifo@redhat.com>
+
+ * lib/target-supports.exp (check_profiling_available): Assume profiling
+ isn't available for mips*-*-elf targets.
+
+2004-04-14 Uros Bizjak <uros@kss-loka.si>
+
+ * gcc.dg/builtins-38.c: New test.
+
+2004-04-14 Eric Christopher <echristo@redhat.com>
+
+ * g++.dg/charset/charset.exp: Run .cc extension tests.
+
+2004-04-14 Zack Weinberg <zack@codesourcery.com>
+
+ * gcc.dg/const-elim-1.c: XFAIL hppa*.*-*-* (PA32). Update commentary.
+
+2004-04-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gcc.dg/torture/builtin-ctype-2.c: Test builtin isdigit.
+
+2004-04-13 Uros Bizjak <uros@kss-loka.si>:
+
+ * gcc.dg/i386-387-1.c: Add new test for __builtin_tan.
+ * gcc.dg/i386-387-2.c: Likewise.
+
+ * gcc.dg/i386-387-7.c: New test.
+ * gcc.dg/i386-387-8.c: New test.
+
+ * gcc.dg/builtins-37.c: New test.
+
+2004-04-13 Geoffrey Keating <geoffk@apple.com>
+
+ * g++.dg/pch/externc-1.C: Add missing semicolon.
+
2004-04-13 Aldy Hernandez <aldyh@redhat.com>
- * gcc.c-torture/execute/20020720-1.x: XFAIL for powerpc-*-*spe.
+ * gcc.c-torture/execute/20020720-1.x: XFAIL for powerpc-*-*spe.
2004-04-12 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
@@ -21810,4 +22279,3 @@ rlsruhe.de>
correspond to c-torture 1.11.
* New file.
-
diff --git a/gcc/testsuite/ChangeLog.tree-ssa b/gcc/testsuite/ChangeLog.tree-ssa
new file mode 100644
index 00000000000..03ccbb01ed2
--- /dev/null
+++ b/gcc/testsuite/ChangeLog.tree-ssa
@@ -0,0 +1,1204 @@
+2004-05-07 Diego Novillo <dnovillo@redhat.com>
+
+ * g++.old-deja/g++.ext/arrnew2.C: Restore XFAIL. It's broken
+ on mainline too.
+
+2004-05-06 Richard Henderson <rth@redhat.com>
+
+ * gcc.dg/tree-ssa/20031015-1.c: Rewrite for all targets. Look at
+ alias dump for two VDEFs.
+
+ * gcc.dg/tree-ssa/20040210-1.c: Tweak scan pattern to look for ifs.
+
+2004-05-05 Diego Novillo <dnovillo@redhat.com>
+
+ * g++.dg/parse/stack1.C: Remove XFAIL.
+ * g++.old-deja/g++.bugs/900205_03.C: Likewise.
+ * g++.old-deja/g++.ext/arrnew2.C: Likewise.
+ * g++.old-deja/g++.mike/p646.C: Likewise.
+ * gcc.c-torture/execute/string-opt-19.x: Remove.
+
+2004-05-05 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c/15062
+ * gcc.c-torture/compile/pr15062.c: New test.
+
+2004-05-03 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR optimization/15245
+ * gcc.c-torture/compile/pr15245.c: New test.
+
+2004-05-03 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.dg/tree-ssa/20040430-1.c: New test.
+
+2004-04-26 Bud Davis <bdavis9659@comcast.net>
+
+ PR fortran/14056
+ * gfortran.fortran-torture/execute/spec_abs.f90: Add new test.
+
+2004-04-25 Bud Davis <bdavis9659@comcast.net>
+
+ PR fortran/14942
+ * gfortran.fortran-torture/execute/list_read_1.f90: Add new test.
+
+2004-04-24 Victor Leikehman <lei@il.ibm.com>
+
+ * gfortran.fortran-torture/execute/der_io.f90: New test.
+
+2004-04-24 Bud Davis <bdavis9659@comcast.net>
+
+ PR fortran/15113
+ * gfortran.fortran-torture/execute/a_edit_1.f90: Add new test.
+
+2004-04-23 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * gcc.c-torture/execute/20040423-1.c: New test.
+
+2004-04-22 Bud Davis <bdavis9659@comcast.net>
+
+ PR fortran/14906
+ * gfortran.fortran-torture/execute/empty_format.f90: Add new test.
+
+2004-04-21 Ben Elliston <bje@au.ibm.com>
+
+ PR middle-end/14730
+ * gcc.c-torture/compile/pr14730.c: New test.
+
+2004-04-24 Tobias Schlüter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * execute/intrinsic_count.f90: Fix typo.
+ * execute/intrinsic_mmloc.f90: Fix typo.
+
+2004-04-18 Feng Wang <fengwang@nudt.edu.cn>
+
+ PR fortran/14921
+ PR fortran/14540
+ * gfortran.fortran-torture/execute/math.f90: Add atan2 and clog
+ simplify test.
+
+2004-04-15 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * gcc.c-torture/compile/20040415-1.c: New test.
+ * gcc.c-torture/compile/20040415-2.c: New test.
+
+2004-04-11 Bud Davis <bdavis9659@comcast.net>
+
+ PR fortran/14904
+ * gfortran.fortran-torture/execute/inquire_4.f90: New test.
+
+2004-04-11 Bud Davis <bdavis9659@comcast.net>
+
+ PR fortran/14901
+ * gfortran.fortran-torture/execute/internal_write.f90: New test.
+
+2004-04-11 Bud Davis <bdavis9659@comcast.net>
+
+ PR gfortran/14872
+ * gfortran.fortran-torture/execute/direct_io.f90: Add new test.
+
+2004-04-11 Feng Wang <fengwang@nudt.edu.cn>
+
+ PR fortran/14377
+ * gfortran.fortran-torture/execute/intrinsic_minmax.f90: Add new test.
+
+2004-04-08 Brian Booth <bbooth@redhat.com>
+
+ * gcc.dg/tree-ssa/20040408-1.c: New test.
+
+2004-04-08 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.dg/tree-ssa/20040326-2.c (boz): Add call to abort.
+
+2004-04-07 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.dg/tree-ssa/20040326-2.c: Update to test for correct
+ gimplification of function call expressions.
+
+2004-04-07 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.dg/tree-ssa/20040326-2.c: New test.
+
+2003-04-04 Paul Brook <paul@codesourcery.com>
+
+ PR 13252
+ PR 14081
+ * gfortran.fortran-torture/execute/strarray_1.f90: New test.
+ * gfortran.fortran-torture/execute/strarray_2.f90: New test.
+ * gfortran.fortran-torture/execute/strarray_3.f90: New test.
+ * gfortran.fortran-torture/execute/strarray_4.f90: New test.
+ * gfortran.fortran-torture/execute/strcommon_1.f90: New test.
+
+2004-04-04 Paul Brook <paul@codesourcery.com>
+
+ * lib/fortran-torture.exp (TORTURE_OPTIONS): Remove -fg77-calls.
+
+2004-04-03 Bud Davis <bdavis9659@comcast.net>
+
+ PR gfortran/14762
+ * gfortran.fortran-torture/execute/slash_edit.f90: New test.
+
+2004-04-03 Bud Davis <bdavis9659@comcast.net>
+
+ PR gfortran/14386
+ * gfortran.fortran-torture/execute/inquire_3.f90: New test.
+
+2004-04-03 Bud Davis <bdavis9659@comcast.net>
+
+ PR gfortran/14837
+ * gfortran.fortran-torture/execute/inquire_2.f90: New test.
+
+2004-04-03 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * lib/gfortran.exp: Sync LD_LIBRARY_PATH part from
+ lib/g++.exp.
+
+2004-04-03 Bud Davis <bdavis9659@comcast.net>
+
+ PR 14831
+ * gfortran.fortran-torture/execute/inquire_1.f90: New test.
+
+2004-04-03 Paolo Bonzini <bonzini@gnu.org>
+
+ * gcc.dg/tree-ssa/20040324-1.c: New test.
+
+2004-04-01 Jeff Law <law@redhat.com>
+
+ * gcc.c-torture/compile/20040401-1.c: New test.
+
+2004-04-01 Bud Davis <bdavis9659@comcast.net>
+
+ PR 14746
+ * gfortran.fortran-torture/execute/f2_edit_1.f90: New test.
+
+2004-04-01 Bud Davis <bdavis9659@comcast.net>
+
+ PR gfortran/14565
+ * gfortran.fortran-torture/execute/unopened_unit_1.f90: New test.
+
+2004-03-30 Richard Henderson <rth@redhat.com>
+
+ * gcc.dg/uninit-1.c, gcc.dg/uninit-3.c, gcc.dg/uninit-8.c,
+ gcc.dg/uninit-9.c: Remove XFAIL.
+
+2004-03-26 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20040326-1.c: New test.
+
+2004-03-24 Paul Brook <paul@codesourcery.com>
+
+ * gfortran.fortran-torture/execute/csqrt_1.f90: Use f95 style
+ comments.
+
+2004-03-24 Bud Davis <bdavis9659@comcast.net>
+
+ PR 14334
+ * gfortran.fortran-torture/execute/write_logical_1.f90: New test.
+
+2004-03-24 Bud Davis <bdavis9659@comcast.net>
+
+ PR 13919
+ * gfortran.fortran-torture/execute/read_eof.f90: New test.
+
+2004-03-24 Bud Davis <bdavis9659@comcast.net>
+
+ PR 14396
+ * gfortran.fortran-torture/execute/csqrt_1.f90: New test.
+
+2004-02-24 Paul Brook <paul@codesourcery.com>
+
+ PR 14055
+ * gfortran.fortran-torture/execute/plusconst_1.f90: New test.
+
+2004-03-23 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.c-torture/20040420-1.c: Move and rename ...
+ * gcc.c-torture/compile/20040220-1.c ... here.
+
+2004-03-23 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * gcc.dg/tree-ssa/20040211-1.c: Update outcome.
+ * gcc.dg/tree-ssa/ssa-dce-3.c: New test.
+
+2004-03-19 Diego Novillo <dnovillo@redhat.com>
+
+ PR optimization/14643
+ * gcc.dg/tree-ssa/20040319-1.c: New test.
+
+2004-03-19 Jeff Law <law@redhat.com>
+
+ * gcc.c-torture/execute/20040319-1.c: New test.
+
+2004-03-17 Jeff Law <law@redhat.com>
+
+ * gcc.c-torture/compile/20040317-1.c: New test.
+ * gcc.c-torture/compile/20040317-2.c: New test.
+ * gcc.c-torture/compile/20040317-3.c: New test.
+
+2004-03-17 Diego Novillo <dnovillo@redhat.com>
+
+ PR optimization/14511
+ * g++.dg/tree-ssa/20040317-1.C: New test.
+
+2004-03-13 Diego Novillo <dnovillo@redhat.com>
+
+ PR optimization/14553
+ * gcc.dg/tree-ssa/20040313-1.c: New test.
+
+2004-03-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * gcc.dg/tree-ssa/20040305-1.c: Change a constant to fit in a
+ 16-bit int.
+
+2004-03-10 Andrew Pinski <apinski@apple.com>
+
+ PR c/14475
+ * gcc.dg/pr14475.c: New test.
+
+2004-03-09 Jeff Law <law@redhat.com>
+
+ * gcc.c-torture/compile/20040309-1.c: New test.
+
+2004-03-05 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20040305-1.c: New test.
+
+2004-03-04 Jeff Law <law@redhat.com>
+
+ * gcc.c-torture/20040304-1.c: New test.
+
+2004-03-03 Jeff Law <law@redhat.com>
+
+ * gcc.c-torture/20040303-1.c: New test.
+ * gcc.c-torture/20040303-2.c: New test.
+
+2004-03-02 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * gcc.dg/tree-ssa/tailrecursion-5.c: New test.
+
+2004-03-02 Diego Novillo <dnovillo@redhat.com>
+
+ * testsuite/gcc.dg/tree-ssa/20030815-1.c: Expect 1 type cast.
+ * testsuite/gcc.dg/tree-ssa/ssa-dce-1.c: Check after aliasing.
+ * testsuite/gcc.dg/tree-ssa/ssa-dce-2.c: Likewise.
+ * testsuite/gcc.dg/tree-ssa/ssa-dom-cse-1.c: Likewise.
+
+2004-03-02 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.dg/tree-ssa/20040302-1.c: New test.
+
+2004-02-10 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20040211-1.c: Update slightly.
+
+2004-02-27 Richard Henderson <rth@redhat.com>
+
+ * gcc.dg/warn-1.c: Update warning line.
+ * gcc.dg/tree-ssa/20030730-1.c: Declare ggc_alloc.
+ * gcc.dg/tree-ssa/20030730-2.c: Likewise.
+ * gcc.dg/tree-ssa/20030917-2.c: Fix int->pointer cast.
+ * gcc.dg/tree-ssa/20030922-2.c: XFAIL.
+
+2004-02-27 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.dg/tree-ssa/tailcall-2.c: New test.
+
+2004-02-20 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * gcc.dg/tree-ssa/copy-headers.c: New test.
+ * gcc.dg/tree-ssa/20030711-1.c: Update outcome.
+ * gcc.dg/tree-ssa/20030714-2.c: Ditto.
+ * gcc.dg/tree-ssa/20030807-3.c: Ditto.
+
+2004-02-10 Jeff Law <law@redhat.com>
+
+ * gcc.c-torture/compile/20040219-1.c: New test.
+
+2004-02-16 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20030807-4.c: Remove bogus test.
+
+ * gcc.dg/tree-ssa/20040216-1.c: New test.
+ * gcc.dg/tree-ssa/20040211-1.c: New test.
+
+2004-02-15 Paul Brook <paul@codesourcery.com>
+
+ PR fortran/13433
+ * gfortran.fortran-torture/execute/straret.f90: New test.
+
+2004-02-14 Richard Henderson <rth@redhat.com>
+
+ * gcc.c-torture/execute/20030120-3.c: Remove duplicate of 920415-1.c.
+
+2004-02-11 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20040210-1.c: New test.
+
+2004-02-10 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.c-torture/execute/20000603-1.c: Resolve alias ambiguity and
+ point to DR#236.
+
+2004-02-09 Richard Henderson <rth@redhat.com>
+
+ * gcc.dg/noreturn-1.c: Adjust line numbers on warnings.
+ * gcc.dg/noreturn-4.c: Likewise.
+ * gcc.dg/noreturn-7.c: Likewise. Adjust warnings for
+ changes to tail-call optimizations.
+ * gcc.dg/return-type-3.c: Turn on optimization.
+ * gcc.dg/uninit-6.c: Adjust line numbers on warnings.
+ * gcc.dg/uninit-8.c: XFAIL.
+
+2004-02-09 Feng Wang <fengwang@nudt.edu.cn>
+
+ * gfortran.fortran-torture/execute/specifics.f90: Fix mod type.
+
+2004-02-09 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+ Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20040209-2.c: New test.
+
+2004-02-06 Feng Wang <fengwang@nudt.edu.cn>
+
+ * gfortran.fortran-torture/execute/intrinsic_dotprod.f90: Add complex
+ test.
+
+2004-02-07 Bud Davis <bdavis9659@comcast.net>
+
+ PR libfortran/14038
+ * gfortran.fortran-torture/execute/holletith.f90: New test.
+
+2004-02-06 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR middle-end/13127
+ * gcc.dg/20040206-1.c: New test.
+
+2004-02-04 Richard Henderson <rth@redhat.com>
+
+ * g++.dg/opt/bool1.C: Declare abort.
+
+2004-02-04 Richard Henderson <rth@redhat.com>
+
+ * gcc.dg/tree-ssa/ssa-ccp-10.c: Look at fab dump.
+
+2004-02-03 Richard Henderson <rth@redhat.com>
+
+ * gcc.dg/tree-ssa/20040204-1.c: Rename from ssa-ccp-5.c.
+ Look at .optimized output. XFAIL.
+ * gcc.dg/tree-ssa/ssa-ccp-11.c: XFAIL.
+ * gcc.dg/tree-ssa/ssa-ccp-3.c: XFAIL.
+ * gcc.dg/tree-ssa/ssa-ccp-4.c: Remove.
+ * gcc.dg/tree-ssa/ssa-ccp-6.c: Remove.
+ * gcc.dg/tree-ssa/ssa-ccp-8.c: Remove.
+
+ * gcc.dg/tree-ssa/20030731-1.c: XFAIL.
+ * gcc.dg/tree-ssa/20030814-6.c: XFAIL.
+ * gcc.dg/tree-ssa/20031106-1.c: XFAIL.
+ * gcc.dg/tree-ssa/20031106-2.c: XFAIL.
+ * gcc.dg/tree-ssa/20031106-3.c: XFAIL.
+ * gcc.dg/tree-ssa/20031106-4.c: XFAIL.
+ * gcc.dg/tree-ssa/20031106-5.c: XFAIL.
+ * gcc.dg/tree-ssa/20031106-6.c: XFAIL.
+ * gcc.dg/tree-ssa/sra-2.c: XFAIL.
+ * gcc.dg/tree-ssa/sra-3.c: XFAIL.
+
+ * gcc.dg/i386-ssetype-1.c: XFAIL.
+ * gcc.dg/i386-ssetype-3.c: XFAIL.
+
+2004-02-03 Steven Bosscher <stevenb@suse.de>
+
+ * gcc.dg/tree-ssa/20030709-2.c: Replace `dce4' with `cddce' for
+ tree dump scans.
+ * gcc.dg/tree-ssa/20030808-1.c: Likewise.
+
+2004-01-31 Canqun Yang <canqun@nudt.edu.cn>
+
+ * gfortran.fortran-torture/execute/intrinsic_mmloc_4.f90:
+ Delete print statements.
+
+2004-01-25 Richard Henderson <rth@redhat.com>
+
+ * gcc.c-torture/execute/930529-1.x: Disable, update commentary.
+
+2004-01-21 Richard Henderson <rth@redhat.com>
+
+ * gcc.dg/tree-ssa/asm-1.c: Fix memory constaint.
+
+2004-01-21 Dale Johannesen <dalej@apple.com>
+
+ * gcc.dg/tree-ssa/20040121-1.c: New test.
+
+2004-01-17 Richard Henderson <rth@redhat.com>
+
+ * gcc.c-torture/execute/string-opt-18.x: Remove.
+ * gcc.dg/uninit-2.c, gcc.dg/uninit-4.c: Don't XFAIL.
+ * gcc.dg/uninit-5.c, gcc.dg/uninit-8.c: Likewise.
+
+2004-01-16 Steven Bosscher <stevenb@suse.de>
+
+ * gcc.dg/tree-ssa/20030709-2.c, gcc.dg/tree-ssa/20030808-1.c:
+ Update for extra DCE pass.
+
+2004-01-15 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20030807-1.c: Update due to improvements in
+ jump threading.
+
+2004-01-12 Richard Henderson <rth@redhat.com>
+
+ * gcc.dg/tree-ssa/20030808-1.c: Fix dump option.
+ * gcc.dg/tree-ssa/20031015-1.c: Update dump name.
+ * gcc.dg/tree-ssa/tailcall-1.c, gcc.dg/tree-ssa/tailrecursion-1.c,
+ gcc.dg/tree-ssa/tailrecursion-2.c, gcc.dg/tree-ssa/tailrecursion-3.c,
+ gcc.dg/tree-ssa/tailrecursion-4.c: Likewise.
+
+2004-01-11 Paul Brook <paul@codesourcery.com>
+
+ * gfortran.fortran-torture/execute/emptyif.f90: New test.
+
+2004-01-11 Feng Wang <fengwang@nudt.edu.cn>
+
+ * gfortran.fortran-torture/execute/cmplx.f90: Add dcmplx test.
+
+2004-01-10 Paul Brook <paul@codesourcery.com>
+
+ * gfortran.fortran-torture/execute/mystery_proc.f90: New test.
+ * gfortran.fortran-torture/compile/mystery_proc.f90: Remove.
+
+2004-01-10 Paul Brook <paul@codesourcery.com>
+
+ * gfortran.fortran-torture/execute/intrinsic_minmax.f90: Test
+ specific names.
+
+2004-01-10 Paul Brook <paul@codesourcery.com>
+
+ * gfortran.fortran-torture/execute/intrinsic_transpose.f90: Test
+ complex variables.
+
+2004-01-09 Steven Bosscher <stevenb@suse.de>
+
+ * gcc.dg/tree-ssa/useless-1.c: New test.
+
+2004-01-07 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.dg/tree-ssa/20030530-2.c: Adjust dump file patterns.
+ * gcc.dg/tree-ssa/20030611-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030703-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030703-2.c: Likewise.
+ * gcc.dg/tree-ssa/20030708-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030709-2.c: Likewise.
+ * gcc.dg/tree-ssa/20030709-3.c: Likewise.
+ * gcc.dg/tree-ssa/20030710-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030711-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030711-2.c: Likewise.
+ * gcc.dg/tree-ssa/20030711-3.c: Likewise.
+ * gcc.dg/tree-ssa/20030714-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030714-2.c: Likewise.
+ * gcc.dg/tree-ssa/20030729-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030730-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030730-2.c: Likewise.
+ * gcc.dg/tree-ssa/20030731-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-10.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-11.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-2.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-3.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-4.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-5.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-6.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-7.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-8.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-9.c: Likewise.
+ * gcc.dg/tree-ssa/20030808-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030814-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030814-2.c: Likewise.
+ * gcc.dg/tree-ssa/20030814-3.c: Likewise.
+ * gcc.dg/tree-ssa/20030814-4.c: Likewise.
+ * gcc.dg/tree-ssa/20030814-5.c: Likewise.
+ * gcc.dg/tree-ssa/20030814-6.c: Likewise.
+ * gcc.dg/tree-ssa/20030814-7.c: Likewise.
+ * gcc.dg/tree-ssa/20030815-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030922-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-1.c: Likewise.
+ Fix test to avoid dereferencing a NULL pointer.
+
+2004-01-07 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+ Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20030709-2.c: Update test and expected
+ output to accomodate improvements in the optimizers.
+
+2004-01-02 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * gcc.dg/tree-ssa/sra-3.c: Replace test, old version was a
+ copy of sra-2.c
+
+2004-01-01 Paul Brook <paul@codesourcery.com>
+
+ * gfortran.fortran-torture/execute/data_2.f90: New test.
+
+2003-12-16 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.dg/tree-ssa/20031216-2.c: Remove duplicate test.
+ * gcc.dg/tree-ssa/20030807-7.c: Use -O2 to enable strict
+ aliasing.
+ (simplify_condition): Remove static declarator.
+
+2003-12-16 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.dg/tree-ssa/20031216-2.c: New test.
+
+2003-12-16 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * gcc.dg/tree-ssa/sra-1.c: New test.
+ * gcc.dg/tree-ssa/sra-2.c: New test.
+ * gcc.dg/tree-ssa/sra-3.c: New test.
+ * gcc.dg/tree-ssa/20031216-1.c: New test.
+ * gcc.dg/tree-ssa/ssa-ccp-11.c: New test.
+
+2003-12-12 Jeff Law <law@redhat.com>
+
+ * ssa-dom-thread-1.c: Update now that jump threading pass is
+ no longer separate from the dominator optimizer.
+
+2003-12-12 Huang Chun <chunhuang73@hotmail.com>
+
+ * gfortran.fortran-torture/execute/intrinsic_len.f90: Fix.
+ * gfortran.fortran-torture/execute/intrinsic_index.f90: New test.
+
+2003-12-11 Jeff Law <law@redhat.com>
+
+ * gcc.c-torture/execute/20031211-1.c: New test.
+ * gcc.c-torture/execute/20031211-2.c: New test.
+
+2003-12-05 Canqun Yang <canqun@nudt.edu.cn>
+
+ * gfortran.fortran-torture/execute/common.f90: New test for
+ COMMON and EQUIVALENCE.
+
+2003-12-01 Feng Wang <fengwang@nudt.edu.cn>
+
+ * gfortran.fortran-torture/excute/intrinsic_fraction_exponent.f90:
+ Use correct types. Handle negative exponents.
+ * gfortran.fortran-torture/excute/intrinsic_scale.f90: Remove
+ incorrect conditions.
+
+2003-12-01 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.dg/tls/asm-1.c: Update expected error message.
+
+2003-11-30 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR optimization/13067
+ * g++.dg/opt/cfg4.C: New test.
+
+2003-11-30 Paul Brook <paul@nowt.org>
+
+ PR fortran/13155
+ * gfortran.fortran-torture/execute/module_interface_2.f90: New test.
+
+2003-11-29 Paul Brook <paul@nowt.org>
+
+ * gfortran.fortran-torture/execute/allocate.f90: New test.
+
+2003-11-27 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * gcc.dg/tree-ssa/ssa-ccp-10.c: New test.
+
+2003-11-26 Richard Henderson <rth@redhat.com>
+
+ * gfortran.fortran-torture/execute/intrinsic_nearest.f90: Correctly
+ test behaviour at infinity.
+
+2003-11-25 Canqun Yang <canqun@nudt.edu.cn>
+
+ * gfortran.fortran-torture/execute/common_size.f90: New test for
+ size of COMMON block containing EQUIVALENCE objects.
+
+2003-11-24 Richard Henderson <rth@redhat.com>
+
+ * gcc.c-torture/compile/20031124-1.c: New.
+
+2003-11-24 Paul Brook <paul@nowt.org>
+
+ PR fortran/13154
+ * gfortran.fortran-torture/compile/module_common.f90: New test.
+
+2003-11-18 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/tree-ssa/tailcall-1.c: New.
+ * gcc.dg/tree-ssa/tailrecursion-?.c: Rename dump
+
+2003-11-18 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/tree-ssa/tailrecursion-1.c: New test.
+ * gcc.dg/tree-ssa/tailrecursion-2.c: New test.
+ * gcc.dg/tree-ssa/tailrecursion-3.c: New test.
+ * gcc.dg/tree-ssa/tailrecursion-4.c: New test.
+
+2003-11-13 Paul Brook <paul@nowt.org>
+
+ * gfortran.fortran-torture/execute/module_interface.f90: New test.
+
+2003-11-13 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20030808-1.c:Scan dce2 output rather than dom2
+ output.
+
+ * gcc.dg/tree-ssa/20030728-1.c: Update for jump threading changes.
+
+ * gcc.dg/tree-ssa/20030730-1.c: No longer expect abort declaration
+ to be present.
+
+ * gcc.dg/tree-ssa/20030730-1.c: Make "foo" have external linkage.
+ * gcc.dg/tree-ssa/20030730-2.c: Similarly.
+
+2003-11-13 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/tree-ssa/ssa-dce-1.c: New test.
+ * gcc.dg/tree-ssa/ssa-dce-2.c: New test.
+ * gcc.dg/tree-ssa/ssa-dom-ccp-1.c: New test.
+ * gcc.dg/tree-ssa/ssa-dom-cse-1.c: New test.
+ * gcc.dg/tree-ssa/ssa-dom-thread-1.c: New test.
+ * gcc.dg/tree-ssa/cfgcleanup-1.c: New test.
+
+2003-11-13 Steven Bosscher <stevenb@suse.de>
+
+ * gcc.dg/tree-ssa/20031113-1.c: New test.
+
+2003-11-12 Jan Hubicka <jh@suse.cz>
+
+ * g++.dg/tree-ssa: New file.
+ * g++.dg/tree-ssa/tree-ssa.exp: New file based on
+ gcc.dg/tree-ssa/tree-ssa.exp.
+ * g++.dg/tree-ssa/nothrow-1.C: New test.
+
+2003-11-11 Canqun Yang <canqun@nudt.edu.cn>
+
+ * gfortran.fortran-torture/execute/stack_varsize.f90: New test.
+
+2003-11-08 Paul Brook <paul@nowt.org>
+
+ * gfortran.fortran-toriture/execute/intrinsic_mmloc_3.f90: Extra test.
+ * gfortran.fortran-toriture/execute/intrinsic_mmloc_4.f90: New test.
+
+2003-11-06 Paul Brook <paul@nowt.org>
+
+ * gfortran.fortran-toriture/execute/intrinsic_mmloc_3.f90: New test.
+
+2003-11-06 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * gcc.dg/tree-ssa/20031106-1.c: New test.
+ * gcc.dg/tree-ssa/20031106-2.c: New test.
+ * gcc.dg/tree-ssa/20031106-3.c: New test.
+ * gcc.dg/tree-ssa/20031106-4.c: New test.
+ * gcc.dg/tree-ssa/20031106-5.c: New test.
+ * gcc.dg/tree-ssa/20031106-6.c: New test.
+
+2003-11-06 Steven Bosscher <stevenb@suse.de>
+
+ * gcc.dg/tree-ssa/ssa-ccp-2.c: Fix overoptimistic expectations
+ of our optimizers.
+
+2003-10-31 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.dg/tree-ssa/20031031-1.c: New test.
+
+2003-10-30 Richard Henderson <rth@redhat.com>
+
+ * g++.dg/warn/Wswitch-1.C: Move "case value not in enumerated type"
+ warning to the proper line.
+ * gcc.dg/Wswitch-enum.c: Likewise.
+ * gcc.dg/Wswitch.c: Likewise.
+
+2003-10-22 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20031022-1.c: New test.
+
+2003-10-17 Paul Brook <paul@nowt.org>
+
+ * gfortran.fortran-torture/execute/intrinsic_size.f90: Add
+ additional case.
+
+2003-10-17 Feng Wang <wf_cs@yahoo.com>
+
+ * gfortran.fortran-torture/execute/intrinsic_mmloc_2.f90: New test.
+
+2003-10-16 Richard Henderson <rth@redhat.com>
+
+ * g++.dg/ext/asm3.C: Update expected error text.
+
+2003-10-16 Steven Bosscher <steven@gcc.gnu.org>
+
+ * gcc.dg/noreturn-1.c: Adjust expected error lines.
+ * gcc.dg/return-type-1.c: Likewise.
+
+2003-10-15 Steven Bosscher <steven@gcc.gnu.org>
+
+ * gcc.dg/tree-ssa/20031015-1.c: New test.
+
+2003-10-14 Richard Henderson <rth@redhat.com>
+
+ * gcc.dg/asm-7.c: Update expected error text.
+
+2003-10-14 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.dg/tree-ssa/20030918-1.c: New test.
+
+2003-10-13 Paul Brook <paul@nowt.org>
+
+ * gfortran.fortran-torture/execute/retarray_2.f90: New test.
+ * gfortran.fortran-torture/compile/named_args.f90: New test.
+
+2003-10-12 Feng Wang <wf_cs@yahoo.com>
+
+ * gfortran.fortran-torture/execute/intrinsic_cshift.f90: New test.
+
+2003-10-11 Huang Chun <jiwang@mail.edu.cn>
+
+ * gfortran.fortran-torture/execute/intrinsic_len.f90: New test.
+ * gfortran.fortran-torture/execute/intrinsic_trim.f90: New test.
+
+2003-10-11 Paul Brook <paul@nowt.org>
+
+ * gfortran.fortran-torture/execute/specifics.f90: New test.
+ * gfortran.fortran-torture/execute/intrinsic_achar.f90: New test.
+ * gfortran.fortran-torture/execute/strret.f90: Also test result vars.
+
+2003-10-01 Richard Henderson <rth@redhat.com>
+
+ * g++.dg/parse/crash10.C: Adjust expected error lines.
+ * g++.old-deja/g++.other/crash31.C: Likewise.
+
+2003-09-29 Richard Henderson <rth@redhat.com>
+
+ * g++.dg/ext/stmtexpr1.C, g++.dg/parse/stack1.C: XFAIL.
+
+2003-09-29 Richard Henderson <rth@redhat.com>
+
+ * g++.dg/opt/nothrow1.C: Use locally declared function rather
+ than printf.
+
+ * g++.dg/ext/label3.C: Add dg-options.
+
+2003-09-25 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20030922-2.c: New test.
+
+2003-09-24 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20030708-1.c: Expect all IF conditions to be
+ removed.
+ * gcc.dg/tree-ssa/20030808-1.c: Similarly.
+
+ * gcc.dg/tree-ssa/20030807-9.c: Add additional test.
+
+2003-09-22 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20030922-1.c: New test.
+
+ * gcc.dg/tree-ssa/20030807-2.c: Add additional cases to this test.
+
+2003-09-21 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.dg/tree-ssa/20030920-1.c: New test.
+
+2003-09-21 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.dg/tree-ssa/20030703-2.c: Expect one if() conditional after
+ the second dominator pass.
+ * gcc.dg/tree-ssa/20030807-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-1.c: Add return statement to avoid DCE
+ removing the whole body.
+ Expect two if() statements after the second dominator pass.
+ * gcc.dg/tree-ssa/20030807-7.c: Explain why we fail to optimize.
+
+2003-09-21 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.dg/tree-ssa/20030530-2.c: Adjust to use -fdump-tree-dom2.
+ * gcc.dg/tree-ssa/20030611-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030703-1.c: Likewise
+ * gcc.dg/tree-ssa/20030703-2.c: Likewise.
+ * gcc.dg/tree-ssa/20030708-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030709-2.c: Likewise.
+ * gcc.dg/tree-ssa/20030709-3.c: Likewise.
+ * gcc.dg/tree-ssa/20030710-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030711-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030711-2.c: Likewise.
+ * gcc.dg/tree-ssa/20030711-3.c: Likewise.
+ * gcc.dg/tree-ssa/20030714-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030714-2.c: Likewise.
+ * gcc.dg/tree-ssa/20030729-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030730-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030730-2.c: Likewise.
+ * gcc.dg/tree-ssa/20030731-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-10.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-11.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-2.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-3.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-4.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-5.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-6.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-7.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-8.c: Likewise.
+ * gcc.dg/tree-ssa/20030807-9.c: Likewise.
+ * gcc.dg/tree-ssa/20030808-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030814-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030814-2.c: Likewise.
+ * gcc.dg/tree-ssa/20030814-3.c: Likewise.
+ * gcc.dg/tree-ssa/20030814-4.c: Likewise.
+ * gcc.dg/tree-ssa/20030814-5.c: Likewise.
+ * gcc.dg/tree-ssa/20030814-6.c: Likewise.
+ * gcc.dg/tree-ssa/20030814-7.c: Likewise.
+ * gcc.dg/tree-ssa/20030815-1.c: Likewise.
+ * gcc.dg/tree-ssa/20030824-2.c: Likewise.
+ * gcc.dg/tree-ssa/20030907-1.c: Likewise.
+
+2003-09-21 Lifang Zeng <zlf605@hotmail.com>
+
+ * gfortran.fortran-torture/execute/data.f90: New test.
+
+2003-09-20 Kejia Zhao <kejia_zh@yahoo.com.cn>
+
+ * gfortran.fortran-torture/execute/intrisic_si_kind.f90: New test.
+ * gfortran.fortran-torture/execute/intrisic_sr_kind.f90: New test.
+
+2003-09-17 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.dg/tree-ssa/20030917-2.c: New test.
+
+2003-09-17 Jeff Law <law@redhat.com>
+
+ * gcc.c-torture/compile/20030917-1.c: New test.
+
+ * gcc.dg/tree-ssa/20030917-1.c: New test.
+ * gcc.dg/tree-ssa/20030917-3.c: New test.
+
+ * gcc.dg/tree-ssa/20030807-8.c: Update.
+
+2003-09-14 Paul Brook <paul@nowt.org>
+
+ * gfortran.fortran-torture/der_init.f90: Also test arrays.
+
+2003-09-13 Paul Brook <paul@nowt.org>
+
+ * gcc.c-torture/execute/20030913-1.c: New test.
+
+2003-09-10 Kejia Zhao <kejia_zh@yahoo.com.cn>
+
+ * gfortran.fortran-torture/intrinsic_fraction_exponent.f90: New test.
+ * gfortran.fortran-torture/intrinsic_nearest.f90: New test.
+ * gfortran.fortran-torture/intrinsic_rrspacing.f90: New test.
+ * gfortran.fortran-torture/intrinsic_scale.f90: New test.
+ * gfortran.fortran-torture/intrinsic_set_exponent.f90: New test
+ * gfortran.fortran-torture/intrinsic_spacing.f90: New test.
+
+2003-09-10 Paul Brook <paul@nowt.org>
+
+ * gcc.c-torture/execute/20030910-1.c: New test.
+ * gcc.g-torture/compile/20030910-1.c: New test.
+
+2003-09-09 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * gcc.c-torture/execute/20030909-1.c: New test.
+
+2003-09-07 Steven Bosscher <steven@gcc.gnu.org>
+
+ PR optimization/12198
+ * gcc.dg/tree-ssa/20030907-1.c: New test.
+
+ PR optimization/12109
+ * gcc.dg/tree-ssa/20030907-2.c: New test.
+
+2003-09-04 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.c-torture/execute/20030828-1.c: New test.
+ * gcc.c-torture/execute/20030828-2.c: New test.
+
+2003-09-02 Jeff Law <law@redhat.com>
+
+ * gcc.c-torture/compile/20030902-1.c: New test.
+
+2003-08-27 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20030821-1.c: Don't get confused by declaration
+ of dont_remove.
+
+2003-08-25 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+ Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20030815-1.c: New test.
+ * gcc.dg/tree-ssa/20030821-1.c: New test.
+
+
+2003-08-25 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * gcc.dg/tree-ssa/20030825-1.c: New test.
+
+2003-08-24 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.dg/tree-ssa/20030824-1.c: New test.
+ * gcc.dg/tree-ssa/20030824-2.c: New test.
+
+2003-08-23 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.c-torture/compile/20030823-1.c: New test.
+
+2003-08-20 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.dg/tree-ssa/20030807-3.c: Adjust expected number of
+ conditionals.
+ * gcc.dg/tree-ssa/20030807-4.c: Likewise.
+
+2003-08-20 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * gcc.dg/tree-ssa/20030820-1.c: New test.
+ * gcc.dg/tree-ssa/20030820-2.c: New test.
+
+2003-08-15 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20030814-6.c: New test.
+ * gcc.dg/tree-ssa/20030814-7.c: New test.
+
+ * gcc.dg/tree-ssa/20030814-4.c: Test optimized output to verify
+ useless statement created by out-of-ssa pass is removed.
+ * gcc.dg/tree-ssa/20030814-5.c: Similarly.
+
+2003-08-14 Paul Brook <paul@nowt.org>
+
+ * gfortran.fortran-torture/compile/allocate.f90: Also test scalars.
+
+2003-08-14 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20030814-1.c: New test.
+ * gcc.dg/tree-ssa/20030814-2.c: New test.
+ * gcc.dg/tree-ssa/20030814-3.c: New test.
+ * gcc.dg/tree-ssa/20030814-4.c: New test.
+ * gcc.dg/tree-ssa/20030814-5.c: New test.
+
+ * gcc.dg/tree-ssa/20030708-1.c: There should only be one conditional.
+ * gcc.dg/tree-ssa/20030714-2.c: New test.
+ * gcc.dg/tree-ssa/20030731-1.c: New test.
+
+ * gcc.dg/tree-ssa/20030711-2.c: Update slightly to avoid
+ dereferences of constant addresses.
+
+ * gcc.dg/tree-ssa/20030729-1.c: Remove incorrect test for
+ IF statement removal.
+
+ * gcc.dg/tree-ssa/20030808-1.c: New test.
+
+2003-08-12 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20030807-8.c: New test.
+
+2003-08-12 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.c-torture/execute/builtins/string-4.x: Remove.
+
+2003-08-12 Paul Brook <paul@nowt.org>
+
+ * gfortran.fortran-torture/execute/forall_4.f90: Fix illegal code.
+
+2003-08-12 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/*.c: Add missing close braces to various tests.
+
+ * gcc.dg/tree-ssa/20030807-6.c: New test.
+ * gcc.dg/tree-ssa/20030807-7.c: New test.
+ * gcc.dg/tree-ssa/20030807-9.c: New test.
+ * gcc.dg/tree-ssa/20030807-11.c: New test.
+
+2003-08-11 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20030807-1.c: New test.
+ * gcc.dg/tree-ssa/20030807-2.c: New test.
+ * gcc.dg/tree-ssa/20030807-3.c: New test.
+ * gcc.dg/tree-ssa/20030807-4.c: New test.
+ * gcc.dg/tree-ssa/20030807-5.c: New test.
+ * gcc.dg/tree-ssa/20030807-10.c: New test.
+
+2003-08-10 Paul Brook <paul@nowt.org>
+
+ * gfortran.fortran-torture/compile/allocate.f90: Also test memebers of
+ derived types.
+
+2003-08-05 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20030731-2.c: New test.
+ * gcc.c-torture/execute/builtins/string-5.x: Kill.
+
+2003-07-30 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20030730-1.c: New test.
+ * gcc.dg/tree-ssa/20030730-2.c: New test.
+ * gcc.dg/tree-ssa/20030729-1.c: Fix comment typo.
+
+2003-07-29 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20030729-1.c: New test.
+
+ * gcc.dg/tree-ssa/20030709-1.c: Look at the .optimized output.
+
+ * gcc.dg/tree-ssa/20030711-2.c: There should only be one load
+ of rtmem after rewriting into SSA form.
+
+2003-07-28 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20030728-1.c: New test.
+
+2003-07-26 Paul Brook <paul@nowt.org>
+
+ * gfortran.fortran-torture: New testsuite.
+ * lib/fortran-torture.exp: New file.
+ * lib/gfortran.exp: New file.
+
+2003-07-16 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20030709-2.c: Also test that we eliminate
+ the redundant load of ->fld[1].rtmem.
+
+ * gcc.c-torture/compile/20030716-1.c: New test.
+
+2003-07-16 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * gcc.dg/tree-ssa/ssa-ccp-1.c: New test.
+ * gcc.dg/tree-ssa/ssa-ccp-2.c: New test.
+ * gcc.dg/tree-ssa/ssa-ccp-3.c: New test.
+ * gcc.dg/tree-ssa/ssa-ccp-4.c: New test.
+ * gcc.dg/tree-ssa/ssa-ccp-5.c: New test.
+ * gcc.dg/tree-ssa/ssa-ccp-6.c: New test.
+ * gcc.dg/tree-ssa/ssa-ccp-7.c: New test.
+ * gcc.dg/tree-ssa/ssa-ccp-8.c: New test.
+ * gcc.dg/tree-ssa/ssa-ccp-9.c: New test.
+
+2003-07-10 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20030703-1.c: New test.
+ * gcc.dg/tree-ssa/20030703-2.c: New test.
+ * gcc.dg/tree-ssa/20030708-1.c: New test.
+ * gcc.dg/tree-ssa/20030709-1.c: New test.
+ * gcc.dg/tree-ssa/20030709-2.c: New test.
+ * gcc.dg/tree-ssa/20030709-3.c: New test.
+ * gcc.dg/tree-ssa/20030710-1.c: New test.
+ * gcc.dg/tree-ssa/20030711-1.c: New test.
+ * gcc.dg/tree-ssa/20030711-2.c: New test.
+ * gcc.dg/tree-ssa/20030711-3.c: New test.
+ * gcc.dg/tree-ssa/20030714-1.c: New test.
+
+2003-07-10 Jeff Law <law@redhat.com>
+
+ * lib/scantree.exp: Always glob the output file.
+:
+2003-06-27 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.dg/20030612-1.c: New test.
+
+2003-06-25 Jeff Law <law@redhat.com>
+
+ * gcc.dg/noncompile/920507-1.c: Return a value so that the
+ variable "a" is always used.
+
+2003-06-11 Jeff Law <law@redhat.com>
+
+ * gcc.c-torture/gcc.dg/tree-ssa/20030611-1.c: New test.
+
+ * gcc.c-torture/compile/20030530-2.c: Move to...
+ * gcc.c-torture/gcc.dg/tree-ssa/20030530-2.c: Here. Use dg
+ and scan-tree-output framework. Verify that redundant expressions
+ are removed.
+ * gcc.c-torture/gcc.dg/tree-ssa/tree-ssa.exp: New driver.
+ * lib/gcc.dg.exp: Load scantree.exp.
+ * lib/scantree.exp: New library of routines to scan tree dumps.
+
+2003-06-03 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.c-torture/execute/builtins/string-4.x: Expect
+ execution failures.
+ * gcc.c-torture/execute/builtins/string-5.x: Likewise.
+
+2003-05-30 Jeff Law <law@redhat.com>
+
+ * gcc.c-torture/compile/20030530-1.c: New test.
+ * gcc.c-torture/compile/20030530-2.c: New test.
+ * gcc.c-torture/compile/20030530-3.c: New test.
+
+2003-05-12 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.c-torture/execute/string-opt-19.x: Expect execution
+ failures.
+
+2003-05-06 Jeff Law <law@redhat.com>
+
+ * gcc.c-torture/execute/string-opt-18.x: Expect execution
+ failures.
+
+2003-05-01 Jeff Law <law@redhat.com>
+
+ * gcc.c-torture/execute/20030501-1.c: New test for tree-ssa bug.
+
+2003-04-16 Jeff Law <law@redhat.com>
+
+ * gcc.c-torture/compile/20030416-1.c: New test from Diego.
+
+ * gcc.c-torture/execute/20030120-3.c: Updates suggested by Kaveh.
+
+2003-04-05 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.c-torture/compile/20030405-1.[cx]: New test.
+
+2003-04-05 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.c-torture/execute/20030404-1.c: New test.
+
+2003-04-03 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.c-torture/execute/20030403-1.c: New test.
+
+2003-03-10 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * gcc.c-torture/compile/20030310-1.c: New test.
+
+2003-02-12 Jeff Law <law@redhat.com>
+
+ * gcc.c-torture/execute/20030120-3.c: New test.
+
+2003-02-08 Diego Novillo <dnovillo@redhat.com>
+
+ * lib/c-torture.exp: Remove -ftree-dce from compiler flags.
+
+2003-02-06 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.c-torture/compile/20001226-1.c: Remove deliberate syntax
+ error.
+
+2003-02-02 Diego Novillo <dnovillo@redhat.com>
+
+ * lib/c-torture.exp (TORTURE_OPTIONS): Add -ftree-dce.
+
+2003-01-28 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.c-torture/execute/builtin-constant.x: Remove.
+
+2003-01-05 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.c-torture/compile/20001226-1.c: Add clarifying
+ remarks about why we introduced a deliberate syntax
+ error.
+
+2002-11-24 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.c-torture/compile/20001226-1.c: Introduce a
+ deliberate syntax error.
+
+2002-11-13 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.c-torture/execute/20021113-1.c: New test.
+
+2002-08-19 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.c-torture/execute/20020819-1.c: New test.
+
+2002-08-21 Diego Novillo <dnovillo@redhat.com>
+
+ * gcc.c-torture/execute/20020819-1.c: Add exit(0).
diff --git a/gcc/testsuite/ada/acats/run_all.sh b/gcc/testsuite/ada/acats/run_all.sh
index d11c6d7ee8f..b317aa73f4c 100755
--- a/gcc/testsuite/ada/acats/run_all.sh
+++ b/gcc/testsuite/ada/acats/run_all.sh
@@ -9,7 +9,7 @@
# gccflags="-O3 -fomit-frame-pointer -funroll-all-loops -finline-functions"
# gnatflags="-gnatN"
-gccflags=""
+gccflags="-O2"
gnatflags="-gnatws"
target_run () {
@@ -71,10 +71,12 @@ rm -f $dir/acats.sum $dir/acats.log
display " === acats configuration ==="
+target=`$GCC -dumpmachine`
+
display target gcc is $GCC
display `$GCC -v 2>&1`
display host=`gcc -dumpmachine`
-display target=`$GCC -dumpmachine`
+display target=$target
display `type gnatmake`
gnatls -v >> $dir/acats.log
display ""
@@ -88,9 +90,32 @@ cd $dir/support
cp $testdir/support/*.ada $testdir/support/*.a $testdir/support/*.tst $dir/support
+# Find out the size in bit of an address on the target
+target_gnatmake $testdir/support/impbit.adb >> $dir/acats.log 2>&1
+target_run $dir/support/impbit > $dir/support/impbit.out 2>&1
+target_bit=`cat $dir/support/impbit.out`
+echo target_bit="$target_bit" >> $dir/acats.log
+
+# Find out a suitable asm statement
+# Adapted from configure.ac gcc_cv_as_dwarf2_debug_line
+case "$target" in
+ ia64*-*-* | s390*-*-*)
+ target_insn="nop 0"
+ ;;
+ mmix-*-*)
+ target_insn="swym 0"
+ ;;
+ *)
+ target_insn="nop"
+ ;;
+esac
+echo target_insn="$target_insn" >> $dir/acats.log
+
sed -e "s,ACATS4GNATDIR,$dir,g" \
< $testdir/support/impdef.a > $dir/support/impdef.a
sed -e "s,ACATS4GNATDIR,$dir,g" \
+ -e "s,ACATS4GNATBIT,$target_bit,g" \
+ -e "s,ACATS4GNATINSN,$target_insn,g" \
< $testdir/support/macro.dfs > $dir/support/MACRO.DFS
sed -e "s,ACATS4GNATDIR,$dir,g" \
< $testdir/support/tsttests.dat > $dir/support/TSTTESTS.DAT
diff --git a/gcc/testsuite/ada/acats/support/impbit.adb b/gcc/testsuite/ada/acats/support/impbit.adb
new file mode 100644
index 00000000000..5e189b06257
--- /dev/null
+++ b/gcc/testsuite/ada/acats/support/impbit.adb
@@ -0,0 +1,6 @@
+with System;
+with Ada.Text_IO;
+procedure Impbit is
+begin
+ Ada.Text_IO.Put_Line (System.Address'Size'Img);
+end Impbit;
diff --git a/gcc/testsuite/ada/acats/support/macro.dfs b/gcc/testsuite/ada/acats/support/macro.dfs
index 000c1f8e28b..8c3723348ad 100644
--- a/gcc/testsuite/ada/acats/support/macro.dfs
+++ b/gcc/testsuite/ada/acats/support/macro.dfs
@@ -99,7 +99,7 @@ BLANKS
-- AN INTEGER LITERAL WHOSE VALUE IS THE MINIMUM NUMBER OF BITS
-- SUFFICIENT TO HOLD ANY VALUE OF AN ACCESS TYPE.
-- USED IN: CD2A83C BD2A02A
-ACC_SIZE 32
+ACC_SIZE ACATS4GNATBIT
-- $ALIGNMENT
-- A VALUE THAT IS LEGITIMATE FOR USE IN A RECORD ALIGNMENT CLAUSE.
@@ -220,7 +220,7 @@ LESS_THAN_DURATION -86_400.0
-- MACHINE_CODE. IF THE IMPLEMENTATION DOES NOT SUPPORT MACHINE
-- CODE THEN USE THE ADA NULL STATEMENT (I.E. NULL; ).
-- USED IN: AD8011A BD8001A BD8002A BD8004A BD8004B
-MACHINE_CODE_STATEMENT Asm_Insn'(Asm ("nop"));
+MACHINE_CODE_STATEMENT Asm_Insn'(Asm ("ACATS4GNATINSN"));
-- $MAX_INT
-- AN INTEGER LITERAL WHOSE VALUE IS SYSTEM.MAX_INT.
@@ -271,7 +271,7 @@ RECORD_NAME Asm_Insn
-- AN INTEGER LITERAL WHOSE VALUE IS THE NUMBER OF BITS REQUIRED TO
-- HOLD A TASK OBJECT.
-- USED IN: CD2A91C
-TASK_SIZE 32
+TASK_SIZE ACATS4GNATBIT
-- $TASK_STORAGE_SIZE
-- THE NUMBER OF STORAGE UNITS REQUIRED FOR A TASK ACTIVATION.
diff --git a/gcc/testsuite/g++.dg/README b/gcc/testsuite/g++.dg/README
index 4e2e4ce9bbc..14b736e7a73 100644
--- a/gcc/testsuite/g++.dg/README
+++ b/gcc/testsuite/g++.dg/README
@@ -22,6 +22,7 @@ rtti Tests for run-time type identification (typeid, dynamic_cast, etc.)
template Tests for templates.
tc1 Tests for Technical Corrigendum 1 conformance.
tls Tests for support of thread-local data.
+tree-ssa Tests for Tree SSA optimizations.
warn Tests for compiler warnings.
other Tests that don't fit into one of the other categories.
diff --git a/gcc/testsuite/g++.dg/charset/charset.exp b/gcc/testsuite/g++.dg/charset/charset.exp
index dc11c3ff5a2..7a74217dec3 100644
--- a/gcc/testsuite/g++.dg/charset/charset.exp
+++ b/gcc/testsuite/g++.dg/charset/charset.exp
@@ -37,7 +37,7 @@ if ![info exists DEFAULT_CHARSETCFLAGS] then {
dg-init
# Main loop.
-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{c,S} ]] \
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{c,cc,S} ]] \
"" $DEFAULT_CHARSETCFLAGS
# All done.
diff --git a/gcc/testsuite/g++.dg/charset/extern3.cc b/gcc/testsuite/g++.dg/charset/extern3.cc
new file mode 100644
index 00000000000..5e46ca6facf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/charset/extern3.cc
@@ -0,0 +1,11 @@
+/* { dg-do compile }
+ { dg-require-iconv "IBM-1047" }
+ { dg-final { scan-assembler-not "abcdefghijklmnopqrstuvwxyz" } } */
+
+extern char *bar;
+
+extern void foo (void)
+{
+ char str[]="abcdefghijklmnopqrstuvwxyz";
+ bar = str;
+}
diff --git a/gcc/testsuite/g++.dg/eh/cleanup3.C b/gcc/testsuite/g++.dg/eh/cleanup3.C
new file mode 100644
index 00000000000..79935dede69
--- /dev/null
+++ b/gcc/testsuite/g++.dg/eh/cleanup3.C
@@ -0,0 +1,20 @@
+// C++/4794
+// This test used to hang in has_cleanups
+// Contributed by: <fritz@intrinsity.com>
+/* { dg-do compile } */
+
+void foo (int a,int b,int c,int d,int e,int f,int g,int h,int i,int j,int k,
+ int l,int m,int n,int o,int p,int q,int r,int s,int t,int u,int v,int w,
+ int x,int y,int z,int aa,int ab,int ac)
+{
+if (!((((ac != 0) + (d != 0) + (c != 0) + (f != 0) + (x != 0) + (y != 0) +
+ (z != 0) + (aa != 0) + (ab != 0) + (g != 0) + (b != 0) + (a != 0) +
+ (h != 0) + (e != 0) + (p != 0) + (q != 0) + (n != 0) + (r != 0) +
+ (o != 0) + (v != 0) + (w != 0) + (t != 0) + (u != 0) + (s != 0) +
+ (k != 0) + (l != 0) + (m != 0) + (i != 0) + (j != 0)) <= 1)))
+ {
+ return;
+ }
+}
+
+
diff --git a/gcc/testsuite/g++.dg/eh/goto1.C b/gcc/testsuite/g++.dg/eh/goto1.C
new file mode 100644
index 00000000000..f3e3e4216fb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/eh/goto1.C
@@ -0,0 +1,34 @@
+extern "C" void abort ();
+
+static int count;
+
+struct S {
+ S() { ++count; }
+ ~S() { --count; }
+};
+
+int foo(int p)
+{
+ S s1;
+ {
+ S s2;
+ if (p)
+ goto L;
+ else
+ return 1;
+ }
+ foo (p);
+ L:
+ return 0;
+}
+
+int main()
+{
+ foo(0);
+ if (count != 0)
+ abort ();
+ foo(1);
+ if (count != 0)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/ext/altivec-8.C b/gcc/testsuite/g++.dg/ext/altivec-8.C
new file mode 100644
index 00000000000..9f4892df860
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/altivec-8.C
@@ -0,0 +1,20 @@
+/* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-options "-maltivec" } */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+
+/* This test case exercises intrinsic/argument combinations that,
+ while not in the Motorola AltiVec PIM, have nevertheless crept
+ into the AltiVec vernacular over the years. */
+
+#include <altivec.h>
+
+void foo (void)
+{
+ vector bool int boolVec1 = (vector bool int) vec_splat_u32(3);
+ vector bool short boolVec2 = (vector bool short) vec_splat_u16(3);
+ vector bool char boolVec3 = (vector bool char) vec_splat_u8(3);
+
+ boolVec1 = vec_sld( boolVec1, boolVec1, 4 );
+ boolVec2 = vec_sld( boolVec2, boolVec2, 2 );
+ boolVec3 = vec_sld( boolVec3, boolVec3, 1 );
+}
diff --git a/gcc/testsuite/g++.dg/ext/altivec-9.C b/gcc/testsuite/g++.dg/ext/altivec-9.C
new file mode 100644
index 00000000000..cb7e4bb4e72
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/altivec-9.C
@@ -0,0 +1,13 @@
+/* Test for AltiVec function vec_ld, passing a pointer to const vector */
+/* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-options "-maltivec" } */
+
+#include <altivec.h>
+
+typedef vector unsigned char vuc_t;
+const vuc_t* p;
+vector unsigned char test_vec_ld()
+{
+ return vec_ld(0,p);
+}
+
diff --git a/gcc/testsuite/g++.dg/ext/asm3.C b/gcc/testsuite/g++.dg/ext/asm3.C
index 699ab4c8252..5eff16ffe7c 100644
--- a/gcc/testsuite/g++.dg/ext/asm3.C
+++ b/gcc/testsuite/g++.dg/ext/asm3.C
@@ -8,6 +8,6 @@
int two(int in)
{
register int out;
- __asm__ ("" : "r" (out) : "r" (in)); // { dg-error "output operand" "" }
+ __asm__ ("" : "r" (out) : "r" (in)); // { dg-error "" "" }
return out;
}
diff --git a/gcc/testsuite/g++.dg/ext/complit3.C b/gcc/testsuite/g++.dg/ext/complit3.C
new file mode 100644
index 00000000000..92e2033100e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/complit3.C
@@ -0,0 +1,8 @@
+// { dg-options "" }
+
+int Compound_Literals_0()
+{
+ static int y[] = (int []) {1, 2, 3}; // { dg-error "" }
+ static int z[] = (int [3]) {1}; // { dg-error "" }
+ return y[0]+z[0];
+}
diff --git a/gcc/testsuite/g++.dg/ext/label3.C b/gcc/testsuite/g++.dg/ext/label3.C
new file mode 100644
index 00000000000..604bfdc12c3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/label3.C
@@ -0,0 +1,39 @@
+// Bug: we were removing the p = q assignment in dce, and then reinserting
+// it *after* the try/catch in out-of-ssa. Oops.
+
+// testcase reduced from libjava/interpret.cc.
+
+// { dg-do run }
+// { dg-options "-O2" }
+
+extern "C" int printf (const char *, ...);
+
+bool b;
+
+int main()
+{
+ __label__ one, two, done;
+ void *labs[] = { &&one, &&two, &&done };
+ const void **q = (const void **)labs;
+ const void **p = q;
+
+ try
+ {
+ one:
+ printf ("one!\n");
+ if (b)
+ throw 42;
+ goto **p++;
+
+ two:
+ printf ("two!\n");
+ goto **p++;
+
+ done:
+ printf ("done!\n");
+ }
+ catch (int)
+ {
+ printf ("caught!\n");
+ }
+}
diff --git a/gcc/testsuite/g++.dg/ext/spe1.C b/gcc/testsuite/g++.dg/ext/spe1.C
new file mode 100644
index 00000000000..b9ae5e7d135
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/spe1.C
@@ -0,0 +1,9 @@
+/* { dg-do compile { target powerpc-*-eabi* } } */
+/* { dg-options "-mcpu=8540 -mabi=spe -O0" } */
+
+typedef int v2si __attribute__ ((vector_size (8)));
+
+/* The two specializations must be considered different. */
+template <class T> class X { };
+template <> class X<__ev64_opaque__> { };
+template <> class X<v2si> { };
diff --git a/gcc/testsuite/g++.dg/init/pmf1.C b/gcc/testsuite/g++.dg/init/pmf1.C
new file mode 100644
index 00000000000..93c67bdd706
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/pmf1.C
@@ -0,0 +1,17 @@
+// PR c++/14089
+// { dg-do compile }
+//
+// C++ front end generated assignment between types that were not
+// compatible in any sense visible to the optimizers.
+
+struct pair {
+ typedef void (pair::*fp)();
+ int first;
+ pair::fp second;
+ pair(const int& a, const pair::fp& b) : first(a), second(b) {}
+ void f(const int& a, const pair::fp& b) { first = a; second = b; }
+};
+
+void op() {
+ pair(5, pair::fp());
+}
diff --git a/gcc/testsuite/g++.dg/lookup/java1.C b/gcc/testsuite/g++.dg/lookup/java1.C
index 4b740085afb..270910d1daa 100644
--- a/gcc/testsuite/g++.dg/lookup/java1.C
+++ b/gcc/testsuite/g++.dg/lookup/java1.C
@@ -45,7 +45,7 @@ void Bar1(void)
* Step 2: constructor declaration
*/
-extern "C" jobject _Jv_AllocObject (jclass, jint) __attribute__((__malloc__));
+extern "C" jobject _Jv_AllocObject (jclass) __attribute__((__malloc__));
void Bar2(void)
{
diff --git a/gcc/testsuite/g++.dg/lookup/java2.C b/gcc/testsuite/g++.dg/lookup/java2.C
index a779bf64dd9..f3c81f43ed0 100644
--- a/gcc/testsuite/g++.dg/lookup/java2.C
+++ b/gcc/testsuite/g++.dg/lookup/java2.C
@@ -37,7 +37,7 @@ public:
* function, so we need to test here if it works with a normal declaration.
*/
-extern "C" jobject _Jv_AllocObject (jclass, jint) __attribute__((__malloc__));
+extern "C" jobject _Jv_AllocObject (jclass) __attribute__((__malloc__));
extern "C" void _Jv_Throw (jthrowable) __attribute__ ((__noreturn__));
void Bar4(void)
diff --git a/gcc/testsuite/g++.dg/opt/bool1.C b/gcc/testsuite/g++.dg/opt/bool1.C
new file mode 100644
index 00000000000..78cdebe32aa
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/bool1.C
@@ -0,0 +1,25 @@
+// PR opt/13869
+// { dg-do run }
+// { dg-options "-O2" }
+
+extern "C" void abort ();
+
+int test ()
+{
+ bool my_bool = true;
+ for (int i = 0; i < 10; ++i)
+ {
+ if (!my_bool)
+ ;
+ else
+ my_bool = false;
+ };
+ return my_bool;
+}
+
+int main ()
+{
+ if (test ())
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/opt/cfg4.C b/gcc/testsuite/g++.dg/opt/cfg4.C
new file mode 100644
index 00000000000..94522ed4171
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/cfg4.C
@@ -0,0 +1,45 @@
+// PR optimization/13067
+// Origin: <bryner@brianryner.com>
+
+// This used to fail on the tree-ssa because of "out-of-ssa"
+// We might have a valid variable, but not a valid value when trying to find
+// useless statements created by out-of-ssa translation. In this case
+// val will be set to null, then later dereferenced. Bad.
+
+// { dg-do compile }
+// { dg-options "-Os" }
+
+
+
+struct Iterator
+{
+ Iterator operator++();
+};
+
+void GetChar(char* aChar);
+
+void foo(char aChar)
+{
+ char quote;
+ Iterator end;
+
+ while (1) {
+ if (aChar == '"')
+ GetChar(&aChar);
+
+ switch (aChar) {
+ case 'a':
+ ++end;
+ if (quote) {
+ if (quote == aChar) {
+ quote = 0;
+ }
+ } else {
+ quote = aChar;
+ }
+ }
+ }
+}
+
+
+
diff --git a/gcc/testsuite/g++.dg/opt/crash1.C b/gcc/testsuite/g++.dg/opt/crash1.C
new file mode 100644
index 00000000000..3526df1ddc9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/crash1.C
@@ -0,0 +1,14 @@
+// PR opt/13681
+// Here we have an out-of-range array index. We should not abort
+// trying to resolve the indirection back to an object.
+
+struct X {
+ double values[1];
+ double & foo (const unsigned int index) { return values[index]; }
+};
+
+void foo() {
+ double d;
+ X h1;
+ h1.foo(1) = d;
+}
diff --git a/gcc/testsuite/g++.dg/opt/inline7.C b/gcc/testsuite/g++.dg/opt/inline7.C
new file mode 100644
index 00000000000..7a873b01a31
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/inline7.C
@@ -0,0 +1,7 @@
+// PR c++/13543
+// { dg-do compile }
+// { dg-options "-O3" }
+
+struct basic_string { basic_string(const basic_string&); };
+basic_string operator+(const basic_string& lhs, char);
+void dumpNode(basic_string start) { dumpNode(start + 'a'); }
diff --git a/gcc/testsuite/g++.dg/opt/nothrow1.C b/gcc/testsuite/g++.dg/opt/nothrow1.C
new file mode 100644
index 00000000000..fb6c6040408
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/nothrow1.C
@@ -0,0 +1,24 @@
+// Test that the nothrow optimization works properly.
+// { dg-do compile }
+// { dg-options "-O -fdump-tree-optimized" }
+
+extern void blah() throw();
+
+int i, j, k;
+
+int main()
+{
+ try
+ {
+ ++i;
+ blah();
+ ++j;
+ }
+ catch (...)
+ {
+ return 42;
+ }
+}
+
+// The catch block should be optimized away.
+// { dg-final { scan-tree-dump-times "42" 0 "optimized" } }
diff --git a/gcc/testsuite/g++.dg/opt/pr15054.C b/gcc/testsuite/g++.dg/opt/pr15054.C
new file mode 100644
index 00000000000..cfc48cf2498
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr15054.C
@@ -0,0 +1,36 @@
+// PR middle-end/15054
+// This used to abort due to overlapping stack temporaries.
+
+// { dg-do run }
+// { dg-options "-O" }
+
+extern "C" void abort (void);
+
+struct pointer
+{
+ void* ptr;
+
+ pointer(void* x = 0) : ptr(x) {}
+ pointer(const pointer& x) : ptr(x.ptr) {}
+};
+
+struct element
+{
+ int canary;
+
+ element() : canary(123) { }
+ ~element() { pointer(); if (canary != 123) abort (); }
+};
+
+inline pointer
+insert(const element& x)
+{
+ return pointer(new element(x));
+}
+
+int
+main (void)
+{
+ insert(element());
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/opt/static4.C b/gcc/testsuite/g++.dg/opt/static4.C
new file mode 100644
index 00000000000..87e11b02756
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/static4.C
@@ -0,0 +1,15 @@
+// PR 13898
+// Make sure the two X variables get assigned unique assembler names
+// if they are promoted to static storage.
+
+// { dg-do compile }
+
+int g(int i) {
+ if (i<1) {
+ const int x[3] = { 1,2,3 };
+ return x[i];
+ } else {
+ const int x[3] = { 4,5,6 };
+ return x[i];
+ }
+}
diff --git a/gcc/testsuite/g++.dg/other/pragma-re-2.C b/gcc/testsuite/g++.dg/other/pragma-re-2.C
new file mode 100644
index 00000000000..44d1b50f699
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/pragma-re-2.C
@@ -0,0 +1,25 @@
+/* PR c++/14962 */
+/* Originator: <phil@fsel.com> */
+
+/* { dg-do compile { target *-*-solaris* } } */
+/* { dg-final { scan-assembler "new_name" } } */
+/* { dg-final { scan-assembler-not "old_name" } } */
+
+#ifndef __PRAGMA_REDEFINE_EXTNAME
+#error
+#endif
+
+extern "C" {
+
+struct old_name { int i; };
+
+#pragma redefine_extname old_name new_name
+
+int old_name(void);
+
+}
+
+int foo(void)
+{
+ return old_name();
+}
diff --git a/gcc/testsuite/g++.dg/other/vararg-1.C b/gcc/testsuite/g++.dg/other/vararg-1.C
new file mode 100644
index 00000000000..f25606e932b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/vararg-1.C
@@ -0,0 +1,20 @@
+// C++/15119
+// This ICEd in substitute_placeholder_in_expr because it did not
+// implement the 4 element trees.
+// Orginal test by: <wanderer@rsu.ru>
+// Reduced by: <bangerth@dealii.org>
+/* { dg-do compile } */
+
+template<typename T>
+const T& xmin(const T& a, const T& b);
+
+void bar (char *, ...);
+
+char const* descs[4];
+
+int main() {
+ int t = 1;
+ char buf[100];
+ bar( buf, descs[ xmin(t-1,4) ], 0 );
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/parse/crash10.C b/gcc/testsuite/g++.dg/parse/crash10.C
index 878139fa0de..8212fcb5b29 100644
--- a/gcc/testsuite/g++.dg/parse/crash10.C
+++ b/gcc/testsuite/g++.dg/parse/crash10.C
@@ -5,6 +5,8 @@
// PR c++ 10953. ICE
+// { dg-bogus "" "" { target *-*-* } 14 }
+
class
{
typename:: // { dg-error "" "" }
diff --git a/gcc/testsuite/g++.dg/pch/externc-1.C b/gcc/testsuite/g++.dg/pch/externc-1.C
index d0978092cac..26ffb50a0e7 100644
--- a/gcc/testsuite/g++.dg/pch/externc-1.C
+++ b/gcc/testsuite/g++.dg/pch/externc-1.C
@@ -3,4 +3,4 @@
template <typename X> struct foo
{
X y;
-}
+};
diff --git a/gcc/testsuite/g++.dg/template/crash18.C b/gcc/testsuite/g++.dg/template/crash18.C
new file mode 100644
index 00000000000..5eb92929cbd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/crash18.C
@@ -0,0 +1,13 @@
+// { dg-do compile }
+// Contributed by: <leif dot lonnblad at thep dot lu dot se>
+// PR c++/15064: typeid does not form an integral constant expression
+
+#include <typeinfo>
+
+template <typename T>
+void dummy() {
+ const std::type_info& t = typeid(T);
+ const std::type_info& t2 = typeid(float);
+}
+
+template void dummy<int>(void);
diff --git a/gcc/testsuite/g++.dg/template/member5.C b/gcc/testsuite/g++.dg/template/member5.C
new file mode 100644
index 00000000000..45dcd6c6c66
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/member5.C
@@ -0,0 +1,32 @@
+// { dg-do compile }
+// Contributed by: <fasbjx at free dot fr>
+// PR c++/14389: Disambiguate overloaded member templates which differ only
+// in the template argument list.
+
+namespace N1 {
+
+struct S {
+ template< typename B, typename A > void foo();
+ template< typename A > void foo();
+};
+
+template< typename A > void S::foo() {}
+template< typename B, typename A > void S::foo() {}
+
+template void S::foo<void> ();
+template void S::foo<void,void> ();
+
+}
+
+namespace N2 {
+
+struct S {
+ template< typename _A > void foo();
+ template< int _i > void foo();
+};
+
+template< typename _A > void S::foo() {}
+
+template void S::foo< 0 >(); // { dg-error "no definition available|instantiated from here" }
+
+}
diff --git a/gcc/testsuite/g++.dg/tree-ssa/20040317-1.C b/gcc/testsuite/g++.dg/tree-ssa/20040317-1.C
new file mode 100644
index 00000000000..e2f3dcdceb8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/20040317-1.C
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+/* Test provided by Brian Ryner in PR 14511. The alias analyzer was
+ not handling structures containing arrays properly. In this case,
+ the static cast was introducing two assignments of the form
+
+ this_6->_vptr.IFoo = &_ZTV4IFoo[2];
+ this_4->_vptr.IFoo = &_ZTV3Bar[2];
+
+ which were not considered to alias each other because the alias
+ analyzer was not computing a proper pointer to array elements.
+ Another related bug was the type based alias analyzer not computing
+ alias relations to _ZTV4IFoo and _ZTV3Bar. Since those variables
+ are read-only, it was disregarding alias information for them.
+ So, the memory tags for the two 'this' variables were not being
+ marked as aliased with these variables. Resulting in the two
+ assignments not aliasing each other.
+
+ This was causing the optimizers to generate a call to the virtual
+ method Foo() instead of the overloaded version. */
+
+struct IFoo
+{
+ virtual void Foo() = 0;
+};
+
+struct Bar : IFoo
+{
+ void Foo() { }
+};
+
+int main(int argc, char **argv)
+{
+ Bar* b = new Bar();
+ static_cast<IFoo*>(b)->Foo();
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/tree-ssa/nothrow-1.C b/gcc/testsuite/g++.dg/tree-ssa/nothrow-1.C
new file mode 100644
index 00000000000..6bd092977cd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/nothrow-1.C
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-cfg" } */
+double a;
+void t()
+{
+ a=1;
+}
+void t1(void);
+void abort(void);
+
+void q()
+{
+ try {
+ t();
+ }
+ catch (...) {abort();}
+}
+/* We shouldnotice nothrow attribute. */
+/* { dg-final { scan-tree-dump-times "exception" 0 "cfg"} } */
diff --git a/gcc/testsuite/g++.dg/tree-ssa/tree-ssa.exp b/gcc/testsuite/g++.dg/tree-ssa/tree-ssa.exp
new file mode 100644
index 00000000000..4788baa7838
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/tree-ssa.exp
@@ -0,0 +1,36 @@
+# Copyright (C) 2003 Free Software Foundation, Inc.
+
+# This program 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 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib g++-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CXXFLAGS
+if ![info exists DEFAULT_CXXFLAGS] then {
+ set DEFAULT_CXXFLAGS " -ansi -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[CS\]]] \
+ "" $DEFAULT_CXXFLAGS
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/g++.dg/warn/Wswitch-1.C b/gcc/testsuite/g++.dg/warn/Wswitch-1.C
index e9fcb581817..4f44e12576e 100644
--- a/gcc/testsuite/g++.dg/warn/Wswitch-1.C
+++ b/gcc/testsuite/g++.dg/warn/Wswitch-1.C
@@ -19,17 +19,17 @@ foo (int i, int j, enum e ei, enum e ej, enum e ek, enum e el,
case 4: return 3;
default: break;
}
- switch (ei)
- { /* { dg-warning "enumeration value `e1' not handled in switch" "enum e1" { target *-*-* } 24 } */
- } /* { dg-warning "enumeration value `e2' not handled in switch" "enum e2" } */
+ switch (ei) /* { dg-warning "enumeration value `e1' not handled in switch" "enum e1" } */
+ { /* { dg-warning "enumeration value `e2' not handled in switch" "enum e2" { target *-*-* } 22 } */
+ }
switch (ej)
{
default: break;
}
- switch (ek)
+ switch (ek) /* { dg-warning "enumeration value `e2' not handled in switch" "enum e2" } */
{
case e1: return 1;
- } /* { dg-warning "enumeration value `e2' not handled in switch" "enum e2" } */
+ }
switch (el)
{
case e1: return 1;
@@ -50,8 +50,8 @@ foo (int i, int j, enum e ei, enum e ej, enum e ek, enum e el,
{
case e1: return 1;
case e2: return 2;
- case 3: return 3;
- } /* { dg-warning "case value `3' not in enumerated type `e'" "excess 3" } */
+ case 3: return 3; /* { dg-warning "case value `3' not in enumerated type `e'" "excess 3" } */
+ }
switch (ep)
{
case e1: return 1;
diff --git a/gcc/testsuite/g++.dg/warn/Wswitch-2.C b/gcc/testsuite/g++.dg/warn/Wswitch-2.C
index b151e2310c7..9bc7d022b46 100644
--- a/gcc/testsuite/g++.dg/warn/Wswitch-2.C
+++ b/gcc/testsuite/g++.dg/warn/Wswitch-2.C
@@ -13,19 +13,19 @@ foo (enum e ei, int j)
case e3: return 2;
case e4: return 3;
} /* No warning here since e2 has the same value as e3. */
- switch (ei)
+ switch (ei) /* { dg-warning "enumeration value `e4' not handled in switch" "enum e4" } */
{
case e1: return 1;
case e2: return 2;
- } /* { dg-warning "enumeration value `e4' not handled in switch" "enum e4" } */
+ }
switch ((int) ei)
{
case e1: return 1;
} /* No warning here since switch condition was cast to int. */
- switch ((enum e) j)
+ switch ((enum e) j) /* { dg-warning "enumeration value `e1' not handled in switch" "enum e1" } */
{
case e2: return 1;
case e4: return 2;
- } /* { dg-warning "enumeration value `e1' not handled in switch" "enum e1" } */
+ }
return 0;
}
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-5.C b/gcc/testsuite/g++.dg/warn/Wunused-5.C
index 06d1a0516bc..8a8d9d280fc 100644
--- a/gcc/testsuite/g++.dg/warn/Wunused-5.C
+++ b/gcc/testsuite/g++.dg/warn/Wunused-5.C
@@ -1,13 +1,19 @@
-// PR c++/14199
-// { dg-options "-W -Wall -Wunused" }
-
-struct X {
- static void foo ();
-};
-
-template <typename T>
-void foo (const T &t) {
- t.foo();
-}
+/* PR opt/14288 */
+/* { dg-do compile } */
+/* { dg-options "-O -Wall" } */
+
+volatile int sink;
+extern int foo(int);
+
+struct S
+{
+ int x;
-template void foo (const X &);
+ S() { x = foo(0); }
+ ~S() { sink = x; }
+};
+
+int test(bool p)
+{
+ return p ? foo(S().x) : 0; /* { dg-bogus "uninitialized" } */
+}
diff --git a/gcc/testsuite/g++.dg/warn/noeffect5.C b/gcc/testsuite/g++.dg/warn/noeffect5.C
new file mode 100644
index 00000000000..f0f4e74109a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/noeffect5.C
@@ -0,0 +1,8 @@
+/* PR middle-end/13325 */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+void *memcpy(void *dest, const void *src, __SIZE_TYPE__ n);
+void f (void *dest, const void *src) {
+ memcpy (dest, src, 0);
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.ext/arrnew2.C b/gcc/testsuite/g++.old-deja/g++.ext/arrnew2.C
index 84063834f1d..93d15d08d90 100644
--- a/gcc/testsuite/g++.old-deja/g++.ext/arrnew2.C
+++ b/gcc/testsuite/g++.old-deja/g++.ext/arrnew2.C
@@ -1,4 +1,8 @@
-// { dg-do assemble }
-// { dg-options "" }
+// { dg-do run { xfail *-*-* } }
+// { dg-options "-w -fpermissive" }
-int *foo = new int[1](0); // { dg-bogus "" }
+int *foo = new int[1](42); // { dg-bogus "" }
+int main ()
+{
+ return foo[0] != 42;
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.martin/new1.C b/gcc/testsuite/g++.old-deja/g++.martin/new1.C
index c7951654c26..502c4f42ad0 100644
--- a/gcc/testsuite/g++.old-deja/g++.martin/new1.C
+++ b/gcc/testsuite/g++.old-deja/g++.martin/new1.C
@@ -71,8 +71,8 @@ void test1()
func(new B(A(10).addr()));
}catch(int){
}
- CHECK(new_done==1);
- CHECK(ctor_done==2);
+ CHECK(ctor_done==1);
+ CHECK(new_done==2);
CHECK(func_done==3);
CHECK(dtor_done==4);
CHECK(delete_done==0);
@@ -86,10 +86,10 @@ void test2()
func(new B(A(10).addr()));
}catch(int){
}
- CHECK(new_done==1);
- CHECK(ctor_done==0);
+ CHECK(ctor_done==1);
+ CHECK(new_done==2);
CHECK(func_done==0);
- CHECK(dtor_done==0);
+ CHECK(dtor_done==3);
CHECK(delete_done==0);
}
@@ -101,11 +101,11 @@ void test3()
func(new B(A(10).addr()));
}catch(int){
}
- CHECK(new_done==1);
- CHECK(ctor_done==2);
+ CHECK(new_done==0);
+ CHECK(ctor_done==1);
CHECK(func_done==0);
CHECK(dtor_done==0);
- CHECK(delete_done==3);
+ CHECK(delete_done==0);
}
int main()
diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb42.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb42.C
deleted file mode 100644
index c27aa8d2df7..00000000000
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb42.C
+++ /dev/null
@@ -1,19 +0,0 @@
-//Build don't link:
-#include <vector>
-#include <algorithm>
-
-template <class T> class Expr
-{
-public :
-Expr(){};
-Expr(const T&){};
-};
-
-template <class T >
-inline bool compare(const Expr<T> a, const Expr<T> b){ return true; };
-
-int main()
-{
- std::vector<int> a(3);
- std::sort( a.begin(), a.end(), compare ); // ERROR - no matching function
-}
diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb58.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb58.C
index 566cf9a7831..04ec92a30af 100644
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb58.C
+++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb58.C
@@ -1,5 +1,5 @@
// { dg-do run }
-// { dg-options "" }
+// { dg-options "-w -fpermissive" }
// Test for g++ array init extension
class A {
diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb63.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb63.C
index a1601f80f9f..a49fb02641c 100644
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb63.C
+++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb63.C
@@ -1,5 +1,5 @@
// { dg-do run }
-// { dg-options "" }
+// { dg-options "-w -fpermissive" }
//This uses GNU extensions, so disable -ansi
#include <stdio.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.c-torture/compile/20010518-1.c b/gcc/testsuite/gcc.c-torture/compile/20010518-1.c
index 4ab40d8e226..0a1b284b447 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20010518-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20010518-1.c
@@ -25,7 +25,7 @@ enum rtx_code
UNKNOWN,
NIL,
REG,
- LAST_AND_UNUSED_RTX_CODE
+ LAST_AND_UNUSED_RTX_CODE = 256
};
typedef struct
diff --git a/gcc/testsuite/gcc.c-torture/compile/20030310-1.c b/gcc/testsuite/gcc.c-torture/compile/20030310-1.c
new file mode 100644
index 00000000000..0e89e0bfca2
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20030310-1.c
@@ -0,0 +1,13 @@
+static inline void
+foo (char accept)
+{
+ char s;
+ while (s == accept) ;
+}
+
+static void
+bar (void)
+{
+ char ch;
+ foo (ch);
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20030405-1.c b/gcc/testsuite/gcc.c-torture/compile/20030405-1.c
index 2e61f1fa3ff..f84e606c045 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20030405-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20030405-1.c
@@ -1,58 +1,30 @@
-/* PR optimization/10024 */
-extern int *allegro_errno;
-typedef long fixed;
-extern inline int
-fixfloor (fixed x)
-{
- if (x >= 0)
- return (x >> 16);
- else
- return ~((~x) >> 16);
-}
-extern inline int
-fixtoi (fixed x)
-{
- return fixfloor (x) + ((x & 0x8000) >> 15);
-}
-extern inline fixed
-ftofix (double x)
-{
- if (x > 32767.0)
- {
- *allegro_errno = 34;
- return 0x7FFFFFFF;
- }
- if (x < -32767.0)
- {
- *allegro_errno = 34;
- return -0x7FFFFFFF;
- }
- return (long) (x * 65536.0 + (x < 0 ? -0.5 : 0.5));
-}
-extern inline double
-fixtof (fixed x)
-{
- return (double) x / 65536.0;
-}
-extern inline fixed
-fixdiv (fixed x, fixed y)
+/* When compiled with -pedantic, this program will cause an ICE when the
+ constant propagator tries to set the value of *str to UNDEFINED.
+
+ This happens because *str is erroneously considered as a store alias.
+ The aliasing code is then making *str an alias leader for its alias set
+ and when the PHI node at the end of the while() is visited the first
+ time, CCP will try to assign it a value of UNDEFINED, but the default
+ value for *str is a constant. */
+typedef unsigned int size_t;
+size_t strlength (const char * const);
+char foo();
+
+static const char * const str = "mingo";
+
+bar()
{
- if (y == 0)
+ size_t c;
+ char *x;
+
+ c = strlength (str);
+ while (c < 10)
{
- *allegro_errno = 34;
- return (x < 0) ? -0x7FFFFFFF : 0x7FFFFFFF;
+ if (c > 5)
+ *x = foo ();
+ if (*x < 'a')
+ break;
}
- else
- return ftofix (fixtof (x) / fixtof (y));
-}
-extern inline fixed
-itofix (int x)
-{
- return x << 16;
-}
-int
-foo (int n)
-{
- return fixtoi (fixdiv (itofix (512), itofix (n)));
+ return *x == '3';
}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20030405-1.x b/gcc/testsuite/gcc.c-torture/compile/20030405-1.x
new file mode 100644
index 00000000000..3dbbbda51b7
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20030405-1.x
@@ -0,0 +1,3 @@
+# This test was found to fail only when -pedantic is used.
+set options "-pedantic"
+return 0
diff --git a/gcc/testsuite/gcc.c-torture/compile/20030416-1.c b/gcc/testsuite/gcc.c-torture/compile/20030416-1.c
new file mode 100644
index 00000000000..c3d18b68281
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20030416-1.c
@@ -0,0 +1,16 @@
+void foo(int x)
+{
+ if (x > 3)
+ {;}
+ else
+ bar();
+ x = 9;
+}
+
+main()
+{
+ int j;
+
+ foo(j);
+ return j;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20030530-1.c b/gcc/testsuite/gcc.c-torture/compile/20030530-1.c
new file mode 100644
index 00000000000..b479ea22b1d
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20030530-1.c
@@ -0,0 +1,23 @@
+union tree_node;
+typedef union tree_node *tree;
+struct tree_common
+{
+ tree type;
+ unsigned lang_flag_0 : 1;
+};
+union tree_node
+{
+ struct tree_common common;
+};
+static void
+java_check_regular_methods (tree class_decl)
+{
+ int saw_constructor = class_decl->common.type->common.lang_flag_0;
+ tree class = class_decl->common.type;
+ for (;;)
+ {
+ if (class)
+ if (class_decl->common.type)
+ bar (class);
+ }
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20030530-3.c b/gcc/testsuite/gcc.c-torture/compile/20030530-3.c
new file mode 100644
index 00000000000..0a93d2f13fa
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20030530-3.c
@@ -0,0 +1,16 @@
+struct tree_decl
+{
+ unsigned in_system_header_flag:1;
+};
+union tree_node
+{
+ struct tree_decl decl;
+};
+typedef union tree_node *tree;
+static int
+redeclaration_error_message (olddecl)
+ tree olddecl;
+{
+ if (({olddecl;})->decl.in_system_header_flag)
+ ;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20030716-1.c b/gcc/testsuite/gcc.c-torture/compile/20030716-1.c
new file mode 100644
index 00000000000..ceb4b6171e9
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20030716-1.c
@@ -0,0 +1,7 @@
+void baz(int i);
+
+void foo(int i, int A[i+1])
+{
+ int j=A[i];
+ void bar() { baz(A[i]); }
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20030823-1.c b/gcc/testsuite/gcc.c-torture/compile/20030823-1.c
new file mode 100644
index 00000000000..89a3ea50a7f
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20030823-1.c
@@ -0,0 +1,18 @@
+struct A
+{
+ int a;
+};
+
+int foo (struct A *a)
+{
+ static int c = 30;
+ int x;
+
+ a->a = c;
+ /* Dominator optimizations will replace the use of 'a->a' with 'c', but
+ they won't copy the virtual operands for 'c' from its originating
+ statement. This exposes symbol 'c' without a correct SSA version
+ number. */
+ x = a->a;
+ return x;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20030902-1.c b/gcc/testsuite/gcc.c-torture/compile/20030902-1.c
new file mode 100644
index 00000000000..443b43921b8
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20030902-1.c
@@ -0,0 +1,37 @@
+typedef unsigned int size_t;
+typedef unsigned long int reg_syntax_t;
+struct re_pattern_buffer
+{
+ unsigned char *buffer;
+};
+typedef enum
+{
+ jump,
+ jump_n,
+} re_opcode_t;
+static int
+foo (bufp)
+ struct re_pattern_buffer *bufp;
+{
+ int mcnt;
+ unsigned char *p = bufp->buffer;
+ switch (((re_opcode_t) * p++))
+ {
+ unconditional_jump:
+ ;
+ /* This test case caused an ICE because the statement insertion
+ routines were failing to update basic block boundaries. */
+ case jump:
+ do
+ {
+ (mcnt) = *(p) & 0377;
+ }
+ while (0);
+ (p) += 2;
+ p += mcnt;
+ case jump_n:
+ (mcnt) = *(p + 2) & 0377;
+ if (mcnt)
+ goto unconditional_jump;
+ }
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20030910-1.c b/gcc/testsuite/gcc.c-torture/compile/20030910-1.c
new file mode 100644
index 00000000000..9fad109208c
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20030910-1.c
@@ -0,0 +1,11 @@
+/* The gimplifier was getting confused when taking the real or
+ imaginary component of a complex rvalue. */
+
+void test()
+{
+ __complex double dc;
+ double d;
+
+ d = __real (dc * dc);
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/compile/20030917-1.c b/gcc/testsuite/gcc.c-torture/compile/20030917-1.c
new file mode 100644
index 00000000000..38b6598af14
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20030917-1.c
@@ -0,0 +1,18 @@
+typedef struct string STR;
+typedef struct atbl ARRAY;
+struct string {
+ unsigned char str_pok;
+};
+struct atbl {
+ int ary_fill;
+};
+blah(size,strp)
+register int size;
+register STR **strp;
+{
+ register ARRAY *ar;
+ ar->ary_fill = size - 1;
+ while (size--)
+ (*strp)->str_pok &= ~128;
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/compile/20031124-1.c b/gcc/testsuite/gcc.c-torture/compile/20031124-1.c
new file mode 100644
index 00000000000..102e71aa84f
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20031124-1.c
@@ -0,0 +1,8 @@
+/* PR 13143 */
+
+int f (void *ptr)
+{
+ extern char const stop[];
+ return ptr >= (void *) &stop;
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/compile/20031125-1.c b/gcc/testsuite/gcc.c-torture/compile/20031125-1.c
new file mode 100644
index 00000000000..735a20bc241
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20031125-1.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+short *_offsetTable;
+/* This tests to make sure PRE splits the entry block ->block 0 edge
+ when there are multiple block 0 predecessors.
+ This is done so that we don't end up with an insertion on the
+ entry block -> block 0 edge which would require a split at insertion
+ time.
+ PR 13163. */
+void proc4WithoutFDFE(char *dst, const char *src, int next_offs, int bw,
+ int bh, int pitch)
+{
+ do {
+ int i = bw;
+ int code = *src++;
+ int x, l;
+ int length = *src++ + 1;
+
+ for (l = 0; l < length; l++) {
+ int x;
+
+ for (x = 0; x < 4; x++) ;
+ if (i == 0)
+ dst += pitch * 3;
+ }
+ char *dst2 = dst + _offsetTable[code] + next_offs;
+
+ for (x = 0; x < 4; x++) {
+ int j = 0;
+ (dst + pitch * x)[j] = (dst2 + pitch * x)[j];
+ }
+ dst += pitch * 3;
+ } while (--bh);
+}
+
+
diff --git a/gcc/testsuite/gcc.c-torture/compile/20031125-2.c b/gcc/testsuite/gcc.c-torture/compile/20031125-2.c
new file mode 100644
index 00000000000..2af8a021175
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20031125-2.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+struct BlobSpan {
+ int right;
+};
+/* This test makes sure we don't accidently cause a bad insertion to occur
+ by choosing the wrong variable name so that we end up with a use not
+ dominated by a def. */
+void render_blob_line(struct BlobSpan blobdata) {
+ int buf[4 * 8];
+ int *data = buf;
+ int i, n = 0;
+ if (blobdata.right)
+ n++;
+ if (n)
+ for (; i < 2 * n;)
+ data[i] = 0;
+ n *= 2;
+ for (; n;) ;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20031203-1.c b/gcc/testsuite/gcc.c-torture/compile/20031203-1.c
new file mode 100644
index 00000000000..7827eb9066f
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20031203-1.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+void make_file_symbol_completion_list (char *);
+/* This tests to make sure PRE doesn't choose the wrong name when
+ inserting phi nodes. Otherwise, we get uses that aren't dominated
+ by defs.
+ PR 13177. */
+void location_completer (char *text)
+{
+ char *p, *symbol_start = text;
+ for (p = text; *p != '\0'; ++p) {
+ if (*p == '\\' && p[1] == '\'')
+ p++;
+ else if (*p == ':')
+ symbol_start = p + 1;
+ else
+ symbol_start = p + 1;
+ make_file_symbol_completion_list(symbol_start);
+ }
+}
+
+
diff --git a/gcc/testsuite/gcc.c-torture/compile/20031203-2.c b/gcc/testsuite/gcc.c-torture/compile/20031203-2.c
new file mode 100644
index 00000000000..47f561bae77
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20031203-2.c
@@ -0,0 +1,6 @@
+/* Don't ICE on stupid user tricks. */
+
+int foo(int bar)
+{
+ return (&bar)[-1];
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20031203-3.c b/gcc/testsuite/gcc.c-torture/compile/20031203-3.c
new file mode 100644
index 00000000000..341a9df984a
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20031203-3.c
@@ -0,0 +1,7 @@
+/* Don't ICE on user silliness. GCC 3.4 and before accepts this without
+ comment; 3.5 warns. Perhaps eventually we'll declare this an error. */
+
+void bar (void)
+{
+ ({});
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040219-1.c b/gcc/testsuite/gcc.c-torture/compile/20040219-1.c
new file mode 100644
index 00000000000..d3bc9272b64
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20040219-1.c
@@ -0,0 +1 @@
+double foo() { return __builtin_isgreater(0.,0.); }
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040220-1.c b/gcc/testsuite/gcc.c-torture/compile/20040220-1.c
new file mode 100644
index 00000000000..8a4a5ba6d0f
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20040220-1.c
@@ -0,0 +1,16 @@
+/* PR 14194 */
+
+int irqs;
+
+static inline __attribute__((always_inline))
+int kstat_irqs (void) {
+ int i, sum = 0;
+ for (i = 0; i < 1; i++)
+ if (__builtin_expect(i, 0))
+ sum += irqs;
+ return sum;
+}
+
+int show_interrupts (void) {
+ return kstat_irqs ();
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040303-1.c b/gcc/testsuite/gcc.c-torture/compile/20040303-1.c
new file mode 100644
index 00000000000..6b2452adab9
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20040303-1.c
@@ -0,0 +1,16 @@
+typedef struct input {
+ struct input *next;
+} input_t;
+static input_t *inputs = (input_t *)((void *)0);
+void
+RemoveInput(unsigned long id)
+{
+ input_t *ip;
+ input_t *prev;
+ while (1)
+ if (ip == (input_t *)id)
+ break;
+ if (ip == (input_t *)((void *)0))
+ return;
+ prev->next = ip->next;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040303-2.c b/gcc/testsuite/gcc.c-torture/compile/20040303-2.c
new file mode 100644
index 00000000000..6751620a43a
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20040303-2.c
@@ -0,0 +1,23 @@
+void abort(void);
+int x, y;
+void init_xy(void);
+void
+test4(void)
+{
+ init_xy();
+ _Bool iftemp0;
+ int x1 = x;
+ _Bool iftemp1;
+ x1++;
+ if (x1 != 3)
+ {
+ iftemp1 = 1;
+ goto endfirstif;
+ }
+ iftemp1 = 0;
+ endfirstif:
+ iftemp0 = iftemp1;
+ if (iftemp0)
+ abort();
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040304-1.c b/gcc/testsuite/gcc.c-torture/compile/20040304-1.c
index 146d42f23d6..ee277d799a4 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20040304-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20040304-1.c
@@ -1,45 +1,20 @@
-/* PR optimization/14235 */
-/* Origin: <senor_fjord@yahoo.com> */
-
-typedef signed char int8_t;
-typedef short int16_t;
-typedef int int32_t;
-typedef unsigned long long uint64_t;
-
-static const uint64_t LOW_BYTE_MASK = 0x00000000000000ffULL;
-static const uint64_t HIGH_BYTE_MASK = 0x000000000000ff00ULL;
-static const uint64_t WORD_MASK = 0x000000000000ffffULL;
-static const uint64_t DWORD_MASK = 0x00000000ffffffffULL;
-
-extern uint64_t *srca_mask;
-extern int *assert_thrown;
-
-void foo()
+void
+cpplib_macroExpand (char * pfile)
{
- uint64_t tempA = 0; /* actually a bunch of code to set A */
- uint64_t tempB = 0; /* actually a bunch of code to set B */
-
- /* cast A to right size */
- tempA = (((*srca_mask == LOW_BYTE_MASK) ||
- (*srca_mask == HIGH_BYTE_MASK)) ?
- ((int8_t)tempA) :
- ((*srca_mask == WORD_MASK) ?
- ((int16_t)tempA) :
- ((*srca_mask == DWORD_MASK) ?
- ((int32_t)tempA) :
- tempA)));
-
- /* cast B to right size */
- tempB = (((*srca_mask == LOW_BYTE_MASK) ||
- (*srca_mask == HIGH_BYTE_MASK)) ?
- ((int8_t)tempB) :
- ((*srca_mask == WORD_MASK) ?
- ((int16_t)tempB) :
- ((*srca_mask == DWORD_MASK) ?
- ((int32_t)tempB) :
- tempB)));
-
- if ((int) tempA > (int) tempB) {
- *assert_thrown = 1;
- }
+ int nargs;
+ int rest_args;
+ int token = -1;
+ rest_args = 0;
+ do
+ {
+ if (rest_args != 0)
+ continue;
+ if (nargs == 0)
+ {
+ rest_args = 1;
+ token = macarg (pfile, rest_args);
+ }
+ }
+ while (token == 20);
}
+
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040309-1.c b/gcc/testsuite/gcc.c-torture/compile/20040309-1.c
new file mode 100644
index 00000000000..df8390f207b
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20040309-1.c
@@ -0,0 +1,20 @@
+static const char default_tupleseps[] = ", \t";
+
+
+fubar (tupleseps)
+ const char *tupleseps;
+{
+ char *kp, *sp;
+ const char *septmp;
+ const char *tseplist;
+ tseplist = (tupleseps) ? tupleseps : default_tupleseps;
+ while (kp)
+ {
+ if (*tseplist)
+ septmp = tseplist;
+ bar (*septmp);
+ if (*tseplist)
+ if (*kp)
+ ;
+ }
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040310-1.c b/gcc/testsuite/gcc.c-torture/compile/20040310-1.c
new file mode 100644
index 00000000000..f0c85f0ada5
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20040310-1.c
@@ -0,0 +1,10 @@
+void I_wacom ()
+{
+ char buffer[50], *p;
+ int RequestData (char *cmd)
+ {
+ p = buffer;
+ foo (buffer);
+ }
+ RequestData (0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040317-1.c b/gcc/testsuite/gcc.c-torture/compile/20040317-1.c
new file mode 100644
index 00000000000..4a3455115cb
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20040317-1.c
@@ -0,0 +1,4 @@
+int String2Array(int len, char strarr[][len])
+{
+ strarr[0];
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040317-2.c b/gcc/testsuite/gcc.c-torture/compile/20040317-2.c
new file mode 100644
index 00000000000..3c8ee2b8ec5
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20040317-2.c
@@ -0,0 +1,25 @@
+typedef struct _ScaleRec *ScaleWidget;
+typedef struct
+{
+ short *x;
+ unsigned short *width;
+} Table;
+typedef struct
+{
+ Table table;
+} ScalePart;
+typedef struct _ScaleRec
+{
+ ScalePart scale;
+} ScaleRec;
+static int
+FindPixel (ScaleWidget sw, short x, short y,
+ short * img_x, short * img_y, unsigned long * img_pixel)
+{
+ if (sw->scale.table.x[(int) *img_x] +
+ (short) sw->scale.table.width[(int) *img_x] < x)
+ {
+ ++*img_x;
+ return FindPixel (sw, x, y, img_x, img_y, img_pixel);
+ }
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040317-3.c b/gcc/testsuite/gcc.c-torture/compile/20040317-3.c
new file mode 100644
index 00000000000..e6982c3e3b3
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20040317-3.c
@@ -0,0 +1,11 @@
+I_wacom ()
+{
+ char buffer[50], *p;
+ int RequestData (char *cmd)
+ {
+ p = buffer;
+ foo (buffer);
+ }
+ RequestData (0);
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040323-1.c b/gcc/testsuite/gcc.c-torture/compile/20040323-1.c
new file mode 100644
index 00000000000..c87e7dc70ba
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20040323-1.c
@@ -0,0 +1,11 @@
+/* PR 14694 */
+/* { dg-require-alias "" } */
+
+extern unsigned int _rtld_local __attribute__ ((alias ("_rtld_global")));
+
+unsigned int
+_dl_start (void *arg)
+{
+ unsigned int elf_machine_rel () { return _rtld_local; }
+ return elf_machine_rel ();
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040401-1.c b/gcc/testsuite/gcc.c-torture/compile/20040401-1.c
new file mode 100644
index 00000000000..ee727a9b205
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20040401-1.c
@@ -0,0 +1,6 @@
+int __atomic_readv_replacement(unsigned char iov_len, int count, int i) {
+ unsigned char bytes = 0;
+ if ((unsigned char)((char)127 - bytes) < iov_len)
+ return 22;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040415-1.c b/gcc/testsuite/gcc.c-torture/compile/20040415-1.c
new file mode 100644
index 00000000000..1b1537a7ba6
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20040415-1.c
@@ -0,0 +1,5 @@
+int isdigit (int);
+int f (const char *type)
+{
+ return isdigit ((unsigned char) *type++);
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040415-2.c b/gcc/testsuite/gcc.c-torture/compile/20040415-2.c
new file mode 100644
index 00000000000..e78e81e8cf8
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20040415-2.c
@@ -0,0 +1,7 @@
+int isascii (int);
+
+int f1 (const char *type)
+{
+ return isascii ((unsigned char) *type++);
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040419-1.c b/gcc/testsuite/gcc.c-torture/compile/20040419-1.c
new file mode 100644
index 00000000000..76910455ffa
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20040419-1.c
@@ -0,0 +1,3 @@
+/* This used to ICE because PHI-OPT would produce non-gimple code. */
+
+int f(double d0, double d1) { return d0 > 0 == d1 > 0; }
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr14730.c b/gcc/testsuite/gcc.c-torture/compile/pr14730.c
new file mode 100644
index 00000000000..b4f36a9ae3c
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr14730.c
@@ -0,0 +1,16 @@
+/* PR middle-end/14730 */
+
+int t (char i)
+{
+ switch (i)
+ {
+ case 1:
+ case 7:
+ case 10:
+ case 14:
+ case 9:
+ case 256:
+ return 0;
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr15245.c b/gcc/testsuite/gcc.c-torture/compile/pr15245.c
new file mode 100644
index 00000000000..d7d9051a1c1
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr15245.c
@@ -0,0 +1,21 @@
+/* Testcase from <marcus@jet.franken.de>
+ PR optimization/15245
+ This used to ICE as convert was used
+ in tree-ssa-phiopt which created non gimple
+ code. */
+
+char *f(char *x, int flag)
+{
+ char *ret = (char*)0;
+
+
+ if( x > (char*)1 ) {
+ if(x)
+ return (char*)0;
+ } else {
+ if( flag & 1 )
+ ret = (char*)1;
+ flag |= 2;
+ }
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20000603-1.c b/gcc/testsuite/gcc.c-torture/execute/20000603-1.c
index 9c9f69baf04..4e31eee4563 100644
--- a/gcc/testsuite/gcc.c-torture/execute/20000603-1.c
+++ b/gcc/testsuite/gcc.c-torture/execute/20000603-1.c
@@ -1,5 +1,10 @@
+/* It is not clear whether this test is conforming. See DR#236
+ http://wwwold.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_236.htm. However,
+ there seems to be consensus that the presence of a union to aggregate
+ struct s1 and struct s2 should make it conforming. */
struct s1 { double d; };
struct s2 { double d; };
+union u { struct s1 x; struct s2 y; };
double f(struct s1 *a, struct s2 *b)
{
@@ -9,9 +14,9 @@ double f(struct s1 *a, struct s2 *b)
int main()
{
- struct s1 a;
- a.d = 0.0;
- if (f (&a, (struct s2 *)&a) != 2.0)
+ union u a;
+ a.x.d = 0.0;
+ if (f (&a.x, &a.y) != 2.0)
abort ();
return 0;
}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20020819-1.c b/gcc/testsuite/gcc.c-torture/execute/20020819-1.c
new file mode 100644
index 00000000000..549da910cd4
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20020819-1.c
@@ -0,0 +1,22 @@
+foo ()
+{
+ return 0;
+}
+
+main()
+{
+ int i, j, k, ccp_bad = 0;
+
+ for (i = 0; i < 10; i++)
+ {
+ for (j = 0; j < 10; j++)
+ if (foo ())
+ ccp_bad = 1;
+
+ k = ccp_bad != 0;
+ if (k)
+ abort ();
+ }
+
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20021113-1.c b/gcc/testsuite/gcc.c-torture/execute/20021113-1.c
new file mode 100644
index 00000000000..420926d7548
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20021113-1.c
@@ -0,0 +1,17 @@
+/* This program tests a data flow bug that would cause constant propagation
+ to propagate constants through function calls. */
+
+foo (int *p)
+{
+ *p = 10;
+}
+
+main()
+{
+ int *ptr = alloca (sizeof (int));
+ *ptr = 5;
+ foo (ptr);
+ if (*ptr == 5)
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20030403-1.c b/gcc/testsuite/gcc.c-torture/execute/20030403-1.c
new file mode 100644
index 00000000000..cbf1351c4be
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20030403-1.c
@@ -0,0 +1,16 @@
+/* The non-destructive folder was always emitting >= when folding
+ comparisons to signed_max+1. */
+
+#include <limits.h>
+
+int
+main ()
+{
+ unsigned long count = 8;
+
+ if (count > INT_MAX)
+ abort ();
+
+ return (0);
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/20030404-1.c b/gcc/testsuite/gcc.c-torture/execute/20030404-1.c
new file mode 100644
index 00000000000..1dd1ec09906
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20030404-1.c
@@ -0,0 +1,23 @@
+/* This exposed a bug in tree-ssa-ccp.c. Since 'j' and 'i' are never
+ defined, CCP was not traversing the edges out of the if(), which caused
+ the PHI node for 'k' at the top of the while to only be visited once.
+ This ended up causing CCP to think that 'k' was the constant '1'. */
+main()
+{
+ int i, j, k;
+
+ k = 0;
+ while (k < 10)
+ {
+ k++;
+ if (j > i)
+ j = 5;
+ else
+ j =3;
+ }
+
+ if (k != 10)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20030501-1.c b/gcc/testsuite/gcc.c-torture/execute/20030501-1.c
new file mode 100644
index 00000000000..f47dc291bd3
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20030501-1.c
@@ -0,0 +1,17 @@
+int
+main (int argc, char **argv)
+{
+ int size = 10;
+
+ {
+ int retframe_block()
+ {
+ return size + 5;
+ }
+
+ if (retframe_block() != 15)
+ abort ();
+ exit (0);
+
+ }
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20030828-1.c b/gcc/testsuite/gcc.c-torture/execute/20030828-1.c
new file mode 100644
index 00000000000..e8c1f0195df
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20030828-1.c
@@ -0,0 +1,18 @@
+const int *p;
+
+int bar (void)
+{
+ return *p + 1;
+}
+
+main ()
+{
+ /* Variable 'i' is never used but it's aliased to a global pointer. The
+ alias analyzer was not considering that 'i' may be used in the call to
+ bar(). */
+ const int i = 5;
+ p = &i;
+ if (bar() != 6)
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20030828-2.c b/gcc/testsuite/gcc.c-torture/execute/20030828-2.c
new file mode 100644
index 00000000000..0c3a195e626
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20030828-2.c
@@ -0,0 +1,28 @@
+struct rtx_def
+{
+ int code;
+};
+
+main()
+{
+ int tmp[2];
+ struct rtx_def *r, s;
+ int *p, *q;
+
+ /* The alias analyzer was creating the same memory tag for r, p and q
+ because 'struct rtx_def *' is type-compatible with 'int *'. However,
+ the alias set of 'int[2]' is not the same as 'int *', so variable
+ 'tmp' was deemed not aliased with anything. */
+ r = &s;
+ r->code = 39;
+
+ /* If 'r' wasn't declared, then q and tmp would have had the same memory
+ tag. */
+ p = tmp;
+ q = p + 1;
+ *q = 0;
+ tmp[1] = 39;
+ if (*q != 39)
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20030903-1.c b/gcc/testsuite/gcc.c-torture/execute/20030903-1.c
new file mode 100644
index 00000000000..95dad576f2d
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20030903-1.c
@@ -0,0 +1,21 @@
+/* Test that we don't let stmt.c think that the enumeration's values are
+ the entire set of possibilities. Such an assumption is false for C,
+ but true for other languages. */
+
+enum X { X1 = 1, X2, X3, X4 };
+static volatile enum X test = 0;
+static void y(int);
+
+int main()
+{
+ switch (test)
+ {
+ case X1: y(1); break;
+ case X2: y(2); break;
+ case X3: y(3); break;
+ case X4: y(4); break;
+ }
+ return 0;
+}
+
+static void y(int x) { abort (); }
diff --git a/gcc/testsuite/gcc.c-torture/execute/20030909-1.c b/gcc/testsuite/gcc.c-torture/execute/20030909-1.c
new file mode 100644
index 00000000000..2f149857fc7
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20030909-1.c
@@ -0,0 +1,35 @@
+void abort ();
+void exit (int);
+
+void test(int x, int y)
+{
+ if (x == y)
+ abort ();
+}
+
+void foo(int x, int y)
+{
+ if (x == y)
+ goto a;
+ else
+ {
+a:;
+ if (x == y)
+ goto b;
+ else
+ {
+b:;
+ if (x != y)
+ test (x, y);
+ }
+ }
+}
+
+int main(void)
+{
+ foo (0, 0);
+
+ exit (0);
+}
+
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/20030910-1.c b/gcc/testsuite/gcc.c-torture/execute/20030910-1.c
new file mode 100644
index 00000000000..6c849134a9b
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20030910-1.c
@@ -0,0 +1,13 @@
+/* The gimplifier was inserting unwanted temporaries for REALPART_EXPR
+ nodes. These need to be treated like a COMPONENT_REF so their address can
+ be taken. */
+
+int main()
+{
+ __complex double dc;
+ double *dp = &(__real dc);
+ *dp = 3.14;
+ if ((__real dc) != 3.14) abort();
+ exit (0);
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/20030913-1.c b/gcc/testsuite/gcc.c-torture/execute/20030913-1.c
new file mode 100644
index 00000000000..5e33f50f560
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20030913-1.c
@@ -0,0 +1,26 @@
+/* Assignments via pointers pointing to global variables were being killed
+ by SSA-DCE. Test contributed by Paul Brook <paul@nowt.org> */
+
+int glob;
+
+void
+fn2(int ** q)
+{
+ *q = &glob;
+}
+
+void test()
+{
+ int *p;
+
+ fn2(&p);
+
+ *p=42;
+}
+
+int main()
+{
+ test();
+ if (glob != 42) abort();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20031010-1.c b/gcc/testsuite/gcc.c-torture/execute/20031010-1.c
new file mode 100644
index 00000000000..54457f964c3
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20031010-1.c
@@ -0,0 +1,34 @@
+/* A reminder to process ops in generate_expr_as_of_bb exactly once. */
+
+long __attribute__((noinline))
+foo (long ct, long cf, _Bool p1, _Bool p2, _Bool p3)
+{
+ long diff;
+
+ diff = ct - cf;
+
+ if (p1)
+ {
+ if (p2)
+ {
+ if (p3)
+ {
+ long tmp = ct;
+ ct = cf;
+ cf = tmp;
+ }
+ diff = ct - cf;
+ }
+
+ return diff;
+ }
+
+ abort ();
+}
+
+int main ()
+{
+ if (foo(2, 3, 1, 1, 1) == 0)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20031211-1.c b/gcc/testsuite/gcc.c-torture/execute/20031211-1.c
new file mode 100644
index 00000000000..2361509a096
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20031211-1.c
@@ -0,0 +1,13 @@
+struct a { unsigned int bitfield : 1; };
+
+unsigned int x;
+
+main()
+{
+ struct a a = {0};
+ x = 0xbeef;
+ a.bitfield |= x;
+ if (a.bitfield != 1)
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20031211-2.c b/gcc/testsuite/gcc.c-torture/execute/20031211-2.c
new file mode 100644
index 00000000000..555b17d9ac6
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20031211-2.c
@@ -0,0 +1,19 @@
+struct a
+{
+ unsigned int bitfield : 3;
+};
+
+int main()
+{
+ struct a a;
+
+ a.bitfield = 131;
+ foo (a.bitfield);
+ exit (0);
+}
+
+foo(unsigned int z)
+{
+ if (z != 3)
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20040319-1.c b/gcc/testsuite/gcc.c-torture/execute/20040319-1.c
new file mode 100644
index 00000000000..357932d9b24
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20040319-1.c
@@ -0,0 +1,17 @@
+int
+blah (int zzz)
+{
+ int foo;
+ if (zzz >= 0)
+ return 1;
+ foo = (zzz >= 0 ? (zzz) : -(zzz));
+ return foo;
+}
+
+main()
+{
+ if (blah (-1) != 1)
+ abort ();
+ else
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20040331-1.c b/gcc/testsuite/gcc.c-torture/execute/20040331-1.c
index 67b3e3a2e0c..2e8f9e86748 100644
--- a/gcc/testsuite/gcc.c-torture/execute/20040331-1.c
+++ b/gcc/testsuite/gcc.c-torture/execute/20040331-1.c
@@ -5,8 +5,16 @@ extern void exit (int);
int
main (void)
{
+#if __INT_MAX__ >= 2147483647
struct { int count: 31; } s = { 0 };
while (s.count--)
abort ();
+#elif __INT_MAX__ >= 32767
+ struct { int count: 15; } s = { 0 };
+ while (s.count--)
+ abort ();
+#else
+ /* Don't bother because __INT_MAX__ is too small. */
+#endif
exit (0);
}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20040409-2.c b/gcc/testsuite/gcc.c-torture/execute/20040409-2.c
index 5bec7ee9218..c83ff1adf5e 100644
--- a/gcc/testsuite/gcc.c-torture/execute/20040409-2.c
+++ b/gcc/testsuite/gcc.c-torture/execute/20040409-2.c
@@ -227,13 +227,13 @@ int main()
test(0x1234,0x8000);
test(0x8000,0x1234);
test(0x9234,0x0000);
- test(0x7fff,0xffff);
- test(0xffff,0x7fff);
+ test(0x7fff,0xedcb);
+ test(0xffff,0x6dcb);
- testu(0x0000,0x8000);
- testu(0x8000,0x0000);
- testu(0x1234,0x9234);
- testu(0x9234,0x1234);
+ testu(0x0000,0x9234);
+ testu(0x8000,0x1234);
+ testu(0x1234,0x8000);
+ testu(0x9234,0x0000);
testu(0x7fff,0xedcb);
testu(0xffff,0x6dcb);
#endif
diff --git a/gcc/testsuite/gcc.c-torture/execute/20040423-1.c b/gcc/testsuite/gcc.c-torture/execute/20040423-1.c
new file mode 100644
index 00000000000..ace797e79d3
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20040423-1.c
@@ -0,0 +1,30 @@
+int
+sub1 (int i, int j)
+{
+ typedef struct
+ {
+ int c[i+2];
+ }c;
+ int x[10], y[10];
+
+ if (j == 2)
+ {
+ memcpy (x, y, 10 * sizeof (int));
+ return sizeof (c);
+ }
+ else
+ return sizeof (c) * 3;
+}
+
+int
+main ()
+{
+ typedef struct
+ {
+ int c[22];
+ }c;
+ if (sub1 (20, 3) != sizeof (c)*3)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/930529-1.x b/gcc/testsuite/gcc.c-torture/execute/930529-1.x
index a44f482c22f..fb86979f7c1 100644
--- a/gcc/testsuite/gcc.c-torture/execute/930529-1.x
+++ b/gcc/testsuite/gcc.c-torture/execute/930529-1.x
@@ -4,15 +4,20 @@
# The problem is that the multiplication was unsigned SImode, and the
# induction variable is DImode, and we lose the truncation that
# should have happened.
+#
+# On tree-ssa branch, the loop problem is still extant, but the
+# gimple-level optimization makes it easy for the tree-rtl expanders
+# to see that the comparisons are always true, and so the loop code
+# is never exercized.
-set torture_eval_before_execute {
-
- set compiler_conditional_xfail_data {
- "division by a constant conflicts with strength reduction" \
- "alpha*-*-*" \
- { "-O3" } \
- { "" }
- }
-}
+# set torture_eval_before_execute {
+#
+# set compiler_conditional_xfail_data {
+# "division by a constant conflicts with strength reduction" \
+# "alpha*-*-*" \
+# { "-O3" } \
+# { "" }
+# }
+# }
return 0
diff --git a/gcc/testsuite/gcc.c-torture/execute/divcmp-1.c b/gcc/testsuite/gcc.c-torture/execute/divcmp-1.c
new file mode 100644
index 00000000000..0a7f305aa7c
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/divcmp-1.c
@@ -0,0 +1,356 @@
+extern void abort(void);
+
+int test1(int x)
+{
+ return x/10 == 2;
+}
+
+int test1u(unsigned int x)
+{
+ return x/10U == 2;
+}
+
+int test2(int x)
+{
+ return x/10 == 0;
+}
+
+int test2u(unsigned int x)
+{
+ return x/10U == 0;
+}
+
+int test3(int x)
+{
+ return x/10 != 2;
+}
+
+int test3u(unsigned int x)
+{
+ return x/10U != 2;
+}
+
+int test4(int x)
+{
+ return x/10 != 0;
+}
+
+int test4u(unsigned int x)
+{
+ return x/10U != 0;
+}
+
+int test5(int x)
+{
+ return x/10 < 2;
+}
+
+int test5u(unsigned int x)
+{
+ return x/10U < 2;
+}
+
+int test6(int x)
+{
+ return x/10 < 0;
+}
+
+int test7(int x)
+{
+ return x/10 <= 2;
+}
+
+int test7u(unsigned int x)
+{
+ return x/10U <= 2;
+}
+
+int test8(int x)
+{
+ return x/10 <= 0;
+}
+
+int test8u(unsigned int x)
+{
+ return x/10U <= 0;
+}
+
+int test9(int x)
+{
+ return x/10 > 2;
+}
+
+int test9u(unsigned int x)
+{
+ return x/10U > 2;
+}
+
+int test10(int x)
+{
+ return x/10 > 0;
+}
+
+int test10u(unsigned int x)
+{
+ return x/10U > 0;
+}
+
+int test11(int x)
+{
+ return x/10 >= 2;
+}
+
+int test11u(unsigned int x)
+{
+ return x/10U >= 2;
+}
+
+int test12(int x)
+{
+ return x/10 >= 0;
+}
+
+
+int main()
+{
+ if (test1(19) != 0)
+ abort ();
+ if (test1(20) != 1)
+ abort ();
+ if (test1(29) != 1)
+ abort ();
+ if (test1(30) != 0)
+ abort ();
+
+ if (test1u(19) != 0)
+ abort ();
+ if (test1u(20) != 1)
+ abort ();
+ if (test1u(29) != 1)
+ abort ();
+ if (test1u(30) != 0)
+ abort ();
+
+ if (test2(0) != 1)
+ abort ();
+ if (test2(9) != 1)
+ abort ();
+ if (test2(10) != 0)
+ abort ();
+ if (test2(-1) != 1)
+ abort ();
+ if (test2(-9) != 1)
+ abort ();
+ if (test2(-10) != 0)
+ abort ();
+
+ if (test2u(0) != 1)
+ abort ();
+ if (test2u(9) != 1)
+ abort ();
+ if (test2u(10) != 0)
+ abort ();
+ if (test2u(-1) != 0)
+ abort ();
+ if (test2u(-9) != 0)
+ abort ();
+ if (test2u(-10) != 0)
+ abort ();
+
+ if (test3(19) != 1)
+ abort ();
+ if (test3(20) != 0)
+ abort ();
+ if (test3(29) != 0)
+ abort ();
+ if (test3(30) != 1)
+ abort ();
+
+ if (test3u(19) != 1)
+ abort ();
+ if (test3u(20) != 0)
+ abort ();
+ if (test3u(29) != 0)
+ abort ();
+ if (test3u(30) != 1)
+ abort ();
+
+ if (test4(0) != 0)
+ abort ();
+ if (test4(9) != 0)
+ abort ();
+ if (test4(10) != 1)
+ abort ();
+ if (test4(-1) != 0)
+ abort ();
+ if (test4(-9) != 0)
+ abort ();
+ if (test4(-10) != 1)
+ abort ();
+
+ if (test4u(0) != 0)
+ abort ();
+ if (test4u(9) != 0)
+ abort ();
+ if (test4u(10) != 1)
+ abort ();
+ if (test4u(-1) != 1)
+ abort ();
+ if (test4u(-9) != 1)
+ abort ();
+ if (test4u(-10) != 1)
+ abort ();
+
+ if (test5(19) != 1)
+ abort ();
+ if (test5(20) != 0)
+ abort ();
+ if (test5(29) != 0)
+ abort ();
+ if (test5(30) != 0)
+ abort ();
+
+ if (test5u(19) != 1)
+ abort ();
+ if (test5u(20) != 0)
+ abort ();
+ if (test5u(29) != 0)
+ abort ();
+ if (test5u(30) != 0)
+ abort ();
+
+ if (test6(0) != 0)
+ abort ();
+ if (test6(9) != 0)
+ abort ();
+ if (test6(10) != 0)
+ abort ();
+ if (test6(-1) != 0)
+ abort ();
+ if (test6(-9) != 0)
+ abort ();
+ if (test6(-10) != 1)
+ abort ();
+
+ if (test7(19) != 1)
+ abort ();
+ if (test7(20) != 1)
+ abort ();
+ if (test7(29) != 1)
+ abort ();
+ if (test7(30) != 0)
+ abort ();
+
+ if (test7u(19) != 1)
+ abort ();
+ if (test7u(20) != 1)
+ abort ();
+ if (test7u(29) != 1)
+ abort ();
+ if (test7u(30) != 0)
+ abort ();
+
+ if (test8(0) != 1)
+ abort ();
+ if (test8(9) != 1)
+ abort ();
+ if (test8(10) != 0)
+ abort ();
+ if (test8(-1) != 1)
+ abort ();
+ if (test8(-9) != 1)
+ abort ();
+ if (test8(-10) != 1)
+ abort ();
+
+ if (test8u(0) != 1)
+ abort ();
+ if (test8u(9) != 1)
+ abort ();
+ if (test8u(10) != 0)
+ abort ();
+ if (test8u(-1) != 0)
+ abort ();
+ if (test8u(-9) != 0)
+ abort ();
+ if (test8u(-10) != 0)
+ abort ();
+
+ if (test9(19) != 0)
+ abort ();
+ if (test9(20) != 0)
+ abort ();
+ if (test9(29) != 0)
+ abort ();
+ if (test9(30) != 1)
+ abort ();
+
+ if (test9u(19) != 0)
+ abort ();
+ if (test9u(20) != 0)
+ abort ();
+ if (test9u(29) != 0)
+ abort ();
+ if (test9u(30) != 1)
+ abort ();
+
+ if (test10(0) != 0)
+ abort ();
+ if (test10(9) != 0)
+ abort ();
+ if (test10(10) != 1)
+ abort ();
+ if (test10(-1) != 0)
+ abort ();
+ if (test10(-9) != 0)
+ abort ();
+ if (test10(-10) != 0)
+ abort ();
+
+ if (test10u(0) != 0)
+ abort ();
+ if (test10u(9) != 0)
+ abort ();
+ if (test10u(10) != 1)
+ abort ();
+ if (test10u(-1) != 1)
+ abort ();
+ if (test10u(-9) != 1)
+ abort ();
+ if (test10u(-10) != 1)
+ abort ();
+
+ if (test11(19) != 0)
+ abort ();
+ if (test11(20) != 1)
+ abort ();
+ if (test11(29) != 1)
+ abort ();
+ if (test11(30) != 1)
+ abort ();
+
+ if (test11u(19) != 0)
+ abort ();
+ if (test11u(20) != 1)
+ abort ();
+ if (test11u(29) != 1)
+ abort ();
+ if (test11u(30) != 1)
+ abort ();
+
+ if (test12(0) != 1)
+ abort ();
+ if (test12(9) != 1)
+ abort ();
+ if (test12(10) != 1)
+ abort ();
+ if (test12(-1) != 1)
+ abort ();
+ if (test12(-9) != 1)
+ abort ();
+ if (test12(-10) != 0)
+ abort ();
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/divcmp-2.c b/gcc/testsuite/gcc.c-torture/execute/divcmp-2.c
new file mode 100644
index 00000000000..b059b8fbaec
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/divcmp-2.c
@@ -0,0 +1,92 @@
+extern void abort (void);
+
+int test1(int x)
+{
+ return x/10 == 2;
+}
+
+int test2(int x)
+{
+ return x/10 == 0;
+}
+
+int test3(int x)
+{
+ return x/10 == -2;
+}
+
+int test4(int x)
+{
+ return x/-10 == 2;
+}
+
+int test5(int x)
+{
+ return x/-10 == 0;
+}
+
+int test6(int x)
+{
+ return x/-10 == -2;
+}
+
+
+int main()
+{
+ if (test1(19) != 0)
+ abort ();
+ if (test1(20) != 1)
+ abort ();
+ if (test1(29) != 1)
+ abort ();
+ if (test1(30) != 0)
+ abort ();
+
+ if (test2(-10) != 0)
+ abort ();
+ if (test2(-9) != 1)
+ abort ();
+ if (test2(9) != 1)
+ abort ();
+ if (test2(10) != 0)
+ abort ();
+
+ if (test3(-30) != 0)
+ abort ();
+ if (test3(-29) != 1)
+ abort ();
+ if (test3(-20) != 1)
+ abort ();
+ if (test3(-19) != 0)
+ abort ();
+
+ if (test4(-30) != 0)
+ abort ();
+ if (test4(-29) != 1)
+ abort ();
+ if (test4(-20) != 1)
+ abort ();
+ if (test4(-19) != 0)
+ abort ();
+
+ if (test5(-10) != 0)
+ abort ();
+ if (test5(-9) != 1)
+ abort ();
+ if (test5(9) != 1)
+ abort ();
+ if (test5(10) != 0)
+ abort ();
+
+ if (test6(19) != 0)
+ abort ();
+ if (test6(20) != 1)
+ abort ();
+ if (test6(29) != 1)
+ abort ();
+ if (test6(30) != 0)
+ abort ();
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/divcmp-3.c b/gcc/testsuite/gcc.c-torture/execute/divcmp-3.c
new file mode 100644
index 00000000000..ba52c9e2414
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/divcmp-3.c
@@ -0,0 +1,97 @@
+extern void abort(void);
+
+int test1(char x)
+{
+ return x/100 == 3;
+}
+
+int test1u(unsigned char x)
+{
+ return x/100 == 3;
+}
+
+int test2(char x)
+{
+ return x/100 != 3;
+}
+
+int test2u(unsigned char x)
+{
+ return x/100 != 3;
+}
+
+int test3(char x)
+{
+ return x/100 < 3;
+}
+
+int test3u(unsigned char x)
+{
+ return x/100 < 3;
+}
+
+int test4(char x)
+{
+ return x/100 <= 3;
+}
+
+int test4u(unsigned char x)
+{
+ return x/100 <= 3;
+}
+
+int test5(char x)
+{
+ return x/100 > 3;
+}
+
+int test5u(unsigned char x)
+{
+ return x/100 > 3;
+}
+
+int test6(char x)
+{
+ return x/100 >= 3;
+}
+
+int test6u(unsigned char x)
+{
+ return x/100 >= 3;
+}
+
+
+int main()
+{
+ int c;
+
+ for (c=-128; c<256; c++)
+ {
+ if (test1(c) != 0)
+ abort ();
+ if (test1u(c) != 0)
+ abort ();
+ if (test2(c) != 1)
+ abort ();
+ if (test2u(c) != 1)
+ abort ();
+ if (test3(c) != 1)
+ abort ();
+ if (test3u(c) != 1)
+ abort ();
+ if (test4(c) != 1)
+ abort ();
+ if (test4u(c) != 1)
+ abort ();
+ if (test5(c) != 0)
+ abort ();
+ if (test5u(c) != 0)
+ abort ();
+ if (test6(c) != 0)
+ abort ();
+ if (test6u(c) != 0)
+ abort ();
+ }
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr15296.c b/gcc/testsuite/gcc.c-torture/execute/pr15296.c
new file mode 100644
index 00000000000..d2468e425af
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr15296.c
@@ -0,0 +1,73 @@
+/* PR optimization/15296. The delayed-branch scheduler caused code that
+ SEGV:d for CRIS; a register was set to -1 in a delay-slot for the
+ fall-through code, while that register held a pointer used in code at
+ the branch target. */
+
+typedef int __attribute__ ((mode (__pointer__))) intptr_t;
+typedef intptr_t W;
+union u0
+{
+ union u0 *r;
+ W i;
+};
+struct s1
+{
+ union u0 **m0;
+ union u0 m1[4];
+};
+
+void f (void *, struct s1 *, const union u0 *, W, W, W)
+ __attribute__ ((__noinline__));
+void g (void *, char *) __attribute__ ((__noinline__));
+
+void
+f (void *a, struct s1 *b, const union u0 *h, W v0, W v1, W v4)
+{
+ union u0 *e = 0;
+ union u0 *k = 0;
+ union u0 **v5 = b->m0;
+ union u0 *c = b->m1;
+ union u0 **d = &v5[0];
+l0:;
+ if (v0 < v1)
+ goto l0;
+ if (v0 == 0)
+ goto l3;
+ v0 = v4;
+ if (v0 != 0)
+ goto l3;
+ c[0].r = *d;
+ v1 = -1;
+ e = c[0].r;
+ if (e != 0)
+ g (a, "");
+ k = e + 3;
+ k->i = v1;
+ goto l4;
+l3:;
+ c[0].i = v0;
+ e = c[1].r;
+ if (e != 0)
+ g (a, "");
+ e = c[0].r;
+ if (e == 0)
+ g (a, "");
+ k = e + 2;
+ k->r = c[1].r;
+l4:;
+}
+
+void g (void *a, char *b) { abort (); }
+
+int
+main ()
+{
+ union u0 uv[] = {{ .i = 111 }, { .i = 222 }, { .i = 333 }, { .i = 444 }};
+ struct s1 s = { 0, {{ .i = 555 }, { .i = 0 }, { .i = 999 }, { .i = 777 }}};
+ f (0, &s, 0, 20000, 10000, (W) uv);
+ if (s.m1[0].i != (W) uv || s.m1[1].i != 0 || s.m1[2].i != 999
+ || s.m1[3].i != 777 || uv[0].i != 111 || uv[1].i != 222
+ || uv[2].i != 0 || uv[3].i != 444)
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/simd-5.c b/gcc/testsuite/gcc.c-torture/execute/simd-5.c
new file mode 100644
index 00000000000..f0584328716
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/simd-5.c
@@ -0,0 +1,59 @@
+/* Test saving and restoring of SIMD registers. */
+
+typedef short Q __attribute__((vector_size(8)));
+
+Q q1 = {1, 2}, q2 = {3, 4}, q3 = {5, 6}, q4 = {7, 8};
+
+Q w1, w2, w3, w4;
+Q z1, z2, z3, z4;
+
+volatile int dummy;
+
+void __attribute__((__noinline__))
+func0 (void)
+{
+ dummy = 1;
+}
+
+void __attribute__((__noinline__))
+func1 (void)
+{
+ Q a, b;
+ a = q1 * q2;
+ b = q3 * q4;
+ w1 = a;
+ w2 = b;
+ func0 ();
+ w3 = a;
+ w4 = b;
+}
+
+void __attribute__((__noinline__))
+func2 (void)
+{
+ Q a, b;
+ a = q1 + q2;
+ b = q3 - q4;
+ z1 = a;
+ z2 = b;
+ func1 ();
+ z3 = a;
+ z4 = b;
+}
+
+int
+main (void)
+{
+ func2 ();
+
+ if (memcmp (&w1, &w3, sizeof (Q)) != 0)
+ abort ();
+ if (memcmp (&w2, &w4, sizeof (Q)) != 0)
+ abort ();
+ if (memcmp (&z1, &z3, sizeof (Q)) != 0)
+ abort ();
+ if (memcmp (&z2, &z4, sizeof (Q)) != 0)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/va-arg-24.c b/gcc/testsuite/gcc.c-torture/execute/va-arg-24.c
new file mode 100644
index 00000000000..811b11f31b7
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/va-arg-24.c
@@ -0,0 +1,96 @@
+/* The purpose of this code is to test argument passing of a tuple of
+ 11 integers, with the break point between named and unnamed arguments
+ at every possible position. */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static int errors = 0;
+
+static void
+verify (const char *tcase, int n[11])
+{
+ int i;
+ for (i = 0; i <= 10; i++)
+ if (n[i] != i)
+ {
+ printf (" %s: n[%d] = %d expected %d\n", tcase, i, n[i], i);
+ errors++;
+ }
+}
+
+#define STR(x) #x
+
+#define p(i) int q##i,
+#define P(i) n[i] = q##i;
+
+#define p0 p(0)
+#define p1 p(1)
+#define p2 p(2)
+#define p3 p(3)
+#define p4 p(4)
+#define p5 p(5)
+#define p6 p(6)
+#define p7 p(7)
+#define p8 p(8)
+#define p9 p(9)
+
+#define P0 P(0)
+#define P1 P(1)
+#define P2 P(2)
+#define P3 P(3)
+#define P4 P(4)
+#define P5 P(5)
+#define P6 P(6)
+#define P7 P(7)
+#define P8 P(8)
+#define P9 P(9)
+
+#define TCASE(x, params, vecinit) \
+static void \
+varargs##x (params ...) \
+{ \
+ va_list ap; \
+ int n[11]; \
+ int i; \
+ \
+ va_start (ap, q##x); \
+ vecinit \
+ for (i = x + 1; i <= 10; i++) \
+ n[i] = va_arg (ap, int); \
+ va_end (ap); \
+ \
+ verify (STR(varargs##x), n); \
+}
+
+#define TEST(x) varargs##x (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+
+TCASE(0, p0 , P0 )
+TCASE(1, p0 p1 , P0 P1 )
+TCASE(2, p0 p1 p2 , P0 P1 P2 )
+TCASE(3, p0 p1 p2 p3 , P0 P1 P2 P3 )
+TCASE(4, p0 p1 p2 p3 p4 , P0 P1 P2 P3 P4 )
+TCASE(5, p0 p1 p2 p3 p4 p5 , P0 P1 P2 P3 P4 P5 )
+TCASE(6, p0 p1 p2 p3 p4 p5 p6 , P0 P1 P2 P3 P4 P5 P6 )
+TCASE(7, p0 p1 p2 p3 p4 p5 p6 p7 , P0 P1 P2 P3 P4 P5 P6 P7 )
+TCASE(8, p0 p1 p2 p3 p4 p5 p6 p7 p8 , P0 P1 P2 P3 P4 P5 P6 P7 P8 )
+TCASE(9, p0 p1 p2 p3 p4 p5 p6 p7 p8 p9, P0 P1 P2 P3 P4 P5 P6 P7 P8 P9)
+
+int main(void)
+{
+ TEST(0);
+ TEST(1);
+ TEST(2);
+ TEST(3);
+ TEST(4);
+ TEST(5);
+ TEST(6);
+ TEST(7);
+ TEST(8);
+ TEST(9);
+
+ if (errors)
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/20010516-1.c b/gcc/testsuite/gcc.dg/20010516-1.c
new file mode 100644
index 00000000000..e9b419f1a68
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/20010516-1.c
@@ -0,0 +1,5 @@
+foo()
+{
+ char d;
+ __asm volatile ( "" :: "m"(&d)); /* { dg-error "" "non-lvalue" } */
+}
diff --git a/gcc/testsuite/gcc.dg/20030612-1.c b/gcc/testsuite/gcc.dg/20030612-1.c
index f9f212caba1..5ecc4c1da89 100644
--- a/gcc/testsuite/gcc.dg/20030612-1.c
+++ b/gcc/testsuite/gcc.dg/20030612-1.c
@@ -1,20 +1,22 @@
-/* Derived from PR middle-end/168. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
-/* { dg-do compile } */
-/* { dg-options "-W" } */
+int A, B;
-extern void foo ();
-
-unsigned char uc;
-unsigned short int usi;
-unsigned int ui;
-
-
-void bar()
+void foo()
{
- if (uc + usi >= ui) /* { dg-bogus "between signed and unsigned" } */
- foo ();
- if (uc * usi >= ui) /* { dg-bogus "between signed and unsigned" } */
- foo ();
+ long x = 3;
+ (void)({
+ A = B + x + ((1) - 1);
+ return; /* { dg-warning "statement-expressions should end with a non-void expression" } */
+ });
}
+main()
+{
+ B = 5;
+ foo();
+ if (A != 8)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/20030805-1.c b/gcc/testsuite/gcc.dg/20030805-1.c
new file mode 100644
index 00000000000..6297c5d83ea
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/20030805-1.c
@@ -0,0 +1,23 @@
+/* Test that gcc understands that the call to g might clobber i. */
+
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+__inline int f ()
+{
+ static int i;
+ int i2 = i;
+ i = i2 + 1;
+ return i;
+}
+
+int g () { return f (); }
+
+int main ()
+{
+ if (f() != 1
+ || g() != 2
+ || f() != 3)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/20040202-1.c b/gcc/testsuite/gcc.dg/20040202-1.c
new file mode 100644
index 00000000000..f0f4e74109a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/20040202-1.c
@@ -0,0 +1,8 @@
+/* PR middle-end/13325 */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+void *memcpy(void *dest, const void *src, __SIZE_TYPE__ n);
+void f (void *dest, const void *src) {
+ memcpy (dest, src, 0);
+}
diff --git a/gcc/testsuite/gcc.dg/20040206-1.c b/gcc/testsuite/gcc.dg/20040206-1.c
new file mode 100644
index 00000000000..7fc4b0d7605
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/20040206-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -W -Wall" } */
+/* PR c/13127
+ On the tree-ssa this used to warn about an anonymous
+ uninitialized variable.
+
+ The warning about "no return statement in function
+ returning non-void" is PR 13000. */
+
+static int foo (int a __attribute__((unused)) ) { } /* { dg-warning "return" "" { xfail *-*-* } } */
+int main (void) { return foo (0); }
diff --git a/gcc/testsuite/gcc.dg/Wswitch-2.c b/gcc/testsuite/gcc.dg/Wswitch-2.c
index b151e2310c7..9bc7d022b46 100644
--- a/gcc/testsuite/gcc.dg/Wswitch-2.c
+++ b/gcc/testsuite/gcc.dg/Wswitch-2.c
@@ -13,19 +13,19 @@ foo (enum e ei, int j)
case e3: return 2;
case e4: return 3;
} /* No warning here since e2 has the same value as e3. */
- switch (ei)
+ switch (ei) /* { dg-warning "enumeration value `e4' not handled in switch" "enum e4" } */
{
case e1: return 1;
case e2: return 2;
- } /* { dg-warning "enumeration value `e4' not handled in switch" "enum e4" } */
+ }
switch ((int) ei)
{
case e1: return 1;
} /* No warning here since switch condition was cast to int. */
- switch ((enum e) j)
+ switch ((enum e) j) /* { dg-warning "enumeration value `e1' not handled in switch" "enum e1" } */
{
case e2: return 1;
case e4: return 2;
- } /* { dg-warning "enumeration value `e1' not handled in switch" "enum e1" } */
+ }
return 0;
}
diff --git a/gcc/testsuite/gcc.dg/Wswitch-default.c b/gcc/testsuite/gcc.dg/Wswitch-default.c
index a1a3d39c1d9..2d4e7994c25 100644
--- a/gcc/testsuite/gcc.dg/Wswitch-default.c
+++ b/gcc/testsuite/gcc.dg/Wswitch-default.c
@@ -7,11 +7,11 @@ int
foo (int i, int j, enum e ei, enum e ej, enum e ek, enum e el,
enum e em, enum e en, enum e eo, enum e ep)
{
- switch (i)
+ switch (i) /* { dg-warning "switch missing default case" } */
{
case 1: return 1;
case 2: return 2;
- } /* { dg-warning "switch missing default case" } */
+ }
switch (j)
{
case 3: return 4;
@@ -25,32 +25,32 @@ foo (int i, int j, enum e ei, enum e ej, enum e ek, enum e el,
{
default: break;
}
- switch (ek)
+ switch (ek) /* { dg-warning "switch missing default case" } */
{
case e1: return 1;
- } /* { dg-warning "switch missing default case" } */
+ }
switch (el)
{
case e1: return 1;
default: break;
}
- switch (em)
+ switch (em) /* { dg-warning "switch missing default case" } */
{
case e1: return 1;
case e2: return 2;
- } /* { dg-warning "switch missing default case" } */
+ }
switch (en)
{
case e1: return 1;
case e2: return 2;
default: break;
}
- switch (eo)
+ switch (eo) /* { dg-warning "switch missing default case" } */
{
case e1: return 1;
case e2: return 2;
case 3: return 3;
- } /* { dg-warning "switch missing default case" } */
+ }
switch (ep)
{
case e1: return 1;
diff --git a/gcc/testsuite/gcc.dg/Wswitch-enum.c b/gcc/testsuite/gcc.dg/Wswitch-enum.c
index d031b12ce14..b51ecfdcc9e 100644
--- a/gcc/testsuite/gcc.dg/Wswitch-enum.c
+++ b/gcc/testsuite/gcc.dg/Wswitch-enum.c
@@ -22,19 +22,19 @@ foo (int i, int j, enum e ei, enum e ej, enum e ek, enum e el,
switch (ei) /* { dg-warning "enumeration value `e1' not handled in switch" "enum e1" } */
{ /* { dg-warning "enumeration value `e2' not handled in switch" "enum e2" { target *-*-* } 22 } */
}
- switch (ej)
- { /* { dg-warning "enumeration value `e1' not handled in switch" "enum e1" { target *-*-* } 28 } */
+ switch (ej) /* { dg-warning "enumeration value `e1' not handled in switch" "enum e1" } */
+ { /* { dg-warning "enumeration value `e2' not handled in switch" "enum e2" { target *-*-* } 25 } */
default: break;
- } /* { dg-warning "enumeration value `e2' not handled in switch" "enum e2" } */
- switch (ek)
+ }
+ switch (ek) /* { dg-warning "enumeration value `e2' not handled in switch" "enum e2" } */
{
case e1: return 1;
- } /* { dg-warning "enumeration value `e2' not handled in switch" "enum e2" } */
- switch (el)
+ }
+ switch (el) /* { dg-warning "enumeration value `e2' not handled in switch" "enum e2" } */
{
case e1: return 1;
default: break;
- } /* { dg-warning "enumeration value `e2' not handled in switch" "enum e2" } */
+ }
switch (em)
{
case e1: return 1;
@@ -50,14 +50,14 @@ foo (int i, int j, enum e ei, enum e ej, enum e ek, enum e el,
{
case e1: return 1;
case e2: return 2;
- case 3: return 3;
- } /* { dg-warning "case value `3' not in enumerated type `e'" "excess 3" } */
+ case 3: return 3; /* { dg-warning "case value `3' not in enumerated type `e'" "excess 3" } */
+ }
switch (ep)
{
case e1: return 1;
case e2: return 2;
- case 3: return 3;
+ case 3: return 3; /* { dg-warning "case value `3' not in enumerated type `e'" "excess 3" } */
default: break;
- } /* { dg-warning "case value `3' not in enumerated type `e'" "excess 3" } */
+ }
return 0;
}
diff --git a/gcc/testsuite/gcc.dg/Wswitch.c b/gcc/testsuite/gcc.dg/Wswitch.c
index 38c3cbbb446..e3deeab0f4b 100644
--- a/gcc/testsuite/gcc.dg/Wswitch.c
+++ b/gcc/testsuite/gcc.dg/Wswitch.c
@@ -26,10 +26,10 @@ foo (int i, int j, enum e ei, enum e ej, enum e ek, enum e el,
{
default: break;
}
- switch (ek)
+ switch (ek) /* { dg-warning "enumeration value `e2' not handled in switch" "enum e2" } */
{
case e1: return 1;
- } /* { dg-warning "enumeration value `e2' not handled in switch" "enum e2" } */
+ }
switch (el)
{
case e1: return 1;
@@ -50,8 +50,8 @@ foo (int i, int j, enum e ei, enum e ej, enum e ek, enum e el,
{
case e1: return 1;
case e2: return 2;
- case 3: return 3;
- } /* { dg-warning "case value `3' not in enumerated type `e'" "excess 3" } */
+ case 3: return 3; /* { dg-warning "case value `3' not in enumerated type `e'" "excess 3" } */
+ }
switch (ep)
{
case e1: return 1;
diff --git a/gcc/testsuite/gcc.dg/altivec-1.c b/gcc/testsuite/gcc.dg/altivec-1.c
index 59654bee2c9..158a91eb974 100644
--- a/gcc/testsuite/gcc.dg/altivec-1.c
+++ b/gcc/testsuite/gcc.dg/altivec-1.c
@@ -1,4 +1,5 @@
/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-xfail-if "" { "powerpc-*-eabispe*" } { "-maltivec" } { "" } } */
/* { dg-options "-maltivec" } */
/* Program to test PowerPC AltiVec instructions. */
diff --git a/gcc/testsuite/gcc.dg/altivec-13.c b/gcc/testsuite/gcc.dg/altivec-13.c
new file mode 100644
index 00000000000..c377442196b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/altivec-13.c
@@ -0,0 +1,20 @@
+/* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-options "-maltivec" } */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+
+/* This test case exercises intrinsic/argument combinations that,
+ while not in the Motorola AltiVec PIM, have nevertheless crept
+ into the AltiVec vernacular over the years. */
+
+#include <altivec.h>
+
+void foo (void)
+{
+ vector bool int boolVec1 = (vector bool int) vec_splat_u32(3);
+ vector bool short boolVec2 = (vector bool short) vec_splat_u16(3);
+ vector bool char boolVec3 = (vector bool char) vec_splat_u8(3);
+
+ boolVec1 = vec_sld( boolVec1, boolVec1, 4 );
+ boolVec2 = vec_sld( boolVec2, boolVec2, 2 );
+ boolVec3 = vec_sld( boolVec3, boolVec3, 1 );
+}
diff --git a/gcc/testsuite/gcc.dg/altivec-3.c b/gcc/testsuite/gcc.dg/altivec-3.c
index 91fa8f296b9..d442b229e5b 100644
--- a/gcc/testsuite/gcc.dg/altivec-3.c
+++ b/gcc/testsuite/gcc.dg/altivec-3.c
@@ -1,4 +1,5 @@
/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-xfail-if "" { "powerpc-*-eabispe*" } { "-maltivec" } { "" } } */
/* { dg-options "-maltivec" } */
#include "altivec_check.h"
diff --git a/gcc/testsuite/gcc.dg/altivec-varargs-1.c b/gcc/testsuite/gcc.dg/altivec-varargs-1.c
index fd2b74f85e2..31724e3c023 100644
--- a/gcc/testsuite/gcc.dg/altivec-varargs-1.c
+++ b/gcc/testsuite/gcc.dg/altivec-varargs-1.c
@@ -1,4 +1,5 @@
/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-xfail-if "" { "powerpc-*-eabispe*" } { "-maltivec" } { "" } } */
/* { dg-options "-maltivec -mabi=altivec -fno-inline" } */
#include <stdarg.h>
diff --git a/gcc/testsuite/gcc.dg/asm-7.c b/gcc/testsuite/gcc.dg/asm-7.c
index 42f40e719f9..a14bb807369 100644
--- a/gcc/testsuite/gcc.dg/asm-7.c
+++ b/gcc/testsuite/gcc.dg/asm-7.c
@@ -12,8 +12,8 @@ void test(void)
__asm__ ("" : : "m"(r)); /* { dg-warning "address of register" } */
__asm__ ("" : : "m"(i));
__asm__ ("" : : "m"(m));
- __asm__ ("" : : "m"(0)); /* { dg-warning "input without lvalue" } */
- __asm__ ("" : : "m"(i+1)); /* { dg-warning "input without lvalue" } */
+ __asm__ ("" : : "m"(0)); /* { dg-error "" } */
+ __asm__ ("" : : "m"(i+1)); /* { dg-error "" } */
__asm__ ("" : : "m"(*p++));
__asm__ ("" : : "g"(r));
diff --git a/gcc/testsuite/gcc.dg/builtins-33.c b/gcc/testsuite/gcc.dg/builtins-33.c
index 758978f0600..11393e30089 100644
--- a/gcc/testsuite/gcc.dg/builtins-33.c
+++ b/gcc/testsuite/gcc.dg/builtins-33.c
@@ -10,10 +10,13 @@
extern double log10(double);
extern double log2(double);
+extern double log1p(double);
extern float log10f(float);
extern float log2f(float);
+extern float log1pf(float);
extern long double log10l(long double);
extern long double log2l(long double);
+extern long double log1pl(long double);
double test1(double x)
@@ -26,6 +29,11 @@ double test2(double x)
return log2(x);
}
+double test3(double x)
+{
+ return log1p(x);
+}
+
float test1f(float x)
{
return log10f(x);
@@ -36,6 +44,11 @@ float test2f(float x)
return log2f(x);
}
+float test3f(float x)
+{
+ return log1pf(x);
+}
+
long double test1l(long double x)
{
return log10l(x);
@@ -46,3 +59,7 @@ long double test2l(long double x)
return log2l(x);
}
+long double test3l(long double x)
+{
+ return log1pl(x);
+}
diff --git a/gcc/testsuite/gcc.dg/builtins-34.c b/gcc/testsuite/gcc.dg/builtins-34.c
index d2bf4d41219..0055f329dd5 100644
--- a/gcc/testsuite/gcc.dg/builtins-34.c
+++ b/gcc/testsuite/gcc.dg/builtins-34.c
@@ -1,7 +1,7 @@
/* Copyright (C) 2004 Free Software Foundation.
- Check that exp10, exp10f, exp10l, exp2, exp2f, exp2l, pow10, pow10f
- and pow10l built-in functions compile.
+ Check that exp10, exp10f, exp10l, exp2, exp2f, exp2l, pow10, pow10f,
+ pow10l, expm1, expm1f and expm1l built-in functions compile.
Written by Uros Bizjak, 13th February 2004. */
@@ -11,12 +11,15 @@
extern double exp10(double);
extern double exp2(double);
extern double pow10(double);
+extern double expm1(double);
extern float exp10f(float);
extern float exp2f(float);
extern float pow10f(float);
+extern float expm1f(float);
extern long double exp10l(long double);
extern long double exp2l(long double);
extern long double pow10l(long double);
+extern long double expm1l(long double);
double test1(double x)
@@ -34,6 +37,11 @@ double test3(double x)
return pow10(x);
}
+double test4(double x)
+{
+ return expm1(x);
+}
+
float test1f(float x)
{
return exp10f(x);
@@ -49,6 +57,11 @@ float test3f(float x)
return pow10f(x);
}
+float test4f(float x)
+{
+ return expm1f(x);
+}
+
long double test1l(long double x)
{
return exp10l(x);
@@ -64,3 +77,8 @@ long double test3l(long double x)
return pow10l(x);
}
+long double test4l(long double x)
+{
+ return expm1l(x);
+}
+
diff --git a/gcc/testsuite/gcc.dg/builtins-37.c b/gcc/testsuite/gcc.dg/builtins-37.c
new file mode 100644
index 00000000000..e366a6ac552
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtins-37.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 2004 Free Software Foundation.
+
+ Check tan, tanf and tanl built-in functions.
+
+ Written by Uros Bizjak, 7th April 2004. */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -ffast-math" } */
+
+extern double tan(double);
+extern float tanf(float);
+extern long double tanl(long double);
+
+
+double test1(double x)
+{
+ return tan(x);
+}
+
+float test1f(float x)
+{
+ return tanf(x);
+}
+
+long double test1l(long double x)
+{
+ return tanl(x);
+}
+
diff --git a/gcc/testsuite/gcc.dg/builtins-38.c b/gcc/testsuite/gcc.dg/builtins-38.c
new file mode 100644
index 00000000000..210516bb7dc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtins-38.c
@@ -0,0 +1,48 @@
+/* Copyright (C) 2004 Free Software Foundation.
+
+ Check that logb, logbf, logbl, ilogb, ilogbf and ilogbl
+ built-in functions compile.
+
+ Written by Uros Bizjak, 14th April 2004. */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -ffast-math" } */
+
+extern double logb(double);
+extern float logbf(float);
+extern long double logbl(long double);
+extern int ilogb(double);
+extern int ilogbf(float);
+extern int ilogbl(long double);
+
+
+double test1(double x)
+{
+ return logb(x);
+}
+
+float test1f(float x)
+{
+ return logbf(x);
+}
+
+long double test1l(long double x)
+{
+ return logbl(x);
+}
+
+int test2(double x)
+{
+ return ilogb(x);
+}
+
+int test2f(float x)
+{
+ return ilogbf(x);
+}
+
+int test2l(long double x)
+{
+ return ilogbl(x);
+}
+
diff --git a/gcc/testsuite/gcc.dg/builtins-39.c b/gcc/testsuite/gcc.dg/builtins-39.c
new file mode 100644
index 00000000000..6359be2b30e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtins-39.c
@@ -0,0 +1,48 @@
+/* Copyright (C) 2004 Free Software Foundation.
+
+ Check that asin, asinf, asinl, acos, acosf
+ and acosl built-in functions compile.
+
+ Written by Uros Bizjak, 20th April 2004. */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -ffast-math" } */
+
+extern double asin(double);
+extern double acos(double);
+extern float asinf(float);
+extern float acosf(float);
+extern long double asinl(long double);
+extern long double acosl(long double);
+
+
+double test1(double x)
+{
+ return asin(x);
+}
+
+double test2(double x)
+{
+ return acos(x);
+}
+
+float test1f(float x)
+{
+ return asinf(x);
+}
+
+float test2f(float x)
+{
+ return acosf(x);
+}
+
+long double test1l(long double x)
+{
+ return asinl(x);
+}
+
+long double test2l(long double x)
+{
+ return acosl(x);
+}
+
diff --git a/gcc/testsuite/gcc.dg/builtins-40.c b/gcc/testsuite/gcc.dg/builtins-40.c
new file mode 100644
index 00000000000..405c8723309
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtins-40.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 2004 Free Software Foundation.
+
+ Check that fmod, fmodf, fmodl, drem, dremf and dreml
+ built-in functions compile.
+
+ Written by Uros Bizjak, 5th May 2004. */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -ffast-math" } */
+
+extern double fmod(double, double);
+extern double drem(double, double);
+extern float fmodf(float, float);
+extern float dremf(float, float);
+extern long double fmodl(long double, long double);
+extern long double dreml(long double, long double);
+
+
+double test1(double x, double y)
+{
+ return fmod(x, y);
+}
+
+double test2(double x, double y)
+{
+ return drem(x, y);
+}
+
+float test1f(float x, float y)
+{
+ return fmodf(x, y);
+}
+
+float test2f(float x, float y)
+{
+ return dremf(x, y);
+}
+
+long double test1l(long double x, long double y)
+{
+ return fmodl(x, y);
+}
+
+long double test2l(long double x, long double y)
+{
+ return dreml(x, y);
+}
diff --git a/gcc/testsuite/gcc.dg/charset/extern.c b/gcc/testsuite/gcc.dg/charset/extern.c
new file mode 100644
index 00000000000..5e46ca6facf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/charset/extern.c
@@ -0,0 +1,11 @@
+/* { dg-do compile }
+ { dg-require-iconv "IBM-1047" }
+ { dg-final { scan-assembler-not "abcdefghijklmnopqrstuvwxyz" } } */
+
+extern char *bar;
+
+extern void foo (void)
+{
+ char str[]="abcdefghijklmnopqrstuvwxyz";
+ bar = str;
+}
diff --git a/gcc/testsuite/gcc.dg/const-elim-1.c b/gcc/testsuite/gcc.dg/const-elim-1.c
index b68abfc917c..c623a2399c4 100644
--- a/gcc/testsuite/gcc.dg/const-elim-1.c
+++ b/gcc/testsuite/gcc.dg/const-elim-1.c
@@ -7,10 +7,13 @@
/* { dg-do compile } */
/* { dg-options "-O2 -std=c99" } */
-/* This test fails on ARM and Xtensa cores because we use a block move to
- initialize "S" in test2, and GCC is not clever enough to eliminate
- the block move. */
-/* { dg-final { scan-assembler-not "L\\\$?C\[^A-Z\]" { xfail arm-*-* strongarm-*-* xscale-*-* powerpc*-*-aix* xtensa-*-* } } } */
+/* This test fails on all processors where we use a block move to
+ initialize "S" in test2. The RTL optimizers are not clever enough
+ to eliminate the block move, so the constant gets emitted.
+ Currently known targets with this problem: all ARM; PA32 ("hppa*.*"
+ matches "hppa2.0w" but not "hppa64"); PPC if string instructions
+ are enabled (notably under AIX); S/390; Xtensa. */
+/* { dg-final { scan-assembler-not "L\\\$?C\[^A-Z\]" { xfail arm-*-* strongarm-*-* xscale-*-* hppa-*-* hppa*.*-*-* powerpc*-*-aix* s390*-*-* xtensa-*-* } } } */
#define I (__extension__ 1.0iF)
diff --git a/gcc/testsuite/gcc.dg/funcorder.c b/gcc/testsuite/gcc.dg/funcorder.c
index b064d1cc467..a3edc1272f9 100644
--- a/gcc/testsuite/gcc.dg/funcorder.c
+++ b/gcc/testsuite/gcc.dg/funcorder.c
@@ -1,8 +1,10 @@
/* { dg-do compile } */
/* { dg-options "-O2 -funit-at-a-time" } */
-/* { dg-final { if [ istarget hppa*-*-* ] { scan-assembler-not "link_error,%r" } else { scan-assembler-not "link_error" } } } */
+/* { dg-final { if [ istarget hppa*-*-* ] { scan-assembler-not "link_error,%r" { xfail hppa*64*-*-* } } else { scan-assembler-not "link_error" } } } */
/* In unit-at-time the functions should be assembled in order
- e q t main, so we realize that they are pure. */
+ e q t main, so we realize that they are pure. The test is
+ xfailed on hppa64 because variable r in q is sign extended
+ to 64-bits. As a result, "if (t!=mem)" is not simplified. */
static int mem;
static int e(void) __attribute__ ((noinline));
diff --git a/gcc/testsuite/gcc.dg/i386-387-1.c b/gcc/testsuite/gcc.dg/i386-387-1.c
index 74a76b63807..92b671bf99c 100644
--- a/gcc/testsuite/gcc.dg/i386-387-1.c
+++ b/gcc/testsuite/gcc.dg/i386-387-1.c
@@ -7,6 +7,8 @@
/* { dg-final { scan-assembler "call\t_?atan2" } } */
/* { dg-final { scan-assembler "call\t_?log" } } */
/* { dg-final { scan-assembler "call\t_?exp" } } */
+/* { dg-final { scan-assembler "call\t_?tan" } } */
+/* { dg-final { scan-assembler "call\t_?fmod" } } */
double f1(double x) { return __builtin_sin(x); }
double f2(double x) { return __builtin_cos(x); }
@@ -14,3 +16,5 @@ double f3(double x) { return __builtin_sqrt(x); }
double f4(double x, double y) { return __builtin_atan2(x,y); }
double f5(double x) { return __builtin_log(x); }
double f6(double x) { return __builtin_exp(x); }
+double f7(double x) { return __builtin_tan(x); }
+double f8(double x, double y) { return __builtin_fmod(x,y); }
diff --git a/gcc/testsuite/gcc.dg/i386-387-2.c b/gcc/testsuite/gcc.dg/i386-387-2.c
index bfda85bc171..11eb0cc9aa5 100644
--- a/gcc/testsuite/gcc.dg/i386-387-2.c
+++ b/gcc/testsuite/gcc.dg/i386-387-2.c
@@ -7,6 +7,8 @@
/* { dg-final { scan-assembler "fpatan" } } */
/* { dg-final { scan-assembler "fyl2x" } } */
/* { dg-final { scan-assembler "f2xm1" } } */
+/* { dg-final { scan-assembler "fptan" } } */
+/* { dg-final { scan-assembler "fprem" } } */
double f1(double x) { return __builtin_sin(x); }
double f2(double x) { return __builtin_cos(x); }
@@ -14,3 +16,5 @@ double f3(double x) { return __builtin_sqrt(x); }
double f4(double x, double y) { return __builtin_atan2(x,y); }
double f5(double x) { return __builtin_log(x); }
double f6(double x) { return __builtin_exp(x); }
+double f7(double x) { return __builtin_tan(x); }
+double f8(double x, double y) { return __builtin_fmod(x,y); }
diff --git a/gcc/testsuite/gcc.dg/i386-387-5.c b/gcc/testsuite/gcc.dg/i386-387-5.c
index 2c86dd0869a..7c512977420 100644
--- a/gcc/testsuite/gcc.dg/i386-387-5.c
+++ b/gcc/testsuite/gcc.dg/i386-387-5.c
@@ -2,6 +2,9 @@
/* { dg-do compile { target "i?86-*-*" } } */
/* { dg-options "-O -ffast-math -mfpmath=387 -mno-fancy-math-387 -march=i386" } */
/* { dg-final { scan-assembler "call\t_?atan" } } */
+/* { dg-final { scan-assembler "call\t_?log1p" } } */
+/* { dg-final { scan-assembler "call\t_?drem" } } */
double f1(double x) { return __builtin_atan(x); }
-
+double f2(double x) { return __builtin_log1p(x); }
+double f3(double x, double y) { return __builtin_drem(x,y); }
diff --git a/gcc/testsuite/gcc.dg/i386-387-6.c b/gcc/testsuite/gcc.dg/i386-387-6.c
index 8eb29a11320..c8e5311c091 100644
--- a/gcc/testsuite/gcc.dg/i386-387-6.c
+++ b/gcc/testsuite/gcc.dg/i386-387-6.c
@@ -2,5 +2,9 @@
/* { dg-do compile { target "i?86-*-*" } } */
/* { dg-options "-O -ffast-math -mfpmath=387 -march=i686 -mno-fancy-math-387" } */
/* { dg-final { scan-assembler "fpatan" } } */
+/* { dg-final { scan-assembler "fyl2xp1" } } */
+/* { dg-final { scan-assembler "fprem1" } } */
double f1(double x) { return __builtin_atan(x); }
+double f2(double x) { return __builtin_log1p(x); }
+double f3(double x, double y) { return __builtin_drem(x,y); }
diff --git a/gcc/testsuite/gcc.dg/i386-387-7.c b/gcc/testsuite/gcc.dg/i386-387-7.c
new file mode 100644
index 00000000000..43c916c61d0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/i386-387-7.c
@@ -0,0 +1,10 @@
+/* Verify that 387 fsincos instruction is generated. */
+/* { dg-do compile { target "i?86-*-*" } } */
+/* { dg-options "-O -ffast-math -march=i686" } */
+/* { dg-final { scan-assembler "fsincos" } } */
+
+double f1(double x)
+{
+ return sin(x) + cos (x);
+}
+
diff --git a/gcc/testsuite/gcc.dg/i386-387-8.c b/gcc/testsuite/gcc.dg/i386-387-8.c
new file mode 100644
index 00000000000..05787160b00
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/i386-387-8.c
@@ -0,0 +1,12 @@
+/* Verify that 387 fptan instruction is generated. Also check fptan
+ peephole2 optimizer. */
+/* { dg-do compile { target "i?86-*-*" } } */
+/* { dg-options "-O2 -ffast-math -march=i686" } */
+/* { dg-final { scan-assembler "fptan" } } */
+/* { dg-final { scan-assembler-not "fld1" } } */
+
+double f1(double x)
+{
+ return 1.0 / tan(x);
+}
+
diff --git a/gcc/testsuite/gcc.dg/i386-ssetype-1.c b/gcc/testsuite/gcc.dg/i386-ssetype-1.c
index 50d0fcaa58a..e4a099bb0b0 100644
--- a/gcc/testsuite/gcc.dg/i386-ssetype-1.c
+++ b/gcc/testsuite/gcc.dg/i386-ssetype-1.c
@@ -4,7 +4,8 @@
/* { dg-final { scan-assembler "andnpd\[^\\n\]*magic" } } */
/* { dg-final { scan-assembler "xorpd\[^\\n\]*magic" } } */
/* { dg-final { scan-assembler "orpd\[^\\n\]*magic" } } */
-/* { dg-final { scan-assembler-not "movdqa" } } */
+/* ??? All of the backend patters are WAY too fragile. */
+/* { dg-final { scan-assembler-not "movdqa" { xfail *-*-* } } } */
/* { dg-final { scan-assembler "movapd\[^\\n\]*magic" } } */
/* Verify that we generate proper instruction with memory operand. */
diff --git a/gcc/testsuite/gcc.dg/i386-ssetype-3.c b/gcc/testsuite/gcc.dg/i386-ssetype-3.c
index 3b2461be32c..f19f5e8b928 100644
--- a/gcc/testsuite/gcc.dg/i386-ssetype-3.c
+++ b/gcc/testsuite/gcc.dg/i386-ssetype-3.c
@@ -4,7 +4,8 @@
/* { dg-final { scan-assembler "andnps\[^\\n\]*magic" } } */
/* { dg-final { scan-assembler "xorps\[^\\n\]*magic" } } */
/* { dg-final { scan-assembler "orps\[^\\n\]*magic" } } */
-/* { dg-final { scan-assembler-not "movdqa" } } */
+/* ??? All of the backend patters are WAY too fragile. */
+/* { dg-final { scan-assembler-not "movdqa" { xfail *-*-* } } } */
/* { dg-final { scan-assembler "movaps\[^\\n\]*magic" } } */
/* Verify that we generate proper instruction with memory operand. */
diff --git a/gcc/testsuite/gcc.dg/local1.c b/gcc/testsuite/gcc.dg/local1.c
index 9d6fdb16752..e9f653bcc56 100644
--- a/gcc/testsuite/gcc.dg/local1.c
+++ b/gcc/testsuite/gcc.dg/local1.c
@@ -3,14 +3,14 @@
C90 6.1.2.2 [as corrected by TC1], C99 6.2.2:
- For an identifier declared with the storage-class specifier
- extern in a scope in which a prior declaration of that
- identifier is visible, if the prior declaration specifies
- internal or external linkage, the linkage of the identifier at
- the later daclaration is the same as the linkage specified at
- the prior declaration. If no prior declaration is visible,
- or if the prior declaration specifies no linkage, then the
- identifer has external linkage.
+ For an identifier declared with the storage-class specifier
+ extern in a scope in which a prior declaration of that
+ identifier is visible, if the prior declaration specifies
+ internal or external linkage, the linkage of the identifier at
+ the later daclaration is the same as the linkage specified at
+ the prior declaration. If no prior declaration is visible,
+ or if the prior declaration specifies no linkage, then the
+ identifer has external linkage.
This is PR 14366. */
diff --git a/gcc/testsuite/gcc.dg/loop-3.c b/gcc/testsuite/gcc.dg/loop-3.c
new file mode 100644
index 00000000000..ba6fe556315
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/loop-3.c
@@ -0,0 +1,45 @@
+/* PR optimization/13985 */
+/* Copied from gcc.c-torture/compile/930621-1.c */
+
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-options "-O3 -mtune=i386" { target i?86-*-* x86_64-*-* } } */
+
+#if defined(STACK_SIZE) && (STACK_SIZE < 65536)
+# define BYTEMEM_SIZE 10000L
+#endif
+
+#ifndef BYTEMEM_SIZE
+# define BYTEMEM_SIZE 45000L
+#endif
+
+int bytestart[5000 + 1];
+unsigned char modtext[400 + 1];
+unsigned char bytemem[2][BYTEMEM_SIZE + 1];
+
+long
+modlookup (int l)
+{
+ signed char c;
+ long j;
+ long k;
+ signed char w;
+ long p;
+ while (p != 0)
+ {
+ while ((k < bytestart[p + 2]) && (j <= l) && (modtext[j] == bytemem[w][k]))
+ {
+ k = k + 1;
+ j = j + 1;
+ }
+ if (k == bytestart[p + 2])
+ if (j > l)
+ c = 1;
+ else c = 4;
+ else if (j > l)
+ c = 3;
+ else if (modtext[j] < bytemem[w][k])
+ c = 0;
+ else c = 2;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/noncompile/920507-1.c b/gcc/testsuite/gcc.dg/noncompile/920507-1.c
index 64ddce7f1ff..c1a3523008c 100644
--- a/gcc/testsuite/gcc.dg/noncompile/920507-1.c
+++ b/gcc/testsuite/gcc.dg/noncompile/920507-1.c
@@ -1,6 +1,7 @@
-void
+int *
x(void)
{
register int *a asm("unknown_register"); /* { dg-error "invalid register" } */
int *v[1] = {a};
+ return v[1];
}
diff --git a/gcc/testsuite/gcc.dg/noreturn-1.c b/gcc/testsuite/gcc.dg/noreturn-1.c
index 3bf62c15b40..90660fa028c 100644
--- a/gcc/testsuite/gcc.dg/noreturn-1.c
+++ b/gcc/testsuite/gcc.dg/noreturn-1.c
@@ -7,8 +7,8 @@ extern void exit (int);
extern void foo1(void) __attribute__ ((__noreturn__));
void
foo1(void)
-{ /* { dg-warning "`noreturn' function does return" "detect falling off end of noreturn" } */
-}
+{
+} /* { dg-warning "`noreturn' function does return" "detect falling off end of noreturn" } */
extern void foo2(void) __attribute__ ((__noreturn__));
void
@@ -26,16 +26,17 @@ foo3(void)
extern void foo4(void);
void
foo4(void)
-{
+{ /* { dg-warning "candidate for attribute `noreturn'" "detect noreturn candidate" } */
exit(0);
-} /* { dg-warning "candidate for attribute `noreturn'" "detect noreturn candidate" } */
+}
extern void foo5(void) __attribute__ ((__noreturn__));
void
foo5(void)
{
return; /* { dg-warning "`noreturn' has a `return' statement" "detect invalid return" } */
-} /* { dg-warning "`noreturn' function does return" "detect return from noreturn" } */
+}
+/* { dg-warning "function does return" "detect return from noreturn" { target *-*-* } 37 } */
extern void foo6(void);
void
diff --git a/gcc/testsuite/gcc.dg/noreturn-4.c b/gcc/testsuite/gcc.dg/noreturn-4.c
index 4a2de5f4200..6a081b3fb4e 100644
--- a/gcc/testsuite/gcc.dg/noreturn-4.c
+++ b/gcc/testsuite/gcc.dg/noreturn-4.c
@@ -5,6 +5,6 @@ extern void exit (int) __attribute__ ((__noreturn__));
int
main (void)
-{
+{ /* { dg-warning "warning: function might be possible candidate for attribute `noreturn'" "warn for main" } */
exit (0);
-} /* { dg-warning "warning: function might be possible candidate for attribute `noreturn'" "warn for main" } */
+}
diff --git a/gcc/testsuite/gcc.dg/noreturn-7.c b/gcc/testsuite/gcc.dg/noreturn-7.c
index 1d94a7ccea5..94a26cc3875 100644
--- a/gcc/testsuite/gcc.dg/noreturn-7.c
+++ b/gcc/testsuite/gcc.dg/noreturn-7.c
@@ -14,11 +14,11 @@ void _exit(int status) __attribute__ ((__noreturn__));
int z = 0;
void g()
-{
+{ /* { dg-warning "possible candidate" } */
if (++z > 10)
_exit(0);
g();
-} /* { dg-warning "possible candidate" } */
+}
void f()
{
@@ -28,15 +28,15 @@ void f()
} /* { dg-bogus "does return" } */
int h()
-{
+{ /* { dg-warning "possible candidate" } */
if (++z > 10)
_exit(0);
return h();
} /* { dg-bogus "end of non-void function" } */
int k()
-{
+{ /* { dg-warning "possible candidate" } */
if (++z > 10)
_exit(0);
k();
-} /* { dg-warning "end of non-void function" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr14475.c b/gcc/testsuite/gcc.dg/pr14475.c
new file mode 100644
index 00000000000..8009d465657
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr14475.c
@@ -0,0 +1,8 @@
+/* This used to ICE because there was no null check in
+ check_bitfield_type_and_width. */
+
+struct tree_common
+{
+ enum tree_code code : 8; /* {dg-error "" "" } */
+/* { dg-warning "" "" { target *-*-* } 6 } */
+};
diff --git a/gcc/testsuite/gcc.dg/return-type-1.c b/gcc/testsuite/gcc.dg/return-type-1.c
index 037dbbf0823..2507cafa5e4 100644
--- a/gcc/testsuite/gcc.dg/return-type-1.c
+++ b/gcc/testsuite/gcc.dg/return-type-1.c
@@ -5,5 +5,5 @@
/* { dg-options "-O -Wreturn-type" } */
int
foo(void)
-{ /* { dg-warning "control reaches end of non-void function" "warning for falling off end of non-void function" } */
-}
+{
+} /* { dg-warning "control reaches end of non-void function" "warning for falling off end of non-void function" } */
diff --git a/gcc/testsuite/gcc.dg/return-type-3.c b/gcc/testsuite/gcc.dg/return-type-3.c
index b6fa16539a4..e06ba7c0233 100644
--- a/gcc/testsuite/gcc.dg/return-type-3.c
+++ b/gcc/testsuite/gcc.dg/return-type-3.c
@@ -3,7 +3,7 @@
call optimization. The return clobber insn was cleaned up and
the warning was never issued. */
/* { dg-do compile } */
-/* { dg-options "-foptimize-sibling-calls -Wreturn-type" } */
+/* { dg-options "-O -foptimize-sibling-calls -Wreturn-type" } */
extern void foo(void);
diff --git a/gcc/testsuite/gcc.dg/rs6000-power2-1.c b/gcc/testsuite/gcc.dg/rs6000-power2-1.c
new file mode 100644
index 00000000000..7d344a93a2c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rs6000-power2-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile { target powerpc-*-* rs6000-*-* } } */
+/* { dg-options "-O3 -mcpu=power2 -fno-schedule-insns -w -mhard-float" } */
+/* This used to ICE as the peephole was not checking to see
+ if the register is a floating point one (I think this cannot
+ happen in real life except in this example). */
+
+register double t1 __asm__("r14");
+register double t2 __asm__("r15");
+register double t3 __asm__("r16"), t4 __asm__("r17");
+void t(double *a, double *b)
+{
+ t1 = a[-1];
+ t2 = a[0];
+ t3 = a[1];
+ t4 = a[2];
+ b[-1] = t1;
+ b[0] = t2;
+ b[1] = t3;
+ b[2] = t4;
+}
+
diff --git a/gcc/testsuite/gcc.dg/rs6000-power2-2.c b/gcc/testsuite/gcc.dg/rs6000-power2-2.c
new file mode 100644
index 00000000000..2fefbcbfb81
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rs6000-power2-2.c
@@ -0,0 +1,22 @@
+/* { dg-do compile { target powerpc-*-* rs6000-*-* } } */
+/* { dg-options "-O3 -mcpu=power2 -fno-schedule-insns -w -mhard-float" } */
+/* { dg-final { scan-assembler-not "lfd" } } */
+/* { dg-final { scan-assembler-not "sfd" } } */
+/* { dg-final { scan-assembler "lfq" } } */
+/* { dg-final { scan-assembler "sfq" } } */
+
+register double t1 __asm__("fr0");
+register double t2 __asm__("fr1");
+register double t3 __asm__("fr2"), t4 __asm__("fr3");
+void t(double *a, double *b)
+{
+ t1 = a[-1];
+ t2 = a[0];
+ t3 = a[1];
+ t4 = a[2];
+ b[-1] = t1;
+ b[0] = t2;
+ b[1] = t3;
+ b[2] = t4;
+}
+
diff --git a/gcc/testsuite/gcc.dg/sibcall-3.c b/gcc/testsuite/gcc.dg/sibcall-3.c
index d0908a2289c..37637e70270 100644
--- a/gcc/testsuite/gcc.dg/sibcall-3.c
+++ b/gcc/testsuite/gcc.dg/sibcall-3.c
@@ -5,7 +5,7 @@
Copyright (C) 2002 Free Software Foundation Inc.
Contributed by Hans-Peter Nilsson <hp@bitrange.com> */
-/* { dg-do run { xfail arc-*-* avr-*-* c4x-*-* cris-*-* h8300-*-* ip2k-*-* m32r-*-* m68hc1?-*-* m681?-*-* m680*-*-* m68k-*-* mcore-*-* mips*-*-* mn10300-*-* ns32k-*-* s390*-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa-*-* } } */
+/* { dg-do run { xfail arc-*-* avr-*-* c4x-*-* cris-*-* h8300-*-* ip2k-*-* m32r-*-* m68hc1?-*-* m681?-*-* m680*-*-* m68k-*-* mcore-*-* mips*-*-irix* mips*-*-linux-gnu mn10300-*-* ns32k-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa-*-* } } */
/* { dg-options "-O2 -foptimize-sibling-calls" } */
/* The option -foptimize-sibling-calls is the default, but serves as
diff --git a/gcc/testsuite/gcc.dg/sibcall-4.c b/gcc/testsuite/gcc.dg/sibcall-4.c
index 3980879536c..15d235c471f 100644
--- a/gcc/testsuite/gcc.dg/sibcall-4.c
+++ b/gcc/testsuite/gcc.dg/sibcall-4.c
@@ -5,7 +5,7 @@
Copyright (C) 2002 Free Software Foundation Inc.
Contributed by Hans-Peter Nilsson <hp@bitrange.com> */
-/* { dg-do run { xfail arc-*-* avr-*-* c4x-*-* cris-*-* h8300-*-* ip2k-*-* m32r-*-* m68hc1?-*-* m681?-*-* m680*-*-* m68k-*-* mcore-*-* mips*-*-* mn10300-*-* ns32k-*-* s390*-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa-*-* } } */
+/* { dg-do run { xfail arc-*-* avr-*-* c4x-*-* cris-*-* h8300-*-* ip2k-*-* m32r-*-* m68hc1?-*-* m681?-*-* m680*-*-* m68k-*-* mcore-*-* mips*-*-irix* mips*-*-linux-gnu mn10300-*-* ns32k-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa-*-* } } */
/* { dg-options "-O2 -foptimize-sibling-calls" } */
/* The option -foptimize-sibling-calls is the default, but serves as
diff --git a/gcc/testsuite/gcc.dg/sibcall-6.c b/gcc/testsuite/gcc.dg/sibcall-6.c
index 771a14e8b56..4b0d299f5b7 100644
--- a/gcc/testsuite/gcc.dg/sibcall-6.c
+++ b/gcc/testsuite/gcc.dg/sibcall-6.c
@@ -6,7 +6,7 @@
Copyright (C) 2002 Free Software Foundation Inc.
Contributed by Andreas Bauer <baueran@in.tum.de> */
-/* { dg-do run { target i?86-*-* x86_64-*-*} } */
+/* { dg-do run { target i?86-*-* s390*-*-* x86_64-*-*} } */
/* { dg-options "-O2 -foptimize-sibling-calls" } */
int foo (int);
diff --git a/gcc/testsuite/gcc.dg/tls/asm-1.c b/gcc/testsuite/gcc.dg/tls/asm-1.c
index 68c49f61180..476fe7cbb72 100644
--- a/gcc/testsuite/gcc.dg/tls/asm-1.c
+++ b/gcc/testsuite/gcc.dg/tls/asm-1.c
@@ -3,5 +3,5 @@ __thread int i;
int foo ()
{
- asm volatile ("" :: "m" (&i)); /* { dg-error "lvalue" } */
+ asm volatile ("" :: "m" (&i)); /* { dg-error "directly addressable" } */
}
diff --git a/gcc/testsuite/gcc.dg/torture/builtin-convert-2.c b/gcc/testsuite/gcc.dg/torture/builtin-convert-2.c
new file mode 100644
index 00000000000..68fc071eb7d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/builtin-convert-2.c
@@ -0,0 +1,79 @@
+/* Copyright (C) 2004 Free Software Foundation.
+
+ Verify that built-in math function conversion into integer rounding
+ functions is correctly performed by the compiler.
+
+ Written by Kaveh ghazi, 2004-04-26. */
+
+/* { dg-do link } */
+/* { dg-options "-ffast-math" } */
+
+#include "../builtins-config.h"
+
+#define PROTOTYPE(FN) extern double FN(double); \
+ extern float FN##f(float); \
+ extern long double FN##l(long double);
+#define PROTOTYPE_RET(FN, RET) extern RET FN(double); \
+ extern RET FN##f(float); \
+ extern RET FN##l(long double);
+
+/* Macro to do all FP type combinations. The second half tests
+ narrowing the FP type. */
+#define TEST_FP2FIXED(FN1, FN2) \
+ PROTOTYPE(FN1) \
+ PROTOTYPE_RET(FN2, long) \
+ PROTOTYPE_RET(l##FN2, long long) \
+ extern void link_error_##FN1##_##FN2(void); \
+ extern void link_error_##FN1##f_##FN2##f(void); \
+ extern void link_error_##FN1##l_##FN2##l(void); \
+ extern void link_error_##FN1##_l##FN2(void); \
+ extern void link_error_##FN1##f_l##FN2##f(void); \
+ extern void link_error_##FN1##l_l##FN2##l(void); \
+ if ((long)FN1(d) != FN2(d)) \
+ link_error_##FN1##_##FN2(); \
+ if ((long)FN1##f(f) != FN2##f(f)) \
+ link_error_##FN1##f_##FN2##f(); \
+ if ((long)FN1##l(ld) != FN2##l(ld)) \
+ link_error_##FN1##l_##FN2##l(); \
+ if ((long long)FN1(d) != l##FN2(d)) \
+ link_error_##FN1##_l##FN2(); \
+ if ((long long)FN1##f(f) != l##FN2##f(f)) \
+ link_error_##FN1##f_l##FN2##f(); \
+ if ((long long)FN1##l(ld) != l##FN2##l(ld)) \
+ link_error_##FN1##l_l##FN2##l(); \
+ extern void link_error_##FN1##_##FN2##f(void); \
+ extern void link_error_##FN1##l_##FN2(void); \
+ extern void link_error_##FN1##l_##FN2##f(void); \
+ extern void link_error_##FN1##_l##FN2##f(void); \
+ extern void link_error_##FN1##l_l##FN2(void); \
+ extern void link_error_##FN1##l_l##FN2##f(void); \
+ if (sizeof(double) > sizeof(float) && (long)FN1(f) != FN2##f(f)) \
+ link_error_##FN1##_##FN2##f(); \
+ if (sizeof(long double) > sizeof(double) && (long)FN1##l(d) != FN2(d)) \
+ link_error_##FN1##l_##FN2(); \
+ if (sizeof(long double) > sizeof(float) && (long)FN1##l(f) != FN2##f(f)) \
+ link_error_##FN1##l_##FN2##f(); \
+ if (sizeof(double) > sizeof(float) && (long long)FN1(f) != l##FN2##f(f)) \
+ link_error_##FN1##_l##FN2##f(); \
+ if (sizeof(long double) > sizeof(double) && (long long)FN1##l(d) != l##FN2(d)) \
+ link_error_##FN1##l_l##FN2(); \
+ if (sizeof(long double) > sizeof(float) && (long long)FN1##l(f) != l##FN2##f(f)) \
+ link_error_##FN1##l_l##FN2##f()
+
+void __attribute__ ((__noinline__)) foo (double d, float f, long double ld)
+{
+#ifdef __OPTIMIZE__
+# ifdef HAVE_C99_RUNTIME
+ /* The resulting transformation functions are all C99. */
+ TEST_FP2FIXED (round, lround);
+ TEST_FP2FIXED (nearbyint, lrint);
+ TEST_FP2FIXED (rint, lrint);
+# endif
+#endif
+}
+
+int main()
+{
+ foo (1.0, 2.0, 3.0);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/builtin-convert-3.c b/gcc/testsuite/gcc.dg/torture/builtin-convert-3.c
new file mode 100644
index 00000000000..9901ceccf81
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/builtin-convert-3.c
@@ -0,0 +1,56 @@
+/* Copyright (C) 2004 Free Software Foundation.
+
+ Verify that builtin math functions (with fixed point return types)
+ are converted to smaller FP types correctly by the compiler.
+
+ Written by Kaveh Ghazi, 2004-05-01. */
+
+/* { dg-do link } */
+/* { dg-options "-ffast-math" } */
+
+#include "../builtins-config.h"
+
+#define PROTOTYPE1_RET(FN, RET) \
+ extern RET FN(double); \
+ extern RET FN##f(float); \
+ extern RET FN##l(long double);
+
+/* Test converting math builtins to narrower FP types based on if the
+ argument is a narrower type (perhaps implicitly) cast to a wider
+ one. */
+#define INNER_CAST1(MATHFN, RET) \
+ PROTOTYPE1_RET (MATHFN, RET); \
+ extern void link_failure_inner_##MATHFN##l_##MATHFN(void); \
+ extern void link_failure_inner_##MATHFN##l_##MATHFN##f(void); \
+ extern void link_failure_inner_##MATHFN##_##MATHFN##f(void); \
+ if (sizeof (long double) > sizeof (double) \
+ && MATHFN##l(d1) != MATHFN(d1)) \
+ link_failure_inner_##MATHFN##l_##MATHFN(); \
+ if (sizeof (long double) > sizeof (float) \
+ && MATHFN##l(f1) != MATHFN##f(f1)) \
+ link_failure_inner_##MATHFN##l_##MATHFN##f(); \
+ if (sizeof (long double) > sizeof (float) \
+ && MATHFN##l((double)f1) != MATHFN##f(f1)) \
+ link_failure_inner_##MATHFN##l_##MATHFN##f(); \
+ if (sizeof (double) > sizeof (float) \
+ && MATHFN(f1) != MATHFN##f(f1)) \
+ link_failure_inner_##MATHFN##_##MATHFN##f()
+
+void __attribute__ ((__noinline__)) test (double d1, float f1)
+{
+#ifdef __OPTIMIZE__
+#ifdef HAVE_C99_RUNTIME
+ /* We're converting to implicitly generated C99 functions. */
+ INNER_CAST1 (lround, long);
+ INNER_CAST1 (llround, long long);
+ INNER_CAST1 (lrint, long);
+ INNER_CAST1 (llrint, long long);
+#endif /* HAVE_C99_RUNTIME */
+#endif /* __OPTIMIZE__ */
+}
+
+int main (void)
+{
+ test (1, 2);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/builtin-ctype-2.c b/gcc/testsuite/gcc.dg/torture/builtin-ctype-2.c
index a306bcc9dae..7046aad6562 100644
--- a/gcc/testsuite/gcc.dg/torture/builtin-ctype-2.c
+++ b/gcc/testsuite/gcc.dg/torture/builtin-ctype-2.c
@@ -75,6 +75,29 @@ void test(int i)
if (toascii(i) != (i & 0x7f))
link_failure_var();
+ TEST_CTYPE_CST_TRUE (isdigit, '0');
+ TEST_CTYPE_CST_TRUE (isdigit, '1');
+ TEST_CTYPE_CST_TRUE (isdigit, '2');
+ TEST_CTYPE_CST_TRUE (isdigit, '3');
+ TEST_CTYPE_CST_TRUE (isdigit, '4');
+ TEST_CTYPE_CST_TRUE (isdigit, '5');
+ TEST_CTYPE_CST_TRUE (isdigit, '6');
+ TEST_CTYPE_CST_TRUE (isdigit, '7');
+ TEST_CTYPE_CST_TRUE (isdigit, '8');
+ TEST_CTYPE_CST_TRUE (isdigit, '9');
+
+ TEST_CTYPE_CST_FALSE (isdigit, '0'-1);
+ TEST_CTYPE_CST_FALSE (isdigit, '9'+1);
+ TEST_CTYPE_CST_FALSE (isdigit, -1);
+ TEST_CTYPE_CST_FALSE (isdigit, 0);
+ TEST_CTYPE_CST_FALSE (isdigit, 255);
+ TEST_CTYPE_CST_FALSE (isdigit, 256);
+ TEST_CTYPE_CST_FALSE (isdigit, 10000);
+ TEST_CTYPE_CST_FALSE (isdigit, __INT_MAX__);
+
+ /* This ctype call should transform into another expression. */
+ if (isdigit(i) != ((unsigned)i - '0' <= 9))
+ link_failure_var();
#endif /* __OPTIMIZE__ */
}
diff --git a/gcc/testsuite/gcc.dg/torture/builtin-integral-1.c b/gcc/testsuite/gcc.dg/torture/builtin-integral-1.c
index 1f2990dd2f0..0aeb7ff7bdb 100644
--- a/gcc/testsuite/gcc.dg/torture/builtin-integral-1.c
+++ b/gcc/testsuite/gcc.dg/torture/builtin-integral-1.c
@@ -9,33 +9,57 @@
#define PROTOTYPE1(FN) extern double FN(double); extern float FN##f(float); \
extern long double FN##l(long double);
+#define PROTOTYPE1_RET(FN, RET) extern RET FN(double); extern RET FN##f(float); \
+ extern RET FN##l(long double);
+#define PROTOTYPE_LINK_FAILURE(FN) extern void link_failure_##FN(void); \
+ extern void link_failure_##FN##f(void); \
+ extern void link_failure_##FN##l(void); \
PROTOTYPE1(fabs)
+PROTOTYPE1(ceil)
+PROTOTYPE1(floor)
+PROTOTYPE1(nearbyint)
+PROTOTYPE1(rint)
+PROTOTYPE1(round)
+PROTOTYPE1(trunc)
+PROTOTYPE1_RET(lround, long)
+PROTOTYPE1_RET(llround, long long)
+PROTOTYPE1_RET(lrint, long)
+PROTOTYPE1_RET(llrint, long long)
-void test(int i1, int i2)
-{
- /* Test that the various FP truncation builtins detect integral
- arguments. */
+/* Test that the various FP truncation builtins detect integral
+ arguments. */
#define CHECK_FN(MATHFN) \
- PROTOTYPE1 (MATHFN) \
- extern void link_failure_##MATHFN(void); \
- extern void link_failure_##MATHFN##f(void); \
- extern void link_failure_##MATHFN##l(void); \
+ PROTOTYPE_LINK_FAILURE(MATHFN); \
if (MATHFN(i1) != i1) link_failure_##MATHFN(); \
if (MATHFN##f(i1) != i1) link_failure_##MATHFN##f(); \
- if (MATHFN##l(i1) != i1) link_failure_##MATHFN##l(); \
+ if (MATHFN##l(i1) != i1) link_failure_##MATHFN##l();
+
+#define CHECK_FN_RET(MATHFN, RET) \
+ PROTOTYPE_LINK_FAILURE(MATHFN); \
+ if (MATHFN(i1) != (RET)(double)i1) link_failure_##MATHFN(); \
+ if (MATHFN##f(i1) != (RET)(float)i1) link_failure_##MATHFN##f(); \
+ if (MATHFN##l(i1) != (RET)(long double)i1) link_failure_##MATHFN##l();
+
+ /* Check that various other integral expressions are detected. */
+#define CHECK_EXPR(EXPR,NAME) \
+ extern void link_failure_FP_##NAME(void); \
+ extern void link_failure_fixed_##NAME(void); \
+ if (ceill(EXPR) != (EXPR)) link_failure_FP_##NAME(); \
+ if (lroundl(EXPR) != (long)(long double)(EXPR)) link_failure_fixed_##NAME();
+void __attribute__ ((__noinline__)) test (int i1, int i2)
+{
CHECK_FN(ceil);
CHECK_FN(floor);
CHECK_FN(nearbyint);
CHECK_FN(rint);
CHECK_FN(round);
CHECK_FN(trunc);
-
- /* Check that various other integral expressions are detected. */
-#define CHECK_EXPR(EXPR,NAME) \
- extern void link_failure_##NAME(void); \
- if (ceill(EXPR) != (EXPR)) link_failure_##NAME(); \
+ CHECK_FN_RET(lround, long);
+ CHECK_FN_RET(llround, long long);
+ CHECK_FN_RET(lrint, long);
+ CHECK_FN_RET(llrint, long long);
CHECK_EXPR (5.0, REAL_CST);
CHECK_EXPR (5.0F, REAL_CSTf);
@@ -54,5 +78,6 @@ void test(int i1, int i2)
int main (void)
{
+ test (1, 2);
return 0;
}
diff --git a/gcc/testsuite/gcc.dg/torture/builtin-rounding-1.c b/gcc/testsuite/gcc.dg/torture/builtin-rounding-1.c
new file mode 100644
index 00000000000..4101f911e5a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/builtin-rounding-1.c
@@ -0,0 +1,106 @@
+/* Copyright (C) 2004 Free Software Foundation.
+
+ Check that constant folding of the rounding math functions doesn't
+ break anything and produces the expected results.
+
+ Written by Kaveh Ghazi, 2004-04-29. */
+
+/* { dg-do link } */
+
+#define PROTOTYPE(FN) \
+ PROTOTYPE_LINK_ERROR(FN) \
+ extern double FN (double); \
+ extern float FN##f (float); \
+ extern long double FN##l (long double);
+
+#define PROTOTYPE_RET(FN, RET) \
+ PROTOTYPE_LINK_ERROR(FN) \
+ extern RET FN (double); \
+ extern RET FN##f (float); \
+ extern RET FN##l (long double);
+
+#define PROTOTYPE_LINK_ERROR(FN) \
+ extern void link_error_##FN(void); \
+ extern void link_error_##FN##f(void); \
+ extern void link_error_##FN##l(void);
+
+#define TEST(FN, VALUE, RESULT) \
+ if (FN (VALUE) != RESULT) link_error_##FN(); \
+ if (FN##f (VALUE) != RESULT) link_error_##FN##f(); \
+ if (FN##l (VALUE) != RESULT) link_error_##FN##l(); \
+
+PROTOTYPE (trunc);
+PROTOTYPE (floor);
+PROTOTYPE (ceil);
+PROTOTYPE (round);
+PROTOTYPE_RET (lround, long);
+PROTOTYPE_RET (llround, long long);
+
+int
+main (void)
+{
+ TEST(trunc, 0, 0);
+ TEST(floor, 0, 0);
+ TEST(ceil, 0, 0);
+ TEST(round, 0, 0);
+ TEST(lround, 0, 0);
+ TEST(llround, 0, 0);
+
+ TEST(trunc, 6, 6);
+ TEST(floor, 6, 6);
+ TEST(ceil, 6, 6);
+ TEST(round, 6, 6);
+ TEST(lround, 6, 6);
+ TEST(llround, 6, 6);
+
+ TEST(trunc, -8, -8);
+ TEST(floor, -8, -8);
+ TEST(ceil, -8, -8);
+ TEST(round, -8, -8);
+ TEST(lround, -8, -8);
+ TEST(llround, -8, -8);
+
+ TEST(trunc, 3.2, 3);
+ TEST(floor, 3.2, 3);
+ TEST(ceil, 3.2, 4);
+ TEST(round, 3.2, 3);
+ TEST(lround, 3.2, 3);
+ TEST(llround, 3.2, 3);
+
+ TEST(trunc, -2.8, -2);
+ TEST(floor, -2.8, -3);
+ TEST(ceil, -2.8, -2);
+ TEST(round, -2.8, -3);
+ TEST(lround, -2.8, -3);
+ TEST(llround, -2.8, -3);
+
+ TEST(trunc, 0.01, 0);
+ TEST(floor, 0.01, 0);
+ TEST(ceil, 0.01, 1);
+ TEST(round, 0.01, 0);
+ TEST(lround, 0.01, 0);
+ TEST(llround, 0.01, 0);
+
+ TEST(trunc, -0.7, 0);
+ TEST(floor, -0.7, -1);
+ TEST(ceil, -0.7, 0);
+ TEST(round, -0.7, -1);
+ TEST(lround, -0.7, -1);
+ TEST(llround, -0.7, -1);
+
+ TEST(trunc, 2.5, 2);
+ TEST(floor, 2.5, 2);
+ TEST(ceil, 2.5, 3);
+ TEST(round, 2.5, 3);
+ TEST(lround, 2.5, 3);
+ TEST(llround, 2.5, 3);
+
+ TEST(trunc, -1.5, -1);
+ TEST(floor, -1.5, -2);
+ TEST(ceil, -1.5, -1);
+ TEST(round, -1.5, -2);
+ TEST(lround, -1.5, -2);
+ TEST(llround, -1.5, -2);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/mips-hilo-1.c b/gcc/testsuite/gcc.dg/torture/mips-hilo-1.c
new file mode 100644
index 00000000000..2b0d668fc69
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/mips-hilo-1.c
@@ -0,0 +1,75 @@
+/* f1 checks that an mtlo is not moved before an mfhi. f2 does the same
+ for an mthi and an mflo. */
+/* { dg-do run { target mips*-*-* } } */
+/* { dg-options "-mtune=rm7000" } */
+
+#if !defined(__mips16)
+
+#define DECLARE(TYPE) \
+ TYPE __attribute__ ((noinline)) \
+ f1##TYPE (TYPE x1, TYPE x2, TYPE x3) \
+ { \
+ TYPE t1, t2; \
+ \
+ asm ("mult\t%1,%2" : "=h" (t1) : "d" (x1), "d" (x2) : "lo"); \
+ asm ("mflo\t%0" : "=r" (t2) : "l" (x3) : "hi"); \
+ return t1 + t2; \
+ } \
+ \
+ TYPE __attribute__ ((noinline)) \
+ f2##TYPE (TYPE x1, TYPE x2, TYPE x3) \
+ { \
+ TYPE t1, t2; \
+ \
+ asm ("mult\t%1,%2" : "=l" (t1) : "d" (x1), "d" (x2) : "hi"); \
+ asm ("mfhi\t%0" : "=r" (t2) : "h" (x3) : "lo"); \
+ return t1 + t2; \
+ }
+
+#define TEST(TYPE) \
+ if (f1##TYPE (1, 2, 10) != 10) \
+ abort (); \
+ if (f2##TYPE (1, 2, 40) != 42) \
+ abort ()
+
+typedef char c;
+typedef signed char sc;
+typedef unsigned char uc;
+typedef short s;
+typedef unsigned short us;
+typedef int i;
+typedef unsigned int ui;
+typedef long long ll;
+typedef unsigned long long ull;
+
+DECLARE (c)
+DECLARE (sc)
+DECLARE (uc)
+DECLARE (s)
+DECLARE (us)
+DECLARE (i)
+DECLARE (ui)
+#if defined (__mips64)
+DECLARE (ll)
+DECLARE (ull)
+#endif
+
+int
+main ()
+{
+ TEST (c);
+ TEST (sc);
+ TEST (uc);
+ TEST (s);
+ TEST (us);
+ TEST (i);
+ TEST (ui);
+#if defined (__mips64)
+ TEST (ll);
+ TEST (ull);
+#endif
+ exit (0);
+}
+#else
+int main () { exit (0); }
+#endif
diff --git a/gcc/testsuite/gcc.dg/torture/mips-hilo-2.c b/gcc/testsuite/gcc.dg/torture/mips-hilo-2.c
new file mode 100644
index 00000000000..0bdff6cd32c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/mips-hilo-2.c
@@ -0,0 +1,28 @@
+/* Due to a reload inheritance bug, the asm statement in f() would be passed
+ the low part of u.ll on little-endian 32-bit targets. */
+/* { dg-do run { target mips*-*-* } } */
+
+#if !defined(__mips16)
+unsigned int g;
+
+unsigned long long f (unsigned int x)
+{
+ union { unsigned long long ll; unsigned int parts[2]; } u;
+
+ u.ll = ((unsigned long long) x * x);
+ asm ("mflo\t%0" : "=r" (g) : "l" (u.parts[1]));
+ return u.ll;
+}
+
+int main ()
+{
+ union { unsigned long long ll; unsigned int parts[2]; } u;
+
+ u.ll = f (0x12345678);
+ if (g != u.parts[1])
+ abort ();
+ exit (0);
+}
+#else
+int main () { exit (0); }
+#endif
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030530-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030530-2.c
new file mode 100644
index 00000000000..408e2464e96
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030530-2.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+
+typedef struct rs6000_stack {
+ int first_gp_reg_save;
+} rs6000_stack_t;
+extern char regs_ever_live[113];
+extern rs6000_stack_t *rs6000_stack_info (void);
+void
+rs6000_emit_prologue (int i, rs6000_stack_t *info)
+{
+ if (regs_ever_live[info->first_gp_reg_save + i] || i+info->first_gp_reg_save)
+ gen_rtx_REG (info->first_gp_reg_save + i);
+}
+
+/* There should be precisely one load of first_gp_reg_save. If there is
+ more than one, then the dominator optimizations failed. */
+/* { dg-final { scan-tree-dump-times "first_gp_reg_save" 1 "dom3"} } */
+
+/* There should be precisely one addition. If there is more than one, then
+ the dominator optimizations failed, most likely due to not handling
+ commutative operands correctly. */
+/* { dg-final { scan-tree-dump-times "\\+" 1 "dom3"} } */
+
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030611-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030611-1.c
new file mode 100644
index 00000000000..d16bda4c1f1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030611-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+extern int square (int) __attribute__ ((__const__));
+shit(int a)
+{
+ return square (a) + square (a);
+
+}
+
+/* There should be precisely one call to square. If there is more than one,
+ then the dominator optimizations failed to remove the redundant call. */
+/* { dg-final { scan-tree-dump-times "square" 1 "dom3"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030703-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030703-1.c
new file mode 100644
index 00000000000..f5b3db3460d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030703-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+
+extern int blah[];
+
+foo(int index)
+{
+ if (blah [(unsigned int)index] != 0)
+ abort ();
+ if (blah [(unsigned int)index] != 0)
+ abort ();
+}
+
+/* There should be precisely one load of blah. If there is
+ more than one, then the dominator optimizations failed. */
+/* { dg-final { scan-tree-dump-times "blah" 1 "dom3"} } */
+
+/* There should be exactly one IF conditional. */
+/* { dg-final { scan-tree-dump-times "if " 1 "dom3"} } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030703-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030703-2.c
new file mode 100644
index 00000000000..a73150a06a3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030703-2.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+union tree_node;
+typedef union tree_node *tree;
+extern const char tree_code_type[];
+
+union tree_node
+{
+ int code;
+ long pointer_alias_set;
+};
+
+long
+get_alias_set (t)
+ tree t;
+{
+ if (tree_code_type[t->code])
+ abort ();
+ if (t->pointer_alias_set)
+ {
+ tree __t = t;
+ if (tree_code_type[__t->code])
+ abort ();
+ }
+}
+
+/* There should be precisely one load of {t,__t}->code. If there is
+ more than one, then the dominator optimizations failed. */
+/* { dg-final { scan-tree-dump-times "->code" 1 "dom3"} } */
+
+/* There should be precisely one load of tree_code_type. If there is
+ more than one, then the dominator optimizations failed. */
+/* { dg-final { scan-tree-dump-times "tree_code_type" 1 "dom3"} } */
+
+/* There should be one IF conditional. If 'tree_code_type[t->code]' is
+ zero, then the third if() conditional is unnecessary. That should cause
+ the call to abort() to be removed, which in turn causes the whole second
+ if() to disappear. */
+/* { dg-final { scan-tree-dump-times "if " 1 "dom3"} } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030708-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030708-1.c
new file mode 100644
index 00000000000..65c8026a341
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030708-1.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+struct rtx_def;
+typedef struct rtx_def *rtx;
+enum rtx_code
+{
+ CALL_INSN,
+ EXPR_LIST,
+ NOTE,
+ LAST = 256
+};
+
+struct rtx_def
+{
+
+ enum rtx_code code:16;
+};
+
+static int
+nonlocal_mentioned_p (x)
+ rtx x;
+{
+ if (x->code == CALL_INSN)
+ {
+ rtx const _rtx = ((x));
+ if (_rtx->code != CALL_INSN
+ && _rtx->code != NOTE
+ && _rtx->code != EXPR_LIST)
+ abort ();
+ }
+
+ blah (&x);
+}
+
+/* There should be no casts to a short unsigned int since the entire
+ set of conditionals should optimize away. */
+/* { dg-final { scan-tree-dump-times "\\(short unsigned int\\)" 0 "dom3"} } */
+
+/* There should be no IF conditionals. */
+/* { dg-final { scan-tree-dump-times "if " 0 "dom3"} } */
+
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030709-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030709-1.c
new file mode 100644
index 00000000000..dc45cbd73a2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030709-1.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+static int copying_arguments;
+static int
+foo ()
+{
+ unsigned int regno;
+ if (regno < 53 && copying_arguments)
+ if (regno >= 53)
+ return 1;
+}
+
+/* There should be no IF conditionals. */
+/* { dg-final { scan-tree-dump-times "if " 0 "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
new file mode 100644
index 00000000000..ffa7f477622
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cddce" } */
+
+struct rtx_def;
+typedef struct rtx_def *rtx;
+union tree_node;
+typedef union tree_node *tree;
+typedef struct mem_attrs
+{
+ int foo;
+
+} mem_attrs;
+union rtunion_def
+{
+ mem_attrs *rtmem;
+};
+typedef union rtunion_def rtunion;
+struct rtx_def
+{
+ rtunion fld[1];
+};
+struct tree_decl
+{
+ rtx rtl;
+};
+union tree_node
+{
+ struct tree_decl decl;
+};
+void *
+get_alias_set (t)
+ tree t;
+{
+ long set;
+ if (t->decl.rtl)
+ return (t->decl.rtl->fld[1].rtmem
+ ? 0
+ : (((t->decl.rtl ? t->decl.rtl: (make_decl_rtl (t, 0), t->decl.rtl)))->fld[1]).rtmem);
+ return (void*)-1;
+}
+
+/* There should be precisely one load of ->decl.rtl. If there is
+ more than, then the dominator optimizations failed. */
+/* { dg-final { scan-tree-dump-times "->decl\\.rtl" 1 "cddce"} } */
+
+/* There should be no loads of .rtmem since the complex return statement
+ is just "return 0". */
+/* { dg-final { scan-tree-dump-times ".rtmem" 0 "cddce"} } */
+
+/* There should be one IF statement (the complex return statement should
+ collapse down to a simple return 0 without any conditionals). */
+/* { dg-final { scan-tree-dump-times "if " 1 "cddce"} } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030709-3.c b/gcc/testsuite/gcc.dg/tree-ssa/20030709-3.c
new file mode 100644
index 00000000000..98681c088c9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030709-3.c
@@ -0,0 +1,45 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+
+union tree_node;
+typedef union tree_node *tree;
+enum tree_code
+{
+ TREE_VEC = 20,
+};
+struct tree_common
+{
+ int code;
+};
+struct tree_type
+{
+ tree binfo;
+};
+union tree_node
+{
+ struct tree_common common;
+ struct tree_type type;
+};
+void
+record_component_aliases (type)
+ tree type;
+{
+ const tree __z = type->type.binfo;
+ if (type->type.binfo->common.code != TREE_VEC)
+ abort ();
+
+ if (__z->common.code != TREE_VEC)
+ abort ();
+}
+
+/* There should be precisely one load of type.binfo. If there is
+ more than one, then the dominator optimizations failed. */
+/* { dg-final { scan-tree-dump-times "type\\.binfo" 1 "dom3"} } */
+
+/* There should be precisely one load of common.code. If there is
+ more than one, then the dominator optimizations failed. */
+/* { dg-final { scan-tree-dump-times "common\\.code" 1 "dom3"} } */
+
+/* There should be one IF conditional. */
+/* { dg-final { scan-tree-dump-times "if " 1 "dom3"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030710-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030710-1.c
new file mode 100644
index 00000000000..53e3d5992cf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030710-1.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+union tree_node;
+typedef union tree_node *tree;
+struct tree_vec
+{
+ int length;
+ tree a[1];
+};
+struct tree_type
+{
+ tree binfo;
+};
+union tree_node
+{
+ struct tree_type type;
+ struct tree_vec vec;
+};
+void
+record_component_aliases (type)
+ tree type;
+{
+ if (type->type.binfo->vec.length)
+ abort ();
+ for (; ((
+ {
+ const tree __z = type->type.binfo;
+ if (type->type.binfo->vec.length)
+ abort ();
+ type->type.binfo->vec.a[4];}
+ )->vec.length);)
+ {
+ if (4 >= type->type.binfo->vec.length)
+ abort ();
+ blah ();
+ }
+}
+
+/* The call to blah should have been eliminated. If the call is not
+ eliminated, then dominator optimizations failed and it'll be
+ impossible to delete other unnecessary code. */
+/* { dg-final { scan-tree-dump-not "blah \\(\\)" "dom3" } } */
+
+/* There should be two IF conditionals. */
+/* { dg-final { scan-tree-dump-times "if " 2 "dom3"} } */
+
+/* There should be a single load of type.binfo. */
+/* { dg-final { scan-tree-dump-times "type\\.binfo" 1 "dom3"} } */
+
+/* There should be two loads of vec.length. */
+/* { dg-final { scan-tree-dump-times "vec.length" 2 "dom3"} } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030711-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030711-1.c
new file mode 100644
index 00000000000..eba207a25e5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030711-1.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+
+union tree_node;
+typedef union tree_node *tree;
+struct tree_vec
+{
+ int length;
+ tree a[1];
+};
+struct tree_type
+{
+ tree binfo;
+};
+union tree_node
+{
+ struct tree_type type;
+ struct tree_vec vec;
+};
+
+void
+record_component_aliases (type)
+ tree type;
+{
+ int i;
+ if (4 >= type->type.binfo->vec.length)
+ abort ();
+ for (; i < ((
+ {
+ const tree __t = type->type.binfo;
+ if (4 >= __t->vec.length)
+ abort (); type->type.binfo->vec.a[4];}
+ )->vec.length);)
+ {
+ if (4 >= type->type.binfo->vec.length)
+ abort ();
+ blah ();
+ }
+}
+
+/* The call to blah can not be eliminated. */
+/* { dg-final { scan-tree-dump-times "blah \\(\\)" 1 "dom3" } } */
+
+/* There should be four IF conditionals. */
+/* { dg-final { scan-tree-dump-times "if " 4 "dom3"} } */
+
+/* There should be two loads of type.binfo. */
+/* { dg-final { scan-tree-dump-times "type\\.binfo" 2 "dom3"} } */
+
+/* There should be four loads of vec.length. */
+/* { dg-final { scan-tree-dump-times "vec.length" 4 "dom3"} } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030711-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030711-2.c
new file mode 100644
index 00000000000..2fd47f753cf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030711-2.c
@@ -0,0 +1,67 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+
+struct rtx_def;
+typedef struct rtx_def *rtx;
+struct rtvec_def;
+typedef struct rtvec_def *rtvec;
+union tree_node;
+typedef union tree_node *tree;
+typedef struct mem_attrs
+{
+ long alias;
+}
+mem_attrs;
+union rtunion_def
+{
+ mem_attrs *rtmem;
+};
+typedef union rtunion_def rtunion;
+struct rtx_def
+{
+ int code;
+ rtunion fld[1];
+};
+struct tree_decl
+{
+ rtx rtl;
+};
+union tree_node
+{
+ struct tree_decl decl;
+};
+long
+get_alias_set (t,z)
+ tree t;
+ rtx z;
+{
+ if (t->decl.rtl && (((t->decl.rtl ? z
+ : (make_decl_rtl (t, 0), t->decl.rtl)))->code))
+ return (((((t->decl.rtl ? z : (make_decl_rtl (t, 0), t->decl.rtl)))->
+ fld[1]).rtmem) == 0 ? 0 : (((((
+ {
+ t;}
+ )->decl.
+ rtl ? z : (make_decl_rtl (t, 0),
+ t->decl.rtl)))->
+ fld[1]).rtmem)->alias);
+}
+
+/* The calls to make_decl_rtl should be eliminated
+/* { dg-final { scan-tree-dump-not "make_decl_rtl \\(\\)" "dom3" } } */
+
+/* There should be three IF conditionals. */
+/* { dg-final { scan-tree-dump-times "if " 3 "dom3"} } */
+
+/* There should be one loads of decl.rtl. */
+/* { dg-final { scan-tree-dump-times "decl\\.rtl" 1 "dom3"} } */
+
+/* There should be one load of code. */
+/* { dg-final { scan-tree-dump-times "code" 1 "dom3"} } */
+
+/* There should be one load of rtmem. */
+/* { dg-final { scan-tree-dump-times "rtmem" 1 "dom3"} } */
+
+/* There should be one load of alias. */
+/* { dg-final { scan-tree-dump-times "->alias" 1 "dom3"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030711-3.c b/gcc/testsuite/gcc.dg/tree-ssa/20030711-3.c
new file mode 100644
index 00000000000..515f3609f70
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030711-3.c
@@ -0,0 +1,59 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+
+struct rtx_def;
+typedef struct rtx_def *rtx;
+struct rtvec_def;
+typedef struct rtvec_def *rtvec;
+union tree_node;
+typedef union tree_node *tree;
+typedef struct mem_attrs
+{
+ long alias;
+}
+mem_attrs;
+union rtunion_def
+{
+ mem_attrs *rtmem;
+};
+typedef union rtunion_def rtunion;
+struct rtx_def
+{
+ int code;
+ rtunion fld[1];
+};
+struct tree_decl
+{
+ rtx rtl;
+};
+union tree_node
+{
+ struct tree_decl decl;
+};
+long
+get_alias_set (t)
+ tree t;
+{
+ if (t->decl.rtl != (void *) 0)
+ return (((t->decl.rtl->fld[1]).rtmem) ==
+ 0 ? 0
+ : ((((t->decl.
+ rtl ? 0 : (make_decl_rtl (t, ((void *) 0)),
+ t->decl.rtl)))->fld[1]).rtmem)->alias);
+}
+
+/* The calls to make_decl_rtl should be eliminated. */
+/* { dg-final { scan-tree-dump-not "make_decl_rtl \\(\\)" "dom3" } } */
+
+/* There should be two IF conditionals. */
+/* { dg-final { scan-tree-dump-times "if " 2 "dom3"} } */
+
+/* There should be one load of decl.rtl. */
+/* { dg-final { scan-tree-dump-times "decl\\.rtl" 1 "dom3"} } */
+
+/* There should be two loads of rtmem. */
+/* { dg-final { scan-tree-dump-times "rtmem" 2 "dom3"} } */
+
+/* There should be one load of alias. */
+/* { dg-final { scan-tree-dump-times "->alias" 1 "dom3"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c
new file mode 100644
index 00000000000..63823f71059
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+struct rtx_def;
+typedef struct rtx_def *rtx;
+enum rtx_code
+{
+ REG,
+ LAST_AND_UNUSED_RTX_CODE = 256
+};
+typedef union rtunion_def rtunion;
+struct rtx_def
+{
+ enum rtx_code code:16;
+ unsigned frame_related:1;
+};
+static rtx
+find_base_value (src)
+ rtx src;
+{
+ rtx temp;
+ rtx src_0;
+ rtx src_1;
+
+ if ((src_0->code == REG) && (({src_0;})->frame_related))
+ return find_base_value (src_0);
+ if ((src_1->code == REG) && (({ src_1;})->frame_related))
+ return find_base_value (src_1);
+ if (src_0->code == REG)
+ find_base_value (src_0);
+ if (src_1->code == REG)
+ find_base_value (src_1);
+}
+
+
+/* There should be six IF conditionals. */
+/* { dg-final { scan-tree-dump-times "if " 6 "dom3"} } */
+
+/* There should be no casts to short unsigned int. */
+/* { dg-final { scan-tree-dump-times "\\(short unsigned int\\)" 0 "dom3"} } */
+
+/* There should be three loads of ->code. */
+/* { dg-final { scan-tree-dump-times "->code" 3 "dom3"} } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030714-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030714-2.c
new file mode 100644
index 00000000000..6a43360b07f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030714-2.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+
+union tree_node;
+typedef union tree_node *tree;
+extern const char tree_code_type[];
+struct tree_common
+{
+ int code;
+ tree type;
+};
+struct tree_exp
+{
+ tree operands[1];
+};
+union tree_node
+{
+ struct tree_common common;
+ struct tree_exp exp;
+};
+long
+get_alias_set (t)
+ tree t;
+{
+ if (tree_code_type[t->common.code] != 't' && t->common.type == 0)
+ return 0;
+ if (tree_code_type[t->common.code] != 't')
+ {
+ while (t->exp.operands[0])
+ t = t->exp.operands[0];
+ }
+}
+
+/* There should be exactly four IF conditionals if we thread jumps
+ properly. */
+/* { dg-final { scan-tree-dump-times "if " 4 "dom3"} } */
+
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c
new file mode 100644
index 00000000000..4bc04bc4da4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c
@@ -0,0 +1,47 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+
+union tree_node;
+typedef union tree_node *tree;
+
+enum tree_code
+{
+ ARRAY_TYPE,
+ LAST_AND_UNUSED_TREE_CODE
+};
+
+struct tree_common
+{
+ enum tree_code code:8;
+};
+
+
+
+
+
+union tree_node
+{
+ struct tree_common common;
+};
+
+
+
+
+int
+objects_must_conflict_p (t1, t2)
+ tree t1, t2;
+{
+
+ if ((t1->common.code == ARRAY_TYPE) != (t2
+ && t2->common.code == ARRAY_TYPE))
+ return 0;
+
+
+ return foo (t2 ? get_alias_set (t2) : 0);
+}
+
+/* There should be three assignments of variables to the value zero. */
+/* { dg-final { scan-tree-dump-times " = 0" 3 "optimized"} } */
+
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030729-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030729-1.c
new file mode 100644
index 00000000000..b4b1a819ff4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030729-1.c
@@ -0,0 +1,51 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+union tree_node;
+typedef union tree_node *tree;
+
+
+enum tree_code
+{
+ SET_TYPE,
+ RECORD_TYPE,
+ LAST_AND_UNUSED_TREE_CODE
+};
+extern const char tree_code_type[];
+
+struct tree_common
+{
+
+ enum tree_code code:8;
+};
+
+
+
+
+
+union tree_node
+{
+ struct tree_common common;
+};
+
+readonly_fields_p (type)
+ tree type;
+{
+
+ if (type->common.code != RECORD_TYPE)
+ return;
+
+ if (tree_code_type[type->common.code] != 't')
+ abort ();
+
+ return;
+}
+
+/* A good optimizer would realize that the cast to (unsigned int) is
+ useless as the earlier cast of the same value of (unsigned char) will
+ always produce the same result. */
+/* { dg-final { scan-tree-dump-times "\\(unsigned int\\)" 0 "dom3"} } */
+
+/* There should be one load of ->common.code. We currently fail this
+ because we load from ->common.code using different types. */
+/* { dg-final { scan-tree-dump-times "common\.code" 1 "dom3"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030730-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030730-1.c
new file mode 100644
index 00000000000..643b5e79271
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030730-1.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dom3" } */
+
+extern void *ggc_alloc (__SIZE_TYPE__);
+typedef struct dw_attr_struct *dw_attr_ref;
+typedef struct dw_attr_struct
+{
+ int dw_attr;
+}
+dw_attr_node;
+void
+foo (int attr_kind, unsigned long offset)
+{
+ dw_attr_ref attr = (dw_attr_ref) ggc_alloc (sizeof (dw_attr_node));
+ attr->dw_attr = attr_kind;
+ if (attr != 0)
+ exit (0);
+}
+
+/* There should be no IF conditionals. */
+/* { dg-final { scan-tree-dump-times "if " 0 "dom3"} } */
+
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030730-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030730-2.c
new file mode 100644
index 00000000000..06b5710f65f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030730-2.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dom3" } */
+
+extern void *ggc_alloc (__SIZE_TYPE__);
+typedef struct dw_attr_struct *dw_attr_ref;
+typedef struct dw_attr_struct
+{
+ int dw_attr;
+}
+dw_attr_node;
+void
+foo (int attr_kind, unsigned long offset)
+{
+ dw_attr_ref attr = (dw_attr_ref) ggc_alloc (sizeof (dw_attr_node));
+ attr->dw_attr = attr_kind;
+ if (attr != ((void *)0))
+ exit (0);
+}
+
+/* There should be no IF conditionals. */
+/* { dg-final { scan-tree-dump-times "if " 0 "dom3"} } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030731-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030731-1.c
new file mode 100644
index 00000000000..82634da1c5b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030731-1.c
@@ -0,0 +1,65 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+
+struct rtx_def;
+typedef struct rtx_def *rtx;
+struct rtvec_def;
+typedef struct rtvec_def *rtvec;
+union tree_node;
+typedef union tree_node *tree;
+struct rtx_def
+{
+ int code;
+ int mode;
+ unsigned int in_struct:1;
+};
+struct tree_common
+{
+ int code;
+};
+struct tree_decl
+{
+ rtx rtl;
+};
+union tree_node
+{
+ struct tree_common common;
+ struct tree_decl decl;
+};
+rtx
+store_expr (exp, target, want_value)
+ tree exp;
+ rtx target;
+ int want_value;
+{
+ if (exp->common.code == 42)
+ abort ();
+ else if (queued_subexp_p (target))
+ {
+ blah (target->mode);
+ if (target->code)
+ abort ();
+ }
+ else
+ {
+ if (target->code && (__extension__({target;})->in_struct));
+ }
+
+ if ((target != (exp->decl.rtl
+ ? (exp->decl.rtl
+ ? exp->decl.rtl
+ : (make_decl_rtl (exp, 0), exp->decl.rtl))
+ : 0))
+ && expr_size (exp))
+ ;
+}
+
+/* All paths to the test "target != 0" occuring in the final IF statement
+ dereference target. Thus target can not have the value zero at that
+ point and the test should have been eliminated. */
+/* ??? The dominator walker (A) doesn't merge this data at joins and
+ (B) only looks at immediate dominators, and only queued_subexp_p
+ immediately dominates the comparison in question. We need something
+ stronger. */
+/* { dg-final { scan-tree-dump-times "target.*!= 0" 0 "dom3" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030731-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030731-2.c
new file mode 100644
index 00000000000..b088f007447
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030731-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-ccp" } */
+
+
+bar (int i, int partial, int args_addr)
+{
+ int offset = 0;
+ if (args_addr == 0)
+ offset = 0;
+ if (i >= offset)
+ foo ();
+}
+
+/* There should be only one IF conditional since the first does nothing
+ useful. */
+/* { dg-final { scan-tree-dump-times "if " 1 "ccp"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030807-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030807-1.c
new file mode 100644
index 00000000000..ab013d3d9fc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030807-1.c
@@ -0,0 +1,46 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+struct rtx_def;
+typedef struct rtx_def *rtx;
+
+
+
+union rtunion_def
+{
+ int rtint;
+};
+typedef union rtunion_def rtunion;
+
+
+
+struct rtx_def
+{
+ rtunion fld[1];
+
+};
+
+static int *uid_cuid;
+static int max_uid_cuid;
+
+static rtx
+bar (rtx r)
+{
+ rtx place = r;
+
+ if (place->fld[0].rtint <= max_uid_cuid
+ && (place->fld[0].rtint > max_uid_cuid ? insn_cuid (place) :
+ uid_cuid[place->fld[0].rtint]))
+ return r;
+
+ return 0;
+}
+
+/* There should be two IF conditionals. One tests <= max_uid_cuid, the
+ other tets the value in uid_cuid. If either is false the jumps
+ are threaded to the return 0. Which in turn means the path
+ which combines the result of those two tests into a new test
+ must always be true and it is optimized appropriately. */
+/* { dg-final { scan-tree-dump-times "if " 2 "dom3"} } */
+
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030807-10.c b/gcc/testsuite/gcc.dg/tree-ssa/20030807-10.c
new file mode 100644
index 00000000000..709395511a4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030807-10.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+
+extern const unsigned char mode_size[];
+unsigned int
+subreg_highpart_offset (outermode, innermode)
+ int outermode, innermode;
+{
+ unsigned int offset = 0;
+ int difference = (mode_size[innermode] - mode_size[outermode]);
+ if (difference > 0)
+ {
+ offset += difference % (0 ? 8 : 4);
+ offset += difference / 4 * 4;
+ }
+ return offset;
+}
+
+/* There should be one mask with the value 3. */
+/* { dg-final { scan-tree-dump-times " \& 3" 1 "dom3"} } */
+
+/* There should be one right shift by 2 places. */
+/* { dg-final { scan-tree-dump-times " >> 2" 1 "dom3"} } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030807-11.c b/gcc/testsuite/gcc.dg/tree-ssa/20030807-11.c
new file mode 100644
index 00000000000..6296346095d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030807-11.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+struct rtx_def;
+typedef struct rtx_def *rtx;
+struct rtx_def
+{
+ int code;
+};
+foo (reg)
+ rtx reg;
+{
+ reg->code = 42;
+ if (reg->code != 42)
+ abort ();
+}
+
+/* There should be no IF conditionals. */
+/* { dg-final { scan-tree-dump-times "if " 0 "dom3"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030807-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030807-2.c
new file mode 100644
index 00000000000..e9837d38814
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030807-2.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+
+oof ()
+{
+ int live_head;
+ int * live = &live_head;
+
+ if (live)
+ bitmap_clear (live);
+}
+
+foo(int n)
+{
+ int *space = (int *)__builtin_alloca (n);
+
+ if (space == 0)
+ abort ();
+ else
+ bar (space);
+}
+
+
+/* There should be no IF conditionals. */
+/* { dg-final { scan-tree-dump-times "if " 0 "dom3"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030807-3.c b/gcc/testsuite/gcc.dg/tree-ssa/20030807-3.c
new file mode 100644
index 00000000000..7e10d382c4e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030807-3.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+typedef unsigned int cppchar_t;
+cppchar_t
+cpp_parse_escape (pstr, limit, wide)
+ const unsigned char **pstr;
+ const unsigned char *limit;
+ int wide;
+{
+ cppchar_t i = 0;
+ int overflow = 0;
+ cppchar_t mask = ~0;
+
+ while (*pstr < limit)
+ {
+ overflow |= i ^ (i << 4 >> 4);
+ i = oof ();
+ }
+ if (overflow | (i != (i & mask)))
+ foo();
+}
+
+/* There should be precisely three IF statements. If there is
+ more than two, then the dominator optimizations failed. */
+/* { dg-final { scan-tree-dump-times "if " 3 "dom3"} } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030807-5.c b/gcc/testsuite/gcc.dg/tree-ssa/20030807-5.c
new file mode 100644
index 00000000000..b530c841a7f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030807-5.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+struct rtx_def;
+typedef struct rtx_def *rtx;
+
+
+struct rtx_def
+{
+
+ int code;
+ unsigned int unchanging:1;
+
+};
+static rtx current_sym_addr;
+
+static int
+foo ()
+{
+ if (current_sym_addr->code == 42
+ && (({
+ rtx _rtx = current_sym_addr;
+ if (((_rtx)->code) != 42)
+ abort ();
+ _rtx;}
+ )->unchanging))
+ return 0;
+}
+
+/* There should be precisely one load of ->code. If there is
+ more than, then the dominator optimizations failed. */
+/* { dg-final { scan-tree-dump-times "->code" 1 "dom3"} } */
+
+/* There should be two IF statements. One for 'current_sym_addr->code == 42'.
+ The other one for '(EXPR)->unchanging'. */
+/* { dg-final { scan-tree-dump-times "if " 2 "dom3"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030807-6.c b/gcc/testsuite/gcc.dg/tree-ssa/20030807-6.c
new file mode 100644
index 00000000000..3b24bcaf662
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030807-6.c
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+
+static void
+foo (distance, i, j)
+ int distance[13][13];
+ int i, j;
+{
+ if (distance[i][j] < 0)
+ distance[i][0] = ((distance[i][j]) < 0 ? -(distance[i][j]) : (distance[i][j]));
+}
+
+static void
+foo2 (distance, i, j)
+ int distance[13][13];
+ int i, j;
+{
+ if (distance[i][j] <= 0)
+ distance[i][0] = ((distance[i][j]) < 0 ? -(distance[i][j]) : (distance[i][j]));
+}
+
+static void
+foo3 (distance, i, j)
+ int distance[13][13];
+ int i, j;
+{
+ if (distance[i][j] > 0)
+ distance[i][0] = ((distance[i][j]) < 0 ? -(distance[i][j]) : (distance[i][j]));
+}
+
+static void
+foo4 (distance, i, j)
+ double distance[13][13];
+ int i, j;
+{
+ if (distance[i][j] >= 0)
+ distance[i][0] = ((distance[i][j]) < 0 ? -(distance[i][j]) : (distance[i][j]));
+}
+
+/* There should be no ABS_EXPR. */
+/* { dg-final { scan-tree-dump-times "ABS_EXPR " 0 "dom3"} } */
+
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030807-7.c b/gcc/testsuite/gcc.dg/tree-ssa/20030807-7.c
new file mode 100644
index 00000000000..7f31578307a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030807-7.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dom3" } */
+
+
+
+union tree_node;
+typedef union tree_node *tree;
+struct tree_common
+{
+ int code;
+};
+struct tree_list
+{
+ tree purpose;
+};
+union tree_node
+{
+ struct tree_common common;
+ struct tree_list list;
+};
+void
+simplify_condition (cond_p)
+ tree *cond_p;
+{
+ tree decl;
+ tree cond = *cond_p;
+ if (cond->common.code != 42)
+ abort ();
+ decl = cond->list.purpose;
+ if (cond->common.code != 42)
+ abort ();
+ c_simplify_stmt (&decl);
+}
+
+/* There should be exactly one IF conditional. TBAA is not able to
+ determine that 'decl' and 'cond' can't alias. */
+/* { dg-final { scan-tree-dump-times "if " 1 "dom3"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030807-8.c b/gcc/testsuite/gcc.dg/tree-ssa/20030807-8.c
new file mode 100644
index 00000000000..1241f32a7f8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030807-8.c
@@ -0,0 +1,52 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+struct die_struct;
+typedef struct die_struct *dw_die_ref;
+typedef struct dw_loc_list_struct *dw_loc_list_ref;
+enum dw_val_class
+{
+ dw_val_class_loc_list,
+};
+typedef struct dw_val_struct
+{
+ enum dw_val_class val_class;
+ union dw_val_struct_union
+ {
+ dw_loc_list_ref val_loc_list;
+ }
+ v;
+}
+dw_val_node;
+typedef struct dw_attr_struct *dw_attr_ref;
+typedef struct dw_attr_struct
+{
+ dw_val_node dw_attr_val;
+}
+dw_attr_node;
+
+extern __inline__ enum dw_val_class
+AT_class (a)
+ dw_attr_ref a;
+{
+ return a->dw_attr_val.val_class;
+}
+extern __inline__ dw_loc_list_ref
+AT_loc_list (a)
+ dw_attr_ref a;
+{
+ if (AT_class (a) == dw_val_class_loc_list)
+ return a->dw_attr_val.v.val_loc_list;
+}
+static void
+output_location_lists (die)
+ dw_die_ref die;
+{
+ dw_die_ref c;
+ dw_attr_ref d_attr;
+ if (AT_class (d_attr) == dw_val_class_loc_list)
+ output_loc_list (AT_loc_list (d_attr));
+}
+
+/* There should be exactly one IF conditional, in output_location_lists. */
+/* { dg-final { scan-tree-dump-times "if " 1 "dom3"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030807-9.c b/gcc/testsuite/gcc.dg/tree-ssa/20030807-9.c
new file mode 100644
index 00000000000..6144bd187ed
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030807-9.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+static void
+bar ()
+{
+ const char *label2 = (*"*.L_sfnames_b" == '*') + "*.L_sfnames_b";
+ oof (label2);
+}
+
+void
+ooof ()
+{
+ if (""[0] == 0)
+ foo();
+}
+
+/* There should be no IF conditionals. */
+/* { dg-final { scan-tree-dump-times "if " 0 "dom3"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030808-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030808-1.c
new file mode 100644
index 00000000000..08f8f15f706
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030808-1.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-cddce" } */
+
+
+struct rtx_def;
+typedef struct rtx_def *rtx;
+enum rtx_code
+{
+ UNKNOWN,
+ CODE_LABEL,
+ NOTE,
+ LAST_AND_UNUSED_RTX_CODE = 256
+};
+typedef union rtunion_def rtunion;
+struct rtx_def
+{
+ enum rtx_code code:16;
+};
+void
+delete_dead_jumptables ()
+{
+ rtx insn, next;
+ if (insn->code == CODE_LABEL)
+ {
+ rtx const _rtx = insn;
+ if (_rtx->code != CODE_LABEL && _rtx->code != NOTE)
+ abort ();
+ }
+ ;
+}
+
+/* There should be no loads of ->code. If any exist, then we failed to
+ optimize away all the IF statements and the statements feeding
+ their conditions. */
+/* { dg-final { scan-tree-dump-times "->code" 0 "cddce"} } */
+
+/* There should be no IF statements. */
+/* { dg-final { scan-tree-dump-times "if " 0 "cddce"} } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030814-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030814-1.c
new file mode 100644
index 00000000000..d165b19bfda
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030814-1.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+
+com(int *blah)
+{
+ int z = *blah;
+ if (z == 256)
+ {
+ oof (z);
+ abort ();
+ }
+ return *blah;
+}
+
+/* There should be precisely one load of blah. If there is
+ more than one, then the dominator optimizations failed. */
+/* { dg-final { scan-tree-dump-times "\\*blah" 1 "dom3"} } */
+
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030814-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030814-2.c
new file mode 100644
index 00000000000..a3f2ae6b70b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030814-2.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+
+void
+foo (int value)
+{
+ switch (value)
+ {
+ case 42:
+ if (value != 42)
+ abort ();
+ case 50:
+ blah ();
+ }
+}
+
+/* There should be no IF conditionals. */
+/* { dg-final { scan-tree-dump-times "if " 0 "dom3"} } */
+
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030814-3.c b/gcc/testsuite/gcc.dg/tree-ssa/20030814-3.c
new file mode 100644
index 00000000000..2058c0c987a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030814-3.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+
+void
+foo (int value)
+{
+ switch (value)
+ {
+ case 40:
+ case 42:
+ if (value != 42)
+ abort ();
+ case 50:
+ blah ();
+ }
+}
+
+/* There should be one IF conditional. */
+/* { dg-final { scan-tree-dump-times "if " 1 "dom3"} } */
+
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030814-4.c b/gcc/testsuite/gcc.dg/tree-ssa/20030814-4.c
new file mode 100644
index 00000000000..81711dd75cd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030814-4.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3 -fdump-tree-optimized" } */
+
+union tree_node;
+typedef union tree_node *tree;
+extern const char tree_code_type[];
+struct tree_common
+{
+ int code;
+};
+struct tree_decl
+{
+ long pointer_alias_set;
+};
+union tree_node
+{
+ struct tree_common common;
+ struct tree_decl decl;
+};
+long
+blah (decl, set)
+ tree decl;
+ long set;
+{
+ decl->decl.pointer_alias_set = set;
+ if (tree_code_type[decl->common.code] != 'd')
+ abort ();
+ record_alias_subset (decl->decl.pointer_alias_set);
+ if (set != -1)
+ set = 0;
+ return set;
+}
+
+/* There should be precisely one reference to pointer_alias_set. If there is
+ more than one, then the dominator optimizations failed. */
+/* { dg-final { scan-tree-dump-times "pointer_alias_set" 1 "dom3"} } */
+
+/* The assignment set = -1 in the ELSE clause of the last IF
+ statement should be removed by the final cleanup phase. */
+/* { dg-final { scan-tree-dump-times "set = -1" 0 "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030814-5.c b/gcc/testsuite/gcc.dg/tree-ssa/20030814-5.c
new file mode 100644
index 00000000000..bab21a3cae8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030814-5.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3 -fdump-tree-optimized" } */
+
+union tree_node;
+typedef union tree_node *tree;
+extern const char tree_code_type[];
+struct tree_common
+{
+ int code;
+};
+struct tree_decl
+{
+ long pointer_alias_set;
+};
+union tree_node
+{
+ struct tree_common common;
+ struct tree_decl decl;
+};
+long
+blah (decl, set)
+ tree decl;
+ long set;
+{
+ decl->decl.pointer_alias_set = oof();
+ if (tree_code_type[decl->common.code] != 'd')
+ abort ();
+ record_alias_subset (decl->decl.pointer_alias_set);
+ if (set != -1)
+ set = 0;
+ return set;
+}
+
+/* There should be precisely one reference to pointer_alias_set. If there is
+ more than one, then the dominator optimizations failed. */
+/* { dg-final { scan-tree-dump-times "pointer_alias_set" 1 "dom3"} } */
+
+/* The assignment set = -1 in the ELSE clause of the last IF
+ statement should be removed by the final cleanup phase. */
+/* { dg-final { scan-tree-dump-times "set = -1" 0 "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030814-6.c b/gcc/testsuite/gcc.dg/tree-ssa/20030814-6.c
new file mode 100644
index 00000000000..c16fda9155c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030814-6.c
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+union tree_node;
+typedef union tree_node *tree;
+enum tree_code
+{
+ LAST_AND_UNUSED_TREE_CODE
+};
+extern const char tree_code_type[];
+struct tree_common
+{
+ enum tree_code code:8;
+};
+struct tree_type
+{
+ double alias_set;
+};
+union tree_node
+{
+ struct tree_common common;
+ struct tree_type type;
+};
+long
+foo (t, set)
+ tree t;
+ double set;
+{
+ if (tree_code_type[t->common.code] != 't')
+ abort ();
+
+ t->type.alias_set = set;
+
+ if (t->common.code == 42)
+ return 1;
+ else
+ return 0;
+}
+/* There should be precisely one load of common.code. If there is
+ more than one, then the dominator optimizations failed. */
+/* ??? Will fail until we properly distinguish member stores. At
+ present the write to type.alias_set kills the previous load. */
+/* { dg-final { scan-tree-dump-times "common.code" 1 "dom3" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030814-7.c b/gcc/testsuite/gcc.dg/tree-ssa/20030814-7.c
new file mode 100644
index 00000000000..cbefbb33c1a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030814-7.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+struct rtx_def;
+typedef struct rtx_def *rtx;
+struct rtvec_def;
+typedef struct rtvec_def *rtvec;
+union tree_node;
+typedef union tree_node *tree;
+struct tree_common
+{
+ int code;
+};
+union tree_node
+{
+ struct tree_common common;
+};
+extern tree current_function_decl;
+struct cgraph_rtl_info
+{
+ _Bool pure_function;
+};
+struct cgraph_rtl_info *cgraph_rtl_info (tree);
+void
+mark_constant_function (void)
+{
+ rtx insn;
+ int nonlocal_memory_referenced;
+
+ if (current_function_decl->common.code != 42)
+ abort ();
+
+ cgraph_rtl_info (current_function_decl)->pure_function = 1;
+}
+
+/* current_function_decl should be loaded once into a temporary
+ and the temporary used as the argument to cgraph_rtl_info.
+ This if we find current_function_decl used as an argument, then
+ we have failed. */
+/* { dg-final { scan-tree-dump-times "\\(current_function_decl\\)" 0 "dom3"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030815-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030815-1.c
new file mode 100644
index 00000000000..13a4917e912
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030815-1.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+typedef unsigned int size_t;
+struct rtx_def;
+typedef struct rtx_def *rtx;
+typedef union varray_data_tag
+{
+ struct reg_info_def *reg[1];
+} varray_data;
+struct varray_head_tag
+{
+ size_t num_elements;
+ varray_data data;
+};
+typedef struct varray_head_tag *varray_type;
+typedef struct reg_info_def
+{
+} reg_info;
+extern varray_type reg_n_info;
+static rtx *reg_base_value;
+static rtx *new_reg_base_value;
+static rtx
+blah (unsigned int regno)
+{
+ if (new_reg_base_value[regno] && ((*(
+ {
+ if (regno >=
+ reg_n_info->
+ num_elements)
+ abort ();
+ &reg_n_info->data.reg[regno];}
+ ))))
+ return reg_base_value[regno];
+}
+
+/* If we have more than 1 cast to a struct rtx_def * *, then we failed to
+ eliminate some useless typecasting. The first type cast is needed
+ to convert the unsigned int regno parameter into a struct rtx_def **. */
+/* { dg-final { scan-tree-dump-times "\\(struct rtx_def \\* \\*\\)" 1 "dom3"} } */
+
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030820-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030820-1.c
new file mode 100644
index 00000000000..4b659ca3411
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030820-1.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+/* A test for unreachable blocks removal -- bind_expr whose entry is
+ unreachable, but it contains reachable statements. */
+
+void foo(void)
+{
+ if (1)
+ {
+ goto bla;
+ }
+ else
+ {
+xxx:
+ {
+bla:
+ bar ();
+ return;
+ }
+ goto xxx;
+ }
+}
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030820-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030820-2.c
new file mode 100644
index 00000000000..9ca9fbb59c6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030820-2.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+/* A test for variables getting out of their scope in copy propagation. */
+
+void foo(void)
+{
+ int k;
+
+ goto forward;
+back:
+ bla (k);
+ return;
+
+forward:
+ {
+ int i = bar ();
+
+ k = i;
+
+ goto back;
+ }
+}
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030821-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030821-1.c
new file mode 100644
index 00000000000..2d1e9e78df2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030821-1.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+void foo(int k)
+{
+ int i = 1;
+ void *label;
+
+ label = k ? &&x : &&y;
+
+ if (k == 1)
+ goto *label;
+
+ i = 0;
+ goto z;
+z:
+x:
+ if (i)
+ dont_remove ();
+y: ;
+}
+
+/* { dg-final { scan-tree-dump-times "dont_remove \\(\\)" 1 "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030824-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030824-1.c
new file mode 100644
index 00000000000..328d33d1243
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030824-1.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+struct A
+{
+ int a,b;
+};
+
+int foo (int x, int y)
+{
+ int i, j;
+ struct A a,b;
+
+ a.a = x;
+ b.b = y;
+ j = a.a;
+ i = b.b;
+ return i + j;
+}
+
+/* The addition should be optimized into 'y+x'. */
+/* { dg-final { scan-tree-dump-times "y \\+ x" 1 "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030824-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030824-2.c
new file mode 100644
index 00000000000..5ed66d094a0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030824-2.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+struct A
+{
+ int a,b;
+};
+
+int foo (int x, int y)
+{
+ int i, j;
+ struct A a;
+
+ a.a = x;
+ a.b = y;
+ j = a.a;
+ i = a.b;
+ return i + j;
+}
+
+/* This function should be optimized into 'return y+x'. */
+/* { dg-final { scan-tree-dump-times "return y \\+ x" 1 "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030825-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030825-1.c
new file mode 100644
index 00000000000..440f75571d4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030825-1.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+void bla(void);
+
+void
+foo(int c, int d)
+{
+ goto skip;
+
+ebef:
+ goto xxx;
+
+skip:
+
+ if (c)
+ {
+xxx:;
+ if (!c)
+ bla ();
+ }
+
+ if (d)
+ goto ebef;
+}
+
+/* Bla should not be optimized away. */
+/* { dg-final { scan-tree-dump-times "bla" 1 "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030907-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030907-1.c
new file mode 100644
index 00000000000..3bc5557cf00
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030907-1.c
@@ -0,0 +1,26 @@
+/* PR optimization/12198
+
+ This was a miscompilation of a switch expressions because
+ the "Case Ranges" extension wasn't handled in tree-cfg.c. */
+
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+int main()
+{
+ int i;
+ i = 2;
+ switch (i)
+ {
+ case 1 ... 5:
+ goto L1;
+ default:
+ abort ();
+ goto L1;
+ }
+ L1:
+ exit(0);
+}
+
+/* The abort() call clearly is unreachable. */
+/* { dg-final { scan-tree-dump-times "abort" 0 "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030907-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030907-2.c
new file mode 100644
index 00000000000..47d60946e0c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030907-2.c
@@ -0,0 +1,30 @@
+/* PR optimization/12109
+
+ This would ICE in tree-ssa-dce.c:process_worklist() when
+ the function was expecting an SSA_NAME but found a VAR_DECL. */
+
+/* { dg-do compile } */
+/* { dg-options "-O -ftree-dce" } */
+
+void *do_it(void * dest, const void * src);
+double *create_float(void);
+
+void parse_rvalue(void **DataPtr)
+{
+ double local = 0.0;
+ int terms = 1;
+
+ *DataPtr = create_float();
+
+ switch (terms)
+ {
+ case 1:
+ *((double *)*DataPtr) = local;
+ break;
+
+ case 2:
+ do_it(*DataPtr, &local);
+ break;
+ }
+}
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030917-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030917-1.c
new file mode 100644
index 00000000000..1b1441f0f9b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030917-1.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-ccp" } */
+
+
+extern int board[];
+
+void
+findbestextension (int blah, int blah2)
+{
+ int defval;
+ defval = def_val (board[blah2]);
+ if (blah)
+ defval = 0;
+ foo (defval);
+}
+
+/* The argument to "foo" should be a variable, not a constant. */
+/* { dg-final { scan-tree-dump-times "foo .defval" 1 "ccp"} } */
+
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030917-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030917-2.c
new file mode 100644
index 00000000000..2c08050c975
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030917-2.c
@@ -0,0 +1,40 @@
+/* This test was causing an ICE in DCE because we were allowing void *
+ pointers to have a memory tag, which we were copying when doing copy
+ propagation. Since void * can never be de-referenced, its memory tag
+ was never renamed. */
+
+/* { dg-do compile } */
+/* { dg-options "-O -ftree-dominator-opts" } */
+
+typedef __SIZE_TYPE__ size_t;
+typedef union tree_node *tree;
+struct operands_d
+{
+ tree *def_op;
+};
+
+void
+gt_ggc_mx_operands_d (void *x_p)
+{
+ struct operands_d *const x = (struct operands_d *) x_p;
+ if ((*x).def_op != ((void *) 0))
+ {
+ size_t i0;
+ do
+ {
+ const void *const a__ = ((*x).def_op);
+ if (a__ != ((void *) 0) && a__ != (void *) 1)
+ ggc_set_mark (a__);
+ }
+ while (0);
+ for (i0 = 0; i0 < (size_t) (1); i0++)
+ {
+ do
+ {
+ if ((void *) (*x).def_op[i0] != ((void *) 0))
+ gt_ggc_mx_lang_tree_node ((*x).def_op[i0]);
+ }
+ while (0);
+ }
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030917-3.c b/gcc/testsuite/gcc.dg/tree-ssa/20030917-3.c
new file mode 100644
index 00000000000..f7fabe5008c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030917-3.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fno-tree-dominator-opts -fdump-tree-ccp" } */
+
+
+main ()
+{
+ int variable = 0;
+ int p = 1;
+ while (1)
+ {
+ if (p)
+ break;
+ variable = variable + 1;
+ if (variable == 10)
+ break;
+ }
+ printf("%d\n", variable);
+}
+
+
+/* The argument to "printf" should be a constant, not a variable. */
+/* { dg-final { scan-tree-dump-times "printf.*, 0" 1 "ccp"} } */
+
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030918-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030918-1.c
new file mode 100644
index 00000000000..719ea65f5bf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030918-1.c
@@ -0,0 +1,15 @@
+/* The compiler was failing to adjust pointer dereferences into array
+ references after propagating &equot[0] into p. */
+
+/* { dg-do compile } */
+/* { dg-options "-O -ftree-dominator-opts" } */
+
+static unsigned short equot[(6 +3)];
+int
+foo (num)
+ unsigned short num[];
+{
+ unsigned short *p = &equot[0];
+ *p++ = num[0];
+ *p++ = num[1];
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030920-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030920-1.c
new file mode 100644
index 00000000000..e27764aecda
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030920-1.c
@@ -0,0 +1,112 @@
+/* Jump threading was creating FALLTHRU edges out of blocks ending in
+ GOTO_EXPR. */
+
+extern int frame_pointer_needed;
+
+struct value_data_entry
+{
+ unsigned int mode;
+ unsigned int oldest_regno;
+ unsigned int next_regno;
+};
+
+struct value_data
+{
+ struct value_data_entry e[53];
+ unsigned int max_value_regs;
+};
+
+struct rtx_def
+{
+ unsigned int code: 16;
+ unsigned int mode : 8;
+ unsigned int jump : 1;
+ unsigned int call : 1;
+ unsigned int unchanging : 1;
+ unsigned int volatil : 1;
+ unsigned int in_struct : 1;
+ unsigned int used : 1;
+ unsigned integrated : 1;
+ unsigned frame_related : 1;
+ int fld[1];
+};
+
+typedef struct rtx_def *rtx;
+
+enum machine_mode { VOIDmode, BImode, QImode, HImode, SImode, DImode,
+ TImode, OImode, PQImode, PHImode, PSImode, PDImode, QFmode, HFmode,
+ TQFmode, SFmode, DFmode, XFmode, TFmode, QCmode, HCmode, SCmode,
+ DCmode, XCmode, TCmode, CQImode, CHImode, CSImode, CDImode, CTImode,
+ COImode, V1DImode, V2QImode, V2HImode, V2SImode, V2DImode, V4QImode,
+ V4HImode, V4SImode, V4DImode, V8QImode, V8HImode, V8SImode, V8DImode,
+ V16QImode, V2HFmode, V2SFmode, V2DFmode, V4HFmode, V4SFmode, V4DFmode,
+ V8HFmode, V8SFmode, V8DFmode, V16SFmode, BLKmode, CCmode, CCGCmode,
+ CCGOCmode, CCNOmode, CCZmode, CCFPmode, CCFPUmode, MAX_MACHINE_MODE };
+
+enum mode_class { MODE_RANDOM, MODE_INT, MODE_FLOAT, MODE_PARTIAL_INT, MODE_CC,
+ MODE_COMPLEX_INT, MODE_COMPLEX_FLOAT,
+ MODE_VECTOR_INT, MODE_VECTOR_FLOAT,
+ MAX_MODE_CLASS};
+
+extern const unsigned char mode_size[(int) MAX_MACHINE_MODE];
+extern const enum mode_class mode_class[(int) MAX_MACHINE_MODE];
+
+extern int target_flags;
+
+static void
+copy_value (rtx dest, rtx src, struct value_data *vd)
+{
+ unsigned int dr = (((dest)->fld[0]));
+ unsigned int sr = (((src)->fld[0]));
+ unsigned int dn, sn;
+ unsigned int i;
+
+
+
+ if (sr == dr)
+ return;
+
+
+
+ if (dr == 7)
+ return;
+
+
+ if (frame_pointer_needed && dr == 6)
+ return;
+
+
+ dn = (((dr) >= 8 && (dr) <= (8 + 7)) || (((dr) >= (20 + 1) && (dr) <= ((20 + 1) + 7)) || ((dr) >= (((((((20 + 1) + 7) + 1) + 7) + 1) + 7) + 1) && (dr) <= ((((((((20 + 1) + 7) + 1) + 7) + 1) + 7) + 1) + 7))) || ((dr) >= (((20 + 1) + 7) + 1) && (dr) <= ((((20 + 1) + 7) + 1) + 7)) ? (((mode_class[(int) (((enum machine_mode) (dest)->mode))]) == MODE_COMPLEX_INT || (mode_class[(int) (((enum machine_mode) (dest)->mode))]) == MODE_COMPLEX_FLOAT) ? 2 : 1) : ((((enum machine_mode) (dest)->mode)) == TFmode ? ((target_flags & 0x00100000) ? 2 : 3) : (((enum machine_mode) (dest)->mode)) == TCmode ? ((target_flags & 0x00100000) ? 4 : 6) : (((mode_size[(int) (((enum machine_mode) (dest)->mode))]) + ((target_flags & 0x00100000) ? 8 : 4) - 1) / ((target_flags & 0x00100000) ? 8 : 4))));
+ sn = (((sr) >= 8 && (sr) <= (8 + 7)) || (((sr) >= (20 + 1) && (sr) <= ((20 + 1) + 7)) || ((sr) >= (((((((20 + 1) + 7) + 1) + 7) + 1) + 7) + 1) && (sr) <= ((((((((20 + 1) + 7) + 1) + 7) + 1) + 7) + 1) + 7))) || ((sr) >= (((20 + 1) + 7) + 1) && (sr) <= ((((20 + 1) + 7) + 1) + 7)) ? (((mode_class[(int) (((enum machine_mode) (dest)->mode))]) == MODE_COMPLEX_INT || (mode_class[(int) (((enum machine_mode) (dest)->mode))]) == MODE_COMPLEX_FLOAT) ? 2 : 1) : ((((enum machine_mode) (dest)->mode)) == TFmode ? ((target_flags & 0x00100000) ? 2 : 3) : (((enum machine_mode) (dest)->mode)) == TCmode ? ((target_flags & 0x00100000) ? 4 : 6) : (((mode_size[(int) (((enum machine_mode) (dest)->mode))]) + ((target_flags & 0x00100000) ? 8 : 4) - 1) / ((target_flags & 0x00100000) ? 8 : 4))));
+ if ((dr > sr && dr < sr + sn)
+ || (sr > dr && sr < dr + dn))
+ return;
+
+
+
+
+ if (vd->e[sr].mode == VOIDmode)
+ set_value_regno (sr, vd->e[dr].mode, vd);
+ else if (sn < (unsigned int) (((sr) >= 8 && (sr) <= (8 + 7)) || (((sr) >= (20 + 1) && (sr) <= ((20 + 1) + 7)) || ((sr) >= (((((((20 + 1) + 7) + 1) + 7) + 1) + 7) + 1) && (sr) <= ((((((((20 + 1) + 7) + 1) + 7) + 1) + 7) + 1) + 7))) || ((sr) >= (((20 + 1) + 7) + 1) && (sr) <= ((((20 + 1) + 7) + 1) + 7)) ? (((mode_class[(int) (vd->e[sr].mode)]) == MODE_COMPLEX_INT || (mode_class[(int) (vd->e[sr].mode)]) == MODE_COMPLEX_FLOAT) ? 2 : 1) : ((vd->e[sr].mode) == TFmode ? ((target_flags & 0x00100000) ? 2 : 3) : (vd->e[sr].mode) == TCmode ? ((target_flags & 0x00100000) ? 4 : 6) : (((mode_size[(int) (vd->e[sr].mode)]) + ((target_flags & 0x00100000) ? 8 : 4) - 1) / ((target_flags & 0x00100000) ? 8 : 4))))
+ && ((mode_size[(int) (vd->e[sr].mode)]) > ((target_flags & 0x00100000) ? 8 : 4)
+ ? 0 : 0))
+ return;
+
+
+
+
+ else if (sn > (unsigned int) (((sr) >= 8 && (sr) <= (8 + 7)) || (((sr) >= (20 + 1) && (sr) <= ((20 + 1) + 7)) || ((sr) >= (((((((20 + 1) + 7) + 1) + 7) + 1) + 7) + 1) && (sr) <= ((((((((20 + 1) + 7) + 1) + 7) + 1) + 7) + 1) + 7))) || ((sr) >= (((20 + 1) + 7) + 1) && (sr) <= ((((20 + 1) + 7) + 1) + 7)) ? (((mode_class[(int) (vd->e[sr].mode)]) == MODE_COMPLEX_INT || (mode_class[(int) (vd->e[sr].mode)]) == MODE_COMPLEX_FLOAT) ? 2 : 1) : ((vd->e[sr].mode) == TFmode ? ((target_flags & 0x00100000) ? 2 : 3) : (vd->e[sr].mode) == TCmode ? ((target_flags & 0x00100000) ? 4 : 6) : (((mode_size[(int) (vd->e[sr].mode)]) + ((target_flags & 0x00100000) ? 8 : 4) - 1) / ((target_flags & 0x00100000) ? 8 : 4)))))
+ return;
+
+
+
+ vd->e[dr].oldest_regno = vd->e[sr].oldest_regno;
+
+ for (i = sr; vd->e[i].next_regno != (~(unsigned int) 0); i = vd->e[i].next_regno)
+ continue;
+ vd->e[i].next_regno = dr;
+
+
+ validate_value_data (vd);
+
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030922-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030922-1.c
new file mode 100644
index 00000000000..8876071c81f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030922-1.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+
+
+union tree_node;
+typedef union tree_node *tree;
+enum tree_code
+{
+ BIND_EXPR,
+};
+struct tree_common
+{
+ enum tree_code code:8;
+};
+union tree_node
+{
+ struct tree_common common;
+};
+tree
+voidify_wrapper_expr (tree wrapper)
+{
+ switch (wrapper->common.code)
+ {
+ case BIND_EXPR:
+ if (wrapper->common.code != BIND_EXPR)
+ abort ();
+ }
+}
+
+
+/* There should be no IF conditionals. */
+/* { dg-final { scan-tree-dump-times "if " 0 "dom3"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030922-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030922-2.c
new file mode 100644
index 00000000000..322f3ab3891
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030922-2.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom1" } */
+
+struct rtx_def;
+typedef struct rtx_def *rtx;
+struct rtx_def
+{
+ int bb;
+};
+static int *block_to_bb;
+static int target_bb;
+static int
+rgn_rank (rtx insn1, rtx insn2)
+{
+ if (block_to_bb[insn1->bb] != block_to_bb[insn2->bb])
+ if (block_to_bb[insn2->bb] == target_bb
+ && block_to_bb[insn1->bb] != target_bb)
+ return 1;
+}
+
+/* There should be two IF conditionals. */
+/* { dg-final { scan-tree-dump-times "if " 2 "dom1" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031015-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20031015-1.c
new file mode 100644
index 00000000000..62772b7b939
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20031015-1.c
@@ -0,0 +1,16 @@
+/* With tree-ssa, gcc.dg/20000724-1.c failed because we missed
+ a VOP of x in the asm statement. */
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-alias-vops" } */
+
+struct s { int a; };
+
+int
+main(void)
+{
+ struct s x = { 0 };
+ asm volatile ("" : : "r" (&x) : "memory");
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "VDEF" 2 "alias" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031021-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20031021-1.c
new file mode 100644
index 00000000000..4534ef34fc8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20031021-1.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+struct A
+{
+ int i : 8;
+};
+
+signed char c1, c2;
+struct A a;
+
+int main()
+{
+ a.i = c1;
+ c2 = a.i;
+ return a.i;
+}
+
+/* We should only store to a.i, not load from it. */
+/* { dg-final { scan-tree-dump-times "a.i" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031022-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20031022-1.c
new file mode 100644
index 00000000000..546e6b00759
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20031022-1.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom1" } */
+
+typedef struct edge_def
+{
+ int z;
+} *edge;
+typedef struct basic_block_def
+{
+ edge pred;
+} *basic_block;
+extern struct basic_block_def entry_exit_blocks[2];
+void
+blah (int arf)
+{
+ edge e;
+ e = (&entry_exit_blocks[1])->pred;
+ for ( ; ;)
+ if (arf)
+ break;
+ commit_edge_insertions ();
+ e = (&entry_exit_blocks[1])->pred;
+ foo (e);
+}
+
+/* There should be two loads from entry_exit_blocks[1].pred. */
+/* { dg-final { scan-tree-dump-times "entry_exit_blocks.1..pred" 2 "dom1"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031031-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20031031-1.c
new file mode 100644
index 00000000000..baca2a00a94
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20031031-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+/* This program requires the SSA renamer to be run after the second DOM
+ pass. Test provided by Falk Hueffner as Bugzilla #12825. */
+
+struct floppy_raw_cmd {
+ int flags, track;
+} *raw_cmd, default_raw_cmd;
+
+void
+setup_format_params (void)
+{
+ raw_cmd = &default_raw_cmd;
+ raw_cmd->track = 0;
+ raw_cmd->flags = 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031106-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20031106-1.c
new file mode 100644
index 00000000000..eb312cea1e2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20031106-1.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+extern void link_error (void);
+
+/* Check for dead stores to an array. */
+
+void foo (int testarray[])
+{
+ testarray[0] = 0;
+ testarray[0]++;
+ if (testarray[0] != 1)
+ link_error ();
+}
+
+/* There should be only one reference to "testarray". */
+/* { dg-final { scan-tree-dump-times "testarray" 1 "optimized" { xfail *-*-* } } } */
+
+/* There should be no link_error calls. */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031106-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20031106-2.c
new file mode 100644
index 00000000000..da430dc5813
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20031106-2.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+extern void link_error (void);
+
+/* Check for dead stores to a struct. */
+
+struct s
+{
+ char d;
+ int a, b;
+ double m;
+};
+
+void foo (struct s* teststruct)
+{
+ teststruct->a = 0;
+ teststruct->a++;
+ if (teststruct->a != 1)
+ link_error ();
+}
+
+/* There should be only one reference to "teststruct". */
+/* { dg-final { scan-tree-dump-times "teststruct" 1 "optimized" { xfail *-*-* } } } */
+
+/* There should be no link_error calls. */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031106-3.c b/gcc/testsuite/gcc.dg/tree-ssa/20031106-3.c
new file mode 100644
index 00000000000..ee7cb8a009d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20031106-3.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+extern void link_error (void);
+
+/* Check for cprop on array elements. */
+
+void foo (int testarray[])
+{
+ testarray[0] = 0;
+ testarray[1] = 1;
+ testarray[0]++;
+ testarray[1]++;
+ if (testarray[0] != 1)
+ link_error ();
+ if (testarray[1] != 2)
+ link_error ();
+}
+
+/* There should be no link_error calls. */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031106-4.c b/gcc/testsuite/gcc.dg/tree-ssa/20031106-4.c
new file mode 100644
index 00000000000..a288dacee47
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20031106-4.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+extern void link_error (void);
+
+/* Check for cprop on fields of the same struct. */
+
+struct s
+{
+ char d;
+ int a, b;
+ double m;
+};
+
+
+void foo (struct s* r)
+{
+ r->a = 0;
+ r->b = 1;
+ r->a++;
+ r->b++;
+ if (r->a != 1)
+ link_error ();
+ if (r->b != 2)
+ link_error ();
+}
+
+/* There should be no link_error calls. */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031106-5.c b/gcc/testsuite/gcc.dg/tree-ssa/20031106-5.c
new file mode 100644
index 00000000000..e543939c77b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20031106-5.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+extern void link_error (void);
+
+/* Check for cprop on different fields of same type structs. */
+
+struct s
+{
+ char d;
+ int a, b;
+ double m;
+};
+
+void foo2 (struct s* r, struct s* p)
+{
+ r->a = 0;
+ p->b = 1;
+ r->a++;
+ p->b++;
+ if (r->a != 1)
+ link_error ();
+ if (p->b != 2)
+ link_error ();
+}
+
+/* There should be no link_error calls. */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031106-6.c b/gcc/testsuite/gcc.dg/tree-ssa/20031106-6.c
new file mode 100644
index 00000000000..39fb08b032a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20031106-6.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+extern void link_error (void);
+
+/* Check for copyprop on structs. */
+
+struct s
+{
+ char d;
+ int a, b;
+ double m;
+};
+
+struct s foo (struct s r)
+{
+ struct s temp_struct1;
+ struct s temp_struct2;
+ struct s temp_struct3;
+ temp_struct1 = r;
+ temp_struct2 = temp_struct1;
+ temp_struct3 = temp_struct2;
+ return temp_struct3;
+}
+
+/* There should be no references to any of "temp_struct*"
+ temporaries. */
+/* { dg-final { scan-tree-dump-times "temp_struct" 0 "optimized" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031113-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20031113-1.c
new file mode 100644
index 00000000000..a114379a7ad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20031113-1.c
@@ -0,0 +1,30 @@
+/* PR optimization/12640
+
+ We used to get into an infinite loop while trying to
+ figure out `strlen (resultString)'. This showed up as
+ a stack overflow while compiling tk. */
+
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+int i;
+
+static void
+SendEventProc (char *resultString)
+{
+ char *p;
+
+ resultString = "";
+ while (*p == '-')
+ {
+ if (p[2] == ' ')
+ {
+ resultString = p + 3;
+ }
+ }
+ for (;;)
+ {
+ i = strlen (resultString) + 1;
+ }
+}
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031216-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20031216-1.c
new file mode 100644
index 00000000000..d3d39df3b11
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20031216-1.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+extern void link_error (void);
+
+void
+foo (int b)
+{
+ int a;
+ a = b + 2;
+ a--;
+ a--;
+ if (a != b)
+ link_error ();
+}
+
+/* The comparison should be eliminated, there should be no reference
+ to link_error. */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040121-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040121-1.c
new file mode 100644
index 00000000000..6987e17d907
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040121-1.c
@@ -0,0 +1,27 @@
+
+
+/* Test that (p!=0) + (q!=0) is computed as int,
+ not boolean */
+/* { dg-options "-O3" } */
+/* { dg-do run } */
+char *foo(char *p, char *q) {
+ int x = (p !=0) + (q != 0);
+ if (x==2) return "a"; else return 0;
+}
+extern char *bar(char*, char*) __attribute__((noinline));
+char *bar(char *first, char *last)
+{
+ int y;
+ if (!first) return last;
+ if (!last) return first;
+ if (*first == 'a')
+ return foo(first, last);
+ return 0;
+}
+main() {
+ char *p = "a", *q = "b";
+ if (p)
+ if (bar(p,q))
+ return 0;
+ abort();
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c
new file mode 100644
index 00000000000..426e2eab51a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+extern void link_error (void);
+
+/*
+ test that a condition is propagated inside an if
+*/
+
+void test5 (int x)
+{
+ extern int foo (int);
+ if (x == 0)
+ foo (x);
+ else if (x == 0 )
+ link_error ();
+}
+
+void test55 (int x, int y)
+{
+ int u;
+ if (x == 5 && y)
+ {
+ u = x + 22;
+ if (u != 27)
+ link_error ();
+ }
+}
+
+/* There should be not link_error calls, if there is any the
+ optimization has failed */
+/* ??? Ug. This one may or may not fail based on how fold decides
+ that the && should be emitted (based on BRANCH_COST). Fix this
+ by teaching dom to look through && and register all components
+ as true. */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040209-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040209-1.c
new file mode 100644
index 00000000000..087715322b7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040209-1.c
@@ -0,0 +1,52 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wuninitialized" } */
+
+typedef union tree_node *tree;
+
+struct tree_common
+{
+ tree chain;
+};
+
+struct tree_decl
+{
+ struct tree_common common;
+ tree name;
+};
+
+
+union tree_node
+{
+ struct tree_common common;
+ struct tree_decl decl;
+};
+
+int pedantic;
+
+void
+finish_struct (tree t, tree fieldlist, tree attributes)
+{
+ union tree_node * x;
+
+ if (pedantic)
+ {
+ x = fieldlist;
+ if (x->decl.name == 0)
+ {
+ while (x)
+ x = x->common.chain;
+ foo (fieldlist);
+ }
+ }
+
+ x = fieldlist;
+ if (x)
+ {
+ do
+ {
+ x = x->common.chain;
+ } while (x != 0);
+ }
+
+ bar1 (&fieldlist);
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040210-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040210-1.c
new file mode 100644
index 00000000000..9eb7905aef0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040210-1.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-phiopt1-details" } */
+
+
+void abort(void);
+void exit(int);
+
+int x, y;
+
+static void
+init_xy(void)
+{
+ x = 3;
+ y = 2;
+}
+
+void
+test4(void)
+{
+ init_xy();
+ if ((x < y ? x++ : y++) != 2)
+ abort ();
+}
+
+int
+main(){
+ test4 ();
+ exit (0);
+}
+
+/* Should have no more than two ifs left after straightening. */
+/* { dg-final { scan-tree-dump-times "if " 2 "phiopt1"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040211-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040211-1.c
new file mode 100644
index 00000000000..5d6e07940a5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040211-1.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cddce" } */
+
+
+
+
+struct rtx_def;
+typedef struct rtx_def *rtx;
+extern const char rtx_class[];
+union rtunion_def
+{
+ rtx rtx;
+};
+typedef union rtunion_def rtunion;
+struct rtx_def
+{
+ int code;
+ rtunion fld[1];
+};
+static int
+can_move_up (rtx insn, int n_insns)
+{
+ while (n_insns > 0)
+ {
+ insn = (((insn)->fld[1]).rtx);
+ if (((rtx_class[(int) (((insn)->code))]) == 'i'))
+ n_insns--;
+ }
+ return n_insns <= 0;
+}
+int
+com (rtx insn, int blah)
+{
+ if (!can_move_up (insn, blah))
+ foo ();
+}
+
+/* Cddce cannot remove possibly infinite loops and there is no way how to
+ determine whether the loop in can_move_up ends. */
+/* { dg-final { scan-tree-dump "if " "cddce"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040216-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040216-1.c
new file mode 100644
index 00000000000..7585905a4da
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040216-1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dse1-details" } */
+
+foo(int *z, int *y, int xx)
+{
+ *z = 1;
+ if (xx)
+ xx = 20;
+ else
+ xx = 30;
+ *z = 2;
+ *z = 3;
+ return xx;
+}
+
+/* We should convert two COND_EXPRs into straightline code. */
+/* { dg-final { scan-tree-dump-times "Deleted dead store" 2 "dse1"} } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040302-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040302-1.c
new file mode 100644
index 00000000000..ef59b041030
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040302-1.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 --param global-var-threshold=0" } */
+
+/* Test for .GLOBAL_VAR not being renamed into SSA after alias analysis.
+ provided by Dale Johannesen in PR 14266. */
+
+void foo() { bar (); }
+main () { foo (); }
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040305-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040305-1.c
new file mode 100644
index 00000000000..2d098d50e1d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040305-1.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cddce -fdump-tree-forwprop1-details" } */
+
+int abarney[2];
+int afred[1];
+
+void foo(int edx, int eax)
+{
+ if (eax == 100)
+ {
+ if (edx == 1)
+ {
+ abarney[0] = 5;
+ abarney[1] = 6;
+ }
+ }
+ if (eax == 100)
+ {
+ if (-- edx == 0)
+ afred[0] = 2;
+ }
+}
+
+
+/* Verify that we did a forward propagation. */
+/* { dg-final { scan-tree-dump-times "Replaced" 1 "forwprop1"} } */
+
+/* After cddce we should have two IF statements remaining as the other
+ two tests can be threaded. */
+/* { dg-final { scan-tree-dump-times "if " 2 "cddce"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040313-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040313-1.c
new file mode 100644
index 00000000000..0ad144c03dd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040313-1.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+/* Test provided by Volker Reichelt in PR 14553. The redundant PHI
+ node elimination pass was not using the right API functions to
+ propagate pointers, which resulted in dereferenced pointers that
+ did not have memory tags associated with them. */
+
+void foo(int* p)
+{
+ int i;
+ for (i=1; i>0; --i, ++p)
+ *p=0;
+}
+
+void bar(int* p) { foo(p); }
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040319-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040319-1.c
new file mode 100644
index 00000000000..571c2aeabad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040319-1.c
@@ -0,0 +1,25 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+/* Test derived from PR 14643. When a function has no addressable
+ variables but 2 or more pointers have conflicting memory tags, they
+ were not being processed by the type based alias analyzer,
+ resulting in optimizations removing a non-redundant load. */
+
+struct bar { int count; int *arr;};
+
+void foo (struct bar *b)
+{
+ b->count = 0;
+ *(b->arr) = 2;
+ if (b->count == 0) /* b->count can't be assumed to be 0 here. */
+ abort ();
+}
+
+main ()
+{
+ struct bar x;
+ x.arr = &x.count;
+ foo (&x);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040324-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040324-1.c
new file mode 100644
index 00000000000..15eb0d62381
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040324-1.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+/* Ensure that BIT_FIELD_REFs gets the appropriate VUSE.
+ Contributed by Paolo Bonzini <bonzini@gnu.org>.
+
+ This testcase actually never triggered in the CVS repo, but it did
+ in my local tree and it seems worth testing. In this test, the if's
+ are folded to BIT_FIELD_REFs but the VUSEs were erroneously left out.
+ Therefore, DOM did not see that i was modified between the two ifs
+ and optimized away the second if. */
+
+struct x
+{
+ unsigned b:1;
+ unsigned c:1;
+};
+
+struct x i = { 1, 1 };
+
+int
+main ()
+{
+ i.b = 1;
+ if (i.b == 1 && i.c == 0)
+ exit (0);
+ i.c = 0;
+ if (i.b == 1 && i.c == 0)
+ exit (0);
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040326-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040326-1.c
new file mode 100644
index 00000000000..c29655a24fd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040326-1.c
@@ -0,0 +1,29 @@
+/* { dg-options "-O2 -fno-inline-functions" } */
+/* { dg-do run } */
+/* When there are no call-clobbered variables, we should still create
+ a .GLOBAL_VAR to model the side effects of functions. Without it,
+ we were moving the call to Faref() inside the second call to
+ Faset(). */
+main ()
+{
+ int table, c, elt;
+ int tem = Faref (table, elt);
+ Faset (table, elt, c);
+ Faset (table, c, tem);/* tem cannot be replaced with Faref (table, elt) */
+ exit (0);
+}
+
+int j = 0;
+
+int __attribute__ ((noinline)) Faref (table, elt)
+{
+ j = 1;
+ return 0;
+}
+
+int __attribute__ ((noinline)) Faset (table, elt, c)
+{
+ if (j != 1)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040326-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20040326-2.c
new file mode 100644
index 00000000000..a3e16ad451e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040326-2.c
@@ -0,0 +1,63 @@
+/* { dg-options "-O2 -fno-inline-functions" } */
+/* { dg-do run } */
+
+/* Gimplification problem exposed by zsh. All the side-effects in
+ function arguments and in the called expression should happen
+ before the actual function call. */
+int A;
+
+typedef void (*fnptr) (void);
+fnptr *F;
+
+void
+foo (int x)
+{
+ if (A == x)
+ abort ();
+}
+
+void
+bar (int x, int y)
+{
+ if (x == 5 || y != 3)
+ abort ();
+}
+
+void
+boz (void)
+{
+ abort ();
+}
+
+void
+baz (void)
+{
+ if (*F != boz)
+ abort ();
+}
+
+fnptr B[2] = { baz, boz };
+
+main ()
+{
+ int b, c;
+
+ /* The gimplifier was emitting A++ after the call to foo. */
+ A = 5;
+ foo (A++);
+
+ /* The increment to 'b' and 'c' must happen before the call. However,
+ the first argument to bar() must be the original value of 'b', while
+ the second argument must be the new value of 'c'. */
+ b = 4;
+ c = 2;
+ bar (b++, ++c);
+
+ /* This call via function pointer *F should go to baz, but F should
+ be incremented before the actual call (i.e., right before the
+ call F should be pointing to boz). */
+ F = &B[0];
+ (*F++) ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040408-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040408-1.c
new file mode 100644
index 00000000000..6578be543a0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040408-1.c
@@ -0,0 +1,51 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* Make sure that when a variable with an NMT is marked for renaming
+ that the NMT's aliases are also marked for renaming. */
+
+static int eiisnan (short unsigned int *x)
+{
+ int i;
+
+ if( x[i] != 0 )
+ return(1);
+}
+
+static int eiisinf (unsigned short *x)
+{
+ if (eiisnan (x))
+ return (0);
+
+ if ((x[1] & 0x7fff) == 0x7fff)
+ return (1);
+}
+
+static void toe64(short unsigned int *a, short unsigned int *b)
+{
+ register unsigned short *p, *q;
+ unsigned short i;
+
+ q = b + 4;
+
+ if (eiisinf (a));
+
+ for( i=0; i<4; i++ )
+ *q-- = *p++;
+}
+
+static int asctoeg(short unsigned int *y, int oprec)
+{
+ unsigned short yy[13];
+ char *s;
+
+ while( *s == ' ' )
+ ++s;
+
+ toe64( yy, y );
+}
+
+long double _strtold (char *s, char **se)
+{
+ long double x;
+ asctoeg( (unsigned short *)&x, 64 );
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040430-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040430-1.c
new file mode 100644
index 00000000000..73ee8da85a6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040430-1.c
@@ -0,0 +1,25 @@
+/* PR middle-end/14470. Similar to
+ gcc.c-torture/execute/20040313-1.c, but with a compile time test to
+ make sure the second if() is removed. We should actually get rid
+ of the first if() too, but we're not that smart yet. */
+
+/* { dg-do run } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+
+extern void abort(void);
+
+int main()
+{
+ int t[1025] = { 1024 }, d;
+
+ d = 0;
+ d = t[d]++;
+ if (t[0] != 1025)
+ abort();
+ if (d != 1024)
+ abort();
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "if " 1 "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040513-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040513-1.c
new file mode 100644
index 00000000000..d53d81849fd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040513-1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-forwprop1" } */
+void bar (void);
+
+void
+foo (unsigned int a)
+{
+ if ((a >> 5) & 1)
+ bar ();
+}
+
+
+
+/* There should be no casts to a _Bool since we can use the temporary
+ holding (a>>5)&1 directly. */
+/* { dg-final { scan-tree-dump-times "\\(_Bool\\)" 0 "forwprop1"} } */
+
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040513-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20040513-2.c
new file mode 100644
index 00000000000..acd6c68652f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040513-2.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom2" } */
+int link_error(void);
+int s(void);
+
+int t(int i)
+{
+ _Bool g = i == 4;
+ int h = g;
+ _Bool j = h;
+ int k = j;
+ _Bool l = k == 0;
+ _Bool o = !l;
+ int m = o;
+
+ if (m)
+ if (i != 4)
+ return link_error();
+ return 0;
+}
+
+/* There should be no link_error calls, if there is any, the
+ optimization has failed */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "dom2"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040514-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040514-1.c
new file mode 100644
index 00000000000..51f4b0f2fc2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040514-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-phiopt1-details" } */
+
+int t( int i)
+{
+ int j;
+ if(i ==0)
+ {
+ j = 1;
+ goto end;
+ }
+ j = 0;
+end:
+ return j;
+
+/* Should have no ifs left after straightening. */
+/* { dg-final { scan-tree-dump-times "if " 0 "phiopt1"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040514-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20040514-2.c
new file mode 100644
index 00000000000..b651ae32cf9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040514-2.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom3" } */
+int
+foo2 (distance, i, j)
+ int distance;
+ int i, j;
+{
+ int t = distance;
+ if (t <= 0)
+ t = ((t) >= 0 ? (t) : -(t));
+ return t;
+}
+
+/* There should be no ABS_EXPR. */
+/* { dg-final { scan-tree-dump-times "ABS_EXPR " 0 "dom3"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/asm-1.c b/gcc/testsuite/gcc.dg/tree-ssa/asm-1.c
new file mode 100644
index 00000000000..ad92408f170
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/asm-1.c
@@ -0,0 +1,16 @@
+/* Make sure that gcc understands that an in/out operand is a use as well
+ as a def. */
+
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+void f()
+{
+ int i = 42;
+ int j = 63;
+
+ asm ("": "=m"(i), "+r"(j) : "m"(i));
+}
+
+/* { dg-final { scan-tree-dump-times "42" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "63" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cfgcleanup-1.c b/gcc/testsuite/gcc.dg/tree-ssa/cfgcleanup-1.c
new file mode 100644
index 00000000000..4d22a42814a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cfgcleanup-1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dce1" } */
+void
+cleanup (int a, int b)
+{
+ if (a)
+ if (b)
+ a = 1;
+ else
+ b = 1;
+ else if (a)
+ a = 1;
+ else
+ b = 1;
+ return;
+}
+/* Dce should get rid of the initializers and cfgcleanup should elliminate ifs */
+/* { dg-final { scan-tree-dump-times "if " 0 "dce1"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers.c b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers.c
new file mode 100644
index 00000000000..efe831beab5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ch-details" } */
+
+extern int foo (int);
+
+void bla (void)
+{
+ int i, n = foo (0);
+
+ for (i = 0; i < n; i++)
+ foo (i);
+}
+
+/* There should be a header scheduled for duplication. */
+/* { dg-final { scan-tree-dump-times "Scheduled" 1 "ch"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sra-1.c b/gcc/testsuite/gcc.dg/tree-ssa/sra-1.c
new file mode 100644
index 00000000000..652f402dc83
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/sra-1.c
@@ -0,0 +1,72 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+/* Tests for SRA. */
+
+typedef struct teststruct
+{
+ double d;
+ char f1;
+} teststruct;
+
+void
+copystruct1 (teststruct param)
+{
+ teststruct local;
+ param.f1 = 0;
+ local = param;
+ if (local.f1 != 0)
+ link_error ();
+}
+
+void
+copystruct11 (teststruct *param)
+{
+ teststruct local;
+ param->f1 = 0;
+ local = *param;
+ if (local.f1 != 0)
+ link_error ();
+}
+
+void
+copystruct111 (teststruct param)
+{
+ teststruct *local = &param;
+ param.f1 = 0;
+ if (local->f1 != 0)
+ link_error ();
+}
+
+teststruct globf;
+void
+copystruct1111 (void)
+{
+ teststruct local;
+ globf.f1 = 0;
+ local = globf;
+ if (local.f1 != 0)
+ link_error ();
+}
+
+void
+copystruct11111 (void)
+{
+ teststruct *local = &globf;
+ globf.f1 = 0;
+ if (local->f1 != 0)
+ link_error ();
+}
+
+void
+copystruct111111 (teststruct param)
+{
+ static teststruct local;
+ param.f1 = 0;
+ local = param;
+ if (local.f1 != 0)
+ link_error ();
+}
+
+/* There should be no referenc to link_error. */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sra-2.c b/gcc/testsuite/gcc.dg/tree-ssa/sra-2.c
new file mode 100644
index 00000000000..fa8bea51bc7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/sra-2.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+/* Test for SRA. */
+
+typedef struct teststruct
+{
+ double d;
+ char f1;
+} teststruct;
+
+
+void
+copystruct11 (teststruct *param)
+{
+ static teststruct local;
+ param->f1 = 0;
+ local = *param;
+ if (local.f1 != 0)
+ link_error ();
+}
+
+
+/* There should be no reference to link_error. */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sra-3.c b/gcc/testsuite/gcc.dg/tree-ssa/sra-3.c
new file mode 100644
index 00000000000..f6ffc575938
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/sra-3.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+/* Test for SRA. */
+
+typedef struct teststruct
+{
+ double d;
+ char f1;
+} teststruct;
+
+teststruct *globf1;
+
+extern void link_error (void);
+
+void
+copystruct1 (void)
+{
+ teststruct local;
+ globf1->f1 = 0;
+ local = *globf1;
+ if (local.f1 != 0)
+ link_error ();
+}
+
+/* There should be no reference to link_error. */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-1.c
new file mode 100644
index 00000000000..419cc95c71e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-1.c
@@ -0,0 +1,74 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-ccp" } */
+
+extern void link_error (void);
+
+/* check folding */
+
+void test1 (void)
+{
+ unsigned int l = 3 * 4 - 5 / 2;
+ if (l != 10)
+ link_error ();
+}
+
+void test11 (void)
+{
+ unsigned int l = (((((((3 / 2 + 2) * 4) & 7) ^ 3) % 8) << 2) + 1) >> 2;
+ if (l != 7)
+ link_error ();
+}
+
+/* cprop in a basic block */
+void test111 (void)
+{
+ unsigned int l0 = 3 / 2 + 2;
+ unsigned int l1 = l0 * 4;
+ unsigned int l2 = 7;
+ unsigned int l3 = l1 & l2;
+ unsigned int l4 = 3;
+ unsigned int l5 = l3 ^ l4;
+ unsigned int l6 = 8;
+ unsigned int l7 = l5 % l6;
+ unsigned int l8 = 2;
+ unsigned int l9 = l7 << l8;
+ unsigned int l10 = l9 + 1;
+ unsigned int l11 = l10 >> 2;
+ if (l11 != 7)
+ link_error ();
+}
+
+
+/* cprop after an if statement */
+void test1111 (int p)
+{
+ int l = 53;
+ if (p)
+ {
+ if ((67 + l - 25) != 95)
+ link_error ();
+ }
+ else
+ {
+ if ((93 - l + 25) != 65)
+ link_error ();
+ }
+}
+
+/* cprop after a loop */
+void test11111 (int p, int q, int r)
+{
+ int l = 53;
+ while (p < r)
+ {
+ if ((67 + l - 25) != 95)
+ link_error ();
+ p -= q;
+ }
+}
+
+
+
+/* There should be not link_error calls, if there is any the
+ optimization has failed */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "ccp"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-10.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-10.c
new file mode 100644
index 00000000000..091703a1017
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-10.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-fab" } */
+
+/* Check that we fold strlen of equally long strings, and that we do not
+ fail to terminate when there is a nontrivial cycle in the corresponding
+ ssa graph. */
+
+void foo(int i)
+{
+ char *s = "abcde";
+
+ if (i)
+ {
+ s = "defgh";
+ goto middle;
+ }
+
+start:
+
+ bla ();
+
+middle:
+
+ if (bla ())
+ goto start;
+
+ bar (strlen (s));
+}
+
+/* There should be no calls to strlen. */
+/* { dg-final { scan-tree-dump-times "strlen" 0 "fab"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-11.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-11.c
new file mode 100644
index 00000000000..b7f307964a6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-11.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+/* Test for CPROP across a DAG. */
+
+int test111 (int param)
+{
+ int a, b, c;
+ if (param) {
+ a = 3;
+ b = 2;
+ }
+ else {
+ a = 2;
+ b = 3;
+ }
+ c = a + b;
+ if (c != 5)
+ return 2;
+ return 0;
+}
+
+int test1111 (int param)
+{
+ _Bool a, b, c;
+ if (param) {
+ a = 1;
+ b = 0;
+ }
+ else {
+ a = 0;
+ b = 1;
+ }
+ c = a && b;
+ if (c)
+ return 2;
+ return 0;
+}
+
+/* All ifs should be eliminated. */
+/* { dg-final { scan-tree-dump-times "if" 0 "optimized" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-2.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-2.c
new file mode 100644
index 00000000000..b3c87fdc7b3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-2.c
@@ -0,0 +1,171 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-ccp" } */
+
+extern void link_error (void);
+
+
+/* check that cprop for variables of different types still works even
+ if function calls or assignments to different types of data are
+ interposed. */
+
+int test7 (int *intarr)
+{
+ extern int foo7 (int);
+ int u = 7, v1;
+ foo7 (u);
+ v1 = u;
+ if (v1 != 7)
+ link_error ();
+ return v1;
+}
+
+int test77 (int *arr)
+{
+ int u = 7, v1;
+ arr[0] = 4;
+ v1 = u;
+ if (v1 != 7)
+ link_error ();
+ return v1 + arr[0];
+}
+
+int test777 (void)
+{
+ extern int foo(int *);
+ int u = 7, v1;
+ static int sarr[10];
+ sarr[0] = 4;
+ v1 = u;
+ if (v1 != 7)
+ link_error ();
+ foo (sarr);
+ return v1 + sarr[0];
+}
+
+int garr[10];
+int test7777 (void)
+{
+ int u = 7, v1;
+ garr[0] = 4;
+ v1 = u;
+ if (v1 != 7)
+ link_error ();
+ return v1 + garr[0];
+}
+
+int test88 (int *arr)
+{
+ static int l;
+ int v1;
+ l = 8;
+ arr[0] = 4;
+ v1 = l;
+ if (v1 != 8)
+ link_error ();
+ l = foo88 (l);
+ return v1 + arr[0];
+}
+
+int test888 (void)
+{
+ static int l;
+ extern int foo(int *);
+ int v1;
+ static int sarr[10];
+ l = 8;
+ sarr[0] = 4;
+ v1 = l;
+ if (v1 != 8)
+ link_error ();
+ foo (sarr);
+ l = foo88(l);
+ return v1 + sarr[0];
+}
+
+int test8888 (void)
+{
+ static int l;
+ int v1;
+ l = 8;
+ garr[0] = 4;
+ v1 = l;
+ if (v1 != 8)
+ link_error ();
+ return v1 + garr[0];
+}
+
+
+
+/* global var */
+int g9;
+int garr9[10];
+int test9 (int *intarr)
+{
+ extern int foo9 (int) __attribute__ ((const));
+ int h, v;
+ g9 = 9;
+ h = foo9 (g9);
+ v = g9;
+ if (v != 9)
+ link_error ();
+ return g9;
+}
+
+int test99 (int *intarr)
+{
+ extern int foo9 (int) __attribute__ ((pure));
+ int h, v;
+ g9 = 9;
+ h = foo9 (g9);
+ v = g9;
+ if (v != 9)
+ link_error ();
+ return g9;
+}
+
+extern int foo99 (int);
+
+int test999 (int *arr)
+{
+ static int l;
+ int v1;
+ g9 = 9;
+ l = 4;
+ v1 = g9;
+ if (v1 != 9)
+ link_error ();
+ l = foo99 (l);
+ return v1 + l;
+}
+
+
+int test9999 (void)
+{
+ int v1;
+ static int sarr[10];
+ g9 = 9;
+ sarr[0] = 4;
+ v1 = g9;
+ if (v1 != 9)
+ link_error ();
+ foo (sarr);
+ g9 = foo99 (g9);
+ return v1 + sarr[0];
+}
+
+
+int test99999 (void)
+{
+ int v1;
+ g9 = 9;
+ garr9[0] = 4;
+ v1 = g9;
+ if (v1 != 9)
+ link_error ();
+ return v1 + garr9[0];
+}
+
+
+/* There should be not link_error calls, if there is any the
+ optimization has failed */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "ccp"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-3.c
new file mode 100644
index 00000000000..15d43cb7ef7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-3.c
@@ -0,0 +1,134 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-ccp" } */
+
+extern void link_error (void);
+
+/* some addresses clearly cannot be equal, check that some address
+ expressions can be evaluated as constants */
+
+char g1, g2;
+void test6 (char p1, char p2)
+{
+ char l1 = 1, l2 = 2;
+ static char s1 = 5, s2 = 7;
+ if (&l1 == &l2)
+ link_error ();
+
+ if (&p1 == &p2)
+ link_error ();
+
+ if (&s1 == &s2)
+ link_error ();
+
+ if (&g1 == &g2)
+ link_error ();
+
+ if (&p1 == &l1)
+ link_error ();
+
+ if (&p1 == &s1)
+ link_error ();
+
+ if (&p1 == &l2)
+ link_error ();
+
+ if (&p1 == &g1)
+ link_error ();
+
+ if (&l1 == &g1)
+ link_error ();
+
+ if (&s1 == &g1)
+ link_error ();
+}
+
+extern void *alloc (int) __attribute__ ((malloc));
+char gca1[128];
+char* __restrict__ rgc1;
+char* test66 (char * __restrict__ rp1, char * __restrict__ rp2, char *p1)
+{
+ char * __restrict__ rl1 = p1;
+ char * l1 = (char*) alloc (20);
+
+ if (l1 == rgc1)
+ link_error ();
+
+ if (l1 == rp1)
+ link_error ();
+
+ if (l1 == rl1)
+ link_error ();
+
+ if (l1 == gca1)
+ link_error ();
+
+ if (rl1 == rgc1)
+ link_error ();
+
+ if (rl1 == rp1)
+ link_error ();
+
+ if (rl1 == gca1)
+ link_error ();
+
+ if (rp1 == rp2)
+ link_error ();
+
+ if (rp1 == rgc1)
+ link_error ();
+
+ if (rp1 == gca1)
+ link_error ();
+
+ if (gca1 == rgc1)
+ link_error ();
+
+}
+
+int gci1[128];
+int* __restrict__ rgi1;
+int* test666 (int * __restrict__ rp1, int * __restrict__ rp2, int *p1)
+{
+ int * __restrict__ rl1 = p1;
+ int * l1 = (int*) alloc (20);
+
+ if (l1 == rgi1)
+ link_error ();
+
+ if (l1 == rp1)
+ link_error ();
+
+ if (l1 == rl1)
+ link_error ();
+
+ if (l1 == gci1)
+ link_error ();
+
+ if (rl1 == rgi1)
+ link_error ();
+
+ if (rl1 == rp1)
+ link_error ();
+
+ if (rl1 == gci1)
+ link_error ();
+
+ if (rp1 == rp2)
+ link_error ();
+
+ if (rp1 == rgi1)
+ link_error ();
+
+ if (rp1 == gci1)
+ link_error ();
+
+ if (gci1 == rgi1)
+ link_error ();
+}
+
+
+/* There should be not link_error calls, if there is any the
+ optimization has failed */
+/* ??? While we indeed don't handle some of these, a couple of the
+ restrict tests are incorrect. */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "ccp" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-7.c
new file mode 100644
index 00000000000..ba6db18e00e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-7.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-ccp" } */
+
+extern void link_error (void);
+
+/* tests to check if cprop works when using non-return functions */
+
+extern int not_returning (int) __attribute__ ((noreturn));
+
+int b;
+int test7 (int a)
+{
+ b = 7;
+ if (a)
+ {
+ not_returning (a);
+ }
+ if (b != 7)
+ link_error ();
+ return b;
+}
+
+
+/* There should be not link_error calls, if there is any the
+ optimization has failed */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "ccp"} } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-9.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-9.c
new file mode 100644
index 00000000000..4656558814e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-9.c
@@ -0,0 +1,54 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-ccp" } */
+
+/* Check that cprop works for assignments to array elements and structs. */
+
+struct foo {
+ int a;
+};
+
+extern void link_error (void);
+
+void
+test9 (struct foo f)
+{
+ f.a = 0;
+ if (f.a != 0)
+ link_error ();
+}
+
+void
+test99 (struct foo *f)
+{
+ f->a = 0;
+ if (f->a != 0)
+ link_error ();
+}
+
+void
+test999 (int *arr)
+{
+ *arr = 0;
+ if (*arr != 0)
+ link_error ();
+}
+
+void
+test9999 (int *arr)
+{
+ arr[13] = 0;
+ if (arr[13] != 0)
+ link_error ();
+}
+
+void
+test99999 (int *arr, int j)
+{
+ arr[j] = 0;
+ if (arr[j] != 0)
+ link_error ();
+}
+
+/* There should be no link_error calls, if there is any, the
+ optimization has failed */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "ccp"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-1.c
new file mode 100644
index 00000000000..e95cf67cde0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dce3" } */
+
+int t() __attribute__ ((const));
+q()
+{
+ int i = t();
+ if (!i)
+ i = t();
+}
+/* There should be no IF conditionals. */
+/* { dg-final { scan-tree-dump-times "if " 0 "dce3"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-2.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-2.c
new file mode 100644
index 00000000000..64525141beb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dce3" } */
+
+/* We should notice constantness of this function. */
+int t(int a)
+{
+ return a+1;
+}
+q()
+{
+ int i = t(1);
+ if (!i)
+ i = t(1);
+}
+/* There should be no IF conditionals. */
+/* { dg-final { scan-tree-dump-times "if " 0 "dce3"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c
new file mode 100644
index 00000000000..efaa3affaf6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cddce" } */
+
+int main(void)
+{
+ unsigned i, j;
+
+ for (i = 1, j = 0; i != 0; i+=2)
+ {
+ j += 500;
+ if (j % 7)
+ {
+ j++;
+ }
+ else
+ {
+ j--;
+ }
+ }
+
+ return 0;
+}
+
+/* We should eliminate the inner condition, but the loop must be preserved
+ as it is infinite. Therefore there should be just one phi node (for i): */
+/* { dg-final { scan-tree-dump-times "PHI " 1 "cddce"} } */
+
+/* And one if (for the exit condition of the loop): */
+/* { dg-final { scan-tree-dump-times "if " 1 "cddce"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-ccp-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-ccp-1.c
new file mode 100644
index 00000000000..db7b4b49ed2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-ccp-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dom1-details" } */
+int t(int a) __attribute__ ((const));
+void abort (void);
+int
+ccp(int b)
+{
+ int a=1;
+ a++;
+ a++;
+ a++;
+ if (b)
+ abort();
+ return a;
+}
+/* We should propagate constant 4 into return. */
+/* { dg-final { scan-tree-dump-times "Replaced.*with constant '4'" 1 "dom1"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-1.c
new file mode 100644
index 00000000000..4e4ed8c912f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-1.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dom2-details" } */
+int t(int a) __attribute__ ((const));
+void q (void);
+void
+threading(int a,int b)
+{
+ if (t(a))
+ {
+ if (t(a))
+ q();
+ }
+}
+/* We should thread the jump twice and eliminate it. Test this in
+ DOM2, after aliases have been computed. */
+/* { dg-final { scan-tree-dump-times "Replaced.* t " 1 "dom2"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-1.c
new file mode 100644
index 00000000000..e4ae8ea0b92
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dom1-details" } */
+void t(void);
+void q(void);
+void q1(void);
+void
+threading(int a,int b)
+{
+ if (a>b)
+ t();
+ else
+ q();
+ if (a<=b)
+ q1();
+}
+/* We should thread the jump twice and elliminate it. */
+/* { dg-final { scan-tree-dump-times "Threaded" 2 "dom1"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-1.c
new file mode 100644
index 00000000000..43eb6e0848f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-1.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-pre-stats" } */
+int main(int argc, char **argv)
+{
+ int a;
+ int b;
+ int c;
+ b = argc + 1;
+ c = argc + 2;
+ a = b + c;
+ if (argc * 2)
+ {
+ c = argc + 3;
+ }
+ printf ("%d, %d\n", a, b + c);
+}
+/* We should eliminate one evaluation of b + c along the main path,
+ causing one reload. */
+/* { dg-final { scan-tree-dump-times "Reloads:1" 1 "pre"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-2.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-2.c
new file mode 100644
index 00000000000..e264c50f920
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-2.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-pre-stats" } */
+int motion_test1(int data, int data_0, int data_3, int v)
+{
+ int i;
+ int t, u;
+
+ if (data)
+ i = data_0 + data_3;
+ else {
+ v = 2;
+ i = 5;
+ }
+ t = data_0 + data_3;
+ u = i;
+ return v * t * u;
+}
+/* We should eliminate one computation of data_0 + data_3 along the
+ main path, causing one reload. */
+/* { dg-final { scan-tree-dump-times "Reloads:1" 1 "pre"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailcall-1.c b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-1.c
new file mode 100644
index 00000000000..c2a85940a30
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-tailc-details" } */
+int q(int a);
+int *v;
+int
+t(int a)
+{
+ int r,r1;
+ if (a)
+ r1=r = q(a-1);
+ else
+ return 0;
+ /* Dead alloca should not disturb us. */
+ if (r!=r1)
+ v=alloca(r);
+ return r;
+}
+/* { dg-final { scan-tree-dump-times "Found tail call" 1 "tailc"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailcall-2.c b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-2.c
new file mode 100644
index 00000000000..7f3415444ff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-2.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-tailc-details" } */
+/* Test provided by Richard Earnshaw in PR 14312. */
+
+void bar (int i);
+void baz (int *);
+
+void
+foo (int *x)
+{
+ if (*x < 0)
+ {
+ baz (x);
+ return;
+ }
+ bar (*x);
+}
+
+/* The test has no local call-clobbered variables. Only the memory
+ tag for 'x' is call-clobbered. And since tags are not real
+ variables, they ought to be ignored. There should be two tail
+ calls here. */
+/* { dg-final { scan-tree-dump-times "Found tail call" 2 "tailc"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-1.c b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-1.c
new file mode 100644
index 00000000000..dc61c1324bd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-tailr-details" } */
+int
+t(int a)
+{
+ if (a)
+ return t(a-1);
+ else
+ return 0;
+}
+/* { dg-final { scan-tree-dump-times "Eliminated tail recursion" 1 "tailr"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-2.c b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-2.c
new file mode 100644
index 00000000000..095993bc133
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-2.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-tailr-details" } */
+int
+t(char *a)
+{
+ static char p[100];
+ if (a)
+ return t(p);
+ else
+ return 0;
+}
+/* { dg-final { scan-tree-dump-times "Eliminated tail recursion" 1 "tailr"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-3.c b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-3.c
new file mode 100644
index 00000000000..097a1de0e4e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-3.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-tailr-details" } */
+int
+t(int a)
+{
+ int r;
+ if (a)
+ r = t(a-1);
+ else
+ return 0;
+ if (r)
+ r=r;
+ return r;
+}
+/* { dg-final { scan-tree-dump-times "Eliminated tail recursion" 1 "tailr"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-4.c b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-4.c
new file mode 100644
index 00000000000..71a4f6716a1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-4.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-tailr-details" } */
+int
+t(int a)
+{
+ int r;
+ if (a&1)
+ r = t(a-1);
+ else if (a)
+ r = t(a-2);
+ else
+ return 0;
+ if (r)
+ r=r;
+ return r;
+}
+/* { dg-final { scan-tree-dump-times "Eliminated tail recursion" 2 "tailr"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-5.c b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-5.c
new file mode 100644
index 00000000000..2940a5019bd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-5.c
@@ -0,0 +1,72 @@
+/* { dg-do run } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+int sum (int n)
+{
+ if (n == 0)
+ return 0;
+
+ return n + sum (n - 1);
+}
+
+int fac (int n)
+{
+ if (n == 0)
+ return 1;
+
+ return n * fac (n - 1);
+}
+
+int sq_sum (int n)
+{
+ if (n == 0)
+ return 0;
+
+ return n * n + sq_sum (n - 1);
+}
+
+int pow2m1 (int n)
+{
+ if (n == 0)
+ return 0;
+
+ return 2 * pow2m1 (n - 1) + 1;
+}
+
+int fib (int n)
+{
+ if (n <= 1)
+ return 1;
+
+ return fib (n - 2) + fib (n - 1);
+}
+
+int main(void)
+{
+ if (sum (5) != 15)
+ abort ();
+
+ if (fac (5) != 120)
+ abort ();
+
+ if (sq_sum (5) != 55)
+ abort ();
+
+ if (pow2m1 (5) != 31)
+ abort ();
+
+ if (fib (5) != 8)
+ abort ();
+
+ exit (0);
+}
+
+/* There is one call of sum in main and then 2 instances of the word in
+ ;; Function sum (sum) and one in the function header. */
+/* { dg-final { scan-tree-dump-times "\\msum\\M" 4 "optimized"} } */
+/* { dg-final { scan-tree-dump-times "\\mfac\\M" 4 "optimized"} } */
+/* { dg-final { scan-tree-dump-times "\\msq_sum\\M" 4 "optimized"} } */
+/* { dg-final { scan-tree-dump-times "\\mpow2m1\\M" 4 "optimized"} } */
+
+/* There is one recursive call to fib. */
+/* { dg-final { scan-tree-dump-times "\\mfib\\M" 5 "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tree-ssa.exp b/gcc/testsuite/gcc.dg/tree-ssa/tree-ssa.exp
new file mode 100644
index 00000000000..7b3403c957d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/tree-ssa.exp
@@ -0,0 +1,36 @@
+# Copyright (C) 1997,2002,2003 Free Software Foundation, Inc.
+
+# This program 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 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+ set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
+ "" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/useless-1.c b/gcc/testsuite/gcc.dg/tree-ssa/useless-1.c
new file mode 100644
index 00000000000..3274998d1fc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/useless-1.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-useless" } */
+
+void
+foo (void)
+{
+ int i, a;
+ for (i = 0; i < 10; i++)
+ { a = i; }
+}
+
+/* There should be three gotos in the dump. If one was removed
+ in the loop exit condition, it would be re-introduced during
+ GIMPLE lowering, at the cost of an extra statement, label,
+ and basic block. */
+/* { dg-final { scan-tree-dump-times "goto" 3 "useless"} } */
diff --git a/gcc/testsuite/gcc.dg/uninit-1.c b/gcc/testsuite/gcc.dg/uninit-1.c
index 91838810fda..060ec250ba7 100644
--- a/gcc/testsuite/gcc.dg/uninit-1.c
+++ b/gcc/testsuite/gcc.dg/uninit-1.c
@@ -13,7 +13,7 @@ extern void free (void *);
void remove_dupes (struct list *el)
{
- struct list *p, *q, *r; /* { dg-bogus "r" "uninitialized variable warning" { xfail *-*-* } } */
+ struct list *p, *q, *r; /* { dg-bogus "r" "uninitialized variable warning" } */
for (p = el; p; p = p->next)
{
diff --git a/gcc/testsuite/gcc.dg/uninit-11.c b/gcc/testsuite/gcc.dg/uninit-11.c
new file mode 100644
index 00000000000..5251f0a2a70
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/uninit-11.c
@@ -0,0 +1,42 @@
+/* Positive test for uninitialized variables. */
+/* { dg-do compile } */
+/* { dg-options "-O -Wuninitialized" } */
+
+int sink;
+
+void f1(int parm) /* { dg-bogus "uninitialized" "parameter" } */
+{
+ sink = parm; /* { dg-bogus "uninitialized" "parameter" } */
+}
+
+void f2(void)
+{
+ int x;
+ sink = x; /* { dg-warning "is used" "unconditional" } */
+}
+
+void f3(int p)
+{
+ int x; /* { dg-warning "may be used" "conditional" } */
+ if (p)
+ x = p;
+ sink = x;
+}
+
+void f4(int p)
+{
+ int x; /* { dg-bogus "uninitialized" "easy if" } */
+ if (p)
+ x = 1;
+ else
+ x = 2;
+ sink = x;
+}
+
+void f5(void)
+{
+ int x, i; /* { dg-bogus "uninitialized" "easy loop" } */
+ for (i = 0; i < 10; ++i)
+ x = 1;
+ sink = x;
+}
diff --git a/gcc/testsuite/gcc.dg/uninit-2.c b/gcc/testsuite/gcc.dg/uninit-2.c
index 5035a309ebd..352bbac06c5 100644
--- a/gcc/testsuite/gcc.dg/uninit-2.c
+++ b/gcc/testsuite/gcc.dg/uninit-2.c
@@ -25,7 +25,7 @@ macroexpand (struct cpp_reader *pfile, struct definition *defn)
if (nargs >= 0)
{
- enum cpp_token token; /* { dg-bogus "token" "uninitialized variable warning" { xfail *-*-* } } */
+ enum cpp_token token; /* { dg-bogus "token" "uninitialized variable warning" } */
int i, rest_args;
i = 0;
rest_args = 0;
diff --git a/gcc/testsuite/gcc.dg/uninit-3.c b/gcc/testsuite/gcc.dg/uninit-3.c
index 78c4254dea5..ac5bfec8e72 100644
--- a/gcc/testsuite/gcc.dg/uninit-3.c
+++ b/gcc/testsuite/gcc.dg/uninit-3.c
@@ -8,7 +8,7 @@ extern void error (char *);
int
parse_charconst (const char *start, const char *end)
{
- int c; /* { dg-bogus "c" "uninitialized variable warning" { xfail *-*-* } } */
+ int c; /* { dg-bogus "c" "uninitialized variable warning" } */
int nchars, retval;
nchars = 0;
diff --git a/gcc/testsuite/gcc.dg/uninit-4.c b/gcc/testsuite/gcc.dg/uninit-4.c
index a27317ebed5..c51d00802b7 100644
--- a/gcc/testsuite/gcc.dg/uninit-4.c
+++ b/gcc/testsuite/gcc.dg/uninit-4.c
@@ -23,7 +23,7 @@ extern struct operation cpp_lex (void);
void
cpp_parse_expr (void)
{
- int rprio; /* { dg-bogus "rprio" "uninitialized variable warning" { xfail *-*-* } } */
+ int rprio; /* { dg-bogus "rprio" "uninitialized variable warning" } */
struct operation op;
for (;;)
diff --git a/gcc/testsuite/gcc.dg/uninit-5.c b/gcc/testsuite/gcc.dg/uninit-5.c
index ac760d69e03..ae7a8de7646 100644
--- a/gcc/testsuite/gcc.dg/uninit-5.c
+++ b/gcc/testsuite/gcc.dg/uninit-5.c
@@ -1,5 +1,4 @@
-/* Spurious uninitialized-variable warnings.
- These cases are documented as not working in the gcc manual. */
+/* Spurious uninitialized-variable warnings. */
/* { dg-do compile } */
/* { dg-options "-O -Wuninitialized" } */
@@ -10,7 +9,7 @@ extern void foo(void);
void
func1(int cond)
{
- int x; /* { dg-bogus "x" "uninitialized variable warning" { xfail *-*-* } } */
+ int x; /* { dg-bogus "x" "uninitialized variable warning" } */
if(cond)
x = 1;
@@ -24,7 +23,7 @@ func1(int cond)
void
func2 (int cond)
{
- int x; /* { dg-bogus "x" "uninitialized variable warning" { xfail *-*-* } } */
+ int x; /* { dg-bogus "x" "uninitialized variable warning" } */
int flag = 0;
if(cond)
diff --git a/gcc/testsuite/gcc.dg/uninit-6.c b/gcc/testsuite/gcc.dg/uninit-6.c
index 2c428df79b6..b0f2083ab4b 100644
--- a/gcc/testsuite/gcc.dg/uninit-6.c
+++ b/gcc/testsuite/gcc.dg/uninit-6.c
@@ -34,12 +34,12 @@ struct tree *
make_something(int a, int b, int c)
{
struct tree *rv;
- struct tree *field; /* { dg-bogus "field" "uninitialized variable warning" { xfail *-*-* } } */
+ struct tree *field;
rv = malloc (sizeof (struct tree));
rv->car = 0;
- APPEND(rv, field, INTEGER_T, a);
+ APPEND(rv, field, INTEGER_T, a); /* { dg-bogus "field" "uninitialized variable warning" { xfail *-*-* } } */
APPEND(rv, field, PTR_T, b);
APPEND(rv, field, INTEGER_T, c);
diff --git a/gcc/testsuite/gcc.dg/uninit-8.c b/gcc/testsuite/gcc.dg/uninit-8.c
index 94117da37c9..98700f4aa1f 100644
--- a/gcc/testsuite/gcc.dg/uninit-8.c
+++ b/gcc/testsuite/gcc.dg/uninit-8.c
@@ -11,7 +11,7 @@ void
add_bignums (int *out, int *x, int *y)
{
int p, sum;
- int carry; /* { dg-bogus "carry" "uninitialized variable warning" { xfail *-*-* } } */
+ int carry; /* { dg-bogus "carry" "uninitialized variable warning" } */
p = 0;
for (; *x; x++, y++, out++, p++)
diff --git a/gcc/testsuite/gcc.dg/uninit-9.c b/gcc/testsuite/gcc.dg/uninit-9.c
index 62681f9e0fd..2a8ccb69f32 100644
--- a/gcc/testsuite/gcc.dg/uninit-9.c
+++ b/gcc/testsuite/gcc.dg/uninit-9.c
@@ -23,7 +23,7 @@ func(struct foo *list, int count)
{
int n_clobbers = 0;
int i;
- struct foo **clob_list; /* { dg-bogus "clob_list" "uninitialized variable warning" { xfail *-*-* } } */
+ struct foo **clob_list; /* { dg-bogus "clob_list" "uninitialized variable warning" } */
if(list[0].type == PARALLEL)
{
diff --git a/gcc/testsuite/gcc.dg/uninit-H.c b/gcc/testsuite/gcc.dg/uninit-H.c
new file mode 100644
index 00000000000..67c33318f97
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/uninit-H.c
@@ -0,0 +1,19 @@
+/* PR 14204 */
+/* { dg-do compile } */
+/* { dg-options "-O -Wall -Werror" } */
+
+#if defined __alpha__
+# define ASM __asm__("$30")
+#elif defined __i386__
+# define ASM __asm__("esp")
+#elif (defined __powerpc__) || (defined __PPC__) || (defined __ppc__)
+# define ASM __asm__("r1")
+#else
+# define ASM
+#endif
+
+void *load_PCB (void)
+{
+ register void *sp ASM;
+ return sp; /* { dg-bogus "uninitialized" } */
+}
diff --git a/gcc/testsuite/gcc.dg/unused-6.c b/gcc/testsuite/gcc.dg/unused-6.c
new file mode 100644
index 00000000000..7651ecb28c9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/unused-6.c
@@ -0,0 +1,11 @@
+
+/* { dg-do compile } */
+/* { dg-options "-O3 -Wunused-parameter" } */
+static int t(int i) /* { dg-warning "unused parameter" "unused parameter warning" } */
+{
+ return 0;
+}
+int tt()
+{
+ return t(0);
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/1b-01.c b/gcc/testsuite/gcc.dg/vmx/1b-01.c
new file mode 100644
index 00000000000..425b0262c60
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/1b-01.c
@@ -0,0 +1,11 @@
+#include "harness.h"
+
+vector unsigned char a;
+
+static void test()
+{
+ check(sizeof(a) == 16, "sizeof(a)");
+ check(((int)&a & 15) == 0, "alignof(a)");
+ check((int)&a != 0, "&a");
+ check(vec_all_eq(a,((vector unsigned char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0})), "value(a)");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/1b-02.c b/gcc/testsuite/gcc.dg/vmx/1b-02.c
new file mode 100644
index 00000000000..2f9aca5da5c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/1b-02.c
@@ -0,0 +1,61 @@
+/* { dg-do compile } */
+#include <altivec.h>
+vector unsigned char u8;
+vector signed char s8;
+vector bool char b8;
+vector unsigned short u16;
+vector signed short s16;
+vector bool short b16;
+vector unsigned int u32;
+vector signed int s32;
+vector bool int b32;
+vector float f32;
+vector pixel p16;
+
+vector unsigned char const u8c;
+vector signed char const s8c;
+vector bool char const b8c;
+vector unsigned short const u16c;
+vector signed short const s16c;
+vector bool short const b16c;
+vector unsigned int const u32c;
+vector signed int const s32c;
+vector bool int const b32c;
+vector float const f32c;
+vector pixel const p16c;
+
+vector unsigned char volatile u8v;
+vector signed char volatile s8v;
+vector bool char volatile b8v;
+vector unsigned short volatile u16v;
+vector signed short volatile s16v;
+vector bool short volatile b16v;
+vector unsigned int volatile u32v;
+vector signed int volatile s32v;
+vector bool int volatile b32v;
+vector float volatile f32v;
+vector pixel volatile p16v;
+
+const vector unsigned char u8c_;
+const vector signed char s8c_;
+const vector bool char b8c_;
+const vector unsigned short u16c_;
+const vector signed short s16c_;
+const vector bool short b16c_;
+const vector unsigned int u32c_;
+const vector signed int s32c_;
+const vector bool int b32c_;
+const vector float f32c_;
+const vector pixel p16c_;
+
+volatile vector unsigned char u8v_;
+volatile vector signed char s8v_;
+volatile vector bool char b8v_;
+volatile vector unsigned short u16v_;
+volatile vector signed short s16v_;
+volatile vector bool short b16v_;
+volatile vector unsigned int u32v_;
+volatile vector signed int s32v_;
+volatile vector bool int b32v_;
+volatile vector float f32v_;
+volatile vector pixel p16v_;
diff --git a/gcc/testsuite/gcc.dg/vmx/1b-03.c b/gcc/testsuite/gcc.dg/vmx/1b-03.c
new file mode 100644
index 00000000000..2f8f816ba23
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/1b-03.c
@@ -0,0 +1,64 @@
+#include <altivec.h>
+int main()
+{
+ vector unsigned char u8;
+ vector signed char s8;
+ vector bool char b8;
+ vector unsigned short u16;
+ vector signed short s16;
+ vector bool short b16;
+ vector unsigned int u32;
+ vector signed int s32;
+ vector bool int b32;
+ vector float f32;
+ vector pixel p16;
+
+ vector unsigned char const u8c;
+ vector signed char const s8c;
+ vector bool char const b8c;
+ vector unsigned short const u16c;
+ vector signed short const s16c;
+ vector bool short const b16c;
+ vector unsigned int const u32c;
+ vector signed int const s32c;
+ vector bool int const b32c;
+ vector float const f32c;
+ vector pixel const p16c;
+
+ vector unsigned char volatile u8v;
+ vector signed char volatile s8v;
+ vector bool char volatile b8v;
+ vector unsigned short volatile u16v;
+ vector signed short volatile s16v;
+ vector bool short volatile b16v;
+ vector unsigned int volatile u32v;
+ vector signed int volatile s32v;
+ vector bool int volatile b32v;
+ vector float volatile f32v;
+ vector pixel volatile p16v;
+
+ const vector unsigned char u8c_;
+ const vector signed char s8c_;
+ const vector bool char b8c_;
+ const vector unsigned short u16c_;
+ const vector signed short s16c_;
+ const vector bool short b16c_;
+ const vector unsigned int u32c_;
+ const vector signed int s32c_;
+ const vector bool int b32c_;
+ const vector float f32c_;
+ const vector pixel p16c_;
+
+ volatile vector unsigned char u8v_;
+ volatile vector signed char s8v_;
+ volatile vector bool char b8v_;
+ volatile vector unsigned short u16v_;
+ volatile vector signed short s16v_;
+ volatile vector bool short b16v_;
+ volatile vector unsigned int u32v_;
+ volatile vector signed int s32v_;
+ volatile vector bool int b32v_;
+ volatile vector float f32v_;
+ volatile vector pixel p16v_;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/1b-04.c b/gcc/testsuite/gcc.dg/vmx/1b-04.c
new file mode 100644
index 00000000000..5807ea335a7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/1b-04.c
@@ -0,0 +1,7 @@
+#include <altivec.h>
+int main()
+{
+ vector unsigned char a,b;
+ b = (vector unsigned char)a;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/1b-05.c b/gcc/testsuite/gcc.dg/vmx/1b-05.c
new file mode 100644
index 00000000000..63eb10b7c3c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/1b-05.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+#include <altivec.h>
+vector float _0 ;
+vector pixel _1 ;
+vector bool int _2 ;
+vector unsigned int _3 ;
+vector signed int _4 ;
+vector bool short _5 ;
+vector unsigned short _6 ;
+vector signed short _7 ;
+vector bool char _8 ;
+vector unsigned char _9 ;
+vector signed char _10 ;
diff --git a/gcc/testsuite/gcc.dg/vmx/1b-06.c b/gcc/testsuite/gcc.dg/vmx/1b-06.c
new file mode 100644
index 00000000000..84c69813ce4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/1b-06.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+#include <altivec.h>
+vector char bool _4 ;
+vector char unsigned _31 ;
+vector char signed _59 ;
+bool _84 ;
+vector pixel _89 ;
+vector int bool _95 ;
+vector short bool _102 ;
+vector unsigned int _122 ;
+vector unsigned short _129 ;
+vector signed int _150 ;
+vector signed short _157 ;
+vector int bool _179 ;
+vector int short bool _186 ;
+vector unsigned int _206 ;
+vector int unsigned short _213 ;
+vector signed int _234 ;
+vector int signed short _241 ;
+vector float _339 ;
diff --git a/gcc/testsuite/gcc.dg/vmx/1b-07.c b/gcc/testsuite/gcc.dg/vmx/1b-07.c
new file mode 100644
index 00000000000..b1f4bb6e8a3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/1b-07.c
@@ -0,0 +1,55 @@
+/* { dg-do compile } */
+#include <altivec.h>
+vector char bool _0 ;
+vector bool char _8 ;
+vector char unsigned _56 ;
+vector unsigned char _64 ;
+vector char signed _112 ;
+vector signed char _120 ;
+bool _168 ;
+vector pixel _170 ;
+vector int bool _178 ;
+vector bool int _186 ;
+vector short bool _234 ;
+vector bool short _242 ;
+vector unsigned int _290 ;
+vector int unsigned _298 ;
+vector unsigned short _346 ;
+vector short unsigned _354 ;
+vector signed int _402 ;
+vector int signed _410 ;
+vector signed short _458 ;
+vector short signed _466 ;
+vector int bool _514 ;
+vector int bool _544 ;
+vector int bool _559 ;
+vector bool int _589 ;
+vector int short bool _874 ;
+vector int bool short _889 ;
+vector short int bool _904 ;
+vector short bool int _919 ;
+vector bool int short _934 ;
+vector bool short int _949 ;
+vector unsigned int _1234 ;
+vector int unsigned _1249 ;
+vector unsigned int _1279 ;
+vector int unsigned _1294 ;
+vector unsigned int _1309 ;
+vector int unsigned short _1594 ;
+vector int short unsigned _1609 ;
+vector unsigned int short _1624 ;
+vector unsigned short int _1639 ;
+vector short int unsigned _1654 ;
+vector short unsigned int _1669 ;
+vector signed int _1954 ;
+vector int signed _1969 ;
+vector signed int _1999 ;
+vector int signed _2014 ;
+vector signed int _2029 ;
+vector int signed short _2314 ;
+vector int short signed _2329 ;
+vector signed int short _2344 ;
+vector signed short int _2359 ;
+vector short int signed _2374 ;
+vector short signed int _2389 ;
+vector float _2674 ;
diff --git a/gcc/testsuite/gcc.dg/vmx/1c-01.c b/gcc/testsuite/gcc.dg/vmx/1c-01.c
new file mode 100644
index 00000000000..974bda19ed5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/1c-01.c
@@ -0,0 +1,56 @@
+#include <stddef.h>
+#include "harness.h"
+
+/* Declare vector types. */
+vector unsigned char u8;
+vector signed char s8;
+vector bool char b8;
+vector unsigned short u16;
+vector signed short s16;
+vector bool short b16;
+vector unsigned int u32;
+vector signed int s32;
+vector bool int b32;
+vector float f32;
+vector pixel p16;
+
+vector unsigned char *u8c = &u8;
+vector signed char *s8c = &s8;
+vector bool char *b8c = &b8;
+vector unsigned short *u16c = &u16;
+vector signed short *s16c = &s16;
+vector bool short *b16c = &b16;
+vector unsigned int *u32c = &u32;
+vector signed int *s32c = &s32;
+vector bool int *b32c = &b32;
+vector float *f32c = &f32;
+vector pixel *p16c = &p16;
+
+static void test()
+{
+ check(((ptrdiff_t)u8c & 15) == 0, "alignof(u8)");
+ check(((ptrdiff_t)u8c & 15) == 0, "alignof(u8)");
+ check(((ptrdiff_t)s8c & 15) == 0, "alignof(s8)");
+ check(((ptrdiff_t)b8c & 15) == 0, "alignof(b8)");
+ check(((ptrdiff_t)u16c & 15) == 0, "alignof(u16)");
+ check(((ptrdiff_t)s16c & 15) == 0, "alignof(s16)");
+ check(((ptrdiff_t)b16c & 15) == 0, "alignof(b16)");
+ check(((ptrdiff_t)u32c & 15) == 0, "alignof(u32)");
+ check(((ptrdiff_t)s32c & 15) == 0, "alignof(s32)");
+ check(((ptrdiff_t)b32c & 15) == 0, "alignof(b32)");
+ check(((ptrdiff_t)f32c & 15) == 0, "alignof(f32)");
+ check(((ptrdiff_t)p16c & 15) == 0, "alignof(p16)");
+
+ check((ptrdiff_t)u8c == (ptrdiff_t)&u8, "u8c == &u8");
+ check((ptrdiff_t)u8c == (ptrdiff_t)&u8, "u8c == &u8");
+ check((ptrdiff_t)s8c == (ptrdiff_t)&s8, "s8c == &s8");
+ check((ptrdiff_t)b8c == (ptrdiff_t)&b8, "b8c == &b8");
+ check((ptrdiff_t)u16c == (ptrdiff_t)&u16, "u16c == &u16");
+ check((ptrdiff_t)s16c == (ptrdiff_t)&s16, "s16c == &s16");
+ check((ptrdiff_t)b16c == (ptrdiff_t)&b16, "b16c == &b16");
+ check((ptrdiff_t)u32c == (ptrdiff_t)&u32, "u32c == &u32");
+ check((ptrdiff_t)s32c == (ptrdiff_t)&s32, "s32c == &s32");
+ check((ptrdiff_t)b32c == (ptrdiff_t)&b32, "b32c == &b32");
+ check((ptrdiff_t)f32c == (ptrdiff_t)&f32, "f32c == &f32");
+ check((ptrdiff_t)p16c == (ptrdiff_t)&p16, "p16c == &p16");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/1c-02.c b/gcc/testsuite/gcc.dg/vmx/1c-02.c
new file mode 100644
index 00000000000..ec591ed596d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/1c-02.c
@@ -0,0 +1,34 @@
+#include "harness.h"
+
+/* Vector types used in aggregates. */
+struct { char b; vector unsigned char a; char e; } u8;
+struct { char b; vector signed char a; char e; } s8;
+struct { char b; vector bool char a; char e; } b8;
+struct { char b; vector unsigned short a; char e; } u16;
+struct { char b; vector signed short a; char e; } s16;
+struct { char b; vector bool short a; char e; } b16;
+struct { char b; vector unsigned int a; char e; } u32;
+struct { char b; vector signed int a; char e; } s32;
+struct { char b; vector bool int a; char e; } b32;
+struct { char b; vector float a; char e; } f32;
+struct { char b; vector pixel a; char e; } p16;
+
+union { char b; vector unsigned char a; } u8u;
+union { char b; vector signed char a; } s8u;
+union { char b; vector bool char a; } b8u;
+union { char b; vector unsigned short a; } u16u;
+union { char b; vector signed short a; } s16u;
+union { char b; vector bool short a; } b16u;
+union { char b; vector unsigned int a; } u32u;
+union { char b; vector signed int a; } s32u;
+union { char b; vector bool int a; } b32u;
+union { char b; vector float a; } f32u;
+union { char b; vector pixel a; } p16u;
+
+static void test()
+{
+ check((int)&u8.a - (int)&u8 == 16, "u8.a");
+ check((int)&u8.e - (int)&u8 == 32, "u8.e");
+ check(sizeof(u8) == 48, "sizeof(u8)");
+ check(sizeof(u8u) == 16, "sizeof(u8u)");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/3a-01.c b/gcc/testsuite/gcc.dg/vmx/3a-01.c
new file mode 100644
index 00000000000..86e514d4a24
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/3a-01.c
@@ -0,0 +1,16 @@
+#include "harness.h"
+/* Simple use of a non-overloaded generic vector intrinsic. */
+
+static vector unsigned int
+f(vector unsigned int a, vector unsigned int b)
+{
+ return vec_addc(a,b);
+}
+
+static void test()
+{
+ check(vec_all_eq(f(((vector unsigned int){1,1,3,2}),
+ ((vector unsigned int){-1,-2,3,-4})),
+ ((vector unsigned int){1,0,0,0})),
+ "f");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/3a-01a.c b/gcc/testsuite/gcc.dg/vmx/3a-01a.c
new file mode 100644
index 00000000000..7619d1185cb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/3a-01a.c
@@ -0,0 +1,17 @@
+#include "harness.h"
+
+/* Simple use of a non-overloaded specific vector intrinsic. */
+
+vector unsigned int
+f(vector unsigned int a, vector unsigned int b)
+{
+ return vec_vaddcuw(a,b);
+}
+
+void test()
+{
+ check(vec_all_eq(f(((vector unsigned int){1,1,3,2}),
+ ((vector unsigned int){-1,-2,3,-4})),
+ ((vector unsigned int){1,0,0,0})),
+ "f");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/3a-01m.c b/gcc/testsuite/gcc.dg/vmx/3a-01m.c
new file mode 100644
index 00000000000..d57287007d9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/3a-01m.c
@@ -0,0 +1,17 @@
+#include "harness.h"
+
+/* Simple use of a non-overloaded specific vector intrinsic. */
+
+vector unsigned int
+f(vector unsigned int a, vector unsigned int b)
+{
+ return vec_vaddcuw(a,b);
+}
+
+static void test()
+{
+ check(vec_all_eq(f(((vector unsigned int){1,1,3,2}),
+ ((vector unsigned int){-1,-2,3,-4})),
+ ((vector unsigned int){1,0,0,0})),
+ "f");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/3a-03.c b/gcc/testsuite/gcc.dg/vmx/3a-03.c
new file mode 100644
index 00000000000..5f46ee6f457
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/3a-03.c
@@ -0,0 +1,18 @@
+#include "harness.h"
+
+/* Small expression involving non-overloaded generic vector intrinsics. */
+
+vector float
+f(vector float a, vector float b, vector float c)
+{
+ return vec_nmsub(a, vec_re(b), vec_nmsub(b, c, vec_expte(a)));
+}
+
+static void test()
+{
+ check(vec_all_eq(f(((vector float){2,3,5,7}),
+ ((vector float){11,13,17,19}),
+ ((vector float){23,29,31,37})),
+ ((vector float){-249.181808, -369.230774, -495.294098, -575.368408})),
+ "f");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/3a-03m.c b/gcc/testsuite/gcc.dg/vmx/3a-03m.c
new file mode 100644
index 00000000000..68feecee713
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/3a-03m.c
@@ -0,0 +1,18 @@
+#include "harness.h"
+
+/* Small expression involving non-overloaded specific vector intrinsics. */
+
+vector float
+f(vector float a, vector float b, vector float c)
+{
+ return vec_nmsub(a, vec_vrefp(b), vec_nmsub(b, c, vec_vexptefp(a)));
+}
+
+static void test()
+{
+ check(vec_all_eq(f(((vector float){2,3,5,7}),
+ ((vector float){11,13,17,19}),
+ ((vector float){23,29,31,37})),
+ ((vector float){-249.181808, -369.230774, -495.294098, -575.368408})),
+ "f");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/3a-04.c b/gcc/testsuite/gcc.dg/vmx/3a-04.c
new file mode 100644
index 00000000000..f6657084cc5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/3a-04.c
@@ -0,0 +1,18 @@
+#include "harness.h"
+
+/* Small expression involving non-overloaded vector intrinsics. */
+
+vector float
+f(vector float a, vector float b, vector float c)
+{
+ return vec_vmaddfp(a, vec_re(b), vec_vmaxfp(c, vec_expte(a)));
+}
+
+static void test()
+{
+ check(vec_all_eq(f(((vector float){2,3,5,7}),
+ ((vector float){11,13,17,19}),
+ ((vector float){23,29,31,37})),
+ ((vector float){23.1818085, 29.2307587, 32.2940826, 128.368393})),
+ "f");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/3a-04m.c b/gcc/testsuite/gcc.dg/vmx/3a-04m.c
new file mode 100644
index 00000000000..e394e9b8bd9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/3a-04m.c
@@ -0,0 +1,18 @@
+#include "harness.h"
+
+/* Small expression involving non-overloaded specific vector intrinsics. */
+
+vector float
+f(vector float a, vector float b, vector float c)
+{
+ return vec_vmaddfp(a, vec_vrefp(b), vec_vmaxfp(c, vec_vexptefp(a)));
+}
+
+static void test()
+{
+ check(vec_all_eq(f(((vector float){2,3,5,7}),
+ ((vector float){11,13,17,19}),
+ ((vector float){23,29,31,37})),
+ ((vector float){23.1818085, 29.2307587, 32.2940826, 128.368393})),
+ "f");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/3a-05.c b/gcc/testsuite/gcc.dg/vmx/3a-05.c
new file mode 100644
index 00000000000..55e0ed8e0c2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/3a-05.c
@@ -0,0 +1,22 @@
+#include "harness.h"
+
+/* Small expression involving non-overloaded specific vector intrinsics. */
+
+vector float
+f(vector float a, vector float b, vector float c)
+{
+ vector float q = vec_expte(a);
+ vector float r = vec_vsubfp(c, q);
+ vector float s = vec_re(b);
+ vector float t = vec_nmsub(s, c, r);
+ return t;
+}
+
+static void test()
+{
+ check(vec_all_eq(f(((vector float){2,3,5,7}),
+ ((vector float){11,13,17,19}),
+ ((vector float){23,29,31,37})),
+ ((vector float){16.9092026, 18.7693329, -2.8233242, -92.9472198})),
+ "f");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/3a-06.c b/gcc/testsuite/gcc.dg/vmx/3a-06.c
new file mode 100644
index 00000000000..6f27b3860a8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/3a-06.c
@@ -0,0 +1,15 @@
+#include "harness.h"
+
+vector unsigned int
+f(vector unsigned int a, vector unsigned int b)
+{
+ return vec_addc(vec_addc(a,b),b);
+}
+
+static void test()
+{
+ check(vec_all_eq(f(((vector unsigned int){2,4,6,8}),
+ ((vector unsigned int){-1,-2,-3,-4})),
+ ((vector unsigned int){1,0,0,0})),
+ "f");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/3a-06m.c b/gcc/testsuite/gcc.dg/vmx/3a-06m.c
new file mode 100644
index 00000000000..e616f9aef2e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/3a-06m.c
@@ -0,0 +1,15 @@
+#include "harness.h"
+
+vector unsigned int
+f(vector unsigned int a, vector unsigned int b)
+{
+ return vec_vaddcuw(vec_vaddcuw(a,b),b);
+}
+
+static void test()
+{
+ check(vec_all_eq(f(((vector unsigned int){2,4,6,8}),
+ ((vector unsigned int){-1,-2,-3,-4})),
+ ((vector unsigned int){1,0,0,0})),
+ "f");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/3a-07.c b/gcc/testsuite/gcc.dg/vmx/3a-07.c
new file mode 100644
index 00000000000..197fd23c86e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/3a-07.c
@@ -0,0 +1,16 @@
+#include "harness.h"
+
+static vector unsigned char
+zero()
+{
+ /* MCC allocates a stack slot for and loads an uninitialized local
+ variable. */
+ vector unsigned char a;
+ return vec_sub(a,a);
+}
+
+static void test()
+{
+ static vector unsigned char zerov;
+ check(vec_all_eq(zero(), zerov), "zero");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/3b-01.c b/gcc/testsuite/gcc.dg/vmx/3b-01.c
new file mode 100644
index 00000000000..e8feec481e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/3b-01.c
@@ -0,0 +1,18 @@
+#include "harness.h"
+
+/* Simple use of a overloaded generic vector intrinsic. */
+
+vector unsigned int
+f(vector unsigned int a, vector unsigned int b)
+{
+ return vec_subs(a,b);
+}
+
+static void test()
+{
+ static vector unsigned int zero;
+ check(vec_all_eq(f(((vector unsigned int){2,4,6,8}),
+ ((vector unsigned int){2,4,6,8})),
+ zero),
+ "f");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/3b-02.c b/gcc/testsuite/gcc.dg/vmx/3b-02.c
new file mode 100644
index 00000000000..66693e0ff71
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/3b-02.c
@@ -0,0 +1,16 @@
+#include "harness.h"
+
+vector unsigned char
+f(vector unsigned char a, vector unsigned char b)
+{
+ return vec_vsububs(a,b);
+}
+
+static void test()
+{
+ static vector unsigned char zero;
+ check(vec_all_eq(f(((vector unsigned char){2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}),
+ ((vector unsigned char){2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2})),
+ zero),
+ "f");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/3b-10.c b/gcc/testsuite/gcc.dg/vmx/3b-10.c
new file mode 100644
index 00000000000..5f8fb3adfab
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/3b-10.c
@@ -0,0 +1,21 @@
+#include "harness.h"
+
+typedef vector unsigned int x;
+
+x f (x a)
+{
+ return vec_addc(a,a);
+}
+
+void g (int b)
+{
+ vec_dst(&b, 3, 3);
+ vec_dst(&b, 1, 1);
+}
+
+static void test()
+{
+ check(vec_all_eq(f(((vector unsigned int){0x80000000,0x7fffffff,3,4})),
+ ((vector unsigned int){1,0,0,0})),
+ "f");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/3b-13.c b/gcc/testsuite/gcc.dg/vmx/3b-13.c
new file mode 100644
index 00000000000..146f737aebd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/3b-13.c
@@ -0,0 +1,15 @@
+#include "harness.h"
+
+vector signed int
+f(vector float a, vector signed int b)
+{
+ return vec_splat(vec_cts(vec_ctf(vec_ctu(a, 31),0),9),30);
+}
+
+static void test()
+{
+ check(vec_all_eq(f(((vector float){1,2,3,4}),
+ ((vector signed int){2,4,6,8})),
+ ((vector signed int){2147483647, 2147483647, 2147483647, 2147483647})),
+ "f");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/3b-14.c b/gcc/testsuite/gcc.dg/vmx/3b-14.c
new file mode 100644
index 00000000000..02b2d901ebc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/3b-14.c
@@ -0,0 +1,29 @@
+#include "harness.h"
+
+static vector bool char x(void);
+static void g(void);
+
+static vector bool char
+f (void)
+{
+ vector bool char a = x();
+ g();
+ return a;
+}
+
+static vector bool char
+x (void)
+{
+ static vector bool char zero;
+ return zero;
+}
+
+static void g ()
+{
+}
+
+static void test()
+{
+ static vector bool char zero;
+ check(vec_all_eq(f(), zero), "f");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/3b-15.c b/gcc/testsuite/gcc.dg/vmx/3b-15.c
new file mode 100644
index 00000000000..ec9cf2c5a0d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/3b-15.c
@@ -0,0 +1,19 @@
+#include "harness.h"
+
+vector unsigned char
+f (vector unsigned char a, vector unsigned char b, vector unsigned char c)
+{
+ return vec_perm(a,b,c);
+}
+
+static void test()
+{
+ check(vec_all_eq(f(((vector unsigned char){0,1,2,3,4,5,6,7,
+ 8,9,10,11,12,13,14,15}),
+ ((vector unsigned char){70,71,72,73,74,75,76,77,
+ 78,79,80,81,82,83,84,85}),
+ ((vector unsigned char){0x1,0x14,0x18,0x10,0x16,0x15,0x19,0x1a,
+ 0x1c,0x1c,0x1c,0x12,0x8,0x1d,0x1b,0xe})),
+ ((vector unsigned char){1,74,78,70,76,75,79,80,82,82,82,72,8,83,81,14})),
+ "f");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/3c-01.c b/gcc/testsuite/gcc.dg/vmx/3c-01.c
new file mode 100644
index 00000000000..c6da229f4b0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/3c-01.c
@@ -0,0 +1,86 @@
+#include "harness.h"
+
+vector unsigned char u8;
+vector signed char s8;
+vector bool char b8;
+vector unsigned short u16;
+vector signed short s16;
+vector bool short b16;
+vector unsigned int u32;
+vector signed int s32;
+vector bool int b32;
+vector float f32;
+vector pixel p16;
+
+static void g(void);
+
+static void f(void *p)
+{
+ u8 = vec_ld(16, (unsigned char *)p);
+ u16 = vec_ld(16, (unsigned short*)p);
+ u32 = vec_ld(16, (unsigned int*)p);
+ s8 = vec_ld(16, (signed char *)p);
+ s16 = vec_ld(16, (short*)p);
+ s32 = vec_ld(16, (int*)p);
+ g();
+ u8 = vec_ld(16, (vector unsigned char*)p);
+ s8 = vec_ld(16, (vector signed char*)p);
+ b8 = vec_ld(16, (vector bool char*)p);
+ g();
+ u16 = vec_ld(16, (vector unsigned short*)p);
+ s16 = vec_ld(16, (vector signed short*)p);
+ b16 = vec_ld(16, (vector bool short*)p);
+ g();
+ u32 = vec_ld(16, (vector unsigned int*)p);
+ s32 = vec_ld(16, (vector signed int*)p);
+ b32 = vec_ld(16, (vector bool int*)p);
+ f32 = vec_ld(16, (vector float*)p);
+ p16 = vec_ld(16, (vector pixel*)p);
+ g();
+ u8 = vec_lde(16, (unsigned char *)p);
+ u16 = vec_lde(16, (unsigned short*)p);
+ u32 = vec_lde(16, (unsigned int*)p);
+ s8 = vec_lde(16, (signed char *)p);
+ s16 = vec_lde(16, (short*)p);
+ s32 = vec_lde(16, (int*)p);
+ f32 = vec_ldl(16, (vector float*)p);
+ p16 = vec_ldl(16, (vector pixel*)p);
+ g();
+ u8 = vec_ldl(16, (vector unsigned char*)p);
+ s8 = vec_ldl(16, (vector signed char*)p);
+ b8 = vec_ldl(16, (vector bool char*)p);
+ g();
+ u16 = vec_ldl(16, (vector unsigned short*)p);
+ s16 = vec_ldl(16, (vector signed short*)p);
+ b16 = vec_ldl(16, (vector bool short*)p);
+ g();
+ u32 = vec_ldl(16, (vector unsigned int*)p);
+ s32 = vec_ldl(16, (vector signed int*)p);
+ b32 = vec_ldl(16, (vector bool int*)p);
+ f32 = vec_ldl(16, (vector float*)p);
+ p16 = vec_ldl(16, (vector pixel*)p);
+}
+
+static void g ()
+{
+}
+
+static void test()
+{
+ static vector unsigned int value = {1,-2,3,-4};
+ static vector unsigned int buffer[2];
+#define chek(v, s) check(vec_all_eq(v, value), s)
+ buffer[1] = value;
+ f((void *)buffer);
+ chek((vector unsigned int) u8, "u8");
+ chek((vector unsigned int) s8, "s8");
+ chek((vector unsigned int) b8, "b8");
+ chek((vector unsigned int) u16, "u16");
+ chek((vector unsigned int) s16, "s16");
+ chek((vector unsigned int) b16, "b16");
+ chek((vector unsigned int) u32, "u32");
+ chek((vector unsigned int) s32, "s32");
+ chek((vector unsigned int) b32, "b32");
+ chek((vector unsigned int) f32, "f32");
+ chek((vector unsigned int) p16, "p16");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/3c-01a.c b/gcc/testsuite/gcc.dg/vmx/3c-01a.c
new file mode 100644
index 00000000000..2499ca66598
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/3c-01a.c
@@ -0,0 +1,1450 @@
+/* { dg-do compile } */
+#include <altivec.h>
+typedef const volatile unsigned int _1;
+typedef const unsigned int _2;
+typedef volatile unsigned int _3;
+typedef unsigned int _4;
+typedef const volatile vector bool short _5;
+typedef const vector bool short _6;
+typedef volatile vector bool short _7;
+typedef vector bool short _8;
+typedef const volatile signed short _9;
+typedef const signed short _10;
+typedef volatile signed short _11;
+typedef signed short _12;
+typedef const volatile unsigned _13;
+typedef const unsigned _14;
+typedef volatile unsigned _15;
+typedef unsigned _16;
+typedef const volatile signed short int _17;
+typedef const signed short int _18;
+typedef volatile signed short int _19;
+typedef signed short int _20;
+typedef const volatile unsigned short int _21;
+typedef const unsigned short int _22;
+typedef volatile unsigned short int _23;
+typedef unsigned short int _24;
+typedef const volatile vector pixel _25;
+typedef const vector pixel _26;
+typedef volatile vector pixel _27;
+typedef vector pixel _28;
+typedef const volatile vector bool int _29;
+typedef const vector bool int _30;
+typedef volatile vector bool int _31;
+typedef vector bool int _32;
+typedef const volatile vector signed char _33;
+typedef const vector signed char _34;
+typedef volatile vector signed char _35;
+typedef vector signed char _36;
+typedef const volatile unsigned _37;
+typedef const unsigned _38;
+typedef volatile unsigned _39;
+typedef unsigned _40;
+typedef const volatile signed int _41;
+typedef const signed int _42;
+typedef volatile signed int _43;
+typedef signed int _44;
+typedef const volatile vector float _45;
+typedef const vector float _46;
+typedef volatile vector float _47;
+typedef vector float _48;
+typedef const volatile vector signed short _49;
+typedef const vector signed short _50;
+typedef volatile vector signed short _51;
+typedef vector signed short _52;
+typedef const volatile unsigned char _53;
+typedef const unsigned char _54;
+typedef volatile unsigned char _55;
+typedef unsigned char _56;
+typedef const volatile signed int _57;
+typedef const signed int _58;
+typedef volatile signed int _59;
+typedef signed int _60;
+typedef const volatile unsigned int _61;
+typedef const unsigned int _62;
+typedef volatile unsigned int _63;
+typedef unsigned int _64;
+typedef const volatile unsigned short _65;
+typedef const unsigned short _66;
+typedef volatile unsigned short _67;
+typedef unsigned short _68;
+typedef const volatile short _69;
+typedef const short _70;
+typedef volatile short _71;
+typedef short _72;
+typedef const volatile int _73;
+typedef const int _74;
+typedef volatile int _75;
+typedef int _76;
+typedef const volatile vector unsigned short _77;
+typedef const vector unsigned short _78;
+typedef volatile vector unsigned short _79;
+typedef vector unsigned short _80;
+typedef const volatile vector bool char _81;
+typedef const vector bool char _82;
+typedef volatile vector bool char _83;
+typedef vector bool char _84;
+typedef const volatile signed _85;
+typedef const signed _86;
+typedef volatile signed _87;
+typedef signed _88;
+typedef const volatile vector signed int _89;
+typedef const vector signed int _90;
+typedef volatile vector signed int _91;
+typedef vector signed int _92;
+typedef const volatile vector unsigned int _93;
+typedef const vector unsigned int _94;
+typedef volatile vector unsigned int _95;
+typedef vector unsigned int _96;
+typedef const volatile signed _97;
+typedef const signed _98;
+typedef volatile signed _99;
+typedef signed _100;
+typedef const volatile short int _101;
+typedef const short int _102;
+typedef volatile short int _103;
+typedef short int _104;
+typedef const volatile int _105;
+typedef const int _106;
+typedef volatile int _107;
+typedef int _108;
+typedef const volatile int _109;
+typedef const int _110;
+typedef volatile int _111;
+typedef int _112;
+typedef const volatile vector unsigned char _113;
+typedef const vector unsigned char _114;
+typedef volatile vector unsigned char _115;
+typedef vector unsigned char _116;
+typedef const volatile signed char _117;
+typedef const signed char _118;
+typedef volatile signed char _119;
+typedef signed char _120;
+typedef const volatile float _121;
+typedef const float _122;
+typedef volatile float _123;
+typedef float _124;
+
+vector unsigned char u8;
+vector signed char s8;
+vector bool char b8;
+vector unsigned short u16;
+vector signed short s16;
+vector bool short b16;
+vector unsigned int u32;
+vector signed int s32;
+vector bool int b32;
+vector float f32;
+vector pixel p16;
+
+void f(void *p)
+{
+ u8 = vec_lvsl(1,(const volatile unsigned int *)p);
+ u8 = vec_lvsl(1,(_1 *)p);
+ u8 = vec_lvsr(1,(const volatile unsigned int *)p);
+ u8 = vec_lvsr(1,(_1 *)p);
+ u8 = vec_lvsl(1,(const unsigned int *)p);
+ u8 = vec_lvsl(1,(_2 *)p);
+ u8 = vec_lvsr(1,(const unsigned int *)p);
+ u8 = vec_lvsr(1,(_2 *)p);
+ u32 = vec_ld(1,(const unsigned int *)p);
+ u32 = vec_ld(1,(_2 *)p);
+ u32 = vec_lde(1,(const unsigned int *)p);
+ u32 = vec_lde(1,(_2 *)p);
+ u32 = vec_ldl(1,(const unsigned int *)p);
+ u32 = vec_ldl(1,(_2 *)p);
+ vec_dst((const unsigned int *)p,1,1);
+ vec_dstst((const unsigned int *)p,1,1);
+ vec_dststt((const unsigned int *)p,1,1);
+ vec_dstt((const unsigned int *)p,1,1);
+ vec_dst((_2 *)p,1,1);
+ vec_dstst((_2 *)p,1,1);
+ vec_dststt((_2 *)p,1,1);
+ vec_dstt((_2 *)p,1,1);
+ u8 = vec_lvsl(1,( volatile unsigned int *)p);
+ u8 = vec_lvsl(1,(_3 *)p);
+ u8 = vec_lvsr(1,( volatile unsigned int *)p);
+ u8 = vec_lvsr(1,(_3 *)p);
+ u8 = vec_lvsl(1,( unsigned int *)p);
+ u8 = vec_lvsl(1,(_4 *)p);
+ u8 = vec_lvsr(1,( unsigned int *)p);
+ u8 = vec_lvsr(1,(_4 *)p);
+ u32 = vec_ld(1,( unsigned int *)p);
+ u32 = vec_ld(1,(_4 *)p);
+ u32 = vec_lde(1,( unsigned int *)p);
+ u32 = vec_lde(1,(_4 *)p);
+ u32 = vec_ldl(1,( unsigned int *)p);
+ u32 = vec_ldl(1,(_4 *)p);
+ vec_dst(( unsigned int *)p,1,1);
+ vec_dstst(( unsigned int *)p,1,1);
+ vec_dststt(( unsigned int *)p,1,1);
+ vec_dstt(( unsigned int *)p,1,1);
+ vec_dst((_4 *)p,1,1);
+ vec_dstst((_4 *)p,1,1);
+ vec_dststt((_4 *)p,1,1);
+ vec_dstt((_4 *)p,1,1);
+ vec_st(u32,1,( unsigned int *)p);
+ vec_st(u32,1,(_4 *)p);
+ vec_ste(u32,1,( unsigned int *)p);
+ vec_ste(u32,1,(_4 *)p);
+ vec_stl(u32,1,( unsigned int *)p);
+ vec_stl(u32,1,(_4 *)p);
+ b16 = vec_ld(1,(const vector bool short *)p);
+ b16 = vec_ld(1,(_6 *)p);
+ b16 = vec_ldl(1,(const vector bool short *)p);
+ b16 = vec_ldl(1,(_6 *)p);
+ vec_dst((const vector bool short *)p,1,1);
+ vec_dstst((const vector bool short *)p,1,1);
+ vec_dststt((const vector bool short *)p,1,1);
+ vec_dstt((const vector bool short *)p,1,1);
+ vec_dst((_6 *)p,1,1);
+ vec_dstst((_6 *)p,1,1);
+ vec_dststt((_6 *)p,1,1);
+ vec_dstt((_6 *)p,1,1);
+ b16 = vec_ld(1,( vector bool short *)p);
+ b16 = vec_ld(1,(_8 *)p);
+ b16 = vec_ldl(1,( vector bool short *)p);
+ b16 = vec_ldl(1,(_8 *)p);
+ vec_dst(( vector bool short *)p,1,1);
+ vec_dstst(( vector bool short *)p,1,1);
+ vec_dststt(( vector bool short *)p,1,1);
+ vec_dstt(( vector bool short *)p,1,1);
+ vec_dst((_8 *)p,1,1);
+ vec_dstst((_8 *)p,1,1);
+ vec_dststt((_8 *)p,1,1);
+ vec_dstt((_8 *)p,1,1);
+ vec_st(b16,1,( vector bool short *)p);
+ vec_st(b16,1,(_8 *)p);
+ vec_stl(b16,1,( vector bool short *)p);
+ vec_stl(b16,1,(_8 *)p);
+ u8 = vec_lvsl(1,(const volatile signed short *)p);
+ u8 = vec_lvsl(1,(_9 *)p);
+ u8 = vec_lvsr(1,(const volatile signed short *)p);
+ u8 = vec_lvsr(1,(_9 *)p);
+ u8 = vec_lvsl(1,(const signed short *)p);
+ u8 = vec_lvsl(1,(_10 *)p);
+ u8 = vec_lvsr(1,(const signed short *)p);
+ u8 = vec_lvsr(1,(_10 *)p);
+ s16 = vec_ld(1,(const signed short *)p);
+ s16 = vec_ld(1,(_10 *)p);
+ s16 = vec_lde(1,(const signed short *)p);
+ s16 = vec_lde(1,(_10 *)p);
+ s16 = vec_ldl(1,(const signed short *)p);
+ s16 = vec_ldl(1,(_10 *)p);
+ vec_dst((const signed short *)p,1,1);
+ vec_dstst((const signed short *)p,1,1);
+ vec_dststt((const signed short *)p,1,1);
+ vec_dstt((const signed short *)p,1,1);
+ vec_dst((_10 *)p,1,1);
+ vec_dstst((_10 *)p,1,1);
+ vec_dststt((_10 *)p,1,1);
+ vec_dstt((_10 *)p,1,1);
+ u8 = vec_lvsl(1,( volatile signed short *)p);
+ u8 = vec_lvsl(1,(_11 *)p);
+ u8 = vec_lvsr(1,( volatile signed short *)p);
+ u8 = vec_lvsr(1,(_11 *)p);
+ u8 = vec_lvsl(1,( signed short *)p);
+ u8 = vec_lvsl(1,(_12 *)p);
+ u8 = vec_lvsr(1,( signed short *)p);
+ u8 = vec_lvsr(1,(_12 *)p);
+ s16 = vec_ld(1,( signed short *)p);
+ s16 = vec_ld(1,(_12 *)p);
+ s16 = vec_lde(1,( signed short *)p);
+ s16 = vec_lde(1,(_12 *)p);
+ s16 = vec_ldl(1,( signed short *)p);
+ s16 = vec_ldl(1,(_12 *)p);
+ vec_dst(( signed short *)p,1,1);
+ vec_dstst(( signed short *)p,1,1);
+ vec_dststt(( signed short *)p,1,1);
+ vec_dstt(( signed short *)p,1,1);
+ vec_dst((_12 *)p,1,1);
+ vec_dstst((_12 *)p,1,1);
+ vec_dststt((_12 *)p,1,1);
+ vec_dstt((_12 *)p,1,1);
+ vec_st(s16,1,( signed short *)p);
+ vec_st(s16,1,(_12 *)p);
+ vec_ste(s16,1,( signed short *)p);
+ vec_ste(s16,1,(_12 *)p);
+ vec_stl(s16,1,( signed short *)p);
+ vec_stl(s16,1,(_12 *)p);
+ u8 = vec_lvsl(1,(const volatile unsigned *)p);
+ u8 = vec_lvsl(1,(_13 *)p);
+ u8 = vec_lvsr(1,(const volatile unsigned *)p);
+ u8 = vec_lvsr(1,(_13 *)p);
+ u8 = vec_lvsl(1,(const unsigned *)p);
+ u8 = vec_lvsl(1,(_14 *)p);
+ u8 = vec_lvsr(1,(const unsigned *)p);
+ u8 = vec_lvsr(1,(_14 *)p);
+ u32 = vec_ld(1,(const unsigned *)p);
+ u32 = vec_ld(1,(_14 *)p);
+ u32 = vec_lde(1,(const unsigned *)p);
+ u32 = vec_lde(1,(_14 *)p);
+ u32 = vec_ldl(1,(const unsigned *)p);
+ u32 = vec_ldl(1,(_14 *)p);
+ vec_dst((const unsigned *)p,1,1);
+ vec_dstst((const unsigned *)p,1,1);
+ vec_dststt((const unsigned *)p,1,1);
+ vec_dstt((const unsigned *)p,1,1);
+ vec_dst((_14 *)p,1,1);
+ vec_dstst((_14 *)p,1,1);
+ vec_dststt((_14 *)p,1,1);
+ vec_dstt((_14 *)p,1,1);
+ u8 = vec_lvsl(1,( volatile unsigned *)p);
+ u8 = vec_lvsl(1,(_15 *)p);
+ u8 = vec_lvsr(1,( volatile unsigned *)p);
+ u8 = vec_lvsr(1,(_15 *)p);
+ u8 = vec_lvsl(1,( unsigned *)p);
+ u8 = vec_lvsl(1,(_16 *)p);
+ u8 = vec_lvsr(1,( unsigned *)p);
+ u8 = vec_lvsr(1,(_16 *)p);
+ u32 = vec_ld(1,( unsigned *)p);
+ u32 = vec_ld(1,(_16 *)p);
+ u32 = vec_lde(1,( unsigned *)p);
+ u32 = vec_lde(1,(_16 *)p);
+ u32 = vec_ldl(1,( unsigned *)p);
+ u32 = vec_ldl(1,(_16 *)p);
+ vec_dst(( unsigned *)p,1,1);
+ vec_dstst(( unsigned *)p,1,1);
+ vec_dststt(( unsigned *)p,1,1);
+ vec_dstt(( unsigned *)p,1,1);
+ vec_dst((_16 *)p,1,1);
+ vec_dstst((_16 *)p,1,1);
+ vec_dststt((_16 *)p,1,1);
+ vec_dstt((_16 *)p,1,1);
+ vec_st(u32,1,( unsigned *)p);
+ vec_st(u32,1,(_16 *)p);
+ vec_ste(u32,1,( unsigned *)p);
+ vec_ste(u32,1,(_16 *)p);
+ vec_stl(u32,1,( unsigned *)p);
+ vec_stl(u32,1,(_16 *)p);
+ u8 = vec_lvsl(1,(const volatile signed short int *)p);
+ u8 = vec_lvsl(1,(_17 *)p);
+ u8 = vec_lvsr(1,(const volatile signed short int *)p);
+ u8 = vec_lvsr(1,(_17 *)p);
+ u8 = vec_lvsl(1,(const signed short int *)p);
+ u8 = vec_lvsl(1,(_18 *)p);
+ u8 = vec_lvsr(1,(const signed short int *)p);
+ u8 = vec_lvsr(1,(_18 *)p);
+ s16 = vec_ld(1,(const signed short int *)p);
+ s16 = vec_ld(1,(_18 *)p);
+ s16 = vec_lde(1,(const signed short int *)p);
+ s16 = vec_lde(1,(_18 *)p);
+ s16 = vec_ldl(1,(const signed short int *)p);
+ s16 = vec_ldl(1,(_18 *)p);
+ vec_dst((const signed short int *)p,1,1);
+ vec_dstst((const signed short int *)p,1,1);
+ vec_dststt((const signed short int *)p,1,1);
+ vec_dstt((const signed short int *)p,1,1);
+ vec_dst((_18 *)p,1,1);
+ vec_dstst((_18 *)p,1,1);
+ vec_dststt((_18 *)p,1,1);
+ vec_dstt((_18 *)p,1,1);
+ u8 = vec_lvsl(1,( volatile signed short int *)p);
+ u8 = vec_lvsl(1,(_19 *)p);
+ u8 = vec_lvsr(1,( volatile signed short int *)p);
+ u8 = vec_lvsr(1,(_19 *)p);
+ u8 = vec_lvsl(1,( signed short int *)p);
+ u8 = vec_lvsl(1,(_20 *)p);
+ u8 = vec_lvsr(1,( signed short int *)p);
+ u8 = vec_lvsr(1,(_20 *)p);
+ s16 = vec_ld(1,( signed short int *)p);
+ s16 = vec_ld(1,(_20 *)p);
+ s16 = vec_lde(1,( signed short int *)p);
+ s16 = vec_lde(1,(_20 *)p);
+ s16 = vec_ldl(1,( signed short int *)p);
+ s16 = vec_ldl(1,(_20 *)p);
+ vec_dst(( signed short int *)p,1,1);
+ vec_dstst(( signed short int *)p,1,1);
+ vec_dststt(( signed short int *)p,1,1);
+ vec_dstt(( signed short int *)p,1,1);
+ vec_dst((_20 *)p,1,1);
+ vec_dstst((_20 *)p,1,1);
+ vec_dststt((_20 *)p,1,1);
+ vec_dstt((_20 *)p,1,1);
+ vec_st(s16,1,( signed short int *)p);
+ vec_st(s16,1,(_20 *)p);
+ vec_ste(s16,1,( signed short int *)p);
+ vec_ste(s16,1,(_20 *)p);
+ vec_stl(s16,1,( signed short int *)p);
+ vec_stl(s16,1,(_20 *)p);
+ u8 = vec_lvsl(1,(const volatile unsigned short int *)p);
+ u8 = vec_lvsl(1,(_21 *)p);
+ u8 = vec_lvsr(1,(const volatile unsigned short int *)p);
+ u8 = vec_lvsr(1,(_21 *)p);
+ u8 = vec_lvsl(1,(const unsigned short int *)p);
+ u8 = vec_lvsl(1,(_22 *)p);
+ u8 = vec_lvsr(1,(const unsigned short int *)p);
+ u8 = vec_lvsr(1,(_22 *)p);
+ u16 = vec_ld(1,(const unsigned short int *)p);
+ u16 = vec_ld(1,(_22 *)p);
+ u16 = vec_lde(1,(const unsigned short int *)p);
+ u16 = vec_lde(1,(_22 *)p);
+ u16 = vec_ldl(1,(const unsigned short int *)p);
+ u16 = vec_ldl(1,(_22 *)p);
+ vec_dst((const unsigned short int *)p,1,1);
+ vec_dstst((const unsigned short int *)p,1,1);
+ vec_dststt((const unsigned short int *)p,1,1);
+ vec_dstt((const unsigned short int *)p,1,1);
+ vec_dst((_22 *)p,1,1);
+ vec_dstst((_22 *)p,1,1);
+ vec_dststt((_22 *)p,1,1);
+ vec_dstt((_22 *)p,1,1);
+ u8 = vec_lvsl(1,( volatile unsigned short int *)p);
+ u8 = vec_lvsl(1,(_23 *)p);
+ u8 = vec_lvsr(1,( volatile unsigned short int *)p);
+ u8 = vec_lvsr(1,(_23 *)p);
+ u8 = vec_lvsl(1,( unsigned short int *)p);
+ u8 = vec_lvsl(1,(_24 *)p);
+ u8 = vec_lvsr(1,( unsigned short int *)p);
+ u8 = vec_lvsr(1,(_24 *)p);
+ u16 = vec_ld(1,( unsigned short int *)p);
+ u16 = vec_ld(1,(_24 *)p);
+ u16 = vec_lde(1,( unsigned short int *)p);
+ u16 = vec_lde(1,(_24 *)p);
+ u16 = vec_ldl(1,( unsigned short int *)p);
+ u16 = vec_ldl(1,(_24 *)p);
+ vec_dst(( unsigned short int *)p,1,1);
+ vec_dstst(( unsigned short int *)p,1,1);
+ vec_dststt(( unsigned short int *)p,1,1);
+ vec_dstt(( unsigned short int *)p,1,1);
+ vec_dst((_24 *)p,1,1);
+ vec_dstst((_24 *)p,1,1);
+ vec_dststt((_24 *)p,1,1);
+ vec_dstt((_24 *)p,1,1);
+ vec_st(u16,1,( unsigned short int *)p);
+ vec_st(u16,1,(_24 *)p);
+ vec_ste(u16,1,( unsigned short int *)p);
+ vec_ste(u16,1,(_24 *)p);
+ vec_stl(u16,1,( unsigned short int *)p);
+ vec_stl(u16,1,(_24 *)p);
+ p16 = vec_ld(1,(const vector pixel *)p);
+ p16 = vec_ld(1,(_26 *)p);
+ p16 = vec_ldl(1,(const vector pixel *)p);
+ p16 = vec_ldl(1,(_26 *)p);
+ vec_dst((const vector pixel *)p,1,1);
+ vec_dstst((const vector pixel *)p,1,1);
+ vec_dststt((const vector pixel *)p,1,1);
+ vec_dstt((const vector pixel *)p,1,1);
+ vec_dst((_26 *)p,1,1);
+ vec_dstst((_26 *)p,1,1);
+ vec_dststt((_26 *)p,1,1);
+ vec_dstt((_26 *)p,1,1);
+ p16 = vec_ld(1,( vector pixel *)p);
+ p16 = vec_ld(1,(_28 *)p);
+ p16 = vec_ldl(1,( vector pixel *)p);
+ p16 = vec_ldl(1,(_28 *)p);
+ vec_dst(( vector pixel *)p,1,1);
+ vec_dstst(( vector pixel *)p,1,1);
+ vec_dststt(( vector pixel *)p,1,1);
+ vec_dstt(( vector pixel *)p,1,1);
+ vec_dst((_28 *)p,1,1);
+ vec_dstst((_28 *)p,1,1);
+ vec_dststt((_28 *)p,1,1);
+ vec_dstt((_28 *)p,1,1);
+ vec_st(p16,1,( vector pixel *)p);
+ vec_st(p16,1,(_28 *)p);
+ vec_stl(p16,1,( vector pixel *)p);
+ vec_stl(p16,1,(_28 *)p);
+ b32 = vec_ld(1,(const vector bool int *)p);
+ b32 = vec_ld(1,(_30 *)p);
+ b32 = vec_ldl(1,(const vector bool int *)p);
+ b32 = vec_ldl(1,(_30 *)p);
+ vec_dst((const vector bool int *)p,1,1);
+ vec_dstst((const vector bool int *)p,1,1);
+ vec_dststt((const vector bool int *)p,1,1);
+ vec_dstt((const vector bool int *)p,1,1);
+ vec_dst((_30 *)p,1,1);
+ vec_dstst((_30 *)p,1,1);
+ vec_dststt((_30 *)p,1,1);
+ vec_dstt((_30 *)p,1,1);
+ b32 = vec_ld(1,( vector bool int *)p);
+ b32 = vec_ld(1,(_32 *)p);
+ b32 = vec_ldl(1,( vector bool int *)p);
+ b32 = vec_ldl(1,(_32 *)p);
+ vec_dst(( vector bool int *)p,1,1);
+ vec_dstst(( vector bool int *)p,1,1);
+ vec_dststt(( vector bool int *)p,1,1);
+ vec_dstt(( vector bool int *)p,1,1);
+ vec_dst((_32 *)p,1,1);
+ vec_dstst((_32 *)p,1,1);
+ vec_dststt((_32 *)p,1,1);
+ vec_dstt((_32 *)p,1,1);
+ vec_st(b32,1,( vector bool int *)p);
+ vec_st(b32,1,(_32 *)p);
+ vec_stl(b32,1,( vector bool int *)p);
+ vec_stl(b32,1,(_32 *)p);
+ s8 = vec_ld(1,(const vector signed char *)p);
+ s8 = vec_ld(1,(_34 *)p);
+ s8 = vec_ldl(1,(const vector signed char *)p);
+ s8 = vec_ldl(1,(_34 *)p);
+ vec_dst((const vector signed char *)p,1,1);
+ vec_dstst((const vector signed char *)p,1,1);
+ vec_dststt((const vector signed char *)p,1,1);
+ vec_dstt((const vector signed char *)p,1,1);
+ vec_dst((_34 *)p,1,1);
+ vec_dstst((_34 *)p,1,1);
+ vec_dststt((_34 *)p,1,1);
+ vec_dstt((_34 *)p,1,1);
+ s8 = vec_ld(1,( vector signed char *)p);
+ s8 = vec_ld(1,(_36 *)p);
+ s8 = vec_ldl(1,( vector signed char *)p);
+ s8 = vec_ldl(1,(_36 *)p);
+ vec_dst(( vector signed char *)p,1,1);
+ vec_dstst(( vector signed char *)p,1,1);
+ vec_dststt(( vector signed char *)p,1,1);
+ vec_dstt(( vector signed char *)p,1,1);
+ vec_dst((_36 *)p,1,1);
+ vec_dstst((_36 *)p,1,1);
+ vec_dststt((_36 *)p,1,1);
+ vec_dstt((_36 *)p,1,1);
+ vec_st(s8,1,( vector signed char *)p);
+ vec_st(s8,1,(_36 *)p);
+ vec_stl(s8,1,( vector signed char *)p);
+ vec_stl(s8,1,(_36 *)p);
+ u8 = vec_lvsl(1,(const volatile unsigned *)p);
+ u8 = vec_lvsl(1,(_37 *)p);
+ u8 = vec_lvsr(1,(const volatile unsigned *)p);
+ u8 = vec_lvsr(1,(_37 *)p);
+ u8 = vec_lvsl(1,(const unsigned *)p);
+ u8 = vec_lvsl(1,(_38 *)p);
+ u8 = vec_lvsr(1,(const unsigned *)p);
+ u8 = vec_lvsr(1,(_38 *)p);
+ u32 = vec_ld(1,(const unsigned *)p);
+ u32 = vec_ld(1,(_38 *)p);
+ u32 = vec_lde(1,(const unsigned *)p);
+ u32 = vec_lde(1,(_38 *)p);
+ u32 = vec_ldl(1,(const unsigned *)p);
+ u32 = vec_ldl(1,(_38 *)p);
+ vec_dst((const unsigned *)p,1,1);
+ vec_dstst((const unsigned *)p,1,1);
+ vec_dststt((const unsigned *)p,1,1);
+ vec_dstt((const unsigned *)p,1,1);
+ vec_dst((_38 *)p,1,1);
+ vec_dstst((_38 *)p,1,1);
+ vec_dststt((_38 *)p,1,1);
+ vec_dstt((_38 *)p,1,1);
+ u8 = vec_lvsl(1,( volatile unsigned *)p);
+ u8 = vec_lvsl(1,(_39 *)p);
+ u8 = vec_lvsr(1,( volatile unsigned *)p);
+ u8 = vec_lvsr(1,(_39 *)p);
+ u8 = vec_lvsl(1,( unsigned *)p);
+ u8 = vec_lvsl(1,(_40 *)p);
+ u8 = vec_lvsr(1,( unsigned *)p);
+ u8 = vec_lvsr(1,(_40 *)p);
+ u32 = vec_ld(1,( unsigned *)p);
+ u32 = vec_ld(1,(_40 *)p);
+ u32 = vec_lde(1,( unsigned *)p);
+ u32 = vec_lde(1,(_40 *)p);
+ u32 = vec_ldl(1,( unsigned *)p);
+ u32 = vec_ldl(1,(_40 *)p);
+ vec_dst(( unsigned *)p,1,1);
+ vec_dstst(( unsigned *)p,1,1);
+ vec_dststt(( unsigned *)p,1,1);
+ vec_dstt(( unsigned *)p,1,1);
+ vec_dst((_40 *)p,1,1);
+ vec_dstst((_40 *)p,1,1);
+ vec_dststt((_40 *)p,1,1);
+ vec_dstt((_40 *)p,1,1);
+ vec_st(u32,1,( unsigned *)p);
+ vec_st(u32,1,(_40 *)p);
+ vec_ste(u32,1,( unsigned *)p);
+ vec_ste(u32,1,(_40 *)p);
+ vec_stl(u32,1,( unsigned *)p);
+ vec_stl(u32,1,(_40 *)p);
+ u8 = vec_lvsl(1,(const volatile signed int *)p);
+ u8 = vec_lvsl(1,(_41 *)p);
+ u8 = vec_lvsr(1,(const volatile signed int *)p);
+ u8 = vec_lvsr(1,(_41 *)p);
+ u8 = vec_lvsl(1,(const signed int *)p);
+ u8 = vec_lvsl(1,(_42 *)p);
+ u8 = vec_lvsr(1,(const signed int *)p);
+ u8 = vec_lvsr(1,(_42 *)p);
+ s32 = vec_ld(1,(const signed int *)p);
+ s32 = vec_ld(1,(_42 *)p);
+ s32 = vec_lde(1,(const signed int *)p);
+ s32 = vec_lde(1,(_42 *)p);
+ s32 = vec_ldl(1,(const signed int *)p);
+ s32 = vec_ldl(1,(_42 *)p);
+ vec_dst((const signed int *)p,1,1);
+ vec_dstst((const signed int *)p,1,1);
+ vec_dststt((const signed int *)p,1,1);
+ vec_dstt((const signed int *)p,1,1);
+ vec_dst((_42 *)p,1,1);
+ vec_dstst((_42 *)p,1,1);
+ vec_dststt((_42 *)p,1,1);
+ vec_dstt((_42 *)p,1,1);
+ u8 = vec_lvsl(1,( volatile signed int *)p);
+ u8 = vec_lvsl(1,(_43 *)p);
+ u8 = vec_lvsr(1,( volatile signed int *)p);
+ u8 = vec_lvsr(1,(_43 *)p);
+ u8 = vec_lvsl(1,( signed int *)p);
+ u8 = vec_lvsl(1,(_44 *)p);
+ u8 = vec_lvsr(1,( signed int *)p);
+ u8 = vec_lvsr(1,(_44 *)p);
+ s32 = vec_ld(1,( signed int *)p);
+ s32 = vec_ld(1,(_44 *)p);
+ s32 = vec_lde(1,( signed int *)p);
+ s32 = vec_lde(1,(_44 *)p);
+ s32 = vec_ldl(1,( signed int *)p);
+ s32 = vec_ldl(1,(_44 *)p);
+ vec_dst(( signed int *)p,1,1);
+ vec_dstst(( signed int *)p,1,1);
+ vec_dststt(( signed int *)p,1,1);
+ vec_dstt(( signed int *)p,1,1);
+ vec_dst((_44 *)p,1,1);
+ vec_dstst((_44 *)p,1,1);
+ vec_dststt((_44 *)p,1,1);
+ vec_dstt((_44 *)p,1,1);
+ vec_st(s32,1,( signed int *)p);
+ vec_st(s32,1,(_44 *)p);
+ vec_ste(s32,1,( signed int *)p);
+ vec_ste(s32,1,(_44 *)p);
+ vec_stl(s32,1,( signed int *)p);
+ vec_stl(s32,1,(_44 *)p);
+ f32 = vec_ld(1,(const vector float *)p);
+ f32 = vec_ld(1,(_46 *)p);
+ f32 = vec_ldl(1,(const vector float *)p);
+ f32 = vec_ldl(1,(_46 *)p);
+ vec_dst((const vector float *)p,1,1);
+ vec_dstst((const vector float *)p,1,1);
+ vec_dststt((const vector float *)p,1,1);
+ vec_dstt((const vector float *)p,1,1);
+ vec_dst((_46 *)p,1,1);
+ vec_dstst((_46 *)p,1,1);
+ vec_dststt((_46 *)p,1,1);
+ vec_dstt((_46 *)p,1,1);
+ f32 = vec_ld(1,( vector float *)p);
+ f32 = vec_ld(1,(_48 *)p);
+ f32 = vec_ldl(1,( vector float *)p);
+ f32 = vec_ldl(1,(_48 *)p);
+ vec_dst(( vector float *)p,1,1);
+ vec_dstst(( vector float *)p,1,1);
+ vec_dststt(( vector float *)p,1,1);
+ vec_dstt(( vector float *)p,1,1);
+ vec_dst((_48 *)p,1,1);
+ vec_dstst((_48 *)p,1,1);
+ vec_dststt((_48 *)p,1,1);
+ vec_dstt((_48 *)p,1,1);
+ vec_st(f32,1,( vector float *)p);
+ vec_st(f32,1,(_48 *)p);
+ vec_stl(f32,1,( vector float *)p);
+ vec_stl(f32,1,(_48 *)p);
+ s16 = vec_ld(1,(const vector signed short *)p);
+ s16 = vec_ld(1,(_50 *)p);
+ s16 = vec_ldl(1,(const vector signed short *)p);
+ s16 = vec_ldl(1,(_50 *)p);
+ vec_dst((const vector signed short *)p,1,1);
+ vec_dstst((const vector signed short *)p,1,1);
+ vec_dststt((const vector signed short *)p,1,1);
+ vec_dstt((const vector signed short *)p,1,1);
+ vec_dst((_50 *)p,1,1);
+ vec_dstst((_50 *)p,1,1);
+ vec_dststt((_50 *)p,1,1);
+ vec_dstt((_50 *)p,1,1);
+ s16 = vec_ld(1,( vector signed short *)p);
+ s16 = vec_ld(1,(_52 *)p);
+ s16 = vec_ldl(1,( vector signed short *)p);
+ s16 = vec_ldl(1,(_52 *)p);
+ vec_dst(( vector signed short *)p,1,1);
+ vec_dstst(( vector signed short *)p,1,1);
+ vec_dststt(( vector signed short *)p,1,1);
+ vec_dstt(( vector signed short *)p,1,1);
+ vec_dst((_52 *)p,1,1);
+ vec_dstst((_52 *)p,1,1);
+ vec_dststt((_52 *)p,1,1);
+ vec_dstt((_52 *)p,1,1);
+ vec_st(s16,1,( vector signed short *)p);
+ vec_st(s16,1,(_52 *)p);
+ vec_stl(s16,1,( vector signed short *)p);
+ vec_stl(s16,1,(_52 *)p);
+ u8 = vec_lvsl(1,(const volatile unsigned char *)p);
+ u8 = vec_lvsl(1,(_53 *)p);
+ u8 = vec_lvsr(1,(const volatile unsigned char *)p);
+ u8 = vec_lvsr(1,(_53 *)p);
+ u8 = vec_lvsl(1,(const unsigned char *)p);
+ u8 = vec_lvsl(1,(_54 *)p);
+ u8 = vec_lvsr(1,(const unsigned char *)p);
+ u8 = vec_lvsr(1,(_54 *)p);
+ u8 = vec_ld(1,(const unsigned char *)p);
+ u8 = vec_ld(1,(_54 *)p);
+ u8 = vec_lde(1,(const unsigned char *)p);
+ u8 = vec_lde(1,(_54 *)p);
+ u8 = vec_ldl(1,(const unsigned char *)p);
+ u8 = vec_ldl(1,(_54 *)p);
+ vec_dst((const unsigned char *)p,1,1);
+ vec_dstst((const unsigned char *)p,1,1);
+ vec_dststt((const unsigned char *)p,1,1);
+ vec_dstt((const unsigned char *)p,1,1);
+ vec_dst((_54 *)p,1,1);
+ vec_dstst((_54 *)p,1,1);
+ vec_dststt((_54 *)p,1,1);
+ vec_dstt((_54 *)p,1,1);
+ u8 = vec_lvsl(1,( volatile unsigned char *)p);
+ u8 = vec_lvsl(1,(_55 *)p);
+ u8 = vec_lvsr(1,( volatile unsigned char *)p);
+ u8 = vec_lvsr(1,(_55 *)p);
+ u8 = vec_lvsl(1,( unsigned char *)p);
+ u8 = vec_lvsl(1,(_56 *)p);
+ u8 = vec_lvsr(1,( unsigned char *)p);
+ u8 = vec_lvsr(1,(_56 *)p);
+ u8 = vec_ld(1,( unsigned char *)p);
+ u8 = vec_ld(1,(_56 *)p);
+ u8 = vec_lde(1,( unsigned char *)p);
+ u8 = vec_lde(1,(_56 *)p);
+ u8 = vec_ldl(1,( unsigned char *)p);
+ u8 = vec_ldl(1,(_56 *)p);
+ vec_dst(( unsigned char *)p,1,1);
+ vec_dstst(( unsigned char *)p,1,1);
+ vec_dststt(( unsigned char *)p,1,1);
+ vec_dstt(( unsigned char *)p,1,1);
+ vec_dst((_56 *)p,1,1);
+ vec_dstst((_56 *)p,1,1);
+ vec_dststt((_56 *)p,1,1);
+ vec_dstt((_56 *)p,1,1);
+ vec_st(u8,1,( unsigned char *)p);
+ vec_st(u8,1,(_56 *)p);
+ vec_ste(u8,1,( unsigned char *)p);
+ vec_ste(u8,1,(_56 *)p);
+ vec_stl(u8,1,( unsigned char *)p);
+ vec_stl(u8,1,(_56 *)p);
+ u8 = vec_lvsl(1,(const volatile signed int *)p);
+ u8 = vec_lvsl(1,(_57 *)p);
+ u8 = vec_lvsr(1,(const volatile signed int *)p);
+ u8 = vec_lvsr(1,(_57 *)p);
+ u8 = vec_lvsl(1,(const signed int *)p);
+ u8 = vec_lvsl(1,(_58 *)p);
+ u8 = vec_lvsr(1,(const signed int *)p);
+ u8 = vec_lvsr(1,(_58 *)p);
+ s32 = vec_ld(1,(const signed int *)p);
+ s32 = vec_ld(1,(_58 *)p);
+ s32 = vec_lde(1,(const signed int *)p);
+ s32 = vec_lde(1,(_58 *)p);
+ s32 = vec_ldl(1,(const signed int *)p);
+ s32 = vec_ldl(1,(_58 *)p);
+ vec_dst((const signed int *)p,1,1);
+ vec_dstst((const signed int *)p,1,1);
+ vec_dststt((const signed int *)p,1,1);
+ vec_dstt((const signed int *)p,1,1);
+ vec_dst((_58 *)p,1,1);
+ vec_dstst((_58 *)p,1,1);
+ vec_dststt((_58 *)p,1,1);
+ vec_dstt((_58 *)p,1,1);
+ u8 = vec_lvsl(1,( volatile signed int *)p);
+ u8 = vec_lvsl(1,(_59 *)p);
+ u8 = vec_lvsr(1,( volatile signed int *)p);
+ u8 = vec_lvsr(1,(_59 *)p);
+ u8 = vec_lvsl(1,( signed int *)p);
+ u8 = vec_lvsl(1,(_60 *)p);
+ u8 = vec_lvsr(1,( signed int *)p);
+ u8 = vec_lvsr(1,(_60 *)p);
+ s32 = vec_ld(1,( signed int *)p);
+ s32 = vec_ld(1,(_60 *)p);
+ s32 = vec_lde(1,( signed int *)p);
+ s32 = vec_lde(1,(_60 *)p);
+ s32 = vec_ldl(1,( signed int *)p);
+ s32 = vec_ldl(1,(_60 *)p);
+ vec_dst(( signed int *)p,1,1);
+ vec_dstst(( signed int *)p,1,1);
+ vec_dststt(( signed int *)p,1,1);
+ vec_dstt(( signed int *)p,1,1);
+ vec_dst((_60 *)p,1,1);
+ vec_dstst((_60 *)p,1,1);
+ vec_dststt((_60 *)p,1,1);
+ vec_dstt((_60 *)p,1,1);
+ vec_st(s32,1,( signed int *)p);
+ vec_st(s32,1,(_60 *)p);
+ vec_ste(s32,1,( signed int *)p);
+ vec_ste(s32,1,(_60 *)p);
+ vec_stl(s32,1,( signed int *)p);
+ vec_stl(s32,1,(_60 *)p);
+ u8 = vec_lvsl(1,(const volatile unsigned int *)p);
+ u8 = vec_lvsl(1,(_61 *)p);
+ u8 = vec_lvsr(1,(const volatile unsigned int *)p);
+ u8 = vec_lvsr(1,(_61 *)p);
+ u8 = vec_lvsl(1,(const unsigned int *)p);
+ u8 = vec_lvsl(1,(_62 *)p);
+ u8 = vec_lvsr(1,(const unsigned int *)p);
+ u8 = vec_lvsr(1,(_62 *)p);
+ u32 = vec_ld(1,(const unsigned int *)p);
+ u32 = vec_ld(1,(_62 *)p);
+ u32 = vec_lde(1,(const unsigned int *)p);
+ u32 = vec_lde(1,(_62 *)p);
+ u32 = vec_ldl(1,(const unsigned int *)p);
+ u32 = vec_ldl(1,(_62 *)p);
+ vec_dst((const unsigned int *)p,1,1);
+ vec_dstst((const unsigned int *)p,1,1);
+ vec_dststt((const unsigned int *)p,1,1);
+ vec_dstt((const unsigned int *)p,1,1);
+ vec_dst((_62 *)p,1,1);
+ vec_dstst((_62 *)p,1,1);
+ vec_dststt((_62 *)p,1,1);
+ vec_dstt((_62 *)p,1,1);
+ u8 = vec_lvsl(1,( volatile unsigned int *)p);
+ u8 = vec_lvsl(1,(_63 *)p);
+ u8 = vec_lvsr(1,( volatile unsigned int *)p);
+ u8 = vec_lvsr(1,(_63 *)p);
+ u8 = vec_lvsl(1,( unsigned int *)p);
+ u8 = vec_lvsl(1,(_64 *)p);
+ u8 = vec_lvsr(1,( unsigned int *)p);
+ u8 = vec_lvsr(1,(_64 *)p);
+ u32 = vec_ld(1,( unsigned int *)p);
+ u32 = vec_ld(1,(_64 *)p);
+ u32 = vec_lde(1,( unsigned int *)p);
+ u32 = vec_lde(1,(_64 *)p);
+ u32 = vec_ldl(1,( unsigned int *)p);
+ u32 = vec_ldl(1,(_64 *)p);
+ vec_dst(( unsigned int *)p,1,1);
+ vec_dstst(( unsigned int *)p,1,1);
+ vec_dststt(( unsigned int *)p,1,1);
+ vec_dstt(( unsigned int *)p,1,1);
+ vec_dst((_64 *)p,1,1);
+ vec_dstst((_64 *)p,1,1);
+ vec_dststt((_64 *)p,1,1);
+ vec_dstt((_64 *)p,1,1);
+ vec_st(u32,1,( unsigned int *)p);
+ vec_st(u32,1,(_64 *)p);
+ vec_ste(u32,1,( unsigned int *)p);
+ vec_ste(u32,1,(_64 *)p);
+ vec_stl(u32,1,( unsigned int *)p);
+ vec_stl(u32,1,(_64 *)p);
+ u8 = vec_lvsl(1,(const volatile unsigned short *)p);
+ u8 = vec_lvsl(1,(_65 *)p);
+ u8 = vec_lvsr(1,(const volatile unsigned short *)p);
+ u8 = vec_lvsr(1,(_65 *)p);
+ u8 = vec_lvsl(1,(const unsigned short *)p);
+ u8 = vec_lvsl(1,(_66 *)p);
+ u8 = vec_lvsr(1,(const unsigned short *)p);
+ u8 = vec_lvsr(1,(_66 *)p);
+ u16 = vec_ld(1,(const unsigned short *)p);
+ u16 = vec_ld(1,(_66 *)p);
+ u16 = vec_lde(1,(const unsigned short *)p);
+ u16 = vec_lde(1,(_66 *)p);
+ u16 = vec_ldl(1,(const unsigned short *)p);
+ u16 = vec_ldl(1,(_66 *)p);
+ vec_dst((const unsigned short *)p,1,1);
+ vec_dstst((const unsigned short *)p,1,1);
+ vec_dststt((const unsigned short *)p,1,1);
+ vec_dstt((const unsigned short *)p,1,1);
+ vec_dst((_66 *)p,1,1);
+ vec_dstst((_66 *)p,1,1);
+ vec_dststt((_66 *)p,1,1);
+ vec_dstt((_66 *)p,1,1);
+ u8 = vec_lvsl(1,( volatile unsigned short *)p);
+ u8 = vec_lvsl(1,(_67 *)p);
+ u8 = vec_lvsr(1,( volatile unsigned short *)p);
+ u8 = vec_lvsr(1,(_67 *)p);
+ u8 = vec_lvsl(1,( unsigned short *)p);
+ u8 = vec_lvsl(1,(_68 *)p);
+ u8 = vec_lvsr(1,( unsigned short *)p);
+ u8 = vec_lvsr(1,(_68 *)p);
+ u16 = vec_ld(1,( unsigned short *)p);
+ u16 = vec_ld(1,(_68 *)p);
+ u16 = vec_lde(1,( unsigned short *)p);
+ u16 = vec_lde(1,(_68 *)p);
+ u16 = vec_ldl(1,( unsigned short *)p);
+ u16 = vec_ldl(1,(_68 *)p);
+ vec_dst(( unsigned short *)p,1,1);
+ vec_dstst(( unsigned short *)p,1,1);
+ vec_dststt(( unsigned short *)p,1,1);
+ vec_dstt(( unsigned short *)p,1,1);
+ vec_dst((_68 *)p,1,1);
+ vec_dstst((_68 *)p,1,1);
+ vec_dststt((_68 *)p,1,1);
+ vec_dstt((_68 *)p,1,1);
+ vec_st(u16,1,( unsigned short *)p);
+ vec_st(u16,1,(_68 *)p);
+ vec_ste(u16,1,( unsigned short *)p);
+ vec_ste(u16,1,(_68 *)p);
+ vec_stl(u16,1,( unsigned short *)p);
+ vec_stl(u16,1,(_68 *)p);
+ u8 = vec_lvsl(1,(const volatile short *)p);
+ u8 = vec_lvsl(1,(_69 *)p);
+ u8 = vec_lvsr(1,(const volatile short *)p);
+ u8 = vec_lvsr(1,(_69 *)p);
+ u8 = vec_lvsl(1,(const short *)p);
+ u8 = vec_lvsl(1,(_70 *)p);
+ u8 = vec_lvsr(1,(const short *)p);
+ u8 = vec_lvsr(1,(_70 *)p);
+ s16 = vec_ld(1,(const short *)p);
+ s16 = vec_ld(1,(_70 *)p);
+ s16 = vec_lde(1,(const short *)p);
+ s16 = vec_lde(1,(_70 *)p);
+ s16 = vec_ldl(1,(const short *)p);
+ s16 = vec_ldl(1,(_70 *)p);
+ vec_dst((const short *)p,1,1);
+ vec_dstst((const short *)p,1,1);
+ vec_dststt((const short *)p,1,1);
+ vec_dstt((const short *)p,1,1);
+ vec_dst((_70 *)p,1,1);
+ vec_dstst((_70 *)p,1,1);
+ vec_dststt((_70 *)p,1,1);
+ vec_dstt((_70 *)p,1,1);
+ u8 = vec_lvsl(1,( volatile short *)p);
+ u8 = vec_lvsl(1,(_71 *)p);
+ u8 = vec_lvsr(1,( volatile short *)p);
+ u8 = vec_lvsr(1,(_71 *)p);
+ u8 = vec_lvsl(1,( short *)p);
+ u8 = vec_lvsl(1,(_72 *)p);
+ u8 = vec_lvsr(1,( short *)p);
+ u8 = vec_lvsr(1,(_72 *)p);
+ s16 = vec_ld(1,( short *)p);
+ s16 = vec_ld(1,(_72 *)p);
+ s16 = vec_lde(1,( short *)p);
+ s16 = vec_lde(1,(_72 *)p);
+ s16 = vec_ldl(1,( short *)p);
+ s16 = vec_ldl(1,(_72 *)p);
+ vec_dst(( short *)p,1,1);
+ vec_dstst(( short *)p,1,1);
+ vec_dststt(( short *)p,1,1);
+ vec_dstt(( short *)p,1,1);
+ vec_dst((_72 *)p,1,1);
+ vec_dstst((_72 *)p,1,1);
+ vec_dststt((_72 *)p,1,1);
+ vec_dstt((_72 *)p,1,1);
+ vec_st(s16,1,( short *)p);
+ vec_st(s16,1,(_72 *)p);
+ vec_ste(s16,1,( short *)p);
+ vec_ste(s16,1,(_72 *)p);
+ vec_stl(s16,1,( short *)p);
+ vec_stl(s16,1,(_72 *)p);
+ u8 = vec_lvsl(1,(const int volatile *)p);
+ u8 = vec_lvsl(1,(_73 *)p);
+ u8 = vec_lvsr(1,(const int volatile *)p);
+ u8 = vec_lvsr(1,(_73 *)p);
+ u8 = vec_lvsl(1,(const int *)p);
+ u8 = vec_lvsl(1,(_74 *)p);
+ u8 = vec_lvsr(1,(const int *)p);
+ u8 = vec_lvsr(1,(_74 *)p);
+ s32 = vec_ld(1,(const int *)p);
+ s32 = vec_ld(1,(_74 *)p);
+ s32 = vec_lde(1,(const int *)p);
+ s32 = vec_lde(1,(_74 *)p);
+ s32 = vec_ldl(1,(const int *)p);
+ s32 = vec_ldl(1,(_74 *)p);
+ vec_dst((const int *)p,1,1);
+ vec_dstst((const int *)p,1,1);
+ vec_dststt((const int *)p,1,1);
+ vec_dstt((const int *)p,1,1);
+ vec_dst((_74 *)p,1,1);
+ vec_dstst((_74 *)p,1,1);
+ vec_dststt((_74 *)p,1,1);
+ vec_dstt((_74 *)p,1,1);
+ u8 = vec_lvsl(1,( volatile int *)p);
+ u8 = vec_lvsl(1,(_75 *)p);
+ u8 = vec_lvsr(1,( volatile int *)p);
+ u8 = vec_lvsr(1,(_75 *)p);
+ u8 = vec_lvsl(1,( int *)p);
+ u8 = vec_lvsl(1,(_76 *)p);
+ u8 = vec_lvsr(1,( int *)p);
+ u8 = vec_lvsr(1,(_76 *)p);
+ s32 = vec_ld(1,( int *)p);
+ s32 = vec_ld(1,(_76 *)p);
+ s32 = vec_lde(1,(int *)p);
+ s32 = vec_lde(1,(_76 *)p);
+ s32 = vec_ldl(1,(int *)p);
+ s32 = vec_ldl(1,(_76 *)p);
+ vec_dst((int *)p,1,1);
+ vec_dstst((int *)p,1,1);
+ vec_dststt((int *)p,1,1);
+ vec_dstt((int *)p,1,1);
+ vec_dst((_76 *)p,1,1);
+ vec_dstst((_76 *)p,1,1);
+ vec_dststt((_76 *)p,1,1);
+ vec_dstt((_76 *)p,1,1);
+ vec_st(s32,1,(int *)p);
+ vec_st(s32,1,(_76 *)p);
+ vec_ste(s32,1,(int *)p);
+ vec_ste(s32,1,(_76 *)p);
+ vec_stl(s32,1,(int *)p);
+ vec_stl(s32,1,(_76 *)p);
+ u16 = vec_ld(1,(const vector unsigned short *)p);
+ u16 = vec_ld(1,(_78 *)p);
+ u16 = vec_ldl(1,(const vector unsigned short *)p);
+ u16 = vec_ldl(1,(_78 *)p);
+ vec_dst((const vector unsigned short *)p,1,1);
+ vec_dstst((const vector unsigned short *)p,1,1);
+ vec_dststt((const vector unsigned short *)p,1,1);
+ vec_dstt((const vector unsigned short *)p,1,1);
+ vec_dst((_78 *)p,1,1);
+ vec_dstst((_78 *)p,1,1);
+ vec_dststt((_78 *)p,1,1);
+ vec_dstt((_78 *)p,1,1);
+ u16 = vec_ld(1,( vector unsigned short *)p);
+ u16 = vec_ld(1,(_80 *)p);
+ u16 = vec_ldl(1,( vector unsigned short *)p);
+ u16 = vec_ldl(1,(_80 *)p);
+ vec_dst(( vector unsigned short *)p,1,1);
+ vec_dstst(( vector unsigned short *)p,1,1);
+ vec_dststt(( vector unsigned short *)p,1,1);
+ vec_dstt(( vector unsigned short *)p,1,1);
+ vec_dst((_80 *)p,1,1);
+ vec_dstst((_80 *)p,1,1);
+ vec_dststt((_80 *)p,1,1);
+ vec_dstt((_80 *)p,1,1);
+ vec_st(u16,1,( vector unsigned short *)p);
+ vec_st(u16,1,(_80 *)p);
+ vec_stl(u16,1,( vector unsigned short *)p);
+ vec_stl(u16,1,(_80 *)p);
+ b8 = vec_ld(1,(const vector bool char *)p);
+ b8 = vec_ld(1,(_82 *)p);
+ b8 = vec_ldl(1,(const vector bool char *)p);
+ b8 = vec_ldl(1,(_82 *)p);
+ vec_dst((const vector bool char *)p,1,1);
+ vec_dstst((const vector bool char *)p,1,1);
+ vec_dststt((const vector bool char *)p,1,1);
+ vec_dstt((const vector bool char *)p,1,1);
+ vec_dst((_82 *)p,1,1);
+ vec_dstst((_82 *)p,1,1);
+ vec_dststt((_82 *)p,1,1);
+ vec_dstt((_82 *)p,1,1);
+ b8 = vec_ld(1,( vector bool char *)p);
+ b8 = vec_ld(1,(_84 *)p);
+ b8 = vec_ldl(1,( vector bool char *)p);
+ b8 = vec_ldl(1,(_84 *)p);
+ vec_dst(( vector bool char *)p,1,1);
+ vec_dstst(( vector bool char *)p,1,1);
+ vec_dststt(( vector bool char *)p,1,1);
+ vec_dstt(( vector bool char *)p,1,1);
+ vec_dst((_84 *)p,1,1);
+ vec_dstst((_84 *)p,1,1);
+ vec_dststt((_84 *)p,1,1);
+ vec_dstt((_84 *)p,1,1);
+ vec_st(b8,1,( vector bool char *)p);
+ vec_st(b8,1,(_84 *)p);
+ vec_stl(b8,1,( vector bool char *)p);
+ vec_stl(b8,1,(_84 *)p);
+ u8 = vec_lvsl(1,(const volatile int signed *)p);
+ u8 = vec_lvsl(1,(_85 *)p);
+ u8 = vec_lvsr(1,(const volatile int signed *)p);
+ u8 = vec_lvsr(1,(_85 *)p);
+ u8 = vec_lvsl(1,(const int signed *)p);
+ u8 = vec_lvsl(1,(_86 *)p);
+ u8 = vec_lvsr(1,(const int signed *)p);
+ u8 = vec_lvsr(1,(_86 *)p);
+ s32 = vec_ld(1,(const int signed *)p);
+ s32 = vec_ld(1,(_86 *)p);
+ s32 = vec_lde(1,(const int signed *)p);
+ s32 = vec_lde(1,(_86 *)p);
+ s32 = vec_ldl(1,(const int signed *)p);
+ s32 = vec_ldl(1,(_86 *)p);
+ vec_dst((const int signed *)p,1,1);
+ vec_dstst((const int signed *)p,1,1);
+ vec_dststt((const int signed *)p,1,1);
+ vec_dstt((const int signed *)p,1,1);
+ vec_dst((_86 *)p,1,1);
+ vec_dstst((_86 *)p,1,1);
+ vec_dststt((_86 *)p,1,1);
+ vec_dstt((_86 *)p,1,1);
+ u8 = vec_lvsl(1,( volatile int signed *)p);
+ u8 = vec_lvsl(1,(_87 *)p);
+ u8 = vec_lvsr(1,( volatile int signed *)p);
+ u8 = vec_lvsr(1,(_87 *)p);
+ u8 = vec_lvsl(1,(int signed *)p);
+ u8 = vec_lvsl(1,(_88 *)p);
+ u8 = vec_lvsr(1,(int signed *)p);
+ u8 = vec_lvsr(1,(_88 *)p);
+ s32 = vec_ld(1,(int signed *)p);
+ s32 = vec_ld(1,(_88 *)p);
+ s32 = vec_lde(1,(int signed *)p);
+ s32 = vec_lde(1,(_88 *)p);
+ s32 = vec_ldl(1,(int signed *)p);
+ s32 = vec_ldl(1,(_88 *)p);
+ vec_dst((int signed *)p,1,1);
+ vec_dstst((int signed *)p,1,1);
+ vec_dststt((int signed *)p,1,1);
+ vec_dstt((int signed *)p,1,1);
+ vec_dst((_88 *)p,1,1);
+ vec_dstst((_88 *)p,1,1);
+ vec_dststt((_88 *)p,1,1);
+ vec_dstt((_88 *)p,1,1);
+ vec_st(s32,1,(int signed *)p);
+ vec_st(s32,1,(_88 *)p);
+ vec_ste(s32,1,(int signed *)p);
+ vec_ste(s32,1,(_88 *)p);
+ vec_stl(s32,1,(int signed *)p);
+ vec_stl(s32,1,(_88 *)p);
+ s32 = vec_ld(1,(const vector signed int *)p);
+ s32 = vec_ld(1,(_90 *)p);
+ s32 = vec_ldl(1,(const vector signed int *)p);
+ s32 = vec_ldl(1,(_90 *)p);
+ vec_dst((const vector signed int *)p,1,1);
+ vec_dstst((const vector signed int *)p,1,1);
+ vec_dststt((const vector signed int *)p,1,1);
+ vec_dstt((const vector signed int *)p,1,1);
+ vec_dst((_90 *)p,1,1);
+ vec_dstst((_90 *)p,1,1);
+ vec_dststt((_90 *)p,1,1);
+ vec_dstt((_90 *)p,1,1);
+ s32 = vec_ld(1,( vector signed int *)p);
+ s32 = vec_ld(1,(_92 *)p);
+ s32 = vec_ldl(1,( vector signed int *)p);
+ s32 = vec_ldl(1,(_92 *)p);
+ vec_dst(( vector signed int *)p,1,1);
+ vec_dstst(( vector signed int *)p,1,1);
+ vec_dststt(( vector signed int *)p,1,1);
+ vec_dstt(( vector signed int *)p,1,1);
+ vec_dst((_92 *)p,1,1);
+ vec_dstst((_92 *)p,1,1);
+ vec_dststt((_92 *)p,1,1);
+ vec_dstt((_92 *)p,1,1);
+ vec_st(s32,1,( vector signed int *)p);
+ vec_st(s32,1,(_92 *)p);
+ vec_stl(s32,1,( vector signed int *)p);
+ vec_stl(s32,1,(_92 *)p);
+ u32 = vec_ld(1,(const vector unsigned int *)p);
+ u32 = vec_ld(1,(_94 *)p);
+ u32 = vec_ldl(1,(const vector unsigned int *)p);
+ u32 = vec_ldl(1,(_94 *)p);
+ vec_dst((const vector unsigned int *)p,1,1);
+ vec_dstst((const vector unsigned int *)p,1,1);
+ vec_dststt((const vector unsigned int *)p,1,1);
+ vec_dstt((const vector unsigned int *)p,1,1);
+ vec_dst((_94 *)p,1,1);
+ vec_dstst((_94 *)p,1,1);
+ vec_dststt((_94 *)p,1,1);
+ vec_dstt((_94 *)p,1,1);
+ u32 = vec_ld(1,( vector unsigned int *)p);
+ u32 = vec_ld(1,(_96 *)p);
+ u32 = vec_ldl(1,( vector unsigned int *)p);
+ u32 = vec_ldl(1,(_96 *)p);
+ vec_dst(( vector unsigned int *)p,1,1);
+ vec_dstst(( vector unsigned int *)p,1,1);
+ vec_dststt(( vector unsigned int *)p,1,1);
+ vec_dstt(( vector unsigned int *)p,1,1);
+ vec_dst((_96 *)p,1,1);
+ vec_dstst((_96 *)p,1,1);
+ vec_dststt((_96 *)p,1,1);
+ vec_dstt((_96 *)p,1,1);
+ vec_st(u32,1,( vector unsigned int *)p);
+ vec_st(u32,1,(_96 *)p);
+ vec_stl(u32,1,( vector unsigned int *)p);
+ vec_stl(u32,1,(_96 *)p);
+ u8 = vec_lvsl(1,(const volatile int signed *)p);
+ u8 = vec_lvsl(1,(_97 *)p);
+ u8 = vec_lvsr(1,(const volatile int signed *)p);
+ u8 = vec_lvsr(1,(_97 *)p);
+ u8 = vec_lvsl(1,(const int signed *)p);
+ u8 = vec_lvsl(1,(_98 *)p);
+ u8 = vec_lvsr(1,(const int signed *)p);
+ u8 = vec_lvsr(1,(_98 *)p);
+ s32 = vec_ld(1,(const int signed *)p);
+ s32 = vec_ld(1,(_98 *)p);
+ s32 = vec_lde(1,(const int signed *)p);
+ s32 = vec_lde(1,(_98 *)p);
+ s32 = vec_ldl(1,(const int signed *)p);
+ s32 = vec_ldl(1,(_98 *)p);
+ vec_dst((const int signed *)p,1,1);
+ vec_dstst((const int signed *)p,1,1);
+ vec_dststt((const int signed *)p,1,1);
+ vec_dstt((const int signed *)p,1,1);
+ vec_dst((_98 *)p,1,1);
+ vec_dstst((_98 *)p,1,1);
+ vec_dststt((_98 *)p,1,1);
+ vec_dstt((_98 *)p,1,1);
+ u8 = vec_lvsl(1,( volatile int signed *)p);
+ u8 = vec_lvsl(1,(_99 *)p);
+ u8 = vec_lvsr(1,( volatile int signed *)p);
+ u8 = vec_lvsr(1,(_99 *)p);
+ u8 = vec_lvsl(1,(int signed *)p);
+ u8 = vec_lvsl(1,(_100 *)p);
+ u8 = vec_lvsr(1,(int signed *)p);
+ u8 = vec_lvsr(1,(_100 *)p);
+ s32 = vec_ld(1,(int signed *)p);
+ s32 = vec_ld(1,(_100 *)p);
+ s32 = vec_lde(1,(int signed *)p);
+ s32 = vec_lde(1,(_100 *)p);
+ s32 = vec_ldl(1,(int signed *)p);
+ s32 = vec_ldl(1,(_100 *)p);
+ vec_dst((int signed *)p,1,1);
+ vec_dstst((int signed *)p,1,1);
+ vec_dststt((int signed *)p,1,1);
+ vec_dstt((int signed *)p,1,1);
+ vec_dst((_100 *)p,1,1);
+ vec_dstst((_100 *)p,1,1);
+ vec_dststt((_100 *)p,1,1);
+ vec_dstt((_100 *)p,1,1);
+ vec_st(s32,1,(int signed *)p);
+ vec_st(s32,1,(_100 *)p);
+ vec_ste(s32,1,(int signed *)p);
+ vec_ste(s32,1,(_100 *)p);
+ vec_stl(s32,1,(int signed *)p);
+ vec_stl(s32,1,(_100 *)p);
+ u8 = vec_lvsl(1,(const volatile short int *)p);
+ u8 = vec_lvsl(1,(_101 *)p);
+ u8 = vec_lvsr(1,(const volatile short int *)p);
+ u8 = vec_lvsr(1,(_101 *)p);
+ u8 = vec_lvsl(1,(const short int *)p);
+ u8 = vec_lvsl(1,(_102 *)p);
+ u8 = vec_lvsr(1,(const short int *)p);
+ u8 = vec_lvsr(1,(_102 *)p);
+ s16 = vec_ld(1,(const short int *)p);
+ s16 = vec_ld(1,(_102 *)p);
+ s16 = vec_lde(1,(const short int *)p);
+ s16 = vec_lde(1,(_102 *)p);
+ s16 = vec_ldl(1,(const short int *)p);
+ s16 = vec_ldl(1,(_102 *)p);
+ vec_dst((const short int *)p,1,1);
+ vec_dstst((const short int *)p,1,1);
+ vec_dststt((const short int *)p,1,1);
+ vec_dstt((const short int *)p,1,1);
+ vec_dst((_102 *)p,1,1);
+ vec_dstst((_102 *)p,1,1);
+ vec_dststt((_102 *)p,1,1);
+ vec_dstt((_102 *)p,1,1);
+ u8 = vec_lvsl(1,( volatile short int *)p);
+ u8 = vec_lvsl(1,(_103 *)p);
+ u8 = vec_lvsr(1,( volatile short int *)p);
+ u8 = vec_lvsr(1,(_103 *)p);
+ u8 = vec_lvsl(1,( short int *)p);
+ u8 = vec_lvsl(1,(_104 *)p);
+ u8 = vec_lvsr(1,( short int *)p);
+ u8 = vec_lvsr(1,(_104 *)p);
+ s16 = vec_ld(1,( short int *)p);
+ s16 = vec_ld(1,(_104 *)p);
+ s16 = vec_lde(1,( short int *)p);
+ s16 = vec_lde(1,(_104 *)p);
+ s16 = vec_ldl(1,( short int *)p);
+ s16 = vec_ldl(1,(_104 *)p);
+ vec_dst(( short int *)p,1,1);
+ vec_dstst(( short int *)p,1,1);
+ vec_dststt(( short int *)p,1,1);
+ vec_dstt(( short int *)p,1,1);
+ vec_dst((_104 *)p,1,1);
+ vec_dstst((_104 *)p,1,1);
+ vec_dststt((_104 *)p,1,1);
+ vec_dstt((_104 *)p,1,1);
+ vec_st(s16,1,( short int *)p);
+ vec_st(s16,1,(_104 *)p);
+ vec_ste(s16,1,( short int *)p);
+ vec_ste(s16,1,(_104 *)p);
+ vec_stl(s16,1,( short int *)p);
+ vec_stl(s16,1,(_104 *)p);
+ u8 = vec_lvsl(1,(const volatile int *)p);
+ u8 = vec_lvsl(1,(_105 *)p);
+ u8 = vec_lvsr(1,(const volatile int *)p);
+ u8 = vec_lvsr(1,(_105 *)p);
+ u8 = vec_lvsl(1,(const int *)p);
+ u8 = vec_lvsl(1,(_106 *)p);
+ u8 = vec_lvsr(1,(const int *)p);
+ u8 = vec_lvsr(1,(_106 *)p);
+ s32 = vec_ld(1,(const int *)p);
+ s32 = vec_ld(1,(_106 *)p);
+ s32 = vec_lde(1,(const int *)p);
+ s32 = vec_lde(1,(_106 *)p);
+ s32 = vec_ldl(1,(const int *)p);
+ s32 = vec_ldl(1,(_106 *)p);
+ vec_dst((const int *)p,1,1);
+ vec_dstst((const int *)p,1,1);
+ vec_dststt((const int *)p,1,1);
+ vec_dstt((const int *)p,1,1);
+ vec_dst((_106 *)p,1,1);
+ vec_dstst((_106 *)p,1,1);
+ vec_dststt((_106 *)p,1,1);
+ vec_dstt((_106 *)p,1,1);
+ u8 = vec_lvsl(1,( volatile int *)p);
+ u8 = vec_lvsl(1,(_107 *)p);
+ u8 = vec_lvsr(1,( volatile int *)p);
+ u8 = vec_lvsr(1,(_107 *)p);
+ u8 = vec_lvsl(1,( int *)p);
+ u8 = vec_lvsl(1,(_108 *)p);
+ u8 = vec_lvsr(1,( int *)p);
+ u8 = vec_lvsr(1,(_108 *)p);
+ s32 = vec_ld(1,( int *)p);
+ s32 = vec_ld(1,(_108 *)p);
+ s32 = vec_lde(1,( int *)p);
+ s32 = vec_lde(1,(_108 *)p);
+ s32 = vec_ldl(1,( int *)p);
+ s32 = vec_ldl(1,(_108 *)p);
+ vec_dst(( int *)p,1,1);
+ vec_dstst(( int *)p,1,1);
+ vec_dststt(( int *)p,1,1);
+ vec_dstt(( int *)p,1,1);
+ vec_dst((_108 *)p,1,1);
+ vec_dstst((_108 *)p,1,1);
+ vec_dststt((_108 *)p,1,1);
+ vec_dstt((_108 *)p,1,1);
+ vec_st(s32,1,( int *)p);
+ vec_st(s32,1,(_108 *)p);
+ vec_ste(s32,1,( int *)p);
+ vec_ste(s32,1,(_108 *)p);
+ vec_stl(s32,1,( int *)p);
+ vec_stl(s32,1,(_108 *)p);
+ u8 = vec_lvsl(1,(const volatile int *)p);
+ u8 = vec_lvsl(1,(_109 *)p);
+ u8 = vec_lvsr(1,(const volatile int *)p);
+ u8 = vec_lvsr(1,(_109 *)p);
+ u8 = vec_lvsl(1,(const int *)p);
+ u8 = vec_lvsl(1,(_110 *)p);
+ u8 = vec_lvsr(1,(const int *)p);
+ u8 = vec_lvsr(1,(_110 *)p);
+ s32 = vec_ld(1,(const int *)p);
+ s32 = vec_ld(1,(_110 *)p);
+ s32 = vec_lde(1,(const int *)p);
+ s32 = vec_lde(1,(_110 *)p);
+ s32 = vec_ldl(1,(const int *)p);
+ s32 = vec_ldl(1,(_110 *)p);
+ vec_dst((const int *)p,1,1);
+ vec_dstst((const int *)p,1,1);
+ vec_dststt((const int *)p,1,1);
+ vec_dstt((const int *)p,1,1);
+ vec_dst((_110 *)p,1,1);
+ vec_dstst((_110 *)p,1,1);
+ vec_dststt((_110 *)p,1,1);
+ vec_dstt((_110 *)p,1,1);
+ u8 = vec_lvsl(1,( volatile int *)p);
+ u8 = vec_lvsl(1,(_111 *)p);
+ u8 = vec_lvsr(1,( volatile int *)p);
+ u8 = vec_lvsr(1,(_111 *)p);
+ u8 = vec_lvsl(1,( int *)p);
+ u8 = vec_lvsl(1,(_112 *)p);
+ u8 = vec_lvsr(1,( int *)p);
+ u8 = vec_lvsr(1,(_112 *)p);
+ s32 = vec_ld(1,( int *)p);
+ s32 = vec_ld(1,(_112 *)p);
+ s32 = vec_lde(1,( int *)p);
+ s32 = vec_lde(1,(_112 *)p);
+ s32 = vec_ldl(1,( int *)p);
+ s32 = vec_ldl(1,(_112 *)p);
+ vec_dst(( int *)p,1,1);
+ vec_dstst(( int *)p,1,1);
+ vec_dststt(( int *)p,1,1);
+ vec_dstt(( int *)p,1,1);
+ vec_dst((_112 *)p,1,1);
+ vec_dstst((_112 *)p,1,1);
+ vec_dststt((_112 *)p,1,1);
+ vec_dstt((_112 *)p,1,1);
+ vec_st(s32,1,( int *)p);
+ vec_st(s32,1,(_112 *)p);
+ vec_ste(s32,1,( int *)p);
+ vec_ste(s32,1,(_112 *)p);
+ vec_stl(s32,1,( int *)p);
+ vec_stl(s32,1,(_112 *)p);
+ u8 = vec_ld(1,(const vector unsigned char *)p);
+ u8 = vec_ld(1,(_114 *)p);
+ u8 = vec_ldl(1,(const vector unsigned char *)p);
+ u8 = vec_ldl(1,(_114 *)p);
+ vec_dst((const vector unsigned char *)p,1,1);
+ vec_dstst((const vector unsigned char *)p,1,1);
+ vec_dststt((const vector unsigned char *)p,1,1);
+ vec_dstt((const vector unsigned char *)p,1,1);
+ vec_dst((_114 *)p,1,1);
+ vec_dstst((_114 *)p,1,1);
+ vec_dststt((_114 *)p,1,1);
+ vec_dstt((_114 *)p,1,1);
+ u8 = vec_ld(1,( vector unsigned char *)p);
+ u8 = vec_ld(1,(_116 *)p);
+ u8 = vec_ldl(1,( vector unsigned char *)p);
+ u8 = vec_ldl(1,(_116 *)p);
+ vec_dst(( vector unsigned char *)p,1,1);
+ vec_dstst(( vector unsigned char *)p,1,1);
+ vec_dststt(( vector unsigned char *)p,1,1);
+ vec_dstt(( vector unsigned char *)p,1,1);
+ vec_dst((_116 *)p,1,1);
+ vec_dstst((_116 *)p,1,1);
+ vec_dststt((_116 *)p,1,1);
+ vec_dstt((_116 *)p,1,1);
+ vec_st(u8,1,( vector unsigned char *)p);
+ vec_st(u8,1,(_116 *)p);
+ vec_stl(u8,1,( vector unsigned char *)p);
+ vec_stl(u8,1,(_116 *)p);
+ u8 = vec_lvsl(1,(const volatile signed char *)p);
+ u8 = vec_lvsl(1,(_117 *)p);
+ u8 = vec_lvsr(1,(const volatile signed char *)p);
+ u8 = vec_lvsr(1,(_117 *)p);
+ u8 = vec_lvsl(1,(const signed char *)p);
+ u8 = vec_lvsl(1,(_118 *)p);
+ u8 = vec_lvsr(1,(const signed char *)p);
+ u8 = vec_lvsr(1,(_118 *)p);
+ s8 = vec_ld(1,(const signed char *)p);
+ s8 = vec_ld(1,(_118 *)p);
+ s8 = vec_lde(1,(const signed char *)p);
+ s8 = vec_lde(1,(_118 *)p);
+ s8 = vec_ldl(1,(const signed char *)p);
+ s8 = vec_ldl(1,(_118 *)p);
+ vec_dst((const signed char *)p,1,1);
+ vec_dstst((const signed char *)p,1,1);
+ vec_dststt((const signed char *)p,1,1);
+ vec_dstt((const signed char *)p,1,1);
+ vec_dst((_118 *)p,1,1);
+ vec_dstst((_118 *)p,1,1);
+ vec_dststt((_118 *)p,1,1);
+ vec_dstt((_118 *)p,1,1);
+ u8 = vec_lvsl(1,( volatile signed char *)p);
+ u8 = vec_lvsl(1,(_119 *)p);
+ u8 = vec_lvsr(1,( volatile signed char *)p);
+ u8 = vec_lvsr(1,(_119 *)p);
+ u8 = vec_lvsl(1,( signed char *)p);
+ u8 = vec_lvsl(1,(_120 *)p);
+ u8 = vec_lvsr(1,( signed char *)p);
+ u8 = vec_lvsr(1,(_120 *)p);
+ s8 = vec_ld(1,( signed char *)p);
+ s8 = vec_ld(1,(_120 *)p);
+ s8 = vec_lde(1,( signed char *)p);
+ s8 = vec_lde(1,(_120 *)p);
+ s8 = vec_ldl(1,( signed char *)p);
+ s8 = vec_ldl(1,(_120 *)p);
+ vec_dst(( signed char *)p,1,1);
+ vec_dstst(( signed char *)p,1,1);
+ vec_dststt(( signed char *)p,1,1);
+ vec_dstt(( signed char *)p,1,1);
+ vec_dst((_120 *)p,1,1);
+ vec_dstst((_120 *)p,1,1);
+ vec_dststt((_120 *)p,1,1);
+ vec_dstt((_120 *)p,1,1);
+ vec_st(s8,1,( signed char *)p);
+ vec_st(s8,1,(_120 *)p);
+ vec_ste(s8,1,( signed char *)p);
+ vec_ste(s8,1,(_120 *)p);
+ vec_stl(s8,1,( signed char *)p);
+ vec_stl(s8,1,(_120 *)p);
+ u8 = vec_lvsl(1,(const volatile float *)p);
+ u8 = vec_lvsl(1,(_121 *)p);
+ u8 = vec_lvsr(1,(const volatile float *)p);
+ u8 = vec_lvsr(1,(_121 *)p);
+ u8 = vec_lvsl(1,(const float *)p);
+ u8 = vec_lvsl(1,(_122 *)p);
+ u8 = vec_lvsr(1,(const float *)p);
+ u8 = vec_lvsr(1,(_122 *)p);
+ f32 = vec_ld(1,(const float *)p);
+ f32 = vec_ld(1,(_122 *)p);
+ f32 = vec_lde(1,(const float *)p);
+ f32 = vec_lde(1,(_122 *)p);
+ f32 = vec_ldl(1,(const float *)p);
+ f32 = vec_ldl(1,(_122 *)p);
+ vec_dst((const float *)p,1,1);
+ vec_dstst((const float *)p,1,1);
+ vec_dststt((const float *)p,1,1);
+ vec_dstt((const float *)p,1,1);
+ vec_dst((_122 *)p,1,1);
+ vec_dstst((_122 *)p,1,1);
+ vec_dststt((_122 *)p,1,1);
+ vec_dstt((_122 *)p,1,1);
+ u8 = vec_lvsl(1,( volatile float *)p);
+ u8 = vec_lvsl(1,(_123 *)p);
+ u8 = vec_lvsr(1,( volatile float *)p);
+ u8 = vec_lvsr(1,(_123 *)p);
+ u8 = vec_lvsl(1,( float *)p);
+ u8 = vec_lvsl(1,(_124 *)p);
+ u8 = vec_lvsr(1,( float *)p);
+ u8 = vec_lvsr(1,(_124 *)p);
+ f32 = vec_ld(1,( float *)p);
+ f32 = vec_ld(1,(_124 *)p);
+ f32 = vec_lde(1,( float *)p);
+ f32 = vec_lde(1,(_124 *)p);
+ f32 = vec_ldl(1,( float *)p);
+ f32 = vec_ldl(1,(_124 *)p);
+ vec_dst(( float *)p,1,1);
+ vec_dstst(( float *)p,1,1);
+ vec_dststt(( float *)p,1,1);
+ vec_dstt(( float *)p,1,1);
+ vec_dst((_124 *)p,1,1);
+ vec_dstst((_124 *)p,1,1);
+ vec_dststt((_124 *)p,1,1);
+ vec_dstt((_124 *)p,1,1);
+ vec_st(f32,1,( float *)p);
+ vec_st(f32,1,(_124 *)p);
+ vec_ste(f32,1,( float *)p);
+ vec_ste(f32,1,(_124 *)p);
+ vec_stl(f32,1,( float *)p);
+ vec_stl(f32,1,(_124 *)p);
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/3c-02.c b/gcc/testsuite/gcc.dg/vmx/3c-02.c
new file mode 100644
index 00000000000..1d105dde407
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/3c-02.c
@@ -0,0 +1,17 @@
+#include "harness.h"
+
+vector unsigned char u8;
+
+static void f(void *p)
+{
+ u8 = vec_ld(1, (unsigned char *)p);
+}
+
+static void test()
+{
+ static vector unsigned int value = {1,-2,3,-4};
+ static vector unsigned int buffer[2];
+ buffer[1] = value;
+ f((void *)(-1+(char*)(buffer+1)));
+ check(vec_all_eq((vector unsigned int) u8, value), "u8");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/3c-03.c b/gcc/testsuite/gcc.dg/vmx/3c-03.c
new file mode 100644
index 00000000000..2228c035756
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/3c-03.c
@@ -0,0 +1,17 @@
+#include "harness.h"
+
+vector unsigned char u8;
+
+static void f(int i, void *p)
+{
+ u8 = vec_ld(i, (unsigned char *)p);
+}
+
+static void test()
+{
+ static vector unsigned int value = {1,-2,3,-4};
+ static vector unsigned int buffer[2];
+ buffer[1] = value;
+ f(37,(void *)(-37+(char*)(buffer+1)));
+ check(vec_all_eq((vector unsigned int) u8, value), "u8");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/3d-01.c b/gcc/testsuite/gcc.dg/vmx/3d-01.c
new file mode 100644
index 00000000000..48657c86693
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/3d-01.c
@@ -0,0 +1,171 @@
+/* { dg-do compile } */
+#include <altivec.h>
+int i;
+
+void
+test_vec_all_gt(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (vec_all_gt(u8a, u8b))
+ i = 1;
+}
+
+void
+test_vec_all_le(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (vec_all_le(u8a, u8b))
+ i = 1;
+}
+
+void
+test_vec_any_gt(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (vec_any_gt(u8a, u8b))
+ i = 1;
+}
+
+void
+test_vec_any_le(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (vec_any_le(u8a, u8b))
+ i = 1;
+}
+
+void
+test_vec_all_lt(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (vec_all_lt(u8a, u8b))
+ i = 1;
+}
+
+void
+test_vec_all_ge(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (vec_all_ge(u8a, u8b))
+ i = 1;
+}
+
+void
+test_vec_any_lt(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (vec_any_lt(u8a, u8b))
+ i = 1;
+}
+
+void
+test_vec_any_ge(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (vec_any_ge(u8a, u8b))
+ i = 1;
+}
+
+void
+test_vec_all_eq(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (vec_all_eq(u8a, u8b))
+ i = 1;
+}
+
+void
+test_vec_all_ne(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (vec_all_ne(u8a, u8b))
+ i = 1;
+}
+
+void
+test_vec_any_eq(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (vec_any_eq(u8a, u8b))
+ i = 1;
+}
+
+void
+test_vec_any_ne(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (vec_any_ne(u8a, u8b))
+ i = 1;
+}
+
+void
+test_not_vec_all_gt(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (!vec_all_gt(u8a, u8b))
+ i = 1;
+}
+
+void
+test_not_vec_all_le(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (!vec_all_le(u8a, u8b))
+ i = 1;
+}
+
+void
+test_not_vec_any_gt(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (!vec_any_gt(u8a, u8b))
+ i = 1;
+}
+
+void
+test_not_vec_any_le(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (!vec_any_le(u8a, u8b))
+ i = 1;
+}
+
+void
+test_not_vec_all_lt(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (!vec_all_lt(u8a, u8b))
+ i = 1;
+}
+
+void
+test_not_vec_all_ge(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (!vec_all_ge(u8a, u8b))
+ i = 1;
+}
+
+void
+test_not_vec_any_lt(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (!vec_any_lt(u8a, u8b))
+ i = 1;
+}
+
+void
+test_not_vec_any_ge(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (!vec_any_ge(u8a, u8b))
+ i = 1;
+}
+
+void
+test_not_vec_all_eq(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (!vec_all_eq(u8a, u8b))
+ i = 1;
+}
+
+void
+test_not_vec_all_ne(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (!vec_all_ne(u8a, u8b))
+ i = 1;
+}
+
+void
+test_not_vec_any_eq(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (!vec_any_eq(u8a, u8b))
+ i = 1;
+}
+
+void
+test_not_vec_any_ne(vector unsigned char u8a, vector unsigned char u8b)
+{
+ if (!vec_any_ne(u8a, u8b))
+ i = 1;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/4-01.c b/gcc/testsuite/gcc.dg/vmx/4-01.c
new file mode 100644
index 00000000000..f454a2edadf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/4-01.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+#include <altivec.h>
+vector unsigned int
+f(vector signed char a)
+{
+ return (vector unsigned int)(a);
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/4-03.c b/gcc/testsuite/gcc.dg/vmx/4-03.c
new file mode 100644
index 00000000000..1c3ccd74693
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/4-03.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+#include <altivec.h>
+vector unsigned int
+f(vector signed char a)
+{
+ return (vector unsigned int)a;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/5-01.c b/gcc/testsuite/gcc.dg/vmx/5-01.c
new file mode 100644
index 00000000000..c3cb6e990dc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/5-01.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+#include <altivec.h>
+vector unsigned int a = {1,1,1,1};
+vector unsigned int b = {1,2,3,4};
diff --git a/gcc/testsuite/gcc.dg/vmx/5-02.c b/gcc/testsuite/gcc.dg/vmx/5-02.c
new file mode 100644
index 00000000000..0bb4eb0084f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/5-02.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+#include <altivec.h>
+vector float a = {1,1,1,1};
+vector float b = {1,2.0,3,4U};
diff --git a/gcc/testsuite/gcc.dg/vmx/5-03.c b/gcc/testsuite/gcc.dg/vmx/5-03.c
new file mode 100644
index 00000000000..3d048e87b01
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/5-03.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+#include <altivec.h>
+vector unsigned char u8 = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+vector signed char s8 = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+vector bool char b8 = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+vector unsigned short u16 = {1,1,1,1,1,1,1,1};
+vector signed short s16 = {1,1,1,1,1,1,1,1};
+vector bool short b16 = {1,1,1,1,1,1,1,1};
+vector unsigned int u32 = {1,1,1,1};
+vector signed int s32 = {1,1,1,1};
+vector bool int b32 = {1,1,1,1};
+vector float f32 = {1,1,1,1};
+vector pixel p16 = {1,1,1,1,1,1,1,1};
+
+vector unsigned char u8_
+ = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
+vector signed char s8_
+ = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
+vector bool char b8_
+ = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
+vector unsigned short u16_ = {1,2,3,4,5,6,7,8};
+vector signed short s16_ = {1,2,3,4,5,6,7,8};
+vector bool short b16_ = {1,2,3,4,5,6,7,8};
+vector unsigned int u32_ = {1,2,3,4};
+vector signed int s32_ = {1,2,3,4};
+vector bool int b32_ = {1,2,3,4};
+vector float f32_ = {1,2,3,4};
+vector pixel p16_ = {1,2,3,4,5,6,7,8};
diff --git a/gcc/testsuite/gcc.dg/vmx/5-04.c b/gcc/testsuite/gcc.dg/vmx/5-04.c
new file mode 100644
index 00000000000..c5135e88864
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/5-04.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+#include <altivec.h>
+vector unsigned int a;
+vector unsigned int b;
+void
+f(void)
+{
+ a = ((vector unsigned int){1,1,1,1});
+ b = ((vector unsigned int){1,2,3,4});
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/5-05.c b/gcc/testsuite/gcc.dg/vmx/5-05.c
new file mode 100644
index 00000000000..c3cb6e990dc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/5-05.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+#include <altivec.h>
+vector unsigned int a = {1,1,1,1};
+vector unsigned int b = {1,2,3,4};
diff --git a/gcc/testsuite/gcc.dg/vmx/5-06.c b/gcc/testsuite/gcc.dg/vmx/5-06.c
new file mode 100644
index 00000000000..0bb4eb0084f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/5-06.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+#include <altivec.h>
+vector float a = {1,1,1,1};
+vector float b = {1,2.0,3,4U};
diff --git a/gcc/testsuite/gcc.dg/vmx/5-07.c b/gcc/testsuite/gcc.dg/vmx/5-07.c
new file mode 100644
index 00000000000..3d048e87b01
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/5-07.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+#include <altivec.h>
+vector unsigned char u8 = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+vector signed char s8 = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+vector bool char b8 = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+vector unsigned short u16 = {1,1,1,1,1,1,1,1};
+vector signed short s16 = {1,1,1,1,1,1,1,1};
+vector bool short b16 = {1,1,1,1,1,1,1,1};
+vector unsigned int u32 = {1,1,1,1};
+vector signed int s32 = {1,1,1,1};
+vector bool int b32 = {1,1,1,1};
+vector float f32 = {1,1,1,1};
+vector pixel p16 = {1,1,1,1,1,1,1,1};
+
+vector unsigned char u8_
+ = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
+vector signed char s8_
+ = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
+vector bool char b8_
+ = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
+vector unsigned short u16_ = {1,2,3,4,5,6,7,8};
+vector signed short s16_ = {1,2,3,4,5,6,7,8};
+vector bool short b16_ = {1,2,3,4,5,6,7,8};
+vector unsigned int u32_ = {1,2,3,4};
+vector signed int s32_ = {1,2,3,4};
+vector bool int b32_ = {1,2,3,4};
+vector float f32_ = {1,2,3,4};
+vector pixel p16_ = {1,2,3,4,5,6,7,8};
diff --git a/gcc/testsuite/gcc.dg/vmx/5-07t.c b/gcc/testsuite/gcc.dg/vmx/5-07t.c
new file mode 100644
index 00000000000..c03e6558f1d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/5-07t.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+#include <altivec.h>
+typedef vector unsigned char t_u8;
+typedef vector signed char t_s8;
+typedef vector bool char t_b8;
+typedef vector unsigned short t_u16;
+typedef vector signed short t_s16;
+typedef vector bool short t_b16;
+typedef vector unsigned int t_u32;
+typedef vector signed int t_s32;
+typedef vector bool int t_b32;
+typedef vector float t_f32;
+typedef vector pixel t_p16;
+
+t_u8 u8 = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+t_s8 s8 = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+t_b8 b8 = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+t_u16 u16 = {1,1,1,1,1,1,1,1};
+t_s16 s16 = {1,1,1,1,1,1,1,1};
+t_b16 b16 = {1,1,1,1,1,1,1,1};
+t_u32 u32 = {1,1,1,1};
+t_s32 s32 = {1,1,1,1};
+t_b32 b32 = {1,1,1,1};
+t_f32 f32 = {1,1,1,1};
+t_p16 p16 = {1,1,1,1,1,1,1,1};
+
+t_u8 u8_ = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
+t_s8 s8_ = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
+t_b8 b8_ = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
+t_u16 u16_ = {1,2,3,4,5,6,7,8};
+t_s16 s16_ = {1,2,3,4,5,6,7,8};
+t_b16 b16_ = {1,2,3,4,5,6,7,8};
+t_u32 u32_ = {1,2,3,4};
+t_s32 s32_ = {1,2,3,4};
+t_b32 b32_ = {1,2,3,4};
+t_f32 f32_ = {1,2,3,4};
+t_p16 p16_ = {1,2,3,4,5,6,7,8};
diff --git a/gcc/testsuite/gcc.dg/vmx/5-08.c b/gcc/testsuite/gcc.dg/vmx/5-08.c
new file mode 100644
index 00000000000..c5135e88864
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/5-08.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+#include <altivec.h>
+vector unsigned int a;
+vector unsigned int b;
+void
+f(void)
+{
+ a = ((vector unsigned int){1,1,1,1});
+ b = ((vector unsigned int){1,2,3,4});
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/5-10.c b/gcc/testsuite/gcc.dg/vmx/5-10.c
new file mode 100644
index 00000000000..5f1b6ddc1b9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/5-10.c
@@ -0,0 +1,1352 @@
+/* { dg-do compile } */
+#include <altivec.h>
+void fu32a(vector unsigned int *u32)
+{
+ *u32++ = ((vector unsigned int){0,0,0,0});
+ *u32++ = ((vector unsigned int){1,1,1,1});
+ *u32++ = ((vector unsigned int){2,2,2,2});
+ *u32++ = ((vector unsigned int){3,3,3,3});
+ *u32++ = ((vector unsigned int){4,4,4,4});
+ *u32++ = ((vector unsigned int){5,5,5,5});
+ *u32++ = ((vector unsigned int){6,6,6,6});
+ *u32++ = ((vector unsigned int){7,7,7,7});
+ *u32++ = ((vector unsigned int){8,8,8,8});
+ *u32++ = ((vector unsigned int){9,9,9,9});
+ *u32++ = ((vector unsigned int){10,10,10,10});
+ *u32++ = ((vector unsigned int){11,11,11,11});
+ *u32++ = ((vector unsigned int){12,12,12,12});
+ *u32++ = ((vector unsigned int){13,13,13,13});
+ *u32++ = ((vector unsigned int){14,14,14,14});
+ *u32++ = ((vector unsigned int){15,15,15,15});
+}
+void fu32b(vector unsigned int *u32)
+{
+ *u32++ = ((vector unsigned int){65537,65537,65537,65537});
+ *u32++ = ((vector unsigned int){131074,131074,131074,131074});
+ *u32++ = ((vector unsigned int){196611,196611,196611,196611});
+ *u32++ = ((vector unsigned int){262148,262148,262148,262148});
+ *u32++ = ((vector unsigned int){327685,327685,327685,327685});
+ *u32++ = ((vector unsigned int){393222,393222,393222,393222});
+ *u32++ = ((vector unsigned int){458759,458759,458759,458759});
+ *u32++ = ((vector unsigned int){524296,524296,524296,524296});
+ *u32++ = ((vector unsigned int){589833,589833,589833,589833});
+ *u32++ = ((vector unsigned int){655370,655370,655370,655370});
+ *u32++ = ((vector unsigned int){720907,720907,720907,720907});
+ *u32++ = ((vector unsigned int){786444,786444,786444,786444});
+ *u32++ = ((vector unsigned int){851981,851981,851981,851981});
+ *u32++ = ((vector unsigned int){917518,917518,917518,917518});
+ *u32++ = ((vector unsigned int){983055,983055,983055,983055});
+}
+void fu32c(vector unsigned int *u32)
+{
+ *u32++ = ((vector unsigned int){16843009,16843009,16843009,16843009});
+ *u32++ = ((vector unsigned int){33686018,33686018,33686018,33686018});
+ *u32++ = ((vector unsigned int){50529027,50529027,50529027,50529027});
+ *u32++ = ((vector unsigned int){67372036,67372036,67372036,67372036});
+ *u32++ = ((vector unsigned int){84215045,84215045,84215045,84215045});
+ *u32++ = ((vector unsigned int){101058054,101058054,101058054,101058054});
+ *u32++ = ((vector unsigned int){117901063,117901063,117901063,117901063});
+ *u32++ = ((vector unsigned int){134744072,134744072,134744072,134744072});
+ *u32++ = ((vector unsigned int){151587081,151587081,151587081,151587081});
+ *u32++ = ((vector unsigned int){168430090,168430090,168430090,168430090});
+ *u32++ = ((vector unsigned int){185273099,185273099,185273099,185273099});
+ *u32++ = ((vector unsigned int){202116108,202116108,202116108,202116108});
+ *u32++ = ((vector unsigned int){218959117,218959117,218959117,218959117});
+ *u32++ = ((vector unsigned int){235802126,235802126,235802126,235802126});
+ *u32++ = ((vector unsigned int){252645135,252645135,252645135,252645135});
+}
+void fu32d(vector unsigned int *u32)
+{
+ *u32++ = ((vector unsigned int){4042322160,4042322160,4042322160,4042322160});
+ *u32++ = ((vector unsigned int){4059165169,4059165169,4059165169,4059165169});
+ *u32++ = ((vector unsigned int){4076008178,4076008178,4076008178,4076008178});
+ *u32++ = ((vector unsigned int){4092851187,4092851187,4092851187,4092851187});
+ *u32++ = ((vector unsigned int){4109694196,4109694196,4109694196,4109694196});
+ *u32++ = ((vector unsigned int){4126537205,4126537205,4126537205,4126537205});
+ *u32++ = ((vector unsigned int){4143380214,4143380214,4143380214,4143380214});
+ *u32++ = ((vector unsigned int){4160223223,4160223223,4160223223,4160223223});
+ *u32++ = ((vector unsigned int){4177066232,4177066232,4177066232,4177066232});
+ *u32++ = ((vector unsigned int){4193909241,4193909241,4193909241,4193909241});
+ *u32++ = ((vector unsigned int){4210752250,4210752250,4210752250,4210752250});
+ *u32++ = ((vector unsigned int){4227595259,4227595259,4227595259,4227595259});
+ *u32++ = ((vector unsigned int){4244438268,4244438268,4244438268,4244438268});
+ *u32++ = ((vector unsigned int){4261281277,4261281277,4261281277,4261281277});
+ *u32++ = ((vector unsigned int){4278124286,4278124286,4278124286,4278124286});
+}
+void fu32e(vector unsigned int *u32)
+{
+ *u32++ = ((vector unsigned int){4293984240,4293984240,4293984240,4293984240});
+ *u32++ = ((vector unsigned int){4294049777,4294049777,4294049777,4294049777});
+ *u32++ = ((vector unsigned int){4294115314,4294115314,4294115314,4294115314});
+ *u32++ = ((vector unsigned int){4294180851,4294180851,4294180851,4294180851});
+ *u32++ = ((vector unsigned int){4294246388,4294246388,4294246388,4294246388});
+ *u32++ = ((vector unsigned int){4294311925,4294311925,4294311925,4294311925});
+ *u32++ = ((vector unsigned int){4294377462,4294377462,4294377462,4294377462});
+ *u32++ = ((vector unsigned int){4294442999,4294442999,4294442999,4294442999});
+ *u32++ = ((vector unsigned int){4294508536,4294508536,4294508536,4294508536});
+ *u32++ = ((vector unsigned int){4294574073,4294574073,4294574073,4294574073});
+ *u32++ = ((vector unsigned int){4294639610,4294639610,4294639610,4294639610});
+ *u32++ = ((vector unsigned int){4294705147,4294705147,4294705147,4294705147});
+ *u32++ = ((vector unsigned int){4294770684,4294770684,4294770684,4294770684});
+ *u32++ = ((vector unsigned int){4294836221,4294836221,4294836221,4294836221});
+ *u32++ = ((vector unsigned int){4294901758,4294901758,4294901758,4294901758});
+}
+void fu32f(vector unsigned int *u32)
+{
+ *u32++ = ((vector unsigned int){4294967280,4294967280,4294967280,4294967280});
+ *u32++ = ((vector unsigned int){4294967281,4294967281,4294967281,4294967281});
+ *u32++ = ((vector unsigned int){4294967282,4294967282,4294967282,4294967282});
+ *u32++ = ((vector unsigned int){4294967283,4294967283,4294967283,4294967283});
+ *u32++ = ((vector unsigned int){4294967284,4294967284,4294967284,4294967284});
+ *u32++ = ((vector unsigned int){4294967285,4294967285,4294967285,4294967285});
+ *u32++ = ((vector unsigned int){4294967286,4294967286,4294967286,4294967286});
+ *u32++ = ((vector unsigned int){4294967287,4294967287,4294967287,4294967287});
+ *u32++ = ((vector unsigned int){4294967288,4294967288,4294967288,4294967288});
+ *u32++ = ((vector unsigned int){4294967289,4294967289,4294967289,4294967289});
+ *u32++ = ((vector unsigned int){4294967290,4294967290,4294967290,4294967290});
+ *u32++ = ((vector unsigned int){4294967291,4294967291,4294967291,4294967291});
+ *u32++ = ((vector unsigned int){4294967292,4294967292,4294967292,4294967292});
+ *u32++ = ((vector unsigned int){4294967293,4294967293,4294967293,4294967293});
+ *u32++ = ((vector unsigned int){4294967294,4294967294,4294967294,4294967294});
+ *u32++ = ((vector unsigned int){4294967295,4294967295,4294967295,4294967295});
+}
+void fu32g(vector unsigned int *u32)
+{
+ *u32++ = ((vector unsigned int){-252645136,-252645136,-252645136,-252645136});
+ *u32++ = ((vector unsigned int){-235802127,-235802127,-235802127,-235802127});
+ *u32++ = ((vector unsigned int){-218959118,-218959118,-218959118,-218959118});
+ *u32++ = ((vector unsigned int){-202116109,-202116109,-202116109,-202116109});
+ *u32++ = ((vector unsigned int){-185273100,-185273100,-185273100,-185273100});
+ *u32++ = ((vector unsigned int){-168430091,-168430091,-168430091,-168430091});
+ *u32++ = ((vector unsigned int){-151587082,-151587082,-151587082,-151587082});
+ *u32++ = ((vector unsigned int){-134744073,-134744073,-134744073,-134744073});
+ *u32++ = ((vector unsigned int){-117901064,-117901064,-117901064,-117901064});
+ *u32++ = ((vector unsigned int){-101058055,-101058055,-101058055,-101058055});
+ *u32++ = ((vector unsigned int){-84215046,-84215046,-84215046,-84215046});
+ *u32++ = ((vector unsigned int){-67372037,-67372037,-67372037,-67372037});
+ *u32++ = ((vector unsigned int){-50529028,-50529028,-50529028,-50529028});
+ *u32++ = ((vector unsigned int){-33686019,-33686019,-33686019,-33686019});
+ *u32++ = ((vector unsigned int){-16843010,-16843010,-16843010,-16843010});
+}
+void fu32h(vector unsigned int *u32)
+{
+ *u32++ = ((vector unsigned int){-983056,-983056,-983056,-983056});
+ *u32++ = ((vector unsigned int){-917519,-917519,-917519,-917519});
+ *u32++ = ((vector unsigned int){-851982,-851982,-851982,-851982});
+ *u32++ = ((vector unsigned int){-786445,-786445,-786445,-786445});
+ *u32++ = ((vector unsigned int){-720908,-720908,-720908,-720908});
+ *u32++ = ((vector unsigned int){-655371,-655371,-655371,-655371});
+ *u32++ = ((vector unsigned int){-589834,-589834,-589834,-589834});
+ *u32++ = ((vector unsigned int){-524297,-524297,-524297,-524297});
+ *u32++ = ((vector unsigned int){-458760,-458760,-458760,-458760});
+ *u32++ = ((vector unsigned int){-393223,-393223,-393223,-393223});
+ *u32++ = ((vector unsigned int){-327686,-327686,-327686,-327686});
+ *u32++ = ((vector unsigned int){-262149,-262149,-262149,-262149});
+ *u32++ = ((vector unsigned int){-196612,-196612,-196612,-196612});
+ *u32++ = ((vector unsigned int){-131075,-131075,-131075,-131075});
+ *u32++ = ((vector unsigned int){-65538,-65538,-65538,-65538});
+}
+void fu32i(vector unsigned int *u32)
+{
+ *u32++ = ((vector unsigned int){-16,-16,-16,-16});
+ *u32++ = ((vector unsigned int){-15,-15,-15,-15});
+ *u32++ = ((vector unsigned int){-14,-14,-14,-14});
+ *u32++ = ((vector unsigned int){-13,-13,-13,-13});
+ *u32++ = ((vector unsigned int){-12,-12,-12,-12});
+ *u32++ = ((vector unsigned int){-11,-11,-11,-11});
+ *u32++ = ((vector unsigned int){-10,-10,-10,-10});
+ *u32++ = ((vector unsigned int){-9,-9,-9,-9});
+ *u32++ = ((vector unsigned int){-8,-8,-8,-8});
+ *u32++ = ((vector unsigned int){-7,-7,-7,-7});
+ *u32++ = ((vector unsigned int){-6,-6,-6,-6});
+ *u32++ = ((vector unsigned int){-5,-5,-5,-5});
+ *u32++ = ((vector unsigned int){-4,-4,-4,-4});
+ *u32++ = ((vector unsigned int){-3,-3,-3,-3});
+ *u32++ = ((vector unsigned int){-2,-2,-2,-2});
+ *u32++ = ((vector unsigned int){-1,-1,-1,-1});
+}
+void fu32j(vector unsigned int *u32)
+{
+ *u32++ = ((vector unsigned int){0xfffffff0,0xfffffff0,0xfffffff0,0xfffffff0});
+ *u32++ = ((vector unsigned int){0xfffffff1,0xfffffff1,0xfffffff1,0xfffffff1});
+ *u32++ = ((vector unsigned int){0xfffffff2,0xfffffff2,0xfffffff2,0xfffffff2});
+ *u32++ = ((vector unsigned int){0xfffffff3,0xfffffff3,0xfffffff3,0xfffffff3});
+ *u32++ = ((vector unsigned int){0xfffffff4,0xfffffff4,0xfffffff4,0xfffffff4});
+ *u32++ = ((vector unsigned int){0xfffffff5,0xfffffff5,0xfffffff5,0xfffffff5});
+ *u32++ = ((vector unsigned int){0xfffffff6,0xfffffff6,0xfffffff6,0xfffffff6});
+ *u32++ = ((vector unsigned int){0xfffffff7,0xfffffff7,0xfffffff7,0xfffffff7});
+ *u32++ = ((vector unsigned int){0xfffffff8,0xfffffff8,0xfffffff8,0xfffffff8});
+ *u32++ = ((vector unsigned int){0xfffffff9,0xfffffff9,0xfffffff9,0xfffffff9});
+ *u32++ = ((vector unsigned int){0xfffffffa,0xfffffffa,0xfffffffa,0xfffffffa});
+ *u32++ = ((vector unsigned int){0xfffffffb,0xfffffffb,0xfffffffb,0xfffffffb});
+ *u32++ = ((vector unsigned int){0xfffffffc,0xfffffffc,0xfffffffc,0xfffffffc});
+ *u32++ = ((vector unsigned int){0xfffffffd,0xfffffffd,0xfffffffd,0xfffffffd});
+ *u32++ = ((vector unsigned int){0xfffffffe,0xfffffffe,0xfffffffe,0xfffffffe});
+ *u32++ = ((vector unsigned int){0xffffffff,0xffffffff,0xffffffff,0xffffffff});
+}
+void fu32k(vector unsigned int *u32)
+{
+ *u32++ = ((vector unsigned int){0x00000000,0x00000000,0x00000000,0x00000000});
+ *u32++ = ((vector unsigned int){0x00000001,0x00000001,0x00000001,0x00000001});
+ *u32++ = ((vector unsigned int){0x00000002,0x00000002,0x00000002,0x00000002});
+ *u32++ = ((vector unsigned int){0x00000003,0x00000003,0x00000003,0x00000003});
+ *u32++ = ((vector unsigned int){0x00000004,0x00000004,0x00000004,0x00000004});
+ *u32++ = ((vector unsigned int){0x00000005,0x00000005,0x00000005,0x00000005});
+ *u32++ = ((vector unsigned int){0x00000006,0x00000006,0x00000006,0x00000006});
+ *u32++ = ((vector unsigned int){0x00000007,0x00000007,0x00000007,0x00000007});
+ *u32++ = ((vector unsigned int){0x00000008,0x00000008,0x00000008,0x00000008});
+ *u32++ = ((vector unsigned int){0x00000009,0x00000009,0x00000009,0x00000009});
+ *u32++ = ((vector unsigned int){0x0000000a,0x0000000a,0x0000000a,0x0000000a});
+ *u32++ = ((vector unsigned int){0x0000000b,0x0000000b,0x0000000b,0x0000000b});
+ *u32++ = ((vector unsigned int){0x0000000c,0x0000000c,0x0000000c,0x0000000c});
+ *u32++ = ((vector unsigned int){0x0000000d,0x0000000d,0x0000000d,0x0000000d});
+ *u32++ = ((vector unsigned int){0x0000000e,0x0000000e,0x0000000e,0x0000000e});
+ *u32++ = ((vector unsigned int){0x0000000f,0x0000000f,0x0000000f,0x0000000f});
+}
+void fu32l(vector unsigned int *u32)
+{
+ *u32++ = ((vector unsigned int){0xfff0fff0,0xfff0fff0,0xfff0fff0,0xfff0fff0});
+ *u32++ = ((vector unsigned int){0xfff1fff1,0xfff1fff1,0xfff1fff1,0xfff1fff1});
+ *u32++ = ((vector unsigned int){0xfff2fff2,0xfff2fff2,0xfff2fff2,0xfff2fff2});
+ *u32++ = ((vector unsigned int){0xfff3fff3,0xfff3fff3,0xfff3fff3,0xfff3fff3});
+ *u32++ = ((vector unsigned int){0xfff4fff4,0xfff4fff4,0xfff4fff4,0xfff4fff4});
+ *u32++ = ((vector unsigned int){0xfff5fff5,0xfff5fff5,0xfff5fff5,0xfff5fff5});
+ *u32++ = ((vector unsigned int){0xfff6fff6,0xfff6fff6,0xfff6fff6,0xfff6fff6});
+ *u32++ = ((vector unsigned int){0xfff7fff7,0xfff7fff7,0xfff7fff7,0xfff7fff7});
+ *u32++ = ((vector unsigned int){0xfff8fff8,0xfff8fff8,0xfff8fff8,0xfff8fff8});
+ *u32++ = ((vector unsigned int){0xfff9fff9,0xfff9fff9,0xfff9fff9,0xfff9fff9});
+ *u32++ = ((vector unsigned int){0xfffafffa,0xfffafffa,0xfffafffa,0xfffafffa});
+ *u32++ = ((vector unsigned int){0xfffbfffb,0xfffbfffb,0xfffbfffb,0xfffbfffb});
+ *u32++ = ((vector unsigned int){0xfffcfffc,0xfffcfffc,0xfffcfffc,0xfffcfffc});
+ *u32++ = ((vector unsigned int){0xfffdfffd,0xfffdfffd,0xfffdfffd,0xfffdfffd});
+ *u32++ = ((vector unsigned int){0xfffefffe,0xfffefffe,0xfffefffe,0xfffefffe});
+ *u32++ = ((vector unsigned int){0xffffffff,0xffffffff,0xffffffff,0xffffffff});
+}
+void fu32m(vector unsigned int *u32)
+{
+ *u32++ = ((vector unsigned int){0x00000000,0x00000000,0x00000000,0x00000000});
+ *u32++ = ((vector unsigned int){0x00010001,0x00010001,0x00010001,0x00010001});
+ *u32++ = ((vector unsigned int){0x00020002,0x00020002,0x00020002,0x00020002});
+ *u32++ = ((vector unsigned int){0x00030003,0x00030003,0x00030003,0x00030003});
+ *u32++ = ((vector unsigned int){0x00040004,0x00040004,0x00040004,0x00040004});
+ *u32++ = ((vector unsigned int){0x00050005,0x00050005,0x00050005,0x00050005});
+ *u32++ = ((vector unsigned int){0x00060006,0x00060006,0x00060006,0x00060006});
+ *u32++ = ((vector unsigned int){0x00070007,0x00070007,0x00070007,0x00070007});
+ *u32++ = ((vector unsigned int){0x00080008,0x00080008,0x00080008,0x00080008});
+ *u32++ = ((vector unsigned int){0x00090009,0x00090009,0x00090009,0x00090009});
+ *u32++ = ((vector unsigned int){0x000a000a,0x000a000a,0x000a000a,0x000a000a});
+ *u32++ = ((vector unsigned int){0x000b000b,0x000b000b,0x000b000b,0x000b000b});
+ *u32++ = ((vector unsigned int){0x000c000c,0x000c000c,0x000c000c,0x000c000c});
+ *u32++ = ((vector unsigned int){0x000d000d,0x000d000d,0x000d000d,0x000d000d});
+ *u32++ = ((vector unsigned int){0x000e000e,0x000e000e,0x000e000e,0x000e000e});
+ *u32++ = ((vector unsigned int){0x000f000f,0x000f000f,0x000f000f,0x000f000f});
+}
+void fu32n(vector unsigned int *u32)
+{
+ *u32++ = ((vector unsigned int){0xf0f0f0f0,0xf0f0f0f0,0xf0f0f0f0,0xf0f0f0f0});
+ *u32++ = ((vector unsigned int){0xf1f1f1f1,0xf1f1f1f1,0xf1f1f1f1,0xf1f1f1f1});
+ *u32++ = ((vector unsigned int){0xf2f2f2f2,0xf2f2f2f2,0xf2f2f2f2,0xf2f2f2f2});
+ *u32++ = ((vector unsigned int){0xf3f3f3f3,0xf3f3f3f3,0xf3f3f3f3,0xf3f3f3f3});
+ *u32++ = ((vector unsigned int){0xf4f4f4f4,0xf4f4f4f4,0xf4f4f4f4,0xf4f4f4f4});
+ *u32++ = ((vector unsigned int){0xf5f5f5f5,0xf5f5f5f5,0xf5f5f5f5,0xf5f5f5f5});
+ *u32++ = ((vector unsigned int){0xf6f6f6f6,0xf6f6f6f6,0xf6f6f6f6,0xf6f6f6f6});
+ *u32++ = ((vector unsigned int){0xf7f7f7f7,0xf7f7f7f7,0xf7f7f7f7,0xf7f7f7f7});
+ *u32++ = ((vector unsigned int){0xf8f8f8f8,0xf8f8f8f8,0xf8f8f8f8,0xf8f8f8f8});
+ *u32++ = ((vector unsigned int){0xf9f9f9f9,0xf9f9f9f9,0xf9f9f9f9,0xf9f9f9f9});
+ *u32++ = ((vector unsigned int){0xfafafafa,0xfafafafa,0xfafafafa,0xfafafafa});
+ *u32++ = ((vector unsigned int){0xfbfbfbfb,0xfbfbfbfb,0xfbfbfbfb,0xfbfbfbfb});
+ *u32++ = ((vector unsigned int){0xfcfcfcfc,0xfcfcfcfc,0xfcfcfcfc,0xfcfcfcfc});
+ *u32++ = ((vector unsigned int){0xfdfdfdfd,0xfdfdfdfd,0xfdfdfdfd,0xfdfdfdfd});
+ *u32++ = ((vector unsigned int){0xfefefefe,0xfefefefe,0xfefefefe,0xfefefefe});
+ *u32++ = ((vector unsigned int){0xffffffff,0xffffffff,0xffffffff,0xffffffff});
+}
+void fu32o(vector unsigned int *u32)
+{
+ *u32++ = ((vector unsigned int){0x00000000,0x00000000,0x00000000,0x00000000});
+ *u32++ = ((vector unsigned int){0x01010101,0x01010101,0x01010101,0x01010101});
+ *u32++ = ((vector unsigned int){0x02020202,0x02020202,0x02020202,0x02020202});
+ *u32++ = ((vector unsigned int){0x03030303,0x03030303,0x03030303,0x03030303});
+ *u32++ = ((vector unsigned int){0x04040404,0x04040404,0x04040404,0x04040404});
+ *u32++ = ((vector unsigned int){0x05050505,0x05050505,0x05050505,0x05050505});
+ *u32++ = ((vector unsigned int){0x06060606,0x06060606,0x06060606,0x06060606});
+ *u32++ = ((vector unsigned int){0x07070707,0x07070707,0x07070707,0x07070707});
+ *u32++ = ((vector unsigned int){0x08080808,0x08080808,0x08080808,0x08080808});
+ *u32++ = ((vector unsigned int){0x09090909,0x09090909,0x09090909,0x09090909});
+ *u32++ = ((vector unsigned int){0x0a0a0a0a,0x0a0a0a0a,0x0a0a0a0a,0x0a0a0a0a});
+ *u32++ = ((vector unsigned int){0x0b0b0b0b,0x0b0b0b0b,0x0b0b0b0b,0x0b0b0b0b});
+ *u32++ = ((vector unsigned int){0x0c0c0c0c,0x0c0c0c0c,0x0c0c0c0c,0x0c0c0c0c});
+ *u32++ = ((vector unsigned int){0x0d0d0d0d,0x0d0d0d0d,0x0d0d0d0d,0x0d0d0d0d});
+ *u32++ = ((vector unsigned int){0x0e0e0e0e,0x0e0e0e0e,0x0e0e0e0e,0x0e0e0e0e});
+ *u32++ = ((vector unsigned int){0x0f0f0f0f,0x0f0f0f0f,0x0f0f0f0f,0x0f0f0f0f});
+}
+void fu16a(vector unsigned short *u16)
+{
+ *u16++ = ((vector unsigned short){0xffff,0xfff0,0xffff,0xfff0,0xffff,0xfff0,0xffff,0xfff0});
+ *u16++ = ((vector unsigned short){0xffff,0xfff1,0xffff,0xfff1,0xffff,0xfff1,0xffff,0xfff1});
+ *u16++ = ((vector unsigned short){0xffff,0xfff2,0xffff,0xfff2,0xffff,0xfff2,0xffff,0xfff2});
+ *u16++ = ((vector unsigned short){0xffff,0xfff3,0xffff,0xfff3,0xffff,0xfff3,0xffff,0xfff3});
+ *u16++ = ((vector unsigned short){0xffff,0xfff4,0xffff,0xfff4,0xffff,0xfff4,0xffff,0xfff4});
+ *u16++ = ((vector unsigned short){0xffff,0xfff5,0xffff,0xfff5,0xffff,0xfff5,0xffff,0xfff5});
+ *u16++ = ((vector unsigned short){0xffff,0xfff6,0xffff,0xfff6,0xffff,0xfff6,0xffff,0xfff6});
+ *u16++ = ((vector unsigned short){0xffff,0xfff7,0xffff,0xfff7,0xffff,0xfff7,0xffff,0xfff7});
+ *u16++ = ((vector unsigned short){0xffff,0xfff8,0xffff,0xfff8,0xffff,0xfff8,0xffff,0xfff8});
+ *u16++ = ((vector unsigned short){0xffff,0xfff9,0xffff,0xfff9,0xffff,0xfff9,0xffff,0xfff9});
+ *u16++ = ((vector unsigned short){0xffff,0xfffa,0xffff,0xfffa,0xffff,0xfffa,0xffff,0xfffa});
+ *u16++ = ((vector unsigned short){0xffff,0xfffb,0xffff,0xfffb,0xffff,0xfffb,0xffff,0xfffb});
+ *u16++ = ((vector unsigned short){0xffff,0xfffc,0xffff,0xfffc,0xffff,0xfffc,0xffff,0xfffc});
+ *u16++ = ((vector unsigned short){0xffff,0xfffd,0xffff,0xfffd,0xffff,0xfffd,0xffff,0xfffd});
+ *u16++ = ((vector unsigned short){0xffff,0xfffe,0xffff,0xfffe,0xffff,0xfffe,0xffff,0xfffe});
+ *u16++ = ((vector unsigned short){0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff});
+}
+void fu16b(vector unsigned short *u16)
+{
+ *u16++ = ((vector unsigned short){0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000});
+ *u16++ = ((vector unsigned short){0x0000,0x0001,0x0000,0x0001,0x0000,0x0001,0x0000,0x0001});
+ *u16++ = ((vector unsigned short){0x0000,0x0002,0x0000,0x0002,0x0000,0x0002,0x0000,0x0002});
+ *u16++ = ((vector unsigned short){0x0000,0x0003,0x0000,0x0003,0x0000,0x0003,0x0000,0x0003});
+ *u16++ = ((vector unsigned short){0x0000,0x0004,0x0000,0x0004,0x0000,0x0004,0x0000,0x0004});
+ *u16++ = ((vector unsigned short){0x0000,0x0005,0x0000,0x0005,0x0000,0x0005,0x0000,0x0005});
+ *u16++ = ((vector unsigned short){0x0000,0x0006,0x0000,0x0006,0x0000,0x0006,0x0000,0x0006});
+ *u16++ = ((vector unsigned short){0x0000,0x0007,0x0000,0x0007,0x0000,0x0007,0x0000,0x0007});
+ *u16++ = ((vector unsigned short){0x0000,0x0008,0x0000,0x0008,0x0000,0x0008,0x0000,0x0008});
+ *u16++ = ((vector unsigned short){0x0000,0x0009,0x0000,0x0009,0x0000,0x0009,0x0000,0x0009});
+ *u16++ = ((vector unsigned short){0x0000,0x000a,0x0000,0x000a,0x0000,0x000a,0x0000,0x000a});
+ *u16++ = ((vector unsigned short){0x0000,0x000b,0x0000,0x000b,0x0000,0x000b,0x0000,0x000b});
+ *u16++ = ((vector unsigned short){0x0000,0x000c,0x0000,0x000c,0x0000,0x000c,0x0000,0x000c});
+ *u16++ = ((vector unsigned short){0x0000,0x000d,0x0000,0x000d,0x0000,0x000d,0x0000,0x000d});
+ *u16++ = ((vector unsigned short){0x0000,0x000e,0x0000,0x000e,0x0000,0x000e,0x0000,0x000e});
+ *u16++ = ((vector unsigned short){0x0000,0x000f,0x0000,0x000f,0x0000,0x000f,0x0000,0x000f});
+}
+void fu16c(vector unsigned short *u16)
+{
+ *u16++ = ((vector unsigned short){0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0});
+ *u16++ = ((vector unsigned short){0xfff1,0xfff1,0xfff1,0xfff1,0xfff1,0xfff1,0xfff1,0xfff1});
+ *u16++ = ((vector unsigned short){0xfff2,0xfff2,0xfff2,0xfff2,0xfff2,0xfff2,0xfff2,0xfff2});
+ *u16++ = ((vector unsigned short){0xfff3,0xfff3,0xfff3,0xfff3,0xfff3,0xfff3,0xfff3,0xfff3});
+ *u16++ = ((vector unsigned short){0xfff4,0xfff4,0xfff4,0xfff4,0xfff4,0xfff4,0xfff4,0xfff4});
+ *u16++ = ((vector unsigned short){0xfff5,0xfff5,0xfff5,0xfff5,0xfff5,0xfff5,0xfff5,0xfff5});
+ *u16++ = ((vector unsigned short){0xfff6,0xfff6,0xfff6,0xfff6,0xfff6,0xfff6,0xfff6,0xfff6});
+ *u16++ = ((vector unsigned short){0xfff7,0xfff7,0xfff7,0xfff7,0xfff7,0xfff7,0xfff7,0xfff7});
+ *u16++ = ((vector unsigned short){0xfff8,0xfff8,0xfff8,0xfff8,0xfff8,0xfff8,0xfff8,0xfff8});
+ *u16++ = ((vector unsigned short){0xfff9,0xfff9,0xfff9,0xfff9,0xfff9,0xfff9,0xfff9,0xfff9});
+ *u16++ = ((vector unsigned short){0xfffa,0xfffa,0xfffa,0xfffa,0xfffa,0xfffa,0xfffa,0xfffa});
+ *u16++ = ((vector unsigned short){0xfffb,0xfffb,0xfffb,0xfffb,0xfffb,0xfffb,0xfffb,0xfffb});
+ *u16++ = ((vector unsigned short){0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc});
+ *u16++ = ((vector unsigned short){0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd});
+ *u16++ = ((vector unsigned short){0xfffe,0xfffe,0xfffe,0xfffe,0xfffe,0xfffe,0xfffe,0xfffe});
+ *u16++ = ((vector unsigned short){0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff});
+}
+void fu16d(vector unsigned short *u16)
+{
+ *u16++ = ((vector unsigned short){0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000});
+ *u16++ = ((vector unsigned short){0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001});
+ *u16++ = ((vector unsigned short){0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002});
+ *u16++ = ((vector unsigned short){0x0003,0x0003,0x0003,0x0003,0x0003,0x0003,0x0003,0x0003});
+ *u16++ = ((vector unsigned short){0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004});
+ *u16++ = ((vector unsigned short){0x0005,0x0005,0x0005,0x0005,0x0005,0x0005,0x0005,0x0005});
+ *u16++ = ((vector unsigned short){0x0006,0x0006,0x0006,0x0006,0x0006,0x0006,0x0006,0x0006});
+ *u16++ = ((vector unsigned short){0x0007,0x0007,0x0007,0x0007,0x0007,0x0007,0x0007,0x0007});
+ *u16++ = ((vector unsigned short){0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008});
+ *u16++ = ((vector unsigned short){0x0009,0x0009,0x0009,0x0009,0x0009,0x0009,0x0009,0x0009});
+ *u16++ = ((vector unsigned short){0x000a,0x000a,0x000a,0x000a,0x000a,0x000a,0x000a,0x000a});
+ *u16++ = ((vector unsigned short){0x000b,0x000b,0x000b,0x000b,0x000b,0x000b,0x000b,0x000b});
+ *u16++ = ((vector unsigned short){0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c});
+ *u16++ = ((vector unsigned short){0x000d,0x000d,0x000d,0x000d,0x000d,0x000d,0x000d,0x000d});
+ *u16++ = ((vector unsigned short){0x000e,0x000e,0x000e,0x000e,0x000e,0x000e,0x000e,0x000e});
+ *u16++ = ((vector unsigned short){0x000f,0x000f,0x000f,0x000f,0x000f,0x000f,0x000f,0x000f});
+}
+void fu16e(vector unsigned short *u16)
+{
+ *u16++ = ((vector unsigned short){0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0});
+ *u16++ = ((vector unsigned short){0xf1f1,0xf1f1,0xf1f1,0xf1f1,0xf1f1,0xf1f1,0xf1f1,0xf1f1});
+ *u16++ = ((vector unsigned short){0xf2f2,0xf2f2,0xf2f2,0xf2f2,0xf2f2,0xf2f2,0xf2f2,0xf2f2});
+ *u16++ = ((vector unsigned short){0xf3f3,0xf3f3,0xf3f3,0xf3f3,0xf3f3,0xf3f3,0xf3f3,0xf3f3});
+ *u16++ = ((vector unsigned short){0xf4f4,0xf4f4,0xf4f4,0xf4f4,0xf4f4,0xf4f4,0xf4f4,0xf4f4});
+ *u16++ = ((vector unsigned short){0xf5f5,0xf5f5,0xf5f5,0xf5f5,0xf5f5,0xf5f5,0xf5f5,0xf5f5});
+ *u16++ = ((vector unsigned short){0xf6f6,0xf6f6,0xf6f6,0xf6f6,0xf6f6,0xf6f6,0xf6f6,0xf6f6});
+ *u16++ = ((vector unsigned short){0xf7f7,0xf7f7,0xf7f7,0xf7f7,0xf7f7,0xf7f7,0xf7f7,0xf7f7});
+ *u16++ = ((vector unsigned short){0xf8f8,0xf8f8,0xf8f8,0xf8f8,0xf8f8,0xf8f8,0xf8f8,0xf8f8});
+ *u16++ = ((vector unsigned short){0xf9f9,0xf9f9,0xf9f9,0xf9f9,0xf9f9,0xf9f9,0xf9f9,0xf9f9});
+ *u16++ = ((vector unsigned short){0xfafa,0xfafa,0xfafa,0xfafa,0xfafa,0xfafa,0xfafa,0xfafa});
+ *u16++ = ((vector unsigned short){0xfbfb,0xfbfb,0xfbfb,0xfbfb,0xfbfb,0xfbfb,0xfbfb,0xfbfb});
+ *u16++ = ((vector unsigned short){0xfcfc,0xfcfc,0xfcfc,0xfcfc,0xfcfc,0xfcfc,0xfcfc,0xfcfc});
+ *u16++ = ((vector unsigned short){0xfdfd,0xfdfd,0xfdfd,0xfdfd,0xfdfd,0xfdfd,0xfdfd,0xfdfd});
+ *u16++ = ((vector unsigned short){0xfefe,0xfefe,0xfefe,0xfefe,0xfefe,0xfefe,0xfefe,0xfefe});
+ *u16++ = ((vector unsigned short){0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff});
+}
+void fu16f(vector unsigned short *u16)
+{
+ *u16++ = ((vector unsigned short){0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000});
+ *u16++ = ((vector unsigned short){0x0101,0x0101,0x0101,0x0101,0x0101,0x0101,0x0101,0x0101});
+ *u16++ = ((vector unsigned short){0x0202,0x0202,0x0202,0x0202,0x0202,0x0202,0x0202,0x0202});
+ *u16++ = ((vector unsigned short){0x0303,0x0303,0x0303,0x0303,0x0303,0x0303,0x0303,0x0303});
+ *u16++ = ((vector unsigned short){0x0404,0x0404,0x0404,0x0404,0x0404,0x0404,0x0404,0x0404});
+ *u16++ = ((vector unsigned short){0x0505,0x0505,0x0505,0x0505,0x0505,0x0505,0x0505,0x0505});
+ *u16++ = ((vector unsigned short){0x0606,0x0606,0x0606,0x0606,0x0606,0x0606,0x0606,0x0606});
+ *u16++ = ((vector unsigned short){0x0707,0x0707,0x0707,0x0707,0x0707,0x0707,0x0707,0x0707});
+ *u16++ = ((vector unsigned short){0x0808,0x0808,0x0808,0x0808,0x0808,0x0808,0x0808,0x0808});
+ *u16++ = ((vector unsigned short){0x0909,0x0909,0x0909,0x0909,0x0909,0x0909,0x0909,0x0909});
+ *u16++ = ((vector unsigned short){0x0a0a,0x0a0a,0x0a0a,0x0a0a,0x0a0a,0x0a0a,0x0a0a,0x0a0a});
+ *u16++ = ((vector unsigned short){0x0b0b,0x0b0b,0x0b0b,0x0b0b,0x0b0b,0x0b0b,0x0b0b,0x0b0b});
+ *u16++ = ((vector unsigned short){0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x0c0c});
+ *u16++ = ((vector unsigned short){0x0d0d,0x0d0d,0x0d0d,0x0d0d,0x0d0d,0x0d0d,0x0d0d,0x0d0d});
+ *u16++ = ((vector unsigned short){0x0e0e,0x0e0e,0x0e0e,0x0e0e,0x0e0e,0x0e0e,0x0e0e,0x0e0e});
+ *u16++ = ((vector unsigned short){0x0f0f,0x0f0f,0x0f0f,0x0f0f,0x0f0f,0x0f0f,0x0f0f,0x0f0f});
+}
+void fu16g(vector unsigned short *u16)
+{
+ *u16++ = ((vector unsigned short){0,0,0,0,0,0,0,0});
+ *u16++ = ((vector unsigned short){1,1,1,1,1,1,1,1});
+ *u16++ = ((vector unsigned short){2,2,2,2,2,2,2,2});
+ *u16++ = ((vector unsigned short){3,3,3,3,3,3,3,3});
+ *u16++ = ((vector unsigned short){4,4,4,4,4,4,4,4});
+ *u16++ = ((vector unsigned short){5,5,5,5,5,5,5,5});
+ *u16++ = ((vector unsigned short){6,6,6,6,6,6,6,6});
+ *u16++ = ((vector unsigned short){7,7,7,7,7,7,7,7});
+ *u16++ = ((vector unsigned short){8,8,8,8,8,8,8,8});
+ *u16++ = ((vector unsigned short){9,9,9,9,9,9,9,9});
+ *u16++ = ((vector unsigned short){10,10,10,10,10,10,10,10});
+ *u16++ = ((vector unsigned short){11,11,11,11,11,11,11,11});
+ *u16++ = ((vector unsigned short){12,12,12,12,12,12,12,12});
+ *u16++ = ((vector unsigned short){13,13,13,13,13,13,13,13});
+ *u16++ = ((vector unsigned short){14,14,14,14,14,14,14,14});
+ *u16++ = ((vector unsigned short){15,15,15,15,15,15,15,15});
+}
+void fu16h(vector unsigned short *u16)
+{
+ *u16++ = ((vector unsigned short){257,257,257,257,257,257,257,257});
+ *u16++ = ((vector unsigned short){514,514,514,514,514,514,514,514});
+ *u16++ = ((vector unsigned short){771,771,771,771,771,771,771,771});
+ *u16++ = ((vector unsigned short){1028,1028,1028,1028,1028,1028,1028,1028});
+ *u16++ = ((vector unsigned short){1285,1285,1285,1285,1285,1285,1285,1285});
+ *u16++ = ((vector unsigned short){1542,1542,1542,1542,1542,1542,1542,1542});
+ *u16++ = ((vector unsigned short){1799,1799,1799,1799,1799,1799,1799,1799});
+ *u16++ = ((vector unsigned short){2056,2056,2056,2056,2056,2056,2056,2056});
+ *u16++ = ((vector unsigned short){2313,2313,2313,2313,2313,2313,2313,2313});
+ *u16++ = ((vector unsigned short){2570,2570,2570,2570,2570,2570,2570,2570});
+ *u16++ = ((vector unsigned short){2827,2827,2827,2827,2827,2827,2827,2827});
+ *u16++ = ((vector unsigned short){3084,3084,3084,3084,3084,3084,3084,3084});
+ *u16++ = ((vector unsigned short){3341,3341,3341,3341,3341,3341,3341,3341});
+ *u16++ = ((vector unsigned short){3598,3598,3598,3598,3598,3598,3598,3598});
+ *u16++ = ((vector unsigned short){3855,3855,3855,3855,3855,3855,3855,3855});
+}
+void fu16i(vector unsigned short *u16)
+{
+ *u16++ = ((vector unsigned short){61680,61680,61680,61680,61680,61680,61680,61680});
+ *u16++ = ((vector unsigned short){61937,61937,61937,61937,61937,61937,61937,61937});
+ *u16++ = ((vector unsigned short){62194,62194,62194,62194,62194,62194,62194,62194});
+ *u16++ = ((vector unsigned short){62451,62451,62451,62451,62451,62451,62451,62451});
+ *u16++ = ((vector unsigned short){62708,62708,62708,62708,62708,62708,62708,62708});
+ *u16++ = ((vector unsigned short){62965,62965,62965,62965,62965,62965,62965,62965});
+ *u16++ = ((vector unsigned short){63222,63222,63222,63222,63222,63222,63222,63222});
+ *u16++ = ((vector unsigned short){63479,63479,63479,63479,63479,63479,63479,63479});
+ *u16++ = ((vector unsigned short){63736,63736,63736,63736,63736,63736,63736,63736});
+ *u16++ = ((vector unsigned short){63993,63993,63993,63993,63993,63993,63993,63993});
+ *u16++ = ((vector unsigned short){64250,64250,64250,64250,64250,64250,64250,64250});
+ *u16++ = ((vector unsigned short){64507,64507,64507,64507,64507,64507,64507,64507});
+ *u16++ = ((vector unsigned short){64764,64764,64764,64764,64764,64764,64764,64764});
+ *u16++ = ((vector unsigned short){65021,65021,65021,65021,65021,65021,65021,65021});
+ *u16++ = ((vector unsigned short){65278,65278,65278,65278,65278,65278,65278,65278});
+}
+void fu16j(vector unsigned short *u16)
+{
+ *u16++ = ((vector unsigned short){65520,65520,65520,65520,65520,65520,65520,65520});
+ *u16++ = ((vector unsigned short){65521,65521,65521,65521,65521,65521,65521,65521});
+ *u16++ = ((vector unsigned short){65522,65522,65522,65522,65522,65522,65522,65522});
+ *u16++ = ((vector unsigned short){65523,65523,65523,65523,65523,65523,65523,65523});
+ *u16++ = ((vector unsigned short){65524,65524,65524,65524,65524,65524,65524,65524});
+ *u16++ = ((vector unsigned short){65525,65525,65525,65525,65525,65525,65525,65525});
+ *u16++ = ((vector unsigned short){65526,65526,65526,65526,65526,65526,65526,65526});
+ *u16++ = ((vector unsigned short){65527,65527,65527,65527,65527,65527,65527,65527});
+ *u16++ = ((vector unsigned short){65528,65528,65528,65528,65528,65528,65528,65528});
+ *u16++ = ((vector unsigned short){65529,65529,65529,65529,65529,65529,65529,65529});
+ *u16++ = ((vector unsigned short){65530,65530,65530,65530,65530,65530,65530,65530});
+ *u16++ = ((vector unsigned short){65531,65531,65531,65531,65531,65531,65531,65531});
+ *u16++ = ((vector unsigned short){65532,65532,65532,65532,65532,65532,65532,65532});
+ *u16++ = ((vector unsigned short){65533,65533,65533,65533,65533,65533,65533,65533});
+ *u16++ = ((vector unsigned short){65534,65534,65534,65534,65534,65534,65534,65534});
+ *u16++ = ((vector unsigned short){65535,65535,65535,65535,65535,65535,65535,65535});
+}
+void fu16k(vector unsigned short *u16)
+{
+ *u16++ = ((vector unsigned short){-3856,-3856,-3856,-3856,-3856,-3856,-3856,-3856});
+ *u16++ = ((vector unsigned short){-3599,-3599,-3599,-3599,-3599,-3599,-3599,-3599});
+ *u16++ = ((vector unsigned short){-3342,-3342,-3342,-3342,-3342,-3342,-3342,-3342});
+ *u16++ = ((vector unsigned short){-3085,-3085,-3085,-3085,-3085,-3085,-3085,-3085});
+ *u16++ = ((vector unsigned short){-2828,-2828,-2828,-2828,-2828,-2828,-2828,-2828});
+ *u16++ = ((vector unsigned short){-2571,-2571,-2571,-2571,-2571,-2571,-2571,-2571});
+ *u16++ = ((vector unsigned short){-2314,-2314,-2314,-2314,-2314,-2314,-2314,-2314});
+ *u16++ = ((vector unsigned short){-2057,-2057,-2057,-2057,-2057,-2057,-2057,-2057});
+ *u16++ = ((vector unsigned short){-1800,-1800,-1800,-1800,-1800,-1800,-1800,-1800});
+ *u16++ = ((vector unsigned short){-1543,-1543,-1543,-1543,-1543,-1543,-1543,-1543});
+ *u16++ = ((vector unsigned short){-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286});
+ *u16++ = ((vector unsigned short){-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029});
+ *u16++ = ((vector unsigned short){-772,-772,-772,-772,-772,-772,-772,-772});
+ *u16++ = ((vector unsigned short){-515,-515,-515,-515,-515,-515,-515,-515});
+ *u16++ = ((vector unsigned short){-258,-258,-258,-258,-258,-258,-258,-258});
+}
+void fu16l(vector unsigned short *u16)
+{
+ *u16++ = ((vector unsigned short){-16,-16,-16,-16,-16,-16,-16,-16});
+ *u16++ = ((vector unsigned short){-15,-15,-15,-15,-15,-15,-15,-15});
+ *u16++ = ((vector unsigned short){-14,-14,-14,-14,-14,-14,-14,-14});
+ *u16++ = ((vector unsigned short){-13,-13,-13,-13,-13,-13,-13,-13});
+ *u16++ = ((vector unsigned short){-12,-12,-12,-12,-12,-12,-12,-12});
+ *u16++ = ((vector unsigned short){-11,-11,-11,-11,-11,-11,-11,-11});
+ *u16++ = ((vector unsigned short){-10,-10,-10,-10,-10,-10,-10,-10});
+ *u16++ = ((vector unsigned short){-9,-9,-9,-9,-9,-9,-9,-9});
+ *u16++ = ((vector unsigned short){-8,-8,-8,-8,-8,-8,-8,-8});
+ *u16++ = ((vector unsigned short){-7,-7,-7,-7,-7,-7,-7,-7});
+ *u16++ = ((vector unsigned short){-6,-6,-6,-6,-6,-6,-6,-6});
+ *u16++ = ((vector unsigned short){-5,-5,-5,-5,-5,-5,-5,-5});
+ *u16++ = ((vector unsigned short){-4,-4,-4,-4,-4,-4,-4,-4});
+ *u16++ = ((vector unsigned short){-3,-3,-3,-3,-3,-3,-3,-3});
+ *u16++ = ((vector unsigned short){-2,-2,-2,-2,-2,-2,-2,-2});
+ *u16++ = ((vector unsigned short){-1,-1,-1,-1,-1,-1,-1,-1});
+}
+void fu8a(vector unsigned char *u8)
+{
+ *u8++ = ((vector unsigned char){0xff,0xff,0xff,0xf0,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,0xf0});
+ *u8++ = ((vector unsigned char){0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xf1});
+ *u8++ = ((vector unsigned char){0xff,0xff,0xff,0xf2,0xff,0xff,0xff,0xf2,0xff,0xff,0xff,0xf2,0xff,0xff,0xff,0xf2});
+ *u8++ = ((vector unsigned char){0xff,0xff,0xff,0xf3,0xff,0xff,0xff,0xf3,0xff,0xff,0xff,0xf3,0xff,0xff,0xff,0xf3});
+ *u8++ = ((vector unsigned char){0xff,0xff,0xff,0xf4,0xff,0xff,0xff,0xf4,0xff,0xff,0xff,0xf4,0xff,0xff,0xff,0xf4});
+ *u8++ = ((vector unsigned char){0xff,0xff,0xff,0xf5,0xff,0xff,0xff,0xf5,0xff,0xff,0xff,0xf5,0xff,0xff,0xff,0xf5});
+ *u8++ = ((vector unsigned char){0xff,0xff,0xff,0xf6,0xff,0xff,0xff,0xf6,0xff,0xff,0xff,0xf6,0xff,0xff,0xff,0xf6});
+ *u8++ = ((vector unsigned char){0xff,0xff,0xff,0xf7,0xff,0xff,0xff,0xf7,0xff,0xff,0xff,0xf7,0xff,0xff,0xff,0xf7});
+ *u8++ = ((vector unsigned char){0xff,0xff,0xff,0xf8,0xff,0xff,0xff,0xf8,0xff,0xff,0xff,0xf8,0xff,0xff,0xff,0xf8});
+ *u8++ = ((vector unsigned char){0xff,0xff,0xff,0xf9,0xff,0xff,0xff,0xf9,0xff,0xff,0xff,0xf9,0xff,0xff,0xff,0xf9});
+ *u8++ = ((vector unsigned char){0xff,0xff,0xff,0xfa,0xff,0xff,0xff,0xfa,0xff,0xff,0xff,0xfa,0xff,0xff,0xff,0xfa});
+ *u8++ = ((vector unsigned char){0xff,0xff,0xff,0xfb,0xff,0xff,0xff,0xfb,0xff,0xff,0xff,0xfb,0xff,0xff,0xff,0xfb});
+ *u8++ = ((vector unsigned char){0xff,0xff,0xff,0xfc,0xff,0xff,0xff,0xfc,0xff,0xff,0xff,0xfc,0xff,0xff,0xff,0xfc});
+ *u8++ = ((vector unsigned char){0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xfd});
+ *u8++ = ((vector unsigned char){0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfe});
+ *u8++ = ((vector unsigned char){0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff});
+}
+void fu8b(vector unsigned char *u8)
+{
+ *u8++ = ((vector unsigned char){0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00});
+ *u8++ = ((vector unsigned char){0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01});
+ *u8++ = ((vector unsigned char){0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02});
+ *u8++ = ((vector unsigned char){0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x03});
+ *u8++ = ((vector unsigned char){0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04});
+ *u8++ = ((vector unsigned char){0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x05});
+ *u8++ = ((vector unsigned char){0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06});
+ *u8++ = ((vector unsigned char){0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x07});
+ *u8++ = ((vector unsigned char){0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08});
+ *u8++ = ((vector unsigned char){0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x09});
+ *u8++ = ((vector unsigned char){0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x0a});
+ *u8++ = ((vector unsigned char){0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x0b});
+ *u8++ = ((vector unsigned char){0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x0c});
+ *u8++ = ((vector unsigned char){0x00,0x00,0x00,0x0d,0x00,0x00,0x00,0x0d,0x00,0x00,0x00,0x0d,0x00,0x00,0x00,0x0d});
+ *u8++ = ((vector unsigned char){0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x0e});
+ *u8++ = ((vector unsigned char){0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x0f});
+}
+void fu8c(vector unsigned char *u8)
+{
+ *u8++ = ((vector unsigned char){0xff,0xf0,0xff,0xf0,0xff,0xf0,0xff,0xf0,0xff,0xf0,0xff,0xf0,0xff,0xf0,0xff,0xf0});
+ *u8++ = ((vector unsigned char){0xff,0xf1,0xff,0xf1,0xff,0xf1,0xff,0xf1,0xff,0xf1,0xff,0xf1,0xff,0xf1,0xff,0xf1});
+ *u8++ = ((vector unsigned char){0xff,0xf2,0xff,0xf2,0xff,0xf2,0xff,0xf2,0xff,0xf2,0xff,0xf2,0xff,0xf2,0xff,0xf2});
+ *u8++ = ((vector unsigned char){0xff,0xf3,0xff,0xf3,0xff,0xf3,0xff,0xf3,0xff,0xf3,0xff,0xf3,0xff,0xf3,0xff,0xf3});
+ *u8++ = ((vector unsigned char){0xff,0xf4,0xff,0xf4,0xff,0xf4,0xff,0xf4,0xff,0xf4,0xff,0xf4,0xff,0xf4,0xff,0xf4});
+ *u8++ = ((vector unsigned char){0xff,0xf5,0xff,0xf5,0xff,0xf5,0xff,0xf5,0xff,0xf5,0xff,0xf5,0xff,0xf5,0xff,0xf5});
+ *u8++ = ((vector unsigned char){0xff,0xf6,0xff,0xf6,0xff,0xf6,0xff,0xf6,0xff,0xf6,0xff,0xf6,0xff,0xf6,0xff,0xf6});
+ *u8++ = ((vector unsigned char){0xff,0xf7,0xff,0xf7,0xff,0xf7,0xff,0xf7,0xff,0xf7,0xff,0xf7,0xff,0xf7,0xff,0xf7});
+ *u8++ = ((vector unsigned char){0xff,0xf8,0xff,0xf8,0xff,0xf8,0xff,0xf8,0xff,0xf8,0xff,0xf8,0xff,0xf8,0xff,0xf8});
+ *u8++ = ((vector unsigned char){0xff,0xf9,0xff,0xf9,0xff,0xf9,0xff,0xf9,0xff,0xf9,0xff,0xf9,0xff,0xf9,0xff,0xf9});
+ *u8++ = ((vector unsigned char){0xff,0xfa,0xff,0xfa,0xff,0xfa,0xff,0xfa,0xff,0xfa,0xff,0xfa,0xff,0xfa,0xff,0xfa});
+ *u8++ = ((vector unsigned char){0xff,0xfb,0xff,0xfb,0xff,0xfb,0xff,0xfb,0xff,0xfb,0xff,0xfb,0xff,0xfb,0xff,0xfb});
+ *u8++ = ((vector unsigned char){0xff,0xfc,0xff,0xfc,0xff,0xfc,0xff,0xfc,0xff,0xfc,0xff,0xfc,0xff,0xfc,0xff,0xfc});
+ *u8++ = ((vector unsigned char){0xff,0xfd,0xff,0xfd,0xff,0xfd,0xff,0xfd,0xff,0xfd,0xff,0xfd,0xff,0xfd,0xff,0xfd});
+ *u8++ = ((vector unsigned char){0xff,0xfe,0xff,0xfe,0xff,0xfe,0xff,0xfe,0xff,0xfe,0xff,0xfe,0xff,0xfe,0xff,0xfe});
+ *u8++ = ((vector unsigned char){0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff});
+}
+void fu8d(vector unsigned char *u8)
+{
+ *u8++ = ((vector unsigned char){0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00});
+ *u8++ = ((vector unsigned char){0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01});
+ *u8++ = ((vector unsigned char){0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02});
+ *u8++ = ((vector unsigned char){0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03});
+ *u8++ = ((vector unsigned char){0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04});
+ *u8++ = ((vector unsigned char){0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05});
+ *u8++ = ((vector unsigned char){0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06});
+ *u8++ = ((vector unsigned char){0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07});
+ *u8++ = ((vector unsigned char){0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08});
+ *u8++ = ((vector unsigned char){0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09});
+ *u8++ = ((vector unsigned char){0x00,0x0a,0x00,0x0a,0x00,0x0a,0x00,0x0a,0x00,0x0a,0x00,0x0a,0x00,0x0a,0x00,0x0a});
+ *u8++ = ((vector unsigned char){0x00,0x0b,0x00,0x0b,0x00,0x0b,0x00,0x0b,0x00,0x0b,0x00,0x0b,0x00,0x0b,0x00,0x0b});
+ *u8++ = ((vector unsigned char){0x00,0x0c,0x00,0x0c,0x00,0x0c,0x00,0x0c,0x00,0x0c,0x00,0x0c,0x00,0x0c,0x00,0x0c});
+ *u8++ = ((vector unsigned char){0x00,0x0d,0x00,0x0d,0x00,0x0d,0x00,0x0d,0x00,0x0d,0x00,0x0d,0x00,0x0d,0x00,0x0d});
+ *u8++ = ((vector unsigned char){0x00,0x0e,0x00,0x0e,0x00,0x0e,0x00,0x0e,0x00,0x0e,0x00,0x0e,0x00,0x0e,0x00,0x0e});
+ *u8++ = ((vector unsigned char){0x00,0x0f,0x00,0x0f,0x00,0x0f,0x00,0x0f,0x00,0x0f,0x00,0x0f,0x00,0x0f,0x00,0x0f});
+}
+void fu8e(vector unsigned char *u8)
+{
+ *u8++ = ((vector unsigned char){0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00});
+ *u8++ = ((vector unsigned char){0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01});
+ *u8++ = ((vector unsigned char){0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02});
+ *u8++ = ((vector unsigned char){0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03});
+ *u8++ = ((vector unsigned char){0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04});
+ *u8++ = ((vector unsigned char){0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05});
+ *u8++ = ((vector unsigned char){0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06});
+ *u8++ = ((vector unsigned char){0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07});
+ *u8++ = ((vector unsigned char){0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08});
+ *u8++ = ((vector unsigned char){0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09});
+ *u8++ = ((vector unsigned char){0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a});
+ *u8++ = ((vector unsigned char){0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b});
+ *u8++ = ((vector unsigned char){0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c});
+ *u8++ = ((vector unsigned char){0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d});
+ *u8++ = ((vector unsigned char){0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e});
+ *u8++ = ((vector unsigned char){0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f});
+}
+void fu8f(vector unsigned char *u8)
+{
+ *u8++ = ((vector unsigned char){0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0});
+ *u8++ = ((vector unsigned char){0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1});
+ *u8++ = ((vector unsigned char){0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2});
+ *u8++ = ((vector unsigned char){0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3});
+ *u8++ = ((vector unsigned char){0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4});
+ *u8++ = ((vector unsigned char){0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5});
+ *u8++ = ((vector unsigned char){0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6});
+ *u8++ = ((vector unsigned char){0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7});
+ *u8++ = ((vector unsigned char){0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8});
+ *u8++ = ((vector unsigned char){0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9});
+ *u8++ = ((vector unsigned char){0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa});
+ *u8++ = ((vector unsigned char){0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb});
+ *u8++ = ((vector unsigned char){0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc});
+ *u8++ = ((vector unsigned char){0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd});
+ *u8++ = ((vector unsigned char){0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe});
+ *u8++ = ((vector unsigned char){0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff});
+}
+void fu8g(vector unsigned char *u8)
+{
+ *u8++ = ((vector unsigned char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0});
+ *u8++ = ((vector unsigned char){1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1});
+ *u8++ = ((vector unsigned char){2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2});
+ *u8++ = ((vector unsigned char){3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3});
+ *u8++ = ((vector unsigned char){4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4});
+ *u8++ = ((vector unsigned char){5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5});
+ *u8++ = ((vector unsigned char){6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6});
+ *u8++ = ((vector unsigned char){7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7});
+ *u8++ = ((vector unsigned char){8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8});
+ *u8++ = ((vector unsigned char){9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9});
+ *u8++ = ((vector unsigned char){10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10});
+ *u8++ = ((vector unsigned char){11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11});
+ *u8++ = ((vector unsigned char){12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12});
+ *u8++ = ((vector unsigned char){13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13});
+ *u8++ = ((vector unsigned char){14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14});
+ *u8++ = ((vector unsigned char){15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15});
+}
+void fu8h(vector unsigned char *u8)
+{
+ *u8++ = ((vector unsigned char){240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240});
+ *u8++ = ((vector unsigned char){241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241});
+ *u8++ = ((vector unsigned char){242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242});
+ *u8++ = ((vector unsigned char){243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243});
+ *u8++ = ((vector unsigned char){244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244});
+ *u8++ = ((vector unsigned char){245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245});
+ *u8++ = ((vector unsigned char){246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246});
+ *u8++ = ((vector unsigned char){247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247});
+ *u8++ = ((vector unsigned char){248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248});
+ *u8++ = ((vector unsigned char){249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249});
+ *u8++ = ((vector unsigned char){250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250});
+ *u8++ = ((vector unsigned char){251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251});
+ *u8++ = ((vector unsigned char){252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252});
+ *u8++ = ((vector unsigned char){253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253});
+ *u8++ = ((vector unsigned char){254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254});
+ *u8++ = ((vector unsigned char){255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255});
+}
+void fu8i(vector unsigned char *u8)
+{
+ *u8++ = ((vector unsigned char){-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1});
+ *u8++ = ((vector unsigned char){-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2});
+ *u8++ = ((vector unsigned char){-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3});
+ *u8++ = ((vector unsigned char){-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4});
+ *u8++ = ((vector unsigned char){-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5});
+ *u8++ = ((vector unsigned char){-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6});
+ *u8++ = ((vector unsigned char){-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7});
+ *u8++ = ((vector unsigned char){-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8});
+ *u8++ = ((vector unsigned char){-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9});
+ *u8++ = ((vector unsigned char){-10,-10,-10,-10,-10,-10,-10,-10,-10,-10,-10,-10,-10,-10,-10,-10});
+ *u8++ = ((vector unsigned char){-11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11});
+ *u8++ = ((vector unsigned char){-12,-12,-12,-12,-12,-12,-12,-12,-12,-12,-12,-12,-12,-12,-12,-12});
+ *u8++ = ((vector unsigned char){-13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13});
+ *u8++ = ((vector unsigned char){-14,-14,-14,-14,-14,-14,-14,-14,-14,-14,-14,-14,-14,-14,-14,-14});
+ *u8++ = ((vector unsigned char){-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15});
+ *u8++ = ((vector unsigned char){-16,-16,-16,-16,-16,-16,-16,-16,-16,-16,-16,-16,-16,-16,-16,-16});
+}
+void fs32a(vector signed int *s32)
+{
+ *s32++ = ((vector signed int){0,0,0,0});
+ *s32++ = ((vector signed int){1,1,1,1});
+ *s32++ = ((vector signed int){2,2,2,2});
+ *s32++ = ((vector signed int){3,3,3,3});
+ *s32++ = ((vector signed int){4,4,4,4});
+ *s32++ = ((vector signed int){5,5,5,5});
+ *s32++ = ((vector signed int){6,6,6,6});
+ *s32++ = ((vector signed int){7,7,7,7});
+ *s32++ = ((vector signed int){8,8,8,8});
+ *s32++ = ((vector signed int){9,9,9,9});
+ *s32++ = ((vector signed int){10,10,10,10});
+ *s32++ = ((vector signed int){11,11,11,11});
+ *s32++ = ((vector signed int){12,12,12,12});
+ *s32++ = ((vector signed int){13,13,13,13});
+ *s32++ = ((vector signed int){14,14,14,14});
+ *s32++ = ((vector signed int){15,15,15,15});
+}
+void fs32b(vector signed int *s32)
+{
+ *s32++ = ((vector signed int){65537,65537,65537,65537});
+ *s32++ = ((vector signed int){131074,131074,131074,131074});
+ *s32++ = ((vector signed int){196611,196611,196611,196611});
+ *s32++ = ((vector signed int){262148,262148,262148,262148});
+ *s32++ = ((vector signed int){327685,327685,327685,327685});
+ *s32++ = ((vector signed int){393222,393222,393222,393222});
+ *s32++ = ((vector signed int){458759,458759,458759,458759});
+ *s32++ = ((vector signed int){524296,524296,524296,524296});
+ *s32++ = ((vector signed int){589833,589833,589833,589833});
+ *s32++ = ((vector signed int){655370,655370,655370,655370});
+ *s32++ = ((vector signed int){720907,720907,720907,720907});
+ *s32++ = ((vector signed int){786444,786444,786444,786444});
+ *s32++ = ((vector signed int){851981,851981,851981,851981});
+ *s32++ = ((vector signed int){917518,917518,917518,917518});
+ *s32++ = ((vector signed int){983055,983055,983055,983055});
+}
+void fs32c(vector signed int *s32)
+{
+ *s32++ = ((vector signed int){16843009,16843009,16843009,16843009});
+ *s32++ = ((vector signed int){33686018,33686018,33686018,33686018});
+ *s32++ = ((vector signed int){50529027,50529027,50529027,50529027});
+ *s32++ = ((vector signed int){67372036,67372036,67372036,67372036});
+ *s32++ = ((vector signed int){84215045,84215045,84215045,84215045});
+ *s32++ = ((vector signed int){101058054,101058054,101058054,101058054});
+ *s32++ = ((vector signed int){117901063,117901063,117901063,117901063});
+ *s32++ = ((vector signed int){134744072,134744072,134744072,134744072});
+ *s32++ = ((vector signed int){151587081,151587081,151587081,151587081});
+ *s32++ = ((vector signed int){168430090,168430090,168430090,168430090});
+ *s32++ = ((vector signed int){185273099,185273099,185273099,185273099});
+ *s32++ = ((vector signed int){202116108,202116108,202116108,202116108});
+ *s32++ = ((vector signed int){218959117,218959117,218959117,218959117});
+ *s32++ = ((vector signed int){235802126,235802126,235802126,235802126});
+ *s32++ = ((vector signed int){252645135,252645135,252645135,252645135});
+}
+void fs32d(vector signed int *s32)
+{
+ *s32++ = ((vector signed int){4042322160,4042322160,4042322160,4042322160});
+ *s32++ = ((vector signed int){4059165169,4059165169,4059165169,4059165169});
+ *s32++ = ((vector signed int){4076008178,4076008178,4076008178,4076008178});
+ *s32++ = ((vector signed int){4092851187,4092851187,4092851187,4092851187});
+ *s32++ = ((vector signed int){4109694196,4109694196,4109694196,4109694196});
+ *s32++ = ((vector signed int){4126537205,4126537205,4126537205,4126537205});
+ *s32++ = ((vector signed int){4143380214,4143380214,4143380214,4143380214});
+ *s32++ = ((vector signed int){4160223223,4160223223,4160223223,4160223223});
+ *s32++ = ((vector signed int){4177066232,4177066232,4177066232,4177066232});
+ *s32++ = ((vector signed int){4193909241,4193909241,4193909241,4193909241});
+ *s32++ = ((vector signed int){4210752250,4210752250,4210752250,4210752250});
+ *s32++ = ((vector signed int){4227595259,4227595259,4227595259,4227595259});
+ *s32++ = ((vector signed int){4244438268,4244438268,4244438268,4244438268});
+ *s32++ = ((vector signed int){4261281277,4261281277,4261281277,4261281277});
+ *s32++ = ((vector signed int){4278124286,4278124286,4278124286,4278124286});
+}
+void fs32e(vector signed int *s32)
+{
+ *s32++ = ((vector signed int){4293984240,4293984240,4293984240,4293984240});
+ *s32++ = ((vector signed int){4294049777,4294049777,4294049777,4294049777});
+ *s32++ = ((vector signed int){4294115314,4294115314,4294115314,4294115314});
+ *s32++ = ((vector signed int){4294180851,4294180851,4294180851,4294180851});
+ *s32++ = ((vector signed int){4294246388,4294246388,4294246388,4294246388});
+ *s32++ = ((vector signed int){4294311925,4294311925,4294311925,4294311925});
+ *s32++ = ((vector signed int){4294377462,4294377462,4294377462,4294377462});
+ *s32++ = ((vector signed int){4294442999,4294442999,4294442999,4294442999});
+ *s32++ = ((vector signed int){4294508536,4294508536,4294508536,4294508536});
+ *s32++ = ((vector signed int){4294574073,4294574073,4294574073,4294574073});
+ *s32++ = ((vector signed int){4294639610,4294639610,4294639610,4294639610});
+ *s32++ = ((vector signed int){4294705147,4294705147,4294705147,4294705147});
+ *s32++ = ((vector signed int){4294770684,4294770684,4294770684,4294770684});
+ *s32++ = ((vector signed int){4294836221,4294836221,4294836221,4294836221});
+ *s32++ = ((vector signed int){4294901758,4294901758,4294901758,4294901758});
+}
+void fs32f(vector signed int *s32)
+{
+ *s32++ = ((vector signed int){4294967280,4294967280,4294967280,4294967280});
+ *s32++ = ((vector signed int){4294967281,4294967281,4294967281,4294967281});
+ *s32++ = ((vector signed int){4294967282,4294967282,4294967282,4294967282});
+ *s32++ = ((vector signed int){4294967283,4294967283,4294967283,4294967283});
+ *s32++ = ((vector signed int){4294967284,4294967284,4294967284,4294967284});
+ *s32++ = ((vector signed int){4294967285,4294967285,4294967285,4294967285});
+ *s32++ = ((vector signed int){4294967286,4294967286,4294967286,4294967286});
+ *s32++ = ((vector signed int){4294967287,4294967287,4294967287,4294967287});
+ *s32++ = ((vector signed int){4294967288,4294967288,4294967288,4294967288});
+ *s32++ = ((vector signed int){4294967289,4294967289,4294967289,4294967289});
+ *s32++ = ((vector signed int){4294967290,4294967290,4294967290,4294967290});
+ *s32++ = ((vector signed int){4294967291,4294967291,4294967291,4294967291});
+ *s32++ = ((vector signed int){4294967292,4294967292,4294967292,4294967292});
+ *s32++ = ((vector signed int){4294967293,4294967293,4294967293,4294967293});
+ *s32++ = ((vector signed int){4294967294,4294967294,4294967294,4294967294});
+ *s32++ = ((vector signed int){4294967295,4294967295,4294967295,4294967295});
+}
+void fs32g(vector signed int *s32)
+{
+ *s32++ = ((vector signed int){-252645136,-252645136,-252645136,-252645136});
+ *s32++ = ((vector signed int){-235802127,-235802127,-235802127,-235802127});
+ *s32++ = ((vector signed int){-218959118,-218959118,-218959118,-218959118});
+ *s32++ = ((vector signed int){-202116109,-202116109,-202116109,-202116109});
+ *s32++ = ((vector signed int){-185273100,-185273100,-185273100,-185273100});
+ *s32++ = ((vector signed int){-168430091,-168430091,-168430091,-168430091});
+ *s32++ = ((vector signed int){-151587082,-151587082,-151587082,-151587082});
+ *s32++ = ((vector signed int){-134744073,-134744073,-134744073,-134744073});
+ *s32++ = ((vector signed int){-117901064,-117901064,-117901064,-117901064});
+ *s32++ = ((vector signed int){-101058055,-101058055,-101058055,-101058055});
+ *s32++ = ((vector signed int){-84215046,-84215046,-84215046,-84215046});
+ *s32++ = ((vector signed int){-67372037,-67372037,-67372037,-67372037});
+ *s32++ = ((vector signed int){-50529028,-50529028,-50529028,-50529028});
+ *s32++ = ((vector signed int){-33686019,-33686019,-33686019,-33686019});
+ *s32++ = ((vector signed int){-16843010,-16843010,-16843010,-16843010});
+}
+void fs32h(vector signed int *s32)
+{
+ *s32++ = ((vector signed int){-983056,-983056,-983056,-983056});
+ *s32++ = ((vector signed int){-917519,-917519,-917519,-917519});
+ *s32++ = ((vector signed int){-851982,-851982,-851982,-851982});
+ *s32++ = ((vector signed int){-786445,-786445,-786445,-786445});
+ *s32++ = ((vector signed int){-720908,-720908,-720908,-720908});
+ *s32++ = ((vector signed int){-655371,-655371,-655371,-655371});
+ *s32++ = ((vector signed int){-589834,-589834,-589834,-589834});
+ *s32++ = ((vector signed int){-524297,-524297,-524297,-524297});
+ *s32++ = ((vector signed int){-458760,-458760,-458760,-458760});
+ *s32++ = ((vector signed int){-393223,-393223,-393223,-393223});
+ *s32++ = ((vector signed int){-327686,-327686,-327686,-327686});
+ *s32++ = ((vector signed int){-262149,-262149,-262149,-262149});
+ *s32++ = ((vector signed int){-196612,-196612,-196612,-196612});
+ *s32++ = ((vector signed int){-131075,-131075,-131075,-131075});
+ *s32++ = ((vector signed int){-65538,-65538,-65538,-65538});
+}
+void fs32i(vector signed int *s32)
+{
+ *s32++ = ((vector signed int){-16,-16,-16,-16});
+ *s32++ = ((vector signed int){-15,-15,-15,-15});
+ *s32++ = ((vector signed int){-14,-14,-14,-14});
+ *s32++ = ((vector signed int){-13,-13,-13,-13});
+ *s32++ = ((vector signed int){-12,-12,-12,-12});
+ *s32++ = ((vector signed int){-11,-11,-11,-11});
+ *s32++ = ((vector signed int){-10,-10,-10,-10});
+ *s32++ = ((vector signed int){-9,-9,-9,-9});
+ *s32++ = ((vector signed int){-8,-8,-8,-8});
+ *s32++ = ((vector signed int){-7,-7,-7,-7});
+ *s32++ = ((vector signed int){-6,-6,-6,-6});
+ *s32++ = ((vector signed int){-5,-5,-5,-5});
+ *s32++ = ((vector signed int){-4,-4,-4,-4});
+ *s32++ = ((vector signed int){-3,-3,-3,-3});
+ *s32++ = ((vector signed int){-2,-2,-2,-2});
+ *s32++ = ((vector signed int){-1,-1,-1,-1});
+}
+void fs32j(vector signed int *s32)
+{
+ *s32++ = ((vector signed int){0xfffffff0,0xfffffff0,0xfffffff0,0xfffffff0});
+ *s32++ = ((vector signed int){0xfffffff1,0xfffffff1,0xfffffff1,0xfffffff1});
+ *s32++ = ((vector signed int){0xfffffff2,0xfffffff2,0xfffffff2,0xfffffff2});
+ *s32++ = ((vector signed int){0xfffffff3,0xfffffff3,0xfffffff3,0xfffffff3});
+ *s32++ = ((vector signed int){0xfffffff4,0xfffffff4,0xfffffff4,0xfffffff4});
+ *s32++ = ((vector signed int){0xfffffff5,0xfffffff5,0xfffffff5,0xfffffff5});
+ *s32++ = ((vector signed int){0xfffffff6,0xfffffff6,0xfffffff6,0xfffffff6});
+ *s32++ = ((vector signed int){0xfffffff7,0xfffffff7,0xfffffff7,0xfffffff7});
+ *s32++ = ((vector signed int){0xfffffff8,0xfffffff8,0xfffffff8,0xfffffff8});
+ *s32++ = ((vector signed int){0xfffffff9,0xfffffff9,0xfffffff9,0xfffffff9});
+ *s32++ = ((vector signed int){0xfffffffa,0xfffffffa,0xfffffffa,0xfffffffa});
+ *s32++ = ((vector signed int){0xfffffffb,0xfffffffb,0xfffffffb,0xfffffffb});
+ *s32++ = ((vector signed int){0xfffffffc,0xfffffffc,0xfffffffc,0xfffffffc});
+ *s32++ = ((vector signed int){0xfffffffd,0xfffffffd,0xfffffffd,0xfffffffd});
+ *s32++ = ((vector signed int){0xfffffffe,0xfffffffe,0xfffffffe,0xfffffffe});
+ *s32++ = ((vector signed int){0xffffffff,0xffffffff,0xffffffff,0xffffffff});
+}
+void fs32k(vector signed int *s32)
+{
+ *s32++ = ((vector signed int){0x00000000,0x00000000,0x00000000,0x00000000});
+ *s32++ = ((vector signed int){0x00000001,0x00000001,0x00000001,0x00000001});
+ *s32++ = ((vector signed int){0x00000002,0x00000002,0x00000002,0x00000002});
+ *s32++ = ((vector signed int){0x00000003,0x00000003,0x00000003,0x00000003});
+ *s32++ = ((vector signed int){0x00000004,0x00000004,0x00000004,0x00000004});
+ *s32++ = ((vector signed int){0x00000005,0x00000005,0x00000005,0x00000005});
+ *s32++ = ((vector signed int){0x00000006,0x00000006,0x00000006,0x00000006});
+ *s32++ = ((vector signed int){0x00000007,0x00000007,0x00000007,0x00000007});
+ *s32++ = ((vector signed int){0x00000008,0x00000008,0x00000008,0x00000008});
+ *s32++ = ((vector signed int){0x00000009,0x00000009,0x00000009,0x00000009});
+ *s32++ = ((vector signed int){0x0000000a,0x0000000a,0x0000000a,0x0000000a});
+ *s32++ = ((vector signed int){0x0000000b,0x0000000b,0x0000000b,0x0000000b});
+ *s32++ = ((vector signed int){0x0000000c,0x0000000c,0x0000000c,0x0000000c});
+ *s32++ = ((vector signed int){0x0000000d,0x0000000d,0x0000000d,0x0000000d});
+ *s32++ = ((vector signed int){0x0000000e,0x0000000e,0x0000000e,0x0000000e});
+ *s32++ = ((vector signed int){0x0000000f,0x0000000f,0x0000000f,0x0000000f});
+}
+void fs32l(vector signed int *s32)
+{
+ *s32++ = ((vector signed int){0xfff0fff0,0xfff0fff0,0xfff0fff0,0xfff0fff0});
+ *s32++ = ((vector signed int){0xfff1fff1,0xfff1fff1,0xfff1fff1,0xfff1fff1});
+ *s32++ = ((vector signed int){0xfff2fff2,0xfff2fff2,0xfff2fff2,0xfff2fff2});
+ *s32++ = ((vector signed int){0xfff3fff3,0xfff3fff3,0xfff3fff3,0xfff3fff3});
+ *s32++ = ((vector signed int){0xfff4fff4,0xfff4fff4,0xfff4fff4,0xfff4fff4});
+ *s32++ = ((vector signed int){0xfff5fff5,0xfff5fff5,0xfff5fff5,0xfff5fff5});
+ *s32++ = ((vector signed int){0xfff6fff6,0xfff6fff6,0xfff6fff6,0xfff6fff6});
+ *s32++ = ((vector signed int){0xfff7fff7,0xfff7fff7,0xfff7fff7,0xfff7fff7});
+ *s32++ = ((vector signed int){0xfff8fff8,0xfff8fff8,0xfff8fff8,0xfff8fff8});
+ *s32++ = ((vector signed int){0xfff9fff9,0xfff9fff9,0xfff9fff9,0xfff9fff9});
+ *s32++ = ((vector signed int){0xfffafffa,0xfffafffa,0xfffafffa,0xfffafffa});
+ *s32++ = ((vector signed int){0xfffbfffb,0xfffbfffb,0xfffbfffb,0xfffbfffb});
+ *s32++ = ((vector signed int){0xfffcfffc,0xfffcfffc,0xfffcfffc,0xfffcfffc});
+ *s32++ = ((vector signed int){0xfffdfffd,0xfffdfffd,0xfffdfffd,0xfffdfffd});
+ *s32++ = ((vector signed int){0xfffefffe,0xfffefffe,0xfffefffe,0xfffefffe});
+ *s32++ = ((vector signed int){0xffffffff,0xffffffff,0xffffffff,0xffffffff});
+}
+void fs32m(vector signed int *s32)
+{
+ *s32++ = ((vector signed int){0x00000000,0x00000000,0x00000000,0x00000000});
+ *s32++ = ((vector signed int){0x00010001,0x00010001,0x00010001,0x00010001});
+ *s32++ = ((vector signed int){0x00020002,0x00020002,0x00020002,0x00020002});
+ *s32++ = ((vector signed int){0x00030003,0x00030003,0x00030003,0x00030003});
+ *s32++ = ((vector signed int){0x00040004,0x00040004,0x00040004,0x00040004});
+ *s32++ = ((vector signed int){0x00050005,0x00050005,0x00050005,0x00050005});
+ *s32++ = ((vector signed int){0x00060006,0x00060006,0x00060006,0x00060006});
+ *s32++ = ((vector signed int){0x00070007,0x00070007,0x00070007,0x00070007});
+ *s32++ = ((vector signed int){0x00080008,0x00080008,0x00080008,0x00080008});
+ *s32++ = ((vector signed int){0x00090009,0x00090009,0x00090009,0x00090009});
+ *s32++ = ((vector signed int){0x000a000a,0x000a000a,0x000a000a,0x000a000a});
+ *s32++ = ((vector signed int){0x000b000b,0x000b000b,0x000b000b,0x000b000b});
+ *s32++ = ((vector signed int){0x000c000c,0x000c000c,0x000c000c,0x000c000c});
+ *s32++ = ((vector signed int){0x000d000d,0x000d000d,0x000d000d,0x000d000d});
+ *s32++ = ((vector signed int){0x000e000e,0x000e000e,0x000e000e,0x000e000e});
+ *s32++ = ((vector signed int){0x000f000f,0x000f000f,0x000f000f,0x000f000f});
+}
+void fs32n(vector signed int *s32)
+{
+ *s32++ = ((vector signed int){0xf0f0f0f0,0xf0f0f0f0,0xf0f0f0f0,0xf0f0f0f0});
+ *s32++ = ((vector signed int){0xf1f1f1f1,0xf1f1f1f1,0xf1f1f1f1,0xf1f1f1f1});
+ *s32++ = ((vector signed int){0xf2f2f2f2,0xf2f2f2f2,0xf2f2f2f2,0xf2f2f2f2});
+ *s32++ = ((vector signed int){0xf3f3f3f3,0xf3f3f3f3,0xf3f3f3f3,0xf3f3f3f3});
+ *s32++ = ((vector signed int){0xf4f4f4f4,0xf4f4f4f4,0xf4f4f4f4,0xf4f4f4f4});
+ *s32++ = ((vector signed int){0xf5f5f5f5,0xf5f5f5f5,0xf5f5f5f5,0xf5f5f5f5});
+ *s32++ = ((vector signed int){0xf6f6f6f6,0xf6f6f6f6,0xf6f6f6f6,0xf6f6f6f6});
+ *s32++ = ((vector signed int){0xf7f7f7f7,0xf7f7f7f7,0xf7f7f7f7,0xf7f7f7f7});
+ *s32++ = ((vector signed int){0xf8f8f8f8,0xf8f8f8f8,0xf8f8f8f8,0xf8f8f8f8});
+ *s32++ = ((vector signed int){0xf9f9f9f9,0xf9f9f9f9,0xf9f9f9f9,0xf9f9f9f9});
+ *s32++ = ((vector signed int){0xfafafafa,0xfafafafa,0xfafafafa,0xfafafafa});
+ *s32++ = ((vector signed int){0xfbfbfbfb,0xfbfbfbfb,0xfbfbfbfb,0xfbfbfbfb});
+ *s32++ = ((vector signed int){0xfcfcfcfc,0xfcfcfcfc,0xfcfcfcfc,0xfcfcfcfc});
+ *s32++ = ((vector signed int){0xfdfdfdfd,0xfdfdfdfd,0xfdfdfdfd,0xfdfdfdfd});
+ *s32++ = ((vector signed int){0xfefefefe,0xfefefefe,0xfefefefe,0xfefefefe});
+ *s32++ = ((vector signed int){0xffffffff,0xffffffff,0xffffffff,0xffffffff});
+}
+void fs32o(vector signed int *s32)
+{
+ *s32++ = ((vector signed int){0x00000000,0x00000000,0x00000000,0x00000000});
+ *s32++ = ((vector signed int){0x01010101,0x01010101,0x01010101,0x01010101});
+ *s32++ = ((vector signed int){0x02020202,0x02020202,0x02020202,0x02020202});
+ *s32++ = ((vector signed int){0x03030303,0x03030303,0x03030303,0x03030303});
+ *s32++ = ((vector signed int){0x04040404,0x04040404,0x04040404,0x04040404});
+ *s32++ = ((vector signed int){0x05050505,0x05050505,0x05050505,0x05050505});
+ *s32++ = ((vector signed int){0x06060606,0x06060606,0x06060606,0x06060606});
+ *s32++ = ((vector signed int){0x07070707,0x07070707,0x07070707,0x07070707});
+ *s32++ = ((vector signed int){0x08080808,0x08080808,0x08080808,0x08080808});
+ *s32++ = ((vector signed int){0x09090909,0x09090909,0x09090909,0x09090909});
+ *s32++ = ((vector signed int){0x0a0a0a0a,0x0a0a0a0a,0x0a0a0a0a,0x0a0a0a0a});
+ *s32++ = ((vector signed int){0x0b0b0b0b,0x0b0b0b0b,0x0b0b0b0b,0x0b0b0b0b});
+ *s32++ = ((vector signed int){0x0c0c0c0c,0x0c0c0c0c,0x0c0c0c0c,0x0c0c0c0c});
+ *s32++ = ((vector signed int){0x0d0d0d0d,0x0d0d0d0d,0x0d0d0d0d,0x0d0d0d0d});
+ *s32++ = ((vector signed int){0x0e0e0e0e,0x0e0e0e0e,0x0e0e0e0e,0x0e0e0e0e});
+ *s32++ = ((vector signed int){0x0f0f0f0f,0x0f0f0f0f,0x0f0f0f0f,0x0f0f0f0f});
+}
+void fs16a(vector signed short *s16)
+{
+ *s16++ = ((vector signed short){0xffff,0xfff0,0xffff,0xfff0,0xffff,0xfff0,0xffff,0xfff0});
+ *s16++ = ((vector signed short){0xffff,0xfff1,0xffff,0xfff1,0xffff,0xfff1,0xffff,0xfff1});
+ *s16++ = ((vector signed short){0xffff,0xfff2,0xffff,0xfff2,0xffff,0xfff2,0xffff,0xfff2});
+ *s16++ = ((vector signed short){0xffff,0xfff3,0xffff,0xfff3,0xffff,0xfff3,0xffff,0xfff3});
+ *s16++ = ((vector signed short){0xffff,0xfff4,0xffff,0xfff4,0xffff,0xfff4,0xffff,0xfff4});
+ *s16++ = ((vector signed short){0xffff,0xfff5,0xffff,0xfff5,0xffff,0xfff5,0xffff,0xfff5});
+ *s16++ = ((vector signed short){0xffff,0xfff6,0xffff,0xfff6,0xffff,0xfff6,0xffff,0xfff6});
+ *s16++ = ((vector signed short){0xffff,0xfff7,0xffff,0xfff7,0xffff,0xfff7,0xffff,0xfff7});
+ *s16++ = ((vector signed short){0xffff,0xfff8,0xffff,0xfff8,0xffff,0xfff8,0xffff,0xfff8});
+ *s16++ = ((vector signed short){0xffff,0xfff9,0xffff,0xfff9,0xffff,0xfff9,0xffff,0xfff9});
+ *s16++ = ((vector signed short){0xffff,0xfffa,0xffff,0xfffa,0xffff,0xfffa,0xffff,0xfffa});
+ *s16++ = ((vector signed short){0xffff,0xfffb,0xffff,0xfffb,0xffff,0xfffb,0xffff,0xfffb});
+ *s16++ = ((vector signed short){0xffff,0xfffc,0xffff,0xfffc,0xffff,0xfffc,0xffff,0xfffc});
+ *s16++ = ((vector signed short){0xffff,0xfffd,0xffff,0xfffd,0xffff,0xfffd,0xffff,0xfffd});
+ *s16++ = ((vector signed short){0xffff,0xfffe,0xffff,0xfffe,0xffff,0xfffe,0xffff,0xfffe});
+ *s16++ = ((vector signed short){0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff});
+}
+void fs16b(vector signed short *s16)
+{
+ *s16++ = ((vector signed short){0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000});
+ *s16++ = ((vector signed short){0x0000,0x0001,0x0000,0x0001,0x0000,0x0001,0x0000,0x0001});
+ *s16++ = ((vector signed short){0x0000,0x0002,0x0000,0x0002,0x0000,0x0002,0x0000,0x0002});
+ *s16++ = ((vector signed short){0x0000,0x0003,0x0000,0x0003,0x0000,0x0003,0x0000,0x0003});
+ *s16++ = ((vector signed short){0x0000,0x0004,0x0000,0x0004,0x0000,0x0004,0x0000,0x0004});
+ *s16++ = ((vector signed short){0x0000,0x0005,0x0000,0x0005,0x0000,0x0005,0x0000,0x0005});
+ *s16++ = ((vector signed short){0x0000,0x0006,0x0000,0x0006,0x0000,0x0006,0x0000,0x0006});
+ *s16++ = ((vector signed short){0x0000,0x0007,0x0000,0x0007,0x0000,0x0007,0x0000,0x0007});
+ *s16++ = ((vector signed short){0x0000,0x0008,0x0000,0x0008,0x0000,0x0008,0x0000,0x0008});
+ *s16++ = ((vector signed short){0x0000,0x0009,0x0000,0x0009,0x0000,0x0009,0x0000,0x0009});
+ *s16++ = ((vector signed short){0x0000,0x000a,0x0000,0x000a,0x0000,0x000a,0x0000,0x000a});
+ *s16++ = ((vector signed short){0x0000,0x000b,0x0000,0x000b,0x0000,0x000b,0x0000,0x000b});
+ *s16++ = ((vector signed short){0x0000,0x000c,0x0000,0x000c,0x0000,0x000c,0x0000,0x000c});
+ *s16++ = ((vector signed short){0x0000,0x000d,0x0000,0x000d,0x0000,0x000d,0x0000,0x000d});
+ *s16++ = ((vector signed short){0x0000,0x000e,0x0000,0x000e,0x0000,0x000e,0x0000,0x000e});
+ *s16++ = ((vector signed short){0x0000,0x000f,0x0000,0x000f,0x0000,0x000f,0x0000,0x000f});
+}
+void fs16c(vector signed short *s16)
+{
+ *s16++ = ((vector signed short){0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0});
+ *s16++ = ((vector signed short){0xfff1,0xfff1,0xfff1,0xfff1,0xfff1,0xfff1,0xfff1,0xfff1});
+ *s16++ = ((vector signed short){0xfff2,0xfff2,0xfff2,0xfff2,0xfff2,0xfff2,0xfff2,0xfff2});
+ *s16++ = ((vector signed short){0xfff3,0xfff3,0xfff3,0xfff3,0xfff3,0xfff3,0xfff3,0xfff3});
+ *s16++ = ((vector signed short){0xfff4,0xfff4,0xfff4,0xfff4,0xfff4,0xfff4,0xfff4,0xfff4});
+ *s16++ = ((vector signed short){0xfff5,0xfff5,0xfff5,0xfff5,0xfff5,0xfff5,0xfff5,0xfff5});
+ *s16++ = ((vector signed short){0xfff6,0xfff6,0xfff6,0xfff6,0xfff6,0xfff6,0xfff6,0xfff6});
+ *s16++ = ((vector signed short){0xfff7,0xfff7,0xfff7,0xfff7,0xfff7,0xfff7,0xfff7,0xfff7});
+ *s16++ = ((vector signed short){0xfff8,0xfff8,0xfff8,0xfff8,0xfff8,0xfff8,0xfff8,0xfff8});
+ *s16++ = ((vector signed short){0xfff9,0xfff9,0xfff9,0xfff9,0xfff9,0xfff9,0xfff9,0xfff9});
+ *s16++ = ((vector signed short){0xfffa,0xfffa,0xfffa,0xfffa,0xfffa,0xfffa,0xfffa,0xfffa});
+ *s16++ = ((vector signed short){0xfffb,0xfffb,0xfffb,0xfffb,0xfffb,0xfffb,0xfffb,0xfffb});
+ *s16++ = ((vector signed short){0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc});
+ *s16++ = ((vector signed short){0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd});
+ *s16++ = ((vector signed short){0xfffe,0xfffe,0xfffe,0xfffe,0xfffe,0xfffe,0xfffe,0xfffe});
+ *s16++ = ((vector signed short){0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff});
+}
+void fs16d(vector signed short *s16)
+{
+ *s16++ = ((vector signed short){0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000});
+ *s16++ = ((vector signed short){0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001});
+ *s16++ = ((vector signed short){0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002});
+ *s16++ = ((vector signed short){0x0003,0x0003,0x0003,0x0003,0x0003,0x0003,0x0003,0x0003});
+ *s16++ = ((vector signed short){0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004});
+ *s16++ = ((vector signed short){0x0005,0x0005,0x0005,0x0005,0x0005,0x0005,0x0005,0x0005});
+ *s16++ = ((vector signed short){0x0006,0x0006,0x0006,0x0006,0x0006,0x0006,0x0006,0x0006});
+ *s16++ = ((vector signed short){0x0007,0x0007,0x0007,0x0007,0x0007,0x0007,0x0007,0x0007});
+ *s16++ = ((vector signed short){0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008});
+ *s16++ = ((vector signed short){0x0009,0x0009,0x0009,0x0009,0x0009,0x0009,0x0009,0x0009});
+ *s16++ = ((vector signed short){0x000a,0x000a,0x000a,0x000a,0x000a,0x000a,0x000a,0x000a});
+ *s16++ = ((vector signed short){0x000b,0x000b,0x000b,0x000b,0x000b,0x000b,0x000b,0x000b});
+ *s16++ = ((vector signed short){0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c});
+ *s16++ = ((vector signed short){0x000d,0x000d,0x000d,0x000d,0x000d,0x000d,0x000d,0x000d});
+ *s16++ = ((vector signed short){0x000e,0x000e,0x000e,0x000e,0x000e,0x000e,0x000e,0x000e});
+ *s16++ = ((vector signed short){0x000f,0x000f,0x000f,0x000f,0x000f,0x000f,0x000f,0x000f});
+}
+void fs16e(vector signed short *s16)
+{
+ *s16++ = ((vector signed short){0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0,0xf0f0});
+ *s16++ = ((vector signed short){0xf1f1,0xf1f1,0xf1f1,0xf1f1,0xf1f1,0xf1f1,0xf1f1,0xf1f1});
+ *s16++ = ((vector signed short){0xf2f2,0xf2f2,0xf2f2,0xf2f2,0xf2f2,0xf2f2,0xf2f2,0xf2f2});
+ *s16++ = ((vector signed short){0xf3f3,0xf3f3,0xf3f3,0xf3f3,0xf3f3,0xf3f3,0xf3f3,0xf3f3});
+ *s16++ = ((vector signed short){0xf4f4,0xf4f4,0xf4f4,0xf4f4,0xf4f4,0xf4f4,0xf4f4,0xf4f4});
+ *s16++ = ((vector signed short){0xf5f5,0xf5f5,0xf5f5,0xf5f5,0xf5f5,0xf5f5,0xf5f5,0xf5f5});
+ *s16++ = ((vector signed short){0xf6f6,0xf6f6,0xf6f6,0xf6f6,0xf6f6,0xf6f6,0xf6f6,0xf6f6});
+ *s16++ = ((vector signed short){0xf7f7,0xf7f7,0xf7f7,0xf7f7,0xf7f7,0xf7f7,0xf7f7,0xf7f7});
+ *s16++ = ((vector signed short){0xf8f8,0xf8f8,0xf8f8,0xf8f8,0xf8f8,0xf8f8,0xf8f8,0xf8f8});
+ *s16++ = ((vector signed short){0xf9f9,0xf9f9,0xf9f9,0xf9f9,0xf9f9,0xf9f9,0xf9f9,0xf9f9});
+ *s16++ = ((vector signed short){0xfafa,0xfafa,0xfafa,0xfafa,0xfafa,0xfafa,0xfafa,0xfafa});
+ *s16++ = ((vector signed short){0xfbfb,0xfbfb,0xfbfb,0xfbfb,0xfbfb,0xfbfb,0xfbfb,0xfbfb});
+ *s16++ = ((vector signed short){0xfcfc,0xfcfc,0xfcfc,0xfcfc,0xfcfc,0xfcfc,0xfcfc,0xfcfc});
+ *s16++ = ((vector signed short){0xfdfd,0xfdfd,0xfdfd,0xfdfd,0xfdfd,0xfdfd,0xfdfd,0xfdfd});
+ *s16++ = ((vector signed short){0xfefe,0xfefe,0xfefe,0xfefe,0xfefe,0xfefe,0xfefe,0xfefe});
+ *s16++ = ((vector signed short){0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff});
+}
+void fs16f(vector signed short *s16)
+{
+ *s16++ = ((vector signed short){0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000});
+ *s16++ = ((vector signed short){0x0101,0x0101,0x0101,0x0101,0x0101,0x0101,0x0101,0x0101});
+ *s16++ = ((vector signed short){0x0202,0x0202,0x0202,0x0202,0x0202,0x0202,0x0202,0x0202});
+ *s16++ = ((vector signed short){0x0303,0x0303,0x0303,0x0303,0x0303,0x0303,0x0303,0x0303});
+ *s16++ = ((vector signed short){0x0404,0x0404,0x0404,0x0404,0x0404,0x0404,0x0404,0x0404});
+ *s16++ = ((vector signed short){0x0505,0x0505,0x0505,0x0505,0x0505,0x0505,0x0505,0x0505});
+ *s16++ = ((vector signed short){0x0606,0x0606,0x0606,0x0606,0x0606,0x0606,0x0606,0x0606});
+ *s16++ = ((vector signed short){0x0707,0x0707,0x0707,0x0707,0x0707,0x0707,0x0707,0x0707});
+ *s16++ = ((vector signed short){0x0808,0x0808,0x0808,0x0808,0x0808,0x0808,0x0808,0x0808});
+ *s16++ = ((vector signed short){0x0909,0x0909,0x0909,0x0909,0x0909,0x0909,0x0909,0x0909});
+ *s16++ = ((vector signed short){0x0a0a,0x0a0a,0x0a0a,0x0a0a,0x0a0a,0x0a0a,0x0a0a,0x0a0a});
+ *s16++ = ((vector signed short){0x0b0b,0x0b0b,0x0b0b,0x0b0b,0x0b0b,0x0b0b,0x0b0b,0x0b0b});
+ *s16++ = ((vector signed short){0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x0c0c});
+ *s16++ = ((vector signed short){0x0d0d,0x0d0d,0x0d0d,0x0d0d,0x0d0d,0x0d0d,0x0d0d,0x0d0d});
+ *s16++ = ((vector signed short){0x0e0e,0x0e0e,0x0e0e,0x0e0e,0x0e0e,0x0e0e,0x0e0e,0x0e0e});
+ *s16++ = ((vector signed short){0x0f0f,0x0f0f,0x0f0f,0x0f0f,0x0f0f,0x0f0f,0x0f0f,0x0f0f});
+}
+void fs16g(vector signed short *s16)
+{
+ *s16++ = ((vector signed short){0,0,0,0,0,0,0,0});
+ *s16++ = ((vector signed short){1,1,1,1,1,1,1,1});
+ *s16++ = ((vector signed short){2,2,2,2,2,2,2,2});
+ *s16++ = ((vector signed short){3,3,3,3,3,3,3,3});
+ *s16++ = ((vector signed short){4,4,4,4,4,4,4,4});
+ *s16++ = ((vector signed short){5,5,5,5,5,5,5,5});
+ *s16++ = ((vector signed short){6,6,6,6,6,6,6,6});
+ *s16++ = ((vector signed short){7,7,7,7,7,7,7,7});
+ *s16++ = ((vector signed short){8,8,8,8,8,8,8,8});
+ *s16++ = ((vector signed short){9,9,9,9,9,9,9,9});
+ *s16++ = ((vector signed short){10,10,10,10,10,10,10,10});
+ *s16++ = ((vector signed short){11,11,11,11,11,11,11,11});
+ *s16++ = ((vector signed short){12,12,12,12,12,12,12,12});
+ *s16++ = ((vector signed short){13,13,13,13,13,13,13,13});
+ *s16++ = ((vector signed short){14,14,14,14,14,14,14,14});
+ *s16++ = ((vector signed short){15,15,15,15,15,15,15,15});
+}
+void fs16h(vector signed short *s16)
+{
+ *s16++ = ((vector signed short){257,257,257,257,257,257,257,257});
+ *s16++ = ((vector signed short){514,514,514,514,514,514,514,514});
+ *s16++ = ((vector signed short){771,771,771,771,771,771,771,771});
+ *s16++ = ((vector signed short){1028,1028,1028,1028,1028,1028,1028,1028});
+ *s16++ = ((vector signed short){1285,1285,1285,1285,1285,1285,1285,1285});
+ *s16++ = ((vector signed short){1542,1542,1542,1542,1542,1542,1542,1542});
+ *s16++ = ((vector signed short){1799,1799,1799,1799,1799,1799,1799,1799});
+ *s16++ = ((vector signed short){2056,2056,2056,2056,2056,2056,2056,2056});
+ *s16++ = ((vector signed short){2313,2313,2313,2313,2313,2313,2313,2313});
+ *s16++ = ((vector signed short){2570,2570,2570,2570,2570,2570,2570,2570});
+ *s16++ = ((vector signed short){2827,2827,2827,2827,2827,2827,2827,2827});
+ *s16++ = ((vector signed short){3084,3084,3084,3084,3084,3084,3084,3084});
+ *s16++ = ((vector signed short){3341,3341,3341,3341,3341,3341,3341,3341});
+ *s16++ = ((vector signed short){3598,3598,3598,3598,3598,3598,3598,3598});
+ *s16++ = ((vector signed short){3855,3855,3855,3855,3855,3855,3855,3855});
+}
+void fs16i(vector signed short *s16)
+{
+ *s16++ = ((vector signed short){61680,61680,61680,61680,61680,61680,61680,61680});
+ *s16++ = ((vector signed short){61937,61937,61937,61937,61937,61937,61937,61937});
+ *s16++ = ((vector signed short){62194,62194,62194,62194,62194,62194,62194,62194});
+ *s16++ = ((vector signed short){62451,62451,62451,62451,62451,62451,62451,62451});
+ *s16++ = ((vector signed short){62708,62708,62708,62708,62708,62708,62708,62708});
+ *s16++ = ((vector signed short){62965,62965,62965,62965,62965,62965,62965,62965});
+ *s16++ = ((vector signed short){63222,63222,63222,63222,63222,63222,63222,63222});
+ *s16++ = ((vector signed short){63479,63479,63479,63479,63479,63479,63479,63479});
+ *s16++ = ((vector signed short){63736,63736,63736,63736,63736,63736,63736,63736});
+ *s16++ = ((vector signed short){63993,63993,63993,63993,63993,63993,63993,63993});
+ *s16++ = ((vector signed short){64250,64250,64250,64250,64250,64250,64250,64250});
+ *s16++ = ((vector signed short){64507,64507,64507,64507,64507,64507,64507,64507});
+ *s16++ = ((vector signed short){64764,64764,64764,64764,64764,64764,64764,64764});
+ *s16++ = ((vector signed short){65021,65021,65021,65021,65021,65021,65021,65021});
+ *s16++ = ((vector signed short){65278,65278,65278,65278,65278,65278,65278,65278});
+}
+void fs16j(vector signed short *s16)
+{
+ *s16++ = ((vector signed short){65520,65520,65520,65520,65520,65520,65520,65520});
+ *s16++ = ((vector signed short){65521,65521,65521,65521,65521,65521,65521,65521});
+ *s16++ = ((vector signed short){65522,65522,65522,65522,65522,65522,65522,65522});
+ *s16++ = ((vector signed short){65523,65523,65523,65523,65523,65523,65523,65523});
+ *s16++ = ((vector signed short){65524,65524,65524,65524,65524,65524,65524,65524});
+ *s16++ = ((vector signed short){65525,65525,65525,65525,65525,65525,65525,65525});
+ *s16++ = ((vector signed short){65526,65526,65526,65526,65526,65526,65526,65526});
+ *s16++ = ((vector signed short){65527,65527,65527,65527,65527,65527,65527,65527});
+ *s16++ = ((vector signed short){65528,65528,65528,65528,65528,65528,65528,65528});
+ *s16++ = ((vector signed short){65529,65529,65529,65529,65529,65529,65529,65529});
+ *s16++ = ((vector signed short){65530,65530,65530,65530,65530,65530,65530,65530});
+ *s16++ = ((vector signed short){65531,65531,65531,65531,65531,65531,65531,65531});
+ *s16++ = ((vector signed short){65532,65532,65532,65532,65532,65532,65532,65532});
+ *s16++ = ((vector signed short){65533,65533,65533,65533,65533,65533,65533,65533});
+ *s16++ = ((vector signed short){65534,65534,65534,65534,65534,65534,65534,65534});
+ *s16++ = ((vector signed short){65535,65535,65535,65535,65535,65535,65535,65535});
+}
+void fs16k(vector signed short *s16)
+{
+ *s16++ = ((vector signed short){-3856,-3856,-3856,-3856,-3856,-3856,-3856,-3856});
+ *s16++ = ((vector signed short){-3599,-3599,-3599,-3599,-3599,-3599,-3599,-3599});
+ *s16++ = ((vector signed short){-3342,-3342,-3342,-3342,-3342,-3342,-3342,-3342});
+ *s16++ = ((vector signed short){-3085,-3085,-3085,-3085,-3085,-3085,-3085,-3085});
+ *s16++ = ((vector signed short){-2828,-2828,-2828,-2828,-2828,-2828,-2828,-2828});
+ *s16++ = ((vector signed short){-2571,-2571,-2571,-2571,-2571,-2571,-2571,-2571});
+ *s16++ = ((vector signed short){-2314,-2314,-2314,-2314,-2314,-2314,-2314,-2314});
+ *s16++ = ((vector signed short){-2057,-2057,-2057,-2057,-2057,-2057,-2057,-2057});
+ *s16++ = ((vector signed short){-1800,-1800,-1800,-1800,-1800,-1800,-1800,-1800});
+ *s16++ = ((vector signed short){-1543,-1543,-1543,-1543,-1543,-1543,-1543,-1543});
+ *s16++ = ((vector signed short){-1286,-1286,-1286,-1286,-1286,-1286,-1286,-1286});
+ *s16++ = ((vector signed short){-1029,-1029,-1029,-1029,-1029,-1029,-1029,-1029});
+ *s16++ = ((vector signed short){-772,-772,-772,-772,-772,-772,-772,-772});
+ *s16++ = ((vector signed short){-515,-515,-515,-515,-515,-515,-515,-515});
+ *s16++ = ((vector signed short){-258,-258,-258,-258,-258,-258,-258,-258});
+}
+void fs16l(vector signed short *s16)
+{
+ *s16++ = ((vector signed short){-16,-16,-16,-16,-16,-16,-16,-16});
+ *s16++ = ((vector signed short){-15,-15,-15,-15,-15,-15,-15,-15});
+ *s16++ = ((vector signed short){-14,-14,-14,-14,-14,-14,-14,-14});
+ *s16++ = ((vector signed short){-13,-13,-13,-13,-13,-13,-13,-13});
+ *s16++ = ((vector signed short){-12,-12,-12,-12,-12,-12,-12,-12});
+ *s16++ = ((vector signed short){-11,-11,-11,-11,-11,-11,-11,-11});
+ *s16++ = ((vector signed short){-10,-10,-10,-10,-10,-10,-10,-10});
+ *s16++ = ((vector signed short){-9,-9,-9,-9,-9,-9,-9,-9});
+ *s16++ = ((vector signed short){-8,-8,-8,-8,-8,-8,-8,-8});
+ *s16++ = ((vector signed short){-7,-7,-7,-7,-7,-7,-7,-7});
+ *s16++ = ((vector signed short){-6,-6,-6,-6,-6,-6,-6,-6});
+ *s16++ = ((vector signed short){-5,-5,-5,-5,-5,-5,-5,-5});
+ *s16++ = ((vector signed short){-4,-4,-4,-4,-4,-4,-4,-4});
+ *s16++ = ((vector signed short){-3,-3,-3,-3,-3,-3,-3,-3});
+ *s16++ = ((vector signed short){-2,-2,-2,-2,-2,-2,-2,-2});
+ *s16++ = ((vector signed short){-1,-1,-1,-1,-1,-1,-1,-1});
+}
+void fs8a(vector signed char *s8)
+{
+ *s8++ = ((vector signed char){0xff,0xff,0xff,0xf0,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,0xf0});
+ *s8++ = ((vector signed char){0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xf1});
+ *s8++ = ((vector signed char){0xff,0xff,0xff,0xf2,0xff,0xff,0xff,0xf2,0xff,0xff,0xff,0xf2,0xff,0xff,0xff,0xf2});
+ *s8++ = ((vector signed char){0xff,0xff,0xff,0xf3,0xff,0xff,0xff,0xf3,0xff,0xff,0xff,0xf3,0xff,0xff,0xff,0xf3});
+ *s8++ = ((vector signed char){0xff,0xff,0xff,0xf4,0xff,0xff,0xff,0xf4,0xff,0xff,0xff,0xf4,0xff,0xff,0xff,0xf4});
+ *s8++ = ((vector signed char){0xff,0xff,0xff,0xf5,0xff,0xff,0xff,0xf5,0xff,0xff,0xff,0xf5,0xff,0xff,0xff,0xf5});
+ *s8++ = ((vector signed char){0xff,0xff,0xff,0xf6,0xff,0xff,0xff,0xf6,0xff,0xff,0xff,0xf6,0xff,0xff,0xff,0xf6});
+ *s8++ = ((vector signed char){0xff,0xff,0xff,0xf7,0xff,0xff,0xff,0xf7,0xff,0xff,0xff,0xf7,0xff,0xff,0xff,0xf7});
+ *s8++ = ((vector signed char){0xff,0xff,0xff,0xf8,0xff,0xff,0xff,0xf8,0xff,0xff,0xff,0xf8,0xff,0xff,0xff,0xf8});
+ *s8++ = ((vector signed char){0xff,0xff,0xff,0xf9,0xff,0xff,0xff,0xf9,0xff,0xff,0xff,0xf9,0xff,0xff,0xff,0xf9});
+ *s8++ = ((vector signed char){0xff,0xff,0xff,0xfa,0xff,0xff,0xff,0xfa,0xff,0xff,0xff,0xfa,0xff,0xff,0xff,0xfa});
+ *s8++ = ((vector signed char){0xff,0xff,0xff,0xfb,0xff,0xff,0xff,0xfb,0xff,0xff,0xff,0xfb,0xff,0xff,0xff,0xfb});
+ *s8++ = ((vector signed char){0xff,0xff,0xff,0xfc,0xff,0xff,0xff,0xfc,0xff,0xff,0xff,0xfc,0xff,0xff,0xff,0xfc});
+ *s8++ = ((vector signed char){0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xfd});
+ *s8++ = ((vector signed char){0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfe});
+ *s8++ = ((vector signed char){0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff});
+}
+void fs8b(vector signed char *s8)
+{
+ *s8++ = ((vector signed char){0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00});
+ *s8++ = ((vector signed char){0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01});
+ *s8++ = ((vector signed char){0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02});
+ *s8++ = ((vector signed char){0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x03});
+ *s8++ = ((vector signed char){0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04});
+ *s8++ = ((vector signed char){0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x05});
+ *s8++ = ((vector signed char){0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x06});
+ *s8++ = ((vector signed char){0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x07});
+ *s8++ = ((vector signed char){0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08});
+ *s8++ = ((vector signed char){0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x09});
+ *s8++ = ((vector signed char){0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x0a});
+ *s8++ = ((vector signed char){0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x0b});
+ *s8++ = ((vector signed char){0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x0c});
+ *s8++ = ((vector signed char){0x00,0x00,0x00,0x0d,0x00,0x00,0x00,0x0d,0x00,0x00,0x00,0x0d,0x00,0x00,0x00,0x0d});
+ *s8++ = ((vector signed char){0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x0e});
+ *s8++ = ((vector signed char){0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x0f});
+}
+void fs8c(vector signed char *s8)
+{
+ *s8++ = ((vector signed char){0xff,0xf0,0xff,0xf0,0xff,0xf0,0xff,0xf0,0xff,0xf0,0xff,0xf0,0xff,0xf0,0xff,0xf0});
+ *s8++ = ((vector signed char){0xff,0xf1,0xff,0xf1,0xff,0xf1,0xff,0xf1,0xff,0xf1,0xff,0xf1,0xff,0xf1,0xff,0xf1});
+ *s8++ = ((vector signed char){0xff,0xf2,0xff,0xf2,0xff,0xf2,0xff,0xf2,0xff,0xf2,0xff,0xf2,0xff,0xf2,0xff,0xf2});
+ *s8++ = ((vector signed char){0xff,0xf3,0xff,0xf3,0xff,0xf3,0xff,0xf3,0xff,0xf3,0xff,0xf3,0xff,0xf3,0xff,0xf3});
+ *s8++ = ((vector signed char){0xff,0xf4,0xff,0xf4,0xff,0xf4,0xff,0xf4,0xff,0xf4,0xff,0xf4,0xff,0xf4,0xff,0xf4});
+ *s8++ = ((vector signed char){0xff,0xf5,0xff,0xf5,0xff,0xf5,0xff,0xf5,0xff,0xf5,0xff,0xf5,0xff,0xf5,0xff,0xf5});
+ *s8++ = ((vector signed char){0xff,0xf6,0xff,0xf6,0xff,0xf6,0xff,0xf6,0xff,0xf6,0xff,0xf6,0xff,0xf6,0xff,0xf6});
+ *s8++ = ((vector signed char){0xff,0xf7,0xff,0xf7,0xff,0xf7,0xff,0xf7,0xff,0xf7,0xff,0xf7,0xff,0xf7,0xff,0xf7});
+ *s8++ = ((vector signed char){0xff,0xf8,0xff,0xf8,0xff,0xf8,0xff,0xf8,0xff,0xf8,0xff,0xf8,0xff,0xf8,0xff,0xf8});
+ *s8++ = ((vector signed char){0xff,0xf9,0xff,0xf9,0xff,0xf9,0xff,0xf9,0xff,0xf9,0xff,0xf9,0xff,0xf9,0xff,0xf9});
+ *s8++ = ((vector signed char){0xff,0xfa,0xff,0xfa,0xff,0xfa,0xff,0xfa,0xff,0xfa,0xff,0xfa,0xff,0xfa,0xff,0xfa});
+ *s8++ = ((vector signed char){0xff,0xfb,0xff,0xfb,0xff,0xfb,0xff,0xfb,0xff,0xfb,0xff,0xfb,0xff,0xfb,0xff,0xfb});
+ *s8++ = ((vector signed char){0xff,0xfc,0xff,0xfc,0xff,0xfc,0xff,0xfc,0xff,0xfc,0xff,0xfc,0xff,0xfc,0xff,0xfc});
+ *s8++ = ((vector signed char){0xff,0xfd,0xff,0xfd,0xff,0xfd,0xff,0xfd,0xff,0xfd,0xff,0xfd,0xff,0xfd,0xff,0xfd});
+ *s8++ = ((vector signed char){0xff,0xfe,0xff,0xfe,0xff,0xfe,0xff,0xfe,0xff,0xfe,0xff,0xfe,0xff,0xfe,0xff,0xfe});
+ *s8++ = ((vector signed char){0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff});
+}
+void fs8d(vector signed char *s8)
+{
+ *s8++ = ((vector signed char){0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00});
+ *s8++ = ((vector signed char){0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01});
+ *s8++ = ((vector signed char){0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02});
+ *s8++ = ((vector signed char){0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03});
+ *s8++ = ((vector signed char){0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04});
+ *s8++ = ((vector signed char){0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05});
+ *s8++ = ((vector signed char){0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06});
+ *s8++ = ((vector signed char){0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07});
+ *s8++ = ((vector signed char){0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08});
+ *s8++ = ((vector signed char){0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09});
+ *s8++ = ((vector signed char){0x00,0x0a,0x00,0x0a,0x00,0x0a,0x00,0x0a,0x00,0x0a,0x00,0x0a,0x00,0x0a,0x00,0x0a});
+ *s8++ = ((vector signed char){0x00,0x0b,0x00,0x0b,0x00,0x0b,0x00,0x0b,0x00,0x0b,0x00,0x0b,0x00,0x0b,0x00,0x0b});
+ *s8++ = ((vector signed char){0x00,0x0c,0x00,0x0c,0x00,0x0c,0x00,0x0c,0x00,0x0c,0x00,0x0c,0x00,0x0c,0x00,0x0c});
+ *s8++ = ((vector signed char){0x00,0x0d,0x00,0x0d,0x00,0x0d,0x00,0x0d,0x00,0x0d,0x00,0x0d,0x00,0x0d,0x00,0x0d});
+ *s8++ = ((vector signed char){0x00,0x0e,0x00,0x0e,0x00,0x0e,0x00,0x0e,0x00,0x0e,0x00,0x0e,0x00,0x0e,0x00,0x0e});
+ *s8++ = ((vector signed char){0x00,0x0f,0x00,0x0f,0x00,0x0f,0x00,0x0f,0x00,0x0f,0x00,0x0f,0x00,0x0f,0x00,0x0f});
+}
+void fs8e(vector signed char *s8)
+{
+ *s8++ = ((vector signed char){0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00});
+ *s8++ = ((vector signed char){0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01});
+ *s8++ = ((vector signed char){0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02});
+ *s8++ = ((vector signed char){0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03});
+ *s8++ = ((vector signed char){0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04});
+ *s8++ = ((vector signed char){0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05});
+ *s8++ = ((vector signed char){0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06});
+ *s8++ = ((vector signed char){0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07});
+ *s8++ = ((vector signed char){0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08});
+ *s8++ = ((vector signed char){0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09});
+ *s8++ = ((vector signed char){0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a});
+ *s8++ = ((vector signed char){0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b});
+ *s8++ = ((vector signed char){0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c});
+ *s8++ = ((vector signed char){0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d});
+ *s8++ = ((vector signed char){0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e});
+ *s8++ = ((vector signed char){0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f});
+}
+void fs8f(vector signed char *s8)
+{
+ *s8++ = ((vector signed char){0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0});
+ *s8++ = ((vector signed char){0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1,0xf1});
+ *s8++ = ((vector signed char){0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2});
+ *s8++ = ((vector signed char){0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3,0xf3});
+ *s8++ = ((vector signed char){0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4});
+ *s8++ = ((vector signed char){0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5});
+ *s8++ = ((vector signed char){0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6});
+ *s8++ = ((vector signed char){0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7});
+ *s8++ = ((vector signed char){0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8});
+ *s8++ = ((vector signed char){0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9});
+ *s8++ = ((vector signed char){0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa});
+ *s8++ = ((vector signed char){0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb});
+ *s8++ = ((vector signed char){0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc});
+ *s8++ = ((vector signed char){0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd});
+ *s8++ = ((vector signed char){0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe});
+ *s8++ = ((vector signed char){0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff});
+}
+void fs8g(vector signed char *s8)
+{
+ *s8++ = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0});
+ *s8++ = ((vector signed char){1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1});
+ *s8++ = ((vector signed char){2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2});
+ *s8++ = ((vector signed char){3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3});
+ *s8++ = ((vector signed char){4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4});
+ *s8++ = ((vector signed char){5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5});
+ *s8++ = ((vector signed char){6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6});
+ *s8++ = ((vector signed char){7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7});
+ *s8++ = ((vector signed char){8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8});
+ *s8++ = ((vector signed char){9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9});
+ *s8++ = ((vector signed char){10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10});
+ *s8++ = ((vector signed char){11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11});
+ *s8++ = ((vector signed char){12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12});
+ *s8++ = ((vector signed char){13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13});
+ *s8++ = ((vector signed char){14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14});
+ *s8++ = ((vector signed char){15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15});
+}
+void fs8h(vector signed char *s8)
+{
+ *s8++ = ((vector signed char){240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240});
+ *s8++ = ((vector signed char){241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241});
+ *s8++ = ((vector signed char){242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242});
+ *s8++ = ((vector signed char){243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243});
+ *s8++ = ((vector signed char){244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244});
+ *s8++ = ((vector signed char){245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245});
+ *s8++ = ((vector signed char){246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246});
+ *s8++ = ((vector signed char){247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247});
+ *s8++ = ((vector signed char){248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248});
+ *s8++ = ((vector signed char){249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249});
+ *s8++ = ((vector signed char){250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250});
+ *s8++ = ((vector signed char){251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251});
+ *s8++ = ((vector signed char){252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252});
+ *s8++ = ((vector signed char){253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253});
+ *s8++ = ((vector signed char){254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254});
+ *s8++ = ((vector signed char){255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255});
+}
+void fs8i(vector signed char *s8)
+{
+ *s8++ = ((vector signed char){-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1});
+ *s8++ = ((vector signed char){-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2});
+ *s8++ = ((vector signed char){-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3});
+ *s8++ = ((vector signed char){-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4});
+ *s8++ = ((vector signed char){-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5});
+ *s8++ = ((vector signed char){-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6});
+ *s8++ = ((vector signed char){-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7});
+ *s8++ = ((vector signed char){-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8,-8});
+ *s8++ = ((vector signed char){-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9});
+ *s8++ = ((vector signed char){-10,-10,-10,-10,-10,-10,-10,-10,-10,-10,-10,-10,-10,-10,-10,-10});
+ *s8++ = ((vector signed char){-11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11});
+ *s8++ = ((vector signed char){-12,-12,-12,-12,-12,-12,-12,-12,-12,-12,-12,-12,-12,-12,-12,-12});
+ *s8++ = ((vector signed char){-13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13});
+ *s8++ = ((vector signed char){-14,-14,-14,-14,-14,-14,-14,-14,-14,-14,-14,-14,-14,-14,-14,-14});
+ *s8++ = ((vector signed char){-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15});
+ *s8++ = ((vector signed char){-16,-16,-16,-16,-16,-16,-16,-16,-16,-16,-16,-16,-16,-16,-16,-16});
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/5-11.c b/gcc/testsuite/gcc.dg/vmx/5-11.c
new file mode 100644
index 00000000000..7d9b3975f5b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/5-11.c
@@ -0,0 +1,289 @@
+/* { dg-do compile } */
+#include <altivec.h>
+extern void fu32(vector unsigned int, vector unsigned int,
+ vector unsigned int, vector unsigned int);
+void fxu32(vector unsigned int u32a, vector unsigned int u32b,
+ vector unsigned int u32c, vector unsigned int u32d)
+{
+ fu32 (u32a,
+ u32b,
+ u32c,
+ vec_avg(u32d, u32d));
+ fu32 (vec_or (u32a, u32a),
+ vec_and (u32b, u32b),
+ vec_max (u32c, u32c),
+ vec_min (u32d, u32d));
+ fu32 (vec_sld (u32a, u32a, 0),
+ vec_sld (u32b, u32b, 0),
+ vec_sld (u32c, u32c, 0),
+ vec_sld (u32d, u32d, 0));
+ fu32 (((vector unsigned int){0,0,0,0}),
+ ((vector unsigned int){0,0,0,0}),
+ ((vector unsigned int){0,0,0,0}),
+ ((vector unsigned int){0,0,0,0}));
+ fu32 (vec_xor(u32a, u32a),
+ vec_andc(u32b, u32b),
+ vec_sub(u32c, u32c),
+ vec_subs(u32d, u32d));
+ fu32 (vec_splat_u32(0),
+ vec_splat_u32(0),
+ vec_splat_u32(0),
+ vec_splat_u32(0));
+ fu32 (((vector unsigned int){0xffffffff,0xffffffff,0xffffffff,0xffffffff}),
+ ((vector unsigned int){0xffffffff,0xffffffff,0xffffffff,0xffffffff}),
+ ((vector unsigned int){0xffffffff,0xffffffff,0xffffffff,0xffffffff}),
+ ((vector unsigned int){0xffffffff,0xffffffff,0xffffffff,0xffffffff}));
+ fu32 (vec_splat_u32(-1),
+ vec_splat_u32(-1),
+ vec_splat_u32(-1),
+ vec_splat_u32(-1));
+ fu32 ((vector unsigned int)vec_cmpeq(u32a, u32a),
+ (vector unsigned int)vec_cmpeq(u32b, u32b),
+ (vector unsigned int)vec_cmpeq(u32c, u32c),
+ (vector unsigned int)vec_cmpeq(u32d, u32d));
+}
+
+extern void fu16(vector unsigned short, vector unsigned short,
+ vector unsigned short, vector unsigned short);
+void fxu16(vector unsigned short u16a, vector unsigned short u16b,
+ vector unsigned short u16c, vector unsigned short u16d)
+{
+ fu16 (u16a,
+ u16b,
+ u16c,
+ vec_avg(u16d, u16d));
+ fu16 (vec_or (u16a, u16a),
+ vec_and (u16b, u16b),
+ vec_max (u16c, u16c),
+ vec_min (u16d, u16d));
+ fu16 (vec_sld (u16a, u16a, 0),
+ vec_sld (u16b, u16b, 0),
+ vec_sld (u16c, u16c, 0),
+ vec_sld (u16d, u16d, 0));
+ fu16 (((vector unsigned short){0,0,0,0,0,0,0,0}),
+ ((vector unsigned short){0,0,0,0,0,0,0,0}),
+ ((vector unsigned short){0,0,0,0,0,0,0,0}),
+ ((vector unsigned short){0,0,0,0,0,0,0,0}));
+ fu16 (vec_xor(u16a, u16a),
+ vec_andc(u16b, u16b),
+ vec_sub(u16c, u16c),
+ vec_subs(u16d, u16d));
+ fu16 (vec_splat_u16(0),
+ vec_splat_u16(0),
+ vec_splat_u16(0),
+ vec_splat_u16(0));
+ fu16 (((vector unsigned short){0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff}),
+ ((vector unsigned short){0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff}),
+ ((vector unsigned short){0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff}),
+ ((vector unsigned short){0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff}));
+ fu16 (vec_splat_u16(-1),
+ vec_splat_u16(-1),
+ vec_splat_u16(-1),
+ vec_splat_u16(-1));
+ fu16 ((vector unsigned short)vec_cmpeq(u16a, u16a),
+ (vector unsigned short)vec_cmpeq(u16b, u16b),
+ (vector unsigned short)vec_cmpeq(u16c, u16c),
+ (vector unsigned short)vec_cmpeq(u16d, u16d));
+}
+
+extern void fu8(vector unsigned char, vector unsigned char,
+ vector unsigned char, vector unsigned char);
+void fxu8(vector unsigned char u8a, vector unsigned char u8b,
+ vector unsigned char u8c, vector unsigned char u8d)
+{
+ fu8 (u8a,
+ u8b,
+ u8c,
+ vec_avg(u8d, u8d));
+ fu8 (vec_or (u8a, u8a),
+ vec_and (u8b, u8b),
+ vec_max (u8c, u8c),
+ vec_min (u8d, u8d));
+ fu8 (vec_sld (u8a, u8a, 0),
+ vec_sld (u8b, u8b, 0),
+ vec_sld (u8c, u8c, 0),
+ vec_sld (u8d, u8d, 0));
+ fu8 (((vector unsigned char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}),
+ ((vector unsigned char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}),
+ ((vector unsigned char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}),
+ ((vector unsigned char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}));
+ fu8 (vec_xor(u8a, u8a),
+ vec_andc(u8b, u8b),
+ vec_sub(u8c, u8c),
+ vec_subs(u8d, u8d));
+ fu8 (vec_splat_u8(0),
+ vec_splat_u8(0),
+ vec_splat_u8(0),
+ vec_splat_u8(0));
+ fu8 (((vector unsigned char){0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}),
+ ((vector unsigned char){0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}),
+ ((vector unsigned char){0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}),
+ ((vector unsigned char){0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}));
+ fu8 (vec_splat_u8(-1),
+ vec_splat_u8(-1),
+ vec_splat_u8(-1),
+ vec_splat_u8(-1));
+ fu8 ((vector unsigned char)vec_cmpeq(u8a, u8a),
+ (vector unsigned char)vec_cmpeq(u8b, u8b),
+ (vector unsigned char)vec_cmpeq(u8c, u8c),
+ (vector unsigned char)vec_cmpeq(u8d, u8d));
+}
+
+extern void fs32(vector signed int, vector signed int,
+ vector signed int, vector signed int);
+void fxs32(vector signed int s32a, vector signed int s32b,
+ vector signed int s32c, vector signed int s32d)
+{
+ fs32 (s32a,
+ s32b,
+ s32c,
+ vec_avg(s32d, s32d));
+ fs32 (vec_or (s32a, s32a),
+ vec_and (s32b, s32b),
+ vec_max (s32c, s32c),
+ vec_min (s32d, s32d));
+ fs32 (vec_sld (s32a, s32a, 0),
+ vec_sld (s32b, s32b, 0),
+ vec_sld (s32c, s32c, 0),
+ vec_sld (s32d, s32d, 0));
+ fs32 (((vector signed int){0,0,0,0}),
+ ((vector signed int){0,0,0,0}),
+ ((vector signed int){0,0,0,0}),
+ ((vector signed int){0,0,0,0}));
+ fs32 (vec_xor(s32a, s32a),
+ vec_andc(s32b, s32b),
+ vec_sub(s32c, s32c),
+ vec_subs(s32d, s32d));
+ fs32 (vec_splat_s32(0),
+ vec_splat_s32(0),
+ vec_splat_s32(0),
+ vec_splat_s32(0));
+ fs32 (((vector signed int){-1,-1,-1,-1}),
+ ((vector signed int){-1,-1,-1,-1}),
+ ((vector signed int){-1,-1,-1,-1}),
+ ((vector signed int){-1,-1,-1,-1}));
+ fs32 (vec_splat_s32(-1),
+ vec_splat_s32(-1),
+ vec_splat_s32(-1),
+ vec_splat_s32(-1));
+ fs32 ((vector signed int)vec_cmpeq(s32a, s32a),
+ (vector signed int)vec_cmpeq(s32b, s32b),
+ (vector signed int)vec_cmpeq(s32c, s32c),
+ (vector signed int)vec_cmpeq(s32d, s32d));
+}
+
+extern void fs16(vector signed short, vector signed short,
+ vector signed short, vector signed short);
+void fxs16(vector signed short s16a, vector signed short s16b,
+ vector signed short s16c, vector signed short s16d)
+{
+ fs16 (s16a,
+ s16b,
+ s16c,
+ vec_avg(s16d, s16d));
+ fs16 (vec_or (s16a, s16a),
+ vec_and (s16b, s16b),
+ vec_max (s16c, s16c),
+ vec_min (s16d, s16d));
+ fs16 (vec_sld (s16a, s16a, 0),
+ vec_sld (s16b, s16b, 0),
+ vec_sld (s16c, s16c, 0),
+ vec_sld (s16d, s16d, 0));
+ fs16 (((vector signed short){0,0,0,0,0,0,0,0}),
+ ((vector signed short){0,0,0,0,0,0,0,0}),
+ ((vector signed short){0,0,0,0,0,0,0,0}),
+ ((vector signed short){0,0,0,0,0,0,0,0}));
+ fs16 (vec_xor(s16a, s16a),
+ vec_andc(s16b, s16b),
+ vec_sub(s16c, s16c),
+ vec_subs(s16d, s16d));
+ fs16 (vec_splat_s16(0),
+ vec_splat_s16(0),
+ vec_splat_s16(0),
+ vec_splat_s16(0));
+ fs16 (((vector signed short){-1,-1,-1,-1,-1,-1,-1,-1}),
+ ((vector signed short){-1,-1,-1,-1,-1,-1,-1,-1}),
+ ((vector signed short){-1,-1,-1,-1,-1,-1,-1,-1}),
+ ((vector signed short){-1,-1,-1,-1,-1,-1,-1,-1}));
+ fs16 (vec_splat_s16(-1),
+ vec_splat_s16(-1),
+ vec_splat_s16(-1),
+ vec_splat_s16(-1));
+ fs16 ((vector signed short)vec_cmpeq(s16a, s16a),
+ (vector signed short)vec_cmpeq(s16b, s16b),
+ (vector signed short)vec_cmpeq(s16c, s16c),
+ (vector signed short)vec_cmpeq(s16d, s16d));
+}
+
+extern void fs8(vector signed char, vector signed char,
+ vector signed char, vector signed char);
+void fxs8(vector signed char s8a, vector signed char s8b,
+ vector signed char s8c, vector signed char s8d)
+{
+ fs8 (s8a,
+ s8b,
+ s8c,
+ vec_avg(s8d, s8d));
+ fs8 (vec_or (s8a, s8a),
+ vec_and (s8b, s8b),
+ vec_max (s8c, s8c),
+ vec_min (s8d, s8d));
+ fs8 (vec_sld (s8a, s8a, 0),
+ vec_sld (s8b, s8b, 0),
+ vec_sld (s8c, s8c, 0),
+ vec_sld (s8d, s8d, 0));
+ fs8 (((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}),
+ ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}),
+ ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}),
+ ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}));
+ fs8 (vec_xor(s8a, s8a),
+ vec_andc(s8b, s8b),
+ vec_sub(s8c, s8c),
+ vec_subs(s8d, s8d));
+ fs8 (vec_splat_s8(0),
+ vec_splat_s8(0),
+ vec_splat_s8(0),
+ vec_splat_s8(0));
+ fs8 (((vector signed char){-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}),
+ ((vector signed char){-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}),
+ ((vector signed char){-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}),
+ ((vector signed char){-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}));
+ fs8 (vec_splat_s8(-1),
+ vec_splat_s8(-1),
+ vec_splat_s8(-1),
+ vec_splat_s8(-1));
+ fs8 ((vector signed char)vec_cmpeq(s8a, s8a),
+ (vector signed char)vec_cmpeq(s8b, s8b),
+ (vector signed char)vec_cmpeq(s8c, s8c),
+ (vector signed char)vec_cmpeq(s8d, s8d));
+}
+
+void fu32(vector unsigned int a, vector unsigned int b,
+ vector unsigned int c, vector unsigned int d)
+{
+}
+
+void fu16(vector unsigned short a, vector unsigned short b,
+ vector unsigned short c, vector unsigned short d)
+{
+}
+
+void fu8(vector unsigned char a, vector unsigned char b,
+ vector unsigned char c, vector unsigned char d)
+{
+}
+
+void fs32(vector signed int a, vector signed int b,
+ vector signed int c, vector signed int d)
+{
+}
+
+void fs16(vector signed short a, vector signed short b,
+ vector signed short c, vector signed short d)
+{
+}
+
+void fs8(vector signed char a, vector signed char b,
+ vector signed char c, vector signed char d)
+{
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/7-01.c b/gcc/testsuite/gcc.dg/vmx/7-01.c
new file mode 100644
index 00000000000..f986d8fe5b0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/7-01.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+#include <altivec.h>
+extern vector signed short image[];
+extern vector signed short band[];
+
+#define load(a,b) (a[b])
+#define store(v,a,b) (a[b]) = (v)
+
+void
+haar (vector signed char a, vector signed char b, vector signed char c,
+ vector signed char d, unsigned int N, int XX)
+{
+ unsigned int i;
+ vector unsigned char high, low;
+ vector signed int zero = ((vector signed int){0,0,0,0});
+
+ for (i = 0; i < N; i++) {
+ high = (vector unsigned char) (vec_vmrghh (load(image, i+XX),
+ load(image, i)));
+ low = (vector unsigned char) (vec_vmrglh (load(image, i+XX),
+ load(image, i)));
+
+ store (vec_vpkswss (vec_vmsummbm (a, high, zero),
+ vec_vmsummbm (a, low, zero)),
+ band, i);
+ store (vec_vpkswss (vec_vmsummbm (b, high, zero),
+ vec_vmsummbm (b, low, zero)),
+ band, i+1);
+ store(vec_vpkswss (vec_vmsummbm (c, high, zero),
+ vec_vmsummbm (c, low, zero)),
+ band, i+2);
+ store(vec_vpkswss (vec_vmsummbm (d, high, zero),
+ vec_vmsummbm (d, low, zero)),
+ band, i+3);
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/7-01a.c b/gcc/testsuite/gcc.dg/vmx/7-01a.c
new file mode 100644
index 00000000000..c09835b437e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/7-01a.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+#include <altivec.h>
+extern vector signed short image[];
+extern vector signed short band[];
+
+#define load(a,b) vec_ld((b)*16, a)
+#define store(v,a,b) vec_st(v,(b)*16,a)
+
+void
+haar (vector signed char a, vector signed char b, vector signed char c,
+ vector signed char d, unsigned int N, int XX)
+{
+ unsigned int i;
+ vector unsigned char high, low;
+ vector signed int zero = ((vector signed int){0,0,0,0});
+
+ for (i = 0; i < N; i++) {
+ high = (vector unsigned char) (vec_vmrghh (load(image, i+XX),
+ load(image, i)));
+ low = (vector unsigned char) (vec_vmrglh (load(image, i+XX),
+ load(image, i)));
+
+ store (vec_vpkswss (vec_vmsummbm (a, high, zero),
+ vec_vmsummbm (a, low, zero)),
+ band, i);
+ store (vec_vpkswss (vec_vmsummbm (b, high, zero),
+ vec_vmsummbm (b, low, zero)),
+ band, i+1);
+ store(vec_vpkswss (vec_vmsummbm (c, high, zero),
+ vec_vmsummbm (c, low, zero)),
+ band, i+2);
+ store(vec_vpkswss (vec_vmsummbm (d, high, zero),
+ vec_vmsummbm (d, low, zero)),
+ band, i+3);
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/7c-01.c b/gcc/testsuite/gcc.dg/vmx/7c-01.c
new file mode 100644
index 00000000000..68e07aa305b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/7c-01.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+#include <altivec.h>
+vector float
+f(int i)
+{
+ switch (i) {
+ case 0:
+ return (vector float)(((vector unsigned char){3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3}));
+ }
+ return ((vector float){0,0,0,0});
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/7d-01.c b/gcc/testsuite/gcc.dg/vmx/7d-01.c
new file mode 100644
index 00000000000..dac5151add1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/7d-01.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+#include <altivec.h>
+extern vector unsigned char a[];
+
+vector unsigned char
+f(vector unsigned char *p, int i, int b)
+{
+ if (b)
+ return p[i];
+ return vec_ld(i*16,p);
+}
+
+vector unsigned char
+g(int i, int b)
+{
+ if (b)
+ return a[i];
+ return vec_ld(i*16,a);
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/7d-02.c b/gcc/testsuite/gcc.dg/vmx/7d-02.c
new file mode 100644
index 00000000000..6294cc99efc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/7d-02.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+#include <altivec.h>
+extern vector unsigned char a[];
+
+void f
+(vector unsigned char v, vector unsigned char *p, int i, int b)
+{
+ if (b)
+ p[i] = v;
+ else
+ vec_st(v, i*16,p);
+}
+
+void g
+(vector unsigned char v, int i, int b)
+{
+ if (b)
+ a[i] = v;
+ else
+ vec_st(v,i*16,a);
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/8-01.c b/gcc/testsuite/gcc.dg/vmx/8-01.c
new file mode 100644
index 00000000000..d65815e3a6d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/8-01.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+#include <altivec.h>
+
+int i = vec_step(vector unsigned short);
diff --git a/gcc/testsuite/gcc.dg/vmx/8-02.c b/gcc/testsuite/gcc.dg/vmx/8-02.c
new file mode 100644
index 00000000000..72a4a907ad3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/8-02.c
@@ -0,0 +1,299 @@
+#include "harness.h"
+
+extern vector unsigned char u8;
+extern vector signed char s8;
+extern vector bool char b8;
+extern vector unsigned short u16;
+extern vector signed short s16;
+extern vector bool short b16;
+extern vector unsigned int u32;
+extern vector signed int s32;
+extern vector bool int b32;
+extern vector float f32;
+extern vector pixel p16;
+extern vector unsigned char const u8c;
+extern vector signed char const s8c;
+extern vector bool char const b8c;
+extern vector unsigned short const u16c;
+extern vector signed short const s16c;
+extern vector bool short const b16c;
+extern vector unsigned int const u32c;
+extern vector signed int const s32c;
+extern vector bool int const b32c;
+extern vector float const f32c;
+extern vector pixel const p16c;
+extern vector unsigned char volatile u8v;
+extern vector signed char volatile s8v;
+extern vector bool char volatile b8v;
+extern vector unsigned short volatile u16v;
+extern vector signed short volatile s16v;
+extern vector bool short volatile b16v;
+extern vector unsigned int volatile u32v;
+extern vector signed int volatile s32v;
+extern vector bool int volatile b32v;
+extern vector float volatile f32v;
+extern vector pixel volatile p16v;
+extern const vector unsigned char u8c_;
+extern const vector signed char s8c_;
+extern const vector bool char b8c_;
+extern const vector unsigned short u16c_;
+extern const vector signed short s16c_;
+extern const vector bool short b16c_;
+extern const vector unsigned int u32c_;
+extern const vector signed int s32c_;
+extern const vector bool int b32c_;
+extern const vector float f32c_;
+extern const vector pixel p16c_;
+extern volatile vector unsigned char u8v_;
+extern volatile vector signed char s8v_;
+extern volatile vector bool char b8v_;
+extern volatile vector unsigned short u16v_;
+extern volatile vector signed short s16v_;
+extern volatile vector bool short b16v_;
+extern volatile vector unsigned int u32v_;
+extern volatile vector signed int s32v_;
+extern volatile vector bool int b32v_;
+extern volatile vector float f32v_;
+extern volatile vector pixel p16v_;
+int i_u8 = vec_step(u8);
+int i_s8 = vec_step(s8);
+int i_b8 = vec_step(b8);
+int i_u16 = vec_step(u16);
+int i_s16 = vec_step(s16);
+int i_b16 = vec_step(b16);
+int i_u32 = vec_step(u32);
+int i_s32 = vec_step(s32);
+int i_b32 = vec_step(b32);
+int i_f32 = vec_step(f32);
+int i_p16 = vec_step(p16);
+int i_u8c = vec_step(u8c);
+int i_s8c = vec_step(s8c);
+int i_b8c = vec_step(b8c);
+int i_u16c = vec_step(u16c);
+int i_s16c = vec_step(s16c);
+int i_b16c = vec_step(b16c);
+int i_u32c = vec_step(u32c);
+int i_s32c = vec_step(s32c);
+int i_b32c = vec_step(b32c);
+int i_f32c = vec_step(f32c);
+int i_p16c = vec_step(p16c);
+int i_u8v = vec_step(u8v);
+int i_s8v = vec_step(s8v);
+int i_b8v = vec_step(b8v);
+int i_u16v = vec_step(u16v);
+int i_s16v = vec_step(s16v);
+int i_b16v = vec_step(b16v);
+int i_u32v = vec_step(u32v);
+int i_s32v = vec_step(s32v);
+int i_b32v = vec_step(b32v);
+int i_f32v = vec_step(f32v);
+int i_p16v = vec_step(p16v);
+int i_u8c_ = vec_step(u8c_);
+int i_s8c_ = vec_step(s8c_);
+int i_b8c_ = vec_step(b8c_);
+int i_u16c_ = vec_step(u16c_);
+int i_s16c_ = vec_step(s16c_);
+int i_b16c_ = vec_step(b16c_);
+int i_u32c_ = vec_step(u32c_);
+int i_s32c_ = vec_step(s32c_);
+int i_b32c_ = vec_step(b32c_);
+int i_f32c_ = vec_step(f32c_);
+int i_p16c_ = vec_step(p16c_);
+int i_u8v_ = vec_step(u8v_);
+int i_s8v_ = vec_step(s8v_);
+int i_b8v_ = vec_step(b8v_);
+int i_u16v_ = vec_step(u16v_);
+int i_s16v_ = vec_step(s16v_);
+int i_b16v_ = vec_step(b16v_);
+int i_u32v_ = vec_step(u32v_);
+int i_s32v_ = vec_step(s32v_);
+int i_b32v_ = vec_step(b32v_);
+int i_f32v_ = vec_step(f32v_);
+int i_p16v_ = vec_step(p16v_);
+int j_u8 = vec_step(vector unsigned char);
+int j_s8 = vec_step(vector signed char);
+int j_b8 = vec_step(vector bool char);
+int j_u16 = vec_step(vector unsigned short);
+int j_s16 = vec_step(vector signed short);
+int j_b16 = vec_step(vector bool short);
+int j_u32 = vec_step(vector unsigned int);
+int j_s32 = vec_step(vector signed int);
+int j_b32 = vec_step(vector bool int);
+int j_f32 = vec_step(vector float);
+int j_p16 = vec_step(vector pixel);
+int j_u8c = vec_step(vector unsigned char const);
+int j_s8c = vec_step(vector signed char const);
+int j_b8c = vec_step(vector bool char const);
+int j_u16c = vec_step(vector unsigned short const);
+int j_s16c = vec_step(vector signed short const);
+int j_b16c = vec_step(vector bool short const);
+int j_u32c = vec_step(vector unsigned int const);
+int j_s32c = vec_step(vector signed int const);
+int j_b32c = vec_step(vector bool int const);
+int j_f32c = vec_step(vector float const);
+int j_p16c = vec_step(vector pixel const);
+int j_u8v = vec_step(vector unsigned char volatile);
+int j_s8v = vec_step(vector signed char volatile);
+int j_b8v = vec_step(vector bool char volatile);
+int j_u16v = vec_step(vector unsigned short volatile);
+int j_s16v = vec_step(vector signed short volatile);
+int j_b16v = vec_step(vector bool short volatile);
+int j_u32v = vec_step(vector unsigned int volatile);
+int j_s32v = vec_step(vector signed int volatile);
+int j_b32v = vec_step(vector bool int volatile);
+int j_f32v = vec_step(vector float volatile);
+int j_p16v = vec_step(vector pixel volatile);
+int j_u8c_ = vec_step(const vector unsigned char);
+int j_s8c_ = vec_step(const vector signed char);
+int j_b8c_ = vec_step(const vector bool char);
+int j_u16c_ = vec_step(const vector unsigned short);
+int j_s16c_ = vec_step(const vector signed short);
+int j_b16c_ = vec_step(const vector bool short);
+int j_u32c_ = vec_step(const vector unsigned int);
+int j_s32c_ = vec_step(const vector signed int);
+int j_b32c_ = vec_step(const vector bool int);
+int j_f32c_ = vec_step(const vector float);
+int j_p16c_ = vec_step(const vector pixel);
+int j_u8v_ = vec_step(volatile vector unsigned char);
+int j_s8v_ = vec_step(volatile vector signed char);
+int j_b8v_ = vec_step(volatile vector bool char);
+int j_u16v_ = vec_step(volatile vector unsigned short);
+int j_s16v_ = vec_step(volatile vector signed short);
+int j_b16v_ = vec_step(volatile vector bool short);
+int j_u32v_ = vec_step(volatile vector unsigned int);
+int j_s32v_ = vec_step(volatile vector signed int);
+int j_b32v_ = vec_step(volatile vector bool int);
+int j_f32v_ = vec_step(volatile vector float);
+int j_p16v_ = vec_step(volatile vector pixel);
+
+static void test()
+{
+ int i_u8 = vec_step(u8);
+ int i_s8 = vec_step(s8);
+ int i_b8 = vec_step(b8);
+ int i_u16 = vec_step(u16);
+ int i_s16 = vec_step(s16);
+ int i_b16 = vec_step(b16);
+ int i_u32 = vec_step(u32);
+ int i_s32 = vec_step(s32);
+ int i_b32 = vec_step(b32);
+ int i_f32 = vec_step(f32);
+ int i_p16 = vec_step(p16);
+ int i_u8c = vec_step(u8c);
+ int i_s8c = vec_step(s8c);
+ int i_b8c = vec_step(b8c);
+ int i_u16c = vec_step(u16c);
+ int i_s16c = vec_step(s16c);
+ int i_b16c = vec_step(b16c);
+ int i_u32c = vec_step(u32c);
+ int i_s32c = vec_step(s32c);
+ int i_b32c = vec_step(b32c);
+ int i_f32c = vec_step(f32c);
+ int i_p16c = vec_step(p16c);
+ int i_u8v = vec_step(u8v);
+ int i_s8v = vec_step(s8v);
+ int i_b8v = vec_step(b8v);
+ int i_u16v = vec_step(u16v);
+ int i_s16v = vec_step(s16v);
+ int i_b16v = vec_step(b16v);
+ int i_u32v = vec_step(u32v);
+ int i_s32v = vec_step(s32v);
+ int i_b32v = vec_step(b32v);
+ int i_f32v = vec_step(f32v);
+ int i_p16v = vec_step(p16v);
+ int i_u8c_ = vec_step(u8c_);
+ int i_s8c_ = vec_step(s8c_);
+ int i_b8c_ = vec_step(b8c_);
+ int i_u16c_ = vec_step(u16c_);
+ int i_s16c_ = vec_step(s16c_);
+ int i_b16c_ = vec_step(b16c_);
+ int i_u32c_ = vec_step(u32c_);
+ int i_s32c_ = vec_step(s32c_);
+ int i_b32c_ = vec_step(b32c_);
+ int i_f32c_ = vec_step(f32c_);
+ int i_p16c_ = vec_step(p16c_);
+ int i_u8v_ = vec_step(u8v_);
+ int i_s8v_ = vec_step(s8v_);
+ int i_b8v_ = vec_step(b8v_);
+ int i_u16v_ = vec_step(u16v_);
+ int i_s16v_ = vec_step(s16v_);
+ int i_b16v_ = vec_step(b16v_);
+ int i_u32v_ = vec_step(u32v_);
+ int i_s32v_ = vec_step(s32v_);
+ int i_b32v_ = vec_step(b32v_);
+ int i_f32v_ = vec_step(f32v_);
+ int i_p16v_ = vec_step(p16v_);
+ int j_u8 = vec_step(vector unsigned char);
+ int j_s8 = vec_step(vector signed char);
+ int j_b8 = vec_step(vector bool char);
+ int j_u16 = vec_step(vector unsigned short);
+ int j_s16 = vec_step(vector signed short);
+ int j_b16 = vec_step(vector bool short);
+ int j_u32 = vec_step(vector unsigned int);
+ int j_s32 = vec_step(vector signed int);
+ int j_b32 = vec_step(vector bool int);
+ int j_f32 = vec_step(vector float);
+ int j_p16 = vec_step(vector pixel);
+ int j_u8c = vec_step(vector unsigned char const);
+ int j_s8c = vec_step(vector signed char const);
+ int j_b8c = vec_step(vector bool char const);
+ int j_u16c = vec_step(vector unsigned short const);
+ int j_s16c = vec_step(vector signed short const);
+ int j_b16c = vec_step(vector bool short const);
+ int j_u32c = vec_step(vector unsigned int const);
+ int j_s32c = vec_step(vector signed int const);
+ int j_b32c = vec_step(vector bool int const);
+ int j_f32c = vec_step(vector float const);
+ int j_p16c = vec_step(vector pixel const);
+ int j_u8v = vec_step(vector unsigned char volatile);
+ int j_s8v = vec_step(vector signed char volatile);
+ int j_b8v = vec_step(vector bool char volatile);
+ int j_u16v = vec_step(vector unsigned short volatile);
+ int j_s16v = vec_step(vector signed short volatile);
+ int j_b16v = vec_step(vector bool short volatile);
+ int j_u32v = vec_step(vector unsigned int volatile);
+ int j_s32v = vec_step(vector signed int volatile);
+ int j_b32v = vec_step(vector bool int volatile);
+ int j_f32v = vec_step(vector float volatile);
+ int j_p16v = vec_step(vector pixel volatile);
+ int j_u8c_ = vec_step(const vector unsigned char);
+ int j_s8c_ = vec_step(const vector signed char);
+ int j_b8c_ = vec_step(const vector bool char);
+ int j_u16c_ = vec_step(const vector unsigned short);
+ int j_s16c_ = vec_step(const vector signed short);
+ int j_b16c_ = vec_step(const vector bool short);
+ int j_u32c_ = vec_step(const vector unsigned int);
+ int j_s32c_ = vec_step(const vector signed int);
+ int j_b32c_ = vec_step(const vector bool int);
+ int j_f32c_ = vec_step(const vector float);
+ int j_p16c_ = vec_step(const vector pixel);
+ int j_u8v_ = vec_step(volatile vector unsigned char);
+ int j_s8v_ = vec_step(volatile vector signed char);
+ int j_b8v_ = vec_step(volatile vector bool char);
+ int j_u16v_ = vec_step(volatile vector unsigned short);
+ int j_s16v_ = vec_step(volatile vector signed short);
+ int j_b16v_ = vec_step(volatile vector bool short);
+ int j_u32v_ = vec_step(volatile vector unsigned int);
+ int j_s32v_ = vec_step(volatile vector signed int);
+ int j_b32v_ = vec_step(volatile vector bool int);
+ int j_f32v_ = vec_step(volatile vector float);
+ int j_p16v_ = vec_step(volatile vector pixel);
+ check((i_u8 + i_s8 + i_b8 + i_u16 + i_s16 + i_b16 + i_u32 + i_s32 +
+ i_b32 + i_f32 + i_p16 + i_u8c + i_s8c + i_b8c + i_u16c +
+ i_s16c + i_b16c + i_u32c + i_s32c + i_b32c + i_f32c + i_p16c
+ + i_u8v + i_s8v + i_b8v + i_u16v + i_s16v + i_b16v + i_u32v
+ + i_s32v + i_b32v + i_f32v + i_p16v + i_u8c_ + i_s8c_ +
+ i_b8c_ + i_u16c_ + i_s16c_ + i_b16c_ + i_u32c_ + i_s32c_ +
+ i_b32c_ + i_f32c_ + i_p16c_ + i_u8v_ + i_s8v_ + i_b8v_ +
+ i_u16v_ + i_s16v_ + i_b16v_ + i_u32v_ + i_s32v_ + i_b32v_ +
+ i_f32v_ + i_p16v_ + j_u8 + j_s8 + j_b8 + j_u16 + j_s16 +
+ j_b16 + j_u32 + j_s32 + j_b32 + j_f32 + j_p16 + j_u8c +
+ j_s8c + j_b8c + j_u16c + j_s16c + j_b16c + j_u32c + j_s32c +
+ j_b32c + j_f32c + j_p16c + j_u8v + j_s8v + j_b8v + j_u16v +
+ j_s16v + j_b16v + j_u32v + j_s32v + j_b32v + j_f32v + j_p16v
+ + j_u8c_ + j_s8c_ + j_b8c_ + j_u16c_ + j_s16c_ + j_b16c_ +
+ j_u32c_ + j_s32c_ + j_b32c_ + j_f32c_ + j_p16c_ + j_u8v_ +
+ j_s8v_ + j_b8v_ + j_u16v_ + j_s16v_ + j_b16v_ + j_u32v_ +
+ j_s32v_ + j_b32v_ + j_f32v_ + j_p16v_) == 960,
+ "vec_step");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/8-02a.c b/gcc/testsuite/gcc.dg/vmx/8-02a.c
new file mode 100644
index 00000000000..34f73878051
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/8-02a.c
@@ -0,0 +1,17 @@
+#include "harness.h"
+
+extern vector pixel p16;
+extern vector pixel const p16c;
+extern vector pixel volatile p16v;
+extern const vector pixel p16c_;
+extern volatile vector pixel p16v_;
+
+static void test()
+{
+ int i_p16 = vec_step(p16);
+ int i_p16c = vec_step(p16c);
+ int i_p16v = vec_step(p16v);
+ int i_p16c_ = vec_step(p16c_);
+ int i_p16v_ = vec_step(p16v_);
+ check((i_p16 + i_p16c + i_p16v + i_p16c_ + i_p16v_) != 40, "vec_step");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/brode-1.c b/gcc/testsuite/gcc.dg/vmx/brode-1.c
new file mode 100644
index 00000000000..234192bac9b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/brode-1.c
@@ -0,0 +1,10 @@
+#include <altivec.h>
+ int main( )
+ {
+ static int a[3][5][7];
+ {
+ vector signed int a4v;
+ a4v = vec_ldl(0, &a[0][0][0]);
+ }
+ return 0;
+ }
diff --git a/gcc/testsuite/gcc.dg/vmx/bug-1.c b/gcc/testsuite/gcc.dg/vmx/bug-1.c
new file mode 100644
index 00000000000..fdf392d5f9b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/bug-1.c
@@ -0,0 +1,39 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <altivec.h>
+
+#define NPAGES 20
+#define NSKIP 10
+static vector float big[NPAGES*4096/16] = { {1,1,1,1} };
+/* NPAGES pages worth. */
+
+static int failed;
+
+static void f(vector float *p)
+{
+ int i = 1;
+ p = (vector float *)(((ptrdiff_t)p + 4095) & ~4095);
+
+ i += NSKIP;
+ p += NSKIP*4096/16;
+
+ while (i < NPAGES)
+ {
+ if (!vec_all_eq(*p,((vector float){0,0,0,0})))
+ {
+ printf("*p isn't zero at 0x%p, page %d\n", p, i);
+ failed++;
+ }
+ i++;
+ p += 4096/16;
+ }
+}
+
+int main(void)
+{
+ f(big);
+ if (failed)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/bug-2.c b/gcc/testsuite/gcc.dg/vmx/bug-2.c
new file mode 100644
index 00000000000..5cdbc9856cb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/bug-2.c
@@ -0,0 +1,24 @@
+#include "harness.h"
+
+static vector unsigned char value =
+ { 0x7c, 0x12, 0x1, 0xd5,
+ 0xc3, 0x99, 0x21, 0xe2,
+ 0x12, 0x57, 0xde, 0x6b,
+ 0x39, 0x66, 0xa8, 0x87 };
+
+void initn_c (int p1, int p2, signed char p3, int p4, double p5 ,
+ vector unsigned char p6, signed char p7)
+{
+ check(p1 == 3, "p1");
+ check(p2 == 4, "p2");
+ check(p3 == 5, "p3");
+ check(p4 == 6, "p4");
+ check(p5 == 1, "p5");
+ check(vec_all_eq(p6, value), "p6");
+ check(p7 == 7, "p7");
+}
+
+void test()
+{
+ initn_c (3, 4, 5, 6, 1, value, 7);
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/bug-3.c b/gcc/testsuite/gcc.dg/vmx/bug-3.c
new file mode 100644
index 00000000000..aacca266769
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/bug-3.c
@@ -0,0 +1,45 @@
+#include "harness.h"
+
+static vector unsigned int value = { 9, 9, 9, 9 };
+
+void varargsC2 (int p1, int p2, int p3, int p4, int p5, int p6, int p7,
+ int p8, vector unsigned int p9, int p10)
+{
+ int i1;
+ int i2;
+ int i3;
+ int i4;
+ int i5;
+ int i6;
+ int i7;
+ int i8;
+ vector unsigned int i9;
+ int i10;
+
+ i1 = p1;
+ i2 = p2;
+ i3 = p3;
+ i4 = p4;
+ i5 = p5;
+ i6 = p6;
+ i7 = p7;
+ i8 = p8;
+ i9 = p9;
+ i10 = p10;
+
+ check(i1 == 1, "i1");
+ check(i2 == 2, "i2");
+ check(i3 == 3, "i3");
+ check(i4 == 4, "i4");
+ check(i5 == 5, "i5");
+ check(i6 == 6, "i6");
+ check(i7 == 7, "i7");
+ check(i8 == 8, "i8");
+ check(vec_all_eq(i9, value), "i9");
+ check(i10 == 10, "i10");
+}
+
+void test()
+{
+ varargsC2 (1, 2, 3, 4, 5, 6, 7, 8, ((vector unsigned int){9,9,9,9}), 10);
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/cw-bug-1.c b/gcc/testsuite/gcc.dg/vmx/cw-bug-1.c
new file mode 100644
index 00000000000..0c3028b5122
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/cw-bug-1.c
@@ -0,0 +1,12 @@
+#include <altivec.h>
+#include <stdlib.h>
+
+#define ZERO (((vector unsigned char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}))
+
+int main(void)
+{
+ vector unsigned char a = ZERO;
+ if (vec_any_ne(a, ZERO))
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/cw-bug-2.c b/gcc/testsuite/gcc.dg/vmx/cw-bug-2.c
new file mode 100644
index 00000000000..1c50dfffd6d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/cw-bug-2.c
@@ -0,0 +1,9 @@
+#include <altivec.h>
+#include <stdlib.h>
+
+int main(void)
+{
+ if (vec_any_ne((vector unsigned short)(((vector unsigned char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0})),
+ vec_mfvscr()))
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/cw-bug-3.c b/gcc/testsuite/gcc.dg/vmx/cw-bug-3.c
new file mode 100644
index 00000000000..511a7e0ae9d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/cw-bug-3.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+#include <altivec.h>
+vector signed short hamming_window[1] = {
+ {2621, 2623, 2629, 2638, 2651, 2668, 2689, 2713}
+};
diff --git a/gcc/testsuite/gcc.dg/vmx/dct.c b/gcc/testsuite/gcc.dg/vmx/dct.c
new file mode 100644
index 00000000000..00c4cd93c7b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/dct.c
@@ -0,0 +1,176 @@
+/* { dg-do compile } */
+#include <altivec.h>
+
+inline void
+transpose_vmx (vector signed short *input, vector signed short *output)
+{
+ vector signed short v0, v1, v2, v3, v4, v5, v6, v7;
+ vector signed short x0, x1, x2, x3, x4, x5, x6, x7;
+
+ /* Matrix transpose */
+ v0 = vec_mergeh (input[0], input[4]);
+ v1 = vec_mergel (input[0], input[4]);
+ v2 = vec_mergeh (input[1], input[5]);
+ v3 = vec_mergel (input[1], input[5]);
+ v4 = vec_mergeh (input[2], input[6]);
+ v5 = vec_mergel (input[2], input[6]);
+ v6 = vec_mergeh (input[3], input[7]);
+ v7 = vec_mergel (input[3], input[7]);
+
+ x0 = vec_mergeh (v0, v4);
+ x1 = vec_mergel (v0, v4);
+ x2 = vec_mergeh (v1, v5);
+ x3 = vec_mergel (v1, v5);
+ x4 = vec_mergeh (v2, v6);
+ x5 = vec_mergel (v2, v6);
+ x6 = vec_mergeh (v3, v7);
+ x7 = vec_mergel (v3, v7);
+
+ output[0] = vec_mergeh (x0, x4);
+ output[1] = vec_mergel (x0, x4);
+ output[2] = vec_mergeh (x1, x5);
+ output[3] = vec_mergel (x1, x5);
+ output[4] = vec_mergeh (x2, x6);
+ output[5] = vec_mergel (x2, x6);
+ output[6] = vec_mergeh (x3, x7);
+ output[7] = vec_mergel (x3, x7);
+}
+
+void
+dct_vmx (vector signed short *input, vector signed short *output,
+ vector signed short *postscale)
+{
+ vector signed short mul0, mul1, mul2, mul3, mul4, mul5, mul6, mul;
+ vector signed short v0, v1, v2, v3, v4, v5, v6, v7, v8, v9;
+ vector signed short v20, v21, v22, v23, v24, v25, v26, v27, v31;
+ int i;
+ vector signed short in[8], out[8];
+
+ /* Load first eight rows of input data */
+
+ /* Load multiplication constants */
+
+ /* Splat multiplication constants */
+ mul0 = vec_splat(input[8],0);
+ mul1 = vec_splat(input[8],1);
+ mul2 = vec_splat(input[8],2);
+ mul3 = vec_splat(input[8],3);
+ mul4 = vec_splat(input[8],4);
+ mul5 = vec_splat(input[8],5);
+ mul6 = vec_splat(input[8],6);
+
+ /* Perform DCT on the eight columns */
+
+ /*********** Stage 1 ***********/
+
+ v8 = vec_adds (input[0], input[7]);
+ v9 = vec_subs (input[0], input[7]);
+ v0 = vec_adds (input[1], input[6]);
+ v7 = vec_subs (input[1], input[6]);
+ v1 = vec_adds (input[2], input[5]);
+ v6 = vec_subs (input[2], input[5]);
+ v2 = vec_adds (input[3], input[4]);
+ v5 = vec_subs (input[3], input[4]);
+
+ /*********** Stage 2 ***********/
+
+ /* Top */
+ v3 = vec_adds (v8, v2); /* (V0+V7) + (V3+V4) */
+ v4 = vec_subs (v8, v2); /* (V0+V7) - (V3+V4) */
+ v2 = vec_adds (v0, v1); /* (V1+V6) + (V2+V5) */
+ v8 = vec_subs (v0, v1); /* (V1+V6) - (V2+V5) */
+
+ /* Bottom */
+ v0 = vec_subs (v7, v6); /* (V1-V6) - (V2-V5) */
+ v1 = vec_adds (v7, v6); /* (V1-V6) + (V2-V5) */
+
+ /*********** Stage 3 ***********/
+
+ /* Top */
+ in[0] = vec_adds (v3, v2); /* y0 = v3 + v2 */
+ in[4] = vec_subs (v3, v2); /* y4 = v3 - v2 */
+ in[2] = vec_mradds (v8, mul2, v4); /* y2 = v8 * a0 + v4 */
+ v6 = vec_mradds (v4, mul2, mul6);
+ in[6] = vec_subs (v6, v8); /* y6 = v4 * a0 - v8 */
+
+ /* Bottom */
+ v6 = vec_mradds (v0, mul0, v5); /* v6 = v0 * (c4) + v5 */
+ v7 = vec_mradds (v0, mul4, v5); /* v7 = v0 * (-c4) + v5 */
+ v2 = vec_mradds (v1, mul4, v9); /* v2 = v1 * (-c4) + v9 */
+ v3 = vec_mradds (v1, mul0, v9); /* v3 = v1 * (c4) + v9 */
+
+ /*********** Stage 4 ***********/
+
+ /* Bottom */
+ in[1] = vec_mradds (v6, mul3, v3); /* y1 = v6 * (a1) + v3 */
+ v23 = vec_mradds (v3, mul3, mul6);
+ in[7] = vec_subs (v23, v6); /* y7 = v3 * (a1) - v6 */
+ in[5] = vec_mradds (v2, mul1, v7); /* y5 = v2 * (a2) + v7 */
+ in[3] = vec_mradds (v7, mul5, v2); /* y3 = v7 * (-a2) + v2 */
+
+ transpose_vmx (in, out);
+
+ /* Perform DCT on the eight rows */
+
+ /*********** Stage 1 ***********/
+
+ v8 = vec_adds (out[0], out[7]);
+ v9 = vec_subs (out[0], out[7]);
+ v0 = vec_adds (out[1], out[6]);
+ v7 = vec_subs (out[1], out[6]);
+ v1 = vec_adds (out[2], out[5]);
+ v6 = vec_subs (out[2], out[5]);
+ v2 = vec_adds (out[3], out[4]);
+ v5 = vec_subs (out[3], out[4]);
+
+ /*********** Stage 2 ***********/
+
+ /* Top */
+ v3 = vec_adds (v8, v2); /* (V0+V7) + (V3+V4) */
+ v4 = vec_subs (v8, v2); /* (V0+V7) - (V3+V4) */
+ v2 = vec_adds (v0, v1); /* (V1+V6) + (V2+V5) */
+ v8 = vec_subs (v0, v1); /* (V1+V6) - (V2+V5) */
+
+ /* Bottom */
+ v0 = vec_subs (v7, v6); /* (V1-V6) - (V2-V5) */
+ v1 = vec_adds (v7, v6); /* (V1-V6) + (V2-V5) */
+
+ /*********** Stage 3 ***********/
+
+ /* Top */
+ v25 = vec_subs (v25, v25); /* reinit v25 = 0 */
+
+ v20 = vec_adds (v3, v2); /* y0 = v3 + v2 */
+ v24 = vec_subs (v3, v2); /* y4 = v3 - v2 */
+ v22 = vec_mradds (v8, mul2, v4); /* y2 = v8 * a0 + v4 */
+ v6 = vec_mradds (v4, mul2, v25);
+ v26 = vec_subs (v6, v8); /* y6 = v4 * a0 - v8 */
+
+ /* Bottom */
+ v6 = vec_mradds (v0, mul0, v5); /* v6 = v0 * (c4) + v5 */
+ v7 = vec_mradds (v0, mul4, v5); /* v7 = v0 * (-c4) + v5 */
+ v2 = vec_mradds (v1, mul4, v9); /* v2 = v1 * (-c4) + v9 */
+ v3 = vec_mradds (v1, mul0, v9); /* v3 = v1 * (c4) + v9 */
+
+ /*********** Stage 4 ***********/
+
+ /* Bottom */
+ v21 = vec_mradds (v6, mul3, v3); /* y1 = v6 * (a1) + v3 */
+ v23 = vec_mradds (v3, mul3, v25);
+ v27 = vec_subs (v23, v6); /* y7 = v3 * (a1) - v6 */
+ v25 = vec_mradds (v2, mul1, v7); /* y5 = v2 * (a2) + v7 */
+ v23 = vec_mradds (v7, mul5, v2); /* y3 = v7 * (-a2) + v2 */
+
+ /* Post-scale and store reults */
+
+ v31 = vec_subs (v31, v31); /* reinit v25 = 0 */
+
+ output[0] = vec_mradds (postscale[0], v20, v31);
+ output[2] = vec_mradds (postscale[2], v22, v31);
+ output[4] = vec_mradds (postscale[4], v24, v31);
+ output[6] = vec_mradds (postscale[6], v26, v31);
+ output[1] = vec_mradds (postscale[1], v21, v31);
+ output[3] = vec_mradds (postscale[3], v23, v31);
+ output[5] = vec_mradds (postscale[5], v25, v31);
+ output[7] = vec_mradds (postscale[7], v27, v31);
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/debug-1.c b/gcc/testsuite/gcc.dg/vmx/debug-1.c
new file mode 100644
index 00000000000..871625d2873
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/debug-1.c
@@ -0,0 +1,26 @@
+#include <altivec.h>
+vector unsigned char v;
+typedef unsigned char T[16];
+T t;
+typedef struct { unsigned char a[16]; } R;
+R r;
+typedef union {
+ unsigned char u8[16];
+ signed char s8[16];
+ unsigned short u16[8];
+ signed short s16[8];
+ unsigned long u32[4];
+ signed long s32[4];
+ float f32[4];
+} U;
+U u;
+static void use(void *p) {
+}
+int main() {
+ use (&v);
+ use (&t);
+ use (&r);
+ use (&u);
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/vmx/debug-2.c b/gcc/testsuite/gcc.dg/vmx/debug-2.c
new file mode 100644
index 00000000000..60380bcfce4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/debug-2.c
@@ -0,0 +1,42 @@
+#include <altivec.h>
+vector unsigned char u8 = {1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10,11,12,13,14,15,16};
+vector signed char s8 = {1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10,11,12,13,14,15,16};
+vector bool char b8 = {0, -1, 0, -1, 0, 0, 0, 0,
+ -1, -1, -1, -1, 0, -1, 0, -1};
+vector unsigned short u16 = {1, 2, 3, 4, 5, 6, 7, 8};
+vector signed short s16 = {1, 2, 3, 4, 5, 6, 7, 8};
+vector bool short b16 = {-1, 0, -1, 0, -1, -1, 0, 0};
+vector unsigned int u32 = {1, 2, 3, 4};
+vector signed int s32 = {1, 2, 3, 4};
+vector bool int b32 = {0, -1, -1, 0};
+vector float f32 = {1, 2, 3, 4};
+vector pixel p16 = {1, 2, 3, 4, 5, 6, 7, 8};
+
+static void f_u8(vector unsigned char *p) {}
+static void f_s8(vector signed char *p) {}
+static void f_b8(vector bool char *p) {}
+static void f_u16(vector unsigned short *p) {}
+static void f_s16(vector signed short *p) {}
+static void f_b16(vector bool short *p) {}
+static void f_u32(vector unsigned int *p) {}
+static void f_s32(vector signed int *p) {}
+static void f_b32(vector bool int *p) {}
+static void f_f32(vector float *p) {}
+static void f_p16(vector pixel *p) {}
+
+int main() {
+ f_u8(&u8);
+ f_s8(&s8);
+ f_b8(&b8);
+ f_u16(&u16);
+ f_s16(&s16);
+ f_b16(&b16);
+ f_u32(&u32);
+ f_s32(&s32);
+ f_b32(&b32);
+ f_f32(&f32);
+ f_p16(&p16);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/debug-3.c b/gcc/testsuite/gcc.dg/vmx/debug-3.c
new file mode 100644
index 00000000000..a9fc8662992
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/debug-3.c
@@ -0,0 +1,75 @@
+#include <altivec.h>
+vector unsigned char u8;
+vector signed char s8;
+vector bool char b8;
+vector unsigned short u16;
+vector signed short s16;
+vector bool short b16;
+vector unsigned int u32;
+vector signed int s32;
+vector bool int b32;
+vector float f32;
+vector pixel p16;
+
+void f_u8(vector unsigned char *p) {
+ u8 = *p;
+}
+void f_s8(vector signed char *p) {
+ s8 = *p;
+}
+void f_b8(vector bool char *p) {
+ b8 = *p;
+}
+void f_u16(vector unsigned short *p) {
+ u16 = *p;
+}
+void f_s16(vector signed short *p) {
+ s16 = *p;
+}
+void f_b16(vector bool short *p) {
+ b16 = *p;
+}
+void f_u32(vector unsigned int *p) {
+ u32 = *p;
+}
+void f_s32(vector signed int *p) {
+ s32 = *p;
+}
+void f_b32(vector bool int *p) {
+ b32 = *p;
+}
+void f_f32(vector float *p) {
+ f32 = *p;
+}
+void f_p16(vector pixel *p) {
+ p16 = *p;
+}
+
+int main() {
+ vector unsigned char u8 = ((vector unsigned char){1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10,11,12,13,14,15,16});
+ vector signed char s8 = ((vector signed char){1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10,11,12,13,14,15,16});
+ vector bool char b8 = ((vector bool char){0, -1, 0, -1, 0, 0, 0, 0,
+ -1, -1, -1, -1, 0, -1, 0, -1});
+ vector unsigned short u16 = ((vector unsigned short){1, 2, 3, 4, 5, 6, 7, 8});
+ vector signed short s16 = ((vector signed short){1, 2, 3, 4, 5, 6, 7, 8});
+ vector bool short b16 = ((vector bool short){-1, 0, -1, 0, -1, -1, 0, 0});
+ vector unsigned int u32 = ((vector unsigned int){1, 2, 3, 4});
+ vector signed int s32 = ((vector signed int){1, 2, 3, 4});
+ vector bool int b32 = ((vector bool int){0, -1, -1, 0});
+ vector float f32 = ((vector float){1, 2, 3, 4});
+ vector pixel p16 = ((vector pixel){1, 2, 3, 4, 5, 6, 7, 8});
+ f_u8(&u8);
+ f_s8(&s8);
+ f_b8(&b8);
+ f_u16(&u16);
+ f_s16(&s16);
+ f_b16(&b16);
+ f_u32(&u32);
+ f_s32(&s32);
+ f_b32(&b32);
+ f_f32(&f32);
+ f_p16(&p16);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/debug-4.c b/gcc/testsuite/gcc.dg/vmx/debug-4.c
new file mode 100644
index 00000000000..e30ba2674f1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/debug-4.c
@@ -0,0 +1,78 @@
+#include <altivec.h>
+vector unsigned char u8;
+vector signed char s8;
+vector bool char b8;
+vector unsigned short u16;
+vector signed short s16;
+vector bool short b16;
+vector unsigned int u32;
+vector signed int s32;
+vector bool int b32;
+vector float f32;
+vector pixel p16;
+
+void f_u8(vector unsigned char *p) {
+ u8 = vec_add(*p, *p);
+}
+void f_s8(vector signed char *p) {
+ s8 = vec_add(*p, *p);
+}
+void f_b8(vector bool char *p) {
+ b8 = vec_cmpgt(s8, s8);
+ b8 = vec_xor(b8, *p);
+}
+void f_u16(vector unsigned short *p) {
+ u16 = vec_add(*p, *p);
+}
+void f_s16(vector signed short *p) {
+ s16 = vec_add(*p, *p);
+}
+void f_b16(vector bool short *p) {
+ b16 = vec_cmpgt(s16, s16);
+ b16 = vec_xor(b16, *p);
+}
+void f_u32(vector unsigned int *p) {
+ u32 = vec_add(*p, *p);
+}
+void f_s32(vector signed int *p) {
+ s32 = vec_add(*p, *p);
+}
+void f_b32(vector bool int *p) {
+ b32 = vec_cmpgt(s32, s32);
+ b32 = vec_xor(b32, *p);
+}
+void f_f32(vector float *p) {
+ f32 = vec_add(*p, *p);
+}
+void f_p16(vector pixel *p) {
+ p16 = *p;
+}
+
+int main() {
+ vector unsigned char u8 = ((vector unsigned char){1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10,11,12,13,14,15,16});
+ vector signed char s8 = ((vector signed char){1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10,11,12,13,14,15,16});
+ vector bool char b8 = ((vector bool char){0, -1, 0, -1, 0, 0, 0, 0,
+ -1, -1, -1, -1, 0, -1, 0, -1});
+ vector unsigned short u16 = ((vector unsigned short){1, 2, 3, 4, 5, 6, 7, 8});
+ vector signed short s16 = ((vector signed short){1, 2, 3, 4, 5, 6, 7, 8});
+ vector bool short b16 = ((vector bool short){-1, 0, -1, 0, -1, -1, 0, 0});
+ vector unsigned int u32 = ((vector unsigned int){1, 2, 3, 4});
+ vector signed int s32 = ((vector signed int){1, 2, 3, 4});
+ vector bool int b32 = ((vector bool int){0, -1, -1, 0});
+ vector float f32 = ((vector float){1, 2, 3, 4});
+ vector pixel p16 = ((vector pixel){1, 2, 3, 4, 5, 6, 7, 8});
+ f_u8(&u8);
+ f_s8(&s8);
+ f_b8(&b8);
+ f_u16(&u16);
+ f_s16(&s16);
+ f_b16(&b16);
+ f_u32(&u32);
+ f_s32(&s32);
+ f_b32(&b32);
+ f_f32(&f32);
+ f_p16(&p16);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/dos-bug-1-gdb.c b/gcc/testsuite/gcc.dg/vmx/dos-bug-1-gdb.c
new file mode 100644
index 00000000000..dc4c4d3d9bb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/dos-bug-1-gdb.c
@@ -0,0 +1,7 @@
+#include <altivec.h>
+static vector unsigned int v = {0x01020304,0x05060708,0x21324354,0x65768798};
+static vector unsigned int f() { return v; }
+int main() {
+ vector unsigned int x = f();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/dos-bug-2-gdb.c b/gcc/testsuite/gcc.dg/vmx/dos-bug-2-gdb.c
new file mode 100644
index 00000000000..4ec47b12d2a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/dos-bug-2-gdb.c
@@ -0,0 +1,7 @@
+#include <altivec.h>
+static vector unsigned int v = {0x01020304,0x05060708,0x21324354,0x65768798};
+static vector unsigned int f() { return vec_splat(v,0); }
+int main() {
+ vector unsigned int x = f();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/eg-5.c b/gcc/testsuite/gcc.dg/vmx/eg-5.c
new file mode 100644
index 00000000000..0b37e69d194
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/eg-5.c
@@ -0,0 +1,27 @@
+#include "harness.h"
+
+static vector float
+matvecmul4 (vector float c0, vector float c1, vector float c2,
+ vector float c3, vector float v)
+{
+ /* Set result to a vector of f32 0's */
+ vector float result = ((vector float){0.,0.,0.,0.});
+
+ result = vec_madd (c0, vec_splat (v, 0), result);
+ result = vec_madd (c1, vec_splat (v, 1), result);
+ result = vec_madd (c2, vec_splat (v, 2), result);
+ result = vec_madd (c3, vec_splat (v, 3), result);
+
+ return result;
+}
+
+static void test()
+{
+ check(vec_all_eq(matvecmul4(((vector float){2,3,5,7}),
+ ((vector float){11,13,17,19}),
+ ((vector float){23,29,31,37}),
+ ((vector float){41,43,47,53}),
+ ((vector float){59,61,67,71})),
+ ((vector float){5241, 5966, 6746, 7814})),
+ "matvecmul4");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/fft.c b/gcc/testsuite/gcc.dg/vmx/fft.c
new file mode 100644
index 00000000000..2b8a537c669
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/fft.c
@@ -0,0 +1,99 @@
+/* { dg-do compile } */
+#include <altivec.h>
+
+inline void
+transpose4x4(vector float *matrix)
+{
+ vector float v0, v1, v2, v3;
+
+ v0 = vec_mergeh(matrix[0], matrix[2]);
+ v1 = vec_mergel(matrix[0], matrix[2]);
+ v2 = vec_mergeh(matrix[1], matrix[3]);
+ v3 = vec_mergel(matrix[1], matrix[3]);
+
+ matrix[0] = vec_mergeh(v0, v2);
+ matrix[1] = vec_mergel(v0, v2);
+ matrix[2] = vec_mergeh(v1, v3);
+ matrix[3] = vec_mergel(v1, v3);
+}
+
+void
+vec_ifft64(vector float *x0, vector float *x1)
+{
+ int i;
+ vector float real[4], imag[4];
+ vector float c0r, c1r, c2r, c3r, c0i, c1i, c2i, c3i;
+ vector float d0r, d1r, d2r, d3r, d0i, d1i, d2i, d3i;
+
+ /*
+ * N=64
+ *
+ * Stage 1: t=1 => k = 0, j = 0..15
+ * ================================
+ * for j = 0:15
+ * c0 = x0(j+0*16);
+ * c1 = x0(j+1*16);
+ * c2 = x0(j+2*16);
+ * c3 = x0(j+3*16);
+ *
+ * d0 = c0 + c2;
+ * d1 = c0 - c2;
+ * d2 = c1 + c3;
+ * d3 = i*(c1 - c3);
+ *
+ * x1(4j+0) = d0 + d2;
+ * x1(4j+1) = d1 + d3;
+ * x1(4j+2) = d0 - d2;
+ * x1(4j+3) = d1 - d3;
+ * end
+ ******************************************************/
+
+ for (i=0; i < 4; i++)
+ {
+ c0r = x0[i];
+ c1r = x0[i+4];
+ c2r = x0[i+8];
+ c3r = x0[i+12];
+
+ c0i = x0[i+16];
+ c1i = x0[i+20];
+ c2i = x0[i+24];
+ c3i = x0[i+28];
+
+ d0r = vec_add(c0r, c2r);
+ d1r = vec_sub(c0r, c2r);
+ d2r = vec_add(c1r, c3r);
+ d3r = vec_sub(c3i, c1i);
+
+ d0i = vec_add(c0i, c2i);
+ d1i = vec_sub(c0i, c2i);
+ d2i = vec_add(c1i, c3i);
+ d3i = vec_sub(c1r, c3r);
+
+ /* Calculate real{x1} */
+ real[0] = vec_add(d0r, d2r);
+ real[1] = vec_add(d1r, d3r);
+ real[2] = vec_sub(d0r, d2r);
+ real[3] = vec_sub(d1r, d3r);
+
+ transpose4x4(real);
+
+ /* Calculate imag{x1} */
+ imag[0] = vec_add(d0i, d2i);
+ imag[1] = vec_add(d1i, d3i);
+ imag[2] = vec_sub(d0i, d2i);
+ imag[3] = vec_sub(d1i, d3i);
+
+ transpose4x4(imag);
+
+ x1[4*i] = real[0];
+ x1[4*i+1] = real[1];
+ x1[4*i+2] = real[2];
+ x1[4*i+3] = real[3];
+
+ x1[4*i+16] = imag[0];
+ x1[4*i+17] = imag[1];
+ x1[4*i+18] = imag[2];
+ x1[4*i+19] = imag[3];
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/gcc-bug-1.c b/gcc/testsuite/gcc.dg/vmx/gcc-bug-1.c
new file mode 100644
index 00000000000..684ffe90eb7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/gcc-bug-1.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+#include <altivec.h>
+typedef struct n_a {
+ signed char m1;
+ vector float m2;
+} n_a;
+
+typedef struct n_b {
+ signed char m1;
+ struct n_a m2;
+} n_b;
+
+extern void f(n_b *);
+
+void initn_b(signed char p1, struct n_a p2)
+{
+ n_b _i;
+ ((_i).m1 = p1, (_i).m2 = p2);
+ f(&_i);
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/gcc-bug-2.c b/gcc/testsuite/gcc.dg/vmx/gcc-bug-2.c
new file mode 100644
index 00000000000..f2f3c4cfe03
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/gcc-bug-2.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+#include <altivec.h>
+typedef struct n_a {
+ signed char m1;
+ vector float m2;
+} n_a;
+
+typedef struct n_b {
+ signed char m1;
+ struct n_a m2;
+} n_b;
+
+extern void f(n_b *);
+
+void initn_b()
+{
+ n_b _i;
+ f(&_i);
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/gcc-bug-3.c b/gcc/testsuite/gcc.dg/vmx/gcc-bug-3.c
new file mode 100644
index 00000000000..77b2a002f33
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/gcc-bug-3.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+#include <altivec.h>
+void valuen014(vector float p1, vector float p2, vector float p3,
+ vector float p4, vector float p5, vector float p6,
+ vector float p7, vector float p8, vector float p9,
+ vector float p10, vector float p11, vector float p12,
+ int p13)
+{
+}
+
+void f()
+{
+ valuen014(((vector float) {1.83e+09, 5.73e+08, -2.96e+08, -7.46e+08}),
+ ((vector float) {-2.01e+09, 9.89e+08, -1.92e+09, 2.09e+09}),
+ ((vector float) {1.95e+09, -2.41e+08, 2.67e+08, 1.67e+09}),
+ ((vector float) {-2.12e+09, 8.18e+08, 9.47e+08, -1.25e+09}),
+ ((vector float) {-9.47e+08, -9.3e+08, -1.65e+09, 1.64e+09}),
+ ((vector float) {-7.99e+07, 4.86e+08, -3.4e+06, 3.11e+08}),
+ ((vector float) {1.78e+09, 1.22e+09, -1.27e+09, -3.11e+08}),
+ ((vector float) {1.41e+09, -5.38e+07, -2.08e+09, 1.54e+09}),
+ ((vector float) {3.1e+08, -1.49e+09, 5.38e+08, -1.3e+09}),
+ ((vector float) {9.66e+08, 5.5e+08, 1.75e+08, -8.22e+07}),
+ ((vector float) {-1.72e+08, -2.06e+09, 1.14e+09, -4.64e+08}),
+ ((vector float) {-1.25e+09, 8.12e+07, -2.02e+09, 4.71e+08}),
+ 962425441);
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/gcc-bug-4.c b/gcc/testsuite/gcc.dg/vmx/gcc-bug-4.c
new file mode 100644
index 00000000000..f76fbdc6e00
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/gcc-bug-4.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+#include <altivec.h>
+extern vector unsigned int gn00111;
+int f() { return (int)&gn00111; }
+
diff --git a/gcc/testsuite/gcc.dg/vmx/gcc-bug-5.c b/gcc/testsuite/gcc.dg/vmx/gcc-bug-5.c
new file mode 100644
index 00000000000..0eaa6adb7bd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/gcc-bug-5.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+#include <altivec.h>
+void valuen014(vector float p1, vector float p2, vector float p3,
+ vector float p4, vector float p5, vector float p6,
+ vector float p7, vector float p8, vector float p9,
+ vector float p10, vector float p11, vector float p12,
+ vector float px)
+{
+}
+
+void f()
+{
+ valuen014(((vector float) {1.83e+09, 5.73e+08, -2.96e+08, -7.46e+08}),
+ ((vector float) {-2.01e+09, 9.89e+08, -1.92e+09, 2.09e+09}),
+ ((vector float) {1.95e+09, -2.41e+08, 2.67e+08, 1.67e+09}),
+ ((vector float) {-2.12e+09, 8.18e+08, 9.47e+08, -1.25e+09}),
+ ((vector float) {-9.47e+08, -9.3e+08, -1.65e+09, 1.64e+09}),
+ ((vector float) {-7.99e+07, 4.86e+08, -3.4e+06, 3.11e+08}),
+ ((vector float) {1.78e+09, 1.22e+09, -1.27e+09, -3.11e+08}),
+ ((vector float) {1.41e+09, -5.38e+07, -2.08e+09, 1.54e+09}),
+ ((vector float) {3.1e+08, -1.49e+09, 5.38e+08, -1.3e+09}),
+ ((vector float) {9.66e+08, 5.5e+08, 1.75e+08, -8.22e+07}),
+ ((vector float) {-1.72e+08, -2.06e+09, 1.14e+09, -4.64e+08}),
+ ((vector float) {-1.25e+09, 8.12e+07, -2.02e+09, 4.71e+08}),
+ ((vector float){1,1,1,1}));
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/gcc-bug-6.c b/gcc/testsuite/gcc.dg/vmx/gcc-bug-6.c
new file mode 100644
index 00000000000..f0a424a2bd5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/gcc-bug-6.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+#include <altivec.h>
+void valuen014(vector float p1, vector float p2, vector float p3,
+ vector float p4, vector float p5, vector float p6,
+ vector float p7, vector float p8, vector float p9,
+ vector float p10, vector float p11, vector float p12,
+ vector float px, vector float py, vector float pz,
+ int p13)
+{
+}
+
+void f()
+{
+ valuen014(((vector float) {1.83e+09, 5.73e+08, -2.96e+08, -7.46e+08}),
+ ((vector float) {-2.01e+09, 9.89e+08, -1.92e+09, 2.09e+09}),
+ ((vector float) {1.95e+09, -2.41e+08, 2.67e+08, 1.67e+09}),
+ ((vector float) {-2.12e+09, 8.18e+08, 9.47e+08, -1.25e+09}),
+ ((vector float) {-9.47e+08, -9.3e+08, -1.65e+09, 1.64e+09}),
+ ((vector float) {-7.99e+07, 4.86e+08, -3.4e+06, 3.11e+08}),
+ ((vector float) {1.78e+09, 1.22e+09, -1.27e+09, -3.11e+08}),
+ ((vector float) {1.41e+09, -5.38e+07, -2.08e+09, 1.54e+09}),
+ ((vector float) {3.1e+08, -1.49e+09, 5.38e+08, -1.3e+09}),
+ ((vector float) {9.66e+08, 5.5e+08, 1.75e+08, -8.22e+07}),
+ ((vector float) {-1.72e+08, -2.06e+09, 1.14e+09, -4.64e+08}),
+ ((vector float) {-1.25e+09, 8.12e+07, -2.02e+09, 4.71e+08}),
+ ((vector float){1,1,1,1}),
+ ((vector float){2,2,2,2}),
+ ((vector float){3,3,3,3}),
+ 962425441);
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/gcc-bug-7.c b/gcc/testsuite/gcc.dg/vmx/gcc-bug-7.c
new file mode 100644
index 00000000000..452977bbfb3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/gcc-bug-7.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+#include <altivec.h>
+extern void referencen001(int *p1, int *p2, int *p3, int *p4, int *p5, int *p6, int *p7, vector float *p8);
+
+extern int gn0011;
+
+extern int gn0012;
+
+extern int gn0013;
+
+extern int gn0014;
+
+extern int gn0015;
+
+extern int gn0016;
+
+extern int gn0017;
+
+extern vector float gn0018;
+
+void testn001(void)
+{
+ int a1;
+ int a2;
+ int a3;
+ int a4;
+ int a5;
+ int a6;
+ int a7;
+ vector float a8;
+
+ (a1 = -53786696, a2 = -1840132710, a3 = -2130504990, a4 = 1429848501, a5 = 1139248605, a6 = 428762253, a7 = -1581480596, a8 = ((vector float) {1.66e+09, -1.83e+09, -6.79e+08, 1.58e+09}));
+
+ referencen001(&a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8);
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/gcc-bug-8.c b/gcc/testsuite/gcc.dg/vmx/gcc-bug-8.c
new file mode 100644
index 00000000000..33d4bd7e63d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/gcc-bug-8.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+#include <altivec.h>
+
+typedef struct n001 {
+ signed char m1;
+ vector float m2;
+ int m3;
+ vector signed short m4;
+ signed char m5;
+ vector unsigned short m6;
+} n001;
+
+ n001 _i = {-4, {-1.84e+09, -2.13e+09, 1.43e+09, 1.14e+09}, 428762253, {-24132, 25298, -27969, -10358, 24164, -5157, -18143, -6509}, 40, {0x8737, 0xd7cf, 0xb6a7, 0x948f, 0x790b, 0x9255, 0x872d, 0xe72c}};
diff --git a/gcc/testsuite/gcc.dg/vmx/gcc-bug-9.c b/gcc/testsuite/gcc.dg/vmx/gcc-bug-9.c
new file mode 100644
index 00000000000..b54338a3bc5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/gcc-bug-9.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+#include <altivec.h>
+
+vector signed short _j = {-24132, 25298, -27969, -10358, 24164, -5157, -18143, -6509};
+
diff --git a/gcc/testsuite/gcc.dg/vmx/gcc-bug-b.c b/gcc/testsuite/gcc.dg/vmx/gcc-bug-b.c
new file mode 100644
index 00000000000..e893ff1813a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/gcc-bug-b.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+#include <altivec.h>
+vector unsigned char u8a, u8b, u8c, u8d, *u8ptr;
+vector signed short s16a, s16b, s16c, s16d;
+vector unsigned short u16a, u16b, u16c, u16d;
+vector unsigned int u32a, u32b, u32c, u32d;
+vector float f32a, f32b, f32c, f32d, f32e;
+int i, j, *p;
+
+void test()
+{
+ u8c = vec_add(u8a, u8b);
+ f32c = vec_ceil(f32a);
+ f32d = vec_vcfux(u32a, 31U);
+ s16c = vec_splat_s16(-16);
+ u8d = vec_vsldoi(u8a, u8b, 15);
+ f32e = vec_vmaddfp(f32a, f32b, f32c);
+
+ vec_dss(3);
+ vec_dssall();
+ vec_mtvscr(u8a);
+ u16a = vec_mfvscr();
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/gcc-bug-c.c b/gcc/testsuite/gcc.dg/vmx/gcc-bug-c.c
new file mode 100644
index 00000000000..33fed4bd9c1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/gcc-bug-c.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+#include <altivec.h>
+vector signed short s16ss() { vector signed short a; return vec_subs(a,a); }
+vector signed short s16s() { vector signed short a; return vec_sub(a,a); }
+vector signed short s16x() { vector signed short a; return vec_xor(a,a); }
+vector signed short s16a() { vector signed short a; return vec_andc(a,a); }
+vector unsigned char u8;
+vector signed short s16;
+vector bool int b32;
+vector float f32;
+vector pixel p16;
+void x()
+{
+ u8 = ((vector unsigned char){3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3});
+ s16 = ((vector signed short){-7,-7,-7,-7,-7,-7,-7,-7});
+ b32 = ((vector bool int) {10,20,30,40});
+ f32 = ((vector float) {2,4,6,8});
+ p16 = ((vector pixel){23,23,23,23,23,23,23,23});
+}
+vector unsigned int a;
+vector unsigned int b;
+void f(void) {
+ a = ((vector unsigned int){1,1,1,1});
+ b = ((vector unsigned int){1,2,3,4});
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/gcc-bug-d.c b/gcc/testsuite/gcc.dg/vmx/gcc-bug-d.c
new file mode 100644
index 00000000000..2b2151eec98
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/gcc-bug-d.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+#include <altivec.h>
+static void f() {}
+extern void g() {}
+extern vector unsigned char permute_128(vector unsigned char);
+
+void foo()
+{
+ vector unsigned char input
+ = {0,1,2,4,8,16,32,64,128,0,1,2,4,8,16,32};
+ vector unsigned char result = permute_128(input);
+ void (*p)() = f;
+ void (*q)() = g;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/gcc-bug-e.c b/gcc/testsuite/gcc.dg/vmx/gcc-bug-e.c
new file mode 100644
index 00000000000..58e4fc3d318
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/gcc-bug-e.c
@@ -0,0 +1,44 @@
+#include "harness.h"
+
+typedef struct n_a
+{
+ signed char m1;
+ short m2;
+ int m3;
+ double m4;
+ vector float m5;
+}
+n_a;
+
+static void
+initn_a(signed char p1, short p2, int p3, double p4, vector float p5)
+{
+ n_a i;
+ static struct
+ {
+ n_a b;
+ char a;
+ }
+ x;
+
+ i.m1 = p1;
+ i.m2 = p2;
+ i.m3 = p3;
+ i.m4 = p4;
+ i.m5 = p5;
+
+ check(i.m1 == -17, "i.m1");
+ check(i.m2 == 9165, "i.m2");
+ check(i.m3 == -1857760764, "i.m3");
+ check(i.m4 == 7.3e+18, "i.m4");
+ check(vec_all_eq(i.m5, ((vector float){-5.02e+08,
+ -4.34e+08,
+ -1.04e+09,
+ 1.42e+09})), "i.m5");
+}
+
+static void test()
+{
+ initn_a(-17, 9165, -1857760764, 7.3e+18,
+ ((vector float){-5.02e+08, -4.34e+08, -1.04e+09, 1.42e+09}));
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/gcc-bug-f.c b/gcc/testsuite/gcc.dg/vmx/gcc-bug-f.c
new file mode 100644
index 00000000000..fb61bb15a76
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/gcc-bug-f.c
@@ -0,0 +1,125 @@
+/* { dg-do compile } */
+#include <altivec.h>
+typedef short Word16;
+typedef int Word32;
+typedef int Flag;
+
+extern Flag Overflow;
+extern Flag Carry;
+
+extern vector signed short table[8];
+extern vector signed short slope_cos[8];
+
+void Lsf_lsp(
+ vector signed short lsfq[],
+ vector signed short lspq[]
+)
+{
+ vector signed short Q17_con = ((vector signed short){20861,20861,20861,20861,20861,20861,20861,20861});
+ vector unsigned char perm1 = ((vector unsigned char){0, 8, 1, 9, 2, 10, 3,
+ 11, 4, 12, 5 ,13, 6, 14, 7, 15});
+ vector unsigned char PerIndex, tmpIndex;
+ vector signed short tmp0, tmp1, tmp2, tmp3;
+ vector signed short stmp0, stmp1, stmp2, stmp3;
+ vector signed short index0, index1, offset0, offset1;
+ vector signed short table0, table1, slope0, slope1;
+ vector unsigned short select;
+ vector signed int L_tmp0, L_tmp1, L_tmp2, L_tmp3;
+
+
+ tmp0 = vec_madds(lsfq[0], Q17_con, (((vector signed short){0,0,0,0,0,0,0,0})) );
+ tmp1 = vec_madds(lsfq[1], Q17_con, (((vector signed short){0,0,0,0,0,0,0,0})) );
+
+
+ offset0 = vec_and(tmp0, (((vector signed short){0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff})) );
+ offset1 = vec_and(tmp1, (((vector signed short){0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff})) );
+
+
+ index0 = vec_min(vec_sra(tmp0, (((vector unsigned short){8,8,8,8,8,8,8,8})) ), (((vector signed short){63,63,63,63,63,63,63,63})) );
+ index1 = vec_min(vec_sra(tmp1, (((vector unsigned short){8,8,8,8,8,8,8,8})) ), (((vector signed short){63,63,63,63,63,63,63,63})) );
+
+
+
+ tmp0 = vec_sl(index0, (vector unsigned short)((((vector signed short){1,1,1,1,1,1,1,1})) ));
+ PerIndex = (vector unsigned char)vec_packs(tmp0, vec_add(tmp0, (((vector signed short){1,1,1,1,1,1,1,1})) ));
+ PerIndex = vec_perm(PerIndex, PerIndex, perm1);
+
+
+ tmp0 = vec_perm(table[0], table[1], PerIndex);
+ stmp0 = vec_perm(slope_cos[0], slope_cos[1], PerIndex);
+
+ tmpIndex = vec_sub(PerIndex, (((vector unsigned char){32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32})) );
+ tmp1 = vec_perm(table[2], table[3], tmpIndex);
+ stmp1 = vec_perm(slope_cos[2], slope_cos[3], tmpIndex);
+
+ select = (vector unsigned short)vec_cmpgt(PerIndex, (((vector unsigned char){31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31})) );
+ tmp2 = vec_sel(tmp0, tmp1, select);
+ stmp2 = vec_sel(stmp0, stmp1, select);
+
+ tmpIndex = vec_sub(tmpIndex, (((vector unsigned char){32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32})) );
+ tmp0 = vec_perm(table[4], table[5], tmpIndex);
+ stmp0 = vec_perm(slope_cos[4], slope_cos[5], tmpIndex);
+
+ tmpIndex = vec_sub(tmpIndex, (((vector unsigned char){32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32})) );
+ tmp1 = vec_perm(table[6], table[7], tmpIndex);
+ stmp1 = vec_perm(slope_cos[6], slope_cos[7], tmpIndex);
+
+ select = (vector unsigned short)vec_cmpgt(PerIndex, (((vector unsigned char){95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95})) );
+ tmp3 = vec_sel(tmp0, tmp1, select);
+ stmp3 = vec_sel(stmp0, stmp1, select);
+
+ select = (vector unsigned short)vec_cmpgt(PerIndex, (((vector unsigned char){63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63})) );
+ table0 = vec_sel(tmp2, tmp3, select);
+ slope0 = vec_sel(stmp2, stmp3, select);
+
+ tmp0 = vec_sl(index1, (vector unsigned short)((((vector signed short){1,1,1,1,1,1,1,1})) ));
+ PerIndex = (vector unsigned char)vec_packs(tmp0, vec_add(tmp0, (((vector signed short){1,1,1,1,1,1,1,1})) ));
+ PerIndex = vec_perm(PerIndex, PerIndex, perm1);
+
+
+ tmp0 = vec_perm(table[0], table[1], PerIndex);
+ stmp0 = vec_perm(slope_cos[0], slope_cos[1], PerIndex);
+
+ tmpIndex = vec_sub(PerIndex, (((vector unsigned char){32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32})) );
+ tmp1 = vec_perm(table[2], table[3], tmpIndex);
+ stmp1 = vec_perm(slope_cos[2], slope_cos[3], tmpIndex);
+
+ select = (vector unsigned short)vec_cmpgt(PerIndex, (((vector unsigned char){31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31})) );
+ tmp2 = vec_sel(tmp0, tmp1, select);
+ stmp2 = vec_sel(stmp0, stmp1, select);
+
+ tmpIndex = vec_sub(tmpIndex, (((vector unsigned char){32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32})) );
+ tmp0 = vec_perm(table[4], table[5], tmpIndex);
+ stmp0 = vec_perm(slope_cos[4], slope_cos[5], tmpIndex);
+
+ tmpIndex = vec_sub(tmpIndex, (((vector unsigned char){32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32})) );
+ tmp1 = vec_perm(table[6], table[7], tmpIndex);
+ stmp1 = vec_perm(slope_cos[6], slope_cos[7], tmpIndex);
+
+ select = (vector unsigned short)vec_cmpgt(PerIndex, (((vector unsigned char){95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95})) );
+ tmp3 = vec_sel(tmp0, tmp1, select);
+ stmp3 = vec_sel(stmp0, stmp1, select);
+
+ select = (vector unsigned short)vec_cmpgt(PerIndex, (((vector unsigned char){63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63})) );
+ table1 = vec_sel(tmp2, tmp3, select);
+ slope1 = vec_sel(stmp2, stmp3, select);
+
+
+
+ L_tmp0 = vec_sra(vec_mule(slope0, offset0), (((vector unsigned int){12,12,12,12})) );
+ L_tmp1 = vec_sra(vec_mulo(slope0, offset0), (((vector unsigned int){12,12,12,12})) );
+ L_tmp2 = vec_sra(vec_mule(slope1, offset1), (((vector unsigned int){12,12,12,12})) );
+ L_tmp3 = vec_sra(vec_mulo(slope1, offset1), (((vector unsigned int){12,12,12,12})) );
+
+
+ tmp0 = vec_packs(L_tmp0, L_tmp2);
+ tmp1 = vec_packs(L_tmp1, L_tmp3);
+ tmp2 = vec_mergeh(tmp0, tmp1);
+ tmp3 = vec_mergel(tmp0, tmp1);
+
+
+ lspq[0] = vec_adds(table0, tmp2);
+ lspq[1] = vec_adds(table1, tmp3);
+
+ return;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/gcc-bug-g.c b/gcc/testsuite/gcc.dg/vmx/gcc-bug-g.c
new file mode 100644
index 00000000000..573a73b356c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/gcc-bug-g.c
@@ -0,0 +1,119 @@
+/* { dg-do compile } */
+#include <altivec.h>
+extern vector signed short table[8];
+extern vector signed short slope_cos[8];
+extern vector signed short slope_acos[8];
+
+void Lsf_lsp(
+ vector signed short lsfq[],
+ vector signed short lspq[]
+)
+{
+ vector signed short Q17_con = ((vector signed short){20861,20861,20861,20861,20861,20861,20861,20861});
+ vector unsigned char perm1 = ((vector unsigned char){0, 8, 1, 9, 2, 10, 3,
+ 11, 4, 12, 5 ,13, 6, 14, 7, 15});
+ vector unsigned char PerIndex, tmpIndex;
+ vector signed short tmp0, tmp1, tmp2, tmp3;
+ vector signed short stmp0, stmp1, stmp2, stmp3;
+ vector signed short index0, index1, offset0, offset1;
+ vector signed short table0, table1, slope0, slope1;
+ vector unsigned short select;
+ vector signed int L_tmp0, L_tmp1, L_tmp2, L_tmp3;
+
+
+ tmp0 = vec_madds(lsfq[0], Q17_con, (((vector signed short){0,0,0,0,0,0,0,0})) );
+ tmp1 = vec_madds(lsfq[1], Q17_con, (((vector signed short){0,0,0,0,0,0,0,0})) );
+
+
+ offset0 = vec_and(tmp0, (((vector signed short){0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff})) );
+ offset1 = vec_and(tmp1, (((vector signed short){0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff})) );
+
+
+ index0 = vec_min(vec_sra(tmp0, (((vector unsigned short){8,8,8,8,8,8,8,8})) ), (((vector signed short){63,63,63,63,63,63,63,63})) );
+ index1 = vec_min(vec_sra(tmp1, (((vector unsigned short){8,8,8,8,8,8,8,8})) ), (((vector signed short){63,63,63,63,63,63,63,63})) );
+
+
+
+ tmp0 = vec_sl(index0, (vector unsigned short)((((vector signed short){1,1,1,1,1,1,1,1})) ));
+ PerIndex = (vector unsigned char)vec_packs(tmp0, vec_add(tmp0, (((vector signed short){1,1,1,1,1,1,1,1})) ));
+ PerIndex = vec_perm(PerIndex, PerIndex, perm1);
+
+
+ tmp0 = vec_perm(table[0], table[1], PerIndex);
+ stmp0 = vec_perm(slope_cos[0], slope_cos[1], PerIndex);
+
+ tmpIndex = vec_sub(PerIndex, (((vector unsigned char){32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32})) );
+ tmp1 = vec_perm(table[2], table[3], tmpIndex);
+ stmp1 = vec_perm(slope_cos[2], slope_cos[3], tmpIndex);
+
+ select = (vector unsigned short)vec_cmpgt(PerIndex, (((vector unsigned char){31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31})) );
+ tmp2 = vec_sel(tmp0, tmp1, select);
+ stmp2 = vec_sel(stmp0, stmp1, select);
+
+ tmpIndex = vec_sub(tmpIndex, (((vector unsigned char){32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32})) );
+ tmp0 = vec_perm(table[4], table[5], tmpIndex);
+ stmp0 = vec_perm(slope_cos[4], slope_cos[5], tmpIndex);
+
+ tmpIndex = vec_sub(tmpIndex, (((vector unsigned char){32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32})) );
+ tmp1 = vec_perm(table[6], table[7], tmpIndex);
+ stmp1 = vec_perm(slope_cos[6], slope_cos[7], tmpIndex);
+
+ select = (vector unsigned short)vec_cmpgt(PerIndex, (((vector unsigned char){95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95})) );
+ tmp3 = vec_sel(tmp0, tmp1, select);
+ stmp3 = vec_sel(stmp0, stmp1, select);
+
+ select = (vector unsigned short)vec_cmpgt(PerIndex, (((vector unsigned char){63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63})) );
+ table0 = vec_sel(tmp2, tmp3, select);
+ slope0 = vec_sel(stmp2, stmp3, select);
+
+ tmp0 = vec_sl(index1, (vector unsigned short)((((vector signed short){1,1,1,1,1,1,1,1})) ));
+ PerIndex = (vector unsigned char)vec_packs(tmp0, vec_add(tmp0, (((vector signed short){1,1,1,1,1,1,1,1})) ));
+ PerIndex = vec_perm(PerIndex, PerIndex, perm1);
+
+
+ tmp0 = vec_perm(table[0], table[1], PerIndex);
+ stmp0 = vec_perm(slope_cos[0], slope_cos[1], PerIndex);
+
+ tmpIndex = vec_sub(PerIndex, (((vector unsigned char){32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32})) );
+ tmp1 = vec_perm(table[2], table[3], tmpIndex);
+ stmp1 = vec_perm(slope_cos[2], slope_cos[3], tmpIndex);
+
+ select = (vector unsigned short)vec_cmpgt(PerIndex, (((vector unsigned char){31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31})) );
+ tmp2 = vec_sel(tmp0, tmp1, select);
+ stmp2 = vec_sel(stmp0, stmp1, select);
+
+ tmpIndex = vec_sub(tmpIndex, (((vector unsigned char){32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32})) );
+ tmp0 = vec_perm(table[4], table[5], tmpIndex);
+ stmp0 = vec_perm(slope_cos[4], slope_cos[5], tmpIndex);
+
+ tmpIndex = vec_sub(tmpIndex, (((vector unsigned char){32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32})) );
+ tmp1 = vec_perm(table[6], table[7], tmpIndex);
+ stmp1 = vec_perm(slope_cos[6], slope_cos[7], tmpIndex);
+
+ select = (vector unsigned short)vec_cmpgt(PerIndex, (((vector unsigned char){95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95})) );
+ tmp3 = vec_sel(tmp0, tmp1, select);
+ stmp3 = vec_sel(stmp0, stmp1, select);
+
+ select = (vector unsigned short)vec_cmpgt(PerIndex, (((vector unsigned char){63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63})) );
+ table1 = vec_sel(tmp2, tmp3, select);
+ slope1 = vec_sel(stmp2, stmp3, select);
+
+
+
+ L_tmp0 = vec_sra(vec_mule(slope0, offset0), (((vector unsigned int){12,12,12,12})) );
+ L_tmp1 = vec_sra(vec_mulo(slope0, offset0), (((vector unsigned int){12,12,12,12})) );
+ L_tmp2 = vec_sra(vec_mule(slope1, offset1), (((vector unsigned int){12,12,12,12})) );
+ L_tmp3 = vec_sra(vec_mulo(slope1, offset1), (((vector unsigned int){12,12,12,12})) );
+
+
+ tmp0 = vec_packs(L_tmp0, L_tmp2);
+ tmp1 = vec_packs(L_tmp1, L_tmp3);
+ tmp2 = vec_mergeh(tmp0, tmp1);
+ tmp3 = vec_mergel(tmp0, tmp1);
+
+
+ lspq[0] = vec_adds(table0, tmp2);
+ lspq[1] = vec_adds(table1, tmp3);
+
+ return;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/gcc-bug-i.c b/gcc/testsuite/gcc.dg/vmx/gcc-bug-i.c
new file mode 100644
index 00000000000..58ccb3fe763
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/gcc-bug-i.c
@@ -0,0 +1,42 @@
+#include "harness.h"
+
+/* This problem occurs if a function is inlined. When its local
+ variables get allocated space on the caller's (the function to
+ which it is inlined) stack frame, they don't get 16-byte alignment
+ even if they need it. Here's an example with a union (that's the
+ first case I uncovered, but it's probably a general occurrence on
+ inlining). */
+
+#define N 10
+/* adjust N = size of buffer to try to get bad alignment for inlined union */
+
+#define DO_INLINE __attribute__ ((always_inline))
+#define DONT_INLINE __attribute__ ((noinline))
+
+static DO_INLINE int inline_me(vector signed short data)
+{
+ union {vector signed short v; signed short s[8];} u;
+ u.v = data;
+ return u.s[7];
+}
+
+static DONT_INLINE int foo(vector signed short data)
+{
+ int c, buffer[N], i;
+ c = inline_me(data);
+ for (i=0; i<N; i++) {
+ if (i == 0)
+ buffer[i] = c;
+ else
+ buffer[i] = buffer[i-1] + c*i;
+ }
+ return buffer[N-1];
+}
+
+static void test()
+{
+ check(foo((vector signed short)
+ ((vector unsigned char){1,2,3,4,5,6,7,8,
+ 9,10,11,12,13,14,15,16})) == 0x2b4e0,
+ "foo");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/harness.h b/gcc/testsuite/gcc.dg/vmx/harness.h
new file mode 100644
index 00000000000..faea3e97dba
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/harness.h
@@ -0,0 +1,30 @@
+/* Common code for most VMX test cases. To use, include this file,
+ then write a routine named test() that performs a series of calls
+ to check(). */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <altivec.h>
+
+static int failed;
+static void test (void);
+
+static void
+check (int result, const char *name)
+{
+ if (!result)
+ {
+ failed++;
+ printf ("fail %s\n", name);
+ }
+}
+
+int
+main (void)
+{
+ test ();
+ if (failed)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/ira1.c b/gcc/testsuite/gcc.dg/vmx/ira1.c
new file mode 100644
index 00000000000..eee2869121d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/ira1.c
@@ -0,0 +1,10 @@
+#include <altivec.h>
+#include <stdlib.h>
+vector unsigned char u8a, u8b;
+
+int main()
+{
+ if (!vec_all_eq(u8a, u8b))
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/ira2.c b/gcc/testsuite/gcc.dg/vmx/ira2.c
new file mode 100644
index 00000000000..cf2248097fb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/ira2.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+#include <altivec.h>
+vector unsigned char u8a, u8b, u8c, u8d, *u8ptr;
+vector signed short s16a, s16b, s16c, s16d;
+vector unsigned short u16a, u16b, u16c, u16d;
+vector unsigned int u32a, u32b, u32c, u32d;
+vector float f32a, f32b, f32c, f32d, f32e;
+int i, j, *p;
+
+void test()
+{
+ u8c = vec_add(u8a, u8b);
+ f32c = vec_ceil(f32a);
+ f32d = vec_vcfux(u32a, 31U);
+ s16c = vec_splat_s16(-16);
+ u8d = vec_vsldoi(u8a, u8b, 15);
+ f32e = vec_vmaddfp(f32a, f32b, f32c);
+ /* vec_dstst(u8ptr, i, 3U); */
+ vec_dss(3);
+ vec_dssall();
+ vec_mtvscr(u8a);
+ u16a = vec_mfvscr();
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/ira2a.c b/gcc/testsuite/gcc.dg/vmx/ira2a.c
new file mode 100644
index 00000000000..e6a716d6fe9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/ira2a.c
@@ -0,0 +1,9 @@
+#include <altivec.h>
+vector unsigned char *u8ptr;
+int i;
+
+int main()
+{
+ vec_dstst(u8ptr, i, 3U);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/ira2b.c b/gcc/testsuite/gcc.dg/vmx/ira2b.c
new file mode 100644
index 00000000000..d9a33f2dd03
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/ira2b.c
@@ -0,0 +1,17 @@
+#include "harness.h"
+
+static vector float
+f(vector float f32a, vector float f32b, vector float f32c)
+{
+ f32c = vec_ceil(f32a);
+ return vec_vmaddfp(f32a, f32b, f32c);
+}
+
+static void test()
+{
+ check(vec_all_eq(f(((vector float){2,3,5,7}),
+ ((vector float){11,13,17,19}),
+ ((vector float){23,29,31,37})),
+ ((vector float){24, 42, 90, 140})),
+ "test");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/ira2c.c b/gcc/testsuite/gcc.dg/vmx/ira2c.c
new file mode 100644
index 00000000000..bce5469ceaa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/ira2c.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+
+double __fabs(double a) { return a; }
+double __fmadd(double a, double b, double c) { return a*b+c; }
+
+double
+test(double f32a, double f32b, double f32c)
+{
+ f32c = __fabs(f32a);
+ return __fmadd(f32a, f32b, f32c);
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/mem.c b/gcc/testsuite/gcc.dg/vmx/mem.c
new file mode 100644
index 00000000000..a26eb3cfc65
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/mem.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+#include <altivec.h>
+void
+f(vector unsigned char *a, vector unsigned char *b, vector unsigned char *c)
+{
+ int i;
+ for (i = 0; i < 16; i++)
+ c[i] = vec_add(a[i], b[i]);
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/newton-1.c b/gcc/testsuite/gcc.dg/vmx/newton-1.c
new file mode 100644
index 00000000000..c5963c03447
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/newton-1.c
@@ -0,0 +1,67 @@
+/* { dg-do compile } */
+#include <altivec.h>
+
+#define SPLAT76 ((vector unsigned char)\
+ {0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3})
+#define SPLAT54 ((vector unsigned char)\
+ {4,5,6,7,4,5,6,7,4,5,6,7,4,5,6,7})
+#define SPLAT32 ((vector unsigned char)\
+ {8,9,10,11,8,9,10,11,8,9,10,11,8,9,10,11})
+#define SPLAT10 ((vector unsigned char)\
+ {12,13,14,15,12,13,14,15,12,13,14,15,12,13,14,15})
+#define INTERLEAVE ((vector unsigned char)\
+ {0,1,16,17,4,5,20,21,8,9,24,25,12,13,28,29})
+
+long real_32_manytaps (long ntaps, vector signed short *c, long ndat,
+ vector signed short *x, vector signed short *y)
+{
+ long i, j, op, ndatavec, ncoefvec;
+ vector signed short x0, x1;
+ vector signed short coef;
+ vector signed short cr10, cr32, cr54, cr76;
+ vector signed int y_even, y_odd;
+ vector signed short *x1p;
+
+ op = 0;
+ ndatavec = ndat >> 3;
+ ncoefvec = ntaps >> 3;
+
+ for (i = 0; i < ndatavec; i += 1) {
+ x0 = x[i];
+
+ y_even = ((vector signed int){0x8000,0x8000,0x8000,0x8000});
+ y_odd = ((vector signed int){0x8000,0x8000,0x8000,0x8000});
+
+ j = 0;
+ x1p = x + 1 + i;
+
+ do {
+
+ coef = c[j];
+ x1 = x1p[j];
+
+ cr10 = vec_perm(coef, coef, SPLAT10);
+ y_odd = vec_msums(cr10, x1, y_odd);
+ y_even = vec_msums(cr10, vec_sld(x0, x1, 14), y_even);
+
+ cr32 = vec_perm(coef, coef, SPLAT32);
+ y_odd = vec_msums(cr32, vec_sld(x0, x1, 12), y_odd);
+ y_even = vec_msums(cr32, vec_sld(x0, x1, 10), y_even);
+
+ cr54 = vec_perm(coef, coef, SPLAT54);
+ y_odd = vec_msums(cr54, vec_sld(x0, x1, 8), y_odd);
+ y_even = vec_msums(cr54, vec_sld(x0, x1, 6), y_even);
+
+ cr76 = vec_perm(coef, coef, SPLAT76);
+ y_odd = vec_msums(cr76, vec_sld(x0, x1, 4), y_odd);
+ y_even = vec_msums(cr76, vec_sld(x0, x1, 2), y_even);
+
+ x0 = x1;
+
+ } while (++j < ncoefvec);
+ y[op++] = (vector signed short) vec_perm(y_even, y_odd, INTERLEAVE);
+
+ }
+
+ return op*8;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/ops.c b/gcc/testsuite/gcc.dg/vmx/ops.c
new file mode 100644
index 00000000000..5be0588ccc0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/ops.c
@@ -0,0 +1,3893 @@
+/* { dg-do compile } */
+#include <altivec.h>
+#include <stdlib.h>
+extern char * *var_char_ptr;
+extern float * *var_float_ptr;
+extern int * *var_int_ptr;
+extern int *var_cc24f;
+extern int *var_cc24fd;
+extern int *var_cc24fr;
+extern int *var_cc24t;
+extern int *var_cc24td;
+extern int *var_cc24tr;
+extern int *var_cc26f;
+extern int *var_cc26fd;
+extern int *var_cc26fr;
+extern int *var_cc26t;
+extern int *var_cc26td;
+extern int *var_cc26tr;
+extern int *var_int;
+extern long * *var_long_ptr;
+extern short * *var_short_ptr;
+extern signed char * *var_signed_char_ptr;
+extern unsigned char * *var_unsigned_char_ptr;
+extern unsigned int * *var_unsigned_int_ptr;
+extern unsigned long * *var_unsigned_long_ptr;
+extern unsigned short * *var_unsigned_short_ptr;
+extern vector bool char * *var_vec_b8_ptr;
+extern vector bool char *var_vec_b8;
+extern vector bool int * *var_vec_b32_ptr;
+extern vector bool int *var_vec_b32;
+extern vector bool short * *var_vec_b16_ptr;
+extern vector bool short *var_vec_b16;
+extern vector float * *var_vec_f32_ptr;
+extern vector float *var_vec_f32;
+extern vector pixel * *var_vec_p16_ptr;
+extern vector pixel *var_vec_p16;
+extern vector signed char * *var_vec_s8_ptr;
+extern vector signed char *var_vec_s8;
+extern vector signed int * *var_vec_s32_ptr;
+extern vector signed int *var_vec_s32;
+extern vector signed short * *var_vec_s16_ptr;
+extern vector signed short *var_vec_s16;
+extern vector unsigned char * *var_vec_u8_ptr;
+extern vector unsigned char *var_vec_u8;
+extern vector unsigned int * *var_vec_u32_ptr;
+extern vector unsigned int *var_vec_u32;
+extern vector unsigned short * *var_vec_u16_ptr;
+extern vector unsigned short *var_vec_u16;
+extern vector unsigned short *var_volatile_vec_u16;
+void f0() {
+ *var_cc24f++ = vec_any_le(var_vec_b16[0], var_vec_s16[1]);
+ *var_cc24f++ = vec_any_le(var_vec_b16[0], var_vec_u16[1]);
+ *var_cc24f++ = vec_any_le(var_vec_b32[0], var_vec_s32[1]);
+ *var_cc24f++ = vec_any_le(var_vec_b32[0], var_vec_u32[1]);
+ *var_cc24f++ = vec_any_le(var_vec_b8[0], var_vec_s8[1]);
+ *var_cc24f++ = vec_any_le(var_vec_b8[0], var_vec_u8[1]);
+ *var_cc24f++ = vec_any_le(var_vec_s16[0], var_vec_b16[1]);
+ *var_cc24f++ = vec_any_le(var_vec_s16[0], var_vec_s16[1]);
+ *var_cc24f++ = vec_any_le(var_vec_s32[0], var_vec_b32[1]);
+ *var_cc24f++ = vec_any_le(var_vec_s32[0], var_vec_s32[1]);
+ *var_cc24f++ = vec_any_le(var_vec_s8[0], var_vec_b8[1]);
+ *var_cc24f++ = vec_any_le(var_vec_s8[0], var_vec_s8[1]);
+ *var_cc24f++ = vec_any_le(var_vec_u16[0], var_vec_b16[1]);
+ *var_cc24f++ = vec_any_le(var_vec_u16[0], var_vec_u16[1]);
+ *var_cc24f++ = vec_any_le(var_vec_u32[0], var_vec_b32[1]);
+ *var_cc24f++ = vec_any_le(var_vec_u32[0], var_vec_u32[1]);
+ *var_cc24f++ = vec_any_le(var_vec_u8[0], var_vec_b8[1]);
+ *var_cc24f++ = vec_any_le(var_vec_u8[0], var_vec_u8[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_b16[0], var_vec_b16[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_b16[0], var_vec_s16[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_b16[0], var_vec_u16[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_b32[0], var_vec_b32[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_b32[0], var_vec_s32[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_b32[0], var_vec_u32[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_b8[0], var_vec_b8[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_b8[0], var_vec_s8[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_b8[0], var_vec_u8[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_f32[0], var_vec_f32[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_p16[0], var_vec_p16[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_s16[0], var_vec_b16[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_s16[0], var_vec_s16[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_s32[0], var_vec_b32[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_s32[0], var_vec_s32[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_s8[0], var_vec_b8[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_s8[0], var_vec_s8[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_u16[0], var_vec_b16[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_u16[0], var_vec_u16[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_u32[0], var_vec_b32[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_u32[0], var_vec_u32[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_u8[0], var_vec_b8[1]);
+ *var_cc24f++ = vec_any_ne(var_vec_u8[0], var_vec_u8[1]);
+ *var_cc24f++ = vec_any_nge(var_vec_f32[0], var_vec_f32[1]);
+ *var_cc24f++ = vec_any_ngt(var_vec_f32[0], var_vec_f32[1]);
+ *var_cc24fd++ = vec_any_nan(var_vec_f32[0]);
+ *var_cc24fr++ = vec_any_ge(var_vec_b16[0], var_vec_s16[1]);
+ *var_cc24fr++ = vec_any_ge(var_vec_b16[0], var_vec_u16[1]);
+ *var_cc24fr++ = vec_any_ge(var_vec_b32[0], var_vec_s32[1]);
+ *var_cc24fr++ = vec_any_ge(var_vec_b32[0], var_vec_u32[1]);
+ *var_cc24fr++ = vec_any_ge(var_vec_b8[0], var_vec_s8[1]);
+ *var_cc24fr++ = vec_any_ge(var_vec_b8[0], var_vec_u8[1]);
+ *var_cc24fr++ = vec_any_ge(var_vec_s16[0], var_vec_b16[1]);
+ *var_cc24fr++ = vec_any_ge(var_vec_s16[0], var_vec_s16[1]);
+ *var_cc24fr++ = vec_any_ge(var_vec_s32[0], var_vec_b32[1]);
+ *var_cc24fr++ = vec_any_ge(var_vec_s32[0], var_vec_s32[1]);
+ *var_cc24fr++ = vec_any_ge(var_vec_s8[0], var_vec_b8[1]);
+ *var_cc24fr++ = vec_any_ge(var_vec_s8[0], var_vec_s8[1]);
+ *var_cc24fr++ = vec_any_ge(var_vec_u16[0], var_vec_b16[1]);
+ *var_cc24fr++ = vec_any_ge(var_vec_u16[0], var_vec_u16[1]);
+ *var_cc24fr++ = vec_any_ge(var_vec_u32[0], var_vec_b32[1]);
+ *var_cc24fr++ = vec_any_ge(var_vec_u32[0], var_vec_u32[1]);
+ *var_cc24fr++ = vec_any_ge(var_vec_u8[0], var_vec_b8[1]);
+ *var_cc24fr++ = vec_any_ge(var_vec_u8[0], var_vec_u8[1]);
+ *var_cc24fr++ = vec_any_nle(var_vec_f32[0], var_vec_f32[1]);
+ *var_cc24fr++ = vec_any_nlt(var_vec_f32[0], var_vec_f32[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_b16[0], var_vec_b16[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_b16[0], var_vec_s16[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_b16[0], var_vec_u16[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_b32[0], var_vec_b32[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_b32[0], var_vec_s32[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_b32[0], var_vec_u32[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_b8[0], var_vec_b8[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_b8[0], var_vec_s8[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_b8[0], var_vec_u8[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_f32[0], var_vec_f32[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_p16[0], var_vec_p16[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_s16[0], var_vec_b16[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_s16[0], var_vec_s16[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_s32[0], var_vec_b32[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_s32[0], var_vec_s32[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_s8[0], var_vec_b8[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_s8[0], var_vec_s8[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_u16[0], var_vec_b16[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_u16[0], var_vec_u16[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_u32[0], var_vec_b32[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_u32[0], var_vec_u32[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_u8[0], var_vec_b8[1]);
+ *var_cc24t++ = vec_all_eq(var_vec_u8[0], var_vec_u8[1]);
+ *var_cc24t++ = vec_all_ge(var_vec_f32[0], var_vec_f32[1]);
+ *var_cc24t++ = vec_all_gt(var_vec_b16[0], var_vec_s16[1]);
+ *var_cc24t++ = vec_all_gt(var_vec_b16[0], var_vec_u16[1]);
+ *var_cc24t++ = vec_all_gt(var_vec_b32[0], var_vec_s32[1]);
+ *var_cc24t++ = vec_all_gt(var_vec_b32[0], var_vec_u32[1]);
+ *var_cc24t++ = vec_all_gt(var_vec_b8[0], var_vec_s8[1]);
+ *var_cc24t++ = vec_all_gt(var_vec_b8[0], var_vec_u8[1]);
+ *var_cc24t++ = vec_all_gt(var_vec_f32[0], var_vec_f32[1]);
+ *var_cc24t++ = vec_all_gt(var_vec_s16[0], var_vec_b16[1]);
+ *var_cc24t++ = vec_all_gt(var_vec_s16[0], var_vec_s16[1]);
+ *var_cc24t++ = vec_all_gt(var_vec_s32[0], var_vec_b32[1]);
+ *var_cc24t++ = vec_all_gt(var_vec_s32[0], var_vec_s32[1]);
+ *var_cc24t++ = vec_all_gt(var_vec_s8[0], var_vec_b8[1]);
+}
+void f1() {
+ *var_cc24t++ = vec_all_gt(var_vec_s8[0], var_vec_s8[1]);
+ *var_cc24t++ = vec_all_gt(var_vec_u16[0], var_vec_b16[1]);
+ *var_cc24t++ = vec_all_gt(var_vec_u16[0], var_vec_u16[1]);
+ *var_cc24t++ = vec_all_gt(var_vec_u32[0], var_vec_b32[1]);
+ *var_cc24t++ = vec_all_gt(var_vec_u32[0], var_vec_u32[1]);
+ *var_cc24t++ = vec_all_gt(var_vec_u8[0], var_vec_b8[1]);
+ *var_cc24t++ = vec_all_gt(var_vec_u8[0], var_vec_u8[1]);
+ *var_cc24td++ = vec_all_numeric(var_vec_f32[0]);
+ *var_cc24tr++ = vec_all_le(var_vec_f32[0], var_vec_f32[1]);
+ *var_cc24tr++ = vec_all_lt(var_vec_b16[0], var_vec_s16[1]);
+ *var_cc24tr++ = vec_all_lt(var_vec_b16[0], var_vec_u16[1]);
+ *var_cc24tr++ = vec_all_lt(var_vec_b32[0], var_vec_s32[1]);
+ *var_cc24tr++ = vec_all_lt(var_vec_b32[0], var_vec_u32[1]);
+ *var_cc24tr++ = vec_all_lt(var_vec_b8[0], var_vec_s8[1]);
+ *var_cc24tr++ = vec_all_lt(var_vec_b8[0], var_vec_u8[1]);
+ *var_cc24tr++ = vec_all_lt(var_vec_f32[0], var_vec_f32[1]);
+ *var_cc24tr++ = vec_all_lt(var_vec_s16[0], var_vec_b16[1]);
+ *var_cc24tr++ = vec_all_lt(var_vec_s16[0], var_vec_s16[1]);
+ *var_cc24tr++ = vec_all_lt(var_vec_s32[0], var_vec_b32[1]);
+ *var_cc24tr++ = vec_all_lt(var_vec_s32[0], var_vec_s32[1]);
+ *var_cc24tr++ = vec_all_lt(var_vec_s8[0], var_vec_b8[1]);
+ *var_cc24tr++ = vec_all_lt(var_vec_s8[0], var_vec_s8[1]);
+ *var_cc24tr++ = vec_all_lt(var_vec_u16[0], var_vec_b16[1]);
+ *var_cc24tr++ = vec_all_lt(var_vec_u16[0], var_vec_u16[1]);
+ *var_cc24tr++ = vec_all_lt(var_vec_u32[0], var_vec_b32[1]);
+ *var_cc24tr++ = vec_all_lt(var_vec_u32[0], var_vec_u32[1]);
+ *var_cc24tr++ = vec_all_lt(var_vec_u8[0], var_vec_b8[1]);
+ *var_cc24tr++ = vec_all_lt(var_vec_u8[0], var_vec_u8[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_b16[0], var_vec_b16[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_b16[0], var_vec_s16[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_b16[0], var_vec_u16[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_b32[0], var_vec_b32[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_b32[0], var_vec_s32[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_b32[0], var_vec_u32[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_b8[0], var_vec_b8[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_b8[0], var_vec_s8[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_b8[0], var_vec_u8[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_f32[0], var_vec_f32[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_p16[0], var_vec_p16[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_s16[0], var_vec_b16[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_s16[0], var_vec_s16[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_s32[0], var_vec_b32[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_s32[0], var_vec_s32[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_s8[0], var_vec_b8[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_s8[0], var_vec_s8[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_u16[0], var_vec_b16[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_u16[0], var_vec_u16[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_u32[0], var_vec_b32[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_u32[0], var_vec_u32[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_u8[0], var_vec_b8[1]);
+ *var_cc26f++ = vec_any_eq(var_vec_u8[0], var_vec_u8[1]);
+ *var_cc26f++ = vec_any_ge(var_vec_f32[0], var_vec_f32[1]);
+ *var_cc26f++ = vec_any_gt(var_vec_b16[0], var_vec_s16[1]);
+ *var_cc26f++ = vec_any_gt(var_vec_b16[0], var_vec_u16[1]);
+ *var_cc26f++ = vec_any_gt(var_vec_b32[0], var_vec_s32[1]);
+ *var_cc26f++ = vec_any_gt(var_vec_b32[0], var_vec_u32[1]);
+ *var_cc26f++ = vec_any_gt(var_vec_b8[0], var_vec_s8[1]);
+ *var_cc26f++ = vec_any_gt(var_vec_b8[0], var_vec_u8[1]);
+ *var_cc26f++ = vec_any_gt(var_vec_f32[0], var_vec_f32[1]);
+ *var_cc26f++ = vec_any_gt(var_vec_s16[0], var_vec_b16[1]);
+ *var_cc26f++ = vec_any_gt(var_vec_s16[0], var_vec_s16[1]);
+ *var_cc26f++ = vec_any_gt(var_vec_s32[0], var_vec_b32[1]);
+ *var_cc26f++ = vec_any_gt(var_vec_s32[0], var_vec_s32[1]);
+ *var_cc26f++ = vec_any_gt(var_vec_s8[0], var_vec_b8[1]);
+ *var_cc26f++ = vec_any_gt(var_vec_s8[0], var_vec_s8[1]);
+ *var_cc26f++ = vec_any_gt(var_vec_u16[0], var_vec_b16[1]);
+ *var_cc26f++ = vec_any_gt(var_vec_u16[0], var_vec_u16[1]);
+ *var_cc26f++ = vec_any_gt(var_vec_u32[0], var_vec_b32[1]);
+ *var_cc26f++ = vec_any_gt(var_vec_u32[0], var_vec_u32[1]);
+ *var_cc26f++ = vec_any_gt(var_vec_u8[0], var_vec_b8[1]);
+ *var_cc26f++ = vec_any_gt(var_vec_u8[0], var_vec_u8[1]);
+ *var_cc26f++ = vec_any_out(var_vec_f32[0], var_vec_f32[1]);
+ *var_cc26fd++ = vec_any_numeric(var_vec_f32[0]);
+ *var_cc26fr++ = vec_any_le(var_vec_f32[0], var_vec_f32[1]);
+ *var_cc26fr++ = vec_any_lt(var_vec_b16[0], var_vec_s16[1]);
+ *var_cc26fr++ = vec_any_lt(var_vec_b16[0], var_vec_u16[1]);
+ *var_cc26fr++ = vec_any_lt(var_vec_b32[0], var_vec_s32[1]);
+ *var_cc26fr++ = vec_any_lt(var_vec_b32[0], var_vec_u32[1]);
+ *var_cc26fr++ = vec_any_lt(var_vec_b8[0], var_vec_s8[1]);
+ *var_cc26fr++ = vec_any_lt(var_vec_b8[0], var_vec_u8[1]);
+ *var_cc26fr++ = vec_any_lt(var_vec_f32[0], var_vec_f32[1]);
+ *var_cc26fr++ = vec_any_lt(var_vec_s16[0], var_vec_b16[1]);
+ *var_cc26fr++ = vec_any_lt(var_vec_s16[0], var_vec_s16[1]);
+ *var_cc26fr++ = vec_any_lt(var_vec_s32[0], var_vec_b32[1]);
+ *var_cc26fr++ = vec_any_lt(var_vec_s32[0], var_vec_s32[1]);
+ *var_cc26fr++ = vec_any_lt(var_vec_s8[0], var_vec_b8[1]);
+ *var_cc26fr++ = vec_any_lt(var_vec_s8[0], var_vec_s8[1]);
+ *var_cc26fr++ = vec_any_lt(var_vec_u16[0], var_vec_b16[1]);
+ *var_cc26fr++ = vec_any_lt(var_vec_u16[0], var_vec_u16[1]);
+ *var_cc26fr++ = vec_any_lt(var_vec_u32[0], var_vec_b32[1]);
+ *var_cc26fr++ = vec_any_lt(var_vec_u32[0], var_vec_u32[1]);
+ *var_cc26fr++ = vec_any_lt(var_vec_u8[0], var_vec_b8[1]);
+ *var_cc26fr++ = vec_any_lt(var_vec_u8[0], var_vec_u8[1]);
+ *var_cc26t++ = vec_all_in(var_vec_f32[0], var_vec_f32[1]);
+ *var_cc26t++ = vec_all_le(var_vec_b16[0], var_vec_s16[1]);
+ *var_cc26t++ = vec_all_le(var_vec_b16[0], var_vec_u16[1]);
+ *var_cc26t++ = vec_all_le(var_vec_b32[0], var_vec_s32[1]);
+ *var_cc26t++ = vec_all_le(var_vec_b32[0], var_vec_u32[1]);
+ *var_cc26t++ = vec_all_le(var_vec_b8[0], var_vec_s8[1]);
+ *var_cc26t++ = vec_all_le(var_vec_b8[0], var_vec_u8[1]);
+}
+void f2() {
+ *var_cc26t++ = vec_all_le(var_vec_s16[0], var_vec_b16[1]);
+ *var_cc26t++ = vec_all_le(var_vec_s16[0], var_vec_s16[1]);
+ *var_cc26t++ = vec_all_le(var_vec_s32[0], var_vec_b32[1]);
+ *var_cc26t++ = vec_all_le(var_vec_s32[0], var_vec_s32[1]);
+ *var_cc26t++ = vec_all_le(var_vec_s8[0], var_vec_b8[1]);
+ *var_cc26t++ = vec_all_le(var_vec_s8[0], var_vec_s8[1]);
+ *var_cc26t++ = vec_all_le(var_vec_u16[0], var_vec_b16[1]);
+ *var_cc26t++ = vec_all_le(var_vec_u16[0], var_vec_u16[1]);
+ *var_cc26t++ = vec_all_le(var_vec_u32[0], var_vec_b32[1]);
+ *var_cc26t++ = vec_all_le(var_vec_u32[0], var_vec_u32[1]);
+ *var_cc26t++ = vec_all_le(var_vec_u8[0], var_vec_b8[1]);
+ *var_cc26t++ = vec_all_le(var_vec_u8[0], var_vec_u8[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_b16[0], var_vec_b16[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_b16[0], var_vec_s16[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_b16[0], var_vec_u16[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_b32[0], var_vec_b32[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_b32[0], var_vec_s32[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_b32[0], var_vec_u32[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_b8[0], var_vec_b8[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_b8[0], var_vec_s8[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_b8[0], var_vec_u8[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_f32[0], var_vec_f32[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_p16[0], var_vec_p16[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_s16[0], var_vec_b16[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_s16[0], var_vec_s16[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_s32[0], var_vec_b32[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_s32[0], var_vec_s32[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_s8[0], var_vec_b8[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_s8[0], var_vec_s8[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_u16[0], var_vec_b16[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_u16[0], var_vec_u16[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_u32[0], var_vec_b32[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_u32[0], var_vec_u32[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_u8[0], var_vec_b8[1]);
+ *var_cc26t++ = vec_all_ne(var_vec_u8[0], var_vec_u8[1]);
+ *var_cc26t++ = vec_all_nge(var_vec_f32[0], var_vec_f32[1]);
+ *var_cc26t++ = vec_all_ngt(var_vec_f32[0], var_vec_f32[1]);
+ *var_cc26td++ = vec_all_nan(var_vec_f32[0]);
+ *var_cc26tr++ = vec_all_ge(var_vec_b16[0], var_vec_s16[1]);
+ *var_cc26tr++ = vec_all_ge(var_vec_b16[0], var_vec_u16[1]);
+ *var_cc26tr++ = vec_all_ge(var_vec_b32[0], var_vec_s32[1]);
+ *var_cc26tr++ = vec_all_ge(var_vec_b32[0], var_vec_u32[1]);
+ *var_cc26tr++ = vec_all_ge(var_vec_b8[0], var_vec_s8[1]);
+ *var_cc26tr++ = vec_all_ge(var_vec_b8[0], var_vec_u8[1]);
+ *var_cc26tr++ = vec_all_ge(var_vec_s16[0], var_vec_b16[1]);
+ *var_cc26tr++ = vec_all_ge(var_vec_s16[0], var_vec_s16[1]);
+ *var_cc26tr++ = vec_all_ge(var_vec_s32[0], var_vec_b32[1]);
+ *var_cc26tr++ = vec_all_ge(var_vec_s32[0], var_vec_s32[1]);
+ *var_cc26tr++ = vec_all_ge(var_vec_s8[0], var_vec_b8[1]);
+ *var_cc26tr++ = vec_all_ge(var_vec_s8[0], var_vec_s8[1]);
+ *var_cc26tr++ = vec_all_ge(var_vec_u16[0], var_vec_b16[1]);
+ *var_cc26tr++ = vec_all_ge(var_vec_u16[0], var_vec_u16[1]);
+ *var_cc26tr++ = vec_all_ge(var_vec_u32[0], var_vec_b32[1]);
+ *var_cc26tr++ = vec_all_ge(var_vec_u32[0], var_vec_u32[1]);
+ *var_cc26tr++ = vec_all_ge(var_vec_u8[0], var_vec_b8[1]);
+ *var_cc26tr++ = vec_all_ge(var_vec_u8[0], var_vec_u8[1]);
+ *var_cc26tr++ = vec_all_nle(var_vec_f32[0], var_vec_f32[1]);
+ *var_cc26tr++ = vec_all_nlt(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_b16++ = vec_and(var_vec_b16[0], var_vec_b16[1]);
+ *var_vec_b16++ = vec_andc(var_vec_b16[0], var_vec_b16[1]);
+ *var_vec_b16++ = vec_cmpeq(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_b16++ = vec_cmpeq(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_b16++ = vec_cmpgt(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_b16++ = vec_cmpgt(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_b16++ = vec_ld(var_int[0], var_vec_b16_ptr[1]);
+ *var_vec_b16++ = vec_ldl(var_int[0], var_vec_b16_ptr[1]);
+ *var_vec_b16++ = vec_lvx(var_int[0], var_vec_b16_ptr[1]);
+ *var_vec_b16++ = vec_lvxl(var_int[0], var_vec_b16_ptr[1]);
+ *var_vec_b16++ = vec_mergeh(var_vec_b16[0], var_vec_b16[1]);
+ *var_vec_b16++ = vec_mergel(var_vec_b16[0], var_vec_b16[1]);
+ *var_vec_b16++ = vec_nor(var_vec_b16[0], var_vec_b16[1]);
+ *var_vec_b16++ = vec_or(var_vec_b16[0], var_vec_b16[1]);
+ *var_vec_b16++ = vec_pack(var_vec_b32[0], var_vec_b32[1]);
+ *var_vec_b16++ = vec_perm(var_vec_b16[0], var_vec_b16[1], var_vec_u8[2]);
+ *var_vec_b16++ = vec_sel(var_vec_b16[0], var_vec_b16[1], var_vec_b16[2]);
+ *var_vec_b16++ = vec_sel(var_vec_b16[0], var_vec_b16[1], var_vec_u16[2]);
+ *var_vec_b16++ = vec_sll(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_b16++ = vec_sll(var_vec_b16[0], var_vec_u32[1]);
+ *var_vec_b16++ = vec_sll(var_vec_b16[0], var_vec_u8[1]);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 0);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 1);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 2);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 3);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 4);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 5);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 6);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 7);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 8);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 9);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 10);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 11);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 12);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 13);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 14);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 15);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 16);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 17);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 18);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 19);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 20);
+}
+void f3() {
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 21);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 22);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 23);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 24);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 25);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 26);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 27);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 28);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 29);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 30);
+ *var_vec_b16++ = vec_splat(var_vec_b16[0], 31);
+ *var_vec_b16++ = vec_srl(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_b16++ = vec_srl(var_vec_b16[0], var_vec_u32[1]);
+ *var_vec_b16++ = vec_srl(var_vec_b16[0], var_vec_u8[1]);
+ *var_vec_b16++ = vec_unpackh(var_vec_b8[0]);
+ *var_vec_b16++ = vec_unpackl(var_vec_b8[0]);
+ *var_vec_b16++ = vec_vand(var_vec_b16[0], var_vec_b16[1]);
+ *var_vec_b16++ = vec_vandc(var_vec_b16[0], var_vec_b16[1]);
+ *var_vec_b16++ = vec_vcmpequh(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_b16++ = vec_vcmpequh(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_b16++ = vec_vcmpgtsh(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_b16++ = vec_vcmpgtuh(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_b16++ = vec_vmrghh(var_vec_b16[0], var_vec_b16[1]);
+ *var_vec_b16++ = vec_vmrglh(var_vec_b16[0], var_vec_b16[1]);
+ *var_vec_b16++ = vec_vnor(var_vec_b16[0], var_vec_b16[1]);
+ *var_vec_b16++ = vec_vor(var_vec_b16[0], var_vec_b16[1]);
+ *var_vec_b16++ = vec_vperm(var_vec_b16[0], var_vec_b16[1], var_vec_u8[2]);
+ *var_vec_b16++ = vec_vpkuwum(var_vec_b32[0], var_vec_b32[1]);
+ *var_vec_b16++ = vec_vsel(var_vec_b16[0], var_vec_b16[1], var_vec_b16[2]);
+ *var_vec_b16++ = vec_vsel(var_vec_b16[0], var_vec_b16[1], var_vec_u16[2]);
+ *var_vec_b16++ = vec_vsl(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_b16++ = vec_vsl(var_vec_b16[0], var_vec_u32[1]);
+ *var_vec_b16++ = vec_vsl(var_vec_b16[0], var_vec_u8[1]);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 0);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 1);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 2);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 3);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 4);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 5);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 6);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 7);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 8);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 9);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 10);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 11);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 12);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 13);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 14);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 15);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 16);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 17);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 18);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 19);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 20);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 21);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 22);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 23);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 24);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 25);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 26);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 27);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 28);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 29);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 30);
+ *var_vec_b16++ = vec_vsplth(var_vec_b16[0], 31);
+ *var_vec_b16++ = vec_vsr(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_b16++ = vec_vsr(var_vec_b16[0], var_vec_u32[1]);
+ *var_vec_b16++ = vec_vsr(var_vec_b16[0], var_vec_u8[1]);
+ *var_vec_b16++ = vec_vupkhsb(var_vec_b8[0]);
+ *var_vec_b16++ = vec_vupklsb(var_vec_b8[0]);
+ *var_vec_b16++ = vec_vxor(var_vec_b16[0], var_vec_b16[1]);
+ *var_vec_b16++ = vec_xor(var_vec_b16[0], var_vec_b16[1]);
+ *var_vec_b32++ = vec_and(var_vec_b32[0], var_vec_b32[1]);
+ *var_vec_b32++ = vec_andc(var_vec_b32[0], var_vec_b32[1]);
+ *var_vec_b32++ = vec_cmpeq(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_b32++ = vec_cmpeq(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_b32++ = vec_cmpeq(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_b32++ = vec_cmpge(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_b32++ = vec_cmpgt(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_b32++ = vec_cmpgt(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_b32++ = vec_cmpgt(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_b32++ = vec_ld(var_int[0], var_vec_b32_ptr[1]);
+ *var_vec_b32++ = vec_ldl(var_int[0], var_vec_b32_ptr[1]);
+ *var_vec_b32++ = vec_lvx(var_int[0], var_vec_b32_ptr[1]);
+ *var_vec_b32++ = vec_lvxl(var_int[0], var_vec_b32_ptr[1]);
+ *var_vec_b32++ = vec_mergeh(var_vec_b32[0], var_vec_b32[1]);
+ *var_vec_b32++ = vec_mergel(var_vec_b32[0], var_vec_b32[1]);
+ *var_vec_b32++ = vec_nor(var_vec_b32[0], var_vec_b32[1]);
+ *var_vec_b32++ = vec_or(var_vec_b32[0], var_vec_b32[1]);
+ *var_vec_b32++ = vec_perm(var_vec_b32[0], var_vec_b32[1], var_vec_u8[2]);
+ *var_vec_b32++ = vec_sel(var_vec_b32[0], var_vec_b32[1], var_vec_b32[2]);
+ *var_vec_b32++ = vec_sel(var_vec_b32[0], var_vec_b32[1], var_vec_u32[2]);
+ *var_vec_b32++ = vec_sll(var_vec_b32[0], var_vec_u16[1]);
+ *var_vec_b32++ = vec_sll(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_b32++ = vec_sll(var_vec_b32[0], var_vec_u8[1]);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 0);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 1);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 2);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 3);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 4);
+}
+void f4() {
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 5);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 6);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 7);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 8);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 9);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 10);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 11);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 12);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 13);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 14);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 15);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 16);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 17);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 18);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 19);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 20);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 21);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 22);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 23);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 24);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 25);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 26);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 27);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 28);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 29);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 30);
+ *var_vec_b32++ = vec_splat(var_vec_b32[0], 31);
+ *var_vec_b32++ = vec_srl(var_vec_b32[0], var_vec_u16[1]);
+ *var_vec_b32++ = vec_srl(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_b32++ = vec_srl(var_vec_b32[0], var_vec_u8[1]);
+ *var_vec_b32++ = vec_unpackh(var_vec_b16[0]);
+ *var_vec_b32++ = vec_unpackl(var_vec_b16[0]);
+ *var_vec_b32++ = vec_vand(var_vec_b32[0], var_vec_b32[1]);
+ *var_vec_b32++ = vec_vandc(var_vec_b32[0], var_vec_b32[1]);
+ *var_vec_b32++ = vec_vcmpeqfp(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_b32++ = vec_vcmpequw(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_b32++ = vec_vcmpequw(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_b32++ = vec_vcmpgefp(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_b32++ = vec_vcmpgtfp(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_b32++ = vec_vcmpgtsw(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_b32++ = vec_vcmpgtuw(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_b32++ = vec_vmrghw(var_vec_b32[0], var_vec_b32[1]);
+ *var_vec_b32++ = vec_vmrglw(var_vec_b32[0], var_vec_b32[1]);
+ *var_vec_b32++ = vec_vnor(var_vec_b32[0], var_vec_b32[1]);
+ *var_vec_b32++ = vec_vor(var_vec_b32[0], var_vec_b32[1]);
+ *var_vec_b32++ = vec_vperm(var_vec_b32[0], var_vec_b32[1], var_vec_u8[2]);
+ *var_vec_b32++ = vec_vsel(var_vec_b32[0], var_vec_b32[1], var_vec_b32[2]);
+ *var_vec_b32++ = vec_vsel(var_vec_b32[0], var_vec_b32[1], var_vec_u32[2]);
+ *var_vec_b32++ = vec_vsl(var_vec_b32[0], var_vec_u16[1]);
+ *var_vec_b32++ = vec_vsl(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_b32++ = vec_vsl(var_vec_b32[0], var_vec_u8[1]);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 0);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 1);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 2);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 3);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 4);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 5);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 6);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 7);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 8);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 9);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 10);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 11);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 12);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 13);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 14);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 15);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 16);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 17);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 18);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 19);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 20);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 21);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 22);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 23);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 24);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 25);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 26);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 27);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 28);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 29);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 30);
+ *var_vec_b32++ = vec_vspltw(var_vec_b32[0], 31);
+ *var_vec_b32++ = vec_vsr(var_vec_b32[0], var_vec_u16[1]);
+ *var_vec_b32++ = vec_vsr(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_b32++ = vec_vsr(var_vec_b32[0], var_vec_u8[1]);
+ *var_vec_b32++ = vec_vupkhsh(var_vec_b16[0]);
+ *var_vec_b32++ = vec_vupklsh(var_vec_b16[0]);
+ *var_vec_b32++ = vec_vxor(var_vec_b32[0], var_vec_b32[1]);
+ *var_vec_b32++ = vec_xor(var_vec_b32[0], var_vec_b32[1]);
+ *var_vec_b8++ = vec_and(var_vec_b8[0], var_vec_b8[1]);
+ *var_vec_b8++ = vec_andc(var_vec_b8[0], var_vec_b8[1]);
+ *var_vec_b8++ = vec_cmpeq(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_b8++ = vec_cmpeq(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_b8++ = vec_cmpgt(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_b8++ = vec_cmpgt(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_b8++ = vec_ld(var_int[0], var_vec_b8_ptr[1]);
+ *var_vec_b8++ = vec_ldl(var_int[0], var_vec_b8_ptr[1]);
+ *var_vec_b8++ = vec_lvx(var_int[0], var_vec_b8_ptr[1]);
+ *var_vec_b8++ = vec_lvxl(var_int[0], var_vec_b8_ptr[1]);
+}
+void f5() {
+ *var_vec_b8++ = vec_mergeh(var_vec_b8[0], var_vec_b8[1]);
+ *var_vec_b8++ = vec_mergel(var_vec_b8[0], var_vec_b8[1]);
+ *var_vec_b8++ = vec_nor(var_vec_b8[0], var_vec_b8[1]);
+ *var_vec_b8++ = vec_or(var_vec_b8[0], var_vec_b8[1]);
+ *var_vec_b8++ = vec_pack(var_vec_b16[0], var_vec_b16[1]);
+ *var_vec_b8++ = vec_perm(var_vec_b8[0], var_vec_b8[1], var_vec_u8[2]);
+ *var_vec_b8++ = vec_sel(var_vec_b8[0], var_vec_b8[1], var_vec_b8[2]);
+ *var_vec_b8++ = vec_sel(var_vec_b8[0], var_vec_b8[1], var_vec_u8[2]);
+ *var_vec_b8++ = vec_sll(var_vec_b8[0], var_vec_u16[1]);
+ *var_vec_b8++ = vec_sll(var_vec_b8[0], var_vec_u32[1]);
+ *var_vec_b8++ = vec_sll(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 0);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 1);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 2);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 3);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 4);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 5);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 6);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 7);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 8);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 9);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 10);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 11);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 12);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 13);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 14);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 15);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 16);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 17);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 18);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 19);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 20);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 21);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 22);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 23);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 24);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 25);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 26);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 27);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 28);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 29);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 30);
+ *var_vec_b8++ = vec_splat(var_vec_b8[0], 31);
+ *var_vec_b8++ = vec_srl(var_vec_b8[0], var_vec_u16[1]);
+ *var_vec_b8++ = vec_srl(var_vec_b8[0], var_vec_u32[1]);
+ *var_vec_b8++ = vec_srl(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_b8++ = vec_vand(var_vec_b8[0], var_vec_b8[1]);
+ *var_vec_b8++ = vec_vandc(var_vec_b8[0], var_vec_b8[1]);
+ *var_vec_b8++ = vec_vcmpequb(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_b8++ = vec_vcmpequb(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_b8++ = vec_vcmpgtsb(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_b8++ = vec_vcmpgtub(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_b8++ = vec_vmrghb(var_vec_b8[0], var_vec_b8[1]);
+ *var_vec_b8++ = vec_vmrglb(var_vec_b8[0], var_vec_b8[1]);
+ *var_vec_b8++ = vec_vnor(var_vec_b8[0], var_vec_b8[1]);
+ *var_vec_b8++ = vec_vor(var_vec_b8[0], var_vec_b8[1]);
+ *var_vec_b8++ = vec_vperm(var_vec_b8[0], var_vec_b8[1], var_vec_u8[2]);
+ *var_vec_b8++ = vec_vpkuhum(var_vec_b16[0], var_vec_b16[1]);
+ *var_vec_b8++ = vec_vsel(var_vec_b8[0], var_vec_b8[1], var_vec_b8[2]);
+ *var_vec_b8++ = vec_vsel(var_vec_b8[0], var_vec_b8[1], var_vec_u8[2]);
+ *var_vec_b8++ = vec_vsl(var_vec_b8[0], var_vec_u16[1]);
+ *var_vec_b8++ = vec_vsl(var_vec_b8[0], var_vec_u32[1]);
+ *var_vec_b8++ = vec_vsl(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 0);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 1);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 2);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 3);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 4);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 5);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 6);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 7);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 8);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 9);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 10);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 11);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 12);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 13);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 14);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 15);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 16);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 17);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 18);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 19);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 20);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 21);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 22);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 23);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 24);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 25);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 26);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 27);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 28);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 29);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 30);
+ *var_vec_b8++ = vec_vspltb(var_vec_b8[0], 31);
+ *var_vec_b8++ = vec_vsr(var_vec_b8[0], var_vec_u16[1]);
+ *var_vec_b8++ = vec_vsr(var_vec_b8[0], var_vec_u32[1]);
+ *var_vec_b8++ = vec_vsr(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_b8++ = vec_vxor(var_vec_b8[0], var_vec_b8[1]);
+ *var_vec_b8++ = vec_xor(var_vec_b8[0], var_vec_b8[1]);
+}
+void f6() {
+ *var_vec_f32++ = vec_add(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_and(var_vec_b32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_and(var_vec_f32[0], var_vec_b32[1]);
+ *var_vec_f32++ = vec_and(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_andc(var_vec_b32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_andc(var_vec_f32[0], var_vec_b32[1]);
+ *var_vec_f32++ = vec_andc(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_ceil(var_vec_f32[0]);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 0);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 1);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 2);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 3);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 4);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 5);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 6);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 7);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 8);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 9);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 10);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 11);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 12);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 13);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 14);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 15);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 16);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 17);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 18);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 19);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 20);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 21);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 22);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 23);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 24);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 25);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 26);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 27);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 28);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 29);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 30);
+ *var_vec_f32++ = vec_ctf(var_vec_s32[0], 31);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 0);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 1);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 2);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 3);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 4);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 5);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 6);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 7);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 8);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 9);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 10);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 11);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 12);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 13);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 14);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 15);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 16);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 17);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 18);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 19);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 20);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 21);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 22);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 23);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 24);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 25);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 26);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 27);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 28);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 29);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 30);
+ *var_vec_f32++ = vec_ctf(var_vec_u32[0], 31);
+ *var_vec_f32++ = vec_expte(var_vec_f32[0]);
+ *var_vec_f32++ = vec_floor(var_vec_f32[0]);
+ *var_vec_f32++ = vec_ld(var_int[0], var_float_ptr[1]);
+ *var_vec_f32++ = vec_ld(var_int[0], var_vec_f32_ptr[1]);
+ *var_vec_f32++ = vec_lde(var_int[0], var_float_ptr[1]);
+ *var_vec_f32++ = vec_ldl(var_int[0], var_float_ptr[1]);
+ *var_vec_f32++ = vec_ldl(var_int[0], var_vec_f32_ptr[1]);
+ *var_vec_f32++ = vec_loge(var_vec_f32[0]);
+ *var_vec_f32++ = vec_lvewx(var_int[0], var_float_ptr[1]);
+ *var_vec_f32++ = vec_lvx(var_int[0], var_float_ptr[1]);
+ *var_vec_f32++ = vec_lvx(var_int[0], var_vec_f32_ptr[1]);
+ *var_vec_f32++ = vec_lvxl(var_int[0], var_float_ptr[1]);
+ *var_vec_f32++ = vec_lvxl(var_int[0], var_vec_f32_ptr[1]);
+ *var_vec_f32++ = vec_madd(var_vec_f32[0], var_vec_f32[1], var_vec_f32[2]);
+ *var_vec_f32++ = vec_max(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_mergeh(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_mergel(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_min(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_nmsub(var_vec_f32[0], var_vec_f32[1], var_vec_f32[2]);
+ *var_vec_f32++ = vec_nor(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_or(var_vec_b32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_or(var_vec_f32[0], var_vec_b32[1]);
+ *var_vec_f32++ = vec_or(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_perm(var_vec_f32[0], var_vec_f32[1], var_vec_u8[2]);
+ *var_vec_f32++ = vec_re(var_vec_f32[0]);
+ *var_vec_f32++ = vec_round(var_vec_f32[0]);
+ *var_vec_f32++ = vec_rsqrte(var_vec_f32[0]);
+ *var_vec_f32++ = vec_sel(var_vec_f32[0], var_vec_f32[1], var_vec_b32[2]);
+}
+void f7() {
+ *var_vec_f32++ = vec_sel(var_vec_f32[0], var_vec_f32[1], var_vec_u32[2]);
+ *var_vec_f32++ = vec_sld(var_vec_f32[0], var_vec_f32[1], 0);
+ *var_vec_f32++ = vec_sld(var_vec_f32[0], var_vec_f32[1], 1);
+ *var_vec_f32++ = vec_sld(var_vec_f32[0], var_vec_f32[1], 2);
+ *var_vec_f32++ = vec_sld(var_vec_f32[0], var_vec_f32[1], 3);
+ *var_vec_f32++ = vec_sld(var_vec_f32[0], var_vec_f32[1], 4);
+ *var_vec_f32++ = vec_sld(var_vec_f32[0], var_vec_f32[1], 5);
+ *var_vec_f32++ = vec_sld(var_vec_f32[0], var_vec_f32[1], 6);
+ *var_vec_f32++ = vec_sld(var_vec_f32[0], var_vec_f32[1], 7);
+ *var_vec_f32++ = vec_sld(var_vec_f32[0], var_vec_f32[1], 8);
+ *var_vec_f32++ = vec_sld(var_vec_f32[0], var_vec_f32[1], 9);
+ *var_vec_f32++ = vec_sld(var_vec_f32[0], var_vec_f32[1], 10);
+ *var_vec_f32++ = vec_sld(var_vec_f32[0], var_vec_f32[1], 11);
+ *var_vec_f32++ = vec_sld(var_vec_f32[0], var_vec_f32[1], 12);
+ *var_vec_f32++ = vec_sld(var_vec_f32[0], var_vec_f32[1], 13);
+ *var_vec_f32++ = vec_sld(var_vec_f32[0], var_vec_f32[1], 14);
+ *var_vec_f32++ = vec_sld(var_vec_f32[0], var_vec_f32[1], 15);
+ *var_vec_f32++ = vec_slo(var_vec_f32[0], var_vec_s8[1]);
+ *var_vec_f32++ = vec_slo(var_vec_f32[0], var_vec_u8[1]);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 0);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 1);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 2);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 3);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 4);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 5);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 6);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 7);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 8);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 9);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 10);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 11);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 12);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 13);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 14);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 15);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 16);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 17);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 18);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 19);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 20);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 21);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 22);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 23);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 24);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 25);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 26);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 27);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 28);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 29);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 30);
+ *var_vec_f32++ = vec_splat(var_vec_f32[0], 31);
+ *var_vec_f32++ = vec_sro(var_vec_f32[0], var_vec_s8[1]);
+ *var_vec_f32++ = vec_sro(var_vec_f32[0], var_vec_u8[1]);
+ *var_vec_f32++ = vec_sub(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_trunc(var_vec_f32[0]);
+ *var_vec_f32++ = vec_vaddfp(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_vand(var_vec_b32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_vand(var_vec_f32[0], var_vec_b32[1]);
+ *var_vec_f32++ = vec_vand(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_vandc(var_vec_b32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_vandc(var_vec_f32[0], var_vec_b32[1]);
+ *var_vec_f32++ = vec_vandc(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 0);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 1);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 2);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 3);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 4);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 5);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 6);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 7);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 8);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 9);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 10);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 11);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 12);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 13);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 14);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 15);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 16);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 17);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 18);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 19);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 20);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 21);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 22);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 23);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 24);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 25);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 26);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 27);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 28);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 29);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 30);
+ *var_vec_f32++ = vec_vcfsx(var_vec_s32[0], 31);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 0);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 1);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 2);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 3);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 4);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 5);
+}
+void f8() {
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 6);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 7);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 8);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 9);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 10);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 11);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 12);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 13);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 14);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 15);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 16);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 17);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 18);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 19);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 20);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 21);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 22);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 23);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 24);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 25);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 26);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 27);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 28);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 29);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 30);
+ *var_vec_f32++ = vec_vcfux(var_vec_u32[0], 31);
+ *var_vec_f32++ = vec_vexptefp(var_vec_f32[0]);
+ *var_vec_f32++ = vec_vlogefp(var_vec_f32[0]);
+ *var_vec_f32++ = vec_vmaddfp(var_vec_f32[0], var_vec_f32[1], var_vec_f32[2]);
+ *var_vec_f32++ = vec_vmaxfp(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_vminfp(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_vmrghw(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_vmrglw(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_vnmsubfp(var_vec_f32[0], var_vec_f32[1], var_vec_f32[2]);
+ *var_vec_f32++ = vec_vnor(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_vor(var_vec_b32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_vor(var_vec_f32[0], var_vec_b32[1]);
+ *var_vec_f32++ = vec_vor(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_vperm(var_vec_f32[0], var_vec_f32[1], var_vec_u8[2]);
+ *var_vec_f32++ = vec_vrefp(var_vec_f32[0]);
+ *var_vec_f32++ = vec_vrfim(var_vec_f32[0]);
+ *var_vec_f32++ = vec_vrfin(var_vec_f32[0]);
+ *var_vec_f32++ = vec_vrfip(var_vec_f32[0]);
+ *var_vec_f32++ = vec_vrfiz(var_vec_f32[0]);
+ *var_vec_f32++ = vec_vrsqrtefp(var_vec_f32[0]);
+ *var_vec_f32++ = vec_vsel(var_vec_f32[0], var_vec_f32[1], var_vec_b32[2]);
+ *var_vec_f32++ = vec_vsel(var_vec_f32[0], var_vec_f32[1], var_vec_u32[2]);
+ *var_vec_f32++ = vec_vsldoi(var_vec_f32[0], var_vec_f32[1], 0);
+ *var_vec_f32++ = vec_vsldoi(var_vec_f32[0], var_vec_f32[1], 1);
+ *var_vec_f32++ = vec_vsldoi(var_vec_f32[0], var_vec_f32[1], 2);
+ *var_vec_f32++ = vec_vsldoi(var_vec_f32[0], var_vec_f32[1], 3);
+ *var_vec_f32++ = vec_vsldoi(var_vec_f32[0], var_vec_f32[1], 4);
+ *var_vec_f32++ = vec_vsldoi(var_vec_f32[0], var_vec_f32[1], 5);
+ *var_vec_f32++ = vec_vsldoi(var_vec_f32[0], var_vec_f32[1], 6);
+ *var_vec_f32++ = vec_vsldoi(var_vec_f32[0], var_vec_f32[1], 7);
+ *var_vec_f32++ = vec_vsldoi(var_vec_f32[0], var_vec_f32[1], 8);
+ *var_vec_f32++ = vec_vsldoi(var_vec_f32[0], var_vec_f32[1], 9);
+ *var_vec_f32++ = vec_vsldoi(var_vec_f32[0], var_vec_f32[1], 10);
+ *var_vec_f32++ = vec_vsldoi(var_vec_f32[0], var_vec_f32[1], 11);
+ *var_vec_f32++ = vec_vsldoi(var_vec_f32[0], var_vec_f32[1], 12);
+ *var_vec_f32++ = vec_vsldoi(var_vec_f32[0], var_vec_f32[1], 13);
+ *var_vec_f32++ = vec_vsldoi(var_vec_f32[0], var_vec_f32[1], 14);
+ *var_vec_f32++ = vec_vsldoi(var_vec_f32[0], var_vec_f32[1], 15);
+ *var_vec_f32++ = vec_vslo(var_vec_f32[0], var_vec_s8[1]);
+ *var_vec_f32++ = vec_vslo(var_vec_f32[0], var_vec_u8[1]);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 0);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 1);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 2);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 3);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 4);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 5);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 6);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 7);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 8);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 9);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 10);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 11);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 12);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 13);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 14);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 15);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 16);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 17);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 18);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 19);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 20);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 21);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 22);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 23);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 24);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 25);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 26);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 27);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 28);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 29);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 30);
+ *var_vec_f32++ = vec_vspltw(var_vec_f32[0], 31);
+ *var_vec_f32++ = vec_vsro(var_vec_f32[0], var_vec_s8[1]);
+ *var_vec_f32++ = vec_vsro(var_vec_f32[0], var_vec_u8[1]);
+ *var_vec_f32++ = vec_vsubfp(var_vec_f32[0], var_vec_f32[1]);
+}
+void f9() {
+ *var_vec_f32++ = vec_vxor(var_vec_b32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_vxor(var_vec_f32[0], var_vec_b32[1]);
+ *var_vec_f32++ = vec_vxor(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_xor(var_vec_b32[0], var_vec_f32[1]);
+ *var_vec_f32++ = vec_xor(var_vec_f32[0], var_vec_b32[1]);
+ *var_vec_f32++ = vec_xor(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_p16++ = vec_ld(var_int[0], var_vec_p16_ptr[1]);
+ *var_vec_p16++ = vec_ldl(var_int[0], var_vec_p16_ptr[1]);
+ *var_vec_p16++ = vec_lvx(var_int[0], var_vec_p16_ptr[1]);
+ *var_vec_p16++ = vec_lvxl(var_int[0], var_vec_p16_ptr[1]);
+ *var_vec_p16++ = vec_mergeh(var_vec_p16[0], var_vec_p16[1]);
+ *var_vec_p16++ = vec_mergel(var_vec_p16[0], var_vec_p16[1]);
+ *var_vec_p16++ = vec_packpx(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_p16++ = vec_perm(var_vec_p16[0], var_vec_p16[1], var_vec_u8[2]);
+ *var_vec_p16++ = vec_sld(var_vec_p16[0], var_vec_p16[1], 0);
+ *var_vec_p16++ = vec_sld(var_vec_p16[0], var_vec_p16[1], 1);
+ *var_vec_p16++ = vec_sld(var_vec_p16[0], var_vec_p16[1], 2);
+ *var_vec_p16++ = vec_sld(var_vec_p16[0], var_vec_p16[1], 3);
+ *var_vec_p16++ = vec_sld(var_vec_p16[0], var_vec_p16[1], 4);
+ *var_vec_p16++ = vec_sld(var_vec_p16[0], var_vec_p16[1], 5);
+ *var_vec_p16++ = vec_sld(var_vec_p16[0], var_vec_p16[1], 6);
+ *var_vec_p16++ = vec_sld(var_vec_p16[0], var_vec_p16[1], 7);
+ *var_vec_p16++ = vec_sld(var_vec_p16[0], var_vec_p16[1], 8);
+ *var_vec_p16++ = vec_sld(var_vec_p16[0], var_vec_p16[1], 9);
+ *var_vec_p16++ = vec_sld(var_vec_p16[0], var_vec_p16[1], 10);
+ *var_vec_p16++ = vec_sld(var_vec_p16[0], var_vec_p16[1], 11);
+ *var_vec_p16++ = vec_sld(var_vec_p16[0], var_vec_p16[1], 12);
+ *var_vec_p16++ = vec_sld(var_vec_p16[0], var_vec_p16[1], 13);
+ *var_vec_p16++ = vec_sld(var_vec_p16[0], var_vec_p16[1], 14);
+ *var_vec_p16++ = vec_sld(var_vec_p16[0], var_vec_p16[1], 15);
+ *var_vec_p16++ = vec_sll(var_vec_p16[0], var_vec_u16[1]);
+ *var_vec_p16++ = vec_sll(var_vec_p16[0], var_vec_u32[1]);
+ *var_vec_p16++ = vec_sll(var_vec_p16[0], var_vec_u8[1]);
+ *var_vec_p16++ = vec_slo(var_vec_p16[0], var_vec_s8[1]);
+ *var_vec_p16++ = vec_slo(var_vec_p16[0], var_vec_u8[1]);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 0);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 1);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 2);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 3);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 4);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 5);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 6);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 7);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 8);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 9);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 10);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 11);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 12);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 13);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 14);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 15);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 16);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 17);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 18);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 19);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 20);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 21);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 22);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 23);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 24);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 25);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 26);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 27);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 28);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 29);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 30);
+ *var_vec_p16++ = vec_splat(var_vec_p16[0], 31);
+ *var_vec_p16++ = vec_srl(var_vec_p16[0], var_vec_u16[1]);
+ *var_vec_p16++ = vec_srl(var_vec_p16[0], var_vec_u32[1]);
+ *var_vec_p16++ = vec_srl(var_vec_p16[0], var_vec_u8[1]);
+ *var_vec_p16++ = vec_sro(var_vec_p16[0], var_vec_s8[1]);
+ *var_vec_p16++ = vec_sro(var_vec_p16[0], var_vec_u8[1]);
+ *var_vec_p16++ = vec_vmrghh(var_vec_p16[0], var_vec_p16[1]);
+ *var_vec_p16++ = vec_vmrglh(var_vec_p16[0], var_vec_p16[1]);
+ *var_vec_p16++ = vec_vperm(var_vec_p16[0], var_vec_p16[1], var_vec_u8[2]);
+ *var_vec_p16++ = vec_vpkpx(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_p16++ = vec_vsl(var_vec_p16[0], var_vec_u16[1]);
+ *var_vec_p16++ = vec_vsl(var_vec_p16[0], var_vec_u32[1]);
+ *var_vec_p16++ = vec_vsl(var_vec_p16[0], var_vec_u8[1]);
+ *var_vec_p16++ = vec_vsldoi(var_vec_p16[0], var_vec_p16[1], 0);
+ *var_vec_p16++ = vec_vsldoi(var_vec_p16[0], var_vec_p16[1], 1);
+ *var_vec_p16++ = vec_vsldoi(var_vec_p16[0], var_vec_p16[1], 2);
+ *var_vec_p16++ = vec_vsldoi(var_vec_p16[0], var_vec_p16[1], 3);
+ *var_vec_p16++ = vec_vsldoi(var_vec_p16[0], var_vec_p16[1], 4);
+ *var_vec_p16++ = vec_vsldoi(var_vec_p16[0], var_vec_p16[1], 5);
+ *var_vec_p16++ = vec_vsldoi(var_vec_p16[0], var_vec_p16[1], 6);
+ *var_vec_p16++ = vec_vsldoi(var_vec_p16[0], var_vec_p16[1], 7);
+ *var_vec_p16++ = vec_vsldoi(var_vec_p16[0], var_vec_p16[1], 8);
+ *var_vec_p16++ = vec_vsldoi(var_vec_p16[0], var_vec_p16[1], 9);
+ *var_vec_p16++ = vec_vsldoi(var_vec_p16[0], var_vec_p16[1], 10);
+ *var_vec_p16++ = vec_vsldoi(var_vec_p16[0], var_vec_p16[1], 11);
+ *var_vec_p16++ = vec_vsldoi(var_vec_p16[0], var_vec_p16[1], 12);
+ *var_vec_p16++ = vec_vsldoi(var_vec_p16[0], var_vec_p16[1], 13);
+ *var_vec_p16++ = vec_vsldoi(var_vec_p16[0], var_vec_p16[1], 14);
+ *var_vec_p16++ = vec_vsldoi(var_vec_p16[0], var_vec_p16[1], 15);
+ *var_vec_p16++ = vec_vslo(var_vec_p16[0], var_vec_s8[1]);
+ *var_vec_p16++ = vec_vslo(var_vec_p16[0], var_vec_u8[1]);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 0);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 1);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 2);
+}
+void f10() {
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 3);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 4);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 5);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 6);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 7);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 8);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 9);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 10);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 11);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 12);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 13);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 14);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 15);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 16);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 17);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 18);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 19);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 20);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 21);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 22);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 23);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 24);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 25);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 26);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 27);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 28);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 29);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 30);
+ *var_vec_p16++ = vec_vsplth(var_vec_p16[0], 31);
+ *var_vec_p16++ = vec_vsr(var_vec_p16[0], var_vec_u16[1]);
+ *var_vec_p16++ = vec_vsr(var_vec_p16[0], var_vec_u32[1]);
+ *var_vec_p16++ = vec_vsr(var_vec_p16[0], var_vec_u8[1]);
+ *var_vec_p16++ = vec_vsro(var_vec_p16[0], var_vec_s8[1]);
+ *var_vec_p16++ = vec_vsro(var_vec_p16[0], var_vec_u8[1]);
+ *var_vec_s16++ = vec_add(var_vec_b16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_add(var_vec_s16[0], var_vec_b16[1]);
+ *var_vec_s16++ = vec_add(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_adds(var_vec_b16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_adds(var_vec_s16[0], var_vec_b16[1]);
+ *var_vec_s16++ = vec_adds(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_and(var_vec_b16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_and(var_vec_s16[0], var_vec_b16[1]);
+ *var_vec_s16++ = vec_and(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_andc(var_vec_b16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_andc(var_vec_s16[0], var_vec_b16[1]);
+ *var_vec_s16++ = vec_andc(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_avg(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_ld(var_int[0], var_short_ptr[1]);
+ *var_vec_s16++ = vec_ld(var_int[0], var_vec_s16_ptr[1]);
+ *var_vec_s16++ = vec_lde(var_int[0], var_short_ptr[1]);
+ *var_vec_s16++ = vec_ldl(var_int[0], var_short_ptr[1]);
+ *var_vec_s16++ = vec_ldl(var_int[0], var_vec_s16_ptr[1]);
+ *var_vec_s16++ = vec_lvehx(var_int[0], var_short_ptr[1]);
+ *var_vec_s16++ = vec_lvx(var_int[0], var_short_ptr[1]);
+ *var_vec_s16++ = vec_lvx(var_int[0], var_vec_s16_ptr[1]);
+ *var_vec_s16++ = vec_lvxl(var_int[0], var_short_ptr[1]);
+ *var_vec_s16++ = vec_lvxl(var_int[0], var_vec_s16_ptr[1]);
+ *var_vec_s16++ = vec_madds(var_vec_s16[0], var_vec_s16[1], var_vec_s16[2]);
+ *var_vec_s16++ = vec_max(var_vec_b16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_max(var_vec_s16[0], var_vec_b16[1]);
+ *var_vec_s16++ = vec_max(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_mergeh(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_mergel(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_min(var_vec_b16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_min(var_vec_s16[0], var_vec_b16[1]);
+ *var_vec_s16++ = vec_min(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_mladd(var_vec_s16[0], var_vec_s16[1], var_vec_s16[2]);
+ *var_vec_s16++ = vec_mladd(var_vec_s16[0], var_vec_u16[1], var_vec_u16[2]);
+ *var_vec_s16++ = vec_mladd(var_vec_u16[0], var_vec_s16[1], var_vec_s16[2]);
+ *var_vec_s16++ = vec_mradds(var_vec_s16[0], var_vec_s16[1], var_vec_s16[2]);
+ *var_vec_s16++ = vec_mule(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s16++ = vec_mulo(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s16++ = vec_nor(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_or(var_vec_b16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_or(var_vec_s16[0], var_vec_b16[1]);
+ *var_vec_s16++ = vec_or(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_pack(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s16++ = vec_packs(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s16++ = vec_perm(var_vec_s16[0], var_vec_s16[1], var_vec_u8[2]);
+ *var_vec_s16++ = vec_rl(var_vec_s16[0], var_vec_u16[1]);
+ *var_vec_s16++ = vec_sel(var_vec_s16[0], var_vec_s16[1], var_vec_b16[2]);
+ *var_vec_s16++ = vec_sel(var_vec_s16[0], var_vec_s16[1], var_vec_u16[2]);
+ *var_vec_s16++ = vec_sl(var_vec_s16[0], var_vec_u16[1]);
+ *var_vec_s16++ = vec_sld(var_vec_s16[0], var_vec_s16[1], 0);
+ *var_vec_s16++ = vec_sld(var_vec_s16[0], var_vec_s16[1], 1);
+ *var_vec_s16++ = vec_sld(var_vec_s16[0], var_vec_s16[1], 2);
+ *var_vec_s16++ = vec_sld(var_vec_s16[0], var_vec_s16[1], 3);
+ *var_vec_s16++ = vec_sld(var_vec_s16[0], var_vec_s16[1], 4);
+ *var_vec_s16++ = vec_sld(var_vec_s16[0], var_vec_s16[1], 5);
+ *var_vec_s16++ = vec_sld(var_vec_s16[0], var_vec_s16[1], 6);
+ *var_vec_s16++ = vec_sld(var_vec_s16[0], var_vec_s16[1], 7);
+ *var_vec_s16++ = vec_sld(var_vec_s16[0], var_vec_s16[1], 8);
+ *var_vec_s16++ = vec_sld(var_vec_s16[0], var_vec_s16[1], 9);
+ *var_vec_s16++ = vec_sld(var_vec_s16[0], var_vec_s16[1], 10);
+ *var_vec_s16++ = vec_sld(var_vec_s16[0], var_vec_s16[1], 11);
+ *var_vec_s16++ = vec_sld(var_vec_s16[0], var_vec_s16[1], 12);
+ *var_vec_s16++ = vec_sld(var_vec_s16[0], var_vec_s16[1], 13);
+ *var_vec_s16++ = vec_sld(var_vec_s16[0], var_vec_s16[1], 14);
+ *var_vec_s16++ = vec_sld(var_vec_s16[0], var_vec_s16[1], 15);
+ *var_vec_s16++ = vec_sll(var_vec_s16[0], var_vec_u16[1]);
+}
+void f11() {
+ *var_vec_s16++ = vec_sll(var_vec_s16[0], var_vec_u32[1]);
+ *var_vec_s16++ = vec_sll(var_vec_s16[0], var_vec_u8[1]);
+ *var_vec_s16++ = vec_slo(var_vec_s16[0], var_vec_s8[1]);
+ *var_vec_s16++ = vec_slo(var_vec_s16[0], var_vec_u8[1]);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 0);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 1);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 2);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 3);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 4);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 5);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 6);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 7);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 8);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 9);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 10);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 11);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 12);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 13);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 14);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 15);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 16);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 17);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 18);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 19);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 20);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 21);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 22);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 23);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 24);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 25);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 26);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 27);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 28);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 29);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 30);
+ *var_vec_s16++ = vec_splat(var_vec_s16[0], 31);
+ *var_vec_s16++ = vec_splat_s16( 0);
+ *var_vec_s16++ = vec_splat_s16( 1);
+ *var_vec_s16++ = vec_splat_s16( 2);
+ *var_vec_s16++ = vec_splat_s16( 3);
+ *var_vec_s16++ = vec_splat_s16( 4);
+ *var_vec_s16++ = vec_splat_s16( 5);
+ *var_vec_s16++ = vec_splat_s16( 6);
+ *var_vec_s16++ = vec_splat_s16( 7);
+ *var_vec_s16++ = vec_splat_s16( 8);
+ *var_vec_s16++ = vec_splat_s16( 9);
+ *var_vec_s16++ = vec_splat_s16( -1);
+ *var_vec_s16++ = vec_splat_s16( -2);
+ *var_vec_s16++ = vec_splat_s16( -3);
+ *var_vec_s16++ = vec_splat_s16( -4);
+ *var_vec_s16++ = vec_splat_s16( -5);
+ *var_vec_s16++ = vec_splat_s16( -6);
+ *var_vec_s16++ = vec_splat_s16( -7);
+ *var_vec_s16++ = vec_splat_s16( -8);
+ *var_vec_s16++ = vec_splat_s16( -9);
+ *var_vec_s16++ = vec_splat_s16( 10);
+ *var_vec_s16++ = vec_splat_s16( 11);
+ *var_vec_s16++ = vec_splat_s16( 12);
+ *var_vec_s16++ = vec_splat_s16( 13);
+ *var_vec_s16++ = vec_splat_s16( 14);
+ *var_vec_s16++ = vec_splat_s16( 15);
+ *var_vec_s16++ = vec_splat_s16(-10);
+ *var_vec_s16++ = vec_splat_s16(-11);
+ *var_vec_s16++ = vec_splat_s16(-12);
+ *var_vec_s16++ = vec_splat_s16(-13);
+ *var_vec_s16++ = vec_splat_s16(-14);
+ *var_vec_s16++ = vec_splat_s16(-15);
+ *var_vec_s16++ = vec_splat_s16(-16);
+ *var_vec_s16++ = vec_sr(var_vec_s16[0], var_vec_u16[1]);
+ *var_vec_s16++ = vec_sra(var_vec_s16[0], var_vec_u16[1]);
+ *var_vec_s16++ = vec_srl(var_vec_s16[0], var_vec_u16[1]);
+ *var_vec_s16++ = vec_srl(var_vec_s16[0], var_vec_u32[1]);
+ *var_vec_s16++ = vec_srl(var_vec_s16[0], var_vec_u8[1]);
+ *var_vec_s16++ = vec_sro(var_vec_s16[0], var_vec_s8[1]);
+ *var_vec_s16++ = vec_sro(var_vec_s16[0], var_vec_u8[1]);
+ *var_vec_s16++ = vec_sub(var_vec_b16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_sub(var_vec_s16[0], var_vec_b16[1]);
+ *var_vec_s16++ = vec_sub(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_subs(var_vec_b16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_subs(var_vec_s16[0], var_vec_b16[1]);
+ *var_vec_s16++ = vec_subs(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_unpackh(var_vec_s8[0]);
+ *var_vec_s16++ = vec_unpackl(var_vec_s8[0]);
+ *var_vec_s16++ = vec_vaddshs(var_vec_b16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vaddshs(var_vec_s16[0], var_vec_b16[1]);
+ *var_vec_s16++ = vec_vaddshs(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vadduhm(var_vec_b16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vadduhm(var_vec_s16[0], var_vec_b16[1]);
+ *var_vec_s16++ = vec_vadduhm(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vand(var_vec_b16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vand(var_vec_s16[0], var_vec_b16[1]);
+ *var_vec_s16++ = vec_vand(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vandc(var_vec_b16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vandc(var_vec_s16[0], var_vec_b16[1]);
+ *var_vec_s16++ = vec_vandc(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vavgsh(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vmaxsh(var_vec_b16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vmaxsh(var_vec_s16[0], var_vec_b16[1]);
+}
+void f12() {
+ *var_vec_s16++ = vec_vmaxsh(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vmhaddshs(var_vec_s16[0], var_vec_s16[1], var_vec_s16[2]);
+ *var_vec_s16++ = vec_vmhraddshs(var_vec_s16[0], var_vec_s16[1], var_vec_s16[2]);
+ *var_vec_s16++ = vec_vminsh(var_vec_b16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vminsh(var_vec_s16[0], var_vec_b16[1]);
+ *var_vec_s16++ = vec_vminsh(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vmladduhm(var_vec_s16[0], var_vec_s16[1], var_vec_s16[2]);
+ *var_vec_s16++ = vec_vmladduhm(var_vec_s16[0], var_vec_u16[1], var_vec_u16[2]);
+ *var_vec_s16++ = vec_vmladduhm(var_vec_u16[0], var_vec_s16[1], var_vec_s16[2]);
+ *var_vec_s16++ = vec_vmrghh(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vmrglh(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vmulesb(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s16++ = vec_vmulosb(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s16++ = vec_vnor(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vor(var_vec_b16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vor(var_vec_s16[0], var_vec_b16[1]);
+ *var_vec_s16++ = vec_vor(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vperm(var_vec_s16[0], var_vec_s16[1], var_vec_u8[2]);
+ *var_vec_s16++ = vec_vpkswss(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s16++ = vec_vpkuwum(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s16++ = vec_vrlh(var_vec_s16[0], var_vec_u16[1]);
+ *var_vec_s16++ = vec_vsel(var_vec_s16[0], var_vec_s16[1], var_vec_b16[2]);
+ *var_vec_s16++ = vec_vsel(var_vec_s16[0], var_vec_s16[1], var_vec_u16[2]);
+ *var_vec_s16++ = vec_vsl(var_vec_s16[0], var_vec_u16[1]);
+ *var_vec_s16++ = vec_vsl(var_vec_s16[0], var_vec_u32[1]);
+ *var_vec_s16++ = vec_vsl(var_vec_s16[0], var_vec_u8[1]);
+ *var_vec_s16++ = vec_vsldoi(var_vec_s16[0], var_vec_s16[1], 0);
+ *var_vec_s16++ = vec_vsldoi(var_vec_s16[0], var_vec_s16[1], 1);
+ *var_vec_s16++ = vec_vsldoi(var_vec_s16[0], var_vec_s16[1], 2);
+ *var_vec_s16++ = vec_vsldoi(var_vec_s16[0], var_vec_s16[1], 3);
+ *var_vec_s16++ = vec_vsldoi(var_vec_s16[0], var_vec_s16[1], 4);
+ *var_vec_s16++ = vec_vsldoi(var_vec_s16[0], var_vec_s16[1], 5);
+ *var_vec_s16++ = vec_vsldoi(var_vec_s16[0], var_vec_s16[1], 6);
+ *var_vec_s16++ = vec_vsldoi(var_vec_s16[0], var_vec_s16[1], 7);
+ *var_vec_s16++ = vec_vsldoi(var_vec_s16[0], var_vec_s16[1], 8);
+ *var_vec_s16++ = vec_vsldoi(var_vec_s16[0], var_vec_s16[1], 9);
+ *var_vec_s16++ = vec_vsldoi(var_vec_s16[0], var_vec_s16[1], 10);
+ *var_vec_s16++ = vec_vsldoi(var_vec_s16[0], var_vec_s16[1], 11);
+ *var_vec_s16++ = vec_vsldoi(var_vec_s16[0], var_vec_s16[1], 12);
+ *var_vec_s16++ = vec_vsldoi(var_vec_s16[0], var_vec_s16[1], 13);
+ *var_vec_s16++ = vec_vsldoi(var_vec_s16[0], var_vec_s16[1], 14);
+ *var_vec_s16++ = vec_vsldoi(var_vec_s16[0], var_vec_s16[1], 15);
+ *var_vec_s16++ = vec_vslh(var_vec_s16[0], var_vec_u16[1]);
+ *var_vec_s16++ = vec_vslo(var_vec_s16[0], var_vec_s8[1]);
+ *var_vec_s16++ = vec_vslo(var_vec_s16[0], var_vec_u8[1]);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 0);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 1);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 2);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 3);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 4);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 5);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 6);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 7);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 8);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 9);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 10);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 11);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 12);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 13);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 14);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 15);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 16);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 17);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 18);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 19);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 20);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 21);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 22);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 23);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 24);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 25);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 26);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 27);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 28);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 29);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 30);
+ *var_vec_s16++ = vec_vsplth(var_vec_s16[0], 31);
+ *var_vec_s16++ = vec_vspltish( 0);
+ *var_vec_s16++ = vec_vspltish( 1);
+ *var_vec_s16++ = vec_vspltish( 2);
+ *var_vec_s16++ = vec_vspltish( 3);
+ *var_vec_s16++ = vec_vspltish( 4);
+ *var_vec_s16++ = vec_vspltish( 5);
+ *var_vec_s16++ = vec_vspltish( 6);
+ *var_vec_s16++ = vec_vspltish( 7);
+ *var_vec_s16++ = vec_vspltish( 8);
+ *var_vec_s16++ = vec_vspltish( 9);
+ *var_vec_s16++ = vec_vspltish( -1);
+ *var_vec_s16++ = vec_vspltish( -2);
+ *var_vec_s16++ = vec_vspltish( -3);
+ *var_vec_s16++ = vec_vspltish( -4);
+ *var_vec_s16++ = vec_vspltish( -5);
+ *var_vec_s16++ = vec_vspltish( -6);
+ *var_vec_s16++ = vec_vspltish( -7);
+ *var_vec_s16++ = vec_vspltish( -8);
+ *var_vec_s16++ = vec_vspltish( -9);
+ *var_vec_s16++ = vec_vspltish( 10);
+ *var_vec_s16++ = vec_vspltish( 11);
+ *var_vec_s16++ = vec_vspltish( 12);
+ *var_vec_s16++ = vec_vspltish( 13);
+}
+void f13() {
+ *var_vec_s16++ = vec_vspltish( 14);
+ *var_vec_s16++ = vec_vspltish( 15);
+ *var_vec_s16++ = vec_vspltish(-10);
+ *var_vec_s16++ = vec_vspltish(-11);
+ *var_vec_s16++ = vec_vspltish(-12);
+ *var_vec_s16++ = vec_vspltish(-13);
+ *var_vec_s16++ = vec_vspltish(-14);
+ *var_vec_s16++ = vec_vspltish(-15);
+ *var_vec_s16++ = vec_vspltish(-16);
+ *var_vec_s16++ = vec_vsr(var_vec_s16[0], var_vec_u16[1]);
+ *var_vec_s16++ = vec_vsr(var_vec_s16[0], var_vec_u32[1]);
+ *var_vec_s16++ = vec_vsr(var_vec_s16[0], var_vec_u8[1]);
+ *var_vec_s16++ = vec_vsrah(var_vec_s16[0], var_vec_u16[1]);
+ *var_vec_s16++ = vec_vsrh(var_vec_s16[0], var_vec_u16[1]);
+ *var_vec_s16++ = vec_vsro(var_vec_s16[0], var_vec_s8[1]);
+ *var_vec_s16++ = vec_vsro(var_vec_s16[0], var_vec_u8[1]);
+ *var_vec_s16++ = vec_vsubshs(var_vec_b16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vsubshs(var_vec_s16[0], var_vec_b16[1]);
+ *var_vec_s16++ = vec_vsubshs(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vsubuhm(var_vec_b16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vsubuhm(var_vec_s16[0], var_vec_b16[1]);
+ *var_vec_s16++ = vec_vsubuhm(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vupkhsb(var_vec_s8[0]);
+ *var_vec_s16++ = vec_vupklsb(var_vec_s8[0]);
+ *var_vec_s16++ = vec_vxor(var_vec_b16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_vxor(var_vec_s16[0], var_vec_b16[1]);
+ *var_vec_s16++ = vec_vxor(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_xor(var_vec_b16[0], var_vec_s16[1]);
+ *var_vec_s16++ = vec_xor(var_vec_s16[0], var_vec_b16[1]);
+ *var_vec_s16++ = vec_xor(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s32++ = vec_add(var_vec_b32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_add(var_vec_s32[0], var_vec_b32[1]);
+ *var_vec_s32++ = vec_add(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_adds(var_vec_b32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_adds(var_vec_s32[0], var_vec_b32[1]);
+ *var_vec_s32++ = vec_adds(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_and(var_vec_b32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_and(var_vec_s32[0], var_vec_b32[1]);
+ *var_vec_s32++ = vec_and(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_andc(var_vec_b32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_andc(var_vec_s32[0], var_vec_b32[1]);
+ *var_vec_s32++ = vec_andc(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_avg(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_cmpb(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 0);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 1);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 2);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 3);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 4);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 5);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 6);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 7);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 8);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 9);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 10);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 11);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 12);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 13);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 14);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 15);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 16);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 17);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 18);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 19);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 20);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 21);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 22);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 23);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 24);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 25);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 26);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 27);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 28);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 29);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 30);
+ *var_vec_s32++ = vec_cts(var_vec_f32[0], 31);
+ *var_vec_s32++ = vec_ld(var_int[0], var_int_ptr[1]);
+ *var_vec_s32++ = vec_ld(var_int[0], var_long_ptr[1]);
+ *var_vec_s32++ = vec_ld(var_int[0], var_vec_s32_ptr[1]);
+ *var_vec_s32++ = vec_lde(var_int[0], var_int_ptr[1]);
+ *var_vec_s32++ = vec_lde(var_int[0], var_long_ptr[1]);
+ *var_vec_s32++ = vec_ldl(var_int[0], var_int_ptr[1]);
+ *var_vec_s32++ = vec_ldl(var_int[0], var_long_ptr[1]);
+ *var_vec_s32++ = vec_ldl(var_int[0], var_vec_s32_ptr[1]);
+ *var_vec_s32++ = vec_lvewx(var_int[0], var_int_ptr[1]);
+ *var_vec_s32++ = vec_lvewx(var_int[0], var_long_ptr[1]);
+ *var_vec_s32++ = vec_lvx(var_int[0], var_int_ptr[1]);
+ *var_vec_s32++ = vec_lvx(var_int[0], var_long_ptr[1]);
+ *var_vec_s32++ = vec_lvx(var_int[0], var_vec_s32_ptr[1]);
+ *var_vec_s32++ = vec_lvxl(var_int[0], var_int_ptr[1]);
+ *var_vec_s32++ = vec_lvxl(var_int[0], var_long_ptr[1]);
+ *var_vec_s32++ = vec_lvxl(var_int[0], var_vec_s32_ptr[1]);
+ *var_vec_s32++ = vec_max(var_vec_b32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_max(var_vec_s32[0], var_vec_b32[1]);
+ *var_vec_s32++ = vec_max(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_mergeh(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_mergel(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_min(var_vec_b32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_min(var_vec_s32[0], var_vec_b32[1]);
+ *var_vec_s32++ = vec_min(var_vec_s32[0], var_vec_s32[1]);
+}
+void f14() {
+ *var_vec_s32++ = vec_msum(var_vec_s16[0], var_vec_s16[1], var_vec_s32[2]);
+ *var_vec_s32++ = vec_msum(var_vec_s8[0], var_vec_u8[1], var_vec_s32[2]);
+ *var_vec_s32++ = vec_msums(var_vec_s16[0], var_vec_s16[1], var_vec_s32[2]);
+ *var_vec_s32++ = vec_mule(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s32++ = vec_mulo(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s32++ = vec_nor(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_or(var_vec_b32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_or(var_vec_s32[0], var_vec_b32[1]);
+ *var_vec_s32++ = vec_or(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_perm(var_vec_s32[0], var_vec_s32[1], var_vec_u8[2]);
+ *var_vec_s32++ = vec_rl(var_vec_s32[0], var_vec_u32[1]);
+ *var_vec_s32++ = vec_sel(var_vec_s32[0], var_vec_s32[1], var_vec_b32[2]);
+ *var_vec_s32++ = vec_sel(var_vec_s32[0], var_vec_s32[1], var_vec_u32[2]);
+ *var_vec_s32++ = vec_sl(var_vec_s32[0], var_vec_u32[1]);
+ *var_vec_s32++ = vec_sld(var_vec_s32[0], var_vec_s32[1], 0);
+ *var_vec_s32++ = vec_sld(var_vec_s32[0], var_vec_s32[1], 1);
+ *var_vec_s32++ = vec_sld(var_vec_s32[0], var_vec_s32[1], 2);
+ *var_vec_s32++ = vec_sld(var_vec_s32[0], var_vec_s32[1], 3);
+ *var_vec_s32++ = vec_sld(var_vec_s32[0], var_vec_s32[1], 4);
+ *var_vec_s32++ = vec_sld(var_vec_s32[0], var_vec_s32[1], 5);
+ *var_vec_s32++ = vec_sld(var_vec_s32[0], var_vec_s32[1], 6);
+ *var_vec_s32++ = vec_sld(var_vec_s32[0], var_vec_s32[1], 7);
+ *var_vec_s32++ = vec_sld(var_vec_s32[0], var_vec_s32[1], 8);
+ *var_vec_s32++ = vec_sld(var_vec_s32[0], var_vec_s32[1], 9);
+ *var_vec_s32++ = vec_sld(var_vec_s32[0], var_vec_s32[1], 10);
+ *var_vec_s32++ = vec_sld(var_vec_s32[0], var_vec_s32[1], 11);
+ *var_vec_s32++ = vec_sld(var_vec_s32[0], var_vec_s32[1], 12);
+ *var_vec_s32++ = vec_sld(var_vec_s32[0], var_vec_s32[1], 13);
+ *var_vec_s32++ = vec_sld(var_vec_s32[0], var_vec_s32[1], 14);
+ *var_vec_s32++ = vec_sld(var_vec_s32[0], var_vec_s32[1], 15);
+ *var_vec_s32++ = vec_sll(var_vec_s32[0], var_vec_u16[1]);
+ *var_vec_s32++ = vec_sll(var_vec_s32[0], var_vec_u32[1]);
+ *var_vec_s32++ = vec_sll(var_vec_s32[0], var_vec_u8[1]);
+ *var_vec_s32++ = vec_slo(var_vec_s32[0], var_vec_s8[1]);
+ *var_vec_s32++ = vec_slo(var_vec_s32[0], var_vec_u8[1]);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 0);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 1);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 2);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 3);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 4);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 5);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 6);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 7);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 8);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 9);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 10);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 11);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 12);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 13);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 14);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 15);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 16);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 17);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 18);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 19);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 20);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 21);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 22);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 23);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 24);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 25);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 26);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 27);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 28);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 29);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 30);
+ *var_vec_s32++ = vec_splat(var_vec_s32[0], 31);
+ *var_vec_s32++ = vec_splat_s32( 0);
+ *var_vec_s32++ = vec_splat_s32( 1);
+ *var_vec_s32++ = vec_splat_s32( 2);
+ *var_vec_s32++ = vec_splat_s32( 3);
+ *var_vec_s32++ = vec_splat_s32( 4);
+ *var_vec_s32++ = vec_splat_s32( 5);
+ *var_vec_s32++ = vec_splat_s32( 6);
+ *var_vec_s32++ = vec_splat_s32( 7);
+ *var_vec_s32++ = vec_splat_s32( 8);
+ *var_vec_s32++ = vec_splat_s32( 9);
+ *var_vec_s32++ = vec_splat_s32( -1);
+ *var_vec_s32++ = vec_splat_s32( -2);
+ *var_vec_s32++ = vec_splat_s32( -3);
+ *var_vec_s32++ = vec_splat_s32( -4);
+ *var_vec_s32++ = vec_splat_s32( -5);
+ *var_vec_s32++ = vec_splat_s32( -6);
+ *var_vec_s32++ = vec_splat_s32( -7);
+ *var_vec_s32++ = vec_splat_s32( -8);
+ *var_vec_s32++ = vec_splat_s32( -9);
+ *var_vec_s32++ = vec_splat_s32( 10);
+ *var_vec_s32++ = vec_splat_s32( 11);
+ *var_vec_s32++ = vec_splat_s32( 12);
+ *var_vec_s32++ = vec_splat_s32( 13);
+ *var_vec_s32++ = vec_splat_s32( 14);
+ *var_vec_s32++ = vec_splat_s32( 15);
+ *var_vec_s32++ = vec_splat_s32(-10);
+ *var_vec_s32++ = vec_splat_s32(-11);
+ *var_vec_s32++ = vec_splat_s32(-12);
+ *var_vec_s32++ = vec_splat_s32(-13);
+ *var_vec_s32++ = vec_splat_s32(-14);
+ *var_vec_s32++ = vec_splat_s32(-15);
+ *var_vec_s32++ = vec_splat_s32(-16);
+ *var_vec_s32++ = vec_sr(var_vec_s32[0], var_vec_u32[1]);
+}
+void f15() {
+ *var_vec_s32++ = vec_sra(var_vec_s32[0], var_vec_u32[1]);
+ *var_vec_s32++ = vec_srl(var_vec_s32[0], var_vec_u16[1]);
+ *var_vec_s32++ = vec_srl(var_vec_s32[0], var_vec_u32[1]);
+ *var_vec_s32++ = vec_srl(var_vec_s32[0], var_vec_u8[1]);
+ *var_vec_s32++ = vec_sro(var_vec_s32[0], var_vec_s8[1]);
+ *var_vec_s32++ = vec_sro(var_vec_s32[0], var_vec_u8[1]);
+ *var_vec_s32++ = vec_sub(var_vec_b32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_sub(var_vec_s32[0], var_vec_b32[1]);
+ *var_vec_s32++ = vec_sub(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_subs(var_vec_b32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_subs(var_vec_s32[0], var_vec_b32[1]);
+ *var_vec_s32++ = vec_subs(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_sum2s(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_sum4s(var_vec_s16[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_sum4s(var_vec_s8[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_sums(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_unpackh(var_vec_s16[0]);
+ *var_vec_s32++ = vec_unpackl(var_vec_s16[0]);
+ *var_vec_s32++ = vec_vaddsws(var_vec_b32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vaddsws(var_vec_s32[0], var_vec_b32[1]);
+ *var_vec_s32++ = vec_vaddsws(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vadduwm(var_vec_b32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vadduwm(var_vec_s32[0], var_vec_b32[1]);
+ *var_vec_s32++ = vec_vadduwm(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vand(var_vec_b32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vand(var_vec_s32[0], var_vec_b32[1]);
+ *var_vec_s32++ = vec_vand(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vandc(var_vec_b32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vandc(var_vec_s32[0], var_vec_b32[1]);
+ *var_vec_s32++ = vec_vandc(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vavgsw(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vcmpbfp(var_vec_f32[0], var_vec_f32[1]);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 0);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 1);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 2);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 3);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 4);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 5);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 6);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 7);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 8);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 9);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 10);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 11);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 12);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 13);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 14);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 15);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 16);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 17);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 18);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 19);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 20);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 21);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 22);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 23);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 24);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 25);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 26);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 27);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 28);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 29);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 30);
+ *var_vec_s32++ = vec_vctsxs(var_vec_f32[0], 31);
+ *var_vec_s32++ = vec_vmaxsw(var_vec_b32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vmaxsw(var_vec_s32[0], var_vec_b32[1]);
+ *var_vec_s32++ = vec_vmaxsw(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vminsw(var_vec_b32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vminsw(var_vec_s32[0], var_vec_b32[1]);
+ *var_vec_s32++ = vec_vminsw(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vmrghw(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vmrglw(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vmsummbm(var_vec_s8[0], var_vec_u8[1], var_vec_s32[2]);
+ *var_vec_s32++ = vec_vmsumshm(var_vec_s16[0], var_vec_s16[1], var_vec_s32[2]);
+ *var_vec_s32++ = vec_vmsumshs(var_vec_s16[0], var_vec_s16[1], var_vec_s32[2]);
+ *var_vec_s32++ = vec_vmulesh(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s32++ = vec_vmulosh(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s32++ = vec_vnor(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vor(var_vec_b32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vor(var_vec_s32[0], var_vec_b32[1]);
+ *var_vec_s32++ = vec_vor(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vperm(var_vec_s32[0], var_vec_s32[1], var_vec_u8[2]);
+ *var_vec_s32++ = vec_vrlw(var_vec_s32[0], var_vec_u32[1]);
+ *var_vec_s32++ = vec_vsel(var_vec_s32[0], var_vec_s32[1], var_vec_b32[2]);
+ *var_vec_s32++ = vec_vsel(var_vec_s32[0], var_vec_s32[1], var_vec_u32[2]);
+ *var_vec_s32++ = vec_vsl(var_vec_s32[0], var_vec_u16[1]);
+ *var_vec_s32++ = vec_vsl(var_vec_s32[0], var_vec_u32[1]);
+ *var_vec_s32++ = vec_vsl(var_vec_s32[0], var_vec_u8[1]);
+ *var_vec_s32++ = vec_vsldoi(var_vec_s32[0], var_vec_s32[1], 0);
+ *var_vec_s32++ = vec_vsldoi(var_vec_s32[0], var_vec_s32[1], 1);
+ *var_vec_s32++ = vec_vsldoi(var_vec_s32[0], var_vec_s32[1], 2);
+ *var_vec_s32++ = vec_vsldoi(var_vec_s32[0], var_vec_s32[1], 3);
+ *var_vec_s32++ = vec_vsldoi(var_vec_s32[0], var_vec_s32[1], 4);
+ *var_vec_s32++ = vec_vsldoi(var_vec_s32[0], var_vec_s32[1], 5);
+ *var_vec_s32++ = vec_vsldoi(var_vec_s32[0], var_vec_s32[1], 6);
+ *var_vec_s32++ = vec_vsldoi(var_vec_s32[0], var_vec_s32[1], 7);
+ *var_vec_s32++ = vec_vsldoi(var_vec_s32[0], var_vec_s32[1], 8);
+ *var_vec_s32++ = vec_vsldoi(var_vec_s32[0], var_vec_s32[1], 9);
+}
+void f16() {
+ *var_vec_s32++ = vec_vsldoi(var_vec_s32[0], var_vec_s32[1], 10);
+ *var_vec_s32++ = vec_vsldoi(var_vec_s32[0], var_vec_s32[1], 11);
+ *var_vec_s32++ = vec_vsldoi(var_vec_s32[0], var_vec_s32[1], 12);
+ *var_vec_s32++ = vec_vsldoi(var_vec_s32[0], var_vec_s32[1], 13);
+ *var_vec_s32++ = vec_vsldoi(var_vec_s32[0], var_vec_s32[1], 14);
+ *var_vec_s32++ = vec_vsldoi(var_vec_s32[0], var_vec_s32[1], 15);
+ *var_vec_s32++ = vec_vslo(var_vec_s32[0], var_vec_s8[1]);
+ *var_vec_s32++ = vec_vslo(var_vec_s32[0], var_vec_u8[1]);
+ *var_vec_s32++ = vec_vslw(var_vec_s32[0], var_vec_u32[1]);
+ *var_vec_s32++ = vec_vspltisw( 0);
+ *var_vec_s32++ = vec_vspltisw( 1);
+ *var_vec_s32++ = vec_vspltisw( 2);
+ *var_vec_s32++ = vec_vspltisw( 3);
+ *var_vec_s32++ = vec_vspltisw( 4);
+ *var_vec_s32++ = vec_vspltisw( 5);
+ *var_vec_s32++ = vec_vspltisw( 6);
+ *var_vec_s32++ = vec_vspltisw( 7);
+ *var_vec_s32++ = vec_vspltisw( 8);
+ *var_vec_s32++ = vec_vspltisw( 9);
+ *var_vec_s32++ = vec_vspltisw( -1);
+ *var_vec_s32++ = vec_vspltisw( -2);
+ *var_vec_s32++ = vec_vspltisw( -3);
+ *var_vec_s32++ = vec_vspltisw( -4);
+ *var_vec_s32++ = vec_vspltisw( -5);
+ *var_vec_s32++ = vec_vspltisw( -6);
+ *var_vec_s32++ = vec_vspltisw( -7);
+ *var_vec_s32++ = vec_vspltisw( -8);
+ *var_vec_s32++ = vec_vspltisw( -9);
+ *var_vec_s32++ = vec_vspltisw( 10);
+ *var_vec_s32++ = vec_vspltisw( 11);
+ *var_vec_s32++ = vec_vspltisw( 12);
+ *var_vec_s32++ = vec_vspltisw( 13);
+ *var_vec_s32++ = vec_vspltisw( 14);
+ *var_vec_s32++ = vec_vspltisw( 15);
+ *var_vec_s32++ = vec_vspltisw(-10);
+ *var_vec_s32++ = vec_vspltisw(-11);
+ *var_vec_s32++ = vec_vspltisw(-12);
+ *var_vec_s32++ = vec_vspltisw(-13);
+ *var_vec_s32++ = vec_vspltisw(-14);
+ *var_vec_s32++ = vec_vspltisw(-15);
+ *var_vec_s32++ = vec_vspltisw(-16);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 0);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 1);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 2);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 3);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 4);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 5);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 6);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 7);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 8);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 9);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 10);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 11);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 12);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 13);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 14);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 15);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 16);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 17);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 18);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 19);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 20);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 21);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 22);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 23);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 24);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 25);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 26);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 27);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 28);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 29);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 30);
+ *var_vec_s32++ = vec_vspltw(var_vec_s32[0], 31);
+ *var_vec_s32++ = vec_vsr(var_vec_s32[0], var_vec_u16[1]);
+ *var_vec_s32++ = vec_vsr(var_vec_s32[0], var_vec_u32[1]);
+ *var_vec_s32++ = vec_vsr(var_vec_s32[0], var_vec_u8[1]);
+ *var_vec_s32++ = vec_vsraw(var_vec_s32[0], var_vec_u32[1]);
+ *var_vec_s32++ = vec_vsro(var_vec_s32[0], var_vec_s8[1]);
+ *var_vec_s32++ = vec_vsro(var_vec_s32[0], var_vec_u8[1]);
+ *var_vec_s32++ = vec_vsrw(var_vec_s32[0], var_vec_u32[1]);
+ *var_vec_s32++ = vec_vsubsws(var_vec_b32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vsubsws(var_vec_s32[0], var_vec_b32[1]);
+ *var_vec_s32++ = vec_vsubsws(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vsubuwm(var_vec_b32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vsubuwm(var_vec_s32[0], var_vec_b32[1]);
+ *var_vec_s32++ = vec_vsubuwm(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vsum2sws(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vsum4sbs(var_vec_s8[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vsum4shs(var_vec_s16[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vsumsws(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vupkhsh(var_vec_s16[0]);
+ *var_vec_s32++ = vec_vupklsh(var_vec_s16[0]);
+ *var_vec_s32++ = vec_vxor(var_vec_b32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_vxor(var_vec_s32[0], var_vec_b32[1]);
+ *var_vec_s32++ = vec_vxor(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_xor(var_vec_b32[0], var_vec_s32[1]);
+ *var_vec_s32++ = vec_xor(var_vec_s32[0], var_vec_b32[1]);
+ *var_vec_s32++ = vec_xor(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_s8++ = vec_add(var_vec_b8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_add(var_vec_s8[0], var_vec_b8[1]);
+}
+void f17() {
+ *var_vec_s8++ = vec_add(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_adds(var_vec_b8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_adds(var_vec_s8[0], var_vec_b8[1]);
+ *var_vec_s8++ = vec_adds(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_and(var_vec_b8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_and(var_vec_s8[0], var_vec_b8[1]);
+ *var_vec_s8++ = vec_and(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_andc(var_vec_b8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_andc(var_vec_s8[0], var_vec_b8[1]);
+ *var_vec_s8++ = vec_andc(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_avg(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_ld(var_int[0], var_signed_char_ptr[1]);
+ *var_vec_s8++ = vec_ld(var_int[0], var_vec_s8_ptr[1]);
+ *var_vec_s8++ = vec_lde(var_int[0], var_signed_char_ptr[1]);
+ *var_vec_s8++ = vec_ldl(var_int[0], var_signed_char_ptr[1]);
+ *var_vec_s8++ = vec_ldl(var_int[0], var_vec_s8_ptr[1]);
+ *var_vec_s8++ = vec_lvebx(var_int[0], var_signed_char_ptr[1]);
+ *var_vec_s8++ = vec_lvx(var_int[0], var_signed_char_ptr[1]);
+ *var_vec_s8++ = vec_lvx(var_int[0], var_vec_s8_ptr[1]);
+ *var_vec_s8++ = vec_lvxl(var_int[0], var_signed_char_ptr[1]);
+ *var_vec_s8++ = vec_lvxl(var_int[0], var_vec_s8_ptr[1]);
+ *var_vec_s8++ = vec_max(var_vec_b8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_max(var_vec_s8[0], var_vec_b8[1]);
+ *var_vec_s8++ = vec_max(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_mergeh(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_mergel(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_min(var_vec_b8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_min(var_vec_s8[0], var_vec_b8[1]);
+ *var_vec_s8++ = vec_min(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_nor(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_or(var_vec_b8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_or(var_vec_s8[0], var_vec_b8[1]);
+ *var_vec_s8++ = vec_or(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_pack(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s8++ = vec_packs(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s8++ = vec_perm(var_vec_s8[0], var_vec_s8[1], var_vec_u8[2]);
+ *var_vec_s8++ = vec_rl(var_vec_s8[0], var_vec_u8[1]);
+ *var_vec_s8++ = vec_sel(var_vec_s8[0], var_vec_s8[1], var_vec_b8[2]);
+ *var_vec_s8++ = vec_sel(var_vec_s8[0], var_vec_s8[1], var_vec_u8[2]);
+ *var_vec_s8++ = vec_sl(var_vec_s8[0], var_vec_u8[1]);
+ *var_vec_s8++ = vec_sld(var_vec_s8[0], var_vec_s8[1], 0);
+ *var_vec_s8++ = vec_sld(var_vec_s8[0], var_vec_s8[1], 1);
+ *var_vec_s8++ = vec_sld(var_vec_s8[0], var_vec_s8[1], 2);
+ *var_vec_s8++ = vec_sld(var_vec_s8[0], var_vec_s8[1], 3);
+ *var_vec_s8++ = vec_sld(var_vec_s8[0], var_vec_s8[1], 4);
+ *var_vec_s8++ = vec_sld(var_vec_s8[0], var_vec_s8[1], 5);
+ *var_vec_s8++ = vec_sld(var_vec_s8[0], var_vec_s8[1], 6);
+ *var_vec_s8++ = vec_sld(var_vec_s8[0], var_vec_s8[1], 7);
+ *var_vec_s8++ = vec_sld(var_vec_s8[0], var_vec_s8[1], 8);
+ *var_vec_s8++ = vec_sld(var_vec_s8[0], var_vec_s8[1], 9);
+ *var_vec_s8++ = vec_sld(var_vec_s8[0], var_vec_s8[1], 10);
+ *var_vec_s8++ = vec_sld(var_vec_s8[0], var_vec_s8[1], 11);
+ *var_vec_s8++ = vec_sld(var_vec_s8[0], var_vec_s8[1], 12);
+ *var_vec_s8++ = vec_sld(var_vec_s8[0], var_vec_s8[1], 13);
+ *var_vec_s8++ = vec_sld(var_vec_s8[0], var_vec_s8[1], 14);
+ *var_vec_s8++ = vec_sld(var_vec_s8[0], var_vec_s8[1], 15);
+ *var_vec_s8++ = vec_sll(var_vec_s8[0], var_vec_u16[1]);
+ *var_vec_s8++ = vec_sll(var_vec_s8[0], var_vec_u32[1]);
+ *var_vec_s8++ = vec_sll(var_vec_s8[0], var_vec_u8[1]);
+ *var_vec_s8++ = vec_slo(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_slo(var_vec_s8[0], var_vec_u8[1]);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 0);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 1);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 2);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 3);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 4);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 5);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 6);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 7);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 8);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 9);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 10);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 11);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 12);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 13);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 14);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 15);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 16);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 17);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 18);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 19);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 20);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 21);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 22);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 23);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 24);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 25);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 26);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 27);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 28);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 29);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 30);
+ *var_vec_s8++ = vec_splat(var_vec_s8[0], 31);
+ *var_vec_s8++ = vec_splat_s8( 0);
+ *var_vec_s8++ = vec_splat_s8( 1);
+ *var_vec_s8++ = vec_splat_s8( 2);
+ *var_vec_s8++ = vec_splat_s8( 3);
+ *var_vec_s8++ = vec_splat_s8( 4);
+ *var_vec_s8++ = vec_splat_s8( 5);
+ *var_vec_s8++ = vec_splat_s8( 6);
+}
+void f18() {
+ *var_vec_s8++ = vec_splat_s8( 7);
+ *var_vec_s8++ = vec_splat_s8( 8);
+ *var_vec_s8++ = vec_splat_s8( 9);
+ *var_vec_s8++ = vec_splat_s8( -1);
+ *var_vec_s8++ = vec_splat_s8( -2);
+ *var_vec_s8++ = vec_splat_s8( -3);
+ *var_vec_s8++ = vec_splat_s8( -4);
+ *var_vec_s8++ = vec_splat_s8( -5);
+ *var_vec_s8++ = vec_splat_s8( -6);
+ *var_vec_s8++ = vec_splat_s8( -7);
+ *var_vec_s8++ = vec_splat_s8( -8);
+ *var_vec_s8++ = vec_splat_s8( -9);
+ *var_vec_s8++ = vec_splat_s8( 10);
+ *var_vec_s8++ = vec_splat_s8( 11);
+ *var_vec_s8++ = vec_splat_s8( 12);
+ *var_vec_s8++ = vec_splat_s8( 13);
+ *var_vec_s8++ = vec_splat_s8( 14);
+ *var_vec_s8++ = vec_splat_s8( 15);
+ *var_vec_s8++ = vec_splat_s8(-10);
+ *var_vec_s8++ = vec_splat_s8(-11);
+ *var_vec_s8++ = vec_splat_s8(-12);
+ *var_vec_s8++ = vec_splat_s8(-13);
+ *var_vec_s8++ = vec_splat_s8(-14);
+ *var_vec_s8++ = vec_splat_s8(-15);
+ *var_vec_s8++ = vec_splat_s8(-16);
+ *var_vec_s8++ = vec_sr(var_vec_s8[0], var_vec_u8[1]);
+ *var_vec_s8++ = vec_sra(var_vec_s8[0], var_vec_u8[1]);
+ *var_vec_s8++ = vec_srl(var_vec_s8[0], var_vec_u16[1]);
+ *var_vec_s8++ = vec_srl(var_vec_s8[0], var_vec_u32[1]);
+ *var_vec_s8++ = vec_srl(var_vec_s8[0], var_vec_u8[1]);
+ *var_vec_s8++ = vec_sro(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_sro(var_vec_s8[0], var_vec_u8[1]);
+ *var_vec_s8++ = vec_sub(var_vec_b8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_sub(var_vec_s8[0], var_vec_b8[1]);
+ *var_vec_s8++ = vec_sub(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_subs(var_vec_b8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_subs(var_vec_s8[0], var_vec_b8[1]);
+ *var_vec_s8++ = vec_subs(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vaddsbs(var_vec_b8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vaddsbs(var_vec_s8[0], var_vec_b8[1]);
+ *var_vec_s8++ = vec_vaddsbs(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vaddubm(var_vec_b8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vaddubm(var_vec_s8[0], var_vec_b8[1]);
+ *var_vec_s8++ = vec_vaddubm(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vand(var_vec_b8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vand(var_vec_s8[0], var_vec_b8[1]);
+ *var_vec_s8++ = vec_vand(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vandc(var_vec_b8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vandc(var_vec_s8[0], var_vec_b8[1]);
+ *var_vec_s8++ = vec_vandc(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vavgsb(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vmaxsb(var_vec_b8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vmaxsb(var_vec_s8[0], var_vec_b8[1]);
+ *var_vec_s8++ = vec_vmaxsb(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vminsb(var_vec_b8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vminsb(var_vec_s8[0], var_vec_b8[1]);
+ *var_vec_s8++ = vec_vminsb(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vmrghb(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vmrglb(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vnor(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vor(var_vec_b8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vor(var_vec_s8[0], var_vec_b8[1]);
+ *var_vec_s8++ = vec_vor(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vperm(var_vec_s8[0], var_vec_s8[1], var_vec_u8[2]);
+ *var_vec_s8++ = vec_vpkshss(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s8++ = vec_vpkuhum(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_s8++ = vec_vrlb(var_vec_s8[0], var_vec_u8[1]);
+ *var_vec_s8++ = vec_vsel(var_vec_s8[0], var_vec_s8[1], var_vec_b8[2]);
+ *var_vec_s8++ = vec_vsel(var_vec_s8[0], var_vec_s8[1], var_vec_u8[2]);
+ *var_vec_s8++ = vec_vsl(var_vec_s8[0], var_vec_u16[1]);
+ *var_vec_s8++ = vec_vsl(var_vec_s8[0], var_vec_u32[1]);
+ *var_vec_s8++ = vec_vsl(var_vec_s8[0], var_vec_u8[1]);
+ *var_vec_s8++ = vec_vslb(var_vec_s8[0], var_vec_u8[1]);
+ *var_vec_s8++ = vec_vsldoi(var_vec_s8[0], var_vec_s8[1], 0);
+ *var_vec_s8++ = vec_vsldoi(var_vec_s8[0], var_vec_s8[1], 1);
+ *var_vec_s8++ = vec_vsldoi(var_vec_s8[0], var_vec_s8[1], 2);
+ *var_vec_s8++ = vec_vsldoi(var_vec_s8[0], var_vec_s8[1], 3);
+ *var_vec_s8++ = vec_vsldoi(var_vec_s8[0], var_vec_s8[1], 4);
+ *var_vec_s8++ = vec_vsldoi(var_vec_s8[0], var_vec_s8[1], 5);
+ *var_vec_s8++ = vec_vsldoi(var_vec_s8[0], var_vec_s8[1], 6);
+ *var_vec_s8++ = vec_vsldoi(var_vec_s8[0], var_vec_s8[1], 7);
+ *var_vec_s8++ = vec_vsldoi(var_vec_s8[0], var_vec_s8[1], 8);
+ *var_vec_s8++ = vec_vsldoi(var_vec_s8[0], var_vec_s8[1], 9);
+ *var_vec_s8++ = vec_vsldoi(var_vec_s8[0], var_vec_s8[1], 10);
+ *var_vec_s8++ = vec_vsldoi(var_vec_s8[0], var_vec_s8[1], 11);
+ *var_vec_s8++ = vec_vsldoi(var_vec_s8[0], var_vec_s8[1], 12);
+ *var_vec_s8++ = vec_vsldoi(var_vec_s8[0], var_vec_s8[1], 13);
+ *var_vec_s8++ = vec_vsldoi(var_vec_s8[0], var_vec_s8[1], 14);
+ *var_vec_s8++ = vec_vsldoi(var_vec_s8[0], var_vec_s8[1], 15);
+ *var_vec_s8++ = vec_vslo(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vslo(var_vec_s8[0], var_vec_u8[1]);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 0);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 1);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 2);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 3);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 4);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 5);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 6);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 7);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 8);
+}
+void f19() {
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 9);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 10);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 11);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 12);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 13);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 14);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 15);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 16);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 17);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 18);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 19);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 20);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 21);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 22);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 23);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 24);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 25);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 26);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 27);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 28);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 29);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 30);
+ *var_vec_s8++ = vec_vspltb(var_vec_s8[0], 31);
+ *var_vec_s8++ = vec_vspltisb( 0);
+ *var_vec_s8++ = vec_vspltisb( 1);
+ *var_vec_s8++ = vec_vspltisb( 2);
+ *var_vec_s8++ = vec_vspltisb( 3);
+ *var_vec_s8++ = vec_vspltisb( 4);
+ *var_vec_s8++ = vec_vspltisb( 5);
+ *var_vec_s8++ = vec_vspltisb( 6);
+ *var_vec_s8++ = vec_vspltisb( 7);
+ *var_vec_s8++ = vec_vspltisb( 8);
+ *var_vec_s8++ = vec_vspltisb( 9);
+ *var_vec_s8++ = vec_vspltisb( -1);
+ *var_vec_s8++ = vec_vspltisb( -2);
+ *var_vec_s8++ = vec_vspltisb( -3);
+ *var_vec_s8++ = vec_vspltisb( -4);
+ *var_vec_s8++ = vec_vspltisb( -5);
+ *var_vec_s8++ = vec_vspltisb( -6);
+ *var_vec_s8++ = vec_vspltisb( -7);
+ *var_vec_s8++ = vec_vspltisb( -8);
+ *var_vec_s8++ = vec_vspltisb( -9);
+ *var_vec_s8++ = vec_vspltisb( 10);
+ *var_vec_s8++ = vec_vspltisb( 11);
+ *var_vec_s8++ = vec_vspltisb( 12);
+ *var_vec_s8++ = vec_vspltisb( 13);
+ *var_vec_s8++ = vec_vspltisb( 14);
+ *var_vec_s8++ = vec_vspltisb( 15);
+ *var_vec_s8++ = vec_vspltisb(-10);
+ *var_vec_s8++ = vec_vspltisb(-11);
+ *var_vec_s8++ = vec_vspltisb(-12);
+ *var_vec_s8++ = vec_vspltisb(-13);
+ *var_vec_s8++ = vec_vspltisb(-14);
+ *var_vec_s8++ = vec_vspltisb(-15);
+ *var_vec_s8++ = vec_vspltisb(-16);
+ *var_vec_s8++ = vec_vsr(var_vec_s8[0], var_vec_u16[1]);
+ *var_vec_s8++ = vec_vsr(var_vec_s8[0], var_vec_u32[1]);
+ *var_vec_s8++ = vec_vsr(var_vec_s8[0], var_vec_u8[1]);
+ *var_vec_s8++ = vec_vsrab(var_vec_s8[0], var_vec_u8[1]);
+ *var_vec_s8++ = vec_vsrb(var_vec_s8[0], var_vec_u8[1]);
+ *var_vec_s8++ = vec_vsro(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vsro(var_vec_s8[0], var_vec_u8[1]);
+ *var_vec_s8++ = vec_vsubsbs(var_vec_b8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vsubsbs(var_vec_s8[0], var_vec_b8[1]);
+ *var_vec_s8++ = vec_vsubsbs(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vsububm(var_vec_b8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vsububm(var_vec_s8[0], var_vec_b8[1]);
+ *var_vec_s8++ = vec_vsububm(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vxor(var_vec_b8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_vxor(var_vec_s8[0], var_vec_b8[1]);
+ *var_vec_s8++ = vec_vxor(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_xor(var_vec_b8[0], var_vec_s8[1]);
+ *var_vec_s8++ = vec_xor(var_vec_s8[0], var_vec_b8[1]);
+ *var_vec_s8++ = vec_xor(var_vec_s8[0], var_vec_s8[1]);
+ *var_vec_u16++ = vec_add(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_add(var_vec_u16[0], var_vec_b16[1]);
+ *var_vec_u16++ = vec_add(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_adds(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_adds(var_vec_u16[0], var_vec_b16[1]);
+ *var_vec_u16++ = vec_adds(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_and(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_and(var_vec_u16[0], var_vec_b16[1]);
+ *var_vec_u16++ = vec_and(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_andc(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_andc(var_vec_u16[0], var_vec_b16[1]);
+ *var_vec_u16++ = vec_andc(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_avg(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_ld(var_int[0], var_unsigned_short_ptr[1]);
+ *var_vec_u16++ = vec_ld(var_int[0], var_vec_u16_ptr[1]);
+ *var_vec_u16++ = vec_lde(var_int[0], var_unsigned_short_ptr[1]);
+ *var_vec_u16++ = vec_ldl(var_int[0], var_unsigned_short_ptr[1]);
+ *var_vec_u16++ = vec_ldl(var_int[0], var_vec_u16_ptr[1]);
+ *var_vec_u16++ = vec_lvehx(var_int[0], var_unsigned_short_ptr[1]);
+ *var_vec_u16++ = vec_lvx(var_int[0], var_unsigned_short_ptr[1]);
+ *var_vec_u16++ = vec_lvx(var_int[0], var_vec_u16_ptr[1]);
+ *var_vec_u16++ = vec_lvxl(var_int[0], var_unsigned_short_ptr[1]);
+ *var_vec_u16++ = vec_lvxl(var_int[0], var_vec_u16_ptr[1]);
+ *var_vec_u16++ = vec_max(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_max(var_vec_u16[0], var_vec_b16[1]);
+ *var_vec_u16++ = vec_max(var_vec_u16[0], var_vec_u16[1]);
+}
+void f20() {
+ *var_vec_u16++ = vec_mergeh(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_mergel(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_min(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_min(var_vec_u16[0], var_vec_b16[1]);
+ *var_vec_u16++ = vec_min(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_mladd(var_vec_u16[0], var_vec_u16[1], var_vec_u16[2]);
+ *var_vec_u16++ = vec_mule(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u16++ = vec_mulo(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u16++ = vec_nor(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_or(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_or(var_vec_u16[0], var_vec_b16[1]);
+ *var_vec_u16++ = vec_or(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_pack(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u16++ = vec_packs(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u16++ = vec_packsu(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_u16++ = vec_packsu(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u16++ = vec_perm(var_vec_u16[0], var_vec_u16[1], var_vec_u8[2]);
+ *var_vec_u16++ = vec_rl(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_sel(var_vec_u16[0], var_vec_u16[1], var_vec_b16[2]);
+ *var_vec_u16++ = vec_sel(var_vec_u16[0], var_vec_u16[1], var_vec_u16[2]);
+ *var_vec_u16++ = vec_sl(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_sld(var_vec_u16[0], var_vec_u16[1], 0);
+ *var_vec_u16++ = vec_sld(var_vec_u16[0], var_vec_u16[1], 1);
+ *var_vec_u16++ = vec_sld(var_vec_u16[0], var_vec_u16[1], 2);
+ *var_vec_u16++ = vec_sld(var_vec_u16[0], var_vec_u16[1], 3);
+ *var_vec_u16++ = vec_sld(var_vec_u16[0], var_vec_u16[1], 4);
+ *var_vec_u16++ = vec_sld(var_vec_u16[0], var_vec_u16[1], 5);
+ *var_vec_u16++ = vec_sld(var_vec_u16[0], var_vec_u16[1], 6);
+ *var_vec_u16++ = vec_sld(var_vec_u16[0], var_vec_u16[1], 7);
+ *var_vec_u16++ = vec_sld(var_vec_u16[0], var_vec_u16[1], 8);
+ *var_vec_u16++ = vec_sld(var_vec_u16[0], var_vec_u16[1], 9);
+ *var_vec_u16++ = vec_sld(var_vec_u16[0], var_vec_u16[1], 10);
+ *var_vec_u16++ = vec_sld(var_vec_u16[0], var_vec_u16[1], 11);
+ *var_vec_u16++ = vec_sld(var_vec_u16[0], var_vec_u16[1], 12);
+ *var_vec_u16++ = vec_sld(var_vec_u16[0], var_vec_u16[1], 13);
+ *var_vec_u16++ = vec_sld(var_vec_u16[0], var_vec_u16[1], 14);
+ *var_vec_u16++ = vec_sld(var_vec_u16[0], var_vec_u16[1], 15);
+ *var_vec_u16++ = vec_sll(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_sll(var_vec_u16[0], var_vec_u32[1]);
+ *var_vec_u16++ = vec_sll(var_vec_u16[0], var_vec_u8[1]);
+ *var_vec_u16++ = vec_slo(var_vec_u16[0], var_vec_s8[1]);
+ *var_vec_u16++ = vec_slo(var_vec_u16[0], var_vec_u8[1]);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 0);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 1);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 2);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 3);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 4);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 5);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 6);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 7);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 8);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 9);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 10);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 11);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 12);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 13);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 14);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 15);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 16);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 17);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 18);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 19);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 20);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 21);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 22);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 23);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 24);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 25);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 26);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 27);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 28);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 29);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 30);
+ *var_vec_u16++ = vec_splat(var_vec_u16[0], 31);
+ *var_vec_u16++ = vec_splat_u16( 0);
+ *var_vec_u16++ = vec_splat_u16( 1);
+ *var_vec_u16++ = vec_splat_u16( 2);
+ *var_vec_u16++ = vec_splat_u16( 3);
+ *var_vec_u16++ = vec_splat_u16( 4);
+ *var_vec_u16++ = vec_splat_u16( 5);
+ *var_vec_u16++ = vec_splat_u16( 6);
+ *var_vec_u16++ = vec_splat_u16( 7);
+ *var_vec_u16++ = vec_splat_u16( 8);
+ *var_vec_u16++ = vec_splat_u16( 9);
+ *var_vec_u16++ = vec_splat_u16( -1);
+ *var_vec_u16++ = vec_splat_u16( -2);
+ *var_vec_u16++ = vec_splat_u16( -3);
+ *var_vec_u16++ = vec_splat_u16( -4);
+ *var_vec_u16++ = vec_splat_u16( -5);
+ *var_vec_u16++ = vec_splat_u16( -6);
+ *var_vec_u16++ = vec_splat_u16( -7);
+ *var_vec_u16++ = vec_splat_u16( -8);
+ *var_vec_u16++ = vec_splat_u16( -9);
+ *var_vec_u16++ = vec_splat_u16( 10);
+ *var_vec_u16++ = vec_splat_u16( 11);
+ *var_vec_u16++ = vec_splat_u16( 12);
+ *var_vec_u16++ = vec_splat_u16( 13);
+ *var_vec_u16++ = vec_splat_u16( 14);
+ *var_vec_u16++ = vec_splat_u16( 15);
+ *var_vec_u16++ = vec_splat_u16(-10);
+}
+void f21() {
+ *var_vec_u16++ = vec_splat_u16(-11);
+ *var_vec_u16++ = vec_splat_u16(-12);
+ *var_vec_u16++ = vec_splat_u16(-13);
+ *var_vec_u16++ = vec_splat_u16(-14);
+ *var_vec_u16++ = vec_splat_u16(-15);
+ *var_vec_u16++ = vec_splat_u16(-16);
+ *var_vec_u16++ = vec_sr(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_sra(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_srl(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_srl(var_vec_u16[0], var_vec_u32[1]);
+ *var_vec_u16++ = vec_srl(var_vec_u16[0], var_vec_u8[1]);
+ *var_vec_u16++ = vec_sro(var_vec_u16[0], var_vec_s8[1]);
+ *var_vec_u16++ = vec_sro(var_vec_u16[0], var_vec_u8[1]);
+ *var_vec_u16++ = vec_sub(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_sub(var_vec_u16[0], var_vec_b16[1]);
+ *var_vec_u16++ = vec_sub(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_subs(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_subs(var_vec_u16[0], var_vec_b16[1]);
+ *var_vec_u16++ = vec_subs(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vadduhm(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vadduhm(var_vec_u16[0], var_vec_b16[1]);
+ *var_vec_u16++ = vec_vadduhm(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vadduhs(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vadduhs(var_vec_u16[0], var_vec_b16[1]);
+ *var_vec_u16++ = vec_vadduhs(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vand(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vand(var_vec_u16[0], var_vec_b16[1]);
+ *var_vec_u16++ = vec_vand(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vandc(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vandc(var_vec_u16[0], var_vec_b16[1]);
+ *var_vec_u16++ = vec_vandc(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vavguh(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vmaxuh(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vmaxuh(var_vec_u16[0], var_vec_b16[1]);
+ *var_vec_u16++ = vec_vmaxuh(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vminuh(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vminuh(var_vec_u16[0], var_vec_b16[1]);
+ *var_vec_u16++ = vec_vminuh(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vmladduhm(var_vec_u16[0], var_vec_u16[1], var_vec_u16[2]);
+ *var_vec_u16++ = vec_vmrghh(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vmrglh(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vmuleub(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u16++ = vec_vmuloub(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u16++ = vec_vnor(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vor(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vor(var_vec_u16[0], var_vec_b16[1]);
+ *var_vec_u16++ = vec_vor(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vperm(var_vec_u16[0], var_vec_u16[1], var_vec_u8[2]);
+ *var_vec_u16++ = vec_vpkswus(var_vec_s32[0], var_vec_s32[1]);
+ *var_vec_u16++ = vec_vpkuwum(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u16++ = vec_vpkuwus(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u16++ = vec_vrlh(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vsel(var_vec_u16[0], var_vec_u16[1], var_vec_b16[2]);
+ *var_vec_u16++ = vec_vsel(var_vec_u16[0], var_vec_u16[1], var_vec_u16[2]);
+ *var_vec_u16++ = vec_vsl(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vsl(var_vec_u16[0], var_vec_u32[1]);
+ *var_vec_u16++ = vec_vsl(var_vec_u16[0], var_vec_u8[1]);
+ *var_vec_u16++ = vec_vsldoi(var_vec_u16[0], var_vec_u16[1], 0);
+ *var_vec_u16++ = vec_vsldoi(var_vec_u16[0], var_vec_u16[1], 1);
+ *var_vec_u16++ = vec_vsldoi(var_vec_u16[0], var_vec_u16[1], 2);
+ *var_vec_u16++ = vec_vsldoi(var_vec_u16[0], var_vec_u16[1], 3);
+ *var_vec_u16++ = vec_vsldoi(var_vec_u16[0], var_vec_u16[1], 4);
+ *var_vec_u16++ = vec_vsldoi(var_vec_u16[0], var_vec_u16[1], 5);
+ *var_vec_u16++ = vec_vsldoi(var_vec_u16[0], var_vec_u16[1], 6);
+ *var_vec_u16++ = vec_vsldoi(var_vec_u16[0], var_vec_u16[1], 7);
+ *var_vec_u16++ = vec_vsldoi(var_vec_u16[0], var_vec_u16[1], 8);
+ *var_vec_u16++ = vec_vsldoi(var_vec_u16[0], var_vec_u16[1], 9);
+ *var_vec_u16++ = vec_vsldoi(var_vec_u16[0], var_vec_u16[1], 10);
+ *var_vec_u16++ = vec_vsldoi(var_vec_u16[0], var_vec_u16[1], 11);
+ *var_vec_u16++ = vec_vsldoi(var_vec_u16[0], var_vec_u16[1], 12);
+ *var_vec_u16++ = vec_vsldoi(var_vec_u16[0], var_vec_u16[1], 13);
+ *var_vec_u16++ = vec_vsldoi(var_vec_u16[0], var_vec_u16[1], 14);
+ *var_vec_u16++ = vec_vsldoi(var_vec_u16[0], var_vec_u16[1], 15);
+ *var_vec_u16++ = vec_vslh(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vslo(var_vec_u16[0], var_vec_s8[1]);
+ *var_vec_u16++ = vec_vslo(var_vec_u16[0], var_vec_u8[1]);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 0);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 1);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 2);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 3);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 4);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 5);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 6);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 7);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 8);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 9);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 10);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 11);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 12);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 13);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 14);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 15);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 16);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 17);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 18);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 19);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 20);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 21);
+}
+void f22() {
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 22);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 23);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 24);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 25);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 26);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 27);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 28);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 29);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 30);
+ *var_vec_u16++ = vec_vsplth(var_vec_u16[0], 31);
+ *var_vec_u16++ = vec_vsr(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vsr(var_vec_u16[0], var_vec_u32[1]);
+ *var_vec_u16++ = vec_vsr(var_vec_u16[0], var_vec_u8[1]);
+ *var_vec_u16++ = vec_vsrah(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vsrh(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vsro(var_vec_u16[0], var_vec_s8[1]);
+ *var_vec_u16++ = vec_vsro(var_vec_u16[0], var_vec_u8[1]);
+ *var_vec_u16++ = vec_vsubuhm(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vsubuhm(var_vec_u16[0], var_vec_b16[1]);
+ *var_vec_u16++ = vec_vsubuhm(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vsubuhs(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vsubuhs(var_vec_u16[0], var_vec_b16[1]);
+ *var_vec_u16++ = vec_vsubuhs(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vxor(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_vxor(var_vec_u16[0], var_vec_b16[1]);
+ *var_vec_u16++ = vec_vxor(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_xor(var_vec_b16[0], var_vec_u16[1]);
+ *var_vec_u16++ = vec_xor(var_vec_u16[0], var_vec_b16[1]);
+ *var_vec_u16++ = vec_xor(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u32++ = vec_add(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_add(var_vec_u32[0], var_vec_b32[1]);
+ *var_vec_u32++ = vec_add(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_addc(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_adds(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_adds(var_vec_u32[0], var_vec_b32[1]);
+ *var_vec_u32++ = vec_adds(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_and(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_and(var_vec_u32[0], var_vec_b32[1]);
+ *var_vec_u32++ = vec_and(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_andc(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_andc(var_vec_u32[0], var_vec_b32[1]);
+ *var_vec_u32++ = vec_andc(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_avg(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 0);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 1);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 2);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 3);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 4);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 5);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 6);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 7);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 8);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 9);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 10);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 11);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 12);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 13);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 14);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 15);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 16);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 17);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 18);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 19);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 20);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 21);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 22);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 23);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 24);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 25);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 26);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 27);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 28);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 29);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 30);
+ *var_vec_u32++ = vec_ctu(var_vec_f32[0], 31);
+ *var_vec_u32++ = vec_ld(var_int[0], var_unsigned_int_ptr[1]);
+ *var_vec_u32++ = vec_ld(var_int[0], var_unsigned_long_ptr[1]);
+ *var_vec_u32++ = vec_ld(var_int[0], var_vec_u32_ptr[1]);
+ *var_vec_u32++ = vec_lde(var_int[0], var_unsigned_int_ptr[1]);
+ *var_vec_u32++ = vec_lde(var_int[0], var_unsigned_long_ptr[1]);
+ *var_vec_u32++ = vec_ldl(var_int[0], var_unsigned_int_ptr[1]);
+ *var_vec_u32++ = vec_ldl(var_int[0], var_unsigned_long_ptr[1]);
+ *var_vec_u32++ = vec_ldl(var_int[0], var_vec_u32_ptr[1]);
+ *var_vec_u32++ = vec_lvewx(var_int[0], var_unsigned_int_ptr[1]);
+ *var_vec_u32++ = vec_lvewx(var_int[0], var_unsigned_long_ptr[1]);
+ *var_vec_u32++ = vec_lvx(var_int[0], var_unsigned_int_ptr[1]);
+ *var_vec_u32++ = vec_lvx(var_int[0], var_unsigned_long_ptr[1]);
+ *var_vec_u32++ = vec_lvx(var_int[0], var_vec_u32_ptr[1]);
+ *var_vec_u32++ = vec_lvxl(var_int[0], var_unsigned_int_ptr[1]);
+ *var_vec_u32++ = vec_lvxl(var_int[0], var_unsigned_long_ptr[1]);
+ *var_vec_u32++ = vec_lvxl(var_int[0], var_vec_u32_ptr[1]);
+ *var_vec_u32++ = vec_max(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_max(var_vec_u32[0], var_vec_b32[1]);
+ *var_vec_u32++ = vec_max(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_mergeh(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_mergel(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_min(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_min(var_vec_u32[0], var_vec_b32[1]);
+ *var_vec_u32++ = vec_min(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_msum(var_vec_u16[0], var_vec_u16[1], var_vec_u32[2]);
+}
+void f23() {
+ *var_vec_u32++ = vec_msum(var_vec_u8[0], var_vec_u8[1], var_vec_u32[2]);
+ *var_vec_u32++ = vec_msums(var_vec_u16[0], var_vec_u16[1], var_vec_u32[2]);
+ *var_vec_u32++ = vec_mule(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u32++ = vec_mulo(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u32++ = vec_nor(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_or(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_or(var_vec_u32[0], var_vec_b32[1]);
+ *var_vec_u32++ = vec_or(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_perm(var_vec_u32[0], var_vec_u32[1], var_vec_u8[2]);
+ *var_vec_u32++ = vec_rl(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_sel(var_vec_u32[0], var_vec_u32[1], var_vec_b32[2]);
+ *var_vec_u32++ = vec_sel(var_vec_u32[0], var_vec_u32[1], var_vec_u32[2]);
+ *var_vec_u32++ = vec_sl(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_sld(var_vec_u32[0], var_vec_u32[1], 0);
+ *var_vec_u32++ = vec_sld(var_vec_u32[0], var_vec_u32[1], 1);
+ *var_vec_u32++ = vec_sld(var_vec_u32[0], var_vec_u32[1], 2);
+ *var_vec_u32++ = vec_sld(var_vec_u32[0], var_vec_u32[1], 3);
+ *var_vec_u32++ = vec_sld(var_vec_u32[0], var_vec_u32[1], 4);
+ *var_vec_u32++ = vec_sld(var_vec_u32[0], var_vec_u32[1], 5);
+ *var_vec_u32++ = vec_sld(var_vec_u32[0], var_vec_u32[1], 6);
+ *var_vec_u32++ = vec_sld(var_vec_u32[0], var_vec_u32[1], 7);
+ *var_vec_u32++ = vec_sld(var_vec_u32[0], var_vec_u32[1], 8);
+ *var_vec_u32++ = vec_sld(var_vec_u32[0], var_vec_u32[1], 9);
+ *var_vec_u32++ = vec_sld(var_vec_u32[0], var_vec_u32[1], 10);
+ *var_vec_u32++ = vec_sld(var_vec_u32[0], var_vec_u32[1], 11);
+ *var_vec_u32++ = vec_sld(var_vec_u32[0], var_vec_u32[1], 12);
+ *var_vec_u32++ = vec_sld(var_vec_u32[0], var_vec_u32[1], 13);
+ *var_vec_u32++ = vec_sld(var_vec_u32[0], var_vec_u32[1], 14);
+ *var_vec_u32++ = vec_sld(var_vec_u32[0], var_vec_u32[1], 15);
+ *var_vec_u32++ = vec_sll(var_vec_u32[0], var_vec_u16[1]);
+ *var_vec_u32++ = vec_sll(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_sll(var_vec_u32[0], var_vec_u8[1]);
+ *var_vec_u32++ = vec_slo(var_vec_u32[0], var_vec_s8[1]);
+ *var_vec_u32++ = vec_slo(var_vec_u32[0], var_vec_u8[1]);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 0);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 1);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 2);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 3);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 4);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 5);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 6);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 7);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 8);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 9);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 10);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 11);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 12);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 13);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 14);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 15);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 16);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 17);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 18);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 19);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 20);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 21);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 22);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 23);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 24);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 25);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 26);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 27);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 28);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 29);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 30);
+ *var_vec_u32++ = vec_splat(var_vec_u32[0], 31);
+ *var_vec_u32++ = vec_splat_u32( 0);
+ *var_vec_u32++ = vec_splat_u32( 1);
+ *var_vec_u32++ = vec_splat_u32( 2);
+ *var_vec_u32++ = vec_splat_u32( 3);
+ *var_vec_u32++ = vec_splat_u32( 4);
+ *var_vec_u32++ = vec_splat_u32( 5);
+ *var_vec_u32++ = vec_splat_u32( 6);
+ *var_vec_u32++ = vec_splat_u32( 7);
+ *var_vec_u32++ = vec_splat_u32( 8);
+ *var_vec_u32++ = vec_splat_u32( 9);
+ *var_vec_u32++ = vec_splat_u32( -1);
+ *var_vec_u32++ = vec_splat_u32( -2);
+ *var_vec_u32++ = vec_splat_u32( -3);
+ *var_vec_u32++ = vec_splat_u32( -4);
+ *var_vec_u32++ = vec_splat_u32( -5);
+ *var_vec_u32++ = vec_splat_u32( -6);
+ *var_vec_u32++ = vec_splat_u32( -7);
+ *var_vec_u32++ = vec_splat_u32( -8);
+ *var_vec_u32++ = vec_splat_u32( -9);
+ *var_vec_u32++ = vec_splat_u32( 10);
+ *var_vec_u32++ = vec_splat_u32( 11);
+ *var_vec_u32++ = vec_splat_u32( 12);
+ *var_vec_u32++ = vec_splat_u32( 13);
+ *var_vec_u32++ = vec_splat_u32( 14);
+ *var_vec_u32++ = vec_splat_u32( 15);
+ *var_vec_u32++ = vec_splat_u32(-10);
+ *var_vec_u32++ = vec_splat_u32(-11);
+ *var_vec_u32++ = vec_splat_u32(-12);
+ *var_vec_u32++ = vec_splat_u32(-13);
+ *var_vec_u32++ = vec_splat_u32(-14);
+ *var_vec_u32++ = vec_splat_u32(-15);
+ *var_vec_u32++ = vec_splat_u32(-16);
+ *var_vec_u32++ = vec_sr(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_sra(var_vec_u32[0], var_vec_u32[1]);
+}
+void f24() {
+ *var_vec_u32++ = vec_srl(var_vec_u32[0], var_vec_u16[1]);
+ *var_vec_u32++ = vec_srl(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_srl(var_vec_u32[0], var_vec_u8[1]);
+ *var_vec_u32++ = vec_sro(var_vec_u32[0], var_vec_s8[1]);
+ *var_vec_u32++ = vec_sro(var_vec_u32[0], var_vec_u8[1]);
+ *var_vec_u32++ = vec_sub(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_sub(var_vec_u32[0], var_vec_b32[1]);
+ *var_vec_u32++ = vec_sub(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_subc(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_subs(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_subs(var_vec_u32[0], var_vec_b32[1]);
+ *var_vec_u32++ = vec_subs(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_sum4s(var_vec_u8[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_unpackh(var_vec_p16[0]);
+ *var_vec_u32++ = vec_unpackl(var_vec_p16[0]);
+ *var_vec_u32++ = vec_vaddcuw(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vadduwm(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vadduwm(var_vec_u32[0], var_vec_b32[1]);
+ *var_vec_u32++ = vec_vadduwm(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vadduws(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vadduws(var_vec_u32[0], var_vec_b32[1]);
+ *var_vec_u32++ = vec_vadduws(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vand(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vand(var_vec_u32[0], var_vec_b32[1]);
+ *var_vec_u32++ = vec_vand(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vandc(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vandc(var_vec_u32[0], var_vec_b32[1]);
+ *var_vec_u32++ = vec_vandc(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vavguw(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 0);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 1);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 2);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 3);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 4);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 5);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 6);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 7);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 8);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 9);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 10);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 11);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 12);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 13);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 14);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 15);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 16);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 17);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 18);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 19);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 20);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 21);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 22);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 23);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 24);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 25);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 26);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 27);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 28);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 29);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 30);
+ *var_vec_u32++ = vec_vctuxs(var_vec_f32[0], 31);
+ *var_vec_u32++ = vec_vmaxuw(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vmaxuw(var_vec_u32[0], var_vec_b32[1]);
+ *var_vec_u32++ = vec_vmaxuw(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vminuw(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vminuw(var_vec_u32[0], var_vec_b32[1]);
+ *var_vec_u32++ = vec_vminuw(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vmrghw(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vmrglw(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vmsumubm(var_vec_u8[0], var_vec_u8[1], var_vec_u32[2]);
+ *var_vec_u32++ = vec_vmsumuhm(var_vec_u16[0], var_vec_u16[1], var_vec_u32[2]);
+ *var_vec_u32++ = vec_vmsumuhs(var_vec_u16[0], var_vec_u16[1], var_vec_u32[2]);
+ *var_vec_u32++ = vec_vmuleuh(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u32++ = vec_vmulouh(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u32++ = vec_vnor(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vor(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vor(var_vec_u32[0], var_vec_b32[1]);
+ *var_vec_u32++ = vec_vor(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vperm(var_vec_u32[0], var_vec_u32[1], var_vec_u8[2]);
+ *var_vec_u32++ = vec_vrlw(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vsel(var_vec_u32[0], var_vec_u32[1], var_vec_b32[2]);
+ *var_vec_u32++ = vec_vsel(var_vec_u32[0], var_vec_u32[1], var_vec_u32[2]);
+ *var_vec_u32++ = vec_vsl(var_vec_u32[0], var_vec_u16[1]);
+ *var_vec_u32++ = vec_vsl(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vsl(var_vec_u32[0], var_vec_u8[1]);
+ *var_vec_u32++ = vec_vsldoi(var_vec_u32[0], var_vec_u32[1], 0);
+ *var_vec_u32++ = vec_vsldoi(var_vec_u32[0], var_vec_u32[1], 1);
+ *var_vec_u32++ = vec_vsldoi(var_vec_u32[0], var_vec_u32[1], 2);
+ *var_vec_u32++ = vec_vsldoi(var_vec_u32[0], var_vec_u32[1], 3);
+ *var_vec_u32++ = vec_vsldoi(var_vec_u32[0], var_vec_u32[1], 4);
+ *var_vec_u32++ = vec_vsldoi(var_vec_u32[0], var_vec_u32[1], 5);
+ *var_vec_u32++ = vec_vsldoi(var_vec_u32[0], var_vec_u32[1], 6);
+ *var_vec_u32++ = vec_vsldoi(var_vec_u32[0], var_vec_u32[1], 7);
+ *var_vec_u32++ = vec_vsldoi(var_vec_u32[0], var_vec_u32[1], 8);
+ *var_vec_u32++ = vec_vsldoi(var_vec_u32[0], var_vec_u32[1], 9);
+ *var_vec_u32++ = vec_vsldoi(var_vec_u32[0], var_vec_u32[1], 10);
+ *var_vec_u32++ = vec_vsldoi(var_vec_u32[0], var_vec_u32[1], 11);
+ *var_vec_u32++ = vec_vsldoi(var_vec_u32[0], var_vec_u32[1], 12);
+}
+void f25() {
+ *var_vec_u32++ = vec_vsldoi(var_vec_u32[0], var_vec_u32[1], 13);
+ *var_vec_u32++ = vec_vsldoi(var_vec_u32[0], var_vec_u32[1], 14);
+ *var_vec_u32++ = vec_vsldoi(var_vec_u32[0], var_vec_u32[1], 15);
+ *var_vec_u32++ = vec_vslo(var_vec_u32[0], var_vec_s8[1]);
+ *var_vec_u32++ = vec_vslo(var_vec_u32[0], var_vec_u8[1]);
+ *var_vec_u32++ = vec_vslw(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 0);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 1);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 2);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 3);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 4);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 5);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 6);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 7);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 8);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 9);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 10);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 11);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 12);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 13);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 14);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 15);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 16);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 17);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 18);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 19);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 20);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 21);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 22);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 23);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 24);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 25);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 26);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 27);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 28);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 29);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 30);
+ *var_vec_u32++ = vec_vspltw(var_vec_u32[0], 31);
+ *var_vec_u32++ = vec_vsr(var_vec_u32[0], var_vec_u16[1]);
+ *var_vec_u32++ = vec_vsr(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vsr(var_vec_u32[0], var_vec_u8[1]);
+ *var_vec_u32++ = vec_vsraw(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vsro(var_vec_u32[0], var_vec_s8[1]);
+ *var_vec_u32++ = vec_vsro(var_vec_u32[0], var_vec_u8[1]);
+ *var_vec_u32++ = vec_vsrw(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vsubcuw(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vsubuwm(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vsubuwm(var_vec_u32[0], var_vec_b32[1]);
+ *var_vec_u32++ = vec_vsubuwm(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vsubuws(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vsubuws(var_vec_u32[0], var_vec_b32[1]);
+ *var_vec_u32++ = vec_vsubuws(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vsum4ubs(var_vec_u8[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vupkhpx(var_vec_p16[0]);
+ *var_vec_u32++ = vec_vupklpx(var_vec_p16[0]);
+ *var_vec_u32++ = vec_vxor(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_vxor(var_vec_u32[0], var_vec_b32[1]);
+ *var_vec_u32++ = vec_vxor(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_xor(var_vec_b32[0], var_vec_u32[1]);
+ *var_vec_u32++ = vec_xor(var_vec_u32[0], var_vec_b32[1]);
+ *var_vec_u32++ = vec_xor(var_vec_u32[0], var_vec_u32[1]);
+ *var_vec_u8++ = vec_add(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_add(var_vec_u8[0], var_vec_b8[1]);
+ *var_vec_u8++ = vec_add(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_adds(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_adds(var_vec_u8[0], var_vec_b8[1]);
+ *var_vec_u8++ = vec_adds(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_and(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_and(var_vec_u8[0], var_vec_b8[1]);
+ *var_vec_u8++ = vec_and(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_andc(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_andc(var_vec_u8[0], var_vec_b8[1]);
+ *var_vec_u8++ = vec_andc(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_avg(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_ld(var_int[0], var_unsigned_char_ptr[1]);
+ *var_vec_u8++ = vec_ld(var_int[0], var_vec_u8_ptr[1]);
+ *var_vec_u8++ = vec_lde(var_int[0], var_unsigned_char_ptr[1]);
+ *var_vec_u8++ = vec_ldl(var_int[0], var_unsigned_char_ptr[1]);
+ *var_vec_u8++ = vec_ldl(var_int[0], var_vec_u8_ptr[1]);
+ *var_vec_u8++ = vec_lvebx(var_int[0], var_unsigned_char_ptr[1]);
+ *var_vec_u8++ = vec_lvsl(var_int[0], var_float_ptr[1]);
+ *var_vec_u8++ = vec_lvsl(var_int[0], var_int_ptr[1]);
+ *var_vec_u8++ = vec_lvsl(var_int[0], var_long_ptr[1]);
+ *var_vec_u8++ = vec_lvsl(var_int[0], var_short_ptr[1]);
+ *var_vec_u8++ = vec_lvsl(var_int[0], var_signed_char_ptr[1]);
+ *var_vec_u8++ = vec_lvsl(var_int[0], var_unsigned_char_ptr[1]);
+ *var_vec_u8++ = vec_lvsl(var_int[0], var_unsigned_int_ptr[1]);
+ *var_vec_u8++ = vec_lvsl(var_int[0], var_unsigned_long_ptr[1]);
+ *var_vec_u8++ = vec_lvsl(var_int[0], var_unsigned_short_ptr[1]);
+ *var_vec_u8++ = vec_lvsr(var_int[0], var_float_ptr[1]);
+ *var_vec_u8++ = vec_lvsr(var_int[0], var_int_ptr[1]);
+ *var_vec_u8++ = vec_lvsr(var_int[0], var_long_ptr[1]);
+ *var_vec_u8++ = vec_lvsr(var_int[0], var_short_ptr[1]);
+ *var_vec_u8++ = vec_lvsr(var_int[0], var_signed_char_ptr[1]);
+ *var_vec_u8++ = vec_lvsr(var_int[0], var_unsigned_char_ptr[1]);
+ *var_vec_u8++ = vec_lvsr(var_int[0], var_unsigned_int_ptr[1]);
+ *var_vec_u8++ = vec_lvsr(var_int[0], var_unsigned_long_ptr[1]);
+ *var_vec_u8++ = vec_lvsr(var_int[0], var_unsigned_short_ptr[1]);
+ *var_vec_u8++ = vec_lvx(var_int[0], var_unsigned_char_ptr[1]);
+ *var_vec_u8++ = vec_lvx(var_int[0], var_vec_u8_ptr[1]);
+}
+void f26() {
+ *var_vec_u8++ = vec_lvxl(var_int[0], var_unsigned_char_ptr[1]);
+ *var_vec_u8++ = vec_lvxl(var_int[0], var_vec_u8_ptr[1]);
+ *var_vec_u8++ = vec_max(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_max(var_vec_u8[0], var_vec_b8[1]);
+ *var_vec_u8++ = vec_max(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_mergeh(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_mergel(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_min(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_min(var_vec_u8[0], var_vec_b8[1]);
+ *var_vec_u8++ = vec_min(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_nor(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_or(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_or(var_vec_u8[0], var_vec_b8[1]);
+ *var_vec_u8++ = vec_or(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_pack(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u8++ = vec_packs(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u8++ = vec_packsu(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_u8++ = vec_packsu(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u8++ = vec_perm(var_vec_u8[0], var_vec_u8[1], var_vec_u8[2]);
+ *var_vec_u8++ = vec_rl(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_sel(var_vec_u8[0], var_vec_u8[1], var_vec_b8[2]);
+ *var_vec_u8++ = vec_sel(var_vec_u8[0], var_vec_u8[1], var_vec_u8[2]);
+ *var_vec_u8++ = vec_sl(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_sld(var_vec_u8[0], var_vec_u8[1], 0);
+ *var_vec_u8++ = vec_sld(var_vec_u8[0], var_vec_u8[1], 1);
+ *var_vec_u8++ = vec_sld(var_vec_u8[0], var_vec_u8[1], 2);
+ *var_vec_u8++ = vec_sld(var_vec_u8[0], var_vec_u8[1], 3);
+ *var_vec_u8++ = vec_sld(var_vec_u8[0], var_vec_u8[1], 4);
+ *var_vec_u8++ = vec_sld(var_vec_u8[0], var_vec_u8[1], 5);
+ *var_vec_u8++ = vec_sld(var_vec_u8[0], var_vec_u8[1], 6);
+ *var_vec_u8++ = vec_sld(var_vec_u8[0], var_vec_u8[1], 7);
+ *var_vec_u8++ = vec_sld(var_vec_u8[0], var_vec_u8[1], 8);
+ *var_vec_u8++ = vec_sld(var_vec_u8[0], var_vec_u8[1], 9);
+ *var_vec_u8++ = vec_sld(var_vec_u8[0], var_vec_u8[1], 10);
+ *var_vec_u8++ = vec_sld(var_vec_u8[0], var_vec_u8[1], 11);
+ *var_vec_u8++ = vec_sld(var_vec_u8[0], var_vec_u8[1], 12);
+ *var_vec_u8++ = vec_sld(var_vec_u8[0], var_vec_u8[1], 13);
+ *var_vec_u8++ = vec_sld(var_vec_u8[0], var_vec_u8[1], 14);
+ *var_vec_u8++ = vec_sld(var_vec_u8[0], var_vec_u8[1], 15);
+ *var_vec_u8++ = vec_sll(var_vec_u8[0], var_vec_u16[1]);
+ *var_vec_u8++ = vec_sll(var_vec_u8[0], var_vec_u32[1]);
+ *var_vec_u8++ = vec_sll(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_slo(var_vec_u8[0], var_vec_s8[1]);
+ *var_vec_u8++ = vec_slo(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 0);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 1);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 2);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 3);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 4);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 5);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 6);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 7);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 8);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 9);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 10);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 11);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 12);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 13);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 14);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 15);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 16);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 17);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 18);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 19);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 20);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 21);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 22);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 23);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 24);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 25);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 26);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 27);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 28);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 29);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 30);
+ *var_vec_u8++ = vec_splat(var_vec_u8[0], 31);
+ *var_vec_u8++ = vec_splat_u8( 0);
+ *var_vec_u8++ = vec_splat_u8( 1);
+ *var_vec_u8++ = vec_splat_u8( 2);
+ *var_vec_u8++ = vec_splat_u8( 3);
+ *var_vec_u8++ = vec_splat_u8( 4);
+ *var_vec_u8++ = vec_splat_u8( 5);
+ *var_vec_u8++ = vec_splat_u8( 6);
+ *var_vec_u8++ = vec_splat_u8( 7);
+ *var_vec_u8++ = vec_splat_u8( 8);
+ *var_vec_u8++ = vec_splat_u8( 9);
+ *var_vec_u8++ = vec_splat_u8( -1);
+ *var_vec_u8++ = vec_splat_u8( -2);
+ *var_vec_u8++ = vec_splat_u8( -3);
+ *var_vec_u8++ = vec_splat_u8( -4);
+ *var_vec_u8++ = vec_splat_u8( -5);
+ *var_vec_u8++ = vec_splat_u8( -6);
+ *var_vec_u8++ = vec_splat_u8( -7);
+ *var_vec_u8++ = vec_splat_u8( -8);
+ *var_vec_u8++ = vec_splat_u8( -9);
+ *var_vec_u8++ = vec_splat_u8( 10);
+ *var_vec_u8++ = vec_splat_u8( 11);
+ *var_vec_u8++ = vec_splat_u8( 12);
+ *var_vec_u8++ = vec_splat_u8( 13);
+ *var_vec_u8++ = vec_splat_u8( 14);
+}
+void f27() {
+ *var_vec_u8++ = vec_splat_u8( 15);
+ *var_vec_u8++ = vec_splat_u8(-10);
+ *var_vec_u8++ = vec_splat_u8(-11);
+ *var_vec_u8++ = vec_splat_u8(-12);
+ *var_vec_u8++ = vec_splat_u8(-13);
+ *var_vec_u8++ = vec_splat_u8(-14);
+ *var_vec_u8++ = vec_splat_u8(-15);
+ *var_vec_u8++ = vec_splat_u8(-16);
+ *var_vec_u8++ = vec_sr(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_sra(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_srl(var_vec_u8[0], var_vec_u16[1]);
+ *var_vec_u8++ = vec_srl(var_vec_u8[0], var_vec_u32[1]);
+ *var_vec_u8++ = vec_srl(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_sro(var_vec_u8[0], var_vec_s8[1]);
+ *var_vec_u8++ = vec_sro(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_sub(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_sub(var_vec_u8[0], var_vec_b8[1]);
+ *var_vec_u8++ = vec_sub(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_subs(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_subs(var_vec_u8[0], var_vec_b8[1]);
+ *var_vec_u8++ = vec_subs(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vaddubm(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vaddubm(var_vec_u8[0], var_vec_b8[1]);
+ *var_vec_u8++ = vec_vaddubm(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vaddubs(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vaddubs(var_vec_u8[0], var_vec_b8[1]);
+ *var_vec_u8++ = vec_vaddubs(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vand(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vand(var_vec_u8[0], var_vec_b8[1]);
+ *var_vec_u8++ = vec_vand(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vandc(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vandc(var_vec_u8[0], var_vec_b8[1]);
+ *var_vec_u8++ = vec_vandc(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vavgub(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vmaxub(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vmaxub(var_vec_u8[0], var_vec_b8[1]);
+ *var_vec_u8++ = vec_vmaxub(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vminub(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vminub(var_vec_u8[0], var_vec_b8[1]);
+ *var_vec_u8++ = vec_vminub(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vmrghb(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vmrglb(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vnor(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vor(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vor(var_vec_u8[0], var_vec_b8[1]);
+ *var_vec_u8++ = vec_vor(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vperm(var_vec_u8[0], var_vec_u8[1], var_vec_u8[2]);
+ *var_vec_u8++ = vec_vpkshus(var_vec_s16[0], var_vec_s16[1]);
+ *var_vec_u8++ = vec_vpkuhum(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u8++ = vec_vpkuhus(var_vec_u16[0], var_vec_u16[1]);
+ *var_vec_u8++ = vec_vrlb(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vsel(var_vec_u8[0], var_vec_u8[1], var_vec_b8[2]);
+ *var_vec_u8++ = vec_vsel(var_vec_u8[0], var_vec_u8[1], var_vec_u8[2]);
+ *var_vec_u8++ = vec_vsl(var_vec_u8[0], var_vec_u16[1]);
+ *var_vec_u8++ = vec_vsl(var_vec_u8[0], var_vec_u32[1]);
+ *var_vec_u8++ = vec_vsl(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vslb(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vsldoi(var_vec_u8[0], var_vec_u8[1], 0);
+ *var_vec_u8++ = vec_vsldoi(var_vec_u8[0], var_vec_u8[1], 1);
+ *var_vec_u8++ = vec_vsldoi(var_vec_u8[0], var_vec_u8[1], 2);
+ *var_vec_u8++ = vec_vsldoi(var_vec_u8[0], var_vec_u8[1], 3);
+ *var_vec_u8++ = vec_vsldoi(var_vec_u8[0], var_vec_u8[1], 4);
+ *var_vec_u8++ = vec_vsldoi(var_vec_u8[0], var_vec_u8[1], 5);
+ *var_vec_u8++ = vec_vsldoi(var_vec_u8[0], var_vec_u8[1], 6);
+ *var_vec_u8++ = vec_vsldoi(var_vec_u8[0], var_vec_u8[1], 7);
+ *var_vec_u8++ = vec_vsldoi(var_vec_u8[0], var_vec_u8[1], 8);
+ *var_vec_u8++ = vec_vsldoi(var_vec_u8[0], var_vec_u8[1], 9);
+ *var_vec_u8++ = vec_vsldoi(var_vec_u8[0], var_vec_u8[1], 10);
+ *var_vec_u8++ = vec_vsldoi(var_vec_u8[0], var_vec_u8[1], 11);
+ *var_vec_u8++ = vec_vsldoi(var_vec_u8[0], var_vec_u8[1], 12);
+ *var_vec_u8++ = vec_vsldoi(var_vec_u8[0], var_vec_u8[1], 13);
+ *var_vec_u8++ = vec_vsldoi(var_vec_u8[0], var_vec_u8[1], 14);
+ *var_vec_u8++ = vec_vsldoi(var_vec_u8[0], var_vec_u8[1], 15);
+ *var_vec_u8++ = vec_vslo(var_vec_u8[0], var_vec_s8[1]);
+ *var_vec_u8++ = vec_vslo(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 0);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 1);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 2);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 3);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 4);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 5);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 6);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 7);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 8);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 9);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 10);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 11);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 12);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 13);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 14);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 15);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 16);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 17);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 18);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 19);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 20);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 21);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 22);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 23);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 24);
+}
+void f28() {
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 25);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 26);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 27);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 28);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 29);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 30);
+ *var_vec_u8++ = vec_vspltb(var_vec_u8[0], 31);
+ *var_vec_u8++ = vec_vsr(var_vec_u8[0], var_vec_u16[1]);
+ *var_vec_u8++ = vec_vsr(var_vec_u8[0], var_vec_u32[1]);
+ *var_vec_u8++ = vec_vsr(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vsrab(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vsrb(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vsro(var_vec_u8[0], var_vec_s8[1]);
+ *var_vec_u8++ = vec_vsro(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vsububm(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vsububm(var_vec_u8[0], var_vec_b8[1]);
+ *var_vec_u8++ = vec_vsububm(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vsububs(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vsububs(var_vec_u8[0], var_vec_b8[1]);
+ *var_vec_u8++ = vec_vsububs(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vxor(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_vxor(var_vec_u8[0], var_vec_b8[1]);
+ *var_vec_u8++ = vec_vxor(var_vec_u8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_xor(var_vec_b8[0], var_vec_u8[1]);
+ *var_vec_u8++ = vec_xor(var_vec_u8[0], var_vec_b8[1]);
+ *var_vec_u8++ = vec_xor(var_vec_u8[0], var_vec_u8[1]);
+ *var_volatile_vec_u16++ = vec_mfvscr();
+ if(!vec_all_eq(var_vec_b16[0], var_vec_b16[1])) *var_cc24t++;
+ if(!vec_all_eq(var_vec_b16[0], var_vec_s16[1])) *var_cc24t++;
+ if(!vec_all_eq(var_vec_b16[0], var_vec_u16[1])) *var_cc24t++;
+ if(!vec_all_eq(var_vec_b32[0], var_vec_b32[1])) *var_cc24t++;
+ if(!vec_all_eq(var_vec_b32[0], var_vec_s32[1])) *var_cc24t++;
+ if(!vec_all_eq(var_vec_b32[0], var_vec_u32[1])) *var_cc24t++;
+ if(!vec_all_eq(var_vec_b8[0], var_vec_b8[1])) *var_cc24t++;
+ if(!vec_all_eq(var_vec_b8[0], var_vec_s8[1])) *var_cc24t++;
+ if(!vec_all_eq(var_vec_b8[0], var_vec_u8[1])) *var_cc24t++;
+ if(!vec_all_eq(var_vec_f32[0], var_vec_f32[1])) *var_cc24t++;
+ if(!vec_all_eq(var_vec_p16[0], var_vec_p16[1])) *var_cc24t++;
+ if(!vec_all_eq(var_vec_s16[0], var_vec_b16[1])) *var_cc24t++;
+ if(!vec_all_eq(var_vec_s16[0], var_vec_s16[1])) *var_cc24t++;
+ if(!vec_all_eq(var_vec_s32[0], var_vec_b32[1])) *var_cc24t++;
+ if(!vec_all_eq(var_vec_s32[0], var_vec_s32[1])) *var_cc24t++;
+ if(!vec_all_eq(var_vec_s8[0], var_vec_b8[1])) *var_cc24t++;
+ if(!vec_all_eq(var_vec_s8[0], var_vec_s8[1])) *var_cc24t++;
+ if(!vec_all_eq(var_vec_u16[0], var_vec_b16[1])) *var_cc24t++;
+ if(!vec_all_eq(var_vec_u16[0], var_vec_u16[1])) *var_cc24t++;
+ if(!vec_all_eq(var_vec_u32[0], var_vec_b32[1])) *var_cc24t++;
+ if(!vec_all_eq(var_vec_u32[0], var_vec_u32[1])) *var_cc24t++;
+ if(!vec_all_eq(var_vec_u8[0], var_vec_b8[1])) *var_cc24t++;
+ if(!vec_all_eq(var_vec_u8[0], var_vec_u8[1])) *var_cc24t++;
+ if(!vec_all_ge(var_vec_b16[0], var_vec_s16[1])) *var_cc26tr++;
+ if(!vec_all_ge(var_vec_b16[0], var_vec_u16[1])) *var_cc26tr++;
+ if(!vec_all_ge(var_vec_b32[0], var_vec_s32[1])) *var_cc26tr++;
+ if(!vec_all_ge(var_vec_b32[0], var_vec_u32[1])) *var_cc26tr++;
+ if(!vec_all_ge(var_vec_b8[0], var_vec_s8[1])) *var_cc26tr++;
+ if(!vec_all_ge(var_vec_b8[0], var_vec_u8[1])) *var_cc26tr++;
+ if(!vec_all_ge(var_vec_f32[0], var_vec_f32[1])) *var_cc24t++;
+ if(!vec_all_ge(var_vec_s16[0], var_vec_b16[1])) *var_cc26tr++;
+ if(!vec_all_ge(var_vec_s16[0], var_vec_s16[1])) *var_cc26tr++;
+ if(!vec_all_ge(var_vec_s32[0], var_vec_b32[1])) *var_cc26tr++;
+ if(!vec_all_ge(var_vec_s32[0], var_vec_s32[1])) *var_cc26tr++;
+ if(!vec_all_ge(var_vec_s8[0], var_vec_b8[1])) *var_cc26tr++;
+ if(!vec_all_ge(var_vec_s8[0], var_vec_s8[1])) *var_cc26tr++;
+ if(!vec_all_ge(var_vec_u16[0], var_vec_b16[1])) *var_cc26tr++;
+ if(!vec_all_ge(var_vec_u16[0], var_vec_u16[1])) *var_cc26tr++;
+ if(!vec_all_ge(var_vec_u32[0], var_vec_b32[1])) *var_cc26tr++;
+ if(!vec_all_ge(var_vec_u32[0], var_vec_u32[1])) *var_cc26tr++;
+ if(!vec_all_ge(var_vec_u8[0], var_vec_b8[1])) *var_cc26tr++;
+ if(!vec_all_ge(var_vec_u8[0], var_vec_u8[1])) *var_cc26tr++;
+ if(!vec_all_gt(var_vec_b16[0], var_vec_s16[1])) *var_cc24t++;
+ if(!vec_all_gt(var_vec_b16[0], var_vec_u16[1])) *var_cc24t++;
+ if(!vec_all_gt(var_vec_b32[0], var_vec_s32[1])) *var_cc24t++;
+ if(!vec_all_gt(var_vec_b32[0], var_vec_u32[1])) *var_cc24t++;
+ if(!vec_all_gt(var_vec_b8[0], var_vec_s8[1])) *var_cc24t++;
+ if(!vec_all_gt(var_vec_b8[0], var_vec_u8[1])) *var_cc24t++;
+ if(!vec_all_gt(var_vec_f32[0], var_vec_f32[1])) *var_cc24t++;
+ if(!vec_all_gt(var_vec_s16[0], var_vec_b16[1])) *var_cc24t++;
+ if(!vec_all_gt(var_vec_s16[0], var_vec_s16[1])) *var_cc24t++;
+ if(!vec_all_gt(var_vec_s32[0], var_vec_b32[1])) *var_cc24t++;
+ if(!vec_all_gt(var_vec_s32[0], var_vec_s32[1])) *var_cc24t++;
+ if(!vec_all_gt(var_vec_s8[0], var_vec_b8[1])) *var_cc24t++;
+ if(!vec_all_gt(var_vec_s8[0], var_vec_s8[1])) *var_cc24t++;
+ if(!vec_all_gt(var_vec_u16[0], var_vec_b16[1])) *var_cc24t++;
+ if(!vec_all_gt(var_vec_u16[0], var_vec_u16[1])) *var_cc24t++;
+ if(!vec_all_gt(var_vec_u32[0], var_vec_b32[1])) *var_cc24t++;
+ if(!vec_all_gt(var_vec_u32[0], var_vec_u32[1])) *var_cc24t++;
+ if(!vec_all_gt(var_vec_u8[0], var_vec_b8[1])) *var_cc24t++;
+ if(!vec_all_gt(var_vec_u8[0], var_vec_u8[1])) *var_cc24t++;
+ if(!vec_all_in(var_vec_f32[0], var_vec_f32[1])) *var_cc26t++;
+ if(!vec_all_le(var_vec_b16[0], var_vec_s16[1])) *var_cc26t++;
+ if(!vec_all_le(var_vec_b16[0], var_vec_u16[1])) *var_cc26t++;
+ if(!vec_all_le(var_vec_b32[0], var_vec_s32[1])) *var_cc26t++;
+ if(!vec_all_le(var_vec_b32[0], var_vec_u32[1])) *var_cc26t++;
+ if(!vec_all_le(var_vec_b8[0], var_vec_s8[1])) *var_cc26t++;
+ if(!vec_all_le(var_vec_b8[0], var_vec_u8[1])) *var_cc26t++;
+ if(!vec_all_le(var_vec_f32[0], var_vec_f32[1])) *var_cc24tr++;
+ if(!vec_all_le(var_vec_s16[0], var_vec_b16[1])) *var_cc26t++;
+ if(!vec_all_le(var_vec_s16[0], var_vec_s16[1])) *var_cc26t++;
+ if(!vec_all_le(var_vec_s32[0], var_vec_b32[1])) *var_cc26t++;
+ if(!vec_all_le(var_vec_s32[0], var_vec_s32[1])) *var_cc26t++;
+}
+void f29() {
+ if(!vec_all_le(var_vec_s8[0], var_vec_b8[1])) *var_cc26t++;
+ if(!vec_all_le(var_vec_s8[0], var_vec_s8[1])) *var_cc26t++;
+ if(!vec_all_le(var_vec_u16[0], var_vec_b16[1])) *var_cc26t++;
+ if(!vec_all_le(var_vec_u16[0], var_vec_u16[1])) *var_cc26t++;
+ if(!vec_all_le(var_vec_u32[0], var_vec_b32[1])) *var_cc26t++;
+ if(!vec_all_le(var_vec_u32[0], var_vec_u32[1])) *var_cc26t++;
+ if(!vec_all_le(var_vec_u8[0], var_vec_b8[1])) *var_cc26t++;
+ if(!vec_all_le(var_vec_u8[0], var_vec_u8[1])) *var_cc26t++;
+ if(!vec_all_lt(var_vec_b16[0], var_vec_s16[1])) *var_cc24tr++;
+ if(!vec_all_lt(var_vec_b16[0], var_vec_u16[1])) *var_cc24tr++;
+ if(!vec_all_lt(var_vec_b32[0], var_vec_s32[1])) *var_cc24tr++;
+ if(!vec_all_lt(var_vec_b32[0], var_vec_u32[1])) *var_cc24tr++;
+ if(!vec_all_lt(var_vec_b8[0], var_vec_s8[1])) *var_cc24tr++;
+ if(!vec_all_lt(var_vec_b8[0], var_vec_u8[1])) *var_cc24tr++;
+ if(!vec_all_lt(var_vec_f32[0], var_vec_f32[1])) *var_cc24tr++;
+ if(!vec_all_lt(var_vec_s16[0], var_vec_b16[1])) *var_cc24tr++;
+ if(!vec_all_lt(var_vec_s16[0], var_vec_s16[1])) *var_cc24tr++;
+ if(!vec_all_lt(var_vec_s32[0], var_vec_b32[1])) *var_cc24tr++;
+ if(!vec_all_lt(var_vec_s32[0], var_vec_s32[1])) *var_cc24tr++;
+ if(!vec_all_lt(var_vec_s8[0], var_vec_b8[1])) *var_cc24tr++;
+ if(!vec_all_lt(var_vec_s8[0], var_vec_s8[1])) *var_cc24tr++;
+ if(!vec_all_lt(var_vec_u16[0], var_vec_b16[1])) *var_cc24tr++;
+ if(!vec_all_lt(var_vec_u16[0], var_vec_u16[1])) *var_cc24tr++;
+ if(!vec_all_lt(var_vec_u32[0], var_vec_b32[1])) *var_cc24tr++;
+ if(!vec_all_lt(var_vec_u32[0], var_vec_u32[1])) *var_cc24tr++;
+ if(!vec_all_lt(var_vec_u8[0], var_vec_b8[1])) *var_cc24tr++;
+ if(!vec_all_lt(var_vec_u8[0], var_vec_u8[1])) *var_cc24tr++;
+ if(!vec_all_nan(var_vec_f32[0])) *var_cc26td++;
+ if(!vec_all_ne(var_vec_b16[0], var_vec_b16[1])) *var_cc26t++;
+ if(!vec_all_ne(var_vec_b16[0], var_vec_s16[1])) *var_cc26t++;
+ if(!vec_all_ne(var_vec_b16[0], var_vec_u16[1])) *var_cc26t++;
+ if(!vec_all_ne(var_vec_b32[0], var_vec_b32[1])) *var_cc26t++;
+ if(!vec_all_ne(var_vec_b32[0], var_vec_s32[1])) *var_cc26t++;
+ if(!vec_all_ne(var_vec_b32[0], var_vec_u32[1])) *var_cc26t++;
+ if(!vec_all_ne(var_vec_b8[0], var_vec_b8[1])) *var_cc26t++;
+ if(!vec_all_ne(var_vec_b8[0], var_vec_s8[1])) *var_cc26t++;
+ if(!vec_all_ne(var_vec_b8[0], var_vec_u8[1])) *var_cc26t++;
+ if(!vec_all_ne(var_vec_f32[0], var_vec_f32[1])) *var_cc26t++;
+ if(!vec_all_ne(var_vec_p16[0], var_vec_p16[1])) *var_cc26t++;
+ if(!vec_all_ne(var_vec_s16[0], var_vec_b16[1])) *var_cc26t++;
+ if(!vec_all_ne(var_vec_s16[0], var_vec_s16[1])) *var_cc26t++;
+ if(!vec_all_ne(var_vec_s32[0], var_vec_b32[1])) *var_cc26t++;
+ if(!vec_all_ne(var_vec_s32[0], var_vec_s32[1])) *var_cc26t++;
+ if(!vec_all_ne(var_vec_s8[0], var_vec_b8[1])) *var_cc26t++;
+ if(!vec_all_ne(var_vec_s8[0], var_vec_s8[1])) *var_cc26t++;
+ if(!vec_all_ne(var_vec_u16[0], var_vec_b16[1])) *var_cc26t++;
+ if(!vec_all_ne(var_vec_u16[0], var_vec_u16[1])) *var_cc26t++;
+ if(!vec_all_ne(var_vec_u32[0], var_vec_b32[1])) *var_cc26t++;
+ if(!vec_all_ne(var_vec_u32[0], var_vec_u32[1])) *var_cc26t++;
+ if(!vec_all_ne(var_vec_u8[0], var_vec_b8[1])) *var_cc26t++;
+ if(!vec_all_ne(var_vec_u8[0], var_vec_u8[1])) *var_cc26t++;
+ if(!vec_all_nge(var_vec_f32[0], var_vec_f32[1])) *var_cc26t++;
+ if(!vec_all_ngt(var_vec_f32[0], var_vec_f32[1])) *var_cc26t++;
+ if(!vec_all_nle(var_vec_f32[0], var_vec_f32[1])) *var_cc26tr++;
+ if(!vec_all_nlt(var_vec_f32[0], var_vec_f32[1])) *var_cc26tr++;
+ if(!vec_all_numeric(var_vec_f32[0])) *var_cc24td++;
+ if(!vec_any_eq(var_vec_b16[0], var_vec_b16[1])) *var_cc26f++;
+ if(!vec_any_eq(var_vec_b16[0], var_vec_s16[1])) *var_cc26f++;
+ if(!vec_any_eq(var_vec_b16[0], var_vec_u16[1])) *var_cc26f++;
+ if(!vec_any_eq(var_vec_b32[0], var_vec_b32[1])) *var_cc26f++;
+ if(!vec_any_eq(var_vec_b32[0], var_vec_s32[1])) *var_cc26f++;
+ if(!vec_any_eq(var_vec_b32[0], var_vec_u32[1])) *var_cc26f++;
+ if(!vec_any_eq(var_vec_b8[0], var_vec_b8[1])) *var_cc26f++;
+ if(!vec_any_eq(var_vec_b8[0], var_vec_s8[1])) *var_cc26f++;
+ if(!vec_any_eq(var_vec_b8[0], var_vec_u8[1])) *var_cc26f++;
+ if(!vec_any_eq(var_vec_f32[0], var_vec_f32[1])) *var_cc26f++;
+ if(!vec_any_eq(var_vec_p16[0], var_vec_p16[1])) *var_cc26f++;
+ if(!vec_any_eq(var_vec_s16[0], var_vec_b16[1])) *var_cc26f++;
+ if(!vec_any_eq(var_vec_s16[0], var_vec_s16[1])) *var_cc26f++;
+ if(!vec_any_eq(var_vec_s32[0], var_vec_b32[1])) *var_cc26f++;
+ if(!vec_any_eq(var_vec_s32[0], var_vec_s32[1])) *var_cc26f++;
+ if(!vec_any_eq(var_vec_s8[0], var_vec_b8[1])) *var_cc26f++;
+ if(!vec_any_eq(var_vec_s8[0], var_vec_s8[1])) *var_cc26f++;
+ if(!vec_any_eq(var_vec_u16[0], var_vec_b16[1])) *var_cc26f++;
+ if(!vec_any_eq(var_vec_u16[0], var_vec_u16[1])) *var_cc26f++;
+ if(!vec_any_eq(var_vec_u32[0], var_vec_b32[1])) *var_cc26f++;
+ if(!vec_any_eq(var_vec_u32[0], var_vec_u32[1])) *var_cc26f++;
+ if(!vec_any_eq(var_vec_u8[0], var_vec_b8[1])) *var_cc26f++;
+ if(!vec_any_eq(var_vec_u8[0], var_vec_u8[1])) *var_cc26f++;
+ if(!vec_any_ge(var_vec_b16[0], var_vec_s16[1])) *var_cc24fr++;
+ if(!vec_any_ge(var_vec_b16[0], var_vec_u16[1])) *var_cc24fr++;
+ if(!vec_any_ge(var_vec_b32[0], var_vec_s32[1])) *var_cc24fr++;
+ if(!vec_any_ge(var_vec_b32[0], var_vec_u32[1])) *var_cc24fr++;
+ if(!vec_any_ge(var_vec_b8[0], var_vec_s8[1])) *var_cc24fr++;
+ if(!vec_any_ge(var_vec_b8[0], var_vec_u8[1])) *var_cc24fr++;
+ if(!vec_any_ge(var_vec_f32[0], var_vec_f32[1])) *var_cc26f++;
+ if(!vec_any_ge(var_vec_s16[0], var_vec_b16[1])) *var_cc24fr++;
+ if(!vec_any_ge(var_vec_s16[0], var_vec_s16[1])) *var_cc24fr++;
+ if(!vec_any_ge(var_vec_s32[0], var_vec_b32[1])) *var_cc24fr++;
+ if(!vec_any_ge(var_vec_s32[0], var_vec_s32[1])) *var_cc24fr++;
+ if(!vec_any_ge(var_vec_s8[0], var_vec_b8[1])) *var_cc24fr++;
+ if(!vec_any_ge(var_vec_s8[0], var_vec_s8[1])) *var_cc24fr++;
+ if(!vec_any_ge(var_vec_u16[0], var_vec_b16[1])) *var_cc24fr++;
+ if(!vec_any_ge(var_vec_u16[0], var_vec_u16[1])) *var_cc24fr++;
+ if(!vec_any_ge(var_vec_u32[0], var_vec_b32[1])) *var_cc24fr++;
+ if(!vec_any_ge(var_vec_u32[0], var_vec_u32[1])) *var_cc24fr++;
+ if(!vec_any_ge(var_vec_u8[0], var_vec_b8[1])) *var_cc24fr++;
+ if(!vec_any_ge(var_vec_u8[0], var_vec_u8[1])) *var_cc24fr++;
+ if(!vec_any_gt(var_vec_b16[0], var_vec_s16[1])) *var_cc26f++;
+ if(!vec_any_gt(var_vec_b16[0], var_vec_u16[1])) *var_cc26f++;
+}
+void f30() {
+ if(!vec_any_gt(var_vec_b32[0], var_vec_s32[1])) *var_cc26f++;
+ if(!vec_any_gt(var_vec_b32[0], var_vec_u32[1])) *var_cc26f++;
+ if(!vec_any_gt(var_vec_b8[0], var_vec_s8[1])) *var_cc26f++;
+ if(!vec_any_gt(var_vec_b8[0], var_vec_u8[1])) *var_cc26f++;
+ if(!vec_any_gt(var_vec_f32[0], var_vec_f32[1])) *var_cc26f++;
+ if(!vec_any_gt(var_vec_s16[0], var_vec_b16[1])) *var_cc26f++;
+ if(!vec_any_gt(var_vec_s16[0], var_vec_s16[1])) *var_cc26f++;
+ if(!vec_any_gt(var_vec_s32[0], var_vec_b32[1])) *var_cc26f++;
+ if(!vec_any_gt(var_vec_s32[0], var_vec_s32[1])) *var_cc26f++;
+ if(!vec_any_gt(var_vec_s8[0], var_vec_b8[1])) *var_cc26f++;
+ if(!vec_any_gt(var_vec_s8[0], var_vec_s8[1])) *var_cc26f++;
+ if(!vec_any_gt(var_vec_u16[0], var_vec_b16[1])) *var_cc26f++;
+ if(!vec_any_gt(var_vec_u16[0], var_vec_u16[1])) *var_cc26f++;
+ if(!vec_any_gt(var_vec_u32[0], var_vec_b32[1])) *var_cc26f++;
+ if(!vec_any_gt(var_vec_u32[0], var_vec_u32[1])) *var_cc26f++;
+ if(!vec_any_gt(var_vec_u8[0], var_vec_b8[1])) *var_cc26f++;
+ if(!vec_any_gt(var_vec_u8[0], var_vec_u8[1])) *var_cc26f++;
+ if(!vec_any_le(var_vec_b16[0], var_vec_s16[1])) *var_cc24f++;
+ if(!vec_any_le(var_vec_b16[0], var_vec_u16[1])) *var_cc24f++;
+ if(!vec_any_le(var_vec_b32[0], var_vec_s32[1])) *var_cc24f++;
+ if(!vec_any_le(var_vec_b32[0], var_vec_u32[1])) *var_cc24f++;
+ if(!vec_any_le(var_vec_b8[0], var_vec_s8[1])) *var_cc24f++;
+ if(!vec_any_le(var_vec_b8[0], var_vec_u8[1])) *var_cc24f++;
+ if(!vec_any_le(var_vec_f32[0], var_vec_f32[1])) *var_cc26fr++;
+ if(!vec_any_le(var_vec_s16[0], var_vec_b16[1])) *var_cc24f++;
+ if(!vec_any_le(var_vec_s16[0], var_vec_s16[1])) *var_cc24f++;
+ if(!vec_any_le(var_vec_s32[0], var_vec_b32[1])) *var_cc24f++;
+ if(!vec_any_le(var_vec_s32[0], var_vec_s32[1])) *var_cc24f++;
+ if(!vec_any_le(var_vec_s8[0], var_vec_b8[1])) *var_cc24f++;
+ if(!vec_any_le(var_vec_s8[0], var_vec_s8[1])) *var_cc24f++;
+ if(!vec_any_le(var_vec_u16[0], var_vec_b16[1])) *var_cc24f++;
+ if(!vec_any_le(var_vec_u16[0], var_vec_u16[1])) *var_cc24f++;
+ if(!vec_any_le(var_vec_u32[0], var_vec_b32[1])) *var_cc24f++;
+ if(!vec_any_le(var_vec_u32[0], var_vec_u32[1])) *var_cc24f++;
+ if(!vec_any_le(var_vec_u8[0], var_vec_b8[1])) *var_cc24f++;
+ if(!vec_any_le(var_vec_u8[0], var_vec_u8[1])) *var_cc24f++;
+ if(!vec_any_lt(var_vec_b16[0], var_vec_s16[1])) *var_cc26fr++;
+ if(!vec_any_lt(var_vec_b16[0], var_vec_u16[1])) *var_cc26fr++;
+ if(!vec_any_lt(var_vec_b32[0], var_vec_s32[1])) *var_cc26fr++;
+ if(!vec_any_lt(var_vec_b32[0], var_vec_u32[1])) *var_cc26fr++;
+ if(!vec_any_lt(var_vec_b8[0], var_vec_s8[1])) *var_cc26fr++;
+ if(!vec_any_lt(var_vec_b8[0], var_vec_u8[1])) *var_cc26fr++;
+ if(!vec_any_lt(var_vec_f32[0], var_vec_f32[1])) *var_cc26fr++;
+ if(!vec_any_lt(var_vec_s16[0], var_vec_b16[1])) *var_cc26fr++;
+ if(!vec_any_lt(var_vec_s16[0], var_vec_s16[1])) *var_cc26fr++;
+ if(!vec_any_lt(var_vec_s32[0], var_vec_b32[1])) *var_cc26fr++;
+ if(!vec_any_lt(var_vec_s32[0], var_vec_s32[1])) *var_cc26fr++;
+ if(!vec_any_lt(var_vec_s8[0], var_vec_b8[1])) *var_cc26fr++;
+ if(!vec_any_lt(var_vec_s8[0], var_vec_s8[1])) *var_cc26fr++;
+ if(!vec_any_lt(var_vec_u16[0], var_vec_b16[1])) *var_cc26fr++;
+ if(!vec_any_lt(var_vec_u16[0], var_vec_u16[1])) *var_cc26fr++;
+ if(!vec_any_lt(var_vec_u32[0], var_vec_b32[1])) *var_cc26fr++;
+ if(!vec_any_lt(var_vec_u32[0], var_vec_u32[1])) *var_cc26fr++;
+ if(!vec_any_lt(var_vec_u8[0], var_vec_b8[1])) *var_cc26fr++;
+ if(!vec_any_lt(var_vec_u8[0], var_vec_u8[1])) *var_cc26fr++;
+ if(!vec_any_nan(var_vec_f32[0])) *var_cc24fd++;
+ if(!vec_any_ne(var_vec_b16[0], var_vec_b16[1])) *var_cc24f++;
+ if(!vec_any_ne(var_vec_b16[0], var_vec_s16[1])) *var_cc24f++;
+ if(!vec_any_ne(var_vec_b16[0], var_vec_u16[1])) *var_cc24f++;
+ if(!vec_any_ne(var_vec_b32[0], var_vec_b32[1])) *var_cc24f++;
+ if(!vec_any_ne(var_vec_b32[0], var_vec_s32[1])) *var_cc24f++;
+ if(!vec_any_ne(var_vec_b32[0], var_vec_u32[1])) *var_cc24f++;
+ if(!vec_any_ne(var_vec_b8[0], var_vec_b8[1])) *var_cc24f++;
+ if(!vec_any_ne(var_vec_b8[0], var_vec_s8[1])) *var_cc24f++;
+ if(!vec_any_ne(var_vec_b8[0], var_vec_u8[1])) *var_cc24f++;
+ if(!vec_any_ne(var_vec_f32[0], var_vec_f32[1])) *var_cc24f++;
+ if(!vec_any_ne(var_vec_p16[0], var_vec_p16[1])) *var_cc24f++;
+ if(!vec_any_ne(var_vec_s16[0], var_vec_b16[1])) *var_cc24f++;
+ if(!vec_any_ne(var_vec_s16[0], var_vec_s16[1])) *var_cc24f++;
+ if(!vec_any_ne(var_vec_s32[0], var_vec_b32[1])) *var_cc24f++;
+ if(!vec_any_ne(var_vec_s32[0], var_vec_s32[1])) *var_cc24f++;
+ if(!vec_any_ne(var_vec_s8[0], var_vec_b8[1])) *var_cc24f++;
+ if(!vec_any_ne(var_vec_s8[0], var_vec_s8[1])) *var_cc24f++;
+ if(!vec_any_ne(var_vec_u16[0], var_vec_b16[1])) *var_cc24f++;
+ if(!vec_any_ne(var_vec_u16[0], var_vec_u16[1])) *var_cc24f++;
+ if(!vec_any_ne(var_vec_u32[0], var_vec_b32[1])) *var_cc24f++;
+ if(!vec_any_ne(var_vec_u32[0], var_vec_u32[1])) *var_cc24f++;
+ if(!vec_any_ne(var_vec_u8[0], var_vec_b8[1])) *var_cc24f++;
+ if(!vec_any_ne(var_vec_u8[0], var_vec_u8[1])) *var_cc24f++;
+ if(!vec_any_nge(var_vec_f32[0], var_vec_f32[1])) *var_cc24f++;
+ if(!vec_any_ngt(var_vec_f32[0], var_vec_f32[1])) *var_cc24f++;
+ if(!vec_any_nle(var_vec_f32[0], var_vec_f32[1])) *var_cc24fr++;
+ if(!vec_any_nlt(var_vec_f32[0], var_vec_f32[1])) *var_cc24fr++;
+ if(!vec_any_numeric(var_vec_f32[0])) *var_cc26fd++;
+ if(!vec_any_out(var_vec_f32[0], var_vec_f32[1])) *var_cc26f++;
+ if(vec_all_eq(var_vec_b16[0], var_vec_b16[1])) *var_cc24t++;
+ if(vec_all_eq(var_vec_b16[0], var_vec_s16[1])) *var_cc24t++;
+ if(vec_all_eq(var_vec_b16[0], var_vec_u16[1])) *var_cc24t++;
+ if(vec_all_eq(var_vec_b32[0], var_vec_b32[1])) *var_cc24t++;
+ if(vec_all_eq(var_vec_b32[0], var_vec_s32[1])) *var_cc24t++;
+ if(vec_all_eq(var_vec_b32[0], var_vec_u32[1])) *var_cc24t++;
+ if(vec_all_eq(var_vec_b8[0], var_vec_b8[1])) *var_cc24t++;
+ if(vec_all_eq(var_vec_b8[0], var_vec_s8[1])) *var_cc24t++;
+ if(vec_all_eq(var_vec_b8[0], var_vec_u8[1])) *var_cc24t++;
+ if(vec_all_eq(var_vec_f32[0], var_vec_f32[1])) *var_cc24t++;
+ if(vec_all_eq(var_vec_p16[0], var_vec_p16[1])) *var_cc24t++;
+ if(vec_all_eq(var_vec_s16[0], var_vec_b16[1])) *var_cc24t++;
+ if(vec_all_eq(var_vec_s16[0], var_vec_s16[1])) *var_cc24t++;
+ if(vec_all_eq(var_vec_s32[0], var_vec_b32[1])) *var_cc24t++;
+ if(vec_all_eq(var_vec_s32[0], var_vec_s32[1])) *var_cc24t++;
+}
+void f31() {
+ if(vec_all_eq(var_vec_s8[0], var_vec_b8[1])) *var_cc24t++;
+ if(vec_all_eq(var_vec_s8[0], var_vec_s8[1])) *var_cc24t++;
+ if(vec_all_eq(var_vec_u16[0], var_vec_b16[1])) *var_cc24t++;
+ if(vec_all_eq(var_vec_u16[0], var_vec_u16[1])) *var_cc24t++;
+ if(vec_all_eq(var_vec_u32[0], var_vec_b32[1])) *var_cc24t++;
+ if(vec_all_eq(var_vec_u32[0], var_vec_u32[1])) *var_cc24t++;
+ if(vec_all_eq(var_vec_u8[0], var_vec_b8[1])) *var_cc24t++;
+ if(vec_all_eq(var_vec_u8[0], var_vec_u8[1])) *var_cc24t++;
+ if(vec_all_ge(var_vec_b16[0], var_vec_s16[1])) *var_cc26tr++;
+ if(vec_all_ge(var_vec_b16[0], var_vec_u16[1])) *var_cc26tr++;
+ if(vec_all_ge(var_vec_b32[0], var_vec_s32[1])) *var_cc26tr++;
+ if(vec_all_ge(var_vec_b32[0], var_vec_u32[1])) *var_cc26tr++;
+ if(vec_all_ge(var_vec_b8[0], var_vec_s8[1])) *var_cc26tr++;
+ if(vec_all_ge(var_vec_b8[0], var_vec_u8[1])) *var_cc26tr++;
+ if(vec_all_ge(var_vec_f32[0], var_vec_f32[1])) *var_cc24t++;
+ if(vec_all_ge(var_vec_s16[0], var_vec_b16[1])) *var_cc26tr++;
+ if(vec_all_ge(var_vec_s16[0], var_vec_s16[1])) *var_cc26tr++;
+ if(vec_all_ge(var_vec_s32[0], var_vec_b32[1])) *var_cc26tr++;
+ if(vec_all_ge(var_vec_s32[0], var_vec_s32[1])) *var_cc26tr++;
+ if(vec_all_ge(var_vec_s8[0], var_vec_b8[1])) *var_cc26tr++;
+ if(vec_all_ge(var_vec_s8[0], var_vec_s8[1])) *var_cc26tr++;
+ if(vec_all_ge(var_vec_u16[0], var_vec_b16[1])) *var_cc26tr++;
+ if(vec_all_ge(var_vec_u16[0], var_vec_u16[1])) *var_cc26tr++;
+ if(vec_all_ge(var_vec_u32[0], var_vec_b32[1])) *var_cc26tr++;
+ if(vec_all_ge(var_vec_u32[0], var_vec_u32[1])) *var_cc26tr++;
+ if(vec_all_ge(var_vec_u8[0], var_vec_b8[1])) *var_cc26tr++;
+ if(vec_all_ge(var_vec_u8[0], var_vec_u8[1])) *var_cc26tr++;
+ if(vec_all_gt(var_vec_b16[0], var_vec_s16[1])) *var_cc24t++;
+ if(vec_all_gt(var_vec_b16[0], var_vec_u16[1])) *var_cc24t++;
+ if(vec_all_gt(var_vec_b32[0], var_vec_s32[1])) *var_cc24t++;
+ if(vec_all_gt(var_vec_b32[0], var_vec_u32[1])) *var_cc24t++;
+ if(vec_all_gt(var_vec_b8[0], var_vec_s8[1])) *var_cc24t++;
+ if(vec_all_gt(var_vec_b8[0], var_vec_u8[1])) *var_cc24t++;
+ if(vec_all_gt(var_vec_f32[0], var_vec_f32[1])) *var_cc24t++;
+ if(vec_all_gt(var_vec_s16[0], var_vec_b16[1])) *var_cc24t++;
+ if(vec_all_gt(var_vec_s16[0], var_vec_s16[1])) *var_cc24t++;
+ if(vec_all_gt(var_vec_s32[0], var_vec_b32[1])) *var_cc24t++;
+ if(vec_all_gt(var_vec_s32[0], var_vec_s32[1])) *var_cc24t++;
+ if(vec_all_gt(var_vec_s8[0], var_vec_b8[1])) *var_cc24t++;
+ if(vec_all_gt(var_vec_s8[0], var_vec_s8[1])) *var_cc24t++;
+ if(vec_all_gt(var_vec_u16[0], var_vec_b16[1])) *var_cc24t++;
+ if(vec_all_gt(var_vec_u16[0], var_vec_u16[1])) *var_cc24t++;
+ if(vec_all_gt(var_vec_u32[0], var_vec_b32[1])) *var_cc24t++;
+ if(vec_all_gt(var_vec_u32[0], var_vec_u32[1])) *var_cc24t++;
+ if(vec_all_gt(var_vec_u8[0], var_vec_b8[1])) *var_cc24t++;
+ if(vec_all_gt(var_vec_u8[0], var_vec_u8[1])) *var_cc24t++;
+ if(vec_all_in(var_vec_f32[0], var_vec_f32[1])) *var_cc26t++;
+ if(vec_all_le(var_vec_b16[0], var_vec_s16[1])) *var_cc26t++;
+ if(vec_all_le(var_vec_b16[0], var_vec_u16[1])) *var_cc26t++;
+ if(vec_all_le(var_vec_b32[0], var_vec_s32[1])) *var_cc26t++;
+ if(vec_all_le(var_vec_b32[0], var_vec_u32[1])) *var_cc26t++;
+ if(vec_all_le(var_vec_b8[0], var_vec_s8[1])) *var_cc26t++;
+ if(vec_all_le(var_vec_b8[0], var_vec_u8[1])) *var_cc26t++;
+ if(vec_all_le(var_vec_f32[0], var_vec_f32[1])) *var_cc24tr++;
+ if(vec_all_le(var_vec_s16[0], var_vec_b16[1])) *var_cc26t++;
+ if(vec_all_le(var_vec_s16[0], var_vec_s16[1])) *var_cc26t++;
+ if(vec_all_le(var_vec_s32[0], var_vec_b32[1])) *var_cc26t++;
+ if(vec_all_le(var_vec_s32[0], var_vec_s32[1])) *var_cc26t++;
+ if(vec_all_le(var_vec_s8[0], var_vec_b8[1])) *var_cc26t++;
+ if(vec_all_le(var_vec_s8[0], var_vec_s8[1])) *var_cc26t++;
+ if(vec_all_le(var_vec_u16[0], var_vec_b16[1])) *var_cc26t++;
+ if(vec_all_le(var_vec_u16[0], var_vec_u16[1])) *var_cc26t++;
+ if(vec_all_le(var_vec_u32[0], var_vec_b32[1])) *var_cc26t++;
+ if(vec_all_le(var_vec_u32[0], var_vec_u32[1])) *var_cc26t++;
+ if(vec_all_le(var_vec_u8[0], var_vec_b8[1])) *var_cc26t++;
+ if(vec_all_le(var_vec_u8[0], var_vec_u8[1])) *var_cc26t++;
+ if(vec_all_lt(var_vec_b16[0], var_vec_s16[1])) *var_cc24tr++;
+ if(vec_all_lt(var_vec_b16[0], var_vec_u16[1])) *var_cc24tr++;
+ if(vec_all_lt(var_vec_b32[0], var_vec_s32[1])) *var_cc24tr++;
+ if(vec_all_lt(var_vec_b32[0], var_vec_u32[1])) *var_cc24tr++;
+ if(vec_all_lt(var_vec_b8[0], var_vec_s8[1])) *var_cc24tr++;
+ if(vec_all_lt(var_vec_b8[0], var_vec_u8[1])) *var_cc24tr++;
+ if(vec_all_lt(var_vec_f32[0], var_vec_f32[1])) *var_cc24tr++;
+ if(vec_all_lt(var_vec_s16[0], var_vec_b16[1])) *var_cc24tr++;
+ if(vec_all_lt(var_vec_s16[0], var_vec_s16[1])) *var_cc24tr++;
+ if(vec_all_lt(var_vec_s32[0], var_vec_b32[1])) *var_cc24tr++;
+ if(vec_all_lt(var_vec_s32[0], var_vec_s32[1])) *var_cc24tr++;
+ if(vec_all_lt(var_vec_s8[0], var_vec_b8[1])) *var_cc24tr++;
+ if(vec_all_lt(var_vec_s8[0], var_vec_s8[1])) *var_cc24tr++;
+ if(vec_all_lt(var_vec_u16[0], var_vec_b16[1])) *var_cc24tr++;
+ if(vec_all_lt(var_vec_u16[0], var_vec_u16[1])) *var_cc24tr++;
+ if(vec_all_lt(var_vec_u32[0], var_vec_b32[1])) *var_cc24tr++;
+ if(vec_all_lt(var_vec_u32[0], var_vec_u32[1])) *var_cc24tr++;
+ if(vec_all_lt(var_vec_u8[0], var_vec_b8[1])) *var_cc24tr++;
+ if(vec_all_lt(var_vec_u8[0], var_vec_u8[1])) *var_cc24tr++;
+ if(vec_all_nan(var_vec_f32[0])) *var_cc26td++;
+ if(vec_all_ne(var_vec_b16[0], var_vec_b16[1])) *var_cc26t++;
+ if(vec_all_ne(var_vec_b16[0], var_vec_s16[1])) *var_cc26t++;
+ if(vec_all_ne(var_vec_b16[0], var_vec_u16[1])) *var_cc26t++;
+ if(vec_all_ne(var_vec_b32[0], var_vec_b32[1])) *var_cc26t++;
+ if(vec_all_ne(var_vec_b32[0], var_vec_s32[1])) *var_cc26t++;
+ if(vec_all_ne(var_vec_b32[0], var_vec_u32[1])) *var_cc26t++;
+ if(vec_all_ne(var_vec_b8[0], var_vec_b8[1])) *var_cc26t++;
+ if(vec_all_ne(var_vec_b8[0], var_vec_s8[1])) *var_cc26t++;
+ if(vec_all_ne(var_vec_b8[0], var_vec_u8[1])) *var_cc26t++;
+ if(vec_all_ne(var_vec_f32[0], var_vec_f32[1])) *var_cc26t++;
+ if(vec_all_ne(var_vec_p16[0], var_vec_p16[1])) *var_cc26t++;
+ if(vec_all_ne(var_vec_s16[0], var_vec_b16[1])) *var_cc26t++;
+ if(vec_all_ne(var_vec_s16[0], var_vec_s16[1])) *var_cc26t++;
+ if(vec_all_ne(var_vec_s32[0], var_vec_b32[1])) *var_cc26t++;
+}
+void f32() {
+ if(vec_all_ne(var_vec_s32[0], var_vec_s32[1])) *var_cc26t++;
+ if(vec_all_ne(var_vec_s8[0], var_vec_b8[1])) *var_cc26t++;
+ if(vec_all_ne(var_vec_s8[0], var_vec_s8[1])) *var_cc26t++;
+ if(vec_all_ne(var_vec_u16[0], var_vec_b16[1])) *var_cc26t++;
+ if(vec_all_ne(var_vec_u16[0], var_vec_u16[1])) *var_cc26t++;
+ if(vec_all_ne(var_vec_u32[0], var_vec_b32[1])) *var_cc26t++;
+ if(vec_all_ne(var_vec_u32[0], var_vec_u32[1])) *var_cc26t++;
+ if(vec_all_ne(var_vec_u8[0], var_vec_b8[1])) *var_cc26t++;
+ if(vec_all_ne(var_vec_u8[0], var_vec_u8[1])) *var_cc26t++;
+ if(vec_all_nge(var_vec_f32[0], var_vec_f32[1])) *var_cc26t++;
+ if(vec_all_ngt(var_vec_f32[0], var_vec_f32[1])) *var_cc26t++;
+ if(vec_all_nle(var_vec_f32[0], var_vec_f32[1])) *var_cc26tr++;
+ if(vec_all_nlt(var_vec_f32[0], var_vec_f32[1])) *var_cc26tr++;
+ if(vec_all_numeric(var_vec_f32[0])) *var_cc24td++;
+ if(vec_any_eq(var_vec_b16[0], var_vec_b16[1])) *var_cc26f++;
+ if(vec_any_eq(var_vec_b16[0], var_vec_s16[1])) *var_cc26f++;
+ if(vec_any_eq(var_vec_b16[0], var_vec_u16[1])) *var_cc26f++;
+ if(vec_any_eq(var_vec_b32[0], var_vec_b32[1])) *var_cc26f++;
+ if(vec_any_eq(var_vec_b32[0], var_vec_s32[1])) *var_cc26f++;
+ if(vec_any_eq(var_vec_b32[0], var_vec_u32[1])) *var_cc26f++;
+ if(vec_any_eq(var_vec_b8[0], var_vec_b8[1])) *var_cc26f++;
+ if(vec_any_eq(var_vec_b8[0], var_vec_s8[1])) *var_cc26f++;
+ if(vec_any_eq(var_vec_b8[0], var_vec_u8[1])) *var_cc26f++;
+ if(vec_any_eq(var_vec_f32[0], var_vec_f32[1])) *var_cc26f++;
+ if(vec_any_eq(var_vec_p16[0], var_vec_p16[1])) *var_cc26f++;
+ if(vec_any_eq(var_vec_s16[0], var_vec_b16[1])) *var_cc26f++;
+ if(vec_any_eq(var_vec_s16[0], var_vec_s16[1])) *var_cc26f++;
+ if(vec_any_eq(var_vec_s32[0], var_vec_b32[1])) *var_cc26f++;
+ if(vec_any_eq(var_vec_s32[0], var_vec_s32[1])) *var_cc26f++;
+ if(vec_any_eq(var_vec_s8[0], var_vec_b8[1])) *var_cc26f++;
+ if(vec_any_eq(var_vec_s8[0], var_vec_s8[1])) *var_cc26f++;
+ if(vec_any_eq(var_vec_u16[0], var_vec_b16[1])) *var_cc26f++;
+ if(vec_any_eq(var_vec_u16[0], var_vec_u16[1])) *var_cc26f++;
+ if(vec_any_eq(var_vec_u32[0], var_vec_b32[1])) *var_cc26f++;
+ if(vec_any_eq(var_vec_u32[0], var_vec_u32[1])) *var_cc26f++;
+ if(vec_any_eq(var_vec_u8[0], var_vec_b8[1])) *var_cc26f++;
+ if(vec_any_eq(var_vec_u8[0], var_vec_u8[1])) *var_cc26f++;
+ if(vec_any_ge(var_vec_b16[0], var_vec_s16[1])) *var_cc24fr++;
+ if(vec_any_ge(var_vec_b16[0], var_vec_u16[1])) *var_cc24fr++;
+ if(vec_any_ge(var_vec_b32[0], var_vec_s32[1])) *var_cc24fr++;
+ if(vec_any_ge(var_vec_b32[0], var_vec_u32[1])) *var_cc24fr++;
+ if(vec_any_ge(var_vec_b8[0], var_vec_s8[1])) *var_cc24fr++;
+ if(vec_any_ge(var_vec_b8[0], var_vec_u8[1])) *var_cc24fr++;
+ if(vec_any_ge(var_vec_f32[0], var_vec_f32[1])) *var_cc26f++;
+ if(vec_any_ge(var_vec_s16[0], var_vec_b16[1])) *var_cc24fr++;
+ if(vec_any_ge(var_vec_s16[0], var_vec_s16[1])) *var_cc24fr++;
+ if(vec_any_ge(var_vec_s32[0], var_vec_b32[1])) *var_cc24fr++;
+ if(vec_any_ge(var_vec_s32[0], var_vec_s32[1])) *var_cc24fr++;
+ if(vec_any_ge(var_vec_s8[0], var_vec_b8[1])) *var_cc24fr++;
+ if(vec_any_ge(var_vec_s8[0], var_vec_s8[1])) *var_cc24fr++;
+ if(vec_any_ge(var_vec_u16[0], var_vec_b16[1])) *var_cc24fr++;
+ if(vec_any_ge(var_vec_u16[0], var_vec_u16[1])) *var_cc24fr++;
+ if(vec_any_ge(var_vec_u32[0], var_vec_b32[1])) *var_cc24fr++;
+ if(vec_any_ge(var_vec_u32[0], var_vec_u32[1])) *var_cc24fr++;
+ if(vec_any_ge(var_vec_u8[0], var_vec_b8[1])) *var_cc24fr++;
+ if(vec_any_ge(var_vec_u8[0], var_vec_u8[1])) *var_cc24fr++;
+ if(vec_any_gt(var_vec_b16[0], var_vec_s16[1])) *var_cc26f++;
+ if(vec_any_gt(var_vec_b16[0], var_vec_u16[1])) *var_cc26f++;
+ if(vec_any_gt(var_vec_b32[0], var_vec_s32[1])) *var_cc26f++;
+ if(vec_any_gt(var_vec_b32[0], var_vec_u32[1])) *var_cc26f++;
+ if(vec_any_gt(var_vec_b8[0], var_vec_s8[1])) *var_cc26f++;
+ if(vec_any_gt(var_vec_b8[0], var_vec_u8[1])) *var_cc26f++;
+ if(vec_any_gt(var_vec_f32[0], var_vec_f32[1])) *var_cc26f++;
+ if(vec_any_gt(var_vec_s16[0], var_vec_b16[1])) *var_cc26f++;
+ if(vec_any_gt(var_vec_s16[0], var_vec_s16[1])) *var_cc26f++;
+ if(vec_any_gt(var_vec_s32[0], var_vec_b32[1])) *var_cc26f++;
+ if(vec_any_gt(var_vec_s32[0], var_vec_s32[1])) *var_cc26f++;
+ if(vec_any_gt(var_vec_s8[0], var_vec_b8[1])) *var_cc26f++;
+ if(vec_any_gt(var_vec_s8[0], var_vec_s8[1])) *var_cc26f++;
+ if(vec_any_gt(var_vec_u16[0], var_vec_b16[1])) *var_cc26f++;
+ if(vec_any_gt(var_vec_u16[0], var_vec_u16[1])) *var_cc26f++;
+ if(vec_any_gt(var_vec_u32[0], var_vec_b32[1])) *var_cc26f++;
+ if(vec_any_gt(var_vec_u32[0], var_vec_u32[1])) *var_cc26f++;
+ if(vec_any_gt(var_vec_u8[0], var_vec_b8[1])) *var_cc26f++;
+ if(vec_any_gt(var_vec_u8[0], var_vec_u8[1])) *var_cc26f++;
+ if(vec_any_le(var_vec_b16[0], var_vec_s16[1])) *var_cc24f++;
+ if(vec_any_le(var_vec_b16[0], var_vec_u16[1])) *var_cc24f++;
+ if(vec_any_le(var_vec_b32[0], var_vec_s32[1])) *var_cc24f++;
+ if(vec_any_le(var_vec_b32[0], var_vec_u32[1])) *var_cc24f++;
+ if(vec_any_le(var_vec_b8[0], var_vec_s8[1])) *var_cc24f++;
+ if(vec_any_le(var_vec_b8[0], var_vec_u8[1])) *var_cc24f++;
+ if(vec_any_le(var_vec_f32[0], var_vec_f32[1])) *var_cc26fr++;
+ if(vec_any_le(var_vec_s16[0], var_vec_b16[1])) *var_cc24f++;
+ if(vec_any_le(var_vec_s16[0], var_vec_s16[1])) *var_cc24f++;
+ if(vec_any_le(var_vec_s32[0], var_vec_b32[1])) *var_cc24f++;
+ if(vec_any_le(var_vec_s32[0], var_vec_s32[1])) *var_cc24f++;
+ if(vec_any_le(var_vec_s8[0], var_vec_b8[1])) *var_cc24f++;
+ if(vec_any_le(var_vec_s8[0], var_vec_s8[1])) *var_cc24f++;
+ if(vec_any_le(var_vec_u16[0], var_vec_b16[1])) *var_cc24f++;
+ if(vec_any_le(var_vec_u16[0], var_vec_u16[1])) *var_cc24f++;
+ if(vec_any_le(var_vec_u32[0], var_vec_b32[1])) *var_cc24f++;
+ if(vec_any_le(var_vec_u32[0], var_vec_u32[1])) *var_cc24f++;
+ if(vec_any_le(var_vec_u8[0], var_vec_b8[1])) *var_cc24f++;
+ if(vec_any_le(var_vec_u8[0], var_vec_u8[1])) *var_cc24f++;
+ if(vec_any_lt(var_vec_b16[0], var_vec_s16[1])) *var_cc26fr++;
+ if(vec_any_lt(var_vec_b16[0], var_vec_u16[1])) *var_cc26fr++;
+ if(vec_any_lt(var_vec_b32[0], var_vec_s32[1])) *var_cc26fr++;
+ if(vec_any_lt(var_vec_b32[0], var_vec_u32[1])) *var_cc26fr++;
+ if(vec_any_lt(var_vec_b8[0], var_vec_s8[1])) *var_cc26fr++;
+ if(vec_any_lt(var_vec_b8[0], var_vec_u8[1])) *var_cc26fr++;
+}
+void f33() {
+ if(vec_any_lt(var_vec_f32[0], var_vec_f32[1])) *var_cc26fr++;
+ if(vec_any_lt(var_vec_s16[0], var_vec_b16[1])) *var_cc26fr++;
+ if(vec_any_lt(var_vec_s16[0], var_vec_s16[1])) *var_cc26fr++;
+ if(vec_any_lt(var_vec_s32[0], var_vec_b32[1])) *var_cc26fr++;
+ if(vec_any_lt(var_vec_s32[0], var_vec_s32[1])) *var_cc26fr++;
+ if(vec_any_lt(var_vec_s8[0], var_vec_b8[1])) *var_cc26fr++;
+ if(vec_any_lt(var_vec_s8[0], var_vec_s8[1])) *var_cc26fr++;
+ if(vec_any_lt(var_vec_u16[0], var_vec_b16[1])) *var_cc26fr++;
+ if(vec_any_lt(var_vec_u16[0], var_vec_u16[1])) *var_cc26fr++;
+ if(vec_any_lt(var_vec_u32[0], var_vec_b32[1])) *var_cc26fr++;
+ if(vec_any_lt(var_vec_u32[0], var_vec_u32[1])) *var_cc26fr++;
+ if(vec_any_lt(var_vec_u8[0], var_vec_b8[1])) *var_cc26fr++;
+ if(vec_any_lt(var_vec_u8[0], var_vec_u8[1])) *var_cc26fr++;
+ if(vec_any_nan(var_vec_f32[0])) *var_cc24fd++;
+ if(vec_any_ne(var_vec_b16[0], var_vec_b16[1])) *var_cc24f++;
+ if(vec_any_ne(var_vec_b16[0], var_vec_s16[1])) *var_cc24f++;
+ if(vec_any_ne(var_vec_b16[0], var_vec_u16[1])) *var_cc24f++;
+ if(vec_any_ne(var_vec_b32[0], var_vec_b32[1])) *var_cc24f++;
+ if(vec_any_ne(var_vec_b32[0], var_vec_s32[1])) *var_cc24f++;
+ if(vec_any_ne(var_vec_b32[0], var_vec_u32[1])) *var_cc24f++;
+ if(vec_any_ne(var_vec_b8[0], var_vec_b8[1])) *var_cc24f++;
+ if(vec_any_ne(var_vec_b8[0], var_vec_s8[1])) *var_cc24f++;
+ if(vec_any_ne(var_vec_b8[0], var_vec_u8[1])) *var_cc24f++;
+ if(vec_any_ne(var_vec_f32[0], var_vec_f32[1])) *var_cc24f++;
+ if(vec_any_ne(var_vec_p16[0], var_vec_p16[1])) *var_cc24f++;
+ if(vec_any_ne(var_vec_s16[0], var_vec_b16[1])) *var_cc24f++;
+ if(vec_any_ne(var_vec_s16[0], var_vec_s16[1])) *var_cc24f++;
+ if(vec_any_ne(var_vec_s32[0], var_vec_b32[1])) *var_cc24f++;
+ if(vec_any_ne(var_vec_s32[0], var_vec_s32[1])) *var_cc24f++;
+ if(vec_any_ne(var_vec_s8[0], var_vec_b8[1])) *var_cc24f++;
+ if(vec_any_ne(var_vec_s8[0], var_vec_s8[1])) *var_cc24f++;
+ if(vec_any_ne(var_vec_u16[0], var_vec_b16[1])) *var_cc24f++;
+ if(vec_any_ne(var_vec_u16[0], var_vec_u16[1])) *var_cc24f++;
+ if(vec_any_ne(var_vec_u32[0], var_vec_b32[1])) *var_cc24f++;
+ if(vec_any_ne(var_vec_u32[0], var_vec_u32[1])) *var_cc24f++;
+ if(vec_any_ne(var_vec_u8[0], var_vec_b8[1])) *var_cc24f++;
+ if(vec_any_ne(var_vec_u8[0], var_vec_u8[1])) *var_cc24f++;
+ if(vec_any_nge(var_vec_f32[0], var_vec_f32[1])) *var_cc24f++;
+ if(vec_any_ngt(var_vec_f32[0], var_vec_f32[1])) *var_cc24f++;
+ if(vec_any_nle(var_vec_f32[0], var_vec_f32[1])) *var_cc24fr++;
+ if(vec_any_nlt(var_vec_f32[0], var_vec_f32[1])) *var_cc24fr++;
+ if(vec_any_numeric(var_vec_f32[0])) *var_cc26fd++;
+ if(vec_any_out(var_vec_f32[0], var_vec_f32[1])) *var_cc26f++;
+ vec_dss( 0);
+ vec_dss( 1);
+ vec_dss( 2);
+ vec_dss( 3);
+ vec_dssall();
+ vec_dst(var_float_ptr[0], var_int[1], 0);
+ vec_dst(var_float_ptr[0], var_int[1], 1);
+ vec_dst(var_float_ptr[0], var_int[1], 2);
+ vec_dst(var_float_ptr[0], var_int[1], 3);
+ vec_dst(var_int_ptr[0], var_int[1], 0);
+ vec_dst(var_int_ptr[0], var_int[1], 1);
+ vec_dst(var_int_ptr[0], var_int[1], 2);
+ vec_dst(var_int_ptr[0], var_int[1], 3);
+ vec_dst(var_long_ptr[0], var_int[1], 0);
+ vec_dst(var_long_ptr[0], var_int[1], 1);
+ vec_dst(var_long_ptr[0], var_int[1], 2);
+ vec_dst(var_long_ptr[0], var_int[1], 3);
+ vec_dst(var_short_ptr[0], var_int[1], 0);
+ vec_dst(var_short_ptr[0], var_int[1], 1);
+ vec_dst(var_short_ptr[0], var_int[1], 2);
+ vec_dst(var_short_ptr[0], var_int[1], 3);
+ vec_dst(var_signed_char_ptr[0], var_int[1], 0);
+ vec_dst(var_signed_char_ptr[0], var_int[1], 1);
+ vec_dst(var_signed_char_ptr[0], var_int[1], 2);
+ vec_dst(var_signed_char_ptr[0], var_int[1], 3);
+ vec_dst(var_unsigned_char_ptr[0], var_int[1], 0);
+ vec_dst(var_unsigned_char_ptr[0], var_int[1], 1);
+ vec_dst(var_unsigned_char_ptr[0], var_int[1], 2);
+ vec_dst(var_unsigned_char_ptr[0], var_int[1], 3);
+ vec_dst(var_unsigned_int_ptr[0], var_int[1], 0);
+ vec_dst(var_unsigned_int_ptr[0], var_int[1], 1);
+ vec_dst(var_unsigned_int_ptr[0], var_int[1], 2);
+ vec_dst(var_unsigned_int_ptr[0], var_int[1], 3);
+ vec_dst(var_unsigned_long_ptr[0], var_int[1], 0);
+ vec_dst(var_unsigned_long_ptr[0], var_int[1], 1);
+ vec_dst(var_unsigned_long_ptr[0], var_int[1], 2);
+ vec_dst(var_unsigned_long_ptr[0], var_int[1], 3);
+ vec_dst(var_unsigned_short_ptr[0], var_int[1], 0);
+ vec_dst(var_unsigned_short_ptr[0], var_int[1], 1);
+ vec_dst(var_unsigned_short_ptr[0], var_int[1], 2);
+ vec_dst(var_unsigned_short_ptr[0], var_int[1], 3);
+ vec_dst(var_vec_b16_ptr[0], var_int[1], 0);
+ vec_dst(var_vec_b16_ptr[0], var_int[1], 1);
+ vec_dst(var_vec_b16_ptr[0], var_int[1], 2);
+ vec_dst(var_vec_b16_ptr[0], var_int[1], 3);
+ vec_dst(var_vec_b32_ptr[0], var_int[1], 0);
+ vec_dst(var_vec_b32_ptr[0], var_int[1], 1);
+ vec_dst(var_vec_b32_ptr[0], var_int[1], 2);
+ vec_dst(var_vec_b32_ptr[0], var_int[1], 3);
+ vec_dst(var_vec_b8_ptr[0], var_int[1], 0);
+ vec_dst(var_vec_b8_ptr[0], var_int[1], 1);
+ vec_dst(var_vec_b8_ptr[0], var_int[1], 2);
+ vec_dst(var_vec_b8_ptr[0], var_int[1], 3);
+ vec_dst(var_vec_f32_ptr[0], var_int[1], 0);
+ vec_dst(var_vec_f32_ptr[0], var_int[1], 1);
+ vec_dst(var_vec_f32_ptr[0], var_int[1], 2);
+ vec_dst(var_vec_f32_ptr[0], var_int[1], 3);
+}
+void f34() {
+ vec_dst(var_vec_p16_ptr[0], var_int[1], 0);
+ vec_dst(var_vec_p16_ptr[0], var_int[1], 1);
+ vec_dst(var_vec_p16_ptr[0], var_int[1], 2);
+ vec_dst(var_vec_p16_ptr[0], var_int[1], 3);
+ vec_dst(var_vec_s16_ptr[0], var_int[1], 0);
+ vec_dst(var_vec_s16_ptr[0], var_int[1], 1);
+ vec_dst(var_vec_s16_ptr[0], var_int[1], 2);
+ vec_dst(var_vec_s16_ptr[0], var_int[1], 3);
+ vec_dst(var_vec_s32_ptr[0], var_int[1], 0);
+ vec_dst(var_vec_s32_ptr[0], var_int[1], 1);
+ vec_dst(var_vec_s32_ptr[0], var_int[1], 2);
+ vec_dst(var_vec_s32_ptr[0], var_int[1], 3);
+ vec_dst(var_vec_s8_ptr[0], var_int[1], 0);
+ vec_dst(var_vec_s8_ptr[0], var_int[1], 1);
+ vec_dst(var_vec_s8_ptr[0], var_int[1], 2);
+ vec_dst(var_vec_s8_ptr[0], var_int[1], 3);
+ vec_dst(var_vec_u16_ptr[0], var_int[1], 0);
+ vec_dst(var_vec_u16_ptr[0], var_int[1], 1);
+ vec_dst(var_vec_u16_ptr[0], var_int[1], 2);
+ vec_dst(var_vec_u16_ptr[0], var_int[1], 3);
+ vec_dst(var_vec_u32_ptr[0], var_int[1], 0);
+ vec_dst(var_vec_u32_ptr[0], var_int[1], 1);
+ vec_dst(var_vec_u32_ptr[0], var_int[1], 2);
+ vec_dst(var_vec_u32_ptr[0], var_int[1], 3);
+ vec_dst(var_vec_u8_ptr[0], var_int[1], 0);
+ vec_dst(var_vec_u8_ptr[0], var_int[1], 1);
+ vec_dst(var_vec_u8_ptr[0], var_int[1], 2);
+ vec_dst(var_vec_u8_ptr[0], var_int[1], 3);
+ vec_dstst(var_float_ptr[0], var_int[1], 0);
+ vec_dstst(var_float_ptr[0], var_int[1], 1);
+ vec_dstst(var_float_ptr[0], var_int[1], 2);
+ vec_dstst(var_float_ptr[0], var_int[1], 3);
+ vec_dstst(var_int_ptr[0], var_int[1], 0);
+ vec_dstst(var_int_ptr[0], var_int[1], 1);
+ vec_dstst(var_int_ptr[0], var_int[1], 2);
+ vec_dstst(var_int_ptr[0], var_int[1], 3);
+ vec_dstst(var_long_ptr[0], var_int[1], 0);
+ vec_dstst(var_long_ptr[0], var_int[1], 1);
+ vec_dstst(var_long_ptr[0], var_int[1], 2);
+ vec_dstst(var_long_ptr[0], var_int[1], 3);
+ vec_dstst(var_short_ptr[0], var_int[1], 0);
+ vec_dstst(var_short_ptr[0], var_int[1], 1);
+ vec_dstst(var_short_ptr[0], var_int[1], 2);
+ vec_dstst(var_short_ptr[0], var_int[1], 3);
+ vec_dstst(var_signed_char_ptr[0], var_int[1], 0);
+ vec_dstst(var_signed_char_ptr[0], var_int[1], 1);
+ vec_dstst(var_signed_char_ptr[0], var_int[1], 2);
+ vec_dstst(var_signed_char_ptr[0], var_int[1], 3);
+ vec_dstst(var_unsigned_char_ptr[0], var_int[1], 0);
+ vec_dstst(var_unsigned_char_ptr[0], var_int[1], 1);
+ vec_dstst(var_unsigned_char_ptr[0], var_int[1], 2);
+ vec_dstst(var_unsigned_char_ptr[0], var_int[1], 3);
+ vec_dstst(var_unsigned_int_ptr[0], var_int[1], 0);
+ vec_dstst(var_unsigned_int_ptr[0], var_int[1], 1);
+ vec_dstst(var_unsigned_int_ptr[0], var_int[1], 2);
+ vec_dstst(var_unsigned_int_ptr[0], var_int[1], 3);
+ vec_dstst(var_unsigned_long_ptr[0], var_int[1], 0);
+ vec_dstst(var_unsigned_long_ptr[0], var_int[1], 1);
+ vec_dstst(var_unsigned_long_ptr[0], var_int[1], 2);
+ vec_dstst(var_unsigned_long_ptr[0], var_int[1], 3);
+ vec_dstst(var_unsigned_short_ptr[0], var_int[1], 0);
+ vec_dstst(var_unsigned_short_ptr[0], var_int[1], 1);
+ vec_dstst(var_unsigned_short_ptr[0], var_int[1], 2);
+ vec_dstst(var_unsigned_short_ptr[0], var_int[1], 3);
+ vec_dstst(var_vec_b16_ptr[0], var_int[1], 0);
+ vec_dstst(var_vec_b16_ptr[0], var_int[1], 1);
+ vec_dstst(var_vec_b16_ptr[0], var_int[1], 2);
+ vec_dstst(var_vec_b16_ptr[0], var_int[1], 3);
+ vec_dstst(var_vec_b32_ptr[0], var_int[1], 0);
+ vec_dstst(var_vec_b32_ptr[0], var_int[1], 1);
+ vec_dstst(var_vec_b32_ptr[0], var_int[1], 2);
+ vec_dstst(var_vec_b32_ptr[0], var_int[1], 3);
+ vec_dstst(var_vec_b8_ptr[0], var_int[1], 0);
+ vec_dstst(var_vec_b8_ptr[0], var_int[1], 1);
+ vec_dstst(var_vec_b8_ptr[0], var_int[1], 2);
+ vec_dstst(var_vec_b8_ptr[0], var_int[1], 3);
+ vec_dstst(var_vec_f32_ptr[0], var_int[1], 0);
+ vec_dstst(var_vec_f32_ptr[0], var_int[1], 1);
+ vec_dstst(var_vec_f32_ptr[0], var_int[1], 2);
+ vec_dstst(var_vec_f32_ptr[0], var_int[1], 3);
+ vec_dstst(var_vec_p16_ptr[0], var_int[1], 0);
+ vec_dstst(var_vec_p16_ptr[0], var_int[1], 1);
+ vec_dstst(var_vec_p16_ptr[0], var_int[1], 2);
+ vec_dstst(var_vec_p16_ptr[0], var_int[1], 3);
+ vec_dstst(var_vec_s16_ptr[0], var_int[1], 0);
+ vec_dstst(var_vec_s16_ptr[0], var_int[1], 1);
+ vec_dstst(var_vec_s16_ptr[0], var_int[1], 2);
+ vec_dstst(var_vec_s16_ptr[0], var_int[1], 3);
+ vec_dstst(var_vec_s32_ptr[0], var_int[1], 0);
+ vec_dstst(var_vec_s32_ptr[0], var_int[1], 1);
+ vec_dstst(var_vec_s32_ptr[0], var_int[1], 2);
+ vec_dstst(var_vec_s32_ptr[0], var_int[1], 3);
+ vec_dstst(var_vec_s8_ptr[0], var_int[1], 0);
+ vec_dstst(var_vec_s8_ptr[0], var_int[1], 1);
+ vec_dstst(var_vec_s8_ptr[0], var_int[1], 2);
+ vec_dstst(var_vec_s8_ptr[0], var_int[1], 3);
+ vec_dstst(var_vec_u16_ptr[0], var_int[1], 0);
+ vec_dstst(var_vec_u16_ptr[0], var_int[1], 1);
+ vec_dstst(var_vec_u16_ptr[0], var_int[1], 2);
+ vec_dstst(var_vec_u16_ptr[0], var_int[1], 3);
+}
+void f35() {
+ vec_dstst(var_vec_u32_ptr[0], var_int[1], 0);
+ vec_dstst(var_vec_u32_ptr[0], var_int[1], 1);
+ vec_dstst(var_vec_u32_ptr[0], var_int[1], 2);
+ vec_dstst(var_vec_u32_ptr[0], var_int[1], 3);
+ vec_dstst(var_vec_u8_ptr[0], var_int[1], 0);
+ vec_dstst(var_vec_u8_ptr[0], var_int[1], 1);
+ vec_dstst(var_vec_u8_ptr[0], var_int[1], 2);
+ vec_dstst(var_vec_u8_ptr[0], var_int[1], 3);
+ vec_dststt(var_float_ptr[0], var_int[1], 0);
+ vec_dststt(var_float_ptr[0], var_int[1], 1);
+ vec_dststt(var_float_ptr[0], var_int[1], 2);
+ vec_dststt(var_float_ptr[0], var_int[1], 3);
+ vec_dststt(var_int_ptr[0], var_int[1], 0);
+ vec_dststt(var_int_ptr[0], var_int[1], 1);
+ vec_dststt(var_int_ptr[0], var_int[1], 2);
+ vec_dststt(var_int_ptr[0], var_int[1], 3);
+ vec_dststt(var_long_ptr[0], var_int[1], 0);
+ vec_dststt(var_long_ptr[0], var_int[1], 1);
+ vec_dststt(var_long_ptr[0], var_int[1], 2);
+ vec_dststt(var_long_ptr[0], var_int[1], 3);
+ vec_dststt(var_short_ptr[0], var_int[1], 0);
+ vec_dststt(var_short_ptr[0], var_int[1], 1);
+ vec_dststt(var_short_ptr[0], var_int[1], 2);
+ vec_dststt(var_short_ptr[0], var_int[1], 3);
+ vec_dststt(var_signed_char_ptr[0], var_int[1], 0);
+ vec_dststt(var_signed_char_ptr[0], var_int[1], 1);
+ vec_dststt(var_signed_char_ptr[0], var_int[1], 2);
+ vec_dststt(var_signed_char_ptr[0], var_int[1], 3);
+ vec_dststt(var_unsigned_char_ptr[0], var_int[1], 0);
+ vec_dststt(var_unsigned_char_ptr[0], var_int[1], 1);
+ vec_dststt(var_unsigned_char_ptr[0], var_int[1], 2);
+ vec_dststt(var_unsigned_char_ptr[0], var_int[1], 3);
+ vec_dststt(var_unsigned_int_ptr[0], var_int[1], 0);
+ vec_dststt(var_unsigned_int_ptr[0], var_int[1], 1);
+ vec_dststt(var_unsigned_int_ptr[0], var_int[1], 2);
+ vec_dststt(var_unsigned_int_ptr[0], var_int[1], 3);
+ vec_dststt(var_unsigned_long_ptr[0], var_int[1], 0);
+ vec_dststt(var_unsigned_long_ptr[0], var_int[1], 1);
+ vec_dststt(var_unsigned_long_ptr[0], var_int[1], 2);
+ vec_dststt(var_unsigned_long_ptr[0], var_int[1], 3);
+ vec_dststt(var_unsigned_short_ptr[0], var_int[1], 0);
+ vec_dststt(var_unsigned_short_ptr[0], var_int[1], 1);
+ vec_dststt(var_unsigned_short_ptr[0], var_int[1], 2);
+ vec_dststt(var_unsigned_short_ptr[0], var_int[1], 3);
+ vec_dststt(var_vec_b16_ptr[0], var_int[1], 0);
+ vec_dststt(var_vec_b16_ptr[0], var_int[1], 1);
+ vec_dststt(var_vec_b16_ptr[0], var_int[1], 2);
+ vec_dststt(var_vec_b16_ptr[0], var_int[1], 3);
+ vec_dststt(var_vec_b32_ptr[0], var_int[1], 0);
+ vec_dststt(var_vec_b32_ptr[0], var_int[1], 1);
+ vec_dststt(var_vec_b32_ptr[0], var_int[1], 2);
+ vec_dststt(var_vec_b32_ptr[0], var_int[1], 3);
+ vec_dststt(var_vec_b8_ptr[0], var_int[1], 0);
+ vec_dststt(var_vec_b8_ptr[0], var_int[1], 1);
+ vec_dststt(var_vec_b8_ptr[0], var_int[1], 2);
+ vec_dststt(var_vec_b8_ptr[0], var_int[1], 3);
+ vec_dststt(var_vec_f32_ptr[0], var_int[1], 0);
+ vec_dststt(var_vec_f32_ptr[0], var_int[1], 1);
+ vec_dststt(var_vec_f32_ptr[0], var_int[1], 2);
+ vec_dststt(var_vec_f32_ptr[0], var_int[1], 3);
+ vec_dststt(var_vec_p16_ptr[0], var_int[1], 0);
+ vec_dststt(var_vec_p16_ptr[0], var_int[1], 1);
+ vec_dststt(var_vec_p16_ptr[0], var_int[1], 2);
+ vec_dststt(var_vec_p16_ptr[0], var_int[1], 3);
+ vec_dststt(var_vec_s16_ptr[0], var_int[1], 0);
+ vec_dststt(var_vec_s16_ptr[0], var_int[1], 1);
+ vec_dststt(var_vec_s16_ptr[0], var_int[1], 2);
+ vec_dststt(var_vec_s16_ptr[0], var_int[1], 3);
+ vec_dststt(var_vec_s32_ptr[0], var_int[1], 0);
+ vec_dststt(var_vec_s32_ptr[0], var_int[1], 1);
+ vec_dststt(var_vec_s32_ptr[0], var_int[1], 2);
+ vec_dststt(var_vec_s32_ptr[0], var_int[1], 3);
+ vec_dststt(var_vec_s8_ptr[0], var_int[1], 0);
+ vec_dststt(var_vec_s8_ptr[0], var_int[1], 1);
+ vec_dststt(var_vec_s8_ptr[0], var_int[1], 2);
+ vec_dststt(var_vec_s8_ptr[0], var_int[1], 3);
+ vec_dststt(var_vec_u16_ptr[0], var_int[1], 0);
+ vec_dststt(var_vec_u16_ptr[0], var_int[1], 1);
+ vec_dststt(var_vec_u16_ptr[0], var_int[1], 2);
+ vec_dststt(var_vec_u16_ptr[0], var_int[1], 3);
+ vec_dststt(var_vec_u32_ptr[0], var_int[1], 0);
+ vec_dststt(var_vec_u32_ptr[0], var_int[1], 1);
+ vec_dststt(var_vec_u32_ptr[0], var_int[1], 2);
+ vec_dststt(var_vec_u32_ptr[0], var_int[1], 3);
+ vec_dststt(var_vec_u8_ptr[0], var_int[1], 0);
+ vec_dststt(var_vec_u8_ptr[0], var_int[1], 1);
+ vec_dststt(var_vec_u8_ptr[0], var_int[1], 2);
+ vec_dststt(var_vec_u8_ptr[0], var_int[1], 3);
+ vec_dstt(var_float_ptr[0], var_int[1], 0);
+ vec_dstt(var_float_ptr[0], var_int[1], 1);
+ vec_dstt(var_float_ptr[0], var_int[1], 2);
+ vec_dstt(var_float_ptr[0], var_int[1], 3);
+ vec_dstt(var_int_ptr[0], var_int[1], 0);
+ vec_dstt(var_int_ptr[0], var_int[1], 1);
+ vec_dstt(var_int_ptr[0], var_int[1], 2);
+ vec_dstt(var_int_ptr[0], var_int[1], 3);
+ vec_dstt(var_long_ptr[0], var_int[1], 0);
+ vec_dstt(var_long_ptr[0], var_int[1], 1);
+ vec_dstt(var_long_ptr[0], var_int[1], 2);
+ vec_dstt(var_long_ptr[0], var_int[1], 3);
+}
+void f36() {
+ vec_dstt(var_short_ptr[0], var_int[1], 0);
+ vec_dstt(var_short_ptr[0], var_int[1], 1);
+ vec_dstt(var_short_ptr[0], var_int[1], 2);
+ vec_dstt(var_short_ptr[0], var_int[1], 3);
+ vec_dstt(var_signed_char_ptr[0], var_int[1], 0);
+ vec_dstt(var_signed_char_ptr[0], var_int[1], 1);
+ vec_dstt(var_signed_char_ptr[0], var_int[1], 2);
+ vec_dstt(var_signed_char_ptr[0], var_int[1], 3);
+ vec_dstt(var_unsigned_char_ptr[0], var_int[1], 0);
+ vec_dstt(var_unsigned_char_ptr[0], var_int[1], 1);
+ vec_dstt(var_unsigned_char_ptr[0], var_int[1], 2);
+ vec_dstt(var_unsigned_char_ptr[0], var_int[1], 3);
+ vec_dstt(var_unsigned_int_ptr[0], var_int[1], 0);
+ vec_dstt(var_unsigned_int_ptr[0], var_int[1], 1);
+ vec_dstt(var_unsigned_int_ptr[0], var_int[1], 2);
+ vec_dstt(var_unsigned_int_ptr[0], var_int[1], 3);
+ vec_dstt(var_unsigned_long_ptr[0], var_int[1], 0);
+ vec_dstt(var_unsigned_long_ptr[0], var_int[1], 1);
+ vec_dstt(var_unsigned_long_ptr[0], var_int[1], 2);
+ vec_dstt(var_unsigned_long_ptr[0], var_int[1], 3);
+ vec_dstt(var_unsigned_short_ptr[0], var_int[1], 0);
+ vec_dstt(var_unsigned_short_ptr[0], var_int[1], 1);
+ vec_dstt(var_unsigned_short_ptr[0], var_int[1], 2);
+ vec_dstt(var_unsigned_short_ptr[0], var_int[1], 3);
+ vec_dstt(var_vec_b16_ptr[0], var_int[1], 0);
+ vec_dstt(var_vec_b16_ptr[0], var_int[1], 1);
+ vec_dstt(var_vec_b16_ptr[0], var_int[1], 2);
+ vec_dstt(var_vec_b16_ptr[0], var_int[1], 3);
+ vec_dstt(var_vec_b32_ptr[0], var_int[1], 0);
+ vec_dstt(var_vec_b32_ptr[0], var_int[1], 1);
+ vec_dstt(var_vec_b32_ptr[0], var_int[1], 2);
+ vec_dstt(var_vec_b32_ptr[0], var_int[1], 3);
+ vec_dstt(var_vec_b8_ptr[0], var_int[1], 0);
+ vec_dstt(var_vec_b8_ptr[0], var_int[1], 1);
+ vec_dstt(var_vec_b8_ptr[0], var_int[1], 2);
+ vec_dstt(var_vec_b8_ptr[0], var_int[1], 3);
+ vec_dstt(var_vec_f32_ptr[0], var_int[1], 0);
+ vec_dstt(var_vec_f32_ptr[0], var_int[1], 1);
+ vec_dstt(var_vec_f32_ptr[0], var_int[1], 2);
+ vec_dstt(var_vec_f32_ptr[0], var_int[1], 3);
+ vec_dstt(var_vec_p16_ptr[0], var_int[1], 0);
+ vec_dstt(var_vec_p16_ptr[0], var_int[1], 1);
+ vec_dstt(var_vec_p16_ptr[0], var_int[1], 2);
+ vec_dstt(var_vec_p16_ptr[0], var_int[1], 3);
+ vec_dstt(var_vec_s16_ptr[0], var_int[1], 0);
+ vec_dstt(var_vec_s16_ptr[0], var_int[1], 1);
+ vec_dstt(var_vec_s16_ptr[0], var_int[1], 2);
+ vec_dstt(var_vec_s16_ptr[0], var_int[1], 3);
+ vec_dstt(var_vec_s32_ptr[0], var_int[1], 0);
+ vec_dstt(var_vec_s32_ptr[0], var_int[1], 1);
+ vec_dstt(var_vec_s32_ptr[0], var_int[1], 2);
+ vec_dstt(var_vec_s32_ptr[0], var_int[1], 3);
+ vec_dstt(var_vec_s8_ptr[0], var_int[1], 0);
+ vec_dstt(var_vec_s8_ptr[0], var_int[1], 1);
+ vec_dstt(var_vec_s8_ptr[0], var_int[1], 2);
+ vec_dstt(var_vec_s8_ptr[0], var_int[1], 3);
+ vec_dstt(var_vec_u16_ptr[0], var_int[1], 0);
+ vec_dstt(var_vec_u16_ptr[0], var_int[1], 1);
+ vec_dstt(var_vec_u16_ptr[0], var_int[1], 2);
+ vec_dstt(var_vec_u16_ptr[0], var_int[1], 3);
+ vec_dstt(var_vec_u32_ptr[0], var_int[1], 0);
+ vec_dstt(var_vec_u32_ptr[0], var_int[1], 1);
+ vec_dstt(var_vec_u32_ptr[0], var_int[1], 2);
+ vec_dstt(var_vec_u32_ptr[0], var_int[1], 3);
+ vec_dstt(var_vec_u8_ptr[0], var_int[1], 0);
+ vec_dstt(var_vec_u8_ptr[0], var_int[1], 1);
+ vec_dstt(var_vec_u8_ptr[0], var_int[1], 2);
+ vec_dstt(var_vec_u8_ptr[0], var_int[1], 3);
+ vec_mtvscr(var_vec_b16[0]);
+ vec_mtvscr(var_vec_b32[0]);
+ vec_mtvscr(var_vec_b8[0]);
+ vec_mtvscr(var_vec_p16[0]);
+ vec_mtvscr(var_vec_s16[0]);
+ vec_mtvscr(var_vec_s32[0]);
+ vec_mtvscr(var_vec_s8[0]);
+ vec_mtvscr(var_vec_u16[0]);
+ vec_mtvscr(var_vec_u32[0]);
+ vec_mtvscr(var_vec_u8[0]);
+ vec_st(var_vec_b16[0], var_int[1], var_vec_b16_ptr[2]);
+ vec_st(var_vec_b32[0], var_int[1], var_vec_b32_ptr[2]);
+ vec_st(var_vec_b8[0], var_int[1], var_vec_b8_ptr[2]);
+ vec_st(var_vec_f32[0], var_int[1], var_float_ptr[2]);
+ vec_st(var_vec_f32[0], var_int[1], var_vec_f32_ptr[2]);
+ vec_st(var_vec_p16[0], var_int[1], var_vec_p16_ptr[2]);
+ vec_st(var_vec_s16[0], var_int[1], var_short_ptr[2]);
+ vec_st(var_vec_s16[0], var_int[1], var_vec_s16_ptr[2]);
+ vec_st(var_vec_s32[0], var_int[1], var_int_ptr[2]);
+ vec_st(var_vec_s32[0], var_int[1], var_long_ptr[2]);
+ vec_st(var_vec_s32[0], var_int[1], var_vec_s32_ptr[2]);
+ vec_st(var_vec_s8[0], var_int[1], var_signed_char_ptr[2]);
+ vec_st(var_vec_s8[0], var_int[1], var_vec_s8_ptr[2]);
+ vec_st(var_vec_u16[0], var_int[1], var_unsigned_short_ptr[2]);
+ vec_st(var_vec_u16[0], var_int[1], var_vec_u16_ptr[2]);
+ vec_st(var_vec_u32[0], var_int[1], var_unsigned_int_ptr[2]);
+ vec_st(var_vec_u32[0], var_int[1], var_unsigned_long_ptr[2]);
+ vec_st(var_vec_u32[0], var_int[1], var_vec_u32_ptr[2]);
+ vec_st(var_vec_u8[0], var_int[1], var_unsigned_char_ptr[2]);
+ vec_st(var_vec_u8[0], var_int[1], var_vec_u8_ptr[2]);
+ vec_ste(var_vec_f32[0], var_int[1], var_float_ptr[2]);
+ vec_ste(var_vec_s16[0], var_int[1], var_short_ptr[2]);
+}
+void f37() {
+ vec_ste(var_vec_s32[0], var_int[1], var_int_ptr[2]);
+ vec_ste(var_vec_s32[0], var_int[1], var_long_ptr[2]);
+ vec_ste(var_vec_s8[0], var_int[1], var_signed_char_ptr[2]);
+ vec_ste(var_vec_u16[0], var_int[1], var_unsigned_short_ptr[2]);
+ vec_ste(var_vec_u32[0], var_int[1], var_unsigned_int_ptr[2]);
+ vec_ste(var_vec_u32[0], var_int[1], var_unsigned_long_ptr[2]);
+ vec_ste(var_vec_u8[0], var_int[1], var_unsigned_char_ptr[2]);
+ vec_stl(var_vec_b16[0], var_int[1], var_vec_b16_ptr[2]);
+ vec_stl(var_vec_b32[0], var_int[1], var_vec_b32_ptr[2]);
+ vec_stl(var_vec_b8[0], var_int[1], var_vec_b8_ptr[2]);
+ vec_stl(var_vec_f32[0], var_int[1], var_float_ptr[2]);
+ vec_stl(var_vec_f32[0], var_int[1], var_vec_f32_ptr[2]);
+ vec_stl(var_vec_p16[0], var_int[1], var_vec_p16_ptr[2]);
+ vec_stl(var_vec_s16[0], var_int[1], var_short_ptr[2]);
+ vec_stl(var_vec_s16[0], var_int[1], var_vec_s16_ptr[2]);
+ vec_stl(var_vec_s32[0], var_int[1], var_int_ptr[2]);
+ vec_stl(var_vec_s32[0], var_int[1], var_long_ptr[2]);
+ vec_stl(var_vec_s32[0], var_int[1], var_vec_s32_ptr[2]);
+ vec_stl(var_vec_s8[0], var_int[1], var_signed_char_ptr[2]);
+ vec_stl(var_vec_s8[0], var_int[1], var_vec_s8_ptr[2]);
+ vec_stl(var_vec_u16[0], var_int[1], var_unsigned_short_ptr[2]);
+ vec_stl(var_vec_u16[0], var_int[1], var_vec_u16_ptr[2]);
+ vec_stl(var_vec_u32[0], var_int[1], var_unsigned_int_ptr[2]);
+ vec_stl(var_vec_u32[0], var_int[1], var_unsigned_long_ptr[2]);
+ vec_stl(var_vec_u32[0], var_int[1], var_vec_u32_ptr[2]);
+ vec_stl(var_vec_u8[0], var_int[1], var_unsigned_char_ptr[2]);
+ vec_stl(var_vec_u8[0], var_int[1], var_vec_u8_ptr[2]);
+ vec_stvebx(var_vec_s8[0], var_int[1], var_signed_char_ptr[2]);
+ vec_stvebx(var_vec_u8[0], var_int[1], var_unsigned_char_ptr[2]);
+ vec_stvehx(var_vec_s16[0], var_int[1], var_short_ptr[2]);
+ vec_stvehx(var_vec_u16[0], var_int[1], var_unsigned_short_ptr[2]);
+ vec_stvewx(var_vec_f32[0], var_int[1], var_float_ptr[2]);
+ vec_stvewx(var_vec_s32[0], var_int[1], var_int_ptr[2]);
+ vec_stvewx(var_vec_s32[0], var_int[1], var_long_ptr[2]);
+ vec_stvewx(var_vec_u32[0], var_int[1], var_unsigned_int_ptr[2]);
+ vec_stvewx(var_vec_u32[0], var_int[1], var_unsigned_long_ptr[2]);
+ vec_stvx(var_vec_b16[0], var_int[1], var_vec_b16_ptr[2]);
+ vec_stvx(var_vec_b32[0], var_int[1], var_vec_b32_ptr[2]);
+ vec_stvx(var_vec_b8[0], var_int[1], var_vec_b8_ptr[2]);
+ vec_stvx(var_vec_f32[0], var_int[1], var_float_ptr[2]);
+ vec_stvx(var_vec_f32[0], var_int[1], var_vec_f32_ptr[2]);
+ vec_stvx(var_vec_p16[0], var_int[1], var_vec_p16_ptr[2]);
+ vec_stvx(var_vec_s16[0], var_int[1], var_short_ptr[2]);
+ vec_stvx(var_vec_s16[0], var_int[1], var_vec_s16_ptr[2]);
+ vec_stvx(var_vec_s32[0], var_int[1], var_int_ptr[2]);
+ vec_stvx(var_vec_s32[0], var_int[1], var_long_ptr[2]);
+ vec_stvx(var_vec_s32[0], var_int[1], var_vec_s32_ptr[2]);
+ vec_stvx(var_vec_s8[0], var_int[1], var_signed_char_ptr[2]);
+ vec_stvx(var_vec_s8[0], var_int[1], var_vec_s8_ptr[2]);
+ vec_stvx(var_vec_u16[0], var_int[1], var_unsigned_short_ptr[2]);
+ vec_stvx(var_vec_u16[0], var_int[1], var_vec_u16_ptr[2]);
+ vec_stvx(var_vec_u32[0], var_int[1], var_unsigned_int_ptr[2]);
+ vec_stvx(var_vec_u32[0], var_int[1], var_unsigned_long_ptr[2]);
+ vec_stvx(var_vec_u32[0], var_int[1], var_vec_u32_ptr[2]);
+ vec_stvx(var_vec_u8[0], var_int[1], var_unsigned_char_ptr[2]);
+ vec_stvx(var_vec_u8[0], var_int[1], var_vec_u8_ptr[2]);
+ vec_stvxl(var_vec_b16[0], var_int[1], var_vec_b16_ptr[2]);
+ vec_stvxl(var_vec_b32[0], var_int[1], var_vec_b32_ptr[2]);
+ vec_stvxl(var_vec_b8[0], var_int[1], var_vec_b8_ptr[2]);
+ vec_stvxl(var_vec_f32[0], var_int[1], var_float_ptr[2]);
+ vec_stvxl(var_vec_f32[0], var_int[1], var_vec_f32_ptr[2]);
+ vec_stvxl(var_vec_p16[0], var_int[1], var_vec_p16_ptr[2]);
+ vec_stvxl(var_vec_s16[0], var_int[1], var_short_ptr[2]);
+ vec_stvxl(var_vec_s16[0], var_int[1], var_vec_s16_ptr[2]);
+ vec_stvxl(var_vec_s32[0], var_int[1], var_int_ptr[2]);
+ vec_stvxl(var_vec_s32[0], var_int[1], var_long_ptr[2]);
+ vec_stvxl(var_vec_s32[0], var_int[1], var_vec_s32_ptr[2]);
+ vec_stvxl(var_vec_s8[0], var_int[1], var_signed_char_ptr[2]);
+ vec_stvxl(var_vec_s8[0], var_int[1], var_vec_s8_ptr[2]);
+ vec_stvxl(var_vec_u16[0], var_int[1], var_unsigned_short_ptr[2]);
+ vec_stvxl(var_vec_u16[0], var_int[1], var_vec_u16_ptr[2]);
+ vec_stvxl(var_vec_u32[0], var_int[1], var_unsigned_int_ptr[2]);
+ vec_stvxl(var_vec_u32[0], var_int[1], var_unsigned_long_ptr[2]);
+ vec_stvxl(var_vec_u32[0], var_int[1], var_vec_u32_ptr[2]);
+ vec_stvxl(var_vec_u8[0], var_int[1], var_unsigned_char_ptr[2]);
+ vec_stvxl(var_vec_u8[0], var_int[1], var_vec_u8_ptr[2]);
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/sn7153.c b/gcc/testsuite/gcc.dg/vmx/sn7153.c
new file mode 100644
index 00000000000..a498a862006
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/sn7153.c
@@ -0,0 +1,62 @@
+/* In the source code, the vec_adds appears before the call to
+ validate_sat(). In the .s code, the vaddubs has been moved to after
+ the call to validate_sat(). This invalidates the meaning of checking
+ the saturation bit. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <altivec.h>
+
+static int failed;
+
+void validate_sat();
+void validate_u8(vector unsigned char, vector unsigned char);
+
+int
+main()
+{
+ vector unsigned char result_u8;
+ vec_mtvscr(((vector unsigned short){0,0,0,0,0,0,0,0}));
+ result_u8 = vec_adds(((vector unsigned
+ char){0,1,2,3,0xfc,0xfd,0xfe,0xff,
+ 0,1,2,3,0xfc,0xfd,0xfe,0xff}),
+ ((vector unsigned
+ char){0,0xf0,0xfd,0xfd,2,2,2,2,0,
+ 0xf0,0xfd,0xfd,2,2,2,2}));
+ validate_sat();
+ validate_u8(result_u8, ((vector unsigned
+ char){0,0xf1,0xff,0xff,0xfe,0xff,0xff,0xff,
+ 0,0xf1,0xff,0xff,0xfe,0xff,0xff,0xff}));
+ if (failed)
+ abort ();
+ return 0;
+}
+
+void validate_sat()
+{
+ if (vec_any_ne(vec_splat(vec_mfvscr(), 7), ((vector unsigned short){1,1,1,1,1,1,1,1})))
+ {
+ union {vector unsigned short v; unsigned short s[8];} u;
+ u.v = vec_mfvscr();
+ printf("error: vscr == { %d,%d,%d,%d,%d,%d,%d,%d }",
+ u.s[0], u.s[1], u.s[2], u.s[3],
+ u.s[4], u.s[5], u.s[6], u.s[7]);
+ printf("expected { 1,1,1,1,1,1,1,1 }\n");
+ failed++;
+ }
+}
+
+void validate_u8(vector unsigned char v, vector unsigned char vx)
+{
+ union {vector unsigned char v; unsigned char x[16]; } u, ux;
+ int i;
+ u.v = v;
+ ux.v = vx;
+ for (i=0; i<16; i++) {
+ if (u.x[i] != ux.x[i]) {
+ printf(" error: field %d %#2.2x expected %#2.2x\n",
+ i, u.x[i], ux.x[i]);
+ failed++;
+ }
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/spill.c b/gcc/testsuite/gcc.dg/vmx/spill.c
new file mode 100644
index 00000000000..dad489c3477
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/spill.c
@@ -0,0 +1,131 @@
+#include <altivec.h>
+extern vector unsigned char u8(void);
+extern vector signed char s8(void);
+extern vector bool char b8(void);
+extern vector unsigned short u16(void);
+extern vector signed short s16(void);
+extern vector bool short b16(void);
+extern vector unsigned int u32(void);
+extern vector signed int s32(void);
+extern vector bool int b32(void);
+extern vector float f32(void);
+extern vector pixel p16(void);
+
+extern void g(vector unsigned char, ...);
+
+void f()
+{
+ vector unsigned char u8l = u8();
+ vector signed char s8l = s8();
+ vector bool char b8l = b8();
+ vector unsigned short u16l = u16();
+ vector signed short s16l = s16();
+ vector bool short b16l = b16();
+ vector unsigned int u32l = u32();
+ vector signed int s32l = s32();
+ vector bool int b32l = b32();
+ vector float f32l = f32();
+ vector pixel p16l = p16();
+ vector unsigned char u8lx = u8();
+ vector signed char s8lx = s8();
+ vector bool char b8lx = b8();
+ vector unsigned short u16lx = u16();
+ vector signed short s16lx = s16();
+ vector bool short b16lx = b16();
+ vector unsigned int u32lx = u32();
+ vector signed int s32lx = s32();
+ vector bool int b32lx = b32();
+ vector float f32lx = f32();
+ vector pixel p16lx = p16();
+
+ g(u8l, s8l, b8l, u16l, s16l, b16l, u32l, s32l, b32l, f32l, p16l,
+ u8lx, s8lx, b8lx, u16lx, s16lx, b16lx, u32lx, s32lx, b32lx, f32lx, p16lx);
+}
+
+vector unsigned char
+u8(void)
+{
+ static vector unsigned char zero;
+ return zero;
+}
+
+vector signed char
+s8(void)
+{
+ static vector signed char zero;
+ return zero;
+}
+
+vector bool char
+b8(void)
+{
+ static vector bool char zero;
+ return zero;
+}
+
+vector unsigned short
+u16(void)
+{
+ static vector unsigned short zero;
+ return zero;
+}
+
+vector signed short
+s16(void)
+{
+ static vector signed short zero;
+ return zero;
+}
+
+vector bool short
+b16(void)
+{
+ static vector bool short zero;
+ return zero;
+}
+
+vector unsigned int
+u32(void)
+{
+ static vector unsigned int zero;
+ return zero;
+}
+
+vector signed int
+s32(void)
+{
+ static vector signed int zero;
+ return zero;
+}
+
+vector bool int
+b32(void)
+{
+ static vector bool int zero;
+ return zero;
+}
+
+vector float
+f32(void)
+{
+ static vector float zero;
+ return zero;
+}
+
+vector pixel
+p16(void)
+{
+ static vector pixel zero;
+ return zero;
+}
+
+void
+g(vector unsigned char a, ...)
+{
+}
+
+int main()
+{
+ f();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/spill2.c b/gcc/testsuite/gcc.dg/vmx/spill2.c
new file mode 100644
index 00000000000..4c7337bd08a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/spill2.c
@@ -0,0 +1,155 @@
+#include <altivec.h>
+extern vector unsigned char u8(void);
+extern vector signed char s8(void);
+extern vector bool char b8(void);
+extern vector unsigned short u16(void);
+extern vector signed short s16(void);
+extern vector bool short b16(void);
+extern vector unsigned int u32(void);
+extern vector signed int s32(void);
+extern vector bool int b32(void);
+extern vector float f32(void);
+extern vector pixel p16(void);
+extern double d(void);
+extern int i(void);
+
+extern void g(vector unsigned char, ...);
+
+void f()
+{
+ int i1l = i();
+ vector unsigned char u8l = u8();
+ vector signed char s8l = s8();
+ vector bool char b8l = b8();
+ int i2l = i();
+ vector unsigned short u16l = u16();
+ vector signed short s16l = s16();
+ vector bool short b16l = b16();
+ int i3l = i();
+ vector unsigned int u32l = u32();
+ vector signed int s32l = s32();
+ vector bool int b32l = b32();
+ double d1l = d();
+ vector float f32l = f32();
+ vector pixel p16l = p16();
+ double d2l = d();
+ vector unsigned char u8lx = u8();
+ vector signed char s8lx = s8();
+ vector bool char b8lx = b8();
+ vector unsigned short u16lx = u16();
+ vector signed short s16lx = s16();
+ vector bool short b16lx = b16();
+ vector unsigned int u32lx = u32();
+ vector signed int s32lx = s32();
+ vector bool int b32lx = b32();
+ vector float f32lx = f32();
+ vector pixel p16lx = p16();
+
+ if (i1l)
+ g(u8l, s8l, b8l, u16l, s16l, b16l, u32l, s32l, b32l, f32l, p16l,
+ u8lx, s8lx, b8lx, u16lx, s16lx, b16lx, u32lx, s32lx, b32lx, f32lx, p16lx,
+ i1l, i2l, i3l, d1l, d2l);
+ g(u8l, i1l, i2l, i3l, d1l, d2l);
+}
+
+double
+d(void)
+{
+ static double zero;
+ return zero;
+}
+
+int
+i(void)
+{
+ static int non_zero;
+ return ++non_zero;
+}
+
+vector unsigned char
+u8(void)
+{
+ static vector unsigned char zero;
+ return zero;
+}
+
+vector signed char
+s8(void)
+{
+ static vector signed char zero;
+ return zero;
+}
+
+vector bool char
+b8(void)
+{
+ static vector bool char zero;
+ return zero;
+}
+
+vector unsigned short
+u16(void)
+{
+ static vector unsigned short zero;
+ return zero;
+}
+
+vector signed short
+s16(void)
+{
+ static vector signed short zero;
+ return zero;
+}
+
+vector bool short
+b16(void)
+{
+ static vector bool short zero;
+ return zero;
+}
+
+vector unsigned int
+u32(void)
+{
+ static vector unsigned int zero;
+ return zero;
+}
+
+vector signed int
+s32(void)
+{
+ static vector signed int zero;
+ return zero;
+}
+
+vector bool int
+b32(void)
+{
+ static vector bool int zero;
+ return zero;
+}
+
+vector float
+f32(void)
+{
+ static vector float zero;
+ return zero;
+}
+
+vector pixel
+p16(void)
+{
+ static vector pixel zero;
+ return zero;
+}
+
+void
+g(vector unsigned char a, ...)
+{
+}
+
+int main()
+{
+ f();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/spill3.c b/gcc/testsuite/gcc.dg/vmx/spill3.c
new file mode 100644
index 00000000000..9f1c45c65b5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/spill3.c
@@ -0,0 +1,156 @@
+#include <altivec.h>
+extern void g(vector unsigned char, ...);
+extern vector unsigned char v(void);
+extern double d(void);
+extern int i(void);
+
+static vector unsigned char v1l = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+static vector unsigned char v2l = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+static vector unsigned char v3l = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+static vector unsigned char v4l = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+static vector unsigned char v5l = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+static vector unsigned char v6l = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+static vector unsigned char v7l = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+static vector unsigned char v8l = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+static vector unsigned char v9l = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+static vector unsigned char v10l = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+static vector unsigned char v11l = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+static vector unsigned char v12l = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+static double d1l = 0;
+static double d2l = 0;
+static double d3l = 0;
+static double d4l = 0;
+static double d5l = 0;
+static double d6l = 0;
+static double d7l = 0;
+static double d8l = 0;
+static double d9l = 0;
+static double d10l = 0;
+static double d11l = 0;
+static double d12l = 0;
+static double d13l = 0;
+static double d14l = 0;
+static double d15l = 0;
+static double d16l = 0;
+static double d17l = 0;
+static double d18l = 0;
+static int i1l = 0;
+static int i2l = 0;
+static int i3l = 0;
+static int i4l = 0;
+static int i5l = 0;
+static int i6l = 0;
+static int i7l = 0;
+static int i8l = 0;
+static int i9l = 0;
+static int i10l = 0;
+static int i11l = 0;
+static int i12l = 0;
+static int i13l = 0;
+static int i14l = 0;
+static int i15l = 0;
+static int i16l = 0;
+static int i17l = 0;
+static int i18l = 0;
+static int i19l = 0;
+
+void f()
+{
+ char buffer[23];
+ vector unsigned char v1l = v();
+ vector unsigned char v2l = v();
+ vector unsigned char v3l = v();
+ vector unsigned char v4l = v();
+ vector unsigned char v5l = v();
+ vector unsigned char v6l = v();
+ vector unsigned char v7l = v();
+ vector unsigned char v8l = v();
+ vector unsigned char v9l = v();
+ vector unsigned char v10l = v();
+ vector unsigned char v11l = v();
+ vector unsigned char v12l = v();
+
+ double d1l = d();
+ double d2l = d();
+ double d3l = d();
+ double d4l = d();
+ double d5l = d();
+ double d6l = d();
+ double d7l = d();
+ double d8l = d();
+ double d9l = d();
+ double d10l = d();
+ double d11l = d();
+ double d12l = d();
+ double d13l = d();
+ double d14l = d();
+ double d15l = d();
+ double d16l = d();
+ double d17l = d();
+ double d18l = d();
+
+ int i1l = i();
+ int i2l = i();
+ int i3l = i();
+ int i4l = i();
+ int i5l = i();
+ int i6l = i();
+ int i7l = i();
+ int i8l = i();
+ int i9l = i();
+ int i10l = i();
+ int i11l = i();
+ int i12l = i();
+ int i13l = i();
+ int i14l = i();
+ int i15l = i();
+ int i16l = i();
+ int i17l = i();
+ int i18l = i();
+ int i19l = i();
+
+ if (d1l)
+ g(v1l, v2l, v3l, v4l, v5l, v6l, v7l, v8l, v9l, v10l, v11l, v12l,
+ d1l, d2l, d3l, d4l, d5l, d6l, d7l, d8l, d9l, d10l, d11l, d12l,
+ d13l, d14l, d15l, d16l, d17l, d18l,
+ i1l, i2l, i3l, i4l, i5l, i6l, i7l, i8l, i9l, i10l, i11l, i12l,
+ i13l, i14l, i15l, i16l, i17l, i18l, i19l);
+
+ g(v1l, buffer,
+ d1l, d2l, d3l, d4l, d5l, d6l, d7l, d8l, d9l, d10l, d11l, d12l,
+ d13l, d14l, d15l, d16l, d17l, d18l,
+ i1l, i2l, i3l, i4l, i5l, i6l, i7l, i8l, i9l, i10l, i11l, i12l,
+ i13l, i14l, i15l, i16l, i17l, i18l, i19l);
+}
+
+double
+d(void)
+{
+ static double zero;
+ return zero;
+}
+
+int
+i(void)
+{
+ static int non_zero;
+ return ++non_zero;
+}
+
+vector unsigned char
+v(void)
+{
+ static vector unsigned char zero;
+ return zero;
+}
+
+void
+g(vector unsigned char a, ...)
+{
+}
+
+int main()
+{
+ f();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/t.c b/gcc/testsuite/gcc.dg/vmx/t.c
new file mode 100644
index 00000000000..3a7d5a94ae7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/t.c
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+#include <altivec.h>
+typedef unsigned long size_t;
+vector signed int T_vec_s32;
+void *T_void_ptr;
+const void *T_const_void_ptr;
+size_t T_size_t;
+char *T_char_ptr;
+vector signed short T_vec_s16;
+vector signed char T_vec_s8;
+vector unsigned short T_vec_u16;
+vector unsigned int T_vec_u32;
+vector unsigned char T_vec_u8;
+vector float T_vec_f32;
+int T_int;
+float *T_float_ptr;
+void f(void);
+short *T_short_ptr;
+vector signed short *T_vec_s16_ptr;
+int *T_int_ptr;
+vector signed int *T_vec_s32_ptr;
+signed char *T_signed_char_ptr;
+vector signed char *T_vec_s8_ptr;
+unsigned short *T_unsigned_short_ptr;
+vector unsigned short *T_vec_u16_ptr;
+unsigned int *T_unsigned_int_ptr;
+vector unsigned int *T_vec_u32_ptr;
+unsigned char *T_unsigned_char_ptr;
+vector unsigned char *T_vec_u8_ptr;
+double T_double;
+int T_intb;
+vector bool short *T_vec_b16_ptr;
+vector bool int *T_vec_b32_ptr;
+vector bool char *T_vec_b8_ptr;
+vector float *T_vec_f32_ptr;
+vector pixel *T_vec_p16_ptr;
+vector bool short T_vec_b16;
+vector pixel T_vec_p16;
+vector bool int T_vec_b32;
+vector bool char T_vec_b8;
+float T_float;
+volatile void g(void);
+const char *T_const_char_ptr;
diff --git a/gcc/testsuite/gcc.dg/vmx/varargs-1.c b/gcc/testsuite/gcc.dg/vmx/varargs-1.c
new file mode 100644
index 00000000000..92167c91a3e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/varargs-1.c
@@ -0,0 +1,96 @@
+#include <altivec.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+typedef vector unsigned int T;
+
+extern void f1(int, ...);
+extern void f2(int, T, ...);
+extern void f3(int, T, T, ...);
+extern void f4(int, T, T, T);
+
+void printx(T a)
+{
+ union {
+ T v;
+ unsigned long a[4];
+ } u;
+ u.v = a;
+ printf("%ld, %ld, %ld, %ld\n", u.a[0], u.a[1], u.a[2], u.a[3]);
+}
+
+void f1(int a, ...)
+{
+ va_list ap;
+ va_start (ap, a);
+ while (a-- > 0)
+ printx(va_arg(ap, T));
+}
+
+void f2(int a, T b, ...)
+{
+ va_list ap;
+ printx(b);
+ a--;
+ va_start (ap, b);
+ while (a-- > 0)
+ printx(va_arg(ap, T));
+}
+
+void f3(int a, T b, T c, ...)
+{
+ va_list ap;
+ printx(b);
+ a--;
+ printx(c);
+ a--;
+ va_start (ap, c);
+ while (a-- > 0)
+ printx(va_arg(ap, T));
+}
+
+void f4(int a, T b, T c,
+ T d)
+{
+ printx(b);
+ a--;
+ printx(c);
+ a--;
+ printx(d);
+ a--;
+}
+
+int main()
+{
+ f4 (3,
+ ((T){1,1,1,1}),
+ ((T){2,2,2,2}),
+ ((T){3,3,3,3}));
+ f3 (3,
+ ((T){4,4,4,4}),
+ ((T){5,5,5,5}),
+ ((T){6,6,6,6}));
+ f2 (3,
+ ((T){7,7,7,7}),
+ ((T){8,8,8,8}),
+ ((T){9,9,9,9}));
+ f1 (3,
+ ((T){10,10,10,10}),
+ ((T){11,11,11,11}),
+ ((T){12,12,12,12}));
+ return 0;
+}
+
+/* { dg-output "1, 1, 1, 1(\n|\r\n|\r)" }
+ { dg-output "2, 2, 2, 2(\n|\r\n|\r)" }
+ { dg-output "3, 3, 3, 3(\n|\r\n|\r)" }
+ { dg-output "4, 4, 4, 4(\n|\r\n|\r)" }
+ { dg-output "5, 5, 5, 5(\n|\r\n|\r)" }
+ { dg-output "6, 6, 6, 6(\n|\r\n|\r)" }
+ { dg-output "7, 7, 7, 7(\n|\r\n|\r)" }
+ { dg-output "8, 8, 8, 8(\n|\r\n|\r)" }
+ { dg-output "9, 9, 9, 9(\n|\r\n|\r)" }
+ { dg-output "10, 10, 10, 10(\n|\r\n|\r)" }
+ { dg-output "11, 11, 11, 11(\n|\r\n|\r)" }
+ { dg-output "12, 12, 12, 12(\n|\r\n|\r)" }
+ */
diff --git a/gcc/testsuite/gcc.dg/vmx/varargs-2.c b/gcc/testsuite/gcc.dg/vmx/varargs-2.c
new file mode 100644
index 00000000000..1df17152909
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/varargs-2.c
@@ -0,0 +1,78 @@
+#include "harness.h"
+#include <stdarg.h>
+
+static void
+varargsn003(vector float p1, vector float p2, vector float p3, ...)
+{
+ va_list ap;
+ vector float i1;
+ vector float i2;
+ vector float i3;
+ vector float i4;
+ vector float i5;
+ vector float i6;
+ vector float i7;
+ vector float i8;
+ vector float i9;
+ vector float i10;
+ vector float i11;
+ vector float i12;
+ vector float i13;
+ vector float i14;
+ vector float i15;
+ int i16;
+
+ va_start(ap, p3);
+ i1 = p1;
+ i2 = p2;
+ i3 = p3;
+ i4 = va_arg(ap, vector float);
+ i5 = va_arg(ap, vector float);
+ i6 = va_arg(ap, vector float);
+ i7 = va_arg(ap, vector float);
+ i8 = va_arg(ap, vector float);
+ i9 = va_arg(ap, vector float);
+ i10 = va_arg(ap, vector float);
+ i11 = va_arg(ap, vector float);
+ i12 = va_arg(ap, vector float);
+ i13 = va_arg(ap, vector float);
+ i14 = va_arg(ap, vector float);
+ i15 = va_arg(ap, vector float);
+ i16 = va_arg(ap, int);
+ va_end(ap);
+
+ check(vec_all_eq(i1, ((vector float){1.14e+09, 4.29e+08, -1.58e+09, 1.66e+09})), "i1");
+ check(vec_all_eq(i2, ((vector float){-1.83e+09, -6.79e+08, 1.58e+09, -3.38e+08})), "i2");
+ check(vec_all_eq(i3, ((vector float){-1.19e+09, -4.27e+08, 6.84e+08, 1.21e+08})), "i3");
+ check(vec_all_eq(i4, ((vector float){1.47e+09, 9.17e+08, 3.45e+08, -1.17e+08})), "i4");
+ check(vec_all_eq(i5, ((vector float){3.08e+08, 1.2e+08, 1.73e+09, 1.77e+09})), "i5");
+ check(vec_all_eq(i6, ((vector float){1.89e+09, 2.06e+09, 2.64e+08, 1.05e+09})), "i6");
+ check(vec_all_eq(i7, ((vector float){5.45e+08, 1.37e+09, -8.2e+08, 4.32e+07})), "i7");
+ check(vec_all_eq(i8, ((vector float){3.47e+08, -1.66e+09, 1.25e+09, 1.53e+09})), "i8");
+ check(vec_all_eq(i9, ((vector float){-6.04e+08, 1.48e+09, -1.48e+09, 1.92e+09})), "i9");
+ check(vec_all_eq(i10, ((vector float){-1.66e+09, -8.92e+08, -3.78e+08, 2.11e+09})), "i10");
+ check(vec_all_eq(i11, ((vector float){-7.46e+08, 4.01e+08, -1.78e+09, 1.83e+09})), "i11");
+ check(vec_all_eq(i12, ((vector float){1.83e+09, 5.73e+08, -2.96e+08, -7.46e+08})), "i12");
+ check(vec_all_eq(i13, ((vector float){-2.01e+09, 9.89e+08, -1.92e+09, 2.09e+09})), "i13");
+ check(vec_all_eq(i14, ((vector float){1.95e+09, -2.41e+08, 2.67e+08, 1.67e+09})), "i14");
+ check(vec_all_eq(i15, ((vector float){-2.12e+09, 8.18e+08, 9.47e+08, -1.25e+09})), "i15");
+ check(i16 == -947264420, "i16");
+}
+
+static void test()
+{
+ varargsn003(((vector float){1.14e+09, 4.29e+08, -1.58e+09, 1.66e+09}),
+ ((vector float){-1.83e+09, -6.79e+08, 1.58e+09, -3.38e+08}),
+ ((vector float){-1.19e+09, -4.27e+08, 6.84e+08, 1.21e+08}),
+ ((vector float){1.47e+09, 9.17e+08, 3.45e+08, -1.17e+08}),
+ ((vector float){3.08e+08, 1.2e+08, 1.73e+09, 1.77e+09}),
+ ((vector float){1.89e+09, 2.06e+09, 2.64e+08, 1.05e+09}),
+ ((vector float){5.45e+08, 1.37e+09, -8.2e+08, 4.32e+07}),
+ ((vector float){3.47e+08, -1.66e+09, 1.25e+09, 1.53e+09}),
+ ((vector float){-6.04e+08, 1.48e+09, -1.48e+09, 1.92e+09}),
+ ((vector float){-1.66e+09, -8.92e+08, -3.78e+08, 2.11e+09}),
+ ((vector float){-7.46e+08, 4.01e+08, -1.78e+09, 1.83e+09}),
+ ((vector float){1.83e+09, 5.73e+08, -2.96e+08, -7.46e+08}),
+ ((vector float){-2.01e+09, 9.89e+08, -1.92e+09, 2.09e+09}),
+ ((vector float){1.95e+09, -2.41e+08, 2.67e+08, 1.67e+09}), ((vector float){-2.12e+09, 8.18e+08, 9.47e+08, -1.25e+09}), -947264420);
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/varargs-3.c b/gcc/testsuite/gcc.dg/vmx/varargs-3.c
new file mode 100644
index 00000000000..be8b71bf947
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/varargs-3.c
@@ -0,0 +1,75 @@
+#include "harness.h"
+#include <stdarg.h>
+
+typedef struct n_a
+{
+ signed char m1;
+ short m2;
+ int m3;
+ double m4;
+ vector float m5;
+}
+n_a;
+
+void
+varlistn_a(signed char p1, va_list ap)
+{
+ n_a q;
+ q.m1 = p1;
+ q.m2 = va_arg(ap, int);
+ q.m3 = va_arg(ap, int);
+ q.m4 = va_arg(ap, double);
+ q.m5 = va_arg(ap, vector float);
+
+ check(q.m1 == 77, "q.m1");
+ check(q.m2 == 1924, "q.m2");
+ check(q.m3 == -1471601920, "q.m3");
+ check(q.m4 == 3.65e+18, "q.m4");
+ check(vec_all_eq(q.m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})), "q.m5");
+}
+
+void
+varargsn_a(signed char p1, ...)
+{
+ n_a r, s;
+ va_list ap;
+
+ va_start(ap, p1);
+ r.m1 = p1;
+ r.m2 = va_arg(ap, int);
+ r.m3 = va_arg(ap, int);
+ r.m4 = va_arg(ap, double);
+ r.m5 = va_arg(ap, vector float);
+ va_end(ap);
+
+ check(r.m1 == 77, "r.m1");
+ check(r.m2 == 1924, "r.m2");
+ check(r.m3 == -1471601920, "r.m3");
+ check(r.m4 == 3.65e+18, "r.m4");
+ check(vec_all_eq(r.m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})), "r.m5");
+
+ va_start(ap, p1);
+ s.m1 = p1;
+ s.m2 = va_arg(ap, int);
+ s.m3 = va_arg(ap, int);
+ s.m4 = va_arg(ap, double);
+ s.m5 = va_arg(ap, vector float);
+ va_end(ap);
+
+ check(s.m1 == 77, "s.m1");
+ check(s.m2 == 1924, "s.m2");
+ check(s.m3 == -1471601920, "s.m3");
+ check(s.m4 == 3.65e+18, "s.m4");
+ check(vec_all_eq(s.m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})), "s.m5");
+
+ va_start(ap, p1);
+ varlistn_a(p1, ap);
+ va_end(ap);
+}
+
+
+
+void test()
+{
+ varargsn_a(77, 1924, -1471601920, 3.65e+18, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08}));
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/varargs-4.c b/gcc/testsuite/gcc.dg/vmx/varargs-4.c
new file mode 100644
index 00000000000..5433329e526
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/varargs-4.c
@@ -0,0 +1,299 @@
+#include "harness.h"
+#include <stdarg.h>
+#include <stddef.h>
+#include <string.h>
+
+typedef struct n_a
+{
+ signed char m1;
+ short m2;
+ int m3;
+ double m4;
+ vector float m5;
+}
+n_a;
+
+typedef struct n_a_x
+{
+ n_a b;
+ char a;
+}
+n_a_x;
+
+static n_a gn_a;
+
+static int
+lay(char *p, int start, int end, int n)
+{
+ int b;
+ unsigned char ch;
+ unsigned int mask;
+
+ start *= 8;
+ end *= 8;
+ n *= 8;
+
+ for (b = 0; b + 8 <= start; b += 8)
+ {
+ ch = *p++;
+ if (ch != 0xff)
+ for (mask = 0x80; mask; b++, mask >>= 1)
+ if ((ch & mask) != mask)
+ return b;
+ }
+
+ if (b < start)
+ {
+ ch = *p++;
+ for (mask = 0x80; b < start; b++, mask >>= 1)
+ if ((ch & mask) != mask)
+ return b;
+ for (; mask && b < end; b++, mask >>= 1)
+ if ((ch & mask) != 0)
+ return b;
+ }
+
+ for (; b + 8 <= end; b += 8)
+ {
+ ch = *p++;
+ if (ch != 0)
+ for (mask = 0x80; mask; b++, mask >>= 1)
+ if ((ch & mask) != 0)
+ return b;
+ }
+
+ if (b < end)
+ {
+ ch = *p++;
+ for (mask = 0x80; b < end; b++, mask >>= 1)
+ if ((ch & mask) != 0)
+ return b;
+ for (; mask && b < n; b++, mask >>= 1)
+ if ((ch & mask) != mask)
+ return b;
+ }
+
+ for (; b + 8 <= n; b += 8)
+ {
+ ch = *p++;
+ if (ch != 0xff)
+ for (mask = 0x80; mask; b++, mask >>= 1)
+ if ((ch & mask) != mask)
+ return b;
+ }
+
+ return n;
+}
+
+static void
+initn_a(signed char p1, short p2, int p3, double p4, vector float p5)
+{
+ n_a i;
+
+ i.m1 = p1;
+ i.m2 = p2;
+ i.m3 = p3;
+ i.m4 = p4;
+ i.m5 = p5;
+
+ check(i.m1 == 77, "i.m1");
+ check(i.m2 == 1924, "i.m2");
+ check(i.m3 == -1471601920, "i.m3");
+ check(vec_all_eq(i.m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})),
+ "i.m5");
+
+ check(sizeof(n_a) == 32, "sizeof(n_a)");
+ check(sizeof(n_a_x) - sizeof(n_a) == 32, "align(n_a_x)");
+
+ check(offsetof(n_a, m1) == 0, "offsetof(m1)");
+ check(offsetof(n_a, m2) == 2, "offsetof(m2)");
+ check(offsetof(n_a, m3) == 4, "offsetof(m3)");
+ check(offsetof(n_a, m4) == 8, "offsetof(m4)");
+ check(offsetof(n_a, m5) == 16, "offsetof(m5)");
+
+ check(sizeof(i.m1) == 1, "sizeof(m1)");
+ check(sizeof(i.m2) == 2, "sizeof(m2)");
+ check(sizeof(i.m3) == 4, "sizeof(m3)");
+ check(sizeof(i.m4) == 8, "sizeof(m4)");
+ check(sizeof(i.m5) == 16, "sizeof(m5)");
+
+#define lay_check(field) do { \
+ memset((char *)&i, 0xFF, sizeof(i)); \
+ lay_reset(field); \
+ check(lay((char *)&i, \
+ offsetof(n_a, field), \
+ offsetof(n_a, field) + sizeof(i.field), \
+ sizeof(i)) == sizeof(i)*8, \
+ "lay(" #field ")"); \
+ } while (0)
+#define lay_reset(field) i.field = 0
+
+ lay_check(m1);
+ lay_check(m2);
+ lay_check(m3);
+ lay_check(m4);
+#undef lay_reset
+#define lay_reset(field) i.field = ((vector float){0,0,0,0})
+ lay_check(m5);
+
+#undef lay_check
+#undef lay_reset
+}
+
+n_a
+valuen_a(void)
+{
+ return gn_a;
+}
+
+n_a *
+addrn_a(void)
+{
+ return &gn_a;
+}
+
+static void
+eqn_a(n_a * a)
+{
+ check(a->m1 == 77, "a->m1");
+ check(a->m2 == 1924, "a->m2");
+ check(a->m3 == -1471601920, "a->m3");
+ check(vec_all_eq(a->m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})),
+ "a->m5");
+}
+
+static void
+getsn_a(n_a * a)
+{
+ a->m1 = 77;
+ a->m2 = 1924;
+ a->m3 = -1471601920;
+ a->m4 = 3.65e+18;
+ a->m5 = ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08});
+}
+
+static void
+varlistn_a(signed char p1, va_list ap)
+{
+ n_a q;
+ q.m1 = p1;
+ q.m2 = va_arg(ap, int);
+ q.m3 = va_arg(ap, int);
+ q.m4 = va_arg(ap, double);
+ q.m5 = va_arg(ap, vector float);
+
+ check(q.m1 == 77, "q.m1");
+ check(q.m2 == 1924, "q.m2");
+ check(q.m3 == -1471601920, "q.m3");
+ check(vec_all_eq(q.m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})),
+ "q.m5");
+}
+
+static void
+varargsn_a(signed char p1, ...)
+{
+ n_a q, r;
+ va_list ap;
+
+ va_start(ap, p1);
+ q.m1 = p1;
+ q.m2 = va_arg(ap, int);
+ q.m3 = va_arg(ap, int);
+ q.m4 = va_arg(ap, double);
+ q.m5 = va_arg(ap, vector float);
+ va_end(ap);
+
+ check(q.m1 == 77, "q.m1");
+ check(q.m2 == 1924, "q.m2");
+ check(q.m3 == -1471601920, "q.m3");
+ check(vec_all_eq(q.m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})),
+ "q.m5");
+
+ va_start(ap, p1);
+ r.m1 = p1;
+ r.m2 = va_arg(ap, int);
+ r.m3 = va_arg(ap, int);
+ r.m4 = va_arg(ap, double);
+ r.m5 = va_arg(ap, vector float);
+ va_end(ap);
+
+ check(r.m1 == 77, "r.m1");
+ check(r.m2 == 1924, "r.m2");
+ check(r.m3 == -1471601920, "r.m3");
+ check(vec_all_eq(r.m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})),
+ "r.m5");
+
+ va_start(ap, p1);
+ varlistn_a(p1, ap);
+ va_end(ap);
+}
+
+static void
+test()
+{
+ static struct
+ {
+ char a;
+ n_a b;
+ }
+ s;
+ n_a v[3], a, *p;
+
+ static n_a i = { 77, 1924, -1471601920, 3.65e+18, {-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08} };
+
+ memset((char *)&(v), -1, sizeof(v));
+ v[1] = s.b;
+ check(lay((char *)&v, sizeof(n_a), sizeof(n_a)*2, sizeof(n_a)*3) == sizeof(n_a)*3*8,
+ "structure assignment");
+
+ check(i.m1 == 77, "i.m1");
+ check(i.m2 == 1924, "i.m2");
+ check(i.m3 == -1471601920, "i.m3");
+ check(vec_all_eq(i.m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})),
+ "i.m5");
+
+ initn_a(77, 1924, -1471601920, 3.65e+18, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08}));
+ varargsn_a(77, 1924, -1471601920, 3.65e+18, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08}));
+
+ gn_a.m1 = 77;
+ gn_a.m2 = 1924;
+ gn_a.m3 = -1471601920;
+ gn_a.m4 = 3.65e+18;
+ gn_a.m5 = ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08});
+ a = valuen_a();
+
+ check(a.m1 == 77, "a.m1");
+ check(a.m2 == 1924, "a.m2");
+ check(a.m3 == -1471601920, "a.m3");
+ check(vec_all_eq(a.m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})),
+ "a.m5");
+
+ p = addrn_a();
+
+ check(p->m1 == 77, "p->m1");
+ check(p->m2 == 1924, "p->m2");
+ check(p->m3 == -1471601920, "p->m3");
+ check(vec_all_eq(p->m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})),
+ "p->m5");
+
+ eqn_a(&a);
+
+ check(gn_a.m1 == 77, "gn_a.m1");
+ check(gn_a.m2 == 1924, "gn_a.m2");
+ check(gn_a.m3 == -1471601920, "gn_a.m3");
+ check(vec_all_eq(gn_a.m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})),
+ "gn_a.m5");
+
+ getsn_a(&v[0]);
+ v[2].m1 = v[0].m1;
+ v[2].m2 = v[0].m2;
+ v[2].m3 = v[0].m3;
+ v[2].m4 = v[0].m4;
+ v[2].m5 = v[0].m5;
+
+ check(v[2].m1 == 77, "v[2].m1");
+ check(v[2].m2 == 1924, "v[2].m2");
+ check(v[2].m3 == -1471601920, "v[2].m3");
+ check(vec_all_eq(v[2].m5, ((vector float){-1.38e+09, 5.96e+08, 6.88e+08, -3.2e+08})),
+ "v[2].m5");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/varargs-5.c b/gcc/testsuite/gcc.dg/vmx/varargs-5.c
new file mode 100644
index 00000000000..ed551c2dfa9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/varargs-5.c
@@ -0,0 +1,71 @@
+#include "harness.h"
+#include <stdarg.h>
+
+typedef struct n025
+{
+ int m1;
+ double m2;
+ int m3;
+ vector signed int m4;
+}
+n025;
+
+static void
+varlistn025(int p1, double p2, va_list ap)
+{
+ n025 q;
+ q.m1 = p1;
+ q.m2 = p2;
+ q.m3 = va_arg(ap, int);
+ q.m4 = va_arg(ap, vector signed int);
+
+ check(q.m1 == 1363477585, "q.m1");
+ check(q.m2 == -8.72e+18, "q.m2");
+ check(q.m3 == 198652649, "q.m3");
+ check(vec_all_eq(q.m4, ((vector signed int){323001541, -1353029458, 1756879633, -327031280})),
+ "q.m5");
+}
+
+
+void
+varargsn025(int p1, double p2, ...)
+{
+ n025 r, s;
+ va_list ap;
+
+ va_start(ap, p2);
+ r.m1 = p1;
+ r.m2 = p2;
+ r.m3 = va_arg(ap, int);
+ r.m4 = va_arg(ap, vector signed int);
+ va_end(ap);
+
+ check(r.m1 == 1363477585, "r.m1");
+ check(r.m2 == -8.72e+18, "r.m2");
+ check(r.m3 == 198652649, "r.m3");
+ check(vec_all_eq(r.m4, ((vector signed int){323001541, -1353029458, 1756879633, -327031280})),
+ "r.m5");
+
+ va_start(ap, p2);
+ s.m1 = p1;
+ s.m2 = p2;
+ s.m3 = va_arg(ap, int);
+ s.m4 = va_arg(ap, vector signed int);
+ va_end(ap);
+
+ check(s.m1 == 1363477585, "s.m1");
+ check(s.m2 == -8.72e+18, "s.m2");
+ check(s.m3 == 198652649, "s.m3");
+ check(vec_all_eq(s.m4, ((vector signed int){323001541, -1353029458, 1756879633, -327031280})),
+ "s.m5");
+
+ va_start(ap, p2);
+ varlistn025(p1, p2, ap);
+ va_end(ap);
+}
+
+static void test()
+{
+ varargsn025(1363477585, -8.72e+18, 198652649,
+ ((vector signed int){323001541, -1353029458, 1756879633, -327031280}));
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/varargs-6.c b/gcc/testsuite/gcc.dg/vmx/varargs-6.c
new file mode 100644
index 00000000000..b1f436fd043
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/varargs-6.c
@@ -0,0 +1,35 @@
+#include "harness.h"
+#include <stdarg.h>
+
+typedef struct n025
+{
+ int m1;
+ double m2;
+ int m3;
+ vector signed int m4;
+}
+n025;
+
+static void
+varargsn025(int p1, double p2, ...)
+{
+ n025 q;
+ va_list ap;
+ va_start(ap, p2);
+ q.m1 = p1;
+ q.m2 = p2;
+ q.m3 = va_arg(ap, int);
+ q.m4 = va_arg(ap, vector signed int);
+ va_end(ap);
+
+ check(q.m1 == 1363477585, "q.m1");
+ check(q.m2 == -8.72e+18, "q.m2");
+ check(q.m3 == 198652649, "q.m3");
+ check(vec_all_eq(q.m4, ((vector signed int){323001541, -1353029458, 1756879633, -327031280})),
+ "q.m4");
+}
+
+static void test()
+{
+ varargsn025(1363477585, -8.72e+18, 198652649, ((vector signed int){323001541, -1353029458, 1756879633, -327031280}));
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/varargs-7.c b/gcc/testsuite/gcc.dg/vmx/varargs-7.c
new file mode 100644
index 00000000000..2a09d0ca08a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/varargs-7.c
@@ -0,0 +1,83 @@
+#include "harness.h"
+#include <stdarg.h>
+
+static void
+varargsn001(vector unsigned int p1, vector unsigned int p2,
+ vector unsigned int p3, vector unsigned int p4,
+ vector unsigned int p5, vector unsigned int p6,
+ vector unsigned int p7, vector unsigned int p8,
+ vector unsigned int p9, vector unsigned int p10,
+ vector unsigned int p11, vector unsigned int p12,
+ vector unsigned int p13, ...)
+{
+ va_list ap;
+ vector unsigned int i1;
+ vector unsigned int i2;
+ vector unsigned int i3;
+ vector unsigned int i4;
+ vector unsigned int i5;
+ vector unsigned int i6;
+ vector unsigned int i7;
+ vector unsigned int i8;
+ vector unsigned int i9;
+ vector unsigned int i10;
+ vector unsigned int i11;
+ vector unsigned int i12;
+ vector unsigned int i13;
+ vector unsigned int i14;
+ int i15;
+
+ va_start(ap, p13);
+
+ i1 = p1;
+ i2 = p2;
+ i3 = p3;
+ i4 = p4;
+ i5 = p5;
+ i6 = p6;
+ i7 = p7;
+ i8 = p8;
+ i9 = p9;
+ i10 = p10;
+ i11 = p11;
+ i12 = p12;
+ i13 = p13;
+ i14 = va_arg(ap, vector unsigned int);
+ i15 = va_arg(ap, int);
+ va_end(ap);
+
+ check(vec_all_eq(i1, ((vector unsigned int){1,1,1,1})), "i1");
+ check(vec_all_eq(i2, ((vector unsigned int){2,2,2,2})), "i2");
+ check(vec_all_eq(i3, ((vector unsigned int){3,3,3,3})), "i3");
+ check(vec_all_eq(i4, ((vector unsigned int){4,4,4,4})), "i4");
+ check(vec_all_eq(i5, ((vector unsigned int){5,5,5,5})), "i5");
+ check(vec_all_eq(i6, ((vector unsigned int){6,6,6,6})), "i6");
+ check(vec_all_eq(i7, ((vector unsigned int){7,7,7,7})), "i7");
+ check(vec_all_eq(i8, ((vector unsigned int){8,8,8,8})), "i8");
+ check(vec_all_eq(i9, ((vector unsigned int){9,9,9,9})), "i9");
+ check(vec_all_eq(i10, ((vector unsigned int){10,10,10,10})), "i10");
+ check(vec_all_eq(i11, ((vector unsigned int){11,11,11,11})), "i11");
+ check(vec_all_eq(i12, ((vector unsigned int){12,12,12,12})), "i12");
+ check(vec_all_eq(i13, ((vector unsigned int){13,13,13,13})), "i13");
+ check(vec_all_eq(i14, ((vector unsigned int){14,14,14,14})), "i14");
+ check(i15 == 15, "i15");
+}
+
+static void test()
+{
+ varargsn001(((vector unsigned int){1,1,1,1}),
+ ((vector unsigned int){2,2,2,2}),
+ ((vector unsigned int){3,3,3,3}),
+ ((vector unsigned int){4,4,4,4}),
+ ((vector unsigned int){5,5,5,5}),
+ ((vector unsigned int){6,6,6,6}),
+ ((vector unsigned int){7,7,7,7}),
+ ((vector unsigned int){8,8,8,8}),
+ ((vector unsigned int){9,9,9,9}),
+ ((vector unsigned int){10,10,10,10}),
+ ((vector unsigned int){11,11,11,11}),
+ ((vector unsigned int){12,12,12,12}),
+ ((vector unsigned int){13,13,13,13}),
+ ((vector unsigned int){14,14,14,14}),
+ 15);
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/vmx.exp b/gcc/testsuite/gcc.dg/vmx/vmx.exp
new file mode 100644
index 00000000000..aa376b1d71d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/vmx.exp
@@ -0,0 +1,51 @@
+# Copyright (C) 2004 Free Software Foundation, Inc.
+
+# This program 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 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# Only run this test on PowerPC targets with Altivec support.
+# For now, that's powerpc*-*-*altivec*. FIXME: generalize.
+if {![istarget powerpc*-*-*altivec*]} {
+ return
+}
+
+# If a testcase doesn't have special options, use these.
+# -pedantic-errors is inappropriate here, as this subdirectory tests
+# nothing but extensions.
+global DEFAULT_VMXCFLAGS
+if ![info exists DEFAULT_VMXCFLAGS] then {
+ set DEFAULT_VMXCFLAGS "-maltivec -mabi=altivec -std=gnu99"
+}
+
+# Default action in this directory is 'run'.
+global dg-do-what-default
+set save-dg-do-what-default ${dg-do-what-default}
+set dg-do-what-default run
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] \
+ $DEFAULT_VMXCFLAGS
+
+# All done.
+dg-finish
+
+set dg-do-what-default ${save-dg-do-what-default}
diff --git a/gcc/testsuite/gcc.dg/vmx/vprint-1.c b/gcc/testsuite/gcc.dg/vmx/vprint-1.c
new file mode 100644
index 00000000000..37cd7bca739
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/vprint-1.c
@@ -0,0 +1,266 @@
+/* These tests require an AltiVec aware C library with vector
+ extensions for printf (%v). Currently newlib handles AltiVec
+ vector extensions. There are some clandestine patches for glibc
+ floating around, as well as a stanalone libaltivec library that
+ implements such extensions. */
+
+#include "harness.h"
+#include <string.h>
+
+static void test()
+{
+ const char *x;
+ char buf[256];
+
+ vector float f32;
+ vector signed char s8;
+ vector unsigned short u16;
+ vector signed short s16;
+ vector signed int s32;
+
+ f32 = ((vector float){1, 2.2, 333.333e-18, -4.5007544});
+
+ x = "%vf: 1.000000 2.200000 0.000000 -4.500754";
+ snprintf(buf, sizeof buf, "%%vf: %vf", f32);
+ check(!strcmp(buf, x), x);
+
+ x = "%ve: 1.000000e+00 2.200000e+00 3.333330e-16 -4.500754e+00";
+ snprintf(buf, sizeof buf, "%%ve: %ve", f32);
+ check(!strcmp(buf, x), x);
+
+ x = "%vE: 1.000000E+00 2.200000E+00 3.333330E-16 -4.500754E+00";
+ snprintf(buf, sizeof buf, "%%vE: %vE", f32);
+ check(!strcmp(buf, x), x);
+
+ x = "%vg: 1 2.2 3.33333e-16 -4.50075";
+ snprintf(buf, sizeof buf, "%%vg: %vg", f32);
+ check(!strcmp(buf, x), x);
+
+ x = "%vG: 1 2.2 3.33333E-16 -4.50075";
+ snprintf(buf, sizeof buf, "%%vG: %vG", f32);
+ check(!strcmp(buf, x), x);
+
+ x = "%7.3vf: 1.000 2.200 0.000 -4.501";
+ snprintf(buf, sizeof buf, "%%7.3vf: %7.3vf", f32);
+ check(!strcmp(buf, x), x);
+
+ x = "%:7.3vf: 1.000: 2.200: 0.000: -4.501";
+ snprintf(buf, sizeof buf, "%%:7.3vf: %:7.3vf", f32);
+ check(!strcmp(buf, x), x);
+
+ x = "%:7.3f: :7.3f";
+ snprintf(buf, sizeof buf, "%%:7.3f: %:7.3f", f32);
+ check(!strcmp(buf, x), x);
+
+
+ s8 = vec_sub((vector signed char)vec_lvsl(1,(signed char *)0),
+ ((vector signed char){8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8}));
+ x = "%vd: -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8";
+ snprintf(buf, sizeof buf, "%%vd: %vd", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%vi: -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8";
+ snprintf(buf, sizeof buf, "%%vi: %vi", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%vu: 249 250 251 252 253 254 255 0 1 2 3 4 5 6 7 8";
+ snprintf(buf, sizeof buf, "%%vu: %vu", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%vx: f9 fa fb fc fd fe ff 0 1 2 3 4 5 6 7 8";
+ snprintf(buf, sizeof buf, "%%vx: %vx", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%vo: 371 372 373 374 375 376 377 0 1 2 3 4 5 6 7 10";
+ snprintf(buf, sizeof buf, "%%vo: %vo", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%vp: 0xf9 0xfa 0xfb 0xfc 0xfd 0xfe 0xff 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8";
+ snprintf(buf, sizeof buf, "%%vp: %vp", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%vx: f9 fa fb fc fd fe ff 0 1 2 3 4 5 6 7 8";
+ snprintf(buf, sizeof buf, "%%vx: %vx", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%vX: F9 FA FB FC FD FE FF 0 1 2 3 4 5 6 7 8";
+ snprintf(buf, sizeof buf, "%%vX: %vX", s8);
+ check(!strcmp(buf, x), x);
+
+
+ x = "%hvd: -1542 -1028 -514 -256 258 772 1286 1800";
+ snprintf(buf, sizeof buf, "%%hvd: %hvd", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%vhi: -1542 -1028 -514 -256 258 772 1286 1800";
+ snprintf(buf, sizeof buf, "%%vhi: %vhi", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%hvu: 63994 64508 65022 65280 258 772 1286 1800";
+ snprintf(buf, sizeof buf, "%%hvu: %hvu", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%vhx: f9fa fbfc fdfe ff00 102 304 506 708";
+ snprintf(buf, sizeof buf, "%%vhx: %vhx", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%hvo: 174772 175774 176776 177400 402 1404 2406 3410";
+ snprintf(buf, sizeof buf, "%%hvo: %hvo", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%vhp: 0xf9fa 0xfbfc 0xfdfe 0xff00 0x102 0x304 0x506 0x708";
+ snprintf(buf, sizeof buf, "%%vhp: %vhp", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%hvx: f9fa fbfc fdfe ff00 102 304 506 708";
+ snprintf(buf, sizeof buf, "%%hvx: %hvx", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%vhX: F9FA FBFC FDFE FF00 102 304 506 708";
+ snprintf(buf, sizeof buf, "%%vhX: %vhX", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "0x%_04vhx: 0xf9fa_fbfc_fdfe_ff00_0102_0304_0506_0708";
+ snprintf(buf, sizeof buf, "0x%%_04vhx: 0x%_04vhx", s8);
+ check(!strcmp(buf, x), x);
+
+
+ x = "%lvd: -100992004 -33620224 16909060 84281096";
+ snprintf(buf, sizeof buf, "%%lvd: %lvd", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%vli: -100992004 -33620224 16909060 84281096";
+ snprintf(buf, sizeof buf, "%%vli: %vli", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%lvu: 4193975292 4261347072 16909060 84281096";
+ snprintf(buf, sizeof buf, "%%lvu: %lvu", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%vlx: f9fafbfc fdfeff00 1020304 5060708";
+ snprintf(buf, sizeof buf, "%%vlx: %vlx", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%lvo: 37176575774 37577577400 100401404 501403410";
+ snprintf(buf, sizeof buf, "%%lvo: %lvo", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%vlp: 0xf9fafbfc 0xfdfeff00 0x1020304 0x5060708";
+ snprintf(buf, sizeof buf, "%%vlp: %vlp", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%lvx: f9fafbfc fdfeff00 1020304 5060708";
+ snprintf(buf, sizeof buf, "%%lvx: %lvx", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%vlX: F9FAFBFC FDFEFF00 1020304 5060708";
+ snprintf(buf, sizeof buf, "%%vlX: %vlX", s8);
+ check(!strcmp(buf, x), x);
+
+ x = ">-154234 ;-1028 ;+0258 ;+1800 <";
+ printf(">%- +;8.4vld<", ((vector signed int){-154234, -1028, 258, 1800}));
+ check(!strcmp(buf, x), x);
+
+ x = "%,2vx: f9,fa,fb,fc,fd,fe,ff, 0, 1, 2, 3, 4, 5, 6, 7, 8";
+ snprintf(buf, sizeof buf, "%%,2vx: %,2vx", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%;4vhX: F9FA;FBFC;FDFE;FF00; 102; 304; 506; 708";
+ snprintf(buf, sizeof buf, "%%;4vhX: %;4vhX", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%;8vlx: f9fafbfc;fdfeff00; 1020304; 5060708";
+ snprintf(buf, sizeof buf, "%%;8vlx: %;8vlx", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%- ;+8.5vhd: -01542 ;-01028 ;-00514 ;-00256 ;+00258 ;+00772 ;+01286 ;+01800 ";
+ snprintf(buf, sizeof buf, "%%- ;+8.5vhd: %- ;+8.5vhd", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%- ;+*.5vhd: -01542 ;-01028 ;-00514 ;-00256 ;+00258 ;+00772 ;+01286 ;+01800 ";
+ snprintf(buf, sizeof buf, "%%- ;+*.5vhd: %- ;+*.5vhd", 8, s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%- ;+8.*vhd: -01542 ;-01028 ;-00514 ;-00256 ;+00258 ;+00772 ;+01286 ;+01800 ";
+ snprintf(buf, sizeof buf, "%%- ;+8.*vhd: %- ;+8.*vhd", 5, s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%- ;+*.*vhd: -01542 ;-01028 ;-00514 ;-00256 ;+00258 ;+00772 ;+01286 ;+01800 ";
+ snprintf(buf, sizeof buf, "%%- ;+*.*vhd: %- ;+*.*vhd", 8, 5, s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%- ;+7.4vhd: -1542 ;-1028 ;-0514 ;-0256 ;+0258 ;+0772 ;+1286 ;+1800 ";
+ snprintf(buf, sizeof buf, "%%- ;+7.4vhd: %- ;+7.4vhd", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%- ;+*.4vhd: -1542 ;-1028 ;-0514 ;-0256 ;+0258 ;+0772 ;+1286 ;+1800 ";
+ snprintf(buf, sizeof buf, "%%- ;+*.4vhd: %- ;+*.4vhd", 7, s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%- ;+7.*vhd: -1542 ;-1028 ;-0514 ;-0256 ;+0258 ;+0772 ;+1286 ;+1800 ";
+ snprintf(buf, sizeof buf, "%%- ;+7.*vhd: %- ;+7.*vhd", 4, s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%- ;+*.*vhd: -1542 ;-1028 ;-0514 ;-0256 ;+0258 ;+0772 ;+1286 ;+1800 ";
+ snprintf(buf, sizeof buf, "%%- ;+*.*vhd: %- ;+*.*vhd", 7, 4, s8);
+ check(!strcmp(buf, x), x);
+
+
+ s8 = vec_add(s8, ((vector signed char){'h','h','h','h','h','h','h','h',
+ 'h','h','h','h','h','h','h','h'}));
+ x = "%vc: abcdefghijklmnop";
+ snprintf(buf, sizeof buf, "%%vc: %vc", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "abcdefghijklmnopqrstuvwxyz,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p";
+ snprintf(buf, sizeof buf, "%vcqrstuvwxyz,%,vc", s8, s8);
+ check(!strcmp(buf, x), x);
+
+ x = "%#0,2vx: 0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70";
+ snprintf(buf, sizeof buf, "%%#0,2vx: %#0,2vx", s8);
+ check(!strcmp(buf, x), x);
+
+
+ s8 = ((vector signed char){'H','e','l','l','o',' ','W','o','r','l','d',',',' ','.','.','.' });
+ x = "s8 = Hello World, ...";
+ snprintf(buf, sizeof buf, "s8 = %vc", s8);
+ check(!strcmp(buf, x), x);
+
+ x = "s8 = H,e,l,l,o, ,W,o,r,l,d,,, ,.,.,.";
+ snprintf(buf, sizeof buf, "s8 = %,vc", s8);
+ check(!strcmp(buf, x), x);
+
+
+ s16 = ((vector signed short){-2,-1,0,1,2,3,4,5});
+ x = "s16 = -2 -1 0 1 2 3 4 5";
+ snprintf(buf, sizeof buf, "s16 = %vhd", s16);
+ check(!strcmp(buf, x), x);
+
+
+ u16 = ((vector unsigned short){65534,65535,0,1,2,3,4,5});
+ x = "u16 = 65534,65535,0,1,2,3,4,5";
+ snprintf(buf, sizeof buf, "u16 = %,vhu", u16);
+ check(!strcmp(buf, x), x);
+
+
+ s32 = ((vector signed int){1,2,3,99});
+ x = "s32 = 1, 2, 3,99";
+ snprintf(buf, sizeof buf, "s32 = %,2lvd", s32);
+ check(!strcmp(buf, x), x);
+
+
+ f32 = ((vector float){1.1, 2.2, 3.3, 4.39501});
+ x = "f32 = 1.10 ,2.20 ,3.30 ,4.40 ";
+ snprintf(buf, sizeof buf, "f32 = %-,5.2vf", f32);
+ check(!strcmp(buf, x), x);
+
+
+ /* <char-conv> only goes with <vector-size> 'v'. */
+ x = "u16 = vhc";
+ snprintf(buf, sizeof buf, "u16 = %vhc", u16);
+ check(!strcmp(buf, x), x);
+
+ x = "s32 = vhc";
+ snprintf(buf, sizeof buf, "s32 = %vhc", s32);
+ check(!strcmp(buf, x), x);
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/vscan-1.c b/gcc/testsuite/gcc.dg/vmx/vscan-1.c
new file mode 100644
index 00000000000..43c05b4b7ac
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/vscan-1.c
@@ -0,0 +1,418 @@
+/* These tests require an AltiVec aware C library with vector
+ extensions for scanf (%v). Currently newlib handles AltiVec
+ vector extensions. There are some clandestine patches for glibc
+ floating around, as well as a stanalone libaltivec library that
+ implements such extensions. */
+
+#include "harness.h"
+#include <string.h>
+
+void test()
+{
+ int n, i;
+ const char *p;
+ const char *x;
+ char buf[256];
+
+ char ch;
+ vector float f32;
+ vector signed char s8, s8a;
+ vector unsigned short u16;
+ vector signed short s16;
+ vector signed int s32;
+
+ f32 = ((vector float){0,0,0,0}); i = -1;
+ p = "%vf: 1.000000 2.200000 0.000000 -4.500754;";
+ x = "1:42:42:1.000000 2.200000 0.000000 -4.500754";
+ n = sscanf(p, "%%vf: %vf;%n", &f32, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vf", n, i, strlen(p), f32);
+ check(!strcmp(x, buf), p);
+
+ f32 = ((vector float){0,0,0,0}); i = -1;
+ p = "%ve: 1.000000e+00 2.200000e+00 3.333330e-16 -4.500754e+00;";
+ x = "1:58:58:1.000000e+00 2.200000e+00 3.333330e-16 -4.500754e+00";
+ n = sscanf(p, "%%ve: %ve;%n", &f32, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%ve", n, i, strlen(p), f32);
+ check(!strcmp(x, buf), p);
+
+ f32 = ((vector float){0,0,0,0}); i = -1;
+ p = "%vg: 1 2.2 3.33333e-16 -4.50075;";
+ x = "1:32:32:1 2.2 3.33333e-16 -4.50075";
+ n = sscanf(p, "%%vg: %vg;%n", &f32, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vg", n, i, strlen(p), f32);
+ check(!strcmp(x, buf), p);
+
+ f32 = ((vector float){0,0,0,0}); i = -1;
+ p = "%vG: 1 2.2 3.33333E-16 -4.50075;";
+ x = "1:32:32:1 2.2 3.33333E-16 -4.50075";
+ n = sscanf(p, "%%vG: %vG;%n", &f32, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vG", n, i, strlen(p), f32);
+ check(!strcmp(x, buf), p);
+
+ f32 = ((vector float){0,0,0,0}); i = -1;
+ p = "%:7.3vf: 1.000: 2.200: 0.000: -4.501;";
+ x = "1:41:41: 1.000: 2.200: 0.000: -4.501";
+ n = sscanf(p, "%%:7.3vf:%:7vf;%n", &f32, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%:7.3vf", n, i, strlen(p), f32);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%vd: -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8;";
+ x = "1:44:44:-7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8";
+ n = sscanf(p, "%%vd:%vd;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vd", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%vi: -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8;";
+ x = "1:44:44:-7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8";
+ n = sscanf(p, "%%vi:%vi;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vi", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%vu: 249 250 251 252 253 254 255 0 1 2 3 4 5 6 7 8;";
+ x = "1:51:51:249 250 251 252 253 254 255 0 1 2 3 4 5 6 7 8";
+ n = sscanf(p, "%%vu:%vu;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vu", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%vx: f9 fa fb fc fd fe ff 0 1 2 3 4 5 6 7 8;";
+ x = "1:44:44:f9 fa fb fc fd fe ff 0 1 2 3 4 5 6 7 8";
+ n = sscanf(p, "%%vx:%vx;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vx", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%vo: 371 372 373 374 375 376 377 0 1 2 3 4 5 6 7 10;";
+ x = "1:52:52:371 372 373 374 375 376 377 0 1 2 3 4 5 6 7 10";
+ n = sscanf(p, "%%vo:%vo;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vo", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%vp: 0xf9 0xfa 0xfb 0xfc 0xfd 0xfe 0xff 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8;";
+ x = "1:76:76:0xf9 0xfa 0xfb 0xfc 0xfd 0xfe 0xff 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8";
+ n = sscanf(p, "%%vp:%vp;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vp", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%vx: f9 fa fb fc fd fe ff 0 1 2 3 4 5 6 7 8;";
+ x = "1:44:44:f9 fa fb fc fd fe ff 0 1 2 3 4 5 6 7 8";
+ n = sscanf(p, "%%vx:%vx;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vx", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%vX: F9 FA FB FC FD FE FF 0 1 2 3 4 5 6 7 8;";
+ x = "1:44:44:F9 FA FB FC FD FE FF 0 1 2 3 4 5 6 7 8";
+ n = sscanf(p, "%%vX:%vX;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vX", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%hvd: -1542 -1028 -514 -256 258 772 1286 1800;";
+ x = "1:46:46:-1542 -1028 -514 -256 258 772 1286 1800";
+ n = sscanf(p, "%%hvd:%hvd;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%hvd", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%vhi: -1542 -1028 -514 -256 258 772 1286 1800;";
+ x = "1:46:46:-1542 -1028 -514 -256 258 772 1286 1800";
+ n = sscanf(p, "%%vhi:%vhi;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vhi", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%hvu: 63994 64508 65022 65280 258 772 1286 1800;";
+ x = "1:48:48:63994 64508 65022 65280 258 772 1286 1800";
+ n = sscanf(p, "%%hvu:%hvu;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%hvu", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%vhx: f9fa fbfc fdfe ff00 102 304 506 708;";
+ x = "1:42:42:f9fa fbfc fdfe ff00 102 304 506 708";
+ n = sscanf(p, "%%vhx:%vhx;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vhx", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "0x%_vhx: 0xf9fa_fbfc_fdfe_ff00_0102_0304_0506_0708;";
+ x = "1:51:51:0xf9fa_fbfc_fdfe_ff00_0102_0304_0506_0708";
+ n = sscanf(p, "0x%%_vhx:%_vhx;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:0x%_04vhx", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%hvo: 174772 175774 176776 177400 402 1404 2406 3410;";
+ x = "1:53:53:174772 175774 176776 177400 402 1404 2406 3410";
+ n = sscanf(p, "%%hvo:%hvo;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%hvo", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%vhp: 0xf9fa 0xfbfc 0xfdfe 0xff00 0x102 0x304 0x506 0x708;";
+ x = "1:58:58:0xf9fa 0xfbfc 0xfdfe 0xff00 0x102 0x304 0x506 0x708";
+ n = sscanf(p, "%%vhp:%vhp;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vhp", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%hvx: f9fa fbfc fdfe ff00 102 304 506 708;";
+ x = "1:42:42:f9fa fbfc fdfe ff00 102 304 506 708";
+ n = sscanf(p, "%%hvx:%hvx;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%hvx", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%vhX: F9FA FBFC FDFE FF00 102 304 506 708;";
+ x = "1:42:42:F9FA FBFC FDFE FF00 102 304 506 708";
+ n = sscanf(p, "%%vhX:%vhX;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vhX", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%lvd: -100992004 -33620224 16909060 84281096;";
+ x = "1:45:45:-100992004 -33620224 16909060 84281096";
+ n = sscanf(p, "%%lvd:%lvd;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%lvd", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%vli: -100992004 -33620224 16909060 84281096;";
+ x = "1:45:45:-100992004 -33620224 16909060 84281096";
+ n = sscanf(p, "%%vli:%vli;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vli", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%lvu: 4193975292 4261347072 16909060 84281096;";
+ x = "1:46:46:4193975292 4261347072 16909060 84281096";
+ n = sscanf(p, "%%lvu:%lvu;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%lvu", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%vlx: f9fafbfc fdfeff00 1020304 5060708;";
+ x = "1:40:40:f9fafbfc fdfeff00 1020304 5060708";
+ n = sscanf(p, "%%vlx:%vlx;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vlx", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%lvo: 37176575774 37577577400 100401404 501403410;";
+ x = "1:50:50:37176575774 37577577400 100401404 501403410";
+ n = sscanf(p, "%%lvo:%lvo;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%lvo", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%vlp: 0xf9fafbfc 0xfdfeff00 0x1020304 0x5060708;";
+ x = "1:48:48:0xf9fafbfc 0xfdfeff00 0x1020304 0x5060708";
+ n = sscanf(p, "%%vlp:%vlp;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vlp", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%lvx: f9fafbfc fdfeff00 1020304 5060708;";
+ x = "1:40:40:f9fafbfc fdfeff00 1020304 5060708";
+ n = sscanf(p, "%%lvx:%lvx;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%lvx", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%vlX: F9FAFBFC FDFEFF00 1020304 5060708;";
+ x = "1:40:40:F9FAFBFC FDFEFF00 1020304 5060708";
+ n = sscanf(p, "%%vlX:%vlX;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vlX", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%,2vx: f9,fa,fb,fc,fd,fe,ff, 0, 1, 2, 3, 4, 5, 6, 7, 8;";
+ x = "1:55:55:f9,fa,fb,fc,fd,fe,ff, 0, 1, 2, 3, 4, 5, 6, 7, 8";
+ n = sscanf(p, "%%,2vx:%,2vx;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%,2vx", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%;4vhX: F9FA;FBFC;FDFE;FF00; 102; 304; 506; 708;";
+ x = "1:48:48:F9FA;FBFC;FDFE;FF00; 102; 304; 506; 708";
+ n = sscanf(p, "%%;4vhX:%;4vhX;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%;4vhX", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%;8vlx: f9fafbfc;fdfeff00; 1020304; 5060708;";
+ x = "1:44:44:f9fafbfc;fdfeff00; 1020304; 5060708";
+ n = sscanf(p, "%%;8vlx:%;8vlx;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%;8vlx", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%;8vhd: -01542; -01028; -00514; -00256; +00258; +00772; +01286; +01800;";
+ x = "1:78:78:-01542 ;-01028 ;-00514 ;-00256 ;+00258 ;+00772 ;+01286 ;+01800 ";
+ n = sscanf(p, "%%;8vhd:%;8vhd;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%- ;+8.5vhd", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%;8vhd: -01542 ;-01028 ;-00514 ;-00256 ;+00258 ;+00772 ;+01286 ;+01800 ;";
+ x = "1:80:80:-01542 ;-01028 ;-00514 ;-00256 ;+00258 ;+00772 ;+01286 ;+01800 ";
+ n = sscanf(p, "%%;8vhd:%;8vhd ;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%- ;+8.5vhd", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%vc: ab defghijklmnop;";
+ x = "1:22:22:ab defghijklmnop";
+ n = sscanf(p, "%%vc: %vc;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vc", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%vcqrstuvwxyz,%,vc: ab defghijklmnopqrstuvwxyz,a,b, ,d,e,f,g,h,i,j,k,l,m,n,o,p;";
+ x = "2:79:79:ab defghijklmnopqrstuvwxyz,a,b, ,d,e,f,g,h,i,j,k,l,m,n,o,p";
+ n = sscanf(p, "%%vcqrstuvwxyz,%%,vc: %vcqrstuvwxyz,%,vc;%n", &s8, &s8a, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vcqrstuvwxyz,%,vc", n, i, strlen(p), s8, s8a);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%,vx: 0x61, 0x62 ,0x63 , 0x64,0x65 ,0x66, 0x67 , 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70;";
+ x = "1:98:98:0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70";
+ n = sscanf(p, "%%,vx:%,vx;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%#,vx", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ /* Input conflict after 0x70. two assignments; %n not processed. */
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%,vx: 0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70#";
+ x = "1:-1:86:0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70";
+ n = sscanf(p, "%%,vx:%,vx;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%#,vx", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ /* Input conflict after 0x67. one assignment; %n not processed. */
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%,vx: 0x61,0x62,0x63,0x64,0x65,0x66,0x67#0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70;";
+ x = "1:-1:86:0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0";
+ n = sscanf(p, "%%,vx%c%,vx;%n", &ch, &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%#,vx", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ /* Input conflict after 0x7. two assignments; %n not processed. */
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%,vx: 0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x7_0;";
+ x = "2:-1:87:0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x7";
+ n = sscanf(p, "%%,vx%c%,vx;%n", &ch, &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%#,vx", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ /* EOF reached before the first assignment. */
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%,vx: 0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f";
+ x = "-1:-1:80:0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0";
+ n = sscanf(p, "%%,vx:%,vx;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%#,vx", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ /* EOF reached before the first assignment. */
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%,vx: 0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f ";
+ x = "-1:-1:81:0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0";
+ n = sscanf(p, "%%,vx:%,vx;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%#,vx", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ /* EOF reached before the first assignment. */
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%,vx: 0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f ,";
+ x = "-1:-1:82:0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0";
+ n = sscanf(p, "%%,vx:%,vx;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%#,vx", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ /* EOF reached before the first assignment. */
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%,vx: 0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, ";
+ x = "-1:-1:82:0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0";
+ n = sscanf(p, "%%,vx:%,vx;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%#,vx", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ /* Input conflict after 0x7. one assignment; %n not processed. */
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%,vx: 0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x7_0;";
+ x = "1:-1:87:0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x7";
+ n = sscanf(p, "%%,vx:%,vx;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%#,vx", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ /* Input conflict after 0x61. zero assignments; %n not processed. */
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "%,vx: 0x61 0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70;";
+ x = "0:-1:86:0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0";
+ n = sscanf(p, "%%,vx:%,vx;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%#,vx", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "Hello World, ...;";
+ x = "1:17:17:Hello World, ...";
+ n = sscanf(p, "%vc;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vc", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s8 = ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); i = -1;
+ p = "H,e,l,l,o, ,W,o,r,l,d,,, ,.,.,.;";
+ x = "1:32:32:H,e,l,l,o, ,W,o,r,l,d,,, ,.,.,.";
+ n = sscanf(p, "%,vc;%n", &s8, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%,vc", n, i, strlen(p), s8);
+ check(!strcmp(x, buf), p);
+
+ s16 = ((vector signed short){0,0,0,0,0,0,0,0}); i = -1;
+ p = "-2 -1 0 1 2 3 4 5;";
+ x = "1:18:18:-2 -1 0 1 2 3 4 5";
+ n = sscanf(p, "%vhd;%n", &s16, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%vhd", n, i, strlen(p), s16);
+ check(!strcmp(x, buf), p);
+
+ u16 = ((vector unsigned short){0,0,0,0,0,0,0,0}); i = -1;
+ p = "65534,65535,0,1,2,3,4,5;";
+ x = "1:24:24:65534,65535,0,1,2,3,4,5";
+ n = sscanf(p, "%,vhu;%n", &u16, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%,vhu", n, i, strlen(p), u16);
+ check(!strcmp(x, buf), p);
+
+ s32 = ((vector signed int){0,0,0,0}); i = -1;
+ p = " 1, 2, 3,99;";
+ x = "1:12:12: 1, 2, 3,99";
+ n = sscanf(p, "%,2lvd;%n", &s32, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%,2lvd", n, i, strlen(p), s32);
+ check(!strcmp(x, buf), p);
+
+ f32 = ((vector float){0,0,0,0}); i = -1;
+ p = "1.10 ,2.20 ,3.30 ,4.40 ;";
+ x = "1:24:24:1.10 ,2.20 ,3.30 ,4.40 ";
+ n = sscanf(p, "%,5vf ;%n", &f32, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%-,5.2vf", n, i, strlen(p), f32);
+ check(!strcmp(x, buf), p);
+
+ /* <char-conv> only goes with <vector-size> 'v'. */
+ u16 = ((vector unsigned short){0,0,0,0,0,0,0,0}); i = -1;
+ p = "abcdefgh;";
+ x = "0:-1:9:0,0,0,0,0,0,0,0";
+ n = sscanf(p, "%vhc;%n", &u16, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%,vhu", n, i, strlen(p), u16);
+ check(!strcmp(x, buf), p);
+
+ s32 = ((vector signed int){0,0,0,0}); i = -1;
+ p = "abcd;";
+ x = "0:-1:5:0,0,0,0";
+ n = sscanf(p, "%lvc;%n", &s32, &i);
+ snprintf(buf, sizeof buf, "%d:%d:%d:%,vlu", n, i, strlen(p), s32);
+ check(!strcmp(x, buf), p);
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/x-01.c b/gcc/testsuite/gcc.dg/vmx/x-01.c
new file mode 100644
index 00000000000..324e83e35a2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/x-01.c
@@ -0,0 +1,25 @@
+#include <altivec.h>
+vector bool char
+g(vector unsigned char, vector bool char);
+
+vector bool char
+f(vector bool char b, vector unsigned char d)
+{
+ vector bool char *p = &b;
+ *p = g(d,b);
+ return *p;
+}
+
+vector bool char b8;
+vector unsigned char u8;
+vector bool char
+g(vector unsigned char a, vector bool char b)
+{
+ return b8;
+}
+
+int main()
+{
+ f(b8, u8);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/x-02.c b/gcc/testsuite/gcc.dg/vmx/x-02.c
new file mode 100644
index 00000000000..4ddcc0c00dd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/x-02.c
@@ -0,0 +1,34 @@
+#include <altivec.h>
+
+static vector bool char
+g(vector unsigned char, vector bool char);
+
+static int q(void);
+
+static vector bool char
+f(vector bool char b, vector unsigned char d)
+{
+ vector bool char *p = &b;
+ *p = g(d,b);
+ return q() ? *p : b;
+}
+
+static vector bool char b8;
+static vector unsigned char u8;
+
+static vector bool char
+g(vector unsigned char a, vector bool char b)
+{
+ return b8;
+}
+
+static int q ()
+{
+ return 1;
+}
+
+int main()
+{
+ f(b8, u8);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/x-03.c b/gcc/testsuite/gcc.dg/vmx/x-03.c
new file mode 100644
index 00000000000..0972ac9a3d8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/x-03.c
@@ -0,0 +1,124 @@
+#include <altivec.h>
+extern vector unsigned char u8(void);
+extern vector signed char s8(void);
+extern vector bool char b8(void);
+extern vector unsigned short u16(void);
+extern vector signed short s16(void);
+extern vector bool short b16(void);
+extern vector unsigned int u32(void);
+extern vector signed int s32(void);
+extern vector bool int b32(void);
+extern vector float f32(void);
+extern vector pixel p16(void);
+
+extern void g(vector unsigned char, ...);
+
+void
+f(vector unsigned char u8p, vector signed char s8p, vector bool char b8p,
+ vector unsigned short u16p, vector signed short s16p,
+ vector bool short b16p, vector unsigned int u32p,
+ vector signed int s32p, vector bool int b32p,
+ vector float f32p, vector pixel p16p)
+{
+ vector unsigned char u8l = u8();
+ vector signed char s8l = s8();
+ vector bool char b8l = b8();
+ vector unsigned short u16l = u16();
+ vector signed short s16l = s16();
+ vector bool short b16l = b16();
+ vector unsigned int u32l = u32();
+ vector signed int s32l = s32();
+ vector bool int b32l = b32();
+ vector float f32l = f32();
+ vector pixel p16l = p16();
+
+ g(u8l, s8l, b8l, u16l, s16l, b16l, u32l, s32l, b32l, f32l, p16l);
+}
+
+vector unsigned char
+u8(void)
+{
+ static vector unsigned char zero;
+ return zero;
+}
+
+vector signed char
+s8(void)
+{
+ static vector signed char zero;
+ return zero;
+}
+
+vector bool char
+b8(void)
+{
+ static vector bool char zero;
+ return zero;
+}
+
+vector unsigned short
+u16(void)
+{
+ static vector unsigned short zero;
+ return zero;
+}
+
+vector signed short
+s16(void)
+{
+ static vector signed short zero;
+ return zero;
+}
+
+vector bool short
+b16(void)
+{
+ static vector bool short zero;
+ return zero;
+}
+
+vector unsigned int
+u32(void)
+{
+ static vector unsigned int zero;
+ return zero;
+}
+
+vector signed int
+s32(void)
+{
+ static vector signed int zero;
+ return zero;
+}
+
+vector bool int
+b32(void)
+{
+ static vector bool int zero;
+ return zero;
+}
+
+vector float
+f32(void)
+{
+ static vector float zero;
+ return zero;
+}
+
+vector pixel
+p16(void)
+{
+ static vector pixel zero;
+ return zero;
+}
+
+void
+g(vector unsigned char a, ...)
+{
+}
+
+int main()
+{
+ f(u8(), s8(), b8(), u16(), s16(), b16(), u32(), s32(), b32(), f32(), p16());
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/x-04.c b/gcc/testsuite/gcc.dg/vmx/x-04.c
new file mode 100644
index 00000000000..44694c8a6d5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/x-04.c
@@ -0,0 +1,80 @@
+#include <altivec.h>
+vector unsigned char
+permute_128(vector unsigned char input)
+{
+ vector unsigned char result, new_bit;
+
+ vector unsigned char select2 = ((vector unsigned char){2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2});
+ vector unsigned char select3 = ((vector unsigned char){4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4});
+ vector unsigned char select4 = ((vector unsigned char){8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8});
+ vector unsigned char select5 = ((vector unsigned char){16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16});
+ vector unsigned char select6 = ((vector unsigned char){32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32});
+ vector unsigned char select7 = ((vector unsigned char){64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64});
+ vector unsigned char select8 = ((vector unsigned char){128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128});
+
+ vector unsigned char control1
+ = ((vector unsigned char){15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0});
+ vector unsigned char control2
+ = ((vector unsigned char){15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0});
+ vector unsigned char control3
+ = ((vector unsigned char){15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0});
+ vector unsigned char control4
+ = ((vector unsigned char){15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0});
+ vector unsigned char control5
+ = ((vector unsigned char){15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0});
+ vector unsigned char control6
+ = ((vector unsigned char){15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0});
+ vector unsigned char control7
+ = ((vector unsigned char){15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0});
+ vector unsigned char control8
+ = ((vector unsigned char){15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0});
+ vector unsigned char rotate1 = ((vector unsigned char){1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1});
+ vector unsigned char rotate2 = ((vector unsigned char){3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3});
+ vector unsigned char rotate3 = ((vector unsigned char){5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5});
+ vector unsigned char rotate4 = ((vector unsigned char){7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7});
+ vector unsigned char rotate5 = ((vector unsigned char){1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1});
+ vector unsigned char rotate6 = ((vector unsigned char){3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3});
+ vector unsigned char rotate7 = ((vector unsigned char){5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5});
+ vector unsigned char rotate8 = ((vector unsigned char){7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7});
+
+ result = vec_vperm(input, input, control1);
+ result = vec_rl(result, rotate1);
+
+ new_bit = vec_vperm(input, input, control2);
+ new_bit = vec_rl(new_bit, rotate2);
+ result = vec_sel(result, new_bit, select2);
+
+ new_bit = vec_vperm(input, input, control3);
+ new_bit = vec_rl(new_bit, rotate3);
+ result = vec_sel(result, new_bit, select3);
+
+ new_bit = vec_vperm(input, input, control4);
+ new_bit = vec_rl(new_bit, rotate4);
+ result = vec_sel(result, new_bit, select4);
+
+ new_bit = vec_vperm(input, input, control5);
+ new_bit = vec_rl(new_bit, rotate5);
+ result = vec_sel(result, new_bit, select5);
+
+ new_bit = vec_vperm(input, input, control6);
+ new_bit = vec_rl(new_bit, rotate6);
+ result = vec_sel(result, new_bit, select6);
+
+ new_bit = vec_vperm(input, input, control7);
+ new_bit = vec_rl(new_bit, rotate7);
+ result = vec_sel(result, new_bit, select7);
+
+ new_bit = vec_vperm(input, input, control8);
+ new_bit = vec_rl(new_bit, rotate8);
+ result = vec_sel(result, new_bit, select8);
+
+ return result;
+}
+
+int main()
+{
+ vector unsigned char input
+ = ((vector unsigned char){0,1,2,4,8,16,32,64,128,0,1,2,4,8,16,32});
+ vector unsigned char result = permute_128(input);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/x-05.c b/gcc/testsuite/gcc.dg/vmx/x-05.c
new file mode 100644
index 00000000000..80c13dcf04e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/x-05.c
@@ -0,0 +1,82 @@
+#include <altivec.h>
+
+static vector unsigned char select2 = {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2};
+static vector unsigned char select3 = {4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4};
+static vector unsigned char select4 = {8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8};
+static vector unsigned char select5 = {16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16};
+static vector unsigned char select6 = {32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32};
+static vector unsigned char select7 = {64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64};
+static vector unsigned char select8 = {128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128};
+
+static vector unsigned char control1
+ = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0};
+static vector unsigned char control2
+ = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0};
+static vector unsigned char control3
+ = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0};
+static vector unsigned char control4
+ = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0};
+static vector unsigned char control5
+ = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0};
+static vector unsigned char control6
+ = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0};
+static vector unsigned char control7
+ = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0};
+static vector unsigned char control8
+ = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0};
+static vector unsigned char rotate1 = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+static vector unsigned char rotate2 = {3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3};
+static vector unsigned char rotate3 = {5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5};
+static vector unsigned char rotate4 = {7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
+static vector unsigned char rotate5 = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+static vector unsigned char rotate6 = {3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3};
+static vector unsigned char rotate7 = {5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5};
+static vector unsigned char rotate8 = {7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
+
+static vector unsigned char permute_128(vector unsigned char input)
+{
+ vector unsigned char result, new_bit;
+
+ /* and now the code */
+ result = vec_vperm(input, input, control1);
+ result = vec_rl(result, rotate1);
+
+ new_bit = vec_vperm(input, input, control2);
+ new_bit = vec_rl(new_bit, rotate2);
+ result = vec_sel(result, new_bit, select2);
+
+ new_bit = vec_vperm(input, input, control3);
+ new_bit = vec_rl(new_bit, rotate3);
+ result = vec_sel(result, new_bit, select3);
+
+ new_bit = vec_vperm(input, input, control4);
+ new_bit = vec_rl(new_bit, rotate4);
+ result = vec_sel(result, new_bit, select4);
+
+ new_bit = vec_vperm(input, input, control5);
+ new_bit = vec_rl(new_bit, rotate5);
+ result = vec_sel(result, new_bit, select5);
+
+ new_bit = vec_vperm(input, input, control6);
+ new_bit = vec_rl(new_bit, rotate6);
+ result = vec_sel(result, new_bit, select6);
+
+ new_bit = vec_vperm(input, input, control7);
+ new_bit = vec_rl(new_bit, rotate7);
+ result = vec_sel(result, new_bit, select7);
+
+ new_bit = vec_vperm(input, input, control8);
+ new_bit = vec_rl(new_bit, rotate8);
+ result = vec_sel(result, new_bit, select8);
+
+ return result;
+}
+
+int main()
+{
+ vector unsigned char input
+ = {0,1,2,4,8,16,32,64,128,0,1,2,4,8,16,32};
+ vector unsigned char result = permute_128(input);
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/vmx/yousufi-1.c b/gcc/testsuite/gcc.dg/vmx/yousufi-1.c
new file mode 100644
index 00000000000..eed4be3d1f4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/yousufi-1.c
@@ -0,0 +1,15 @@
+#include "harness.h"
+
+/* Tests the vec_ctu function, which converts a vector of floats to a vector
+ of unsigned ints. In powerpc-eabisim-run ver. moto-1.0, vec_ctu produces
+ strange output for input values of less than ~.0039. -Umair */
+
+static void test()
+{
+ vector float input = ((vector float){0.003,0.003,0.003,0.003});
+ vector unsigned int output;
+ vector unsigned int expect = ((vector unsigned int){0,0,0,0});
+
+ output = vec_ctu(input, 1);
+ check(vec_all_eq(output, expect), "vec_ctu");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/zero-1.c b/gcc/testsuite/gcc.dg/vmx/zero-1.c
new file mode 100644
index 00000000000..637351cc5d4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/zero-1.c
@@ -0,0 +1,13 @@
+#include "harness.h"
+
+static vector unsigned int funny()
+{
+ vector unsigned int a;
+ return vec_andc(vec_add(a,a),vec_add(a,a));
+}
+
+static void test()
+{
+ static vector unsigned int zero;
+ check(vec_all_eq(funny(), zero), "funny");
+}
diff --git a/gcc/testsuite/gcc.dg/vmx/zero.c b/gcc/testsuite/gcc.dg/vmx/zero.c
new file mode 100644
index 00000000000..9a337e6e855
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/zero.c
@@ -0,0 +1,100 @@
+#include "harness.h"
+
+vector signed short zs16() { return ((vector signed short){0,0,0,0,0,0,0,0}); }
+vector signed short s16ss() { vector signed short a; return vec_subs(a,a); }
+vector signed short s16s() { vector signed short a; return vec_sub(a,a); }
+vector signed short s16x() { vector signed short a; return vec_xor(a,a); }
+vector signed short s16a() { vector signed short a; return vec_andc(a,a); }
+
+vector unsigned short zu16() { return ((vector unsigned short){0,0,0,0,0,0,0,0}); }
+vector unsigned short u16ss() { vector unsigned short a; return vec_subs(a,a); }
+vector unsigned short u16s() { vector unsigned short a; return vec_sub(a,a); }
+vector unsigned short u16x() { vector unsigned short a; return vec_xor(a,a); }
+vector unsigned short u16a() { vector unsigned short a; return vec_andc(a,a); }
+
+vector signed int zs32() { return ((vector signed int){0,0,0,0}); }
+vector signed int s32ss() { vector signed int a; return vec_subs(a,a); }
+vector signed int s32s() { vector signed int a; return vec_sub(a,a); }
+vector signed int s32x() { vector signed int a; return vec_xor(a,a); }
+vector signed int s32a() { vector signed int a; return vec_andc(a,a); }
+
+vector unsigned int zu32() { return ((vector unsigned int){0,0,0,0}); }
+vector unsigned int u32ss() { vector unsigned int a; return vec_subs(a,a); }
+vector unsigned int u32s() { vector unsigned int a; return vec_sub(a,a); }
+vector unsigned int u32x() { vector unsigned int a; return vec_xor(a,a); }
+vector unsigned int u32a() { vector unsigned int a; return vec_andc(a,a); }
+
+vector signed char zs8() { return ((vector signed char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); }
+vector signed char s8ss() { vector signed char a; return vec_subs(a,a); }
+vector signed char s8s() { vector signed char a; return vec_sub(a,a); }
+vector signed char s8x() { vector signed char a; return vec_xor(a,a); }
+vector signed char s8a() { vector signed char a; return vec_andc(a,a); }
+
+vector unsigned char zu8() { return ((vector unsigned char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); }
+vector unsigned char u8ss() { vector unsigned char a; return vec_subs(a,a); }
+vector unsigned char u8s() { vector unsigned char a; return vec_sub(a,a); }
+vector unsigned char u8x() { vector unsigned char a; return vec_xor(a,a); }
+vector unsigned char u8a() { vector unsigned char a; return vec_andc(a,a); }
+
+vector pixel zp16() { return ((vector pixel){0,0,0,0,0,0,0,0}); }
+
+vector bool short zb16() { return ((vector bool short){0,0,0,0,0,0,0,0}); }
+
+vector bool short b16x() { vector bool short a; return vec_xor(a,a); }
+vector bool short b16a() { vector bool short a; return vec_andc(a,a); }
+vector bool int zb32() { return ((vector bool int){0,0,0,0}); }
+
+vector bool int b32x() { vector bool int a; return vec_xor(a,a); }
+vector bool int b32a() { vector bool int a; return vec_andc(a,a); }
+vector bool char zb8() { return ((vector bool char){0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); }
+
+vector bool char b8x() { vector bool char a; return vec_xor(a,a); }
+vector bool char b8a() { vector bool char a; return vec_andc(a,a); }
+
+static void test()
+{
+ static vector unsigned int zerov;
+#define zcheck(val, tag) \
+ check(vec_all_eq((vector unsigned int)(val), zerov), tag)
+
+ zcheck(zs16(), "zs16");
+ zcheck(s16ss(), "s16ss");
+ zcheck(s16s(), "s16s");
+ zcheck(s16x(), "s16x");
+ zcheck(s16a(), "s16a");
+ zcheck(zu16(), "zu16");
+ zcheck(u16ss(), "u16ss");
+ zcheck(u16s(), "u16s");
+ zcheck(u16x(), "u16x");
+ zcheck(u16a(), "u16a");
+ zcheck(zs32(), "zs32");
+ zcheck(s32ss(), "s32ss");
+ zcheck(s32s(), "s32s");
+ zcheck(s32x(), "s32x");
+ zcheck(s32a(), "s32a");
+ zcheck(zu32(), "zu32");
+ zcheck(u32ss(), "u32ss");
+ zcheck(u32s(), "u32s");
+ zcheck(u32x(), "u32x");
+ zcheck(u32a(), "u32a");
+ zcheck(zs8(), "zs8");
+ zcheck(s8ss(), "s8ss");
+ zcheck(s8s(), "s8s");
+ zcheck(s8x(), "s8x");
+ zcheck(s8a(), "s8a");
+ zcheck(zu8(), "zu8");
+ zcheck(u8ss(), "u8ss");
+ zcheck(u8s(), "u8s");
+ zcheck(u8x(), "u8x");
+ zcheck(u8a(), "u8a");
+ zcheck(zp16(), "zp16");
+ zcheck(zb16(), "zb16");
+ zcheck(b16x(), "b16x");
+ zcheck(b16a(), "b16a");
+ zcheck(zb32(), "zb32");
+ zcheck(b32x(), "b32x");
+ zcheck(b32a(), "b32a");
+ zcheck(zb8(), "zb8");
+ zcheck(b8x(), "b8x");
+ zcheck(b8a(), "b8a");
+}
diff --git a/gcc/testsuite/gcc.dg/vr-mult-1.c b/gcc/testsuite/gcc.dg/vr-mult-1.c
new file mode 100644
index 00000000000..a208067fb7d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vr-mult-1.c
@@ -0,0 +1,10 @@
+/* Make sure that mul/addu is preferred over mtlo/macc on targets that
+ support both. */
+/* { dg-do compile { target mips*-*-* } } */
+/* { dg-options "-O2" } */
+#if defined (_MIPS_ARCH_VR5400) || defined (_MIPS_ARCH_VR5500)
+int f (int a, int b, int c) { return a + b * c; }
+#else
+void f () { asm volatile ("mul/addu"); }
+#endif
+/* { dg-final { scan-assembler "mul.*addu" } } */
diff --git a/gcc/testsuite/gcc.dg/vr-mult-2.c b/gcc/testsuite/gcc.dg/vr-mult-2.c
new file mode 100644
index 00000000000..4a3ad98cc2a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vr-mult-2.c
@@ -0,0 +1,10 @@
+/* Make sure that mul/subu is preferred over mtlo/msac on targets that
+ support both. */
+/* { dg-do compile { target mips*-*-* } } */
+/* { dg-options "-O2" } */
+#if defined (_MIPS_ARCH_VR5400) || defined (_MIPS_ARCH_VR5500)
+int f (int a, int b, int c) { return a - b * c; }
+#else
+void f () { asm volatile ("mul/subu"); }
+#endif
+/* { dg-final { scan-assembler "mul.*subu" } } */
diff --git a/gcc/testsuite/gcc.dg/warn-1.c b/gcc/testsuite/gcc.dg/warn-1.c
index 9d0080171d2..ce35b41e941 100644
--- a/gcc/testsuite/gcc.dg/warn-1.c
+++ b/gcc/testsuite/gcc.dg/warn-1.c
@@ -5,12 +5,12 @@
static void foo (p)
int p;
-{ /* { dg-warning "passing arg 1 of" } */
+{
}
void bar (void)
{
void *vp;
- foo (vp); /* { dg-warning "" } */
+ foo (vp); /* { dg-warning "passing arg 1 of" } */
}
diff --git a/gcc/testsuite/gfortran.fortran-torture/ChangeLog.g95 b/gcc/testsuite/gfortran.fortran-torture/ChangeLog.g95
new file mode 100644
index 00000000000..c333a3eab1a
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/ChangeLog.g95
@@ -0,0 +1,99 @@
+2003-07-24 Lifang Zeng <zlf605@hotmail.com>
+
+ * execute/where_3.f90: Modified.
+ * execute/where_6.f90: New testcase.
+
+2003-07-09 Chun HUang <compiler@sohu.com>
+
+ * execute/intrinsic_scan.f90: Test the SCAN intrinsic.
+ * execute/intrinsic_verify.f90: Test the VERIFY intrinsic.
+
+2003-07-02 Paul Brook <paul@nowt.org>
+
+ * execite/initializer.f90: Test arrays with scalar initializer.
+
+2003-06-02 Kejia Zhao <kejia_zh@yahoo.com.cn>
+
+ * execute/intrinsic_associated.f90: New testcase.
+ * execute/intrinsic_associated_2.f90: New testcase.
+
+2003-06-01 Paul Brook <paul@nowt.org>
+
+ * execute/power.f90: Check complex ** real.
+
+2003-05-20 Paul Brook <paul@nowt.org>
+
+ * execute/forall_1.f90: Avoid many to one assignment.
+
+2003-05-20 Canqun Yang <canqun@yahoo.com.cn>
+
+ * execute/forall_1.f90: Replace logical operator 'and' with 'or'.
+
+2003-05-19 Lifang Zeng <zlf605@hotmail.com>
+
+ * execute/forall_1.f90: FORALL with negative stride, FORALL has
+ arbitrary number of indexes, and actual variables used as FORALL
+ indexes.
+
+2003-05-07 Kejia Zhao <kejia_zh@yahoo.com.cn>
+
+ * execute/der_point.f90: DERIVED type with components point to the
+ DERIVED type itself, and two DERIVED type with components point to
+ each other.
+
+2003-03-16 Paul Brook <paul@nowt.org>
+
+ * execute/arrayarg.f90: Assumed shape dummy arrays aren't legal when
+ using an implicit interface.
+ * execute/arraysave.f90: Ditto.
+ * execute/bounds.f90: Ditto.
+ * lib/f95-torture.exp (TORTURE_OPTIONS): Check f77 arrays.
+
+2003-03-15 Paul Brook <paul@nowt.org>
+
+ * execute/elemental.f90: Test expressions inside elemental functions.
+
+2003-03-14 Paul Brook <paul@nowt.org>
+
+ * lib/f95-torture.exp (TORTURE_OPTIONS): Check different array
+ repacking strategies.
+
+2003-02-15 Paul Brook <paul@nowt.org>
+
+ * execute/der_init.f90: Add tests for non-constant constructors.
+
+2003-02-08 Paul Brook <paul@nowt.org>
+
+ * execute/constructor.f90: Additional tests for non-constant
+ constructors with unexpanded implicit do loops.
+
+2003-02-06 Paul Brook <paul@nowt.org>
+
+ * execute/der_type.f90: Add extra tests for initializers and passing
+ components as arguments.
+
+2003-02-01 Paul Brook <paul@nowr.org>
+
+ * execute/elemental.f90: Test intrinsic elemental conversion
+ routines.
+
+2003-01-28 Paul Brook <paul@nowt.org>
+
+ * compile/mystery_proc.f90: New testcase.
+
+2003-01-27 Paul Brook <paul@nowt.org>
+
+ * execute/intrinsic_minmax.f90: Add a couple more variations.
+
+2003-01-26 Paul Brook <paul@nowt.org>
+
+ * execute/contained.f90: New testcase.
+ * execute/intrinsic_present.f90: New testcase.
+
+2003-01-22 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * compile/bergervoet2.f90, compile/ambig.f90,
+ compile/actual.f90, execute/integer_select.f90:
+ New testcases.
+ * execute/function_module_1.f90: Fix syntax error.
+ * execute/retarray.f90: Fix another syntax error.
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/actual.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/actual.f90
new file mode 100644
index 00000000000..871c0814900
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/actual.f90
@@ -0,0 +1,38 @@
+module modull
+
+contains
+
+function fun( a )
+ real, intent(in) :: a
+ real :: fun
+ fun = a
+end function fun
+
+end module modull
+
+
+
+program t5
+
+use modull
+
+real :: a, b
+
+b = foo( fun, a )
+
+contains
+
+function foo( f, a )
+ real, intent(in) :: a
+ interface
+ function f( x )
+ real, intent(in) :: x
+ real :: f
+ end function f
+ end interface
+ real :: foo
+
+ foo = f( a )
+end function foo
+
+end program t5
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/allocate.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/allocate.f90
new file mode 100644
index 00000000000..f5cce41f71e
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/allocate.f90
@@ -0,0 +1,26 @@
+! Snippet to test various allocate statements
+
+program test_allocate
+ implicit none
+ type t
+ integer i
+ real r
+ end type
+ type pt
+ integer, pointer :: p
+ end type
+ integer, allocatable, dimension(:, :) :: a
+ type (t), pointer, dimension(:) :: b
+ type (pt), pointer :: c
+ integer, pointer:: p
+ integer n
+
+ n = 10
+ allocate (a(1:10, 4))
+ allocate (a(5:n, n:14))
+ allocate (a(6, 8))
+ allocate (b(n))
+ allocate (c)
+ allocate (c%p)
+ allocate (p)
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/ambig.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/ambig.f90
new file mode 100644
index 00000000000..3e5e07dadb0
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/ambig.f90
@@ -0,0 +1,26 @@
+MODULE TYPESP
+ TYPE DMT
+ REAL(KIND(1.D0)), POINTER :: ASPK(:)
+ END TYPE DMT
+END MODULE TYPESP
+
+MODULE TCNST
+ Integer, Parameter :: DIM_TEMP_BUFFER=10000
+ Real(Kind(1.d0)), Parameter :: COLROW_=0.33,PERCENT=0.7
+end MODULE TCNST
+
+
+Subroutine DOWORK(A)
+ Use TYPESP
+ Use TCNST
+ Type(DMT), intent (inout) :: A
+ Real(Kind(1.d0)),Pointer :: ASPK(:)
+ Integer :: ISIZE, IDIM
+
+ ISIZE=DIM_TEMP_BUFFER
+
+ Allocate(ASPK(ISIZE),STAT=INFO)
+ IDIM = MIN(ISIZE,SIZE(A%ASPK))
+ ASPK(1:IDIM) = A%ASPK(1:IDIM)
+ Return
+End Subroutine DOWORK
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/arrayio.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/arrayio.f90
new file mode 100644
index 00000000000..1eec0bb59ce
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/arrayio.f90
@@ -0,0 +1,12 @@
+! Program to test array IO. Should print the numbers 1-20 in order
+program arrayio
+ implicit none
+ integer, dimension(5, 4) :: a
+ integer i, j
+
+ do j=1,4
+ a(:, j) = (/ (i + (j - 1) * 5, i=1,5) /)
+ end do
+
+ write (*) a
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/bergervoet2.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/bergervoet2.f90
new file mode 100644
index 00000000000..eef33e425c2
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/bergervoet2.f90
@@ -0,0 +1,5 @@
+ function testi() result(res)
+ integer :: res
+ res = 0
+ end function testi
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/compile.exp b/gcc/testsuite/gfortran.fortran-torture/compile/compile.exp
new file mode 100644
index 00000000000..81e1c1cebee
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/compile.exp
@@ -0,0 +1,55 @@
+# Expect driver script for GCC Regression Tests
+# Copyright (C) 2003 Free Software Foundation
+#
+# This file 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 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# These tests come from many different contributors.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+# load support procs
+load_lib fortran-torture.exp
+
+foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.f]] {
+ # If we're only testing specific files and this isn't one of them, skip it.
+ if ![runtest_file_p $runtests $testcase] then {
+ continue
+ }
+ fortran-torture $testcase
+}
+
+foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.F]] {
+ if ![runtest_file_p $runtests $testcase] then {
+ continue
+ }
+ fortran-torture $testcase
+}
+
+foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.f90]] {
+ if ![runtest_file_p $runtests $testcase] then {
+ continue
+ }
+ fortran-torture $testcase
+}
+
+foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.f95]] {
+ if ![runtest_file_p $runtests $testcase] then {
+ continue
+ }
+ fortran-torture $testcase
+}
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/contained_1.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/contained_1.f90
new file mode 100644
index 00000000000..60f31092e73
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/contained_1.f90
@@ -0,0 +1,15 @@
+! Obscure failure that disappeared when the parameter was removed.
+! Works OK now.
+module mymod
+implicit none
+contains
+ subroutine test(i)
+ implicit none
+ integer i
+ end subroutine
+end module mymod
+
+program error
+ use mymod
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/contained_2.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/contained_2.f90
new file mode 100644
index 00000000000..76ef6c62871
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/contained_2.f90
@@ -0,0 +1,11 @@
+! Arrays declared in parent but used in the child.
+program error
+ implicit none
+ integer, dimension (10) :: a
+contains
+ subroutine test()
+ implicit none
+ a(1) = 0
+ end subroutine
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/contained_3.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/contained_3.f90
new file mode 100644
index 00000000000..da5e8475c54
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/contained_3.f90
@@ -0,0 +1,12 @@
+! Program to check using parent variables in more than one contained function
+program contained_3
+ implicit none
+ integer var
+contains
+ subroutine one
+ var = 1
+ end subroutine
+ subroutine two
+ var = 2
+ end subroutine
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/contained_4.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/contained_4.f90
new file mode 100644
index 00000000000..233dab878fd
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/contained_4.f90
@@ -0,0 +1,35 @@
+! Check contained functions with the same name.
+module contained_4
+
+contains
+
+ subroutine foo1()
+ call bar()
+ contains
+ subroutine bar()
+ end subroutine bar
+ end subroutine foo1
+
+ subroutine foo2()
+ call bar()
+ contains
+ subroutine bar()
+ end subroutine bar
+ end subroutine foo2
+
+end module contained_4
+
+subroutine foo1()
+call bar()
+contains
+ subroutine bar()
+ end subroutine bar
+end subroutine
+
+subroutine foo2()
+ call bar()
+contains
+ subroutine bar()
+ end subroutine bar
+end subroutine foo2
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/contained_5.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/contained_5.f90
new file mode 100644
index 00000000000..94946f76b0d
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/contained_5.f90
@@ -0,0 +1,10 @@
+! Function returning an array continaed in a module. Caused problems 'cos
+! we tried to add the dummy return vars to the parent scope.
+
+Module contained_5
+contains
+FUNCTION test ()
+ REAL, DIMENSION (1) :: test
+ test(1)=0.0
+END FUNCTION
+end module
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/convert.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/convert.f90
new file mode 100644
index 00000000000..777cd132c85
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/convert.f90
@@ -0,0 +1,37 @@
+! Program to test conversion. Does not actualy test the generated code
+program convert
+ implicit none
+ integer(kind=4) i
+ integer(kind=8) m
+ real(kind=4) r
+ real(kind=8) q
+ complex(kind=4) c
+ complex(kind=8) z
+
+ ! each of these should generate a single intrinsic conversion expression
+ i = int(i)
+ i = int(m)
+ i = int(r)
+ i = int(q)
+ i = int(c)
+ i = int(z)
+ m = int(i, kind=8)
+ m = int(m, kind=8)
+ m = int(r, kind=8)
+ m = int(q, kind=8)
+ m = int(c, kind=8)
+ m = int(z, kind=8)
+ r = real(i)
+ r = real(m)
+ r = real(r)
+ r = real(q)
+ r = real(c)
+ r = real(z, kind=4)
+ q = real(i, kind=8)
+ q = real(m, kind=8)
+ q = real(r, kind=8)
+ q = real(q, kind=8)
+ q = real(c, kind=8)
+ ! Note real(<complex>) returns the type kind of the argument.
+ q = real(z)
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/do_1.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/do_1.f90
new file mode 100644
index 00000000000..396592c39c7
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/do_1.f90
@@ -0,0 +1,28 @@
+! test various forms of the DO statement
+! inspired by PR14066
+LOGICAL L
+DO i=1,10
+END DO
+DO 10 i=1,20
+ DO 20,j=1,10,2
+20 CONTINUE
+10 END DO
+L = .TRUE.
+DO WHILE(L)
+ L = .FALSE.
+END DO
+DO 50 WHILE(.NOT.L)
+ L = .TRUE.
+50 CONTINUE
+DO
+ DO 30
+ DO 40
+40 CONTINUE
+30 END DO
+END DO
+outer: DO i=1,20
+ inner: DO,j=i,30
+ IF (j.EQ.2*i) CYCLE outer
+ END DO inner
+END DO outer
+END
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/dummyfn.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/dummyfn.f90
new file mode 100644
index 00000000000..d54f64899f3
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/dummyfn.f90
@@ -0,0 +1,13 @@
+! Program to test array valued dummy functions
+SUBROUTINE dummyfn(deriv)
+ implicit none
+ INTERFACE
+ FUNCTION deriv()
+ REAL :: deriv(4)
+ END FUNCTION deriv
+ END INTERFACE
+
+ REAL :: dx(4)
+
+ dx = deriv()
+END SUBROUTINE
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/empty_interface_1.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/empty_interface_1.f90
new file mode 100644
index 00000000000..d9089542394
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/empty_interface_1.f90
@@ -0,0 +1,4 @@
+! Program to test empty interfaces PR15051
+INTERFACE leer
+END INTERFACE
+END
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/emptyif.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/emptyif.f90
new file mode 100644
index 00000000000..bd12d502ef8
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/emptyif.f90
@@ -0,0 +1,42 @@
+! Program to test empty IF statements
+program emptyif
+ implicit none
+ logical c
+ logical d
+
+ if (c) then
+ c = .true.
+ end if
+
+ if (c) then
+ else
+ c = .true.
+ end if
+
+ if (c) then
+ c = .true.
+ else
+ end if
+
+ if (c) then
+ c = .true.
+ elseif (d) then
+ c = .true.
+ else
+ end if
+
+ if (c) then
+ c = .true.
+ elseif (d) then
+ else
+ c = .true.
+ end if
+
+ if (c) then
+ elseif (d) then
+ c = .true.
+ else
+ c = .true.
+ end if
+
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/fnresvar.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/fnresvar.f90
new file mode 100644
index 00000000000..fab9aa665a4
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/fnresvar.f90
@@ -0,0 +1,5 @@
+! Explicit function rsult variables
+function fnresvar() result (r)
+ integer r
+ r = 0
+end function
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/gen_interf.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/gen_interf.f90
new file mode 100644
index 00000000000..eb493411b34
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/gen_interf.f90
@@ -0,0 +1,19 @@
+! Program to test generic interfaces.
+program gen_interf
+ implicit none
+ interface gen
+ function ifn (a)
+ integer :: a, ifn
+ end function
+ end interface
+ interface gsub
+ subroutine igsub (a)
+ integer a
+ end subroutine
+ end interface
+
+ integer i
+
+ call gsub (i)
+ i = gen(i)
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/implicit.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/implicit.f90
new file mode 100644
index 00000000000..296821e8983
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/implicit.f90
@@ -0,0 +1,8 @@
+implicit integer(a), logical(b-c), real(d-y), integer(z)
+a = 1_4
+b = .true.
+c = b
+d = 1.0e2
+y = d
+z = a
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/io_end.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/io_end.f90
new file mode 100644
index 00000000000..f67ae57ae8e
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/io_end.f90
@@ -0,0 +1,9 @@
+! Check we can cope with end labels in IO statements
+program m
+ implicit none
+ integer i
+ do while (.true.)
+ read(*, *, end = 1) i
+ end do
+1 continue
+end program m
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/module_common.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/module_common.f90
new file mode 100644
index 00000000000..f727881d75b
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/module_common.f90
@@ -0,0 +1,10 @@
+! We were incorrectly trying to create a variable for the common block itself,
+! in addition to the variables it contains.
+module FOO
+ implicit none
+ integer I
+ common /C/I
+contains
+ subroutine BAR
+ end subroutine BAR
+end module FOO
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/module_expr.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/module_expr.f90
new file mode 100644
index 00000000000..a1ca83a9a21
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/module_expr.f90
@@ -0,0 +1,18 @@
+! This uncovered a bug in the reading/writing of expressions.
+module module_expr_1
+ integer a
+end module
+
+module module_expr_2
+ use module_expr_1
+contains
+
+subroutine myproc (p)
+ integer, dimension (a) :: p
+end subroutine
+end module
+
+program module_expr
+ use module_expr_1
+ use module_expr_2
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/module_proc.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/module_proc.f90
new file mode 100644
index 00000000000..17386d4b8e0
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/module_proc.f90
@@ -0,0 +1,14 @@
+! Check module procedures with arguments
+module module_proc
+contains
+subroutine s(p)
+ integer p
+end subroutine
+end module
+
+program test
+use module_proc
+integer i
+call s(i)
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/module_result.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/module_result.f90
new file mode 100644
index 00000000000..105073596f5
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/module_result.f90
@@ -0,0 +1,9 @@
+! Result variables in module procedures
+module module_result
+ implicit none
+contains
+function test () result (res)
+ integer res
+ res = 0
+end function
+end module
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/named_args.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/named_args.f90
new file mode 100644
index 00000000000..1e0b4a6733c
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/named_args.f90
@@ -0,0 +1,6 @@
+! This caused problems because we created a symbol for P while
+! trying to parse the argument list as a substring reference.
+program named_args
+ implicit none
+ integer, parameter :: realdp = selected_real_kind(p=8,r=30)
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/noncontinuation_1.f b/gcc/testsuite/gfortran.fortran-torture/compile/noncontinuation_1.f
new file mode 100644
index 00000000000..5921f014d22
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/noncontinuation_1.f
@@ -0,0 +1,3 @@
+! verifies that 0 in column six doesn't start a continuation line
+!234567890
+ 0 END
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/parameter_1.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/parameter_1.f90
new file mode 100644
index 00000000000..8921bcddcad
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/parameter_1.f90
@@ -0,0 +1,7 @@
+! legal
+integer, parameter :: j = huge(j)
+integer i
+
+ if (j /= huge(i)) call abort
+end
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/parameter_2.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/parameter_2.f90
new file mode 100644
index 00000000000..e480751f19d
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/parameter_2.f90
@@ -0,0 +1,23 @@
+! Program to test initialization expressions involving subobjects
+program parameter_2
+ implicit none
+ type :: SS
+ integer :: I
+ integer :: J
+ end type SS
+ type :: TT
+ integer :: N
+ type (SS), dimension(2) :: o
+ end type
+
+ type (SS), parameter :: s = SS (1, 2)
+ type (TT), parameter :: t = TT(42, (/ SS(3, 4), SS(8, 9) /))
+
+ integer, parameter :: a(2) = (/5, 10/)
+ integer, parameter :: d1 = s%i
+ integer, parameter :: d2 = a(2)
+ integer, parameter :: d4 = t%o(2)%j
+
+ integer q1, q2, q3, q4
+ common /c1/q1(d1), q2(d2), q3(a(1)), q4(d4) ! legal
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/shape_reshape.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/shape_reshape.f90
new file mode 100644
index 00000000000..a8e632b1f4b
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/shape_reshape.f90
@@ -0,0 +1,8 @@
+! This checks that the shape of the SHAPE intrinsic is known.
+PROGRAM shape_reshape
+ INTEGER, ALLOCATABLE :: I(:,:)
+ ALLOCATE(I(2,2))
+ I = RESHAPE((/1,2,3,4/),SHAPE=SHAPE(I))
+ DEALLOCATE(I)
+END PROGRAM
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/stoppause.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/stoppause.f90
new file mode 100644
index 00000000000..9a936f09c3d
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/stoppause.f90
@@ -0,0 +1,10 @@
+! Program to check the STOP and PAUSE intrinsics
+program stoppause
+
+ pause
+ pause 1
+ pause 'Hello world'
+ stop
+ stop 42
+ stop 'Go away'
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/strparm_1.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/strparm_1.f90
new file mode 100644
index 00000000000..9625b10fed2
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/strparm_1.f90
@@ -0,0 +1,6 @@
+! Check known length string parameters
+subroutine test (s)
+ character(len=80) :: s
+
+ s = "Hello World"
+end subroutine
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/write.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/write.f90
new file mode 100644
index 00000000000..50b83cc6a12
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/write.f90
@@ -0,0 +1,5 @@
+! Program to test simple IO
+program testwrite
+ write (*) 1
+ write (*) "Hello World"
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/a_edit_1.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/a_edit_1.f90
new file mode 100644
index 00000000000..55a6f3cdf2c
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/a_edit_1.f90
@@ -0,0 +1,17 @@
+! pr 15113
+! Ax edit descriptor x larger than destination
+! A edit descriptor with no field width segfaults
+ character*16 C
+ character*4 D
+ data C / 'ABCDEFGHIJKLMNOP'/
+ read(C,'(A7)')D
+ if (D.NE.'DEFG') then
+! print*,D
+ call abort
+ endif
+ read(C,'(A)')D
+ if (D.NE.'ABCD') then
+! print*,D
+ call abort
+ endif
+ end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/adjustr.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/adjustr.f90
new file mode 100644
index 00000000000..8264ba7f811
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/adjustr.f90
@@ -0,0 +1,46 @@
+! pr 15294 - [gfortran] ADJUSTR intrinsic accesses corrupted pointer
+!
+ program test_adjustr
+ implicit none
+ integer test_cases
+ parameter (test_cases=13)
+ integer i
+ character(len=10) s1(test_cases), s2(test_cases)
+ s1(1)='A'
+ s2(1)=' A'
+ s1(2)='AB'
+ s2(2)=' AB'
+ s1(3)='ABC'
+ s2(3)=' ABC'
+ s1(4)='ABCD'
+ s2(4)=' ABCD'
+ s1(5)='ABCDE'
+ s2(5)=' ABCDE'
+ s1(6)='ABCDEF'
+ s2(6)=' ABCDEF'
+ s1(7)='ABCDEFG'
+ s2(7)=' ABCDEFG'
+ s1(8)='ABCDEFGH'
+ s2(8)=' ABCDEFGH'
+ s1(9)='ABCDEFGHI'
+ s2(9)=' ABCDEFGHI'
+ s1(10)='ABCDEFGHIJ'
+ s2(10)='ABCDEFGHIJ'
+ s1(11)=''
+ s2(11)=''
+ s1(12)=' '
+ s2(12)=' '
+ s1(13)=' '
+ s2(13)=' '
+ do I = 1,test_cases
+ print*,i
+ print*, 's1 = "', s1(i), '"'
+ print*, 's2 = "', s2(i), '"'
+ print*, 'adjustr(s1) = "', adjustr(s1(i)), '"'
+ if (adjustr(s1(i)).ne.s2(i)) then
+ print*,'fail'
+ call abort
+ endif
+ enddo
+
+ end program test_adjustr
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/allocate.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/allocate.f90
new file mode 100644
index 00000000000..61f717da7bc
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/allocate.f90
@@ -0,0 +1,38 @@
+! Test allocation and deallocation.
+program test_allocate
+ call t1 (.true.)
+ call t1 (.false.)
+ call t2
+contains
+
+! Implicit deallocation and saved aloocated variables.
+subroutine t1(first)
+ real, allocatable, save :: p(:)
+ real, allocatable :: q(:)
+ logical first
+
+ if (first) then
+ if (allocated (p)) call abort ()
+ else
+ if (.not. allocated (p)) call abort ()
+ end if
+ if (allocated (q)) call abort ()
+
+ if (first) then
+ allocate (p(5))
+ else
+ deallocate (p)
+ end if
+ allocate (q(5))
+end subroutine
+
+! Explicit deallocation.
+subroutine t2()
+ real, allocatable :: r(:)
+
+ allocate (r(5))
+ pr = 1.0
+ deallocate (r)
+ if (allocated(r)) call abort ()
+end subroutine
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/alternate_return.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/alternate_return.f90
new file mode 100644
index 00000000000..5c77844e6da
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/alternate_return.f90
@@ -0,0 +1,18 @@
+program alt_return
+ implicit none
+
+ call myproc (1, *10, 42)
+20 continue
+ call abort ()
+10 continue
+ call myproc(2, *20, 42)
+ call myproc(3, *20, 42)
+contains
+subroutine myproc(n, *, i)
+ integer n, i
+ if (i .ne. 42) call abort ()
+ if (n .eq. 1) return 1
+ if (n .eq. 2) return
+end subroutine
+end program alt_return
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/args.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/args.f90
new file mode 100644
index 00000000000..263c795ed70
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/args.f90
@@ -0,0 +1,22 @@
+! Program to test procudure args
+subroutine test (a, b)
+ integer, intent (IN) :: a
+ integer, intent (OUT) :: b
+
+ if (a .ne. 42) call abort
+ b = 43
+end subroutine
+
+program args
+ implicit none
+ external test
+ integer i, j
+
+ i = 42
+ j = 0
+ CALL test (i, j)
+ if (i .ne. 42) call abort
+ if (j .ne. 43) call abort
+ i = 41
+ CALL test (i + 1, j)
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/arithmeticif.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/arithmeticif.f90
new file mode 100644
index 00000000000..d06167e6814
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/arithmeticif.f90
@@ -0,0 +1,25 @@
+! Program to test the arithmetic if statement
+function testif (a)
+ implicit none
+ integer a, b, testif
+
+ if (a) 1, 2, 3
+ b = 2
+ goto 4
+ 1 b = -1
+ goto 4
+ 2 b = 0
+ goto 4
+ 3 b = 1
+ 4 testif = b
+end function
+
+program testwrite
+ implicit none
+ integer i
+ integer testif
+
+ if (testif (-10) .ne. -1) call abort
+ if (testif (0) .ne. 0) call abort
+ if (testif (10) .ne. 1) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/arrayarg.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/arrayarg.f90
new file mode 100644
index 00000000000..b588d050b69
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/arrayarg.f90
@@ -0,0 +1,145 @@
+! Program to test arrays
+! The program outputs a series of numbers.
+! Two digit numbers beginning with 0, 1, 2 or 3 is a normal.
+! Three digit numbers starting with 4 indicate an error.
+! Using 1D arrays isn't a sufficient test, the first dimension is often
+! handled specially.
+
+! Fixed size parameter
+subroutine f1 (a)
+ implicit none
+ integer, dimension (5, 8) :: a
+
+ if (a(1, 1) .ne. 42) call abort
+
+ if (a(5, 8) .ne. 43) call abort
+end subroutine
+
+
+program testprog
+ implicit none
+ integer, dimension(3:7, 4:11) :: a
+ a(:,:) = 0
+ a(3, 4) = 42
+ a(7, 11) = 43
+ call test(a)
+contains
+subroutine test (parm)
+ implicit none
+ ! parameter
+ integer, dimension(2:, 3:) :: parm
+ ! Known size arry
+ integer, dimension(5, 8) :: a
+ ! Known size array with different bounds
+ integer, dimension(4:8, 3:10) :: b
+ ! Unknown size arrays
+ integer, dimension(:, :), allocatable :: c, d, e
+ ! Vectors
+ integer, dimension(5) :: v1
+ integer, dimension(10, 10) :: v2
+ integer n
+ external f1
+
+ ! Same size
+ allocate (c(5,8))
+ ! Same size, different bounds
+ allocate (d(11:15, 12:19))
+ ! A larger array
+ allocate (e(15, 24))
+ a(:,:) = 0
+ b(:,:) = 0
+ c(:,:) = 0
+ d(:,:) = 0
+ a(1,1) = 42
+ b(4, 3) = 42
+ c(1,1) = 42
+ d(11,12) = 42
+ a(5, 8) = 43
+ b(8, 10) = 43
+ c(5, 8) = 43
+ d(15, 19) = 43
+
+ v2(:, :) = 0
+ do n=1,5
+ v1(n) = n
+ end do
+
+ v2 (3, 1::2) = v1 (5:1:-1)
+ v1 = v1 + 1
+
+ if (v1(1) .ne. 2) call abort
+ if (v2(3, 3) .ne. 4) call abort
+
+ ! Passing whole arrays
+ call f1 (a)
+ call f1 (b)
+ call f1 (c)
+ call f2 (a)
+ call f2 (b)
+ call f2 (c)
+ ! passing expressions
+ a(1,1) = 41
+ a(5,8) = 42
+ call f1(a+1)
+ call f2(a+1)
+ a(1,1) = 42
+ a(5,8) = 43
+ call f1 ((a + b) / 2)
+ call f2 ((a + b) / 2)
+ ! Passing whole arrays as sections
+ call f1 (a(:,:))
+ call f1 (b(:,:))
+ call f1 (c(:,:))
+ call f2 (a(:,:))
+ call f2 (b(:,:))
+ call f2 (c(:,:))
+ ! Passing sections
+ e(:,:) = 0
+ e(2, 3) = 42
+ e(6, 10) = 43
+ n = 3
+ call f1 (e(2:6, n:10))
+ call f2 (e(2:6, n:10))
+ ! Vector subscripts
+ ! v1= index plus one, v2(3, ::2) = reverse of index
+ e(:,:) = 0
+ e(2, 3) = 42
+ e(6, 10) = 43
+ call f1 (e(v1, n:10))
+ call f2 (e(v1, n:10))
+ ! Double vector subscript
+ e(:,:) = 0
+ e(6, 3) = 42
+ e(2, 10) = 43
+ !These are not resolved properly
+ call f1 (e(v1(v2(3, ::2)), n:10))
+ call f2 (e(v1(v2(3, ::2)), n:10))
+ ! non-contiguous sections
+ e(:,:) = 0
+ e(1, 1) = 42
+ e(13, 22) = 43
+ n = 3
+ call f1 (e(1:15:3, 1:24:3))
+ call f2 (e(::3, ::n))
+ ! non-contiguous sections with bounds
+ e(:,:) = 0
+ e(3, 4) = 42
+ e(11, 18) = 43
+ n = 19
+ call f1 (e(3:11:2, 4:n:2))
+ call f2 (e(3:11:2, 4:n:2))
+
+ ! Passing a dummy variable
+ call f1 (parm)
+ call f2 (parm)
+end subroutine
+! Assumed shape parameter
+subroutine f2 (a)
+ integer, dimension (1:, 1:) :: a
+
+ if (a(1, 1) .ne. 42) call abort
+
+ if (a(5, 8) .ne. 43) call abort
+end subroutine
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/arrayarg2.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/arrayarg2.f90
new file mode 100644
index 00000000000..9cb5b613d64
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/arrayarg2.f90
@@ -0,0 +1,21 @@
+! Program to test array arguments which depend on other array arguments
+program arrayarg2
+ integer, dimension(5) :: a, b
+
+ a = (/1, 2, 3, 4, 5/)
+ b = (/2, 3, 4, 5, 6/)
+
+ call test (a, b)
+
+ if (any (b .ne. (/4, 7, 10, 13, 16/))) call abort
+contains
+subroutine test (x1, x2)
+ implicit none
+ integer, dimension(1:), intent(in) :: x1
+ integer, dimension(1:), intent(inout) :: x2
+ integer, dimension(1:size(x1)) :: x3
+
+ x3 = x1 * 2
+ x2 = x2 + x3
+end subroutine test
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/arraysave.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/arraysave.f90
new file mode 100644
index 00000000000..94b234bd512
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/arraysave.f90
@@ -0,0 +1,24 @@
+! Program to test arrays with the save attribute
+program testarray
+ implicit none
+ integer, save, dimension (6, 5) :: a, b
+
+ a = 0
+ a(1, 1) = 42
+ a(6, 5) = 43
+ b(:,1:5) = a
+
+ call fn (a)
+contains
+subroutine fn (a)
+ implicit none
+ integer, dimension(1:, 1:) :: a
+ integer, dimension(2) :: b
+
+ b = ubound (a)
+ if (any (b .ne. (/6, 5/))) call abort
+ if (a(1, 1) .ne. 42) call abort
+ if (a(6, 5) .ne. 43) call abort
+end subroutine
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/assumed_size.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/assumed_size.f90
new file mode 100644
index 00000000000..b2c4657c647
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/assumed_size.f90
@@ -0,0 +1,39 @@
+! Program to test assumed size arrays
+subroutine test2(p)
+ integer, dimension(2, *) :: p
+
+ if (any (p(:, 1:3) .ne. reshape((/1, 2, 4, 5, 7, 8/), (/2, 3/)))) &
+ call abort ()
+end subroutine
+
+program assumed_size
+ integer, dimension (3, 3) :: a
+ external test2
+
+ a = reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9/), (/3, 3/))
+
+ call test1(a, (/1, 2, 3, 4, 5, 6/))
+ if (a(1,1) .ne. 0) call abort
+ a(1, 1) = 1
+ call test1(a(1:2, :), (/1, 2, 4, 5, 7, 8/))
+ if (a(1,1) .ne. 0) call abort
+ a(1, 1) = 1
+ call test1(a(3:1:-1, :), (/3, 2, 1, 6, 5, 4/))
+ if (a(3,1) .ne. 0) call abort
+ a(3, 1) = 3
+ call test1(a(:, 2:3), (/4, 5, 6, 7, 8, 9/))
+ if (a(1, 2) .ne. 0) call abort
+ a(1, 2) = 4
+
+ call test2(a(1:2, :))
+ call test2((/1, 2, 4, 5, 7, 8/))
+contains
+subroutine test1(p, q)
+ integer, dimension(*) :: p
+ integer, dimension(1:) :: q
+
+ if (any (p(1:size(q)) .ne. q)) call abort ()
+ p(1) = 0
+end subroutine
+
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/bounds.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/bounds.f90
new file mode 100644
index 00000000000..b1ad840738c
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/bounds.f90
@@ -0,0 +1,35 @@
+! Program to test the upper and lower bound intrinsics
+program testbounds
+ implicit none
+ real, dimension(:, :), allocatable :: a
+ integer, dimension(5) :: j
+ integer i
+
+ allocate (a(3:8, 6:7))
+
+ ! With one parameter
+ j = 0;
+ j(3:4) = ubound(a)
+ if (j(3) .ne. 8) call abort
+ if (j(4) .ne. 7) call abort
+
+ ! With two parameters, assigning to an array
+ j = lbound(a, 1)
+ if ((j(1) .ne. 3) .or. (j(5) .ne. 3)) call abort
+
+ ! With a variable second parameter
+ i = 2
+ i = lbound(a, i)
+ if (i .ne. 6) call abort
+
+ call test(a)
+contains
+subroutine test (a)
+ real, dimension (1:, 1:) :: a
+ integer i
+
+ i = 2
+ if ((ubound(a, 1) .ne. 6) .or. (ubound(a, i) .ne. 2)) call abort
+end subroutine
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/character_select_1.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/character_select_1.f90
new file mode 100644
index 00000000000..c42cea4fc21
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/character_select_1.f90
@@ -0,0 +1,12 @@
+CHARACTER(LEN=6) :: C = "STEVEN"
+
+SELECT CASE (C)
+ CASE ("AAA":"EEE")
+ CALL abort
+ CASE ("R":"T")
+ CONTINUE
+ CASE DEFAULT
+ CALL abort
+END SELECT
+END
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/cmplx.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/cmplx.f90
new file mode 100644
index 00000000000..8e434c03342
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/cmplx.f90
@@ -0,0 +1,45 @@
+! Test complex munbers
+program testcmplx
+ implicit none
+ complex(kind=4) c, d
+ complex(kind=8) z
+ real(kind=4) x, y
+ real(kind=8) q
+
+ ! cmplx intrinsic
+ x = 3
+ y = 4
+ c = cmplx(x,y)
+ if (c .ne. (3.0, 4.0)) call abort
+ x = 4
+ y = 3
+ z = cmplx(x, y, 8)
+ if (z .ne. (4.0, 3.0)) call abort
+ z = c
+ if (z .ne. (3.0, 4.0)) call abort
+
+ ! dcmplx intrinsic
+ x = 3
+ y = 4
+ z = dcmplx (x, y)
+ if (z .ne. (3.0, 4.0)) call abort
+
+ ! conjucates and aimag
+ c = (1.0, 2.0)
+ c = conjg (c)
+ x = aimag (c)
+ if (abs (c - (1.0, -2.0)) .gt. 0.001) call abort
+ if (x .ne. -2.0) call abort
+ z = (2.0, 1.0)
+ z = conjg (z)
+ q = aimag (z)
+ if (z .ne. (2.0, -1.0)) call abort
+ if (q .ne. -1.0) call abort
+
+ ! addition, subtraction and multiplication
+ c = (1, 3)
+ d = (5, 2)
+ if (c + d .ne. ( 6, 5)) call abort
+ if (c - d .ne. (-4, 1)) call abort
+ if (c * d .ne. (-1, 17)) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/common.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/common.f90
new file mode 100644
index 00000000000..2ea1788eb54
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/common.f90
@@ -0,0 +1,53 @@
+! Program to test COMMON and EQUIVALENCE.
+program common
+ real (kind=8) a(8)
+ real (kind=8) b(5), c(5)
+ common /com1/b,c
+ equivalence (a(1), b(2))
+ b = 100
+ c = 200
+ call common_pass
+ call common_par (a, b,c)
+ call global_equiv
+ call local_equiv
+end
+
+! Use common block to pass values
+subroutine common_pass
+ real (kind=8) a(8)
+ real (kind=8) b(5), c(5)
+ common /com1/b,c
+ equivalence (a(1), b(2))
+ if (any (a .ne. (/100,100,100,100,200,200,200,200/))) call abort
+end subroutine
+
+! Common variables as argument
+subroutine common_par (a, b, c)
+ real (kind=8) a(8), b(5), c(5)
+ if (any (a .ne. (/100,100,100,100,200,200,200,200/))) call abort
+ if (any (b .ne. (/100,100,100,100,100/))) call abort
+ if (any (c .ne. (/200,200,200,200,200/))) call abort
+end subroutine
+
+! Global equivalence
+subroutine global_equiv
+ real (kind=8) a(8), b(5), c(5), x(8), y(4), z(4)
+ common /com2/b, c, y, z
+ equivalence (a(1), b(2))
+ equivalence (x(4), y(1))
+ b = 100
+ c = 200
+ y = 300
+ z = 400
+ if (any (a .ne. (/100,100,100,100,200,200,200,200/))) call abort
+ if (any (x .ne. (/200,200,200,300,300,300,300,400/))) call abort
+end
+
+! Local equivalence
+subroutine local_equiv
+ real (kind=8) a(8), b(10)
+ equivalence (a(1), b(3))
+ b(1:5) = 100
+ b(6:10) = 200
+ if (any (a .ne. (/100,100,100,200,200,200,200,200/))) call abort
+end subroutine
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/common_size.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/common_size.f90
new file mode 100644
index 00000000000..936c41e3282
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/common_size.f90
@@ -0,0 +1,10 @@
+! The size of common 'com1' should be 80, instead of 112.
+program common_size
+ real (kind=8) a(8)
+ real (kind=8) b(5), c(5)
+ common /com1/b,c
+ equivalence (a(1), b(2))
+ b = 100
+ c = 200
+ if ((a (4) .ne. 100) .or. (a(5) .ne. 200)) call abort
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/constructor.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/constructor.f90
new file mode 100644
index 00000000000..96cb89d721c
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/constructor.f90
@@ -0,0 +1,29 @@
+! Program to test array constructors
+program constructors
+ integer, dimension (4) :: a
+ integer, dimension (3, 2) :: b
+ integer i, j, k, l, m, n
+
+ a = (/1, (i,i=2,4)/)
+ do i = 1, 4
+ if (a(i) .ne. i) call abort
+ end do
+
+ b = reshape ((/0, 1, 2, 3, 4, 5/), (/3, 2/)) + 1
+ do i=1,3
+ if (b(i, 1) .ne. i) call abort
+ if (b(i, 2) .ne. i + 3) call abort
+ end do
+
+ k = 1
+ l = 2
+ m = 3
+ n = 4
+ ! The remainder assumes constant constructors work ok.
+ a = (/n, m, l, k/)
+ if (any (a .ne. (/4, 3, 2, 1/))) call abort
+ a = (/((/i+10, 42/), i = k, l)/)
+ if (any (a .ne. (/11, 42, 12, 42/))) call abort
+ a = (/(I, I=k,l) , (J, J=m,n)/)
+ if (any (a .ne. (/1, 2, 3, 4/))) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/contained.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/contained.f90
new file mode 100644
index 00000000000..3c7117744dd
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/contained.f90
@@ -0,0 +1,16 @@
+program contained
+ implicit none
+ integer i
+
+ i = 0;
+ call testproc (40)
+ if (i .ne. 42) call abort
+contains
+ subroutine testproc (p)
+ implicit none
+ integer p
+
+ if (p .ne. 40) call abort
+ i = p + 2
+ end subroutine
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/contained2.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/contained2.f90
new file mode 100644
index 00000000000..cae94b704e1
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/contained2.f90
@@ -0,0 +1,28 @@
+! Program to check resolution of symbols with the same name
+program contained2
+ implicit none
+ integer var1
+
+ var1 = 42
+ if (f1() .ne. 1) call abort
+ call f2()
+ if (var1 .ne. 42) call abort
+contains
+
+function f1 ()
+ implicit none
+ integer f1
+ integer var1
+ integer f2
+
+ var1 = 1
+ f2 = var1
+ f1 = f2
+end function
+
+subroutine f2()
+ implicit none
+ if (f1() .ne. 1) call abort
+end subroutine
+
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/csqrt_1.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/csqrt_1.f90
new file mode 100644
index 00000000000..680449f3ede
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/csqrt_1.f90
@@ -0,0 +1,78 @@
+! PR 14396
+! These we failing on targets which do not provide the c99 complex math
+! functions.
+! Extracted from intrinsic77.f in the g77 testsuite.
+ logical fail
+ common /flags/ fail
+ fail = .false.
+ call square_root
+ if (fail) call abort
+ end
+ subroutine square_root
+ intrinsic sqrt, dsqrt, csqrt
+ real x, a
+ x = 4.0
+ a = 2.0
+ call c_r(SQRT(x),a,'SQRT(real)')
+ call c_d(SQRT(1.d0*x),1.d0*a,'SQRT(double)')
+ call c_c(SQRT((1.,0.)*x),(1.,0.)*a,'SQRT(complex)')
+ call c_d(DSQRT(1.d0*x),1.d0*a,'DSQRT(double)')
+ call c_c(CSQRT((1.,0.)*x),(1.,0.)*a,'CSQRT(complex)')
+ call p_r_r(SQRT,x,a,'SQRT')
+ call p_d_d(DSQRT,1.d0*x,1.d0*a,'DSQRT')
+ call p_c_c(CSQRT,(1.,0.)*x,(1.,0.)*a ,'CSQRT')
+ end
+ subroutine failure(label)
+! Report failure and set flag
+ character*(*) label
+ logical fail
+ common /flags/ fail
+ write(6,'(a,a,a)') 'Test ',label,' FAILED'
+ fail = .true.
+ end
+ subroutine c_r(a,b,label)
+! Check if REAL a equals b, and fail otherwise
+ real a, b
+ character*(*) label
+ if ( abs(a-b) .gt. 1.0e-5 ) then
+ call failure(label)
+ write(6,*) 'Got ',a,' expected ', b
+ end if
+ end
+ subroutine c_d(a,b,label)
+! Check if DOUBLE PRECISION a equals b, and fail otherwise
+ double precision a, b
+ character*(*) label
+ if ( abs(a-b) .gt. 1.0d-5 ) then
+ call failure(label)
+ write(6,*) 'Got ',a,' expected ', b
+ end if
+ end
+
+ subroutine c_c(a,b,label)
+! Check if COMPLEX a equals b, and fail otherwise
+ complex a, b
+ character*(*) label
+ if ( abs(a-b) .gt. 1.0e-5 ) then
+ call failure(label)
+ write(6,*) 'Got ',a,' expected ', b
+ end if
+ end
+ subroutine p_r_r(f,x,a,label)
+! Check if REAL f(x) equals a for REAL x
+ real f,x,a
+ character*(*) label
+ call c_r(f(x),a,label)
+ end
+ subroutine p_d_d(f,x,a,label)
+! Check if DOUBLE PRECISION f(x) equals a for DOUBLE PRECISION x
+ double precision f,x,a
+ character*(*) label
+ call c_d(f(x),a,label)
+ end
+ subroutine p_c_c(f,x,a,label)
+! Check if COMPLEX f(x) equals a for COMPLEX x
+ complex f,x,a
+ character*(*) label
+ call c_c(f(x),a,label)
+ end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/data.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/data.f90
new file mode 100644
index 00000000000..81954e222b5
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/data.f90
@@ -0,0 +1,72 @@
+ ! Program to test data statement
+ program data
+ call sub1()
+ call sub2()
+ end
+ subroutine sub1()
+ integer i
+ type tmp
+ integer, dimension(4)::a
+ real :: r
+ end type
+ type tmp1
+ type (tmp) t1(4)
+ integer b
+ end type
+ type (tmp1) tmp2(2)
+ ! Full array and scalar component initializer
+ data tmp2(2)%t1(2)%r, tmp2(1)%t1(3)%a, tmp2(1)%b/220,136,137,138,139,10/
+ data tmp2(2)%t1(4)%a,tmp2(2)%t1(3)%a/241,242,4*5,233,234/
+ ! implied DO
+ data (tmp2(1)%t1(2)%a(i),i=4,1,-1)/124,123,122,121/
+ ! array section
+ data tmp2(1)%t1(4)%a(4:1:-1)/144,143,142,141/
+ data tmp2(1)%t1(1)%a(1:4:2)/111,113/
+ ! array element reference
+ data tmp2(2)%t1(2)%a(3), tmp2(2)%t1(2)%a(1)/223,221/
+
+ if (any(tmp2(1)%t1(1)%a .ne. (/111,0,113,0/))) call abort
+ if (tmp2(1)%t1(1)%r .ne. 0.0) call abort
+ if (tmp2(1)%b .ne. 10) call abort
+
+ if (any(tmp2(1)%t1(2)%a .ne. (/121,122,123,124/))) call abort
+ if (tmp2(1)%t1(2)%r .ne. 0.0) call abort
+ if (tmp2(1)%b .ne. 10) call abort
+
+ if (any(tmp2(1)%t1(3)%a .ne. (/136,137,138,139/))) call abort
+ if (tmp2(1)%t1(3)%r .ne. 0.0) call abort
+ if (tmp2(1)%b .ne. 10) call abort
+
+ if (any(tmp2(1)%t1(4)%a .ne. (/141,142,143,144/))) call abort
+ if (tmp2(1)%t1(4)%r .ne. 0.0) call abort
+ if (tmp2(1)%b .ne. 10) call abort
+
+ if (any(tmp2(2)%t1(1)%a .ne. (/0,0,0,0/))) call abort
+ if (tmp2(2)%t1(1)%r .ne. 0.0) call abort
+ if (tmp2(2)%b .ne. 0) call abort
+
+ if (any(tmp2(2)%t1(2)%a .ne. (/221,0,223,0/))) call abort
+ if (tmp2(2)%t1(2)%r .ne. 220.0) call abort
+ if (tmp2(2)%b .ne. 0) call abort
+
+ if (any(tmp2(2)%t1(3)%a .ne. (/5,5,233,234/))) call abort
+ if (tmp2(2)%t1(3)%r .ne. 0.0) call abort
+ if (tmp2(2)%b .ne. 0) call abort
+
+ if (any(tmp2(2)%t1(4)%a .ne. (/241,242,5,5/))) call abort
+ if (tmp2(2)%t1(4)%r .ne. 0.0) call abort
+ if (tmp2(2)%b .ne. 0) call abort
+
+ end
+ subroutine sub2()
+ integer a(4,4), b(10)
+ integer i,j,k
+ real r,t
+ data i,j,r,k,t,b(5),b(2),((a(i,j),i=1,4,1),j=4,1,-1)/1,2,3,4,5,5,2,&
+ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16/
+ if ((i.ne.1) .and. (j.ne.2).and.(k.ne.4)) call abort
+ if ((r.ne.3.0).and.(t.ne.5.0)) call abort
+ if (any(b.ne.(/0,2,0,0,5,0,0,0,0,0/))) call abort
+ if (any(a.ne.reshape((/13,14,15,16,9,10,11,12,5,6,7,8,1,2,3,4/),(/4,4/)))) call abort
+ end
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/data_2.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/data_2.f90
new file mode 100644
index 00000000000..0aa44f6052a
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/data_2.f90
@@ -0,0 +1,17 @@
+! Check more array variants of the data statement
+program data_2
+ implicit none
+ type t
+ integer i
+ end type t
+ integer, dimension(3) :: a
+ type (t), dimension(3) :: b
+ integer, dimension(2,2) :: c
+ data a(:), b%i /1, 2, 3, 4, 5, 6/
+ data c(1, :), c(2, :) /7, 8, 9, 10/
+
+ if (any (a .ne. (/1, 2, 3/))) call abort ()
+ if (any (b%i .ne. (/4, 5, 6/))) call abort ()
+ if ((any (c(1, :) .ne. (/7, 8/))) &
+ .or. (any (c(2,:) .ne. (/9, 10/)))) call abort ()
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/dep_fails.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/dep_fails.f90
new file mode 100644
index 00000000000..c8eec5c73ac
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/dep_fails.f90
@@ -0,0 +1,50 @@
+! This gives incorrect results when compiled with
+! the intel and pgf90 compilers
+Program Strange
+
+ Implicit None
+
+ Type Link
+ Integer, Dimension(2) :: Next
+ End Type Link
+
+ Integer, Parameter :: N = 2
+ Integer, dimension (2, 4) :: results
+ Integer :: i, j
+
+ Type(Link), Dimension(:,:), Pointer :: Perm
+ Integer, Dimension(2) :: Current
+
+ Allocate (Perm(N,N))
+
+! Print*, 'Spanned by indices'
+ Do i = 1, N**2
+ Perm(mod(i-1,N)+1, (i-1)/N+1)%Next = (/ Mod(i,N) + 1, Mod(i/N+1,N)+1/)
+! Write(*,100) mod(i-1,N)+1, (i-1)/N+1, Perm(mod(i-1,N)+1, (i-1)/N+1)%Next
+! Expected output:
+! Spanned by indices
+! 1 1---> 2 2
+! 2 1---> 1 1
+! 1 2---> 2 1
+! 2 2---> 1 2
+ End Do
+
+! Print*, 'Spanned as a cycle'
+ Current = (/1,1/)
+ Do i = 1, n**2
+ results (:, i) = Perm(Current(1), Current(2))%Next
+! Write(*,100) Current, Perm(Current(1), Current(2))%Next
+! Expected output:
+! 1 1---> 2 2
+! 2 2---> 1 2
+! 1 2---> 2 1
+! 2 1---> 1 1
+ Current = Perm(Current(1), Current(2))%Next
+ End Do
+
+ if (any(results .ne. reshape ((/2,2,1,2,2,1,1,1/), (/2, 4/)))) call abort
+
+! 100 Format( 2I3, '--->', 2I3)
+ DeAllocate (Perm)
+
+End Program Strange
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/der_init.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/der_init.f90
new file mode 100644
index 00000000000..72531f9acf6
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/der_init.f90
@@ -0,0 +1,32 @@
+! Program to test derived type initializers and constructors
+program der_init
+ implicit none
+ type t
+ integer :: i
+ integer :: j = 4
+ end type
+ integer :: m, n
+
+ ! Explicit initializer
+ type (t) :: var = t(1, 2)
+ ! Type (default) initializer
+ type (t) :: var2
+ ! Initialization of arrays
+ type (t), dimension(2) :: var3
+ type (t), dimension(2) :: var4 = (/t(7, 9), t(8, 6)/)
+
+ if (var%i .ne. 1 .or. var%j .ne. 2) call abort
+ if (var2%j .ne. 4) call abort
+ var2 = t(6, 5)
+ if (var2%i .ne. 6 .or. var2%j .ne. 5) call abort
+
+ if ((var3(1)%j .ne. 4) .or. (var3(2)%j .ne. 4)) call abort
+ if ((var4(1)%i .ne. 7) .or. (var4(2)%i .ne. 8) &
+ .or. (var4(1)%j .ne. 9) .or. (var4(2)%j .ne. 6)) call abort
+
+ ! Non-constant constructor
+ n = 1
+ m = 5
+ var2 = t(n, n + m)
+ if (var2%i .ne. 1 .or. var2%j .ne. 6) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/der_init_2.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/der_init_2.f90
new file mode 100644
index 00000000000..d0448a55b67
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/der_init_2.f90
@@ -0,0 +1,15 @@
+! PR 15314
+! We were looking at the type of the initialization expression, not the type
+! of the field.
+program der_init_2
+ implicit none
+ type foo
+ integer :: a(3) = 42
+ integer :: b = 123
+ end type
+
+ type (foo) :: v
+
+ if ((v%b .ne. 123) .or. any (v%a .ne. 42)) call abort ();
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/der_io.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/der_io.f90
new file mode 100644
index 00000000000..0e9b0716654
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/der_io.f90
@@ -0,0 +1,67 @@
+! Program to test IO of derived types
+program derived_io
+ character(100) :: buf1, buf2, buf3
+
+ type xyz_type
+ integer :: x
+ character(11) :: y
+ logical :: z
+ end type xyz_type
+
+ type abcdef_type
+ integer :: a
+ logical :: b
+ type (xyz_type) :: c
+ integer :: d
+ real(4) :: e
+ character(11) :: f
+ end type abcdef_type
+
+ type (xyz_type), dimension(2) :: xyz
+ type (abcdef_type) abcdef
+
+ xyz(1)%x = 11111
+ xyz(1)%y = "hello world"
+ xyz(1)%z = .true.
+ xyz(2)%x = 0
+ xyz(2)%y = "go away"
+ xyz(2)%z = .false.
+
+ abcdef%a = 0
+ abcdef%b = .true.
+ abcdef%c%x = 111
+ abcdef%c%y = "bzz booo"
+ abcdef%c%z = .false.
+ abcdef%d = 3
+ abcdef%e = 4.0
+ abcdef%f = "kawabanga"
+
+ write (buf1, *), xyz(1)%x, xyz(1)%y, xyz(1)%z
+ ! Use function call to ensure it is only evaluated once
+ write (buf2, *), xyz(bar())
+ if (buf1.ne.buf2) call abort
+
+ write (buf1, *), abcdef
+ write (buf2, *), abcdef%a, abcdef%b, abcdef%c, abcdef%d, abcdef%e, abcdef%f
+ write (buf3, *), abcdef%a, abcdef%b, abcdef%c%x, abcdef%c%y, &
+ abcdef%c%z, abcdef%d, abcdef%e, abcdef%f
+ if (buf1.ne.buf2) call abort
+ if (buf1.ne.buf3) call abort
+
+ call foo(xyz(1))
+
+ contains
+
+ subroutine foo(t)
+ type (xyz_type) t
+ write (buf1, *), t%x, t%y, t%z
+ write (buf2, *), t
+ if (buf1.ne.buf2) call abort
+ end subroutine foo
+
+ integer function bar()
+ integer, save :: i = 1
+ bar = i
+ i = i + 1
+ end function
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/der_point.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/der_point.f90
new file mode 100644
index 00000000000..1dcb07c2108
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/der_point.f90
@@ -0,0 +1,45 @@
+! Program to test DERIVED type with components point to the DERIVED
+! type itself, and two DERIVED type with componets point to each
+! other.
+program nest_derived
+ type record
+ integer :: value
+ type(record), pointer :: rp
+ end type record
+
+ type record1
+ integer value
+ type(record2), pointer :: r1p
+ end type
+
+ type record2
+ integer value
+ type(record1), pointer :: r2p
+ end type
+
+ type(record), target :: e1, e2, e3
+ type(record1), target :: r1
+ type(record2), target :: r2
+ nullify(r1%r1p,r2%r2p,e1%rp,e2%rp,e3%rp)
+
+ r1%r1p => r2
+ r2%r2p => r1
+ e1%rp => e2
+ e2%rp => e3
+
+ r1%value = 11
+ r2%value = 22
+
+ e1%value = 33
+ e1%rp%value = 44
+ e1%rp%rp%value = 55
+
+ if (r1%r1p%value .ne. 22) call abort
+ if (r2%r2p%value .ne. 11) call abort
+ if (e1%value .ne. 33) call abort
+ if (e2%value .ne. 44) call abort
+ if (e3%value .ne. 55) call abort
+ if (r1%value .ne. 11) call abort
+ if (r2%value .ne. 22) call abort
+
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/der_type.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/der_type.f90
new file mode 100644
index 00000000000..6a2716407bf
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/der_type.f90
@@ -0,0 +1,45 @@
+! Program to test derived types
+program der_type
+ implicit none
+ type t1
+ integer, dimension (4, 5) :: a
+ integer :: s
+ end type
+
+ type my_type
+ character(20) :: c
+ type (t1), dimension (4, 3) :: ca
+ type (t1) :: r
+ end type
+
+ type init_type
+ integer :: i = 13
+ integer :: j = 14
+ end type
+
+ type (my_type) :: var
+ type (init_type) :: def_init
+ type (init_type) :: is_init = init_type (10, 11)
+ integer i;
+
+ if ((def_init%i .ne. 13) .or. (def_init%j .ne. 14)) call abort
+ if ((is_init%i .ne. 10) .or. (is_init%j .ne. 11)) call abort
+ ! Passing a component as a parameter tests getting the addr of a component
+ call test_call(def_init%i)
+ var%c = "Hello World"
+ if (var%c .ne. "Hello World") call abort
+ var%r%a(:, :) = 0
+ var%ca(:, :)%s = 0
+ var%r%a(1, 1) = 42
+ var%r%a(4, 5) = 43
+ var%ca(:, :)%s = var%r%a(:, 1:5:2)
+ if (var%ca(1, 1)%s .ne. 42) call abort
+ if (var%ca(4, 3)%s .ne. 43) call abort
+contains
+ subroutine test_call (p)
+ integer p
+
+ if (p .ne. 13) call abort
+ end subroutine
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/direct_io.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/direct_io.f90
new file mode 100644
index 00000000000..b8078f03d5e
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/direct_io.f90
@@ -0,0 +1,20 @@
+! demonstrates basic direct access using variables for REC
+! pr14872
+ OPEN(UNIT=10,ACCESS='DIRECT',RECL=128)
+ DO I = 1,10
+ WRITE(10,REC=I,ERR=10)I
+ ENDDO
+ CLOSE(10)
+ OPEN(UNIT=10,ACCESS='DIRECT',RECL=128)
+ DO I = 1,10
+ READ(10,REC=I,ERR=10)J
+ IF (J.NE.I) THEN
+! PRINT*,' READ ',J,' EXPECTED ',I
+ CALL ABORT
+ ENDIF
+ ENDDO
+ STOP
+ 10 CONTINUE
+! PRINT*,' ERR= RETURN FROM READ OR WRITE'
+ CALL ABORT
+ END
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/elemental.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/elemental.f90
new file mode 100644
index 00000000000..fcfe233df9c
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/elemental.f90
@@ -0,0 +1,32 @@
+! Program to test elemental functions.
+program test_elemental
+ implicit none
+ integer(kind = 4), dimension (2, 4) :: a
+ integer(kind = 4), dimension (2, 4) :: b
+ integer(kind = 8), dimension(2) :: c
+
+ a = reshape ((/2, 3, 4, 5, 6, 7, 8, 9/), (/2, 4/))
+ b = 0
+ b(2, :) = e_fn (a(1, :), 1)
+ if (any (b .ne. reshape ((/0, 1, 0, 3, 0, 5, 0, 7/), (/2, 4/)))) call abort
+ a = e_fn (a(:, 4:1:-1), 1 + b)
+ if (any (a .ne. reshape ((/7, 7, 5, 3, 3, -1, 1, -5/), (/2, 4/)))) call abort
+ ! This tests intrinsic elemental conversion functions.
+ c = 2 * a(1, 1)
+ if (any (c .ne. 14)) call abort
+
+ ! This triggered bug due to building ss chains in the wrong order.
+ b = 0;
+ a = a - e_fn (a, b)
+ if (any (a .ne. 0)) call abort
+
+ ! Check expressions involving constants
+ a = e_fn (b + 1, 1)
+ if (any (a .ne. 0)) call abort
+contains
+
+elemental integer function e_fn (p, q)
+ integer, intent(in) :: p, q
+ e_fn = p - q
+end function
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/empty_format.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/empty_format.f90
new file mode 100644
index 00000000000..242bee8b467
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/empty_format.f90
@@ -0,0 +1,14 @@
+! from NIST test FM406.FOR
+ CHARACTER*10 A10VK
+ A10VK = 'XXXXXXXXXX'
+ WRITE(A10VK,39110)
+39110 FORMAT()
+!
+! the empty format should fill the target of the internal
+! write with blanks.
+!
+ IF (A10VK.NE.'') THEN
+! PRINT*,A10VK
+ CALL ABORT
+ ENDIF
+ END
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/emptyif.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/emptyif.f90
new file mode 100644
index 00000000000..0c19fa57108
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/emptyif.f90
@@ -0,0 +1,20 @@
+! Test empty if statements. We Used to fail this because we folded
+! the if stmt before we finished building it.
+program emptyif
+ implicit none
+ integer i
+
+ i=1
+ if(i .le. 0) then
+ else
+ i = 2
+ endif
+ if (i .ne. 2) call abort()
+
+ if (i .eq. 0) then
+ elseif (i .eq. 2) then
+ i = 3
+ end if
+ if (i .ne. 3) call abort()
+end
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/execute.exp b/gcc/testsuite/gfortran.fortran-torture/execute/execute.exp
new file mode 100644
index 00000000000..a476ee945bf
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/execute.exp
@@ -0,0 +1,59 @@
+# Copyright (C) 2003 Free Software Foundation, Inc.
+
+# This program 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 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+# Modified and maintained by Jeffrey Wheat (cassidy@cygnus.com)
+
+#
+# These tests come from many different contributors.
+#
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+# load support procs
+load_lib fortran-torture.exp
+
+foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.f]] {
+ # If we're only testing specific files and this isn't one of them, skip it.
+ if ![runtest_file_p $runtests $testcase] then {
+ continue
+ }
+ fortran-torture-execute $testcase
+}
+
+foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.F]] {
+ if ![runtest_file_p $runtests $testcase] then {
+ continue
+ }
+ fortran-torture-execute $testcase
+}
+
+foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.f90]] {
+ if ![runtest_file_p $runtests $testcase] then {
+ continue
+ }
+ fortran-torture-execute $testcase
+}
+
+foreach testcase [lsort [glob -nocomplain $srcdir/$subdir/*.f95]] {
+ if ![runtest_file_p $runtests $testcase] then {
+ continue
+ }
+ fortran-torture-execute $testcase
+}
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/f2_edit_1.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/f2_edit_1.f90
new file mode 100644
index 00000000000..cb2f5eacd33
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/f2_edit_1.f90
@@ -0,0 +1,10 @@
+! check F2.x edit descriptors
+! PR 14746
+ CHARACTER*15 LINE
+ RCON21 = 9.
+ RCON22 = .9
+ WRITE(LINE,'(F2.0,1H,,F2.1)')RCON21,RCON22
+ READ(LINE,'(F2.0,1X,F2.1)')XRCON21,XRCON22
+ IF (RCON21.NE.XRCON21) CALL ABORT
+ IF (RCON22.NE.XRCON22) CALL ABORT
+ END
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/forall.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/forall.f90
new file mode 100644
index 00000000000..b60e67fb0d7
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/forall.f90
@@ -0,0 +1,17 @@
+! Program to test the FORALL construct
+program testforall
+ implicit none
+ integer, dimension (3, 3) :: a
+ integer, dimension (3) :: b
+ integer i
+
+ a = reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9/), (/3, 3/));
+
+ forall (i=1:3)
+ b(i) = sum (a(:, i))
+ end forall
+
+ if (b(1) .ne. 6) call abort
+ if (b(2) .ne. 15) call abort
+ if (b(3) .ne. 24) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/forall_1.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/forall_1.f90
new file mode 100644
index 00000000000..806dede70f3
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/forall_1.f90
@@ -0,0 +1,61 @@
+! Program to test FORALL construct
+program forall_1
+
+ call actual_variable ()
+ call negative_stride ()
+ call forall_index ()
+
+contains
+ subroutine actual_variable ()
+ integer:: x = -1
+ integer a(3,4)
+ j = 100
+
+ ! Actual variable 'x' and 'j' used as FORALL index
+ forall (x = 1:3, j = 1:4)
+ a (x,j) = j
+ end forall
+ if (any (a.ne.reshape ((/1,1,1,2,2,2,3,3,3,4,4,4/), (/3,4/)))) call abort
+ if ((x.ne.-1).or.(j.ne.100)) call abort
+
+ call actual_variable_2 (x, j, a)
+ end subroutine
+
+ subroutine actual_variable_2(x, j, a)
+ integer x,j,x1,j1
+ integer a(3,4), b(3,4)
+
+ ! Actual variable 'x' and 'j' used as FORALL index.
+ forall (x=3:1:-1, j=4:1:-1)
+ a(x,j) = j
+ b(x,j) = j
+ end forall
+
+ if (any (a.ne.reshape ((/1,1,1,2,2,2,3,3,3,4,4,4/), (/3,4/)))) call abort
+ if (any (b.ne.reshape ((/1,1,1,2,2,2,3,3,3,4,4,4/), (/3,4/)))) call abort
+ if ((x.ne.-1).or.(j.ne.100)) call abort
+ end subroutine
+
+ subroutine negative_stride ()
+ integer a(3,4)
+ integer x, j
+
+ ! FORALL with negative stride
+ forall (x = 3:1:-1, j = 4:1:-1)
+ a(x,j) = j + x
+ end forall
+ if (any (a.ne.reshape ((/2,3,4,3,4,5,4,5,6,5,6,7/), (/3,4/)))) call abort
+ end subroutine
+
+ subroutine forall_index
+ integer a(32,32)
+
+ ! FORALL with arbitrary number indexes
+ forall (i1=1:2,i2=1:2,i3=1:2,i4=1:2,i5=1:2,i6=1:2,i7=1:2,i8=1:2,i9=1:2,&
+ i10=1:2)
+ a(i1+2*i3+4*i5+8*i7+16*i9-30,i2+2*i4+4*i6+8*i8+16*i10-30) = 1
+ end forall
+ if ((a(5,5).ne.1).or. (a(32,32).ne.1)) call abort
+ end subroutine
+
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/forall_2.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/forall_2.f90
new file mode 100644
index 00000000000..92a4ff102cc
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/forall_2.f90
@@ -0,0 +1,20 @@
+!program to test nested forall construct and forall mask
+program test
+ implicit none
+ integer a(4,4)
+ integer i, j
+
+ do i=1,4
+ do j=1,4
+ a(j,i) = j-i
+ enddo
+ enddo
+ forall (i=2:4, a(1,i).GT.-2)
+ forall (j=1:4, a(j,2).GT.0)
+ a(j,i) = a(j,i-1)
+ end forall
+ end forall
+ if (any (a.ne.reshape ((/0,1,2,3,-1,0,2,3,-2,-1,0,1,-3,-2,-1,0/),&
+ (/4,4/)))) call abort
+end
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/forall_3.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/forall_3.f90
new file mode 100644
index 00000000000..957178c8a65
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/forall_3.f90
@@ -0,0 +1,36 @@
+! Really test forall with temporary
+program evil_forall
+ implicit none
+ type t
+ logical valid
+ integer :: s
+ integer, dimension(:), pointer :: p
+ end type
+ type (t), dimension (5) :: v
+ integer i
+
+ allocate (v(1)%p(2))
+ allocate (v(2)%p(8))
+ v(3)%p => NULL()
+ allocate (v(4)%p(8))
+ allocate (v(5)%p(2))
+
+ v(:)%valid = (/.true., .true., .false., .true., .true./)
+ v(:)%s = (/1, 8, 999, 6, 2/)
+ v(1)%p(:) = (/9, 10/)
+ v(2)%p(:) = (/1, 2, 3, 4, 5, 6, 7, 8/)
+ v(4)%p(:) = (/13, 14, 15, 16, 17, 18, 19, 20/)
+ v(5)%p(:) = (/11, 12/)
+
+
+ forall (i=1:5,v(i)%valid)
+ v(i)%p(1:v(i)%s) = v(6-i)%p(1:v(i)%s)
+ end forall
+
+ if (any(v(1)%p(:) .ne. (/11, 10/))) call abort
+ if (any(v(2)%p(:) .ne. (/13, 14, 15, 16, 17, 18, 19, 20/))) call abort
+ if (any(v(4)%p(:) .ne. (/1, 2, 3, 4, 5, 6, 19, 20/))) call abort
+ if (any(v(5)%p(:) .ne. (/9, 10/))) call abort
+
+ ! I should really free the memory I've allocated.
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/forall_4.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/forall_4.f90
new file mode 100644
index 00000000000..f2dded73587
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/forall_4.f90
@@ -0,0 +1,27 @@
+! Program to test nested forall
+program forall2
+ implicit none
+ integer a(4,4,2)
+ integer i, j, k, n
+
+ a(:,:,1) = reshape((/ 1, 2, 3, 4,&
+ 5, 6, 7, 8,&
+ 9,10,11,12,&
+ 13,14,15,16/), (/4,4/))
+ a(:,:,2) = a(:,:,1) + 16
+ n=4
+ k=1
+ ! Mirror half the matrix
+ forall (i=k:n)
+ forall (j=1:5-i)
+ a(i,j,:) = a(j,i,:)
+ end forall
+ end forall
+
+ if (any (a(:,:,1) &
+ .ne. reshape((/ 1, 5, 9,13,&
+ 2, 6,10, 8,&
+ 3, 7,11,12,&
+ 4,14,15,16/),(/4,4/)))) call abort
+ if (any (a(:,:,2) .ne. a(:,:,1) + 16)) call abort
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/forall_5.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/forall_5.f90
new file mode 100644
index 00000000000..0595adf0c89
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/forall_5.f90
@@ -0,0 +1,28 @@
+! Program to test FORALL with pointer assignment inside it.
+program forall_5
+ type element
+ integer, pointer, dimension(:)::p
+ end type
+
+ type (element) q(5)
+ integer, target, dimension(25)::t
+
+ n = 5
+ do i = 1,5
+ q(i)%p => t((i-1)*n + 1:i*n)
+ enddo
+
+ forall (i = 2:5)
+ q(i)%p => q(i-1)%p
+ end forall
+
+ do i = 1, 25
+ t(i) = i
+ enddo
+
+ if (any(q(1)%p .ne. (/1,2,3,4,5/))) call abort
+ if (any(q(2)%p .ne. (/1,2,3,4,5/))) call abort
+ if (any(q(3)%p .ne. (/6,7,8,9,10/))) call abort
+ if (any(q(4)%p .ne. (/11,12,13,14,15/))) call abort
+ if (any(q(5)%p .ne. (/16,17,18,19,20/))) call abort
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/forall_6.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/forall_6.f90
new file mode 100644
index 00000000000..b277814fb3f
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/forall_6.f90
@@ -0,0 +1,25 @@
+! Program to test FORALL with scalar pointer assignment inside it.
+program forall_6
+ type element
+ real, pointer :: p
+ end type
+
+ type (element) q(5)
+ real, target, dimension(5) :: t
+ integer i;
+
+ t = (/1.0, 2.0, 3.0, 4.0, 5.0/)
+
+ do i = 1,5
+ q(i)%p => t(i)
+ end do
+
+ forall (i = 1:5)
+ q(i)%p => q(6 - i)%p
+ end forall
+
+
+ do i = 1,5
+ if (q(i)%p .ne. t(6 - i)) call abort
+ end do
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/function_module_1.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/function_module_1.f90
new file mode 100644
index 00000000000..e57ff161d29
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/function_module_1.f90
@@ -0,0 +1,36 @@
+! This can fail because BB is not resolved correctly.
+module M1
+
+INTEGER p
+
+CONTAINS
+subroutine AA ()
+ implicit NONE
+ p = BB ()
+ CONTAINS
+ subroutine AA_1 ()
+ implicit NONE
+ integer :: i
+ i = BB ()
+ end subroutine
+
+ function BB()
+ integer :: BB
+ BB = 1
+ end function
+end subroutine
+
+function BB()
+ implicit NONE
+ integer :: BB
+ BB = 2
+end function
+end module
+
+program P1
+ USE M1
+ implicit none
+ p = 0
+ call AA ()
+ if (p /= 1) call abort
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/hollerith.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/hollerith.f90
new file mode 100644
index 00000000000..aa7b17def75
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/hollerith.f90
@@ -0,0 +1,9 @@
+! PR 14038- 'H' in hollerith causes mangling of string
+program hollerith
+ IMPLICIT NONE
+ CHARACTER*4 LINE
+100 FORMAT (4H12H4)
+ WRITE(LINE,100)
+ IF (LINE .NE. '12H4') call abort ()
+end
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/initializer.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/initializer.f90
new file mode 100644
index 00000000000..55cc185f370
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/initializer.f90
@@ -0,0 +1,26 @@
+! Program to test static variable initialization
+! returns the parameter from the previous invocation, or 42 on the first call.
+function test (parm)
+ implicit none
+ integer test, parm
+ integer :: val = 42
+
+ test = val
+ val = parm
+end function
+
+program intializer
+ implicit none
+ integer test
+ character(11) :: c = "Hello World"
+ character(15) :: d = "Teststring"
+ integer, dimension(3) :: a = 1
+
+ if (any (a .ne. 1)) call abort
+ if (test(11) .ne. 42) call abort
+ ! The second call should return
+ if (test(0) .ne. 11) call abort
+
+ if (c .ne. "Hello World") call abort
+ if (d .ne. "Teststring") call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/inquire_1.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/inquire_1.f90
new file mode 100644
index 00000000000..492f74476d3
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/inquire_1.f90
@@ -0,0 +1,8 @@
+! PR 14831
+ CHARACTER*4 BLANK
+ CHARACTER*10 ACCESS
+ OPEN(UNIT=9,ACCESS='SEQUENTIAL')
+ INQUIRE(UNIT=9,ACCESS=ACCESS,BLANK=BLANK)
+ IF(BLANK.NE.'NULL') CALL ABORT
+ IF(ACCESS.NE.'SEQUENTIAL') CALL ABORT
+ END
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/inquire_2.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/inquire_2.f90
new file mode 100644
index 00000000000..bc7ea74c39a
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/inquire_2.f90
@@ -0,0 +1,6 @@
+! PR 14837
+ INTEGER UNIT
+ OPEN(FILE='CSEQ', UNIT=23)
+ INQUIRE(FILE='CSEQ',NUMBER=UNIT)
+ IF (UNIT.NE.23) CALL ABORT
+ END
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/inquire_3.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/inquire_3.f90
new file mode 100644
index 00000000000..8967dcfbc0f
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/inquire_3.f90
@@ -0,0 +1,13 @@
+! pr14836
+ OPEN(UNIT=9, ACCESS='DIRECT', RECL=80, FORM='UNFORMATTED')
+ INQUIRE(UNIT=9,NEXTREC=NREC)
+ WRITE(UNIT=9,REC=5) 1
+ INQUIRE(UNIT=9,NEXTREC=NREC)
+! PRINT*,NREC
+ IF (NREC.NE.6) CALL ABORT
+ READ(UNIT=9,REC=1) MVI
+ INQUIRE(UNIT=9,NEXTREC=NREC)
+ IF (NREC.NE.2) CALL ABORT
+! PRINT*,NREC
+ END
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/inquire_4.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/inquire_4.f90
new file mode 100644
index 00000000000..5b94ad232bc
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/inquire_4.f90
@@ -0,0 +1,20 @@
+! pr 14904
+! inquire lastrec not correct when two records written
+! with one write statement
+ OPEN(UNIT=10,ACCESS='DIRECT',FORM='FORMATTED',RECL=120)
+ 100 FORMAT(I4)
+ WRITE(UNIT=10,REC=1,FMT=100)1
+ INQUIRE(UNIT=10,NEXTREC=J)
+ IF (J.NE.2) THEN
+! PRINT*,'NEXTREC RETURNED ',J,' EXPECTED 2'
+ CALL ABORT
+ ENDIF
+ 200 FORMAT(I4,/,I4)
+ WRITE(UNIT=10,REC=2,FMT=200)2,3
+ INQUIRE(UNIT=10,NEXTREC=J)
+ IF (J.NE.4) THEN
+! PRINT*,'NEXTREC RETURNED ',J,' EXPECTED 4'
+ CALL ABORT
+ ENDIF
+ END
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/integer_select.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/integer_select.f90
new file mode 100644
index 00000000000..148cd394e68
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/integer_select.f90
@@ -0,0 +1,71 @@
+PROGRAM Test_INTEGER_select
+
+! Every wrong branch leads to destruction.
+
+ INTEGER, PARAMETER :: maxI = HUGE (maxI)
+ INTEGER, PARAMETER :: minI = -1 * maxI
+ INTEGER :: I = 0
+
+ SELECT CASE (I)
+ CASE (:-1)
+ CALL abort
+ CASE (1:)
+ CALL abort
+ CASE DEFAULT
+ CONTINUE
+ END SELECT
+
+ SELECT CASE (I)
+ CASE (3,2,1)
+ CALL abort
+ CASE (0)
+ CONTINUE
+ CASE DEFAULT
+ call abort
+ END SELECT
+
+! Not aborted by here, so it worked
+! See about weird corner cases
+
+ I = maxI
+
+ SELECT CASE (I)
+ CASE (:-1)
+ CALL abort
+ CASE (1:)
+ CONTINUE
+ CASE DEFAULT
+ CALL abort
+ END SELECT
+
+ SELECT CASE (I)
+ CASE (3,2,1,:0)
+ CALL abort
+ CASE (maxI)
+ CONTINUE
+ CASE DEFAULT
+ call abort
+ END SELECT
+
+ I = minI
+
+ SELECT CASE (I)
+ CASE (:-1)
+ CONTINUE
+ CASE (1:)
+ CALL abort
+ CASE DEFAULT
+ CALL abort
+ END SELECT
+
+ SELECT CASE (I)
+ CASE (3:,2,1,0)
+ CALL abort
+ CASE (minI)
+ CONTINUE
+ CASE DEFAULT
+ call abort
+ END SELECT
+
+END
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/integer_select_1.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/integer_select_1.f90
new file mode 100644
index 00000000000..cd9bb00a98c
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/integer_select_1.f90
@@ -0,0 +1,31 @@
+INTEGER :: I = 1
+SELECT CASE (I)
+ CASE (-3:-5) ! Can never be matched
+ CALL abort
+ CASE (1)
+ CONTINUE
+ CASE DEFAULT
+ CALL abort
+END SELECT
+
+I = -3
+SELECT CASE (I)
+ CASE (-3:-5) ! Can never be matched
+ CALL abort
+ CASE (1)
+ CONTINUE
+ CASE DEFAULT
+ CONTINUE
+END SELECT
+
+I = -5
+SELECT CASE (I)
+ CASE (-3:-5) ! Can never be matched
+ CALL abort
+ CASE (-5)
+ CONTINUE
+ CASE DEFAULT
+ CALL abort
+END SELECT
+END
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/internal_write.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/internal_write.f90
new file mode 100644
index 00000000000..1e492977b06
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/internal_write.f90
@@ -0,0 +1,11 @@
+! PR 14901
+! Internal writes were appending CR after the last char
+! written by the format statement.
+ CHARACTER*10 A
+ WRITE(A,'(3HGCC)')
+ IF (A.NE.'GCC ') THEN
+! PRINT*,'A was not filled correctly by internal write'
+! PRINT*,' A = ',A
+ CALL ABORT
+ ENDIF
+ END
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_abs.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_abs.f90
new file mode 100644
index 00000000000..9e44657bad1
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_abs.f90
@@ -0,0 +1,33 @@
+! Program to test the ABS intrinsic
+program intrinsic_abs
+ implicit none
+ integer i
+ real(kind=4) r
+ real(kind=8) q
+ complex z
+
+ i = 42
+ i = abs(i)
+ if (i .ne. 42) call abort
+ i = -43
+ i = abs(i)
+ if (i .ne. 43) call abort
+
+ r = 42.0
+ r = abs(r)
+ if (r .ne. 42.0) call abort
+ r = -43.0
+ r = abs(r)
+ if (r .ne. 43.0) call abort
+
+ q = 42.0_8
+ q = abs(q)
+ if (q .ne. 42.0_8) call abort
+ q = -43.0_8
+ q = abs(q)
+ if (q .ne. 43.0_8) call abort
+
+ z = (3, 4)
+ r = abs(z)
+ if (r .ne. 5) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_achar.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_achar.f90
new file mode 100644
index 00000000000..fba0a08974f
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_achar.f90
@@ -0,0 +1,9 @@
+! Program to test the ACHAR and IACHAR intrinsics
+program intrinsic_achar
+ integer i
+
+ i = 32
+ if (achar(i) .ne. " ") call abort
+ i = iachar("A")
+ if ((i .ne. 65) .or. char(i) .ne. "A") call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_aint_anint.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_aint_anint.f90
new file mode 100644
index 00000000000..16e816c6bd0
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_aint_anint.f90
@@ -0,0 +1,55 @@
+! Program to test AINT and ANINT intrinsics
+
+subroutine real4test (op, res1, res2)
+ implicit none
+ real(kind=4) :: op
+ real(kind=4) :: res1, res2
+
+ if (diff(aint(op), res1) .or. &
+ diff(anint(op), res2)) call abort
+contains
+function diff(a, b)
+ real(kind=4) :: a, b
+ logical diff
+
+ diff = (abs (a - b) .gt. abs(a * 1e-6))
+end function
+end subroutine
+
+subroutine real8test (op, res1, res2)
+ implicit none
+ real(kind=8) :: op
+ real(kind=8) :: res1, res2
+
+ if (diff(aint(op), res1) .or. &
+ diff(anint(op), res2)) call abort
+contains
+function diff(a, b)
+ real(kind=8) :: a, b
+ logical diff
+
+ diff = (abs(a - b) .gt. abs(a * 1e-6))
+end function
+end subroutine
+
+program aint_aninttest
+ implicit none
+
+ call real4test (3.456, 3.0, 3.0)
+ call real4test (-2.798, -2.0, -3.0)
+ call real4test (3.678, 3.0, 4.0)
+ call real4test (-1.375, -1.0, -1.0)
+ call real4test (-0.5, 0.0,-1.0)
+ call real4test (0.4, 0.0,0.0)
+
+ call real8test (3.456_8, 3.0_8, 3.0_8)
+ call real8test (-2.798_8, -2.0_8, -3.0_8)
+ call real8test (3.678_8, 3.0_8, 4.0_8)
+ call real8test (-1.375_8, -1.0_8, -1.0_8)
+ call real8test (-0.5_8, 0.0_8,-1.0_8)
+ call real8test (0.4_8, 0.0_8,0.0_8)
+
+ ! Check large numbers
+ call real4test (2e34, 2e34, 2e34)
+ call real4test (-2e34, -2e34, -2e34)
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_anyall.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_anyall.f90
new file mode 100644
index 00000000000..d1b99dacb5d
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_anyall.f90
@@ -0,0 +1,26 @@
+! Program to test the ANY and ALL intrinsics
+program anyall
+ implicit none
+ logical, dimension(3, 3) :: a
+ logical, dimension(3) :: b
+
+ a = .false.
+ if (any(a)) call abort
+ a(1, 1) = .true.
+ a(2, 3) = .true.
+ if (.not. any(a)) call abort
+ b = any(a, 1)
+ if (.not. b(1)) call abort
+ if (b(2)) call abort
+ if (.not. b(3)) call abort
+
+ a = .true.
+ if (.not. all(a)) call abort
+ a(1, 1) = .false.
+ a(2, 3) = .false.
+ if (all(a)) call abort
+ b = all(a, 1)
+ if (b(1)) call abort
+ if (.not. b(2)) call abort
+ if (b(3)) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_associated.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_associated.f90
new file mode 100644
index 00000000000..24d647ef15a
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_associated.f90
@@ -0,0 +1,137 @@
+! Program to test the ASSOCIATED intrinsic.
+program intrinsic_associated
+ call pointer_to_section ()
+ call associate_1 ()
+ call pointer_to_derived_1 ()
+ call associated_2 ()
+end
+
+subroutine pointer_to_section ()
+ integer, dimension(100, 100), target :: xy
+ integer, dimension(:, :), pointer :: window
+ integer i, j, k, m, n
+ data xy /10000*0/
+ logical t
+
+ window => xy(10:50, 30:60)
+ window = 10
+ window (1, 1) = 0101
+ window (41, 31) = 4161
+ window (41, 1) = 4101
+ window (1, 31) = 0161
+
+ t = associated (window, xy(10:50, 30:60))
+ if (.not.t) call abort ()
+ if (window(1, 1) .ne. xy(10, 30)) call abort ()
+ if (window(41, 31) .ne. xy(50, 60)) call abort ()
+ if (window(1, 31) .ne. xy(10, 60)) call abort ()
+ if (window(41, 1) .ne. xy(50, 30)) call abort ()
+ if (xy(9, 29) .ne. 0) call abort ()
+ if (xy(51,29 ) .ne. 0) call abort ()
+ if (xy(9, 60) .ne. 0) call abort ()
+ if (xy(51, 60) .ne. 0) call abort ()
+ if (xy(11, 31) .ne. 10) call abort ()
+ if (xy(49, 59) .ne. 10) call abort ()
+ if (xy(11, 59) .ne. 10) call abort ()
+ if (xy(49, 31) .ne. 10) call abort ()
+end
+
+subroutine sub1 (a, ap)
+ integer, pointer :: ap(:, :)
+ integer, target :: a(10, 10)
+
+ ap => a
+end
+
+subroutine nullify_pp (a)
+ integer, pointer :: a(:, :)
+
+ if (.not. associated (a)) call abort ()
+ nullify (a)
+end
+
+subroutine associate_1 ()
+ integer, pointer :: a(:, :), b(:, :)
+ interface
+ subroutine nullify_pp (a)
+ integer, pointer :: a(:, :)
+ end subroutine nullify_pp
+ end interface
+
+ allocate (a(80, 80))
+ b => a
+ if (.not. associated(a)) call abort ()
+ if (.not. associated(b)) call abort ()
+ call nullify_pp (a)
+ if (associated (a)) call abort ()
+ if (.not. associated (b)) call abort ()
+end
+
+subroutine pointer_to_derived_1 ()
+ type record
+ integer :: value
+ type(record), pointer :: rp
+ end type record
+
+ type record1
+ integer value
+ type(record2), pointer :: r1p
+ end type
+
+ type record2
+ integer value
+ type(record1), pointer :: r2p
+ end type
+
+ type(record), target :: e1, e2, e3
+ type(record1), target :: r1
+ type(record2), target :: r2
+
+ nullify (r1%r1p, r2%r2p, e1%rp, e2%rp, e3%rp)
+ if (associated (r1%r1p)) call abort ()
+ if (associated (r2%r2p)) call abort ()
+ if (associated (e2%rp)) call abort ()
+ if (associated (e1%rp)) call abort ()
+ if (associated (e3%rp)) call abort ()
+ r1%r1p => r2
+ r2%r2p => r1
+ r1%value = 11
+ r2%value = 22
+ e1%rp => e2
+ e2%rp => e3
+ e1%value = 33
+ e1%rp%value = 44
+ e1%rp%rp%value = 55
+ if (.not. associated (r1%r1p)) call abort ()
+ if (.not. associated (r2%r2p)) call abort ()
+ if (.not. associated (e1%rp)) call abort ()
+ if (.not. associated (e2%rp)) call abort ()
+ if (associated (e3%rp)) call abort ()
+ if (r1%r1p%value .ne. 22) call abort ()
+ if (r2%r2p%value .ne. 11) call abort ()
+ if (e1%value .ne. 33) call abort ()
+ if (e2%value .ne. 44) call abort ()
+ if (e3%value .ne. 55) call abort ()
+ if (r1%value .ne. 11) call abort ()
+ if (r2%value .ne. 22) call abort ()
+
+end
+
+subroutine associated_2 ()
+ integer, pointer :: xp(:, :)
+ integer, target :: x(10, 10)
+ integer, target :: y(100, 100)
+ interface
+ subroutine sub1 (a, ap)
+ integer, pointer :: ap(:, :)
+ integer, target :: a(10, 1)
+ end
+ endinterface
+
+ xp => y
+ if (.not. associated (xp)) call abort ()
+ call sub1 (x, xp)
+ if (associated (xp, y)) call abort ()
+ if (.not. associated (xp, x)) call abort ()
+end
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_associated_2.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_associated_2.f90
new file mode 100644
index 00000000000..5f353b2f85b
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_associated_2.f90
@@ -0,0 +1,36 @@
+! Program to test the ASSOCIATED intrinsic with cross-kinds
+program intrinsic_associated_2
+ logical*4 :: t4, L44, L48
+ logical*8 :: t8, L84, L88
+ real*4, pointer :: a4p(:, :)
+ real*8, pointer :: a8p(:, :)
+ real*4, target :: a4(10, 10)
+ real*8, target :: a8(10, 10)
+
+ t4 = .true.
+ t8 = .true.
+ t8 = t4
+ a4p => a4
+ a8p => a8
+ L44 = t4 .and. associated (a4p, a4)
+ L84 = t8 .and. associated (a4p, a4)
+ L48 = t4 .and. associated (a8p, a8)
+ L88 = t8 .and. associated (a8p, a8)
+ if (.not. (L44 .and. L84 .and. L48 .and. L88)) call abort ()
+
+ nullify (a4p, a8p)
+ L44 = t4 .and. associated (a4p, a4)
+ L84 = t8 .and. associated (a4p, a4)
+ L48 = t4 .and. associated (a8p, a8)
+ L88 = t8 .and. associated (a8p, a8)
+ if (L44 .and. L84 .and. L48 .and. L88) call abort ()
+
+ a4p => a4(1:10:2, 1:10:2)
+ a8p => a8(1:4, 1:4)
+ L44 = t4 .and. associated (a4p, a4(1:10:2, 1:10:2))
+ L84 = t8 .and. associated (a4p, a4(1:10:2, 1:10:2))
+ L48 = t4 .and. associated (a8p, a8(1:4, 1:4))
+ L88 = t8 .and. associated (a8p, a8(1:4, 1:4))
+ if (.not. (L44 .and. L84 .and. L48 .and. L88)) call abort ()
+end
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_bitops.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_bitops.f90
new file mode 100644
index 00000000000..95ff44c999e
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_bitops.f90
@@ -0,0 +1,29 @@
+! Program to test intrinsic bitops
+program intrinsic_bitops
+ implicit none
+ integer(kind=4) :: i, j, k, o, t
+ integer(kind=8) :: a, b, c
+
+ o = 0
+ i = 2
+ j = 3
+ k = 12
+
+ if (.not. btest (i, o+1)) call abort
+ if (btest (i, o+2)) call abort
+ if (iand (i, j) .ne. 2) call abort
+ if (ibclr (j, o+1) .ne. 1) call abort
+ if (ibclr (j, o+2) .ne. 3) call abort
+ if (ibits (k, o+1, o+2) .ne. 2) call abort
+ if (ibset (j, o+1) .ne. 3) call abort
+ if (ibset (j, o+2) .ne. 7) call abort
+ if (ieor (i, j) .ne. 1) call abort
+ if (ior (i, j) .ne. 3) call abort
+ if (ishft (k, o+2) .ne. 48) call abort
+ if (ishft (k, o-3) .ne. 1) call abort
+ if (ishft (k, o) .ne. 12) call abort
+ if (ishftc (k, o+30) .ne. 3) call abort
+ if (ishftc (k, o-30) .ne. 48) call abort
+ if (ishftc (k, o+1, o+3) .ne. 9) call abort
+ if (not (i) .ne. -3) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_count.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_count.f90
new file mode 100644
index 00000000000..a2de59fb985
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_count.f90
@@ -0,0 +1,21 @@
+! Program to test the COUNT intrinsic
+program intrinsic_count
+ implicit none
+ logical(kind=4), dimension (3, 5) :: a
+ integer(kind=4), dimension (5) :: b
+ integer i
+
+ a = .false.
+ if (count(a) .ne. 0) call abort
+ a = .true.
+ if (count(a) .ne. 15) call abort
+ a(1, 1) = .false.
+ a(2, 2) = .false.
+ a(2, 5) = .false.
+ if (count(a) .ne. 12) call abort
+
+ b(1:3) = count(a, 2);
+ if (b(1) .ne. 4) call abort
+ if (b(2) .ne. 3) call abort
+ if (b(3) .ne. 5) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_cshift.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_cshift.f90
new file mode 100644
index 00000000000..f188cd8f4bb
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_cshift.f90
@@ -0,0 +1,43 @@
+! Program to test the cshift intrinsic
+program intrinsic_cshift
+ integer, dimension(3, 3) :: a
+ integer, dimension(3, 3, 2) :: b
+
+ ! Scalar shift
+ a = reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9/), (/3, 3/))
+ a = cshift (a, 1, 1)
+ if (any (a .ne. reshape ((/2, 3, 1, 5, 6, 4, 8, 9, 7/), (/3, 3/)))) &
+ call abort
+
+ a = reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9/), (/3, 3/))
+ a = cshift (a, -2, dim = 2)
+ if (any (a .ne. reshape ((/4, 5, 6, 7, 8, 9, 1, 2, 3/), (/3, 3/)))) &
+ call abort
+
+ ! Array shift
+ a = reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9/), (/3, 3/))
+ a = cshift (a, (/1, 0, -1/))
+ if (any (a .ne. reshape ((/2, 3, 1, 4, 5, 6, 9, 7, 8/), (/3, 3/)))) &
+ call abort
+
+ a = reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9/), (/3, 3/))
+ a = cshift (a, (/2, -2, 0/), dim = 2)
+ if (any (a .ne. reshape ((/7, 5, 3, 1, 8, 6, 4, 2, 9/), (/3, 3/)))) &
+ call abort
+
+ ! Test arrays > rank 2
+ b = reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17,&
+ 18, 19/), (/3, 3, 2/))
+ b = cshift (b, 1)
+ if (any (b .ne. reshape ((/2, 3, 1, 5, 6, 4, 8, 9, 7, 12, 13, 11, 15,&
+ 16, 14, 18, 19, 17/), (/3, 3, 2/)))) &
+ call abort
+
+ b = reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17,&
+ 18, 19/), (/3, 3, 2/))
+ b = cshift (b, reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9/), (/3, 3/)), 3)
+ if (any (b .ne. reshape ((/11, 2, 13, 4, 15, 6, 17, 8, 19, 1, 12, 3,&
+ 14, 5, 16, 7, 18, 9/), (/3, 3, 2/)))) &
+ call abort
+
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_dim.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_dim.f90
new file mode 100644
index 00000000000..4753de3606d
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_dim.f90
@@ -0,0 +1,20 @@
+! Program to test the DIM intrinsic
+program intrinsic_dim
+ implicit none
+ integer i, j
+ real(kind=4) :: r, s
+ real(kind=8) :: p, q
+
+ i = 1
+ j = 4
+ if (dim (i, j) .ne. 0) call abort
+ if (dim (j, i) .ne. 3) call abort
+ r = 1.0
+ s = 4.0
+ if (dim (r, s) .ne. 0.0) call abort
+ if (dim (s, r) .ne. 3.0) call abort
+ p = 1.0
+ q = 4.0
+ if (dim (p, q) .ne. 0.0) call abort
+ if (dim (q, p) .ne. 3.0) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_dotprod.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_dotprod.f90
new file mode 100644
index 00000000000..5444dd6dac1
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_dotprod.f90
@@ -0,0 +1,25 @@
+! Program to test the DOT_PRODUCT intrinsic
+program testforall
+ implicit none
+ integer, dimension (3) :: a
+ integer, dimension (3) :: b
+ real, dimension(3) :: c
+ real r
+ complex, dimension (2) :: z1
+ complex, dimension (2) :: z2
+ complex z
+
+ a = (/1, 2, 3/);
+ b = (/4, 5, 6/);
+ c = (/4, 5, 6/);
+
+ if (dot_product(a, b) .ne. 32) call abort
+
+ r = dot_product(a, c)
+ if (abs(r - 32.0) .gt. 0.001) call abort
+
+ z1 = (/(1.0, 2.0), (2.0, 3.0)/)
+ z2 = (/(3.0, 4.0), (4.0, 5.0)/)
+ z = dot_product (z1, z2)
+ if (abs (z - (34.0, -4.0)) .gt. 0.001) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_dprod.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_dprod.f90
new file mode 100644
index 00000000000..feb3367934b
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_dprod.f90
@@ -0,0 +1,13 @@
+! Program to test DPROD intrinsic
+program intrinsic_dprod
+ implicit none
+ real r, s, t
+ double precision dp
+
+ ! 6d60 doesn't fit in a 4-byte real
+ r = 2e30
+ s = 4e30
+ dp = dprod (r, s)
+ if ((dp .gt. 8.001d60) .or. (dp .lt. 7.999d60)) call abort
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_dummy.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_dummy.f90
new file mode 100644
index 00000000000..2e8a3401492
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_dummy.f90
@@ -0,0 +1,23 @@
+! Program to test passing intrinsic functions as actual arguments for
+! dummy procedures.
+subroutine test (proc)
+ implicit none
+ real proc
+ real a, b, c
+
+ a = 1.0
+ b = sin (a)
+ c = proc (a)
+
+ if (abs (b - c) .gt. 0.001) call abort
+
+end subroutine
+
+program dummy
+ implicit none
+ external test
+ intrinsic sin
+
+ call test (sin)
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_eoshift.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_eoshift.f90
new file mode 100644
index 00000000000..12edc630e50
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_eoshift.f90
@@ -0,0 +1,60 @@
+! Program to test the eoshift intrinsic
+program intrinsic_eoshift
+ integer, dimension(3, 3) :: a
+ integer, dimension(3, 3, 2) :: b
+
+ ! Scalar shift and scalar bound.
+ a = reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9/), (/3, 3/))
+ a = eoshift (a, 1, 99, 1)
+ if (any (a .ne. reshape ((/2, 3, 99, 5, 6, 99, 8, 9, 99/), (/3, 3/)))) &
+ call abort
+
+ a = reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9/), (/3, 3/))
+ a = eoshift (a, -2, dim = 2)
+ if (any (a .ne. reshape ((/0, 0, 0, 0, 0, 0, 1, 2, 3/), (/3, 3/)))) &
+ call abort
+
+ ! Array shift and scalar bound.
+ a = reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9/), (/3, 3/))
+ a = eoshift (a, (/1, 0, -1/), 99, 1)
+ if (any (a .ne. reshape ((/2, 3, 99, 4, 5, 6, 99, 7, 8/), (/3, 3/)))) &
+ call abort
+
+ a = reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9/), (/3, 3/))
+ a = eoshift (a, (/2, -2, 0/), dim = 2)
+ if (any (a .ne. reshape ((/7, 0, 3, 0, 0, 6, 0, 2, 9/), (/3, 3/)))) &
+ call abort
+
+ ! Scalar shift and array bound.
+ a = reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9/), (/3, 3/))
+ a = eoshift (a, 1, (/99, -1, 42/), 1)
+ if (any (a .ne. reshape ((/2, 3, 99, 5, 6, -1, 8, 9, 42/), (/3, 3/)))) &
+ call abort
+
+ a = reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9/), (/3, 3/))
+ a = eoshift (a, -2, (/99, -1, 42/), 2)
+ if (any (a .ne. reshape ((/99, -1, 42, 99, -1, 42, 1, 2, 3/), (/3, 3/)))) &
+ call abort
+
+ ! Array shift and array bound.
+ a = reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9/), (/3, 3/))
+ a = eoshift (a, (/1, 0, -1/), (/99, -1, 42/), 1)
+ if (any (a .ne. reshape ((/2, 3, 99, 4, 5, 6, 42, 7, 8/), (/3, 3/)))) &
+ call abort
+
+ a = reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9/), (/3, 3/))
+ a = eoshift (a, (/2, -2, 0/), (/99, -1, 42/), 2)
+ if (any (a .ne. reshape ((/7, -1, 3, 99, -1, 6, 99, 2, 9/), (/3, 3/)))) &
+ call abort
+
+ ! Test arrays > rank 2
+ b(:, :, 1) = reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9/), (/3, 3/))
+ b(:, :, 2) = 10 + reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9/), (/3, 3/))
+ b = eoshift (b, 1, 99, 1)
+ if (any (b(:, :, 1) .ne. reshape ((/2, 3, 99, 5, 6, 99, 8, 9, 99/), (/3, 3/)))) &
+ call abort
+ if (any (b(:, :, 2) .ne. reshape ((/12, 13, 99, 15, 16, 99, 18, 19, 99/), (/3, 3/)))) &
+ call abort
+
+ ! TODO: Test array sections
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_fraction_exponent.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_fraction_exponent.f90
new file mode 100644
index 00000000000..a22d0b9f50a
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_fraction_exponent.f90
@@ -0,0 +1,84 @@
+!Program to test EXPONENT and FRACTION intrinsic function.
+
+program test_exponent_fraction
+ real x
+ integer*4 i
+ real*8 y
+ integer*8 j
+ equivalence (x, i), (y, j)
+
+ x = 3.
+ call test_4(x)
+
+ x = 0.
+ call test_4(x)
+
+ i = o'00000000001'
+ call test_4(x)
+
+ i = o'00010000000'
+ call test_4(x)
+
+ i = o'17700000000'
+ call test_4(x)
+
+ i = o'00004000001'
+ call test_4(x)
+
+ i = o'17737777777'
+ call test_4(x)
+
+ i = o'10000000000'
+ call test_4(x)
+
+ i = o'0000010000'
+ call test_4(x)
+
+ y = 0.5
+ call test_8(y)
+
+ y = 0.
+ call test_8(y)
+
+ j = o'00000000001'
+ call test_8(y)
+
+ y = 0.2938735877D-38
+ call test_8(y)
+
+ y = -1.469369D-39
+ call test_8(y)
+
+ y = z'7fe00000'
+ call test_8(y)
+
+ y = -5.739719D+42
+ call test_8(y)
+end
+
+subroutine test_4(x)
+real*4 x,y
+integer z
+y = fraction (x)
+z = exponent(x)
+if (z .gt. 0) then
+ y = (y * 2.) * (2. ** (z - 1))
+else
+ y = (y / 2.) * (2. ** (z + 1))
+end if
+if (abs (x - y) .gt. abs(x * 1e-6)) call abort()
+end
+
+subroutine test_8(x)
+real*8 x, y
+integer z
+y = fraction (x)
+z = exponent(x)
+if (z .gt. 0) then
+ y = (y * 2._8) * (2._8 ** (z - 1))
+else
+ y = (y / 2._8) * (2._8 ** (z + 1))
+end if
+if (abs (x - y) .gt. abs(x * 1e-6)) call abort()
+end
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_index.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_index.f90
new file mode 100644
index 00000000000..9b181775f9c
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_index.f90
@@ -0,0 +1,15 @@
+! Program to test the INDEX intrinsic
+program test
+ character(len=10) a
+ integer w
+ if (index("FORTRAN", "R") .ne. 3) call abort
+ if (index("FORTRAN", "R", .TRUE.) .ne. 5) call abort
+ if (w ("FORTRAN") .ne. 3) call abort
+end
+
+function w(str)
+ character(len=8) str
+ integer w
+ w = index(str, "R")
+end
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_integer.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_integer.f90
new file mode 100644
index 00000000000..43578ed54a7
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_integer.f90
@@ -0,0 +1,18 @@
+! Program to test the real->integer conversion routines.
+program intrinsic_integer
+ implicit none
+
+ call test (0.0, (/0, 0, 0, 0/))
+ call test (0.3, (/0, 1, 0, 0/))
+ call test (0.7, (/0, 1, 0, 1/))
+ call test (-0.3, (/-1, 0, 0, 0/))
+ call test (-0.7, (/-1, 0, 0, -1/))
+contains
+subroutine test(val, res)
+ real :: val
+ integer, dimension(4) :: res
+
+ if ((floor(val) .ne. res(1)) .or. (ceiling(val) .ne. res(2)) &
+ .or. (int(val) .ne. res(3)) .or. (nint(val) .ne. res(4))) call abort
+end subroutine
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_len.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_len.f90
new file mode 100644
index 00000000000..6721738608f
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_len.f90
@@ -0,0 +1,22 @@
+! Program to test the LEN intrinsic
+program test
+ character(len=10) a
+ character(len=8) w
+ type person
+ character(len=10) name
+ integer age
+ end type person
+ type(person) Tom
+ integer n
+ a = w (n)
+
+ if ((a .ne. "01234567") .or. (n .ne. 8)) call abort
+ if (len(Tom%name) .ne. 10) call abort
+end
+
+function w(i)
+ character(len=8) w
+ integer i
+ w = "01234567"
+ i = len(w)
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_matmul.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_matmul.f90
new file mode 100644
index 00000000000..4b195d267bd
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_matmul.f90
@@ -0,0 +1,24 @@
+! Program to test the MATMUL intrinsic
+program intrinsic_matmul
+ implicit none
+ integer, dimension(2, 3) :: a
+ integer, dimension(3, 2) :: b
+ integer, dimension(2) :: x
+ integer, dimension(3) :: y
+ integer, dimension(2, 2) :: r
+ integer, dimension(3) :: v
+
+ a = reshape((/1, 2, 2, 3, 3, 4/), (/2, 3/))
+ b = reshape((/1, 2, 3, 3, 4, 5/), (/3, 2/))
+ x = (/1, 2/)
+ y = (/1, 2, 3/)
+
+ r = matmul(a, b)
+ if (any(r .ne. reshape((/14, 20, 26, 38/), (/2, 2/)))) call abort
+
+ v = matmul(x, a)
+ if (any(v .ne. (/5, 8, 11/))) call abort
+
+ v(1:2) = matmul(a, y)
+ if (any(v(1:2) .ne. (/14, 20/))) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_merge.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_merge.f90
new file mode 100644
index 00000000000..b4fc18f4dd6
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_merge.f90
@@ -0,0 +1,15 @@
+! Program to test the MERGE intrinsic
+program intrinsic_merge
+ integer, dimension(3) :: a, b
+ integer i
+
+ a = (/-1, 2, 3/)
+
+ i = 5
+ if (merge (-1, 1, i .gt. 3) .ne. -1) call abort
+ i = 1
+ if (merge (-1, 1, i .ge. 3) .ne. 1) call abort
+
+ b = merge(a, 0, a .ge. 0)
+ if (any (b .ne. (/0, 2, 3/))) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_minmax.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_minmax.f90
new file mode 100644
index 00000000000..02feaad1523
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_minmax.f90
@@ -0,0 +1,37 @@
+! Program to test min and max intrinsics
+program intrinsic_minmax
+ implicit none
+ integer i, j, k, m
+ real r, s, t, u
+
+ i = 1
+ j = -2
+ k = 3
+ m = 4
+ if (min (i, k) .ne. 1) call abort
+ if (min (i, j, k, m) .ne. -2) call abort
+ if (max (i, k) .ne. 3) call abort
+ if (max (i, j, k, m) .ne. 4) call abort
+ if (max (i+1, j) .ne. 2) call abort
+
+ r = 1
+ s = -2
+ t = 3
+ u = 4
+ if (min (r, t) .ne. 1) call abort
+ if (min (r, s, t, u) .ne. -2) call abort
+ if (max (r, t) .ne. 3) call abort
+ if (max (r, s, t, u) .ne. 4) call abort
+
+ if (max (4d0, r) .ne. 4d0) call abort
+ if (amax0 (i, j) .ne. 1.0) call abort
+ if (min1 (r, s) .ne. -2) call abort
+
+ ! Test simplify.
+ if (min (1, -2, 3, 4) .ne. -2) call abort
+ if (max (1, -2, 3, 4) .ne. 4) call abort
+ if (amax0 (1, -2) .ne. 1.0) call abort
+ if (min1 (1., -2.) .ne. -2) call abort
+
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc.f90
new file mode 100644
index 00000000000..f64242af9e8
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc.f90
@@ -0,0 +1,52 @@
+! Program to test the MINLOC and MAXLOC intrinsics
+program testmmloc
+ implicit none
+ integer, dimension (3, 3) :: a
+ integer, dimension (3) :: b
+ logical, dimension (3, 3) :: m
+ integer i
+
+ a = reshape ((/1, 2, 3, 5, 4, 6, 9, 8, 7/), (/3, 3/));
+
+ b = minloc (a, 1)
+ if (b(1) .ne. 1) call abort
+ if (b(2) .ne. 2) call abort
+ if (b(3) .ne. 3) call abort
+
+ m = .true.
+ m(1, 1) = .false.
+ m(1, 2) = .false.
+ b = minloc (a, 1, m)
+ if (b(1) .ne. 2) call abort
+ if (b(2) .ne. 2) call abort
+ if (b(3) .ne. 3) call abort
+
+ b(1:2) = minloc(a)
+ if (b(1) .ne. 1) call abort
+ if (b(2) .ne. 1) call abort
+
+ b(1:2) = minloc(a, mask=m)
+ if (b(1) .ne. 2) call abort
+ if (b(2) .ne. 1) call abort
+
+ b = maxloc (a, 1)
+ if (b(1) .ne. 3) call abort
+ if (b(2) .ne. 3) call abort
+ if (b(3) .ne. 1) call abort
+
+ m = .true.
+ m(1, 2) = .false.
+ m(1, 3) = .false.
+ b = maxloc (a, 1, m)
+ if (b(1) .ne. 3) call abort
+ if (b(2) .ne. 3) call abort
+ if (b(3) .ne. 2) call abort
+
+ b(1:2) = maxloc(a)
+ if (b(1) .ne. 1) call abort
+ if (b(2) .ne. 3) call abort
+
+ b(1:2) = maxloc(a, mask=m)
+ if (b(1) .ne. 2) call abort
+ if (b(2) .ne. 3) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc_2.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc_2.f90
new file mode 100644
index 00000000000..5f0b5b5da1d
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc_2.f90
@@ -0,0 +1,22 @@
+program intrinsic_mmloc_2
+ real a(-1:1), b(2:3), c(1:2)
+ integer, dimension(1):: i
+ real (kind = 8), dimension(-1:1) :: vc
+
+ a = 0
+ b = 0
+ c = 0
+ a(-1) = 1
+ b(2) = 1
+ c(1) = 1
+
+ if (maxloc (a, 1) .ne. 1) call abort()
+ if (maxloc (b, 1) .ne. 1) call abort()
+ if (maxloc (c, 1) .ne. 1) call abort()
+
+
+ ! We were giving MINLOC and MAXLOC the wrong return type
+ vc = (/4.0d0, 2.50d1, 1.0d1/)
+ i = minloc (vc)
+ if (i(1) .ne. 1) call abort()
+END PROGRAM
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc_3.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc_3.f90
new file mode 100644
index 00000000000..2e18a29bc16
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc_3.f90
@@ -0,0 +1,12 @@
+! Check we do the right thing with extreme values.
+! From PR12704
+program intrinsic_mmloc_3
+ integer, dimension(2) :: d
+ integer, dimension(2,2) :: a
+
+ d = -huge (d)
+ if (maxloc (d, 1) .ne. 1) call abort()
+ a = huge (a)
+ d = minloc (a)
+ if (any (d .ne. 1)) call abort()
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc_4.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc_4.f90
new file mode 100644
index 00000000000..2a53fb0124a
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmloc_4.f90
@@ -0,0 +1,13 @@
+! Check zero sized arrays work correcly
+! From PR12704
+program intrinsic_mmloc_4
+ integer, allocatable, dimension(:) :: d
+ integer, allocatable, dimension(:,:) :: a
+ integer, dimension(2) :: b
+
+ allocate (d(0))
+ if (maxloc (d, 1) .ne. 0) call abort()
+ allocate (a(1, 0))
+ b = minloc (a)
+ if (any (b .ne. 0)) call abort()
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmval.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmval.f90
new file mode 100644
index 00000000000..368c83ba133
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mmval.f90
@@ -0,0 +1,28 @@
+! Program to test the MINVAL and MAXVAL intrinsics
+program testmmval
+ implicit none
+ integer, dimension (3, 3) :: a
+ integer, dimension (3) :: b
+ logical, dimension (3, 3) :: m
+ integer i
+
+ a = reshape ((/1, 2, 3, 5, 4, 6, 9, 8, 7/), (/3, 3/));
+
+ b = minval (a, 1)
+ if (any(b .ne. (/1, 4, 7/))) call abort
+
+ m = .true.
+ m(1, 1) = .false.
+ m(1, 2) = .false.
+ b = minval (a, 1, m)
+ if (any(b .ne. (/2, 4, 7/))) call abort
+
+ b = maxval (a, 1)
+ if (any(b .ne. (/3, 6, 9/))) call abort
+
+ m = .true.
+ m(1, 2) = .false.
+ m(1, 3) = .false.
+ b = maxval (a, 1, m)
+ if (any(b .ne. (/3, 6, 8/))) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mod_ulo.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mod_ulo.f90
new file mode 100644
index 00000000000..7050c2ccd53
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mod_ulo.f90
@@ -0,0 +1,64 @@
+! Program to test MOD and MODULO intrinsics
+subroutine integertest (ops, res)
+ implicit none
+ integer, dimension(2) :: ops
+ integer, dimension(2) :: res
+
+ if ((mod(ops(1), ops(2)) .ne. res(1)) .or. &
+ (modulo(ops(1), ops(2)) .ne. res(2))) call abort
+end subroutine
+
+subroutine real4test (ops, res)
+ implicit none
+ real(kind=4), dimension(2) :: ops
+ real(kind=4), dimension(2) :: res
+
+ if (diff(mod(ops(1), ops(2)), res(1)) .or. &
+ diff(modulo(ops(1), ops(2)), res(2))) call abort
+contains
+function diff(a, b)
+ real(kind=4) :: a, b
+ logical diff
+
+ diff = (abs (a - b) .gt. abs(a * 1e-6))
+end function
+end subroutine
+
+subroutine real8test (ops, res)
+ implicit none
+ real(kind=8), dimension(2) :: ops
+ real(kind=8), dimension(2) :: res
+
+ if (diff(mod(ops(1), ops(2)), res(1)) .or. &
+ diff(modulo(ops(1), ops(2)), res(2))) call abort
+contains
+function diff(a, b)
+ real(kind=8) :: a, b
+ logical diff
+
+ diff = (abs(a - b) .gt. abs(a * 1e-6))
+end function
+end subroutine
+
+program mod_modulotest
+ implicit none
+
+ call integertest ((/8, 5/), (/3, 3/))
+ call integertest ((/-8, 5/), (/-3, 2/))
+ call integertest ((/8, -5/), (/3, -2/))
+ call integertest ((/-8, -5/), (/-3, -3/))
+
+ call real4test ((/3.0, 2.5/), (/0.5, 0.5/))
+ call real4test ((/-3.0, 2.5/), (/-0.5, 2.0/))
+ call real4test ((/3.0, -2.5/), (/0.5, -2.0/))
+ call real4test ((/-3.0, -2.5/), (/-0.5, -0.5/))
+
+ call real8test ((/3.0_8, 2.5_8/), (/0.5_8, 0.5_8/))
+ call real8test ((/-3.0_8, 2.5_8/), (/-0.5_8, 2.0_8/))
+ call real8test ((/3.0_8, -2.5_8/), (/0.5_8, -2.0_8/))
+ call real8test ((/-3.0_8, -2.5_8/), (/-0.5_8, -0.5_8/))
+
+ ! Check large numbers
+ call real4test ((/2e34, 1.0/), (/0.0, 0.0/))
+ call real4test ((/2e34, 1.5e34/), (/0.5e34, 0.5e34/))
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_nearest.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_nearest.f90
new file mode 100644
index 00000000000..99d802e6189
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_nearest.f90
@@ -0,0 +1,71 @@
+!Program to test NEAREST intrinsic function.
+
+program test_nearest
+ real s, r, x, y, inf, max, min
+ integer i, infi, maxi, mini
+ equivalence (s,i)
+ equivalence (inf,infi)
+ equivalence (max,maxi)
+ equivalence (min,mini)
+
+ r = 2.0
+ s = 3.0
+ call test_n (s, r)
+
+ i = z'00800000'
+ call test_n (s, r)
+
+ i = z'007fffff'
+ call test_n (s, r)
+
+ i = z'00800100'
+ call test_n (s, r)
+
+ s = 0
+ x = nearest(s, r)
+ y = nearest(s, -r)
+ if (.not. (x .gt. s .and. y .lt. s )) call abort()
+
+ infi = z'7f800000'
+ maxi = z'7f7fffff'
+ mini = 1
+
+ call test_up(max, inf)
+ call test_up(-inf, -max)
+ call test_up(0, min)
+ call test_up(-min, 0)
+
+ call test_down(inf, max)
+ call test_down(-max, -inf)
+ call test_down(0, -min)
+ call test_down(min, 0)
+end
+
+subroutine test_up(s, e)
+ real s, e, x
+
+ x = nearest(s, 1.0)
+ if (x .ne. e) call abort()
+end
+
+subroutine test_down(s, e)
+ real s, e, x
+
+ x = nearest(s, -1.0)
+ if (x .ne. e) call abort()
+end
+
+subroutine test_n(s1, r)
+ real r, s1, x
+
+ x = nearest(s1, r)
+ if (nearest(x, -r) .ne. s1) call abort()
+ x = nearest(s1, -r)
+ if (nearest(x, r) .ne. s1) call abort()
+
+ s1 = -s1
+ x = nearest(s1, r)
+ if (nearest(x, -r) .ne. s1) call abort()
+ x = nearest(s1, -r)
+ if (nearest(x, r) .ne. s1) call abort()
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_pack.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_pack.f90
new file mode 100644
index 00000000000..565446e4e8b
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_pack.f90
@@ -0,0 +1,12 @@
+! Program to test the PACK intrinsic
+program intrinsic_pack
+ integer, dimension(3, 3) :: a
+ integer, dimension(6) :: b
+
+ a = reshape ((/0, 0, 0, 0, 9, 0, 0, 0, 7/), (/3, 3/))
+ b = 0
+ b(1:6:3) = pack (a, a .ne. 0);
+ if (any (b(1:6:3) .ne. (/9, 7/))) call abort
+ b = pack (a(2:3, 2:3), a(2:3, 2:3) .ne. 0, (/1, 2, 3, 4, 5, 6/));
+ if (any (b .ne. (/9, 7, 3, 4, 5, 6/))) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_present.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_present.f90
new file mode 100644
index 00000000000..d2e9981353d
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_present.f90
@@ -0,0 +1,40 @@
+! Program to test the PRESENT intrinsic
+program intrinsic_present
+ implicit none
+ integer a
+ integer, pointer :: b
+ integer, dimension(10) :: c
+ integer, pointer, dimension(:) :: d
+
+ if (testvar()) call abort ()
+ if (.not. testvar(a)) call abort ()
+ if (testptr()) call abort ()
+ if (.not. testptr(b)) call abort ()
+ if (testarray()) call abort ()
+ if (.not. testarray(c)) call abort ()
+ if (testparray()) call abort ()
+ if (.not. testparray(d)) call abort ()
+
+contains
+logical function testvar (p)
+ integer, optional :: p
+ testvar = present(p)
+end function
+
+logical function testptr (p)
+ integer, pointer, optional :: p
+ testptr = present(p)
+end function
+
+logical function testarray (p)
+ integer, dimension (10), optional :: p
+ testarray = present(p)
+end function
+
+logical function testparray (p)
+ integer, pointer, dimension(:), optional :: p
+ testparray = present(p)
+end function
+
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_product.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_product.f90
new file mode 100644
index 00000000000..102832c9f9b
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_product.f90
@@ -0,0 +1,25 @@
+! Program to test the PRODUCT intrinsic
+program testproduct
+ implicit none
+ integer, dimension (3, 3) :: a
+ integer, dimension (3) :: b
+ logical, dimension (3, 3) :: m
+
+ a = reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9/), (/3, 3/));
+
+ b = product (a, 1)
+
+ if (any(b .ne. (/6, 120, 504/))) call abort
+
+ if (product (a) .ne. 362880) call abort
+
+ m = .true.
+ m(1, 1) = .false.
+ m(2, 1) = .false.
+ b = product (a, 2, m)
+
+ if (any(b .ne. (/28, 40, 162/))) call abort
+
+ if (product (a, mask=m) .ne. 181440) call abort
+
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_rrspacing.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_rrspacing.f90
new file mode 100644
index 00000000000..0f411a633b2
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_rrspacing.f90
@@ -0,0 +1,27 @@
+!Program to test RRSPACING intrinsic function.
+
+program test_rrspacing
+ call test_real4(3.0)
+ call test_real4(33.0)
+ call test_real4(-3.0)
+ call test_real8(3.0_8)
+ call test_real8(33.0_8)
+ call test_real8(-33.0_8)
+end
+subroutine test_real4(x)
+ real x,y
+ integer p
+ p = 24
+ y = abs (x * 2.0 ** (- exponent (x))) * (2.0 ** p)
+ x = rrspacing(x)
+ if (abs (x - y) .gt. abs(x * 1e-6)) call abort
+end
+
+subroutine test_real8(x)
+ real*8 x,y,t
+ integer p
+ p = 53
+ y = abs (x * 2.0 ** (- exponent (x))) * (2.0 ** p)
+ x = rrspacing(x)
+ if (abs (x - y) .gt. abs(x * 1e-6)) call abort
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_scale.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_scale.f90
new file mode 100644
index 00000000000..df483811415
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_scale.f90
@@ -0,0 +1,27 @@
+!Program to test SCALE intrinsic function.
+
+program test_scale
+ call test_real4 (3.0, 2)
+ call test_real4 (33.0, -2)
+ call test_real4 (-3., 2)
+ call test_real4 (0, 3)
+ call test_real8 (0, 3)
+ call test_real8 (3.0_8, 4)
+ call test_real8 (33.0_8, -4)
+ call test_real8 (-33._8, 4)
+end
+subroutine test_real4 (x, i)
+ real x,y
+ integer i
+ y = x * (2.0 ** i)
+ x = scale (x, i)
+ if (abs (x - y) .gt. abs(x * 1e-6)) call abort
+end
+
+subroutine test_real8 (x, i)
+ real*8 x,y
+ integer i
+ y = x * (2.0 ** i)
+ x = scale (x, i)
+ if (abs (x - y) .gt. abs(x * 1e-6)) call abort
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_set_exponent.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_set_exponent.f90
new file mode 100644
index 00000000000..da84ea7d723
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_set_exponent.f90
@@ -0,0 +1,91 @@
+!Program to test SET_EXPONENT intrinsic function.
+
+program test_set_exponent
+ call test_real4()
+ call test_real8()
+end
+subroutine test_real4()
+ real x,y
+ integer i,n
+ equivalence(x,i)
+
+ n = -148
+ x = 1024.0
+ y = set_exponent (x, n)
+ if (exponent (y) .ne. n) call abort()
+
+ n = 8
+ x = 1024.0
+ y = set_exponent (x, n)
+ if (exponent (y) .ne. n) call abort()
+
+ n = 128
+ i = o'00037777777'
+ y = set_exponent (x, n)
+ if (exponent (y) .ne. n) call abort()
+
+ n = -148
+ x = -1024.0
+ y = set_exponent (x, n)
+ if (exponent (y) .ne. n) call abort()
+
+ n = 8
+ x = -1024.0
+ y = set_exponent (x, n)
+ if (y .ne. -128.0) call abort()
+ if (exponent (y) .ne. n) call abort()
+
+ n = 128
+ i = o'20037777777'
+ y = set_exponent (x, n)
+ if (exponent (y) .ne. n) call abort()
+
+end
+
+subroutine test_real8()
+ implicit none
+ real*8 x, y
+ integer*8 i, n, low
+ equivalence(x, i)
+
+ n = -1073
+ x = 1024.0_8
+ y = set_exponent (x, n)
+ if (exponent (y) .ne. n) call abort()
+
+ n = 8
+ x = 1024.0_8
+ y = set_exponent (x, n)
+ if (y .ne. 128.0) call abort()
+ if (exponent (y) .ne. n) call abort()
+
+ n = 1024
+ low = z'ffffffff'
+ i = z'000fffff'
+ i = ishft (i, 32) + low !'000fffffffffffff'
+ y = set_exponent (x, n)
+ low = z'fffffffe'
+ i = z'7fefffff'
+ i = ishft (i, 32) + low
+ if (exponent (y) .ne. n) call abort()
+
+ n = -1073
+ x = -1024.0
+ y = set_exponent (x, n)
+ low = z'00000001'
+ if (exponent (y) .ne. n) call abort()
+
+ n = 8
+ x = -1024.0
+ y = set_exponent (x, n)
+ if (y .ne. -128.0) call abort()
+ if (exponent (y) .ne. n) call abort()
+
+ n = 1024
+ low = z'ffffffff'
+ i = z'800fffff'
+ i = ishft (i, 32) + low !z'800fffffffffffff'
+ y = set_exponent (x, n)
+ if (exponent (y) .ne. n) call abort()
+
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_shape.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_shape.f90
new file mode 100644
index 00000000000..e1c5f7b4ba1
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_shape.f90
@@ -0,0 +1,22 @@
+! Program to test the shape intrinsic
+program testbounds
+ implicit none
+ real, dimension(:, :), allocatable :: a
+ integer, dimension(2) :: j
+ integer i
+
+ allocate (a(3:8, 6:7))
+
+ j = shape (a);
+ if (any (j .ne. (/ 6, 2 /))) call abort
+
+ call test(a)
+contains
+
+subroutine test (a)
+ real, dimension (1:, 1:) :: a
+
+ if (any (shape (a) .ne. (/ 6, 2 /))) call abort
+end subroutine
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_si_kind.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_si_kind.f90
new file mode 100644
index 00000000000..b231dc66ebe
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_si_kind.f90
@@ -0,0 +1,35 @@
+! Program to test SELECTED_INT_KIND intrinsic function.
+Program test_si_kind
+ integer*1 i1
+ integer*2 i2
+ integer*4 i4
+ integer*8 i8
+ integer res
+ real t
+
+ t = huge (i1)
+ t = log10 (t)
+ res = selected_int_kind (int (t))
+ if (res .ne. 1) call abort
+
+ t = huge (i2)
+ t = log10 (t)
+ res = selected_int_kind (int (t))
+ if (res .ne. 2) call abort
+
+ t = huge (i4)
+ t = log10 (t)
+ res = selected_int_kind (int (t))
+ if (res .ne. 4) call abort
+
+ t = huge (i8)
+ t = log10 (t)
+ res = selected_int_kind (int (t))
+ if (res .ne. 8) call abort
+
+ i4 = huge (i4)
+ res = selected_int_kind (i4)
+ if (res .ne. (-1)) call abort
+
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_sign.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_sign.f90
new file mode 100644
index 00000000000..fbc457d917c
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_sign.f90
@@ -0,0 +1,31 @@
+! Program to test SIGN intrinsic
+program intrinsic_sign
+ implicit none
+ integer i, j
+ real r, s
+
+ i = 2
+ j = 3
+ if (sign (i, j) .ne. 2) call abort
+ i = 4
+ j = -5
+ if (sign (i, j) .ne. -4) call abort
+ i = -6
+ j = 7
+ if (sign (i, j) .ne. 6) call abort
+ i = -8
+ j = -9
+ if (sign (i, j) .ne. -8) call abort
+ r = 1
+ s = 2
+ if (sign (r, s) .ne. 1) call abort
+ r = 1
+ s = -2
+ if (sign (r, s) .ne. -1) call abort
+ s = 0
+ if (sign (r, s) .ne. 1) call abort
+ ! Will fail on machines which cannot represent negative zero.
+ s = -s ! Negative zero
+ if (sign (r, s) .ne. -1) call abort
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_size.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_size.f90
new file mode 100644
index 00000000000..729c55f2283
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_size.f90
@@ -0,0 +1,37 @@
+! Program to test the SIZE intrinsics
+program testsize
+ implicit none
+ real, dimension(:, :), allocatable :: a
+ integer, dimension(5) :: j
+ integer, dimension(2, 3) :: b
+ integer i
+
+ if (size (b(2, :), 1) .ne. 3) call abort
+
+ allocate (a(3:8, 5:7))
+
+ ! With one parameter
+ if (size(a) .ne. 18) call abort
+
+ ! With two parameters, assigning to an array
+ j = size(a, 1)
+ if (any (j .ne. (/6, 6, 6, 6, 6/))) call abort
+
+ ! With a variable second parameter
+ i = 2
+ i = size(a, i)
+ if (i .ne. 3) call abort
+
+ call test(a)
+contains
+
+subroutine test (a)
+ real, dimension (1:, 1:) :: a
+ integer i
+
+ i = 2
+ if ((size(a, 1) .ne. 6) .or. (size(a, i) .ne. 3)) call abort
+ if (size (a) .ne. 18 ) call abort
+end subroutine
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_spacing.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_spacing.f90
new file mode 100644
index 00000000000..4fac9f1b303
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_spacing.f90
@@ -0,0 +1,33 @@
+!Program to test SPACING intrinsic function.
+
+program test_spacing
+ call test_real4(3.0)
+ call test_real4(33.0)
+ call test_real4(-3.)
+ call test_real4(0)
+ call test_real8(0)
+ call test_real8(3.0_8)
+ call test_real8(33.0_8)
+ call test_real8(-33._8)
+end
+subroutine test_real4(x)
+ real x,y,t
+ integer p
+ p = 24
+ y = 2.0 ** (exponent (x) - p)
+ t = tiny(x)
+ x = spacing(x)
+ if ((abs (x - y) .gt. abs(x * 1e-6)) &
+ .and. (abs (x - t) .gt. abs(x * 1e-6)))call abort
+end
+
+subroutine test_real8(x)
+ real*8 x,y,t
+ integer p
+ p = 53
+ y = 2.0 ** (exponent (x) - p)
+ t = tiny (x)
+ x = spacing(x)
+ if ((abs (x - y) .gt. abs(x * 1e-6)) &
+ .and. (abs (x - t) .gt. abs(x * 1e-6)))call abort
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_spread.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_spread.f90
new file mode 100644
index 00000000000..50b66ff6c2b
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_spread.f90
@@ -0,0 +1,10 @@
+program foo
+ integer, dimension (2, 3) :: a
+ integer, dimension (2, 2, 3) :: b
+
+ a = reshape ((/1, 2, 3, 4, 5, 6/), (/2, 3/))
+ b = spread (a, 1, 2)
+ if (any (b .ne. reshape ((/1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6/), &
+ (/2, 2, 3/)))) &
+ call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_sr_kind.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_sr_kind.f90
new file mode 100644
index 00000000000..fe2f978197d
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_sr_kind.f90
@@ -0,0 +1,61 @@
+! Program to test SELECTED_REAL_KIND intrinsic function.
+Program test_sr_kind
+ integer res, i4, i8, t
+ real*4 r4
+ real*8 r8
+
+ i4 = int (log10 (huge (r4)))
+ t = - int (log10 (tiny (r4)))
+ if (i4 .gt. t) i4 = t
+
+ i8 = int (log10 (huge (r8)))
+ t = - int (log10 (tiny (r8)))
+ if (i8 .gt. t) i8 = t
+
+ res = selected_real_kind (r = i4)
+ if (res .ne. 4) call abort
+
+ res = selected_real_kind (r = i8)
+ if (res .ne. 8) call abort
+
+ res = selected_real_kind (r = (i8 + 1))
+ if (res .ne. -2) call abort
+
+ res = selected_real_kind (p = precision (r4))
+ if (res .ne. 4) call abort
+
+ res = selected_real_kind (p = precision (r4), r = i4)
+ if (res .ne. 4) call abort
+
+ res = selected_real_kind (p = precision (r4), r = i8)
+ if (res .ne. 8) call abort
+
+ res = selected_real_kind (p = precision (r4), r = i8 + 1)
+ if (res .ne. -2) call abort
+
+ res = selected_real_kind (p = precision (r8))
+ if (res .ne. 8) call abort
+
+ res = selected_real_kind (p = precision (r8), r = i4)
+ if (res .ne. 8) call abort
+
+ res = selected_real_kind (p = precision (r8), r = i8)
+ if (res .ne. 8) call abort
+
+ res = selected_real_kind (p = precision (r8), r = i8 + 1)
+ if (res .ne. -2) call abort
+
+ res = selected_real_kind (p = (precision (r8) + 1))
+ if (res .ne. -1) call abort
+
+ res = selected_real_kind (p = (precision (r8) + 1), r = i4)
+ if (res .ne. -1) call abort
+
+ res = selected_real_kind (p = (precision (r8) + 1), r = i8)
+ if (res .ne. -1) call abort
+
+ res = selected_real_kind (p = (precision (r8) + 1), r = i8 + 1)
+ if (res .ne. -3) call abort
+
+end
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_sum.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_sum.f90
new file mode 100644
index 00000000000..43f832ec63c
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_sum.f90
@@ -0,0 +1,26 @@
+! Program to test the FORALL construct
+program testforall
+ implicit none
+ integer, dimension (3, 3) :: a
+ integer, dimension (3) :: b
+ logical, dimension (3, 3) :: m
+ integer i
+
+ a = reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9/), (/3, 3/));
+
+ if (sum(a) .ne. 45) call abort
+ b = sum (a, 1)
+ if (b(1) .ne. 6) call abort
+ if (b(2) .ne. 15) call abort
+ if (b(3) .ne. 24) call abort
+
+ m = .true.
+ m(1, 1) = .false.
+ m(2, 1) = .false.
+
+ if (sum (a, mask=m) .ne. 42) call abort
+ b = sum (a, 2, m)
+ if (b(1) .ne. 11) call abort
+ if (b(2) .ne. 13) call abort
+ if (b(3) .ne. 18) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_transpose.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_transpose.f90
new file mode 100644
index 00000000000..e1f268e310d
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_transpose.f90
@@ -0,0 +1,24 @@
+! Program to test the transpose intrinsic
+program intrinsic_transpose
+ integer, dimension (3, 3) :: a, b
+ complex(kind=8), dimension (2, 2) :: c, d
+ complex(kind=4), dimension (2, 2) :: e
+
+ a = 0
+ b = reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9/), (/3, 3/))
+ a = transpose (b)
+ if (any (a .ne. reshape ((/1, 4, 7, 2, 5, 8, 3, 6, 9/), (/3, 3/)))) &
+ call abort
+ c = (0.0, 0.0)
+ d = reshape ((/(1d0,2d0), (3d0, 4d0), (5d0, 6d0), (7d0, 8d0)/), (/2, 2/))
+ c = transpose (d);
+ if (any (c .ne. reshape ((/(1d0, 2d0), (5d0, 6d0), &
+ (3d0, 4d0), (7d0, 8d0)/), (/2, 2/)))) &
+ call abort ();
+
+ e = reshape ((/(1.0,2.0), (3.0, 4.0), (5.0, 6.0), (7.0, 8.0)/), (/2, 2/))
+ e = transpose (e);
+ if (any (e .ne. reshape ((/(1.0, 2.0), (5.0, 6.0), &
+ (3.0, 4.0), (7.0, 8.0)/), (/2, 2/)))) &
+ call abort ();
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_trim.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_trim.f90
new file mode 100644
index 00000000000..90e4131685a
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_trim.f90
@@ -0,0 +1,23 @@
+! Program to test the TRIM and REPEAT intrinsics.
+program intrinsic_trim
+ character(len=8) a
+ character(len=4) b,work
+ a='1234 '
+ b=work(9,a)
+ if (llt(b,"1234")) call abort()
+ a=' '
+ b=trim(a)
+ if (b .gt. "") call abort()
+ b='12'
+ a=repeat(b,0)
+ if (a .gt. "") call abort()
+ a=repeat(b,2)
+ if (a .ne. "12 12 ") call abort()
+end
+
+function work(i,a)
+ integer i
+ character(len=i) a
+ character(len=4) work
+ work = trim(a)
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_unpack.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_unpack.f90
new file mode 100644
index 00000000000..807aadf136f
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_unpack.f90
@@ -0,0 +1,17 @@
+! Program to test the UNPACK intrinsic
+program intrinsic_unpack
+ integer, dimension(3, 3) :: a, b
+ logical, dimension(3, 3) :: mask;
+ integer i
+
+ mask = reshape ((/.false.,.true.,.false.,.true.,.false.,.false.,&
+ &.false.,.false.,.true./), (/3, 3/));
+ a = reshape ((/1, 0, 0, 0, 1, 0, 0, 0, 1/), (/3, 3/));
+ b = unpack ((/2, 3, 4/), mask, a)
+ if (any (b .ne. reshape ((/1, 2, 0, 3, 1, 0, 0, 0, 4/), (/3, 3/)))) &
+ call abort
+ b = -1
+ b = unpack ((/2, 3, 4/), mask, 0)
+ if (any (b .ne. reshape ((/0, 2, 0, 3, 0, 0, 0, 0, 4/), (/3, 3/)))) &
+ call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/list_read_1.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/list_read_1.f90
new file mode 100644
index 00000000000..040ae72d8e0
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/list_read_1.f90
@@ -0,0 +1,53 @@
+! pr 14942, list directed io
+ program d
+ implicit none
+ integer i, j, m, n, nin, k
+ real x(3,4)
+ data x / 1,1,1,2,2,2,3,3,3,4,4,4 /
+ real y(3,4)
+ data y / 1,1,1,2,2,2,3,3,3,4,4,4 /
+ logical debug ! set me true to see the output
+ debug = .FALSE.
+ nin = 1
+ n = 4
+ open(unit = nin)
+ write(nin,*) n
+ do I = 1,3
+ write(nin,*)(x(i,j), j=1, n)
+ end do
+ m = 3
+ n = 4
+ write(nin,*) m,n
+ do I = 1,3
+ write(nin,*)(x(i,j), j=1, n)
+ enddo
+ close(nin)
+! ok, the data file is written
+ open(unit = nin)
+ read(nin, fmt = *) n
+ if (debug ) write(*,'(A,I2)') 'n = ', n
+ do i = 1, 3
+ do K = 1,n
+ x(i,k) = -1
+ enddo
+ read(nin, fmt = *) (x(i,j), j=1, n)
+ if (debug) write(*, *) (x(i,j), j=1, n)
+ do K = 1,n
+ if (x(i,k).ne.y(i,k)) call abort
+ end do
+ end do
+ m = 0
+ n = 0
+ read(nin, fmt = *) m, n
+ if (debug) write(*,'(A,I2,2X,A,I2)') 'm = ', m, 'n = ', n
+ do i = 1, m
+ do K = 1,n
+ x(i,k) = -1
+ enddo
+ read(nin, fmt = *) (x(i,j), j=1, n)
+ if (debug) write(*, *) (x(i,j), j=1, n)
+ do K = 1,n
+ if (x(i,k).ne.y(i,k)) call abort
+ end do
+ end do
+ end program d
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/logical_select_1.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/logical_select_1.f90
new file mode 100644
index 00000000000..60c077c4347
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/logical_select_1.f90
@@ -0,0 +1,55 @@
+LOGICAL :: L = .FALSE.
+
+SELECT CASE (L)
+ CASE (.TRUE.)
+ CALL abort
+ CASE (.FALSE.)
+ CONTINUE
+ CASE DEFAULT
+ CALL abort
+END SELECT
+
+SELECT CASE (L)
+ CASE (.TRUE., .FALSE.)
+ CONTINUE
+ CASE DEFAULT
+ CALL abort
+END SELECT
+
+SELECT CASE (L)
+ CASE (.FALSE.)
+ CONTINUE
+ CASE DEFAULT
+ CALL abort
+END SELECT
+
+SELECT CASE (L)
+ CASE (.NOT. .TRUE.)
+ CONTINUE
+ CASE DEFAULT
+ CALL abort
+END SELECT
+
+SELECT CASE (.NOT. L)
+ CASE (.TRUE.)
+ CONTINUE
+ CASE DEFAULT
+ CALL abort
+END SELECT
+
+SELECT CASE (Truth_or_Dare() .OR. L)
+ CASE (.TRUE.)
+ CONTINUE
+ CASE DEFAULT
+ CALL abort
+END SELECT
+
+CONTAINS
+
+ FUNCTION Truth_or_Dare ()
+ LOGICAL Truth_or_Dare
+ Truth_or_Dare = .TRUE.
+ END FUNCTION
+
+END
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/mainsub.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/mainsub.f90
new file mode 100644
index 00000000000..f84e91f2525
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/mainsub.f90
@@ -0,0 +1,17 @@
+! Program to test compilation of subroutines following the main program
+program mainsub
+ implicit none
+ integer i
+ external test
+
+ i = 0
+ call test (i)
+ if (i .ne. 42) call abort
+end program
+
+subroutine test (p)
+ implicit none
+ integer p
+
+ p = 42
+end subroutine
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/math.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/math.f90
new file mode 100644
index 00000000000..4f54dcfc7fb
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/math.f90
@@ -0,0 +1,100 @@
+! Program to test mathematical intrinsics
+subroutine dotest (n, val4, val8, known)
+ implicit none
+ real(kind=4) val4, known
+ real(kind=8) val8
+ integer n
+
+ if (abs (val4 - known) .gt. 0.001) call abort
+ if (abs (real (val8, kind=4) - known) .gt. 0.001) call abort
+end subroutine
+
+subroutine dotestc (n, val4, val8, known)
+ implicit none
+ complex(kind=4) val4, known
+ complex(kind=8) val8
+ integer n
+ if (abs (val4 - known) .gt. 0.001) call abort
+ if (abs (cmplx (val8, kind=4) - known) .gt. 0.001) call abort
+end subroutine
+
+program testmath
+ implicit none
+ real(kind=4) r, two4, half4
+ real(kind=8) q, two8, half8
+ complex(kind=4) cr
+ complex(kind=8) cq
+ external dotest, dotest2
+
+ two4 = 2.0
+ two8 = 2.0_8
+ half4 = 0.5
+ half8 = 0.5_8
+ r = sin (two4)
+ q = sin (two8)
+ call dotest (1, r, q, 0.9093)
+ r = cos (two4)
+ q = cos (two8)
+ call dotest (2, r, q, -0.4161)
+ r = tan (two4)
+ q = tan (two8)
+ call dotest (3, r, q, -2.1850)
+ r = asin (half4)
+ q = asin (half8)
+ call dotest (4, r, q, 0.5234)
+ r = acos (half4)
+ q = acos (half8)
+ call dotest (5, r, q, 1.0472)
+ r = atan (half4)
+ q = atan (half8)
+ call dotest (6, r, q, 0.4636)
+ r = atan2 (two4, half4)
+ q = atan2 (two8, half8)
+ call dotest (7, r, q, 1.3258)
+ r = exp (two4)
+ q = exp (two8)
+ call dotest (8, r, q, 7.3891)
+ r = log (two4)
+ q = log (two8)
+ call dotest (9, r, q, 0.6931)
+ r = log10 (two4)
+ q = log10 (two8)
+ call dotest (10, r, q, 0.3010)
+ r = sinh (two4)
+ q = sinh (two8)
+ call dotest (11, r, q, 3.6269)
+ r = cosh (two4)
+ q = cosh (two8)
+ call dotest (12, r, q, 3.7622)
+ r = tanh (two4)
+ q = tanh (two8)
+ call dotest (13, r, q, 0.9640)
+ r = sqrt (two4)
+ q = sqrt (two8)
+ call dotest (14, r, q, 1.4142)
+
+ r = atan2 (0.0, 1.0)
+ q = atan2 (0.0_8, 1.0_8)
+ call dotest (15, r, q, 0.0)
+ r = atan2 (-1.0, 1.0)
+ q = atan2 (-1.0_8, 1.0_8)
+ call dotest (16, r, q, -0.7854)
+ r = atan2 (0.0, -1.0)
+ q = atan2 (0.0_8, -1.0_8)
+ call dotest (17, r, q, 3.1416)
+ r = atan2 (-1.0, -1.0)
+ q = atan2 (-1.0_8, -1.0_8)
+ call dotest (18, r, q, -2.3562)
+ r = atan2 (1.0, 0.0)
+ q = atan2 (1.0_8, 0.0_8)
+ call dotest (19, r, q, 1.5708)
+ r = atan2 (-1.0, 0.0)
+ q = atan2 (-1.0_8, 0.0_8)
+ call dotest (20, r, q, -1.5708)
+
+ cr = log ((-1.0, -1.0))
+ cq = log ((-1.0_8, -1.0_8))
+ call dotestc (21, cr, cq, (0.3466, -2.3562))
+
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/module_interface.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/module_interface.f90
new file mode 100644
index 00000000000..86fd7914b4d
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/module_interface.f90
@@ -0,0 +1,39 @@
+! We were incorrectly mangling procedures in interfaces in modules
+
+module module_interface
+ interface
+ subroutine foo ()
+ end subroutine foo
+ end interface
+contains
+subroutine cs
+end subroutine
+
+subroutine cproc
+ interface
+ subroutine bar ()
+ end subroutine
+ end interface
+ call bar ()
+ call foo ()
+ call cs ()
+end subroutine
+end module
+
+subroutine foo ()
+end subroutine
+
+subroutine bar ()
+end subroutine
+
+program module_interface_proc
+ use module_interface
+ interface
+ subroutine bar ()
+ end subroutine
+ end interface
+
+ call cproc ()
+ call foo ()
+ call bar ()
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/module_interface_2.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/module_interface_2.f90
new file mode 100644
index 00000000000..dba736654c4
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/module_interface_2.f90
@@ -0,0 +1,29 @@
+! Test generic interfaces declared in modules.
+! We used to get the name mangling wrong for these.
+module module_interface_2
+ interface foo
+ subroutine myfoo (i)
+ integer i
+ end subroutine
+ module procedure bar
+ end interface
+contains
+subroutine bar (r)
+ real r
+
+ if (r .ne. 1.0) call abort ()
+end subroutine
+end module
+
+subroutine myfoo (i)
+ integer i
+
+ if (i .ne. 42) call abort ()
+end subroutine
+
+program test
+ use module_interface_2
+
+ call foo (42)
+ call foo (1.0)
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/mystery_proc.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/mystery_proc.f90
new file mode 100644
index 00000000000..06fa21614ed
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/mystery_proc.f90
@@ -0,0 +1,23 @@
+! Program to test dummy procedures
+subroutine bar()
+end subroutine
+
+subroutine foo2(p)
+ external p
+
+ call p()
+end subroutine
+
+subroutine foo(p)
+ external p
+ ! We never actually discover if this is a function or a subroutine
+ call foo2(p)
+end subroutine
+
+program intrinsic_minmax
+ implicit none
+ external bar
+
+ call foo(bar)
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/nestcons.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/nestcons.f90
new file mode 100644
index 00000000000..d2d54562503
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/nestcons.f90
@@ -0,0 +1,9 @@
+! Program to test array expressions in array constructors.
+program nestcons
+ implicit none
+ integer, parameter :: w1(3)= (/ 5, 6, 7/)
+ integer, dimension(6) :: w2
+
+ w2 = (/ 1, 2, w1(3:1:-1), 3 /)
+ if (any (w2 .ne. (/ 1, 2, 7, 6, 5, 3/))) call abort
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/parameter_1.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/parameter_1.f90
new file mode 100644
index 00000000000..8a8af73851d
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/parameter_1.f90
@@ -0,0 +1,12 @@
+! Program to test array parameter variables.
+program parameter_1
+ implicit none
+ integer i
+ INTEGER, PARAMETER :: ii(10) = (/ (I,I=1,10) /)
+ REAL, PARAMETER :: rr(10) = ii
+
+ do i = 1, 10
+ if (ii(i) /= i) call abort()
+ if (rr(i) /= i) call abort()
+ end do
+end program parameter_1
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/partparm.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/partparm.f90
new file mode 100644
index 00000000000..839ecf02f69
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/partparm.f90
@@ -0,0 +1,15 @@
+! Program to test
+subroutine test (p)
+ integer, dimension (3) :: p
+
+ if (any (p .ne. (/ 2, 4, 6/))) call abort
+end subroutine
+
+program partparm
+ implicit none
+ integer, dimension (2, 3) :: a
+ external test
+
+ a = reshape ((/ 1, 2, 3, 4, 5, 6/), (/ 2, 3/))
+ call test (a(2, :))
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/plusconst_1.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/plusconst_1.f90
new file mode 100644
index 00000000000..7fc3eebb15b
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/plusconst_1.f90
@@ -0,0 +1,15 @@
+! PR14005
+! The GMP conversion routines object to a leading "+"
+program plusconst_1
+ implicit none
+ real p
+ integer i
+ data p /+3.1415/
+ data i /+42/
+ real :: q = +1.234
+ integer :: j = +100
+
+ if ((p .ne. 3.1415) .or. (i .ne. 42) .or. (q .ne. 1.234) .or. (j .ne. 100)) &
+ call abort
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/power.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/power.f90
new file mode 100644
index 00000000000..91ddc73d3e4
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/power.f90
@@ -0,0 +1,43 @@
+! Program to test the power (**) operator
+program testpow
+ implicit none
+ real(kind=4) r, s, two
+ real(kind=8) :: q
+ complex(kind=4) :: c
+ real, parameter :: del = 0.0001
+ integer i
+
+ two = 2.0
+
+ r = two ** 1
+ if (abs (r - 2.0) .gt. del) call abort
+ r = two ** 2
+ if (abs (r - 4.0) .gt. del) call abort
+ r = two ** 3
+ if (abs (r - 8.0) .gt. del) call abort
+ r = two ** 4
+ if (abs (r - 16.0) .gt. del) call abort
+ r = two ** 0
+ if (abs (r - 1.0) .gt. del) call abort
+ r = two ** (-1)
+ if (abs (r - 0.5) .gt. del) call abort
+ r = two ** (-2)
+ if (abs (r - 0.25) .gt. del) call abort
+ r = two ** (-4)
+ if (abs (r - 0.0625) .gt. del) call abort
+ s = 3.0
+ r = two ** s
+ if (abs (r - 8.0) .gt. del) call abort
+ s = -3.0
+ r = two ** s
+ if (abs (r - 0.125) .gt. del) call abort
+ i = 3
+ r = two ** i
+ if (abs (r - 8.0) .gt. del) call abort
+ i = -3
+ r = two ** i
+ if (abs (r - 0.125) .gt. del) call abort
+ c = (2.0, 3.0)
+ c = c ** two
+ if (abs(c - (-5.0, 12.0)) .gt. del) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/procarg.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/procarg.f90
new file mode 100644
index 00000000000..37718f5fc43
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/procarg.f90
@@ -0,0 +1,29 @@
+! Pogram to test
+subroutine myp (a)
+ implicit none
+ integer a
+
+ if (a .ne. 42) call abort
+end subroutine
+
+subroutine test2 (p)
+ implicit none
+ external p
+
+ call p(42)
+end subroutine
+
+subroutine test (p)
+ implicit none
+ external p, test2
+
+ call p(42)
+ call test2(p)
+end subroutine
+
+program arrayio
+ implicit none
+ external test, myp
+
+ call test (myp)
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/ptr.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/ptr.f90
new file mode 100644
index 00000000000..2675f0866c2
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/ptr.f90
@@ -0,0 +1,20 @@
+program ptr
+ implicit none
+ integer, pointer, dimension(:) :: a, b
+ integer, pointer :: p
+ integer, target :: i
+
+ allocate (a(1:6))
+
+ a = (/ 1, 2, 3, 4, 5, 6 /)
+ b => a
+ if (any (b .ne. (/ 1, 2, 3, 4, 5, 6 /))) call abort
+ b => a(1:6:2)
+ if (any (b .ne. (/ 1, 3, 5/))) call abort
+
+ p => i
+ i = 42
+ if (p .ne. 42) call abort
+ p => a(4)
+ if (p .ne. 4) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/random_init.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/random_init.f90
new file mode 100644
index 00000000000..36394589d8b
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/random_init.f90
@@ -0,0 +1,11 @@
+! pr 15149
+! verify the random number generator is functional
+ program test_random
+ implicit none
+ real :: r(5) = 0.0
+
+ call random_number(r)
+ if (all (r .eq. 0)) call abort
+ end program
+
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/read_eof.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/read_eof.f90
new file mode 100644
index 00000000000..92e454025b5
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/read_eof.f90
@@ -0,0 +1,5 @@
+! PR 13919, segfault when file is empty
+ open(unit=8,file='/dev/null')
+ read(8,*,end=1)i
+1 continue
+ end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/retarray.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/retarray.f90
new file mode 100644
index 00000000000..a0bdc97c47d
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/retarray.f90
@@ -0,0 +1,45 @@
+! Program to test functions returning arrays
+
+program testfnarray
+ implicit none
+ integer, dimension (6, 5) :: a
+ integer n
+
+! These first two shouldn't require a temporary.
+ a = 0
+ a = test(6, 5)
+ if (a(1,1) .ne. 42) call abort
+ if (a(6,5) .ne. 43) call abort
+
+ a = 0
+ a(1:6:2, 2:5) = test2()
+ if (a(1,2) .ne. 42) call abort
+ if (a(5,5) .ne. 43) call abort
+
+ a = 1
+ ! This requires a temporary
+ a = test(6, 5) - a
+ if (a(1,1) .ne. 41) call abort
+ if (a(6,5) .ne. 42) call abort
+
+ contains
+
+ function test (x, y)
+ implicit none
+ integer x, y
+ integer, dimension (1:x, 1:y) :: test
+
+ test(1, 1) = 42
+ test(x, y) = 43
+ end function
+
+ function test2 () result (foo)
+ implicit none
+ integer, dimension (3, 4) :: foo
+
+ foo(1, 1) = 42
+ foo(3, 4) = 43
+ end function
+
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/retarray_2.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/retarray_2.f90
new file mode 100644
index 00000000000..ab14dd03caf
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/retarray_2.f90
@@ -0,0 +1,20 @@
+! Procedure to test module procedures returning arrays.
+! The array spec only gets applied to the result variable, not the function
+! itself. As a result we missed it during resolution, and used the wrong
+! calling convention (functions returning arrays must always have explicit
+! interfaces).
+module retarray_2
+contains
+ function z(a) result (aout)
+ integer, dimension(4) :: aout,a
+ aout = a
+ end function z
+end module retarray_2
+
+program retarray
+ use retarray_2
+ integer, dimension(4) :: b, a=(/1,2,3,4/)
+ b = z(a)
+ if (any (b .ne. (/1, 2, 3, 4/))) call abort
+end
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/scalarize.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/scalarize.f90
new file mode 100644
index 00000000000..63004c82797
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/scalarize.f90
@@ -0,0 +1,23 @@
+! Program to test the scalarizer
+program testarray
+ implicit none
+ integer, dimension (6, 5) :: a, b
+ integer n
+
+ a = 0
+ do n = 1, 5
+ a(4, n) = n
+ end do
+
+ b(:, 5:1:-1) = a
+ a(1:5, 2) = a(4, :) + 1
+
+ ! The following expression should cause loop reordering
+ a(:, 2:4) = a(:, 1:3)
+
+ do n = 1, 5
+ if (a(n, 3) .ne. (n + 1)) call abort
+ if (b(4, n) .ne. (6 - n)) call abort
+ end do
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/scalarize2.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/scalarize2.f90
new file mode 100644
index 00000000000..608c051d31c
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/scalarize2.f90
@@ -0,0 +1,24 @@
+! Program to test the scalarizer
+program testarray
+ implicit none
+ integer, dimension (:, :), allocatable :: a, b
+ integer n
+
+ allocate(a(6, 5), b(6, 5))
+ a = 0
+ do n = 1, 5
+ a(4, n) = n
+ end do
+
+ b(:, 5:1:-1) = a
+ a(1:5, 2) = a(4, :) + 1
+
+ ! The following expression should cause loop reordering
+ a(:, 2:4) = a(:, 1:3)
+
+ do n = 1, 5
+ if (a(n, 3) .ne. (n + 1)) call abort
+ if (b(4, n) .ne. (6 - n)) call abort
+ end do
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/scalarize3.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/scalarize3.f90
new file mode 100644
index 00000000000..76d41484c70
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/scalarize3.f90
@@ -0,0 +1,8 @@
+program foo
+ integer, dimension(3, 2) :: a
+
+ a = reshape ((/1, 2, 3, 4, 5, 6/), (/3, 2/))
+ a = a(3:1:-1, 2:1:-1);
+
+ if (any (a .ne. reshape ((/6, 5, 4, 3, 2, 1/), (/3, 2/)))) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/slash_edit.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/slash_edit.f90
new file mode 100644
index 00000000000..c73d5432a31
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/slash_edit.f90
@@ -0,0 +1,14 @@
+! pr 14762 - '/' not working in format
+ INTEGER N(5)
+ DATA N/1,2,3,4,5/
+ OPEN(UNIT=7)
+ 100 FORMAT(I4)
+ WRITE(7,100)N
+ CLOSE(7)
+ OPEN(7)
+ 200 FORMAT(I4,///I4)
+ READ(7,200)I,J
+ CLOSE(7)
+ IF (I.NE.1) CALL ABORT
+ IF (J.NE.4) CALL ABORT
+ END
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/spec_abs.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/spec_abs.f90
new file mode 100644
index 00000000000..be8e3f7487b
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/spec_abs.f90
@@ -0,0 +1,12 @@
+!pr 14056
+ INTRINSIC IABS
+ INTEGER FF324
+ IVCOMP = FF324(IABS,-7)
+ IF (IVCOMP.NE.8) CALL ABORT
+ END
+ INTEGER FUNCTION FF324(NINT, IDON03)
+ FF324 = NINT(IDON03) + 1
+! **** THE NAME NINT IS A DUMMY ARGUMENT
+! AND NOT AN INTRINSIC FUNCTION REFERENCE *****
+ RETURN
+ END
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/specifics.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/specifics.f90
new file mode 100644
index 00000000000..d9f3ff0c7b2
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/specifics.f90
@@ -0,0 +1,133 @@
+! Program to test intrinsic functions as actual arguments
+subroutine test_r(fn, val, res)
+ real fn
+ real val, res
+
+ if (diff(fn(val), res)) call abort
+contains
+function diff(a, b)
+ real a, b
+ logical diff
+ diff = (abs(a - b) .gt. 0.00001)
+end function
+end subroutine
+
+subroutine test_d(fn, val, res)
+ double precision fn
+ double precision val, res
+
+ if (diff(fn(val), res)) call abort
+contains
+function diff(a, b)
+ double precision a, b
+ logical diff
+ diff = (abs(a - b) .gt. 0.00001d0)
+end function
+end subroutine
+
+subroutine test_r2(fn, val1, val2, res)
+ real fn
+ real val1, val2, res
+
+ if (diff(fn(val1, val2), res)) call abort
+contains
+function diff(a, b)
+ real a, b
+ logical diff
+ diff = (abs(a - b) .gt. 0.00001)
+end function
+end subroutine
+
+subroutine test_d2(fn, val1, val2, res)
+ double precision fn
+ double precision val1, val2, res
+
+ if (diff(fn(val1, val2), res)) call abort
+contains
+function diff(a, b)
+ double precision a, b
+ logical diff
+ diff = (abs(a - b) .gt. 0.00001d0)
+end function
+end subroutine
+
+subroutine test_dprod(fn)
+ if (abs (fn (2.0, 3.0) - 6d0) .gt. 0.00001) call abort
+end subroutine
+
+program specifics
+ intrinsic abs
+ intrinsic aint
+ intrinsic anint
+ intrinsic acos
+ intrinsic asin
+ intrinsic atan
+ intrinsic cos
+ intrinsic sin
+ intrinsic tan
+ intrinsic cosh
+ intrinsic sinh
+ intrinsic tanh
+ intrinsic alog
+ intrinsic exp
+ intrinsic sign
+ intrinsic amod
+
+ intrinsic dabs
+ intrinsic dint
+ intrinsic dnint
+ intrinsic dacos
+ intrinsic dasin
+ intrinsic datan
+ intrinsic dcos
+ intrinsic dsin
+ intrinsic dtan
+ intrinsic dcosh
+ intrinsic dsinh
+ intrinsic dtanh
+ intrinsic dlog
+ intrinsic dexp
+ intrinsic dsign
+ intrinsic dmod
+
+ intrinsic dprod
+
+ !TODO: Also test complex variants
+
+ call test_r (abs, -1.0, abs(-1.0))
+ call test_r (aint, 1.7, 1.0)
+ call test_r (anint, 1.7, 2.0)
+ call test_r (acos, 0.5, acos(0.5))
+ call test_r (asin, 0.5, asin(0.5))
+ call test_r (atan, 0.5, atan(0.5))
+ call test_r (cos, 1.0, cos(1.0))
+ call test_r (sin, 1.0, sin(1.0))
+ call test_r (tan, 1.0, tan(1.0))
+ call test_r (cosh, 1.0, cosh(1.0))
+ call test_r (sinh, 1.0, sinh(1.0))
+ call test_r (tanh, 1.0, tanh(1.0))
+ call test_r (alog, 2.0, alog(2.0))
+ call test_r (exp, 1.0, exp(1.0))
+ call test_r2 (sign, 1.0, -2.0, sign(1.0, -2.0))
+ call test_r2 (amod, 3.5, 2.0, amod(3.5, 2.0))
+
+ call test_d (dabs, -1d0, abs(-1d0))
+ call test_d (dint, 1.7d0, 1d0)
+ call test_d (dnint, 1.7d0, 2d0)
+ call test_d (dacos, 0.5d0, dacos(0.5d0))
+ call test_d (dasin, 0.5d0, dasin(0.5d0))
+ call test_d (datan, 0.5d0, datan(0.5d0))
+ call test_d (dcos, 1d0, dcos(1d0))
+ call test_d (dsin, 1d0, dsin(1d0))
+ call test_d (dtan, 1d0, dtan(1d0))
+ call test_d (dcosh, 1d0, dcosh(1d0))
+ call test_d (dsinh, 1d0, dsinh(1d0))
+ call test_d (dtanh, 1d0, dtanh(1d0))
+ call test_d (dlog, 2d0, dlog(2d0))
+ call test_d (dexp, 1d0, dexp(1d0))
+ call test_d2 (dsign, 1d0, -2d0, sign(1d0, -2d0))
+ call test_d2 (dmod, 3.5d0, 2d0, dmod(3.5d0, 2d0))
+
+ call test_dprod(dprod)
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/st_function.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/st_function.f90
new file mode 100644
index 00000000000..8bde9b2f740
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/st_function.f90
@@ -0,0 +1,87 @@
+! Program to test STATEMENT function
+program st_fuction
+ call simple_case
+ call with_function_call
+ call with_character_dummy
+ call with_derived_type_dummy
+ call with_pointer_dummy
+ call multiple_eval
+
+contains
+ subroutine simple_case
+ integer st1, st2
+ integer c(10, 10)
+ st1 (i, j) = i + j
+ st2 (i, j) = c(i, j)
+
+ if (st1 (1, 2) .ne. 3) call abort
+ c = 3
+ if (st2 (1, 2) .ne. 3 .or. st2 (2, 3) .ne. 3) call abort
+ end subroutine
+
+ subroutine with_function_call
+ integer fun, st3
+ st3 (i, j) = fun (i) + fun (j)
+
+ if (st3 (fun (2), 4) .ne. 16) call abort
+ end subroutine
+
+ subroutine with_character_dummy
+ character (len=4) s1, s2, st4
+ character (len=10) st5, s0
+ st4 (i, j) = "0123456789"(i:j)
+ st5 (s1, s2) = s1 // s2
+
+ if (st4 (1, 4) .ne. "0123" ) call abort
+ if (st5 ("01", "02") .ne. "01 02 ") call abort
+ end subroutine
+
+ subroutine with_derived_type_dummy
+ type person
+ integer age
+ character (len=50) name
+ end type person
+ type (person) me, p, tom
+ type (person) st6
+ st6 (p) = p
+
+ me%age = 5
+ me%name = "Tom"
+ tom = st6 (me)
+ if (tom%age .ne. 5) call abort
+ if (tom%name .gt. "Tom") call abort
+ end subroutine
+
+ subroutine with_pointer_dummy
+ character(len=4), pointer:: p, p1
+ character(len=4), target:: i
+ character(len=6) a
+ a (p) = p // '10'
+
+ p1 => i
+ i = '1234'
+ if (a (p1) .ne. '123410') call abort
+ end subroutine
+
+ subroutine multiple_eval
+ integer st7, fun2, fun
+
+ st7(i) = i + fun(i)
+
+ if (st7(fun2(10)) .ne. 3) call abort
+ end subroutine
+end
+
+! This functon returns the argument passed on the previous call.
+integer function fun2 (i)
+ integer i
+ integer, save :: val = 1
+
+ fun2 = val
+ val = i
+end function
+
+integer function fun (i)
+ integer i
+ fun = i * 2
+end function
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/stack_varsize.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/stack_varsize.f90
new file mode 100644
index 00000000000..f839c8e36bc
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/stack_varsize.f90
@@ -0,0 +1,30 @@
+! Program to test the stack variable size limit.
+program stack
+ call sub1
+ call sub2 (1)
+contains
+
+ ! Local variables larger than 32768 in byte size shall be placed in static
+ ! storage area, while others be put on stack by default.
+ subroutine sub1
+ real a, b(32768/4), c(32768/4+1)
+ integer m, n(1024,4), k(1024,1024)
+ a = 10.0
+ b = 20.0
+ c = 30.0
+ m = 10
+ n = 20
+ k = 30
+ if ((a .ne. 10.0).or.(b(1) .ne. 20.0).or.(c(1) .ne. 30.0)) call abort
+ if ((m .ne. 10).or.(n(256,4) .ne. 20).or.(k(1,1024) .ne. 30)) call abort
+ end
+
+ ! Local variables defined in recursive subroutine are always put on stack.
+ recursive subroutine sub2 (n)
+ real a (32769)
+ a (1) = 42
+ if (n .ge. 1) call sub2 (n-1)
+ if (a(1) .ne. 42) call abort
+ a (1) = 0
+ end
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/straret.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/straret.f90
new file mode 100644
index 00000000000..579e35a70a4
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/straret.f90
@@ -0,0 +1,18 @@
+! Test assumed length character functions.
+
+character*(*) function f()
+ f = "Hello"
+end function
+
+character*6 function g()
+ g = "World"
+end function
+
+program straret
+ character*6 f, g
+ character*12 v
+
+
+ v = f() // g()
+ if (v .ne. "Hello World ") call abort ()
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/strarray_1.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/strarray_1.f90
new file mode 100644
index 00000000000..95e9b038559
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/strarray_1.f90
@@ -0,0 +1,13 @@
+subroutine foo(i)
+character c
+integer i
+character(1),parameter :: hex_chars(0:15)=&
+ (/'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'/)
+
+c = hex_chars(i)
+if (c.ne.'3') call abort()
+end
+
+program strarray_1
+call foo(3)
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/strarray_2.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/strarray_2.f90
new file mode 100644
index 00000000000..dbb3b89e43f
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/strarray_2.f90
@@ -0,0 +1,14 @@
+subroutine foo(i,c)
+character c
+integer i
+character(1),parameter :: hex_chars(0:15)=&
+ (/'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'/)
+
+c = hex_chars(i)
+end
+
+program strarray_2
+ character c
+ call foo(3,c)
+ if (c.ne.'3') call abort()
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/strarray_3.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/strarray_3.f90
new file mode 100644
index 00000000000..9d369c7f196
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/strarray_3.f90
@@ -0,0 +1,50 @@
+program strarray_3
+ character(len=5), dimension(2) :: c
+
+ c(1) = "Hello"
+ c(2) = "World"
+
+ call foo1(c)
+ call foo2(c, 2)
+ call foo3(c, 5)
+ call foo4(c, 5, 2)
+ call foo5(c(2:1:-1))
+contains
+subroutine foo1(a)
+ implicit none
+ character(len=5), dimension(2) :: a
+
+ if ((a(1) .ne. "Hello") .or. (a(2) .ne. "World")) call abort
+end subroutine
+
+subroutine foo2(a, m)
+ implicit none
+ integer m
+ character(len=5), dimension(m) :: a
+
+ if ((a(1) .ne. "Hello") .or. (a(2) .ne. "World")) call abort
+end subroutine
+
+subroutine foo3(a, n)
+ implicit none
+ integer n
+ character(len=n), dimension(:) :: a
+
+ if ((a(1) .ne. "Hello") .or. (a(2) .ne. "World")) call abort
+end subroutine
+
+subroutine foo4(a, n, m)
+ implicit none
+ integer n, m
+ character(len=n), dimension(m) :: a
+
+ if ((a(1) .ne. "Hello") .or. (a(2) .ne. "World")) call abort
+end subroutine
+
+subroutine foo5(a)
+ implicit none
+ character(len=2), dimension(5) :: a
+
+ if ((a(1) .ne. "Wo") .or. (a(3) .ne. "dH") .or. (a(5) .ne. "lo")) call abort
+end subroutine
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/strarray_4.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/strarray_4.f90
new file mode 100644
index 00000000000..c33f4b53d69
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/strarray_4.f90
@@ -0,0 +1,39 @@
+program strarray_4
+ character(len=5), dimension(2) :: c
+
+ c(1) = "Hello"
+ c(2) = "World"
+
+ call foo1(c)
+ call foo2(c, 2)
+ call foo3(c, 5, 2)
+contains
+subroutine foo1(a)
+ implicit none
+ character(len=5), dimension(2) :: a
+ character(len=5), dimension(2) :: b
+
+ b = a;
+ if ((b(1) .ne. "Hello") .or. (b(2) .ne. "World")) call abort
+end subroutine
+
+subroutine foo2(a, m)
+ implicit none
+ integer m
+ character(len=5), dimension(m) :: a
+ character(len=5), dimension(m) :: b
+
+ b = a
+ if ((b(1) .ne. "Hello") .or. (b(2) .ne. "World")) call abort
+end subroutine
+
+subroutine foo3(a, n, m)
+ implicit none
+ integer n, m
+ character(len=n), dimension(m) :: a
+ character(len=n), dimension(m) :: b
+
+ b = a
+ if ((b(1) .ne. "Hello") .or. (b(2) .ne. "World")) call abort
+end subroutine
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/strcmp.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/strcmp.f90
new file mode 100644
index 00000000000..26980901c7e
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/strcmp.f90
@@ -0,0 +1,16 @@
+program test
+ implicit none
+ character(len=20) :: foo
+
+ foo="hello"
+
+ if (llt(foo, "hello")) call abort
+ if (.not. lle(foo, "hello")) call abort
+ if (lgt("hello", foo)) call abort
+ if (.not. lge("hello", foo)) call abort
+
+ if (.not. llt(foo, "world")) call abort
+ if (.not. lle(foo, "world")) call abort
+ if (lgt(foo, "world")) call abort
+ if (lge(foo, "world")) call abort
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/strcommon_1.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/strcommon_1.f90
new file mode 100644
index 00000000000..aa51ccf4bae
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/strcommon_1.f90
@@ -0,0 +1,28 @@
+! PR14081 character variables in common blocks.
+
+subroutine test1
+ implicit none
+ common /block/ c
+ character(len=12) :: c
+
+ if (c .ne. "Hello World") call abort
+end subroutine
+
+subroutine test2
+ implicit none
+ common /block/ a
+ character(len=6), dimension(2) :: a
+
+ if ((a(1) .ne. "Hello") .or. (a(2) .ne. "World")) call abort
+end subroutine
+
+program strcommon_1
+ implicit none
+ common /block/ s, t
+ character(len=6) :: s, t
+ s = "Hello "
+ t = "World "
+ call test1
+ call test2
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/string.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/string.f90
new file mode 100644
index 00000000000..f220f4a477b
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/string.f90
@@ -0,0 +1,15 @@
+! Program to test string handling
+program string
+ implicit none
+ character(len=5) :: a, b
+ character(len=20) :: c
+
+ a = 'Hello'
+ b = 'World'
+ c = a//b
+
+ if (c .ne. 'HelloWorld') call abort
+ if (c .eq. 'WorldHello') call abort
+ if (a//'World' .ne. 'HelloWorld') call abort
+ if (a .ge. b) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/strlen.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/strlen.f90
new file mode 100644
index 00000000000..17f9aa277b6
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/strlen.f90
@@ -0,0 +1,34 @@
+! Program to test the LEN and LEN_TRIM intrinsics.
+subroutine test (c)
+ character(*) c
+ character(len(c)) d
+
+ d = c
+ if (len(d) .ne. 20) call abort
+ if (d .ne. "Longer Test String") call abort
+ c = "Hello World"
+end subroutine
+
+subroutine test2 (c)
+ character (*) c
+ character(len(c)) d
+
+ d = c
+ if (len(d) .ne. 6) call abort
+ if (d .ne. "Foobar") call abort
+end subroutine
+
+program strlen
+ implicit none
+ character(20) c
+ character(5) a, b
+ integer i
+
+ c = "Longer Test String"
+ call test (c)
+
+ if (len(c) .ne. 20) call abort
+ if (len_trim(c) .ne. 11) call abort
+
+ call test2 ("Foobar");
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/strret.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/strret.f90
new file mode 100644
index 00000000000..7346fff5df7
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/strret.f90
@@ -0,0 +1,25 @@
+! Program to test caracter string return values
+function test ()
+ implicit none
+ character(len=10) :: test
+ test = "World"
+end function
+
+function test2 () result (r)
+ implicit none
+ character(len=5) :: r
+ r = "Hello"
+end function
+
+program strret
+ implicit none
+ character(len=15) :: s
+ character(len=10) :: test
+ character(len=5) :: test2
+
+ s = test ()
+ if (s .ne. "World") call abort
+
+ s = "Hello " // test ()
+ if (s .ne. test2 () //" World") call abort
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/test_slice.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/test_slice.f90
new file mode 100644
index 00000000000..f2291cd832a
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/test_slice.f90
@@ -0,0 +1,17 @@
+! Program to test handling of reduced rank array sections. This uncovered
+! bugs in simplify_shape and the scalarization of array sections.
+program test_slice
+ implicit none
+
+ real (kind = 8), dimension(2, 2, 2) :: x
+ real (kind = 8) :: min, max
+
+ x = 1.0
+ if (minval(x(1, 1:2, 1:1)) .ne. 1.0) call abort ()
+ if (maxval(x(1, 1:2, 1:1)) .ne. 1.0) call abort ()
+ if (any (shape(x(1, 1:2, 1:1)) .ne. (/2, 1/))) call abort ()
+
+ if (any (shape(x(1, 1:2, 1)) .ne. (/2/))) call abort ()
+ if (any (shape(x(1:1, 1:2, 1:1)) .ne. (/1, 2, 1/))) call abort ()
+
+end program test_slice
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/unopened_unit_1.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/unopened_unit_1.f90
new file mode 100644
index 00000000000..d87406ab4db
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/unopened_unit_1.f90
@@ -0,0 +1,13 @@
+! PR 14565
+program unopened_unit_1
+ Integer I,J
+ Do I = 1,10
+ Write(99,*)I
+ End Do
+ Rewind(99)
+ Do I = 1,10
+ Read(99,*)J
+ If (J.ne.I) Call abort
+ End Do
+End program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/userop.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/userop.f90
new file mode 100644
index 00000000000..4fceb476685
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/userop.f90
@@ -0,0 +1,67 @@
+module uops
+ implicit none
+ interface operator (.foo.)
+ module procedure myfoo
+ end interface
+
+ interface operator (*)
+ module procedure boolmul
+ end interface
+
+ interface assignment (=)
+ module procedure int2bool
+ end interface
+
+contains
+function myfoo (lhs, rhs)
+ implicit none
+ integer myfoo
+ integer, intent(in) :: lhs, rhs
+
+ myfoo = lhs + rhs
+end function
+
+! This is deliberately different from integer multiplication
+function boolmul (lhs, rhs)
+ implicit none
+ logical boolmul
+ logical, intent(IN) :: lhs, rhs
+
+ boolmul = lhs .and. .not. rhs
+end function
+
+subroutine int2bool (lhs, rhs)
+ implicit none
+ logical, intent(out) :: lhs
+ integer, intent(in) :: rhs
+
+ lhs = rhs .ne. 0
+end subroutine
+end module
+
+program me
+ use uops
+ implicit none
+ integer i, j
+ logical b, c
+
+ b = .true.
+ c = .true.
+ if (b * c) call abort
+ c = .false.
+ if (.not. (b * c)) call abort
+ if (c * b) call abort
+ b = .false.
+ if (b * c) call abort
+
+ i = 0
+ b = i
+ if (b) call abort
+ i = 2
+ b = i
+ if (.not. b) call abort
+
+ j = 3
+ if ((i .foo. j) .ne. 5) call abort
+end program
+
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/where_1.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/where_1.f90
new file mode 100644
index 00000000000..ba1f8a62579
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/where_1.f90
@@ -0,0 +1,41 @@
+! Program to test WHERE inside FORALL
+program where_1
+ integer :: A(5,5)
+
+ A(1,:) = (/1,0,0,0,0/)
+ A(2,:) = (/2,1,1,1,0/)
+ A(3,:) = (/1,2,2,0,2/)
+ A(4,:) = (/2,1,0,2,3/)
+ A(5,:) = (/1,0,0,0,0/)
+
+ ! Where inside FORALL.
+ ! WHERE masks must be evaluated before executing the assignments
+ forall (I=1:5)
+ where (A(I,:) .EQ. 0)
+ A(:,I) = I
+ elsewhere (A(I,:) >2)
+ A(I,:) = 6
+ endwhere
+ end forall
+
+ if (any (A .ne. reshape ((/1, 1, 1, 1, 1, 0, 1, 2, 1, 2, 0, 1, 2, 3, 0, &
+ 0, 1, 4, 2, 0, 0, 5, 6, 6, 5/), (/5, 5/)))) call abort
+
+ ! Where inside DO
+ A(1,:) = (/1,0,0,0,0/)
+ A(2,:) = (/2,1,1,1,0/)
+ A(3,:) = (/1,2,2,0,2/)
+ A(4,:) = (/2,1,0,2,3/)
+ A(5,:) = (/1,0,0,0,0/)
+
+ do I=1,5
+ where (A(I,:) .EQ. 0)
+ A(:,I) = I
+ elsewhere (A(I,:) >2)
+ A(I,:) = 6
+ endwhere
+ enddo
+
+ if (any (A .ne. reshape ((/1, 1, 1, 1, 1, 0, 1, 2, 1, 2, 0, 1, 2, 6, 0, &
+ 0, 1, 0, 2, 0, 0, 0, 5, 5, 5/), (/5, 5/)))) call abort
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/where_2.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/where_2.f90
new file mode 100644
index 00000000000..25a8dc9e7a8
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/where_2.f90
@@ -0,0 +1,22 @@
+! Program to test the WHERE constructs
+program where_2
+ integer temp(10), reduce(10)
+
+ temp = 10
+ reduce(1:3) = -1
+ reduce(4:6) = 0
+ reduce(7:8) = 5
+ reduce(9:10) = 10
+
+ WHERE (reduce < 0)
+ temp = 100
+ ELSE WHERE (reduce .EQ. 0)
+ temp = 200 + temp
+ ELSE WHERE
+ WHERE (reduce > 6) temp = temp + sum(reduce)
+ temp = 300 + temp
+ END WHERE
+
+ if (any (temp .ne. (/100, 100, 100, 210, 210, 210, 310, 310, 337, 337/))) &
+ call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/where_3.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/where_3.f90
new file mode 100644
index 00000000000..a9f7ef7bc08
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/where_3.f90
@@ -0,0 +1,21 @@
+! Program to test WHERE on unknown size arrays
+program where_3
+ integer A(10, 2)
+
+ A = 0
+ call sub(A)
+
+contains
+
+subroutine sub(B)
+ integer, dimension(:, :) :: B
+
+ B(1:5, 1) = 0
+ B(6:10, 1) = 5
+ where (B(:,1)>0)
+ B(:,1) = B(:,1) + 10
+ endwhere
+ if (any (B .ne. reshape ((/0, 0, 0, 0, 0, 15, 15, 15, 15, 15, &
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0/), (/10, 2/)))) call abort
+end subroutine
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/where_4.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/where_4.f90
new file mode 100644
index 00000000000..104096b356a
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/where_4.f90
@@ -0,0 +1,13 @@
+! Tests WHERE statement with a data dependency
+program where_4
+ integer, dimension(5) :: a
+ integer, dimension(5) :: b
+
+ a = (/1, 2, 3, 4, 5/)
+ b = (/1, 0, 1, 0, 1/)
+
+ where (b .ne. 0)
+ a(:) = a(5:1:-1)
+ endwhere
+ if (any (a .ne. (/5, 2, 3, 4, 1/))) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/where_5.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/where_5.f90
new file mode 100644
index 00000000000..58d24ecbb30
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/where_5.f90
@@ -0,0 +1,13 @@
+! Tests WHERE satement with non-integer array in the mask expression
+program where_5
+ integer, dimension(5) :: a
+ real(kind=8), dimension(5) :: b
+
+ a = (/1, 2, 3, 4, 5/)
+ b = (/1d0, 0d0, 1d0, 0d0, 1d0/)
+
+ where (b .ne. 0d0)
+ a(:) = a(:) + 10
+ endwhere
+ if (any (a .ne. (/11, 2, 13, 4, 15/))) call abort
+end program
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/where_6.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/where_6.f90
new file mode 100644
index 00000000000..274598b8d77
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/where_6.f90
@@ -0,0 +1,23 @@
+! Program to test WHERE inside FORALL and the WHERE assignment need temporary
+program where_6
+ integer :: A(5,5)
+
+ A(1,:) = (/1,0,0,0,0/)
+ A(2,:) = (/2,1,1,1,0/)
+ A(3,:) = (/1,2,2,0,2/)
+ A(4,:) = (/2,1,0,2,3/)
+ A(5,:) = (/1,0,0,0,0/)
+
+ ! Where inside FORALL.
+ ! WHERE masks must be evaluated before executing the assignments
+ m=5
+ forall (I=1:4)
+ where (A(I,:) .EQ. 0)
+ A(1:m,I) = A(1:m,I+1) + I
+ elsewhere (A(I,:) >2)
+ A(I,1:m) = 6
+ endwhere
+ end forall
+ if (any (A .ne. reshape ((/1,2,6,2,1,0,1,2,1,2,0,1,2,5,0,0,1,6,2,0,0,0,2,&
+ 6,0/), (/5, 5/)))) call abort
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/write_logical.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/write_logical.f90
new file mode 100644
index 00000000000..4e0060702f3
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/write_logical.f90
@@ -0,0 +1,23 @@
+! PR 14334, L edit descriptor does not work
+!
+! this test uses L1 and L4 to print TRUE and FALSE
+ logical true,false
+ character*10 b
+ true = .TRUE.
+ false = .FALSE.
+ b = ''
+ write (b, '(L1)') true
+ if (b(1:1) .ne. 'T') call abort
+
+ b = ''
+ write (b, '(L1)') false
+ if (b(1:1) .ne. 'F') call abort
+
+ b = ''
+ write(b, '(L4)') true
+ if (b(1:4) .ne. ' T') call abort
+
+ b = ''
+ write(b, '(L4)') false
+ if (b(1:4) .ne. ' F') call abort
+ end
diff --git a/gcc/testsuite/lib/fortran-torture.exp b/gcc/testsuite/lib/fortran-torture.exp
new file mode 100644
index 00000000000..67b18ebc7ac
--- /dev/null
+++ b/gcc/testsuite/lib/fortran-torture.exp
@@ -0,0 +1,344 @@
+# Copyright (C) 2003 Free Software Foundation, Inc.
+
+# This program 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 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 program; if not, write to the Free Software
+# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to
+# the author.
+
+# This file was written by Steven Bosscher (s.bosscher@student.tudelft.nl)
+# based on f-torture.exp, which was written by Rob Savoye.
+
+# The biggest change from g77 is that we always test all testcases with
+# loop options, because it is much harder to figure out whether a testcase
+# has loops if you have array syntax, like Fortran 95. In fact, the whole
+# point of F95 is arrays, so loops show up in most testcases anyway.
+
+
+# The default option list can be overridden by
+# TORTURE_OPTIONS="{ { list1 } ... { listN } }"
+
+if ![info exists TORTURE_OPTIONS] {
+ set TORTURE_OPTIONS [list \
+ { -O0 } { -O1 } { -O2 } \
+ { -O2 -fomit-frame-pointer -finline-functions } \
+ { -O2 -fomit-frame-pointer -finline-functions -funroll-loops } \
+ { -O2 -fomit-frame-pointer -finline-functions -funroll-all-loops } \
+ { -O2 -fno-repack-arrays } \
+ { -O3 -g } \
+ { -Os }]
+}
+
+
+#
+# fortran-torture-compile -- compile a gfortran.fortran-torture testcase.
+#
+# SRC is the full pathname of the testcase.
+# OPTION is the specific compiler flag we're testing (eg: -O2).
+#
+proc fortran-torture-compile { src option } {
+ global output
+ global srcdir tmpdir
+ global host_triplet
+
+ set output "$tmpdir/[file tail [file rootname $src]].o"
+
+ regsub "^$srcdir/?" $src "" testcase
+
+ # If we couldn't rip $srcdir out of `src' then just do the best we can.
+ # The point is to reduce the unnecessary noise in the logs. Don't strip
+ # out too much because different testcases with the same name can confuse
+ # `test-tool'.
+ if [string match "/*" $testcase] {
+ set testcase "[file tail [file dirname $src]]/[file tail $src]"
+ }
+
+ verbose "Testing $testcase, $option" 1
+
+ # Run the compiler and get results in comp_output.
+ set options ""
+ lappend options "additional_flags=-w $option"
+
+ set comp_output [gfortran_target_compile "$src" "$output" object $options];
+
+ # See if we got something bad.
+ set fatal_signal "*95*: Internal compiler error: program*got fatal signal"
+
+ if [string match "$fatal_signal 6" $comp_output] then {
+ gfortran_fail $testcase "Got Signal 6, $option"
+ remote_file build delete $output
+ return
+ }
+
+ if [string match "$fatal_signal 11" $comp_output] then {
+ gfortran_fail $testcase "Got Signal 11, $option"
+ remote_file build delete $output
+ return
+ }
+
+ # We shouldn't get these because of -w, but just in case.
+ if [string match "*95*:*warning:*" $comp_output] then {
+ warning "$testcase: (with warnings) $option"
+ send_log "$comp_output\n"
+ unresolved "$testcase, $option"
+ remote_file build delete $output
+ return
+ }
+
+ # Prune warnings we know are unwanted.
+ set comp_output [prune_warnings $comp_output]
+
+ # Report if the testcase is not supported.
+ set unsupported_message [gfortran_check_unsupported_p $comp_output]
+ if { $unsupported_message != "" } {
+ unsupported "$testcase: $unsupported_message"
+ remote_file build delete $output
+ return
+ }
+
+ # remove any leftover LF/CR to make sure any output is legit
+ regsub -all -- "\[\r\n\]*" $comp_output "" comp_output
+
+ # If any message remains, we fail.
+ if ![string match "" $comp_output] then {
+ gfortran_fail $testcase $option
+ remote_file build delete $output
+ return
+ }
+
+ gfortran_pass $testcase $option
+ remote_file build delete $output
+}
+
+
+#
+# fortran-torture-execute -- compile and execute a testcase.
+#
+# SRC is the full pathname of the testcase.
+#
+# If the testcase has an associated .x file, we source that to run the
+# test instead. We use .x so that we don't lengthen the existing filename
+# to more than 14 chars.
+#
+proc fortran-torture-execute { src } {
+ global output
+ global srcdir tmpdir
+ global tool
+ global compiler_conditional_xfail_data
+ global TORTURE_OPTIONS
+
+ # Check for alternate driver.
+ if [file exists [file rootname $src].x] {
+ verbose "Using alternate driver [file rootname [file tail $src]].x" 2
+ set done_p 0
+ catch "set done_p \[source [file rootname $src].x\]"
+ if { $done_p } {
+ return
+ }
+ }
+
+ # Setup the options for the testcase run.
+ set option_list $TORTURE_OPTIONS
+ set executable $tmpdir/[file tail [file rootname $src].x]
+ regsub "^$srcdir/?" $src "" testcase
+
+ # If we couldn't rip $srcdir out of `src' then just do the best we can.
+ # The point is to reduce the unnecessary noise in the logs. Don't strip
+ # out too much because different testcases with the same name can confuse
+ # `test-tool'.
+ if [string match "/*" $testcase] {
+ set testcase "[file tail [file dirname $src]]/[file tail $src]"
+ }
+
+ # Walk the list of options and copmile and run the testcase for all
+ # options that are not explicitly disabled by the .x script (if present).
+ foreach option $option_list {
+
+ # Torture_{compile,execute}_xfail are set by the .x script.
+ if [info exists torture_compile_xfail] {
+ setup_xfail $torture_compile_xfail
+ }
+
+ # Torture_execute_before_{compile,execute} can be set by the .x script.
+ if [info exists torture_eval_before_compile] {
+ set ignore_me [eval $torture_eval_before_compile]
+ }
+
+ # FIXME: We should make sure that the modules required by this testcase
+ # exist. If not, the testcase should XFAIL.
+
+ # Compile the testcase.
+ remote_file build delete $executable
+ verbose "Testing $testcase, $option" 1
+
+ set options ""
+ lappend options "additional_flags=-w $option"
+ set comp_output [gfortran_target_compile "$src" "$executable" executable $options];
+
+ # See if we got something bad.
+ set fatal_signal "*95*: Internal compiler error: program*got fatal signal"
+
+ if [string match "$fatal_signal 6" $comp_output] then {
+ gfortran_fail $testcase "Got Signal 6, $option"
+ remote_file build delete $executable
+ continue
+ }
+
+ if [string match "$fatal_signal 11" $comp_output] then {
+ gfortran_fail $testcase "Got Signal 11, $option"
+ remote_file build delete $executable
+ continue
+ }
+
+ # We shouldn't get these because of -w, but just in case.
+ if [string match "*95*:*warning:*" $comp_output] then {
+ warning "$testcase: (with warnings) $option"
+ send_log "$comp_output\n"
+ unresolved "$testcase, $option"
+ remote_file build delete $executable
+ continue
+ }
+
+ # Prune warnings we know are unwanted.
+ set comp_output [prune_warnings $comp_output]
+
+ # Report if the testcase is not supported.
+ set unsupported_message [gfortran_check_unsupported_p $comp_output]
+ if { $unsupported_message != "" } {
+ unsupported "$testcase: $unsupported_message"
+ continue
+ } elseif ![file exists $executable] {
+ if ![is3way] {
+ fail "$testcase compilation, $option"
+ untested "$testcase execution, $option"
+ continue
+ } else {
+ # FIXME: since we can't test for the existance of a remote
+ # file without short of doing an remote file list, we assume
+ # that since we got no output, it must have compiled.
+ pass "$testcase compilation, $option"
+ }
+ } else {
+ pass "$testcase compilation, $option"
+ }
+
+ # See if this source file uses INTEGER(KIND=8) types, if it does, and
+ # no_long_long is set, skip execution of the test.
+ # FIXME: We should also look for F95 style "_8" or select_int_kind()
+ # integers, but that is obviously much harder than just regexping this.
+ # So maybe we should just avoid those in testcases.
+ if [target_info exists no_long_long] then {
+ if [expr [search_for $src "integer\*8"] \
+ +[search_for $src "integer *( *8 *)"] \
+ +[search_for $src "integer *( *kind *= *8 *)"]] \
+ then {
+ untested "$testcase execution, $option"
+ continue
+ }
+ }
+
+ if [info exists torture_execute_xfail] {
+ setup_xfail $torture_execute_xfail
+ }
+
+ if [info exists torture_eval_before_execute] {
+ set ignore_me [eval $torture_eval_before_execute]
+ }
+
+ # Run the testcase, and analyse the output.
+ set result [gfortran_load "$executable" "" ""]
+ set status [lindex $result 0];
+ set output [lindex $result 1];
+ if { $status == "pass" } {
+ remote_file build delete $executable
+ }
+ $status "$testcase execution, $option"
+ }
+}
+
+
+#
+# search_for -- looks for a string match in a file
+#
+proc search_for { file pattern } {
+ set fd [open $file r]
+ while { [gets $fd cur_line]>=0 } {
+ set lower [string tolower $cur_line]
+ if [regexp "$pattern" $lower] then {
+ close $fd
+ return 1
+ }
+ }
+ close $fd
+ return 0
+}
+
+
+#
+# fortran-torture -- the fortran-torture testcase source file processor
+#
+# This runs compilation only tests (no execute tests).
+#
+# SRC is the full pathname of the testcase, or just a file name in which
+# case we prepend $srcdir/$subdir.
+#
+# If the testcase has an associated .x file, we source that to run the
+# test instead. We use .x so that we don't lengthen the existing filename
+# to more than 14 chars.
+#
+proc fortran-torture { args } {
+ global srcdir subdir
+ global compiler_conditional_xfail_data
+ global TORTURE_OPTIONS
+
+ set src [lindex $args 0];
+ if { [llength $args] > 1 } {
+ set options [lindex $args 1];
+ } else {
+ set options ""
+ }
+
+ # Prepend $srdir/$subdir if missing.
+ if ![string match "*/*" $src] {
+ set src "$srcdir/$subdir/$src"
+ }
+
+ # Check for alternate driver.
+ if [file exists [file rootname $src].x] {
+ verbose "Using alternate driver [file rootname [file tail $src]].x" 2
+ set done_p 0
+ catch "set done_p \[source [file rootname $src].x\]"
+ if { $done_p } {
+ return
+ }
+ }
+
+ # loop through all the options
+ set option_list $TORTURE_OPTIONS
+ foreach option $option_list {
+
+ # torture_compile_xfail is set by the .x script (if present)
+ if [info exists torture_compile_xfail] {
+ setup_xfail $torture_compile_xfail
+ }
+
+ # torture_execute_before_compile is set by the .x script (if present)
+ if [info exists torture_eval_before_compile] {
+ set ignore_me [eval $torture_eval_before_compile]
+ }
+
+ fortran-torture-compile $src "$option $options"
+ }
+}
+
diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp
index 7977893cae6..803d609068f 100644
--- a/gcc/testsuite/lib/gcc-dg.exp
+++ b/gcc/testsuite/lib/gcc-dg.exp
@@ -18,6 +18,7 @@ load_lib dg.exp
load_lib file-format.exp
load_lib target-supports.exp
load_lib scanasm.exp
+load_lib scantree.exp
load_lib prune.exp
if ![info exists TORTURE_OPTIONS] {
diff --git a/gcc/testsuite/lib/gfortran.exp b/gcc/testsuite/lib/gfortran.exp
new file mode 100644
index 00000000000..27640a550a5
--- /dev/null
+++ b/gcc/testsuite/lib/gfortran.exp
@@ -0,0 +1,233 @@
+# Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+# This program 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 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 program; if not, write to the Free Software
+# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# This file is just 'sed -e 's/77/fortran/g' \
+# -e 's/f2c/gfortran' g77.exp > gfortran.exp'
+#
+# with some minor modifications to make it work.
+
+#
+# gfortran support library routines
+#
+load_lib prune.exp
+load_lib gcc-defs.exp
+
+#
+# GFORTRAN_UNDER_TEST is the compiler under test.
+#
+
+
+set gpp_compile_options ""
+
+
+#
+# gfortran_version -- extract and print the version number of the compiler
+#
+
+proc gfortran_version { } {
+ global GFORTRAN_UNDER_TEST
+
+ gfortran_init
+
+ # ignore any arguments after the command
+ set compiler [lindex $GFORTRAN_UNDER_TEST 0]
+
+ # verify that the compiler exists
+ if { [is_remote host] || [which $compiler] != 0 } then {
+ set tmp [remote_exec host "$compiler -v"]
+ set status [lindex $tmp 0];
+ set output [lindex $tmp 1];
+ regexp "version\[^\n\r\]*" $output version
+ if { $status == 0 && [info exists version] } then {
+ if [is_remote host] {
+ clone_output "$compiler $version\n"
+ } else {
+ clone_output "[which $compiler] $version\n"
+ }
+ } else {
+ clone_output "Couldn't determine version of [which $compiler]\n"
+ }
+ } else {
+ # compiler does not exist (this should have already been detected)
+ warning "$compiler does not exist"
+ }
+}
+
+#
+# gfortran_link_flags -- provide new version of gfortran_link_flags
+# (originally from libgloss.exp) which knows about the gcc tree structure
+#
+
+proc gfortran_link_flags { paths } {
+ global rootme
+ global srcdir
+ global ld_library_path
+ global GFORTRAN_UNDER_TEST
+
+ set gccpath ${paths}
+ set libio_dir ""
+ set flags ""
+ set ld_library_path "."
+
+ if { $gccpath != "" } {
+ if [file exists "${gccpath}/libgfortran/.libs/libgfortran.a"] {
+ append flags "-L${gccpath}/libgfortran/.libs "
+ append ld_library_path ":${gccpath}/libgfortran/.libs"
+ }
+ if [file exists "${gccpath}/libgfortran/libgforbegin.a"] {
+ append flags "-L${gccpath}/libgfortran "
+ }
+ if [file exists "${gccpath}/libiberty/libiberty.a"] {
+ append flags "-L${gccpath}/libiberty "
+ }
+ append ld_library_path ":${rootme}"
+ set compiler [lindex $GFORTRAN_UNDER_TEST 0]
+ if { [is_remote host] == 0 && [which $compiler] != 0 } {
+ foreach i "[exec $compiler --print-multi-lib]" {
+ set mldir ""
+ regexp -- "\[a-z0-9=/\.-\]*;" $i mldir
+ set mldir [string trimright $mldir "\;@"]
+ if { "$mldir" == "." } {
+ continue
+ }
+ if { [llength [glob -nocomplain ${rootme}/${mldir}/libgcc_s*.so.*]] == 1 } {
+ append ld_library_path ":${rootme}/${mldir}"
+ }
+ }
+ }
+ }
+
+ # On IRIX 6, we have to set variables akin to LD_LIBRARY_PATH, but
+ # called LD_LIBRARYN32_PATH (for the N32 ABI) and LD_LIBRARY64_PATH
+ # (for the 64-bit ABI). The right way to do this would be to modify
+ # unix.exp -- but that's not an option since it's part of DejaGNU
+ # proper, so we do it here.
+ # The same applies to Darwin (DYLD_LIBRARY_PATH), Solaris 32 bit
+ # (LD_LIBRARY_PATH_32), Solaris 64 bit (LD_LIBRARY_PATH_64), and HP-UX
+ # (SHLIB_PATH).
+ # Doing this does cause trouble when testing cross-compilers.
+ if {![is_remote target]} {
+ global env;
+ if { [info exists env(LD_LIBRARY_PATH)]
+ && $env(LD_LIBRARY_PATH) != "" } {
+ append ld_library_path ":$env(LD_LIBRARY_PATH)";
+ }
+ setenv LD_LIBRARY_PATH $ld_library_path
+ setenv SHLIB_PATH $ld_library_path
+ setenv LD_LIBRARYN32_PATH $ld_library_path
+ setenv LD_LIBRARY64_PATH $ld_library_path
+ setenv LD_LIBRARY_PATH_32 $ld_library_path
+ setenv LD_LIBRARY_PATH_64 $ld_library_path
+ setenv DYLD_LIBRARY_PATH $ld_library_path
+ }
+
+ return "$flags"
+}
+
+#
+# gfortran_init -- called at the start of each subdir of tests
+#
+
+proc gfortran_init { args } {
+ global subdir
+ global gpp_initialized
+ global base_dir
+ global tmpdir
+ global libdir
+ global gluefile wrap_flags;
+ global objdir srcdir
+ global ALWAYS_GFORTRANFLAGS
+ global TOOL_EXECUTABLE TOOL_OPTIONS
+ global GFORTRAN_UNDER_TEST
+ global TESTING_IN_BUILD_TREE
+
+ if ![info exists GFORTRAN_UNDER_TEST] then {
+ if [info exists TOOL_EXECUTABLE] {
+ set GFORTRAN_UNDER_TEST $TOOL_EXECUTABLE;
+ } else {
+ if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } {
+ set GFORTRAN_UNDER_TEST [transform gfortran]
+ } else {
+ set GFORTRAN_UNDER_TEST [findfile $base_dir/../gfortran "$base_dir/../gfortran -B$base_dir/../" [findfile $base_dir/gfortran "$base_dir/gfortran -B$base_dir/" [transform gfortran]]]
+ }
+ }
+ }
+
+ if ![is_remote host] {
+ if { [which $GFORTRAN_UNDER_TEST] == 0 } then {
+ perror "GFORTRAN_UNDER_TEST ($GFORTRAN_UNDER_TEST) does not exist"
+ exit 1
+ }
+ }
+ if ![info exists tmpdir] {
+ set tmpdir "/tmp"
+ }
+
+ if [info exists gluefile] {
+ unset gluefile
+ }
+
+ if { [target_info needs_status_wrapper] != "" } {
+ set gluefile ${tmpdir}/gfortran-testglue.o;
+ set result [build_wrapper $gluefile];
+ if { $result != "" } {
+ set gluefile [lindex $result 0];
+ set wrap_flags [lindex $result 1];
+ } else {
+ unset gluefile
+ }
+ }
+
+ set ALWAYS_GFORTRANFLAGS ""
+
+ if ![is_remote host] {
+ if [info exists TOOL_OPTIONS] {
+ lappend ALWAYS_GFORTRANFLAGS "ldflags=[gfortran_link_flags [get_multilibs ${TOOL_OPTIONS}] ]";
+ } else {
+ lappend ALWAYS_GFORTRANFLAGS "ldflags=[gfortran_link_flags [get_multilibs] ]";
+ }
+ }
+
+ if [info exists TOOL_OPTIONS] {
+ lappend ALWAYS_GFORTRANFLAGS "additional_flags=$TOOL_OPTIONS";
+ }
+
+ verbose -log "ALWAYS_GFORTRANFLAGS set to $ALWAYS_GFORTRANFLAGS"
+
+ verbose "gfortran is initialized" 3
+}
+
+#
+# gfortran_target_compile -- compile a source file
+#
+
+proc gfortran_target_compile { source dest type options } {
+ global tmpdir;
+ global gluefile wrap_flags
+ global ALWAYS_GFORTRANFLAGS;
+ global GFORTRAN_UNDER_TEST;
+
+ if { [target_info needs_status_wrapper] != "" && [info exists gluefile] } {
+ lappend options "libs=${gluefile}"
+ lappend options "ldflags=${wrap_flags}"
+ }
+
+ lappend options "compiler=$GFORTRAN_UNDER_TEST";
+
+ set options [concat "$ALWAYS_GFORTRANFLAGS" $options];
+
+ return [target_compile $source $dest $type $options]
+}
diff --git a/gcc/testsuite/lib/scantree.exp b/gcc/testsuite/lib/scantree.exp
new file mode 100644
index 00000000000..76d1a59fb60
--- /dev/null
+++ b/gcc/testsuite/lib/scantree.exp
@@ -0,0 +1,243 @@
+# Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
+
+# This program 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 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Various utilities for scanning tree dump output, used by gcc-dg.exp and
+# g++-dg.exp.
+#
+# This is largely borrowed from scanasm.exp.
+
+# Utility for scanning compiler result, invoked via dg-final.
+# Call pass if pattern is present, otherwise fail.
+#
+# Argument 0 is the regexp to match.
+# Argument 1 is the suffix for the tree dump file
+# Argument 2 handles expected failures and the like
+proc scan-tree-dump { args } {
+ if { [llength $args] < 2 } {
+ error "scan-tree-dump: too few arguments"
+ return
+ }
+ if { [llength $args] > 3 } {
+ error "scan-tree-dump: too many arguments"
+ return
+ }
+ if { [llength $args] >= 3 } {
+ switch [dg-process-target [lindex $args 2]] {
+ "S" { }
+ "N" { return }
+ "F" { setup_xfail "*-*-*" }
+ "P" { }
+ }
+ }
+
+ # This assumes that we are two frames down from dg-test, and that
+ # it still stores the filename of the testcase in a local variable "name".
+ # A cleaner solution would require a new dejagnu release.
+ upvar 2 name testcase
+
+ # This must match the rule in gcc-dg.exp.
+ set output_file "[glob [file tail $testcase].t??.[lindex $args 1]]"
+
+ set fd [open $output_file r]
+ set text [read $fd]
+ close $fd
+
+ if [regexp -- [lindex $args 0] $text] {
+ pass "$testcase scan-tree-dump [lindex $args 0]"
+ } else {
+ fail "$testcase scan-tree-dump [lindex $args 0]"
+ }
+}
+
+# Call pass if pattern is present given number of times, otherwise fail.
+# Argument 0 is the regexp to match.
+# Argument 1 is number of times the regexp must be found
+# Argument 2 is the suffix for the tree dump file
+# Argument 3 handles expected failures and the like
+proc scan-tree-dump-times { args } {
+ if { [llength $args] < 3 } {
+ error "scan-tree-dump: too few arguments"
+ return
+ }
+ if { [llength $args] > 4 } {
+ error "scan-tree-dump: too many arguments"
+ return
+ }
+ if { [llength $args] >= 4 } {
+ switch [dg-process-target [lindex $args 3]] {
+ "S" { }
+ "N" { return }
+ "F" { setup_xfail "*-*-*" }
+ "P" { }
+ }
+ }
+
+ # This assumes that we are two frames down from dg-test, and that
+ # it still stores the filename of the testcase in a local variable "name".
+ # A cleaner solution would require a new dejagnu release.
+ upvar 2 name testcase
+
+ # This must match the rule in gcc-dg.exp.
+ set output_file "[glob [file tail $testcase].t??.[lindex $args 2]]"
+
+ set fd [open $output_file r]
+ set text [read $fd]
+ close $fd
+
+ if { [llength [regexp -inline -all -- [lindex $args 0] $text]] == [lindex $args 1]} {
+ pass "$testcase scan-tree-dump-times [lindex $args 0] [lindex $args 1]"
+ } else {
+ fail "$testcase scan-tree-dump-times [lindex $args 0] [lindex $args 1]"
+ }
+}
+
+# Call pass if pattern is not present, otherwise fail.
+#
+# Argument 0 is the regexp to match.
+# Argument 1 is the suffix for the tree dump file
+# Argument 2 handles expected failures and the like
+proc scan-tree-dump-not { args } {
+ if { [llength $args] < 2 } {
+ error "scan-tree-dump-not: too few arguments"
+ return
+ }
+ if { [llength $args] > 3 } {
+ error "scan-tree-dump-not: too many arguments"
+ return
+ }
+ if { [llength $args] >= 3 } {
+ switch [dg-process-target [lindex $args 2]] {
+ "S" { }
+ "N" { return }
+ "F" { setup_xfail "*-*-*" }
+ "P" { }
+ }
+ }
+
+ upvar 2 name testcase
+ set output_file "[glob [file tail $testcase].t??.[lindex $args 1]]"
+
+ set fd [open $output_file r]
+ set text [read $fd]
+ close $fd
+
+ if ![regexp -- [lindex $args 0] $text] {
+ pass "$testcase scan-tree-dump-not [lindex $args 0]"
+ } else {
+ fail "$testcase scan-tree-dump-not [lindex $args 0]"
+ }
+}
+
+# Utility for scanning demangled compiler result, invoked via dg-final.
+# Call pass if pattern is present, otherwise fail.
+#
+# Argument 0 is the regexp to match.
+# Argument 1 is the suffix for the tree dump file
+# Argument 2 handles expected failures and the like
+proc scan-tree-dump-dem { args } {
+ global cxxfilt
+ global base_dir
+
+ if { [llength $args] < 2 } {
+ error "scan-tree-dump-dem: too few arguments"
+ return
+ }
+ if { [llength $args] > 3 } {
+ error "scan-tree-dump-dem: too many arguments"
+ return
+ }
+ if { [llength $args] >= 3 } {
+ switch [dg-process-target [lindex $args 2]] {
+ "S" { }
+ "N" { return }
+ "F" { setup_xfail "*-*-*" }
+ "P" { }
+ }
+ }
+
+ # Find c++filt like we find g++ in g++.exp.
+ if ![info exists cxxfilt] {
+ set cxxfilt [findfile $base_dir/../../binutils/cxxfilt \
+ $base_dir/../../binutils/cxxfilt \
+ [findfile $base_dir/../c++filt $base_dir/../c++filt \
+ [findfile $base_dir/c++filt $base_dir/c++filt \
+ [transform c++filt]]]]
+ verbose -log "c++filt is $cxxfilt"
+ }
+
+ upvar 2 name testcase
+ set output_file "[glob [file tail $testcase].t??.[lindex $args 1]]"
+
+ set fd [open "| $cxxfilt < $output_file" r]
+ set text [read $fd]
+ close $fd
+
+ if [regexp -- [lindex $args 0] $text] {
+ pass "$testcase scan-tree-dump-dem [lindex $args 0]"
+ } else {
+ fail "$testcase scan-tree-dump-dem [lindex $args 0]"
+ }
+}
+
+# Call pass if demangled pattern is not present, otherwise fail.
+#
+# Argument 0 is the regexp to match.
+# Argument 1 is the suffix for the tree dump file
+# Argument 2 handles expected failures and the like
+proc scan-tree-dump-dem-not { args } {
+ global cxxfilt
+ global base_dir
+
+ if { [llength $args] < 2 } {
+ error "scan-tree-dump-dem-not: too few arguments"
+ return
+ }
+ if { [llength $args] > 3 } {
+ error "scan-tree-dump-dem-not: too many arguments"
+ return
+ }
+ if { [llength $args] >= 3 } {
+ switch [dg-process-target [lindex $args 2]] {
+ "S" { }
+ "N" { return }
+ "F" { setup_xfail "*-*-*" }
+ "P" { }
+ }
+ }
+
+ # Find c++filt like we find g++ in g++.exp.
+ if ![info exists cxxfilt] {
+ set cxxfilt [findfile $base_dir/../../binutils/cxxfilt \
+ $base_dir/../../binutils/cxxfilt \
+ [findfile $base_dir/../c++filt $base_dir/../c++filt \
+ [findfile $base_dir/c++filt $base_dir/c++filt \
+ [transform c++filt]]]]
+ verbose -log "c++filt is $cxxfilt"
+ }
+
+ upvar 2 name testcase
+ set output_file "[glob [file tail $testcase].t??.[lindex $args 1]]"
+
+ set fd [open "| $cxxfilt < $output_file" r]
+ set text [read $fd]
+ close $fd
+
+ if ![regexp -- [lindex $args 0] $text] {
+ pass "$testcase scan-tree-dump-dem-not [lindex $args 0]"
+ } else {
+ fail "$testcase scan-tree-dump-dem-not [lindex $args 0]"
+ }
+}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 7dfa893ced6..e5043c3aee1 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -198,10 +198,12 @@ proc check_profiling_available { test_what } {
# missing other needed machinery.
if { [istarget mmix-*-*]
|| [istarget arm*-*-elf]
+ || [istarget powerpc-*-eabi*]
|| [istarget strongarm*-*-elf]
|| [istarget xscale*-*-elf]
|| [istarget cris-*-*]
|| [istarget h8300-*-*]
+ || [istarget mips*-*-elf]
|| [istarget *-*-windiss] } {
set profiling_available_saved 0
} else {
diff --git a/gcc/testsuite/objc.dg/image-info.m b/gcc/testsuite/objc.dg/image-info.m
index 5ba3fa4f904..02511bc4b82 100644
--- a/gcc/testsuite/objc.dg/image-info.m
+++ b/gcc/testsuite/objc.dg/image-info.m
@@ -35,4 +35,4 @@ extern void abort(void);
}
@end
-/* { dg-final { scan-assembler "\n.data\n.section __OBJC, __image_info\n\t.align.*\nL_OBJC_IMAGE_INFO.*:\n\t.long\t0\n\t.long\t1\n.data\n.objc_module_info\n" } } */
+/* { dg-final { scan-assembler "\n.data\n.section __OBJC, __image_info.*\n\t.align.*\nL_OBJC_IMAGE_INFO.*:\n\t.long\t0\n\t.long\t1\n.data\n.objc_module_info\n" } } */
diff --git a/gcc/timevar.def b/gcc/timevar.def
index c7ccd53a484..ec942588c0e 100644
--- a/gcc/timevar.def
+++ b/gcc/timevar.def
@@ -59,12 +59,41 @@ DEFTIMEVAR (TV_CPP , "preprocessing")
DEFTIMEVAR (TV_LEX , "lexical analysis")
DEFTIMEVAR (TV_PARSE , "parser")
DEFTIMEVAR (TV_NAME_LOOKUP , "name lookup")
+DEFTIMEVAR (TV_INTEGRATION , "integration")
+DEFTIMEVAR (TV_TREE_GIMPLIFY , "tree gimplify")
+DEFTIMEVAR (TV_TREE_EH , "tree eh")
+DEFTIMEVAR (TV_TREE_CFG , "tree CFG construction")
+DEFTIMEVAR (TV_TREE_CLEANUP_CFG , "tree CFG cleanup")
+DEFTIMEVAR (TV_TREE_PTA , "tree PTA")
+DEFTIMEVAR (TV_TREE_MAY_ALIAS , "tree alias analysis")
+DEFTIMEVAR (TV_TREE_INSERT_PHI_NODES , "tree PHI insertion")
+DEFTIMEVAR (TV_TREE_SSA_REWRITE_BLOCKS, "tree SSA rewrite")
+DEFTIMEVAR (TV_TREE_SSA_OTHER , "tree SSA other")
+DEFTIMEVAR (TV_TREE_OPS , "tree operand scan")
+DEFTIMEVAR (TV_TREE_SSA_DOMINATOR_OPTS , "dominator optimization")
+DEFTIMEVAR (TV_TREE_SRA , "tree SRA")
+DEFTIMEVAR (TV_TREE_CCP , "tree CCP")
+DEFTIMEVAR (TV_TREE_SPLIT_EDGES , "tree split crit edges")
+DEFTIMEVAR (TV_TREE_PRE , "tree PRE")
+DEFTIMEVAR (TV_TREE_PHIOPT , "tree linearize phis")
+DEFTIMEVAR (TV_TREE_FORWPROP , "tree forward propagate")
+DEFTIMEVAR (TV_TREE_DCE , "tree conservative DCE")
+DEFTIMEVAR (TV_TREE_CD_DCE , "tree aggressive DCE")
+DEFTIMEVAR (TV_TREE_DSE , "tree DSE")
+DEFTIMEVAR (TV_TREE_LOOP , "tree loop optimization")
+DEFTIMEVAR (TV_TREE_CH , "tree copy headers")
+DEFTIMEVAR (TV_TREE_SSA_TO_NORMAL , "tree SSA to normal")
+DEFTIMEVAR (TV_TREE_NRV , "tree NRV optimization")
+DEFTIMEVAR (TV_TREE_COPY_RENAME , "tree rename SSA copies")
+DEFTIMEVAR (TV_TREE_SSA_VERIFY , "tree SSA verifier")
+DEFTIMEVAR (TV_TREE_STMT_VERIFY , "tree STMT verifier")
+DEFTIMEVAR (TV_CGRAPH_VERIFY , "callgraph verifier")
+DEFTIMEVAR (TV_DOM_FRONTIERS , "dominance frontiers")
+DEFTIMEVAR (TV_CONTROL_DEPENDENCES , "control dependences")
DEFTIMEVAR (TV_OVERLOAD , "overload resolution")
DEFTIMEVAR (TV_TEMPLATE_INSTANTIATION, "template instantiation")
-DEFTIMEVAR (TV_CGRAPH_VERIFY , "callgraph verifier")
DEFTIMEVAR (TV_EXPAND , "expand")
DEFTIMEVAR (TV_VARCONST , "varconst")
-DEFTIMEVAR (TV_INTEGRATION , "integration")
DEFTIMEVAR (TV_JUMP , "jump")
DEFTIMEVAR (TV_CSE , "CSE")
DEFTIMEVAR (TV_GCSE , "global CSE")
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 39b2ddf1f6f..c15ab99f910 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -73,6 +73,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "target.h"
#include "langhooks.h"
#include "cfglayout.h"
+#include "tree-alias-common.h"
#include "cfgloop.h"
#include "hosthooks.h"
#include "cgraph.h"
@@ -138,6 +139,10 @@ static const char **save_argv;
const char *main_input_filename;
+/* Used to enable -fvar-tracking, -fweb and -frename-registers according
+ to optimize and default_debug_hooks in process_options (). */
+#define AUTODETECT_FLAG_VAR_TRACKING 2
+
/* Current position in real source file. */
location_t input_location;
@@ -177,6 +182,10 @@ int target_flags_explicit;
const struct gcc_debug_hooks *debug_hooks;
+/* Debug hooks - target default. */
+
+static const struct gcc_debug_hooks *default_debug_hooks;
+
/* Other flags saying which kinds of debugging dump have been requested. */
int rtl_dump_and_exit;
@@ -211,6 +220,11 @@ tree current_function_decl;
if none. */
tree current_function_func_begin_label;
+/* A DECL for the current file-scope context. When using IMA, this heads a
+ chain of FILE_DECLs; currently only C uses it. */
+
+tree current_file_decl;
+
/* Nonzero if doing dwarf2 duplicate elimination. */
int flag_eliminate_dwarf2_dups = 0;
@@ -258,8 +272,10 @@ int flag_reorder_blocks_and_partition = 0;
int flag_reorder_functions = 0;
-/* Nonzero if registers should be renamed. */
-
+/* Nonzero if registers should be renamed. When
+ flag_rename_registers == AUTODETECT_FLAG_VAR_TRACKING it will be set
+ according to optimize and default_debug_hooks in process_options (),
+ but we do not do this yet because it triggers aborts in flow.c. */
int flag_rename_registers = 0;
int flag_cprop_registers = 0;
@@ -304,7 +320,8 @@ unsigned local_tick;
int flag_signed_char;
-/* Nonzero means give an enum type only as many bytes as it needs. */
+/* Nonzero means give an enum type only as many bytes as it needs. A value
+ of 2 means it has not yet been initialized. */
int flag_short_enums;
@@ -485,9 +502,11 @@ int flag_complex_divide_method = 0;
int flag_syntax_only = 0;
-/* Nonzero means performs web construction pass. */
+/* Nonzero means performs web construction pass. When flag_web ==
+ AUTODETECT_FLAG_VAR_TRACKING it will be set according to optimize
+ and default_debug_hooks in process_options (). */
-int flag_web;
+int flag_web = AUTODETECT_FLAG_VAR_TRACKING;
/* Nonzero means perform loop optimizer. */
@@ -776,6 +795,11 @@ int flag_guess_branch_prob = 0;
For Fortran: defaults to off. */
int flag_bounds_check = 0;
+/* Mudflap bounds-checking transform. */
+int flag_mudflap = 0;
+int flag_mudflap_threads = 0;
+int flag_mudflap_ignore_reads = 0;
+
/* This will attempt to merge constant section constants, if 1 only
string constants and constants from constant pool, if 2 also constant
variables. */
@@ -789,8 +813,49 @@ int flag_renumber_insns = 1;
/* If nonzero, use the graph coloring register allocator. */
int flag_new_regalloc = 0;
-/* Nonzero if we perform superblock formation. */
+/* If nonzero, use tree-based instead of rtl-based profiling. */
+int flag_tree_based_profiling = 0;
+
+/* Enable SSA-GVN on trees. */
+int flag_tree_gvn = 0;
+
+/* Enable the SSA-PRE tree optimization. */
+int flag_tree_pre = 0;
+
+/* Enable points-to analysis on trees. */
+enum pta_type flag_tree_points_to = PTA_NONE;
+
+/* Enable SSA-CCP on trees. */
+int flag_tree_ccp = 0;
+/* Enable SSA-DCE on trees. */
+int flag_tree_dce = 0;
+
+/* Enable loop header copying on tree-ssa. */
+int flag_tree_ch = 0;
+
+/* Enable scalar replacement of aggregates. */
+int flag_tree_sra = 0;
+
+/* Enable SSA->normal pass memory location coalescing. */
+int flag_tree_combine_temps = 0;
+
+/* Enable SSA->normal pass expression replacement. */
+int flag_tree_ter = 0;
+
+/* Enable SSA->normal live range splitting. */
+int flag_tree_live_range_split = 0;
+
+/* Enable dominator optimizations. */
+int flag_tree_dom = 0;
+
+/* Enable copy rename optimization. */
+int flag_tree_copyrename = 0;
+
+/* Enable dead store elimination. */
+int flag_tree_dse = 0;
+
+/* Nonzero if we perform superblock formation. */
int flag_tracer = 0;
/* Nonzero if we perform whole unit at a time compilation. */
@@ -800,8 +865,6 @@ int flag_unit_at_a_time = 0;
/* Nonzero if we should track variables. When
flag_var_tracking == AUTODETECT_FLAG_VAR_TRACKING it will be set according
to optimize, debug_info_level and debug_hooks in process_options (). */
-
-#define AUTODETECT_FLAG_VAR_TRACKING 2
int flag_var_tracking = AUTODETECT_FLAG_VAR_TRACKING;
/* Values of the -falign-* flags: how much to align labels in code.
@@ -959,6 +1022,7 @@ static const lang_independent_options f_options[] =
{"test-coverage", &flag_test_coverage, 1 },
{"branch-probabilities", &flag_branch_probabilities, 1 },
{"profile", &profile_flag, 1 },
+ {"tree-based-profiling", &flag_tree_based_profiling, 1 },
{"reorder-blocks", &flag_reorder_blocks, 1 },
{"reorder-blocks-and-partition", &flag_reorder_blocks_and_partition, 1},
{"reorder-functions", &flag_reorder_functions, 1 },
@@ -1003,7 +1067,18 @@ static const lang_independent_options f_options[] =
{ "trapv", &flag_trapv, 1 },
{ "wrapv", &flag_wrapv, 1 },
{ "new-ra", &flag_new_regalloc, 1 },
- { "var-tracking", &flag_var_tracking, 1}
+ { "var-tracking", &flag_var_tracking, 1},
+ { "tree-gvn", &flag_tree_gvn, 1 },
+ { "tree-pre", &flag_tree_pre, 1 },
+ { "tree-ccp", &flag_tree_ccp, 1 },
+ { "tree-dce", &flag_tree_dce, 1 },
+ { "tree-dominator-opts", &flag_tree_dom, 1 },
+ { "tree-copyrename", &flag_tree_copyrename, 1 },
+ { "tree-dse", &flag_tree_dse, 1 },
+ { "tree-combine-temps", &flag_tree_combine_temps, 1 },
+ { "tree-ter", &flag_tree_ter, 1 },
+ { "tree-lrs", &flag_tree_live_range_split, 1 },
+ { "tree-ch", &flag_tree_ch, 1 }
};
/* Here is a table, controlled by the tm.h file, listing each -m switch
@@ -1400,18 +1475,6 @@ wrapup_global_declarations (tree *vec, int len)
rest_of_decl_compilation (decl, NULL, 1, 1);
}
}
-
- if (TREE_CODE (decl) == FUNCTION_DECL
- && DECL_INITIAL (decl) != 0
- && DECL_STRUCT_FUNCTION (decl) != 0
- && DECL_STRUCT_FUNCTION (decl)->saved_for_inline
- && (flag_keep_inline_functions
- || (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
- || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
- {
- reconsider = 1;
- output_inline_function (decl);
- }
}
if (reconsider)
@@ -1624,8 +1687,6 @@ compile_file (void)
dw2_output_indirect_constants ();
- targetm.asm_out.file_end ();
-
/* Attach a special .ident directive to the end of the file to identify
the version of GCC which compiled this code. The format of the .ident
string is patterned after the ones produced by native SVR4 compilers. */
@@ -1634,6 +1695,11 @@ compile_file (void)
fprintf (asm_out_file, "%s\"GCC: (GNU) %s\"\n",
IDENT_ASM_OP, version_string);
#endif
+
+ /* This must be at the end. Some target ports emit end of file directives
+ into the assembly file here, and hence we can not output anything to the
+ assembly file after this point. */
+ targetm.asm_out.file_end ();
}
/* Display help for target options. */
@@ -2201,6 +2267,7 @@ general_init (const char *argv0)
/* This must be done after add_params but before argument processing. */
init_ggc_heuristics();
+ init_tree_optimization_passes ();
}
/* Process the options that have been parsed. */
@@ -2219,6 +2286,9 @@ process_options (void)
OVERRIDE_OPTIONS;
#endif
+ if (flag_short_enums == 2)
+ flag_short_enums = targetm.default_short_enums ();
+
/* Set aux_base_name if not already set. */
if (aux_base_name)
;
@@ -2298,6 +2368,11 @@ process_options (void)
warning ("this target machine does not have delayed branches");
#endif
+ if (flag_tree_based_profiling && flag_test_coverage)
+ sorry ("test-coverage not yet implemented in trees.");
+ if (flag_tree_based_profiling && flag_profile_values)
+ sorry ("value-based profiling not yet implemented in trees.");
+
user_label_prefix = USER_LABEL_PREFIX;
if (flag_leading_underscore != -1)
{
@@ -2335,6 +2410,30 @@ process_options (void)
/* Now we know write_symbols, set up the debug hooks based on it.
By default we do nothing for debug output. */
+ if (PREFERRED_DEBUGGING_TYPE == NO_DEBUG)
+ default_debug_hooks = &do_nothing_debug_hooks;
+#if defined(DBX_DEBUGGING_INFO)
+ else if (PREFERRED_DEBUGGING_TYPE == DBX_DEBUG)
+ default_debug_hooks = &dbx_debug_hooks;
+#endif
+#if defined(XCOFF_DEBUGGING_INFO)
+ else if (PREFERRED_DEBUGGING_TYPE == XCOFF_DEBUG)
+ default_debug_hooks = &xcoff_debug_hooks;
+#endif
+#ifdef SDB_DEBUGGING_INFO
+ else if (PREFERRED_DEBUGGING_TYPE == SDB_DEBUG)
+ default_debug_hooks = &sdb_debug_hooks;
+#endif
+#ifdef DWARF2_DEBUGGING_INFO
+ else if (PREFERRED_DEBUGGING_TYPE == DWARF2_DEBUG)
+ default_debug_hooks = &dwarf2_debug_hooks;
+#endif
+#ifdef VMS_DEBUGGING_INFO
+ else if (PREFERRED_DEBUGGING_TYPE == VMS_DEBUG
+ || PREFERRED_DEBUGGING_TYPE == VMS_AND_DWARF2_DEBUG)
+ default_debug_hooks = &vmsdbg_debug_hooks;
+#endif
+
if (write_symbols == NO_DEBUG)
debug_hooks = &do_nothing_debug_hooks;
#if defined(DBX_DEBUGGING_INFO)
@@ -2362,15 +2461,34 @@ process_options (void)
debug_type_names[write_symbols]);
/* Now we know which debug output will be used so we can set
- flag_var_tracking if user has not specified it. */
- if (flag_var_tracking == AUTODETECT_FLAG_VAR_TRACKING)
+ flag_var_tracking, flag_rename_registers and flag_web if the user has
+ not specified them. */
+ if (debug_info_level < DINFO_LEVEL_NORMAL
+ || debug_hooks->var_location == do_nothing_debug_hooks.var_location)
{
- /* User has not specified -f(no-)var-tracking so autodetect it. */
- flag_var_tracking
- = (optimize >= 1 && debug_info_level >= DINFO_LEVEL_NORMAL
- && debug_hooks->var_location != do_nothing_debug_hooks.var_location);
+ if (flag_var_tracking == 1)
+ {
+ if (debug_info_level < DINFO_LEVEL_NORMAL)
+ warning ("variable tracking requested, but useless unless "
+ "producing debug info");
+ else
+ warning ("variable tracking requested, but not supported "
+ "by this debug format");
+ }
+ flag_var_tracking = 0;
}
+ if (flag_rename_registers == AUTODETECT_FLAG_VAR_TRACKING)
+ flag_rename_registers = default_debug_hooks->var_location
+ != do_nothing_debug_hooks.var_location;
+
+ if (flag_web == AUTODETECT_FLAG_VAR_TRACKING)
+ flag_web = optimize >= 2 && (default_debug_hooks->var_location
+ != do_nothing_debug_hooks.var_location);
+
+ if (flag_var_tracking == AUTODETECT_FLAG_VAR_TRACKING)
+ flag_var_tracking = optimize >= 1;
+
/* If auxiliary info generation is desired, open the output file.
This goes in the same directory as the source file--unlike
all the other output files. */
@@ -2428,9 +2546,9 @@ process_options (void)
warning ("-ffunction-sections may affect debugging on some targets");
#endif
- /* The presence of IEEE signaling NaNs, implies all math can trap. */
- if (flag_signaling_nans)
- flag_trapping_math = 1;
+ /* The presence of IEEE signaling NaNs, implies all math can trap. */
+ if (flag_signaling_nans)
+ flag_trapping_math = 1;
}
/* Initialize the compiler back end. */
diff --git a/gcc/toplev.h b/gcc/toplev.h
index 91fea9e253c..daad92fa10e 100644
--- a/gcc/toplev.h
+++ b/gcc/toplev.h
@@ -68,6 +68,7 @@ extern void rest_of_decl_compilation (tree, const char *, int, int);
extern void rest_of_type_compilation (tree, int);
extern void rest_of_compilation (tree);
extern void tree_rest_of_compilation (tree, bool);
+extern void init_tree_optimization_passes (void);
extern void init_optimization_passes (void);
extern void finish_optimization_passes (void);
extern bool enable_rtl_dump_file (int);
@@ -124,6 +125,7 @@ extern int flag_unswitch_loops;
extern int flag_cprop_registers;
extern int time_report;
extern int flag_new_regalloc;
+extern int flag_tree_based_profiling;
/* Things to do with target switches. */
extern void display_target_options (void);
diff --git a/gcc/tracer.c b/gcc/tracer.c
index 1e23a8e236a..9635737ff53 100644
--- a/gcc/tracer.c
+++ b/gcc/tracer.c
@@ -271,7 +271,7 @@ tail_duplicate (void)
}
traced_insns += bb2->frequency * counts [bb2->index];
if (bb2->pred && bb2->pred->pred_next
- && cfg_layout_can_duplicate_bb_p (bb2))
+ && can_duplicate_block_p (bb2))
{
edge e = bb2->pred;
basic_block old = bb2;
@@ -279,7 +279,7 @@ tail_duplicate (void)
while (e->src != bb)
e = e->pred_next;
nduplicated += counts [bb2->index];
- bb2 = cfg_layout_duplicate_bb (bb2, e);
+ bb2 = duplicate_block (bb2, e);
/* Reconsider the original copy of block we've duplicated.
Removing the most common predecessor may make it to be
diff --git a/gcc/tree-alias-ander.c b/gcc/tree-alias-ander.c
new file mode 100644
index 00000000000..3f277342836
--- /dev/null
+++ b/gcc/tree-alias-ander.c
@@ -0,0 +1,933 @@
+/* Tree based Andersen points-to analysis
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Daniel Berlin <dberlin@dberlin.org>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "ggc.h"
+#include "bitmap.h"
+#include "tree-alias-type.h"
+#include "tree-alias-ander.h"
+#include "flags.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "output.h"
+#include "errors.h"
+#include "expr.h"
+#include "diagnostic.h"
+#include "tree.h"
+#include "tree-flow.h"
+#include "tree-inline.h"
+#include "varray.h"
+#include "tree-gimple.h"
+#include "splay-tree.h"
+#include "engine/util.h"
+#include "libcompat/regions.h"
+#include "andersen_terms.h"
+#include "cgraph.h"
+#include "tree-pass.h"
+
+
+/* Andersen's interprocedural points-to analysis.
+ This is a flow-insensitive, context insensitive algorithm.
+
+ This file is an implementation of the alias_ops structure used by
+ tree-alias-common.c to drive PTA analysis.
+
+ All these functions do is generate constraints for and through
+ libbanshee. When we query for a points-to set, we ask libbanshee
+ to solve the constraints and give us the answer. The terms of the
+ constraints are the aterms, which are an opaque data structure
+ that stores libbanshee specific data for the constraints.
+
+ The constraints to be generated come from andersen's paper. By
+ constraint, we mean something like "the points-to set of A must be
+ a subset or equal to the points-to set of B" or "the points-to set
+ of A must include Q". In order to avoid having to write all the
+ constraints directly in the code, we use helper functions such as
+ pta_assignment, pta_rvalue, etc, that generate the necessary
+ constraint terms for us, making for much more readable code.
+
+ One could replace libbanshee with some other constraint solving
+ engine, and you'd simply have to replace the implementation of the
+ pta_* functions, and provide replacements for the aterm specific
+ functions (like making a list of aterms, printing the label of an
+ aterm). However, libbanshee is extremely fast, and extremely low
+ memory usage, so one would be hard pressed to do better than it
+ anyway.
+
+ Understanding how constraint solving and what each constraint means is
+ beyond the scope of this documentation. See the libbanshee
+ documentation, and references therein for more enlightenment.
+
+ That said, our constraints inclusion constraints of set
+ expressions. Given the helper functions, the various inference
+ functions we implement should *look* relatively straightforward.
+
+ In order to save time during queries, we cache the resulting
+ points-to sets of each variable, rather than recalculate them
+ again and again. (libbanshee actually has it's own internal
+ caching, but the function call overhead for calling the solver is
+ non-trivial, given the number of queries).
+
+ Todo: Don't pass alias ops as first argument, just have a global
+ "current_alias_ops". */
+
+static unsigned int id_num = 1;
+static region andersen_rgn;
+static void andersen_simple_assign (struct tree_alias_ops *,
+ alias_var, alias_var);
+static void andersen_addr_assign (struct tree_alias_ops *,
+ alias_var, alias_var);
+static void andersen_ptr_assign (struct tree_alias_ops *,
+ alias_var, alias_var);
+static void andersen_op_assign (struct tree_alias_ops *,
+ alias_var, varray_type, tree, bitmap);
+static void andersen_heap_assign (struct tree_alias_ops *, alias_var);
+static void andersen_assign_ptr (struct tree_alias_ops *,
+ alias_var, alias_var);
+static void andersen_function_def (struct tree_alias_ops *, alias_var,
+ varray_type, alias_var);
+static int andersen_function_call (struct tree_alias_ops *, alias_var,
+ alias_var, varray_type, bitmap);
+static void andersen_init (struct tree_alias_ops *);
+static int print_out_result (splay_tree_node, void *);
+static void andersen_cleanup (struct tree_alias_ops *);
+static bool andersen_may_alias (struct tree_alias_ops *, alias_var,
+ alias_var);
+static bool andersen_same_points_to_set (struct tree_alias_ops *,
+ alias_var, alias_var);
+static bool andersen_empty_points_to_set (struct tree_alias_ops *,
+ alias_var);
+static alias_var andersen_add_var (struct tree_alias_ops *, tree);
+static alias_var andersen_add_var_same (struct tree_alias_ops *,
+ tree, alias_var);
+static bool pointer_destroying_op (tree);
+static aterm_list get_ptset (alias_var);
+static splay_tree ptamap;
+
+
+static struct tree_alias_ops andersen_ops = {
+ andersen_init,
+ andersen_cleanup,
+ andersen_add_var,
+ andersen_add_var_same,
+ andersen_simple_assign,
+ andersen_addr_assign,
+ andersen_ptr_assign,
+ andersen_op_assign,
+ andersen_heap_assign,
+ andersen_assign_ptr,
+ andersen_function_def,
+ andersen_function_call,
+ andersen_may_alias,
+ andersen_same_points_to_set,
+ andersen_empty_points_to_set,
+ 0, /* data */
+ 0, /* Currently non-interprocedural */
+ 1 /* Can do IP on all statics without help. */
+};
+struct tree_alias_ops *andersen_alias_ops = &andersen_ops;
+
+static void term_inclusion (aterm, aterm);
+static void pta_init (void);
+static void pta_reset (void);
+static aterm get_ref (aterm);
+static argterm fun_rec_aterm (aterm_list);
+static aterm pta_make_lam (const char *, aterm, aterm_list);
+static aterm pta_make_ref (const char *);
+static aterm pta_bottom (void);
+static aterm pta_join (aterm, aterm);
+static aterm pta_deref (aterm);
+static aterm pta_rvalue (aterm);
+static aterm pta_address (aterm);
+static void pta_assignment (aterm, aterm);
+static aterm pta_make_fun (const char *, aterm, aterm_list);
+static aterm pta_application (aterm, aterm_list);
+
+typedef aterm contents_type;
+static contents_type pta_get_contents (aterm);
+static void pr_ptset_aterm_elem (aterm);
+static void pta_pr_ptset (contents_type);
+
+/* Hook for debugging. This function is called instead of
+ aterm_inclusion, and lets us print the actual constraints as they
+ are generated. */
+
+static void
+term_inclusion (aterm t1, aterm t2)
+{
+ if (dump_file)
+ {
+ fprintf (dump_file, "Constraint: ");
+ aterm_print (dump_file, t1);
+ fprintf (dump_file, " <= ");
+ aterm_print (dump_file, t2);
+ fprintf (dump_file, "\n");
+ }
+
+ aterm_inclusion (t1, t2);
+}
+
+/* Initialize libbanshee's constraint engine. */
+
+static void
+pta_init (void)
+{
+ andersen_terms_init ();
+}
+
+/* Reset libbanshee's constraint engine. We do this when we are done
+ using it, as it releases the memory libbanshee is using. */
+
+static void
+pta_reset (void)
+{
+ andersen_terms_reset ();
+}
+
+static aterm
+get_ref (aterm t)
+{
+ struct ref_decon r_decon;
+ r_decon = ref_decon (t);
+
+ assert (r_decon.f1);
+
+ return r_decon.f1;
+}
+
+/* Make a function record out of the arguments. */
+
+static argterm
+fun_rec_aterm (aterm_list args)
+{
+ region scratch;
+ int counter = 0;
+ argterm rest, result;
+ aterm_list_scanner scan;
+ aterm temp;
+ char field_name[512];
+ argterm_map map;
+
+ scratch = newregion ();
+ map = new_argterm_map (scratch);
+ aterm_list_scan (args, &scan);
+ while (aterm_list_next (&scan, &temp))
+ {
+ snprintf (field_name, 512, "%d", counter++);
+ argterm_map_cons (argterm_make_field (field_name, temp), map);
+ }
+
+ rest = argterm_wild ();
+ /* rest = argterm_fresh(); */
+
+ /* safe since field_add makes a copy of the string*/
+ result = argterm_row (map, rest);
+
+ deleteregion (scratch);
+
+ return result;
+}
+
+
+static aterm
+pta_make_lam (const char *id, aterm ret, aterm_list args)
+{
+ return lam (label_term_constant (id), fun_rec_aterm (args), ret);
+}
+
+/* Make a label reference to the given id. */
+
+static aterm
+pta_make_ref (const char *id)
+{
+
+ aterm var = aterm_fresh (id);
+
+ label_term tag = label_term_constant (id);
+
+ return ref (tag, var, var);
+}
+
+/* Return the empty set. */
+
+static aterm
+pta_bottom (void)
+{
+ return aterm_zero ();
+}
+
+/* Join two terms, such that anything in set t1 will also be in set
+ t2, and vice versa. */
+
+static aterm
+pta_join (aterm t1, aterm t2)
+{
+ aterm result;
+ region scratch_rgn = newregion ();
+ aterm_list list = new_aterm_list (scratch_rgn);
+
+ aterm_list_cons (t1, list);
+ aterm_list_cons (t2, list);
+
+
+ result = aterm_union (list);
+ deleteregion (scratch_rgn);
+
+ return result;
+}
+
+/* Generate the constraint for a dereference of term t1. */
+
+static aterm
+pta_deref (aterm t1)
+{
+ return ref_proj2 (t1);
+}
+
+/* Generate the constraint for t1 being an rvalue. */
+
+static aterm
+pta_rvalue (aterm t1)
+{
+ return pta_deref (t1);
+}
+
+/* Generate the constraint for taking the address of t1. */
+
+static aterm
+pta_address (aterm t1)
+{
+ return ref (label_term_one (), aterm_one (), t1);
+}
+
+/* Generate the constraint for assigning t2 to t1. */
+
+static void
+pta_assignment (aterm t1, aterm t2)
+{
+ term_inclusion (t1, ref_pat1 (t2));
+}
+
+/* Make a function from the given name, return value, and arguments. */
+
+static aterm
+pta_make_fun (const char *name, aterm ret, aterm_list args)
+{
+ aterm temp;
+ aterm_list_scanner scan;
+ region scratch_rgn = newregion ();
+ aterm_list arg_list = new_aterm_list (scratch_rgn);
+
+ aterm_list_scan (args, &scan);
+
+ while (aterm_list_next (&scan, &temp))
+ {
+ aterm_list_cons (get_ref (temp), arg_list);
+ }
+
+ return pta_make_lam (name, get_ref (ret), arg_list);
+}
+
+/* Return the constraint for calling function T with arguments
+ ACTUALS. */
+
+static aterm
+pta_application (aterm t, aterm_list actuals)
+{
+ argterm args = fun_rec_aterm (actuals);
+
+ term_inclusion (t, lam_pat1 (args));
+ return pta_address (lam_proj2 (t));
+}
+
+/* Return the contents of set expression T. */
+
+static contents_type
+pta_get_contents (aterm t)
+{
+ struct ref_decon t_decon;
+ t_decon = ref_decon (t);
+
+ return t_decon.f1;
+}
+
+/* Print out a points-to set element. */
+
+static void
+pr_ptset_aterm_elem (aterm t)
+{
+ struct ref_decon ref;
+ struct lam_decon lam;
+
+ ref = ref_decon (t);
+ lam = lam_decon (t);
+
+ fprintf (dump_file, ",");
+ if (ref.f0)
+ label_term_print (dump_file, ref.f0);
+ else if (lam.f0)
+ label_term_print (dump_file, lam.f0);
+}
+
+
+/* Print out a points-to set. */
+
+static void
+pta_pr_ptset (contents_type t)
+{
+ int size;
+ region scratch_rgn;
+ aterm_list ptset;
+ scratch_rgn = newregion ();
+ ptset = aterm_list_copy (scratch_rgn, aterm_tlb (t));
+
+ size = aterm_list_length (ptset);
+
+ fprintf (dump_file, "{");
+ if (!aterm_list_empty (ptset))
+ {
+ struct ref_decon ref;
+ struct lam_decon lam;
+ ref = ref_decon (aterm_list_head (ptset));
+ lam = lam_decon (aterm_list_head (ptset));
+ if (ref.f0)
+ label_term_print (dump_file, ref.f0);
+ else if (lam.f0)
+ label_term_print (dump_file, lam.f0);
+
+ /* aterm_pr(stdout,aterm_hd(ptset)); */
+ ptset = aterm_list_tail (ptset);
+ }
+ aterm_list_app (ptset, pr_ptset_aterm_elem);
+ fprintf (dump_file, "}(%d)\n", size);
+ deleteregion (scratch_rgn);
+}
+
+/* Initialize Andersen alias analysis. */
+static int initted = 0;
+
+static void
+andersen_init (struct tree_alias_ops *ops ATTRIBUTE_UNUSED)
+{
+#if 0
+ /* Don't claim we can do ip partial unless we have unit_at_a_time on. */
+ if (!flag_unit_at_a_time)
+#endif
+ andersen_ops.ip_partial = 0;
+ if (!initted || (!andersen_ops.ip_partial && !andersen_ops.ip))
+ {
+ pta_init ();
+ andersen_rgn = newregion ();
+ initted = 1;
+ }
+
+ ptamap = splay_tree_new (splay_tree_compare_pointers, NULL, NULL);
+
+}
+
+static int
+print_out_result (splay_tree_node node, void *data ATTRIBUTE_UNUSED)
+{
+ fprintf (dump_file, "%s :=",
+ alias_get_name (ALIAS_VAR_DECL (((alias_var) node->value))));
+ pta_pr_ptset (pta_get_contents ((aterm) node->key));
+ return 0;
+}
+
+/* Cleanup after Andersen alias analysis. */
+
+static void
+andersen_cleanup (struct tree_alias_ops *ops ATTRIBUTE_UNUSED)
+{
+ if (dump_file)
+ {
+ if (dump_flags & TDF_STATS)
+ {
+ fprintf (dump_file, "\nPoints-to stats:\n");
+ andersen_terms_stats (dump_file);
+ }
+
+ fprintf (dump_file, "\nPoints-to sets:\n");
+ splay_tree_foreach (ptamap, print_out_result, NULL);
+ }
+
+ splay_tree_delete (ptamap);
+
+ if (!andersen_ops.ip_partial && !andersen_ops.ip)
+ {
+ pta_reset ();
+ deleteregion (andersen_rgn);
+ andersen_rgn = NULL;
+ }
+}
+
+/* Add decl to the analyzer, and return a var for it. For
+ Andersen, we create a new alias var for the declaration, and
+ return that. */
+
+static alias_var
+andersen_add_var (struct tree_alias_ops *ops ATTRIBUTE_UNUSED, tree decl)
+{
+ alias_var ret;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Adding variable %s\n",
+ alias_get_name (decl));
+
+ if (alias_get_name (decl) != NULL)
+ {
+ ret = alias_var_new_with_aterm (decl,
+ pta_make_ref (alias_get_name (decl)));
+ }
+ else
+ {
+ char *tmp_name;
+ ASM_FORMAT_PRIVATE_NAME (tmp_name, "unnamed var", id_num++);
+ ret = alias_var_new_with_aterm (decl, pta_make_ref (tmp_name));
+ }
+ splay_tree_insert (ptamap, (splay_tree_key) ALIAS_VAR_ATERM (ret),
+ (splay_tree_value) ret);
+ ALIAS_VAR_PTSET (ret) = NULL;
+
+ return ret;
+}
+
+/* Add a variable to the analyzer that is equivalent (as far as
+ aliases go) to some existing alias variable.
+ For Andersen, we just call a function that does this for us. */
+
+static alias_var
+andersen_add_var_same (struct tree_alias_ops *ops ATTRIBUTE_UNUSED, tree decl,
+ alias_var tv)
+{
+ alias_var ret;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Adding variable %s same as %s\n",
+ alias_get_name (decl), alias_get_name (ALIAS_VAR_DECL (tv)));
+
+ if (alias_get_name (decl) != NULL)
+ ret = alias_var_new_with_aterm (decl,
+ pta_make_ref (alias_get_name (decl)));
+ else
+ {
+ char *tmp_name;
+ ASM_FORMAT_PRIVATE_NAME (tmp_name, "unnamed var", id_num++);
+ ret = alias_var_new_with_aterm (decl, pta_make_ref (tmp_name));
+ }
+
+ pta_join (ALIAS_VAR_ATERM (tv), ALIAS_VAR_ATERM (ret));
+ splay_tree_insert (ptamap, (splay_tree_key) ALIAS_VAR_ATERM (ret),
+ (splay_tree_value) ret);
+ ALIAS_VAR_PTSET (tv) = NULL;
+ ALIAS_VAR_PTSET (ret) = NULL;
+
+ return ret;
+}
+
+/* Inference for simple assignment (lhs = rhs) */
+
+static void
+andersen_simple_assign (struct tree_alias_ops *ops ATTRIBUTE_UNUSED,
+ alias_var lhs, alias_var rhs)
+{
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Simple assignment %s = %s\n",
+ alias_get_name (ALIAS_VAR_DECL (lhs)),
+ alias_get_name (ALIAS_VAR_DECL (rhs)));
+ if (lhs == rhs)
+ return;
+
+ /* The rvalue is just the term itself, and we generate a constraint
+ for assigning it to the lhs. */
+ pta_assignment (ALIAS_VAR_ATERM (lhs),
+ pta_rvalue (ALIAS_VAR_ATERM (rhs)));
+}
+
+/* Inference for address assignment (lhs = &addr) */
+
+static void
+andersen_addr_assign (struct tree_alias_ops *ops ATTRIBUTE_UNUSED,
+ alias_var lhs, alias_var addr)
+{
+ if (addr == NULL)
+ return;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Address assignment %s = &%s\n",
+ alias_get_name (ALIAS_VAR_DECL (lhs)),
+ alias_get_name (ALIAS_VAR_DECL (addr)));
+
+ /* The rvalue here is the address of a term, and we generate a
+ constraint to assign this address to the lhs. */
+ pta_assignment (ALIAS_VAR_ATERM (lhs),
+ pta_rvalue (pta_address (ALIAS_VAR_ATERM (addr))));
+}
+
+
+/* Inference for pointer assignment (lhs = *ptr) */
+
+static void
+andersen_ptr_assign (struct tree_alias_ops *ops ATTRIBUTE_UNUSED,
+ alias_var lhs, alias_var ptr)
+{
+
+ if (ptr == NULL)
+ return;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Pointer assignment %s = *%s\n",
+ alias_get_name (ALIAS_VAR_DECL (lhs)),
+ alias_get_name (ALIAS_VAR_DECL (ptr)));
+
+ pta_assignment (ALIAS_VAR_ATERM (lhs),
+ pta_rvalue (pta_deref (ALIAS_VAR_ATERM (ptr))));
+
+}
+
+/* Determine if OP destroys the current assumed to be valid pointer
+ (whether it generates a new valid pointer is not relevant). */
+
+static bool
+pointer_destroying_op (tree op)
+{
+ switch (TREE_CODE (op))
+ {
+ case TRUTH_AND_EXPR:
+ case TRUTH_OR_EXPR:
+ case TRUTH_NOT_EXPR:
+ case LT_EXPR:
+ case GT_EXPR:
+ case GE_EXPR:
+ case LE_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ case LSHIFT_EXPR:
+ case RSHIFT_EXPR:
+ case LROTATE_EXPR:
+ case RROTATE_EXPR:
+ return true;
+ default:
+ return false;
+ }
+ return false;
+}
+
+/* Inference rule for operations (lhs = operation(operands)). */
+
+static void
+andersen_op_assign (struct tree_alias_ops *ops ATTRIBUTE_UNUSED,
+ alias_var lhs, varray_type operands, tree operation,
+ bitmap addrargs)
+{
+ aterm newvar = NULL;
+
+ if (VARRAY_ACTIVE_SIZE (operands) == 0)
+ return;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Op assignment %s = ",
+ alias_get_name (ALIAS_VAR_DECL (lhs)));
+ print_generic_stmt (dump_file, operation, dump_flags);
+ fprintf (dump_file, "\n");
+ }
+
+
+ /* Pointer destroying operations do not give us the same valid pointer
+ back, and thus, are assignment to pta_bottom. */
+ if (pointer_destroying_op (operation))
+ {
+ pta_assignment (ALIAS_VAR_ATERM (lhs), pta_rvalue (pta_bottom ()));
+ return;
+ }
+
+ /* Operations in general we can't track the exact effect of. Thus,
+ we conservatively assume that it could make the LHS point to
+ *anything* the RHS points to. To signify this, we join the RHS
+ variables together and assign it to the LHS. */
+ /* The >2 case occurs when we are dealing with constructors. */
+ if (VARRAY_ACTIVE_SIZE (operands) > 2)
+ {
+ size_t i;
+ alias_var tv1 = VARRAY_GENERIC_PTR (operands, 0);
+ newvar = ALIAS_VAR_ATERM (tv1);
+ for (i = 1; i < VARRAY_ACTIVE_SIZE (operands); i++)
+ {
+ alias_var tempvar = VARRAY_GENERIC_PTR (operands, i);
+ aterm t2 = ALIAS_VAR_ATERM (tempvar);
+ if (bitmap_bit_p (addrargs, i))
+ newvar = pta_join (newvar, pta_address (t2));
+ else
+ newvar = pta_join (newvar, t2);
+ }
+ }
+ else if (VARRAY_ACTIVE_SIZE (operands) == 2)
+ {
+ alias_var tv1 = VARRAY_GENERIC_PTR (operands, 0);
+ alias_var tv2 = VARRAY_GENERIC_PTR (operands, 1);
+ aterm t1 = ALIAS_VAR_ATERM (tv1);
+ aterm t2 = ALIAS_VAR_ATERM (tv2);
+ if (bitmap_bit_p (addrargs, 0) && bitmap_bit_p (addrargs, 1))
+ newvar = pta_join (pta_address (t1), pta_address (t2));
+ else if (bitmap_bit_p (addrargs, 0))
+ newvar = pta_join (pta_address (t1), t2);
+ else if (bitmap_bit_p (addrargs, 1))
+ newvar = pta_join (t1, pta_address (t2));
+ else
+ newvar = pta_join (t1, t2);
+ }
+ else if (VARRAY_ACTIVE_SIZE (operands) == 1)
+ {
+ alias_var tv1 = VARRAY_GENERIC_PTR (operands, 0);
+ aterm t1 = ALIAS_VAR_ATERM (tv1);
+ if (bitmap_bit_p (addrargs, 0))
+ newvar = pta_address (t1);
+ else
+ newvar = t1;
+ }
+ pta_assignment (ALIAS_VAR_ATERM (lhs), pta_rvalue (newvar));
+}
+
+/* Inference for heap assignment (lhs = alloc). */
+
+static void
+andersen_heap_assign (struct tree_alias_ops *ops ATTRIBUTE_UNUSED,
+ alias_var lhs ATTRIBUTE_UNUSED)
+{
+#if 0
+ alias_type type1;
+ ECR tau;
+ type1 = ECR_get_type (alias_var_get_ECR (lhs));
+ tau = alias_ltype_loc (type1);
+
+ if (ECR_get_type (tau) == alias_bottom)
+ ECR_set_type (tau, alias_ltype_new ());
+#endif
+}
+
+/* Inference for assignment to a pointer (*ptr = rhs). */
+
+static void
+andersen_assign_ptr (struct tree_alias_ops *ops ATTRIBUTE_UNUSED,
+ alias_var ptr, alias_var rhs)
+{
+
+ if (rhs == NULL)
+ return;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Assignment to pointer *%s = %s\n",
+ alias_get_name (ALIAS_VAR_DECL (ptr)),
+ alias_get_name (ALIAS_VAR_DECL (rhs)));
+ /* The RHS is a standard rvalue, and the LHS is a pointer
+ dereference. */
+ pta_assignment (pta_deref (ALIAS_VAR_ATERM (ptr)),
+ pta_rvalue (ALIAS_VAR_ATERM (rhs)));
+}
+
+/* Inference for a function definition. */
+
+static void
+andersen_function_def (struct tree_alias_ops *ops ATTRIBUTE_UNUSED,
+ alias_var func, varray_type params,
+ alias_var retval)
+{
+ aterm_list args = new_aterm_list (andersen_rgn);
+ aterm fun_type;
+
+ size_t l = VARRAY_ACTIVE_SIZE (params);
+ size_t i;
+
+ /* Set up the arguments for the new function type. */
+ for (i = 0; i < l; i++)
+ {
+ alias_var tv = VARRAY_GENERIC_PTR (params, i);
+ aterm_list_cons (ALIAS_VAR_ATERM (tv), args);
+ }
+ /* Create the function type. */
+ fun_type = pta_make_fun (alias_get_name (ALIAS_VAR_DECL (func)),
+ ALIAS_VAR_ATERM (retval), args);
+
+ /* Assign the function type itself to the function. */
+ pta_assignment (ALIAS_VAR_ATERM (func), fun_type);
+}
+
+/* Inference for a function call assignment. */
+
+static int
+andersen_function_call (struct tree_alias_ops *ops,
+ alias_var lhs, alias_var func,
+ varray_type args, bitmap addrargs)
+{
+ aterm_list actuals = new_aterm_list (andersen_rgn);
+ aterm ftype = ALIAS_VAR_ATERM (func);
+ aterm ret = NULL;
+ aterm res;
+ tree decl = ALIAS_VAR_DECL (func);
+
+ size_t i;
+
+ if (lhs)
+ ret = ALIAS_VAR_ATERM (lhs);
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (args); i++)
+ {
+ alias_var argtv = VARRAY_GENERIC_PTR (args, i);
+ aterm arg = ALIAS_VAR_ATERM (argtv);
+ if (bitmap_bit_p (addrargs, i))
+ aterm_list_cons (pta_rvalue (pta_address (arg)), actuals);
+ else
+ aterm_list_cons (pta_rvalue (arg), actuals);
+ }
+ aterm_list_reverse (actuals);
+
+ /* Generate the constraint that calls the function with it's
+ arguments, and gives us the result. This in turn applies
+ whatever constraints are in that function. */
+ res = pta_application (pta_rvalue (ftype), actuals);
+ /* We only need care about the result if we have an LHS. If we do,
+ assign the result of function application back to the LHS. */
+ if (ret)
+ pta_assignment (ret, pta_rvalue (res));
+
+ /* We can handle functions we've got trees for. non-statics will
+ just have incoming parameters assigned to global_var if
+ necessary. */
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_PTA_ALIASVAR (decl)
+ && ops->ip_partial
+ && (cgraph_local_info (decl)->local))
+ {
+ return 0;
+ }
+ return 1;
+}
+
+
+/* Simple pointer comparison function for list sorting. */
+
+static int
+simple_cmp (const aterm a, const aterm b)
+{
+ return (int *)a - (int *)b;
+}
+
+
+/* Get the points-to set for TV, caching if it we had to compute it. */
+
+static aterm_list
+get_ptset (alias_var tv)
+{
+ aterm_list ptset;
+ ptset = ALIAS_VAR_PTSET (tv);
+ if (ptset != NULL)
+ return ptset;
+ ptset = aterm_tlb (pta_get_contents (ALIAS_VAR_ATERM (tv)));
+ ALIAS_VAR_PTSET (tv) = ptset;
+ return ptset;
+}
+
+
+/* Determine if two aterm's have the same points-to set. */
+
+static bool
+andersen_same_points_to_set (struct tree_alias_ops *ops ATTRIBUTE_UNUSED,
+ alias_var ptrtv, alias_var vartv)
+{
+ aterm_list ptset1, ptset2;
+ aterm_list_scanner scan1, scan2;
+ aterm data1, data2;
+ region scratch_rgn = newregion ();
+
+ ptset1 = get_ptset (ptrtv);
+ ptset2 = get_ptset (vartv);
+
+ if (aterm_list_length (ptset1) != aterm_list_length (ptset2))
+ {
+ deleteregion (scratch_rgn);
+ return false;
+ }
+
+ if (ptset1 == ptset2)
+ {
+ deleteregion (scratch_rgn);
+ return true;
+ }
+
+ ptset1 = aterm_list_copy (scratch_rgn, ptset1);
+ ptset2 = aterm_list_copy (scratch_rgn, ptset2);
+
+ if (aterm_list_length (ptset1) != aterm_list_length (ptset2))
+ {
+ deleteregion (scratch_rgn);
+ return false;
+ }
+
+ ptset1 = aterm_list_sort (ptset1, simple_cmp);
+ ptset2 = aterm_list_sort (ptset2, simple_cmp);
+
+ aterm_list_scan (ptset1, &scan1);
+ aterm_list_scan (ptset2, &scan2);
+ while (aterm_list_next (&scan1, &data1))
+ {
+ aterm_list_next (&scan2, &data2);
+ if (data1 != data2)
+ {
+ deleteregion(scratch_rgn);
+ return false;
+ }
+ }
+ deleteregion(scratch_rgn);
+ return true;
+}
+
+
+/* Determine if two variables may alias. In our case, this means
+ whether the decl represented by PTRTV can point to VARTV. */
+
+static bool
+andersen_may_alias (struct tree_alias_ops *ops ATTRIBUTE_UNUSED,
+ alias_var ptrtv, alias_var vartv)
+{
+ aterm_list ptset;
+ ptset = get_ptset (ptrtv);
+
+ if (aterm_list_empty (ptset))
+ return false;
+
+ return aterm_list_member (ptset, ALIAS_VAR_ATERM (vartv));
+}
+
+/* Determine whether PTRTV has an empty points-to set. IE it may not
+ point to anything. */
+
+static bool
+andersen_empty_points_to_set (struct tree_alias_ops *ops ATTRIBUTE_UNUSED,
+ alias_var ptrtv)
+{
+ aterm_list ptset;
+ ptset = get_ptset (ptrtv);
+ return aterm_list_empty (ptset);
+}
diff --git a/gcc/tree-alias-ander.h b/gcc/tree-alias-ander.h
new file mode 100644
index 00000000000..92e313fd066
--- /dev/null
+++ b/gcc/tree-alias-ander.h
@@ -0,0 +1,7 @@
+#ifndef TREE_ALIAS_ANDER
+#define TREE_ALIAS_ANDER
+#include "tree-alias-common.h"
+
+
+extern struct tree_alias_ops *andersen_alias_ops;
+#endif
diff --git a/gcc/tree-alias-common.c b/gcc/tree-alias-common.c
new file mode 100644
index 00000000000..f7b6fed5f34
--- /dev/null
+++ b/gcc/tree-alias-common.c
@@ -0,0 +1,1264 @@
+/* Tree based points-to analysis
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Daniel Berlin <dberlin@dberlin.org>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "ggc.h"
+#include "tree-alias-type.h"
+#include "bitmap.h"
+#include "tree-alias-common.h"
+/* If we have andersen's points-to analysis, include it. */
+#ifdef HAVE_BANSHEE
+#include "tree-alias-ander.h"
+#endif
+#include "flags.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "output.h"
+#include "errors.h"
+#include "expr.h"
+#include "diagnostic.h"
+#include "tree.h"
+#include "c-common.h"
+#include "tree-flow.h"
+#include "tree-inline.h"
+#include "varray.h"
+#include "c-tree.h"
+#include "tree-gimple.h"
+#include "hashtab.h"
+#include "function.h"
+#include "cgraph.h"
+#include "tree-pass.h"
+#include "timevar.h"
+
+/* Reduce ifdefery later. */
+#ifndef HAVE_BANSHEE
+#define HAVE_BANSHEE 0
+#endif
+
+/* This file contains the implementation of the common parts of the
+ tree points-to analysis infrastructure.
+
+ Overview:
+
+ This file contains the points-to analysis driver. It does two main things:
+ 1. Keeps track of the PTA data for each variable (IE the data each
+ specific PTA implementation wants to keep associated with a
+ variable).
+ 2. Walks the function trees, calling the appropriate functions that
+ each PTA implementation has implemented.
+
+ In order to speed up PTA queries, the PTA specific data is stored
+ in the tree for *_DECL's, in DECL_PTA_ALIASVAR. This way, we only
+ need to use the hash table for non-DECL's. */
+#define FIELD_BASED 0
+
+/* Array of all created alias_vars.
+ Note that this should contain all the alias_vars we wanted
+ marked during GC. */
+static GTY((param_is (union alias_var_def))) varray_type alias_vars = NULL;
+struct tree_alias_ops *current_alias_ops;
+
+/* Array of local (to a function) alias_vars.
+ Note that this should contain all the alias_vars that are
+ local to this function. We delete these from alias_vars before
+ collection. */
+static GTY(()) varray_type local_alias_vars;
+static GTY(()) varray_type local_alias_varnums;
+tree pta_global_var;
+static bitmap addrargs;
+static alias_var get_alias_var_decl (tree);
+static alias_var get_alias_var (tree);
+static void find_func_aliases (tree);
+static void deal_with_call_aliasing (tree, alias_var);
+static alias_var create_fun_alias_var_ptf (tree, tree);
+static alias_var create_fun_alias_var (tree, int);
+static alias_var create_alias_var (tree);
+static void intra_function_call (varray_type);
+static void get_values_from_constructor (tree, varray_type *, bitmap, int *);
+static bool call_may_clobber (tree);
+static bool call_may_return (tree);
+
+/* Return true if a EXPR, which is a CALL_EXPR, may clobber variables. */
+
+static bool
+call_may_clobber (tree expr)
+{
+ int flags;
+
+ if (TREE_CODE (expr) != CALL_EXPR)
+ return false;
+
+ flags = call_expr_flags (expr);
+ return (! (flags & (ECF_CONST | ECF_PURE | ECF_NORETURN)));
+}
+
+/* Return true if a EXPR, which is a CALL_EXPR, may return. */
+
+static bool
+call_may_return (tree expr)
+{
+ int flags;
+
+ if (TREE_CODE (expr) != CALL_EXPR)
+ return false;
+
+ flags = call_expr_flags (expr);
+ return ! (flags & ECF_NORETURN);
+}
+
+/* Get the alias_var for DECL.
+ Creates the alias_var if it does not exist already. Also
+ handles FUNCTION_DECL properly. */
+
+static alias_var
+get_alias_var_decl (tree decl)
+{
+ alias_var newvar;
+ if (TREE_CODE (decl) == FIELD_DECL)
+ abort ();
+ if (DECL_P (decl))
+ {
+ if (DECL_PTA_ALIASVAR (decl))
+ return DECL_PTA_ALIASVAR (decl);
+ }
+
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ newvar = create_fun_alias_var (decl, 0);
+ else
+ {
+ newvar = create_alias_var (decl);
+ /* Assign globals to global var for purposes of intraprocedural
+ analysis. */
+ if ((DECL_CONTEXT (decl) == NULL
+ || TREE_PUBLIC (decl)
+ || TREE_STATIC (decl)
+ || decl_function_context (decl) == NULL)
+ && decl != pta_global_var)
+ {
+ current_alias_ops->addr_assign (current_alias_ops,
+ get_alias_var (pta_global_var),
+ newvar);
+ /* If the global has some DECL_INITIAL, we need to process
+ it here. */
+ if (DECL_INITIAL (decl))
+ find_func_aliases (decl);
+ }
+ }
+
+ if (!current_alias_ops->ip)
+ {
+ if (!current_alias_ops->ip_partial
+ || (TREE_CODE (decl) != FUNCTION_DECL
+ && TREE_CODE (decl) != PARM_DECL))
+ {
+ VARRAY_PUSH_INT (local_alias_varnums, ALIAS_VAR_VARNUM (newvar));
+ VARRAY_PUSH_TREE (local_alias_vars, decl);
+ }
+ }
+ return newvar;
+}
+
+/* Get the alias_var for an expression EXPR.
+ Note that this function expects to only be handed a RHS or LHS, not
+ a MODIFY_EXPR. */
+
+static alias_var
+get_alias_var (tree expr)
+{
+ /* If it's a decl, get the alias var of the decl. We farm this off
+ to get_alias_var_decl so it can abort if the alias var doesn't
+ exist, and in case something else *knows* it has a decl, and
+ wants the alias var. */
+
+ if (DECL_P (expr))
+ return get_alias_var_decl (expr);
+
+ /* True constants have no aliases (unless modifiable strings are on,
+ in which case i don't think we'll end up with a STRING_CST anyway) */
+ if (TREE_CODE_CLASS (TREE_CODE (expr)) == 'c')
+ return NULL;
+
+
+ switch (TREE_CODE (expr))
+ {
+ case ARRAY_REF:
+ {
+ /* Find the first non-array ref, and return it's alias
+ variable */
+ tree p;
+ for (p = expr; TREE_CODE (p) == ARRAY_REF;
+ p = TREE_OPERAND (p, 0));
+ return get_alias_var (p);
+ }
+ break;
+ case COMPONENT_REF:
+ {
+#if FIELD_BASED
+ bool safe = true;
+ tree p;
+ for (p = expr;
+ TREE_CODE (p) == COMPONENT_REF || TREE_CODE (p) == INDIRECT_REF;
+ p = TREE_OPERAND (p, 0))
+ {
+ if (TREE_CODE (TREE_TYPE (p)) == UNION_TYPE
+ || TREE_CODE (TREE_TYPE (p)) == QUAL_UNION_TYPE)
+ {
+ safe = false;
+ break;
+ }
+ }
+ if (!safe)
+ {
+ for (p = expr; TREE_CODE (p) == COMPONENT_REF;
+ p = TREE_OPERAND (p, 0));
+ return get_alias_var (p);
+ }
+ else
+ {
+ return get_alias_var (TREE_OPERAND (expr, 1));
+ }
+#else
+ /* Find the first non-component ref, and return its alias variable. */
+ tree p;
+ for (p = expr; TREE_CODE (p) == COMPONENT_REF;
+ p = TREE_OPERAND (p, 0));
+ return get_alias_var (p);
+#endif
+ }
+ break;
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ case NOP_EXPR:
+ case CONVERT_EXPR:
+ case FIX_TRUNC_EXPR:
+ case FIX_CEIL_EXPR:
+ case FIX_FLOOR_EXPR:
+ case FIX_ROUND_EXPR:
+ case ADDR_EXPR:
+ case INDIRECT_REF:
+ case BIT_FIELD_REF:
+ /* If it's a ref or cast or conversion of something, get the
+ alias var of the something. */
+ return get_alias_var (TREE_OPERAND (expr, 0));
+ break;
+
+ default:
+ return NULL;
+ }
+}
+
+/* Perform conservative aliasing for an intraprocedural mode function
+ call. ARGS are the arguments that were passed to that function
+ call. */
+
+static void
+intra_function_call (varray_type args)
+{
+ size_t l = VARRAY_ACTIVE_SIZE (args);
+ size_t i;
+ alias_var av = get_alias_var (pta_global_var);
+
+ /* We assume assignments among the actual parameters. */
+ for (i = 0; i < l; i++)
+ {
+ alias_var argi = VARRAY_GENERIC_PTR (args, i);
+ size_t j;
+ for (j = 0; j < l; j++)
+ {
+ alias_var argj;
+ if (i == j)
+ continue;
+ argj = VARRAY_GENERIC_PTR (args, j);
+ /* Restricted pointers can't be aliased with other
+ restricted pointers. */
+ if (!TYPE_RESTRICT (TREE_TYPE (ALIAS_VAR_DECL (argi)))
+ || !TYPE_RESTRICT (TREE_TYPE (ALIAS_VAR_DECL (argj))))
+ /* Do a bit of TBAA to avoid pointless assignments. */
+ if (alias_sets_conflict_p (get_alias_set (ALIAS_VAR_DECL (argi)),
+ get_alias_set (ALIAS_VAR_DECL (argj))))
+ current_alias_ops->simple_assign (current_alias_ops, argi, argj);
+ }
+ }
+ /* We assume that an actual parameter can point to any global. */
+ for (i = 0; i < l; i++)
+ {
+ alias_var argav = VARRAY_GENERIC_PTR (args, i);
+ /* Restricted pointers can't be aliased with other
+ restricted pointers. */
+ if (!TYPE_RESTRICT (TREE_TYPE (ALIAS_VAR_DECL (argav)))
+ || !TYPE_RESTRICT (TREE_TYPE (ALIAS_VAR_DECL (av))))
+ {
+ /* Arguments can alias globals, and whatever they point to
+ can point to a global as well. */
+ current_alias_ops->simple_assign (current_alias_ops, argav, av);
+ }
+ }
+}
+
+/* Put all pointers in a constructor in an array. */
+
+static void
+get_values_from_constructor (tree constructor, varray_type *vals,
+ bitmap addrargs, int *i)
+{
+ tree elt_list;
+ switch (TREE_CODE (constructor))
+ {
+ case CONSTRUCTOR:
+ {
+ for (elt_list = CONSTRUCTOR_ELTS (constructor);
+ elt_list;
+ elt_list = TREE_CHAIN (elt_list))
+ {
+ tree value = TREE_VALUE (elt_list);
+ if (TREE_CODE (value) == TREE_LIST
+ || TREE_CODE (value) == CONSTRUCTOR)
+ {
+ get_values_from_constructor (value, vals, addrargs, i); }
+ else
+ {
+ alias_var aav;
+ aav = get_alias_var (value);
+ if (aav)
+ VARRAY_PUSH_GENERIC_PTR (*vals, aav);
+ if (TREE_CODE (value) == ADDR_EXPR)
+ bitmap_set_bit (addrargs, *i);
+ *i = *i + 1;
+ }
+ }
+ }
+ break;
+ case TREE_LIST:
+ for (elt_list = constructor;
+ elt_list;
+ elt_list = TREE_CHAIN (elt_list))
+ {
+ get_values_from_constructor (TREE_VALUE (elt_list), vals, addrargs, i);
+ }
+ break;
+ default:
+ abort();
+ }
+}
+
+/* Deal with the possible return values of a call that we don't have
+ actual PTA info about. */
+
+static void
+deal_with_call_aliasing (tree callargs, alias_var lhsAV)
+{
+ tree arg, argp;
+
+ for (argp = callargs;
+ argp;
+ argp = TREE_CHAIN (argp))
+ {
+ arg = TREE_VALUE (argp);
+ /* If we take the address of a variable directly in the
+ argument, the return value could be the address of that
+ variable. */
+ if (TREE_CODE (arg) == ADDR_EXPR)
+ current_alias_ops->addr_assign (current_alias_ops, lhsAV,
+ get_alias_var (arg));
+ /* If we pass in a pointer, we could return that pointer. */
+ else if (POINTER_TYPE_P (TREE_TYPE (arg)))
+ {
+ alias_var argtv = get_alias_var (arg);
+ if (argtv)
+ current_alias_ops->simple_assign (current_alias_ops, lhsAV,
+ argtv);
+ }
+ }
+}
+
+/* Find the operand of the component ref that actually is doing
+ something to the DECL */
+static tree
+find_op_of_decl (tree cref)
+{
+ while (!DECL_P (TREE_OPERAND (cref, 0)))
+ {
+ cref = TREE_OPERAND (cref, 0);
+ }
+ return cref;
+}
+
+
+/* Tree walker that is the heart of the aliasing infrastructure.
+ TP is a pointer to the current tree.
+ WALK_SUBTREES specifies whether to continue traversing subtrees or
+ not.
+ Returns NULL_TREE when we should stop.
+
+ This function is the main part of the aliasing infrastructure. It
+ walks the trees, calling the appropriate alias analyzer functions to process
+ various statements. */
+
+static void
+find_func_aliases (tree stp)
+{
+ if (TREE_CODE (stp) == RETURN_EXPR)
+ {
+ stp = TREE_OPERAND (stp, 0);
+ if (!stp)
+ return;
+ }
+
+ if (TREE_CODE (stp) == MODIFY_EXPR
+ || (DECL_P (stp) && DECL_INITIAL (stp) != NULL_TREE ))
+ {
+ tree op0, op1;
+ alias_var lhsAV = NULL;
+ alias_var rhsAV = NULL;
+
+ if (DECL_P (stp))
+ {
+ op0 = stp;
+ op1 = DECL_INITIAL (stp);
+ }
+ else
+ {
+ op0 = TREE_OPERAND (stp, 0);
+ op1 = TREE_OPERAND (stp, 1);
+ }
+ /* lhsAV should always have an alias variable */
+ lhsAV = get_alias_var (op0);
+ if (!lhsAV)
+ return;
+ /* rhsAV might not have one, c.f. c = 5 */
+ rhsAV = get_alias_var (op1);
+#if !FIELD_BASED
+ while (TREE_CODE (op1) == COMPONENT_REF
+ && TREE_CODE (TREE_OPERAND (op1, 0)) == COMPONENT_REF)
+ {
+ op1 = TREE_OPERAND (op1, 0);
+ }
+ while (TREE_CODE (op1) == BIT_FIELD_REF)
+ {
+ op1 = TREE_OPERAND (op1, 0);
+ }
+ /* Take care of fact that we may have multi-level component
+ refs. */
+ if (TREE_CODE (op1) == COMPONENT_REF)
+ op1 = find_op_of_decl (op1);
+#endif
+
+ /* You would think we could test rhsAV at the top, rather than
+ 50 separate times, but we can't, because it can be NULL for
+ operator assignments, where we'd still collect the individual
+ alias vars for the operator. */
+
+ /* Note that structures are treated as a single alias
+ variable, since we can disambiguate based on TBAA first,
+ and fall back on points-to. */
+ /* x = <something> */
+ if (is_gimple_variable (op0))
+ {
+ /* x = y */
+ if (is_gimple_variable (op1))
+ {
+ if (rhsAV != NULL)
+ current_alias_ops->simple_assign (current_alias_ops, lhsAV,
+ rhsAV);
+ }
+ /* x = foo.y */
+ else if (TREE_CODE (op1) == COMPONENT_REF
+ && DECL_P (TREE_OPERAND (op1, 0)))
+ {
+ if (rhsAV != NULL)
+ current_alias_ops->simple_assign (current_alias_ops, lhsAV,
+ rhsAV);
+ }
+ /* x = (cast) [maybe-addr-expr] y */
+ else if (is_gimple_cast (op1))
+ {
+ tree stripped_op1 = op1;
+ STRIP_NOPS (stripped_op1);
+ if (rhsAV != NULL)
+ {
+ if (TREE_CODE (stripped_op1) == ADDR_EXPR)
+ current_alias_ops->addr_assign (current_alias_ops, lhsAV,
+ rhsAV);
+ else
+ current_alias_ops->simple_assign (current_alias_ops, lhsAV,
+ rhsAV);
+ }
+ }
+ /* x = *y or x = foo->y */
+ else if (TREE_CODE (op1) == INDIRECT_REF
+ || TREE_CODE (op1) == ARRAY_REF
+ || (TREE_CODE (op1) == COMPONENT_REF
+ && TREE_CODE (TREE_OPERAND (op1, 0)) == INDIRECT_REF))
+ {
+ if (rhsAV != NULL)
+ current_alias_ops->ptr_assign (current_alias_ops, lhsAV,
+ rhsAV);
+ }
+ /* x = &y = x = &foo.y */
+ else if (TREE_CODE (op1) == ADDR_EXPR)
+ {
+ if (rhsAV != NULL)
+ current_alias_ops->addr_assign (current_alias_ops, lhsAV,
+ rhsAV);
+ }
+ /* x = func(...) */
+ else if (TREE_CODE (op1) == CALL_EXPR)
+ {
+ /* Heap assignment. These are __attribute__ malloc or
+ something, i'll deal with it later. */
+ if (0)
+ {}
+ else
+ {
+
+ /* NORETURN functions have no effect on aliasing. */
+ if (call_may_return (op1))
+ {
+ varray_type args;
+ tree arg;
+ tree callop0, callop1;
+ int argnum;
+
+ /* Collect the arguments */
+ VARRAY_GENERIC_PTR_INIT (args, 1, "Arguments");
+ bitmap_clear (addrargs);
+ callop1 = TREE_OPERAND (op1, 1);
+ callop0 = TREE_OPERAND (op1, 0);
+ for (arg = callop1, argnum = 0;
+ arg;
+ arg = TREE_CHAIN (arg), argnum++)
+ {
+ alias_var aav = get_alias_var (TREE_VALUE (arg));
+ if (aav)
+ {
+ VARRAY_PUSH_GENERIC_PTR (args, aav);
+ if (TREE_CODE (TREE_VALUE (arg)) == ADDR_EXPR)
+ bitmap_set_bit (addrargs, argnum);
+ }
+ }
+ /* Simulate the call */
+ if (current_alias_ops->function_call (current_alias_ops, lhsAV,
+ get_alias_var (callop0),
+ args, addrargs))
+ {
+ if (call_may_clobber (op1)
+ && !current_alias_ops->ip
+ && flag_argument_noalias != 2)
+ {
+ intra_function_call (args);
+ }
+ if (POINTER_TYPE_P (TREE_TYPE (op0)))
+ deal_with_call_aliasing (callop1, lhsAV);
+ }
+ }
+ }
+ }
+ /* x = op (...) */
+ else
+ {
+ bitmap_clear (addrargs);
+ if (TREE_CODE (op1) == CONSTRUCTOR)
+ {
+ varray_type ops;
+ int i = 0;
+ VARRAY_GENERIC_PTR_INIT (ops, 1, "Operands");
+ get_values_from_constructor (op1, &ops, addrargs, &i);
+ current_alias_ops->op_assign (current_alias_ops, lhsAV,
+ ops, op1, addrargs);
+ }
+ else
+ switch (TREE_CODE_CLASS (TREE_CODE (op1)))
+ {
+ case 'e': /* an expression */
+ case 's': /* an expression with side effects */
+ case '<': /* a comparison expression */
+ case '1': /* a unary arithmetic expression */
+ case 'r': /* a reference */
+ case '2': /* a binary arithmetic expression */
+ {
+ tree op;
+ varray_type ops;
+ int i;
+ VARRAY_GENERIC_PTR_INIT (ops, 1, "Operands");
+ for (i = 0; i < TREE_CODE_LENGTH (TREE_CODE (op1)); i++)
+ {
+ alias_var aav;
+ op = TREE_OPERAND (op1, i);
+ aav = get_alias_var (op);
+ if (aav)
+ VARRAY_PUSH_GENERIC_PTR (ops, aav);
+ if (TREE_CODE (op) == ADDR_EXPR)
+ bitmap_set_bit (addrargs, i);
+ }
+ current_alias_ops->op_assign (current_alias_ops, lhsAV,
+ ops, op1, addrargs);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ /* *x = <something> */
+ else
+ {
+ /* x.f = y or x->f = y */
+ if ((TREE_CODE (op0) == COMPONENT_REF
+ || TREE_CODE (op0) == BIT_FIELD_REF)
+ && is_gimple_variable (op1))
+ {
+ if (rhsAV != NULL)
+ current_alias_ops->simple_assign (current_alias_ops, lhsAV,
+ rhsAV);
+ }
+ /* x.f = &y or x->f = &y */
+ else if (TREE_CODE (op0) == COMPONENT_REF
+ && TREE_CODE (op1) == ADDR_EXPR)
+ {
+ if (rhsAV != NULL)
+ current_alias_ops->addr_assign (current_alias_ops, lhsAV,
+ rhsAV);
+ }
+ /* *x.f = y or *x->f = y */
+ else if ((TREE_CODE (op0) == INDIRECT_REF
+ || TREE_CODE (op0) == ARRAY_REF)
+ && TREE_CODE (TREE_OPERAND (op0, 0)) == COMPONENT_REF
+ && is_gimple_variable (op1))
+ {
+ if (rhsAV != NULL)
+ current_alias_ops->assign_ptr (current_alias_ops, lhsAV,
+ rhsAV);
+ }
+ /* *x = &y */
+ else if ((TREE_CODE (op0) == INDIRECT_REF
+ || TREE_CODE (op0) == ARRAY_REF)
+ && TREE_CODE (op1) == ADDR_EXPR)
+ {
+ /* This becomes temp = &y and *x = temp . */
+ alias_var tempvar;
+ tree temp = create_tmp_var_raw (void_type_node, "aliastmp");
+ tempvar = current_alias_ops->add_var (current_alias_ops, temp);
+ current_alias_ops->addr_assign (current_alias_ops, tempvar,
+ rhsAV);
+ current_alias_ops->assign_ptr (current_alias_ops, lhsAV,
+ tempvar);
+ }
+
+ /* *x = *y */
+ else if ((TREE_CODE (op0) == INDIRECT_REF
+ || TREE_CODE (op0) == ARRAY_REF)
+ && (TREE_CODE (op1) == INDIRECT_REF
+ || TREE_CODE (op1) == ARRAY_REF))
+ {
+ /* This becomes temp = *y and *x = temp . */
+ alias_var tempvar;
+ tree temp;
+ temp = create_tmp_var_raw (void_type_node, "aliastmp");
+ tempvar = current_alias_ops->add_var (current_alias_ops, temp);
+ current_alias_ops->ptr_assign (current_alias_ops, tempvar,
+ rhsAV);
+ current_alias_ops->assign_ptr (current_alias_ops, lhsAV,
+ tempvar);
+ }
+
+ /* *x = (cast) y */
+ else if ((TREE_CODE (op0) == INDIRECT_REF
+ || TREE_CODE (op0) == ARRAY_REF)
+ && is_gimple_cast (op1))
+ {
+ if (rhsAV != NULL)
+ {
+ /* This becomes temp = (cast) y and *x = temp. */
+ alias_var tempvar;
+ tree temp;
+ temp = create_tmp_var_raw (void_type_node, "aliastmp");
+ tempvar = current_alias_ops->add_var (current_alias_ops,
+ temp);
+ current_alias_ops->simple_assign (current_alias_ops,
+ tempvar, rhsAV);
+ current_alias_ops->assign_ptr (current_alias_ops, lhsAV,
+ tempvar);
+ }
+ }
+ /* *x = <something else> */
+ else
+ {
+ if (rhsAV != NULL)
+ current_alias_ops->assign_ptr (current_alias_ops, lhsAV,
+ rhsAV);
+ }
+ }
+ }
+ /* Calls without return values. */
+ else if (TREE_CODE (stp) == CALL_EXPR)
+ {
+ alias_var callvar;
+ varray_type args;
+ tree arg;
+ callvar = get_alias_var (TREE_OPERAND (stp, 0));
+ if (callvar != NULL)
+ {
+
+ /* NORETURN and CONST functions with no return value
+ have no effect on aliasing (as may be seen above,
+ const functions that return a value might have an
+ effect on aliasing, since the return value can point
+ to one of the arguments. */
+ if (call_may_clobber (stp))
+ {
+ int argnum;
+ VARRAY_GENERIC_PTR_INIT (args, 1, "Arguments");
+ bitmap_clear (addrargs);
+ for (arg = TREE_OPERAND (stp, 1), argnum=0;
+ arg;
+ arg = TREE_CHAIN (arg), argnum++)
+ {
+ alias_var aav = get_alias_var (TREE_VALUE (arg));
+ if (aav)
+ {
+ VARRAY_PUSH_GENERIC_PTR (args, aav);
+ if (TREE_CODE (TREE_VALUE (arg)) == ADDR_EXPR)
+ bitmap_set_bit (addrargs, argnum);
+ }
+
+ }
+
+ if (current_alias_ops->function_call (current_alias_ops, NULL,
+ callvar, args, addrargs))
+ if (!current_alias_ops->ip && flag_argument_noalias != 2)
+ intra_function_call (args);
+ }
+ }
+ }
+}
+
+/* Create the alias_var for a function definition DECL, it's
+ arguments, and it's return value. If FORCE is true, we force
+ creation of the alias_var, regardless of whether one exists already.
+
+ This includes creation of alias_var's for
+ - The function itself.
+ - The arguments.
+ - The return value. */
+
+static alias_var
+create_fun_alias_var (tree decl, int force)
+{
+ alias_var avar, retvar;
+ tree rdecl;
+ varray_type params = NULL;
+
+ if (!force)
+ {
+ if (DECL_PTA_ALIASVAR (decl))
+ return DECL_PTA_ALIASVAR (decl);
+ }
+
+ VARRAY_GENERIC_PTR_INIT (params, 1, "Arguments");
+ if (DECL_ARGUMENTS (decl) != NULL)
+ {
+ tree arg;
+ for (arg = DECL_ARGUMENTS (decl); arg; arg = TREE_CHAIN (arg))
+ {
+ alias_var var = get_alias_var (arg);
+ VARRAY_PUSH_GENERIC_PTR (params, var);
+ /* Incoming pointers can point to pta_global_var, unless
+ either we are interprocedural, or we can do ip on all
+ statics + this function has been defined + it's not an
+ external function. */
+ if (POINTER_TYPE_P (TREE_TYPE (arg))
+ && !current_alias_ops->ip
+ /* FIXME: Need to let analyzer decide in partial case. */
+ && (!current_alias_ops->ip_partial
+ || !cgraph_local_info (decl)->local))
+ current_alias_ops->simple_assign (current_alias_ops, var,
+ get_alias_var (pta_global_var));
+ }
+ }
+ else if (TYPE_ARG_TYPES (TREE_TYPE (decl)) != NULL)
+ {
+ tree arg;
+ /* FIXME: Handle varargs */
+ for (arg = TYPE_ARG_TYPES (TREE_TYPE (decl));
+ arg && TREE_VALUE (arg) != void_type_node;
+ arg = TREE_CHAIN (arg))
+ {
+ tree fakedecl = create_tmp_var_raw (TREE_VALUE (arg), "normarg");
+ alias_var var;
+ DECL_CONTEXT (fakedecl) = current_function_decl;
+ var = get_alias_var (fakedecl);
+ VARRAY_PUSH_GENERIC_PTR (params, var);
+
+ /* Incoming pointers can point to pta_global_var, unless
+ either we are interprocedural, or we can do ip on all
+ statics + this function has been defined + it's not an
+ external function. */
+ if (POINTER_TYPE_P (TREE_TYPE (fakedecl))
+ && !current_alias_ops->ip
+ /* FIXME: need to let analyzer decide in partial case. */
+ && (!current_alias_ops->ip_partial
+ || !TREE_STATIC (decl)
+ || TREE_PUBLIC (decl)))
+ current_alias_ops->simple_assign (current_alias_ops, var,
+ get_alias_var (pta_global_var));
+ }
+ }
+ /* Functions declared like void f() are *not* equivalent to void
+ f(void). You can pass an argument to them. Thus, we need to
+ create some fake argument that would alias any actuals that get
+ passed to our function. */
+ else
+ {
+ tree fakedecl = create_tmp_var_raw (void_type_node, "fakearg");
+ alias_var fakevar;
+ DECL_CONTEXT (fakedecl) = current_function_decl;
+ fakevar = get_alias_var (fakedecl);
+ VARRAY_PUSH_GENERIC_PTR (params, fakevar);
+ }
+
+ if (!DECL_RESULT (decl))
+ {
+ rdecl = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (decl)), "_rv_");
+ retvar = current_alias_ops->add_var (current_alias_ops, rdecl);
+ DECL_PTA_ALIASVAR (rdecl) = retvar;
+ }
+ else
+ {
+ retvar = current_alias_ops->add_var (current_alias_ops,
+ DECL_RESULT (decl));
+ DECL_PTA_ALIASVAR (DECL_RESULT (decl)) = retvar;
+ }
+ VARRAY_PUSH_GENERIC_PTR (alias_vars, retvar);
+ ALIAS_VAR_VARNUM (retvar) = VARRAY_ACTIVE_SIZE (alias_vars) - 1;
+ avar = current_alias_ops->add_var (current_alias_ops, decl);
+ VARRAY_PUSH_GENERIC_PTR (alias_vars, avar);
+ ALIAS_VAR_VARNUM (avar) = VARRAY_ACTIVE_SIZE (alias_vars) - 1;
+
+ current_alias_ops->function_def (current_alias_ops, avar, params, retvar);
+ DECL_PTA_ALIASVAR (decl) = avar;
+
+ /* FIXME: Also, if this is a defining declaration then add the annotation
+ to all extern definitions of the function. */
+ return avar;
+}
+
+/* Create an alias variable for a pointer-to-member function DECL of
+ type TYPE, it's arguments, and it's return value.
+ Returns the alias_var for the PTF.
+
+ This includes creating alias_var's for
+ - The function itself.
+ - The arguments.
+ - The return value. */
+
+static alias_var
+create_fun_alias_var_ptf (tree decl, tree type)
+{
+ alias_var avar, retvar;
+ tree rdecl;
+ varray_type params = NULL;
+
+ if (DECL_PTA_ALIASVAR (decl))
+ return DECL_PTA_ALIASVAR (decl);
+
+ VARRAY_GENERIC_PTR_INIT (params, 1, "Arguments");
+
+ if (TYPE_ARG_TYPES (type) != NULL)
+ {
+ tree arg;
+ /* FIXME: Handle varargs */
+ for (arg = TYPE_ARG_TYPES (type);
+ arg && TREE_VALUE (arg) != void_type_node;
+ arg = TREE_CHAIN (arg))
+ {
+ tree fakedecl = create_tmp_var_raw (TREE_VALUE (arg), "ptfarg");
+ alias_var var;
+ DECL_CONTEXT (fakedecl) = DECL_CONTEXT (decl);
+ var = get_alias_var (fakedecl);
+ VARRAY_PUSH_GENERIC_PTR (params, var);
+ }
+ }
+ /* Functions declared like void f() are *not* equivalent to void
+ f(void). You can pass an argument to them. Thus, we need to
+ create some fake argument that would alias any actuals that get
+ passed to our function. */
+ else
+ {
+ tree fakedecl = create_tmp_var_raw (void_type_node, "fakearg");
+ alias_var fakevar;
+ DECL_CONTEXT (fakedecl) = DECL_CONTEXT (decl);
+ fakevar = get_alias_var (fakedecl);
+ VARRAY_PUSH_GENERIC_PTR (params, fakevar);
+ }
+
+ rdecl = create_tmp_var_raw (TREE_TYPE (type), "_rv_");
+ retvar = current_alias_ops->add_var (current_alias_ops, rdecl);
+ VARRAY_PUSH_GENERIC_PTR (alias_vars, retvar);
+ ALIAS_VAR_VARNUM (retvar) = VARRAY_ACTIVE_SIZE (alias_vars) - 1;
+
+ avar = current_alias_ops->add_var (current_alias_ops, decl);
+ VARRAY_PUSH_GENERIC_PTR (alias_vars, avar);
+ ALIAS_VAR_VARNUM (avar) = VARRAY_ACTIVE_SIZE (alias_vars) - 1;
+
+ current_alias_ops->function_def (current_alias_ops, avar, params, retvar);
+ DECL_PTA_ALIASVAR (decl) = avar;
+
+ return avar;
+}
+
+/* Create the alias_var for a *_DECL node DECL.
+ Returns the alias_var for DECL.
+
+ This function also handles creation of alias_var's for PTF
+ variables. */
+
+static alias_var
+create_alias_var (tree decl)
+{
+ alias_var avar;
+
+ if (!DECL_P (decl))
+ abort ();
+
+ if (DECL_P (decl))
+ {
+ if (DECL_PTA_ALIASVAR (decl))
+ return DECL_PTA_ALIASVAR (decl);
+ }
+
+ if (POINTER_TYPE_P (TREE_TYPE (decl))
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == FUNCTION_TYPE)
+ {
+ avar = create_fun_alias_var_ptf (decl, TREE_TYPE (TREE_TYPE (decl)));
+ }
+ else
+ avar = current_alias_ops->add_var (current_alias_ops, decl);
+
+ if (DECL_P (decl))
+ {
+ DECL_PTA_ALIASVAR (decl) = avar;
+ }
+
+ VARRAY_PUSH_GENERIC_PTR (alias_vars, avar);
+ ALIAS_VAR_VARNUM (avar) = VARRAY_ACTIVE_SIZE (alias_vars) - 1;
+ return avar;
+}
+
+/* Create points-to sets for the current function. */
+
+static void
+create_alias_vars (void)
+{
+ basic_block bb;
+#if HAVE_BANSHEE
+ if (flag_tree_points_to == PTA_ANDERSEN)
+ current_alias_ops = andersen_alias_ops;
+ else
+#endif
+ {
+ current_alias_ops = NULL;
+ flag_tree_points_to = PTA_NONE;
+ return;
+ }
+
+ pta_global_var = build_decl (VAR_DECL, get_identifier (".pta_global_var"),
+ size_type_node);
+ DECL_ARTIFICIAL (pta_global_var) = 1;
+ TREE_READONLY (pta_global_var) = 1;
+ DECL_EXTERNAL (pta_global_var) = 0;
+ TREE_STATIC (pta_global_var) = 1;
+ TREE_USED (pta_global_var) = 1;
+ DECL_CONTEXT (pta_global_var) = current_function_decl;
+ TREE_THIS_VOLATILE (pta_global_var) = 1;
+ TREE_ADDRESSABLE (pta_global_var) = 0;
+
+ init_alias_vars ();
+
+ DECL_PTA_ALIASVAR (current_function_decl) = NULL;
+ get_alias_var (current_function_decl);
+
+ /* First, walk the variables and their DECL_INITIAL's */
+ if (cfun->unexpanded_var_list)
+ {
+ tree vars, var;
+ for (vars = cfun->unexpanded_var_list; vars; vars = TREE_CHAIN (vars))
+ {
+ var = TREE_VALUE (vars);
+ if (TREE_CODE (var) != LABEL_DECL
+ && decl_function_context (var) == NULL
+ && DECL_INITIAL (var))
+ find_func_aliases (var);
+ }
+ }
+
+ /* Now walk all statements and derive aliases. */
+ FOR_EACH_BB (bb)
+ {
+ block_stmt_iterator bsi;
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ find_func_aliases (bsi_stmt (bsi));
+ }
+
+ pta_global_var = NULL_TREE;
+}
+
+struct tree_opt_pass pass_build_pta =
+{
+ "pta", /* name */
+ NULL, /* gate */
+ create_alias_vars, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_PTA, /* tv_id */
+ PROP_cfg, /* properties_required */
+ PROP_pta, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0 /* todo_flags_finish */
+};
+
+
+/* Delete created points-to sets. */
+
+static void
+delete_alias_vars (void)
+{
+ size_t i;
+
+ if (flag_tree_points_to != PTA_ANDERSEN)
+ return;
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (local_alias_vars); i++)
+ {
+ tree key = VARRAY_TREE (local_alias_vars, i);
+ if (DECL_P (key))
+ DECL_PTA_ALIASVAR (key) = NULL;
+ else
+ abort ();
+ }
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (local_alias_varnums); i ++)
+ VARRAY_GENERIC_PTR (alias_vars, VARRAY_INT (local_alias_varnums, i)) = NULL;
+ if (!current_alias_ops->ip && !current_alias_ops->ip_partial)
+ {
+ /* VARRAY_CLEAR (alias_vars); */
+ VARRAY_CLEAR (local_alias_vars);
+ VARRAY_CLEAR (local_alias_varnums);
+ }
+ BITMAP_XFREE (addrargs);
+ current_alias_ops->cleanup (current_alias_ops);
+}
+
+struct tree_opt_pass pass_del_pta =
+{
+ "pta", /* name */
+ NULL, /* gate */
+ delete_alias_vars, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_PTA, /* tv_id */
+ PROP_pta, /* properties_required */
+ 0, /* properties_provided */
+ PROP_pta, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0 /* todo_flags_finish */
+};
+
+
+/* Initialize points-to analysis machinery. */
+
+void
+init_alias_vars (void)
+{
+ current_alias_ops->init (current_alias_ops);
+ addrargs = BITMAP_XMALLOC ();
+ VARRAY_TREE_INIT (local_alias_vars, 10, "Local alias vars");
+ VARRAY_INT_INIT (local_alias_varnums, 10, "Local alias varnums");
+ if ((!current_alias_ops->ip && !current_alias_ops->ip_partial)
+ || alias_vars == NULL)
+ VARRAY_GENERIC_PTR_INIT (alias_vars, 10, "Alias vars");
+}
+
+/* Return true if PTR can't point to anything (i.e. it has an empty
+ points-to set. */
+bool
+empty_points_to_set (tree ptr)
+{
+ alias_var ptrtv;
+
+#if !FIELD_BASED
+#else
+ if (TREE_CODE (ptr) == COMPONENT_REF)
+ ptr = TREE_OPERAND (ptr, 1);
+#endif
+
+ if (DECL_P (ptr))
+ {
+ ptrtv = DECL_PTA_ALIASVAR (ptr);
+ if (!ptrtv)
+ return true;
+ }
+ else
+ abort ();
+
+ return current_alias_ops->empty_points_to_set (current_alias_ops, ptrtv);
+}
+
+/* Return true if PTR and VAR have the same points-to set. */
+
+bool
+same_points_to_set (tree ptr, tree var)
+{
+ alias_var ptrtv, vartv;
+
+#if !FIELD_BASED
+#else
+ if (TREE_CODE (ptr) == COMPONENT_REF)
+ ptr = TREE_OPERAND (ptr, 1);
+ if (TREE_CODE (var) == COMPONENT_REF)
+ var = TREE_OPERAND (var, 1);
+#endif
+
+ if (ptr == var)
+ return true;
+
+ if (DECL_P (ptr))
+ {
+ ptrtv = DECL_PTA_ALIASVAR (ptr);
+ if (!ptrtv)
+ return false;
+ }
+ else
+ abort ();
+
+ if (DECL_P (var))
+ {
+ vartv = DECL_PTA_ALIASVAR (var);
+ if (!vartv)
+ return false;
+ }
+ else
+ abort ();
+
+ return current_alias_ops->same_points_to_set (current_alias_ops, vartv, ptrtv);
+}
+
+/* Determine whether two variables (PTR and VAR) may-alias.
+ Returns TRUE if PTR may-alias VAR. */
+
+bool
+ptr_may_alias_var (tree ptr, tree var)
+{
+ alias_var ptrtv, vartv;
+
+#if !FIELD_BASED
+#else
+ if (TREE_CODE (ptr) == COMPONENT_REF)
+ ptr = TREE_OPERAND (ptr, 1);
+ if (TREE_CODE (var) == COMPONENT_REF)
+ var = TREE_OPERAND (var, 1);
+#endif
+
+ if (ptr == var)
+ return true;
+
+ if (DECL_P (ptr))
+ {
+ ptrtv = DECL_PTA_ALIASVAR (ptr);
+ if (!ptrtv)
+ return false;
+ }
+ else
+ abort ();
+
+ if (DECL_P (var))
+ {
+ vartv = DECL_PTA_ALIASVAR (var);
+ if (!vartv)
+ return false;
+ }
+ else
+ abort ();
+
+ return current_alias_ops->may_alias (current_alias_ops, ptrtv, vartv);
+}
+
+#define MASK_POINTER(P) ((unsigned)((unsigned long)(P) & 0xffff))
+
+const char *
+alias_get_name (tree t)
+{
+ const char *name;
+
+#if FIELD_BASED
+ if (TREE_CODE (t) == FIELD_DECL)
+ {
+ /* First get the name of the field, then the prefix, then smash them
+ together. */
+ const char *fieldname = IDENTIFIER_POINTER (DECL_NAME (t));
+ const char *prefix = alias_get_name (DECL_CONTEXT (t));
+ char *smashed;
+ size_t neededlen = strlen (fieldname) + strlen (prefix) + 2;
+ smashed = ggc_alloc (neededlen);
+ sprintf (smashed, "%s.%s", prefix, fieldname);
+ name = smashed;
+
+ }
+ else if (TYPE_P (t))
+ {
+ if (TYPE_NAME (t) && IDENTIFIER_POINTER (TYPE_NAME (t)))
+ name = IDENTIFIER_POINTER (TYPE_NAME (t));
+ else
+ name = "<unnamed type>";
+ }
+ else
+#endif
+ {
+ if (TREE_CODE (t) == FUNCTION_DECL)
+ name = IDENTIFIER_POINTER (DECL_NAME (t));
+ else if (TREE_CODE (t) == RESULT_DECL)
+ name = "<return value>";
+ else
+ name = get_name (t);
+ }
+
+ if (!name)
+ {
+ char *namep;
+ /* 2 = UF
+ 4 = the masked pointer
+ 2 = the <> around it
+ 1 = the terminator. */
+ namep = ggc_alloc (2 + 4 + 2 + 1);
+ sprintf (namep, "<UV%x>", MASK_POINTER (t));
+ return namep;
+ }
+
+ return name;
+}
+
+#include "gt-tree-alias-common.h"
diff --git a/gcc/tree-alias-common.h b/gcc/tree-alias-common.h
new file mode 100644
index 00000000000..45c9e4b8973
--- /dev/null
+++ b/gcc/tree-alias-common.h
@@ -0,0 +1,99 @@
+#ifndef TREE_ALIAS_COMMON
+#define TREE_ALIAS_COMMON
+#include "tree-alias-type.h"
+/* Alias analysis function pointers.
+ Functions implemented by the actual alias analysis algorithms in
+ order for them to work with the common points-to structure. */
+struct tree_alias_ops
+{
+ /* Initialization.
+ Called right before we start using the other functions. */
+ void (*init) (struct tree_alias_ops *);
+
+ /* Cleanup.
+ Called when we are finished with the alias analyzer. */
+ void (*cleanup) (struct tree_alias_ops *);
+
+ /* Add variable.
+ Called when we want to inform the alias analyzer about a new
+ variable we've found. */
+ alias_var (*add_var) (struct tree_alias_ops *, tree);
+
+ /* Add variable equivalent to existing one.
+ Called when we want to inform the alias analyzer about a new
+ variable that has the same points-to set as an existing
+ variable. */
+ alias_var (*add_var_same) (struct tree_alias_ops *, tree,
+ alias_var);
+
+ /* Process a simple assignment (a = b).
+ Called to process simple assignment statements of the form a = b,
+ where a and b are both variables. */
+ void (*simple_assign) (struct tree_alias_ops *, alias_var,
+ alias_var);
+ /* Process an address assignment (a = &b).
+ Called to process address assignment statements of the form a =
+ &b, where a and b are both variables. */
+ void (*addr_assign) (struct tree_alias_ops *, alias_var, alias_var);
+
+ /* Process a pointer assignment (a = *b).
+ Called to process pointer assignment statements of the form a =
+ *b, where a and b are both variables. */
+ void (*ptr_assign) (struct tree_alias_ops *, alias_var, alias_var);
+
+ /* Process an operator assignment (a = op (...))
+ Called to process operators of the form a = op(...), where a is a
+ variable. */
+ void (*op_assign) (struct tree_alias_ops *, alias_var, varray_type,
+ tree, bitmap);
+ /* Process a heap assignment (a = alloc (...))
+ Called to process a heap assignment of the form a = alloc
+ (...), where a is a variable, and *alloc is a function that
+ returns new memory. */
+ void (*heap_assign) (struct tree_alias_ops *, alias_var);
+
+ /* Process an assignment to a pointer (*a = b)
+ Called to process assignment to pointer statements of the form
+ *a = b, where a and b are both variables. */
+ void (*assign_ptr) (struct tree_alias_ops *, alias_var, alias_var);
+
+ /* Process a function definition.
+ Called to inform the alias analyzer about a new function
+ definition. */
+ void (*function_def) (struct tree_alias_ops *, alias_var,
+ varray_type, alias_var);
+
+ /* Process a function call.
+ Return 1 if we need to assume conservative side-effects. */
+ int (*function_call) (struct tree_alias_ops *, alias_var,
+ alias_var, varray_type, bitmap);
+
+ /* Determine if two alias variables may alias. */
+ bool (*may_alias) (struct tree_alias_ops *, alias_var, alias_var);
+
+ /* Determine if two alias variables have the same points-to set. */
+ bool (*same_points_to_set) (struct tree_alias_ops *, alias_var,
+ alias_var);
+
+ /* Determine if the alias variable has an empty points-to set. */
+ bool (*empty_points_to_set) (struct tree_alias_ops *, alias_var);
+
+ /* Private data. */
+ void *data;
+
+ /* Interprocedural. */
+ int ip:1;
+
+ /* Can do conservative interprocedural analysis if we save the
+ * info. */
+ int ip_partial:1;
+
+};
+
+extern struct tree_alias_ops *current_alias_ops;
+extern void init_alias_vars (void);
+extern bool ptr_may_alias_var (tree, tree);
+extern bool same_points_to_set (tree, tree);
+extern bool empty_points_to_set (tree);
+extern const char *alias_get_name (tree);
+#endif
diff --git a/gcc/tree-alias-type.c b/gcc/tree-alias-type.c
new file mode 100644
index 00000000000..20bcbf733fd
--- /dev/null
+++ b/gcc/tree-alias-type.c
@@ -0,0 +1,37 @@
+/* Tree based linear points-to analysis
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Daniel Berlin <dberlin@dberlin.org>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "ggc.h"
+#include "tree-alias-type.h"
+
+alias_var
+alias_var_new_with_aterm (tree decl, struct aterm_ *term)
+{
+ alias_var ret = ggc_alloc (sizeof (struct alias_var_aterm));
+ ALIAS_VAR_KIND (ret) = ATERM_AVAR;
+ ALIAS_VAR_DECL (ret) = decl;
+ ALIAS_VAR_ATERM (ret) = term;
+ return ret;
+}
diff --git a/gcc/tree-alias-type.h b/gcc/tree-alias-type.h
new file mode 100644
index 00000000000..7740e9933d7
--- /dev/null
+++ b/gcc/tree-alias-type.h
@@ -0,0 +1,41 @@
+#ifndef TREE_ALIAS_TYPE_H
+#define TREE_ALIAS_TYPE_H
+
+#include "varray.h"
+
+union alias_var_def;
+struct aterm_;
+struct aterm_list_a;
+enum alias_var_kind
+{
+ ATERM_AVAR
+};
+struct alias_var_common GTY (())
+{
+ enum alias_var_kind kind;
+ unsigned int varnum;
+ tree decl;
+};
+struct alias_var_aterm GTY (())
+{
+ struct alias_var_common common;
+ struct aterm_ * GTY((skip (""))) term;
+ struct aterm_list_a *GTY ((skip (""))) ptset;
+};
+union alias_var_def GTY ((desc ("%0.common.kind")))
+{
+ struct alias_var_common GTY ((tag ("-1"))) common;
+ struct alias_var_aterm GTY ((tag ("ATERM_AVAR"))) aterm;
+};
+typedef union alias_var_def *alias_var;
+
+#define ALIAS_VAR_KIND(x) ((x)->common.kind)
+#define ALIAS_VAR_VARNUM(x) ((x)->common.varnum)
+#define ALIAS_VAR_DECL(x) ((x)->common.decl)
+#define ALIAS_VAR_ATERM(x) ((x)->aterm.term)
+#define ALIAS_VAR_PTSET(x) ((x)->aterm.ptset)
+union alias_type_def;
+typedef union alias_type_def *alias_type;
+
+alias_var alias_var_new_with_aterm (tree, struct aterm_ *);
+#endif
diff --git a/gcc/tree-browser.c b/gcc/tree-browser.c
new file mode 100644
index 00000000000..891c761e25e
--- /dev/null
+++ b/gcc/tree-browser.c
@@ -0,0 +1,1045 @@
+/* Tree browser.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Sebastian Pop <s.pop@laposte.net>
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "errors.h"
+#include "tree.h"
+#include "tree-inline.h"
+#include "diagnostic.h"
+#include "hashtab.h"
+
+
+#define TB_OUT_FILE stdout
+#define TB_IN_FILE stdin
+#define TB_NIY fprintf (TB_OUT_FILE, "Sorry this command is not yet implemented.\n")
+#define TB_WF fprintf (TB_OUT_FILE, "Warning, this command failed.\n")
+
+
+/* Structures for handling Tree Browser's commands. */
+#define DEFTBCODE(COMMAND, STRING, HELP) COMMAND,
+enum TB_Comm_code {
+#include "tree-browser.def"
+ TB_UNUSED_COMMAND
+};
+#undef DEFTBCODE
+typedef enum TB_Comm_code TB_CODE;
+
+struct tb_command {
+ const char *help_msg;
+ const char *comm_text;
+ size_t comm_len;
+ TB_CODE comm_code;
+};
+
+#define DEFTBCODE(code, str, help) { help, str, sizeof(str) - 1, code },
+#ifdef HOST_EBCDIC
+static struct tb_command tb_commands[] =
+#else
+static const struct tb_command tb_commands[] =
+#endif
+{
+#include "tree-browser.def"
+};
+#undef DEFTBCODE
+
+#define TB_COMMAND_LEN(N) (tb_commands[N].comm_len)
+#define TB_COMMAND_TEXT(N) (tb_commands[N].comm_text)
+#define TB_COMMAND_CODE(N) (tb_commands[N].comm_code)
+#define TB_COMMAND_HELP(N) (tb_commands[N].help_msg)
+
+
+/* Next structure is for parsing TREE_CODEs. */
+struct tb_tree_code {
+ enum tree_code code;
+ const char *code_string;
+ size_t code_string_len;
+};
+
+#define DEFTREECODE(SYM, STRING, TYPE, NARGS) { SYM, STRING, sizeof (STRING) - 1 },
+#ifdef HOST_EBCDIC
+static struct tb_tree_code tb_tree_codes[] =
+#else
+static const struct tb_tree_code tb_tree_codes[] =
+#endif
+{
+#include "tree.def"
+};
+#undef DEFTREECODE
+
+#define TB_TREE_CODE(N) (tb_tree_codes[N].code)
+#define TB_TREE_CODE_TEXT(N) (tb_tree_codes[N].code_string)
+#define TB_TREE_CODE_LEN(N) (tb_tree_codes[N].code_string_len)
+
+
+/* Function declarations. */
+
+static long TB_getline (char **, long *, FILE *);
+static TB_CODE TB_get_command (char *);
+static enum tree_code TB_get_tree_code (char *);
+static tree find_node_with_code (tree *, int *, void *);
+static tree store_child_info (tree *, int *, void *);
+static void TB_update_up (tree);
+static tree TB_current_chain_node (tree);
+static tree TB_prev_expr (tree);
+static tree TB_next_expr (tree);
+static tree TB_up_expr (tree);
+static tree TB_first_in_bind (tree);
+static tree TB_last_in_bind (tree);
+static int TB_parent_eq (const void *, const void *);
+static tree TB_history_prev (void);
+
+/* FIXME: To be declared in a .h file. */
+void browse_tree (tree);
+
+/* Static variables. */
+static htab_t TB_up_ht;
+static tree TB_history_stack = NULL_TREE;
+static int TB_verbose = 1;
+
+
+/* Entry point in the Tree Browser. */
+
+void
+browse_tree (tree begin)
+{
+ tree head;
+ TB_CODE tbc = TB_UNUSED_COMMAND;
+ ssize_t rd;
+ char *input = NULL;
+ long input_size = 0;
+
+ fprintf (TB_OUT_FILE, "\nTree Browser\n");
+
+#define TB_SET_HEAD(N) do { \
+ TB_history_stack = tree_cons (NULL_TREE, (N), TB_history_stack); \
+ head = N; \
+ if (TB_verbose) \
+ if (head) \
+ { \
+ print_generic_expr (TB_OUT_FILE, head, 0); \
+ fprintf (TB_OUT_FILE, "\n"); \
+ } \
+} while (0)
+
+ TB_SET_HEAD (begin);
+
+ /* Store in a hashtable information about previous and upper statements. */
+ {
+ TB_up_ht = htab_create (1023, htab_hash_pointer, &TB_parent_eq, NULL);
+ TB_update_up (head);
+ }
+
+ while (24)
+ {
+ fprintf (TB_OUT_FILE, "TB> ");
+ rd = TB_getline (&input, &input_size, TB_IN_FILE);
+
+ if (rd == -1)
+ /* EOF. */
+ goto ret;
+
+ if (rd != 1)
+ /* Get a new command. Otherwise the user just pressed enter, and thus
+ she expects the last command to be reexecuted. */
+ tbc = TB_get_command (input);
+
+ switch (tbc)
+ {
+ case TB_UPDATE_UP:
+ TB_update_up (head);
+ break;
+
+ case TB_MAX:
+ if (head && (INTEGRAL_TYPE_P (head)
+ || TREE_CODE (head) == REAL_TYPE))
+ TB_SET_HEAD (TYPE_MAX_VALUE (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_MIN:
+ if (head && (INTEGRAL_TYPE_P (head)
+ || TREE_CODE (head) == REAL_TYPE))
+ TB_SET_HEAD (TYPE_MIN_VALUE (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_ELT:
+ if (head && TREE_CODE (head) == TREE_VEC)
+ {
+ /* This command takes another argument: the element number:
+ for example "elt 1". */
+ TB_NIY;
+ }
+ else if (head && TREE_CODE (head) == VECTOR_CST)
+ {
+ /* This command takes another argument: the element number:
+ for example "elt 1". */
+ TB_NIY;
+ }
+ else
+ TB_WF;
+ break;
+
+ case TB_VALUE:
+ if (head && TREE_CODE (head) == TREE_LIST)
+ TB_SET_HEAD (TREE_VALUE (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_PURPOSE:
+ if (head && TREE_CODE (head) == TREE_LIST)
+ TB_SET_HEAD (TREE_PURPOSE (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_IMAG:
+ if (head && TREE_CODE (head) == COMPLEX_CST)
+ TB_SET_HEAD (TREE_IMAGPART (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_REAL:
+ if (head && TREE_CODE (head) == COMPLEX_CST)
+ TB_SET_HEAD (TREE_REALPART (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_BLOCK:
+ if (head && TREE_CODE (head) == BIND_EXPR)
+ TB_SET_HEAD (TREE_OPERAND (head, 2));
+ else
+ TB_WF;
+ break;
+
+ case TB_SUBBLOCKS:
+ if (head && TREE_CODE (head) == BLOCK)
+ TB_SET_HEAD (BLOCK_SUBBLOCKS (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_SUPERCONTEXT:
+ if (head && TREE_CODE (head) == BLOCK)
+ TB_SET_HEAD (BLOCK_SUPERCONTEXT (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_VARS:
+ if (head && TREE_CODE (head) == BLOCK)
+ TB_SET_HEAD (BLOCK_VARS (head));
+ else if (head && TREE_CODE (head) == BIND_EXPR)
+ TB_SET_HEAD (TREE_OPERAND (head, 0));
+ else
+ TB_WF;
+ break;
+
+ case TB_REFERENCE_TO_THIS:
+ if (head && TREE_CODE_CLASS (TREE_CODE (head)) == 't')
+ TB_SET_HEAD (TYPE_REFERENCE_TO (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_POINTER_TO_THIS:
+ if (head && TREE_CODE_CLASS (TREE_CODE (head)) == 't')
+ TB_SET_HEAD (TYPE_POINTER_TO (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_BASETYPE:
+ if (head && TREE_CODE (head) == OFFSET_TYPE)
+ TB_SET_HEAD (TYPE_OFFSET_BASETYPE (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_ARG_TYPES:
+ if (head && (TREE_CODE (head) == FUNCTION_TYPE
+ || TREE_CODE (head) == METHOD_TYPE))
+ TB_SET_HEAD (TYPE_ARG_TYPES (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_METHOD_BASE_TYPE:
+ if (head && (TREE_CODE (head) == FUNCTION_TYPE
+ || TREE_CODE (head) == METHOD_TYPE)
+ && TYPE_METHOD_BASETYPE (head))
+ TB_SET_HEAD (TYPE_METHOD_BASETYPE (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_FIELDS:
+ if (head && (TREE_CODE (head) == RECORD_TYPE
+ || TREE_CODE (head) == UNION_TYPE
+ || TREE_CODE (head) == QUAL_UNION_TYPE))
+ TB_SET_HEAD (TYPE_FIELDS (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_DOMAIN:
+ if (head && (TREE_CODE (head) == ARRAY_TYPE
+ || TREE_CODE (head) == SET_TYPE))
+ TB_SET_HEAD (TYPE_DOMAIN (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_VALUES:
+ if (head && TREE_CODE (head) == ENUMERAL_TYPE)
+ TB_SET_HEAD (TYPE_VALUES (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_ARG_TYPE_AS_WRITTEN:
+ if (head && TREE_CODE (head) == PARM_DECL)
+ TB_SET_HEAD (DECL_ARG_TYPE_AS_WRITTEN (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_ARG_TYPE:
+ if (head && TREE_CODE (head) == PARM_DECL)
+ TB_SET_HEAD (DECL_ARG_TYPE (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_INITIAL:
+ if (head && TREE_CODE_CLASS (TREE_CODE (head)) == 'd')
+ TB_SET_HEAD (DECL_INITIAL (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_RESULT:
+ if (head && TREE_CODE_CLASS (TREE_CODE (head)) == 'd')
+ TB_SET_HEAD (DECL_RESULT_FLD (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_ARGUMENTS:
+ if (head && TREE_CODE_CLASS (TREE_CODE (head)) == 'd')
+ TB_SET_HEAD (DECL_ARGUMENTS (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_ABSTRACT_ORIGIN:
+ if (head && TREE_CODE_CLASS (TREE_CODE (head)) == 'd')
+ TB_SET_HEAD (DECL_ABSTRACT_ORIGIN (head));
+ else if (head && TREE_CODE (head) == BLOCK)
+ TB_SET_HEAD (BLOCK_ABSTRACT_ORIGIN (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_ATTRIBUTES:
+ if (head && TREE_CODE_CLASS (TREE_CODE (head)) == 'd')
+ TB_SET_HEAD (DECL_ATTRIBUTES (head));
+ else if (head && TREE_CODE_CLASS (TREE_CODE (head)) == 't')
+ TB_SET_HEAD (TYPE_ATTRIBUTES (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_CONTEXT:
+ if (head && TREE_CODE_CLASS (TREE_CODE (head)) == 'd')
+ TB_SET_HEAD (DECL_CONTEXT (head));
+ else if (head && TREE_CODE_CLASS (TREE_CODE (head)) == 't'
+ && TYPE_CONTEXT (head))
+ TB_SET_HEAD (TYPE_CONTEXT (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_OFFSET:
+ if (head && TREE_CODE (head) == FIELD_DECL)
+ TB_SET_HEAD (DECL_FIELD_OFFSET (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_BIT_OFFSET:
+ if (head && TREE_CODE (head) == FIELD_DECL)
+ TB_SET_HEAD (DECL_FIELD_BIT_OFFSET (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_UNIT_SIZE:
+ if (head && TREE_CODE_CLASS (TREE_CODE (head)) == 'd')
+ TB_SET_HEAD (DECL_SIZE_UNIT (head));
+ else if (head && TREE_CODE_CLASS (TREE_CODE (head)) == 't')
+ TB_SET_HEAD (TYPE_SIZE_UNIT (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_SIZE:
+ if (head && TREE_CODE_CLASS (TREE_CODE (head)) == 'd')
+ TB_SET_HEAD (DECL_SIZE (head));
+ else if (head && TREE_CODE_CLASS (TREE_CODE (head)) == 't')
+ TB_SET_HEAD (TYPE_SIZE (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_TYPE:
+ if (head && TREE_TYPE (head))
+ TB_SET_HEAD (TREE_TYPE (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_DECL_SAVED_TREE:
+ if (head && TREE_CODE (head) == FUNCTION_DECL
+ && DECL_SAVED_TREE (head))
+ TB_SET_HEAD (DECL_SAVED_TREE (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_BODY:
+ if (head && TREE_CODE (head) == BIND_EXPR)
+ TB_SET_HEAD (TREE_OPERAND (head, 1));
+ else
+ TB_WF;
+ break;
+
+ case TB_CHILD_0:
+ if (head && IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (head)))
+ && TREE_OPERAND (head, 0))
+ TB_SET_HEAD (TREE_OPERAND (head, 0));
+ else
+ TB_WF;
+ break;
+
+ case TB_CHILD_1:
+ if (head && IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (head)))
+ && TREE_OPERAND (head, 1))
+ TB_SET_HEAD (TREE_OPERAND (head, 1));
+ else
+ TB_WF;
+ break;
+
+ case TB_CHILD_2:
+ if (head && IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (head)))
+ && TREE_OPERAND (head, 2))
+ TB_SET_HEAD (TREE_OPERAND (head, 2));
+ else
+ TB_WF;
+ break;
+
+ case TB_CHILD_3:
+ if (head && IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (head)))
+ && TREE_OPERAND (head, 3))
+ TB_SET_HEAD (TREE_OPERAND (head, 3));
+ else
+ TB_WF;
+ break;
+
+ case TB_PRINT:
+ if (head)
+ debug_tree (head);
+ else
+ TB_WF;
+ break;
+
+ case TB_PRETTY_PRINT:
+ if (head)
+ {
+ print_generic_stmt (TB_OUT_FILE, head, 0);
+ fprintf (TB_OUT_FILE, "\n");
+ }
+ else
+ TB_WF;
+ break;
+
+ case TB_SEARCH_NAME:
+
+ break;
+
+ case TB_SEARCH_CODE:
+ {
+ enum tree_code code;
+ char *arg_text;
+
+ arg_text = strchr (input, ' ');
+ if (arg_text == NULL)
+ {
+ fprintf (TB_OUT_FILE, "First argument is missing. This isn't a valid search command. \n");
+ break;
+ }
+ code = TB_get_tree_code (arg_text + 1);
+
+ /* Search in the subtree a node with the given code. */
+ {
+ tree res;
+
+ res = walk_tree (&head, find_node_with_code, &code, NULL);
+ if (res == NULL_TREE)
+ {
+ fprintf (TB_OUT_FILE, "There's no node with this code (reachable via the walk_tree function from this node).\n");
+ }
+ else
+ {
+ fprintf (TB_OUT_FILE, "Achoo! I got this node in the tree.\n");
+ TB_SET_HEAD (res);
+ }
+ }
+ break;
+ }
+
+#define TB_MOVE_HEAD(FCT) do { \
+ if (head) \
+ { \
+ tree t; \
+ t = FCT (head); \
+ if (t) \
+ TB_SET_HEAD (t); \
+ else \
+ TB_WF; \
+ } \
+ else \
+ TB_WF; \
+} while (0)
+
+ case TB_FIRST:
+ TB_MOVE_HEAD (TB_first_in_bind);
+ break;
+
+ case TB_LAST:
+ TB_MOVE_HEAD (TB_last_in_bind);
+ break;
+
+ case TB_UP:
+ TB_MOVE_HEAD (TB_up_expr);
+ break;
+
+ case TB_PREV:
+ TB_MOVE_HEAD (TB_prev_expr);
+ break;
+
+ case TB_NEXT:
+ TB_MOVE_HEAD (TB_next_expr);
+ break;
+
+ case TB_HPREV:
+ /* This command is a little bit special, since it deals with history
+ stack. For this reason it should keep the "head = ..." statement
+ and not use TB_MOVE_HEAD. */
+ if (head)
+ {
+ tree t;
+ t = TB_history_prev ();
+ if (t)
+ {
+ head = t;
+ if (TB_verbose)
+ {
+ print_generic_expr (TB_OUT_FILE, head, 0);
+ fprintf (TB_OUT_FILE, "\n");
+ }
+ }
+ else
+ TB_WF;
+ }
+ else
+ TB_WF;
+ break;
+
+ case TB_CHAIN:
+ /* Don't go further if it's the last node in this chain. */
+ if (head && TREE_CODE (head) == BLOCK)
+ TB_SET_HEAD (BLOCK_CHAIN (head));
+ else if (head && TREE_CHAIN (head))
+ TB_SET_HEAD (TREE_CHAIN (head));
+ else
+ TB_WF;
+ break;
+
+ case TB_FUN:
+ /* Go up to the current function declaration. */
+ TB_SET_HEAD (current_function_decl);
+ fprintf (TB_OUT_FILE, "Current function declaration.\n");
+ break;
+
+ case TB_HELP:
+ /* Display a help message. */
+ {
+ int i;
+ fprintf (TB_OUT_FILE, "Possible commands are:\n\n");
+ for (i = 0; i < TB_UNUSED_COMMAND; i++)
+ {
+ fprintf (TB_OUT_FILE, "%20s - %s\n", TB_COMMAND_TEXT (i), TB_COMMAND_HELP (i));
+ }
+ }
+ break;
+
+ case TB_VERBOSE:
+ if (TB_verbose == 0)
+ {
+ TB_verbose = 1;
+ fprintf (TB_OUT_FILE, "Verbose on.\n");
+ }
+ else
+ {
+ TB_verbose = 0;
+ fprintf (TB_OUT_FILE, "Verbose off.\n");
+ }
+ break;
+
+ case TB_EXIT:
+ case TB_QUIT:
+ /* Just exit from this function. */
+ goto ret;
+
+ default:
+ TB_NIY;
+ }
+ }
+
+ ret:;
+ htab_delete (TB_up_ht);
+ return;
+}
+
+
+/* Search the first node in this BIND_EXPR. */
+
+static tree
+TB_first_in_bind (tree node)
+{
+ tree t;
+
+ if (node == NULL_TREE)
+ return NULL_TREE;
+
+ while ((t = TB_prev_expr (node)))
+ node = t;
+
+ return node;
+}
+
+/* Search the last node in this BIND_EXPR. */
+
+static tree
+TB_last_in_bind (tree node)
+{
+ tree t;
+
+ if (node == NULL_TREE)
+ return NULL_TREE;
+
+ while ((t = TB_next_expr (node)))
+ node = t;
+
+ return node;
+}
+
+/* Search the parent expression for this node. */
+
+static tree
+TB_up_expr (tree node)
+{
+ tree res;
+ if (node == NULL_TREE)
+ return NULL_TREE;
+
+ res = (tree) htab_find (TB_up_ht, node);
+ return res;
+}
+
+/* Search the previous expression in this BIND_EXPR. */
+
+static tree
+TB_prev_expr (tree node)
+{
+ node = TB_current_chain_node (node);
+
+ if (node == NULL_TREE)
+ return NULL_TREE;
+
+ node = TB_up_expr (node);
+ if (node && TREE_CODE (node) == COMPOUND_EXPR)
+ return node;
+ else
+ return NULL_TREE;
+}
+
+/* Search the next expression in this BIND_EXPR. */
+
+static tree
+TB_next_expr (tree node)
+{
+ node = TB_current_chain_node (node);
+
+ if (node == NULL_TREE)
+ return NULL_TREE;
+
+ node = TREE_OPERAND (node, 1);
+ return node;
+}
+
+static tree
+TB_current_chain_node (tree node)
+{
+ if (node == NULL_TREE)
+ return NULL_TREE;
+
+ if (TREE_CODE (node) == COMPOUND_EXPR)
+ return node;
+
+ node = TB_up_expr (node);
+ if (node)
+ {
+ if (TREE_CODE (node) == COMPOUND_EXPR)
+ return node;
+
+ node = TB_up_expr (node);
+ if (TREE_CODE (node) == COMPOUND_EXPR)
+ return node;
+ }
+
+ return NULL_TREE;
+}
+
+/* For each node store in its children nodes that the current node is their
+ parent. This function is used by walk_tree. */
+
+static tree
+store_child_info (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
+{
+ tree node;
+ void **slot;
+
+ node = *tp;
+
+ /* 'node' is the parent of 'TREE_OPERAND (node, *)'. */
+ if (TREE_CODE_CLASS (TREE_CODE (node)) == 'e')
+ {
+
+#define STORE_CHILD(N) do { \
+ tree op = TREE_OPERAND (node, N); \
+ slot = htab_find_slot (TB_up_ht, op, INSERT); \
+ *slot = (void *) node; \
+} while (0)
+
+ switch (TREE_CODE_LENGTH (TREE_CODE (node)))
+ {
+ case 4:
+ STORE_CHILD (0);
+ STORE_CHILD (1);
+ STORE_CHILD (2);
+ STORE_CHILD (3);
+ break;
+
+ case 3:
+ STORE_CHILD (0);
+ STORE_CHILD (1);
+ STORE_CHILD (2);
+ break;
+
+ case 2:
+ STORE_CHILD (0);
+ STORE_CHILD (1);
+ break;
+
+ case 1:
+ STORE_CHILD (0);
+ break;
+
+ case 0:
+ default:
+ /* No children: nothing to do. */
+ break;
+ }
+#undef STORE_CHILD
+ }
+
+ /* Never stop walk_tree. */
+ return NULL_TREE;
+}
+
+/* Function used in TB_up_ht. */
+
+static int
+TB_parent_eq (const void *p1, const void *p2)
+{
+ tree node, parent;
+ node = (tree) p2;
+ parent = (tree) p1;
+
+ if (p1 == NULL || p2 == NULL)
+ return 0;
+
+ if (TREE_CODE_CLASS(TREE_CODE(parent)) == 'e')
+ {
+
+#define TEST_CHILD(N) do { \
+ if (node == TREE_OPERAND (parent, N)) \
+ return 1; \
+} while (0)
+
+ switch (TREE_CODE_LENGTH (TREE_CODE (parent)))
+ {
+ case 4:
+ TEST_CHILD (0);
+ TEST_CHILD (1);
+ TEST_CHILD (2);
+ TEST_CHILD (3);
+ break;
+
+ case 3:
+ TEST_CHILD (0);
+ TEST_CHILD (1);
+ TEST_CHILD (2);
+ break;
+
+ case 2:
+ TEST_CHILD (0);
+ TEST_CHILD (1);
+ break;
+
+ case 1:
+ TEST_CHILD (0);
+ break;
+
+ case 0:
+ default:
+ /* No children: nothing to do. */
+ break;
+ }
+#undef TEST_CHILD
+ }
+
+ return 0;
+}
+
+/* Update information about upper expressions in the hash table. */
+
+static void
+TB_update_up (tree node)
+{
+ while (node)
+ {
+ walk_tree (&node, store_child_info, NULL, NULL);
+
+ /* Walk function's body. */
+ if (TREE_CODE (node) == FUNCTION_DECL)
+ if (DECL_SAVED_TREE (node))
+ walk_tree (&DECL_SAVED_TREE (node), store_child_info, NULL, NULL);
+
+ /* Walk rest of the chain. */
+ node = TREE_CHAIN (node);
+ }
+ fprintf (TB_OUT_FILE, "Up/prev expressions updated.\n");
+}
+
+/* Parse the input string for determining the command the user asked for. */
+
+static TB_CODE
+TB_get_command (char *input)
+{
+ unsigned int mn, size_tok;
+ int comp;
+ char *space;
+
+ space = strchr (input, ' ');
+ if (space != NULL)
+ size_tok = strlen (input) - strlen (space);
+ else
+ size_tok = strlen (input) - 1;
+
+ for (mn = 0; mn < TB_UNUSED_COMMAND; mn++)
+ {
+ if (size_tok != TB_COMMAND_LEN (mn))
+ continue;
+
+ comp = memcmp (input, TB_COMMAND_TEXT (mn), TB_COMMAND_LEN (mn));
+ if (comp == 0)
+ /* Here we just determined the command. If this command takes
+ an argument, then the argument is determined later. */
+ return TB_COMMAND_CODE (mn);
+ }
+
+ /* Not a valid command. */
+ return TB_UNUSED_COMMAND;
+}
+
+/* Parse the input string for determining the tree code. */
+
+static enum tree_code
+TB_get_tree_code (char *input)
+{
+ unsigned int mn, size_tok;
+ int comp;
+ char *space;
+
+ space = strchr (input, ' ');
+ if (space != NULL)
+ size_tok = strlen (input) - strlen (space);
+ else
+ size_tok = strlen (input) - 1;
+
+ for (mn = 0; mn < LAST_AND_UNUSED_TREE_CODE; mn++)
+ {
+ if (size_tok != TB_TREE_CODE_LEN (mn))
+ continue;
+
+ comp = memcmp (input, TB_TREE_CODE_TEXT (mn), TB_TREE_CODE_LEN (mn));
+ if (comp == 0)
+ {
+ fprintf (TB_OUT_FILE, "%s\n", TB_TREE_CODE_TEXT (mn));
+ return TB_TREE_CODE (mn);
+ }
+ }
+
+ /* This isn't a valid code. */
+ return LAST_AND_UNUSED_TREE_CODE;
+}
+
+/* Find a node with a given code. This function is used as an argument to
+ walk_tree. */
+
+static tree
+find_node_with_code (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
+ void *data)
+{
+ enum tree_code *code;
+ code = (enum tree_code *) data;
+ if (*code == TREE_CODE (*tp))
+ return *tp;
+
+ return NULL_TREE;
+}
+
+/* Returns a pointer to the last visited node. */
+
+static tree
+TB_history_prev (void)
+{
+ if (TB_history_stack)
+ {
+ TB_history_stack = TREE_CHAIN (TB_history_stack);
+ if (TB_history_stack)
+ return TREE_VALUE (TB_history_stack);
+ }
+ return NULL_TREE;
+}
+
+/* Read up to (and including) a '\n' from STREAM into *LINEPTR
+ (and null-terminate it). *LINEPTR is a pointer returned from malloc
+ (or NULL), pointing to *N characters of space. It is realloc'd as
+ necessary. Returns the number of characters read (not including the
+ null terminator), or -1 on error or EOF.
+ This function comes from sed (and is supposed to be a portable version
+ of getline). */
+
+static long
+TB_getline (char **lineptr, long *n, FILE *stream)
+{
+ char *line, *p;
+ long size, copy;
+
+ if (lineptr == NULL || n == NULL)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (ferror (stream))
+ return -1;
+
+ /* Make sure we have a line buffer to start with. */
+ if (*lineptr == NULL || *n < 2) /* !seen and no buf yet need 2 chars. */
+ {
+#ifndef MAX_CANON
+#define MAX_CANON 256
+#endif
+ line = (char *) xrealloc (*lineptr, MAX_CANON);
+ if (line == NULL)
+ return -1;
+ *lineptr = line;
+ *n = MAX_CANON;
+ }
+
+ line = *lineptr;
+ size = *n;
+
+ copy = size;
+ p = line;
+
+ while (1)
+ {
+ long len;
+
+ while (--copy > 0)
+ {
+ register int c = getc (stream);
+ if (c == EOF)
+ goto lose;
+ else if ((*p++ = c) == '\n')
+ goto win;
+ }
+
+ /* Need to enlarge the line buffer. */
+ len = p - line;
+ size *= 2;
+ line = (char *) xrealloc (line, size);
+ if (line == NULL)
+ goto lose;
+ *lineptr = line;
+ *n = size;
+ p = line + len;
+ copy = size - len;
+ }
+
+ lose:
+ if (p == *lineptr)
+ return -1;
+
+ /* Return a partial line since we got an error in the middle. */
+ win:
+#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(MSDOS)
+ if (p - 2 >= *lineptr && p[-2] == '\r')
+ p[-2] = p[-1], --p;
+#endif
+ *p = '\0';
+ return p - *lineptr;
+}
diff --git a/gcc/tree-browser.def b/gcc/tree-browser.def
new file mode 100644
index 00000000000..57fb1df8044
--- /dev/null
+++ b/gcc/tree-browser.def
@@ -0,0 +1,98 @@
+/* Definitions and documentation for the codes used by the Tree Browser.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Contributed by Sebastian Pop <s.pop@laposte.net>
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* First field in the following declarations is the code of the command
+ used by the tree browser.
+ Second field is what is parsed in order to recognize a command.
+ Third field is used for printing the help message. */
+
+
+/* Misc. commands. */
+DEFTBCODE (TB_EXIT, "x", "Exits tree-browser.")
+DEFTBCODE (TB_QUIT, "q", "Exits tree-browser.")
+DEFTBCODE (TB_HELP, "h", "Prints this help message.")
+DEFTBCODE (TB_UPDATE_UP, "update", "Update information about parent expressions.")
+DEFTBCODE (TB_VERBOSE, "verbose", "Sets/unsets verbose mode (default is on).")
+
+/* Walking commands. */
+DEFTBCODE (TB_FUN, "fun", "Go to the curent function declaration.")
+DEFTBCODE (TB_NEXT, "nx", "Go to the next expression in a BIND_EXPR.")
+DEFTBCODE (TB_PREV, "pr", "Go to the previous expression in a BIND_EXPR.")
+DEFTBCODE (TB_UP, "up", "Go to the parent tree node.")
+DEFTBCODE (TB_LAST, "last", "Go to the last expression in a BIND_EXPR.")
+DEFTBCODE (TB_FIRST, "first","Go to the first expression in a BIND_EXPR.")
+DEFTBCODE (TB_HPREV, "hpr", "Go to the previous visited node (history previous).")
+
+/* Fields accessors. */
+DEFTBCODE (TB_CHILD_0, "arg0", "Child 0.")
+DEFTBCODE (TB_CHILD_1, "arg1", "Child 1.")
+DEFTBCODE (TB_CHILD_2, "arg2", "Child 2.")
+DEFTBCODE (TB_CHILD_3, "arg3", "Child 3.")
+DEFTBCODE (TB_DECL_SAVED_TREE, "decl_saved_tree", "Body of a function.")
+DEFTBCODE (TB_TYPE, "type", "Field accessor.")
+DEFTBCODE (TB_SIZE, "size", "Field accessor.")
+DEFTBCODE (TB_UNIT_SIZE, "unit_size", "Field accessor.")
+DEFTBCODE (TB_OFFSET, "offset", "Field accessor.")
+DEFTBCODE (TB_BIT_OFFSET, "bit_offset", "Field accessor.")
+DEFTBCODE (TB_CONTEXT, "context", "Field accessor.")
+DEFTBCODE (TB_ATTRIBUTES, "attributes", "Field accessor.")
+DEFTBCODE (TB_ABSTRACT_ORIGIN, "abstract_origin", "Field accessor.")
+DEFTBCODE (TB_ARGUMENTS, "arguments", "Field accessor.")
+DEFTBCODE (TB_RESULT, "result", "Field accessor.")
+DEFTBCODE (TB_INITIAL, "initial", "Field accessor.")
+DEFTBCODE (TB_ARG_TYPE, "arg-type", "Field accessor.")
+DEFTBCODE (TB_ARG_TYPE_AS_WRITTEN, "arg-type-as-written", "Field accessor.")
+DEFTBCODE (TB_CHAIN, "chain", "Field accessor.")
+DEFTBCODE (TB_VALUES, "values", "Field accessor.")
+DEFTBCODE (TB_DOMAIN, "domain", "Field accessor.")
+DEFTBCODE (TB_METHOD_BASE_TYPE, "method_basetype", "Field accessor.")
+DEFTBCODE (TB_FIELDS, "fields", "Field accessor.")
+DEFTBCODE (TB_ARG_TYPES, "arg-types", "Field accessor.")
+DEFTBCODE (TB_BASETYPE, "basetype", "Field accessor.")
+DEFTBCODE (TB_POINTER_TO_THIS, "pointer_to_this", "Field accessor.")
+DEFTBCODE (TB_REFERENCE_TO_THIS,"reference_to_this", "Field accessor.")
+DEFTBCODE (TB_VARS, "vars", "Field accessor.")
+DEFTBCODE (TB_SUPERCONTEXT, "supercontext", "Field accessor.")
+DEFTBCODE (TB_BODY, "body", "Field accessor.")
+DEFTBCODE (TB_SUBBLOCKS, "subblocks", "Field accessor.")
+DEFTBCODE (TB_BLOCK, "block", "Field accessor.")
+DEFTBCODE (TB_REAL, "real", "Field accessor.")
+DEFTBCODE (TB_IMAG, "imag", "Field accessor.")
+DEFTBCODE (TB_PURPOSE, "purpose", "Field accessor.")
+DEFTBCODE (TB_VALUE, "value", "Field accessor.")
+DEFTBCODE (TB_ELT, "elt", "Field accessor.")
+DEFTBCODE (TB_MIN, "min", "Field accessor.")
+DEFTBCODE (TB_MAX, "max", "Field accessor.")
+
+/* Searching commands. */
+DEFTBCODE (TB_SEARCH_CODE, "sc", "Search a node having a TREE_CODE given as a parameter.")
+DEFTBCODE (TB_SEARCH_NAME, "sn", "Search an identifier having a name given as a parameter.")
+
+/* Printing commands. */
+DEFTBCODE (TB_PRETTY_PRINT, "pp", "Pretty print current node.")
+DEFTBCODE (TB_PRINT, "p", "Prints the current node.")
+
+
+/*
+Local variables:
+mode:c
+End:
+*/
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
new file mode 100644
index 00000000000..26954e4bd01
--- /dev/null
+++ b/gcc/tree-cfg.c
@@ -0,0 +1,4594 @@
+/* Control flow functions for trees.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Diego Novillo <dnovillo@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "output.h"
+#include "errors.h"
+#include "flags.h"
+#include "function.h"
+#include "expr.h"
+#include "ggc.h"
+#include "langhooks.h"
+#include "diagnostic.h"
+#include "tree-flow.h"
+#include "timevar.h"
+#include "tree-dump.h"
+#include "tree-pass.h"
+#include "toplev.h"
+#include "except.h"
+#include "cfgloop.h"
+
+/* This file contains functions for building the Control Flow Graph (CFG)
+ for a function tree. */
+
+/* Local declarations. */
+
+/* Initial capacity for the basic block array. */
+static const int initial_cfg_capacity = 20;
+
+/* Mapping of labels to their associated blocks. This can greatly speed up
+ building of the CFG in code with lots of gotos. */
+static GTY(()) varray_type label_to_block_map;
+
+/* CFG statistics. */
+struct cfg_stats_d
+{
+ long num_merged_labels;
+};
+
+static struct cfg_stats_d cfg_stats;
+
+/* Nonzero if we found a computed goto while building basic blocks. */
+static bool found_computed_goto;
+
+/* Basic blocks and flowgraphs. */
+static basic_block create_bb (void *, void *, basic_block);
+static void create_block_annotation (basic_block);
+static void free_blocks_annotations (void);
+static void clear_blocks_annotations (void);
+static void make_blocks (tree);
+static void factor_computed_gotos (void);
+static tree tree_block_label (basic_block bb);
+
+/* Edges. */
+static void make_edges (void);
+static void make_ctrl_stmt_edges (basic_block);
+static void make_exit_edges (basic_block);
+static void make_cond_expr_edges (basic_block);
+static void make_switch_expr_edges (basic_block);
+static void make_goto_expr_edges (basic_block);
+static edge tree_redirect_edge_and_branch (edge, basic_block);
+static edge tree_try_redirect_by_replacing_jump (edge, basic_block);
+static void split_critical_edges (void);
+
+/* Various helpers. */
+static inline bool stmt_starts_bb_p (tree, tree);
+static int tree_verify_flow_info (void);
+static void tree_make_forwarder_block (edge);
+static bool thread_jumps (void);
+static bool tree_forwarder_block_p (basic_block);
+static void bsi_commit_edge_inserts_1 (edge e);
+static void tree_cfg2vcg (FILE *);
+
+/* Flowgraph optimization and cleanup. */
+static void tree_merge_blocks (basic_block, basic_block);
+static bool tree_can_merge_blocks_p (basic_block, basic_block);
+static void remove_bb (basic_block);
+static void cleanup_dead_labels (void);
+static bool cleanup_control_flow (void);
+static bool cleanup_control_expr_graph (basic_block, block_stmt_iterator);
+static edge find_taken_edge_cond_expr (basic_block, tree);
+static edge find_taken_edge_switch_expr (basic_block, tree);
+static tree find_case_label_for_value (tree, tree);
+static bool phi_alternatives_equal (basic_block, edge, edge);
+
+
+/*---------------------------------------------------------------------------
+ Create basic blocks
+---------------------------------------------------------------------------*/
+
+/* Entry point to the CFG builder for trees. TP points to the list of
+ statements to be added to the flowgraph. */
+
+static void
+build_tree_cfg (tree *tp)
+{
+ /* Register specific tree functions. */
+ tree_register_cfg_hooks ();
+
+ /* Initialize rbi_pool. */
+ alloc_rbi_pool ();
+
+ /* Initialize the basic block array. */
+ init_flow ();
+ n_basic_blocks = 0;
+ last_basic_block = 0;
+ VARRAY_BB_INIT (basic_block_info, initial_cfg_capacity, "basic_block_info");
+ memset ((void *) &cfg_stats, 0, sizeof (cfg_stats));
+
+ /* Build a mapping of labels to their associated blocks. */
+ VARRAY_BB_INIT (label_to_block_map, initial_cfg_capacity,
+ "label to block map");
+
+ ENTRY_BLOCK_PTR->next_bb = EXIT_BLOCK_PTR;
+ EXIT_BLOCK_PTR->prev_bb = ENTRY_BLOCK_PTR;
+
+ found_computed_goto = 0;
+ make_blocks (*tp);
+
+ /* Computed gotos are hell to deal with, especially if there are
+ lots of them with a large number of destinations. So we factor
+ them to a common computed goto location before we build the
+ edge list. After we convert back to normal form, we will un-factor
+ the computed gotos since factoring introduces an unwanted jump. */
+ if (found_computed_goto)
+ factor_computed_gotos ();
+
+ /* Make sure there is always at least one block, even if its empty. */
+ if (n_basic_blocks == 0)
+ create_empty_bb (ENTRY_BLOCK_PTR);
+
+ create_block_annotation (ENTRY_BLOCK_PTR);
+ create_block_annotation (EXIT_BLOCK_PTR);
+
+ /* Adjust the size of the array. */
+ VARRAY_GROW (basic_block_info, n_basic_blocks);
+
+ /* Create the edges of the flowgraph. */
+ make_edges ();
+
+ /* Debugging dumps. */
+
+ /* Write the flowgraph to a VCG file. */
+ {
+ int local_dump_flags;
+ FILE *dump_file = dump_begin (TDI_vcg, &local_dump_flags);
+ if (dump_file)
+ {
+ tree_cfg2vcg (dump_file);
+ dump_end (TDI_vcg, dump_file);
+ }
+ }
+
+ /* Dump a textual representation of the flowgraph. */
+ if (dump_file)
+ dump_tree_cfg (dump_file, dump_flags);
+}
+
+static void
+execute_build_cfg (void)
+{
+ build_tree_cfg (&DECL_SAVED_TREE (current_function_decl));
+}
+
+struct tree_opt_pass pass_build_cfg =
+{
+ "cfg", /* name */
+ NULL, /* gate */
+ execute_build_cfg, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_CFG, /* tv_id */
+ PROP_gimple_leh, /* properties_required */
+ PROP_cfg, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_stmts /* todo_flags_finish */
+};
+
+/* Search the CFG for any computed gotos. If found, factor them to a
+ common computed goto site. Also record the location of that site so
+ that we can un-factor the gotos after we have converted back to
+ normal form. */
+
+static void
+factor_computed_gotos (void)
+{
+ basic_block bb;
+ tree factored_label_decl = NULL;
+ tree var = NULL;
+ tree factored_computed_goto_label = NULL;
+ tree factored_computed_goto = NULL;
+
+ /* We know there are one or more computed gotos in this function.
+ Examine the last statement in each basic block to see if the block
+ ends with a computed goto. */
+
+ FOR_EACH_BB (bb)
+ {
+ block_stmt_iterator bsi = bsi_last (bb);
+ tree last;
+
+ if (bsi_end_p (bsi))
+ continue;
+ last = bsi_stmt (bsi);
+
+ /* Ignore the computed goto we create when we factor the original
+ computed gotos. */
+ if (last == factored_computed_goto)
+ continue;
+
+ /* If the last statement is a computed goto, factor it. */
+ if (computed_goto_p (last))
+ {
+ tree assignment;
+
+ /* The first time we find a computed goto we need to create
+ the factored goto block and the variable each original
+ computed goto will use for their goto destination. */
+ if (! factored_computed_goto)
+ {
+ basic_block new_bb = create_empty_bb (bb);
+ block_stmt_iterator new_bsi = bsi_start (new_bb);
+
+ /* Create the destination of the factored goto. Each original
+ computed goto will put its desired destination into this
+ variable and jump to the label we create immediately
+ below. */
+ var = create_tmp_var (ptr_type_node, "gotovar");
+
+ /* Build a label for the new block which will contain the
+ factored computed goto. */
+ factored_label_decl = create_artificial_label ();
+ factored_computed_goto_label
+ = build1 (LABEL_EXPR, void_type_node, factored_label_decl);
+ bsi_insert_after (&new_bsi, factored_computed_goto_label,
+ BSI_NEW_STMT);
+
+ /* Build our new computed goto. */
+ factored_computed_goto = build1 (GOTO_EXPR, void_type_node, var);
+ bsi_insert_after (&new_bsi, factored_computed_goto,
+ BSI_NEW_STMT);
+ }
+
+ /* Copy the original computed goto's destination into VAR. */
+ assignment = build (MODIFY_EXPR, ptr_type_node,
+ var, GOTO_DESTINATION (last));
+ bsi_insert_before (&bsi, assignment, BSI_SAME_STMT);
+
+ /* And re-vector the computed goto to the new destination. */
+ GOTO_DESTINATION (last) = factored_label_decl;
+ }
+ }
+}
+
+
+/* Create annotations for a single basic block. */
+
+static void
+create_block_annotation (basic_block bb)
+{
+ /* Verify that the tree_annotations field is clear. */
+ if (bb->tree_annotations)
+ abort ();
+ bb->tree_annotations = ggc_alloc_cleared (sizeof (struct bb_ann_d));
+}
+
+
+/* Free the annotations for all the basic blocks. */
+
+static void free_blocks_annotations (void)
+{
+ clear_blocks_annotations ();
+}
+
+
+/* Clear the annotations for all the basic blocks. */
+
+static void
+clear_blocks_annotations (void)
+{
+ basic_block bb;
+
+ FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
+ bb->tree_annotations = NULL;
+}
+
+
+/* Build a flowgraph for the statement_list STMT_LIST. */
+
+static void
+make_blocks (tree stmt_list)
+{
+ tree_stmt_iterator i = tsi_start (stmt_list);
+ tree stmt = NULL;
+ bool start_new_block = true;
+ bool first_stmt_of_list = true;
+ basic_block bb = ENTRY_BLOCK_PTR;
+
+ while (!tsi_end_p (i))
+ {
+ tree prev_stmt;
+
+ prev_stmt = stmt;
+ stmt = tsi_stmt (i);
+
+ /* If the statement starts a new basic block or if we have determined
+ in a previous pass that we need to create a new block for STMT, do
+ so now. */
+ if (start_new_block || stmt_starts_bb_p (stmt, prev_stmt))
+ {
+ if (!first_stmt_of_list)
+ stmt_list = tsi_split_statement_list_before (&i);
+ bb = create_basic_block (stmt_list, NULL, bb);
+ start_new_block = false;
+ }
+
+ /* Now add STMT to BB and create the subgraphs for special statement
+ codes. */
+ set_bb_for_stmt (stmt, bb);
+
+ if (computed_goto_p (stmt))
+ found_computed_goto = true;
+
+ /* If STMT is a basic block terminator, set START_NEW_BLOCK for the
+ next iteration. */
+ if (stmt_ends_bb_p (stmt))
+ start_new_block = true;
+
+ tsi_next (&i);
+ first_stmt_of_list = false;
+ }
+}
+
+
+/* Create and return a new empty basic block after bb AFTER. */
+
+static basic_block
+create_bb (void *h, void *e, basic_block after)
+{
+ basic_block bb;
+
+ if (e)
+ abort ();
+
+ /* Create and initialize a new basic block. */
+ bb = alloc_block ();
+ memset (bb, 0, sizeof (*bb));
+
+ bb->index = last_basic_block;
+ bb->flags = BB_NEW;
+ bb->stmt_list = h ? h : alloc_stmt_list ();
+
+ /* Add the new block to the linked list of blocks. */
+ link_block (bb, after);
+
+ /* Grow the basic block array if needed. */
+ if ((size_t) last_basic_block == VARRAY_SIZE (basic_block_info))
+ {
+ size_t new_size = last_basic_block + (last_basic_block + 3) / 4;
+ VARRAY_GROW (basic_block_info, new_size);
+ }
+
+ /* Add the newly created block to the array. */
+ BASIC_BLOCK (last_basic_block) = bb;
+
+ create_block_annotation (bb);
+
+ n_basic_blocks++;
+ last_basic_block++;
+
+ initialize_bb_rbi (bb);
+ return bb;
+}
+
+
+/*---------------------------------------------------------------------------
+ Edge creation
+---------------------------------------------------------------------------*/
+
+/* Join all the blocks in the flowgraph. */
+
+static void
+make_edges (void)
+{
+ basic_block bb;
+ edge e;
+
+ /* Create an edge from entry to the first block with executable
+ statements in it. */
+ make_edge (ENTRY_BLOCK_PTR, BASIC_BLOCK (0), EDGE_FALLTHRU);
+
+ /* Traverse basic block array placing edges. */
+ FOR_EACH_BB (bb)
+ {
+ tree first = first_stmt (bb);
+ tree last = last_stmt (bb);
+
+ if (first)
+ {
+ /* Edges for statements that always alter flow control. */
+ if (is_ctrl_stmt (last))
+ make_ctrl_stmt_edges (bb);
+
+ /* Edges for statements that sometimes alter flow control. */
+ if (is_ctrl_altering_stmt (last))
+ make_exit_edges (bb);
+ }
+
+ /* Finally, if no edges were created above, this is a regular
+ basic block that only needs a fallthru edge. */
+ if (bb->succ == NULL)
+ make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
+ }
+
+ /* If there is a fallthru edge to exit out of the last block, transform it
+ to a return statement. */
+ for (e = EXIT_BLOCK_PTR->prev_bb->succ; e; e = e->succ_next)
+ if (e->flags & EDGE_FALLTHRU)
+ break;
+
+ if (e && e->dest == EXIT_BLOCK_PTR)
+ {
+ block_stmt_iterator bsi;
+ basic_block ret_bb = EXIT_BLOCK_PTR->prev_bb;
+ tree x;
+
+ /* If E->SRC ends with a call that has an abnormal edge (for EH or
+ nonlocal goto), then we will need to split the edge to insert
+ an explicit return statement. */
+ if (e != ret_bb->succ || e->succ_next)
+ {
+ ret_bb = split_edge (e);
+ e = ret_bb->succ;
+ }
+ e->flags &= ~EDGE_FALLTHRU;
+
+ x = build (RETURN_EXPR, void_type_node, NULL_TREE);
+ bsi = bsi_last (ret_bb);
+ bsi_insert_after (&bsi, x, BSI_NEW_STMT);
+ }
+
+ /* We do not care about fake edges, so remove any that the CFG
+ builder inserted for completeness. */
+ remove_fake_edges ();
+
+ /* To speed up statement iterator walks, we first purge dead labels. */
+ cleanup_dead_labels ();
+
+ /* Clean up the graph and warn for unreachable code. */
+ cleanup_tree_cfg ();
+}
+
+
+/* Create edges for control statement at basic block BB. */
+
+static void
+make_ctrl_stmt_edges (basic_block bb)
+{
+ tree last = last_stmt (bb);
+ tree first = first_stmt (bb);
+
+#if defined ENABLE_CHECKING
+ if (last == NULL_TREE)
+ abort();
+#endif
+
+ if (TREE_CODE (first) == LABEL_EXPR
+ && DECL_NONLOCAL (LABEL_EXPR_LABEL (first)))
+ make_edge (ENTRY_BLOCK_PTR, bb, EDGE_ABNORMAL);
+
+ switch (TREE_CODE (last))
+ {
+ case GOTO_EXPR:
+ make_goto_expr_edges (bb);
+ break;
+
+ case RETURN_EXPR:
+ make_edge (bb, EXIT_BLOCK_PTR, 0);
+ break;
+
+ case COND_EXPR:
+ make_cond_expr_edges (bb);
+ break;
+
+ case SWITCH_EXPR:
+ make_switch_expr_edges (bb);
+ break;
+
+ case RESX_EXPR:
+ make_eh_edges (last);
+ /* Yet another NORETURN hack. */
+ if (bb->succ == NULL)
+ make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
+ break;
+
+ default:
+ abort ();
+ }
+}
+
+
+/* Create exit edges for statements in block BB that alter the flow of
+ control. Statements that alter the control flow are 'goto', 'return'
+ and calls to non-returning functions. */
+
+static void
+make_exit_edges (basic_block bb)
+{
+ tree last = last_stmt (bb);
+
+ if (last == NULL_TREE)
+ abort ();
+
+ switch (TREE_CODE (last))
+ {
+ case CALL_EXPR:
+ /* If this function receives a nonlocal goto, then we need to
+ make edges from this call site to all the nonlocal goto
+ handlers. */
+ if (TREE_SIDE_EFFECTS (last)
+ && current_function_has_nonlocal_label)
+ make_goto_expr_edges (bb);
+
+ /* If this statement has reachable exception handlers, then
+ create abnormal edges to them. */
+ make_eh_edges (last);
+
+ /* Some calls are known not to return. For such calls we create
+ a fake edge.
+
+ We really need to revamp how we build edges so that it's not
+ such a bloody pain to avoid creating edges for this case since
+ all we do is remove these edges when we're done building the
+ CFG. */
+ if (call_expr_flags (last) & (ECF_NORETURN | ECF_LONGJMP))
+ {
+ make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
+ return;
+ }
+
+ /* Don't forget the fall-thru edge. */
+ make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
+ break;
+
+ case MODIFY_EXPR:
+ /* A MODIFY_EXPR may have a CALL_EXPR on its RHS and the CALL_EXPR
+ may have an abnormal edge. Search the RHS for this case and
+ create any required edges. */
+ if (TREE_CODE (TREE_OPERAND (last, 1)) == CALL_EXPR
+ && TREE_SIDE_EFFECTS (TREE_OPERAND (last, 1))
+ && current_function_has_nonlocal_label)
+ make_goto_expr_edges (bb);
+
+ make_eh_edges (last);
+ make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
+ break;
+
+ default:
+ abort ();
+ }
+}
+
+
+/* Create the edges for a COND_EXPR starting at block BB.
+ At this point, both clauses must contain only simple gotos. */
+
+static void
+make_cond_expr_edges (basic_block bb)
+{
+ tree entry = last_stmt (bb);
+ basic_block then_bb, else_bb;
+ tree then_label, else_label;
+
+#if defined ENABLE_CHECKING
+ if (entry == NULL_TREE || TREE_CODE (entry) != COND_EXPR)
+ abort ();
+#endif
+
+ /* Entry basic blocks for each component. */
+ then_label = GOTO_DESTINATION (COND_EXPR_THEN (entry));
+ else_label = GOTO_DESTINATION (COND_EXPR_ELSE (entry));
+ then_bb = label_to_block (then_label);
+ else_bb = label_to_block (else_label);
+
+ make_edge (bb, then_bb, EDGE_TRUE_VALUE);
+ make_edge (bb, else_bb, EDGE_FALSE_VALUE);
+}
+
+
+/* Create the edges for a SWITCH_EXPR starting at block BB.
+ At this point, the switch body has been lowered and the
+ SWITCH_LABELS filled in, so this is in effect a multi-way branch. */
+
+static void
+make_switch_expr_edges (basic_block bb)
+{
+ tree entry = last_stmt (bb);
+ size_t i, n;
+ tree vec;
+
+ vec = SWITCH_LABELS (entry);
+ n = TREE_VEC_LENGTH (vec);
+
+ for (i = 0; i < n; ++i)
+ {
+ tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
+ basic_block label_bb = label_to_block (lab);
+ make_edge (bb, label_bb, 0);
+ }
+}
+
+
+/* Return the basic block holding label DEST. */
+
+basic_block
+label_to_block (tree dest)
+{
+ return VARRAY_BB (label_to_block_map, LABEL_DECL_UID (dest));
+}
+
+
+/* Create edges for a goto statement at block BB. */
+
+static void
+make_goto_expr_edges (basic_block bb)
+{
+ tree goto_t, dest;
+ basic_block target_bb;
+ int for_call;
+ block_stmt_iterator last = bsi_last (bb);
+
+ goto_t = bsi_stmt (last);
+
+ /* If the last statement is not a GOTO (i.e., it is a RETURN_EXPR,
+ CALL_EXPR or MODIFY_EXPR), then the edge is an abnormal edge resulting
+ from a nonlocal goto. */
+ if (TREE_CODE (goto_t) != GOTO_EXPR)
+ {
+ dest = error_mark_node;
+ for_call = 1;
+ }
+ else
+ {
+ dest = GOTO_DESTINATION (goto_t);
+ for_call = 0;
+
+ /* A GOTO to a local label creates normal edges. */
+ if (simple_goto_p (goto_t))
+ {
+ make_edge (bb, label_to_block (dest), EDGE_FALLTHRU);
+ bsi_remove (&last);
+ return;
+ }
+
+ /* Nothing more to do for nonlocal gotos. */
+ if (TREE_CODE (dest) == LABEL_DECL)
+ return;
+
+ /* Computed gotos remain. */
+ }
+
+ /* Look for the block starting with the destination label. In the
+ case of a computed goto, make an edge to any label block we find
+ in the CFG. */
+ FOR_EACH_BB (target_bb)
+ {
+ block_stmt_iterator bsi;
+
+ for (bsi = bsi_start (target_bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ tree target = bsi_stmt (bsi);
+
+ if (TREE_CODE (target) != LABEL_EXPR)
+ break;
+
+ if (
+ /* Computed GOTOs. Make an edge to every label block that has
+ been marked as a potential target for a computed goto. */
+ (FORCED_LABEL (LABEL_EXPR_LABEL (target)) && for_call == 0)
+ /* Nonlocal GOTO target. Make an edge to every label block
+ that has been marked as a potential target for a nonlocal
+ goto. */
+ || (DECL_NONLOCAL (LABEL_EXPR_LABEL (target)) && for_call == 1))
+ {
+ make_edge (bb, target_bb, EDGE_ABNORMAL);
+ break;
+ }
+ }
+ }
+
+ /* Degenerate case of computed goto with no labels. */
+ if (!for_call && !bb->succ)
+ make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
+}
+
+
+/*---------------------------------------------------------------------------
+ Flowgraph analysis
+---------------------------------------------------------------------------*/
+
+/* Remove unreachable blocks and other miscellaneous clean up work. */
+
+void
+cleanup_tree_cfg (void)
+{
+ bool something_changed = true;
+
+ timevar_push (TV_TREE_CLEANUP_CFG);
+
+ /* These three transformations can cascade, so we iterate on them until
+ nothing changes. */
+ while (something_changed)
+ {
+ something_changed = cleanup_control_flow ();
+ something_changed |= thread_jumps ();
+ something_changed |= delete_unreachable_blocks ();
+ }
+
+ /* Merging the blocks creates no new opportunities for the other
+ optimizations, so do it here. */
+ merge_seq_blocks ();
+
+ compact_blocks ();
+
+#ifdef ENABLE_CHECKING
+ verify_flow_info ();
+#endif
+ timevar_pop (TV_TREE_CLEANUP_CFG);
+}
+
+
+/* Cleanup useless labels from the flow graph. */
+
+static void
+cleanup_dead_labels (void)
+{
+ basic_block bb;
+ tree *label_for_bb = xcalloc (last_basic_block, sizeof (tree));
+
+ /* Find a suitable label for each block. We use the first user-defined
+ label is there is one, or otherwise just the first label we see. */
+ FOR_EACH_BB (bb)
+ {
+ block_stmt_iterator i;
+
+ for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
+ {
+ tree label, stmt = bsi_stmt (i);
+
+ if (TREE_CODE (stmt) != LABEL_EXPR)
+ break;
+
+ label = LABEL_EXPR_LABEL (stmt);
+
+ /* If we have not yet seen a label for the current block,
+ remember this one and see if there are more labels. */
+ if (! label_for_bb[bb->index])
+ {
+ label_for_bb[bb->index] = label;
+ continue;
+ }
+
+ /* If we did see a label for the current block already, but it
+ is an artificially created label, replace it if the current
+ label is a user defined label. */
+ if (! DECL_ARTIFICIAL (label)
+ && DECL_ARTIFICIAL (label_for_bb[bb->index]))
+ {
+ label_for_bb[bb->index] = label;
+ break;
+ }
+ }
+ }
+
+ /* Now redirect all jumps/branches to the selected label for each block. */
+ FOR_EACH_BB (bb)
+ {
+ tree stmt = last_stmt (bb);
+ if (!stmt)
+ continue;
+
+ switch (TREE_CODE (stmt))
+ {
+ case COND_EXPR:
+ {
+ tree true_branch, false_branch;
+ basic_block true_bb, false_bb;
+
+ true_branch = COND_EXPR_THEN (stmt);
+ false_branch = COND_EXPR_ELSE (stmt);
+ true_bb = label_to_block (GOTO_DESTINATION (true_branch));
+ false_bb = label_to_block (GOTO_DESTINATION (false_branch));
+
+ GOTO_DESTINATION (true_branch) = label_for_bb[true_bb->index];
+ GOTO_DESTINATION (false_branch) = label_for_bb[false_bb->index];
+
+ break;
+ }
+
+ case SWITCH_EXPR:
+ {
+ size_t i;
+ tree vec = SWITCH_LABELS (stmt);
+ size_t n = TREE_VEC_LENGTH (vec);
+
+ /* Replace all destination labels. */
+ for (i = 0; i < n; ++i)
+ {
+ tree label = CASE_LABEL (TREE_VEC_ELT (vec, i));
+
+ CASE_LABEL (TREE_VEC_ELT (vec, i)) =
+ label_for_bb[label_to_block (label)->index];
+ }
+
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ /* Finally, purge dead labels. All user-defined labels and labels that
+ can be the target of non-local gotos are preserved. */
+ FOR_EACH_BB (bb)
+ {
+ block_stmt_iterator i;
+ tree label_for_this_bb = label_for_bb[bb->index];
+
+ if (! label_for_this_bb)
+ continue;
+
+ for (i = bsi_start (bb); !bsi_end_p (i); )
+ {
+ tree label, stmt = bsi_stmt (i);
+
+ if (TREE_CODE (stmt) != LABEL_EXPR)
+ break;
+
+ label = LABEL_EXPR_LABEL (stmt);
+
+ if (label == label_for_this_bb
+ || ! DECL_ARTIFICIAL (label)
+ || DECL_NONLOCAL (label))
+ bsi_next (&i);
+ else
+ bsi_remove (&i);
+ }
+ }
+
+ free (label_for_bb);
+}
+
+
+/* Checks whether we can merge block B into block A. */
+
+static bool
+tree_can_merge_blocks_p (basic_block a, basic_block b)
+{
+ tree stmt;
+ block_stmt_iterator bsi;
+
+ if (!a->succ
+ || a->succ->succ_next)
+ return false;
+
+ if (a->succ->flags & EDGE_ABNORMAL)
+ return false;
+
+ if (a->succ->dest != b)
+ return false;
+
+ if (b == EXIT_BLOCK_PTR)
+ return false;
+
+ if (b->pred->pred_next)
+ return false;
+
+ /* If A ends by a statement causing exceptions or something similar, we
+ cannot merge the blocks. */
+ stmt = last_stmt (a);
+ if (stmt && stmt_ends_bb_p (stmt))
+ return false;
+
+ /* Do not allow a block with only a non-local label to be merged. */
+ if (stmt && TREE_CODE (stmt) == LABEL_EXPR
+ && DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt)))
+ return false;
+
+ /* There may be no phi nodes at the start of b. Most of these degenerate
+ phi nodes should be cleaned up by kill_redundant_phi_nodes. */
+ if (phi_nodes (b))
+ return false;
+
+ /* Do not remove user labels. */
+ for (bsi = bsi_start (b); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ stmt = bsi_stmt (bsi);
+ if (TREE_CODE (stmt) != LABEL_EXPR)
+ break;
+ if (!DECL_ARTIFICIAL (LABEL_EXPR_LABEL (stmt)))
+ return false;
+ }
+
+ return true;
+}
+
+
+/* Merge block B into block A. */
+
+static void
+tree_merge_blocks (basic_block a, basic_block b)
+{
+ block_stmt_iterator bsi;
+ tree_stmt_iterator last;
+
+ if (dump_file)
+ fprintf (dump_file, "Merging blocks %d and %d\n", a->index, b->index);
+
+ /* Ensure that B follows A. */
+ move_block_after (b, a);
+
+ if (!(a->succ->flags & EDGE_FALLTHRU))
+ abort ();
+
+ if (last_stmt (a)
+ && stmt_ends_bb_p (last_stmt (a)))
+ abort ();
+
+ /* Remove labels from B and set bb_for_stmt to A for other statements. */
+ for (bsi = bsi_start (b); !bsi_end_p (bsi);)
+ {
+ if (TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR)
+ bsi_remove (&bsi);
+ else
+ {
+ set_bb_for_stmt (bsi_stmt (bsi), a);
+ bsi_next (&bsi);
+ }
+ }
+
+ /* Merge the chains. */
+ last = tsi_last (a->stmt_list);
+ tsi_link_after (&last, b->stmt_list, TSI_NEW_STMT);
+ b->stmt_list = NULL;
+}
+
+
+/* Walk the function tree removing unnecessary statements.
+
+ * Empty statement nodes are removed
+
+ * Unnecessary TRY_FINALLY and TRY_CATCH blocks are removed
+
+ * Unnecessary COND_EXPRs are removed
+
+ * Some unnecessary BIND_EXPRs are removed
+
+ Clearly more work could be done. The trick is doing the analysis
+ and removal fast enough to be a net improvement in compile times.
+
+ Note that when we remove a control structure such as a COND_EXPR
+ BIND_EXPR, or TRY block, we will need to repeat this optimization pass
+ to ensure we eliminate all the useless code. */
+
+struct rus_data
+{
+ tree *last_goto;
+ bool repeat;
+ bool may_throw;
+ bool may_branch;
+ bool has_label;
+};
+
+static void remove_useless_stmts_1 (tree *, struct rus_data *);
+
+static bool
+remove_useless_stmts_warn_notreached (tree stmt)
+{
+ if (EXPR_LOCUS (stmt))
+ {
+ warning ("%Hwill never be executed", EXPR_LOCUS (stmt));
+ return true;
+ }
+
+ switch (TREE_CODE (stmt))
+ {
+ case STATEMENT_LIST:
+ {
+ tree_stmt_iterator i;
+ for (i = tsi_start (stmt); !tsi_end_p (i); tsi_next (&i))
+ if (remove_useless_stmts_warn_notreached (tsi_stmt (i)))
+ return true;
+ }
+ break;
+
+ case COND_EXPR:
+ if (remove_useless_stmts_warn_notreached (COND_EXPR_COND (stmt)))
+ return true;
+ if (remove_useless_stmts_warn_notreached (COND_EXPR_THEN (stmt)))
+ return true;
+ if (remove_useless_stmts_warn_notreached (COND_EXPR_ELSE (stmt)))
+ return true;
+ break;
+
+ case TRY_FINALLY_EXPR:
+ case TRY_CATCH_EXPR:
+ if (remove_useless_stmts_warn_notreached (TREE_OPERAND (stmt, 0)))
+ return true;
+ if (remove_useless_stmts_warn_notreached (TREE_OPERAND (stmt, 1)))
+ return true;
+ break;
+
+ case CATCH_EXPR:
+ return remove_useless_stmts_warn_notreached (CATCH_BODY (stmt));
+ case EH_FILTER_EXPR:
+ return remove_useless_stmts_warn_notreached (EH_FILTER_FAILURE (stmt));
+ case BIND_EXPR:
+ return remove_useless_stmts_warn_notreached (BIND_EXPR_BLOCK (stmt));
+
+ default:
+ /* Not a live container. */
+ break;
+ }
+
+ return false;
+}
+
+static void
+remove_useless_stmts_cond (tree *stmt_p, struct rus_data *data)
+{
+ tree then_clause, else_clause, cond;
+ bool save_has_label, then_has_label, else_has_label;
+
+ save_has_label = data->has_label;
+ data->has_label = false;
+ data->last_goto = NULL;
+
+ remove_useless_stmts_1 (&COND_EXPR_THEN (*stmt_p), data);
+
+ then_has_label = data->has_label;
+ data->has_label = false;
+ data->last_goto = NULL;
+
+ remove_useless_stmts_1 (&COND_EXPR_ELSE (*stmt_p), data);
+
+ else_has_label = data->has_label;
+ data->has_label = save_has_label | then_has_label | else_has_label;
+
+ fold_stmt (stmt_p);
+ then_clause = COND_EXPR_THEN (*stmt_p);
+ else_clause = COND_EXPR_ELSE (*stmt_p);
+ cond = COND_EXPR_COND (*stmt_p);
+
+ /* If neither arm does anything at all, we can remove the whole IF. */
+ if (!TREE_SIDE_EFFECTS (then_clause) && !TREE_SIDE_EFFECTS (else_clause))
+ {
+ *stmt_p = build_empty_stmt ();
+ data->repeat = true;
+ }
+
+ /* If there are no reachable statements in an arm, then we can
+ zap the entire conditional. */
+ else if (integer_nonzerop (cond) && !else_has_label)
+ {
+ if (warn_notreached)
+ remove_useless_stmts_warn_notreached (else_clause);
+ *stmt_p = then_clause;
+ data->repeat = true;
+ }
+ else if (integer_zerop (cond) && !then_has_label)
+ {
+ if (warn_notreached)
+ remove_useless_stmts_warn_notreached (then_clause);
+ *stmt_p = else_clause;
+ data->repeat = true;
+ }
+
+ /* Check a couple of simple things on then/else with single stmts. */
+ else
+ {
+ tree then_stmt = expr_only (then_clause);
+ tree else_stmt = expr_only (else_clause);
+
+ /* Notice branches to a common destination. */
+ if (then_stmt && else_stmt
+ && TREE_CODE (then_stmt) == GOTO_EXPR
+ && TREE_CODE (else_stmt) == GOTO_EXPR
+ && (GOTO_DESTINATION (then_stmt) == GOTO_DESTINATION (else_stmt)))
+ {
+ *stmt_p = then_stmt;
+ data->repeat = true;
+ }
+
+ /* If the THEN/ELSE clause merely assigns a value to a variable or
+ parameter which is already known to contain that value, then
+ remove the useless THEN/ELSE clause. */
+ else if (TREE_CODE (cond) == VAR_DECL || TREE_CODE (cond) == PARM_DECL)
+ {
+ if (else_stmt
+ && TREE_CODE (else_stmt) == MODIFY_EXPR
+ && TREE_OPERAND (else_stmt, 0) == cond
+ && integer_zerop (TREE_OPERAND (else_stmt, 1)))
+ COND_EXPR_ELSE (*stmt_p) = alloc_stmt_list ();
+ }
+ else if ((TREE_CODE (cond) == EQ_EXPR || TREE_CODE (cond) == NE_EXPR)
+ && (TREE_CODE (TREE_OPERAND (cond, 0)) == VAR_DECL
+ || TREE_CODE (TREE_OPERAND (cond, 0)) == PARM_DECL)
+ && TREE_CONSTANT (TREE_OPERAND (cond, 1)))
+ {
+ tree stmt = (TREE_CODE (cond) == EQ_EXPR
+ ? then_stmt : else_stmt);
+ tree *location = (TREE_CODE (cond) == EQ_EXPR
+ ? &COND_EXPR_THEN (*stmt_p)
+ : &COND_EXPR_ELSE (*stmt_p));
+
+ if (stmt
+ && TREE_CODE (stmt) == MODIFY_EXPR
+ && TREE_OPERAND (stmt, 0) == TREE_OPERAND (cond, 0)
+ && TREE_OPERAND (stmt, 1) == TREE_OPERAND (cond, 1))
+ *location = alloc_stmt_list ();
+ }
+ }
+
+ /* Protect GOTOs in the arm of COND_EXPRs from being removed. They
+ would be re-introduced during lowering. */
+ data->last_goto = NULL;
+}
+
+
+static void
+remove_useless_stmts_tf (tree *stmt_p, struct rus_data *data)
+{
+ bool save_may_branch, save_may_throw;
+ bool this_may_branch, this_may_throw;
+
+ /* Collect may_branch and may_throw information for the body only. */
+ save_may_branch = data->may_branch;
+ save_may_throw = data->may_throw;
+ data->may_branch = false;
+ data->may_throw = false;
+ data->last_goto = NULL;
+
+ remove_useless_stmts_1 (&TREE_OPERAND (*stmt_p, 0), data);
+
+ this_may_branch = data->may_branch;
+ this_may_throw = data->may_throw;
+ data->may_branch |= save_may_branch;
+ data->may_throw |= save_may_throw;
+ data->last_goto = NULL;
+
+ remove_useless_stmts_1 (&TREE_OPERAND (*stmt_p, 1), data);
+
+ /* If the body is empty, then we can emit the FINALLY block without
+ the enclosing TRY_FINALLY_EXPR. */
+ if (!TREE_SIDE_EFFECTS (TREE_OPERAND (*stmt_p, 0)))
+ {
+ *stmt_p = TREE_OPERAND (*stmt_p, 1);
+ data->repeat = true;
+ }
+
+ /* If the handler is empty, then we can emit the TRY block without
+ the enclosing TRY_FINALLY_EXPR. */
+ else if (!TREE_SIDE_EFFECTS (TREE_OPERAND (*stmt_p, 1)))
+ {
+ *stmt_p = TREE_OPERAND (*stmt_p, 0);
+ data->repeat = true;
+ }
+
+ /* If the body neither throws, nor branches, then we can safely
+ string the TRY and FINALLY blocks together. */
+ else if (!this_may_branch && !this_may_throw)
+ {
+ tree stmt = *stmt_p;
+ *stmt_p = TREE_OPERAND (stmt, 0);
+ append_to_statement_list (TREE_OPERAND (stmt, 1), stmt_p);
+ data->repeat = true;
+ }
+}
+
+
+static void
+remove_useless_stmts_tc (tree *stmt_p, struct rus_data *data)
+{
+ bool save_may_throw, this_may_throw;
+ tree_stmt_iterator i;
+ tree stmt;
+
+ /* Collect may_throw information for the body only. */
+ save_may_throw = data->may_throw;
+ data->may_throw = false;
+ data->last_goto = NULL;
+
+ remove_useless_stmts_1 (&TREE_OPERAND (*stmt_p, 0), data);
+
+ this_may_throw = data->may_throw;
+ data->may_throw = save_may_throw;
+
+ /* If the body cannot throw, then we can drop the entire TRY_CATCH_EXPR. */
+ if (!this_may_throw)
+ {
+ if (warn_notreached)
+ remove_useless_stmts_warn_notreached (TREE_OPERAND (*stmt_p, 1));
+ *stmt_p = TREE_OPERAND (*stmt_p, 0);
+ data->repeat = true;
+ return;
+ }
+
+ /* Process the catch clause specially. We may be able to tell that
+ no exceptions propagate past this point. */
+
+ this_may_throw = true;
+ i = tsi_start (TREE_OPERAND (*stmt_p, 1));
+ stmt = tsi_stmt (i);
+ data->last_goto = NULL;
+
+ switch (TREE_CODE (stmt))
+ {
+ case CATCH_EXPR:
+ for (; !tsi_end_p (i); tsi_next (&i))
+ {
+ stmt = tsi_stmt (i);
+ /* If we catch all exceptions, then the body does not
+ propagate exceptions past this point. */
+ if (CATCH_TYPES (stmt) == NULL)
+ this_may_throw = false;
+ data->last_goto = NULL;
+ remove_useless_stmts_1 (&CATCH_BODY (stmt), data);
+ }
+ break;
+
+ case EH_FILTER_EXPR:
+ if (EH_FILTER_MUST_NOT_THROW (stmt))
+ this_may_throw = false;
+ else if (EH_FILTER_TYPES (stmt) == NULL)
+ this_may_throw = false;
+ remove_useless_stmts_1 (&EH_FILTER_FAILURE (stmt), data);
+ break;
+
+ default:
+ /* Otherwise this is a cleanup. */
+ remove_useless_stmts_1 (&TREE_OPERAND (*stmt_p, 1), data);
+
+ /* If the cleanup is empty, then we can emit the TRY block without
+ the enclosing TRY_CATCH_EXPR. */
+ if (!TREE_SIDE_EFFECTS (TREE_OPERAND (*stmt_p, 1)))
+ {
+ *stmt_p = TREE_OPERAND (*stmt_p, 0);
+ data->repeat = true;
+ }
+ break;
+ }
+ data->may_throw |= this_may_throw;
+}
+
+
+static void
+remove_useless_stmts_bind (tree *stmt_p, struct rus_data *data)
+{
+ tree block;
+
+ /* First remove anything underneath the BIND_EXPR. */
+ remove_useless_stmts_1 (&BIND_EXPR_BODY (*stmt_p), data);
+
+ /* If the BIND_EXPR has no variables, then we can pull everything
+ up one level and remove the BIND_EXPR, unless this is the toplevel
+ BIND_EXPR for the current function or an inlined function.
+
+ When this situation occurs we will want to apply this
+ optimization again. */
+ block = BIND_EXPR_BLOCK (*stmt_p);
+ if (BIND_EXPR_VARS (*stmt_p) == NULL_TREE
+ && *stmt_p != DECL_SAVED_TREE (current_function_decl)
+ && (! block
+ || ! BLOCK_ABSTRACT_ORIGIN (block)
+ || (TREE_CODE (BLOCK_ABSTRACT_ORIGIN (block))
+ != FUNCTION_DECL)))
+ {
+ *stmt_p = BIND_EXPR_BODY (*stmt_p);
+ data->repeat = true;
+ }
+}
+
+
+static void
+remove_useless_stmts_goto (tree *stmt_p, struct rus_data *data)
+{
+ tree dest = GOTO_DESTINATION (*stmt_p);
+
+ data->may_branch = true;
+ data->last_goto = NULL;
+
+ /* Record the last goto expr, so that we can delete it if unnecessary. */
+ if (TREE_CODE (dest) == LABEL_DECL)
+ data->last_goto = stmt_p;
+}
+
+
+static void
+remove_useless_stmts_label (tree *stmt_p, struct rus_data *data)
+{
+ tree label = LABEL_EXPR_LABEL (*stmt_p);
+
+ data->has_label = true;
+
+ /* We do want to jump across non-local label receiver code. */
+ if (DECL_NONLOCAL (label))
+ data->last_goto = NULL;
+
+ else if (data->last_goto && GOTO_DESTINATION (*data->last_goto) == label)
+ {
+ *data->last_goto = build_empty_stmt ();
+ data->repeat = true;
+ }
+
+ /* ??? Add something here to delete unused labels. */
+}
+
+
+/* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
+ decl. This allows us to eliminate redundant or useless
+ calls to "const" functions.
+
+ Gimplifier already does the same operation, but we may notice functions
+ being const and pure once their calls has been gimplified, so we need
+ to update the flag. */
+
+static void
+update_call_expr_flags (tree call)
+{
+ tree decl = get_callee_fndecl (call);
+ if (!decl)
+ return;
+ if (call_expr_flags (call) & (ECF_CONST | ECF_PURE))
+ TREE_SIDE_EFFECTS (call) = 0;
+ if (TREE_NOTHROW (decl))
+ TREE_NOTHROW (call) = 1;
+}
+
+
+/* T is CALL_EXPR. Set current_function_calls_* flags. */
+
+void
+notice_special_calls (tree t)
+{
+ int flags = call_expr_flags (t);
+
+ if (flags & ECF_MAY_BE_ALLOCA)
+ current_function_calls_alloca = true;
+ if (flags & ECF_RETURNS_TWICE)
+ current_function_calls_setjmp = true;
+}
+
+
+/* Clear flags set by notice_special_calls. Used by dead code removal
+ to update the flags. */
+
+void
+clear_special_calls (void)
+{
+ current_function_calls_alloca = false;
+ current_function_calls_setjmp = false;
+}
+
+
+static void
+remove_useless_stmts_1 (tree *tp, struct rus_data *data)
+{
+ tree t = *tp;
+
+ switch (TREE_CODE (t))
+ {
+ case COND_EXPR:
+ remove_useless_stmts_cond (tp, data);
+ break;
+
+ case TRY_FINALLY_EXPR:
+ remove_useless_stmts_tf (tp, data);
+ break;
+
+ case TRY_CATCH_EXPR:
+ remove_useless_stmts_tc (tp, data);
+ break;
+
+ case BIND_EXPR:
+ remove_useless_stmts_bind (tp, data);
+ break;
+
+ case GOTO_EXPR:
+ remove_useless_stmts_goto (tp, data);
+ break;
+
+ case LABEL_EXPR:
+ remove_useless_stmts_label (tp, data);
+ break;
+
+ case RETURN_EXPR:
+ fold_stmt (tp);
+ data->last_goto = NULL;
+ data->may_branch = true;
+ break;
+
+ case CALL_EXPR:
+ fold_stmt (tp);
+ data->last_goto = NULL;
+ notice_special_calls (t);
+ update_call_expr_flags (t);
+ if (tree_could_throw_p (t))
+ data->may_throw = true;
+ break;
+
+ case MODIFY_EXPR:
+ data->last_goto = NULL;
+ fold_stmt (tp);
+ if (TREE_CODE (TREE_OPERAND (t, 1)) == CALL_EXPR)
+ {
+ update_call_expr_flags (TREE_OPERAND (t, 1));
+ notice_special_calls (TREE_OPERAND (t, 1));
+ }
+ if (tree_could_throw_p (t))
+ data->may_throw = true;
+ break;
+
+ case STATEMENT_LIST:
+ {
+ tree_stmt_iterator i = tsi_start (t);
+ while (!tsi_end_p (i))
+ {
+ t = tsi_stmt (i);
+ if (IS_EMPTY_STMT (t))
+ {
+ tsi_delink (&i);
+ continue;
+ }
+
+ remove_useless_stmts_1 (tsi_stmt_ptr (i), data);
+
+ t = tsi_stmt (i);
+ if (TREE_CODE (t) == STATEMENT_LIST)
+ {
+ tsi_link_before (&i, t, TSI_SAME_STMT);
+ tsi_delink (&i);
+ }
+ else
+ tsi_next (&i);
+ }
+ }
+ break;
+ case SWITCH_EXPR:
+ fold_stmt (tp);
+ data->last_goto = NULL;
+ break;
+
+ default:
+ data->last_goto = NULL;
+ break;
+ }
+}
+
+static void
+remove_useless_stmts (void)
+{
+ struct rus_data data;
+
+ clear_special_calls ();
+
+ do
+ {
+ memset (&data, 0, sizeof (data));
+ remove_useless_stmts_1 (&DECL_SAVED_TREE (current_function_decl), &data);
+ }
+ while (data.repeat);
+}
+
+
+struct tree_opt_pass pass_remove_useless_stmts =
+{
+ "useless", /* name */
+ NULL, /* gate */
+ remove_useless_stmts, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ PROP_gimple_any, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func /* todo_flags_finish */
+};
+
+
+/* Remove obviously useless statements in basic block BB. */
+
+static void
+cfg_remove_useless_stmts_bb (basic_block bb)
+{
+ block_stmt_iterator bsi;
+ tree stmt = NULL_TREE;
+ tree cond, var = NULL_TREE, val = NULL_TREE;
+ struct var_ann_d *ann;
+
+ /* Check whether we come here from a condition, and if so, get the
+ condition. */
+ if (!bb->pred
+ || bb->pred->pred_next
+ || !(bb->pred->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
+ return;
+
+ cond = COND_EXPR_COND (last_stmt (bb->pred->src));
+
+ if (TREE_CODE (cond) == VAR_DECL || TREE_CODE (cond) == PARM_DECL)
+ {
+ var = cond;
+ val = (bb->pred->flags & EDGE_FALSE_VALUE
+ ? boolean_false_node : boolean_true_node);
+ }
+ else if (TREE_CODE (cond) == TRUTH_NOT_EXPR
+ && (TREE_CODE (TREE_OPERAND (cond, 0)) == VAR_DECL
+ || TREE_CODE (TREE_OPERAND (cond, 0)) == PARM_DECL))
+ {
+ var = TREE_OPERAND (cond, 0);
+ val = (bb->pred->flags & EDGE_FALSE_VALUE
+ ? boolean_true_node : boolean_false_node);
+ }
+ else
+ {
+ if (bb->pred->flags & EDGE_FALSE_VALUE)
+ cond = invert_truthvalue (cond);
+ if (TREE_CODE (cond) == EQ_EXPR
+ && (TREE_CODE (TREE_OPERAND (cond, 0)) == VAR_DECL
+ || TREE_CODE (TREE_OPERAND (cond, 0)) == PARM_DECL)
+ && (TREE_CODE (TREE_OPERAND (cond, 1)) == VAR_DECL
+ || TREE_CODE (TREE_OPERAND (cond, 1)) == PARM_DECL
+ || TREE_CONSTANT (TREE_OPERAND (cond, 1))))
+ {
+ var = TREE_OPERAND (cond, 0);
+ val = TREE_OPERAND (cond, 1);
+ }
+ else
+ return;
+ }
+
+ /* Only work for normal local variables. */
+ ann = var_ann (var);
+ if (!ann
+ || ann->may_aliases
+ || TREE_ADDRESSABLE (var))
+ return;
+
+ if (! TREE_CONSTANT (val))
+ {
+ ann = var_ann (val);
+ if (!ann
+ || ann->may_aliases
+ || TREE_ADDRESSABLE (val))
+ return;
+ }
+
+ /* Ignore floating point variables, since comparison behaves weird for
+ them. */
+ if (FLOAT_TYPE_P (TREE_TYPE (var)))
+ return;
+
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi);)
+ {
+ stmt = bsi_stmt (bsi);
+
+ /* If the THEN/ELSE clause merely assigns a value to a variable/parameter
+ which is already known to contain that value, then remove the useless
+ THEN/ELSE clause. */
+ if (TREE_CODE (stmt) == MODIFY_EXPR
+ && TREE_OPERAND (stmt, 0) == var
+ && operand_equal_p (val, TREE_OPERAND (stmt, 1), 0))
+ {
+ bsi_remove (&bsi);
+ continue;
+ }
+
+ /* Invalidate the var if we encounter something that could modify it. */
+ if (TREE_CODE (stmt) == ASM_EXPR
+ || TREE_CODE (stmt) == VA_ARG_EXPR
+ || (TREE_CODE (stmt) == MODIFY_EXPR
+ && (TREE_OPERAND (stmt, 0) == var
+ || TREE_OPERAND (stmt, 0) == val
+ || TREE_CODE (TREE_OPERAND (stmt, 1)) == VA_ARG_EXPR)))
+ return;
+
+ bsi_next (&bsi);
+ }
+}
+
+
+/* A CFG-aware version of remove_useless_stmts. */
+
+void
+cfg_remove_useless_stmts (void)
+{
+ basic_block bb;
+
+#ifdef ENABLE_CHECKING
+ verify_flow_info ();
+#endif
+
+ FOR_EACH_BB (bb)
+ {
+ cfg_remove_useless_stmts_bb (bb);
+ }
+}
+
+
+/* Remove PHI nodes associated with basic block BB and all edges out of BB. */
+
+static void
+remove_phi_nodes_and_edges_for_unreachable_block (basic_block bb)
+{
+ tree phi;
+
+ /* Since this block is no longer reachable, we can just delete all
+ of its PHI nodes. */
+ phi = phi_nodes (bb);
+ while (phi)
+ {
+ tree next = TREE_CHAIN (phi);
+ remove_phi_node (phi, NULL_TREE, bb);
+ phi = next;
+ }
+
+ /* Remove edges to BB's successors. */
+ while (bb->succ != NULL)
+ ssa_remove_edge (bb->succ);
+}
+
+
+/* Remove statements of basic block BB. */
+
+static void
+remove_bb (basic_block bb)
+{
+ block_stmt_iterator i;
+ location_t *loc = NULL;
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "Removing basic block %d\n", bb->index);
+ if (dump_flags & TDF_DETAILS)
+ {
+ dump_bb (bb, dump_file, 0);
+ fprintf (dump_file, "\n");
+ }
+ }
+
+ /* Remove all the instructions in the block. */
+ for (i = bsi_start (bb); !bsi_end_p (i); bsi_remove (&i))
+ {
+ tree stmt = bsi_stmt (i);
+
+ set_bb_for_stmt (stmt, NULL);
+
+ /* Don't warn for removed gotos. Gotos are often removed due to
+ jump threading, thus resulting in bogus warnings. Not great,
+ since this way we lose warnings for gotos in the original
+ program that are indeed unreachable. */
+ if (TREE_CODE (stmt) != GOTO_EXPR && EXPR_LOCUS (stmt) && !loc)
+ loc = EXPR_LOCUS (stmt);
+ }
+
+ /* If requested, give a warning that the first statement in the
+ block is unreachable. We walk statements backwards in the
+ loop above, so the last statement we process is the first statement
+ in the block. */
+ if (warn_notreached && loc)
+ warning ("%Hwill never be executed", loc);
+
+ remove_phi_nodes_and_edges_for_unreachable_block (bb);
+}
+
+
+/* Examine BB to determine if it is a forwarding block (a block which only
+ transfers control to a new destination). If BB is a forwarding block,
+ then return the edge leading to the ultimate destination. */
+
+edge
+tree_block_forwards_to (basic_block bb)
+{
+ block_stmt_iterator bsi;
+ bb_ann_t ann = bb_ann (bb);
+ tree stmt;
+
+ /* If this block is not forwardable, then avoid useless work. */
+ if (! ann->forwardable)
+ return NULL;
+
+ /* Set this block to not be forwardable. This prevents infinite loops since
+ any block currently under examination is considered non-forwardable. */
+ ann->forwardable = 0;
+
+ /* No forwarding is possible if this block is a special block (ENTRY/EXIT),
+ this block has more than one successor, this block's single successor is
+ reached via an abnormal edge, this block has phi nodes, or this block's
+ single successor has phi nodes. */
+ if (bb == EXIT_BLOCK_PTR
+ || bb == ENTRY_BLOCK_PTR
+ || !bb->succ
+ || bb->succ->succ_next
+ || bb->succ->dest == EXIT_BLOCK_PTR
+ || (bb->succ->flags & EDGE_ABNORMAL) != 0
+ || phi_nodes (bb)
+ || phi_nodes (bb->succ->dest))
+ return NULL;
+
+ /* Walk past any labels at the start of this block. */
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ stmt = bsi_stmt (bsi);
+ if (TREE_CODE (stmt) != LABEL_EXPR)
+ break;
+ }
+
+ /* If we reached the end of this block we may be able to optimize this
+ case. */
+ if (bsi_end_p (bsi))
+ {
+ edge dest;
+
+ /* Recursive call to pick up chains of forwarding blocks. */
+ dest = tree_block_forwards_to (bb->succ->dest);
+
+ /* If none found, we forward to bb->succ at minimum. */
+ if (!dest)
+ dest = bb->succ;
+
+ ann->forwardable = 1;
+ return dest;
+ }
+
+ /* No forwarding possible. */
+ return NULL;
+}
+
+
+/* Try to remove superfluous control structures. */
+
+static bool
+cleanup_control_flow (void)
+{
+ basic_block bb;
+ block_stmt_iterator bsi;
+ bool retval = false;
+ tree stmt;
+
+ FOR_EACH_BB (bb)
+ {
+ bsi = bsi_last (bb);
+
+ if (bsi_end_p (bsi))
+ continue;
+
+ stmt = bsi_stmt (bsi);
+ if (TREE_CODE (stmt) == COND_EXPR
+ || TREE_CODE (stmt) == SWITCH_EXPR)
+ retval |= cleanup_control_expr_graph (bb, bsi);
+ }
+ return retval;
+}
+
+
+/* Disconnect an unreachable block in the control expression starting
+ at block BB. */
+
+static bool
+cleanup_control_expr_graph (basic_block bb, block_stmt_iterator bsi)
+{
+ edge taken_edge;
+ bool retval = false;
+ tree expr = bsi_stmt (bsi), val;
+
+ if (bb->succ->succ_next)
+ {
+ edge e, next;
+
+ switch (TREE_CODE (expr))
+ {
+ case COND_EXPR:
+ val = COND_EXPR_COND (expr);
+ break;
+
+ case SWITCH_EXPR:
+ val = SWITCH_COND (expr);
+ if (TREE_CODE (val) != INTEGER_CST)
+ return false;
+ break;
+
+ default:
+ abort ();
+ }
+
+ taken_edge = find_taken_edge (bb, val);
+ if (!taken_edge)
+ return false;
+
+ /* Remove all the edges except the one that is always executed. */
+ for (e = bb->succ; e; e = next)
+ {
+ next = e->succ_next;
+ if (e != taken_edge)
+ {
+ taken_edge->probability += e->probability;
+ taken_edge->count += e->count;
+ ssa_remove_edge (e);
+ retval = true;
+ }
+ }
+ if (taken_edge->probability > REG_BR_PROB_BASE)
+ taken_edge->probability = REG_BR_PROB_BASE;
+ }
+ else
+ taken_edge = bb->succ;
+
+ bsi_remove (&bsi);
+ taken_edge->flags = EDGE_FALLTHRU;
+
+ /* We removed some paths from the cfg. */
+ if (dom_computed[CDI_DOMINATORS] >= DOM_CONS_OK)
+ dom_computed[CDI_DOMINATORS] = DOM_CONS_OK;
+
+ return retval;
+}
+
+
+/* Given a control block BB and a constant value VAL, return the edge that
+ will be taken out of the block. If VAL does not match a unique edge,
+ NULL is returned. */
+
+edge
+find_taken_edge (basic_block bb, tree val)
+{
+ tree stmt;
+
+ stmt = last_stmt (bb);
+
+#if defined ENABLE_CHECKING
+ if (stmt == NULL_TREE || !is_ctrl_stmt (stmt))
+ abort ();
+#endif
+
+ /* If VAL is not a constant, we can't determine which edge might
+ be taken. */
+ if (val == NULL || !really_constant_p (val))
+ return NULL;
+
+ if (TREE_CODE (stmt) == COND_EXPR)
+ return find_taken_edge_cond_expr (bb, val);
+
+ if (TREE_CODE (stmt) == SWITCH_EXPR)
+ return find_taken_edge_switch_expr (bb, val);
+
+ return bb->succ;
+}
+
+
+/* Given a constant value VAL and the entry block BB to a COND_EXPR
+ statement, determine which of the two edges will be taken out of the
+ block. Return NULL if either edge may be taken. */
+
+static edge
+find_taken_edge_cond_expr (basic_block bb, tree val)
+{
+ edge true_edge, false_edge;
+
+ extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
+
+ /* If both edges of the branch lead to the same basic block, it doesn't
+ matter which edge is taken. */
+ if (true_edge->dest == false_edge->dest)
+ return true_edge;
+
+ /* Otherwise, try to determine which branch of the if() will be taken.
+ If VAL is a constant but it can't be reduced to a 0 or a 1, then
+ we don't really know which edge will be taken at runtime. This
+ may happen when comparing addresses (e.g., if (&var1 == 4)). */
+ if (integer_nonzerop (val))
+ return true_edge;
+ else if (integer_zerop (val))
+ return false_edge;
+ else
+ return NULL;
+}
+
+
+/* Given a constant value VAL and the entry block BB to a SWITCH_EXPR
+ statement, determine which edge will be taken out of the block. Return
+ NULL if any edge may be taken. */
+
+static edge
+find_taken_edge_switch_expr (basic_block bb, tree val)
+{
+ tree switch_expr, taken_case;
+ basic_block dest_bb;
+ edge e;
+
+ if (TREE_CODE (val) != INTEGER_CST)
+ return NULL;
+
+ switch_expr = last_stmt (bb);
+ taken_case = find_case_label_for_value (switch_expr, val);
+ dest_bb = label_to_block (CASE_LABEL (taken_case));
+
+ e = find_edge (bb, dest_bb);
+ if (!e)
+ abort ();
+ return e;
+}
+
+
+/* Return the CASE_LABEL_EXPR that SWITCH_EXPR will take for VAL. */
+
+static tree
+find_case_label_for_value (tree switch_expr, tree val)
+{
+ tree vec = SWITCH_LABELS (switch_expr);
+ size_t i, n = TREE_VEC_LENGTH (vec);
+ tree default_case = NULL;
+
+ for (i = 0; i < n; ++i)
+ {
+ tree t = TREE_VEC_ELT (vec, i);
+
+ if (CASE_LOW (t) == NULL)
+ default_case = t;
+ else if (CASE_HIGH (t) == NULL)
+ {
+ /* A `normal' case label. */
+ if (simple_cst_equal (CASE_LOW (t), val) == 1)
+ return t;
+ }
+ else
+ {
+ /* A case range. We can only handle integer ranges. */
+ if (tree_int_cst_compare (CASE_LOW (t), val) <= 0
+ && tree_int_cst_compare (CASE_HIGH (t), val) >= 0)
+ return t;
+ }
+ }
+
+ if (!default_case)
+ abort ();
+
+ return default_case;
+}
+
+
+/* If all the PHI nodes in DEST have alternatives for E1 and E2 and
+ those alternatives are equal in each of the PHI nodes, then return
+ true, else return false. */
+
+static bool
+phi_alternatives_equal (basic_block dest, edge e1, edge e2)
+{
+ tree phi, val1, val2;
+ int n1, n2;
+
+ for (phi = phi_nodes (dest); phi; phi = TREE_CHAIN (phi))
+ {
+ n1 = phi_arg_from_edge (phi, e1);
+ n2 = phi_arg_from_edge (phi, e2);
+
+#ifdef ENABLE_CHECKING
+ if (n1 < 0 || n2 < 0)
+ abort ();
+#endif
+
+ val1 = PHI_ARG_DEF (phi, n1);
+ val2 = PHI_ARG_DEF (phi, n2);
+
+ if (!operand_equal_p (val1, val2, 0))
+ return false;
+ }
+
+ return true;
+}
+
+
+/* Computing the Dominance Frontier:
+
+ As described in Morgan, section 3.5, this may be done simply by
+ walking the dominator tree bottom-up, computing the frontier for
+ the children before the parent. When considering a block B,
+ there are two cases:
+
+ (1) A flow graph edge leaving B that does not lead to a child
+ of B in the dominator tree must be a block that is either equal
+ to B or not dominated by B. Such blocks belong in the frontier
+ of B.
+
+ (2) Consider a block X in the frontier of one of the children C
+ of B. If X is not equal to B and is not dominated by B, it
+ is in the frontier of B. */
+
+static void
+compute_dominance_frontiers_1 (bitmap *frontiers, basic_block bb, sbitmap done)
+{
+ edge e;
+ basic_block c;
+
+ SET_BIT (done, bb->index);
+
+ /* Do the frontier of the children first. Not all children in the
+ dominator tree (blocks dominated by this one) are children in the
+ CFG, so check all blocks. */
+ for (c = first_dom_son (CDI_DOMINATORS, bb);
+ c;
+ c = next_dom_son (CDI_DOMINATORS, c))
+ {
+ if (! TEST_BIT (done, c->index))
+ compute_dominance_frontiers_1 (frontiers, c, done);
+ }
+
+ /* Find blocks conforming to rule (1) above. */
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ if (e->dest == EXIT_BLOCK_PTR)
+ continue;
+ if (get_immediate_dominator (CDI_DOMINATORS, e->dest) != bb)
+ bitmap_set_bit (frontiers[bb->index], e->dest->index);
+ }
+
+ /* Find blocks conforming to rule (2). */
+ for (c = first_dom_son (CDI_DOMINATORS, bb);
+ c;
+ c = next_dom_son (CDI_DOMINATORS, c))
+ {
+ int x;
+
+ EXECUTE_IF_SET_IN_BITMAP (frontiers[c->index], 0, x,
+ {
+ if (get_immediate_dominator (CDI_DOMINATORS, BASIC_BLOCK (x)) != bb)
+ bitmap_set_bit (frontiers[bb->index], x);
+ });
+ }
+}
+
+
+void
+compute_dominance_frontiers (bitmap *frontiers)
+{
+ sbitmap done = sbitmap_alloc (last_basic_block);
+
+ timevar_push (TV_DOM_FRONTIERS);
+
+ sbitmap_zero (done);
+
+ compute_dominance_frontiers_1 (frontiers, ENTRY_BLOCK_PTR->succ->dest, done);
+
+ sbitmap_free (done);
+
+ timevar_pop (TV_DOM_FRONTIERS);
+}
+
+
+
+/*---------------------------------------------------------------------------
+ Debugging functions
+---------------------------------------------------------------------------*/
+
+/* Dump tree-specific information of block BB to file OUTF. */
+
+void
+tree_dump_bb (basic_block bb, FILE *outf, int indent)
+{
+ dump_generic_bb (outf, bb, indent, TDF_VOPS);
+}
+
+
+/* Dump a basic block on stderr. */
+
+void
+debug_tree_bb (basic_block bb)
+{
+ dump_bb (bb, stderr, 0);
+}
+
+
+/* Dump basic block with index N on stderr. */
+
+basic_block
+debug_tree_bb_n (int n)
+{
+ debug_tree_bb (BASIC_BLOCK (n));
+ return BASIC_BLOCK (n);
+}
+
+
+/* Dump the CFG on stderr.
+
+ FLAGS are the same used by the tree dumping functions
+ (see TDF_* in tree.h). */
+
+void
+debug_tree_cfg (int flags)
+{
+ dump_tree_cfg (stderr, flags);
+}
+
+
+/* Dump the program showing basic block boundaries on the given FILE.
+
+ FLAGS are the same used by the tree dumping functions (see TDF_* in
+ tree.h). */
+
+void
+dump_tree_cfg (FILE *file, int flags)
+{
+ if (flags & TDF_DETAILS)
+ {
+ const char *funcname
+ = (*lang_hooks.decl_printable_name) (current_function_decl, 2);
+
+ fputc ('\n', file);
+ fprintf (file, ";; Function %s\n\n", funcname);
+ fprintf (file, ";; \n%d basic blocks, %d edges, last basic block %d.\n\n",
+ n_basic_blocks, n_edges, last_basic_block);
+
+ brief_dump_cfg (file);
+ fprintf (file, "\n");
+ }
+
+ if (flags & TDF_STATS)
+ dump_cfg_stats (file);
+
+ dump_function_to_file (current_function_decl, file, flags | TDF_BLOCKS);
+}
+
+
+/* Dump CFG statistics on FILE. */
+
+void
+dump_cfg_stats (FILE *file)
+{
+ static long max_num_merged_labels = 0;
+ unsigned long size, total = 0;
+ long n_edges;
+ basic_block bb;
+ const char * const fmt_str = "%-30s%-13s%12s\n";
+ const char * const fmt_str_1 = "%-30s%13lu%11lu%c\n";
+ const char * const fmt_str_3 = "%-43s%11lu%c\n";
+ const char *funcname
+ = (*lang_hooks.decl_printable_name) (current_function_decl, 2);
+
+
+ fprintf (file, "\nCFG Statistics for %s\n\n", funcname);
+
+ fprintf (file, "---------------------------------------------------------\n");
+ fprintf (file, fmt_str, "", " Number of ", "Memory");
+ fprintf (file, fmt_str, "", " instances ", "used ");
+ fprintf (file, "---------------------------------------------------------\n");
+
+ size = n_basic_blocks * sizeof (struct basic_block_def);
+ total += size;
+ fprintf (file, fmt_str_1, "Basic blocks", n_basic_blocks, SCALE (size),
+ LABEL (size));
+
+ n_edges = 0;
+ FOR_EACH_BB (bb)
+ {
+ edge e;
+ for (e = bb->succ; e; e = e->succ_next)
+ n_edges++;
+ }
+ size = n_edges * sizeof (struct edge_def);
+ total += size;
+ fprintf (file, fmt_str_1, "Edges", n_edges, SCALE (size), LABEL (size));
+
+ size = n_basic_blocks * sizeof (struct bb_ann_d);
+ total += size;
+ fprintf (file, fmt_str_1, "Basic block annotations", n_basic_blocks,
+ SCALE (size), LABEL (size));
+
+ fprintf (file, "---------------------------------------------------------\n");
+ fprintf (file, fmt_str_3, "Total memory used by CFG data", SCALE (total),
+ LABEL (total));
+ fprintf (file, "---------------------------------------------------------\n");
+ fprintf (file, "\n");
+
+ if (cfg_stats.num_merged_labels > max_num_merged_labels)
+ max_num_merged_labels = cfg_stats.num_merged_labels;
+
+ fprintf (file, "Coalesced label blocks: %ld (Max so far: %ld)\n",
+ cfg_stats.num_merged_labels, max_num_merged_labels);
+
+ fprintf (file, "\n");
+}
+
+
+/* Dump CFG statistics on stderr. Keep extern so that it's always
+ linked in the final executable. */
+
+void
+debug_cfg_stats (void)
+{
+ dump_cfg_stats (stderr);
+}
+
+
+/* Dump the flowgraph to a .vcg FILE. */
+
+static void
+tree_cfg2vcg (FILE *file)
+{
+ edge e;
+ basic_block bb;
+ const char *funcname
+ = (*lang_hooks.decl_printable_name) (current_function_decl, 2);
+
+ /* Write the file header. */
+ fprintf (file, "graph: { title: \"%s\"\n", funcname);
+ fprintf (file, "node: { title: \"ENTRY\" label: \"ENTRY\" }\n");
+ fprintf (file, "node: { title: \"EXIT\" label: \"EXIT\" }\n");
+
+ /* Write blocks and edges. */
+ for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
+ {
+ fprintf (file, "edge: { sourcename: \"ENTRY\" targetname: \"%d\"",
+ e->dest->index);
+
+ if (e->flags & EDGE_FAKE)
+ fprintf (file, " linestyle: dotted priority: 10");
+ else
+ fprintf (file, " linestyle: solid priority: 100");
+
+ fprintf (file, " }\n");
+ }
+ fputc ('\n', file);
+
+ FOR_EACH_BB (bb)
+ {
+ enum tree_code head_code, end_code;
+ const char *head_name, *end_name;
+ int head_line = 0;
+ int end_line = 0;
+ tree first = first_stmt (bb);
+ tree last = last_stmt (bb);
+
+ if (first)
+ {
+ head_code = TREE_CODE (first);
+ head_name = tree_code_name[head_code];
+ head_line = get_lineno (first);
+ }
+ else
+ head_name = "no-statement";
+
+ if (last)
+ {
+ end_code = TREE_CODE (last);
+ end_name = tree_code_name[end_code];
+ end_line = get_lineno (last);
+ }
+ else
+ end_name = "no-statement";
+
+ fprintf (file, "node: { title: \"%d\" label: \"#%d\\n%s (%d)\\n%s (%d)\"}\n",
+ bb->index, bb->index, head_name, head_line, end_name,
+ end_line);
+
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ if (e->dest == EXIT_BLOCK_PTR)
+ fprintf (file, "edge: { sourcename: \"%d\" targetname: \"EXIT\"", bb->index);
+ else
+ fprintf (file, "edge: { sourcename: \"%d\" targetname: \"%d\"", bb->index, e->dest->index);
+
+ if (e->flags & EDGE_FAKE)
+ fprintf (file, " priority: 10 linestyle: dotted");
+ else
+ fprintf (file, " priority: 100 linestyle: solid");
+
+ fprintf (file, " }\n");
+ }
+
+ if (bb->next_bb != EXIT_BLOCK_PTR)
+ fputc ('\n', file);
+ }
+
+ fputs ("}\n\n", file);
+}
+
+
+
+/*---------------------------------------------------------------------------
+ Miscellaneous helpers
+---------------------------------------------------------------------------*/
+
+/* Return true if T represents a stmt that always transfers control. */
+
+bool
+is_ctrl_stmt (tree t)
+{
+ return (TREE_CODE (t) == COND_EXPR
+ || TREE_CODE (t) == SWITCH_EXPR
+ || TREE_CODE (t) == GOTO_EXPR
+ || TREE_CODE (t) == RETURN_EXPR
+ || TREE_CODE (t) == RESX_EXPR);
+}
+
+
+/* Return true if T is a statement that may alter the flow of control
+ (e.g., a call to a non-returning function). */
+
+bool
+is_ctrl_altering_stmt (tree t)
+{
+ tree call = t;
+
+#if defined ENABLE_CHECKING
+ if (t == NULL)
+ abort ();
+#endif
+
+ switch (TREE_CODE (t))
+ {
+ case MODIFY_EXPR:
+ /* A MODIFY_EXPR with a rhs of a call has the characteristics
+ of the call. */
+ call = TREE_OPERAND (t, 1);
+ if (TREE_CODE (call) != CALL_EXPR)
+ break;
+ /* FALLTHRU */
+
+ case CALL_EXPR:
+ /* A non-pure/const CALL_EXPR alters flow control if the current
+ function has nonlocal labels. */
+ if (TREE_SIDE_EFFECTS (t)
+ && current_function_has_nonlocal_label)
+ return true;
+
+ /* A CALL_EXPR also alters control flow if it does not return. */
+ if (call_expr_flags (call) & (ECF_NORETURN | ECF_LONGJMP))
+ return true;
+ break;
+
+ default:
+ return false;
+ }
+
+ /* If a statement can throw, it alters control flow. */
+ return tree_can_throw_internal (t);
+}
+
+
+/* Return true if T is a computed goto. */
+
+bool
+computed_goto_p (tree t)
+{
+ return (TREE_CODE (t) == GOTO_EXPR
+ && TREE_CODE (GOTO_DESTINATION (t)) != LABEL_DECL);
+}
+
+
+/* Checks whether EXPR is a simple local goto. */
+
+bool
+simple_goto_p (tree expr)
+{
+ return (TREE_CODE (expr) == GOTO_EXPR
+ && TREE_CODE (GOTO_DESTINATION (expr)) == LABEL_DECL
+ && (decl_function_context (GOTO_DESTINATION (expr))
+ == current_function_decl));
+}
+
+
+/* Return true if T should start a new basic block. PREV_T is the
+ statement preceding T. It is used when T is a label or a case label.
+ Labels should only start a new basic block if their previous statement
+ wasn't a label. Otherwise, sequence of labels would generate
+ unnecessary basic blocks that only contain a single label. */
+
+static inline bool
+stmt_starts_bb_p (tree t, tree prev_t)
+{
+ enum tree_code code;
+
+ if (t == NULL_TREE)
+ return false;
+
+ /* LABEL_EXPRs start a new basic block only if the preceding
+ statement wasn't a label of the same type. This prevents the
+ creation of consecutive blocks that have nothing but a single
+ label. */
+ code = TREE_CODE (t);
+ if (code == LABEL_EXPR)
+ {
+ /* Nonlocal and computed GOTO targets always start a new block. */
+ if (code == LABEL_EXPR
+ && (DECL_NONLOCAL (LABEL_EXPR_LABEL (t))
+ || FORCED_LABEL (LABEL_EXPR_LABEL (t))))
+ return true;
+
+ if (prev_t && TREE_CODE (prev_t) == code)
+ {
+ if (DECL_NONLOCAL (LABEL_EXPR_LABEL (prev_t)))
+ return true;
+
+ cfg_stats.num_merged_labels++;
+ return false;
+ }
+ else
+ return true;
+ }
+
+ return false;
+}
+
+
+/* Return true if T should end a basic block. */
+
+bool
+stmt_ends_bb_p (tree t)
+{
+ return is_ctrl_stmt (t) || is_ctrl_altering_stmt (t);
+}
+
+
+/* Add gotos that used to be represented implicitly in the CFG. */
+
+void
+disband_implicit_edges (void)
+{
+ basic_block bb;
+ block_stmt_iterator last;
+ edge e;
+ tree stmt, label, forward;
+
+ FOR_EACH_BB (bb)
+ {
+ last = bsi_last (bb);
+ stmt = last_stmt (bb);
+
+ if (stmt && TREE_CODE (stmt) == COND_EXPR)
+ {
+ /* Remove superfluous gotos from COND_EXPR branches. Moved
+ from cfg_remove_useless_stmts here since it violates the
+ invariants for tree--cfg correspondence and thus fits better
+ here where we do it anyway. */
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ if (e->dest != bb->next_bb)
+ continue;
+
+ if (e->flags & EDGE_TRUE_VALUE)
+ COND_EXPR_THEN (stmt) = build_empty_stmt ();
+ else if (e->flags & EDGE_FALSE_VALUE)
+ COND_EXPR_ELSE (stmt) = build_empty_stmt ();
+ else
+ abort ();
+ e->flags |= EDGE_FALLTHRU;
+ }
+
+ continue;
+ }
+
+ if (stmt && TREE_CODE (stmt) == RETURN_EXPR)
+ {
+ /* Remove the RETURN_EXPR if we may fall though to the exit
+ instead. */
+ if (!bb->succ
+ || bb->succ->succ_next
+ || bb->succ->dest != EXIT_BLOCK_PTR)
+ abort ();
+
+ if (bb->next_bb == EXIT_BLOCK_PTR
+ && !TREE_OPERAND (stmt, 0))
+ {
+ bsi_remove (&last);
+ bb->succ->flags |= EDGE_FALLTHRU;
+ }
+ continue;
+ }
+
+ /* There can be no fallthru edge if the last statement is a control
+ one. */
+ if (stmt && is_ctrl_stmt (stmt))
+ continue;
+
+ /* Find a fallthru edge and emit the goto if necessary. */
+ for (e = bb->succ; e; e = e->succ_next)
+ if (e->flags & EDGE_FALLTHRU)
+ break;
+
+ if (!e
+ || e->dest == bb->next_bb)
+ continue;
+
+ if (e->dest == EXIT_BLOCK_PTR)
+ abort ();
+
+ label = tree_block_label (e->dest);
+
+ /* If this is a goto to a goto, jump to the final destination.
+ Handles unfactoring of the computed jumps.
+ ??? Why bother putting this back together when rtl is just
+ about to take it apart again? */
+ forward = last_and_only_stmt (e->dest);
+ if (forward
+ && TREE_CODE (forward) == GOTO_EXPR)
+ label = GOTO_DESTINATION (forward);
+
+ bsi_insert_after (&last,
+ build1 (GOTO_EXPR, void_type_node, label),
+ BSI_NEW_STMT);
+ e->flags &= ~EDGE_FALLTHRU;
+ }
+}
+
+
+/* Remove all the blocks and edges that make up the flowgraph. */
+
+void
+delete_tree_cfg (void)
+{
+ if (n_basic_blocks > 0)
+ free_blocks_annotations ();
+
+ free_basic_block_vars ();
+ basic_block_info = NULL;
+ label_to_block_map = NULL;
+ free_rbi_pool ();
+}
+
+
+/* Return the first statement in basic block BB. */
+
+tree
+first_stmt (basic_block bb)
+{
+ block_stmt_iterator i = bsi_start (bb);
+ return !bsi_end_p (i) ? bsi_stmt (i) : NULL_TREE;
+}
+
+
+/* Return the last statement in basic block BB. */
+
+tree
+last_stmt (basic_block bb)
+{
+ block_stmt_iterator b = bsi_last (bb);
+ return !bsi_end_p (b) ? bsi_stmt (b) : NULL_TREE;
+}
+
+
+/* Return a pointer to the last statement in block BB. */
+
+tree *
+last_stmt_ptr (basic_block bb)
+{
+ block_stmt_iterator last = bsi_last (bb);
+ return !bsi_end_p (last) ? bsi_stmt_ptr (last) : NULL;
+}
+
+
+/* Return the last statement of an otherwise empty block. Return NULL
+ if the block is totally empty, or if it contains more than one
+ statement. */
+
+tree
+last_and_only_stmt (basic_block bb)
+{
+ block_stmt_iterator i = bsi_last (bb);
+ tree last, prev;
+
+ if (bsi_end_p (i))
+ return NULL_TREE;
+
+ last = bsi_stmt (i);
+ bsi_prev (&i);
+ if (bsi_end_p (i))
+ return last;
+
+ /* Empty statements should no longer appear in the instruction stream.
+ Everything that might have appeared before should be deleted by
+ remove_useless_stmts, and the optimizers should just bsi_remove
+ instead of smashing with build_empty_stmt.
+
+ Thus the only thing that should appear here in a block containing
+ one executable statement is a label. */
+ prev = bsi_stmt (i);
+ if (TREE_CODE (prev) == LABEL_EXPR)
+ return last;
+ else
+ return NULL_TREE;
+}
+
+
+/* Mark BB as the basic block holding statement T. */
+
+void
+set_bb_for_stmt (tree t, basic_block bb)
+{
+ if (TREE_CODE (t) == STATEMENT_LIST)
+ {
+ tree_stmt_iterator i;
+ for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
+ set_bb_for_stmt (tsi_stmt (i), bb);
+ }
+ else
+ {
+ stmt_ann_t ann = get_stmt_ann (t);
+ ann->bb = bb;
+
+ /* If the statement is a label, add the label to block-to-labels map
+ so that we can speed up edge creation for GOTO_EXPRs. */
+ if (TREE_CODE (t) == LABEL_EXPR)
+ {
+ int uid;
+
+ t = LABEL_EXPR_LABEL (t);
+ uid = LABEL_DECL_UID (t);
+ if (uid == -1)
+ {
+ LABEL_DECL_UID (t) = uid = cfun->last_label_uid++;
+ if (VARRAY_SIZE (label_to_block_map) <= (unsigned) uid)
+ VARRAY_GROW (label_to_block_map, 3 * uid / 2);
+ }
+ else
+ {
+#ifdef ENABLE_CHECKING
+ /* We're moving an existing label. Make sure that we've
+ removed it from the old block. */
+ if (bb && VARRAY_BB (label_to_block_map, uid))
+ abort ();
+#endif
+ }
+ VARRAY_BB (label_to_block_map, uid) = bb;
+ }
+ }
+}
+
+
+/* Insert statement (or statement list) T before the statement
+ pointed-to by iterator I. M specifies how to update iterator I
+ after insertion (see enum bsi_iterator_update). */
+
+void
+bsi_insert_before (block_stmt_iterator *i, tree t, enum bsi_iterator_update m)
+{
+ set_bb_for_stmt (t, i->bb);
+ modify_stmt (t);
+ tsi_link_before (&i->tsi, t, m);
+}
+
+
+/* Insert statement (or statement list) T after the statement
+ pointed-to by iterator I. M specifies how to update iterator I
+ after insertion (see enum bsi_iterator_update). */
+
+void
+bsi_insert_after (block_stmt_iterator *i, tree t, enum bsi_iterator_update m)
+{
+ set_bb_for_stmt (t, i->bb);
+ modify_stmt (t);
+ tsi_link_after (&i->tsi, t, m);
+}
+
+
+/* Remove the statement pointed to by iterator I. The iterator is updated
+ to the next statement. */
+
+void
+bsi_remove (block_stmt_iterator *i)
+{
+ tree t = bsi_stmt (*i);
+ set_bb_for_stmt (t, NULL);
+ modify_stmt (t);
+ tsi_delink (&i->tsi);
+}
+
+
+/* Move the statement at FROM so it comes right after the statement at TO. */
+
+void
+bsi_move_after (block_stmt_iterator *from, block_stmt_iterator *to)
+{
+ tree stmt = bsi_stmt (*from);
+ bsi_remove (from);
+ bsi_insert_after (to, stmt, BSI_SAME_STMT);
+}
+
+
+/* Move the statement at FROM so it comes right before the statement at TO. */
+
+void
+bsi_move_before (block_stmt_iterator *from, block_stmt_iterator *to)
+{
+ tree stmt = bsi_stmt (*from);
+ bsi_remove (from);
+ bsi_insert_before (to, stmt, BSI_SAME_STMT);
+}
+
+
+/* Move the statement at FROM to the end of basic block BB. */
+
+void
+bsi_move_to_bb_end (block_stmt_iterator *from, basic_block bb)
+{
+ block_stmt_iterator last = bsi_last (bb);
+
+ /* Have to check bsi_end_p because it could be an empty block. */
+ if (!bsi_end_p (last) && is_ctrl_stmt (bsi_stmt (last)))
+ bsi_move_before (from, &last);
+ else
+ bsi_move_after (from, &last);
+}
+
+
+/* Replace the contents of the statement pointed to by iterator BSI
+ with STMT. If PRESERVE_EH_INFO is true, the exception handling
+ information of the original statement is preserved. */
+
+void
+bsi_replace (const block_stmt_iterator *bsi, tree stmt, bool preserve_eh_info)
+{
+ int eh_region;
+ tree orig_stmt = bsi_stmt (*bsi);
+
+ SET_EXPR_LOCUS (stmt, EXPR_LOCUS (orig_stmt));
+ set_bb_for_stmt (stmt, bsi->bb);
+
+ /* Preserve EH region information from the original statement, if
+ requested by the caller. */
+ if (preserve_eh_info)
+ {
+ eh_region = lookup_stmt_eh_region (orig_stmt);
+ if (eh_region >= 0)
+ add_stmt_to_eh_region (stmt, eh_region);
+ }
+
+ *bsi_stmt_ptr (*bsi) = stmt;
+ modify_stmt (stmt);
+}
+
+
+/* Insert the statement pointed-to by BSI into edge E. Every attempt
+ is made to place the statement in an existing basic block, but
+ sometimes that isn't possible. When it isn't possible, the edge is
+ split and the statement is added to the new block.
+
+ In all cases, the returned *BSI points to the correct location. The
+ return value is true if insertion should be done after the location,
+ or false if it should be done before the location. */
+
+static bool
+tree_find_edge_insert_loc (edge e, block_stmt_iterator *bsi)
+{
+ basic_block dest, src;
+ tree tmp;
+
+ dest = e->dest;
+ restart:
+
+ /* If the destination has one predecessor which has no PHI nodes,
+ insert there. Except for the exit block.
+
+ The requirement for no PHI nodes could be relaxed. Basically we
+ would have to examine the PHIs to prove that none of them used
+ the value set by the statement we want to insert on E. That
+ hardly seems worth the effort. */
+ if (dest->pred->pred_next == NULL
+ && ! phi_nodes (dest)
+ && dest != EXIT_BLOCK_PTR)
+ {
+ *bsi = bsi_start (dest);
+ if (bsi_end_p (*bsi))
+ return true;
+
+ /* Make sure we insert after any leading labels. */
+ tmp = bsi_stmt (*bsi);
+ while (TREE_CODE (tmp) == LABEL_EXPR)
+ {
+ bsi_next (bsi);
+ if (bsi_end_p (*bsi))
+ break;
+ tmp = bsi_stmt (*bsi);
+ }
+
+ if (bsi_end_p (*bsi))
+ {
+ *bsi = bsi_last (dest);
+ return true;
+ }
+ else
+ return false;
+ }
+
+ /* If the source has one successor, the edge is not abnormal and
+ the last statement does not end a basic block, insert there.
+ Except for the entry block. */
+ src = e->src;
+ if ((e->flags & EDGE_ABNORMAL) == 0
+ && src->succ->succ_next == NULL
+ && src != ENTRY_BLOCK_PTR)
+ {
+ *bsi = bsi_last (src);
+ if (bsi_end_p (*bsi))
+ return true;
+
+ tmp = bsi_stmt (*bsi);
+ if (!stmt_ends_bb_p (tmp))
+ return true;
+ }
+
+ /* Otherwise, create a new basic block, and split this edge. */
+ dest = split_edge (e);
+ e = dest->pred;
+ goto restart;
+}
+
+
+/* This routine will commit all pending edge insertions, creating any new
+ basic blocks which are necessary.
+
+ If specified, NEW_BLOCKS returns a count of the number of new basic
+ blocks which were created. */
+
+void
+bsi_commit_edge_inserts (int *new_blocks)
+{
+ basic_block bb;
+ edge e;
+ int blocks;
+
+ blocks = n_basic_blocks;
+
+ bsi_commit_edge_inserts_1 (ENTRY_BLOCK_PTR->succ);
+
+ FOR_EACH_BB (bb)
+ for (e = bb->succ; e; e = e->succ_next)
+ bsi_commit_edge_inserts_1 (e);
+
+ if (new_blocks)
+ *new_blocks = n_basic_blocks - blocks;
+}
+
+
+/* Commit insertions pending at edge E. */
+
+static void
+bsi_commit_edge_inserts_1 (edge e)
+{
+ if (PENDING_STMT (e))
+ {
+ block_stmt_iterator bsi;
+ tree stmt = PENDING_STMT (e);
+
+ PENDING_STMT (e) = NULL_TREE;
+
+ if (tree_find_edge_insert_loc (e, &bsi))
+ bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
+ else
+ bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
+ }
+}
+
+
+/* Add STMT to the pending list of edge E. No actual insertion is
+ made until a call to bsi_commit_edge_inserts () is made. */
+
+void
+bsi_insert_on_edge (edge e, tree stmt)
+{
+ append_to_statement_list (stmt, &PENDING_STMT (e));
+}
+
+
+/* Specialized edge insertion for SSA-PRE. FIXME: This should
+ probably disappear. The only reason it's here is because PRE needs
+ the call to tree_find_edge_insert_loc(). */
+
+void pre_insert_on_edge (edge e, tree stmt);
+
+void
+pre_insert_on_edge (edge e, tree stmt)
+{
+ block_stmt_iterator bsi;
+
+ if (PENDING_STMT (e))
+ abort ();
+
+ if (tree_find_edge_insert_loc (e, &bsi))
+ bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
+ else
+ bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
+}
+
+
+/*---------------------------------------------------------------------------
+ Tree specific functions for CFG manipulation
+---------------------------------------------------------------------------*/
+
+/* Split a (typically critical) edge EDGE_IN. Return the new block.
+ Abort on abnormal edges. */
+
+static basic_block
+tree_split_edge (edge edge_in)
+{
+ basic_block new_bb, after_bb, dest, src;
+ edge new_edge, e;
+ tree phi;
+ int i, num_elem;
+
+ /* Abnormal edges cannot be split. */
+ if (edge_in->flags & EDGE_ABNORMAL)
+ abort ();
+
+ src = edge_in->src;
+ dest = edge_in->dest;
+
+ /* Place the new block in the block list. Try to keep the new block
+ near its "logical" location. This is of most help to humans looking
+ at debugging dumps. */
+ for (e = dest->pred; e; e = e->pred_next)
+ if (e->src->next_bb == dest)
+ break;
+ if (!e)
+ after_bb = dest->prev_bb;
+ else
+ after_bb = edge_in->src;
+
+ new_bb = create_empty_bb (after_bb);
+ new_edge = make_edge (new_bb, dest, EDGE_FALLTHRU);
+
+ /* Find all the PHI arguments on the original edge, and change them to
+ the new edge. Do it before redirection, so that the argument does not
+ get removed. */
+ for (phi = phi_nodes (dest); phi; phi = TREE_CHAIN (phi))
+ {
+ num_elem = PHI_NUM_ARGS (phi);
+ for (i = 0; i < num_elem; i++)
+ if (PHI_ARG_EDGE (phi, i) == edge_in)
+ {
+ PHI_ARG_EDGE (phi, i) = new_edge;
+ break;
+ }
+ }
+
+ if (!redirect_edge_and_branch (edge_in, new_bb))
+ abort ();
+
+ if (PENDING_STMT (edge_in))
+ abort ();
+
+ return new_bb;
+}
+
+
+/* Return true when BB has label LABEL in it. */
+
+static bool
+has_label_p (basic_block bb, tree label)
+{
+ block_stmt_iterator bsi;
+
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ tree stmt = bsi_stmt (bsi);
+
+ if (TREE_CODE (stmt) != LABEL_EXPR)
+ return false;
+ if (LABEL_EXPR_LABEL (stmt) == label)
+ return true;
+ }
+ return false;
+}
+
+
+/* Callback for walk_tree, check that all elements with address taken are
+ properly noticed as such. */
+
+static tree
+verify_expr (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
+{
+ tree t = *tp, x;
+
+ if (TYPE_P (t))
+ *walk_subtrees = 0;
+
+ switch (TREE_CODE (t))
+ {
+ case SSA_NAME:
+ if (SSA_NAME_IN_FREE_LIST (t))
+ {
+ error ("SSA name in freelist but still referenced");
+ return *tp;
+ }
+ break;
+
+ case MODIFY_EXPR:
+ x = TREE_OPERAND (t, 0);
+ if (TREE_CODE (x) == BIT_FIELD_REF
+ && is_gimple_reg (TREE_OPERAND (x, 0)))
+ {
+ error ("GIMPLE register modified with BIT_FIELD_REF");
+ return *tp;
+ }
+ break;
+
+ case ADDR_EXPR:
+ x = TREE_OPERAND (t, 0);
+ while (TREE_CODE (x) == ARRAY_REF
+ || TREE_CODE (x) == COMPONENT_REF
+ || TREE_CODE (x) == REALPART_EXPR
+ || TREE_CODE (x) == IMAGPART_EXPR)
+ x = TREE_OPERAND (x, 0);
+ if (TREE_CODE (x) != VAR_DECL && TREE_CODE (x) != PARM_DECL)
+ return NULL;
+ if (!TREE_ADDRESSABLE (x))
+ {
+ error ("address taken, but ADDRESSABLE bit not set");
+ return x;
+ }
+ break;
+
+ case COND_EXPR:
+ x = TREE_OPERAND (t, 0);
+ if (TREE_CODE (TREE_TYPE (x)) != BOOLEAN_TYPE)
+ {
+ error ("non-boolean used in condition");
+ return x;
+ }
+ break;
+
+ case NOP_EXPR:
+ case CONVERT_EXPR:
+ case FIX_TRUNC_EXPR:
+ case FIX_CEIL_EXPR:
+ case FIX_FLOOR_EXPR:
+ case FIX_ROUND_EXPR:
+ case FLOAT_EXPR:
+ case NEGATE_EXPR:
+ case ABS_EXPR:
+ case BIT_NOT_EXPR:
+ case NON_LVALUE_EXPR:
+ case TRUTH_NOT_EXPR:
+ x = TREE_OPERAND (t, 0);
+ /* We check for constants explicitly since they are not considered
+ gimple invariants if they overflowed. */
+ if (TREE_CODE_CLASS (TREE_CODE (x)) != 'c'
+ && !is_gimple_val (x))
+ {
+ error ("Invalid operand to unary operator");
+ return x;
+ }
+ break;
+
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ break;
+
+ case LT_EXPR:
+ case LE_EXPR:
+ case GT_EXPR:
+ case GE_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ case UNORDERED_EXPR:
+ case ORDERED_EXPR:
+ case UNLT_EXPR:
+ case UNLE_EXPR:
+ case UNGT_EXPR:
+ case UNGE_EXPR:
+ case UNEQ_EXPR:
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case TRUNC_MOD_EXPR:
+ case CEIL_MOD_EXPR:
+ case FLOOR_MOD_EXPR:
+ case ROUND_MOD_EXPR:
+ case RDIV_EXPR:
+ case EXACT_DIV_EXPR:
+ case MIN_EXPR:
+ case MAX_EXPR:
+ case LSHIFT_EXPR:
+ case RSHIFT_EXPR:
+ case LROTATE_EXPR:
+ case RROTATE_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ case BIT_AND_EXPR:
+ x = TREE_OPERAND (t, 0);
+ /* We check for constants explicitly since they are not considered
+ gimple invariants if they overflowed. */
+ if (TREE_CODE_CLASS (TREE_CODE (x)) != 'c'
+ && !is_gimple_val (x))
+ {
+ error ("Invalid operand to binary operator");
+ return x;
+ }
+ x = TREE_OPERAND (t, 1);
+ /* We check for constants explicitly since they are not considered
+ gimple invariants if they overflowed. */
+ if (TREE_CODE_CLASS (TREE_CODE (x)) != 'c'
+ && !is_gimple_val (x))
+ {
+ error ("Invalid operand to binary operator");
+ return x;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return NULL;
+}
+
+
+/* Verify STMT, return true if STMT is not in GIMPLE form.
+ TODO: Implement type checking. */
+
+static bool
+verify_stmt (tree stmt)
+{
+ tree addr;
+
+ if (!is_gimple_stmt (stmt))
+ {
+ error ("Is not a valid GIMPLE statement.");
+ debug_generic_stmt (stmt);
+ return true;
+ }
+
+ addr = walk_tree (&stmt, verify_expr, NULL, NULL);
+ if (addr)
+ {
+ debug_generic_stmt (addr);
+ return true;
+ }
+
+ return false;
+}
+
+
+/* Return true when the T can be shared. */
+
+static bool
+tree_node_can_be_shared (tree t)
+{
+ if (TYPE_P (t) || DECL_P (t)
+ /* We check for constants explicitly since they are not considered
+ gimple invariants if they overflowed. */
+ || TREE_CODE_CLASS (TREE_CODE (t)) == 'c'
+ || is_gimple_min_invariant (t)
+ || TREE_CODE (t) == SSA_NAME)
+ return true;
+
+ while ((TREE_CODE (t) == ARRAY_REF
+ /* We check for constants explicitly since they are not considered
+ gimple invariants if they overflowed. */
+ && (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t, 1))) == 'c'
+ || is_gimple_min_invariant (TREE_OPERAND (t, 1))))
+ || (TREE_CODE (t) == COMPONENT_REF
+ || TREE_CODE (t) == REALPART_EXPR
+ || TREE_CODE (t) == IMAGPART_EXPR))
+ t = TREE_OPERAND (t, 0);
+
+ if (DECL_P (t))
+ return true;
+
+ return false;
+}
+
+
+/* Called via walk_trees. Verify tree sharing. */
+
+static tree
+verify_node_sharing (tree * tp, int *walk_subtrees, void *data)
+{
+ htab_t htab = (htab_t) data;
+ void **slot;
+
+ if (tree_node_can_be_shared (*tp))
+ {
+ *walk_subtrees = false;
+ return NULL;
+ }
+
+ slot = htab_find_slot (htab, *tp, INSERT);
+ if (*slot)
+ return *slot;
+ *slot = *tp;
+
+ return NULL;
+}
+
+
+/* Verify the GIMPLE statement chain. */
+
+void
+verify_stmts (void)
+{
+ basic_block bb;
+ block_stmt_iterator bsi;
+ bool err = false;
+ htab_t htab;
+ tree addr;
+
+ timevar_push (TV_TREE_STMT_VERIFY);
+ htab = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL);
+
+ FOR_EACH_BB (bb)
+ {
+ tree phi;
+ int i;
+
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ int phi_num_args = PHI_NUM_ARGS (phi);
+
+ for (i = 0; i < phi_num_args; i++)
+ {
+ tree t = PHI_ARG_DEF (phi, i);
+ tree addr;
+
+ /* Addressable variables do have SSA_NAMEs but they
+ are not considered gimple values. */
+ if (TREE_CODE (t) != SSA_NAME
+ && TREE_CODE (t) != FUNCTION_DECL
+ && !is_gimple_val (t))
+ {
+ error ("PHI def is not a GIMPLE value");
+ debug_generic_stmt (phi);
+ debug_generic_stmt (t);
+ err |= true;
+ }
+
+ addr = walk_tree (&t, verify_expr, NULL, NULL);
+ if (addr)
+ {
+ debug_generic_stmt (addr);
+ err |= true;
+ }
+
+ addr = walk_tree (&t, verify_node_sharing, htab, NULL);
+ if (addr)
+ {
+ error ("Incorrect sharing of tree nodes");
+ debug_generic_stmt (phi);
+ debug_generic_stmt (addr);
+ err |= true;
+ }
+ }
+ }
+
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ tree stmt = bsi_stmt (bsi);
+ err |= verify_stmt (stmt);
+ addr = walk_tree (&stmt, verify_node_sharing, htab, NULL);
+ if (addr)
+ {
+ error ("Incorrect sharing of tree nodes");
+ debug_generic_stmt (stmt);
+ debug_generic_stmt (addr);
+ err |= true;
+ }
+ }
+ }
+
+ if (err)
+ internal_error ("verify_stmts failed.");
+
+ htab_delete (htab);
+ timevar_pop (TV_TREE_STMT_VERIFY);
+}
+
+
+/* Verifies that the flow information is OK. */
+
+static int
+tree_verify_flow_info (void)
+{
+ int err = 0;
+ basic_block bb;
+ block_stmt_iterator bsi;
+ tree stmt;
+ edge e;
+
+ if (ENTRY_BLOCK_PTR->stmt_list)
+ {
+ error ("ENTRY_BLOCK has a statement list associated with it\n");
+ err = 1;
+ }
+
+ if (EXIT_BLOCK_PTR->stmt_list)
+ {
+ error ("EXIT_BLOCK has a statement list associated with it\n");
+ err = 1;
+ }
+
+ for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
+ if (e->flags & EDGE_FALLTHRU)
+ {
+ error ("Fallthru to exit from bb %d\n", e->src->index);
+ err = 1;
+ }
+
+ FOR_EACH_BB (bb)
+ {
+ bool found_ctrl_stmt = false;
+
+ /* Skip labels on the start of basic block. */
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ if (TREE_CODE (bsi_stmt (bsi)) != LABEL_EXPR)
+ break;
+
+ if (label_to_block (LABEL_EXPR_LABEL (bsi_stmt (bsi))) != bb)
+ {
+ error ("Label %s to block does not match in bb %d\n",
+ IDENTIFIER_POINTER (DECL_NAME (bsi_stmt (bsi))),
+ bb->index);
+ err = 1;
+ }
+
+ if (decl_function_context (LABEL_EXPR_LABEL (bsi_stmt (bsi)))
+ != current_function_decl)
+ {
+ error ("Label %s has incorrect context in bb %d\n",
+ IDENTIFIER_POINTER (DECL_NAME (bsi_stmt (bsi))),
+ bb->index);
+ err = 1;
+ }
+ }
+
+ /* Verify that body of basic block BB is free of control flow. */
+ for (; !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ tree stmt = bsi_stmt (bsi);
+
+ if (found_ctrl_stmt)
+ {
+ error ("Control flow in the middle of basic block %d\n",
+ bb->index);
+ err = 1;
+ }
+
+ if (stmt_ends_bb_p (stmt))
+ found_ctrl_stmt = true;
+
+ if (TREE_CODE (stmt) == LABEL_EXPR)
+ {
+ error ("Label %s in the middle of basic block %d\n",
+ IDENTIFIER_POINTER (DECL_NAME (stmt)),
+ bb->index);
+ err = 1;
+ }
+ }
+ bsi = bsi_last (bb);
+ if (bsi_end_p (bsi))
+ continue;
+
+ stmt = bsi_stmt (bsi);
+
+ if (is_ctrl_stmt (stmt))
+ {
+ for (e = bb->succ; e; e = e->succ_next)
+ if (e->flags & EDGE_FALLTHRU)
+ {
+ error ("Fallthru edge after a control statement in bb %d \n",
+ bb->index);
+ err = 1;
+ }
+ }
+
+ switch (TREE_CODE (stmt))
+ {
+ case COND_EXPR:
+ {
+ edge true_edge;
+ edge false_edge;
+ if (TREE_CODE (COND_EXPR_THEN (stmt)) != GOTO_EXPR
+ || TREE_CODE (COND_EXPR_ELSE (stmt)) != GOTO_EXPR)
+ {
+ error ("Structured COND_EXPR at the end of bb %d\n", bb->index);
+ err = 1;
+ }
+
+ extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
+
+ if (!true_edge || !false_edge
+ || !(true_edge->flags & EDGE_TRUE_VALUE)
+ || !(false_edge->flags & EDGE_FALSE_VALUE)
+ || (true_edge->flags & (EDGE_FALLTHRU | EDGE_ABNORMAL))
+ || (false_edge->flags & (EDGE_FALLTHRU | EDGE_ABNORMAL))
+ || bb->succ->succ_next->succ_next)
+ {
+ error ("Wrong outgoing edge flags at end of bb %d\n",
+ bb->index);
+ err = 1;
+ }
+
+ if (!has_label_p (true_edge->dest,
+ GOTO_DESTINATION (COND_EXPR_THEN (stmt))))
+ {
+ error ("`then' label does not match edge at end of bb %d\n",
+ bb->index);
+ err = 1;
+ }
+
+ if (!has_label_p (false_edge->dest,
+ GOTO_DESTINATION (COND_EXPR_ELSE (stmt))))
+ {
+ error ("`else' label does not match edge at end of bb %d\n",
+ bb->index);
+ err = 1;
+ }
+ }
+ break;
+
+ case GOTO_EXPR:
+ if (simple_goto_p (stmt))
+ {
+ error ("Explicit goto at end of bb %d\n", bb->index);
+ err = 1;
+ }
+ else
+ {
+ /* FIXME. We should double check that the labels in the
+ destination blocks have their address taken. */
+ for (e = bb->succ; e; e = e->succ_next)
+ if ((e->flags & (EDGE_FALLTHRU | EDGE_TRUE_VALUE
+ | EDGE_FALSE_VALUE))
+ || !(e->flags & EDGE_ABNORMAL))
+ {
+ error ("Wrong outgoing edge flags at end of bb %d\n",
+ bb->index);
+ err = 1;
+ }
+ }
+ break;
+
+ case RETURN_EXPR:
+ if (!bb->succ || bb->succ->succ_next
+ || (bb->succ->flags & (EDGE_FALLTHRU | EDGE_ABNORMAL
+ | EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
+ {
+ error ("Wrong outgoing edge flags at end of bb %d\n", bb->index);
+ err = 1;
+ }
+ if (bb->succ->dest != EXIT_BLOCK_PTR)
+ {
+ error ("Return edge does not point to exit in bb %d\n",
+ bb->index);
+ err = 1;
+ }
+ break;
+
+ case SWITCH_EXPR:
+ {
+ edge e;
+ size_t i, n;
+ tree vec;
+
+ vec = SWITCH_LABELS (stmt);
+ n = TREE_VEC_LENGTH (vec);
+
+ /* Mark all the destination basic blocks. */
+ for (i = 0; i < n; ++i)
+ {
+ tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
+ basic_block label_bb = label_to_block (lab);
+
+ if (label_bb->aux && label_bb->aux != (void *)1)
+ abort ();
+ label_bb->aux = (void *)1;
+ }
+
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ if (!e->dest->aux)
+ {
+ error ("Extra outgoing edge %d->%d\n",
+ bb->index, e->dest->index);
+ err = 1;
+ }
+ e->dest->aux = (void *)2;
+ if ((e->flags & (EDGE_FALLTHRU | EDGE_ABNORMAL
+ | EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
+ {
+ error ("Wrong outgoing edge flags at end of bb %d\n",
+ bb->index);
+ err = 1;
+ }
+ }
+
+ /* Check that we have all of them. */
+ for (i = 0; i < n; ++i)
+ {
+ tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
+ basic_block label_bb = label_to_block (lab);
+
+ if (label_bb->aux != (void *)2)
+ {
+ error ("Missing edge %i->%i\n",
+ bb->index, label_bb->index);
+ err = 1;
+ }
+ }
+
+ for (e = bb->succ; e; e = e->succ_next)
+ e->dest->aux = (void *)0;
+ }
+
+ default: ;
+ }
+ }
+
+ if (dom_computed[CDI_DOMINATORS] >= DOM_NO_FAST_QUERY)
+ verify_dominators (CDI_DOMINATORS);
+
+ return err;
+}
+
+
+/* Updates phi nodes after creating forwarder block joined
+ by edge FALLTHRU. */
+
+static void
+tree_make_forwarder_block (edge fallthru)
+{
+ edge e;
+ basic_block dummy, bb;
+ tree phi, new_phi, var;
+
+ dummy = fallthru->src;
+ bb = fallthru->dest;
+
+ if (!bb->pred->pred_next)
+ return;
+
+ /* If we redirected a branch we must create new phi nodes at the
+ start of BB. */
+ for (phi = phi_nodes (dummy); phi; phi = TREE_CHAIN (phi))
+ {
+ var = PHI_RESULT (phi);
+ new_phi = create_phi_node (var, bb);
+ SSA_NAME_DEF_STMT (var) = new_phi;
+ PHI_RESULT (phi) = make_ssa_name (SSA_NAME_VAR (var), phi);
+ add_phi_arg (&new_phi, PHI_RESULT (phi), fallthru);
+ }
+
+ /* Ensure that the PHI node chains are in the same order. */
+ set_phi_nodes (bb, nreverse (phi_nodes (bb)));
+
+ /* Add the arguments we have stored on edges. */
+ for (e = bb->pred; e; e = e->pred_next)
+ {
+ if (e == fallthru)
+ continue;
+
+ for (phi = phi_nodes (bb), var = PENDING_STMT (e);
+ phi;
+ phi = TREE_CHAIN (phi), var = TREE_CHAIN (var))
+ add_phi_arg (&phi, TREE_VALUE (var), e);
+
+ PENDING_STMT (e) = NULL;
+ }
+}
+
+
+/* Return true if basic block BB does nothing except pass control
+ flow to another block and that we can safely insert a label at
+ the start of the successor block. */
+
+static bool
+tree_forwarder_block_p (basic_block bb)
+{
+ block_stmt_iterator bsi;
+ edge e;
+
+ /* If we have already determined that this block is not forwardable,
+ then no further checks are necessary. */
+ if (! bb_ann (bb)->forwardable)
+ return false;
+
+ /* BB must have a single outgoing normal edge. Otherwise it can not be
+ a forwarder block. */
+ if (!bb->succ
+ || bb->succ->succ_next
+ || bb->succ->dest == EXIT_BLOCK_PTR
+ || (bb->succ->flags & EDGE_ABNORMAL)
+ || bb == ENTRY_BLOCK_PTR)
+ {
+ bb_ann (bb)->forwardable = 0;
+ return false;
+ }
+
+ /* Successors of the entry block are not forwarders. */
+ for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
+ if (e->dest == bb)
+ {
+ bb_ann (bb)->forwardable = 0;
+ return false;
+ }
+
+ /* BB can not have any PHI nodes. This could potentially be relaxed
+ early in compilation if we re-rewrote the variables appearing in
+ any PHI nodes in forwarder blocks. */
+ if (phi_nodes (bb))
+ {
+ bb_ann (bb)->forwardable = 0;
+ return false;
+ }
+
+ /* Now walk through the statements. We can ignore labels, anything else
+ means this is not a forwarder block. */
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ tree stmt = bsi_stmt (bsi);
+
+ switch (TREE_CODE (stmt))
+ {
+ case LABEL_EXPR:
+ if (DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt)))
+ return false;
+ break;
+
+ default:
+ bb_ann (bb)->forwardable = 0;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+/* Thread jumps over empty statements.
+
+ This code should _not_ thread over obviously equivalent conditions
+ as that requires nontrivial updates to the SSA graph. */
+
+static bool
+thread_jumps (void)
+{
+ edge e, next, last, old;
+ basic_block bb, dest, tmp;
+ tree phi;
+ int arg;
+ bool retval = false;
+
+ FOR_EACH_BB (bb)
+ bb_ann (bb)->forwardable = 1;
+
+ FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
+ {
+ /* Don't waste time on unreachable blocks. */
+ if (!bb->pred)
+ continue;
+
+ /* Nor on forwarders. */
+ if (tree_forwarder_block_p (bb))
+ continue;
+
+ /* This block is now part of a forwarding path, mark it as not
+ forwardable so that we can detect loops. This bit will be
+ reset below. */
+ bb_ann (bb)->forwardable = 0;
+
+ /* Examine each of our block's successors to see if it is
+ forwardable. */
+ for (e = bb->succ; e; e = next)
+ {
+ next = e->succ_next;
+
+ /* If the edge is abnormal or its destination is not
+ forwardable, then there's nothing to do. */
+ if ((e->flags & EDGE_ABNORMAL)
+ || !tree_forwarder_block_p (e->dest))
+ continue;
+
+ /* Now walk through as many forwarder block as possible to
+ find the ultimate destination we want to thread our jump
+ to. */
+ last = e->dest->succ;
+ bb_ann (e->dest)->forwardable = 0;
+ for (dest = e->dest->succ->dest;
+ tree_forwarder_block_p (dest);
+ last = dest->succ,
+ dest = dest->succ->dest)
+ {
+ /* An infinite loop detected. We redirect the edge anyway, so
+ that the loop is shrinked into single basic block. */
+ if (!bb_ann (dest)->forwardable)
+ break;
+
+ if (dest->succ->dest == EXIT_BLOCK_PTR)
+ break;
+
+ bb_ann (dest)->forwardable = 0;
+ }
+
+ /* Reset the forwardable marks to 1. */
+ for (tmp = e->dest;
+ tmp != dest;
+ tmp = tmp->succ->dest)
+ bb_ann (tmp)->forwardable = 1;
+
+ if (dest == e->dest)
+ continue;
+
+ old = find_edge (bb, dest);
+ if (old)
+ {
+ /* If there already is an edge, check whether the values
+ in phi nodes differ. */
+ if (!phi_alternatives_equal (dest, last, old))
+ {
+ /* The previous block is forwarder. Redirect our jump
+ to that target instead since we know it has no PHI
+ nodes that will need updating. */
+ dest = last->src;
+
+ /* That might mean that no forwarding at all is possible. */
+ if (dest == e->dest)
+ continue;
+
+ old = find_edge (bb, dest);
+ }
+ }
+
+ /* Perform the redirection. */
+ retval = true;
+ e = redirect_edge_and_branch (e, dest);
+
+ /* TODO -- updating dominators in this case is simple. */
+ free_dominance_info (CDI_DOMINATORS);
+
+ if (!old)
+ {
+ /* Update PHI nodes. We know that the new argument should
+ have the same value as the argument associated with LAST.
+ Otherwise we would have changed our target block above. */
+ for (phi = phi_nodes (dest); phi; phi = TREE_CHAIN (phi))
+ {
+ arg = phi_arg_from_edge (phi, last);
+ if (arg < 0)
+ abort ();
+ add_phi_arg (&phi, PHI_ARG_DEF (phi, arg), e);
+ }
+ }
+ }
+
+ /* Reset the forwardable bit on our block since it's no longer in
+ a forwarding chain path. */
+ bb_ann (bb)->forwardable = 1;
+ }
+
+ return retval;
+}
+
+
+/* Return a non-special label in the head of basic block BLOCK.
+ Create one if it doesn't exist. */
+
+static tree
+tree_block_label (basic_block bb)
+{
+ block_stmt_iterator i, s = bsi_start (bb);
+ bool first = true;
+ tree label, stmt;
+
+ for (i = s; !bsi_end_p (i); first = false, bsi_next (&i))
+ {
+ stmt = bsi_stmt (i);
+ if (TREE_CODE (stmt) != LABEL_EXPR)
+ break;
+ label = LABEL_EXPR_LABEL (stmt);
+ if (!DECL_NONLOCAL (label))
+ {
+ if (!first)
+ bsi_move_before (&i, &s);
+ return label;
+ }
+ }
+
+ label = create_artificial_label ();
+ stmt = build1 (LABEL_EXPR, void_type_node, label);
+ bsi_insert_before (&s, stmt, BSI_NEW_STMT);
+ return label;
+}
+
+
+/* Attempt to perform edge redirection by replacing a possibly complex
+ jump instruction by a goto or by removing the jump completely.
+ This can apply only if all edges now point to the same block. The
+ parameters and return values are equivalent to
+ redirect_edge_and_branch. */
+
+static edge
+tree_try_redirect_by_replacing_jump (edge e, basic_block target)
+{
+ basic_block src = e->src;
+ edge tmp;
+ block_stmt_iterator b;
+ tree stmt;
+
+ /* Verify that all targets will be TARGET. */
+ for (tmp = src->succ; tmp; tmp = tmp->succ_next)
+ if (tmp->dest != target && tmp != e)
+ break;
+
+ if (tmp)
+ return NULL;
+
+ b = bsi_last (src);
+ if (bsi_end_p (b))
+ return NULL;
+ stmt = bsi_stmt (b);
+
+ if (TREE_CODE (stmt) == COND_EXPR
+ || TREE_CODE (stmt) == SWITCH_EXPR)
+ {
+ bsi_remove (&b);
+ e = ssa_redirect_edge (e, target);
+ e->flags = EDGE_FALLTHRU;
+ return e;
+ }
+
+ return NULL;
+}
+
+
+/* Redirect E to DEST. Return NULL on failure. Otherwise, return the
+ edge representing the redirected branch. */
+
+static edge
+tree_redirect_edge_and_branch (edge e, basic_block dest)
+{
+ basic_block bb = e->src;
+ block_stmt_iterator bsi;
+ edge ret;
+ tree label, stmt;
+
+ if (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH))
+ return NULL;
+
+ if (e->src != ENTRY_BLOCK_PTR
+ && (ret = tree_try_redirect_by_replacing_jump (e, dest)))
+ return ret;
+
+ if (e->dest == dest)
+ return NULL;
+
+ label = tree_block_label (dest);
+
+ bsi = bsi_last (bb);
+ stmt = bsi_end_p (bsi) ? NULL : bsi_stmt (bsi);
+
+ switch (stmt ? TREE_CODE (stmt) : ERROR_MARK)
+ {
+ case COND_EXPR:
+ stmt = (e->flags & EDGE_TRUE_VALUE
+ ? COND_EXPR_THEN (stmt)
+ : COND_EXPR_ELSE (stmt));
+ GOTO_DESTINATION (stmt) = label;
+ break;
+
+ case GOTO_EXPR:
+ /* No non-abnormal edges should lead from a non-simple goto, and
+ simple ones should be represented implicitly. */
+ abort ();
+
+ case SWITCH_EXPR:
+ {
+ tree vec = SWITCH_LABELS (stmt);
+ size_t i, n = TREE_VEC_LENGTH (vec);
+
+ for (i = 0; i < n; ++i)
+ {
+ tree elt = TREE_VEC_ELT (vec, i);
+ if (label_to_block (CASE_LABEL (elt)) == e->dest)
+ CASE_LABEL (elt) = label;
+ }
+ }
+ break;
+
+ case RETURN_EXPR:
+ bsi_remove (&bsi);
+ e->flags |= EDGE_FALLTHRU;
+ break;
+
+ default:
+ /* Otherwise it must be a fallthru edge, and we don't need to
+ do anything besides redirecting it. */
+ if (!(e->flags & EDGE_FALLTHRU))
+ abort ();
+ break;
+ }
+
+ /* Update/insert PHI nodes as necessary. */
+
+ /* Now update the edges in the CFG. */
+ e = ssa_redirect_edge (e, dest);
+
+ return e;
+}
+
+
+/* Simple wrapper, as we can always redirect fallthru edges. */
+
+static basic_block
+tree_redirect_edge_and_branch_force (edge e, basic_block dest)
+{
+ e = tree_redirect_edge_and_branch (e, dest);
+ if (!e)
+ abort ();
+
+ return NULL;
+}
+
+
+/* Splits basic block BB after statement STMT (but at least after the
+ labels). If STMT is NULL, BB is split just after the labels. */
+
+static basic_block
+tree_split_block (basic_block bb, void *stmt)
+{
+ block_stmt_iterator bsi, bsi_tgt;
+ tree act;
+ basic_block new_bb;
+ edge e;
+
+ new_bb = create_empty_bb (bb);
+
+ /* Redirect the outgoing edges. */
+ new_bb->succ = bb->succ;
+ bb->succ = NULL;
+ for (e = new_bb->succ; e; e = e->succ_next)
+ e->src = new_bb;
+
+ if (stmt && TREE_CODE ((tree) stmt) == LABEL_EXPR)
+ stmt = NULL;
+
+ /* Move everything from BSI to the new basic block. */
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ act = bsi_stmt (bsi);
+ if (TREE_CODE (act) == LABEL_EXPR)
+ continue;
+
+ if (!stmt)
+ break;
+
+ if (stmt == act)
+ {
+ bsi_next (&bsi);
+ break;
+ }
+ }
+
+ bsi_tgt = bsi_start (new_bb);
+ while (!bsi_end_p (bsi))
+ {
+ act = bsi_stmt (bsi);
+ bsi_remove (&bsi);
+ bsi_insert_after (&bsi_tgt, act, BSI_NEW_STMT);
+ }
+
+ return new_bb;
+}
+
+
+/* Moves basic block BB after block AFTER. */
+
+static bool
+tree_move_block_after (basic_block bb, basic_block after)
+{
+ if (bb->prev_bb == after)
+ return true;
+
+ unlink_block (bb);
+ link_block (bb, after);
+
+ return true;
+}
+
+
+/* Return true if basic_block can be duplicated. */
+
+static bool
+tree_can_duplicate_bb_p (basic_block bb ATTRIBUTE_UNUSED)
+{
+ return true;
+}
+
+
+/* Create a duplicate of the basic block BB. NOTE: This does not
+ preserve SSA form. */
+
+static basic_block
+tree_duplicate_bb (basic_block bb)
+{
+ basic_block new_bb;
+ block_stmt_iterator bsi, bsi_tgt;
+
+ new_bb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
+ bsi_tgt = bsi_start (new_bb);
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ tree stmt = bsi_stmt (bsi);
+
+ if (TREE_CODE (stmt) == LABEL_EXPR)
+ continue;
+
+ bsi_insert_after (&bsi_tgt, unshare_expr (stmt), BSI_NEW_STMT);
+ }
+
+ return new_bb;
+}
+
+
+/* Dump FUNCTION_DECL FN to file FILE using FLAGS (see TDF_* in tree.h) */
+
+void
+dump_function_to_file (tree fn, FILE *file, int flags)
+{
+ tree arg, vars, var;
+ bool ignore_topmost_bind = false, any_var = false;
+ basic_block bb;
+ tree chain;
+
+ fprintf (file, "%s (", (*lang_hooks.decl_printable_name) (fn, 2));
+
+ arg = DECL_ARGUMENTS (fn);
+ while (arg)
+ {
+ print_generic_expr (file, arg, dump_flags);
+ if (TREE_CHAIN (arg))
+ fprintf (file, ", ");
+ arg = TREE_CHAIN (arg);
+ }
+ fprintf (file, ")\n");
+
+ if (flags & TDF_RAW)
+ {
+ dump_node (fn, TDF_SLIM | flags, file);
+ return;
+ }
+
+ /* When GIMPLE is lowered, the variables are no longer available in
+ BIND_EXPRs, so display them separately. */
+ if (cfun && cfun->unexpanded_var_list)
+ {
+ ignore_topmost_bind = true;
+
+ fprintf (file, "{\n");
+ for (vars = cfun->unexpanded_var_list; vars; vars = TREE_CHAIN (vars))
+ {
+ var = TREE_VALUE (vars);
+
+ print_generic_decl (file, var, flags);
+ fprintf (file, "\n");
+
+ any_var = true;
+ }
+ }
+
+ if (basic_block_info)
+ {
+ /* Make a CFG based dump. */
+ if (!ignore_topmost_bind)
+ fprintf (file, "{\n");
+
+ if (any_var && n_basic_blocks)
+ fprintf (file, "\n");
+
+ FOR_EACH_BB (bb)
+ dump_generic_bb (file, bb, 2, flags);
+
+ fprintf (file, "}\n");
+ }
+ else
+ {
+ int indent;
+
+ /* Make a tree based dump. */
+ chain = DECL_SAVED_TREE (fn);
+
+ if (TREE_CODE (chain) == BIND_EXPR)
+ {
+ if (ignore_topmost_bind)
+ {
+ chain = BIND_EXPR_BODY (chain);
+ indent = 2;
+ }
+ else
+ indent = 0;
+ }
+ else
+ {
+ if (!ignore_topmost_bind)
+ fprintf (file, "{\n");
+ indent = 2;
+ }
+
+ if (any_var)
+ fprintf (file, "\n");
+
+ print_generic_stmt_indented (file, chain, flags, indent);
+ if (ignore_topmost_bind)
+ fprintf (file, "}\n");
+ }
+
+ fprintf (file, "\n\n");
+}
+
+
+/* Pretty print of the loops intermediate representation. */
+static void print_loop (FILE *, struct loop *, int);
+static void print_pred_bbs (FILE *, edge);
+static void print_succ_bbs (FILE *, edge);
+
+
+/* Print the predecessors indexes of edge E on FILE. */
+
+static void
+print_pred_bbs (FILE *file, edge e)
+{
+ if (e == NULL)
+ return;
+
+ else if (e->pred_next == NULL)
+ fprintf (file, "bb_%d", e->src->index);
+
+ else
+ {
+ fprintf (file, "bb_%d, ", e->src->index);
+ print_pred_bbs (file, e->pred_next);
+ }
+}
+
+
+/* Print the successors indexes of edge E on FILE. */
+
+static void
+print_succ_bbs (FILE *file, edge e)
+{
+ if (e == NULL)
+ return;
+ else if (e->succ_next == NULL)
+ fprintf (file, "bb_%d", e->dest->index);
+ else
+ {
+ fprintf (file, "bb_%d, ", e->dest->index);
+ print_succ_bbs (file, e->succ_next);
+ }
+}
+
+
+/* Pretty print LOOP on FILE, indented INDENT spaces. */
+
+static void
+print_loop (FILE *file, struct loop *loop, int indent)
+{
+ char *s_indent;
+ basic_block bb;
+
+ if (loop == NULL)
+ return;
+
+ s_indent = (char *) alloca ((size_t) indent + 1);
+ memset ((void *) s_indent, ' ', (size_t) indent);
+ s_indent[indent] = '\0';
+
+ /* Print the loop's header. */
+ fprintf (file, "%sloop_%d\n", s_indent, loop->num);
+
+ /* Print the loop's body. */
+ fprintf (file, "%s{\n", s_indent);
+ FOR_EACH_BB (bb)
+ if (bb->loop_father == loop)
+ {
+ /* Print the basic_block's header. */
+ fprintf (file, "%s bb_%d (preds = {", s_indent, bb->index);
+ print_pred_bbs (file, bb->pred);
+ fprintf (file, "}, succs = {");
+ print_succ_bbs (file, bb->succ);
+ fprintf (file, "})\n");
+
+ /* Print the basic_block's body. */
+ fprintf (file, "%s {\n", s_indent);
+ tree_dump_bb (bb, file, indent + 4);
+ fprintf (file, "%s }\n", s_indent);
+ }
+
+ print_loop (file, loop->inner, indent + 2);
+ fprintf (file, "%s}\n", s_indent);
+ print_loop (file, loop->next, indent);
+}
+
+
+/* Follow a CFG edge from the entry point of the program, and on entry
+ of a loop, pretty print the loop structure on FILE. */
+
+void
+print_loop_ir (FILE *file)
+{
+ basic_block bb;
+
+ bb = BASIC_BLOCK (0);
+ if (bb && bb->loop_father)
+ print_loop (file, bb->loop_father, 0);
+}
+
+
+/* Debugging loops structure at tree level. */
+
+void
+debug_loop_ir (void)
+{
+ print_loop_ir (stderr);
+}
+
+
+/* Return true if BB ends with a call, possibly followed by some
+ instructions that must stay with the call. Return false,
+ otherwise. */
+
+static bool
+tree_block_ends_with_call_p (basic_block bb)
+{
+ block_stmt_iterator bsi = bsi_last (bb);
+ tree t = tsi_stmt (bsi.tsi);
+
+ if (TREE_CODE (t) == RETURN_EXPR && TREE_OPERAND (t, 0))
+ t = TREE_OPERAND (t, 0);
+
+ if (TREE_CODE (t) == MODIFY_EXPR)
+ t = TREE_OPERAND (t, 1);
+
+ return TREE_CODE (t) == CALL_EXPR;
+}
+
+
+/* Return true if BB ends with a conditional branch. Return false,
+ otherwise. */
+
+static bool
+tree_block_ends_with_condjump_p (basic_block bb)
+{
+ tree stmt = tsi_stmt (bsi_last (bb).tsi);
+ return (TREE_CODE (stmt) == COND_EXPR);
+}
+
+
+/* Return true if we need to add fake edge to exit at statement T.
+ Helper function for tree_flow_call_edges_add. */
+
+static bool
+need_fake_edge_p (tree t)
+{
+ if (TREE_CODE (t) == RETURN_EXPR && TREE_OPERAND (t, 0))
+ t = TREE_OPERAND (t, 0);
+
+ if (TREE_CODE (t) == MODIFY_EXPR)
+ t = TREE_OPERAND (t, 1);
+
+ /* NORETURN and LONGJMP calls already have an edge to exit.
+ CONST, PURE and ALWAYS_RETURN calls do not need one.
+ We don't currently check for CONST and PURE here, although
+ it would be a good idea, because those attributes are
+ figured out from the RTL in mark_constant_function, and
+ the counter incrementation code from -fprofile-arcs
+ leads to different results from -fbranch-probabilities. */
+ if (TREE_CODE (t) == CALL_EXPR
+ && !(call_expr_flags (t) &
+ (ECF_NORETURN | ECF_LONGJMP | ECF_ALWAYS_RETURN)))
+ return true;
+
+ if (TREE_CODE (t) == ASM_EXPR
+ && (ASM_VOLATILE_P (t) || ASM_INPUT_P (t)))
+ return true;
+
+ return false;
+}
+
+
+/* Add fake edges to the function exit for any non constant and non
+ noreturn calls, volatile inline assembly in the bitmap of blocks
+ specified by BLOCKS or to the whole CFG if BLOCKS is zero. Return
+ the number of blocks that were split.
+
+ The goal is to expose cases in which entering a basic block does
+ not imply that all subsequent instructions must be executed. */
+
+static int
+tree_flow_call_edges_add (sbitmap blocks)
+{
+ int i;
+ int blocks_split = 0;
+ int last_bb = last_basic_block;
+ bool check_last_block = false;
+
+ if (n_basic_blocks == 0)
+ return 0;
+
+ if (! blocks)
+ check_last_block = true;
+ else
+ check_last_block = TEST_BIT (blocks, EXIT_BLOCK_PTR->prev_bb->index);
+
+ /* In the last basic block, before epilogue generation, there will be
+ a fallthru edge to EXIT. Special care is required if the last insn
+ of the last basic block is a call because make_edge folds duplicate
+ edges, which would result in the fallthru edge also being marked
+ fake, which would result in the fallthru edge being removed by
+ remove_fake_edges, which would result in an invalid CFG.
+
+ Moreover, we can't elide the outgoing fake edge, since the block
+ profiler needs to take this into account in order to solve the minimal
+ spanning tree in the case that the call doesn't return.
+
+ Handle this by adding a dummy instruction in a new last basic block. */
+ if (check_last_block)
+ {
+ basic_block bb = EXIT_BLOCK_PTR->prev_bb;
+ block_stmt_iterator bsi = bsi_last (bb);
+ tree t = NULL_TREE;
+ if (!bsi_end_p (bsi))
+ t = bsi_stmt (bsi);
+
+ if (need_fake_edge_p (t))
+ {
+ edge e;
+
+ for (e = bb->succ; e; e = e->succ_next)
+ if (e->dest == EXIT_BLOCK_PTR)
+ {
+ bsi_insert_on_edge (e, build_empty_stmt ());
+ bsi_commit_edge_inserts ((int *)NULL);
+ break;
+ }
+ }
+ }
+
+ /* Now add fake edges to the function exit for any non constant
+ calls since there is no way that we can determine if they will
+ return or not... */
+ for (i = 0; i < last_bb; i++)
+ {
+ basic_block bb = BASIC_BLOCK (i);
+ block_stmt_iterator bsi;
+ tree stmt, last_stmt;
+
+ if (!bb)
+ continue;
+
+ if (blocks && !TEST_BIT (blocks, i))
+ continue;
+
+ bsi = bsi_last (bb);
+ if (!bsi_end_p (bsi))
+ {
+ last_stmt = bsi_stmt (bsi);
+ do
+ {
+ stmt = bsi_stmt (bsi);
+ if (need_fake_edge_p (stmt))
+ {
+ edge e;
+ /* The handling above of the final block before the
+ epilogue should be enough to verify that there is
+ no edge to the exit block in CFG already.
+ Calling make_edge in such case would cause us to
+ mark that edge as fake and remove it later. */
+#ifdef ENABLE_CHECKING
+ if (stmt == last_stmt)
+ for (e = bb->succ; e; e = e->succ_next)
+ if (e->dest == EXIT_BLOCK_PTR)
+ abort ();
+#endif
+
+ /* Note that the following may create a new basic block
+ and renumber the existing basic blocks. */
+ if (stmt != last_stmt)
+ {
+ e = split_block (bb, stmt);
+ if (e)
+ blocks_split++;
+ }
+ make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
+ }
+ bsi_prev (&bsi);
+ }
+ while (!bsi_end_p (bsi));
+ }
+ }
+
+ if (blocks_split)
+ verify_flow_info ();
+
+ return blocks_split;
+}
+
+
+struct cfg_hooks tree_cfg_hooks = {
+ "tree",
+ tree_verify_flow_info,
+ tree_dump_bb, /* dump_bb */
+ create_bb, /* create_basic_block */
+ tree_redirect_edge_and_branch,/* redirect_edge_and_branch */
+ tree_redirect_edge_and_branch_force,/* redirect_edge_and_branch_force */
+ remove_bb, /* delete_basic_block */
+ tree_split_block, /* split_block */
+ tree_move_block_after, /* move_block_after */
+ tree_can_merge_blocks_p, /* can_merge_blocks_p */
+ tree_merge_blocks, /* merge_blocks */
+ tree_predict_edge, /* predict_edge */
+ tree_predicted_by_p, /* predicted_by_p */
+ tree_can_duplicate_bb_p, /* can_duplicate_block_p */
+ tree_duplicate_bb, /* duplicate_block */
+ tree_split_edge, /* split_edge */
+ tree_make_forwarder_block, /* make_forward_block */
+ NULL, /* tidy_fallthru_edge */
+ tree_block_ends_with_call_p, /* block_ends_with_call_p */
+ tree_block_ends_with_condjump_p, /* block_ends_with_condjump_p */
+ tree_flow_call_edges_add /* flow_call_edges_add */
+};
+
+
+/* Split all critical edges. */
+
+static void
+split_critical_edges (void)
+{
+ basic_block bb;
+ edge e;
+
+ FOR_ALL_BB (bb)
+ {
+ for (e = bb->succ; e ; e = e->succ_next)
+ if (EDGE_CRITICAL_P (e) && !(e->flags & EDGE_ABNORMAL))
+ {
+ split_edge (e);
+ }
+ }
+}
+
+struct tree_opt_pass pass_split_crit_edges =
+{
+ NULL, /* name */
+ NULL, /* gate */
+ split_critical_edges, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_SPLIT_EDGES, /* tv_id */
+ PROP_cfg, /* properties required */
+ PROP_no_crit_edges, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+};
+
+/* Emit return warnings. */
+
+static void
+execute_warn_function_return (void)
+{
+ location_t *locus;
+ tree last;
+ edge e;
+
+ if (warn_missing_noreturn
+ && !TREE_THIS_VOLATILE (cfun->decl)
+ && EXIT_BLOCK_PTR->pred == NULL
+ && !lang_hooks.function.missing_noreturn_ok_p (cfun->decl))
+ warning ("%Jfunction might be possible candidate for attribute `noreturn'",
+ cfun->decl);
+
+ /* If we have a path to EXIT, then we do return. */
+ if (TREE_THIS_VOLATILE (cfun->decl)
+ && EXIT_BLOCK_PTR->pred != NULL)
+ {
+ locus = NULL;
+ for (e = EXIT_BLOCK_PTR->pred; e ; e = e->pred_next)
+ {
+ last = last_stmt (e->src);
+ if (TREE_CODE (last) == RETURN_EXPR
+ && (locus = EXPR_LOCUS (last)) != NULL)
+ break;
+ }
+ if (!locus)
+ locus = &cfun->function_end_locus;
+ warning ("%H`noreturn' function does return", locus);
+ }
+
+ /* If we see "return;" in some basic block, then we do reach the end
+ without returning a value. */
+ else if (warn_return_type
+ && EXIT_BLOCK_PTR->pred != NULL
+ && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (cfun->decl))))
+ {
+ for (e = EXIT_BLOCK_PTR->pred; e ; e = e->pred_next)
+ {
+ tree last = last_stmt (e->src);
+ if (TREE_CODE (last) == RETURN_EXPR
+ && TREE_OPERAND (last, 0) == NULL)
+ {
+ locus = EXPR_LOCUS (last);
+ if (!locus)
+ locus = &cfun->function_end_locus;
+ warning ("%Hcontrol reaches end of non-void function", locus);
+ break;
+ }
+ }
+ }
+}
+
+
+/* Given a basic block B which ends with a conditional and has
+ precisely two successors, determine which of the edges is taken if
+ the conditional is true and which is taken if the conditional is
+ false. Set TRUE_EDGE and FALSE_EDGE appropriately. */
+
+void
+extract_true_false_edges_from_block (basic_block b,
+ edge *true_edge,
+ edge *false_edge)
+{
+ edge e = b->succ;
+
+ if (e->flags & EDGE_TRUE_VALUE)
+ {
+ *true_edge = e;
+ *false_edge = e->succ_next;
+ }
+ else
+ {
+ *false_edge = e;
+ *true_edge = e->succ_next;
+ }
+}
+
+struct tree_opt_pass pass_warn_function_return =
+{
+ NULL, /* name */
+ NULL, /* gate */
+ execute_warn_function_return, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0 /* todo_flags_finish */
+};
+
+#include "gt-tree-cfg.h"
diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
new file mode 100644
index 00000000000..66fa6129c6d
--- /dev/null
+++ b/gcc/tree-complex.c
@@ -0,0 +1,561 @@
+/* Lower complex operations to scalar operations.
+ Copyright (C) 2004 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 2, or (at your option) any
+later version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "tm.h"
+#include "tree-flow.h"
+#include "tree-gimple.h"
+#include "tree-iterator.h"
+#include "tree-pass.h"
+#include "flags.h"
+
+
+/* Force EXP to be a gimple_val. */
+
+static tree
+gimplify_val (block_stmt_iterator *bsi, tree type, tree exp)
+{
+ tree t, new_stmt, orig_stmt;
+
+ if (is_gimple_val (exp))
+ return exp;
+
+ t = make_rename_temp (type, NULL);
+ new_stmt = build (MODIFY_EXPR, type, t, exp);
+
+ orig_stmt = bsi_stmt (*bsi);
+ SET_EXPR_LOCUS (new_stmt, EXPR_LOCUS (orig_stmt));
+ TREE_BLOCK (new_stmt) = TREE_BLOCK (orig_stmt);
+
+ bsi_insert_before (bsi, new_stmt, BSI_SAME_STMT);
+
+ return t;
+}
+
+/* Extract the real or imaginary part of a complex variable or constant.
+ Make sure that it's a proper gimple_val and gimplify it if not.
+ Emit any new code before BSI. */
+
+static tree
+extract_component (block_stmt_iterator *bsi, tree t, bool imagpart_p)
+{
+ tree ret, inner_type;
+
+ inner_type = TREE_TYPE (TREE_TYPE (t));
+ switch (TREE_CODE (t))
+ {
+ case COMPLEX_CST:
+ ret = (imagpart_p ? TREE_IMAGPART (t) : TREE_REALPART (t));
+ break;
+
+ case COMPLEX_EXPR:
+ ret = TREE_OPERAND (t, imagpart_p);
+ break;
+
+ case VAR_DECL:
+ case PARM_DECL:
+ ret = build1 ((imagpart_p ? IMAGPART_EXPR : REALPART_EXPR),
+ inner_type, t);
+ break;
+
+ default:
+ abort ();
+ }
+
+ return gimplify_val (bsi, inner_type, ret);
+}
+
+/* Build a binary operation and gimplify it. Emit code before BSI.
+ Return the gimple_val holding the result. */
+
+static tree
+do_binop (block_stmt_iterator *bsi, enum tree_code code,
+ tree type, tree a, tree b)
+{
+ tree ret;
+
+ ret = fold (build (code, type, a, b));
+ STRIP_NOPS (ret);
+
+ return gimplify_val (bsi, type, ret);
+}
+
+/* Build a unary operation and gimplify it. Emit code before BSI.
+ Return the gimple_val holding the result. */
+
+static tree
+do_unop (block_stmt_iterator *bsi, enum tree_code code, tree type, tree a)
+{
+ tree ret;
+
+ ret = fold (build1 (code, type, a));
+ STRIP_NOPS (ret);
+
+ return gimplify_val (bsi, type, ret);
+}
+
+/* Update an assignment to a complex variable in place. */
+
+static void
+update_complex_assignment (block_stmt_iterator *bsi, tree r, tree i)
+{
+ tree stmt = bsi_stmt (*bsi);
+ tree type;
+
+ modify_stmt (stmt);
+ if (TREE_CODE (stmt) == RETURN_EXPR)
+ stmt = TREE_OPERAND (stmt, 0);
+
+ type = TREE_TYPE (TREE_OPERAND (stmt, 1));
+ TREE_OPERAND (stmt, 1) = build (COMPLEX_EXPR, type, r, i);
+}
+
+/* Expand complex addition to scalars:
+ a + b = (ar + br) + i(ai + bi)
+ a - b = (ar - br) + i(ai + bi)
+*/
+
+static void
+expand_complex_addition (block_stmt_iterator *bsi, tree inner_type,
+ tree ar, tree ai, tree br, tree bi,
+ enum tree_code code)
+{
+ tree rr, ri;
+
+ rr = do_binop (bsi, code, inner_type, ar, br);
+ ri = do_binop (bsi, code, inner_type, ai, bi);
+
+ update_complex_assignment (bsi, rr, ri);
+}
+
+/* Expand complex multiplication to scalars:
+ a * b = (ar*br - ai*bi) + i(ar*bi + br*ai)
+*/
+
+static void
+expand_complex_multiplication (block_stmt_iterator *bsi, tree inner_type,
+ tree ar, tree ai, tree br, tree bi)
+{
+ tree t1, t2, t3, t4, rr, ri;
+
+ t1 = do_binop (bsi, MULT_EXPR, inner_type, ar, br);
+ t2 = do_binop (bsi, MULT_EXPR, inner_type, ai, bi);
+ t3 = do_binop (bsi, MULT_EXPR, inner_type, ar, bi);
+
+ /* Avoid expanding redundant multiplication for the common
+ case of squaring a complex number. */
+ if (ar == br && ai == bi)
+ t4 = t3;
+ else
+ t4 = do_binop (bsi, MULT_EXPR, inner_type, ai, br);
+
+ rr = do_binop (bsi, MINUS_EXPR, inner_type, t1, t2);
+ ri = do_binop (bsi, PLUS_EXPR, inner_type, t3, t4);
+
+ update_complex_assignment (bsi, rr, ri);
+}
+
+/* Expand complex division to scalars, straightforward algorithm.
+ a / b = ((ar*br + ai*bi)/t) + i((ai*br - ar*bi)/t)
+ t = br*br + bi*bi
+*/
+
+static void
+expand_complex_div_straight (block_stmt_iterator *bsi, tree inner_type,
+ tree ar, tree ai, tree br, tree bi,
+ enum tree_code code)
+{
+ tree rr, ri, div, t1, t2, t3;
+
+ t1 = do_binop (bsi, MULT_EXPR, inner_type, br, br);
+ t2 = do_binop (bsi, MULT_EXPR, inner_type, bi, bi);
+ div = do_binop (bsi, PLUS_EXPR, inner_type, t1, t2);
+
+ t1 = do_binop (bsi, MULT_EXPR, inner_type, ar, br);
+ t2 = do_binop (bsi, MULT_EXPR, inner_type, ai, bi);
+ t3 = do_binop (bsi, PLUS_EXPR, inner_type, t1, t2);
+ rr = do_binop (bsi, code, inner_type, t3, div);
+
+ t1 = do_binop (bsi, MULT_EXPR, inner_type, ai, br);
+ t2 = do_binop (bsi, MULT_EXPR, inner_type, ar, bi);
+ t3 = do_binop (bsi, MINUS_EXPR, inner_type, t1, t2);
+ ri = do_binop (bsi, code, inner_type, t3, div);
+
+ update_complex_assignment (bsi, rr, ri);
+}
+
+/* Expand complex division to scalars, modified algorithm to minimize
+ overflow with wide input ranges. */
+
+static void
+expand_complex_div_wide (block_stmt_iterator *bsi, tree inner_type,
+ tree ar, tree ai, tree br, tree bi,
+ enum tree_code code)
+{
+ tree rr, ri, ratio, div, t1, t2, min, max, cond;
+
+ /* Examine |br| < |bi|, and branch. */
+ t1 = do_unop (bsi, ABS_EXPR, inner_type, br);
+ t2 = do_unop (bsi, ABS_EXPR, inner_type, bi);
+ cond = fold (build (LT_EXPR, boolean_type_node, t1, t2));
+ STRIP_NOPS (cond);
+
+ if (TREE_CONSTANT (cond))
+ {
+ if (integer_zerop (cond))
+ min = bi, max = br;
+ else
+ min = br, max = bi;
+ }
+ else
+ {
+ basic_block bb_cond, bb_true, bb_false, bb_join;
+ tree l1, l2, l3;
+ edge e;
+
+ l1 = create_artificial_label ();
+ t1 = build (GOTO_EXPR, void_type_node, l1);
+ l2 = create_artificial_label ();
+ t2 = build (GOTO_EXPR, void_type_node, l2);
+ cond = build (COND_EXPR, void_type_node, cond, t1, t2);
+ bsi_insert_before (bsi, cond, BSI_SAME_STMT);
+
+ min = make_rename_temp (inner_type, NULL);
+ max = make_rename_temp (inner_type, NULL);
+ l3 = create_artificial_label ();
+
+ /* Split the original block, and create the TRUE and FALSE blocks. */
+ e = split_block (bsi->bb, cond);
+ bb_cond = e->src;
+ bb_join = e->dest;
+ bb_true = create_empty_bb (bb_cond);
+ bb_false = create_empty_bb (bb_true);
+
+ /* Wire the blocks together. */
+ e->flags = EDGE_TRUE_VALUE;
+ redirect_edge_succ (e, bb_true);
+ make_edge (bb_cond, bb_false, EDGE_FALSE_VALUE);
+ make_edge (bb_true, bb_join, 0);
+ make_edge (bb_false, bb_join, 0);
+
+ /* Update dominance info. Note that bb_join's data was
+ updated by split_block. */
+ if (dom_computed[CDI_DOMINATORS] >= DOM_CONS_OK)
+ {
+ set_immediate_dominator (CDI_DOMINATORS, bb_true, bb_cond);
+ set_immediate_dominator (CDI_DOMINATORS, bb_false, bb_cond);
+ }
+
+ /* Compute min and max for TRUE block. */
+ *bsi = bsi_start (bb_true);
+ t1 = build (LABEL_EXPR, void_type_node, l1);
+ bsi_insert_after (bsi, t1, BSI_NEW_STMT);
+ t1 = build (MODIFY_EXPR, inner_type, min, br);
+ bsi_insert_after (bsi, t1, BSI_NEW_STMT);
+ t1 = build (MODIFY_EXPR, inner_type, max, bi);
+ bsi_insert_after (bsi, t1, BSI_NEW_STMT);
+
+ /* Compute min and max for FALSE block. */
+ *bsi = bsi_start (bb_false);
+ t1 = build (LABEL_EXPR, void_type_node, l2);
+ bsi_insert_after (bsi, t1, BSI_NEW_STMT);
+ t1 = build (MODIFY_EXPR, inner_type, min, bi);
+ bsi_insert_after (bsi, t1, BSI_NEW_STMT);
+ t1 = build (MODIFY_EXPR, inner_type, max, br);
+ bsi_insert_after (bsi, t1, BSI_NEW_STMT);
+
+ /* Insert the join label into the tail of the original block. */
+ *bsi = bsi_start (bb_join);
+ t1 = build (LABEL_EXPR, void_type_node, l3);
+ bsi_insert_before (bsi, t1, BSI_SAME_STMT);
+ }
+
+ /* Now we have MIN(|br|, |bi|) and MAX(|br|, |bi|). We now use the
+ ratio min/max to scale both the dividend and divisor. */
+ ratio = do_binop (bsi, code, inner_type, min, max);
+
+ /* Calculate the divisor: min*ratio + max. */
+ t1 = do_binop (bsi, MULT_EXPR, inner_type, min, ratio);
+ div = do_binop (bsi, PLUS_EXPR, inner_type, t1, max);
+
+ /* Result is now ((ar + ai*ratio)/div) + i((ai - ar*ratio)/div). */
+ t1 = do_binop (bsi, MULT_EXPR, inner_type, ai, ratio);
+ t2 = do_binop (bsi, PLUS_EXPR, inner_type, ar, t1);
+ rr = do_binop (bsi, code, inner_type, t2, div);
+
+ t1 = do_binop (bsi, MULT_EXPR, inner_type, ar, ratio);
+ t2 = do_binop (bsi, MINUS_EXPR, inner_type, ai, t1);
+ ri = do_binop (bsi, code, inner_type, t2, div);
+
+ update_complex_assignment (bsi, rr, ri);
+}
+
+/* Expand complex division to scalars. */
+
+static void
+expand_complex_division (block_stmt_iterator *bsi, tree inner_type,
+ tree ar, tree ai, tree br, tree bi,
+ enum tree_code code)
+{
+ switch (flag_complex_divide_method)
+ {
+ case 0:
+ /* straightforward implementation of complex divide acceptable. */
+ expand_complex_div_straight (bsi, inner_type, ar, ai, br, bi, code);
+ break;
+ case 1:
+ /* wide ranges of inputs must work for complex divide. */
+ expand_complex_div_wide (bsi, inner_type, ar, ai, br, bi, code);
+ break;
+ default:
+ /* C99-like requirements for complex divide (not yet implemented). */
+ abort ();
+ }
+}
+
+/* Expand complex negation to scalars:
+ -a = (-ar) + i(-ai)
+*/
+
+static void
+expand_complex_negation (block_stmt_iterator *bsi, tree inner_type,
+ tree ar, tree ai)
+{
+ tree rr, ri;
+
+ rr = do_unop (bsi, NEGATE_EXPR, inner_type, ar);
+ ri = do_unop (bsi, NEGATE_EXPR, inner_type, ai);
+
+ update_complex_assignment (bsi, rr, ri);
+}
+
+/* Expand complex conjugate to scalars:
+ ~a = (ar) + i(-ai)
+*/
+
+static void
+expand_complex_conjugate (block_stmt_iterator *bsi, tree inner_type,
+ tree ar, tree ai)
+{
+ tree ri;
+
+ ri = do_unop (bsi, NEGATE_EXPR, inner_type, ai);
+
+ update_complex_assignment (bsi, ar, ri);
+}
+
+/* Expand complex comparison (EQ or NE only). */
+
+static void
+expand_complex_comparison (block_stmt_iterator *bsi, tree ar, tree ai,
+ tree br, tree bi, enum tree_code code)
+{
+ tree cr, ci, cc, stmt, type;
+
+ cr = do_binop (bsi, code, boolean_type_node, ar, br);
+ ci = do_binop (bsi, code, boolean_type_node, ai, bi);
+ cc = do_binop (bsi, (code == EQ_EXPR ? TRUTH_AND_EXPR : TRUTH_OR_EXPR),
+ boolean_type_node, cr, ci);
+
+ stmt = bsi_stmt (*bsi);
+ modify_stmt (stmt);
+
+ switch (TREE_CODE (stmt))
+ {
+ case RETURN_EXPR:
+ stmt = TREE_OPERAND (stmt, 0);
+ /* FALLTHRU */
+ case MODIFY_EXPR:
+ type = TREE_TYPE (TREE_OPERAND (stmt, 1));
+ TREE_OPERAND (stmt, 1) = convert (type, cc);
+ break;
+ case COND_EXPR:
+ TREE_OPERAND (stmt, 0) = cc;
+ break;
+ default:
+ abort ();
+ }
+}
+
+/* Process one statement. If we identify a complex operation, expand it. */
+
+static void
+expand_complex_operations_1 (block_stmt_iterator *bsi)
+{
+ tree stmt = bsi_stmt (*bsi);
+ tree rhs, type, inner_type;
+ tree ac, ar, ai, bc, br, bi;
+ enum tree_code code;
+
+ switch (TREE_CODE (stmt))
+ {
+ case RETURN_EXPR:
+ stmt = TREE_OPERAND (stmt, 0);
+ if (!stmt)
+ return;
+ if (TREE_CODE (stmt) != MODIFY_EXPR)
+ return;
+ /* FALLTHRU */
+
+ case MODIFY_EXPR:
+ rhs = TREE_OPERAND (stmt, 1);
+ break;
+
+ case COND_EXPR:
+ rhs = TREE_OPERAND (stmt, 0);
+ break;
+
+ default:
+ return;
+ }
+
+ type = TREE_TYPE (rhs);
+ code = TREE_CODE (rhs);
+
+ /* Initial filter for operations we handle. */
+ switch (code)
+ {
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case RDIV_EXPR:
+ case NEGATE_EXPR:
+ case CONJ_EXPR:
+ if (TREE_CODE (type) != COMPLEX_TYPE)
+ return;
+ inner_type = TREE_TYPE (type);
+ break;
+
+ case EQ_EXPR:
+ case NE_EXPR:
+ inner_type = TREE_TYPE (TREE_OPERAND (rhs, 1));
+ if (TREE_CODE (inner_type) != COMPLEX_TYPE)
+ return;
+ break;
+
+ default:
+ return;
+ }
+
+ /* Extract the components of the two complex values. Make sure and
+ handle the common case of the same value used twice specially. */
+ ac = TREE_OPERAND (rhs, 0);
+ ar = extract_component (bsi, ac, 0);
+ ai = extract_component (bsi, ac, 1);
+
+ if (TREE_CODE_CLASS (code) == '1')
+ bc = br = bi = NULL;
+ else
+ {
+ bc = TREE_OPERAND (rhs, 1);
+ if (ac == bc)
+ br = ar, bi = ai;
+ else
+ {
+ br = extract_component (bsi, bc, 0);
+ bi = extract_component (bsi, bc, 1);
+ }
+ }
+
+ switch (code)
+ {
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ expand_complex_addition (bsi, inner_type, ar, ai, br, bi, code);
+ break;
+
+ case MULT_EXPR:
+ expand_complex_multiplication (bsi, inner_type, ar, ai, br, bi);
+ break;
+
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case RDIV_EXPR:
+ expand_complex_division (bsi, inner_type, ar, ai, br, bi, code);
+ break;
+
+ case NEGATE_EXPR:
+ expand_complex_negation (bsi, inner_type, ar, ai);
+ break;
+
+ case CONJ_EXPR:
+ expand_complex_conjugate (bsi, inner_type, ar, ai);
+ break;
+
+ case EQ_EXPR:
+ case NE_EXPR:
+ expand_complex_comparison (bsi, ar, ai, br, bi, code);
+ break;
+
+ default:
+ abort ();
+ }
+}
+
+/* Main loop to process each statement. */
+/* ??? Could use dominator bits to propagate from complex_expr at the
+ same time. This might reveal more constants, particularly in cases
+ such as (complex = complex op scalar). This may not be relevant
+ after SRA and subsequent cleanups. Proof of this would be if we
+ verify that the code generated by expand_complex_div_wide is
+ simplified properly to straight-line code. */
+
+static void
+expand_complex_operations (void)
+{
+ int old_last_basic_block = last_basic_block;
+ block_stmt_iterator bsi;
+ basic_block bb;
+
+ FOR_EACH_BB (bb)
+ {
+ if (bb->index >= old_last_basic_block)
+ continue;
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ expand_complex_operations_1 (&bsi);
+ }
+}
+
+struct tree_opt_pass pass_lower_complex =
+{
+ "complex", /* name */
+ NULL, /* gate */
+ expand_complex_operations, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func | TODO_rename_vars
+ | TODO_ggc_collect | TODO_verify_ssa
+ | TODO_verify_stmts | TODO_verify_flow /* todo_flags_finish */
+};
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
new file mode 100644
index 00000000000..e94640eee00
--- /dev/null
+++ b/gcc/tree-dfa.c
@@ -0,0 +1,1165 @@
+/* Data flow functions for trees.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Diego Novillo <dnovillo@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "hashtab.h"
+#include "tree.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "output.h"
+#include "errors.h"
+#include "timevar.h"
+#include "expr.h"
+#include "ggc.h"
+#include "langhooks.h"
+#include "flags.h"
+#include "function.h"
+#include "diagnostic.h"
+#include "tree-dump.h"
+#include "tree-gimple.h"
+#include "tree-flow.h"
+#include "tree-inline.h"
+#include "tree-alias-common.h"
+#include "tree-pass.h"
+#include "convert.h"
+#include "params.h"
+
+/* Build and maintain data flow information for trees. */
+
+/* Counters used to display DFA and SSA statistics. */
+struct dfa_stats_d
+{
+ long num_stmt_anns;
+ long num_var_anns;
+ long num_defs;
+ long num_uses;
+ long num_phis;
+ long num_phi_args;
+ int max_num_phi_args;
+ long num_vdefs;
+ long num_vuses;
+};
+
+
+/* State information for find_vars_r. */
+struct walk_state
+{
+ /* Hash table used to avoid adding the same variable more than once. */
+ htab_t vars_found;
+};
+
+
+/* Local functions. */
+static void collect_dfa_stats (struct dfa_stats_d *);
+static tree collect_dfa_stats_r (tree *, int *, void *);
+static void add_immediate_use (tree, tree);
+static tree find_vars_r (tree *, int *, void *);
+static void add_referenced_var (tree, struct walk_state *);
+static void compute_immediate_uses_for_phi (tree, bool (*)(tree));
+static void compute_immediate_uses_for_stmt (tree, int, bool (*)(tree));
+static void find_hidden_use_vars (tree);
+static tree find_hidden_use_vars_r (tree *, int *, void *);
+
+
+/* Global declarations. */
+
+/* Array of all variables referenced in the function. */
+varray_type referenced_vars;
+
+
+/*---------------------------------------------------------------------------
+ Dataflow analysis (DFA) routines
+---------------------------------------------------------------------------*/
+/* Find all the variables referenced in the function. This function
+ builds the global arrays REFERENCED_VARS and CALL_CLOBBERED_VARS.
+
+ Note that this function does not look for statement operands, it simply
+ determines what variables are referenced in the program and detects
+ various attributes for each variable used by alias analysis and the
+ optimizer. */
+
+static void
+find_referenced_vars (void)
+{
+ htab_t vars_found;
+ basic_block bb;
+ block_stmt_iterator si;
+ struct walk_state walk_state;
+ tree block;
+
+ /* This is the very first pass in preparation for building the SSA
+ form of the function, so initialize internal data structures now. */
+ init_tree_ssa ();
+
+ /* Walk the lexical blocks in the function looking for variables that may
+ have been used to declare VLAs and for nested functions. Both
+ constructs create hidden uses of variables.
+
+ Note that at this point we may have multiple blocks hung off
+ DECL_INITIAL chained through the BLOCK_CHAIN field due to
+ how inlining works. Egad. */
+ block = DECL_INITIAL (current_function_decl);
+ while (block)
+ {
+ find_hidden_use_vars (block);
+ block = BLOCK_CHAIN (block);
+ }
+
+ vars_found = htab_create (50, htab_hash_pointer, htab_eq_pointer, NULL);
+ memset (&walk_state, 0, sizeof (walk_state));
+ walk_state.vars_found = vars_found;
+
+ FOR_EACH_BB (bb)
+ for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ {
+ tree *stmt_p = bsi_stmt_ptr (si);
+ walk_tree (stmt_p, find_vars_r, &walk_state, NULL);
+ }
+
+ htab_delete (vars_found);
+}
+
+struct tree_opt_pass pass_referenced_vars =
+{
+ NULL, /* name */
+ NULL, /* gate */
+ find_referenced_vars, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ PROP_gimple_leh | PROP_cfg, /* properties_required */
+ PROP_referenced_vars, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+};
+
+
+/* Compute immediate uses.
+
+ CALC_FOR is an optional function pointer which indicates whether
+ immediate uses information should be calculated for a given SSA
+ variable. If NULL, then information is computed for all
+ variables.
+
+ FLAGS is one of {TDFA_USE_OPS, TDFA_USE_VOPS}. It is used by
+ compute_immediate_uses_for_stmt to determine whether to look at
+ virtual and/or real operands while computing def-use chains. */
+
+void
+compute_immediate_uses (int flags, bool (*calc_for)(tree))
+{
+ basic_block bb;
+ block_stmt_iterator si;
+
+ FOR_EACH_BB (bb)
+ {
+ tree phi;
+
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ compute_immediate_uses_for_phi (phi, calc_for);
+
+ for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ {
+ tree stmt = bsi_stmt (si);
+ get_stmt_operands (stmt);
+ compute_immediate_uses_for_stmt (stmt, flags, calc_for);
+ }
+ }
+}
+
+
+/* Invalidates dataflow information for a statement STMT. */
+
+static void
+free_df_for_stmt (tree stmt)
+{
+ stmt_ann_t ann = stmt_ann (stmt);
+
+ if (ann && ann->df)
+ {
+ /* If we have a varray of immediate uses, then go ahead and release
+ it for re-use. */
+ if (ann->df->immediate_uses)
+ ggc_free (ann->df->immediate_uses);
+
+ /* Similarly for the main dataflow structure. */
+ ggc_free (ann->df);
+ ann->df = NULL;
+ }
+}
+
+
+/* Invalidate dataflow information for the whole function. */
+
+void
+free_df (void)
+{
+ basic_block bb;
+ block_stmt_iterator si;
+
+ FOR_EACH_BB (bb)
+ {
+ tree phi;
+
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ free_df_for_stmt (phi);
+
+ for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ {
+ tree stmt = bsi_stmt (si);
+ free_df_for_stmt (stmt);
+ }
+ }
+}
+
+
+/* Helper for compute_immediate_uses. Check all the USE and/or VUSE
+ operands in phi node PHI and add a def-use edge between their
+ defining statement and PHI. CALC_FOR is as in
+ compute_immediate_uses.
+
+ PHI nodes are easy, we only need to look at their arguments. */
+
+static void
+compute_immediate_uses_for_phi (tree phi, bool (*calc_for)(tree))
+{
+ int i;
+
+#ifdef ENABLE_CHECKING
+ if (TREE_CODE (phi) != PHI_NODE)
+ abort ();
+#endif
+
+ for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ {
+ tree arg = PHI_ARG_DEF (phi, i);
+
+ if (TREE_CODE (arg) == SSA_NAME && (!calc_for || calc_for (arg)))
+ {
+ tree imm_rdef_stmt = SSA_NAME_DEF_STMT (PHI_ARG_DEF (phi, i));
+ if (!IS_EMPTY_STMT (imm_rdef_stmt))
+ add_immediate_use (imm_rdef_stmt, phi);
+ }
+ }
+}
+
+
+/* Another helper for compute_immediate_uses. Depending on the value
+ of FLAGS, check all the USE and/or VUSE operands in STMT and add a
+ def-use edge between their defining statement and STMT. CALC_FOR
+ is as in compute_immediate_uses. */
+
+static void
+compute_immediate_uses_for_stmt (tree stmt, int flags, bool (*calc_for)(tree))
+{
+ size_t i;
+ use_optype uses;
+ vuse_optype vuses;
+ vdef_optype vdefs;
+ stmt_ann_t ann;
+
+#ifdef ENABLE_CHECKING
+ /* PHI nodes are handled elsewhere. */
+ if (TREE_CODE (stmt) == PHI_NODE)
+ abort ();
+#endif
+
+ /* Look at USE_OPS or VUSE_OPS according to FLAGS. */
+ ann = stmt_ann (stmt);
+ if (flags & TDFA_USE_OPS)
+ {
+ uses = USE_OPS (ann);
+ for (i = 0; i < NUM_USES (uses); i++)
+ {
+ tree use = USE_OP (uses, i);
+ tree imm_stmt = SSA_NAME_DEF_STMT (use);
+ if (!IS_EMPTY_STMT (imm_stmt) && (!calc_for || calc_for (use)))
+ add_immediate_use (imm_stmt, stmt);
+ }
+ }
+
+ if (flags & TDFA_USE_VOPS)
+ {
+ vuses = VUSE_OPS (ann);
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ {
+ tree vuse = VUSE_OP (vuses, i);
+ tree imm_rdef_stmt = SSA_NAME_DEF_STMT (vuse);
+ if (!IS_EMPTY_STMT (imm_rdef_stmt) && (!calc_for || calc_for (vuse)))
+ add_immediate_use (imm_rdef_stmt, stmt);
+ }
+
+ vdefs = VDEF_OPS (ann);
+ for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ {
+ tree vuse = VDEF_OP (vdefs, i);
+ tree imm_rdef_stmt = SSA_NAME_DEF_STMT (vuse);
+ if (!IS_EMPTY_STMT (imm_rdef_stmt) && (!calc_for || calc_for (vuse)))
+ add_immediate_use (imm_rdef_stmt, stmt);
+ }
+ }
+}
+
+
+/* Add statement USE_STMT to the list of statements that use definitions
+ made by STMT. */
+
+static void
+add_immediate_use (tree stmt, tree use_stmt)
+{
+ stmt_ann_t ann = get_stmt_ann (stmt);
+ struct dataflow_d *df;
+
+ df = ann->df;
+ if (df == NULL)
+ {
+ df = ann->df = ggc_alloc (sizeof (struct dataflow_d));
+ memset ((void *) df, 0, sizeof (struct dataflow_d));
+ df->uses[0] = use_stmt;
+ return;
+ }
+
+ if (!df->uses[1])
+ {
+ df->uses[1] = use_stmt;
+ return;
+ }
+
+ if (ann->df->immediate_uses == NULL)
+ VARRAY_TREE_INIT (ann->df->immediate_uses, 4, "immediate_uses");
+
+ VARRAY_PUSH_TREE (ann->df->immediate_uses, use_stmt);
+}
+
+
+/* If the immediate use of USE points to OLD, then redirect it to NEW. */
+
+static void
+redirect_immediate_use (tree use, tree old, tree new)
+{
+ tree imm_stmt = SSA_NAME_DEF_STMT (use);
+ struct dataflow_d *df = get_stmt_ann (imm_stmt)->df;
+ unsigned int num_uses = num_immediate_uses (df);
+ unsigned int i;
+
+ for (i = 0; i < num_uses; i++)
+ {
+ if (immediate_use (df, i) == old)
+ {
+ if (i == 0 || i == 1)
+ df->uses[i] = new;
+ else
+ VARRAY_TREE (df->immediate_uses, i - 2) = new;
+ }
+ }
+}
+
+
+/* Redirect all immediate uses for operands in OLD so that they point
+ to NEW. This routine should have no knowledge of how immediate
+ uses are stored. */
+
+void
+redirect_immediate_uses (tree old, tree new)
+{
+ stmt_ann_t ann = get_stmt_ann (old);
+ use_optype uses = USE_OPS (ann);
+ vuse_optype vuses = VUSE_OPS (ann);
+ vdef_optype vdefs = VDEF_OPS (ann);
+ unsigned int i;
+
+ /* Look at USE_OPS or VUSE_OPS according to FLAGS. */
+ for (i = 0; i < NUM_USES (uses); i++)
+ redirect_immediate_use (USE_OP (uses, i), old, new);
+
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ redirect_immediate_use (VUSE_OP (vuses, i), old, new);
+
+ for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ redirect_immediate_use (VDEF_OP (vdefs, i), old, new);
+}
+
+
+/*---------------------------------------------------------------------------
+ Manage annotations
+---------------------------------------------------------------------------*/
+/* Create a new annotation for a _DECL node T. */
+
+var_ann_t
+create_var_ann (tree t)
+{
+ var_ann_t ann;
+
+#if defined ENABLE_CHECKING
+ if (t == NULL_TREE
+ || !DECL_P (t)
+ || (t->common.ann
+ && t->common.ann->common.type != VAR_ANN))
+ abort ();
+#endif
+
+ ann = ggc_alloc (sizeof (*ann));
+ memset ((void *) ann, 0, sizeof (*ann));
+
+ ann->common.type = VAR_ANN;
+
+ t->common.ann = (tree_ann) ann;
+
+ return ann;
+}
+
+
+/* Create a new annotation for a statement node T. */
+
+stmt_ann_t
+create_stmt_ann (tree t)
+{
+ stmt_ann_t ann;
+
+#if defined ENABLE_CHECKING
+ if ((!is_gimple_stmt (t) && !is_essa_node (t))
+ || (t->common.ann
+ && t->common.ann->common.type != STMT_ANN))
+ abort ();
+#endif
+
+ ann = ggc_alloc (sizeof (*ann));
+ memset ((void *) ann, 0, sizeof (*ann));
+
+ ann->common.type = STMT_ANN;
+
+ /* Since we just created the annotation, mark the statement modified. */
+ ann->modified = true;
+
+ t->common.ann = (tree_ann) ann;
+
+ return ann;
+}
+
+
+/* Create a new annotation for an SSA name T. */
+
+ssa_name_ann_t
+create_ssa_name_ann (tree t)
+{
+ ssa_name_ann_t ann;
+
+#if defined ENABLE_CHECKING
+ if (t == NULL_TREE
+ || (t->common.ann
+ && t->common.ann->common.type != SSA_NAME_ANN))
+ abort ();
+#endif
+
+ ann = ggc_alloc (sizeof (*ann));
+ memset ((void *) ann, 0, sizeof (*ann));
+
+ ann->common.type = SSA_NAME_ANN;
+ t->common.ann = (tree_ann) ann;
+
+ return ann;
+}
+
+
+/* Build a temporary. Make sure and register it to be renamed. */
+
+tree
+make_rename_temp (tree type, const char *prefix)
+{
+ tree t = create_tmp_var (type, prefix);
+ add_referenced_tmp_var (t);
+ bitmap_set_bit (vars_to_rename, var_ann (t)->uid);
+ return t;
+}
+
+
+
+/*---------------------------------------------------------------------------
+ Debugging functions
+---------------------------------------------------------------------------*/
+/* Dump the list of all the referenced variables in the current function to
+ FILE. */
+
+void
+dump_referenced_vars (FILE *file)
+{
+ size_t i;
+
+ fprintf (file, "\nReferenced variables in %s: %u\n\n",
+ get_name (current_function_decl), (unsigned) num_referenced_vars);
+
+ for (i = 0; i < num_referenced_vars; i++)
+ {
+ tree var = referenced_var (i);
+ fprintf (file, "Variable: ");
+ dump_variable (file, var);
+ fprintf (file, "\n");
+ }
+}
+
+
+/* Dump the list of all the referenced variables to stderr. */
+
+void
+debug_referenced_vars (void)
+{
+ dump_referenced_vars (stderr);
+}
+
+
+/* Dump variable VAR and its may-aliases to FILE. */
+
+void
+dump_variable (FILE *file, tree var)
+{
+ var_ann_t ann;
+
+ if (var == NULL_TREE)
+ {
+ fprintf (file, "<nil>");
+ return;
+ }
+
+ print_generic_expr (file, var, dump_flags);
+
+ if (TREE_CODE (var) == SSA_NAME)
+ var = SSA_NAME_VAR (var);
+
+ ann = var_ann (var);
+
+ fprintf (file, ", UID %u", (unsigned) ann->uid);
+
+ if (ann->has_hidden_use)
+ fprintf (file, ", has hidden uses");
+
+ if (ann->type_mem_tag)
+ {
+ fprintf (file, ", type memory tag: ");
+ print_generic_expr (file, ann->type_mem_tag, dump_flags);
+ }
+
+ if (ann->is_alias_tag)
+ fprintf (file, ", is an alias tag");
+
+ if (needs_to_live_in_memory (var))
+ fprintf (file, ", is %s", TREE_STATIC (var) ? "static" : "global");
+
+ if (is_call_clobbered (var))
+ fprintf (file, ", call clobbered");
+
+ if (ann->default_def)
+ {
+ fprintf (file, ", default def: ");
+ print_generic_expr (file, ann->default_def, dump_flags);
+ }
+
+ if (ann->may_aliases)
+ {
+ fprintf (file, ", may aliases: ");
+ dump_may_aliases_for (file, var);
+ }
+
+ fprintf (file, "\n");
+}
+
+
+/* Dump variable VAR and its may-aliases to stderr. */
+
+void
+debug_variable (tree var)
+{
+ dump_variable (stderr, var);
+}
+
+
+/* Dump def-use edges on FILE. */
+
+void
+dump_immediate_uses (FILE *file)
+{
+ basic_block bb;
+ block_stmt_iterator si;
+ const char *funcname
+ = (*lang_hooks.decl_printable_name) (current_function_decl, 2);
+
+ fprintf (file, "\nDef-use edges for function %s\n", funcname);
+
+ FOR_EACH_BB (bb)
+ {
+ tree phi;
+
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ dump_immediate_uses_for (file, phi);
+
+ for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ dump_immediate_uses_for (file, bsi_stmt (si));
+ }
+
+ fprintf (file, "\n");
+}
+
+
+/* Dump def-use edges on stderr. */
+
+void
+debug_immediate_uses (void)
+{
+ dump_immediate_uses (stderr);
+}
+
+
+/* Dump all immediate uses for STMT on FILE. */
+
+void
+dump_immediate_uses_for (FILE *file, tree stmt)
+{
+ dataflow_t df = get_immediate_uses (stmt);
+ int num_imm_uses = num_immediate_uses (df);
+
+ if (num_imm_uses > 0)
+ {
+ int i;
+
+ fprintf (file, "-> ");
+ print_generic_stmt (file, stmt, TDF_SLIM);
+ fprintf (file, "\n");
+
+ for (i = 0; i < num_imm_uses; i++)
+ {
+ fprintf (file, "\t");
+ print_generic_stmt (file, immediate_use (df, i), TDF_SLIM);
+ fprintf (file, "\n");
+ }
+
+ fprintf (file, "\n");
+ }
+}
+
+
+/* Dump immediate uses for STMT on stderr. */
+
+void
+debug_immediate_uses_for (tree stmt)
+{
+ dump_immediate_uses_for (stderr, stmt);
+}
+
+
+/* Dump various DFA statistics to FILE. */
+
+void
+dump_dfa_stats (FILE *file)
+{
+ struct dfa_stats_d dfa_stats;
+
+ unsigned long size, total = 0;
+ const char * const fmt_str = "%-30s%-13s%12s\n";
+ const char * const fmt_str_1 = "%-30s%13lu%11lu%c\n";
+ const char * const fmt_str_3 = "%-43s%11lu%c\n";
+ const char *funcname
+ = (*lang_hooks.decl_printable_name) (current_function_decl, 2);
+
+ collect_dfa_stats (&dfa_stats);
+
+ fprintf (file, "\nDFA Statistics for %s\n\n", funcname);
+
+ fprintf (file, "---------------------------------------------------------\n");
+ fprintf (file, fmt_str, "", " Number of ", "Memory");
+ fprintf (file, fmt_str, "", " instances ", "used ");
+ fprintf (file, "---------------------------------------------------------\n");
+
+ size = num_referenced_vars * sizeof (tree);
+ total += size;
+ fprintf (file, fmt_str_1, "Referenced variables", num_referenced_vars,
+ SCALE (size), LABEL (size));
+
+ size = dfa_stats.num_stmt_anns * sizeof (struct stmt_ann_d);
+ total += size;
+ fprintf (file, fmt_str_1, "Statements annotated", dfa_stats.num_stmt_anns,
+ SCALE (size), LABEL (size));
+
+ size = dfa_stats.num_var_anns * sizeof (struct var_ann_d);
+ total += size;
+ fprintf (file, fmt_str_1, "Variables annotated", dfa_stats.num_var_anns,
+ SCALE (size), LABEL (size));
+
+ size = dfa_stats.num_uses * sizeof (tree *);
+ total += size;
+ fprintf (file, fmt_str_1, "USE operands", dfa_stats.num_uses,
+ SCALE (size), LABEL (size));
+
+ size = dfa_stats.num_defs * sizeof (tree *);
+ total += size;
+ fprintf (file, fmt_str_1, "DEF operands", dfa_stats.num_defs,
+ SCALE (size), LABEL (size));
+
+ size = dfa_stats.num_vuses * sizeof (tree *);
+ total += size;
+ fprintf (file, fmt_str_1, "VUSE operands", dfa_stats.num_vuses,
+ SCALE (size), LABEL (size));
+
+ size = dfa_stats.num_vdefs * sizeof (tree *);
+ total += size;
+ fprintf (file, fmt_str_1, "VDEF operands", dfa_stats.num_vdefs,
+ SCALE (size), LABEL (size));
+
+ size = dfa_stats.num_phis * sizeof (struct tree_phi_node);
+ total += size;
+ fprintf (file, fmt_str_1, "PHI nodes", dfa_stats.num_phis,
+ SCALE (size), LABEL (size));
+
+ size = dfa_stats.num_phi_args * sizeof (struct phi_arg_d);
+ total += size;
+ fprintf (file, fmt_str_1, "PHI arguments", dfa_stats.num_phi_args,
+ SCALE (size), LABEL (size));
+
+ fprintf (file, "---------------------------------------------------------\n");
+ fprintf (file, fmt_str_3, "Total memory used by DFA/SSA data", SCALE (total),
+ LABEL (total));
+ fprintf (file, "---------------------------------------------------------\n");
+ fprintf (file, "\n");
+
+ if (dfa_stats.num_phis)
+ fprintf (file, "Average number of arguments per PHI node: %.1f (max: %d)\n",
+ (float) dfa_stats.num_phi_args / (float) dfa_stats.num_phis,
+ dfa_stats.max_num_phi_args);
+
+ fprintf (file, "\n");
+}
+
+
+/* Dump DFA statistics on stderr. */
+
+void
+debug_dfa_stats (void)
+{
+ dump_dfa_stats (stderr);
+}
+
+
+/* Collect DFA statistics and store them in the structure pointed by
+ DFA_STATS_P. */
+
+static void
+collect_dfa_stats (struct dfa_stats_d *dfa_stats_p)
+{
+ htab_t htab;
+ basic_block bb;
+ block_stmt_iterator i;
+
+ if (dfa_stats_p == NULL)
+ abort ();
+
+ memset ((void *)dfa_stats_p, 0, sizeof (struct dfa_stats_d));
+
+ /* Walk all the trees in the function counting references. Start at
+ basic block 0, but don't stop at block boundaries. */
+ htab = htab_create (30, htab_hash_pointer, htab_eq_pointer, NULL);
+
+ for (i = bsi_start (BASIC_BLOCK (0)); !bsi_end_p (i); bsi_next (&i))
+ walk_tree (bsi_stmt_ptr (i), collect_dfa_stats_r, (void *) dfa_stats_p,
+ (void *) htab);
+
+ htab_delete (htab);
+
+ FOR_EACH_BB (bb)
+ {
+ tree phi;
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ dfa_stats_p->num_phis++;
+ dfa_stats_p->num_phi_args += PHI_NUM_ARGS (phi);
+ if (PHI_NUM_ARGS (phi) > dfa_stats_p->max_num_phi_args)
+ dfa_stats_p->max_num_phi_args = PHI_NUM_ARGS (phi);
+ }
+ }
+}
+
+
+/* Callback for walk_tree to collect DFA statistics for a tree and its
+ children. */
+
+static tree
+collect_dfa_stats_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
+ void *data)
+{
+ tree t = *tp;
+ struct dfa_stats_d *dfa_stats_p = (struct dfa_stats_d *)data;
+
+ if (t->common.ann)
+ {
+ switch (ann_type (t->common.ann))
+ {
+ case STMT_ANN:
+ {
+ stmt_ann_t ann = (stmt_ann_t) t->common.ann;
+ dfa_stats_p->num_stmt_anns++;
+ dfa_stats_p->num_defs += NUM_DEFS (DEF_OPS (ann));
+ dfa_stats_p->num_uses += NUM_USES (USE_OPS (ann));
+ dfa_stats_p->num_vdefs += NUM_VDEFS (VDEF_OPS (ann));
+ dfa_stats_p->num_vuses += NUM_VUSES (VUSE_OPS (ann));
+ break;
+ }
+
+ case VAR_ANN:
+ dfa_stats_p->num_var_anns++;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+
+/*---------------------------------------------------------------------------
+ Miscellaneous helpers
+---------------------------------------------------------------------------*/
+/* Callback for walk_tree. Used to collect variables referenced in
+ the function. */
+
+static tree
+find_vars_r (tree *tp, int *walk_subtrees, void *data)
+{
+ tree t = *tp;
+ struct walk_state *walk_state = (struct walk_state *)data;
+
+ if (SSA_VAR_P (t))
+ {
+ /* If T is a regular variable that the optimizers are interested
+ in, add it to the list of variables. */
+ add_referenced_var (t, walk_state);
+ }
+ else if (DECL_P (t)
+ || TYPE_P (t)
+ || TREE_CODE_CLASS (TREE_CODE (t)) == 'c')
+ {
+ /* Type, _DECL and constant nodes have no interesting children.
+ Ignore them. */
+ *walk_subtrees = 0;
+ }
+
+
+ return NULL_TREE;
+}
+
+
+/* Add VAR to the list of dereferenced variables.
+
+ WALK_STATE contains a hash table used to avoid adding the same
+ variable more than once. Note that this function assumes that
+ VAR is a valid SSA variable. If WALK_STATE is NULL, no
+ duplicate checking is done. */
+
+static void
+add_referenced_var (tree var, struct walk_state *walk_state)
+{
+ void **slot;
+ var_ann_t v_ann;
+
+ v_ann = get_var_ann (var);
+
+ if (walk_state)
+ slot = htab_find_slot (walk_state->vars_found, (void *) var, INSERT);
+ else
+ slot = NULL;
+
+ if (slot == NULL || *slot == NULL)
+ {
+ /* This is the first time we find this variable, add it to the
+ REFERENCED_VARS array and annotate it with attributes that are
+ intrinsic to the variable. */
+ if (slot)
+ *slot = (void *) var;
+ v_ann->uid = num_referenced_vars;
+ VARRAY_PUSH_TREE (referenced_vars, var);
+
+ /* Global and static variables are call-clobbered, always. */
+ if (needs_to_live_in_memory (var))
+ mark_call_clobbered (var);
+
+ /* DECL_NONLOCAL variables should not be removed, as they are needed
+ to emit nested functions. */
+ if (DECL_NONLOCAL (var))
+ v_ann->used = 1;
+ }
+}
+
+
+/* Return the virtual variable associated to the non-scalar variable VAR. */
+
+tree
+get_virtual_var (tree var)
+{
+ enum tree_code code;
+
+ STRIP_NOPS (var);
+
+ if (TREE_CODE (var) == SSA_NAME)
+ var = SSA_NAME_VAR (var);
+
+ code = TREE_CODE (var);
+
+ while (code == ARRAY_REF
+ || code == COMPONENT_REF
+ || code == REALPART_EXPR
+ || code == IMAGPART_EXPR)
+ {
+ var = TREE_OPERAND (var, 0);
+ code = TREE_CODE (var);
+ }
+
+#ifdef ENABLE_CHECKING
+ /* Treating GIMPLE registers as virtual variables makes no sense.
+ Also complain if we couldn't extract a _DECL out of the original
+ expression. */
+ if (!SSA_VAR_P (var)
+ || is_gimple_reg (var))
+ abort ();
+#endif
+
+ return var;
+}
+
+
+/* Mark variables in BLOCK that have hidden uses. A hidden use can
+ occur due to VLA declarations or nested functions. */
+
+static void
+find_hidden_use_vars (tree block)
+{
+ tree sub, decl, tem;
+
+ /* Check all the arrays declared in the block for VLAs.
+ While scanning the block's variables, also see if there is
+ a nested function at this scope. */
+ for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl))
+ {
+ int inside_vla = 0;
+ walk_tree (&decl, find_hidden_use_vars_r, &inside_vla, NULL);
+ }
+
+ /* Now repeat the search in any sub-blocks. */
+ for (sub = BLOCK_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub))
+ find_hidden_use_vars (sub);
+
+ /* A VLA parameter may use a variable which as set from another
+ parameter to declare the size of the VLA. We need to mark the
+ variable as having a hidden use since it is used to declare the
+ VLA parameter and that declaration is not seen by the SSA code.
+
+ Note get_pending_sizes clears the PENDING_SIZES chain, so we
+ must restore it. */
+ tem = get_pending_sizes ();
+ put_pending_sizes (tem);
+ for (; tem; tem = TREE_CHAIN (tem))
+ {
+ int inside_vla = 1;
+ walk_tree (&TREE_VALUE (tem), find_hidden_use_vars_r, &inside_vla, NULL);
+ }
+}
+
+
+/* Callback for walk_tree used by find_hidden_use_vars to analyze each
+ variable in a lexical block. If the variable's size has a variable
+ size, then mark all objects needed to compute the variable's size
+ as having hidden uses. */
+
+static tree
+find_hidden_use_vars_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
+{
+ int *inside_vla = (int *) data;
+
+ /* We need to look for hidden uses due to VLAs in variable
+ definitions. We originally used to look for these hidden
+ uses in the variable's type, but that's unreliable if the
+ type's size contains a SAVE_EXPR for a different function
+ context than the variable is used within. */
+ if (SSA_VAR_P (*tp)
+ && ((DECL_SIZE (*tp)
+ && ! really_constant_p (DECL_SIZE (*tp)))
+ || (DECL_SIZE_UNIT (*tp)
+ && ! really_constant_p (DECL_SIZE_UNIT (*tp)))))
+ {
+ int save = *inside_vla;
+
+ *inside_vla = 1;
+ walk_tree (&DECL_SIZE (*tp), find_hidden_use_vars_r, inside_vla, NULL);
+ walk_tree (&DECL_SIZE_UNIT (*tp), find_hidden_use_vars_r,
+ inside_vla, NULL);
+ *inside_vla = save;
+ }
+ else if (*inside_vla && SSA_VAR_P (*tp))
+ set_has_hidden_use (*tp);
+
+ return NULL_TREE;
+}
+
+
+/* Add a temporary variable to REFERENCED_VARS. This is similar to
+ add_referenced_var, but is used by passes that need to add new temps to
+ the REFERENCED_VARS array after the program has been scanned for
+ variables. The variable will just receive a new UID and be added
+ to the REFERENCED_VARS array without checking for duplicates. */
+
+void
+add_referenced_tmp_var (tree var)
+{
+ add_referenced_var (var, NULL);
+}
+
+
+/* Return true if VDEFS_AFTER contains fewer entries than VDEFS_BEFORE.
+ Note that this assumes that both varrays are VDEF operands for the same
+ statement. */
+
+static inline bool
+vdefs_disappeared_p (vdef_optype vdefs_before, vdef_optype vdefs_after)
+{
+ /* If there was nothing before, nothing could've disappeared. */
+ if (vdefs_before == NULL)
+ return false;
+
+ /* All/some of them gone. */
+ if (vdefs_after == NULL
+ || NUM_VDEFS (vdefs_before) > NUM_VDEFS (vdefs_after))
+ return true;
+
+ return false;
+}
+
+
+/* Add all the non-SSA variables found in STMT's operands to the bitmap
+ VARS_TO_RENAME. */
+
+void
+mark_new_vars_to_rename (tree stmt, bitmap vars_to_rename)
+{
+ def_optype defs;
+ use_optype uses;
+ vdef_optype vdefs;
+ vuse_optype vuses;
+ size_t i;
+ bitmap vars_in_vops_to_rename;
+ bool found_exposed_symbol = false;
+ vdef_optype vdefs_before, vdefs_after;
+ stmt_ann_t ann;
+
+ vars_in_vops_to_rename = BITMAP_XMALLOC ();
+
+ /* Before re-scanning the statement for operands, mark the existing
+ virtual operands to be renamed again. We do this because when new
+ symbols are exposed, the virtual operands that were here before due to
+ aliasing will probably be removed by the call to get_stmt_operand.
+ Therefore, we need to flag them to be renamed beforehand.
+
+ We flag them in a separate bitmap because we don't really want to
+ rename them if there are not any newly exposed symbols in the
+ statement operands. */
+ ann = stmt_ann (stmt);
+ vdefs_before = vdefs = VDEF_OPS (ann);
+ for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ {
+ tree var = VDEF_RESULT (vdefs, i);
+ if (!DECL_P (var))
+ var = SSA_NAME_VAR (var);
+ bitmap_set_bit (vars_in_vops_to_rename, var_ann (var)->uid);
+ }
+
+ vuses = VUSE_OPS (ann);
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ {
+ tree var = VUSE_OP (vuses, i);
+ if (!DECL_P (var))
+ var = SSA_NAME_VAR (var);
+ bitmap_set_bit (vars_in_vops_to_rename, var_ann (var)->uid);
+ }
+
+ /* Now force an operand re-scan on the statement and mark any newly
+ exposed variables. */
+ modify_stmt (stmt);
+ get_stmt_operands (stmt);
+
+ defs = DEF_OPS (ann);
+ for (i = 0; i < NUM_DEFS (defs); i++)
+ {
+ tree var = DEF_OP (defs, i);
+ if (DECL_P (var))
+ {
+ found_exposed_symbol = true;
+ bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
+ }
+ }
+
+ uses = USE_OPS (ann);
+ for (i = 0; i < NUM_USES (uses); i++)
+ {
+ tree var = USE_OP (uses, i);
+ if (DECL_P (var))
+ {
+ found_exposed_symbol = true;
+ bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
+ }
+ }
+
+ vdefs_after = vdefs = VDEF_OPS (ann);
+ for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ {
+ tree var = VDEF_RESULT (vdefs, i);
+ if (DECL_P (var))
+ {
+ found_exposed_symbol = true;
+ bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
+ }
+ }
+
+ vuses = VUSE_OPS (ann);
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ {
+ tree var = VUSE_OP (vuses, i);
+ if (DECL_P (var))
+ {
+ found_exposed_symbol = true;
+ bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
+ }
+ }
+
+ /* If we found any newly exposed symbols, or if there are fewer VDEF
+ operands in the statement, add the variables we had set in
+ VARS_IN_VOPS_TO_RENAME to VARS_TO_RENAME. We need to check for
+ vanishing VDEFs because in those cases, the names that were formerly
+ generated by this statement are not going to be available anymore. */
+ if (found_exposed_symbol
+ || vdefs_disappeared_p (vdefs_before, vdefs_after))
+ bitmap_a_or_b (vars_to_rename, vars_to_rename, vars_in_vops_to_rename);
+
+ BITMAP_XFREE (vars_in_vops_to_rename);
+}
diff --git a/gcc/tree-dump.c b/gcc/tree-dump.c
index e0dd6f1e437..55ab9389b0b 100644
--- a/gcc/tree-dump.c
+++ b/gcc/tree-dump.c
@@ -36,6 +36,7 @@ static void dequeue_and_dump (dump_info_p);
static void dump_new_line (dump_info_p);
static void dump_maybe_newline (dump_info_p);
static void dump_string_field (dump_info_p, const char *, const char *);
+static void dump_enable_all (int);
/* Add T to the end of the queue of nodes to dump. Returns the index
assigned to T. */
@@ -573,10 +574,6 @@ dequeue_and_dump (dump_info_p di)
dump_child ("init", TREE_OPERAND (t, 3));
break;
- case EXPR_WITH_FILE_LOCATION:
- dump_child ("expr", EXPR_WFL_NODE (t));
- break;
-
default:
/* There are no additional fields to print. */
break;
@@ -638,8 +635,8 @@ dump_node (tree t, int flags, FILE *stream)
/* Define a tree dump switch. */
struct dump_file_info
{
- const char *const suffix; /* suffix to give output file. */
- const char *const swtch; /* command line switch */
+ const char *suffix; /* suffix to give output file. */
+ const char *swtch; /* command line switch */
int flags; /* user flags */
int state; /* state of play */
};
@@ -648,13 +645,23 @@ struct dump_file_info
TREE_DUMP_INDEX enumeration in tree.h */
static struct dump_file_info dump_files[TDI_end] =
{
+ {NULL, NULL, 0, 0},
{".tu", "translation-unit", 0, 0},
{".class", "class-hierarchy", 0, 0},
{".original", "tree-original", 0, 0},
- {".optimized", "tree-optimized", 0, 0},
+ {".generic", "tree-generic", 0, 0},
+ {".nested", "tree-nested", 0, 0},
{".inlined", "tree-inlined", 0, 0},
+ {".vcg", "tree-vcg", 0, 0},
+ {".xml", "call-graph", 0, 0},
+ {NULL, "tree-all", 0, 0},
};
+/* Dynamically registered tree dump files and switches. */
+static struct dump_file_info *extra_dump_files;
+static size_t extra_dump_files_in_use;
+static size_t extra_dump_files_alloced;
+
/* Define a name->number mapping for a dump flag value. */
struct dump_option_value_info
{
@@ -668,10 +675,54 @@ static const struct dump_option_value_info dump_options[] =
{
{"address", TDF_ADDRESS},
{"slim", TDF_SLIM},
- {"all", ~0},
+ {"raw", TDF_RAW},
+ {"details", TDF_DETAILS},
+ {"stats", TDF_STATS},
+ {"blocks", TDF_BLOCKS},
+ {"vops", TDF_VOPS},
+ {"lineno", TDF_LINENO},
+ {"uid", TDF_UID},
+ {"all", ~(TDF_RAW | TDF_SLIM | TDF_LINENO)},
{NULL, 0}
};
+unsigned int
+dump_register (const char *suffix, const char *swtch)
+{
+ size_t this = extra_dump_files_in_use++;
+
+ if (this >= extra_dump_files_alloced)
+ {
+ if (extra_dump_files_alloced == 0)
+ extra_dump_files_alloced = 32;
+ else
+ extra_dump_files_alloced *= 2;
+ extra_dump_files = xrealloc (extra_dump_files,
+ sizeof (struct dump_file_info)
+ * extra_dump_files_alloced);
+ }
+
+ memset (&extra_dump_files[this], 0, sizeof (struct dump_file_info));
+ extra_dump_files[this].suffix = suffix;
+ extra_dump_files[this].swtch = swtch;
+
+ return this + TDI_end;
+}
+
+/* Return the dump_file_info for the given phase. */
+
+static struct dump_file_info *
+get_dump_file_info (enum tree_dump_index phase)
+{
+ if (phase < TDI_end)
+ return &dump_files[phase];
+ else if (phase - TDI_end >= extra_dump_files_in_use)
+ abort ();
+ else
+ return extra_dump_files + (phase - TDI_end);
+}
+
+
/* Begin a tree dump for PHASE. Stores any user supplied flag in
*FLAG_PTR and returns a stream to write to. If the dump is not
enabled, returns NULL.
@@ -682,19 +733,29 @@ dump_begin (enum tree_dump_index phase, int *flag_ptr)
{
FILE *stream;
char *name;
+ char dump_id[10];
+ struct dump_file_info *dfi;
- if (!dump_files[phase].state)
+ if (phase == TDI_none)
return NULL;
- name = concat (dump_base_name, dump_files[phase].suffix, NULL);
- stream = fopen (name, dump_files[phase].state < 0 ? "w" : "a");
+ dfi = get_dump_file_info (phase);
+ if (dfi->state == 0)
+ return NULL;
+
+ if (snprintf (dump_id, sizeof (dump_id), ".t%02d", phase) < 0)
+ dump_id[0] = '\0';
+
+ name = concat (dump_base_name, dump_id, dfi->suffix, NULL);
+ stream = fopen (name, dfi->state < 0 ? "w" : "a");
if (!stream)
- error ("could not open dump file `%s'", name);
+ error ("could not open dump file `%s': %s", name, strerror (errno));
else
- dump_files[phase].state = 1;
+ dfi->state = 1;
free (name);
+
if (flag_ptr)
- *flag_ptr = dump_files[phase].flags;
+ *flag_ptr = dfi->flags;
return stream;
}
@@ -704,7 +765,8 @@ dump_begin (enum tree_dump_index phase, int *flag_ptr)
int
dump_enabled_p (enum tree_dump_index phase)
{
- return dump_files[phase].state;
+ struct dump_file_info *dfi = get_dump_file_info (phase);
+ return dfi->state;
}
/* Returns the switch name of PHASE. */
@@ -712,7 +774,8 @@ dump_enabled_p (enum tree_dump_index phase)
const char *
dump_flag_name (enum tree_dump_index phase)
{
- return dump_files[phase].swtch;
+ struct dump_file_info *dfi = get_dump_file_info (phase);
+ return dfi->swtch;
}
/* Finish a tree dump for PHASE. STREAM is the stream created by
@@ -724,52 +787,110 @@ dump_end (enum tree_dump_index phase ATTRIBUTE_UNUSED, FILE *stream)
fclose (stream);
}
+/* Enable all tree dumps. */
+
+static void
+dump_enable_all (int flags)
+{
+ size_t i;
+
+ for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
+ {
+ dump_files[i].state = -1;
+ dump_files[i].flags = flags;
+ }
+
+ for (i = 0; i < extra_dump_files_in_use; i++)
+ {
+ extra_dump_files[i].state = -1;
+ extra_dump_files[i].flags = flags;
+ }
+
+ /* FIXME -fdump-call-graph is broken. */
+ dump_files[TDI_xml].state = 0;
+ dump_files[TDI_xml].flags = 0;
+}
+
/* Parse ARG as a dump switch. Return nonzero if it is, and store the
relevant details in the dump_files array. */
-int
-dump_switch_p (const char *arg)
+static int
+dump_switch_p_1 (const char *arg, struct dump_file_info *dfi)
{
- unsigned ix;
const char *option_value;
+ const char *ptr;
+ int flags;
- for (ix = 0; ix != TDI_end; ix++)
- if ((option_value = skip_leading_substring (arg, dump_files[ix].swtch)))
- {
- const char *ptr = option_value;
- int flags = 0;
+ option_value = skip_leading_substring (arg, dfi->swtch);
+ if (!option_value)
+ return 0;
- while (*ptr)
+ ptr = option_value;
+ flags = 0;
+
+ while (*ptr)
+ {
+ const struct dump_option_value_info *option_ptr;
+ const char *end_ptr;
+ unsigned length;
+
+ while (*ptr == '-')
+ ptr++;
+ end_ptr = strchr (ptr, '-');
+ if (!end_ptr)
+ end_ptr = ptr + strlen (ptr);
+ length = end_ptr - ptr;
+
+ for (option_ptr = dump_options; option_ptr->name; option_ptr++)
+ if (strlen (option_ptr->name) == length
+ && !memcmp (option_ptr->name, ptr, length))
{
- const struct dump_option_value_info *option_ptr;
- const char *end_ptr;
- unsigned length;
-
- while (*ptr == '-')
- ptr++;
- end_ptr = strchr (ptr, '-');
- if (!end_ptr)
- end_ptr = ptr + strlen (ptr);
- length = end_ptr - ptr;
-
- for (option_ptr = dump_options; option_ptr->name;
- option_ptr++)
- if (strlen (option_ptr->name) == length
- && !memcmp (option_ptr->name, ptr, length))
- {
- flags |= option_ptr->value;
- goto found;
- }
- warning ("ignoring unknown option `%.*s' in `-fdump-%s'",
- length, ptr, dump_files[ix].swtch);
- found:;
- ptr = end_ptr;
+ flags |= option_ptr->value;
+ goto found;
}
+ warning ("ignoring unknown option `%.*s' in `-fdump-%s'",
+ length, ptr, dfi->swtch);
+ found:;
+ ptr = end_ptr;
+ }
+
+ dfi->state = -1;
+ dfi->flags = flags;
+
+ /* Process -fdump-tree-all by enabling all the known dumps. */
+ if (dfi->suffix == NULL)
+ dump_enable_all (flags);
+
+ return 1;
+}
- dump_files[ix].state = -1;
- dump_files[ix].flags = flags;
+int
+dump_switch_p (const char *arg)
+{
+ size_t i;
+ int any = 0;
+
+ for (i = TDI_none + 1; i != TDI_end; i++)
+ any |= dump_switch_p_1 (arg, &dump_files[i]);
+
+ for (i = 0; i < extra_dump_files_in_use; i++)
+ any |= dump_switch_p_1 (arg, &extra_dump_files[i]);
+
+ return any;
+}
- return 1;
- }
- return 0;
+/* Dump FUNCTION_DECL FN as tree dump PHASE. */
+
+void
+dump_function (enum tree_dump_index phase, tree fn)
+{
+ FILE *stream;
+ int flags;
+
+ stream = dump_begin (phase, &flags);
+ if (stream)
+ {
+ dump_function_to_file (fn, stream, flags);
+ dump_end (phase, stream);
+ }
}
diff --git a/gcc/tree-dump.h b/gcc/tree-dump.h
index 3f6497b23f8..974362b6225 100644
--- a/gcc/tree-dump.h
+++ b/gcc/tree-dump.h
@@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#ifndef GCC_TREE_DUMP_H
#define GCC_TREE_DUMP_H
+#include "splay-tree.h"
+
/* Flags used with queue functions. */
#define DUMP_NONE 0
#define DUMP_BINFO 1
@@ -84,5 +86,9 @@ extern void dump_stmt (dump_info_p, tree);
extern void dump_next_stmt (dump_info_p, tree);
extern void queue_and_dump_index (dump_info_p, const char *, tree, int);
extern void queue_and_dump_type (dump_info_p, tree);
+extern void dump_function (enum tree_dump_index, tree);
+extern void dump_function_to_file (tree, FILE *, int);
+
+extern unsigned int dump_register (const char *, const char *);
#endif /* ! GCC_TREE_DUMP_H */
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
new file mode 100644
index 00000000000..1f37ac6789c
--- /dev/null
+++ b/gcc/tree-eh.c
@@ -0,0 +1,1756 @@
+/* Exception handling semantics and decomposition for trees.
+ Copyright (C) 2003 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 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "flags.h"
+#include "function.h"
+#include "except.h"
+#include "tree-flow.h"
+#include "tree-dump.h"
+#include "tree-inline.h"
+#include "tree-iterator.h"
+#include "tree-pass.h"
+#include "timevar.h"
+#include "langhooks.h"
+#include "ggc.h"
+
+/* HACK */
+extern int using_eh_for_cleanups_p;
+
+/* Misc functions used in this file. */
+
+/* Compare and hash for any structure which begins with a canonical
+ pointer. Assumes all pointers are interchangable, which is sort
+ of already assumed by gcc elsewhere IIRC. */
+
+static int
+struct_ptr_eq (const void *a, const void *b)
+{
+ const void * const * x = a;
+ const void * const * y = b;
+ return *x == *y;
+}
+
+static hashval_t
+struct_ptr_hash (const void *a)
+{
+ const void * const * x = a;
+ return (size_t)*x >> 4;
+}
+
+
+/* Remember and lookup EH region data for arbitrary statements.
+ Really this means any statement that could_throw_p. We could
+ stuff this information into the stmt_ann data structure, but:
+
+ (1) We absolutely rely on this information being kept until
+ we get to rtl. Once we're done with lowering here, if we lose
+ the information there's no way to recover it!
+
+ (2) There are many more statements that *cannot* throw as
+ compared to those that can. We should be saving some amount
+ of space by only allocating memory for those that can throw. */
+
+struct throw_stmt_node GTY(())
+{
+ tree stmt;
+ int region_nr;
+};
+
+static GTY((param_is (struct throw_stmt_node))) htab_t throw_stmt_table;
+
+static void
+record_stmt_eh_region (struct eh_region *region, tree t)
+{
+ struct throw_stmt_node *n;
+ void **slot;
+
+ if (!region)
+ return;
+
+ n = ggc_alloc (sizeof (*n));
+ n->stmt = t;
+ n->region_nr = get_eh_region_number (region);
+
+ slot = htab_find_slot (throw_stmt_table, n, INSERT);
+ if (*slot)
+ abort ();
+ *slot = n;
+}
+
+void
+add_stmt_to_eh_region (tree t, int num)
+{
+ struct throw_stmt_node *n;
+ void **slot;
+
+ if (num < 0)
+ abort ();
+
+ n = ggc_alloc (sizeof (*n));
+ n->stmt = t;
+ n->region_nr = num;
+
+ slot = htab_find_slot (throw_stmt_table, n, INSERT);
+ if (*slot)
+ abort ();
+ *slot = n;
+}
+
+int
+lookup_stmt_eh_region (tree t)
+{
+ struct throw_stmt_node *p, n;
+
+ if (!throw_stmt_table)
+ return -2;
+
+ n.stmt = t;
+ p = htab_find (throw_stmt_table, &n);
+
+ return (p ? p->region_nr : -1);
+}
+
+
+
+/* First pass of EH node decomposition. Build up a tree of TRY_FINALLY_EXPR
+ nodes and LABEL_DECL nodes. We will use this during the second phase to
+ determine if a goto leaves the body of a TRY_FINALLY_EXPR node. */
+
+struct finally_tree_node
+{
+ tree child, parent;
+};
+
+/* Note that this table is *not* marked GTY. It is short-lived. */
+static htab_t finally_tree;
+
+static void
+record_in_finally_tree (tree child, tree parent)
+{
+ struct finally_tree_node *n;
+ void **slot;
+
+ n = xmalloc (sizeof (*n));
+ n->child = child;
+ n->parent = parent;
+
+ slot = htab_find_slot (finally_tree, n, INSERT);
+ if (*slot)
+ abort ();
+ *slot = n;
+}
+
+static void
+collect_finally_tree (tree t, tree region)
+{
+ tailrecurse:
+ switch (TREE_CODE (t))
+ {
+ case LABEL_EXPR:
+ record_in_finally_tree (LABEL_EXPR_LABEL (t), region);
+ break;
+
+ case TRY_FINALLY_EXPR:
+ record_in_finally_tree (t, region);
+ collect_finally_tree (TREE_OPERAND (t, 0), t);
+ t = TREE_OPERAND (t, 1);
+ goto tailrecurse;
+
+ case TRY_CATCH_EXPR:
+ collect_finally_tree (TREE_OPERAND (t, 0), region);
+ t = TREE_OPERAND (t, 1);
+ goto tailrecurse;
+
+ case CATCH_EXPR:
+ t = CATCH_BODY (t);
+ goto tailrecurse;
+
+ case EH_FILTER_EXPR:
+ t = EH_FILTER_FAILURE (t);
+ goto tailrecurse;
+
+ case STATEMENT_LIST:
+ {
+ tree_stmt_iterator i;
+ for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
+ collect_finally_tree (tsi_stmt (i), region);
+ }
+ break;
+
+ default:
+ /* A type, a decl, or some kind of statement that we're not
+ interested in. Don't walk them. */
+ break;
+ }
+}
+
+/* Use the finally tree to determine if a jump from START to TARGET
+ would leave the try_finally node that START lives in. */
+
+static bool
+outside_finally_tree (tree start, tree target)
+{
+ struct finally_tree_node n, *p;
+
+ do
+ {
+ n.child = start;
+ p = htab_find (finally_tree, &n);
+ if (!p)
+ return true;
+ start = p->parent;
+ }
+ while (start != target);
+
+ return false;
+}
+
+/* Second pass of EH node decomposition. Actually transform the TRY_FINALLY
+ and TRY_CATCH nodes into a set of gotos, magic labels, and eh regions.
+ The eh region creation is straight-forward, but frobbing all the gotos
+ and such into shape isn't. */
+
+/* State of the world while lowering. */
+
+struct leh_state
+{
+ /* What's "current" while constructing the eh region tree. These
+ correspond to variables of the same name in cfun->eh, which we
+ don't have easy access to. */
+ struct eh_region *cur_region;
+ struct eh_region *prev_try;
+
+ /* Processing of TRY_FINALLY requires a bit more state. This is
+ split out into a separate structure so that we don't have to
+ copy so much when processing other nodes. */
+ struct leh_tf_state *tf;
+};
+
+struct leh_tf_state
+{
+ /* Pointer to the TRY_FINALLY node under discussion. The try_finally_expr
+ is the original TRY_FINALLY_EXPR. We need to retain this so that
+ outside_finally_tree can reliably reference the tree used in the
+ collect_finally_tree data structures. */
+ tree try_finally_expr;
+ tree *top_p;
+
+ /* The state outside this try_finally node. */
+ struct leh_state *outer;
+
+ /* The exception region created for it. */
+ struct eh_region *region;
+
+ /* The GOTO_QUEUE is is an array of GOTO_EXPR and RETURN_EXPR statements
+ that are seen to escape this TRY_FINALLY_EXPR node. */
+ struct goto_queue_node {
+ tree stmt;
+ tree repl_stmt;
+ tree cont_stmt;
+ int index;
+ } *goto_queue;
+ size_t goto_queue_size;
+ size_t goto_queue_active;
+
+ /* The set of unique labels seen as entries in the goto queue. */
+ varray_type dest_array;
+
+ /* A label to be added at the end of the completed transformed
+ sequence. It will be set if may_fallthru was true *at one time*,
+ though subsequent transformations may have cleared that flag. */
+ tree fallthru_label;
+
+ /* A label that has been registered with except.c to be the
+ landing pad for this try block. */
+ tree eh_label;
+
+ /* True if it is possible to fall out the bottom of the try block.
+ Cleared if the fallthru is converted to a goto. */
+ bool may_fallthru;
+
+ /* True if any entry in goto_queue is a RETURN_EXPR. */
+ bool may_return;
+
+ /* True if the finally block can receive an exception edge.
+ Cleared if the exception case is handled by code duplication. */
+ bool may_throw;
+};
+
+static void lower_eh_filter (struct leh_state *, tree *);
+static void lower_eh_constructs_1 (struct leh_state *, tree *);
+
+/* Comparison function for qsort/bsearch. We're interested in
+ searching goto queue elements for source statements. */
+
+static int
+goto_queue_cmp (const void *x, const void *y)
+{
+ tree a = ((const struct goto_queue_node *)x)->stmt;
+ tree b = ((const struct goto_queue_node *)y)->stmt;
+ return (a == b ? 0 : a < b ? -1 : 1);
+}
+
+/* Search for STMT in the goto queue. Return the replacement,
+ or null if the statement isn't in the queue. */
+
+static tree
+find_goto_replacement (struct leh_tf_state *tf, tree stmt)
+{
+ struct goto_queue_node tmp, *ret;
+ tmp.stmt = stmt;
+ ret = bsearch (&tmp, tf->goto_queue, tf->goto_queue_active,
+ sizeof (struct goto_queue_node), goto_queue_cmp);
+ return (ret ? ret->repl_stmt : NULL);
+}
+
+/* A subroutine of replace_goto_queue_1. Handles the sub-clauses of a
+ lowered COND_EXPR. If, by chance, the replacement is a simple goto,
+ then we can just splat it in, otherwise we add the new stmts immediately
+ after the COND_EXPR and redirect. */
+
+static void
+replace_goto_queue_cond_clause (tree *tp, struct leh_tf_state *tf,
+ tree_stmt_iterator *tsi)
+{
+ tree new, one, label;
+
+ new = find_goto_replacement (tf, *tp);
+ if (!new)
+ return;
+
+ one = expr_only (new);
+ if (one && TREE_CODE (one) == GOTO_EXPR)
+ {
+ *tp = one;
+ return;
+ }
+
+ label = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
+ *tp = build_and_jump (&LABEL_EXPR_LABEL (label));
+
+ tsi_link_after (tsi, label, TSI_CONTINUE_LINKING);
+ tsi_link_after (tsi, new, TSI_CONTINUE_LINKING);
+}
+
+/* The real work of replace_goto_queue. Returns with TSI updated to
+ point to the next statement. */
+
+static void replace_goto_queue_stmt_list (tree, struct leh_tf_state *);
+
+static void
+replace_goto_queue_1 (tree t, struct leh_tf_state *tf, tree_stmt_iterator *tsi)
+{
+ switch (TREE_CODE (t))
+ {
+ case GOTO_EXPR:
+ case RETURN_EXPR:
+ t = find_goto_replacement (tf, t);
+ if (t)
+ {
+ tsi_link_before (tsi, t, TSI_SAME_STMT);
+ tsi_delink (tsi);
+ return;
+ }
+ break;
+
+ case COND_EXPR:
+ replace_goto_queue_cond_clause (&COND_EXPR_THEN (t), tf, tsi);
+ replace_goto_queue_cond_clause (&COND_EXPR_ELSE (t), tf, tsi);
+ break;
+
+ case TRY_FINALLY_EXPR:
+ case TRY_CATCH_EXPR:
+ replace_goto_queue_stmt_list (TREE_OPERAND (t, 0), tf);
+ replace_goto_queue_stmt_list (TREE_OPERAND (t, 1), tf);
+ break;
+ case CATCH_EXPR:
+ replace_goto_queue_stmt_list (CATCH_BODY (t), tf);
+ break;
+ case EH_FILTER_EXPR:
+ replace_goto_queue_stmt_list (EH_FILTER_FAILURE (t), tf);
+ break;
+
+ case STATEMENT_LIST:
+ abort ();
+
+ default:
+ /* These won't have gotos in them. */
+ break;
+ }
+
+ tsi_next (tsi);
+}
+
+/* A subroutine of replace_goto_queue. Handles STATEMENT_LISTs. */
+
+static void
+replace_goto_queue_stmt_list (tree t, struct leh_tf_state *tf)
+{
+ tree_stmt_iterator i = tsi_start (t);
+ while (!tsi_end_p (i))
+ replace_goto_queue_1 (tsi_stmt (i), tf, &i);
+}
+
+/* Replace all goto queue members. */
+
+static void
+replace_goto_queue (struct leh_tf_state *tf)
+{
+ replace_goto_queue_stmt_list (*tf->top_p, tf);
+}
+
+/* For any GOTO_EXPR or RETURN_EXPR, decide whether it leaves a try_finally
+ node, and if so record that fact in the goto queue associated with that
+ try_finally node. */
+
+static void
+maybe_record_in_goto_queue (struct leh_state *state, tree stmt)
+{
+ struct leh_tf_state *tf = state->tf;
+ struct goto_queue_node *q;
+ size_t active, size;
+ int index;
+
+ if (!tf)
+ return;
+
+ switch (TREE_CODE (stmt))
+ {
+ case GOTO_EXPR:
+ {
+ tree lab = GOTO_DESTINATION (stmt);
+
+ /* Computed and non-local gotos do not get processed. Given
+ their nature we can neither tell whether we've escaped the
+ finally block nor redirect them if we knew. */
+ if (TREE_CODE (lab) != LABEL_DECL)
+ return;
+
+ /* No need to record gotos that don't leave the try block. */
+ if (! outside_finally_tree (lab, tf->try_finally_expr))
+ return;
+
+ if (! tf->dest_array)
+ {
+ VARRAY_TREE_INIT (tf->dest_array, 10, "dest_array");
+ VARRAY_PUSH_TREE (tf->dest_array, lab);
+ index = 0;
+ }
+ else
+ {
+ int n = VARRAY_ACTIVE_SIZE (tf->dest_array);
+ for (index = 0; index < n; ++index)
+ if (VARRAY_TREE (tf->dest_array, index) == lab)
+ break;
+ if (index == n)
+ VARRAY_PUSH_TREE (tf->dest_array, lab);
+ }
+ }
+ break;
+
+ case RETURN_EXPR:
+ tf->may_return = true;
+ index = -1;
+ break;
+
+ default:
+ abort ();
+ }
+
+ active = tf->goto_queue_active;
+ size = tf->goto_queue_size;
+ if (active >= size)
+ {
+ size = (size ? size * 2 : 32);
+ tf->goto_queue_size = size;
+ tf->goto_queue
+ = xrealloc (tf->goto_queue, size * sizeof (struct goto_queue_node));
+ }
+
+ q = &tf->goto_queue[active];
+ tf->goto_queue_active = active + 1;
+
+ memset (q, 0, sizeof (*q));
+ q->stmt = stmt;
+ q->index = index;
+}
+
+#ifdef ENABLE_CHECKING
+/* We do not process SWITCH_EXPRs for now. As long as the original source
+ was in fact structured, and we've not yet done jump threading, then none
+ of the labels will leave outer TRY_FINALLY_EXPRs. Verify this. */
+
+static void
+verify_norecord_switch_expr (struct leh_state *state, tree switch_expr)
+{
+ struct leh_tf_state *tf = state->tf;
+ size_t i, n;
+ tree vec;
+
+ if (!tf)
+ return;
+
+ vec = SWITCH_LABELS (switch_expr);
+ n = TREE_VEC_LENGTH (vec);
+
+ for (i = 0; i < n; ++i)
+ {
+ tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
+ if (outside_finally_tree (lab, tf->try_finally_expr))
+ abort ();
+ }
+}
+#else
+#define verify_norecord_switch_expr(state, switch_expr)
+#endif
+
+/* Redirect a RETURN_EXPR pointed to by STMT_P to FINLAB. Place in CONT_P
+ whatever is needed to finish the return. If MOD is non-null, insert it
+ before the new branch. RETURN_VALUE_P is a cache containing a temporary
+ variable to be used in manipulating the value returned from the function. */
+
+static void
+do_return_redirection (struct goto_queue_node *q, tree finlab, tree mod,
+ tree *return_value_p)
+{
+ tree ret_expr = TREE_OPERAND (q->stmt, 0);
+ tree x;
+
+ if (ret_expr)
+ {
+ /* The nasty part about redirecting the return value is that the
+ return value itself is to be computed before the FINALLY block
+ is executed. e.g.
+
+ int x;
+ int foo (void)
+ {
+ x = 0;
+ try {
+ return x;
+ } finally {
+ x++;
+ }
+ }
+
+ should return 0, not 1. Arrange for this to happen by copying
+ computed the return value into a local temporary. This also
+ allows us to redirect multiple return statements through the
+ same destination block; whether this is a net win or not really
+ depends, I guess, but it does make generation of the switch in
+ lower_try_finally_switch easier. */
+
+ if (TREE_CODE (ret_expr) == RESULT_DECL)
+ {
+ if (!*return_value_p)
+ *return_value_p = ret_expr;
+ else if (*return_value_p != ret_expr)
+ abort ();
+ q->cont_stmt = q->stmt;
+ }
+ else if (TREE_CODE (ret_expr) == MODIFY_EXPR)
+ {
+ tree result = TREE_OPERAND (ret_expr, 0);
+ tree new, old = TREE_OPERAND (ret_expr, 1);
+
+ if (!*return_value_p)
+ {
+ if (aggregate_value_p (TREE_TYPE (result),
+ TREE_TYPE (current_function_decl)))
+ /* If this function returns in memory, copy the argument
+ into the return slot now. Otherwise, we might need to
+ worry about magic return semantics, so we need to use a
+ temporary to hold the value until we're actually ready
+ to return. */
+ new = result;
+ else
+ new = create_tmp_var (TREE_TYPE (old), "rettmp");
+ *return_value_p = new;
+ }
+ else
+ new = *return_value_p;
+
+ x = build (MODIFY_EXPR, TREE_TYPE (new), new, old);
+ append_to_statement_list (x, &q->repl_stmt);
+
+ if (new == result)
+ x = result;
+ else
+ x = build (MODIFY_EXPR, TREE_TYPE (result), result, new);
+ q->cont_stmt = build1 (RETURN_EXPR, void_type_node, x);
+ }
+ else
+ abort ();
+ }
+ else
+ {
+ /* If we don't return a value, all return statements are the same. */
+ q->cont_stmt = q->stmt;
+ }
+
+ if (mod)
+ append_to_statement_list (mod, &q->repl_stmt);
+
+ x = build1 (GOTO_EXPR, void_type_node, finlab);
+ append_to_statement_list (x, &q->repl_stmt);
+}
+
+/* Similar, but easier, for GOTO_EXPR. */
+
+static void
+do_goto_redirection (struct goto_queue_node *q, tree finlab, tree mod)
+{
+ tree x;
+
+ q->cont_stmt = q->stmt;
+ if (mod)
+ append_to_statement_list (mod, &q->repl_stmt);
+
+ x = build1 (GOTO_EXPR, void_type_node, finlab);
+ append_to_statement_list (x, &q->repl_stmt);
+}
+
+/* We want to transform
+ try { body; } catch { stuff; }
+ to
+ body; goto over; lab: stuff; over:
+
+ T is a TRY_FINALLY or TRY_CATCH node. LAB is the label that
+ should be placed before the second operand, or NULL. OVER is
+ an existing label that should be put at the exit, or NULL. */
+
+static void
+frob_into_branch_around (tree *tp, tree lab, tree over)
+{
+ tree x, op1;
+
+ op1 = TREE_OPERAND (*tp, 1);
+ *tp = TREE_OPERAND (*tp, 0);
+
+ if (block_may_fallthru (*tp))
+ {
+ if (!over)
+ over = create_artificial_label ();
+ x = build1 (GOTO_EXPR, void_type_node, over);
+ append_to_statement_list (x, tp);
+ }
+
+ if (lab)
+ {
+ x = build1 (LABEL_EXPR, void_type_node, lab);
+ append_to_statement_list (x, tp);
+ }
+
+ append_to_statement_list (op1, tp);
+
+ if (over)
+ {
+ x = build1 (LABEL_EXPR, void_type_node, over);
+ append_to_statement_list (x, tp);
+ }
+}
+
+/* A subroutine of lower_try_finally. Duplicate the tree rooted at T.
+ Make sure to record all new labels found. */
+
+static tree
+lower_try_finally_dup_block (tree t, struct leh_state *outer_state)
+{
+ tree region = NULL;
+
+ t = lhd_unsave_expr_now (t);
+
+ if (outer_state->tf)
+ region = outer_state->tf->try_finally_expr;
+ collect_finally_tree (t, region);
+
+ return t;
+}
+
+/* A subroutine of lower_try_finally. Create a fallthru label for
+ the given try_finally state. The only tricky bit here is that
+ we have to make sure to record the label in our outer context. */
+
+static tree
+lower_try_finally_fallthru_label (struct leh_tf_state *tf)
+{
+ tree label = tf->fallthru_label;
+ if (!label)
+ {
+ label = create_artificial_label ();
+ tf->fallthru_label = label;
+ if (tf->outer->tf)
+ record_in_finally_tree (label, tf->outer->tf->try_finally_expr);
+ }
+ return label;
+}
+
+/* A subroutine of lower_try_finally. If lang_protect_cleanup_actions
+ returns non-null, then the language requires that the exception path out
+ of a try_finally be treated specially. To wit: the code within the
+ finally block may not itself throw an exception. We have two choices here.
+ First we can duplicate the finally block and wrap it in a must_not_throw
+ region. Second, we can generate code like
+
+ try {
+ finally_block;
+ } catch {
+ if (fintmp == eh_edge)
+ protect_cleanup_actions;
+ }
+
+ where "fintmp" is the temporary used in the switch statement generation
+ alternative considered below. For the nonce, we always choose the first
+ option.
+
+ THIS_STATE may be null if if this is a try-cleanup, not a try-finally. */
+
+static void
+honor_protect_cleanup_actions (struct leh_state *outer_state,
+ struct leh_state *this_state,
+ struct leh_tf_state *tf)
+{
+ tree protect_cleanup_actions, finally, x;
+ tree_stmt_iterator i;
+ bool finally_may_fallthru;
+
+ /* First check for nothing to do. */
+ if (lang_protect_cleanup_actions)
+ protect_cleanup_actions = lang_protect_cleanup_actions ();
+ else
+ protect_cleanup_actions = NULL;
+
+ finally = TREE_OPERAND (*tf->top_p, 1);
+
+ /* If the EH case of the finally block can fall through, this may be a
+ structure of the form
+ try {
+ try {
+ throw ...;
+ } cleanup {
+ try {
+ throw ...;
+ } catch (...) {
+ }
+ }
+ } catch (...) {
+ yyy;
+ }
+ E.g. with an inline destructor with an embedded try block. In this
+ case we must save the runtime EH data around the nested exception.
+
+ This complication means that any time the previous runtime data might
+ be used (via fallthru from the finally) we handle the eh case here,
+ whether or not protect_cleanup_actions is active. */
+
+ finally_may_fallthru = block_may_fallthru (finally);
+ if (!finally_may_fallthru && !protect_cleanup_actions)
+ return;
+
+ /* Duplicate the FINALLY block. Only need to do this for try-finally,
+ and not for cleanups. */
+ if (this_state)
+ finally = lower_try_finally_dup_block (finally, outer_state);
+
+ /* Resume execution after the exception. Adding this now lets
+ lower_eh_filter not add unnecessary gotos, as it is clear that
+ we never fallthru from this copy of the finally block. */
+ if (finally_may_fallthru)
+ {
+ tree save_eptr, save_filt;
+
+ save_eptr = create_tmp_var (ptr_type_node, "save_eptr");
+ save_filt = create_tmp_var (integer_type_node, "save_filt");
+
+ i = tsi_start (finally);
+ x = build (EXC_PTR_EXPR, ptr_type_node);
+ x = build (MODIFY_EXPR, void_type_node, save_eptr, x);
+ tsi_link_before (&i, x, TSI_CONTINUE_LINKING);
+
+ x = build (FILTER_EXPR, integer_type_node);
+ x = build (MODIFY_EXPR, void_type_node, save_filt, x);
+ tsi_link_before (&i, x, TSI_CONTINUE_LINKING);
+
+ i = tsi_last (finally);
+ x = build (EXC_PTR_EXPR, ptr_type_node);
+ x = build (MODIFY_EXPR, void_type_node, x, save_eptr);
+ tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
+
+ x = build (FILTER_EXPR, integer_type_node);
+ x = build (MODIFY_EXPR, void_type_node, x, save_filt);
+ tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
+
+ x = build1 (RESX_EXPR, void_type_node,
+ build_int_2 (get_eh_region_number (tf->region), 0));
+ tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
+ }
+
+ /* Wrap the block with protect_cleanup_actions as the action. */
+ if (protect_cleanup_actions)
+ {
+ x = build (EH_FILTER_EXPR, void_type_node, NULL, NULL);
+ append_to_statement_list (protect_cleanup_actions, &EH_FILTER_FAILURE (x));
+ EH_FILTER_MUST_NOT_THROW (x) = 1;
+ finally = build (TRY_CATCH_EXPR, void_type_node, finally, x);
+ lower_eh_filter (outer_state, &finally);
+ }
+ else
+ lower_eh_constructs_1 (outer_state, &finally);
+
+ /* Hook this up to the end of the existing try block. If we
+ previously fell through the end, we'll have to branch around.
+ This means adding a new goto, and adding it to the queue. */
+
+ i = tsi_last (TREE_OPERAND (*tf->top_p, 0));
+
+ if (tf->may_fallthru)
+ {
+ x = lower_try_finally_fallthru_label (tf);
+ x = build1 (GOTO_EXPR, void_type_node, x);
+ tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
+
+ if (this_state)
+ maybe_record_in_goto_queue (this_state, x);
+
+ tf->may_fallthru = false;
+ }
+
+ x = build1 (LABEL_EXPR, void_type_node, tf->eh_label);
+ tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
+ tsi_link_after (&i, finally, TSI_CONTINUE_LINKING);
+
+ /* Having now been handled, EH isn't to be considered with
+ the rest of the outgoing edges. */
+ tf->may_throw = false;
+}
+
+/* A subroutine of lower_try_finally. We have determined that there is
+ no fallthru edge out of the finally block. This means that there is
+ no outgoing edge corresponding to any incoming edge. Restructure the
+ try_finally node for this special case. */
+
+static void
+lower_try_finally_nofallthru (struct leh_state *state, struct leh_tf_state *tf)
+{
+ tree x, finally, lab, return_val;
+ struct goto_queue_node *q, *qe;
+
+ if (tf->may_throw)
+ lab = tf->eh_label;
+ else
+ lab = create_artificial_label ();
+
+ finally = TREE_OPERAND (*tf->top_p, 1);
+ *tf->top_p = TREE_OPERAND (*tf->top_p, 0);
+
+ x = build1 (LABEL_EXPR, void_type_node, lab);
+ append_to_statement_list (x, tf->top_p);
+
+ return_val = NULL;
+ q = tf->goto_queue;
+ qe = q + tf->goto_queue_active;
+ for (; q < qe; ++q)
+ if (q->index < 0)
+ do_return_redirection (q, lab, NULL, &return_val);
+ else
+ do_goto_redirection (q, lab, NULL);
+
+ replace_goto_queue (tf);
+
+ lower_eh_constructs_1 (state, &finally);
+ append_to_statement_list (finally, tf->top_p);
+}
+
+/* A subroutine of lower_try_finally. We have determined that there is
+ exactly one destination of the finally block. Restructure the
+ try_finally node for this special case. */
+
+static void
+lower_try_finally_onedest (struct leh_state *state, struct leh_tf_state *tf)
+{
+ struct goto_queue_node *q, *qe;
+ tree x, finally, finally_label;
+
+ finally = TREE_OPERAND (*tf->top_p, 1);
+ *tf->top_p = TREE_OPERAND (*tf->top_p, 0);
+
+ lower_eh_constructs_1 (state, &finally);
+
+ if (tf->may_throw)
+ {
+ /* Only reachable via the exception edge. Add the given label to
+ the head of the FINALLY block. Append a RESX at the end. */
+
+ x = build1 (LABEL_EXPR, void_type_node, tf->eh_label);
+ append_to_statement_list (x, tf->top_p);
+
+ append_to_statement_list (finally, tf->top_p);
+
+ x = build1 (RESX_EXPR, void_type_node,
+ build_int_2 (get_eh_region_number (tf->region), 0));
+ append_to_statement_list (x, tf->top_p);
+
+ return;
+ }
+
+ if (tf->may_fallthru)
+ {
+ /* Only reachable via the fallthru edge. Do nothing but let
+ the two blocks run together; we'll fall out the bottom. */
+ append_to_statement_list (finally, tf->top_p);
+ return;
+ }
+
+ finally_label = create_artificial_label ();
+ x = build1 (LABEL_EXPR, void_type_node, finally_label);
+ append_to_statement_list (x, tf->top_p);
+
+ append_to_statement_list (finally, tf->top_p);
+
+ q = tf->goto_queue;
+ qe = q + tf->goto_queue_active;
+
+ if (tf->may_return)
+ {
+ /* Reachable by return expressions only. Redirect them. */
+ tree return_val = NULL;
+ for (; q < qe; ++q)
+ do_return_redirection (q, finally_label, NULL, &return_val);
+ replace_goto_queue (tf);
+ }
+ else
+ {
+ /* Reachable by goto expressions only. Redirect them. */
+ for (; q < qe; ++q)
+ do_goto_redirection (q, finally_label, NULL);
+ replace_goto_queue (tf);
+
+ if (VARRAY_TREE (tf->dest_array, 0) == tf->fallthru_label)
+ {
+ /* Reachable by goto to fallthru label only. Redirect it
+ to the new label (already created, sadly), and do not
+ emit the final branch out, or the fallthru label. */
+ tf->fallthru_label = NULL;
+ return;
+ }
+ }
+
+ append_to_statement_list (tf->goto_queue[0].cont_stmt, tf->top_p);
+ maybe_record_in_goto_queue (state, tf->goto_queue[0].cont_stmt);
+}
+
+/* A subroutine of lower_try_finally. There are multiple edges incoming
+ and outgoing from the finally block. Implement this by duplicating the
+ finally block for every destination. */
+
+static void
+lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf)
+{
+ tree finally, new_stmt;
+ tree x;
+
+ finally = TREE_OPERAND (*tf->top_p, 1);
+ *tf->top_p = TREE_OPERAND (*tf->top_p, 0);
+
+ new_stmt = NULL_TREE;
+
+ if (tf->may_fallthru)
+ {
+ x = lower_try_finally_dup_block (finally, state);
+ lower_eh_constructs_1 (state, &x);
+ append_to_statement_list (x, &new_stmt);
+
+ x = lower_try_finally_fallthru_label (tf);
+ x = build1 (GOTO_EXPR, void_type_node, x);
+ append_to_statement_list (x, &new_stmt);
+ }
+
+ if (tf->may_throw)
+ {
+ x = build1 (LABEL_EXPR, void_type_node, tf->eh_label);
+ append_to_statement_list (x, &new_stmt);
+
+ x = lower_try_finally_dup_block (finally, state);
+ lower_eh_constructs_1 (state, &x);
+ append_to_statement_list (x, &new_stmt);
+
+ x = build1 (RESX_EXPR, void_type_node,
+ build_int_2 (get_eh_region_number (tf->region), 0));
+ append_to_statement_list (x, &new_stmt);
+ }
+
+ if (tf->goto_queue)
+ {
+ struct goto_queue_node *q, *qe;
+ tree return_val = NULL;
+ int return_index;
+ tree *labels;
+
+ if (tf->dest_array)
+ return_index = VARRAY_ACTIVE_SIZE (tf->dest_array);
+ else
+ return_index = 0;
+ labels = xcalloc (sizeof (tree), return_index + 1);
+
+ q = tf->goto_queue;
+ qe = q + tf->goto_queue_active;
+ for (; q < qe; q++)
+ {
+ int index = q->index < 0 ? return_index : q->index;
+ tree lab = labels[index];
+ bool build_p = false;
+
+ if (!lab)
+ {
+ labels[index] = lab = create_artificial_label ();
+ build_p = true;
+ }
+
+ if (index == return_index)
+ do_return_redirection (q, lab, NULL, &return_val);
+ else
+ do_goto_redirection (q, lab, NULL);
+
+ if (build_p)
+ {
+ x = build1 (LABEL_EXPR, void_type_node, lab);
+ append_to_statement_list (x, &new_stmt);
+
+ x = lower_try_finally_dup_block (finally, state);
+ lower_eh_constructs_1 (state, &x);
+ append_to_statement_list (x, &new_stmt);
+
+ append_to_statement_list (q->cont_stmt, &new_stmt);
+ maybe_record_in_goto_queue (state, q->cont_stmt);
+ }
+ }
+ replace_goto_queue (tf);
+ free (labels);
+ }
+
+ /* Need to link new stmts after running replace_goto_queue due
+ to not wanting to process the same goto stmts twice. */
+ append_to_statement_list (new_stmt, tf->top_p);
+}
+
+/* A subroutine of lower_try_finally. There are multiple edges incoming
+ and outgoing from the finally block. Implement this by instrumenting
+ each incoming edge and creating a switch statement at the end of the
+ finally block that branches to the appropriate destination. */
+
+static void
+lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
+{
+ struct goto_queue_node *q, *qe;
+ tree return_val = NULL;
+ tree finally, finally_tmp, finally_label;
+ int return_index, eh_index, fallthru_index;
+ int nlabels, ndests, j, last_case_index;
+ tree case_label_vec, switch_stmt, last_case, switch_body;
+ tree x;
+
+ /* Mash the TRY block to the head of the chain. */
+ finally = TREE_OPERAND (*tf->top_p, 1);
+ *tf->top_p = TREE_OPERAND (*tf->top_p, 0);
+
+ /* Lower the finally block itself. */
+ lower_eh_constructs_1 (state, &finally);
+
+ /* Prepare for switch statement generation. */
+ if (tf->dest_array)
+ nlabels = VARRAY_ACTIVE_SIZE (tf->dest_array);
+ else
+ nlabels = 0;
+ return_index = nlabels;
+ eh_index = return_index + tf->may_return;
+ fallthru_index = eh_index + tf->may_throw;
+ ndests = fallthru_index + tf->may_fallthru;
+
+ finally_tmp = create_tmp_var (integer_type_node, "finally_tmp");
+ finally_label = create_artificial_label ();
+
+ case_label_vec = make_tree_vec (ndests);
+ switch_stmt = build (SWITCH_EXPR, integer_type_node, finally_tmp,
+ NULL_TREE, case_label_vec);
+ switch_body = NULL;
+ last_case = NULL;
+ last_case_index = 0;
+
+ /* Begin inserting code for getting to the finally block. Things
+ are done in this order to correspond to the sequence the code is
+ layed out. */
+
+ if (tf->may_fallthru)
+ {
+ x = build (MODIFY_EXPR, void_type_node, finally_tmp,
+ build_int_2 (fallthru_index, 0));
+ append_to_statement_list (x, tf->top_p);
+
+ if (tf->may_throw)
+ {
+ x = build1 (GOTO_EXPR, void_type_node, finally_label);
+ append_to_statement_list (x, tf->top_p);
+ }
+
+
+ last_case = build (CASE_LABEL_EXPR, void_type_node,
+ build_int_2 (fallthru_index, 0), NULL,
+ create_artificial_label ());
+ TREE_VEC_ELT (case_label_vec, last_case_index) = last_case;
+ last_case_index++;
+
+ x = build (LABEL_EXPR, void_type_node, CASE_LABEL (last_case));
+ append_to_statement_list (x, &switch_body);
+
+ x = lower_try_finally_fallthru_label (tf);
+ x = build1 (GOTO_EXPR, void_type_node, x);
+ append_to_statement_list (x, &switch_body);
+ }
+
+ if (tf->may_throw)
+ {
+ x = build1 (LABEL_EXPR, void_type_node, tf->eh_label);
+ append_to_statement_list (x, tf->top_p);
+
+ x = build (MODIFY_EXPR, void_type_node, finally_tmp,
+ build_int_2 (eh_index, 0));
+ append_to_statement_list (x, tf->top_p);
+
+ last_case = build (CASE_LABEL_EXPR, void_type_node,
+ build_int_2 (eh_index, 0), NULL,
+ create_artificial_label ());
+ TREE_VEC_ELT (case_label_vec, last_case_index) = last_case;
+ last_case_index++;
+
+ x = build (LABEL_EXPR, void_type_node, CASE_LABEL (last_case));
+ append_to_statement_list (x, &switch_body);
+ x = build1 (RESX_EXPR, void_type_node,
+ build_int_2 (get_eh_region_number (tf->region), 0));
+ append_to_statement_list (x, &switch_body);
+ }
+
+ x = build1 (LABEL_EXPR, void_type_node, finally_label);
+ append_to_statement_list (x, tf->top_p);
+
+ append_to_statement_list (finally, tf->top_p);
+
+ /* Redirect each incoming goto edge. */
+ q = tf->goto_queue;
+ qe = q + tf->goto_queue_active;
+ j = last_case_index + tf->may_return;
+ last_case_index += nlabels;
+ for (; q < qe; ++q)
+ {
+ tree mod;
+ int switch_id, case_index;
+
+ if (q->index < 0)
+ {
+ mod = build (MODIFY_EXPR, void_type_node, finally_tmp,
+ build_int_2 (return_index, 0));
+ do_return_redirection (q, finally_label, mod, &return_val);
+ switch_id = return_index;
+ }
+ else
+ {
+ mod = build (MODIFY_EXPR, void_type_node, finally_tmp,
+ build_int_2 (q->index, 0));
+ do_goto_redirection (q, finally_label, mod);
+ switch_id = q->index;
+ }
+
+ case_index = j + q->index;
+ if (!TREE_VEC_ELT (case_label_vec, case_index))
+ {
+ last_case = build (CASE_LABEL_EXPR, void_type_node,
+ build_int_2 (switch_id, 0), NULL,
+ create_artificial_label ());
+ TREE_VEC_ELT (case_label_vec, case_index) = last_case;
+
+ x = build (LABEL_EXPR, void_type_node, CASE_LABEL (last_case));
+ append_to_statement_list (x, &switch_body);
+ append_to_statement_list (q->cont_stmt, &switch_body);
+ maybe_record_in_goto_queue (state, q->cont_stmt);
+ }
+ }
+ replace_goto_queue (tf);
+ last_case_index += nlabels;
+
+ /* Make sure that we have a default label, as one is required. */
+ CASE_LOW (last_case) = NULL;
+
+ /* Need to link switch_stmt after running replace_goto_queue due
+ to not wanting to process the same goto stmts twice. */
+ append_to_statement_list (switch_stmt, tf->top_p);
+ append_to_statement_list (switch_body, tf->top_p);
+}
+
+/* Decide whether or not we are going to duplicate the finally block.
+ There are several considerations.
+
+ First, if this is Java, then the finally block contains code
+ written by the user. It has line numbers associated with it,
+ so duplicating the block means it's difficult to set a breakpoint.
+ Since controlling code generation via -g is verboten, we simply
+ never duplicate code without optimization.
+
+ Second, we'd like to prevent egregious code growth. One way to
+ do this is to estimate the size of the finally block, multiply
+ that by the number of copies we'd need to make, and compare against
+ the estimate of the size of the switch machinery we'd have to add. */
+
+static bool
+decide_copy_try_finally (int ndests, tree finally)
+{
+ int f_estimate, sw_estimate;
+
+ if (!optimize)
+ return false;
+
+ /* Finally estimate N times, plus N gotos. */
+ f_estimate = estimate_num_insns (finally);
+ f_estimate = (f_estimate + 1) * ndests;
+
+ /* Switch statement (cost 10), N variable assignments, N gotos. */
+ sw_estimate = 10 + 2 * ndests;
+
+ /* Optimize for size clearly wants our best guess. */
+ if (optimize_size)
+ return f_estimate < sw_estimate;
+
+ /* ??? These numbers are completely made up so far. */
+ if (optimize > 1)
+ return f_estimate < 100 || f_estimate * 2 < sw_estimate;
+ else
+ return f_estimate < 40 || f_estimate * 3 < sw_estimate * 2;
+}
+
+/* A subroutine of lower_eh_constructs_1. Lower a TRY_FINALLY_EXPR nodes
+ to a sequence of labels and blocks, plus the exception region trees
+ that record all the magic. This is complicated by the need to
+ arrange for the FINALLY block to be executed on all exits. */
+
+static void
+lower_try_finally (struct leh_state *state, tree *tp)
+{
+ struct leh_tf_state this_tf;
+ struct leh_state this_state;
+ int ndests;
+
+ /* Process the try block. */
+
+ memset (&this_tf, 0, sizeof (this_tf));
+ this_tf.try_finally_expr = *tp;
+ this_tf.top_p = tp;
+ this_tf.outer = state;
+ if (using_eh_for_cleanups_p)
+ this_tf.region
+ = gen_eh_region_cleanup (state->cur_region, state->prev_try);
+ else
+ this_tf.region = NULL;
+
+ this_state.cur_region = this_tf.region;
+ this_state.prev_try = state->prev_try;
+ this_state.tf = &this_tf;
+
+ lower_eh_constructs_1 (&this_state, &TREE_OPERAND (*tp, 0));
+
+ /* Determine if the try block is escaped through the bottom. */
+ this_tf.may_fallthru = block_may_fallthru (TREE_OPERAND (*tp, 0));
+
+ /* Determine if any exceptions are possible within the try block. */
+ if (using_eh_for_cleanups_p)
+ this_tf.may_throw = get_eh_region_may_contain_throw (this_tf.region);
+ if (this_tf.may_throw)
+ {
+ this_tf.eh_label = create_artificial_label ();
+ set_eh_region_tree_label (this_tf.region, this_tf.eh_label);
+ honor_protect_cleanup_actions (state, &this_state, &this_tf);
+ }
+
+ /* Sort the goto queue for efficient searching later. */
+ if (this_tf.goto_queue_active > 1)
+ qsort (this_tf.goto_queue, this_tf.goto_queue_active,
+ sizeof (struct goto_queue_node), goto_queue_cmp);
+
+ /* Determine how many edges (still) reach the finally block. Or rather,
+ how many destinations are reached by the finally block. Use this to
+ determine how we process the finally block itself. */
+
+ if (this_tf.dest_array)
+ ndests = VARRAY_ACTIVE_SIZE (this_tf.dest_array);
+ else
+ ndests = 0;
+ ndests += this_tf.may_fallthru;
+ ndests += this_tf.may_return;
+ ndests += this_tf.may_throw;
+
+ /* If the FINALLY block is not reachable, dike it out. */
+ if (ndests == 0)
+ *tp = TREE_OPERAND (*tp, 0);
+
+ /* If the finally block doesn't fall through, then any destination
+ we might try to impose there isn't reached either. There may be
+ some minor amount of cleanup and redirection still needed. */
+ else if (!block_may_fallthru (TREE_OPERAND (*tp, 1)))
+ lower_try_finally_nofallthru (state, &this_tf);
+
+ /* We can easily special-case redirection to a single destination. */
+ else if (ndests == 1)
+ lower_try_finally_onedest (state, &this_tf);
+
+ else if (decide_copy_try_finally (ndests, TREE_OPERAND (*tp, 1)))
+ lower_try_finally_copy (state, &this_tf);
+ else
+ lower_try_finally_switch (state, &this_tf);
+
+ /* If someone requested we add a label at the end of the transformed
+ block, do so. */
+ if (this_tf.fallthru_label)
+ {
+ tree x = build1 (LABEL_EXPR, void_type_node, this_tf.fallthru_label);
+ append_to_statement_list (x, tp);
+ }
+
+ if (this_tf.goto_queue)
+ free (this_tf.goto_queue);
+}
+
+/* A subroutine of lower_eh_constructs_1. Lower a TRY_CATCH_EXPR with a
+ list of CATCH_EXPR nodes to a sequence of labels and blocks, plus the
+ exception region trees that record all the magic. */
+
+static void
+lower_catch (struct leh_state *state, tree *tp)
+{
+ struct eh_region *try_region;
+ struct leh_state this_state;
+ tree_stmt_iterator i;
+ tree out_label;
+
+ try_region = gen_eh_region_try (state->cur_region);
+ this_state.cur_region = try_region;
+ this_state.prev_try = try_region;
+ this_state.tf = state->tf;
+
+ lower_eh_constructs_1 (&this_state, &TREE_OPERAND (*tp, 0));
+
+ if (!get_eh_region_may_contain_throw (try_region))
+ {
+ *tp = TREE_OPERAND (*tp, 0);
+ return;
+ }
+
+ out_label = NULL;
+ for (i = tsi_start (TREE_OPERAND (*tp, 1)); !tsi_end_p (i); )
+ {
+ struct eh_region *catch_region;
+ tree catch, x, eh_label;
+
+ catch = tsi_stmt (i);
+ catch_region = gen_eh_region_catch (try_region, CATCH_TYPES (catch));
+
+ this_state.cur_region = catch_region;
+ this_state.prev_try = state->prev_try;
+ lower_eh_constructs_1 (&this_state, &CATCH_BODY (catch));
+
+ eh_label = create_artificial_label ();
+ set_eh_region_tree_label (catch_region, eh_label);
+
+ x = build1 (LABEL_EXPR, void_type_node, eh_label);
+ tsi_link_before (&i, x, TSI_SAME_STMT);
+
+ if (block_may_fallthru (CATCH_BODY (catch)))
+ {
+ if (!out_label)
+ out_label = create_artificial_label ();
+
+ x = build1 (GOTO_EXPR, void_type_node, out_label);
+ append_to_statement_list (x, &CATCH_BODY (catch));
+ }
+
+ tsi_link_before (&i, CATCH_BODY (catch), TSI_SAME_STMT);
+ tsi_delink (&i);
+ }
+
+ frob_into_branch_around (tp, NULL, out_label);
+}
+
+/* A subroutine of lower_eh_constructs_1. Lower a TRY_CATCH_EXPR with a
+ EH_FILTER_EXPR to a sequence of labels and blocks, plus the exception
+ region trees that record all the magic. */
+
+static void
+lower_eh_filter (struct leh_state *state, tree *tp)
+{
+ struct leh_state this_state;
+ struct eh_region *this_region;
+ tree inner = expr_first (TREE_OPERAND (*tp, 1));
+ tree eh_label;
+
+ if (EH_FILTER_MUST_NOT_THROW (inner))
+ this_region = gen_eh_region_must_not_throw (state->cur_region);
+ else
+ this_region = gen_eh_region_allowed (state->cur_region,
+ EH_FILTER_TYPES (inner));
+ this_state = *state;
+ this_state.cur_region = this_region;
+
+ lower_eh_constructs_1 (&this_state, &TREE_OPERAND (*tp, 0));
+
+ if (!get_eh_region_may_contain_throw (this_region))
+ {
+ *tp = TREE_OPERAND (*tp, 0);
+ return;
+ }
+
+ lower_eh_constructs_1 (state, &EH_FILTER_FAILURE (inner));
+ TREE_OPERAND (*tp, 1) = EH_FILTER_FAILURE (inner);
+
+ eh_label = create_artificial_label ();
+ set_eh_region_tree_label (this_region, eh_label);
+
+ frob_into_branch_around (tp, eh_label, NULL);
+}
+
+/* Implement a cleanup expression. This is similar to try-finally,
+ except that we only execute the cleanup block for exception edges. */
+
+static void
+lower_cleanup (struct leh_state *state, tree *tp)
+{
+ struct leh_state this_state;
+ struct eh_region *this_region;
+ struct leh_tf_state fake_tf;
+
+ /* If not using eh, then exception-only cleanups are no-ops. */
+ if (!flag_exceptions)
+ {
+ *tp = TREE_OPERAND (*tp, 0);
+ lower_eh_constructs_1 (state, tp);
+ return;
+ }
+
+ this_region = gen_eh_region_cleanup (state->cur_region, state->prev_try);
+ this_state = *state;
+ this_state.cur_region = this_region;
+
+ lower_eh_constructs_1 (&this_state, &TREE_OPERAND (*tp, 0));
+
+ if (!get_eh_region_may_contain_throw (this_region))
+ {
+ *tp = TREE_OPERAND (*tp, 0);
+ return;
+ }
+
+ /* Build enough of a try-finally state so that we can reuse
+ honor_protect_cleanup_actions. */
+ memset (&fake_tf, 0, sizeof (fake_tf));
+ fake_tf.top_p = tp;
+ fake_tf.outer = state;
+ fake_tf.region = this_region;
+ fake_tf.may_fallthru = block_may_fallthru (TREE_OPERAND (*tp, 0));
+ fake_tf.may_throw = true;
+
+ fake_tf.eh_label = create_artificial_label ();
+ set_eh_region_tree_label (this_region, fake_tf.eh_label);
+
+ honor_protect_cleanup_actions (state, NULL, &fake_tf);
+
+ if (fake_tf.may_throw)
+ {
+ /* In this case honor_protect_cleanup_actions had nothing to do,
+ and we should process this normally. */
+ lower_eh_constructs_1 (state, &TREE_OPERAND (*tp, 1));
+ frob_into_branch_around (tp, fake_tf.eh_label, fake_tf.fallthru_label);
+ }
+ else
+ {
+ /* In this case honor_protect_cleanup_actions did nearly all of
+ the work. All we have left is to append the fallthru_label. */
+
+ *tp = TREE_OPERAND (*tp, 0);
+ if (fake_tf.fallthru_label)
+ {
+ tree x = build1 (LABEL_EXPR, void_type_node, fake_tf.fallthru_label);
+ append_to_statement_list (x, tp);
+ }
+ }
+}
+
+/* Main loop for lowering eh constructs. */
+
+static void
+lower_eh_constructs_1 (struct leh_state *state, tree *tp)
+{
+ tree_stmt_iterator i;
+ tree t = *tp;
+
+ switch (TREE_CODE (t))
+ {
+ case COND_EXPR:
+ lower_eh_constructs_1 (state, &COND_EXPR_THEN (t));
+ lower_eh_constructs_1 (state, &COND_EXPR_ELSE (t));
+ break;
+
+ case CALL_EXPR:
+ /* Look for things that can throw exceptions, and record them. */
+ if (state->cur_region && tree_could_throw_p (t))
+ {
+ record_stmt_eh_region (state->cur_region, t);
+ note_eh_region_may_contain_throw (state->cur_region);
+ }
+ break;
+
+ case MODIFY_EXPR:
+ /* Look for things that can throw exceptions, and record them. */
+ if (state->cur_region && tree_could_throw_p (t))
+ {
+ record_stmt_eh_region (state->cur_region, t);
+ note_eh_region_may_contain_throw (state->cur_region);
+
+ /* ??? For the benefit of calls.c, converting all this to rtl,
+ we need to record the call expression, not just the outer
+ modify statement. */
+ if (TREE_CODE (TREE_OPERAND (t, 1)) == CALL_EXPR)
+ record_stmt_eh_region (state->cur_region, TREE_OPERAND (t, 1));
+ }
+ break;
+
+ case GOTO_EXPR:
+ case RETURN_EXPR:
+ maybe_record_in_goto_queue (state, t);
+ break;
+ case SWITCH_EXPR:
+ verify_norecord_switch_expr (state, t);
+ break;
+
+ case TRY_FINALLY_EXPR:
+ lower_try_finally (state, tp);
+ break;
+
+ case TRY_CATCH_EXPR:
+ i = tsi_start (TREE_OPERAND (t, 1));
+ switch (TREE_CODE (tsi_stmt (i)))
+ {
+ case CATCH_EXPR:
+ lower_catch (state, tp);
+ break;
+ case EH_FILTER_EXPR:
+ lower_eh_filter (state, tp);
+ break;
+ default:
+ lower_cleanup (state, tp);
+ break;
+ }
+ break;
+
+ case STATEMENT_LIST:
+ for (i = tsi_start (t); !tsi_end_p (i); )
+ {
+ lower_eh_constructs_1 (state, tsi_stmt_ptr (i));
+ t = tsi_stmt (i);
+ if (TREE_CODE (t) == STATEMENT_LIST)
+ {
+ tsi_link_before (&i, t, TSI_SAME_STMT);
+ tsi_delink (&i);
+ }
+ else
+ tsi_next (&i);
+ }
+ break;
+
+ default:
+ /* A type, a decl, or some kind of statement that we're not
+ interested in. Don't walk them. */
+ break;
+ }
+}
+
+static void
+lower_eh_constructs (void)
+{
+ struct leh_state null_state;
+ tree *tp = &DECL_SAVED_TREE (current_function_decl);
+
+ finally_tree = htab_create (31, struct_ptr_hash, struct_ptr_eq, free);
+ throw_stmt_table = htab_create_ggc (31, struct_ptr_hash, struct_ptr_eq, free);
+
+ collect_finally_tree (*tp, NULL);
+
+ memset (&null_state, 0, sizeof (null_state));
+ lower_eh_constructs_1 (&null_state, tp);
+
+ htab_delete (finally_tree);
+
+ collect_eh_region_array ();
+}
+
+struct tree_opt_pass pass_lower_eh =
+{
+ "eh", /* name */
+ NULL, /* gate */
+ lower_eh_constructs, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_EH, /* tv_id */
+ PROP_gimple_lcf, /* properties_required */
+ PROP_gimple_leh, /* properties_provided */
+ PROP_gimple_lcf, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func /* todo_flags_finish */
+};
+
+
+/* Construct EH edges for STMT. */
+
+static void
+make_eh_edge (struct eh_region *region, void *data)
+{
+ tree stmt, lab;
+ basic_block src, dst;
+
+ stmt = data;
+ lab = get_eh_region_tree_label (region);
+
+ src = bb_for_stmt (stmt);
+ dst = label_to_block (lab);
+
+ make_edge (src, dst, EDGE_ABNORMAL | EDGE_EH);
+}
+
+void
+make_eh_edges (tree stmt)
+{
+ int region_nr;
+ bool is_resx;
+
+ if (TREE_CODE (stmt) == RESX_EXPR)
+ {
+ region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0));
+ is_resx = true;
+ }
+ else
+ {
+ region_nr = lookup_stmt_eh_region (stmt);
+ if (region_nr < 0)
+ return;
+ is_resx = false;
+ }
+
+ foreach_reachable_handler (region_nr, is_resx, make_eh_edge, stmt);
+}
+
+
+
+/* Return true if the expr can trap, as in dereferencing an
+ invalid pointer location. */
+
+bool
+tree_could_trap_p (tree expr)
+{
+ enum tree_code code = TREE_CODE (expr);
+ tree t;
+
+ switch (code)
+ {
+ case ARRAY_REF:
+ case COMPONENT_REF:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ case BIT_FIELD_REF:
+ t = get_base_address (expr);
+ return !t || TREE_CODE (t) == INDIRECT_REF;
+
+ case INDIRECT_REF:
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case EXACT_DIV_EXPR:
+ case CEIL_MOD_EXPR:
+ case FLOOR_MOD_EXPR:
+ case ROUND_MOD_EXPR:
+ case TRUNC_MOD_EXPR:
+ return true;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+
+bool
+tree_could_throw_p (tree t)
+{
+ if (!flag_exceptions)
+ return false;
+ if (TREE_CODE (t) == MODIFY_EXPR)
+ {
+ tree sub = TREE_OPERAND (t, 1);
+ if (TREE_CODE (sub) == CALL_EXPR)
+ t = sub;
+ else
+ {
+ if (flag_non_call_exceptions)
+ {
+ if (tree_could_trap_p (sub))
+ return true;
+ return tree_could_trap_p (TREE_OPERAND (t, 0));
+ }
+ return false;
+ }
+ }
+
+ if (TREE_CODE (t) == CALL_EXPR)
+ return (call_expr_flags (t) & ECF_NOTHROW) == 0;
+
+ return false;
+}
+
+bool
+tree_can_throw_internal (tree stmt)
+{
+ int region_nr = lookup_stmt_eh_region (stmt);
+ if (region_nr < 0)
+ return false;
+ return can_throw_internal_1 (region_nr);
+}
+
+bool
+tree_can_throw_external (tree stmt)
+{
+ int region_nr = lookup_stmt_eh_region (stmt);
+ if (region_nr < 0)
+ return false;
+ return can_throw_external_1 (region_nr);
+}
+
+#include "gt-tree-eh.h"
diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h
new file mode 100644
index 00000000000..3505b0c4f19
--- /dev/null
+++ b/gcc/tree-flow-inline.h
@@ -0,0 +1,604 @@
+/* Inline functions for tree-flow.h
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ Contributed by Diego Novillo <dnovillo@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#ifndef _TREE_FLOW_INLINE_H
+#define _TREE_FLOW_INLINE_H 1
+
+/* Inline functions for manipulating various data structures defined in
+ tree-flow.h. See tree-flow.h for documentation. */
+
+static inline var_ann_t
+var_ann (tree t)
+{
+#if defined ENABLE_CHECKING
+ if (t == NULL_TREE
+ || !DECL_P (t)
+ || (t->common.ann
+ && t->common.ann->common.type != VAR_ANN))
+ abort ();
+#endif
+
+ return (var_ann_t) t->common.ann;
+}
+
+static inline var_ann_t
+get_var_ann (tree var)
+{
+ var_ann_t ann = var_ann (var);
+ return (ann) ? ann : create_var_ann (var);
+}
+
+static inline stmt_ann_t
+stmt_ann (tree t)
+{
+#if defined ENABLE_CHECKING
+ if (!is_gimple_stmt (t) && !is_essa_node (t))
+ abort ();
+#endif
+
+ return (stmt_ann_t) t->common.ann;
+}
+
+static inline stmt_ann_t
+get_stmt_ann (tree stmt)
+{
+ stmt_ann_t ann = stmt_ann (stmt);
+ return (ann) ? ann : create_stmt_ann (stmt);
+}
+
+static inline ssa_name_ann_t
+ssa_name_ann (tree t)
+{
+#if defined ENABLE_CHECKING
+ if (t == NULL_TREE
+ || TREE_CODE (t) != SSA_NAME
+ || (t->common.ann
+ && t->common.ann->common.type != SSA_NAME_ANN))
+ abort ();
+#endif
+
+ return (ssa_name_ann_t) t->common.ann;
+}
+
+static inline ssa_name_ann_t
+get_ssa_name_ann (tree var)
+{
+ ssa_name_ann_t ann = ssa_name_ann (var);
+ return (ann) ? ann : create_ssa_name_ann (var);
+}
+
+
+static inline enum tree_ann_type
+ann_type (tree_ann ann)
+{
+ return ann->common.type;
+}
+
+static inline basic_block
+bb_for_stmt (tree t)
+{
+ stmt_ann_t ann = stmt_ann (t);
+ return ann ? ann->bb : NULL;
+}
+
+static inline varray_type
+may_aliases (tree var)
+{
+ var_ann_t ann = var_ann (var);
+ return ann ? ann->may_aliases : NULL;
+}
+
+static inline bool
+has_hidden_use (tree var)
+{
+ var_ann_t ann = var_ann (var);
+ return ann ? ann->has_hidden_use : false;
+}
+
+static inline void
+set_has_hidden_use (tree var)
+{
+ var_ann_t ann = var_ann (var);
+ if (ann == NULL)
+ ann = create_var_ann (var);
+ ann->has_hidden_use = 1;
+}
+
+static inline int
+get_lineno (tree expr)
+{
+ if (expr == NULL_TREE)
+ return -1;
+
+ if (TREE_CODE (expr) == COMPOUND_EXPR)
+ expr = TREE_OPERAND (expr, 0);
+
+ if (! EXPR_LOCUS (expr))
+ return -1;
+
+ return EXPR_LINENO (expr);
+}
+
+static inline const char *
+get_filename (tree expr)
+{
+ if (expr == NULL_TREE)
+ return "???";
+
+ if (TREE_CODE (expr) == COMPOUND_EXPR)
+ expr = TREE_OPERAND (expr, 0);
+
+ if (EXPR_LOCUS (expr) && EXPR_FILENAME (expr))
+ return EXPR_FILENAME (expr);
+ else
+ return "???";
+}
+
+static inline void
+modify_stmt (tree t)
+{
+ stmt_ann_t ann = stmt_ann (t);
+ if (ann == NULL)
+ ann = create_stmt_ann (t);
+ ann->modified = 1;
+}
+
+static inline void
+unmodify_stmt (tree t)
+{
+ stmt_ann_t ann = stmt_ann (t);
+ if (ann == NULL)
+ ann = create_stmt_ann (t);
+ ann->modified = 0;
+}
+
+static inline bool
+stmt_modified_p (tree t)
+{
+ stmt_ann_t ann = stmt_ann (t);
+
+ /* Note that if the statement doesn't yet have an annotation, we consider it
+ modified. This will force the next call to get_stmt_operands to scan the
+ statement. */
+ return ann ? ann->modified : true;
+}
+
+static inline def_optype
+get_def_ops (stmt_ann_t ann)
+{
+ return ann ? ann->def_ops : NULL;
+}
+
+static inline use_optype
+get_use_ops (stmt_ann_t ann)
+{
+ return ann ? ann->use_ops : NULL;
+}
+
+static inline vdef_optype
+get_vdef_ops (stmt_ann_t ann)
+{
+ return ann ? ann->vdef_ops : NULL;
+}
+
+static inline vuse_optype
+get_vuse_ops (stmt_ann_t ann)
+{
+ return ann ? ann->vuse_ops : NULL;
+}
+
+static inline tree *
+get_use_op_ptr (use_optype uses, unsigned int index)
+{
+#ifdef ENABLE_CHECKING
+ if (index >= uses->num_uses)
+ abort();
+#endif
+ return uses->uses[index];
+}
+
+static inline tree *
+get_def_op_ptr (def_optype defs, unsigned int index)
+{
+#ifdef ENABLE_CHECKING
+ if (index >= defs->num_defs)
+ abort();
+#endif
+ return defs->defs[index];
+}
+
+static inline tree *
+get_vdef_result_ptr(vdef_optype vdefs, unsigned int index)
+{
+#ifdef ENABLE_CHECKING
+ if (index >= vdefs->num_vdefs)
+ abort();
+#endif
+ return &(vdefs->vdefs[index * 2]);
+}
+
+static inline tree *
+get_vdef_op_ptr(vdef_optype vdefs, unsigned int index)
+{
+#ifdef ENABLE_CHECKING
+ if (index >= vdefs->num_vdefs)
+ abort();
+#endif
+ return &(vdefs->vdefs[index * 2 + 1]);
+}
+
+static inline tree *
+get_vuse_op_ptr(vuse_optype vuses, unsigned int index)
+{
+#ifdef ENABLE_CHECKING
+ if (index >= vuses->num_vuses)
+ abort();
+#endif
+ return &(vuses->vuses[index]);
+}
+
+static inline void
+start_ssa_stmt_operands (tree stmt ATTRIBUTE_UNUSED)
+{
+#ifdef ENABLE_CHECKING
+ verify_start_operands (stmt);
+#endif
+}
+
+static inline bitmap
+addresses_taken (tree stmt)
+{
+ stmt_ann_t ann = stmt_ann (stmt);
+ return ann ? ann->addresses_taken : NULL;
+}
+
+static dataflow_t
+get_immediate_uses (tree stmt)
+{
+ stmt_ann_t ann = stmt_ann (stmt);
+ return ann ? ann->df : NULL;
+}
+
+static inline int
+num_immediate_uses (dataflow_t df)
+{
+ varray_type imm;
+
+ if (!df)
+ return 0;
+
+ imm = df->immediate_uses;
+ if (!imm)
+ return df->uses[1] ? 2 : 1;
+
+ return VARRAY_ACTIVE_SIZE (imm) + 2;
+}
+
+static inline tree
+immediate_use (dataflow_t df, int num)
+{
+#ifdef ENABLE_CHECKING
+ if (num >= num_immediate_uses (df))
+ abort ();
+#endif
+ if (num < 2)
+ return df->uses[num];
+ return VARRAY_TREE (df->immediate_uses, num - 2);
+}
+
+static inline bb_ann_t
+bb_ann (basic_block bb)
+{
+ return (bb_ann_t)bb->tree_annotations;
+}
+
+static inline tree
+phi_nodes (basic_block bb)
+{
+ if (bb->index < 0)
+ return NULL;
+ return bb_ann (bb)->phi_nodes;
+}
+
+/* Set list of phi nodes of a basic block BB to L. */
+
+static inline void
+set_phi_nodes (basic_block bb, tree l)
+{
+ tree phi;
+
+ bb_ann (bb)->phi_nodes = l;
+ for (phi = l; phi; phi = TREE_CHAIN (phi))
+ set_bb_for_stmt (phi, bb);
+}
+
+/* Return the phi index number for an edge. */
+static inline int
+phi_arg_from_edge (tree phi, edge e)
+{
+ int i;
+#if defined ENABLE_CHECKING
+ if (!phi || TREE_CODE (phi) != PHI_NODE)
+ abort();
+#endif
+
+ for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ if (PHI_ARG_EDGE (phi, i) == e)
+ return i;
+
+ return -1;
+}
+
+
+/* Return the phi argument number for an edge. */
+static inline struct phi_arg_d *
+phi_element_for_edge (tree phi, edge e)
+{
+ int i;
+
+ i = phi_arg_from_edge (phi, e);
+ if (i != -1)
+ return &(PHI_ARG_ELT (phi, i));
+ else
+ return (struct phi_arg_d *)NULL;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static inline bool
+is_exec_stmt (tree t)
+{
+ return (t && !IS_EMPTY_STMT (t) && t != error_mark_node);
+}
+
+
+/* Return true if this stmt can be the target of a control transfer stmt such
+ as a goto. */
+static inline bool
+is_label_stmt (tree t)
+{
+ if (t)
+ switch (TREE_CODE (t))
+ {
+ case LABEL_DECL:
+ case LABEL_EXPR:
+ case CASE_LABEL_EXPR:
+ return true;
+ default:
+ return false;
+ }
+ return false;
+}
+
+static inline bool
+may_propagate_copy (tree dest, tree orig)
+{
+ /* FIXME. GIMPLE is allowing pointer assignments and comparisons of
+ pointers that have different alias sets. This means that these
+ pointers will have different memory tags associated to them.
+
+ If we allow copy propagation in these cases, statements de-referencing
+ the new pointer will now have a reference to a different memory tag
+ with potentially incorrect SSA information.
+
+ This was showing up in libjava/java/util/zip/ZipFile.java with code
+ like:
+
+ struct java.io.BufferedInputStream *T.660;
+ struct java.io.BufferedInputStream *T.647;
+ struct java.io.InputStream *is;
+ struct java.io.InputStream *is.662;
+ [ ... ]
+ T.660 = T.647;
+ is = T.660; <-- This ought to be type-casted
+ is.662 = is;
+
+ Also, f/name.c exposed a similar problem with a COND_EXPR predicate
+ that was causing DOM to generate and equivalence with two pointers of
+ alias-incompatible types:
+
+ struct _ffename_space *n;
+ struct _ffename *ns;
+ [ ... ]
+ if (n == ns)
+ goto lab;
+ ...
+ lab:
+ return n;
+
+ I think that GIMPLE should emit the appropriate type-casts. For the
+ time being, blocking copy-propagation in these cases is the safe thing
+ to do. */
+ if (TREE_CODE (dest) == SSA_NAME
+ && TREE_CODE (orig) == SSA_NAME
+ && POINTER_TYPE_P (TREE_TYPE (dest))
+ && POINTER_TYPE_P (TREE_TYPE (orig)))
+ {
+ tree mt_dest = var_ann (SSA_NAME_VAR (dest))->type_mem_tag;
+ tree mt_orig = var_ann (SSA_NAME_VAR (orig))->type_mem_tag;
+ if (mt_dest && mt_orig && mt_dest != mt_orig)
+ return false;
+ }
+
+ /* If the destination is a SSA_NAME for a virtual operand, then we have
+ some special cases to handle. */
+ if (TREE_CODE (dest) == SSA_NAME && !is_gimple_reg (dest))
+ {
+ /* If both operands are SSA_NAMEs referring to virtual operands, then
+ we can always propagate. */
+ if (TREE_CODE (orig) == SSA_NAME)
+ {
+ if (!is_gimple_reg (orig))
+ return true;
+
+#ifdef ENABLE_CHECKING
+ /* If we have one real and one virtual operand, then something has
+ gone terribly wrong. */
+ if (is_gimple_reg (orig))
+ abort ();
+#endif
+ }
+
+ /* We have a "copy" from something like a constant into a virtual
+ operand. Reject these. */
+ return false;
+ }
+
+ return (!SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest)
+ && (TREE_CODE (orig) != SSA_NAME
+ || !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig))
+ && !DECL_HARD_REGISTER (SSA_NAME_VAR (dest)));
+}
+
+static inline void
+set_default_def (tree var, tree def)
+{
+ var_ann_t ann = var_ann (var);
+ if (ann == NULL)
+ ann = create_var_ann (var);
+ ann->default_def = def;
+}
+
+static inline tree
+default_def (tree var)
+{
+ var_ann_t ann = var_ann (var);
+ return ann ? ann->default_def : NULL_TREE;
+}
+
+/* PHI nodes should contain only ssa_names and invariants. A test
+ for ssa_name is definitely simpler; don't let invalid contents
+ slip in in the meantime. */
+
+static inline bool
+phi_ssa_name_p (tree t)
+{
+ if (TREE_CODE (t) == SSA_NAME)
+ return true;
+#ifdef ENABLE_CHECKING
+ if (!is_gimple_min_invariant (t))
+ abort ();
+#endif
+ return false;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static inline block_stmt_iterator
+bsi_start (basic_block bb)
+{
+ block_stmt_iterator bsi;
+ if (bb->stmt_list)
+ bsi.tsi = tsi_start (bb->stmt_list);
+ else
+ {
+#ifdef ENABLE_CHECKING
+ if (bb->index >= 0)
+ abort ();
+#endif
+ bsi.tsi.ptr = NULL;
+ bsi.tsi.container = NULL;
+ }
+ bsi.bb = bb;
+ return bsi;
+}
+
+static inline block_stmt_iterator
+bsi_last (basic_block bb)
+{
+ block_stmt_iterator bsi;
+ if (bb->stmt_list)
+ bsi.tsi = tsi_last (bb->stmt_list);
+ else
+ {
+#ifdef ENABLE_CHECKING
+ if (bb->index >= 0)
+ abort ();
+#endif
+ bsi.tsi.ptr = NULL;
+ bsi.tsi.container = NULL;
+ }
+ bsi.bb = bb;
+ return bsi;
+}
+
+static inline bool
+bsi_end_p (block_stmt_iterator i)
+{
+ return tsi_end_p (i.tsi);
+}
+
+static inline void
+bsi_next (block_stmt_iterator *i)
+{
+ tsi_next (&i->tsi);
+}
+
+static inline void
+bsi_prev (block_stmt_iterator *i)
+{
+ tsi_prev (&i->tsi);
+}
+
+static inline tree
+bsi_stmt (block_stmt_iterator i)
+{
+ return tsi_stmt (i.tsi);
+}
+
+static inline tree *
+bsi_stmt_ptr (block_stmt_iterator i)
+{
+ return tsi_stmt_ptr (i.tsi);
+}
+
+static inline bool
+may_be_aliased (tree var)
+{
+ return (TREE_ADDRESSABLE (var)
+ || decl_function_context (var) != current_function_decl);
+}
+
+static inline bool
+is_call_clobbered (tree var)
+{
+ return needs_to_live_in_memory (var)
+ || bitmap_bit_p (call_clobbered_vars, var_ann (var)->uid);
+}
+
+static inline void
+mark_call_clobbered (tree var)
+{
+ var_ann_t ann = var_ann (var);
+ /* Call-clobbered variables need to live in memory. */
+ DECL_NEEDS_TO_LIVE_IN_MEMORY_INTERNAL (var) = 1;
+ bitmap_set_bit (call_clobbered_vars, ann->uid);
+}
+
+static inline void
+mark_non_addressable (tree var)
+{
+ bitmap_clear_bit (call_clobbered_vars, var_ann (var)->uid);
+ DECL_NEEDS_TO_LIVE_IN_MEMORY_INTERNAL (var) = 0;
+ TREE_ADDRESSABLE (var) = 0;
+}
+
+#endif /* _TREE_FLOW_INLINE_H */
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
new file mode 100644
index 00000000000..66995338a40
--- /dev/null
+++ b/gcc/tree-flow.h
@@ -0,0 +1,597 @@
+/* Data and Control Flow Analysis for Trees.
+ Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Diego Novillo <dnovillo@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#ifndef _TREE_FLOW_H
+#define _TREE_FLOW_H 1
+
+#include "bitmap.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "hashtab.h"
+#include "tree-gimple.h"
+#include "tree-ssa-operands.h"
+
+/* Forward declare structures for the garbage collector GTY markers. */
+#ifndef GCC_BASIC_BLOCK_H
+struct edge_def;
+typedef struct edge_def *edge;
+struct basic_block_def;
+typedef struct basic_block_def *basic_block;
+#endif
+
+/*---------------------------------------------------------------------------
+ Tree annotations stored in tree_common.ann
+---------------------------------------------------------------------------*/
+enum tree_ann_type { TREE_ANN_COMMON, VAR_ANN, STMT_ANN, SSA_NAME_ANN };
+
+struct tree_ann_common_d GTY(())
+{
+ /* Annotation type. */
+ enum tree_ann_type type;
+};
+
+/* It is advantageous to avoid things like life analysis for variables which
+ do not need PHI nodes. This enum describes whether or not a particular
+ variable may need a PHI node. */
+
+enum need_phi_state {
+ /* This is the default. If we are still in this state after finding
+ all the definition and use sites, then we will assume the variable
+ needs PHI nodes. This is probably an overly conservative assumption. */
+ NEED_PHI_STATE_UNKNOWN,
+
+ /* This state indicates that we have seen one or more sets of the
+ variable in a single basic block and that the sets dominate all
+ uses seen so far. If after finding all definition and use sites
+ we are still in this state, then the variable does not need any
+ PHI nodes. */
+ NEED_PHI_STATE_NO,
+
+ /* This state indicates that we have either seen multiple definitions of
+ the variable in multiple blocks, or that we encountered a use in a
+ block that was not dominated by the block containing the set(s) of
+ this variable. This variable is assumed to need PHI nodes. */
+ NEED_PHI_STATE_MAYBE
+};
+
+
+/* When computing aliasing information, we represent the memory pointed-to
+ by pointers with artificial variables called "memory tags" (MT). There
+ are two kinds of tags: type and name. Type tags (TMT) are used in
+ type-based alias analysis, they represent all the pointed-to locations
+ and variables of the same alias set class. Name tags (NMT) are used in
+ flow-sensitive points-to alias analysis, they represent the variables
+ and memory locations pointed-to by a specific SSA_NAME pointer. */
+enum mem_tag_kind {
+ /* This variable is not a memory tag. */
+ NOT_A_TAG,
+
+ /* This variable is a type memory tag (TMT). */
+ TYPE_TAG,
+
+ /* This variable is a name memory tag (NMT). */
+ NAME_TAG
+};
+
+struct var_ann_d GTY(())
+{
+ struct tree_ann_common_d common;
+
+ /* Nonzero if this variable has uses which may not appear
+ in the IL. This can happen in the following cases:
+
+ 1. If the variable is used in a variable length
+ array declaration.
+
+ 2. If the variable is the return value in a C++
+ function where the named return value optimization
+ has been performed. */
+ unsigned has_hidden_use : 1;
+
+ /* Used by the out of SSA pass to determine whether this variable has
+ been seen yet or not. */
+ unsigned out_of_ssa_tag : 1;
+
+ /* Used when building root_var structures in tree_ssa_live.[ch]. */
+ unsigned root_var_processed : 1;
+
+ /* If nonzero, this variable is a memory tag. */
+ ENUM_BITFIELD (mem_tag_kind) mem_tag_kind : 2;
+
+ /* Nonzero if this variable is an alias tag that represents references to
+ other variables (i.e., this variable appears in the MAY_ALIASES array
+ of other variables). */
+ unsigned is_alias_tag : 1;
+
+ /* Nonzero if this variable was used after SSA optimizations were
+ applied. We set this when translating out of SSA form. */
+ unsigned used : 1;
+
+ /* This field indicates whether or not the variable may need PHI nodes.
+ See the enum's definition for more detailed information about the
+ states. */
+ ENUM_BITFIELD (need_phi_state) need_phi_state : 2;
+
+ /* An artificial variable representing the memory location pointed-to by
+ all the pointers that TBAA (type-based alias analysis) considers
+ to be aliased. If the variable is not a pointer or if it is never
+ dereferenced, this must be NULL. */
+ tree type_mem_tag;
+
+ /* Variables that may alias this variable. */
+ varray_type may_aliases;
+
+ /* Unique ID of this variable. */
+ size_t uid;
+
+ /* Used when going out of SSA form to indicate which partition this
+ variable represents storage for. */
+ unsigned partition;
+
+ /* Used by the root-var object in tree-ssa-live.[ch]. */
+ unsigned root_index;
+
+ /* Default definition for this symbol. If this field is not NULL, it
+ means that the first reference to this variable in the function is a
+ USE or a VUSE. In those cases, the SSA renamer creates an SSA name
+ for this variable with an empty defining statement. */
+ tree default_def;
+
+ /* During into-ssa and the dominator optimizer, this field holds the
+ current version of this variable (an SSA_NAME).
+
+ This was previously two varrays (one in into-ssa the other in the
+ dominator optimizer). That is wasteful, particularly since the
+ dominator optimizer calls into-ssa resulting in having two varrays
+ live at the same time and this can happen for each call to the
+ dominator optimizer. */
+ tree current_def;
+};
+
+
+struct dataflow_d GTY(())
+{
+ /* Immediate uses. This is a list of all the statements and PHI nodes
+ that are immediately reached by the definitions made in this
+ statement. */
+ varray_type immediate_uses;
+
+ /* Use this array for very small numbers of uses instead of the varray. */
+ tree uses[2];
+
+ /* Reached uses. This is a list of all the possible program statements
+ that may be reached directly or indirectly by definitions made in this
+ statement. Notice that this is a superset of IMMEDIATE_USES.
+ For instance, given the following piece of code:
+
+ 1 a1 = 10;
+ 2 if (a1 > 3)
+ 3 a2 = a1 + 5;
+ 4 a3 = PHI (a1, a2)
+ 5 b1 = a3 - 2;
+
+ IMMEDIATE_USES for statement #1 are all those statements that use a1
+ directly (i.e., #2, #3 and #4). REACHED_USES for statement #1 also
+ includes statement #5 because 'a1' could reach 'a3' via the PHI node
+ at statement #4. The set of REACHED_USES is then the transitive
+ closure over all the PHI nodes in the IMMEDIATE_USES set. */
+
+ /* Reaching definitions. Similarly to REACHED_USES, the set
+ REACHING_DEFS is the set of all the statements that make definitions
+ that may reach this statement. Notice that we don't need to have a
+ similar entry for immediate definitions, as these are represented by
+ the SSA_NAME nodes themselves (each SSA_NAME node contains a pointer
+ to the statement that makes that definition). */
+};
+
+typedef struct dataflow_d *dataflow_t;
+
+
+struct stmt_ann_d GTY(())
+{
+ struct tree_ann_common_d common;
+
+ /* Nonzero if the statement has been modified (meaning that the operands
+ need to be scanned again). */
+ unsigned modified : 1;
+
+ /* Nonzero if the statement is in the CCP worklist and has not been
+ "cancelled". If we ever need to use this bit outside CCP, then
+ it should be renamed. */
+ unsigned in_ccp_worklist: 1;
+
+ /* Nonzero if the statement makes aliased loads. */
+ unsigned makes_aliased_loads : 1;
+
+ /* Nonzero if the statement makes aliased stores. */
+ unsigned makes_aliased_stores : 1;
+
+ /* Nonzero if the statement makes references to volatile storage. */
+ unsigned has_volatile_ops : 1;
+
+ /* Nonzero if the statement makes a function call that may clobber global
+ and local addressable variables. */
+ unsigned makes_clobbering_call : 1;
+
+ /* Basic block that contains this statement. */
+ basic_block GTY ((skip (""))) bb;
+
+ /* Statement operands. */
+ struct def_optype_d * GTY (()) def_ops;
+ struct use_optype_d * GTY (()) use_ops;
+
+ /* Virtual operands (VDEF and VUSE). */
+ struct vdef_optype_d * GTY (()) vdef_ops;
+ struct vuse_optype_d * GTY (()) vuse_ops;
+
+ /* Dataflow information. */
+ dataflow_t df;
+
+ /* Set of variables that have had their address taken in the statement. */
+ bitmap addresses_taken;
+
+ /* Unique identifier for this statement. These ID's are to be created
+ by each pass on an as-needed basis in any order convenient for the
+ pass which needs statement UIDs. */
+ unsigned int uid;
+};
+
+
+struct ssa_name_ann_d GTY(())
+{
+ struct tree_ann_common_d common;
+
+ /* Nonzero if points-to analysis couldn't determine where this pointer
+ is pointing to. */
+ unsigned int pt_anything : 1;
+
+ /* Nonzero if this pointer is the result of a call to malloc. */
+ unsigned int pt_malloc : 1;
+
+ /* Nonzero if the value of this pointer escapes the current function. */
+ unsigned int value_escapes_p : 1;
+
+ /* Set of variables that this pointer may point to. */
+ bitmap pt_vars;
+
+ /* If this pointer has been dereferenced, and points-to information is
+ more precise than type-based aliasing, indirect references to this
+ pointer will be represented by this memory tag, instead of the type
+ tag computed by TBAA. */
+ tree name_mem_tag;
+};
+
+
+union tree_ann_d GTY((desc ("ann_type ((tree_ann)&%h)")))
+{
+ struct tree_ann_common_d GTY((tag ("TREE_ANN_COMMON"))) common;
+ struct var_ann_d GTY((tag ("VAR_ANN"))) decl;
+ struct stmt_ann_d GTY((tag ("STMT_ANN"))) stmt;
+ struct ssa_name_ann_d GTY((tag ("SSA_NAME_ANN"))) ssa_name;
+};
+
+typedef union tree_ann_d *tree_ann;
+typedef struct var_ann_d *var_ann_t;
+typedef struct stmt_ann_d *stmt_ann_t;
+typedef struct ssa_name_ann_d *ssa_name_ann_t;
+
+static inline var_ann_t var_ann (tree);
+static inline var_ann_t get_var_ann (tree);
+static inline stmt_ann_t stmt_ann (tree);
+static inline stmt_ann_t get_stmt_ann (tree);
+static inline ssa_name_ann_t ssa_name_ann (tree);
+static inline ssa_name_ann_t get_ssa_name_ann (tree);
+static inline enum tree_ann_type ann_type (tree_ann);
+static inline basic_block bb_for_stmt (tree);
+extern void set_bb_for_stmt (tree, basic_block);
+static inline void modify_stmt (tree);
+static inline void unmodify_stmt (tree);
+static inline bool stmt_modified_p (tree);
+static inline varray_type may_aliases (tree);
+static inline int get_lineno (tree);
+static inline const char *get_filename (tree);
+static inline bool is_exec_stmt (tree);
+static inline bool is_label_stmt (tree);
+static inline vdef_optype get_vdef_ops (stmt_ann_t);
+static inline vuse_optype get_vuse_ops (stmt_ann_t);
+static inline use_optype get_use_ops (stmt_ann_t);
+static inline def_optype get_def_ops (stmt_ann_t);
+static inline bitmap addresses_taken (tree);
+static inline int num_immediate_uses (dataflow_t);
+static inline tree immediate_use (dataflow_t, int);
+static inline dataflow_t get_immediate_uses (tree);
+static inline bool has_hidden_use (tree);
+static inline void set_has_hidden_use (tree);
+static inline void set_default_def (tree, tree);
+static inline tree default_def (tree);
+static inline bool may_be_aliased (tree);
+
+/*---------------------------------------------------------------------------
+ Structure representing predictions in tree level.
+---------------------------------------------------------------------------*/
+struct edge_prediction GTY((chain_next ("%h.next")))
+{
+ struct edge_prediction *next;
+ edge edge;
+ enum br_predictor predictor;
+ int probability;
+};
+
+/*---------------------------------------------------------------------------
+ Block annotations stored in basic_block.tree_annotations
+---------------------------------------------------------------------------*/
+struct bb_ann_d GTY(())
+{
+ /* Chain of PHI nodes for this block. */
+ tree phi_nodes;
+
+ /* Chain of EPHI nodes created in this block. */
+ tree ephi_nodes;
+
+ /* Number of predecessors for this block. This is only valid during
+ SSA rewriting. It is not maintained after conversion into SSA form. */
+ int num_preds;
+
+ /* Nonzero if this block is forwardable during cfg cleanups. This is also
+ used to detect loops during cfg cleanups. */
+ unsigned forwardable: 1;
+
+ /* Nonzero if this block contains an escape point (see is_escape_site). */
+ unsigned has_escape_site : 1;
+
+ struct edge_prediction *predictions;
+};
+
+typedef struct bb_ann_d *bb_ann_t;
+
+/* Accessors for basic block annotations. */
+static inline bb_ann_t bb_ann (basic_block);
+static inline tree phi_nodes (basic_block);
+static inline void set_phi_nodes (basic_block, tree);
+
+/*---------------------------------------------------------------------------
+ Global declarations
+---------------------------------------------------------------------------*/
+/* Array of all variables referenced in the function. */
+extern GTY(()) varray_type referenced_vars;
+
+#define num_referenced_vars VARRAY_ACTIVE_SIZE (referenced_vars)
+#define referenced_var(i) VARRAY_TREE (referenced_vars, i)
+
+/* Artificial variable used to model the effects of function calls. */
+extern GTY(()) tree global_var;
+
+/* Call clobbered variables in the function. If bit I is set, then
+ REFERENCED_VARS (I) is call-clobbered. */
+extern bitmap call_clobbered_vars;
+
+/* 'true' after aliases have been computed (see compute_may_aliases). */
+extern bool aliases_computed_p;
+
+/* Macros for showing usage statistics. */
+#define SCALE(x) ((unsigned long) ((x) < 1024*10 \
+ ? (x) \
+ : ((x) < 1024*1024*10 \
+ ? (x) / 1024 \
+ : (x) / (1024*1024))))
+
+#define LABEL(x) ((x) < 1024*10 ? 'b' : ((x) < 1024*1024*10 ? 'k' : 'M'))
+
+#define PERCENT(x,y) ((float)(x) * 100.0 / (float)(y))
+
+
+/*---------------------------------------------------------------------------
+ Block iterators
+---------------------------------------------------------------------------*/
+
+typedef struct {
+ tree_stmt_iterator tsi;
+ basic_block bb;
+} block_stmt_iterator;
+
+static inline block_stmt_iterator bsi_start (basic_block);
+static inline block_stmt_iterator bsi_last (basic_block);
+static inline bool bsi_end_p (block_stmt_iterator);
+static inline void bsi_next (block_stmt_iterator *);
+static inline void bsi_prev (block_stmt_iterator *);
+static inline tree bsi_stmt (block_stmt_iterator);
+static inline tree * bsi_stmt_ptr (block_stmt_iterator);
+
+extern void bsi_remove (block_stmt_iterator *);
+extern void bsi_move_before (block_stmt_iterator *, block_stmt_iterator *);
+extern void bsi_move_after (block_stmt_iterator *, block_stmt_iterator *);
+extern void bsi_move_to_bb_end (block_stmt_iterator *, basic_block);
+
+enum bsi_iterator_update
+{
+ /* Note that these are intentionally in the same order as TSI_FOO. They
+ mean exactly the same as their TSI_* counterparts. */
+ BSI_NEW_STMT,
+ BSI_SAME_STMT,
+ BSI_CHAIN_START,
+ BSI_CHAIN_END,
+ BSI_CONTINUE_LINKING
+};
+
+extern void bsi_insert_before (block_stmt_iterator *, tree,
+ enum bsi_iterator_update);
+extern void bsi_insert_after (block_stmt_iterator *, tree,
+ enum bsi_iterator_update);
+
+extern void bsi_replace (const block_stmt_iterator *, tree, bool);
+
+/*---------------------------------------------------------------------------
+ Function prototypes
+---------------------------------------------------------------------------*/
+/* In tree-cfg.c */
+
+/* Location to track pending stmt for edge insertion. */
+#define PENDING_STMT(e) ((e)->insns.t)
+
+extern void delete_tree_cfg (void);
+extern void disband_implicit_edges (void);
+extern bool stmt_ends_bb_p (tree);
+extern bool is_ctrl_stmt (tree);
+extern bool is_ctrl_altering_stmt (tree);
+extern bool computed_goto_p (tree);
+extern bool simple_goto_p (tree);
+extern void tree_dump_bb (basic_block, FILE *, int);
+extern void debug_tree_bb (basic_block);
+extern basic_block debug_tree_bb_n (int);
+extern void dump_tree_cfg (FILE *, int);
+extern void debug_tree_cfg (int);
+extern void dump_cfg_stats (FILE *);
+extern void debug_cfg_stats (void);
+extern void debug_loop_ir (void);
+extern void print_loop_ir (FILE *);
+extern void cleanup_tree_cfg (void);
+extern tree first_stmt (basic_block);
+extern tree last_stmt (basic_block);
+extern tree *last_stmt_ptr (basic_block);
+extern tree last_and_only_stmt (basic_block);
+extern edge find_taken_edge (basic_block, tree);
+extern void cfg_remove_useless_stmts (void);
+extern edge thread_edge (edge, basic_block);
+extern basic_block label_to_block (tree);
+extern void tree_optimize_tail_calls (bool, enum tree_dump_index);
+extern edge tree_block_forwards_to (basic_block bb);
+extern void bsi_insert_on_edge (edge, tree);
+extern void bsi_commit_edge_inserts (int *);
+extern void notice_special_calls (tree);
+extern void clear_special_calls (void);
+extern void compute_dominance_frontiers (bitmap *);
+extern void verify_stmts (void);
+extern void extract_true_false_edges_from_block (basic_block, edge *, edge *);
+
+/* In tree-pretty-print.c. */
+extern void dump_generic_bb (FILE *, basic_block, int, int);
+
+/* In tree-dfa.c */
+extern var_ann_t create_var_ann (tree);
+extern stmt_ann_t create_stmt_ann (tree);
+extern ssa_name_ann_t create_ssa_name_ann (tree);
+extern tree create_phi_node (tree, basic_block);
+extern void add_phi_arg (tree *, tree, edge);
+extern void remove_phi_arg (tree, basic_block);
+extern void remove_phi_arg_num (tree, int);
+extern void remove_phi_node (tree, tree, basic_block);
+extern void remove_all_phi_nodes_for (bitmap);
+extern void dump_dfa_stats (FILE *);
+extern void debug_dfa_stats (void);
+extern void debug_referenced_vars (void);
+extern void dump_referenced_vars (FILE *);
+extern void dump_variable (FILE *, tree);
+extern void debug_variable (tree);
+extern void dump_immediate_uses (FILE *);
+extern void debug_immediate_uses (void);
+extern void dump_immediate_uses_for (FILE *, tree);
+extern void debug_immediate_uses_for (tree);
+extern void compute_immediate_uses (int, bool (*)(tree));
+extern void free_df (void);
+extern tree get_virtual_var (tree);
+extern void add_referenced_tmp_var (tree var);
+extern void mark_new_vars_to_rename (tree, bitmap);
+extern void redirect_immediate_uses (tree, tree);
+extern tree make_rename_temp (tree, const char *);
+
+/* Flags used when computing reaching definitions and reached uses. */
+#define TDFA_USE_OPS 1 << 0
+#define TDFA_USE_VOPS 1 << 1
+
+/* In gimple-low.c */
+struct lower_data;
+extern void lower_stmt_body (tree, struct lower_data *);
+extern void expand_used_vars (void);
+extern void record_vars (tree);
+extern bool block_may_fallthru (tree block);
+
+/* In tree-ssa-alias.c */
+extern void dump_may_aliases_for (FILE *, tree);
+extern void debug_may_aliases_for (tree);
+extern void dump_alias_info (FILE *);
+extern void debug_alias_info (void);
+extern void dump_points_to_info (FILE *);
+extern void debug_points_to_info (void);
+
+/* Call-back function for walk_use_def_chains(). At each reaching
+ definition, a function with this prototype is called. */
+typedef bool (*walk_use_def_chains_fn) (tree, tree, void *);
+
+/* In tree-ssa.c */
+extern void init_tree_ssa (void);
+extern void rewrite_vars_out_of_ssa (bitmap);
+extern void dump_reaching_defs (FILE *);
+extern void debug_reaching_defs (void);
+extern void dump_tree_ssa (FILE *);
+extern void debug_tree_ssa (void);
+extern void debug_def_blocks (void);
+extern void dump_tree_ssa_stats (FILE *);
+extern void debug_tree_ssa_stats (void);
+extern void ssa_remove_edge (edge);
+extern edge ssa_redirect_edge (edge, basic_block);
+extern void set_is_used (tree);
+extern bool tree_ssa_useless_type_conversion (tree);
+extern bool tree_ssa_useless_type_conversion_1 (tree, tree);
+extern void verify_ssa (void);
+extern void delete_tree_ssa (void);
+extern void register_new_def (tree, varray_type *);
+extern void walk_use_def_chains (tree, walk_use_def_chains_fn, void *);
+
+/* In tree-into-ssa.c */
+extern void rewrite_into_ssa (void);
+
+extern unsigned int highest_ssa_version;
+
+/* In tree-ssa-pre.c */
+extern void tree_perform_ssapre (tree, enum tree_dump_index);
+
+/* In tree-ssa-ccp.c */
+bool fold_stmt (tree *);
+tree widen_bitfield (tree, tree, tree);
+
+/* In tree-ssa-dom.c */
+extern void dump_dominator_optimization_stats (FILE *);
+extern void debug_dominator_optimization_stats (void);
+
+/* In tree-ssa-copy.c */
+extern void propagate_value (tree *, tree);
+extern void replace_exp (tree *, tree);
+extern bool cprop_into_stmt (tree, varray_type);
+extern void cprop_into_successor_phis (basic_block, varray_type);
+
+/* In tree-flow-inline.h */
+static inline int phi_arg_from_edge (tree, edge);
+static inline struct phi_arg_d *phi_element_for_edge (tree, edge);
+static inline bool may_propagate_copy (tree, tree);
+static inline bool is_call_clobbered (tree);
+static inline void mark_call_clobbered (tree);
+
+/* In tree-eh.c */
+extern void make_eh_edges (tree);
+extern bool tree_could_trap_p (tree);
+extern bool tree_could_throw_p (tree);
+extern bool tree_can_throw_internal (tree);
+extern bool tree_can_throw_external (tree);
+extern void add_stmt_to_eh_region (tree, int);
+
+#include "tree-flow-inline.h"
+
+#endif /* _TREE_FLOW_H */
diff --git a/gcc/tree-gimple.c b/gcc/tree-gimple.c
new file mode 100644
index 00000000000..dbe2966e1e9
--- /dev/null
+++ b/gcc/tree-gimple.c
@@ -0,0 +1,642 @@
+/* Functions to analyze and validate GIMPLE trees.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Diego Novillo <dnovillo@redhat.com>
+ Rewritten by Jason Merrill <jason@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "ggc.h"
+#include "tm.h"
+#include "tree.h"
+#include "tree-gimple.h"
+#include "output.h"
+#include "rtl.h"
+#include "expr.h"
+#include "bitmap.h"
+
+/* GCC GIMPLE structure
+
+ Inspired by the SIMPLE C grammar at
+
+ http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
+
+ function:
+ FUNCTION_DECL
+ DECL_SAVED_TREE -> block
+ block:
+ BIND_EXPR
+ BIND_EXPR_VARS -> DECL chain
+ BIND_EXPR_BLOCK -> BLOCK
+ BIND_EXPR_BODY -> compound-stmt
+ compound-stmt:
+ COMPOUND_EXPR
+ op0 -> non-compound-stmt
+ op1 -> stmt
+ | EXPR_VEC
+ (or other alternate solution)
+ stmt: compound-stmt | non-compound-stmt
+ non-compound-stmt:
+ block
+ | if-stmt
+ | switch-stmt
+ | jump-stmt
+ | label-stmt
+ | try-stmt
+ | modify-stmt
+ | call-stmt
+ if-stmt:
+ COND_EXPR
+ op0 -> condition
+ op1 -> stmt
+ op2 -> stmt
+ switch-stmt:
+ SWITCH_EXPR
+ op0 -> val
+ op1 -> stmt
+ op2 -> array of case labels (as LABEL_DECLs?)
+ FIXME: add case value info
+ jump-stmt:
+ GOTO_EXPR
+ op0 -> LABEL_DECL | '*' ID
+ | RETURN_EXPR
+ op0 -> modify-stmt | NULL_TREE
+ (maybe -> RESULT_DECL | NULL_TREE? seems like some of expand_return
+ depends on getting a MODIFY_EXPR.)
+ | THROW_EXPR? do we need/want such a thing for opts, perhaps
+ to generate an ERT_THROW region? I think so.
+ Hmm...this would only work at the GIMPLE level, where we know that
+ the call args don't have any EH impact. Perhaps
+ annotation of the CALL_EXPR would work better.
+ | RESX_EXPR
+ label-stmt:
+ LABEL_EXPR
+ op0 -> LABEL_DECL
+ | CASE_LABEL_EXPR
+ CASE_LOW -> val | NULL_TREE
+ CASE_HIGH -> val | NULL_TREE
+ CASE_LABEL -> LABEL_DECL FIXME
+ try-stmt:
+ TRY_CATCH_EXPR
+ op0 -> stmt
+ op1 -> handler
+ | TRY_FINALLY_EXPR
+ op0 -> stmt
+ op1 -> stmt
+ handler:
+ catch-seq
+ | EH_FILTER_EXPR
+ | stmt
+ modify-stmt:
+ MODIFY_EXPR
+ op0 -> lhs
+ op1 -> rhs
+ call-stmt: CALL_EXPR
+ op0 -> ID | '&' ID
+ op1 -> arglist
+
+ addr-expr-arg : compref | ID
+ lhs: addr-expr-arg | '*' ID | bitfieldref
+ min-lval: ID | '*' ID
+ bitfieldref :
+ BIT_FIELD_REF
+ op0 -> compref | min-lval
+ op1 -> CONST
+ op2 -> CONST
+ compref :
+ COMPONENT_REF
+ op0 -> compref | min-lval
+ | ARRAY_REF
+ op0 -> compref | min-lval
+ op1 -> val
+ | REALPART_EXPR
+ | IMAGPART_EXPR
+
+ condition : val | val relop val
+ val : ID | CONST
+
+ rhs : varname | CONST
+ | '*' ID
+ | '&' addr-expr-arg
+ | call_expr
+ | unop val
+ | val binop val
+ | '(' cast ')' val
+
+ (cast here stands for all valid C typecasts)
+
+ unop
+ : '+'
+ | '-'
+ | '!'
+ | '~'
+
+ binop
+ : relop | '-'
+ | '+'
+ | '/'
+ | '*'
+ | '%'
+ | '&'
+ | '|'
+ | '<<'
+ | '>>'
+ | '^'
+
+ relop
+ : '<'
+ | '<='
+ | '>'
+ | '>='
+ | '=='
+ | '!='
+
+*/
+
+static inline bool is_gimple_id (tree);
+
+/* Validation of GIMPLE expressions. */
+
+/* Return nonzero if T is a GIMPLE RHS:
+
+ rhs : varname | CONST
+ | '*' ID
+ | '&' varname_or_temp
+ | call_expr
+ | unop val
+ | val binop val
+ | '(' cast ')' val
+ | <CONSTRUCTOR <gimple_val ...>>
+
+ The last option is only valid GIMPLE for vector and complex types;
+ aggregate types should have their constructors decomposed. */
+
+bool
+is_gimple_rhs (tree t)
+{
+ enum tree_code code = TREE_CODE (t);
+
+ switch (TREE_CODE_CLASS (code))
+ {
+ case '1':
+ case '2':
+ case '<':
+ return 1;
+
+ default:
+ break;
+ }
+
+ switch (code)
+ {
+ case TRUTH_NOT_EXPR:
+ case TRUTH_AND_EXPR:
+ case TRUTH_OR_EXPR:
+ case TRUTH_XOR_EXPR:
+ case ADDR_EXPR:
+ case CALL_EXPR:
+ case CONSTRUCTOR:
+ case COMPLEX_EXPR:
+ /* FIXME lower VA_ARG_EXPR. */
+ case VA_ARG_EXPR:
+ case INTEGER_CST:
+ case REAL_CST:
+ case STRING_CST:
+ case COMPLEX_CST:
+ case VECTOR_CST:
+ return 1;
+
+ default:
+ break;
+ }
+
+ if (is_gimple_lvalue (t) || is_gimple_val (t))
+ return 1;
+
+ return 0;
+}
+
+/* Returns nonzero if T is a valid CONSTRUCTOR component in GIMPLE, either
+ a val or another CONSTRUCTOR. */
+
+bool
+is_gimple_constructor_elt (tree t)
+{
+ return (is_gimple_val (t)
+ || TREE_CODE (t) == CONSTRUCTOR);
+}
+
+/* Return nonzero if T is a valid LHS for a GIMPLE assignment expression. */
+
+bool
+is_gimple_lvalue (tree t)
+{
+ return (is_gimple_addr_expr_arg (t)
+ || TREE_CODE (t) == INDIRECT_REF
+ /* These are complex lvalues, but don't have addresses, so they
+ go here. */
+ || TREE_CODE (t) == BIT_FIELD_REF);
+}
+
+
+/* Return nonzero if T is a GIMPLE condition:
+
+ condexpr
+ : val
+ | val relop val */
+
+bool
+is_gimple_condexpr (tree t)
+{
+ return (is_gimple_val (t)
+ || TREE_CODE_CLASS (TREE_CODE (t)) == '<');
+}
+
+
+/* Return nonzero if T is a valid operand for '&':
+
+ varname
+ : arrayref
+ | compref
+ | ID */
+
+bool
+is_gimple_addr_expr_arg (tree t)
+{
+ return (is_gimple_id (t)
+ || TREE_CODE (t) == ARRAY_REF
+ || TREE_CODE (t) == COMPONENT_REF
+ || TREE_CODE (t) == REALPART_EXPR
+ || TREE_CODE (t) == IMAGPART_EXPR);
+}
+
+/* Return nonzero if T is function invariant. Or rather a restricted
+ form of function invariant. */
+
+bool
+is_gimple_min_invariant (tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case ADDR_EXPR:
+ return TREE_INVARIANT (t);
+
+ case INTEGER_CST:
+ case REAL_CST:
+ case STRING_CST:
+ case COMPLEX_CST:
+ case VECTOR_CST:
+ return !TREE_OVERFLOW (t);
+
+ default:
+ return false;
+ }
+}
+
+/* Return nonzero if T looks like a valid GIMPLE statement. */
+
+bool
+is_gimple_stmt (tree t)
+{
+ enum tree_code code = TREE_CODE (t);
+
+ if (IS_EMPTY_STMT (t))
+ return 1;
+
+ switch (code)
+ {
+ case BIND_EXPR:
+ case COND_EXPR:
+ /* These are only valid if they're void. */
+ return VOID_TYPE_P (TREE_TYPE (t));
+
+ case SWITCH_EXPR:
+ case GOTO_EXPR:
+ case RETURN_EXPR:
+ case LABEL_EXPR:
+ case CASE_LABEL_EXPR:
+ case TRY_CATCH_EXPR:
+ case TRY_FINALLY_EXPR:
+ case EH_FILTER_EXPR:
+ case CATCH_EXPR:
+ case ASM_EXPR:
+ case RESX_EXPR:
+ case PHI_NODE:
+ case STATEMENT_LIST:
+ /* These are always void. */
+ return 1;
+
+ case VA_ARG_EXPR:
+ /* FIXME this should be lowered. */
+ return 1;
+
+ case COMPOUND_EXPR:
+ /* FIXME should we work harder to make COMPOUND_EXPRs void? */
+ case CALL_EXPR:
+ case MODIFY_EXPR:
+ /* These are valid regardless of their type. */
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+/* Return nonzero if T is a variable. */
+
+bool
+is_gimple_variable (tree t)
+{
+ return (TREE_CODE (t) == VAR_DECL
+ || TREE_CODE (t) == PARM_DECL
+ || TREE_CODE (t) == RESULT_DECL
+ || TREE_CODE (t) == SSA_NAME);
+}
+
+/* Return nonzero if T is a GIMPLE identifier (something with an address). */
+
+static inline bool
+is_gimple_id (tree t)
+{
+ return (is_gimple_variable (t)
+ || TREE_CODE (t) == FUNCTION_DECL
+ || TREE_CODE (t) == LABEL_DECL
+ /* Allow string constants, since they are addressable. */
+ || TREE_CODE (t) == STRING_CST);
+}
+
+/* Return nonzero if TYPE is a suitable type for a scalar register
+ variable. */
+
+bool
+is_gimple_reg_type (tree type)
+{
+ return (!AGGREGATE_TYPE_P (type)
+ && TREE_CODE (type) != COMPLEX_TYPE);
+}
+
+
+/* Return nonzero if T is a scalar register variable. */
+
+bool
+is_gimple_reg (tree t)
+{
+ if (TREE_CODE (t) == SSA_NAME)
+ t = SSA_NAME_VAR (t);
+
+ return (is_gimple_variable (t)
+ && is_gimple_reg_type (TREE_TYPE (t))
+ /* A volatile decl is not acceptable because we can't reuse it as
+ needed. We need to copy it into a temp first. */
+ && ! TREE_THIS_VOLATILE (t)
+ && ! TREE_ADDRESSABLE (t)
+ && ! needs_to_live_in_memory (t));
+}
+
+/* Return nonzero if T is a GIMPLE variable whose address is not needed. */
+
+bool
+is_gimple_non_addressable (tree t)
+{
+ if (TREE_CODE (t) == SSA_NAME)
+ t = SSA_NAME_VAR (t);
+
+ return (is_gimple_variable (t)
+ && ! TREE_ADDRESSABLE (t)
+ && ! needs_to_live_in_memory (t));
+}
+
+/* Return nonzero if T is a GIMPLE rvalue, i.e. an identifier or a
+ constant. */
+
+bool
+is_gimple_val (tree t)
+{
+ /* Make loads from volatiles and memory vars explicit. */
+ if (is_gimple_variable (t)
+ && is_gimple_reg_type (TREE_TYPE (t))
+ && !is_gimple_reg (t))
+ return 0;
+
+ /* FIXME make these decls. That can happen only when we expose the
+ entire landing-pad construct at the tree level. */
+ if (TREE_CODE (t) == EXC_PTR_EXPR || TREE_CODE (t) == FILTER_EXPR)
+ return 1;
+
+ return (is_gimple_variable (t) || is_gimple_min_invariant (t));
+}
+
+
+/* Return true if T is a GIMPLE minimal lvalue, of the form
+
+ min_lval: ID | '(' '*' ID ')'
+
+ This never actually appears in the original SIMPLE grammar, but is
+ repeated in several places. */
+
+bool
+is_gimple_min_lval (tree t)
+{
+ return (is_gimple_id (t)
+ || TREE_CODE (t) == INDIRECT_REF);
+}
+
+/* Return nonzero if T is a typecast operation of the form
+ '(' cast ')' val. */
+
+bool
+is_gimple_cast (tree t)
+{
+ return (TREE_CODE (t) == NOP_EXPR
+ || TREE_CODE (t) == CONVERT_EXPR
+ || TREE_CODE (t) == FIX_TRUNC_EXPR
+ || TREE_CODE (t) == FIX_CEIL_EXPR
+ || TREE_CODE (t) == FIX_FLOOR_EXPR
+ || TREE_CODE (t) == FIX_ROUND_EXPR);
+}
+
+
+/* If T makes a function call, return the corresponding CALL_EXPR operand.
+ Otherwise, return NULL_TREE. */
+
+tree
+get_call_expr_in (tree t)
+{
+ if (TREE_CODE (t) == CALL_EXPR)
+ return t;
+ else if (TREE_CODE (t) == MODIFY_EXPR
+ && TREE_CODE (TREE_OPERAND (t, 1)) == CALL_EXPR)
+ return TREE_OPERAND (t, 1);
+ else if (TREE_CODE (t) == RETURN_EXPR
+ && TREE_OPERAND (t, 0)
+ && TREE_CODE (TREE_OPERAND (t, 0)) == MODIFY_EXPR
+ && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 1)) == CALL_EXPR)
+ return TREE_OPERAND (TREE_OPERAND (t, 0), 1);
+
+ return NULL_TREE;
+}
+
+
+/* Given an _EXPR TOP, reorganize all of the nested _EXPRs with the same
+ code so that they only appear as the second operand. This should only
+ be used for tree codes which are truly associative, such as
+ COMPOUND_EXPR and TRUTH_ANDIF_EXPR. Arithmetic is not associative
+ enough, due to the limited precision of arithmetic data types.
+
+ This transformation is conservative; the operand 0 of a matching tree
+ node will only change if it is also a matching node. */
+
+tree
+right_assocify_expr (tree top)
+{
+ tree *p = &top;
+ enum tree_code code = TREE_CODE (*p);
+ while (TREE_CODE (*p) == code)
+ {
+ tree cur = *p;
+ tree lhs = TREE_OPERAND (cur, 0);
+ if (TREE_CODE (lhs) == code)
+ {
+ /* There's a left-recursion. If we have ((a, (b, c)), d), we
+ want to rearrange to (a, (b, (c, d))). */
+ tree *q;
+
+ /* Replace cur with the lhs; move (a, *) up. */
+ *p = lhs;
+
+ if (code == COMPOUND_EXPR)
+ {
+ /* We need to give (b, c) the type of c; previously lhs had
+ the type of b. */
+ TREE_TYPE (lhs) = TREE_TYPE (cur);
+ if (TREE_SIDE_EFFECTS (cur))
+ TREE_SIDE_EFFECTS (lhs) = 1;
+ }
+
+ /* Walk through the op1 chain from there until we find something
+ with a different code. In this case, c. */
+ for (q = &TREE_OPERAND (lhs, 1); TREE_CODE (*q) == code;
+ q = &TREE_OPERAND (*q, 1))
+ TREE_TYPE (*q) = TREE_TYPE (cur);
+
+ /* Change (*, d) into (c, d). */
+ TREE_OPERAND (cur, 0) = *q;
+
+ /* And plug it in where c used to be. */
+ *q = cur;
+ }
+ else
+ p = &TREE_OPERAND (cur, 1);
+ }
+ return top;
+}
+
+/* Normalize the statement TOP. If it is a COMPOUND_EXPR, reorganize it so
+ that we can traverse it without recursion. If it is null, replace it
+ with a nop. */
+
+tree
+rationalize_compound_expr (tree top)
+{
+ if (top == NULL_TREE)
+ top = build_empty_stmt ();
+ else if (TREE_CODE (top) == COMPOUND_EXPR)
+ top = right_assocify_expr (top);
+
+ return top;
+}
+
+/* Given a memory reference expression, return the base address. Note that,
+ in contrast with get_base_var, this will not recurse inside INDIRECT_REF
+ expressions. Therefore, given the reference PTR->FIELD, this function
+ will return *PTR. Whereas get_base_var would've returned PTR. */
+
+tree
+get_base_address (tree t)
+{
+ do
+ {
+ if (SSA_VAR_P (t)
+ || TREE_CODE (t) == INDIRECT_REF)
+ return t;
+
+ switch (TREE_CODE (t))
+ {
+ case ARRAY_REF:
+ case COMPONENT_REF:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ case BIT_FIELD_REF:
+ t = TREE_OPERAND (t, 0);
+ break;
+
+ default:
+ return NULL_TREE;
+ }
+ }
+ while (t);
+
+ return t;
+}
+
+
+void
+recalculate_side_effects (tree t)
+{
+ enum tree_code code = TREE_CODE (t);
+ int fro = first_rtl_op (code);
+ int i;
+
+ switch (TREE_CODE_CLASS (code))
+ {
+ case 'e':
+ switch (code)
+ {
+ case INIT_EXPR:
+ case MODIFY_EXPR:
+ case VA_ARG_EXPR:
+ case RTL_EXPR:
+ case PREDECREMENT_EXPR:
+ case PREINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ /* All of these have side-effects, no matter what their
+ operands are. */
+ return;
+
+ default:
+ break;
+ }
+ /* Fall through. */
+
+ case '<': /* a comparison expression */
+ case '1': /* a unary arithmetic expression */
+ case '2': /* a binary arithmetic expression */
+ case 'r': /* a reference */
+ TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
+ for (i = 0; i < fro; ++i)
+ {
+ tree op = TREE_OPERAND (t, i);
+ if (op && TREE_SIDE_EFFECTS (op))
+ TREE_SIDE_EFFECTS (t) = 1;
+ }
+ break;
+ }
+}
diff --git a/gcc/tree-gimple.h b/gcc/tree-gimple.h
new file mode 100644
index 00000000000..d2c91032031
--- /dev/null
+++ b/gcc/tree-gimple.h
@@ -0,0 +1,127 @@
+/* Functions to analyze and validate GIMPLE trees.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Diego Novillo <dnovillo@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#ifndef _TREE_SIMPLE_H
+#define _TREE_SIMPLE_H 1
+
+
+#include "tree-iterator.h"
+
+extern tree create_tmp_var_raw (tree, const char *);
+extern tree create_tmp_var (tree, const char *);
+extern bool is_gimple_tmp_var (tree);
+extern tree get_initialized_tmp_var (tree, tree *, tree *);
+extern tree get_formal_tmp_var (tree, tree *);
+extern void declare_tmp_vars (tree, tree);
+
+extern tree rationalize_compound_expr (tree);
+extern tree right_assocify_expr (tree);
+extern void annotate_all_with_locus (tree *, location_t);
+
+/* Validation of GIMPLE expressions. Note that these predicates only check
+ the basic form of the expression, they don't recurse to make sure that
+ underlying nodes are also of the right form. */
+
+/* Returns true iff T is a valid GIMPLE statement. */
+bool is_gimple_stmt (tree);
+
+/* Returns true iff TYPE is a valid type for a scalar register variable. */
+bool is_gimple_reg_type (tree);
+/* Returns true iff T is a scalar register variable. */
+bool is_gimple_reg (tree);
+/* Returns true iff T is any sort of variable. */
+bool is_gimple_variable (tree);
+/* Returns true iff T is a variable or an INDIRECT_REF (of a variable). */
+bool is_gimple_min_lval (tree);
+/* Returns true iff T is an lvalue other than an INDIRECT_REF. */
+bool is_gimple_addr_expr_arg (tree);
+/* Returns true iff T is any valid GIMPLE lvalue. */
+bool is_gimple_lvalue (tree);
+
+/* Returns true iff T is a GIMPLE restricted function invariant. */
+bool is_gimple_min_invariant (tree);
+/* Returns true iff T is a GIMPLE rvalue. */
+bool is_gimple_val (tree);
+/* Returns true iff T is a valid rhs for a MODIFY_EXPR. */
+bool is_gimple_rhs (tree);
+
+/* Returns true iff T is a valid if-statement condition. */
+bool is_gimple_condexpr (tree);
+
+/* Returns true iff T is a type conversion. */
+bool is_gimple_cast (tree);
+/* Returns true iff T is a valid CONSTRUCTOR element (either an rvalue or
+ another CONSTRUCTOR). */
+bool is_gimple_constructor_elt (tree);
+/* Returns true iff T is a variable that does not need to live in memory. */
+bool is_gimple_non_addressable (tree t);
+
+/* If T makes a function call, returns the CALL_EXPR operand. */
+tree get_call_expr_in (tree t);
+
+void recalculate_side_effects (tree);
+
+void append_to_statement_list (tree, tree *);
+void append_to_statement_list_force (tree, tree *);
+void append_to_compound_expr (tree, tree *);
+
+/* FIXME we should deduce this from the predicate. */
+typedef enum fallback_t {
+ fb_none = 0,
+ fb_rvalue = 1,
+ fb_lvalue = 2,
+ fb_mayfail = 4,
+ fb_either= fb_rvalue | fb_lvalue
+} fallback_t;
+
+enum gimplify_status {
+ GS_ERROR = -2, /* Something Bad Seen. */
+ GS_UNHANDLED = -1, /* A langhook result for "I dunno". */
+ GS_OK = 0, /* We did something, maybe more to do. */
+ GS_ALL_DONE = 1 /* The expression is fully gimplified. */
+};
+
+enum gimplify_status gimplify_expr (tree *, tree *, tree *,
+ bool (*) (tree), fallback_t);
+void gimplify_stmt (tree *);
+void gimplify_to_stmt_list (tree *);
+void gimplify_body (tree *, tree);
+void push_gimplify_context (void);
+void pop_gimplify_context (tree);
+
+/* Miscellaneous helpers. */
+tree get_base_address (tree t);
+void gimple_add_tmp_var (tree);
+tree gimple_current_bind_expr (void);
+void gimple_push_bind_expr (tree);
+void gimple_pop_bind_expr (void);
+void unshare_all_trees (tree);
+tree voidify_wrapper_expr (tree);
+tree gimple_build_eh_filter (tree, tree, tree);
+tree build_and_jump (tree *);
+tree alloc_stmt_list (void);
+void free_stmt_list (tree);
+tree force_labels_r (tree *, int *, void *);
+
+/* In tree-nested.c. */
+extern void lower_nested_functions (tree);
+
+#endif /* _TREE_SIMPLE_H */
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 622ae18a548..cf50b9b18c2 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -39,17 +39,14 @@ Boston, MA 02111-1307, USA. */
#include "langhooks.h"
#include "cgraph.h"
#include "intl.h"
-#include "diagnostic.h"
+#include "tree-mudflap.h"
#include "function.h"
+#include "diagnostic.h"
-/* This should be eventually be generalized to other languages, but
- this would require a shared function-as-trees infrastructure. */
-#ifndef INLINER_FOR_JAVA
-#include "c-common.h"
-#else /* INLINER_FOR_JAVA */
-#include "parse.h"
-#include "java-tree.h"
-#endif /* INLINER_FOR_JAVA */
+/* I'm not real happy about this, but we need to handle gimple and
+ non-gimple trees. */
+#include "tree-iterator.h"
+#include "tree-gimple.h"
/* 0 if we should not perform inlining.
1 if we should expand functions calls inline at the tree level.
@@ -88,6 +85,8 @@ typedef struct inline_data
this value is NULL, then return statements will simply be
remapped as return statements, rather than as jumps. */
tree ret_label;
+ /* The VAR_DECL for the return value. */
+ tree retvar;
/* The map from local declarations in the inlined function to
equivalents in the function into which it is being inlined. */
splay_tree decl_map;
@@ -110,10 +109,19 @@ typedef struct inline_data
struct cgraph_node *node;
/* Callgraph node of currently inlined function. */
struct cgraph_node *current_node;
+ /* Statement iterator. We need this so we can keep the tree in
+ gimple form when we insert the inlined function. It is not
+ used when we are not dealing with gimple trees. */
+ tree_stmt_iterator tsi;
} inline_data;
/* Prototypes. */
+/* The approximate number of instructions per statement. This number
+ need not be particularly accurate; it is used only to make
+ decisions about when a function is too big to inline. */
+#define INSNS_PER_STMT (10)
+
static tree declare_return_variable (inline_data *, tree, tree *);
static tree copy_body_r (tree *, int *, void *);
static tree copy_body (inline_data *);
@@ -122,15 +130,14 @@ static void expand_calls_inline (tree *, inline_data *);
static bool inlinable_function_p (tree);
static tree remap_decl (tree, inline_data *);
static tree remap_type (tree, inline_data *);
-#ifndef INLINER_FOR_JAVA
-static tree initialize_inlined_parameters (inline_data *, tree, tree);
-static void remap_block (tree, tree, inline_data *);
-static void copy_scope_stmt (tree *, int *, inline_data *);
-#else /* INLINER_FOR_JAVA */
-static tree initialize_inlined_parameters (inline_data *, tree, tree, tree);
-static void remap_block (tree *, tree, inline_data *);
-static tree add_stmt_to_compound (tree, tree, tree);
-#endif /* INLINER_FOR_JAVA */
+static tree initialize_inlined_parameters (inline_data *, tree,
+ tree, tree, tree);
+static void remap_block (tree *, inline_data *);
+static tree remap_decls (tree, inline_data *);
+static void copy_bind_expr (tree *, int *, inline_data *);
+static tree mark_local_for_remap_r (tree *, int *, void *);
+static tree unsave_r (tree *, int *, void *);
+static void declare_inline_vars (tree bind_expr, tree vars);
/* Insert a tree->tree mapping for ID. Despite the name suggests
that the trees should be variables, it is used for more than that. */
@@ -158,8 +165,13 @@ remap_decl (tree decl, inline_data *id)
/* We only remap local variables in the current function. */
fn = VARRAY_TOP_TREE (id->fns);
+#if 0
+ /* We need to remap statics, too, so that they get expanded even if the
+ inline function is never emitted out of line. We might as well also
+ remap extern decls so that they show up in the debug info. */
if (! lang_hooks.tree_inlining.auto_var_in_fn_p (decl, fn))
return NULL_TREE;
+#endif
/* See if we have remapped this declaration. */
n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl);
@@ -185,7 +197,8 @@ remap_decl (tree decl, inline_data *id)
walk_tree (&DECL_SIZE (t), copy_body_r, id, NULL);
walk_tree (&DECL_SIZE_UNIT (t), copy_body_r, id, NULL);
-#ifndef INLINER_FOR_JAVA
+#if 0
+ /* FIXME handle anon aggrs. */
if (! DECL_NAME (t) && TREE_TYPE (t)
&& lang_hooks.tree_inlining.anon_aggr_type_p (TREE_TYPE (t)))
{
@@ -205,7 +218,7 @@ remap_decl (tree decl, inline_data *id)
}
DECL_ANON_UNION_ELEMS (t) = nreverse (members);
}
-#endif /* not INLINER_FOR_JAVA */
+#endif
/* Remember it, so that if we encounter this local entity
again we can reuse this copy. */
@@ -213,7 +226,7 @@ remap_decl (tree decl, inline_data *id)
return t;
}
- return (tree) n->value;
+ return unshare_expr ((tree) n->value);
}
static tree
@@ -320,115 +333,47 @@ remap_type (tree type, inline_data *id)
return new;
}
-#ifndef INLINER_FOR_JAVA
-/* Copy the SCOPE_STMT_BLOCK associated with SCOPE_STMT to contain
- remapped versions of the variables therein. And hook the new block
- into the block-tree. If non-NULL, the DECLS are declarations to
- add to use instead of the BLOCK_VARS in the old block. */
-#else /* INLINER_FOR_JAVA */
-/* Copy the BLOCK to contain remapped versions of the variables
- therein. And hook the new block into the block-tree. */
-#endif /* INLINER_FOR_JAVA */
-
-static void
-#ifndef INLINER_FOR_JAVA
-remap_block (tree scope_stmt, tree decls, inline_data *id)
-#else /* INLINER_FOR_JAVA */
-remap_block (tree *block, tree decls, inline_data *id)
-#endif /* INLINER_FOR_JAVA */
+static tree
+remap_decls (tree decls, inline_data *id)
{
-#ifndef INLINER_FOR_JAVA
- /* We cannot do this in the cleanup for a TARGET_EXPR since we do
- not know whether or not expand_expr will actually write out the
- code we put there. If it does not, then we'll have more BLOCKs
- than block-notes, and things will go awry. At some point, we
- should make the back-end handle BLOCK notes in a tidier way,
- without requiring a strict correspondence to the block-tree; then
- this check can go. */
- if (id->in_target_cleanup_p)
- {
- SCOPE_STMT_BLOCK (scope_stmt) = NULL_TREE;
- return;
- }
+ tree old_var;
+ tree new_decls = NULL_TREE;
- /* If this is the beginning of a scope, remap the associated BLOCK. */
- if (SCOPE_BEGIN_P (scope_stmt) && SCOPE_STMT_BLOCK (scope_stmt))
+ /* Remap its variables. */
+ for (old_var = decls; old_var; old_var = TREE_CHAIN (old_var))
{
- tree old_block;
- tree new_block;
- tree old_var;
- tree fn;
-
- /* Make the new block. */
- old_block = SCOPE_STMT_BLOCK (scope_stmt);
- new_block = make_node (BLOCK);
- TREE_USED (new_block) = TREE_USED (old_block);
- BLOCK_ABSTRACT_ORIGIN (new_block) = old_block;
- SCOPE_STMT_BLOCK (scope_stmt) = new_block;
-
- /* Remap its variables. */
- for (old_var = decls ? decls : BLOCK_VARS (old_block);
- old_var;
- old_var = TREE_CHAIN (old_var))
- {
- tree new_var;
-
- /* Remap the variable. */
- new_var = remap_decl (old_var, id);
- /* If we didn't remap this variable, so we can't mess with
- its TREE_CHAIN. If we remapped this variable to
- something other than a declaration (say, if we mapped it
- to a constant), then we must similarly omit any mention
- of it here. */
- if (!new_var || !DECL_P (new_var))
- ;
- else
- {
- TREE_CHAIN (new_var) = BLOCK_VARS (new_block);
- BLOCK_VARS (new_block) = new_var;
- }
- }
- /* We put the BLOCK_VARS in reverse order; fix that now. */
- BLOCK_VARS (new_block) = nreverse (BLOCK_VARS (new_block));
- fn = VARRAY_TREE (id->fns, 0);
- if (id->cloning_p)
- /* We're building a clone; DECL_INITIAL is still
- error_mark_node, and current_binding_level is the parm
- binding level. */
- lang_hooks.decls.insert_block (new_block);
+ tree new_var;
+
+ /* Remap the variable. */
+ new_var = remap_decl (old_var, id);
+
+ /* If we didn't remap this variable, so we can't mess with its
+ TREE_CHAIN. If we remapped this variable to the return slot, it's
+ already declared somewhere else, so don't declare it here. */
+ if (!new_var || new_var == id->retvar)
+ ;
+#ifdef ENABLE_CHECKING
+ else if (!DECL_P (new_var))
+ abort ();
+#endif
else
{
- /* Attach this new block after the DECL_INITIAL block for the
- function into which this block is being inlined. In
- rest_of_compilation we will straighten out the BLOCK tree. */
- tree *first_block;
- if (DECL_INITIAL (fn))
- first_block = &BLOCK_CHAIN (DECL_INITIAL (fn));
- else
- first_block = &DECL_INITIAL (fn);
- BLOCK_CHAIN (new_block) = *first_block;
- *first_block = new_block;
+ TREE_CHAIN (new_var) = new_decls;
+ new_decls = new_var;
}
- /* Remember the remapped block. */
- insert_decl_map (id, old_block, new_block);
}
- /* If this is the end of a scope, set the SCOPE_STMT_BLOCK to be the
- remapped block. */
- else if (SCOPE_END_P (scope_stmt) && SCOPE_STMT_BLOCK (scope_stmt))
- {
- splay_tree_node n;
- /* Find this block in the table of remapped things. */
- n = splay_tree_lookup (id->decl_map,
- (splay_tree_key) SCOPE_STMT_BLOCK (scope_stmt));
- if (! n)
- abort ();
- SCOPE_STMT_BLOCK (scope_stmt) = (tree) n->value;
- }
-#else /* INLINER_FOR_JAVA */
+ return nreverse (new_decls);
+}
+
+/* Copy the BLOCK to contain remapped versions of the variables
+ therein. And hook the new block into the block-tree. */
+
+static void
+remap_block (tree *block, inline_data *id)
+{
tree old_block;
tree new_block;
- tree old_var;
tree fn;
/* Make the new block. */
@@ -436,82 +381,70 @@ remap_block (tree *block, tree decls, inline_data *id)
new_block = make_node (BLOCK);
TREE_USED (new_block) = TREE_USED (old_block);
BLOCK_ABSTRACT_ORIGIN (new_block) = old_block;
- BLOCK_SUBBLOCKS (new_block) = BLOCK_SUBBLOCKS (old_block);
- TREE_SIDE_EFFECTS (new_block) = TREE_SIDE_EFFECTS (old_block);
- TREE_TYPE (new_block) = TREE_TYPE (old_block);
*block = new_block;
/* Remap its variables. */
- for (old_var = decls ? decls : BLOCK_VARS (old_block);
- old_var;
- old_var = TREE_CHAIN (old_var))
- {
- tree new_var;
+ BLOCK_VARS (new_block) = remap_decls (BLOCK_VARS (old_block), id);
- /* All local class initialization flags go in the outermost
- scope. */
- if (LOCAL_CLASS_INITIALIZATION_FLAG_P (old_var))
- {
- /* We may already have one. */
- if (! splay_tree_lookup (id->decl_map, (splay_tree_key) old_var))
- {
- tree outermost_block;
- new_var = remap_decl (old_var, id);
- DECL_ABSTRACT_ORIGIN (new_var) = NULL;
- outermost_block = DECL_SAVED_TREE (current_function_decl);
- TREE_CHAIN (new_var) = BLOCK_VARS (outermost_block);
- BLOCK_VARS (outermost_block) = new_var;
- }
- continue;
- }
-
- /* Remap the variable. */
- new_var = remap_decl (old_var, id);
- /* If we didn't remap this variable, so we can't mess with
- its TREE_CHAIN. If we remapped this variable to
- something other than a declaration (say, if we mapped it
- to a constant), then we must similarly omit any mention
- of it here. */
- if (!new_var || !DECL_P (new_var))
- ;
+ fn = VARRAY_TREE (id->fns, 0);
+#if 1
+ /* FIXME! It shouldn't be so hard to manage blocks. Rebuilding them in
+ rest_of_compilation is a good start. */
+ if (id->cloning_p)
+ /* We're building a clone; DECL_INITIAL is still
+ error_mark_node, and current_binding_level is the parm
+ binding level. */
+ (*lang_hooks.decls.insert_block) (new_block);
+ else
+ {
+ /* Attach this new block after the DECL_INITIAL block for the
+ function into which this block is being inlined. In
+ rest_of_compilation we will straighten out the BLOCK tree. */
+ tree *first_block;
+ if (DECL_INITIAL (fn))
+ first_block = &BLOCK_CHAIN (DECL_INITIAL (fn));
else
- {
- TREE_CHAIN (new_var) = BLOCK_VARS (new_block);
- BLOCK_VARS (new_block) = new_var;
- }
+ first_block = &DECL_INITIAL (fn);
+ BLOCK_CHAIN (new_block) = *first_block;
+ *first_block = new_block;
}
- /* We put the BLOCK_VARS in reverse order; fix that now. */
- BLOCK_VARS (new_block) = nreverse (BLOCK_VARS (new_block));
- fn = VARRAY_TREE (id->fns, 0);
+#endif
/* Remember the remapped block. */
- splay_tree_insert (id->decl_map,
- (splay_tree_key) old_block,
- (splay_tree_value) new_block);
-#endif /* INLINER_FOR_JAVA */
+ insert_decl_map (id, old_block, new_block);
}
-#ifndef INLINER_FOR_JAVA
-/* Copy the SCOPE_STMT pointed to by TP. */
-
static void
-copy_scope_stmt (tree *tp, int *walk_subtrees, inline_data *id)
+copy_statement_list (tree *tp)
{
- tree block;
+ tree_stmt_iterator oi, ni;
+ tree new;
+
+ new = alloc_stmt_list ();
+ ni = tsi_start (new);
+ oi = tsi_start (*tp);
+ *tp = new;
+
+ for (; !tsi_end_p (oi); tsi_next (&oi))
+ tsi_link_after (&ni, tsi_stmt (oi), TSI_NEW_STMT);
+}
- /* Remember whether or not this statement was nullified. When
- making a copy, copy_tree_r always sets SCOPE_NULLIFIED_P (and
- doesn't copy the SCOPE_STMT_BLOCK) to free callers from having to
- deal with copying BLOCKs if they do not wish to do so. */
- block = SCOPE_STMT_BLOCK (*tp);
+static void
+copy_bind_expr (tree *tp, int *walk_subtrees, inline_data *id)
+{
+ tree block = BIND_EXPR_BLOCK (*tp);
/* Copy (and replace) the statement. */
copy_tree_r (tp, walk_subtrees, NULL);
- /* Restore the SCOPE_STMT_BLOCK. */
- SCOPE_STMT_BLOCK (*tp) = block;
+ if (block)
+ {
+ remap_block (&block, id);
+ BIND_EXPR_BLOCK (*tp) = block;
+ }
- /* Remap the associated block. */
- remap_block (*tp, NULL_TREE, id);
+ if (BIND_EXPR_VARS (*tp))
+ /* This will remap a lot of the same decls again, but this should be
+ harmless. */
+ BIND_EXPR_VARS (*tp) = remap_decls (BIND_EXPR_VARS (*tp), id);
}
-#endif /* not INLINER_FOR_JAVA */
/* Called from copy_body via walk_tree. DATA is really an
`inline_data *'. */
@@ -534,60 +467,36 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
abort ();
#endif
-#ifdef INLINER_FOR_JAVA
- if (TREE_CODE (*tp) == BLOCK)
- remap_block (tp, NULL_TREE, id);
-#endif
-
/* If this is a RETURN_STMT, change it into an EXPR_STMT and a
GOTO_STMT with the RET_LABEL as its target. */
-#ifndef INLINER_FOR_JAVA
- if (TREE_CODE (*tp) == RETURN_STMT && id->ret_label && !id->saving_p)
-#else /* INLINER_FOR_JAVA */
- if (TREE_CODE (*tp) == RETURN_EXPR && id->ret_label && !id->saving_p)
-#endif /* INLINER_FOR_JAVA */
+ if (TREE_CODE (*tp) == RETURN_EXPR && id->ret_label)
{
tree return_stmt = *tp;
tree goto_stmt;
- /* Build the GOTO_STMT. */
-#ifndef INLINER_FOR_JAVA
- goto_stmt = build_stmt (GOTO_STMT, id->ret_label);
- TREE_CHAIN (goto_stmt) = TREE_CHAIN (return_stmt);
- GOTO_FAKE_P (goto_stmt) = 1;
-#else /* INLINER_FOR_JAVA */
+ /* Build the GOTO_EXPR. */
tree assignment = TREE_OPERAND (return_stmt, 0);
goto_stmt = build1 (GOTO_EXPR, void_type_node, id->ret_label);
- TREE_SIDE_EFFECTS (goto_stmt) = 1;
-#endif /* INLINER_FOR_JAVA */
+ TREE_USED (id->ret_label) = 1;
/* If we're returning something, just turn that into an
assignment into the equivalent of the original
RESULT_DECL. */
-#ifndef INLINER_FOR_JAVA
- if (RETURN_STMT_EXPR (return_stmt))
- {
- *tp = build_stmt (EXPR_STMT,
- RETURN_STMT_EXPR (return_stmt));
- STMT_IS_FULL_EXPR_P (*tp) = 1;
- /* And then jump to the end of the function. */
- TREE_CHAIN (*tp) = goto_stmt;
- }
-#else /* INLINER_FOR_JAVA */
if (assignment)
- {
- copy_body_r (&assignment, walk_subtrees, data);
- *tp = build (COMPOUND_EXPR, void_type_node, assignment, goto_stmt);
- TREE_SIDE_EFFECTS (*tp) = 1;
- }
-#endif /* INLINER_FOR_JAVA */
+ {
+ /* Do not create a statement containing a naked RESULT_DECL. */
+ if (lang_hooks.gimple_before_inlining)
+ if (TREE_CODE (assignment) == RESULT_DECL)
+ gimplify_stmt (&assignment);
+
+ *tp = build (BIND_EXPR, void_type_node, NULL_TREE, NULL_TREE,
+ make_node (BLOCK));
+ append_to_statement_list (assignment, &BIND_EXPR_BODY (*tp));
+ append_to_statement_list (goto_stmt, &BIND_EXPR_BODY (*tp));
+ }
/* If we're not returning anything just do the jump. */
else
*tp = goto_stmt;
-
- /* We can't replace return label while inlining function
- because it is in the outer function. */
- insert_decl_map (id, id->ret_label, id->ret_label);
}
/* Local variables and labels need to be replaced by equivalent
variables. We don't want to copy static variables; there's only
@@ -610,18 +519,16 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
&& DECL_CONTEXT (*tp) != VARRAY_TREE (id->fns, 0))
abort ();
#endif
+ else if (TREE_CODE (*tp) == STATEMENT_LIST)
+ copy_statement_list (tp);
else if (TREE_CODE (*tp) == SAVE_EXPR)
remap_save_expr (tp, id->decl_map, VARRAY_TREE (id->fns, 0),
walk_subtrees);
else if (TREE_CODE (*tp) == UNSAVE_EXPR)
/* UNSAVE_EXPRs should not be generated until expansion time. */
abort ();
-#ifndef INLINER_FOR_JAVA
- /* For a SCOPE_STMT, we must copy the associated block so that we
- can write out debugging information for the inlined variables. */
- else if (TREE_CODE (*tp) == SCOPE_STMT && !id->in_target_cleanup_p)
- copy_scope_stmt (tp, walk_subtrees, id);
-#else /* INLINER_FOR_JAVA */
+ else if (TREE_CODE (*tp) == BIND_EXPR)
+ copy_bind_expr (tp, walk_subtrees, id);
else if (TREE_CODE (*tp) == LABELED_BLOCK_EXPR)
{
/* We need a new copy of this labeled block; the EXIT_BLOCK_EXPR
@@ -642,7 +549,6 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
*tp = copy_node (*tp);
TREE_OPERAND (*tp, 0) = (tree) n->value;
}
-#endif /* INLINER_FOR_JAVA */
/* Types may need remapping as well. */
else if (TYPE_P (*tp))
*tp = remap_type (*tp, id);
@@ -692,7 +598,32 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
value = (tree) n->value;
if (TREE_CODE (value) == INDIRECT_REF)
{
- *tp = convert (TREE_TYPE (*tp), TREE_OPERAND (value, 0));
+ /* Assume that the argument types properly match the
+ parameter types. We can't compare them well enough
+ without a comptypes langhook, and we don't want to
+ call convert and introduce a NOP_EXPR to convert
+ between two equivalent types (i.e. that only differ
+ in use of typedef names). */
+ *tp = TREE_OPERAND (value, 0);
+ return copy_body_r (tp, walk_subtrees, data);
+ }
+ }
+ }
+ else if (TREE_CODE (*tp) == INDIRECT_REF)
+ {
+ /* Get rid of *& from inline substitutions that can happen when a
+ pointer argument is an ADDR_EXPR. */
+ tree decl = TREE_OPERAND (*tp, 0), value;
+ splay_tree_node n;
+
+ n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl);
+ if (n)
+ {
+ value = (tree) n->value;
+ STRIP_NOPS (value);
+ if (TREE_CODE (value) == ADDR_EXPR)
+ {
+ *tp = TREE_OPERAND (value, 0);
return copy_body_r (tp, walk_subtrees, data);
}
}
@@ -716,7 +647,7 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
abort ();
}
}
- else if (!id->cloning_p)
+ else
{
struct cgraph_edge *edge;
@@ -760,45 +691,142 @@ copy_body (inline_data *id)
return body;
}
+static void
+setup_one_parameter (inline_data *id, tree p, tree value,
+ tree fn, tree *init_stmts, tree *vars,
+ bool *gimplify_init_stmts_p)
+{
+ tree init_stmt;
+ tree var;
+ tree var_sub;
+
+ /* If the parameter is never assigned to, we may not need to
+ create a new variable here at all. Instead, we may be able
+ to just use the argument value. */
+ if (TREE_READONLY (p)
+ && !TREE_ADDRESSABLE (p)
+ && value && !TREE_SIDE_EFFECTS (value))
+ {
+ /* We can't risk substituting complex expressions. They
+ might contain variables that will be assigned to later.
+ Theoretically, we could check the expression to see if
+ all of the variables that determine its value are
+ read-only, but we don't bother. */
+ if ((TREE_CONSTANT (value) || TREE_READONLY_DECL_P (value))
+ /* We may produce non-gimple trees by adding NOPs or introduce
+ invalid sharing when operand is not really constant.
+ It is not big deal to prohibit constant propagation here as
+ we will constant propagate in DOM1 pass anyway. */
+ && (!lang_hooks.gimple_before_inlining
+ || (is_gimple_min_invariant (value)
+ && TREE_TYPE (value) == TREE_TYPE (p))))
+ {
+ /* If this is a declaration, wrap it a NOP_EXPR so that
+ we don't try to put the VALUE on the list of BLOCK_VARS. */
+ if (DECL_P (value))
+ value = build1 (NOP_EXPR, TREE_TYPE (value), value);
+
+ /* If this is a constant, make sure it has the right type. */
+ else if (TREE_TYPE (value) != TREE_TYPE (p))
+ value = fold (build1 (NOP_EXPR, TREE_TYPE (p), value));
+
+ insert_decl_map (id, p, value);
+ return;
+ }
+ }
+
+ /* Make an equivalent VAR_DECL. */
+ var = copy_decl_for_inlining (p, fn, VARRAY_TREE (id->fns, 0));
+
+ /* See if the frontend wants to pass this by invisible reference. If
+ so, our new VAR_DECL will have REFERENCE_TYPE, and we need to
+ replace uses of the PARM_DECL with dereferences. */
+ if (TREE_TYPE (var) != TREE_TYPE (p)
+ && POINTER_TYPE_P (TREE_TYPE (var))
+ && TREE_TYPE (TREE_TYPE (var)) == TREE_TYPE (p))
+ {
+ insert_decl_map (id, var, var);
+ var_sub = build1 (INDIRECT_REF, TREE_TYPE (p), var);
+ }
+ else
+ var_sub = var;
+
+ /* Register the VAR_DECL as the equivalent for the PARM_DECL;
+ that way, when the PARM_DECL is encountered, it will be
+ automatically replaced by the VAR_DECL. */
+ insert_decl_map (id, p, var_sub);
+
+ /* Declare this new variable. */
+ TREE_CHAIN (var) = *vars;
+ *vars = var;
+
+ /* Make gimplifier happy about this variable. */
+ var->decl.seen_in_bind_expr = lang_hooks.gimple_before_inlining;
+
+ /* Even if P was TREE_READONLY, the new VAR should not be.
+ In the original code, we would have constructed a
+ temporary, and then the function body would have never
+ changed the value of P. However, now, we will be
+ constructing VAR directly. The constructor body may
+ change its value multiple times as it is being
+ constructed. Therefore, it must not be TREE_READONLY;
+ the back-end assumes that TREE_READONLY variable is
+ assigned to only once. */
+ if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (p)))
+ TREE_READONLY (var) = 0;
+
+ /* Initialize this VAR_DECL from the equivalent argument. Convert
+ the argument to the proper type in case it was promoted. */
+ if (value)
+ {
+ tree rhs = convert (TREE_TYPE (var), value);
+
+ if (rhs == error_mark_node)
+ return;
+
+ /* We want to use MODIFY_EXPR, not INIT_EXPR here so that we
+ keep our trees in gimple form. */
+ init_stmt = build (MODIFY_EXPR, TREE_TYPE (var), var, rhs);
+ append_to_statement_list (init_stmt, init_stmts);
+
+ /* If we did not create a gimple value and we did not create a gimple
+ cast of a gimple value, then we will need to gimplify INIT_STMTS
+ at the end. Note that is_gimple_cast only checks the outer
+ tree code, not its operand. Thus the explicit check that it's
+ operand is a gimple value. */
+ if (!is_gimple_val (rhs)
+ && (!is_gimple_cast (rhs)
+ || !is_gimple_val (TREE_OPERAND (rhs, 0))))
+ *gimplify_init_stmts_p = true;
+ }
+}
+
/* Generate code to initialize the parameters of the function at the
top of the stack in ID from the ARGS (presented as a TREE_LIST). */
static tree
-#ifndef INLINER_FOR_JAVA
-initialize_inlined_parameters (inline_data *id, tree args, tree fn)
-#else /* INLINER_FOR_JAVA */
-initialize_inlined_parameters (inline_data *id, tree args, tree fn, tree block)
-#endif /* INLINER_FOR_JAVA */
+initialize_inlined_parameters (inline_data *id, tree args, tree static_chain,
+ tree fn, tree bind_expr)
{
- tree init_stmts;
+ tree init_stmts = NULL_TREE;
tree parms;
tree a;
tree p;
-#ifdef INLINER_FOR_JAVA
tree vars = NULL_TREE;
-#endif /* INLINER_FOR_JAVA */
+ bool gimplify_init_stmts_p = false;
int argnum = 0;
/* Figure out what the parameters are. */
parms = DECL_ARGUMENTS (fn);
- if (fn == current_function_decl && cfun->saved_args)
+ if (fn == current_function_decl)
parms = cfun->saved_args;
- /* Start with no initializations whatsoever. */
- init_stmts = NULL_TREE;
-
/* Loop through the parameter declarations, replacing each with an
equivalent VAR_DECL, appropriately initialized. */
for (p = parms, a = args; p;
a = a ? TREE_CHAIN (a) : a, p = TREE_CHAIN (p))
{
-#ifndef INLINER_FOR_JAVA
- tree init_stmt;
- tree cleanup;
-#endif /* not INLINER_FOR_JAVA */
- tree var;
tree value;
- tree var_sub;
++argnum;
@@ -806,148 +834,34 @@ initialize_inlined_parameters (inline_data *id, tree args, tree fn, tree block)
value = lang_hooks.tree_inlining.convert_parm_for_inlining
(p, a ? TREE_VALUE (a) : NULL_TREE, fn, argnum);
- /* If the parameter is never assigned to, we may not need to
- create a new variable here at all. Instead, we may be able
- to just use the argument value. */
- if (TREE_READONLY (p)
- && !TREE_ADDRESSABLE (p)
- && value && !TREE_SIDE_EFFECTS (value))
- {
- /* Simplify the value, if possible. */
- value = fold (DECL_P (value) ? decl_constant_value (value) : value);
-
- /* We can't risk substituting complex expressions. They
- might contain variables that will be assigned to later.
- Theoretically, we could check the expression to see if
- all of the variables that determine its value are
- read-only, but we don't bother. */
- if (TREE_CONSTANT (value) || TREE_READONLY_DECL_P (value))
- {
- /* If this is a declaration, wrap it a NOP_EXPR so that
- we don't try to put the VALUE on the list of
- BLOCK_VARS. */
- if (DECL_P (value))
- value = build1 (NOP_EXPR, TREE_TYPE (value), value);
-
- /* If this is a constant, make sure it has the right type. */
- else if (TREE_TYPE (value) != TREE_TYPE (p))
- value = fold (build1 (NOP_EXPR, TREE_TYPE (p), value));
-
- insert_decl_map (id, p, value);
- continue;
- }
- }
-
- /* Make an equivalent VAR_DECL. */
- var = copy_decl_for_inlining (p, fn, VARRAY_TREE (id->fns, 0));
-
- /* See if the frontend wants to pass this by invisible reference. If
- so, our new VAR_DECL will have REFERENCE_TYPE, and we need to
- replace uses of the PARM_DECL with dereferences. */
- if (TREE_TYPE (var) != TREE_TYPE (p)
- && POINTER_TYPE_P (TREE_TYPE (var))
- && TREE_TYPE (TREE_TYPE (var)) == TREE_TYPE (p))
- var_sub = build1 (INDIRECT_REF, TREE_TYPE (p), var);
- else
- var_sub = var;
-
- /* Register the VAR_DECL as the equivalent for the PARM_DECL;
- that way, when the PARM_DECL is encountered, it will be
- automatically replaced by the VAR_DECL. */
- insert_decl_map (id, p, var_sub);
-
- /* Declare this new variable. */
-#ifndef INLINER_FOR_JAVA
- init_stmt = build_stmt (DECL_STMT, var);
- TREE_CHAIN (init_stmt) = init_stmts;
- init_stmts = init_stmt;
-#else /* INLINER_FOR_JAVA */
- TREE_CHAIN (var) = vars;
- vars = var;
-#endif /* INLINER_FOR_JAVA */
-
- /* Initialize this VAR_DECL from the equivalent argument. If
- the argument is an object, created via a constructor or copy,
- this will not result in an extra copy: the TARGET_EXPR
- representing the argument will be bound to VAR, and the
- object will be constructed in VAR. */
- if (! TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (p)))
-#ifndef INLINER_FOR_JAVA
- DECL_INITIAL (var) = value;
- else
- {
- /* Even if P was TREE_READONLY, the new VAR should not be.
- In the original code, we would have constructed a
- temporary, and then the function body would have never
- changed the value of P. However, now, we will be
- constructing VAR directly. The constructor body may
- change its value multiple times as it is being
- constructed. Therefore, it must not be TREE_READONLY;
- the back-end assumes that TREE_READONLY variable is
- assigned to only once. */
- TREE_READONLY (var) = 0;
-
- /* Build a run-time initialization. */
- init_stmt = build_stmt (EXPR_STMT,
- build (INIT_EXPR, TREE_TYPE (p),
- var, value));
- /* Add this initialization to the list. Note that we want the
- declaration *after* the initialization because we are going
- to reverse all the initialization statements below. */
- TREE_CHAIN (init_stmt) = init_stmts;
- init_stmts = init_stmt;
- }
-
- /* See if we need to clean up the declaration. */
- cleanup = lang_hooks.maybe_build_cleanup (var);
- if (cleanup)
- {
- tree cleanup_stmt;
- /* Build the cleanup statement. */
- cleanup_stmt = build_stmt (CLEANUP_STMT, var, cleanup);
- /* Add it to the *front* of the list; the list will be
- reversed below. */
- TREE_CHAIN (cleanup_stmt) = init_stmts;
- init_stmts = cleanup_stmt;
- }
-#else /* INLINER_FOR_JAVA */
- {
- tree assignment = build (MODIFY_EXPR, TREE_TYPE (p), var, value);
- init_stmts = add_stmt_to_compound (init_stmts, TREE_TYPE (p),
- assignment);
- }
- else
- {
- /* Java objects don't ever need constructing when being
- passed as arguments because only call by reference is
- supported. */
- abort ();
- }
-#endif /* INLINER_FOR_JAVA */
+ setup_one_parameter (id, p, value, fn, &init_stmts, &vars,
+ &gimplify_init_stmts_p);
}
-#ifndef INLINER_FOR_JAVA
/* Evaluate trailing arguments. */
for (; a; a = TREE_CHAIN (a))
{
- tree init_stmt;
tree value = TREE_VALUE (a);
+ append_to_statement_list (value, &init_stmts);
+ }
- if (! value || ! TREE_SIDE_EFFECTS (value))
- continue;
+ /* Initialize the static chain. */
+ p = DECL_STRUCT_FUNCTION (fn)->static_chain_decl;
+ if (p)
+ {
+ /* No static chain? Seems like a bug in tree-nested.c. */
+ if (!static_chain)
+ abort ();
- init_stmt = build_stmt (EXPR_STMT, value);
- TREE_CHAIN (init_stmt) = init_stmts;
- init_stmts = init_stmt;
+ setup_one_parameter (id, p, static_chain, fn, &init_stmts, &vars,
+ &gimplify_init_stmts_p);
}
- /* The initialization statements have been built up in reverse
- order. Straighten them out now. */
- return nreverse (init_stmts);
-#else /* INLINER_FOR_JAVA */
- BLOCK_VARS (block) = nreverse (vars);
+ if (gimplify_init_stmts_p && lang_hooks.gimple_before_inlining)
+ gimplify_body (&init_stmts, fn);
+
+ declare_inline_vars (bind_expr, vars);
return init_stmts;
-#endif /* INLINER_FOR_JAVA */
}
/* Declare a return variable to replace the RESULT_DECL for the
@@ -955,71 +869,58 @@ initialize_inlined_parameters (inline_data *id, tree args, tree fn, tree block)
The USE_STMT is filled in to contain a use of the declaration to
indicate the return value of the function. */
-#ifndef INLINER_FOR_JAVA
-static tree
-declare_return_variable (struct inline_data *id, tree return_slot_addr,
- tree *use_stmt)
-#else /* INLINER_FOR_JAVA */
static tree
-declare_return_variable (struct inline_data *id, tree return_slot_addr,
- tree *var)
-#endif /* INLINER_FOR_JAVA */
+declare_return_variable (inline_data *id, tree return_slot_addr, tree *use_p)
{
tree fn = VARRAY_TOP_TREE (id->fns);
tree result = DECL_RESULT (fn);
-#ifndef INLINER_FOR_JAVA
- tree var;
-#endif /* not INLINER_FOR_JAVA */
int need_return_decl = 1;
+ tree var;
/* We don't need to do anything for functions that don't return
anything. */
if (!result || VOID_TYPE_P (TREE_TYPE (result)))
{
-#ifndef INLINER_FOR_JAVA
- *use_stmt = NULL_TREE;
-#else /* INLINER_FOR_JAVA */
- *var = NULL_TREE;
-#endif /* INLINER_FOR_JAVA */
+ *use_p = NULL_TREE;
return NULL_TREE;
}
-#ifndef INLINER_FOR_JAVA
var = (lang_hooks.tree_inlining.copy_res_decl_for_inlining
(result, fn, VARRAY_TREE (id->fns, 0), id->decl_map,
&need_return_decl, return_slot_addr));
+
+ /* Do not have the rest of GCC warn about this variable as it should
+ not be visible to the user. */
+ TREE_NO_WARNING (var) = 1;
/* Register the VAR_DECL as the equivalent for the RESULT_DECL; that
way, when the RESULT_DECL is encountered, it will be
automatically replaced by the VAR_DECL. */
insert_decl_map (id, result, var);
- /* Build the USE_STMT. If the return type of the function was
+ /* Remember this so we can ignore it in remap_decls. */
+ id->retvar = var;
+
+ /* Build the use expr. If the return type of the function was
promoted, convert it back to the expected type. */
- if (TREE_TYPE (var) == TREE_TYPE (TREE_TYPE (fn)))
- *use_stmt = build_stmt (EXPR_STMT, var);
+ if (return_slot_addr)
+ /* The function returns through an explicit return slot, not a normal
+ return value. */
+ *use_p = NULL_TREE;
+ else if (TREE_TYPE (var) == TREE_TYPE (TREE_TYPE (fn)))
+ *use_p = var;
+ else if (TREE_CODE (var) == INDIRECT_REF)
+ *use_p = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (fn)),
+ TREE_OPERAND (var, 0));
+ else if (TREE_ADDRESSABLE (TREE_TYPE (var)))
+ abort ();
else
- *use_stmt = build_stmt (EXPR_STMT,
- build1 (NOP_EXPR, TREE_TYPE (TREE_TYPE (fn)),
- var));
- TREE_ADDRESSABLE (*use_stmt) = 1;
+ *use_p = build1 (NOP_EXPR, TREE_TYPE (TREE_TYPE (fn)), var);
/* Build the declaration statement if FN does not return an
aggregate. */
if (need_return_decl)
- return build_stmt (DECL_STMT, var);
-#else /* INLINER_FOR_JAVA */
- *var = (lang_hooks.tree_inlining.copy_res_decl_for_inlining
- (result, fn, VARRAY_TREE (id->fns, 0), id->decl_map,
- &need_return_decl, return_slot_addr));
-
- splay_tree_insert (id->decl_map,
- (splay_tree_key) result,
- (splay_tree_value) *var);
- DECL_IGNORED_P (*var) = 1;
- if (need_return_decl)
- return *var;
-#endif /* INLINER_FOR_JAVA */
+ return var;
/* If FN does return an aggregate, there's no need to declare the
return variable; we're using a variable in our caller's frame. */
else
@@ -1073,7 +974,7 @@ inline_forbidden_p_1 (tree *nodep, int *walk_subtrees ATTRIBUTE_UNUSED,
return node;
}
- if (DECL_BUILT_IN (t))
+ if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL)
switch (DECL_FUNCTION_CODE (t))
{
/* We cannot inline functions that take a variable number of
@@ -1082,49 +983,48 @@ inline_forbidden_p_1 (tree *nodep, int *walk_subtrees ATTRIBUTE_UNUSED,
case BUILT_IN_STDARG_START:
case BUILT_IN_NEXT_ARG:
case BUILT_IN_VA_END:
- {
- inline_forbidden_reason
- = N_("%Jfunction '%F' can never be inlined because it "
- "uses variable argument lists");
- return node;
- }
+ inline_forbidden_reason
+ = N_("%Jfunction '%F' can never be inlined because it "
+ "uses variable argument lists");
+ return node;
+
case BUILT_IN_LONGJMP:
- {
- /* We can't inline functions that call __builtin_longjmp at
- all. The non-local goto machinery really requires the
- destination be in a different function. If we allow the
- function calling __builtin_longjmp to be inlined into the
- function calling __builtin_setjmp, Things will Go Awry. */
- /* ??? Need front end help to identify "regular" non-local
- goto. */
- if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL)
- {
- inline_forbidden_reason
- = N_("%Jfunction '%F' can never be inlined because "
- "it uses setjmp-longjmp exception handling");
- return node;
- }
- }
+ /* We can't inline functions that call __builtin_longjmp at
+ all. The non-local goto machinery really requires the
+ destination be in a different function. If we allow the
+ function calling __builtin_longjmp to be inlined into the
+ function calling __builtin_setjmp, Things will Go Awry. */
+ inline_forbidden_reason
+ = N_("%Jfunction '%F' can never be inlined because "
+ "it uses setjmp-longjmp exception handling");
+ return node;
+
+ case BUILT_IN_NONLOCAL_GOTO:
+ /* Similarly. */
+ inline_forbidden_reason
+ = N_("%Jfunction '%F' can never be inlined because "
+ "it uses non-local goto");
+ return node;
default:
break;
}
break;
-#ifndef INLINER_FOR_JAVA
- case DECL_STMT:
- /* We cannot inline functions that contain other functions. */
- if (TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
- && DECL_INITIAL (TREE_OPERAND (node, 0)))
+ case BIND_EXPR:
+ for (t = BIND_EXPR_VARS (node); t ; t = TREE_CHAIN (t))
{
- inline_forbidden_reason
- = N_("%Jfunction '%F' can never be inlined "
- "because it contains a nested function");
- return node;
+ /* We cannot inline functions that contain other functions. */
+ if (TREE_CODE (t) == FUNCTION_DECL && DECL_INITIAL (t))
+ {
+ inline_forbidden_reason
+ = N_("%Jfunction '%F' can never be inlined "
+ "because it contains a nested function");
+ return node;
+ }
}
break;
- case GOTO_STMT:
case GOTO_EXPR:
t = TREE_OPERAND (node, 0);
@@ -1139,17 +1039,19 @@ inline_forbidden_p_1 (tree *nodep, int *walk_subtrees ATTRIBUTE_UNUSED,
"because it contains a computed goto");
return node;
}
+ break;
- /* We cannot inline a nested function that jumps to a nonlocal
- label. */
- if (TREE_CODE (t) == LABEL_DECL && DECL_CONTEXT (t) != fn)
+ case LABEL_EXPR:
+ t = TREE_OPERAND (node, 0);
+ if (DECL_NONLOCAL (t))
{
+ /* We cannot inline a function that receives a non-local goto
+ because we cannot remap the destination label used in the
+ function that is performing the non-local goto. */
inline_forbidden_reason
= N_("%Jfunction '%F' can never be inlined "
- "because it contains a nonlocal goto");
- return node;
+ "because it receives a non-local goto");
}
-
break;
case RECORD_TYPE:
@@ -1172,7 +1074,7 @@ inline_forbidden_p_1 (tree *nodep, int *walk_subtrees ATTRIBUTE_UNUSED,
"because it uses variable sized variables");
return node;
}
-#endif
+
default:
break;
}
@@ -1271,6 +1173,223 @@ inlinable_function_p (tree fn)
return inlinable;
}
+/* Used by estimate_num_insns. Estimate number of instructions seen
+ by given statement. */
+static tree
+estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
+{
+ int *count = data;
+ tree x = *tp;
+
+ if (TYPE_P (x) || DECL_P (x))
+ {
+ *walk_subtrees = 0;
+ return NULL;
+ }
+ /* Assume that constants and references counts nothing. These should
+ be majorized by amount of operations among them we count later
+ and are common target of CSE and similar optimizations. */
+ if (TREE_CODE_CLASS (TREE_CODE (x)) == 'c'
+ || TREE_CODE_CLASS (TREE_CODE (x)) == 'r')
+ return NULL;
+ switch (TREE_CODE (x))
+ {
+ /* Containers have no cost. */
+ case TREE_LIST:
+ case TREE_VEC:
+ case BLOCK:
+ case COMPONENT_REF:
+ case BIT_FIELD_REF:
+ case INDIRECT_REF:
+ case BUFFER_REF:
+ case ARRAY_REF:
+ case ARRAY_RANGE_REF:
+ case VTABLE_REF:
+ case EXC_PTR_EXPR: /* ??? */
+ case FILTER_EXPR: /* ??? */
+ case COMPOUND_EXPR:
+ case BIND_EXPR:
+ case LABELED_BLOCK_EXPR:
+ case WITH_CLEANUP_EXPR:
+ case NOP_EXPR:
+ case VIEW_CONVERT_EXPR:
+ case SAVE_EXPR:
+ case UNSAVE_EXPR:
+ case ADDR_EXPR:
+ case REFERENCE_EXPR:
+ case COMPLEX_EXPR:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ case EXIT_BLOCK_EXPR:
+ case CASE_LABEL_EXPR:
+ case SSA_NAME:
+ case CATCH_EXPR:
+ case EH_FILTER_EXPR:
+ case STATEMENT_LIST:
+ case ERROR_MARK:
+ case NON_LVALUE_EXPR:
+ case ENTRY_VALUE_EXPR:
+ case FDESC_EXPR:
+ case VA_ARG_EXPR:
+ case TRY_CATCH_EXPR:
+ case TRY_FINALLY_EXPR:
+ case LABEL_EXPR:
+ case GOTO_EXPR:
+ case RETURN_EXPR:
+ case EXIT_EXPR:
+ case LOOP_EXPR:
+ case EUSE_NODE:
+ case EKILL_NODE:
+ case EPHI_NODE:
+ case EEXIT_NODE:
+ case PHI_NODE:
+ break;
+ /* We don't account constants for now. Assume that the cost is amortized
+ by operations that do use them. We may re-consider this decision once
+ we are able to optimize the tree before estimating it's size and break
+ out static initializers. */
+ case IDENTIFIER_NODE:
+ case INTEGER_CST:
+ case REAL_CST:
+ case COMPLEX_CST:
+ case VECTOR_CST:
+ case STRING_CST:
+ *walk_subtrees = 0;
+ return NULL;
+ /* Recognize assignments of large structures and constructors of
+ big arrays. */
+ case INIT_EXPR:
+ case TARGET_EXPR:
+ case MODIFY_EXPR:
+ case CONSTRUCTOR:
+ {
+ HOST_WIDE_INT size;
+
+ size = int_size_in_bytes (TREE_TYPE (x));
+
+ if (size < 0 || size > MOVE_MAX_PIECES * MOVE_RATIO)
+ *count += 10;
+ else
+ *count += ((size + MOVE_MAX_PIECES - 1) / MOVE_MAX_PIECES);
+ }
+ break;
+
+ /* Assign cost of 1 to usual operations.
+ ??? We may consider mapping RTL costs to this. */
+ case COND_EXPR:
+
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+
+ case FIX_TRUNC_EXPR:
+ case FIX_CEIL_EXPR:
+ case FIX_FLOOR_EXPR:
+ case FIX_ROUND_EXPR:
+
+ case NEGATE_EXPR:
+ case FLOAT_EXPR:
+ case MIN_EXPR:
+ case MAX_EXPR:
+ case ABS_EXPR:
+
+ case LSHIFT_EXPR:
+ case RSHIFT_EXPR:
+ case LROTATE_EXPR:
+ case RROTATE_EXPR:
+
+ case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ case BIT_AND_EXPR:
+ case BIT_NOT_EXPR:
+
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_ORIF_EXPR:
+ case TRUTH_AND_EXPR:
+ case TRUTH_OR_EXPR:
+ case TRUTH_XOR_EXPR:
+ case TRUTH_NOT_EXPR:
+
+ case LT_EXPR:
+ case LE_EXPR:
+ case GT_EXPR:
+ case GE_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ case ORDERED_EXPR:
+ case UNORDERED_EXPR:
+
+ case UNLT_EXPR:
+ case UNLE_EXPR:
+ case UNGT_EXPR:
+ case UNGE_EXPR:
+ case UNEQ_EXPR:
+
+ case CONVERT_EXPR:
+
+ case CONJ_EXPR:
+
+ case PREDECREMENT_EXPR:
+ case PREINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+
+ case SWITCH_EXPR:
+
+ case ASM_EXPR:
+
+ case RESX_EXPR:
+ *count++;
+ break;
+
+ /* Few special cases of expensive operations. This is usefull
+ to avoid inlining on functions having too many of these. */
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case EXACT_DIV_EXPR:
+ case TRUNC_MOD_EXPR:
+ case CEIL_MOD_EXPR:
+ case FLOOR_MOD_EXPR:
+ case ROUND_MOD_EXPR:
+ case RDIV_EXPR:
+ *count += 10;
+ break;
+ case CALL_EXPR:
+ {
+ tree decl = get_callee_fndecl (x);
+
+ if (decl && DECL_BUILT_IN (decl))
+ switch (DECL_FUNCTION_CODE (decl))
+ {
+ case BUILT_IN_CONSTANT_P:
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ case BUILT_IN_EXPECT:
+ return NULL_TREE;
+ default:
+ break;
+ }
+ *count += 10;
+ break;
+ }
+ default:
+ /* Abort here se we know we don't miss any nodes. */
+ abort ();
+ }
+ return NULL;
+}
+
+/* Estimate number of instructions that will be created by expanding EXPR. */
+int
+estimate_num_insns (tree expr)
+{
+ int num = 0;
+ walk_tree_without_duplicates (&expr, estimate_num_insns_1, &num);
+ return num;
+}
+
/* If *TP is a CALL_EXPR, replace it with its inline expansion. */
static tree
@@ -1280,19 +1399,16 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
tree t;
tree expr;
tree stmt;
-#ifndef INLINER_FOR_JAVA
- tree chain;
- tree scope_stmt;
- tree use_stmt;
-#else /* INLINER_FOR_JAVA */
- tree retvar;
-#endif /* INLINER_FOR_JAVA */
+ tree use_retvar;
+ tree decl;
tree fn;
tree arg_inits;
tree *inlined_body;
+ tree inline_result;
splay_tree st;
tree args;
tree return_slot_addr;
+ location_t saved_location;
struct cgraph_edge *edge;
const char *reason;
@@ -1300,11 +1416,17 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
id = (inline_data *) data;
t = *tp;
+ /* Set input_location here so we get the right instantiation context
+ if we call instantiate_decl from inlinable_function_p. */
+ saved_location = input_location;
+ if (EXPR_HAS_LOCATION (t))
+ input_location = EXPR_LOCATION (t);
+
/* Recurse, but letting recursive invocations know that we are
inside the body of a TARGET_EXPR. */
if (TREE_CODE (*tp) == TARGET_EXPR)
{
-#ifndef INLINER_FOR_JAVA
+#if 0
int i, len = first_rtl_op (TARGET_EXPR);
/* We're walking our own subtrees. */
@@ -1323,23 +1445,8 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
--id->in_target_cleanup_p;
}
- return NULL_TREE;
-#else /* INLINER_FOR_JAVA */
- abort ();
-#endif /* INLINER_FOR_JAVA */
- }
- else if (TREE_CODE (t) == EXPR_WITH_FILE_LOCATION)
- {
- /* We're walking the subtree directly. */
- *walk_subtrees = 0;
- /* Update the source position. */
- push_srcloc (EXPR_WFL_FILENAME (t), EXPR_WFL_LINENO (t));
- walk_tree (&EXPR_WFL_NODE (t), expand_call_inline, data,
- id->tree_pruner);
- /* Restore the original source position. */
- pop_srcloc ();
-
- return NULL_TREE;
+ goto egress;
+#endif
}
if (TYPE_P (t))
@@ -1350,13 +1457,13 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
/* From here on, we're only interested in CALL_EXPRs. */
if (TREE_CODE (t) != CALL_EXPR)
- return NULL_TREE;
+ goto egress;
/* First, see if we can figure out what function is being called.
If we cannot, then there is no hope of inlining the function. */
fn = get_callee_fndecl (t);
if (!fn)
- return NULL_TREE;
+ goto egress;
/* Turn forward declarations into real ones. */
fn = cgraph_node (fn)->decl;
@@ -1376,7 +1483,7 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
/* Objective C and fortran still calls tree_rest_of_compilation directly.
Kill this check once this is fixed. */
if (!id->current_node->analyzed)
- return NULL_TREE;
+ goto egress;
edge = cgraph_edge (id->current_node, t);
@@ -1386,12 +1493,15 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
{
struct cgraph_node *dest = cgraph_node (fn);
- /* FN must have address taken so it can be passed as argument. */
+ /* We have missing edge in the callgraph. This can happen in one case
+ where previous inlining turned indirect call into direct call by
+ constant propagating arguments. In all other cases we hit a bug
+ (incorrect node sharing is most common reason for missing edges. */
if (!dest->needed)
abort ();
cgraph_create_edge (id->node, dest, t)->inline_failed
= N_("originally indirect function call not considered for inlining");
- return NULL_TREE;
+ goto egress;
}
/* Don't try to inline functions that are not well-suited to
@@ -1410,7 +1520,7 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
warning ("%Jinlining failed in call to '%F': %s", fn, fn, reason);
warning ("called from here");
}
- return NULL_TREE;
+ goto egress;
}
#ifdef ENABLE_CHECKING
@@ -1419,36 +1529,16 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
#endif
if (! lang_hooks.tree_inlining.start_inlining (fn))
- return NULL_TREE;
+ goto egress;
- /* Set the current filename and line number to the function we are
- inlining so that when we create new _STMT nodes here they get
- line numbers corresponding to the function we are calling. We
- wrap the whole inlined body in an EXPR_WITH_FILE_AND_LINE as well
- because individual statements don't record the filename. */
- push_srcloc (DECL_SOURCE_FILE (fn), DECL_SOURCE_LINE (fn));
-
-#ifndef INLINER_FOR_JAVA
- /* Build a statement-expression containing code to initialize the
- arguments, the actual inline expansion of the body, and a label
- for the return statements within the function to jump to. The
- type of the statement expression is the return type of the
- function call. */
- expr = build1 (STMT_EXPR, TREE_TYPE (TREE_TYPE (fn)), make_node (COMPOUND_STMT));
- /* There is no scope associated with the statement-expression. */
- STMT_EXPR_NO_SCOPE (expr) = 1;
- if (lookup_attribute ("warn_unused_result",
- TYPE_ATTRIBUTES (TREE_TYPE (fn))))
- STMT_EXPR_WARN_UNUSED_RESULT (expr) = 1;
- stmt = STMT_EXPR_STMT (expr);
-#else /* INLINER_FOR_JAVA */
/* Build a block containing code to initialize the arguments, the
actual inline expansion of the body, and a label for the return
statements within the function to jump to. The type of the
statement expression is the return type of the function call. */
stmt = NULL;
- expr = build (BLOCK, TREE_TYPE (TREE_TYPE (fn)));
-#endif /* INLINER_FOR_JAVA */
+ expr = build (BIND_EXPR, TREE_TYPE (TREE_TYPE (fn)), NULL_TREE,
+ stmt, make_node (BLOCK));
+ BLOCK_ABSTRACT_ORIGIN (BIND_EXPR_BLOCK (expr)) = fn;
/* Local declarations will be replaced by their equivalents in this
map. */
@@ -1463,33 +1553,29 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
{
return_slot_addr = TREE_VALUE (args);
args = TREE_CHAIN (args);
+ TREE_TYPE (expr) = void_type_node;
}
-#ifndef INLINER_FOR_JAVA
- arg_inits = initialize_inlined_parameters (id, args, fn);
- /* Expand any inlined calls in the initializers. Do this before we
- push FN on the stack of functions we are inlining; we want to
- inline calls to FN that appear in the initializers for the
- parameters. */
- expand_calls_inline (&arg_inits, id);
- /* And add them to the tree. */
- COMPOUND_BODY (stmt) = chainon (COMPOUND_BODY (stmt), arg_inits);
-#else /* INLINER_FOR_JAVA */
- arg_inits = initialize_inlined_parameters (id, args, fn, expr);
+ arg_inits = initialize_inlined_parameters (id, args, TREE_OPERAND (t, 2),
+ fn, expr);
if (arg_inits)
{
/* Expand any inlined calls in the initializers. Do this before we
push FN on the stack of functions we are inlining; we want to
inline calls to FN that appear in the initializers for the
- parameters. */
+ parameters.
+
+ Note we need to save and restore the saved tree statement iterator
+ to avoid having it clobbered by expand_calls_inline. */
+ tree_stmt_iterator save_tsi;
+
+ save_tsi = id->tsi;
expand_calls_inline (&arg_inits, id);
+ id->tsi = save_tsi;
/* And add them to the tree. */
- BLOCK_EXPR_BODY (expr) = add_stmt_to_compound (BLOCK_EXPR_BODY (expr),
- TREE_TYPE (arg_inits),
- arg_inits);
+ append_to_statement_list (arg_inits, &BIND_EXPR_BODY (expr));
}
-#endif /* INLINER_FOR_JAVA */
/* Record the function we are about to inline so that we can avoid
recursing into it. */
@@ -1511,45 +1597,18 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
/* Return statements in the function body will be replaced by jumps
to the RET_LABEL. */
id->ret_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+ DECL_ARTIFICIAL (id->ret_label) = 1;
DECL_CONTEXT (id->ret_label) = VARRAY_TREE (id->fns, 0);
+ insert_decl_map (id, id->ret_label, id->ret_label);
if (! DECL_INITIAL (fn)
|| TREE_CODE (DECL_INITIAL (fn)) != BLOCK)
abort ();
-#ifndef INLINER_FOR_JAVA
- /* Create a block to put the parameters in. We have to do this
- after the parameters have been remapped because remapping
- parameters is different from remapping ordinary variables. */
- scope_stmt = build_stmt (SCOPE_STMT, DECL_INITIAL (fn));
- SCOPE_BEGIN_P (scope_stmt) = 1;
- SCOPE_NO_CLEANUPS_P (scope_stmt) = 1;
- remap_block (scope_stmt, DECL_ARGUMENTS (fn), id);
- TREE_CHAIN (scope_stmt) = COMPOUND_BODY (stmt);
- COMPOUND_BODY (stmt) = scope_stmt;
-
- /* Tell the debugging backends that this block represents the
- outermost scope of the inlined function. */
- if (SCOPE_STMT_BLOCK (scope_stmt))
- BLOCK_ABSTRACT_ORIGIN (SCOPE_STMT_BLOCK (scope_stmt)) = DECL_ORIGIN (fn);
-
/* Declare the return variable for the function. */
- COMPOUND_BODY (stmt)
- = chainon (COMPOUND_BODY (stmt),
- declare_return_variable (id, return_slot_addr, &use_stmt));
-#else /* INLINER_FOR_JAVA */
- {
- /* Declare the return variable for the function. */
- tree decl = declare_return_variable (id, return_slot_addr, &retvar);
- if (retvar)
- {
- tree *next = &BLOCK_VARS (expr);
- while (*next)
- next = &TREE_CHAIN (*next);
- *next = decl;
- }
- }
-#endif /* INLINER_FOR_JAVA */
+ decl = declare_return_variable (id, return_slot_addr, &use_retvar);
+ if (decl)
+ declare_inline_vars (expr, decl);
/* After we've initialized the parameters, we insert the body of the
function itself. */
@@ -1557,67 +1616,25 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
struct cgraph_node *old_node = id->current_node;
id->current_node = edge->callee;
-#ifndef INLINER_FOR_JAVA
- inlined_body = &COMPOUND_BODY (stmt);
- while (*inlined_body)
- inlined_body = &TREE_CHAIN (*inlined_body);
- *inlined_body = copy_body (id);
-#else /* INLINER_FOR_JAVA */
- {
- tree new_body;
- java_inlining_map_static_initializers (fn, id->decl_map);
- new_body = copy_body (id);
- TREE_TYPE (new_body) = TREE_TYPE (TREE_TYPE (fn));
- BLOCK_EXPR_BODY (expr)
- = add_stmt_to_compound (BLOCK_EXPR_BODY (expr),
- TREE_TYPE (new_body), new_body);
- inlined_body = &BLOCK_EXPR_BODY (expr);
- }
-#endif /* INLINER_FOR_JAVA */
+ append_to_statement_list (copy_body (id), &BIND_EXPR_BODY (expr));
id->current_node = old_node;
}
+ inlined_body = &BIND_EXPR_BODY (expr);
/* After the body of the function comes the RET_LABEL. This must come
before we evaluate the returned value below, because that evaluation
may cause RTL to be generated. */
-#ifndef INLINER_FOR_JAVA
- COMPOUND_BODY (stmt)
- = chainon (COMPOUND_BODY (stmt),
- build_stmt (LABEL_STMT, id->ret_label));
-#else /* INLINER_FOR_JAVA */
- {
- tree label = build1 (LABEL_EXPR, void_type_node, id->ret_label);
- BLOCK_EXPR_BODY (expr)
- = add_stmt_to_compound (BLOCK_EXPR_BODY (expr), void_type_node, label);
- TREE_SIDE_EFFECTS (label) = TREE_SIDE_EFFECTS (t);
- }
-#endif /* INLINER_FOR_JAVA */
-
- /* Finally, mention the returned value so that the value of the
- statement-expression is the returned value of the function. */
-#ifndef INLINER_FOR_JAVA
- COMPOUND_BODY (stmt) = chainon (COMPOUND_BODY (stmt), use_stmt);
-
- /* Close the block for the parameters. */
- scope_stmt = build_stmt (SCOPE_STMT, DECL_INITIAL (fn));
- SCOPE_NO_CLEANUPS_P (scope_stmt) = 1;
- remap_block (scope_stmt, NULL_TREE, id);
- COMPOUND_BODY (stmt)
- = chainon (COMPOUND_BODY (stmt), scope_stmt);
-#else /* INLINER_FOR_JAVA */
- if (retvar)
+ if (TREE_USED (id->ret_label))
{
- /* Mention the retvar. If the return type of the function was
- promoted, convert it back to the expected type. */
- if (TREE_TYPE (TREE_TYPE (fn)) != TREE_TYPE (retvar))
- retvar = build1 (NOP_EXPR, TREE_TYPE (TREE_TYPE (fn)), retvar);
- BLOCK_EXPR_BODY (expr)
- = add_stmt_to_compound (BLOCK_EXPR_BODY (expr),
- TREE_TYPE (retvar), retvar);
+ tree label = build1 (LABEL_EXPR, void_type_node, id->ret_label);
+ append_to_statement_list (label, &BIND_EXPR_BODY (expr));
}
- java_inlining_merge_static_initializers (fn, id->decl_map);
-#endif /* INLINER_FOR_JAVA */
+ /* Finally, mention the returned value so that the value of the
+ statement-expression is the returned value of the function. */
+ if (use_retvar)
+ /* Set TREE_TYPE on BIND_EXPR? */
+ append_to_statement_list_force (use_retvar, &BIND_EXPR_BODY (expr));
/* Clean up. */
splay_tree_delete (id->decl_map);
@@ -1626,19 +1643,54 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
/* The new expression has side-effects if the old one did. */
TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (t);
- /* Replace the call by the inlined body. Wrap it in an
- EXPR_WITH_FILE_LOCATION so that we'll get debugging line notes
- pointing to the right place. */
-#ifndef INLINER_FOR_JAVA
- chain = TREE_CHAIN (*tp);
-#endif /* INLINER_FOR_JAVA */
- *tp = build_expr_wfl (expr, DECL_SOURCE_FILE (fn), DECL_SOURCE_LINE (fn),
- /*col=*/0);
- EXPR_WFL_EMIT_LINE_NOTE (*tp) = 1;
-#ifndef INLINER_FOR_JAVA
- TREE_CHAIN (*tp) = chain;
-#endif /* not INLINER_FOR_JAVA */
- pop_srcloc ();
+ /* If we are working with gimple form, then we need to keep the tree
+ in gimple form. If we are not in gimple form, we can just replace
+ *tp with the new BIND_EXPR. */
+ if (lang_hooks.gimple_before_inlining)
+ {
+ tree save_decl;
+
+ /* Keep the new trees in gimple form. */
+ BIND_EXPR_BODY (expr)
+ = rationalize_compound_expr (BIND_EXPR_BODY (expr));
+
+ /* We want to create a new variable to hold the result of the
+ inlined body. This new variable needs to be added to the
+ function which we are inlining into, thus the saving and
+ restoring of current_function_decl. */
+ save_decl = current_function_decl;
+ current_function_decl = id->node->decl;
+ inline_result = voidify_wrapper_expr (expr);
+ current_function_decl = save_decl;
+
+ /* If the inlined function returns a result that we care about,
+ then we're going to need to splice in a MODIFY_EXPR. Otherwise
+ the call was a standalone statement and we can just replace it
+ with the BIND_EXPR inline representation of the called function. */
+ if (TREE_CODE (tsi_stmt (id->tsi)) != CALL_EXPR)
+ {
+ tsi_link_before (&id->tsi, expr, TSI_SAME_STMT);
+ *tp = inline_result;
+ }
+ else
+ *tp = expr;
+
+ /* When we gimplify a function call, we may clear TREE_SIDE_EFFECTS
+ on the call if it is to a "const" function. Thus the copy of
+ TREE_SIDE_EFFECTS from the CALL_EXPR to the BIND_EXPR above
+ with result in TREE_SIDE_EFFECTS not being set for the inlined
+ copy of a "const" function.
+
+ Unfortunately, that is wrong as inlining the function
+ can create/expose interesting side effects (such as setting
+ of a return value).
+
+ The easiest solution is to simply recalculate TREE_SIDE_EFFECTS
+ for the toplevel expression. */
+ recalculate_side_effects (expr);
+ }
+ else
+ *tp = expr;
/* If the value of the new expression is ignored, that's OK. We
don't warn about this for CALL_EXPRs, so we shouldn't warn about
@@ -1658,21 +1710,108 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
lang_hooks.tree_inlining.end_inlining (fn);
/* Keep iterating. */
+ egress:
+ input_location = saved_location;
return NULL_TREE;
}
+
+static void
+gimple_expand_calls_inline (tree *stmt_p, inline_data *id)
+{
+ tree stmt = *stmt_p;
+ enum tree_code code = TREE_CODE (stmt);
+ int dummy;
+
+ switch (code)
+ {
+ case STATEMENT_LIST:
+ {
+ tree_stmt_iterator i;
+ tree new;
+
+ for (i = tsi_start (stmt); !tsi_end_p (i); )
+ {
+ id->tsi = i;
+ gimple_expand_calls_inline (tsi_stmt_ptr (i), id);
+
+ new = tsi_stmt (i);
+ if (TREE_CODE (new) == STATEMENT_LIST)
+ {
+ tsi_link_before (&i, new, TSI_SAME_STMT);
+ tsi_delink (&i);
+ }
+ else
+ tsi_next (&i);
+ }
+ }
+ break;
+
+ case COND_EXPR:
+ gimple_expand_calls_inline (&COND_EXPR_THEN (stmt), id);
+ gimple_expand_calls_inline (&COND_EXPR_ELSE (stmt), id);
+ break;
+ case CATCH_EXPR:
+ gimple_expand_calls_inline (&CATCH_BODY (stmt), id);
+ break;
+ case EH_FILTER_EXPR:
+ gimple_expand_calls_inline (&EH_FILTER_FAILURE (stmt), id);
+ break;
+ case TRY_CATCH_EXPR:
+ case TRY_FINALLY_EXPR:
+ gimple_expand_calls_inline (&TREE_OPERAND (stmt, 0), id);
+ gimple_expand_calls_inline (&TREE_OPERAND (stmt, 1), id);
+ break;
+ case BIND_EXPR:
+ gimple_expand_calls_inline (&BIND_EXPR_BODY (stmt), id);
+ break;
+
+ case COMPOUND_EXPR:
+ /* We're gimple. We should have gotten rid of all these. */
+ abort ();
+
+ case RETURN_EXPR:
+ stmt_p = &TREE_OPERAND (stmt, 0);
+ stmt = *stmt_p;
+ if (!stmt || TREE_CODE (stmt) != MODIFY_EXPR)
+ break;
+ /* FALLTHRU */
+ case MODIFY_EXPR:
+ stmt_p = &TREE_OPERAND (stmt, 1);
+ stmt = *stmt_p;
+ if (TREE_CODE (stmt) != CALL_EXPR)
+ break;
+ /* FALLTHRU */
+ case CALL_EXPR:
+ expand_call_inline (stmt_p, &dummy, id);
+ break;
+
+ default:
+ break;
+ }
+}
+
/* Walk over the entire tree *TP, replacing CALL_EXPRs with inline
expansions as appropriate. */
static void
expand_calls_inline (tree *tp, inline_data *id)
{
- /* Search through *TP, replacing all calls to inline functions by
- appropriate equivalents. Use walk_tree in no-duplicates mode
- to avoid exponential time complexity. (We can't just use
- walk_tree_without_duplicates, because of the special TARGET_EXPR
- handling in expand_calls. The hash table is set up in
- optimize_function. */
- walk_tree (tp, expand_call_inline, id, id->tree_pruner);
+ /* If we are not in gimple form, then we want to walk the tree
+ recursively as we do not know anything about the structure
+ of the tree. */
+
+ if (!lang_hooks.gimple_before_inlining)
+ {
+ walk_tree (tp, expand_call_inline, id, id->tree_pruner);
+ return;
+ }
+
+ /* We are in gimple form. We want to stay in gimple form. Walk
+ the statements, inlining calls in each statement. By walking
+ the statements, we have enough information to keep the tree
+ in gimple form as we insert inline bodies. */
+
+ gimple_expand_calls_inline (tp, id);
}
/* Expand calls to inline functions in the body of FN. */
@@ -1731,6 +1870,7 @@ optimize_inline_calls (tree fn)
VARRAY_ACTIVE_SIZE (id.inlined_fns) * sizeof (tree));
DECL_INLINED_FNS (fn) = ifn;
}
+
#ifdef ENABLE_CHECKING
{
struct cgraph_edge *e;
@@ -1800,8 +1940,6 @@ save_body (tree fn, tree *arg_copy)
/* Actually copy the body. */
body = copy_body (&id);
- if (lang_hooks.update_decl_after_saving)
- lang_hooks.update_decl_after_saving (fn, id.decl_map);
/* Clean up. */
splay_tree_delete (id.decl_map);
@@ -1867,12 +2005,11 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
code = TREE_CODE (*tp);
-#ifndef INLINER_FOR_JAVA
/* Even if we didn't, FUNC may have decided that there was nothing
interesting below this point in the tree. */
if (!walk_subtrees)
{
- if (STATEMENT_CODE_P (code) || code == TREE_LIST
+ if (code == TREE_LIST
|| lang_hooks.tree_inlining.tree_chain_matters_p (*tp))
/* But we still need to check our siblings. */
WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
@@ -1880,23 +2017,18 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
return NULL_TREE;
}
- /* Handle common cases up front. */
- if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
-#else /* INLINER_FOR_JAVA */
+ result = (*lang_hooks.tree_inlining.walk_subtrees) (tp, &walk_subtrees, func,
+ data, htab);
+ if (result || ! walk_subtrees)
+ return result;
+
if (code != EXIT_BLOCK_EXPR
&& code != SAVE_EXPR
+ && code != BIND_EXPR
&& IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
-#endif /* INLINER_FOR_JAVA */
{
int i, len;
-#ifndef INLINER_FOR_JAVA
- /* Set lineno here so we get the right instantiation context
- if we call instantiate_decl from inlinable_function_p. */
- if (STATEMENT_CODE_P (code) && !STMT_LINENO_FOR_FN_P (*tp))
- input_line = STMT_LINENO (*tp);
-#endif /* not INLINER_FOR_JAVA */
-
/* Walk over all the sub-trees of this operand. */
len = first_rtl_op (code);
/* TARGET_EXPRs are peculiar: operands 1 and 3 can be the same.
@@ -1906,147 +2038,161 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
--len;
/* Go through the subtrees. We need to do this in forward order so
that the scope of a FOR_EXPR is handled properly. */
+#ifdef DEBUG_WALK_TREE
for (i = 0; i < len; ++i)
WALK_SUBTREE (TREE_OPERAND (*tp, i));
+#else
+ for (i = 0; i < len - 1; ++i)
+ WALK_SUBTREE (TREE_OPERAND (*tp, i));
-#ifndef INLINER_FOR_JAVA
- /* For statements, we also walk the chain so that we cover the
- entire statement tree. */
- if (STATEMENT_CODE_P (code))
+ if (len)
{
- if (code == DECL_STMT
- && DECL_STMT_DECL (*tp)
- && DECL_P (DECL_STMT_DECL (*tp)))
- {
- /* Walk the DECL_INITIAL and DECL_SIZE. We don't want to walk
- into declarations that are just mentioned, rather than
- declared; they don't really belong to this part of the tree.
- And, we can see cycles: the initializer for a declaration can
- refer to the declaration itself. */
- WALK_SUBTREE (DECL_INITIAL (DECL_STMT_DECL (*tp)));
- WALK_SUBTREE (DECL_SIZE (DECL_STMT_DECL (*tp)));
- WALK_SUBTREE (DECL_SIZE_UNIT (DECL_STMT_DECL (*tp)));
- WALK_SUBTREE (TREE_TYPE (*tp));
- }
-
- /* This can be tail-recursion optimized if we write it this way. */
- WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
+ /* The common case is that we may tail recurse here. */
+ if (code != BIND_EXPR
+ && !TREE_CHAIN (*tp))
+ WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len - 1));
+ else
+ WALK_SUBTREE (TREE_OPERAND (*tp, len - 1));
}
+#endif
-#endif /* not INLINER_FOR_JAVA */
- /* We didn't find what we were looking for. */
- return NULL_TREE;
+ if ((*lang_hooks.tree_inlining.tree_chain_matters_p) (*tp))
+ /* Check our siblings. */
+ WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
}
else if (TREE_CODE_CLASS (code) == 'd')
{
WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
}
- else if (TREE_CODE_CLASS (code) == 't')
+ else
{
- WALK_SUBTREE (TYPE_SIZE (*tp));
- WALK_SUBTREE (TYPE_SIZE_UNIT (*tp));
- /* Also examine various special fields, below. */
- }
+ if (TREE_CODE_CLASS (code) == 't')
+ {
+ WALK_SUBTREE (TYPE_SIZE (*tp));
+ WALK_SUBTREE (TYPE_SIZE_UNIT (*tp));
+ /* Also examine various special fields, below. */
+ }
- result = lang_hooks.tree_inlining.walk_subtrees (tp, &walk_subtrees, func,
- data, htab);
- if (result || ! walk_subtrees)
- return result;
+ /* Not one of the easy cases. We must explicitly go through the
+ children. */
+ switch (code)
+ {
+ case ERROR_MARK:
+ case IDENTIFIER_NODE:
+ case INTEGER_CST:
+ case REAL_CST:
+ case VECTOR_CST:
+ case STRING_CST:
+ case REAL_TYPE:
+ case COMPLEX_TYPE:
+ case VECTOR_TYPE:
+ case VOID_TYPE:
+ case BOOLEAN_TYPE:
+ case UNION_TYPE:
+ case ENUMERAL_TYPE:
+ case BLOCK:
+ case RECORD_TYPE:
+ case PLACEHOLDER_EXPR:
+ case SSA_NAME:
+ /* None of thse have subtrees other than those already walked
+ above. */
+ break;
- /* Not one of the easy cases. We must explicitly go through the
- children. */
- switch (code)
- {
- case ERROR_MARK:
- case IDENTIFIER_NODE:
- case INTEGER_CST:
- case REAL_CST:
- case VECTOR_CST:
- case STRING_CST:
- case REAL_TYPE:
- case COMPLEX_TYPE:
- case VECTOR_TYPE:
- case VOID_TYPE:
- case BOOLEAN_TYPE:
- case UNION_TYPE:
- case ENUMERAL_TYPE:
- case BLOCK:
- case RECORD_TYPE:
- case CHAR_TYPE:
- case PLACEHOLDER_EXPR:
- /* None of these have subtrees other than those already walked
- above. */
- break;
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
+ break;
- case POINTER_TYPE:
- case REFERENCE_TYPE:
- WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
- break;
+ case TREE_LIST:
+ WALK_SUBTREE (TREE_VALUE (*tp));
+ WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
+ break;
- case TREE_LIST:
- WALK_SUBTREE (TREE_VALUE (*tp));
- WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
- break;
+ case TREE_VEC:
+ {
+ int len = TREE_VEC_LENGTH (*tp);
- case TREE_VEC:
- {
- int len = TREE_VEC_LENGTH (*tp);
+ if (len == 0)
+ break;
- if (len == 0)
- break;
+ /* Walk all elements but the first. */
+ while (--len)
+ WALK_SUBTREE (TREE_VEC_ELT (*tp, len));
- /* Walk all elements but the first. */
- while (--len)
- WALK_SUBTREE (TREE_VEC_ELT (*tp, len));
+ /* Now walk the first one as a tail call. */
+ WALK_SUBTREE_TAIL (TREE_VEC_ELT (*tp, 0));
+ }
- /* Now walk the first one as a tail call. */
- WALK_SUBTREE_TAIL (TREE_VEC_ELT (*tp, 0));
- }
+ case COMPLEX_CST:
+ WALK_SUBTREE (TREE_REALPART (*tp));
+ WALK_SUBTREE_TAIL (TREE_IMAGPART (*tp));
- case COMPLEX_CST:
- WALK_SUBTREE (TREE_REALPART (*tp));
- WALK_SUBTREE_TAIL (TREE_IMAGPART (*tp));
+ case CONSTRUCTOR:
+ WALK_SUBTREE_TAIL (CONSTRUCTOR_ELTS (*tp));
- case CONSTRUCTOR:
- WALK_SUBTREE_TAIL (CONSTRUCTOR_ELTS (*tp));
+ case METHOD_TYPE:
+ WALK_SUBTREE (TYPE_METHOD_BASETYPE (*tp));
+ /* Fall through. */
- case METHOD_TYPE:
- WALK_SUBTREE (TYPE_METHOD_BASETYPE (*tp));
- /* Fall through. */
+ case FUNCTION_TYPE:
+ WALK_SUBTREE (TREE_TYPE (*tp));
+ {
+ tree arg = TYPE_ARG_TYPES (*tp);
- case FUNCTION_TYPE:
- WALK_SUBTREE (TREE_TYPE (*tp));
- {
- tree arg = TYPE_ARG_TYPES (*tp);
+ /* We never want to walk into default arguments. */
+ for (; arg; arg = TREE_CHAIN (arg))
+ WALK_SUBTREE (TREE_VALUE (arg));
+ }
+ break;
- /* We never want to walk into default arguments. */
- for (; arg; arg = TREE_CHAIN (arg))
- WALK_SUBTREE (TREE_VALUE (arg));
- }
- break;
+ case ARRAY_TYPE:
+ WALK_SUBTREE (TREE_TYPE (*tp));
+ WALK_SUBTREE_TAIL (TYPE_DOMAIN (*tp));
- case ARRAY_TYPE:
- WALK_SUBTREE (TREE_TYPE (*tp));
- WALK_SUBTREE_TAIL (TYPE_DOMAIN (*tp));
+ case INTEGER_TYPE:
+ case CHAR_TYPE:
+ WALK_SUBTREE (TYPE_MIN_VALUE (*tp));
+ WALK_SUBTREE_TAIL (TYPE_MAX_VALUE (*tp));
- case INTEGER_TYPE:
- WALK_SUBTREE (TYPE_MIN_VALUE (*tp));
- WALK_SUBTREE_TAIL (TYPE_MAX_VALUE (*tp));
+ case OFFSET_TYPE:
+ WALK_SUBTREE (TREE_TYPE (*tp));
+ WALK_SUBTREE_TAIL (TYPE_OFFSET_BASETYPE (*tp));
- case OFFSET_TYPE:
- WALK_SUBTREE (TREE_TYPE (*tp));
- WALK_SUBTREE_TAIL (TYPE_OFFSET_BASETYPE (*tp));
+ case EXIT_BLOCK_EXPR:
+ WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 1));
-#ifdef INLINER_FOR_JAVA
- case EXIT_BLOCK_EXPR:
- WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 1));
+ case SAVE_EXPR:
+ WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0));
- case SAVE_EXPR:
- WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0));
-#endif /* INLINER_FOR_JAVA */
+ case BIND_EXPR:
+ {
+ tree decl;
+ for (decl = BIND_EXPR_VARS (*tp); decl; decl = TREE_CHAIN (decl))
+ {
+ /* Walk the DECL_INITIAL and DECL_SIZE. We don't want to walk
+ into declarations that are just mentioned, rather than
+ declared; they don't really belong to this part of the tree.
+ And, we can see cycles: the initializer for a declaration can
+ refer to the declaration itself. */
+ WALK_SUBTREE (DECL_INITIAL (decl));
+ WALK_SUBTREE (DECL_SIZE (decl));
+ WALK_SUBTREE (DECL_SIZE_UNIT (decl));
+ WALK_SUBTREE (TREE_TYPE (decl));
+ }
+ WALK_SUBTREE_TAIL (BIND_EXPR_BODY (*tp));
+ }
- default:
- abort ();
+ case STATEMENT_LIST:
+ {
+ tree_stmt_iterator i;
+ for (i = tsi_start (*tp); !tsi_end_p (i); tsi_next (&i))
+ WALK_SUBTREE (*tsi_stmt_ptr (i));
+ }
+ break;
+
+ default:
+ abort ();
+ }
}
/* We didn't find what we were looking for. */
@@ -2089,29 +2235,34 @@ copy_tree_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
/* Because the chain gets clobbered when we make a copy, we save it
here. */
tree chain = TREE_CHAIN (*tp);
+ tree new;
/* Copy the node. */
- *tp = copy_node (*tp);
+ new = copy_node (*tp);
+
+ /* Propagate mudflap marked-ness. */
+ if (flag_mudflap && mf_marked_p (*tp))
+ mf_mark (new);
+
+ *tp = new;
/* Now, restore the chain, if appropriate. That will cause
walk_tree to walk into the chain as well. */
if (code == PARM_DECL || code == TREE_LIST
-#ifndef INLINER_FOR_JAVA
- || lang_hooks.tree_inlining.tree_chain_matters_p (*tp)
- || STATEMENT_CODE_P (code))
+ || lang_hooks.tree_inlining.tree_chain_matters_p (*tp))
TREE_CHAIN (*tp) = chain;
/* For now, we don't update BLOCKs when we make copies. So, we
- have to nullify all scope-statements. */
- if (TREE_CODE (*tp) == SCOPE_STMT)
- SCOPE_STMT_BLOCK (*tp) = NULL_TREE;
-#else /* INLINER_FOR_JAVA */
- || lang_hooks.tree_inlining.tree_chain_matters_p (*tp))
- TREE_CHAIN (*tp) = chain;
-#endif /* INLINER_FOR_JAVA */
+ have to nullify all BIND_EXPRs. */
+ if (TREE_CODE (*tp) == BIND_EXPR)
+ BIND_EXPR_BLOCK (*tp) = NULL_TREE;
}
else if (TREE_CODE_CLASS (code) == 't')
*walk_subtrees = 0;
+ else if (TREE_CODE_CLASS (code) == 'd')
+ *walk_subtrees = 0;
+ else if (code == STATEMENT_LIST)
+ abort ();
return NULL_TREE;
}
@@ -2157,19 +2308,148 @@ remap_save_expr (tree *tp, void *st_, tree fn, int *walk_subtrees)
*tp = t;
}
-#ifdef INLINER_FOR_JAVA
-/* Add STMT to EXISTING if possible, otherwise create a new
- COMPOUND_EXPR and add STMT to it. */
+/* Called via walk_tree. If *TP points to a DECL_STMT for a local
+ declaration, copies the declaration and enters it in the splay_tree
+ in DATA (which is really an `inline_data *'). */
+
+static tree
+mark_local_for_remap_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
+ void *data)
+{
+ tree t = *tp;
+ inline_data *id = (inline_data *) data;
+ tree decl;
+
+ /* Don't walk into types. */
+ if (TYPE_P (t))
+ {
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ }
+
+ if (TREE_CODE (t) == LABEL_EXPR)
+ decl = TREE_OPERAND (t, 0);
+ else
+ /* We don't need to handle anything else ahead of time. */
+ decl = NULL_TREE;
+
+ if (decl)
+ {
+ tree copy;
+
+ /* Make a copy. */
+ copy = copy_decl_for_inlining (decl,
+ DECL_CONTEXT (decl),
+ DECL_CONTEXT (decl));
+
+ /* Remember the copy. */
+ insert_decl_map (id, decl, copy);
+ }
+
+ return NULL_TREE;
+}
+
+/* Called via walk_tree when an expression is unsaved. Using the
+ splay_tree pointed to by ST (which is really a `splay_tree'),
+ remaps all local declarations to appropriate replacements. */
static tree
-add_stmt_to_compound (tree existing, tree type, tree stmt)
+unsave_r (tree *tp, int *walk_subtrees, void *data)
{
- if (!stmt)
- return existing;
- else if (existing)
- return build (COMPOUND_EXPR, type, existing, stmt);
+ inline_data *id = (inline_data *) data;
+ splay_tree st = id->decl_map;
+ splay_tree_node n;
+
+ /* Only a local declaration (variable or label). */
+ if ((TREE_CODE (*tp) == VAR_DECL && !TREE_STATIC (*tp))
+ || TREE_CODE (*tp) == LABEL_DECL)
+ {
+ /* Lookup the declaration. */
+ n = splay_tree_lookup (st, (splay_tree_key) *tp);
+
+ /* If it's there, remap it. */
+ if (n)
+ *tp = (tree) n->value;
+ }
+ else if (TREE_CODE (*tp) == STATEMENT_LIST)
+ copy_statement_list (tp);
+ else if (TREE_CODE (*tp) == BIND_EXPR)
+ copy_bind_expr (tp, walk_subtrees, id);
+ else if (TREE_CODE (*tp) == SAVE_EXPR)
+ remap_save_expr (tp, st, current_function_decl, walk_subtrees);
else
- return stmt;
+ {
+ copy_tree_r (tp, walk_subtrees, NULL);
+
+ /* Do whatever unsaving is required. */
+ unsave_expr_1 (*tp);
+ }
+
+ /* Keep iterating. */
+ return NULL_TREE;
}
-#endif /* INLINER_FOR_JAVA */
+/* Default lang hook for "unsave_expr_now". Copies everything in EXPR and
+ replaces variables, labels and SAVE_EXPRs local to EXPR. */
+
+tree
+lhd_unsave_expr_now (tree expr)
+{
+ inline_data id;
+
+ /* There's nothing to do for NULL_TREE. */
+ if (expr == 0)
+ return expr;
+
+ /* Set up ID. */
+ memset (&id, 0, sizeof (id));
+ VARRAY_TREE_INIT (id.fns, 1, "fns");
+ VARRAY_PUSH_TREE (id.fns, current_function_decl);
+ id.decl_map = splay_tree_new (splay_tree_compare_pointers, NULL, NULL);
+
+ /* Walk the tree once to find local labels. */
+ walk_tree_without_duplicates (&expr, mark_local_for_remap_r, &id);
+
+ /* Walk the tree again, copying, remapping, and unsaving. */
+ walk_tree (&expr, unsave_r, &id, NULL);
+
+ /* Clean up. */
+ splay_tree_delete (id.decl_map);
+
+ return expr;
+}
+
+/* Allow someone to determine if SEARCH is a child of TOP from gdb. */
+static tree
+debug_find_tree_1 (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, void *data)
+{
+ if (*tp == data)
+ return (tree) data;
+ else
+ return NULL;
+}
+
+extern bool debug_find_tree (tree top, tree search);
+
+bool
+debug_find_tree (tree top, tree search)
+{
+ return walk_tree_without_duplicates (&top, debug_find_tree_1, search) != 0;
+}
+
+
+/* Declare the variables created by the inliner. Add all the variables in
+ VARS to BIND_EXPR. */
+
+static void
+declare_inline_vars (tree bind_expr, tree vars)
+{
+ if (lang_hooks.gimple_before_inlining)
+ {
+ tree t;
+ for (t = vars; t; t = TREE_CHAIN (t))
+ vars->decl.seen_in_bind_expr = 1;
+ }
+
+ add_var_to_bind_expr (bind_expr, vars);
+}
diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h
index 03a2b0a5ddb..142f5569f58 100644
--- a/gcc/tree-inline.h
+++ b/gcc/tree-inline.h
@@ -26,12 +26,11 @@ Boston, MA 02111-1307, USA. */
void optimize_inline_calls (tree);
bool tree_inlinable_function_p (tree);
-tree walk_tree (tree*, walk_tree_fn, void*, void*);
-tree walk_tree_without_duplicates (tree*, walk_tree_fn, void*);
tree copy_tree_r (tree*, int*, void*);
void clone_body (tree, tree, void*);
tree save_body (tree, tree *);
void remap_save_expr (tree*, void*, tree, int*);
+int estimate_num_insns (tree expr);
/* 0 if we should not perform inlining.
1 if we should expand functions calls inline at the tree level.
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
new file mode 100644
index 00000000000..a569d0536b1
--- /dev/null
+++ b/gcc/tree-into-ssa.c
@@ -0,0 +1,1176 @@
+/* Rewrite a program in Normal form into SSA.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Diego Novillo <dnovillo@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "flags.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "langhooks.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "output.h"
+#include "errors.h"
+#include "expr.h"
+#include "function.h"
+#include "diagnostic.h"
+#include "bitmap.h"
+#include "tree-flow.h"
+#include "tree-gimple.h"
+#include "tree-inline.h"
+#include "varray.h"
+#include "timevar.h"
+#include "tree-alias-common.h"
+#include "hashtab.h"
+#include "tree-dump.h"
+#include "tree-pass.h"
+#include "cfgloop.h"
+#include "domwalk.h"
+
+/* This file builds the SSA form for a function as described in:
+ R. Cytron, J. Ferrante, B. Rosen, M. Wegman, and K. Zadeck. Efficiently
+ Computing Static Single Assignment Form and the Control Dependence
+ Graph. ACM Transactions on Programming Languages and Systems,
+ 13(4):451-490, October 1991. */
+
+
+/* Structure to map a variable VAR to the set of blocks that contain
+ definitions for VAR. */
+struct def_blocks_d
+{
+ /* The variable. */
+ tree var;
+
+ /* Blocks that contain definitions of VAR. Bit I will be set if the
+ Ith block contains a definition of VAR. */
+ bitmap def_blocks;
+
+ /* Blocks where VAR is live-on-entry. Similar semantics as
+ DEF_BLOCKS. */
+ bitmap livein_blocks;
+};
+
+/* Each entry in DEF_BLOCKS contains an element of type STRUCT
+ DEF_BLOCKS_D, mapping a variable VAR to a bitmap describing all the
+ basic blocks where VAR is defined (assigned a new value). It also
+ contains a bitmap of all the blocks where VAR is live-on-entry
+ (i.e., there is a use of VAR in block B without a preceding
+ definition in B). The live-on-entry information is used when
+ computing PHI pruning heuristics. */
+static htab_t def_blocks;
+
+/* Global data to attach to the main dominator walk structure. */
+struct mark_def_sites_global_data
+{
+ /* This sbitmap contains the variables which are set before they
+ are used in a basic block. We keep it as a global variable
+ solely to avoid the overhead of allocating and deallocating
+ the bitmap. */
+ sbitmap kills;
+};
+
+struct rewrite_block_data
+{
+ varray_type block_defs;
+};
+
+
+/* Local functions. */
+static void rewrite_finalize_block (struct dom_walk_data *, basic_block);
+static void rewrite_initialize_block_local_data (struct dom_walk_data *,
+ basic_block, bool);
+static void rewrite_initialize_block (struct dom_walk_data *, basic_block);
+static void rewrite_add_phi_arguments (struct dom_walk_data *, basic_block);
+static void mark_def_sites (struct dom_walk_data *walk_data,
+ basic_block bb, block_stmt_iterator);
+static void mark_def_sites_initialize_block (struct dom_walk_data *walk_data,
+ basic_block bb);
+static void compute_global_livein (bitmap, bitmap);
+static void set_def_block (tree, basic_block);
+static void set_livein_block (tree, basic_block);
+static bool prepare_operand_for_rename (tree *op_p, size_t *uid_p);
+static void insert_phi_nodes (bitmap *);
+static void rewrite_stmt (struct dom_walk_data *, basic_block,
+ block_stmt_iterator);
+static inline void rewrite_operand (tree *);
+static void insert_phi_nodes_for (tree, bitmap *, varray_type *);
+static tree get_reaching_def (tree);
+static hashval_t def_blocks_hash (const void *);
+static int def_blocks_eq (const void *, const void *);
+static void def_blocks_free (void *);
+static int debug_def_blocks_r (void **, void *);
+static inline struct def_blocks_d *get_def_blocks_for (tree);
+static inline struct def_blocks_d *find_def_blocks_for (tree);
+static void htab_statistics (FILE *, htab_t);
+
+/* Compute global livein information given the set of blockx where
+ an object is locally live at the start of the block (LIVEIN)
+ and the set of blocks where the object is defined (DEF_BLOCKS).
+
+ Note: This routine augments the existing local livein information
+ to include global livein (i.e., it modifies the underlying bitmap
+ for LIVEIN). */
+
+static void
+compute_global_livein (bitmap livein, bitmap def_blocks)
+{
+ basic_block bb, *worklist, *tos;
+ int i;
+
+ tos = worklist
+ = (basic_block *) xmalloc (sizeof (basic_block) * (last_basic_block + 1));
+
+ EXECUTE_IF_SET_IN_BITMAP (livein, 0, i,
+ {
+ *tos++ = BASIC_BLOCK (i);
+ });
+
+ /* Iterate until the worklist is empty. */
+ while (tos != worklist)
+ {
+ edge e;
+
+ /* Pull a block off the worklist. */
+ bb = *--tos;
+
+ /* For each predecessor block. */
+ for (e = bb->pred; e; e = e->pred_next)
+ {
+ basic_block pred = e->src;
+ int pred_index = pred->index;
+
+ /* None of this is necessary for the entry block. */
+ if (pred != ENTRY_BLOCK_PTR
+ && ! bitmap_bit_p (livein, pred_index)
+ && ! bitmap_bit_p (def_blocks, pred_index))
+ {
+ *tos++ = pred;
+ bitmap_set_bit (livein, pred_index);
+ }
+ }
+ }
+
+ free (worklist);
+}
+
+
+/* Block initialization routine for mark_def_sites. Clear the
+ KILLS bitmap at the start of each block. */
+
+static void
+mark_def_sites_initialize_block (struct dom_walk_data *walk_data,
+ basic_block bb ATTRIBUTE_UNUSED)
+{
+ struct mark_def_sites_global_data *gd = walk_data->global_data;
+ sbitmap kills = gd->kills;
+
+ sbitmap_zero (kills);
+}
+
+
+/* Call back for walk_dominator_tree used to collect definition sites
+ for every variable in the function. For every statement S in block
+ BB:
+
+ 1- Variables defined by S in DEF_OPS(S) are marked in the bitmap
+ WALK_DATA->GLOBAL_DATA->KILLS.
+
+ 2- If S uses a variable VAR and there is no preceding kill of VAR,
+ then it is marked in marked in the LIVEIN_BLOCKS bitmap
+ associated with VAR.
+
+ This information is used to determine which variables are live
+ across block boundaries to reduce the number of PHI nodes
+ we create. */
+
+static void
+mark_def_sites (struct dom_walk_data *walk_data,
+ basic_block bb,
+ block_stmt_iterator bsi)
+{
+ struct mark_def_sites_global_data *gd = walk_data->global_data;
+ sbitmap kills = gd->kills;
+ vdef_optype vdefs;
+ vuse_optype vuses;
+ def_optype defs;
+ use_optype uses;
+ size_t i, uid;
+ tree stmt;
+ stmt_ann_t ann;
+
+ /* Mark all the blocks that have definitions for each variable in the
+ VARS_TO_RENAME bitmap. */
+ stmt = bsi_stmt (bsi);
+ get_stmt_operands (stmt);
+ ann = stmt_ann (stmt);
+
+ /* If a variable is used before being set, then the variable is live
+ across a block boundary, so mark it live-on-entry to BB. */
+ uses = USE_OPS (ann);
+ for (i = 0; i < NUM_USES (uses); i++)
+ {
+ tree *use_p = USE_OP_PTR (uses, i);
+
+ if (prepare_operand_for_rename (use_p, &uid)
+ && !TEST_BIT (kills, uid))
+ set_livein_block (*use_p, bb);
+ }
+
+ /* Similarly for virtual uses. */
+ vuses = VUSE_OPS (ann);
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ {
+ tree *use_p = VUSE_OP_PTR (vuses, i);
+
+ if (prepare_operand_for_rename (use_p, &uid))
+ set_livein_block (*use_p, bb);
+ }
+
+ /* Note that virtual definitions are irrelevant for computing KILLS
+ because a VDEF does not constitute a killing definition of the
+ variable. However, the operand of a virtual definitions is a use
+ of the variable, so it may cause the variable to be considered
+ live-on-entry. */
+ vdefs = VDEF_OPS (ann);
+ for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ {
+ size_t dummy;
+
+ if (prepare_operand_for_rename (VDEF_OP_PTR (vdefs, i), &uid)
+ && prepare_operand_for_rename (VDEF_RESULT_PTR (vdefs, i), &dummy))
+ {
+ VDEF_RESULT (vdefs, i) = VDEF_OP (vdefs, i);
+
+ set_livein_block (VDEF_OP (vdefs, i), bb);
+ set_def_block (VDEF_RESULT (vdefs, i), bb);
+ }
+ }
+
+ /* Now process the definition made by this statement. Mark the
+ variables in KILLS. */
+ defs = DEF_OPS (ann);
+ for (i = 0; i < NUM_DEFS (defs); i++)
+ {
+ tree *def_p = DEF_OP_PTR (defs, i);
+
+ if (prepare_operand_for_rename (def_p, &uid))
+ {
+ set_def_block (*def_p, bb);
+ SET_BIT (kills, uid);
+ }
+ }
+}
+
+
+/* Mark block BB as the definition site for variable VAR. */
+
+static void
+set_def_block (tree var, basic_block bb)
+{
+ struct def_blocks_d *db_p;
+ enum need_phi_state state = var_ann (var)->need_phi_state;
+
+ db_p = get_def_blocks_for (var);
+
+ /* Set the bit corresponding to the block where VAR is defined. */
+ bitmap_set_bit (db_p->def_blocks, bb->index);
+
+ /* Keep track of whether or not we may need to insert phi nodes.
+
+ If we are in the UNKNOWN state, then this is the first definition
+ of VAR. Additionally, we have not seen any uses of VAR yet, so
+ we do not need a phi node for this variable at this time (i.e.,
+ transition to NEED_PHI_STATE_NO).
+
+ If we are in any other state, then we either have multiple definitions
+ of this variable occurring in different blocks or we saw a use of the
+ variable which was not dominated by the block containing the
+ definition(s). In this case we may need a PHI node, so enter
+ state NEED_PHI_STATE_MAYBE. */
+ if (state == NEED_PHI_STATE_UNKNOWN)
+ var_ann (var)->need_phi_state = NEED_PHI_STATE_NO;
+ else
+ var_ann (var)->need_phi_state = NEED_PHI_STATE_MAYBE;
+}
+
+
+/* Mark block BB as having VAR live at the entry to BB. */
+
+static void
+set_livein_block (tree var, basic_block bb)
+{
+ struct def_blocks_d *db_p;
+ enum need_phi_state state = var_ann (var)->need_phi_state;
+
+ db_p = get_def_blocks_for (var);
+
+ /* Set the bit corresponding to the block where VAR is live in. */
+ bitmap_set_bit (db_p->livein_blocks, bb->index);
+
+ /* Keep track of whether or not we may need to insert phi nodes.
+
+ If we reach here in NEED_PHI_STATE_NO, see if this use is dominated
+ by the single block containing the definition(s) of this variable. If
+ it is, then we remain in NEED_PHI_STATE_NO, otherwise we transition to
+ NEED_PHI_STATE_MAYBE. */
+ if (state == NEED_PHI_STATE_NO)
+ {
+ int def_block_index = bitmap_first_set_bit (db_p->def_blocks);
+
+ if (def_block_index == -1
+ || ! dominated_by_p (CDI_DOMINATORS, bb,
+ BASIC_BLOCK (def_block_index)))
+ var_ann (var)->need_phi_state = NEED_PHI_STATE_MAYBE;
+ }
+ else
+ var_ann (var)->need_phi_state = NEED_PHI_STATE_MAYBE;
+}
+
+
+/* If the operand pointed by OP_P needs to be renamed, strip away SSA_NAME
+ wrappers (if needed) and return true. The unique ID for the operand's
+ variable will be stored in *UID_P. */
+
+static bool
+prepare_operand_for_rename (tree *op_p, size_t *uid_p)
+{
+ tree var = (TREE_CODE (*op_p) != SSA_NAME) ? *op_p : SSA_NAME_VAR (*op_p);
+ *uid_p = var_ann (var)->uid;
+
+ /* Ignore variables that don't need to be renamed. */
+ if (vars_to_rename && !bitmap_bit_p (vars_to_rename, *uid_p))
+ return false;
+
+ /* The variable needs to be renamed. If it already had an
+ SSA_NAME, strip it off. This way, the SSA rename pass
+ doesn't need to deal with existing SSA names. */
+ if (TREE_CODE (*op_p) == SSA_NAME)
+ {
+ if (default_def (SSA_NAME_VAR (*op_p)) != *op_p)
+ release_ssa_name (*op_p);
+ *op_p = var;
+ }
+
+ return true;
+}
+
+
+/* Helper for insert_phi_nodes. If VAR needs PHI nodes, insert them
+ at the dominance frontier (DFS) of blocks defining VAR. */
+
+static inline
+void insert_phi_nodes_1 (tree var, bitmap *dfs, varray_type *work_stack)
+{
+ var_ann_t ann = var_ann (var);
+ if (ann->need_phi_state != NEED_PHI_STATE_NO)
+ insert_phi_nodes_for (var, dfs, work_stack);
+}
+
+
+/* Insert PHI nodes at the dominance frontier of blocks with variable
+ definitions. DFS contains the dominance frontier information for
+ the flowgraph. PHI nodes will only be inserted at the dominance
+ frontier of definition blocks for variables whose NEED_PHI_STATE
+ annotation is marked as ``maybe'' or ``unknown'' (computed by
+ mark_def_sites). */
+
+static void
+insert_phi_nodes (bitmap *dfs)
+{
+ size_t i;
+ varray_type work_stack;
+
+ timevar_push (TV_TREE_INSERT_PHI_NODES);
+
+ /* Array WORK_STACK is a stack of CFG blocks. Each block that contains
+ an assignment or PHI node will be pushed to this stack. */
+ VARRAY_BB_INIT (work_stack, last_basic_block, "work_stack");
+
+ /* Iterate over all variables in VARS_TO_RENAME. For each variable, add
+ to the work list all the blocks that have a definition for the
+ variable. PHI nodes will be added to the dominance frontier blocks of
+ each definition block. */
+ if (vars_to_rename)
+ EXECUTE_IF_SET_IN_BITMAP (vars_to_rename, 0, i,
+ insert_phi_nodes_1 (referenced_var (i), dfs, &work_stack));
+ else
+ for (i = 0; i < num_referenced_vars; i++)
+ insert_phi_nodes_1 (referenced_var (i), dfs, &work_stack);
+
+ timevar_pop (TV_TREE_INSERT_PHI_NODES);
+}
+
+
+/* Perform a depth-first traversal of the dominator tree looking for
+ variables to rename. BB is the block where to start searching.
+ Renaming is a five step process:
+
+ 1- Every definition made by PHI nodes at the start of the blocks is
+ registered as the current definition for the corresponding variable.
+
+ 2- Every statement in BB is rewritten. USE and VUSE operands are
+ rewritten with their corresponding reaching definition. DEF and
+ VDEF targets are registered as new definitions.
+
+ 3- All the PHI nodes in successor blocks of BB are visited. The
+ argument corresponding to BB is replaced with its current reaching
+ definition.
+
+ 4- Recursively rewrite every dominator child block of BB.
+
+ 5- Restore (in reverse order) the current reaching definition for every
+ new definition introduced in this block. This is done so that when
+ we return from the recursive call, all the current reaching
+ definitions are restored to the names that were valid in the
+ dominator parent of BB. */
+
+/* Initialize the local stacks.
+
+ BLOCK_DEFS is used to save all the existing reaching definitions for
+ the new SSA names introduced in this block. Before registering a
+ new definition for a variable, the existing reaching definition is
+ pushed into this stack so that we can restore it in Step 5. */
+
+static void
+rewrite_initialize_block_local_data (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
+ basic_block bb ATTRIBUTE_UNUSED,
+ bool recycled ATTRIBUTE_UNUSED)
+{
+#ifdef ENABLE_CHECKING
+ struct rewrite_block_data *bd
+ = (struct rewrite_block_data *)VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
+
+ /* We get cleared memory from the allocator, so if the memory is
+ not cleared, then we are re-using a previously allocated entry. In
+ that case, we can also re-use the underlying virtal arrays. Just
+ make sure we clear them before using them! */
+ if (recycled && bd->block_defs && VARRAY_ACTIVE_SIZE (bd->block_defs) > 0)
+ abort ();
+#endif
+}
+
+
+/* SSA Rewriting Step 1. Initialization, create a block local stack
+ of reaching definitions for new SSA names produced in this block
+ (BLOCK_DEFS). Register new definitions for every PHI node in the
+ block. */
+
+static void
+rewrite_initialize_block (struct dom_walk_data *walk_data, basic_block bb)
+{
+ tree phi;
+ struct rewrite_block_data *bd
+ = (struct rewrite_block_data *)VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "\n\nRenaming block #%d\n\n", bb->index);
+
+ /* Step 1. Register new definitions for every PHI node in the block.
+ Conceptually, all the PHI nodes are executed in parallel and each PHI
+ node introduces a new version for the associated variable. */
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ tree result = PHI_RESULT (phi);
+
+ register_new_def (result, &bd->block_defs);
+ }
+}
+
+
+/* SSA Rewriting Step 3. Visit all the successor blocks of BB looking for
+ PHI nodes. For every PHI node found, add a new argument containing the
+ current reaching definition for the variable and the edge through which
+ that definition is reaching the PHI node. */
+
+static void
+rewrite_add_phi_arguments (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
+ basic_block bb)
+{
+ edge e;
+
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ tree phi;
+
+ for (phi = phi_nodes (e->dest); phi; phi = TREE_CHAIN (phi))
+ {
+ tree currdef;
+
+ /* If this PHI node has already been rewritten, then there is
+ nothing to do for this PHI or any following PHIs since we
+ always add new PHI nodes at the start of the PHI chain. */
+ if (PHI_REWRITTEN (phi))
+ break;
+
+ currdef = get_reaching_def (SSA_NAME_VAR (PHI_RESULT (phi)));
+ add_phi_arg (&phi, currdef, e);
+ }
+ }
+}
+
+/* SSA Rewriting Step 5. Restore the current reaching definition for each
+ variable referenced in the block (in reverse order). */
+
+static void
+rewrite_finalize_block (struct dom_walk_data *walk_data,
+ basic_block bb ATTRIBUTE_UNUSED)
+{
+ struct rewrite_block_data *bd
+ = (struct rewrite_block_data *)VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
+
+ /* Step 5. Restore the current reaching definition for each variable
+ referenced in the block (in reverse order). */
+ while (bd->block_defs && VARRAY_ACTIVE_SIZE (bd->block_defs) > 0)
+ {
+ tree tmp = VARRAY_TOP_TREE (bd->block_defs);
+ tree saved_def, var;
+
+ VARRAY_POP (bd->block_defs);
+ if (TREE_CODE (tmp) == SSA_NAME)
+ {
+ saved_def = tmp;
+ var = SSA_NAME_VAR (saved_def);
+ }
+ else
+ {
+ saved_def = NULL;
+ var = tmp;
+ }
+
+ var_ann (var)->current_def = saved_def;
+ }
+}
+
+
+/* Dump SSA information to FILE. */
+
+void
+dump_tree_ssa (FILE *file)
+{
+ basic_block bb;
+ const char *funcname
+ = (*lang_hooks.decl_printable_name) (current_function_decl, 2);
+
+ fprintf (file, "SSA information for %s\n\n", funcname);
+
+ FOR_EACH_BB (bb)
+ {
+ dump_bb (bb, file, 0);
+ fputs (" ", file);
+ print_generic_stmt (file, phi_nodes (bb), dump_flags);
+ fputs ("\n\n", file);
+ }
+}
+
+
+/* Dump SSA information to stderr. */
+
+void
+debug_tree_ssa (void)
+{
+ dump_tree_ssa (stderr);
+}
+
+
+/* Dump SSA statistics on FILE. */
+
+void
+dump_tree_ssa_stats (FILE *file)
+{
+ fprintf (file, "\nHash table statistics:\n");
+
+ fprintf (file, " def_blocks: ");
+ htab_statistics (file, def_blocks);
+
+ fprintf (file, "\n");
+}
+
+
+/* Dump SSA statistics on stderr. */
+
+void
+debug_tree_ssa_stats (void)
+{
+ dump_tree_ssa_stats (stderr);
+}
+
+
+/* Dump statistics for the hash table HTAB. */
+
+static void
+htab_statistics (FILE *file, htab_t htab)
+{
+ fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n",
+ (long) htab_size (htab),
+ (long) htab_elements (htab),
+ htab_collisions (htab));
+}
+
+
+/* Insert PHI nodes for variable VAR using the dominance frontier
+ information given in DFS. */
+
+static void
+insert_phi_nodes_for (tree var, bitmap *dfs, varray_type *work_stack)
+{
+ struct def_blocks_d *def_map;
+ bitmap phi_insertion_points;
+ int bb_index;
+
+ def_map = find_def_blocks_for (var);
+ if (def_map == NULL)
+ return;
+
+ phi_insertion_points = BITMAP_XMALLOC ();
+
+ EXECUTE_IF_SET_IN_BITMAP (def_map->def_blocks, 0, bb_index,
+ {
+ VARRAY_PUSH_BB (*work_stack, BASIC_BLOCK (bb_index));
+ });
+
+ /* Pop a block off the worklist, add every block that appears in
+ the original block's dfs that we have not already processed to
+ the worklist. Iterate until the worklist is empty. Blocks
+ which are added to the worklist are potential sites for
+ PHI nodes.
+
+ The iteration step could be done during PHI insertion just as
+ easily. We do it here for historical reasons -- we used to have
+ a heuristic which used the potential PHI insertion points to
+ determine if fully pruned or semi pruned SSA form was appropriate.
+
+ We now always use fully pruned SSA form. */
+ while (VARRAY_ACTIVE_SIZE (*work_stack) > 0)
+ {
+ basic_block bb = VARRAY_TOP_BB (*work_stack);
+ int bb_index = bb->index;
+ int dfs_index;
+
+ VARRAY_POP (*work_stack);
+
+ EXECUTE_IF_AND_COMPL_IN_BITMAP (dfs[bb_index],
+ phi_insertion_points,
+ 0, dfs_index,
+ {
+ basic_block bb = BASIC_BLOCK (dfs_index);
+
+ VARRAY_PUSH_BB (*work_stack, bb);
+ bitmap_set_bit (phi_insertion_points, dfs_index);
+ });
+ }
+
+ /* Now compute global livein for this variable. Note this modifies
+ def_map->livein_blocks. */
+ compute_global_livein (def_map->livein_blocks, def_map->def_blocks);
+
+ /* And insert the PHI nodes. */
+ EXECUTE_IF_AND_IN_BITMAP (phi_insertion_points, def_map->livein_blocks,
+ 0, bb_index,
+ {
+ create_phi_node (var, BASIC_BLOCK (bb_index));
+ });
+
+ BITMAP_XFREE (phi_insertion_points);
+}
+
+/* SSA Rewriting Step 2. Rewrite every variable used in each statement in
+ the block with its immediate reaching definitions. Update the current
+ definition of a variable when a new real or virtual definition is found. */
+
+static void
+rewrite_stmt (struct dom_walk_data *walk_data,
+ basic_block bb ATTRIBUTE_UNUSED,
+ block_stmt_iterator si)
+{
+ size_t i;
+ stmt_ann_t ann;
+ tree stmt;
+ vuse_optype vuses;
+ vdef_optype vdefs;
+ def_optype defs;
+ use_optype uses;
+ struct rewrite_block_data *bd;
+
+ bd = VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
+
+ stmt = bsi_stmt (si);
+ ann = stmt_ann (stmt);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Renaming statement ");
+ print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ fprintf (dump_file, "\n");
+ }
+
+#if defined ENABLE_CHECKING
+ /* We have just scanned the code for operands. No statement should
+ be modified. */
+ if (ann->modified)
+ abort ();
+#endif
+
+ defs = DEF_OPS (ann);
+ uses = USE_OPS (ann);
+ vuses = VUSE_OPS (ann);
+ vdefs = VDEF_OPS (ann);
+
+ /* Step 1. Rewrite USES and VUSES in the statement. */
+ for (i = 0; i < NUM_USES (uses); i++)
+ rewrite_operand (USE_OP_PTR (uses, i));
+
+ /* Rewrite virtual uses in the statement. */
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ rewrite_operand (VUSE_OP_PTR (vuses, i));
+
+ /* Step 2. Register the statement's DEF and VDEF operands. */
+ for (i = 0; i < NUM_DEFS (defs); i++)
+ {
+ tree *def_p = DEF_OP_PTR (defs, i);
+
+ if (TREE_CODE (*def_p) != SSA_NAME)
+ *def_p = make_ssa_name (*def_p, stmt);
+
+ /* FIXME: We shouldn't be registering new defs if the variable
+ doesn't need to be renamed. */
+ register_new_def (*def_p, &bd->block_defs);
+ }
+
+ /* Register new virtual definitions made by the statement. */
+ for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ {
+ rewrite_operand (VDEF_OP_PTR (vdefs, i));
+
+ if (TREE_CODE (VDEF_RESULT (vdefs, i)) != SSA_NAME)
+ *VDEF_RESULT_PTR (vdefs, i)
+ = make_ssa_name (VDEF_RESULT (vdefs, i), stmt);
+
+ /* FIXME: We shouldn't be registering new defs if the variable
+ doesn't need to be renamed. */
+ register_new_def (VDEF_RESULT (vdefs, i), &bd->block_defs);
+ }
+}
+
+
+/* Replace the operand pointed by OP_P with its immediate reaching
+ definition. */
+
+static inline void
+rewrite_operand (tree *op_p)
+{
+ if (TREE_CODE (*op_p) != SSA_NAME)
+ *op_p = get_reaching_def (*op_p);
+}
+
+
+/* Register DEF (an SSA_NAME) to be a new definition for its underlying
+ variable (SSA_NAME_VAR (DEF)) and push VAR's current reaching definition
+ into the stack pointed by BLOCK_DEFS_P. */
+
+void
+register_new_def (tree def, varray_type *block_defs_p)
+{
+ tree var = SSA_NAME_VAR (def);
+ tree currdef;
+
+ /* If this variable is set in a single basic block and all uses are
+ dominated by the set(s) in that single basic block, then there is
+ no reason to record anything for this variable in the block local
+ definition stacks. Doing so just wastes time and memory.
+
+ This is the same test to prune the set of variables which may
+ need PHI nodes. So we just use that information since it's already
+ computed and available for us to use. */
+ if (var_ann (var)->need_phi_state == NEED_PHI_STATE_NO)
+ {
+ var_ann (var)->current_def = def;
+ return;
+ }
+
+ currdef = var_ann (var)->current_def;
+ if (! *block_defs_p)
+ VARRAY_TREE_INIT (*block_defs_p, 20, "block_defs");
+
+ /* Push the current reaching definition into *BLOCK_DEFS_P. This stack is
+ later used by the dominator tree callbacks to restore the reaching
+ definitions for all the variables defined in the block after a recursive
+ visit to all its immediately dominated blocks. If there is no current
+ reaching definition, then just record the underlying _DECL node. */
+ VARRAY_PUSH_TREE (*block_defs_p, currdef ? currdef : var);
+
+ /* Set the current reaching definition for VAR to be DEF. */
+ var_ann (var)->current_def = def;
+}
+
+
+/* Return the current definition for variable VAR. If none is found,
+ create a new SSA name to act as the zeroth definition for VAR. If VAR
+ is call clobbered and there exists a more recent definition of
+ GLOBAL_VAR, return the definition for GLOBAL_VAR. This means that VAR
+ has been clobbered by a function call since its last assignment. */
+
+static tree
+get_reaching_def (tree var)
+{
+ tree default_d, currdef_var;
+
+ /* Lookup the current reaching definition for VAR. */
+ default_d = NULL_TREE;
+ currdef_var = var_ann (var)->current_def;
+
+ /* If there is no reaching definition for VAR, create and register a
+ default definition for it (if needed). */
+ if (currdef_var == NULL_TREE)
+ {
+ default_d = default_def (var);
+ if (default_d == NULL_TREE)
+ {
+ default_d = make_ssa_name (var, build_empty_stmt ());
+ set_default_def (var, default_d);
+ }
+ var_ann (var)->current_def = default_d;
+ }
+
+ /* Return the current reaching definition for VAR, or the default
+ definition, if we had to create one. */
+ return (currdef_var) ? currdef_var : default_d;
+}
+
+
+/* Hashing and equality functions for DEF_BLOCKS. */
+
+static hashval_t
+def_blocks_hash (const void *p)
+{
+ return htab_hash_pointer
+ ((const void *)((const struct def_blocks_d *)p)->var);
+}
+
+static int
+def_blocks_eq (const void *p1, const void *p2)
+{
+ return ((const struct def_blocks_d *)p1)->var
+ == ((const struct def_blocks_d *)p2)->var;
+}
+
+/* Free memory allocated by one entry in DEF_BLOCKS. */
+
+static void
+def_blocks_free (void *p)
+{
+ struct def_blocks_d *entry = p;
+ BITMAP_XFREE (entry->def_blocks);
+ BITMAP_XFREE (entry->livein_blocks);
+ free (entry);
+}
+
+
+/* Dump the DEF_BLOCKS hash table on stderr. */
+
+void
+debug_def_blocks (void)
+{
+ htab_traverse (def_blocks, debug_def_blocks_r, NULL);
+}
+
+/* Callback for htab_traverse to dump the DEF_BLOCKS hash table. */
+
+static int
+debug_def_blocks_r (void **slot, void *data ATTRIBUTE_UNUSED)
+{
+ unsigned long i;
+ struct def_blocks_d *db_p = (struct def_blocks_d *) *slot;
+
+ fprintf (stderr, "VAR: ");
+ print_generic_expr (stderr, db_p->var, dump_flags);
+ fprintf (stderr, ", DEF_BLOCKS: { ");
+ EXECUTE_IF_SET_IN_BITMAP (db_p->def_blocks, 0, i,
+ fprintf (stderr, "%ld ", i));
+ fprintf (stderr, "}");
+ fprintf (stderr, ", LIVEIN_BLOCKS: { ");
+ EXECUTE_IF_SET_IN_BITMAP (db_p->livein_blocks, 0, i,
+ fprintf (stderr, "%ld ", i));
+ fprintf (stderr, "}\n");
+
+ return 1;
+}
+
+
+/* Return the set of blocks where variable VAR is defined and the blocks
+ where VAR is live on entry (livein). Return NULL, if no entry is
+ found in DEF_BLOCKS. */
+
+static inline struct def_blocks_d *
+find_def_blocks_for (tree var)
+{
+ struct def_blocks_d dm;
+ dm.var = var;
+ return (struct def_blocks_d *) htab_find (def_blocks, &dm);
+}
+
+
+/* Return the set of blocks where variable VAR is defined and the blocks
+ where VAR is live on entry (livein). If no entry is found in
+ DEF_BLOCKS, a new one is created and returned. */
+
+static inline struct def_blocks_d *
+get_def_blocks_for (tree var)
+{
+ struct def_blocks_d db, *db_p;
+ void **slot;
+
+ db.var = var;
+ slot = htab_find_slot (def_blocks, (void *) &db, INSERT);
+ if (*slot == NULL)
+ {
+ db_p = xmalloc (sizeof (*db_p));
+ db_p->var = var;
+ db_p->def_blocks = BITMAP_XMALLOC ();
+ db_p->livein_blocks = BITMAP_XMALLOC ();
+ *slot = (void *) db_p;
+ }
+ else
+ db_p = (struct def_blocks_d *) *slot;
+
+ return db_p;
+}
+
+/* If a variable V in VARS_TO_RENAME is a pointer, the renaming
+ process will cause us to lose the name memory tags that may have
+ been associated with the various SSA_NAMEs of V. This means that
+ the variables aliased to those name tags also need to be renamed
+ again.
+
+ FIXME 1- We should either have a better scheme for renaming
+ pointers that doesn't lose name tags or re-run alias
+ analysis to recover points-to information.
+
+ 2- Currently we just invalidate *all* the name tags. This
+ should be more selective. */
+
+static void
+invalidate_name_tags (bitmap vars_to_rename)
+{
+ size_t i;
+ bool rename_name_tags_p;
+
+ rename_name_tags_p = false;
+ EXECUTE_IF_SET_IN_BITMAP (vars_to_rename, 0, i,
+ if (POINTER_TYPE_P (TREE_TYPE (referenced_var (i))))
+ {
+ rename_name_tags_p = true;
+ break;
+ });
+
+ if (rename_name_tags_p)
+ for (i = 0; i < num_referenced_vars; i++)
+ {
+ var_ann_t ann = var_ann (referenced_var (i));
+
+ if (ann->mem_tag_kind == NAME_TAG)
+ {
+ size_t j;
+ varray_type may_aliases = ann->may_aliases;
+
+ bitmap_set_bit (vars_to_rename, ann->uid);
+ if (ann->may_aliases)
+ for (j = 0; j < VARRAY_ACTIVE_SIZE (may_aliases); j++)
+ {
+ tree var = VARRAY_TREE (may_aliases, j);
+ bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
+ }
+ }
+ }
+}
+
+
+/* Main entry point into the SSA builder. The renaming process
+ proceeds in five main phases:
+
+ 1- If VARS_TO_RENAME has any entries, any existing PHI nodes for
+ those variables are removed from the flow graph so that they can
+ be computed again.
+
+ 2- Compute dominance frontier and immediate dominators, needed to
+ insert PHI nodes and rename the function in dominator tree
+ order.
+
+ 3- Find and mark all the blocks that define variables
+ (mark_def_sites).
+
+ 4- Insert PHI nodes at dominance frontiers (insert_phi_nodes).
+
+ 5- Rename all the blocks (rewrite_initialize_block,
+ rewrite_add_phi_arguments) and statements in the program
+ (rewrite_stmt).
+
+ Steps 3 and 5 are done using the dominator tree walker
+ (walk_dominator_tree). */
+
+void
+rewrite_into_ssa (void)
+{
+ bitmap *dfs;
+ basic_block bb;
+ struct dom_walk_data walk_data;
+ struct mark_def_sites_global_data mark_def_sites_global_data;
+ unsigned int i;
+
+ timevar_push (TV_TREE_SSA_OTHER);
+
+ /* Initialize the array of variables to rename. */
+ if (vars_to_rename != NULL)
+ {
+ invalidate_name_tags (vars_to_rename);
+
+ /* Now remove all the existing PHI nodes (if any) for the variables
+ that we are about to rename into SSA. */
+ remove_all_phi_nodes_for (vars_to_rename);
+ }
+
+ /* Allocate memory for the DEF_BLOCKS hash table. */
+ def_blocks = htab_create (VARRAY_ACTIVE_SIZE (referenced_vars),
+ def_blocks_hash, def_blocks_eq, def_blocks_free);
+
+ /* Initialize dominance frontier and immediate dominator bitmaps.
+ Also count the number of predecessors for each block. Doing so
+ can save significant time during PHI insertion for large graphs. */
+ dfs = (bitmap *) xmalloc (last_basic_block * sizeof (bitmap *));
+ FOR_EACH_BB (bb)
+ {
+ edge e;
+ int count = 0;
+
+ for (e = bb->pred; e; e = e->pred_next)
+ count++;
+
+ bb_ann (bb)->num_preds = count;
+ dfs[bb->index] = BITMAP_XMALLOC ();
+ }
+
+ for (i = 0; i < num_referenced_vars; i++)
+ var_ann (referenced_var (i))->current_def = NULL;
+
+ /* Ensure that the dominance information is OK. */
+ calculate_dominance_info (CDI_DOMINATORS);
+
+ /* Compute dominance frontiers. */
+ compute_dominance_frontiers (dfs);
+
+ /* Setup callbacks for the generic dominator tree walker to find and
+ mark definition sites. */
+ walk_data.walk_stmts_backward = false;
+ walk_data.dom_direction = CDI_DOMINATORS;
+ walk_data.initialize_block_local_data = NULL;
+ walk_data.before_dom_children_before_stmts = mark_def_sites_initialize_block;
+ walk_data.before_dom_children_walk_stmts = mark_def_sites;
+ walk_data.before_dom_children_after_stmts = NULL;
+ walk_data.after_dom_children_before_stmts = NULL;
+ walk_data.after_dom_children_walk_stmts = NULL;
+ walk_data.after_dom_children_after_stmts = NULL;
+
+ /* Notice that this bitmap is indexed using variable UIDs, so it must be
+ large enough to accommodate all the variables referenced in the
+ function, not just the ones we are renaming. */
+ mark_def_sites_global_data.kills = sbitmap_alloc (num_referenced_vars);
+ walk_data.global_data = &mark_def_sites_global_data;
+
+ /* We do not have any local data. */
+ walk_data.block_local_data_size = 0;
+
+ /* Initialize the dominator walker. */
+ init_walk_dominator_tree (&walk_data);
+
+ /* Recursively walk the dominator tree. */
+ walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
+
+ /* Finalize the dominator walker. */
+ fini_walk_dominator_tree (&walk_data);
+
+ /* We no longer need this bitmap, clear and free it. */
+ sbitmap_free (mark_def_sites_global_data.kills);
+
+ /* Insert PHI nodes at dominance frontiers of definition blocks. */
+ insert_phi_nodes (dfs);
+
+ /* Rewrite all the basic blocks in the program. */
+ timevar_push (TV_TREE_SSA_REWRITE_BLOCKS);
+
+ /* Setup callbacks for the generic dominator tree walker. */
+ walk_data.walk_stmts_backward = false;
+ walk_data.dom_direction = CDI_DOMINATORS;
+ walk_data.initialize_block_local_data = rewrite_initialize_block_local_data;
+ walk_data.before_dom_children_before_stmts = rewrite_initialize_block;
+ walk_data.before_dom_children_walk_stmts = rewrite_stmt;
+ walk_data.before_dom_children_after_stmts = rewrite_add_phi_arguments;
+ walk_data.after_dom_children_before_stmts = NULL;
+ walk_data.after_dom_children_walk_stmts = NULL;
+ walk_data.after_dom_children_after_stmts = rewrite_finalize_block;
+ walk_data.global_data = NULL;
+ walk_data.block_local_data_size = sizeof (struct rewrite_block_data);
+
+ /* Initialize the dominator walker. */
+ init_walk_dominator_tree (&walk_data);
+
+ /* Recursively walk the dominator tree rewriting each statement in
+ each basic block. */
+ walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
+
+ /* Finalize the dominator walker. */
+ fini_walk_dominator_tree (&walk_data);
+
+ timevar_pop (TV_TREE_SSA_REWRITE_BLOCKS);
+
+ /* Debugging dumps. */
+ if (dump_file && (dump_flags & TDF_STATS))
+ {
+ dump_dfa_stats (dump_file);
+ dump_tree_ssa_stats (dump_file);
+ }
+
+ /* Free allocated memory. */
+ FOR_EACH_BB (bb)
+ BITMAP_XFREE (dfs[bb->index]);
+ free (dfs);
+
+ htab_delete (def_blocks);
+
+ timevar_pop (TV_TREE_SSA_OTHER);
+}
+
+struct tree_opt_pass pass_build_ssa =
+{
+ "ssa", /* name */
+ NULL, /* gate */
+ rewrite_into_ssa, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ PROP_cfg | PROP_referenced_vars, /* properties_required */
+ PROP_ssa, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */
+};
diff --git a/gcc/tree-iterator.c b/gcc/tree-iterator.c
new file mode 100644
index 00000000000..ebc477b68d0
--- /dev/null
+++ b/gcc/tree-iterator.c
@@ -0,0 +1,369 @@
+/* Iterator routines for manipulating GENERIC and GIMPLE tree statements.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Andrew MacLeod <amacleod@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "tree-gimple.h"
+#include "tree-iterator.h"
+#include "ggc.h"
+
+
+/* This is a cache of STATEMENT_LIST nodes. We create and destroy them
+ fairly often during gimplification. */
+
+static GTY ((deletable (""))) tree stmt_list_cache;
+
+tree
+alloc_stmt_list (void)
+{
+ tree list = stmt_list_cache;
+ if (list)
+ {
+ stmt_list_cache = TREE_CHAIN (list);
+ TREE_CHAIN (list) = NULL;
+ TREE_SIDE_EFFECTS (list) = 0;
+ }
+ else
+ {
+ list = make_node (STATEMENT_LIST);
+ TREE_TYPE (list) = void_type_node;
+ }
+ return list;
+}
+
+void
+free_stmt_list (tree t)
+{
+#ifdef ENABLE_CHECKING
+ if (STATEMENT_LIST_HEAD (t) || STATEMENT_LIST_TAIL (t))
+ abort ();
+#endif
+ TREE_CHAIN (t) = stmt_list_cache;
+ stmt_list_cache = t;
+}
+
+/* Links a statement, or a chain of statements, before the current stmt. */
+
+void
+tsi_link_before (tree_stmt_iterator *i, tree t, enum tsi_iterator_update mode)
+{
+ struct tree_statement_list_node *head, *tail, *cur;
+
+ /* Die on looping. */
+ if (t == i->container)
+ abort ();
+
+ TREE_SIDE_EFFECTS (i->container) = 1;
+
+ if (TREE_CODE (t) == STATEMENT_LIST)
+ {
+ head = STATEMENT_LIST_HEAD (t);
+ tail = STATEMENT_LIST_TAIL (t);
+ STATEMENT_LIST_HEAD (t) = NULL;
+ STATEMENT_LIST_TAIL (t) = NULL;
+
+ free_stmt_list (t);
+
+ /* Empty statement lists need no work. */
+ if (!head || !tail)
+ {
+ if (head != tail)
+ abort ();
+ return;
+ }
+ }
+ else
+ {
+ head = ggc_alloc (sizeof (*head));
+ head->prev = NULL;
+ head->next = NULL;
+ head->stmt = t;
+ tail = head;
+ }
+
+ cur = i->ptr;
+
+ /* Link it into the list. */
+ if (cur)
+ {
+ head->prev = cur->prev;
+ if (head->prev)
+ head->prev->next = head;
+ else
+ STATEMENT_LIST_HEAD (i->container) = head;
+ tail->next = cur;
+ cur->prev = tail;
+ }
+ else
+ {
+ if (STATEMENT_LIST_TAIL (i->container))
+ abort ();
+ STATEMENT_LIST_HEAD (i->container) = head;
+ STATEMENT_LIST_TAIL (i->container) = tail;
+ }
+
+ /* Update the iterator, if requested. */
+ switch (mode)
+ {
+ case TSI_NEW_STMT:
+ case TSI_CONTINUE_LINKING:
+ case TSI_CHAIN_START:
+ i->ptr = head;
+ break;
+ case TSI_CHAIN_END:
+ i->ptr = tail;
+ break;
+ case TSI_SAME_STMT:
+ if (!cur)
+ abort ();
+ break;
+ }
+}
+
+/* Links a statement, or a chain of statements, after the current stmt. */
+
+void
+tsi_link_after (tree_stmt_iterator *i, tree t, enum tsi_iterator_update mode)
+{
+ struct tree_statement_list_node *head, *tail, *cur;
+
+ /* Die on looping. */
+ if (t == i->container)
+ abort ();
+
+ TREE_SIDE_EFFECTS (i->container) = 1;
+
+ if (TREE_CODE (t) == STATEMENT_LIST)
+ {
+ head = STATEMENT_LIST_HEAD (t);
+ tail = STATEMENT_LIST_TAIL (t);
+ STATEMENT_LIST_HEAD (t) = NULL;
+ STATEMENT_LIST_TAIL (t) = NULL;
+
+ free_stmt_list (t);
+
+ /* Empty statement lists need no work. */
+ if (!head || !tail)
+ {
+ if (head != tail)
+ abort ();
+ return;
+ }
+ }
+ else
+ {
+ head = ggc_alloc (sizeof (*head));
+ head->prev = NULL;
+ head->next = NULL;
+ head->stmt = t;
+ tail = head;
+ }
+
+ cur = i->ptr;
+
+ /* Link it into the list. */
+ if (cur)
+ {
+ tail->next = cur->next;
+ if (tail->next)
+ tail->next->prev = tail;
+ else
+ STATEMENT_LIST_TAIL (i->container) = tail;
+ head->prev = cur;
+ cur->next = head;
+ }
+ else
+ {
+ if (STATEMENT_LIST_TAIL (i->container))
+ abort ();
+ STATEMENT_LIST_HEAD (i->container) = head;
+ STATEMENT_LIST_TAIL (i->container) = tail;
+ }
+
+ /* Update the iterator, if requested. */
+ switch (mode)
+ {
+ case TSI_NEW_STMT:
+ case TSI_CHAIN_START:
+ i->ptr = head;
+ break;
+ case TSI_CONTINUE_LINKING:
+ case TSI_CHAIN_END:
+ i->ptr = tail;
+ break;
+ case TSI_SAME_STMT:
+ if (!cur)
+ abort ();
+ break;
+ }
+}
+
+/* Remove a stmt from the tree list. The iterator is updated to point to
+ the next stmt. */
+
+void
+tsi_delink (tree_stmt_iterator *i)
+{
+ struct tree_statement_list_node *cur, *next, *prev;
+
+ cur = i->ptr;
+ next = cur->next;
+ prev = cur->prev;
+
+ if (prev)
+ prev->next = next;
+ else
+ STATEMENT_LIST_HEAD (i->container) = next;
+ if (next)
+ next->prev = prev;
+ else
+ STATEMENT_LIST_TAIL (i->container) = prev;
+
+ if (!next && !prev)
+ TREE_SIDE_EFFECTS (i->container) = 0;
+
+ i->ptr = next;
+}
+
+/* Move all statements in the statement list after I to a new
+ statement list. I itself is unchanged. */
+
+tree
+tsi_split_statement_list_after (const tree_stmt_iterator *i)
+{
+ struct tree_statement_list_node *cur, *next;
+ tree old_sl, new_sl;
+
+ cur = i->ptr;
+ /* How can we possibly split after the end, or before the beginning? */
+ if (cur == NULL)
+ abort ();
+ next = cur->next;
+
+ old_sl = i->container;
+ new_sl = alloc_stmt_list ();
+ TREE_SIDE_EFFECTS (new_sl) = 1;
+
+ STATEMENT_LIST_HEAD (new_sl) = next;
+ STATEMENT_LIST_TAIL (new_sl) = STATEMENT_LIST_TAIL (old_sl);
+ STATEMENT_LIST_TAIL (old_sl) = cur;
+ cur->next = NULL;
+ next->prev = NULL;
+
+ return new_sl;
+}
+
+/* Move all statements in the statement list before I to a new
+ statement list. I is set to the head of the new list. */
+
+tree
+tsi_split_statement_list_before (tree_stmt_iterator *i)
+{
+ struct tree_statement_list_node *cur, *prev;
+ tree old_sl, new_sl;
+
+ cur = i->ptr;
+ /* How can we possibly split after the end, or before the beginning? */
+ if (cur == NULL)
+ abort ();
+ prev = cur->prev;
+
+ old_sl = i->container;
+ new_sl = alloc_stmt_list ();
+ TREE_SIDE_EFFECTS (new_sl) = 1;
+ i->container = new_sl;
+
+ STATEMENT_LIST_HEAD (new_sl) = cur;
+ STATEMENT_LIST_TAIL (new_sl) = STATEMENT_LIST_TAIL (old_sl);
+ STATEMENT_LIST_TAIL (old_sl) = prev;
+ cur->prev = NULL;
+ prev->next = NULL;
+
+ return new_sl;
+}
+
+/* Return the first expression in a sequence of COMPOUND_EXPRs,
+ or in a STATEMENT_LIST. */
+
+tree
+expr_first (tree expr)
+{
+ if (expr == NULL_TREE)
+ return expr;
+
+ if (TREE_CODE (expr) == STATEMENT_LIST)
+ {
+ struct tree_statement_list_node *n = STATEMENT_LIST_HEAD (expr);
+ return n ? n->stmt : NULL_TREE;
+ }
+
+ while (TREE_CODE (expr) == COMPOUND_EXPR)
+ expr = TREE_OPERAND (expr, 0);
+ return expr;
+}
+
+/* Return the last expression in a sequence of COMPOUND_EXPRs,
+ or in a STATEMENT_LIST. */
+
+tree
+expr_last (tree expr)
+{
+ if (expr == NULL_TREE)
+ return expr;
+
+ if (TREE_CODE (expr) == STATEMENT_LIST)
+ {
+ struct tree_statement_list_node *n = STATEMENT_LIST_TAIL (expr);
+ return n ? n->stmt : NULL_TREE;
+ }
+
+ while (TREE_CODE (expr) == COMPOUND_EXPR)
+ expr = TREE_OPERAND (expr, 1);
+ return expr;
+}
+
+/* If EXPR is a single statement, naked or in a STATEMENT_LIST, then
+ return it. Otherwise return NULL. */
+
+tree
+expr_only (tree expr)
+{
+ if (expr == NULL_TREE)
+ return NULL_TREE;
+
+ if (TREE_CODE (expr) == STATEMENT_LIST)
+ {
+ struct tree_statement_list_node *n = STATEMENT_LIST_TAIL (expr);
+ if (n && STATEMENT_LIST_HEAD (expr) == n)
+ return n->stmt;
+ else
+ return NULL_TREE;
+ }
+
+ if (TREE_CODE (expr) == COMPOUND_EXPR)
+ return NULL_TREE;
+
+ return expr;
+}
+
+#include "gt-tree-iterator.h"
diff --git a/gcc/tree-iterator.h b/gcc/tree-iterator.h
new file mode 100644
index 00000000000..9008b1b1d00
--- /dev/null
+++ b/gcc/tree-iterator.h
@@ -0,0 +1,120 @@
+/* Iterator routines for manipulating GENERIC and GIMPLE tree statements.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Andrew MacLeod <amacleod@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+/* This file is dependent upon the implementation of tree's. It provides an
+ abstract interface to the tree objects such that if all tree creation and
+ manipulations are done through this interface, we can easily change the
+ implementation of tree's, and not impact other code. */
+
+#ifndef GCC_TREE_ITERATOR_H
+#define GCC_TREE_ITERATOR_H 1
+
+/* Iterator object for GENERIC or GIMPLE TREE statements. */
+
+typedef struct {
+ struct tree_statement_list_node *ptr;
+ tree container;
+} tree_stmt_iterator;
+
+static inline tree_stmt_iterator
+tsi_start (tree t)
+{
+ tree_stmt_iterator i;
+
+ i.ptr = STATEMENT_LIST_HEAD (t);
+ i.container = t;
+
+ return i;
+}
+
+static inline tree_stmt_iterator
+tsi_last (tree t)
+{
+ tree_stmt_iterator i;
+
+ i.ptr = STATEMENT_LIST_TAIL (t);
+ i.container = t;
+
+ return i;
+}
+
+static inline bool
+tsi_end_p (tree_stmt_iterator i)
+{
+ return i.ptr == NULL;
+}
+
+static inline bool
+tsi_one_before_end_p (tree_stmt_iterator i)
+{
+ return i.ptr != NULL && i.ptr->next == NULL;
+}
+
+static inline void
+tsi_next (tree_stmt_iterator *i)
+{
+ i->ptr = i->ptr->next;
+}
+
+static inline void
+tsi_prev (tree_stmt_iterator *i)
+{
+ i->ptr = i->ptr->prev;
+}
+
+static inline tree *
+tsi_stmt_ptr (tree_stmt_iterator i)
+{
+ return &i.ptr->stmt;
+}
+
+static inline tree
+tsi_stmt (tree_stmt_iterator i)
+{
+ return i.ptr->stmt;
+}
+
+enum tsi_iterator_update
+{
+ TSI_NEW_STMT, /* Leave the iterator at the same statement. */
+ TSI_SAME_STMT, /* Only valid when single statement is added, move
+ iterator to it. */
+ TSI_CHAIN_START, /* Only valid when chain of statements is added, move
+ iterator to the first statement in the chain. */
+ TSI_CHAIN_END, /* Only valid when chain of statements is added, move
+ iterator to the last statement in the chain. */
+ TSI_CONTINUE_LINKING /* Move iterator to whatever position is suitable for
+ linking other statements/chains of statements in
+ the same direction. */
+};
+
+extern void tsi_link_before (tree_stmt_iterator *, tree,
+ enum tsi_iterator_update);
+extern void tsi_link_after (tree_stmt_iterator *, tree,
+ enum tsi_iterator_update);
+
+void tsi_delink (tree_stmt_iterator *);
+
+tree tsi_split_statement_list_after (const tree_stmt_iterator *);
+tree tsi_split_statement_list_before (tree_stmt_iterator *);
+
+#endif /* GCC_TREE_ITERATOR_H */
diff --git a/gcc/tree-mudflap.c b/gcc/tree-mudflap.c
new file mode 100644
index 00000000000..474c7c45546
--- /dev/null
+++ b/gcc/tree-mudflap.c
@@ -0,0 +1,1093 @@
+/* Mudflap: narrow-pointer bounds-checking by tree rewriting.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Frank Ch. Eigler <fche@redhat.com>
+ and Graydon Hoare <graydon@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#include "config.h"
+#include "errors.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "flags.h"
+#include "function.h"
+#include "tree-inline.h"
+#include "tree-gimple.h"
+#include "tree-flow.h"
+#include "tree-mudflap.h"
+#include "tree-dump.h"
+#include "tree-pass.h"
+#include "hashtab.h"
+#include "diagnostic.h"
+#include <demangle.h>
+#include "langhooks.h"
+#include "ggc.h"
+
+/* Internal function decls */
+
+static void mf_xform_derefs (tree);
+static void mf_xform_decls (tree, tree);
+static void mf_init_extern_trees (void);
+static void mf_decl_cache_locals (tree *);
+static void mf_decl_clear_locals (void);
+static tree mf_varname_tree (tree);
+static tree mx_xfn_xform_decls (tree *, int *, void *);
+
+static void mx_register_decls (tree, tree *);
+
+
+/* extern mudflap functions */
+
+static GTY ((param_is (union tree_node))) htab_t marked_trees = NULL;
+
+
+/* Mark and return the given tree node to prevent further mudflap
+ transforms. */
+tree
+mf_mark (tree t)
+{
+ void **slot;
+
+ if (marked_trees == NULL)
+ marked_trees = htab_create_ggc (31, htab_hash_pointer, htab_eq_pointer, NULL);
+
+ slot = htab_find_slot (marked_trees, t, INSERT);
+ *slot = t;
+ return t;
+}
+
+
+int
+mf_marked_p (tree t)
+{
+ void *entry;
+
+ if (marked_trees == NULL)
+ return 0;
+
+ entry = htab_find (marked_trees, t);
+ return (entry != NULL);
+}
+
+static tree
+mf_build_string (const char *string)
+{
+ size_t len = strlen (string);
+ tree result = mf_mark (build_string (len + 1, string));
+
+ TREE_TYPE (result)
+ = build_array_type (char_type_node,
+ build_index_type (build_int_2 (len, 0)));
+ TREE_CONSTANT (result) = 1;
+ TREE_INVARIANT (result) = 1;
+ TREE_READONLY (result) = 1;
+ TREE_STATIC (result) = 1;
+
+ result = build1 (ADDR_EXPR, build_pointer_type (char_type_node), result);
+
+ return mf_mark (result);
+}
+
+/* Perform the declaration-related mudflap tree transforms on the
+ given function. Update its DECL_SAVED_TREE. */
+
+static void
+mudflap_function_decls (void)
+{
+ if (mf_marked_p (current_function_decl))
+ return;
+
+ push_gimplify_context ();
+
+ mf_init_extern_trees ();
+ mf_xform_decls (DECL_SAVED_TREE (current_function_decl),
+ DECL_ARGUMENTS (current_function_decl));
+
+ pop_gimplify_context (NULL);
+}
+
+static bool
+gate_mudflap (void)
+{
+ return flag_mudflap != 0;
+}
+
+struct tree_opt_pass pass_mudflap_1 =
+{
+ "mudflap1", /* name */
+ gate_mudflap, /* gate */
+ mudflap_function_decls, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ PROP_gimple_any, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func /* todo_flags_finish */
+};
+
+
+/* Same as above, for the indirection-related transforms. */
+
+static void
+mudflap_function_ops (void)
+{
+ if (mf_marked_p (current_function_decl))
+ return;
+
+ push_gimplify_context ();
+
+ /* In multithreaded mode, don't cache the lookup cache parameters. */
+ if (! flag_mudflap_threads)
+ mf_decl_cache_locals (&DECL_SAVED_TREE (current_function_decl));
+
+ mf_xform_derefs (DECL_SAVED_TREE (current_function_decl));
+
+ if (! flag_mudflap_threads)
+ mf_decl_clear_locals ();
+
+ pop_gimplify_context (NULL);
+}
+
+struct tree_opt_pass pass_mudflap_2 =
+{
+ "mudflap2", /* name */
+ gate_mudflap, /* gate */
+ mudflap_function_ops, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ PROP_gimple_leh, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func /* todo_flags_finish */
+};
+
+/* global tree nodes */
+
+/* Global tree objects for global variables and functions exported by
+ mudflap runtime library. mf_init_extern_trees must be called
+ before using these. */
+
+/* uintptr_t (usually "unsigned long") */
+static GTY (()) tree mf_uintptr_type;
+
+/* struct __mf_cache { uintptr_t low; uintptr_t high; }; */
+static GTY (()) tree mf_cache_struct_type;
+
+/* struct __mf_cache * const */
+static GTY (()) tree mf_cache_structptr_type;
+
+/* extern struct __mf_cache __mf_lookup_cache []; */
+static GTY (()) tree mf_cache_array_decl;
+
+/* extern const unsigned char __mf_lc_shift; */
+static GTY (()) tree mf_cache_shift_decl;
+
+/* extern const uintptr_t __mf_lc_mask; */
+static GTY (()) tree mf_cache_mask_decl;
+
+/* Their function-scope local shadows, used in single-threaded mode only. */
+
+/* auto const unsigned char __mf_lc_shift_l; */
+static GTY (()) tree mf_cache_shift_decl_l;
+
+/* auto const uintptr_t __mf_lc_mask_l; */
+static GTY (()) tree mf_cache_mask_decl_l;
+
+/* extern void __mf_check (void *ptr, size_t sz, int type, const char *); */
+static GTY (()) tree mf_check_fndecl;
+
+/* extern void __mf_register (void *ptr, size_t sz, int type, const char *); */
+static GTY (()) tree mf_register_fndecl;
+
+/* extern void __mf_unregister (void *ptr, size_t sz); */
+static GTY (()) tree mf_unregister_fndecl;
+
+
+/* Initialize the global tree nodes that correspond to mf-runtime.h
+ declarations. */
+static void
+mf_init_extern_trees (void)
+{
+ static bool done = false;
+
+ if (done)
+ return;
+ done = true;
+
+ mf_uintptr_type = TREE_TYPE (mflang_lookup_decl ("uintptr_t"));
+ mf_cache_array_decl = mf_mark (mflang_lookup_decl ("__mf_lookup_cache"));
+ mf_cache_struct_type = TREE_TYPE (TREE_TYPE (mf_cache_array_decl));
+ mf_cache_structptr_type = build_pointer_type (mf_cache_struct_type);
+ mf_cache_shift_decl = mf_mark (mflang_lookup_decl ("__mf_lc_shift"));
+ mf_cache_mask_decl = mf_mark (mflang_lookup_decl ("__mf_lc_mask"));
+ mf_check_fndecl = mflang_lookup_decl ("__mf_check");
+ mf_register_fndecl = mflang_lookup_decl ("__mf_register");
+ mf_unregister_fndecl = mflang_lookup_decl ("__mf_unregister");
+}
+
+
+
+/* Create and initialize local shadow variables for the lookup cache
+ globals. Put their decls in the *_l globals for use by
+ mf_build_check_statement_for. */
+
+static void
+mf_decl_cache_locals (tree* body)
+{
+ tree_stmt_iterator i = tsi_start (*body);
+ tree t;
+
+ mf_cache_shift_decl_l
+ = mf_mark (create_tmp_var (TREE_TYPE (mf_cache_shift_decl),
+ "__mf_lookup_shift_l"));
+
+ mf_cache_mask_decl_l
+ = mf_mark (create_tmp_var (TREE_TYPE (mf_cache_mask_decl),
+ "__mf_lookup_mask_l"));
+
+ /* Build initialization nodes for them. */
+ t = build (MODIFY_EXPR, TREE_TYPE (mf_cache_shift_decl_l),
+ mf_cache_shift_decl_l, mf_cache_shift_decl);
+ annotate_with_locus (t, DECL_SOURCE_LOCATION (current_function_decl));
+ gimplify_stmt (&t);
+ tsi_link_before (&i, t, TSI_NEW_STMT);
+
+ t = build (MODIFY_EXPR, TREE_TYPE (mf_cache_mask_decl_l),
+ mf_cache_mask_decl_l, mf_cache_mask_decl);
+ annotate_with_locus (t, DECL_SOURCE_LOCATION (current_function_decl));
+ gimplify_stmt (&t);
+ tsi_link_before (&i, t, TSI_NEW_STMT);
+}
+
+
+static void
+mf_decl_clear_locals (void)
+{
+ /* Unset local shadows. */
+ mf_cache_shift_decl_l = NULL_TREE;
+ mf_cache_mask_decl_l = NULL_TREE;
+}
+
+/* Create a properly typed STRING_CST node that describes the given
+ declaration. It will be used as an argument for __mf_register().
+ Try to construct a helpful string, including file/function/variable
+ name. */
+
+static tree
+mf_varname_tree (tree decl)
+{
+ static pretty_printer buf_rec;
+ static int initialized = 0;
+ pretty_printer *buf = & buf_rec;
+ const char *buf_contents;
+ tree result;
+
+ if (decl == NULL_TREE)
+ abort ();
+
+ if (!initialized)
+ {
+ pp_construct (buf, /* prefix */ NULL, /* line-width */ 0);
+ initialized = 1;
+ }
+ pp_clear_output_area (buf);
+
+ /* Add FILENAME[:LINENUMBER]. */
+ {
+ const char *sourcefile;
+ unsigned sourceline;
+
+ sourcefile = DECL_SOURCE_FILE (decl);
+ if (sourcefile == NULL && current_function_decl != NULL_TREE)
+ sourcefile = DECL_SOURCE_FILE (current_function_decl);
+ if (sourcefile == NULL)
+ sourcefile = "<unknown file>";
+
+ pp_string (buf, sourcefile);
+
+ sourceline = DECL_SOURCE_LINE (decl);
+ if (sourceline != 0)
+ {
+ pp_string (buf, ":");
+ pp_decimal_int (buf, sourceline);
+ }
+ }
+
+ if (current_function_decl != NULL_TREE)
+ {
+ /* Add (FUNCTION): */
+ pp_string (buf, " (");
+ {
+ const char *funcname = NULL;
+ if (DECL_NAME (current_function_decl))
+ funcname = (*lang_hooks.decl_printable_name) (current_function_decl, 1);
+ if (funcname == NULL)
+ funcname = "anonymous fn";
+
+ pp_string (buf, funcname);
+ }
+ pp_string (buf, ") ");
+ }
+ else
+ pp_string (buf, " ");
+
+ /* Add <variable-declaration>, possibly demangled. */
+ {
+ const char *declname = NULL;
+
+ if (strcmp ("GNU C++", lang_hooks.name) == 0 &&
+ DECL_NAME (decl) != NULL)
+ {
+ /* The gcc/cp decl_printable_name hook doesn't do as good a job as
+ the libiberty demangler. */
+ declname = cplus_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)),
+ DMGL_AUTO | DMGL_VERBOSE);
+ }
+
+ if (declname == NULL)
+ declname = (*lang_hooks.decl_printable_name) (decl, 3);
+
+ if (declname == NULL)
+ declname = "<unnamed variable>";
+
+ pp_string (buf, declname);
+ }
+
+ /* Return the lot as a new STRING_CST. */
+ buf_contents = pp_base_formatted_text (buf);
+ result = mf_build_string (buf_contents);
+ pp_clear_output_area (buf);
+
+ return result;
+}
+
+
+/* And another friend, for producing a simpler message. */
+
+static tree
+mf_file_function_line_tree (location_t *locus)
+{
+ const char *file = NULL, *colon, *line, *op, *name, *cp;
+ char linebuf[18];
+ char *string;
+ tree result;
+
+ /* Add FILENAME. */
+ if (locus != NULL)
+ file = locus->file;
+ if (file == NULL && current_function_decl != NULL_TREE)
+ file = DECL_SOURCE_FILE (current_function_decl);
+ if (file == NULL)
+ file = "<unknown file>";
+
+ /* Add :LINENUMBER. */
+ if (locus != NULL && locus->line > 0)
+ {
+ sprintf (linebuf, "%d", locus->line);
+ colon = ":";
+ line = linebuf;
+ }
+ else
+ colon = line = "";
+
+ /* Add (FUNCTION). */
+ name = (*lang_hooks.decl_printable_name) (current_function_decl, 1);
+ if (name)
+ {
+ op = " (";
+ cp = ")";
+ }
+ else
+ op = name = cp = "";
+
+ string = concat (file, colon, line, op, name, cp, NULL);
+ result = mf_build_string (string);
+ free (string);
+
+ return result;
+}
+
+
+static void
+mf_build_check_statement_for (tree addr, tree size, tree_stmt_iterator *iter,
+ location_t *locus, tree dirflag)
+{
+ tree ptrtype = TREE_TYPE (addr);
+ tree stmt, cond, t, u, v;
+ tree mf_value;
+ tree mf_base;
+ tree mf_elem;
+
+ /* Build our local variables. */
+ mf_value = create_tmp_var (ptrtype, "__mf_value");
+ mf_elem = create_tmp_var (mf_cache_structptr_type, "__mf_elem");
+ mf_base = create_tmp_var (mf_uintptr_type, "__mf_base");
+
+ /* Build: __mf_value = <address expression>. */
+ stmt = build (MODIFY_EXPR, void_type_node, mf_value, addr);
+ if (locus != NULL)
+ annotate_with_locus (stmt, *locus);
+ gimplify_stmt (&stmt);
+ tsi_link_before (iter, stmt, TSI_SAME_STMT);
+
+ /* Build: __mf_base = (uintptr_t)__mf_value. */
+ stmt = build (MODIFY_EXPR, void_type_node, mf_base,
+ build1 (NOP_EXPR, mf_uintptr_type, mf_value));
+ if (locus != NULL)
+ annotate_with_locus (stmt, *locus);
+ gimplify_stmt (&stmt);
+ tsi_link_before (iter, stmt, TSI_SAME_STMT);
+
+ /* Build: __mf_elem = &__mf_lookup_cache [(__mf_base >> __mf_shift)
+ & __mf_mask]. */
+ t = build (RSHIFT_EXPR, mf_uintptr_type, mf_base,
+ (flag_mudflap_threads ? mf_cache_shift_decl : mf_cache_shift_decl_l));
+ t = build (BIT_AND_EXPR, mf_uintptr_type, t,
+ (flag_mudflap_threads ? mf_cache_mask_decl : mf_cache_mask_decl_l));
+ t = build (ARRAY_REF,
+ TREE_TYPE (TREE_TYPE (mf_cache_array_decl)),
+ mf_cache_array_decl, t);
+ t = build1 (ADDR_EXPR, mf_cache_structptr_type, t);
+ stmt = build (MODIFY_EXPR, void_type_node, mf_elem, t);
+ if (locus != NULL)
+ annotate_with_locus (stmt, *locus);
+ gimplify_stmt (&stmt);
+ tsi_link_before (iter, stmt, TSI_SAME_STMT);
+
+ /* Quick validity check.
+ if (__builtin_expect ((__mf_elem->low > __mf_base)
+ | (__mf_elem_high < __mf_base + sizeof(T) - 1),
+ 0))
+ {
+ __mf_check ();
+ ... and only if single-threaded:
+ __mf_lookup_shift_1 = f...;
+ __mf_lookup_mask_l = ...;
+ }
+ */
+
+ /* __mf_elem->low */
+ t = build (COMPONENT_REF, mf_uintptr_type,
+ build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
+ TYPE_FIELDS (mf_cache_struct_type));
+
+ /* __mf_elem->high */
+ u = build (COMPONENT_REF, mf_uintptr_type,
+ build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
+ TREE_CHAIN (TYPE_FIELDS (mf_cache_struct_type)));
+
+ /* __mf_base + sizeof (T) - 1 */
+ v = size_binop (MINUS_EXPR, size, size_one_node);
+ v = convert (mf_uintptr_type, v);
+ v = fold (build (PLUS_EXPR, mf_uintptr_type, mf_base, v));
+
+ t = build (TRUTH_OR_EXPR, boolean_type_node,
+ build (GT_EXPR, boolean_type_node, t, mf_base),
+ build (LT_EXPR, boolean_type_node, u, v));
+
+ /* Mark condition as UNLIKELY using __builtin_expect. */
+ u = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
+ u = tree_cons (NULL_TREE, convert (long_integer_type_node, t), u);
+ cond = build_function_call_expr (built_in_decls[BUILT_IN_EXPECT], u);
+
+ /* Build up the body of the cache-miss handling:
+ __mf_check(); refresh *_l vars. */
+
+ stmt = NULL;
+
+ u = tree_cons (NULL_TREE, mf_file_function_line_tree (locus), NULL_TREE);
+ u = tree_cons (NULL_TREE, dirflag, u);
+ u = tree_cons (NULL_TREE, size, u);
+ u = tree_cons (NULL_TREE, mf_value, u);
+ t = build_function_call_expr (mf_check_fndecl, u);
+ append_to_statement_list (t, &stmt);
+
+ if (! flag_mudflap_threads)
+ {
+ t = build (MODIFY_EXPR, void_type_node,
+ mf_cache_shift_decl_l, mf_cache_shift_decl);
+ append_to_statement_list (t, &stmt);
+
+ t = build (MODIFY_EXPR, void_type_node,
+ mf_cache_mask_decl_l, mf_cache_mask_decl);
+ append_to_statement_list (t, &stmt);
+ }
+
+ stmt = build (COND_EXPR, void_type_node, cond, stmt, build_empty_stmt ());
+ if (locus != NULL)
+ annotate_with_locus (stmt, *locus);
+ gimplify_to_stmt_list (&stmt);
+ lower_stmt_body (stmt, NULL);
+ tsi_link_before (iter, stmt, TSI_SAME_STMT);
+}
+
+static void
+mf_xform_derefs_1 (tree_stmt_iterator *iter, tree *tp,
+ location_t *locus, tree dirflag)
+{
+ tree type, ptr_type, addr, size, t;
+
+ /* Don't instrument read operations. */
+ if (dirflag == integer_zero_node && flag_mudflap_ignore_reads)
+ return;
+
+ t = *tp;
+ type = TREE_TYPE (t);
+ size = TYPE_SIZE_UNIT (type);
+
+ switch (TREE_CODE (t))
+ {
+ case ARRAY_REF:
+ {
+ /* Omit checking if we can statically determine that the access is
+ valid. For non-addressable local arrays this is not optional,
+ since we won't have called __mf_register for the object. */
+ tree op0, op1;
+
+ op0 = TREE_OPERAND (t, 0);
+ op1 = TREE_OPERAND (t, 1);
+ while (TREE_CODE (op1) == INTEGER_CST)
+ {
+ tree dom = TYPE_DOMAIN (TREE_TYPE (op0));
+
+ /* Test for index in range. Break if not. */
+ if (!dom)
+ break;
+ if (!TYPE_MIN_VALUE (dom) || !really_constant_p (TYPE_MIN_VALUE (dom)))
+ break;
+ if (!TYPE_MAX_VALUE (dom) || !really_constant_p (TYPE_MAX_VALUE (dom)))
+ break;
+ if (tree_int_cst_lt (op1, TYPE_MIN_VALUE (dom))
+ || tree_int_cst_lt (TYPE_MAX_VALUE (dom), op1))
+ break;
+
+ /* If we're looking at a non-external VAR_DECL, then the
+ access must be ok. */
+ if (TREE_CODE (op0) == VAR_DECL && !DECL_EXTERNAL (op0))
+ return;
+
+ /* Only continue if we're still looking at an array. */
+ if (TREE_CODE (op0) != ARRAY_REF)
+ break;
+
+ op1 = TREE_OPERAND (op0, 1);
+ op0 = TREE_OPERAND (op0, 0);
+ }
+
+ /* If we got here, we couldn't statically the check. */
+ ptr_type = build_pointer_type (type);
+ addr = build1 (ADDR_EXPR, ptr_type, t);
+ }
+ break;
+
+ case INDIRECT_REF:
+ addr = TREE_OPERAND (t, 0);
+ ptr_type = TREE_TYPE (addr);
+ break;
+
+ case ARRAY_RANGE_REF:
+ warning ("mudflap checking not yet implemented for ARRAY_RANGE_REF");
+ return;
+
+ case COMPONENT_REF:
+ {
+ tree field;
+
+ /* If we're not dereferencing something, then the access
+ must be ok. */
+ if (TREE_CODE (TREE_OPERAND (t, 0)) != INDIRECT_REF)
+ return;
+
+ field = TREE_OPERAND (t, 1);
+
+ /* If we're looking at a bit field, then we can't take its address
+ with ADDR_EXPR -- lang_hooks.mark_addressable will error. Do
+ things the hard way with PLUS. */
+ if (DECL_BIT_FIELD_TYPE (field))
+ {
+ size = bitsize_int (BITS_PER_UNIT);
+ size = size_binop (CEIL_DIV_EXPR, DECL_SIZE (field), size);
+ size = convert (sizetype, size);
+
+ addr = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
+ addr = convert (ptr_type_node, addr);
+ addr = fold (build (PLUS_EXPR, ptr_type_node,
+ addr, byte_position (field)));
+ }
+ else
+ {
+ ptr_type = build_pointer_type (type);
+ addr = build1 (ADDR_EXPR, ptr_type, t);
+ }
+ }
+ break;
+
+ case BIT_FIELD_REF:
+ {
+ tree ofs, rem, bpu;
+
+ /* If we're not dereferencing something, then the access
+ must be ok. */
+ if (TREE_CODE (TREE_OPERAND (t, 0)) != INDIRECT_REF)
+ return;
+
+ bpu = bitsize_int (BITS_PER_UNIT);
+ ofs = convert (bitsizetype, TREE_OPERAND (t, 2));
+ rem = size_binop (TRUNC_MOD_EXPR, ofs, bpu);
+ ofs = size_binop (TRUNC_DIV_EXPR, ofs, bpu);
+
+ size = convert (bitsizetype, TREE_OPERAND (t, 1));
+ size = size_binop (PLUS_EXPR, size, rem);
+ size = size_binop (CEIL_DIV_EXPR, size, bpu);
+ size = convert (sizetype, size);
+
+ addr = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
+ addr = convert (ptr_type_node, addr);
+ addr = fold (build (PLUS_EXPR, ptr_type_node, addr, ofs));
+ }
+ break;
+
+ default:
+ return;
+ }
+
+ mf_build_check_statement_for (addr, size, iter, locus, dirflag);
+}
+
+static void
+mf_xform_derefs (tree fnbody)
+{
+ tree_stmt_iterator i = tsi_start (fnbody);
+
+ for (i = tsi_start (fnbody); !tsi_end_p (i); tsi_next (&i))
+ {
+ tree s = tsi_stmt (i);
+
+ /* Only a few GIMPLE statements can reference memory. */
+ switch (TREE_CODE (s))
+ {
+ case MODIFY_EXPR: /* This includes INIT_EXPR after gimplification. */
+ mf_xform_derefs_1 (&i, &TREE_OPERAND (s, 0), EXPR_LOCUS (s),
+ integer_one_node);
+ mf_xform_derefs_1 (&i, &TREE_OPERAND (s, 1), EXPR_LOCUS (s),
+ integer_zero_node);
+ break;
+
+ case RETURN_EXPR:
+ if (TREE_OPERAND (s, 0) != NULL_TREE)
+ {
+ if (TREE_CODE (TREE_OPERAND (s, 0)) == MODIFY_EXPR)
+ mf_xform_derefs_1 (&i, &TREE_OPERAND (TREE_OPERAND (s, 0), 1), EXPR_LOCUS (s),
+ integer_zero_node);
+ else
+ mf_xform_derefs_1 (&i, &TREE_OPERAND (s, 0), EXPR_LOCUS (s),
+ integer_zero_node);
+ }
+ break;
+
+ default:
+ ;
+ }
+ }
+}
+
+/* ------------------------------------------------------------------------ */
+/* ADDR_EXPR transform */
+
+
+/* This struct is passed between mf_xform_decls to store state needed
+ during the traversal searching for objects that have their
+ addresses taken. */
+struct mf_xform_decls_data
+{
+ tree param_decls;
+};
+
+
+/* Synthesize a CALL_EXPR and a TRY_FINALLY_EXPR, for this chain of
+ _DECLs if appropriate. Arrange to call the __mf_register function
+ now, and the __mf_unregister function later for each. */
+static void
+mx_register_decls (tree decl, tree *stmt_list)
+{
+ tree finally_stmts = NULL_TREE;
+ tree_stmt_iterator initially_stmts = tsi_start (*stmt_list);
+
+ while (decl != NULL_TREE)
+ {
+ /* Eligible decl? */
+ if ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL) &&
+ (! TREE_STATIC (decl)) && /* auto variable */
+ (! DECL_EXTERNAL (decl)) && /* not extern variable */
+ (COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (decl))) && /* complete type */
+ (! mf_marked_p (decl)) && /* not already processed */
+ (TREE_ADDRESSABLE (decl))) /* has address taken */
+ {
+ tree size = NULL_TREE, variable_name;
+ tree unregister_fncall, unregister_fncall_params;
+ tree register_fncall, register_fncall_params;
+
+ if (DECL_DEFER_OUTPUT (decl))
+ {
+ /* Oh no ... it's probably a variable-length array (VLA).
+ The size and address cannot be computed by merely
+ looking at the DECL. See gimplfiy_decl_stmt for the
+ method by which VLA declarations turn into calls to
+ BUILT_IN_STACK_ALLOC. We assume that multiple
+ VLAs declared later in the same block get allocation
+ code later than the others. */
+ tree stack_alloc_call = NULL_TREE;
+
+ while(! tsi_end_p (initially_stmts))
+ {
+ tree t = tsi_stmt (initially_stmts);
+
+ tree call = NULL_TREE;
+ if (TREE_CODE (t) == CALL_EXPR)
+ call = t;
+ else if (TREE_CODE (t) == MODIFY_EXPR &&
+ TREE_CODE (TREE_OPERAND (t, 1)) == CALL_EXPR)
+ call = TREE_OPERAND (t, 1);
+ else if (TREE_CODE (t) == TRY_FINALLY_EXPR)
+ {
+ /* We hope that this is the try/finally block sometimes
+ constructed by gimplify_bind_expr() for a BIND_EXPR
+ that contains VLAs. This very naive recursion
+ appears to be sufficient. */
+ initially_stmts = tsi_start (TREE_OPERAND (t, 0));
+ }
+
+ if (call != NULL_TREE)
+ {
+ if (TREE_CODE (TREE_OPERAND(call, 0)) == ADDR_EXPR &&
+ TREE_OPERAND (TREE_OPERAND (call, 0), 0) ==
+ implicit_built_in_decls [BUILT_IN_STACK_ALLOC])
+ {
+ tree stack_alloc_args = TREE_OPERAND (call, 1);
+ tree stack_alloc_op1 = TREE_VALUE (stack_alloc_args);
+ tree stack_alloc_op2 = TREE_VALUE (TREE_CHAIN (stack_alloc_args));
+
+ if (TREE_CODE (stack_alloc_op1) == ADDR_EXPR &&
+ TREE_OPERAND (stack_alloc_op1, 0) == decl)
+ {
+ /* Got it! */
+ size = stack_alloc_op2;
+ stack_alloc_call = call;
+ /* Advance iterator to point past this allocation call. */
+ tsi_next (&initially_stmts);
+ break;
+ }
+ }
+ }
+
+ tsi_next (&initially_stmts);
+ }
+
+ if (stack_alloc_call == NULL_TREE)
+ {
+ warning ("mudflap cannot handle variable-sized declaration `%s'",
+ IDENTIFIER_POINTER (DECL_NAME (decl)));
+ break;
+ }
+ }
+ else
+ {
+ size = convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (decl)));
+ }
+
+ /* (& VARIABLE, sizeof (VARIABLE)) */
+ unregister_fncall_params =
+ tree_cons (NULL_TREE,
+ convert (ptr_type_node,
+ mf_mark (build1 (ADDR_EXPR,
+ build_pointer_type (TREE_TYPE (decl)),
+ decl))),
+ tree_cons (NULL_TREE, size, NULL_TREE));
+ /* __mf_unregister (...) */
+ unregister_fncall = build_function_call_expr (mf_unregister_fndecl,
+ unregister_fncall_params);
+
+ /* (& VARIABLE, sizeof (VARIABLE), __MF_TYPE_STACK) */
+ variable_name = mf_varname_tree (decl);
+ register_fncall_params =
+ tree_cons (NULL_TREE,
+ convert (ptr_type_node,
+ mf_mark (build1 (ADDR_EXPR,
+ build_pointer_type (TREE_TYPE (decl)),
+ decl))),
+ tree_cons (NULL_TREE,
+ size,
+ tree_cons (NULL_TREE,
+ build_int_2 (3, 0), /* __MF_TYPE_STACK */
+ tree_cons (NULL_TREE,
+ variable_name,
+ NULL_TREE))));
+
+ /* __mf_register (...) */
+ register_fncall = build_function_call_expr (mf_register_fndecl,
+ register_fncall_params);
+
+ /* Accumulate the two calls. */
+ /* ??? Set EXPR_LOCUS. */
+ gimplify_stmt (&register_fncall);
+ gimplify_stmt (&unregister_fncall);
+
+ /* Add the __mf_register call at the current appending point. */
+ if (tsi_end_p (initially_stmts))
+ internal_error ("mudflap ran off end of BIND_EXPR body");
+ tsi_link_before (& initially_stmts, register_fncall, TSI_SAME_STMT);
+
+ /* Accumulate the FINALLY piece. */
+ append_to_statement_list (unregister_fncall, &finally_stmts);
+
+ mf_mark (decl);
+ }
+
+ decl = TREE_CHAIN (decl);
+ }
+
+ /* Actually, (initially_stmts!=NULL) <=> (finally_stmts!=NULL) */
+ if (finally_stmts != NULL_TREE)
+ {
+ tree t = build (TRY_FINALLY_EXPR, void_type_node,
+ *stmt_list, finally_stmts);
+ *stmt_list = NULL;
+ append_to_statement_list (t, stmt_list);
+ }
+}
+
+
+/* Process every variable mentioned in BIND_EXPRs. */
+static tree
+mx_xfn_xform_decls (tree *t, int *continue_p, void *data)
+{
+ struct mf_xform_decls_data* d = (struct mf_xform_decls_data*) data;
+
+ if (*t == NULL_TREE || *t == error_mark_node)
+ {
+ *continue_p = 0;
+ return NULL_TREE;
+ }
+
+ *continue_p = 1;
+
+ switch (TREE_CODE (*t))
+ {
+ case BIND_EXPR:
+ {
+ /* Process function parameters now (but only once). */
+ mx_register_decls (d->param_decls, &BIND_EXPR_BODY (*t));
+ d->param_decls = NULL_TREE;
+
+ mx_register_decls (BIND_EXPR_VARS (*t), &BIND_EXPR_BODY (*t));
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+/* Perform the object lifetime tracking mudflap transform on the given function
+ tree. The tree is mutated in place, with possibly copied subtree nodes.
+
+ For every auto variable declared, if its address is ever taken
+ within the function, then supply its lifetime to the mudflap
+ runtime with the __mf_register and __mf_unregister calls.
+*/
+
+static void
+mf_xform_decls (tree fnbody, tree fnparams)
+{
+ struct mf_xform_decls_data d;
+ d.param_decls = fnparams;
+ walk_tree_without_duplicates (&fnbody, mx_xfn_xform_decls, &d);
+}
+
+
+/* ------------------------------------------------------------------------ */
+
+
+/* Remember given node as a static of some kind: global data,
+ function-scope static, or an anonymous constant. Its assembler
+ label is given.
+*/
+
+
+/* A list of globals whose incomplete declarations we encountered.
+ Instead of emitting the __mf_register call for them here, it's
+ delayed until program finish time. If they're still incomplete by
+ then, warnings are emitted. */
+
+static GTY (()) varray_type deferred_static_decls;
+
+/* A list of statements for calling __mf_register() at startup time. */
+static GTY (()) tree enqueued_call_stmt_chain;
+
+static void
+mudflap_register_call (tree obj, tree object_size, tree varname)
+{
+ tree arg, args, call_stmt;
+
+ args = tree_cons (NULL_TREE, varname, NULL_TREE);
+
+ arg = build_int_2 (4, 0); /* __MF_TYPE_STATIC */
+ args = tree_cons (NULL_TREE, arg, args);
+
+ arg = convert (size_type_node, object_size);
+ args = tree_cons (NULL_TREE, arg, args);
+
+ arg = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (obj)), obj);
+ arg = convert (ptr_type_node, arg);
+ args = tree_cons (NULL_TREE, arg, args);
+
+ mf_init_extern_trees ();
+ call_stmt = build_function_call_expr (mf_register_fndecl, args);
+
+ append_to_statement_list (call_stmt, &enqueued_call_stmt_chain);
+}
+
+void
+mudflap_enqueue_decl (tree obj)
+{
+ if (mf_marked_p (obj))
+ return;
+
+ /* We don't need to process variable decls that are internally
+ generated extern. If we did, we'd end up with warnings for them
+ during mudflap_finish_file (). That would confuse the user,
+ since the text would refer to variables that don't show up in the
+ user's source code. */
+ if (DECL_P (obj) && DECL_EXTERNAL (obj) && DECL_ARTIFICIAL (obj))
+ return;
+
+ if (COMPLETE_TYPE_P (TREE_TYPE (obj)))
+ {
+ tree object_size;
+
+ mf_mark (obj);
+
+ object_size = size_in_bytes (TREE_TYPE (obj));
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "enqueue_decl obj=`");
+ print_generic_expr (dump_file, obj, dump_flags);
+ fprintf (dump_file, "' size=");
+ print_generic_expr (dump_file, object_size, dump_flags);
+ fprintf (dump_file, "\n");
+ }
+
+ /* NB: the above condition doesn't require TREE_USED or
+ TREE_ADDRESSABLE. That's because this object may be a global
+ only used from other compilation units. XXX: Maybe static
+ objects could require those attributes being set. */
+
+ mudflap_register_call (obj, object_size, mf_varname_tree (obj));
+ }
+ else
+ {
+ size_t i;
+
+ if (! deferred_static_decls)
+ VARRAY_TREE_INIT (deferred_static_decls, 10, "deferred static list");
+
+ /* Ugh, linear search... */
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_static_decls); i++)
+ if (VARRAY_TREE (deferred_static_decls, i) == obj)
+ {
+ warning ("mudflap cannot track lifetime of `%s'",
+ IDENTIFIER_POINTER (DECL_NAME (obj)));
+ return;
+ }
+
+ VARRAY_PUSH_TREE (deferred_static_decls, obj);
+ }
+}
+
+void
+mudflap_enqueue_constant (tree obj)
+{
+ tree object_size, varname;
+
+ if (mf_marked_p (obj))
+ return;
+
+ if (TREE_CODE (obj) == STRING_CST)
+ object_size = build_int_2 (TREE_STRING_LENGTH (obj), 0);
+ else
+ object_size = size_in_bytes (TREE_TYPE (obj));
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "enqueue_constant obj=`");
+ print_generic_expr (dump_file, obj, dump_flags);
+ fprintf (dump_file, "' size=");
+ print_generic_expr (dump_file, object_size, dump_flags);
+ fprintf (dump_file, "\n");
+ }
+
+ if (TREE_CODE (obj) == STRING_CST)
+ varname = mf_build_string ("string literal");
+ else
+ varname = mf_build_string ("constant");
+
+ mudflap_register_call (obj, object_size, varname);
+}
+
+
+
+/* Emit any file-wide instrumentation. */
+void
+mudflap_finish_file (void)
+{
+ /* Try to give the deferred objects one final try. */
+ if (deferred_static_decls)
+ {
+ size_t i;
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_static_decls); i++)
+ {
+ tree obj = VARRAY_TREE (deferred_static_decls, i);
+
+ /* Call enqueue_decl again on the same object it has previously
+ put into the table. (It won't modify the table this time, so
+ infinite iteration is not a problem.) */
+ mudflap_enqueue_decl (obj);
+ }
+
+ VARRAY_CLEAR (deferred_static_decls);
+ }
+
+ mflang_flush_calls (enqueued_call_stmt_chain);
+}
+
+
+
+#include "gt-tree-mudflap.h"
diff --git a/gcc/tree-mudflap.h b/gcc/tree-mudflap.h
new file mode 100644
index 00000000000..20c6ef9b1fc
--- /dev/null
+++ b/gcc/tree-mudflap.h
@@ -0,0 +1,41 @@
+/* Mudflap: narrow-pointer bounds-checking by tree rewriting.
+ Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Frank Ch. Eigler <fche@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#ifndef TREE_MUDFLAP_H
+#define TREE_MUDFLAP_H
+
+/* Instrumentation. */
+extern void mudflap_c_function_decls (tree);
+extern void mudflap_c_function_ops (tree);
+extern void mudflap_enqueue_decl (tree);
+extern void mudflap_enqueue_constant (tree);
+extern void mudflap_finish_file (void);
+
+/* Tree node marking. */
+extern int mf_marked_p (tree);
+extern tree mf_mark (tree);
+
+/* To be provided by a front-end interface module. */
+extern tree mflang_lookup_decl (const char *);
+extern void mflang_flush_calls (tree);
+
+
+#endif /* TREE_MUDFLAP_H */
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
new file mode 100644
index 00000000000..1a00ff30f86
--- /dev/null
+++ b/gcc/tree-nested.c
@@ -0,0 +1,1383 @@
+/* Nested function decomposition for trees.
+ Copyright (C) 2004 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 2, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "function.h"
+#include "tree-dump.h"
+#include "tree-inline.h"
+#include "tree-gimple.h"
+#include "tree-iterator.h"
+#include "tree-flow.h"
+#include "cgraph.h"
+#include "expr.h"
+#include "langhooks.h"
+#include "ggc.h"
+
+
+/* The object of this pass is to lower the representation of a set of nested
+ functions in order to expose all of the gory details of the various
+ nonlocal references. We want to do this sooner rather than later, in
+ order to give us more freedom in emitting all of the functions in question.
+
+ Back in olden times, when gcc was young, we developed an insanely
+ complicated scheme whereby variables which were referenced nonlocally
+ were forced to live in the stack of the declaring function, and then
+ the nested functions magically discovered where these variables were
+ placed. In order for this scheme to function properly, it required
+ that the outer function be partially expanded, then we switch to
+ compiling the inner function, and once done with those we switch back
+ to compiling the outer function. Such delicate ordering requirements
+ makes it difficult to do whole translation unit optimizations
+ involving such functions.
+
+ The implementation here is much more direct. Everything that can be
+ referenced by an inner function is a member of an explicitly created
+ structure herein called the "nonlocal frame struct". The incomming
+ static chain for a nested function is a pointer to this struct in
+ the parent. In this way, we settle on known offsets from a known
+ base, and so are decoupled from the logic that places objects in the
+ function's stack frame. More importantly, we don't have to wait for
+ that to happen -- since the compilation of the inner function is no
+ longer tied to a real stack frame, the nonlocal frame struct can be
+ allocated anywhere. Which means that the outer function is now
+ inlinable.
+
+ Theory of operation here is very simple. Iterate over all the
+ statements in all the functions (depth first) several times,
+ allocating structures and fields on demand. In general we want to
+ examine inner functions first, so that we can avoid making changes
+ to outer functions which are unnecessary.
+
+ The order of the passes matters a bit, in that later passes will be
+ skipped if it is discovered that the functions don't actually interact
+ at all. That is, they're nested in the lexical sense but could have
+ been written as independent functions without change. */
+
+
+struct var_map_elt
+{
+ tree old;
+ tree new;
+};
+
+struct nesting_info
+{
+ struct nesting_info *outer;
+ struct nesting_info *inner;
+ struct nesting_info *next;
+
+ htab_t var_map;
+ tree context;
+ tree new_local_var_chain;
+ tree frame_type;
+ tree frame_decl;
+ tree chain_field;
+ tree chain_decl;
+ tree nl_goto_field;
+
+ bool any_parm_remapped;
+ bool any_tramp_created;
+};
+
+
+/* Hashing and equality functions for nesting_info->var_map. */
+
+static hashval_t
+var_map_hash (const void *x)
+{
+ const struct var_map_elt *a = x;
+ return htab_hash_pointer (a->old);
+}
+
+static int
+var_map_eq (const void *x, const void *y)
+{
+ const struct var_map_elt *a = x;
+ const struct var_map_elt *b = y;
+ return a->old == b->old;
+}
+
+/* We're working in so many different function contexts simultaneously,
+ that create_tmp_var is dangerous. Prevent mishap. */
+#define create_tmp_var cant_use_create_tmp_var_here_dummy
+
+/* Like create_tmp_var, except record the variable for registration at
+ the given nesting level. */
+
+static tree
+create_tmp_var_for (struct nesting_info *info, tree type, const char *prefix)
+{
+ tree tmp_var;
+
+#if defined ENABLE_CHECKING
+ /* If the type is an array or a type which must be created by the
+ frontend, something is wrong. Note that we explicitly allow
+ incomplete types here, since we create them ourselves here. */
+ if (TREE_CODE (type) == ARRAY_TYPE || TREE_ADDRESSABLE (type))
+ abort ();
+ if (TYPE_SIZE_UNIT (type)
+ && TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
+ abort ();
+#endif
+
+ tmp_var = create_tmp_var_raw (type, prefix);
+ DECL_CONTEXT (tmp_var) = info->context;
+ TREE_CHAIN (tmp_var) = info->new_local_var_chain;
+ info->new_local_var_chain = tmp_var;
+
+ return tmp_var;
+}
+
+/* Take the address of EXP. Mark it for addressability as necessary. */
+
+static tree
+build_addr (tree exp)
+{
+ tree base = exp;
+ while (TREE_CODE (base) == COMPONENT_REF || TREE_CODE (base) == ARRAY_REF)
+ base = TREE_OPERAND (base, 0);
+ if (DECL_P (base))
+ TREE_ADDRESSABLE (base) = 1;
+
+ return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (exp)), exp);
+}
+
+/* Insert FIELD into TYPE, sorted by alignment requirements. */
+
+static void
+insert_field_into_struct (tree type, tree field)
+{
+ tree *p;
+
+ DECL_CONTEXT (field) = type;
+
+ for (p = &TYPE_FIELDS (type); *p ; p = &TREE_CHAIN (*p))
+ if (DECL_ALIGN (field) >= DECL_ALIGN (*p))
+ break;
+
+ TREE_CHAIN (field) = *p;
+ *p = field;
+}
+
+/* Build or return the RECORD_TYPE that describes the frame state that is
+ shared between INFO->CONTEXT and its nested functions. This record will
+ not be complete until finalize_nesting_tree; up until that point we'll
+ be adding fields as necessary.
+
+ We also build the DECL that represents this frame in the function. */
+
+static tree
+get_frame_type (struct nesting_info *info)
+{
+ tree type = info->frame_type;
+ if (!type)
+ {
+ char *name;
+
+ type = make_node (RECORD_TYPE);
+
+ name = concat ("FRAME.",
+ IDENTIFIER_POINTER (DECL_NAME (info->context)),
+ NULL);
+ TYPE_NAME (type) = get_identifier (name);
+ free (name);
+
+ info->frame_type = type;
+ info->frame_decl = create_tmp_var_for (info, type, "FRAME");
+ }
+ return type;
+}
+
+/* Return true if DECL should be referenced by pointer in the non-local
+ frame structure. */
+
+static bool
+use_pointer_in_frame (tree decl)
+{
+ if (TREE_CODE (decl) == PARM_DECL)
+ {
+ /* It's illegal to copy TREE_ADDRESSABLE, impossible to copy variable
+ sized decls, and inefficient to copy large aggregates. Don't bother
+ moving anything but scalar variables. */
+ return AGGREGATE_TYPE_P (TREE_TYPE (decl));
+ }
+ else
+ {
+ /* Variable sized types make things "interesting" in the frame. */
+ return DECL_SIZE (decl) == NULL || !TREE_CONSTANT (DECL_SIZE (decl));
+ }
+}
+
+/* Given DECL, a non-locally accessed variable, find or create a field
+ in the non-local frame structure for the given nesting context. */
+
+static tree
+lookup_field_for_decl (struct nesting_info *info, tree decl,
+ enum insert_option insert)
+{
+ struct var_map_elt *elt, dummy;
+ void **slot;
+ tree field;
+
+ dummy.old = decl;
+ slot = htab_find_slot (info->var_map, &dummy, insert);
+ if (!slot)
+ {
+ if (insert == INSERT)
+ abort ();
+ return NULL;
+ }
+ elt = *slot;
+
+ if (!elt && insert == INSERT)
+ {
+ field = make_node (FIELD_DECL);
+ DECL_NAME (field) = DECL_NAME (decl);
+
+ if (use_pointer_in_frame (decl))
+ {
+ TREE_TYPE (field) = build_pointer_type (TREE_TYPE (decl));
+ DECL_ALIGN (field) = TYPE_ALIGN (TREE_TYPE (field));
+ DECL_NONADDRESSABLE_P (field) = 1;
+ }
+ else
+ {
+ TREE_TYPE (field) = TREE_TYPE (decl);
+ DECL_SOURCE_LOCATION (field) = DECL_SOURCE_LOCATION (decl);
+ DECL_ALIGN (field) = DECL_ALIGN (decl);
+ DECL_USER_ALIGN (field) = DECL_USER_ALIGN (decl);
+ TREE_ADDRESSABLE (field) = TREE_ADDRESSABLE (decl);
+ DECL_NONADDRESSABLE_P (field) = !TREE_ADDRESSABLE (decl);
+ TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (decl);
+ }
+
+ insert_field_into_struct (get_frame_type (info), field);
+
+ elt = xmalloc (sizeof (*elt));
+ elt->old = decl;
+ elt->new = field;
+ *slot = elt;
+
+ if (TREE_CODE (decl) == PARM_DECL)
+ info->any_parm_remapped = true;
+ }
+ else
+ field = elt ? elt->new : NULL;
+
+ return field;
+}
+
+/* Build or return the variable that holds the static chain within
+ INFO->CONTEXT. This variable may only be used within INFO->CONTEXT. */
+
+static tree
+get_chain_decl (struct nesting_info *info)
+{
+ tree decl = info->chain_decl;
+ if (!decl)
+ {
+ tree type;
+
+ type = get_frame_type (info->outer);
+ type = build_pointer_type (type);
+
+ /* Note that this variable is *not* entered into any BIND_EXPR;
+ the construction of this variable is handled specially in
+ expand_function_start and initialize_inlined_parameters. */
+ decl = create_tmp_var_raw (type, "CHAIN");
+ DECL_CONTEXT (decl) = info->context;
+ decl->decl.seen_in_bind_expr = 1;
+
+ /* The initialization of CHAIN is not visible to the tree-ssa
+ analyzers and optimizers. Thus we do not want to issue
+ warnings for CHAIN. */
+ TREE_NO_WARNING (decl) = 1;
+
+ /* Tell tree-inline.c that we never write to this variable, so
+ it can copy-prop the replacement value immediately. */
+ TREE_READONLY (decl) = 1;
+
+ info->chain_decl = decl;
+ }
+ return decl;
+}
+
+/* Build or return the field within the non-local frame state that holds
+ the static chain for INFO->CONTEXT. This is the way to walk back up
+ multiple nesting levels. */
+
+static tree
+get_chain_field (struct nesting_info *info)
+{
+ tree field = info->chain_field;
+ if (!field)
+ {
+ tree type = build_pointer_type (get_frame_type (info->outer));
+
+ field = make_node (FIELD_DECL);
+ DECL_NAME (field) = get_identifier ("__chain");
+ TREE_TYPE (field) = type;
+ DECL_ALIGN (field) = TYPE_ALIGN (type);
+ DECL_NONADDRESSABLE_P (field) = 1;
+
+ insert_field_into_struct (get_frame_type (info), field);
+
+ info->chain_field = field;
+ }
+ return field;
+}
+
+/* Copy EXP into a temporary. Allocate the temporary in the context of
+ INFO and insert the initialization statement before TSI. */
+
+static tree
+init_tmp_var (struct nesting_info *info, tree exp, tree_stmt_iterator *tsi)
+{
+ tree t, stmt;
+
+ t = create_tmp_var_for (info, TREE_TYPE (exp), NULL);
+ stmt = build (MODIFY_EXPR, TREE_TYPE (t), t, exp);
+ SET_EXPR_LOCUS (stmt, EXPR_LOCUS (tsi_stmt (*tsi)));
+ tsi_link_before (tsi, stmt, TSI_SAME_STMT);
+
+ return t;
+}
+
+/* Similarly, but only do so to force EXP to satisfy is_gimple_val. */
+
+static tree
+gimplify_val (struct nesting_info *info, tree exp, tree_stmt_iterator *tsi)
+{
+ if (is_gimple_val (exp))
+ return exp;
+ else
+ return init_tmp_var (info, exp, tsi);
+}
+
+/* Build or return the type used to represent a nested function trampoline. */
+
+static GTY(()) tree trampoline_type;
+
+static tree
+get_trampoline_type (void)
+{
+ tree record, t;
+ unsigned align, size;
+
+ if (trampoline_type)
+ return trampoline_type;
+
+ align = TRAMPOLINE_ALIGNMENT;
+ size = TRAMPOLINE_SIZE;
+
+ /* If we won't be able to guarantee alignment simply via TYPE_ALIGN,
+ then allocate extra space so that we can do dynamic alignment. */
+ if (align > STACK_BOUNDARY)
+ {
+ size += ((align/BITS_PER_UNIT) - 1) & -(STACK_BOUNDARY/BITS_PER_UNIT);
+ align = STACK_BOUNDARY;
+ }
+
+ t = build_index_type (build_int_2 (size - 1, 0));
+ t = build_array_type (char_type_node, t);
+ t = build_decl (FIELD_DECL, get_identifier ("__data"), t);
+ DECL_ALIGN (t) = align;
+ DECL_USER_ALIGN (t) = 1;
+
+ record = make_node (RECORD_TYPE);
+ TYPE_NAME (record) = get_identifier ("__builtin_trampoline");
+ TYPE_FIELDS (record) = t;
+ layout_type (record);
+
+ return record;
+}
+
+/* Given DECL, a nested function, find or create a field in the non-local
+ frame structure for a trampoline for this function. */
+
+static tree
+lookup_tramp_for_decl (struct nesting_info *info, tree decl,
+ enum insert_option insert)
+{
+ struct var_map_elt *elt, dummy;
+ void **slot;
+ tree field;
+
+ dummy.old = decl;
+ slot = htab_find_slot (info->var_map, &dummy, insert);
+ if (!slot)
+ {
+ if (insert == INSERT)
+ abort ();
+ return NULL;
+ }
+ elt = *slot;
+
+ if (!elt && insert == INSERT)
+ {
+ field = make_node (FIELD_DECL);
+ DECL_NAME (field) = DECL_NAME (decl);
+ TREE_TYPE (field) = get_trampoline_type ();
+ TREE_ADDRESSABLE (field) = 1;
+
+ insert_field_into_struct (get_frame_type (info), field);
+
+ elt = xmalloc (sizeof (*elt));
+ elt->old = decl;
+ elt->new = field;
+ *slot = elt;
+
+ info->any_tramp_created = true;
+ }
+ else
+ field = elt ? elt->new : NULL;
+
+ return field;
+}
+
+/* Build or return the field within the non-local frame state that holds
+ the non-local goto "jmp_buf". The buffer itself is maintained by the
+ rtl middle-end as dynamic stack space is allocated. */
+
+static tree
+get_nl_goto_field (struct nesting_info *info)
+{
+ tree field = info->nl_goto_field;
+ if (!field)
+ {
+ unsigned size;
+ tree type;
+
+ /* For __builtin_nonlocal_goto, we need N words. The first is the
+ frame pointer, the rest is for the target's stack pointer save
+ area. The number of words is controled by STACK_SAVEAREA_MODE;
+ not the best interface, but it'll do for now. */
+ if (Pmode == ptr_mode)
+ type = ptr_type_node;
+ else
+ type = lang_hooks.types.type_for_mode (Pmode, 1);
+
+ size = GET_MODE_SIZE (STACK_SAVEAREA_MODE (SAVE_NONLOCAL));
+ size = size / GET_MODE_SIZE (Pmode);
+ size = size + 1;
+
+ type = build_array_type (type, build_index_type (build_int_2 (size, 0)));
+
+ field = make_node (FIELD_DECL);
+ DECL_NAME (field) = get_identifier ("__nl_goto_buf");
+ TREE_TYPE (field) = type;
+ DECL_ALIGN (field) = TYPE_ALIGN (type);
+ TREE_ADDRESSABLE (field) = 1;
+
+ insert_field_into_struct (get_frame_type (info), field);
+
+ info->nl_goto_field = field;
+ }
+
+ return field;
+}
+
+/* Convenience routines to walk all statements of a gimple function.
+
+ For each statement, we invoke CALLBACK via walk_tree. The passed
+ data is a walk_stmt_info structure. Of note here is a TSI that
+ points to the current statement being walked. The VAL_ONLY flag
+ that indicates whether the *TP being examined may be replaced
+ with something that matches is_gimple_val (if true) or something
+ slightly more complicated (if false). "Something" technically
+ means the common subset of is_gimple_lvalue and is_gimple_rhs,
+ but we never try to form anything more complicated than that, so
+ we don't bother checking. */
+
+struct walk_stmt_info
+{
+ walk_tree_fn callback;
+ tree_stmt_iterator tsi;
+ struct nesting_info *info;
+ bool val_only;
+};
+
+/* A subroutine of walk_function. Iterate over all sub-statements of *TP. */
+
+static void
+walk_stmts (struct walk_stmt_info *wi, tree *tp)
+{
+ tree t = *tp;
+ if (!t)
+ return;
+
+ switch (TREE_CODE (t))
+ {
+ case STATEMENT_LIST:
+ {
+ tree_stmt_iterator i;
+ for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
+ {
+ wi->tsi = i;
+ walk_stmts (wi, tsi_stmt_ptr (i));
+ }
+ }
+ break;
+
+ case COND_EXPR:
+ walk_tree (&COND_EXPR_COND (t), wi->callback, wi, NULL);
+ walk_stmts (wi, &COND_EXPR_THEN (t));
+ walk_stmts (wi, &COND_EXPR_ELSE (t));
+ break;
+ case CATCH_EXPR:
+ walk_stmts (wi, &CATCH_BODY (t));
+ case EH_FILTER_EXPR:
+ walk_stmts (wi, &EH_FILTER_FAILURE (t));
+ break;
+ case TRY_CATCH_EXPR:
+ case TRY_FINALLY_EXPR:
+ walk_stmts (wi, &TREE_OPERAND (t, 0));
+ walk_stmts (wi, &TREE_OPERAND (t, 1));
+ break;
+ case BIND_EXPR:
+ walk_stmts (wi, &BIND_EXPR_BODY (t));
+ break;
+
+ case RETURN_EXPR:
+ walk_stmts (wi, &TREE_OPERAND (t, 0));
+ break;
+
+ case MODIFY_EXPR:
+ /* The immediate arguments of a MODIFY_EXPR may use COMPONENT_REF. */
+ wi->val_only = false;
+ walk_tree (&TREE_OPERAND (t, 0), wi->callback, wi, NULL);
+ wi->val_only = false;
+ walk_tree (&TREE_OPERAND (t, 1), wi->callback, wi, NULL);
+ wi->val_only = true;
+ break;
+
+ default:
+ wi->val_only = true;
+ walk_tree (tp, wi->callback, wi, NULL);
+ break;
+ }
+}
+
+/* Invoke CALLBACK on all statements of INFO->CONTEXT. */
+
+static void
+walk_function (walk_tree_fn callback, struct nesting_info *info)
+{
+ struct walk_stmt_info wi;
+
+ memset (&wi, 0, sizeof (wi));
+ wi.callback = callback;
+ wi.info = info;
+ wi.val_only = true;
+
+ walk_stmts (&wi, &DECL_SAVED_TREE (info->context));
+}
+
+/* Similarly for ROOT and all functions nested underneath, depth first. */
+
+static void
+walk_all_functions (walk_tree_fn callback, struct nesting_info *root)
+{
+ do
+ {
+ if (root->inner)
+ walk_all_functions (callback, root->inner);
+ walk_function (callback, root);
+ root = root->next;
+ }
+ while (root);
+}
+
+
+/* Construct our local datastructure describing the function nesting
+ tree rooted by CGN. */
+
+static struct nesting_info *
+create_nesting_tree (struct cgraph_node *cgn)
+{
+ struct nesting_info *info = xcalloc (1, sizeof (*info));
+ info->var_map = htab_create (7, var_map_hash, var_map_eq, free);
+ info->context = cgn->decl;
+
+ for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
+ {
+ struct nesting_info *sub = create_nesting_tree (cgn);
+ sub->outer = info;
+ sub->next = info->inner;
+ info->inner = sub;
+ }
+
+ return info;
+}
+
+/* Return an expression computing the static chain for TARGET_CONTEXT
+ from INFO->CONTEXT. Insert any necessary computations before TSI. */
+
+static tree
+get_static_chain (struct nesting_info *info, tree target_context,
+ tree_stmt_iterator *tsi)
+{
+ struct nesting_info *i;
+ tree x;
+
+ if (info->context == target_context)
+ {
+ x = build_addr (info->frame_decl);
+ }
+ else
+ {
+ x = get_chain_decl (info);
+
+ for (i = info->outer; i->context != target_context; i = i->outer)
+ {
+ tree field = get_chain_field (i);
+
+ x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
+ x = build (COMPONENT_REF, TREE_TYPE (field), x, field);
+ x = init_tmp_var (info, x, tsi);
+ }
+ }
+
+ return x;
+}
+
+/* Return an expression referencing FIELD from TARGET_CONTEXT's non-local
+ frame as seen from INFO->CONTEXT. Insert any necessary computations
+ before TSI. */
+
+static tree
+get_frame_field (struct nesting_info *info, tree target_context,
+ tree field, tree_stmt_iterator *tsi)
+{
+ struct nesting_info *i;
+ tree x;
+
+ if (info->context == target_context)
+ {
+ /* Make sure frame_decl gets created. */
+ (void) get_frame_type (info);
+ x = info->frame_decl;
+ }
+ else
+ {
+ x = get_chain_decl (info);
+
+ for (i = info->outer; i->context != target_context; i = i->outer)
+ {
+ tree field = get_chain_field (i);
+
+ x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
+ x = build (COMPONENT_REF, TREE_TYPE (field), x, field);
+ x = init_tmp_var (info, x, tsi);
+ }
+
+ x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
+ }
+
+ x = build (COMPONENT_REF, TREE_TYPE (field), x, field);
+ return x;
+}
+
+/* Called via walk_function+walk_tree, rewrite all references to VAR
+ and PARM_DECLs that belong to outer functions.
+
+ The rewrite will involve some number of structure accesses back up
+ the static chain. E.g. for a variable FOO up one nesting level it'll
+ be CHAIN->FOO. For two levels it'll be CHAIN->__chain->FOO. Further
+ indirections apply to decls for which use_pointer_in_frame is true. */
+
+static tree
+convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data)
+{
+ struct walk_stmt_info *wi = data;
+ struct nesting_info *info = wi->info;
+ tree t = *tp;
+
+ *walk_subtrees = 0;
+ switch (TREE_CODE (t))
+ {
+ case VAR_DECL:
+ /* Non-automatic variables are never processed. */
+ if (TREE_STATIC (t) || DECL_EXTERNAL (t))
+ break;
+ /* FALLTHRU */
+
+ case PARM_DECL:
+ if (decl_function_context (t) != info->context)
+ {
+ tree target_context = decl_function_context (t);
+ struct nesting_info *i;
+ tree x;
+
+ for (i = info->outer; i->context != target_context; i = i->outer)
+ continue;
+ x = lookup_field_for_decl (i, t, INSERT);
+ x = get_frame_field (info, target_context, x, &wi->tsi);
+ if (use_pointer_in_frame (t))
+ {
+ x = init_tmp_var (info, x, &wi->tsi);
+ x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
+ }
+ if (wi->val_only)
+ x = init_tmp_var (info, x, &wi->tsi);
+
+ *tp = x;
+ }
+ break;
+
+ case GOTO_EXPR:
+ /* Don't walk non-local gotos for now. */
+ if (TREE_CODE (GOTO_DESTINATION (t)) != LABEL_DECL)
+ {
+ *walk_subtrees = 1;
+ wi->val_only = true;
+ }
+ break;
+
+ case LABEL_DECL:
+ /* We're taking the address of a label from a parent function, but
+ this is not itself a non-local goto. Mark the label such that it
+ will not be deleted, much as we would with a label address in
+ static storage. */
+ if (decl_function_context (t) != info->context)
+ FORCED_LABEL (t) = 1;
+ break;
+
+ case ADDR_EXPR:
+ {
+ bool save_val_only = wi->val_only;
+ tree save_sub = TREE_OPERAND (t, 0);
+
+ wi->val_only = false;
+ walk_tree (&TREE_OPERAND (t, 0), convert_nonlocal_reference, wi, NULL);
+ wi->val_only = true;
+
+ if (save_sub != TREE_OPERAND (t, 0))
+ {
+ /* If we changed anything, then TREE_INVARIANT is be wrong,
+ since we're no longer directly referencing a decl. */
+ TREE_INVARIANT (t) = 0;
+
+ /* If the callback converted the address argument in a context
+ where we only accept variables (and min_invariant, presumably),
+ then compute the address into a temporary. */
+ if (save_val_only)
+ *tp = gimplify_val (wi->info, t, &wi->tsi);
+ }
+ }
+ break;
+
+ case COMPONENT_REF:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ wi->val_only = false;
+ walk_tree (&TREE_OPERAND (t, 0), convert_nonlocal_reference, wi, NULL);
+ wi->val_only = true;
+ break;
+
+ case ARRAY_REF:
+ wi->val_only = false;
+ walk_tree (&TREE_OPERAND (t, 0), convert_nonlocal_reference, wi, NULL);
+ wi->val_only = true;
+ walk_tree (&TREE_OPERAND (t, 1), convert_nonlocal_reference, wi, NULL);
+ break;
+
+ case BIT_FIELD_REF:
+ wi->val_only = false;
+ walk_tree (&TREE_OPERAND (t, 0), convert_nonlocal_reference, wi, NULL);
+ wi->val_only = true;
+ walk_tree (&TREE_OPERAND (t, 1), convert_nonlocal_reference, wi, NULL);
+ walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference, wi, NULL);
+ break;
+
+ default:
+ if (!DECL_P (t) && !TYPE_P (t))
+ {
+ *walk_subtrees = 1;
+ wi->val_only = true;
+ }
+ break;
+ }
+
+ return NULL_TREE;
+}
+
+/* Called via walk_function+walk_tree, rewrite all references to VAR
+ and PARM_DECLs that were referenced by inner nested functions.
+ The rewrite will be a structure reference to the local frame variable. */
+
+static tree
+convert_local_reference (tree *tp, int *walk_subtrees, void *data)
+{
+ struct walk_stmt_info *wi = data;
+ struct nesting_info *info = wi->info;
+ tree t = *tp, field, x, y;
+
+ switch (TREE_CODE (t))
+ {
+ case VAR_DECL:
+ /* Non-automatic variables are never processed. */
+ if (TREE_STATIC (t) || DECL_EXTERNAL (t))
+ break;
+ /* FALLTHRU */
+
+ case PARM_DECL:
+ if (decl_function_context (t) == info->context)
+ {
+ /* If we copied a pointer to the frame, then the original decl
+ is used unchanged in the parent function. */
+ if (use_pointer_in_frame (t))
+ break;
+
+ /* No need to transform anything if no child references the
+ variable. */
+ field = lookup_field_for_decl (info, t, NO_INSERT);
+ if (!field)
+ break;
+
+ x = get_frame_field (info, info->context, field, &wi->tsi);
+ if (wi->val_only)
+ x = init_tmp_var (info, x, &wi->tsi);
+ *tp = x;
+ }
+ break;
+
+ case ADDR_EXPR:
+ {
+ bool save_val_only = wi->val_only;
+ tree save_sub = TREE_OPERAND (t, 0);
+
+ wi->val_only = false;
+ walk_tree (&TREE_OPERAND (t, 0), convert_local_reference, wi, NULL);
+ wi->val_only = save_val_only;
+
+ /* If we converted anything ... */
+ if (TREE_OPERAND (t, 0) != save_sub)
+ {
+ /* Then the frame decl is now addressable. */
+ TREE_ADDRESSABLE (info->frame_decl) = 1;
+
+ /* If we are in a context where we only accept values, then
+ compute the address into a temporary. */
+ if (save_val_only)
+ *tp = gimplify_val (wi->info, t, &wi->tsi);
+ }
+ }
+ break;
+
+ case CALL_EXPR:
+ *walk_subtrees = 1;
+
+ /* Ready for some fun? We need to recognize
+ __builtin_stack_alloc (&x, n)
+ and insert
+ FRAME.x = &x
+ after that. X should have use_pointer_in_frame set. We can't
+ do this any earlier, since we can't meaningfully evaluate &x. */
+
+ x = get_callee_fndecl (t);
+ if (!x || DECL_BUILT_IN_CLASS (x) != BUILT_IN_NORMAL)
+ break;
+ if (DECL_FUNCTION_CODE (x) != BUILT_IN_STACK_ALLOC)
+ break;
+ t = TREE_VALUE (TREE_OPERAND (t, 1));
+ if (TREE_CODE (t) != ADDR_EXPR)
+ abort ();
+ t = TREE_OPERAND (t, 0);
+ if (TREE_CODE (t) != VAR_DECL)
+ abort ();
+ field = lookup_field_for_decl (info, t, NO_INSERT);
+ if (!field)
+ break;
+ if (!use_pointer_in_frame (t))
+ abort ();
+
+ x = build_addr (t);
+ y = get_frame_field (info, info->context, field, &wi->tsi);
+ x = build (MODIFY_EXPR, void_type_node, y, x);
+ SET_EXPR_LOCUS (x, EXPR_LOCUS (tsi_stmt (wi->tsi)));
+ tsi_link_after (&wi->tsi, x, TSI_SAME_STMT);
+ break;
+
+ case COMPONENT_REF:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ wi->val_only = false;
+ walk_tree (&TREE_OPERAND (t, 0), convert_local_reference, wi, NULL);
+ wi->val_only = true;
+ break;
+
+ case ARRAY_REF:
+ wi->val_only = false;
+ walk_tree (&TREE_OPERAND (t, 0), convert_local_reference, wi, NULL);
+ wi->val_only = true;
+ walk_tree (&TREE_OPERAND (t, 1), convert_local_reference, wi, NULL);
+ break;
+
+ case BIT_FIELD_REF:
+ wi->val_only = false;
+ walk_tree (&TREE_OPERAND (t, 0), convert_local_reference, wi, NULL);
+ wi->val_only = true;
+ walk_tree (&TREE_OPERAND (t, 1), convert_local_reference, wi, NULL);
+ walk_tree (&TREE_OPERAND (t, 2), convert_local_reference, wi, NULL);
+ break;
+
+ default:
+ if (!DECL_P (t) && !TYPE_P (t))
+ {
+ *walk_subtrees = 1;
+ wi->val_only = true;
+ }
+ break;
+ }
+
+ return NULL_TREE;
+}
+
+/* Called via walk_function+walk_tree, rewrite all GOTO_EXPRs that
+ reference labels from outer functions. The rewrite will be a
+ call to __builtin_nonlocal_goto. */
+
+static tree
+convert_nl_goto_reference (tree *tp, int *walk_subtrees, void *data)
+{
+ struct walk_stmt_info *wi = data;
+ struct nesting_info *info = wi->info, *i;
+ tree t = *tp, label, new_label, target_context, x, arg, field;
+ struct var_map_elt *elt;
+ void **slot;
+
+ *walk_subtrees = 0;
+ if (TREE_CODE (t) != GOTO_EXPR)
+ return NULL_TREE;
+ label = GOTO_DESTINATION (t);
+ if (TREE_CODE (label) != LABEL_DECL)
+ return NULL_TREE;
+ target_context = decl_function_context (label);
+ if (target_context == info->context)
+ return NULL_TREE;
+
+ for (i = info->outer; target_context != i->context; i = i->outer)
+ continue;
+
+ /* The original user label may also be use for a normal goto, therefore
+ we must create a new label that will actually receive the abnormal
+ control transfer. This new label will be marked LABEL_NONLOCAL; this
+ mark will trigger proper behaviour in the cfg, as well as cause the
+ (hairy target-specific) non-local goto receiver code to be generated
+ when we expand rtl. */
+ new_label = create_artificial_label ();
+ DECL_NONLOCAL (new_label) = 1;
+
+ /* Enter this association into var_map so that we can insert the new
+ label into the IL during a second pass. */
+ elt = xmalloc (sizeof (*elt));
+ elt->old = label;
+ elt->new = new_label;
+ slot = htab_find_slot (i->var_map, elt, INSERT);
+ *slot = elt;
+
+ /* Build: __builtin_nl_goto(new_label, &chain->nl_goto_field). */
+ field = get_nl_goto_field (i);
+ x = get_frame_field (info, target_context, field, &wi->tsi);
+ x = build_addr (x);
+ x = gimplify_val (info, x, &wi->tsi);
+ arg = tree_cons (NULL, x, NULL);
+ x = build_addr (new_label);
+ arg = tree_cons (NULL, x, arg);
+ x = implicit_built_in_decls[BUILT_IN_NONLOCAL_GOTO];
+ x = build_function_call_expr (x, arg);
+
+ SET_EXPR_LOCUS (x, EXPR_LOCUS (tsi_stmt (wi->tsi)));
+ *tsi_stmt_ptr (wi->tsi) = x;
+
+ return NULL_TREE;
+}
+
+/* Called via walk_function+walk_tree, rewrite all LABEL_EXPRs that
+ are referenced via nonlocal goto from a nested function. The rewrite
+ will involve installing a newly generated DECL_NONLOCAL label, and
+ (potentially) a branch around the rtl gunk that is assumed to be
+ attached to such a label. */
+
+static tree
+convert_nl_goto_receiver (tree *tp, int *walk_subtrees, void *data)
+{
+ struct walk_stmt_info *wi = data;
+ struct nesting_info *info = wi->info;
+ tree t = *tp, label, new_label, x;
+ struct var_map_elt *elt, dummy;
+ tree_stmt_iterator tmp_tsi;
+
+ *walk_subtrees = 0;
+ if (TREE_CODE (t) != LABEL_EXPR)
+ return NULL_TREE;
+ label = LABEL_EXPR_LABEL (t);
+
+ dummy.old = label;
+ elt = htab_find (info->var_map, &dummy);
+ if (!elt)
+ return NULL_TREE;
+ new_label = elt->new;
+
+ /* If there's any possibility that the previous statement falls through,
+ then we must branch around the new non-local label. */
+ tmp_tsi = wi->tsi;
+ tsi_prev (&tmp_tsi);
+ if (tsi_end_p (tmp_tsi) || block_may_fallthru (tsi_stmt (tmp_tsi)))
+ {
+ x = build1 (GOTO_EXPR, void_type_node, label);
+ tsi_link_before (&wi->tsi, x, TSI_SAME_STMT);
+ }
+ x = build1 (LABEL_EXPR, void_type_node, new_label);
+ tsi_link_before (&wi->tsi, x, TSI_SAME_STMT);
+
+ return NULL_TREE;
+}
+
+/* Called via walk_function+walk_tree, rewrite all references to addresses
+ of nested functions that require the use of trampolines. The rewrite
+ will involve a reference a trampoline generated for the occasion. */
+
+static tree
+convert_tramp_reference (tree *tp, int *walk_subtrees, void *data)
+{
+ struct walk_stmt_info *wi = data;
+ struct nesting_info *info = wi->info, *i;
+ tree t = *tp, decl, target_context, x, arg;
+
+ *walk_subtrees = 0;
+ switch (TREE_CODE (t))
+ {
+ case ADDR_EXPR:
+ /* Build
+ T.1 = &CHAIN->tramp;
+ T.2 = __builtin_adjust_trampoline (T.1);
+ T.3 = (func_type)T.2;
+ */
+
+ decl = TREE_OPERAND (t, 0);
+ if (TREE_CODE (decl) != FUNCTION_DECL)
+ break;
+
+ /* Only need to process nested functions. */
+ target_context = decl_function_context (decl);
+ if (!target_context)
+ break;
+
+ /* If the nested function doesn't use a static chain, then
+ it doesn't need a trampoline. */
+ if (DECL_NO_STATIC_CHAIN (decl))
+ break;
+
+ /* Lookup the immediate parent of the callee, as that's where
+ we need to insert the trampoline. */
+ for (i = info; i->context != target_context; i = i->outer)
+ continue;
+ x = lookup_tramp_for_decl (i, decl, INSERT);
+
+ /* Compute the address of the field holding the trampoline. */
+ x = get_frame_field (info, target_context, x, &wi->tsi);
+ x = build_addr (x);
+ x = gimplify_val (info, x, &wi->tsi);
+ arg = tree_cons (NULL, x, NULL);
+
+ /* Do machine-specific ugliness. Normally this will involve
+ computing extra alignment, but it can really be anything. */
+ x = implicit_built_in_decls[BUILT_IN_ADJUST_TRAMPOLINE];
+ x = build_function_call_expr (x, arg);
+ x = init_tmp_var (info, x, &wi->tsi);
+
+ /* Cast back to the proper function type. */
+ x = build1 (NOP_EXPR, TREE_TYPE (t), x);
+ x = init_tmp_var (info, x, &wi->tsi);
+
+ *tp = x;
+ break;
+
+ case CALL_EXPR:
+ /* Only walk call arguments, lest we generate trampolines for
+ direct calls. */
+ walk_tree (&TREE_OPERAND (t, 1), convert_tramp_reference, wi, NULL);
+ break;
+
+ default:
+ if (!DECL_P (t) && !TYPE_P (t))
+ *walk_subtrees = 1;
+ break;
+ }
+
+ return NULL_TREE;
+}
+
+/* Called via walk_function+walk_tree, rewrite all CALL_EXPRs that
+ reference nested functions to make sure that the static chain is
+ set up properly for the call. */
+
+static tree
+convert_call_expr (tree *tp, int *walk_subtrees, void *data)
+{
+ struct walk_stmt_info *wi = data;
+ struct nesting_info *info = wi->info;
+ tree t = *tp, decl, target_context;
+
+ *walk_subtrees = 0;
+ switch (TREE_CODE (t))
+ {
+ case CALL_EXPR:
+ decl = get_callee_fndecl (t);
+ if (!decl)
+ break;
+ target_context = decl_function_context (decl);
+ if (target_context && !DECL_NO_STATIC_CHAIN (decl))
+ TREE_OPERAND (t, 2)
+ = get_static_chain (info, target_context, &wi->tsi);
+ break;
+
+ case RETURN_EXPR:
+ case MODIFY_EXPR:
+ /* Only return and modify may contain calls. */
+ *walk_subtrees = 1;
+ break;
+
+ default:
+ break;
+ }
+
+ return NULL_TREE;
+}
+
+/* Walk the nesting tree starting with ROOT, depth first. Convert all
+ trampolines and call expressions. On the way back up, determine if
+ a nested function actually uses its static chain; if not, remember that. */
+
+static void
+convert_all_function_calls (struct nesting_info *root)
+{
+ do
+ {
+ if (root->inner)
+ convert_all_function_calls (root->inner);
+
+ walk_function (convert_tramp_reference, root);
+ walk_function (convert_call_expr, root);
+
+ /* If the function does not use a static chain, then remember that. */
+ if (root->outer && !root->chain_decl && !root->chain_field)
+ DECL_NO_STATIC_CHAIN (root->context) = 1;
+ else
+ {
+#ifdef ENABLE_CHECKING
+ if (DECL_NO_STATIC_CHAIN (root->context))
+ abort ();
+#endif
+ }
+
+ root = root->next;
+ }
+ while (root);
+}
+
+/* Do "everything else" to clean up or complete state collected by the
+ various walking passes -- lay out the types and decls, generate code
+ to initialize the frame decl, store critical expressions in the
+ struct function for rtl to find. */
+
+static void
+finalize_nesting_tree_1 (struct nesting_info *root)
+{
+ tree stmt_list = NULL;
+ tree context = root->context;
+ struct function *sf;
+
+ /* If we created a non-local frame type or decl, we need to lay them
+ out at this time. */
+ if (root->frame_type)
+ {
+ layout_type (root->frame_type);
+ layout_decl (root->frame_decl, 0);
+ }
+
+ /* If any parameters were referenced non-locally, then we need to
+ insert a copy. Likewise, if any variables were referenced by
+ pointer, we need to initialize the address. */
+ if (root->any_parm_remapped)
+ {
+ tree p;
+ for (p = DECL_ARGUMENTS (context); p ; p = TREE_CHAIN (p))
+ {
+ tree field, x, y;
+
+ field = lookup_field_for_decl (root, p, NO_INSERT);
+ if (!field)
+ continue;
+
+ if (use_pointer_in_frame (p))
+ x = build_addr (p);
+ else
+ x = p;
+
+ y = build (COMPONENT_REF, TREE_TYPE (field),
+ root->frame_decl, field);
+ x = build (MODIFY_EXPR, TREE_TYPE (field), y, x);
+ append_to_statement_list (x, &stmt_list);
+ }
+ }
+
+ /* If a chain_field was created, then it needs to be initialized
+ from chain_decl. */
+ if (root->chain_field)
+ {
+ tree x;
+ x = build (COMPONENT_REF, TREE_TYPE (root->chain_field),
+ root->frame_decl, root->chain_field);
+ x = build (MODIFY_EXPR, TREE_TYPE (x), x, get_chain_decl (root));
+ append_to_statement_list (x, &stmt_list);
+ }
+
+ /* If trampolines were created, then we need to initialize them. */
+ if (root->any_tramp_created)
+ {
+ struct nesting_info *i;
+ for (i = root->inner; i ; i = i->next)
+ {
+ tree arg, x, field;
+
+ field = lookup_tramp_for_decl (root, i->context, NO_INSERT);
+ if (!field)
+ continue;
+
+ if (DECL_NO_STATIC_CHAIN (i->context))
+ x = null_pointer_node;
+ else
+ x = build_addr (root->frame_decl);
+ arg = tree_cons (NULL, x, NULL);
+
+ x = build_addr (i->context);
+ arg = tree_cons (NULL, x, arg);
+
+ x = build (COMPONENT_REF, TREE_TYPE (field),
+ root->frame_decl, field);
+ x = build_addr (x);
+ arg = tree_cons (NULL, x, arg);
+
+ x = implicit_built_in_decls[BUILT_IN_INIT_TRAMPOLINE];
+ x = build_function_call_expr (x, arg);
+
+ append_to_statement_list (x, &stmt_list);
+ }
+ }
+
+ /* If we created initialization statements, insert them. */
+ if (stmt_list)
+ {
+ annotate_all_with_locus (&stmt_list,
+ DECL_SOURCE_LOCATION (context));
+ append_to_statement_list (BIND_EXPR_BODY (DECL_SAVED_TREE (context)),
+ &stmt_list);
+ BIND_EXPR_BODY (DECL_SAVED_TREE (context)) = stmt_list;
+ }
+
+ /* If a chain_decl was created, then it needs to be registered with
+ struct function so that it gets initialized from the static chain
+ register at the beginning of the function. */
+ sf = DECL_STRUCT_FUNCTION (root->context);
+ sf->static_chain_decl = root->chain_decl;
+
+ /* Similarly for the non-local goto save area. */
+ if (root->nl_goto_field)
+ {
+ sf->nonlocal_goto_save_area
+ = get_frame_field (root, context, root->nl_goto_field, NULL);
+ sf->has_nonlocal_label = 1;
+ }
+
+ /* Make sure all new local variables get insertted into the
+ proper BIND_EXPR. */
+ if (root->new_local_var_chain)
+ declare_tmp_vars (root->new_local_var_chain,
+ DECL_SAVED_TREE (root->context));
+
+ /* Dump the translated tree function. */
+ dump_function (TDI_nested, root->context);
+}
+
+static void
+finalize_nesting_tree (struct nesting_info *root)
+{
+ do
+ {
+ if (root->inner)
+ finalize_nesting_tree (root->inner);
+ finalize_nesting_tree_1 (root);
+ root = root->next;
+ }
+ while (root);
+}
+
+/* Free the data structures allocated during this pass. */
+
+static void
+free_nesting_tree (struct nesting_info *root)
+{
+ struct nesting_info *next;
+ do
+ {
+ if (root->inner)
+ free_nesting_tree (root->inner);
+ htab_delete (root->var_map);
+ next = root->next;
+ free (root);
+ root = next;
+ }
+ while (root);
+}
+
+/* Main entry point for this pass. Process FNDECL and all of its nested
+ subroutines and turn them into something less tightly bound. */
+
+void
+lower_nested_functions (tree fndecl)
+{
+ struct nesting_info *root;
+ struct cgraph_node *cgn;
+
+ /* If there are no nested functions, there's nothing to do. */
+ cgn = cgraph_node (fndecl);
+ if (!cgn->nested)
+ return;
+
+ root = create_nesting_tree (cgn);
+ walk_all_functions (convert_nonlocal_reference, root);
+ walk_all_functions (convert_local_reference, root);
+ walk_all_functions (convert_nl_goto_reference, root);
+ walk_all_functions (convert_nl_goto_receiver, root);
+ convert_all_function_calls (root);
+ finalize_nesting_tree (root);
+ free_nesting_tree (root);
+}
+
+#include "gt-tree-nested.h"
diff --git a/gcc/tree-nomudflap.c b/gcc/tree-nomudflap.c
new file mode 100644
index 00000000000..1e30194f77e
--- /dev/null
+++ b/gcc/tree-nomudflap.c
@@ -0,0 +1,127 @@
+/* Mudflap: narrow-pointer bounds-checking by tree rewriting.
+ Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Frank Ch. Eigler <fche@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#include "config.h"
+#include "errors.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "tree-inline.h"
+#include "c-tree.h"
+#include "c-common.h"
+#include "tree-gimple.h"
+#include "diagnostic.h"
+#include "hashtab.h"
+#include "output.h"
+#include "varray.h"
+#include "langhooks.h"
+#include "tree-mudflap.h"
+#include "tree-pass.h"
+#include "ggc.h"
+
+
+
+/* This file contains placeholder functions, to be used only for
+ language processors that cannot handle tree-mudflap.c directly.
+ (e.g. Fortran). */
+
+static void
+nogo (void)
+{
+ internal_error ("mudflap: this language is not supported");
+}
+
+void
+mudflap_enqueue_decl (tree obj ATTRIBUTE_UNUSED)
+{
+ nogo ();
+}
+
+void
+mudflap_enqueue_constant (tree obj ATTRIBUTE_UNUSED)
+{
+ nogo ();
+}
+
+void
+mudflap_finish_file (void)
+{
+ nogo ();
+}
+
+int
+mf_marked_p (tree t ATTRIBUTE_UNUSED)
+{
+ nogo ();
+ return 0;
+}
+
+tree
+mf_mark (tree t ATTRIBUTE_UNUSED)
+{
+ nogo ();
+ return NULL;
+}
+
+/* The pass structures must exist, but need not do anything. */
+
+struct tree_opt_pass pass_mudflap_1 =
+{
+ "mudflap1", /* name */
+ NULL, /* gate */
+ NULL, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0 /* todo_flags_finish */
+};
+
+struct tree_opt_pass pass_mudflap_2 =
+{
+ "mudflap2", /* name */
+ NULL, /* gate */
+ NULL, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0 /* todo_flags_finish */
+};
+
+/* Instead of:
+#include "gt-tree-mudflap.h"
+We prepare a little dummy struct here.
+*/
+
+const struct ggc_root_tab gt_ggc_r_gt_tree_mudflap_h[] = {
+ LAST_GGC_ROOT_TAB
+};
diff --git a/gcc/tree-nrv.c b/gcc/tree-nrv.c
new file mode 100644
index 00000000000..2c344967d66
--- /dev/null
+++ b/gcc/tree-nrv.c
@@ -0,0 +1,217 @@
+/* Language independent return value optimizations
+ Copyright (C) 2004 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 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "rtl.h"
+#include "function.h"
+#include "basic-block.h"
+#include "expr.h"
+#include "diagnostic.h"
+#include "tree-flow.h"
+#include "timevar.h"
+#include "tree-dump.h"
+#include "tree-pass.h"
+#include "langhooks.h"
+
+/* This file implements return value optimizations for functions which
+ return aggregate types.
+
+ Basically this pass searches the function for return statements which
+ return a local aggregate. When converted to RTL such statements will
+ generate a copy from the local aggregate to final return value destination
+ mandated by the target's ABI.
+
+ That copy can often be avoided by directly constructing the return value
+ into the final destination mandated by the target's ABI.
+
+ This is basically a generic equivalent to the C++ front-end's
+ Named Return Value optimization. */
+
+struct nrv_data
+{
+ /* This is the temporary (a VAR_DECL) which appears in all of
+ this function's RETURN_EXPR statements. */
+ tree var;
+
+ /* This is the function's RESULT_DECL. We will replace all occurences
+ of VAR with RESULT_DECL when we apply this optimization. */
+ tree result;
+};
+
+static tree finalize_nrv_r (tree *, int *, void *);
+
+/* Callback for the tree walker.
+
+ If TP refers to a RETURN_EXPR, then set the expression being returned
+ to nrv_data->result.
+
+ If TP refers to nrv_data->var, then replace nrv_data->var with
+ nrv_data->result.
+
+ If we reach a node where we know all the subtrees are uninteresting,
+ then set *WALK_SUBTREES to zero. */
+
+static tree
+finalize_nrv_r (tree *tp, int *walk_subtrees, void *data)
+{
+ struct nrv_data *dp = (struct nrv_data *)data;
+
+ /* No need to walk into types. */
+ if (TYPE_P (*tp))
+ *walk_subtrees = 0;
+ /* If this is a RETURN_EXPR, then set the expression being returned
+ to RESULT. */
+ else if (TREE_CODE (*tp) == RETURN_EXPR)
+ TREE_OPERAND (*tp, 0) = dp->result;
+ /* Replace all occurences of VAR with RESULT. */
+ else if (*tp == dp->var)
+ *tp = dp->result;
+
+ /* Keep iterating. */
+ return NULL_TREE;
+}
+
+/* Main entry point for return value optimizations.
+
+ If this function always returns the same local variable, and that
+ local variable is an aggregate type, then replace the variable with
+ the function's DECL_RESULT.
+
+ This is the equivalent of the C++ named return value optimization
+ applied to optimized trees in a language independent form. If we
+ ever encounter languages which prevent this kind of optimization,
+ then we could either have the languages register the optimization or
+ we could change the gating function to check the current language. */
+
+static void
+tree_nrv (void)
+{
+ tree result = DECL_RESULT (current_function_decl);
+ tree result_type = TREE_TYPE (result);
+ tree found = NULL;
+ basic_block bb;
+ struct nrv_data data;
+
+ /* If this function does not return an aggregate type in memory, then
+ there is nothing to do. */
+ if (!aggregate_value_p (result, current_function_decl))
+ return;
+
+ /* Look through each block for suitable return expressions. RETURN_EXPRs
+ end basic blocks, so we only have to look at the last statement in
+ each block. That makes this very fast. */
+ FOR_EACH_BB (bb)
+ {
+ tree stmt = last_stmt (bb);
+
+ if (stmt && TREE_CODE (stmt) == RETURN_EXPR)
+ {
+ tree ret_expr = TREE_OPERAND (stmt, 0);
+
+ /* This probably should not happen, but just to be safe do
+ not perform NRV optimizations if only some of the return
+ statement return a value. */
+ if (!ret_expr
+ || TREE_CODE (ret_expr) != MODIFY_EXPR
+ || TREE_CODE (TREE_OPERAND (ret_expr, 0)) != RESULT_DECL)
+ return;
+
+ /* Now verify that this return statement uses the same value
+ as any previously encountered return statement. */
+ if (found != NULL)
+ {
+ /* If we found a return statement using a different variable
+ than previous return statements, then we can not perform
+ NRV optimizations. */
+ if (found != TREE_OPERAND (ret_expr, 1))
+ return;
+ }
+ else
+ found = TREE_OPERAND (ret_expr, 1);
+
+ /* The returned value must be a local automatic variable of the
+ same type and alignment as the function's result. */
+ if (TREE_CODE (found) != VAR_DECL
+ || DECL_CONTEXT (found) != current_function_decl
+ || TREE_STATIC (found)
+ || TREE_ADDRESSABLE (found)
+ || DECL_ALIGN (found) > DECL_ALIGN (result)
+ || !lang_hooks.types_compatible_p (TREE_TYPE (found),
+ result_type))
+ return;
+ }
+ }
+
+ if (!found)
+ return;
+
+ /* If dumping details, then note once and only the NRV replacement. */
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "NRV Replaced: ");
+ print_generic_expr (dump_file, found, dump_flags);
+ fprintf (dump_file, " with: ");
+ print_generic_expr (dump_file, result, dump_flags);
+ fprintf (dump_file, "\n");
+ }
+
+ /* At this point we know that all the return statements return the
+ same local which has suitable attributes for NRV. Copy debugging
+ information from FOUND to RESULT. */
+ DECL_NAME (result) = DECL_NAME (found);
+ DECL_SOURCE_LOCATION (result) = DECL_SOURCE_LOCATION (found);
+ DECL_ABSTRACT_ORIGIN (result) = DECL_ABSTRACT_ORIGIN (found);
+ TREE_ADDRESSABLE (result) = TREE_ADDRESSABLE (found);
+
+ /* Now walk through the function changing all references to VAR to be
+ RESULT. */
+ data.var = found;
+ data.result = result;
+ FOR_EACH_BB (bb)
+ {
+ block_stmt_iterator bsi;
+
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ walk_tree (bsi_stmt_ptr (bsi), finalize_nrv_r, &data, 0);
+ }
+
+ /* FOUND is no longer used. Ensure it gets removed. */
+ var_ann (found)->used = 0;
+}
+
+struct tree_opt_pass pass_nrv =
+{
+ "nrv", /* name */
+ NULL, /* gate */
+ tree_nrv, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_NRV, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */
+};
diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c
index f946593dc33..80a2b41b6a1 100644
--- a/gcc/tree-optimize.c
+++ b/gcc/tree-optimize.c
@@ -1,5 +1,6 @@
/* Control and data flow functions for trees.
Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Diego Novillo <dnovillo@redhat.com>
This file is part of GCC.
@@ -21,18 +22,424 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "toplev.h"
+#include "tm.h"
#include "tree.h"
-#include "tree-inline.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "output.h"
+#include "expr.h"
+#include "diagnostic.h"
+#include "basic-block.h"
#include "flags.h"
-#include "langhooks.h"
-#include "cgraph.h"
+#include "tree-flow.h"
+#include "tree-dump.h"
#include "timevar.h"
-#include "tm.h"
#include "function.h"
+#include "langhooks.h"
+#include "toplev.h"
+#include "flags.h"
+#include "cgraph.h"
+#include "tree-inline.h"
+#include "tree-mudflap.h"
+#include "tree-pass.h"
+#include "tree-alias-common.h"
#include "ggc.h"
+#include "cgraph.h"
+
+
+/* Global variables used to communicate with passes. */
+int dump_flags;
+bitmap vars_to_rename;
+bool in_gimple_form;
+
+/* The root of the compilation pass tree, once constructed. */
+static struct tree_opt_pass *all_passes;
+
+/* Pass: gimplify the function if it's not been done. */
+
+static void
+execute_gimple (void)
+{
+ /* We have this test here rather than as the gate because we always
+ want to dump the original gimplified function. */
+ if (!lang_hooks.gimple_before_inlining)
+ gimplify_function_tree (current_function_decl);
+}
+
+static struct tree_opt_pass pass_gimple =
+{
+ "gimple", /* name */
+ NULL, /* gate */
+ execute_gimple, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ 0, /* properties_required */
+ PROP_gimple_any, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func /* todo_flags_finish */
+};
+
+/* Pass: replace the outermost BIND_EXPR. We removed all of them while
+ optimizing, but the tree->rtl expander requires it. */
+
+static void
+execute_rebuild_bind (void)
+{
+ DECL_SAVED_TREE (current_function_decl)
+ = build (BIND_EXPR, void_type_node, NULL_TREE,
+ DECL_SAVED_TREE (current_function_decl), NULL_TREE);
+}
+
+static struct tree_opt_pass pass_rebuild_bind =
+{
+ NULL, /* name */
+ NULL, /* gate */
+ execute_rebuild_bind, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0 /* todo_flags_finish */
+};
+
+/* Gate: execute, or not, all of the non-trivial optimizations. */
+
+static bool
+gate_all_optimizations (void)
+{
+ return (optimize >= 1
+ /* Don't bother doing anything if the program has errors. */
+ && !(errorcount || sorrycount));
+}
+
+static struct tree_opt_pass pass_all_optimizations =
+{
+ NULL, /* name */
+ gate_all_optimizations, /* gate */
+ NULL, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0 /* todo_flags_finish */
+};
+
+/* Pass: do the actions required to finish with tree-ssa optimization
+ passes. */
+
+static void
+execute_del_cfg (void)
+{
+ basic_block bb;
+ tree *chain;
+
+ /* ??? This isn't the right place for this. Worse, it got computed
+ more or less at random in various passes. */
+ free_dominance_info (CDI_DOMINATORS);
+
+ /* Emit gotos for implicit jumps. */
+ disband_implicit_edges ();
+
+ /* Remove the ssa structures. Do it here since this includes statement
+ annotations that need to be intact during disband_implicit_edges. */
+ delete_tree_ssa ();
+
+ /* Re-chain the statements from the blocks. */
+ chain = &DECL_SAVED_TREE (current_function_decl);
+ *chain = alloc_stmt_list ();
+ FOR_EACH_BB (bb)
+ {
+ append_to_statement_list_force (bb->stmt_list, chain);
+ }
+
+ /* And get rid of the cfg. */
+ delete_tree_cfg ();
+}
+
+static struct tree_opt_pass pass_del_cfg =
+{
+ NULL, /* name */
+ NULL, /* gate */
+ execute_del_cfg, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ PROP_cfg, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0 /* todo_flags_finish */
+};
+
+/* Iterate over the pass tree allocating dump file numbers. We want
+ to do this depth first, and independent of whether the pass is
+ enabled or not. */
+
+static void
+register_one_dump_file (struct tree_opt_pass *pass)
+{
+ char *dot_name, *flag_name;
+ char num[10];
+
+ if (!pass->name)
+ return;
+
+ /* See below in dup_pass_1. */
+ num[0] = '\0';
+ if (pass->static_pass_number)
+ sprintf (num, "%d", ((int) pass->static_pass_number < 0
+ ? 1 : pass->static_pass_number));
+
+ dot_name = concat (".", pass->name, num, NULL);
+ flag_name = concat ("tree-", pass->name, num, NULL);
+
+ pass->static_pass_number = dump_register (dot_name, flag_name);
+}
+
+static void
+register_dump_files (struct tree_opt_pass *pass)
+{
+ do
+ {
+ register_one_dump_file (pass);
+ if (pass->sub)
+ register_dump_files (pass->sub);
+ pass = pass->next;
+ }
+ while (pass);
+}
+
+/* Duplicate a pass that's to be run more than once. */
+
+static struct tree_opt_pass *
+dup_pass_1 (struct tree_opt_pass *pass)
+{
+ struct tree_opt_pass *new;
+
+ new = xmalloc (sizeof (*new));
+ memcpy (new, pass, sizeof (*new));
+
+ /* Indicate to register_dump_files that this pass has duplicates,
+ and so it should rename the dump file. The first instance will
+ be < 0, and be number of duplicates = -static_pass_number + 1.
+ Subsequent instances will be > 0 and just the duplicate number. */
+ if (pass->name)
+ {
+ int n, p = pass->static_pass_number;
+
+ if (p)
+ n = -(--p) + 1;
+ else
+ n = 2, p = -1;
+
+ pass->static_pass_number = p;
+ new->static_pass_number = n;
+ }
+
+ return new;
+}
+
+/* Construct the pass tree. */
+
+void
+init_tree_optimization_passes (void)
+{
+ struct tree_opt_pass **p;
+
+#define NEXT_PASS(PASS) (*p = &PASS, p = &(*p)->next)
+#define DUP_PASS(PASS) (*dup_pass_1 (&PASS))
+
+ p = &all_passes;
+ NEXT_PASS (pass_gimple);
+ NEXT_PASS (pass_remove_useless_stmts);
+ NEXT_PASS (pass_mudflap_1);
+ NEXT_PASS (pass_lower_cf);
+ NEXT_PASS (pass_lower_eh);
+ NEXT_PASS (pass_all_optimizations);
+ NEXT_PASS (pass_mudflap_2);
+ NEXT_PASS (pass_rebuild_bind);
+ *p = NULL;
+
+ p = &pass_all_optimizations.sub;
+ NEXT_PASS (pass_build_cfg);
+ NEXT_PASS (pass_tree_profile);
+ NEXT_PASS (pass_referenced_vars);
+ NEXT_PASS (pass_build_pta);
+ NEXT_PASS (pass_build_ssa);
+ NEXT_PASS (pass_rename_ssa_copies);
+ NEXT_PASS (pass_early_warn_uninitialized);
+ NEXT_PASS (pass_dce);
+ NEXT_PASS (pass_dominator);
+ NEXT_PASS (pass_redundant_phi);
+ NEXT_PASS (DUP_PASS (pass_dce));
+ NEXT_PASS (pass_forwprop);
+ NEXT_PASS (pass_phiopt);
+ NEXT_PASS (pass_may_alias);
+ NEXT_PASS (pass_tail_recursion);
+ NEXT_PASS (pass_ch);
+ NEXT_PASS (pass_del_pta);
+ NEXT_PASS (pass_profile);
+ NEXT_PASS (pass_lower_complex);
+ NEXT_PASS (pass_sra);
+ NEXT_PASS (DUP_PASS (pass_rename_ssa_copies));
+ NEXT_PASS (DUP_PASS (pass_dominator));
+ NEXT_PASS (DUP_PASS (pass_redundant_phi));
+ NEXT_PASS (DUP_PASS (pass_dce));
+ NEXT_PASS (pass_dse);
+ NEXT_PASS (DUP_PASS (pass_forwprop));
+ NEXT_PASS (DUP_PASS (pass_phiopt));
+ NEXT_PASS (pass_ccp);
+ NEXT_PASS (DUP_PASS (pass_redundant_phi));
+ NEXT_PASS (pass_fold_builtins);
+ NEXT_PASS (pass_split_crit_edges);
+ NEXT_PASS (pass_pre);
+ NEXT_PASS (DUP_PASS (pass_dominator));
+ NEXT_PASS (DUP_PASS (pass_redundant_phi));
+ NEXT_PASS (pass_cd_dce);
+ NEXT_PASS (DUP_PASS (pass_dse));
+ NEXT_PASS (DUP_PASS (pass_forwprop));
+ NEXT_PASS (DUP_PASS (pass_phiopt));
+ NEXT_PASS (pass_tail_calls);
+ NEXT_PASS (pass_late_warn_uninitialized);
+ NEXT_PASS (pass_warn_function_return);
+ NEXT_PASS (pass_del_ssa);
+ NEXT_PASS (pass_nrv);
+ NEXT_PASS (pass_remove_useless_vars);
+ NEXT_PASS (pass_del_cfg);
+ *p = NULL;
+
+#undef NEXT_PASS
+#undef DUP_PASS
+
+ /* Register the passes with the tree dump code. */
+ register_dump_files (all_passes);
+}
+
+static void execute_pass_list (struct tree_opt_pass *);
+
+static unsigned int current_properties;
+static unsigned int last_verified;
+
+static void
+execute_todo (unsigned int flags)
+{
+ if (flags & TODO_rename_vars)
+ {
+ if (bitmap_first_set_bit (vars_to_rename) >= 0)
+ rewrite_into_ssa ();
+ BITMAP_XFREE (vars_to_rename);
+ }
+
+ if ((flags & TODO_dump_func) && dump_file)
+ dump_function_to_file (current_function_decl,
+ dump_file, dump_flags);
+
+ if (flags & TODO_ggc_collect)
+ ggc_collect ();
+
+#ifdef ENABLE_CHECKING
+ if (flags & TODO_verify_ssa)
+ verify_ssa ();
+ if (flags & TODO_verify_flow)
+ verify_flow_info ();
+ if (flags & TODO_verify_stmts)
+ verify_stmts ();
+#endif
+}
+
+static bool
+execute_one_pass (struct tree_opt_pass *pass)
+{
+ unsigned int todo;
+
+ /* See if we're supposed to run this pass. */
+ if (pass->gate && !pass->gate ())
+ return false;
+
+ /* Verify that all required properties are present. */
+ if (pass->properties_required & ~current_properties)
+ abort ();
+
+ /* Run pre-pass verification. */
+ todo = pass->todo_flags_start & ~last_verified;
+ if (todo)
+ execute_todo (todo);
+
+ /* If a dump file name is present, open it if enabled. */
+ if (pass->static_pass_number)
+ {
+ dump_file = dump_begin (pass->static_pass_number, &dump_flags);
+ if (dump_file)
+ {
+ const char *dname, *aname;
+ dname = (*lang_hooks.decl_printable_name) (current_function_decl, 2);
+ aname = (IDENTIFIER_POINTER
+ (DECL_ASSEMBLER_NAME (current_function_decl)));
+ fprintf (dump_file, "\n;; Function %s (%s)\n\n", dname, aname);
+ }
+ }
+
+ /* If a timevar is present, start it. */
+ if (pass->tv_id)
+ timevar_push (pass->tv_id);
+
+ /* If the pass is requesting ssa variable renaming, allocate the bitmap. */
+ if (pass->todo_flags_finish & TODO_rename_vars)
+ vars_to_rename = BITMAP_XMALLOC ();
+ /* Do it! */
+ if (pass->execute)
+ pass->execute ();
+ /* Run post-pass cleanup and verification. */
+ todo = pass->todo_flags_finish;
+ last_verified = todo & TODO_verify_all;
+ if (todo)
+ execute_todo (todo);
+
+ /* Update properties. */
+ current_properties &= ~pass->properties_destroyed;
+ current_properties |= pass->properties_provided;
+
+ /* Close down timevar and dump file. */
+ if (pass->tv_id)
+ timevar_pop (pass->tv_id);
+ if (dump_file)
+ {
+ dump_end (pass->static_pass_number, dump_file);
+ dump_file = NULL;
+ }
+
+ return true;
+}
+
+static void
+execute_pass_list (struct tree_opt_pass *pass)
+{
+ do
+ {
+ if (execute_one_pass (pass) && pass->sub)
+ execute_pass_list (pass->sub);
+ pass = pass->next;
+ }
+ while (pass);
+}
+
+
/* Called to move the SAVE_EXPRs for parameter declarations in a
nested function into the nested function. DATA is really the
nested FUNCTION_DECL. */
@@ -52,43 +459,6 @@ set_save_expr_context (tree *tp,
return NULL;
}
-/* Clear out the DECL_RTL for the non-static local variables in BLOCK and
- its sub-blocks. DATA is the decl of the function being processed. */
-
-static tree
-clear_decl_rtl (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, void *data)
-{
- bool nonstatic_p, local_p;
- tree t = *tp;
-
- switch (TREE_CODE (t))
- {
- case VAR_DECL:
- nonstatic_p = !TREE_STATIC (t) && !DECL_EXTERNAL (t);
- local_p = decl_function_context (t) == data;
- break;
-
- case PARM_DECL:
- case LABEL_DECL:
- nonstatic_p = true;
- local_p = decl_function_context (t) == data;
- break;
-
- case RESULT_DECL:
- nonstatic_p = local_p = true;
- break;
-
- default:
- nonstatic_p = local_p = false;
- break;
- }
-
- if (nonstatic_p && local_p)
- SET_DECL_RTL (t, NULL);
-
- return NULL;
-}
-
/* For functions-as-trees languages, this performs all optimization and
compilation for FNDECL. */
@@ -96,7 +466,7 @@ void
tree_rest_of_compilation (tree fndecl, bool nested_p)
{
location_t saved_loc;
- struct cgraph_node *node, *saved_node = NULL;
+ struct cgraph_node *saved_node = NULL, *node;
timevar_push (TV_EXPAND);
@@ -152,21 +522,34 @@ tree_rest_of_compilation (tree fndecl, bool nested_p)
}
}
+ /* Note that the folders should only create gimple expressions.
+ This is a hack until the new folder is ready. */
+ in_gimple_form = true;
+
+ /* Perform all tree transforms and optimizations. */
+ execute_pass_list (all_passes);
+
+ /* Note that the folders can create non-gimple expressions again. */
+ in_gimple_form = false;
+
/* If the function has a variably modified type, there may be
SAVE_EXPRs in the parameter types. Their context must be set to
refer to this function; they cannot be expanded in the containing
function. */
- if (decl_function_context (fndecl)
+ if (decl_function_context (fndecl) == current_function_decl
&& variably_modified_type_p (TREE_TYPE (fndecl)))
walk_tree (&TREE_TYPE (fndecl), set_save_expr_context, fndecl,
NULL);
+ /* Expand the variables recorded during gimple lowering. This must
+ occur before the call to expand_function_start to ensure that
+ all used variables are expanded before we expand anything on the
+ PENDING_SIZES list. */
+ expand_used_vars ();
+
/* Set up parameters and prepare for return, for the function. */
expand_function_start (fndecl, 0);
- /* Allow language dialects to perform special processing. */
- lang_hooks.rtl_expand.start ();
-
/* If this function is `main', emit a call to `__main'
to run global initializers, etc. */
if (DECL_NAME (fndecl)
@@ -175,7 +558,7 @@ tree_rest_of_compilation (tree fndecl, bool nested_p)
expand_main_function ();
/* Generate the RTL for this function. */
- lang_hooks.rtl_expand.stmt (DECL_SAVED_TREE (fndecl));
+ expand_expr_stmt_value (DECL_SAVED_TREE (fndecl), 0, 0);
/* We hard-wired immediate_size_expand to zero above.
expand_function_end will decrement this variable. So, we set the
@@ -183,9 +566,14 @@ tree_rest_of_compilation (tree fndecl, bool nested_p)
zero. */
immediate_size_expand = 1;
- /* Allow language dialects to perform special processing. */
- lang_hooks.rtl_expand.end ();
+ /* Make sure the locus is set to the end of the function, so that
+ epilogue line numbers and warnings are set properly. */
+ if (cfun->function_end_locus.file)
+ input_location = cfun->function_end_locus;
+ /* The following insns belong to the top scope. */
+ record_block_change (DECL_INITIAL (current_function_decl));
+
/* Generate rtl for function exit. */
expand_function_end ();
@@ -201,10 +589,30 @@ tree_rest_of_compilation (tree fndecl, bool nested_p)
/* Run the optimizers and output the assembler code for this function. */
rest_of_compilation (fndecl);
+ /* Restore original body if still needed. */
+ if (cfun->saved_tree)
+ {
+ DECL_SAVED_TREE (fndecl) = cfun->saved_tree;
+ DECL_ARGUMENTS (fndecl) = cfun->saved_args;
- /* Undo the GC context switch. */
- if (nested_p)
- ggc_pop_context ();
+ /* When not in unit-at-a-time mode, we must preserve out of line copy
+ representing node before inlining. Restore original outgoing edges
+ using clone we created earlier. */
+ if (!flag_unit_at_a_time)
+ {
+ struct cgraph_edge *e;
+ while (node->callees)
+ cgraph_remove_edge (node->callees);
+ node->callees = saved_node->callees;
+ saved_node->callees = NULL;
+ for (e = saved_node->callees; e; e = e->next_callee)
+ e->caller = node;
+ cgraph_remove_node (saved_node);
+ }
+ }
+ else
+ DECL_SAVED_TREE (fndecl) = NULL;
+ cfun = 0;
/* If requested, warn about function definitions where the function will
return a value (usually of some struct or union type) which itself will
@@ -230,41 +638,11 @@ tree_rest_of_compilation (tree fndecl, bool nested_p)
}
}
- /* Since we don't need the RTL for this function anymore, stop pointing to
- it. That's especially important for LABEL_DECLs, since you can reach all
- the instructions in the function from the CODE_LABEL stored in the
- DECL_RTL for the LABEL_DECL. Walk the BLOCK-tree, clearing DECL_RTL for
- LABEL_DECLs and non-static local variables. Note that we must check the
- context of the variables, otherwise processing a nested function can kill
- the rtl of a variable from an outer function. */
- walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
- clear_decl_rtl,
- fndecl);
- /* Restore original body if still needed. */
- if (cfun->saved_tree)
- {
- DECL_SAVED_TREE (fndecl) = cfun->saved_tree;
- DECL_ARGUMENTS (fndecl) = cfun->saved_args;
-
- /* When not in unit-at-a-time mode, we must preserve out of line copy
- representing node before inlining. Restore original outgoing edges
- using clone we created earlier. */
- if (!flag_unit_at_a_time)
- {
- struct cgraph_edge *e;
- while (node->callees)
- cgraph_remove_edge (node->callees);
- node->callees = saved_node->callees;
- saved_node->callees = NULL;
- for (e = saved_node->callees; e; e = e->next_callee)
- e->caller = node;
- cgraph_remove_node (saved_node);
- }
- }
- else
+ if (!nested_p && !flag_inline_trees)
{
DECL_SAVED_TREE (fndecl) = NULL;
- if (cgraph_node (fndecl)->origin)
+ if (DECL_STRUCT_FUNCTION (fndecl) == 0
+ && !cgraph_node (fndecl)->origin)
{
/* Stop pointing to the local nodes about to be freed.
But DECL_INITIAL must remain nonzero so we know this
@@ -275,11 +653,13 @@ tree_rest_of_compilation (tree fndecl, bool nested_p)
DECL_INITIAL (fndecl) = error_mark_node;
}
}
- free_after_compilation (cfun);
- cfun = 0;
- DECL_STRUCT_FUNCTION (fndecl) = 0;
input_location = saved_loc;
+ ggc_collect ();
+
+ /* Undo the GC context switch. */
+ if (nested_p)
+ ggc_pop_context ();
timevar_pop (TV_EXPAND);
}
diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c
new file mode 100644
index 00000000000..97b0b4a3e82
--- /dev/null
+++ b/gcc/tree-outof-ssa.c
@@ -0,0 +1,2173 @@
+/* Convert a program in SSA form into Normal form.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ Contributed by Andrew Macleod <amacleod@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "flags.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "ggc.h"
+#include "langhooks.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "output.h"
+#include "errors.h"
+#include "expr.h"
+#include "function.h"
+#include "diagnostic.h"
+#include "bitmap.h"
+#include "tree-flow.h"
+#include "tree-gimple.h"
+#include "tree-inline.h"
+#include "varray.h"
+#include "timevar.h"
+#include "tree-alias-common.h"
+#include "hashtab.h"
+#include "tree-dump.h"
+#include "tree-ssa-live.h"
+#include "tree-pass.h"
+
+/* Used to hold all the components required to do SSA PHI elimination.
+ The node and pred/succ list is a simple linear list of nodes and
+ edges represented as pairs of nodes.
+
+ The predecessor and successor list: Nodes are entered in pairs, where
+ [0] ->PRED, [1]->SUCC. All the even indexes in the array represent
+ predecessors, all the odd elements are successors.
+
+ Rationale:
+ When implemented as bitmaps, very large programs SSA->Normal times were
+ being dominated by clearing the interference graph.
+
+ Typically this list of edges is extremely small since it only includes
+ PHI results and uses from a single edge which have not coalesced with
+ each other. This means that no virtual PHI nodes are included, and
+ empirical evidence suggests that the number of edges rarely exceed
+ 3, and in a bootstrap of GCC, the maximum size encountered was 7.
+ This also limits the number of possible nodes that are involved to
+ rarely more than 6, and in the bootstrap of gcc, the maximum number
+ of nodes encountered was 12. */
+
+typedef struct _elim_graph {
+ /* Size of the elimination vectors. */
+ int size;
+
+ /* List of nodes in the elimination graph. */
+ varray_type nodes;
+
+ /* The predecessor and successor edge list. */
+ varray_type edge_list;
+
+ /* Visited vector. */
+ sbitmap visited;
+
+ /* Stack for visited nodes. */
+ varray_type stack;
+
+ /* The variable partition map. */
+ var_map map;
+
+ /* Edge being eliminated by this graph. */
+ edge e;
+
+ /* List of constant copies to emit. These are pushed on in pairs. */
+ varray_type const_copies;
+} *elim_graph;
+
+
+/* Local functions. */
+static tree create_temp (tree);
+static void insert_copy_on_edge (edge, tree, tree);
+static elim_graph new_elim_graph (int);
+static inline void delete_elim_graph (elim_graph);
+static inline void clear_elim_graph (elim_graph);
+static inline int elim_graph_size (elim_graph);
+static inline void elim_graph_add_node (elim_graph, tree);
+static inline void elim_graph_add_edge (elim_graph, int, int);
+static inline int elim_graph_remove_succ_edge (elim_graph, int);
+
+static inline void eliminate_name (elim_graph, tree);
+static void eliminate_build (elim_graph, basic_block, int);
+static void elim_forward (elim_graph, int);
+static int elim_unvisited_predecessor (elim_graph, int);
+static void elim_backward (elim_graph, int);
+static void elim_create (elim_graph, int);
+static void eliminate_phi (edge, int, elim_graph);
+static tree_live_info_p coalesce_ssa_name (var_map, int);
+static void assign_vars (var_map);
+static bool replace_variable (var_map, tree *, tree *);
+static void eliminate_virtual_phis (void);
+static void coalesce_abnormal_edges (var_map, conflict_graph, root_var_p);
+static void print_exprs (FILE *, const char *, tree, const char *, tree,
+ const char *);
+static void print_exprs_edge (FILE *, edge, const char *, tree, const char *,
+ tree);
+
+
+/* Create a temporary variable based on the type of variable T. Use T's name
+ as the prefix. */
+
+static tree
+create_temp (tree t)
+{
+ tree tmp;
+ const char *name = NULL;
+ tree type;
+
+ if (TREE_CODE (t) == SSA_NAME)
+ t = SSA_NAME_VAR (t);
+
+ if (TREE_CODE (t) != VAR_DECL
+ && TREE_CODE (t) != PARM_DECL)
+ abort ();
+
+ type = TREE_TYPE (t);
+ tmp = DECL_NAME (t);
+ if (tmp)
+ name = IDENTIFIER_POINTER (tmp);
+
+ if (name == NULL)
+ name = "temp";
+ tmp = create_tmp_var (type, name);
+ DECL_ARTIFICIAL (tmp) = DECL_ARTIFICIAL (t);
+ add_referenced_tmp_var (tmp);
+
+ /* add_referenced_tmp_var will create the annotation and set up some
+ of the flags in the annotation. However, some flags we need to
+ inherit from our original variable. */
+ var_ann (tmp)->type_mem_tag = var_ann (t)->type_mem_tag;
+ if (is_call_clobbered (t))
+ mark_call_clobbered (tmp);
+
+ return tmp;
+}
+
+
+/* This helper function fill insert a copy from a constant or variable SRC to
+ variable DEST on edge E. */
+
+static void
+insert_copy_on_edge (edge e, tree dest, tree src)
+{
+ tree copy;
+
+ copy = build (MODIFY_EXPR, TREE_TYPE (dest), dest, src);
+ set_is_used (dest);
+
+ if (TREE_CODE (src) == ADDR_EXPR)
+ src = TREE_OPERAND (src, 0);
+ if (TREE_CODE (src) == VAR_DECL || TREE_CODE (src) == PARM_DECL)
+ set_is_used (src);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file,
+ "Inserting a copy on edge BB%d->BB%d :",
+ e->src->index,
+ e->dest->index);
+ print_generic_expr (dump_file, copy, dump_flags);
+ fprintf (dump_file, "\n");
+ }
+
+ bsi_insert_on_edge (e, copy);
+}
+
+
+/* Create an elimination graph with SIZE nodes and associated data
+ structures. */
+
+static elim_graph
+new_elim_graph (int size)
+{
+ elim_graph g = (elim_graph) xmalloc (sizeof (struct _elim_graph));
+
+ VARRAY_TREE_INIT (g->nodes, 30, "Elimination Node List");
+ VARRAY_TREE_INIT (g->const_copies, 20, "Elimination Constant Copies");
+ VARRAY_INT_INIT (g->edge_list, 20, "Elimination Edge List");
+ VARRAY_INT_INIT (g->stack, 30, " Elimination Stack");
+
+ g->visited = sbitmap_alloc (size);
+
+ return g;
+}
+
+
+/* Empty elimination graph G. */
+
+static inline void
+clear_elim_graph (elim_graph g)
+{
+ VARRAY_POP_ALL (g->nodes);
+ VARRAY_POP_ALL (g->edge_list);
+}
+
+
+/* Delete elimination graph G. */
+
+static inline void
+delete_elim_graph (elim_graph g)
+{
+ sbitmap_free (g->visited);
+ free (g);
+}
+
+
+/* Return the number of nodes in graph G. */
+
+static inline int
+elim_graph_size (elim_graph g)
+{
+ return VARRAY_ACTIVE_SIZE (g->nodes);
+}
+
+
+/* Add NODE to graph G, if it doesn't exist already. */
+
+static inline void
+elim_graph_add_node (elim_graph g, tree node)
+{
+ int x;
+ for (x = 0; x < elim_graph_size (g); x++)
+ if (VARRAY_TREE (g->nodes, x) == node)
+ return;
+ VARRAY_PUSH_TREE (g->nodes, node);
+}
+
+
+/* Add the edge PRED->SUCC to graph G. */
+
+static inline void
+elim_graph_add_edge (elim_graph g, int pred, int succ)
+{
+ VARRAY_PUSH_INT (g->edge_list, pred);
+ VARRAY_PUSH_INT (g->edge_list, succ);
+}
+
+
+/* Remove an edge from graph G for which NODE is the predecessor, and
+ return the successor node. -1 is returned if there is no such edge. */
+
+static inline int
+elim_graph_remove_succ_edge (elim_graph g, int node)
+{
+ int y;
+ unsigned x;
+ for (x = 0; x < VARRAY_ACTIVE_SIZE (g->edge_list); x += 2)
+ if (VARRAY_INT (g->edge_list, x) == node)
+ {
+ VARRAY_INT (g->edge_list, x) = -1;
+ y = VARRAY_INT (g->edge_list, x + 1);
+ VARRAY_INT (g->edge_list, x + 1) = -1;
+ return y;
+ }
+ return -1;
+}
+
+
+/* Find all the nodes in GRAPH which are successors to NODE in the
+ edge list. VAR will hold the partition number found. CODE is the
+ code fragment executed for every node found. */
+
+#define FOR_EACH_ELIM_GRAPH_SUCC(GRAPH, NODE, VAR, CODE) \
+do { \
+ unsigned x_; \
+ int y_; \
+ for (x_ = 0; x_ < VARRAY_ACTIVE_SIZE ((GRAPH)->edge_list); x_ += 2) \
+ { \
+ y_ = VARRAY_INT ((GRAPH)->edge_list, x_); \
+ if (y_ != (NODE)) \
+ continue; \
+ (VAR) = VARRAY_INT ((GRAPH)->edge_list, x_ + 1); \
+ CODE; \
+ } \
+} while (0)
+
+
+/* Find all the nodes which are predecessors of NODE in the edge list for
+ GRAPH. VAR will hold the partition number found. CODE is the
+ code fragment executed for every node found. */
+
+#define FOR_EACH_ELIM_GRAPH_PRED(GRAPH, NODE, VAR, CODE) \
+do { \
+ unsigned x_; \
+ int y_; \
+ for (x_ = 0; x_ < VARRAY_ACTIVE_SIZE ((GRAPH)->edge_list); x_ += 2) \
+ { \
+ y_ = VARRAY_INT ((GRAPH)->edge_list, x_ + 1); \
+ if (y_ != (NODE)) \
+ continue; \
+ (VAR) = VARRAY_INT ((GRAPH)->edge_list, x_); \
+ CODE; \
+ } \
+} while (0)
+
+
+/* Add T to elimination graph G. */
+
+static inline void
+eliminate_name (elim_graph g, tree T)
+{
+ elim_graph_add_node (g, T);
+}
+
+
+/* Build elimination graph G for basic block BB on incoming PHI edge I. */
+
+static void
+eliminate_build (elim_graph g, basic_block B, int i)
+{
+ tree phi;
+ tree T0, Ti;
+ int p0, pi;
+
+ clear_elim_graph (g);
+
+ for (phi = phi_nodes (B); phi; phi = TREE_CHAIN (phi))
+ {
+ T0 = var_to_partition_to_var (g->map, PHI_RESULT (phi));
+
+ /* Ignore results which are not in partitions. */
+ if (T0 == NULL_TREE)
+ continue;
+
+ if (PHI_ARG_EDGE (phi, i) == g->e)
+ Ti = PHI_ARG_DEF (phi, i);
+ else
+ {
+ /* On rare occasions, a PHI node may not have the arguments
+ in the same order as all of the other PHI nodes. If they don't
+ match, find the appropriate index here. */
+ pi = phi_arg_from_edge (phi, g->e);
+ if (pi == -1)
+ abort();
+ Ti = PHI_ARG_DEF (phi, pi);
+ }
+
+ /* If this argument is a constant, or a SSA_NAME which is being
+ left in SSA form, just queue a copy to be emitted on this
+ edge. */
+ if (!phi_ssa_name_p (Ti)
+ || (TREE_CODE (Ti) == SSA_NAME
+ && var_to_partition (g->map, Ti) == NO_PARTITION))
+ {
+ /* Save constant copies until all other copies have been emitted
+ on this edge. */
+ VARRAY_PUSH_TREE (g->const_copies, T0);
+ VARRAY_PUSH_TREE (g->const_copies, Ti);
+ }
+ else
+ {
+ Ti = var_to_partition_to_var (g->map, Ti);
+ if (T0 != Ti)
+ {
+ eliminate_name (g, T0);
+ eliminate_name (g, Ti);
+ p0 = var_to_partition (g->map, T0);
+ pi = var_to_partition (g->map, Ti);
+ elim_graph_add_edge (g, p0, pi);
+ }
+ }
+ }
+}
+
+
+/* Push successors of T onto the elimination stack for G. */
+
+static void
+elim_forward (elim_graph g, int T)
+{
+ int S;
+ SET_BIT (g->visited, T);
+ FOR_EACH_ELIM_GRAPH_SUCC (g, T, S,
+ {
+ if (!TEST_BIT (g->visited, S))
+ elim_forward (g, S);
+ });
+ VARRAY_PUSH_INT (g->stack, T);
+}
+
+
+/* Return 1 if there unvisited predecessors of T in graph G. */
+
+static int
+elim_unvisited_predecessor (elim_graph g, int T)
+{
+ int P;
+ FOR_EACH_ELIM_GRAPH_PRED (g, T, P,
+ {
+ if (!TEST_BIT (g->visited, P))
+ return 1;
+ });
+ return 0;
+}
+
+/* Process predecessors first, and insert a copy. */
+
+static void
+elim_backward (elim_graph g, int T)
+{
+ int P;
+ SET_BIT (g->visited, T);
+ FOR_EACH_ELIM_GRAPH_PRED (g, T, P,
+ {
+ if (!TEST_BIT (g->visited, P))
+ {
+ elim_backward (g, P);
+ insert_copy_on_edge (g->e,
+ partition_to_var (g->map, P),
+ partition_to_var (g->map, T));
+ }
+ });
+}
+
+/* Insert required copies for T in graph G. Check for a strongly connected
+ region, and create a temporary to break the cycle if one is found. */
+
+static void
+elim_create (elim_graph g, int T)
+{
+ tree U;
+ int P, S;
+
+ if (elim_unvisited_predecessor (g, T))
+ {
+ U = create_temp (partition_to_var (g->map, T));
+ insert_copy_on_edge (g->e, U, partition_to_var (g->map, T));
+ FOR_EACH_ELIM_GRAPH_PRED (g, T, P,
+ {
+ if (!TEST_BIT (g->visited, P))
+ {
+ elim_backward (g, P);
+ insert_copy_on_edge (g->e, partition_to_var (g->map, P), U);
+ }
+ });
+ }
+ else
+ {
+ S = elim_graph_remove_succ_edge (g, T);
+ if (S != -1)
+ {
+ SET_BIT (g->visited, T);
+ insert_copy_on_edge (g->e,
+ partition_to_var (g->map, T),
+ partition_to_var (g->map, S));
+ }
+ }
+
+}
+
+/* Eliminate all the phi nodes on edge E in graph G. I is the usual PHI
+ index that edge E's values are found on. */
+
+static void
+eliminate_phi (edge e, int i, elim_graph g)
+{
+ int num_nodes = 0;
+ int x;
+ basic_block B = e->dest;
+
+#if defined ENABLE_CHECKING
+ if (i == -1)
+ abort ();
+ if (VARRAY_ACTIVE_SIZE (g->const_copies) != 0)
+ abort ();
+#endif
+
+ /* Abnormal edges already have everything coalesced, or the coalescer
+ would have aborted. */
+ if (e->flags & EDGE_ABNORMAL)
+ return;
+
+ num_nodes = num_var_partitions (g->map);
+ g->e = e;
+
+ eliminate_build (g, B, i);
+
+ if (elim_graph_size (g) != 0)
+ {
+ sbitmap_zero (g->visited);
+ VARRAY_POP_ALL (g->stack);
+
+ for (x = 0; x < elim_graph_size (g); x++)
+ {
+ tree var = VARRAY_TREE (g->nodes, x);
+ int p = var_to_partition (g->map, var);
+ if (!TEST_BIT (g->visited, p))
+ elim_forward (g, p);
+ }
+
+ sbitmap_zero (g->visited);
+ while (VARRAY_ACTIVE_SIZE (g->stack) > 0)
+ {
+ x = VARRAY_TOP_INT (g->stack);
+ VARRAY_POP (g->stack);
+ if (!TEST_BIT (g->visited, x))
+ elim_create (g, x);
+ }
+ }
+
+ /* If there are any pending constant copies, issue them now. */
+ while (VARRAY_ACTIVE_SIZE (g->const_copies) > 0)
+ {
+ tree src, dest;
+ src = VARRAY_TOP_TREE (g->const_copies);
+ VARRAY_POP (g->const_copies);
+ dest = VARRAY_TOP_TREE (g->const_copies);
+ VARRAY_POP (g->const_copies);
+ insert_copy_on_edge (e, dest, src);
+ }
+}
+
+
+/* Shortcut routine to print messages to file F of the form:
+ "STR1 EXPR1 STR2 EXPR2 STR3." */
+
+static void
+print_exprs (FILE *f, const char *str1, tree expr1, const char *str2,
+ tree expr2, const char *str3)
+{
+ fprintf (f, "%s", str1);
+ print_generic_expr (f, expr1, TDF_SLIM);
+ fprintf (f, "%s", str2);
+ print_generic_expr (f, expr2, TDF_SLIM);
+ fprintf (f, "%s", str3);
+}
+
+
+/* Shortcut routine to print abnormal edge messages to file F of the form:
+ "STR1 EXPR1 STR2 EXPR2 across edge E. */
+
+static void
+print_exprs_edge (FILE *f, edge e, const char *str1, tree expr1,
+ const char *str2, tree expr2)
+{
+ print_exprs (f, str1, expr1, str2, expr2, " across an abnormal edge");
+ fprintf (f, " from BB%d->BB%d\n", e->src->index,
+ e->dest->index);
+}
+
+
+/* Coalesce partitions in MAP which are live across abnormal edges in GRAPH.
+ RV is the root variable groupings of the partitions in MAP. Since code
+ cannot be inserted on these edges, failure to coalesce something across
+ an abnormal edge is an error. */
+
+static void
+coalesce_abnormal_edges (var_map map, conflict_graph graph, root_var_p rv)
+{
+ basic_block bb;
+ edge e;
+ tree phi, var, tmp;
+ int x, y;
+
+ /* Code cannot be inserted on abnormal edges. Look for all abnormal
+ edges, and coalesce any PHI results with their arguments across
+ that edge. */
+
+ FOR_EACH_BB (bb)
+ for (e = bb->succ; e; e = e->succ_next)
+ if (e->dest != EXIT_BLOCK_PTR && e->flags & EDGE_ABNORMAL)
+ for (phi = phi_nodes (e->dest); phi; phi = TREE_CHAIN (phi))
+ {
+ /* Visit each PHI on the destination side of this abnormal
+ edge, and attempt to coalesce the argument with the result. */
+ var = PHI_RESULT (phi);
+ x = var_to_partition (map, var);
+
+ /* Ignore results which are not relevant. */
+ if (x == NO_PARTITION)
+ continue;
+
+ y = phi_arg_from_edge (phi, e);
+ if (y == -1)
+ abort ();
+
+ tmp = PHI_ARG_DEF (phi, y);
+ if (!phi_ssa_name_p (tmp))
+ {
+ print_exprs_edge (stderr, e,
+ "\nConstant argument in PHI. Can't insert :",
+ var, " = ", tmp);
+ abort ();
+ }
+ y = var_to_partition (map, tmp);
+ if (x == NO_PARTITION || y == NO_PARTITION)
+ abort ();
+ if (root_var_find (rv, x) != root_var_find (rv, y))
+ {
+ print_exprs_edge (stderr, e, "\nDifferent root vars: ",
+ root_var (rv, root_var_find (rv, x)),
+ " and ",
+ root_var (rv, root_var_find (rv, y)));
+ abort ();
+ }
+
+ if (x != y)
+ {
+ if (!conflict_graph_conflict_p (graph, x, y))
+ {
+ /* Now map the partitions back to their real variables. */
+ var = partition_to_var (map, x);
+ tmp = partition_to_var (map, y);
+ if (dump_file
+ && (dump_flags & TDF_DETAILS))
+ {
+ print_exprs_edge (dump_file, e,
+ "ABNORMAL: Coalescing ",
+ var, " and ", tmp);
+ }
+ if (var_union (map, var, tmp) == NO_PARTITION)
+ {
+ print_exprs_edge (stderr, e, "\nUnable to coalesce",
+ partition_to_var (map, x), " and ",
+ partition_to_var (map, y));
+ abort ();
+ }
+ conflict_graph_merge_regs (graph, x, y);
+ }
+ else
+ {
+ print_exprs_edge (stderr, e, "\n Conflict ",
+ partition_to_var (map, x),
+ " and ", partition_to_var (map, y));
+ abort ();
+ }
+ }
+ }
+}
+
+
+/* Reduce the number of live ranges in MAP. Live range information is
+ returned if FLAGS indicates that we are combining temporaries, otherwise
+ NULL is returned. The only partitions which are associated with actual
+ variables at this point are those which are forced to be coalesced for
+ various reason. (live on entry, live across abnormal edges, etc.). */
+
+static tree_live_info_p
+coalesce_ssa_name (var_map map, int flags)
+{
+ int num, x, i;
+ sbitmap live;
+ tree var, phi;
+ root_var_p rv;
+ tree_live_info_p liveinfo;
+ var_ann_t ann;
+ conflict_graph graph;
+ basic_block bb;
+ coalesce_list_p cl = NULL;
+
+ if (num_var_partitions (map) <= 1)
+ return NULL;
+
+ /* If no preference given, use cheap coalescing of all partitions. */
+ if ((flags & (SSANORM_COALESCE_PARTITIONS | SSANORM_USE_COALESCE_LIST)) == 0)
+ flags |= SSANORM_COALESCE_PARTITIONS;
+
+ liveinfo = calculate_live_on_entry (map);
+ calculate_live_on_exit (liveinfo);
+ rv = root_var_init (map);
+
+ /* Remove single element variable from the list. */
+ root_var_compact (rv);
+
+ if (flags & SSANORM_USE_COALESCE_LIST)
+ {
+ cl = create_coalesce_list (map);
+
+ /* Add all potential copies via PHI arguments to the list. */
+ FOR_EACH_BB (bb)
+ {
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ tree res = PHI_RESULT (phi);
+ int p = var_to_partition (map, res);
+ if (p == NO_PARTITION)
+ continue;
+ for (x = 0; x < PHI_NUM_ARGS (phi); x++)
+ {
+ tree arg = PHI_ARG_DEF (phi, x);
+ int p2;
+
+ if (TREE_CODE (arg) != SSA_NAME)
+ continue;
+ if (SSA_NAME_VAR (res) != SSA_NAME_VAR (arg))
+ continue;
+ p2 = var_to_partition (map, PHI_ARG_DEF (phi, x));
+ if (p2 != NO_PARTITION)
+ add_coalesce (cl, p, p2, 1);
+ }
+ }
+ }
+
+ /* Coalesce all the result decls together. */
+ var = NULL_TREE;
+ i = 0;
+ for (x = 0; x < num_var_partitions (map); x++)
+ {
+ tree p = partition_to_var (map, x);
+ if (TREE_CODE (SSA_NAME_VAR(p)) == RESULT_DECL)
+ {
+ if (var == NULL_TREE)
+ {
+ var = p;
+ i = x;
+ }
+ else
+ add_coalesce (cl, i, x, 1);
+ }
+ }
+ }
+
+ /* Build a conflict graph. */
+ graph = build_tree_conflict_graph (liveinfo, rv, cl);
+
+ if (cl)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Before sorting:\n");
+ dump_coalesce_list (dump_file, cl);
+ }
+
+ sort_coalesce_list (cl);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "\nAfter sorting:\n");
+ dump_coalesce_list (dump_file, cl);
+ }
+ }
+
+ /* Put the single element variables back in. */
+ root_var_decompact (rv);
+
+ /* First, coalesce all live on entry variables to their root variable.
+ This will ensure the first use is coming from the correct location. */
+
+ live = sbitmap_alloc (num_var_partitions (map));
+ sbitmap_zero (live);
+
+ /* Set 'live' vector to indicate live on entry partitions. */
+ num = num_var_partitions (map);
+ for (x = 0 ; x < num; x++)
+ {
+ var = partition_to_var (map, x);
+ if (default_def (SSA_NAME_VAR (var)) == var)
+ SET_BIT (live, x);
+ }
+
+ if ((flags & SSANORM_COMBINE_TEMPS) == 0)
+ {
+ delete_tree_live_info (liveinfo);
+ liveinfo = NULL;
+ }
+
+ /* Assign root variable as partition representative for each live on entry
+ partition. */
+ EXECUTE_IF_SET_IN_SBITMAP (live, 0, x,
+ {
+ var = root_var (rv, root_var_find (rv, x));
+ ann = var_ann (var);
+ /* If these aren't already coalesced... */
+ if (partition_to_var (map, x) != var)
+ {
+ if (ann->out_of_ssa_tag)
+ {
+ /* This root variable has already been assigned to another
+ partition which is not coalesced with this one. */
+ abort ();
+ }
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ print_exprs (dump_file, "Must coalesce ",
+ partition_to_var (map, x),
+ " with the root variable ", var, ".\n");
+ }
+
+ change_partition_var (map, var, x);
+ }
+ });
+
+ sbitmap_free (live);
+
+ /* Coalesce partitions live across abnormal edges. */
+ coalesce_abnormal_edges (map, graph, rv);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ dump_var_map (dump_file, map);
+
+ /* Coalesce partitions. */
+ if (flags & SSANORM_USE_COALESCE_LIST)
+ coalesce_tpa_members (rv, graph, map, cl,
+ ((dump_flags & TDF_DETAILS) ? dump_file
+ : NULL));
+
+
+ if (flags & SSANORM_COALESCE_PARTITIONS)
+ coalesce_tpa_members (rv, graph, map, NULL,
+ ((dump_flags & TDF_DETAILS) ? dump_file
+ : NULL));
+ if (cl)
+ delete_coalesce_list (cl);
+ root_var_delete (rv);
+ conflict_graph_delete (graph);
+
+ return liveinfo;
+}
+
+
+/* Take the ssa-name var_map MAP, and assign real variables to each
+ partition. */
+
+static void
+assign_vars (var_map map)
+{
+ int x, i, num, rep;
+ tree t, var;
+ var_ann_t ann;
+ root_var_p rv;
+
+ rv = root_var_init (map);
+ if (!rv)
+ return;
+
+ /* Coalescing may already have forced some partitions to their root
+ variable. Find these and tag them. */
+
+ num = num_var_partitions (map);
+ for (x = 0; x < num; x++)
+ {
+ var = partition_to_var (map, x);
+ if (TREE_CODE (var) != SSA_NAME)
+ {
+ /* Coalescing will already have verified that more than one
+ partition doesn't have the same root variable. Simply marked
+ the variable as assigned. */
+ ann = var_ann (var);
+ ann->out_of_ssa_tag = 1;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "partition %d has variable ", x);
+ print_generic_expr (dump_file, var, TDF_SLIM);
+ fprintf (dump_file, " assigned to it.\n");
+ }
+
+ }
+ }
+
+ num = root_var_num (rv);
+ for (x = 0; x < num; x++)
+ {
+ var = root_var (rv, x);
+ ann = var_ann (var);
+ for (i = root_var_first_partition (rv, x);
+ i != ROOT_VAR_NONE;
+ i = root_var_next_partition (rv, i))
+ {
+ t = partition_to_var (map, i);
+
+ if (t == var || TREE_CODE (t) != SSA_NAME)
+ continue;
+
+ rep = var_to_partition (map, t);
+
+ if (!ann->out_of_ssa_tag)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ print_exprs (dump_file, "", t, " --> ", var, "\n");
+ change_partition_var (map, var, rep);
+ continue;
+ }
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ print_exprs (dump_file, "", t, " not coalesced with ", var,
+ "");
+
+ var = create_temp (t);
+ change_partition_var (map, var, rep);
+ ann = var_ann (var);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, " --> New temp: '");
+ print_generic_expr (dump_file, var, TDF_SLIM);
+ fprintf (dump_file, "'\n");
+ }
+ }
+ }
+
+ root_var_delete (rv);
+}
+
+
+/* Replace *P with whatever variable it has been rewritten to based on the
+ partitions in MAP. EXPR is an optional expression vector over SSA versions
+ which is used to replace *P with an expression instead of a variable.
+ If the stmt is changed, return true. */
+
+static inline bool
+replace_variable (var_map map, tree *p, tree *expr)
+{
+ tree new_var;
+ tree var = *p;
+
+ /* Check if we are replacing this variable with an expression. */
+ if (expr)
+ {
+ int version = SSA_NAME_VERSION (*p);
+ if (expr[version])
+ {
+ tree new_expr = TREE_OPERAND (expr[version], 1);
+ *p = new_expr;
+ /* Clear the stmt's RHS, or GC might bite us. */
+ TREE_OPERAND (expr[version], 1) = NULL_TREE;
+ return true;
+ }
+ }
+
+ new_var = var_to_partition_to_var (map, var);
+ if (new_var)
+ {
+ *p = new_var;
+ set_is_used (new_var);
+ return true;
+ }
+ return false;
+}
+
+
+/* Remove any PHI node which is a virtual PHI. */
+
+static void
+eliminate_virtual_phis (void)
+{
+ basic_block bb;
+ tree phi, next;
+
+ FOR_EACH_BB (bb)
+ {
+ for (phi = phi_nodes (bb); phi; phi = next)
+ {
+ next = TREE_CHAIN (phi);
+ if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
+ {
+#ifdef ENABLE_CHECKING
+ int i;
+ /* There should be no arguments of this PHI which are in
+ the partition list, or we get incorrect results. */
+ for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ {
+ tree arg = PHI_ARG_DEF (phi, i);
+ if (TREE_CODE (arg) == SSA_NAME
+ && is_gimple_reg (SSA_NAME_VAR (arg)))
+ {
+ fprintf (stderr, "Argument of PHI is not virtual (");
+ print_generic_expr (stderr, arg, TDF_SLIM);
+ fprintf (stderr, "), but the result is :");
+ print_generic_stmt (stderr, phi, TDF_SLIM);
+ abort();
+ }
+ }
+#endif
+ remove_phi_node (phi, NULL_TREE, bb);
+ }
+ }
+ }
+}
+
+
+/* This routine will coalesce variables in MAP of the same type which do not
+ interfere with each other. LIVEINFO is the live range info for variables
+ of interest. This will both reduce the memory footprint of the stack, and
+ allow us to coalesce together local copies of globals and scalarized
+ component refs. */
+
+static void
+coalesce_vars (var_map map, tree_live_info_p liveinfo)
+{
+ basic_block bb;
+ type_var_p tv;
+ tree var;
+ int x, p, p2;
+ coalesce_list_p cl;
+ conflict_graph graph;
+
+ cl = create_coalesce_list (map);
+
+ /* Merge all the live on entry vectors for coalesced partitions. */
+ for (x = 0; x < num_var_partitions (map); x++)
+ {
+ var = partition_to_var (map, x);
+ p = var_to_partition (map, var);
+ if (p != x)
+ live_merge_and_clear (liveinfo, p, x);
+ }
+
+ /* When PHI nodes are turned into copies, the result of each PHI node
+ becomes live on entry to the block. Mark these now. */
+ FOR_EACH_BB (bb)
+ {
+ tree phi, arg;
+ int p;
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ p = var_to_partition (map, PHI_RESULT (phi));
+
+ /* Skip virtual PHI nodes. */
+ if (p == NO_PARTITION)
+ continue;
+
+ make_live_on_entry (liveinfo, bb, p);
+
+ /* Each argument is a potential copy operation. Add any arguments
+ which are not coalesced to the result to the coalesce list. */
+ for (x = 0; x < PHI_NUM_ARGS (phi); x++)
+ {
+ arg = PHI_ARG_DEF (phi, x);
+ if (!phi_ssa_name_p (arg))
+ continue;
+ p2 = var_to_partition (map, arg);
+ if (p2 == NO_PARTITION)
+ continue;
+ if (p != p2)
+ add_coalesce (cl, p, p2, 1);
+ }
+ }
+ }
+
+
+ /* Re-calculate live on exit info. */
+ calculate_live_on_exit (liveinfo);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Live range info for variable memory coalescing.\n");
+ dump_live_info (dump_file, liveinfo, LIVEDUMP_ALL);
+
+ fprintf (dump_file, "Coalesce list from phi nodes:\n");
+ dump_coalesce_list (dump_file, cl);
+ }
+
+
+ tv = type_var_init (map);
+ if (dump_file)
+ type_var_dump (dump_file, tv);
+ type_var_compact (tv);
+ if (dump_file)
+ type_var_dump (dump_file, tv);
+
+ graph = build_tree_conflict_graph (liveinfo, tv, cl);
+
+ type_var_decompact (tv);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "type var list now looks like:n");
+ type_var_dump (dump_file, tv);
+
+ fprintf (dump_file, "Coalesce list after conflict graph build:\n");
+ dump_coalesce_list (dump_file, cl);
+ }
+
+ sort_coalesce_list (cl);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Coalesce list after sorting:\n");
+ dump_coalesce_list (dump_file, cl);
+ }
+
+ coalesce_tpa_members (tv, graph, map, cl,
+ ((dump_flags & TDF_DETAILS) ? dump_file : NULL));
+
+ type_var_delete (tv);
+ delete_coalesce_list (cl);
+}
+
+
+/* Temporary Expression Replacement (TER)
+
+ Replace SSA version variables during out-of-ssa with their defining
+ expression if there is only one use of the variable.
+
+ A pass is made through the function, one block at a time. No cross block
+ information is tracked.
+
+ Variables which only have one use, and whose defining stmt is considered
+ a replaceable expression (see check_replaceable) are entered into
+ consideration by adding a list of dependent partitions to the version_info
+ vector for that ssa_name_version. This information comes from the partition
+ mapping for each USE. At the same time, the partition_dep_list vector for
+ these partitions have this version number entered into their lists.
+
+ When the use of a replaceable ssa_variable is encountered, the dependence
+ list in version_info[] is moved to the "pending_dependence" list in case
+ the current expression is also replaceable. (To be determined later in
+ processing this stmt.) version_info[] for the version is then updated to
+ point to the defining stmt and the 'replaceable' bit is set.
+
+ Any partition which is defined by a statement 'kills' any expression which
+ is dependent on this partition. Every ssa version in the partitions'
+ dependence list is removed from future consideration.
+
+ All virtual references are lumped together. Any expression which is
+ dependent on any virtual variable (via a VUSE) has a dependence added
+ to the special partition defined by VIRTUAL_PARTITION.
+
+ Whenever a VDEF is seen, all expressions dependent this VIRTUAL_PARTITION
+ are removed from consideration.
+
+ At the end of a basic block, all expression are removed from consideration
+ in preparation for the next block.
+
+ The end result is a vector over SSA_NAME_VERSION which is passed back to
+ rewrite_out_of_ssa. As the SSA variables are being rewritten, instead of
+ replacing the SSA_NAME tree element with the partition it was assigned,
+ it is replaced with the RHS of the defining expression. */
+
+
+/* Dependancy list element. This can contain either a partition index or a
+ version number, depending on which list it is in. */
+
+typedef struct value_expr_d
+{
+ int value;
+ struct value_expr_d *next;
+} *value_expr_p;
+
+
+/* Temporary Expression Replacement (TER) table information. */
+
+typedef struct temp_expr_table_d
+{
+ var_map map;
+ void **version_info;
+ value_expr_p *partition_dep_list;
+ bitmap replaceable;
+ bool saw_replaceable;
+ int virtual_partition;
+ bitmap partition_in_use;
+ value_expr_p free_list;
+ value_expr_p pending_dependence;
+} *temp_expr_table_p;
+
+/* Used to indicate a dependancy on VDEFs. */
+#define VIRTUAL_PARTITION(table) (table->virtual_partition)
+
+static temp_expr_table_p new_temp_expr_table (var_map);
+static tree *free_temp_expr_table (temp_expr_table_p);
+static inline value_expr_p new_value_expr (temp_expr_table_p);
+static inline void free_value_expr (temp_expr_table_p, value_expr_p);
+static inline value_expr_p find_value_in_list (value_expr_p, int,
+ value_expr_p *);
+static inline void add_value_to_list (temp_expr_table_p, value_expr_p *, int);
+static inline void add_info_to_list (temp_expr_table_p, value_expr_p *,
+ value_expr_p);
+static value_expr_p remove_value_from_list (value_expr_p *, int);
+static void add_dependance (temp_expr_table_p, int, tree);
+static bool check_replaceable (temp_expr_table_p, tree);
+static void finish_expr (temp_expr_table_p, int, bool);
+static void mark_replaceable (temp_expr_table_p, tree);
+static inline void kill_expr (temp_expr_table_p, int, bool);
+static inline void kill_virtual_exprs (temp_expr_table_p, bool);
+static void find_replaceable_in_bb (temp_expr_table_p, basic_block);
+static tree *find_replaceable_exprs (var_map);
+static void dump_replaceable_exprs (FILE *, tree *);
+
+
+/* Create a new TER table for MAP. */
+
+static temp_expr_table_p
+new_temp_expr_table (var_map map)
+{
+ temp_expr_table_p t;
+
+ t = (temp_expr_table_p) xmalloc (sizeof (struct temp_expr_table_d));
+ t->map = map;
+
+ t->version_info = xcalloc (highest_ssa_version + 1, sizeof (void *));
+ t->partition_dep_list = xcalloc (num_var_partitions (map) + 1,
+ sizeof (value_expr_p));
+
+ t->replaceable = BITMAP_XMALLOC ();
+ t->partition_in_use = BITMAP_XMALLOC ();
+
+ t->saw_replaceable = false;
+ t->virtual_partition = num_var_partitions (map);
+ t->free_list = NULL;
+ t->pending_dependence = NULL;
+
+ return t;
+}
+
+
+/* Free TER table T. If there are valid replacements, return the expression
+ vector. */
+
+static tree *
+free_temp_expr_table (temp_expr_table_p t)
+{
+ value_expr_p p;
+ tree *ret = NULL;
+
+#ifdef ENABLE_CHECKING
+ int x;
+ for (x = 0; x <= num_var_partitions (t->map); x++)
+ if (t->partition_dep_list[x] != NULL)
+ abort();
+#endif
+
+ while ((p = t->free_list))
+ {
+ t->free_list = p->next;
+ free (p);
+ }
+
+ BITMAP_XFREE (t->partition_in_use);
+ BITMAP_XFREE (t->replaceable);
+
+ free (t->partition_dep_list);
+ if (t->saw_replaceable)
+ ret = (tree *)t->version_info;
+ else
+ free (t->version_info);
+
+ free (t);
+ return ret;
+}
+
+
+/* Allocate a new value list node. Take it from the free list in TABLE if
+ possible. */
+
+static inline value_expr_p
+new_value_expr (temp_expr_table_p table)
+{
+ value_expr_p p;
+ if (table->free_list)
+ {
+ p = table->free_list;
+ table->free_list = p->next;
+ }
+ else
+ p = (value_expr_p) xmalloc (sizeof (struct value_expr_d));
+
+ return p;
+}
+
+
+/* Add value list node P to the free list in TABLE. */
+
+static inline void
+free_value_expr (temp_expr_table_p table, value_expr_p p)
+{
+ p->next = table->free_list;
+ table->free_list = p;
+}
+
+
+/* Find VALUE if its in LIST. Return a pointer to the list object if found,
+ else return NULL. If LAST_PTR is provided, it will point to the previous
+ item upon return, or NULL if this is the first item in the list. */
+
+static inline value_expr_p
+find_value_in_list (value_expr_p list, int value, value_expr_p *last_ptr)
+{
+ value_expr_p curr;
+ value_expr_p last = NULL;
+
+ for (curr = list; curr; last = curr, curr = curr->next)
+ {
+ if (curr->value == value)
+ break;
+ }
+ if (last_ptr)
+ *last_ptr = last;
+ return curr;
+}
+
+
+/* Add VALUE to LIST, if it isn't already present. TAB is the expression
+ table */
+
+static inline void
+add_value_to_list (temp_expr_table_p tab, value_expr_p *list, int value)
+{
+ value_expr_p info;
+
+ if (!find_value_in_list (*list, value, NULL))
+ {
+ info = new_value_expr (tab);
+ info->value = value;
+ info->next = *list;
+ *list = info;
+ }
+}
+
+
+/* Add value node INFO if it's value isn't already in LIST. Free INFO if
+ it is already in the list. TAB is the expression table. */
+
+static inline void
+add_info_to_list (temp_expr_table_p tab, value_expr_p *list, value_expr_p info)
+{
+ if (find_value_in_list (*list, info->value, NULL))
+ free_value_expr (tab, info);
+ else
+ {
+ info->next = *list;
+ *list = info;
+ }
+}
+
+
+/* Look for VALUE in LIST. If found, remove it from the list and return it's
+ pointer. */
+
+static value_expr_p
+remove_value_from_list (value_expr_p *list, int value)
+{
+ value_expr_p info, last;
+
+ info = find_value_in_list (*list, value, &last);
+ if (!info)
+ return NULL;
+ if (!last)
+ *list = info->next;
+ else
+ last->next = info->next;
+
+ return info;
+}
+
+
+/* Add a dependancy between the def of ssa VERSION and VAR. if VAR is
+ replaceable by an expression, add a dependance each of the elements of the
+ expression. These are contained in the pending list. TAB is the
+ expression table. */
+
+static void
+add_dependance (temp_expr_table_p tab, int version, tree var)
+{
+ int i, x;
+ value_expr_p info;
+
+ i = SSA_NAME_VERSION (var);
+ if (bitmap_bit_p (tab->replaceable, i))
+ {
+ /* This variable is being substituted, so use whatever dependences
+ were queued up when we marked this as replaceable earlier. */
+ while ((info = tab->pending_dependence))
+ {
+ tab->pending_dependence = info->next;
+ /* Get the partition this variable was dependent on. Reuse this
+ object to represent the current expression instead. */
+ x = info->value;
+ info->value = version;
+ add_info_to_list (tab, &(tab->partition_dep_list[x]), info);
+ add_value_to_list (tab,
+ (value_expr_p *)&(tab->version_info[version]), x);
+ bitmap_set_bit (tab->partition_in_use, x);
+ }
+ }
+ else
+ {
+ i = var_to_partition (tab->map, var);
+#ifdef ENABLE_CHECKING
+ if (i== NO_PARTITION)
+ abort ();
+#endif
+ add_value_to_list (tab, &(tab->partition_dep_list[i]), version);
+ add_value_to_list (tab,
+ (value_expr_p *)&(tab->version_info[version]), i);
+ bitmap_set_bit (tab->partition_in_use, i);
+ }
+}
+
+
+/* Check if expression STMT is suitable for replacement in table TAB. If so,
+ create an expression entry. Return true if this stmt is replaceable. */
+
+static bool
+check_replaceable (temp_expr_table_p tab, tree stmt)
+{
+ stmt_ann_t ann;
+ vuse_optype vuseops;
+ def_optype defs;
+ use_optype uses;
+ tree var, def;
+ int num_use_ops, version, i;
+ var_map map = tab->map;
+
+ if (TREE_CODE (stmt) != MODIFY_EXPR)
+ return false;
+
+ ann = stmt_ann (stmt);
+ defs = DEF_OPS (ann);
+
+ /* Punt if there is more than 1 def, or more than 1 use. */
+ if (NUM_DEFS (defs) != 1)
+ return false;
+ def = DEF_OP (defs, 0);
+ if (version_ref_count (map, def) != 1)
+ return false;
+
+ /* Assignments to variables assigned to hard registers are not
+ replaceable. */
+ if (DECL_HARD_REGISTER (SSA_NAME_VAR (def)))
+ return false;
+
+ /* There must be no VDEFS. */
+ if (NUM_VDEFS (VDEF_OPS (ann)) != 0)
+ return false;
+
+ /* Float expressions must go through memory if float-store is on. */
+ if (flag_float_store && FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (stmt, 1))))
+ return false;
+
+ uses = USE_OPS (ann);
+ num_use_ops = NUM_USES (uses);
+ vuseops = VUSE_OPS (ann);
+
+ /* Any expression which has no virtual operands and no real operands
+ should have been propagated if it's possible to do anything with them.
+ If this happens here, it probably exists that way for a reason, so we
+ won't touch it. An example is:
+ b_4 = &tab
+ There are no virtual uses nor any real uses, so we just leave this
+ alone to be safe. */
+
+ if (num_use_ops == 0 && NUM_VUSES (vuseops) == 0)
+ return false;
+
+ version = SSA_NAME_VERSION (def);
+
+ /* Add this expression to the dependancy list for each use partition. */
+ for (i = 0; i < num_use_ops; i++)
+ {
+ var = USE_OP (uses, i);
+ add_dependance (tab, version, var);
+ }
+
+ /* If there are VUSES, add a dependence on virtual defs. */
+ if (NUM_VUSES (vuseops) != 0)
+ {
+ add_value_to_list (tab, (value_expr_p *)&(tab->version_info[version]),
+ VIRTUAL_PARTITION (tab));
+ add_value_to_list (tab,
+ &(tab->partition_dep_list[VIRTUAL_PARTITION (tab)]),
+ version);
+ bitmap_set_bit (tab->partition_in_use, VIRTUAL_PARTITION (tab));
+ }
+
+ return true;
+}
+
+
+/* This function will remove the expression for VERSION from replacement
+ consideration.n table TAB If 'replace' is true, it is marked as
+ replaceable, otherwise not. */
+
+static void
+finish_expr (temp_expr_table_p tab, int version, bool replace)
+{
+ value_expr_p info, tmp;
+ int partition;
+
+ /* Remove this expression from its dependent lists. The partition dependance
+ list is retained and transfered later to whomever uses this version. */
+ for (info = (value_expr_p) tab->version_info[version]; info; info = tmp)
+ {
+ partition = info->value;
+#ifdef ENABLE_CHECKING
+ if (tab->partition_dep_list[partition] == NULL)
+ abort ();
+#endif
+ tmp = remove_value_from_list (&(tab->partition_dep_list[partition]),
+ version);
+#ifdef ENABLE_CHECKING
+ if (!tmp)
+ abort ();
+#endif
+ free_value_expr (tab, tmp);
+ /* Only clear the bit when the dependancy list is emptied via
+ a replacement. Otherwise kill_expr will take care of it. */
+ if (!(tab->partition_dep_list[partition]) && replace)
+ bitmap_clear_bit (tab->partition_in_use, partition);
+ tmp = info->next;
+ if (!replace)
+ free_value_expr (tab, info);
+ }
+
+ if (replace)
+ {
+ tab->saw_replaceable = true;
+ bitmap_set_bit (tab->replaceable, version);
+ }
+ else
+ {
+#ifdef ENABLE_CHECKING
+ if (bitmap_bit_p (tab->replaceable, version))
+ abort ();
+#endif
+ tab->version_info[version] = NULL;
+ }
+}
+
+
+/* Mark the expression associated with VAR as replaceable, and enter
+ the defining stmt into the version_info table TAB. */
+
+static void
+mark_replaceable (temp_expr_table_p tab, tree var)
+{
+ value_expr_p info;
+ int version = SSA_NAME_VERSION (var);
+ finish_expr (tab, version, true);
+
+ /* Move the dependence list to the pending list. */
+ if (tab->version_info[version])
+ {
+ info = (value_expr_p) tab->version_info[version];
+ for ( ; info->next; info = info->next)
+ continue;
+ info->next = tab->pending_dependence;
+ tab->pending_dependence = (value_expr_p)tab->version_info[version];
+ }
+
+ tab->version_info[version] = SSA_NAME_DEF_STMT (var);
+}
+
+
+/* This function marks any expression in TAB which is dependent on PARTITION
+ as NOT replaceable. CLEAR_BIT is used to determine whether partition_in_use
+ should have its bit cleared. Since this routine can be called within an
+ EXECUTE_IF_SET_IN_BITMAP, the bit can't always be cleared. */
+
+static inline void
+kill_expr (temp_expr_table_p tab, int partition, bool clear_bit)
+{
+ value_expr_p ptr;
+
+ /* Mark every active expr dependant on this var as not replaceable. */
+ while ((ptr = tab->partition_dep_list[partition]) != NULL)
+ finish_expr (tab, ptr->value, false);
+
+ if (clear_bit)
+ bitmap_clear_bit (tab->partition_in_use, partition);
+}
+
+
+/* This function kills all expressions in TAB which are dependant on virtual
+ DEFs. CLEAR_BIT determines whether partition_in_use gets cleared. */
+
+static inline void
+kill_virtual_exprs (temp_expr_table_p tab, bool clear_bit)
+{
+ kill_expr (tab, VIRTUAL_PARTITION (tab), clear_bit);
+}
+
+
+/* This function processes basic block BB, and looks for variables which can
+ be replaced by their expressions. Results are stored in TAB. */
+
+static void
+find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb)
+{
+ block_stmt_iterator bsi;
+ tree stmt, def;
+ stmt_ann_t ann;
+ int partition, num, i;
+ use_optype uses;
+ def_optype defs;
+ var_map map = tab->map;
+ value_expr_p p;
+
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ stmt = bsi_stmt (bsi);
+ ann = stmt_ann (stmt);
+
+ /* Determine if this stmt finishes an existing expression. */
+ uses = USE_OPS (ann);
+ num = NUM_USES (uses);
+ for (i = 0; i < num; i++)
+ {
+ def = USE_OP (uses, i);
+ if (tab->version_info[SSA_NAME_VERSION (def)])
+ {
+ /* Mark expression as replaceable unless stmt is volatile. */
+ if (!ann->has_volatile_ops)
+ mark_replaceable (tab, def);
+ else
+ finish_expr (tab, SSA_NAME_VERSION (def), false);
+ }
+ }
+
+ /* Next, see if this stmt kills off an active expression. */
+ defs = DEF_OPS (ann);
+ num = NUM_DEFS (defs);
+ for (i = 0; i < num; i++)
+ {
+ def = DEF_OP (defs, i);
+ partition = var_to_partition (map, def);
+ if (partition != NO_PARTITION && tab->partition_dep_list[partition])
+ kill_expr (tab, partition, true);
+ }
+
+ /* Now see if we are creating a new expression or not. */
+ if (!ann->has_volatile_ops)
+ check_replaceable (tab, stmt);
+
+ /* Free any unused dependancy lists. */
+ while ((p = tab->pending_dependence))
+ {
+ tab->pending_dependence = p->next;
+ free_value_expr (tab, p);
+ }
+
+ /* A VDEF kills any expression using a virtual operand. */
+ if (NUM_VDEFS (VDEF_OPS (ann)) > 0)
+ kill_virtual_exprs (tab, true);
+ }
+}
+
+
+/* This function is the driver routine for replacement of temporary expressions
+ in the SSA->normal phase, operating on MAP. If there are replaceable
+ expressions, a table is returned which maps SSA versions to the
+ expressions they should be replaced with. A NULL_TREE indicates no
+ replacement should take place. If there are no replacements at all,
+ NULL is returned by the function, otherwise an expression vector indexed
+ by SSA_NAME version numbers. */
+
+static tree *
+find_replaceable_exprs (var_map map)
+{
+ basic_block bb;
+ int i;
+ temp_expr_table_p table;
+ tree *ret;
+
+ table = new_temp_expr_table (map);
+ FOR_EACH_BB (bb)
+ {
+ find_replaceable_in_bb (table, bb);
+ EXECUTE_IF_SET_IN_BITMAP ((table->partition_in_use), 0, i,
+ {
+ kill_expr (table, i, false);
+ });
+ }
+
+ ret = free_temp_expr_table (table);
+ return ret;
+}
+
+
+/* Dump TER expression table EXPR to file F. */
+
+static void
+dump_replaceable_exprs (FILE *f, tree *expr)
+{
+ tree stmt, var;
+ int x;
+ fprintf (f, "\nReplacing Expressions\n");
+ for (x = 0; x < (int)highest_ssa_version + 1; x++)
+ if (expr[x])
+ {
+ stmt = expr[x];
+ var = DEF_OP (STMT_DEF_OPS (stmt), 0);
+ print_generic_expr (f, var, TDF_SLIM);
+ fprintf (f, " replace with --> ");
+ print_generic_expr (f, TREE_OPERAND (stmt, 1), TDF_SLIM);
+ fprintf (f, "\n");
+ }
+ fprintf (f, "\n");
+}
+
+
+/* Helper function for discover_nonconstant_array_refs.
+ Look for ARRAY_REF nodes with non-constant indexes and mark them
+ addressable. */
+
+static tree
+discover_nonconstant_array_refs_r (tree * tp, int *walk_subtrees,
+ void *data ATTRIBUTE_UNUSED)
+{
+ tree t = *tp;
+
+ if (TYPE_P (t) || DECL_P (t))
+ *walk_subtrees = 0;
+ else if (TREE_CODE (t) == ARRAY_REF)
+ {
+ while ((TREE_CODE (t) == ARRAY_REF
+ && is_gimple_min_invariant (TREE_OPERAND (t, 1)))
+ || (TREE_CODE (t) == COMPONENT_REF
+ || TREE_CODE (t) == BIT_FIELD_REF
+ || TREE_CODE (t) == REALPART_EXPR
+ || TREE_CODE (t) == IMAGPART_EXPR))
+ t = TREE_OPERAND (t, 0);
+
+ if (TREE_CODE (t) == ARRAY_REF)
+ {
+ t = get_base_address (t);
+ if (t && DECL_P (t))
+ TREE_ADDRESSABLE (t) = 1;
+ }
+
+ *walk_subtrees = 0;
+ }
+
+ return NULL_TREE;
+}
+
+
+/* RTL expansion is not able to compile array references with variable
+ offsets for arrays stored in single register. Discover such
+ expressions and mark variables as addressable to avoid this
+ scenario. */
+
+static void
+discover_nonconstant_array_refs (void)
+{
+ basic_block bb;
+ block_stmt_iterator bsi;
+
+ FOR_EACH_BB (bb)
+ {
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ walk_tree (bsi_stmt_ptr (bsi), discover_nonconstant_array_refs_r,
+ NULL , NULL);
+ }
+}
+
+
+/* This function will rewrite the current program using the variable mapping
+ found in MAP. If the replacement vector VALUES is provided, any
+ occurrences of partitions with non-null entries in the vector will be
+ replaced with the expression in the vector instead of its mapped
+ variable. */
+
+static void
+rewrite_trees (var_map map, tree *values)
+{
+ elim_graph g;
+ basic_block bb;
+ block_stmt_iterator si;
+ edge e;
+ tree phi;
+ bool changed;
+
+#ifdef ENABLE_CHECKING
+ /* Search for PHIs where the destination has no partition, but one
+ or more arguments has a partition. This should not happen and can
+ create incorrect code. */
+ FOR_EACH_BB (bb)
+ {
+ tree phi;
+
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ tree T0 = var_to_partition_to_var (map, PHI_RESULT (phi));
+
+ if (T0 == NULL_TREE)
+ {
+ int i;
+
+ for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ {
+ tree arg = PHI_ARG_DEF (phi, i);
+
+ if (TREE_CODE (arg) == SSA_NAME
+ && var_to_partition (map, arg) != NO_PARTITION)
+ {
+ fprintf (stderr, "Argument of PHI is in a partition :(");
+ print_generic_expr (stderr, arg, TDF_SLIM);
+ fprintf (stderr, "), but the result is not :");
+ print_generic_stmt (stderr, phi, TDF_SLIM);
+ abort();
+ }
+ }
+ }
+ }
+ }
+#endif
+
+ /* Replace PHI nodes with any required copies. */
+ g = new_elim_graph (map->num_partitions);
+ g->map = map;
+ FOR_EACH_BB (bb)
+ {
+ for (si = bsi_start (bb); !bsi_end_p (si); )
+ {
+ size_t i, num_uses, num_defs;
+ use_optype uses;
+ def_optype defs;
+ tree stmt = bsi_stmt (si);
+ tree *use_p = NULL;
+ int remove = 0, is_copy = 0;
+ stmt_ann_t ann;
+
+ get_stmt_operands (stmt);
+ ann = stmt_ann (stmt);
+ changed = false;
+
+ if (TREE_CODE (stmt) == MODIFY_EXPR
+ && (TREE_CODE (TREE_OPERAND (stmt, 1)) == SSA_NAME))
+ is_copy = 1;
+
+ uses = USE_OPS (ann);
+ num_uses = NUM_USES (uses);
+
+ for (i = 0; i < num_uses; i++)
+ {
+ use_p = USE_OP_PTR (uses, i);
+ if (replace_variable (map, use_p, values))
+ changed = true;
+ }
+
+ defs = DEF_OPS (ann);
+ num_defs = NUM_DEFS (defs);
+
+ /* Mark this stmt for removal if it is the list of replaceable
+ expressions. */
+ if (values && num_defs == 1)
+ {
+ tree def = DEF_OP (defs, 0);
+ tree val;
+ val = values[SSA_NAME_VERSION (def)];
+ if (val)
+ remove = 1;
+ }
+ if (!remove)
+ {
+ for (i = 0; i < num_defs; i++)
+ {
+ tree *def_p = DEF_OP_PTR (defs, i);
+
+ if (replace_variable (map, def_p, NULL))
+ changed = true;
+
+ /* If both SSA_NAMEs coalesce to the same variable,
+ mark the now redundant copy for removal. */
+ if (is_copy
+ && num_uses == 1
+ && use_p
+ && def_p
+ && (*def_p == *use_p))
+ remove = 1;
+ }
+ if (changed)
+ modify_stmt (stmt);
+ }
+
+ /* Remove any stmts marked for removal. */
+ if (remove)
+ bsi_remove (&si);
+ else
+ bsi_next (&si);
+ }
+
+ phi = phi_nodes (bb);
+ if (phi)
+ {
+ for (e = bb->pred; e; e = e->pred_next)
+ eliminate_phi (e, phi_arg_from_edge (phi, e), g);
+ }
+ }
+
+ delete_elim_graph (g);
+
+ /* If any copies were inserted on edges, actually insert them now. */
+ bsi_commit_edge_inserts (NULL);
+}
+
+
+/* Remove the variables specified in MAP from SSA form. Any debug information
+ is sent to DUMP. FLAGS indicate what options should be used. */
+
+void
+remove_ssa_form (FILE *dump, var_map map, int flags)
+{
+ tree_live_info_p liveinfo;
+ basic_block bb;
+ tree phi, next;
+ FILE *save;
+ tree *values = NULL;
+
+ save = dump_file;
+ dump_file = dump;
+
+ /* If we are not combining temps, don't calculate live ranges for variables
+ with only one SSA version. */
+ if ((flags & SSANORM_COMBINE_TEMPS) == 0)
+ compact_var_map (map, VARMAP_NO_SINGLE_DEFS);
+ else
+ compact_var_map (map, VARMAP_NORMAL);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ dump_var_map (dump_file, map);
+
+ liveinfo = coalesce_ssa_name (map, flags);
+
+ /* Make sure even single occurrence variables are in the list now. */
+ if ((flags & SSANORM_COMBINE_TEMPS) == 0)
+ compact_var_map (map, VARMAP_NORMAL);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "After Coalescing:\n");
+ dump_var_map (dump_file, map);
+ }
+
+ if (flags & SSANORM_PERFORM_TER)
+ {
+ values = find_replaceable_exprs (map);
+ if (values && dump_file && (dump_flags & TDF_DETAILS))
+ dump_replaceable_exprs (dump_file, values);
+ }
+
+ /* Assign real variables to the partitions now. */
+ assign_vars (map);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "After Root variable replacement:\n");
+ dump_var_map (dump_file, map);
+ }
+
+ if ((flags & SSANORM_COMBINE_TEMPS) && liveinfo)
+ {
+ coalesce_vars (map, liveinfo);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "After variable memory coalescing:\n");
+ dump_var_map (dump_file, map);
+ }
+ }
+
+ if (liveinfo)
+ delete_tree_live_info (liveinfo);
+
+ rewrite_trees (map, values);
+
+ if (values)
+ free (values);
+
+ /* Remove phi nodes which have been translated back to real variables. */
+ FOR_EACH_BB (bb)
+ {
+ for (phi = phi_nodes (bb); phi; phi = next)
+ {
+ next = TREE_CHAIN (phi);
+ if ((flags & SSANORM_REMOVE_ALL_PHIS)
+ || var_to_partition (map, PHI_RESULT (phi)) != NO_PARTITION)
+ remove_phi_node (phi, NULL_TREE, bb);
+ }
+ }
+
+ dump_file = save;
+}
+
+
+/* Take a subset of the variables VARS in the current function out of SSA
+ form. */
+
+void
+rewrite_vars_out_of_ssa (bitmap vars)
+{
+ if (bitmap_first_set_bit (vars) >= 0)
+ {
+ var_map map;
+ basic_block bb;
+ tree phi;
+ int i;
+ int ssa_flags;
+
+ /* Search for PHIs in which one of the PHI arguments is marked for
+ translation out of SSA form, but for which the PHI result is not
+ marked for translation out of SSA form.
+
+ Our per-variable out of SSA translation can not handle that case;
+ however we can easily handle it here by creating a new instance
+ of the PHI result's underlying variable and initializing it to
+ the offending PHI argument on the edge associated with the
+ PHI argument. We then change the PHI argument to use our new
+ instead of the PHI's underlying variable.
+
+ You might think we could register partitions for the out-of-ssa
+ translation here and avoid a second walk of the PHI nodes. No
+ such luck since the size of the var map will change if we have
+ to manually take variables out of SSA form here. */
+ FOR_EACH_BB (bb)
+ {
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ tree result = SSA_NAME_VAR (PHI_RESULT (phi));
+
+ /* If the definition is marked for renaming, then we need
+ to do nothing more for this PHI node. */
+ if (bitmap_bit_p (vars, var_ann (result)->uid))
+ continue;
+
+ /* Look at all the arguments and see if any of them are
+ marked for renaming. If so, we need to handle them
+ specially. */
+ for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ {
+ tree arg = PHI_ARG_DEF (phi, i);
+
+ /* If the argument is not an SSA_NAME, then we can ignore
+ this argument. */
+ if (TREE_CODE (arg) != SSA_NAME)
+ continue;
+
+ /* If this argument is marked for renaming, then we need
+ to undo the copy propagation so that we can take
+ the argument out of SSA form without taking the
+ result out of SSA form. */
+ arg = SSA_NAME_VAR (arg);
+ if (bitmap_bit_p (vars, var_ann (arg)->uid))
+ {
+ tree new_name, copy;
+
+ /* Get a new SSA_NAME for the copy, it is based on
+ the result, not the argument! We use the PHI
+ as the definition since we haven't created the
+ definition statement yet. */
+ new_name = make_ssa_name (result, phi);
+
+ /* Now create the copy statement. */
+ copy = build (MODIFY_EXPR, TREE_TYPE (arg),
+ new_name, PHI_ARG_DEF (phi, i));
+
+ /* Now update SSA_NAME_DEF_STMT to point to the
+ newly created statement. */
+ SSA_NAME_DEF_STMT (new_name) = copy;
+
+ /* Now make the argument reference our new SSA_NAME. */
+ PHI_ARG_DEF (phi, i) = new_name;
+
+ /* Queue the statement for insertion. */
+ bsi_insert_on_edge (PHI_ARG_EDGE (phi, i), copy);
+ modify_stmt (copy);
+ }
+ }
+ }
+ }
+
+ /* If any copies were inserted on edges, actually insert them now. */
+ bsi_commit_edge_inserts (NULL);
+
+ /* Now register partitions for all instances of the variables we
+ are taking out of SSA form. */
+ map = init_var_map (highest_ssa_version + 1);
+ register_ssa_partitions_for_vars (vars, map);
+
+ /* Now that we have all the partitions registered, translate the
+ appropriate variables out of SSA form. */
+ ssa_flags = SSANORM_COALESCE_PARTITIONS;
+ if (flag_tree_combine_temps)
+ ssa_flags |= SSANORM_COMBINE_TEMPS;
+ remove_ssa_form (dump_file, map, ssa_flags);
+
+ /* And finally, reset the out_of_ssa flag for each of the vars
+ we just took out of SSA form. */
+ EXECUTE_IF_SET_IN_BITMAP (vars, 0, i,
+ {
+ var_ann (referenced_var (i))->out_of_ssa_tag = 0;
+ });
+
+ /* Free the map as we are done with it. */
+ delete_var_map (map);
+
+ }
+}
+
+
+/* Take the current function out of SSA form, as described in
+ R. Morgan, ``Building an Optimizing Compiler'',
+ Butterworth-Heinemann, Boston, MA, 1998. pp 176-186. */
+
+static void
+rewrite_out_of_ssa (void)
+{
+ var_map map;
+ int var_flags = 0;
+ int ssa_flags = (SSANORM_REMOVE_ALL_PHIS | SSANORM_USE_COALESCE_LIST);
+
+ if (!flag_tree_live_range_split)
+ ssa_flags |= SSANORM_COALESCE_PARTITIONS;
+
+ eliminate_virtual_phis ();
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ dump_tree_cfg (dump_file, dump_flags & ~TDF_DETAILS);
+
+ /* We cannot allow unssa to un-gimplify trees before we instrument them. */
+ if (flag_tree_ter && !flag_mudflap)
+ var_flags = SSA_VAR_MAP_REF_COUNT;
+
+ map = create_ssa_var_map (var_flags);
+
+ if (flag_tree_combine_temps)
+ ssa_flags |= SSANORM_COMBINE_TEMPS;
+ if (flag_tree_ter && !flag_mudflap)
+ ssa_flags |= SSANORM_PERFORM_TER;
+
+ remove_ssa_form (dump_file, map, ssa_flags);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ dump_tree_cfg (dump_file, dump_flags & ~TDF_DETAILS);
+
+ /* Do some cleanups which reduce the amount of data the
+ tree->rtl expanders deal with. */
+ cfg_remove_useless_stmts ();
+
+ /* Flush out flow graph and SSA data. */
+ delete_var_map (map);
+
+ /* Mark arrays indexed with non-constant indices with TREE_ADDRESSABLE. */
+ discover_nonconstant_array_refs ();
+}
+
+
+/* Define the parameters of the out of SSA pass. */
+
+struct tree_opt_pass pass_del_ssa =
+{
+ "optimized", /* name */
+ NULL, /* gate */
+ rewrite_out_of_ssa, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_SSA_TO_NORMAL, /* tv_id */
+ PROP_cfg | PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ /* ??? If TER is enabled, we also kill gimple. */
+ PROP_ssa, /* properties_destroyed */
+ TODO_verify_ssa | TODO_verify_flow
+ | TODO_verify_stmts, /* todo_flags_start */
+ TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */
+};
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
new file mode 100644
index 00000000000..cdaf8efefdc
--- /dev/null
+++ b/gcc/tree-pass.h
@@ -0,0 +1,130 @@
+/* Definitions for describing one tree-ssa optimization pass.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+#ifndef GCC_TREE_PASS_H
+#define GCC_TREE_PASS_H 1
+
+/* Global variables used to communicate with passes. */
+extern FILE *dump_file;
+extern int dump_flags;
+
+extern struct bitmap_head_def *vars_to_rename;
+
+/* Describe one pass. */
+struct tree_opt_pass
+{
+ /* Terse name of the pass used as a fragment of the dump file name. */
+ const char *name;
+
+ /* If non-null, this pass and all sub-passes are executed only if
+ the function returns true. */
+ bool (*gate) (void);
+
+ /* This is the code to run. If null, then there should be sub-passes
+ otherwise this pass does nothing. */
+ void (*execute) (void);
+
+ /* A list of sub-passes to run, dependent on gate predicate. */
+ struct tree_opt_pass *sub;
+
+ /* Next in the list of passes to run, independent of gate predicate. */
+ struct tree_opt_pass *next;
+
+ /* Static pass number, used as a fragment of the dump file name. */
+ unsigned int static_pass_number;
+
+ /* The timevar id associated with this pass. */
+ /* ??? Ideally would be dynamically assigned. */
+ unsigned int tv_id;
+
+ /* Sets of properties input and output from this pass. */
+ unsigned int properties_required;
+ unsigned int properties_provided;
+ unsigned int properties_destroyed;
+
+ /* Flags indicating common sets things to do before and after. */
+ unsigned int todo_flags_start;
+ unsigned int todo_flags_finish;
+};
+
+/* Pass properties. */
+#define PROP_gimple_any (1 << 0) /* entire gimple grammar */
+#define PROP_gimple_lcf (1 << 1) /* lowered control flow */
+#define PROP_gimple_leh (1 << 2) /* lowered eh */
+#define PROP_cfg (1 << 3)
+#define PROP_referenced_vars (1 << 4)
+#define PROP_pta (1 << 5)
+#define PROP_ssa (1 << 6)
+#define PROP_no_crit_edges (1 << 7)
+
+/* To-do flags. */
+#define TODO_dump_func (1 << 0) /* pass doesn't dump itself */
+#define TODO_rename_vars (1 << 1) /* rewrite new vars to ssa */
+#define TODO_ggc_collect (1 << 2) /* run the collector */
+#define TODO_verify_ssa (1 << 3)
+#define TODO_verify_flow (1 << 4)
+#define TODO_verify_stmts (1 << 5)
+
+#define TODO_verify_all \
+ (TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts)
+
+
+extern struct tree_opt_pass pass_mudflap_1;
+extern struct tree_opt_pass pass_mudflap_2;
+extern struct tree_opt_pass pass_remove_useless_stmts;
+extern struct tree_opt_pass pass_lower_cf;
+extern struct tree_opt_pass pass_lower_eh;
+extern struct tree_opt_pass pass_build_cfg;
+extern struct tree_opt_pass pass_tree_profile;
+extern struct tree_opt_pass pass_referenced_vars;
+extern struct tree_opt_pass pass_build_pta;
+extern struct tree_opt_pass pass_del_pta;
+extern struct tree_opt_pass pass_sra;
+extern struct tree_opt_pass pass_tail_recursion;
+extern struct tree_opt_pass pass_tail_calls;
+extern struct tree_opt_pass pass_loop;
+extern struct tree_opt_pass pass_ch;
+extern struct tree_opt_pass pass_ccp;
+extern struct tree_opt_pass pass_build_ssa;
+extern struct tree_opt_pass pass_del_ssa;
+extern struct tree_opt_pass pass_dominator;
+extern struct tree_opt_pass pass_dce;
+extern struct tree_opt_pass pass_cd_dce;
+extern struct tree_opt_pass pass_may_alias;
+extern struct tree_opt_pass pass_split_crit_edges;
+extern struct tree_opt_pass pass_pre;
+extern struct tree_opt_pass pass_profile;
+extern struct tree_opt_pass pass_lower_complex;
+extern struct tree_opt_pass pass_fold_builtins;
+extern struct tree_opt_pass pass_early_warn_uninitialized;
+extern struct tree_opt_pass pass_late_warn_uninitialized;
+extern struct tree_opt_pass pass_warn_function_return;
+extern struct tree_opt_pass pass_phiopt;
+extern struct tree_opt_pass pass_forwprop;
+extern struct tree_opt_pass pass_redundant_phi;
+extern struct tree_opt_pass pass_dse;
+extern struct tree_opt_pass pass_nrv;
+extern struct tree_opt_pass pass_remove_useless_vars;
+extern struct tree_opt_pass pass_rename_ssa_copies;
+
+
+#endif /* GCC_TREE_PASS_H */
diff --git a/gcc/tree-phinodes.c b/gcc/tree-phinodes.c
new file mode 100644
index 00000000000..e4fc904fd4a
--- /dev/null
+++ b/gcc/tree-phinodes.c
@@ -0,0 +1,524 @@
+/* Generic routines for manipulating PHIs
+ Copyright (C) 2003 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 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "rtl.h"
+#include "varray.h"
+#include "ggc.h"
+#include "basic-block.h"
+#include "tree-flow.h"
+#include "toplev.h"
+
+/* Rewriting a function into SSA form can create a huge number of PHIs
+ many of which may be thrown away shortly after their creation if jumps
+ were threaded through PHI nodes.
+
+ While our garbage collection mechanisms will handle this situation, it
+ is extremely wasteful to create nodes and throw them away, especially
+ when the nodes can be reused.
+
+ For PR 8361, we can significantly reduce the number of nodes allocated
+ and thus the total amount of memory allocated by managing PHIs a
+ little. This additionally helps reduce the amount of work done by the
+ garbage collector. Similar results have been seen on a wider variety
+ of tests (such as the compiler itself).
+
+ Right now we maintain our free list on a per-function basis. It may
+ or may not make sense to maintain the free list for the duration of
+ a compilation unit.
+
+ We could also use a zone allocator for these objects since they have
+ a very well defined lifetime. If someone wants to experiment with that
+ this is the place to try it.
+
+ PHI nodes have different sizes, so we can't have a single list of all
+ the PHI nodes as it would be too expensive to walk down that list to
+ find a PHI of a suitable size.
+
+ Instead we have an array of lists of free PHI nodes. The array is
+ indexed by the number of PHI alternatives that PHI node can hold.
+ Except for the last array member, which holds all remaining PHI
+ nodes.
+
+ So to find a free PHI node, we compute its index into the free PHI
+ node array and see if there are any elements with an exact match.
+ If so, then we are done. Otherwise, we test the next larger size
+ up and continue until we are in the last array element.
+
+ We do not actually walk members of the last array element. While it
+ might allow us to pick up a few reusable PHI nodes, it could potentially
+ be very expensive if the program has released a bunch of large PHI nodes,
+ but keeps asking for even larger PHI nodes. Experiments have shown that
+ walking the elements of the last array entry would result in finding less
+ than .1% additional reusable PHI nodes.
+
+ Note that we can never have less than two PHI argument slots. Thus,
+ the -2 on all the calculations below. */
+
+#define NUM_BUCKETS 10
+static GTY ((deletable (""))) tree free_phinodes[NUM_BUCKETS - 2];
+static unsigned long free_phinode_count;
+
+static int ideal_phi_node_len (int);
+static void resize_phi_node (tree *, int);
+
+#ifdef GATHER_STATISTICS
+unsigned int phi_nodes_reused;
+unsigned int phi_nodes_created;
+#endif
+
+/* Initialize management of PHIs. */
+
+void
+init_phinodes (void)
+{
+ int i;
+
+ for (i = 0; i < NUM_BUCKETS - 2; i++)
+ free_phinodes[i] = NULL;
+ free_phinode_count = 0;
+}
+
+/* Finalize management of PHIs. */
+
+void
+fini_phinodes (void)
+{
+ int i;
+
+ for (i = 0; i < NUM_BUCKETS - 2; i++)
+ free_phinodes[i] = NULL;
+ free_phinode_count = 0;
+}
+
+/* Dump some simple statistics regarding the re-use of PHI nodes. */
+
+#ifdef GATHER_STATISTICS
+void
+phinodes_print_statistics (void)
+{
+ fprintf (stderr, "PHI nodes allocated: %u\n", phi_nodes_created);
+ fprintf (stderr, "PHI nodes reused: %u\n", phi_nodes_reused);
+}
+#endif
+
+/* Given LEN, the original number of requested PHI arguments, return
+ a new, "ideal" length for the PHI node. The "ideal" length rounds
+ the total size of the PHI node up to the next power of two bytes.
+
+ Rounding up will not result in wasting any memory since the size request
+ will be rounded up by the GC system anyway. [ Note this is not entirely
+ true since the original length might have fit on one of the special
+ GC pages. ] By rounding up, we may avoid the need to reallocate the
+ PHI node later if we increase the number of arguments for the PHI. */
+
+static int
+ideal_phi_node_len (int len)
+{
+ size_t size, new_size;
+ int log2, new_len;
+
+ /* We do not support allocations of less than two PHI argument slots. */
+ if (len < 2)
+ len = 2;
+
+ /* Compute the number of bytes of the original request. */
+ size = sizeof (struct tree_phi_node) + (len - 1) * sizeof (struct phi_arg_d);
+
+ /* Round it up to the next power of two. */
+ log2 = ceil_log2 (size);
+ new_size = 1 << log2;
+
+ /* Now compute and return the number of PHI argument slots given an
+ ideal size allocation. */
+ new_len = len + (new_size - size) / sizeof (struct phi_arg_d);
+ return new_len;
+}
+
+/* Return a PHI node for variable VAR defined in statement STMT.
+ STMT may be an empty statement for artificial references (e.g., default
+ definitions created when a variable is used without a preceding
+ definition). */
+
+tree
+make_phi_node (tree var, int len)
+{
+ tree phi;
+ int size;
+ int bucket = NUM_BUCKETS - 2;
+
+ len = ideal_phi_node_len (len);
+
+ size = sizeof (struct tree_phi_node) + (len - 1) * sizeof (struct phi_arg_d);
+
+ if (free_phinode_count)
+ for (bucket = len - 2; bucket < NUM_BUCKETS - 2; bucket++)
+ if (free_phinodes[bucket])
+ break;
+
+ /* If our free list has an element, then use it. */
+ if (bucket < NUM_BUCKETS - 2
+ && PHI_ARG_CAPACITY (free_phinodes[bucket]) >= len)
+ {
+ free_phinode_count--;
+ phi = free_phinodes[bucket];
+ free_phinodes[bucket] = TREE_CHAIN (free_phinodes[bucket]);
+#ifdef GATHER_STATISTICS
+ phi_nodes_reused++;
+#endif
+ }
+ else
+ {
+ phi = ggc_alloc (size);
+#ifdef GATHER_STATISTICS
+ phi_nodes_created++;
+ tree_node_counts[(int) phi_kind]++;
+ tree_node_sizes[(int) phi_kind] += size;
+#endif
+
+ }
+
+ memset (phi, 0, size);
+ TREE_SET_CODE (phi, PHI_NODE);
+ PHI_ARG_CAPACITY (phi) = len;
+ if (TREE_CODE (var) == SSA_NAME)
+ PHI_RESULT (phi) = var;
+ else
+ PHI_RESULT (phi) = make_ssa_name (var, phi);
+
+ return phi;
+}
+
+/* We no longer need PHI, release it so that it may be reused. */
+
+void
+release_phi_node (tree phi)
+{
+ int bucket;
+ int len = PHI_ARG_CAPACITY (phi);
+
+ bucket = len > NUM_BUCKETS - 1 ? NUM_BUCKETS - 1 : len;
+ bucket -= 2;
+ TREE_CHAIN (phi) = free_phinodes[bucket];
+ free_phinodes[bucket] = phi;
+ free_phinode_count++;
+}
+
+/* Resize an existing PHI node. The only way is up. Return the
+ possibly relocated phi. */
+
+static void
+resize_phi_node (tree *phi, int len)
+{
+ int size, old_size;
+ tree new_phi;
+ int i, old_len, bucket = NUM_BUCKETS - 2;
+
+#ifdef ENABLE_CHECKING
+ if (len < PHI_ARG_CAPACITY (*phi))
+ abort ();
+#endif
+
+ /* Note that OLD_SIZE is guaranteed to be smaller than SIZE. */
+ old_size = (sizeof (struct tree_phi_node)
+ + (PHI_ARG_CAPACITY (*phi) - 1) * sizeof (struct phi_arg_d));
+ size = sizeof (struct tree_phi_node) + (len - 1) * sizeof (struct phi_arg_d);
+
+ if (free_phinode_count)
+ for (bucket = len - 2; bucket < NUM_BUCKETS - 2; bucket++)
+ if (free_phinodes[bucket])
+ break;
+
+ /* If our free list has an element, then use it. */
+ if (bucket < NUM_BUCKETS - 2
+ && PHI_ARG_CAPACITY (free_phinodes[bucket]) >= len)
+ {
+ free_phinode_count--;
+ new_phi = free_phinodes[bucket];
+ free_phinodes[bucket] = TREE_CHAIN (free_phinodes[bucket]);
+#ifdef GATHER_STATISTICS
+ phi_nodes_reused++;
+#endif
+ }
+ else
+ {
+ new_phi = ggc_alloc (size);
+#ifdef GATHER_STATISTICS
+ phi_nodes_created++;
+ tree_node_counts[(int) phi_kind]++;
+ tree_node_sizes[(int) phi_kind] += size;
+#endif
+ }
+
+ memcpy (new_phi, *phi, old_size);
+
+ old_len = PHI_ARG_CAPACITY (new_phi);
+ PHI_ARG_CAPACITY (new_phi) = len;
+
+ for (i = old_len; i < len; i++)
+ {
+ PHI_ARG_DEF (new_phi, i) = NULL_TREE;
+ PHI_ARG_EDGE (new_phi, i) = NULL;
+ }
+
+ *phi = new_phi;
+}
+
+/* Create a new PHI node for variable VAR at basic block BB. */
+
+tree
+create_phi_node (tree var, basic_block bb)
+{
+ tree phi;
+
+ phi = make_phi_node (var, bb_ann (bb)->num_preds);
+
+ /* This is a new phi node, so note that is has not yet been
+ rewritten. */
+ PHI_REWRITTEN (phi) = 0;
+
+ /* Add the new PHI node to the list of PHI nodes for block BB. */
+ TREE_CHAIN (phi) = phi_nodes (bb);
+ bb_ann (bb)->phi_nodes = phi;
+
+ /* Associate BB to the PHI node. */
+ set_bb_for_stmt (phi, bb);
+
+ return phi;
+}
+
+/* Add a new argument to PHI node PHI. DEF is the incoming reaching
+ definition and E is the edge through which DEF reaches PHI. The new
+ argument is added at the end of the argument list.
+ If PHI has reached its maximum capacity, add a few slots. In this case,
+ PHI points to the reallocated phi node when we return. */
+
+void
+add_phi_arg (tree *phi, tree def, edge e)
+{
+ int i = PHI_NUM_ARGS (*phi);
+
+ if (i >= PHI_ARG_CAPACITY (*phi))
+ {
+ tree old_phi = *phi;
+
+ /* Resize the phi. Unfortunately, this may also relocate it. */
+ resize_phi_node (phi, ideal_phi_node_len (i + 4));
+
+ /* The result of the phi is defined by this phi node. */
+ SSA_NAME_DEF_STMT (PHI_RESULT (*phi)) = *phi;
+
+ /* If the PHI was relocated, update the PHI chains appropriately and
+ release the old PHI node. */
+ if (*phi != old_phi)
+ {
+ release_phi_node (old_phi);
+
+ /* Update the list head if replacing the first listed phi. */
+ if (phi_nodes (e->dest) == old_phi)
+ bb_ann (e->dest)->phi_nodes = *phi;
+ else
+ {
+ /* Traverse the list looking for the phi node to chain to. */
+ tree p;
+
+ for (p = phi_nodes (e->dest);
+ p && TREE_CHAIN (p) != old_phi;
+ p = TREE_CHAIN (p))
+ ;
+
+ if (!p)
+ abort ();
+
+ TREE_CHAIN (p) = *phi;
+ }
+ }
+ }
+
+ /* Copy propagation needs to know what object occur in abnormal
+ PHI nodes. This is a convenient place to record such information. */
+ if (e->flags & EDGE_ABNORMAL)
+ {
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def) = 1;
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (*phi)) = 1;
+ }
+
+ PHI_ARG_DEF (*phi, i) = def;
+ PHI_ARG_EDGE (*phi, i) = e;
+ PHI_NUM_ARGS (*phi)++;
+}
+
+/* Remove a PHI argument from PHI. BLOCK is the predecessor block where
+ the PHI argument is coming from. */
+
+void
+remove_phi_arg (tree phi, basic_block block)
+{
+ int i, num_elem = PHI_NUM_ARGS (phi);
+
+ for (i = 0; i < num_elem; i++)
+ {
+ basic_block src_bb;
+
+ src_bb = PHI_ARG_EDGE (phi, i)->src;
+
+ if (src_bb == block)
+ {
+ remove_phi_arg_num (phi, i);
+ return;
+ }
+ }
+}
+
+
+/* Remove the Ith argument from PHI's argument list. This routine assumes
+ ordering of alternatives in the vector is not important and implements
+ removal by swapping the last alternative with the alternative we want to
+ delete, then shrinking the vector. */
+
+void
+remove_phi_arg_num (tree phi, int i)
+{
+ int num_elem = PHI_NUM_ARGS (phi);
+
+ /* If we are not at the last element, switch the last element
+ with the element we want to delete. */
+ if (i != num_elem - 1)
+ {
+ PHI_ARG_DEF (phi, i) = PHI_ARG_DEF (phi, num_elem - 1);
+ PHI_ARG_EDGE (phi, i) = PHI_ARG_EDGE (phi, num_elem - 1);
+ }
+
+ /* Shrink the vector and return. */
+ PHI_ARG_DEF (phi, num_elem - 1) = NULL_TREE;
+ PHI_ARG_EDGE (phi, num_elem - 1) = NULL;
+ PHI_NUM_ARGS (phi)--;
+
+ /* If we removed the last PHI argument, then go ahead and
+ remove the PHI node. */
+ if (PHI_NUM_ARGS (phi) == 0)
+ remove_phi_node (phi, NULL, bb_for_stmt (phi));
+}
+
+/* Remove PHI node PHI from basic block BB. If PREV is non-NULL, it is
+ used as the node immediately before PHI in the linked list. */
+
+void
+remove_phi_node (tree phi, tree prev, basic_block bb)
+{
+ if (prev)
+ {
+ /* Rewire the list if we are given a PREV pointer. */
+ TREE_CHAIN (prev) = TREE_CHAIN (phi);
+
+ /* If we are deleting the PHI node, then we should release the
+ SSA_NAME node so that it can be reused. */
+ release_ssa_name (PHI_RESULT (phi));
+ release_phi_node (phi);
+ }
+ else if (phi == phi_nodes (bb))
+ {
+ /* Update the list head if removing the first element. */
+ bb_ann (bb)->phi_nodes = TREE_CHAIN (phi);
+
+ /* If we are deleting the PHI node, then we should release the
+ SSA_NAME node so that it can be reused. */
+ release_ssa_name (PHI_RESULT (phi));
+ release_phi_node (phi);
+ }
+ else
+ {
+ /* Traverse the list looking for the node to remove. */
+ tree prev, t;
+ prev = NULL_TREE;
+ for (t = phi_nodes (bb); t && t != phi; t = TREE_CHAIN (t))
+ prev = t;
+ if (t)
+ remove_phi_node (t, prev, bb);
+ }
+}
+
+
+/* Remove all the PHI nodes for variables in the VARS bitmap. */
+
+void
+remove_all_phi_nodes_for (bitmap vars)
+{
+ basic_block bb;
+
+ FOR_EACH_BB (bb)
+ {
+ /* Build a new PHI list for BB without variables in VARS. */
+ tree phi, new_phi_list, last_phi, next;
+
+ last_phi = new_phi_list = NULL_TREE;
+ for (phi = phi_nodes (bb), next = NULL; phi; phi = next)
+ {
+ tree var = SSA_NAME_VAR (PHI_RESULT (phi));
+
+ next = TREE_CHAIN (phi);
+ /* Only add PHI nodes for variables not in VARS. */
+ if (!bitmap_bit_p (vars, var_ann (var)->uid))
+ {
+ /* If we're not removing this PHI node, then it must have
+ been rewritten by a previous call into the SSA rewriter.
+ Note that fact in PHI_REWRITTEN. */
+ PHI_REWRITTEN (phi) = 1;
+
+ if (new_phi_list == NULL_TREE)
+ new_phi_list = last_phi = phi;
+ else
+ {
+ TREE_CHAIN (last_phi) = phi;
+ last_phi = phi;
+ }
+ }
+ else
+ {
+ /* If we are deleting the PHI node, then we should release the
+ SSA_NAME node so that it can be reused. */
+ release_ssa_name (PHI_RESULT (phi));
+ release_phi_node (phi);
+ }
+ }
+
+ /* Make sure the last node in the new list has no successors. */
+ if (last_phi)
+ TREE_CHAIN (last_phi) = NULL_TREE;
+ bb_ann (bb)->phi_nodes = new_phi_list;
+
+#if defined ENABLE_CHECKING
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ tree var = SSA_NAME_VAR (PHI_RESULT (phi));
+ if (bitmap_bit_p (vars, var_ann (var)->uid))
+ abort ();
+ }
+#endif
+ }
+}
+
+
+#include "gt-tree-phinodes.h"
+
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
new file mode 100644
index 00000000000..7eea529f063
--- /dev/null
+++ b/gcc/tree-pretty-print.c
@@ -0,0 +1,2267 @@
+/* Pretty formatting of GENERIC trees in C syntax.
+ Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+ Adapted from c-pretty-print.c by Diego Novillo <dnovillo@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "errors.h"
+#include "tree.h"
+#include "diagnostic.h"
+#include "real.h"
+#include "hashtab.h"
+#include "tree-flow.h"
+#include "langhooks.h"
+#include "tree-iterator.h"
+
+/* Local functions, macros and variables. */
+static int op_prio (tree);
+static const char *op_symbol (tree);
+static void pretty_print_string (pretty_printer *, const char*);
+static void print_call_name (pretty_printer *, tree);
+static void newline_and_indent (pretty_printer *, int);
+static void maybe_init_pretty_print (FILE *);
+static void print_declaration (pretty_printer *, tree, int, int);
+static void print_struct_decl (pretty_printer *, tree, int, int);
+static void do_niy (pretty_printer *, tree);
+static void dump_vops (pretty_printer *, tree, int, int);
+static void dump_generic_bb_buff (pretty_printer *, basic_block, int, int);
+
+#define INDENT(SPACE) do { \
+ int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
+
+#define NIY do_niy(buffer,node)
+
+#define PRINT_FUNCTION_NAME(NODE) pp_printf \
+ (buffer, "%s", TREE_CODE (NODE) == NOP_EXPR ? \
+ (*lang_hooks.decl_printable_name) (TREE_OPERAND (NODE, 0), 1) : \
+ (*lang_hooks.decl_printable_name) (NODE, 1))
+
+#define MASK_POINTER(P) ((unsigned)((unsigned long)(P) & 0xffff))
+
+static pretty_printer buffer;
+static int initialized = 0;
+static bool dumping_stmts;
+
+/* Try to print something for an unknown tree code. */
+
+static void
+do_niy (pretty_printer *buffer, tree node)
+{
+ int i, len;
+
+ pp_string (buffer, "<<< Unknown tree: ");
+ pp_string (buffer, tree_code_name[(int) TREE_CODE (node)]);
+
+ if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (node))))
+ {
+ len = first_rtl_op (TREE_CODE (node));
+ for (i = 0; i < len; ++i)
+ {
+ newline_and_indent (buffer, 2);
+ dump_generic_node (buffer, TREE_OPERAND (node, i), 2, 0, false);
+ }
+ }
+
+ pp_string (buffer, " >>>\n");
+}
+
+void
+debug_generic_expr (tree t)
+{
+ print_generic_expr (stderr, t, TDF_VOPS|TDF_UID);
+ fprintf (stderr, "\n");
+}
+
+void
+debug_generic_stmt (tree t)
+{
+ print_generic_stmt (stderr, t, TDF_VOPS|TDF_UID);
+ fprintf (stderr, "\n");
+}
+
+/* Prints declaration DECL to the FILE with details specified by FLAGS. */
+void
+print_generic_decl (FILE *file, tree decl, int flags)
+{
+ maybe_init_pretty_print (file);
+ dumping_stmts = true;
+ print_declaration (&buffer, decl, 2, flags);
+ pp_write_text_to_stream (&buffer);
+}
+
+/* Print tree T, and its successors, on file FILE. FLAGS specifies details
+ to show in the dump. See TDF_* in tree.h. */
+
+void
+print_generic_stmt (FILE *file, tree t, int flags)
+{
+ maybe_init_pretty_print (file);
+ dumping_stmts = true;
+ dump_generic_node (&buffer, t, 0, flags, true);
+ pp_flush (&buffer);
+}
+
+/* Print tree T, and its successors, on file FILE. FLAGS specifies details
+ to show in the dump. See TDF_* in tree.h. The output is indented by
+ INDENT spaces. */
+
+void
+print_generic_stmt_indented (FILE *file, tree t, int flags, int indent)
+{
+ int i;
+
+ maybe_init_pretty_print (file);
+ dumping_stmts = true;
+
+ for (i = 0; i < indent; i++)
+ pp_space (&buffer);
+ dump_generic_node (&buffer, t, indent, flags, true);
+ pp_flush (&buffer);
+}
+
+/* Print a single expression T on file FILE. FLAGS specifies details to show
+ in the dump. See TDF_* in tree.h. */
+
+void
+print_generic_expr (FILE *file, tree t, int flags)
+{
+ maybe_init_pretty_print (file);
+ dumping_stmts = false;
+ dump_generic_node (&buffer, t, 0, flags, false);
+}
+
+/* Dump the name of a _DECL node and its DECL_UID if TDF_UID is set
+ in FLAGS. */
+
+static void
+dump_decl_name (pretty_printer *buffer, tree node, int flags)
+{
+ if (DECL_NAME (node))
+ pp_tree_identifier (buffer, DECL_NAME (node));
+
+ if ((flags & TDF_UID)
+ || DECL_NAME (node) == NULL_TREE)
+ {
+ if (TREE_CODE (node) == LABEL_DECL
+ && LABEL_DECL_UID (node) != -1)
+ pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
+ LABEL_DECL_UID (node));
+ else
+ pp_printf (buffer, "<D%u>", DECL_UID (node));
+ }
+}
+
+/* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of indent.
+ FLAGS specifies details to show in the dump (see TDF_* in tree.h). If
+ IS_STMT is true, the object printed is considered to be a statement
+ and it is terminated by ';' if appropriate. */
+
+int
+dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
+ bool is_stmt)
+{
+ tree type;
+ tree op0, op1;
+ const char* str;
+ bool is_expr;
+
+ if (node == NULL_TREE)
+ return spc;
+
+ is_expr = EXPR_P (node);
+
+ if (TREE_CODE (node) != ERROR_MARK
+ && is_gimple_stmt (node)
+ && (flags & TDF_VOPS)
+ && stmt_ann (node))
+ dump_vops (buffer, node, spc, flags);
+
+ if (dumping_stmts
+ && (flags & TDF_LINENO)
+ && EXPR_HAS_LOCATION (node))
+ {
+ pp_character (buffer, '[');
+ if (EXPR_FILENAME (node))
+ {
+ pp_string (buffer, EXPR_FILENAME (node));
+ pp_string (buffer, " : ");
+ }
+ pp_decimal_int (buffer, EXPR_LINENO (node));
+ pp_string (buffer, "] ");
+ }
+
+ switch (TREE_CODE (node))
+ {
+ case ERROR_MARK:
+ pp_string (buffer, "<<< error >>>");
+ break;
+
+ case IDENTIFIER_NODE:
+ pp_tree_identifier (buffer, node);
+ break;
+
+ case TREE_LIST:
+ while (node && node != error_mark_node)
+ {
+ if (TREE_PURPOSE (node))
+ {
+ dump_generic_node (buffer, TREE_PURPOSE (node), spc, flags, false);
+ pp_space (buffer);
+ }
+ dump_generic_node (buffer, TREE_VALUE (node), spc, flags, false);
+ node = TREE_CHAIN (node);
+ if (node && TREE_CODE (node) == TREE_LIST)
+ {
+ pp_character (buffer, ',');
+ pp_space (buffer);
+ }
+ }
+ break;
+
+ case TREE_VEC:
+ dump_generic_node (buffer, BINFO_TYPE (node), spc, flags, false);
+ break;
+
+ case BLOCK:
+ NIY;
+ break;
+
+ case VOID_TYPE:
+ case INTEGER_TYPE:
+ case REAL_TYPE:
+ case COMPLEX_TYPE:
+ case VECTOR_TYPE:
+ case ENUMERAL_TYPE:
+ case BOOLEAN_TYPE:
+ case CHAR_TYPE:
+ {
+ unsigned int quals = TYPE_QUALS (node);
+ char class;
+
+ if (quals & TYPE_QUAL_CONST)
+ pp_string (buffer, "const ");
+ else if (quals & TYPE_QUAL_VOLATILE)
+ pp_string (buffer, "volatile ");
+ else if (quals & TYPE_QUAL_RESTRICT)
+ pp_string (buffer, "restrict ");
+
+ class = TREE_CODE_CLASS (TREE_CODE (node));
+
+ if (class == 'd')
+ {
+ if (DECL_NAME (node))
+ dump_decl_name (buffer, node, flags);
+ else
+ pp_string (buffer, "<unnamed type decl>");
+ }
+ else if (class == 't')
+ {
+ if (TYPE_NAME (node))
+ {
+ if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
+ pp_tree_identifier (buffer, TYPE_NAME (node));
+ else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
+ && DECL_NAME (TYPE_NAME (node)))
+ dump_decl_name (buffer, TYPE_NAME (node), flags);
+ else
+ pp_string (buffer, "<unnamed type>");
+ }
+ else
+ pp_string (buffer, "<unnamed type>");
+ }
+ break;
+ }
+
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&");
+
+ if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
+ {
+ tree fnode = TREE_TYPE (node);
+ dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
+ pp_space (buffer);
+ pp_character (buffer, '(');
+ pp_string (buffer, str);
+ if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
+ dump_decl_name (buffer, TYPE_NAME (node), flags);
+ else
+ pp_printf (buffer, "<T%x>", TYPE_UID (node));
+
+ pp_character (buffer, ')');
+ pp_space (buffer);
+ pp_character (buffer, '(');
+ /* Print the argument types. The last element in the list is a
+ VOID_TYPE. The following avoid to print the last element. */
+ {
+ tree tmp = TYPE_ARG_TYPES (fnode);
+ while (tmp && TREE_CHAIN (tmp) && tmp != error_mark_node)
+ {
+ dump_generic_node (buffer, TREE_VALUE (tmp), spc, flags, false);
+ tmp = TREE_CHAIN (tmp);
+ if (TREE_CHAIN (tmp) && TREE_CODE (TREE_CHAIN (tmp)) == TREE_LIST)
+ {
+ pp_character (buffer, ',');
+ pp_space (buffer);
+ }
+ }
+ }
+ pp_character (buffer, ')');
+ }
+ else
+ {
+ unsigned int quals = TYPE_QUALS (node);
+
+ dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
+ pp_space (buffer);
+ pp_string (buffer, str);
+
+ if (quals & TYPE_QUAL_CONST)
+ pp_string (buffer, " const");
+ else if (quals & TYPE_QUAL_VOLATILE)
+ pp_string (buffer, "volatile");
+ else if (quals & TYPE_QUAL_RESTRICT)
+ pp_string (buffer, " restrict");
+ }
+ break;
+
+ case OFFSET_TYPE:
+ NIY;
+ break;
+
+ case METHOD_TYPE:
+ dump_decl_name (buffer, TYPE_NAME (TYPE_METHOD_BASETYPE (node)), flags);
+ pp_string (buffer, "::");
+ break;
+
+ case FILE_TYPE:
+ NIY;
+ break;
+
+ case ARRAY_TYPE:
+ {
+ tree tmp;
+
+ /* Print the array type. */
+ dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
+
+ /* Print the dimensions. */
+ tmp = node;
+ while (tmp && TREE_CODE (tmp) == ARRAY_TYPE)
+ {
+ pp_character (buffer, '[');
+ if (TYPE_SIZE (tmp))
+ {
+ tree size = TYPE_SIZE (tmp);
+ if (TREE_CODE (size) == INTEGER_CST)
+ pp_wide_integer (buffer,
+ TREE_INT_CST_LOW (TYPE_SIZE (tmp)) /
+ TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tmp))));
+ else if (TREE_CODE (size) == MULT_EXPR)
+ dump_generic_node (buffer, TREE_OPERAND (size, 0), spc, flags, false);
+ /* else punt. */
+ }
+ pp_character (buffer, ']');
+ tmp = TREE_TYPE (tmp);
+ }
+ break;
+ }
+
+ case SET_TYPE:
+ NIY;
+ break;
+
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ /* Print the name of the structure. */
+ if (TREE_CODE (node) == RECORD_TYPE)
+ pp_string (buffer, "struct ");
+ else if (TREE_CODE (node) == UNION_TYPE)
+ pp_string (buffer, "union ");
+
+ if (TYPE_NAME (node))
+ dump_generic_node (buffer, TYPE_NAME (node), spc, flags, false);
+ else
+ print_struct_decl (buffer, node, spc, flags);
+ break;
+
+ case QUAL_UNION_TYPE:
+ NIY;
+ break;
+
+
+ case LANG_TYPE:
+ NIY;
+ break;
+
+ case INTEGER_CST:
+ if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
+ {
+ /* In the case of a pointer, one may want to divide by the
+ size of the pointed-to type. Unfortunately, this not
+ straightforward. The C front-end maps expressions
+
+ (int *) 5
+ int *p; (p + 5)
+
+ in such a way that the two INTEGER_CST nodes for "5" have
+ different values but identical types. In the latter
+ case, the 5 is multiplied by sizeof (int) in c-common.c
+ (pointer_int_sum) to convert it to a byte address, and
+ yet the type of the node is left unchanged. Argh. What
+ is consistent though is that the number value corresponds
+ to bytes (UNITS) offset.
+
+ NB: Neither of the following divisors can be trivially
+ used to recover the original literal:
+
+ TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
+ TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node))) */
+ pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
+ pp_string (buffer, "B"); /* pseudo-unit */
+ }
+ else if (! host_integerp (node, 0))
+ {
+ tree val = node;
+
+ if (tree_int_cst_sgn (val) < 0)
+ {
+ pp_character (buffer, '-');
+ val = build_int_2 (-TREE_INT_CST_LOW (val),
+ ~TREE_INT_CST_HIGH (val)
+ + !TREE_INT_CST_LOW (val));
+ }
+ /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
+ systems? */
+ {
+ static char format[10]; /* "%x%09999x\0" */
+ if (!format[0])
+ sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
+ sprintf (pp_buffer (buffer)->digit_buffer, format,
+ TREE_INT_CST_HIGH (val),
+ TREE_INT_CST_LOW (val));
+ pp_string (buffer, pp_buffer (buffer)->digit_buffer);
+ }
+ }
+ else
+ pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
+ break;
+
+ case REAL_CST:
+ /* Code copied from print_node. */
+ {
+ REAL_VALUE_TYPE d;
+ if (TREE_OVERFLOW (node))
+ pp_string (buffer, " overflow");
+
+#if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
+ d = TREE_REAL_CST (node);
+ if (REAL_VALUE_ISINF (d))
+ pp_string (buffer, " Inf");
+ else if (REAL_VALUE_ISNAN (d))
+ pp_string (buffer, " Nan");
+ else
+ {
+ char string[100];
+ real_to_decimal (string, &d, sizeof (string), 0, 1);
+ pp_string (buffer, string);
+ }
+#else
+ {
+ HOST_WIDE_INT i;
+ unsigned char *p = (unsigned char *) &TREE_REAL_CST (node);
+ pp_string (buffer, "0x");
+ for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
+ output_formatted_integer (buffer, "%02x", *p++);
+ }
+#endif
+ break;
+ }
+
+ case COMPLEX_CST:
+ pp_string (buffer, "__complex__ (");
+ dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
+ pp_string (buffer, ", ");
+ dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
+ pp_string (buffer, ")");
+ break;
+
+ case STRING_CST:
+ pp_string (buffer, "\"");
+ pretty_print_string (buffer, TREE_STRING_POINTER (node));
+ pp_string (buffer, "\"");
+ break;
+
+ case VECTOR_CST:
+ {
+ tree elt;
+ pp_string (buffer, "{ ");
+ for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
+ {
+ dump_generic_node (buffer, TREE_VALUE (elt), spc, flags, false);
+ if (TREE_CHAIN (elt))
+ pp_string (buffer, ", ");
+ }
+ pp_string (buffer, " }");
+ }
+ break;
+
+ case FUNCTION_TYPE:
+ break;
+
+ case FUNCTION_DECL:
+ case CONST_DECL:
+ dump_decl_name (buffer, node, flags);
+ break;
+
+ case LABEL_DECL:
+ if (DECL_NAME (node))
+ dump_decl_name (buffer, node, flags);
+ else if (LABEL_DECL_UID (node) != -1)
+ pp_printf (buffer, "<L" HOST_WIDE_INT_PRINT_DEC ">",
+ LABEL_DECL_UID (node));
+ else
+ pp_printf (buffer, "<D%u>", DECL_UID (node));
+ break;
+
+ case TYPE_DECL:
+ if (strcmp (DECL_SOURCE_FILE (node), "<built-in>") == 0)
+ {
+ /* Don't print the declaration of built-in types. */
+ break;
+ }
+ if (DECL_NAME (node))
+ {
+ dump_decl_name (buffer, node, flags);
+ }
+ else
+ {
+ if (TYPE_METHODS (TREE_TYPE (node)))
+ {
+ /* The type is a c++ class: all structures have at least
+ 4 methods. */
+ pp_string (buffer, "class ");
+ dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
+ }
+ else
+ {
+ pp_string (buffer, "struct ");
+ dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
+ pp_character (buffer, ';');
+ pp_newline (buffer);
+ }
+ }
+ break;
+
+ case VAR_DECL:
+ case PARM_DECL:
+ case FIELD_DECL:
+ case NAMESPACE_DECL:
+ dump_decl_name (buffer, node, flags);
+ break;
+
+ case RESULT_DECL:
+ pp_string (buffer, "<retval>");
+ break;
+
+ case COMPONENT_REF:
+ op0 = TREE_OPERAND (node, 0);
+ str = ".";
+ if (TREE_CODE (op0) == INDIRECT_REF)
+ {
+ op0 = TREE_OPERAND (op0, 0);
+ str = "->";
+ }
+ if (op_prio (op0) < op_prio (node))
+ pp_character (buffer, '(');
+ dump_generic_node (buffer, op0, spc, flags, false);
+ if (op_prio (op0) < op_prio (node))
+ pp_character (buffer, ')');
+ pp_string (buffer, str);
+ dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+ break;
+
+ case BIT_FIELD_REF:
+ pp_string (buffer, "BIT_FIELD_REF <");
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+ pp_string (buffer, ", ");
+ dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+ pp_string (buffer, ", ");
+ dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
+ pp_string (buffer, ">");
+ break;
+
+ case BUFFER_REF:
+ NIY;
+ break;
+
+ case ARRAY_REF:
+ op0 = TREE_OPERAND (node, 0);
+ if (op_prio (op0) < op_prio (node))
+ pp_character (buffer, '(');
+ dump_generic_node (buffer, op0, spc, flags, false);
+ if (op_prio (op0) < op_prio (node))
+ pp_character (buffer, ')');
+ pp_character (buffer, '[');
+ dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+ pp_character (buffer, ']');
+ break;
+
+ case ARRAY_RANGE_REF:
+ NIY;
+ break;
+
+ case CONSTRUCTOR:
+ {
+ tree lnode;
+ bool is_struct_init = FALSE;
+ pp_character (buffer, '{');
+ lnode = CONSTRUCTOR_ELTS (node);
+ if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
+ || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
+ is_struct_init = TRUE;
+ while (lnode && lnode != error_mark_node)
+ {
+ tree val;
+ if (TREE_PURPOSE (lnode) && is_struct_init)
+ {
+ pp_character (buffer, '.');
+ dump_generic_node (buffer, TREE_PURPOSE (lnode), spc, flags, false);
+ pp_string (buffer, "=");
+ }
+ val = TREE_VALUE (lnode);
+ if (val && TREE_CODE (val) == ADDR_EXPR)
+ if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
+ val = TREE_OPERAND (val, 0);
+ if (val && TREE_CODE (val) == FUNCTION_DECL)
+ {
+ dump_decl_name (buffer, val, flags);
+ }
+ else
+ {
+ dump_generic_node (buffer, TREE_VALUE (lnode), spc, flags, false);
+ }
+ lnode = TREE_CHAIN (lnode);
+ if (lnode && TREE_CODE (lnode) == TREE_LIST)
+ {
+ pp_character (buffer, ',');
+ pp_space (buffer);
+ }
+ }
+ pp_character (buffer, '}');
+ }
+ break;
+
+ case COMPOUND_EXPR:
+ {
+ tree *tp;
+ if (flags & TDF_SLIM)
+ {
+ pp_string (buffer, "<COMPOUND_EXPR>");
+ break;
+ }
+
+ dump_generic_node (buffer, TREE_OPERAND (node, 0),
+ spc, flags, dumping_stmts);
+ if (dumping_stmts)
+ newline_and_indent (buffer, spc);
+ else
+ {
+ pp_character (buffer, ',');
+ pp_space (buffer);
+ }
+
+ for (tp = &TREE_OPERAND (node, 1);
+ TREE_CODE (*tp) == COMPOUND_EXPR;
+ tp = &TREE_OPERAND (*tp, 1))
+ {
+ dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
+ spc, flags, dumping_stmts);
+ if (dumping_stmts)
+ newline_and_indent (buffer, spc);
+ else
+ {
+ pp_character (buffer, ',');
+ pp_space (buffer);
+ }
+ }
+
+ dump_generic_node (buffer, *tp, spc, flags, dumping_stmts);
+ }
+ break;
+
+ case STATEMENT_LIST:
+ {
+ tree_stmt_iterator si;
+ bool first = true;
+
+ if ((flags & TDF_SLIM) || !dumping_stmts)
+ {
+ pp_string (buffer, "<STATEMENT_LIST>");
+ break;
+ }
+
+ for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
+ {
+ if (!first)
+ newline_and_indent (buffer, spc);
+ else
+ first = false;
+ dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
+ }
+ }
+ break;
+
+ case MODIFY_EXPR:
+ case INIT_EXPR:
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+ pp_space (buffer);
+ pp_character (buffer, '=');
+ pp_space (buffer);
+ dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+ break;
+
+ case TARGET_EXPR:
+ dump_generic_node (buffer, TYPE_NAME (TREE_TYPE (node)), spc, flags, false);
+ pp_character (buffer, '(');
+ dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
+ pp_character (buffer, ')');
+ break;
+
+ case COND_EXPR:
+ if (TREE_TYPE (node) == void_type_node)
+ {
+ pp_string (buffer, "if (");
+ dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
+ pp_character (buffer, ')');
+ /* The lowered cond_exprs should always be printed in full. */
+ if (COND_EXPR_THEN (node)
+ && TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR
+ && COND_EXPR_ELSE (node)
+ && TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR)
+ {
+ pp_space (buffer);
+ dump_generic_node (buffer, COND_EXPR_THEN (node), 0, flags, true);
+ pp_string (buffer, " else ");
+ dump_generic_node (buffer, COND_EXPR_ELSE (node), 0, flags, true);
+ }
+ else if (!(flags & TDF_SLIM))
+ {
+ /* Output COND_EXPR_THEN. */
+ if (COND_EXPR_THEN (node))
+ {
+ newline_and_indent (buffer, spc+2);
+ pp_character (buffer, '{');
+ newline_and_indent (buffer, spc+4);
+ dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
+ flags, true);
+ newline_and_indent (buffer, spc+2);
+ pp_character (buffer, '}');
+ }
+
+ /* Output COND_EXPR_ELSE. */
+ if (COND_EXPR_ELSE (node))
+ {
+ newline_and_indent (buffer, spc);
+ pp_string (buffer, "else");
+ newline_and_indent (buffer, spc+2);
+ pp_character (buffer, '{');
+ newline_and_indent (buffer, spc+4);
+ dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
+ flags, true);
+ newline_and_indent (buffer, spc+2);
+ pp_character (buffer, '}');
+ }
+ }
+ is_expr = false;
+ }
+ else
+ {
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+ pp_space (buffer);
+ pp_character (buffer, '?');
+ pp_space (buffer);
+ dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+ pp_space (buffer);
+ pp_character (buffer, ':');
+ pp_space (buffer);
+ dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
+ }
+ break;
+
+ case BIND_EXPR:
+ pp_character (buffer, '{');
+ if (!(flags & TDF_SLIM))
+ {
+ if (BIND_EXPR_VARS (node))
+ {
+ pp_newline (buffer);
+
+ for (op0 = BIND_EXPR_VARS (node); op0; op0 = TREE_CHAIN (op0))
+ {
+ print_declaration (buffer, op0, spc+2, flags);
+ pp_newline (buffer);
+ }
+ }
+
+ newline_and_indent (buffer, spc+2);
+ dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
+ newline_and_indent (buffer, spc);
+ pp_character (buffer, '}');
+ }
+ is_expr = false;
+ break;
+
+ case CALL_EXPR:
+ print_call_name (buffer, node);
+
+ /* Print parameters. */
+ pp_space (buffer);
+ pp_character (buffer, '(');
+ op1 = TREE_OPERAND (node, 1);
+ if (op1)
+ dump_generic_node (buffer, op1, spc, flags, false);
+ pp_character (buffer, ')');
+
+ op1 = TREE_OPERAND (node, 2);
+ if (op1)
+ {
+ pp_string (buffer, " [static-chain: ");
+ dump_generic_node (buffer, op1, spc, flags, false);
+ pp_character (buffer, ']');
+ }
+
+ if (CALL_EXPR_TAILCALL (node))
+ pp_string (buffer, " [tail call]");
+ break;
+
+ case WITH_CLEANUP_EXPR:
+ NIY;
+ break;
+
+ case CLEANUP_POINT_EXPR:
+ pp_string (buffer, "<<cleanup_point ");
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+ pp_string (buffer, ">>");
+ break;
+
+ case PLACEHOLDER_EXPR:
+ NIY;
+ break;
+
+ /* Binary arithmetic and logic expressions. */
+ case MULT_EXPR:
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case TRUNC_MOD_EXPR:
+ case CEIL_MOD_EXPR:
+ case FLOOR_MOD_EXPR:
+ case ROUND_MOD_EXPR:
+ case RDIV_EXPR:
+ case EXACT_DIV_EXPR:
+ case LSHIFT_EXPR:
+ case RSHIFT_EXPR:
+ case LROTATE_EXPR:
+ case RROTATE_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ case BIT_AND_EXPR:
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_ORIF_EXPR:
+ case TRUTH_AND_EXPR:
+ case TRUTH_OR_EXPR:
+ case TRUTH_XOR_EXPR:
+ case LT_EXPR:
+ case LE_EXPR:
+ case GT_EXPR:
+ case GE_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ case UNLT_EXPR:
+ case UNLE_EXPR:
+ case UNGT_EXPR:
+ case UNGE_EXPR:
+ case UNEQ_EXPR:
+ {
+ const char *op = op_symbol (node);
+ op0 = TREE_OPERAND (node, 0);
+ op1 = TREE_OPERAND (node, 1);
+
+ /* When the operands are expressions with less priority,
+ keep semantics of the tree representation. */
+ if (op_prio (op0) < op_prio (node))
+ {
+ pp_character (buffer, '(');
+ dump_generic_node (buffer, op0, spc, flags, false);
+ pp_character (buffer, ')');
+ }
+ else
+ dump_generic_node (buffer, op0, spc, flags, false);
+
+ pp_space (buffer);
+ pp_string (buffer, op);
+ pp_space (buffer);
+
+ /* When the operands are expressions with less priority,
+ keep semantics of the tree representation. */
+ if (op_prio (op1) < op_prio (node))
+ {
+ pp_character (buffer, '(');
+ dump_generic_node (buffer, op1, spc, flags, false);
+ pp_character (buffer, ')');
+ }
+ else
+ dump_generic_node (buffer, op1, spc, flags, false);
+ }
+ break;
+
+ /* Unary arithmetic and logic expressions. */
+ case NEGATE_EXPR:
+ case BIT_NOT_EXPR:
+ case TRUTH_NOT_EXPR:
+ case ADDR_EXPR:
+ case REFERENCE_EXPR:
+ case PREDECREMENT_EXPR:
+ case PREINCREMENT_EXPR:
+ case INDIRECT_REF:
+ if (TREE_CODE (node) == ADDR_EXPR
+ && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
+ || TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
+ ; /* Do not output '&' for strings and function pointers. */
+ else
+ pp_string (buffer, op_symbol (node));
+
+ if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
+ {
+ pp_character (buffer, '(');
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+ pp_character (buffer, ')');
+ }
+ else
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+ break;
+
+ case POSTDECREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
+ {
+ pp_character (buffer, '(');
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+ pp_character (buffer, ')');
+ }
+ else
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+ pp_string (buffer, op_symbol (node));
+ break;
+
+ case MIN_EXPR:
+ pp_string (buffer, "MIN_EXPR <");
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+ pp_string (buffer, ", ");
+ dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+ pp_character (buffer, '>');
+ break;
+
+ case MAX_EXPR:
+ pp_string (buffer, "MAX_EXPR <");
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+ pp_string (buffer, ", ");
+ dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+ pp_character (buffer, '>');
+ break;
+
+ case ABS_EXPR:
+ pp_string (buffer, "ABS_EXPR <");
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+ pp_character (buffer, '>');
+ break;
+
+ case UNORDERED_EXPR:
+ NIY;
+ break;
+
+ case ORDERED_EXPR:
+ NIY;
+ break;
+
+ case IN_EXPR:
+ NIY;
+ break;
+
+ case SET_LE_EXPR:
+ NIY;
+ break;
+
+ case CARD_EXPR:
+ NIY;
+ break;
+
+ case RANGE_EXPR:
+ NIY;
+ break;
+
+ case FIX_TRUNC_EXPR:
+ case FIX_CEIL_EXPR:
+ case FIX_FLOOR_EXPR:
+ case FIX_ROUND_EXPR:
+ case FLOAT_EXPR:
+ case CONVERT_EXPR:
+ case NOP_EXPR:
+ type = TREE_TYPE (node);
+ op0 = TREE_OPERAND (node, 0);
+ if (type != TREE_TYPE (op0))
+ {
+ pp_character (buffer, '(');
+ dump_generic_node (buffer, type, spc, flags, false);
+ pp_string (buffer, ")");
+ }
+ if (op_prio (op0) < op_prio (node))
+ pp_character (buffer, '(');
+ dump_generic_node (buffer, op0, spc, flags, false);
+ if (op_prio (op0) < op_prio (node))
+ pp_character (buffer, ')');
+ break;
+
+ case VIEW_CONVERT_EXPR:
+ pp_string (buffer, "VIEW_CONVERT_EXPR<");
+ dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
+ pp_string (buffer, ">(");
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+ pp_character (buffer, ')');
+ break;
+
+ case NON_LVALUE_EXPR:
+ pp_string (buffer, "NON_LVALUE_EXPR <");
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+ pp_character (buffer, '>');
+ break;
+
+ case SAVE_EXPR:
+ pp_string (buffer, "SAVE_EXPR <");
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+ pp_character (buffer, '>');
+ break;
+
+ case UNSAVE_EXPR:
+ pp_string (buffer, "UNSAVE_EXPR <");
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+ pp_character (buffer, '>');
+ break;
+
+ case RTL_EXPR:
+ NIY;
+ break;
+
+ case ENTRY_VALUE_EXPR:
+ NIY;
+ break;
+
+ case COMPLEX_EXPR:
+ pp_string (buffer, "COMPLEX_EXPR <");
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+ pp_string (buffer, ", ");
+ dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+ pp_string (buffer, ">");
+ break;
+
+ case CONJ_EXPR:
+ pp_string (buffer, "CONJ_EXPR <");
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+ pp_string (buffer, ">");
+ break;
+
+ case REALPART_EXPR:
+ pp_string (buffer, "REALPART_EXPR <");
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+ pp_string (buffer, ">");
+ break;
+
+ case IMAGPART_EXPR:
+ pp_string (buffer, "IMAGPART_EXPR <");
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+ pp_string (buffer, ">");
+ break;
+
+ case VA_ARG_EXPR:
+ pp_string (buffer, "VA_ARG_EXPR <");
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+ pp_string (buffer, ">");
+ break;
+
+ case TRY_FINALLY_EXPR:
+ case TRY_CATCH_EXPR:
+ pp_string (buffer, "try");
+ newline_and_indent (buffer, spc+2);
+ pp_string (buffer, "{");
+ newline_and_indent (buffer, spc+4);
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
+ newline_and_indent (buffer, spc+2);
+ pp_string (buffer, "}");
+ newline_and_indent (buffer, spc);
+ pp_string (buffer,
+ (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
+ newline_and_indent (buffer, spc+2);
+ pp_string (buffer, "{");
+ newline_and_indent (buffer, spc+4);
+ dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
+ newline_and_indent (buffer, spc+2);
+ pp_string (buffer, "}");
+ is_expr = false;
+ break;
+
+ case CATCH_EXPR:
+ pp_string (buffer, "catch (");
+ dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
+ pp_string (buffer, ")");
+ newline_and_indent (buffer, spc+2);
+ pp_string (buffer, "{");
+ newline_and_indent (buffer, spc+4);
+ dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
+ newline_and_indent (buffer, spc+2);
+ pp_string (buffer, "}");
+ is_expr = false;
+ break;
+
+ case EH_FILTER_EXPR:
+ pp_string (buffer, "<<<eh_filter (");
+ dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
+ pp_string (buffer, ")>>>");
+ newline_and_indent (buffer, spc+2);
+ pp_string (buffer, "{");
+ newline_and_indent (buffer, spc+4);
+ dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
+ newline_and_indent (buffer, spc+2);
+ pp_string (buffer, "}");
+ is_expr = false;
+ break;
+
+ case GOTO_SUBROUTINE_EXPR:
+ NIY;
+ break;
+
+ case LABEL_EXPR:
+ op0 = TREE_OPERAND (node, 0);
+ /* If this is for break or continue, don't bother printing it. */
+ if (DECL_NAME (op0))
+ {
+ const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
+ if (strcmp (name, "break") == 0
+ || strcmp (name, "continue") == 0)
+ break;
+ }
+ dump_generic_node (buffer, op0, spc, flags, false);
+ pp_character (buffer, ':');
+ if (DECL_NONLOCAL (op0))
+ pp_string (buffer, " [non-local]");
+ break;
+
+ case LABELED_BLOCK_EXPR:
+ op0 = LABELED_BLOCK_LABEL (node);
+ /* If this is for break or continue, don't bother printing it. */
+ if (DECL_NAME (op0))
+ {
+ const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
+ if (strcmp (name, "break") == 0
+ || strcmp (name, "continue") == 0)
+ {
+ dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc, flags, false);
+ break;
+ }
+ }
+ dump_generic_node (buffer, LABELED_BLOCK_LABEL (node), spc, flags, false);
+ pp_string (buffer, ": {");
+ if (!(flags & TDF_SLIM))
+ newline_and_indent (buffer, spc+2);
+ dump_generic_node (buffer, LABELED_BLOCK_BODY (node), spc+2, flags, true);
+ if (!flags)
+ newline_and_indent (buffer, spc);
+ pp_character (buffer, '}');
+ is_expr = false;
+ break;
+
+ case EXIT_BLOCK_EXPR:
+ op0 = LABELED_BLOCK_LABEL (EXIT_BLOCK_LABELED_BLOCK (node));
+ /* If this is for a break or continue, print it accordingly. */
+ if (DECL_NAME (op0))
+ {
+ const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
+ if (strcmp (name, "break") == 0
+ || strcmp (name, "continue") == 0)
+ {
+ pp_string (buffer, name);
+ break;
+ }
+ }
+ pp_string (buffer, "<<<exit block ");
+ dump_generic_node (buffer, op0, spc, flags, false);
+ pp_string (buffer, ">>>");
+ break;
+
+ case EXC_PTR_EXPR:
+ pp_string (buffer, "<<<exception object>>>");
+ break;
+
+ case FILTER_EXPR:
+ pp_string (buffer, "<<<filter object>>>");
+ break;
+
+ case LOOP_EXPR:
+ pp_string (buffer, "while (1)");
+ if (!(flags & TDF_SLIM))
+ {
+ newline_and_indent (buffer, spc+2);
+ pp_character (buffer, '{');
+ newline_and_indent (buffer, spc+4);
+ dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
+ newline_and_indent (buffer, spc+2);
+ pp_character (buffer, '}');
+ }
+ is_expr = false;
+ break;
+
+ case RETURN_EXPR:
+ pp_string (buffer, "return");
+ op0 = TREE_OPERAND (node, 0);
+ if (op0)
+ {
+ pp_space (buffer);
+ if (TREE_CODE (op0) == MODIFY_EXPR)
+ dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, flags, false);
+ else
+ dump_generic_node (buffer, op0, spc, flags, false);
+ }
+ break;
+
+ case EXIT_EXPR:
+ pp_string (buffer, "if (");
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+ pp_string (buffer, ") break");
+ break;
+
+ case SWITCH_EXPR:
+ pp_string (buffer, "switch (");
+ dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
+ pp_character (buffer, ')');
+ if (!(flags & TDF_SLIM))
+ {
+ newline_and_indent (buffer, spc+2);
+ pp_character (buffer, '{');
+ if (SWITCH_BODY (node))
+ {
+ newline_and_indent (buffer, spc+4);
+ dump_generic_node (buffer, SWITCH_BODY (node), spc+4, flags, true);
+ }
+ else
+ {
+ tree vec = SWITCH_LABELS (node);
+ size_t i, n = TREE_VEC_LENGTH (vec);
+ for (i = 0; i < n; ++i)
+ {
+ tree elt = TREE_VEC_ELT (vec, i);
+ newline_and_indent (buffer, spc+4);
+ dump_generic_node (buffer, elt, spc+4, flags, false);
+ pp_string (buffer, " goto ");
+ dump_generic_node (buffer, CASE_LABEL (elt), spc+4, flags, true);
+ pp_semicolon (buffer);
+ }
+ }
+ newline_and_indent (buffer, spc+2);
+ pp_character (buffer, '}');
+ }
+ is_expr = false;
+ break;
+
+ case GOTO_EXPR:
+ op0 = GOTO_DESTINATION (node);
+ if (TREE_CODE (op0) != SSA_NAME
+ && DECL_P (op0)
+ && DECL_NAME (op0))
+ {
+ const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
+ if (strcmp (name, "break") == 0
+ || strcmp (name, "continue") == 0)
+ {
+ pp_string (buffer, name);
+ break;
+ }
+ }
+ pp_string (buffer, "goto ");
+ dump_generic_node (buffer, op0, spc, flags, false);
+ break;
+
+ case RESX_EXPR:
+ pp_string (buffer, "resx");
+ /* ??? Any sensible way to present the eh region? */
+ break;
+
+ case ASM_EXPR:
+ pp_string (buffer, "__asm__");
+ if (ASM_VOLATILE_P (node))
+ pp_string (buffer, " __volatile__");
+ pp_character (buffer, '(');
+ dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
+ pp_character (buffer, ':');
+ dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
+ pp_character (buffer, ':');
+ dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
+ if (ASM_CLOBBERS (node))
+ {
+ pp_character (buffer, ':');
+ dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
+ }
+ pp_string (buffer, ")");
+ break;
+
+ case CASE_LABEL_EXPR:
+ if (CASE_LOW (node) && CASE_HIGH (node))
+ {
+ pp_string (buffer, "case ");
+ dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
+ pp_string (buffer, " ... ");
+ dump_generic_node (buffer, CASE_HIGH (node), spc, flags, false);
+ }
+ else if (CASE_LOW (node))
+ {
+ pp_string (buffer, "case ");
+ dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
+ }
+ else
+ pp_string (buffer, "default ");
+ pp_character (buffer, ':');
+ break;
+
+ case VTABLE_REF:
+ pp_string (buffer, "VTABLE_REF <(");
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+ pp_string (buffer, "),");
+ dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+ pp_character (buffer, ',');
+ dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
+ pp_character (buffer, '>');
+ break;
+
+ case EPHI_NODE:
+ {
+ int i;
+
+ pp_string (buffer, " EPHI (");
+ dump_generic_node (buffer, EREF_NAME (node), spc, flags, false);
+ pp_string (buffer, ") ");
+ pp_character (buffer, '[');
+ pp_string (buffer, " class:");
+ pp_decimal_int (buffer, EREF_CLASS (node));
+ if (EPHI_DOWNSAFE (node))
+ pp_string (buffer, " downsafe");
+ if (EPHI_CANT_BE_AVAIL (node))
+ pp_string (buffer, " cant_be_avail");
+ if (EPHI_STOPS (node))
+ pp_string (buffer, " stops");
+ pp_string (buffer, " bb:");
+ pp_decimal_int (buffer, bb_for_stmt (node)->index);
+ pp_character (buffer, ']');
+ if (! (flags & TDF_SLIM))
+ {
+ pp_string (buffer, " <");
+ for (i = 0; i < EPHI_NUM_ARGS (node); i++)
+ {
+ if (EPHI_ARG_DEF (node, i))
+ {
+ newline_and_indent (buffer, spc + 2);
+ pp_string (buffer, " edge ");
+ pp_decimal_int (buffer, EPHI_ARG_EDGE (node, i)->src->index);
+ pp_string (buffer, "->");
+ pp_decimal_int (buffer, EPHI_ARG_EDGE (node, i)->dest->index);
+ pp_string (buffer, " [ ");
+ if (EPHI_ARG_HAS_REAL_USE (node, i))
+ pp_string (buffer, " real use");
+ if (EPHI_ARG_INJURED (node, i))
+ pp_string (buffer, " injured");
+ if (EPHI_ARG_STOPS (node, i))
+ pp_string (buffer, " stops");
+ pp_string (buffer, " ] ");
+ pp_string (buffer, " defined by:");
+ dump_generic_node (buffer, EPHI_ARG_DEF (node, i),
+ spc + 4, flags | TDF_SLIM, false);
+ }
+ }
+ }
+ pp_string (buffer, " >");
+ }
+ break;
+ case EEXIT_NODE:
+ case EKILL_NODE:
+ if (TREE_CODE (node) == EEXIT_NODE)
+ pp_string (buffer, "EEXIT (");
+ else if (TREE_CODE (node) == EKILL_NODE)
+ pp_string (buffer, "EKILL (");
+ dump_generic_node (buffer, EREF_NAME (node), spc, flags, false);
+ pp_string (buffer, ") ");
+ pp_character (buffer, '[');
+ pp_string (buffer, "class:");
+ pp_decimal_int (buffer, EREF_CLASS (node));
+ pp_string (buffer, " bb:");
+ pp_decimal_int (buffer, bb_for_stmt (node)->index);
+ pp_character (buffer, ']');
+ break;
+ case EUSE_NODE:
+ pp_string (buffer, " EUSE (");
+ dump_generic_node (buffer, EREF_NAME (node), spc, flags, false);
+
+ pp_string (buffer, ") ");
+ pp_character (buffer, '[');
+ pp_string (buffer, "class:");
+ pp_decimal_int (buffer, EREF_CLASS (node));
+ pp_string (buffer, " phiop:");
+ pp_decimal_int (buffer, EUSE_PHIOP (node));
+ pp_string (buffer, " bb:");
+ pp_decimal_int (buffer, bb_for_stmt (node)->index);
+ if (EUSE_LVAL (node))
+ pp_string (buffer, " left-occurrence");
+ pp_string (buffer, " ]");
+
+ break;
+ case PHI_NODE:
+ {
+ int i;
+
+ dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
+ pp_string (buffer, " = PHI <");
+ for (i = 0; i < PHI_NUM_ARGS (node); i++)
+ {
+ dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
+ pp_string (buffer, "(");
+ pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
+ pp_string (buffer, ")");
+ if (i < PHI_NUM_ARGS (node) - 1)
+ pp_string (buffer, ", ");
+ }
+ pp_string (buffer, ">;");
+ }
+ break;
+
+ case SSA_NAME:
+ dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
+ pp_string (buffer, "_");
+ pp_decimal_int (buffer, SSA_NAME_VERSION (node));
+ break;
+
+ default:
+ NIY;
+ }
+
+ if (is_stmt && is_expr)
+ pp_semicolon (buffer);
+ pp_write_text_to_stream (buffer);
+
+ return spc;
+}
+
+/* Print the declaration of a variable. */
+
+static void
+print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
+{
+ /* Don't print type declarations. */
+ if (TREE_CODE (t) == TYPE_DECL)
+ return;
+
+ INDENT (spc);
+
+ if (DECL_REGISTER (t))
+ pp_string (buffer, "register ");
+
+ if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
+ pp_string (buffer, "extern ");
+ else if (TREE_STATIC (t))
+ pp_string (buffer, "static ");
+
+ /* Print the type and name. */
+ if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
+ {
+ tree tmp;
+
+ /* Print array's type. */
+ tmp = TREE_TYPE (t);
+ while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
+ tmp = TREE_TYPE (tmp);
+ dump_generic_node (buffer, TREE_TYPE (tmp), spc, flags, false);
+
+ /* Print variable's name. */
+ pp_space (buffer);
+ dump_generic_node (buffer, t, spc, flags, false);
+
+ /* Print the dimensions. */
+ tmp = TREE_TYPE (t);
+ while (TREE_CODE (tmp) == ARRAY_TYPE)
+ {
+ pp_character (buffer, '[');
+ if (TYPE_DOMAIN (tmp))
+ {
+ if (TREE_CODE (TYPE_SIZE (tmp)) == INTEGER_CST)
+ pp_wide_integer (buffer,
+ TREE_INT_CST_LOW (TYPE_SIZE (tmp)) /
+ TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tmp))));
+ else
+ dump_generic_node (buffer, TYPE_SIZE_UNIT (tmp), spc, flags,
+ false);
+ }
+ pp_character (buffer, ']');
+ tmp = TREE_TYPE (tmp);
+ }
+ }
+ else
+ {
+ /* Print type declaration. */
+ dump_generic_node (buffer, TREE_TYPE (t), spc, flags, false);
+
+ /* Print variable's name. */
+ pp_space (buffer);
+ dump_generic_node (buffer, t, spc, flags, false);
+ }
+
+ /* The initial value of a function serves to determine wether the function
+ is declared or defined. So the following does not apply to function
+ nodes. */
+ if (TREE_CODE (t) != FUNCTION_DECL)
+ {
+ /* Print the initial value. */
+ if (DECL_INITIAL (t))
+ {
+ pp_space (buffer);
+ pp_character (buffer, '=');
+ pp_space (buffer);
+ dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
+ }
+ }
+
+ pp_character (buffer, ';');
+}
+
+
+/* Prints a structure: name, fields, and methods.
+ FIXME: Still incomplete. */
+
+static void
+print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
+{
+ /* Print the name of the structure. */
+ if (TYPE_NAME (node))
+ {
+ INDENT (spc);
+ if (TREE_CODE (node) == RECORD_TYPE)
+ pp_string (buffer, "struct ");
+ else if (TREE_CODE (node) == UNION_TYPE)
+ pp_string (buffer, "union ");
+ else
+ NIY;
+ dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
+ }
+
+ /* Print the contents of the structure. */
+ pp_newline (buffer);
+ INDENT (spc);
+ pp_character (buffer, '{');
+ pp_newline (buffer);
+
+ /* Print the fields of the structure. */
+ {
+ tree tmp;
+ tmp = TYPE_FIELDS (node);
+ while (tmp)
+ {
+ /* Avoid to print recursively the structure. */
+ /* FIXME : Not implemented correctly...,
+ what about the case when we have a cycle in the contain graph? ...
+ Maybe this could be solved by looking at the scope in which the
+ structure was declared. */
+ if (TREE_TYPE (tmp) != node
+ || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE &&
+ TREE_TYPE (TREE_TYPE (tmp)) != node))
+ {
+ print_declaration (buffer, tmp, spc+2, flags);
+ pp_newline (buffer);
+ }
+ else
+ {
+
+ }
+ tmp = TREE_CHAIN (tmp);
+ }
+ }
+ INDENT (spc);
+ pp_character (buffer, '}');
+}
+
+/* Return the priority of the operator OP.
+
+ From lowest to highest precedence with either left-to-right (L-R)
+ or right-to-left (R-L) associativity]:
+
+ 1 [L-R] ,
+ 2 [R-L] = += -= *= /= %= &= ^= |= <<= >>=
+ 3 [R-L] ?:
+ 4 [L-R] ||
+ 5 [L-R] &&
+ 6 [L-R] |
+ 7 [L-R] ^
+ 8 [L-R] &
+ 9 [L-R] == !=
+ 10 [L-R] < <= > >=
+ 11 [L-R] << >>
+ 12 [L-R] + -
+ 13 [L-R] * / %
+ 14 [R-L] ! ~ ++ -- + - * & (type) sizeof
+ 15 [L-R] fn() [] -> .
+
+ unary +, - and * have higher precedence than the corresponding binary
+ operators. */
+
+static int
+op_prio (tree op)
+{
+ if (op == NULL)
+ return 9999;
+
+ switch (TREE_CODE (op))
+ {
+ case TREE_LIST:
+ case COMPOUND_EXPR:
+ case BIND_EXPR:
+ return 1;
+
+ case MODIFY_EXPR:
+ case INIT_EXPR:
+ return 2;
+
+ case COND_EXPR:
+ return 3;
+
+ case TRUTH_OR_EXPR:
+ case TRUTH_ORIF_EXPR:
+ return 4;
+
+ case TRUTH_AND_EXPR:
+ case TRUTH_ANDIF_EXPR:
+ return 5;
+
+ case BIT_IOR_EXPR:
+ return 6;
+
+ case BIT_XOR_EXPR:
+ case TRUTH_XOR_EXPR:
+ return 7;
+
+ case BIT_AND_EXPR:
+ return 8;
+
+ case EQ_EXPR:
+ case NE_EXPR:
+ return 9;
+
+ case LT_EXPR:
+ case LE_EXPR:
+ case GT_EXPR:
+ case GE_EXPR:
+ return 10;
+
+ case LSHIFT_EXPR:
+ case RSHIFT_EXPR:
+ case LROTATE_EXPR:
+ case RROTATE_EXPR:
+ return 11;
+
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ return 12;
+
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case RDIV_EXPR:
+ case EXACT_DIV_EXPR:
+ case TRUNC_MOD_EXPR:
+ case CEIL_MOD_EXPR:
+ case FLOOR_MOD_EXPR:
+ case ROUND_MOD_EXPR:
+ return 13;
+
+ case TRUTH_NOT_EXPR:
+ case BIT_NOT_EXPR:
+ case POSTINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ case PREINCREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ case NEGATE_EXPR:
+ case INDIRECT_REF:
+ case ADDR_EXPR:
+ case FLOAT_EXPR:
+ case NOP_EXPR:
+ case CONVERT_EXPR:
+ case FIX_TRUNC_EXPR:
+ case FIX_CEIL_EXPR:
+ case FIX_FLOOR_EXPR:
+ case FIX_ROUND_EXPR:
+ case TARGET_EXPR:
+ return 14;
+
+ case CALL_EXPR:
+ case ARRAY_REF:
+ case COMPONENT_REF:
+ return 15;
+
+ /* Special expressions. */
+ case MIN_EXPR:
+ case MAX_EXPR:
+ case ABS_EXPR:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ return 16;
+
+ case SAVE_EXPR:
+ case NON_LVALUE_EXPR:
+ return op_prio (TREE_OPERAND (op, 0));
+
+ default:
+ /* Return an arbitrarily high precedence to avoid surrounding single
+ VAR_DECLs in ()s. */
+ return 9999;
+ }
+}
+
+
+/* Return the symbol associated with operator OP. */
+
+static const char *
+op_symbol (tree op)
+{
+ if (op == NULL)
+ abort ();
+
+ switch (TREE_CODE (op))
+ {
+ case MODIFY_EXPR:
+ return "=";
+
+ case TRUTH_OR_EXPR:
+ case TRUTH_ORIF_EXPR:
+ return "||";
+
+ case TRUTH_AND_EXPR:
+ case TRUTH_ANDIF_EXPR:
+ return "&&";
+
+ case BIT_IOR_EXPR:
+ return "|";
+
+ case TRUTH_XOR_EXPR:
+ case BIT_XOR_EXPR:
+ return "^";
+
+ case ADDR_EXPR:
+ case BIT_AND_EXPR:
+ return "&";
+
+ case EQ_EXPR:
+ case UNEQ_EXPR:
+ return "==";
+
+ case NE_EXPR:
+ return "!=";
+
+ case LT_EXPR:
+ case UNLT_EXPR:
+ return "<";
+
+ case LE_EXPR:
+ case UNLE_EXPR:
+ return "<=";
+
+ case GT_EXPR:
+ case UNGT_EXPR:
+ return ">";
+
+ case GE_EXPR:
+ case UNGE_EXPR:
+ return ">=";
+
+ case LSHIFT_EXPR:
+ return "<<";
+
+ case RSHIFT_EXPR:
+ return ">>";
+
+ case PLUS_EXPR:
+ return "+";
+
+ case NEGATE_EXPR:
+ case MINUS_EXPR:
+ return "-";
+
+ case BIT_NOT_EXPR:
+ return "~";
+
+ case TRUTH_NOT_EXPR:
+ return "!";
+
+ case MULT_EXPR:
+ case INDIRECT_REF:
+ return "*";
+
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case RDIV_EXPR:
+ case EXACT_DIV_EXPR:
+ return "/";
+
+ case TRUNC_MOD_EXPR:
+ case CEIL_MOD_EXPR:
+ case FLOOR_MOD_EXPR:
+ case ROUND_MOD_EXPR:
+ return "%";
+
+ case PREDECREMENT_EXPR:
+ return " --";
+
+ case PREINCREMENT_EXPR:
+ return " ++";
+
+ case POSTDECREMENT_EXPR:
+ return "-- ";
+
+ case POSTINCREMENT_EXPR:
+ return "++ ";
+
+ case REFERENCE_EXPR:
+ return "";
+
+ default:
+ return "<<< ??? >>>";
+ }
+}
+
+/* Prints the name of a CALL_EXPR. */
+
+static void
+print_call_name (pretty_printer *buffer, tree node)
+{
+ tree op0;
+
+ if (TREE_CODE (node) != CALL_EXPR)
+ abort ();
+
+ op0 = TREE_OPERAND (node, 0);
+
+ if (TREE_CODE (op0) == NON_LVALUE_EXPR)
+ op0 = TREE_OPERAND (op0, 0);
+
+ switch (TREE_CODE (op0))
+ {
+ case VAR_DECL:
+ case PARM_DECL:
+ PRINT_FUNCTION_NAME (op0);
+ break;
+
+ case ADDR_EXPR:
+ case INDIRECT_REF:
+ case NOP_EXPR:
+ dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
+ break;
+
+ case COND_EXPR:
+ pp_string (buffer, "(");
+ dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
+ pp_string (buffer, ") ? ");
+ dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
+ pp_string (buffer, " : ");
+ dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
+ break;
+
+ case COMPONENT_REF:
+ /* The function is a pointer contained in a structure. */
+ if (TREE_CODE (TREE_OPERAND (op0, 0)) == INDIRECT_REF ||
+ TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
+ PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 1));
+ else
+ dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
+ /* else
+ We can have several levels of structures and a function
+ pointer inside. This is not implemented yet... */
+ /* NIY;*/
+ break;
+
+ case ARRAY_REF:
+ if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
+ PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 0));
+ else
+ dump_generic_node (buffer, op0, 0, 0, false);
+ break;
+
+ case SSA_NAME:
+ dump_generic_node (buffer, op0, 0, 0, false);
+ break;
+
+ default:
+ NIY;
+ }
+}
+
+/* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ... */
+
+static void
+pretty_print_string (pretty_printer *buffer, const char *str)
+{
+ if (str == NULL)
+ return;
+
+ while (*str)
+ {
+ switch (str[0])
+ {
+ case '\b':
+ pp_string (buffer, "\\b");
+ break;
+
+ case '\f':
+ pp_string (buffer, "\\f");
+ break;
+
+ case '\n':
+ pp_string (buffer, "\\n");
+ break;
+
+ case '\r':
+ pp_string (buffer, "\\r");
+ break;
+
+ case '\t':
+ pp_string (buffer, "\\t");
+ break;
+
+ case '\v':
+ pp_string (buffer, "\\v");
+ break;
+
+ case '\\':
+ pp_string (buffer, "\\\\");
+ break;
+
+ case '\"':
+ pp_string (buffer, "\\\"");
+ break;
+
+ case '\'':
+ pp_string (buffer, "\\'");
+ break;
+
+ case '\0':
+ pp_string (buffer, "\\0");
+ break;
+
+ case '\1':
+ pp_string (buffer, "\\1");
+ break;
+
+ case '\2':
+ pp_string (buffer, "\\2");
+ break;
+
+ case '\3':
+ pp_string (buffer, "\\3");
+ break;
+
+ case '\4':
+ pp_string (buffer, "\\4");
+ break;
+
+ case '\5':
+ pp_string (buffer, "\\5");
+ break;
+
+ case '\6':
+ pp_string (buffer, "\\6");
+ break;
+
+ case '\7':
+ pp_string (buffer, "\\7");
+ break;
+
+ default:
+ pp_character (buffer, str[0]);
+ break;
+ }
+ str++;
+ }
+}
+
+static void
+maybe_init_pretty_print (FILE *file)
+{
+ if (!initialized)
+ {
+ pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
+ pp_needs_newline (&buffer) = true;
+ initialized = 1;
+ }
+
+ buffer.buffer->stream = file;
+}
+
+static void
+newline_and_indent (pretty_printer *buffer, int spc)
+{
+ pp_newline (buffer);
+ INDENT (spc);
+}
+
+static void
+dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
+{
+ size_t i;
+ stmt_ann_t ann = stmt_ann (stmt);
+ vdef_optype vdefs = VDEF_OPS (ann);
+ vuse_optype vuses = VUSE_OPS (ann);
+
+ for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ {
+ pp_string (buffer, "# ");
+ dump_generic_node (buffer, VDEF_RESULT (vdefs, i), spc + 2, flags, false);
+ pp_string (buffer, " = VDEF <");
+ dump_generic_node (buffer, VDEF_OP (vdefs, i), spc + 2, flags, false);
+ pp_string (buffer, ">;");
+ newline_and_indent (buffer, spc);
+ }
+
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ {
+ tree vuse = VUSE_OP (vuses, i);
+ pp_string (buffer, "# VUSE <");
+ dump_generic_node (buffer, vuse, spc + 2, flags, false);
+ pp_string (buffer, ">;");
+ newline_and_indent (buffer, spc);
+ }
+}
+
+/* Dumps basic block BB to FILE with details described by FLAGS and
+ indented by INDENT spaces. */
+
+void
+dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
+{
+ maybe_init_pretty_print (file);
+ dumping_stmts = true;
+ dump_generic_bb_buff (&buffer, bb, indent, flags);
+ pp_flush (&buffer);
+}
+
+/* Dumps header of basic block BB to buffer BUFFER indented by INDENT
+ spaces and details described by flags. */
+
+static void
+dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
+{
+ edge e;
+ tree stmt;
+
+ if (flags & TDF_BLOCKS)
+ {
+ INDENT (indent);
+ pp_string (buffer, "# BLOCK ");
+ pp_decimal_int (buffer, bb->index);
+
+ if (flags & TDF_LINENO)
+ {
+ block_stmt_iterator bsi;
+
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ if (get_lineno (bsi_stmt (bsi)) != -1)
+ {
+ pp_string (buffer, ", starting at line ");
+ pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
+ break;
+ }
+ }
+ newline_and_indent (buffer, indent);
+
+ pp_string (buffer, "# PRED:");
+ pp_write_text_to_stream (buffer);
+ for (e = bb->pred; e; e = e->pred_next)
+ if (flags & TDF_SLIM)
+ {
+ pp_string (buffer, " ");
+ if (e->src == ENTRY_BLOCK_PTR)
+ pp_string (buffer, "ENTRY");
+ else
+ pp_decimal_int (buffer, e->src->index);
+ }
+ else
+ dump_edge_info (buffer->buffer->stream, e, 0);
+ pp_newline (buffer);
+ }
+ else
+ {
+ stmt = first_stmt (bb);
+ if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
+ {
+ INDENT (indent - 2);
+ pp_string (buffer, "<bb ");
+ pp_decimal_int (buffer, bb->index);
+ pp_string (buffer, ">:");
+ pp_newline (buffer);
+ }
+ }
+}
+
+/* Dumps end of basic block BB to buffer BUFFER indented by INDENT
+ spaces. */
+
+static void
+dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
+{
+ edge e;
+
+ INDENT (indent);
+ pp_string (buffer, "# SUCC:");
+ pp_write_text_to_stream (buffer);
+ for (e = bb->succ; e; e = e->succ_next)
+ if (flags & TDF_SLIM)
+ {
+ pp_string (buffer, " ");
+ if (e->dest == EXIT_BLOCK_PTR)
+ pp_string (buffer, "EXIT");
+ else
+ pp_decimal_int (buffer, e->dest->index);
+ }
+ else
+ dump_edge_info (buffer->buffer->stream, e, 1);
+ pp_newline (buffer);
+}
+
+/* Dumps phi nodes of basic block BB to buffer BUFFER with details described by
+ FLAGS indented by INDENT spaces. */
+
+static void
+dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
+{
+ tree phi = phi_nodes (bb);
+ if (!phi)
+ return;
+
+ for (; phi; phi = TREE_CHAIN (phi))
+ {
+ if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
+ {
+ INDENT (indent);
+ pp_string (buffer, "# ");
+ dump_generic_node (buffer, phi, indent, flags, false);
+ pp_newline (buffer);
+ }
+ }
+}
+
+/* Dump jump to basic block BB that is represented implicitly in the cfg
+ to BUFFER. */
+
+static void
+pp_cfg_jump (pretty_printer *buffer, basic_block bb)
+{
+ tree stmt;
+
+ stmt = first_stmt (bb);
+
+ pp_string (buffer, "goto <bb ");
+ pp_decimal_int (buffer, bb->index);
+ pp_string (buffer, ">");
+ if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
+ {
+ pp_string (buffer, " (");
+ dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
+ pp_string (buffer, ")");
+ }
+ pp_semicolon (buffer);
+}
+
+/* Dump edges represented implicitly in basic block BB to BUFFER, indented
+ by INDENT spaces, with details given by FLAGS. */
+
+static void
+dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent)
+{
+ edge e;
+
+ /* If there is a fallthru edge, we may need to add an artificial goto to the
+ dump. */
+ for (e = bb->succ; e; e = e->succ_next)
+ if (e->flags & EDGE_FALLTHRU)
+ break;
+ if (e && e->dest != bb->next_bb)
+ {
+ INDENT (indent);
+ pp_cfg_jump (buffer, e->dest);
+ pp_newline (buffer);
+ }
+}
+
+/* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
+ indented by INDENT spaces. */
+
+static void
+dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
+ int indent, int flags)
+{
+ block_stmt_iterator bsi;
+ tree stmt;
+ int label_indent = indent - 2;
+
+ if (label_indent < 0)
+ label_indent = 0;
+
+ dump_bb_header (buffer, bb, indent, flags);
+
+ if (bb_ann (bb))
+ dump_phi_nodes (buffer, bb, indent, flags);
+
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ int curr_indent;
+
+ stmt = bsi_stmt (bsi);
+
+ curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
+
+ INDENT (curr_indent);
+ dump_generic_node (buffer, stmt, curr_indent, flags, true);
+ pp_newline (buffer);
+ }
+
+ dump_implicit_edges (buffer, bb, indent);
+
+ if (flags & TDF_BLOCKS)
+ dump_bb_end (buffer, bb, indent, flags);
+}
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
new file mode 100644
index 00000000000..c1498ea8d5c
--- /dev/null
+++ b/gcc/tree-profile.c
@@ -0,0 +1,188 @@
+/* Calculate branch probabilities, and basic block execution counts.
+ Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
+ based on some ideas from Dain Samples of UC Berkeley.
+ Further mangling by Bob Manson, Cygnus Support.
+ Converted to use trees by Dale Johannesen, Apple Computer.
+
+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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Generate basic block profile instrumentation and auxiliary files.
+ Profile generation is optimized, so that not all arcs in the basic
+ block graph need instrumenting. First, the BB graph is closed with
+ one entry (function start), and one exit (function exit). Any
+ ABNORMAL_EDGE cannot be instrumented (because there is no control
+ path to place the code). We close the graph by inserting fake
+ EDGE_FAKE edges to the EXIT_BLOCK, from the sources of abnormal
+ edges that do not go to the exit_block. We ignore such abnormal
+ edges. Naturally these fake edges are never directly traversed,
+ and so *cannot* be directly instrumented. Some other graph
+ massaging is done. To optimize the instrumentation we generate the
+ BB minimal span tree, only edges that are not on the span tree
+ (plus the entry point) need instrumenting. From that information
+ all other edge counts can be deduced. By construction all fake
+ edges must be on the spanning tree. We also attempt to place
+ EDGE_CRITICAL edges on the spanning tree.
+
+ The auxiliary file generated is <dumpbase>.bbg. The format is
+ described in full in gcov-io.h. */
+
+/* ??? Register allocation should use basic block execution counts to
+ give preference to the most commonly executed blocks. */
+
+/* ??? Should calculate branch probabilities before instrumenting code, since
+ then we can use arc counts to help decide which arcs to instrument. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "flags.h"
+#include "output.h"
+#include "regs.h"
+#include "expr.h"
+#include "function.h"
+#include "toplev.h"
+#include "coverage.h"
+#include "tree.h"
+#include "tree-flow.h"
+#include "tree-dump.h"
+#include "tree-pass.h"
+#include "timevar.h"
+#include "value-prof.h"
+
+
+/* Output instructions as GIMPLE trees to increment the edge
+ execution count, and insert them on E. We rely on
+ bsi_insert_on_edge to preserve the order. */
+
+static void
+tree_gen_edge_profiler (int edgeno, edge e)
+{
+ tree tmp1 = create_tmp_var (GCOV_TYPE_NODE, "PROF");
+ tree tmp2 = create_tmp_var (GCOV_TYPE_NODE, "PROF");
+ tree ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
+ tree stmt1 = build (MODIFY_EXPR, GCOV_TYPE_NODE, tmp1, ref);
+ tree stmt2 = build (MODIFY_EXPR, GCOV_TYPE_NODE, tmp2,
+ build (PLUS_EXPR, GCOV_TYPE_NODE,
+ tmp1, integer_one_node));
+ tree stmt3 = build (MODIFY_EXPR, GCOV_TYPE_NODE, ref, tmp2);
+ bsi_insert_on_edge (e, stmt1);
+ bsi_insert_on_edge (e, stmt2);
+ bsi_insert_on_edge (e, stmt3);
+}
+
+/* Output instructions as GIMPLE trees to increment the interval histogram
+ counter. VALUE is the expression whose value is profiled. TAG is the
+ tag of the section for counters, BASE is offset of the counter position. */
+
+static void
+tree_gen_interval_profiler (struct histogram_value *value ATTRIBUTE_UNUSED,
+ unsigned tag ATTRIBUTE_UNUSED,
+ unsigned base ATTRIBUTE_UNUSED)
+{
+ /* FIXME implement this. */
+ abort ();
+}
+
+/* Output instructions as GIMPLE trees to increment the power of two histogram
+ counter. VALUE is the expression whose value is profiled. TAG is the tag
+ of the section for counters, BASE is offset of the counter position. */
+
+static void
+tree_gen_pow2_profiler (struct histogram_value *value ATTRIBUTE_UNUSED,
+ unsigned tag ATTRIBUTE_UNUSED,
+ unsigned base ATTRIBUTE_UNUSED)
+{
+ /* FIXME implement this. */
+ abort ();
+}
+
+/* Output instructions as GIMPLE trees for code to find the most common value.
+ VALUE is the expression whose value is profiled. TAG is the tag of the
+ section for counters, BASE is offset of the counter position. */
+
+static void
+tree_gen_one_value_profiler (struct histogram_value *value ATTRIBUTE_UNUSED,
+ unsigned tag ATTRIBUTE_UNUSED,
+ unsigned base ATTRIBUTE_UNUSED)
+{
+ /* FIXME implement this. */
+ abort ();
+}
+
+/* Output instructions as GIMPLE trees for code to find the most common value
+ of a difference between two evaluations of an expression.
+ VALUE is the expression whose value is profiled. TAG is the tag of the
+ section for counters, BASE is offset of the counter position. */
+
+static void
+tree_gen_const_delta_profiler (struct histogram_value *value ATTRIBUTE_UNUSED,
+ unsigned tag ATTRIBUTE_UNUSED,
+ unsigned base ATTRIBUTE_UNUSED)
+{
+ /* FIXME implement this. */
+ abort ();
+}
+
+/* Return 1 if tree-based profiling is in effect, else 0.
+ If it is, set up hooks for tree-based profiling.
+ Gate for pass_tree_profile. */
+
+static bool do_tree_profiling (void) {
+ if (flag_tree_based_profiling)
+ {
+ tree_register_profile_hooks ();
+ tree_register_value_prof_hooks ();
+ }
+ return flag_tree_based_profiling;
+}
+
+/* Return the file on which profile dump output goes, if any. */
+
+static FILE *tree_profile_dump_file (void) {
+ return dump_file;
+}
+
+struct tree_opt_pass pass_tree_profile =
+{
+ "tree_profile", /* name */
+ do_tree_profiling, /* gate */
+ branch_prob, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_BRANCH_PROB, /* tv_id */
+ PROP_gimple_leh | PROP_cfg, /* properties_required */
+ PROP_gimple_leh | PROP_cfg, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_stmts /* todo_flags_finish */
+};
+
+struct profile_hooks tree_profile_hooks =
+{
+ tree_gen_edge_profiler, /* gen_edge_profiler */
+ tree_gen_interval_profiler, /* gen_interval_profiler */
+ tree_gen_pow2_profiler, /* gen_pow2_profiler */
+ tree_gen_one_value_profiler, /* gen_one_value_profiler */
+ tree_gen_const_delta_profiler,/* gen_const_delta_profiler */
+ tree_profile_dump_file /* profile_dump_file */
+};
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
new file mode 100644
index 00000000000..46a3c59e117
--- /dev/null
+++ b/gcc/tree-sra.c
@@ -0,0 +1,1182 @@
+/* Scalar Replacement of Aggregates (SRA) converts some structure
+ references into scalar references, exposing them to the scalar
+ optimizers.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Diego Novillo <dnovillo@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "errors.h"
+#include "ggc.h"
+#include "tree.h"
+
+/* These RTL headers are needed for basic-block.h. */
+#include "rtl.h"
+#include "tm_p.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "diagnostic.h"
+#include "langhooks.h"
+#include "tree-inline.h"
+#include "tree-flow.h"
+#include "tree-gimple.h"
+#include "tree-dump.h"
+#include "tree-pass.h"
+#include "timevar.h"
+#include "flags.h"
+#include "bitmap.h"
+
+
+/* Maximum number of fields that a structure should have to be scalarized.
+ FIXME This limit has been arbitrarily set to 5. Experiment to find a
+ sensible setting. */
+#define MAX_NFIELDS_FOR_SRA 5
+
+/* Codes indicating how to copy one structure into another. */
+enum sra_copy_mode { SCALAR_SCALAR, FIELD_SCALAR, SCALAR_FIELD };
+
+/* Local functions. */
+static inline bool can_be_scalarized_p (tree);
+static inline void insert_edge_copies (tree stmt, basic_block bb);
+static tree create_scalar_copies (tree lhs, tree rhs, enum sra_copy_mode mode);
+static inline void scalarize_component_ref (tree, tree *tp);
+static void scalarize_structures (void);
+static void scalarize_stmt (block_stmt_iterator *);
+static void scalarize_modify_expr (block_stmt_iterator *);
+static void scalarize_call_expr (block_stmt_iterator *);
+static void scalarize_asm_expr (block_stmt_iterator *);
+static void scalarize_return_expr (block_stmt_iterator *);
+
+/* The set of aggregate variables that are candidates for scalarization. */
+static bitmap sra_candidates;
+
+/* Set of scalarizable PARM_DECLs that need copy-in operations at the
+ beginning of the function. */
+static bitmap needs_copy_in;
+
+/* This structure holds the mapping between and element of an aggregate
+ and the scalar replacement variable. */
+struct sra_elt
+{
+ enum tree_code kind;
+ tree base;
+ tree field;
+ tree replace;
+};
+
+static htab_t sra_map;
+
+static hashval_t
+sra_elt_hash (const void *x)
+{
+ const struct sra_elt *e = x;
+ hashval_t h = (size_t) e->base * e->kind;
+ if (e->kind == COMPONENT_REF)
+ h ^= (size_t) e->field;
+ return h;
+}
+
+static int
+sra_elt_eq (const void *x, const void *y)
+{
+ const struct sra_elt *a = x;
+ const struct sra_elt *b = y;
+
+ if (a->kind != b->kind)
+ return false;
+ if (a->base != b->base)
+ return false;
+ if (a->kind == COMPONENT_REF)
+ if (a->field != b->field)
+ return false;
+
+ return true;
+}
+
+/* Mark all the variables in VDEF operands for STMT for renaming.
+ This becomes necessary when we modify all of a non-scalar. */
+
+static void
+mark_all_vdefs (tree stmt)
+{
+ vdef_optype vdefs;
+ size_t i, n;
+
+ get_stmt_operands (stmt);
+ vdefs = VDEF_OPS (stmt_ann (stmt));
+ n = NUM_VDEFS (vdefs);
+
+ for (i = 0; i < n; i++)
+ {
+ tree sym = VDEF_RESULT (vdefs, i);
+ bitmap_set_bit (vars_to_rename, var_ann (sym)->uid);
+ }
+}
+
+/* Return true if DECL is an SRA candidate. */
+
+static bool
+is_sra_candidate_decl (tree decl)
+{
+ return DECL_P (decl) && bitmap_bit_p (sra_candidates, var_ann (decl)->uid);
+}
+
+/* Return true if EXP is of the form <ref decl>, where REF is one of the
+ field access references we handle and DECL is an SRA candidate.
+
+ Set ALLOW_BIT_FIELD_REF to accept BIT_FIELD_REF as well. This is
+ normally false, except when we're trying to work around it. */
+
+static bool
+is_sra_candidate_ref (tree exp, bool allow_bit_field_ref)
+{
+ switch (TREE_CODE (exp))
+ {
+ case BIT_FIELD_REF:
+ if (!allow_bit_field_ref)
+ break;
+ /* FALLTHRU */
+
+ case COMPONENT_REF:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ return is_sra_candidate_decl (TREE_OPERAND (exp, 0));
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+/* Return the scalar in SRA_MAP[VAR_IX][FIELD_IX]. If none exists, create
+ a new scalar with type TYPE. */
+
+static tree
+lookup_scalar (struct sra_elt *key, tree type)
+{
+ struct sra_elt **slot, *res;
+
+ slot = (struct sra_elt **) htab_find_slot (sra_map, key, INSERT);
+ res = *slot;
+ if (!res)
+ {
+ res = xmalloc (sizeof (*res));
+ *slot = res;
+ *res = *key;
+ res->replace = make_rename_temp (type, "SR");
+
+ if (DECL_NAME (key->base) && !DECL_IGNORED_P (key->base))
+ {
+ char *name = NULL;
+ switch (key->kind)
+ {
+ case COMPONENT_REF:
+ if (!DECL_NAME (key->field))
+ break;
+ name = concat (IDENTIFIER_POINTER (DECL_NAME (key->base)),
+ "$",
+ IDENTIFIER_POINTER (DECL_NAME (key->field)),
+ NULL);
+ break;
+ case REALPART_EXPR:
+ name = concat (IDENTIFIER_POINTER (DECL_NAME (key->base)),
+ "$real", NULL);
+ break;
+ case IMAGPART_EXPR:
+ name = concat (IDENTIFIER_POINTER (DECL_NAME (key->base)),
+ "$imag", NULL);
+ break;
+ default:
+ abort ();
+ }
+ if (name)
+ {
+ DECL_NAME (res->replace) = get_identifier (name);
+ free (name);
+ }
+ }
+
+ DECL_SOURCE_LOCATION (res->replace) = DECL_SOURCE_LOCATION (key->base);
+ TREE_NO_WARNING (res->replace) = TREE_NO_WARNING (key->base);
+ DECL_ARTIFICIAL (res->replace) = DECL_ARTIFICIAL (key->base);
+ }
+
+ return res->replace;
+}
+
+
+/* Given a structure reference VAR.FIELD, return a scalar representing it.
+ If no scalar is found, a new one is created and added to the SRA_MAP
+ matrix. */
+
+static tree
+get_scalar_for_field (tree var, tree field)
+{
+ struct sra_elt key;
+
+#ifdef ENABLE_CHECKING
+ /* Validate that FIELD actually exists in VAR's type. */
+ {
+ tree f;
+ for (f = TYPE_FIELDS (TREE_TYPE (var)); f ; f = TREE_CHAIN (f))
+ if (f == field)
+ goto found;
+ abort ();
+ found:;
+ }
+#endif
+
+ key.kind = COMPONENT_REF;
+ key.base = var;
+ key.field = field;
+
+ return lookup_scalar (&key, TREE_TYPE (field));
+}
+
+
+/* Similarly for the parts of a complex type. */
+
+static tree
+get_scalar_for_complex_part (tree var, enum tree_code part)
+{
+ struct sra_elt key;
+
+ key.kind = part;
+ key.base = var;
+
+ return lookup_scalar (&key, TREE_TYPE (TREE_TYPE (var)));
+}
+
+/* Return true if the fields of VAR can be replaced by scalar temporaries.
+ This only happens if VAR is not call-clobbered and it contains less
+ than MAX_NFIELDS_FOR_SRA scalar fields. */
+
+static inline bool
+can_be_scalarized_p (tree var)
+{
+ tree field, type;
+ int nfields;
+
+ if (!is_gimple_non_addressable (var))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Cannot scalarize variable ");
+ print_generic_expr (dump_file, var, dump_flags);
+ fprintf (dump_file, " because it must live in memory\n");
+ }
+ return false;
+ }
+
+ if (TREE_THIS_VOLATILE (var))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Cannot scalarize variable ");
+ print_generic_expr (dump_file, var, dump_flags);
+ fprintf (dump_file, " because it is declared volatile\n");
+ }
+ return false;
+ }
+
+ /* Any COMPLEX_TYPE that has reached this point can be scalarized. */
+ if (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE)
+ return true;
+
+ type = TREE_TYPE (var);
+ nfields = 0;
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ {
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ /* FIXME: We really should recurse down the type hierarchy and
+ scalarize the fields at the leaves. */
+ if (AGGREGATE_TYPE_P (TREE_TYPE (field)))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Cannot scalarize variable ");
+ print_generic_expr (dump_file, var, dump_flags);
+ fprintf (dump_file,
+ " because it contains an aggregate type field, ");
+ print_generic_expr (dump_file, field, dump_flags);
+ fprintf (dump_file, "\n");
+ }
+ return false;
+ }
+
+ /* FIXME: Similarly. Indeed, considering that we treat complex
+ as an aggregate, this is exactly the same problem.
+ Structures with __complex__ fields are tested in the libstdc++
+ testsuite: 26_numerics/complex_inserters_extractors.cc. */
+ if (TREE_CODE (TREE_TYPE (field)) == COMPLEX_TYPE)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Cannot scalarize variable ");
+ print_generic_expr (dump_file, var, dump_flags);
+ fprintf (dump_file,
+ " because it contains a __complex__ field, ");
+ print_generic_expr (dump_file, field, dump_flags);
+ fprintf (dump_file, "\n");
+ }
+ return false;
+ }
+
+ /* FIXME. We don't scalarize structures with bit fields yet. To
+ support this, we should make sure that all the fields fit in one
+ word and modify every operation done on the scalarized bit fields
+ to mask them properly. */
+ if (DECL_BIT_FIELD (field))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Cannot scalarize variable ");
+ print_generic_expr (dump_file, var, dump_flags);
+ fprintf (dump_file,
+ " because it contains a bit-field, ");
+ print_generic_expr (dump_file, field, dump_flags);
+ fprintf (dump_file, "\n");
+ }
+ return false;
+ }
+
+ nfields++;
+ if (nfields > MAX_NFIELDS_FOR_SRA)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Cannot scalarize variable ");
+ print_generic_expr (dump_file, var, dump_flags);
+ fprintf (dump_file,
+ " because it contains more than %d fields\n",
+ MAX_NFIELDS_FOR_SRA);
+ }
+ return false;
+ }
+ }
+
+ /* If the structure had no FIELD_DECLs, then don't bother
+ scalarizing it. */
+ return nfields > 0;
+}
+
+
+/* Replace the COMPONENT_REF, REALPART_EXPR or IMAGPART_EXPR pointed-to by
+ TP inside STMT with the corresponding scalar replacement from SRA_MAP. */
+
+static inline void
+scalarize_component_ref (tree stmt, tree *tp)
+{
+ tree t = *tp, obj = TREE_OPERAND (t, 0);
+
+ /* When scalarizing a function argument, we will need to insert copy-in
+ operations from the original PARM_DECLs. Note that these copy-in
+ operations may end up being dead, but we won't know until we rename
+ the new variables into SSA. */
+ if (TREE_CODE (obj) == PARM_DECL)
+ bitmap_set_bit (needs_copy_in, var_ann (obj)->uid);
+
+ switch (TREE_CODE (t))
+ {
+ case COMPONENT_REF:
+ t = get_scalar_for_field (obj, TREE_OPERAND (t, 1));
+ break;
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ t = get_scalar_for_complex_part (obj, TREE_CODE (t));
+ break;
+ default:
+ abort ();
+ }
+
+ *tp = t;
+ modify_stmt (stmt);
+}
+
+
+/* Scalarize the structure assignment for the statement pointed by SI_P. */
+
+static void
+scalarize_structure_assignment (block_stmt_iterator *si_p)
+{
+ var_ann_t lhs_ann, rhs_ann;
+ tree lhs, rhs, list, orig_stmt;
+ bool lhs_can, rhs_can;
+
+ orig_stmt = bsi_stmt (*si_p);
+ lhs = TREE_OPERAND (orig_stmt, 0);
+ rhs = TREE_OPERAND (orig_stmt, 1);
+ list = NULL_TREE;
+
+#if defined ENABLE_CHECKING
+ if (TREE_CODE (orig_stmt) != MODIFY_EXPR)
+ abort ();
+#endif
+
+ /* Remove all type casts from RHS. This may seem heavy handed but
+ it's actually safe and it is necessary in the presence of C++
+ reinterpret_cast<> where structure assignments of different
+ structures will be present in the IL. This was the case of PR
+ 13347 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13347) which
+ had something like this:
+
+ struct A f;
+ struct B g;
+ f = (struct A)g;
+
+ Both 'f' and 'g' were scalarizable, but the presence of the type
+ cast was causing SRA to not replace the RHS of the assignment
+ with g's scalar replacements. Furthermore, the fact that this
+ assignment reached this point without causing syntax errors means
+ that the type cast is safe and that a field-by-field assignment
+ from 'g' into 'f' is the right thing to do. */
+ STRIP_NOPS (rhs);
+
+ lhs_ann = DECL_P (lhs) ? var_ann (lhs) : NULL;
+ rhs_ann = DECL_P (rhs) ? var_ann (rhs) : NULL;
+
+#if defined ENABLE_CHECKING
+ /* Two different variables should not have the same UID. */
+ if (lhs_ann
+ && rhs_ann
+ && lhs != rhs
+ && lhs_ann->uid == rhs_ann->uid)
+ abort ();
+#endif
+
+ lhs_can = lhs_ann && bitmap_bit_p (sra_candidates, lhs_ann->uid);
+ rhs_can = rhs_ann && bitmap_bit_p (sra_candidates, rhs_ann->uid);
+
+ /* Both LHS and RHS are scalarizable. */
+ if (lhs_can && rhs_can)
+ list = create_scalar_copies (lhs, rhs, SCALAR_SCALAR);
+
+ /* Only RHS is scalarizable. */
+ else if (rhs_can)
+ list = create_scalar_copies (lhs, rhs, FIELD_SCALAR);
+
+ /* Only LHS is scalarizable. */
+ else if (lhs_can)
+ list = create_scalar_copies (lhs, rhs, SCALAR_FIELD);
+
+ /* If neither side is scalarizable, do nothing else. */
+ else
+ return;
+
+ /* Set line number information for our replacements. */
+ if (EXPR_HAS_LOCATION (orig_stmt))
+ annotate_all_with_locus (&list, EXPR_LOCATION (orig_stmt));
+
+ /* Replace the existing statement with the newly created list of
+ scalarized copies. When replacing the original statement, the first
+ copy replaces it and the remaining copies are inserted either after
+ the first copy or on the outgoing edges of the original statement's
+ block. */
+ {
+ tree_stmt_iterator tsi = tsi_start (list);
+ bsi_replace (si_p, tsi_stmt (tsi), true);
+ tsi_delink (&tsi);
+ if (stmt_ends_bb_p (orig_stmt))
+ insert_edge_copies (list, bb_for_stmt (orig_stmt));
+ else
+ bsi_insert_after (si_p, list, BSI_CONTINUE_LINKING);
+ }
+}
+
+
+/* Traverse all the referenced variables in the program looking for
+ structures that could be replaced with scalars. */
+
+static bool
+find_candidates_for_sra (void)
+{
+ size_t i;
+ bool any_set = false;
+
+ for (i = 0; i < num_referenced_vars; i++)
+ {
+ tree var = referenced_var (i);
+
+ if ((TREE_CODE (TREE_TYPE (var)) == RECORD_TYPE
+ || TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE)
+ && can_be_scalarized_p (var))
+ {
+ bitmap_set_bit (sra_candidates, var_ann (var)->uid);
+ any_set = true;
+ }
+ }
+
+ return any_set;
+}
+
+
+/* Insert STMT on all the outgoing edges out of BB. Note that if BB
+ has more than one edge, STMT will be replicated for each edge. Also,
+ abnormal edges will be ignored. */
+
+static inline void
+insert_edge_copies (tree stmt, basic_block bb)
+{
+ edge e;
+ bool first_copy;
+
+ first_copy = true;
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ /* We don't need to insert copies on abnormal edges. The
+ value of the scalar replacement is not guaranteed to
+ be valid through an abnormal edge. */
+ if (!(e->flags & EDGE_ABNORMAL))
+ {
+ if (first_copy)
+ {
+ bsi_insert_on_edge (e, stmt);
+ first_copy = false;
+ }
+ else
+ bsi_insert_on_edge (e, lhd_unsave_expr_now (stmt));
+ }
+ }
+}
+
+
+/* Append a new assignment statement to TSI. */
+
+static tree
+csc_assign (tree_stmt_iterator *tsi, tree lhs, tree rhs)
+{
+ tree stmt = build (MODIFY_EXPR, TREE_TYPE (lhs), lhs, rhs);
+ modify_stmt (stmt);
+ tsi_link_after (tsi, stmt, TSI_NEW_STMT);
+ return stmt;
+}
+
+/* A subroutine of create_scalar_copies. Construct a COMPONENT_REF
+ expression for BASE referencing FIELD. INDEX is the field index. */
+
+static tree
+csc_build_component_ref (tree base, tree field)
+{
+ switch (TREE_CODE (base))
+ {
+ case CONSTRUCTOR:
+ /* Only appears on RHS. The only remaining CONSTRUCTORS for
+ record types that should remain are empty, and imply that
+ the entire structure should be zeroed. */
+ if (CONSTRUCTOR_ELTS (base))
+ abort ();
+ return convert (TREE_TYPE (field), integer_zero_node);
+
+ default:
+ /* Avoid sharing BASE when building the different COMPONENT_REFs.
+ We let the first field have the original version. */
+ if (field != TYPE_FIELDS (TREE_TYPE (base)))
+ base = unshare_expr (base);
+ break;
+
+ case VAR_DECL:
+ case PARM_DECL:
+ /* Special case for the above -- decls are always shared. */
+ break;
+ }
+
+ return build (COMPONENT_REF, TREE_TYPE (field), base, field);
+}
+
+/* Similarly for REALPART_EXPR and IMAGPART_EXPR for complex types. */
+
+static tree
+csc_build_complex_part (tree base, enum tree_code part)
+{
+ switch (TREE_CODE (base))
+ {
+ case COMPLEX_CST:
+ if (part == REALPART_EXPR)
+ return TREE_REALPART (base);
+ else
+ return TREE_IMAGPART (base);
+
+ case COMPLEX_EXPR:
+ if (part == REALPART_EXPR)
+ return TREE_OPERAND (base, 0);
+ else
+ return TREE_OPERAND (base, 1);
+
+ default:
+ /* Avoid sharing BASE when building the different references.
+ We let the real part have the original version. */
+ if (part != REALPART_EXPR)
+ base = unshare_expr (base);
+ break;
+
+ case VAR_DECL:
+ case PARM_DECL:
+ /* Special case for the above -- decls are always shared. */
+ break;
+ }
+
+ return build1 (part, TREE_TYPE (TREE_TYPE (base)), base);
+}
+
+/* Create and return a list of assignments to perform a scalarized
+ structure assignment 'LHS = RHS'. Both LHS and RHS are assumed to be
+ of an aggregate or complex type. Three types of copies may be specified:
+
+ SCALAR_SCALAR will emit assignments for all the scalar temporaries
+ corresponding to the fields of LHS and RHS.
+
+ FIELD_SCALAR will emit assignments from the scalar replacements of
+ RHS into each of the fields of the LHS.
+
+ SCALAR_FIELD will emit assignments from each field of the RHS into
+ the scalar replacements of the LHS. */
+
+static tree
+create_scalar_copies (tree lhs, tree rhs, enum sra_copy_mode mode)
+{
+ tree type, list;
+ tree_stmt_iterator tsi;
+
+#if defined ENABLE_CHECKING
+ /* Sanity checking. Check that we are not trying to scalarize a
+ non-decl. */
+ if (!DECL_P (lhs) && (mode == SCALAR_FIELD || mode == SCALAR_SCALAR))
+ abort ();
+ if (!DECL_P (rhs) && (mode == FIELD_SCALAR || mode == SCALAR_SCALAR))
+ abort ();
+#endif
+
+ type = TREE_TYPE (lhs);
+ list = alloc_stmt_list ();
+ tsi = tsi_start (list);
+
+ /* VA_ARG_EXPRs have side effects, so we need to copy it first to a
+ temporary before scalarizing. FIXME: This should disappear once
+ VA_ARG_EXPRs are properly lowered. */
+ if (TREE_CODE (rhs) == VA_ARG_EXPR)
+ {
+ tree stmt, tmp;
+
+ /* Add TMP = VA_ARG_EXPR <> */
+ tmp = make_rename_temp (TREE_TYPE (rhs), NULL);
+ stmt = csc_assign (&tsi, tmp, rhs);
+
+ /* Mark all the variables in VDEF operands for renaming, because
+ the VA_ARG_EXPR will now be in a different statement. */
+ mark_all_vdefs (stmt);
+
+ /* Set RHS to be the new temporary TMP. */
+ rhs = tmp;
+ }
+
+ /* When making *_SCALAR copies from PARM_DECLs, we will need to insert
+ copy-in operations from the original PARM_DECLs. Note that these
+ copy-in operations may end up being dead, but we won't know until
+ we rename the new variables into SSA. */
+ if ((mode == SCALAR_SCALAR || mode == FIELD_SCALAR)
+ && TREE_CODE (rhs) == PARM_DECL)
+ bitmap_set_bit (needs_copy_in, var_ann (rhs)->uid);
+
+ /* Now create scalar copies for each individual field according to MODE. */
+ if (TREE_CODE (type) == COMPLEX_TYPE)
+ {
+ /* Create scalar copies of both the real and imaginary parts. */
+ tree real_lhs, real_rhs, imag_lhs, imag_rhs;
+
+ if (mode == SCALAR_FIELD)
+ {
+ real_rhs = csc_build_complex_part (rhs, REALPART_EXPR);
+ imag_rhs = csc_build_complex_part (rhs, IMAGPART_EXPR);
+ }
+ else
+ {
+ real_rhs = get_scalar_for_complex_part (rhs, REALPART_EXPR);
+ imag_rhs = get_scalar_for_complex_part (rhs, IMAGPART_EXPR);
+ }
+
+ if (mode == FIELD_SCALAR)
+ {
+ /* In this case we do not need to create but one statement,
+ since we can create a new complex value whole. */
+
+ if (TREE_CONSTANT (real_rhs) && TREE_CONSTANT (imag_rhs))
+ rhs = build_complex (type, real_rhs, imag_rhs);
+ else
+ rhs = build (COMPLEX_EXPR, type, real_rhs, imag_rhs);
+ csc_assign (&tsi, lhs, rhs);
+ }
+ else
+ {
+ real_lhs = get_scalar_for_complex_part (lhs, REALPART_EXPR);
+ imag_lhs = get_scalar_for_complex_part (lhs, IMAGPART_EXPR);
+
+ csc_assign (&tsi, real_lhs, real_rhs);
+ csc_assign (&tsi, imag_lhs, imag_rhs);
+ }
+ }
+ else
+ {
+ tree lf, rf;
+
+ /* ??? C++ generates copies between different pointer-to-member
+ structures of different types. To combat this, we must track
+ the field of both the left and right structures, so that we
+ index the variables with fields of their own type. */
+
+ for (lf = TYPE_FIELDS (type), rf = TYPE_FIELDS (TREE_TYPE (rhs));
+ lf;
+ lf = TREE_CHAIN (lf), rf = TREE_CHAIN (rf))
+ {
+ tree lhs_var, rhs_var;
+
+ /* Only copy FIELD_DECLs. */
+ if (TREE_CODE (lf) != FIELD_DECL)
+ continue;
+
+ if (mode == FIELD_SCALAR)
+ lhs_var = csc_build_component_ref (lhs, lf);
+ else
+ lhs_var = get_scalar_for_field (lhs, lf);
+
+ if (mode == SCALAR_FIELD)
+ rhs_var = csc_build_component_ref (rhs, rf);
+ else
+ rhs_var = get_scalar_for_field (rhs, rf);
+
+ csc_assign (&tsi, lhs_var, rhs_var);
+ }
+ }
+
+ /* All the scalar copies just created will either create new definitions
+ or remove existing definitions of LHS, so we need to mark it for
+ renaming. */
+ if (TREE_SIDE_EFFECTS (list))
+ {
+ if (mode == SCALAR_FIELD || mode == SCALAR_SCALAR)
+ {
+ /* If the LHS has been scalarized, mark it for renaming. */
+ bitmap_set_bit (vars_to_rename, var_ann (lhs)->uid);
+ }
+ else if (mode == FIELD_SCALAR)
+ {
+ /* Otherwise, mark all the symbols in the VDEFs for the last
+ scalarized statement just created. Since all the statements
+ introduce the same VDEFs, we only need to check the last one. */
+ mark_all_vdefs (tsi_stmt (tsi));
+ }
+ else
+ abort ();
+ }
+
+ return list;
+}
+
+/* A helper function that creates the copies, updates line info,
+ and emits the code either before or after BSI. */
+
+static void
+emit_scalar_copies (block_stmt_iterator *bsi, tree lhs, tree rhs,
+ enum sra_copy_mode mode)
+{
+ tree list = create_scalar_copies (lhs, rhs, mode);
+ tree stmt = bsi_stmt (*bsi);
+
+ if (EXPR_HAS_LOCATION (stmt))
+ annotate_all_with_locus (&list, EXPR_LOCATION (stmt));
+
+ bsi_insert_before (bsi, list, BSI_SAME_STMT);
+}
+
+/* Traverse all the statements in the function replacing references to
+ scalarizable structures with their corresponding scalar temporaries. */
+
+static void
+scalarize_structures (void)
+{
+ basic_block bb;
+ block_stmt_iterator si;
+ size_t i;
+
+ FOR_EACH_BB (bb)
+ for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ {
+ tree stmt;
+ stmt_ann_t ann;
+
+ stmt = bsi_stmt (si);
+ ann = stmt_ann (stmt);
+
+ /* If the statement has no virtual operands, then it doesn't make
+ structure references that we care about. */
+ if (NUM_VDEFS (VDEF_OPS (ann)) == 0
+ && NUM_VUSES (VUSE_OPS (ann)) == 0)
+ continue;
+
+ /* Structure references may only appear in certain statements. */
+ if (TREE_CODE (stmt) != MODIFY_EXPR
+ && TREE_CODE (stmt) != CALL_EXPR
+ && TREE_CODE (stmt) != RETURN_EXPR
+ && TREE_CODE (stmt) != ASM_EXPR)
+ continue;
+
+ scalarize_stmt (&si);
+ }
+
+ /* Initialize the scalar replacements for every structure that is a
+ function argument. */
+ EXECUTE_IF_SET_IN_BITMAP (needs_copy_in, 0, i,
+ {
+ tree var = referenced_var (i);
+ tree list = create_scalar_copies (var, var, SCALAR_FIELD);
+ bsi_insert_on_edge (ENTRY_BLOCK_PTR->succ, list);
+ });
+
+ /* Commit edge insertions. */
+ bsi_commit_edge_inserts (NULL);
+}
+
+
+/* Scalarize structure references in the statement pointed by SI_P. */
+
+static void
+scalarize_stmt (block_stmt_iterator *si_p)
+{
+ tree stmt = bsi_stmt (*si_p);
+
+ /* Handle assignments. */
+ if (TREE_CODE (stmt) == MODIFY_EXPR
+ && TREE_CODE (TREE_OPERAND (stmt, 1)) != CALL_EXPR)
+ scalarize_modify_expr (si_p);
+
+ /* Handle RETURN_EXPR. */
+ else if (TREE_CODE (stmt) == RETURN_EXPR)
+ scalarize_return_expr (si_p);
+
+ /* Handle function calls (note that this must be handled after
+ MODIFY_EXPR and RETURN_EXPR because a function call can appear in
+ both). */
+ else if (get_call_expr_in (stmt) != NULL_TREE)
+ scalarize_call_expr (si_p);
+
+ /* Handle ASM_EXPRs. */
+ else if (TREE_CODE (stmt) == ASM_EXPR)
+ scalarize_asm_expr (si_p);
+}
+
+
+/* Helper for scalarize_stmt to handle assignments. */
+
+static void
+scalarize_modify_expr (block_stmt_iterator *si_p)
+{
+ tree stmt = bsi_stmt (*si_p);
+ tree lhs = TREE_OPERAND (stmt, 0);
+ tree rhs = TREE_OPERAND (stmt, 1);
+
+ /* Found AGGREGATE.FIELD = ... */
+ if (is_sra_candidate_ref (lhs, false))
+ {
+ tree sym;
+ vdef_optype vdefs;
+
+ scalarize_component_ref (stmt, &TREE_OPERAND (stmt, 0));
+
+ /* Mark the LHS to be renamed, as we have just removed the previous
+ VDEF for AGGREGATE. The statement should have exactly one VDEF
+ for variable AGGREGATE. */
+ vdefs = STMT_VDEF_OPS (stmt);
+ if (NUM_VDEFS (vdefs) != 1)
+ abort ();
+ sym = SSA_NAME_VAR (VDEF_RESULT (vdefs, 0));
+ bitmap_set_bit (vars_to_rename, var_ann (sym)->uid);
+ }
+
+ /* Found ... = AGGREGATE.FIELD */
+ else if (is_sra_candidate_ref (rhs, false))
+ scalarize_component_ref (stmt, &TREE_OPERAND (stmt, 1));
+
+ /* Found ... = BIT_FIELD_REF <>. This is similar to a CALL_EXPR, if the
+ operand of the BIT_FIELD_REF is a scalarizable structure, we need to
+ copy from its scalar replacements before doing the bitfield operation.
+
+ FIXME: BIT_FIELD_REFs are often generated by fold-const.c. This is
+ not always desirable because they obfuscate the original predicates,
+ limiting what the tree optimizers may do. For instance, in
+ testsuite/g++.dg/opt/nrv4.C the use of SRA allows the optimizers to
+ optimize function main() to 'return 0;'. However, the folder
+ generates a BIT_FIELD_REF operation for one of the comparisons,
+ preventing the optimizers from removing all the redundant
+ operations. */
+ else if (is_sra_candidate_ref (rhs, true))
+ {
+ tree var = TREE_OPERAND (rhs, 0);
+ emit_scalar_copies (si_p, var, var, FIELD_SCALAR);
+ }
+
+ /* Found AGGREGATE = ... or ... = AGGREGATE */
+ else if (DECL_P (lhs) || DECL_P (rhs))
+ scalarize_structure_assignment (si_p);
+}
+
+
+/* Scalarize structure references in LIST. Use DONE to avoid duplicates. */
+
+static inline void
+scalarize_tree_list (tree list, block_stmt_iterator *si_p, bitmap done)
+{
+ tree op;
+
+ for (op = list; op; op = TREE_CHAIN (op))
+ {
+ tree arg = TREE_VALUE (op);
+
+ if (is_sra_candidate_decl (arg))
+ {
+ int index = var_ann (arg)->uid;
+ if (!bitmap_bit_p (done, index))
+ {
+ emit_scalar_copies (si_p, arg, arg, FIELD_SCALAR);
+ bitmap_set_bit (done, index);
+ }
+ }
+ else if (is_sra_candidate_ref (arg, false))
+ {
+ tree stmt = bsi_stmt (*si_p);
+ scalarize_component_ref (stmt, &TREE_VALUE (op));
+ }
+ }
+}
+
+
+/* Helper for scalarize_stmt to handle function calls. */
+
+static void
+scalarize_call_expr (block_stmt_iterator *si_p)
+{
+ tree stmt = bsi_stmt (*si_p);
+ tree call = (TREE_CODE (stmt) == MODIFY_EXPR) ? TREE_OPERAND (stmt, 1) : stmt;
+ struct bitmap_head_def done_head;
+
+ /* First scalarize the arguments. Order is important, because the copy
+ operations for the arguments need to go before the call.
+ Scalarization of the return value needs to go after the call. */
+ bitmap_initialize (&done_head, 1);
+ scalarize_tree_list (TREE_OPERAND (call, 1), si_p, &done_head);
+ bitmap_clear (&done_head);
+
+ /* Scalarize the return value, if any. */
+ if (TREE_CODE (stmt) == MODIFY_EXPR)
+ {
+ tree var = TREE_OPERAND (stmt, 0);
+
+ /* If the LHS of the assignment is a scalarizable structure, insert
+ copies into the scalar replacements after the call. */
+ if (is_sra_candidate_decl (var))
+ {
+ tree list = create_scalar_copies (var, var, SCALAR_FIELD);
+ if (EXPR_HAS_LOCATION (stmt))
+ annotate_all_with_locus (&list, EXPR_LOCATION (stmt));
+ if (stmt_ends_bb_p (stmt))
+ insert_edge_copies (list, bb_for_stmt (stmt));
+ else
+ bsi_insert_after (si_p, list, BSI_NEW_STMT);
+ }
+ }
+}
+
+
+/* Helper for scalarize_stmt to handle ASM_EXPRs. */
+
+static void
+scalarize_asm_expr (block_stmt_iterator *si_p)
+{
+ tree stmt = bsi_stmt (*si_p);
+ struct bitmap_head_def done_head;
+
+ bitmap_initialize (&done_head, 1);
+ scalarize_tree_list (ASM_INPUTS (stmt), si_p, &done_head);
+ scalarize_tree_list (ASM_OUTPUTS (stmt), si_p, &done_head);
+ bitmap_clear (&done_head);
+
+ /* ??? Process outputs after the asm. */
+}
+
+
+/* Helper for scalarize_stmt to handle return expressions. */
+
+static void
+scalarize_return_expr (block_stmt_iterator *si_p)
+{
+ tree stmt = bsi_stmt (*si_p);
+ tree op = TREE_OPERAND (stmt, 0);
+
+ if (op == NULL_TREE)
+ return;
+
+ /* Handle a bare RESULT_DECL. This will handle for types needed
+ constructors, or possibly after NRV type optimizations. */
+ if (is_sra_candidate_decl (op))
+ emit_scalar_copies (si_p, op, op, FIELD_SCALAR);
+ else if (TREE_CODE (op) == MODIFY_EXPR)
+ {
+ tree *rhs_p = &TREE_OPERAND (op, 1);
+ tree rhs = *rhs_p;
+
+ /* Handle 'return STRUCTURE;' */
+ if (is_sra_candidate_decl (rhs))
+ emit_scalar_copies (si_p, rhs, rhs, FIELD_SCALAR);
+
+ /* Handle 'return STRUCTURE.FIELD;' */
+ else if (is_sra_candidate_ref (rhs, false))
+ scalarize_component_ref (stmt, rhs_p);
+
+ /* Handle 'return CALL_EXPR;' */
+ else if (TREE_CODE (rhs) == CALL_EXPR)
+ {
+ struct bitmap_head_def done_head;
+ bitmap_initialize (&done_head, 1);
+ scalarize_tree_list (TREE_OPERAND (rhs, 1), si_p, &done_head);
+ bitmap_clear (&done_head);
+ }
+ }
+}
+
+
+/* Debugging dump for the scalar replacement map. */
+
+static int
+dump_sra_map_trav (void **slot, void *data)
+{
+ struct sra_elt *e = *slot;
+ FILE *f = data;
+
+ switch (e->kind)
+ {
+ case REALPART_EXPR:
+ fputs ("__real__ ", f);
+ print_generic_expr (dump_file, e->base, dump_flags);
+ fprintf (f, " -> %s\n", get_name (e->replace));
+ break;
+ case IMAGPART_EXPR:
+ fputs ("__imag__ ", f);
+ print_generic_expr (dump_file, e->base, dump_flags);
+ fprintf (f, " -> %s\n", get_name (e->replace));
+ break;
+ case COMPONENT_REF:
+ print_generic_expr (dump_file, e->base, dump_flags);
+ fprintf (f, ".%s -> %s\n", get_name (e->field), get_name (e->replace));
+ break;
+ default:
+ abort ();
+ }
+
+ return 1;
+}
+
+static void
+dump_sra_map (FILE *f)
+{
+ fputs ("Scalar replacements:\n", f);
+ htab_traverse_noresize (sra_map, dump_sra_map_trav, f);
+ fputs ("\n\n", f);
+}
+
+/* Main entry point to Scalar Replacement of Aggregates (SRA). This pass
+ re-writes non-aliased structure references into scalar temporaries. The
+ goal is to expose some/all structures to the scalar optimizers.
+
+ FNDECL is the function to process.
+
+ VARS_TO_RENAME_P is a pointer to the set of variables that need to be
+ renamed into SSA after this pass is done. These are going to be all the
+ new scalars created by the SRA process. Notice that since this pass
+ creates new variables, the bitmap representing all the variables in the
+ program will be re-sized here.
+
+ PHASE indicates which dump file from the DUMP_FILES array to use when
+ dumping debugging information.
+
+ TODO
+
+ 1- Scalarize COMPLEX_TYPEs
+ 2- Scalarize ARRAY_REFs that are always referenced with a
+ constant index.
+ 3- Timings to determine when scalarization is not profitable.
+ 4- Determine what's a good value for MAX_NFIELDS_FOR_SRA. */
+
+static void
+tree_sra (void)
+{
+ /* Initialize local variables. */
+ sra_candidates = BITMAP_XMALLOC ();
+ sra_map = NULL;
+ needs_copy_in = NULL;
+
+ /* Find structures to be scalarized. */
+ if (!find_candidates_for_sra ())
+ {
+ BITMAP_XFREE (sra_candidates);
+ return;
+ }
+
+ /* If we found any, re-write structure references with their
+ corresponding scalar replacement. */
+ sra_map = htab_create (101, sra_elt_hash, sra_elt_eq, free);
+ needs_copy_in = BITMAP_XMALLOC ();
+
+ scalarize_structures ();
+
+ if (dump_file)
+ dump_sra_map (dump_file);
+
+ /* Free allocated memory. */
+ htab_delete (sra_map);
+ sra_map = NULL;
+ BITMAP_XFREE (needs_copy_in);
+ BITMAP_XFREE (sra_candidates);
+}
+
+static bool
+gate_sra (void)
+{
+ return flag_tree_sra != 0;
+}
+
+struct tree_opt_pass pass_sra =
+{
+ "sra", /* name */
+ gate_sra, /* gate */
+ tree_sra, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_SRA, /* tv_id */
+ PROP_cfg | PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func | TODO_rename_vars
+ | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */
+};
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
new file mode 100644
index 00000000000..2bcb4efec9b
--- /dev/null
+++ b/gcc/tree-ssa-alias.c
@@ -0,0 +1,2118 @@
+/* Alias analysis for trees.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ Contributed by Diego Novillo <dnovillo@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "timevar.h"
+#include "expr.h"
+#include "ggc.h"
+#include "langhooks.h"
+#include "flags.h"
+#include "function.h"
+#include "diagnostic.h"
+#include "tree-dump.h"
+#include "tree-gimple.h"
+#include "tree-flow.h"
+#include "tree-inline.h"
+#include "tree-alias-common.h"
+#include "tree-pass.h"
+#include "convert.h"
+#include "params.h"
+
+
+/* Structure to map a variable to its alias set and keep track of the
+ virtual operands that will be needed to represent it. */
+struct alias_map_d
+{
+ /* Variable and its alias set. */
+ tree var;
+ HOST_WIDE_INT set;
+
+ /* Total number of virtual operands that will be needed to represent
+ all the aliases of VAR. */
+ long total_alias_vops;
+
+ /* Nonzero if the aliases for this memory tag have been grouped
+ already. Used in group_aliases. */
+ unsigned int grouped_p : 1;
+
+ /* Set of variables aliased with VAR. This is the exact same
+ information contained in VAR_ANN (VAR)->MAY_ALIASES, but in
+ bitmap form to speed up alias grouping. */
+ sbitmap may_aliases;
+};
+
+
+/* Alias information used by compute_may_aliases and its helpers. */
+struct alias_info
+{
+ /* SSA names visited while collecting points-to information. If bit I
+ is set, it means that SSA variable with version I has already been
+ visited. */
+ bitmap ssa_names_visited;
+
+ /* Array of SSA_NAME pointers processed by the points-to collector. */
+ varray_type processed_ptrs;
+
+ /* Variables whose address is still needed. */
+ bitmap addresses_needed;
+
+ /* ADDRESSABLE_VARS contains all the global variables and locals that
+ have had their address taken. */
+ struct alias_map_d **addressable_vars;
+ size_t num_addressable_vars;
+
+ /* POINTERS contains all the _DECL pointers with unique memory tags
+ that have been referenced in the program. */
+ struct alias_map_d **pointers;
+ size_t num_pointers;
+
+ /* Number of function calls found in the program. */
+ size_t num_calls_found;
+
+ /* Array of counters to keep track of how many times each pointer has
+ been dereferenced in the program. This is used by the alias grouping
+ heuristic in compute_flow_insensitive_aliasing. */
+ varray_type num_references;
+
+ /* Total number of virtual operands that will be needed to represent
+ all the aliases of all the pointers found in the program. */
+ long total_alias_vops;
+
+ /* Variables that have been written to. */
+ bitmap written_vars;
+
+ /* Pointers that have been used in an indirect store operation. */
+ bitmap dereferenced_ptrs_store;
+
+ /* Pointers that have been used in an indirect load operation. */
+ bitmap dereferenced_ptrs_load;
+};
+
+
+/* Counters used to display statistics on alias analysis. */
+struct alias_stats_d
+{
+ unsigned int alias_queries;
+ unsigned int alias_mayalias;
+ unsigned int alias_noalias;
+ unsigned int simple_queries;
+ unsigned int simple_resolved;
+ unsigned int tbaa_queries;
+ unsigned int tbaa_resolved;
+ unsigned int pta_queries;
+ unsigned int pta_resolved;
+};
+
+
+/* Local variables. */
+static struct alias_stats_d alias_stats;
+
+/* Local functions. */
+static void compute_flow_insensitive_aliasing (struct alias_info *);
+static void dump_alias_stats (FILE *);
+static bool may_alias_p (tree, HOST_WIDE_INT, tree, HOST_WIDE_INT);
+static tree create_memory_tag (tree type, bool is_type_tag);
+static tree get_tmt_for (tree, struct alias_info *);
+static tree get_nmt_for (tree);
+static void add_may_alias (tree, tree);
+static struct alias_info *init_alias_info (void);
+static void delete_alias_info (struct alias_info *);
+static void compute_points_to_and_addr_escape (struct alias_info *);
+static void compute_flow_sensitive_aliasing (struct alias_info *);
+static void setup_pointers_and_addressables (struct alias_info *);
+static bool collect_points_to_info_r (tree, tree, void *);
+static bool is_escape_site (tree, size_t *);
+static void add_pointed_to_var (struct alias_info *, tree, tree);
+static void add_pointed_to_expr (tree, tree);
+static void create_global_var (void);
+static void collect_points_to_info_for (struct alias_info *, tree);
+static bool ptr_is_dereferenced_by (tree, tree, bool *);
+static void maybe_create_global_var (struct alias_info *ai);
+static void group_aliases (struct alias_info *);
+
+/* Global declarations. */
+
+/* Call clobbered variables in the function. If bit I is set, then
+ REFERENCED_VARS (I) is call-clobbered. */
+bitmap call_clobbered_vars;
+
+/* 'true' after aliases have been computed (see compute_may_aliases). This
+ is used by get_stmt_operands and its helpers to determine what to do
+ when scanning an operand for a variable that may be aliased. If
+ may-alias information is still not available, the statement is marked as
+ having volatile operands. */
+bool aliases_computed_p;
+
+/* When the program has too many call-clobbered variables and call-sites,
+ this variable is used to represent the clobbering effects of function
+ calls. In these cases, all the call clobbered variables in the program
+ are forced to alias this variable. This reduces compile times by not
+ having to keep track of too many VDEF expressions at call sites. */
+tree global_var;
+
+
+/* Compute may-alias information for every variable referenced in function
+ FNDECL.
+
+ Alias analysis proceeds in 3 main phases:
+
+ 1- Points-to and escape analysis.
+
+ This phase walks the use-def chains in the SSA web looking for three
+ things:
+
+ * Assignments of the form P_i = &VAR
+ * Assignments of the form P_i = malloc()
+ * Pointers and ADDR_EXPR that escape the current function.
+
+ The concept of 'escaping' is the same one used in the Java world. When
+ a pointer or an ADDR_EXPR escapes, it means that it has been exposed
+ outside of the current function. So, assignment to global variables,
+ function arguments and returning a pointer are all escape sites.
+
+ This is where we are currently limited. Since not everything is renamed
+ into SSA, we lose track of escape properties when a pointer is stashed
+ inside a field in a structure, for instance. In those cases, we are
+ assuming that the pointer does escape.
+
+ We use escape analysis to determine whether a variable is
+ call-clobbered. Simply put, if an ADDR_EXPR escapes, then the variable
+ is call-clobbered. If a pointer P_i escapes, then all the variables
+ pointed-to by P_i (and its memory tag) also escape.
+
+ 2- Compute flow-sensitive aliases
+
+ We have two classes of memory tags. Memory tags associated with the
+ pointed-to data type of the pointers in the program. These tags are
+ called "type memory tag" (TMT). The other class are those associated
+ with SSA_NAMEs, called "name memory tag" (NMT). The basic idea is that
+ when adding operands for an INDIRECT_REF *P_i, we will first check
+ whether P_i has a name tag, if it does we use it, because that will have
+ more precise aliasing information. Otherwise, we use the standard type
+ tag.
+
+ In this phase, we go through all the pointers we found in points-to
+ analysis and create alias sets for the name memory tags associated with
+ each pointer P_i. If P_i escapes, we mark call-clobbered the variables
+ it points to and its tag.
+
+
+ 3- Compute flow-insensitive aliases
+
+ This pass will compare the alias set of every type memory tag and every
+ addressable variable found in the program. Given a type memory tag TMT
+ and an addressable variable V. If the alias sets of TMT and V conflict
+ (as computed by may_alias_p), then V is marked as an alias tag and added
+ to the alias set of TMT.
+
+ For instance, consider the following function:
+
+ foo (int i)
+ {
+ int *p, *q, a, b;
+
+ if (i > 10)
+ p = &a;
+ else
+ q = &b;
+
+ *p = 3;
+ *q = 5;
+ a = b + 2;
+ return *p;
+ }
+
+ After aliasing analysis has finished, the type memory tag for pointer
+ 'p' will have two aliases, namely variables 'a' and 'b'. Every time
+ pointer 'p' is dereferenced, we want to mark the operation as a
+ potential reference to 'a' and 'b'.
+
+ foo (int i)
+ {
+ int *p, a, b;
+
+ if (i_2 > 10)
+ p_4 = &a;
+ else
+ p_6 = &b;
+ # p_1 = PHI <p_4(1), p_6(2)>;
+
+ # a_7 = VDEF <a_3>;
+ # b_8 = VDEF <b_5>;
+ *p_1 = 3;
+
+ # a_9 = VDEF <a_7>
+ # VUSE <b_8>
+ a_9 = b_8 + 2;
+
+ # VUSE <a_9>;
+ # VUSE <b_8>;
+ return *p_1;
+ }
+
+ In certain cases, the list of may aliases for a pointer may grow too
+ large. This may cause an explosion in the number of virtual operands
+ inserted in the code. Resulting in increased memory consumption and
+ compilation time.
+
+ When the number of virtual operands needed to represent aliased
+ loads and stores grows too large (configurable with @option{--param
+ max-aliased-vops}), alias sets are grouped to avoid severe
+ compile-time slow downs and memory consumption. See group_aliases. */
+
+static void
+compute_may_aliases (void)
+{
+ struct alias_info *ai;
+
+ memset (&alias_stats, 0, sizeof (alias_stats));
+
+ /* Initialize aliasing information. */
+ ai = init_alias_info ();
+
+ /* For each pointer P_i, determine the sets of variables that P_i may
+ point-to. For every addressable variable V, determine whether the
+ address of V escapes the current function, making V call-clobbered
+ (i.e., whether &V is stored in a global variable or if its passed as a
+ function call argument). */
+ compute_points_to_and_addr_escape (ai);
+
+ /* Collect all pointers and addressable variables, compute alias sets,
+ create memory tags for pointers and promote variables whose address is
+ not needed anymore. */
+ setup_pointers_and_addressables (ai);
+
+ /* Compute flow-sensitive, points-to based aliasing for all the name
+ memory tags. Note that this pass needs to be done before flow
+ insensitive analysis because it uses the points-to information
+ gathered before to mark call-clobbered type tags. */
+ compute_flow_sensitive_aliasing (ai);
+
+ /* Compute type-based flow-insensitive aliasing for all the type
+ memory tags. */
+ compute_flow_insensitive_aliasing (ai);
+
+ /* If the program has too many call-clobbered variables and/or function
+ calls, create .GLOBAL_VAR and use it to model call-clobbering
+ semantics at call sites. This reduces the number of virtual operands
+ considerably, improving compile times at the expense of lost
+ aliasing precision. */
+ maybe_create_global_var (ai);
+
+ /* Debugging dumps. */
+ if (dump_file)
+ {
+ dump_referenced_vars (dump_file);
+ if (dump_flags & TDF_STATS)
+ dump_alias_stats (dump_file);
+ dump_points_to_info (dump_file);
+ dump_alias_info (dump_file);
+ }
+
+ /* Deallocate memory used by aliasing data structures. */
+ delete_alias_info (ai);
+
+ /* Indicate that may-alias information is now available. */
+ aliases_computed_p = true;
+}
+
+struct tree_opt_pass pass_may_alias =
+{
+ "alias", /* name */
+ NULL, /* gate */
+ compute_may_aliases, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_MAY_ALIAS, /* tv_id */
+ PROP_cfg | PROP_ssa | PROP_pta, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func | TODO_rename_vars
+ | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */
+};
+
+
+/* Initialize the data structures used for alias analysis. */
+
+static struct alias_info *
+init_alias_info (void)
+{
+ struct alias_info *ai;
+
+ ai = xcalloc (1, sizeof (struct alias_info));
+ ai->ssa_names_visited = BITMAP_XMALLOC ();
+ VARRAY_TREE_INIT (ai->processed_ptrs, 50, "processed_ptrs");
+ ai->addresses_needed = BITMAP_XMALLOC ();
+ VARRAY_UINT_INIT (ai->num_references, num_referenced_vars, "num_references");
+ ai->written_vars = BITMAP_XMALLOC ();
+ ai->dereferenced_ptrs_store = BITMAP_XMALLOC ();
+ ai->dereferenced_ptrs_load = BITMAP_XMALLOC ();
+
+ return ai;
+}
+
+
+/* Deallocate memory used by alias analysis. */
+
+static void
+delete_alias_info (struct alias_info *ai)
+{
+ size_t i;
+
+ BITMAP_XFREE (ai->ssa_names_visited);
+ ai->processed_ptrs = NULL;
+ BITMAP_XFREE (ai->addresses_needed);
+
+ for (i = 0; i < ai->num_addressable_vars; i++)
+ {
+ sbitmap_free (ai->addressable_vars[i]->may_aliases);
+ free (ai->addressable_vars[i]);
+ }
+ free (ai->addressable_vars);
+
+ for (i = 0; i < ai->num_pointers; i++)
+ {
+ sbitmap_free (ai->pointers[i]->may_aliases);
+ free (ai->pointers[i]);
+ }
+ free (ai->pointers);
+
+ ai->num_references = NULL;
+ BITMAP_XFREE (ai->written_vars);
+ BITMAP_XFREE (ai->dereferenced_ptrs_store);
+ BITMAP_XFREE (ai->dereferenced_ptrs_load);
+
+ free (ai);
+}
+
+
+/* Walk use-def chains for pointer PTR to determine what variables is PTR
+ pointing to. */
+
+static void
+collect_points_to_info_for (struct alias_info *ai, tree ptr)
+{
+#if defined ENABLE_CHECKING
+ if (!POINTER_TYPE_P (TREE_TYPE (ptr)))
+ abort ();
+#endif
+
+ if (!bitmap_bit_p (ai->ssa_names_visited, SSA_NAME_VERSION (ptr)))
+ {
+ ssa_name_ann_t ann;
+
+ bitmap_set_bit (ai->ssa_names_visited, SSA_NAME_VERSION (ptr));
+ walk_use_def_chains (ptr, collect_points_to_info_r, ai);
+
+ VARRAY_PUSH_TREE (ai->processed_ptrs, ptr);
+
+ /* If we could not determine where PTR was pointing to, clear all the
+ other points-to information. */
+ ann = ssa_name_ann (ptr);
+ if (ann->pt_anything)
+ {
+ ann->pt_malloc = 0;
+ ann->pt_vars = NULL;
+ }
+ }
+}
+
+
+/* Helper for ptr_is_dereferenced_by. Called by walk_tree to look for
+ INDIRECT_REF nodes for the pointer passed in DATA. */
+
+static tree
+find_ptr_dereference (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, void *data)
+{
+ tree ptr = (tree) data;
+
+ if (TREE_CODE (*tp) == INDIRECT_REF
+ && TREE_OPERAND (*tp, 0) == ptr)
+ return *tp;
+
+ return NULL_TREE;
+}
+
+
+/* Return true if STMT contains INDIRECT_REF <PTR>. *IS_STORE is set
+ to 'true' if the dereference is on the LHS of an assignment. */
+
+static bool
+ptr_is_dereferenced_by (tree ptr, tree stmt, bool *is_store)
+{
+ *is_store = false;
+
+ if (TREE_CODE (stmt) == MODIFY_EXPR
+ || (TREE_CODE (stmt) == RETURN_EXPR
+ && TREE_CODE (TREE_OPERAND (stmt, 0)) == MODIFY_EXPR))
+ {
+ tree e, lhs, rhs;
+
+ e = (TREE_CODE (stmt) == RETURN_EXPR) ? TREE_OPERAND (stmt, 0) : stmt;
+ lhs = TREE_OPERAND (e, 0);
+ rhs = TREE_OPERAND (e, 1);
+
+ if (EXPR_P (lhs)
+ && walk_tree (&lhs, find_ptr_dereference, ptr, NULL))
+ {
+ *is_store = true;
+ return true;
+ }
+ else if (EXPR_P (rhs)
+ && walk_tree (&rhs, find_ptr_dereference, ptr, NULL))
+ {
+ return true;
+ }
+ }
+ else if (TREE_CODE (stmt) == ASM_EXPR)
+ {
+ if (walk_tree (&ASM_OUTPUTS (stmt), find_ptr_dereference, ptr, NULL)
+ || walk_tree (&ASM_CLOBBERS (stmt), find_ptr_dereference, ptr, NULL))
+ {
+ *is_store = true;
+ return true;
+ }
+ else if (walk_tree (&ASM_INPUTS (stmt), find_ptr_dereference, ptr, NULL))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+/* Traverse use-def links for all the pointers in the program to collect
+ address escape and points-to information.
+
+ This is loosely based on the same idea described in R. Hasti and S.
+ Horwitz, ``Using static single assignment form to improve
+ flow-insensitive pointer analysis,'' in SIGPLAN Conference on
+ Programming Language Design and Implementation, pp. 97-105, 1998. */
+
+static void
+compute_points_to_and_addr_escape (struct alias_info *ai)
+{
+ basic_block bb;
+ size_t i;
+
+ timevar_push (TV_TREE_PTA);
+
+ FOR_EACH_BB (bb)
+ {
+ bb_ann_t block_ann = bb_ann (bb);
+ block_stmt_iterator si;
+
+ for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ {
+ use_optype uses;
+ def_optype defs;
+ vdef_optype vdefs;
+ stmt_ann_t ann;
+ bitmap addr_taken;
+ tree stmt = bsi_stmt (si);
+ bool stmt_escapes_p = is_escape_site (stmt, &ai->num_calls_found);
+
+ /* Mark all the variables whose address are taken by the
+ statement. Note that this will miss all the addresses taken
+ in PHI nodes (those are discovered while following the use-def
+ chains). */
+ get_stmt_operands (stmt);
+ addr_taken = addresses_taken (stmt);
+ if (addr_taken)
+ EXECUTE_IF_SET_IN_BITMAP (addr_taken, 0, i,
+ {
+ tree var = referenced_var (i);
+ bitmap_set_bit (ai->addresses_needed, var_ann (var)->uid);
+ if (stmt_escapes_p)
+ mark_call_clobbered (var);
+ });
+
+ if (stmt_escapes_p)
+ block_ann->has_escape_site = 1;
+
+ /* Special case for silly ADDR_EXPR tricks. If this
+ statement is an assignment to a non-pointer variable and
+ the RHS takes the address of a variable, assume that the
+ variable on the RHS is call-clobbered. We could add the
+ LHS to the list of "pointers" and follow it to see if it
+ really escapes, but it's not worth the pain. */
+ if (addr_taken
+ && TREE_CODE (stmt) == MODIFY_EXPR
+ && !POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (stmt, 0))))
+ EXECUTE_IF_SET_IN_BITMAP (addr_taken, 0, i,
+ {
+ tree var = referenced_var (i);
+ mark_call_clobbered (var);
+ });
+
+ ann = stmt_ann (stmt);
+ uses = USE_OPS (ann);
+ for (i = 0; i < NUM_USES (uses); i++)
+ {
+ tree op = USE_OP (uses, i);
+ var_ann_t v_ann = var_ann (SSA_NAME_VAR (op));
+ ssa_name_ann_t ptr_ann;
+ bool is_store;
+
+ /* If the operand's variable may be aliased, keep track
+ of how many times we've referenced it. This is used
+ for alias grouping in compute_flow_sensitive_aliasing.
+ Note that we don't need to grow AI->NUM_REFERENCES
+ because we are processing regular variables, not
+ memory tags (the array's initial size is set to
+ NUM_REFERENCED_VARS). */
+ if (may_be_aliased (SSA_NAME_VAR (op)))
+ (VARRAY_UINT (ai->num_references, v_ann->uid))++;
+
+ if (!POINTER_TYPE_P (TREE_TYPE (op)))
+ continue;
+
+ collect_points_to_info_for (ai, op);
+
+ ptr_ann = ssa_name_ann (op);
+ if (ptr_is_dereferenced_by (op, stmt, &is_store))
+ {
+ /* If we found OP to point to a set of variables or
+ malloc, then create a name memory tag for it. This
+ gives more precise aliasing information, which helps
+ the optimizers.
+
+ FIXME: Cycles in the SSA web and the lack of SSA
+ information for structures will prevent the creation
+ of name tags. Find ways around this limitation. */
+ if (ptr_ann->pt_malloc || ptr_ann->pt_vars)
+ ptr_ann->name_mem_tag = get_nmt_for (op);
+
+ /* Keep track of how many time we've dereferenced each
+ pointer. Again, we don't need to grow
+ AI->NUM_REFERENCES because we're processing
+ existing program variables. */
+ (VARRAY_UINT (ai->num_references, v_ann->uid))++;
+
+ /* If this is a store operation, mark OP as being
+ dereferenced to store, otherwise mark it as being
+ dereferenced to load. */
+ if (is_store)
+ bitmap_set_bit (ai->dereferenced_ptrs_store, v_ann->uid);
+ else
+ bitmap_set_bit (ai->dereferenced_ptrs_load, v_ann->uid);
+ }
+ else if (stmt_escapes_p)
+ {
+ /* Note that even if STMT is an escape point, pointer OP
+ will not escape if it is being dereferenced. That's
+ why we only check for escape points if OP is not
+ dereferenced by STMT. */
+ ptr_ann->value_escapes_p = 1;
+
+ /* If the statement makes a function call, assume
+ that pointer OP will be dereferenced in a store
+ operation inside the called function. */
+ if (get_call_expr_in (stmt))
+ bitmap_set_bit (ai->dereferenced_ptrs_store, v_ann->uid);
+ }
+ }
+
+ /* Update reference counter for definitions to any
+ potentially aliased variable. This is used in the alias
+ grouping heuristics. */
+ defs = DEF_OPS (ann);
+ for (i = 0; i < NUM_DEFS (defs); i++)
+ {
+ tree op = DEF_OP (defs, i);
+ tree var = SSA_NAME_VAR (op);
+ var_ann_t ann = var_ann (var);
+ bitmap_set_bit (ai->written_vars, ann->uid);
+ if (may_be_aliased (var))
+ (VARRAY_UINT (ai->num_references, ann->uid))++;
+ }
+
+ /* Mark variables in VDEF operands as being written to. */
+ vdefs = VDEF_OPS (ann);
+ for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ {
+ tree op = VDEF_OP (vdefs, i);
+ tree var = SSA_NAME_VAR (op);
+ var_ann_t ann = var_ann (var);
+ bitmap_set_bit (ai->written_vars, ann->uid);
+ }
+
+ /* After promoting variables and computing aliasing we will
+ need to re-scan most statements. FIXME: Try to minimize the
+ number of statements re-scanned. It's not really necessary to
+ re-scan *all* statements. */
+ modify_stmt (stmt);
+ }
+ }
+
+ timevar_pop (TV_TREE_PTA);
+}
+
+
+/* For every pointer P_i in AI->PROCESSED_PTRS, create may-alias sets for
+ the name memory tag (NMT) associated with P_i. If P_i escapes, then its
+ name tag and the variables it points-to are call-clobbered. Finally, if
+ P_i escapes and we could not determine where it points to, then all the
+ variables in the same alias set as *P_i are marked call-clobbered. This
+ is necessary because we must assume that P_i may take the address of any
+ variable in the same alias set. */
+
+static void
+compute_flow_sensitive_aliasing (struct alias_info *ai)
+{
+ size_t i;
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (ai->processed_ptrs); i++)
+ {
+ size_t j;
+ tree ptr = VARRAY_TREE (ai->processed_ptrs, i);
+ ssa_name_ann_t ann = ssa_name_ann (ptr);
+ var_ann_t v_ann = var_ann (SSA_NAME_VAR (ptr));
+
+ if (ann->value_escapes_p || ann->pt_anything)
+ {
+ /* If PTR escapes or may point to anything, then its associated
+ memory tags are call-clobbered. */
+ if (ann->name_mem_tag)
+ mark_call_clobbered (ann->name_mem_tag);
+
+ if (v_ann->type_mem_tag)
+ mark_call_clobbered (v_ann->type_mem_tag);
+
+ /* If PTR may point to anything, mark call-clobbered all the
+ addressables with the same alias set as the type pointed-to by
+ PTR. */
+ if (ann->pt_anything)
+ {
+ HOST_WIDE_INT ptr_set;
+ ptr_set = get_alias_set (TREE_TYPE (TREE_TYPE (ptr)));
+ for (j = 0; j < ai->num_addressable_vars; j++)
+ {
+ struct alias_map_d *alias_map = ai->addressable_vars[j];
+ if (alias_map->set == ptr_set)
+ mark_call_clobbered (alias_map->var);
+ }
+ }
+
+ /* If PTR's value may escape and PTR is never dereferenced, we
+ need to mark all the variables PTR points-to as
+ call-clobbered. Note that we only need do this it PTR is
+ never dereferenced. If PTR is dereferenced, it will have a
+ name memory tag, which will have been marked call-clobbered.
+ This will in turn mark the pointed-to variables as
+ call-clobbered when we call add_may_alias below. */
+ if (ann->value_escapes_p && !ann->name_mem_tag && ann->pt_vars)
+ EXECUTE_IF_SET_IN_BITMAP (ann->pt_vars, 0, j,
+ mark_call_clobbered (referenced_var (j)));
+ }
+
+ /* Set up aliasing information for PTR's name memory tag (if it has
+ one). Note that only pointers that have been dereferenced will
+ have a name memory tag. */
+ if (ann->name_mem_tag && ann->pt_vars)
+ EXECUTE_IF_SET_IN_BITMAP (ann->pt_vars, 0, j,
+ add_may_alias (ann->name_mem_tag, referenced_var (j)));
+
+ /* If the name tag is call clobbered, so is the type tag
+ associated with the base VAR_DECL. */
+ if (ann->name_mem_tag
+ && v_ann->type_mem_tag
+ && is_call_clobbered (ann->name_mem_tag))
+ mark_call_clobbered (v_ann->type_mem_tag);
+ }
+}
+
+
+/* Compute type-based alias sets. Traverse all the pointers and
+ addressable variables found in setup_pointers_and_addressables.
+
+ For every pointer P in AI->POINTERS and addressable variable V in
+ AI->ADDRESSABLE_VARS, add V to the may-alias sets of P's type
+ memory tag (TMT) if their alias sets conflict. V is then marked as
+ an alias tag so that the operand scanner knows that statements
+ containing V have aliased operands. */
+
+static void
+compute_flow_insensitive_aliasing (struct alias_info *ai)
+{
+ size_t i;
+
+ /* Initialize counter for the total number of virtual operands that
+ aliasing will introduce. When AI->TOTAL_ALIAS_VOPS goes beyond the
+ threshold set by --params max-alias-vops, we enable alias
+ grouping. */
+ ai->total_alias_vops = 0;
+
+ /* For every pointer P, determine which addressable variables may alias
+ with P's type memory tag. */
+ for (i = 0; i < ai->num_pointers; i++)
+ {
+ size_t j;
+ struct alias_map_d *p_map = ai->pointers[i];
+ tree tag = var_ann (p_map->var)->type_mem_tag;
+ var_ann_t tag_ann = var_ann (tag);
+
+ p_map->total_alias_vops = 0;
+ p_map->may_aliases = sbitmap_alloc (num_referenced_vars);
+ sbitmap_zero (p_map->may_aliases);
+
+ for (j = 0; j < ai->num_addressable_vars; j++)
+ {
+ struct alias_map_d *v_map;
+ var_ann_t v_ann;
+ tree var;
+ bool tag_stored_p, var_stored_p;
+
+ v_map = ai->addressable_vars[j];
+ var = v_map->var;
+ v_ann = var_ann (var);
+
+ /* Skip memory tags and variables that have never been
+ written to. We also need to check if the variables are
+ call-clobbered because they may be overwritten by
+ function calls. */
+ tag_stored_p = bitmap_bit_p (ai->written_vars, tag_ann->uid)
+ || is_call_clobbered (tag);
+ var_stored_p = bitmap_bit_p (ai->written_vars, v_ann->uid)
+ || is_call_clobbered (var);
+ if (!tag_stored_p && !var_stored_p)
+ continue;
+
+ if (may_alias_p (p_map->var, p_map->set, var, v_map->set))
+ {
+ size_t num_tag_refs, num_var_refs;
+
+ num_tag_refs = VARRAY_UINT (ai->num_references, tag_ann->uid);
+ num_var_refs = VARRAY_UINT (ai->num_references, v_ann->uid);
+
+ /* Add VAR to TAG's may-aliases set. */
+ add_may_alias (tag, var);
+
+ /* Update the total number of virtual operands due to
+ aliasing. Since we are adding one more alias to TAG's
+ may-aliases set, the total number of virtual operands due
+ to aliasing will be increased by the number of references
+ made to VAR and TAG (every reference to TAG will also
+ count as a reference to VAR). */
+ ai->total_alias_vops += (num_var_refs + num_tag_refs);
+ p_map->total_alias_vops += (num_var_refs + num_tag_refs);
+
+ /* Update the bitmap used to represent TAG's alias set
+ in case we need to group aliases. */
+ SET_BIT (p_map->may_aliases, var_ann (var)->uid);
+ }
+ }
+ }
+
+ if (dump_file)
+ fprintf (dump_file, "%s: Total number of aliased vops: %ld\n",
+ get_name (current_function_decl),
+ ai->total_alias_vops);
+
+ /* Determine if we need to enable alias grouping. */
+ if (ai->total_alias_vops >= MAX_ALIASED_VOPS)
+ group_aliases (ai);
+}
+
+
+/* Comparison function for qsort used in group_aliases. */
+
+static int
+total_alias_vops_cmp (const void *p, const void *q)
+{
+ const struct alias_map_d **p1 = (const struct alias_map_d **)p;
+ const struct alias_map_d **p2 = (const struct alias_map_d **)q;
+ long n1 = (*p1)->total_alias_vops;
+ long n2 = (*p2)->total_alias_vops;
+
+ /* We want to sort in descending order. */
+ return (n1 > n2 ? -1 : (n1 == n2) ? 0 : 1);
+}
+
+/* Group all the aliases for TAG to make TAG represent all the
+ variables in its alias set. Update the total number
+ of virtual operands due to aliasing (AI->TOTAL_ALIAS_VOPS). This
+ function will make TAG be the unique alias tag for all the
+ variables in its may-aliases. So, given:
+
+ may-aliases(TAG) = { V1, V2, V3 }
+
+ This function will group the variables into:
+
+ may-aliases(V1) = { TAG }
+ may-aliases(V2) = { TAG }
+ may-aliases(V2) = { TAG } */
+
+static void
+group_aliases_into (tree tag, sbitmap tag_aliases, struct alias_info *ai)
+{
+ size_t i;
+ var_ann_t tag_ann = var_ann (tag);
+ size_t num_tag_refs = VARRAY_UINT (ai->num_references, tag_ann->uid);
+
+ EXECUTE_IF_SET_IN_SBITMAP (tag_aliases, 0, i,
+ {
+ tree var = referenced_var (i);
+ var_ann_t ann = var_ann (var);
+
+ /* Make TAG the unique alias of VAR. */
+ ann->is_alias_tag = 0;
+ ann->may_aliases = NULL;
+
+ /* Note that VAR and TAG may be the same if the function has no
+ addressable variables (see the discussion at the end of
+ setup_pointers_and_addressables). */
+ if (var != tag)
+ add_may_alias (var, tag);
+
+ /* Reduce total number of virtual operands contributed
+ by TAG on behalf of VAR. Notice that the references to VAR
+ itself won't be removed. We will merely replace them with
+ references to TAG. */
+ ai->total_alias_vops -= num_tag_refs;
+ });
+
+ /* We have reduced the number of virtual operands that TAG makes on
+ behalf of all the variables formerly aliased with it. However,
+ we have also "removed" all the virtual operands for TAG itself,
+ so we add them back. */
+ ai->total_alias_vops += num_tag_refs;
+
+ /* TAG no longer has any aliases. */
+ tag_ann->may_aliases = NULL;
+}
+
+
+/* Group may-aliases sets to reduce the number of virtual operands due
+ to aliasing.
+
+ 1- Sort the list of pointers in decreasing number of contributed
+ virtual operands.
+
+ 2- Take the first entry in AI->POINTERS and revert the role of
+ the memory tag and its aliases. Usually, whenever an aliased
+ variable Vi is found to alias with a memory tag T, we add Vi
+ to the may-aliases set for T. Meaning that after alias
+ analysis, we will have:
+
+ may-aliases(T) = { V1, V2, V3, ..., Vn }
+
+ This means that every statement that references T, will get 'n'
+ virtual operands for each of the Vi tags. But, when alias
+ grouping is enabled, we make T an alias tag and add it to the
+ alias set of all the Vi variables:
+
+ may-aliases(V1) = { T }
+ may-aliases(V2) = { T }
+ ...
+ may-aliases(Vn) = { T }
+
+ This has two effects: (a) statements referencing T will only get
+ a single virtual operand, and, (b) all the variables Vi will now
+ appear to alias each other. So, we lose alias precision to
+ improve compile time. But, in theory, a program with such a high
+ level of aliasing should not be very optimizable in the first
+ place.
+
+ 3- Since variables may be in the alias set of more than one
+ memory tag, the grouping done in step (2) needs to be extended
+ to all the memory tags that have a non-empty intersection with
+ the may-aliases set of tag T. For instance, if we originally
+ had these may-aliases sets:
+
+ may-aliases(T) = { V1, V2, V3 }
+ may-aliases(R) = { V2, V4 }
+
+ In step (2) we would have reverted the aliases for T as:
+
+ may-aliases(V1) = { T }
+ may-aliases(V2) = { T }
+ may-aliases(V3) = { T }
+
+ But note that now V2 is no longer aliased with R. We could
+ add R to may-aliases(V2), but we are in the process of
+ grouping aliases to reduce virtual operands so what we do is
+ add V4 to the grouping to obtain:
+
+ may-aliases(V1) = { T }
+ may-aliases(V2) = { T }
+ may-aliases(V3) = { T }
+ may-aliases(V4) = { T }
+
+ 4- If the total number of virtual operands due to aliasing is
+ still above the threshold set by max-alias-vops, go back to (2). */
+
+static void
+group_aliases (struct alias_info *ai)
+{
+ size_t i;
+ sbitmap res;
+
+ /* Sort the POINTERS array in descending order of contributed
+ virtual operands. */
+ qsort (ai->pointers, ai->num_pointers, sizeof (struct alias_map_d *),
+ total_alias_vops_cmp);
+
+ res = sbitmap_alloc (num_referenced_vars);
+
+ /* For every pointer in AI->POINTERS, reverse the roles of its tag
+ and the tag's may-aliases set. */
+ for (i = 0; i < ai->num_pointers; i++)
+ {
+ size_t j;
+ tree tag1 = var_ann (ai->pointers[i]->var)->type_mem_tag;
+ sbitmap tag1_aliases = ai->pointers[i]->may_aliases;
+
+ /* Skip tags that have been grouped already. */
+ if (ai->pointers[i]->grouped_p)
+ continue;
+
+ /* See if TAG1 had any aliases in common with other type tags.
+ If we find a TAG2 with common aliases with TAG1, add TAG2's
+ aliases into TAG1. */
+ for (j = i + 1; j < ai->num_pointers; j++)
+ {
+ sbitmap tag2_aliases = ai->pointers[j]->may_aliases;
+
+ sbitmap_a_and_b (res, tag1_aliases, tag2_aliases);
+ if (sbitmap_first_set_bit (res) >= 0)
+ {
+ tree tag2 = var_ann (ai->pointers[j]->var)->type_mem_tag;
+
+ sbitmap_a_or_b (tag1_aliases, tag1_aliases, tag2_aliases);
+
+ /* TAG2 does not need its aliases anymore. */
+ sbitmap_zero (tag2_aliases);
+ var_ann (tag2)->may_aliases = NULL;
+
+ /* TAG1 is the unique alias of TAG2. */
+ add_may_alias (tag2, tag1);
+
+ ai->pointers[j]->grouped_p = true;
+ }
+ }
+
+ /* Now group all the aliases we collected into TAG1. */
+ group_aliases_into (tag1, tag1_aliases, ai);
+
+ /* If we've reduced total number of virtual operands below the
+ threshold, stop. */
+ if (ai->total_alias_vops < MAX_ALIASED_VOPS)
+ break;
+ }
+
+ /* Finally, all the variables that have been grouped cannot be in
+ the may-alias set of name memory tags. Suppose that we have
+ grouped the aliases in this code so that may-aliases(a) = TMT.20
+
+ p_5 = &a;
+ ...
+ # a_9 = VDEF <a_8>
+ p_5->field = 0
+ ... Several modifications to TMT.20 ...
+ # VUSE <a_9>
+ x_30 = p_5->field
+
+ Since p_5 points to 'a', the optimizers will try to propagate 0
+ into p_5->field, but that is wrong because there have been
+ modifications to 'TMT.20' in between. To prevent this we have to
+ replace 'a' with 'TMT.20' in the name tag of p_5. */
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (ai->processed_ptrs); i++)
+ {
+ size_t j;
+ tree ptr = VARRAY_TREE (ai->processed_ptrs, i);
+ tree name_tag = ssa_name_ann (ptr)->name_mem_tag;
+ varray_type aliases;
+
+ if (name_tag == NULL_TREE)
+ continue;
+
+ aliases = var_ann (name_tag)->may_aliases;
+ for (j = 0; aliases && j < VARRAY_ACTIVE_SIZE (aliases); j++)
+ {
+ tree alias = VARRAY_TREE (aliases, j);
+ var_ann_t ann = var_ann (alias);
+ if (ann->may_aliases)
+ {
+#if defined ENABLE_CHECKING
+ if (VARRAY_ACTIVE_SIZE (ann->may_aliases) != 1)
+ abort ();
+#endif
+ VARRAY_TREE (aliases, j) = VARRAY_TREE (ann->may_aliases, 0);
+ }
+ }
+ }
+
+ sbitmap_free (res);
+
+ if (dump_file)
+ fprintf (dump_file,
+ "%s: Total number of aliased vops after grouping: %ld%s\n",
+ get_name (current_function_decl),
+ ai->total_alias_vops,
+ (ai->total_alias_vops < 0) ? " (negative values are OK)" : "");
+}
+
+
+/* Create a new alias set entry for VAR in AI->ADDRESSABLE_VARS. */
+
+static void
+create_alias_map_for (tree var, struct alias_info *ai)
+{
+ struct alias_map_d *alias_map;
+ alias_map = xcalloc (1, sizeof (*alias_map));
+ alias_map->var = var;
+
+ if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
+ alias_map->set = get_alias_set (TREE_TYPE (TREE_TYPE (var)));
+ else
+ alias_map->set = get_alias_set (var);
+ ai->addressable_vars[ai->num_addressable_vars++] = alias_map;
+}
+
+
+/* Create memory tags for all the dereferenced pointers and build the
+ ADDRESSABLE_VARS and POINTERS arrays used for building the may-alias
+ sets. Based on the address escape and points-to information collected
+ earlier, this pass will also clear the TREE_ADDRESSABLE flag from those
+ variables whose address is not needed anymore. */
+
+static void
+setup_pointers_and_addressables (struct alias_info *ai)
+{
+ size_t i, n_vars, num_addressable_vars, num_pointers;
+
+ /* Size up the arrays ADDRESSABLE_VARS and POINTERS. */
+ num_addressable_vars = num_pointers = 0;
+ for (i = 0; i < num_referenced_vars; i++)
+ {
+ tree var = referenced_var (i);
+
+ if (may_be_aliased (var))
+ num_addressable_vars++;
+
+ if (POINTER_TYPE_P (TREE_TYPE (var)))
+ {
+ /* Since we don't keep track of volatile variables nor
+ variables with hidden uses, assume that these pointers
+ are used in indirect store operations. */
+ var_ann_t ann = var_ann (var);
+ if (TREE_THIS_VOLATILE (var) || ann->has_hidden_use)
+ bitmap_set_bit (ai->dereferenced_ptrs_store, ann->uid);
+
+ num_pointers++;
+ }
+ }
+
+ /* Create ADDRESSABLE_VARS and POINTERS. Note that these arrays are
+ always going to be slightly bigger than we actually need them
+ because some TREE_ADDRESSABLE variables will be marked
+ non-addressable below and only pointers with unique type tags are
+ going to be added to POINTERS. */
+ ai->addressable_vars = xcalloc (num_addressable_vars,
+ sizeof (struct alias_map_d *));
+ ai->pointers = xcalloc (num_pointers, sizeof (struct alias_map_d *));
+ ai->num_addressable_vars = 0;
+ ai->num_pointers = 0;
+
+ /* Since we will be creating type memory tags within this loop, cache the
+ value of NUM_REFERENCED_VARS to avoid processing the additional tags
+ unnecessarily. */
+ n_vars = num_referenced_vars;
+
+ for (i = 0; i < n_vars; i++)
+ {
+ tree var = referenced_var (i);
+ var_ann_t v_ann = var_ann (var);
+
+ /* Name memory tags already have flow-sensitive aliasing information, so
+ they need not be processed by compute_may_aliases. Similarly,
+ type memory tags are already accounted for when we process their
+ associated pointer. */
+ if (v_ann->mem_tag_kind != NOT_A_TAG)
+ continue;
+
+ /* Remove the ADDRESSABLE flag from every addressable variable whose
+ address is not needed anymore. This is caused by the propagation
+ of ADDR_EXPR constants into INDIRECT_REF expressions and the
+ removal of dead pointer assignments done by the early scalar
+ cleanup passes. */
+ if (TREE_ADDRESSABLE (var))
+ {
+ if (!bitmap_bit_p (ai->addresses_needed, v_ann->uid)
+ && !v_ann->has_hidden_use
+ && v_ann->mem_tag_kind == NOT_A_TAG
+ && !needs_to_live_in_memory (var))
+ {
+ /* The address of VAR is not needed, remove the addressable bit,
+ so that it can be optimized as a regular variable. */
+ mark_non_addressable (var);
+
+ /* Since VAR is now a regular GIMPLE register, we will need
+ to rename VAR into SSA afterwards. */
+ bitmap_set_bit (vars_to_rename, v_ann->uid);
+ }
+ }
+
+ /* Global variables and addressable locals may be aliased. Create an
+ entry in ADDRESSABLE_VARS for VAR. */
+ if (may_be_aliased (var))
+ {
+ create_alias_map_for (var, ai);
+ bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
+ }
+
+ /* Add pointer variables that have been dereferenced to the POINTERS
+ array and create a type memory tag for them. */
+ if (POINTER_TYPE_P (TREE_TYPE (var))
+ && (bitmap_bit_p (ai->dereferenced_ptrs_store, v_ann->uid)
+ || bitmap_bit_p (ai->dereferenced_ptrs_load, v_ann->uid)))
+ {
+ tree tag = v_ann->type_mem_tag;
+ var_ann_t t_ann;
+
+ /* If pointer VAR still doesn't have a memory tag associated with it,
+ create it now or re-use an existing one. */
+ if (tag == NULL_TREE)
+ tag = get_tmt_for (var, ai);
+ t_ann = var_ann (tag);
+
+ /* Associate the tag with pointer VAR. */
+ v_ann->type_mem_tag = tag;
+
+ /* If pointer VAR has been used in a store operation, then its
+ memory tag must be marked as written-to. */
+ if (bitmap_bit_p (ai->dereferenced_ptrs_store, v_ann->uid))
+ bitmap_set_bit (ai->written_vars, t_ann->uid);
+
+ /* If pointer VAR is a global variable or a PARM_DECL, then its
+ memory tag should be considered a global variable. */
+ if (TREE_CODE (var) == PARM_DECL || needs_to_live_in_memory (var))
+ mark_call_clobbered (tag);
+
+ /* All the dereferences of pointer VAR count as references of
+ TAG. Since TAG can be associated with several pointers, add
+ the dereferences of VAR to the TAG. We may need to grow
+ AI->NUM_REFERENCES because we have been adding name and
+ type tags. */
+ if (t_ann->uid >= VARRAY_SIZE (ai->num_references))
+ VARRAY_GROW (ai->num_references, t_ann->uid + 10);
+
+ VARRAY_UINT (ai->num_references, t_ann->uid)
+ += VARRAY_UINT (ai->num_references, v_ann->uid);
+ }
+ }
+
+ /* If we found no addressable variables, but we have more than one
+ pointer, we will need to check for conflicts between the
+ pointers. Otherwise, we would miss alias relations as in
+ testsuite/gcc.dg/tree-ssa/20040319-1.c:
+
+ struct bar { int count; int *arr;};
+
+ void foo (struct bar *b)
+ {
+ b->count = 0;
+ *(b->arr) = 2;
+ if (b->count == 0)
+ abort ();
+ }
+
+ b->count and *(b->arr) could be aliased if b->arr == &b->count.
+ To do this, we add all the memory tags for the pointers in
+ AI->POINTERS to AI->ADDRESSABLE_VARS, so that
+ compute_flow_insensitive_aliasing will naturally compare every
+ pointer to every type tag. */
+ if (ai->num_addressable_vars == 0
+ && ai->num_pointers > 1)
+ {
+ free (ai->addressable_vars);
+ ai->addressable_vars = xcalloc (ai->num_pointers,
+ sizeof (struct alias_map_d *));
+ ai->num_addressable_vars = 0;
+ for (i = 0; i < ai->num_pointers; i++)
+ {
+ struct alias_map_d *p = ai->pointers[i];
+ tree tag = var_ann (p->var)->type_mem_tag;
+ create_alias_map_for (tag, ai);
+ }
+ }
+}
+
+
+/* Determine whether to use .GLOBAL_VAR to model call clobbering semantics. At
+ every call site, we need to emit VDEF expressions to represent the
+ clobbering effects of the call for variables whose address escapes the
+ current function.
+
+ One approach is to group all call-clobbered variables into a single
+ representative that is used as an alias of every call-clobbered variable
+ (.GLOBAL_VAR). This works well, but it ties the optimizer hands because
+ references to any call clobbered variable is a reference to .GLOBAL_VAR.
+
+ The second approach is to emit a clobbering VDEF for every call-clobbered
+ variable at call sites. This is the preferred way in terms of optimization
+ opportunities but it may create too many VDEF operands if there are many
+ call clobbered variables and function calls in the function.
+
+ To decide whether or not to use .GLOBAL_VAR we multiply the number of
+ function calls found by the number of call-clobbered variables. If that
+ product is beyond a certain threshold, as determined by the parameterized
+ values shown below, we use .GLOBAL_VAR.
+
+ FIXME. This heuristic should be improved. One idea is to use several
+ .GLOBAL_VARs of different types instead of a single one. The thresholds
+ have been derived from a typical bootstrap cycle, including all target
+ libraries. Compile times were found increase by ~1% compared to using
+ .GLOBAL_VAR. */
+
+static void
+maybe_create_global_var (struct alias_info *ai)
+{
+ size_t i, n_clobbered;
+
+ /* Count all the call-clobbered variables. */
+ n_clobbered = 0;
+ EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, n_clobbered++);
+
+ /* Create .GLOBAL_VAR if we have too many call-clobbered variables.
+ We also create .GLOBAL_VAR when there no call-clobbered variables
+ to prevent code motion transformations from re-arranging function
+ calls that may have side effects. For instance,
+
+ foo ()
+ {
+ int a = f ();
+ g ();
+ h (a);
+ }
+
+ There are no call-clobbered variables in foo(), so it would be
+ entirely possible for a pass to want to move the call to f()
+ after the call to g(). If f() has side effects, that would be
+ wrong. Creating .GLOBAL_VAR in this case will insert VDEFs for
+ it and prevent such transformations. */
+ if (n_clobbered == 0
+ || ai->num_calls_found * n_clobbered >= (size_t) GLOBAL_VAR_THRESHOLD)
+ create_global_var ();
+
+ /* If the function has calls to clobbering functions and .GLOBAL_VAR has
+ been created, make it an alias for all call-clobbered variables. */
+ if (global_var)
+ EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i,
+ {
+ tree var = referenced_var (i);
+ if (var != global_var)
+ {
+ add_may_alias (var, global_var);
+ bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
+ }
+ });
+}
+
+
+/* Return TRUE if pointer PTR may point to variable VAR.
+
+ MEM_ALIAS_SET is the alias set for the memory location pointed-to by PTR
+ This is needed because when checking for type conflicts we are
+ interested in the alias set of the memory location pointed-to by
+ PTR. The alias set of PTR itself is irrelevant.
+
+ VAR_ALIAS_SET is the alias set for VAR. */
+
+static bool
+may_alias_p (tree ptr, HOST_WIDE_INT mem_alias_set,
+ tree var, HOST_WIDE_INT var_alias_set)
+{
+ tree mem;
+ var_ann_t v_ann, m_ann;
+
+ alias_stats.alias_queries++;
+ alias_stats.simple_queries++;
+
+ /* By convention, a variable cannot alias itself. */
+ mem = var_ann (ptr)->type_mem_tag;
+ if (mem == var)
+ {
+ alias_stats.alias_noalias++;
+ alias_stats.simple_resolved++;
+ return false;
+ }
+
+ v_ann = var_ann (var);
+ m_ann = var_ann (mem);
+
+#if defined ENABLE_CHECKING
+ if (m_ann->mem_tag_kind != TYPE_TAG)
+ abort ();
+#endif
+
+ alias_stats.tbaa_queries++;
+
+ /* If VAR is a pointer with the same alias set as PTR, then dereferencing
+ PTR can't possibly affect VAR. Note, that we are specifically testing
+ for PTR's alias set here, not its pointed-to type. We also can't
+ do this check with relaxed aliasing enabled. */
+ if (POINTER_TYPE_P (TREE_TYPE (var))
+ && var_alias_set != 0)
+ {
+ HOST_WIDE_INT ptr_alias_set = get_alias_set (ptr);
+ if (ptr_alias_set == var_alias_set)
+ {
+ alias_stats.alias_noalias++;
+ alias_stats.tbaa_resolved++;
+ return false;
+ }
+ }
+
+ /* If the alias sets don't conflict then MEM cannot alias VAR. */
+ if (!alias_sets_conflict_p (mem_alias_set, var_alias_set))
+ {
+ /* Handle aliases to structure fields. If either VAR or MEM are
+ aggregate types, they may not have conflicting types, but one of
+ the structures could contain a pointer to the other one.
+
+ For instance, given
+
+ MEM -> struct P *p;
+ VAR -> struct Q *q;
+
+ It may happen that '*p' and '*q' can't alias because 'struct P'
+ and 'struct Q' have non-conflicting alias sets. However, it could
+ happen that one of the fields in 'struct P' is a 'struct Q *' or
+ vice-versa.
+
+ Therefore, we also need to check if 'struct P' aliases 'struct Q *'
+ or 'struct Q' aliases 'struct P *'. Notice, that since GIMPLE
+ does not have more than one-level pointers, we don't need to
+ recurse into the structures. */
+ if (AGGREGATE_TYPE_P (TREE_TYPE (mem))
+ || AGGREGATE_TYPE_P (TREE_TYPE (var)))
+ {
+ tree ptr_to_var;
+
+ if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
+ ptr_to_var = TYPE_POINTER_TO (TREE_TYPE (TREE_TYPE (var)));
+ else
+ ptr_to_var = TYPE_POINTER_TO (TREE_TYPE (var));
+
+ /* If no pointer-to VAR exists, then MEM can't alias VAR. */
+ if (ptr_to_var == NULL_TREE)
+ {
+ alias_stats.alias_noalias++;
+ alias_stats.tbaa_resolved++;
+ return false;
+ }
+
+ /* If MEM doesn't alias a pointer to VAR and VAR doesn't alias
+ PTR, then PTR can't alias VAR. */
+ if (!alias_sets_conflict_p (mem_alias_set, get_alias_set (ptr_to_var))
+ && !alias_sets_conflict_p (var_alias_set, get_alias_set (ptr)))
+ {
+ alias_stats.alias_noalias++;
+ alias_stats.tbaa_resolved++;
+ return false;
+ }
+ }
+ else
+ {
+ alias_stats.alias_noalias++;
+ alias_stats.tbaa_resolved++;
+ return false;
+ }
+ }
+
+ if (flag_tree_points_to != PTA_NONE)
+ alias_stats.pta_queries++;
+
+ /* If -ftree-points-to is given, check if PTR may point to VAR. */
+ if (flag_tree_points_to == PTA_ANDERSEN
+ && !ptr_may_alias_var (ptr, var))
+ {
+ alias_stats.alias_noalias++;
+ alias_stats.pta_resolved++;
+ return false;
+ }
+
+ alias_stats.alias_mayalias++;
+ return true;
+}
+
+
+/* Add ALIAS to the set of variables that may alias VAR. */
+
+static void
+add_may_alias (tree var, tree alias)
+{
+ size_t i;
+ var_ann_t v_ann = get_var_ann (var);
+ var_ann_t a_ann = get_var_ann (alias);
+
+#if defined ENABLE_CHECKING
+ if (var == alias)
+ abort ();
+#endif
+
+ if (v_ann->may_aliases == NULL)
+ VARRAY_TREE_INIT (v_ann->may_aliases, 2, "aliases");
+
+ /* Avoid adding duplicates. */
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (v_ann->may_aliases); i++)
+ if (alias == VARRAY_TREE (v_ann->may_aliases, i))
+ return;
+
+ /* If VAR is a call-clobbered variable, so is its new ALIAS. */
+ if (is_call_clobbered (var))
+ mark_call_clobbered (alias);
+
+ /* Likewise. If ALIAS is call-clobbered, so is VAR. */
+ else if (is_call_clobbered (alias))
+ mark_call_clobbered (var);
+
+ VARRAY_PUSH_TREE (v_ann->may_aliases, alias);
+ a_ann->is_alias_tag = 1;
+}
+
+
+/* Given two pointers DEST and ORIG. Merge the points-to information in
+ ORIG into DEST. AI is as in collect_points_to_info. */
+
+static void
+merge_pointed_to_info (struct alias_info *ai, tree dest, tree orig)
+{
+ ssa_name_ann_t dest_ann, orig_ann;
+
+ /* Make sure we have points-to information for ORIG. */
+ collect_points_to_info_for (ai, orig);
+
+ dest_ann = get_ssa_name_ann (dest);
+ orig_ann = ssa_name_ann (orig);
+
+ if (orig_ann)
+ {
+ dest_ann->pt_anything |= orig_ann->pt_anything;
+ dest_ann->pt_malloc |= orig_ann->pt_malloc;
+
+ if (orig_ann->pt_vars)
+ {
+ if (dest_ann->pt_vars == NULL)
+ {
+ dest_ann->pt_vars = BITMAP_GGC_ALLOC ();
+ bitmap_copy (dest_ann->pt_vars, orig_ann->pt_vars);
+ }
+ else
+ bitmap_a_or_b (dest_ann->pt_vars,
+ dest_ann->pt_vars,
+ orig_ann->pt_vars);
+ }
+ }
+}
+
+
+/* Add VALUE to the list of expressions pointed-to by PTR. */
+
+static void
+add_pointed_to_expr (tree ptr, tree value)
+{
+ ssa_name_ann_t ann;
+
+#if defined ENABLE_CHECKING
+ /* Pointer variables should have been handled by merge_pointed_to_info. */
+ if (TREE_CODE (value) == SSA_NAME
+ && POINTER_TYPE_P (TREE_TYPE (value)))
+ abort ();
+#endif
+
+ ann = get_ssa_name_ann (ptr);
+
+ /* If VALUE is the result of a malloc-like call, then the area pointed to
+ PTR is guaranteed to not alias with anything else. */
+ if (TREE_CODE (value) == CALL_EXPR
+ && (call_expr_flags (value) & (ECF_MALLOC | ECF_MAY_BE_ALLOCA)))
+ ann->pt_malloc = 1;
+ else
+ ann->pt_anything = 1;
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "Pointer ");
+ print_generic_expr (dump_file, ptr, dump_flags);
+ fprintf (dump_file, " points to ");
+ if (ann->pt_malloc)
+ fprintf (dump_file, "malloc space: ");
+ else
+ fprintf (dump_file, "an arbitrary address: ");
+ print_generic_expr (dump_file, value, dump_flags);
+ fprintf (dump_file, "\n");
+ }
+}
+
+
+/* If VALUE is of the form &DECL, add DECL to the set of variables
+ pointed-to by PTR. Otherwise, add VALUE as a pointed-to expression by
+ PTR. AI is as in collect_points_to_info. */
+
+static void
+add_pointed_to_var (struct alias_info *ai, tree ptr, tree value)
+{
+ if (TREE_CODE (value) == ADDR_EXPR)
+ {
+ tree pt_var;
+ ssa_name_ann_t ann;
+ size_t uid;
+
+ pt_var = TREE_OPERAND (value, 0);
+ if (TREE_CODE_CLASS (TREE_CODE (pt_var)) == 'r')
+ pt_var = get_base_address (pt_var);
+
+ if (pt_var && SSA_VAR_P (pt_var))
+ {
+ ann = get_ssa_name_ann (ptr);
+ uid = var_ann (pt_var)->uid;
+ if (ann->pt_vars == NULL)
+ ann->pt_vars = BITMAP_GGC_ALLOC ();
+ bitmap_set_bit (ann->pt_vars, uid);
+ bitmap_set_bit (ai->addresses_needed, uid);
+ }
+ else
+ add_pointed_to_expr (ptr, value);
+ }
+ else
+ add_pointed_to_expr (ptr, value);
+}
+
+
+/* Callback for walk_use_def_chains to gather points-to information from the
+ SSA web.
+
+ VAR is an SSA variable or a GIMPLE expression.
+
+ STMT is the statement that generates the SSA variable or, if STMT is a
+ PHI_NODE, VAR is one of the PHI arguments.
+
+ DATA is a pointer to a structure of type ALIAS_INFO. */
+
+static bool
+collect_points_to_info_r (tree var, tree stmt, void *data)
+{
+ struct alias_info *ai = (struct alias_info *) data;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Visiting use-def links for ");
+ print_generic_expr (dump_file, var, dump_flags);
+ fprintf (dump_file, "\n");
+ }
+
+ if (TREE_CODE (stmt) == MODIFY_EXPR)
+ {
+ tree rhs = TREE_OPERAND (stmt, 1);
+ STRIP_NOPS (rhs);
+
+ /* Found P_i = CONST. */
+ if (is_gimple_min_invariant (rhs))
+ add_pointed_to_var (ai, var, rhs);
+
+ /* Found P_i = Q_j. */
+ else if (TREE_CODE (rhs) == SSA_NAME
+ && POINTER_TYPE_P (TREE_TYPE (rhs)))
+ merge_pointed_to_info (ai, var, rhs);
+
+ /* Found P_i = PLUS_EXPR or P_i = MINUS_EXPR */
+ else if (TREE_CODE (rhs) == PLUS_EXPR
+ || TREE_CODE (rhs) == MINUS_EXPR)
+ {
+ tree op0 = TREE_OPERAND (rhs, 0);
+ tree op1 = TREE_OPERAND (rhs, 1);
+
+ if (TREE_CODE (op0) == SSA_NAME
+ && POINTER_TYPE_P (TREE_TYPE (op0)))
+ merge_pointed_to_info (ai, var, op0);
+ else if (TREE_CODE (op1) == SSA_NAME
+ && POINTER_TYPE_P (TREE_TYPE (op1)))
+ merge_pointed_to_info (ai, var, op1);
+ else if (is_gimple_min_invariant (op0))
+ add_pointed_to_var (ai, var, op0);
+ else if (is_gimple_min_invariant (op1))
+ add_pointed_to_var (ai, var, op1);
+ else
+ add_pointed_to_expr (var, rhs);
+ }
+
+ /* Something else. */
+ else
+ add_pointed_to_expr (var, rhs);
+ }
+ else if (TREE_CODE (stmt) == ASM_EXPR)
+ {
+ /* Pointers defined by __asm__ statements can point anywhere. */
+ ssa_name_ann_t ann = get_ssa_name_ann (var);
+ ann->pt_anything = 1;
+ }
+ else if (IS_EMPTY_STMT (stmt))
+ {
+ tree decl = SSA_NAME_VAR (var);
+
+ if (TREE_CODE (decl) == PARM_DECL)
+ add_pointed_to_expr (var, decl);
+ else if (DECL_INITIAL (decl))
+ add_pointed_to_var (ai, var, DECL_INITIAL (decl));
+ else
+ add_pointed_to_expr (var, decl);
+ }
+ else if (TREE_CODE (stmt) == PHI_NODE)
+ {
+ tree lhs = PHI_RESULT (stmt);
+
+ if (is_gimple_min_invariant (var))
+ add_pointed_to_var (ai, lhs, var);
+ else if (TREE_CODE (var) == SSA_NAME)
+ merge_pointed_to_info (ai, lhs, var);
+ else
+ abort ();
+ }
+ else
+ abort ();
+
+ return false;
+}
+
+
+/* Return true if STMT is an "escape" site from the current function. Escape
+ sites those statements which might expose the address of a variable
+ outside the current function. STMT is an escape site iff:
+
+ 1- STMT is a function call, or
+ 2- STMT is an __asm__ expression, or
+ 3- STMT is an assignment to a non-local variable, or
+ 4- STMT is a return statement.
+
+ If NUM_CALLS_P is not NULL, the counter is incremented if STMT contains
+ a function call. */
+
+static bool
+is_escape_site (tree stmt, size_t *num_calls_p)
+{
+ if (get_call_expr_in (stmt) != NULL_TREE)
+ {
+ if (num_calls_p)
+ (*num_calls_p)++;
+
+ return true;
+ }
+ else if (TREE_CODE (stmt) == ASM_EXPR)
+ return true;
+ else if (TREE_CODE (stmt) == MODIFY_EXPR)
+ {
+ tree lhs = TREE_OPERAND (stmt, 0);
+
+ /* Get to the base of _REF nodes. */
+ if (TREE_CODE (lhs) != SSA_NAME)
+ lhs = get_base_address (lhs);
+
+ /* If we couldn't recognize the LHS of the assignment, assume that it
+ is a non-local store. */
+ if (lhs == NULL_TREE)
+ return true;
+
+ /* If the LHS is an SSA name, it can't possibly represent a non-local
+ memory store. */
+ if (TREE_CODE (lhs) == SSA_NAME)
+ return false;
+
+ /* FIXME: LHS is not an SSA_NAME. Even if it's an assignment to a
+ local variables we cannot be sure if it will escape, because we
+ don't have information about objects not in SSA form. Need to
+ implement something along the lines of
+
+ J.-D. Choi, M. Gupta, M. J. Serrano, V. C. Sreedhar, and S. P.
+ Midkiff, ``Escape analysis for java,'' in Proceedings of the
+ Conference on Object-Oriented Programming Systems, Languages, and
+ Applications (OOPSLA), pp. 1-19, 1999. */
+ return true;
+ }
+ else if (TREE_CODE (stmt) == RETURN_EXPR)
+ return true;
+
+ return false;
+}
+
+
+/* Create a new memory tag of type TYPE. If IS_TYPE_TAG is true, the tag
+ is considered to represent all the pointers whose pointed-to types are
+ in the same alias set class. Otherwise, the tag represents a single
+ SSA_NAME pointer variable. */
+
+static tree
+create_memory_tag (tree type, bool is_type_tag)
+{
+ var_ann_t ann;
+ tree tag = create_tmp_var_raw (type, (is_type_tag) ? "TMT" : "NMT");
+
+ /* By default, memory tags are local variables. Alias analysis will
+ determine whether they should be considered globals. */
+ DECL_CONTEXT (tag) = current_function_decl;
+
+ /* If the pointed-to type is volatile, so is the tag. */
+ TREE_THIS_VOLATILE (tag) = TREE_THIS_VOLATILE (type);
+
+ /* Memory tags are by definition addressable. This also prevents
+ is_gimple_ref frome confusing memory tags with optimizable
+ variables. */
+ TREE_ADDRESSABLE (tag) = 1;
+
+ ann = get_var_ann (tag);
+ ann->mem_tag_kind = (is_type_tag) ? TYPE_TAG : NAME_TAG;
+ ann->type_mem_tag = NULL_TREE;
+
+ /* Add the tag to the symbol table and mark it for renaming. */
+ add_referenced_tmp_var (tag);
+ bitmap_set_bit (vars_to_rename, ann->uid);
+
+ return tag;
+}
+
+
+/* Create a name memory tag to represent a specific SSA_NAME pointer P_i.
+ This is used if P_i has been found to point to a specific set of
+ variables or to a non-aliased memory location like the address returned
+ by malloc functions. */
+
+static tree
+get_nmt_for (tree ptr)
+{
+ ssa_name_ann_t ptr_ann = ssa_name_ann (ptr);
+ tree tag = ptr_ann->name_mem_tag;
+
+ if (tag == NULL_TREE)
+ {
+ tag = create_memory_tag (TREE_TYPE (TREE_TYPE (ptr)), false);
+
+ /* If PTR is a PARM_DECL, its memory tag should be considered a
+ global variable. */
+ if (TREE_CODE (SSA_NAME_VAR (ptr)) == PARM_DECL)
+ mark_call_clobbered (tag);
+
+ /* Similarly, if PTR points to malloc, then TAG is a global. */
+ if (ptr_ann->pt_malloc)
+ mark_call_clobbered (tag);
+ }
+
+ return tag;
+}
+
+
+/* Return the type memory tag associated to pointer PTR. A memory tag is an
+ artificial variable that represents the memory location pointed-to by
+ PTR. It is used to model the effects of pointer de-references on
+ addressable variables.
+
+ AI points to the data gathered during alias analysis. This function
+ populates the array AI->POINTERS. */
+
+static tree
+get_tmt_for (tree ptr, struct alias_info *ai)
+{
+ size_t i;
+ tree tag;
+ tree tag_type = TREE_TYPE (TREE_TYPE (ptr));
+ HOST_WIDE_INT tag_set = get_alias_set (tag_type);
+
+ /* To avoid creating unnecessary memory tags, only create one memory tag
+ per alias set class. Note that it may be tempting to group
+ memory tags based on conflicting alias sets instead of
+ equivalence. That would be wrong because alias sets are not
+ necessarily transitive (as demonstrated by the libstdc++ test
+ 23_containers/vector/cons/4.cc). Given three alias sets A, B, C
+ such that conflicts (A, B) == true and conflicts (A, C) == true,
+ it does not necessarily follow that conflicts (B, C) == true. */
+ for (i = 0, tag = NULL_TREE; i < ai->num_pointers; i++)
+ {
+ struct alias_map_d *curr = ai->pointers[i];
+ if (tag_set == curr->set
+ && (flag_tree_points_to == PTA_NONE
+ || same_points_to_set (curr->var, ptr)))
+ {
+ tag = var_ann (curr->var)->type_mem_tag;
+ break;
+ }
+ }
+
+ /* If VAR cannot alias with any of the existing memory tags, create a new
+ tag for PTR and add it to the POINTERS array. */
+ if (tag == NULL_TREE)
+ {
+ struct alias_map_d *alias_map;
+
+ /* Create a new MT.* artificial variable representing the memory
+ location pointed-to by PTR. */
+ tag = create_memory_tag (tag_type, true);
+
+ /* Add PTR to the POINTERS array. Note that we are not interested in
+ PTR's alias set. Instead, we cache the alias set for the memory that
+ PTR points to. */
+ alias_map = xcalloc (1, sizeof (*alias_map));
+ alias_map->var = ptr;
+ alias_map->set = tag_set;
+ ai->pointers[ai->num_pointers++] = alias_map;
+ }
+
+ return tag;
+}
+
+
+/* Create GLOBAL_VAR, an artificial global variable to act as a
+ representative of all the variables that may be clobbered by function
+ calls. */
+
+static void
+create_global_var (void)
+{
+ global_var = build_decl (VAR_DECL, get_identifier (".GLOBAL_VAR"),
+ size_type_node);
+ DECL_ARTIFICIAL (global_var) = 1;
+ TREE_READONLY (global_var) = 0;
+ DECL_EXTERNAL (global_var) = 0;
+ TREE_STATIC (global_var) = 1;
+ TREE_USED (global_var) = 1;
+ DECL_CONTEXT (global_var) = NULL_TREE;
+ TREE_THIS_VOLATILE (global_var) = 0;
+ TREE_ADDRESSABLE (global_var) = 0;
+
+ add_referenced_tmp_var (global_var);
+ bitmap_set_bit (vars_to_rename, var_ann (global_var)->uid);
+}
+
+
+/* Dump alias statistics on FILE. */
+
+static void
+dump_alias_stats (FILE *file)
+{
+ const char *funcname
+ = (*lang_hooks.decl_printable_name) (current_function_decl, 2);
+ fprintf (file, "\nAlias statistics for %s\n\n", funcname);
+ fprintf (file, "Total alias queries:\t%u\n", alias_stats.alias_queries);
+ fprintf (file, "Total alias mayalias results:\t%u\n",
+ alias_stats.alias_mayalias);
+ fprintf (file, "Total alias noalias results:\t%u\n",
+ alias_stats.alias_noalias);
+ fprintf (file, "Total simple queries:\t%u\n",
+ alias_stats.simple_queries);
+ fprintf (file, "Total simple resolved:\t%u\n",
+ alias_stats.simple_resolved);
+ fprintf (file, "Total TBAA queries:\t%u\n",
+ alias_stats.tbaa_queries);
+ fprintf (file, "Total TBAA resolved:\t%u\n",
+ alias_stats.tbaa_resolved);
+ fprintf (file, "Total PTA queries:\t%u\n",
+ alias_stats.pta_queries);
+ fprintf (file, "Total PTA resolved:\t%u\n",
+ alias_stats.pta_resolved);
+}
+
+
+/* Dump alias information on FILE. */
+
+void
+dump_alias_info (FILE *file)
+{
+ size_t i;
+ const char *funcname
+ = (*lang_hooks.decl_printable_name) (current_function_decl, 2);
+
+ fprintf (file, "\nAlias information for %s\n\n", funcname);
+
+ for (i = 0; i < num_referenced_vars; i++)
+ {
+ tree var = referenced_var (i);
+ var_ann_t ann = var_ann (var);
+ if (ann->may_aliases
+ || ann->type_mem_tag
+ || ann->is_alias_tag
+ || ann->mem_tag_kind != NOT_A_TAG)
+ dump_variable (file, var);
+ }
+
+ fprintf (file, "\n");
+}
+
+
+/* Dump alias information on stderr. */
+
+void
+debug_alias_info (void)
+{
+ dump_alias_info (stderr);
+}
+
+
+/* Dump points-to information for SSA_NAME PTR into FILE. */
+
+static void
+dump_points_to_info_for (FILE *file, tree ptr)
+{
+ ssa_name_ann_t ann = ssa_name_ann (ptr);
+
+ fprintf (file, "Pointer ");
+ print_generic_expr (file, ptr, dump_flags);
+
+ if (ann == NULL)
+ return;
+
+ if (ann->name_mem_tag)
+ {
+ fprintf (file, ", name memory tag: ");
+ print_generic_expr (file, ann->name_mem_tag, dump_flags);
+ }
+
+ if (ann->value_escapes_p)
+ fprintf (file, ", its value escapes");
+
+ if (ann->pt_anything)
+ fprintf (file, ", points-to anything");
+
+ if (ann->pt_malloc)
+ fprintf (file, ", points-to malloc");
+
+ if (ann->pt_vars)
+ {
+ unsigned ix;
+
+ fprintf (file, ", points-to vars: { ");
+ EXECUTE_IF_SET_IN_BITMAP (ann->pt_vars, 0, ix,
+ {
+ print_generic_expr (file, referenced_var (ix), dump_flags);
+ fprintf (file, " ");
+ });
+ fprintf (file, "}");
+ }
+
+ fprintf (file, "\n");
+}
+
+
+/* Dump points-to information into FILE. NOTE: This function is slow, as
+ it needs to traverse the whole CFG looking for pointer SSA_NAMEs. */
+
+void
+dump_points_to_info (FILE *file)
+{
+ basic_block bb;
+ block_stmt_iterator si;
+ size_t i;
+ const char *fname =
+ (*lang_hooks.decl_printable_name) (current_function_decl, 2);
+
+ fprintf (file, "\n\nPointed-to sets for pointers in %s\n\n", fname);
+
+ /* First dump points-to information for the default definitions of
+ pointer variables. This is necessary because default definitions are
+ not part of the code. */
+ for (i = 0; i < num_referenced_vars; i++)
+ {
+ tree var = referenced_var (i);
+ if (POINTER_TYPE_P (TREE_TYPE (var)))
+ {
+ var_ann_t ann = var_ann (var);
+ if (ann->default_def)
+ dump_points_to_info_for (file, ann->default_def);
+ }
+ }
+
+ /* Dump points-to information for every pointer defined in the program. */
+ FOR_EACH_BB (bb)
+ {
+ tree phi;
+
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ tree ptr = PHI_RESULT (phi);
+ if (POINTER_TYPE_P (TREE_TYPE (ptr)))
+ dump_points_to_info_for (file, ptr);
+ }
+
+ for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ {
+ stmt_ann_t ann = stmt_ann (bsi_stmt (si));
+ def_optype defs = DEF_OPS (ann);
+ if (defs)
+ for (i = 0; i < NUM_DEFS (defs); i++)
+ if (POINTER_TYPE_P (TREE_TYPE (DEF_OP (defs, i))))
+ dump_points_to_info_for (file, DEF_OP (defs, i));
+ }
+ }
+
+ fprintf (file, "\n");
+}
+
+
+/* Dump points-to info pointed by PTO into STDERR. */
+
+void
+debug_points_to_info (void)
+{
+ dump_points_to_info (stderr);
+}
+
+/* Dump to FILE the list of variables that may be aliasing VAR. */
+
+void
+dump_may_aliases_for (FILE *file, tree var)
+{
+ varray_type aliases;
+
+ if (TREE_CODE (var) == SSA_NAME)
+ var = SSA_NAME_VAR (var);
+
+ aliases = var_ann (var)->may_aliases;
+ if (aliases)
+ {
+ size_t i;
+ fprintf (file, "{ ");
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (aliases); i++)
+ {
+ print_generic_expr (file, VARRAY_TREE (aliases, i), dump_flags);
+ fprintf (file, " ");
+ }
+ fprintf (file, "}");
+ }
+}
+
+
+/* Dump to stderr the list of variables that may be aliasing VAR. */
+
+void
+debug_may_aliases_for (tree var)
+{
+ dump_may_aliases_for (stderr, var);
+}
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
new file mode 100644
index 00000000000..bb7939cd10c
--- /dev/null
+++ b/gcc/tree-ssa-ccp.c
@@ -0,0 +1,2393 @@
+/* Conditional constant propagation pass for the GNU compiler.
+ Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Adapted from original RTL SSA-CCP by Daniel Berlin <dberlin@dberlin.org>
+ Adapted to GIMPLE trees by Diego Novillo <dnovillo@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Conditional constant propagation.
+
+ References:
+
+ Constant propagation with conditional branches,
+ Wegman and Zadeck, ACM TOPLAS 13(2):181-210.
+
+ Building an Optimizing Compiler,
+ Robert Morgan, Butterworth-Heinemann, 1998, Section 8.9.
+
+ Advanced Compiler Design and Implementation,
+ Steven Muchnick, Morgan Kaufmann, 1997, Section 12.6 */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "errors.h"
+#include "ggc.h"
+#include "tree.h"
+#include "langhooks.h"
+
+/* These RTL headers are needed for basic-block.h. */
+#include "rtl.h"
+#include "tm_p.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+
+#include "diagnostic.h"
+#include "tree-inline.h"
+#include "tree-flow.h"
+#include "tree-gimple.h"
+#include "tree-dump.h"
+#include "tree-pass.h"
+#include "timevar.h"
+#include "expr.h"
+#include "flags.h"
+
+
+/* Possible lattice values. */
+typedef enum
+{
+ UNINITIALIZED = 0,
+ UNDEFINED,
+ CONSTANT,
+ VARYING
+} latticevalue;
+
+/* Use the TREE_VISITED bitflag to mark statements and PHI nodes that have
+ been deemed VARYING and shouldn't be simulated again. */
+#define DONT_SIMULATE_AGAIN(T) TREE_VISITED (T)
+
+/* Main structure for CCP. Contains the lattice value and, if it's a
+ constant, the constant value. */
+typedef struct
+{
+ latticevalue lattice_val;
+ tree const_val;
+} value;
+
+/* A bitmap to keep track of executable blocks in the CFG. */
+static sbitmap executable_blocks;
+
+/* Array of control flow edges on the worklist. */
+static GTY(()) varray_type cfg_blocks = NULL;
+
+static unsigned int cfg_blocks_num = 0;
+static int cfg_blocks_tail;
+static int cfg_blocks_head;
+
+static sbitmap bb_in_list;
+
+/* This is used to track the current value of each variable. */
+static value *value_vector;
+
+/* Worklist of SSA edges which will need reexamination as their definition
+ has changed. SSA edges are def-use edges in the SSA web. For each
+ edge, we store the definition statement or PHI node D. The destination
+ nodes that need to be visited are accessed using immediate_uses (D). */
+static GTY(()) varray_type ssa_edges;
+
+static void initialize (void);
+static void finalize (void);
+static void visit_phi_node (tree);
+static tree ccp_fold (tree);
+static value cp_lattice_meet (value, value);
+static void visit_stmt (tree);
+static void visit_cond_stmt (tree);
+static void visit_assignment (tree);
+static void add_var_to_ssa_edges_worklist (tree);
+static void add_outgoing_control_edges (basic_block);
+static void add_control_edge (edge);
+static void def_to_varying (tree);
+static void set_lattice_value (tree, value);
+static void simulate_block (basic_block);
+static void simulate_stmt (tree);
+static void substitute_and_fold (void);
+static value evaluate_stmt (tree);
+static void dump_lattice_value (FILE *, const char *, value);
+static bool replace_uses_in (tree, bool *);
+static latticevalue likely_value (tree);
+static tree get_rhs (tree);
+static void set_rhs (tree *, tree);
+static value *get_value (tree);
+static value get_default_value (tree);
+static tree ccp_fold_builtin (tree, tree);
+static bool get_strlen (tree, tree *, bitmap);
+static inline bool cfg_blocks_empty_p (void);
+static void cfg_blocks_add (basic_block);
+static basic_block cfg_blocks_get (void);
+static bool need_imm_uses_for (tree var);
+
+/* Main entry point for SSA Conditional Constant Propagation. FNDECL is
+ the declaration for the function to optimize.
+
+ On exit, VARS_TO_RENAME will contain the symbols that have been exposed by
+ the propagation of ADDR_EXPR expressions into pointer dereferences and need
+ to be renamed into SSA.
+
+ PHASE indicates which dump file from the DUMP_FILES array to use when
+ dumping debugging information. */
+
+static void
+tree_ssa_ccp (void)
+{
+ initialize ();
+
+ /* Iterate until the worklists are empty. */
+ while (!cfg_blocks_empty_p () || VARRAY_ACTIVE_SIZE (ssa_edges) > 0)
+ {
+ if (!cfg_blocks_empty_p ())
+ {
+ /* Pull the next block to simulate off the worklist. */
+ basic_block dest_block = cfg_blocks_get ();
+ simulate_block (dest_block);
+ }
+
+ /* The SSA_EDGES worklist can get rather large. Go ahead and
+ drain the entire worklist each iteration through this loop. */
+ while (VARRAY_ACTIVE_SIZE (ssa_edges) > 0)
+ {
+ /* Pull the statement to simulate off the worklist. */
+ tree stmt = VARRAY_TOP_TREE (ssa_edges);
+ stmt_ann_t ann = stmt_ann (stmt);
+ VARRAY_POP (ssa_edges);
+
+ /* visit_stmt can "cancel" reevaluation of some statements.
+ If it does, then in_ccp_worklist will be zero. */
+ if (ann->in_ccp_worklist)
+ {
+ ann->in_ccp_worklist = 0;
+ simulate_stmt (stmt);
+ }
+ }
+ }
+
+ /* Now perform substitutions based on the known constant values. */
+ substitute_and_fold ();
+
+ /* Now cleanup any unreachable code. */
+ cleanup_tree_cfg ();
+
+ /* Free allocated memory. */
+ finalize ();
+
+ /* Debugging dumps. */
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ dump_referenced_vars (dump_file);
+ fprintf (dump_file, "\n\n");
+ }
+}
+
+static bool
+gate_ccp (void)
+{
+ return flag_tree_ccp != 0;
+}
+
+struct tree_opt_pass pass_ccp =
+{
+ "ccp", /* name */
+ gate_ccp, /* gate */
+ tree_ssa_ccp, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_CCP, /* tv_id */
+ PROP_cfg | PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func | TODO_rename_vars
+ | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */
+};
+
+
+/* Get the constant value associated with variable VAR. */
+
+static value *
+get_value (tree var)
+{
+ value *val;
+
+#if defined ENABLE_CHECKING
+ if (TREE_CODE (var) != SSA_NAME)
+ abort ();
+#endif
+
+ val = &value_vector[SSA_NAME_VERSION (var)];
+ if (val->lattice_val == UNINITIALIZED)
+ *val = get_default_value (var);
+
+ return val;
+}
+
+
+/* Simulate the execution of BLOCK. Evaluate the statement associated
+ with each variable reference inside the block. */
+
+static void
+simulate_block (basic_block block)
+{
+ tree phi;
+
+ /* There is nothing to do for the exit block. */
+ if (block == EXIT_BLOCK_PTR)
+ return;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "\nSimulating block %d\n", block->index);
+
+ /* Always simulate PHI nodes, even if we have simulated this block
+ before. */
+ for (phi = phi_nodes (block); phi; phi = TREE_CHAIN (phi))
+ visit_phi_node (phi);
+
+ /* If this is the first time we've simulated this block, then we
+ must simulate each of its statements. */
+ if (!TEST_BIT (executable_blocks, block->index))
+ {
+ block_stmt_iterator j;
+ unsigned int normal_edge_count;
+ edge e, normal_edge;
+
+ /* Note that we have simulated this block. */
+ SET_BIT (executable_blocks, block->index);
+
+ for (j = bsi_start (block); !bsi_end_p (j); bsi_next (&j))
+ visit_stmt (bsi_stmt (j));
+
+ /* We can not predict when abnormal edges will be executed, so
+ once a block is considered executable, we consider any
+ outgoing abnormal edges as executable.
+
+ At the same time, if this block has only one successor that is
+ reached by non-abnormal edges, then add that successor to the
+ worklist. */
+ normal_edge_count = 0;
+ normal_edge = NULL;
+ for (e = block->succ; e; e = e->succ_next)
+ {
+ if (e->flags & EDGE_ABNORMAL)
+ {
+ add_control_edge (e);
+ }
+ else
+ {
+ normal_edge_count++;
+ normal_edge = e;
+ }
+ }
+
+ if (normal_edge_count == 1)
+ add_control_edge (normal_edge);
+ }
+}
+
+
+/* Follow the def-use edges for statement DEF_STMT and simulate all the
+ statements reached by it. */
+
+static void
+simulate_stmt (tree use_stmt)
+{
+ basic_block use_bb = bb_for_stmt (use_stmt);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "\nSimulating statement (from ssa_edges): ");
+ print_generic_stmt (dump_file, use_stmt, dump_flags);
+ }
+
+ if (TREE_CODE (use_stmt) == PHI_NODE)
+ {
+ /* PHI nodes are always visited, regardless of whether or not the
+ destination block is executable. */
+ visit_phi_node (use_stmt);
+ }
+ else if (TEST_BIT (executable_blocks, use_bb->index))
+ {
+ /* Otherwise, visit the statement containing the use reached by
+ DEF, only if the destination block is marked executable. */
+ visit_stmt (use_stmt);
+ }
+}
+
+
+/* Perform final substitution and folding. After this pass the program
+ should still be in SSA form. */
+
+static void
+substitute_and_fold (void)
+{
+ basic_block bb;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ "\nSubstituing constants and folding statements\n\n");
+
+ /* Substitute constants in every statement of every basic block. */
+ FOR_EACH_BB (bb)
+ {
+ block_stmt_iterator i;
+ tree phi;
+
+ /* Propagate our known constants into PHI nodes. */
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ int i;
+
+ for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ {
+ value *new_val;
+ tree *orig_p = &PHI_ARG_DEF (phi, i);
+
+ if (! SSA_VAR_P (*orig_p))
+ break;
+
+ new_val = get_value (*orig_p);
+ if (new_val->lattice_val == CONSTANT
+ && may_propagate_copy (*orig_p, new_val->const_val))
+ *orig_p = new_val->const_val;
+ }
+ }
+
+ for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
+ {
+ bool replaced_address;
+ tree stmt = bsi_stmt (i);
+
+ /* Skip statements that have been folded already. */
+ if (stmt_modified_p (stmt) || !is_exec_stmt (stmt))
+ continue;
+
+ /* Replace the statement with its folded version and mark it
+ folded. */
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Line %d: replaced ", get_lineno (stmt));
+ print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ }
+
+ if (replace_uses_in (stmt, &replaced_address))
+ {
+ bool changed = fold_stmt (bsi_stmt_ptr (i));
+ stmt = bsi_stmt(i);
+ modify_stmt (stmt);
+ /* If we folded a builtin function, we'll likely
+ need to rename VDEFs. */
+ if (replaced_address || changed)
+ mark_new_vars_to_rename (stmt, vars_to_rename);
+ }
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, " with ");
+ print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ fprintf (dump_file, "\n");
+ }
+ }
+ }
+}
+
+
+/* Loop through the PHI_NODE's parameters for BLOCK and compare their
+ lattice values to determine PHI_NODE's lattice value. The value of a
+ PHI node is determined calling cp_lattice_meet() with all the arguments
+ of the PHI node that are incoming via executable edges. */
+
+static void
+visit_phi_node (tree phi)
+{
+ bool short_circuit = 0;
+ value phi_val, *curr_val;
+ int i;
+
+ /* If the PHI node has already been deemed to be VARYING, don't simulate
+ it again. */
+ if (DONT_SIMULATE_AGAIN (phi))
+ return;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "\nVisiting PHI node: ");
+ print_generic_expr (dump_file, phi, dump_flags);
+ }
+
+ curr_val = get_value (PHI_RESULT (phi));
+ switch (curr_val->lattice_val)
+ {
+ case VARYING:
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "\n Shortcircuit. Default of VARYING.");
+ short_circuit = 1;
+ break;
+
+ case CONSTANT:
+ phi_val = *curr_val;
+ break;
+
+ case UNDEFINED:
+ case UNINITIALIZED:
+ phi_val.lattice_val = UNDEFINED;
+ phi_val.const_val = NULL_TREE;
+ break;
+
+ default:
+ abort ();
+ }
+
+ /* If the variable is volatile or the variable is never referenced in a
+ real operand, then consider the PHI node VARYING. */
+ if (short_circuit || TREE_THIS_VOLATILE (SSA_NAME_VAR (PHI_RESULT (phi))))
+ {
+ phi_val.lattice_val = VARYING;
+ phi_val.const_val = NULL;
+ }
+ else
+ for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ {
+ /* Compute the meet operator over all the PHI arguments. */
+ edge e = PHI_ARG_EDGE (phi, i);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file,
+ "\n Argument #%d (%d -> %d %sexecutable)\n",
+ i, e->src->index, e->dest->index,
+ (e->flags & EDGE_EXECUTABLE) ? "" : "not ");
+ }
+
+ /* If the incoming edge is executable, Compute the meet operator for
+ the existing value of the PHI node and the current PHI argument. */
+ if (e->flags & EDGE_EXECUTABLE)
+ {
+ tree rdef = PHI_ARG_DEF (phi, i);
+ value *rdef_val, val;
+
+ if (is_gimple_min_invariant (rdef))
+ {
+ val.lattice_val = CONSTANT;
+ val.const_val = rdef;
+ rdef_val = &val;
+ }
+ else
+ rdef_val = get_value (rdef);
+
+ phi_val = cp_lattice_meet (phi_val, *rdef_val);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "\t");
+ print_generic_expr (dump_file, rdef, dump_flags);
+ dump_lattice_value (dump_file, "\tValue: ", *rdef_val);
+ fprintf (dump_file, "\n");
+ }
+
+ if (phi_val.lattice_val == VARYING)
+ break;
+ }
+ }
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ dump_lattice_value (dump_file, "\n PHI node value: ", phi_val);
+ fprintf (dump_file, "\n\n");
+ }
+
+ set_lattice_value (PHI_RESULT (phi), phi_val);
+ if (phi_val.lattice_val == VARYING)
+ DONT_SIMULATE_AGAIN (phi) = 1;
+}
+
+
+/* Compute the meet operator between VAL1 and VAL2:
+
+ any M UNDEFINED = any
+ any M VARYING = VARYING
+ Ci M Cj = Ci if (i == j)
+ Ci M Cj = VARYING if (i != j) */
+static value
+cp_lattice_meet (value val1, value val2)
+{
+ value result;
+
+ /* any M UNDEFINED = any. */
+ if (val1.lattice_val == UNDEFINED)
+ return val2;
+ else if (val2.lattice_val == UNDEFINED)
+ return val1;
+
+ /* any M VARYING = VARYING. */
+ if (val1.lattice_val == VARYING || val2.lattice_val == VARYING)
+ {
+ result.lattice_val = VARYING;
+ result.const_val = NULL_TREE;
+ return result;
+ }
+
+ /* Ci M Cj = Ci if (i == j)
+ Ci M Cj = VARYING if (i != j) */
+ if (simple_cst_equal (val1.const_val, val2.const_val) == 1)
+ {
+ result.lattice_val = CONSTANT;
+ result.const_val = val1.const_val;
+ }
+ else
+ {
+ result.lattice_val = VARYING;
+ result.const_val = NULL_TREE;
+ }
+
+ return result;
+}
+
+
+/* Evaluate statement STMT. If the statement produces an output value and
+ its evaluation changes the lattice value of its output, do the following:
+
+ - If the statement is an assignment, add all the SSA edges starting at
+ this definition.
+
+ - If the statement is a conditional branch:
+ . If the statement evaluates to non-constant, add all edges to
+ worklist.
+ . If the statement is constant, add the edge executed as the
+ result of the branch. */
+
+static void
+visit_stmt (tree stmt)
+{
+ size_t i;
+ stmt_ann_t ann;
+ def_optype defs;
+ vdef_optype vdefs;
+
+ /* If the statement has already been deemed to be VARYING, don't simulate
+ it again. */
+ if (DONT_SIMULATE_AGAIN (stmt))
+ return;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "\nVisiting statement: ");
+ print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ fprintf (dump_file, "\n");
+ }
+
+ ann = stmt_ann (stmt);
+
+ /* If this statement is already in the worklist then "cancel" it. The
+ reevaluation implied by the worklist entry will produce the same
+ value we generate here and thus reevaluating it again from the
+ worklist is pointless. */
+ if (ann->in_ccp_worklist)
+ ann->in_ccp_worklist = 0;
+
+ /* Now examine the statement. If the statement is an assignment that
+ produces a single output value, evaluate its RHS to see if the lattice
+ value of its output has changed. */
+ if (TREE_CODE (stmt) == MODIFY_EXPR
+ && TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME)
+ visit_assignment (stmt);
+
+ /* Definitions made by statements other than assignments to SSA_NAMEs
+ represent unknown modifications to their outputs. Mark them VARYING. */
+ else if (NUM_DEFS (defs = DEF_OPS (ann)) != 0)
+ {
+ DONT_SIMULATE_AGAIN (stmt) = 1;
+ for (i = 0; i < NUM_DEFS (defs); i++)
+ {
+ tree def = DEF_OP (defs, i);
+ def_to_varying (def);
+ }
+ }
+
+ /* If STMT is a conditional branch, see if we can determine which branch
+ will be taken. */
+ else if (TREE_CODE (stmt) == COND_EXPR || TREE_CODE (stmt) == SWITCH_EXPR)
+ visit_cond_stmt (stmt);
+
+ /* Any other kind of statement is not interesting for constant
+ propagation and, therefore, not worth simulating. */
+ else
+ {
+ DONT_SIMULATE_AGAIN (stmt) = 1;
+
+ /* If STMT is a computed goto, then mark all the output edges
+ executable. */
+ if (computed_goto_p (stmt))
+ add_outgoing_control_edges (bb_for_stmt (stmt));
+ }
+
+ /* Mark all VDEF operands VARYING. */
+ vdefs = VDEF_OPS (ann);
+ for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ def_to_varying (VDEF_RESULT (vdefs, i));
+}
+
+
+/* Visit the assignment statement STMT. Set the value of its LHS to the
+ value computed by the RHS. */
+
+static void
+visit_assignment (tree stmt)
+{
+ value val;
+ tree lhs, rhs;
+
+ lhs = TREE_OPERAND (stmt, 0);
+ rhs = TREE_OPERAND (stmt, 1);
+
+ if (TREE_THIS_VOLATILE (SSA_NAME_VAR (lhs)))
+ {
+ /* Volatile variables are always VARYING. */
+ val.lattice_val = VARYING;
+ val.const_val = NULL_TREE;
+ }
+ else if (TREE_CODE (rhs) == SSA_NAME)
+ {
+ /* For a simple copy operation, we copy the lattice values. */
+ value *nval = get_value (rhs);
+ val = *nval;
+ }
+ else
+ {
+ /* Evaluate the statement. */
+ val = evaluate_stmt (stmt);
+ }
+
+ /* FIXME: Hack. If this was a definition of a bitfield, we need to widen
+ the constant value into the type of the destination variable. This
+ should not be necessary if GCC represented bitfields properly. */
+ {
+ tree lhs = TREE_OPERAND (stmt, 0);
+ if (val.lattice_val == CONSTANT
+ && TREE_CODE (lhs) == COMPONENT_REF
+ && DECL_BIT_FIELD (TREE_OPERAND (lhs, 1)))
+ {
+ tree w = widen_bitfield (val.const_val, TREE_OPERAND (lhs, 1), lhs);
+
+ if (w && is_gimple_min_invariant (w))
+ val.const_val = w;
+ else
+ {
+ val.lattice_val = VARYING;
+ val.const_val = NULL;
+ }
+ }
+ }
+
+ /* Set the lattice value of the statement's output. */
+ set_lattice_value (lhs, val);
+ if (val.lattice_val == VARYING)
+ DONT_SIMULATE_AGAIN (stmt) = 1;
+}
+
+
+/* Visit the conditional statement STMT. If it evaluates to a constant value,
+ mark outgoing edges appropriately. */
+
+static void
+visit_cond_stmt (tree stmt)
+{
+ edge e;
+ value val;
+ basic_block block;
+
+ block = bb_for_stmt (stmt);
+ val = evaluate_stmt (stmt);
+
+ /* Find which edge out of the conditional block will be taken and add it
+ to the worklist. If no single edge can be determined statically, add
+ all outgoing edges from BLOCK. */
+ e = find_taken_edge (block, val.const_val);
+ if (e)
+ add_control_edge (e);
+ else
+ {
+ DONT_SIMULATE_AGAIN (stmt) = 1;
+ add_outgoing_control_edges (block);
+ }
+}
+
+
+/* Add all the edges coming out of BB to the control flow worklist. */
+
+static void
+add_outgoing_control_edges (basic_block bb)
+{
+ edge e;
+
+ for (e = bb->succ; e; e = e->succ_next)
+ add_control_edge (e);
+}
+
+
+/* Add edge E to the control flow worklist. */
+
+static void
+add_control_edge (edge e)
+{
+ basic_block bb = e->dest;
+ if (bb == EXIT_BLOCK_PTR)
+ return;
+
+ /* If the edge had already been executed, skip it. */
+ if (e->flags & EDGE_EXECUTABLE)
+ return;
+
+ e->flags |= EDGE_EXECUTABLE;
+
+ /* If the block is already in the list, we're done. */
+ if (TEST_BIT (bb_in_list, bb->index))
+ return;
+
+ cfg_blocks_add (bb);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Adding Destination of edge (%d -> %d) to worklist\n\n",
+ e->src->index, e->dest->index);
+}
+
+
+/* CCP specific front-end to the non-destructive constant folding routines.
+
+ Attempt to simplify the RHS of STMT knowing that one or more
+ operands are constants.
+
+ If simplification is possible, return the simplified RHS,
+ otherwise return the original RHS. */
+
+static tree
+ccp_fold (tree stmt)
+{
+ tree rhs = get_rhs (stmt);
+ enum tree_code code = TREE_CODE (rhs);
+ int kind = TREE_CODE_CLASS (code);
+ tree retval = NULL_TREE;
+
+ /* If the RHS is just a variable, then that variable must now have
+ a constant value that we can return directly. */
+ if (TREE_CODE (rhs) == SSA_NAME)
+ return get_value (rhs)->const_val;
+
+ /* Unary operators. Note that we know the single operand must
+ be a constant. So this should almost always return a
+ simplified RHS. */
+ if (kind == '1')
+ {
+ /* Handle unary operators which can appear in GIMPLE form. */
+ tree op0 = TREE_OPERAND (rhs, 0);
+
+ /* Simplify the operand down to a constant. */
+ if (TREE_CODE (op0) == SSA_NAME)
+ {
+ value *val = get_value (op0);
+ if (val->lattice_val == CONSTANT)
+ op0 = get_value (op0)->const_val;
+ }
+
+ retval = nondestructive_fold_unary_to_constant (code,
+ TREE_TYPE (rhs),
+ op0);
+
+ /* If we folded, but did not create an invariant, then we can not
+ use this expression. */
+ if (retval && ! is_gimple_min_invariant (retval))
+ return NULL;
+
+ /* If we could not fold the expression, but the arguments are all
+ constants and gimple values, then build and return the new
+ expression.
+
+ In some cases the new expression is still something we can
+ use as a replacement for an argument. This happens with
+ NOP conversions of types for example.
+
+ In other cases the new expression can not be used as a
+ replacement for an argument (as it would create non-gimple
+ code). But the new expression can still be used to derive
+ other constants. */
+ if (! retval && is_gimple_min_invariant (op0))
+ return build1 (code, TREE_TYPE (rhs), op0);
+ }
+
+ /* Binary and comparison operators. We know one or both of the
+ operands are constants. */
+ else if (kind == '2'
+ || kind == '<'
+ || code == TRUTH_AND_EXPR
+ || code == TRUTH_OR_EXPR
+ || code == TRUTH_XOR_EXPR)
+ {
+ /* Handle binary and comparison operators that can appear in
+ GIMPLE form. */
+ tree op0 = TREE_OPERAND (rhs, 0);
+ tree op1 = TREE_OPERAND (rhs, 1);
+
+ /* Simplify the operands down to constants when appropriate. */
+ if (TREE_CODE (op0) == SSA_NAME)
+ {
+ value *val = get_value (op0);
+ if (val->lattice_val == CONSTANT)
+ op0 = val->const_val;
+ }
+
+ if (TREE_CODE (op1) == SSA_NAME)
+ {
+ value *val = get_value (op1);
+ if (val->lattice_val == CONSTANT)
+ op1 = val->const_val;
+ }
+
+ retval = nondestructive_fold_binary_to_constant (code,
+ TREE_TYPE (rhs),
+ op0, op1);
+
+ /* If we folded, but did not create an invariant, then we can not
+ use this expression. */
+ if (retval && ! is_gimple_min_invariant (retval))
+ return NULL;
+
+ /* If we could not fold the expression, but the arguments are all
+ constants and gimple values, then build and return the new
+ expression.
+
+ In some cases the new expression is still something we can
+ use as a replacement for an argument. This happens with
+ NOP conversions of types for example.
+
+ In other cases the new expression can not be used as a
+ replacement for an argument (as it would create non-gimple
+ code). But the new expression can still be used to derive
+ other constants. */
+ if (! retval
+ && is_gimple_min_invariant (op0)
+ && is_gimple_min_invariant (op1))
+ return build (code, TREE_TYPE (rhs), op0, op1);
+ }
+
+ /* We may be able to fold away calls to builtin functions if their
+ arguments are constants. */
+ else if (code == CALL_EXPR
+ && TREE_CODE (TREE_OPERAND (rhs, 0)) == ADDR_EXPR
+ && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (rhs, 0), 0))
+ == FUNCTION_DECL)
+ && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (rhs, 0), 0)))
+ {
+ use_optype uses = STMT_USE_OPS (stmt);
+ if (NUM_USES (uses) != 0)
+ {
+ tree *orig;
+ size_t i;
+
+ /* Preserve the original values of every operand. */
+ orig = xmalloc (sizeof (tree) * NUM_USES (uses));
+ for (i = 0; i < NUM_USES (uses); i++)
+ orig[i] = USE_OP (uses, i);
+
+ /* Substitute operands with their values and try to fold. */
+ replace_uses_in (stmt, NULL);
+ retval = fold_builtin (rhs);
+
+ /* Restore operands to their original form. */
+ for (i = 0; i < NUM_USES (uses); i++)
+ *(USE_OP_PTR (uses, i)) = orig[i];
+ free (orig);
+ }
+ }
+ else
+ return rhs;
+
+ /* If we got a simplified form, see if we need to convert its type. */
+ if (retval)
+ {
+ if (TREE_TYPE (retval) != TREE_TYPE (rhs))
+ retval = convert (TREE_TYPE (rhs), retval);
+
+ if (TREE_TYPE (retval) == TREE_TYPE (rhs))
+ return retval;
+ }
+
+ /* No simplification was possible. */
+ return rhs;
+}
+
+
+/* Evaluate statement STMT. */
+
+static value
+evaluate_stmt (tree stmt)
+{
+ value val;
+ tree simplified;
+ latticevalue likelyvalue = likely_value (stmt);
+
+ /* If the statement is likely to have a CONSTANT result, then try
+ to fold the statement to determine the constant value. */
+ if (likelyvalue == CONSTANT)
+ simplified = ccp_fold (stmt);
+ /* If the statement is likely to have a VARYING result, then do not
+ bother folding the statement. */
+ else if (likelyvalue == VARYING)
+ simplified = get_rhs (stmt);
+ /* Otherwise the statement is likely to have an UNDEFINED value and
+ there will be nothing to do. */
+ else
+ simplified = NULL_TREE;
+
+ if (simplified && is_gimple_min_invariant (simplified))
+ {
+ /* The statement produced a constant value. */
+ val.lattice_val = CONSTANT;
+ val.const_val = simplified;
+ }
+ else
+ {
+ /* The statement produced a nonconstant value. If the statement
+ had undefined operands, then the result of the statement should
+ be undefined. Else the result of the statement is VARYING. */
+ val.lattice_val = (likelyvalue == UNDEFINED ? UNDEFINED : VARYING);
+ val.const_val = NULL_TREE;
+ }
+
+ return val;
+}
+
+
+/* Debugging dumps. */
+
+static void
+dump_lattice_value (FILE *outf, const char *prefix, value val)
+{
+ switch (val.lattice_val)
+ {
+ case UNDEFINED:
+ fprintf (outf, "%sUNDEFINED", prefix);
+ break;
+ case VARYING:
+ fprintf (outf, "%sVARYING", prefix);
+ break;
+ case CONSTANT:
+ fprintf (outf, "%sCONSTANT ", prefix);
+ print_generic_expr (outf, val.const_val, dump_flags);
+ break;
+ default:
+ abort ();
+ }
+}
+
+/* Given a constant value VAL for bitfield FIELD, and a destination
+ variable VAR, return VAL appropriately widened to fit into VAR. If
+ FIELD is wider than HOST_WIDE_INT, NULL is returned. */
+
+tree
+widen_bitfield (tree val, tree field, tree var)
+{
+ unsigned var_size, field_size;
+ tree wide_val;
+ unsigned HOST_WIDE_INT mask;
+ unsigned i;
+
+ var_size = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE ((var))));
+ field_size = TREE_INT_CST_LOW (DECL_SIZE (field));
+
+ /* Give up if either the bitfield or the variable are too wide. */
+ if (field_size > HOST_BITS_PER_WIDE_INT || var_size > HOST_BITS_PER_WIDE_INT)
+ return NULL;
+
+#if defined ENABLE_CHECKING
+ if (var_size < field_size)
+ abort ();
+#endif
+
+ /* If VAL is not an integer constant, then give up. */
+ if (TREE_CODE (val) != INTEGER_CST)
+ return NULL;
+
+ /* If the sign bit of the value is not set, or the field's type is
+ unsigned, then just mask off the high order bits of the value. */
+ if ((TREE_INT_CST_LOW (val) & (1 << (field_size - 1))) == 0
+ || DECL_UNSIGNED (field))
+ {
+ /* Zero extension. Build a mask with the lower 'field_size' bits
+ set and a BIT_AND_EXPR node to clear the high order bits of
+ the value. */
+ for (i = 0, mask = 0; i < field_size; i++)
+ mask |= 1 << i;
+
+ wide_val = build (BIT_AND_EXPR, TREE_TYPE (var), val,
+ build_int_2 (mask, 0));
+ }
+ else
+ {
+ /* Sign extension. Create a mask with the upper 'field_size'
+ bits set and a BIT_IOR_EXPR to set the high order bits of the
+ value. */
+ for (i = 0, mask = 0; i < (var_size - field_size); i++)
+ mask |= 1 << (var_size - i - 1);
+
+ wide_val = build (BIT_IOR_EXPR, TREE_TYPE (var), val,
+ build_int_2 (mask, 0));
+ }
+
+ return fold (wide_val);
+}
+
+
+/* Function indicating whether we ought to include information for 'var'
+ when calculating immediate uses. */
+
+static bool
+need_imm_uses_for (tree var)
+{
+ return get_value (var)->lattice_val != VARYING;
+}
+
+
+/* Initialize local data structures and worklists for CCP. */
+
+static void
+initialize (void)
+{
+ edge e;
+ basic_block bb;
+ sbitmap virtual_var;
+
+ /* Worklist of SSA edges. */
+ VARRAY_TREE_INIT (ssa_edges, 20, "ssa_edges");
+
+ executable_blocks = sbitmap_alloc (last_basic_block);
+ sbitmap_zero (executable_blocks);
+
+ bb_in_list = sbitmap_alloc (last_basic_block);
+ sbitmap_zero (bb_in_list);
+
+ value_vector = (value *) xmalloc (highest_ssa_version * sizeof (value));
+ memset (value_vector, 0, highest_ssa_version * sizeof (value));
+
+ /* 1 if ssa variable is used in a virtual variable context. */
+ virtual_var = sbitmap_alloc (highest_ssa_version);
+ sbitmap_zero (virtual_var);
+
+ /* Initialize default values and simulation flags for PHI nodes, statements
+ and edges. */
+ FOR_EACH_BB (bb)
+ {
+ block_stmt_iterator i;
+ tree stmt;
+ stmt_ann_t ann;
+ def_optype defs;
+ vdef_optype vdefs;
+ size_t x;
+ int vary;
+
+ /* Get the default value for each definition. */
+ for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
+ {
+ vary = 0;
+ stmt = bsi_stmt (i);
+ get_stmt_operands (stmt);
+ ann = stmt_ann (stmt);
+ defs = DEF_OPS (ann);
+ for (x = 0; x < NUM_DEFS (defs); x++)
+ {
+ tree def = DEF_OP (defs, x);
+ if (get_value (def)->lattice_val == VARYING)
+ vary = 1;
+ }
+ DONT_SIMULATE_AGAIN (stmt) = vary;
+
+ /* Mark all VDEF operands VARYING. */
+ vdefs = VDEF_OPS (ann);
+ for (x = 0; x < NUM_VDEFS (vdefs); x++)
+ {
+ tree res = VDEF_RESULT (vdefs, x);
+ get_value (res)->lattice_val = VARYING;
+ SET_BIT (virtual_var, SSA_NAME_VERSION (res));
+ }
+ }
+
+ for (e = bb->succ; e; e = e->succ_next)
+ e->flags &= ~EDGE_EXECUTABLE;
+ }
+
+ /* Now process PHI nodes. */
+ FOR_EACH_BB (bb)
+ {
+ tree phi, var;
+ int x;
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ value *val;
+ val = get_value (PHI_RESULT (phi));
+ if (val->lattice_val != VARYING)
+ {
+ for (x = 0; x < PHI_NUM_ARGS (phi); x++)
+ {
+ var = PHI_ARG_DEF (phi, x);
+ /* If one argument is virtual, the result is virtual, and
+ therefore varying. */
+ if (TREE_CODE (var) == SSA_NAME)
+ {
+ if (TEST_BIT (virtual_var, SSA_NAME_VERSION (var)))
+ {
+ val->lattice_val = VARYING;
+ SET_BIT (virtual_var,
+ SSA_NAME_VERSION (PHI_RESULT (phi)));
+ break;
+ }
+ }
+ }
+ }
+ DONT_SIMULATE_AGAIN (phi) = ((val->lattice_val == VARYING) ? 1 : 0);
+ }
+ }
+
+ sbitmap_free (virtual_var);
+ /* Compute immediate uses for variables we care about. */
+ compute_immediate_uses (TDFA_USE_OPS, need_imm_uses_for);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ dump_immediate_uses (dump_file);
+
+ VARRAY_BB_INIT (cfg_blocks, 20, "cfg_blocks");
+
+ /* Seed the algorithm by adding the successors of the entry block to the
+ edge worklist. */
+ for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
+ {
+ if (e->dest != EXIT_BLOCK_PTR)
+ {
+ e->flags |= EDGE_EXECUTABLE;
+ cfg_blocks_add (e->dest);
+ }
+ }
+}
+
+
+/* Free allocated storage. */
+
+static void
+finalize (void)
+{
+ ssa_edges = NULL;
+ cfg_blocks = NULL;
+ free (value_vector);
+ sbitmap_free (bb_in_list);
+ sbitmap_free (executable_blocks);
+ free_df ();
+}
+
+/* Is the block worklist empty. */
+
+static inline bool
+cfg_blocks_empty_p (void)
+{
+ return (cfg_blocks_num == 0);
+}
+
+/* Add a basic block to the worklist. */
+
+static void
+cfg_blocks_add (basic_block bb)
+{
+ if (bb == ENTRY_BLOCK_PTR || bb == EXIT_BLOCK_PTR)
+ return;
+
+ if (TEST_BIT (bb_in_list, bb->index))
+ return;
+
+ if (cfg_blocks_empty_p ())
+ {
+ cfg_blocks_tail = cfg_blocks_head = 0;
+ cfg_blocks_num = 1;
+ }
+ else
+ {
+ cfg_blocks_num++;
+ if (cfg_blocks_num > VARRAY_SIZE (cfg_blocks))
+ {
+ /* We have to grow the array now. Adjust to queue to occupy the
+ full space of the original array. */
+ cfg_blocks_tail = VARRAY_SIZE (cfg_blocks);
+ cfg_blocks_head = 0;
+ VARRAY_GROW (cfg_blocks, 2 * VARRAY_SIZE (cfg_blocks));
+ }
+ else
+ cfg_blocks_tail = (cfg_blocks_tail + 1) % VARRAY_SIZE (cfg_blocks);
+ }
+ VARRAY_BB (cfg_blocks, cfg_blocks_tail) = bb;
+ SET_BIT (bb_in_list, bb->index);
+}
+
+/* Remove a block from the worklist. */
+
+static basic_block
+cfg_blocks_get (void)
+{
+ basic_block bb;
+
+ bb = VARRAY_BB (cfg_blocks, cfg_blocks_head);
+
+#ifdef ENABLE_CHECKING
+ if (cfg_blocks_empty_p () || !bb)
+ abort ();
+#endif
+
+ cfg_blocks_head = (cfg_blocks_head + 1) % VARRAY_SIZE (cfg_blocks);
+ --cfg_blocks_num;
+ RESET_BIT (bb_in_list, bb->index);
+
+ return bb;
+}
+
+/* We have just defined a new value for VAR. Add all immediate uses
+ of VAR to the ssa_edges worklist. */
+static void
+add_var_to_ssa_edges_worklist (tree var)
+{
+ tree stmt = SSA_NAME_DEF_STMT (var);
+ dataflow_t df = get_immediate_uses (stmt);
+ int num_uses = num_immediate_uses (df);
+ int i;
+
+ for (i = 0; i < num_uses; i++)
+ {
+ tree use = immediate_use (df, i);
+
+ if (!DONT_SIMULATE_AGAIN (use))
+ {
+ stmt_ann_t ann = stmt_ann (use);
+ if (ann->in_ccp_worklist == 0)
+ {
+ ann->in_ccp_worklist = 1;
+ VARRAY_PUSH_TREE (ssa_edges, use);
+ }
+ }
+ }
+}
+
+/* Set the lattice value for the variable VAR to VARYING. */
+
+static void
+def_to_varying (tree var)
+{
+ value val;
+ val.lattice_val = VARYING;
+ val.const_val = NULL_TREE;
+ set_lattice_value (var, val);
+}
+
+/* Set the lattice value for variable VAR to VAL. */
+
+static void
+set_lattice_value (tree var, value val)
+{
+ value *old = get_value (var);
+
+#ifdef ENABLE_CHECKING
+ if (val.lattice_val == UNDEFINED)
+ {
+ /* CONSTANT->UNDEFINED is never a valid state transition. */
+ if (old->lattice_val == CONSTANT)
+ abort ();
+
+ /* VARYING->UNDEFINED is generally not a valid state transition,
+ except for values which are initialized to VARYING. */
+ if (old->lattice_val == VARYING
+ && get_default_value (var).lattice_val != VARYING)
+ abort ();
+ }
+ else if (val.lattice_val == CONSTANT)
+ {
+ /* VARYING -> CONSTANT is an invalid state transition, except
+ for objects which start off in a VARYING state. */
+ if (old->lattice_val == VARYING
+ && get_default_value (var).lattice_val != VARYING)
+ abort ();
+ }
+#endif
+
+ /* If the constant for VAR has changed, then this VAR is really varying. */
+ if (old->lattice_val == CONSTANT && val.lattice_val == CONSTANT
+ && !simple_cst_equal (old->const_val, val.const_val))
+ {
+ val.lattice_val = VARYING;
+ val.const_val = NULL_TREE;
+ }
+
+ if (old->lattice_val != val.lattice_val)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ dump_lattice_value (dump_file,
+ "Lattice value changed to ", val);
+ fprintf (dump_file, ". Adding definition to SSA edges.\n");
+ }
+
+ add_var_to_ssa_edges_worklist (var);
+ *old = val;
+ }
+}
+
+/* Replace USE references in statement STMT with their immediate reaching
+ definition. Return true if at least one reference was replaced. If
+ REPLACED_ADDRESSES_P is given, it will be set to true if an address
+ constant was replaced. */
+
+static bool
+replace_uses_in (tree stmt, bool *replaced_addresses_p)
+{
+ bool replaced = false;
+ use_optype uses;
+ size_t i;
+
+ if (replaced_addresses_p)
+ *replaced_addresses_p = false;
+
+ get_stmt_operands (stmt);
+
+ uses = STMT_USE_OPS (stmt);
+ for (i = 0; i < NUM_USES (uses); i++)
+ {
+ tree *use = USE_OP_PTR (uses, i);
+ value *val = get_value (*use);
+
+ if (val->lattice_val == CONSTANT)
+ {
+ *use = val->const_val;
+ replaced = true;
+ if (POINTER_TYPE_P (TREE_TYPE (*use)) && replaced_addresses_p)
+ *replaced_addresses_p = true;
+ }
+ }
+
+ return replaced;
+}
+
+/* Return the likely latticevalue for STMT.
+
+ If STMT has no operands, then return CONSTANT.
+
+ Else if any operands of STMT are undefined, then return UNDEFINED.
+
+ Else if any operands of STMT are constants, then return CONSTANT.
+
+ Else return VARYING. */
+
+static latticevalue
+likely_value (tree stmt)
+{
+ use_optype uses;
+ size_t i;
+ int found_constant = 0;
+ stmt_ann_t ann;
+
+ /* If the statement makes aliased loads or has volatile operands, it
+ won't fold to a constant value. */
+ ann = stmt_ann (stmt);
+ if (ann->makes_aliased_loads || ann->has_volatile_ops)
+ return VARYING;
+
+ /* A CALL_EXPR is assumed to be varying. This may be overly conservative,
+ in the presence of const and pure calls. */
+ if (get_call_expr_in (stmt) != NULL_TREE)
+ return VARYING;
+
+ get_stmt_operands (stmt);
+
+ uses = USE_OPS (ann);
+ for (i = 0; i < NUM_USES (uses); i++)
+ {
+ tree use = USE_OP (uses, i);
+ value *val = get_value (use);
+
+ if (val->lattice_val == UNDEFINED)
+ return UNDEFINED;
+
+ if (val->lattice_val == CONSTANT)
+ found_constant = 1;
+ }
+
+ return ((found_constant || !uses) ? CONSTANT : VARYING);
+}
+
+/* A subroutine of fold_stmt_r. Attempts to fold *(A+O) to A[X].
+ BASE is an array type. OFFSET is a byte displacement. ORIG_TYPE
+ is the desired result type. */
+
+static tree
+maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type)
+{
+ unsigned HOST_WIDE_INT lquo, lrem;
+ HOST_WIDE_INT hquo, hrem;
+ tree elt_size, min_idx, idx;
+ tree array_type, elt_type;
+
+ /* Ignore stupid user tricks of indexing non-array variables. */
+ array_type = TREE_TYPE (base);
+ if (TREE_CODE (array_type) != ARRAY_TYPE)
+ return NULL_TREE;
+ elt_type = TREE_TYPE (array_type);
+ if (!lang_hooks.types_compatible_p (orig_type, elt_type))
+ return NULL_TREE;
+
+ /* Whee. Ignore indexing of variable sized types. */
+ elt_size = TYPE_SIZE_UNIT (elt_type);
+ if (TREE_CODE (elt_size) != INTEGER_CST)
+ return NULL_TREE;
+
+ /* If the division isn't exact, then don't do anything. Equally
+ invalid as the above indexing of non-array variables. */
+ if (div_and_round_double (TRUNC_DIV_EXPR, 1,
+ TREE_INT_CST_LOW (offset),
+ TREE_INT_CST_HIGH (offset),
+ TREE_INT_CST_LOW (elt_size),
+ TREE_INT_CST_HIGH (elt_size),
+ &lquo, &hquo, &lrem, &hrem)
+ || lrem || hrem)
+ return NULL_TREE;
+ idx = build_int_2_wide (lquo, hquo);
+
+ /* Re-bias the index by the min index of the array type. */
+ min_idx = TYPE_DOMAIN (TREE_TYPE (base));
+ if (min_idx)
+ {
+ min_idx = TYPE_MIN_VALUE (min_idx);
+ if (min_idx)
+ {
+ idx = convert (TREE_TYPE (min_idx), idx);
+ if (!integer_zerop (min_idx))
+ idx = int_const_binop (PLUS_EXPR, idx, min_idx, 1);
+ }
+ }
+
+ return build (ARRAY_REF, orig_type, base, idx);
+}
+
+/* A subroutine of fold_stmt_r. Attempts to fold *(S+O) to S.X.
+ BASE is a record type. OFFSET is a byte displacement. ORIG_TYPE
+ is the desired result type. */
+/* ??? This doesn't handle class inheritance. */
+
+static tree
+maybe_fold_offset_to_component_ref (tree record_type, tree base, tree offset,
+ tree orig_type, bool base_is_ptr)
+{
+ tree f, t, field_type, tail_array_field;
+
+ if (TREE_CODE (record_type) != RECORD_TYPE
+ && TREE_CODE (record_type) != UNION_TYPE
+ && TREE_CODE (record_type) != QUAL_UNION_TYPE)
+ return NULL_TREE;
+
+ /* Short-circuit silly cases. */
+ if (lang_hooks.types_compatible_p (record_type, orig_type))
+ return NULL_TREE;
+
+ tail_array_field = NULL_TREE;
+ for (f = TYPE_FIELDS (record_type); f ; f = TREE_CHAIN (f))
+ {
+ int cmp;
+
+ if (TREE_CODE (f) != FIELD_DECL)
+ continue;
+ if (DECL_BIT_FIELD (f))
+ continue;
+ if (TREE_CODE (DECL_FIELD_OFFSET (f)) != INTEGER_CST)
+ continue;
+
+ /* ??? Java creates "interesting" fields for representing base classes.
+ They have no name, and have no context. With no context, we get into
+ trouble with nonoverlapping_component_refs_p. Skip them. */
+ if (!DECL_FIELD_CONTEXT (f))
+ continue;
+
+ /* The previous array field isn't at the end. */
+ tail_array_field = NULL_TREE;
+
+ /* Check to see if this offset overlaps with the field. */
+ cmp = tree_int_cst_compare (DECL_FIELD_OFFSET (f), offset);
+ if (cmp > 0)
+ continue;
+
+ field_type = TREE_TYPE (f);
+ if (cmp < 0)
+ {
+ /* Don't care about offsets into the middle of scalars. */
+ if (!AGGREGATE_TYPE_P (field_type))
+ continue;
+
+ /* Check for array at the end of the struct. This is often
+ used as for flexible array members. We should be able to
+ turn this into an array access anyway. */
+ if (TREE_CODE (field_type) == ARRAY_TYPE)
+ tail_array_field = f;
+
+ /* Check the end of the field against the offset. */
+ if (!DECL_SIZE_UNIT (f)
+ || TREE_CODE (DECL_SIZE_UNIT (f)) != INTEGER_CST)
+ continue;
+ t = int_const_binop (MINUS_EXPR, offset, DECL_FIELD_OFFSET (f), 1);
+ if (!tree_int_cst_lt (t, DECL_SIZE_UNIT (f)))
+ continue;
+
+ /* If we matched, then set offset to the displacement into
+ this field. */
+ offset = t;
+ }
+
+ /* Here we exactly match the offset being checked. If the types match,
+ then we can return that field. */
+ else if (lang_hooks.types_compatible_p (orig_type, field_type))
+ {
+ if (base_is_ptr)
+ base = build1 (INDIRECT_REF, record_type, base);
+ t = build (COMPONENT_REF, field_type, base, f);
+ return t;
+ }
+
+ /* Don't care about type-punning of scalars. */
+ else if (!AGGREGATE_TYPE_P (field_type))
+ return NULL_TREE;
+
+ goto found;
+ }
+
+ if (!tail_array_field)
+ return NULL_TREE;
+
+ f = tail_array_field;
+ field_type = TREE_TYPE (f);
+
+ found:
+ /* If we get here, we've got an aggregate field, and a possibly
+ non-zero offset into them. Recurse and hope for a valid match. */
+ if (base_is_ptr)
+ base = build1 (INDIRECT_REF, record_type, base);
+ base = build (COMPONENT_REF, field_type, base, f);
+
+ t = maybe_fold_offset_to_array_ref (base, offset, orig_type);
+ if (t)
+ return t;
+ return maybe_fold_offset_to_component_ref (field_type, base, offset,
+ orig_type, false);
+}
+
+/* A subroutine of fold_stmt_r. Attempt to simplify *(BASE+OFFSET).
+ Return the simplified expression, or NULL if nothing could be done. */
+
+static tree
+maybe_fold_stmt_indirect (tree expr, tree base, tree offset)
+{
+ tree t;
+
+ /* We may well have constructed a double-nested PLUS_EXPR via multiple
+ substitutions. Fold that down to one. Remove NON_LVALUE_EXPRs that
+ are sometimes added. */
+ base = fold (base);
+ STRIP_NOPS (base);
+ TREE_OPERAND (expr, 0) = base;
+
+ /* One possibility is that the address reduces to a string constant. */
+ t = fold_read_from_constant_string (expr);
+ if (t)
+ return t;
+
+ /* Add in any offset from a PLUS_EXPR. */
+ if (TREE_CODE (base) == PLUS_EXPR)
+ {
+ tree offset2;
+
+ offset2 = TREE_OPERAND (base, 1);
+ if (TREE_CODE (offset2) != INTEGER_CST)
+ return NULL_TREE;
+ base = TREE_OPERAND (base, 0);
+
+ offset = int_const_binop (PLUS_EXPR, offset, offset2, 1);
+ }
+
+ if (TREE_CODE (base) == ADDR_EXPR)
+ {
+ /* Strip the ADDR_EXPR. */
+ base = TREE_OPERAND (base, 0);
+
+ /* Try folding *(&B+O) to B[X]. */
+ t = maybe_fold_offset_to_array_ref (base, offset, TREE_TYPE (expr));
+ if (t)
+ return t;
+
+ /* Try folding *(&B+O) to B.X. */
+ t = maybe_fold_offset_to_component_ref (TREE_TYPE (base), base, offset,
+ TREE_TYPE (expr), false);
+ if (t)
+ return t;
+
+ /* Fold *&B to B. */
+ if (integer_zerop (offset))
+ return base;
+ }
+ else
+ {
+ /* We can get here for out-of-range string constant accesses,
+ such as "_"[3]. Bail out of the entire substitution search
+ and arrange for the entire statement to be replaced by a
+ call to __builtin_trap. In all likelyhood this will all be
+ constant-folded away, but in the meantime we can't leave with
+ something that get_expr_operands can't understand. */
+
+ t = base;
+ STRIP_NOPS (t);
+ if (TREE_CODE (t) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST)
+ {
+ /* FIXME: Except that this causes problems elsewhere with dead
+ code not being deleted, and we abort in the rtl expanders
+ because we failed to remove some ssa_name. In the meantime,
+ just return zero. */
+ /* FIXME2: This condition should be signaled by
+ fold_read_from_constant_string directly, rather than
+ re-checking for it here. */
+ return integer_zero_node;
+ }
+
+ /* Try folding *(B+O) to B->X. Still an improvement. */
+ if (POINTER_TYPE_P (TREE_TYPE (base)))
+ {
+ t = maybe_fold_offset_to_component_ref (TREE_TYPE (TREE_TYPE (base)),
+ base, offset,
+ TREE_TYPE (expr), true);
+ if (t)
+ return t;
+ }
+ }
+
+ /* Otherwise we had an offset that we could not simplify. */
+ return NULL_TREE;
+}
+
+/* A subroutine of fold_stmt_r. EXPR is a PLUS_EXPR.
+
+ A quaint feature extant in our address arithmetic is that there
+ can be hidden type changes here. The type of the result need
+ not be the same as the type of the input pointer.
+
+ What we're after here is an expression of the form
+ (T *)(&array + const)
+ where the cast doesn't actually exist, but is implicit in the
+ type of the PLUS_EXPR. We'd like to turn this into
+ &array[x]
+ which may be able to propagate further. */
+
+static tree
+maybe_fold_stmt_addition (tree expr)
+{
+ tree op0 = TREE_OPERAND (expr, 0);
+ tree op1 = TREE_OPERAND (expr, 1);
+ tree ptr_type = TREE_TYPE (expr);
+ tree ptd_type;
+ tree t;
+ bool subtract = (TREE_CODE (expr) == MINUS_EXPR);
+
+ /* We're only interested in pointer arithmetic. */
+ if (!POINTER_TYPE_P (ptr_type))
+ return NULL_TREE;
+ /* Canonicalize the integral operand to op1. */
+ if (INTEGRAL_TYPE_P (TREE_TYPE (op0)))
+ {
+ if (subtract)
+ return NULL_TREE;
+ t = op0, op0 = op1, op1 = t;
+ }
+ /* It had better be a constant. */
+ if (TREE_CODE (op1) != INTEGER_CST)
+ return NULL_TREE;
+ /* The first operand should be an ADDR_EXPR. */
+ if (TREE_CODE (op0) != ADDR_EXPR)
+ return NULL_TREE;
+ op0 = TREE_OPERAND (op0, 0);
+
+ /* If the first operand is an ARRAY_REF, expand it so that we can fold
+ the offset into it. */
+ while (TREE_CODE (op0) == ARRAY_REF)
+ {
+ tree array_obj = TREE_OPERAND (op0, 0);
+ tree array_idx = TREE_OPERAND (op0, 1);
+ tree elt_type = TREE_TYPE (op0);
+ tree elt_size = TYPE_SIZE_UNIT (elt_type);
+ tree min_idx;
+
+ if (TREE_CODE (array_idx) != INTEGER_CST)
+ break;
+ if (TREE_CODE (elt_size) != INTEGER_CST)
+ break;
+
+ /* Un-bias the index by the min index of the array type. */
+ min_idx = TYPE_DOMAIN (TREE_TYPE (array_obj));
+ if (min_idx)
+ {
+ min_idx = TYPE_MIN_VALUE (min_idx);
+ if (min_idx)
+ {
+ array_idx = convert (TREE_TYPE (min_idx), array_idx);
+ if (!integer_zerop (min_idx))
+ array_idx = int_const_binop (MINUS_EXPR, array_idx,
+ min_idx, 0);
+ }
+ }
+
+ /* Convert the index to a byte offset. */
+ array_idx = convert (sizetype, array_idx);
+ array_idx = int_const_binop (MULT_EXPR, array_idx, elt_size, 0);
+
+ /* Update the operands for the next round, or for folding. */
+ /* If we're manipulating unsigned types, then folding into negative
+ values can produce incorrect results. Particularly if the type
+ is smaller than the width of the pointer. */
+ if (subtract
+ && TYPE_UNSIGNED (TREE_TYPE (op1))
+ && tree_int_cst_lt (array_idx, op1))
+ return NULL;
+ op1 = int_const_binop (subtract ? MINUS_EXPR : PLUS_EXPR,
+ array_idx, op1, 0);
+ subtract = false;
+ op0 = array_obj;
+ }
+
+ /* If we weren't able to fold the subtraction into another array reference,
+ canonicalize the integer for passing to the array and component ref
+ simplification functions. */
+ if (subtract)
+ {
+ if (TYPE_UNSIGNED (TREE_TYPE (op1)))
+ return NULL;
+ op1 = fold (build1 (NEGATE_EXPR, TREE_TYPE (op1), op1));
+ /* ??? In theory fold should always produce another integer. */
+ if (TREE_CODE (op1) != INTEGER_CST)
+ return NULL;
+ }
+
+ ptd_type = TREE_TYPE (ptr_type);
+
+ /* At which point we can try some of the same things as for indirects. */
+ t = maybe_fold_offset_to_array_ref (op0, op1, ptd_type);
+ if (!t)
+ t = maybe_fold_offset_to_component_ref (TREE_TYPE (op0), op0, op1,
+ ptd_type, false);
+ if (t)
+ t = build1 (ADDR_EXPR, ptr_type, t);
+
+ return t;
+}
+
+/* Subroutine of fold_stmt called via walk_tree. We perform several
+ simplifications of EXPR_P, mostly having to do with pointer arithmetic. */
+
+static tree
+fold_stmt_r (tree *expr_p, int *walk_subtrees, void *data)
+{
+ bool *changed_p = data;
+ tree expr = *expr_p, t;
+
+ /* ??? It'd be nice if walk_tree had a pre-order option. */
+ switch (TREE_CODE (expr))
+ {
+ case INDIRECT_REF:
+ t = walk_tree (&TREE_OPERAND (expr, 0), fold_stmt_r, data, NULL);
+ if (t)
+ return t;
+ *walk_subtrees = 0;
+
+ t = maybe_fold_stmt_indirect (expr, TREE_OPERAND (expr, 0),
+ integer_zero_node);
+ break;
+
+ /* ??? Could handle ARRAY_REF here, as a variant of INDIRECT_REF.
+ We'd only want to bother decomposing an existing ARRAY_REF if
+ the base array is found to have another offset contained within.
+ Otherwise we'd be wasting time. */
+
+ case ADDR_EXPR:
+ t = walk_tree (&TREE_OPERAND (expr, 0), fold_stmt_r, data, NULL);
+ if (t)
+ return t;
+ *walk_subtrees = 0;
+
+ /* Set TREE_INVARIANT properly so that the value is properly
+ considered constant, and so gets propagated as expected. */
+ if (*changed_p)
+ recompute_tree_invarant_for_addr_expr (expr);
+ return NULL_TREE;
+
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ t = walk_tree (&TREE_OPERAND (expr, 0), fold_stmt_r, data, NULL);
+ if (t)
+ return t;
+ t = walk_tree (&TREE_OPERAND (expr, 1), fold_stmt_r, data, NULL);
+ if (t)
+ return t;
+ *walk_subtrees = 0;
+
+ t = maybe_fold_stmt_addition (expr);
+ break;
+
+ case COMPONENT_REF:
+ t = walk_tree (&TREE_OPERAND (expr, 0), fold_stmt_r, data, NULL);
+ if (t)
+ return t;
+ *walk_subtrees = 0;
+
+ /* Make sure the FIELD_DECL is actually a field in the type on
+ the lhs. In cases with IMA it is possible that it came
+ from another, equivalent type at this point. We have
+ already checked the equivalence in this case.
+ Match on type plus offset, to allow for unnamed fields.
+ We won't necessarily get the corresponding field for
+ unions; this is believed to be harmless. */
+
+ if ((current_file_decl && TREE_CHAIN (current_file_decl))
+ && (DECL_FIELD_CONTEXT (TREE_OPERAND (expr, 1)) !=
+ TREE_TYPE (TREE_OPERAND (expr, 0))))
+ {
+ tree f;
+ tree orig_field = TREE_OPERAND (expr, 1);
+ tree orig_type = TREE_TYPE (orig_field);
+ for (f = TYPE_FIELDS (TREE_TYPE (TREE_OPERAND (expr, 0)));
+ f; f = TREE_CHAIN (f))
+ {
+ if (lang_hooks.types_compatible_p (TREE_TYPE (f), orig_type)
+ && tree_int_cst_compare (DECL_FIELD_BIT_OFFSET (f),
+ DECL_FIELD_BIT_OFFSET (orig_field))
+ == 0
+ && tree_int_cst_compare (DECL_FIELD_OFFSET (f),
+ DECL_FIELD_OFFSET (orig_field))
+ == 0)
+ {
+ TREE_OPERAND (expr, 1) = f;
+ break;
+ }
+ }
+ /* Fall through is an error; it will be detected in tree-sra. */
+ }
+ break;
+
+ default:
+ return NULL_TREE;
+ }
+
+ if (t)
+ {
+ *expr_p = t;
+ *changed_p = true;
+ }
+
+ return NULL_TREE;
+}
+
+/* Fold the statement pointed by STMT_P. In some cases, this function may
+ replace the whole statement with a new one. Returns true iff folding
+ makes any changes. */
+
+bool
+fold_stmt (tree *stmt_p)
+{
+ tree rhs, result, stmt;
+ bool changed = false;
+
+ stmt = *stmt_p;
+
+ /* If we replaced constants and the statement makes pointer dereferences,
+ then we may need to fold instances of *&VAR into VAR, etc. */
+ if (walk_tree (stmt_p, fold_stmt_r, &changed, NULL))
+ {
+ *stmt_p
+ = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
+ NULL);
+ return true;
+ }
+
+ rhs = get_rhs (stmt);
+ if (!rhs)
+ return changed;
+ result = NULL_TREE;
+
+ /* Check for builtins that CCP can handle using information not
+ available in the generic fold routines. */
+ if (TREE_CODE (rhs) == CALL_EXPR)
+ {
+ tree callee = get_callee_fndecl (rhs);
+ if (callee && DECL_BUILT_IN (callee))
+ result = ccp_fold_builtin (stmt, rhs);
+ }
+
+ /* If we couldn't fold the RHS, hand over to the generic fold routines. */
+ if (result == NULL_TREE)
+ result = fold (rhs);
+
+ /* Strip away useless type conversions. Both the NON_LVALUE_EXPR that
+ may have been added by fold, and "useless" type conversions that might
+ now be apparent due to propagation. */
+ STRIP_MAIN_TYPE_NOPS (result);
+ STRIP_USELESS_TYPE_CONVERSION (result);
+
+ if (result != rhs)
+ {
+ changed = true;
+ set_rhs (stmt_p, result);
+ }
+
+ return changed;
+}
+
+/* Get the main expression from statement STMT. */
+
+static tree
+get_rhs (tree stmt)
+{
+ enum tree_code code = TREE_CODE (stmt);
+
+ if (code == MODIFY_EXPR)
+ return TREE_OPERAND (stmt, 1);
+ if (code == COND_EXPR)
+ return COND_EXPR_COND (stmt);
+ else if (code == SWITCH_EXPR)
+ return SWITCH_COND (stmt);
+ else if (code == RETURN_EXPR)
+ {
+ if (!TREE_OPERAND (stmt, 0))
+ return NULL_TREE;
+ if (TREE_CODE (TREE_OPERAND (stmt, 0)) == MODIFY_EXPR)
+ return TREE_OPERAND (TREE_OPERAND (stmt, 0), 1);
+ else
+ return TREE_OPERAND (stmt, 0);
+ }
+ else if (code == GOTO_EXPR)
+ return GOTO_DESTINATION (stmt);
+ else if (code == LABEL_EXPR)
+ return LABEL_EXPR_LABEL (stmt);
+ else
+ return stmt;
+}
+
+
+/* Set the main expression of *STMT_P to EXPR. */
+
+static void
+set_rhs (tree *stmt_p, tree expr)
+{
+ tree stmt = *stmt_p;
+ enum tree_code code = TREE_CODE (stmt);
+
+ if (code == MODIFY_EXPR)
+ TREE_OPERAND (stmt, 1) = expr;
+ else if (code == COND_EXPR)
+ COND_EXPR_COND (stmt) = expr;
+ else if (code == SWITCH_EXPR)
+ SWITCH_COND (stmt) = expr;
+ else if (code == RETURN_EXPR)
+ {
+ if (TREE_OPERAND (stmt, 0)
+ && TREE_CODE (TREE_OPERAND (stmt, 0)) == MODIFY_EXPR)
+ TREE_OPERAND (TREE_OPERAND (stmt, 0), 1) = expr;
+ else
+ TREE_OPERAND (stmt, 0) = expr;
+ }
+ else if (code == GOTO_EXPR)
+ GOTO_DESTINATION (stmt) = expr;
+ else if (code == LABEL_EXPR)
+ LABEL_EXPR_LABEL (stmt) = expr;
+ else
+ {
+ /* Replace the whole statement with EXPR. If EXPR has no side
+ effects, then replace *STMT_P with an empty statement. */
+ stmt_ann_t ann = stmt_ann (stmt);
+ *stmt_p = TREE_SIDE_EFFECTS (expr) ? expr : build_empty_stmt ();
+ (*stmt_p)->common.ann = (tree_ann) ann;
+
+ if (TREE_SIDE_EFFECTS (expr))
+ {
+ def_optype defs;
+ vdef_optype vdefs;
+ size_t i;
+
+ /* Fix all the SSA_NAMEs created by *STMT_P to point to its new
+ replacement. */
+ defs = DEF_OPS (ann);
+ for (i = 0; i < NUM_DEFS (defs); i++)
+ {
+ tree var = DEF_OP (defs, i);
+ if (TREE_CODE (var) == SSA_NAME)
+ SSA_NAME_DEF_STMT (var) = *stmt_p;
+ }
+
+ vdefs = VDEF_OPS (ann);
+ for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ {
+ tree var = VDEF_RESULT (vdefs, i);
+ if (TREE_CODE (var) == SSA_NAME)
+ SSA_NAME_DEF_STMT (var) = *stmt_p;
+ }
+ }
+ }
+}
+
+
+/* Return a default value for variable VAR using the following rules:
+
+ 1- Global and static variables are considered VARYING, unless they are
+ declared const.
+
+ 2- Function arguments are considered VARYING.
+
+ 3- Any other value is considered UNDEFINED. This is useful when
+ considering PHI nodes. PHI arguments that are undefined do not
+ change the constant value of the PHI node, which allows for more
+ constants to be propagated. */
+
+static value
+get_default_value (tree var)
+{
+ value val;
+ tree sym;
+
+ if (TREE_CODE (var) == SSA_NAME)
+ sym = SSA_NAME_VAR (var);
+ else
+ {
+#ifdef ENABLE_CHECKING
+ if (!DECL_P (var))
+ abort ();
+#endif
+ sym = var;
+ }
+
+ val.lattice_val = UNDEFINED;
+ val.const_val = NULL_TREE;
+
+ if (TREE_CODE (sym) == PARM_DECL || TREE_THIS_VOLATILE (sym))
+ {
+ /* Function arguments and volatile variables are considered VARYING. */
+ val.lattice_val = VARYING;
+ }
+ else if (decl_function_context (sym) != current_function_decl
+ || TREE_STATIC (sym))
+ {
+ /* Globals and static variables are considered VARYING, unless they
+ are declared 'const'. */
+ val.lattice_val = VARYING;
+
+ if (TREE_READONLY (sym)
+ && DECL_INITIAL (sym)
+ && is_gimple_min_invariant (DECL_INITIAL (sym)))
+ {
+ val.lattice_val = CONSTANT;
+ val.const_val = DECL_INITIAL (sym);
+ }
+ }
+ else
+ {
+ enum tree_code code;
+ tree stmt = SSA_NAME_DEF_STMT (var);
+
+ if (!IS_EMPTY_STMT (stmt))
+ {
+ code = TREE_CODE (stmt);
+ if (code != MODIFY_EXPR && code != PHI_NODE)
+ val.lattice_val = VARYING;
+ }
+ }
+
+ return val;
+}
+
+
+/* Fold builtin call FN in statement STMT. If it cannot be folded into a
+ constant, return NULL_TREE. Otherwise, return its constant value. */
+
+static tree
+ccp_fold_builtin (tree stmt, tree fn)
+{
+ tree result, strlen_val[2];
+ tree arglist = TREE_OPERAND (fn, 1), a;
+ tree callee = get_callee_fndecl (fn);
+ bitmap visited;
+ int strlen_arg, i;
+
+ /* Ignore MD builtins. */
+ if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_MD)
+ return NULL_TREE;
+
+ /* First try the generic builtin folder. If that succeeds, return the
+ result directly. */
+ result = fold_builtin (fn);
+ if (result)
+ return result;
+
+ /* If the builtin could not be folded, and it has no argument list,
+ we're done. */
+ if (!arglist)
+ return NULL_TREE;
+
+ /* Limit the work only for builtins we know how to simplify. */
+ switch (DECL_FUNCTION_CODE (callee))
+ {
+ case BUILT_IN_STRLEN:
+ case BUILT_IN_FPUTS:
+ case BUILT_IN_FPUTS_UNLOCKED:
+ strlen_arg = 1;
+ break;
+ case BUILT_IN_STRCPY:
+ case BUILT_IN_STRNCPY:
+ strlen_arg = 2;
+ break;
+ default:
+ return NULL_TREE;
+ }
+
+ /* Try to use the dataflow information gathered by the CCP process. */
+ visited = BITMAP_XMALLOC ();
+
+ memset (strlen_val, 0, sizeof (strlen_val));
+ for (i = 0, a = arglist;
+ strlen_arg;
+ i++, strlen_arg >>= 1, a = TREE_CHAIN (a))
+ if (strlen_arg & 1)
+ {
+ bitmap_clear (visited);
+ if (!get_strlen (TREE_VALUE (a), &strlen_val[i], visited))
+ strlen_val[i] = NULL_TREE;
+ }
+
+ BITMAP_XFREE (visited);
+
+ /* FIXME. All this code looks dangerous in the sense that it might
+ create non-gimple expressions. */
+ switch (DECL_FUNCTION_CODE (callee))
+ {
+ case BUILT_IN_STRLEN:
+ /* Convert from the internal "sizetype" type to "size_t". */
+ if (strlen_val[0]
+ && size_type_node)
+ {
+ tree new = convert (size_type_node, strlen_val[0]);
+
+ /* If the result is not a valid gimple value, or not a cast
+ of a valid gimple value, then we can not use the result. */
+ if (is_gimple_val (new)
+ || (is_gimple_cast (new)
+ && is_gimple_val (TREE_OPERAND (new, 0))))
+ return new;
+ else
+ return NULL_TREE;
+ }
+ return strlen_val[0];
+ case BUILT_IN_STRCPY:
+ if (strlen_val[1]
+ && is_gimple_val (strlen_val[1]))
+ return simplify_builtin_strcpy (arglist, strlen_val[1]);
+ case BUILT_IN_STRNCPY:
+ if (strlen_val[1]
+ && is_gimple_val (strlen_val[1]))
+ return simplify_builtin_strncpy (arglist, strlen_val[1]);
+ case BUILT_IN_FPUTS:
+ return simplify_builtin_fputs (arglist,
+ TREE_CODE (stmt) != MODIFY_EXPR, 0,
+ strlen_val[0]);
+ case BUILT_IN_FPUTS_UNLOCKED:
+ return simplify_builtin_fputs (arglist,
+ TREE_CODE (stmt) != MODIFY_EXPR, 1,
+ strlen_val[0]);
+
+ default:
+ abort ();
+ }
+
+ return NULL_TREE;
+}
+
+
+/* Return the string length of ARG in LENGTH. If ARG is an SSA name variable,
+ follow its use-def chains. If LENGTH is not NULL and its value is not
+ equal to the length we determine, or if we are unable to determine the
+ length, return false. VISITED is a bitmap of visited variables. */
+
+static bool
+get_strlen (tree arg, tree *length, bitmap visited)
+{
+ tree var, def_stmt, val;
+
+ if (TREE_CODE (arg) != SSA_NAME)
+ {
+ val = c_strlen (arg, 1);
+ if (!val)
+ return false;
+
+ if (*length && simple_cst_equal (val, *length) != 1)
+ return false;
+
+ *length = val;
+ return true;
+ }
+
+ /* If we were already here, break the infinite cycle. */
+ if (bitmap_bit_p (visited, SSA_NAME_VERSION (arg)))
+ return true;
+ bitmap_set_bit (visited, SSA_NAME_VERSION (arg));
+
+ var = arg;
+ def_stmt = SSA_NAME_DEF_STMT (var);
+
+ switch (TREE_CODE (def_stmt))
+ {
+ case MODIFY_EXPR:
+ {
+ tree len, rhs;
+
+ /* The RHS of the statement defining VAR must either have a
+ constant length or come from another SSA_NAME with a constant
+ length. */
+ rhs = TREE_OPERAND (def_stmt, 1);
+ STRIP_NOPS (rhs);
+ if (TREE_CODE (rhs) == SSA_NAME)
+ return get_strlen (rhs, length, visited);
+
+ /* See if the RHS is a constant length. */
+ len = c_strlen (rhs, 1);
+ if (len)
+ {
+ if (*length && simple_cst_equal (len, *length) != 1)
+ return false;
+
+ *length = len;
+ return true;
+ }
+
+ break;
+ }
+
+ case PHI_NODE:
+ {
+ /* All the arguments of the PHI node must have the same constant
+ length. */
+ int i;
+
+ for (i = 0; i < PHI_NUM_ARGS (def_stmt); i++)
+ {
+ tree arg = PHI_ARG_DEF (def_stmt, i);
+
+ /* If this PHI has itself as an argument, we cannot
+ determine the string length of this argument. However,
+ if we can find a constant string length for the other
+ PHI args then we can still be sure that this is a
+ constant string length. So be optimistic and just
+ continue with the next argument. */
+ if (arg == PHI_RESULT (def_stmt))
+ continue;
+
+ if (!get_strlen (arg, length, visited))
+ return false;
+ }
+
+ return true;
+ }
+
+ default:
+ break;
+ }
+
+
+ return false;
+}
+
+
+/* A simple pass that attempts to fold all builtin functions. This pass
+ is run after we've propagated as many constants as we can. */
+
+static void
+execute_fold_all_builtins (void)
+{
+ basic_block bb;
+ FOR_EACH_BB (bb)
+ {
+ block_stmt_iterator i;
+ for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
+ {
+ tree *stmtp = bsi_stmt_ptr (i);
+ tree call = get_rhs (*stmtp);
+ tree callee, result;
+
+ if (!call || TREE_CODE (call) != CALL_EXPR)
+ continue;
+ callee = get_callee_fndecl (call);
+ if (!callee || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL)
+ continue;
+
+ result = ccp_fold_builtin (*stmtp, call);
+ if (!result)
+ switch (DECL_FUNCTION_CODE (callee))
+ {
+ case BUILT_IN_CONSTANT_P:
+ /* Resolve __builtin_constant_p. If it hasn't been
+ folded to integer_one_node by now, it's fairly
+ certain that the value simply isn't constant. */
+ result = integer_zero_node;
+ break;
+
+ default:
+ continue;
+ }
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Simplified\n ");
+ print_generic_stmt (dump_file, *stmtp, dump_flags);
+ }
+
+ set_rhs (stmtp, result);
+ modify_stmt (*stmtp);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "to\n ");
+ print_generic_stmt (dump_file, *stmtp, dump_flags);
+ fprintf (dump_file, "\n");
+ }
+ }
+ }
+}
+
+struct tree_opt_pass pass_fold_builtins =
+{
+ "fab", /* name */
+ NULL, /* gate */
+ execute_fold_all_builtins, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ PROP_cfg | PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */
+};
+
+
+#include "gt-tree-ssa-ccp.h"
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
new file mode 100644
index 00000000000..ca9f0cce81a
--- /dev/null
+++ b/gcc/tree-ssa-copy.c
@@ -0,0 +1,355 @@
+/* Const/copy propagation and SSA_NAME replacement support routines.
+ Copyright (C) 2004 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 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "flags.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "ggc.h"
+#include "basic-block.h"
+#include "output.h"
+#include "errors.h"
+#include "expr.h"
+#include "function.h"
+#include "diagnostic.h"
+#include "timevar.h"
+#include "tree-dump.h"
+#include "tree-flow.h"
+#include "tree-pass.h"
+#include "langhooks.h"
+
+/* This file provides a handful of interfaces for performing const/copy
+ propagation and simple expression replacement which keep variable
+ annotations up-to-date.
+
+ We require that for any copy operation where the RHS and LHS have
+ a non-null memory tag that the memory tag be the same. It is OK
+ for one or both of the memory tags to be NULL.
+
+ We also require tracking if a variable is dereferenced in a load or
+ store operation.
+
+ We enforce these requirements by having all copy propagation and
+ replacements of one SSA_NAME with a different SSA_NAME to use the
+ APIs defined in this file. */
+
+/* Given two SSA_NAMEs, replace the one pointed to by OP_P with VAR.
+
+ If *OP_P is a pointer, copy the memory tag used originally by *OP_P into
+ VAR. This is needed in cases where VAR had never been dereferenced in the
+ program.
+
+ If FOR_PROPAGATION is true, then perform additional checks to ensure
+ that const/copy propagation of var for *OP_P is valid. */
+
+static void
+replace_ssa_names (tree *op_p,
+ tree var,
+ bool for_propagation ATTRIBUTE_UNUSED)
+{
+#if defined ENABLE_CHECKING
+ if (for_propagation && !may_propagate_copy (*op_p, var))
+ abort ();
+#endif
+
+ /* If VAR doesn't have a memory tag, copy the one from the original
+ operand. Also copy the dereferenced flags. */
+ if (POINTER_TYPE_P (TREE_TYPE (*op_p)))
+ {
+ var_ann_t new_ann = var_ann (SSA_NAME_VAR (var));
+ var_ann_t orig_ann = var_ann (SSA_NAME_VAR (*op_p));
+
+ if (new_ann->type_mem_tag == NULL_TREE)
+ new_ann->type_mem_tag = orig_ann->type_mem_tag;
+ else if (orig_ann->type_mem_tag == NULL_TREE)
+ orig_ann->type_mem_tag = new_ann->type_mem_tag;
+ else if (new_ann->type_mem_tag != orig_ann->type_mem_tag)
+ abort ();
+ }
+
+ *op_p = var;
+}
+
+/* Common code for propagate_value and replace_exp.
+
+ Replace *OP_P with VAL. FOR_PROPAGATION indicates if the replacement
+ is done to propagate a value or not. */
+
+static void
+replace_exp_1 (tree *op_p, tree val, bool for_propagation)
+{
+ if (TREE_CODE (val) == SSA_NAME)
+ {
+ if (TREE_CODE (*op_p) == SSA_NAME)
+ replace_ssa_names (op_p, val, for_propagation);
+ else
+ *op_p = val;
+ }
+ else
+ *op_p = lhd_unsave_expr_now (val);
+}
+
+/* Propagate the value VAL (assumed to be a constant or another SSA_NAME)
+ into the operand pointed by OP_P.
+
+ Use this version for const/copy propagation as it will perform additional
+ checks to ensure validity of the const/copy propagation. */
+
+void
+propagate_value (tree *op_p, tree val)
+{
+ replace_exp_1 (op_p, val, true);
+}
+
+/* Replace *OP_P with value VAL (assumed to be a constant or another SSA_NAME).
+
+ Use this version when not const/copy propagating values. For example,
+ PRE uses this version when building expressions as they would appear
+ in specific blocks taking into account actions of PHI nodes. */
+
+void
+replace_exp (tree *op_p, tree val)
+{
+ replace_exp_1 (op_p, val, false);
+}
+
+/* Replace *OP_P in STMT with any known equivalent value for *OP_P from
+ CONST_AND_COPIES. */
+
+static bool
+cprop_operand (stmt_ann_t ann, tree *op_p, varray_type const_and_copies)
+{
+ bool may_have_exposed_new_symbols = false;
+ tree val;
+
+ /* If the operand has a known constant value or it is known to be a
+ copy of some other variable, use the value or copy stored in
+ CONST_AND_COPIES. */
+ val = VARRAY_TREE (const_and_copies, SSA_NAME_VERSION (*op_p));
+ if (val)
+ {
+ tree op_type, val_type;
+
+ /* Do not change the base variable in the virtual operand
+ tables. That would make it impossible to reconstruct
+ the renamed virtual operand if we later modify this
+ statement. Also only allow the new value to be an SSA_NAME
+ for propagation into virtual operands. */
+ if (!is_gimple_reg (*op_p)
+ && (get_virtual_var (val) != get_virtual_var (*op_p)
+ || TREE_CODE (val) != SSA_NAME))
+ return false;
+
+ /* Get the toplevel type of each operand. */
+ op_type = TREE_TYPE (*op_p);
+ val_type = TREE_TYPE (val);
+
+ /* While both types are pointers, get the type of the object
+ pointed to. */
+ while (POINTER_TYPE_P (op_type) && POINTER_TYPE_P (val_type))
+ {
+ op_type = TREE_TYPE (op_type);
+ val_type = TREE_TYPE (val_type);
+ }
+
+ /* Make sure underlying types match before propagating a
+ constant by converting the constant to the proper type. Note
+ that convert may return a non-gimple expression, in which case
+ we ignore this propagation opportunity. */
+ if (!lang_hooks.types_compatible_p (op_type, val_type)
+ && TREE_CODE (val) != SSA_NAME)
+ {
+ val = convert (TREE_TYPE (*op_p), val);
+ if (!is_gimple_min_invariant (val)
+ && TREE_CODE (val) != SSA_NAME)
+ return false;
+ }
+
+ /* Certain operands are not allowed to be copy propagated due
+ to their interaction with exception handling and some GCC
+ extensions. */
+ if (TREE_CODE (val) == SSA_NAME
+ && !may_propagate_copy (*op_p, val))
+ return false;
+
+ /* Dump details. */
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, " Replaced '");
+ print_generic_expr (dump_file, *op_p, dump_flags);
+ fprintf (dump_file, "' with %s '",
+ (TREE_CODE (val) != SSA_NAME ? "constant" : "variable"));
+ print_generic_expr (dump_file, val, dump_flags);
+ fprintf (dump_file, "'\n");
+ }
+
+ /* If VAL is an ADDR_EXPR or a constant of pointer type, note
+ that we may have exposed a new symbol for SSA renaming. */
+ if (TREE_CODE (val) == ADDR_EXPR
+ || (POINTER_TYPE_P (TREE_TYPE (*op_p))
+ && is_gimple_min_invariant (val)))
+ may_have_exposed_new_symbols = true;
+
+ propagate_value (op_p, val);
+
+ /* And note that we modified this statement. This is now
+ safe, even if we changed virtual operands since we will
+ rescan the statement and rewrite its operands again. */
+ ann->modified = 1;
+ }
+ return may_have_exposed_new_symbols;
+}
+
+/* CONST_AND_COPIES is a table which maps an SSA_NAME to the current
+ known value for that SSA_NAME (or NULL if no value is known).
+
+ Propagate values from CONST_AND_COPIES into the uses, vuses and
+ vdef_ops of STMT. */
+
+bool
+cprop_into_stmt (tree stmt, varray_type const_and_copies)
+{
+ bool may_have_exposed_new_symbols = false;
+ stmt_ann_t ann = stmt_ann (stmt);
+ size_t i, num_uses, num_vuses, num_vdefs;
+ vuse_optype vuses;
+ vdef_optype vdefs;
+ use_optype uses;
+
+ uses = USE_OPS (ann);
+ num_uses = NUM_USES (uses);
+ for (i = 0; i < num_uses; i++)
+ {
+ tree *op_p = USE_OP_PTR (uses, i);
+ if (TREE_CODE (*op_p) == SSA_NAME)
+ may_have_exposed_new_symbols
+ |= cprop_operand (ann, op_p, const_and_copies);
+ }
+
+ vuses = VUSE_OPS (ann);
+ num_vuses = NUM_VUSES (vuses);
+ for (i = 0; i < num_vuses; i++)
+ {
+ tree *op_p = VUSE_OP_PTR (vuses, i);
+ if (TREE_CODE (*op_p) == SSA_NAME)
+ may_have_exposed_new_symbols
+ |= cprop_operand (ann, op_p, const_and_copies);
+ }
+
+ vdefs = VDEF_OPS (ann);
+ num_vdefs = NUM_VDEFS (vdefs);
+ for (i = 0; i < num_vdefs; i++)
+ {
+ tree *op_p = VDEF_OP_PTR (vdefs, i);
+ if (TREE_CODE (*op_p) == SSA_NAME)
+ may_have_exposed_new_symbols
+ |= cprop_operand (ann, op_p, const_and_copies);
+ }
+ return may_have_exposed_new_symbols;
+}
+
+/* CONST_AND_COPIES is a table which maps an SSA_NAME to the current
+ known value for that SSA_NAME (or NULL if no value is known).
+
+ Propagate values from CONST_AND_COPIES into the PHI nodes of the
+ successors of BB. */
+
+void
+cprop_into_successor_phis (basic_block bb, varray_type const_and_copies)
+{
+ edge e;
+
+ /* This can get rather expensive if the implementation is naive in
+ how it finds the phi alternative associated with a particular edge. */
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ tree phi;
+ int phi_num_args;
+ int hint;
+
+ /* If this is an abnormal edge, then we do not want to copy propagate
+ into the PHI alternative associated with this edge. */
+ if (e->flags & EDGE_ABNORMAL)
+ continue;
+
+ phi = phi_nodes (e->dest);
+ if (! phi)
+ continue;
+
+ /* There is no guarantee that for any two PHI nodes in a block that
+ the phi alternative associated with a particular edge will be
+ at the same index in the phi alternative array.
+
+ However, it is very likely they will be the same. So we keep
+ track of the index of the alternative where we found the edge in
+ the previous phi node and check that index first in the next
+ phi node. If that hint fails, then we actually search all
+ the entries. */
+ phi_num_args = PHI_NUM_ARGS (phi);
+ hint = phi_num_args;
+ for ( ; phi; phi = TREE_CHAIN (phi))
+ {
+ int i;
+ tree new;
+ tree *orig_p;
+
+ /* If the hint is valid (!= phi_num_args), see if it points
+ us to the desired phi alternative. */
+ if (hint != phi_num_args && PHI_ARG_EDGE (phi, hint) == e)
+ ;
+ else
+ {
+ /* The hint was either invalid or did not point to the
+ correct phi alternative. Search all the alternatives
+ for the correct one. Update the hint. */
+ for (i = 0; i < phi_num_args; i++)
+ if (PHI_ARG_EDGE (phi, i) == e)
+ break;
+ hint = i;
+ }
+
+#ifdef ENABLE_CHECKING
+ /* If we did not find the proper alternative, then something is
+ horribly wrong. */
+ if (hint == phi_num_args)
+ abort ();
+#endif
+
+ /* The alternative may be associated with a constant, so verify
+ it is an SSA_NAME before doing anything with it. */
+ orig_p = &PHI_ARG_DEF (phi, hint);
+ if (TREE_CODE (*orig_p) != SSA_NAME)
+ continue;
+
+ /* If we have *ORIG_P in our constant/copy table, then replace
+ ORIG_P with its value in our constant/copy table. */
+ new = VARRAY_TREE (const_and_copies, SSA_NAME_VERSION (*orig_p));
+ if (new
+ && (TREE_CODE (new) == SSA_NAME
+ || is_gimple_min_invariant (new))
+ && may_propagate_copy (*orig_p, new))
+ propagate_value (orig_p, new);
+ }
+ }
+}
diff --git a/gcc/tree-ssa-copyrename.c b/gcc/tree-ssa-copyrename.c
new file mode 100644
index 00000000000..dd698835f06
--- /dev/null
+++ b/gcc/tree-ssa-copyrename.c
@@ -0,0 +1,388 @@
+/* Rename SSA copies.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ Contributed by Andrew MacLeod <amacleod@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "flags.h"
+#include "basic-block.h"
+#include "function.h"
+#include "diagnostic.h"
+#include "bitmap.h"
+#include "tree-flow.h"
+#include "tree-gimple.h"
+#include "tree-inline.h"
+#include "timevar.h"
+#include "tree-alias-common.h"
+#include "hashtab.h"
+#include "tree-dump.h"
+#include "tree-ssa-live.h"
+#include "tree-pass.h"
+
+extern void rename_ssa_copies (void);
+
+/* The following routines implement the SSA copy renaming phase.
+
+ This optimization looks for copies between 2 SSA_NAMES, either through a
+ direct copy, or an implicit one via a PHI node result and its arguments.
+
+ Each copy is examined to determine if it is possible to rename the base
+ variable of one of the operands to the same variable as the other operand.
+ ie.
+ T.3_5 = <blah>
+ a_1 = T.3_5
+
+ If this copy couldn't be copy propagated, it could possibly remain in the
+ program throughout the optimization phases. After SSA->normal, it would
+ become:
+
+ T.3 = <blah>
+ a = T.3
+
+ Since T.3_5 is distinct from all other SSA versions of T.3, there is no
+ fundamental reason why the base variable needs to be T.3, subject to
+ certain restrictions. This optimization attempts to determine if we can
+ change the base variable on copies like this, and result in code such as:
+
+ a_5 = <blah>
+ a_1 = a_5
+
+ This gives the SSA->normal pass a shot at coalescing a_1 and a_5. If it is
+ possible, the copy goes away completely. If it isn't possible, a new temp
+ will be created for a_5, and you will end up with the exact same code:
+
+ a.8 = <blah>
+ a = a.8
+
+ The other benefit of performing this optimization relates to what variables
+ are chosen in copies. Gimplification of the program uses temporaries for
+ a lot of things. expressions like
+
+ a_1 = <blah>
+ <blah2> = a_1
+
+ get turned into
+
+ T.3_5 = <blah>
+ a_1 = T.3_5
+ <blah2> = a_1
+
+ Copy propagation is done in a forward direction, and if we can propagate
+ through the copy, we end up with:
+
+ T.3_5 = <blah>
+ <blah2> = T.3_5
+
+ The copy is gone, but so is all reference to the user variable 'a'. By
+ performing this optimization, we would see the sequence:
+
+ a_5 = <blah>
+ a_1 = a_5
+ <blah2> = a_1
+
+ which copy propagation would then turn into:
+
+ a_5 = <blah>
+ <blah2> = a_5
+
+ and so we still retain the user variable whenever possible. */
+
+
+/* Coalesce the partitions in MAP representing VAR1 and VAR2 if it is valid.
+ Choose a representative for the partition, and send debug info to DEBUG. */
+
+static void
+copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
+{
+ int p1, p2, p3;
+ tree root1, root2;
+ var_ann_t ann1, ann2, ann3;
+ bool gimp1, gimp2;
+
+#ifdef ENABLE_CHECKING
+ if (TREE_CODE (var1) != SSA_NAME || TREE_CODE (var2) != SSA_NAME)
+ abort ();
+#endif
+
+ register_ssa_partition (map, var1, false);
+ register_ssa_partition (map, var2, true);
+
+ p1 = partition_find (map->var_partition, SSA_NAME_VERSION (var1));
+ p2 = partition_find (map->var_partition, SSA_NAME_VERSION (var2));
+
+ if (debug)
+ {
+ fprintf (debug, "Try : ");
+ print_generic_expr (debug, var1, TDF_SLIM);
+ fprintf (debug, "(P%d) & ", p1);
+ print_generic_expr (debug, var2, TDF_SLIM);
+ fprintf (debug, "(P%d)", p2);
+ }
+
+#ifdef ENABLE_CHECKING
+ if (p1 == NO_PARTITION || p2 == NO_PARTITION)
+ abort ();
+#endif
+
+ root1 = SSA_NAME_VAR (partition_to_var (map, p1));
+ root2 = SSA_NAME_VAR (partition_to_var (map, p2));
+
+ if (DECL_HARD_REGISTER (root1) || DECL_HARD_REGISTER (root2))
+ {
+ if (debug)
+ {
+ if (DECL_HARD_REGISTER (root1))
+ print_generic_expr (debug, var1, TDF_SLIM);
+ else
+ print_generic_expr (debug, var2, TDF_SLIM);
+ fprintf (debug, " is a hardware register. No Coalescing.\n");
+ }
+ return;
+ }
+
+ ann1 = var_ann (root1);
+ ann2 = var_ann (root2);
+
+ if (p1 == p2)
+ {
+ if (debug)
+ fprintf (debug, " : Already coalesced.\n");
+ return;
+ }
+
+ /* Partitions already have the same root, simply merge them. */
+ if (root1 == root2)
+ {
+ p1 = partition_union (map->var_partition, p1, p2);
+ if (debug)
+ fprintf (debug, " : Same root, coalesced --> P%d.\n", p1);
+ return;
+ }
+
+ /* Never attempt to coalesce 2 difference parameters. */
+ if (TREE_CODE (root1) == PARM_DECL && TREE_CODE (root2) == PARM_DECL)
+ {
+ if (debug)
+ fprintf (debug, " : 2 different PARM_DECLS. No coalesce.\n");
+ return;
+ }
+
+ gimp1 = is_gimple_tmp_var (root1);
+ gimp2 = is_gimple_tmp_var (root2);
+
+ /* Never attempt to coalesce 2 user variables unless one is an inline
+ variable. */
+ if (!gimp1 && !gimp2)
+ {
+ if (DECL_FROM_INLINE (root2))
+ gimp2 = true;
+ else
+ if (DECL_FROM_INLINE (root1))
+ gimp1 = true;
+ else
+ {
+ if (debug)
+ fprintf (debug, " : 2 different USER vars. No coalesce.\n");
+ return;
+ }
+ }
+
+
+ /* Don't coalesce if there are two different memory tags. */
+ if (ann1->type_mem_tag && ann2->type_mem_tag
+ && ann1->type_mem_tag != ann2->type_mem_tag)
+ {
+ if (debug)
+ fprintf (debug, " : 2 memory tags. No coalesce.\n");
+ return;
+ }
+
+ /* If both values have default defs, we can't coalesce. If only one has a
+ tag, make sure that variable is the new root partition. */
+ if (default_def (root1))
+ {
+ if (default_def (root2))
+ {
+ if (debug)
+ fprintf (debug, " : 2 default defs. No coalesce.\n");
+ return;
+ }
+ else
+ {
+ gimp2 = true;
+ gimp1 = false;
+ }
+ }
+ else
+ if (default_def (root2))
+ {
+ gimp1 = true;
+ gimp2 = false;
+ }
+
+ /* Merge the two partitions. */
+ p3 = partition_union (map->var_partition, p1, p2);
+
+ /* Set the root variable of the partition to the better choice, if there is
+ one. */
+ if (!gimp2)
+ SSA_NAME_VAR (partition_to_var (map, p3)) = root2;
+ else
+ if (!gimp1)
+ SSA_NAME_VAR (partition_to_var (map, p3)) = root1;
+
+ /* Update the various flag widgitry of the current base representative. */
+ ann3 = var_ann (SSA_NAME_VAR (partition_to_var (map, p3)));
+ if (ann1->type_mem_tag)
+ ann3->type_mem_tag = ann1->type_mem_tag;
+ else
+ ann3->type_mem_tag = ann2->type_mem_tag;
+
+ if (debug)
+ {
+ fprintf (debug, " --> P%d ", p3);
+ print_generic_expr (debug, SSA_NAME_VAR (partition_to_var (map, p3)),
+ TDF_SLIM);
+ fprintf (debug, "\n");
+ }
+}
+
+
+/* This function will make a pass through the IL, and attempt to coalesce any
+ SSA versions which occur in PHI's or copies. Coalescing is accomplished by
+ changing the underlying root variable of all coalesced version. This will
+ then cause the SSA->normal pass to attempt to coalesce them all to the same
+ variable. */
+
+void
+rename_ssa_copies (void)
+{
+ var_map map;
+ basic_block bb;
+ block_stmt_iterator bsi;
+ tree phi, stmt, var, part_var;
+ unsigned x;
+ FILE *debug;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ debug = dump_file;
+ else
+ debug = NULL;
+
+ map = init_var_map (highest_ssa_version + 1);
+
+ FOR_EACH_BB (bb)
+ {
+ /* Scan for real copies. */
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ stmt = bsi_stmt (bsi);
+ if (TREE_CODE (stmt) == MODIFY_EXPR)
+ {
+ tree lhs = TREE_OPERAND (stmt, 0);
+ tree rhs = TREE_OPERAND (stmt, 1);
+
+ if (TREE_CODE (lhs) == SSA_NAME
+ && !has_hidden_use (SSA_NAME_VAR (lhs))
+ && TREE_CODE (rhs) == SSA_NAME)
+ copy_rename_partition_coalesce (map, lhs, rhs, debug);
+ }
+ }
+ }
+
+ FOR_EACH_BB (bb)
+ {
+ /* Treat PHI nodes as copies between the result and each argument. */
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ int i;
+ tree res = PHI_RESULT (phi);
+
+ /* Do not process virtual SSA_NAMES or variables which have
+ hidden uses. */
+ if (!is_gimple_reg (SSA_NAME_VAR (res))
+ || has_hidden_use (SSA_NAME_VAR (res)))
+ continue;
+
+ for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ {
+ tree arg = PHI_ARG_DEF (phi, i);
+ if (TREE_CODE (arg) == SSA_NAME)
+ copy_rename_partition_coalesce (map, res, arg, debug);
+ }
+ }
+ }
+
+ if (debug)
+ dump_var_map (debug, map);
+
+ /* Now one more pass to make all elements of a partition share the same
+ root variable. */
+
+ for (x = 1; x <= highest_ssa_version; x++)
+ {
+ part_var = partition_to_var (map, x);
+ if (!part_var)
+ continue;
+ var = map->partition_to_var[x];
+ if (debug)
+ {
+ if (SSA_NAME_VAR (var) != SSA_NAME_VAR (part_var))
+ {
+ fprintf (debug, "Coalesced ");
+ print_generic_expr (debug, var, TDF_SLIM);
+ fprintf (debug, " to ");
+ print_generic_expr (debug, part_var, TDF_SLIM);
+ fprintf (debug, "\n");
+ }
+ }
+ SSA_NAME_VAR (var) = SSA_NAME_VAR (part_var);
+ }
+
+ delete_var_map (map);
+}
+
+/* Return true if copy rename is to be performed. */
+
+static bool
+gate_copyrename (void)
+{
+ return flag_tree_copyrename != 0;
+}
+
+struct tree_opt_pass pass_rename_ssa_copies =
+{
+ "copyrename", /* name */
+ gate_copyrename, /* gate */
+ rename_ssa_copies, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_COPY_RENAME, /* tv_id */
+ PROP_cfg | PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */
+};
+
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
new file mode 100644
index 00000000000..7921a9f0cf6
--- /dev/null
+++ b/gcc/tree-ssa-dce.c
@@ -0,0 +1,913 @@
+/* Dead code elimination pass for the GNU compiler.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Ben Elliston <bje@redhat.com>
+ and Andrew MacLeod <amacleod@redhat.com>
+ Adapted to use control dependence by Steven Bosscher, SUSE Labs.
+
+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 2, or (at your option) any
+later version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Dead code elimination.
+
+ References:
+
+ Building an Optimizing Compiler,
+ Robert Morgan, Butterworth-Heinemann, 1998, Section 8.9.
+
+ Advanced Compiler Design and Implementation,
+ Steven Muchnick, Morgan Kaufmann, 1997, Section 18.10.
+
+ Dead-code elimination is the removal of statements which have no
+ impact on the program's output. "Dead statements" have no impact
+ on the program's output, while "necessary statements" may have
+ impact on the output.
+
+ The algorithm consists of three phases:
+ 1. Marking as necessary all statements known to be necessary,
+ e.g. most function calls, writing a value to memory, etc;
+ 2. Propagating necessary statements, e.g., the statements
+ giving values to operands in necessary statements; and
+ 3. Removing dead statements. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "errors.h"
+#include "ggc.h"
+
+/* These RTL headers are needed for basic-block.h. */
+#include "rtl.h"
+#include "tm_p.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+
+#include "tree.h"
+#include "diagnostic.h"
+#include "tree-flow.h"
+#include "tree-gimple.h"
+#include "tree-dump.h"
+#include "tree-pass.h"
+#include "timevar.h"
+#include "flags.h"
+
+static struct stmt_stats
+{
+ int total;
+ int total_phis;
+ int removed;
+ int removed_phis;
+} stats;
+
+static varray_type worklist;
+
+/* Vector indicating an SSA name has already been processed and marked
+ as necessary. */
+static sbitmap processed;
+
+/* Vector indicating that last_stmt if a basic block has already been
+ marked as necessary. */
+static sbitmap last_stmt_necessary;
+
+/* Before we can determine whether a control branch is dead, we need to
+ compute which blocks are control dependent on which edges.
+
+ We expect each block to be control dependent on very few edges so we
+ use a bitmap for each block recording its edges. An array holds the
+ bitmap. The Ith bit in the bitmap is set if that block is dependent
+ on the Ith edge. */
+bitmap *control_dependence_map;
+
+/* Execute CODE for each edge (given number EDGE_NUMBER within the CODE)
+ for which the block with index N is control dependent. */
+#define EXECUTE_IF_CONTROL_DEPENDENT(N, EDGE_NUMBER, CODE) \
+ EXECUTE_IF_SET_IN_BITMAP (control_dependence_map[N], 0, EDGE_NUMBER, CODE)
+
+/* Local function prototypes. */
+static inline void set_control_dependence_map_bit (basic_block, int);
+static inline void clear_control_dependence_bitmap (basic_block);
+static void find_all_control_dependences (struct edge_list *);
+static void find_control_dependence (struct edge_list *, int);
+static inline basic_block find_pdom (basic_block);
+
+static inline void mark_stmt_necessary (tree, bool);
+static inline void mark_operand_necessary (tree);
+
+static bool need_to_preserve_store (tree);
+static void mark_stmt_if_obviously_necessary (tree, bool);
+static void find_obviously_necessary_stmts (struct edge_list *);
+
+static void mark_control_dependent_edges_necessary (basic_block, struct edge_list *);
+static void propagate_necessity (struct edge_list *);
+
+static void eliminate_unnecessary_stmts (void);
+static void remove_dead_phis (basic_block);
+static void remove_dead_stmt (block_stmt_iterator *, basic_block);
+
+static void print_stats (void);
+static void tree_dce_init (bool);
+static void tree_dce_done (bool);
+
+/* Indicate block BB is control dependent on an edge with index EDGE_INDEX. */
+static inline void
+set_control_dependence_map_bit (basic_block bb, int edge_index)
+{
+ if (bb == ENTRY_BLOCK_PTR)
+ return;
+ if (bb == EXIT_BLOCK_PTR)
+ abort ();
+ bitmap_set_bit (control_dependence_map[bb->index], edge_index);
+}
+
+/* Clear all control dependences for block BB. */
+static inline
+void clear_control_dependence_bitmap (basic_block bb)
+{
+ bitmap_clear (control_dependence_map[bb->index]);
+}
+
+/* Record all blocks' control dependences on all edges in the edge
+ list EL, ala Morgan, Section 3.6. */
+
+static void
+find_all_control_dependences (struct edge_list *el)
+{
+ int i;
+
+ for (i = 0; i < NUM_EDGES (el); ++i)
+ find_control_dependence (el, i);
+}
+
+/* Determine all blocks' control dependences on the given edge with edge_list
+ EL index EDGE_INDEX, ala Morgan, Section 3.6. */
+
+static void
+find_control_dependence (struct edge_list *el, int edge_index)
+{
+ basic_block current_block;
+ basic_block ending_block;
+
+#ifdef ENABLE_CHECKING
+ if (INDEX_EDGE_PRED_BB (el, edge_index) == EXIT_BLOCK_PTR)
+ abort ();
+#endif
+
+ if (INDEX_EDGE_PRED_BB (el, edge_index) == ENTRY_BLOCK_PTR)
+ ending_block = ENTRY_BLOCK_PTR->next_bb;
+ else
+ ending_block = find_pdom (INDEX_EDGE_PRED_BB (el, edge_index));
+
+ for (current_block = INDEX_EDGE_SUCC_BB (el, edge_index);
+ current_block != ending_block && current_block != EXIT_BLOCK_PTR;
+ current_block = find_pdom (current_block))
+ {
+ edge e = INDEX_EDGE (el, edge_index);
+
+ /* For abnormal edges, we don't make current_block control
+ dependent because instructions that throw are always necessary
+ anyway. */
+ if (e->flags & EDGE_ABNORMAL)
+ continue;
+
+ set_control_dependence_map_bit (current_block, edge_index);
+ }
+}
+
+/* Find the immediate postdominator PDOM of the specified basic block BLOCK.
+ This function is necessary because some blocks have negative numbers. */
+
+static inline basic_block
+find_pdom (basic_block block)
+{
+ if (block == ENTRY_BLOCK_PTR)
+ abort ();
+ else if (block == EXIT_BLOCK_PTR)
+ return EXIT_BLOCK_PTR;
+ else
+ {
+ basic_block bb = get_immediate_dominator (CDI_POST_DOMINATORS, block);
+ if (! bb)
+ return EXIT_BLOCK_PTR;
+ return bb;
+ }
+}
+
+#define NECESSARY(stmt) stmt->common.asm_written_flag
+
+/* If STMT is not already marked necessary, mark it, and add it to the
+ worklist if ADD_TO_WORKLIST is true. */
+static inline void
+mark_stmt_necessary (tree stmt, bool add_to_worklist)
+{
+#ifdef ENABLE_CHECKING
+ if (stmt == NULL
+ || stmt == error_mark_node
+ || (stmt && DECL_P (stmt)))
+ abort ();
+#endif
+
+ if (NECESSARY (stmt))
+ return;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Marking useful stmt: ");
+ print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ fprintf (dump_file, "\n");
+ }
+
+ NECESSARY (stmt) = 1;
+ if (add_to_worklist)
+ VARRAY_PUSH_TREE (worklist, stmt);
+}
+
+/* Mark the statement defining operand OP as necessary. */
+
+static inline void
+mark_operand_necessary (tree op)
+{
+ tree stmt;
+ int ver;
+
+#ifdef ENABLE_CHECKING
+ if (op == NULL)
+ abort ();
+#endif
+
+ ver = SSA_NAME_VERSION (op);
+ if (TEST_BIT (processed, ver))
+ return;
+ SET_BIT (processed, ver);
+
+ stmt = SSA_NAME_DEF_STMT (op);
+#ifdef ENABLE_CHECKING
+ if (stmt == NULL)
+ abort ();
+#endif
+
+ if (NECESSARY (stmt)
+ || IS_EMPTY_STMT (stmt))
+ return;
+
+ NECESSARY (stmt) = 1;
+ VARRAY_PUSH_TREE (worklist, stmt);
+}
+
+/* Return true if a store to a variable needs to be preserved. */
+
+static inline bool
+need_to_preserve_store (tree ssa_name)
+{
+ return (needs_to_live_in_memory (SSA_NAME_VAR (ssa_name)));
+}
+
+
+/* Mark STMT as necessary if it is obviously is. Add it to the worklist if
+ it can make other statements necessary.
+
+ If AGGRESSIVE is false, control statements are conservatively marked as
+ necessary. */
+
+static void
+mark_stmt_if_obviously_necessary (tree stmt, bool aggressive)
+{
+ def_optype defs;
+ vdef_optype vdefs;
+ stmt_ann_t ann;
+ size_t i;
+
+ /* Statements that are implicitly live. Most function calls, asm and return
+ statements are required. Labels and BIND_EXPR nodes are kept because
+ they are control flow, and we have no way of knowing whether they can be
+ removed. DCE can eliminate all the other statements in a block, and CFG
+ can then remove the block and labels. */
+ switch (TREE_CODE (stmt))
+ {
+ case BIND_EXPR:
+ case LABEL_EXPR:
+ case CASE_LABEL_EXPR:
+ mark_stmt_necessary (stmt, false);
+ return;
+
+ case ASM_EXPR:
+ case RESX_EXPR:
+ case RETURN_EXPR:
+ mark_stmt_necessary (stmt, true);
+ return;
+
+ case CALL_EXPR:
+ /* Most, but not all function calls are required. Function calls that
+ produce no result and have no side effects (i.e. const pure
+ functions) are unnecessary. */
+ if (TREE_SIDE_EFFECTS (stmt))
+ mark_stmt_necessary (stmt, true);
+ return;
+
+ case MODIFY_EXPR:
+ if (TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR
+ && TREE_SIDE_EFFECTS (TREE_OPERAND (stmt, 1)))
+ {
+ mark_stmt_necessary (stmt, true);
+ return;
+ }
+
+ /* These values are mildly magic bits of the EH runtime. We can't
+ see the entire lifetime of these values until landing pads are
+ generated. */
+ if (TREE_CODE (TREE_OPERAND (stmt, 0)) == EXC_PTR_EXPR
+ || TREE_CODE (TREE_OPERAND (stmt, 0)) == FILTER_EXPR)
+ {
+ mark_stmt_necessary (stmt, true);
+ return;
+ }
+ break;
+
+ case GOTO_EXPR:
+ if (! simple_goto_p (stmt))
+ mark_stmt_necessary (stmt, true);
+ return;
+
+ case COND_EXPR:
+ if (GOTO_DESTINATION (COND_EXPR_THEN (stmt))
+ == GOTO_DESTINATION (COND_EXPR_ELSE (stmt)))
+ {
+ /* A COND_EXPR is obviously dead if the target labels are the same.
+ We cannot kill the statement at this point, so to prevent the
+ statement from being marked necessary, we replace the condition
+ with a constant. The stmt is killed later on in cfg_cleanup. */
+ COND_EXPR_COND (stmt) = integer_zero_node;
+ modify_stmt (stmt);
+ return;
+ }
+ /* Fall through. */
+
+ case SWITCH_EXPR:
+ if (! aggressive)
+ mark_stmt_necessary (stmt, true);
+ break;
+
+ default:
+ break;
+ }
+
+ ann = stmt_ann (stmt);
+ /* If the statement has volatile operands, it needs to be preserved. Same
+ for statements that can alter control flow in unpredictable ways. */
+ if (ann->has_volatile_ops
+ || is_ctrl_altering_stmt (stmt))
+ {
+ mark_stmt_necessary (stmt, true);
+ return;
+ }
+
+ get_stmt_operands (stmt);
+
+ defs = DEF_OPS (ann);
+ for (i = 0; i < NUM_DEFS (defs); i++)
+ {
+ tree def = DEF_OP (defs, i);
+ if (need_to_preserve_store (def))
+ {
+ mark_stmt_necessary (stmt, true);
+ return;
+ }
+ }
+
+ vdefs = VDEF_OPS (ann);
+ for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ {
+ tree vdef = VDEF_RESULT (vdefs, i);
+ if (need_to_preserve_store (vdef))
+ {
+ mark_stmt_necessary (stmt, true);
+ return;
+ }
+ }
+
+ return;
+}
+
+/* Find obviously necessary statements. These are things like most function
+ calls, and stores to file level variables.
+
+ If EL is NULL, control statements are conservatively marked as
+ necessary. Otherwise it contains the list of edges used by control
+ dependence analysis. */
+
+static void
+find_obviously_necessary_stmts (struct edge_list *el)
+{
+ basic_block bb;
+ block_stmt_iterator i;
+ edge e;
+
+ FOR_EACH_BB (bb)
+ {
+ tree phi;
+
+ /* Check any PHI nodes in the block. */
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ NECESSARY (phi) = 0;
+
+ /* PHIs for virtual variables do not directly affect code
+ generation and need not be considered inherently necessary
+ regardless of the bits set in their decl.
+
+ Thus, we only need to mark PHIs for real variables which
+ need their result preserved as being inherently necessary. */
+ if (is_gimple_reg (PHI_RESULT (phi))
+ && need_to_preserve_store (PHI_RESULT (phi)))
+ mark_stmt_necessary (phi, true);
+ }
+
+ /* Check all statements in the block. */
+ for (i = bsi_start (bb); ! bsi_end_p (i); bsi_next (&i))
+ {
+ tree stmt = bsi_stmt (i);
+ NECESSARY (stmt) = 0;
+ mark_stmt_if_obviously_necessary (stmt, el != NULL);
+ }
+
+ /* Mark this basic block as `not visited'. A block will be marked
+ visited when the edges that it is control dependent on have been
+ marked. */
+ bb->flags &= ~BB_VISITED;
+ }
+
+ if (el)
+ {
+ /* Prevent the loops from being removed. We must keep the infinite loops,
+ and we currently do not have a means to recognize the finite ones. */
+ FOR_EACH_BB (bb)
+ {
+ for (e = bb->succ; e; e = e->succ_next)
+ if (e->flags & EDGE_DFS_BACK)
+ mark_control_dependent_edges_necessary (e->dest, el);
+ }
+ }
+}
+
+/* Make corresponding control dependent edges necessary. We only
+ have to do this once for each basic block, so we clear the bitmap
+ after we're done. */
+static void
+mark_control_dependent_edges_necessary (basic_block bb, struct edge_list *el)
+{
+ int edge_number;
+
+ EXECUTE_IF_CONTROL_DEPENDENT (bb->index, edge_number,
+ {
+ tree t;
+ basic_block cd_bb = INDEX_EDGE_PRED_BB (el, edge_number);
+
+ if (TEST_BIT (last_stmt_necessary, cd_bb->index))
+ continue;
+ SET_BIT (last_stmt_necessary, cd_bb->index);
+
+ t = last_stmt (cd_bb);
+ if (is_ctrl_stmt (t))
+ mark_stmt_necessary (t, true);
+ });
+}
+
+/* Propagate necessity using the operands of necessary statements. Process
+ the uses on each statement in the worklist, and add all feeding statements
+ which contribute to the calculation of this value to the worklist.
+
+ In conservative mode, EL is NULL. */
+
+static void
+propagate_necessity (struct edge_list *el)
+{
+ tree i;
+ bool aggressive = (el ? true : false);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "\nProcessing worklist:\n");
+
+ while (VARRAY_ACTIVE_SIZE (worklist) > 0)
+ {
+ /* Take `i' from worklist. */
+ i = VARRAY_TOP_TREE (worklist);
+ VARRAY_POP (worklist);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "processing: ");
+ print_generic_stmt (dump_file, i, TDF_SLIM);
+ fprintf (dump_file, "\n");
+ }
+
+ if (aggressive)
+ {
+ /* Mark the last statements of the basic blocks that the block
+ containing `i' is control dependent on, but only if we haven't
+ already done so. */
+ basic_block bb = bb_for_stmt (i);
+ if (! (bb->flags & BB_VISITED))
+ {
+ bb->flags |= BB_VISITED;
+ mark_control_dependent_edges_necessary (bb, el);
+ }
+ }
+
+ if (TREE_CODE (i) == PHI_NODE)
+ {
+ /* PHI nodes are somewhat special in that each PHI alternative has
+ data and control dependencies. All the statements feeding the
+ PHI node's arguments are always necessary. In aggressive mode,
+ we also consider the control dependent edges leading to the
+ predecessor block associated with each PHI alternative as
+ necessary. */
+ int k;
+ for (k = 0; k < PHI_NUM_ARGS (i); k++)
+ {
+ tree arg = PHI_ARG_DEF (i, k);
+ if (TREE_CODE (arg) == SSA_NAME)
+ mark_operand_necessary (arg);
+ }
+
+ if (aggressive)
+ {
+ for (k = 0; k < PHI_NUM_ARGS (i); k++)
+ {
+ basic_block arg_bb = PHI_ARG_EDGE (i, k)->src;
+ if (! (arg_bb->flags & BB_VISITED))
+ {
+ arg_bb->flags |= BB_VISITED;
+ mark_control_dependent_edges_necessary (arg_bb, el);
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Propagate through the operands. Examine all the USE, VUSE and
+ VDEF operands in this statement. Mark all the statements which
+ feed this statement's uses as necessary. */
+ vuse_optype vuses;
+ vdef_optype vdefs;
+ use_optype uses;
+ stmt_ann_t ann;
+ size_t k;
+
+ get_stmt_operands (i);
+ ann = stmt_ann (i);
+
+ uses = USE_OPS (ann);
+ for (k = 0; k < NUM_USES (uses); k++)
+ mark_operand_necessary (USE_OP (uses, k));
+
+ vuses = VUSE_OPS (ann);
+ for (k = 0; k < NUM_VUSES (vuses); k++)
+ mark_operand_necessary (VUSE_OP (vuses, k));
+
+ /* The operands of VDEF expressions are also needed as they
+ represent potential definitions that may reach this
+ statement (VDEF operands allow us to follow def-def links). */
+ vdefs = VDEF_OPS (ann);
+ for (k = 0; k < NUM_VDEFS (vdefs); k++)
+ mark_operand_necessary (VDEF_OP (vdefs, k));
+ }
+ }
+}
+
+/* Eliminate unnecessary statements. Any instruction not marked as necessary
+ contributes nothing to the program, and can be deleted. */
+
+static void
+eliminate_unnecessary_stmts (void)
+{
+ basic_block bb;
+ block_stmt_iterator i;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "\nEliminating unnecessary statements:\n");
+
+ clear_special_calls ();
+ FOR_EACH_BB (bb)
+ {
+ /* Remove dead PHI nodes. */
+ remove_dead_phis (bb);
+
+ /* Remove dead statements. */
+ for (i = bsi_start (bb); ! bsi_end_p (i) ; )
+ {
+ tree t = bsi_stmt (i);
+
+ stats.total++;
+
+ /* If `i' is not necessary then remove it. */
+ if (! NECESSARY (t))
+ remove_dead_stmt (&i, bb);
+ else
+ {
+ if (TREE_CODE (t) == CALL_EXPR)
+ notice_special_calls (t);
+ else if (TREE_CODE (t) == MODIFY_EXPR
+ && TREE_CODE (TREE_OPERAND (t, 1)) == CALL_EXPR)
+ notice_special_calls (TREE_OPERAND (t, 1));
+ bsi_next (&i);
+ }
+ }
+ }
+}
+
+/* Remove dead PHI nodes from block BB. */
+
+static void
+remove_dead_phis (basic_block bb)
+{
+ tree prev, phi;
+
+ prev = NULL_TREE;
+ phi = phi_nodes (bb);
+ while (phi)
+ {
+ stats.total_phis++;
+
+ if (! NECESSARY (phi))
+ {
+ tree next = TREE_CHAIN (phi);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Deleting : ");
+ print_generic_stmt (dump_file, phi, TDF_SLIM);
+ fprintf (dump_file, "\n");
+ }
+
+ remove_phi_node (phi, prev, bb);
+ stats.removed_phis++;
+ phi = next;
+ }
+ else
+ {
+ prev = phi;
+ phi = TREE_CHAIN (phi);
+ }
+ }
+}
+
+/* Remove dead statement pointed by iterator I. Receives the basic block BB
+ containing I so that we don't have to look it up. */
+
+static void
+remove_dead_stmt (block_stmt_iterator *i, basic_block bb)
+{
+ tree t = bsi_stmt (*i);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Deleting : ");
+ print_generic_stmt (dump_file, t, TDF_SLIM);
+ fprintf (dump_file, "\n");
+ }
+
+ stats.removed++;
+
+ /* If we have determined that a conditional branch statement contributes
+ nothing to the program, then we not only remove it, but we also change
+ the flow graph so that the current block will simply fall-thru to its
+ immediate post-dominator. The blocks we are circumventing will be
+ removed by cleaup_cfg if this change in the flow graph makes them
+ unreachable. */
+ if (is_ctrl_stmt (t))
+ {
+ basic_block post_dom_bb;
+ edge e;
+#ifdef ENABLE_CHECKING
+ /* The post dominance info has to be up-to-date. */
+ if (dom_computed[CDI_POST_DOMINATORS] != DOM_OK)
+ abort ();
+#endif
+ /* Get the immediate post dominator of bb. */
+ post_dom_bb = get_immediate_dominator (CDI_POST_DOMINATORS, bb);
+ /* Some blocks don't have an immediate post dominator. This can happen
+ for example with infinite loops. Removing an infinite loop is an
+ inappropriate transformation anyway... */
+ if (! post_dom_bb)
+ {
+ bsi_next (i);
+ return;
+ }
+
+ /* Redirect the first edge out of BB to reach POST_DOM_BB. */
+ redirect_edge_and_branch (bb->succ, post_dom_bb);
+ PENDING_STMT (bb->succ) = NULL;
+
+ /* The edge is no longer associated with a conditional, so it does
+ not have TRUE/FALSE flags. */
+ bb->succ->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
+
+ /* If the edge reaches any block other than the exit, then it is a
+ fallthru edge; if it reaches the exit, then it is not a fallthru
+ edge. */
+ if (post_dom_bb != EXIT_BLOCK_PTR)
+ bb->succ->flags |= EDGE_FALLTHRU;
+ else
+ bb->succ->flags &= ~EDGE_FALLTHRU;
+
+ /* Remove the remaining the outgoing edges. */
+ for (e = bb->succ->succ_next; e != NULL;)
+ {
+ edge tmp = e;
+ e = e->succ_next;
+ remove_edge (tmp);
+ }
+ }
+
+ bsi_remove (i);
+}
+
+/* Print out removed statement statistics. */
+
+static void
+print_stats (void)
+{
+ if (dump_file && (dump_flags & (TDF_STATS|TDF_DETAILS)))
+ {
+ float percg;
+
+ percg = ((float) stats.removed / (float) stats.total) * 100;
+ fprintf (dump_file, "Removed %d of %d statements (%d%%)\n",
+ stats.removed, stats.total, (int) percg);
+
+ if (stats.total_phis == 0)
+ percg = 0;
+ else
+ percg = ((float) stats.removed_phis / (float) stats.total_phis) * 100;
+
+ fprintf (dump_file, "Removed %d of %d PHI nodes (%d%%)\n",
+ stats.removed_phis, stats.total_phis, (int) percg);
+ }
+}
+
+/* Initialization for this pass. Set up the used data structures. */
+
+static void
+tree_dce_init (bool aggressive)
+{
+ memset ((void *) &stats, 0, sizeof (stats));
+
+ if (aggressive)
+ {
+ int i;
+
+ control_dependence_map
+ = xmalloc (last_basic_block * sizeof (bitmap));
+ for (i = 0; i < last_basic_block; ++i)
+ control_dependence_map[i] = BITMAP_XMALLOC ();
+
+ last_stmt_necessary = sbitmap_alloc (last_basic_block);
+ sbitmap_zero (last_stmt_necessary);
+ }
+
+ processed = sbitmap_alloc (highest_ssa_version + 1);
+ sbitmap_zero (processed);
+
+ VARRAY_TREE_INIT (worklist, 64, "work list");
+}
+
+/* Cleanup after this pass. */
+
+static void
+tree_dce_done (bool aggressive)
+{
+ if (aggressive)
+ {
+ int i;
+
+ for (i = 0; i < last_basic_block; ++i)
+ BITMAP_XFREE (control_dependence_map[i]);
+ free (control_dependence_map);
+
+ sbitmap_free (last_stmt_necessary);
+ }
+
+ sbitmap_free (processed);
+}
+
+/* Main routine to eliminate dead code.
+
+ AGGRESSIVE controls the aggressiveness of the algorithm.
+ In conservative mode, we ignore control dependence and simply declare
+ all but the most trivially dead branches necessary. This mode is fast.
+ In aggressive mode, control dependences are taken into account, which
+ results in more dead code elimination, but at the cost of some time.
+
+ FIXME: Aggressive mode before PRE doesn't work currently because
+ the dominance info is not invalidated after DCE1. This is
+ not an issue right now because we only run aggressive DCE
+ as the last tree SSA pass, but keep this in mind when you
+ start experimenting with pass ordering. */
+
+static void
+perform_tree_ssa_dce (bool aggressive)
+{
+ struct edge_list *el = NULL;
+
+ tree_dce_init (aggressive);
+
+ if (aggressive)
+ {
+ /* Compute control dependence. */
+ timevar_push (TV_CONTROL_DEPENDENCES);
+ calculate_dominance_info (CDI_POST_DOMINATORS);
+ el = create_edge_list ();
+ find_all_control_dependences (el);
+ timevar_pop (TV_CONTROL_DEPENDENCES);
+
+ mark_dfs_back_edges ();
+ }
+
+ find_obviously_necessary_stmts (el);
+
+ propagate_necessity (el);
+
+ eliminate_unnecessary_stmts ();
+
+ if (aggressive)
+ free_dominance_info (CDI_POST_DOMINATORS);
+
+ cleanup_tree_cfg ();
+
+ /* Debugging dumps. */
+ if (dump_file)
+ {
+ dump_function_to_file (current_function_decl, dump_file, dump_flags);
+ print_stats ();
+ }
+
+ tree_dce_done (aggressive);
+
+ free_edge_list (el);
+}
+
+/* Pass entry points. */
+static void
+tree_ssa_dce (void)
+{
+ perform_tree_ssa_dce (/*aggressive=*/false);
+}
+
+static void
+tree_ssa_cd_dce (void)
+{
+ perform_tree_ssa_dce (/*aggressive=*/optimize >= 2);
+}
+
+static bool
+gate_dce (void)
+{
+ return flag_tree_dce != 0;
+}
+
+struct tree_opt_pass pass_dce =
+{
+ "dce", /* name */
+ gate_dce, /* gate */
+ tree_ssa_dce, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_DCE, /* tv_id */
+ PROP_cfg | PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */
+};
+
+struct tree_opt_pass pass_cd_dce =
+{
+ "cddce", /* name */
+ gate_dce, /* gate */
+ tree_ssa_cd_dce, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_CD_DCE, /* tv_id */
+ PROP_cfg | PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_ggc_collect | TODO_verify_ssa | TODO_verify_flow
+ /* todo_flags_finish */
+};
+
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
new file mode 100644
index 00000000000..89f4c6a5cb0
--- /dev/null
+++ b/gcc/tree-ssa-dom.c
@@ -0,0 +1,3144 @@
+/* SSA Dominator optimizations for trees
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Diego Novillo <dnovillo@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "flags.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "ggc.h"
+#include "basic-block.h"
+#include "output.h"
+#include "errors.h"
+#include "expr.h"
+#include "function.h"
+#include "diagnostic.h"
+#include "timevar.h"
+#include "tree-dump.h"
+#include "tree-flow.h"
+#include "domwalk.h"
+#include "real.h"
+#include "tree-pass.h"
+#include "flags.h"
+#include "langhooks.h"
+
+/* This file implements optimizations on the dominator tree. */
+
+/* Hash table with expressions made available during the renaming process.
+ When an assignment of the form X_i = EXPR is found, the statement is
+ stored in this table. If the same expression EXPR is later found on the
+ RHS of another statement, it is replaced with X_i (thus performing
+ global redundancy elimination). Similarly as we pass through conditionals
+ we record the conditional itself as having either a true or false value
+ in this table. */
+static htab_t avail_exprs;
+
+/* Structure for entries in the expression hash table.
+
+ This requires more memory for the hash table entries, but allows us
+ to avoid creating silly tree nodes and annotations for conditionals,
+ eliminates 2 global hash tables and two block local varrays.
+
+ It also allows us to reduce the number of hash table lookups we
+ have to perform in lookup_avail_expr and finally it allows us to
+ significantly reduce the number of calls into the hashing routine
+ itself. */
+struct expr_hash_elt
+{
+ /* The value (lhs) of this expression. */
+ tree lhs;
+
+ /* The expression (rhs) we want to record. */
+ tree rhs;
+
+ /* The annotation if this element corresponds to a statement. */
+ stmt_ann_t ann;
+
+ /* The hash value for RHS/ann. */
+ hashval_t hash;
+};
+
+/* Table of constant values and copies indexed by SSA name. When the
+ renaming pass finds an assignment of a constant (X_i = C) or a copy
+ assignment from another SSA variable (X_i = Y_j), it creates a mapping
+ between X_i and the RHS in this table. This mapping is used later on,
+ when renaming uses of X_i. If an assignment to X_i is found in this
+ table, instead of using X_i, we use the RHS of the statement stored in
+ this table (thus performing very simplistic copy and constant
+ propagation). */
+static varray_type const_and_copies;
+
+/* Bitmap of SSA_NAMEs known to have a nonzero value, even if we do not
+ know their exact value. */
+static bitmap nonzero_vars;
+
+/* Track whether or not we have changed the control flow graph. */
+static bool cfg_altered;
+
+/* Statistics for dominator optimizations. */
+struct opt_stats_d
+{
+ long num_stmts;
+ long num_exprs_considered;
+ long num_re;
+};
+
+/* Value range propagation record. Each time we encounter a conditional
+ of the form SSA_NAME COND CONST we create a new vrp_element to record
+ how the condition affects the possible values SSA_NAME may have.
+
+ Each record contains the condition tested (COND), and the the range of
+ values the variable may legitimately have if COND is true. Note the
+ range of values may be a smaller range than COND specifies if we have
+ recorded other ranges for this variable. Each record also contains the
+ block in which the range was recorded for invalidation purposes.
+
+ Note that the current known range is computed lazily. This allows us
+ to avoid the overhead of computing ranges which are never queried.
+
+ When we encounter a conditional, we look for records which constrain
+ the SSA_NAME used in the condition. In some cases those records allow
+ us to determine the condition's result at compile time. In other cases
+ they may allow us to simplify the condition.
+
+ We also use value ranges to do things like transform signed div/mod
+ operations into unsigned div/mod or to simplify ABS_EXPRs.
+
+ Simple experiments have shown these optimizations to not be all that
+ useful on switch statements (much to my surprise). So switch statement
+ optimizations are not performed.
+
+ Note carefully we do not propagate information through each statement
+ in the block. ie, if we know variable X has a value defined of
+ [0, 25] and we encounter Y = X + 1, we do not track a value range
+ for Y (which would be [1, 26] if we cared). Similarly we do not
+ constrain values as we encounter narrowing typecasts, etc. */
+
+struct vrp_element
+{
+ /* The highest and lowest values the variable in COND may contain when
+ COND is true. Note this may not necessarily be the same values
+ tested by COND if the same variable was used in earlier conditionals.
+
+ Note this is computed lazily and thus can be NULL indicating that
+ the values have not been computed yet. */
+ tree low;
+ tree high;
+
+ /* The actual conditional we recorded. This is needed since we compute
+ ranges lazily. */
+ tree cond;
+
+ /* The basic block where this record was created. We use this to determine
+ when to remove records. */
+ basic_block bb;
+};
+
+static struct opt_stats_d opt_stats;
+
+/* This virtual array holds pairs of edges which describe a scheduled
+ edge redirection from jump threading.
+
+ The first entry in each pair is the edge we are going to redirect.
+
+ The second entry in each pair is the edge leading to our final
+ destination block. By providing this as an edge rather than the
+ final target block itself we can correctly handle redirections
+ when the target block had PHIs which required edge insertions/splitting
+ to remove the PHIs. */
+static GTY(()) varray_type redirection_edges;
+
+/* A virtual array holding value range records for the variable identified
+ by the index, SSA_VERSION. */
+static varray_type vrp_data;
+
+/* Datastructure for block local data used during the dominator walk.
+ We maintain a stack of these as we recursively walk down the
+ dominator tree. */
+
+struct dom_walk_block_data
+{
+ /* Array of all the expressions entered into the global expression
+ hash table by this block. During finalization we use this array to
+ know what expressions to remove from the global expression hash
+ table. */
+ varray_type avail_exprs;
+
+ /* Array of dest, src pairs that need to be restored during finalization
+ into the global const/copies table during finalization. */
+ varray_type const_and_copies;
+
+ /* Similarly for the nonzero state of variables that needs to be
+ restored during finalization. */
+ varray_type nonzero_vars;
+
+ /* Array of statements we need to rescan during finalization for newly
+ exposed variables. */
+ varray_type stmts_to_rescan;
+
+ /* Array of variables which have their values constrained by operations
+ in this basic block. We use this during finalization to know
+ which variables need their VRP data updated. */
+ varray_type vrp_variables;
+
+ /* Array of tree pairs used to restore the global currdefs to its
+ original state after completing optimization of a block and its
+ dominator children. */
+ varray_type block_defs;
+};
+
+struct eq_expr_value
+{
+ tree src;
+ tree dst;
+};
+
+/* Local functions. */
+static void optimize_stmt (struct dom_walk_data *,
+ basic_block bb,
+ block_stmt_iterator);
+static inline tree get_value_for (tree, varray_type table);
+static inline void set_value_for (tree, tree, varray_type table);
+static tree lookup_avail_expr (tree, varray_type *, bool);
+static struct eq_expr_value get_eq_expr_value (tree, int, varray_type *,
+ basic_block, varray_type *);
+static hashval_t avail_expr_hash (const void *);
+static int avail_expr_eq (const void *, const void *);
+static void htab_statistics (FILE *, htab_t);
+static void record_cond (tree, tree, varray_type *);
+static void record_const_or_copy (tree, tree, varray_type *);
+static void record_equality (tree, tree, varray_type *);
+static tree update_rhs_and_lookup_avail_expr (tree, tree, varray_type *,
+ stmt_ann_t, bool);
+static tree simplify_rhs_and_lookup_avail_expr (struct dom_walk_data *,
+ tree, stmt_ann_t, int);
+static tree simplify_cond_and_lookup_avail_expr (tree, varray_type *,
+ stmt_ann_t, int);
+static tree simplify_switch_and_lookup_avail_expr (tree, varray_type *,
+ stmt_ann_t, int);
+static tree find_equivalent_equality_comparison (tree);
+static void record_range (tree, basic_block, varray_type *);
+static bool extract_range_from_cond (tree, tree *, tree *, int *);
+static void record_equivalences_from_phis (struct dom_walk_data *, basic_block);
+static void record_equivalences_from_incoming_edge (struct dom_walk_data *,
+ basic_block);
+static bool eliminate_redundant_computations (struct dom_walk_data *,
+ tree, stmt_ann_t);
+static void record_equivalences_from_stmt (tree, varray_type *, varray_type *,
+ int, stmt_ann_t);
+static void thread_across_edge (struct dom_walk_data *, edge);
+static void dom_opt_finalize_block (struct dom_walk_data *, basic_block);
+static void dom_opt_initialize_block_local_data (struct dom_walk_data *,
+ basic_block, bool);
+static void dom_opt_initialize_block (struct dom_walk_data *, basic_block);
+static void cprop_into_phis (struct dom_walk_data *, basic_block);
+static void remove_local_expressions_from_table (varray_type locals,
+ unsigned limit,
+ htab_t table);
+static void restore_vars_to_original_value (varray_type locals,
+ unsigned limit,
+ varray_type table);
+static void restore_currdefs_to_original_value (varray_type locals,
+ unsigned limit);
+static void register_definitions_for_stmt (stmt_ann_t, varray_type *);
+static void redirect_edges_and_update_ssa_graph (varray_type);
+
+/* Local version of fold that doesn't introduce cruft. */
+
+static tree
+local_fold (tree t)
+{
+ t = fold (t);
+
+ /* Strip away useless type conversions. Both the NON_LVALUE_EXPR that
+ may have been added by fold, and "useless" type conversions that might
+ now be apparent due to propagation. */
+ STRIP_MAIN_TYPE_NOPS (t);
+ STRIP_USELESS_TYPE_CONVERSION (t);
+
+ return t;
+}
+
+/* Return the value associated with variable VAR in TABLE. */
+
+static inline tree
+get_value_for (tree var, varray_type table)
+{
+ return VARRAY_TREE (table, SSA_NAME_VERSION (var));
+}
+
+/* Associate VALUE to variable VAR in TABLE. */
+
+static inline void
+set_value_for (tree var, tree value, varray_type table)
+{
+ VARRAY_TREE (table, SSA_NAME_VERSION (var)) = value;
+}
+
+/* REDIRECTION_EDGES contains edge pairs where we want to revector the
+ destination of the first edge to the destination of the second edge.
+
+ These redirections may significantly change the SSA graph since we
+ allow redirection through blocks with PHI nodes and blocks with
+ real instructions in some cases.
+
+ This routine will perform the requested redirections and incrementally
+ update the SSA graph.
+
+ Note in some cases requested redirections may be ignored as they can
+ not be safely implemented. */
+
+static void
+redirect_edges_and_update_ssa_graph (varray_type redirection_edges)
+{
+ basic_block tgt;
+ unsigned int i;
+ size_t old_num_referenced_vars = num_referenced_vars;
+
+ /* First note any variables which we are going to have to take
+ out of SSA form. */
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (redirection_edges); i += 2)
+ {
+ block_stmt_iterator bsi;
+ edge e;
+ basic_block tgt;
+ tree phi;
+
+ e = VARRAY_EDGE (redirection_edges, i);
+ tgt = VARRAY_EDGE (redirection_edges, i + 1)->dest;
+
+ /* All variables referenced in PHI nodes we bypass must be
+ renamed. */
+ for (phi = phi_nodes (e->dest); phi; phi = TREE_CHAIN (phi))
+ {
+ tree result = SSA_NAME_VAR (PHI_RESULT (phi));
+ bitmap_set_bit (vars_to_rename, var_ann (result)->uid);
+ }
+
+ /* Any variables set by statements at the start of the block we
+ are bypassing must also be taken our of SSA form. */
+ for (bsi = bsi_start (e->dest); ! bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ unsigned int j;
+ def_optype defs;
+ vdef_optype vdefs;
+ tree stmt = bsi_stmt (bsi);
+ stmt_ann_t ann = stmt_ann (stmt);
+
+ if (TREE_CODE (stmt) == COND_EXPR)
+ break;
+
+ get_stmt_operands (stmt);
+
+ defs = DEF_OPS (ann);
+ for (j = 0; j < NUM_DEFS (defs); j++)
+ {
+ tree op = SSA_NAME_VAR (DEF_OP (defs, j));
+ bitmap_set_bit (vars_to_rename, var_ann (op)->uid);
+ }
+
+ vdefs = VDEF_OPS (ann);
+ for (j = 0; j < NUM_VDEFS (vdefs); j++)
+ {
+ tree op = VDEF_RESULT (vdefs, j);
+ bitmap_set_bit (vars_to_rename, var_ann (op)->uid);
+ }
+ }
+
+ /* Finally, any variables in PHI nodes at our final destination
+ must also be taken our of SSA form. */
+ for (phi = phi_nodes (tgt); phi; phi = TREE_CHAIN (phi))
+ {
+ tree result = SSA_NAME_VAR (PHI_RESULT (phi));
+ int j;
+
+ bitmap_set_bit (vars_to_rename, var_ann (result)->uid);
+
+ for (j = 0; j < PHI_NUM_ARGS (phi); j++)
+ {
+ tree arg = PHI_ARG_DEF (phi, j);
+
+ if (TREE_CODE (arg) != SSA_NAME)
+ continue;
+
+ arg = SSA_NAME_VAR (arg);
+ bitmap_set_bit (vars_to_rename, var_ann (arg)->uid);
+ }
+ }
+ }
+
+ /* Take those selected variables out of SSA form. This must be
+ done before we start redirecting edges. */
+ if (bitmap_first_set_bit (vars_to_rename) >= 0)
+ rewrite_vars_out_of_ssa (vars_to_rename);
+
+ /* The out of SSA translation above may split the edge from
+ E->src to E->dest. This could potentially cause us to lose
+ an assignment leading to invalid warnings about uninitialized
+ variables or incorrect code.
+
+ Luckily, we can detect this by looking at the last statement
+ in E->dest. If it is not a COND_EXPR or SWITCH_EXPR, then
+ the edge was split and instead of E, we want E->dest->succ. */
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (redirection_edges); i += 2)
+ {
+ edge e = VARRAY_EDGE (redirection_edges, i);
+ tree last = last_stmt (e->dest);
+
+ if (last
+ && TREE_CODE (last) != COND_EXPR
+ && TREE_CODE (last) != SWITCH_EXPR)
+ {
+ e = e->dest->succ;
+
+#ifdef ENABLE_CHECKING
+ /* There should only be a single successor if the
+ original edge was split. */
+ if (e->succ_next)
+ abort ();
+#endif
+ /* Replace the edge in REDIRECTION_EDGES for the
+ loop below. */
+ VARRAY_EDGE (redirection_edges, i) = e;
+ }
+ }
+
+ /* If we created any new variables as part of the out-of-ssa
+ translation, then any jump threads must be invalidated if they
+ bypass a block in which we skipped instructions.
+
+ This is necessary as instructions which appeared to be NOPS
+ may be necessary after the out-of-ssa translation. */
+ if (num_referenced_vars != old_num_referenced_vars)
+ {
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (redirection_edges); i += 2)
+ {
+ block_stmt_iterator bsi;
+ edge e;
+
+ e = VARRAY_EDGE (redirection_edges, i);
+ for (bsi = bsi_start (e->dest); ! bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ tree stmt = bsi_stmt (bsi);
+
+ if (IS_EMPTY_STMT (stmt)
+ || TREE_CODE (stmt) == LABEL_EXPR)
+ continue;
+
+ if (TREE_CODE (stmt) == COND_EXPR)
+ break;
+
+ /* Invalidate the jump thread. */
+ VARRAY_EDGE (redirection_edges, i) = NULL;
+ VARRAY_EDGE (redirection_edges, i + 1) = NULL;
+ break;
+ }
+ }
+ }
+
+ /* Now redirect the edges. */
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (redirection_edges); i += 2)
+ {
+ basic_block src;
+ edge e;
+
+ e = VARRAY_EDGE (redirection_edges, i);
+ if (!e)
+ continue;
+
+ tgt = VARRAY_EDGE (redirection_edges, i + 1)->dest;
+
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, " Threaded jump %d --> %d to %d\n",
+ e->src->index, e->dest->index, tgt->index);
+
+ src = e->src;
+
+ e = redirect_edge_and_branch (e, tgt);
+ PENDING_STMT (e) = NULL_TREE;
+
+ /* Updating the dominance information would be nontrivial. */
+ free_dominance_info (CDI_DOMINATORS);
+
+ if ((dump_file && (dump_flags & TDF_DETAILS))
+ && e->src != src)
+ fprintf (dump_file, " basic block %d created\n",
+ e->src->index);
+
+ cfg_altered = true;
+ }
+
+ VARRAY_CLEAR (redirection_edges);
+
+ for (i = old_num_referenced_vars; i < num_referenced_vars; i++)
+ {
+ bitmap_set_bit (vars_to_rename, i);
+ var_ann (referenced_var (i))->out_of_ssa_tag = 0;
+ }
+}
+
+/* Jump threading, redundancy elimination and const/copy propagation.
+
+ Optimize function FNDECL based on a walk through the dominator tree.
+
+ This pass may expose new symbols that need to be renamed into SSA. For
+ every new symbol exposed, its corresponding bit will be set in
+ VARS_TO_RENAME.
+
+ PHASE indicates which dump file from the DUMP_FILES array to use when
+ dumping debugging information. */
+
+static void
+tree_ssa_dominator_optimize (void)
+{
+ basic_block bb;
+ struct dom_walk_data walk_data;
+ unsigned int i;
+
+ for (i = 0; i < num_referenced_vars; i++)
+ var_ann (referenced_var (i))->current_def = NULL;
+
+ /* Mark loop edges so we avoid threading across loop boundaries.
+ This may result in transforming natural loop into irreducible
+ region. */
+ mark_dfs_back_edges ();
+
+ /* Create our hash tables. */
+ avail_exprs = htab_create (1024, avail_expr_hash, avail_expr_eq, free);
+ VARRAY_TREE_INIT (const_and_copies, highest_ssa_version, "const_and_copies");
+ nonzero_vars = BITMAP_XMALLOC ();
+ VARRAY_EDGE_INIT (redirection_edges, 20, "redirection_edges");
+ VARRAY_GENERIC_PTR_INIT (vrp_data, highest_ssa_version, "vrp_data");
+
+ /* Setup callbacks for the generic dominator tree walker. */
+ walk_data.walk_stmts_backward = false;
+ walk_data.dom_direction = CDI_DOMINATORS;
+ walk_data.initialize_block_local_data = dom_opt_initialize_block_local_data;
+ walk_data.before_dom_children_before_stmts = dom_opt_initialize_block;
+ walk_data.before_dom_children_walk_stmts = optimize_stmt;
+ walk_data.before_dom_children_after_stmts = cprop_into_phis;
+ walk_data.after_dom_children_before_stmts = NULL;
+ walk_data.after_dom_children_walk_stmts = NULL;
+ walk_data.after_dom_children_after_stmts = dom_opt_finalize_block;
+ /* Right now we only attach a dummy COND_EXPR to the global data pointer.
+ When we attach more stuff we'll need to fill this out with a real
+ structure. */
+ walk_data.global_data = NULL;
+ walk_data.block_local_data_size = sizeof (struct dom_walk_block_data);
+
+ /* Now initialize the dominator walker. */
+ init_walk_dominator_tree (&walk_data);
+
+ /* Reset block_forwardable in each block's annotation. We use that
+ attribute when threading through COND_EXPRs. */
+ FOR_EACH_BB (bb)
+ bb_ann (bb)->forwardable = 1;
+
+ calculate_dominance_info (CDI_DOMINATORS);
+
+ /* If we prove certain blocks are unreachable, then we want to
+ repeat the dominator optimization process as PHI nodes may
+ have turned into copies which allows better propagation of
+ values. So we repeat until we do not identify any new unreachable
+ blocks. */
+ do
+ {
+ /* Optimize the dominator tree. */
+ cfg_altered = false;
+
+ /* Recursively walk the dominator tree optimizing statements. */
+ walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
+
+ /* Wipe the hash tables. */
+
+ if (VARRAY_ACTIVE_SIZE (redirection_edges) > 0)
+ redirect_edges_and_update_ssa_graph (redirection_edges);
+
+ /* We may have made some basic blocks unreachable, remove them. */
+ cfg_altered |= delete_unreachable_blocks ();
+
+ /* If the CFG was altered, then recompute the dominator tree. This
+ is not strictly needed if we only removed unreachable blocks, but
+ may produce better results. If we threaded jumps, then rebuilding
+ the dominator tree is strictly necessary. */
+ if (cfg_altered)
+ {
+ cleanup_tree_cfg ();
+ calculate_dominance_info (CDI_DOMINATORS);
+ }
+
+ /* If we are going to iterate (CFG_ALTERED is true), then we must
+ perform any queued renaming before the next iteration. */
+ if (cfg_altered
+ && bitmap_first_set_bit (vars_to_rename) >= 0)
+ {
+ rewrite_into_ssa ();
+ bitmap_clear (vars_to_rename);
+
+ /* The into SSA translation may have created new SSA_NAMES whic
+ affect the size of CONST_AND_COPIES and VRP_DATA. */
+ VARRAY_GROW (const_and_copies, highest_ssa_version);
+ VARRAY_GROW (vrp_data, highest_ssa_version);
+ }
+
+ /* Reinitialize the various tables. */
+ bitmap_clear (nonzero_vars);
+ htab_empty (avail_exprs);
+ VARRAY_CLEAR (const_and_copies);
+ VARRAY_CLEAR (vrp_data);
+
+ for (i = 0; i < num_referenced_vars; i++)
+ var_ann (referenced_var (i))->current_def = NULL;
+ }
+ while (cfg_altered);
+
+ /* Remove any unreachable blocks left behind and linearize the CFG. */
+ cleanup_tree_cfg ();
+
+ /* Debugging dumps. */
+ if (dump_file && (dump_flags & TDF_STATS))
+ dump_dominator_optimization_stats (dump_file);
+
+ /* We emptyed the hash table earlier, now delete it completely. */
+ htab_delete (avail_exprs);
+
+ /* It is not nocessary to clear CURRDEFS, REDIRECTION_EDGES, VRP_DATA,
+ CONST_AND_COPIES, and NONZERO_VARS as they all get cleared at the bottom
+ of the do-while loop above. */
+
+ /* And finalize the dominator walker. */
+ fini_walk_dominator_tree (&walk_data);
+
+ /* Free nonzero_vars. */
+ BITMAP_XFREE (nonzero_vars);
+}
+
+static bool
+gate_dominator (void)
+{
+ return flag_tree_dom != 0;
+}
+
+struct tree_opt_pass pass_dominator =
+{
+ "dom", /* name */
+ gate_dominator, /* gate */
+ tree_ssa_dominator_optimize, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_SSA_DOMINATOR_OPTS, /* tv_id */
+ PROP_cfg | PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func | TODO_rename_vars
+ | TODO_verify_ssa /* todo_flags_finish */
+};
+
+
+/* We are exiting BB, see if the target block begins with a conditional
+ jump which has a known value when reached via BB. */
+
+static void
+thread_across_edge (struct dom_walk_data *walk_data, edge e)
+{
+ struct dom_walk_block_data *bd
+ = VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
+ block_stmt_iterator bsi;
+ tree stmt = NULL;
+ tree phi;
+
+ /* Each PHI creates a temporary equivalence, record them. */
+ for (phi = phi_nodes (e->dest); phi; phi = TREE_CHAIN (phi))
+ {
+ tree src = PHI_ARG_DEF (phi, phi_arg_from_edge (phi, e));
+ tree dst = PHI_RESULT (phi);
+ record_const_or_copy (dst, src, &bd->const_and_copies);
+ register_new_def (dst, &bd->block_defs);
+ }
+
+ for (bsi = bsi_start (e->dest); ! bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ tree lhs, cached_lhs;
+
+ stmt = bsi_stmt (bsi);
+
+ /* Ignore empty statements and labels. */
+ if (IS_EMPTY_STMT (stmt) || TREE_CODE (stmt) == LABEL_EXPR)
+ continue;
+
+ /* If this is not a MODIFY_EXPR which sets an SSA_NAME to a new
+ value, then stop our search here. Ideally when we stop a
+ search we stop on a COND_EXPR or SWITCH_EXPR. */
+ if (TREE_CODE (stmt) != MODIFY_EXPR
+ || TREE_CODE (TREE_OPERAND (stmt, 0)) != SSA_NAME)
+ break;
+
+ /* At this point we have a statement which assigns an RHS to an
+ SSA_VAR on the LHS. We want to prove that the RHS is already
+ available and that its value is held in the current definition
+ of the LHS -- meaning that this assignment is a NOP when
+ reached via edge E. */
+ if (TREE_CODE (TREE_OPERAND (stmt, 1)) == SSA_NAME)
+ cached_lhs = TREE_OPERAND (stmt, 1);
+ else
+ cached_lhs = lookup_avail_expr (stmt, NULL, false);
+
+ lhs = TREE_OPERAND (stmt, 0);
+
+ /* This can happen if we thread around to the start of a loop. */
+ if (lhs == cached_lhs)
+ break;
+
+ /* If we did not find RHS in the hash table, then try again after
+ temporarily const/copy propagating the operands. */
+ if (!cached_lhs)
+ {
+ /* Copy the operands. */
+ stmt_ann_t ann = stmt_ann (stmt);
+ use_optype uses = USE_OPS (ann);
+ vuse_optype vuses = VUSE_OPS (ann);
+ tree *uses_copy = xcalloc (NUM_USES (uses), sizeof (tree));
+ tree *vuses_copy = xcalloc (NUM_VUSES (vuses), sizeof (tree));
+ unsigned int i;
+
+ /* Make a copy of the uses into USES_COPY, then cprop into
+ the use operands. */
+ for (i = 0; i < NUM_USES (uses); i++)
+ {
+ tree tmp = NULL;
+
+ uses_copy[i] = USE_OP (uses, i);
+ if (TREE_CODE (USE_OP (uses, i)) == SSA_NAME)
+ tmp = get_value_for (USE_OP (uses, i), const_and_copies);
+ if (tmp)
+ *USE_OP_PTR (uses, i) = tmp;
+ }
+
+ /* Similarly for virtual uses. */
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ {
+ tree tmp = NULL;
+
+ vuses_copy[i] = VUSE_OP (vuses, i);
+ if (TREE_CODE (VUSE_OP (vuses, i)) == SSA_NAME)
+ tmp = get_value_for (VUSE_OP (vuses, i), const_and_copies);
+ if (tmp)
+ VUSE_OP (vuses, i) = tmp;
+ }
+
+ /* Try to lookup the new expression. */
+ cached_lhs = lookup_avail_expr (stmt, NULL, false);
+
+ /* Restore the statement's original uses/defs. */
+ for (i = 0; i < NUM_USES (uses); i++)
+ *USE_OP_PTR (uses, i) = uses_copy[i];
+
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ VUSE_OP (vuses, i) = vuses_copy[i];
+
+ free (uses_copy);
+ free (vuses_copy);
+
+ /* If we still did not find the expression in the hash table,
+ then we can not ignore this statement. */
+ if (! cached_lhs)
+ break;
+ }
+
+ /* If the expression in the hash table was not assigned to an
+ SSA_NAME, then we can not ignore this statement. */
+ if (TREE_CODE (cached_lhs) != SSA_NAME)
+ break;
+
+ /* If we have different underlying variables, then we can not
+ ignore this statement. */
+ if (SSA_NAME_VAR (cached_lhs) != SSA_NAME_VAR (lhs))
+ break;
+
+ /* If CACHED_LHS does not represent the current value of the undering
+ variable in CACHED_LHS/LHS, then we can not ignore this statement. */
+ if (var_ann (SSA_NAME_VAR (lhs))->current_def != cached_lhs)
+ break;
+
+ /* If we got here, then we can ignore this statement and continue
+ walking through the statements in the block looking for a threadable
+ COND_EXPR.
+
+ We want to record an equivalence lhs = cache_lhs so that if
+ the result of this statement is used later we can copy propagate
+ suitably. */
+ record_const_or_copy (lhs, cached_lhs, &bd->const_and_copies);
+ register_new_def (lhs, &bd->block_defs);
+ }
+
+ /* If we stopped at a COND_EXPR or SWITCH_EXPR, then see if we know which
+ arm will be taken. */
+ if (stmt
+ && (TREE_CODE (stmt) == COND_EXPR
+ || TREE_CODE (stmt) == SWITCH_EXPR))
+ {
+ tree cond, cached_lhs;
+ edge e1;
+
+ /* Do not forward entry edges into the loop. In the case loop
+ has multiple entry edges we may end up in constructing irreducible
+ region.
+ ??? We may consider forwarding the edges in the case all incoming
+ edges forward to the same destination block. */
+ if (!e->flags & EDGE_DFS_BACK)
+ {
+ for (e1 = e->dest->pred; e; e = e->pred_next)
+ if (e1->flags & EDGE_DFS_BACK)
+ break;
+ if (e1)
+ return;
+ }
+
+ /* Now temporarily cprop the operands and try to find the resulting
+ expression in the hash tables. */
+ if (TREE_CODE (stmt) == COND_EXPR)
+ cond = COND_EXPR_COND (stmt);
+ else
+ cond = SWITCH_COND (stmt);
+
+ if (TREE_CODE_CLASS (TREE_CODE (cond)) == '<')
+ {
+ tree dummy_cond, op0, op1;
+ enum tree_code cond_code;
+
+ op0 = TREE_OPERAND (cond, 0);
+ op1 = TREE_OPERAND (cond, 1);
+ cond_code = TREE_CODE (cond);
+
+ /* Get the current value of both operands. */
+ if (TREE_CODE (op0) == SSA_NAME)
+ {
+ tree tmp = get_value_for (op0, const_and_copies);
+ if (tmp)
+ op0 = tmp;
+ }
+
+ if (TREE_CODE (op1) == SSA_NAME)
+ {
+ tree tmp = get_value_for (op1, const_and_copies);
+ if (tmp)
+ op1 = tmp;
+ }
+
+ /* Stuff the operator and operands into our dummy conditional
+ expression, creating the dummy conditional if necessary. */
+ dummy_cond = walk_data->global_data;
+ if (! dummy_cond)
+ {
+ dummy_cond = build (cond_code, boolean_type_node, op0, op1);
+ dummy_cond = build (COND_EXPR, void_type_node,
+ dummy_cond, NULL, NULL);
+ walk_data->global_data = dummy_cond;
+ }
+ else
+ {
+ TREE_SET_CODE (TREE_OPERAND (dummy_cond, 0), cond_code);
+ TREE_OPERAND (TREE_OPERAND (dummy_cond, 0), 0) = op0;
+ TREE_OPERAND (TREE_OPERAND (dummy_cond, 0), 1) = op1;
+ }
+
+ /* If the conditional folds to an invariant, then we are done,
+ otherwise look it up in the hash tables. */
+ cached_lhs = local_fold (COND_EXPR_COND (dummy_cond));
+ if (! is_gimple_min_invariant (cached_lhs))
+ cached_lhs = lookup_avail_expr (dummy_cond, NULL, false);
+ if (!cached_lhs || ! is_gimple_min_invariant (cached_lhs))
+ {
+ stmt_ann_t ann = get_stmt_ann (dummy_cond);
+ cached_lhs = simplify_cond_and_lookup_avail_expr (dummy_cond,
+ NULL,
+ ann,
+ false);
+ }
+ }
+ /* We can have conditionals which just test the state of a
+ variable rather than use a relational operator. These are
+ simpler to handle. */
+ else if (TREE_CODE (cond) == SSA_NAME)
+ {
+ cached_lhs = cond;
+ cached_lhs = get_value_for (cached_lhs, const_and_copies);
+ if (cached_lhs && ! is_gimple_min_invariant (cached_lhs))
+ cached_lhs = 0;
+ }
+ else
+ cached_lhs = lookup_avail_expr (stmt, NULL, false);
+
+ if (cached_lhs)
+ {
+ edge taken_edge = find_taken_edge (e->dest, cached_lhs);
+ basic_block dest = (taken_edge ? taken_edge->dest : NULL);
+
+ if (dest == e->src)
+ return;
+
+ /* If we have a known destination for the conditional, then
+ we can perform this optimization, which saves at least one
+ conditional jump each time it applies since we get to
+ bypass the conditional at our original destination.
+
+ Note that we can either thread through a block with PHIs
+ or to a block with PHIs, but not both. At this time the
+ bookkeeping to keep the CFG & SSA up-to-date has proven
+ difficult. */
+ if (dest)
+ {
+ int saved_forwardable = bb_ann (e->src)->forwardable;
+ edge tmp_edge;
+
+ bb_ann (e->src)->forwardable = 0;
+ tmp_edge = tree_block_forwards_to (dest);
+ taken_edge = (tmp_edge ? tmp_edge : taken_edge);
+ bb_ann (e->src)->forwardable = saved_forwardable;
+ VARRAY_PUSH_EDGE (redirection_edges, e);
+ VARRAY_PUSH_EDGE (redirection_edges, taken_edge);
+ }
+ }
+ }
+}
+
+
+/* Initialize the local stacks.
+
+ AVAIL_EXPRS stores all the expressions made available in this block.
+
+ CONST_AND_COPIES stores var/value pairs to restore at the end of this
+ block.
+
+ NONZERO_VARS stores the vars which have a nonzero value made in this
+ block.
+
+ STMTS_TO_RESCAN is a list of statements we will rescan for operands.
+
+ VRP_VARIABLES is the list of variables which have had their values
+ constrained by an operation in this block.
+
+ These stacks are cleared in the finalization routine run for each
+ block. */
+
+static void
+dom_opt_initialize_block_local_data (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
+ basic_block bb ATTRIBUTE_UNUSED,
+ bool recycled ATTRIBUTE_UNUSED)
+{
+#ifdef ENABLE_CHECKING
+ struct dom_walk_block_data *bd
+ = (struct dom_walk_block_data *)VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
+
+ /* We get cleared memory from the allocator, so if the memory is not
+ cleared, then we are re-using a previously allocated entry. In
+ that case, we can also re-use the underlying virtual arrays. Just
+ make sure we clear them before using them! */
+ if (recycled)
+ {
+ if (bd->avail_exprs && VARRAY_ACTIVE_SIZE (bd->avail_exprs) > 0)
+ abort ();
+ if (bd->const_and_copies && VARRAY_ACTIVE_SIZE (bd->const_and_copies) > 0)
+ abort ();
+ if (bd->nonzero_vars && VARRAY_ACTIVE_SIZE (bd->nonzero_vars) > 0)
+ abort ();
+ if (bd->stmts_to_rescan && VARRAY_ACTIVE_SIZE (bd->stmts_to_rescan) > 0)
+ abort ();
+ if (bd->vrp_variables && VARRAY_ACTIVE_SIZE (bd->vrp_variables) > 0)
+ abort ();
+ if (bd->block_defs && VARRAY_ACTIVE_SIZE (bd->block_defs) > 0)
+ abort ();
+ }
+#endif
+}
+
+/* Initialize local stacks for this optimizer and record equivalences
+ upon entry to BB. Equivalences can come from the edge traversed to
+ reach BB or they may come from PHI nodes at the start of BB. */
+
+static void
+dom_opt_initialize_block (struct dom_walk_data *walk_data, basic_block bb)
+{
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "\n\nOptimizing block #%d\n\n", bb->index);
+
+ record_equivalences_from_incoming_edge (walk_data, bb);
+
+ /* PHI nodes can create equivalences too. */
+ record_equivalences_from_phis (walk_data, bb);
+}
+
+/* Given an expression EXPR (a relational expression or a statement),
+ initialize the hash table element pointed by by ELEMENT. */
+
+static void
+initialize_hash_element (tree expr, tree lhs, struct expr_hash_elt *element)
+{
+ /* Hash table elements may be based on conditional expressions or statements.
+
+ For the former case, we have no annotation and we want to hash the
+ conditional expression. In the latter case we have an annotation and
+ we want to record the expression the statement evaluates. */
+ if (TREE_CODE_CLASS (TREE_CODE (expr)) == '<'
+ || TREE_CODE (expr) == TRUTH_NOT_EXPR)
+ {
+ element->ann = NULL;
+ element->rhs = expr;
+ }
+ else if (TREE_CODE (expr) == COND_EXPR)
+ {
+ element->ann = stmt_ann (expr);
+ element->rhs = COND_EXPR_COND (expr);
+ }
+ else if (TREE_CODE (expr) == SWITCH_EXPR)
+ {
+ element->ann = stmt_ann (expr);
+ element->rhs = SWITCH_COND (expr);
+ }
+ else if (TREE_CODE (expr) == RETURN_EXPR && TREE_OPERAND (expr, 0))
+ {
+ element->ann = stmt_ann (expr);
+ element->rhs = TREE_OPERAND (TREE_OPERAND (expr, 0), 1);
+ }
+ else
+ {
+ element->ann = stmt_ann (expr);
+ element->rhs = TREE_OPERAND (expr, 1);
+ }
+
+ element->lhs = lhs;
+ element->hash = avail_expr_hash (element);
+}
+
+/* Remove all the expressions in LOCALS from TABLE, stopping when there are
+ LIMIT entries left in LOCALs. */
+
+static void
+remove_local_expressions_from_table (varray_type locals,
+ unsigned limit,
+ htab_t table)
+{
+ if (! locals)
+ return;
+
+ /* Remove all the expressions made available in this block. */
+ while (VARRAY_ACTIVE_SIZE (locals) > limit)
+ {
+ struct expr_hash_elt element;
+ tree expr = VARRAY_TOP_TREE (locals);
+ VARRAY_POP (locals);
+
+ initialize_hash_element (expr, NULL, &element);
+ htab_remove_elt_with_hash (table, &element, element.hash);
+ }
+}
+
+/* Use the SSA_NAMES in LOCALS to restore TABLE to its original
+ state, stopping when there are LIMIT entires left in LOCALs. */
+
+static void
+restore_nonzero_vars_to_original_value (varray_type locals,
+ unsigned limit,
+ bitmap table)
+{
+ if (!locals)
+ return;
+
+ while (VARRAY_ACTIVE_SIZE (locals) > limit)
+ {
+ tree name = VARRAY_TOP_TREE (locals);
+ VARRAY_POP (locals);
+ bitmap_clear_bit (table, SSA_NAME_VERSION (name));
+ }
+}
+
+/* Use the source/dest pairs in LOCALS to restore TABLE to its original
+ state, stopping when there are LIMIT entires left in LOCALs. */
+
+static void
+restore_vars_to_original_value (varray_type locals,
+ unsigned limit,
+ varray_type table)
+{
+ if (! locals)
+ return;
+
+ while (VARRAY_ACTIVE_SIZE (locals) > limit)
+ {
+ tree prev_value, dest;
+
+ prev_value = VARRAY_TOP_TREE (locals);
+ VARRAY_POP (locals);
+ dest = VARRAY_TOP_TREE (locals);
+ VARRAY_POP (locals);
+
+ set_value_for (dest, prev_value, table);
+ }
+}
+
+/* Similar to restore_vars_to_original_value, except that it restores
+ CURRDEFS to its original value. */
+static void
+restore_currdefs_to_original_value (varray_type locals, unsigned limit)
+{
+ if (!locals)
+ return;
+
+ /* Restore CURRDEFS to its original state. */
+ while (VARRAY_ACTIVE_SIZE (locals) > limit)
+ {
+ tree tmp = VARRAY_TOP_TREE (locals);
+ tree saved_def, var;
+
+ VARRAY_POP (locals);
+
+ /* If we recorded an SSA_NAME, then make the SSA_NAME the current
+ definition of its underlying variable. If we recorded anything
+ else, it must have been an _DECL node and its current reaching
+ definition must have been NULL. */
+ if (TREE_CODE (tmp) == SSA_NAME)
+ {
+ saved_def = tmp;
+ var = SSA_NAME_VAR (saved_def);
+ }
+ else
+ {
+ saved_def = NULL;
+ var = tmp;
+ }
+
+ var_ann (var)->current_def = saved_def;
+ }
+}
+
+/* We have finished processing the dominator children of BB, perform
+ any finalization actions in preparation for leaving this node in
+ the dominator tree. */
+
+static void
+dom_opt_finalize_block (struct dom_walk_data *walk_data, basic_block bb)
+{
+ struct dom_walk_block_data *bd
+ = VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
+ tree last;
+
+ /* If we are at a leaf node in the dominator graph, see if we can thread
+ the edge from BB through its successor.
+
+ Do this before we remove entries from our equivalence tables. */
+ if (bb->succ
+ && ! bb->succ->succ_next
+ && (bb->succ->flags & EDGE_ABNORMAL) == 0
+ && (get_immediate_dominator (CDI_DOMINATORS, bb->succ->dest) != bb
+ || phi_nodes (bb->succ->dest)))
+
+ {
+ thread_across_edge (walk_data, bb->succ);
+ }
+ else if ((last = last_stmt (bb))
+ && TREE_CODE (last) == COND_EXPR
+ && (TREE_CODE_CLASS (TREE_CODE (COND_EXPR_COND (last))) == '<'
+ || TREE_CODE (COND_EXPR_COND (last)) == SSA_NAME)
+ && bb->succ
+ && (bb->succ->flags & EDGE_ABNORMAL) == 0
+ && bb->succ->succ_next
+ && (bb->succ->succ_next->flags & EDGE_ABNORMAL) == 0
+ && ! bb->succ->succ_next->succ_next)
+ {
+ edge true_edge, false_edge;
+ tree cond, inverted = NULL;
+ enum tree_code cond_code;
+
+ extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
+
+ cond = COND_EXPR_COND (last);
+ cond_code = TREE_CODE (cond);
+
+ if (TREE_CODE_CLASS (cond_code) == '<')
+ inverted = invert_truthvalue (cond);
+
+ /* If the THEN arm is the end of a dominator tree or has PHI nodes,
+ then try to thread through its edge. */
+ if (get_immediate_dominator (CDI_DOMINATORS, true_edge->dest) != bb
+ || phi_nodes (true_edge->dest))
+ {
+ unsigned avail_expr_limit;
+ unsigned const_and_copies_limit;
+ unsigned currdefs_limit;
+
+ avail_expr_limit
+ = bd->avail_exprs ? VARRAY_ACTIVE_SIZE (bd->avail_exprs) : 0;
+ const_and_copies_limit
+ = bd->const_and_copies ? VARRAY_ACTIVE_SIZE (bd->const_and_copies)
+ : 0;
+ currdefs_limit
+ = bd->block_defs ? VARRAY_ACTIVE_SIZE (bd->block_defs) : 0;
+
+ /* Record any equivalences created by following this edge. */
+ if (TREE_CODE_CLASS (cond_code) == '<')
+ {
+ record_cond (cond, boolean_true_node, &bd->avail_exprs);
+ record_cond (inverted, boolean_false_node, &bd->avail_exprs);
+ }
+ else if (cond_code == SSA_NAME)
+ record_const_or_copy (cond, boolean_true_node,
+ &bd->const_and_copies);
+
+ /* Now thread the edge. */
+ thread_across_edge (walk_data, true_edge);
+
+ /* And restore the various tables to their state before
+ we threaded this edge. */
+ remove_local_expressions_from_table (bd->avail_exprs,
+ avail_expr_limit,
+ avail_exprs);
+ restore_vars_to_original_value (bd->const_and_copies,
+ const_and_copies_limit,
+ const_and_copies);
+ restore_currdefs_to_original_value (bd->block_defs, currdefs_limit);
+ }
+
+ /* Similarly for the ELSE arm. */
+ if (get_immediate_dominator (CDI_DOMINATORS, false_edge->dest) != bb
+ || phi_nodes (false_edge->dest))
+ {
+ /* Record any equivalences created by following this edge. */
+ if (TREE_CODE_CLASS (cond_code) == '<')
+ {
+ record_cond (cond, boolean_false_node, &bd->avail_exprs);
+ record_cond (inverted, boolean_true_node, &bd->avail_exprs);
+ }
+ else if (cond_code == SSA_NAME)
+ record_const_or_copy (cond, boolean_false_node,
+ &bd->const_and_copies);
+
+ thread_across_edge (walk_data, false_edge);
+
+ /* No need to remove local expressions from our tables
+ or restore vars to their original value as that will
+ be done immediately below. */
+ }
+ }
+
+ remove_local_expressions_from_table (bd->avail_exprs, 0, avail_exprs);
+ restore_nonzero_vars_to_original_value (bd->nonzero_vars, 0, nonzero_vars);
+ restore_vars_to_original_value (bd->const_and_copies, 0, const_and_copies);
+ restore_currdefs_to_original_value (bd->block_defs, 0);
+
+ /* Remove VRP records associated with this basic block. They are no
+ longer valid.
+
+ To be efficient, we note which variables have had their values
+ constrained in this block. So walk over each variable in the
+ VRP_VARIABLEs array. */
+ while (bd->vrp_variables && VARRAY_ACTIVE_SIZE (bd->vrp_variables) > 0)
+ {
+ tree var = VARRAY_TOP_TREE (bd->vrp_variables);
+
+ /* Each variable has a stack of value range records. We want to
+ invalidate those associated with our basic block. So we walk
+ the array backwards popping off records associated with our
+ block. Once we hit a record not associated with our block
+ we are done. */
+ varray_type var_vrp_records = VARRAY_GENERIC_PTR (vrp_data,
+ SSA_NAME_VERSION (var));
+
+ while (VARRAY_ACTIVE_SIZE (var_vrp_records) > 0)
+ {
+ struct vrp_element *element
+ = (struct vrp_element *)VARRAY_TOP_GENERIC_PTR (var_vrp_records);
+
+ if (element->bb != bb)
+ break;
+
+ VARRAY_POP (var_vrp_records);
+ }
+
+ VARRAY_POP (bd->vrp_variables);
+ }
+
+ /* Re-scan operands in all statements that may have had new symbols
+ exposed. */
+ while (bd->stmts_to_rescan && VARRAY_ACTIVE_SIZE (bd->stmts_to_rescan) > 0)
+ {
+ tree stmt = VARRAY_TOP_TREE (bd->stmts_to_rescan);
+ VARRAY_POP (bd->stmts_to_rescan);
+ mark_new_vars_to_rename (stmt, vars_to_rename);
+ }
+}
+
+/* PHI nodes can create equivalences too.
+
+ Ignoring any alternatives which are the same as the result, if
+ all the alternatives are equal, then the PHI node creates an
+ equivalence. */
+static void
+record_equivalences_from_phis (struct dom_walk_data *walk_data, basic_block bb)
+{
+ struct dom_walk_block_data *bd
+ = VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
+ tree phi;
+
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ tree lhs = PHI_RESULT (phi);
+ tree rhs = NULL;
+ int i;
+
+ for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ {
+ tree t = PHI_ARG_DEF (phi, i);
+
+ if (TREE_CODE (t) == SSA_NAME || is_gimple_min_invariant (t))
+ {
+ /* Ignore alternatives which are the same as our LHS. */
+ if (operand_equal_p (lhs, t, 0))
+ continue;
+
+ /* If we have not processed an alternative yet, then set
+ RHS to this alternative. */
+ if (rhs == NULL)
+ rhs = t;
+ /* If we have processed an alternative (stored in RHS), then
+ see if it is equal to this one. If it isn't, then stop
+ the search. */
+ else if (! operand_equal_p (rhs, t, 0))
+ break;
+ }
+ else
+ break;
+ }
+
+ /* If we had no interesting alternatives, then all the RHS alternatives
+ must have been the same as LHS. */
+ if (!rhs)
+ rhs = lhs;
+
+ /* If we managed to iterate through each PHI alternative without
+ breaking out of the loop, then we have a PHI which may create
+ a useful equivalence. We do not need to record unwind data for
+ this, since this is a true assignment and not an equivalence
+ infered from a comparison. All uses of this ssa name are dominated
+ by this assignment, so unwinding just costs time and space. */
+ if (i == PHI_NUM_ARGS (phi)
+ && may_propagate_copy (lhs, rhs))
+ set_value_for (lhs, rhs, const_and_copies);
+
+ register_new_def (lhs, &bd->block_defs);
+ }
+}
+
+/* Record any equivalences created by the incoming edge to BB. If BB
+ has more than one incoming edge, then no equivalence is created. */
+
+static void
+record_equivalences_from_incoming_edge (struct dom_walk_data *walk_data,
+ basic_block bb)
+{
+ int edge_flags;
+ basic_block parent;
+ struct eq_expr_value eq_expr_value;
+ tree parent_block_last_stmt = NULL;
+ struct dom_walk_block_data *bd
+ = VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
+
+ /* If our parent block ended with a control statment, then we may be
+ able to record some equivalences based on which outgoing edge from
+ the parent was followed. */
+ parent = get_immediate_dominator (CDI_DOMINATORS, bb);
+ if (parent)
+ {
+ parent_block_last_stmt = last_stmt (parent);
+ if (parent_block_last_stmt && !is_ctrl_stmt (parent_block_last_stmt))
+ parent_block_last_stmt = NULL;
+ }
+
+ eq_expr_value.src = NULL;
+ eq_expr_value.dst = NULL;
+
+ /* If we have a single predecessor, then extract EDGE_FLAGS from
+ our single incoming edge. Otherwise clear EDGE_FLAGS and
+ PARENT_BLOCK_LAST_STMT since they're not needed. */
+ if (bb->pred
+ && ! bb->pred->pred_next
+ && parent_block_last_stmt
+ && bb_for_stmt (parent_block_last_stmt) == bb->pred->src)
+ {
+ edge_flags = bb->pred->flags;
+ }
+ else
+ {
+ edge_flags = 0;
+ parent_block_last_stmt = NULL;
+ }
+
+ /* If our parent block ended in a COND_EXPR, add any equivalences
+ created by the COND_EXPR to the hash table and initialize
+ EQ_EXPR_VALUE appropriately.
+
+ EQ_EXPR_VALUE is an assignment expression created when BB's immediate
+ dominator ends in a COND_EXPR statement whose predicate is of the form
+ 'VAR == VALUE', where VALUE may be another variable or a constant.
+ This is used to propagate VALUE on the THEN_CLAUSE of that
+ conditional. This assignment is inserted in CONST_AND_COPIES so that
+ the copy and constant propagator can find more propagation
+ opportunities. */
+ if (parent_block_last_stmt
+ && bb->pred->pred_next == NULL
+ && TREE_CODE (parent_block_last_stmt) == COND_EXPR
+ && (edge_flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
+ eq_expr_value = get_eq_expr_value (parent_block_last_stmt,
+ (edge_flags & EDGE_TRUE_VALUE) != 0,
+ &bd->avail_exprs,
+ bb,
+ &bd->vrp_variables);
+ /* Similarly when the parent block ended in a SWITCH_EXPR. */
+ else if (parent_block_last_stmt
+ && bb->pred->pred_next == NULL
+ && TREE_CODE (parent_block_last_stmt) == SWITCH_EXPR)
+ {
+ tree switch_cond = SWITCH_COND (parent_block_last_stmt);
+
+ /* If the switch's condition is an SSA variable, then we may
+ know its value at each of the case labels. */
+ if (TREE_CODE (switch_cond) == SSA_NAME)
+ {
+ tree switch_vec = SWITCH_LABELS (parent_block_last_stmt);
+ size_t i, n = TREE_VEC_LENGTH (switch_vec);
+ int case_count = 0;
+ tree match_case = NULL_TREE;
+
+ /* Search the case labels for those whose destination is
+ the current basic block. */
+ for (i = 0; i < n; ++i)
+ {
+ tree elt = TREE_VEC_ELT (switch_vec, i);
+ if (label_to_block (CASE_LABEL (elt)) == bb)
+ {
+ if (++case_count > 1)
+ break;
+ match_case = elt;
+ }
+ }
+
+ /* If we encountered precisely one CASE_LABEL_EXPR and it
+ was not the default case, or a case range, then we know
+ the exact value of SWITCH_COND which caused us to get to
+ this block. Record that equivalence in EQ_EXPR_VALUE. */
+ if (case_count == 1
+ && CASE_LOW (match_case)
+ && !CASE_HIGH (match_case))
+ {
+ eq_expr_value.dst = switch_cond;
+ eq_expr_value.src = CASE_LOW (match_case);
+ }
+ }
+ }
+
+ /* If EQ_EXPR_VALUE (VAR == VALUE) is given, register the VALUE as a
+ new value for VAR, so that occurrences of VAR can be replaced with
+ VALUE while re-writing the THEN arm of a COND_EXPR. */
+ if (eq_expr_value.src && eq_expr_value.dst)
+ record_equality (eq_expr_value.dst, eq_expr_value.src,
+ &bd->const_and_copies);
+}
+
+/* Dump SSA statistics on FILE. */
+
+void
+dump_dominator_optimization_stats (FILE *file)
+{
+ long n_exprs;
+
+ fprintf (file, "Total number of statements: %6ld\n\n",
+ opt_stats.num_stmts);
+ fprintf (file, "Exprs considered for dominator optimizations: %6ld\n",
+ opt_stats.num_exprs_considered);
+
+ n_exprs = opt_stats.num_exprs_considered;
+ if (n_exprs == 0)
+ n_exprs = 1;
+
+ fprintf (file, " Redundant expressions eliminated: %6ld (%.0f%%)\n",
+ opt_stats.num_re, PERCENT (opt_stats.num_re,
+ n_exprs));
+
+ fprintf (file, "\nHash table statistics:\n");
+
+ fprintf (file, " avail_exprs: ");
+ htab_statistics (file, avail_exprs);
+}
+
+
+/* Dump SSA statistics on stderr. */
+
+void
+debug_dominator_optimization_stats (void)
+{
+ dump_dominator_optimization_stats (stderr);
+}
+
+
+/* Dump statistics for the hash table HTAB. */
+
+static void
+htab_statistics (FILE *file, htab_t htab)
+{
+ fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n",
+ (long) htab_size (htab),
+ (long) htab_elements (htab),
+ htab_collisions (htab));
+}
+
+/* Record the fact that VAR has a nonzero value, though we may not know
+ its exact value. Note that if VAR is already known to have a nonzero
+ value, then we do nothing. */
+
+static void
+record_var_is_nonzero (tree var, varray_type *block_nonzero_vars_p)
+{
+ int indx = SSA_NAME_VERSION (var);
+
+ if (bitmap_bit_p (nonzero_vars, indx))
+ return;
+
+ /* Mark it in the global table. */
+ bitmap_set_bit (nonzero_vars, indx);
+
+ /* Record this SSA_NAME so that we can reset the global table
+ when we leave this block. */
+ if (! *block_nonzero_vars_p)
+ VARRAY_TREE_INIT (*block_nonzero_vars_p, 2, "block_nonzero_vars");
+ VARRAY_PUSH_TREE (*block_nonzero_vars_p, var);
+}
+
+/* Enter a statement into the true/false expression hash table indicating
+ that the condition COND has the value VALUE. */
+
+static void
+record_cond (tree cond, tree value, varray_type *block_avail_exprs_p)
+{
+ struct expr_hash_elt *element = xmalloc (sizeof (struct expr_hash_elt));
+ void **slot;
+
+ initialize_hash_element (cond, value, element);
+
+ slot = htab_find_slot_with_hash (avail_exprs, (void *)element,
+ element->hash, true);
+ if (*slot == NULL)
+ {
+ *slot = (void *) element;
+ if (! *block_avail_exprs_p)
+ VARRAY_TREE_INIT (*block_avail_exprs_p, 20, "block_avail_exprs");
+ VARRAY_PUSH_TREE (*block_avail_exprs_p, cond);
+ }
+ else
+ free (element);
+}
+
+/* A helper function for record_const_or_copy and record_equality.
+ Do the work of recording the value and undo info. */
+
+static void
+record_const_or_copy_1 (tree x, tree y, tree prev_x,
+ varray_type *block_const_and_copies_p)
+{
+ set_value_for (x, y, const_and_copies);
+
+ if (!*block_const_and_copies_p)
+ VARRAY_TREE_INIT (*block_const_and_copies_p, 2, "block_const_and_copies");
+ VARRAY_PUSH_TREE (*block_const_and_copies_p, x);
+ VARRAY_PUSH_TREE (*block_const_and_copies_p, prev_x);
+}
+
+/* Record that X is equal to Y in const_and_copies. Record undo
+ information in the block-local varray. */
+
+static void
+record_const_or_copy (tree x, tree y, varray_type *block_const_and_copies_p)
+{
+ tree prev_x = get_value_for (x, const_and_copies);
+
+ if (TREE_CODE (y) == SSA_NAME)
+ {
+ tree tmp = get_value_for (y, const_and_copies);
+ if (tmp)
+ y = tmp;
+ }
+
+ record_const_or_copy_1 (x, y, prev_x, block_const_and_copies_p);
+}
+
+/* Similarly, but assume that X and Y are the two operands of an EQ_EXPR.
+ This constrains the cases in which we may treat this as assignment. */
+
+static void
+record_equality (tree x, tree y, varray_type *block_const_and_copies_p)
+{
+ tree prev_x = NULL, prev_y = NULL;
+
+ if (TREE_CODE (x) == SSA_NAME)
+ prev_x = get_value_for (x, const_and_copies);
+ if (TREE_CODE (y) == SSA_NAME)
+ prev_y = get_value_for (y, const_and_copies);
+
+ /* If one of the previous values is invariant, then use that.
+ Otherwise it doesn't matter which value we choose, just so
+ long as we canonicalize on one value. */
+ if (TREE_INVARIANT (y))
+ ;
+ else if (TREE_INVARIANT (x))
+ prev_x = x, x = y, y = prev_x, prev_x = prev_y;
+ else if (prev_x && TREE_INVARIANT (prev_x))
+ x = y, y = prev_x, prev_x = prev_y;
+ else if (prev_y)
+ y = prev_y;
+
+ /* After the swapping, we must have one SSA_NAME. */
+ if (TREE_CODE (x) != SSA_NAME)
+ return;
+
+ /* For IEEE, -0.0 == 0.0, so we don't necessarily know the sign of a
+ variable compared against zero. If we're honoring signed zeros,
+ then we cannot record this value unless we know that the value is
+ non-zero. */
+ if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (x)))
+ && (TREE_CODE (y) != REAL_CST
+ || REAL_VALUES_EQUAL (dconst0, TREE_REAL_CST (y))))
+ return;
+
+ record_const_or_copy_1 (x, y, prev_x, block_const_and_copies_p);
+}
+
+/* STMT is a MODIFY_EXPR for which we were unable to find RHS in the
+ hash tables. Try to simplify the RHS using whatever equivalences
+ we may have recorded.
+
+ If we are able to simplify the RHS, then lookup the simplified form in
+ the hash table and return the result. Otherwise return NULL. */
+
+static tree
+simplify_rhs_and_lookup_avail_expr (struct dom_walk_data *walk_data,
+ tree stmt,
+ stmt_ann_t ann,
+ int insert)
+{
+ tree rhs = TREE_OPERAND (stmt, 1);
+ enum tree_code rhs_code = TREE_CODE (rhs);
+ tree result = NULL;
+ struct dom_walk_block_data *bd
+ = VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
+
+ /* If we have lhs = ~x, look and see if we earlier had x = ~y.
+ In which case we can change this statement to be lhs = y.
+ Which can then be copy propagated.
+
+ Similarly for negation. */
+ if ((rhs_code == BIT_NOT_EXPR || rhs_code == NEGATE_EXPR)
+ && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
+ {
+ /* Get the definition statement for our RHS. */
+ tree rhs_def_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0));
+
+ /* See if the RHS_DEF_STMT has the same form as our statement. */
+ if (TREE_CODE (rhs_def_stmt) == MODIFY_EXPR
+ && TREE_CODE (TREE_OPERAND (rhs_def_stmt, 1)) == rhs_code)
+ {
+ tree rhs_def_operand;
+
+ rhs_def_operand = TREE_OPERAND (TREE_OPERAND (rhs_def_stmt, 1), 0);
+
+ /* Verify that RHS_DEF_OPERAND is a suitable SSA variable. */
+ if (TREE_CODE (rhs_def_operand) == SSA_NAME
+ && ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs_def_operand))
+ result = update_rhs_and_lookup_avail_expr (stmt,
+ rhs_def_operand,
+ &bd->avail_exprs,
+ ann,
+ insert);
+ }
+ }
+
+ /* If we have z = (x OP C1), see if we earlier had x = y OP C2.
+ If OP is associative, create and fold (y OP C2) OP C1 which
+ should result in (y OP C3), use that as the RHS for the
+ assignment. Add minus to this, as we handle it specially below. */
+ if ((associative_tree_code (rhs_code) || rhs_code == MINUS_EXPR)
+ && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
+ && is_gimple_min_invariant (TREE_OPERAND (rhs, 1)))
+ {
+ tree rhs_def_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0));
+
+ /* See if the RHS_DEF_STMT has the same form as our statement. */
+ if (TREE_CODE (rhs_def_stmt) == MODIFY_EXPR)
+ {
+ tree rhs_def_rhs = TREE_OPERAND (rhs_def_stmt, 1);
+ enum tree_code rhs_def_code = TREE_CODE (rhs_def_rhs);
+
+ if (rhs_code == rhs_def_code
+ || (rhs_code == PLUS_EXPR && rhs_def_code == MINUS_EXPR)
+ || (rhs_code == MINUS_EXPR && rhs_def_code == PLUS_EXPR))
+ {
+ tree def_stmt_op0 = TREE_OPERAND (rhs_def_rhs, 0);
+ tree def_stmt_op1 = TREE_OPERAND (rhs_def_rhs, 1);
+
+ if (TREE_CODE (def_stmt_op0) == SSA_NAME
+ && ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def_stmt_op0)
+ && is_gimple_min_invariant (def_stmt_op1))
+ {
+ tree outer_const = TREE_OPERAND (rhs, 1);
+ tree type = TREE_TYPE (TREE_OPERAND (stmt, 0));
+ tree t;
+
+ /* Ho hum. So fold will only operate on the outermost
+ thingy that we give it, so we have to build the new
+ expression in two pieces. This requires that we handle
+ combinations of plus and minus. */
+ if (rhs_def_code != rhs_code)
+ {
+ if (rhs_def_code == MINUS_EXPR)
+ t = build (MINUS_EXPR, type, outer_const, def_stmt_op1);
+ else
+ t = build (MINUS_EXPR, type, def_stmt_op1, outer_const);
+ rhs_code = PLUS_EXPR;
+ }
+ else if (rhs_def_code == MINUS_EXPR)
+ t = build (PLUS_EXPR, type, def_stmt_op1, outer_const);
+ else
+ t = build (rhs_def_code, type, def_stmt_op1, outer_const);
+ t = local_fold (t);
+ t = build (rhs_code, type, def_stmt_op0, t);
+ t = local_fold (t);
+
+ /* If the result is a suitable looking gimple expression,
+ then use it instead of the original for STMT. */
+ if (TREE_CODE (t) == SSA_NAME
+ || (TREE_CODE_CLASS (TREE_CODE (t)) == '1'
+ && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME)
+ || ((TREE_CODE_CLASS (TREE_CODE (t)) == '2'
+ || TREE_CODE_CLASS (TREE_CODE (t)) == '<')
+ && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME
+ && is_gimple_val (TREE_OPERAND (t, 1))))
+ result = update_rhs_and_lookup_avail_expr
+ (stmt, t, &bd->avail_exprs, ann, insert);
+ }
+ }
+ }
+ }
+
+ /* Transform TRUNC_DIV_EXPR and TRUNC_MOD_EXPR into RSHIFT_EXPR
+ and BIT_AND_EXPR respectively if the first operand is greater
+ than zero and the second operand is an exact power of two. */
+ if ((rhs_code == TRUNC_DIV_EXPR || rhs_code == TRUNC_MOD_EXPR)
+ && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (rhs, 0)))
+ && integer_pow2p (TREE_OPERAND (rhs, 1)))
+ {
+ tree val;
+ tree op = TREE_OPERAND (rhs, 0);
+
+ if (TYPE_UNSIGNED (TREE_TYPE (op)))
+ {
+ val = integer_one_node;
+ }
+ else
+ {
+ tree dummy_cond = walk_data->global_data;
+
+ if (! dummy_cond)
+ {
+ dummy_cond = build (GT_EXPR, boolean_type_node,
+ op, integer_zero_node);
+ dummy_cond = build (COND_EXPR, void_type_node,
+ dummy_cond, NULL, NULL);
+ walk_data->global_data = dummy_cond;
+ }
+ else
+ {
+ TREE_SET_CODE (TREE_OPERAND (dummy_cond, 0), GT_EXPR);
+ TREE_OPERAND (TREE_OPERAND (dummy_cond, 0), 0) = op;
+ TREE_OPERAND (TREE_OPERAND (dummy_cond, 0), 1)
+ = integer_zero_node;
+ }
+ val = simplify_cond_and_lookup_avail_expr (dummy_cond,
+ &bd->avail_exprs,
+ NULL, false);
+ }
+
+ if (val && integer_onep (val))
+ {
+ tree t;
+ tree op0 = TREE_OPERAND (rhs, 0);
+ tree op1 = TREE_OPERAND (rhs, 1);
+
+ if (rhs_code == TRUNC_DIV_EXPR)
+ t = build (RSHIFT_EXPR, TREE_TYPE (op0), op0,
+ build_int_2 (tree_log2 (op1), 0));
+ else
+ t = build (BIT_AND_EXPR, TREE_TYPE (op0), op0,
+ local_fold (build (MINUS_EXPR, TREE_TYPE (op1),
+ op1, integer_one_node)));
+
+ result = update_rhs_and_lookup_avail_expr (stmt, t,
+ &bd->avail_exprs,
+ ann, insert);
+ }
+ }
+
+ /* Transform ABS (X) into X or -X as appropriate. */
+ if (rhs_code == ABS_EXPR
+ && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (rhs, 0))))
+ {
+ tree val;
+ tree op = TREE_OPERAND (rhs, 0);
+ tree type = TREE_TYPE (op);
+
+ if (TYPE_UNSIGNED (type))
+ {
+ val = integer_zero_node;
+ }
+ else
+ {
+ tree dummy_cond = walk_data->global_data;
+
+ if (! dummy_cond)
+ {
+ dummy_cond = build (LE_EXPR, boolean_type_node,
+ op, integer_zero_node);
+ dummy_cond = build (COND_EXPR, void_type_node,
+ dummy_cond, NULL, NULL);
+ walk_data->global_data = dummy_cond;
+ }
+ else
+ {
+ TREE_SET_CODE (TREE_OPERAND (dummy_cond, 0), LE_EXPR);
+ TREE_OPERAND (TREE_OPERAND (dummy_cond, 0), 0) = op;
+ TREE_OPERAND (TREE_OPERAND (dummy_cond, 0), 1)
+ = convert (type, integer_zero_node);
+ }
+ val = simplify_cond_and_lookup_avail_expr (dummy_cond,
+ &bd->avail_exprs,
+ NULL, false);
+
+ if (!val)
+ {
+ TREE_SET_CODE (TREE_OPERAND (dummy_cond, 0), GE_EXPR);
+ TREE_OPERAND (TREE_OPERAND (dummy_cond, 0), 0) = op;
+ TREE_OPERAND (TREE_OPERAND (dummy_cond, 0), 1)
+ = convert (type, integer_zero_node);
+
+ val = simplify_cond_and_lookup_avail_expr (dummy_cond,
+ &bd->avail_exprs,
+ NULL, false);
+
+ if (val)
+ {
+ if (integer_zerop (val))
+ val = integer_one_node;
+ else if (integer_onep (val))
+ val = integer_zero_node;
+ }
+ }
+ }
+
+ if (val
+ && (integer_onep (val) || integer_zerop (val)))
+ {
+ tree t;
+
+ if (integer_onep (val))
+ t = build1 (NEGATE_EXPR, TREE_TYPE (op), op);
+ else
+ t = op;
+
+ result = update_rhs_and_lookup_avail_expr (stmt, t,
+ &bd->avail_exprs,
+ ann, insert);
+ }
+ }
+
+ /* Optimize *"foo" into 'f'. This is done here rather than
+ in fold to avoid problems with stuff like &*"foo". */
+ if (TREE_CODE (rhs) == INDIRECT_REF || TREE_CODE (rhs) == ARRAY_REF)
+ {
+ tree t = fold_read_from_constant_string (rhs);
+
+ if (t)
+ result = update_rhs_and_lookup_avail_expr (stmt, t,
+ &bd->avail_exprs,
+ ann, insert);
+ }
+
+ return result;
+}
+
+/* COND is a condition of the form:
+
+ x == const or x != const
+
+ Look back to x's defining statement and see if x is defined as
+
+ x = (type) y;
+
+ If const is unchanged if we convert it to type, then we can build
+ the equivalent expression:
+
+
+ y == const or y != const
+
+ Which may allow further optimizations.
+
+ Return the equivalent comparison or NULL if no such equivalent comparison
+ was found. */
+
+static tree
+find_equivalent_equality_comparison (tree cond)
+{
+ tree op0 = TREE_OPERAND (cond, 0);
+ tree op1 = TREE_OPERAND (cond, 1);
+ tree def_stmt = SSA_NAME_DEF_STMT (op0);
+
+ /* OP0 might have been a parameter, so first make sure it
+ was defined by a MODIFY_EXPR. */
+ if (def_stmt && TREE_CODE (def_stmt) == MODIFY_EXPR)
+ {
+ tree def_rhs = TREE_OPERAND (def_stmt, 1);
+
+ /* Now make sure the RHS of the MODIFY_EXPR is a typecast. */
+ if ((TREE_CODE (def_rhs) == NOP_EXPR
+ || TREE_CODE (def_rhs) == CONVERT_EXPR)
+ && TREE_CODE (TREE_OPERAND (def_rhs, 0)) == SSA_NAME)
+ {
+ tree def_rhs_inner = TREE_OPERAND (def_rhs, 0);
+ tree def_rhs_inner_type = TREE_TYPE (def_rhs_inner);
+ tree new;
+
+ if (TYPE_PRECISION (def_rhs_inner_type)
+ > TYPE_PRECISION (TREE_TYPE (def_rhs)))
+ return NULL;
+
+ /* What we want to prove is that if we convert OP1 to
+ the type of the object inside the NOP_EXPR that the
+ result is still equivalent to SRC.
+
+ If that is true, the build and return new equivalent
+ condition which uses the source of the typecast and the
+ new constant (which has only changed its type). */
+ new = build1 (TREE_CODE (def_rhs), def_rhs_inner_type, op1);
+ new = local_fold (new);
+ if (is_gimple_val (new) && tree_int_cst_equal (new, op1))
+ return build (TREE_CODE (cond), TREE_TYPE (cond),
+ def_rhs_inner, new);
+ }
+ }
+ return NULL;
+}
+
+/* STMT is a COND_EXPR for which we could not trivially determine its
+ result. This routine attempts to find equivalent forms of the
+ condition which we may be able to optimize better. It also
+ uses simple value range propagation to optimize conditionals. */
+
+static tree
+simplify_cond_and_lookup_avail_expr (tree stmt,
+ varray_type *block_avail_exprs_p,
+ stmt_ann_t ann,
+ int insert)
+{
+ tree cond = COND_EXPR_COND (stmt);
+
+ if (TREE_CODE_CLASS (TREE_CODE (cond)) == '<')
+ {
+ tree op0 = TREE_OPERAND (cond, 0);
+ tree op1 = TREE_OPERAND (cond, 1);
+
+ if (TREE_CODE (op0) == SSA_NAME && is_gimple_min_invariant (op1))
+ {
+ int limit;
+ tree low, high, cond_low, cond_high;
+ int lowequal, highequal, swapped, no_overlap, subset, cond_inverted;
+ varray_type vrp_records;
+ struct vrp_element *element;
+
+ /* First see if we have test of an SSA_NAME against a constant
+ where the SSA_NAME is defined by an earlier typecast which
+ is irrelevant when performing tests against the given
+ constant. */
+ if (TREE_CODE (cond) == EQ_EXPR || TREE_CODE (cond) == NE_EXPR)
+ {
+ tree new_cond = find_equivalent_equality_comparison (cond);
+
+ if (new_cond)
+ {
+ /* Update the statement to use the new equivalent
+ condition. */
+ COND_EXPR_COND (stmt) = new_cond;
+ ann->modified = 1;
+
+ /* Lookup the condition and return its known value if it
+ exists. */
+ new_cond = lookup_avail_expr (stmt, block_avail_exprs_p,
+ insert);
+ if (new_cond)
+ return new_cond;
+
+ /* The operands have changed, so update op0 and op1. */
+ op0 = TREE_OPERAND (cond, 0);
+ op1 = TREE_OPERAND (cond, 1);
+ }
+ }
+
+ /* Consult the value range records for this variable (if they exist)
+ to see if we can eliminate or simplify this conditional.
+
+ Note two tests are necessary to determine no records exist.
+ First we have to see if the virtual array exists, if it
+ exists, then we have to check its active size.
+
+ Also note the vast majority of conditionals are not testing
+ a variable which has had its range constrained by an earlier
+ conditional. So this filter avoids a lot of unnecessary work. */
+ vrp_records = VARRAY_GENERIC_PTR (vrp_data, SSA_NAME_VERSION (op0));
+ if (vrp_records == NULL)
+ return NULL;
+
+ limit = VARRAY_ACTIVE_SIZE (vrp_records);
+
+ /* If we have no value range records for this variable, or we are
+ unable to extract a range for this condition, then there is
+ nothing to do. */
+ if (limit == 0
+ || ! extract_range_from_cond (cond, &cond_high,
+ &cond_low, &cond_inverted))
+ return NULL;
+
+ /* We really want to avoid unnecessary computations of range
+ info. So all ranges are computed lazily; this avoids a
+ lot of unnecessary work. ie, we record the conditional,
+ but do not process how it constrains the variable's
+ potential values until we know that processing the condition
+ could be helpful.
+
+ However, we do not want to have to walk a potentially long
+ list of ranges, nor do we want to compute a variable's
+ range more than once for a given path.
+
+ Luckily, each time we encounter a conditional that can not
+ be otherwise optimized we will end up here and we will
+ compute the necessary range information for the variable
+ used in this condition.
+
+ Thus you can conclude that there will never be more than one
+ conditional associated with a variable which has not been
+ processed. So we never need to merge more than one new
+ conditional into the current range.
+
+ These properties also help us avoid unnecessary work. */
+ element
+ = (struct vrp_element *)VARRAY_GENERIC_PTR (vrp_records, limit - 1);
+
+ if (element->high && element->low)
+ {
+ /* The last element has been processed, so there is no range
+ merging to do, we can simply use the high/low values
+ recorded in the last element. */
+ low = element->low;
+ high = element->high;
+ }
+ else
+ {
+ tree tmp_high, tmp_low;
+ int dummy;
+
+ /* The last element has not been processed. Process it now. */
+ extract_range_from_cond (element->cond, &tmp_high,
+ &tmp_low, &dummy);
+
+ /* If this is the only element, then no merging is necessary,
+ the high/low values from extract_range_from_cond are all
+ we need. */
+ if (limit == 1)
+ {
+ low = tmp_low;
+ high = tmp_high;
+ }
+ else
+ {
+ /* Get the high/low value from the previous element. */
+ struct vrp_element *prev
+ = (struct vrp_element *)VARRAY_GENERIC_PTR (vrp_records,
+ limit - 2);
+ low = prev->low;
+ high = prev->high;
+
+ /* Merge in this element's range with the range from the
+ previous element.
+
+ The low value for the merged range is the maximum of
+ the previous low value and the low value of this record.
+
+ Similarly the high value for the merged range is the
+ minimum of the previous high value and the high value of
+ this record. */
+ low = (tree_int_cst_compare (low, tmp_low) == 1
+ ? low : tmp_low);
+ high = (tree_int_cst_compare (high, tmp_high) == -1
+ ? high : tmp_high);
+ }
+
+ /* And record the computed range. */
+ element->low = low;
+ element->high = high;
+
+ }
+
+ /* After we have constrained this variable's potential values,
+ we try to determine the result of the given conditional.
+
+ To simplify later tests, first determine if the current
+ low value is the same low value as the conditional.
+ Similarly for the current high value and the high value
+ for the conditional. */
+ lowequal = tree_int_cst_equal (low, cond_low);
+ highequal = tree_int_cst_equal (high, cond_high);
+
+ if (lowequal && highequal)
+ return (cond_inverted ? boolean_false_node : boolean_true_node);
+
+ /* To simplify the overlap/subset tests below we may want
+ to swap the two ranges so that the larger of the two
+ ranges occurs "first". */
+ swapped = 0;
+ if (tree_int_cst_compare (low, cond_low) == 1
+ || (lowequal
+ && tree_int_cst_compare (cond_high, high) == 1))
+ {
+ tree temp;
+
+ swapped = 1;
+ temp = low;
+ low = cond_low;
+ cond_low = temp;
+ temp = high;
+ high = cond_high;
+ cond_high = temp;
+ }
+
+ /* Now determine if there is no overlap in the ranges
+ or if the second range is a subset of the first range. */
+ no_overlap = tree_int_cst_lt (high, cond_low);
+ subset = tree_int_cst_compare (cond_high, high) != 1;
+
+ /* If there was no overlap in the ranges, then this conditional
+ always has a false value (unless we had to invert this
+ conditional, in which case it always has a true value). */
+ if (no_overlap)
+ return (cond_inverted ? boolean_true_node : boolean_false_node);
+
+ /* If the current range is a subset of the condition's range,
+ then this conditional always has a true value (unless we
+ had to invert this conditional, in which case it always
+ has a true value). */
+ if (subset && swapped)
+ return (cond_inverted ? boolean_false_node : boolean_true_node);
+
+ /* We were unable to determine the result of the conditional.
+ However, we may be able to simplify the conditional. First
+ merge the ranges in the same manner as range merging above. */
+ low = tree_int_cst_compare (low, cond_low) == 1 ? low : cond_low;
+ high = tree_int_cst_compare (high, cond_high) == -1 ? high : cond_high;
+
+ /* If the range has converged to a single point, then turn this
+ into an equality comparison. */
+ if (TREE_CODE (cond) != EQ_EXPR
+ && TREE_CODE (cond) != NE_EXPR
+ && tree_int_cst_equal (low, high))
+ {
+ TREE_SET_CODE (cond, EQ_EXPR);
+ TREE_OPERAND (cond, 1) = high;
+ }
+ }
+ }
+ return 0;
+}
+
+/* STMT is a SWITCH_EXPR for which we could not trivially determine its
+ result. This routine attempts to find equivalent forms of the
+ condition which we may be able to optimize better. */
+
+static tree
+simplify_switch_and_lookup_avail_expr (tree stmt,
+ varray_type *block_avail_exprs_p,
+ stmt_ann_t ann,
+ int insert)
+{
+ tree cond = SWITCH_COND (stmt);
+ tree def, to, ti;
+
+ /* The optimization that we really care about is removing unnecessary
+ casts. That will let us do much better in propagating the inferred
+ constant at the switch target. */
+ if (TREE_CODE (cond) == SSA_NAME)
+ {
+ def = SSA_NAME_DEF_STMT (cond);
+ if (TREE_CODE (def) == MODIFY_EXPR)
+ {
+ def = TREE_OPERAND (def, 1);
+ if (TREE_CODE (def) == NOP_EXPR)
+ {
+ def = TREE_OPERAND (def, 0);
+ to = TREE_TYPE (cond);
+ ti = TREE_TYPE (def);
+
+ /* If we have an extension that preserves sign, then we
+ can copy the source value into the switch. */
+ if (TYPE_UNSIGNED (to) == TYPE_UNSIGNED (ti)
+ && TYPE_PRECISION (to) >= TYPE_PRECISION (ti)
+ && is_gimple_val (def))
+ {
+ SWITCH_COND (stmt) = def;
+ ann->modified = 1;
+
+ return lookup_avail_expr (stmt, block_avail_exprs_p, insert);
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* Propagate known constants/copies into PHI nodes of BB's successor
+ blocks. */
+
+static void
+cprop_into_phis (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
+ basic_block bb)
+{
+ cprop_into_successor_phis (bb, const_and_copies);
+}
+
+/* Search for redundant computations in STMT. If any are found, then
+ replace them with the variable holding the result of the computation.
+
+ If safe, record this expression into the available expression hash
+ table. */
+
+static bool
+eliminate_redundant_computations (struct dom_walk_data *walk_data,
+ tree stmt, stmt_ann_t ann)
+{
+ vdef_optype vdefs = VDEF_OPS (ann);
+ tree *expr_p, def = NULL_TREE;
+ bool insert = true;
+ tree cached_lhs;
+ bool retval = false;
+ struct dom_walk_block_data *bd
+ = VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
+
+ if (TREE_CODE (stmt) == MODIFY_EXPR)
+ def = TREE_OPERAND (stmt, 0);
+
+ /* Certain expressions on the RHS can be optimized away, but can not
+ themselves be entered into the hash tables. */
+ if (ann->makes_aliased_stores
+ || ! def
+ || TREE_CODE (def) != SSA_NAME
+ || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def)
+ || NUM_VDEFS (vdefs) != 0)
+ insert = false;
+
+ /* Check if the expression has been computed before. */
+ cached_lhs = lookup_avail_expr (stmt, &bd->avail_exprs, insert);
+
+ /* If this is an assignment and the RHS was not in the hash table,
+ then try to simplify the RHS and lookup the new RHS in the
+ hash table. */
+ if (! cached_lhs && TREE_CODE (stmt) == MODIFY_EXPR)
+ cached_lhs = simplify_rhs_and_lookup_avail_expr (walk_data,
+ stmt,
+ ann,
+ insert);
+ /* Similarly if this is a COND_EXPR and we did not find its
+ expression in the hash table, simplify the condition and
+ try again. */
+ else if (! cached_lhs && TREE_CODE (stmt) == COND_EXPR)
+ cached_lhs = simplify_cond_and_lookup_avail_expr (stmt,
+ &bd->avail_exprs,
+ ann,
+ insert);
+ /* Similarly for a SWITCH_EXPR. */
+ else if (!cached_lhs && TREE_CODE (stmt) == SWITCH_EXPR)
+ cached_lhs = simplify_switch_and_lookup_avail_expr (stmt,
+ &bd->avail_exprs,
+ ann,
+ insert);
+
+ opt_stats.num_exprs_considered++;
+
+ /* Get a pointer to the expression we are trying to optimize. */
+ if (TREE_CODE (stmt) == COND_EXPR)
+ expr_p = &COND_EXPR_COND (stmt);
+ else if (TREE_CODE (stmt) == SWITCH_EXPR)
+ expr_p = &SWITCH_COND (stmt);
+ else if (TREE_CODE (stmt) == RETURN_EXPR && TREE_OPERAND (stmt, 0))
+ expr_p = &TREE_OPERAND (TREE_OPERAND (stmt, 0), 1);
+ else
+ expr_p = &TREE_OPERAND (stmt, 1);
+
+ /* It is safe to ignore types here since we have already done
+ type checking in the hashing and equality routines. In fact
+ type checking here merely gets in the way of constant
+ propagation. Also, make sure that it is safe to propagate
+ CACHED_LHS into *EXPR_P. */
+ if (cached_lhs
+ && (TREE_CODE (cached_lhs) != SSA_NAME
+ || may_propagate_copy (cached_lhs, *expr_p)))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, " Replaced redundant expr '");
+ print_generic_expr (dump_file, *expr_p, dump_flags);
+ fprintf (dump_file, "' with '");
+ print_generic_expr (dump_file, cached_lhs, dump_flags);
+ fprintf (dump_file, "'\n");
+ }
+
+ opt_stats.num_re++;
+
+#if defined ENABLE_CHECKING
+ if (TREE_CODE (cached_lhs) != SSA_NAME
+ && !is_gimple_min_invariant (cached_lhs))
+ abort ();
+#endif
+
+ if (TREE_CODE (cached_lhs) == ADDR_EXPR
+ || (POINTER_TYPE_P (TREE_TYPE (*expr_p))
+ && is_gimple_min_invariant (cached_lhs)))
+ retval = true;
+
+ propagate_value (expr_p, cached_lhs);
+ ann->modified = 1;
+ }
+ return retval;
+}
+
+/* STMT, a MODIFY_EXPR, may create certain equivalences, in either
+ the available expressions table or the const_and_copies table.
+ Detect and record those equivalences. */
+
+static void
+record_equivalences_from_stmt (tree stmt,
+ varray_type *block_avail_exprs_p,
+ varray_type *block_nonzero_vars_p,
+ int may_optimize_p,
+ stmt_ann_t ann)
+{
+ tree lhs = TREE_OPERAND (stmt, 0);
+ enum tree_code lhs_code = TREE_CODE (lhs);
+ int i;
+
+ if (lhs_code == SSA_NAME)
+ {
+ tree rhs = TREE_OPERAND (stmt, 1);
+
+ /* Strip away any useless type conversions. */
+ STRIP_USELESS_TYPE_CONVERSION (rhs);
+
+ /* If the RHS of the assignment is a constant or another variable that
+ may be propagated, register it in the CONST_AND_COPIES table. We
+ do not need to record unwind data for this, since this is a true
+ assignment and not an equivalence infered from a comparison. All
+ uses of this ssa name are dominated by this assignment, so unwinding
+ just costs time and space. */
+ if (may_optimize_p
+ && (TREE_CODE (rhs) == SSA_NAME
+ || is_gimple_min_invariant (rhs)))
+ set_value_for (lhs, rhs, const_and_copies);
+
+ /* alloca never returns zero and the address of a non-weak symbol
+ is never zero. NOP_EXPRs and CONVERT_EXPRs can be completely
+ stripped as they do not affect this equivalence. */
+ while (TREE_CODE (rhs) == NOP_EXPR
+ || TREE_CODE (rhs) == CONVERT_EXPR)
+ rhs = TREE_OPERAND (rhs, 0);
+
+ if (alloca_call_p (rhs)
+ || (TREE_CODE (rhs) == ADDR_EXPR
+ && DECL_P (TREE_OPERAND (rhs, 0))
+ && ! DECL_WEAK (TREE_OPERAND (rhs, 0))))
+ record_var_is_nonzero (lhs, block_nonzero_vars_p);
+
+ /* IOR of any value with a nonzero value will result in a nonzero
+ value. Even if we do not know the exact result recording that
+ the result is nonzero is worth the effort. */
+ if (TREE_CODE (rhs) == BIT_IOR_EXPR
+ && integer_nonzerop (TREE_OPERAND (rhs, 1)))
+ record_var_is_nonzero (lhs, block_nonzero_vars_p);
+ }
+
+ /* Look at both sides for pointer dereferences. If we find one, then
+ the pointer must be nonnull and we can enter that equivalence into
+ the hash tables. */
+ for (i = 0; i < 2; i++)
+ {
+ tree t = TREE_OPERAND (stmt, i);
+
+ /* Strip away any COMPONENT_REFs. */
+ while (TREE_CODE (t) == COMPONENT_REF)
+ t = TREE_OPERAND (t, 0);
+
+ /* Now see if this is a pointer dereference. */
+ if (TREE_CODE (t) == INDIRECT_REF)
+ {
+ tree op = TREE_OPERAND (t, 0);
+
+ /* If the pointer is a SSA variable, then enter new
+ equivalences into the hash table. */
+ if (TREE_CODE (op) == SSA_NAME)
+ record_var_is_nonzero (op, block_nonzero_vars_p);
+ }
+ }
+
+ /* A memory store, even an aliased store, creates a useful
+ equivalence. By exchanging the LHS and RHS, creating suitable
+ vops and recording the result in the available expression table,
+ we may be able to expose more redundant loads. */
+ if (!ann->has_volatile_ops
+ && (TREE_CODE (TREE_OPERAND (stmt, 1)) == SSA_NAME
+ || is_gimple_min_invariant (TREE_OPERAND (stmt, 1)))
+ && !is_gimple_reg (lhs))
+ {
+ tree rhs = TREE_OPERAND (stmt, 1);
+ tree new;
+ size_t j;
+
+ /* FIXME: If the LHS of the assignment is a bitfield and the RHS
+ is a constant, we need to adjust the constant to fit into the
+ type of the LHS. If the LHS is a bitfield and the RHS is not
+ a constant, then we can not record any equivalences for this
+ statement since we would need to represent the widening or
+ narrowing of RHS. This fixes gcc.c-torture/execute/921016-1.c
+ and should not be necessary if GCC represented bitfields
+ properly. */
+ if (lhs_code == COMPONENT_REF
+ && DECL_BIT_FIELD (TREE_OPERAND (lhs, 1)))
+ {
+ if (TREE_CONSTANT (rhs))
+ rhs = widen_bitfield (rhs, TREE_OPERAND (lhs, 1), lhs);
+ else
+ rhs = NULL;
+
+ /* If the value overflowed, then we can not use this equivalence. */
+ if (rhs && ! is_gimple_min_invariant (rhs))
+ rhs = NULL;
+ }
+
+ if (rhs)
+ {
+ vdef_optype vdefs = VDEF_OPS (ann);
+
+ /* Build a new statement with the RHS and LHS exchanged. */
+ new = build (MODIFY_EXPR, TREE_TYPE (stmt), rhs, lhs);
+
+ /* Get an annotation and set up the real operands. */
+ get_stmt_ann (new);
+ get_stmt_operands (new);
+
+ /* Clear out the virtual operands on the new statement, we are
+ going to set them explicitly below. */
+ remove_vuses (new);
+ remove_vdefs (new);
+
+ start_ssa_stmt_operands (new);
+ /* For each VDEF on the original statement, we want to create a
+ VUSE of the VDEF result on the new statement. */
+ for (j = 0; j < NUM_VDEFS (vdefs); j++)
+ {
+ tree op = VDEF_RESULT (vdefs, j);
+ add_vuse (op, new);
+ }
+
+ finalize_ssa_stmt_operands (new);
+
+ /* Finally enter the statement into the available expression
+ table. */
+ lookup_avail_expr (new, block_avail_exprs_p, true);
+ }
+ }
+}
+
+/* Optimize the statement pointed by iterator SI.
+
+ We try to perform some simplistic global redundancy elimination and
+ constant propagation:
+
+ 1- To detect global redundancy, we keep track of expressions that have
+ been computed in this block and its dominators. If we find that the
+ same expression is computed more than once, we eliminate repeated
+ computations by using the target of the first one.
+
+ 2- Constant values and copy assignments. This is used to do very
+ simplistic constant and copy propagation. When a constant or copy
+ assignment is found, we map the value on the RHS of the assignment to
+ the variable in the LHS in the CONST_AND_COPIES table. */
+
+static void
+optimize_stmt (struct dom_walk_data *walk_data,
+ basic_block bb ATTRIBUTE_UNUSED,
+ block_stmt_iterator si)
+{
+ stmt_ann_t ann;
+ tree stmt;
+ vdef_optype vdefs;
+ bool may_optimize_p;
+ bool may_have_exposed_new_symbols = false;
+ struct dom_walk_block_data *bd
+ = VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
+
+ stmt = bsi_stmt (si);
+
+ get_stmt_operands (stmt);
+ ann = stmt_ann (stmt);
+ vdefs = VDEF_OPS (ann);
+ opt_stats.num_stmts++;
+ may_have_exposed_new_symbols = false;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Optimizing statement ");
+ print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ }
+
+ /* Const/copy propagate into USES, VUSES and the RHS of VDEFs. */
+ may_have_exposed_new_symbols = cprop_into_stmt (stmt, const_and_copies);
+
+ /* If the statement has been modified with constant replacements,
+ fold its RHS before checking for redundant computations. */
+ if (ann->modified)
+ {
+ /* Try to fold the statement making sure that STMT is kept
+ up to date. */
+ if (fold_stmt (bsi_stmt_ptr (si)))
+ {
+ stmt = bsi_stmt (si);
+ ann = stmt_ann (stmt);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, " Folded to: ");
+ print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ }
+ }
+
+ /* Constant/copy propagation above may change the set of
+ virtual operands associated with this statement. Folding
+ may remove the need for some virtual operands.
+
+ Indicate we will need to rescan and rewrite the statement. */
+ may_have_exposed_new_symbols = true;
+ }
+
+ /* Check for redundant computations. Do this optimization only
+ for assignments that have no volatile ops and conditionals. */
+ may_optimize_p = (!ann->has_volatile_ops
+ && ((TREE_CODE (stmt) == RETURN_EXPR
+ && TREE_OPERAND (stmt, 0)
+ && TREE_CODE (TREE_OPERAND (stmt, 0)) == MODIFY_EXPR
+ && ! (TREE_SIDE_EFFECTS
+ (TREE_OPERAND (TREE_OPERAND (stmt, 0), 1))))
+ || (TREE_CODE (stmt) == MODIFY_EXPR
+ && ! TREE_SIDE_EFFECTS (TREE_OPERAND (stmt, 1)))
+ || TREE_CODE (stmt) == COND_EXPR
+ || TREE_CODE (stmt) == SWITCH_EXPR));
+
+ if (may_optimize_p)
+ may_have_exposed_new_symbols
+ |= eliminate_redundant_computations (walk_data, stmt, ann);
+
+ /* Record any additional equivalences created by this statement. */
+ if (TREE_CODE (stmt) == MODIFY_EXPR)
+ record_equivalences_from_stmt (stmt,
+ &bd->avail_exprs,
+ &bd->nonzero_vars,
+ may_optimize_p,
+ ann);
+
+ register_definitions_for_stmt (ann, &bd->block_defs);
+
+ /* If STMT is a COND_EXPR and it was modified, then we may know
+ where it goes. If that is the case, then mark the CFG as altered.
+
+ This will cause us to later call remove_unreachable_blocks and
+ cleanup_tree_cfg when it is safe to do so. It is not safe to
+ clean things up here since removal of edges and such can trigger
+ the removal of PHI nodes, which in turn can release SSA_NAMEs to
+ the manager.
+
+ That's all fine and good, except that once SSA_NAMEs are released
+ to the manager, we must not call create_ssa_name until all references
+ to released SSA_NAMEs have been eliminated.
+
+ All references to the deleted SSA_NAMEs can not be eliminated until
+ we remove unreachable blocks.
+
+ We can not remove unreachable blocks until after we have completed
+ any queued jump threading.
+
+ We can not complete any queued jump threads until we have taken
+ appropriate variables out of SSA form. Taking variables out of
+ SSA form can call create_ssa_name and thus we lose.
+
+ Ultimately I suspect we're going to need to change the interface
+ into the SSA_NAME manager. */
+
+ if (ann->modified)
+ {
+ tree val = NULL;
+
+ if (TREE_CODE (stmt) == COND_EXPR)
+ val = COND_EXPR_COND (stmt);
+ else if (TREE_CODE (stmt) == SWITCH_EXPR)
+ val = SWITCH_COND (stmt);
+
+ if (val && TREE_CODE (val) == INTEGER_CST
+ && find_taken_edge (bb_for_stmt (stmt), val))
+ cfg_altered = true;
+ }
+
+ if (may_have_exposed_new_symbols)
+ {
+ if (! bd->stmts_to_rescan)
+ VARRAY_TREE_INIT (bd->stmts_to_rescan, 20, "stmts_to_rescan");
+ VARRAY_PUSH_TREE (bd->stmts_to_rescan, bsi_stmt (si));
+ }
+}
+
+/* Replace the RHS of STMT with NEW_RHS. If RHS can be found in the
+ available expression hashtable, then return the LHS from the hash
+ table.
+
+ If INSERT is true, then we also update the available expression
+ hash table to account for the changes made to STMT. */
+
+static tree
+update_rhs_and_lookup_avail_expr (tree stmt, tree new_rhs,
+ varray_type *block_avail_exprs_p,
+ stmt_ann_t ann,
+ bool insert)
+{
+ tree cached_lhs = NULL;
+
+ /* Remove the old entry from the hash table. */
+ if (insert)
+ {
+ struct expr_hash_elt element;
+
+ initialize_hash_element (stmt, NULL, &element);
+ htab_remove_elt_with_hash (avail_exprs, &element, element.hash);
+ }
+
+ /* Now update the RHS of the assignment. */
+ TREE_OPERAND (stmt, 1) = new_rhs;
+
+ /* Now lookup the updated statement in the hash table. */
+ cached_lhs = lookup_avail_expr (stmt, block_avail_exprs_p, insert);
+
+ /* We have now called lookup_avail_expr twice with two different
+ versions of this same statement, once in optimize_stmt, once here.
+
+ We know the call in optimize_stmt did not find an existing entry
+ in the hash table, so a new entry was created. At the same time
+ this statement was pushed onto the BLOCK_AVAIL_EXPRS varray.
+
+ If this call failed to find an existing entry on the hash table,
+ then the new version of this statement was entered into the
+ hash table. And this statement was pushed onto BLOCK_AVAIL_EXPR
+ for the second time. So there are two copies on BLOCK_AVAIL_EXPRs
+
+ If this call succeeded, we still have one copy of this statement
+ on the BLOCK_AVAIL_EXPRs varray.
+
+ For both cases, we need to pop the most recent entry off the
+ BLOCK_AVAIL_EXPRs varray. For the case where we never found this
+ statement in the hash tables, that will leave precisely one
+ copy of this statement on BLOCK_AVAIL_EXPRs. For the case where
+ we found a copy of this statement in the second hash table lookup
+ we want _no_ copies of this statement in BLOCK_AVAIL_EXPRs. */
+ if (insert)
+ VARRAY_POP (*block_avail_exprs_p);
+
+ /* And make sure we record the fact that we modified this
+ statement. */
+ ann->modified = 1;
+
+ return cached_lhs;
+}
+
+/* Search for an existing instance of STMT in the AVAIL_EXPRS table. If
+ found, return its LHS. Otherwise insert STMT in the table and return
+ NULL_TREE.
+
+ Also, when an expression is first inserted in the AVAIL_EXPRS table, it
+ is also added to the stack pointed by BLOCK_AVAIL_EXPRS_P, so that they
+ can be removed when we finish processing this block and its children.
+
+ NOTE: This function assumes that STMT is a MODIFY_EXPR node that
+ contains no CALL_EXPR on its RHS and makes no volatile nor
+ aliased references. */
+
+static tree
+lookup_avail_expr (tree stmt, varray_type *block_avail_exprs_p, bool insert)
+{
+ void **slot;
+ tree lhs;
+ tree temp;
+ struct expr_hash_elt *element = xcalloc (sizeof (struct expr_hash_elt), 1);
+
+ lhs = TREE_CODE (stmt) == MODIFY_EXPR ? TREE_OPERAND (stmt, 0) : NULL;
+
+ initialize_hash_element (stmt, lhs, element);
+
+ /* Don't bother remembering constant assignments and copy operations.
+ Constants and copy operations are handled by the constant/copy propagator
+ in optimize_stmt. */
+ if (TREE_CODE (element->rhs) == SSA_NAME
+ || is_gimple_min_invariant (element->rhs))
+ {
+ free (element);
+ return NULL_TREE;
+ }
+
+ /* If this is an equality test against zero, see if we have recorded a
+ nonzero value for the variable in question. */
+ if ((TREE_CODE (element->rhs) == EQ_EXPR
+ || TREE_CODE (element->rhs) == NE_EXPR)
+ && TREE_CODE (TREE_OPERAND (element->rhs, 0)) == SSA_NAME
+ && integer_zerop (TREE_OPERAND (element->rhs, 1)))
+ {
+ int indx = SSA_NAME_VERSION (TREE_OPERAND (element->rhs, 0));
+
+ if (bitmap_bit_p (nonzero_vars, indx))
+ {
+ tree t = element->rhs;
+ free (element);
+
+ if (TREE_CODE (t) == EQ_EXPR)
+ return boolean_false_node;
+ else
+ return boolean_true_node;
+ }
+ }
+
+ /* Finally try to find the expression in the main expression hash table. */
+ slot = htab_find_slot_with_hash (avail_exprs, element, element->hash,
+ (insert ? INSERT : NO_INSERT));
+ if (slot == NULL)
+ {
+ free (element);
+ return NULL_TREE;
+ }
+
+ if (*slot == NULL)
+ {
+ *slot = (void *) element;
+ if (! *block_avail_exprs_p)
+ VARRAY_TREE_INIT (*block_avail_exprs_p, 20, "block_avail_exprs");
+ VARRAY_PUSH_TREE (*block_avail_exprs_p, stmt ? stmt : element->rhs);
+ return NULL_TREE;
+ }
+
+ /* Extract the LHS of the assignment so that it can be used as the current
+ definition of another variable. */
+ lhs = ((struct expr_hash_elt *)*slot)->lhs;
+
+ /* See if the LHS appears in the CONST_AND_COPIES table. If it does, then
+ use the value from the const_and_copies table. */
+ if (TREE_CODE (lhs) == SSA_NAME)
+ {
+ temp = get_value_for (lhs, const_and_copies);
+ if (temp)
+ lhs = temp;
+ }
+
+ free (element);
+ return lhs;
+}
+
+/* Given a condition COND, record into HI_P, LO_P and INVERTED_P the
+ range of values that result in the conditional having a true value.
+
+ Return true if we are successful in extracting a range from COND and
+ false if we are unsuccessful. */
+
+static bool
+extract_range_from_cond (tree cond, tree *hi_p, tree *lo_p, int *inverted_p)
+{
+ tree op1 = TREE_OPERAND (cond, 1);
+ tree high, low, type;
+ int inverted;
+
+ /* Experiments have shown that it's rarely, if ever useful to
+ record ranges for enumerations. Presumably this is due to
+ the fact that they're rarely used directly. They are typically
+ cast into an integer type and used that way. */
+ if (TREE_CODE (TREE_TYPE (op1)) != INTEGER_TYPE)
+ return 0;
+
+ type = TREE_TYPE (op1);
+
+ switch (TREE_CODE (cond))
+ {
+ case EQ_EXPR:
+ high = low = op1;
+ inverted = 0;
+ break;
+
+ case NE_EXPR:
+ high = low = op1;
+ inverted = 1;
+ break;
+
+ case GE_EXPR:
+ low = op1;
+ high = TYPE_MAX_VALUE (type);
+ inverted = 0;
+ break;
+
+ case GT_EXPR:
+ low = int_const_binop (PLUS_EXPR, op1, integer_one_node, 1);
+ high = TYPE_MAX_VALUE (type);
+ inverted = 0;
+ break;
+
+ case LE_EXPR:
+ high = op1;
+ low = TYPE_MIN_VALUE (type);
+ inverted = 0;
+ break;
+
+ case LT_EXPR:
+ high = int_const_binop (MINUS_EXPR, op1, integer_one_node, 1);
+ low = TYPE_MIN_VALUE (type);
+ inverted = 0;
+ break;
+
+ default:
+ return 0;
+ }
+
+ *hi_p = high;
+ *lo_p = low;
+ *inverted_p = inverted;
+ return 1;
+}
+
+/* Record a range created by COND for basic block BB. */
+
+static void
+record_range (tree cond, basic_block bb, varray_type *vrp_variables_p)
+{
+ /* We explicitly ignore NE_EXPRs. They rarely allow for meaningful
+ range optimizations and significantly complicate the implementation. */
+ if (TREE_CODE_CLASS (TREE_CODE (cond)) == '<'
+ && TREE_CODE (cond) != NE_EXPR
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (cond, 1))) == INTEGER_TYPE)
+ {
+ struct vrp_element *element = ggc_alloc (sizeof (struct vrp_element));
+ int ssa_version = SSA_NAME_VERSION (TREE_OPERAND (cond, 0));
+
+ varray_type *vrp_records_p
+ = (varray_type *)&VARRAY_GENERIC_PTR (vrp_data, ssa_version);
+
+ element->low = NULL;
+ element->high = NULL;
+ element->cond = cond;
+ element->bb = bb;
+
+ if (*vrp_records_p == NULL)
+ {
+ VARRAY_GENERIC_PTR_INIT (*vrp_records_p, 2, "vrp records");
+ VARRAY_GENERIC_PTR (vrp_data, ssa_version) = *vrp_records_p;
+ }
+
+ VARRAY_PUSH_GENERIC_PTR (*vrp_records_p, element);
+ if (! *vrp_variables_p)
+ VARRAY_TREE_INIT (*vrp_variables_p, 2, "vrp_variables");
+ VARRAY_PUSH_TREE (*vrp_variables_p, TREE_OPERAND (cond, 0));
+ }
+}
+
+/* Given a conditional statement IF_STMT, return the assignment 'X = Y'
+ known to be true depending on which arm of IF_STMT is taken.
+
+ Not all conditional statements will result in a useful assignment.
+ Return NULL_TREE in that case.
+
+ Also enter into the available expression table statements of
+ the form:
+
+ TRUE ARM FALSE ARM
+ 1 = cond 1 = cond'
+ 0 = cond' 0 = cond
+
+ This allows us to lookup the condition in a dominated block and
+ get back a constant indicating if the condition is true. */
+
+static struct eq_expr_value
+get_eq_expr_value (tree if_stmt,
+ int true_arm,
+ varray_type *block_avail_exprs_p,
+ basic_block bb,
+ varray_type *vrp_variables_p)
+{
+ tree cond;
+ struct eq_expr_value retval;
+
+ cond = COND_EXPR_COND (if_stmt);
+ retval.src = NULL;
+ retval.dst = NULL;
+
+ /* If the conditional is a single variable 'X', return 'X = 1' for
+ the true arm and 'X = 0' on the false arm. */
+ if (TREE_CODE (cond) == SSA_NAME)
+ {
+ retval.dst = cond;
+ retval.src = (true_arm ? integer_one_node : integer_zero_node);
+ return retval;
+ }
+
+ /* If we have a comparison expression, then record its result into
+ the available expression table. */
+ if (TREE_CODE_CLASS (TREE_CODE (cond)) == '<')
+ {
+ tree op0 = TREE_OPERAND (cond, 0);
+ tree op1 = TREE_OPERAND (cond, 1);
+
+ /* Special case comparing booleans against a constant as we know
+ the value of OP0 on both arms of the branch. ie, we can record
+ an equivalence for OP0 rather than COND. */
+ if ((TREE_CODE (cond) == EQ_EXPR || TREE_CODE (cond) == NE_EXPR)
+ && TREE_CODE (op0) == SSA_NAME
+ && TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
+ && is_gimple_min_invariant (op1))
+ {
+ if ((TREE_CODE (cond) == EQ_EXPR && true_arm)
+ || (TREE_CODE (cond) == NE_EXPR && ! true_arm))
+ {
+ retval.src = op1;
+ }
+ else
+ {
+ if (integer_zerop (op1))
+ retval.src = boolean_true_node;
+ else
+ retval.src = boolean_false_node;
+ }
+ retval.dst = op0;
+ return retval;
+ }
+
+ if (TREE_CODE (op0) == SSA_NAME
+ && (is_gimple_min_invariant (op1) || TREE_CODE (op1) == SSA_NAME))
+ {
+ tree inverted = invert_truthvalue (cond);
+
+ /* When we find an available expression in the hash table, we replace
+ the expression with the LHS of the statement in the hash table.
+
+ So, we want to build statements such as "1 = <condition>" on the
+ true arm and "0 = <condition>" on the false arm. That way if we
+ find the expression in the table, we will replace it with its
+ known constant value. Also insert inversions of the result and
+ condition into the hash table. */
+ if (true_arm)
+ {
+ record_cond (cond, boolean_true_node, block_avail_exprs_p);
+ record_cond (inverted, boolean_false_node, block_avail_exprs_p);
+
+ if (TREE_CONSTANT (op1))
+ record_range (cond, bb, vrp_variables_p);
+
+ /* If the conditional is of the form 'X == Y', return 'X = Y'
+ for the true arm. */
+ if (TREE_CODE (cond) == EQ_EXPR)
+ {
+ retval.dst = op0;
+ retval.src = op1;
+ return retval;
+ }
+ }
+ else
+ {
+
+ record_cond (inverted, boolean_true_node, block_avail_exprs_p);
+ record_cond (cond, boolean_false_node, block_avail_exprs_p);
+
+ if (TREE_CONSTANT (op1))
+ record_range (inverted, bb, vrp_variables_p);
+
+ /* If the conditional is of the form 'X != Y', return 'X = Y'
+ for the false arm. */
+ if (TREE_CODE (cond) == NE_EXPR)
+ {
+ retval.dst = op0;
+ retval.src = op1;
+ return retval;
+ }
+ }
+ }
+ }
+
+ return retval;
+}
+
+/* Hashing and equality functions for AVAIL_EXPRS. The table stores
+ MODIFY_EXPR statements. We compute a value number for expressions using
+ the code of the expression and the SSA numbers of its operands. */
+
+static hashval_t
+avail_expr_hash (const void *p)
+{
+ stmt_ann_t ann = ((struct expr_hash_elt *)p)->ann;
+ tree rhs = ((struct expr_hash_elt *)p)->rhs;
+ hashval_t val = 0;
+ size_t i;
+ vuse_optype vuses;
+
+ /* iterative_hash_expr knows how to deal with any expression and
+ deals with commutative operators as well, so just use it instead
+ of duplicating such complexities here. */
+ val = iterative_hash_expr (rhs, val);
+
+ /* If the hash table entry is not associated with a statement, then we
+ can just hash the expression and not worry about virtual operands
+ and such. */
+ if (!ann)
+ return val;
+
+ /* Add the SSA version numbers of every vuse operand. This is important
+ because compound variables like arrays are not renamed in the
+ operands. Rather, the rename is done on the virtual variable
+ representing all the elements of the array. */
+ vuses = VUSE_OPS (ann);
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ val = iterative_hash_expr (VUSE_OP (vuses, i), val);
+
+ return val;
+}
+
+
+static int
+avail_expr_eq (const void *p1, const void *p2)
+{
+ stmt_ann_t ann1 = ((struct expr_hash_elt *)p1)->ann;
+ tree rhs1 = ((struct expr_hash_elt *)p1)->rhs;
+ stmt_ann_t ann2 = ((struct expr_hash_elt *)p2)->ann;
+ tree rhs2 = ((struct expr_hash_elt *)p2)->rhs;
+
+ /* If they are the same physical expression, return true. */
+ if (rhs1 == rhs2 && ann1 == ann2)
+ return true;
+
+ /* If their codes are not equal, then quit now. */
+ if (TREE_CODE (rhs1) != TREE_CODE (rhs2))
+ return false;
+
+ /* In case of a collision, both RHS have to be identical and have the
+ same VUSE operands. */
+ if ((TREE_TYPE (rhs1) == TREE_TYPE (rhs2)
+ || lang_hooks.types_compatible_p (TREE_TYPE (rhs1), TREE_TYPE (rhs2)))
+ && operand_equal_p (rhs1, rhs2, OEP_PURE_SAME))
+ {
+ vuse_optype ops1 = NULL;
+ vuse_optype ops2 = NULL;
+ size_t num_ops1 = 0;
+ size_t num_ops2 = 0;
+ size_t i;
+
+ if (ann1)
+ {
+ ops1 = VUSE_OPS (ann1);
+ num_ops1 = NUM_VUSES (ops1);
+ }
+
+ if (ann2)
+ {
+ ops2 = VUSE_OPS (ann2);
+ num_ops2 = NUM_VUSES (ops2);
+ }
+
+ /* If the number of virtual uses is different, then we consider
+ them not equal. */
+ if (num_ops1 != num_ops2)
+ return false;
+
+ for (i = 0; i < num_ops1; i++)
+ if (VUSE_OP (ops1, i) != VUSE_OP (ops2, i))
+ return false;
+
+#ifdef ENABLE_CHECKING
+ if (((struct expr_hash_elt *)p1)->hash
+ != ((struct expr_hash_elt *)p2)->hash)
+ abort ();
+#endif
+ return true;
+ }
+
+ return false;
+}
+
+/* Given STMT and a pointer to the block local defintions BLOCK_DEFS_P,
+ register register all objects set by this statement into BLOCK_DEFS_P
+ and CURRDEFS. */
+
+static void
+register_definitions_for_stmt (stmt_ann_t ann, varray_type *block_defs_p)
+{
+ def_optype defs;
+ vdef_optype vdefs;
+ unsigned int i;
+
+ defs = DEF_OPS (ann);
+ for (i = 0; i < NUM_DEFS (defs); i++)
+ {
+ tree def = DEF_OP (defs, i);
+
+ /* FIXME: We shouldn't be registering new defs if the variable
+ doesn't need to be renamed. */
+ register_new_def (def, block_defs_p);
+ }
+
+ /* Register new virtual definitions made by the statement. */
+ vdefs = VDEF_OPS (ann);
+ for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ {
+ /* FIXME: We shouldn't be registering new defs if the variable
+ doesn't need to be renamed. */
+ register_new_def (VDEF_RESULT (vdefs, i), block_defs_p);
+ }
+}
+
diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
new file mode 100644
index 00000000000..fca08ac6519
--- /dev/null
+++ b/gcc/tree-ssa-dse.c
@@ -0,0 +1,445 @@
+/* Dead store elimination
+ Copyright (C) 2004 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 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "errors.h"
+#include "ggc.h"
+#include "tree.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "basic-block.h"
+#include "timevar.h"
+#include "diagnostic.h"
+#include "tree-flow.h"
+#include "tree-pass.h"
+#include "tree-dump.h"
+#include "domwalk.h"
+#include "flags.h"
+
+/* This file implements dead store elimination.
+
+ A dead store is a store into a memory location which will later be
+ overwritten by another store without any intervening loads. In this
+ case the earlier store can be deleted.
+
+ In our SSA + virtual operand world we use immediate uses of virtual
+ operands to detect dead stores. If a store's virtual definition
+ is used precisely once by a later store to the same location which
+ post dominates the first store, then the first store is dead.
+
+ The single use of the store's virtual definition ensures that
+ there are no intervening aliased loads and the requirement that
+ the second load post dominate the first ensures that if the earlier
+ store executes, then the later stores will execute before the function
+ exits.
+
+ It may help to think of this as first moving the earlier store to
+ the point immediately before the later store. Again, the single
+ use of the virtual defintion and the post-dominance relationship
+ ensure that such movement would be safe. Clearly if there are
+ back to back stores, then the second is redundant.
+
+ Reviewing section 10.7.2 in Morgan's "Building an Optimizing Compiler"
+ may also help in understanding this code since it discusses the
+ relationship between dead store and redundant load elimination. In
+ fact, they are the same transformation applied to different views of
+ the CFG. */
+
+
+struct dse_global_data
+{
+ /* This is the global bitmap for store statements.
+
+ Each statement has a unique ID. When we encounter a store statement
+ that we want to record, set the bit corresponding to the statement's
+ unique ID in this bitmap. */
+ bitmap stores;
+};
+
+/* We allocate a bitmap-per-block for stores which are encountered
+ during the scan of that block. This allows us to restore the
+ global bitmap of stores when we finish processing a block. */
+struct dse_block_local_data
+{
+ bitmap stores;
+};
+
+static bool gate_dse (void);
+static void tree_ssa_dse (void);
+static void dse_initialize_block_local_data (struct dom_walk_data *,
+ basic_block,
+ bool);
+static void dse_optimize_stmt (struct dom_walk_data *,
+ basic_block,
+ block_stmt_iterator);
+static void dse_record_phis (struct dom_walk_data *, basic_block);
+static void dse_finalize_block (struct dom_walk_data *, basic_block);
+static void fix_phi_uses (tree, tree);
+static void fix_stmt_vdefs (tree, tree);
+static void record_voperand_set (bitmap, bitmap *, unsigned int);
+
+/* Function indicating whether we ought to include information for 'var'
+ when calculating immediate uses. For this pass we only want use
+ information for virtual variables. */
+
+static bool
+need_imm_uses_for (tree var)
+{
+ return !is_gimple_reg (var);
+}
+
+
+/* Replace uses in PHI which match VDEF_RESULTs in STMT with the
+ corresponding VDEF_OP in STMT. */
+
+static void
+fix_phi_uses (tree phi, tree stmt)
+{
+ stmt_ann_t ann = stmt_ann (stmt);
+ vdef_optype vdefs;
+ unsigned int i;
+ int j;
+
+ get_stmt_operands (stmt);
+ vdefs = VDEF_OPS (ann);
+
+ /* Walk each VDEF in STMT. */
+ for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ {
+ tree vdef = VDEF_RESULT (vdefs, i);
+
+ /* Find any uses in the PHI which match VDEF and replace
+ them with the appropriate VDEF_OP. */
+ for (j = 0; j < PHI_NUM_ARGS (phi); j++)
+ if (vdef == PHI_ARG_DEF (phi, j))
+ PHI_ARG_DEF (phi, j) = VDEF_OP (vdefs, i);
+ }
+}
+
+/* Replace the VDEF_OPs in STMT1 which match VDEF_RESULTs in STMT2 with
+ the appropriate VDEF_OPs from STMT2. */
+
+static void
+fix_stmt_vdefs (tree stmt1, tree stmt2)
+{
+ stmt_ann_t ann1 = stmt_ann (stmt1);
+ stmt_ann_t ann2 = stmt_ann (stmt2);
+ vdef_optype vdefs1;
+ vdef_optype vdefs2;
+ unsigned int i, j;
+
+ get_stmt_operands (stmt1);
+ get_stmt_operands (stmt2);
+ vdefs1 = VDEF_OPS (ann1);
+ vdefs2 = VDEF_OPS (ann2);
+
+ /* Walk each VDEF_OP in stmt1. */
+ for (i = 0; i < NUM_VDEFS (vdefs1); i++)
+ {
+ tree vdef1 = VDEF_OP (vdefs1, i);
+
+ /* Find the appropriate VDEF_RESULT in STMT2. */
+ for (j = 0; j < NUM_VDEFS (vdefs2); j++)
+ {
+ if (vdef1 == VDEF_RESULT (vdefs2, j))
+ {
+ /* Update. */
+ *VDEF_OP_PTR (vdefs1, i) = VDEF_OP (vdefs2, j);
+ break;
+ }
+ }
+
+#ifdef ENABLE_CHECKING
+ /* If we did not find a corresponding VDEF_RESULT, then something
+ has gone terribly wrong. */
+ if (j == NUM_VDEFS (vdefs2))
+ abort ();
+#endif
+
+ }
+}
+
+
+/* Set bit UID in bitmaps GLOBAL and *LOCAL, creating *LOCAL as needed. */
+static void
+record_voperand_set (bitmap global, bitmap *local, unsigned int uid)
+{
+ /* Lazily allocate the bitmap. Note that we do not get a notification
+ when the block local data structures die, so we allocate the local
+ bitmap backed by the GC system. */
+ if (*local == NULL)
+ *local = BITMAP_GGC_ALLOC ();
+
+ /* Set the bit in the local and global bitmaps. */
+ bitmap_set_bit (*local, uid);
+ bitmap_set_bit (global, uid);
+}
+/* Initialize block local data structures. */
+
+static void
+dse_initialize_block_local_data (struct dom_walk_data *walk_data,
+ basic_block bb ATTRIBUTE_UNUSED,
+ bool recycled)
+{
+ struct dse_block_local_data *bd
+ = VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
+
+ /* If we are given a recycled block local data structure, ensure any
+ bitmap associated with the block is cleared. */
+ if (recycled)
+ {
+ if (bd->stores)
+ bitmap_clear (bd->stores);
+ }
+}
+
+/* Attempt to eliminate dead stores in the statement referenced by BSI.
+
+ A dead store is a store into a memory location which will later be
+ overwritten by another store without any intervening loads. In this
+ case the earlier store can be deleted.
+
+ In our SSA + virtual operand world we use immediate uses of virtual
+ operands to detect dead stores. If a store's virtual definition
+ is used precisely once by a later store to the same location which
+ post dominates the first store, then the first store is dead. */
+
+static void
+dse_optimize_stmt (struct dom_walk_data *walk_data,
+ basic_block bb ATTRIBUTE_UNUSED,
+ block_stmt_iterator bsi)
+{
+ struct dse_block_local_data *bd
+ = VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
+ struct dse_global_data *dse_gd = walk_data->global_data;
+ tree stmt = bsi_stmt (bsi);
+ stmt_ann_t ann = stmt_ann (stmt);
+ vdef_optype vdefs;
+
+ get_stmt_operands (stmt);
+ vdefs = VDEF_OPS (ann);
+
+ /* If this statement has no virtual uses, then there is nothing
+ to do. */
+ if (NUM_VDEFS (vdefs) == 0)
+ return;
+
+ /* We know we have virtual definitions. If this is a MODIFY_EXPR, then
+ record it into our table. */
+ if (TREE_CODE (stmt) == MODIFY_EXPR
+ && TREE_CODE (TREE_OPERAND (stmt, 1)) != CALL_EXPR)
+ {
+ dataflow_t df = get_immediate_uses (stmt);
+ unsigned int num_uses = num_immediate_uses (df);
+ tree use;
+ tree skipped_phi;
+
+
+ /* If there are no uses then there is nothing left to do. */
+ if (num_uses == 0)
+ {
+ record_voperand_set (dse_gd->stores, &bd->stores, ann->uid);
+ return;
+ }
+
+ use = immediate_use (df, 0);
+ skipped_phi = NULL;
+
+ /* Skip through any PHI nodes we have already seen if the PHI
+ represents the only use of this store.
+
+ Note this does not handle the case where the store has
+ multiple VDEFs which all reach a set of PHI nodes in the
+ same block. */
+ while (num_uses == 1
+ && TREE_CODE (use) == PHI_NODE
+ && bitmap_bit_p (dse_gd->stores, stmt_ann (use)->uid))
+ {
+ /* Record the first PHI we skip so that we can fix its
+ uses if we find that STMT is a dead store. */
+ if (!skipped_phi)
+ skipped_phi = use;
+
+ /* Skip past this PHI and loop again in case we had a PHI
+ chain. */
+ df = get_immediate_uses (use);
+ num_uses = num_immediate_uses (df);
+ use = immediate_use (df, 0);
+ }
+
+ /* If we have precisely one immediate use at this point, then we may
+ have found redundant store. */
+ if (num_uses == 1
+ && bitmap_bit_p (dse_gd->stores, stmt_ann (use)->uid)
+ && operand_equal_p (TREE_OPERAND (stmt, 0),
+ TREE_OPERAND (use, 0), 0))
+ {
+ /* We need to fix the operands if either the first PHI we
+ skipped, or the store which we are not deleting if we did
+ not skip any PHIs. */
+ if (skipped_phi)
+ fix_phi_uses (skipped_phi, stmt);
+ else
+ fix_stmt_vdefs (use, stmt);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, " Deleted dead store '");
+ print_generic_expr (dump_file, bsi_stmt (bsi), dump_flags);
+ fprintf (dump_file, "'\n");
+ }
+
+ /* Any immediate uses which reference STMT need to instead
+ reference the new consumer, either SKIPPED_PHI or USE.
+ This allows us to cascade dead stores. */
+ redirect_immediate_uses (stmt, skipped_phi ? skipped_phi : use);
+
+ /* Finally remove the dead store. */
+ bsi_remove (&bsi);
+ }
+
+ record_voperand_set (dse_gd->stores, &bd->stores, ann->uid);
+ }
+}
+
+/* Record that we have seen the PHIs at the start of BB which correspond
+ to virtual operands. */
+static void
+dse_record_phis (struct dom_walk_data *walk_data, basic_block bb)
+{
+ struct dse_block_local_data *bd
+ = VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
+ struct dse_global_data *dse_gd = walk_data->global_data;
+ tree phi;
+
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ if (need_imm_uses_for (PHI_RESULT (phi)))
+ record_voperand_set (dse_gd->stores,
+ &bd->stores,
+ get_stmt_ann (phi)->uid);
+}
+
+static void
+dse_finalize_block (struct dom_walk_data *walk_data,
+ basic_block bb ATTRIBUTE_UNUSED)
+{
+ struct dse_block_local_data *bd
+ = VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
+ struct dse_global_data *dse_gd = walk_data->global_data;
+ bitmap stores = dse_gd->stores;
+ unsigned int i;
+
+ /* Unwind the stores noted in this basic block. */
+ if (bd->stores)
+ EXECUTE_IF_SET_IN_BITMAP (bd->stores, 0, i, bitmap_clear_bit (stores, i););
+}
+
+static void
+tree_ssa_dse (void)
+{
+ struct dom_walk_data walk_data;
+ struct dse_global_data dse_gd;
+ unsigned int uid = 0;
+ basic_block bb;
+
+ /* Create a UID for each statement in the function. Ordering of the
+ UIDs is not important for this pass. */
+ FOR_EACH_BB (bb)
+ {
+ block_stmt_iterator bsi;
+ tree phi;
+
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ stmt_ann (bsi_stmt (bsi))->uid = uid++;
+
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ stmt_ann (phi)->uid = uid++;
+ }
+
+ /* We might consider making this a property of each pass so that it
+ can be [re]computed on an as-needed basis. Particularly since
+ this pass could be seen as an extension of DCE which needs post
+ dominators. */
+ calculate_dominance_info (CDI_POST_DOMINATORS);
+
+ /* We also need immediate use information for virtual operands. */
+ compute_immediate_uses (TDFA_USE_VOPS, need_imm_uses_for);
+
+ /* Dead store elimination is fundamentally a walk of the post-dominator
+ tree and a backwards walk of statements within each block. */
+ walk_data.walk_stmts_backward = true;
+ walk_data.dom_direction = CDI_POST_DOMINATORS;
+ walk_data.initialize_block_local_data = dse_initialize_block_local_data;
+ walk_data.before_dom_children_before_stmts = NULL;
+ walk_data.before_dom_children_walk_stmts = dse_optimize_stmt;
+ walk_data.before_dom_children_after_stmts = dse_record_phis;
+ walk_data.after_dom_children_before_stmts = NULL;
+ walk_data.after_dom_children_walk_stmts = NULL;
+ walk_data.after_dom_children_after_stmts = dse_finalize_block;
+
+ walk_data.block_local_data_size = sizeof (struct dse_block_local_data);
+
+ /* This is the main hash table for the dead store elimination pass. */
+ dse_gd.stores = BITMAP_XMALLOC ();
+ walk_data.global_data = &dse_gd;
+
+ /* Initialize the dominator walker. */
+ init_walk_dominator_tree (&walk_data);
+
+ /* Recursively walk the dominator tree. */
+ walk_dominator_tree (&walk_data, EXIT_BLOCK_PTR);
+
+ /* Finalize the dominator walker. */
+ fini_walk_dominator_tree (&walk_data);
+
+ /* Release the main bitmap. */
+ BITMAP_XFREE (dse_gd.stores);
+
+ /* Free dataflow information. It's probably out of date now anyway. */
+ free_df ();
+
+ /* For now, just wipe the post-dominator information. */
+ free_dominance_info (CDI_POST_DOMINATORS);
+}
+
+static bool
+gate_dse (void)
+{
+ return flag_tree_dse != 0;
+}
+
+struct tree_opt_pass pass_dse = {
+ "dse", /* name */
+ gate_dse, /* gate */
+ tree_ssa_dse, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_DSE, /* tv_id */
+ PROP_cfg | PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */
+ | TODO_verify_ssa
+};
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
new file mode 100644
index 00000000000..d4e893c1067
--- /dev/null
+++ b/gcc/tree-ssa-forwprop.c
@@ -0,0 +1,526 @@
+/* Forward propagation of single use variables.
+ Copyright (C) 2004 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 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "errors.h"
+#include "ggc.h"
+#include "tree.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "basic-block.h"
+#include "timevar.h"
+#include "diagnostic.h"
+#include "tree-flow.h"
+#include "tree-pass.h"
+#include "tree-dump.h"
+
+/* This pass performs simple forward propagation of single use variables
+ from their definition site into their single use site.
+
+ Right now we only bother forward propagating into COND_EXPRs since those
+ are relatively common cases where forward propagation creates valid
+ gimple code without the expression needing to fold. ie
+
+ bb0:
+ x = a COND b;
+ if (x) goto ... else goto ...
+
+ Will be transformed into:
+
+ bb0:
+ if (a COND b) goto ... else goto ...
+
+ Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
+
+ Or (assuming c1 and c2 are constants):
+
+ bb0:
+ x = a + c1;
+ if (x EQ/NEQ c2) goto ... else goto ...
+
+ Will be transformed into:
+
+ bb0:
+ if (a EQ/NEQ (c2 - c1)) goto ... else goto ...
+
+ Similarly for x = a - c1.
+
+ Or
+
+ bb0:
+ x = !a
+ if (x) goto ... else goto ...
+
+ Will be transformed into:
+
+ bb0:
+ if (a == 0) goto ... else goto ...
+
+ Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
+ For these cases, we propagate A into all, possibly more than one,
+ COND_EXPRs that use X.
+
+ Or
+
+ bb0:
+ x = (typecast) a
+ if (x) goto ... else goto ...
+
+ Will be transformed into:
+
+ bb0:
+ if (a != 0) goto ... else goto ...
+
+ (Assuming a is an integral type and x is a boolean or x is an
+ integral and a is a boolean.)
+
+ Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
+ For these cases, we propagate A into all, possibly more than one,
+ COND_EXPRs that use X.
+
+ In addition to eliminating the variable and the statement which assigns
+ a value to the variable, we may be able to later thread the jump without
+ adding insane complexity in the dominator optimizer.
+
+ Also note these transformations can cascade. We handle this by having
+ a worklist of COND_EXPR statements to examine. As we make a change to
+ a statement, we put it back on the worklist to examine on the next
+ iteration of the main loop.
+
+ This will (of course) be extended as other needs arise. */
+
+/* Bitmap of variables for which we want immediate uses. This is set
+ by record_single_argument_cond_exprs and tested in need_imm_uses_for. */
+static bitmap vars;
+
+static bool need_imm_uses_for (tree);
+static void tree_ssa_forward_propagate_single_use_vars (void);
+static void record_single_argument_cond_exprs (varray_type,
+ varray_type *,
+ bitmap);
+static void substitute_single_use_vars (varray_type *, varray_type);
+
+/* Function indicating whether we ought to include information for 'var'
+ when calculating immediate uses. */
+
+static bool
+need_imm_uses_for (tree var)
+{
+ return bitmap_bit_p (vars, SSA_NAME_VERSION (var));
+}
+
+/* Find all COND_EXPRs with a condition that is a naked SSA_NAME or
+ an equality comparison against a constant.
+
+ Record the identified COND_EXPRs and the SSA_NAME used in the COND_EXPR
+ into a virtual array, which is returned to the caller. Also record
+ into VARS that we will need immediate uses for the identified SSA_NAME.
+
+ The more uninteresting COND_EXPRs and associated SSA_NAMEs we can
+ filter out here, the faster this pass will run since its runtime is
+ dominated by the time to build immediate uses. */
+
+static void
+record_single_argument_cond_exprs (varray_type cond_worklist,
+ varray_type *vars_worklist,
+ bitmap vars)
+
+{
+ /* The first pass over the blocks gathers the set of variables we need
+ immediate uses for as well as the set of interesting COND_EXPRs.
+
+ A simpler implementation may be appropriate if/when we have a lower
+ overhead means of getting immediate use information. */
+ while (VARRAY_ACTIVE_SIZE (cond_worklist) > 0)
+ {
+ tree last = VARRAY_TOP_TREE (cond_worklist);
+
+ VARRAY_POP (cond_worklist);
+
+ /* See if this block ends in a COND_EXPR. */
+ if (last && TREE_CODE (last) == COND_EXPR)
+ {
+ tree cond = COND_EXPR_COND (last);
+ enum tree_code cond_code = TREE_CODE (cond);
+
+ /* If the condition is a lone variable or an equality test of
+ an SSA_NAME against an integral constant, then we may have an
+ optimizable case.
+
+ Note these conditions also ensure the COND_EXPR has no
+ virtual operands or other side effects. */
+ if (cond_code == SSA_NAME
+ || ((cond_code == EQ_EXPR || cond_code == NE_EXPR)
+ && TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME
+ && TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (cond, 1))) == 'c'
+ && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 1)))))
+ {
+ tree def;
+ tree test_var;
+
+ /* Extract the single variable used in the test into TEST_VAR. */
+ if (cond_code == SSA_NAME)
+ test_var = cond;
+ else
+ test_var = TREE_OPERAND (cond, 0);
+
+ /* If we have already recorded this SSA_NAME as interesting,
+ do not do so again. */
+ if (bitmap_bit_p (vars, SSA_NAME_VERSION (test_var)))
+ continue;
+
+ /* Now get the defining statement for TEST_VAR and see if it
+ something we are interested in. */
+ def = SSA_NAME_DEF_STMT (test_var);
+ if (TREE_CODE (def) == MODIFY_EXPR)
+ {
+ tree def_rhs = TREE_OPERAND (def, 1);
+
+ /* If TEST_VAR is set by adding or subtracting a constant
+ from an SSA_NAME, then it is interesting to us as we
+ can adjust the constant in the conditional and thus
+ eliminate the arithmetic operation. */
+ if (TREE_CODE (def_rhs) == PLUS_EXPR
+ || TREE_CODE (def_rhs) == MINUS_EXPR)
+ {
+ tree op0 = TREE_OPERAND (def_rhs, 0);
+ tree op1 = TREE_OPERAND (def_rhs, 1);
+
+ /* The first operand must be an SSA_NAME and the second
+ operand must be a constant. */
+ if (TREE_CODE (op0) != SSA_NAME
+ || TREE_CODE_CLASS (TREE_CODE (op1)) != 'c'
+ || !INTEGRAL_TYPE_P (TREE_TYPE (op1)))
+ continue;
+ }
+
+ /* These cases require comparisons of a naked SSA_NAME or
+ comparison of an SSA_NAME against zero or one. */
+ else if (TREE_CODE (cond) == SSA_NAME
+ || integer_zerop (TREE_OPERAND (cond, 1))
+ || integer_onep (TREE_OPERAND (cond, 1)))
+ {
+ /* If TEST_VAR is set from a relational operation
+ between two SSA_NAMEs or a combination of an SSA_NAME
+ and a constant, then it is interesting. */
+ if (TREE_CODE_CLASS (TREE_CODE (def_rhs)) == '<')
+ {
+ tree op0 = TREE_OPERAND (def_rhs, 0);
+ tree op1 = TREE_OPERAND (def_rhs, 1);
+
+ /* Both operands of DEF_RHS must be SSA_NAMEs or
+ constants. */
+ if ((TREE_CODE (op0) != SSA_NAME
+ && !is_gimple_min_invariant (op0))
+ || (TREE_CODE (op1) != SSA_NAME
+ && !is_gimple_min_invariant (op1)))
+ continue;
+ }
+
+ /* If TEST_VAR is set from a TRUTH_NOT_EXPR, then it
+ is interesting. */
+ else if (TREE_CODE (def_rhs) == TRUTH_NOT_EXPR)
+ {
+ def_rhs = TREE_OPERAND (def_rhs, 0);
+
+ /* DEF_RHS must be an SSA_NAME or constant. */
+ if (TREE_CODE (def_rhs) != SSA_NAME
+ && !is_gimple_min_invariant (def_rhs))
+ continue;
+ }
+
+ /* If TEST_VAR was set from a cast of an integer type
+ to a boolean type or a cast of a boolean to an
+ integral, then it is interesting. */
+ else if (TREE_CODE (def_rhs) == NOP_EXPR
+ || TREE_CODE (def_rhs) == CONVERT_EXPR)
+ {
+ tree outer_type;
+ tree inner_type;
+
+ outer_type = TREE_TYPE (def_rhs);
+ inner_type = TREE_TYPE (TREE_OPERAND (def_rhs, 0));
+
+ if ((TREE_CODE (outer_type) == BOOLEAN_TYPE
+ && INTEGRAL_TYPE_P (inner_type))
+ || (TREE_CODE (inner_type) == BOOLEAN_TYPE
+ && INTEGRAL_TYPE_P (outer_type)))
+ ;
+ else
+ continue;
+ }
+ else
+ continue;
+ }
+ else
+ continue;
+
+ /* All the tests passed, record TEST_VAR as interesting. */
+ VARRAY_PUSH_TREE (*vars_worklist, test_var);
+ bitmap_set_bit (vars, SSA_NAME_VERSION (test_var));
+ }
+ }
+ }
+ }
+}
+
+/* Given FORWPROP_DATA containing SSA_NAMEs which are used in COND_EXPRs
+ that we may be able to optimize, attempt to rewrite the condition
+ in each COND_EXPR to use the RHS of the statement which defines the
+ SSA_NAME used in the COND_EXPR. */
+
+static void
+substitute_single_use_vars (varray_type *cond_worklist,
+ varray_type vars_worklist)
+{
+ while (VARRAY_ACTIVE_SIZE (vars_worklist) > 0)
+ {
+ tree test_var = VARRAY_TOP_TREE (vars_worklist);
+ tree def = SSA_NAME_DEF_STMT (test_var);
+ dataflow_t df;
+ int j, num_uses, propagated_uses;
+ block_stmt_iterator bsi;
+
+ VARRAY_POP (vars_worklist);
+
+ /* Now compute the immediate uses of TEST_VAR. */
+ df = get_immediate_uses (def);
+ num_uses = num_immediate_uses (df);
+ propagated_uses = 0;
+
+ /* If TEST_VAR is used more than once and is not a boolean set
+ via TRUTH_NOT_EXPR with another SSA_NAME as its argument, then
+ we can not optimize. */
+ if (num_uses == 1
+ || (TREE_CODE (TREE_TYPE (test_var)) == BOOLEAN_TYPE
+ && TREE_CODE (TREE_OPERAND (def, 1)) == TRUTH_NOT_EXPR
+ && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (def, 1), 0))
+ == SSA_NAME)))
+ ;
+ else
+ continue;
+
+ /* Walk over each use and try to forward propagate the RHS of
+ DEF into the use. */
+ for (j = 0; j < num_uses; j++)
+ {
+ tree cond_stmt;
+ tree cond;
+ enum tree_code cond_code;
+ tree def_rhs;
+ enum tree_code def_rhs_code;
+ tree new_cond;
+
+ cond_stmt = immediate_use (df, j);
+
+ /* For now we can only propagate into COND_EXPRs. */
+ if (TREE_CODE (cond_stmt) != COND_EXPR)
+ continue;
+
+ cond = COND_EXPR_COND (cond_stmt);
+ cond_code = TREE_CODE (cond);
+ def_rhs = TREE_OPERAND (def, 1);
+ def_rhs_code = TREE_CODE (def_rhs);
+
+ /* If the definition of the single use variable was from an
+ arithmetic operation, then we just need to adjust the
+ constant in the COND_EXPR_COND and update the variable tested. */
+ if (def_rhs_code == PLUS_EXPR || def_rhs_code == MINUS_EXPR)
+ {
+ tree op0 = TREE_OPERAND (def_rhs, 0);
+ tree op1 = TREE_OPERAND (def_rhs, 1);
+ enum tree_code new_code;
+ tree t;
+
+ /* If the variable was defined via X + C, then we must subtract
+ C from the constant in the conditional. Otherwise we add
+ C to the constant in the conditional. The result must fold
+ into a valid gimple operand to be optimizable. */
+ new_code = def_rhs_code == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR;
+ t = int_const_binop (new_code, TREE_OPERAND (cond, 1), op1, 0);
+ if (!is_gimple_val (t))
+ continue;
+
+ new_cond = build (cond_code, boolean_type_node, op0, t);
+ }
+ /* If the variable is defined by a conditional expression... */
+ else if (TREE_CODE_CLASS (def_rhs_code) == '<')
+ {
+ /* TEST_VAR was set from a relational operator. */
+ tree op0 = TREE_OPERAND (def_rhs, 0);
+ tree op1 = TREE_OPERAND (def_rhs, 1);
+
+ new_cond = build (def_rhs_code, boolean_type_node, op0, op1);
+
+ /* Invert the conditional if necessary. */
+ if ((cond_code == EQ_EXPR
+ && integer_zerop (TREE_OPERAND (cond, 1)))
+ || (cond_code == NE_EXPR
+ && integer_onep (TREE_OPERAND (cond, 1))))
+ {
+ new_cond = invert_truthvalue (new_cond);
+
+ /* If we did not get a simple relational expression or
+ bare SSA_NAME, then we can not optimize this case. */
+ if (TREE_CODE_CLASS (TREE_CODE (new_cond)) != '<'
+ && TREE_CODE (new_cond) != SSA_NAME)
+ continue;
+ }
+ }
+ else
+ {
+ bool invert = false;
+ enum tree_code new_code;
+
+ /* TEST_VAR was set from a TRUTH_NOT_EXPR or a NOP_EXPR. */
+ if (def_rhs_code == TRUTH_NOT_EXPR)
+ invert = true;
+
+ if (cond_code == SSA_NAME
+ || (cond_code == NE_EXPR
+ && integer_zerop (TREE_OPERAND (cond, 1)))
+ || (cond_code == EQ_EXPR
+ && integer_onep (TREE_OPERAND (cond, 1))))
+ new_code = NE_EXPR;
+ else
+ new_code = EQ_EXPR;
+
+ if (invert)
+ new_code = (new_code == EQ_EXPR ? NE_EXPR : EQ_EXPR);
+
+ new_cond = build (new_code,
+ boolean_type_node,
+ TREE_OPERAND (def_rhs, 0),
+ convert (TREE_TYPE (def_rhs),
+ integer_zero_node));
+ }
+
+ /* Dump details. */
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, " Replaced '");
+ print_generic_expr (dump_file, cond, dump_flags);
+ fprintf (dump_file, "' with '");
+ print_generic_expr (dump_file, new_cond, dump_flags);
+ fprintf (dump_file, "'\n");
+ }
+
+ /* Replace the condition. */
+ COND_EXPR_COND (cond_stmt) = new_cond;
+ modify_stmt (cond_stmt);
+ propagated_uses++;
+ VARRAY_PUSH_TREE (*cond_worklist, cond_stmt);
+ }
+
+ /* If we propagated into all the uses, then we can delete DEF.
+ Unfortunately, we have to find the defining statement in
+ whatever block it might be in. */
+ if (num_uses && num_uses == propagated_uses)
+ for (bsi = bsi_start (bb_for_stmt (def));
+ !bsi_end_p (bsi);
+ bsi_next (&bsi))
+ {
+ if (def == bsi_stmt (bsi))
+ {
+ bsi_remove (&bsi);
+ break;
+ }
+ }
+ }
+}
+
+/* Main entry point for the forward propagation optimizer. */
+
+static void
+tree_ssa_forward_propagate_single_use_vars (void)
+{
+ basic_block bb;
+ varray_type vars_worklist, cond_worklist;
+
+ vars = BITMAP_XMALLOC ();
+ VARRAY_TREE_INIT (vars_worklist, 10, "VARS worklist");
+ VARRAY_TREE_INIT (cond_worklist, 10, "COND worklist");
+
+ /* Prime the COND_EXPR worklist by placing all the COND_EXPRs on the
+ worklist. */
+ FOR_EACH_BB (bb)
+ {
+ tree last = last_stmt (bb);
+ if (last && TREE_CODE (last) == COND_EXPR)
+ VARRAY_PUSH_TREE (cond_worklist, last);
+ }
+
+ while (VARRAY_ACTIVE_SIZE (cond_worklist) > 0)
+ {
+ /* First get a list of all the interesting COND_EXPRs and potential
+ single use variables which feed those COND_EXPRs. This will drain
+ COND_WORKLIST and initialize VARS_WORKLIST. */
+ record_single_argument_cond_exprs (cond_worklist, &vars_worklist, vars);
+
+ if (VARRAY_ACTIVE_SIZE (vars_worklist) > 0)
+ {
+ /* Now compute immediate uses for all the variables we care about. */
+ compute_immediate_uses (TDFA_USE_OPS, need_imm_uses_for);
+
+ /* We've computed immediate uses, so we can/must clear the VARS
+ bitmap for the next iteration. */
+ bitmap_clear (vars);
+
+ /* And optimize. This will drain VARS_WORKLIST and initialize
+ COND_WORKLIST for the next iteration. */
+ substitute_single_use_vars (&cond_worklist, vars_worklist);
+
+ /* We do not incrementally update the dataflow information
+ so we must free it here and recompute the necessary bits
+ on the next iteration. If this turns out to be expensive,
+ methods for incrementally updating the dataflow are known. */
+ free_df ();
+ }
+ }
+
+ /* All done. Clean up. */
+ BITMAP_XFREE (vars);
+}
+
+
+static bool
+gate_forwprop (void)
+{
+ return 1;
+}
+
+struct tree_opt_pass pass_forwprop = {
+ "forwprop", /* name */
+ gate_forwprop, /* gate */
+ tree_ssa_forward_propagate_single_use_vars, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_FORWPROP, /* tv_id */
+ PROP_cfg | PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */
+ | TODO_verify_ssa
+};
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
new file mode 100644
index 00000000000..3a166a7c21c
--- /dev/null
+++ b/gcc/tree-ssa-live.c
@@ -0,0 +1,1889 @@
+/* Liveness for SSA trees.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Contributed by Andrew MacLeod <amacleod@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "flags.h"
+#include "basic-block.h"
+#include "function.h"
+#include "diagnostic.h"
+#include "bitmap.h"
+#include "tree-flow.h"
+#include "tree-gimple.h"
+#include "tree-inline.h"
+#include "varray.h"
+#include "timevar.h"
+#include "tree-alias-common.h"
+#include "hashtab.h"
+#include "tree-dump.h"
+#include "tree-ssa-live.h"
+
+static void live_worklist (tree_live_info_p, varray_type, int);
+static tree_live_info_p new_tree_live_info (var_map);
+static inline void set_if_valid (var_map, bitmap, tree);
+static inline void add_livein_if_notdef (tree_live_info_p, bitmap,
+ tree, basic_block);
+static inline void register_ssa_partition (var_map, tree, bool);
+static inline void add_conflicts_if_valid (tpa_p, conflict_graph,
+ var_map, bitmap, tree);
+static partition_pair_p find_partition_pair (coalesce_list_p, int, int, bool);
+
+/* This is where the mapping from SSA version number to real storage variable
+ is tracked.
+
+ All SSA versions of the same variable may not ultimately be mapped back to
+ the same real variable. In that instance, we need to detect the live
+ range overlap, and give one of the variable new storage. The vector
+ 'partition_to_var' tracks which partition maps to which variable.
+
+ Given a VAR, it is sometimes desirable to know which partition that VAR
+ represents. There is an additional field in the variable annotation to
+ track that information. */
+
+/* Create a variable partition map of SIZE, initialize and return it. */
+
+var_map
+init_var_map (int size)
+{
+ var_map map;
+
+ map = (var_map) xmalloc (sizeof (struct _var_map));
+ map->var_partition = partition_new (size);
+ map->partition_to_var
+ = (tree *)xmalloc (size * sizeof (tree));
+ memset (map->partition_to_var, 0, size * sizeof (tree));
+
+ map->partition_to_compact = NULL;
+ map->compact_to_partition = NULL;
+ map->num_partitions = size;
+ map->partition_size = size;
+ map->ref_count = NULL;
+ return map;
+}
+
+
+/* Free memory associated with MAP. */
+
+void
+delete_var_map (var_map map)
+{
+ free (map->partition_to_var);
+ partition_delete (map->var_partition);
+ if (map->partition_to_compact)
+ free (map->partition_to_compact);
+ if (map->compact_to_partition)
+ free (map->compact_to_partition);
+ if (map->ref_count)
+ free (map->ref_count);
+ free (map);
+}
+
+
+/* This function will combine the partitions in MAP for VAR1 and VAR2. It
+ Returns the partition which represents the new partition. If the two
+ partitions cannot be combined, NO_PARTITION is returned. */
+
+int
+var_union (var_map map, tree var1, tree var2)
+{
+ int p1, p2, p3;
+ tree root_var = NULL_TREE;
+ tree other_var = NULL_TREE;
+
+ /* This is independent of partition_to_compact. If partition_to_compact is
+ on, then whichever one of these partitions is absorbed will never have a
+ dereference into the partition_to_compact array any more. */
+
+ if (TREE_CODE (var1) == SSA_NAME)
+ p1 = partition_find (map->var_partition, SSA_NAME_VERSION (var1));
+ else
+ {
+ p1 = var_to_partition (map, var1);
+ if (map->compact_to_partition)
+ p1 = map->compact_to_partition[p1];
+ root_var = var1;
+ }
+
+ if (TREE_CODE (var2) == SSA_NAME)
+ p2 = partition_find (map->var_partition, SSA_NAME_VERSION (var2));
+ else
+ {
+ p2 = var_to_partition (map, var2);
+ if (map->compact_to_partition)
+ p2 = map->compact_to_partition[p2];
+
+ /* If there is no root_var set, or its not a user variable, set the
+ root_var to this one. */
+ if (!root_var || is_gimple_tmp_var (root_var))
+ {
+ other_var = root_var;
+ root_var = var2;
+ }
+ else
+ other_var = var2;
+ }
+
+ if (p1 == NO_PARTITION || p2 == NO_PARTITION)
+ abort ();
+
+ if (p1 == p2)
+ p3 = p1;
+ else
+ p3 = partition_union (map->var_partition, p1, p2);
+
+ if (map->partition_to_compact)
+ p3 = map->partition_to_compact[p3];
+
+ if (root_var)
+ change_partition_var (map, root_var, p3);
+ if (other_var)
+ change_partition_var (map, other_var, p3);
+
+ return p3;
+}
+
+
+/* Compress the partition numbers in MAP such that they fall in the range
+ 0..(num_partitions-1) instead of wherever they turned out during
+ the partitioning exercise. This removes any references to unused
+ partitions, thereby allowing bitmaps and other vectors to be much
+ denser. Compression type is controlled by FLAGS.
+
+ This is implemented such that compaction doesn't affect partitioning.
+ Ie., once partitions are created and possibly merged, running one
+ or more different kind of compaction will not affect the partitions
+ themselves. Their index might change, but all the same variables will
+ still be members of the same partition group. This allows work on reduced
+ sets, and no loss of information when a larger set is later desired.
+
+ In particular, coalescing can work on partitions which have 2 or more
+ definitions, and then 'recompact' later to include all the single
+ definitions for assignment to program variables. */
+
+void
+compact_var_map (var_map map, int flags)
+{
+ sbitmap used;
+ int x, limit, count, tmp, root, root_i;
+ tree var;
+ root_var_p rv = NULL;
+
+ limit = map->partition_size;
+ used = sbitmap_alloc (limit);
+ sbitmap_zero (used);
+
+ /* Already compressed? Abandon the old one. */
+ if (map->partition_to_compact)
+ {
+ free (map->partition_to_compact);
+ map->partition_to_compact = NULL;
+ }
+ if (map->compact_to_partition)
+ {
+ free (map->compact_to_partition);
+ map->compact_to_partition = NULL;
+ }
+
+ map->num_partitions = map->partition_size;
+
+ if (flags & VARMAP_NO_SINGLE_DEFS)
+ rv = root_var_init (map);
+
+ map->partition_to_compact = (int *)xmalloc (limit * sizeof (int));
+ memset (map->partition_to_compact, 0xff, (limit * sizeof (int)));
+
+ /* Find out which partitions are actually referenced. */
+ count = 0;
+ for (x = 0; x < limit; x++)
+ {
+ tmp = partition_find (map->var_partition, x);
+ if (!TEST_BIT (used, tmp) && map->partition_to_var[tmp] != NULL_TREE)
+ {
+ /* It is referenced, check to see if there is more than one version
+ in the root_var table, if one is available. */
+ if (rv)
+ {
+ root = root_var_find (rv, tmp);
+ root_i = root_var_first_partition (rv, root);
+ /* If there is only one, don't include this in the compaction. */
+ if (root_var_next_partition (rv, root_i) == ROOT_VAR_NONE)
+ continue;
+ }
+ SET_BIT (used, tmp);
+ count++;
+ }
+ }
+
+ /* Build a compacted partitioning. */
+ if (count != limit)
+ {
+ map->compact_to_partition = (int *)xmalloc (count * sizeof (int));
+ count = 0;
+ /* SSA renaming begins at 1, so skip 0 when compacting. */
+ EXECUTE_IF_SET_IN_SBITMAP (used, 1, x,
+ {
+ map->partition_to_compact[x] = count;
+ map->compact_to_partition[count] = x;
+ var = map->partition_to_var[x];
+ if (TREE_CODE (var) != SSA_NAME)
+ change_partition_var (map, var, count);
+ count++;
+ });
+ }
+ else
+ {
+ free (map->partition_to_compact);
+ map->partition_to_compact = NULL;
+ }
+
+ map->num_partitions = count;
+
+ if (rv)
+ root_var_delete (rv);
+ sbitmap_free (used);
+}
+
+
+/* This function is used to change the representative variable in MAP for VAR's
+ partition from an SSA_NAME variable to a regular variable. This allows
+ partitions to be mapped back to real variables. */
+
+void
+change_partition_var (var_map map, tree var, int part)
+{
+ var_ann_t ann;
+
+ if (TREE_CODE (var) == SSA_NAME)
+ abort();
+
+ ann = var_ann (var);
+ ann->out_of_ssa_tag = 1;
+ VAR_ANN_PARTITION (ann) = part;
+ if (map->compact_to_partition)
+ map->partition_to_var[map->compact_to_partition[part]] = var;
+}
+
+
+/* This function looks through the program and uses FLAGS to determine what
+ SSA versioned variables are given entries in a new partition table. This
+ new partition map is returned. */
+
+var_map
+create_ssa_var_map (int flags)
+{
+ block_stmt_iterator bsi;
+ basic_block bb;
+ tree *dest, *use;
+ tree stmt;
+ stmt_ann_t ann;
+ vuse_optype vuses;
+ vdef_optype vdefs;
+ use_optype uses;
+ def_optype defs;
+ unsigned x;
+ var_map map;
+#if defined ENABLE_CHECKING
+ sbitmap used_in_real_ops;
+ sbitmap used_in_virtual_ops;
+#endif
+
+ map = init_var_map (highest_ssa_version + 1);
+
+#if defined ENABLE_CHECKING
+ used_in_real_ops = sbitmap_alloc (num_referenced_vars);
+ sbitmap_zero (used_in_real_ops);
+
+ used_in_virtual_ops = sbitmap_alloc (num_referenced_vars);
+ sbitmap_zero (used_in_virtual_ops);
+#endif
+
+ if (flags & SSA_VAR_MAP_REF_COUNT)
+ {
+ map->ref_count
+ = (int *)xmalloc (((highest_ssa_version + 1) * sizeof (int)));
+ memset (map->ref_count, 0, (highest_ssa_version + 1) * sizeof (int));
+ }
+
+ FOR_EACH_BB (bb)
+ {
+ tree phi, arg;
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ int i;
+ register_ssa_partition (map, PHI_RESULT (phi), false);
+ for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ {
+ arg = PHI_ARG_DEF (phi, i);
+ if (TREE_CODE (arg) == SSA_NAME)
+ register_ssa_partition (map, arg, true);
+ }
+ }
+
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ stmt = bsi_stmt (bsi);
+ get_stmt_operands (stmt);
+ ann = stmt_ann (stmt);
+
+ /* Register USE and DEF operands in each statement. */
+ uses = USE_OPS (ann);
+ for (x = 0; x < NUM_USES (uses); x++)
+ {
+ use = USE_OP_PTR (uses, x);
+ register_ssa_partition (map, *use, true);
+
+#if defined ENABLE_CHECKING
+ SET_BIT (used_in_real_ops, var_ann (SSA_NAME_VAR (*use))->uid);
+#endif
+ }
+
+ defs = DEF_OPS (ann);
+ for (x = 0; x < NUM_DEFS (defs); x++)
+ {
+ dest = DEF_OP_PTR (defs, x);
+ register_ssa_partition (map, *dest, false);
+
+#if defined ENABLE_CHECKING
+ SET_BIT (used_in_real_ops, var_ann (SSA_NAME_VAR (*dest))->uid);
+#endif
+ }
+
+ /* While we do not care about virtual operands for
+ out of SSA, we do need to look at them to make sure
+ we mark all the variables which are used. */
+ vuses = VUSE_OPS (ann);
+ for (x = 0; x < NUM_VUSES (vuses); x++)
+ {
+ tree var = VUSE_OP (vuses, x);
+ set_is_used (var);
+
+#if defined ENABLE_CHECKING
+ SET_BIT (used_in_virtual_ops, var_ann (SSA_NAME_VAR (var))->uid);
+#endif
+ }
+
+ vdefs = VDEF_OPS (ann);
+ for (x = 0; x < NUM_VDEFS (vdefs); x++)
+ {
+ tree var = VDEF_OP (vdefs, x);
+ set_is_used (var);
+
+#if defined ENABLE_CHECKING
+ SET_BIT (used_in_virtual_ops, var_ann (SSA_NAME_VAR (var))->uid);
+#endif
+ }
+ }
+ }
+
+#if defined ENABLE_CHECKING
+ {
+ unsigned i;
+ sbitmap both = sbitmap_alloc (num_referenced_vars);
+ sbitmap_a_and_b (both, used_in_real_ops, used_in_virtual_ops);
+ if (sbitmap_first_set_bit (both) >= 0)
+ {
+ EXECUTE_IF_SET_IN_SBITMAP (both, 0, i,
+ fprintf (stderr, "Variable %s used in real and virtual operands\n",
+ get_name (referenced_var (i))));
+ abort ();
+ }
+
+ sbitmap_free (used_in_real_ops);
+ sbitmap_free (used_in_virtual_ops);
+ sbitmap_free (both);
+ }
+#endif
+
+ return map;
+}
+
+
+/* Allocate and return a new live range information object base on MAP. */
+
+static tree_live_info_p
+new_tree_live_info (var_map map)
+{
+ tree_live_info_p live;
+ int x;
+
+ live = (tree_live_info_p) xmalloc (sizeof (struct tree_live_info_d));
+ live->map = map;
+ live->num_blocks = last_basic_block;
+
+ live->global = BITMAP_XMALLOC ();
+
+ live->livein = (bitmap *)xmalloc (num_var_partitions (map) * sizeof (bitmap));
+ for (x = 0; x < num_var_partitions (map); x++)
+ live->livein[x] = BITMAP_XMALLOC ();
+
+ /* liveout is deferred until it is actually requested. */
+ live->liveout = NULL;
+ return live;
+}
+
+
+/* Free storage for live range info object LIVE. */
+
+void
+delete_tree_live_info (tree_live_info_p live)
+{
+ int x;
+ if (live->liveout)
+ {
+ for (x = live->num_blocks - 1; x >= 0; x--)
+ BITMAP_XFREE (live->liveout[x]);
+ free (live->liveout);
+ }
+ if (live->livein)
+ {
+ for (x = num_var_partitions (live->map) - 1; x >= 0; x--)
+ BITMAP_XFREE (live->livein[x]);
+ free (live->livein);
+ }
+ if (live->global)
+ BITMAP_XFREE (live->global);
+
+ free (live);
+}
+
+
+/* Using LIVE, fill in all the live-on-entry blocks between the defs and uses
+ for partition I. STACK is a varray used for temporary memory which is
+ passed in rather than being allocated on every call. */
+
+static void
+live_worklist (tree_live_info_p live, varray_type stack, int i)
+{
+ int b;
+ tree var;
+ basic_block def_bb = NULL;
+ edge e;
+ var_map map = live->map;
+
+ var = partition_to_var (map, i);
+ if (SSA_NAME_DEF_STMT (var))
+ def_bb = bb_for_stmt (SSA_NAME_DEF_STMT (var));
+
+ EXECUTE_IF_SET_IN_BITMAP (live->livein[i], 0, b,
+ {
+ VARRAY_PUSH_INT (stack, b);
+ });
+
+ while (VARRAY_ACTIVE_SIZE (stack) > 0)
+ {
+ b = VARRAY_TOP_INT (stack);
+ VARRAY_POP (stack);
+
+ for (e = BASIC_BLOCK (b)->pred; e; e = e->pred_next)
+ if (e->src != ENTRY_BLOCK_PTR)
+ {
+ /* Its not live on entry to the block its defined in. */
+ if (e->src == def_bb)
+ continue;
+ if (!bitmap_bit_p (live->livein[i], e->src->index))
+ {
+ bitmap_set_bit (live->livein[i], e->src->index);
+ VARRAY_PUSH_INT (stack, e->src->index);
+ }
+ }
+ }
+}
+
+
+/* If VAR is in a partition of MAP, set the bit for that partition in VEC. */
+
+static inline void
+set_if_valid (var_map map, bitmap vec, tree var)
+{
+ int p = var_to_partition (map, var);
+ if (p != NO_PARTITION)
+ bitmap_set_bit (vec, p);
+}
+
+
+/* If VAR is in a partition and it isn't defined in DEF_VEC, set the livein and
+ global bit for it in the LIVE object. BB is the block being processed. */
+
+static inline void
+add_livein_if_notdef (tree_live_info_p live, bitmap def_vec,
+ tree var, basic_block bb)
+{
+ int p = var_to_partition (live->map, var);
+ if (p == NO_PARTITION || bb == ENTRY_BLOCK_PTR)
+ return;
+ if (!bitmap_bit_p (def_vec, p))
+ {
+ bitmap_set_bit (live->livein[p], bb->index);
+ bitmap_set_bit (live->global, p);
+ }
+}
+
+
+/* Given partition map MAP, calculate all the live on entry bitmaps for
+ each basic block. Return a live info object. */
+
+tree_live_info_p
+calculate_live_on_entry (var_map map)
+{
+ tree_live_info_p live;
+ int num, i;
+ basic_block bb;
+ bitmap saw_def;
+ tree phi, var, stmt;
+ tree op;
+ edge e;
+ varray_type stack;
+ block_stmt_iterator bsi;
+ use_optype uses;
+ def_optype defs;
+ stmt_ann_t ann;
+
+ saw_def = BITMAP_XMALLOC ();
+
+ live = new_tree_live_info (map);
+
+ FOR_EACH_BB (bb)
+ {
+ bitmap_clear (saw_def);
+
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ {
+ var = PHI_ARG_DEF (phi, i);
+ if (!phi_ssa_name_p (var))
+ continue;
+ stmt = SSA_NAME_DEF_STMT (var);
+ e = PHI_ARG_EDGE (phi, i);
+
+ /* Any uses in PHIs which either don't have def's or are not
+ defined in the block from which the def comes, will be live
+ on entry to that block. */
+ if (!stmt || e->src != bb_for_stmt (stmt))
+ add_livein_if_notdef (live, saw_def, var, e->src);
+ }
+ }
+
+ /* Don't mark PHI results as defined until all the PHI nodes have
+ been processed. If the PHI sequence is:
+ a_3 = PHI <a_1, a_2>
+ b_3 = PHI <b_1, a_3>
+ The a_3 referred to in b_3's PHI node is the one incoming on the
+ edge, *not* the PHI node just seen. */
+
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ var = PHI_RESULT (phi);
+ set_if_valid (map, saw_def, var);
+ }
+
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ stmt = bsi_stmt (bsi);
+ get_stmt_operands (stmt);
+ ann = stmt_ann (stmt);
+
+ uses = USE_OPS (ann);
+ num = NUM_USES (uses);
+ for (i = 0; i < num; i++)
+ {
+ op = USE_OP (uses, i);
+ add_livein_if_notdef (live, saw_def, op, bb);
+ }
+
+ defs = DEF_OPS (ann);
+ num = NUM_DEFS (defs);
+ for (i = 0; i < num; i++)
+ {
+ op = DEF_OP (defs, i);
+ set_if_valid (map, saw_def, op);
+ }
+ }
+ }
+
+ VARRAY_INT_INIT (stack, last_basic_block, "stack");
+ EXECUTE_IF_SET_IN_BITMAP (live->global, 0, i,
+ {
+ live_worklist (live, stack, i);
+ });
+
+#ifdef ENABLE_CHECKING
+ /* Check for live on entry partitions and report those with a DEF in
+ the program. This will typically mean an optimization has done
+ something wrong. */
+
+ bb = ENTRY_BLOCK_PTR;
+ num = 0;
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ int entry_block = e->dest->index;
+ if (e->dest == EXIT_BLOCK_PTR)
+ continue;
+ for (i = 0; i < num_var_partitions (map); i++)
+ {
+ basic_block tmp;
+ tree d;
+ var = partition_to_var (map, i);
+ stmt = SSA_NAME_DEF_STMT (var);
+ tmp = bb_for_stmt (stmt);
+ d = default_def (SSA_NAME_VAR (var));
+
+ if (bitmap_bit_p (live_entry_blocks (live, i), entry_block))
+ {
+ if (!IS_EMPTY_STMT (stmt))
+ {
+ num++;
+ print_generic_expr (stderr, var, TDF_SLIM);
+ fprintf (stderr, " is defined ");
+ if (tmp)
+ fprintf (stderr, " in BB%d, ", tmp->index);
+ fprintf (stderr, "by:\n");
+ print_generic_expr (stderr, stmt, TDF_SLIM);
+ fprintf (stderr, "\nIt is also live-on-entry to entry BB %d",
+ entry_block);
+ fprintf (stderr, " So it appears to have multiple defs.\n");
+ }
+ else
+ {
+ if (d != var)
+ {
+ num++;
+ print_generic_expr (stderr, var, TDF_SLIM);
+ fprintf (stderr, " is live-on-entry to BB%d ",entry_block);
+ if (d)
+ {
+ fprintf (stderr, " but is not the default def of ");
+ print_generic_expr (stderr, d, TDF_SLIM);
+ fprintf (stderr, "\n");
+ }
+ else
+ fprintf (stderr, " and there is no default def.\n");
+ }
+ }
+ }
+ else
+ if (d == var)
+ {
+ /* The only way this var shouldn't be marked live on entry is
+ if it occurs in a PHI argument of the block. */
+ int z, ok = 0;
+ for (phi = phi_nodes (e->dest);
+ phi && !ok;
+ phi = TREE_CHAIN (phi))
+ {
+ for (z = 0; z < PHI_NUM_ARGS (phi); z++)
+ if (var == PHI_ARG_DEF (phi, z))
+ {
+ ok = 1;
+ break;
+ }
+ }
+ if (ok)
+ continue;
+ num++;
+ print_generic_expr (stderr, var, TDF_SLIM);
+ fprintf (stderr, " is not marked live-on-entry to entry BB%d ",
+ entry_block);
+ fprintf (stderr, "but it is a default def so it should be.\n");
+ }
+ }
+ }
+ if (num > 0)
+ abort ();
+#endif
+
+ BITMAP_XFREE (saw_def);
+
+ return live;
+}
+
+
+/* Calculate the live on exit vectors based on the entry info in LIVEINFO. */
+
+void
+calculate_live_on_exit (tree_live_info_p liveinfo)
+{
+ unsigned b;
+ int i, x;
+ bitmap *on_exit;
+ basic_block bb;
+ edge e;
+ tree t, phi;
+ bitmap on_entry;
+ var_map map = liveinfo->map;
+
+ on_exit = (bitmap *)xmalloc (last_basic_block * sizeof (bitmap));
+ for (x = 0; x < last_basic_block; x++)
+ on_exit[x] = BITMAP_XMALLOC ();
+
+ /* Set all the live-on-exit bits for uses in PHIs. */
+ FOR_EACH_BB (bb)
+ {
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ {
+ t = PHI_ARG_DEF (phi, i);
+ e = PHI_ARG_EDGE (phi, i);
+ if (!phi_ssa_name_p (t) || e->src == ENTRY_BLOCK_PTR)
+ continue;
+ set_if_valid (map, on_exit[e->src->index], t);
+ }
+ }
+
+ /* Set live on exit for all predecessors of live on entry's. */
+ for (i = 0; i < num_var_partitions (map); i++)
+ {
+ on_entry = live_entry_blocks (liveinfo, i);
+ EXECUTE_IF_SET_IN_BITMAP (on_entry, 0, b,
+ {
+ for (e = BASIC_BLOCK(b)->pred; e; e = e->pred_next)
+ if (e->src != ENTRY_BLOCK_PTR)
+ bitmap_set_bit (on_exit[e->src->index], i);
+ });
+ }
+
+ liveinfo->liveout = on_exit;
+}
+
+
+/* Initialize a tree_partition_associator object using MAP. */
+
+tpa_p
+tpa_init (var_map map)
+{
+ tpa_p tpa;
+ int num_partitions = num_var_partitions (map);
+ int x;
+
+ if (num_partitions == 0)
+ return NULL;
+
+ tpa = (tpa_p) xmalloc (sizeof (struct tree_partition_associator_d));
+ tpa->num_trees = 0;
+ tpa->uncompressed_num = -1;
+ tpa->map = map;
+ tpa->next_partition = (int *)xmalloc (num_partitions * sizeof (int));
+ memset (tpa->next_partition, TPA_NONE, num_partitions * sizeof (int));
+
+ tpa->partition_to_tree_map = (int *)xmalloc (num_partitions * sizeof (int));
+ memset (tpa->partition_to_tree_map, TPA_NONE, num_partitions * sizeof (int));
+
+ x = MAX (40, (num_partitions / 20));
+ VARRAY_TREE_INIT (tpa->trees, x, "trees");
+ VARRAY_INT_INIT (tpa->first_partition, x, "first_partition");
+
+ return tpa;
+
+}
+
+
+/* Remove PARTITION_INDEX from TREE_INDEX's list in the tpa structure TPA. */
+
+void
+tpa_remove_partition (tpa_p tpa, int tree_index, int partition_index)
+{
+ int i;
+
+ i = tpa_first_partition (tpa, tree_index);
+ if (i == partition_index)
+ {
+ VARRAY_INT (tpa->first_partition, tree_index) = tpa->next_partition[i];
+ }
+ else
+ {
+ for ( ; i != TPA_NONE; i = tpa_next_partition (tpa, i))
+ {
+ if (tpa->next_partition[i] == partition_index)
+ {
+ tpa->next_partition[i] = tpa->next_partition[partition_index];
+ break;
+ }
+ }
+ }
+}
+
+
+/* Free the memory used by tree_partition_associator object TPA. */
+
+void
+tpa_delete (tpa_p tpa)
+{
+ if (!tpa)
+ return;
+
+ free (tpa->partition_to_tree_map);
+ free (tpa->next_partition);
+ free (tpa);
+}
+
+
+/* This function will remove any tree entires from TPA which have only a single
+ element. This will help keep the size of the conflict graph down. The
+ function returns the number of remaining tree lists. */
+
+int
+tpa_compact (tpa_p tpa)
+{
+ int last, x, y, first, swap_i;
+ tree swap_t;
+
+ /* Find the last list which has more than 1 partition. */
+ for (last = tpa->num_trees - 1; last > 0; last--)
+ {
+ first = tpa_first_partition (tpa, last);
+ if (tpa_next_partition (tpa, first) != NO_PARTITION)
+ break;
+ }
+
+ x = 0;
+ while (x < last)
+ {
+ first = tpa_first_partition (tpa, x);
+
+ /* If there is not more than one partition, swap with the current end
+ of the tree list. */
+ if (tpa_next_partition (tpa, first) == NO_PARTITION)
+ {
+ swap_t = VARRAY_TREE (tpa->trees, last);
+ swap_i = VARRAY_INT (tpa->first_partition, last);
+
+ /* Update the last entry. Since it is known to only have one
+ partition, there is nothing else to update. */
+ VARRAY_TREE (tpa->trees, last) = VARRAY_TREE (tpa->trees, x);
+ VARRAY_INT (tpa->first_partition, last)
+ = VARRAY_INT (tpa->first_partition, x);
+ tpa->partition_to_tree_map[tpa_first_partition (tpa, last)] = last;
+
+ /* Since this list is known to have more than one partition, update
+ the list owner entries. */
+ VARRAY_TREE (tpa->trees, x) = swap_t;
+ VARRAY_INT (tpa->first_partition, x) = swap_i;
+ for (y = tpa_first_partition (tpa, x);
+ y != NO_PARTITION;
+ y = tpa_next_partition (tpa, y))
+ tpa->partition_to_tree_map[y] = x;
+
+ /* Ensure last is a list with more than one partition. */
+ last--;
+ for (; last > x; last--)
+ {
+ first = tpa_first_partition (tpa, last);
+ if (tpa_next_partition (tpa, first) != NO_PARTITION)
+ break;
+ }
+ }
+ x++;
+ }
+
+ first = tpa_first_partition (tpa, x);
+ if (tpa_next_partition (tpa, first) != NO_PARTITION)
+ x++;
+ tpa->uncompressed_num = tpa->num_trees;
+ tpa->num_trees = x;
+ return last;
+}
+
+
+/* Initialize a root_var object with SSA partitions from MAP which are based
+ on each root variable. */
+
+root_var_p
+root_var_init (var_map map)
+{
+ root_var_p rv;
+ int num_partitions = num_var_partitions (map);
+ int x, p;
+ tree t;
+ var_ann_t ann;
+ sbitmap seen;
+
+ rv = tpa_init (map);
+ if (!rv)
+ return NULL;
+
+ seen = sbitmap_alloc (num_partitions);
+ sbitmap_zero (seen);
+
+ /* Start at the end and work towards the front. This will provide a list
+ that is ordered from smallest to largest. */
+ for (x = num_partitions - 1; x >= 0; x--)
+ {
+ t = partition_to_var (map, x);
+
+ /* The var map may not be compacted yet, so check for NULL. */
+ if (!t)
+ continue;
+
+ p = var_to_partition (map, t);
+
+#ifdef ENABLE_CHECKING
+ if (p == NO_PARTITION)
+ abort ();
+#endif
+
+ /* Make sure we only put coalesced partitions into the list once. */
+ if (TEST_BIT (seen, p))
+ continue;
+ SET_BIT (seen, p);
+ if (TREE_CODE (t) == SSA_NAME)
+ t = SSA_NAME_VAR (t);
+ ann = var_ann (t);
+ if (ann->root_var_processed)
+ {
+ rv->next_partition[p] = VARRAY_INT (rv->first_partition,
+ VAR_ANN_ROOT_INDEX (ann));
+ VARRAY_INT (rv->first_partition, VAR_ANN_ROOT_INDEX (ann)) = p;
+ }
+ else
+ {
+ ann->root_var_processed = 1;
+ VAR_ANN_ROOT_INDEX (ann) = rv->num_trees++;
+ VARRAY_PUSH_TREE (rv->trees, t);
+ VARRAY_PUSH_INT (rv->first_partition, p);
+ }
+ rv->partition_to_tree_map[p] = VAR_ANN_ROOT_INDEX (ann);
+ }
+
+ /* Reset the out_of_ssa_tag flag on each variable for later use. */
+ for (x = 0; x < rv->num_trees; x++)
+ {
+ t = VARRAY_TREE (rv->trees, x);
+ var_ann (t)->root_var_processed = 0;
+ }
+
+ sbitmap_free (seen);
+ return rv;
+}
+
+
+/* Initialize a type_var structure which associates all the partitions in MAP
+ of the same type to the type node's index. Volatiles are ignored. */
+
+type_var_p
+type_var_init (var_map map)
+{
+ type_var_p tv;
+ int x, y, p;
+ int num_partitions = num_var_partitions (map);
+ tree t;
+ sbitmap seen;
+
+ seen = sbitmap_alloc (num_partitions);
+ sbitmap_zero (seen);
+
+ tv = tpa_init (map);
+ if (!tv)
+ return NULL;
+
+ for (x = num_partitions - 1; x >= 0; x--)
+ {
+ t = partition_to_var (map, x);
+
+ /* Disallow coalescing of these types of variables. */
+ if (!t
+ || TREE_THIS_VOLATILE (t)
+ || TREE_CODE (t) == RESULT_DECL
+ || TREE_CODE (t) == PARM_DECL
+ || (DECL_P (t)
+ && (DECL_REGISTER (t)
+ || !DECL_ARTIFICIAL (t)
+ || DECL_RTL_SET_P (t))))
+ continue;
+
+ p = var_to_partition (map, t);
+
+#ifdef ENABLE_CHECKING
+ if (p == NO_PARTITION)
+ abort ();
+#endif
+
+ /* If partitions have been coalesced, only add the representative
+ for the partition to the list once. */
+ if (TEST_BIT (seen, p))
+ continue;
+ SET_BIT (seen, p);
+ t = TREE_TYPE (t);
+
+ /* Find the list for this type. */
+ for (y = 0; y < tv->num_trees; y++)
+ if (t == VARRAY_TREE (tv->trees, y))
+ break;
+ if (y == tv->num_trees)
+ {
+ tv->num_trees++;
+ VARRAY_PUSH_TREE (tv->trees, t);
+ VARRAY_PUSH_INT (tv->first_partition, p);
+ }
+ else
+ {
+ tv->next_partition[p] = VARRAY_INT (tv->first_partition, y);
+ VARRAY_INT (tv->first_partition, y) = p;
+ }
+ tv->partition_to_tree_map[p] = y;
+ }
+ sbitmap_free (seen);
+ return tv;
+}
+
+
+/* Create a new coalesce list object from MAP and return it. */
+
+coalesce_list_p
+create_coalesce_list (var_map map)
+{
+ coalesce_list_p list;
+
+ list = (coalesce_list_p) xmalloc (sizeof (struct coalesce_list_d));
+
+ list->map = map;
+ list->add_mode = true;
+ list->list = (partition_pair_p *) xcalloc (num_var_partitions (map),
+ sizeof (struct partition_pair_d));
+ return list;
+}
+
+
+/* Delete coalesce list CL. */
+
+void
+delete_coalesce_list (coalesce_list_p cl)
+{
+ free (cl->list);
+ free (cl);
+}
+
+
+/* Find a matching coalesce pair object in CL for partitions P1 and P2. If
+ one isn't found, return NULL if CREATE is false, otherwise create a new
+ coalesce pair object and return it. */
+
+static partition_pair_p
+find_partition_pair (coalesce_list_p cl, int p1, int p2, bool create)
+{
+ partition_pair_p node, tmp;
+ int s;
+
+ /* Normalize so that p1 is the smaller value. */
+ if (p2 < p1)
+ {
+ s = p1;
+ p1 = p2;
+ p2 = s;
+ }
+
+ tmp = NULL;
+
+ /* The list is sorted such that if we find a value greater than p2,
+ p2 is not in the list. */
+ for (node = cl->list[p1]; node; node = node->next)
+ {
+ if (node->second_partition == p2)
+ return node;
+ else
+ if (node->second_partition > p2)
+ break;
+ tmp = node;
+ }
+
+ if (!create)
+ return NULL;
+
+ node = (partition_pair_p) xmalloc (sizeof (struct partition_pair_d));
+ node->first_partition = p1;
+ node->second_partition = p2;
+ node->cost = 0;
+
+ if (tmp != NULL)
+ {
+ node->next = tmp->next;
+ tmp->next = node;
+ }
+ else
+ {
+ /* This is now the first node in the list. */
+ node->next = cl->list[p1];
+ cl->list[p1] = node;
+ }
+
+ return node;
+}
+
+
+/* Add a potential coalesce between P1 and P2 in CL with a cost of VALUE. */
+
+void
+add_coalesce (coalesce_list_p cl, int p1, int p2, int value)
+{
+ partition_pair_p node;
+
+#ifdef ENABLE_CHECKING
+ if (!cl->add_mode)
+ abort();
+#endif
+
+ if (p1 == p2)
+ return;
+
+ node = find_partition_pair (cl, p1, p2, true);
+
+ node->cost += value;
+}
+
+
+/* Comparison function to allow qsort to sort P1 and P2 in descending order. */
+
+static
+int compare_pairs (const void *p1, const void *p2)
+{
+ return (*(partition_pair_p *)p2)->cost - (*(partition_pair_p *)p1)->cost;
+}
+
+
+/* Prepare CL for removal of preferred pairs. When finished, list element
+ 0 has all the coalesce pairs, sorted in order from most important coalesce
+ to least important. */
+
+void
+sort_coalesce_list (coalesce_list_p cl)
+{
+ int x, num, count;
+ partition_pair_p chain, p;
+ partition_pair_p *list;
+
+ if (!cl->add_mode)
+ abort();
+
+ cl->add_mode = false;
+
+ /* Compact the array of lists to a single list, and count the elements. */
+ num = 0;
+ chain = NULL;
+ for (x = 0; x < num_var_partitions (cl->map); x++)
+ if (cl->list[x] != NULL)
+ {
+ for (p = cl->list[x]; p->next != NULL; p = p->next)
+ num++;
+ num++;
+ p->next = chain;
+ chain = cl->list[x];
+ cl->list[x] = NULL;
+ }
+
+ /* Only call qsort if there are more than 2 items. */
+ if (num > 2)
+ {
+ list = xmalloc (sizeof (partition_pair_p) * num);
+ count = 0;
+ for (p = chain; p != NULL; p = p->next)
+ list[count++] = p;
+
+#ifdef ENABLE_CHECKING
+ if (count != num)
+ abort ();
+#endif
+
+ qsort (list, count, sizeof (partition_pair_p), compare_pairs);
+
+ p = list[0];
+ for (x = 1; x < num; x++)
+ {
+ p->next = list[x];
+ p = list[x];
+ }
+ p->next = NULL;
+ cl->list[0] = list[0];
+ free (list);
+ }
+ else
+ {
+ cl->list[0] = chain;
+ if (num == 2)
+ {
+ /* Simply swap the two elements if they are in the wrong order. */
+ if (chain->cost < chain->next->cost)
+ {
+ cl->list[0] = chain->next;
+ cl->list[0]->next = chain;
+ chain->next = NULL;
+ }
+ }
+ }
+}
+
+
+/* Retrieve the best remaining pair to coalesce from CL. Returns the 2
+ partitions via P1 and P2. Their calculated cost is returned by the function.
+ NO_BEST_COALESCE is returned if the coalesce list is empty. */
+
+int
+pop_best_coalesce (coalesce_list_p cl, int *p1, int *p2)
+{
+ partition_pair_p node;
+ int ret;
+
+ if (cl->add_mode)
+ abort();
+
+ node = cl->list[0];
+ if (!node)
+ return NO_BEST_COALESCE;
+
+ cl->list[0] = node->next;
+
+ *p1 = node->first_partition;
+ *p2 = node->second_partition;
+ ret = node->cost;
+ free (node);
+
+ return ret;
+}
+
+
+/* If variable VAR is in a partition in MAP, add a conflict in GRAPH between
+ VAR and any other live partitions in VEC which are associated via TPA.
+ Reset the live bit in VEC. */
+
+static inline void
+add_conflicts_if_valid (tpa_p tpa, conflict_graph graph,
+ var_map map, bitmap vec, tree var)
+{
+ int p, y, first;
+ p = var_to_partition (map, var);
+ if (p != NO_PARTITION)
+ {
+ bitmap_clear_bit (vec, p);
+ first = tpa_find_tree (tpa, p);
+ /* If find returns nothing, this object isn't interesting. */
+ if (first == TPA_NONE)
+ return;
+ /* Only add interferences between objects in the same list. */
+ for (y = tpa_first_partition (tpa, first);
+ y != TPA_NONE;
+ y = tpa_next_partition (tpa, y))
+ {
+ if (bitmap_bit_p (vec, y))
+ conflict_graph_add (graph, p, y);
+ }
+ }
+}
+
+
+/* Return a conflict graph for the information contained in LIVE_INFO. Only
+ conflicts between items in the same TPA list are added. If optional
+ coalesce list CL is passed in, any copies encountered are added. */
+
+conflict_graph
+build_tree_conflict_graph (tree_live_info_p liveinfo, tpa_p tpa,
+ coalesce_list_p cl)
+{
+ conflict_graph graph;
+ var_map map;
+ bitmap live;
+ int num, x, y, i;
+ basic_block bb;
+ varray_type partition_link, tpa_to_clear, tpa_nodes;
+ def_optype defs;
+ use_optype uses;
+ unsigned l;
+
+ map = live_var_map (liveinfo);
+ graph = conflict_graph_new (num_var_partitions (map));
+
+ if (tpa_num_trees (tpa) == 0)
+ return graph;
+
+ live = BITMAP_XMALLOC ();
+
+ VARRAY_INT_INIT (partition_link, num_var_partitions (map) + 1, "part_link");
+ VARRAY_INT_INIT (tpa_nodes, tpa_num_trees (tpa), "tpa nodes");
+ VARRAY_INT_INIT (tpa_to_clear, 50, "tpa to clear");
+
+ FOR_EACH_BB (bb)
+ {
+ block_stmt_iterator bsi;
+ tree phi;
+
+ /* Start with live on exit temporaries. */
+ bitmap_copy (live, live_on_exit (liveinfo, bb));
+
+ for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
+ {
+ bool is_a_copy = false;
+ tree stmt = bsi_stmt (bsi);
+ stmt_ann_t ann;
+
+ get_stmt_operands (stmt);
+ ann = stmt_ann (stmt);
+
+ /* A copy between 2 partitions does not introduce an interference
+ by itself. If they did, you would never be able to coalesce
+ two things which are copied. If the two variables really do
+ conflict, they will conflict elsewhere in the program.
+
+ This is handled specially here since we may also be interested
+ in copies between real variables and SSA_NAME variables. We may
+ be interested in trying to coalesce SSA_NAME variables with
+ root variables in some cases. */
+
+ if (TREE_CODE (stmt) == MODIFY_EXPR)
+ {
+ tree lhs = TREE_OPERAND (stmt, 0);
+ tree rhs = TREE_OPERAND (stmt, 1);
+ int p1, p2;
+ int bit;
+
+ if (DECL_P (lhs) || TREE_CODE (lhs) == SSA_NAME)
+ p1 = var_to_partition (map, lhs);
+ else
+ p1 = NO_PARTITION;
+
+ if (DECL_P (rhs) || TREE_CODE (rhs) == SSA_NAME)
+ p2 = var_to_partition (map, rhs);
+ else
+ p2 = NO_PARTITION;
+
+ if (p1 != NO_PARTITION && p2 != NO_PARTITION)
+ {
+ is_a_copy = true;
+ bit = bitmap_bit_p (live, p2);
+ /* If the RHS is live, make it not live while we add
+ the conflicts, then make it live again. */
+ if (bit)
+ bitmap_clear_bit (live, p2);
+ add_conflicts_if_valid (tpa, graph, map, live, lhs);
+ if (bit)
+ bitmap_set_bit (live, p2);
+ if (cl)
+ add_coalesce (cl, p1, p2, 1);
+ set_if_valid (map, live, rhs);
+ }
+ }
+
+ if (!is_a_copy)
+ {
+ tree *var_p;
+
+ defs = DEF_OPS (ann);
+ num = NUM_DEFS (defs);
+ for (x = 0; x < num; x++)
+ {
+ var_p = DEF_OP_PTR (defs, x);
+ add_conflicts_if_valid (tpa, graph, map, live, *var_p);
+ }
+
+ uses = USE_OPS (ann);
+ num = NUM_USES (uses);
+ for (x = 0; x < num; x++)
+ {
+ var_p = USE_OP_PTR (uses, x);
+ set_if_valid (map, live, *var_p);
+ }
+ }
+ }
+
+ /* If result of a PHI is unused, then the loops over the statements
+ will not record any conflicts. However, since the PHI node is
+ going to be translated out of SSA form we must record a conflict
+ between the result of the PHI and any variables with are live.
+ Otherwise the out-of-ssa translation may create incorrect code. */
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ tree result = PHI_RESULT (phi);
+ int p = var_to_partition (map, result);
+
+ if (p != NO_PARTITION && ! bitmap_bit_p (live, p))
+ add_conflicts_if_valid (tpa, graph, map, live, result);
+ }
+
+ /* Anything which is still live at this point interferes.
+ In order to implement this efficiently, only conflicts between
+ partitions which have the same TPA root need be added.
+ TPA roots which have been seen are tracked in 'tpa_nodes'. A non-zero
+ entry points to an index into 'partition_link', which then indexes
+ into itself forming a linked list of partitions sharing a tpa root
+ which have been seen as live up to this point. Since partitions start
+ at index zero, all entries in partition_link are (partition + 1).
+
+ Conflicts are added between the current partition and any already seen.
+ tpa_clear contains all the tpa_roots processed, and these are the only
+ entries which need to be zero'd out for a clean restart. */
+
+ EXECUTE_IF_SET_IN_BITMAP (live, 0, x,
+ {
+ i = tpa_find_tree (tpa, x);
+ if (i != TPA_NONE)
+ {
+ int start = VARRAY_INT (tpa_nodes, i);
+ /* If start is 0, a new root reference list is being started.
+ Register it to be cleared. */
+ if (!start)
+ VARRAY_PUSH_INT (tpa_to_clear, i);
+
+ /* Add interferences to other tpa members seen. */
+ for (y = start; y != 0; y = VARRAY_INT (partition_link, y))
+ conflict_graph_add (graph, x, y - 1);
+ VARRAY_INT (tpa_nodes, i) = x + 1;
+ VARRAY_INT (partition_link, x + 1) = start;
+ }
+ });
+
+ /* Now clear the used tpa root references. */
+ for (l = 0; l < VARRAY_ACTIVE_SIZE (tpa_to_clear); l++)
+ VARRAY_INT (tpa_nodes, VARRAY_INT (tpa_to_clear, l)) = 0;
+ VARRAY_POP_ALL (tpa_to_clear);
+ }
+
+ BITMAP_XFREE (live);
+ return graph;
+}
+
+
+/* This routine will attempt to coalesce the elements in TPA subject to the
+ conflicts found in GRAPH. If optional coalesce_list CL is provided,
+ only coalesces specified within the coalesce list are attempted. Otherwise
+ an attempt is made to coalesce as many partitions within each TPA grouping
+ as possible. If DEBUG is provided, debug output will be sent there. */
+
+void
+coalesce_tpa_members (tpa_p tpa, conflict_graph graph, var_map map,
+ coalesce_list_p cl, FILE *debug)
+{
+ int x, y, z, w;
+ tree var, tmp;
+
+ /* Attempt to coalesce any items in a coalesce list. */
+ if (cl)
+ {
+ while (pop_best_coalesce (cl, &x, &y) != NO_BEST_COALESCE)
+ {
+ if (debug)
+ {
+ fprintf (debug, "Coalesce list: (%d)", x);
+ print_generic_expr (debug, partition_to_var (map, x), TDF_SLIM);
+ fprintf (debug, " & (%d)", y);
+ print_generic_expr (debug, partition_to_var (map, y), TDF_SLIM);
+ }
+
+ w = tpa_find_tree (tpa, x);
+ z = tpa_find_tree (tpa, y);
+ if (w != z || w == TPA_NONE || z == TPA_NONE)
+ {
+ if (debug)
+ {
+ if (w != z)
+ fprintf (debug, ": Fail, Non-matching TPA's\n");
+ if (w == TPA_NONE)
+ fprintf (debug, ": Fail %d non TPA.\n", x);
+ else
+ fprintf (debug, ": Fail %d non TPA.\n", y);
+ }
+ continue;
+ }
+ var = partition_to_var (map, x);
+ tmp = partition_to_var (map, y);
+ x = var_to_partition (map, var);
+ y = var_to_partition (map, tmp);
+ if (debug)
+ fprintf (debug, " [map: %d, %d] ", x, y);
+ if (x == y)
+ {
+ if (debug)
+ fprintf (debug, ": Already Coalesced.\n");
+ continue;
+ }
+ if (!conflict_graph_conflict_p (graph, x, y))
+ {
+ z = var_union (map, var, tmp);
+ if (z == NO_PARTITION)
+ {
+ if (debug)
+ fprintf (debug, ": Unable to perform partition union.\n");
+ continue;
+ }
+
+ /* z is the new combined partition. We need to remove the other
+ partition from the list. Set x to be that other partition. */
+ if (z == x)
+ {
+ conflict_graph_merge_regs (graph, x, y);
+ w = tpa_find_tree (tpa, y);
+ tpa_remove_partition (tpa, w, y);
+ }
+ else
+ {
+ conflict_graph_merge_regs (graph, y, x);
+ w = tpa_find_tree (tpa, x);
+ tpa_remove_partition (tpa, w, x);
+ }
+
+ if (debug)
+ fprintf (debug, ": Success -> %d\n", z);
+ }
+ else
+ if (debug)
+ fprintf (debug, ": Fail due to conflict\n");
+ }
+ /* If using a coalesce list, don't try to coalesce anything else. */
+ return;
+ }
+
+ for (x = 0; x < tpa_num_trees (tpa); x++)
+ {
+ while (tpa_first_partition (tpa, x) != TPA_NONE)
+ {
+ int p1, p2;
+ /* Coalesce first partition with anything that doesn't conflict. */
+ y = tpa_first_partition (tpa, x);
+ tpa_remove_partition (tpa, x, y);
+
+ var = partition_to_var (map, y);
+ /* p1 is the partition representative to which y belongs. */
+ p1 = var_to_partition (map, var);
+
+ for (z = tpa_next_partition (tpa, y);
+ z != TPA_NONE;
+ z = tpa_next_partition (tpa, z))
+ {
+ tmp = partition_to_var (map, z);
+ /* p2 is the partition representative to which z belongs. */
+ p2 = var_to_partition (map, tmp);
+ if (debug)
+ {
+ fprintf (debug, "Coalesce : ");
+ print_generic_expr (debug, var, TDF_SLIM);
+ fprintf (debug, " &");
+ print_generic_expr (debug, tmp, TDF_SLIM);
+ fprintf (debug, " (%d ,%d)", p1, p2);
+ }
+
+ /* If partitions are already merged, don't check for conflict. */
+ if (tmp == var)
+ {
+ tpa_remove_partition (tpa, x, z);
+ if (debug)
+ fprintf (debug, ": Already coalesced\n");
+ }
+ else
+ if (!conflict_graph_conflict_p (graph, p1, p2))
+ {
+ int v;
+ if (tpa_find_tree (tpa, y) == TPA_NONE
+ || tpa_find_tree (tpa, z) == TPA_NONE)
+ {
+ if (debug)
+ fprintf (debug, ": Fail non-TPA member\n");
+ continue;
+ }
+ if ((v = var_union (map, var, tmp)) == NO_PARTITION)
+ {
+ if (debug)
+ fprintf (debug, ": Fail cannot combine partitions\n");
+ continue;
+ }
+
+ tpa_remove_partition (tpa, x, z);
+ if (v == p1)
+ conflict_graph_merge_regs (graph, v, z);
+ else
+ {
+ /* Update the first partition's representative. */
+ conflict_graph_merge_regs (graph, v, y);
+ p1 = v;
+ }
+
+ /* The root variable of the partition may be changed
+ now. */
+ var = partition_to_var (map, p1);
+
+ if (debug)
+ fprintf (debug, ": Success -> %d\n", v);
+ }
+ else
+ if (debug)
+ fprintf (debug, ": Fail, Conflict\n");
+ }
+ }
+ }
+}
+
+
+/* Send debug info for coalesce list CL to file F. */
+
+void
+dump_coalesce_list (FILE *f, coalesce_list_p cl)
+{
+ partition_pair_p node;
+ int x, num;
+ tree var;
+
+ if (cl->add_mode)
+ {
+ fprintf (f, "Coalesce List:\n");
+ num = num_var_partitions (cl->map);
+ for (x = 0; x < num; x++)
+ {
+ node = cl->list[x];
+ if (node)
+ {
+ fprintf (f, "[");
+ print_generic_expr (f, partition_to_var (cl->map, x), TDF_SLIM);
+ fprintf (f, "] - ");
+ for ( ; node; node = node->next)
+ {
+ var = partition_to_var (cl->map, node->second_partition);
+ print_generic_expr (f, var, TDF_SLIM);
+ fprintf (f, "(%1d), ", node->cost);
+ }
+ fprintf (f, "\n");
+ }
+ }
+ }
+ else
+ {
+ fprintf (f, "Sorted Coalesce list:\n");
+ for (node = cl->list[0]; node; node = node->next)
+ {
+ fprintf (f, "(%d) ", node->cost);
+ var = partition_to_var (cl->map, node->first_partition);
+ print_generic_expr (f, var, TDF_SLIM);
+ fprintf (f, " : ");
+ var = partition_to_var (cl->map, node->second_partition);
+ print_generic_expr (f, var, TDF_SLIM);
+ fprintf (f, "\n");
+ }
+ }
+}
+
+
+/* Output tree_partition_associator object TPA to file F.. */
+
+void
+tpa_dump (FILE *f, tpa_p tpa)
+{
+ int x, i;
+
+ if (!tpa)
+ return;
+
+ for (x = 0; x < tpa_num_trees (tpa); x++)
+ {
+ print_generic_expr (f, tpa_tree (tpa, x), TDF_SLIM);
+ fprintf (f, " : (");
+ for (i = tpa_first_partition (tpa, x);
+ i != TPA_NONE;
+ i = tpa_next_partition (tpa, i))
+ {
+ fprintf (f, "(%d)",i);
+ print_generic_expr (f, partition_to_var (tpa->map, i), TDF_SLIM);
+ fprintf (f, " ");
+
+#ifdef ENABLE_CHECKING
+ if (tpa_find_tree (tpa, i) != x)
+ fprintf (f, "**find tree incorrectly set** ");
+#endif
+
+ }
+ fprintf (f, ")\n");
+ }
+ fflush (f);
+}
+
+
+/* Output partition map MAP to file F. */
+
+void
+dump_var_map (FILE *f, var_map map)
+{
+ int t;
+ unsigned x, y;
+ int p;
+
+ fprintf (f, "\nPartition map \n\n");
+
+ for (x = 0; x < map->num_partitions; x++)
+ {
+ if (map->compact_to_partition != NULL)
+ p = map->compact_to_partition[x];
+ else
+ p = x;
+
+ if (map->partition_to_var[p] == NULL_TREE)
+ continue;
+
+ t = 0;
+ for (y = 1; y < highest_ssa_version; y++)
+ {
+ p = partition_find (map->var_partition, y);
+ if (map->partition_to_compact)
+ p = map->partition_to_compact[p];
+ if (p == (int)x)
+ {
+ if (t++ == 0)
+ {
+ fprintf(f, "Partition %d (", x);
+ print_generic_expr (f, partition_to_var (map, p), TDF_SLIM);
+ fprintf (f, " - ");
+ }
+ fprintf (f, "%d ", y);
+ }
+ }
+ if (t != 0)
+ fprintf (f, ")\n");
+ }
+ fprintf (f, "\n");
+}
+
+
+/* Output live range info LIVE to file F, controlled by FLAG. */
+
+void
+dump_live_info (FILE *f, tree_live_info_p live, int flag)
+{
+ basic_block bb;
+ int i;
+ var_map map = live->map;
+
+ if ((flag & LIVEDUMP_ENTRY) && live->livein)
+ {
+ FOR_EACH_BB (bb)
+ {
+ fprintf (f, "\nLive on entry to BB%d : ", bb->index);
+ for (i = 0; i < num_var_partitions (map); i++)
+ {
+ if (bitmap_bit_p (live_entry_blocks (live, i), bb->index))
+ {
+ print_generic_expr (f, partition_to_var (map, i), TDF_SLIM);
+ fprintf (f, " ");
+ }
+ }
+ fprintf (f, "\n");
+ }
+ }
+
+ if ((flag & LIVEDUMP_EXIT) && live->liveout)
+ {
+ FOR_EACH_BB (bb)
+ {
+ fprintf (f, "\nLive on exit from BB%d : ", bb->index);
+ EXECUTE_IF_SET_IN_BITMAP (live->liveout[bb->index], 0, i,
+ {
+ print_generic_expr (f, partition_to_var (map, i), TDF_SLIM);
+ fprintf (f, " ");
+ });
+ fprintf (f, "\n");
+ }
+ }
+}
+
+/* Register partitions in MAP so that we can take VARS out of SSA form.
+ This requires a walk over all the PHI nodes and all the statements. */
+
+void
+register_ssa_partitions_for_vars (bitmap vars, var_map map)
+{
+ basic_block bb;
+
+ if (bitmap_first_set_bit (vars) >= 0)
+ {
+
+ /* Find every instance (SSA_NAME) of variables in VARs and
+ register a new partition for them. This requires examining
+ every statement and every PHI node once. */
+ FOR_EACH_BB (bb)
+ {
+ block_stmt_iterator bsi;
+ tree next;
+ tree phi;
+
+ /* Register partitions for SSA_NAMEs appearing in the PHI
+ nodes in this basic block.
+
+ Note we delete PHI nodes in this loop if they are
+ associated with virtual vars which are going to be
+ renamed. */
+ for (phi = phi_nodes (bb); phi; phi = next)
+ {
+ tree result = SSA_NAME_VAR (PHI_RESULT (phi));
+
+ next = TREE_CHAIN (phi);
+ if (bitmap_bit_p (vars, var_ann (result)->uid))
+ {
+ if (! is_gimple_reg (result))
+ remove_phi_node (phi, NULL_TREE, bb);
+ else
+ {
+ int i;
+
+ /* Register a partition for the result. */
+ register_ssa_partition (map, PHI_RESULT (phi), 0);
+
+ /* Register a partition for each argument as needed. */
+ for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ {
+ tree arg = PHI_ARG_DEF (phi, i);
+
+ if (TREE_CODE (arg) != SSA_NAME)
+ continue;
+ if (!bitmap_bit_p (vars,
+ var_ann (SSA_NAME_VAR (arg))->uid))
+ continue;
+
+ register_ssa_partition (map, arg, 1);
+ }
+ }
+ }
+ }
+
+ /* Now register partitions for SSA_NAMEs appearing in each
+ statement in this block. */
+ for (bsi = bsi_start (bb); ! bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ stmt_ann_t ann = stmt_ann (bsi_stmt (bsi));
+ use_optype uses = USE_OPS (ann);
+ def_optype defs = DEF_OPS (ann);
+ unsigned int i;
+
+ for (i = 0; i < NUM_USES (uses); i++)
+ {
+ tree op = USE_OP (uses, i);
+
+ if (TREE_CODE (op) == SSA_NAME
+ && bitmap_bit_p (vars, var_ann (SSA_NAME_VAR (op))->uid))
+ register_ssa_partition (map, op, 1);
+ }
+
+ for (i = 0; i < NUM_DEFS (defs); i++)
+ {
+ tree op = DEF_OP (defs, i);
+
+ if (TREE_CODE (op) == SSA_NAME
+ && bitmap_bit_p (vars,
+ var_ann (SSA_NAME_VAR (op))->uid))
+ register_ssa_partition (map, op, 0);
+ }
+ }
+ }
+ }
+}
+
diff --git a/gcc/tree-ssa-live.h b/gcc/tree-ssa-live.h
new file mode 100644
index 00000000000..30c33cfb84b
--- /dev/null
+++ b/gcc/tree-ssa-live.h
@@ -0,0 +1,748 @@
+/* Routines for liveness in SSA trees.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Andrew MacLeod <amacleod@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+#ifndef _TREE_SSA_LIVE_H
+#define _TREE_SSA_LIVE_H 1
+
+/* Used to create the variable mapping when we go out of SSA form. */
+typedef struct _var_map
+{
+ /* The partition of all variables. */
+ partition var_partition;
+
+ /* Vector for compacting partitions. */
+ int *partition_to_compact;
+ int *compact_to_partition;
+
+ /* Mapping of partition numbers to vars. */
+ tree *partition_to_var;
+
+ /* Current number of partitions. */
+ unsigned int num_partitions;
+
+ /* Original partition size. */
+ unsigned int partition_size;
+
+ /* Reference count, if required. */
+ int *ref_count;
+} *var_map;
+
+#define VAR_ANN_PARTITION(ann) (ann->partition)
+#define VAR_ANN_ROOT_INDEX(ann) (ann->root_index)
+
+#define NO_PARTITION -1
+
+/* Flags to pass to compact_var_map */
+
+#define VARMAP_NORMAL 0
+#define VARMAP_NO_SINGLE_DEFS 1
+
+/* Flags to pass to remove_ssa_form. */
+
+#define SSANORM_PERFORM_TER 0x1
+#define SSANORM_COMBINE_TEMPS 0x2
+#define SSANORM_REMOVE_ALL_PHIS 0x4
+#define SSANORM_COALESCE_PARTITIONS 0x8
+#define SSANORM_USE_COALESCE_LIST 0x10
+
+extern var_map init_var_map (int);
+extern void delete_var_map (var_map);
+extern void dump_var_map (FILE *, var_map);
+extern int var_union (var_map, tree, tree);
+extern void change_partition_var (var_map, tree, int);
+extern void compact_var_map (var_map, int);
+extern void remove_ssa_form (FILE *, var_map, int);
+extern void register_ssa_partitions_for_vars (bitmap vars, var_map map);
+extern tree make_ssa_temp (tree);
+
+static inline int num_var_partitions (var_map);
+static inline tree var_to_partition_to_var (var_map, tree);
+static inline tree partition_to_var (var_map, int);
+static inline int var_to_partition (var_map, tree);
+static inline tree version_to_var (var_map, int);
+static inline int version_ref_count (var_map, tree);
+static inline void register_ssa_partition (var_map, tree, bool);
+
+#define SSA_VAR_MAP_REF_COUNT 0x01
+extern var_map create_ssa_var_map (int);
+
+
+/* Number of partitions in MAP. */
+
+static inline int
+num_var_partitions (var_map map)
+{
+ return map->num_partitions;
+}
+
+
+/* Return the reference count for SSA_VAR's partition in MAP. */
+
+static inline int
+version_ref_count (var_map map, tree ssa_var)
+{
+ int version = SSA_NAME_VERSION (ssa_var);
+#ifdef ENABLE_CHECKING
+ if (!map->ref_count)
+ abort ();
+#endif
+ return map->ref_count[version];
+}
+
+
+/* Given partition index I from MAP, return the variable which represents that
+ partition. */
+
+static inline tree
+partition_to_var (var_map map, int i)
+{
+ if (map->compact_to_partition)
+ i = map->compact_to_partition[i];
+ i = partition_find (map->var_partition, i);
+ return map->partition_to_var[i];
+}
+
+
+/* Given ssa_name VERSION, if it has a partition in MAP, return the var it
+ is associated with. Otherwise return NULL. */
+
+static inline tree version_to_var (var_map map, int version)
+{
+ int part;
+ part = partition_find (map->var_partition, version);
+ if (map->partition_to_compact)
+ part = map->partition_to_compact[part];
+ if (part == NO_PARTITION)
+ return NULL_TREE;
+
+ return partition_to_var (map, part);
+}
+
+
+/* Given VAR, return the partition number in MAP which contains it.
+ NO_PARTITION is returned if its not in any partition. */
+
+static inline int
+var_to_partition (var_map map, tree var)
+{
+ var_ann_t ann;
+ int part;
+
+ if (TREE_CODE (var) == SSA_NAME)
+ {
+ part = partition_find (map->var_partition, SSA_NAME_VERSION (var));
+ if (map->partition_to_compact)
+ part = map->partition_to_compact[part];
+ }
+ else
+ {
+ ann = var_ann (var);
+ if (ann->out_of_ssa_tag)
+ part = VAR_ANN_PARTITION (ann);
+ else
+ part = NO_PARTITION;
+ }
+ return part;
+}
+
+
+/* Given VAR, return the variable which represents the entire partition
+ it is a member of in MAP. NULL is returned if it is not in a partition. */
+
+static inline tree
+var_to_partition_to_var (var_map map, tree var)
+{
+ int part;
+
+ part = var_to_partition (map, var);
+ if (part == NO_PARTITION)
+ return NULL_TREE;
+ return partition_to_var (map, part);
+}
+
+
+/* This routine registers a partition for SSA_VAR with MAP. IS_USE is used
+ to count references. Any unregistered partitions may be compacted out
+ later. */
+
+static inline void
+register_ssa_partition (var_map map, tree ssa_var, bool is_use)
+{
+ int version;
+
+#if defined ENABLE_CHECKING
+ if (TREE_CODE (ssa_var) != SSA_NAME)
+ abort ();
+
+ if (!is_gimple_reg (SSA_NAME_VAR (ssa_var)))
+ {
+ fprintf (stderr, "Illegally registering a virtual SSA name :");
+ print_generic_expr (stderr, ssa_var, TDF_SLIM);
+ fprintf (stderr, " in the SSA->Normal phase.\n");
+ abort();
+ }
+#endif
+
+ version = SSA_NAME_VERSION (ssa_var);
+ if (is_use && map->ref_count)
+ map->ref_count[version]++;
+
+ if (map->partition_to_var[version] == NULL_TREE)
+ map->partition_to_var[SSA_NAME_VERSION (ssa_var)] = ssa_var;
+}
+
+
+/* ---------------- live on entry/exit info ------------------------------
+
+ This structure is used to represent live range information on SSA based
+ trees. A partition map must be provided, and based on the active partitions,
+ live-on-entry information and live-on-exit information can be calculated.
+ As well, partitions are marked as to whether they are global (live
+ outside the basic block they are defined in).
+
+ The live-on-entry information is per variable. It provide a bitmap for
+ each variable which has a bit set for each basic block that the variable
+ is live on entry to that block.
+
+ The live-on-exit information is per block. It provides a bitmap for each
+ block indicating which partitions are live on exit from the block.
+
+ For the purposes of this implementation, we treat the elements of a PHI
+ as follows:
+
+ Uses in a PHI are considered LIVE-ON-EXIT to the block from which they
+ originate. They are *NOT* considered live on entry to the block
+ containing the PHI node.
+
+ The Def of a PHI node is *not* considered live on entry to the block.
+ It is considered to be "define early" in the block. Picture it as each
+ block having a stmt (or block-preheader) before the first real stmt in
+ the block which defines all the variables that are defined by PHIs.
+
+ ----------------------------------------------------------------------- */
+
+
+typedef struct tree_live_info_d
+{
+ /* Var map this relates to. */
+ var_map map;
+
+ /* Bitmap indicating which partitions are global. */
+ bitmap global;
+
+ /* Bitmap of live on entry blocks for partition elements. */
+ bitmap *livein;
+
+ /* Number of basic blocks when live on exit calculated. */
+ int num_blocks;
+
+ /* Bitmap of what variables are live on exit for a basic blocks. */
+ bitmap *liveout;
+} *tree_live_info_p;
+
+
+extern tree_live_info_p calculate_live_on_entry (var_map);
+extern void calculate_live_on_exit (tree_live_info_p);
+extern void delete_tree_live_info (tree_live_info_p);
+
+#define LIVEDUMP_ENTRY 0x01
+#define LIVEDUMP_EXIT 0x02
+#define LIVEDUMP_ALL (LIVEDUMP_ENTRY | LIVEDUMP_EXIT)
+extern void dump_live_info (FILE *, tree_live_info_p, int);
+
+static inline int partition_is_global (tree_live_info_p, int);
+static inline bitmap live_entry_blocks (tree_live_info_p, int);
+static inline bitmap live_on_exit (tree_live_info_p, basic_block);
+static inline var_map live_var_map (tree_live_info_p);
+static inline void live_merge_and_clear (tree_live_info_p, int, int);
+static inline void make_live_on_entry (tree_live_info_p, basic_block, int);
+
+
+/* Return TRUE if P is marked as a global in LIVE. */
+
+static inline int
+partition_is_global (tree_live_info_p live, int p)
+{
+ if (!live->global)
+ abort ();
+
+ return bitmap_bit_p (live->global, p);
+}
+
+
+/* Return the bitmap from LIVE representing the live on entry blocks for
+ partition P. */
+
+static inline bitmap
+live_entry_blocks (tree_live_info_p live, int p)
+{
+ if (!live->livein)
+ abort ();
+
+ return live->livein[p];
+}
+
+
+/* Return the bitmap from LIVE representing the live on exit partitions from
+ block BB. */
+
+static inline bitmap
+live_on_exit (tree_live_info_p live, basic_block bb)
+{
+ if (!live->liveout)
+ abort();
+
+ if (bb == ENTRY_BLOCK_PTR || bb == EXIT_BLOCK_PTR)
+ abort ();
+
+ return live->liveout[bb->index];
+}
+
+
+/* Return the partition map which the information in LIVE utilizes. */
+
+static inline var_map
+live_var_map (tree_live_info_p live)
+{
+ return live->map;
+}
+
+
+/* Merge the live on entry information in LIVE for partitions P1 and P2. Place
+ the result into P1. Clear P2. */
+
+static inline void
+live_merge_and_clear (tree_live_info_p live, int p1, int p2)
+{
+ bitmap_a_or_b (live->livein[p1], live->livein[p1], live->livein[p2]);
+ bitmap_zero (live->livein[p2]);
+}
+
+
+/* Mark partition P as live on entry to basic block BB in LIVE. */
+
+static inline void
+make_live_on_entry (tree_live_info_p live, basic_block bb , int p)
+{
+ bitmap_set_bit (live->livein[p], bb->index);
+ bitmap_set_bit (live->global, p);
+}
+
+
+/* A tree_partition_associator (TPA)object is a base structure which allows
+ partitions to be associated with a tree object.
+
+ A varray of tree elements represent each distinct tree item.
+ A parallel int array represents the first partition number associated with
+ the tree.
+ This partition number is then used as in index into the next_partition
+ array, which returns the index of the next partition which is associated
+ with the tree. TPA_NONE indicates the end of the list.
+ A varray paralleling the partition list 'partition_to_tree_map' is used
+ to indicate which tree index the partition is in. */
+
+typedef struct tree_partition_associator_d
+{
+ varray_type trees;
+ varray_type first_partition;
+ int *next_partition;
+ int *partition_to_tree_map;
+ int num_trees;
+ int uncompressed_num;
+ var_map map;
+} *tpa_p;
+
+/* Value returned when there are no more partitions associated with a tree. */
+#define TPA_NONE -1
+
+static inline tree tpa_tree (tpa_p, int);
+static inline int tpa_first_partition (tpa_p, int);
+static inline int tpa_next_partition (tpa_p, int);
+static inline int tpa_num_trees (tpa_p);
+static inline int tpa_find_tree (tpa_p, int);
+static inline void tpa_decompact (tpa_p);
+extern tpa_p tpa_init (var_map);
+extern void tpa_delete (tpa_p);
+extern void tpa_dump (FILE *, tpa_p);
+extern void tpa_remove_partition (tpa_p, int, int);
+extern int tpa_compact (tpa_p);
+
+
+/* Return the number of distinct tree nodes in TPA. */
+
+static inline int
+tpa_num_trees (tpa_p tpa)
+{
+ return tpa->num_trees;
+}
+
+
+/* Return the tree node for index I in TPA. */
+
+static inline tree
+tpa_tree (tpa_p tpa, int i)
+{
+ return VARRAY_TREE (tpa->trees, i);
+}
+
+
+/* Return the first partition associated with tree list I in TPA. */
+
+static inline int
+tpa_first_partition (tpa_p tpa, int i)
+{
+ return VARRAY_INT (tpa->first_partition, i);
+}
+
+
+/* Return the next partition after partition I in TPA's list. */
+
+static inline int
+tpa_next_partition (tpa_p tpa, int i)
+{
+ return tpa->next_partition[i];
+}
+
+
+/* Return the tree index from TPA whose list contains partition I.
+ TPA_NONE is returned if I is not associated with any list. */
+
+static inline int
+tpa_find_tree (tpa_p tpa, int i)
+{
+ int index;
+
+ index = tpa->partition_to_tree_map[i];
+ /* When compressed, any index higher than the number of tree elements is
+ a compressed element, so return TPA_NONE. */
+ if (index != TPA_NONE && index >= tpa_num_trees (tpa))
+ {
+#ifdef ENABLE_CHECKING
+ if (tpa->uncompressed_num == -1)
+ abort ();
+#endif
+ index = TPA_NONE;
+ }
+
+ return index;
+}
+
+
+/* This function removes any compaction which was performed on TPA. */
+
+static inline void
+tpa_decompact(tpa_p tpa)
+{
+#ifdef ENABLE_CHECKING
+ if (tpa->uncompressed_num == -1)
+ abort ();
+#endif
+ tpa->num_trees = tpa->uncompressed_num;
+}
+
+
+/* Once a var_map has been created and compressed, a complimentary root_var
+ object can be built. This creates a list of all the root variables from
+ which ssa version names are derived. Each root variable has a list of
+ which partitions are versions of that root.
+
+ This is implemented using the tree_partition_associator.
+
+ The tree vector is used to represent the root variable.
+ The list of partitions represent SSA versions of the root variable. */
+
+typedef tpa_p root_var_p;
+
+static inline tree root_var (root_var_p, int);
+static inline int root_var_first_partition (root_var_p, int);
+static inline int root_var_next_partition (root_var_p, int);
+static inline int root_var_num (root_var_p);
+static inline void root_var_dump (FILE *, root_var_p);
+static inline void root_var_remove_partition (root_var_p, int, int);
+static inline void root_var_delete (root_var_p);
+static inline int root_var_find (root_var_p, int);
+static inline int root_var_compact (root_var_p);
+static inline void root_var_decompact (tpa_p);
+
+extern root_var_p root_var_init (var_map);
+
+/* Value returned when there are no more partitions associated with a root
+ variable. */
+#define ROOT_VAR_NONE TPA_NONE
+
+
+/* Return the number of distinct root variables in RV. */
+
+static inline int
+root_var_num (root_var_p rv)
+{
+ return tpa_num_trees (rv);
+}
+
+
+/* Return root variable I from RV. */
+
+static inline tree
+root_var (root_var_p rv, int i)
+{
+ return tpa_tree (rv, i);
+}
+
+
+/* Return the first partition in RV belonging to root variable list I. */
+
+static inline int
+root_var_first_partition (root_var_p rv, int i)
+{
+ return tpa_first_partition (rv, i);
+}
+
+
+/* Return the next partition after partition I in a root list from RV. */
+
+static inline int
+root_var_next_partition (root_var_p rv, int i)
+{
+ return tpa_next_partition (rv, i);
+}
+
+
+/* Send debug info for root_var list RV to file F. */
+
+static inline void
+root_var_dump (FILE *f, root_var_p rv)
+{
+ fprintf (f, "\nRoot Var dump\n");
+ tpa_dump (f, rv);
+ fprintf (f, "\n");
+}
+
+
+/* Destroy root_var object RV. */
+
+static inline void
+root_var_delete (root_var_p rv)
+{
+ tpa_delete (rv);
+}
+
+
+/* Remove partition PARTITION_INDEX from root_var list ROOT_INDEX in RV. */
+
+static inline void
+root_var_remove_partition (root_var_p rv, int root_index, int partition_index)
+{
+ tpa_remove_partition (rv, root_index, partition_index);
+}
+
+
+/* Return the root_var list index for partition I in RV. */
+
+static inline int
+root_var_find (root_var_p rv, int i)
+{
+ return tpa_find_tree (rv, i);
+}
+
+
+/* Hide single element lists in RV. */
+
+static inline int
+root_var_compact (root_var_p rv)
+{
+ return tpa_compact (rv);
+}
+
+
+/* Expose the single element lists in RV. */
+
+static inline void
+root_var_decompact (root_var_p rv)
+{
+ tpa_decompact (rv);
+}
+
+
+/* A TYPE_VAR object is similar to a root_var object, except this associates
+ partitions with their type rather than their root variable. This is used to
+ coalesce memory locations based on type. */
+
+typedef tpa_p type_var_p;
+
+static inline tree type_var (type_var_p, int);
+static inline int type_var_first_partition (type_var_p, int);
+static inline int type_var_next_partition (type_var_p, int);
+static inline int type_var_num (type_var_p);
+static inline void type_var_dump (FILE *, type_var_p);
+static inline void type_var_remove_partition (type_var_p, int, int);
+static inline void type_var_delete (type_var_p);
+static inline int type_var_find (type_var_p, int);
+static inline int type_var_compact (type_var_p);
+static inline void type_var_decompact (type_var_p);
+
+extern type_var_p type_var_init (var_map);
+
+/* Value returned when there is no partitions associated with a list. */
+#define TYPE_VAR_NONE TPA_NONE
+
+
+/* Return the number of distinct type lists in TV. */
+
+static inline int
+type_var_num (type_var_p tv)
+{
+ return tpa_num_trees (tv);
+}
+
+
+/* Return the type of list I in TV. */
+
+static inline tree
+type_var (type_var_p tv, int i)
+{
+ return tpa_tree (tv, i);
+}
+
+
+/* Return the first partition belonging to type list I in TV. */
+
+static inline int
+type_var_first_partition (type_var_p tv, int i)
+{
+ return tpa_first_partition (tv, i);
+}
+
+
+/* Return the next partition after partition I in a type list within TV. */
+
+static inline int
+type_var_next_partition (type_var_p tv, int i)
+{
+ return tpa_next_partition (tv, i);
+}
+
+
+/* Send debug info for type_var object TV to file F. */
+
+static inline void
+type_var_dump (FILE *f, type_var_p tv)
+{
+ fprintf (f, "\nType Var dump\n");
+ tpa_dump (f, tv);
+ fprintf (f, "\n");
+}
+
+
+/* Delete type_var object TV. */
+
+static inline void
+type_var_delete (type_var_p tv)
+{
+ tpa_delete (tv);
+}
+
+
+/* Remove partition PARTITION_INDEX from type list TYPE_INDEX in TV. */
+
+static inline void
+type_var_remove_partition (type_var_p tv, int type_index, int partition_index)
+{
+ tpa_remove_partition (tv, type_index, partition_index);
+}
+
+
+/* Return the type index in TV for the list partition I is in. */
+
+static inline int
+type_var_find (type_var_p tv, int i)
+{
+ return tpa_find_tree (tv, i);
+}
+
+
+/* Hide single element lists in TV. */
+
+static inline int
+type_var_compact (type_var_p tv)
+{
+ return tpa_compact (tv);
+}
+
+
+/* Expose single element lists in TV. */
+
+static inline void
+type_var_decompact (type_var_p tv)
+{
+ tpa_decompact (tv);
+}
+
+/* This set of routines implements a coalesce_list. This is an object which
+ is used to track pairs of partitions which are desirable to coalesce
+ together at some point. Costs are associated with each pair, and when
+ all desired information has been collected, the object can be used to
+ order the pairs for processing. */
+
+/* This structure defines a pair for coalescing. */
+
+typedef struct partition_pair_d
+{
+ int first_partition;
+ int second_partition;
+ int cost;
+ struct partition_pair_d *next;
+} *partition_pair_p;
+
+/* This structure maintains the list of coalesce pairs.
+ When add_mode is true, list is a triangular shaped list of coalesce pairs.
+ The smaller partition number is used to index the list, and the larger is
+ index is located in a partition_pair_p object. These lists are sorted from
+ smallest to largest by 'second_partition'. New coalesce pairs are allowed
+ to be added in this mode.
+ When add_mode is false, the lists have all been merged into list[0]. The
+ rest of the lists are not used. list[0] is ordered from most desirable
+ coalesce to least desirable. pop_best_coalesce() retrieves the pairs
+ one at a time. */
+
+typedef struct coalesce_list_d
+{
+ var_map map;
+ partition_pair_p *list;
+ bool add_mode;
+} *coalesce_list_p;
+
+extern coalesce_list_p create_coalesce_list (var_map);
+extern void add_coalesce (coalesce_list_p, int, int, int);
+extern void sort_coalesce_list (coalesce_list_p);
+extern void dump_coalesce_list (FILE *, coalesce_list_p);
+extern void delete_coalesce_list (coalesce_list_p);
+
+#define NO_BEST_COALESCE -1
+extern int pop_best_coalesce (coalesce_list_p, int *, int *);
+
+extern conflict_graph build_tree_conflict_graph (tree_live_info_p, tpa_p,
+ coalesce_list_p);
+extern void coalesce_tpa_members (tpa_p tpa, conflict_graph graph, var_map map,
+ coalesce_list_p cl, FILE *);
+
+
+#endif /* _TREE_SSA_LIVE_H */
diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c
new file mode 100644
index 00000000000..c35b6a9633c
--- /dev/null
+++ b/gcc/tree-ssa-loop.c
@@ -0,0 +1,365 @@
+/* Loop optimizations over tree-ssa.
+ Copyright (C) 2003 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 2, or (at your option) any
+later version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "output.h"
+#include "diagnostic.h"
+#include "basic-block.h"
+#include "tree-flow.h"
+#include "tree-dump.h"
+#include "tree-pass.h"
+#include "timevar.h"
+#include "cfgloop.h"
+#include "flags.h"
+#include "tree-inline.h"
+
+
+/* Check whether we should duplicate HEADER of LOOP. At most *LIMIT
+ instructions should be duplicated, limit is decreased by the actual
+ amount. */
+
+static bool
+should_duplicate_loop_header_p (basic_block header, struct loop *loop,
+ int *limit)
+{
+ block_stmt_iterator bsi;
+ tree last;
+
+ /* Do not copy one block more than once (we do not really want to do
+ loop peeling here). */
+ if (header->aux)
+ return false;
+
+ if (!header->succ)
+ abort ();
+ if (!header->succ->succ_next)
+ return false;
+ if (header->succ->succ_next->succ_next)
+ return false;
+ if (flow_bb_inside_loop_p (loop, header->succ->dest)
+ && flow_bb_inside_loop_p (loop, header->succ->succ_next->dest))
+ return false;
+
+ /* If this is not the original loop header, we want it to have just
+ one predecessor in order to match the && pattern. */
+ if (header != loop->header
+ && header->pred->pred_next)
+ return false;
+
+ last = last_stmt (header);
+ if (TREE_CODE (last) != COND_EXPR)
+ return false;
+
+ /* Approximately copy the conditions that used to be used in jump.c --
+ at most 20 insns and no calls. */
+ for (bsi = bsi_start (header); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ last = bsi_stmt (bsi);
+
+ if (TREE_CODE (last) == LABEL_EXPR)
+ continue;
+
+ if (get_call_expr_in (last))
+ return false;
+
+ *limit -= estimate_num_insns (last);
+ if (*limit < 0)
+ return false;
+ }
+
+ return true;
+}
+
+/* Marks variables defined in basic block BB for rewriting. */
+
+static void
+mark_defs_for_rewrite (basic_block bb)
+{
+ tree stmt, var;
+ block_stmt_iterator bsi;
+ stmt_ann_t ann;
+ def_optype defs;
+ vdef_optype vdefs;
+ vuse_optype vuses;
+ unsigned i;
+
+ for (stmt = phi_nodes (bb); stmt; stmt = TREE_CHAIN (stmt))
+ {
+ var = SSA_NAME_VAR (PHI_RESULT (stmt));
+ bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
+
+ /* If we have a type_mem_tag, add it as well. Due to rewriting the
+ variable out of ssa, we lose its name tag, so we use type_mem_tag
+ instead. */
+ var = var_ann (var)->type_mem_tag;
+ if (var)
+ bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
+ }
+
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ stmt = bsi_stmt (bsi);
+ get_stmt_operands (stmt);
+ ann = stmt_ann (stmt);
+
+ defs = DEF_OPS (ann);
+ for (i = 0; i < NUM_DEFS (defs); i++)
+ {
+ var = SSA_NAME_VAR (DEF_OP (defs, i));
+ bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
+
+ /* If we have a type_mem_tag, add it as well. Due to rewriting the
+ variable out of ssa, we lose its name tag, so we use type_mem_tag
+ instead. */
+ var = var_ann (var)->type_mem_tag;
+ if (var)
+ bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
+ }
+
+ vdefs = VDEF_OPS (ann);
+ for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ {
+ var = SSA_NAME_VAR (VDEF_RESULT (vdefs, i));
+ bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
+ }
+
+ /* We also need to rewrite vuses, since we will copy the statements
+ and the ssa versions could not be recovered in the copy. We do
+ not have to do this for operands of VDEFS explicitly, since
+ they have the same underlying variable as the results. */
+ vuses = VUSE_OPS (ann);
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ {
+ var = SSA_NAME_VAR (VUSE_OP (vuses, i));
+ bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
+ }
+ }
+}
+
+/* Duplicates destinations of edges in BBS_TO_DUPLICATE. */
+
+static void
+duplicate_blocks (varray_type bbs_to_duplicate)
+{
+ unsigned i;
+ edge preheader_edge, e, e1;
+ basic_block header, new_header;
+ tree phi;
+ size_t old_num_referenced_vars = num_referenced_vars;
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (bbs_to_duplicate); i++)
+ {
+ preheader_edge = VARRAY_GENERIC_PTR_NOGC (bbs_to_duplicate, i);
+ header = preheader_edge->dest;
+
+ /* It is sufficient to rewrite the definitions, since the uses of
+ the operands defined outside of the duplicated basic block are
+ still valid (every basic block that dominates the original block
+ also dominates the duplicate). */
+ mark_defs_for_rewrite (header);
+ }
+
+ rewrite_vars_out_of_ssa (vars_to_rename);
+
+ for (i = old_num_referenced_vars; i < num_referenced_vars; i++)
+ {
+ bitmap_set_bit (vars_to_rename, i);
+ var_ann (referenced_var (i))->out_of_ssa_tag = 0;
+ }
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (bbs_to_duplicate); i++)
+ {
+ preheader_edge = VARRAY_GENERIC_PTR_NOGC (bbs_to_duplicate, i);
+ header = preheader_edge->dest;
+
+ /* We might have split the edge into the loop header when we have
+ eliminated the phi nodes, so find the edge to that we want to
+ copy the header. */
+ while (!header->aux)
+ {
+ preheader_edge = header->succ;
+ header = preheader_edge->dest;
+ }
+ header->aux = NULL;
+
+ new_header = duplicate_block (header, preheader_edge);
+
+ /* Add the phi arguments to the outgoing edges. */
+ for (e = header->succ; e; e = e->succ_next)
+ {
+ for (e1 = new_header->succ; e1->dest != e->dest; e1 = e1->succ_next)
+ continue;
+
+ for (phi = phi_nodes (e->dest); phi; phi = TREE_CHAIN (phi))
+ {
+ tree def = phi_element_for_edge (phi, e)->def;
+ add_phi_arg (&phi, def, e1);
+ }
+ }
+ }
+}
+
+/* Checks whether LOOP is a do-while style loop. */
+
+static bool
+do_while_loop_p (struct loop *loop)
+{
+ tree stmt = last_stmt (loop->latch);
+
+ /* If the latch of the loop is not empty, it is not a do-while loop. */
+ if (stmt
+ && TREE_CODE (stmt) != LABEL_EXPR)
+ return false;
+
+ /* If the header contains just a condition, it is not a do-while loop. */
+ stmt = last_and_only_stmt (loop->header);
+ if (stmt
+ && TREE_CODE (stmt) == COND_EXPR)
+ return false;
+
+ return true;
+}
+
+/* For all loops, copy the condition at the end of the loop body in front
+ of the loop. This is beneficial since it increases effectivity of
+ code motion optimizations. It also saves one jump on entry to the loop. */
+
+static void
+copy_loop_headers (void)
+{
+ struct loops *loops;
+ unsigned i;
+ struct loop *loop;
+ basic_block header;
+ edge preheader_edge;
+ varray_type bbs_to_duplicate = NULL;
+
+ loops = loop_optimizer_init (dump_file);
+ if (!loops)
+ return;
+
+ /* We are not going to need or update dominators. */
+ free_dominance_info (CDI_DOMINATORS);
+
+ create_preheaders (loops, CP_SIMPLE_PREHEADERS);
+
+ /* We do not try to keep the information about irreductible regions
+ up-to-date. */
+ loops->state &= ~LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS;
+
+#ifdef ENABLE_CHECKING
+ verify_loop_structure (loops);
+#endif
+
+ for (i = 1; i < loops->num; i++)
+ {
+ /* Copy at most 20 insns. */
+ int limit = 20;
+
+ loop = loops->parray[i];
+ preheader_edge = loop_preheader_edge (loop);
+ header = preheader_edge->dest;
+
+ /* If the loop is already a do-while style one (either because it was
+ written as such, or because jump threading transformed it into one),
+ we might be in fact peeling the first iteration of the loop. This
+ in general is not a good idea. */
+ if (do_while_loop_p (loop))
+ continue;
+
+ /* Iterate the header copying up to limit; this takes care of the cases
+ like while (a && b) {...}, where we want to have both of the conditions
+ copied. TODO -- handle while (a || b) - like cases, by not requiring
+ the header to have just a single successor and copying up to
+ postdominator.
+
+ We do not really copy the blocks immediately, so that we do not have
+ to worry about updating loop structures, and also so that we do not
+ have to rewrite variables out of and into ssa form for each block.
+ Instead we just record the block into worklist and duplicate all of
+ them at once. */
+ while (should_duplicate_loop_header_p (header, loop, &limit))
+ {
+ if (!bbs_to_duplicate)
+ VARRAY_GENERIC_PTR_NOGC_INIT (bbs_to_duplicate, 10,
+ "bbs_to_duplicate");
+ VARRAY_PUSH_GENERIC_PTR_NOGC (bbs_to_duplicate, preheader_edge);
+ header->aux = &header->aux;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ "Scheduled basic block %d for duplication.\n",
+ header->index);
+
+ /* Find a successor of header that is inside a loop; i.e. the new
+ header after the condition is copied. */
+ if (flow_bb_inside_loop_p (loop, header->succ->dest))
+ preheader_edge = header->succ;
+ else
+ preheader_edge = header->succ->succ_next;
+ header = preheader_edge->dest;
+ }
+ }
+
+ loop_optimizer_finalize (loops, NULL);
+
+ if (bbs_to_duplicate)
+ {
+ duplicate_blocks (bbs_to_duplicate);
+ VARRAY_FREE (bbs_to_duplicate);
+ }
+
+ /* Run cleanup_tree_cfg here regardless of whether we have done anything, so
+ that we cleanup the blocks created in order to get the loops into a
+ canonical shape. */
+ cleanup_tree_cfg ();
+}
+
+static bool
+gate_ch (void)
+{
+ return flag_tree_ch != 0;
+}
+
+struct tree_opt_pass pass_ch =
+{
+ "ch", /* name */
+ gate_ch, /* gate */
+ copy_loop_headers, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_CH, /* tv_id */
+ PROP_cfg | PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ (TODO_rename_vars
+ | TODO_dump_func
+ | TODO_verify_ssa) /* todo_flags_finish */
+};
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
new file mode 100644
index 00000000000..de5b16d1fd4
--- /dev/null
+++ b/gcc/tree-ssa-operands.c
@@ -0,0 +1,1318 @@
+/* SSA operands management for trees.
+ Copyright (C) 2003 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 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "flags.h"
+#include "function.h"
+#include "diagnostic.h"
+#include "tree-flow.h"
+#include "tree-inline.h"
+#include "tree-pass.h"
+#include "ggc.h"
+#include "timevar.h"
+
+/* Flags to describe operand properties in get_stmt_operands and helpers. */
+
+/* By default, operands are loaded. */
+#define opf_none 0
+
+/* Operand is the target of an assignment expression. */
+#define opf_is_def (1 << 0)
+
+/* No virtual operands should be created in the expression. This is used
+ when traversing ADDR_EXPR nodes which have different semantics than
+ other expressions. Inside an ADDR_EXPR node, the only operands that we
+ need to consider are indices into arrays. For instance, &a.b[i] should
+ generate a USE of 'i' but it should not generate a VUSE for 'a' nor a
+ VUSE for 'b'. */
+#define opf_no_vops (1 << 1)
+
+/* Array for building all the def operands. */
+static GTY (()) varray_type build_defs;
+
+/* Array for building all the use operands. */
+static GTY (()) varray_type build_uses;
+
+/* Array for building all the vdef operands. */
+static GTY (()) varray_type build_vdefs;
+
+/* Array for building all the vuse operands. */
+static GTY (()) varray_type build_vuses;
+
+#ifdef ENABLE_CHECKING
+tree check_build_stmt;
+#endif
+
+typedef struct voperands_d
+{
+ vdef_optype vdef_ops;
+ vuse_optype vuse_ops;
+} *voperands_t;
+
+static void note_addressable (tree, stmt_ann_t);
+static void get_expr_operands (tree, tree *, int, voperands_t);
+static inline void append_def (tree *, tree);
+static inline void append_use (tree *, tree);
+static void append_vdef (tree, tree, voperands_t);
+static void add_call_clobber_ops (tree, voperands_t);
+static void add_call_read_ops (tree, voperands_t);
+static void add_stmt_operand (tree *, tree, int, voperands_t);
+
+
+struct freelist_d GTY((chain_next ("%h.next")))
+{
+ struct freelist_d *next;
+};
+
+#define NUM_FREE 4
+static GTY ((length ("NUM_FREE"))) struct freelist_d optype_freelist[NUM_FREE] = { {0}, {0}, {0}, {0} };
+
+
+static inline void *
+check_optype_freelist (size_t num ATTRIBUTE_UNUSED)
+{
+ return NULL;
+#if 0
+ void *vec = NULL;
+
+ if (num <= NUM_FREE && optype_freelist[num - 1].next)
+ {
+ vec = (void *)optype_freelist[num - 1].next;
+ optype_freelist[num - 1].next = optype_freelist[num - 1].next->next;
+ }
+ return vec;
+#endif
+}
+/* Return a vector of contiguous memory of a specified size. */
+
+
+static inline void
+add_optype_freelist (void *vec ATTRIBUTE_UNUSED, size_t size ATTRIBUTE_UNUSED)
+{
+#if 0
+ struct freelist_d *ptr;
+#ifdef ENABLE_CHECKING
+ if (size == 0)
+ abort ();
+#endif
+
+ /* if its bigger than one of our lists, simply let it go and let GC
+ collect it. */
+ if (size > NUM_FREE)
+ return;
+
+ ptr = vec;
+ ptr->next = optype_freelist[size - 1].next;;
+ optype_freelist[size - 1].next = ptr;
+#endif
+}
+
+
+static inline def_optype
+allocate_def_optype (unsigned num)
+{
+ def_optype def_ops;
+ unsigned size;
+ size = sizeof (struct def_optype_d) + sizeof (tree *) * (num - 1);
+ def_ops = check_optype_freelist (num);
+ if (!def_ops)
+ def_ops = ggc_alloc (size);
+ def_ops->num_defs = num;
+ return def_ops;
+}
+
+static inline use_optype
+allocate_use_optype (unsigned num)
+{
+ use_optype use_ops;
+ unsigned size;
+ size = sizeof (struct use_optype_d) + sizeof (tree *) * (num - 1);
+ use_ops = check_optype_freelist (num);
+ if (!use_ops)
+ use_ops = ggc_alloc (size);
+ use_ops->num_uses = num;
+ return use_ops;
+}
+
+static inline vdef_optype
+allocate_vdef_optype (unsigned num)
+{
+ vdef_optype vdef_ops;
+ unsigned size;
+ size = sizeof (struct vdef_optype_d) + sizeof (tree) * ((num * 2) - 1);
+ vdef_ops = check_optype_freelist (num * 2);
+ if (!vdef_ops)
+ vdef_ops = ggc_alloc (size);
+ vdef_ops->num_vdefs = num;
+ return vdef_ops;
+}
+
+static inline vuse_optype
+allocate_vuse_optype (unsigned num)
+{
+ vuse_optype vuse_ops;
+ unsigned size;
+ size = sizeof (struct vuse_optype_d) + sizeof (tree) * (num - 1);
+ vuse_ops = check_optype_freelist (num);
+ if (!vuse_ops)
+ vuse_ops = ggc_alloc (size);
+ vuse_ops->num_vuses = num;
+ return vuse_ops;
+}
+
+static inline void
+free_uses (use_optype *uses, bool dealloc)
+{
+ if (*uses)
+ {
+ if (dealloc)
+ add_optype_freelist (*uses, (*uses)->num_uses);
+ *uses = NULL;
+ }
+}
+
+static inline void
+free_defs (def_optype *defs, bool dealloc)
+{
+ if (*defs)
+ {
+ if (dealloc)
+ add_optype_freelist (*defs, (*defs)->num_defs);
+ *defs = NULL;
+ }
+}
+
+static inline void
+free_vuses (vuse_optype *vuses, bool dealloc)
+{
+ if (*vuses)
+ {
+ if (dealloc)
+ add_optype_freelist (*vuses, (*vuses)->num_vuses);
+ *vuses = NULL;
+ }
+}
+
+static inline void
+free_vdefs (vdef_optype *vdefs, bool dealloc)
+{
+ if (*vdefs)
+ {
+ if (dealloc)
+ add_optype_freelist (*vdefs, (*vdefs)->num_vdefs);
+ *vdefs = NULL;
+ }
+}
+
+void
+remove_vuses (tree stmt)
+{
+ stmt_ann_t ann;
+
+ ann = stmt_ann (stmt);
+ if (ann)
+ free_vuses (&(ann->vuse_ops), true);
+}
+
+void
+remove_vdefs (tree stmt)
+{
+ stmt_ann_t ann;
+
+ ann = stmt_ann (stmt);
+ if (ann)
+ free_vdefs (&(ann->vdef_ops), true);
+}
+
+
+void
+init_ssa_operands (void)
+{
+ int x;
+
+ VARRAY_TREE_PTR_INIT (build_defs, 5, "build defs");
+ VARRAY_TREE_PTR_INIT (build_uses, 10, "build uses");
+ VARRAY_TREE_INIT (build_vdefs, 10, "build vdefs");
+ VARRAY_TREE_INIT (build_vuses, 10, "build vuses");
+
+ for (x = 0; x < NUM_FREE; x++)
+ optype_freelist[x].next = NULL;
+}
+
+void
+fini_ssa_operands (void)
+{
+ int x;
+ for (x = 0; x < NUM_FREE; x++)
+ optype_freelist[x].next = NULL;
+}
+
+static void
+finalize_ssa_defs (tree stmt)
+{
+ unsigned num, x;
+ stmt_ann_t ann;
+ def_optype def_ops;
+
+ num = VARRAY_ACTIVE_SIZE (build_defs);
+ if (num == 0)
+ return;
+
+#ifdef ENABLE_CHECKING
+ /* There should only be a single real definition per assignment. */
+ if (TREE_CODE (stmt) == MODIFY_EXPR && num > 1)
+ abort ();
+#endif
+
+ def_ops = allocate_def_optype (num);
+ for (x = 0; x < num ; x++)
+ def_ops->defs[x] = VARRAY_TREE_PTR (build_defs, x);
+ VARRAY_POP_ALL (build_defs);
+
+ ann = stmt_ann (stmt);
+ ann->def_ops = def_ops;
+}
+
+static void
+finalize_ssa_uses (tree stmt)
+{
+ unsigned num, x;
+ use_optype use_ops;
+ stmt_ann_t ann;
+
+ num = VARRAY_ACTIVE_SIZE (build_uses);
+ if (num == 0)
+ return;
+
+#ifdef ENABLE_CHECKING
+ {
+ unsigned x;
+ /* If the pointer to the operand is the statement itself, something is
+ wrong. It means that we are pointing to a local variable (the
+ initial call to get_stmt_operands does not pass a pointer to a
+ statement). */
+ for (x = 0; x < num; x++)
+ if (*(VARRAY_TREE_PTR (build_uses, x)) == stmt)
+ abort ();
+ }
+#endif
+
+ use_ops = allocate_use_optype (num);
+ for (x = 0; x < num ; x++)
+ use_ops->uses[x] = VARRAY_TREE_PTR (build_uses, x);
+ VARRAY_POP_ALL (build_uses);
+
+ ann = stmt_ann (stmt);
+ ann->use_ops = use_ops;
+}
+
+static void
+finalize_ssa_vdefs (tree stmt)
+{
+ unsigned num, x;
+ vdef_optype vdef_ops;
+ stmt_ann_t ann;
+
+ num = VARRAY_ACTIVE_SIZE (build_vdefs);
+ if (num == 0)
+ return;
+
+#ifdef ENABLE_CHECKING
+ /* VDEFs must be entered in pairs of result/uses. */
+ if (num % 2 != 0)
+ abort();
+#endif
+
+ vdef_ops = allocate_vdef_optype (num / 2);
+ for (x = 0; x < num; x++)
+ vdef_ops->vdefs[x] = VARRAY_TREE (build_vdefs, x);
+ VARRAY_CLEAR (build_vdefs);
+
+ ann = stmt_ann (stmt);
+ ann->vdef_ops = vdef_ops;
+}
+
+static inline void
+finalize_ssa_vuses (tree stmt)
+{
+ unsigned num, x;
+ stmt_ann_t ann;
+ vuse_optype vuse_ops;
+ vdef_optype vdefs;
+
+#ifdef ENABLE_CHECKING
+ if (VARRAY_ACTIVE_SIZE (build_vdefs) > 0)
+ {
+ fprintf (stderr, "Please finalize VDEFs before finalize VUSES.\n");
+ abort ();
+ }
+#endif
+
+ num = VARRAY_ACTIVE_SIZE (build_vuses);
+ if (num == 0)
+ return;
+
+ /* Remove superfluous VUSE operands. If the statement already has a
+ VDEF operation for a variable 'a', then a VUSE for 'a' is not
+ needed because VDEFs imply a VUSE of the variable. For instance,
+ suppose that variable 'a' is aliased:
+
+ # VUSE <a_2>
+ # a_3 = VDEF <a_2>
+ a = a + 1;
+
+ The VUSE <a_2> is superfluous because it is implied by the VDEF
+ operation. */
+
+ ann = stmt_ann (stmt);
+ vdefs = VDEF_OPS (ann);
+ if (NUM_VDEFS (vdefs) > 0)
+ {
+ size_t i, j;
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (build_vuses); i++)
+ {
+ bool found = false;
+ for (j = 0; j < NUM_VDEFS (vdefs); j++)
+ {
+ tree vuse_var, vdef_var;
+ tree vuse = VARRAY_TREE (build_vuses, i);
+ tree vdef = VDEF_OP (vdefs, j);
+
+ if (TREE_CODE (vuse) == SSA_NAME)
+ vuse_var = SSA_NAME_VAR (vuse);
+ else
+ vuse_var = vuse;
+
+ if (TREE_CODE (vdef) == SSA_NAME)
+ vdef_var = SSA_NAME_VAR (vdef);
+ else
+ vdef_var = vdef;
+
+ if (vuse_var == vdef_var)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ /* If we found a useless VUSE operand, remove it from the
+ operand array by replacing it with the last active element
+ in the operand array (unless the useless VUSE was the
+ last operand, in which case we simply remove it. */
+ if (found)
+ {
+ if (i != VARRAY_ACTIVE_SIZE (build_vuses) - 1)
+ {
+ VARRAY_TREE (build_vuses, i)
+ = VARRAY_TREE (build_vuses,
+ VARRAY_ACTIVE_SIZE (build_vuses) - 1);
+ }
+ VARRAY_POP (build_vuses);
+
+ /* We want to rescan the element at this index, unless
+ this was the last element, in which case the loop
+ terminates. */
+ i--;
+ }
+ }
+ }
+
+ num = VARRAY_ACTIVE_SIZE (build_vuses);
+ /* We could have reduced the size to zero now, however. */
+ if (num == 0)
+ return;
+
+ vuse_ops = allocate_vuse_optype (num);
+ for (x = 0; x < num; x++)
+ vuse_ops->vuses[x] = VARRAY_TREE (build_vuses, x);
+ VARRAY_CLEAR (build_vuses);
+ ann->vuse_ops = vuse_ops;
+}
+
+extern void
+finalize_ssa_stmt_operands (tree stmt)
+{
+#ifdef ENABLE_CHECKING
+ if (check_build_stmt == NULL)
+ abort();
+#endif
+
+ finalize_ssa_defs (stmt);
+ finalize_ssa_uses (stmt);
+ finalize_ssa_vdefs (stmt);
+ finalize_ssa_vuses (stmt);
+
+#ifdef ENABLE_CHECKING
+ check_build_stmt = NULL;
+#endif
+}
+
+
+extern void
+verify_start_operands (tree stmt ATTRIBUTE_UNUSED)
+{
+#ifdef ENABLE_CHECKING
+ if (VARRAY_ACTIVE_SIZE (build_defs) > 0
+ || VARRAY_ACTIVE_SIZE (build_uses) > 0
+ || VARRAY_ACTIVE_SIZE (build_vuses) > 0
+ || VARRAY_ACTIVE_SIZE (build_vdefs) > 0)
+ abort ();
+ if (check_build_stmt != NULL)
+ abort();
+ check_build_stmt = stmt;
+#endif
+}
+
+
+/* Add DEF_P to the list of pointers to operands defined by STMT. */
+
+static inline void
+append_def (tree *def_p, tree stmt ATTRIBUTE_UNUSED)
+{
+#ifdef ENABLE_CHECKING
+ if (check_build_stmt != stmt)
+ abort();
+#endif
+ VARRAY_PUSH_TREE_PTR (build_defs, def_p);
+}
+
+
+/* Add USE_P to the list of pointers to operands used by STMT. */
+
+static inline void
+append_use (tree *use_p, tree stmt ATTRIBUTE_UNUSED)
+{
+#ifdef ENABLE_CHECKING
+ if (check_build_stmt != stmt)
+ abort();
+#endif
+ VARRAY_PUSH_TREE_PTR (build_uses, use_p);
+}
+
+
+/* Add a new virtual def for variable VAR to statement STMT. If PREV_VOPS
+ is not NULL, the existing entries are preserved and no new entries are
+ added here. This is done to preserve the SSA numbering of virtual
+ operands. */
+
+static void
+append_vdef (tree var, tree stmt, voperands_t prev_vops)
+{
+ stmt_ann_t ann;
+ size_t i;
+ tree result, source;
+
+#ifdef ENABLE_CHECKING
+ if (check_build_stmt != stmt)
+ abort();
+#endif
+
+ ann = stmt_ann (stmt);
+
+ /* Don't allow duplicate entries. */
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (build_vdefs); i += 2)
+ {
+ tree result = VARRAY_TREE (build_vdefs, i);
+ if (var == result
+ || (TREE_CODE (result) == SSA_NAME
+ && var == SSA_NAME_VAR (result)))
+ return;
+ }
+
+ /* If the statement already had virtual definitions, see if any of the
+ existing VDEFs matches VAR. If so, re-use it, otherwise add a new
+ VDEF for VAR. */
+ result = NULL_TREE;
+ source = NULL_TREE;
+ if (prev_vops)
+ for (i = 0; i < NUM_VDEFS (prev_vops->vdef_ops); i++)
+ {
+ result = VDEF_RESULT (prev_vops->vdef_ops, i);
+ if (result == var
+ || (TREE_CODE (result) == SSA_NAME
+ && SSA_NAME_VAR (result) == var))
+ {
+ source = VDEF_OP (prev_vops->vdef_ops, i);
+ break;
+ }
+ }
+
+ /* If no previous VDEF operand was found for VAR, create one now. */
+ if (source == NULL_TREE)
+ {
+ result = var;
+ source = var;
+ }
+
+ VARRAY_PUSH_TREE (build_vdefs, result);
+ VARRAY_PUSH_TREE (build_vdefs, source);
+}
+
+
+/* Add VAR to the list of virtual uses for STMT. If PREV_VOPS
+ is not NULL, the existing entries are preserved and no new entries are
+ added here. This is done to preserve the SSA numbering of virtual
+ operands. */
+
+static void
+append_vuse (tree var, tree stmt, voperands_t prev_vops)
+{
+ stmt_ann_t ann;
+ size_t i;
+ bool found;
+ tree vuse;
+
+#ifdef ENABLE_CHECKING
+ if (check_build_stmt != stmt)
+ abort();
+#endif
+
+ ann = stmt_ann (stmt);
+
+ /* Don't allow duplicate entries. */
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (build_vuses); i++)
+ {
+ tree vuse_var = VARRAY_TREE (build_vuses, i);
+ if (var == vuse_var
+ || (TREE_CODE (vuse_var) == SSA_NAME
+ && var == SSA_NAME_VAR (vuse_var)))
+ return;
+ }
+
+ /* If the statement already had virtual uses, see if any of the
+ existing VUSEs matches VAR. If so, re-use it, otherwise add a new
+ VUSE for VAR. */
+ found = false;
+ vuse = NULL_TREE;
+ if (prev_vops)
+ for (i = 0; i < NUM_VUSES (prev_vops->vuse_ops); i++)
+ {
+ vuse = VUSE_OP (prev_vops->vuse_ops, i);
+ if (vuse == var
+ || (TREE_CODE (vuse) == SSA_NAME
+ && SSA_NAME_VAR (vuse) == var))
+ {
+ found = true;
+ break;
+ }
+ }
+
+ /* If VAR existed already in PREV_VOPS, re-use it. */
+ if (found)
+ var = vuse;
+
+ VARRAY_PUSH_TREE (build_vuses, var);
+}
+
+
+/* External entry point which by-passes the previous vops mechanism. */
+void
+add_vuse (tree var, tree stmt)
+{
+ append_vuse (var, stmt, NULL);
+}
+
+
+/* Get the operands of statement STMT. Note that repeated calls to
+ get_stmt_operands for the same statement will do nothing until the
+ statement is marked modified by a call to modify_stmt(). */
+
+void
+get_stmt_operands (tree stmt)
+{
+ enum tree_code code;
+ stmt_ann_t ann;
+ struct voperands_d prev_vops;
+
+#if defined ENABLE_CHECKING
+ /* The optimizers cannot handle statements that are nothing but a
+ _DECL. This indicates a bug in the gimplifier. */
+ if (SSA_VAR_P (stmt))
+ abort ();
+#endif
+
+ /* Ignore error statements. */
+ if (TREE_CODE (stmt) == ERROR_MARK)
+ return;
+
+ ann = get_stmt_ann (stmt);
+
+ /* If the statement has not been modified, the operands are still valid. */
+ if (!ann->modified)
+ return;
+
+ timevar_push (TV_TREE_OPS);
+
+ /* Initially assume that the statement has no volatile operands.
+ Statements marked with 'has_volatile_ops' are not processed by the
+ optimizers. */
+ ann->has_volatile_ops = false;
+
+ /* Remove any existing operands as they will be scanned again. */
+ free_defs (&(ann->def_ops), true);
+ free_uses (&(ann->use_ops), true);
+
+ /* Before removing existing virtual operands, save them in PREV_VOPS so
+ that we can re-use their SSA versions. */
+ prev_vops.vdef_ops = VDEF_OPS (ann);
+ prev_vops.vuse_ops = VUSE_OPS (ann);
+
+ /* Dont free the previous values to memory since we're still using them. */
+ free_vdefs (&(ann->vdef_ops), false);
+ free_vuses (&(ann->vuse_ops), false);
+
+ start_ssa_stmt_operands (stmt);
+
+ code = TREE_CODE (stmt);
+ switch (code)
+ {
+ case MODIFY_EXPR:
+ get_expr_operands (stmt, &TREE_OPERAND (stmt, 1), opf_none, &prev_vops);
+ get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), opf_is_def, &prev_vops);
+ break;
+
+ case COND_EXPR:
+ get_expr_operands (stmt, &COND_EXPR_COND (stmt), opf_none, &prev_vops);
+ break;
+
+ case SWITCH_EXPR:
+ get_expr_operands (stmt, &SWITCH_COND (stmt), opf_none, &prev_vops);
+ break;
+
+ case ASM_EXPR:
+ {
+ int noutputs = list_length (ASM_OUTPUTS (stmt));
+ const char **oconstraints
+ = (const char **) alloca ((noutputs) * sizeof (const char *));
+ int i;
+ tree link;
+ const char *constraint;
+ bool allows_mem, allows_reg, is_inout;
+
+ for (i=0, link = ASM_OUTPUTS (stmt); link;
+ ++i, link = TREE_CHAIN (link))
+ {
+ oconstraints[i] = constraint
+ = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
+ parse_output_constraint (&constraint, i, 0, 0,
+ &allows_mem, &allows_reg, &is_inout);
+ if (allows_reg && is_inout)
+ /* This should have been split in gimplify_asm_expr. */
+ abort ();
+
+ if (!allows_reg && allows_mem)
+ {
+ tree t = get_base_address (TREE_VALUE (link));
+ if (t && DECL_P (t))
+ mark_call_clobbered (t);
+ }
+
+ get_expr_operands (stmt, &TREE_VALUE (link), opf_is_def,
+ &prev_vops);
+ }
+
+ for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link))
+ {
+ constraint
+ = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
+ parse_input_constraint (&constraint, 0, 0, noutputs, 0,
+ oconstraints, &allows_mem, &allows_reg);
+
+ if (!allows_reg && allows_mem)
+ {
+ tree t = get_base_address (TREE_VALUE (link));
+ if (t && DECL_P (t))
+ mark_call_clobbered (t);
+ }
+
+ get_expr_operands (stmt, &TREE_VALUE (link), 0, &prev_vops);
+ }
+
+ /* Clobber memory for asm ("" : : : "memory"); */
+ for (link = ASM_CLOBBERS (stmt); link; link = TREE_CHAIN (link))
+ if (!strcmp (TREE_STRING_POINTER (TREE_VALUE (link)), "memory"))
+ add_call_clobber_ops (stmt, &prev_vops);
+ }
+ break;
+
+ case RETURN_EXPR:
+ get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), opf_none, &prev_vops);
+ break;
+
+ case GOTO_EXPR:
+ get_expr_operands (stmt, &GOTO_DESTINATION (stmt), opf_none, &prev_vops);
+ break;
+
+ case LABEL_EXPR:
+ get_expr_operands (stmt, &LABEL_EXPR_LABEL (stmt), opf_none, &prev_vops);
+ break;
+
+ /* These nodes contain no variable references. */
+ case BIND_EXPR:
+ case CASE_LABEL_EXPR:
+ case TRY_CATCH_EXPR:
+ case TRY_FINALLY_EXPR:
+ case EH_FILTER_EXPR:
+ case CATCH_EXPR:
+ case RESX_EXPR:
+ break;
+
+ default:
+ /* Notice that if get_expr_operands tries to use &STMT as the operand
+ pointer (which may only happen for USE operands), we will abort in
+ append_use. This default will handle statements like empty statements,
+ CALL_EXPRs or VA_ARG_EXPRs that may appear on the RHS of a statement
+ or as statements themselves. */
+ get_expr_operands (stmt, &stmt, opf_none, &prev_vops);
+ break;
+ }
+
+ finalize_ssa_stmt_operands (stmt);
+
+ /* Now free the previous virtual ops to memory. */
+ free_vdefs (&(prev_vops.vdef_ops), true);
+ free_vuses (&(prev_vops.vuse_ops), true);
+
+ /* Clear the modified bit for STMT. Subsequent calls to
+ get_stmt_operands for this statement will do nothing until the
+ statement is marked modified by a call to modify_stmt(). */
+ ann->modified = 0;
+
+ timevar_pop (TV_TREE_OPS);
+}
+
+
+/* Recursively scan the expression pointed by EXPR_P in statement STMT.
+ FLAGS is one of the OPF_* constants modifying how to interpret the
+ operands found. PREV_VOPS is as in append_vdef and append_vuse. */
+
+static void
+get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops)
+{
+ enum tree_code code;
+ char class;
+ tree expr = *expr_p;
+
+ if (expr == NULL || expr == error_mark_node)
+ return;
+
+ code = TREE_CODE (expr);
+ class = TREE_CODE_CLASS (code);
+
+ /* Expressions that make no memory references. */
+ if (class == 'c'
+ || class == 't'
+ || code == BLOCK
+ || code == FUNCTION_DECL
+ || code == EXC_PTR_EXPR
+ || code == FILTER_EXPR
+ || code == LABEL_DECL)
+ return;
+
+ /* We could have the address of a component, array member, etc which
+ has interesting variable references. */
+ if (code == ADDR_EXPR)
+ {
+ enum tree_code subcode = TREE_CODE (TREE_OPERAND (expr, 0));
+
+ /* Taking the address of a variable does not represent a
+ reference to it, but the fact that STMT takes its address will be
+ of interest to some passes (e.g. alias resolution). */
+ add_stmt_operand (expr_p, stmt, 0, NULL);
+
+ /* If the address is invariant, there may be no interesting variable
+ references inside. */
+ if (is_gimple_min_invariant (expr))
+ return;
+
+ /* There should be no VUSEs created, since the referenced objects are
+ not really accessed. The only operands that we should find here
+ are ARRAY_REF indices which will always be real operands (GIMPLE
+ does not allow non-registers as array indices). */
+ flags |= opf_no_vops;
+
+ /* Avoid recursion. */
+ code = subcode;
+ class = TREE_CODE_CLASS (code);
+ expr_p = &TREE_OPERAND (expr, 0);
+ expr = *expr_p;
+ }
+
+ /* If we found a variable, add it to DEFS or USES depending on the
+ operand flags. */
+ if (SSA_VAR_P (expr))
+ {
+ add_stmt_operand (expr_p, stmt, flags, prev_vops);
+ return;
+ }
+
+ /* Pointer dereferences always represent a use of the base pointer. */
+ if (code == INDIRECT_REF)
+ {
+ tree *pptr = &TREE_OPERAND (expr, 0);
+ tree ptr = *pptr;
+
+ if (SSA_VAR_P (ptr))
+ {
+ if (!aliases_computed_p)
+ {
+ /* If the pointer does not have a memory tag and aliases have not
+ been computed yet, mark the statement as having volatile
+ operands to prevent DOM from entering it in equivalence tables
+ and DCE from killing it. */
+ stmt_ann (stmt)->has_volatile_ops = true;
+ }
+ else
+ {
+ ssa_name_ann_t ptr_ann = NULL;
+
+ /* If we have computed aliasing already, check if PTR has
+ flow-sensitive points-to information. */
+ if (TREE_CODE (ptr) == SSA_NAME
+ && (ptr_ann = ssa_name_ann (ptr)) != NULL
+ && ptr_ann->name_mem_tag)
+ {
+ /* PTR has its own memory tag. Use it. */
+ add_stmt_operand (&ptr_ann->name_mem_tag, stmt, flags,
+ prev_vops);
+ }
+ else
+ {
+ /* If PTR is not an SSA_NAME or it doesn't have a name
+ tag, use its type memory tag. */
+ var_ann_t ann;
+
+ /* If we are emitting debugging dumps, display a warning if
+ PTR is an SSA_NAME with no flow-sensitive alias
+ information. That means that we may need to compute
+ aliasing again. */
+ if (dump_file
+ && TREE_CODE (ptr) == SSA_NAME
+ && ptr_ann == NULL)
+ {
+ fprintf (dump_file,
+ "NOTE: no flow-sensitive alias info for ");
+ print_generic_expr (dump_file, ptr, dump_flags);
+ fprintf (dump_file, " in ");
+ print_generic_stmt (dump_file, stmt, dump_flags);
+ }
+
+ if (TREE_CODE (ptr) == SSA_NAME)
+ ptr = SSA_NAME_VAR (ptr);
+ ann = var_ann (ptr);
+ add_stmt_operand (&ann->type_mem_tag, stmt, flags, prev_vops);
+ }
+ }
+ }
+
+ /* If a constant is used as a pointer, we can't generate a real
+ operand for it but we mark the statement volatile to prevent
+ optimizations from messing things up. */
+ else if (TREE_CODE (ptr) == INTEGER_CST)
+ {
+ stmt_ann (stmt)->has_volatile_ops = true;
+ return;
+ }
+
+ /* Everything else *should* have been folded elsewhere, but users
+ are smarter than we in finding ways to write invalid code. We
+ cannot just abort here. If we were absolutely certain that we
+ do handle all valid cases, then we could just do nothing here.
+ That seems optimistic, so attempt to do something logical... */
+ else if ((TREE_CODE (ptr) == PLUS_EXPR || TREE_CODE (ptr) == MINUS_EXPR)
+ && TREE_CODE (TREE_OPERAND (ptr, 0)) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (ptr, 1)) == INTEGER_CST)
+ {
+ /* Make sure we know the object is addressable. */
+ pptr = &TREE_OPERAND (ptr, 0);
+ add_stmt_operand (pptr, stmt, 0, NULL);
+
+ /* Mark the object itself with a VUSE. */
+ pptr = &TREE_OPERAND (*pptr, 0);
+ get_expr_operands (stmt, pptr, flags, prev_vops);
+ return;
+ }
+
+ /* Ok, this isn't even is_gimple_min_invariant. Something's broke. */
+ else
+ abort ();
+
+ /* Add a USE operand for the base pointer. */
+ get_expr_operands (stmt, pptr, opf_none, prev_vops);
+ return;
+ }
+
+ /* Treat array references as references to the virtual variable
+ representing the array. The virtual variable for an ARRAY_REF
+ is the VAR_DECL for the array. */
+ if (code == ARRAY_REF)
+ {
+ /* Add the virtual variable for the ARRAY_REF to VDEFS or VUSES
+ according to the value of IS_DEF. Recurse if the LHS of the
+ ARRAY_REF node is not a regular variable. */
+ if (SSA_VAR_P (TREE_OPERAND (expr, 0)))
+ add_stmt_operand (expr_p, stmt, flags, prev_vops);
+ else
+ get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags, prev_vops);
+
+ get_expr_operands (stmt, &TREE_OPERAND (expr, 1), opf_none, prev_vops);
+ return;
+ }
+
+ /* Similarly to arrays, references to compound variables (complex types
+ and structures/unions) are globbed.
+
+ FIXME: This means that
+
+ a.x = 6;
+ a.y = 7;
+ foo (a.x, a.y);
+
+ will not be constant propagated because the two partial
+ definitions to 'a' will kill each other. Note that SRA may be
+ able to fix this problem if 'a' can be scalarized. */
+ if (code == IMAGPART_EXPR || code == REALPART_EXPR || code == COMPONENT_REF)
+ {
+ /* If the LHS of the compound reference is not a regular variable,
+ recurse to keep looking for more operands in the subexpression. */
+ if (SSA_VAR_P (TREE_OPERAND (expr, 0)))
+ add_stmt_operand (expr_p, stmt, flags, prev_vops);
+ else
+ get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags, prev_vops);
+
+ return;
+ }
+
+ /* Function calls. Add every argument to USES. If the callee is
+ neither pure nor const, create a VDEF reference for GLOBAL_VAR
+ (See find_vars_r). */
+ if (code == CALL_EXPR)
+ {
+ tree op;
+ int call_flags = call_expr_flags (expr);
+
+ /* Find uses in the called function. */
+ get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_none, prev_vops);
+
+ for (op = TREE_OPERAND (expr, 1); op; op = TREE_CHAIN (op))
+ get_expr_operands (stmt, &TREE_VALUE (op), opf_none, prev_vops);
+
+ get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_none, prev_vops);
+
+ if (bitmap_first_set_bit (call_clobbered_vars) >= 0)
+ {
+ if (!(call_flags
+ & (ECF_PURE
+ | ECF_CONST
+ | ECF_NORETURN
+ | ECF_MALLOC
+ | ECF_MAY_BE_ALLOCA)))
+ add_call_clobber_ops (stmt, prev_vops);
+ else if (!(call_flags & (ECF_CONST | ECF_NORETURN)))
+ add_call_read_ops (stmt, prev_vops);
+ }
+ else if (!aliases_computed_p)
+ stmt_ann (stmt)->has_volatile_ops = true;
+
+ return;
+ }
+
+ /* Lists. */
+ if (code == TREE_LIST)
+ {
+ tree op;
+
+ for (op = expr; op; op = TREE_CHAIN (op))
+ get_expr_operands (stmt, &TREE_VALUE (op), flags, prev_vops);
+
+ return;
+ }
+
+ /* Assignments. */
+ if (code == MODIFY_EXPR)
+ {
+ get_expr_operands (stmt, &TREE_OPERAND (expr, 1), opf_none, prev_vops);
+ get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_is_def, prev_vops);
+ return;
+ }
+
+
+ /* Mark VA_ARG_EXPR nodes as making volatile references. FIXME,
+ this is needed because we currently do not gimplify VA_ARG_EXPR
+ properly. */
+ if (code == VA_ARG_EXPR)
+ {
+ stmt_ann (stmt)->has_volatile_ops = true;
+ return;
+ }
+
+ /* Unary expressions. */
+ if (class == '1'
+ || code == TRUTH_NOT_EXPR
+ || code == BIT_FIELD_REF
+ || code == CONSTRUCTOR)
+ {
+ get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags, prev_vops);
+ return;
+ }
+
+ /* Binary expressions. */
+ if (class == '2'
+ || class == '<'
+ || code == TRUTH_AND_EXPR
+ || code == TRUTH_OR_EXPR
+ || code == TRUTH_XOR_EXPR
+ || code == COMPOUND_EXPR)
+ {
+ get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags, prev_vops);
+ get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags, prev_vops);
+ return;
+ }
+
+ /* If we get here, something has gone wrong. */
+ fprintf (stderr, "unhandled expression in get_expr_operands():\n");
+ debug_tree (expr);
+ fputs ("\n", stderr);
+ abort ();
+}
+
+
+/* Add *VAR_P to the appropriate operand array of STMT. FLAGS is as in
+ get_expr_operands. If *VAR_P is a GIMPLE register, it will be added to
+ the statement's real operands, otherwise it is added to virtual
+ operands.
+
+ PREV_VOPS is used when adding virtual operands to statements that
+ already had them (See append_vdef and append_vuse). */
+
+static void
+add_stmt_operand (tree *var_p, tree stmt, int flags, voperands_t prev_vops)
+{
+ bool is_real_op;
+ tree var, sym;
+ stmt_ann_t s_ann;
+ var_ann_t v_ann;
+
+ var = *var_p;
+ STRIP_NOPS (var);
+
+ s_ann = stmt_ann (stmt);
+
+ /* If the operand is an ADDR_EXPR, add its operand to the list of
+ variables that have had their address taken in this statement. */
+ if (TREE_CODE (var) == ADDR_EXPR)
+ {
+ note_addressable (TREE_OPERAND (var, 0), s_ann);
+ return;
+ }
+
+ /* If the original variable is not a scalar, it will be added to the list
+ of virtual operands. In that case, use its base symbol as the virtual
+ variable representing it. */
+ is_real_op = is_gimple_reg (var);
+ if (!is_real_op && !DECL_P (var))
+ var = get_virtual_var (var);
+
+ /* If VAR is not a variable that we care to optimize, do nothing. */
+ if (var == NULL_TREE || !SSA_VAR_P (var))
+ return;
+
+ sym = (TREE_CODE (var) == SSA_NAME ? SSA_NAME_VAR (var) : var);
+ v_ann = var_ann (sym);
+
+ /* FIXME: We currently refuse to optimize variables that have hidden uses
+ (variables used in VLA declarations, MD builtin calls and variables
+ from the parent function in nested functions). This is because not
+ all uses of these variables are exposed in the IL or the statements
+ that reference them are not in GIMPLE form. If that's the case, mark
+ the statement as having volatile operands and return. */
+ if (v_ann->has_hidden_use)
+ {
+ s_ann->has_volatile_ops = true;
+ return;
+ }
+
+ /* Don't expose volatile variables to the optimizers. */
+ if (TREE_THIS_VOLATILE (sym))
+ {
+ s_ann->has_volatile_ops = true;
+ return;
+ }
+
+ if (is_real_op)
+ {
+ /* The variable is a GIMPLE register. Add it to real operands. */
+ if (flags & opf_is_def)
+ append_def (var_p, stmt);
+ else
+ append_use (var_p, stmt);
+ }
+ else
+ {
+ varray_type aliases;
+
+ /* The variable is not a GIMPLE register. Add it (or its aliases) to
+ virtual operands, unless the caller has specifically requested
+ not to add virtual operands (used when adding operands inside an
+ ADDR_EXPR expression). */
+ if (flags & opf_no_vops)
+ return;
+
+ aliases = v_ann->may_aliases;
+
+ /* If alias information hasn't been computed yet, then
+ addressable variables will not be an alias tag nor will they
+ have aliases. In this case, mark the statement as having
+ volatile operands. */
+ if (!aliases_computed_p && may_be_aliased (var))
+ s_ann->has_volatile_ops = true;
+
+ if (aliases == NULL)
+ {
+ /* The variable is not aliased or it is an alias tag. */
+ if (flags & opf_is_def)
+ {
+ append_vdef (var, stmt, prev_vops);
+ if (v_ann->is_alias_tag)
+ s_ann->makes_aliased_stores = 1;
+ }
+ else
+ {
+ append_vuse (var, stmt, prev_vops);
+ if (v_ann->is_alias_tag)
+ s_ann->makes_aliased_loads = 1;
+ }
+ }
+ else
+ {
+ size_t i;
+
+ /* The variable is aliased. Add its aliases to the virtual
+ operands. */
+ if (VARRAY_ACTIVE_SIZE (aliases) == 0)
+ abort ();
+
+ if (flags & opf_is_def)
+ {
+ /* If the variable is also an alias tag, add a virtual
+ operand for it, otherwise we will miss representing
+ references to the members of the variable's alias set.
+ This fixes the bug in gcc.c-torture/execute/20020503-1.c. */
+ if (v_ann->is_alias_tag)
+ append_vdef (var, stmt, prev_vops);
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (aliases); i++)
+ append_vdef (VARRAY_TREE (aliases, i), stmt, prev_vops);
+
+ s_ann->makes_aliased_stores = 1;
+ }
+ else
+ {
+ if (v_ann->is_alias_tag)
+ append_vuse (var, stmt, prev_vops);
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (aliases); i++)
+ append_vuse (VARRAY_TREE (aliases, i), stmt, prev_vops);
+
+ s_ann->makes_aliased_loads = 1;
+ }
+ }
+ }
+}
+
+/* Record that VAR had its address taken in the statement with annotations
+ S_ANN. */
+
+static void
+note_addressable (tree var, stmt_ann_t s_ann)
+{
+ var = get_base_address (var);
+ if (var && SSA_VAR_P (var))
+ {
+ if (s_ann->addresses_taken == NULL)
+ s_ann->addresses_taken = BITMAP_GGC_ALLOC ();
+ bitmap_set_bit (s_ann->addresses_taken, var_ann (var)->uid);
+ }
+}
+
+
+/* Add clobbering definitions for .GLOBAL_VAR or for each of the call
+ clobbered variables in the function. */
+
+static void
+add_call_clobber_ops (tree stmt, voperands_t prev_vops)
+{
+ /* Functions that are not const, pure or never return may clobber
+ call-clobbered variables. */
+ stmt_ann (stmt)->makes_clobbering_call = true;
+
+ /* If we had created .GLOBAL_VAR earlier, use it. Otherwise, add a VDEF
+ operand for every call clobbered variable. See compute_may_aliases for
+ the heuristic used to decide whether to create .GLOBAL_VAR or not. */
+ if (global_var)
+ add_stmt_operand (&global_var, stmt, opf_is_def, prev_vops);
+ else
+ {
+ size_t i;
+
+ EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i,
+ {
+ tree var = referenced_var (i);
+
+ /* If VAR is read-only, don't add a VDEF, just a VUSE operand. */
+ if (!TREE_READONLY (var))
+ add_stmt_operand (&var, stmt, opf_is_def, prev_vops);
+ else
+ add_stmt_operand (&var, stmt, opf_none, prev_vops);
+ });
+ }
+}
+
+
+/* Add VUSE operands for .GLOBAL_VAR or all call clobbered variables in the
+ function. */
+
+static void
+add_call_read_ops (tree stmt, voperands_t prev_vops)
+{
+ /* Otherwise, if the function is not pure, it may reference memory. Add
+ a VUSE for .GLOBAL_VAR if it has been created. Otherwise, add a VUSE
+ for each call-clobbered variable. See add_referenced_var for the
+ heuristic used to decide whether to create .GLOBAL_VAR. */
+ if (global_var)
+ add_stmt_operand (&global_var, stmt, opf_none, prev_vops);
+ else
+ {
+ size_t i;
+
+ EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i,
+ {
+ tree var = referenced_var (i);
+ add_stmt_operand (&var, stmt, opf_none, prev_vops);
+ });
+ }
+}
+
+#include "gt-tree-ssa-operands.h"
diff --git a/gcc/tree-ssa-operands.h b/gcc/tree-ssa-operands.h
new file mode 100644
index 00000000000..ceee6d037ab
--- /dev/null
+++ b/gcc/tree-ssa-operands.h
@@ -0,0 +1,97 @@
+/* SSA operand management for trees.
+ Copyright (C) 2003 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 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#ifndef GCC_TREE_SSA_OPERANDS_H
+#define GCC_TREE_SSA_OPERANDS_H
+
+/* Interface to SSA operands. */
+
+typedef struct def_optype_d GTY(())
+{
+ unsigned num_defs;
+ tree * GTY((length("%h.num_defs"), skip(""))) defs[1];
+} def_optype_t;
+
+typedef def_optype_t *def_optype;
+
+typedef struct use_optype_d GTY(())
+{
+ unsigned num_uses;
+ tree * GTY((length("%h.num_uses"), skip(""))) uses[1];
+} use_optype_t;
+
+typedef use_optype_t *use_optype;
+
+typedef struct vdef_optype_d GTY(())
+{
+ unsigned num_vdefs;
+ tree GTY((length ("%h.num_vdefs * 2"))) vdefs[1];
+} vdef_optype_t;
+
+typedef vdef_optype_t *vdef_optype;
+
+typedef struct vuse_optype_d GTY(())
+{
+ unsigned num_vuses;
+ tree GTY((length ("%h.num_vuses"))) vuses[1];
+} vuse_optype_t;
+
+typedef vuse_optype_t *vuse_optype;
+
+#define USE_OPS(ANN) get_use_ops (ANN)
+#define STMT_USE_OPS(STMT) get_use_ops (stmt_ann (STMT))
+#define NUM_USES(OPS) ((OPS) ? (OPS)->num_uses : 0)
+#define USE_OP_PTR(OPS, I) get_use_op_ptr ((OPS), (I))
+#define USE_OP(OPS, I) (*(USE_OP_PTR ((OPS), (I))))
+
+
+#define DEF_OPS(ANN) get_def_ops (ANN)
+#define STMT_DEF_OPS(STMT) get_def_ops (stmt_ann (STMT))
+#define NUM_DEFS(OPS) ((OPS) ? (OPS)->num_defs : 0)
+#define DEF_OP_PTR(OPS, I) get_def_op_ptr ((OPS), (I))
+#define DEF_OP(OPS, I) (*(DEF_OP_PTR ((OPS), (I))))
+
+
+#define VDEF_OPS(ANN) get_vdef_ops (ANN)
+#define STMT_VDEF_OPS(STMT) get_vdef_ops (stmt_ann(STMT))
+#define NUM_VDEFS(OPS) ((OPS) ? (OPS)->num_vdefs : 0)
+#define VDEF_RESULT_PTR(OPS, I) get_vdef_result_ptr ((OPS), (I))
+#define VDEF_RESULT(OPS, I) (*(VDEF_RESULT_PTR ((OPS), (I))))
+#define VDEF_OP_PTR(OPS, I) get_vdef_op_ptr ((OPS), (I))
+#define VDEF_OP(OPS, I) (*(VDEF_OP_PTR ((OPS), (I))))
+
+
+#define VUSE_OPS(ANN) get_vuse_ops (ANN)
+#define STMT_VUSE_OPS(STMT) get_vuse_ops (stmt_ann(STMT))
+#define NUM_VUSES(OPS) ((OPS) ? (OPS)->num_vuses : 0)
+#define VUSE_OP_PTR(OPS, I) get_vuse_op_ptr ((OPS), (I))
+#define VUSE_OP(OPS, I) (*(VUSE_OP_PTR ((OPS), (I))))
+
+
+extern void init_ssa_operands (void);
+extern void fini_ssa_operands (void);
+extern void verify_start_operands (tree);
+extern void finalize_ssa_stmt_operands (tree);
+void add_vuse (tree, tree);
+extern void get_stmt_operands (tree);
+extern void remove_vuses (tree);
+extern void remove_vdefs (tree);
+
+#endif /* GCC_TREE_SSA_OPERANDS_H */
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
new file mode 100644
index 00000000000..c302145393e
--- /dev/null
+++ b/gcc/tree-ssa-phiopt.c
@@ -0,0 +1,346 @@
+/* Optimization of PHI nodes by converting them into straightline code.
+ Copyright (C) 2004 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 2, or (at your option) any
+later version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "errors.h"
+#include "ggc.h"
+#include "tree.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "basic-block.h"
+#include "timevar.h"
+#include "diagnostic.h"
+#include "tree-flow.h"
+#include "tree-pass.h"
+#include "tree-dump.h"
+#include "langhooks.h"
+
+static void tree_ssa_phiopt (void);
+static bool conditional_replacement (basic_block bb, tree phi, tree arg0,
+ tree arg1);
+
+/* This pass eliminates PHI nodes which can be trivially implemented as
+ an assignment from a conditional expression. ie if we have something
+ like:
+
+ bb0:
+ if (cond) goto bb2; else goto bb1;
+ bb1:
+ bb2:
+ x = PHI (0 (bb1), 1 (bb0)
+
+ We can rewrite that as:
+
+ bb0:
+ bb1:
+ bb2:
+ x = cond;
+
+ bb1 will become unreachable and bb0 and bb2 will almost always
+ be merged into a single block. This occurs often due to gimplification
+ of conditionals. */
+
+static void
+tree_ssa_phiopt (void)
+{
+ basic_block bb;
+ bool removed_phis = false;
+
+ /* Search every basic block for PHI nodes we may be able to optimize. */
+ FOR_EACH_BB (bb)
+ {
+ tree arg0, arg1, phi;
+
+
+ /* We're searching for blocks with one PHI node which has two
+ arguments. */
+ phi = phi_nodes (bb);
+ if (phi && TREE_CHAIN (phi) == NULL
+ && PHI_NUM_ARGS (phi) == 2)
+ {
+
+ arg0 = PHI_ARG_DEF (phi, 0);
+ arg1 = PHI_ARG_DEF (phi, 1);
+
+ /* Do the replacement of conditional if it can be done. */
+ if (conditional_replacement (bb, phi, arg0, arg1))
+ {
+ /* We have done the replacement so we need to rebuild the cfg. */
+ removed_phis = true;
+ continue;
+ }
+ }
+ }
+
+ /* If we removed any PHIs, then we have unreachable blocks and blocks
+ which need to be merged in the CFG. */
+ if (removed_phis)
+ cleanup_tree_cfg ();
+}
+
+/* The function conditional_replacement does the main work of doing the conditional
+ replacement. Return true if the replacement is done. Otherwise return false.
+ bb is the basic block where the replacement is going to be done on. arg0
+ is argument 0 from the phi. Likewise for arg1. */
+
+static bool
+conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
+{
+ tree result;
+ tree old_result = NULL;
+ basic_block other_block = NULL;
+ basic_block cond_block = NULL;
+ tree last0, last1, new, cond;
+ block_stmt_iterator bsi;
+ edge true_edge, false_edge;
+ tree new_var = NULL;
+
+ /* The PHI arguments have the constants 0 and 1, then convert
+ it to the conditional. */
+ if ((integer_zerop (arg0) && integer_onep (arg1))
+ || (integer_zerop (arg1) && integer_onep (arg0)))
+ ;
+ else
+ return false;
+
+ /* One of the alternatives must come from a block ending with
+ a COND_EXPR. The other block must be entirely empty, except
+ for labels. */
+ last0 = last_stmt (bb->pred->src);
+ last1 = last_stmt (bb->pred->pred_next->src);
+ if (last0 && TREE_CODE (last0) == COND_EXPR)
+ {
+ cond_block = bb->pred->src;
+ other_block = bb->pred->pred_next->src;
+ }
+ else if (last1 && TREE_CODE (last1) == COND_EXPR)
+ {
+ other_block = bb->pred->src;
+ cond_block = bb->pred->pred_next->src;
+ }
+ else
+ return false;
+
+ /* COND_BLOCK must have precisely two successors. We indirectly
+ verify that those successors are BB and OTHER_BLOCK. */
+ if (!cond_block->succ
+ || !cond_block->succ->succ_next
+ || cond_block->succ->succ_next->succ_next
+ || (cond_block->succ->flags & EDGE_ABNORMAL) != 0
+ || (cond_block->succ->succ_next->flags & EDGE_ABNORMAL) != 0)
+ return false;
+
+ /* OTHER_BLOCK must have a single predecessor which is COND_BLOCK,
+ OTHER_BLOCK must have a single successor which is BB and
+ OTHER_BLOCK must have no PHI nodes. */
+ if (!other_block->pred
+ || other_block->pred->src != cond_block
+ || other_block->pred->pred_next
+ || !other_block->succ
+ || other_block->succ->dest != bb
+ || other_block->succ->succ_next
+ || phi_nodes (other_block))
+ return false;
+
+ /* OTHER_BLOCK must have no executable statements. */
+ bsi = bsi_start (other_block);
+ while (!bsi_end_p (bsi)
+ && (TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR
+ || IS_EMPTY_STMT (bsi_stmt (bsi))))
+ bsi_next (&bsi);
+
+ if (!bsi_end_p (bsi))
+ return false;
+
+ /* If the condition is not a naked SSA_NAME and its type does not
+ match the type of the result, then we have to create a new
+ variable to optimize this case as it would likely create
+ non-gimple code when the condition was converted to the
+ result's type. */
+
+ cond = COND_EXPR_COND (last_stmt (cond_block));
+ result = PHI_RESULT (phi);
+ if (TREE_CODE (cond) != SSA_NAME
+ && !lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
+ {
+ new_var = make_rename_temp (TREE_TYPE (cond), NULL);
+ old_result = cond;
+ cond = new_var;
+ }
+
+ /* If the condition was a naked SSA_NAME and the type is not the
+ same as the type of the result, then convert the type of the
+ condition. */
+ if (!lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
+ cond = fold_convert (TREE_TYPE (result), cond);
+
+ /* We need to know which is the true edge and which is the false
+ edge so that we know when to invert the condition below. */
+ extract_true_false_edges_from_block (cond_block, &true_edge, &false_edge);
+
+ /* Insert our new statement at the head of our block. */
+ bsi = bsi_start (bb);
+
+ if (old_result)
+ {
+ tree new1;
+ if (TREE_CODE_CLASS (TREE_CODE (old_result)) != '<')
+ return false;
+
+ new1 = build (TREE_CODE (old_result), TREE_TYPE (result),
+ TREE_OPERAND (old_result, 0),
+ TREE_OPERAND (old_result, 1));
+
+ new1 = build (MODIFY_EXPR, TREE_TYPE (result),
+ new_var, new1);
+ bsi_insert_after (&bsi, new1, BSI_NEW_STMT);
+ }
+
+
+ /* At this point we know we have a COND_EXPR with two successors.
+ One successor is BB, the other successor is an empty block which
+ falls through into BB.
+
+ There is a single PHI node at the join point (BB) and its arguments
+ are constants (0, 1).
+
+ So, given the condition COND, and the two PHI arguments, we can
+ rewrite this PHI into non-branching code:
+
+ dest = (COND) or dest = COND'
+
+ We use the condition as-is if the argument associated with the
+ true edge has the value one or the argument associated with the
+ false edge as the value zero. Note that those conditions are not
+ the same since only one of the outgoing edges from the COND_EXPR
+ will directly reach BB and thus be associated with an argument. */
+
+ if ((PHI_ARG_EDGE (phi, 0) == true_edge && integer_onep (arg0))
+ || (PHI_ARG_EDGE (phi, 0) == false_edge && integer_zerop (arg0))
+ || (PHI_ARG_EDGE (phi, 1) == true_edge && integer_onep (arg1))
+ || (PHI_ARG_EDGE (phi, 1) == false_edge && integer_zerop (arg1)))
+ {
+ new = build (MODIFY_EXPR, TREE_TYPE (PHI_RESULT (phi)),
+ PHI_RESULT (phi), cond);
+ }
+ else
+ {
+ tree cond1 = invert_truthvalue (cond);
+
+ cond = cond1;
+ /* If what we get back is a conditional expression, there is no
+ way that is can be gimple. */
+ if (TREE_CODE (cond) == COND_EXPR)
+ return false;
+
+ /* If what we get back is not gimple try to create it as gimple by
+ using a temporary variable. */
+ if (is_gimple_cast (cond)
+ && !is_gimple_val (TREE_OPERAND (cond, 0)))
+ {
+ tree temp = TREE_OPERAND (cond, 0);
+ tree new_var_1 = make_rename_temp (TREE_TYPE (temp), NULL);
+ new = build (MODIFY_EXPR, TREE_TYPE (new_var_1), new_var_1, temp);
+ bsi_insert_after (&bsi, new, BSI_NEW_STMT);
+ cond = fold_convert (TREE_TYPE (result), new_var_1);
+ }
+
+ if (TREE_CODE (cond) == TRUTH_NOT_EXPR
+ && !is_gimple_val (TREE_OPERAND (cond, 0)))
+ return false;
+
+ new = build (MODIFY_EXPR, TREE_TYPE (PHI_RESULT (phi)),
+ PHI_RESULT (phi), cond);
+ }
+
+ bsi_insert_after (&bsi, new, BSI_NEW_STMT);
+
+ /* Register our new statement as the defining statement for
+ the result. */
+ SSA_NAME_DEF_STMT (PHI_RESULT (phi)) = new;
+
+ /* Remove the now useless PHI node.
+
+ We do not want to use remove_phi_node since that releases the
+ SSA_NAME as well and the SSA_NAME is still being used. */
+ release_phi_node (phi);
+ bb_ann (bb)->phi_nodes = NULL;
+
+ /* Disconnect the edge leading into the empty block. That will
+ make the empty block unreachable and it will be removed later. */
+ if (cond_block->succ->dest == bb)
+ {
+ cond_block->succ->flags |= EDGE_FALLTHRU;
+ cond_block->succ->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
+ ssa_remove_edge (cond_block->succ->succ_next);
+ }
+ else
+ {
+ cond_block->succ->succ_next->flags |= EDGE_FALLTHRU;
+ cond_block->succ->succ_next->flags
+ &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
+ ssa_remove_edge (cond_block->succ);
+ }
+
+ /* Eliminate the COND_EXPR at the end of COND_BLOCK. */
+ bsi = bsi_last (cond_block);
+ bsi_remove (&bsi);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ "COND_EXPR in block %d and PHI in block %d converted to straightline code.\n",
+ cond_block->index,
+ bb->index);
+
+ /* Note that we optimized this PHI. */
+ return true;
+}
+
+
+/* Always do these optimizations if we have SSA
+ trees to work on. */
+static bool
+gate_phiopt (void)
+{
+ return 1;
+}
+
+struct tree_opt_pass pass_phiopt =
+{
+ "phiopt", /* name */
+ gate_phiopt, /* gate */
+ tree_ssa_phiopt, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_PHIOPT, /* tv_id */
+ PROP_cfg | PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */
+ | TODO_verify_ssa | TODO_rename_vars
+ | TODO_verify_flow
+};
+
+
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
new file mode 100644
index 00000000000..c249441dd7c
--- /dev/null
+++ b/gcc/tree-ssa-pre.c
@@ -0,0 +1,3390 @@
+/* SSA-PRE for trees.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Daniel Berlin <dan@dberlin.org>
+
+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 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "errors.h"
+#include "ggc.h"
+#include "tree.h"
+
+/* These RTL headers are needed for basic-block.h. */
+#include "rtl.h"
+#include "tm_p.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "diagnostic.h"
+#include "tree-inline.h"
+#include "tree-flow.h"
+#include "tree-gimple.h"
+#include "tree-dump.h"
+#include "timevar.h"
+#include "fibheap.h"
+#include "hashtab.h"
+#include "tree-iterator.h"
+#include "real.h"
+#include "alloc-pool.h"
+#include "tree-pass.h"
+#include "flags.h"
+
+
+/*
+
+ Some of the algorithms are also based on Open64's SSAPRE implementation.
+
+ Since the papers are a bit dense to read, take a while to grasp,
+ and have a few bugs, i'll give a quick rundown:
+
+ Normally, in non-SSA form, one performs PRE on expressions using
+ bit vectors, determining properties for all expressions at once
+ through bitmap operations and iterative dataflow.
+
+ SSAPRE, like most non-SSA->SSA algorithm conversions, operates one
+ expression at a time, and doesn't use bitvectors or iterative
+ dataflow.
+
+ It answers the question "Given a single hypothetical temporary
+ variable, what expressions could we eliminate.
+
+ To be able to do this, we need an SSA form for expressions.
+ If you are already confused, you likely think an expression, as
+ used here, is something like "b_3 = a_2 + 5". It's not. It's "a +
+ 5". "a_2 + 5" is an *occurrence* of the expression "a + 5". Just
+ like PRE, it's lexical equivalence that matters.
+ Compilers generally give you an SSA form for variables, and maybe
+ arrays (and/or conditionals). But not for expressions.
+
+ GCC doesn't give you one either, so we have to build it.
+ Thus, the first steps of SSAPRE are to do just these things.
+
+ First we collect lists of occurrences of expressions we are going
+ to operate on.
+ Note that:
+ Unlike the paper, we don't have to ever add newly formed
+ expressions to the list (for normal SSAPRE, anyway), because we
+ don't have expressions with more than two operators, and each
+ operator is either a constant or a variable. Thus, no second
+ order effects.
+
+ Once we have the lists of occurrences, we process one expression
+ at a time, doing the following:
+ 1. Using a slightly modified SSA phi placement algorithm, place
+ expression PHI's for expressions.
+ 2. Using a two step optimistic SSA renaming algorithm, version the
+ nodes and link phi operands to their real occurrences, if they
+ exist. This creates a factored graph of our expression SSA occurrences.
+ 3. Using the factored graph, compute downsafe, avail, and later for
+ EPHIs (which are SSA versions of the same named bitvector PRE
+ problems)
+ 4. Using EPHI availability information and versions, compute what
+ occurrences need to have saves, and what occurrences can be
+ reloaded from an already saved value.
+ 5. Insert the saves and reloads, and transform EPHIs into regular
+ phis of the temporary we use for insertion/saving.
+
+ See http://citeseer.nj.nec.com/chow97new.html, and
+ http://citeseer.nj.nec.com/kennedy99partial.html for details of the
+ algorithm.
+
+ kennedy99partial is newer, and is what this implementation is based
+ on.
+
+ For strength reduction addition, see
+ http://citeseer.nj.nec.com/kennedy98strength.html.
+
+ There is also a paper on sparse register promotion using PRE that
+ contains the basic algorithm for load PRE. The exact title/url of
+ the paper escapes me.
+
+ Lastly, there is a code hoisting extension that open64 performs
+ (see opt_ehoist.cxx), but we don't. It's not documented in any
+ papers, but not that difficult to understand of implement. */
+
+
+/* TODOS:
+ Do strength reduction on a +-b and -a, not just a * <constant>.
+ */
+
+struct expr_info;
+static void clear_all_eref_arrays (void);
+static inline bool expr_lexically_eq (const tree, const tree);
+static void free_expr_info (struct expr_info *);
+static bitmap compute_idfs (bitmap *, tree);
+static void set_var_phis (struct expr_info *, tree);
+static inline bool names_match_p (const tree, const tree);
+static bool is_strred_cand (const tree);
+static int pre_expression (struct expr_info *, void *, bitmap);
+static bool is_injuring_def (struct expr_info *, tree);
+static inline bool okay_injuring_def (tree, tree);
+static bool expr_phi_insertion (bitmap *, struct expr_info *);
+static tree factor_through_injuries (struct expr_info *, tree, tree, bool *);
+static inline tree maybe_find_rhs_use_for_var (tree, tree, unsigned int);
+static inline tree find_rhs_use_for_var (tree, tree);
+static tree create_ephi_node (basic_block, unsigned int);
+static inline int opnum_of_phi (tree, int);
+static inline int opnum_of_ephi (const tree, const edge);
+static tree subst_phis (struct expr_info *, tree, basic_block, basic_block);
+static void generate_expr_as_of_bb (tree, basic_block, basic_block);
+static void generate_vops_as_of_bb (tree, basic_block, basic_block);
+static void rename_1 (struct expr_info *);
+static void process_delayed_rename (struct expr_info *, tree, tree);
+static void assign_new_class (tree, varray_type *, varray_type *);
+static void create_and_insert_occ_in_preorder_dt_order (struct expr_info *);
+static void insert_euse_in_preorder_dt_order (struct expr_info *);
+static bool ephi_has_unsafe_arg (tree);
+static void reset_down_safe (tree, int);
+static void compute_down_safety (struct expr_info *);
+static void compute_will_be_avail (struct expr_info *);
+static void compute_stops (struct expr_info *);
+static bool finalize_1 (struct expr_info *);
+static void finalize_2 (struct expr_info *);
+static tree occ_identical_to (tree);
+static void require_phi (struct expr_info *, basic_block);
+static bool really_available_def (tree node);
+
+/* Functions used for an EPHI based depth first search. */
+struct ephi_df_search
+{
+ /* Return true if the ephi has been seen. */
+ bool (*seen) (tree);
+ /* Mark the ephi as seen. */
+ void (*set_seen) (tree);
+ /* Note that the search reaches from one ephi to it's use. */
+ void (*reach_from_to) (tree, int, tree);
+ /* Return true if we should start a search from this PHI. */
+ bool (*start_from) (tree);
+ /* Return true if we should continue the search to this use. */
+ bool (*continue_from_to) (tree, int, tree);
+};
+static bool repl_search_seen (tree);
+static void repl_search_set_seen (tree);
+static void repl_search_reach_from_to (tree, int, tree);
+static bool repl_search_start_from (tree);
+static bool repl_search_continue_from_to (tree, int, tree);
+static bool stops_search_seen (tree);
+static void stops_search_set_seen (tree);
+static void stops_search_reach_from_to (tree, int, tree);
+static bool stops_search_start_from (tree);
+static bool stops_search_continue_from_to (tree, int, tree);
+static bool cba_search_seen (tree);
+static void cba_search_set_seen (tree);
+static bool cba_search_start_from (tree);
+static bool cba_search_continue_from_to (tree, int, tree);
+struct ephi_df_search cant_be_avail_search = {
+ cba_search_seen,
+ cba_search_set_seen,
+ NULL,
+ cba_search_start_from,
+ cba_search_continue_from_to
+};
+
+struct ephi_df_search stops_search = {
+ stops_search_seen,
+ stops_search_set_seen,
+ stops_search_reach_from_to,
+ stops_search_start_from,
+ stops_search_continue_from_to
+};
+
+
+/* depth-first replacement search used during temp ESSA minimization. */
+struct ephi_df_search replacing_search = {
+ repl_search_seen,
+ repl_search_set_seen,
+ repl_search_reach_from_to,
+ repl_search_start_from,
+ repl_search_continue_from_to
+};
+
+static void do_ephi_df_search_1 (struct ephi_df_search, tree);
+static void do_ephi_df_search (struct expr_info *, struct ephi_df_search);
+
+static inline bool any_operand_injured (tree);
+static void code_motion (struct expr_info *);
+static tree pick_ssa_name (tree stmt);
+#if 0
+static tree calculate_increment (struct expr_info *, tree);
+#endif
+static bool can_insert (tree, int);
+static void set_save (struct expr_info *, tree);
+static tree reaching_def (tree, tree, basic_block, tree);
+static tree do_proper_save (tree , tree, int);
+static void process_left_occs_and_kills (varray_type, tree);
+static tree create_expr_ref (struct expr_info *, tree, enum tree_code,
+ basic_block, tree);
+static inline bool ephi_will_be_avail (tree);
+static inline tree ephi_at_block (basic_block);
+static tree get_default_def (tree, htab_t);
+static inline bool same_e_version_real_occ_real_occ (struct expr_info *,
+ const tree,
+ const tree);
+static inline bool load_modified_phi_result (basic_block, tree);
+static inline bool same_e_version_phi_result (struct expr_info *,
+ tree, tree, tree);
+static inline bool load_modified_real_occ_real_occ (tree, tree);
+static inline bool same_e_version_real_occ_phi_opnd (struct expr_info *,
+ tree, basic_block,
+ int, tree, bool *);
+static inline bool injured_real_occ_real_occ (struct expr_info *,
+ tree, tree);
+static inline bool injured_phi_result_real_occ (struct expr_info *,
+ tree, tree, basic_block);
+static inline bool injured_real_occ_phi_opnd (struct expr_info *,
+ tree, basic_block, int);
+static void compute_du_info (struct expr_info *);
+static void add_ephi_use (tree, tree, int);
+static void insert_one_operand (struct expr_info *, tree, int, tree, edge,
+ tree **);
+static void collect_expressions (basic_block, varray_type *);
+static int build_dfn_array (basic_block, int);
+static int eref_compare (const void *, const void *);
+
+
+/* Bitmap of E-PHI predecessor operands have already been created.
+ We only create one phi-pred per block. */
+static bitmap created_phi_preds;
+
+/* PRE dominance frontiers. */
+static bitmap *pre_dfs;
+
+/* Number of redundancy classes. */
+static int class_count = 0;
+
+
+/* Iterated dominance frontiers cache. */
+static bitmap *idfs_cache;
+
+/* Partial redundancies statistics. */
+static struct pre_stats_d
+{
+ int reloads;
+ int saves;
+ int repairs;
+ int newphis;
+ int ephi_allocated;
+ int ephis_current;
+ int eref_allocated;
+ int exprs_generated;
+} pre_stats = {0, 0, 0, 0, 0, 0, 0, 0};
+
+
+/* USE entry in list of uses of ephi's. */
+struct ephi_use_entry
+{
+ tree phi;
+ int opnd_indx;
+};
+
+/* PRE Expression specific info. */
+struct expr_info
+{
+ /* The actual expression. */
+ tree expr;
+ /* The occurrences. */
+ varray_type occurs;
+ /* The kills. */
+ varray_type kills;
+ /* The left occurrences. */
+ varray_type lefts;
+ /* An array of real occurrences. */
+ varray_type reals;
+ /* True if it's a strength reduction candidate. */
+ bool strred_cand;
+ /* True if it's a load PRE candidate. */
+ bool loadpre_cand;
+ /* The euses/ephis in preorder dt order. */
+ varray_type euses_dt_order;
+ /* The name of the temporary for this expression. */
+ tree temp;
+};
+
+
+/* Cache of expressions generated for given phi operand, to avoid
+ recomputation and wasting memory. */
+static tree *phi_pred_cache;
+static int n_phi_preds;
+
+/* Trying to lookup ephi pred operand indexes takes forever on graphs
+ that have high connectivity because it's an O(n) linked list
+ traversal. Thus, we set up a hashtable that tells us the operand
+ index for a given edge. */
+
+typedef struct ephi_pred_index_elt
+{
+ tree ephi;
+ edge edge;
+ int opnd;
+} ephi_pindex_t;
+
+/* Hash an (ephi, edge, opnd) tuple. */
+
+static hashval_t
+ephi_pindex_hash (const void *p)
+{
+ const ephi_pindex_t *ep = (const ephi_pindex_t *)p;
+ return htab_hash_pointer (ep->ephi) + htab_hash_pointer (ep->edge);
+}
+
+/* Determine equality of an (ephi, edge, opnd) tuple. */
+
+static int
+ephi_pindex_eq (const void *p1, const void *p2)
+{
+ const ephi_pindex_t *ep1 = (const ephi_pindex_t *)p1;
+ const ephi_pindex_t *ep2 = (const ephi_pindex_t *)p2;
+
+ return ep1->ephi == ep2->ephi && ep1->edge == ep2->edge;
+}
+
+/* The (ephi, edge) => opnd mapping hashtable. */
+static htab_t ephi_pindex_htab;
+
+/* Add an ephi predecessor to a PHI. */
+
+static int
+add_ephi_pred (tree phi, tree def, edge e)
+{
+ int i = EPHI_NUM_ARGS (phi);
+ void **slot;
+ ephi_pindex_t ep, *epp;
+
+ EPHI_ARG_PRED (phi, i) = def;
+ EPHI_ARG_EDGE (phi, i) = e;
+
+ ep.ephi = phi;
+ ep.edge = e;
+ slot = htab_find_slot (ephi_pindex_htab, (void *)&ep, INSERT);
+ if (*slot == NULL)
+ {
+ epp = xmalloc (sizeof (*epp));
+ epp->ephi = phi;
+ epp->edge = e;
+ epp->opnd = i;
+ *slot = (void *)epp;
+ }
+ else
+ abort ();
+
+ EPHI_NUM_ARGS (phi)++;
+ return i;
+}
+
+/* Create a new EPHI node at basic block BB. */
+
+static tree
+create_ephi_node (basic_block bb, unsigned int add)
+{
+ tree phi;
+ int len;
+ edge e;
+ size_t size;
+ bb_ann_t ann;
+
+ for (len = 0, e = bb->pred; e; e = e->pred_next)
+ len++;
+ size = (sizeof (struct tree_ephi_node)
+ + ((len - 1) * sizeof (struct ephi_arg_d)));
+
+ phi = xmalloc (size);
+ memset (phi, 0, size);
+ if (add)
+ {
+ ann = bb_ann (bb);
+ if (ann->ephi_nodes == NULL)
+ ann->ephi_nodes = phi;
+ else
+ chainon (ann->ephi_nodes, phi);
+ }
+ pre_stats.ephi_allocated += size;
+ pre_stats.ephis_current += 1;
+ TREE_SET_CODE (phi, EPHI_NODE);
+ EPHI_NUM_ARGS (phi) = 0;
+ EPHI_ARG_CAPACITY (phi) = len;
+
+ /* Associate BB to the PHI node. */
+ set_bb_for_stmt (phi, bb);
+
+ return phi;
+}
+
+/* Given DEF (which can be an SSA_NAME or entire statement), and VAR,
+ find a use of VAR on the RHS of DEF, if one exists. Abort if we
+ can't find one. */
+
+static inline tree
+find_rhs_use_for_var (tree def, tree var)
+{
+ tree ret = maybe_find_rhs_use_for_var (def, var, 0);
+ if (!ret)
+ abort ();
+ return ret;
+}
+
+/* Determine if two trees are referring to the same variable.
+ Handles SSA_NAME vs non SSA_NAME, etc. Uses operand_equal_p for
+ non-trivial cases (INDIRECT_REF and friends). */
+
+static inline bool
+names_match_p (const tree t1, const tree t2)
+{
+ tree name1, name2;
+
+ if (t1 == t2)
+ return true;
+
+ if (TREE_CODE (t1) == INDIRECT_REF)
+ return names_match_p (TREE_OPERAND (t1, 0), t2);
+
+ if (TREE_CODE (t2) == INDIRECT_REF)
+ return names_match_p (t1, TREE_OPERAND (t2, 0));
+
+ if (TREE_CODE (t1) == SSA_NAME)
+ name1 = SSA_NAME_VAR (t1);
+ else if (DECL_P (t1))
+ name1 = t1;
+ else
+ name1 = NULL_TREE;
+
+ if (TREE_CODE (t2) == SSA_NAME)
+ name2 = SSA_NAME_VAR (t2);
+ else if (DECL_P (t2))
+ name2 = t2;
+ else
+ name2 = NULL_TREE;
+
+ if (name1 == NULL_TREE && name2 != NULL_TREE)
+ return false;
+ if (name2 == NULL_TREE && name1 != NULL_TREE)
+ return false;
+ if (name1 == NULL_TREE && name2 == NULL_TREE)
+ return operand_equal_p (t1, t2, 0);
+
+ return name1 == name2;
+}
+
+/* Given DEF (which can be an SSA_NAME or entire statement), and VAR,
+ find a use of VAR on the RHS of DEF, if one exists. Return NULL if
+ we cannot find one. */
+
+static inline tree
+maybe_find_rhs_use_for_var (tree def, tree var, unsigned int startpos)
+{
+ use_optype uses;
+ size_t i;
+
+ if (SSA_VAR_P (def))
+ {
+ if (names_match_p (var, def))
+ return def;
+ return NULL_TREE;
+ }
+ get_stmt_operands (def);
+ uses = STMT_USE_OPS (def);
+
+ for (i = startpos; i < NUM_USES (uses); i++)
+ {
+ tree use = USE_OP (uses, i);
+ if (names_match_p (use, var))
+ return use;
+ }
+ return NULL_TREE;
+}
+
+/* Determine if an injuring def is one which we can repair, and thus,
+ ignore for purposes of determining the version of a variable. */
+
+static inline bool
+okay_injuring_def (tree inj, tree var)
+{
+ /* Acceptable injuries are those which
+ 1. aren't empty statements.
+ 2. aren't phi nodes.
+ 3. contain a use of VAR on the RHS. */
+ if (!inj || IS_EMPTY_STMT (inj)
+ || TREE_CODE (inj) == PHI_NODE
+ || !maybe_find_rhs_use_for_var (inj, var, 0))
+ return false;
+ return true;
+}
+
+/* Return true if INJ is an injuring definition */
+
+static bool
+is_injuring_def (struct expr_info *ei, tree inj)
+{
+ /* Things that are never injuring definitions. */
+ if (!inj || IS_EMPTY_STMT (inj) || TREE_CODE (inj) == PHI_NODE)
+ return false;
+
+ /* Things we can't handle. */
+ if (TREE_CODE (TREE_OPERAND (inj, 1)) != PLUS_EXPR
+ && TREE_CODE (TREE_OPERAND (inj, 1)) != MINUS_EXPR)
+ return false;
+
+ /* given inj: a1 = a2 + 5
+ expr: a3 * c
+ we are testing:
+ if (a1 != a3
+ || ! (a2 exists)
+ || a2 != a3)
+ return false
+
+ Or, in English, if either the assigned-to variable in
+ the injury is different from the first variable in the
+ expression, or the incremented variable is different from the
+ first variable in the expression, punt.
+
+ This makes sure we have something of the form
+
+ a = a {+,-} {expr}
+ for an expression like "a * 5".
+
+ This limitation only exists because we don't know how to repair
+ other forms of increments/decrements. */
+ if (!names_match_p (TREE_OPERAND (inj, 0), TREE_OPERAND (ei->expr, 0))
+ || !TREE_OPERAND (TREE_OPERAND (inj, 1), 0)
+ || !names_match_p (TREE_OPERAND (TREE_OPERAND (inj, 1), 0),
+ TREE_OPERAND (ei->expr, 0)))
+ return false;
+
+ /* If we are strength reducing a multiply, we have the additional
+ constraints that
+ 1. {expr} is 1
+ 2. {expr} and the RHS of the expression are constants. */
+ if (TREE_CODE (ei->expr) == MULT_EXPR)
+ {
+ tree irhs1;
+ tree irhs2;
+ tree irhs;
+ irhs = TREE_OPERAND (inj, 1);
+ irhs1 = TREE_OPERAND (irhs, 0);
+ irhs2 = TREE_OPERAND (irhs, 1);
+
+ if (TREE_CODE (irhs2) != INTEGER_CST)
+ return false;
+ if (tree_low_cst (irhs2, 0) == 1)
+ return true;
+ if (really_constant_p (irhs2)
+ && really_constant_p (TREE_OPERAND (ei->expr, 1)))
+ return true;
+ /* We don't currently support "the injury is inside a loop,expr is
+ loop-invariant, and b is either loop-invariant or is
+ another induction variable with respect to the loop." */
+ return false;
+ }
+ return true;
+}
+
+/* Find the statement defining VAR, ignoring injuries we can repair.
+ START is the first potential injuring def. */
+
+static tree
+factor_through_injuries (struct expr_info *ei, tree start, tree var,
+ bool *injured)
+{
+ tree end = start;
+
+ while (is_injuring_def (ei, SSA_NAME_DEF_STMT (end)))
+ {
+ if (injured)
+ *injured = true;
+ end = find_rhs_use_for_var (SSA_NAME_DEF_STMT (end), var);
+ if (!okay_injuring_def (SSA_NAME_DEF_STMT (end), var))
+ break;
+ if (dump_file)
+ {
+ fprintf (dump_file, "Found a real injury:");
+ print_generic_stmt (dump_file, SSA_NAME_DEF_STMT (end), dump_flags);
+ fprintf (dump_file, "\n");
+ }
+ if (injured)
+ *injured = true;
+ end = find_rhs_use_for_var (SSA_NAME_DEF_STMT (end), var);
+ }
+ return end;
+}
+
+/* Return true if the result of the EPHI, when transformed into a phi,
+ will be available. */
+
+static inline bool
+ephi_will_be_avail (tree ephi)
+{
+ if (!EPHI_CANT_BE_AVAIL (ephi))
+ if (EPHI_STOPS (ephi))
+ return true;
+
+ return false;
+}
+
+/* EUSE node pool. We allocate EUSE nodes out of this*/
+static alloc_pool euse_node_pool;
+
+/* EREF node pool. We allocate regular EREF nodes (like EEXIT_NODE)
+ out of this. */
+static alloc_pool eref_node_pool;
+
+
+/* To order EREF's in a given block, we assign them each an ID based
+ on when we see them. */
+static int eref_id_counter = 0;
+
+/* Creation an expression reference of TYPE. */
+
+static tree
+create_expr_ref (struct expr_info *ei, tree expr, enum tree_code type,
+ basic_block bb, tree parent)
+{
+ tree ret;
+ if (type == EPHI_NODE)
+ {
+ int len;
+ edge e;
+
+ ret = create_ephi_node (bb, 1);
+ for (len = 0, e = bb->pred; e; e = e->pred_next)
+ len++;
+
+ EREF_TEMP (ret) = make_phi_node (ei->temp, len);
+ }
+ else
+ {
+ if (type == EUSE_NODE)
+ ret = (tree) pool_alloc (euse_node_pool);
+ else
+ ret = (tree) pool_alloc (eref_node_pool);
+ TREE_SET_CODE (ret, type);
+ memset (ret, 0, tree_size (ret));
+ TREE_SET_CODE (ret, type);
+ pre_stats.eref_allocated += tree_size (ret);
+ }
+
+ EREF_NAME (ret) = expr;
+ set_bb_for_stmt (ret, bb);
+ EREF_STMT (ret) = parent;
+ EREF_SAVE (ret) = false;
+ EREF_ID (ret) = eref_id_counter++;
+
+ return ret;
+}
+
+
+/* dfphis is a bitmap of where we need to insert ephis due to the
+ iterated dominance frontier of an expression. */
+
+static bitmap dfphis;
+
+/* varphis is a bitmap of where we need to insert ephis due to the
+ presence of phis for a variable. */
+
+static bitmap varphis;
+
+
+/* Function to recursively figure out where EPHI's need to be placed
+ because of PHI's.
+ We always place EPHI's where we place PHI's because they are also
+ partially anticipated expression points (because some expression
+ alteration reaches that merge point).
+
+ We do this recursively, because we have to figure out
+ EPHI's for the variables in the PHI as well. */
+
+static void
+set_var_phis (struct expr_info *ei, tree phi)
+{
+ basic_block bb = bb_for_stmt (phi);
+ /* If we've already got an EPHI set to be placed in PHI's BB, we
+ don't need to do this again. */
+ if (!bitmap_bit_p (varphis, bb->index)
+ && !bitmap_bit_p (dfphis, bb->index))
+ {
+ tree phi_operand;
+ int curr_phi_operand;
+ bitmap_set_bit (varphis, bb->index);
+ for (curr_phi_operand = 0;
+ curr_phi_operand < PHI_NUM_ARGS (phi);
+ curr_phi_operand++)
+ {
+ phi_operand = PHI_ARG_DEF (phi, curr_phi_operand);
+ /* For strength reduction, factor through injuries we can
+ repair. */
+ if (ei->strred_cand && TREE_CODE (phi_operand) != PHI_NODE)
+ {
+ phi_operand = factor_through_injuries (ei, phi_operand,
+ SSA_NAME_VAR (phi_operand),
+ NULL);
+ phi_operand = SSA_NAME_DEF_STMT (phi_operand);
+ if (dump_file)
+ {
+ fprintf (dump_file, "After factoring through injuries:");
+ print_generic_stmt (dump_file, phi_operand, dump_flags);
+ fprintf (dump_file, "\n");
+ }
+ }
+
+ /* If our phi operand is defined by a phi, we need to
+ record where the phi operands alter the expression as
+ well, and place EPHI's at each point. */
+ if (TREE_CODE (phi_operand) == PHI_NODE)
+ set_var_phis (ei, phi_operand);
+ }
+ }
+}
+
+
+/* Clear all the expression reference arrays. */
+
+static void
+clear_all_eref_arrays (void)
+{
+ basic_block bb;
+ bb_ann_t ann;
+
+ FOR_ALL_BB (bb)
+ {
+ ann = bb_ann (bb);
+ if (ann->ephi_nodes)
+ {
+ free (ann->ephi_nodes);
+ pre_stats.ephis_current -= 1;
+ }
+ ann->ephi_nodes = NULL;
+ }
+}
+
+/* EPHI insertion algorithm. */
+
+static bool
+expr_phi_insertion (bitmap *dfs, struct expr_info *ei)
+{
+ size_t i, j;
+ vuse_optype vuses;
+ use_optype uses;
+ bool retval = true;
+
+ dfphis = BITMAP_XMALLOC ();
+ bitmap_zero (dfphis);
+ varphis = BITMAP_XMALLOC ();
+ bitmap_zero (varphis);
+
+ /* Compute where we need to place EPHIS. There are two types of
+ places we need EPHI's: Those places we would normally place a
+ PHI for the occurrence (calculated by determining the IDF+ of
+ the statement), and those places we need an EPHI due to partial
+ anticipation. */
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->occurs); i++)
+ {
+ tree occurp = VARRAY_TREE (ei->occurs, i);
+ tree occur = occurp ? occurp : NULL;
+ tree killp = VARRAY_TREE (ei->kills, i);
+ tree kill = killp ? killp : NULL;
+ tree leftp = VARRAY_TREE (ei->lefts, i);
+ tree left = leftp ? leftp : NULL;
+ bitmap temp;
+ stmt_ann_t ann;
+
+#ifdef ENABLE_CHECKING
+ if ((kill && occur) || (left && occur) || (kill && left))
+ abort();
+#endif
+ occurp = occur ? occurp : kill ? killp : leftp;
+ occur = occur ? occur : kill ? kill : left;
+ temp = compute_idfs (dfs, occur);
+ bitmap_a_or_b (dfphis, dfphis, temp);
+ if (kill != NULL)
+ continue;
+ get_stmt_operands (occurp);
+ ann = stmt_ann (occurp);
+ uses = USE_OPS (ann);
+ for (j = 0; j < NUM_USES (uses); j ++)
+ {
+ tree use = USE_OP (uses, j);
+ if (ei->strred_cand)
+ use = factor_through_injuries (ei, use, SSA_NAME_VAR (use),
+ NULL);
+ if (TREE_CODE (SSA_NAME_DEF_STMT (use)) != PHI_NODE)
+ continue;
+ set_var_phis (ei, SSA_NAME_DEF_STMT (use));
+ }
+ if (ei->loadpre_cand && TREE_CODE (ei->expr) == INDIRECT_REF)
+ {
+ vuses = VUSE_OPS (ann);
+ for (j = 0; j < NUM_VUSES (vuses); j ++)
+ {
+ tree use = VUSE_OP (vuses, j);
+ if (ei->strred_cand)
+ use = factor_through_injuries (ei, use, SSA_NAME_VAR (use),
+ NULL);
+ if (TREE_CODE (SSA_NAME_DEF_STMT (use)) != PHI_NODE)
+ continue;
+ set_var_phis (ei, SSA_NAME_DEF_STMT (use));
+ }
+ }
+ }
+ /* Union the results of the dfphis and the varphis to get the
+ answer to everywhere we need EPHIS. */
+ bitmap_a_or_b (dfphis, dfphis, varphis);
+
+ /* Now create the EPHI's in each of these blocks. */
+ EXECUTE_IF_SET_IN_BITMAP(dfphis, 0, i,
+ {
+ tree ref = create_expr_ref (ei, ei->expr, EPHI_NODE, BASIC_BLOCK (i),
+ NULL);
+ EREF_PROCESSED (ref) = false;
+ EPHI_DOWNSAFE (ref) = true;
+ EPHI_DEAD (ref) = true;
+ });
+#if 0
+ /* If there are no phis, we don't have anything to optimize,
+ assuming the dominator optimizer took care of it all. */
+ if (bitmap_first_set_bit (dfphis) == -1)
+ retval = false;
+#endif
+ BITMAP_XFREE (dfphis);
+ BITMAP_XFREE (varphis);
+ return retval;
+
+}
+
+/* Return the EPHI at block BB, if one exists. */
+
+static inline tree
+ephi_at_block (basic_block bb)
+{
+ bb_ann_t ann = bb_ann (bb);
+ if (ann->ephi_nodes)
+ return ann->ephi_nodes;
+ else
+ return NULL_TREE;
+}
+
+/* Depth first numbering array. */
+static int *dfn;
+
+/* Build a depth first numbering array to be used in sorting in
+ dominator order. */
+
+static int
+build_dfn_array (basic_block bb, int num)
+{
+ basic_block son;
+
+ if (bb->index >= 0)
+ dfn[bb->index] = num;
+
+ for (son = first_dom_son (CDI_DOMINATORS, bb);
+ son;
+ son = next_dom_son (CDI_DOMINATORS, son))
+ num = build_dfn_array (son, ++num);
+ return num;
+}
+
+
+/* Compare two EREF's in terms of dominator preorder. Return -1 if
+ ELEM1 goes before ELEM2, 1 if ELEM1 goes after ELEM2, and 0 if they
+ are equal. */
+
+static int
+eref_compare (const void *elem1, const void *elem2)
+{
+ tree t1 = *(tree *)elem1;
+ tree t2 = *(tree *)elem2;
+ basic_block bb1, bb2;
+ if (t1 == t2)
+ return 0;
+ bb1 = bb_for_stmt (t1);
+ bb2 = bb_for_stmt (t2);
+ if (bb1 == bb2)
+ {
+ if (TREE_CODE (t1) == EEXIT_NODE)
+ return 1;
+ if (TREE_CODE (t2) == EEXIT_NODE)
+ return -1;
+ if (TREE_CODE (t1) == EPHI_NODE)
+ return -1;
+ if (TREE_CODE (t2) == EPHI_NODE)
+ return 1;
+ if ((TREE_CODE (t1) == EUSE_NODE && EUSE_PHIOP (t1))
+ && (TREE_CODE (t2) == EUSE_NODE && !EUSE_PHIOP (t2)))
+ return 1;
+ if ((TREE_CODE (t1) == EUSE_NODE && !EUSE_PHIOP (t1))
+ && (TREE_CODE (t2) == EUSE_NODE && EUSE_PHIOP (t2)))
+ return -1;
+ if (TREE_CODE (t1) == EUSE_NODE && TREE_CODE (t2) == EUSE_NODE)
+ return EREF_ID (t1) - EREF_ID (t2);
+ if (TREE_CODE (t1) == EPHI_NODE && TREE_CODE (t2) == EPHI_NODE)
+ abort ();
+
+ }
+ else
+ {
+ if (dfn[bb1->index] == dfn[bb2->index])
+ {
+ if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
+ return 1;
+ else
+ return -1;
+ }
+ else
+ return (dfn[bb1->index] < dfn[bb2->index]) ? -1 : 1;
+ }
+
+ abort ();
+}
+
+/* Create expression references for occurrences, kills, phi operands,
+ and the like. At the same time, insert the occurrences into the
+ ei->euses_dt_order array in the proper order. If this function had
+ any use outside of rename_1, you could split it into two
+ functions, one creating, one inserting. */
+
+static void
+create_and_insert_occ_in_preorder_dt_order (struct expr_info *ei)
+{
+ size_t i;
+ edge succ;
+ tree curr_phi_pred = NULL_TREE;
+ basic_block block;
+
+ /* The ephis references were already created, so just push them into
+ the euses_dt_order list. */
+ FOR_EACH_BB (block)
+ {
+ tree ephi = ephi_at_block (block);
+ /* The ordering for a given BB is EPHI's, real/left/kill
+ occurrences, phi preds, exit occurrences. */
+ if (ephi != NULL_TREE)
+ VARRAY_PUSH_TREE (ei->euses_dt_order, ephi);
+ }
+
+ /* The non-ephis have to actually be created, so do that, then push
+ them into the list. */
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->occurs); i++)
+ {
+ tree newref;
+ tree current;
+ current = VARRAY_TREE (ei->occurs, i);
+ current = current ? current : VARRAY_TREE (ei->kills, i);
+ current = current ? current : VARRAY_TREE (ei->lefts, i);
+ block = bb_for_stmt (current);
+ if (VARRAY_TREE (ei->kills, i) != NULL)
+ {
+ tree killexpr = VARRAY_TREE (ei->kills, i);
+ tree killname = ei->expr;
+ newref = create_expr_ref (ei, killname, EKILL_NODE, block, killexpr);
+ VARRAY_PUSH_TREE (ei->euses_dt_order, newref);
+ }
+ else if (VARRAY_TREE (ei->lefts, i) != NULL)
+ {
+ tree occurexpr = VARRAY_TREE (ei->lefts, i);
+ tree occurname;
+ occurname = ei->expr;
+ newref = create_expr_ref (ei, occurname, EUSE_NODE, block,
+ occurexpr);
+ EUSE_DEF (newref) = NULL_TREE;
+ EUSE_LVAL (newref) = true;
+ EREF_CLASS (newref) = -1;
+ EUSE_PHIOP (newref) = false;
+ EREF_PROCESSED (newref) = false;
+ VARRAY_PUSH_TREE (ei->euses_dt_order, newref);
+ }
+ else
+ {
+ tree occurexpr = VARRAY_TREE (ei->occurs, i);
+ tree occurname;
+ occurname = ei->expr;
+ newref = create_expr_ref (ei, occurname, EUSE_NODE, block,
+ occurexpr);
+ EUSE_DEF (newref) = NULL_TREE;
+ EREF_CLASS (newref) = -1;
+ EUSE_PHIOP (newref) = false;
+ EREF_PROCESSED (newref) = false;
+ VARRAY_PUSH_TREE (ei->euses_dt_order, newref);
+ }
+ }
+
+ /* Lastly, we need to create and insert the ephi operand occurrences
+ into the list. */
+ FOR_ALL_BB (block)
+ {
+ /* Insert the phi operand occurrences into the list at the
+ successors.*/
+ for (succ = block->succ; succ; succ = succ->succ_next)
+ {
+ if (succ->dest != EXIT_BLOCK_PTR)
+ {
+ tree ephi = ephi_at_block (succ->dest);
+ if (ephi != NULL
+ && !bitmap_bit_p (created_phi_preds, block->index))
+ {
+ tree newref = create_expr_ref (ei, 0, EUSE_NODE, block, NULL);
+ curr_phi_pred = newref;
+ VARRAY_PUSH_TREE (ei->euses_dt_order, newref);
+ EUSE_DEF (newref) = NULL_TREE;
+ EREF_CLASS (newref) = -1;
+ EUSE_PHIOP (newref) = true;
+ EREF_SAVE (newref) = false;
+ EREF_RELOAD (newref) = false;
+ EUSE_INSERTED (newref) = false;
+ EREF_PROCESSED (newref) = false;
+ bitmap_set_bit (created_phi_preds, block->index);
+ add_ephi_pred (ephi, newref, succ);
+ }
+ else if (ephi != NULL)
+ {
+#ifdef ENABLE_CHECKING
+ if (curr_phi_pred == NULL_TREE)
+ abort();
+#endif
+ add_ephi_pred (ephi, curr_phi_pred, succ);
+ }
+ }
+ else if (succ->dest == EXIT_BLOCK_PTR && !(succ->flags & EDGE_FAKE))
+ {
+ /* No point in inserting exit blocks into heap first, since
+ they'll never be anything on the stack. */
+ tree newref;
+ newref = create_expr_ref (ei, ei->expr, EEXIT_NODE,
+ block,
+ NULL);
+ VARRAY_PUSH_TREE (ei->euses_dt_order, newref);
+ }
+ }
+ }
+ qsort (ei->euses_dt_order->data.tree,
+ VARRAY_ACTIVE_SIZE (ei->euses_dt_order),
+ sizeof (tree),
+ eref_compare);
+}
+
+
+/* Assign a new redundancy class to the occurrence, and push it on the
+ renaming stack. */
+
+static void
+assign_new_class (tree occ, varray_type * stack, varray_type * stack2)
+{
+ /* class(occ) <- count
+ Push(occ, stack)
+ count <- count + 1
+ */
+ EREF_CLASS (occ) = class_count;
+ VARRAY_PUSH_TREE (*stack, occ);
+ if (stack2)
+ VARRAY_PUSH_TREE (*stack2, occ);
+ class_count++;
+}
+
+/* Determine if two real occurrences have the same ESSA version.
+ We do this by hashing the expressions and comparing the hash
+ values. Even if they don't match, we then see if this is a
+ strength reduction candidate, and if so, if the use is simply
+ injured. */
+
+static inline bool
+same_e_version_real_occ_real_occ (struct expr_info *ei,
+ const tree def, const tree use)
+{
+ hashval_t expr1val;
+ hashval_t expr2val;
+ vuse_optype vuses;
+ size_t i;
+ const tree t1 = EREF_STMT (def);
+ const tree t2 = EREF_STMT (use);
+
+ expr1val = iterative_hash_expr (TREE_OPERAND (t1, 1), 0);
+ expr2val = iterative_hash_expr (TREE_OPERAND (t2, 1), 0);
+
+ if (expr1val == expr2val)
+ {
+ vuses = STMT_VUSE_OPS (t1);
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ expr1val = iterative_hash_expr (VUSE_OP (vuses, i), expr1val);
+ vuses = STMT_VUSE_OPS (t2);
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ expr2val = iterative_hash_expr (VUSE_OP (vuses, i), expr2val);
+ if (expr1val != expr2val)
+ return false;
+ }
+
+ /* If the def is injured, and the expressions have the same value,
+ then the use is injured. */
+ if (expr1val == expr2val)
+ {
+ if (EREF_INJURED (def))
+ EREF_INJURED (use) = true;
+ return true;
+ }
+
+ /* Even if the expressions don't have the same value, it might be
+ the case that the use is simply injured, in which case, it's
+ still okay. */
+ if (expr1val != expr2val && ei->strred_cand)
+ {
+ if (injured_real_occ_real_occ (ei, def, use))
+ {
+ EREF_INJURED (use) = true;
+ return true;
+ }
+ }
+ return false;
+}
+
+/* Determine if the use occurrence is injured.
+ TODO: Finish actually implementing this. */
+
+static inline bool
+injured_real_occ_real_occ (struct expr_info *ei ATTRIBUTE_UNUSED,
+ tree def ATTRIBUTE_UNUSED,
+ tree use ATTRIBUTE_UNUSED)
+{
+ tree defstmt;
+ tree defvar;
+
+ defstmt = EREF_STMT (def);
+ if (TREE_CODE (TREE_OPERAND (defstmt, 0)) != SSA_NAME)
+ return false;
+
+ defvar = TREE_OPERAND (defstmt, 0);
+ /* XXX: Implement. */
+ return false;
+
+}
+
+/* Determine the operand number of edge E in EPHI. */
+
+static inline int
+opnum_of_ephi (const tree ephi, const edge e)
+{
+ ephi_pindex_t ep, *epp;
+
+ ep.ephi = ephi;
+ ep.edge = e;
+ epp = htab_find (ephi_pindex_htab, &ep);
+ if (epp == NULL)
+ abort ();
+ return epp->opnd;
+}
+
+/* Determine the phi operand index for J in PHI. */
+
+static inline int
+opnum_of_phi (tree phi, int j)
+{
+ int i;
+ /* We can't just count predecessors, since tree-ssa.c generates them
+ when it sees a phi in the successor during it's traversal. So the
+ order is dependent on the traversal order. */
+ for (i = 0 ; i < PHI_NUM_ARGS (phi); i++)
+ if (PHI_ARG_EDGE (phi, i)->src->index == j)
+ return i;
+
+ abort();
+}
+
+/* Generate EXPR as it would look in basic block PRED (using the phi in
+ block BB). We do this by replacing the variables with the phi
+ argument definitions for block J if they are defined by a phi in
+ block BB. */
+
+static void
+generate_expr_as_of_bb (tree expr, basic_block pred, basic_block bb)
+{
+ use_optype uses = STMT_USE_OPS (expr);
+ bool replaced_constants = false;
+ size_t k;
+
+ for (k = 0; k < NUM_USES (uses); k++)
+ {
+ tree *vp = USE_OP_PTR (uses, k);
+ tree v = *vp;
+ tree phi;
+
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ if (PHI_RESULT (phi) == v)
+ {
+ int opnum = opnum_of_phi (phi, pred->index);
+ tree p = PHI_ARG_DEF (phi, opnum);
+ replace_exp (vp, p);
+ if (!phi_ssa_name_p (p))
+ replaced_constants = true;
+ break;
+ }
+ }
+ }
+
+ /* If we've substituted in new constants, we must be sure to
+ simplify the result lest we crash in get_expr_operands. */
+ if (replaced_constants)
+ fold_stmt (&expr);
+}
+
+/* Generate VUSE ops as they would look in basic block PRED (using the
+ phi in block BB). Done the same way as we do generation of regular
+ ops for the bb. */
+
+static void
+generate_vops_as_of_bb (tree expr, basic_block pred, basic_block bb)
+{
+ vuse_optype vuses = STMT_VUSE_OPS (expr);
+ size_t i;
+
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ {
+ tree v = VUSE_OP (vuses, i);
+ tree phi;
+
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ if (PHI_RESULT (phi) == v)
+ {
+ int opnum = opnum_of_phi (phi, pred->index);
+ tree p = PHI_ARG_DEF (phi, opnum);
+ replace_exp (VUSE_OP_PTR (vuses, i), p);
+ break;
+ }
+ }
+ }
+}
+
+/* Make a copy of Z as it would look in basic block PRED, using the PHIs
+ in BB. */
+
+static tree
+subst_phis (struct expr_info *ei, tree Z, basic_block pred, basic_block bb)
+{
+ tree stmt_copy;
+ size_t i;
+
+ /* Return the cached version, if we have one. */
+ if (pred->index < n_phi_preds
+ && phi_pred_cache[pred->index] != NULL_TREE)
+ return phi_pred_cache[pred->index];
+
+ /* Otherwise, generate a new expression. */
+ pre_stats.exprs_generated++;
+ stmt_copy = unshare_expr (Z);
+ create_stmt_ann (stmt_copy);
+ modify_stmt (stmt_copy);
+ get_stmt_operands (stmt_copy);
+ generate_expr_as_of_bb (stmt_copy, pred, bb);
+ set_bb_for_stmt (stmt_copy, bb);
+ modify_stmt (stmt_copy);
+ get_stmt_operands (stmt_copy);
+
+ /* If we have vuses on the original statement, and we still have
+ use_ops on the generated expr, we need to copy the vuses. */
+
+ if (ei->loadpre_cand
+ && NUM_VUSES (STMT_VUSE_OPS (Z)) != 0
+ && NUM_USES (STMT_USE_OPS (stmt_copy)) != 0)
+ {
+ vuse_optype vuses = STMT_VUSE_OPS (Z);
+ remove_vuses (stmt_copy);
+
+ start_ssa_stmt_operands (stmt_copy);
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ add_vuse (VUSE_OP (vuses, i), stmt_copy);
+ finalize_ssa_stmt_operands (stmt_copy);
+
+ generate_vops_as_of_bb (stmt_copy, pred, bb);
+ }
+ else
+ {
+ remove_vuses (stmt_copy);
+ remove_vdefs (stmt_copy);
+ }
+
+ if (pred->index < n_phi_preds)
+ phi_pred_cache[pred->index] = stmt_copy;
+ return stmt_copy;
+}
+
+/* Determine if def and use_tree should have the same e-version. We do
+ this by simply determining if something modifies the expression
+ between DEF and USE_TREE. USE_TREE was generated from the OPND_NUM'th
+ operand of the EPHI in USE_BB. If it is modified, we determine if
+ it is simply injured, and thus, okay. */
+
+static inline bool
+same_e_version_real_occ_phi_opnd (struct expr_info *ei, tree def,
+ basic_block use_bb, int opnd_num,
+ tree use_tree, bool *injured)
+{
+ bool not_mod = true;
+ *injured = false;
+
+ if (load_modified_real_occ_real_occ (EREF_STMT (def),
+ use_tree))
+ not_mod = false;
+
+ if (not_mod)
+ return true;
+ else if (ei->strred_cand)
+ {
+ if (injured_real_occ_phi_opnd (ei, def, use_bb, opnd_num))
+ return true;
+ }
+ return false;
+}
+
+/* Determine whether the OPND_NUM'th operand of USE_BB's EPHI is an
+ injured version of DEF. */
+static inline bool
+injured_real_occ_phi_opnd (struct expr_info *ei ATTRIBUTE_UNUSED,
+ tree def ATTRIBUTE_UNUSED,
+ basic_block use_bb ATTRIBUTE_UNUSED,
+ int opnd_num ATTRIBUTE_UNUSED)
+{
+ /* XXX: Implement. */
+ return false;
+}
+
+/* Determine whether the expression is modified between DEF and USE,
+ by comparing the hash values of the two expressions. */
+static inline bool
+load_modified_real_occ_real_occ (tree def, tree use)
+{
+ hashval_t expr1val;
+ hashval_t expr2val;
+ vuse_optype vuses;
+ size_t i;
+
+ if (TREE_CODE (def) == VA_ARG_EXPR)
+ expr1val = iterative_hash_expr (def, 0);
+ else
+ expr1val = iterative_hash_expr (TREE_OPERAND (def, 1), 0);
+
+ if (TREE_CODE (use) == VA_ARG_EXPR)
+ expr2val = iterative_hash_expr (use, 0);
+ else
+ expr2val = iterative_hash_expr (TREE_OPERAND (use, 1), 0);
+
+ if (expr1val == expr2val)
+ {
+ vuses = STMT_VUSE_OPS (def);
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ expr1val = iterative_hash_expr (VUSE_OP (vuses, i), expr1val);
+ vuses = STMT_VUSE_OPS (use);
+ for (i = 0; i < NUM_VUSES (vuses); i++)
+ expr2val = iterative_hash_expr (VUSE_OP (vuses, i), expr2val);
+ if (expr1val != expr2val)
+ return false;
+ }
+ return expr1val != expr2val;
+}
+
+/* Determine if the expression is modified between the start of BB,
+ and the use at USE, ignoring phis. We do this by simple
+ domination, because of the properties of SSA. */
+static bool
+load_modified_phi_result (basic_block bb, tree use)
+{
+ basic_block defbb = bb_for_stmt (SSA_NAME_DEF_STMT (use));
+ if (defbb != bb)
+ {
+ /* This guards against moving around undefined variables.
+ However, PARM_DECL is special because it *IS* live on entry,
+ so it's not really undefined. */
+ if (!defbb && TREE_CODE (SSA_NAME_VAR (use)) != PARM_DECL)
+ return true;
+ else if (!defbb && TREE_CODE (SSA_NAME_VAR (use)) == PARM_DECL)
+ return false;
+ if (dominated_by_p (CDI_DOMINATORS, bb, defbb))
+ return false;
+ }
+ else
+ {
+ if (TREE_CODE (SSA_NAME_DEF_STMT (use)) == PHI_NODE)
+ return false;
+ }
+ return true;
+}
+
+/* Determine if the variables in EXP are modified between DEF and
+ USE. If they are, we have to give a new e-version to the result.
+ For load PRE, we have to check the vuses too. For strength
+ reduction, we need to check whether the modification is a simple
+ injury. */
+
+static bool
+same_e_version_phi_result (struct expr_info *ei, tree def, tree exp,
+ tree use)
+{
+ stmt_ann_t ann = stmt_ann (exp);
+ bool not_mod = true;
+ size_t i;
+ use_optype real_expuses = USE_OPS (ann);
+ vuse_optype expuses;
+
+
+ if (NUM_USES (real_expuses) == 0)
+ return false;
+
+ for (i = 0; i < NUM_USES (real_expuses) && not_mod; i++)
+ {
+ tree *use1p = USE_OP_PTR (real_expuses, i);
+ tree use1;
+ if (!use1p)
+ continue;
+ use1 = *use1p;
+ if (load_modified_phi_result (bb_for_stmt (def), use1))
+ not_mod = false;
+ }
+
+ if (not_mod && ei->loadpre_cand)
+ {
+ expuses = VUSE_OPS (ann);
+
+ for (i = 0; i < NUM_VUSES (expuses) && not_mod; i++)
+ {
+ tree use1 = VUSE_OP (expuses, i);
+ if (load_modified_phi_result (bb_for_stmt (def), use1))
+ not_mod = false;
+ }
+ }
+
+ if (not_mod)
+ return true;
+ else if (ei->strred_cand)
+ {
+ if (injured_phi_result_real_occ (ei, def, exp, bb_for_stmt (use)))
+ {
+ EREF_INJURED (use) = true;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/* Determine whether USE_TREE is an injured version of DEF. */
+
+static inline bool
+injured_phi_result_real_occ (struct expr_info *ei ATTRIBUTE_UNUSED,
+ tree def ATTRIBUTE_UNUSED,
+ tree use_tree ATTRIBUTE_UNUSED,
+ basic_block use_bb ATTRIBUTE_UNUSED)
+{
+ /* XXX: Implement. */
+ return false;
+}
+
+/* Delayed renaming checks to make sure the optimistic assumptions
+ about ephi operand versions in rename_1 actually turned out to be
+ true. This requires generating the expressions for each ephi
+ operand, and comparing them to the versions of the occurrence it is
+ defined by.
+ Delayed rename handling is done like open64 does it. Basically,
+ like the delayed renaming is described in the paper, with
+ extensions for strength reduction. */
+
+static void
+process_delayed_rename (struct expr_info *ei, tree use, tree real_occ)
+{
+ tree exp_phi = use;
+ int opnd_num = 0;
+
+ /* We only care about operands we actually have DELAYED_RENAME set
+ on. */
+ for (opnd_num = 0; opnd_num < EPHI_NUM_ARGS (exp_phi); opnd_num++)
+ {
+ tree opnd = EPHI_ARG_DEF (exp_phi, opnd_num);
+ if (EPHI_ARG_DELAYED_RENAME (exp_phi, opnd_num))
+ {
+ tree def;
+ tree newexp;
+
+ /* Mark it as being processed, then generate the ephi
+ operand expression. */
+ EPHI_ARG_DELAYED_RENAME (exp_phi, opnd_num) = false;
+ def = opnd;
+ newexp = subst_phis (ei, real_occ,
+ EPHI_ARG_EDGE (exp_phi, opnd_num)->src,
+ bb_for_stmt (exp_phi));
+
+ /* For operands defined by EPHIs, we need to compare the
+ generated expression and the phi result.
+ For operands defined by real occurrences, we simply compare
+ the phi operand and the real occurrence. */
+ if (TREE_CODE (def) == EPHI_NODE)
+ {
+ tree tmp_use = EPHI_ARG_PRED (exp_phi, opnd_num);
+ EREF_STMT (tmp_use) = newexp;
+ if (same_e_version_phi_result (ei, def, newexp,
+ tmp_use))
+ {
+
+ if (EREF_INJURED (tmp_use))
+ {
+ EREF_INJURED (tmp_use) = false;
+ EPHI_ARG_INJURED (exp_phi, opnd_num) = true;
+ }
+ if (EREF_STMT (def) == NULL)
+ {
+ /* If it was injured, we need to make up a new
+ phi result with the actually injured
+ version. */
+ if (EPHI_ARG_INJURED (exp_phi, opnd_num))
+ {
+ /* XXX: Allocate phi result with correct version. */
+
+ }
+ EREF_STMT (def) = newexp;
+ process_delayed_rename (ei, def, newexp);
+ }
+ }
+ /* If it's not the same version, the defining ephi can't
+ be downsafe, and the operand is not really defined by
+ anything. */
+ else
+ {
+ EPHI_DOWNSAFE (def) = false;
+ EPHI_ARG_DEF (exp_phi, opnd_num) = NULL;
+ }
+ }
+ else if (TREE_CODE (def) == EUSE_NODE && !EUSE_PHIOP (def))
+ {
+ bool injured = false;
+ if (same_e_version_real_occ_phi_opnd (ei, def,
+ bb_for_stmt (use),
+ opnd_num, newexp, &injured))
+ {
+ tree tmp_use = EPHI_ARG_PRED (exp_phi, opnd_num);
+ EPHI_ARG_HAS_REAL_USE (exp_phi, opnd_num) = true;
+ /* EREF_STMT (opnd) = EREF_STMT (def); */
+ if (injured || EREF_INJURED (def))
+ EREF_INJURED (def) = true;
+ if (injured || EREF_INJURED (def))
+ EREF_INJURED (opnd) = true;
+ else
+ EREF_STMT (tmp_use) = EREF_STMT (def);
+ if (EUSE_DEF (def) != NULL)
+ EPHI_ARG_DEF (exp_phi, opnd_num) = EUSE_DEF (def);
+ else
+ EPHI_ARG_DEF (exp_phi, opnd_num) = def;
+ }
+ else
+ {
+ EPHI_ARG_DEF (exp_phi, opnd_num) = NULL;
+ }
+ }
+ }
+ }
+}
+
+/* For the uninitiated, the algorithm is a modified SSA renaming
+ algorithm (working on expressions rather than variables) . We
+ attempt to determine which expression occurrences have the same
+ ESSA version (we call it class, for equivalence/redunancy class,
+ which is what the papers call it. Open64 calls it e-version), and
+ which occurrences are actually operands for an EPHI (since this has
+ to be discovered from the program).
+
+ Renaming is done like Open64 does it. Basically as the paper says,
+ except that we try to use earlier defined occurrences if they are
+ available in order to keep the number of saves down. */
+
+static void
+rename_1 (struct expr_info *ei)
+{
+ tree occur;
+ basic_block phi_bb;
+ size_t i;
+ varray_type stack;
+
+ VARRAY_GENERIC_PTR_NOGC_INIT (stack, 1, "Stack for renaming");
+
+ /* Start by creating and inserting the occurrences in preorder,
+ dominator tree into a list. */
+ create_and_insert_occ_in_preorder_dt_order (ei);
+
+ /* Walk the occurrences. */
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
+ {
+ occur = VARRAY_TREE (ei->euses_dt_order, i);
+
+ /* The current occurrence can't have the same version as
+ something on the top of the stack unless it is in a basic
+ block dominated by the basic block of the occurrence on the
+ top of the stack. */
+ while (VARRAY_ACTIVE_SIZE (stack) > 0
+ && !dominated_by_p (CDI_DOMINATORS,
+ bb_for_stmt (occur),
+ bb_for_stmt (VARRAY_TOP_TREE (stack))))
+
+ VARRAY_POP (stack);
+
+ /* If the stack is empty, we assign a new version since it isn't
+ dominated by any other version. */
+ if (VARRAY_ACTIVE_SIZE (stack) == 0 || VARRAY_TOP_TREE (stack) == NULL)
+ {
+ if (TREE_CODE (occur) == EPHI_NODE)
+ assign_new_class (occur, &stack, NULL);
+ else if (TREE_CODE (occur) == EUSE_NODE && !EUSE_PHIOP (occur))
+ assign_new_class (occur, &stack, NULL);
+ }
+ else
+ {
+ if (TREE_CODE (occur) == EUSE_NODE && !EUSE_PHIOP (occur))
+ {
+ tree tos = VARRAY_TOP_TREE (stack);
+
+ if (TREE_CODE (tos) == EUSE_NODE && !EUSE_PHIOP (tos))
+ {
+ /* If two real occurrences have the same
+ e-version/class, then this occurrence can be
+ defined by the prior occurrence (or whatever
+ the prior occurrence is defined by, if
+ anything).
+ Otherwise, we have to assign a new version.
+ lvalue occurrences always need a new version,
+ since they are definitions. */
+ if (!EUSE_LVAL (occur)
+ && same_e_version_real_occ_real_occ (ei, tos, occur))
+ {
+
+
+ tree newdef;
+ EREF_CLASS (occur) = EREF_CLASS (tos);
+ newdef = EUSE_DEF (tos) != NULL ? EUSE_DEF (tos) : tos;
+ EUSE_DEF (occur) = newdef;
+ }
+ else
+ assign_new_class (occur, &stack, NULL);
+ }
+ else if (TREE_CODE (tos) == EPHI_NODE)
+ {
+ /* Here we have an ephi occurrence at the top of the
+ stack, and the current occurrence is a real
+ occurrence. So determine if the real occurrence
+ has the same version as the result of the phi.
+ If so, then this real occurrence is defined by the
+ EPHI at the top of the stack.
+ If not, the EPHI isn't downsafe (because something
+ must change in between the ephi result and the next
+ occurrence), and we need a new version for the real
+ occurrence.
+ lvalues always need a new version. */
+ if (!EUSE_LVAL (occur)
+ && same_e_version_phi_result (ei, tos, EREF_STMT (occur),
+ occur))
+ {
+ EREF_CLASS (occur) = EREF_CLASS (tos);
+ EUSE_DEF (occur) = tos;
+ EREF_STMT (tos) = EREF_STMT (occur);
+
+ VARRAY_PUSH_TREE (stack, occur);
+ }
+ else
+ {
+ EPHI_DOWNSAFE (tos) = false;
+ assign_new_class (occur, &stack, NULL);
+ }
+ }
+ }
+ /* EPHI occurrences always get new versions. */
+ else if (TREE_CODE (occur) == EPHI_NODE)
+ {
+ assign_new_class (occur, &stack, NULL);
+ }
+ /* EPHI operands are optimistcally assumed to be whatever is
+ at the top of the stack at the time we hit the ephi
+ operand occurrence. The delayed renaming checks this
+ optimistic assumption for validity. */
+ else if (TREE_CODE (occur) == EUSE_NODE && EUSE_PHIOP (occur))
+ {
+ basic_block pred_bb = bb_for_stmt (occur);
+ edge e;
+ tree tos = VARRAY_TOP_TREE (stack);
+ for (e = pred_bb->succ; e; e = e->succ_next)
+ {
+ tree ephi = ephi_at_block (e->dest);
+ if (ephi != NULL_TREE)
+ {
+ int opnum = opnum_of_ephi (ephi, e);
+
+ EPHI_ARG_DELAYED_RENAME (ephi, opnum) = true;
+ EPHI_ARG_DEF (ephi, opnum) = tos;
+ }
+ }
+ }
+ /* No EPHI can be downsafe past an exit node. */
+ else if (TREE_CODE (occur) == EEXIT_NODE)
+ {
+ if (VARRAY_ACTIVE_SIZE (stack) > 0
+ && TREE_CODE (VARRAY_TOP_TREE (stack)) == EPHI_NODE)
+ EPHI_DOWNSAFE (VARRAY_TOP_TREE (stack)) = false;
+ }
+ }
+ }
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ size_t i;
+ fprintf (dump_file, "Occurrences for expression ");
+ print_generic_expr (dump_file, ei->expr, dump_flags);
+ fprintf (dump_file, " after Rename 1\n");
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
+ {
+ print_generic_expr (dump_file,
+ VARRAY_TREE (ei->euses_dt_order, i), 1);
+ fprintf (dump_file, "\n");
+ }
+ }
+
+ /* Now process the renames for EPHI's that actually have the result
+ valid and used. These will be the EPHI's that have the statement
+ set above. */
+ FOR_EACH_BB (phi_bb)
+ {
+ tree ephi = ephi_at_block (phi_bb);
+ if (ephi != NULL && EREF_STMT (ephi) != NULL)
+ process_delayed_rename (ei, ephi, EREF_STMT (ephi));
+ }
+
+ /* If we didn't process the delayed rename for an ephi argument,
+ but thought we needed to, mark the operand as NULL. Also, if the
+ operand was defined by an EPHI, we can mark it not downsafe
+ because there can't have been a real occurrence (or else we would
+ have processed a rename for it). */
+ FOR_EACH_BB (phi_bb)
+ {
+ tree ephi = ephi_at_block (phi_bb);
+ if (ephi != NULL)
+ {
+ int j;
+ for (j = 0; j < EPHI_NUM_ARGS (ephi); j++)
+ {
+ if (EPHI_ARG_DELAYED_RENAME (ephi, j))
+ {
+ tree def = EPHI_ARG_DEF (ephi, j);
+ if (def && TREE_CODE (def) == EPHI_NODE)
+ EPHI_DOWNSAFE (def) = false;
+ EPHI_ARG_DEF (ephi, j) = NULL;
+ }
+ }
+ }
+ }
+ VARRAY_FREE (stack);
+}
+
+/* Determine if the EPHI has an argument we could never insert
+ or extend the lifetime of, such as an argument occurring on
+ an abnormal edge. */
+
+static bool
+ephi_has_unsafe_arg (tree ephi)
+{
+ int i;
+ for (i = 0; i < EPHI_NUM_ARGS (ephi); i++)
+ if (EPHI_ARG_EDGE (ephi, i)->flags & EDGE_ABNORMAL)
+ return true;
+ return false;
+}
+
+/* Reset down safety flags for non-downsafe ephis. Uses depth first
+ search. */
+
+static void
+reset_down_safe (tree currphi, int opnum)
+{
+ tree ephi;
+ int i;
+
+ if (EPHI_ARG_HAS_REAL_USE (currphi, opnum))
+ return;
+ ephi = EPHI_ARG_DEF (currphi, opnum);
+ if (!ephi || TREE_CODE (ephi) != EPHI_NODE)
+ return;
+ if (!EPHI_DOWNSAFE (ephi))
+ return;
+ EPHI_DOWNSAFE (ephi) = false;
+ for (i = 0; i < EPHI_NUM_ARGS (ephi); i++)
+ reset_down_safe (ephi, i);
+}
+
+/* Compute down_safety using a depth first search.
+ This propagates not fully anticipated phi assignments upwards. */
+
+static void
+compute_down_safety (struct expr_info *ei)
+{
+ size_t i;
+ basic_block bb;
+ FOR_EACH_BB (bb)
+ {
+ tree ephi = ephi_at_block (bb);
+ if (ephi == NULL_TREE)
+ continue;
+ if (ephi_has_unsafe_arg (ephi))
+ EPHI_DOWNSAFE (ephi) = false;
+ }
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
+ {
+ int j;
+ tree ephi = VARRAY_TREE (ei->euses_dt_order, i);
+ if (TREE_CODE (ephi) != EPHI_NODE)
+ continue;
+
+ if (!EPHI_DOWNSAFE (ephi))
+ for (j = 0; j < EPHI_NUM_ARGS (ephi); j++)
+ reset_down_safe (ephi, j);
+
+ }
+}
+
+/* EPHI use node pool. We allocate ephi_use_node's out of this. */
+static alloc_pool ephi_use_pool;
+
+/* Add a use of DEF to it's use list. The use is at operand OPND_INDX
+ of USE. */
+
+static void
+add_ephi_use (tree def, tree use, int opnd_indx)
+{
+ struct ephi_use_entry *entry;
+ if (EPHI_USES (def) == NULL)
+ VARRAY_GENERIC_PTR_INIT (EPHI_USES (def), 1, "EPHI uses");
+ entry = (struct ephi_use_entry *) pool_alloc (ephi_use_pool);
+ entry->phi = use;
+ entry->opnd_indx = opnd_indx;
+ VARRAY_PUSH_GENERIC_PTR (EPHI_USES (def), entry);
+}
+
+/* Compute def-uses of ephis. */
+
+static void
+compute_du_info (struct expr_info *ei)
+{
+ size_t i;
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
+ {
+ int j;
+ tree ephi = VARRAY_TREE (ei->euses_dt_order, i);
+ if (TREE_CODE (ephi) != EPHI_NODE)
+ continue;
+ for (j = 0; j < EPHI_NUM_ARGS (ephi); j++)
+ {
+ tree def = EPHI_ARG_DEF (ephi, j);
+ if (def != NULL_TREE)
+ {
+ if (TREE_CODE (def) == EPHI_NODE)
+ add_ephi_use (def, ephi, j);
+#ifdef ENABLE_CHECKING
+ else
+ if (! (TREE_CODE (def) == EUSE_NODE && !EUSE_PHIOP (def)))
+ abort();
+#endif
+ }
+ }
+ }
+}
+
+/* STOPS marks what EPHI's/operands stop forward movement. (IE where
+ we can't insert past). */
+
+static void
+compute_stops (struct expr_info *ei)
+{
+ size_t i;
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
+ {
+ tree ephi = VARRAY_TREE (ei->euses_dt_order, i);
+ int j;
+
+ if (TREE_CODE (ephi) != EPHI_NODE)
+ continue;
+ if (EPHI_CANT_BE_AVAIL (ephi))
+ EPHI_STOPS (ephi) = true;
+ for (j = 0; j < EPHI_NUM_ARGS (ephi); j++)
+ if (EPHI_ARG_HAS_REAL_USE (ephi, j))
+ EPHI_ARG_STOPS (ephi, j) = true;
+ }
+ do_ephi_df_search (ei, stops_search);
+}
+
+/* Compute will_be_avail property, which consists of cant_be_avail and
+ stops properties. */
+
+static void
+compute_will_be_avail (struct expr_info *ei)
+{
+ do_ephi_df_search (ei, cant_be_avail_search);
+ compute_stops (ei);
+}
+
+/* Insert the expressions into ei->euses_dt_order in preorder dt order. */
+
+static void
+insert_euse_in_preorder_dt_order (struct expr_info *ei)
+{
+ varray_type new_euses_dt_order;
+ size_t i;
+ VARRAY_GENERIC_PTR_NOGC_INIT (new_euses_dt_order, 1, "EUSEs");
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
+ {
+ tree ref = VARRAY_TREE (ei->euses_dt_order, i);
+ if (TREE_CODE (ref) == EUSE_NODE || TREE_CODE (ref) == EPHI_NODE)
+ VARRAY_PUSH_TREE (new_euses_dt_order, ref);
+ }
+ VARRAY_FREE (ei->euses_dt_order);
+ ei->euses_dt_order = new_euses_dt_order;
+ qsort (ei->euses_dt_order->data.tree,
+ VARRAY_ACTIVE_SIZE (ei->euses_dt_order),
+ sizeof (tree),
+ eref_compare);
+
+}
+
+/* Determine if we can insert operand OPND_INDX of EPHI. */
+
+static bool
+can_insert (tree ephi, int opnd_indx)
+{
+ tree def;
+
+ if (EPHI_ARG_DEF (ephi, opnd_indx) == NULL_TREE)
+ return true;
+ def = EPHI_ARG_DEF (ephi, opnd_indx);
+ if (!EPHI_ARG_HAS_REAL_USE (ephi, opnd_indx))
+ if (TREE_CODE (def) == EPHI_NODE && !(ephi_will_be_avail (def)))
+ return true;
+ return false;
+}
+
+/* Find the default definition of VAR.
+ This is incredibly ugly, since we have to walk back through all
+ the definitions to find the one defined by the empty statement. */
+
+static tree
+get_default_def (tree var, htab_t seen)
+{
+ def_optype defs;
+ size_t i;
+ tree defstmt = SSA_NAME_DEF_STMT (var);
+
+ if (IS_EMPTY_STMT (defstmt))
+ return var;
+ *(htab_find_slot (seen, var, INSERT)) = var;
+ if (TREE_CODE (defstmt) == PHI_NODE)
+ {
+ int j;
+ for (j = 0; j < PHI_NUM_ARGS (defstmt); j++)
+ if (htab_find (seen, PHI_ARG_DEF (defstmt, j)) == NULL)
+ {
+ if (TREE_CODE (PHI_ARG_DEF (defstmt, j)) == SSA_NAME)
+ {
+ tree temp = get_default_def (PHI_ARG_DEF (defstmt, j), seen);
+ if (temp != NULL_TREE)
+ return temp;
+ }
+ }
+ }
+
+
+ defs = STMT_DEF_OPS (defstmt);
+ for (i = 0; i < NUM_DEFS (defs); i++)
+ {
+ tree def = DEF_OP (defs, i);
+ if (SSA_NAME_VAR (def) == SSA_NAME_VAR (var))
+ {
+ if (htab_find (seen, def) != NULL)
+ return NULL;
+ return get_default_def (def, seen);
+ }
+ }
+
+ /* We should never get here. */
+ abort ();
+}
+
+/* Hunt down the right reaching def for VAR, starting with BB. Ignore
+ defs in statement IGNORE, and stop if we hit CURRSTMT. */
+
+static tree
+reaching_def (tree var, tree currstmt, basic_block bb, tree ignore)
+{
+ tree curruse = NULL_TREE;
+ block_stmt_iterator bsi;
+ basic_block dom;
+ tree phi;
+
+ /* Check phis first. */
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ if (phi == currstmt)
+ break;
+ if (phi == ignore)
+ continue;
+ if (names_match_p (var, PHI_RESULT (phi)))
+ curruse = PHI_RESULT (phi);
+ }
+
+ /* We can't walk BB's backwards right now, so we have to walk *all*
+ the statements, and choose the last name we find. */
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ tree stmt = bsi_stmt (bsi);
+ tree *def;
+ def_optype defs;
+ size_t i;
+
+ if (stmt == currstmt)
+ break;
+
+ get_stmt_operands (stmt);
+ defs = STMT_DEF_OPS (stmt);
+ for (i = 0; i < NUM_DEFS (defs); i++)
+ {
+ def = DEF_OP_PTR (defs, i);
+ if (def && *def != ignore && names_match_p (var, *def))
+ {
+ curruse = *def;
+ break;
+ }
+ }
+ }
+ if (curruse != NULL_TREE)
+ return curruse;
+ dom = get_immediate_dominator (CDI_DOMINATORS, bb);
+ if (bb == ENTRY_BLOCK_PTR)
+ {
+ htab_t temp;
+ temp = htab_create (7, htab_hash_pointer, htab_eq_pointer, NULL);
+ curruse = get_default_def (var, temp);
+ htab_delete (temp);
+ }
+ if (!dom)
+ return curruse;
+ return reaching_def (var, currstmt, dom, ignore);
+}
+
+/* Insert one ephi operand that doesn't currently exist as a use. */
+
+static void
+insert_one_operand (struct expr_info *ei, tree ephi, int opnd_indx,
+ tree x, edge succ, tree **avdefsp)
+{
+ /* FIXME. pre_insert_on_edge should probably disappear. */
+ extern void pre_insert_on_edge (edge, tree);
+ tree expr;
+ tree temp = ei->temp;
+ tree copy;
+ tree newtemp;
+ basic_block bb = bb_for_stmt (x);
+
+ /* Insert definition of expr at end of BB containing x. */
+ copy = TREE_OPERAND (EREF_STMT (ephi), 1);
+ copy = unshare_expr (copy);
+ expr = build (MODIFY_EXPR, TREE_TYPE (ei->expr),
+ temp, copy);
+ expr = subst_phis (ei, expr, bb, bb_for_stmt (ephi));
+ newtemp = make_ssa_name (temp, expr);
+ TREE_OPERAND (expr, 0) = newtemp;
+ copy = TREE_OPERAND (expr, 1);
+ if (dump_file)
+ {
+ fprintf (dump_file, "In BB %d, insert save of ", bb->index);
+ print_generic_expr (dump_file, expr, dump_flags);
+ fprintf (dump_file, " to ");
+ print_generic_expr (dump_file, newtemp, dump_flags);
+ fprintf (dump_file, " after ");
+ print_generic_stmt (dump_file, last_stmt (bb), dump_flags);
+ fprintf (dump_file, " (on edge), because of EPHI");
+ fprintf (dump_file, " in BB %d\n", bb_for_stmt (ephi)->index);
+ }
+
+ /* Do the insertion. */
+ /* ??? Previously we did bizarre searching, presumably to get
+ around bugs elsewhere in the infrastructure. I'm not sure
+ if we really should be using pre_insert_on_edge
+ or just bsi_insert_after at the end of BB. */
+ pre_insert_on_edge (succ, expr);
+
+ EPHI_ARG_DEF (ephi, opnd_indx)
+ = create_expr_ref (ei, ei->expr, EUSE_NODE, bb, 0);
+ EUSE_DEF (x) = EPHI_ARG_DEF (ephi, opnd_indx);
+ VARRAY_PUSH_TREE (ei->euses_dt_order, EPHI_ARG_DEF (ephi, opnd_indx));
+ qsort (ei->euses_dt_order->data.tree,
+ VARRAY_ACTIVE_SIZE (ei->euses_dt_order),
+ sizeof (tree),
+ eref_compare);
+ EREF_TEMP (EUSE_DEF (x)) = newtemp;
+ EREF_RELOAD (EUSE_DEF (x)) = false;
+ EREF_SAVE (EUSE_DEF (x)) = false;
+ EUSE_INSERTED (EUSE_DEF (x)) = true;
+ EUSE_PHIOP (EUSE_DEF (x)) = false;
+ EREF_SAVE (x) = false;
+ EREF_RELOAD (x) = false;
+ EUSE_INSERTED (x) = true;
+ EREF_CLASS (x) = class_count++;
+ EREF_CLASS (EUSE_DEF (x)) = class_count++;
+ *avdefsp = xrealloc (*avdefsp, sizeof (tree) * (class_count + 1));
+ (*avdefsp)[class_count - 2] = x;
+ (*avdefsp)[class_count - 1] = EUSE_DEF (x);
+ pre_stats.saves++;
+}
+
+/* First step of finalization. Determine which expressions are being
+ saved and which are being deleted.
+ This is done as a simple dominator based availabilty calculation,
+ using the e-versions/redundancy classes. */
+
+static bool
+finalize_1 (struct expr_info *ei)
+{
+ tree x;
+ int nx;
+ bool made_a_reload = false;
+ size_t i;
+ tree *avdefs;
+
+ avdefs = xcalloc (class_count + 1, sizeof (tree));
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
+ {
+ x = VARRAY_TREE (ei->euses_dt_order, i);
+ nx = EREF_CLASS (x);
+
+ if (TREE_CODE (x) == EPHI_NODE)
+ {
+ if (ephi_will_be_avail (x))
+ avdefs[nx] = x;
+ }
+ else if (TREE_CODE (x) == EUSE_NODE && EUSE_LVAL (x))
+ {
+ avdefs[nx] = x;
+ }
+ else if (TREE_CODE (x) == EUSE_NODE && !EUSE_PHIOP (x))
+ {
+ if (avdefs[nx] == NULL
+ || !dominated_by_p (CDI_DOMINATORS, bb_for_stmt (x),
+ bb_for_stmt (avdefs[nx])))
+ {
+ EREF_RELOAD (x) = false;
+ avdefs[nx] = x;
+ EUSE_DEF (x) = NULL;
+ }
+ else
+ {
+ EREF_RELOAD (x) = true;
+ made_a_reload = true;
+ EUSE_DEF (x) = avdefs[nx];
+#ifdef ENABLE_CHECKING
+ if (EREF_CLASS (x) != EREF_CLASS (avdefs[nx]))
+ abort ();
+#endif
+ }
+ }
+ else
+ {
+ edge succ;
+ basic_block bb = bb_for_stmt (x);
+ /* For each ephi in the successor blocks. */
+ for (succ = bb->succ; succ; succ = succ->succ_next)
+ {
+ tree ephi = ephi_at_block (succ->dest);
+ if (ephi == NULL_TREE)
+ continue;
+ if (ephi_will_be_avail (ephi))
+ {
+ int opnd_indx = opnum_of_ephi (ephi, succ);
+#ifdef ENABLE_CHECKING
+ if (EPHI_ARG_PRED (ephi, opnd_indx) != x)
+ abort ();
+#endif
+ if (can_insert (ephi, opnd_indx))
+ {
+ insert_one_operand (ei, ephi, opnd_indx, x, succ,
+ &avdefs);
+ }
+ else
+ {
+ nx = EREF_CLASS (EPHI_ARG_DEF (ephi,opnd_indx));
+ EPHI_ARG_DEF (ephi, opnd_indx) = avdefs[nx];
+ }
+ }
+ }
+ }
+ }
+ free (avdefs);
+ return made_a_reload;
+}
+
+/* Mark the necessary SAVE bits on X. */
+
+static void
+set_save (struct expr_info *ei, tree X)
+{
+ if (TREE_CODE (X) == EUSE_NODE && !EUSE_PHIOP (X))
+ EREF_SAVE (X) = true;
+ else if (TREE_CODE (X) == EPHI_NODE)
+ {
+ int curr_phiop;
+ for (curr_phiop = 0; curr_phiop < EPHI_NUM_ARGS (X); curr_phiop++)
+ {
+ tree w = EPHI_ARG_DEF (X, curr_phiop);
+ if (!EPHI_ARG_PROCESSED2 (X, curr_phiop))
+ {
+ EPHI_ARG_PROCESSED2 (X, curr_phiop) = true;
+ if (w)
+ set_save (ei, w);
+ }
+ }
+ }
+}
+
+/* DFS Search function: Return true if PHI is can't be available. */
+
+static bool
+cba_search_seen (tree phi)
+{
+ return EPHI_CANT_BE_AVAIL (phi);
+}
+
+/* DFS Search function: Mark PHI as can't be available when seen. */
+
+static void
+cba_search_set_seen (tree phi)
+{
+ EPHI_CANT_BE_AVAIL (phi) = true;
+}
+
+/* DFS Search function: Return true if PHI should be marked can't be
+ available due to a NULL operand. */
+
+static bool
+cba_search_start_from (tree phi)
+{
+ if (!EPHI_DOWNSAFE (phi))
+ {
+ int i;
+ for (i = 0; i < EPHI_NUM_ARGS (phi); i++)
+ if (EPHI_ARG_DEF (phi, i) == NULL_TREE
+ || EPHI_ARG_EDGE (phi, i)->flags & EDGE_ABNORMAL)
+ return true;
+ }
+ return false;
+}
+
+/* DFS Search function: Return true if the used PHI is not downsafe,
+ unless we have a real use for the operand. */
+
+static bool
+cba_search_continue_from_to (tree def_phi ATTRIBUTE_UNUSED,
+ int opnd_indx,
+ tree use_phi)
+{
+ if (EPHI_ARG_HAS_REAL_USE (use_phi, opnd_indx) &&
+ !(EPHI_ARG_EDGE (use_phi, opnd_indx)->flags & EDGE_ABNORMAL))
+ return false;
+ if (!EPHI_DOWNSAFE (use_phi))
+ return true;
+ return false;
+}
+
+/* DFS Search function: Return true if this PHI stops forward
+ movement. */
+
+static bool
+stops_search_seen (tree phi)
+{
+ return EPHI_STOPS (phi);
+}
+
+/* DFS Search function: Mark the PHI as stopping forward movement. */
+
+static void
+stops_search_set_seen (tree phi)
+{
+ EPHI_STOPS (phi) = true;
+}
+
+/* DFS Search function: Note that the used phi argument stops forward
+ movement. */
+
+static void
+stops_search_reach_from_to (tree def_phi ATTRIBUTE_UNUSED,
+ int opnd_indx,
+ tree use_phi)
+{
+ EPHI_ARG_STOPS (use_phi, opnd_indx) = true;
+}
+
+/* DFS Search function: Return true if the PHI has any arguments
+ stopping forward movement. */
+
+static bool
+stops_search_start_from (tree phi)
+{
+ int i;
+ for (i = 0; i < EPHI_NUM_ARGS (phi); i++)
+ if (EPHI_ARG_STOPS (phi, i))
+ return true;
+ return false;
+}
+
+/* DFS Search function: Return true if the PHI has any arguments
+ stopping forward movement. */
+
+static bool
+stops_search_continue_from_to (tree def_phi ATTRIBUTE_UNUSED,
+ int opnd_indx ATTRIBUTE_UNUSED,
+ tree use_phi)
+{
+ return stops_search_start_from (use_phi);
+}
+
+/* DFS Search function: Return true if the replacing occurrence is
+ known. */
+
+static bool
+repl_search_seen (tree phi)
+{
+ return EPHI_REP_OCCUR_KNOWN (phi);
+}
+
+/* DFS Search function: Set the identical_to field and note the
+ replacing occurrence is now known. */
+
+static void
+repl_search_set_seen (tree phi)
+{
+ int i;
+
+#ifdef ENABLE_CHECKING
+ if (!ephi_will_be_avail (phi))
+ abort ();
+#endif
+
+ if (EPHI_IDENTICAL_TO (phi) == NULL_TREE)
+ {
+ for (i = 0; i < EPHI_NUM_ARGS (phi); i++)
+ {
+ tree identical_to = occ_identical_to (EPHI_ARG_DEF (phi, i));
+ if (identical_to != NULL_TREE)
+ {
+ if (EPHI_IDENTICAL_TO (phi) == NULL)
+ EPHI_IDENTICAL_TO (phi) = identical_to;
+ if (EPHI_ARG_INJURED (phi, i))
+ EPHI_IDENT_INJURED (phi) = true;
+ }
+ }
+ }
+ EPHI_REP_OCCUR_KNOWN (phi) = true;
+}
+
+/* Helper function. Return true if any argument in the PHI is
+ injured. */
+
+static inline bool
+any_operand_injured (tree ephi)
+{
+ int i;
+ for (i = 0; i < EPHI_NUM_ARGS (ephi); i++)
+ if (EPHI_ARG_INJURED (ephi, i))
+ return true;
+ return false;
+
+}
+
+/* DFS Search function: Note the identity of the used phi operand is
+ the same as it's defining phi operand, if that phi will be
+ available, and it's known. */
+
+static void
+repl_search_reach_from_to (tree def_phi, int opnd_indx ATTRIBUTE_UNUSED,
+ tree use_phi)
+{
+ if (ephi_will_be_avail (use_phi)
+ && EPHI_IDENTITY (use_phi)
+ && EPHI_IDENTICAL_TO (use_phi) == NULL_TREE)
+ {
+ EPHI_IDENTICAL_TO (use_phi) = EPHI_IDENTICAL_TO (def_phi);
+
+ if (EPHI_IDENT_INJURED (def_phi)
+ || any_operand_injured (use_phi))
+ EPHI_IDENT_INJURED (use_phi) = true;
+ }
+}
+
+/* DFS Search function: Return true if the PHI will be available,
+ it's an identity PHI, and it's arguments are identical to
+ something. */
+
+static bool
+repl_search_start_from (tree phi)
+{
+ if (ephi_will_be_avail (phi) && EPHI_IDENTITY (phi))
+ {
+ int i;
+ for (i = 0; i < EPHI_NUM_ARGS (phi); i++)
+ if (occ_identical_to (EPHI_ARG_DEF (phi, i)) != NULL_TREE)
+ return true;
+ }
+ return false;
+}
+
+/* DFS Search function: Return true if the using PHI is will be available,
+ and identity. */
+
+static bool
+repl_search_continue_from_to (tree def_phi ATTRIBUTE_UNUSED,
+ int opnd_indx ATTRIBUTE_UNUSED,
+ tree use_phi)
+{
+ return ephi_will_be_avail (use_phi) && EPHI_IDENTITY (use_phi);
+}
+
+/* Mark all will-be-avail ephi's in the dominance frontier of BB as
+ required. */
+
+static void
+require_phi (struct expr_info *ei, basic_block bb)
+{
+ size_t i;
+ EXECUTE_IF_SET_IN_BITMAP (pre_dfs[bb->index], 0, i,
+ {
+ tree ephi;
+ ephi = ephi_at_block (BASIC_BLOCK (i));
+ if (ephi != NULL_TREE
+ && ephi_will_be_avail (ephi)
+ && EPHI_IDENTITY (ephi))
+ {
+ EPHI_IDENTITY (ephi) = false;
+ require_phi (ei, BASIC_BLOCK (i));
+ }
+ });
+}
+
+/* Return the occurrence this occurrence is identical to, if one exists. */
+
+static tree
+occ_identical_to (tree t)
+{
+ if (TREE_CODE (t) == EUSE_NODE && !EUSE_PHIOP (t))
+ return t;
+ else if (TREE_CODE (t) == EUSE_NODE && EUSE_PHIOP (t))
+ return t;
+ else if (TREE_CODE (t) == EPHI_NODE)
+ {
+ if (EPHI_IDENTITY (t) && EPHI_REP_OCCUR_KNOWN (t))
+ return EPHI_IDENTICAL_TO (t);
+ else if (!EPHI_IDENTITY (t))
+ return t;
+ }
+ return NULL_TREE;
+}
+
+/* Return true if NODE was or is going to be saved. */
+static bool
+really_available_def (tree node)
+{
+ if (TREE_CODE (node) == EUSE_NODE
+ && EUSE_PHIOP (node)
+ && EUSE_INSERTED (node))
+ return true;
+ if (TREE_CODE (node) == EUSE_NODE
+ && EUSE_DEF (node) == NULL_TREE)
+ return true;
+ return false;
+}
+
+
+/* Second part of the finalize step. Performs save bit setting, and
+ ESSA minimization. */
+
+static void
+finalize_2 (struct expr_info *ei)
+{
+ size_t i;
+
+ insert_euse_in_preorder_dt_order (ei);
+ /* Note which uses need to be saved to a temporary. */
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
+ {
+ tree ref = VARRAY_TREE (ei->euses_dt_order, i);
+ if (TREE_CODE (ref) == EUSE_NODE
+ && !EUSE_PHIOP (ref)
+ && EREF_RELOAD (ref))
+ {
+ set_save (ei, EUSE_DEF (ref));
+ }
+ }
+
+ /* ESSA Minimization. Determines which phis are identical to other
+ phis, and not strictly necessary. */
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
+ {
+ tree ephi = VARRAY_TREE (ei->euses_dt_order, i);
+ if (TREE_CODE (ephi) != EPHI_NODE)
+ continue;
+ EPHI_IDENTITY (ephi) = true;
+ EPHI_IDENTICAL_TO (ephi) = NULL;
+ }
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
+ {
+ tree ephi = VARRAY_TREE (ei->euses_dt_order, i);
+ if (!ephi || TREE_CODE (ephi) != EPHI_NODE)
+ continue;
+ if (ephi_will_be_avail (ephi))
+ {
+ int k;
+ for (k = 0; k < EPHI_NUM_ARGS (ephi); k++)
+ {
+ if (EPHI_ARG_INJURED (ephi, k))
+ require_phi (ei, EPHI_ARG_EDGE (ephi, k)->src);
+ else if (EPHI_ARG_DEF (ephi, k)
+ && TREE_CODE (EPHI_ARG_DEF (ephi, k)) == EUSE_NODE
+ && really_available_def (EPHI_ARG_DEF (ephi, k)))
+ require_phi (ei, bb_for_stmt (EPHI_ARG_DEF (ephi, k)));
+ }
+ }
+ }
+ do_ephi_df_search (ei, replacing_search);
+}
+
+/* Perform a DFS on EPHI using the functions in SEARCH. */
+
+static void
+do_ephi_df_search_1 (struct ephi_df_search search, tree ephi)
+{
+ varray_type uses;
+ size_t i;
+ search.set_seen (ephi);
+
+ uses = EPHI_USES (ephi);
+ if (!uses)
+ return;
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (uses); i++)
+ {
+ struct ephi_use_entry *use = VARRAY_GENERIC_PTR (uses, i);
+ if (search.reach_from_to)
+ search.reach_from_to (ephi, use->opnd_indx, use->phi);
+ if (!search.seen (use->phi) &&
+ search.continue_from_to (ephi, use->opnd_indx, use->phi))
+ {
+ do_ephi_df_search_1 (search, use->phi);
+ }
+ }
+}
+
+/* Perform a DFS on the EPHI's, using the functions in SEARCH. */
+
+static void
+do_ephi_df_search (struct expr_info *ei, struct ephi_df_search search)
+{
+ size_t i;
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
+ {
+ tree ephi = VARRAY_TREE (ei->euses_dt_order, i);
+ if (!ephi || TREE_CODE (ephi) != EPHI_NODE)
+ continue;
+ if (!search.seen (ephi)
+ && search.start_from (ephi))
+ do_ephi_df_search_1 (search, ephi);
+ }
+}
+
+#if 0
+/* Calculate the increment necessary due to EXPR for the temporary. */
+static tree
+calculate_increment (struct expr_info *ei, tree expr)
+{
+ tree incr;
+
+ /*XXX: Currently assume it's like a = a + 5, thus, this will give us the 5.
+ */
+ incr = TREE_OPERAND (TREE_OPERAND (expr, 1), 1);
+ if (TREE_CODE (incr) != INTEGER_CST)
+ abort();
+ if (TREE_CODE (ei->expr) == MULT_EXPR)
+ incr = fold (build (MULT_EXPR, TREE_TYPE (ei->expr),
+ incr, TREE_OPERAND (ei->expr, 1)));
+#if DEBUGGING_STRRED
+ if (dump_file)
+ {
+ fprintf (dump_file, "Increment calculated to be: ");
+ print_generic_expr (dump_file, incr, 0);
+ fprintf (dump_file, "\n");
+ }
+#endif
+ return incr;
+}
+#endif
+
+
+/* Perform an insertion of EXPR before/after USE, depending on the
+ value of BEFORE. */
+
+static tree
+do_proper_save (tree use, tree expr, int before)
+{
+ basic_block bb = bb_for_stmt (use);
+ block_stmt_iterator bsi;
+
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ if (bsi_stmt (bsi) == use)
+ {
+ if (before)
+ bsi_insert_before (&bsi, expr, BSI_SAME_STMT);
+ else
+ bsi_insert_after (&bsi, expr, BSI_SAME_STMT);
+ return use;
+ }
+ }
+ abort ();
+}
+
+/* Get the temporary for ESSA node USE.
+ Takes into account minimized ESSA. */
+static tree
+get_temp (tree use)
+{
+ tree newtemp;
+ if (TREE_CODE (use) == EPHI_NODE && EPHI_IDENTITY (use))
+ {
+ tree newuse = use;
+ while (TREE_CODE (newuse) == EPHI_NODE
+ && EPHI_IDENTITY (newuse))
+ {
+#ifdef ENABLE_CHECKING
+ if (!EPHI_IDENTICAL_TO (newuse))
+ abort ();
+#endif
+ newuse = EPHI_IDENTICAL_TO (newuse);
+ if (TREE_CODE (newuse) != EPHI_NODE)
+ break;
+ }
+ if (TREE_CODE (EREF_TEMP (newuse)) == PHI_NODE)
+ newtemp = PHI_RESULT (EREF_TEMP (newuse));
+ else
+ newtemp = EREF_TEMP (newuse);
+ }
+ else
+ {
+ if (TREE_CODE (EREF_TEMP (use)) == PHI_NODE)
+ newtemp = PHI_RESULT (EREF_TEMP (use));
+ else
+ newtemp = EREF_TEMP (use);
+ }
+ return newtemp;
+}
+
+/* Return the side of the statement that contains an SSA name. */
+
+static tree
+pick_ssa_name (tree stmt)
+{
+ if (TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME)
+ return TREE_OPERAND (stmt, 0);
+ else if (TREE_CODE (TREE_OPERAND (stmt, 1)) == SSA_NAME)
+ return TREE_OPERAND (stmt, 1);
+ else
+ abort ();
+}
+
+/* Code motion step of SSAPRE. Take the save bits, and reload bits,
+ and perform the saves and reloads. Also insert new phis where
+ necessary. */
+
+static void
+code_motion (struct expr_info *ei)
+{
+ tree use;
+ tree newtemp;
+ size_t euse_iter;
+ tree temp = ei->temp;
+ basic_block bb;
+
+ /* First, add the phi node temporaries so the reaching defs are
+ always right. */
+ for (euse_iter = 0;
+ euse_iter < VARRAY_ACTIVE_SIZE (ei->euses_dt_order);
+ euse_iter++)
+ {
+
+ use = VARRAY_TREE (ei->euses_dt_order, euse_iter);
+ if (TREE_CODE (use) != EPHI_NODE)
+ continue;
+ if (ephi_will_be_avail (use) && !EPHI_IDENTITY (use))
+ {
+ bb = bb_for_stmt (use);
+ /* Add the new PHI node to the list of PHI nodes for block BB. */
+ bb_ann (bb)->phi_nodes = chainon (phi_nodes (bb), EREF_TEMP (use));
+ }
+ else if (EPHI_IDENTITY (use))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Pointless EPHI in block %d\n",
+ bb_for_stmt (use)->index);
+ }
+ }
+ }
+ /* Now do the actual saves and reloads, plus repairs. */
+ for (euse_iter = 0;
+ euse_iter < VARRAY_ACTIVE_SIZE (ei->euses_dt_order);
+ euse_iter++)
+ {
+ use = VARRAY_TREE (ei->euses_dt_order, euse_iter);
+#ifdef ENABLE_CHECKING
+ if (TREE_CODE (use) == EUSE_NODE && EUSE_PHIOP (use)
+ && (EREF_RELOAD (use) || EREF_SAVE (use)))
+ abort ();
+#endif
+ if (EREF_SAVE (use) && !EUSE_INSERTED (use))
+ {
+ tree newexpr;
+ tree use_stmt;
+ tree copy;
+ basic_block usebb = bb_for_stmt (use);
+ use_stmt = EREF_STMT (use);
+
+ copy = TREE_OPERAND (use_stmt, 1);
+ copy = unshare_expr (copy);
+ newexpr = build (MODIFY_EXPR, TREE_TYPE (temp), temp, copy);
+ newtemp = make_ssa_name (temp, newexpr);
+ EREF_TEMP (use) = newtemp;
+ TREE_OPERAND (newexpr, 0) = newtemp;
+ TREE_OPERAND (use_stmt, 1) = newtemp;
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "In BB %d, insert save of ",
+ usebb->index);
+ print_generic_expr (dump_file, copy, dump_flags);
+ fprintf (dump_file, " to ");
+ print_generic_expr (dump_file, newtemp, dump_flags);
+ fprintf (dump_file, " before statement ");
+ print_generic_expr (dump_file, use_stmt, dump_flags);
+ fprintf (dump_file, "\n");
+ if (EXPR_HAS_LOCATION (use_stmt))
+ fprintf (dump_file, " on line %d\n",
+ EXPR_LINENO (use_stmt));
+ }
+ modify_stmt (newexpr);
+ modify_stmt (use_stmt);
+ set_bb_for_stmt (newexpr, usebb);
+ EREF_STMT (use) = do_proper_save (use_stmt, newexpr, true);
+ pre_stats.saves++;
+ }
+ else if (EREF_RELOAD (use))
+ {
+ tree use_stmt;
+ tree newtemp;
+
+ use_stmt = EREF_STMT (use);
+ bb = bb_for_stmt (use_stmt);
+
+ newtemp = get_temp (EUSE_DEF (use));
+ if (!newtemp)
+ abort ();
+ if (dump_file)
+ {
+ fprintf (dump_file, "In BB %d, insert reload of ",
+ bb->index);
+ print_generic_expr (dump_file,
+ TREE_OPERAND (use_stmt, 1), 0);
+ fprintf (dump_file, " from ");
+ print_generic_expr (dump_file, newtemp, dump_flags);
+ fprintf (dump_file, " in statement ");
+ print_generic_stmt (dump_file, use_stmt, dump_flags);
+ fprintf (dump_file, "\n");
+ if (EXPR_HAS_LOCATION (use_stmt))
+ fprintf (dump_file, " on line %d\n",
+ EXPR_LINENO (use_stmt));
+ }
+ TREE_OPERAND (use_stmt, 1) = newtemp;
+ EREF_TEMP (use) = newtemp;
+ modify_stmt (use_stmt);
+ pre_stats.reloads++;
+ }
+ }
+
+ /* Now do the phi nodes. */
+ for (euse_iter = 0;
+ euse_iter < VARRAY_ACTIVE_SIZE (ei->euses_dt_order);
+ euse_iter++)
+ {
+ use = VARRAY_TREE (ei->euses_dt_order, euse_iter);
+ if (TREE_CODE (use) == EPHI_NODE
+ && ephi_will_be_avail (use)
+ && !EPHI_IDENTITY (use))
+ {
+ int i;
+ tree argdef;
+ bb = bb_for_stmt (use);
+ if (dump_file)
+ {
+ fprintf (dump_file,
+ "In BB %d, insert PHI to replace EPHI\n", bb->index);
+ }
+ newtemp = EREF_TEMP (use);
+ for (i = 0; i < EPHI_NUM_ARGS (use); i++)
+ {
+ tree rdef;
+ argdef = EPHI_ARG_DEF (use, i);
+ if (argdef == use)
+ rdef = get_temp (use);
+ else if (EREF_RELOAD (argdef) || EREF_SAVE (argdef))
+ rdef = get_temp (argdef);
+ else if (TREE_CODE (argdef) == EPHI_NODE)
+ rdef = get_temp (argdef);
+ else if (argdef
+ && EPHI_ARG_HAS_REAL_USE (use, i)
+ && EREF_STMT (argdef)
+ && !EPHI_ARG_INJURED (use, i))
+ rdef = pick_ssa_name (EREF_STMT (argdef));
+ else
+ abort ();
+
+ if (!rdef)
+ abort();
+ add_phi_arg (&newtemp, rdef, EPHI_ARG_EDGE (use, i));
+ }
+
+ /* Associate BB to the PHI node. */
+ set_bb_for_stmt (EREF_TEMP (use), bb);
+ pre_stats.newphis++;
+
+ }
+ }
+}
+
+/* Compute the iterated dominance frontier of a statement. */
+
+static bitmap
+compute_idfs (bitmap * dfs, tree stmt)
+{
+ fibheap_t worklist;
+ sbitmap inworklist, done;
+ bitmap idf;
+ size_t i;
+ basic_block block;
+
+ block = bb_for_stmt (stmt);
+ if (idfs_cache[block->index] != NULL)
+ return idfs_cache[block->index];
+
+ inworklist = sbitmap_alloc (last_basic_block);
+ done = sbitmap_alloc (last_basic_block);
+ worklist = fibheap_new ();
+ sbitmap_zero (inworklist);
+ sbitmap_zero (done);
+
+ idf = BITMAP_XMALLOC ();
+ bitmap_zero (idf);
+
+ block = bb_for_stmt (stmt);
+ fibheap_insert (worklist, block->index, (void *)(size_t)block->index);
+ SET_BIT (inworklist, block->index);
+
+ while (!fibheap_empty (worklist))
+ {
+ int a = (size_t) fibheap_extract_min (worklist);
+ if (TEST_BIT (done, a))
+ continue;
+ SET_BIT (done, a);
+ if (idfs_cache[a])
+ {
+ bitmap_a_or_b (idf, idf, idfs_cache[a]);
+ EXECUTE_IF_SET_IN_BITMAP (idfs_cache[a], 0, i,
+ {
+ SET_BIT (inworklist, i);
+ SET_BIT (done, i);
+ });
+ }
+ else
+ {
+ bitmap_a_or_b (idf, idf, dfs[a]);
+ EXECUTE_IF_SET_IN_BITMAP (dfs[a], 0, i,
+ {
+ if (!TEST_BIT (inworklist, i))
+ {
+ SET_BIT (inworklist, i);
+ fibheap_insert (worklist, i, (void *)i);
+ }
+ });
+ }
+
+ }
+ fibheap_delete (worklist);
+ sbitmap_free (inworklist);
+ sbitmap_free (done);
+ idfs_cache[block->index] = idf;
+ return idf;
+
+}
+
+/* Return true if EXPR is a strength reduction candidate. */
+static bool
+is_strred_cand (const tree expr ATTRIBUTE_UNUSED)
+{
+#if 0
+ if (TREE_CODE (TREE_OPERAND (expr, 1)) != MULT_EXPR
+ && TREE_CODE (TREE_OPERAND (expr, 1)) != MINUS_EXPR
+ && TREE_CODE (TREE_OPERAND (expr, 1)) != NEGATE_EXPR
+ && TREE_CODE (TREE_OPERAND (expr, 1)) != PLUS_EXPR)
+ return false;
+ return true;
+#endif
+ return false;
+}
+
+
+
+/* Determine if two expressions are lexically equivalent. */
+
+static inline bool
+expr_lexically_eq (const tree v1, const tree v2)
+{
+ if (TREE_CODE_CLASS (TREE_CODE (v1)) != TREE_CODE_CLASS (TREE_CODE (v2)))
+ return false;
+ if (TREE_CODE (v1) != TREE_CODE (v2))
+ return false;
+ switch (TREE_CODE_CLASS (TREE_CODE (v1)))
+ {
+ case 'r':
+ case '1':
+ return names_match_p (TREE_OPERAND (v1, 0), TREE_OPERAND (v2, 0));
+ case 'x':
+ case 'd':
+ return names_match_p (v1, v2);
+ case '2':
+ {
+ bool match;
+ match = names_match_p (TREE_OPERAND (v1, 0), TREE_OPERAND (v2, 0));
+ if (!match)
+ return false;
+ match = names_match_p (TREE_OPERAND (v1, 1), TREE_OPERAND (v2, 1));
+ if (!match)
+ return false;
+ return true;
+ }
+ default:
+ return false;
+ }
+
+}
+
+/* Free an expression info structure. */
+
+static void
+free_expr_info (struct expr_info *v1)
+{
+ struct expr_info *e1 = (struct expr_info *)v1;
+ VARRAY_FREE (e1->occurs);
+ VARRAY_FREE (e1->kills);
+ VARRAY_FREE (e1->lefts);
+ VARRAY_FREE (e1->reals);
+ VARRAY_FREE (e1->euses_dt_order);
+}
+
+/* Process left occurrences and kills due to EXPR.
+ A left occurrence occurs wherever a variable in an expression we
+ are PRE'ing is stored to directly in a def, or indirectly because
+ of a VDEF of an expression that we VUSE. */
+
+static void
+process_left_occs_and_kills (varray_type bexprs, tree expr)
+{
+ size_t i, j, k;
+
+ stmt_ann_t ann = stmt_ann (expr);
+ vdef_optype vdefs;
+ vuse_optype vuses;
+ def_optype defs;
+ defs = DEF_OPS (ann);
+ vdefs = VDEF_OPS (ann);
+ if (NUM_DEFS (defs) == 0 && NUM_VDEFS (vdefs) == 0)
+ return;
+
+ for (j = 0; j < VARRAY_ACTIVE_SIZE (bexprs); j++)
+ {
+ struct expr_info *ei = VARRAY_GENERIC_PTR (bexprs, j);
+ tree vuse_name;
+ tree random_occur;
+ stmt_ann_t ann;
+
+ if (!ei->loadpre_cand)
+ continue;
+
+ /* If we define the variable itself (IE a in *a, or a in a),
+ it's a left occurrence. */
+ for (i = 0; i < NUM_DEFS (defs); i++)
+ {
+ if (names_match_p (DEF_OP (defs, i), ei->expr))
+ {
+ if (TREE_CODE (expr) == ASM_EXPR)
+ {
+ ei->loadpre_cand = false;
+ continue;
+ }
+ VARRAY_PUSH_TREE (ei->lefts, expr);
+ VARRAY_PUSH_TREE (ei->occurs, NULL);
+ VARRAY_PUSH_TREE (ei->kills, NULL);
+ }
+ }
+
+ /* If we VDEF the VUSE of the expression, it's also a left
+ occurrence. */
+ random_occur = VARRAY_TREE (ei->occurs, 0);
+ ann = stmt_ann (random_occur);
+ vuses = VUSE_OPS (ann);
+ if (NUM_VDEFS (vdefs) != 0)
+ {
+ for (k = 0; k < NUM_VUSES (vuses); k++)
+ {
+ vuse_name = VUSE_OP (vuses, k);
+ for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ {
+ if (names_match_p (VDEF_OP (vdefs, i), vuse_name))
+ {
+ VARRAY_PUSH_TREE (ei->lefts, expr);
+ VARRAY_PUSH_TREE (ei->occurs, NULL);
+ VARRAY_PUSH_TREE (ei->kills, NULL);
+ }
+ }
+ }
+ }
+ }
+}
+
+/* Perform SSAPRE on an expression. */
+
+static int
+pre_expression (struct expr_info *slot, void *data, bitmap vars_to_rename)
+{
+ struct expr_info *ei = (struct expr_info *) slot;
+ basic_block bb;
+
+ class_count = 0;
+ eref_id_counter = 0;
+
+ /* If we don't have two occurrences along any dominated path, and
+ it's not load PRE, this is a waste of time. */
+
+ if (VARRAY_ACTIVE_SIZE (ei->reals) < 2)
+ return 1;
+
+ memset (&pre_stats, 0, sizeof (struct pre_stats_d));
+
+ ei->temp = create_tmp_var (TREE_TYPE (ei->expr), "pretmp");
+ add_referenced_tmp_var (ei->temp);
+
+ bitmap_clear (created_phi_preds);
+ ephi_pindex_htab = htab_create (500, ephi_pindex_hash, ephi_pindex_eq, free);
+ phi_pred_cache = xcalloc (last_basic_block, sizeof (tree));
+ n_phi_preds = last_basic_block;
+
+ if (!expr_phi_insertion ((bitmap *)data, ei))
+ goto cleanup;
+ rename_1 (ei);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ size_t i;
+ fprintf (dump_file, "Occurrences for expression ");
+ print_generic_expr (dump_file, ei->expr, dump_flags);
+ fprintf (dump_file, " after Rename 2\n");
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
+ {
+ print_generic_expr (dump_file,
+ VARRAY_TREE (ei->euses_dt_order, i), 1);
+ fprintf (dump_file, "\n");
+ }
+ }
+ compute_down_safety (ei);
+ compute_du_info (ei);
+ compute_will_be_avail (ei);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "EPHI's for expression ");
+ print_generic_expr (dump_file, ei->expr, dump_flags);
+ fprintf (dump_file,
+ " after down safety and will_be_avail computation\n");
+ FOR_EACH_BB (bb)
+ {
+ tree ephi = ephi_at_block (bb);
+ if (ephi != NULL)
+ {
+ print_generic_expr (dump_file, ephi, 1);
+ fprintf (dump_file, "\n");
+ }
+ }
+ }
+
+ if (finalize_1 (ei))
+ {
+ finalize_2 (ei);
+ code_motion (ei);
+ if (ei->loadpre_cand)
+ bitmap_set_bit (vars_to_rename, var_ann (ei->temp)->uid);
+ }
+
+ clear_all_eref_arrays ();
+ if (dump_file)
+ if (dump_flags & TDF_STATS)
+ {
+ fprintf (dump_file, "PRE stats:\n");
+ fprintf (dump_file, "Reloads:%d\n", pre_stats.reloads);
+ fprintf (dump_file, "Saves:%d\n", pre_stats.saves);
+ fprintf (dump_file, "Repairs:%d\n", pre_stats.repairs);
+ fprintf (dump_file, "New phis:%d\n", pre_stats.newphis);
+ fprintf (dump_file, "EPHI memory allocated:%d\n",
+ pre_stats.ephi_allocated);
+ fprintf (dump_file, "EREF memory allocated:%d\n",
+ pre_stats.eref_allocated);
+ fprintf (dump_file, "Expressions generated for rename2:%d\n",
+ pre_stats.exprs_generated);
+ }
+ cleanup:
+ free (phi_pred_cache);
+ if (ephi_pindex_htab)
+ {
+ htab_delete (ephi_pindex_htab);
+ ephi_pindex_htab = NULL;
+ }
+
+
+ return 0;
+}
+
+
+/* Step 1 - Collect the expressions to perform PRE on. */
+
+static void
+collect_expressions (basic_block block, varray_type *bexprsp)
+{
+ size_t k;
+ block_stmt_iterator j;
+ basic_block son;
+
+ varray_type bexprs = *bexprsp;
+
+ for (j = bsi_start (block); !bsi_end_p (j); bsi_next (&j))
+ {
+ tree stmt = bsi_stmt (j);
+ tree expr = stmt;
+ tree orig_expr = expr;
+ stmt_ann_t ann;
+ struct expr_info *slot = NULL;
+
+ get_stmt_operands (expr);
+ ann = stmt_ann (expr);
+
+ if (NUM_USES (USE_OPS (ann)) == 0)
+ {
+ process_left_occs_and_kills (bexprs, expr);
+ continue;
+ }
+
+ if (TREE_CODE (expr) == MODIFY_EXPR)
+ expr = TREE_OPERAND (expr, 1);
+ if ((TREE_CODE_CLASS (TREE_CODE (expr)) == '2'
+ || TREE_CODE_CLASS (TREE_CODE (expr)) == '<'
+ /*|| TREE_CODE_CLASS (TREE_CODE (expr)) == '1'*/
+ || TREE_CODE (expr) == SSA_NAME
+ || TREE_CODE (expr) == INDIRECT_REF)
+ && !ann->makes_aliased_stores
+ && !ann->has_volatile_ops)
+ {
+ bool is_scalar = true;
+ tree origop0 = TREE_OPERAND (orig_expr, 0);
+
+ if (AGGREGATE_TYPE_P (TREE_TYPE (origop0))
+ || TREE_CODE (TREE_TYPE (origop0)) == COMPLEX_TYPE)
+ is_scalar = false;
+
+ if (is_scalar
+ && (TREE_CODE (expr) == SSA_NAME
+ || (TREE_CODE (expr) == INDIRECT_REF
+ && !DECL_P (TREE_OPERAND (expr, 0)))
+ ||(!DECL_P (TREE_OPERAND (expr, 0))
+ && (!TREE_OPERAND (expr, 1)
+ || !DECL_P (TREE_OPERAND (expr, 1))))))
+ {
+ for (k = 0; k < VARRAY_ACTIVE_SIZE (bexprs); k++)
+ {
+ slot = VARRAY_GENERIC_PTR (bexprs, k);
+ if (expr_lexically_eq (slot->expr, expr))
+ break;
+ }
+ if (k >= VARRAY_ACTIVE_SIZE (bexprs))
+ slot = NULL;
+ if (slot)
+ {
+ VARRAY_PUSH_TREE (slot->occurs, orig_expr);
+ VARRAY_PUSH_TREE (slot->kills, NULL);
+ VARRAY_PUSH_TREE (slot->lefts, NULL);
+ VARRAY_PUSH_TREE (slot->reals, stmt);
+ slot->strred_cand &= is_strred_cand (orig_expr);
+ }
+ else
+ {
+ slot = ggc_alloc (sizeof (struct expr_info));
+ slot->expr = expr;
+ VARRAY_GENERIC_PTR_NOGC_INIT (slot->occurs, 1, "Occurrence");
+ VARRAY_GENERIC_PTR_NOGC_INIT (slot->kills, 1, "Kills");
+ VARRAY_GENERIC_PTR_NOGC_INIT (slot->lefts, 1, "Left occurrences");
+ VARRAY_GENERIC_PTR_NOGC_INIT (slot->reals, 1, "Real occurrences");
+ VARRAY_GENERIC_PTR_NOGC_INIT (slot->euses_dt_order, 1, "EUSEs");
+
+ VARRAY_PUSH_TREE (slot->occurs, orig_expr);
+ VARRAY_PUSH_TREE (slot->kills, NULL);
+ VARRAY_PUSH_TREE (slot->lefts, NULL);
+ VARRAY_PUSH_TREE (slot->reals, stmt);
+ VARRAY_PUSH_GENERIC_PTR (bexprs, slot);
+ slot->strred_cand = is_strred_cand (orig_expr);
+ slot->loadpre_cand = false;
+ if (TREE_CODE (expr) == SSA_NAME
+ || TREE_CODE (expr) == INDIRECT_REF)
+ slot->loadpre_cand = true;
+ }
+ }
+ }
+ process_left_occs_and_kills (bexprs, orig_expr);
+ }
+ *bexprsp = bexprs;
+
+ for (son = first_dom_son (CDI_DOMINATORS, block);
+ son;
+ son = next_dom_son (CDI_DOMINATORS, son))
+ collect_expressions (son, bexprsp);
+}
+
+/* Main entry point to the SSA-PRE pass.
+
+ PHASE indicates which dump file from the DUMP_FILES array to use when
+ dumping debugging information. */
+
+static void
+execute_pre (void)
+{
+ int currbbs;
+ varray_type bexprs;
+ size_t k;
+ int i;
+
+ if (ENTRY_BLOCK_PTR->succ->dest->pred->pred_next)
+ if (!(ENTRY_BLOCK_PTR->succ->flags & EDGE_ABNORMAL))
+ split_edge (ENTRY_BLOCK_PTR->succ);
+
+ euse_node_pool = create_alloc_pool ("EUSE node pool",
+ sizeof (struct tree_euse_node), 30);
+ eref_node_pool = create_alloc_pool ("EREF node pool",
+ sizeof (struct tree_eref_common), 30);
+ ephi_use_pool = create_alloc_pool ("EPHI use node pool",
+ sizeof (struct ephi_use_entry), 30);
+ VARRAY_GENERIC_PTR_INIT (bexprs, 1, "bexprs");
+ /* Compute immediate dominators. */
+ calculate_dominance_info (CDI_DOMINATORS);
+
+ /* DCE screws the dom_children up, without bothering to fix it. So fix it. */
+ currbbs = n_basic_blocks;
+ dfn = xcalloc (last_basic_block + 1, sizeof (int));
+ build_dfn_array (ENTRY_BLOCK_PTR, 0);
+
+ /* Initialize IDFS cache. */
+ idfs_cache = xcalloc (currbbs, sizeof (bitmap));
+
+ /* Compute dominance frontiers. */
+ pre_dfs = (bitmap *) xmalloc (sizeof (bitmap) * currbbs);
+ for (i = 0; i < currbbs; i++)
+ pre_dfs[i] = BITMAP_XMALLOC ();
+ compute_dominance_frontiers (pre_dfs);
+
+ created_phi_preds = BITMAP_XMALLOC ();
+
+ collect_expressions (ENTRY_BLOCK_PTR, &bexprs);
+
+ ggc_push_context ();
+
+ for (k = 0; k < VARRAY_ACTIVE_SIZE (bexprs); k++)
+ {
+ pre_expression (VARRAY_GENERIC_PTR (bexprs, k), pre_dfs, vars_to_rename);
+ free_alloc_pool (euse_node_pool);
+ free_alloc_pool (eref_node_pool);
+ free_alloc_pool (ephi_use_pool);
+ euse_node_pool = create_alloc_pool ("EUSE node pool",
+ sizeof (struct tree_euse_node), 30);
+ eref_node_pool = create_alloc_pool ("EREF node pool",
+ sizeof (struct tree_eref_common), 30);
+ ephi_use_pool = create_alloc_pool ("EPHI use node pool",
+ sizeof (struct ephi_use_entry), 30);
+ free_expr_info (VARRAY_GENERIC_PTR (bexprs, k));
+#ifdef ENABLE_CHECKING
+ if (pre_stats.ephis_current != 0)
+ abort ();
+#endif
+ ggc_collect ();
+ }
+
+ ggc_pop_context ();
+
+ /* Clean up after PRE. */
+ memset (&pre_stats, 0, sizeof (struct pre_stats_d));
+ free_alloc_pool (euse_node_pool);
+ free_alloc_pool (eref_node_pool);
+ free_alloc_pool (ephi_use_pool);
+ VARRAY_CLEAR (bexprs);
+ for (i = 0; i < currbbs; i++)
+ BITMAP_XFREE (pre_dfs[i]);
+ free (pre_dfs);
+ BITMAP_XFREE (created_phi_preds);
+ for (i = 0; i < currbbs; i++)
+ if (idfs_cache[i] != NULL)
+ BITMAP_XFREE (idfs_cache[i]);
+
+ free (dfn);
+ free (idfs_cache);
+}
+
+static bool
+gate_pre (void)
+{
+ return flag_tree_pre != 0;
+}
+
+struct tree_opt_pass pass_pre =
+{
+ "pre", /* name */
+ gate_pre, /* gate */
+ execute_pre, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_PRE, /* tv_id */
+ PROP_no_crit_edges | PROP_cfg | PROP_ssa,/* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func | TODO_rename_vars
+ | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */
+};
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
new file mode 100644
index 00000000000..8ecce07e4f4
--- /dev/null
+++ b/gcc/tree-ssa.c
@@ -0,0 +1,1099 @@
+/* Miscellaneous SSA utility functions.
+ Copyright (C) 2001, 2002, 2003, 2004 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 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "flags.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "ggc.h"
+#include "langhooks.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "output.h"
+#include "errors.h"
+#include "expr.h"
+#include "function.h"
+#include "diagnostic.h"
+#include "bitmap.h"
+#include "tree-flow.h"
+#include "tree-gimple.h"
+#include "tree-inline.h"
+#include "varray.h"
+#include "timevar.h"
+#include "tree-alias-common.h"
+#include "hashtab.h"
+#include "tree-dump.h"
+#include "tree-pass.h"
+
+
+/* Remove edge E and remove the corresponding arguments from the PHI nodes
+ in E's destination block. */
+
+void
+ssa_remove_edge (edge e)
+{
+ tree phi, next;
+
+ /* Remove the appropriate PHI arguments in E's destination block. */
+ for (phi = phi_nodes (e->dest); phi; phi = next)
+ {
+ next = TREE_CHAIN (phi);
+ remove_phi_arg (phi, e->src);
+ }
+
+ remove_edge (e);
+}
+
+/* Remove remove the corresponding arguments from the PHI nodes
+ in E's destination block and redirect it to DEST. Return redirected edge.
+ The list of removed arguments is stored in PENDING_STMT (e). */
+
+edge
+ssa_redirect_edge (edge e, basic_block dest)
+{
+ tree phi, next;
+ tree list = NULL, *last = &list;
+ tree src, dst, node;
+ int i;
+
+ /* Remove the appropriate PHI arguments in E's destination block. */
+ for (phi = phi_nodes (e->dest); phi; phi = next)
+ {
+ next = TREE_CHAIN (phi);
+
+ i = phi_arg_from_edge (phi, e);
+ if (i < 0)
+ continue;
+
+ src = PHI_ARG_DEF (phi, i);
+ dst = PHI_RESULT (phi);
+ node = build_tree_list (dst, src);
+ *last = node;
+ last = &TREE_CHAIN (node);
+
+ remove_phi_arg_num (phi, i);
+ }
+
+ e = redirect_edge_succ_nodup (e, dest);
+ PENDING_STMT (e) = list;
+
+ return e;
+}
+
+
+/* Return true if the definition of SSA_NAME at block BB is malformed.
+
+ STMT is the statement where SSA_NAME is created.
+
+ DEFINITION_BLOCK is an array of basic blocks indexed by SSA_NAME version
+ numbers. If DEFINITION_BLOCK[SSA_NAME_VERSION] is set, it means that the
+ block in that array slot contains the definition of SSA_NAME. */
+
+static bool
+verify_def (basic_block bb, basic_block *definition_block, tree ssa_name,
+ tree stmt)
+{
+ bool err = false;
+
+ if (TREE_CODE (ssa_name) != SSA_NAME)
+ {
+ error ("Expected an SSA_NAME object");
+ debug_generic_stmt (ssa_name);
+ debug_generic_stmt (stmt);
+ }
+
+ if (definition_block[SSA_NAME_VERSION (ssa_name)])
+ {
+ error ("SSA_NAME created in two different blocks %i and %i",
+ definition_block[SSA_NAME_VERSION (ssa_name)]->index, bb->index);
+ fprintf (stderr, "SSA_NAME: ");
+ debug_generic_stmt (ssa_name);
+ debug_generic_stmt (stmt);
+ err = true;
+ }
+
+ definition_block[SSA_NAME_VERSION (ssa_name)] = bb;
+
+ if (SSA_NAME_DEF_STMT (ssa_name) != stmt)
+ {
+ error ("SSA_NAME_DEF_STMT is wrong");
+ fprintf (stderr, "SSA_NAME: ");
+ debug_generic_stmt (ssa_name);
+ fprintf (stderr, "Expected definition statement:\n");
+ debug_generic_stmt (SSA_NAME_DEF_STMT (ssa_name));
+ fprintf (stderr, "\nActual definition statement:\n");
+ debug_generic_stmt (stmt);
+ err = true;
+ }
+
+ return err;
+}
+
+
+/* Return true if the use of SSA_NAME at statement STMT in block BB is
+ malformed.
+
+ DEF_BB is the block where SSA_NAME was found to be created.
+
+ IDOM contains immediate dominator information for the flowgraph.
+
+ CHECK_ABNORMAL is true if the caller wants to check whether this use
+ is flowing through an abnormal edge (only used when checking PHI
+ arguments). */
+
+static bool
+verify_use (basic_block bb, basic_block def_bb, tree ssa_name,
+ tree stmt, bool check_abnormal)
+{
+ bool err = false;
+
+ if (IS_EMPTY_STMT (SSA_NAME_DEF_STMT (ssa_name)))
+ ; /* Nothing to do. */
+ else if (!def_bb)
+ {
+ error ("Missing definition");
+ err = true;
+ }
+ else if (bb != def_bb
+ && !dominated_by_p (CDI_DOMINATORS, bb, def_bb))
+ {
+ error ("Definition in block %i does not dominate use in block %i",
+ def_bb->index, bb->index);
+ err = true;
+ }
+
+ if (check_abnormal
+ && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssa_name))
+ {
+ error ("SSA_NAME_OCCURS_IN_ABNORMAL_PHI should be set");
+ err = true;
+ }
+
+ if (err)
+ {
+ fprintf (stderr, "for SSA_NAME: ");
+ debug_generic_stmt (ssa_name);
+ fprintf (stderr, "in statement:\n");
+ debug_generic_stmt (stmt);
+ }
+
+ return err;
+}
+
+
+/* Return true if any of the arguments for PHI node PHI at block BB is
+ malformed.
+
+ IDOM contains immediate dominator information for the flowgraph.
+
+ DEFINITION_BLOCK is an array of basic blocks indexed by SSA_NAME version
+ numbers. If DEFINITION_BLOCK[SSA_NAME_VERSION] is set, it means that the
+ block in that array slot contains the definition of SSA_NAME. */
+
+static bool
+verify_phi_args (tree phi, basic_block bb, basic_block *definition_block)
+{
+ edge e;
+ bool err = false;
+ int i, phi_num_args = PHI_NUM_ARGS (phi);
+
+ /* Mark all the incoming edges. */
+ for (e = bb->pred; e; e = e->pred_next)
+ e->aux = (void *) 1;
+
+ for (i = 0; i < phi_num_args; i++)
+ {
+ tree op = PHI_ARG_DEF (phi, i);
+
+ e = PHI_ARG_EDGE (phi, i);
+
+ if (TREE_CODE (op) == SSA_NAME)
+ err |= verify_use (e->src, definition_block[SSA_NAME_VERSION (op)], op,
+ phi, e->flags & EDGE_ABNORMAL);
+
+ if (e->dest != bb)
+ {
+ error ("Wrong edge %d->%d for PHI argument\n",
+ e->src->index, e->dest->index, bb->index);
+ err = true;
+ }
+
+ if (e->aux == (void *) 0)
+ {
+ error ("PHI argument flowing through dead edge %d->%d\n",
+ e->src->index, e->dest->index);
+ err = true;
+ }
+
+ if (e->aux == (void *) 2)
+ {
+ error ("PHI argument duplicated for edge %d->%d\n", e->src->index,
+ e->dest->index);
+ err = true;
+ }
+
+ if (err)
+ {
+ fprintf (stderr, "PHI argument\n");
+ debug_generic_stmt (op);
+ }
+
+ e->aux = (void *) 2;
+ }
+
+ for (e = bb->pred; e; e = e->pred_next)
+ {
+ if (e->aux != (void *) 2)
+ {
+ error ("No argument flowing through edge %d->%d\n", e->src->index,
+ e->dest->index);
+ err = true;
+ }
+ e->aux = (void *) 0;
+ }
+
+ if (err)
+ {
+ fprintf (stderr, "for PHI node\n");
+ debug_generic_stmt (phi);
+ }
+
+
+ return err;
+}
+
+
+/* Verify common invariants in the SSA web.
+ TODO: verify the variable annotations. */
+
+void
+verify_ssa (void)
+{
+ bool err = false;
+ basic_block bb;
+ basic_block *definition_block = xcalloc (highest_ssa_version,
+ sizeof (basic_block));
+
+ timevar_push (TV_TREE_SSA_VERIFY);
+
+ calculate_dominance_info (CDI_DOMINATORS);
+
+ /* Verify and register all the SSA_NAME definitions found in the
+ function. */
+ FOR_EACH_BB (bb)
+ {
+ tree phi;
+ block_stmt_iterator bsi;
+
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ err |= verify_def (bb, definition_block, PHI_RESULT (phi), phi);
+
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ tree stmt;
+ stmt_ann_t ann;
+ unsigned int j;
+ vdef_optype vdefs;
+ def_optype defs;
+
+ stmt = bsi_stmt (bsi);
+ ann = stmt_ann (stmt);
+ get_stmt_operands (stmt);
+
+ vdefs = VDEF_OPS (ann);
+ for (j = 0; j < NUM_VDEFS (vdefs); j++)
+ {
+ tree op = VDEF_RESULT (vdefs, j);
+ if (is_gimple_reg (op))
+ {
+ error ("Found a virtual definition for a GIMPLE register");
+ debug_generic_stmt (op);
+ debug_generic_stmt (stmt);
+ err = true;
+ }
+ err |= verify_def (bb, definition_block, op, stmt);
+ }
+
+ defs = DEF_OPS (ann);
+ for (j = 0; j < NUM_DEFS (defs); j++)
+ {
+ tree op = DEF_OP (defs, j);
+ if (TREE_CODE (op) == SSA_NAME && !is_gimple_reg (op))
+ {
+ error ("Found a real definition for a non-GIMPLE register");
+ debug_generic_stmt (op);
+ debug_generic_stmt (stmt);
+ err = true;
+ }
+ err |= verify_def (bb, definition_block, op, stmt);
+ }
+ }
+ }
+
+
+ /* Now verify all the uses and make sure they agree with the definitions
+ found in the previous pass. */
+ FOR_EACH_BB (bb)
+ {
+ edge e;
+ tree phi;
+ block_stmt_iterator bsi;
+
+ /* Make sure that all edges have a clear 'aux' field. */
+ for (e = bb->pred; e; e = e->pred_next)
+ {
+ if (e->aux)
+ {
+ error ("AUX pointer initialized for edge %d->%d\n", e->src->index,
+ e->dest->index);
+ err = true;
+ }
+ }
+
+ /* Verify the arguments for every PHI node in the block. */
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ err |= verify_phi_args (phi, bb, definition_block);
+
+ /* Now verify all the uses and vuses in every statement of the block.
+
+ Remember, the RHS of a VDEF is a use as well. */
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ tree stmt = bsi_stmt (bsi);
+ stmt_ann_t ann = stmt_ann (stmt);
+ unsigned int j;
+ vuse_optype vuses;
+ vdef_optype vdefs;
+ use_optype uses;
+
+ vuses = VUSE_OPS (ann);
+ for (j = 0; j < NUM_VUSES (vuses); j++)
+ {
+ tree op = VUSE_OP (vuses, j);
+
+ if (is_gimple_reg (op))
+ {
+ error ("Found a virtual use for a GIMPLE register");
+ debug_generic_stmt (op);
+ debug_generic_stmt (stmt);
+ err = true;
+ }
+ err |= verify_use (bb, definition_block[SSA_NAME_VERSION (op)],
+ op, stmt, false);
+ }
+
+ vdefs = VDEF_OPS (ann);
+ for (j = 0; j < NUM_VDEFS (vdefs); j++)
+ {
+ tree op = VDEF_OP (vdefs, j);
+
+ if (is_gimple_reg (op))
+ {
+ error ("Found a virtual use for a GIMPLE register");
+ debug_generic_stmt (op);
+ debug_generic_stmt (stmt);
+ err = true;
+ }
+ err |= verify_use (bb, definition_block[SSA_NAME_VERSION (op)],
+ op, stmt, false);
+ }
+
+ uses = USE_OPS (ann);
+ for (j = 0; j < NUM_USES (uses); j++)
+ {
+ tree op = USE_OP (uses, j);
+
+ if (TREE_CODE (op) == SSA_NAME && !is_gimple_reg (op))
+ {
+ error ("Found a real use of a non-GIMPLE register");
+ debug_generic_stmt (op);
+ debug_generic_stmt (stmt);
+ err = true;
+ }
+ err |= verify_use (bb, definition_block[SSA_NAME_VERSION (op)],
+ op, stmt, false);
+ }
+ }
+ }
+
+ free (definition_block);
+
+ timevar_pop (TV_TREE_SSA_VERIFY);
+
+ if (err)
+ internal_error ("verify_ssa failed.");
+}
+
+
+/* Set the USED bit in the annotation for T. */
+
+void
+set_is_used (tree t)
+{
+ while (1)
+ {
+ if (SSA_VAR_P (t))
+ break;
+
+ switch (TREE_CODE (t))
+ {
+ case ARRAY_REF:
+ case COMPONENT_REF:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ case BIT_FIELD_REF:
+ case INDIRECT_REF:
+ t = TREE_OPERAND (t, 0);
+ break;
+
+ default:
+ return;
+ }
+ }
+
+ if (TREE_CODE (t) == SSA_NAME)
+ t = SSA_NAME_VAR (t);
+
+ var_ann (t)->used = 1;
+}
+
+
+/* Initialize global DFA and SSA structures. */
+
+void
+init_tree_ssa (void)
+{
+ VARRAY_TREE_INIT (referenced_vars, 20, "referenced_vars");
+ call_clobbered_vars = BITMAP_XMALLOC ();
+ init_ssa_operands ();
+ init_ssanames ();
+ init_phinodes ();
+ global_var = NULL_TREE;
+ aliases_computed_p = false;
+}
+
+
+/* Deallocate memory associated with SSA data structures for FNDECL. */
+
+void
+delete_tree_ssa (void)
+{
+ size_t i;
+ basic_block bb;
+ block_stmt_iterator bsi;
+
+ /* Remove annotations from every tree in the function. */
+ FOR_EACH_BB (bb)
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ bsi_stmt (bsi)->common.ann = NULL;
+
+ /* Remove annotations from every referenced variable. */
+ if (referenced_vars)
+ {
+ for (i = 0; i < num_referenced_vars; i++)
+ referenced_var (i)->common.ann = NULL;
+ referenced_vars = NULL;
+ }
+
+ fini_ssanames ();
+ fini_phinodes ();
+ fini_ssa_operands ();
+
+ global_var = NULL_TREE;
+ BITMAP_XFREE (call_clobbered_vars);
+ call_clobbered_vars = NULL;
+ aliases_computed_p = false;
+}
+
+
+/* Return true if EXPR is a useless type conversion, otherwise return
+ false. */
+
+bool
+tree_ssa_useless_type_conversion_1 (tree outer_type, tree inner_type)
+{
+ /* If the inner and outer types are effectively the same, then
+ strip the type conversion and enter the equivalence into
+ the table. */
+ if (inner_type == outer_type
+ || (lang_hooks.types_compatible_p (inner_type, outer_type)))
+ return true;
+
+ /* If both types are pointers and the outer type is a (void *), then
+ the conversion is not necessary. The opposite is not true since
+ that conversion would result in a loss of information if the
+ equivalence was used. Consider an indirect function call where
+ we need to know the exact type of the function to correctly
+ implement the ABI. */
+ else if (POINTER_TYPE_P (inner_type)
+ && POINTER_TYPE_P (outer_type)
+ && TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE)
+ return true;
+
+ /* Pointers and references are equivalent once we get to GENERIC,
+ so strip conversions that just switch between them. */
+ else if (POINTER_TYPE_P (inner_type)
+ && POINTER_TYPE_P (outer_type)
+ && lang_hooks.types_compatible_p (inner_type, outer_type))
+ return true;
+
+ /* If both the inner and outer types are integral types, then the
+ conversion is not necessary if they have the same mode and
+ signedness and precision. Note that type _Bool can have size of
+ 4 (only happens on powerpc-darwin right now but can happen on any
+ target that defines BOOL_TYPE_SIZE to be INT_TYPE_SIZE) and a
+ precision of 1 while unsigned int is the same expect for a
+ precision of 4 so testing of precision is necessary. */
+ else if (INTEGRAL_TYPE_P (inner_type)
+ && INTEGRAL_TYPE_P (outer_type)
+ && TYPE_MODE (inner_type) == TYPE_MODE (outer_type)
+ && TYPE_UNSIGNED (inner_type) == TYPE_UNSIGNED (outer_type)
+ && TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type))
+ return true;
+
+ /* Recurse for complex types. */
+ else if (TREE_CODE (inner_type) == COMPLEX_TYPE
+ && TREE_CODE (outer_type) == COMPLEX_TYPE
+ && tree_ssa_useless_type_conversion_1 (TREE_TYPE (outer_type),
+ TREE_TYPE (inner_type)))
+ return true;
+
+ return false;
+}
+
+/* Return true if EXPR is a useless type conversion, otherwise return
+ false. */
+
+bool
+tree_ssa_useless_type_conversion (tree expr)
+{
+ /* If we have an assignment that merely uses a NOP_EXPR to change
+ the top of the RHS to the type of the LHS and the type conversion
+ is "safe", then strip away the type conversion so that we can
+ enter LHS = RHS into the const_and_copies table. */
+ if (TREE_CODE (expr) == NOP_EXPR || TREE_CODE (expr) == CONVERT_EXPR)
+ return tree_ssa_useless_type_conversion_1 (TREE_TYPE (expr),
+ TREE_TYPE (TREE_OPERAND (expr,
+ 0)));
+
+
+ return false;
+}
+
+
+/* Internal helper for walk_use_def_chains. VAR, FN and DATA are as
+ described in walk_use_def_chains. VISITED is a bitmap used to mark
+ visited SSA_NAMEs to avoid infinite loops. */
+
+static bool
+walk_use_def_chains_1 (tree var, walk_use_def_chains_fn fn, void *data,
+ bitmap visited)
+{
+ tree def_stmt;
+
+ if (bitmap_bit_p (visited, SSA_NAME_VERSION (var)))
+ return false;
+
+ bitmap_set_bit (visited, SSA_NAME_VERSION (var));
+
+ def_stmt = SSA_NAME_DEF_STMT (var);
+
+ if (TREE_CODE (def_stmt) != PHI_NODE)
+ {
+ /* If we reached the end of the use-def chain, call FN. */
+ return (*fn) (var, def_stmt, data);
+ }
+ else
+ {
+ int i;
+
+ /* Otherwise, follow use-def links out of each PHI argument and call
+ FN after visiting each one. */
+ for (i = 0; i < PHI_NUM_ARGS (def_stmt); i++)
+ {
+ tree arg = PHI_ARG_DEF (def_stmt, i);
+ if (TREE_CODE (arg) == SSA_NAME
+ && walk_use_def_chains_1 (arg, fn, data, visited))
+ return true;
+
+ if ((*fn) (arg, def_stmt, data))
+ return true;
+ }
+ }
+ return false;
+}
+
+
+
+/* Walk use-def chains starting at the SSA variable VAR. Call function FN
+ at each reaching definition found. FN takes three arguments: VAR, its
+ defining statement (DEF_STMT) and a generic pointer to whatever state
+ information that FN may want to maintain (DATA). FN is able to stop the
+ walk by returning true, otherwise in order to continue the walk, FN
+ should return false.
+
+ Note, that if DEF_STMT is a PHI node, the semantics are slightly
+ different. For each argument ARG of the PHI node, this function will:
+
+ 1- Walk the use-def chains for ARG.
+ 2- Call (*FN) (ARG, PHI, DATA).
+
+ Note how the first argument to FN is no longer the original variable
+ VAR, but the PHI argument currently being examined. If FN wants to get
+ at VAR, it should call PHI_RESULT (PHI). */
+
+void
+walk_use_def_chains (tree var, walk_use_def_chains_fn fn, void *data)
+{
+ tree def_stmt;
+
+#if defined ENABLE_CHECKING
+ if (TREE_CODE (var) != SSA_NAME)
+ abort ();
+#endif
+
+ def_stmt = SSA_NAME_DEF_STMT (var);
+
+ /* We only need to recurse if the reaching definition comes from a PHI
+ node. */
+ if (TREE_CODE (def_stmt) != PHI_NODE)
+ (*fn) (var, def_stmt, data);
+ else
+ {
+ bitmap visited = BITMAP_XMALLOC ();
+ walk_use_def_chains_1 (var, fn, data, visited);
+ BITMAP_XFREE (visited);
+ }
+}
+
+
+/* Replaces immediate uses of VAR by REPL. */
+
+static void
+replace_immediate_uses (tree var, tree repl)
+{
+ use_optype uses;
+ vuse_optype vuses;
+ vdef_optype vdefs;
+ int i, j, n;
+ dataflow_t df;
+ tree stmt;
+ stmt_ann_t ann;
+
+ df = get_immediate_uses (SSA_NAME_DEF_STMT (var));
+ n = num_immediate_uses (df);
+
+ for (i = 0; i < n; i++)
+ {
+ stmt = immediate_use (df, i);
+ ann = stmt_ann (stmt);
+
+ if (TREE_CODE (stmt) == PHI_NODE)
+ {
+ for (j = 0; j < PHI_NUM_ARGS (stmt); j++)
+ if (PHI_ARG_DEF (stmt, j) == var)
+ {
+ PHI_ARG_DEF (stmt, j) = repl;
+ if (TREE_CODE (repl) == SSA_NAME
+ && PHI_ARG_EDGE (stmt, j)->flags & EDGE_ABNORMAL)
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI (repl) = 1;
+ }
+
+ continue;
+ }
+
+ get_stmt_operands (stmt);
+ if (is_gimple_reg (SSA_NAME_VAR (var)))
+ {
+ uses = USE_OPS (ann);
+ for (j = 0; j < (int) NUM_USES (uses); j++)
+ if (USE_OP (uses, j) == var)
+ propagate_value (USE_OP_PTR (uses, j), repl);
+ }
+ else
+ {
+ vuses = VUSE_OPS (ann);
+ for (j = 0; j < (int) NUM_VUSES (vuses); j++)
+ if (VUSE_OP (vuses, j) == var)
+ propagate_value (VUSE_OP_PTR (vuses, j), repl);
+
+ vdefs = VDEF_OPS (ann);
+ for (j = 0; j < (int) NUM_VDEFS (vdefs); j++)
+ if (VDEF_OP (vdefs, j) == var)
+ propagate_value (VDEF_OP_PTR (vdefs, j), repl);
+ }
+
+ modify_stmt (stmt);
+
+ /* If REPL is a pointer, it may have different memory tags associated
+ with it. For instance, VAR may have had a name tag while REPL
+ only had a type tag. In these cases, the virtual operands (if
+ any) in the statement will refer to different symbols which need
+ to be renamed. */
+ if (POINTER_TYPE_P (TREE_TYPE (repl)))
+ mark_new_vars_to_rename (stmt, vars_to_rename);
+ }
+}
+
+/* Raises value of phi node PHI by joining it with VAL. Processes immediate
+ uses of PHI recursively. */
+
+static void
+raise_value (tree phi, tree val, tree *eq_to)
+{
+ int i, n;
+ tree var = PHI_RESULT (phi), stmt;
+ int ver = SSA_NAME_VERSION (var);
+ dataflow_t df;
+
+ if (eq_to[ver] == var)
+ return;
+
+ switch (TREE_CODE (val))
+ {
+ case SSA_NAME:
+ case REAL_CST:
+ case COMPLEX_CST:
+ break;
+ case INTEGER_CST:
+ if (TREE_CODE (TREE_TYPE (var)) != POINTER_TYPE)
+ break;
+
+ default:
+ /* Do not propagate pointer constants. This might require folding
+ things like *&foo and rewriting the ssa, which is not worth the
+ trouble. */
+ val = var;
+ }
+
+ if (eq_to[ver])
+ {
+ if (operand_equal_p (eq_to[ver], val, 0))
+ return;
+
+ eq_to[ver] = var;
+ }
+ else
+ eq_to[ver] = val;
+
+ df = get_immediate_uses (SSA_NAME_DEF_STMT (var));
+ n = num_immediate_uses (df);
+
+ for (i = 0; i < n; i++)
+ {
+ stmt = immediate_use (df, i);
+
+ if (TREE_CODE (stmt) != PHI_NODE)
+ continue;
+
+ raise_value (stmt, eq_to[ver], eq_to);
+ }
+}
+
+/* Removes redundant phi nodes.
+
+ A redundant PHI node is a PHI node where all of its PHI arguments
+ are the same value, excluding any PHI arguments which are the same
+ as the PHI result.
+
+ A redundant PHI node is effectively a copy, so we forward copy propagate
+ which removes all uses of the destination of the PHI node then
+ finally we delete the redundant PHI node.
+
+ Note that if we can not copy propagate the PHI node, then the PHI
+ will not be removed. Thus we do not have to worry about dependencies
+ between PHIs and the problems serializing PHIs into copies creates.
+
+ The most important effect of this pass is to remove degenerate PHI
+ nodes created by removing unreachable code. */
+
+static void
+kill_redundant_phi_nodes (void)
+{
+ tree *eq_to, *ssa_names;
+ unsigned i, ver, aver;
+ basic_block bb;
+ tree phi, t, stmt, var;
+
+ /* The EQ_TO array holds the current value of the ssa name in the
+ lattice:
+
+ top
+ / | \
+ const variables
+ \ | /
+ bottom
+
+ Bottom is represented by NULL and top by the variable itself.
+
+ Once the dataflow stabilizes, we know that the phi nodes we need to keep
+ are exactly those with top as their result.
+
+ The remaining phi nodes have their uses replaced with their value
+ in the lattice and the phi node itself is removed. */
+ eq_to = xcalloc (highest_ssa_version, sizeof (tree));
+
+ /* The SSA_NAMES array holds each SSA_NAME node we encounter
+ in a PHI node (indexed by ssa version number).
+
+ One could argue that the SSA_NAME manager ought to provide a
+ generic interface to get at the SSA_NAME node for a given
+ ssa version number. */
+ ssa_names = xcalloc (highest_ssa_version, sizeof (tree));
+
+ /* We have had cases where computing immediate uses takes a
+ significant amount of compile time. If we run into such
+ problems here, we may want to only compute immediate uses for
+ a subset of all the SSA_NAMEs instead of computing it for
+ all of the SSA_NAMEs. */
+ compute_immediate_uses (TDFA_USE_OPS | TDFA_USE_VOPS, NULL);
+
+ FOR_EACH_BB (bb)
+ {
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ var = PHI_RESULT (phi);
+ ver = SSA_NAME_VERSION (var);
+ ssa_names[ver] = var;
+
+ for (i = 0; i < (unsigned) PHI_NUM_ARGS (phi); i++)
+ {
+ t = PHI_ARG_DEF (phi, i);
+
+ if (TREE_CODE (t) != SSA_NAME)
+ {
+ raise_value (phi, t, eq_to);
+ continue;
+ }
+
+ stmt = SSA_NAME_DEF_STMT (t);
+ aver = SSA_NAME_VERSION (t);
+ ssa_names[aver] = t;
+
+ /* If the defining statement for this argument is not a
+ phi node or the argument is associated with an abnormal
+ edge, then we need to recursively start the forward
+ dataflow starting with PHI. */
+ if (TREE_CODE (stmt) != PHI_NODE
+ || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (t))
+ {
+ eq_to[aver] = t;
+ raise_value (phi, t, eq_to);
+ }
+ }
+ }
+ }
+
+ /* Now propagate the values. */
+ for (i = 0; i < highest_ssa_version; i++)
+ if (eq_to[i]
+ && eq_to[i] != ssa_names[i])
+ replace_immediate_uses (ssa_names[i], eq_to[i]);
+
+ /* And remove the dead phis. */
+ for (i = 0; i < highest_ssa_version; i++)
+ if (eq_to[i]
+ && eq_to[i] != ssa_names[i])
+ {
+ stmt = SSA_NAME_DEF_STMT (ssa_names[i]);
+ remove_phi_node (stmt, 0, bb_for_stmt (stmt));
+ }
+
+ free_df ();
+ free (eq_to);
+ free (ssa_names);
+}
+
+struct tree_opt_pass pass_redundant_phi =
+{
+ "redphi", /* name */
+ NULL, /* gate */
+ kill_redundant_phi_nodes, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ PROP_cfg | PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func | TODO_rename_vars
+ | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */
+};
+
+/* Emit warnings for uninitialized variables. This is done in two passes.
+
+ The first pass notices real uses of SSA names with default definitions.
+ Such uses are unconditionally uninitialized, and we can be certain that
+ such a use is a mistake. This pass is run before most optimizations,
+ so that we catch as many as we can.
+
+ The second pass follows PHI nodes to find uses that are potentially
+ uninitialized. In this case we can't necessarily prove that the use
+ is really uninitialized. This pass is run after most optimizations,
+ so that we thread as many jumps and possible, and delete as much dead
+ code as possible, in order to reduce false positives. We also look
+ again for plain uninitialized variables, since optimization may have
+ changed conditionally uninitialized to unconditionally uninitialized. */
+
+/* Emit a warning for T, an SSA_NAME, being uninitialized. The exact
+ warning text is in MSGID and LOCUS may contain a location or be null. */
+
+static void
+warn_uninit (tree t, const char *msgid, location_t *locus)
+{
+ tree var = SSA_NAME_VAR (t);
+ tree def = SSA_NAME_DEF_STMT (t);
+
+ /* Default uses (indicated by an empty definition statement),
+ are uninitialized. */
+ if (!IS_EMPTY_STMT (def))
+ return;
+
+ /* Except for PARMs of course, which are always initialized. */
+ if (TREE_CODE (var) == PARM_DECL)
+ return;
+
+ /* Hard register variables get their initial value from the ether. */
+ if (DECL_HARD_REGISTER (var))
+ return;
+
+ /* TREE_NO_WARNING either means we already warned, or the front end
+ wishes to suppress the warning. */
+ if (TREE_NO_WARNING (var))
+ return;
+
+ if (!locus)
+ locus = &DECL_SOURCE_LOCATION (var);
+ warning (msgid, locus, var);
+ TREE_NO_WARNING (var) = 1;
+}
+
+/* Called via walk_tree, look for SSA_NAMEs that have empty definitions
+ and warn about them. */
+
+static tree
+warn_uninitialized_var (tree *tp, int *walk_subtrees, void *data)
+{
+ location_t *locus = data;
+ tree t = *tp;
+
+ /* We only do data flow with SSA_NAMEs, so that's all we can warn about. */
+ if (TREE_CODE (t) == SSA_NAME)
+ {
+ warn_uninit (t, "%H'%D' is used uninitialized in this function", locus);
+ *walk_subtrees = 0;
+ }
+ else if (DECL_P (t) || TYPE_P (t))
+ *walk_subtrees = 0;
+
+ return NULL_TREE;
+}
+
+/* Look for inputs to PHI that are SSA_NAMEs that have empty definitions
+ and warn about them. */
+
+static void
+warn_uninitialized_phi (tree phi)
+{
+ int i, n = PHI_NUM_ARGS (phi);
+
+ /* Don't look at memory tags. */
+ if (!is_gimple_reg (PHI_RESULT (phi)))
+ return;
+
+ for (i = 0; i < n; ++i)
+ {
+ tree op = PHI_ARG_DEF (phi, i);
+ if (TREE_CODE (op) == SSA_NAME)
+ warn_uninit (op, "%H'%D' may be used uninitialized in this function",
+ NULL);
+ }
+}
+
+static void
+execute_early_warn_uninitialized (void)
+{
+ block_stmt_iterator bsi;
+ basic_block bb;
+
+ FOR_EACH_BB (bb)
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ walk_tree (bsi_stmt_ptr (bsi), warn_uninitialized_var,
+ EXPR_LOCUS (bsi_stmt (bsi)), NULL);
+}
+
+static void
+execute_late_warn_uninitialized (void)
+{
+ basic_block bb;
+ tree phi;
+
+ /* Re-do the plain uninitialized variable check, as optimization may have
+ straightened control flow. Do this first so that we don't accidentally
+ get a "may be" warning when we'd have seen an "is" warning later. */
+ execute_early_warn_uninitialized ();
+
+ FOR_EACH_BB (bb)
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ warn_uninitialized_phi (phi);
+}
+
+static bool
+gate_warn_uninitialized (void)
+{
+ return warn_uninitialized != 0;
+}
+
+struct tree_opt_pass pass_early_warn_uninitialized =
+{
+ NULL, /* name */
+ gate_warn_uninitialized, /* gate */
+ execute_early_warn_uninitialized, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0 /* todo_flags_finish */
+};
+
+struct tree_opt_pass pass_late_warn_uninitialized =
+{
+ NULL, /* name */
+ gate_warn_uninitialized, /* gate */
+ execute_late_warn_uninitialized, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0 /* todo_flags_finish */
+};
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
new file mode 100644
index 00000000000..1142492430e
--- /dev/null
+++ b/gcc/tree-ssanames.c
@@ -0,0 +1,184 @@
+/* Generic routines for manipulating SSA_NAME expressions
+ Copyright (C) 2003 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 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "varray.h"
+#include "ggc.h"
+
+/* Rewriting a function into SSA form can create a huge number of SSA_NAMEs,
+ many of which may be thrown away shortly after their creation if jumps
+ were threaded through PHI nodes.
+
+ While our garbage collection mechanisms will handle this situation, it
+ is extremely wasteful to create nodes and throw them away, especially
+ when the nodes can be reused.
+
+ For PR 8361, we can significantly reduce the number of nodes allocated
+ and thus the total amount of memory allocated by managing SSA_NAMEs a
+ little. This additionally helps reduce the amount of work done by the
+ garbage collector. Similar results have been seen on a wider variety
+ of tests (such as the compiler itself).
+
+ Right now we maintain our free list on a per-function basis. It may
+ or may not make sense to maintain the free list for the duration of
+ a compilation unit.
+
+ External code should rely solely upon HIGHEST_SSA_VERSION and the
+ externally defined functions. External code should not know about
+ the details of the free list management.
+
+ External code should also not assume the version number on nodes is
+ monotonically increasing. We reuse the version number when we
+ reuse an SSA_NAME expression. This helps keep arrays and bitmaps
+ more compact.
+
+ We could also use a zone allocator for these objects since they have
+ a very well defined lifetime. If someone wants to experiment with that
+ this is the place to try it. */
+
+/* Next SSA version number to be allocated. */
+unsigned int highest_ssa_version;
+
+/* Free list of SSA_NAMEs. This list is wiped at the end of each function
+ after we leave SSA form. */
+static GTY (()) tree free_ssanames;
+
+/* Version numbers with special meanings. We start allocating new version
+ numbers after the special ones. */
+#define UNUSED_NAME_VERSION 0
+
+#ifdef GATHER_STATISTICS
+unsigned int ssa_name_nodes_reused;
+unsigned int ssa_name_nodes_created;
+#endif
+
+/* Initialize management of SSA_NAMEs. */
+
+void
+init_ssanames (void)
+{
+ highest_ssa_version = UNUSED_NAME_VERSION + 1;
+ free_ssanames = NULL;
+}
+
+/* Finalize management of SSA_NAMEs. */
+
+void
+fini_ssanames (void)
+{
+ free_ssanames = NULL;
+}
+
+/* Dump some simple statistics regarding the re-use of SSA_NAME nodes. */
+
+#ifdef GATHER_STATISTICS
+void
+ssanames_print_statistics (void)
+{
+ fprintf (stderr, "SSA_NAME nodes allocated: %u\n", ssa_name_nodes_created);
+ fprintf (stderr, "SSA_NAME nodes reused: %u\n", ssa_name_nodes_reused);
+}
+#endif
+
+/* Return an SSA_NAME node for variable VAR defined in statement STMT.
+ STMT may be an empty statement for artificial references (e.g., default
+ definitions created when a variable is used without a preceding
+ definition). */
+
+tree
+make_ssa_name (tree var, tree stmt)
+{
+ tree t;
+
+#if defined ENABLE_CHECKING
+ if ((!DECL_P (var)
+ && TREE_CODE (var) != INDIRECT_REF)
+ || (!IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (stmt)))
+ && TREE_CODE (stmt) != PHI_NODE))
+ abort ();
+#endif
+
+ /* If our free list has an element, then use it. Also reuse the
+ SSA version number of the element on the free list which helps
+ keep sbitmaps and arrays sized HIGHEST_SSA_VERSION smaller. */
+ if (free_ssanames)
+ {
+ unsigned int save_version;
+
+ t = free_ssanames;
+ free_ssanames = TREE_CHAIN (free_ssanames);
+#ifdef GATHER_STATISTICS
+ ssa_name_nodes_reused++;
+#endif
+
+ /* Clear the node so that it looks just like one we would have
+ received from make_node. */
+ save_version = SSA_NAME_VERSION (t);
+ memset (t, 0, tree_size (t));
+ TREE_SET_CODE (t, SSA_NAME);
+ SSA_NAME_VERSION (t) = save_version;
+ }
+ else
+ {
+ t = make_node (SSA_NAME);
+ SSA_NAME_VERSION (t) = highest_ssa_version++;
+#ifdef GATHER_STATISTICS
+ ssa_name_nodes_created++;
+#endif
+ }
+
+ TREE_TYPE (t) = TREE_TYPE (var);
+ SSA_NAME_VAR (t) = var;
+ SSA_NAME_DEF_STMT (t) = stmt;
+
+ return t;
+}
+
+/* We no longer need the SSA_NAME expression VAR, release it so that
+ it may be reused.
+
+ Note it is assumed that no calls to make_ssa_name will be made
+ until all uses of the ssa name are released and that the only
+ use of the SSA_NAME expression is to check its SSA_NAME_VAR. All
+ other fields must be assumed clobbered. */
+
+void
+release_ssa_name (tree var)
+{
+ /* release_ssa_name can be called multiple times on a single SSA_NAME.
+ However, it should only end up on our free list one time. We
+ keep a status bit in the SSA_NAME node itself to indicate it has
+ been put on the free list.
+
+ Note that once on the freelist you can not reference the SSA_NAME's
+ defining statement. */
+ if (! SSA_NAME_IN_FREE_LIST (var))
+ {
+ SSA_NAME_IN_FREE_LIST (var) = 1;
+ TREE_CHAIN (var) = free_ssanames;
+ free_ssanames = var;
+ }
+}
+
+#include "gt-tree-ssanames.h"
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
new file mode 100644
index 00000000000..65657da250b
--- /dev/null
+++ b/gcc/tree-tailcall.c
@@ -0,0 +1,932 @@
+/* Tail calls optimization on trees.
+ Copyright (C) 2003 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 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "function.h"
+#include "tree-flow.h"
+#include "tree-dump.h"
+#include "diagnostic.h"
+#include "except.h"
+#include "tree-pass.h"
+#include "flags.h"
+#include "langhooks.h"
+
+/* The file implements the tail recursion elimination. It is also used to
+ analyse the tail calls in general, passing the results to the rtl level
+ where they are used for sibcall optimization.
+
+ In addition to the standard tail recursion elimination, we handle the most
+ trivial cases of making the call tail recursive by creating accumulators.
+ For example the following function
+
+ int sum (int n)
+ {
+ if (n > 0)
+ return n + sum (n - 1);
+ else
+ return 0;
+ }
+
+ is transformed into
+
+ int sum (int n)
+ {
+ int acc = 0;
+
+ while (n > 0)
+ acc += n--;
+
+ return acc;
+ }
+
+ To do this, we maintain two accumulators (a_acc and m_acc) that indicate
+ when we reach the return x statement, we should return a_acc + x * m_acc
+ instead. They are initially initialized to 0 and 1, respectively,
+ so the semantics of the function is obviously preserved. If we are
+ guaranteed that the value of the accumulator never change, we
+ omit the accumulator.
+
+ There are three cases how the function may exit. The first one is
+ handled in adjust_return_value, the later two in adjust_accumulator_values
+ (the second case is actually a special case of the third one and we
+ present it separately just for clarity):
+
+ 1) Just return x, where x is not in any of the remaining special shapes.
+ We rewrite this to a gimple equivalent of return m_acc * x + a_acc.
+
+ 2) return f (...), where f is the current function, is rewritten in a
+ clasical tail-recursion elimination way, into assignment of arguments
+ and jump to the start of the function. Values of the accumulators
+ are unchanged.
+
+ 3) return a + m * f(...), where a and m do not depend on call to f.
+ To preserve the semantics described before we want this to be rewritten
+ in such a way that we finally return
+
+ a_acc + (a + m * f(...)) * m_acc = (a_acc + a * m_acc) + (m * m_acc) * f(...).
+
+ I.e. we increase a_acc by a * m_acc, multiply m_acc by m and
+ eliminate the tail call to f. Special cases when the value is just
+ added or just multiplied are obtained by setting a = 0 or m = 1.
+
+ TODO -- it is possible to do similar tricks for other operations. */
+
+/* A structure that describes the tailcall. */
+
+struct tailcall
+{
+ /* The block in that the call occur. */
+ basic_block call_block;
+
+ /* The iterator pointing to the call statement. */
+ block_stmt_iterator call_bsi;
+
+ /* True if it is a call to the current function. */
+ bool tail_recursion;
+
+ /* The return value of the caller is mult * f + add, where f is the return
+ value of the call. */
+ tree mult, add;
+
+ /* Next tailcall in the chain. */
+ struct tailcall *next;
+};
+
+/* The variables holding the value of multiplicative and additive
+ accumulator. */
+static tree m_acc, a_acc;
+
+static bool suitable_for_tail_opt_p (void);
+static bool optimize_tail_call (struct tailcall *, bool);
+static void eliminate_tail_call (struct tailcall *);
+static void find_tail_calls (basic_block, struct tailcall **);
+
+/* Returns false when the function is not suitable for tail call optimization
+ from some reason (e.g. if it takes variable number of arguments). */
+
+static bool
+suitable_for_tail_opt_p (void)
+{
+ int i;
+
+ if (current_function_stdarg)
+ return false;
+
+ /* No local variable should be call-clobbered. We ignore any kind
+ of memory tag, as these are not real variables. */
+ for (i = 0; i < (int) VARRAY_ACTIVE_SIZE (referenced_vars); i++)
+ {
+ tree var = VARRAY_TREE (referenced_vars, i);
+
+ if (decl_function_context (var) == current_function_decl
+ && !TREE_STATIC (var)
+ && var_ann (var)->mem_tag_kind == NOT_A_TAG
+ && is_call_clobbered (var))
+ return false;
+ }
+
+ return true;
+}
+/* Returns false when the function is not suitable for tail call optimization
+ from some reason (e.g. if it takes variable number of arguments).
+ This test must pass in addition to suitable_for_tail_opt_p in order to make
+ tail call discovery happen. */
+
+static bool
+suitable_for_tail_call_opt_p (void)
+{
+ /* alloca (until we have stack slot life analysis) inhibits
+ sibling call optimizations, but not tail recursion. */
+ if (current_function_calls_alloca)
+ return false;
+
+ /* If we are using sjlj exceptions, we may need to add a call to
+ _Unwind_SjLj_Unregister at exit of the function. Which means
+ that we cannot do any sibcall transformations. */
+ if (USING_SJLJ_EXCEPTIONS && current_function_has_exception_handlers ())
+ return false;
+
+ /* Any function that calls setjmp might have longjmp called from
+ any called function. ??? We really should represent this
+ properly in the CFG so that this needn't be special cased. */
+ if (current_function_calls_setjmp)
+ return false;
+
+ return true;
+}
+
+/* Checks whether the expression EXPR in stmt AT is independent of the
+ statement pointed by BSI (in a sense that we already know EXPR's value
+ at BSI). We use the fact that we are only called from the chain of
+ basic blocks that have only single successor. Returns the expression
+ containing the value of EXPR at BSI. */
+
+static tree
+independent_of_stmt_p (tree expr, tree at, block_stmt_iterator bsi)
+{
+ basic_block bb, call_bb, at_bb;
+ edge e;
+
+ if (is_gimple_min_invariant (expr))
+ return expr;
+
+ if (TREE_CODE (expr) != SSA_NAME)
+ return NULL_TREE;
+
+ /* Mark the blocks in the chain leading to the end. */
+ at_bb = bb_for_stmt (at);
+ call_bb = bb_for_stmt (bsi_stmt (bsi));
+ for (bb = call_bb; bb != at_bb; bb = bb->succ->dest)
+ bb->aux = &bb->aux;
+ bb->aux = &bb->aux;
+
+ while (1)
+ {
+ at = SSA_NAME_DEF_STMT (expr);
+ bb = bb_for_stmt (at);
+
+ /* The default defininition or defined before the chain. */
+ if (!bb || !bb->aux)
+ break;
+
+ if (bb == call_bb)
+ {
+ for (; !bsi_end_p (bsi); bsi_next (&bsi))
+ if (bsi_stmt (bsi) == at)
+ break;
+
+ if (!bsi_end_p (bsi))
+ expr = NULL_TREE;
+ break;
+ }
+
+ if (TREE_CODE (at) != PHI_NODE)
+ {
+ expr = NULL_TREE;
+ break;
+ }
+
+ for (e = bb->pred; e; e = e->pred_next)
+ if (e->src->aux)
+ break;
+ if (!e)
+ abort ();
+
+ expr = phi_element_for_edge (at, e)->def;
+ }
+
+ /* Unmark the blocks. */
+ for (bb = call_bb; bb != at_bb; bb = bb->succ->dest)
+ bb->aux = NULL;
+ bb->aux = NULL;
+
+ return expr;
+}
+
+/* Simulates the effect of an assignment of ASS in STMT on the return value
+ of the tail recursive CALL passed in ASS_VAR. M and A are the
+ multiplicative and the additive factor for the real return value. */
+
+static bool
+process_assignment (tree ass, tree stmt, block_stmt_iterator call, tree *m,
+ tree *a, tree *ass_var)
+{
+ tree op0, op1, non_ass_var;
+ tree dest = TREE_OPERAND (ass, 0);
+ tree src = TREE_OPERAND (ass, 1);
+ enum tree_code code = TREE_CODE (src);
+
+ if (code == SSA_NAME)
+ {
+ if (src != *ass_var)
+ return false;
+
+ *ass_var = dest;
+ return true;
+ }
+
+ if (TREE_CODE_CLASS (code) != '2')
+ return false;
+
+ /* We only handle the code like
+
+ x = call ();
+ y = m * x;
+ z = y + a;
+ return z;
+
+ TODO -- Extend it for cases where the linear transformation of the output
+ is expressed in a more complicated way. */
+
+ op0 = TREE_OPERAND (src, 0);
+ op1 = TREE_OPERAND (src, 1);
+
+ if (op0 == *ass_var
+ && (non_ass_var = independent_of_stmt_p (op1, stmt, call)))
+ ;
+ else if (op1 == *ass_var
+ && (non_ass_var = independent_of_stmt_p (op0, stmt, call)))
+ ;
+ else
+ return false;
+
+ switch (TREE_CODE (src))
+ {
+ case PLUS_EXPR:
+ /* There should be no previous addition. TODO -- it should be fairly
+ straightforward to lift this restriction -- just allow storing
+ more complicated expressions in *A, and gimplify it in
+ adjust_accumulator_values. */
+ if (*a)
+ return false;
+ *a = non_ass_var;
+ *ass_var = dest;
+ return true;
+
+ case MULT_EXPR:
+ /* Similar remark applies here. Handling multiplication after addition
+ is just slightly more complicated -- we need to multiply both *A and
+ *M. */
+ if (*a || *m)
+ return false;
+ *m = non_ass_var;
+ *ass_var = dest;
+ return true;
+
+ /* TODO -- Handle other codes (NEGATE_EXPR, MINUS_EXPR). */
+
+ default:
+ return false;
+ }
+}
+
+/* Propagate VAR through phis on edge E. */
+
+static tree
+propagate_through_phis (tree var, edge e)
+{
+ basic_block dest = e->dest;
+ tree phi;
+
+ for (phi = phi_nodes (dest); phi; phi = TREE_CHAIN (phi))
+ if (phi_element_for_edge (phi, e)->def == var)
+ return PHI_RESULT (phi);
+
+ return var;
+}
+
+/* Finds tailcalls falling into basic block BB. The list of found tailcalls is
+ added to the start of RET. */
+
+static void
+find_tail_calls (basic_block bb, struct tailcall **ret)
+{
+ tree ass_var, ret_var, stmt, func, param, args, call = NULL_TREE;
+ block_stmt_iterator bsi, absi;
+ bool tail_recursion;
+ struct tailcall *nw;
+ edge e;
+ tree m, a;
+ basic_block abb;
+ stmt_ann_t ann;
+
+ if (bb->succ->succ_next)
+ return;
+
+ for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
+ {
+ stmt = bsi_stmt (bsi);
+
+ /* Ignore labels. */
+ if (TREE_CODE (stmt) == LABEL_EXPR)
+ continue;
+
+ get_stmt_operands (stmt);
+
+ /* Check for a call. */
+ if (TREE_CODE (stmt) == MODIFY_EXPR)
+ {
+ ass_var = TREE_OPERAND (stmt, 0);
+ call = TREE_OPERAND (stmt, 1);
+ }
+ else
+ {
+ ass_var = NULL_TREE;
+ call = stmt;
+ }
+
+ if (TREE_CODE (call) == CALL_EXPR)
+ break;
+
+ /* If the statement has virtual operands, fail. */
+ ann = stmt_ann (stmt);
+ if (NUM_VDEFS (VDEF_OPS (ann))
+ || NUM_VUSES (VUSE_OPS (ann)))
+ return;
+ }
+
+ if (bsi_end_p (bsi))
+ {
+ /* Recurse to the predecessors. */
+ for (e = bb->pred; e; e = e->pred_next)
+ find_tail_calls (e->src, ret);
+
+ return;
+ }
+
+ /* We found the call, check whether it is suitable. */
+ tail_recursion = false;
+ func = get_callee_fndecl (call);
+ if (func == current_function_decl)
+ {
+ for (param = DECL_ARGUMENTS (func), args = TREE_OPERAND (call, 1);
+ param && args;
+ param = TREE_CHAIN (param), args = TREE_CHAIN (args))
+ {
+ tree arg = TREE_VALUE (args);
+ if (param != arg
+ /* Make sure there are no problems with copying. Note we must
+ have a copyable type and the two arguments must have reasonably
+ equivalent types. The latter requirement could be relaxed if
+ we emitted a suitable type conversion statement. */
+ && (!is_gimple_reg_type (TREE_TYPE (param))
+ || !lang_hooks.types_compatible_p (TREE_TYPE (param),
+ TREE_TYPE (arg))))
+ break;
+ }
+ if (!args && !param)
+ tail_recursion = true;
+ }
+
+ /* Now check the statements after the call. None of them has virtual
+ operands, so they may only depend on the call through its return
+ value. The return value should also be dependent on each of them,
+ since we are running after dce. */
+ m = NULL_TREE;
+ a = NULL_TREE;
+
+ abb = bb;
+ absi = bsi;
+ while (1)
+ {
+ bsi_next (&absi);
+
+ while (bsi_end_p (absi))
+ {
+ ass_var = propagate_through_phis (ass_var, abb->succ);
+ abb = abb->succ->dest;
+ absi = bsi_start (abb);
+ }
+
+ stmt = bsi_stmt (absi);
+
+ if (TREE_CODE (stmt) == LABEL_EXPR)
+ continue;
+
+ if (TREE_CODE (stmt) == RETURN_EXPR)
+ break;
+
+ if (TREE_CODE (stmt) != MODIFY_EXPR)
+ return;
+
+ /* Unless this is a tail recursive call, we cannot do anything with
+ the statement anyway. */
+ if (!tail_recursion)
+ return;
+
+ if (!process_assignment (stmt, stmt, bsi, &m, &a, &ass_var))
+ return;
+ }
+
+ ret_var = TREE_OPERAND (stmt, 0);
+ if (ret_var
+ && TREE_CODE (ret_var) == MODIFY_EXPR)
+ {
+ if (!tail_recursion
+ && TREE_CODE (TREE_OPERAND (ret_var, 1)) != SSA_NAME)
+ return;
+
+ if (!process_assignment (ret_var, stmt, bsi, &m, &a, &ass_var))
+ return;
+ ret_var = TREE_OPERAND (ret_var, 0);
+ }
+
+ /* We may proceed if there either is no return value, or the return value
+ is identical to the call's return. */
+ if (ret_var
+ && (ret_var != ass_var))
+ return;
+
+ nw = xmalloc (sizeof (struct tailcall));
+
+ nw->call_block = bb;
+ nw->call_bsi = bsi;
+
+ nw->tail_recursion = tail_recursion;
+
+ nw->mult = m;
+ nw->add = a;
+
+ nw->next = *ret;
+ *ret = nw;
+}
+
+/* Adjust the accumulator values according to A and M after BSI, and update
+ the phi nodes on edge BACK. */
+
+static void
+adjust_accumulator_values (block_stmt_iterator bsi, tree m, tree a, edge back)
+{
+ tree stmt, var, phi, tmp;
+ tree ret_type = TREE_TYPE (DECL_RESULT (current_function_decl));
+ tree a_acc_arg = a_acc, m_acc_arg = m_acc;
+
+ if (a)
+ {
+ if (m_acc)
+ {
+ if (integer_onep (a))
+ var = m_acc;
+ else
+ {
+ stmt = build (MODIFY_EXPR, ret_type, NULL_TREE,
+ build (MULT_EXPR, ret_type, m_acc, a));
+
+ tmp = create_tmp_var (ret_type, "acc_tmp");
+ add_referenced_tmp_var (tmp);
+
+ var = make_ssa_name (tmp, stmt);
+ TREE_OPERAND (stmt, 0) = var;
+ bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
+ }
+ }
+ else
+ var = a;
+
+ stmt = build (MODIFY_EXPR, ret_type, NULL_TREE,
+ build (PLUS_EXPR, ret_type, a_acc, var));
+ var = make_ssa_name (SSA_NAME_VAR (a_acc), stmt);
+ TREE_OPERAND (stmt, 0) = var;
+ bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
+ a_acc_arg = var;
+ }
+
+ if (m)
+ {
+ stmt = build (MODIFY_EXPR, ret_type, NULL_TREE,
+ build (MULT_EXPR, ret_type, m_acc, m));
+ var = make_ssa_name (SSA_NAME_VAR (m_acc), stmt);
+ TREE_OPERAND (stmt, 0) = var;
+ bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
+ m_acc_arg = var;
+ }
+
+ if (a_acc)
+ {
+ for (phi = phi_nodes (back->dest); phi; phi = TREE_CHAIN (phi))
+ if (PHI_RESULT (phi) == a_acc)
+ break;
+
+ add_phi_arg (&phi, a_acc_arg, back);
+ }
+
+ if (m_acc)
+ {
+ for (phi = phi_nodes (back->dest); phi; phi = TREE_CHAIN (phi))
+ if (PHI_RESULT (phi) == m_acc)
+ break;
+
+ add_phi_arg (&phi, m_acc_arg, back);
+ }
+}
+
+/* Adjust value of the return at the end of BB accodring to M and A
+ accumulators. */
+
+static void
+adjust_return_value (basic_block bb, tree m, tree a)
+{
+ tree ret_stmt = last_stmt (bb), ret_var, var, stmt, tmp;
+ tree ret_type = TREE_TYPE (DECL_RESULT (current_function_decl));
+ block_stmt_iterator bsi = bsi_last (bb);
+
+ if (TREE_CODE (ret_stmt) != RETURN_EXPR)
+ abort ();
+
+ ret_var = TREE_OPERAND (ret_stmt, 0);
+ if (!ret_var)
+ return;
+
+ if (TREE_CODE (ret_var) == MODIFY_EXPR)
+ {
+ ret_var->common.ann = (tree_ann) stmt_ann (ret_stmt);
+ bsi_replace (&bsi, ret_var, true);
+ SSA_NAME_DEF_STMT (TREE_OPERAND (ret_var, 0)) = ret_var;
+ ret_var = TREE_OPERAND (ret_var, 0);
+ ret_stmt = build1 (RETURN_EXPR, TREE_TYPE (ret_stmt), ret_var);
+ bsi_insert_after (&bsi, ret_stmt, BSI_NEW_STMT);
+ }
+
+ if (m)
+ {
+ stmt = build (MODIFY_EXPR, ret_type, NULL_TREE,
+ build (MULT_EXPR, ret_type, m_acc, ret_var));
+
+ tmp = create_tmp_var (ret_type, "acc_tmp");
+ add_referenced_tmp_var (tmp);
+
+ var = make_ssa_name (tmp, stmt);
+ TREE_OPERAND (stmt, 0) = var;
+ bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
+ }
+ else
+ var = ret_var;
+
+ if (a)
+ {
+ stmt = build (MODIFY_EXPR, ret_type, NULL_TREE,
+ build (PLUS_EXPR, ret_type, a_acc, var));
+
+ tmp = create_tmp_var (ret_type, "acc_tmp");
+ add_referenced_tmp_var (tmp);
+
+ var = make_ssa_name (tmp, stmt);
+ TREE_OPERAND (stmt, 0) = var;
+ bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
+ }
+
+ TREE_OPERAND (ret_stmt, 0) = var;
+ modify_stmt (ret_stmt);
+}
+
+/* Eliminates tail call described by T. TMP_VARS is a list of
+ temporary variables used to copy the function arguments. */
+
+static void
+eliminate_tail_call (struct tailcall *t)
+{
+ tree param, stmt, args, rslt, call;
+ basic_block bb, first;
+ edge e;
+ tree phi;
+ stmt_ann_t ann;
+ vdef_optype vdefs;
+ unsigned i;
+
+ stmt = bsi_stmt (t->call_bsi);
+ get_stmt_operands (stmt);
+ ann = stmt_ann (stmt);
+ bb = t->call_block;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Eliminated tail recursion in bb %d : ",
+ bb->index);
+ print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ fprintf (dump_file, "\n");
+ }
+
+ if (TREE_CODE (stmt) == MODIFY_EXPR)
+ stmt = TREE_OPERAND (stmt, 1);
+
+ first = ENTRY_BLOCK_PTR->succ->dest;
+
+ /* Replace the call by a jump to the start of function. */
+ e = redirect_edge_and_branch (t->call_block->succ, first);
+ if (!e)
+ abort ();
+ PENDING_STMT (e) = NULL_TREE;
+
+ /* Add phi node entries for arguments. Not every PHI node corresponds to
+ a function argument (there may be PHI nodes for virtual definitions of the
+ eliminated calls), so we search for a PHI corresponding to each argument
+ rather than searching for which argument a PHI node corresponds to. */
+
+ for (param = DECL_ARGUMENTS (current_function_decl),
+ args = TREE_OPERAND (stmt, 1);
+ param;
+ param = TREE_CHAIN (param),
+ args = TREE_CHAIN (args))
+ {
+
+ for (phi = phi_nodes (first); phi; phi = TREE_CHAIN (phi))
+ if (param == SSA_NAME_VAR (PHI_RESULT (phi)))
+ break;
+
+ /* The phi node indeed does not have to be there, in case the operand is
+ invariant in the function. */
+ if (!phi)
+ continue;
+
+ add_phi_arg (&phi, TREE_VALUE (args), e);
+ }
+
+ /* Add phi nodes for the call clobbered variables. */
+ vdefs = VDEF_OPS (ann);
+ for (i = 0; i < NUM_VDEFS (vdefs); i++)
+ {
+ param = SSA_NAME_VAR (VDEF_RESULT (vdefs, i));
+ for (phi = phi_nodes (first); phi; phi = TREE_CHAIN (phi))
+ if (param == SSA_NAME_VAR (PHI_RESULT (phi)))
+ break;
+
+ if (!phi)
+ {
+ tree name = var_ann (param)->default_def;
+ tree new_name = make_ssa_name (param, SSA_NAME_DEF_STMT (name));
+
+ var_ann (param)->default_def = new_name;
+ phi = create_phi_node (name, first);
+ SSA_NAME_DEF_STMT (name) = phi;
+ add_phi_arg (&phi, new_name, ENTRY_BLOCK_PTR->succ);
+
+ /* For all calls the same set of variables should be clobbered. This
+ means that there always should be the appropriate phi node except
+ for the first time we eliminate the call. */
+ if (first->pred->pred_next->pred_next)
+ abort ();
+ }
+
+ add_phi_arg (&phi, VDEF_OP (vdefs, i), e);
+ }
+
+ /* Update the values of accumulators. */
+ adjust_accumulator_values (t->call_bsi, t->mult, t->add, e);
+
+ call = bsi_stmt (t->call_bsi);
+ if (TREE_CODE (call) == MODIFY_EXPR)
+ {
+ rslt = TREE_OPERAND (call, 0);
+
+ /* Result of the call will no longer be defined. So adjust the
+ SSA_NAME_DEF_STMT accordingly. */
+ SSA_NAME_DEF_STMT (rslt) = build_empty_stmt ();
+ }
+
+ bsi_remove (&t->call_bsi);
+}
+
+/* Optimizes the tailcall described by T. If OPT_TAILCALLS is true, also
+ mark the tailcalls for the sibcall optimization. */
+
+static bool
+optimize_tail_call (struct tailcall *t, bool opt_tailcalls)
+{
+ if (t->tail_recursion)
+ {
+ eliminate_tail_call (t);
+ return true;
+ }
+
+ if (opt_tailcalls)
+ {
+ tree stmt = bsi_stmt (t->call_bsi);
+
+ if (TREE_CODE (stmt) == MODIFY_EXPR)
+ stmt = TREE_OPERAND (stmt, 1);
+ if (TREE_CODE (stmt) != CALL_EXPR)
+ abort ();
+ CALL_EXPR_TAILCALL (stmt) = 1;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Found tail call ");
+ print_generic_expr (dump_file, stmt, dump_flags);
+ fprintf (dump_file, " in bb %i\n", t->call_block->index);
+ }
+ }
+
+ return false;
+}
+
+/* Optimizes tail calls in the function, turning the tail recursion
+ into iteration. */
+
+static void
+tree_optimize_tail_calls_1 (bool opt_tailcalls)
+{
+ edge e;
+ bool phis_constructed = false;
+ struct tailcall *tailcalls = NULL, *act, *next;
+ bool changed = false;
+ basic_block first = ENTRY_BLOCK_PTR->succ->dest;
+ tree stmt, param, ret_type, tmp, phi;
+
+ if (!suitable_for_tail_opt_p ())
+ return;
+ if (opt_tailcalls)
+ opt_tailcalls = suitable_for_tail_call_opt_p ();
+
+ for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
+ {
+ /* Only traverse the normal exits, i.e. those that end with return
+ statement. */
+ stmt = last_stmt (e->src);
+
+ if (stmt
+ && TREE_CODE (stmt) == RETURN_EXPR)
+ find_tail_calls (e->src, &tailcalls);
+ }
+
+ /* Construct the phi nodes and accumulators if necessary. */
+ a_acc = m_acc = NULL_TREE;
+ for (act = tailcalls; act; act = act->next)
+ {
+ if (!act->tail_recursion)
+ continue;
+
+ if (!phis_constructed)
+ {
+ /* Ensure that there is only one predecessor of the block. */
+ if (first->pred->pred_next)
+ first = split_edge (ENTRY_BLOCK_PTR->succ);
+
+ /* Copy the args if needed. */
+ for (param = DECL_ARGUMENTS (current_function_decl);
+ param;
+ param = TREE_CHAIN (param))
+ if (var_ann (param)
+ /* Also parameters that are only defined but never used need not
+ be copied. */
+ && (var_ann (param)->default_def
+ && TREE_CODE (var_ann (param)->default_def) == SSA_NAME))
+ {
+ tree name = var_ann (param)->default_def;
+ tree new_name = make_ssa_name (param, SSA_NAME_DEF_STMT (name));
+ tree phi;
+
+ var_ann (param)->default_def = new_name;
+ phi = create_phi_node (name, first);
+ SSA_NAME_DEF_STMT (name) = phi;
+ add_phi_arg (&phi, new_name, first->pred);
+ }
+ phis_constructed = true;
+ }
+
+ if (act->add && !a_acc)
+ {
+ ret_type = TREE_TYPE (DECL_RESULT (current_function_decl));
+
+ tmp = create_tmp_var (ret_type, "add_acc");
+ add_referenced_tmp_var (tmp);
+
+ phi = create_phi_node (tmp, first);
+ add_phi_arg (&phi, convert (ret_type, integer_zero_node),
+ first->pred);
+ a_acc = PHI_RESULT (phi);
+ }
+
+ if (act->mult && !m_acc)
+ {
+ ret_type = TREE_TYPE (DECL_RESULT (current_function_decl));
+
+ tmp = create_tmp_var (ret_type, "mult_acc");
+ add_referenced_tmp_var (tmp);
+
+ phi = create_phi_node (tmp, first);
+ add_phi_arg (&phi, convert (ret_type, integer_one_node),
+ first->pred);
+ m_acc = PHI_RESULT (phi);
+ }
+ }
+
+ for (; tailcalls; tailcalls = next)
+ {
+ next = tailcalls->next;
+ changed |= optimize_tail_call (tailcalls, opt_tailcalls);
+ free (tailcalls);
+ }
+
+ if (a_acc || m_acc)
+ {
+ /* Modify the remaining return statements. */
+ for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
+ {
+ stmt = last_stmt (e->src);
+
+ if (stmt
+ && TREE_CODE (stmt) == RETURN_EXPR)
+ adjust_return_value (e->src, m_acc, a_acc);
+ }
+ }
+
+ if (changed)
+ {
+ free_dominance_info (CDI_DOMINATORS);
+ cleanup_tree_cfg ();
+ }
+}
+
+static void
+execute_tail_recursion (void)
+{
+ tree_optimize_tail_calls_1 (false);
+}
+
+static bool
+gate_tail_calls (void)
+{
+ return flag_optimize_sibling_calls != 0;
+}
+
+static void
+execute_tail_calls (void)
+{
+ tree_optimize_tail_calls_1 (true);
+}
+
+struct tree_opt_pass pass_tail_recursion =
+{
+ "tailr", /* name */
+ NULL, /* gate */
+ execute_tail_recursion, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ PROP_cfg | PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */
+};
+
+struct tree_opt_pass pass_tail_calls =
+{
+ "tailc", /* name */
+ gate_tail_calls, /* gate */
+ execute_tail_calls, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ PROP_cfg | PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */
+};
diff --git a/gcc/tree.c b/gcc/tree.c
index 0b301e2bb38..791cc221349 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -45,6 +45,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "output.h"
#include "target.h"
#include "langhooks.h"
+#include "tree-iterator.h"
+#include "basic-block.h"
+#include "tree-flow.h"
/* obstack.[ch] explicitly declined to prototype this. */
extern int _obstack_allocated_p (struct obstack *h, void *obj);
@@ -68,6 +71,8 @@ static const char * const tree_node_kind_names[] = {
"perm_tree_lists",
"temp_tree_lists",
"vecs",
+ "phi_nodes",
+ "ssa names",
"random kinds",
"lang_decl kinds",
"lang_type kinds"
@@ -150,9 +155,6 @@ tree_size (tree node)
case 't': /* a type node */
return sizeof (struct tree_type);
- case 'b': /* a lexical block node */
- return sizeof (struct tree_block);
-
case 'r': /* a reference */
case 'e': /* an expression */
case 's': /* an expression with side effects */
@@ -186,6 +188,23 @@ tree_size (tree node)
case ERROR_MARK:
case PLACEHOLDER_EXPR: return sizeof (struct tree_common);
+ case PHI_NODE: return (sizeof (struct tree_phi_node)
+ + (PHI_ARG_CAPACITY (node) - 1) *
+ sizeof (struct phi_arg_d));
+
+ case EPHI_NODE: return (sizeof (struct tree_ephi_node)
+ + (EPHI_ARG_CAPACITY (node) - 1) *
+ sizeof (struct ephi_arg_d));
+
+ case SSA_NAME: return sizeof (struct tree_ssa_name);
+ case EUSE_NODE: return sizeof (struct tree_euse_node);
+
+ case EKILL_NODE:
+ case EEXIT_NODE: return sizeof (struct tree_eref_common);
+
+ case STATEMENT_LIST: return sizeof (struct tree_statement_list);
+ case BLOCK: return sizeof (struct tree_block);
+
default:
return lang_hooks.tree_size (code);
}
@@ -212,9 +231,9 @@ make_node_stat (enum tree_code code MEM_STAT_DECL)
#endif
struct tree_common ttmp;
- /* We can't allocate a TREE_VEC without knowing how many elements
- it will have. */
- if (code == TREE_VEC)
+ /* We can't allocate a TREE_VEC, PHI_NODE, EPHI_NODE or STRING_CST
+ without knowing how many elements it will have. */
+ if (code == TREE_VEC || code == PHI_NODE || code == EPHI_NODE)
abort ();
TREE_SET_CODE ((tree)&ttmp, code);
@@ -231,10 +250,6 @@ make_node_stat (enum tree_code code MEM_STAT_DECL)
kind = t_kind;
break;
- case 'b': /* a lexical block */
- kind = b_kind;
- break;
-
case 's': /* an expression with side effects */
kind = s_kind;
break;
@@ -259,6 +274,12 @@ make_node_stat (enum tree_code code MEM_STAT_DECL)
kind = id_kind;
else if (code == TREE_VEC)
kind = vec_kind;
+ else if (code == PHI_NODE)
+ kind = phi_kind;
+ else if (code == SSA_NAME)
+ kind = ssa_name_kind;
+ else if (code == BLOCK)
+ kind = b_kind;
else
kind = x_kind;
break;
@@ -311,6 +332,7 @@ make_node_stat (enum tree_code code MEM_STAT_DECL)
case 'c':
TREE_CONSTANT (t) = 1;
+ TREE_INVARIANT (t) = 1;
break;
case 'e':
@@ -348,12 +370,19 @@ copy_node_stat (tree node MEM_STAT_DECL)
enum tree_code code = TREE_CODE (node);
size_t length;
+#ifdef ENABLE_CHECKING
+ if (code == STATEMENT_LIST)
+ abort ();
+#endif
+
length = tree_size (node);
t = ggc_alloc_zone_stat (length, tree_zone PASS_MEM_STAT);
memcpy (t, node, length);
TREE_CHAIN (t) = 0;
TREE_ASM_WRITTEN (t) = 0;
+ TREE_VISITED (t) = 0;
+ t->common.ann = 0;
if (TREE_CODE_CLASS (code) == 'd')
DECL_UID (t) = next_decl_uid++;
@@ -456,9 +485,8 @@ build_constructor (tree type, tree vals)
TREE_SIDE_EFFECTS (c) = TREE_SIDE_EFFECTS (vals);
TREE_READONLY (c) = TREE_READONLY (vals);
TREE_CONSTANT (c) = TREE_CONSTANT (vals);
+ TREE_INVARIANT (c) = TREE_INVARIANT (vals);
}
- else
- TREE_CONSTANT (c) = 0; /* safe side */
return c;
}
@@ -1073,44 +1101,6 @@ tree_cons_stat (tree purpose, tree value, tree chain MEM_STAT_DECL)
return node;
}
-/* Return the first expression in a sequence of COMPOUND_EXPRs. */
-
-tree
-expr_first (tree expr)
-{
- if (expr == NULL_TREE)
- return expr;
- while (TREE_CODE (expr) == COMPOUND_EXPR)
- expr = TREE_OPERAND (expr, 0);
- return expr;
-}
-
-/* Return the last expression in a sequence of COMPOUND_EXPRs. */
-
-tree
-expr_last (tree expr)
-{
- if (expr == NULL_TREE)
- return expr;
- while (TREE_CODE (expr) == COMPOUND_EXPR)
- expr = TREE_OPERAND (expr, 1);
- return expr;
-}
-
-/* Return the number of subexpressions in a sequence of COMPOUND_EXPRs. */
-
-int
-expr_length (tree expr)
-{
- int len = 0;
-
- if (expr == NULL_TREE)
- return 0;
- for (; TREE_CODE (expr) == COMPOUND_EXPR; expr = TREE_OPERAND (expr, 1))
- len += expr_length (TREE_OPERAND (expr, 0));
- ++len;
- return len;
-}
/* Return the size nominally occupied by an object of type TYPE
when it resides in memory. The value is measured in units of bytes,
@@ -1299,11 +1289,18 @@ staticp (tree arg)
case STRING_CST:
return 1;
+ case COMPONENT_REF:
+ /* If the thing being referenced is not a field, then it is
+ something language specific. */
+ if (TREE_CODE (TREE_OPERAND (arg, 1)) != FIELD_DECL)
+ return (*lang_hooks.staticp) (arg);
+
/* If we are referencing a bitfield, we can't evaluate an
ADDR_EXPR at compile time and so it isn't a constant. */
- case COMPONENT_REF:
- return (! DECL_BIT_FIELD (TREE_OPERAND (arg, 1))
- && staticp (TREE_OPERAND (arg, 0)));
+ if (DECL_BIT_FIELD (TREE_OPERAND (arg, 1)))
+ return 0;
+
+ return staticp (TREE_OPERAND (arg, 0));
case BIT_FIELD_REF:
return 0;
@@ -1321,6 +1318,8 @@ staticp (tree arg)
if (TREE_CODE (TYPE_SIZE (TREE_TYPE (arg))) == INTEGER_CST
&& TREE_CODE (TREE_OPERAND (arg, 1)) == INTEGER_CST)
return staticp (TREE_OPERAND (arg, 0));
+ else
+ return 0;
default:
if ((unsigned int) TREE_CODE (arg)
@@ -1365,7 +1364,8 @@ save_expr (tree expr)
Since it is no problem to reevaluate literals, we just return the
literal node. */
inner = skip_simple_arithmetic (t);
- if (TREE_CONSTANT (inner)
+
+ if (TREE_INVARIANT (inner)
|| (TREE_READONLY (inner) && ! TREE_SIDE_EFFECTS (inner))
|| TREE_CODE (inner) == SAVE_EXPR
|| TREE_CODE (inner) == ERROR_MARK)
@@ -1390,6 +1390,7 @@ save_expr (tree expr)
eliminated as dead. */
TREE_SIDE_EFFECTS (t) = 1;
TREE_READONLY (t) = 1;
+ TREE_INVARIANT (t) = 1;
return t;
}
@@ -1417,9 +1418,9 @@ skip_simple_arithmetic (tree expr)
inner = TREE_OPERAND (inner, 0);
else if (TREE_CODE_CLASS (TREE_CODE (inner)) == '2')
{
- if (TREE_CONSTANT (TREE_OPERAND (inner, 1)))
+ if (TREE_INVARIANT (TREE_OPERAND (inner, 1)))
inner = TREE_OPERAND (inner, 0);
- else if (TREE_CONSTANT (TREE_OPERAND (inner, 0)))
+ else if (TREE_INVARIANT (TREE_OPERAND (inner, 0)))
inner = TREE_OPERAND (inner, 1);
else
break;
@@ -1489,7 +1490,6 @@ tree_node_structure (tree t)
{
case 'd': return TS_DECL;
case 't': return TS_TYPE;
- case 'b': return TS_BLOCK;
case 'r': case '<': case '1': case '2': case 'e': case 's':
return TS_EXP;
default: /* 'c' and 'x' */
@@ -1508,7 +1508,15 @@ tree_node_structure (tree t)
case IDENTIFIER_NODE: return TS_IDENTIFIER;
case TREE_LIST: return TS_LIST;
case TREE_VEC: return TS_VEC;
+ case PHI_NODE: return TS_PHI_NODE;
+ case EPHI_NODE: return TS_EPHI_NODE;
+ case EUSE_NODE: return TS_EUSE_NODE;
+ case EKILL_NODE: return TS_EREF_NODE;
+ case EEXIT_NODE: return TS_EREF_NODE;
+ case SSA_NAME: return TS_SSA_NAME;
case PLACEHOLDER_EXPR: return TS_COMMON;
+ case STATEMENT_LIST: return TS_STATEMENT_LIST;
+ case BLOCK: return TS_BLOCK;
default:
abort ();
@@ -1551,57 +1559,6 @@ unsave_expr_1 (tree expr)
}
}
-/* Default lang hook for "unsave_expr_now". */
-
-tree
-lhd_unsave_expr_now (tree expr)
-{
- enum tree_code code;
-
- /* There's nothing to do for NULL_TREE. */
- if (expr == 0)
- return expr;
-
- unsave_expr_1 (expr);
-
- code = TREE_CODE (expr);
- switch (TREE_CODE_CLASS (code))
- {
- case 'c': /* a constant */
- case 't': /* a type node */
- case 'd': /* A decl node */
- case 'b': /* A block node */
- break;
-
- case 'x': /* miscellaneous: e.g., identifier, TREE_LIST or ERROR_MARK. */
- if (code == TREE_LIST)
- {
- lhd_unsave_expr_now (TREE_VALUE (expr));
- lhd_unsave_expr_now (TREE_CHAIN (expr));
- }
- break;
-
- case 'e': /* an expression */
- case 'r': /* a reference */
- case 's': /* an expression with side effects */
- case '<': /* a comparison expression */
- case '2': /* a binary arithmetic expression */
- case '1': /* a unary arithmetic expression */
- {
- int i;
-
- for (i = first_rtl_op (code) - 1; i >= 0; i--)
- lhd_unsave_expr_now (TREE_OPERAND (expr, i));
- }
- break;
-
- default:
- abort ();
- }
-
- return expr;
-}
-
/* Return 0 if it is safe to evaluate EXPR multiple times,
return 1 if it is safe if EXPR is unsaved afterward, or
return 2 if it is completely unsafe.
@@ -1639,6 +1596,14 @@ unsafe_for_reeval (tree expr)
case RTL_EXPR:
return 2;
+ /* A label can only be emitted once. */
+ case LABEL_EXPR:
+ return 1;
+
+ case BIND_EXPR:
+ unsafeness = 1;
+ break;
+
case TREE_LIST:
for (exp = expr; exp != 0; exp = TREE_CHAIN (exp))
{
@@ -1677,7 +1642,6 @@ unsafe_for_reeval (tree expr)
case 't': /* a type node */
case 'x': /* something random, like an identifier or an ERROR_MARK. */
case 'd': /* A decl node */
- case 'b': /* A block node */
return 0;
case 'e': /* an expression */
@@ -2053,7 +2017,7 @@ tree
substitute_placeholder_in_expr (tree exp, tree obj)
{
enum tree_code code = TREE_CODE (exp);
- tree op0, op1, op2;
+ tree op0, op1, op2, op3;
/* If this is a PLACEHOLDER_EXPR, see if we find a corresponding type
in the chain of OBJ. */
@@ -2109,7 +2073,6 @@ substitute_placeholder_in_expr (tree exp, tree obj)
{
case 'c':
case 'd':
- case 'b':
return exp;
case 'x':
@@ -2151,6 +2114,19 @@ substitute_placeholder_in_expr (tree exp, tree obj)
else
return fold (build3 (code, TREE_TYPE (exp), op0, op1, op2));
+ case 4:
+ op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
+ op1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 1), obj);
+ op2 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 2), obj);
+ op3 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 3), obj);
+
+ if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
+ && op2 == TREE_OPERAND (exp, 2)
+ && op3 == TREE_OPERAND (exp, 3))
+ return exp;
+ else
+ return fold (build4 (code, TREE_TYPE (exp), op0, op1, op2, op3));
+
default:
abort ();
}
@@ -2277,7 +2253,7 @@ stabilize_reference_1 (tree e)
ignore things that are actual constant or that already have been
handled by this function. */
- if (TREE_CONSTANT (e) || code == SAVE_EXPR)
+ if (TREE_INVARIANT (e))
return e;
switch (TREE_CODE_CLASS (code))
@@ -2285,7 +2261,6 @@ stabilize_reference_1 (tree e)
case 'x':
case 't':
case 'd':
- case 'b':
case '<':
case 's':
case 'e':
@@ -2330,12 +2305,50 @@ stabilize_reference_1 (tree e)
TREE_READONLY (result) = TREE_READONLY (e);
TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (e);
TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e);
+ TREE_INVARIANT (result) = 1;
return result;
}
/* Low-level constructors for expressions. */
+/* A helper function for build1 and constant folders.
+ Set TREE_CONSTANT and TREE_INVARIANT for an ADDR_EXPR. */
+
+void
+recompute_tree_invarant_for_addr_expr (tree t)
+{
+ tree node = TREE_OPERAND (t, 0);
+ bool tc = false, ti = false;
+
+ /* Addresses of constants and static variables are constant;
+ all other decl addresses are invariant. */
+ if (staticp (node))
+ tc = ti = true;
+ else
+ {
+ /* Step past constant offsets. */
+ while (1)
+ {
+ if (TREE_CODE (node) == COMPONENT_REF
+ && TREE_CODE (TREE_OPERAND (node, 1)) == FIELD_DECL
+ && ! DECL_BIT_FIELD (TREE_OPERAND (node, 1)))
+ ;
+ else if (TREE_CODE (node) == ARRAY_REF
+ && TREE_CONSTANT (TREE_OPERAND (node, 1)))
+ ;
+ else
+ break;
+ node = TREE_OPERAND (node, 0);
+ }
+ if (DECL_P (node))
+ ti = true;
+ }
+
+ TREE_CONSTANT (t) = tc;
+ TREE_INVARIANT (t) = ti;
+}
+
/* Build an expression of code CODE, data type TYPE, and operands as
specified. Expressions and reference nodes can be created this way.
Constants, decls, types and misc nodes cannot be.
@@ -2400,8 +2413,10 @@ build1_stat (enum tree_code code, tree type, tree node MEM_STAT_DECL)
TREE_SET_CODE (t, code);
TREE_TYPE (t) = type;
+ SET_EXPR_LOCUS (t, NULL);
TREE_COMPLEXITY (t) = 0;
TREE_OPERAND (t, 0) = node;
+ TREE_BLOCK (t) = NULL_TREE;
if (node && !TYPE_P (node) && first_rtl_op (code) != 0)
{
TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (node);
@@ -2435,6 +2450,8 @@ build1_stat (enum tree_code code, tree type, tree node MEM_STAT_DECL)
case ADDR_EXPR:
if (node)
{
+ recompute_tree_invarant_for_addr_expr (t);
+
/* The address of a volatile decl or reference does not have
side-effects. But be careful not to ignore side-effects from
other sources deeper in the expression--if node is a _REF and
@@ -2459,6 +2476,8 @@ build1_stat (enum tree_code code, tree type, tree node MEM_STAT_DECL)
if (TREE_CODE_CLASS (code) == '1' && node && !TYPE_P (node)
&& TREE_CONSTANT (node))
TREE_CONSTANT (t) = 1;
+ if (TREE_CODE_CLASS (code) == '1' && node && TREE_INVARIANT (node))
+ TREE_INVARIANT (t) = 1;
break;
}
@@ -2476,13 +2495,15 @@ build1_stat (enum tree_code code, tree type, tree node MEM_STAT_DECL)
read_only = 0; \
if (!TREE_CONSTANT (arg##N)) \
constant = 0; \
+ if (!TREE_INVARIANT (arg##N)) \
+ invariant = 0; \
} \
} while (0)
tree
build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL)
{
- bool constant, read_only, side_effects;
+ bool constant, read_only, side_effects, invariant;
tree t;
int fro;
@@ -2506,32 +2527,14 @@ build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL)
|| TREE_CODE_CLASS (code) == '2');
read_only = 1;
side_effects = TREE_SIDE_EFFECTS (t);
+ invariant = constant;
PROCESS_ARG(0);
PROCESS_ARG(1);
- if (code == CALL_EXPR && !side_effects)
- {
- tree node;
- int i;
-
- /* Calls have side-effects, except those to const or
- pure functions. */
- i = call_expr_flags (t);
- if (!(i & (ECF_CONST | ECF_PURE)))
- side_effects = 1;
-
- /* And even those have side-effects if their arguments do. */
- else for (node = TREE_OPERAND (t, 1); node; node = TREE_CHAIN (node))
- if (TREE_SIDE_EFFECTS (TREE_VALUE (node)))
- {
- side_effects = 1;
- break;
- }
- }
-
TREE_READONLY (t) = read_only;
TREE_CONSTANT (t) = constant;
+ TREE_INVARIANT (t) = invariant;
TREE_SIDE_EFFECTS (t) = side_effects;
return t;
@@ -2541,20 +2544,10 @@ tree
build3_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
tree arg2 MEM_STAT_DECL)
{
- bool constant, read_only, side_effects;
+ bool constant, read_only, side_effects, invariant;
tree t;
int fro;
- /* ??? Quite a lot of existing code passes one too many arguments to
- CALL_EXPR. Not going to fix them, because CALL_EXPR is about to
- grow a new argument, so it would just mean changing them back. */
- if (code == CALL_EXPR)
- {
- if (arg2 != NULL_TREE)
- abort ();
- return build2 (code, tt, arg0, arg1);
- }
-
#ifdef ENABLE_CHECKING
if (TREE_CODE_LENGTH (code) != 3)
abort ();
@@ -2571,6 +2564,26 @@ build3_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
PROCESS_ARG(1);
PROCESS_ARG(2);
+ if (code == CALL_EXPR && !side_effects)
+ {
+ tree node;
+ int i;
+
+ /* Calls have side-effects, except those to const or
+ pure functions. */
+ i = call_expr_flags (t);
+ if (!(i & (ECF_CONST | ECF_PURE)))
+ side_effects = 1;
+
+ /* And even those have side-effects if their arguments do. */
+ else for (node = arg1; node; node = TREE_CHAIN (node))
+ if (TREE_SIDE_EFFECTS (TREE_VALUE (node)))
+ {
+ side_effects = 1;
+ break;
+ }
+ }
+
TREE_SIDE_EFFECTS (t) = side_effects;
return t;
@@ -2580,7 +2593,7 @@ tree
build4_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
tree arg2, tree arg3 MEM_STAT_DECL)
{
- bool constant, read_only, side_effects;
+ bool constant, read_only, side_effects, invariant;
tree t;
int fro;
@@ -2722,35 +2735,49 @@ build_block (tree vars, tree tags ATTRIBUTE_UNUSED, tree subblocks,
return block;
}
-/* EXPR_WITH_FILE_LOCATION are used to keep track of the exact
- location where an expression or an identifier were encountered. It
- is necessary for languages where the frontend parser will handle
- recursively more than one file (Java is one of them). */
+static GTY(()) tree last_annotated_node;
-tree
-build_expr_wfl (tree node, const char *file, int line, int col)
-{
- static const char *last_file = 0;
- static tree last_filenode = NULL_TREE;
- tree wfl = make_node (EXPR_WITH_FILE_LOCATION);
+/* Record the exact location where an expression or an identifier were
+ encountered. */
- EXPR_WFL_NODE (wfl) = node;
- EXPR_WFL_SET_LINECOL (wfl, line, col);
- if (file != last_file)
+void
+annotate_with_file_line (tree node, const char *file, int line)
+{
+ /* Roughly one percent of the calls to this function are to annotate
+ a node with the same information already attached to that node!
+ Just return instead of wasting memory. */
+ if (EXPR_LOCUS (node)
+ && (EXPR_FILENAME (node) == file
+ || ! strcmp (EXPR_FILENAME (node), file))
+ && EXPR_LINENO (node) == line)
{
- last_file = file;
- last_filenode = file ? get_identifier (file) : NULL_TREE;
+ last_annotated_node = node;
+ return;
}
- EXPR_WFL_FILENAME_NODE (wfl) = last_filenode;
-
- if (node && !TYPE_P (node))
+ /* In heavily macroized code (such as GCC itself) this single
+ entry cache can reduce the number of allocations by more
+ than half. */
+ if (last_annotated_node
+ && EXPR_LOCUS (last_annotated_node)
+ && (EXPR_FILENAME (last_annotated_node) == file
+ || ! strcmp (EXPR_FILENAME (last_annotated_node), file))
+ && EXPR_LINENO (last_annotated_node) == line)
{
- TREE_SIDE_EFFECTS (wfl) = TREE_SIDE_EFFECTS (node);
- TREE_TYPE (wfl) = TREE_TYPE (node);
+ SET_EXPR_LOCUS (node, EXPR_LOCUS (last_annotated_node));
+ return;
}
- return wfl;
+ SET_EXPR_LOCUS (node, ggc_alloc (sizeof (location_t)));
+ EXPR_LINENO (node) = line;
+ EXPR_FILENAME (node) = file;
+ last_annotated_node = node;
+}
+
+void
+annotate_with_locus (tree node, location_t locus)
+{
+ annotate_with_file_line (node, locus.file, locus.line);
}
/* Return a declaration like DDECL except that its DECL_ATTRIBUTES
@@ -3642,10 +3669,8 @@ simple_cst_equal (tree t1, tree t2)
TREE_STRING_LENGTH (t1)));
case CONSTRUCTOR:
- if (CONSTRUCTOR_ELTS (t1) == CONSTRUCTOR_ELTS (t2))
- return 1;
- else
- abort ();
+ return simple_cst_list_equal (CONSTRUCTOR_ELTS (t1),
+ CONSTRUCTOR_ELTS (t2));
case SAVE_EXPR:
return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
@@ -3760,10 +3785,7 @@ associative_tree_code (enum tree_code code)
case BIT_AND_EXPR:
case BIT_XOR_EXPR:
case PLUS_EXPR:
- case MINUS_EXPR:
case MULT_EXPR:
- case LSHIFT_EXPR:
- case RSHIFT_EXPR:
case MIN_EXPR:
case MAX_EXPR:
return true;
@@ -3851,9 +3873,17 @@ iterative_hash_expr (tree t, hashval_t val)
{
val = iterative_hash_object (code, val);
- if (code == NOP_EXPR || code == CONVERT_EXPR
+ /* Don't hash the type, that can lead to having nodes which
+ compare equal according to operand_equal_p, but which
+ have different hash codes. */
+ if (code == NOP_EXPR
+ || code == CONVERT_EXPR
|| code == NON_LVALUE_EXPR)
- val = iterative_hash_object (TREE_TYPE (t), val);
+ {
+ /* Make sure to include signness in the hash computation. */
+ val += TYPE_UNSIGNED (TREE_TYPE (t));
+ val = iterative_hash_expr (TREE_OPERAND (t, 0), val);
+ }
if (commutative_tree_code (code))
{
@@ -3882,6 +3912,11 @@ iterative_hash_expr (tree t, hashval_t val)
for (; t; t = TREE_CHAIN (t))
val = iterative_hash_expr (TREE_VALUE (t), val);
}
+ else if (code == SSA_NAME)
+ {
+ val = iterative_hash_object (SSA_NAME_VERSION (t), val);
+ val = iterative_hash_expr (SSA_NAME_VAR (t), val);
+ }
else
abort ();
@@ -4842,6 +4877,8 @@ dump_tree_statistics (void)
fprintf (stderr, "---------------------------------------\n");
fprintf (stderr, "%-20s %7d %10d\n", "Total", total_nodes, total_bytes);
fprintf (stderr, "---------------------------------------\n");
+ ssanames_print_statistics ();
+ phinodes_print_statistics ();
#else
fprintf (stderr, "(No per-node statistics)\n");
#endif
@@ -5142,6 +5179,30 @@ tree_vec_elt_check_failed (int idx, int len, const char *file, int line,
idx + 1, len, function, trim_filename (file), line);
}
+/* Similar to above, except that the check is for the bounds of a EPHI_NODE's
+ (dynamically sized) vector. */
+
+void
+ephi_node_elt_check_failed (int idx, int len, const char *file, int line,
+ const char *function)
+{
+ internal_error
+ ("tree check: accessed elt %d of ephi_node with %d elts in %s, at %s:%d",
+ idx + 1, len, function, trim_filename (file), line);
+}
+
+/* Similar to above, except that the check is for the bounds of a PHI_NODE's
+ (dynamically sized) vector. */
+
+void
+phi_node_elt_check_failed (int idx, int len, const char *file, int line,
+ const char *function)
+{
+ internal_error
+ ("tree check: accessed elt %d of phi_node with %d elts in %s, at %s:%d",
+ idx + 1, len, function, trim_filename (file), line);
+}
+
/* Similar to above, except that the check is for the bounds of the operand
vector of an expression node. */
@@ -5182,6 +5243,27 @@ finish_vector_type (tree t)
}
}
+static tree
+make_or_reuse_type (unsigned size, int unsignedp)
+{
+ if (size == INT_TYPE_SIZE)
+ return unsignedp ? unsigned_type_node : integer_type_node;
+ if (size == CHAR_TYPE_SIZE)
+ return unsignedp ? unsigned_char_type_node : signed_char_type_node;
+ if (size == SHORT_TYPE_SIZE)
+ return unsignedp ? short_unsigned_type_node : short_integer_type_node;
+ if (size == LONG_TYPE_SIZE)
+ return unsignedp ? long_unsigned_type_node : long_integer_type_node;
+ if (size == LONG_LONG_TYPE_SIZE)
+ return (unsignedp ? long_long_unsigned_type_node
+ : long_long_integer_type_node);
+
+ if (unsignedp)
+ return make_unsigned_type (size);
+ else
+ return make_signed_type (size);
+}
+
/* Create nodes for all integer types (and error_mark_node) using the sizes
of C datatypes. The caller should call set_sizetype soon after calling
this function to select one of the types as sizetype. */
@@ -5224,17 +5306,19 @@ build_common_tree_nodes (int signed_char)
TREE_TYPE (TYPE_MAX_VALUE (boolean_type_node)) = boolean_type_node;
TYPE_PRECISION (boolean_type_node) = 1;
- intQI_type_node = make_signed_type (GET_MODE_BITSIZE (QImode));
- intHI_type_node = make_signed_type (GET_MODE_BITSIZE (HImode));
- intSI_type_node = make_signed_type (GET_MODE_BITSIZE (SImode));
- intDI_type_node = make_signed_type (GET_MODE_BITSIZE (DImode));
- intTI_type_node = make_signed_type (GET_MODE_BITSIZE (TImode));
-
- unsigned_intQI_type_node = make_unsigned_type (GET_MODE_BITSIZE (QImode));
- unsigned_intHI_type_node = make_unsigned_type (GET_MODE_BITSIZE (HImode));
- unsigned_intSI_type_node = make_unsigned_type (GET_MODE_BITSIZE (SImode));
- unsigned_intDI_type_node = make_unsigned_type (GET_MODE_BITSIZE (DImode));
- unsigned_intTI_type_node = make_unsigned_type (GET_MODE_BITSIZE (TImode));
+ /* Fill in the rest of the sized types. Reuse existing type nodes
+ when possible. */
+ intQI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (QImode), 0);
+ intHI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (HImode), 0);
+ intSI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (SImode), 0);
+ intDI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (DImode), 0);
+ intTI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (TImode), 0);
+
+ unsigned_intQI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (QImode), 1);
+ unsigned_intHI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (HImode), 1);
+ unsigned_intSI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (SImode), 1);
+ unsigned_intDI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (DImode), 1);
+ unsigned_intTI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (TImode), 1);
access_public_node = get_identifier ("public");
access_protected_node = get_identifier ("protected");
@@ -5411,44 +5495,94 @@ build_vector_type (tree innertype, int nunits)
bool
initializer_zerop (tree init)
{
+ tree elt;
+
STRIP_NOPS (init);
switch (TREE_CODE (init))
{
case INTEGER_CST:
return integer_zerop (init);
+
case REAL_CST:
+ /* ??? Note that this is not correct for C4X float formats. There,
+ a bit pattern of all zeros is 1.0; 0.0 is encoded with the most
+ negative exponent. */
return real_zerop (init)
&& ! REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (init));
+
case COMPLEX_CST:
return integer_zerop (init)
|| (real_zerop (init)
&& ! REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (TREE_REALPART (init)))
&& ! REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (TREE_IMAGPART (init))));
- case CONSTRUCTOR:
- {
- /* Set is empty if it has no elements. */
- if ((TREE_CODE (TREE_TYPE (init)) == SET_TYPE)
- && CONSTRUCTOR_ELTS (init))
+
+ case VECTOR_CST:
+ for (elt = TREE_VECTOR_CST_ELTS (init); elt; elt = TREE_CHAIN (elt))
+ if (!initializer_zerop (TREE_VALUE (elt)))
return false;
+ return true;
- if (AGGREGATE_TYPE_P (TREE_TYPE (init)))
- {
- tree aggr_init = CONSTRUCTOR_ELTS (init);
-
- while (aggr_init)
- {
- if (! initializer_zerop (TREE_VALUE (aggr_init)))
- return false;
- aggr_init = TREE_CHAIN (aggr_init);
- }
- return true;
- }
+ case CONSTRUCTOR:
+ elt = CONSTRUCTOR_ELTS (init);
+ if (elt == NULL_TREE)
+ return true;
+
+ /* A set is empty only if it has no elements. */
+ if (TREE_CODE (TREE_TYPE (init)) == SET_TYPE)
return false;
- }
+
+ for (; elt ; elt = TREE_CHAIN (elt))
+ if (! initializer_zerop (TREE_VALUE (elt)))
+ return false;
+ return true;
+
default:
return false;
}
}
+void
+add_var_to_bind_expr (tree bind_expr, tree var)
+{
+ BIND_EXPR_VARS (bind_expr)
+ = chainon (BIND_EXPR_VARS (bind_expr), var);
+ if (BIND_EXPR_BLOCK (bind_expr))
+ BLOCK_VARS (BIND_EXPR_BLOCK (bind_expr))
+ = BIND_EXPR_VARS (bind_expr);
+}
+
+/* Build an empty statement. */
+
+tree
+build_empty_stmt (void)
+{
+ return build1 (NOP_EXPR, void_type_node, size_zero_node);
+}
+
+bool
+is_essa_node (tree t)
+{
+ if (TREE_CODE (t) == EPHI_NODE || TREE_CODE (t) == EUSE_NODE
+ || TREE_CODE (t) == EEXIT_NODE || TREE_CODE (t) == EKILL_NODE)
+ return true;
+ return false;
+}
+
+
+/* Return true if T (assumed to be a DECL) must be assigned a memory
+ location. */
+
+bool
+needs_to_live_in_memory (tree t)
+{
+ return (DECL_NEEDS_TO_LIVE_IN_MEMORY_INTERNAL (t)
+ || TREE_STATIC (t)
+ || DECL_EXTERNAL (t)
+ || DECL_NONLOCAL (t)
+ || (TREE_CODE (t) == RESULT_DECL
+ && aggregate_value_p (t, current_function_decl))
+ || decl_function_context (t) != current_function_decl);
+}
+
#include "gt-tree.h"
diff --git a/gcc/tree.def b/gcc/tree.def
index c8e5398d575..213367b8dfd 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -24,7 +24,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* The third argument can be:
'x' for an exceptional code (fits no category).
't' for a type object code.
- 'b' for a lexical block.
'c' for codes for constants.
'd' for codes for declarations (also serving as variable refs).
'r' for codes for references to storage.
@@ -86,7 +85,7 @@ DEFTREECODE (TREE_VEC, "tree_vec", 'x', 0)
instance of an inline function).
TREE_ASM_WRITTEN is nonzero if the block was actually referenced
in the generated assembly. */
-DEFTREECODE (BLOCK, "block", 'b', 0)
+DEFTREECODE (BLOCK, "block", 'x', 0)
/* Each data type is represented by a tree node whose code is one of
the following: */
@@ -390,6 +389,12 @@ DEFTREECODE (ARRAY_RANGE_REF, "array_range_ref", 'r', 2)
Operand 2: index into vtable (must be an integer_cst). */
DEFTREECODE (VTABLE_REF, "vtable_ref", 'r', 3)
+/* The exception object from the runtime. */
+DEFTREECODE (EXC_PTR_EXPR, "exc_ptr_expr", 'e', 0)
+
+/* The filter object from the runtime. */
+DEFTREECODE (FILTER_EXPR, "filter_expr", 'e', 0)
+
/* Constructor: return an aggregate value made from specified components.
In C, this is used only for structure and array initializers.
Also used for SET_TYPE in Chill (and potentially Pascal).
@@ -447,10 +452,10 @@ DEFTREECODE (TARGET_EXPR, "target_expr", 'e', 4)
DEFTREECODE (COND_EXPR, "cond_expr", 'e', 3)
/* Declare local variables, including making RTL and allocating space.
- Operand 0 is a chain of VAR_DECL nodes for the variables.
- Operand 1 is the body, the expression to be computed using
+ BIND_EXPR_VARS is a chain of VAR_DECL nodes for the variables.
+ BIND_EXPR_BODY is the body, the expression to be computed using
the variables. The value of operand 1 becomes that of the BIND_EXPR.
- Operand 2 is the BLOCK that corresponds to these bindings
+ BIND_EXPR_BLOCK is the BLOCK that corresponds to these bindings
for debugging purposes. If this BIND_EXPR is actually expanded,
that sets the TREE_USED flag in the BLOCK.
@@ -469,10 +474,16 @@ DEFTREECODE (COND_EXPR, "cond_expr", 'e', 3)
nodes for the function. */
DEFTREECODE (BIND_EXPR, "bind_expr", 'e', 3)
+/* A labeled block. Operand 0 is the label that will be generated to
+ mark the end of the block.
+ Operand 1 is the labeled block body. */
+DEFTREECODE (LABELED_BLOCK_EXPR, "labeled_block_expr", 'e', 2)
+
/* Function call. Operand 0 is the function.
Operand 1 is the argument list, a list of expressions
- made out of a chain of TREE_LIST nodes. */
-DEFTREECODE (CALL_EXPR, "call_expr", 'e', 2)
+ made out of a chain of TREE_LIST nodes.
+ Operand 2 is the static chain argument, or NULL. */
+DEFTREECODE (CALL_EXPR, "call_expr", 'e', 3)
/* Specify a value to compute along with its corresponding cleanup.
Operand 0 argument is an expression whose value needs a cleanup.
@@ -768,21 +779,14 @@ DEFTREECODE (VA_ARG_EXPR, "va_arg_expr", 'e', 1)
/* Evaluate operand 1. If and only if an exception is thrown during
the evaluation of operand 1, evaluate operand 2.
- This differs from WITH_CLEANUP_EXPR, in that operand 2 is never
- evaluated unless an exception is throw. */
+ This differs from TRY_FINALLY_EXPR in that operand 2 is not evaluated
+ on a normal or jump exit, only on an exception. */
DEFTREECODE (TRY_CATCH_EXPR, "try_catch_expr", 'e', 2)
/* Evaluate the first operand.
The second operand is a cleanup expression which is evaluated
on any exit (normal, exception, or jump out) from this expression. */
DEFTREECODE (TRY_FINALLY_EXPR, "try_finally", 'e', 2)
-
-/* Used internally for cleanups in the implementation of TRY_FINALLY_EXPR.
- (Specifically, it is created by expand_expr, not front-ends.)
- Operand 0 is the rtx for the start of the subroutine we need to call.
- Operand 1 is the rtx for a variable in which to store the address
- of where the subroutine should return to. */
-DEFTREECODE (GOTO_SUBROUTINE_EXPR, "goto_subroutine", 'e', 2)
/* These types of expressions have no useful value,
and always have side effects. */
@@ -796,6 +800,13 @@ DEFTREECODE (LABEL_EXPR, "label_expr", 's', 1)
The type should be void and the value should be ignored. */
DEFTREECODE (GOTO_EXPR, "goto_expr", 's', 1)
+/* Used internally for cleanups in the implementation of TRY_FINALLY_EXPR.
+ (Specifically, it is created by expand_expr, not front-ends.)
+ Operand 0 is the rtx for the start of the subroutine we need to call.
+ Operand 1 is the rtx for a variable in which to store the address
+ of where the subroutine should return to. */
+DEFTREECODE (GOTO_SUBROUTINE_EXPR, "goto_subroutine", 's', 2)
+
/* RETURN. Evaluates operand 0, then returns from the current function.
Presumably that operand is an assignment that stores into the
RESULT_DECL that hold the value to be returned.
@@ -812,33 +823,80 @@ DEFTREECODE (EXIT_EXPR, "exit_expr", 's', 1)
The type should be void and the value should be ignored. */
DEFTREECODE (LOOP_EXPR, "loop_expr", 's', 1)
-/* A labeled block. Operand 0 is the label that will be generated to
- mark the end of the block.
- Operand 1 is the labeled block body. */
-DEFTREECODE (LABELED_BLOCK_EXPR, "labeled_block_expr", 'e', 2)
-
/* Exit a labeled block, possibly returning a value. Operand 0 is a
LABELED_BLOCK_EXPR to exit. Operand 1 is the value to return. It
may be left null. */
-DEFTREECODE (EXIT_BLOCK_EXPR, "exit_block_expr", 'e', 2)
-
-/* Annotates a tree node (usually an expression) with source location
- information: a file name (EXPR_WFL_FILENAME); a line number
- (EXPR_WFL_LINENO); and column number (EXPR_WFL_COLNO). It is
- expanded as the contained node (EXPR_WFL_NODE); a line note should
- be emitted first if EXPR_WFL_EMIT_LINE_NOTE.
- The third operand is only used in the Java front-end, and will
- eventually be removed. */
-DEFTREECODE (EXPR_WITH_FILE_LOCATION, "expr_with_file_location", 'e', 3)
+DEFTREECODE (EXIT_BLOCK_EXPR, "exit_block_expr", 's', 2)
/* Switch expression.
- Operand 0 is the expression used to perform the branch,
- Operand 1 contains the case values. The way they're organized is
- front-end implementation defined. */
-DEFTREECODE (SWITCH_EXPR, "switch_expr", 'e', 2)
-/* The exception object from the runtime. */
-DEFTREECODE (EXC_PTR_EXPR, "exc_ptr_expr", 'e', 0)
+ TREE_TYPE is the original type of the condition, before any
+ language required type conversions. It may be NULL, in which case
+ the original type and final types are assumed to be the same.
+
+ Operand 0 is the expression used to perform the branch,
+ Operand 1 is the body of the switch, which probably contains
+ CASE_LABEL_EXPRs. It may also be NULL, in which case operand 2
+ must not be NULL.
+ Operand 2 is either NULL_TREE or a TREE_VEC of the CASE_LABEL_EXPRs
+ of all the cases. */
+DEFTREECODE (SWITCH_EXPR, "switch_expr", 's', 3)
+
+/* Used to represent a case label. The operands are CASE_LOW and
+ CASE_HIGH, respectively. If CASE_LOW is NULL_TREE, the label is a
+ 'default' label. If CASE_HIGH is NULL_TREE, the label is a normal case
+ label. CASE_LABEL is the corresponding LABEL_DECL. */
+DEFTREECODE (CASE_LABEL_EXPR, "case_label_expr", 's', 3)
+
+/* RESX. Resume execution after an exception. Operand 0 is a
+ number indicating the exception region that is being left. */
+DEFTREECODE (RESX_EXPR, "resx_expr", 's', 1)
+
+/* Used to represent an inline assembly statement. ASM_STRING returns a
+ STRING_CST for the instruction (e.g., "mov x, y"). ASM_OUTPUTS,
+ ASM_INPUTS, and ASM_CLOBBERS represent the outputs, inputs, and clobbers
+ for the statement. */
+DEFTREECODE (ASM_EXPR, "asm_expr", 's', 4)
+
+/* Variable references for SSA analysis. New SSA names are created every
+ time a variable is assigned a new value. The SSA builder uses SSA_NAME
+ nodes to implement SSA versioning. */
+DEFTREECODE (SSA_NAME, "ssa_name", 'x', 0)
+
+/* Expression SSA real and phi operand occurrence node. */
+DEFTREECODE (EUSE_NODE, "euse_node", 'x', 0)
+
+/* Expression SSA kill occurrence node. */
+DEFTREECODE (EKILL_NODE, "ekill_node", 'x', 0)
+
+/* Expression SSA expression PHI. Like a regular SSA PHI operator,
+ but for expressions*/
+DEFTREECODE (EPHI_NODE, "ephi_node", 'x', 0)
+
+/* Expression SSA exit occurrence node. */
+DEFTREECODE (EEXIT_NODE, "eexit_node", 'x', 0)
+
+/* SSA PHI operator. PHI_RESULT is the new SSA_NAME node created by
+ the PHI node. PHI_ARG_LENGTH is the number of arguments.
+ PHI_ARG_ELT returns the Ith tuple <ssa_name, edge> from the
+ argument list. Each tuple contains the incoming reaching
+ definition (SSA_NAME node) and the edge via which that definition
+ is coming through. */
+DEFTREECODE (PHI_NODE, "phi_node", 'x', 0)
+
+/* Used to represent a typed exception handler. CATCH_TYPES is the type (or
+ list of types) handled, and CATCH_BODY is the code for the handler. */
+DEFTREECODE (CATCH_EXPR, "catch_expr", 's', 2)
+
+/* Used to represent an exception specification. EH_FILTER_TYPES is a list
+ of allowed types, and EH_FILTER_FAILURE is an expression to evaluate on
+ failure. EH_FILTER_MUST_NOT_THROW controls which range type to use when
+ expanding. */
+DEFTREECODE (EH_FILTER_EXPR, "eh_filter_expr", 's', 2)
+
+/* Used to chain children of container statements together.
+ Use the interface in tree-iterator.h to access this node. */
+DEFTREECODE (STATEMENT_LIST, "statement_list", 'x', 0)
/*
Local variables:
diff --git a/gcc/tree.h b/gcc/tree.h
index 12dec421f67..efc8691a0d0 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -148,11 +148,13 @@ extern GTY(()) tree implicit_built_in_decls[(int) END_BUILTINS];
See the accessor macros, defined below, for documentation of the
fields. */
+union tree_ann_d;
struct tree_common GTY(())
{
tree chain;
tree type;
+ union tree_ann_d *ann;
ENUM_BITFIELD(tree_code) code : 8;
@@ -163,17 +165,16 @@ struct tree_common GTY(())
unsigned readonly_flag : 1;
unsigned unsigned_flag : 1;
unsigned asm_written_flag: 1;
- unsigned used_flag : 1;
+ unsigned nowarning_flag : 1;
+ unsigned used_flag : 1;
unsigned nothrow_flag : 1;
unsigned static_flag : 1;
unsigned public_flag : 1;
unsigned private_flag : 1;
unsigned protected_flag : 1;
unsigned deprecated_flag : 1;
-
- unsigned unused_0 : 1;
- unsigned unused_1 : 1;
+ unsigned invariant_flag : 1;
unsigned lang_flag_0 : 1;
unsigned lang_flag_1 : 1;
@@ -182,7 +183,7 @@ struct tree_common GTY(())
unsigned lang_flag_4 : 1;
unsigned lang_flag_5 : 1;
unsigned lang_flag_6 : 1;
- unsigned unused_2 : 1;
+ unsigned visited : 1;
};
/* The following table lists the uses of each of the above flags and
@@ -196,14 +197,12 @@ struct tree_common GTY(())
..._TYPE, IDENTIFIER_NODE.
In a STMT_EXPR, it means we want the result of the enclosed
expression.
+ CALL_EXPR_TAILCALL in CALL_EXPR
static_flag:
TREE_STATIC in
VAR_DECL, FUNCTION_DECL, CONSTRUCTOR, ADDR_EXPR
- TREE_NO_UNUSED_WARNING in
- CONVERT_EXPR, NOP_EXPR, COMPOUND_EXPR, NON_LVALUE_EXPR
- ??? plus other expressions, apparently (e.g. MODIFY_EXPR).
TREE_VIA_VIRTUAL in
TREE_LIST or TREE_VEC
TREE_CONSTANT_OVERFLOW in
@@ -213,6 +212,9 @@ struct tree_common GTY(())
CLEANUP_EH_ONLY in
TARGET_EXPR, WITH_CLEANUP_EXPR, CLEANUP_STMT,
TREE_LIST elements of a block's cleanup list.
+ ASM_INPUT_P in
+ ASM_EXPR
+ EH_FILTER_MUST_NOT_THROW in EH_FILTER_EXPR
TYPE_REF_CAN_ALIAS_ALL in
POINTER_TYPE, REFERENCE_TYPE
@@ -223,8 +225,10 @@ struct tree_common GTY(())
??? and other expressions?
TREE_PUBLIC in
VAR_DECL or FUNCTION_DECL or IDENTIFIER_NODE
- EXPR_WFL_EMIT_LINE_NOTE in
- EXPR_WITH_FILE_LOCATION
+ TREE_VIA_PUBLIC in
+ TREE_LIST or TREE_VEC
+ ASM_VOLATILE_P in
+ ASM_EXPR
private_flag:
@@ -248,6 +252,9 @@ struct tree_common GTY(())
all decls
all constants
+ FORCED_LABEL in
+ LABEL_DECL
+
volatile_flag:
TREE_THIS_VOLATILE in
@@ -284,7 +291,7 @@ struct tree_common GTY(())
TREE_ASM_WRITTEN in
VAR_DECL, FUNCTION_DECL, RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE
- BLOCK
+ BLOCK, SSA_NAME
used_flag:
@@ -304,6 +311,19 @@ struct tree_common GTY(())
TREE_DEPRECATED in
..._DECL
+ visited:
+
+ Used in tree traversals to mark visited nodes.
+
+ invariant_flag:
+
+ TREE_INVARIANT in
+ all expressions.
+
+ nowarning_flag:
+
+ TREE_NO_WARNING in
+ ... any expr node
*/
/* Define accessors for the fields that all tree nodes have
@@ -387,6 +407,16 @@ struct tree_common GTY(())
__FUNCTION__); \
__t; })
+#define EREF_NODE_CHECK(t) __extension__ \
+({ const tree __t = t; \
+ if (TREE_CODE (__t) != EPHI_NODE \
+ && TREE_CODE (__t) != EKILL_NODE \
+ && TREE_CODE (__t) != EUSE_NODE \
+ && TREE_CODE (__t) != EEXIT_NODE) \
+ tree_check_failed (__t, TREE_CODE (t), \
+ __FILE__, __LINE__, __FUNCTION__); \
+ __t; })
+
#define TREE_VEC_ELT_CHECK(T, I) __extension__ \
(*({const tree __t = (T); \
const int __i = (I); \
@@ -398,6 +428,28 @@ struct tree_common GTY(())
__FILE__, __LINE__, __FUNCTION__); \
&__t->vec.a[__i]; }))
+#define EPHI_NODE_ELT_CHECK(t, i) __extension__ \
+(*({const tree __t = t; \
+ const int __i = (i); \
+ if (TREE_CODE (__t) != EPHI_NODE) \
+ tree_check_failed (__t, EPHI_NODE, \
+ __FILE__, __LINE__, __FUNCTION__); \
+ if (__i < 0 || __i >= __t->ephi.capacity) \
+ ephi_node_elt_check_failed (__i, __t->ephi.num_args, \
+ __FILE__, __LINE__, __FUNCTION__); \
+ &__t->ephi.a[__i]; }))
+
+#define PHI_NODE_ELT_CHECK(t, i) __extension__ \
+(*({const tree __t = t; \
+ const int __i = (i); \
+ if (TREE_CODE (__t) != PHI_NODE) \
+ tree_check_failed (__t, PHI_NODE, \
+ __FILE__, __LINE__, __FUNCTION__); \
+ if (__i < 0 || __i >= __t->phi.capacity) \
+ phi_node_elt_check_failed (__i, __t->phi.num_args, \
+ __FILE__, __LINE__, __FUNCTION__); \
+ &__t->phi.a[__i]; }))
+
/* Special checks for TREE_OPERANDs. */
#define TREE_OPERAND_CHECK(T, I) __extension__ \
(*({const tree __t = EXPR_CHECK (T); \
@@ -452,6 +504,12 @@ extern void tree_class_check_failed (const tree, int,
extern void tree_vec_elt_check_failed (int, int, const char *,
int, const char *)
ATTRIBUTE_NORETURN;
+extern void phi_node_elt_check_failed (int, int, const char *,
+ int, const char *)
+ ATTRIBUTE_NORETURN;
+extern void ephi_node_elt_check_failed (int, int, const char *,
+ int, const char *)
+ ATTRIBUTE_NORETURN;
extern void tree_operand_check_failed (int, enum tree_code,
const char *, int, const char *)
@@ -471,9 +529,14 @@ extern void tree_operand_check_failed (int, enum tree_code,
#define TREE_OPERAND_CHECK(T, I) ((T)->exp.operands[I])
#define TREE_OPERAND_CHECK_CODE(T, CODE, I) ((T)->exp.operands[I])
#define TREE_RTL_OPERAND_CHECK(T, CODE, I) (*(rtx *) &((T)->exp.operands[I]))
+#define EREF_NODE_CHECK(T) (T)
+#define PHI_NODE_ELT_CHECK(T, i) ((T)->phi.a[i])
+#define EPHI_NODE_ELT_CHECK(T, i) ((T)->ephi.a[i])
#endif
+#define TREE_BLOCK(NODE) ((NODE)->exp.block)
+
#include "tree-check.h"
#define TYPE_CHECK(T) TREE_CLASS_CHECK (T, 't')
@@ -483,8 +546,8 @@ extern void tree_operand_check_failed (int, enum tree_code,
#define FUNC_OR_METHOD_CHECK(T) TREE_CHECK2 (T, FUNCTION_TYPE, METHOD_TYPE)
#define PTR_OR_REF_CHECK(T) TREE_CHECK2 (T, POINTER_TYPE, REFERENCE_TYPE)
-#define SET_ARRAY_OR_VECTOR_CHECK(T) \
- TREE_CHECK3 (T, ARRAY_TYPE, SET_TYPE, VECTOR_TYPE)
+#define SET_OR_ARRAY_CHECK(T) \
+ TREE_CHECK2 (T, ARRAY_TYPE, SET_TYPE)
#define REC_OR_UNION_CHECK(T) \
TREE_CHECK3 (T, RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE)
@@ -565,6 +628,13 @@ extern void tree_operand_check_failed (int, enum tree_code,
== TREE_TYPE (TREE_OPERAND (EXP, 0)))) \
(EXP) = TREE_OPERAND (EXP, 0)
+/* Remove unnecessary type conversions according to
+ tree_ssa_useless_type_conversion. */
+
+#define STRIP_USELESS_TYPE_CONVERSION(EXP) \
+ while (tree_ssa_useless_type_conversion (EXP)) \
+ EXP = TREE_OPERAND (EXP, 0)
+
/* Nonzero if TYPE represents an integral type. Note that we do not
include COMPLEX types here. */
@@ -638,6 +708,8 @@ extern void tree_operand_check_failed (int, enum tree_code,
had its address taken. That matters for inline functions. */
#define TREE_ADDRESSABLE(NODE) ((NODE)->common.addressable_flag)
+#define CALL_EXPR_TAILCALL(NODE) (CALL_EXPR_CHECK(NODE)->common.addressable_flag)
+
/* In a VAR_DECL, nonzero means allocate static storage.
In a FUNCTION_DECL, nonzero if function has been defined.
In a CONSTRUCTOR, nonzero means allocate static storage.
@@ -651,13 +723,9 @@ extern void tree_operand_check_failed (int, enum tree_code,
executed if an exception is thrown, not on normal exit of its scope. */
#define CLEANUP_EH_ONLY(NODE) ((NODE)->common.static_flag)
-/* In a CONVERT_EXPR, NOP_EXPR, NON_LVALUE_EXPR or COMPOUND_EXPR, this means
- the node was made implicitly and should not lead to an "unused value"
- warning.
-
- ??? Apparently this is also used on other expression types (such as
- MODIFY_EXPR. This needs to be cleaned up sometime. */
-#define TREE_NO_UNUSED_WARNING(NODE) (EXPR_CHECK (NODE)->common.static_flag)
+/* In an expr node (usually a conversion) this means the node was made
+ implicitly and should not lead to any sort of warning. */
+#define TREE_NO_WARNING(NODE) ((NODE)->common.nowarning_flag)
/* Nonzero for a TREE_LIST or TREE_VEC node means that the derivation
chain is via a `virtual' declaration. */
@@ -704,6 +772,11 @@ extern void tree_operand_check_failed (int, enum tree_code,
#define TREE_SIDE_EFFECTS(NODE) \
(NON_TYPE_CHECK (NODE)->common.side_effects_flag)
+/* In a LABEL_DECL, nonzero means this label had its address taken
+ and therefore can never be deleted and is a jump target for
+ computed gotos. */
+#define FORCED_LABEL(NODE) ((NODE)->common.side_effects_flag)
+
/* Nonzero means this expression is volatile in the C sense:
its address should be of type `volatile WHATEVER *'.
In other words, the declared item is volatile qualified.
@@ -746,7 +819,9 @@ extern void tree_operand_check_failed (int, enum tree_code,
to be compiled separately.
Nonzero in a RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE or ENUMERAL_TYPE
if the sdb debugging info for the type has been written.
- In a BLOCK node, nonzero if reorder_blocks has already seen this block. */
+ In a BLOCK node, nonzero if reorder_blocks has already seen this block.
+ In an SSA_NAME node, nonzero if the SSA_NAME occurs in an abnormal
+ PHI node. */
#define TREE_ASM_WRITTEN(NODE) ((NODE)->common.asm_written_flag)
/* Nonzero in a _DECL if the name is used in its scope.
@@ -772,7 +847,10 @@ extern void tree_operand_check_failed (int, enum tree_code,
of this type is aligned at least to the alignment of the type, even if it
doesn't appear that it is. We see this, for example, in object-oriented
languages where a tag field may show this is an object of a more-aligned
- variant of the more generic type. */
+ variant of the more generic type.
+
+ In an SSA_NAME node, nonzero if the SSA_NAME node is on the SSA_NAME
+ freelist. */
#define TYPE_ALIGN_OK(NODE) (TYPE_CHECK (NODE)->common.nothrow_flag)
/* Used in classes in C++. */
@@ -785,6 +863,12 @@ extern void tree_operand_check_failed (int, enum tree_code,
deprecated feature by __attribute__((deprecated)). */
#define TREE_DEPRECATED(NODE) ((NODE)->common.deprecated_flag)
+/* Value of expression is function invariant. A strict subset of
+ TREE_CONSTANT, such an expression is constant over any one function
+ invocation, though not across different invocations. May appear in
+ any expression node. */
+#define TREE_INVARIANT(NODE) ((NODE)->common.invariant_flag)
+
/* These flags are available for each language front end to use internally. */
#define TREE_LANG_FLAG_0(NODE) ((NODE)->common.lang_flag_0)
#define TREE_LANG_FLAG_1(NODE) ((NODE)->common.lang_flag_1)
@@ -924,6 +1008,11 @@ struct tree_vec GTY(())
/* Define fields and accessors for some nodes that represent expressions. */
+/* Non-zero if NODE is an emtpy statement (NOP_EXPR <0>). */
+#define IS_EMPTY_STMT(NODE) (TREE_CODE (NODE) == NOP_EXPR \
+ && VOID_TYPE_P (TREE_TYPE (NODE)) \
+ && integer_zerop (TREE_OPERAND (NODE, 0)))
+
/* In a SAVE_EXPR node. */
#define SAVE_EXPR_CONTEXT(NODE) TREE_OPERAND_CHECK_CODE (NODE, SAVE_EXPR, 1)
#define SAVE_EXPR_RTL(NODE) TREE_RTL_OPERAND_CHECK (NODE, SAVE_EXPR, 2)
@@ -967,36 +1056,331 @@ struct tree_vec GTY(())
/* In a LOOP_EXPR node. */
#define LOOP_EXPR_BODY(NODE) TREE_OPERAND_CHECK_CODE (NODE, LOOP_EXPR, 0)
-/* In an EXPR_WITH_FILE_LOCATION node. */
-#define EXPR_WFL_EMIT_LINE_NOTE(NODE) \
- (EXPR_WITH_FILE_LOCATION_CHECK (NODE)->common.public_flag)
-#define EXPR_WFL_NODE(NODE) \
- TREE_OPERAND_CHECK_CODE (NODE, EXPR_WITH_FILE_LOCATION, 0)
-#define EXPR_WFL_FILENAME_NODE(NODE) \
- TREE_OPERAND_CHECK_CODE (NODE, EXPR_WITH_FILE_LOCATION, 1)
-#define EXPR_WFL_FILENAME(NODE) \
- IDENTIFIER_POINTER (EXPR_WFL_FILENAME_NODE (NODE))
-/* ??? Java uses this in all expressions. */
-#define EXPR_WFL_LINECOL(NODE) (EXPR_CHECK (NODE)->exp.complexity)
-#define EXPR_WFL_LINENO(NODE) (EXPR_WFL_LINECOL (NODE) >> 12)
-#define EXPR_WFL_COLNO(NODE) (EXPR_WFL_LINECOL (NODE) & 0xfff)
-#define EXPR_WFL_SET_LINECOL(NODE, LINE, COL) \
- (EXPR_WFL_LINECOL(NODE) = ((LINE) << 12) | ((COL) & 0xfff))
+/* The source location of this expression. Non-tree_exp nodes such as
+ decls and constants can be shared among multiple locations, so
+ return nothing. */
+#define EXPR_LOCUS(NODE) \
+ (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (NODE))) \
+ ? (NODE)->exp.locus \
+ : (location_t *)NULL)
+#define SET_EXPR_LOCUS(NODE, FROM) \
+ (EXPR_CHECK (NODE)->exp.locus = (FROM))
+#define EXPR_FILENAME(NODE) \
+ (EXPR_CHECK (NODE)->exp.locus->file)
+#define EXPR_LINENO(NODE) \
+ (EXPR_CHECK (NODE)->exp.locus->line)
+#ifdef USE_MAPPED_LOCATION
+#define EXPR_LOCATION(NODE) \
+ (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (NODE))) \
+ ? (NODE)->exp.locus \
+ : UNKNOWN_LOCATION)
+#define EXPR_HAS_LOCATION(NODE) (EXPR_LOCATION (NODE) != UNKNOWN_LOCATION)
+#else
+#define EXPR_LOCATION(NODE) (*EXPR_LOCUS (NODE))
+#define EXPR_HAS_LOCATION(NODE) (EXPR_LOCUS (NODE) != NULL)
+#endif
/* In a TARGET_EXPR node. */
#define TARGET_EXPR_SLOT(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 0)
#define TARGET_EXPR_INITIAL(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 1)
#define TARGET_EXPR_CLEANUP(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 2)
+#define EXIT_EXPR_COND(NODE) TREE_OPERAND (EXIT_EXPR_CHECK (NODE), 0)
+
+/* SWITCH_EXPR accessors. These give access to the condition, body and
+ original condition type (before any compiler conversions)
+ of the switch statement, respectively. */
+#define SWITCH_COND(NODE) TREE_OPERAND ((NODE), 0)
+#define SWITCH_BODY(NODE) TREE_OPERAND ((NODE), 1)
+#define SWITCH_LABELS(NODE) TREE_OPERAND ((NODE), 2)
+
+/* CASE_LABEL accessors. These give access to the high and low values
+ of a case label, respectively. */
+#define CASE_LOW(NODE) TREE_OPERAND ((NODE), 0)
+#define CASE_HIGH(NODE) TREE_OPERAND ((NODE), 1)
+#define CASE_LABEL(NODE) TREE_OPERAND ((NODE), 2)
+
+/* The operands of a BIND_EXPR. */
+#define BIND_EXPR_VARS(NODE) (TREE_OPERAND (BIND_EXPR_CHECK (NODE), 0))
+#define BIND_EXPR_BODY(NODE) (TREE_OPERAND (BIND_EXPR_CHECK (NODE), 1))
+#define BIND_EXPR_BLOCK(NODE) (TREE_OPERAND (BIND_EXPR_CHECK (NODE), 2))
+
+/* GOTO_EXPR accessor. This gives access to the label associated with
+ a goto statement. */
+#define GOTO_DESTINATION(NODE) TREE_OPERAND ((NODE), 0)
+
+/* ASM_STMT accessors. ASM_STRING returns a STRING_CST for the
+ instruction (e.g., "mov x, y"). ASM_OUTPUTS, ASM_INPUTS, and
+ ASM_CLOBBERS represent the outputs, inputs, and clobbers for the
+ statement. */
+#define ASM_STRING(NODE) TREE_OPERAND ((NODE), 0)
+#define ASM_OUTPUTS(NODE) TREE_OPERAND ((NODE), 1)
+#define ASM_INPUTS(NODE) TREE_OPERAND ((NODE), 2)
+#define ASM_CLOBBERS(NODE) TREE_OPERAND ((NODE), 3)
+/* Nonzero if we want to create an ASM_INPUT instead of an
+ ASM_OPERAND with no operands. */
+#define ASM_INPUT_P(NODE) (TREE_STATIC (NODE))
+#define ASM_VOLATILE_P(NODE) (TREE_PUBLIC (NODE))
+
+/* COND_EXPR accessors. */
+#define COND_EXPR_COND(NODE) (TREE_OPERAND (COND_EXPR_CHECK (NODE), 0))
+#define COND_EXPR_THEN(NODE) (TREE_OPERAND (COND_EXPR_CHECK (NODE), 1))
+#define COND_EXPR_ELSE(NODE) (TREE_OPERAND (COND_EXPR_CHECK (NODE), 2))
+
+/* LABEL_EXPR accessor. This gives access to the label associated with
+ the given label expression. */
+#define LABEL_EXPR_LABEL(NODE) TREE_OPERAND (LABEL_EXPR_CHECK (NODE), 0)
+
+/* VDEF_EXPR accessors are specified in tree-flow.h, along with the other
+ accessors for SSA operands. */
+
+/* CATCH_EXPR accessors. */
+#define CATCH_TYPES(NODE) TREE_OPERAND (CATCH_EXPR_CHECK (NODE), 0)
+#define CATCH_BODY(NODE) TREE_OPERAND (CATCH_EXPR_CHECK (NODE), 1)
+
+/* EH_FILTER_EXPR accessors. */
+#define EH_FILTER_TYPES(NODE) TREE_OPERAND (EH_FILTER_EXPR_CHECK (NODE), 0)
+#define EH_FILTER_FAILURE(NODE) TREE_OPERAND (EH_FILTER_EXPR_CHECK (NODE), 1)
+#define EH_FILTER_MUST_NOT_THROW(NODE) TREE_STATIC (EH_FILTER_EXPR_CHECK (NODE))
+
struct tree_exp GTY(())
{
struct tree_common common;
+ location_t *locus;
int complexity;
+ tree block;
tree GTY ((special ("tree_exp"),
desc ("TREE_CODE ((tree) &%0)")))
operands[1];
};
+/* SSA_NAME accessors. */
+
+/* Returns the variable being referenced. Once released, this is the
+ only field that can be relied upon. */
+#define SSA_NAME_VAR(NODE) SSA_NAME_CHECK (NODE)->ssa_name.var
+
+/* Returns the statement which defines this reference. Note that
+ we use the same field when chaining SSA_NAME nodes together on
+ the SSA_NAME freelist. */
+#define SSA_NAME_DEF_STMT(NODE) SSA_NAME_CHECK (NODE)->common.chain
+
+/* Returns the SSA version number of this SSA name. Note that in
+ tree SSA, version numbers are not per variable and may be recycled. */
+#define SSA_NAME_VERSION(NODE) SSA_NAME_CHECK (NODE)->ssa_name.version
+
+/* Nonzero if this SSA name occurs in an abnormal PHI. SSA_NAMES are
+ never output, so we can safely use the ASM_WRITTEN_FLAG for this
+ status bit. */
+#define SSA_NAME_OCCURS_IN_ABNORMAL_PHI(NODE) \
+ SSA_NAME_CHECK (NODE)->common.asm_written_flag
+
+/* Nonzero if this SSA_NAME expression is currently on the freelist of
+ SSA_NAMES. Using NOTHROW_FLAG seems reasonably safe since throwing
+ has no meaning for an SSA_NAME. */
+#define SSA_NAME_IN_FREE_LIST(NODE) \
+ SSA_NAME_CHECK (NODE)->common.nothrow_flag
+
+struct tree_ssa_name GTY(())
+{
+ struct tree_common common;
+
+ /* _DECL wrapped by this SSA name. */
+ tree var;
+
+ /* SSA version number. */
+ unsigned int version;
+};
+
+/* In a PHI_NODE node. */
+#define PHI_RESULT(NODE) PHI_NODE_CHECK (NODE)->phi.result
+
+/* Nonzero if the PHI node was rewritten by a previous pass through the
+ SSA renamer. */
+#define PHI_REWRITTEN(NODE) PHI_NODE_CHECK (NODE)->phi.rewritten
+#define PHI_NUM_ARGS(NODE) PHI_NODE_CHECK (NODE)->phi.num_args
+#define PHI_ARG_CAPACITY(NODE) PHI_NODE_CHECK (NODE)->phi.capacity
+#define PHI_ARG_ELT(NODE, I) PHI_NODE_ELT_CHECK (NODE, I)
+#define PHI_ARG_EDGE(NODE, I) PHI_NODE_ELT_CHECK (NODE, I).e
+#define PHI_ARG_DEF(NODE, I) PHI_NODE_ELT_CHECK (NODE, I).def
+
+struct edge_def;
+
+struct phi_arg_d GTY(())
+{
+ tree def;
+ struct edge_def * GTY((skip (""))) e;
+};
+
+struct tree_phi_node GTY(())
+{
+ struct tree_common common;
+ tree result;
+ int num_args;
+ int capacity;
+
+ /* Nonzero if the PHI node was rewritten by a previous pass through the
+ SSA renamer. */
+ int rewritten;
+
+ struct phi_arg_d GTY ((length ("((tree)&%h)->phi.capacity"))) a[1];
+};
+
+
+struct varray_head_tag;
+
+struct tree_eref_common GTY(())
+{
+ struct tree_common common;
+
+ /* SSAPRE: ID for the EREF. Used only for sorting erefs inside a
+ block. */
+ int id;
+
+ /* SSAPRE: Name for the EREF. Used only for printing.*/
+ tree name;
+
+ /* SSAPRE: The statement associated with this expression reference. */
+ tree stmt;
+
+ /* SSAPRE: True if expression needs to be saved to a temporary. */
+ unsigned int save:1;
+
+ /* SSAPRE: True if expression needs to be reloaded from a temporary. */
+ unsigned int reload:1;
+
+ /* SSAPRE: Redundancy class of expression. */
+ unsigned int class;
+
+ /* SSAPRE: Processed flag 1. */
+ unsigned int processed:1;
+
+ /* SSAPRE: True if expression is injured. */
+ unsigned int injured:1;
+
+ /* SSAPRE: Temporary assigned to this reference. */
+ tree temp;
+
+};
+
+struct tree_euse_node GTY(())
+{
+ struct tree_eref_common common;
+
+ /* SSAPRE: Definition for this use. */
+ tree def;
+
+ /* SSAPRE: True if this is an EPHI operand occurrence. */
+ unsigned int op_occurrence:1;
+
+ /* SSAPRE: True if expression was inserted as a PHI operand occurrence. */
+ unsigned int inserted:1;
+
+ /* SSAPRE: True if expression occurs as a lvalue. */
+ unsigned int lval:1;
+};
+struct ephi_arg_d GTY(())
+{
+
+ /* SSAPRE: True if this phi argument is injured. */
+ unsigned int injured:1;
+
+ /* SSAPRE: True if there is a real occurrence for this phi argument. */
+ unsigned int has_real_use:1;
+
+ /* SSAPRE: True if delayed renaming is required on this phi argument. */
+ unsigned int delayed_rename:1;
+
+ /* SSAPRE: Processed 2 flag for this phi argument. */
+ unsigned int processed2:1;
+
+ /* SSAPRE: True if this operand stops forward movement. */
+ unsigned int stops:1;
+
+ /* SSAPRE: Definition of this phi operand. */
+ tree def;
+
+ /* SSAPRE: Phi predecessor for this phi operand. */
+ tree pred;
+
+ struct edge_def * GTY((skip (""))) e;
+};
+struct tree_ephi_node GTY(())
+{
+ struct tree_eref_common common;
+
+ /* SSAPRE: True if PHI is downsafe. */
+ unsigned int downsafe:1;
+
+ /* SSAPRE: True if PHI is cant_be_avail. */
+ unsigned int cant_be_avail:1;
+
+ /* SSAPRE: True if PHI is dead. */
+ unsigned int dead:1;
+
+ /* SSAPRE: True if PHI is pointless or identical to some value. */
+ unsigned int identity:1;
+
+ /* SSAPRE: True if replacing occurrence known for ESSA minimization. */
+ unsigned int rep_occur_known:1;
+
+ /* SSAPRE: True if PHI is pointless, but is also injured. */
+ unsigned int ident_injured:1;
+
+ /* SSAPRE: True if this PHI stops forward movement. */
+ unsigned int stops:1;
+
+ /* SSAPRE: If PHI's replacing occurrence is known, this is it. */
+ tree identical_to;
+
+ /* SSAPRE: Uses of this ephi. */
+ struct varray_head_tag *uses;
+
+ int num_args;
+ int capacity;
+ struct ephi_arg_d GTY ((length ("((tree)&%h)->ephi.capacity"))) a[1];
+
+};
+/* In both EPHI's and EUSES */
+#define EREF_PROCESSED(NODE) EREF_NODE_CHECK (NODE)->eref.processed
+#define EREF_ID(NODE) EREF_NODE_CHECK (NODE)->eref.id
+#define EREF_NAME(NODE) EREF_NODE_CHECK (NODE)->eref.name
+#define EREF_STMT(NODE) EREF_NODE_CHECK (NODE)->eref.stmt
+#define EREF_RELOAD(NODE) EREF_NODE_CHECK (NODE)->eref.reload
+#define EREF_SAVE(NODE) EREF_NODE_CHECK (NODE)->eref.save
+#define EREF_CLASS(NODE) EREF_NODE_CHECK (NODE)->eref.class
+#define EREF_INJURED(NODE) EREF_NODE_CHECK (NODE)->eref.injured
+#define EREF_TEMP(NODE) EREF_NODE_CHECK (NODE)->eref.temp
+
+/* In a EUSE_NODE node. */
+#define EUSE_DEF(NODE) EUSE_NODE_CHECK (NODE)->euse.def
+#define EUSE_PHIOP(NODE) EUSE_NODE_CHECK (NODE)->euse.op_occurrence
+#define EUSE_INSERTED(NODE) EUSE_NODE_CHECK (NODE)->euse.inserted
+#define EUSE_LVAL(NODE) EUSE_NODE_CHECK (NODE)->euse.lval
+
+/* In a EPHI_NODE node. */
+#define EPHI_NUM_ARGS(NODE) EPHI_NODE_CHECK (NODE)->ephi.num_args
+#define EPHI_ARG_CAPACITY(NODE) EPHI_NODE_CHECK (NODE)->ephi.capacity
+#define EPHI_ARG_ELT(NODE, I) EPHI_NODE_ELT_CHECK (NODE, I)
+#define EPHI_ARG_EDGE(NODE, I) EPHI_NODE_ELT_CHECK (NODE, I).e
+#define EPHI_ARG_PRED(NODE, I) EPHI_NODE_ELT_CHECK (NODE, I).pred
+#define EPHI_ARG_DEF(NODE, I) EPHI_NODE_ELT_CHECK (NODE, I).def
+#define EPHI_ARG_INJURED(NODE, I) EPHI_NODE_ELT_CHECK (NODE, I).injured
+#define EPHI_ARG_DELAYED_RENAME(NODE, I) EPHI_NODE_ELT_CHECK (NODE, I).delayed_rename
+#define EPHI_ARG_HAS_REAL_USE(NODE, I) EPHI_NODE_ELT_CHECK (NODE, I).has_real_use
+#define EPHI_ARG_STOPS(NODE, I) EPHI_NODE_ELT_CHECK (NODE, I).stops
+#define EPHI_ARG_PROCESSED2(NODE, I) EPHI_NODE_ELT_CHECK (NODE, I).processed2
+#define EPHI_IDENTITY(NODE) EPHI_NODE_CHECK (NODE)->ephi.identity
+#define EPHI_IDENT_INJURED(NODE) EPHI_NODE_CHECK (NODE)->ephi.ident_injured
+
+#define EPHI_REP_OCCUR_KNOWN(NODE) EPHI_NODE_CHECK (NODE)->ephi.rep_occur_known
+#define EPHI_IDENTICAL_TO(NODE) EPHI_NODE_CHECK (NODE)->ephi.identical_to
+#define EPHI_DOWNSAFE(NODE) EPHI_NODE_CHECK (NODE)->ephi.downsafe
+#define EPHI_CANT_BE_AVAIL(NODE) EPHI_NODE_CHECK (NODE)->ephi.cant_be_avail
+#define EPHI_DEAD(NODE) EPHI_NODE_CHECK (NODE)->ephi.dead
+#define EPHI_USES(NODE) EPHI_NODE_CHECK (NODE)->ephi.uses
+#define EPHI_STOPS(NODE) EPHI_NODE_CHECK (NODE)->ephi.stops
+
/* In a BLOCK node. */
#define BLOCK_VARS(NODE) (BLOCK_CHECK (NODE)->block.vars)
#define BLOCK_SUBBLOCKS(NODE) (BLOCK_CHECK (NODE)->block.subblocks)
@@ -1075,7 +1459,7 @@ struct tree_block GTY(())
#define TYPE_MODE(NODE) (TYPE_CHECK (NODE)->type.mode)
#define TYPE_ORIG_SIZE_TYPE(NODE) (INTEGER_TYPE_CHECK (NODE)->type.values)
#define TYPE_VALUES(NODE) (ENUMERAL_TYPE_CHECK (NODE)->type.values)
-#define TYPE_DOMAIN(NODE) (SET_ARRAY_OR_VECTOR_CHECK (NODE)->type.values)
+#define TYPE_DOMAIN(NODE) (SET_OR_ARRAY_CHECK (NODE)->type.values)
#define TYPE_FIELDS(NODE) (REC_OR_UNION_CHECK (NODE)->type.values)
#define TYPE_METHODS(NODE) (REC_OR_UNION_CHECK (NODE)->type.maxval)
#define TYPE_VFIELD(NODE) (REC_OR_UNION_CHECK (NODE)->type.minval)
@@ -1101,7 +1485,7 @@ struct tree_block GTY(())
/* For a VECTOR_TYPE node, this describes a different type which is emitted
in the debugging output. We use this to describe a vector as a
structure containing an array. */
-#define TYPE_DEBUG_REPRESENTATION_TYPE(NODE) (TYPE_CHECK (NODE)->type.values)
+#define TYPE_DEBUG_REPRESENTATION_TYPE(NODE) (VECTOR_TYPE_CHECK (NODE)->type.values)
/* For aggregate types, information about this type, as a base type
for itself. Used in a language-dependent way for types that are
@@ -1198,6 +1582,10 @@ struct tree_block GTY(())
#define TYPE_LANG_FLAG_5(NODE) (TYPE_CHECK (NODE)->type.lang_flag_5)
#define TYPE_LANG_FLAG_6(NODE) (TYPE_CHECK (NODE)->type.lang_flag_6)
+/* Used to keep track of visited nodes in tree traversals. This is set to
+ 0 by copy_node and make_node. */
+#define TREE_VISITED(NODE) ((NODE)->common.visited)
+
/* If set in an ARRAY_TYPE, indicates a string type (for languages
that distinguish string from array of char).
If set in a SET_TYPE, indicates a bitstring type. */
@@ -1384,6 +1772,16 @@ struct tree_type GTY(())
/* Nonzero if DECL represents a decl. */
#define DECL_P(DECL) (TREE_CODE_CLASS (TREE_CODE (DECL)) == 'd')
+/* Nonzero if DECL represents a variable for the SSA passes. */
+#define SSA_VAR_P(DECL) \
+ (TREE_CODE (DECL) == VAR_DECL \
+ || TREE_CODE (DECL) == PARM_DECL \
+ || TREE_CODE (DECL) == RESULT_DECL \
+ || (TREE_CODE (DECL) == SSA_NAME \
+ && (TREE_CODE (SSA_NAME_VAR (DECL)) == VAR_DECL \
+ || TREE_CODE (SSA_NAME_VAR (DECL)) == PARM_DECL \
+ || TREE_CODE (SSA_NAME_VAR (DECL)) == RESULT_DECL)))
+
/* This is the name of the object as written by the user.
It is an IDENTIFIER_NODE. */
#define DECL_NAME(NODE) (DECL_CHECK (NODE)->decl.name)
@@ -1533,6 +1931,12 @@ struct tree_type GTY(())
this identifies which built-in operation it is. */
#define DECL_FUNCTION_CODE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.u1.f)
+/* In a FUNCTION_DECL for which DECL_BUILT_IN does not hold, this is
+ the approximate number of statements in this function. There is
+ no need for this number to be exact; it is only used in various
+ heuristics regarding optimization. */
+#define DECL_NUM_STMTS(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.u1.i)
+
/* The DECL_VINDEX is used for FUNCTION_DECLS in two different ways.
Before the struct containing the FUNCTION_DECL is laid out,
DECL_VINDEX may point to a FUNCTION_DECL in a base class which
@@ -1647,6 +2051,10 @@ struct tree_type GTY(())
#define DECL_DECLARED_INLINE_P(NODE) \
(FUNCTION_DECL_CHECK (NODE)->decl.declared_inline_flag)
+/* In a VAR_DECL, nonzero if the decl is a register variable with
+ an explicit asm specification. */
+#define DECL_HARD_REGISTER(NODE) (DECL_CHECK (NODE)->decl.inline_flag)
+
/* Value of the decls's visibility attribute */
#define DECL_VISIBILITY(NODE) (DECL_CHECK (NODE)->decl.visibility)
@@ -1774,6 +2182,16 @@ struct tree_type GTY(())
#define DECL_POINTER_ALIAS_SET(NODE) \
(DECL_CHECK (NODE)->decl.pointer_alias_set)
+/* Used to store the alias_var for a DECL node. */
+#define DECL_PTA_ALIASVAR(NODE) \
+ (DECL_CHECK (NODE)->decl.alias_var)
+
+/* A numeric unique identifier for a LABEL_DECL. The UID allocation is
+ dense, unique within any one function, and may be used to index arrays.
+ If the value is -1, then no UID has been assigned. */
+#define LABEL_DECL_UID(NODE) \
+ (LABEL_DECL_CHECK (NODE)->decl.pointer_alias_set)
+
/* Nonzero if an alias set has been assigned to this declaration. */
#define DECL_POINTER_ALIAS_SET_KNOWN_P(NODE) \
(DECL_POINTER_ALIAS_SET (NODE) != - 1)
@@ -1783,6 +2201,15 @@ struct tree_type GTY(())
(! DECL_CONTEXT (EXP) \
|| TREE_CODE (DECL_CONTEXT (EXP)) == TRANSLATION_UNIT_DECL)
+/* Nonzero for a decl that has been marked as needing a memory slot.
+ NOTE: Never use this macro directly. It will give you incomplete
+ information. Most of the time this bit will only be set after alias
+ analysis in the tree optimizers. It's always better to call
+ needs_to_live_in_memory instead. To mark memory variables use
+ mark_call_clobbered. */
+#define DECL_NEEDS_TO_LIVE_IN_MEMORY_INTERNAL(DECL) \
+ DECL_CHECK (DECL)->decl.needs_to_live_in_memory
+
/* Enumerate visibility settings. */
enum symbol_visibility
@@ -1794,7 +2221,7 @@ enum symbol_visibility
};
struct function;
-
+union alias_var_def;
struct tree_decl GTY(())
{
struct tree_common common;
@@ -1834,9 +2261,8 @@ struct tree_decl GTY(())
unsigned uninlinable : 1;
unsigned thread_local_flag : 1;
unsigned declared_inline_flag : 1;
+ unsigned seen_in_bind_expr : 1;
ENUM_BITFIELD(symbol_visibility) visibility : 2;
- unsigned unused : 1;
- /* one unused bit. */
unsigned lang_flag_0 : 1;
unsigned lang_flag_1 : 1;
@@ -1847,6 +2273,9 @@ struct tree_decl GTY(())
unsigned lang_flag_6 : 1;
unsigned lang_flag_7 : 1;
+ unsigned needs_to_live_in_memory : 1;
+ /* 15 unused bits. */
+
union tree_decl_u1 {
/* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is
DECL_FUNCTION_CODE. */
@@ -1895,9 +2324,38 @@ struct tree_decl GTY(())
tree vindex;
HOST_WIDE_INT pointer_alias_set;
+ union alias_var_def *GTY ((skip(""))) alias_var;
/* Points to a structure whose details depend on the language in use. */
struct lang_decl *lang_specific;
};
+
+
+/* A STATEMENT_LIST chains statements together in GENERIC and GIMPLE.
+ To reduce overhead, the nodes containing the statements are not trees.
+ This avoids the overhead of tree_common on all linked list elements.
+
+ Use the interface in tree-iterator.h to access this node. */
+
+#define STATEMENT_LIST_HEAD(NODE) \
+ (STATEMENT_LIST_CHECK (NODE)->stmt_list.head)
+#define STATEMENT_LIST_TAIL(NODE) \
+ (STATEMENT_LIST_CHECK (NODE)->stmt_list.tail)
+
+struct tree_statement_list_node
+ GTY ((chain_next ("%h.next"), chain_prev ("%h.prev")))
+{
+ struct tree_statement_list_node *prev;
+ struct tree_statement_list_node *next;
+ tree stmt;
+};
+
+struct tree_statement_list
+ GTY(())
+{
+ struct tree_common common;
+ struct tree_statement_list_node *head;
+ struct tree_statement_list_node *tail;
+};
enum tree_node_structure_enum {
TS_COMMON,
@@ -1912,7 +2370,13 @@ enum tree_node_structure_enum {
TS_LIST,
TS_VEC,
TS_EXP,
+ TS_SSA_NAME,
+ TS_PHI_NODE,
+ TS_EPHI_NODE,
+ TS_EUSE_NODE,
+ TS_EREF_NODE,
TS_BLOCK,
+ TS_STATEMENT_LIST,
LAST_TS_ENUM
};
@@ -1935,8 +2399,14 @@ union tree_node GTY ((ptr_alias (union lang_tree_node),
struct tree_list GTY ((tag ("TS_LIST"))) list;
struct tree_vec GTY ((tag ("TS_VEC"))) vec;
struct tree_exp GTY ((tag ("TS_EXP"))) exp;
+ struct tree_ssa_name GTY ((tag ("TS_SSA_NAME"))) ssa_name;
+ struct tree_phi_node GTY ((tag ("TS_PHI_NODE"))) phi;
+ struct tree_eref_common GTY ((tag ("TS_EREF_NODE"))) eref;
+ struct tree_ephi_node GTY ((tag ("TS_EPHI_NODE"))) ephi;
+ struct tree_euse_node GTY ((tag ("TS_EUSE_NODE"))) euse;
struct tree_block GTY ((tag ("TS_BLOCK"))) block;
- };
+ struct tree_statement_list GTY ((tag ("TS_STATEMENT_LIST"))) stmt_list;
+};
/* Standard named or nameless data types of the C compiler. */
@@ -1992,6 +2462,7 @@ enum tree_index
TI_PTR_TYPE,
TI_CONST_PTR_TYPE,
TI_SIZE_TYPE,
+ TI_PID_TYPE,
TI_PTRDIFF_TYPE,
TI_VA_LIST_TYPE,
TI_BOOLEAN_TYPE,
@@ -2056,6 +2527,7 @@ extern GTY(()) tree global_trees[TI_MAX];
#define const_ptr_type_node global_trees[TI_CONST_PTR_TYPE]
/* The C type `size_t'. */
#define size_type_node global_trees[TI_SIZE_TYPE]
+#define pid_type_node global_trees[TI_PID_TYPE]
#define ptrdiff_type_node global_trees[TI_PTRDIFF_TYPE]
#define va_list_type_node global_trees[TI_VA_LIST_TYPE]
@@ -2181,6 +2653,24 @@ extern tree copy_list (tree);
extern tree make_tree_vec_stat (int MEM_STAT_DECL);
#define make_tree_vec(t) make_tree_vec_stat (t MEM_STAT_INFO)
+/* Tree nodes for SSA analysis. */
+
+extern tree make_phi_node (tree, int);
+extern void init_phinodes (void);
+extern void fini_phinodes (void);
+extern void release_phi_node (tree);
+#ifdef GATHER_STATISTICS
+extern void phinodes_print_statistics (void);
+#endif
+
+extern void init_ssanames (void);
+extern void fini_ssanames (void);
+extern tree make_ssa_name (tree, tree);
+extern void release_ssa_name (tree);
+#ifdef GATHER_STATISTICS
+extern void ssanames_print_statistics (void);
+#endif
+
/* Return the (unique) IDENTIFIER_NODE node for a given name.
The name is supplied as a char *. */
@@ -2248,7 +2738,9 @@ extern tree build_tree_list_stat (tree, tree MEM_STAT_DECL);
extern tree build_decl_stat (enum tree_code, tree, tree MEM_STAT_DECL);
#define build_decl(c,t,q) build_decl_stat (c,t,q MEM_STAT_INFO)
extern tree build_block (tree, tree, tree, tree, tree);
-extern tree build_expr_wfl (tree, const char *, int, int);
+extern void annotate_with_file_line (tree, const char *, int);
+extern void annotate_with_locus (tree, location_t);
+extern tree build_empty_stmt (void);
/* Construct various nodes representing data types. */
@@ -2538,7 +3030,7 @@ extern tree convert (tree, tree);
extern unsigned int expr_align (tree);
extern tree expr_first (tree);
extern tree expr_last (tree);
-extern int expr_length (tree);
+extern tree expr_only (tree);
extern tree size_in_bytes (tree);
extern HOST_WIDE_INT int_size_in_bytes (tree);
extern tree bit_position (tree);
@@ -2631,11 +3123,14 @@ extern int fields_length (tree);
extern bool initializer_zerop (tree);
-/* Given an initializer INIT, return TRUE if INIT is at least 3/4 zeros.
- Otherwise return FALSE. */
-
+extern void categorize_ctor_elements (tree, HOST_WIDE_INT *, HOST_WIDE_INT *);
+extern HOST_WIDE_INT count_type_elements (tree);
extern int mostly_zeros_p (tree);
+/* add_var_to_bind_expr (bind_expr, var) binds var to bind_expr. */
+
+extern void add_var_to_bind_expr (tree, tree);
+
/* integer_zerop (tree x) is nonzero if X is an integer constant of value 0 */
extern int integer_zerop (tree);
@@ -2823,13 +3318,6 @@ extern tree decl_function_context (tree);
this _DECL with its context, or zero if none. */
extern tree decl_type_context (tree);
-/* Given the FUNCTION_DECL for the current function,
- return zero if it is ok for this function to be inline.
- Otherwise return a warning message with a single %s
- for the function's name. */
-
-extern const char *function_cannot_inline_p (tree);
-
/* Return 1 if EXPR is the real constant zero. */
extern int real_zerop (tree);
@@ -2852,6 +3340,11 @@ extern GTY(()) tree current_function_decl;
/* Nonzero means a FUNC_BEGIN label was emitted. */
extern GTY(()) tree current_function_func_begin_label;
+/* A DECL for the current file-scope context. When using IMA, this heads a
+ chain of FILE_DECLs; currently only C uses it. */
+
+extern GTY(()) tree current_file_decl;
+
/* Nonzero means all ..._TYPE nodes should be allocated permanently. */
extern int all_types_permanent;
@@ -2875,6 +3368,7 @@ extern tree get_callee_fndecl (tree);
extern void change_decl_assembler_name (tree, tree);
extern int type_num_arguments (tree);
extern tree lhd_unsave_expr_now (tree);
+extern bool is_essa_node (tree);
extern bool associative_tree_code (enum tree_code);
extern bool commutative_tree_code (enum tree_code);
@@ -2908,6 +3402,9 @@ extern int expand_exit_loop_if_false (struct nesting *,tree);
extern int expand_exit_loop_top_cond (struct nesting *, tree);
extern int expand_exit_something (void);
+extern void expand_stack_alloc (tree, tree);
+extern rtx expand_stack_save (void);
+extern void expand_stack_restore (tree);
extern void expand_return (tree);
extern int optimize_tail_recursion (tree, rtx);
extern void expand_start_bindings_and_block (int, tree);
@@ -2925,7 +3422,7 @@ extern tree last_cleanup_this_contour (void);
extern void expand_start_case (int, tree, tree, const char *);
extern void expand_end_case_type (tree, tree);
#define expand_end_case(cond) expand_end_case_type (cond, NULL)
-extern int add_case_node (tree, tree, tree, tree *);
+extern int add_case_node (tree, tree, tree, tree *, bool);
extern int pushcase (tree, tree (*) (tree, tree), tree, tree *);
extern int pushcase_range (tree, tree, tree (*) (tree, tree), tree, tree *);
extern void using_eh_for_cleanups (void);
@@ -2940,6 +3437,7 @@ extern void using_eh_for_cleanups (void);
extern tree fold (tree);
extern tree fold_initializer (tree);
+extern tree fold_convert (tree, tree);
extern tree fold_single_bit_test (enum tree_code, tree, tree, tree);
extern int force_fit_type (tree, int);
@@ -2970,15 +3468,29 @@ extern int div_and_round_double (enum tree_code, int, unsigned HOST_WIDE_INT,
HOST_WIDE_INT *, unsigned HOST_WIDE_INT *,
HOST_WIDE_INT *);
-extern int operand_equal_p (tree, tree, int);
+enum operand_equal_flag
+{
+ OEP_ONLY_CONST = 1,
+ OEP_PURE_SAME = 2
+};
+
+extern int operand_equal_p (tree, tree, unsigned int);
+
extern tree omit_one_operand (tree, tree, tree);
extern tree invert_truthvalue (tree);
+extern tree nondestructive_fold_unary_to_constant (enum tree_code, tree, tree);
+extern tree nondestructive_fold_binary_to_constant (enum tree_code, tree, tree, tree);
+extern tree fold_read_from_constant_string (tree);
+extern tree int_const_binop (enum tree_code, tree, tree, int);
/* In builtins.c */
extern tree fold_builtin (tree);
extern enum built_in_function builtin_mathfn_code (tree);
extern tree build_function_call_expr (tree, tree);
extern tree mathfn_built_in (tree, enum built_in_function fn);
+extern tree strip_float_extensions (tree);
+extern tree simplify_builtin (tree, int);
+extern tree c_strlen (tree, int);
/* In convert.c */
extern tree strip_float_extensions (tree);
@@ -3009,6 +3521,9 @@ extern void dump_tree_statistics (void);
extern void expand_function_end (void);
extern void expand_function_start (tree, int);
extern void expand_pending_sizes (tree);
+extern void recompute_tree_invarant_for_addr_expr (tree);
+extern bool needs_to_live_in_memory (tree);
+extern tree make_vector (enum machine_mode, tree, int);
extern tree reconstruct_complex_type (tree, tree);
extern int real_onep (tree);
@@ -3031,7 +3546,7 @@ extern void init_function_start (tree);
extern void assign_parms (tree);
extern void put_var_into_stack (tree, int);
extern void flush_addressof (tree);
-extern void uninitialized_vars_warning (tree);
+extern void setjmp_vars_warning (tree);
extern void setjmp_args_warning (void);
extern void mark_all_temps_used (void);
extern void init_temp_slots (void);
@@ -3089,18 +3604,17 @@ extern rtx emit_line_note (location_t);
#define ECF_LONGJMP 64
/* Nonzero if this is a syscall that makes a new process in the image of
the current one. */
-#define ECF_FORK_OR_EXEC 128
-#define ECF_SIBCALL 256
+#define ECF_SIBCALL 128
/* Nonzero if this is a call to "pure" function (like const function,
but may read memory. */
-#define ECF_PURE 512
+#define ECF_PURE 256
/* Nonzero if this is a call to a function that returns with the stack
pointer depressed. */
-#define ECF_SP_DEPRESSED 1024
+#define ECF_SP_DEPRESSED 512
/* Nonzero if this call is known to always return. */
-#define ECF_ALWAYS_RETURN 2048
+#define ECF_ALWAYS_RETURN 1024
/* Create libcall block around the call. */
-#define ECF_LIBCALL_BLOCK 4096
+#define ECF_LIBCALL_BLOCK 2048
extern int flags_from_decl_or_type (tree);
extern int call_expr_flags (tree);
@@ -3121,16 +3635,15 @@ extern bool alloca_call_p (tree);
extern tree decl_attributes (tree *, tree, int);
/* In integrate.c */
-extern void save_for_inline (tree);
extern void set_decl_abstract_flags (tree, int);
-extern void output_inline_function (tree);
extern void set_decl_origin_self (tree);
/* In stor-layout.c */
extern void set_min_and_max_values_for_integral_type (tree, int, bool);
extern void fixup_signed_type (tree);
extern void internal_reference_types (void);
-
+extern unsigned int update_alignment_for_field (record_layout_info, tree,
+ unsigned int);
/* varasm.c */
extern void make_decl_rtl (tree, const char *);
extern void make_decl_one_only (tree);
@@ -3149,6 +3662,8 @@ extern bool parse_output_constraint (const char **, int, int, int,
extern bool parse_input_constraint (const char **, int, int, int, int,
const char * const *, bool *, bool *);
extern void expand_asm_operands (tree, tree, tree, tree, int, location_t);
+extern void expand_asm_expr (tree);
+extern bool asm_op_is_mem_input (tree, tree);
extern tree resolve_asm_operand_names (tree, tree, tree);
extern int any_pending_cleanups (void);
extern void init_stmt_for_function (void);
@@ -3160,9 +3675,13 @@ extern void expand_decl (tree);
extern int expand_decl_cleanup (tree, tree);
extern int expand_decl_cleanup_eh (tree, tree, int);
extern void expand_anon_union_decl (tree, tree, tree);
-extern HOST_WIDE_INT all_cases_count (tree, int *);
-extern void check_for_full_enumeration_handling (tree);
-extern void declare_nonlocal_label (tree);
+extern int containing_blocks_have_cleanups_or_stack_level (void);
+
+/* In gimplify.c. */
+extern tree create_artificial_label (void);
+extern void gimplify_function_tree (tree);
+extern const char *get_name (tree);
+extern tree unshare_expr (tree);
/* If KIND=='I', return a suitable global initializer (constructor) name.
If KIND=='D', return a suitable global clean-up (destructor) name. */
@@ -3199,22 +3718,30 @@ extern void dwarf2out_return_save (const char *, HOST_WIDE_INT);
extern void dwarf2out_return_reg (const char *, unsigned);
-/* The type of a function that walks over tree structure. */
+/* The type of a callback function for walking over tree structure. */
typedef tree (*walk_tree_fn) (tree *, int *, void *);
+tree walk_tree (tree*, walk_tree_fn, void*, void*);
+tree walk_tree_without_duplicates (tree*, walk_tree_fn, void*);
/* In tree-dump.c */
/* Different tree dump places. When you add new tree dump places,
- extend the DUMP_FILES array in tree-dump.c */
+ extend the DUMP_FILES array in tree-dump.c. */
enum tree_dump_index
{
- TDI_all, /* dump the whole translation unit */
- TDI_class, /* dump class hierarchy */
+ TDI_none, /* No dump */
+ TDI_tu, /* dump the whole translation unit. */
+ TDI_class, /* dump class hierarchy. */
TDI_original, /* dump each function before optimizing it */
- TDI_optimized, /* dump each function after optimizing it */
+ TDI_generic, /* dump each function after genericizing it */
+ TDI_nested, /* dump each function after unnesting it */
TDI_inlined, /* dump each function after inlining
within it. */
+ TDI_vcg, /* create a VCG graph file for each
+ function's flowgraph. */
+ TDI_xml, /* dump function call graph. */
+ TDI_all, /* enable all the dumps. */
TDI_end
};
@@ -3223,6 +3750,16 @@ enum tree_dump_index
values, extend the DUMP_OPTIONS array in tree-dump.c */
#define TDF_ADDRESS (1 << 0) /* dump node addresses */
#define TDF_SLIM (1 << 1) /* don't go wild following links */
+#define TDF_RAW (1 << 2) /* don't unparse the function */
+#define TDF_DETAILS (1 << 3) /* show more detailed info about
+ each pass */
+#define TDF_STATS (1 << 4) /* dump various statistics about
+ each pass */
+#define TDF_BLOCKS (1 << 5) /* display basic block boundaries */
+#define TDF_VOPS (1 << 6) /* display virtual operands */
+#define TDF_LINENO (1 << 7) /* display statement line numbers */
+#define TDF_UID (1 << 8) /* display decl UIDs */
+
typedef struct dump_info *dump_info_p;
@@ -3263,6 +3800,8 @@ typedef enum
perm_list_kind,
temp_list_kind,
vec_kind,
+ phi_kind,
+ ssa_name_kind,
x_kind,
lang_decl,
lang_type,
@@ -3271,5 +3810,10 @@ typedef enum
extern int tree_node_counts[];
extern int tree_node_sizes[];
+
+/* True if we are in gimple form and the actions of the folders need to
+ be restricted. False if we are not in gimple form and folding is not
+ restricted to creating gimple expressions. */
+extern bool in_gimple_form;
#endif /* GCC_TREE_H */
diff --git a/gcc/unroll.c b/gcc/unroll.c
index 88e442301e6..455d906ffe0 100644
--- a/gcc/unroll.c
+++ b/gcc/unroll.c
@@ -724,10 +724,6 @@ unroll_loop (struct loop *loop, int insn_count, int strength_reduce_p)
map->insn_map = xmalloc (max_insnno * sizeof (rtx));
- /* Set this to zero, to indicate that we are doing loop unrolling,
- not function inlining. */
- map->inline_target = 0;
-
/* The register and constant maps depend on the number of registers
present, so the final maps can't be created until after
find_splittable_regs is called. However, they are needed for
diff --git a/gcc/unwind-sjlj.c b/gcc/unwind-sjlj.c
index 505bb86dc5a..08290fc081c 100644
--- a/gcc/unwind-sjlj.c
+++ b/gcc/unwind-sjlj.c
@@ -270,16 +270,13 @@ uw_init_context (struct _Unwind_Context *context)
context->fc = _Unwind_SjLj_GetContext ();
}
-/* ??? There appear to be bugs in integrate.c wrt __builtin_longjmp and
- virtual-stack-vars. An inline version of this segfaults on SPARC. */
-#define uw_install_context(CURRENT, TARGET) \
- do \
- { \
- _Unwind_SjLj_SetContext ((TARGET)->fc); \
- longjmp ((TARGET)->fc->jbuf, 1); \
- } \
- while (0)
-
+static void __attribute__((noreturn))
+uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
+ struct _Unwind_Context *target)
+{
+ _Unwind_SjLj_SetContext (target->fc);
+ longjmp (target->fc->jbuf, 1);
+}
static inline _Unwind_Ptr
uw_identify_context (struct _Unwind_Context *context)
diff --git a/gcc/value-prof.c b/gcc/value-prof.c
index 7be8db4f897..66b5c6589bd 100644
--- a/gcc/value-prof.c
+++ b/gcc/value-prof.c
@@ -34,6 +34,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "optabs.h"
#include "regs.h"
+static struct value_prof_hooks *value_prof_hooks;
+
/* In this file value profile based optimizations will be placed (none are
here just now, but they are hopefully coming soon).
@@ -174,12 +176,14 @@ insn_values_to_profile (rtx insn,
}
/* Find list of values for that we want to measure histograms. */
-void
-find_values_to_profile (unsigned *n_values, struct histogram_value **values)
+static void
+rtl_find_values_to_profile (unsigned *n_values, struct histogram_value **values)
{
rtx insn;
unsigned i;
+ life_analysis (get_insns (), NULL, PROP_DEATH_NOTES);
+
*n_values = 0;
*values = NULL;
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
@@ -193,7 +197,7 @@ find_values_to_profile (unsigned *n_values, struct histogram_value **values)
if (dump_file)
fprintf (dump_file,
"Interval counter for insn %d, range %d -- %d.\n",
- INSN_UID ((*values)[i].insn),
+ INSN_UID ((rtx)(*values)[i].insn),
(*values)[i].hdata.intvl.int_start,
((*values)[i].hdata.intvl.int_start
+ (*values)[i].hdata.intvl.steps - 1));
@@ -206,16 +210,17 @@ find_values_to_profile (unsigned *n_values, struct histogram_value **values)
if (dump_file)
fprintf (dump_file,
"Pow2 counter for insn %d.\n",
- INSN_UID ((*values)[i].insn));
- (*values)[i].n_counters = GET_MODE_BITSIZE ((*values)[i].mode) +
- ((*values)[i].hdata.pow2.may_be_other ? 1 : 0);
+ INSN_UID ((rtx)(*values)[i].insn));
+ (*values)[i].n_counters
+ = GET_MODE_BITSIZE ((*values)[i].mode)
+ + ((*values)[i].hdata.pow2.may_be_other ? 1 : 0);
break;
case HIST_TYPE_SINGLE_VALUE:
if (dump_file)
fprintf (dump_file,
"Single value counter for insn %d.\n",
- INSN_UID ((*values)[i].insn));
+ INSN_UID ((rtx)(*values)[i].insn));
(*values)[i].n_counters = 3;
break;
@@ -223,7 +228,7 @@ find_values_to_profile (unsigned *n_values, struct histogram_value **values)
if (dump_file)
fprintf (dump_file,
"Constant delta counter for insn %d.\n",
- INSN_UID ((*values)[i].insn));
+ INSN_UID ((rtx)(*values)[i].insn));
(*values)[i].n_counters = 4;
break;
@@ -231,6 +236,7 @@ find_values_to_profile (unsigned *n_values, struct histogram_value **values)
abort ();
}
}
+ allocate_reg_info (max_reg_num (), FALSE, FALSE);
}
/* Main entry point. Finds REG_VALUE_PROFILE notes from profiler and uses
@@ -313,8 +319,8 @@ find_values_to_profile (unsigned *n_values, struct histogram_value **values)
making unroller happy. Since this may grow the code significantly,
we would have to be very careful here. */
-bool
-value_profile_transformations (void)
+static bool
+rtl_value_profile_transformations (void)
{
rtx insn, next;
int changed = false;
@@ -706,3 +712,71 @@ mod_subtract_transform (rtx insn)
return true;
}
+
+/* Connection to the outside world. */
+/* Struct for IR-dependent hooks. */
+struct value_prof_hooks {
+ /* Find list of values for which we want to measure histograms. */
+ void (*find_values_to_profile) (unsigned *, struct histogram_value **);
+
+ /* Identify and exploit properties of values that are hard to analyze
+ statically. See value-prof.c for more detail. */
+ bool (*value_profile_transformations) (void);
+};
+
+/* Hooks for RTL-based versions (the only ones that currently work). */
+static struct value_prof_hooks rtl_value_prof_hooks =
+{
+ rtl_find_values_to_profile,
+ rtl_value_profile_transformations
+};
+
+void
+rtl_register_value_prof_hooks (void)
+{
+ value_prof_hooks = &rtl_value_prof_hooks;
+ if (ir_type ())
+ abort ();
+}
+
+/* Tree-based versions are stubs for now. */
+static void
+tree_find_values_to_profile (unsigned *n_values, struct histogram_value **values)
+{
+ (void)n_values;
+ (void)values;
+ abort ();
+}
+
+static bool
+tree_value_profile_transformations (void)
+{
+ abort ();
+}
+
+static struct value_prof_hooks tree_value_prof_hooks = {
+ tree_find_values_to_profile,
+ tree_value_profile_transformations
+};
+
+void
+tree_register_value_prof_hooks (void)
+{
+ value_prof_hooks = &tree_value_prof_hooks;
+ if (!ir_type ())
+ abort ();
+}
+
+/* IR-independent entry points. */
+void
+find_values_to_profile (unsigned *n_values, struct histogram_value **values)
+{
+ (value_prof_hooks->find_values_to_profile) (n_values, values);
+}
+
+bool
+value_profile_transformations (void)
+{
+ return (value_prof_hooks->value_profile_transformations) ();
+}
+
diff --git a/gcc/value-prof.h b/gcc/value-prof.h
index afbeb916eb8..16276f2b7de 100644
--- a/gcc/value-prof.h
+++ b/gcc/value-prof.h
@@ -18,6 +18,9 @@ along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
+#ifndef GCC_VALUE_PROF_H
+#define GCC_VALUE_PROF_H
+
/* Supported histogram types. */
enum hist_type
{
@@ -35,12 +38,13 @@ enum hist_type
((enum hist_type) ((COUNTER) - GCOV_FIRST_VALUE_COUNTER))
/* The value to measure. */
+/* The void *'s are either rtx or tree, depending on which IR is in use. */
struct histogram_value
{
- rtx value; /* The value to profile. */
+ void * value; /* The value to profile. */
enum machine_mode mode; /* And its mode. */
- rtx seq; /* Insns required to count the profiled value. */
- rtx insn; /* Insn before that to measure. */
+ void * seq; /* Insns required to count the profiled value. */
+ void * insn; /* Insn before that to measure. */
enum hist_type type; /* Type of information to measure. */
unsigned n_counters; /* Number of required counters. */
union
@@ -59,6 +63,48 @@ struct histogram_value
} hdata; /* Profiled information specific data. */
};
+/* Hooks registration. */
+extern void rtl_register_value_prof_hooks (void);
+extern void tree_register_value_prof_hooks (void);
+
+/* IR-independent entry points. */
extern void find_values_to_profile (unsigned *, struct histogram_value **);
extern void free_profiled_values (unsigned, struct histogram_value *);
extern bool value_profile_transformations (void);
+
+/* External declarations for edge-based profiling. */
+struct profile_hooks {
+ /* Insert code to increment an edge count. */
+ void (*gen_edge_profiler) (int, edge);
+
+ /* Insert code to increment the interval histogram counter. */
+ void (*gen_interval_profiler) (struct histogram_value *, unsigned, unsigned);
+
+ /* Insert code to increment the power of two histogram counter. */
+ void (*gen_pow2_profiler) (struct histogram_value *, unsigned, unsigned);
+
+ /* Insert code to find the most common value. */
+ void (*gen_one_value_profiler) (struct histogram_value *, unsigned, unsigned);
+
+ /* Insert code to find the most common value of a difference between two
+ evaluations of an expression. */
+ void (*gen_const_delta_profiler) (struct histogram_value *, unsigned,
+ unsigned);
+ FILE * (*profile_dump_file) (void);
+};
+
+/* In profile.c. */
+extern void init_branch_prob (void);
+extern void branch_prob (void);
+extern void end_branch_prob (void);
+extern void tree_register_profile_hooks (void);
+extern void rtl_register_profile_hooks (void);
+
+/* In tree-profile.c. */
+extern struct profile_hooks tree_profile_hooks;
+
+/* In rtl-profile.c. */
+extern struct profile_hooks rtl_profile_hooks;
+
+#endif /* GCC_VALUE_PROF_H */
+
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index d26893bdfe0..28c0c6fbdba 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -265,7 +265,7 @@ static htab_t changed_variables;
static bool emit_notes;
/* Fake variable for stack pointer. */
-GTY(()) tree frame_base_decl;
+tree frame_base_decl;
/* Local function prototypes. */
static void stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
@@ -304,7 +304,7 @@ static int variable_union_info_cmp_pos (const void *, const void *);
static int variable_union (void **, void *);
static void dataflow_set_union (dataflow_set *, dataflow_set *);
static bool variable_part_different_p (variable_part *, variable_part *);
-static bool variable_different_p (variable, variable);
+static bool variable_different_p (variable, variable, bool);
static int dataflow_set_different_1 (void **, void *);
static int dataflow_set_different_2 (void **, void *);
static bool dataflow_set_different (dataflow_set *, dataflow_set *);
@@ -1260,12 +1260,13 @@ variable_part_different_p (variable_part *vp1, variable_part *vp2)
return false;
}
-/* Return true if variables VAR1 and VAR2 are different (only the first
- location in the list of locations is checked for each offset,
- i.e. when true is returned a note should be emitted). */
+/* Return true if variables VAR1 and VAR2 are different.
+ If COMPARE_CURRENT_LOCATION is true compare also the cur_loc of each
+ variable part. */
static bool
-variable_different_p (variable var1, variable var2)
+variable_different_p (variable var1, variable var2,
+ bool compare_current_location)
{
int i;
@@ -1279,6 +1280,16 @@ variable_different_p (variable var1, variable var2)
{
if (var1->var_part[i].offset != var2->var_part[i].offset)
return true;
+ if (compare_current_location)
+ {
+ if (!((GET_CODE (var1->var_part[i].cur_loc) == REG
+ && GET_CODE (var2->var_part[i].cur_loc) == REG
+ && (REGNO (var1->var_part[i].cur_loc)
+ == REGNO (var2->var_part[i].cur_loc)))
+ || rtx_equal_p (var1->var_part[i].cur_loc,
+ var2->var_part[i].cur_loc)))
+ return true;
+ }
if (variable_part_different_p (&var1->var_part[i], &var2->var_part[i]))
return true;
if (variable_part_different_p (&var2->var_part[i], &var1->var_part[i]))
@@ -1307,7 +1318,7 @@ dataflow_set_different_1 (void **slot, void *data)
return 0;
}
- if (variable_different_p (var1, var2))
+ if (variable_different_p (var1, var2, false))
{
dataflow_set_different_value = true;
@@ -1342,7 +1353,7 @@ dataflow_set_different_2 (void **slot, void *data)
#ifdef ENABLE_CHECKING
/* If both variables are defined they have been already checked for
equivalence. */
- if (variable_different_p (var1, var2))
+ if (variable_different_p (var1, var2, false))
abort ();
#endif
@@ -2286,7 +2297,7 @@ emit_notes_for_differences_1 (void **slot, void *data)
empty_var->n_var_parts = 0;
variable_was_changed (empty_var, NULL);
}
- else if (variable_different_p (old_var, new_var))
+ else if (variable_different_p (old_var, new_var, true))
{
variable_was_changed (new_var, NULL);
}
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 780bba8a11a..4b59129b0f6 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -48,6 +48,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tm_p.h"
#include "debug.h"
#include "target.h"
+#include "tree-mudflap.h"
#include "cgraph.h"
#include "cfglayout.h"
@@ -56,10 +57,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
declarations for e.g. AIX 4.x. */
#endif
-#ifndef TRAMPOLINE_ALIGNMENT
-#define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY
-#endif
-
#ifndef ASM_STABS_OP
#define ASM_STABS_OP "\t.stabs\t"
#endif
@@ -228,7 +225,6 @@ unlikely_text_section (void)
{
in_section = in_unlikely_executed_text;
fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP);
- ASM_OUTPUT_ALIGN (asm_out_file, 2);
}
if (!unlikely_section_label_printed)
@@ -236,6 +232,10 @@ unlikely_text_section (void)
fprintf (asm_out_file, "__%s_unlikely_section:\n",
current_function_name ());
unlikely_section_label_printed = true;
+
+ /* Make sure that we have appropriate alignment for instructions
+ in this section. */
+ assemble_align (FUNCTION_BOUNDARY);
}
}
}
@@ -779,6 +779,11 @@ make_decl_rtl (tree decl, const char *asmspec)
This is necessary, for example, when one machine specific
decl attribute overrides another. */
targetm.encode_section_info (decl, DECL_RTL (decl), false);
+
+ /* Make this function static known to the mudflap runtime. */
+ if (flag_mudflap && TREE_CODE (decl) == VAR_DECL)
+ mudflap_enqueue_decl (decl);
+
return;
}
@@ -879,6 +884,10 @@ make_decl_rtl (tree decl, const char *asmspec)
If the name is changed, the macro ASM_OUTPUT_LABELREF
will have to know how to strip this information. */
targetm.encode_section_info (decl, DECL_RTL (decl), true);
+
+ /* Make this function static known to the mudflap runtime. */
+ if (flag_mudflap && TREE_CODE (decl) == VAR_DECL)
+ mudflap_enqueue_decl (decl);
}
/* Make the rtl for variable VAR be volatile.
@@ -1771,6 +1780,8 @@ assemble_static_space (unsigned HOST_WIDE_INT size)
This is done at most once per compilation.
Returns an RTX for the address of the template. */
+static GTY(()) rtx initial_trampoline;
+
#ifdef TRAMPOLINE_TEMPLATE
rtx
assemble_trampoline_template (void)
@@ -1780,6 +1791,9 @@ assemble_trampoline_template (void)
int align;
rtx symbol;
+ if (initial_trampoline)
+ return initial_trampoline;
+
/* By default, put trampoline templates in read-only data section. */
#ifdef TRAMPOLINE_SECTION
@@ -1804,7 +1818,10 @@ assemble_trampoline_template (void)
symbol = gen_rtx_SYMBOL_REF (Pmode, name);
SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOCAL;
- return symbol;
+ initial_trampoline = gen_rtx_MEM (BLKmode, symbol);
+ set_mem_align (initial_trampoline, TRAMPOLINE_ALIGNMENT);
+
+ return initial_trampoline;
}
#endif
@@ -2299,6 +2316,7 @@ compare_constant (const tree t1, const tree t2)
case NOP_EXPR:
case CONVERT_EXPR:
case NON_LVALUE_EXPR:
+ case VIEW_CONVERT_EXPR:
return compare_constant (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
default:
@@ -2404,6 +2422,10 @@ build_constant_desc (tree exp)
desc = ggc_alloc (sizeof (*desc));
desc->value = copy_constant (exp);
+ /* Propagate marked-ness to copied constant. */
+ if (flag_mudflap && mf_marked_p (exp))
+ mf_mark (desc->value);
+
/* Create a string containing the label name, in LABEL. */
labelno = const_labelno++;
ASM_GENERATE_INTERNAL_LABEL (label, "LC", labelno);
@@ -2549,15 +2571,8 @@ output_constant_def_contents (rtx symbol)
/* Output the value of EXP. */
output_constant (exp, size, align);
-}
-
-/* A constant which was deferred in its original location has been
- inserted by the RTL inliner into a different function. The
- current function's deferred constant count must be incremented. */
-void
-notice_rtl_inlining_of_deferred_constant (void)
-{
- n_deferred_constants++;
+ if (flag_mudflap)
+ mudflap_enqueue_constant (exp);
}
/* Look up EXP in the table of constant descriptors. Return the rtl
@@ -4591,7 +4606,12 @@ categorize_decl_for_section (tree decl, int reloc, int shlib)
if (TREE_CODE (decl) == FUNCTION_DECL)
return SECCAT_TEXT;
else if (TREE_CODE (decl) == STRING_CST)
- return SECCAT_RODATA_MERGE_STR;
+ {
+ if (flag_mudflap) /* or !flag_merge_constants */
+ return SECCAT_RODATA;
+ else
+ return SECCAT_RODATA_MERGE_STR;
+ }
else if (TREE_CODE (decl) == VAR_DECL)
{
if (DECL_INITIAL (decl) == NULL
@@ -5016,6 +5036,9 @@ default_file_start (void)
which emits a special section directive used to indicate whether or
not this object file needs an executable stack. This is primarily
a GNU extension to ELF but could be used on other targets. */
+
+int trampolines_created;
+
void
file_end_indicate_exec_stack (void)
{
diff --git a/gcc/varray.c b/gcc/varray.c
index 9c70b9f6dad..fc951da56e4 100644
--- a/gcc/varray.c
+++ b/gcc/varray.c
@@ -99,6 +99,7 @@ static const struct {
{ sizeof (HOST_WIDE_INT), 1 },
{ sizeof (unsigned HOST_WIDE_INT), 1 },
{ sizeof (void *), 1 },
+ { sizeof (void *), 0 },
{ sizeof (char *), 1 },
{ sizeof (struct rtx_def *), 1 },
{ sizeof (struct rtvec_def *), 1 },
@@ -106,8 +107,10 @@ static const struct {
{ sizeof (struct bitmap_head_def *), 1 },
{ sizeof (struct reg_info_def *), 0 },
{ sizeof (struct const_equiv_data), 0 },
- { sizeof (struct basic_block_def *), 0 },
+ { sizeof (struct basic_block_def *), 1 },
{ sizeof (struct elt_list *), 1 },
+ { sizeof (struct edge_def *), 1 },
+ { sizeof (tree *), 1 },
};
/* Allocate a virtual array with NUM_ELEMENT elements, each of which is
@@ -207,6 +210,26 @@ varray_underflow (varray_type va, const char *file, int line,
#endif
+
+/* Copy varray V2 into varray V1. Both arrays must be the same size
+ and type. */
+
+void
+varray_copy (varray_type v1, varray_type v2)
+{
+ size_t data_size;
+
+ if (v1->type != v2->type)
+ abort ();
+
+ if (v1->num_elements != v2->num_elements)
+ abort ();
+
+ data_size = element[v2->type].size * v2->num_elements;
+ memcpy (v1->data.c, v2->data.c, data_size);
+ v1->elements_used = v2->elements_used;
+}
+
/* Output per-varray statistics. */
#ifdef GATHER_STATISTICS
diff --git a/gcc/varray.h b/gcc/varray.h
index 57a3711bb22..371e4e70bcb 100644
--- a/gcc/varray.h
+++ b/gcc/varray.h
@@ -72,6 +72,7 @@ enum varray_data_enum {
VARRAY_DATA_HINT,
VARRAY_DATA_UHINT,
VARRAY_DATA_GENERIC,
+ VARRAY_DATA_GENERIC_NOGC,
VARRAY_DATA_CPTR,
VARRAY_DATA_RTX,
VARRAY_DATA_RTVEC,
@@ -81,6 +82,8 @@ enum varray_data_enum {
VARRAY_DATA_CONST_EQUIV,
VARRAY_DATA_BB,
VARRAY_DATA_TE,
+ VARRAY_DATA_EDGE,
+ VARRAY_DATA_TREE_PTR,
NUM_VARRAY_DATA
};
@@ -108,6 +111,8 @@ typedef union varray_data_tag GTY (()) {
tag ("VARRAY_DATA_UHINT"))) uhint[1];
PTR GTY ((length ("%0.num_elements"), use_param,
tag ("VARRAY_DATA_GENERIC"))) generic[1];
+ PTR GTY ((length ("%0.num_elements"), skip (""),
+ tag ("VARRAY_DATA_GENERIC_NOGC"))) generic_nogc[1];
char *GTY ((length ("%0.num_elements"),
tag ("VARRAY_DATA_CPTR"))) cptr[1];
rtx GTY ((length ("%0.num_elements"),
@@ -126,6 +131,10 @@ typedef union varray_data_tag GTY (()) {
tag ("VARRAY_DATA_BB"))) bb[1];
struct elt_list *GTY ((length ("%0.num_elements"),
tag ("VARRAY_DATA_TE"))) te[1];
+ struct edge_def *GTY ((length ("%0.num_elements"),
+ tag ("VARRAY_DATA_EDGE"))) e[1];
+ tree *GTY ((length ("%0.num_elements"), skip (""),
+ tag ("VARRAY_DATA_TREE_PTR"))) tp[1];
} varray_data;
/* Virtual array of pointers header. */
@@ -177,6 +186,9 @@ extern varray_type varray_init (size_t, enum varray_data_enum, const char *);
#define VARRAY_GENERIC_PTR_INIT(va, num, name) \
va = varray_init (num, VARRAY_DATA_GENERIC, name)
+#define VARRAY_GENERIC_PTR_NOGC_INIT(va, num, name) \
+ va = varray_init (num, VARRAY_DATA_GENERIC_NOGC, name)
+
#define VARRAY_CHAR_PTR_INIT(va, num, name) \
va = varray_init (num, VARRAY_DATA_CPTR, name)
@@ -204,6 +216,12 @@ extern varray_type varray_init (size_t, enum varray_data_enum, const char *);
#define VARRAY_ELT_LIST_INIT(va, num, name) \
va = varray_init (num, VARRAY_DATA_TE, name)
+#define VARRAY_EDGE_INIT(va, num, name) \
+ va = varray_init (num, VARRAY_DATA_EDGE, name)
+
+#define VARRAY_TREE_PTR_INIT(va, num, name) \
+ va = varray_init (num, VARRAY_DATA_TREE_PTR, name)
+
/* Free up memory allocated by the virtual array, but do not free any of the
elements involved. */
#define VARRAY_FREE(vp) \
@@ -222,6 +240,7 @@ extern varray_type varray_grow (varray_type, size_t);
#define VARRAY_CLEAR(VA) varray_clear(VA)
extern void varray_clear (varray_type);
+extern void varray_copy (varray_type v1, varray_type v2);
extern void dump_varray_statistics (void);
@@ -274,6 +293,7 @@ extern void varray_underflow (varray_type, const char *, int, const char *)
#define VARRAY_WIDE_INT(VA, N) VARRAY_CHECK (VA, N, hint)
#define VARRAY_UWIDE_INT(VA, N) VARRAY_CHECK (VA, N, uhint)
#define VARRAY_GENERIC_PTR(VA,N) VARRAY_CHECK (VA, N, generic)
+#define VARRAY_GENERIC_PTR_NOGC(VA,N) VARRAY_CHECK (VA, N, generic_nogc)
#define VARRAY_CHAR_PTR(VA,N) VARRAY_CHECK (VA, N, cptr)
#define VARRAY_RTX(VA, N) VARRAY_CHECK (VA, N, rtx)
#define VARRAY_RTVEC(VA, N) VARRAY_CHECK (VA, N, rtvec)
@@ -283,6 +303,8 @@ extern void varray_underflow (varray_type, const char *, int, const char *)
#define VARRAY_CONST_EQUIV(VA, N) VARRAY_CHECK (VA, N, const_equiv)
#define VARRAY_BB(VA, N) VARRAY_CHECK (VA, N, bb)
#define VARRAY_ELT_LIST(VA, N) VARRAY_CHECK (VA, N, te)
+#define VARRAY_EDGE(VA, N) VARRAY_CHECK (VA, N, e)
+#define VARRAY_TREE_PTR(VA, N) VARRAY_CHECK (VA, N, tp)
/* Push a new element on the end of VA, extending it if necessary. */
#define VARRAY_PUSH_CHAR(VA, X) VARRAY_PUSH (VA, c, X)
@@ -296,6 +318,7 @@ extern void varray_underflow (varray_type, const char *, int, const char *)
#define VARRAY_PUSH_WIDE_INT(VA, X) VARRAY_PUSH (VA, hint, X)
#define VARRAY_PUSH_UWIDE_INT(VA, X) VARRAY_PUSH (VA, uhint, X)
#define VARRAY_PUSH_GENERIC_PTR(VA, X) VARRAY_PUSH (VA, generic, X)
+#define VARRAY_PUSH_GENERIC_PTR_NOGC(VA, X) VARRAY_PUSH (VA, generic_nogc, X)
#define VARRAY_PUSH_CHAR_PTR(VA, X) VARRAY_PUSH (VA, cptr, X)
#define VARRAY_PUSH_RTX(VA, X) VARRAY_PUSH (VA, rtx, X)
#define VARRAY_PUSH_RTVEC(VA, X) VARRAY_PUSH (VA, rtvec, X)
@@ -304,6 +327,8 @@ extern void varray_underflow (varray_type, const char *, int, const char *)
#define VARRAY_PUSH_REG(VA, X) VARRAY_PUSH (VA, reg, X)
#define VARRAY_PUSH_CONST_EQUIV(VA, X) VARRAY_PUSH (VA, const_equiv, X)
#define VARRAY_PUSH_BB(VA, X) VARRAY_PUSH (VA, bb, X)
+#define VARRAY_PUSH_EDGE(VA, X) VARRAY_PUSH (VA, e, X)
+#define VARRAY_PUSH_TREE_PTR(VA, X) VARRAY_PUSH (VA, tp, X)
/* Return the last element of VA. */
#define VARRAY_TOP(VA, T) VARRAY_CHECK(VA, (VA)->elements_used - 1, T)
@@ -319,6 +344,7 @@ extern void varray_underflow (varray_type, const char *, int, const char *)
#define VARRAY_TOP_WIDE_INT(VA) VARRAY_TOP (VA, hint)
#define VARRAY_TOP_UWIDE_INT(VA) VARRAY_TOP (VA, uhint)
#define VARRAY_TOP_GENERIC_PTR(VA) VARRAY_TOP (VA, generic)
+#define VARRAY_TOP_GENERIC_PTR_NOGC(VA) VARRAY_TOP (VA, generic_nogc)
#define VARRAY_TOP_CHAR_PTR(VA) VARRAY_TOP (VA, cptr)
#define VARRAY_TOP_RTX(VA) VARRAY_TOP (VA, rtx)
#define VARRAY_TOP_RTVEC(VA) VARRAY_TOP (VA, rtvec)
@@ -327,5 +353,7 @@ extern void varray_underflow (varray_type, const char *, int, const char *)
#define VARRAY_TOP_REG(VA) VARRAY_TOP (VA, reg)
#define VARRAY_TOP_CONST_EQUIV(VA) VARRAY_TOP (VA, const_equiv)
#define VARRAY_TOP_BB(VA) VARRAY_TOP (VA, bb)
+#define VARRAY_TOP_EDGE(VA) VARRAY_TOP (VA, e)
+#define VARRAY_TOP_TREE_PTR(VA) VARRAY_TOP (VA, tp)
#endif /* ! GCC_VARRAY_H */
diff --git a/gcc/version.c b/gcc/version.c
index c5705df64a8..77f4d9de85a 100644
--- a/gcc/version.c
+++ b/gcc/version.c
@@ -5,7 +5,7 @@
please modify this string to indicate that, e.g. by putting your
organization's name in parentheses at the end of the string. */
-const char version_string[] = "3.5.0 20040413 (experimental)";
+const char version_string[] = "3.5.0-abi 20040514 (gcj-abi-2-dev-branch)";
/* This is the location of the online document giving instructions for
reporting bugs. If you distribute a modified version of GCC,
diff --git a/gcc/vmsdbgout.c b/gcc/vmsdbgout.c
index 64562518e9d..e32564946b7 100644
--- a/gcc/vmsdbgout.c
+++ b/gcc/vmsdbgout.c
@@ -2,6 +2,7 @@
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
+ Updated by Bernard W. Giroud (bgiroud@users.sourceforge.net).
This file is part of GCC.
@@ -102,11 +103,26 @@ static unsigned int file_info_table_in_use;
table. */
#define FILE_TABLE_INCREMENT 64
-static char **func_table;
+/* A structure to hold basic information for the VMS end
+ routine. */
+
+typedef struct vms_func_struct
+{
+ const char *vms_func_name;
+ unsigned funcdef_number;
+}
+vms_func_node;
+
+typedef struct vms_func_struct *vms_func_ref;
+
static unsigned int func_table_allocated;
static unsigned int func_table_in_use;
#define FUNC_TABLE_INCREMENT 256
+/* A pointer to the base of a table that contains frame description
+ information for each routine. */
+static vms_func_ref func_table;
+
/* Local pointer to the name of the main input file. Initialized in
avmdbgout_init. */
static const char *primary_filename;
@@ -778,8 +794,9 @@ write_rtnbeg (int rtnnum, int dosizeonly)
char label[MAX_ARTIFICIAL_LABEL_BYTES];
DST_ROUTINE_BEGIN rtnbeg;
DST_PROLOG prolog;
+ vms_func_ref fde = &func_table[rtnnum];
- rtnname = func_table[rtnnum];
+ rtnname = (char *)fde->vms_func_name;
rtnnamelen = strlen (rtnname);
rtnentryname = concat (rtnname, "..en", NULL);
@@ -850,7 +867,7 @@ write_rtnbeg (int rtnnum, int dosizeonly)
totsize += write_debug_header (&prolog.dst_a_prolog_header, "prolog",
dosizeonly);
- ASM_GENERATE_INTERNAL_LABEL (label, FUNC_PROLOG_LABEL, rtnnum);
+ ASM_GENERATE_INTERNAL_LABEL (label, FUNC_PROLOG_LABEL, fde->funcdef_number);
totsize += write_debug_addr (label, "prolog breakpoint addr",
dosizeonly);
}
@@ -868,6 +885,8 @@ write_rtnend (int rtnnum, int dosizeonly)
char label1[MAX_ARTIFICIAL_LABEL_BYTES];
char label2[MAX_ARTIFICIAL_LABEL_BYTES];
int totsize;
+ vms_func_ref fde = &func_table[rtnnum];
+ int corrected_rtnnum = fde->funcdef_number;
totsize = 0;
@@ -882,8 +901,8 @@ write_rtnend (int rtnnum, int dosizeonly)
totsize += write_debug_data1 (rtnend.dst_b_rtnend_unused, "unused",
dosizeonly);
- ASM_GENERATE_INTERNAL_LABEL (label1, FUNC_BEGIN_LABEL, rtnnum);
- ASM_GENERATE_INTERNAL_LABEL (label2, FUNC_END_LABEL, rtnnum);
+ ASM_GENERATE_INTERNAL_LABEL (label1, FUNC_BEGIN_LABEL, corrected_rtnnum);
+ ASM_GENERATE_INTERNAL_LABEL (label2, FUNC_END_LABEL, corrected_rtnnum);
totsize += write_debug_delta4 (label2, label1, "routine size", dosizeonly);
return totsize;
@@ -1358,6 +1377,7 @@ static void
vmsdbgout_begin_function (tree decl)
{
const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
+ vms_func_ref fde;
if (write_symbols == VMS_AND_DWARF2_DEBUG)
(*dwarf2_debug_hooks.begin_function) (decl);
@@ -1365,12 +1385,16 @@ vmsdbgout_begin_function (tree decl)
if (func_table_in_use == func_table_allocated)
{
func_table_allocated += FUNC_TABLE_INCREMENT;
- func_table = xrealloc (func_table,
- func_table_allocated * sizeof (char *));
+ func_table
+ = (vms_func_ref) xrealloc (func_table,
+ func_table_allocated * sizeof (vms_func_node));
}
/* Add the new entry to the end of the function name table. */
- func_table[func_table_in_use++] = xstrdup (name);
+ fde = &func_table[func_table_in_use++];
+ fde->vms_func_name = xstrdup (name);
+ fde->funcdef_number = current_function_funcdef_no;
+
}
static char fullname_buff [4096];
@@ -1581,7 +1605,7 @@ vmsdbgout_init (const char *main_input_filename)
/* Skip the first entry - file numbers begin at 1 */
file_info_table_in_use = 1;
- func_table = xcalloc (FUNC_TABLE_INCREMENT, sizeof (char *));
+ func_table = (vms_func_ref) xcalloc (FUNC_TABLE_INCREMENT, sizeof (vms_func_node));
func_table_allocated = FUNC_TABLE_INCREMENT;
func_table_in_use = 1;
diff --git a/include/ChangeLog b/include/ChangeLog
index e415afaaf9b..a4df91ab323 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,16 @@
+2004-05-04 Andreas Jaeger <aj@suse.de>
+
+ * demangle.h: Do not use C++ reserved keyword typename as
+ parameter for cplus_demangle_fill_builtin_type.
+
+2004-04-22 Richard Henderson <rth@redhat.com>
+
+ * hashtab.h (struct htab): Add size_prime_index.
+
+2004-04-13 Jeff Law <law@redhat.com>
+
+ * hashtab.h (htab_remove_elt_with_hash): Prototype new function.
+
2004-03-30 Zack Weinberg <zack@codesourcery.com>
* hashtab.h, splay-tree.h: Use new shorter form of GTY markers.
@@ -541,8 +554,8 @@ Tue May 30 16:53:34 2000 Andrew Cagney <cagney@b1.cygnus.com>
2000-05-06 Zack Weinberg <zack@wolery.cumb.org>
- * ansidecl.h: #define __extension__ to nothing if
- GCC_VERSION < 2008.
+ * ansidecl.h: #define __extension__ to nothing if
+ GCC_VERSION < 2008.
2000-05-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
@@ -787,8 +800,8 @@ Tue Feb 24 13:05:02 1998 Doug Evans <devans@canuck.cygnus.com>
Tue Feb 17 12:32:18 1998 Andrew Cagney <cagney@b1.cygnus.com>
* remote-sim.h (sim_fetch_register, sim_store_register): Add
- register length parameter. Functions return actual length of
- register.
+ register length parameter. Functions return actual length of
+ register.
Thu Feb 12 16:29:01 1998 Ian Lance Taylor <ian@cygnus.com>
@@ -846,7 +859,7 @@ Tue Nov 25 01:35:52 1997 Doug Evans <devans@seba.cygnus.com>
Sat Nov 22 23:34:15 1997 Andrew Cagney <cagney@b1.cygnus.com>
* remote-sim.h (sim_stop_reason): Clarify sim_signalled SIGRC
- argument.
+ argument.
Mon Nov 17 14:00:51 1997 Doug Evans <devans@seba.cygnus.com>
@@ -926,12 +939,12 @@ Fri May 23 13:43:41 1997 Fred Fish <fnf@cygnus.com>
Thu May 22 11:32:49 1997 Andrew Cagney <cagney@b1.cygnus.com>
* remote-sim.h: Review documentation. Clarify restrictions on
- when functions can be called.
+ when functions can be called.
Wed May 21 16:47:53 1997 Andrew Cagney <cagney@b1.cygnus.com>
* remote-sim.h (sim_set_profile_size): Add prototype, document as
- depreciated.
+ depreciated.
Tue May 20 09:32:22 1997 Andrew Cagney <cagney@b1.cygnus.com>
@@ -965,16 +978,16 @@ Tue Apr 22 10:24:34 1997 Fred Fish <fnf@cygnus.com>
Fri Apr 18 13:04:49 1997 Andrew Cagney <cagney@b1.cygnus.com>
* remote-sim.h (sim_stop): New interface - asynchronous
- notification of a request to stop / suspend the running
- simulation.
+ notification of a request to stop / suspend the running
+ simulation.
* remote-sim.h (enum sim_stop): Add sim_running and sim_polling as
- states for use internal to simulators.
+ states for use internal to simulators.
* callback.h (struct host_callback_strut): Put a magic number at
- the end of the struct to allow basic checking.
+ the end of the struct to allow basic checking.
(struct host_callback_struct ): Add poll_quit - so
- that the console etc can be polled at regular intervals.
+ that the console etc can be polled at regular intervals.
Thu Apr 17 02:17:12 1997 Doug Evans <dje@canuck.cygnus.com>
@@ -985,7 +998,7 @@ Thu Apr 17 02:17:12 1997 Doug Evans <dje@canuck.cygnus.com>
Wed Apr 2 17:09:12 1997 Andrew Cagney <cagney@kremvax.cygnus.com>
* remote-sim.h (sim_trace, sim_size): Make these global. They
- will go away shortly.
+ will go away shortly.
Wed Apr 2 15:23:49 1997 Doug Evans <dje@canuck.cygnus.com>
@@ -1015,7 +1028,7 @@ Mon Mar 17 19:22:12 1997 Ian Lance Taylor <ian@cygnus.com>
Mon Mar 17 14:57:55 1997 Andrew Cagney <cagney@kremvax.cygnus.com>
* remote-sim.h: New file, copied in from gdb/remote-sim.h. One
- day this will be placed in a directory of its own.
+ day this will be placed in a directory of its own.
Sat Mar 15 19:00:14 1997 Ian Lance Taylor <ian@cygnus.com>
@@ -1024,8 +1037,8 @@ Sat Mar 15 19:00:14 1997 Ian Lance Taylor <ian@cygnus.com>
Thu Mar 6 15:46:59 1997 Andrew Cagney <cagney@kremvax.cygnus.com>
* callback.h (struct host_callback_struct): Add callbacks -
- flush_stdout, write_stderr, flush_stderr, vprintf_filtered,
- evprintf_filtered. Delete redundant callbacks - printf_filtered.
+ flush_stdout, write_stderr, flush_stderr, vprintf_filtered,
+ evprintf_filtered. Delete redundant callbacks - printf_filtered.
Thu Feb 27 23:18:27 1997 Ian Lance Taylor <ian@cygnus.com>
@@ -1137,7 +1150,7 @@ Tue Jul 23 17:37:58 1996 Fred Fish <fnf@cygnus.com>
can define PRIVATE_XMALLOC and then define xmalloc and
xrealloc anyway they want.
(basename): Document in source that we can't declare the
- parameter type because it is declared inconsistently across
+ parameter type because it is declared inconsistently across
different systems.
Mon Jul 22 13:16:13 1996 Richard Henderson <rth@tamu.edu>
@@ -1932,7 +1945,7 @@ Sat Nov 30 20:46:43 1991 Steve Chamberlain (sac at rtl.cygnus.com)
Wed Nov 27 10:38:31 1991 Steve Chamberlain (sac at rtl.cygnus.com)
* internalcoff.h: (internal_scnhdr) took out #def dependency, now
- s_nreloc and s_nlnno are always long. (internal_reloc): allways
+ s_nreloc and s_nlnno are always long. (internal_reloc): allways
has an offset field now.
Fri Nov 22 08:12:58 1991 John Gilmore (gnu at cygnus.com)
diff --git a/include/demangle.h b/include/demangle.h
index 6e995e4817d..b3b8c58c517 100644
--- a/include/demangle.h
+++ b/include/demangle.h
@@ -458,7 +458,7 @@ cplus_demangle_fill_name PARAMS ((struct demangle_component *fill,
extern int
cplus_demangle_fill_builtin_type PARAMS ((struct demangle_component *fill,
- const char *typename));
+ const char *type_name));
/* Fill in a DEMANGLE_COMPONENT_OPERATOR, using the name of the
operator and the number of arguments which it takes (the latter is
diff --git a/include/hashtab.h b/include/hashtab.h
index 1af7368d338..de24dedb91b 100644
--- a/include/hashtab.h
+++ b/include/hashtab.h
@@ -1,5 +1,5 @@
/* An expandable hash tables datatype.
- Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Vladimir Makarov (vmakarov@cygnus.com).
This program is free software; you can redistribute it and/or modify
@@ -101,13 +101,13 @@ struct htab GTY(())
/* Table itself. */
PTR * GTY ((use_param, length ("%h.size"))) entries;
- /* Current size (in entries) of the hash table */
+ /* Current size (in entries) of the hash table. */
size_t size;
- /* Current number of elements including also deleted elements */
+ /* Current number of elements including also deleted elements. */
size_t n_elements;
- /* Current number of deleted elements in the table */
+ /* Current number of deleted elements in the table. */
size_t n_deleted;
/* The following member is used for debugging. Its value is number
@@ -126,6 +126,10 @@ struct htab GTY(())
PTR GTY((skip)) alloc_arg;
htab_alloc_with_arg alloc_with_arg_f;
htab_free_with_arg free_with_arg_f;
+
+ /* Current size (in entries) of the hash table, as an index into the
+ table of primes. */
+ unsigned int size_prime_index;
};
typedef struct htab *htab_t;
@@ -166,6 +170,7 @@ extern PTR *htab_find_slot_with_hash PARAMS ((htab_t, const void *,
enum insert_option));
extern void htab_clear_slot PARAMS ((htab_t, void **));
extern void htab_remove_elt PARAMS ((htab_t, void *));
+extern void htab_remove_elt_with_hash PARAMS ((htab_t, void *, hashval_t));
extern void htab_traverse PARAMS ((htab_t, htab_trav, void *));
extern void htab_traverse_noresize PARAMS ((htab_t, htab_trav, void *));
diff --git a/libada/ChangeLog b/libada/ChangeLog
index 8c62345fa82..ca8ac2bda47 100644
--- a/libada/ChangeLog
+++ b/libada/ChangeLog
@@ -1,3 +1,54 @@
+2004-04-26 Arnaud Charlet <charlet@act-europe.fr>
+
+ * Makefile.in: Put back merge of some targets to avoid code duplication.
+ Remove at the same obsolete variable GNATLIBLDFLAGS.
+
+2004-04-19 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.ac: Fix stupid brain-fade; set default_gnattools_target
+ correctly.
+ * configure: Regenerate.
+
+2004-04-19 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Makefile.in: Revert most of Arnaud's last change. Prefer anything
+ over error-prone Make abuse. Remove temporary debug code.
+ (gnatlib-zcx): New target.
+ (gnattools): Split into gnattools-native, gnattools-cross, to fix
+ previous bug; select which on the basis of default_gnattools_target.
+ (ada.all.cross): Merged with gnattools-cross target.
+ * configure.ac: Set default_gnattools_target.
+ * configure: Regenerate.
+
+2004-04-19 Arnaud Charlet <charlet@act-europe.fr>
+
+ * Makefile.in: Fix errors introduced in previous change (in particular,
+ errors when building gnattools were ignored).
+ Code clean up and simplification.
+ update comments.
+ Remove temporary debug code introduced by mistake in previous check in.
+ Prefer GNU Make syntax over complex and error-prone sh syntax.
+ (gnatlib-zcx): New target.
+ (ada.all.cross): Merged with gnattools-cross target.
+
+2004-04-17 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.ac: It's gnatlib-plain in the Makefile, not
+ gnatlib-simple; make configure match.
+ * configure: Regenerate.
+
+2004-04-14 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Makefile.in: Call gcc/ada/Makefile directly, not through the
+ intermediary of gcc/Makefile. Incorporate all necessary parts of
+ rules from gcc/ada/Make-lang.in, including extra gnatlib/gnattools
+ targets, rts-zfp, rts-ravenscar. Get needed bits of GCC
+ configuration from (new) gcc/libada-mk. Decide what gnatlib variant
+ to build in configure.ac, not here.
+ * configure.ac: Provide Makefile.in with the new information it needs,
+ such as GCC's tmake_file and xmake_file.
+ * configure: Regenerate.
+
2004-03-10 Kelley Cook <kcook@gcc.gnu.org>
* configure.in: Rename file to ...
diff --git a/libada/Makefile.in b/libada/Makefile.in
index e1565e792ec..e77f9cd958f 100644
--- a/libada/Makefile.in
+++ b/libada/Makefile.in
@@ -23,32 +23,210 @@ SHELL = @SHELL@
srcdir = @srcdir@
build = @build@
target = @target@
-enable_shared = @enable_shared@
+prefix = @prefix@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
# Nonstandard autoconf-set variables.
+enable_shared = @enable_shared@
+LN_S=@LN_S@
+target_noncanonical=@target_noncanonical@
-FLAGS_TO_PASS =
+# Variables for the user (or the top level) to override.
+objext=.o
+GNATLIBFLAGS= -W -Wall -gnatpg
+THREAD_KIND=native
+TRACE=no
+GNATLIBLDFLAGS=
+ADA_FOR_BUILD=
+ADA_FOR_TARGET=
+LDFLAGS=
+STAGE_PREFIX=
-GNATLIB = gnatlib
+# The tedious process of getting CFLAGS right.
+CFLAGS=-g
+LOOSE_WARN = -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes
+GCC_WARN_CFLAGS = $(LOOSE_WARN) $(NOCOMMON_FLAG)
-ifeq ($(build),$(target))
- GNATTOOLS = gnattools
+ADA_CFLAGS=
+T_ADA_CFLAGS=
+# HPPA is literally the only target which sets X_ADA_CFLAGS
+X_ADA_CFLAGS=@x_ada_cflags@
+ALL_ADA_CFLAGS=$(X_ADA_CFLAGS) $(T_ADA_CFLAGS) $(ADA_CFLAGS)
- ifeq ($(enable_shared),yes)
- GNATLIB = gnatlib-shared
- endif
+# Variables for gnattools.
+ADAFLAGS= -gnatpg -gnata
+ADA_INCLUDE_DIR = $(libsubdir)/adainclude
+ADA_RTL_OBJ_DIR = $(libsubdir)/adalib
-else
- GNATTOOLS = cross-gnattools ada.all.cross
+# For finding the GCC build dir, which is used far too much
+GCC_DIR=../../gcc
+# Include fragment generated by GCC configure.
+include $(GCC_DIR)/libada-mk
+# Variables based on those gleaned from the GCC makefile. :-P
+libsubdir=$(libdir)/gcc/$(target_noncanonical)/$(gcc_version)
+
+TARGET_LIBGCC2_CFLAGS=
+GNATLIBCFLAGS= -g -O2
+# Get target-specific overrides for TARGET_LIBGCC2_CFLAGS
+# and possibly GNATLIBCFLAGS. Currently this uses files
+# in gcc/config. The 'subst' call is used to rerelativize them
+# from their gcc locations. This is hackery, but there isn't
+# yet a better way to do this.
+tmake_file=$(subst /config,/../gcc/config,$(gcc_tmake_file))
+ifneq ($(tmake_file),)
+include $(tmake_file)
endif
+# Get possible host-specific override for libsubdir (ick).
+xmake_file=$(subst /config,/../gcc/config,$(gcc_xmake_file))
+ifneq ($(xmake_file),)
+include $(xmake_file)
+endif
+
+FLAGS_TO_PASS = \
+ "MAKEOVERRIDES=" \
+ "LDFLAGS=$(LDFLAGS)" \
+ "LN_S=$(LN_S)" \
+ "SHELL=$(SHELL)" \
+ "exeext=$(exeext)" \
+ "objext=$(objext)" \
+ "prefix=$(prefix)" \
+ "STAGE_PREFIX=$(STAGE_PREFIX)" \
+ "CC=$(cc_set_by_configure)" \
+ "CFLAGS=$(CFLAGS) $(WARN_CFLAGS)"
+
+ADA_FLAGS_TO_PASS = \
+ "ADA_FOR_BUILD=$(ADA_FOR_BUILD)" \
+ "ADA_INCLUDE_DIR=$(ADA_INCLUDE_DIR)" \
+ "ADA_RTL_OBJ_DIR=$(ADA_RTL_OBJ_DIR)" \
+ "ADAFLAGS=$(ADAFLAGS)" \
+ "ADA_FOR_TARGET=$(ADA_FOR_TARGET)" \
+ "INSTALL=$(INSTALL)" \
+ "INSTALL_DATA=$(INSTALL_DATA)" \
+ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)"
+
+ADA_TOOLS_FLAGS_TO_PASS=\
+ "CC=../../xgcc -B../../" \
+ "CFLAGS=$(CFLAGS)" \
+ "exeext=$(exeext)" \
+ "ADAFLAGS=$(ADAFLAGS)" \
+ "ADA_INCLUDES=-I../rts" \
+ "GNATMAKE=../../gnatmake" \
+ "GNATLINK=../../gnatlink" \
+ "GNATBIND=../../gnatbind"
+
# Rules to build gnatlib.
-gnatlib:
- $(MAKE) -C ../../gcc $(FLAGS_TO_PASS) $(GNATLIB)
+.PHONY: gnatlib gnatlib-plain gnatlib-sjlj gnatlib-zcx gnatlib-shared
+gnatlib: @default_gnatlib_target@
+
+gnatlib-plain:
+ $(MAKE) -C $(GCC_DIR)/ada $(FLAGS_TO_PASS) \
+ GNATLIBFLAGS="$(GNATLIBFLAGS)" \
+ GNATLIBCFLAGS="$(GNATLIBCFLAGS)" \
+ TARGET_LIBGCC2_CFLAGS="$(TARGET_LIBGCC2_CFLAGS)" \
+ THREAD_KIND="$(THREAD_KIND)" \
+ TRACE="$(TRACE)" \
+ gnatlib
+
+gnatlib-sjlj gnatlib-zcx gnatlib-shared:
+ $(MAKE) -C $(GCC_DIR)/ada $(FLAGS_TO_PASS) \
+ GNATLIBFLAGS="$(GNATLIBFLAGS)" \
+ GNATLIBCFLAGS="$(GNATLIBCFLAGS)" \
+ TARGET_LIBGCC2_CFLAGS="$(TARGET_LIBGCC2_CFLAGS)" \
+ THREAD_KIND="$(THREAD_KIND)" \
+ TRACE="$(TRACE)" \
+ $@
+
+.PHONY: rts-zfp rts-ravenscar
+rts-zfp rts-ravenscar:
+ $(MAKE) -C $(GCC_DIR)/ada $(FLAGS_TO_PASS) \
+ GNATMAKE=../gnatmake-cross \
+ $@
# Rules to build gnattools.
-gnattools: gnatlib
- $(MAKE) -C ../../gcc $(FLAGS_TO_PASS) $(GNATTOOLS)
+.PHONY: gnattools gnattools-native gnattools-cross regnattools
+gnattools: @default_gnattools_target@
+
+gnattools-native: gnatlib
+ $(MAKE) -C $(GCC_DIR)/ada $(FLAGS_TO_PASS) $(ADA_FLAGS_TO_PASS) \
+ ADA_INCLUDES="-I- -I../rts" \
+ CC="../../xgcc -B../../" STAGE_PREFIX=../../ gnattools1
+ $(MAKE) -C $(GCC_DIR)/ada $(ADA_TOOLS_FLAGS_TO_PASS) gnattools2
+ $(MAKE) -C $(GCC_DIR)/ada $(ADA_TOOLS_FLAGS_TO_PASS) gnattools3
+
+# For cross builds of gnattools,
+# put the host RTS dir first in the PATH to hide the default runtime
+# files that are among the sources
+# FIXME: This should be done in configure.
+RTS_DIR:=$(strip $(subst \,/,$(shell gnatls -v | grep adalib )))
+gnattools-cross: gnatlib
+ $(MAKE) -C $(GCC_DIR)/ada $(FLAGS_TO_PASS) $(ADA_FLAGS_TO_PASS) \
+ ADA_INCLUDES="-I$(RTS_DIR)../adainclude -I$(RTS_DIR)" \
+ GNATMAKE="gnatmake" \
+ GNATBIND="gnatbind" \
+ GNATLINK="gnatlink" \
+ LIBGNAT="" \
+ gnattools1-re gnattools2 gnattools4
+ # Rename cross tools to where the GCC makefile wants them when
+ # installing. FIXME: installation should be done elsewhere.
+ if [ -f $(GCC_DIR)/gnatbind$(exeext) ] ; then \
+ mv $(GCC_DIR)/gnatbind$(exeext) $(GCC_DIR)/gnatbind-cross$(exeext); \
+ fi
+ if [ -f $(GCC_DIR)/gnatbl$(exeext) ] ; then \
+ mv $(GCC_DIR)/gnatbl$(exeext) $(GCC_DIR)/gnatbl-cross$(exeext); \
+ fi
+ if [ -f $(GCC_DIR)/gnatchop$(exeext) ] ; then \
+ mv $(GCC_DIR)/gnatchop$(exeext) $(GCC_DIR)/gnatchop-cross$(exeext); \
+ fi
+ if [ -f $(GCC_DIR)/gnat$(exeext) ] ; then \
+ mv $(GCC_DIR)/gnat$(exeext) $(GCC_DIR)/gnat-cross$(exeext); \
+ fi
+ if [ -f $(GCC_DIR)/gnatkr$(exeext) ] ; then \
+ mv $(GCC_DIR)/gnatkr$(exeext) $(GCC_DIR)/gnatkr-cross$(exeext); \
+ fi
+ if [ -f $(GCC_DIR)/gnatlink$(exeext) ] ; then \
+ mv $(GCC_DIR)/gnatlink$(exeext) $(GCC_DIR)/gnatlink-cross$(exeext); \
+ fi
+ if [ -f $(GCC_DIR)/gnatls$(exeext) ] ; then \
+ mv $(GCC_DIR)/gnatls$(exeext) $(GCC_DIR)/gnatls-cross$(exeext); \
+ fi
+ if [ -f $(GCC_DIR)/gnatmake$(exeext) ] ; then \
+ mv $(GCC_DIR)/gnatmake$(exeext) $(GCC_DIR)/gnatmake-cross$(exeext); \
+ fi
+ if [ -f $(GCC_DIR)/gnatmem$(exeext) ] ; then \
+ mv $(GCC_DIR)/gnatmem$(exeext) $(GCC_DIR)/gnatmem-cross$(exeext); \
+ fi
+ if [ -f $(GCC_DIR)/gnatname$(exeext) ] ; then \
+ mv $(GCC_DIR)/gnatname$(exeext) $(GCC_DIR)/gnatname-cross$(exeext); \
+ fi
+ if [ -f $(GCC_DIR)/gnatprep$(exeext) ] ; then \
+ mv $(GCC_DIR)/gnatprep$(exeext) $(GCC_DIR)/gnatprep-cross$(exeext); \
+ fi
+ if [ -f $(GCC_DIR)/gnatxref$(exeext) ] ; then \
+ mv $(GCC_DIR)/gnatxref$(exeext) $(GCC_DIR)/gnatxref-cross$(exeext); \
+ fi
+ if [ -f $(GCC_DIR)/gnatfind$(exeext) ] ; then \
+ mv $(GCC_DIR)/gnatfind$(exeext) $(GCC_DIR)/gnatfind-cross$(exeext); \
+ fi
+ if [ -f $(GCC_DIR)/gnatclean$(exeext) ] ; then \
+ mv $(GCC_DIR)/gnatclean$(exeext) $(GCC_DIR)/gnatclean-cross$(exeext); \
+ fi
+ if [ -f $(GCC_DIR)/gnatsym$(exeext) ] ; then \
+ mv $(GCC_DIR)/gnatsym$(exeext) $(GCC_DIR)/gnatsym-cross$(exeext); \
+ fi
+ if [ -f $(GCC_DIR)/gpr2make$(exeext) ] ; then \
+ mv $(GCC_DIR)/gpr2make$(exeext) $(GCC_DIR)/gpr2make-cross$(exeext); \
+ fi
+ if [ -f $(GCC_DIR)/gprcmd$(exeext) ] ; then \
+ mv $(GCC_DIR)/gprcmd$(exeext) $(GCC_DIR)/gprcmd-cross$(exeext); \
+ fi
+
+regnattools:
+ $(MAKE) -C $(GCC_DIR)/ada $(ADA_TOOLS_FLAGS_TO_PASS) gnattools1-re
+ $(MAKE) -C $(GCC_DIR)/ada $(ADA_TOOLS_FLAGS_TO_PASS) gnattools2
+ $(MAKE) -C $(GCC_DIR)/ada $(ADA_TOOLS_FLAGS_TO_PASS) gnattools3
# Check uninstalled version.
check:
@@ -89,5 +267,5 @@ Makefile: $(srcdir)/Makefile.in config.status
config.status: $(srcdir)/configure
$(SHELL) ./config.status --recheck
-$(srcdir)/configure: @MAINT@ $(srcdir)/configure.in
+$(srcdir)/configure: @MAINT@ $(srcdir)/configure.ac
cd $(srcdir) && autoconf
diff --git a/libada/configure b/libada/configure
index 8c248092a45..1d5e30da9d5 100755
--- a/libada/configure
+++ b/libada/configure
@@ -272,7 +272,7 @@ PACKAGE_STRING=
PACKAGE_BUGREPORT=
ac_unique_file="Makefile.in"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS MAINT build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os enable_shared LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS MAINT enable_shared INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os target_noncanonical LN_S x_ada_cflags default_gnatlib_target default_gnattools_target LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@@ -881,7 +881,7 @@ esac
else
echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
fi
- cd $ac_popdir
+ cd "$ac_popdir"
done
fi
@@ -1230,9 +1230,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
-# This is an autoconf 2.5x script.
+# Command-line options.
# Very limited version of AC_MAINTAINER_MODE.
# Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
if test "${enable_maintainer_mode+set}" = set; then
@@ -1249,11 +1249,31 @@ else
MAINT='#'
fi;
-# Start of actual configure tests
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
-# Output: create a Makefile.
- ac_config_files="$ac_config_files Makefile"
+case $enable_shared in
+ yes | no) ;;
+ *)
+ enable_shared=no
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ case $pkg in
+ ada | libada)
+ enable_shared=yes ;;
+ esac
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_shared=yes
+fi;
+
+
+# Start of actual configure tests
ac_aux_dir=
for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
@@ -1280,6 +1300,86 @@ ac_config_guess="$SHELL $ac_aux_dir/config.guess"
ac_config_sub="$SHELL $ac_aux_dir/config.sub"
ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+ ./ | .// | /cC/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+done
+
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL=$ac_install_sh
+ fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
# Make sure we can run config.sub.
$ac_config_sub sun4 >/dev/null 2>&1 ||
{ { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
@@ -1363,27 +1463,115 @@ test -n "$target_alias" &&
NONENONEs,x,x, &&
program_prefix=${target_alias}-
-# Check whether --enable-shared or --disable-shared was given.
-if test "${enable_shared+set}" = set; then
- enableval="$enable_shared"
+# Autoconf M4 include file defining utility macros for complex Canadian
+# cross builds.
+
- case $enable_shared in
- yes | no) ;;
- *)
- enable_shared=no
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
- for pkg in $enableval; do
- if test "$pkg" = "ada" || test "$pkg" = "libada"; then
- enable_shared=yes
- fi
- done
- IFS="$ac_save_ifs"
- ;;
- esac
+
+
+
+####
+# _NCN_TOOL_PREFIXES: Some stuff that oughtta be done in AC_CANONICAL_SYSTEM
+# or AC_INIT.
+# These demand that AC_CANONICAL_SYSTEM be called beforehand.
+
+####
+# NCN_CHECK_TARGET_TOOL(variable, prog-to-check-for,[value-if-not-found],[path])
+# Like AC_CHECK_TOOL, but tries a prefix of the target, not the host.
+# Code is pretty much lifted from autoconf2.53.
+
+
+
+####
+# NCN_STRICT_CHECK_TOOL(variable, prog-to-check-for,[value-if-not-found],[path])
+# Like AC_CHECK_TOOL, but requires the prefix if build!=host.
+
+
+
+####
+# NCN_STRICT_CHECK_TARGET_TOOL(variable, prog-to-check-for,[value-if-not-found],[path])
+# Like NCN_CHECK_TARGET_TOOL, but requires the prefix if build!=target.
+
+
+###
+# AC_PROG_CPP_WERROR
+# Used for autoconf 2.5x to force AC_PREPROC_IFELSE to reject code which
+# triggers warnings from the preprocessor. Will be in autoconf 2.58.
+# For now, using this also overrides header checks to use only the
+# preprocessor (matches 2.13 behavior; matching 2.58's behavior is a
+# bit harder from here).
+# Eventually autoconf will default to checking headers with the compiler
+# instead, and we'll have to do this differently.
+
+# AC_PROG_CPP_WERROR
+
+# Test for GNAT.
+# We require the gnatbind program, and a compiler driver that
+# understands Ada. We use the user's CC setting, already found.
+#
+# Sets the shell variable have_gnat to yes or no as appropriate, and
+# substitutes GNATBIND.
+
+
+ case ${build_alias} in
+ "") build_noncanonical=${build} ;;
+ *) build_noncanonical=${build_alias} ;;
+esac
+
+ case ${host_alias} in
+ "") host_noncanonical=${build_noncanonical} ;;
+ *) host_noncanonical=${host_alias} ;;
+esac
+
+ case ${target_alias} in
+ "") target_noncanonical=${host_noncanonical} ;;
+ *) target_noncanonical=${target_alias} ;;
+esac
+
+
+
+# Need to pass this down for now :-P
+echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
else
- enable_shared=yes
-fi;
+ echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6
+fi
+
+
+# Determine x_ada_cflags
+case $host in
+ hppa*) x_ada_cflags=-mdisable-indexing ;;
+ *) x_ada_cflags= ;;
+esac
+
+
+# Determine what to build for 'gnatlib'
+if test $build = $target \
+ && test ${enable_shared} = yes ; then
+ # Note that build=target is almost certainly the wrong test; FIXME
+ default_gnatlib_target="gnatlib-shared"
+else
+ default_gnatlib_target="gnatlib-plain"
+fi
+
+
+# Determine what to build for 'gnattools'
+if test $build = $target ; then
+ # Note that build=target is almost certainly the wrong test; FIXME
+ default_gnattools_target="gnattools-native"
+else
+ default_gnattools_target="gnattools-cross"
+fi
+
+
+# Output: create a Makefile.
+ ac_config_files="$ac_config_files Makefile"
cat >confcache <<\_ACEOF
@@ -1842,6 +2030,7 @@ Copyright (C) 2003 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
srcdir=$srcdir
+INSTALL="$INSTALL"
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
@@ -2021,6 +2210,10 @@ s,@ECHO_N@,$ECHO_N,;t t
s,@ECHO_T@,$ECHO_T,;t t
s,@LIBS@,$LIBS,;t t
s,@MAINT@,$MAINT,;t t
+s,@enable_shared@,$enable_shared,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
s,@build@,$build,;t t
s,@build_cpu@,$build_cpu,;t t
s,@build_vendor@,$build_vendor,;t t
@@ -2033,7 +2226,11 @@ s,@target@,$target,;t t
s,@target_cpu@,$target_cpu,;t t
s,@target_vendor@,$target_vendor,;t t
s,@target_os@,$target_os,;t t
-s,@enable_shared@,$enable_shared,;t t
+s,@target_noncanonical@,$target_noncanonical,;t t
+s,@LN_S@,$LN_S,;t t
+s,@x_ada_cflags@,$x_ada_cflags,;t t
+s,@default_gnatlib_target@,$default_gnatlib_target,;t t
+s,@default_gnattools_target@,$default_gnattools_target,;t t
s,@LIBOBJS@,$LIBOBJS,;t t
s,@LTLIBOBJS@,$LTLIBOBJS,;t t
CEOF
@@ -2197,12 +2394,11 @@ case $ac_abs_builddir in
esac
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+ esac
- if test x"$ac_file" != x-; then
- { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
- rm -f "$ac_file"
- fi
# Let's still pretend it is `configure' which instantiates (i.e., don't
# use $as_me), people would be surprised to read:
# /* config.h. Generated by config.status. */
@@ -2241,6 +2437,12 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
fi;;
esac
done` || { (exit 1); exit 1; }
+
+ if test x"$ac_file" != x-; then
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ rm -f "$ac_file"
+ fi
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
sed "$ac_vpsub
@@ -2258,6 +2460,7 @@ s,@builddir@,$ac_builddir,;t t
s,@abs_builddir@,$ac_abs_builddir,;t t
s,@top_builddir@,$ac_top_builddir,;t t
s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
rm -f $tmp/stdin
if test x"$ac_file" != x-; then
diff --git a/libada/configure.ac b/libada/configure.ac
index e2d6198e4e7..1b52698cd7a 100644
--- a/libada/configure.ac
+++ b/libada/configure.ac
@@ -16,17 +16,16 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
AC_INIT
-AC_CONFIG_SRCDIR([Makefile.in])
-
-# This is an autoconf 2.5x script.
AC_PREREQ([2.59])
+AC_CONFIG_SRCDIR([Makefile.in])
+
+# Command-line options.
# Very limited version of AC_MAINTAINER_MODE.
-AC_ARG_ENABLE(
- [maintainer-mode],
- AC_HELP_STRING([--enable-maintainer-mode],
+AC_ARG_ENABLE([maintainer-mode],
+ [AC_HELP_STRING([--enable-maintainer-mode],
[enable make rules and dependencies not useful (and
- sometimes confusing) to the casual installer]),
+ sometimes confusing) to the casual installer])],
[case ${enable_maintainer_mode} in
yes) MAINT='' ;;
no) MAINT='#' ;;
@@ -36,30 +35,67 @@ AC_ARG_ENABLE(
[MAINT='#'])
AC_SUBST([MAINT])dnl
-# Start of actual configure tests
-
-# Output: create a Makefile.
-AC_CONFIG_FILES([Makefile])
-
-AC_CANONICAL_SYSTEM
-
-AC_ARG_ENABLE(shared,
-[ --disable-shared don't provide a shared libgnat],
-[
- case $enable_shared in
+AC_ARG_ENABLE([shared],
+[AC_HELP_STRING([--disable-shared],
+ [don't provide a shared libgnat])],
+[
+case $enable_shared in
yes | no) ;;
*)
enable_shared=no
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
for pkg in $enableval; do
- if test "$pkg" = "ada" || test "$pkg" = "libada"; then
- enable_shared=yes
- fi
+ case $pkg in
+ ada | libada)
+ enable_shared=yes ;;
+ esac
done
IFS="$ac_save_ifs"
;;
- esac
+esac
], [enable_shared=yes])
-AC_SUBST(enable_shared)
+AC_SUBST([enable_shared])
+
+# Start of actual configure tests
+
+AC_PROG_INSTALL
+
+AC_CANONICAL_SYSTEM
+
+sinclude(../config/acx.m4)
+_GCC_TOPLEV_NONCANONICAL_TARGET
+AC_SUBST(target_noncanonical)
+
+# Need to pass this down for now :-P
+AC_PROG_LN_S
+
+# Determine x_ada_cflags
+case $host in
+ hppa*) x_ada_cflags=-mdisable-indexing ;;
+ *) x_ada_cflags= ;;
+esac
+AC_SUBST([x_ada_cflags])
+
+# Determine what to build for 'gnatlib'
+if test $build = $target \
+ && test ${enable_shared} = yes ; then
+ # Note that build=target is almost certainly the wrong test; FIXME
+ default_gnatlib_target="gnatlib-shared"
+else
+ default_gnatlib_target="gnatlib-plain"
+fi
+AC_SUBST([default_gnatlib_target])
+
+# Determine what to build for 'gnattools'
+if test $build = $target ; then
+ # Note that build=target is almost certainly the wrong test; FIXME
+ default_gnattools_target="gnattools-native"
+else
+ default_gnattools_target="gnattools-cross"
+fi
+AC_SUBST([default_gnattools_target])
+
+# Output: create a Makefile.
+AC_CONFIG_FILES([Makefile])
AC_OUTPUT
diff --git a/libbanshee/AUTHORS b/libbanshee/AUTHORS
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/libbanshee/AUTHORS
diff --git a/libbanshee/COPYING b/libbanshee/COPYING
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/libbanshee/COPYING
diff --git a/libbanshee/COPYRIGHT b/libbanshee/COPYRIGHT
new file mode 100644
index 00000000000..af706e1ead2
--- /dev/null
+++ b/libbanshee/COPYRIGHT
@@ -0,0 +1,26 @@
+Copyright (c) 2000-2001
+ The Regents of the University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
diff --git a/libbanshee/ChangeLog b/libbanshee/ChangeLog
new file mode 100644
index 00000000000..8c0e6be8c3f
--- /dev/null
+++ b/libbanshee/ChangeLog
@@ -0,0 +1,120 @@
+2004-03-26 Andreas Jaeger <aj@suse.de>
+
+ * configure.in: Remove GCC_NO_EXECUTABLES.
+ * configure: Regenerated.
+
+2004-03-07 Daniel Berlin <dberlin@dberlin.org>
+
+ * engine/Makefile.am (AM_CFLAGS): Add -I$(top_srcddir)/../include, so we
+ can get ansidecl.h and friends.
+ * engine/array.c (array_extend): Fix unsigned/signed comparison.
+ * engine/banshee.h (struct gen_e): Just make void * when empty, instead
+ of empty struct.
+ * engine/compiler.h: Don't ever define HAVE_VARIADIC_MACROS, -pedantic
+ whines about them even when we know we can use them.
+ * engine/dot.c: constify our char *'s everywhere.
+ (declare_node): Cast &result to char * before casting to hash_data *.
+ * engine/dot.h: constify our char *'s everywhere.
+ * engine/flow-var.c: Ditto.
+ * engine/flow-var.h: Ditto.
+ * engine/flowrow-sort.c: Include ansidecl.h.
+ (get_contour): Mark unused parameter.
+ (update_upper_bound): Make comment /* instead of //.
+ (field_eq): Staticify.
+ * engine/hash.c (string_hash): Staticify.
+ (string_eq): Ditto.
+ (entry_cmp): Ditto.
+ * engine/hash.h: Move comments around.
+ (hash_table_apply): Add prototype.
+ * engine/hashset.c (INIT_TABLE_SIZE): Remove extra semicolon.
+ (EMPTY_KEY): Ditto.
+ * engine/jcollection.c (jcoll_create_chain): // -> /* comment.
+ (jcoll_accum): Staticify.
+ * engine/list.c (sort_linked_list): Staticify.
+ (compare): Use comparator_fn as last argument, not void *.
+ * engine/list.h: Declare the functions even for opaque lists.
+ (list_clear macro): don't return value.
+ * engine/setif-sort.c: Replaced with new version from banshee cvs.
+ * engine/setif-var.c: constify our char *'s.
+ * engine/setif-var.h: Ditto.
+ * engine/setst-var.c: Ditto.
+ * engine/setst-var.h: Ditto.
+ * engine/stamp.c (stamp_string): Use long, not int.
+ Cast through char *.
+ * engine/stamp.h (stamp): Long, not int.
+ * engine/term-sort.c (term_print_stats): Mark argument unused.
+ include ansidecl.h.
+ * engine/term-var.c: constify the char *'s.
+ * engine/term-var.h: Ditto.
+ * engine/ufind.h (union find update macro): Don't return uf_update's value
+ (which is void anyway).
+ * engine/util.c (ptr_hash): Return long, not int.
+ * engine/util.h (ptr_hash): Ditto.
+
+2004-02-29 Andreas Jaeger <aj@suse.de>
+
+ * configure.in: Set ac_libbanshee_warn_cflags for GCC.
+ * configure: Regenerated.
+
+ * libcompat/Makefile.am (AM_CFLAGS): Add
+ ac_libbanshee_warn_cflags.
+ * engine/Makefile.am (AM_CFLAGS): Likewise.
+ * points-to/Makefile.am (AM_CFLAGS): Likewise.
+
+ * libcompat/Makefile.in: Regenerated.
+ * engine/Makefile.in: Regenerated.
+ * points-to/Makefile.in: Regenerated.
+ * Makefile.in: Regenerated.
+
+ * libcompat/radix-tree.c: Include <stdlib.h> for calloc.
+
+2004-02-03 Daniel Berlin <dberlin@dberlin.org>
+
+ Fix PR other/12220
+ * engine/Makefile.am: Remove -fno-strict-aliasing.
+ * libcompat/Makefile.am: Ditto.
+ * points-to/Makefile.am: Ditto.
+ * configure: Regenerated.
+ * config.h.in: Ditto.
+ * Makefile.in: Ditto.
+ * engine/Makefile.am: Ditto.
+ * libcompat/Makefile.am: Ditto.
+ * points-to/Makefile.am: Ditto.
+
+2003-07-01 Daniel Berlin <dberlin@dberlin.org>
+
+ * acinclude.m4: New, copy the bool tests from gcc.
+
+ * configure.in: Use the new bool tests.
+
+ * Regenerate configure.
+
+ * engine/bool.h: Rewrite to use the part of gcc's system.h that does
+ bool type handling.
+
+2002-12-26 Daniel Berlin <dberlin@dberlin.org>
+
+ * Makefile.am: Use the same flag passing hack all other subdirs use.
+
+ * */Makefile.am: Use -fno-strict-aliasing till i get rid of the
+ type-punning.
+
+ * Regenerate configure and Makefiles.
+
+ * engine/setst-*.c: Remove nested functions.
+
+2002-11-28 Diego Novillo <dnovillo@redhat.com>
+
+ * aclocal.m4: Don't call aclocal and automake with a
+ version number suffix.
+ * Makefile.in, config.h.in, configure,
+ engine/Makefile.in, libcompat/Makefile.in,
+ points-to/Makefile.in: Regenerate.
+
+2002-11-24 Daniel Berlin <dberlin@dberlin.org>
+
+ * points-to/andersen_terms.c: Fix multi-line string literals
+
+2002-10-31 Daniel Berlin <dberlin@dberlin.org>
+
+ * Autoconf'ed, automak'ed, de-nested functified, etc.
diff --git a/libbanshee/INSTALL b/libbanshee/INSTALL
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/libbanshee/INSTALL
diff --git a/libbanshee/Makefile.am b/libbanshee/Makefile.am
new file mode 100644
index 00000000000..9b9d70b0842
--- /dev/null
+++ b/libbanshee/Makefile.am
@@ -0,0 +1,41 @@
+SUBDIRS = engine points-to libcompat
+# Work around what appears to be a GNU make bug handling MAKEFLAGS
+# values defined in terms of make variables, as is the case for CC and
+# friends when we are called from the top level Makefile.
+AM_MAKEFLAGS = \
+ "AR_FLAGS=$(AR_FLAGS)" \
+ "CC_FOR_BUILD=$(CC_FOR_BUILD)" \
+ "CFLAGS=$(CFLAGS)" \
+ "CXXFLAGS=$(CXXFLAGS)" \
+ "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
+ "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
+ "INSTALL=$(INSTALL)" \
+ "INSTALL_DATA=$(INSTALL_DATA)" \
+ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+ "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
+ "LDFLAGS=$(LDFLAGS)" \
+ "LIBCFLAGS=$(LIBCFLAGS)" \
+ "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
+ "MAKE=$(MAKE)" \
+ "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
+ "PICFLAG=$(PICFLAG)" \
+ "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
+ "SHELL=$(SHELL)" \
+ "EXPECT=$(EXPECT)" \
+ "RUNTEST=$(RUNTEST)" \
+ "RUNTESTFLAGS=$(RUNTESTFLAGS)" \
+ "exec_prefix=$(exec_prefix)" \
+ "infodir=$(infodir)" \
+ "libdir=$(libdir)" \
+ "prefix=$(prefix)" \
+ "tooldir=$(tooldir)" \
+ "AR=$(AR)" \
+ "AS=$(AS)" \
+ "CC=$(CC)" \
+ "CXX=$(CXX)" \
+ "LD=$(LD)" \
+ "LIBCFLAGS=$(LIBCFLAGS)" \
+ "NM=$(NM)" \
+ "PICFLAG=$(PICFLAG)" \
+ "RANLIB=$(RANLIB)" \
+ "DESTDIR=$(DESTDIR)"
diff --git a/libbanshee/Makefile.in b/libbanshee/Makefile.in
new file mode 100644
index 00000000000..ac898541dcd
--- /dev/null
+++ b/libbanshee/Makefile.in
@@ -0,0 +1,554 @@
+# Makefile.in generated by automake 1.7.6 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = .
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+ac_libbanshee_warn_cflags = @ac_libbanshee_warn_cflags@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build_alias = @build_alias@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+SUBDIRS = engine points-to libcompat
+# Work around what appears to be a GNU make bug handling MAKEFLAGS
+# values defined in terms of make variables, as is the case for CC and
+# friends when we are called from the top level Makefile.
+AM_MAKEFLAGS = \
+ "AR_FLAGS=$(AR_FLAGS)" \
+ "CC_FOR_BUILD=$(CC_FOR_BUILD)" \
+ "CFLAGS=$(CFLAGS)" \
+ "CXXFLAGS=$(CXXFLAGS)" \
+ "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
+ "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
+ "INSTALL=$(INSTALL)" \
+ "INSTALL_DATA=$(INSTALL_DATA)" \
+ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+ "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
+ "LDFLAGS=$(LDFLAGS)" \
+ "LIBCFLAGS=$(LIBCFLAGS)" \
+ "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
+ "MAKE=$(MAKE)" \
+ "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
+ "PICFLAG=$(PICFLAG)" \
+ "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
+ "SHELL=$(SHELL)" \
+ "EXPECT=$(EXPECT)" \
+ "RUNTEST=$(RUNTEST)" \
+ "RUNTESTFLAGS=$(RUNTESTFLAGS)" \
+ "exec_prefix=$(exec_prefix)" \
+ "infodir=$(infodir)" \
+ "libdir=$(libdir)" \
+ "prefix=$(prefix)" \
+ "tooldir=$(tooldir)" \
+ "AR=$(AR)" \
+ "AS=$(AS)" \
+ "CC=$(CC)" \
+ "CXX=$(CXX)" \
+ "LD=$(LD)" \
+ "LIBCFLAGS=$(LIBCFLAGS)" \
+ "NM=$(NM)" \
+ "PICFLAG=$(PICFLAG)" \
+ "RANLIB=$(RANLIB)" \
+ "DESTDIR=$(DESTDIR)"
+
+subdir = .
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+DIST_SOURCES =
+
+RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \
+ ps-recursive install-info-recursive uninstall-info-recursive \
+ all-recursive install-data-recursive install-exec-recursive \
+ installdirs-recursive install-recursive uninstall-recursive \
+ check-recursive installcheck-recursive
+DIST_COMMON = README ../install-sh ../missing ../mkinstalldirs AUTHORS \
+ COPYING ChangeLog INSTALL Makefile.am Makefile.in NEWS \
+ acinclude.m4 aclocal.m4 config.h.in configure configure.in
+DIST_SUBDIRS = $(SUBDIRS)
+all: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu Makefile
+Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)
+
+$(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+$(srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in acinclude.m4
+ cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+
+config.h: stamp-h1
+ @if test ! -f $@; then \
+ rm -f stamp-h1; \
+ $(MAKE) stamp-h1; \
+ else :; fi
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+ @rm -f stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status config.h
+
+$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOHEADER)
+ touch $(srcdir)/config.h.in
+
+distclean-hdr:
+ -rm -f config.h stamp-h1
+uninstall-info-am:
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @set fnord $$MAKEFLAGS; amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $$MAKEFLAGS; amf=$$2; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ if (etags --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ else \
+ include_option=--include; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && \
+ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$tags$$unique" \
+ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique
+
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = .
+distdir = $(PACKAGE)-$(VERSION)
+
+am__remove_distdir = \
+ { test ! -d $(distdir) \
+ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -fr $(distdir); }; }
+
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+
+distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ mkdir $(distdir)
+ $(mkinstalldirs) $(distdir)/..
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkinstalldirs) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ (cd $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" \
+ distdir=../$(distdir)/$$subdir \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+ -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r $(distdir)
+dist-gzip: distdir
+ $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+dist dist-all: distdir
+ $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ $(am__remove_distdir)
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf -
+ chmod -R a-w $(distdir); chmod a+w $(distdir)
+ mkdir $(distdir)/_build
+ mkdir $(distdir)/_inst
+ chmod a-w $(distdir)
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && cd $(distdir)/_build \
+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && $(mkinstalldirs) "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist-gzip \
+ && rm -f $(distdir).tar.gz \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck
+ $(am__remove_distdir)
+ @echo "$(distdir).tar.gz is ready for distribution" | \
+ sed 'h;s/./=/g;p;x;p;x'
+distuninstallcheck:
+ @cd $(distuninstallcheck_dir) \
+ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile config.h
+installdirs: installdirs-recursive
+installdirs-am:
+
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+distclean-am: clean-am distclean-generic distclean-hdr distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \
+ clean-generic clean-recursive ctags ctags-recursive dist \
+ dist-all dist-gzip distcheck distclean distclean-generic \
+ distclean-hdr distclean-recursive distclean-tags distcleancheck \
+ distdir distuninstallcheck dvi dvi-am dvi-recursive info \
+ info-am info-recursive install install-am install-data \
+ install-data-am install-data-recursive install-exec \
+ install-exec-am install-exec-recursive install-info \
+ install-info-am install-info-recursive install-man \
+ install-recursive install-strip installcheck installcheck-am \
+ installdirs installdirs-am installdirs-recursive \
+ maintainer-clean maintainer-clean-generic \
+ maintainer-clean-recursive mostlyclean mostlyclean-generic \
+ mostlyclean-recursive pdf pdf-am pdf-recursive ps ps-am \
+ ps-recursive tags tags-recursive uninstall uninstall-am \
+ uninstall-info-am uninstall-info-recursive uninstall-recursive
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libbanshee/NEWS b/libbanshee/NEWS
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/libbanshee/NEWS
diff --git a/libbanshee/README b/libbanshee/README
new file mode 100644
index 00000000000..f5e2198957b
--- /dev/null
+++ b/libbanshee/README
@@ -0,0 +1,11 @@
+This is banshee, a toolkit for constructing constraint-based program analyses.
+See the user manual in docs/banshee.ps for a complete description of banshee.
+
+This is a beta release of banshee. Although banshee has been designed to solve
+many kinds of constraints, it has only been extensively tested on
+Andersen's-style points-to analysis.
+
+banshee is distributed under the BSD license. See the COPYRIGHT file for more
+details.
+
+Send bug reports to jkodumal@cs.berkeley.edu. \ No newline at end of file
diff --git a/libbanshee/acinclude.m4 b/libbanshee/acinclude.m4
new file mode 100644
index 00000000000..8a3afa34ecb
--- /dev/null
+++ b/libbanshee/acinclude.m4
@@ -0,0 +1,27 @@
+sinclude(../config/accross.m4)
+
+dnl See if stdbool.h properly defines bool and true/false.
+AC_DEFUN(gcc_AC_HEADER_STDBOOL,
+[AC_CACHE_CHECK([for working stdbool.h],
+ ac_cv_header_stdbool_h,
+[AC_TRY_COMPILE([#include <stdbool.h>],
+[bool foo = false;],
+ac_cv_header_stdbool_h=yes, ac_cv_header_stdbool_h=no)])
+if test $ac_cv_header_stdbool_h = yes; then
+ AC_DEFINE(HAVE_STDBOOL_H, 1,
+ [Define if you have a working <stdbool.h> header file.])
+fi
+])
+
+dnl Check whether _Bool is built-in.
+AC_DEFUN(gcc_AC_C__BOOL,
+[AC_CACHE_CHECK(for built-in _Bool, gcc_cv_c__bool,
+[AC_TRY_COMPILE(,
+[_Bool foo;],
+gcc_cv_c__bool=yes, gcc_cv_c__bool=no)
+])
+if test $gcc_cv_c__bool = yes; then
+ AC_DEFINE(HAVE__BOOL, 1, [Define if the \`_Bool' type is built-in.])
+fi
+])
+
diff --git a/libbanshee/aclocal.m4 b/libbanshee/aclocal.m4
new file mode 100644
index 00000000000..d548adaaaa3
--- /dev/null
+++ b/libbanshee/aclocal.m4
@@ -0,0 +1,928 @@
+# generated automatically by aclocal 1.7.6 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
+# Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+sinclude(../config/accross.m4)
+
+dnl See if stdbool.h properly defines bool and true/false.
+AC_DEFUN(gcc_AC_HEADER_STDBOOL,
+[AC_CACHE_CHECK([for working stdbool.h],
+ ac_cv_header_stdbool_h,
+[AC_TRY_COMPILE([#include <stdbool.h>],
+[bool foo = false;],
+ac_cv_header_stdbool_h=yes, ac_cv_header_stdbool_h=no)])
+if test $ac_cv_header_stdbool_h = yes; then
+ AC_DEFINE(HAVE_STDBOOL_H, 1,
+ [Define if you have a working <stdbool.h> header file.])
+fi
+])
+
+dnl Check whether _Bool is built-in.
+AC_DEFUN(gcc_AC_C__BOOL,
+[AC_CACHE_CHECK(for built-in _Bool, gcc_cv_c__bool,
+[AC_TRY_COMPILE(,
+[_Bool foo;],
+gcc_cv_c__bool=yes, gcc_cv_c__bool=no)
+])
+if test $gcc_cv_c__bool = yes; then
+ AC_DEFINE(HAVE__BOOL, 1, [Define if the \`_Bool' type is built-in.])
+fi
+])
+
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# This macro actually does too much some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 10
+
+AC_PREREQ([2.54])
+
+# Autoconf 2.50 wants to disallow AM_ names. We explicitly allow
+# the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+ AC_REQUIRE([AC_PROG_INSTALL])dnl
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+ test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_MISSING_PROG(AMTAR, tar)
+AM_PROG_INSTALL_SH
+AM_PROG_INSTALL_STRIP
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_CC],
+ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_CXX],
+ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+])
+])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $1 | $1:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+
+# Copyright 2002 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.7"])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION so it can be traced.
+# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+ [AM_AUTOMAKE_VERSION([1.7.6])])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright 2001, 2002 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 2
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 3
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# -*- Autoconf -*-
+
+
+# Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 3
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# AM_AUX_DIR_EXPAND
+
+# Copyright 2001 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+# Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])
+
+AC_DEFUN([AM_AUX_DIR_EXPAND], [
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+
+# Copyright 2001 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+AC_SUBST(install_sh)])
+
+# AM_PROG_INSTALL_STRIP
+
+# Copyright 2001 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# -*- Autoconf -*-
+# Copyright (C) 2003 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 1
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# serial 5 -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
+ [$1], CXX, [depcc="$CXX" am_compiler_list=],
+ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ : > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored.
+ if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[ --disable-dependency-tracking Speeds up one-time builds
+ --enable-dependency-tracking Do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+#serial 2
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[for mf in $CONFIG_FILES; do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # So let's grep whole file.
+ if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue
+ # Extract the definition of DEP_FILES from the Makefile without
+ # running `make'.
+ DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n -e '/^U = / s///p' < "$mf"`
+ test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+ # We invoke sed twice because it is the simplest approach to
+ # changing $(DEPDIR) to its actual value in the expansion.
+ for file in `sed -n -e '
+ /^DEP_FILES = .*\\\\$/ {
+ s/^DEP_FILES = //
+ :loop
+ s/\\\\$//
+ p
+ n
+ /\\\\$/ b loop
+ p
+ }
+ /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+done
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 2
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+ am__include=include
+ am__quote=
+ _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ fi
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright 1997, 2000, 2001 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 5
+
+AC_PREREQ(2.52)
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])
+AC_SUBST([$1_FALSE])
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.])
+fi])])
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*-
+
+# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+AC_PREREQ([2.52])
+
+# serial 6
+
+# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS.
+AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
+
+# Add --enable-maintainer-mode option to configure.
+# From Jim Meyering
+
+# Copyright 1996, 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 2
+
+AC_DEFUN([AM_MAINTAINER_MODE],
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode is disabled by default
+ AC_ARG_ENABLE(maintainer-mode,
+[ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ USE_MAINTAINER_MODE=$enableval,
+ USE_MAINTAINER_MODE=no)
+ AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+ AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes])
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST(MAINT)dnl
+]
+)
+
+AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
+
diff --git a/libbanshee/config.h.in b/libbanshee/config.h.in
new file mode 100644
index 00000000000..7ef529c3daf
--- /dev/null
+++ b/libbanshee/config.h.in
@@ -0,0 +1,110 @@
+/* config.h.in. Generated from configure.in by autoheader. */
+
+/* Define to 1 if you have the `atexit' function. */
+#undef HAVE_ATEXIT
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+#undef HAVE_DOPRNT
+
+/* Define to 1 if you have the `dup2' function. */
+#undef HAVE_DUP2
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the `floor' function. */
+#undef HAVE_FLOOR
+
+/* Define to 1 if you have the `getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `memset' function. */
+#undef HAVE_MEMSET
+
+/* Define to 1 if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define to 1 if you have the `munmap' function. */
+#undef HAVE_MUNMAP
+
+/* Define if you have a working <stdbool.h> header file. */
+#undef HAVE_STDBOOL_H
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#undef HAVE_STDDEF_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `vprintf' function. */
+#undef HAVE_VPRINTF
+
+/* Define if the \`_Bool' type is built-in. */
+#undef HAVE__BOOL
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define as `__inline' if that's what the C compiler calls it, or to nothing
+ if it is not supported. */
+#undef inline
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+#undef size_t
diff --git a/libbanshee/configure b/libbanshee/configure
new file mode 100755
index 00000000000..11f4436b348
--- /dev/null
+++ b/libbanshee/configure
@@ -0,0 +1,5967 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.57 for engine/flowrow-sort.c 0.9.
+#
+# Report bugs to <dberlin@dberlin.org>.
+#
+# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+# Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete. It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME='engine/flowrow-sort.c'
+PACKAGE_TARNAME='engine-flowrow-sort-c'
+PACKAGE_VERSION='0.9'
+PACKAGE_STRING='engine/flowrow-sort.c 0.9'
+PACKAGE_BUGREPORT='dberlin@dberlin.org'
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE am__leading_dot CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE RANLIB ac_ct_RANLIB ac_libbanshee_warn_cflags MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT CPP EGREP LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_option in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ eval "enable_$ac_feature=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_$ac_feature='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_$ac_package='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package | sed 's/-/_/g'`
+ eval "with_$ac_package=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+ eval "$ac_envvar='$ac_optarg'"
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+ localstatedir libdir includedir oldincludedir infodir mandir
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$0" : 'X\(//\)[^/]' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+ { (exit 1); exit 1; }; }
+ else
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+ fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+ { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+ { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures engine/flowrow-sort.c 0.9 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+ cat <<_ACEOF
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --infodir=DIR info documentation [PREFIX/info]
+ --mandir=DIR man documentation [PREFIX/man]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of engine/flowrow-sort.c 0.9:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --disable-dependency-tracking Speeds up one-time builds
+ --enable-dependency-tracking Do not reject slow dependency extractors
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
+ headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <dberlin@dberlin.org>.
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ ac_popdir=`pwd`
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d $ac_dir || continue
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+ cd $ac_dir
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f $ac_srcdir/configure.gnu; then
+ echo
+ $SHELL $ac_srcdir/configure.gnu --help=recursive
+ elif test -f $ac_srcdir/configure; then
+ echo
+ $SHELL $ac_srcdir/configure --help=recursive
+ elif test -f $ac_srcdir/configure.ac ||
+ test -f $ac_srcdir/configure.in; then
+ echo
+ $ac_configure --help
+ else
+ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi
+ cd $ac_popdir
+ done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+ cat <<\_ACEOF
+engine/flowrow-sort.c configure 0.9
+generated by GNU Autoconf 2.57
+
+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by engine/flowrow-sort.c $as_me 0.9, which was
+generated by GNU Autoconf 2.57. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo = `(hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+ # Get rid of the leading space.
+ ac_sep=" "
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+{
+ (set) 2>&1 |
+ case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ sed -n \
+ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+ ;;
+ *)
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+}
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ sed "/^$/d" confdefs.h | sort
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ echo "$as_me: caught signal $ac_signal"
+ echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core core.* *.core &&
+ rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+ ' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . $cache_file;;
+ *) . ./$cache_file;;
+ esac
+ fi
+else
+ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+ sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+ eval ac_new_val="\$ac_env_${ac_var}_value"
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
+echo "$as_me: former value: $ac_old_val" >&2;}
+ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
+echo "$as_me: current value: $ac_new_val" >&2;}
+ ac_cache_corrupted=:
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+am__api_version="1.7"
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f $ac_dir/shtool; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+ ./ | .// | /cC/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+done
+
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL=$ac_install_sh
+ fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo "$as_me:$LINENO: checking whether build environment is sane" >&5
+echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" >&5
+echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ { { echo "$as_me:$LINENO: error: newly created file is older than distributed files!
+Check your system clock" >&5
+echo "$as_me: error: newly created file is older than distributed files!
+Check your system clock" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,$program_prefix,;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$,$program_suffix,;$program_transform_name"
+# Double any \ or $. echo might interpret backslashes.
+# By default was `s,x,x', remove it if useless.
+cat <<\_ACEOF >conftest.sed
+s/[\\$]/&&/g;s/;s,x,x,$//
+_ACEOF
+program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
+rm conftest.sed
+
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5
+echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AWK+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$AWK" && break
+done
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.make <<\_ACEOF
+all:
+ @echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+ SET_MAKE=
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+ # test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+ test -f $srcdir/config.status; then
+ { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
+echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE=libbanshee
+ VERSION=0.9
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_STRIP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ STRIP=$ac_ct_STRIP
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+
+
+
+ ac_config_headers="$ac_config_headers config.h"
+
+
+# Checks for programs.
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$ac_ct_CC" && break
+done
+
+ CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+ "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+ (eval $ac_compiler --version </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+ (eval $ac_compiler -v </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+ (eval $ac_compiler -V </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output" >&5
+echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+ (eval $ac_link_default) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Find the output, starting from the most likely. This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+ ;;
+ conftest.$ac_ext )
+ # This is the source file.
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ # FIXME: I believe we export ac_cv_exeext for Libtool,
+ # but it would be cool to find out if it's true. Does anybody
+ # maintain Libtool? --akim.
+ export ac_cv_exeext
+ break;;
+ * )
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ export ac_cv_exeext
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_compiler_gnu=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX 10.20 and later -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+ x|xno)
+ echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+ *)
+ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+ CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C. Since we use `exit',
+# in C++ we need to declare it. In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+ choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ for ac_declaration in \
+ ''\
+ '#include <stdlib.h>' \
+ 'extern "C" void std::exit (int) throw (); using std::exit;' \
+ 'extern "C" void std::exit (int); using std::exit;' \
+ 'extern "C" void exit (int) throw ();' \
+ 'extern "C" void exit (int);' \
+ 'void exit (int);'
+do
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+$ac_declaration
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+ echo '#ifdef __cplusplus' >>confdefs.h
+ echo $ac_declaration >>confdefs.h
+ echo '#endif' >>confdefs.h
+fi
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+ ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
+echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+ am__include=include
+ am__quote=
+ _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ fi
+fi
+
+
+echo "$as_me:$LINENO: result: $_am_result" >&5
+echo "${ECHO_T}$_am_result" >&6
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then
+ enableval="$enable_dependency_tracking"
+
+fi;
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+
+
+if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+
+
+depcc="$CC" am_compiler_list=
+
+echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ : > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored.
+ if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
+echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+
+
+if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+ ./ | .// | /cC/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+done
+
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL=$ac_install_sh
+ fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ RANLIB=$ac_ct_RANLIB
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+# Checks for libraries.
+# FIXME: Replace `main' with a function in `-llambda':
+#AC_CHECK_LIB([lambda], [main])
+# FIXME: Replace `main' with a function in `-lm':
+#AC_CHECK_LIB([m], [main])
+
+
+if test x$GCC = xyes; then
+ ac_libbanshee_warn_cflags='-W -Wall -pedantic -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes'
+fi
+
+
+echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6
+ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+ enableval="$enable_maintainer_mode"
+ USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi;
+ echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5
+echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6
+
+
+if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+# Checks for header files.
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+ then ac_cv_prog_egrep='grep -E'
+ else ac_cv_prog_egrep='egrep'
+ fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_stdc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ exit(2);
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_Header=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+
+
+
+
+for ac_header in fcntl.h limits.h stddef.h stdlib.h string.h sys/param.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+ yes:no )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+ no:yes )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+echo "$as_me:$LINENO: checking for working stdbool.h" >&5
+echo $ECHO_N "checking for working stdbool.h... $ECHO_C" >&6
+if test "${ac_cv_header_stdbool_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdbool.h>
+int
+main ()
+{
+bool foo = false;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_stdbool_h=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdbool_h=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdbool_h" >&5
+echo "${ECHO_T}$ac_cv_header_stdbool_h" >&6
+if test $ac_cv_header_stdbool_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STDBOOL_H 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for built-in _Bool" >&5
+echo $ECHO_N "checking for built-in _Bool... $ECHO_C" >&6
+if test "${gcc_cv_c__bool+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+_Bool foo;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ gcc_cv_c__bool=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gcc_cv_c__bool=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_c__bool" >&5
+echo "${ECHO_T}$gcc_cv_c__bool" >&6
+if test $gcc_cv_c__bool = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE__BOOL 1
+_ACEOF
+
+fi
+
+# Checks for typedefs, structures, and compiler characteristics.
+echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
+echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6
+if test "${ac_cv_c_const+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+ /* Ultrix mips cc rejects this. */
+ typedef int charset[2];
+ const charset x;
+ /* SunOS 4.1.1 cc rejects this. */
+ char const *const *ccp;
+ char **p;
+ /* NEC SVR4.0.2 mips cc rejects this. */
+ struct point {int x, y;};
+ static struct point const zero = {0,0};
+ /* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in
+ an arm of an if-expression whose if-part is not a constant
+ expression */
+ const char *g = "string";
+ ccp = &g + (g ? g-g : 0);
+ /* HPUX 7.0 cc rejects these. */
+ ++ccp;
+ p = (char**) ccp;
+ ccp = (char const *const *) p;
+ { /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+ }
+ { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+ }
+ { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+ }
+ { /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+ }
+ { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+ }
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_const=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_const=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
+echo "${ECHO_T}$ac_cv_c_const" >&6
+if test $ac_cv_c_const = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define const
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for inline" >&5
+echo $ECHO_N "checking for inline... $ECHO_C" >&6
+if test "${ac_cv_c_inline+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+done
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5
+echo "${ECHO_T}$ac_cv_c_inline" >&6
+case $ac_cv_c_inline in
+ inline | yes) ;;
+ no)
+cat >>confdefs.h <<\_ACEOF
+#define inline
+_ACEOF
+ ;;
+ *) cat >>confdefs.h <<_ACEOF
+#define inline $ac_cv_c_inline
+_ACEOF
+ ;;
+esac
+
+echo "$as_me:$LINENO: checking for pid_t" >&5
+echo $ECHO_N "checking for pid_t... $ECHO_C" >&6
+if test "${ac_cv_type_pid_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((pid_t *) 0)
+ return 0;
+if (sizeof (pid_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_pid_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_pid_t=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5
+echo "${ECHO_T}$ac_cv_type_pid_t" >&6
+if test $ac_cv_type_pid_t = yes; then
+ :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define pid_t int
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for size_t" >&5
+echo $ECHO_N "checking for size_t... $ECHO_C" >&6
+if test "${ac_cv_type_size_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((size_t *) 0)
+ return 0;
+if (sizeof (size_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_size_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_size_t=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
+echo "${ECHO_T}$ac_cv_type_size_t" >&6
+if test $ac_cv_type_size_t = yes; then
+ :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned
+_ACEOF
+
+fi
+
+
+# Checks for library functions.
+echo "$as_me:$LINENO: checking for working memcmp" >&5
+echo $ECHO_N "checking for working memcmp... $ECHO_C" >&6
+if test "${ac_cv_func_memcmp_working+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_memcmp_working=no
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ /* Some versions of memcmp are not 8-bit clean. */
+ char c0 = 0x40, c1 = 0x80, c2 = 0x81;
+ if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0)
+ exit (1);
+
+ /* The Next x86 OpenStep bug shows up only when comparing 16 bytes
+ or more and with at least one buffer not starting on a 4-byte boundary.
+ William Lewis provided this test program. */
+ {
+ char foo[21];
+ char bar[21];
+ int i;
+ for (i = 0; i < 4; i++)
+ {
+ char *a = foo + i;
+ char *b = bar + i;
+ strcpy (a, "--------01111111");
+ strcpy (b, "--------10000000");
+ if (memcmp (a, b, 16) >= 0)
+ exit (1);
+ }
+ exit (0);
+ }
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_memcmp_working=yes
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_func_memcmp_working=no
+fi
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_memcmp_working" >&5
+echo "${ECHO_T}$ac_cv_func_memcmp_working" >&6
+test $ac_cv_func_memcmp_working = no && LIBOBJS="$LIBOBJS memcmp.$ac_objext"
+
+
+
+for ac_header in stdlib.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+ yes:no )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+ no:yes )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_func in getpagesize
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+echo "$as_me:$LINENO: checking for working mmap" >&5
+echo $ECHO_N "checking for working mmap... $ECHO_C" >&6
+if test "${ac_cv_func_mmap_fixed_mapped+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_mmap_fixed_mapped=no
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+/* malloc might have been renamed as rpl_malloc. */
+#undef malloc
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+ Here is a matrix of mmap possibilities:
+ mmap private not fixed
+ mmap private fixed at somewhere currently unmapped
+ mmap private fixed at somewhere already mapped
+ mmap shared not fixed
+ mmap shared fixed at somewhere currently unmapped
+ mmap shared fixed at somewhere already mapped
+ For private mappings, we should verify that changes cannot be read()
+ back from the file, nor mmap's back from the file at a different
+ address. (There have been systems where private was not correctly
+ implemented like the infamous i386 svr4.0, and systems where the
+ VM page cache was not coherent with the file system buffer cache
+ like early versions of FreeBSD and possibly contemporary NetBSD.)
+ For shared mappings, we should conversely verify that changes get
+ propagated back to all the places they're supposed to be.
+
+ Grep wants private fixed already mapped.
+ The main things grep needs to know about mmap are:
+ * does it exist and is it safe to write into the mmap'd area
+ * how to use it (BSD variants) */
+
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#if !STDC_HEADERS && !HAVE_STDLIB_H
+char *malloc ();
+#endif
+
+/* This mess was copied from the GNU getpagesize.h. */
+#if !HAVE_GETPAGESIZE
+/* Assume that all systems that can run configure have sys/param.h. */
+# if !HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# if HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+int
+main ()
+{
+ char *data, *data2, *data3;
+ int i, pagesize;
+ int fd;
+
+ pagesize = getpagesize ();
+
+ /* First, make a file with some known garbage in it. */
+ data = (char *) malloc (pagesize);
+ if (!data)
+ exit (1);
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand ();
+ umask (0);
+ fd = creat ("conftest.mmap", 0600);
+ if (fd < 0)
+ exit (1);
+ if (write (fd, data, pagesize) != pagesize)
+ exit (1);
+ close (fd);
+
+ /* Next, try to mmap the file at a fixed address which already has
+ something else allocated at it. If we can, also make sure that
+ we see the same garbage. */
+ fd = open ("conftest.mmap", O_RDWR);
+ if (fd < 0)
+ exit (1);
+ data2 = (char *) malloc (2 * pagesize);
+ if (!data2)
+ exit (1);
+ data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
+ if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, fd, 0L))
+ exit (1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ exit (1);
+
+ /* Finally, make sure that changes to the mapped area do not
+ percolate back to the file as seen by read(). (This is a bug on
+ some variants of i386 svr4.0.) */
+ for (i = 0; i < pagesize; ++i)
+ *(data2 + i) = *(data2 + i) + 1;
+ data3 = (char *) malloc (pagesize);
+ if (!data3)
+ exit (1);
+ if (read (fd, data3, pagesize) != pagesize)
+ exit (1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data3 + i))
+ exit (1);
+ close (fd);
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_mmap_fixed_mapped=yes
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_mmap_fixed_mapped" >&5
+echo "${ECHO_T}$ac_cv_func_mmap_fixed_mapped" >&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_MMAP 1
+_ACEOF
+
+fi
+rm -f conftest.mmap
+
+
+for ac_func in vprintf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+echo "$as_me:$LINENO: checking for _doprnt" >&5
+echo $ECHO_N "checking for _doprnt... $ECHO_C" >&6
+if test "${ac_cv_func__doprnt+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char _doprnt (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char _doprnt ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub__doprnt) || defined (__stub____doprnt)
+choke me
+#else
+char (*f) () = _doprnt;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != _doprnt;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func__doprnt=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func__doprnt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5
+echo "${ECHO_T}$ac_cv_func__doprnt" >&6
+if test $ac_cv_func__doprnt = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DOPRNT 1
+_ACEOF
+
+fi
+
+fi
+done
+
+
+
+
+
+
+
+
+for ac_func in atexit dup2 floor getpagesize memset munmap
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+ ac_config_files="$ac_config_files Makefile engine/Makefile libcompat/Makefile points-to/Makefile"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+ (set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+} |
+ sed '
+ t clear
+ : clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+ if test -w $cache_file; then
+ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+ cat confcache >$cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[ ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[ ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_i=`echo "$ac_i" |
+ sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+ # 2. Add them.
+ ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling. Logging --version etc. is OK.
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by engine/flowrow-sort.c $as_me 0.9, which was
+generated by GNU Autoconf 2.57. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+ echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+ echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+ echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+ echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+engine/flowrow-sort.c config.status 0.9
+configured by $0, generated by GNU Autoconf 2.57,
+ with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value. By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "x$1" : 'x\([^=]*\)='`
+ ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ -*)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ *) # This is not an option, so the user has probably given explicit
+ # arguments.
+ ac_option=$1
+ ac_need_defaults=false;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --vers* | -V )
+ echo "$ac_cs_version"; exit 0 ;;
+ --he | --h)
+ # Conflict between --help and --header
+ { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; };;
+ --help | --hel | -h )
+ echo "$ac_cs_usage"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+ ac_need_defaults=false;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1" ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+ echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+ exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+#
+# INIT-COMMANDS section.
+#
+
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+_ACEOF
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+ case "$ac_config_target" in
+ # Handling of arguments.
+ "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "engine/Makefile" ) CONFIG_FILES="$CONFIG_FILES engine/Makefile" ;;
+ "libcompat/Makefile" ) CONFIG_FILES="$CONFIG_FILES libcompat/Makefile" ;;
+ "points-to/Makefile" ) CONFIG_FILES="$CONFIG_FILES points-to/Makefile" ;;
+ "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+ trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./confstat$$-$RANDOM
+ (umask 077 && mkdir $tmp)
+} ||
+{
+ echo "$me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+ # Protect against being on the right side of a sed subst in config.status.
+ sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+ s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@CYGPATH_W@,$CYGPATH_W,;t t
+s,@PACKAGE@,$PACKAGE,;t t
+s,@VERSION@,$VERSION,;t t
+s,@ACLOCAL@,$ACLOCAL,;t t
+s,@AUTOCONF@,$AUTOCONF,;t t
+s,@AUTOMAKE@,$AUTOMAKE,;t t
+s,@AUTOHEADER@,$AUTOHEADER,;t t
+s,@MAKEINFO@,$MAKEINFO,;t t
+s,@AMTAR@,$AMTAR,;t t
+s,@install_sh@,$install_sh,;t t
+s,@STRIP@,$STRIP,;t t
+s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t
+s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t
+s,@AWK@,$AWK,;t t
+s,@SET_MAKE@,$SET_MAKE,;t t
+s,@am__leading_dot@,$am__leading_dot,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@DEPDIR@,$DEPDIR,;t t
+s,@am__include@,$am__include,;t t
+s,@am__quote@,$am__quote,;t t
+s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t
+s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t
+s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t
+s,@CCDEPMODE@,$CCDEPMODE,;t t
+s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t
+s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@ac_libbanshee_warn_cflags@,$ac_libbanshee_warn_cflags,;t t
+s,@MAINTAINER_MODE_TRUE@,$MAINTAINER_MODE_TRUE,;t t
+s,@MAINTAINER_MODE_FALSE@,$MAINTAINER_MODE_FALSE,;t t
+s,@MAINT@,$MAINT,;t t
+s,@CPP@,$CPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+ cat >>$CONFIG_STATUS <<\_ACEOF
+ # Split the substitutions into bite-sized pieces for seds with
+ # small command number limits, like on Digital OSF/1 and HP-UX.
+ ac_max_sed_lines=48
+ ac_sed_frag=1 # Number of current file.
+ ac_beg=1 # First line for current file.
+ ac_end=$ac_max_sed_lines # Line after last line for current file.
+ ac_more_lines=:
+ ac_sed_cmds=
+ while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ else
+ sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ fi
+ if test ! -s $tmp/subs.frag; then
+ ac_more_lines=false
+ else
+ # The purpose of the label and of the branching condition is to
+ # speed up the sed processing (if there are no `@' at all, there
+ # is no need to browse any of the substitutions).
+ # These are the two extra sed commands mentioned above.
+ (echo ':t
+ /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+ fi
+ ac_sed_frag=`expr $ac_sed_frag + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_lines`
+ fi
+ done
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+ fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
+ esac
+
+ # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+ esac
+
+ if test x"$ac_file" != x-; then
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ rm -f "$ac_file"
+ fi
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ configure_input=
+ else
+ configure_input="$ac_file. "
+ fi
+ configure_input=$configure_input"Generated from `echo $ac_file_in |
+ sed 's,.*/,,'` by configure."
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ echo $f;;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo $f
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo $srcdir/$f
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+ rm -f $tmp/stdin
+ if test x"$ac_file" != x-; then
+ mv $tmp/out $ac_file
+ else
+ cat $tmp/out
+ rm -f $tmp/out
+ fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='[ ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
+ esac
+
+ test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ echo $f;;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo $f
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo $srcdir/$f
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+ # Remove the trailing spaces.
+ sed 's/[ ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h. The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status. Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless. Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo ' :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+ # Write a limited-size here document to $tmp/defines.sed.
+ echo ' cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+ # Speed up: don't consider the non `#define' lines.
+ echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS
+ # Work around the forget-to-reset-the-flag bug.
+ echo 't clr' >>$CONFIG_STATUS
+ echo ': clr' >>$CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+ echo 'CEOF
+ sed -f $tmp/defines.sed $tmp/in >$tmp/out
+ rm -f $tmp/in
+ mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+ rm -f conftest.defines
+ mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo ' fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo ' # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+ # Write a limited-size here document to $tmp/undefs.sed.
+ echo ' cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+ # Speed up: don't consider the non `#undef'
+ echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS
+ # Work around the forget-to-reset-the-flag bug.
+ echo 't clr' >>$CONFIG_STATUS
+ echo ': clr' >>$CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+ echo 'CEOF
+ sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+ rm -f $tmp/in
+ mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+ rm -f conftest.undefs
+ mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ echo "/* Generated by configure. */" >$tmp/config.h
+ else
+ echo "/* $ac_file. Generated by configure. */" >$tmp/config.h
+ fi
+ cat $tmp/in >>$tmp/config.h
+ rm -f $tmp/in
+ if test x"$ac_file" != x-; then
+ if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+ { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ rm -f $ac_file
+ mv $tmp/config.h $ac_file
+ fi
+ else
+ cat $tmp/config.h
+ rm -f $tmp/config.h
+ fi
+# Compute $ac_file's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $ac_file | $ac_file:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null ||
+$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X$ac_file : 'X\(//\)[^/]' \| \
+ X$ac_file : 'X\(//\)$' \| \
+ X$ac_file : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X$ac_file |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`/stamp-h$_am_stamp_count
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_COMMANDS section.
+#
+for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue
+ ac_dest=`echo "$ac_file" | sed 's,:.*,,'`
+ ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
+$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_dest" : 'X\(//\)[^/]' \| \
+ X"$ac_dest" : 'X\(//\)$' \| \
+ X"$ac_dest" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_dest" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+
+ { echo "$as_me:$LINENO: executing $ac_dest commands" >&5
+echo "$as_me: executing $ac_dest commands" >&6;}
+ case $ac_dest in
+ depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # So let's grep whole file.
+ if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+ dirpart=`(dirname "$mf") 2>/dev/null ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue
+ # Extract the definition of DEP_FILES from the Makefile without
+ # running `make'.
+ DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n -e '/^U = / s///p' < "$mf"`
+ test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+ # We invoke sed twice because it is the simplest approach to
+ # changing $(DEPDIR) to its actual value in the expansion.
+ for file in `sed -n -e '
+ /^DEP_FILES = .*\\\\$/ {
+ s/^DEP_FILES = //
+ :loop
+ s/\\\\$//
+ p
+ n
+ /\\\\$/ b loop
+ p
+ }
+ /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`(dirname "$file") 2>/dev/null ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p $dirpart/$fdir
+ else
+ as_dir=$dirpart/$fdir
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5
+echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+done
+ ;;
+ esac
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/libbanshee/configure.in b/libbanshee/configure.in
new file mode 100644
index 00000000000..a44e7000a0c
--- /dev/null
+++ b/libbanshee/configure.in
@@ -0,0 +1,44 @@
+# Process this file with autoconf to produce a configure script.
+AC_INIT(engine/flowrow-sort.c, 0.9, dberlin@dberlin.org)
+AM_INIT_AUTOMAKE(libbanshee, 0.9)
+AM_CONFIG_HEADER(config.h)
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PROG_RANLIB
+# Checks for libraries.
+# FIXME: Replace `main' with a function in `-llambda':
+#AC_CHECK_LIB([lambda], [main])
+# FIXME: Replace `main' with a function in `-lm':
+#AC_CHECK_LIB([m], [main])
+
+
+if test x$GCC = xyes; then
+ ac_libbanshee_warn_cflags='-W -Wall -pedantic -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes'
+fi
+AC_SUBST(ac_libbanshee_warn_cflags)
+
+AM_MAINTAINER_MODE
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([fcntl.h limits.h stddef.h stdlib.h string.h sys/param.h unistd.h])
+
+gcc_AC_HEADER_STDBOOL
+gcc_AC_C__BOOL
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_C_INLINE
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+
+# Checks for library functions.
+AC_FUNC_MEMCMP
+AC_FUNC_MMAP
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS([atexit dup2 floor getpagesize memset munmap])
+
+AC_OUTPUT([Makefile
+ engine/Makefile
+ libcompat/Makefile
+ points-to/Makefile])
diff --git a/libbanshee/engine/ChangeLog b/libbanshee/engine/ChangeLog
new file mode 100644
index 00000000000..5309328c6fa
--- /dev/null
+++ b/libbanshee/engine/ChangeLog
@@ -0,0 +1,14 @@
+2003-07-01 Daniel Berlin <dberlin@dberlin.org>
+
+ * bool.h: Can't include gcc's system.h and bool.h at the same time.
+
+2003-06-25 Daniel Berlin <dberlin@dberlin.org>
+
+ * compiler.h: Fix the grouping of the #if
+
+2003-02-02 Daniel Berlin <dberlin@dberlin.org>
+
+ * compiler.h: Only define HAVE_VARIADIC_MACROS if IN_GCC is not
+ defined.
+ * util.h: Add prototypes for min and max.
+
diff --git a/libbanshee/engine/Makefile.am b/libbanshee/engine/Makefile.am
new file mode 100644
index 00000000000..d3a8ba6d805
--- /dev/null
+++ b/libbanshee/engine/Makefile.am
@@ -0,0 +1,6 @@
+AM_CFLAGS = -I$(srcdir)/../libcompat -I$(top_srcdir)/../include -I$(srcdir)/../include -I. -Ddeletes= -Dtraditional= -Dsameregion= -Dparentptr= @ac_libbanshee_warn_cflags@
+noinst_LIBRARIES = libbansheeengine.a
+libbansheeengine_a_SOURCES = array.c bounds.c hash.c hashset.c list.c stamp.c \
+ufind.c util.c setif-sort.c termhash.c setif-var.c flow-var.c flowrow-sort.c \
+setst-var.c jcollection.c banshee.c buffer.c setst-sort.c term-var.c \
+term-sort.c dot.c
diff --git a/libbanshee/engine/Makefile.in b/libbanshee/engine/Makefile.in
new file mode 100644
index 00000000000..ddc83d51db3
--- /dev/null
+++ b/libbanshee/engine/Makefile.in
@@ -0,0 +1,405 @@
+# Makefile.in generated by automake 1.7.6 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+ac_libbanshee_warn_cflags = @ac_libbanshee_warn_cflags@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build_alias = @build_alias@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+AM_CFLAGS = -I$(srcdir)/../libcompat -I$(top_srcdir)/../include -I$(srcdir)/../include -I. -Ddeletes= -Dtraditional= -Dsameregion= -Dparentptr= @ac_libbanshee_warn_cflags@
+noinst_LIBRARIES = libbansheeengine.a
+libbansheeengine_a_SOURCES = array.c bounds.c hash.c hashset.c list.c stamp.c \
+ufind.c util.c setif-sort.c termhash.c setif-var.c flow-var.c flowrow-sort.c \
+setst-var.c jcollection.c banshee.c buffer.c setst-sort.c term-var.c \
+term-sort.c dot.c
+
+subdir = engine
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+
+libbansheeengine_a_AR = $(AR) cru
+libbansheeengine_a_LIBADD =
+am_libbansheeengine_a_OBJECTS = array.$(OBJEXT) bounds.$(OBJEXT) \
+ hash.$(OBJEXT) hashset.$(OBJEXT) list.$(OBJEXT) stamp.$(OBJEXT) \
+ ufind.$(OBJEXT) util.$(OBJEXT) setif-sort.$(OBJEXT) \
+ termhash.$(OBJEXT) setif-var.$(OBJEXT) flow-var.$(OBJEXT) \
+ flowrow-sort.$(OBJEXT) setst-var.$(OBJEXT) \
+ jcollection.$(OBJEXT) banshee.$(OBJEXT) buffer.$(OBJEXT) \
+ setst-sort.$(OBJEXT) term-var.$(OBJEXT) term-sort.$(OBJEXT) \
+ dot.$(OBJEXT)
+libbansheeengine_a_OBJECTS = $(am_libbansheeengine_a_OBJECTS)
+
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/../depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/array.Po ./$(DEPDIR)/banshee.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/bounds.Po ./$(DEPDIR)/buffer.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/dot.Po ./$(DEPDIR)/flow-var.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/flowrow-sort.Po ./$(DEPDIR)/hash.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/hashset.Po ./$(DEPDIR)/jcollection.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/list.Po ./$(DEPDIR)/setif-sort.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/setif-var.Po ./$(DEPDIR)/setst-sort.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/setst-var.Po ./$(DEPDIR)/stamp.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/term-sort.Po ./$(DEPDIR)/term-var.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/termhash.Po ./$(DEPDIR)/ufind.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/util.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = $(libbansheeengine_a_SOURCES)
+DIST_COMMON = ChangeLog Makefile.am Makefile.in
+SOURCES = $(libbansheeengine_a_SOURCES)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu engine/Makefile
+Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+
+AR = ar
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libbansheeengine.a: $(libbansheeengine_a_OBJECTS) $(libbansheeengine_a_DEPENDENCIES)
+ -rm -f libbansheeengine.a
+ $(libbansheeengine_a_AR) libbansheeengine.a $(libbansheeengine_a_OBJECTS) $(libbansheeengine_a_LIBADD)
+ $(RANLIB) libbansheeengine.a
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/array.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/banshee.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bounds.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dot.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flow-var.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flowrow-sort.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hashset.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jcollection.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setif-sort.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setif-var.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setst-sort.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setst-var.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stamp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/term-sort.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/term-var.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/termhash.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ufind.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@
+
+distclean-depend:
+ -rm -rf ./$(DEPDIR)
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@ fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@ fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
+uninstall-info-am:
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$tags$$unique" \
+ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique
+
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkinstalldirs) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES)
+
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+
+distclean-am: clean-am distclean-compile distclean-depend \
+ distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-noinstLIBRARIES ctags distclean distclean-compile \
+ distclean-depend distclean-generic distclean-tags distdir dvi \
+ dvi-am info info-am install install-am install-data \
+ install-data-am install-exec install-exec-am install-info \
+ install-info-am install-man install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+ uninstall-am uninstall-info-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libbanshee/engine/array.c b/libbanshee/engine/array.c
new file mode 100644
index 00000000000..be297533fa6
--- /dev/null
+++ b/libbanshee/engine/array.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <regions.h>
+#include <assert.h>
+#include <limits.h>
+#include "array.h"
+
+struct array {
+ region sameregion r;
+ void *sameregion data;
+ size_t elemsize;
+ type_t elemtype;
+ size_t nelems, nalloc;
+};
+
+struct array *new_array(region r, size_t initialsize,
+ size_t typesize, type_t typeinfo)
+{
+ struct array *a = ralloc(r, struct array);
+
+ a->r = r;
+ a->data = typed_rarrayalloc(r, initialsize, typesize, typeinfo);
+ a->elemsize = typesize;
+ a->elemtype = typeinfo;
+ a->nelems = 0;
+ a->nalloc = initialsize;
+
+ return a;
+}
+
+void *array_extend(struct array *a, int by)
+{
+ size_t oldelems = a->nelems;
+
+ if (by < 0)
+ assert(((unsigned int)-by) <= a->nelems && by != INT_MIN);
+ else if (a->nelems + by > a->nalloc)
+ {
+ size_t newsize = a->nalloc * 2 + by;
+ void *newdata = typed_rarrayalloc(a->r, newsize, a->elemsize, a->elemtype);
+
+ /* XXX: could work harder to support really large array sizes
+ (this code will fail for a->nalloc >= (max(size_t)-by)/2) */
+ assert(newsize > a->nalloc); /* die when we get really big */
+ typed_rarraycopy(newdata, a->data, a->nelems, a->elemsize, a->elemtype);
+ a->data = newdata;
+ a->nalloc = newsize;
+ }
+ a->nelems += by;
+
+ return (char *)a->data + a->elemsize * oldelems;
+}
+
+void array_reset(struct array *a)
+{
+ a->nelems = 0;
+}
+
+size_t array_length(struct array *a)
+{
+ return a->nelems;
+}
+
+void *array_data(struct array *a)
+{
+ return a->data;
+}
+
diff --git a/libbanshee/engine/array.h b/libbanshee/engine/array.h
new file mode 100644
index 00000000000..6fe3a6cf17d
--- /dev/null
+++ b/libbanshee/engine/array.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef ARRAY_H
+#define ARRAY_H
+
+/* A region-based growable array type */
+
+struct array;
+
+struct array *new_array(region r, size_t initialsize,
+ size_t typesize, type_t typeinfo);
+void *array_extend(struct array *a, int by);
+void array_reset(struct array *a);
+size_t array_length(struct array *a);
+void *array_data(struct array *a);
+
+
+#define DECLARE_ARRAY(name, type) \
+typedef struct name ## _a *name; \
+name new_ ## name(region r, size_t initialsize); \
+type *name ## _extend(name a, int by); \
+void name ## _reset(name a); \
+size_t name ## _length(name a); \
+type *name ## _data(name a);
+
+#define DEFINE_ARRAY(name, type) \
+name new_ ## name(region r, size_t initialsize) \
+{ \
+ return (name)new_array(r, initialsize, sizeof(type), rctypeof(type)); \
+} \
+type *name ## _extend(name a, int by) \
+{ \
+ return array_extend((struct array *)a, by); \
+} \
+void name ## _reset(name a) \
+{ \
+ return array_reset((struct array *)a); \
+} \
+size_t name ## _length(name a) \
+{ \
+ return array_length((struct array *)a); \
+} \
+type *name ## _data(name a) \
+{ \
+ return array_data((struct array *)a); \
+}
+
+#endif
diff --git a/libbanshee/engine/banshee.c b/libbanshee/engine/banshee.c
new file mode 100644
index 00000000000..54b975afd9c
--- /dev/null
+++ b/libbanshee/engine/banshee.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <regions.h>
+#include "banshee.h"
+#include "setif-sort.h"
+#include "setst-sort.h"
+#include "flowrow-sort.h"
+#include "setif-var.h"
+
+DEFINE_LIST(gen_e_list,gen_e)
+
+void engine_init(void)
+{
+ region_init();
+ stamp_init();
+}
+
+void engine_reset(void) deletes
+{
+ stamp_reset();
+}
+
+/* TODO */
+void engine_update(void)
+{
+}
+
+void engine_stats(FILE *f)
+{
+ setif_print_stats(f);
+ setst_print_stats(f);
+ flowrow_print_stats(f);
+}
+
+void print_constraint_graphs(FILE *f)
+{
+ setif_print_constraint_graph(f);
+}
diff --git a/libbanshee/engine/banshee.h b/libbanshee/engine/banshee.h
new file mode 100644
index 00000000000..f9b647d02a7
--- /dev/null
+++ b/libbanshee/engine/banshee.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef BANSHEE_H
+#define BANSHEE_H
+
+#include <stdio.h>
+#include "linkage.h"
+#include "stamp.h"
+#include "list.h"
+#include "util.h"
+#include "dot.h"
+
+#define ALIAS_TYPE -2
+#define VAR_TYPE -1
+#define ZERO_TYPE 0
+#define ONE_TYPE 1
+#define UNION_TYPE 2
+#define INTER_TYPE 3
+#define CONSTANT_TYPE 4
+
+EXTERN_C_BEGIN
+
+
+#ifdef NONSPEC
+
+typedef enum sort_kind
+{
+ flowrow_sort,
+ setif_sort,
+ setst_sort,
+ flowterm_sort,
+ term_sort
+} sort_kind;
+
+typedef struct gen_e
+{
+ sort_kind sort;
+} *gen_e;
+#else
+typedef void *gen_e;
+#endif
+
+DECLARE_LIST(gen_e_list,gen_e)
+
+ typedef void (*gen_e_pr_fn_ptr) (FILE *, gen_e);
+
+/*
+ Function pointers that are common to all sorts
+*/
+
+/* inclusion */
+typedef void (*incl_fn_ptr) (gen_e, gen_e) deletes;
+
+/* match constructed terms */
+typedef void (*con_match_fn_ptr) (gen_e, gen_e) deletes;
+
+/* make fresh variables */
+typedef gen_e (*fresh_fn_ptr) (const char *);
+typedef gen_e (*fresh_small_fn_ptr) (const char *);
+typedef gen_e (*fresh_large_fn_ptr) (const char *);
+
+/* get a stamp */
+typedef stamp (*get_stamp_fn_ptr) (gen_e);
+
+/* extract a term from a proj pat */
+typedef gen_e (*get_proj_fn_ptr) (gen_e_list);
+
+void engine_init(void);
+void engine_reset(void) deletes;
+void engine_update(void);
+void engine_stats(FILE *f);
+
+void print_constraint_graphs(FILE *f);
+
+EXTERN_C_END
+
+#endif /* BANSHEE_H */
diff --git a/libbanshee/engine/bool.h b/libbanshee/engine/bool.h
new file mode 100644
index 00000000000..87638fc2dc6
--- /dev/null
+++ b/libbanshee/engine/bool.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef BOOL_H
+#define BOOL_H
+#ifndef GCC_SYSTEM_H
+#include "config.h"
+/* 1 if we have _Bool. */
+#ifndef HAVE__BOOL
+# define HAVE__BOOL \
+ ((GCC_VERSION >= 3000) || (__STDC_VERSION__ >= 199901L))
+#endif
+/* Provide some sort of boolean type. We use stdbool.h if it's
+ available. This must be after all inclusion of system headers,
+ as some of them will mess us up. */
+#undef bool
+#undef true
+#undef false
+#undef TRUE
+#undef FALSE
+
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# if !HAVE__BOOL
+typedef char _Bool;
+# endif
+# define bool _Bool
+# define true 1
+# define false 0
+#endif
+
+#define TRUE true
+#define FALSE false
+#endif
+#endif
diff --git a/libbanshee/engine/bounds.c b/libbanshee/engine/bounds.c
new file mode 100644
index 00000000000..9b14b75b4d9
--- /dev/null
+++ b/libbanshee/engine/bounds.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+#include "bounds.h"
+
+struct bounds
+{
+ hash_set set;
+ gen_e_list elems;
+};
+
+bounds bounds_create(region r)
+{
+ bounds result;
+
+ result = ralloc(r, struct bounds);
+ result->set = hs_create(r);
+ result->elems = new_gen_e_list(r);
+
+ return result;
+}
+
+gen_e_list bounds_exprs(bounds b)
+{
+ return b->elems;
+}
+
+bool bounds_add(bounds b, gen_e e, stamp s)
+{
+ if (hs_member(b->set, s))
+ return TRUE;
+
+ else
+ {
+ gen_e_list_cons(e,b->elems);
+ return FALSE;
+ }
+}
+
+bool bounds_empty(bounds b)
+{
+ return (gen_e_list_empty(b->elems));
+}
+
+bool bounds_query(bounds b, stamp x)
+{
+ return (hs_query(b->set, x));
+}
+
+void bounds_set(bounds b,gen_e_list l)
+{
+ b->elems = l;
+}
+
+void bounds_delete(bounds b)
+{
+ hs_delete(b->set);
+}
+
+
diff --git a/libbanshee/engine/bounds.h b/libbanshee/engine/bounds.h
new file mode 100644
index 00000000000..8b52247b362
--- /dev/null
+++ b/libbanshee/engine/bounds.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef BOUNDS_H
+#define BOUNDS_H
+
+#include "linkage.h"
+#include "banshee.h"
+#include "stamp.h"
+#include "hashset.h"
+
+EXTERN_C_BEGIN
+
+typedef struct bounds *bounds;
+
+bounds bounds_create(region r);
+
+gen_e_list bounds_exprs(bounds);
+
+/* returns true if the bound was already present */
+bool bounds_add(bounds,gen_e,stamp);
+bool bounds_query(bounds,stamp);
+bool bounds_empty(bounds);
+void bounds_delete(bounds);
+void bounds_set(bounds,gen_e_list);
+
+EXTERN_C_END
+
+#endif /* BOUNDS_H */
diff --git a/libbanshee/engine/buffer.c b/libbanshee/engine/buffer.c
new file mode 100644
index 00000000000..68f062d365c
--- /dev/null
+++ b/libbanshee/engine/buffer.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include "buffer.h"
+
+/* Invariant: buffer always null-terminated */
+struct growbuf
+{
+ region r;
+ unsigned int maxsize, cursize;
+ char *buffer;
+};
+
+/* Make a new buffer with initial size */
+growbuf growbuf_new(region r, int size)
+{
+ growbuf b = ralloc(r, struct growbuf);
+
+ assert(size > 0);
+ b->r = r;
+ b->maxsize = size; /* Force some growth! */
+ b->cursize = 1;
+ b->buffer = rstralloc(r, size);
+ b->buffer[0] = '\0';
+ return b;
+}
+
+/* Empty a buffer */
+void growbuf_reset(growbuf b)
+{
+ assert(b->maxsize > 0);
+ b->cursize = 1;
+ b->buffer[0] = '\0';
+}
+
+/* Print to a buffer */
+int gprintf(growbuf b, const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ return gvprintf(b, fmt, args);
+}
+
+/* Print to a buffer */
+int gvprintf(growbuf b, const char *fmt, va_list args)
+{
+ int nchars;
+
+ if (!fmt) /* Bug (?)/feature of vnsprintf -- printing \0 returns -1,
+ goes into infinite loop. */
+ return 0;
+ while (1)
+ {
+ char *bufStart;
+ int sizeLeft;
+
+ bufStart = b->buffer + b->cursize - 1; /* chop trailing \0 */
+ sizeLeft = b->maxsize - b->cursize + 1; /* +1 size we're chooping
+ the trailing \0 */
+ assert(*bufStart == '\0');
+ nchars = vsnprintf(bufStart, sizeLeft, fmt, args);
+ if (nchars > -1 && nchars < sizeLeft)
+ {
+ b->cursize += nchars; /* nchars doesn't include \0,
+ but we overwrote our \0 */
+ break;
+ }
+ else
+ {
+ /* How much room do we need? In the new glibc, nchars
+ tells us how much (not including the trailing null).
+ So we need the current size, -1 since we'll remove the null,
+ plus the new size, plus 1 for the new null. */
+ int newSize = (nchars > -1) ? b->cursize - 1 + nchars + 1
+ : b->maxsize * 2;
+ char *newBuf;
+
+ /* fprintf(stderr, "Reallocating buffer, newSize=%d\n", newSize); */
+ newBuf = rstralloc(b->r, newSize);
+ memcpy(newBuf, b->buffer, b->cursize);
+ newBuf[b->cursize-1] = '\0'; /* vsnprintf has printed something! */
+ b->buffer = newBuf;
+ b->maxsize = newSize;
+ /* b->cursize unchanged */
+ }
+ }
+ return nchars;
+}
+
+/* Get the contents of a buffer */
+char *growbuf_contents(growbuf b)
+{
+ return b->buffer;
+}
+
+bool growbuf_empty(growbuf b)
+{
+ return b->cursize == 1; /* Buffer always null terminated */
+}
diff --git a/libbanshee/engine/buffer.h b/libbanshee/engine/buffer.h
new file mode 100644
index 00000000000..c270ade32c3
--- /dev/null
+++ b/libbanshee/engine/buffer.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef BUFFER_H
+#define BUFFER_H
+
+/*
+ * Growable buffers
+ *
+ * Always null terminated.
+ */
+
+#include <stdarg.h>
+#include "bool.h"
+#include "regions.h"
+#include "linkage.h"
+
+EXTERN_C_BEGIN
+
+typedef struct growbuf *growbuf;
+
+growbuf growbuf_new(region, int); /* Make a new buffer with initial size */
+void growbuf_reset(growbuf); /* Empty a buffer */
+int gprintf(growbuf, const char *, ...); /* Print to a buffer */
+int gvprintf(growbuf, const char *, va_list); /* Print to a buffer */
+char *growbuf_contents(growbuf); /* Get the contents of a buffer */
+bool growbuf_empty(growbuf); /* Return true iff buffer is empty */
+
+EXTERN_C_END
+
+#endif
diff --git a/libbanshee/engine/compiler.h b/libbanshee/engine/compiler.h
new file mode 100644
index 00000000000..6c90a63d26c
--- /dev/null
+++ b/libbanshee/engine/compiler.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef COMPILER_H
+#define COMPILER_H
+
+# if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+# define HAVE_C99
+# endif
+
+# if 0
+/*(defined(__GNUC__) || defined(HAVE_C99)) && !defined (IN_GCC) */
+# define HAVE_VARIADIC_MACROS
+# endif
+
+
+# if !defined(__GNUC__) && !defined(__attribute__)
+# define __attribute__(attributes)
+# endif
+
+#endif /* !COMPILER_H */
diff --git a/libbanshee/engine/dot.c b/libbanshee/engine/dot.c
new file mode 100644
index 00000000000..73c772fee53
--- /dev/null
+++ b/libbanshee/engine/dot.c
@@ -0,0 +1,362 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <assert.h>
+#include <regions.h>
+#include "dot.h"
+#include "hash.h"
+
+static FILE *of;
+static hash_table node_hash_table;
+static region dot_region;
+static int node_count;
+static const char *edge_op;
+
+static void print_n_attrs(node_attr *attrs, int n)
+{
+ int i;
+ fputc('[',of);
+
+ for (i = 0; i < n; i++)
+ {
+ const char *name;
+ switch (attrs[i].name)
+ {
+ case n_color:
+ name = "color";
+ break;
+ case n_fontcolor:
+ name = "fontcolor";
+ break;
+ case n_fontname:
+ name = "fontname";
+ break;
+ case n_fontsize:
+ name = "fontsize";
+ break;
+ case n_height:
+ name = "height";
+ break;
+ case n_width:
+ name = "width";
+ break;
+ case n_label:
+ name = "label";
+ break;
+ case n_layer:
+ name = "layer";
+ break;
+ case n_shape:
+ name = "shape";
+ break;
+ case n_shapefile:
+ name = "shapefile";
+ break;
+ case n_style:
+ name = "style";
+ break;
+ default:
+ name = "";
+ assert(0);
+ break;
+ }
+ if (i > 0)
+ fputc(',',of);
+ fprintf(of,"%s = %s",name,attrs[i].value);
+ }
+
+ fputc(']',of);
+}
+
+static void print_e_attrs(edge_attr *attrs, int n)
+{
+ int i;
+ fputc('[',of);
+ for (i = 0; i < n; i++)
+ {
+ const char *name;
+ switch(attrs[i].name)
+ {
+ case e_color:
+ name = "color";
+ break;
+ case e_decorate:
+ name = "decorate";
+ break;
+ case e_dir:
+ name = "dir";
+ break;
+ case e_fontcolor:
+ name = "fontcolor";
+ break;
+ case e_fontname:
+ name = "fontname";
+ break;
+ case e_fontsize:
+ name = "fontsize";
+ break;
+ case e_id:
+ name = "id";
+ break;
+ case e_label:
+ name = "label";
+ break;
+ case e_layer:
+ name = "layer";
+ break;
+ case e_minlen:
+ name = "minlen";
+ break;
+ case e_style:
+ name = "style";
+ break;
+ case e_weight:
+ name = "weight";
+ break;
+ default :
+ name = "";
+ assert(0);
+ break;
+ }
+ if (i > 0)
+ fputc(',',of);
+ fprintf(of,"%s = %s",name,attrs[i].value);
+ }
+ fputc(']',of);
+}
+
+static void print_g_attrs(graph_attr *attrs, int n)
+{
+ int i;
+ fputc('[',of);
+
+ for (i = 0; i < n; i++)
+ {
+ const char *name;
+ switch (attrs[i].name)
+ {
+ case g_center:
+ name = "center";
+ break;
+ case g_clusterrank:
+ name = "clusterrank";
+ break;
+ case g_color:
+ name = "color";
+ break;
+ case g_concentrate:
+ name = "concentrate";
+ break;
+ case g_fontcolor:
+ name = "fontcolor";
+ break;
+ case g_fontname:
+ name = "fontname";
+ break;
+ case g_fontsize:
+ name = "fontsize";
+ break;
+ case g_label:
+ name = "label";
+ break;
+ case g_layerseq:
+ name = "layerseq";
+ break;
+ case g_margin:
+ name = "margin";
+ break;
+ case g_mclimit:
+ name = "mclimit";
+ break;
+ case g_nodesep:
+ name = "nodesep";
+ break;
+ case g_nslimit:
+ name = "nslimit";
+ break;
+ case g_ordering:
+ name = "ordering";
+ break;
+ case g_orientation:
+ name = "orientation";
+ break;
+ case g_page:
+ name = "page";
+ break;
+ case g_rank:
+ name = "rank";
+ break;
+ case g_rankdir:
+ name = "rankdir";
+ break;
+ case g_ranksep:
+ name = "ranksep";
+ break;
+ case g_ratio:
+ name = "ratio";
+ break;
+ case g_size:
+ name = "size";
+ break;
+ default :
+ name = "";
+ assert(0);
+ break;
+ }
+ if (i > 0)
+ fputc(',',of);
+ fprintf(of,"%s = %s",name,attrs[i].value);
+ }
+ fputc(']',of);
+}
+
+
+void dot_start(FILE *to,const char *name,bool is_directed,bool is_strict)
+{
+ const char *graph_type,*strict;
+
+
+ node_count = 0;
+ dot_region = newregion();
+ node_hash_table = make_string_hash_table(dot_region,8,TRUE);
+ of = to;
+
+ if (is_directed)
+ {
+ edge_op = "->";
+ graph_type = "digraph";
+ }
+ else
+ {
+ edge_op = "--";
+ graph_type = "graph";
+ }
+
+ if (is_strict)
+ strict = "strict";
+ else
+ strict = "";
+
+ fprintf(of,"%s %s %s{\n",strict,graph_type,name);
+
+}
+
+void dot_global_graph_style(graph_attr *attrs, int n)
+{
+ fputs("graph ",of);
+ print_g_attrs(attrs,n);
+ fputc(';',of);
+ fputc('\n',of);
+}
+
+void dot_global_edge_style(edge_attr *attrs, int n)
+{
+ fputs("edge ",of);
+ print_e_attrs(attrs,n);
+ fputc(';',of);
+ fputc('\n',of);
+}
+
+void dot_global_node_style(node_attr *attrs, int n)
+{
+ fputs("node ",of);
+ print_n_attrs(attrs,n);
+ fputc(';',of);
+ fputc('\n',of);
+}
+
+/* by default, set the node's name to label */
+static void declare_node(dot_node n, char *label)
+{
+ int i;
+ char mangled[512];
+
+ if (label[0] == '\"')
+ mangled[0] = 's';
+ else
+ mangled[0] = label[0];
+
+ for (i = 1; label[i] && i < 512 ;i++)
+ {
+ if (label[i] == '\"')
+ mangled[i] = '_';
+ else mangled[i] = label[i];
+ }
+ mangled[i] = '\0';
+
+ fprintf(of,"nd_%d [label=\"%s\"]\n",n,mangled);
+}
+
+dot_node dot_get_node(char *label) deletes
+{
+ dot_node result;
+ if (!hash_table_lookup(node_hash_table,(hash_key)label,(hash_data *)(char *)&result))
+ {
+ dot_node newnode = node_count++;
+
+ declare_node(newnode,label);
+ hash_table_insert(node_hash_table,
+ (hash_key)rstrdup(dot_region,label),
+ (hash_data)newnode);
+
+ return newnode;
+ }
+ else
+ return result;
+
+}
+
+void dot_node_style(dot_node node,node_attr *attrs, int n)
+{
+ fprintf(of,"nd_%d ",node);
+ print_n_attrs(attrs,n);
+ fputc(';',of);
+ fputc('\n',of);
+}
+
+void dot_plain_edge(dot_node from, dot_node to)
+{
+ fprintf(of,"nd_%d %s nd_%d;\n",from,edge_op,to);
+}
+
+void dot_styled_edge(dot_node from, dot_node to, edge_attr *attrs, int n)
+{
+ fprintf(of,"nd_%d %s nd_%d ",from,edge_op,to);
+ print_e_attrs(attrs,n);
+ fputc(';',of);
+ fputc('\n',of);
+}
+
+void dot_end(void) deletes
+{
+ fputc('}',of);
+ hash_table_delete(node_hash_table);
+ deleteregion_ptr(&dot_region);
+}
diff --git a/libbanshee/engine/dot.h b/libbanshee/engine/dot.h
new file mode 100644
index 00000000000..7e221e68145
--- /dev/null
+++ b/libbanshee/engine/dot.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef DOT_H
+#define DOT_H
+
+#include <stdio.h>
+#include "linkage.h"
+#include "bool.h"
+
+EXTERN_C_BEGIN
+
+typedef int dot_node;
+
+typedef struct
+{
+ enum n_attrs
+ {
+ n_color,
+ n_fontcolor,
+ n_fontname,
+ n_fontsize,
+ n_height,
+ n_width,
+ n_label,
+ n_layer,
+ n_shape,
+ n_shapefile,
+ n_style
+ } name;
+ const char *value;
+} node_attr;
+
+typedef struct
+{
+ enum e_attrs
+ {
+ e_color,
+ e_decorate,
+ e_dir,
+ e_fontcolor,
+ e_fontname,
+ e_fontsize,
+ e_id,
+ e_label,
+ e_layer,
+ e_minlen,
+ e_style,
+ e_weight
+ } name;
+ const char *value;
+} edge_attr;
+
+typedef struct
+{
+ enum g_attrs
+ {
+ g_center,
+ g_clusterrank,
+ g_color,
+ g_concentrate,
+ g_fontcolor,
+ g_fontname,
+ g_fontsize,
+ g_label,
+ g_layerseq,
+ g_margin,
+ g_mclimit,
+ g_nodesep,
+ g_nslimit,
+ g_ordering,
+ g_orientation,
+ g_page,
+ g_rank,
+ g_rankdir,
+ g_ranksep,
+ g_ratio,
+ g_size
+ } name;
+ const char *value;
+} graph_attr;
+
+void dot_start(FILE *to,const char *name,bool directed,bool strict);
+
+void dot_global_graph_style(graph_attr *attrs,int n);
+void dot_global_edge_style(edge_attr *attrs,int n);
+void dot_global_node_style(node_attr *attrs,int n);
+
+dot_node dot_get_node(char *label) deletes;
+void dot_node_style(dot_node node,node_attr *attrs,int n);
+
+void dot_plain_edge(dot_node from, dot_node to);
+void dot_styled_edge(dot_node from, dot_node to, edge_attr *attrs,int n);
+
+void dot_end(void) deletes;
+
+EXTERN_C_END
+
+#endif /* DOT_H */
diff --git a/libbanshee/engine/flow-var.c b/libbanshee/engine/flow-var.c
new file mode 100644
index 00000000000..4c60aa4eb47
--- /dev/null
+++ b/libbanshee/engine/flow-var.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include "banshee.h"
+#include "flow-var.h"
+#include "ufind.h"
+#include "bounds.h"
+
+DECLARE_UFIND(contour_elt,contour)
+
+struct flow_var /* extends gen_e */
+{
+#ifdef NONSPEC
+ sort_kind sort;
+#endif
+ int type; /* alias or var */
+ stamp st;
+ gen_e alias;
+ bounds sameregion ubs;
+ bounds sameregion lbs;
+ contour_elt elt;
+ const char *name;
+};
+
+DEFINE_UFIND(contour_elt,contour)
+DEFINE_LIST(flow_var_list, flow_var)
+
+#define get_contour(x) (contour_elt_get_info((x)->elt))
+
+static flow_var make_var(region r, const char *name, stamp st)
+{
+ flow_var result = ralloc(r,struct flow_var);
+
+ result->type = VAR_TYPE;
+ result->st = st;
+ result->alias = NULL;
+ result->ubs = bounds_create(r);
+ result->lbs = bounds_create(r);
+ result->elt = new_contour_elt(r,NULL);
+ result->name = name;
+
+#ifdef NONSPEC
+ result->sort = flow_sort;
+#endif
+
+ return result;
+}
+
+flow_var fv_fresh(region r, const char *name)
+{
+ return make_var(r,name,stamp_fresh());
+}
+
+flow_var fv_fresh_large(region r, const char *name)
+{
+ return make_var(r,name,stamp_fresh_large());
+}
+
+flow_var fv_fresh_small(region r, const char *name)
+{
+ return make_var(r,name,stamp_fresh_small());
+}
+
+const char * fv_get_name(flow_var v)
+{
+ return v->name;
+}
+
+gen_e_list fv_get_lbs(flow_var v)
+{
+ return bounds_exprs(v->lbs);
+}
+
+gen_e_list fv_get_ubs(flow_var v)
+{
+ return bounds_exprs(v->ubs);
+}
+
+bool fv_add_ub(flow_var v, gen_e e, stamp st)
+{
+ return bounds_add(v->ubs,e,st);
+}
+
+bool fv_add_lb(flow_var v, gen_e e, stamp st)
+{
+ return bounds_add(v->lbs,e,st);
+}
+
+bool fv_is_ub(flow_var v, stamp st)
+{
+ bool self_edge = v->st == st,
+ in_bounds = bounds_query(v->ubs,st);
+
+ return (self_edge || in_bounds);
+}
+
+bool fv_is_lb(flow_var v, stamp st)
+{
+ bool self_edge = v->st == st,
+ in_bounds = bounds_query(v->lbs,st);
+
+ return (self_edge || in_bounds);
+}
+
+void fv_set_alias(flow_var v, gen_e e)
+{
+ assert(v->type == VAR_TYPE);
+
+ v->type = ALIAS_TYPE;
+ v->alias = e;
+}
+
+gen_e fv_get_alias(flow_var v)
+{
+ return v->alias;
+}
+
+bool fv_has_contour(flow_var v)
+{
+ return (get_contour(v) != NULL);
+}
+
+void fv_set_contour(flow_var v, contour c)
+{
+ contour_elt_update(v->elt,c);
+}
+
+static contour combine_contour(contour c1, contour c2)
+{
+ if (c1 == NULL)
+ return c2;
+ else if (c2 == NULL)
+ return c1;
+
+ else
+ {
+ fail("Attempt to unify two distinct contours\n");
+ return NULL;
+ }
+
+}
+void fv_unify_contour(flow_var v1, flow_var v2)
+{
+ contour_elt_unify(combine_contour,v1->elt,v2->elt);
+}
+
+
+gen_e fv_instantiate_contour(flow_var v) deletes
+{
+ contour c = get_contour(v);
+ return c->instantiate(c->fresh,c->get_stamp,c->shape);
+}
diff --git a/libbanshee/engine/flow-var.h b/libbanshee/engine/flow-var.h
new file mode 100644
index 00000000000..2d77007824a
--- /dev/null
+++ b/libbanshee/engine/flow-var.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef FLOW_VAR_H
+#define FLOW_VAR_H
+
+#include "linkage.h"
+#include "banshee.h"
+#include "jcollection.h"
+
+EXTERN_C_BEGIN
+
+typedef struct flow_var *flow_var;
+
+typedef gen_e (*contour_inst_fn_ptr) (fresh_fn_ptr,get_stamp_fn_ptr,gen_e) deletes;
+
+struct contour
+{
+ gen_e shape;
+ fresh_fn_ptr fresh;
+ get_stamp_fn_ptr get_stamp;
+ contour_inst_fn_ptr instantiate;
+};
+
+typedef struct contour *contour;
+
+DECLARE_LIST(flow_var_list, flow_var)
+
+flow_var fv_fresh(region r, const char *name);
+flow_var fv_fresh_large(region r, const char *name);
+flow_var fv_fresh_small(region r, const char *name);
+const char * fv_get_name(flow_var v);
+gen_e_list fv_get_lbs(flow_var v);
+gen_e_list fv_get_ubs(flow_var v);
+bool fv_add_ub(flow_var v, gen_e e, stamp st);
+bool fv_add_lb(flow_var v, gen_e e, stamp st);
+bool fv_is_ub(flow_var v, stamp st);
+bool fv_is_lb(flow_var v, stamp st);
+
+void fv_set_alias(flow_var v, gen_e e);
+gen_e fv_get_alias(flow_var v);
+void fv_set_contour(flow_var v, contour c);
+bool fv_has_contour(flow_var v);
+void fv_unify_contour(flow_var v1, flow_var v2);
+gen_e fv_instantiate_contour(flow_var v) deletes;
+
+EXTERN_C_END
+
+#endif /* FLOW_VAR_H */
diff --git a/libbanshee/engine/flowrow-sort.c b/libbanshee/engine/flowrow-sort.c
new file mode 100644
index 00000000000..baee348ffd3
--- /dev/null
+++ b/libbanshee/engine/flowrow-sort.c
@@ -0,0 +1,1107 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <regions.h>
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <ansidecl.h>
+#include "flowrow-sort.h"
+#include "termhash.h"
+
+#include "setif-sort.h"
+
+#define ABS_TYPE 2
+#define WILD_TYPE 3
+#define ROW_TYPE 4
+
+/* generic flow row */
+struct flowrow_gen
+{
+#ifdef NONSPEC
+ sort_kind sort;
+#endif
+ int type;
+ stamp st;
+#ifdef NONSPEC
+ sort_kind base_sort;
+#endif
+};
+
+typedef struct flowrow_gen *flowrow_gen;
+
+struct flowrow
+{
+#ifdef NONSPEC
+ sort_kind sort;
+#endif
+ int type;
+ stamp st;
+#ifdef NONSPEC
+ sort_kind base_sort;
+#endif
+ flowrow_map fields;
+ gen_e rest;
+};
+
+typedef struct flowrow *flowrow;
+
+struct field_split
+{
+ gen_e_list matched1;
+ gen_e_list matched2;
+ flowrow_map nomatch1;
+ flowrow_map nomatch2;
+};
+
+region flowrow_region;
+term_hash flowrow_hash;
+struct flowrow_stats flowrow_stats;
+static void fields_print(FILE *f,flowrow_map m,field_print_fn_ptr field_print) deletes;
+
+stamp flowrow_get_stamp(gen_e e)
+{
+ if ( ((flowrow_gen)e)->type == ALIAS_TYPE)
+ return ((flowrow_gen)fv_get_alias( (flow_var)e ))->st;
+ else
+ return ((flowrow_gen)e)->st;
+
+}
+
+static flowrow_map flowrow_get_fields(gen_e e)
+{
+ assert (flowrow_is_row(e));
+
+ return ((flowrow)e)->fields;
+}
+
+static gen_e flowrow_get_rest(gen_e e)
+{
+ assert(flowrow_is_row(e));
+
+ return ((flowrow)e)->rest;
+}
+
+
+static int field_compare(const flowrow_field f1,const flowrow_field f2)
+
+{
+ int compare = strcmp(f1->label,f2->label);
+ return compare;
+}
+
+
+static int field_compare_ne(const flowrow_field f1,const flowrow_field f2)
+
+{
+ int compare = strcmp(f1->label,f2->label);
+
+ if (! compare) /* rows should never have two fields with the same labels */
+ {
+ failure("Multiple fields in this row share the same label\n");
+ }
+ return compare;
+}
+
+static struct field_split split_fields(region r, flowrow_map fields1,
+ flowrow_map fields2)
+{
+ struct field_split split;
+ flowrow_map_scanner scan1, scan2;
+ flowrow_field field1,field2;
+ bool consumed1 = TRUE,consumed2 = TRUE,
+ fields1_remain = TRUE, fields2_remain = TRUE;;
+
+ split.matched1 = new_gen_e_list(r);
+ split.matched2 = new_gen_e_list(r);
+ split.nomatch1 = new_flowrow_map(r);
+ split.nomatch2 = new_flowrow_map(r);
+
+ flowrow_map_scan(fields1,&scan1);
+ flowrow_map_scan(fields2,&scan2);
+
+ while (TRUE)
+ {
+ if (consumed1)
+ fields1_remain = flowrow_map_next(&scan1,&field1);
+ if (consumed2)
+ fields2_remain = flowrow_map_next(&scan2,&field2);
+
+ if (fields1_remain && fields2_remain)
+ {
+ int compare_fields = field_compare(field1,field2);
+
+ if (compare_fields < 0)
+ {
+ flowrow_map_cons(field1,split.nomatch1);
+ consumed1 = TRUE;
+ consumed2 = FALSE;
+ }
+ else if (compare_fields > 0)
+ {
+ flowrow_map_cons(field2,split.nomatch2);
+ consumed2 = TRUE;
+ consumed1 = FALSE;
+ }
+ else /* two fields are equal */
+ {
+ gen_e_list_cons(field1->expr,split.matched1);
+ gen_e_list_cons(field2->expr,split.matched2);
+ consumed1 = TRUE;
+ consumed2 = TRUE;
+ continue;
+ }
+ }
+ else if (fields1_remain)
+ {
+ /* flowrow_map_append(split.nomatch1,flowrow_map_copy(r,fields1)); */
+ flowrow_map_cons(field1,split.nomatch1);
+
+ while (flowrow_map_next(&scan1,&field1))
+ {
+ flowrow_map_cons(field1,split.nomatch1);
+ }
+
+ break;
+ }
+ else if (fields2_remain)
+ {
+ /* flowrow_map_append(split.nomatch2,flowrow_map_copy(r,fields2)); */
+ flowrow_map_cons(field2,split.nomatch2);
+ while (flowrow_map_next(&scan2,&field2))
+ {
+ flowrow_map_cons(field2,split.nomatch2);
+ }
+ break;
+ }
+ else /* no remaining fields, so */ break;
+ }
+
+ return split;
+}
+
+static bool flowrow_is_normalized(gen_e r)
+{
+ if ( flowrow_is_row(r) )
+ {
+ gen_e rest = flowrow_get_rest(r);
+
+ if ( flowrow_is_row(rest) || flowrow_is_alias(rest) )
+ return FALSE;
+ }
+ else if ( flowrow_is_alias(r) )
+ return FALSE;
+
+ return TRUE;
+}
+
+static gen_e normalize(get_stamp_fn_ptr get_stamp,
+ flowrow_map m,gen_e r) deletes
+{
+ if (flowrow_is_row(r))
+ {
+ flowrow_map_append(m,
+ flowrow_map_copy(flowrow_region,
+ flowrow_get_fields(r)));
+ return normalize(get_stamp,m,flowrow_get_rest(r));
+ }
+ else if (flowrow_is_alias(r))
+ {
+ assert (! flowrow_is_alias(fv_get_alias((flow_var)r)) );
+ return normalize(get_stamp, m,fv_get_alias((flow_var)r));
+ }
+ else
+ return flowrow_row(get_stamp,m,r);
+}
+
+static gen_e normalize_row(get_stamp_fn_ptr get_stamp, gen_e r) deletes
+{
+ if (flowrow_is_normalized(r))
+ return r;
+ else /* normalize the row */
+ return normalize(get_stamp,new_flowrow_map(flowrow_region),r);
+}
+
+static bool eq(gen_e e1, gen_e e2)
+{
+ return ( flowrow_get_stamp(e1) == flowrow_get_stamp(e2) );
+}
+
+
+/*
+ A row constraint row1 <= row2 is l-inductive iff row2 is a var and for all
+ X = tlv(row1), o(row2) > o(X).
+
+ tlv(row) = {X} if row is a var X, {} otherwise
+*/
+static bool l_inductive(gen_e e1, gen_e e2)
+{
+ if (flowrow_is_var(e2))
+ {
+ if (flowrow_is_var(e1))
+ return flowrow_get_stamp(e2) > flowrow_get_stamp(e1);
+ else return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ A row constraint row1 <= row2 is r-inductive iff row1 is a var and for all
+ X = tlv(row2), o(row1) > o(X)
+*/
+static bool r_inductive(gen_e e1, gen_e e2)
+{
+ if (flowrow_is_var(e1))
+ {
+ if (flowrow_is_var(e2))
+ return flowrow_get_stamp(e1) > flowrow_get_stamp(e2);
+ else return TRUE;
+ }
+ return FALSE;
+}
+
+static inline bool flowrow_minimal(flowrow r)
+{
+ return flowrow_is_zero(r->rest);
+}
+
+static inline bool flowrow_maximal(flowrow r)
+{
+ return flowrow_is_one(r->rest);
+}
+
+static inline bool flowrow_closed(flowrow r)
+{
+ return flowrow_is_abs(r->rest);
+}
+
+static inline bool flowrow_wildcard(flowrow r)
+{
+ return flowrow_is_wild(r->rest);
+}
+
+static inline bool flowrow_var(flowrow r)
+{
+ return flowrow_is_var(r->rest);
+}
+
+static gen_e contour_instantiate(fresh_fn_ptr fresh,
+ get_stamp_fn_ptr get_stamp,
+ gen_e e) deletes
+{
+ if (flowrow_is_row(e))
+ {
+ gen_e result;
+ flowrow_map_scanner scan;
+ flowrow_field f;
+ gen_e row = normalize_row(get_stamp,e);
+
+ region scratch_rgn = newregion();
+
+ flowrow_map new_fields = new_flowrow_map(scratch_rgn);
+
+ flowrow_map_scan(flowrow_get_fields(row),&scan);
+
+ while (flowrow_map_next(&scan,&f))
+ {
+ flowrow_field new_field =
+ ralloc(flowrow_region,struct flowrow_field);
+ new_field->label = f->label;
+ new_field->expr = fresh(NULL);
+
+ flowrow_map_cons(new_field,new_fields);
+ }
+
+ result = flowrow_row(get_stamp,new_fields,flowrow_fresh(NULL));
+
+ deleteregion(scratch_rgn);
+
+ assert( flowrow_is_row(result) );
+
+ return result;
+ }
+
+ else /* TODO */
+ {
+ failure("Unmatched contour\n");
+ return NULL;
+ }
+}
+
+static contour get_contour(fresh_fn_ptr fresh,get_stamp_fn_ptr get_stamp,
+ gen_e zero_elem ATTRIBUTE_UNUSED,gen_e e)
+{
+ if (flowrow_is_row(e))
+ {
+ contour result;
+
+ result = ralloc(flowrow_region,struct contour);
+ result->shape = e;
+ result->fresh = fresh;
+ result->get_stamp = get_stamp;
+ result->instantiate = contour_instantiate;
+
+ return result;
+ }
+ else /* TODO */
+ {
+ failure("Unmatched contour\n");
+ return NULL;
+ }
+}
+
+
+static void trans_lbs(fresh_fn_ptr fresh,get_stamp_fn_ptr get_stamp,
+ incl_fn_ptr field_incl, gen_e zero_elem,
+ flow_var v, gen_e e) deletes
+{
+ gen_e temp;
+ gen_e_list_scanner scan;
+
+ gen_e_list_scan(fv_get_lbs(v),&scan);
+ while (gen_e_list_next(&scan,&temp))
+ flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,temp,e);
+
+}
+
+static void trans_ubs(fresh_fn_ptr fresh,get_stamp_fn_ptr get_stamp,
+ incl_fn_ptr field_incl, gen_e zero_elem,
+ flow_var v, gen_e e) deletes
+{
+ gen_e temp;
+ gen_e_list_scanner scan;
+
+ gen_e_list_scan(fv_get_ubs(v),&scan);
+ while (gen_e_list_next(&scan,&temp))
+ flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,e,temp);
+}
+
+static void update_lower_bound(fresh_fn_ptr fresh,get_stamp_fn_ptr get_stamp,
+ incl_fn_ptr field_incl, gen_e zero_elem,
+ flow_var v,gen_e e) deletes
+{
+ if (fv_has_contour(v)) /* _ <= v, and v has a contour */
+ {
+ gen_e shape = fv_instantiate_contour(v);
+
+ fv_set_alias(v,shape);
+ trans_ubs(fresh,get_stamp,field_incl,zero_elem,v,shape);
+ trans_lbs(fresh,get_stamp,field_incl,zero_elem,v,shape);
+
+ flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,e,shape);
+
+ }
+
+ else if (flowrow_is_var(e))
+ {
+ flow_var v_lb = (flow_var)e;
+
+ if (fv_has_contour(v_lb)) /* v1 <= v2, v1 has a contour */
+ {
+ gen_e shape = fv_instantiate_contour(v_lb);
+
+ fv_set_alias(v_lb,shape);
+ trans_ubs(fresh,get_stamp,field_incl,zero_elem,v_lb,shape);
+ trans_lbs(fresh,get_stamp,field_incl,zero_elem,v_lb,shape);
+
+ flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,
+ shape,(gen_e)v);
+
+ }
+
+ else /* we have v1 <= v2, no contours */
+ {
+ bool redundant;
+
+ fv_unify_contour(v,(flow_var)e);
+ redundant = fv_add_lb(v,e,flowrow_get_stamp(e));
+
+ if (! redundant)
+ trans_ubs(fresh,get_stamp,field_incl,zero_elem,v,e);
+
+ }
+ }
+ else /* we have c(...) <= v, and v has no contour */
+ {
+ gen_e shape = NULL;
+ fv_set_contour(v,get_contour(fresh,get_stamp,zero_elem,e));
+
+ shape = fv_instantiate_contour(v);
+ fv_set_alias(v,shape);
+ trans_ubs(fresh,get_stamp,field_incl,zero_elem,v,shape);
+ trans_lbs(fresh,get_stamp,field_incl,zero_elem,v,shape);
+
+ flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,e,shape);
+
+ }
+}
+
+static void update_upper_bound(fresh_fn_ptr fresh,get_stamp_fn_ptr get_stamp,
+ incl_fn_ptr field_incl, gen_e zero_elem,
+ flow_var v,gen_e e) deletes
+{
+ if (fv_has_contour(v)) /* v isn't aliased, and we discovered a contour*/
+ {
+ gen_e shape = fv_instantiate_contour(v);
+
+ fv_set_alias(v,shape);
+ trans_ubs(fresh,get_stamp,field_incl,zero_elem,v,shape);
+ trans_lbs(fresh,get_stamp,field_incl,zero_elem,v,shape);
+
+ flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,shape,e);
+
+ }
+
+ else if (flowrow_is_var(e))
+ {
+ flow_var v2 = (flow_var)e;
+
+ if (fv_has_contour(v2)) // v2 isn't aliased, and we discovered a contour
+ {
+ gen_e shape = fv_instantiate_contour(v2);
+
+ fv_set_alias(v2,shape);
+ trans_ubs(fresh,get_stamp,field_incl,zero_elem,v2,shape);
+ trans_lbs(fresh,get_stamp,field_incl,zero_elem,v2,shape);
+
+
+ flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,
+ (gen_e)v,shape);
+
+ }
+
+ else /* we have v1 <= v2, no contours */
+ {
+ bool redundant;
+
+ fv_unify_contour(v,(flow_var)e);
+ redundant = fv_add_ub(v,e,flowrow_get_stamp(e));
+
+ if (! redundant)
+ trans_lbs(fresh,get_stamp,field_incl,zero_elem,v,e);
+
+ }
+ }
+ else /* we have v <= c(...), and v has no contour */
+ {
+ gen_e shape = NULL;
+ fv_set_contour(v,get_contour(fresh,get_stamp,zero_elem,e));
+
+ shape = fv_instantiate_contour(v);
+
+ if (! flowrow_is_row(shape) )
+ {
+ assert(0);
+ }
+
+ fv_set_alias(v,shape);
+ trans_ubs(fresh,get_stamp,field_incl,zero_elem,v,shape);
+ trans_lbs(fresh,get_stamp,field_incl,zero_elem,v,shape);
+
+
+ flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,shape,e);
+
+ }
+
+}
+
+// END
+
+
+void flowrow_inclusion(fresh_fn_ptr fresh,get_stamp_fn_ptr get_stamp,
+ incl_fn_ptr field_incl, gen_e zero_elem, gen_e a,
+ gen_e b) deletes
+{
+ gen_e e1 = normalize_row(get_stamp, a),
+ e2 = normalize_row(get_stamp, b);
+
+ if (eq(e1,e2))
+ return;
+ else if (flowrow_is_zero(e1) || flowrow_is_wild(e1))
+ return;
+ else if (flowrow_is_one(e2) || flowrow_is_wild(e2))
+ return;
+
+ else if ( l_inductive(e1,e2) )
+ {
+ flow_var v2 = (flow_var)e2;
+
+ flowrow_stats.rows_l_inductive++;
+
+ update_lower_bound(fresh,get_stamp,field_incl,zero_elem,v2,e1);
+ return;
+ }
+
+ else if ( r_inductive(e1,e2) )
+ {
+ flow_var v1 = (flow_var)e1;
+
+ flowrow_stats.rows_r_inductive++;
+
+ update_upper_bound(fresh,get_stamp,field_incl,zero_elem,v1,e2);
+ return;
+ }
+
+ else if ( flowrow_is_row(e1) && flowrow_is_row(e2))
+ {
+ region scratch_rgn = newregion();
+
+ flowrow r1 = (flowrow)e1,
+ r2 = (flowrow)e2;
+
+ struct field_split split =
+ split_fields(scratch_rgn,r1->fields,r2->fields);
+
+ if ( gen_e_list_empty(split.matched1) )
+ {
+ assert ( gen_e_list_empty(split.matched2) );
+
+ if (flowrow_wildcard(r1) || flowrow_minimal(r1))
+ {
+ gen_e newrow =
+ flowrow_row(get_stamp,split.nomatch1,flowrow_get_rest(e1));
+
+ flowrow_inclusion(fresh,get_stamp,field_incl, zero_elem,newrow,
+ flowrow_get_rest(e2));
+ }
+ else if (flowrow_maximal(r2) || flowrow_closed(r2))
+ {
+ gen_e newrow =
+ flowrow_row(get_stamp,split.nomatch2,flowrow_get_rest(e2));
+
+ flowrow_inclusion(fresh, get_stamp,field_incl,zero_elem,
+ flowrow_get_rest(e1),newrow);
+ }
+ else
+ {
+ gen_e rest1 = flowrow_get_rest(e1),
+ rest2 = flowrow_get_rest(e2);
+
+ //assert( flowrow_is_var(rest1) && flowrow_is_var(rest2));
+
+ if ( eq(rest1,rest2))
+ failure("Recursive row resolution\n");
+ else
+ {
+ gen_e fv = flowrow_fresh(NULL);
+ gen_e newrow1 = flowrow_row(get_stamp,split.nomatch1,fv);
+ gen_e newrow2 = flowrow_row(get_stamp,split.nomatch2,fv);
+
+ flowrow_inclusion(fresh,get_stamp,field_incl,
+ zero_elem,rest1,newrow2);
+ flowrow_inclusion(fresh,get_stamp,field_incl,
+ zero_elem,newrow1,rest2);
+ }
+
+ }
+ }
+
+ else /* some fields matched */
+ {
+ gen_e_list_scanner scan1, scan2;
+ gen_e f1,f2;
+
+ assert( gen_e_list_length(split.matched1)
+ == gen_e_list_length(split.matched2) );
+
+ gen_e_list_scan(split.matched1,&scan1);
+ gen_e_list_scan(split.matched2,&scan2);
+
+ while (gen_e_list_next(&scan1,&f1) &&
+ gen_e_list_next(&scan2,&f2) )
+ {
+ field_incl(f1,f2);
+ }
+
+ if ( flowrow_wildcard(r1) && flowrow_wildcard(r2) )
+ {
+ goto END;
+ }
+ else
+ {
+ flowrow_map fields1 = split.nomatch1;
+ flowrow_map fields2 = split.nomatch2;
+
+ gen_e newrow1 = flowrow_row(get_stamp,fields1,r1->rest);
+ gen_e newrow2 = flowrow_row(get_stamp,fields2,r2->rest);
+
+ flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,
+ newrow1, newrow2);
+ }
+ }
+ END:
+ deleteregion(scratch_rgn);
+ }
+
+ else /* potentially a problem normalizing a row? */
+ {
+ failure("Unmatched case in row inclusion\n");
+ return;
+ }
+}
+
+gen_e flowrow_row(get_stamp_fn_ptr get_stamp,flowrow_map f, gen_e rest) deletes
+{
+ flowrow_map fields = flowrow_map_copy(flowrow_region,f);
+
+ if (flowrow_map_empty(fields))
+ {
+ return rest;
+ }
+ else
+ {
+ flowrow_map_scanner scan;
+ flowrow_field temp;
+ gen_e result;
+ int i = 2,
+ length = flowrow_map_length(fields);
+ stamp st[2+2*length];
+
+ st[0] = ROW_TYPE;
+ if (rest)
+ st[1] = flowrow_get_stamp(rest);
+ else
+ assert(0);
+
+ flowrow_map_sort(fields,field_compare_ne);
+
+ flowrow_map_scan(fields,&scan);
+ while(flowrow_map_next(&scan,&temp))
+ {
+ st[i++] = stamp_string(temp->label);
+ if (temp->expr)
+ st[i++] = get_stamp(temp->expr);
+ else
+ assert(0);
+ }
+
+ if ( (result = term_hash_find(flowrow_hash,st,2 + 2*length)) == NULL)
+ {
+ flowrow r = ralloc(flowrow_region, struct flowrow);
+ r->type = ROW_TYPE;
+ r->st = stamp_fresh();
+ r->fields = fields;
+ r->rest = rest;
+
+#ifdef NONSPEC
+ r->base_sort = row_map_head(fields)->expr->sort;
+ r->sort = flowrow_sort;
+#endif
+ result = (gen_e) r;
+ term_hash_insert(flowrow_hash,result,st,2+2*length);
+ }
+ /* assert(flowrow_is_normalized(result)); */
+ return result;
+
+ }
+}
+
+#ifndef NONSPEC
+static struct flowrow_gen zero_row = {ZERO_TYPE,ZERO_TYPE};
+static struct flowrow_gen one_row = {ONE_TYPE,ONE_TYPE};
+static struct flowrow_gen abs_row = {ABS_TYPE, ABS_TYPE};
+static struct flowrow_gen wild_row = {WILD_TYPE, WILD_TYPE};
+
+gen_e flowrow_zero(void)
+{
+ return (gen_e)&zero_row;
+}
+
+gen_e flowrow_one(void)
+{
+ return (gen_e)&one_row;
+}
+
+gen_e flowrow_abs(void)
+{
+ return (gen_e)&abs_row;
+}
+
+gen_e flowrow_wild(void)
+{
+ return (gen_e)&wild_row;
+}
+
+gen_e flowrow_fresh(const char *name)
+{
+ flowrow_stats.fresh++;
+ return (gen_e)fv_fresh(flowrow_region,name);
+}
+
+gen_e flowrow_fresh_small(const char *name)
+{
+ flowrow_stats.fresh_small++;
+ return (gen_e)fv_fresh_small(flowrow_region,name);
+}
+
+gen_e flowrow_fresh_large(const char *name)
+{
+ flowrow_stats.fresh_large++;
+ return (gen_e)fv_fresh_large(flowrow_region,name);
+}
+
+#else
+static struct flowrow_gen term_zero_row = {flowrow_sort,ZERO_TYPE,ZERO_TYPE,term_sort};
+static struct flowrow_gen term_one_row = {flowrow_sort,ONE_TYPE,ONE_TYPE,term_sort};
+static struct flowrow_gen term_abs_row = {flowrow_sort,ABS_TYPE, ABS_TYPE,term_sort};
+static struct flowrow_gen term_wild_row = {flowrow_sort,WILD_TYPE, WILD_TYPE,term_sort};
+
+
+static struct flowrow_gen setif_zero_row = {flowrow_sort,ZERO_TYPE,ZERO_TYPE,setif_sort};
+static struct flowrow_gen setif_one_row = {flowrow_sort,ONE_TYPE,ONE_TYPE,setif_sort};
+static struct flowrow_gen setif_abs_row = {flowrow_sort,ABS_TYPE, ABS_TYPE,setif_sort};
+static struct flowrow_gen setif_wild_row = {flowrow_sort,WILD_TYPE, WILD_TYPE,setif_sort};
+
+static struct flowrow_gen setst_zero_row = {flowrow_sort,ZERO_TYPE,ZERO_TYPE,setst_sort};
+static struct flowrow_gen setst_one_row = {flowrow_sort,ONE_TYPE,ONE_TYPE,setst_sort};
+static struct flowrow_gen setst_abs_row = {flowrow_sort,ABS_TYPE, ABS_TYPE,setst_sort};
+static struct flowrow_gen setst_wild_row = {flowrow_sort,WILD_TYPE, WILD_TYPE,setst_sort};
+
+
+gen_e flowrow_zero(sort_kind base_sort)
+{
+ switch (base_sort)
+ {
+ case setif_sort:
+ return (gen_e)&setif_zero_row;
+ case setst_sort:
+ return (gen_e)&setst_zero_row;
+ case term_sort:
+ return (gen_e)&term_zero_row;
+ default:
+ {
+ failure("No matching base sort: flowrow_zero\n");
+ return NULL;
+ }
+ }
+
+ return NULL;
+}
+
+gen_e flowrow_one(sort_kind base_sort)
+{
+ switch (base_sort)
+ {
+ case setif_sort:
+ return (gen_e)&setif_one_row;
+ case setst_sort:
+ return (gen_e)&setst_one_row;
+ case term_sort:
+ return (gen_e)&term_one_row;
+ default:
+ {
+ failure("No matching base sort: flowrow_one\n");
+ return NULL;
+ }
+ }
+
+ return NULL;
+}
+
+gen_e flowrow_abs(sort_kind base_sort)
+{
+ switch (base_sort)
+ {
+ case setif_sort:
+ return (gen_e)&setif_abs_row;
+ case setst_sort:
+ return (gen_e)&setst_abs_row;
+ case term_sort:
+ return (gen_e)&term_abs_row;
+ default:
+ {
+ failure("No matching base sort: flowrow_abs\n");
+ return NULL;
+ }
+ }
+
+ return NULL;
+}
+
+gen_e flowrow_wild(sort_kind base_sort)
+{
+
+ switch (base_sort)
+ {
+ case setif_sort:
+ return (gen_e)&setif_wild_row;
+ case setst_sort:
+ return (gen_e)&setst_wild_row;
+ case term_sort:
+ return (gen_e)&term_wild_row;
+ default:
+ {
+ failure("No matching base sort: flowrow_wild\n");
+ return NULL;
+ }
+ }
+
+ return NULL;
+}
+
+gen_e flowrow_fresh(const char *name,sort_kind base_sort)
+{
+
+ switch (base_sort)
+ {
+ case setif_sort:
+ return
+ case setst_sort:
+ return (gen_e)&setst_one_row;
+ case term_sort:
+ return (gen_e)&term_one_row;
+ default:
+ {
+ failure("No matching base sort: flowrow_one\n");
+ return NULL;
+ }
+ }
+
+ return NULL;
+}
+
+gen_e flowrow_fresh_small(sort_kind base_sort)
+{
+
+ switch (base_sort)
+ {
+ case setif_sort:
+ return (gen_e)&setif_one_row;
+ case setst_sort:
+ return (gen_e)&setst_one_row;
+ case term_sort:
+ return (gen_e)&term_one_row;
+ default:
+ {
+ failure("No matching base sort: flowrow_one\n");
+ return NULL;
+ }
+ }
+
+ return NULL;
+}
+
+gen_e flowrow_fresh_large(sort_kind base_sort)
+{
+
+}
+
+sort_kind flowrow_base_sort(gen_e e)
+{
+
+}
+#endif /* NONSPEC */
+
+
+gen_e flowrow_extract_field(const char *name, gen_e e)
+{
+
+ static bool field_eq(const flowrow_field f)
+ {
+ return (! strcmp(f->label,name));
+ }
+
+ if (flowrow_is_row(e))
+ {
+ flowrow_map fields = flowrow_get_fields(e);
+ flowrow_field f = flowrow_map_find(fields,field_eq);
+
+ if (f)
+ return f->expr;
+ }
+ return NULL;
+}
+
+gen_e flowrow_extract_rest(gen_e e)
+{
+ if (flowrow_is_row(e))
+ return flowrow_get_rest(e);
+ else
+ return NULL;
+}
+
+flowrow_map flowrow_extract_fields(gen_e e)
+{
+ if (flowrow_is_row(e))
+ return flowrow_map_copy(flowrow_region,flowrow_get_fields(e));
+ else
+ return NULL;
+}
+
+
+bool flowrow_is_alias(gen_e e)
+{
+ return ((flowrow_gen)e)->type == ALIAS_TYPE;
+}
+
+bool flowrow_is_zero(gen_e e)
+{
+ return ((flowrow_gen)e)->type == ZERO_TYPE;
+}
+
+bool flowrow_is_one(gen_e e)
+{
+ return ((flowrow_gen)e)->type == ONE_TYPE;
+}
+
+bool flowrow_is_abs(gen_e e)
+{
+ return ((flowrow_gen)e)->type == ABS_TYPE;
+}
+
+bool flowrow_is_wild(gen_e e)
+{
+ return ((flowrow_gen)e)->type == WILD_TYPE;
+}
+
+bool flowrow_is_var(gen_e e)
+{
+ return ((flowrow_gen)e)->type == VAR_TYPE;
+}
+
+bool flowrow_is_row(gen_e e)
+{
+ return ((flowrow_gen)e)->type == ROW_TYPE;
+}
+
+void flowrow_init(void)
+{
+ flowrow_region = newregion();
+ flowrow_hash = make_term_hash(flowrow_region);
+}
+
+static void flowrow_reset_stats(void)
+{
+ flowrow_stats.fresh = 0;
+ flowrow_stats.fresh_small = 0;
+ flowrow_stats.fresh_large = 0;
+
+ flowrow_stats.rows_disjoint_wild = 0;
+ flowrow_stats.rows_equal = 0;
+ flowrow_stats.rows_zero_one_wild = 0;
+ flowrow_stats.rows_l_inductive = 0;
+ flowrow_stats.rows_r_inductive = 0;
+ flowrow_stats.rows_disjoint_r1_minimal = 0;
+ flowrow_stats.rows_disjoint_r1_var_r2_minimal = 0;
+ flowrow_stats.rows_disjoint_r1_var_r2_maximal = 0;
+ flowrow_stats.rows_disjoint_r1_var_r2_closed = 0;
+ flowrow_stats.rows_disjoint_r1_var_r2_var_lt = 0;
+ flowrow_stats.rows_disjoint_r1_var_r2_var_gt = 0;
+ flowrow_stats.rows_equal_domains = 0;
+ flowrow_stats.rows_nonempty_intersection = 0;
+ flowrow_stats.rows_fresh = 0;
+ flowrow_stats.rows_fresh_large = 0;
+}
+
+void flowrow_reset(void) deletes
+{
+ term_hash_delete(flowrow_hash);
+ deleteregion_ptr(&flowrow_region);
+
+ flowrow_reset_stats();
+
+ flowrow_region = newregion();
+ flowrow_hash = make_term_hash(flowrow_region);
+
+}
+
+static void fields_print(FILE *f,flowrow_map m,field_print_fn_ptr field_print) deletes
+{
+ flowrow_map_scanner scan;
+ flowrow_field temp;
+
+ flowrow_map_scan(m,&scan);
+
+ if (flowrow_map_next(&scan,&temp))
+ {
+ fprintf(f,"%s : ",temp->label);
+
+ if (field_print)
+ field_print(f,temp->expr);
+ else
+ fprintf(f,"?");
+ }
+
+ while (flowrow_map_next(&scan,&temp))
+ {
+ fprintf(f,",%s : ",temp->label);
+
+ if (field_print)
+ field_print(f,temp->expr);
+ else
+ fprintf(f,"?");
+ }
+}
+
+void flowrow_print(FILE *f,get_stamp_fn_ptr get_stamp,
+ field_print_fn_ptr field_print,gen_e row) deletes
+{
+ gen_e e = normalize_row(get_stamp,row);
+
+ switch ( ((flowrow_gen)e)->type)
+ {
+ case ZERO_TYPE:
+ fprintf(f, "0");
+ break;
+ case ONE_TYPE:
+ fprintf(f, "1");
+ break;
+ case ABS_TYPE:
+ fprintf(f, "abs");
+ break;
+ case WILD_TYPE:
+ fprintf(f, "wild");
+ break;
+ case VAR_TYPE:
+ fprintf(f, fv_get_name((flow_var)e));
+ break;
+ case ROW_TYPE:
+ fprintf(f, "<");
+ fields_print(f, flowrow_get_fields(e), field_print);
+ fprintf(f, "|");
+ flowrow_print(f, get_stamp, field_print, flowrow_get_rest(e));
+ fprintf(f, ">");
+ break;
+ default:
+ assert(0);
+ break;
+ }
+}
+
+void flowrow_print_stats(FILE *f)
+{
+ fprintf(f,"\n========== Flow Var Stats ==========\n");
+ fprintf(f,"Fresh : %d\n",flowrow_stats.fresh);
+ fprintf(f,"Fresh Small : %d\n",flowrow_stats.fresh_small);
+ fprintf(f,"Fresh Large : %d\n",flowrow_stats.fresh_large);
+ fprintf(f,"=====================================\n");
+}
+
+DEFINE_LIST(flowrow_map,flowrow_field)
diff --git a/libbanshee/engine/flowrow-sort.h b/libbanshee/engine/flowrow-sort.h
new file mode 100644
index 00000000000..8d79b42c29d
--- /dev/null
+++ b/libbanshee/engine/flowrow-sort.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef FLOWROW_SORT_H
+#define FLOWROW_SORT_H
+
+
+#include "stdio.h"
+#include "banshee.h"
+#include "termhash.h"
+#include "flow-var.h"
+
+struct flowrow_field
+{
+ char *label;
+ gen_e expr;
+};
+
+typedef struct flowrow_field *flowrow_field;
+
+DECLARE_LIST(flowrow_map,flowrow_field)
+
+extern region flowrow_region;
+
+void flowrow_inclusion(fresh_fn_ptr fresh, get_stamp_fn_ptr get_stamp,
+ incl_fn_ptr field_incl,gen_e zero_elem, gen_e e1,
+ gen_e e2) deletes;
+
+gen_e flowrow_row(get_stamp_fn_ptr get_stamp,flowrow_map fields, gen_e rest) deletes;
+
+gen_e flowrow_extract_field(const char *name, gen_e e);
+gen_e flowrow_extract_rest(gen_e e);
+flowrow_map flowrow_extract_fields(gen_e e);
+
+stamp flowrow_get_stamp(gen_e e);
+
+#ifndef NONSPEC
+gen_e flowrow_zero(void);
+gen_e flowrow_one(void);
+gen_e flowrow_abs(void);
+gen_e flowrow_wild(void);
+gen_e flowrow_fresh(const char *name);
+gen_e flowrow_fresh_small(const char *name);
+gen_e flowrow_fresh_large(const char *name);
+#else
+sort_kind flowrow_base_sort(gen_e e);
+gen_e flowrow_zero(sort_kind base_sort);
+gen_e flowrow_one(sort_kind base_sort);
+gen_e flowrow_abs(sort_kind base_sort);
+gen_e flowrow_wild(sort_kind base_sort);
+gen_e flowrow_fresh(sort_kind base_sort);
+gen_e flowrow_fresh_small(sort_kind base_sort);
+gen_e flowrow_fresh_large(sort_kind base_sort);
+#endif
+
+bool flowrow_is_zero(gen_e e);
+bool flowrow_is_one(gen_e e);
+bool flowrow_is_abs(gen_e e);
+bool flowrow_is_wild(gen_e e);
+bool flowrow_is_var(gen_e e);
+bool flowrow_is_row(gen_e e);
+bool flowrow_is_alias(gen_e e);
+
+
+void flowrow_init(void);
+void flowrow_reset(void) deletes;
+
+typedef void (* field_print_fn_ptr) (FILE *f,gen_e e) deletes;
+
+void flowrow_print(FILE *f,get_stamp_fn_ptr get_stamp,
+ field_print_fn_ptr field_print,gen_e e) deletes;
+void flowrow_print_stats(FILE *f);
+
+extern struct flowrow_stats flowrow_stats;
+
+struct flowrow_stats
+{
+ int fresh;
+ int fresh_small;
+ int fresh_large;
+
+ int rows_disjoint_wild;
+ int rows_equal;
+ int rows_zero_one_wild;
+ int rows_l_inductive;
+ int rows_r_inductive;
+ int rows_disjoint_r1_minimal;
+ int rows_disjoint_r1_var_r2_minimal;
+ int rows_disjoint_r1_var_r2_maximal;
+ int rows_disjoint_r1_var_r2_closed;
+ int rows_disjoint_r1_var_r2_var_lt;
+ int rows_disjoint_r1_var_r2_var_gt;
+ int rows_equal_domains;
+ int rows_nonempty_intersection;
+ int rows_fresh;
+ int rows_fresh_large;
+};
+
+#endif /* FLOWROW_H */
+
+
+
+
+
+
+
diff --git a/libbanshee/engine/hash.c b/libbanshee/engine/hash.c
new file mode 100644
index 00000000000..bf315cee4a5
--- /dev/null
+++ b/libbanshee/engine/hash.c
@@ -0,0 +1,427 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include "hash.h"
+#include "util.h"
+
+struct bucket
+{
+ hash_key key;
+ hash_data data;
+ struct bucket *next;
+};
+
+#define scan_bucket(b, var) for (var = b; var; var = var->next)
+
+struct Hash_table
+{
+ region r; /* Region for this table */
+ hash_fn hash; /* Function for hashing keys */
+ keyeq_fn cmp; /* Function for comparing keys */
+
+ int size; /* Number of buckets */
+ int elts; /* Number of elements */
+ bool internal_rgn; /* TRUE if the ht uses an internal region */
+ bucket *table; /* Array of (size) buckets */
+};
+
+static void rehash(hash_table ht) deletes;
+
+/* Make a new hash table, with size buckets initially. The actual
+ table is allocated in a local region, which is discarded on rehashing. */
+hash_table make_hash_table(region r, int size, hash_fn hash,
+ keyeq_fn cmp, bool internal_rgn)
+{
+ hash_table result;
+
+ assert(size > 0);
+ result = ralloc(r, struct Hash_table);
+
+ if (internal_rgn)
+ result->r = newregion();
+ else
+ result->r = r;
+
+ result->internal_rgn = internal_rgn;
+ result->hash = hash;
+ result->cmp = cmp;
+ result->size = size;
+ result->elts = 0;
+ result->table = rarrayalloc(result->r, size, bucket);
+
+ return result;
+}
+
+/* Hash a string */
+static int string_hash(char *str)
+{
+ char *c;
+ int h;
+
+ c = str;
+ h = 0;
+ if (!c)
+ return 0;
+ while (*c)
+ h = 33*h + 720 + *c++; /* SML/NJ's string hash function */
+ return h;
+}
+
+/* Return TRUE iff s1 == s2 */
+static bool string_eq(char *s1, char *s2)
+{
+ return !strcmp(s1, s2);
+}
+
+/* Make a hash table for strings. */
+hash_table make_string_hash_table(region rhash, int size, bool internal_rgn)
+{
+ return make_hash_table(rhash, size, (hash_fn) string_hash,
+ (keyeq_fn) string_eq,internal_rgn);
+}
+
+/* Zero out ht. Doesn't reclaim bucket space. */
+void hash_table_reset(hash_table ht) deletes
+{
+ int i;
+
+ if (ht->internal_rgn)
+ {
+ deleteregion(ht->r);
+ ht->r = newregion();
+ }
+
+ ht->elts = 0;
+ for (i = 0; i < ht->size; i++)
+ ht->table[i] = NULL;
+}
+
+void hash_table_delete(hash_table ht) deletes
+{
+ if (ht->internal_rgn)
+ deleteregion(ht->r);
+}
+
+
+/* Return the number of entries in ht */
+int hash_table_size(hash_table ht)
+{
+ return ht->elts;
+}
+
+/* Return the bucket corresponding to k in ht */
+static inline bucket *find_bucket(hash_table ht, hash_key k)
+{
+ int hash;
+
+ hash = ht->hash(k);
+ if (hash < 0)
+ hash = -1*hash;
+ return &ht->table[hash % ht->size];
+}
+
+/* Lookup k in ht. Returns corresponding data in *d, and function
+ result is TRUE if the k was in ht, false otherwise. */
+bool hash_table_lookup(hash_table ht, hash_key k, hash_data *d)
+{
+ bucket cur;
+
+ cur = *find_bucket(ht, k);
+ while (cur)
+ {
+ if (ht->cmp(k, cur->key))
+ {
+ if (d)
+ *d = cur->data;
+ return TRUE;
+ }
+ cur = cur->next;
+ }
+ return FALSE;
+}
+
+
+/* Add k:d to ht. If k was already in ht, replace old entry by k:d.
+ Rehash if necessary. Returns TRUE if k was not already in ht. */
+bool hash_table_insert(hash_table ht, hash_key k, hash_data d) deletes
+{
+ bucket *cur;
+
+ if (ht->elts > ht->size*15)
+ rehash(ht);
+ cur = find_bucket(ht, k);
+ while (*cur)
+ {
+ if (ht->cmp(k, (*cur)->key))
+ {
+ (*cur)->data = d;
+ return FALSE; /* Replace */
+ }
+ cur = &(*cur)->next;
+ }
+ *cur = ralloc(ht->r, struct bucket);
+ (*cur)->key = k;
+ (*cur)->data = d;
+ (*cur)->next = NULL;
+ ht->elts++;
+ return TRUE; /* New key */
+}
+
+/* Remove mapping for k in ht. Returns TRUE if k was in ht. */
+bool hash_table_remove(hash_table ht, hash_key k)
+{
+ bucket *cur;
+ bucket *prev = NULL;
+
+ cur = find_bucket(ht, k);
+ while (*cur)
+ {
+ if (ht->cmp(k, (*cur)->key))
+ {
+ if (!*prev)
+ (*prev)->next = (*cur)->next;
+ else
+ *cur = NULL;
+ ht->elts--;
+ return TRUE;
+ }
+ prev = cur;
+ cur = &(*cur)->next;
+ }
+ return FALSE;
+}
+
+/* Return a copy of ht */
+hash_table hash_table_copy(region r, hash_table ht)
+{
+ int i;
+ hash_table result;
+ bucket cur, newbucket, *prev;
+
+ result = make_hash_table(r, ht->size, ht->hash, ht->cmp,ht->internal_rgn);
+ result->elts = ht->elts;
+
+ for (i = 0; i < ht->size; i++)
+ {
+ prev = &result->table[i];
+ scan_bucket(ht->table[i], cur)
+ {
+ newbucket = ralloc(result->r, struct bucket);
+ newbucket->key = cur->key;
+ newbucket->data = cur->data;
+ newbucket->next = NULL;
+ assert(!*prev);
+ *prev = newbucket;
+ prev = &newbucket->next;
+ }
+ }
+ return result;
+ /*
+ hash_table result;
+ hash_table_scanner hts;
+ hash_key k;
+ hash_data d;
+
+ result = make_hash_table(r, ht->size, ht->hash, ht->cmp);
+ hash_table_scan(ht, &hts);
+ while (hash_table_next(&hts, &k, &d))
+ insist(hash_table_insert(result, k, d));
+
+ return result;
+ */
+}
+
+/* Increase size of ht (double it) and reinsert all the elements */
+static void rehash(hash_table ht) deletes
+{
+ int old_table_size, i;
+ bucket *old_table, cur;
+ region old_region;
+
+#ifdef DEBUG
+ printf("Rehash table size=%d, elts=%d\n", ht->size, ht->elts);
+#endif
+
+ old_table_size = ht->size;
+ old_table = ht->table;
+ old_region = ht->r;
+
+ if (ht->internal_rgn)
+ ht->r = newregion();
+
+ ht->size = ht->size*2;
+ ht->elts = 0;
+ ht->table = rarrayalloc(ht->r, ht->size, bucket);
+
+ for (i = 0; i < old_table_size; i++)
+ scan_bucket(old_table[i], cur)
+ insist(hash_table_insert(ht, cur->key, cur->data));
+
+ if (ht->internal_rgn)
+ deleteregion(old_region);
+}
+
+/* Begin scanning ht */
+void hash_table_scan(hash_table ht, hash_table_scanner *hts)
+{
+ hts->ht = ht;
+ hts->i = 0;
+ hts->cur = hts->ht->table[0];
+}
+
+/* Get next elt in table, storing the elt in *k and *d if k and d are
+ non-NULL, respectively. Returns TRUE if there is a next elt, FALSE
+ otherwise. */
+bool hash_table_next(hash_table_scanner *hts, hash_key *k, hash_data *d)
+{
+ while (hts->cur == NULL)
+ {
+ hts->i++;
+ if (hts->i < hts->ht->size)
+ hts->cur = hts->ht->table[hts->i];
+ else
+ break;
+ }
+
+ if (hts->i == hts->ht->size)
+ {
+ return FALSE;
+ }
+ else
+ {
+ if (k)
+ *k = hts->cur->key;
+ if (d)
+ *d = hts->cur->data;
+ hts->cur = hts->cur->next;
+ }
+ return TRUE;
+}
+
+/* Apply f to all elements of ht, in some arbitrary order */
+void hash_table_apply(hash_table ht, hash_apply_fn f, void *arg)
+{
+ int i;
+ bucket cur;
+
+ for (i = 0; i < ht->size; i++)
+ scan_bucket(ht->table[i], cur)
+ f(cur->key, cur->data, arg);
+}
+
+/* Map f to all elements on ht, creating a new hash table */
+hash_table hash_table_map(hash_table ht, hash_map_fn f, void *arg)
+{
+ int i;
+ hash_table result;
+ bucket cur, newbucket, *prev;
+
+ result = make_hash_table(ht->r, ht->size, ht->hash, ht->cmp,ht->internal_rgn);
+ result->elts = ht->elts;
+
+ for (i = 0; i < ht->size; i++)
+ {
+ prev = &result->table[i];
+ scan_bucket(ht->table[i], cur)
+ {
+ newbucket = ralloc(ht->r, struct bucket);
+ newbucket->key = cur->key;
+ newbucket->data = f(cur->key, cur->data, arg);
+ newbucket->next = NULL;
+ assert(!*prev);
+ *prev = newbucket;
+ prev = &newbucket->next;
+ }
+ }
+ return result;
+ /*
+ hash_table result;
+ int i;
+ bucket cur;
+
+ result = make_hash_table(ht->r, ht->size, ht->hash, ht->cmp);
+ for (i = 0; i < ht->size; i++)
+ scan_bucket(ht->table[i], cur)
+ insist(hash_table_insert(result, cur->key, f(cur->key, cur->data, arg)));
+ return result;
+ */
+}
+
+static keycmp_fn cur_cmp = NULL;
+
+static int entry_cmp(const void *a, const void *b)
+{
+ struct sorted_entry *ae = (struct sorted_entry *) a;
+ struct sorted_entry *be = (struct sorted_entry *) b;
+ return cur_cmp(ae->k, be->k);
+}
+
+/* Begin scanning ht in sorted order according to f */
+void hash_table_scan_sorted(hash_table ht, keycmp_fn f,
+ hash_table_scanner_sorted *htss)
+{
+ hash_table_scanner hts;
+ int i;
+
+ htss->r = newregion();
+ htss->size = hash_table_size(ht);
+ htss->entries = rarrayalloc(htss->r, htss->size, struct sorted_entry);
+ htss->i = 0;
+
+ hash_table_scan(ht, &hts);
+ i = 0;
+ while (hash_table_next(&hts, &htss->entries[i].k,
+ &htss->entries[i].d))
+ i++;
+ assert(i == htss->size);
+ cur_cmp = f;
+ qsort(htss->entries, htss->size, sizeof(struct sorted_entry), entry_cmp);
+ cur_cmp = NULL;
+}
+
+/* Just like hash_table_next, but scans in sorted order */
+bool hash_table_next_sorted(hash_table_scanner_sorted *htss, hash_key *k,
+ hash_data *d) deletes
+{
+ if (htss->i < htss->size)
+ {
+ *k = htss->entries[htss->i].k;
+ *d = htss->entries[htss->i].d;
+ htss->i++;
+ return TRUE;
+ }
+ else
+ {
+ deleteregion(htss->r);
+ htss->r = NULL;
+ return FALSE;
+ }
+}
diff --git a/libbanshee/engine/hash.h b/libbanshee/engine/hash.h
new file mode 100644
index 00000000000..eb93ac88b31
--- /dev/null
+++ b/libbanshee/engine/hash.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef HASH_H
+#define HASH_H
+
+#include <regions.h>
+#include "bool.h"
+/*#include "hash_info.h"*/ /* Includes hash_key, hash_data typedef */
+#include "linkage.h"
+
+EXTERN_C_BEGIN
+
+typedef void *hash_key;
+typedef void *hash_data;
+
+/* Function to hash a key */
+typedef int (*hash_fn)(hash_key k);
+
+/* Function returning true iff k1 and k2 are equal */
+typedef bool (*keyeq_fn)(hash_key k1, hash_key k2);
+
+/* Function applied to elts in the hash table */
+typedef void (*hash_apply_fn)(hash_key k, hash_data d, void *arg);
+
+/* Function mapped to elts in the hash table */
+typedef hash_data (*hash_map_fn)(hash_key k, hash_data d, void *arg);
+
+typedef struct Hash_table *hash_table;
+
+/* Make a new hash table, with size buckets initially. */
+hash_table make_hash_table(region rhash, int size, hash_fn hash,
+ keyeq_fn cmp, bool internal_rgn);
+
+/* Make a hash table for strings. */
+hash_table make_string_hash_table(region rhash, int size, bool internal_rgn);
+
+/* Zero out ht. Doesn't reclaim bucket space. */
+void hash_table_reset(hash_table ht) deletes;
+
+/* Delete ht and internal memory associated with it. The top level pointer
+ must still be deleted. */
+void hash_table_delete(hash_table ht) deletes;
+
+/* Return the number of entries in ht */
+int hash_table_size(hash_table ht);
+
+
+/* Lookup k in ht. If d is not NULL, returns corresponding data in *d.
+ Function result is TRUE if the k was in ht, false otherwise. */
+bool hash_table_lookup(hash_table ht, hash_key k, hash_data *d);
+
+/* Add k:d to ht. If k was already in ht, replace old entry by k:d.
+ Rehash if necessary. Returns TRUE if k was not already in ht. */
+bool hash_table_insert(hash_table ht, hash_key k, hash_data d) deletes;
+
+/* Remove mapping for k in ht. Returns TRUE if k was in ht. */
+bool hash_table_remove(hash_table ht, hash_key k);
+
+/* Return a copy of ht, allocated in rhash */
+hash_table hash_table_copy(region rhash, hash_table ht);
+
+/* Apply f to all elements of ht, in some arbitrary order */
+void hash_table_apply(hash_table ht, hash_apply_fn f, void *arg);
+
+/* Map f to all elements on ht, creating a new hash table */
+hash_table hash_table_map(hash_table ht, hash_map_fn f, void *arg);
+
+typedef struct bucket *bucket;
+typedef struct
+{
+ hash_table ht;
+ int i;
+ bucket cur;
+} hash_table_scanner; /* Opaque type! Do not modify fields. */
+
+/* Begin scanning ht */
+void hash_table_scan(hash_table ht, hash_table_scanner *);
+
+/* Get next elt in table, storing the elt in *k and *d if k and d are
+ non-NULL, respectively. Returns TRUE if there is a next elt, FALSE
+ otherwise. */
+bool hash_table_next(hash_table_scanner *, hash_key *k, hash_data *d);
+
+/* Total order on hash table keys, only uesd for hash_table_scan_sorted */
+typedef int (*keycmp_fn)(hash_key k1, hash_key k2);
+
+struct sorted_entry
+{
+ hash_key k;
+ hash_data d;
+};
+
+typedef struct
+{
+ region r;
+ int i;
+ int size;
+ struct sorted_entry *entries;
+} hash_table_scanner_sorted;
+
+/* Begin scanning ht in sorted order according to f */
+void hash_table_scan_sorted(hash_table ht, keycmp_fn f,
+ hash_table_scanner_sorted *htss);
+
+/* Just like hash_table_next, but scans in sorted order */
+bool hash_table_next_sorted(hash_table_scanner_sorted *htss, hash_key *k,
+ hash_data *d) deletes;
+
+
+EXTERN_C_END
+
+#endif
diff --git a/libbanshee/engine/hashset.c b/libbanshee/engine/hashset.c
new file mode 100644
index 00000000000..27195e767bd
--- /dev/null
+++ b/libbanshee/engine/hashset.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <math.h>
+
+#include "hashset.h"
+#include "util.h"
+#define INIT_TABLE_SIZE 2
+#define EMPTY_KEY 0
+#define UB(n) ((1<<n)-1) /* 2^n-1 */
+#define CAP(n) (1<<n) /* 2^n */
+
+struct hash_set
+{
+ int *traditional table;
+ unsigned int ub;
+ unsigned int capacity;
+ unsigned int inserts;
+ unsigned int size;
+};
+
+static const int prime_1 = 83;
+static const int prime_2 = 5189;
+static const int init_table_size = INIT_TABLE_SIZE;
+static const int empty_key = EMPTY_KEY;
+
+hash_set hs_create(region r)
+{
+
+ hash_set hs = ralloc(r, struct hash_set);
+
+ hs->ub = UB(init_table_size);
+ hs->size = init_table_size;
+ hs->capacity = CAP(init_table_size);
+ hs->table = (int *)calloc(hs->capacity, sizeof(int));
+ hs->inserts = 0;
+ return hs;
+}
+
+int hs_num_items(hash_set hs)
+{
+ return hs->inserts;
+}
+
+int *hs_list_items(hash_set hs)
+{
+ return hs->table;
+}
+
+static bool member(int *table, int ub, int i, int value)
+{
+ while (table[i] != empty_key)
+ {
+ if (table[i] == value)
+ return TRUE;
+
+ else
+ i = ub & (i + prime_2);
+ }
+ return FALSE;
+}
+
+static inline void reinsert(int *table, int ub, int value)
+{
+ int i;
+
+ i = ub & (prime_1 * value);
+
+ while (table[i] != empty_key)
+ {
+ /* possibly the value is already present */
+ if (table[i] == value)
+ return;
+
+ else
+ i = ub & (i + prime_2);
+ }
+
+ table[i] = value;
+}
+
+static bool member_or_insert(int *table, int ub, int i, int value)
+{
+ while (table[i] != empty_key)
+ {
+ if (table[i] == value)
+ return TRUE;
+
+ else
+ i = ub & (i + prime_2);
+ }
+ table[i] = value;
+ return FALSE;
+}
+
+static void rehash(hash_set hs)
+{
+ int *old_table;
+ int old_capacity, i;
+
+ old_table = hs->table;
+ old_capacity = hs->capacity;
+ hs->capacity *= 2;
+ hs->ub = UB(++hs->size);
+ hs->table = (int *)calloc(hs->capacity, sizeof(int));
+ assert(hs->table);
+
+
+ for (i = 0; i < old_capacity; i++)
+ {
+ reinsert(hs->table, hs->ub, old_table[i]);
+ }
+
+ free(old_table);
+}
+/*
+static void post_insert(hash_set hs)
+{
+ float percent_full;
+
+ int capacity = hs->capacity;
+ int inserts = ++hs->inserts;
+
+ printf("%d,%d->%f\n",inserts,capacity,percent_full);
+ assert(capacity);
+ percent_full = (float) inserts / capacity;
+
+
+ if (percent_full != percent_full)
+ {
+ assert (0);
+ }
+
+ if (percent_full >= .85)
+ rehash(hs);
+}
+*/
+
+static void post_insert(hash_set hs)
+{
+ int capacity = hs->capacity;
+ int inserts = ++hs->inserts;
+
+ float percent_capacity = capacity * .85;
+
+ /*
+ printf("%d,%d->%f\n",inserts,capacity,percent_capacity);
+ */
+
+ if ( (float) inserts >= percent_capacity)
+ {
+ rehash(hs);
+ }
+
+}
+
+
+bool hs_query(hash_set hs, int entry)
+{
+ int hash;
+ int ub = hs->ub;
+
+ hash = ub & (prime_1 * abs(entry));
+ return member(hs->table, ub, hash, entry);
+}
+
+bool hs_member(hash_set hs, int entry)
+{
+ int hash;
+ int ub = hs->ub;
+
+ hash = ub & (prime_1 * abs(entry));
+ if (member_or_insert(hs->table, ub, hash, entry))
+ return TRUE;
+
+ else
+ {
+ post_insert(hs);
+ return FALSE;
+ }
+}
+
+void hs_delete(hash_set hs)
+{
+ free(hs->table);
+}
+
+
diff --git a/libbanshee/engine/hashset.h b/libbanshee/engine/hashset.h
new file mode 100644
index 00000000000..0b06cd0a657
--- /dev/null
+++ b/libbanshee/engine/hashset.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef HASHSET_H
+#define HASHSET_H
+
+#include "linkage.h"
+#include "banshee.h"
+
+EXTERN_C_BEGIN
+
+typedef struct hash_set *hash_set;
+
+hash_set hs_create(region r);
+void hs_delete(hash_set);
+bool hs_member(hash_set,int); /* adds the entry if not present */
+bool hs_query(hash_set,int); /* query only */
+int *hs_list_items(hash_set);
+int hs_num_items(hash_set);
+
+EXTERN_C_END
+
+#endif /* HASHSET_H */
diff --git a/libbanshee/engine/jcollection.c b/libbanshee/engine/jcollection.c
new file mode 100644
index 00000000000..8df072c8c8d
--- /dev/null
+++ b/libbanshee/engine/jcollection.c
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <assert.h>
+#include "jcollection.h"
+#include "hashset.h"
+#include "termhash.h"
+
+
+/*
+ static term_hash jcoll_hash;
+ */
+
+struct jcoll_dict
+{
+ region r;
+ term_hash hash;
+ get_stamp_fn_ptr get_stamp;
+};
+
+enum jcoll_type
+{
+ j_single,
+ j_chain,
+ j_join
+};
+
+/* generic jcoll type */
+struct jcoll
+{
+ enum jcoll_type type;
+ stamp st;
+};
+
+struct jcoll_single
+{
+ enum jcoll_type type;
+ stamp st;
+ gen_e entry;
+};
+
+struct jcoll_chain
+{
+ enum jcoll_type type;
+ stamp st;
+ gen_e_list sameregion entries;
+};
+
+struct jcoll_join
+{
+ enum jcoll_type type;
+ stamp st;
+ jcoll_list sameregion joins;
+ gen_e_list sameregion cache;
+};
+
+typedef struct jcoll_single *jcoll_single;
+typedef struct jcoll_chain *jcoll_chain;
+typedef struct jcoll_join *jcoll_join;
+
+DEFINE_LIST(jcoll_list,jcoll)
+
+
+
+jcoll jcoll_new(jcoll_dict d, gen_e e)
+{
+ jcoll_single result = ralloc(d->r, struct jcoll_single);
+ result->type = j_single;
+ result->st = stamp_fresh();
+ result->entry = e;
+ return (jcoll)result;
+}
+
+jcoll jcoll_jjoin(jcoll_dict d,jcoll_list list)
+{
+
+ if (jcoll_list_empty(list))
+ return NULL;
+ else if (jcoll_list_length(list) == 1)
+ return jcoll_list_head(list);
+
+ else
+ {
+ int i = 0,
+ length = jcoll_list_length(list) + 1;
+ stamp sts[length];
+ jcoll_join result;
+
+ jcoll_list_scanner scan;
+ jcoll temp;
+
+ sts[i++] = j_join;
+
+ jcoll_list_scan(list,&scan);
+ while (jcoll_list_next(&scan,&temp))
+ {
+ stamp st = temp ? temp->st : 0;
+ sts[i++] = st;
+ }
+ qsort(&sts[1],length-1,sizeof(int),ptr_cmp);
+
+ if ( NULL == (result = (jcoll_join)term_hash_find(d->hash,sts,length)) )
+ {
+ result = ralloc(d->r,struct jcoll_join);
+
+ result->type = j_join;
+ result->st = stamp_fresh();
+ result->joins = list;
+ result->cache = new_gen_e_list(d->r);
+ term_hash_insert(d->hash,(gen_e)result,sts,length);
+ }
+ return (jcoll)result;
+ }
+
+}
+
+/*
+ Hash chains
+ */
+jcoll jcoll_create_chain(jcoll_dict d, gen_e_list elems)
+{
+ int i = 0,
+ length = gen_e_list_length(elems) + 1;
+ stamp sts[length];
+ gen_e_list_scanner scan;
+ gen_e temp;
+ jcoll_chain result;
+
+ sts[i++] = j_chain;
+
+ gen_e_list_scan(elems,&scan);
+ while (gen_e_list_next(&scan,&temp))
+ {
+ sts[i++] = d->get_stamp(temp);
+ }
+ qsort(&sts[1],length-1,sizeof(int),ptr_cmp); /* FIX, first pos should always be chain */
+
+ if ( NULL == (result = (jcoll_chain)term_hash_find(d->hash,sts,length)) )
+ {
+ result = ralloc(d->r,struct jcoll_chain);
+ result->type = j_chain;
+ result->st = stamp_fresh();
+ result->entries = elems;
+ term_hash_insert(d->hash,(gen_e)result,sts,
+ length);
+ }
+ return (jcoll)result;
+}
+
+typedef void (*japp_fn_ptr) (void *, void *);
+
+static void app_aux(hash_set h, get_stamp_fn_ptr get_stamp, japp_fn_ptr app,
+ jcoll j, void *data)
+{
+ if (! j)
+ return;
+
+ switch(j->type)
+ {
+ case j_single:
+ {
+ jcoll_single single = (jcoll_single) j;
+
+ if (! hs_member(h,get_stamp(single->entry)) )
+ app(single->entry, data);
+ }
+ break;
+ case j_chain:
+ {
+ jcoll_chain chain = (jcoll_chain) j;
+
+ if (! hs_member(h,chain->st) )
+ {
+ gen_e_list_scanner scan;
+ gen_e entry;
+
+ gen_e_list_scan(chain->entries, &scan);
+ while (gen_e_list_next(&scan, &entry))
+ {
+ if (! hs_member(h, get_stamp(entry)) )
+ app(entry, data);
+ }
+
+ }
+
+ }
+ break;
+ case j_join:
+ {
+ jcoll_join join = (jcoll_join) j;
+
+ if (! hs_member(h, join->st))
+ {
+ if (! gen_e_list_empty(join->cache))
+ {
+ gen_e_list_scanner scan;
+ gen_e entry;
+
+ gen_e_list_scan(join->cache, &scan);
+ while (gen_e_list_next(&scan, &entry))
+ {
+ if (! hs_member(h, get_stamp(entry)) )
+ app(entry, data);
+ }
+ }
+ else
+ {
+ jcoll_list_scanner scan;
+ jcoll temp;
+
+ jcoll_list_scan(join->joins, &scan);
+ while (jcoll_list_next(&scan,&temp))
+ {
+ app_aux(h,get_stamp,app,temp, data);
+ }
+
+ }
+ }
+
+ }
+ break;
+ }
+
+}
+
+static void jcoll_app(jcoll_dict d, japp_fn_ptr app, jcoll j, void *data) deletes
+{
+ region scratch_rgn = newregion();
+ hash_set hash = hs_create(scratch_rgn);
+ app_aux(hash,d->get_stamp, app, j, data);
+ hs_delete(hash);
+ deleteregion(scratch_rgn);
+}
+ static void jcoll_accum(void *e, void *accum)
+ {
+ gen_e_list_cons((gen_e) e, (gen_e_list) accum);
+ }
+
+gen_e_list jcoll_flatten(jcoll_dict d, jcoll j) deletes
+{
+
+ gen_e_list accum = NULL;
+
+
+ if (j == NULL)
+ return new_gen_e_list(d->r);
+
+ switch (j->type)
+ {
+ case j_single:
+ {
+ jcoll_single single = (jcoll_single)j;
+
+ accum = new_gen_e_list(d->r);
+ gen_e_list_cons(single->entry,accum);
+ }
+ break;
+ case j_chain:
+ {
+ jcoll_chain chain = (jcoll_chain)j;
+ /* accum = gen_e_list_copy(r,chain->entries); */
+ accum = chain->entries;
+ }
+ break;
+ case j_join:
+ {
+ jcoll_join join = (jcoll_join)j;
+
+ if (! gen_e_list_empty(join->cache))
+ return join->cache;
+ else
+ {
+ accum = new_gen_e_list(d->r);
+ jcoll_app(d, jcoll_accum,j, accum);
+
+ gen_e_list_append(join->cache,accum /* gen_e_list_copy(r,accum)*/);
+ }
+ }
+ break;
+ }
+
+ return accum;
+}
+
+jcoll_dict jcoll_create_dict(region r,get_stamp_fn_ptr get_stamp)
+{
+ jcoll_dict result = ralloc(r,struct jcoll_dict);
+
+ result->r = r;
+ result->hash = make_term_hash(r);
+ result->get_stamp = get_stamp;
+ return result;
+}
+
+
+void jcoll_delete_dict(jcoll_dict d)
+{
+ term_hash_delete(d->hash);
+}
diff --git a/libbanshee/engine/jcollection.h b/libbanshee/engine/jcollection.h
new file mode 100644
index 00000000000..b1f0e717d4e
--- /dev/null
+++ b/libbanshee/engine/jcollection.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef JCOLLECTION_H
+#define JCOLLECTION_H
+
+#include "linkage.h"
+#include "banshee.h"
+
+EXTERN_C_BEGIN
+
+typedef struct jcoll *jcoll;
+
+typedef struct jcoll_dict *jcoll_dict;
+
+DECLARE_LIST(jcoll_list,jcoll)
+
+jcoll jcoll_new(jcoll_dict d, gen_e e);
+jcoll jcoll_jjoin(jcoll_dict d, jcoll_list list);
+gen_e_list jcoll_flatten(jcoll_dict d, jcoll j) deletes;
+jcoll jcoll_create_chain(jcoll_dict d, gen_e_list elems);
+
+jcoll_dict jcoll_create_dict(region r,get_stamp_fn_ptr get_stamp);
+void jcoll_delete_dict(jcoll_dict d);
+
+EXTERN_C_END
+
+#endif /* JCOLLECTION_H */
+
+
+
+
+
+
+
+
diff --git a/libbanshee/engine/linkage.h b/libbanshee/engine/linkage.h
new file mode 100644
index 00000000000..ef70bbe2468
--- /dev/null
+++ b/libbanshee/engine/linkage.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef LINKAGE_H
+#define LINKAGE_H
+
+#ifdef __cplusplus
+# define EXTERN_C extern "C"
+# define EXTERN_C_BEGIN extern "C" {
+# define EXTERN_C_END }
+#else
+# define EXTERN_C
+# define EXTERN_C_BEGIN
+# define EXTERN_C_END
+#endif
+
+#endif
diff --git a/libbanshee/engine/list.c b/libbanshee/engine/list.c
new file mode 100644
index 00000000000..3972e2dd904
--- /dev/null
+++ b/libbanshee/engine/list.c
@@ -0,0 +1,438 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <assert.h>
+#include "list.h"
+#include "util.h"
+
+struct list_node
+{
+ void *data;
+ struct list_node *sameregion next;
+};
+
+#define scan_node(b,var) for (var = b; var; var = var->next)
+
+struct list
+{
+ region sameregion r;
+ int length;
+ list_node sameregion head;
+};
+
+struct list *new_list(region r)
+{
+ struct list *result;
+
+ assert(r);
+
+ result = ralloc(r,struct list);
+ result->r = r;
+ result->length = 0;
+ result->head = NULL;
+
+ return result;
+}
+
+int list_size(struct list *l)
+{
+ return l->length;
+}
+
+struct list *list_cons(void *data, struct list *l)
+{
+ list_node newnode = ralloc(l->r, struct list_node);
+ newnode->next = l->head;
+ newnode->data = data;
+
+ l->head = newnode;
+ l->length++;
+
+ return l;
+}
+
+struct list *list_reverse(struct list *l)
+{
+
+ if (list_empty(l))
+ return l;
+
+ else
+ {
+ list_node temp,reversed = NULL;
+
+ while (l->head)
+ {
+ temp = l->head->next;
+
+ l->head->next = reversed;
+
+ reversed = l->head;
+
+ l->head = temp;
+ }
+
+ l->head = reversed;
+ return l;
+ }
+
+}
+
+bool list_empty(struct list *l)
+{
+ return (l->head == NULL);
+}
+
+static inline list_node tail(list_node n)
+{
+ if (n == NULL)
+ return NULL;
+ else
+ {
+ list_node temp = NULL,
+ tail = NULL;
+
+ scan_node(n,temp)
+ tail = temp;
+
+ assert(tail && tail->next == NULL);
+
+ return tail;
+ }
+}
+
+struct list *list_append(struct list *a, struct list *b)
+{
+ list_node tl;
+
+ assert( a && b );
+ assert( a != b);
+ assert( ptr_eq(a->r,b->r) );
+
+ tl = tail(a->head);
+
+
+ if (! tl)
+ {
+ a->head = b->head;
+ a->length = b->length;
+ }
+
+ else
+ {
+ tl->next = b->head;
+ a->length += b->length;
+ }
+ return a;
+}
+
+struct list *list_app(struct list *l,app_fn app)
+{
+ list_node n = NULL;
+
+
+ assert(l);
+
+ scan_node(l->head,n)
+ {
+ app(n->data);
+ }
+ return l;
+}
+
+void *list_find(struct list *l,eq_fn eq)
+{
+ list_node n = NULL;
+ assert(l);
+
+ scan_node(l->head,n)
+ {
+ if (eq(n->data))
+ return n;
+ }
+
+ return NULL;
+}
+
+struct list *list_tail(struct list *l)
+{
+ l->length--;
+ l->head = l->head->next;
+ return l;
+}
+
+void *list_head(struct list *l)
+{
+ return l->head->data;
+}
+
+struct list *list_filter(region r,struct list *l,eq_fn eq)
+{
+ struct list *result;
+ list_node n = NULL;
+ assert(l);
+
+ result = new_list(r);
+
+ scan_node(l->head,n)
+ {
+ if (eq(n->data))
+ list_cons(n->data,result);
+ }
+
+ return result;
+}
+
+struct list *list_keep(struct list *l, eq_fn eq)
+{
+ list_node prev, n;
+ assert(l);
+
+ while (l->head && !eq(l->head->data))
+ {
+ l->head = l->head->next;
+ }
+
+ prev = l->head;
+ scan_node(l->head->next,n)
+ {
+ if (!eq(n->data))
+ prev->next = n->next;
+ else prev = n;
+ }
+ return l;
+}
+
+struct list *list_filter2(struct list *l,eq_fn eq)
+{
+ return list_filter(l->r,l,eq);
+}
+
+struct list *list_copy(region r, struct list *l)
+{
+
+ struct list *result;
+ list_node n = NULL;
+#ifndef NDEBUG
+ int count = 0;
+#endif
+ assert(l);
+
+ result = new_list(r);
+
+ scan_node(l->head,n)
+ {
+ list_cons(n->data,result);
+ assert(++count <= l->length);
+ }
+
+ return list_reverse(result);
+}
+/* A Linked-List Memory Sort
+ by Philip J. Erdelsky
+ pje@acm.org
+ http://www.alumni.caltech.edu/~pje/
+*/
+
+#include <stdio.h>
+
+static void *sort_linked_list(void *p, unsigned index,
+ int (*compare)(const void *,const void *, comparator_fn), long *pcount, comparator_fn data)
+{
+ unsigned base;
+ unsigned long block_size;
+
+ struct record
+ {
+ struct record *next[1];
+ /* other members not directly accessed by this function */
+ };
+
+ struct tape
+ {
+ struct record *first, *last;
+ unsigned long count;
+ } tape[4];
+
+ /* Distribute the records alternately to tape[0] and tape[1]. */
+
+ tape[0].count = tape[1].count = 0L;
+ tape[0].first = NULL;
+ base = 0;
+ while (p != NULL)
+ {
+ struct record *next = ((struct record *)p)->next[index];
+ ((struct record *)p)->next[index] = tape[base].first;
+ tape[base].first = ((struct record *)p);
+ tape[base].count++;
+ p = next;
+ base ^= 1;
+ }
+
+ /* If the list is empty or contains only a single record, then */
+ /* tape[1].count == 0L and this part is vacuous. */
+
+ for (base = 0, block_size = 1L; tape[base+1].count != 0L;
+ base ^= 2, block_size <<= 1)
+ {
+ int dest;
+ struct tape *tape0, *tape1;
+ tape0 = tape + base;
+ tape1 = tape + base + 1;
+ dest = base ^ 2;
+ tape[dest].count = tape[dest+1].count = 0;
+ for (; tape0->count != 0; dest ^= 1)
+ {
+ unsigned long n0, n1;
+ struct tape *output_tape = tape + dest;
+ n0 = n1 = block_size;
+ while (1)
+ {
+ struct record *chosen_record;
+ struct tape *chosen_tape;
+ if (n0 == 0 || tape0->count == 0)
+ {
+ if (n1 == 0 || tape1->count == 0)
+ break;
+ chosen_tape = tape1;
+ n1--;
+ }
+ else if (n1 == 0 || tape1->count == 0)
+ {
+ chosen_tape = tape0;
+ n0--;
+ }
+ else if ((*compare)(tape0->first, tape1->first, data) > 0)
+ {
+ chosen_tape = tape1;
+ n1--;
+ }
+ else
+ {
+ chosen_tape = tape0;
+ n0--;
+ }
+ chosen_tape->count--;
+ chosen_record = chosen_tape->first;
+ chosen_tape->first = chosen_record->next[index];
+ if (output_tape->count == 0)
+ output_tape->first = chosen_record;
+ else
+ output_tape->last->next[index] = chosen_record;
+ output_tape->last = chosen_record;
+ output_tape->count++;
+ }
+ }
+ }
+
+ if (tape[base].count > 1L)
+ tape[base].last->next[index] = NULL;
+ if (pcount != NULL)
+ *pcount = tape[base].count;
+ return tape[base].first;
+}
+
+
+
+static int compare(const void *node1, const void *node2, comparator_fn data)
+{
+ comparator_fn cmp = (comparator_fn) data;
+ return cmp(((struct list_node *)node1)->data,
+ ((struct list_node *)node2)->data);
+}
+
+struct list *list_sort(struct list *l, comparator_fn cmp)
+{
+ long pcount;
+ l->head = sort_linked_list(l->head,1,compare,&pcount, cmp);
+ assert(pcount == l->length);
+ return l;
+}
+
+struct list *list_merge(struct list *a,struct list *b, comparator_fn cmp)
+{
+ return list_sort( list_append(a,b),cmp);
+}
+
+void list_scan(struct list *a,struct list_scanner *scan)
+{
+ scan->l = a;
+ scan->cur = a->head;
+}
+
+bool list_next(struct list_scanner *scan, void **data)
+{
+ if (!scan->cur)
+ return FALSE;
+ else
+ {
+ if (data)
+ *data = scan->cur->data;
+ scan->cur = scan->cur->next;
+ return TRUE;
+ }
+}
+
+void list_clear(struct list *l)
+{
+ l->head = NULL;
+ l->length = 0;
+}
+
+bool list_member(struct list *l,void *data)
+{
+ list_node n = NULL;
+ scan_node(l->head,n)
+ {
+ if (n->data == data)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+struct list *list_from_array(region r,void **data, int length)
+{
+ struct list *result = new_list(r);
+ int i;
+
+ for (i = length -1; i >= 0; i--)
+ {
+ list_cons(data[i],result);
+ }
+ return result;
+}
+
+
+
+
+
+
+
diff --git a/libbanshee/engine/list.h b/libbanshee/engine/list.h
new file mode 100644
index 00000000000..1dfae50c0f1
--- /dev/null
+++ b/libbanshee/engine/list.h
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef LIST_H
+#define LIST_H
+
+#include <regions.h>
+#include "bool.h"
+
+typedef void *list_data;
+typedef void (*app_fn) (void *);
+typedef bool (*eq_fn)(const void *);
+typedef int (*comparator_fn)(const void *,const void *);
+
+struct list;
+
+typedef struct list_node *list_node;
+
+struct list_scanner
+{
+ struct list *l;
+ list_node cur;
+}; /* Opaque type. Do not modify fields */
+
+
+struct list *new_list(region r);
+int list_size(struct list *a);
+struct list *list_cons(void *data, struct list *a);
+struct list *list_append(struct list *a, struct list *b);
+struct list *list_app(struct list *a,app_fn app);
+void *list_find(struct list *a,eq_fn eq);
+void *list_head(struct list *a);
+struct list *list_tail(struct list *a);
+struct list *list_filter(region r,struct list *a,eq_fn eq);
+struct list *list_filter2(struct list *a,eq_fn eq);
+struct list *list_keep(struct list *a,eq_fn eq);
+struct list *list_copy(region r, struct list *a);
+struct list *list_sort(struct list *a, comparator_fn cmp);
+struct list *list_merge(struct list *a,struct list *b, comparator_fn cmp);
+void list_scan(struct list *a,struct list_scanner *scan);
+bool list_next(struct list_scanner *scan, void **data);
+bool list_empty(struct list *a);
+bool list_member(struct list *a, void *data);
+void list_clear(struct list *a);
+struct list *list_reverse(struct list *a);
+struct list *list_from_array(region r,void **data, int length);
+
+#define DECLARE_OPAQUE_LIST(name,type) \
+typedef struct list_scanner name ## _scanner; \
+typedef void (* name ## _app_fn) (type); \
+typedef bool (* name ## _eq_fn) (const type); \
+typedef int (* name ## _comparator_fn)(const type,const type); \
+name new_ ## name(region r); \
+int name ## _length(name a); \
+name name ## _cons(type data, name a); \
+name name ## _append(name a, name b); \
+name name ## _app(name a, name ## _app_fn app); \
+type name ## _find(name a, name ## _eq_fn eq); \
+type name ## _head(name a); \
+name name ## _tail(name a); \
+name name ## _filter(region r,name a, name ## _eq_fn eq); \
+name name ## _filter2(name a, name ## _eq_fn eq); \
+name name ## _keep(name a, name ## _eq_fn eq); \
+name name ## _copy(region r, name a); \
+name name ## _sort(name a, name ## _comparator_fn cmp); \
+name name ## _merge(name a,name b, name ## _comparator_fn cmp); \
+void name ## _scan(name a, name ##_scanner *scan); \
+bool name ## _next(name ##_scanner *scan, type *data); \
+bool name ## _empty(name a); \
+void name ## _clear(name a); \
+bool name ## _member(name a, type data); \
+name name ## _reverse(name a); \
+name name ## _from_array(region r,type data[], int length);
+
+#define DECLARE_LIST(name,type) \
+typedef struct name ## _a *name; \
+typedef struct list_scanner name ## _scanner; \
+typedef void (* name ## _app_fn) (type); \
+typedef bool (* name ## _eq_fn) (const type); \
+typedef int (* name ## _comparator_fn)(const type,const type); \
+name new_ ## name(region r); \
+int name ## _length(name a); \
+name name ## _cons(type data, name a); \
+name name ## _append(name a, name b); \
+name name ## _app(name a, name ## _app_fn app); \
+type name ## _find(name a, name ## _eq_fn eq); \
+type name ## _head(name a); \
+name name ## _tail(name a); \
+name name ## _filter(region r,name a, name ## _eq_fn eq); \
+name name ## _filter2(name a, name ## _eq_fn eq); \
+name name ## _keep(name a, name ## _eq_fn eq); \
+name name ## _copy(region r, name a); \
+name name ## _sort(name a, name ## _comparator_fn cmp); \
+name name ## _merge(name a,name b, name ## _comparator_fn cmp); \
+void name ## _scan(name a, name ##_scanner *scan); \
+bool name ## _next(name ##_scanner *scan, type *data); \
+bool name ## _empty(name a); \
+void name ## _clear(name a); \
+bool name ## _member(name a, type data); \
+name name ## _reverse(name a); \
+name name ## _from_array(region r,type data[], int length);
+
+#define DEFINE_LIST(name,type) \
+name new_ ## name(region r) \
+{ \
+ return (name)new_list(r); \
+} \
+int name ## _length(name a) \
+{ \
+ return list_size((struct list *)a); \
+} \
+name name ## _cons(type data, name a) \
+{ \
+ return (name)list_cons((void *)data,(struct list *) a ); \
+}\
+name name ## _append(name a, name b) \
+{ \
+ return (name)list_append((struct list *)a,(struct list *)b); \
+} \
+name name ## _app(name a, name ## _app_fn app) \
+{ \
+ return (name)list_app((struct list *) a, (app_fn) app); \
+} \
+type name ## _find(name a, name ## _eq_fn eq) \
+{ \
+ return (type)list_find((struct list *)a, (eq_fn) eq); \
+} \
+name name ## _tail(name a) \
+{\
+ return (name)list_tail((struct list *)a);\
+}\
+type name ## _head(name a) \
+{ \
+ return (type)list_head((struct list *)a); \
+} \
+name name ## _filter(region r,name a, name ## _eq_fn eq) \
+{ \
+ return (name)list_filter(r,(struct list *)a, (eq_fn) eq); \
+} \
+name name ## _keep(name a, name ## _eq_fn eq) \
+{ \
+ return (name)list_keep((struct list *)a, (eq_fn) eq); \
+} \
+name name ## _filter2(name a, name ## _eq_fn eq) \
+{ \
+ return (name)list_filter2((struct list *)a, (eq_fn) eq); \
+} \
+name name ## _copy(region r, name a) \
+{ \
+ return (name)list_copy(r,(struct list *) a); \
+} \
+name name ## _sort(name a, name ## _comparator_fn cmp) \
+{ \
+ return (name)list_sort((struct list *)a,(comparator_fn) cmp); \
+} \
+name name ## _merge(name a,name b, name ## _comparator_fn cmp) \
+{ \
+ return (name)list_merge((struct list *)a,(struct list *)b,(comparator_fn)cmp); \
+} \
+void name ## _scan(name a, name ##_scanner *scan) \
+{ \
+ list_scan((struct list *)a,(struct list_scanner *)scan);\
+}\
+bool name ## _next(name ##_scanner *scan, type *data) \
+{ \
+ return list_next((struct list_scanner *)scan, (void **)data); \
+} \
+bool name ## _empty(name a) \
+{ \
+ return list_empty((struct list *)a); \
+} \
+void name ## _clear(name a) \
+{ \
+ list_clear((struct list *)a); \
+} \
+bool name ## _member(name a, type data) \
+{ \
+ return list_member((struct list *)a,(void *)data); \
+} \
+name name ## _reverse(name a) \
+{\
+ return (name)list_reverse((struct list *)a);\
+}\
+name name ## _from_array(region r,type data[], int length) \
+{\
+ return (name)list_from_array(r,(void **)data,length); \
+}\
+
+#endif /* LIST_H */
diff --git a/libbanshee/engine/malloc.c b/libbanshee/engine/malloc.c
new file mode 100644
index 00000000000..84facdb0160
--- /dev/null
+++ b/libbanshee/engine/malloc.c
@@ -0,0 +1,5400 @@
+/*
+ This is a version (aka dlmalloc) of malloc/free/realloc written by
+ Doug Lea and released to the public domain. Use, modify, and
+ redistribute this code without permission or acknowledgement in any
+ way you wish. Send questions, comments, complaints, performance
+ data, etc to dl@cs.oswego.edu
+
+* VERSION 2.7.0 Sun Mar 11 14:14:06 2001 Doug Lea (dl at gee)
+
+ Note: There may be an updated version of this malloc obtainable at
+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c
+ Check before installing!
+
+* Quickstart
+
+ This library is all in one file to simplify the most common usage:
+ ftp it, compile it (-O), and link it into another program. All
+ of the compile-time options default to reasonable values for use on
+ most unix platforms. Compile -DWIN32 for reasonable defaults on windows.
+ You might later want to step through various compile-time and dynamic
+ tuning options.
+
+ For convenience, an include file for code using this malloc is at:
+ ftp://gee.cs.oswego.edu/pub/misc/malloc-2.7.0.h
+ You don't really need this .h file unless you call functions not
+ defined in your system include files. The .h file contains only the
+ excerpts from this file needed for using this malloc on ANSI C/C++
+ systems, so long as you haven't changed compile-time options about
+ naming and tuning parameters. If you do, then you can create your
+ own malloc.h that does include all settings by cutting at the point
+ indicated below.
+
+* Why use this malloc?
+
+ This is not the fastest, most space-conserving, most portable, or
+ most tunable malloc ever written. However it is among the fastest
+ while also being among the most space-conserving, portable and tunable.
+ Consistent balance across these factors results in a good general-purpose
+ allocator for malloc-intensive programs.
+
+ The main properties of the algorithms are:
+ * For large (>= 512 bytes) requests, it is a pure best-fit allocator,
+ with ties normally decided via FIFO (i.e. least recently used).
+ * For small (<= 64 bytes by default) requests, it is a caching
+ allocator, that maintains pools of quickly recycled chunks.
+ * In between, and for combinations of large and small requests, it does
+ the best it can trying to meet both goals at once.
+ * For very large requests (>= 128KB by default), it relies on system
+ memory mapping facilities, if supported.
+
+ For a longer but slightly out of date high-level description, see
+ http://gee.cs.oswego.edu/dl/html/malloc.html
+
+ You may already by default be using a C library containing a malloc
+ that is based on some version of this malloc (for example in
+ linux). You might still want to use the one in this file in order to
+ customize settings or to avoid overheads associated with library
+ versions.
+
+* Contents, described in more detail in "description of public routines" below.
+
+ Standard (ANSI/SVID/...) functions:
+ malloc(size_t n);
+ calloc(size_t n_elements, size_t element_size);
+ free(Void_t* p);
+ realloc(Void_t* p, size_t n);
+ memalign(size_t alignment, size_t n);
+ valloc(size_t n);
+ mallinfo()
+ mallopt(int parameter_number, int parameter_value)
+
+ Additional functions:
+ independent_calloc(size_t n_elements, size_t size, Void_t* chunks[]);
+ independent_comalloc(size_t n_elements, size_t sizes[], Void_t* chunks[]);
+ pvalloc(size_t n);
+ cfree(Void_t* p);
+ malloc_trim(size_t pad);
+ malloc_usable_size(Void_t* p);
+ malloc_stats();
+
+* Vital statistics:
+
+ Supported pointer representation: 4 or 8 bytes
+ Supported size_t representation: 4 or 8 bytes
+ Note that size_t is allowed to be 4 bytes even if pointers are 8.
+ You can adjust this by defining INTERNAL_SIZE_T
+
+ Alignment: 2 * sizeof(size_t) (default)
+ (i.e., 8 byte alignment with 4byte size_t). This suffices for
+ nearly all current machines and C compilers. However, you can
+ define MALLOC_ALIGNMENT to be wider than this if necessary.
+
+ Minimum overhead per allocated chunk: 4 or 8 bytes
+ Each malloced chunk has a hidden word of overhead holding size
+ and status information.
+
+ Minimum allocated size: 4-byte ptrs: 16 bytes (including 4 overhead)
+ 8-byte ptrs: 24/32 bytes (including, 4/8 overhead)
+
+ When a chunk is freed, 12 (for 4byte ptrs) or 20 (for 8 byte
+ ptrs but 4 byte size) or 24 (for 8/8) additional bytes are
+ needed; 4 (8) for a trailing size field and 8 (16) bytes for
+ free list pointers. Thus, the minimum allocatable size is
+ 16/24/32 bytes.
+
+ Even a request for zero bytes (i.e., malloc(0)) returns a
+ pointer to something of the minimum allocatable size.
+
+ The maximum overhead wastage (i.e., number of extra bytes
+ allocated than were requested in malloc) is less than or equal
+ to the minimum size, except for requests >= mmap_threshold that
+ are serviced via mmap(), where the worst case wastage is 2 *
+ sizeof(size_t) bytes plus the remainder from a system page (the
+ minimal mmap unit); typically 4096 or 8192 bytes.
+
+ Maximum allocated size: 4-byte size_t: 2^32 minus about two pages
+ 8-byte size_t: 2^64 minus about two pages
+
+ It is assumed that (possibly signed) size_t values suffice to
+ represent chunk sizes. `Possibly signed' is due to the fact
+ that `size_t' may be defined on a system as either a signed or
+ an unsigned type. The ISO C standard says that it must be
+ unsigned, but a few systems are known not to adhere to this.
+ Additionally, even when size_t is unsigned, sbrk (which is by
+ default used to obtain memory from system) accepts signed
+ arguments, and may not be able to handle size_t-wide arguments
+ with negative sign bit. Generally, values that would
+ appear as negative after accounting for overhead and alignment
+ are supported only via mmap(), which does not have this
+ limitation.
+
+ Requests for sizes outside the allowed range will perform an optional
+ failure action and then return null. (Requests may also
+ also fail because a system is out of memory.)
+
+ Thread-safety: NOT thread-safe unless USE_MALLOC_LOCK defined
+
+ When USE_MALLOC_LOCK is defined, wrappers are created to
+ surround every public call with either a pthread mutex or
+ a win32 spinlock (depending on WIN32). This is not
+ especially fast, and can be a major bottleneck.
+ It is designed only to provide minimal protection
+ in concurrent environments, and to provide a basis for
+ extensions. If you are using malloc in a concurrent program,
+ you would be far better off obtaining ptmalloc, which is
+ derived from a version of this malloc, and is well-tuned for
+ concurrent programs. (See http://www.malloc.de)
+
+ Compliance: I believe it is compliant with the 1997 Single Unix Specification
+ (See http://www.opennc.org). Also SVID/XPG, ANSI C, and probably
+ others as well.
+
+* Synopsis of compile-time options:
+
+ People have reported using previous versions of this malloc on all
+ versions of Unix, sometimes by tweaking some of the defines
+ below. It has been tested most extensively on Solaris and
+ Linux. It is also reported to work on WIN32 platforms.
+ People also report using it in stand-alone embedded systems.
+
+ The implementation is in straight, hand-tuned ANSI C. It is not
+ at all modular. (Sorry!) It uses a lot of macros. To be at all
+ usable, this code should be compiled using an optimizing compiler
+ (for example gcc -O3) that can simplify expressions and control
+ paths. (FAQ: some macros import variables as arguments rather than
+ declare locals because people reported that some debuggers
+ otherwise get confused.)
+
+ OPTION DEFAULT VALUE
+
+ Compilation Environment options:
+
+ __STD_C derived from C compiler defines
+ WIN32 NOT defined
+ HAVE_MEMCPY defined
+ USE_MEMCPY 1 if HAVE_MEMCPY is defined
+ HAVE_MMAP defined as 1
+ MMAP_CLEARS 1
+ HAVE_MREMAP 0 unless linux defined
+ malloc_getpagesize derived from system #includes, or 4096 if not
+ HAVE_USR_INCLUDE_MALLOC_H NOT defined
+ LACKS_UNISTD_H NOT defined unless WIN32
+ LACKS_SYS_PARAM_H NOT defined unless WIN32
+ LACKS_SYS_MMAN_H NOT defined unless WIN32
+
+ Changing default word sizes:
+
+ INTERNAL_SIZE_T size_t
+ MALLOC_ALIGNMENT 2 * sizeof(INTERNAL_SIZE_T)
+
+ Configuration and functionality options:
+
+ USE_DL_PREFIX NOT defined
+ USE_PUBLIC_MALLOC_WRAPPERS NOT defined
+ USE_MALLOC_LOCK NOT defined
+ DEBUG NOT defined
+ REALLOC_ZERO_BYTES_FREES NOT defined
+ MALLOC_FAILURE_ACTION errno = ENOMEM, if __STD_C defined, else no-op
+ TRIM_FASTBINS 0
+
+ Options for customizing MORECORE:
+
+ MORECORE sbrk
+ MORECORE_CONTIGUOUS 1
+ MORECORE_CANNOT_TRIM NOT defined
+ MMAP_AS_MORECORE_SIZE (1024 * 1024)
+
+ Tuning options that are also dynamically changeable via mallopt:
+
+ DEFAULT_MXFAST 64
+ DEFAULT_TRIM_THRESHOLD 128 * 1024
+ DEFAULT_TOP_PAD 0
+ DEFAULT_MMAP_THRESHOLD 128 * 1024
+ DEFAULT_MMAP_MAX 65536
+
+ There are several other #defined constants and macros that you
+ probably don't want to touch unless you are extending or adapting malloc.
+*/
+
+/*
+ WIN32 sets up defaults for MS environment and compilers.
+ Otherwise defaults are for unix.
+*/
+
+/* #define WIN32 */
+
+#ifdef WIN32
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+/* Win32 doesn't supply or need the following headers */
+#define LACKS_UNISTD_H
+#define LACKS_SYS_PARAM_H
+#define LACKS_SYS_MMAN_H
+
+/* Use the supplied emulation of sbrk */
+#define MORECORE sbrk
+#define MORECORE_CONTIGUOUS 1
+#define MORECORE_FAILURE ((void*)(-1))
+
+/* Use the supplied emulation of mmap and munmap */
+#define HAVE_MMAP 1
+#define MUNMAP_FAILURE (-1)
+#define MMAP_CLEARS 1
+
+/* These values don't really matter in windows mmap emulation */
+#define MAP_PRIVATE 1
+#define MAP_ANONYMOUS 2
+#define PROT_READ 1
+#define PROT_WRITE 2
+
+/* Emulation functions defined at the end of this file */
+
+/* If USE_MALLOC_LOCK, use supplied critical-section-based lock functions */
+#ifdef USE_MALLOC_LOCK
+static int slwait(int *sl);
+static int slrelease(int *sl);
+#endif
+
+static long getpagesize(void);
+static long getregionsize(void);
+static void *sbrk(long size);
+static void *mmap(void *ptr, long size, long prot, long type, long handle, long arg);
+static long munmap(void *ptr, long size);
+
+static void vminfo (unsigned long *free, unsigned long *reserved, unsigned long *committed);
+static int cpuinfo (int whole, unsigned long *kernel, unsigned long *user);
+
+#endif
+
+/*
+ __STD_C should be nonzero if using ANSI-standard C compiler, a C++
+ compiler, or a C compiler sufficiently close to ANSI to get away
+ with it.
+*/
+
+#ifndef __STD_C
+#if defined(__STDC__) || defined(_cplusplus)
+#define __STD_C 1
+#else
+#define __STD_C 0
+#endif
+#endif /*__STD_C*/
+
+
+/*
+ Void_t* is the pointer type that malloc should say it returns
+*/
+
+#ifndef Void_t
+#if (__STD_C || defined(WIN32))
+#define Void_t void
+#else
+#define Void_t char
+#endif
+#endif /*Void_t*/
+
+#if __STD_C
+#include <stddef.h> /* for size_t */
+#else
+#include <sys/types.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* define LACKS_UNISTD_H if your system does not have a <unistd.h>. */
+
+/* #define LACKS_UNISTD_H */
+
+#ifndef LACKS_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* define LACKS_SYS_PARAM_H if your system does not have a <sys/param.h>. */
+
+/* #define LACKS_SYS_PARAM_H */
+
+
+#include <stdio.h> /* needed for malloc_stats */
+#include <errno.h> /* needed for optional MALLOC_FAILURE_ACTION */
+
+
+/*
+ Debugging:
+
+ Because freed chunks may be overwritten with bookkeeping fields, this
+ malloc will often die when freed memory is overwritten by user
+ programs. This can be very effective (albeit in an annoying way)
+ in helping track down dangling pointers.
+
+ If you compile with -DDEBUG, a number of assertion checks are
+ enabled that will catch more memory errors. You probably won't be
+ able to make much sense of the actual assertion errors, but they
+ should help you locate incorrectly overwritten memory. The
+ checking is fairly extensive, and will slow down execution
+ noticeably. Calling malloc_stats or mallinfo with DEBUG set will
+ attempt to check every non-mmapped allocated and free chunk in the
+ course of computing the summmaries. (By nature, mmapped regions
+ cannot be checked very much automatically.)
+
+ Setting DEBUG may also be helpful if you are trying to modify
+ this code. The assertions in the check routines spell out in more
+ detail the assumptions and invariants underlying the algorithms.
+
+ Setting DEBUG does NOT provide an automated mechanism for checking
+ that all accesses to malloced memory stay within their
+ bounds. However, there are several add-ons and adaptations of this
+ or other mallocs available that do this.
+*/
+
+#if DEBUG
+#include <assert.h>
+#else
+#define assert(x) ((void)0)
+#endif
+
+
+/*
+ INTERNAL_SIZE_T is the word-size used for internal bookkeeping
+ of chunk sizes.
+
+ The default version is the same as size_t.
+
+ While not strictly necessary, it is best to define this as an
+ unsigned type, even if size_t is a signed type. This may avoid some
+ artificial size limitations on some systems.
+
+ On a 64-bit machine, you may be able to reduce malloc overhead by
+ defining INTERNAL_SIZE_T to be a 32 bit `unsigned int' at the
+ expense of not being able to handle more than 2^32 of malloced
+ space. If this limitation is acceptable, you are encouraged to set
+ this unless you are on a platform requiring 16byte alignments. In
+ this case the alignment requirements turn out to negate any
+ potential advantages of decreasing size_t word size.
+
+ Implementors: Beware of the possible combinations of:
+ - INTERNAL_SIZE_T might be signed or unsigned, might be 32 or 64 bits,
+ and might be the same width as int or as long
+ - size_t might have different width and signedness as INTERNAL_SIZE_T
+ - int and long might be 32 or 64 bits, and might be the same width
+ To deal with this, most comparisons and difference computations
+ among INTERNAL_SIZE_Ts should cast them to unsigned long, being
+ aware of the fact that casting an unsigned int to a wider long does
+ not sign-extend. (This also makes checking for negative numbers
+ awkward.) Some of these casts result in harmless compiler warnings
+ on some systems.
+*/
+
+#ifndef INTERNAL_SIZE_T
+#define INTERNAL_SIZE_T size_t
+#endif
+
+/* The corresponding word size */
+#define SIZE_SZ (sizeof(INTERNAL_SIZE_T))
+
+
+/*
+ MALLOC_ALIGNMENT is the minimum alignment for malloc'ed chunks.
+ It must be a power of two at least 2 * SIZE_SZ, even on machines
+ for which smaller alignments would suffice. It may be defined as
+ larger than this though. Note however that code and data structures
+ are optimized for the case of 8-byte alignment.
+*/
+
+
+#ifndef MALLOC_ALIGNMENT
+#define MALLOC_ALIGNMENT (2 * SIZE_SZ)
+#endif
+
+/* The corresponding bit mask value */
+#define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1)
+
+
+
+/*
+ REALLOC_ZERO_BYTES_FREES should be set if a call to
+ realloc with zero bytes should be the same as a call to free.
+ Some people think it should. Otherwise, since this malloc
+ returns a unique pointer for malloc(0), so does realloc(p, 0).
+*/
+
+/* #define REALLOC_ZERO_BYTES_FREES */
+
+/*
+ TRIM_FASTBINS controls whether free() of a very small chunk can
+ immediately lead to trimming. Setting to true (1) can reduce memory
+ footprint, but will almost always slow down programs that use a lot
+ of small chunks.
+
+ Define this only if you are willing to give up some speed to more
+ aggressively reduce system-level memory footprint when releasing
+ memory in programs that use many small chunks. You can get
+ essentially the same effect by setting MXFAST to 0, but this can
+ lead to even greater slowdowns in programs using many small chunks.
+ TRIM_FASTBINS is an in-between compile-time option, that disables
+ only those chunks bordering topmost memory from being placed in
+ fastbins.
+*/
+
+#ifndef TRIM_FASTBINS
+#define TRIM_FASTBINS 0
+#endif
+
+
+/*
+ USE_DL_PREFIX will prefix all public routines with the string 'dl'.
+ This is necessary when you only want to use this malloc in one part
+ of a program, using your regular system malloc elsewhere.
+*/
+
+/* #define USE_DL_PREFIX */
+
+
+/*
+ USE_MALLOC_LOCK causes wrapper functions to surround each
+ callable routine with pthread mutex lock/unlock.
+
+ USE_MALLOC_LOCK forces USE_PUBLIC_MALLOC_WRAPPERS to be defined
+*/
+
+
+/* #define USE_MALLOC_LOCK */
+
+
+/*
+ If USE_PUBLIC_MALLOC_WRAPPERS is defined, every public routine is
+ actually a wrapper function that first calls MALLOC_PREACTION, then
+ calls the internal routine, and follows it with
+ MALLOC_POSTACTION. This is needed for locking, but you can also use
+ this, without USE_MALLOC_LOCK, for purposes of interception,
+ instrumentation, etc. It is a sad fact that using wrappers often
+ noticeably degrades performance of malloc-intensive programs.
+*/
+
+#ifdef USE_MALLOC_LOCK
+#define USE_PUBLIC_MALLOC_WRAPPERS
+#else
+/* #define USE_PUBLIC_MALLOC_WRAPPERS */
+#endif
+
+
+/*
+ Two-phase name translation.
+ All of the actual routines are given mangled names.
+ When wrappers are used, they become the public callable versions.
+ When DL_PREFIX is used, the callable names are prefixed.
+*/
+
+#ifndef USE_PUBLIC_MALLOC_WRAPPERS
+#define cALLOc public_cALLOc
+#define fREe public_fREe
+#define cFREe public_cFREe
+#define mALLOc public_mALLOc
+#define mEMALIGn public_mEMALIGn
+#define rEALLOc public_rEALLOc
+#define vALLOc public_vALLOc
+#define pVALLOc public_pVALLOc
+#define mALLINFo public_mALLINFo
+#define mALLOPt public_mALLOPt
+#define mTRIm public_mTRIm
+#define mSTATs public_mSTATs
+#define mUSABLe public_mUSABLe
+#define iCALLOc public_iCALLOc
+#define iCOMALLOc public_iCOMALLOc
+#endif
+
+#ifdef USE_DL_PREFIX
+#define public_cALLOc dlcalloc
+#define public_fREe dlfree
+#define public_cFREe dlcfree
+#define public_mALLOc dlmalloc
+#define public_mEMALIGn dlmemalign
+#define public_rEALLOc dlrealloc
+#define public_vALLOc dlvalloc
+#define public_pVALLOc dlpvalloc
+#define public_mALLINFo dlmallinfo
+#define public_mALLOPt dlmallopt
+#define public_mTRIm dlmalloc_trim
+#define public_mSTATs dlmalloc_stats
+#define public_mUSABLe dlmalloc_usable_size
+#define public_iCALLOc dlindependent_calloc
+#define public_iCOMALLOc dlindependent_comalloc
+#else /* USE_DL_PREFIX */
+#define public_cALLOc calloc
+#define public_fREe free
+#define public_cFREe cfree
+#define public_mALLOc malloc
+#define public_mEMALIGn memalign
+#define public_rEALLOc realloc
+#define public_vALLOc valloc
+#define public_pVALLOc pvalloc
+#define public_mALLINFo mallinfo
+#define public_mALLOPt mallopt
+#define public_mTRIm malloc_trim
+#define public_mSTATs malloc_stats
+#define public_mUSABLe malloc_usable_size
+#define public_iCALLOc independent_calloc
+#define public_iCOMALLOc independent_comalloc
+#endif /* USE_DL_PREFIX */
+
+
+/*
+ HAVE_MEMCPY should be defined if you are not otherwise using
+ ANSI STD C, but still have memcpy and memset in your C library
+ and want to use them in calloc and realloc. Otherwise simple
+ macro versions are defined below.
+
+ USE_MEMCPY should be defined as 1 if you actually want to
+ have memset and memcpy called. People report that the macro
+ versions are faster than libc versions on some systems.
+
+ Even if USE_MEMCPY is set to 1, loops to copy/clear small chunks
+ (of <= 36 bytes) are manually unrolled in realloc and calloc.
+*/
+
+#define HAVE_MEMCPY
+
+#ifndef USE_MEMCPY
+#ifdef HAVE_MEMCPY
+#define USE_MEMCPY 1
+#else
+#define USE_MEMCPY 0
+#endif
+#endif
+
+
+#if (__STD_C || defined(HAVE_MEMCPY))
+
+#ifdef WIN32
+/* On Win32 memset and memcpy are already declared in windows.h */
+#else
+#if __STD_C
+void* memset(void*, int, size_t);
+void* memcpy(void*, const void*, size_t);
+#else
+Void_t* memset();
+Void_t* memcpy();
+#endif
+#endif
+#endif
+
+/*
+ MALLOC_FAILURE_ACTION is the action to take before "return 0" when
+ malloc fails to be able to return memory, either because memory is
+ exhausted or because of illegal arguments.
+
+ By default, sets errno if running on STD_C platform, else does nothing.
+*/
+
+#ifndef MALLOC_FAILURE_ACTION
+#if __STD_C
+#define MALLOC_FAILURE_ACTION \
+ errno = ENOMEM;
+
+#else
+#define MALLOC_FAILURE_ACTION
+#endif
+#endif
+
+/*
+ MORECORE-related declarations. By default, rely on sbrk
+*/
+
+
+#ifdef LACKS_UNISTD_H
+#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
+#if __STD_C
+extern Void_t* sbrk(ptrdiff_t);
+#else
+extern Void_t* sbrk();
+#endif
+#endif
+#endif
+
+/*
+ MORECORE is the name of the routine to call to obtain more memory
+ from the system. See below for general guidance on writing
+ alternative MORECORE functions, as well as a version for WIN32 and a
+ sample version for pre-OSX macos.
+*/
+
+#ifndef MORECORE
+#define MORECORE sbrk
+#endif
+
+/*
+ MORECORE_FAILURE is the value returned upon failure of MORECORE
+ as well as mmap. Since it cannot be an otherwise valid memory address,
+ and must reflect values of standard sys calls, you probably ought not
+ try to redefine it.
+*/
+
+#ifndef MORECORE_FAILURE
+#define MORECORE_FAILURE (-1)
+#endif
+
+/*
+ If MORECORE_CONTIGUOUS is true, take advantage of fact that
+ consecutive calls to MORECORE with positive arguments always return
+ contiguous increasing addresses. This is true of unix sbrk. Even
+ if not defined, when regions happen to be contiguous, malloc will
+ permit allocations spanning regions obtained from different
+ calls. But defining this when applicable enables some stronger
+ consistency checks and space efficiencies.
+*/
+
+#ifndef MORECORE_CONTIGUOUS
+#define MORECORE_CONTIGUOUS 1
+#endif
+
+/*
+ Define MORECORE_CANNOT_TRIM if your version of MORECORE
+ cannot release space back to the system when given negative
+ arguments. This is generally necessary only if you are using
+ a hand-crafted MORECORE function that cannot handle negative arguments.
+*/
+
+/* #define MORECORE_CANNOT_TRIM */
+
+
+/*
+ Define HAVE_MMAP as true to optionally make malloc() use mmap() to
+ allocate very large blocks. These will be returned to the
+ operating system immediately after a free(). Also, if mmap
+ is available, it is used as a backup strategy in cases where
+ MORECORE fails to provide space from system.
+
+ This malloc is best tuned to work with mmap for large requests.
+ If you do not have mmap, operations involving very large chunks (1MB
+ or so) may be slower than you'd like.
+*/
+
+#ifndef HAVE_MMAP
+#define HAVE_MMAP 1
+
+/*
+ Standard unix mmap using /dev/zero clears memory so calloc doesn't
+ need to.
+*/
+
+#ifndef MMAP_CLEARS
+#define MMAP_CLEARS 1
+#endif
+
+#else /* no mmap */
+#ifndef MMAP_CLEARS
+#define MMAP_CLEARS 0
+#endif
+#endif
+
+
+/*
+ MMAP_AS_MORECORE_SIZE is the minimum mmap size argument to use if
+ sbrk fails, and mmap is used as a backup (which is done only if
+ HAVE_MMAP). The value must be a multiple of page size. This
+ backup strategy generally applies only when systems have "holes" in
+ address space, so sbrk cannot perform contiguous expansion, but
+ there is still space available on system. On systems for which
+ this is known to be useful (i.e. most linux kernels), this occurs
+ only when programs allocate huge amounts of memory. Between this,
+ and the fact that mmap regions tend to be limited, the size should
+ be large, to avoid too many mmap calls and thus avoid running out
+ of kernel resources.
+*/
+
+#ifndef MMAP_AS_MORECORE_SIZE
+#define MMAP_AS_MORECORE_SIZE (1024 * 1024)
+#endif
+
+/*
+ Define HAVE_MREMAP to make realloc() use mremap() to re-allocate
+ large blocks. This is currently only possible on Linux with
+ kernel versions newer than 1.3.77.
+*/
+
+#ifndef HAVE_MREMAP
+#ifdef linux
+#define HAVE_MREMAP 1
+#else
+#define HAVE_MREMAP 0
+#endif
+
+#endif /* HAVE_MMAP */
+
+
+/*
+ The system page size. To the extent possible, this malloc manages
+ memory from the system in page-size units. Note that this value is
+ cached during initialization into a field of malloc_state. So even
+ if malloc_getpagesize is a function, it is only called once.
+
+ The following mechanics for getpagesize were adapted from bsd/gnu
+ getpagesize.h. If none of the system-probes here apply, a value of
+ 4096 is used, which should be OK: If they don't apply, then using
+ the actual value probably doesn't impact performance.
+*/
+
+
+#ifndef malloc_getpagesize
+
+#ifndef LACKS_UNISTD_H
+# include <unistd.h>
+#endif
+
+# ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */
+# ifndef _SC_PAGE_SIZE
+# define _SC_PAGE_SIZE _SC_PAGESIZE
+# endif
+# endif
+
+# ifdef _SC_PAGE_SIZE
+# define malloc_getpagesize sysconf(_SC_PAGE_SIZE)
+# else
+# if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)
+ extern size_t getpagesize();
+# define malloc_getpagesize getpagesize()
+# else
+# ifdef WIN32 /* use supplied emulation of getpagesize */
+# define malloc_getpagesize getpagesize()
+# else
+# ifndef LACKS_SYS_PARAM_H
+# include <sys/param.h>
+# endif
+# ifdef EXEC_PAGESIZE
+# define malloc_getpagesize EXEC_PAGESIZE
+# else
+# ifdef NBPG
+# ifndef CLSIZE
+# define malloc_getpagesize NBPG
+# else
+# define malloc_getpagesize (NBPG * CLSIZE)
+# endif
+# else
+# ifdef NBPC
+# define malloc_getpagesize NBPC
+# else
+# ifdef PAGESIZE
+# define malloc_getpagesize PAGESIZE
+# else /* just guess */
+# define malloc_getpagesize (4096)
+# endif
+# endif
+# endif
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/*
+ This version of malloc supports the standard SVID/XPG mallinfo
+ routine that returns a struct containing usage properties and
+ statistics. It should work on any SVID/XPG compliant system that has
+ a /usr/include/malloc.h defining struct mallinfo. (If you'd like to
+ install such a thing yourself, cut out the preliminary declarations
+ as described above and below and save them in a malloc.h file. But
+ there's no compelling reason to bother to do this.)
+
+ The main declaration needed is the mallinfo struct that is returned
+ (by-copy) by mallinfo(). The SVID/XPG malloinfo struct contains a
+ bunch of field that are not even meaningful in this version of
+ malloc. These fields are are instead filled by mallinfo() with
+ other numbers that might be of interest.
+
+ HAVE_USR_INCLUDE_MALLOC_H should be set if you have a
+ /usr/include/malloc.h file that includes a declaration of struct
+ mallinfo. If so, it is included; else an SVID2/XPG2 compliant
+ version is declared below. These must be precisely the same for
+ mallinfo() to work. The original SVID version of this struct,
+ defined on most systems with mallinfo, declares all fields as
+ ints. But some others define as unsigned long. If your system
+ defines the fields using a type of different width than listed here,
+ you must #include your system version and #define
+ HAVE_USR_INCLUDE_MALLOC_H.
+*/
+
+/* #define HAVE_USR_INCLUDE_MALLOC_H */
+
+#ifdef HAVE_USR_INCLUDE_MALLOC_H
+#include "/usr/include/malloc.h"
+#else
+
+/* SVID2/XPG mallinfo structure */
+
+struct mallinfo {
+ int arena; /* non-mmapped space allocated from system */
+ int ordblks; /* number of free chunks */
+ int smblks; /* number of fastbin blocks */
+ int hblks; /* number of mmapped regions */
+ int hblkhd; /* space in mmapped regions */
+ int usmblks; /* maximum total allocated space */
+ int fsmblks; /* space available in freed fastbin blocks */
+ int uordblks; /* total allocated space */
+ int fordblks; /* total free space */
+ int keepcost; /* top-most, releasable (via malloc_trim) space */
+};
+
+/*
+ SVID/XPG defines four standard parameter numbers for mallopt,
+ normally defined in malloc.h. Only one of these (M_MXFAST) is used
+ in this malloc. The others (M_NLBLKS, M_GRAIN, M_KEEP) don't apply,
+ so setting them has no effect. But this malloc also supports other
+ options in mallopt described below.
+*/
+#endif
+
+
+/* ---------- description of public routines ------------ */
+
+/*
+ malloc(size_t n)
+ Returns a pointer to a newly allocated chunk of at least n bytes, or null
+ if no space is available. Additionally, on failure, errno is
+ set to ENOMEM on ANSI C systems.
+
+ If n is zero, malloc returns a minumum-sized chunk. (The minimum
+ size is 16 bytes on most 32bit systems, and 24 or 32 bytes on 64bit
+ systems.) On most systems, size_t is an unsigned type, so calls
+ with negative arguments are interpreted as requests for huge amounts
+ of space, which will often fail. The maximum supported value of n
+ differs across systems, but is in all cases less than the maximum
+ representable value of a size_t.
+*/
+#if __STD_C
+Void_t* public_mALLOc(size_t);
+#else
+Void_t* public_mALLOc();
+#endif
+
+/*
+ free(Void_t* p)
+ Releases the chunk of memory pointed to by p, that had been previously
+ allocated using malloc or a related routine such as realloc.
+ It has no effect if p is null. It can have arbitrary (i.e., bad!)
+ effects if p has already been freed.
+
+ Unless disabled (using mallopt), freeing very large spaces will
+ when possible, automatically trigger operations that give
+ back unused memory to the system, thus reducing program footprint.
+*/
+#if __STD_C
+void public_fREe(Void_t*);
+#else
+void public_fREe();
+#endif
+
+/*
+ calloc(size_t n_elements, size_t element_size);
+ Returns a pointer to n_elements * element_size bytes, with all locations
+ set to zero.
+*/
+#if __STD_C
+Void_t* public_cALLOc(size_t, size_t);
+#else
+Void_t* public_cALLOc();
+#endif
+
+/*
+ realloc(Void_t* p, size_t n)
+ Returns a pointer to a chunk of size n that contains the same data
+ as does chunk p up to the minimum of (n, p's size) bytes, or null
+ if no space is available.
+
+ The returned pointer may or may not be the same as p. The algorithm
+ prefers extending p when possible, otherwise it employs the
+ equivalent of a malloc-copy-free sequence.
+
+ If p is null, realloc is equivalent to malloc.
+
+ If space is not available, realloc returns null, errno is set (if on
+ ANSI) and p is NOT freed.
+
+ if n is for fewer bytes than already held by p, the newly unused
+ space is lopped off and freed if possible. Unless the #define
+ REALLOC_ZERO_BYTES_FREES is set, realloc with a size argument of
+ zero (re)allocates a minimum-sized chunk.
+
+ Large chunks that were internally obtained via mmap will always
+ be reallocated using malloc-copy-free sequences unless
+ the system supports MREMAP (currently only linux).
+
+ The old unix realloc convention of allowing the last-free'd chunk
+ to be used as an argument to realloc is not supported.
+*/
+#if __STD_C
+Void_t* public_rEALLOc(Void_t*, size_t);
+#else
+Void_t* public_rEALLOc();
+#endif
+
+/*
+ memalign(size_t alignment, size_t n);
+ Returns a pointer to a newly allocated chunk of n bytes, aligned
+ in accord with the alignment argument.
+
+ The alignment argument should be a power of two. If the argument is
+ not a power of two, the nearest greater power is used.
+ 8-byte alignment is guaranteed by normal malloc calls, so don't
+ bother calling memalign with an argument of 8 or less.
+
+ Overreliance on memalign is a sure way to fragment space.
+*/
+#if __STD_C
+Void_t* public_mEMALIGn(size_t, size_t);
+#else
+Void_t* public_mEMALIGn();
+#endif
+
+/*
+ valloc(size_t n);
+ Equivalent to memalign(pagesize, n), where pagesize is the page
+ size of the system. If the pagesize is unknown, 4096 is used.
+*/
+#if __STD_C
+Void_t* public_vALLOc(size_t);
+#else
+Void_t* public_vALLOc();
+#endif
+
+
+
+/*
+ mallopt(int parameter_number, int parameter_value)
+ Sets tunable parameters The format is to provide a
+ (parameter-number, parameter-value) pair. mallopt then sets the
+ corresponding parameter to the argument value if it can (i.e., so
+ long as the value is meaningful), and returns 1 if successful else
+ 0. SVID/XPG/ANSI defines four standard param numbers for mallopt,
+ normally defined in malloc.h. Only one of these (M_MXFAST) is used
+ in this malloc. The others (M_NLBLKS, M_GRAIN, M_KEEP) don't apply,
+ so setting them has no effect. But this malloc also supports four
+ other options in mallopt. See below for details. Briefly, supported
+ parameters are as follows (listed defaults are for "typical"
+ configurations).
+
+ Symbol param # default allowed param values
+ M_MXFAST 1 64 0-80 (0 disables fastbins)
+ M_TRIM_THRESHOLD -1 128*1024 any (-1U disables trimming)
+ M_TOP_PAD -2 0 any
+ M_MMAP_THRESHOLD -3 128*1024 any (or 0 if no MMAP support)
+ M_MMAP_MAX -4 65536 any (0 disables use of mmap)
+*/
+#if __STD_C
+int public_mALLOPt(int, int);
+#else
+int public_mALLOPt();
+#endif
+
+
+/*
+ mallinfo()
+ Returns (by copy) a struct containing various summary statistics:
+
+ arena: current total non-mmapped bytes allocated from system
+ ordblks: the number of free chunks
+ smblks: the number of fastbin blocks (i.e., small chunks that
+ have been freed but not use resused or consolidated)
+ hblks: current number of mmapped regions
+ hblkhd: total bytes held in mmapped regions
+ usmblks: the maximum total allocated space. This will be greater
+ than current total if trimming has occurred.
+ fsmblks: total bytes held in fastbin blocks
+ uordblks: current total allocated space (normal or mmapped)
+ fordblks: total free space
+ keepcost: the maximum number of bytes that could ideally be released
+ back to system via malloc_trim. ("ideally" means that
+ it ignores page restrictions etc.)
+
+ Because these fields are ints, but internal bookkeeping may
+ be kept as longs, the reported values may wrap around zero and
+ thus be inaccurate.
+*/
+#if __STD_C
+struct mallinfo public_mALLINFo(void);
+#else
+struct mallinfo public_mALLINFo();
+#endif
+
+/*
+ independent_calloc(size_t n_elements, size_t element_size, Void_t* chunks[]);
+
+ independent_calloc is similar to calloc, but instead of returning a
+ single cleared space, it returns an array of pointers to n_elements
+ independent elements that can hold contents of size elem_size, each
+ of which starts out cleared, and can be independently freed,
+ realloc'ed etc. The elements are guaranteed to be adjacently
+ allocated (this is not guaranteed to occur with multiple callocs or
+ mallocs), which may also improve cache locality in some
+ applications.
+
+ The "chunks" argument is optional (i.e., may be null, which is
+ probably the most typical usage). If it is null, the returned array
+ is itself dynamically allocated and should also be freed when it is
+ no longer needed. Otherwise, the chunks array must be of at least
+ n_elements in length. It is filled in with the pointers to the
+ chunks.
+
+ In either case, independent_calloc returns this pointer array, or
+ null if the allocation failed. If n_elements is zero and "chunks"
+ is null, it returns a chunk representing an array with zero elements
+ (which should be freed if not wanted).
+
+ Each element must be individually freed when it is no longer
+ needed. If you'd like to instead be able to free all at once, you
+ should instead use regular calloc and assign pointers into this
+ space to represent elements. (In this case though, you cannot
+ independently free elements.)
+
+ independent_calloc simplifies and speeds up implementations of many
+ kinds of pools. It may also be useful when constructing large data
+ structures that initially have a fixed number of fixed-sized nodes,
+ but the number is not known at compile time, and some of the nodes
+ may later need to be freed. For example:
+
+ struct Node { int item; struct Node* next; };
+
+ struct Node* build_list() {
+ struct Node** pool;
+ int n = read_number_of_nodes_needed();
+ if (n <= 0) return 0;
+ pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0);
+ if (pool == 0) die();
+ // organize into a linked list...
+ struct Node* first = pool[0];
+ for (i = 0; i < n-1; ++i)
+ pool[i]->next = pool[i+1];
+ free(pool); // Can now free the array (or not, if it is needed later)
+ return first;
+ }
+*/
+#if __STD_C
+Void_t** public_iCALLOc(size_t, size_t, Void_t**);
+#else
+Void_t** public_iCALLOc();
+#endif
+
+/*
+ independent_comalloc(size_t n_elements, size_t sizes[], Void_t* chunks[]);
+
+ independent_comalloc allocates, all at once, a set of n_elements
+ chunks with sizes indicated in the "sizes" array. It returns
+ an array of pointers to these elements, each of which can be
+ independently freed, realloc'ed etc. The elements are guaranteed to
+ be adjacently allocated (this is not guaranteed to occur with
+ multiple callocs or mallocs), which may also improve cache locality
+ in some applications.
+
+ The "chunks" argument is optional (i.e., may be null). If it is null
+ the returned array is itself dynamically allocated and should also
+ be freed when it is no longer needed. Otherwise, the chunks array
+ must be of at least n_elements in length. It is filled in with the
+ pointers to the chunks.
+
+ In either case, independent_comalloc returns this pointer array, or
+ null if the allocation failed. If n_elements is zero and chunks is
+ null, it returns a chunk representing an array with zero elements
+ (which should be freed if not wanted).
+
+ Each element must be individually freed when it is no longer
+ needed. If you'd like to instead be able to free all at once, you
+ should instead use a single regular malloc, and assign pointers at
+ particular offsets in the aggregate space. (In this case though, you
+ cannot independently free elements.)
+
+ independent_comallac differs from independent_calloc in that each
+ element may have a different size, and also that it does not
+ automatically clear elements.
+
+ independent_comalloc can be used to speed up allocation in cases
+ where several structs or objects must always be allocated at the
+ same time. For example:
+
+ struct Head { ... }
+ struct Foot { ... }
+
+ void send_message(char* msg) {
+ int msglen = strlen(msg);
+ size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) };
+ void* chunks[3];
+ if (independent_comalloc(3, sizes, chunks) == 0)
+ die();
+ struct Head* head = (struct Head*)(chunks[0]);
+ char* body = (char*)(chunks[1]);
+ struct Foot* foot = (struct Foot*)(chunks[2]);
+ // ...
+ }
+
+ In general though, independent_comalloc is worth using only for
+ larger values of n_elements. For small values, you probably won't
+ detect enough difference from series of malloc calls to bother.
+
+ Overuse of independent_comalloc can increase overall memory usage,
+ since it cannot reuse existing noncontiguous small chunks that
+ might be available for some of the elements.
+*/
+#if __STD_C
+Void_t** public_iCOMALLOc(size_t, size_t*, Void_t**);
+#else
+Void_t** public_iCOMALLOc();
+#endif
+
+
+/*
+ pvalloc(size_t n);
+ Equivalent to valloc(minimum-page-that-holds(n)), that is,
+ round up n to nearest pagesize.
+ */
+#if __STD_C
+Void_t* public_pVALLOc(size_t);
+#else
+Void_t* public_pVALLOc();
+#endif
+
+/*
+ cfree(Void_t* p);
+ Equivalent to free(p).
+
+ cfree is needed/defined on some systems that pair it with calloc,
+ for odd historical reasons (such as: cfree is used in example
+ code in the first edition of K&R).
+*/
+#if __STD_C
+void public_cFREe(Void_t*);
+#else
+void public_cFREe();
+#endif
+
+/*
+ malloc_trim(size_t pad);
+
+ If possible, gives memory back to the system (via negative
+ arguments to sbrk) if there is unused memory at the `high' end of
+ the malloc pool. You can call this after freeing large blocks of
+ memory to potentially reduce the system-level memory requirements
+ of a program. However, it cannot guarantee to reduce memory. Under
+ some allocation patterns, some large free blocks of memory will be
+ locked between two used chunks, so they cannot be given back to
+ the system.
+
+ The `pad' argument to malloc_trim represents the amount of free
+ trailing space to leave untrimmed. If this argument is zero,
+ only the minimum amount of memory to maintain internal data
+ structures will be left (one page or less). Non-zero arguments
+ can be supplied to maintain enough trailing space to service
+ future expected allocations without having to re-obtain memory
+ from the system.
+
+ Malloc_trim returns 1 if it actually released any memory, else 0.
+ On systems that do not support "negative sbrks", it will always
+ rreturn 0.
+*/
+#if __STD_C
+int public_mTRIm(size_t);
+#else
+int public_mTRIm();
+#endif
+
+/*
+ malloc_usable_size(Void_t* p);
+
+ Returns the number of bytes you can actually use in
+ an allocated chunk, which may be more than you requested (although
+ often not) due to alignment and minimum size constraints.
+ You can use this many bytes without worrying about
+ overwriting other allocated objects. This is not a particularly great
+ programming practice. malloc_usable_size can be more useful in
+ debugging and assertions, for example:
+
+ p = malloc(n);
+ assert(malloc_usable_size(p) >= 256);
+
+*/
+#if __STD_C
+size_t public_mUSABLe(Void_t*);
+#else
+size_t public_mUSABLe();
+#endif
+
+/*
+ malloc_stats();
+ Prints on stderr the amount of space obtained from the system (both
+ via sbrk and mmap), the maximum amount (which may be more than
+ current if malloc_trim and/or munmap got called), and the current
+ number of bytes allocated via malloc (or realloc, etc) but not yet
+ freed. Note that this is the number of bytes allocated, not the
+ number requested. It will be larger than the number requested
+ because of alignment and bookkeeping overhead. Because it includes
+ alignment wastage as being in use, this figure may be greater than
+ zero even when no user-level chunks are allocated.
+
+ The reported current and maximum system memory can be inaccurate if
+ a program makes other calls to system memory allocation functions
+ (normally sbrk) outside of malloc.
+
+ malloc_stats prints only the most commonly interesting statistics.
+ More information can be obtained by calling mallinfo.
+
+*/
+#if __STD_C
+void public_mSTATs();
+#else
+void public_mSTATs();
+#endif
+
+/* mallopt tuning options */
+
+/*
+ M_MXFAST is the maximum request size used for "fastbins", special bins
+ that hold returned chunks without consolidating their spaces. This
+ enables future requests for chunks of the same size to be handled
+ very quickly, but can increase fragmentation, and thus increase the
+ overall memory footprint of a program.
+
+ This malloc manages fastbins very conservatively yet still
+ efficiently, so fragmentation is rarely a problem for values less
+ than or equal to the default. The maximum supported value of MXFAST
+ is 80. You wouldn't want it any higher than this anyway. Fastbins
+ are designed especially for use with many small structs, objects or
+ strings -- the default handles structs/objects/arrays with sizes up
+ to 8 4byte fields, or small strings representing words, tokens,
+ etc. Using fastbins for larger objects normally worsens
+ fragmentation without improving speed.
+
+ M_MXFAST is set in REQUEST size units. It is internally used in
+ chunksize units, which adds padding and alignment. You can reduce
+ M_MXFAST to 0 to disable all use of fastbins. This causes the malloc
+ algorithm to be a closer approximation of fifo-best-fit in all cases,
+ not just for larger requests, but will generally cause it to be
+ slower.
+*/
+
+
+/* M_MXFAST is a standard SVID/XPG tuning option, usually listed in malloc.h */
+#ifndef M_MXFAST
+#define M_MXFAST 1
+#endif
+
+#ifndef DEFAULT_MXFAST
+#define DEFAULT_MXFAST 64
+#endif
+
+
+/*
+ M_TRIM_THRESHOLD is the maximum amount of unused top-most memory
+ to keep before releasing via malloc_trim in free().
+
+ Automatic trimming is mainly useful in long-lived programs.
+ Because trimming via sbrk can be slow on some systems, and can
+ sometimes be wasteful (in cases where programs immediately
+ afterward allocate more large chunks) the value should be high
+ enough so that your overall system performance would improve by
+ releasing this much memory.
+
+ The trim threshold and the mmap control parameters (see below)
+ can be traded off with one another. Trimming and mmapping are
+ two different ways of releasing unused memory back to the
+ system. Between these two, it is often possible to keep
+ system-level demands of a long-lived program down to a bare
+ minimum. For example, in one test suite of sessions measuring
+ the XF86 X server on Linux, using a trim threshold of 128K and a
+ mmap threshold of 192K led to near-minimal long term resource
+ consumption.
+
+ If you are using this malloc in a long-lived program, it should
+ pay to experiment with these values. As a rough guide, you
+ might set to a value close to the average size of a process
+ (program) running on your system. Releasing this much memory
+ would allow such a process to run in memory. Generally, it's
+ worth it to tune for trimming rather tham memory mapping when a
+ program undergoes phases where several large chunks are
+ allocated and released in ways that can reuse each other's
+ storage, perhaps mixed with phases where there are no such
+ chunks at all. And in well-behaved long-lived programs,
+ controlling release of large blocks via trimming versus mapping
+ is usually faster.
+
+ However, in most programs, these parameters serve mainly as
+ protection against the system-level effects of carrying around
+ massive amounts of unneeded memory. Since frequent calls to
+ sbrk, mmap, and munmap otherwise degrade performance, the default
+ parameters are set to relatively high values that serve only as
+ safeguards.
+
+ The trim value It must be greater than page size to have any useful
+ effect. To disable trimming completely, you can set to
+ (unsigned long)(-1)
+
+ Trim settings interact with fastbin (MXFAST) settings: Unless
+ TRIM_FASTBINS is defined, automatic trimming never takes place upon
+ freeing a chunk with size less than or equal to MXFAST. Trimming is
+ instead delayed until subsequent freeing of larger chunks. However,
+ you can still force an attempted trim by calling malloc_trim.
+
+ Also, trimming is not generally possible in cases where
+ the main arena is obtained via mmap.
+
+ Note that the trick some people use of mallocing a huge space and
+ then freeing it at program startup, in an attempt to reserve system
+ memory, doesn't have the intended effect under automatic trimming,
+ since that memory will immediately be returned to the system.
+*/
+
+#define M_TRIM_THRESHOLD -1
+
+#ifndef DEFAULT_TRIM_THRESHOLD
+#define DEFAULT_TRIM_THRESHOLD (128 * 1024)
+#endif
+
+/*
+ M_TOP_PAD is the amount of extra `padding' space to allocate or
+ retain whenever sbrk is called. It is used in two ways internally:
+
+ * When sbrk is called to extend the top of the arena to satisfy
+ a new malloc request, this much padding is added to the sbrk
+ request.
+
+ * When malloc_trim is called automatically from free(),
+ it is used as the `pad' argument.
+
+ In both cases, the actual amount of padding is rounded
+ so that the end of the arena is always a system page boundary.
+
+ The main reason for using padding is to avoid calling sbrk so
+ often. Having even a small pad greatly reduces the likelihood
+ that nearly every malloc request during program start-up (or
+ after trimming) will invoke sbrk, which needlessly wastes
+ time.
+
+ Automatic rounding-up to page-size units is normally sufficient
+ to avoid measurable overhead, so the default is 0. However, in
+ systems where sbrk is relatively slow, it can pay to increase
+ this value, at the expense of carrying around more memory than
+ the program needs.
+*/
+
+#define M_TOP_PAD -2
+
+#ifndef DEFAULT_TOP_PAD
+#define DEFAULT_TOP_PAD (0)
+#endif
+
+/*
+ M_MMAP_THRESHOLD is the request size threshold for using mmap()
+ to service a request. Requests of at least this size that cannot
+ be allocated using already-existing space will be serviced via mmap.
+ (If enough normal freed space already exists it is used instead.)
+
+ Using mmap segregates relatively large chunks of memory so that
+ they can be individually obtained and released from the host
+ system. A request serviced through mmap is never reused by any
+ other request (at least not directly; the system may just so
+ happen to remap successive requests to the same locations).
+
+ Segregating space in this way has the benefits that:
+
+ 1. Mmapped space can ALWAYS be individually released back
+ to the system, which helps keep the system level memory
+ demands of a long-lived program low.
+ 2. Mapped memory can never become `locked' between
+ other chunks, as can happen with normally allocated chunks, which
+ means that even trimming via malloc_trim would not release them.
+ 3. On some systems with "holes" in address spaces, mmap can obtain
+ memory that sbrk cannot.
+
+ However, it has the disadvantages that:
+
+ 1. The space cannot be reclaimed, consolidated, and then
+ used to service later requests, as happens with normal chunks.
+ 2. It can lead to more wastage because of mmap page alignment
+ requirements
+ 3. It causes malloc performance to be more dependent on host
+ system memory management support routines which may vary in
+ implementation quality and may impose arbitrary
+ limitations. Generally, servicing a request via normal
+ malloc steps is faster than going through a system's mmap.
+
+ The advantages of mmap nearly always outweigh disadvantages for
+ "large" chunks, but the value of "large" varies across systems. The
+ default is an empirically derived value that works well in most
+ systems.
+*/
+
+#define M_MMAP_THRESHOLD -3
+
+#ifndef DEFAULT_MMAP_THRESHOLD
+#define DEFAULT_MMAP_THRESHOLD (128 * 1024)
+#endif
+
+/*
+ M_MMAP_MAX is the maximum number of requests to simultaneously
+ service using mmap. This parameter exists because
+. Some systems have a limited number of internal tables for
+ use by mmap, and using more than a few of them may degrade
+ performance.
+
+ The default is set to a value that serves only as a safeguard.
+ Setting to 0 disables use of mmap for servicing large requests. If
+ HAVE_MMAP is not set, the default value is 0, and attempts to set it
+ to non-zero values in mallopt will fail.
+*/
+
+#define M_MMAP_MAX -4
+
+#ifndef DEFAULT_MMAP_MAX
+#if HAVE_MMAP
+#define DEFAULT_MMAP_MAX (65536)
+#else
+#define DEFAULT_MMAP_MAX (0)
+#endif
+#endif
+
+#ifdef __cplusplus
+}; /* end of extern "C" */
+#endif
+
+/*
+ ========================================================================
+ To make a fully customizable malloc.h header file, cut everything
+ above this line, put into file malloc.h, edit to suit, and #include it
+ on the next line, as well as in programs that use this malloc.
+ ========================================================================
+*/
+
+/* #include "malloc.h" */
+
+/* --------------------- public wrappers ---------------------- */
+
+#ifdef USE_PUBLIC_MALLOC_WRAPPERS
+
+/* Declare all routines as internal */
+#if __STD_C
+static Void_t* mALLOc(size_t);
+static void fREe(Void_t*);
+static Void_t* rEALLOc(Void_t*, size_t);
+static Void_t* mEMALIGn(size_t, size_t);
+static Void_t* vALLOc(size_t);
+static Void_t* pVALLOc(size_t);
+static Void_t* cALLOc(size_t, size_t);
+static Void_t** iCALLOc(size_t, size_t, Void_t**);
+static Void_t** iCOMALLOc(size_t, size_t*, Void_t**);
+static void cFREe(Void_t*);
+static int mTRIm(size_t);
+static size_t mUSABLe(Void_t*);
+static void mSTATs();
+static int mALLOPt(int, int);
+static struct mallinfo mALLINFo(void);
+#else
+static Void_t* mALLOc();
+static void fREe();
+static Void_t* rEALLOc();
+static Void_t* mEMALIGn();
+static Void_t* vALLOc();
+static Void_t* pVALLOc();
+static Void_t* cALLOc();
+static Void_t** iCALLOc();
+static Void_t** iCOMALLOc();
+static void cFREe();
+static int mTRIm();
+static size_t mUSABLe();
+static void mSTATs();
+static int mALLOPt();
+static struct mallinfo mALLINFo();
+#endif
+
+/*
+ MALLOC_PREACTION and MALLOC_POSTACTION should be
+ defined to return 0 on success, and nonzero on failure.
+ The return value of MALLOC_POSTACTION is currently ignored
+ in wrapper functions since there is no reasonable default
+ action to take on failure.
+*/
+
+
+#ifdef USE_MALLOC_LOCK
+
+#ifdef WIN32
+
+static int mALLOC_MUTEx;
+#define MALLOC_PREACTION slwait(&mALLOC_MUTEx)
+#define MALLOC_POSTACTION slrelease(&mALLOC_MUTEx)
+
+#else
+
+#include <pthread.h>
+
+static pthread_mutex_t mALLOC_MUTEx = PTHREAD_MUTEX_INITIALIZER;
+
+#define MALLOC_PREACTION pthread_mutex_lock(&mALLOC_MUTEx)
+#define MALLOC_POSTACTION pthread_mutex_unlock(&mALLOC_MUTEx)
+
+#endif /* USE_MALLOC_LOCK */
+
+#else
+
+/* Substitute anything you like for these */
+
+#define MALLOC_PREACTION (0)
+#define MALLOC_POSTACTION (0)
+
+#endif
+
+Void_t* public_mALLOc(size_t bytes) {
+ Void_t* m;
+ if (MALLOC_PREACTION != 0) {
+ return 0;
+ }
+ m = mALLOc(bytes);
+ if (MALLOC_POSTACTION != 0) {
+ }
+ return m;
+}
+
+void public_fREe(Void_t* m) {
+ if (MALLOC_PREACTION != 0) {
+ return;
+ }
+ fREe(m);
+ if (MALLOC_POSTACTION != 0) {
+ }
+}
+
+Void_t* public_rEALLOc(Void_t* m, size_t bytes) {
+ if (MALLOC_PREACTION != 0) {
+ return 0;
+ }
+ m = rEALLOc(m, bytes);
+ if (MALLOC_POSTACTION != 0) {
+ }
+ return m;
+}
+
+Void_t* public_mEMALIGn(size_t alignment, size_t bytes) {
+ Void_t* m;
+ if (MALLOC_PREACTION != 0) {
+ return 0;
+ }
+ m = mEMALIGn(alignment, bytes);
+ if (MALLOC_POSTACTION != 0) {
+ }
+ return m;
+}
+
+Void_t* public_vALLOc(size_t bytes) {
+ Void_t* m;
+ if (MALLOC_PREACTION != 0) {
+ return 0;
+ }
+ m = vALLOc(bytes);
+ if (MALLOC_POSTACTION != 0) {
+ }
+ return m;
+}
+
+Void_t* public_pVALLOc(size_t bytes) {
+ Void_t* m;
+ if (MALLOC_PREACTION != 0) {
+ return 0;
+ }
+ m = pVALLOc(bytes);
+ if (MALLOC_POSTACTION != 0) {
+ }
+ return m;
+}
+
+Void_t* public_cALLOc(size_t n, size_t elem_size) {
+ Void_t* m;
+ if (MALLOC_PREACTION != 0) {
+ return 0;
+ }
+ m = cALLOc(n, elem_size);
+ if (MALLOC_POSTACTION != 0) {
+ }
+ return m;
+}
+
+
+Void_t** public_iCALLOc(size_t n, size_t elem_size, Void_t** chunks) {
+ Void_t** m;
+ if (MALLOC_PREACTION != 0) {
+ return 0;
+ }
+ m = iCALLOc(n, elem_size, chunks);
+ if (MALLOC_POSTACTION != 0) {
+ }
+ return m;
+}
+
+Void_t** public_iCOMALLOc(size_t n, size_t sizes[], Void_t** chunks) {
+ Void_t** m;
+ if (MALLOC_PREACTION != 0) {
+ return 0;
+ }
+ m = iCOMALLOc(n, sizes, chunks);
+ if (MALLOC_POSTACTION != 0) {
+ }
+ return m;
+}
+
+void public_cFREe(Void_t* m) {
+ if (MALLOC_PREACTION != 0) {
+ return;
+ }
+ cFREe(m);
+ if (MALLOC_POSTACTION != 0) {
+ }
+}
+
+int public_mTRIm(size_t s) {
+ int result;
+ if (MALLOC_PREACTION != 0) {
+ return 0;
+ }
+ result = mTRIm(s);
+ if (MALLOC_POSTACTION != 0) {
+ }
+ return result;
+}
+
+size_t public_mUSABLe(Void_t* m) {
+ size_t result;
+ if (MALLOC_PREACTION != 0) {
+ return 0;
+ }
+ result = mUSABLe(m);
+ if (MALLOC_POSTACTION != 0) {
+ }
+ return result;
+}
+
+void public_mSTATs() {
+ if (MALLOC_PREACTION != 0) {
+ return;
+ }
+ mSTATs();
+ if (MALLOC_POSTACTION != 0) {
+ }
+}
+
+struct mallinfo public_mALLINFo() {
+ struct mallinfo m;
+ if (MALLOC_PREACTION != 0) {
+ struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ return nm;
+ }
+ m = mALLINFo();
+ if (MALLOC_POSTACTION != 0) {
+ }
+ return m;
+}
+
+int public_mALLOPt(int p, int v) {
+ int result;
+ if (MALLOC_PREACTION != 0) {
+ return 0;
+ }
+ result = mALLOPt(p, v);
+ if (MALLOC_POSTACTION != 0) {
+ }
+ return result;
+}
+
+#endif
+
+
+
+/* ------------- Optional versions of memcopy ---------------- */
+
+
+#if USE_MEMCPY
+
+/*
+ Note: memcpy is ONLY invoked with non-overlapping regions,
+ so the (usually slower) memmove is not needed.
+*/
+
+#define MALLOC_COPY(dest, src, nbytes) memcpy(dest, src, nbytes)
+#define MALLOC_ZERO(dest, nbytes) memset(dest, 0, nbytes)
+
+#else /* !USE_MEMCPY */
+
+/* Use Duff's device for good zeroing/copying performance. */
+
+#define MALLOC_ZERO(charp, nbytes) \
+do { \
+ INTERNAL_SIZE_T* mzp = (INTERNAL_SIZE_T*)(charp); \
+ unsigned long mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T); \
+ long mcn; \
+ if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; } \
+ switch (mctmp) { \
+ case 0: for(;;) { *mzp++ = 0; \
+ case 7: *mzp++ = 0; \
+ case 6: *mzp++ = 0; \
+ case 5: *mzp++ = 0; \
+ case 4: *mzp++ = 0; \
+ case 3: *mzp++ = 0; \
+ case 2: *mzp++ = 0; \
+ case 1: *mzp++ = 0; if(mcn <= 0) break; mcn--; } \
+ } \
+} while(0)
+
+define MALLOC_COPY(dest,src,nbytes) \
+do { \
+ INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) src; \
+ INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) dest; \
+ unsigned long mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T); \
+ long mcn; \
+ if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; } \
+ switch (mctmp) { \
+ case 0: for(;;) { *mcdst++ = *mcsrc++; \
+ case 7: *mcdst++ = *mcsrc++; \
+ case 6: *mcdst++ = *mcsrc++; \
+ case 5: *mcdst++ = *mcsrc++; \
+ case 4: *mcdst++ = *mcsrc++; \
+ case 3: *mcdst++ = *mcsrc++; \
+ case 2: *mcdst++ = *mcsrc++; \
+ case 1: *mcdst++ = *mcsrc++; if(mcn <= 0) break; mcn--; } \
+ } \
+} while(0)
+
+#endif
+
+/* ------------------ MMAP support ------------------ */
+
+
+#if HAVE_MMAP
+
+#include <fcntl.h>
+#ifndef LACKS_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+
+#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+/*
+ Nearly all versions of mmap support MAP_ANONYMOUS,
+ so the following is unlikely to be needed, but is
+ supplied just in case.
+*/
+
+#ifndef MAP_ANONYMOUS
+
+static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */
+
+#define MMAP(addr, size, prot, flags) ((dev_zero_fd < 0) ? \
+ (dev_zero_fd = open("/dev/zero", O_RDWR), \
+ mmap((addr), (size), (prot), (flags), dev_zero_fd, 0)) : \
+ mmap((addr), (size), (prot), (flags), dev_zero_fd, 0))
+
+#else
+
+#define MMAP(addr, size, prot, flags) \
+ (mmap((addr), (size), (prot), (flags)|MAP_ANONYMOUS, -1, 0))
+
+#endif
+
+
+#endif /* HAVE_MMAP */
+
+
+/*
+ ----------------------- Chunk representations -----------------------
+*/
+
+
+/*
+ This struct declaration is misleading (but accurate and necessary).
+ It declares a "view" into memory allowing access to necessary
+ fields at known offsets from a given base. See explanation below.
+*/
+
+struct malloc_chunk {
+
+ INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */
+ INTERNAL_SIZE_T size; /* Size in bytes, including overhead. */
+
+ struct malloc_chunk* fd; /* double links -- used only if free. */
+ struct malloc_chunk* bk;
+};
+
+
+typedef struct malloc_chunk* mchunkptr;
+
+/*
+ malloc_chunk details:
+
+ (The following includes lightly edited explanations by Colin Plumb.)
+
+ Chunks of memory are maintained using a `boundary tag' method as
+ described in e.g., Knuth or Standish. (See the paper by Paul
+ Wilson ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a
+ survey of such techniques.) Sizes of free chunks are stored both
+ in the front of each chunk and at the end. This makes
+ consolidating fragmented chunks into bigger chunks very fast. The
+ size fields also hold bits representing whether chunks are free or
+ in use.
+
+ An allocated chunk looks like this:
+
+
+ chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Size of previous chunk, if allocated | |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Size of chunk, in bytes |P|
+ mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | User data starts here... .
+ . .
+ . (malloc_usable_space() bytes) .
+ . |
+nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Size of chunk |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+ Where "chunk" is the front of the chunk for the purpose of most of
+ the malloc code, but "mem" is the pointer that is returned to the
+ user. "Nextchunk" is the beginning of the next contiguous chunk.
+
+ Chunks always begin on even word boundries, so the mem portion
+ (which is returned to the user) is also on an even word boundary, and
+ thus at least double-word aligned.
+
+ Free chunks are stored in circular doubly-linked lists, and look like this:
+
+ chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Size of previous chunk |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ `head:' | Size of chunk, in bytes |P|
+ mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Forward pointer to next chunk in list |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Back pointer to previous chunk in list |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Unused space (may be 0 bytes long) .
+ . .
+ . |
+nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ `foot:' | Size of chunk, in bytes |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ The P (PREV_INUSE) bit, stored in the unused low-order bit of the
+ chunk size (which is always a multiple of two words), is an in-use
+ bit for the *previous* chunk. If that bit is *clear*, then the
+ word before the current chunk size contains the previous chunk
+ size, and can be used to find the front of the previous chunk.
+ The very first chunk allocated always has this bit set,
+ preventing access to non-existent (or non-owned) memory. If
+ prev_inuse is set for any given chunk, then you CANNOT determine
+ the size of the previous chunk, and might even get a memory
+ addressing fault when trying to do so.
+
+ Note that the `foot' of the current chunk is actually represented
+ as the prev_size of the NEXT chunk. This makes it easier to
+ deal with alignments etc but can be very confusing when trying
+ to extend or adapt this code.
+
+ The two exceptions to all this are
+
+ 1. The special chunk `top' doesn't bother using the
+ trailing size field since there is no next contiguous chunk
+ that would have to index off it. After initialization, `top'
+ is forced to always exist. If it would become less than
+ MINSIZE bytes long, it is replenished.
+
+ 2. Chunks allocated via mmap, which have the second-lowest-order
+ bit (IS_MMAPPED) set in their size fields. Because they are
+ allocated one-by-one, each must contain its own trailing size field.
+
+*/
+
+/*
+ ---------- Size and alignment checks and conversions ----------
+*/
+
+/* conversion from malloc headers to user pointers, and back */
+
+#define chunk2mem(p) ((Void_t*)((char*)(p) + 2*SIZE_SZ))
+#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - 2*SIZE_SZ))
+
+/* The smallest possible chunk */
+#define MIN_CHUNK_SIZE (sizeof(struct malloc_chunk))
+
+/* The smallest size we can malloc is an aligned minimal chunk */
+
+#define MINSIZE \
+ (unsigned long)(((MIN_CHUNK_SIZE+MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK))
+
+/* Check if m has acceptable alignment */
+
+#define aligned_OK(m) (((unsigned long)((m)) & (MALLOC_ALIGN_MASK)) == 0)
+
+
+/*
+ Check if a request is so large that it would wrap around zero when
+ padded and aligned. To simplify some other code, the bound is made
+ low enough so that adding MINSIZE will also not wrap around sero.
+*/
+
+#define REQUEST_OUT_OF_RANGE(req) \
+ ((unsigned long)(req) >= \
+ (unsigned long)(INTERNAL_SIZE_T)(-2 * MINSIZE))
+
+/* pad request bytes into a usable size -- internal version */
+
+#define request2size(req) \
+ (((req) + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE) ? \
+ MINSIZE : \
+ ((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)
+
+/* Same, except also perform argument check */
+
+#define checked_request2size(req, sz) \
+ if (REQUEST_OUT_OF_RANGE(req)) { \
+ MALLOC_FAILURE_ACTION; \
+ return 0; \
+ } \
+ (sz) = request2size(req);
+
+/*
+ --------------- Physical chunk operations ---------------
+*/
+
+
+/* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */
+#define PREV_INUSE 0x1
+
+/* extract inuse bit of previous chunk */
+#define prev_inuse(p) ((p)->size & PREV_INUSE)
+
+
+/* size field is or'ed with IS_MMAPPED if the chunk was obtained with mmap() */
+#define IS_MMAPPED 0x2
+
+/* check for mmap()'ed chunk */
+#define chunk_is_mmapped(p) ((p)->size & IS_MMAPPED)
+
+/*
+ Bits to mask off when extracting size
+
+ Note: IS_MMAPPED is intentionally not masked off from size field in
+ macros for which mmapped chunks should never be seen. This should
+ cause helpful core dumps to occur if it is tried by accident by
+ people extending or adapting this malloc.
+*/
+#define SIZE_BITS (PREV_INUSE|IS_MMAPPED)
+
+/* Get size, ignoring use bits */
+#define chunksize(p) ((p)->size & ~(SIZE_BITS))
+
+
+/* Ptr to next physical malloc_chunk. */
+#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->size & ~PREV_INUSE) ))
+
+/* Ptr to previous physical malloc_chunk */
+#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_size) ))
+
+/* Treat space at ptr + offset as a chunk */
+#define chunk_at_offset(p, s) ((mchunkptr)(((char*)(p)) + (s)))
+
+/* extract p's inuse bit */
+#define inuse(p)\
+((((mchunkptr)(((char*)(p))+((p)->size & ~PREV_INUSE)))->size) & PREV_INUSE)
+
+/* set/clear chunk as being inuse without otherwise disturbing */
+#define set_inuse(p)\
+((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size |= PREV_INUSE
+
+#define clear_inuse(p)\
+((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size &= ~(PREV_INUSE)
+
+
+/* check/set/clear inuse bits in known places */
+#define inuse_bit_at_offset(p, s)\
+ (((mchunkptr)(((char*)(p)) + (s)))->size & PREV_INUSE)
+
+#define set_inuse_bit_at_offset(p, s)\
+ (((mchunkptr)(((char*)(p)) + (s)))->size |= PREV_INUSE)
+
+#define clear_inuse_bit_at_offset(p, s)\
+ (((mchunkptr)(((char*)(p)) + (s)))->size &= ~(PREV_INUSE))
+
+
+/* Set size at head, without disturbing its use bit */
+#define set_head_size(p, s) ((p)->size = (((p)->size & PREV_INUSE) | (s)))
+
+/* Set size/use field */
+#define set_head(p, s) ((p)->size = (s))
+
+/* Set size at footer (only when chunk is not in use) */
+#define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_size = (s))
+
+
+/*
+ -------------------- Internal data structures --------------------
+
+ All internal state is held in an instance of malloc_state defined
+ below. There are no other static variables, except in two optional
+ cases:
+ * If USE_MALLOC_LOCK is defined, the mALLOC_MUTEx declared above.
+ * If HAVE_MMAP is true, but mmap doesn't support
+ MAP_ANONYMOUS, a dummy file descriptor for mmap.
+
+ Beware of lots of tricks that minimize the total bookkeeping space
+ requirements. The result is a little over 1K bytes (for 4byte
+ pointers and size_t.)
+*/
+
+/*
+ Bins
+
+ An array of bin headers for free chunks. Each bin is doubly
+ linked. The bins are approximately proportionally (log) spaced.
+ There are a lot of these bins (128). This may look excessive, but
+ works very well in practice. Most bins hold sizes that are
+ unusual as malloc request sizes, but are more usual for fragments
+ and consolidated sets of chunks, which is what these bins hold, so
+ they can be found quickly. All procedures maintain the invariant
+ that no consolidated chunk physically borders another one, so each
+ chunk in a list is known to be preceeded and followed by either
+ inuse chunks or the ends of memory.
+
+ Chunks in bins are kept in size order, with ties going to the
+ approximately least recently used chunk. Ordering isn't needed
+ for the small bins, which all contain the same-sized chunks, but
+ facilitates best-fit allocation for larger chunks. These lists
+ are just sequential. Keeping them in order almost never requires
+ enough traversal to warrant using fancier ordered data
+ structures.
+
+ Chunks of the same size are linked with the most
+ recently freed at the front, and allocations are taken from the
+ back. This results in LRU (FIFO) allocation order, which tends
+ to give each chunk an equal opportunity to be consolidated with
+ adjacent freed chunks, resulting in larger free chunks and less
+ fragmentation.
+
+ To simplify use in double-linked lists, each bin header acts
+ as a malloc_chunk. This avoids special-casing for headers.
+ But to conserve space and improve locality, we allocate
+ only the fd/bk pointers of bins, and then use repositioning tricks
+ to treat these as the fields of a malloc_chunk*.
+*/
+
+typedef struct malloc_chunk* mbinptr;
+
+/* addressing -- note that bin_at(0) does not exist */
+#define bin_at(m, i) ((mbinptr)((char*)&((m)->bins[(i)<<1]) - (SIZE_SZ<<1)))
+
+/* analog of ++bin */
+#define next_bin(b) ((mbinptr)((char*)(b) + (sizeof(mchunkptr)<<1)))
+
+/* Reminders about list directionality within bins */
+#define first(b) ((b)->fd)
+#define last(b) ((b)->bk)
+
+/* Take a chunk off a bin list */
+#define unlink(P, BK, FD) { \
+ FD = P->fd; \
+ BK = P->bk; \
+ FD->bk = BK; \
+ BK->fd = FD; \
+}
+
+/*
+ Indexing
+
+ Bins for sizes < 512 bytes contain chunks of all the same size, spaced
+ 8 bytes apart. Larger bins are approximately logarithmically spaced:
+
+ 64 bins of size 8
+ 32 bins of size 64
+ 16 bins of size 512
+ 8 bins of size 4096
+ 4 bins of size 32768
+ 2 bins of size 262144
+ 1 bin of size what's left
+
+ There is actually a little bit of slop in the numbers in bin_index
+ for the sake of speed. This makes no difference elsewhere.
+
+ The bins top out around 1MB because we expect to service large
+ requests via mmap.
+*/
+
+#define NBINS 128
+#define NSMALLBINS 64
+#define SMALLBIN_WIDTH 8
+#define MIN_LARGE_SIZE 512
+
+#define in_smallbin_range(sz) \
+ ((unsigned long)(sz) < (unsigned long)MIN_LARGE_SIZE)
+
+#define smallbin_index(sz) (((unsigned)(sz)) >> 3)
+
+#define largebin_index(sz) \
+(((((unsigned long)(sz)) >> 6) <= 32)? 56 + (((unsigned long)(sz)) >> 6): \
+ ((((unsigned long)(sz)) >> 9) <= 20)? 91 + (((unsigned long)(sz)) >> 9): \
+ ((((unsigned long)(sz)) >> 12) <= 10)? 110 + (((unsigned long)(sz)) >> 12): \
+ ((((unsigned long)(sz)) >> 15) <= 4)? 119 + (((unsigned long)(sz)) >> 15): \
+ ((((unsigned long)(sz)) >> 18) <= 2)? 124 + (((unsigned long)(sz)) >> 18): \
+ 126)
+
+#define bin_index(sz) \
+ ((in_smallbin_range(sz)) ? smallbin_index(sz) : largebin_index(sz))
+
+
+/*
+ Unsorted chunks
+
+ All remainders from chunk splits, as well as all returned chunks,
+ are first placed in the "unsorted" bin. They are then placed
+ in regular bins after malloc gives them ONE chance to be used before
+ binning. So, basically, the unsorted_chunks list acts as a queue,
+ with chunks being placed on it in free (and malloc_consolidate),
+ and taken off (to be either used or placed in bins) in malloc.
+*/
+
+/* The otherwise unindexable 1-bin is used to hold unsorted chunks. */
+#define unsorted_chunks(M) (bin_at(M, 1))
+
+/*
+ Top
+
+ The top-most available chunk (i.e., the one bordering the end of
+ available memory) is treated specially. It is never included in
+ any bin, is used only if no other chunk is available, and is
+ released back to the system if it is very large (see
+ M_TRIM_THRESHOLD). Because top initially
+ points to its own bin with initial zero size, thus forcing
+ extension on the first malloc request, we avoid having any special
+ code in malloc to check whether it even exists yet. But we still
+ need to do so when getting memory from system, so we make
+ initial_top treat the bin as a legal but unusable chunk during the
+ interval between initialization and the first call to
+ sYSMALLOc. (This is somewhat delicate, since it relies on
+ the 2 preceding words to be zero during this interval as well.)
+*/
+
+/* Conveniently, the unsorted bin can be used as dummy top on first call */
+#define initial_top(M) (unsorted_chunks(M))
+
+/*
+ Binmap
+
+ To help compensate for the large number of bins, a one-level index
+ structure is used for bin-by-bin searching. `binmap' is a
+ bitvector recording whether bins are definitely empty so they can
+ be skipped over during during traversals. The bits are NOT always
+ cleared as soon as bins are empty, but instead only
+ when they are noticed to be empty during traversal in malloc.
+*/
+
+/* Conservatively use 32 bits per map word, even if on 64bit system */
+#define BINMAPSHIFT 5
+#define BITSPERMAP (1U << BINMAPSHIFT)
+#define BINMAPSIZE (NBINS / BITSPERMAP)
+
+#define idx2block(i) ((i) >> BINMAPSHIFT)
+#define idx2bit(i) ((1U << ((i) & ((1U << BINMAPSHIFT)-1))))
+
+#define mark_bin(m,i) ((m)->binmap[idx2block(i)] |= idx2bit(i))
+#define unmark_bin(m,i) ((m)->binmap[idx2block(i)] &= ~(idx2bit(i)))
+#define get_binmap(m,i) ((m)->binmap[idx2block(i)] & idx2bit(i))
+
+/*
+ Fastbins
+
+ An array of lists holding recently freed small chunks. Fastbins
+ are not doubly linked. It is faster to single-link them, and
+ since chunks are never removed from the middles of these lists,
+ double linking is not necessary. Also, unlike regular bins, they
+ are not even processed in FIFO order (they use faster LIFO) since
+ ordering doesn't much matter in the transient contexts in which
+ fastbins are normally used.
+
+ Chunks in fastbins keep their inuse bit set, so they cannot
+ be consolidated with other free chunks. malloc_consolidate
+ releases all chunks in fastbins and consolidates them with
+ other free chunks.
+*/
+
+typedef struct malloc_chunk* mfastbinptr;
+
+/* offset 2 to use otherwise unindexable first 2 bins */
+#define fastbin_index(sz) ((((unsigned int)(sz)) >> 3) - 2)
+
+/* The maximum fastbin request size we support */
+#define MAX_FAST_SIZE 80
+
+#define NFASTBINS (fastbin_index(request2size(MAX_FAST_SIZE))+1)
+
+/*
+ FASTBIN_CONSOLIDATION_THRESHOLD is the size of a chunk in free()
+ that triggers automatic consolidation of possibly-surrounding
+ fastbin chunks. This is a heuristic, so the exact value should not
+ matter too much. It is defined at half the default trim threshold as a
+ compromise heuristic to only attempt consolidation if it is likely
+ to lead to trimming. However, it is not dynamically tunable, since
+ consolidation reduces fragmentation surrounding loarge chunks even
+ if trimming is not used.
+*/
+
+#define FASTBIN_CONSOLIDATION_THRESHOLD (65536UL)
+
+/*
+ Since the lowest 2 bits in max_fast don't matter in size comparisons,
+ they are used as flags.
+*/
+
+/*
+ FASTCHUNKS_BIT held in max_fast indicates that there are probably
+ some fastbin chunks. It is set true on entering a chunk into any
+ fastbin, and cleared only in malloc_consolidate.
+
+ The truth value is inverted so that have_fastchunks will be true
+ upon startup (since statics are zero-filled), simplifying
+ initialization checks.
+*/
+
+#define FASTCHUNKS_BIT (1U)
+
+#define have_fastchunks(M) (((M)->max_fast & FASTCHUNKS_BIT) == 0)
+#define clear_fastchunks(M) ((M)->max_fast |= FASTCHUNKS_BIT)
+#define set_fastchunks(M) ((M)->max_fast &= ~FASTCHUNKS_BIT)
+
+/*
+ NONCONTIGUOUS_BIT indicates that MORECORE does not return contiguous
+ regions. Otherwise, contiguity is exploited in merging together,
+ when possible, results from consecutive MORECORE calls.
+
+ The initial value comes from MORECORE_CONTIGUOUS, but is
+ changed dynamically if mmap is ever used as an sbrk substitute.
+*/
+
+#define NONCONTIGUOUS_BIT (2U)
+
+#define contiguous(M) (((M)->max_fast & NONCONTIGUOUS_BIT) == 0)
+#define noncontiguous(M) (((M)->max_fast & NONCONTIGUOUS_BIT) != 0)
+#define set_noncontiguous(M) ((M)->max_fast |= NONCONTIGUOUS_BIT)
+#define set_contiguous(M) ((M)->max_fast &= ~NONCONTIGUOUS_BIT)
+
+/*
+ Set value of max_fast.
+ Use impossibly small value if 0.
+ Precondition: there are no existing fastbin chunks.
+ Setting the value clears fastchunk bit but preserves noncontiguous bit.
+*/
+
+#define set_max_fast(M, s) \
+ (M)->max_fast = (((s) == 0)? SMALLBIN_WIDTH: request2size(s)) | \
+ FASTCHUNKS_BIT | \
+ ((M)->max_fast & NONCONTIGUOUS_BIT)
+
+
+/*
+ ----------- Internal state representation and initialization -----------
+*/
+
+struct malloc_state {
+
+ /* The maximum chunk size to be eligible for fastbin */
+ INTERNAL_SIZE_T max_fast; /* low 2 bits used as flags */
+
+ /* Fastbins */
+ mfastbinptr fastbins[NFASTBINS];
+
+ /* Base of the topmost chunk -- not otherwise kept in a bin */
+ mchunkptr top;
+
+ /* The remainder from the most recent split of a small request */
+ mchunkptr last_remainder;
+
+ /* Normal bins packed as described above */
+ mchunkptr bins[NBINS * 2];
+
+ /* Bitmap of bins */
+ unsigned int binmap[BINMAPSIZE];
+
+ /* Tunable parameters */
+ unsigned long trim_threshold;
+ INTERNAL_SIZE_T top_pad;
+ INTERNAL_SIZE_T mmap_threshold;
+
+ /* Memory map support */
+ int n_mmaps;
+ int n_mmaps_max;
+ int max_n_mmaps;
+
+ /* Cache malloc_getpagesize */
+ unsigned int pagesize;
+
+ /* Statistics */
+ INTERNAL_SIZE_T mmapped_mem;
+ INTERNAL_SIZE_T sbrked_mem;
+ INTERNAL_SIZE_T max_sbrked_mem;
+ INTERNAL_SIZE_T max_mmapped_mem;
+ INTERNAL_SIZE_T max_total_mem;
+};
+
+typedef struct malloc_state *mstate;
+
+/*
+ There is exactly one instance of this struct in this malloc.
+ If you are adapting this malloc in a way that does NOT use a static
+ malloc_state, you MUST explicitly zero-fill it before using. This
+ malloc relies on the property that malloc_state is initialized to
+ all zeroes (as is true of C statics).
+*/
+
+static struct malloc_state av_; /* never directly referenced */
+
+/*
+ All uses of av_ are via get_malloc_state().
+ At most one "call" to get_malloc_state is made per invocation of
+ the public versions of malloc and free, but other routines
+ that in turn invoke malloc and/or free may call more then once.
+ Also, it is called in check* routines if DEBUG is set.
+*/
+
+#define get_malloc_state() (&(av_))
+
+/*
+ Initialize a malloc_state struct.
+
+ This is called only from within malloc_consolidate, which needs
+ be called in the same contexts anyway. It is never called directly
+ outside of malloc_consolidate because some optimizing compilers try
+ to inline it at all call points, which turns out not to be an
+ optimization at all. (Inlining it in malloc_consolidate is fine though.)
+*/
+
+#if __STD_C
+static void malloc_init_state(mstate av)
+#else
+static void malloc_init_state(av) mstate av;
+#endif
+{
+ int i;
+ mbinptr bin;
+
+ /* Establish circular links for normal bins */
+ for (i = 1; i < NBINS; ++i) {
+ bin = bin_at(av,i);
+ bin->fd = bin->bk = bin;
+ }
+
+ av->top_pad = DEFAULT_TOP_PAD;
+ av->n_mmaps_max = DEFAULT_MMAP_MAX;
+ av->mmap_threshold = DEFAULT_MMAP_THRESHOLD;
+ av->trim_threshold = DEFAULT_TRIM_THRESHOLD;
+
+#if !MORECORE_CONTIGUOUS
+ set_noncontiguous(av);
+#endif
+
+ set_max_fast(av, DEFAULT_MXFAST);
+
+ av->top = initial_top(av);
+ av->pagesize = malloc_getpagesize;
+}
+
+/*
+ Other internal utilities operating on mstates
+*/
+
+#if __STD_C
+static Void_t* sYSMALLOc(INTERNAL_SIZE_T, mstate);
+static int sYSTRIm(size_t, mstate);
+static void malloc_consolidate(mstate);
+static Void_t** iALLOc(size_t, size_t*, int, Void_t**);
+#else
+static Void_t* sYSMALLOc();
+static int sYSTRIm();
+static void malloc_consolidate();
+static Void_t** iALLOc();
+#endif
+
+/*
+ Debugging support
+
+ These routines make a number of assertions about the states
+ of data structures that should be true at all times. If any
+ are not true, it's very likely that a user program has somehow
+ trashed memory. (It's also possible that there is a coding error
+ in malloc. In which case, please report it!)
+*/
+
+#if ! DEBUG
+
+#define check_chunk(P)
+#define check_free_chunk(P)
+#define check_inuse_chunk(P)
+#define check_remalloced_chunk(P,N)
+#define check_malloced_chunk(P,N)
+#define check_malloc_state()
+
+#else
+#define check_chunk(P) do_check_chunk(P)
+#define check_free_chunk(P) do_check_free_chunk(P)
+#define check_inuse_chunk(P) do_check_inuse_chunk(P)
+#define check_remalloced_chunk(P,N) do_check_remalloced_chunk(P,N)
+#define check_malloced_chunk(P,N) do_check_malloced_chunk(P,N)
+#define check_malloc_state() do_check_malloc_state()
+
+/*
+ Properties of all chunks
+*/
+
+#if __STD_C
+static void do_check_chunk(mchunkptr p)
+#else
+static void do_check_chunk(p) mchunkptr p;
+#endif
+{
+ mstate av = get_malloc_state();
+ unsigned long sz = chunksize(p);
+ /* min and max possible addresses assuming contiguous allocation */
+ char* max_address = (char*)(av->top) + chunksize(av->top);
+ char* min_address = max_address - av->sbrked_mem;
+
+ if (!chunk_is_mmapped(p)) {
+
+ /* Has legal address ... */
+ if (p != av->top) {
+ if (contiguous(av)) {
+ assert(((char*)p) >= min_address);
+ assert(((char*)p + sz) <= ((char*)(av->top)));
+ }
+ }
+ else {
+ /* top size is always at least MINSIZE */
+ assert((unsigned long)(sz) >= MINSIZE);
+ /* top predecessor always marked inuse */
+ assert(prev_inuse(p));
+ }
+
+ }
+ else {
+#if HAVE_MMAP
+ /* address is outside main heap */
+ if (contiguous(av) && av->top != initial_top(av)) {
+ assert(((char*)p) < min_address || ((char*)p) > max_address);
+ }
+ /* chunk is page-aligned */
+ assert(((p->prev_size + sz) & (av->pagesize-1)) == 0);
+ /* mem is aligned */
+ assert(aligned_OK(chunk2mem(p)));
+#else
+ /* force an appropriate assert violation if debug set */
+ assert(!chunk_is_mmapped(p));
+#endif
+ }
+}
+
+/*
+ Properties of free chunks
+*/
+
+#if __STD_C
+static void do_check_free_chunk(mchunkptr p)
+#else
+static void do_check_free_chunk(p) mchunkptr p;
+#endif
+{
+ mstate av = get_malloc_state();
+
+ INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE;
+ mchunkptr next = chunk_at_offset(p, sz);
+
+ do_check_chunk(p);
+
+ /* Chunk must claim to be free ... */
+ assert(!inuse(p));
+ assert (!chunk_is_mmapped(p));
+
+ /* Unless a special marker, must have OK fields */
+ if ((unsigned long)(sz) >= MINSIZE)
+ {
+ assert((sz & MALLOC_ALIGN_MASK) == 0);
+ assert(aligned_OK(chunk2mem(p)));
+ /* ... matching footer field */
+ assert(next->prev_size == sz);
+ /* ... and is fully consolidated */
+ assert(prev_inuse(p));
+ assert (next == av->top || inuse(next));
+
+ /* ... and has minimally sane links */
+ assert(p->fd->bk == p);
+ assert(p->bk->fd == p);
+ }
+ else /* markers are always of size SIZE_SZ */
+ assert(sz == SIZE_SZ);
+}
+
+/*
+ Properties of inuse chunks
+*/
+
+#if __STD_C
+static void do_check_inuse_chunk(mchunkptr p)
+#else
+static void do_check_inuse_chunk(p) mchunkptr p;
+#endif
+{
+ mstate av = get_malloc_state();
+ mchunkptr next;
+ do_check_chunk(p);
+
+ if (chunk_is_mmapped(p))
+ return; /* mmapped chunks have no next/prev */
+
+ /* Check whether it claims to be in use ... */
+ assert(inuse(p));
+
+ next = next_chunk(p);
+
+ /* ... and is surrounded by OK chunks.
+ Since more things can be checked with free chunks than inuse ones,
+ if an inuse chunk borders them and debug is on, it's worth doing them.
+ */
+ if (!prev_inuse(p)) {
+ /* Note that we cannot even look at prev unless it is not inuse */
+ mchunkptr prv = prev_chunk(p);
+ assert(next_chunk(prv) == p);
+ do_check_free_chunk(prv);
+ }
+
+ if (next == av->top) {
+ assert(prev_inuse(next));
+ assert(chunksize(next) >= MINSIZE);
+ }
+ else if (!inuse(next))
+ do_check_free_chunk(next);
+}
+
+/*
+ Properties of chunks recycled from fastbins
+*/
+
+#if __STD_C
+static void do_check_remalloced_chunk(mchunkptr p, INTERNAL_SIZE_T s)
+#else
+static void do_check_remalloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s;
+#endif
+{
+ INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE;
+
+ do_check_inuse_chunk(p);
+
+ /* Legal size ... */
+ assert((sz & MALLOC_ALIGN_MASK) == 0);
+ assert((unsigned long)(sz) >= MINSIZE);
+ /* ... and alignment */
+ assert(aligned_OK(chunk2mem(p)));
+ /* chunk is less than MINSIZE more than request */
+ assert((long)(sz) - (long)(s) >= 0);
+ assert((long)(sz) - (long)(s + MINSIZE) < 0);
+}
+
+/*
+ Properties of nonrecycled chunks at the point they are malloced
+*/
+
+#if __STD_C
+static void do_check_malloced_chunk(mchunkptr p, INTERNAL_SIZE_T s)
+#else
+static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s;
+#endif
+{
+ /* same as recycled case ... */
+ do_check_remalloced_chunk(p, s);
+
+ /*
+ ... plus, must obey implementation invariant that prev_inuse is
+ always true of any allocated chunk; i.e., that each allocated
+ chunk borders either a previously allocated and still in-use
+ chunk, or the base of its memory arena. This is ensured
+ by making all allocations from the the `lowest' part of any found
+ chunk. This does not necessarily hold however for chunks
+ recycled via fastbins.
+ */
+
+ assert(prev_inuse(p));
+}
+
+
+/*
+ Properties of malloc_state.
+
+ This may be useful for debugging malloc, as well as detecting user
+ programmer errors that somehow write into malloc_state.
+
+ If you are extending or experimenting with this malloc, you can
+ probably figure out how to hack this routine to print out or
+ display chunk addresses, sizes, bins, and other instrumentation.
+*/
+
+static void do_check_malloc_state()
+{
+ mstate av = get_malloc_state();
+ int i;
+ mchunkptr p;
+ mchunkptr q;
+ mbinptr b;
+ unsigned int binbit;
+ int empty;
+ unsigned int idx;
+ INTERNAL_SIZE_T size;
+ unsigned long total = 0;
+ int max_fast_bin;
+
+ /* internal size_t must be no wider than pointer type */
+ assert(sizeof(INTERNAL_SIZE_T) <= sizeof(char*));
+
+ /* alignment is a power of 2 */
+ assert((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-1)) == 0);
+
+ /* cannot run remaining checks until fully initialized */
+ if (av->top == 0 || av->top == initial_top(av))
+ return;
+
+ /* pagesize is a power of 2 */
+ assert((av->pagesize & (av->pagesize-1)) == 0);
+
+ /* properties of fastbins */
+
+ /* max_fast is in allowed range */
+ assert((av->max_fast & ~1) <= request2size(MAX_FAST_SIZE));
+
+ max_fast_bin = fastbin_index(av->max_fast);
+
+ for (i = 0; i < NFASTBINS; ++i) {
+ p = av->fastbins[i];
+
+ /* all bins past max_fast are empty */
+ if (i > max_fast_bin)
+ assert(p == 0);
+
+ while (p != 0) {
+ /* each chunk claims to be inuse */
+ do_check_inuse_chunk(p);
+ total += chunksize(p);
+ /* chunk belongs in this bin */
+ assert(fastbin_index(chunksize(p)) == i);
+ p = p->fd;
+ }
+ }
+
+ if (total != 0)
+ assert(have_fastchunks(av));
+ else if (!have_fastchunks(av))
+ assert(total == 0);
+
+ /* check normal bins */
+ for (i = 1; i < NBINS; ++i) {
+ b = bin_at(av,i);
+
+ /* binmap is accurate (except for bin 1 == unsorted_chunks) */
+ if (i >= 2) {
+ binbit = get_binmap(av,i);
+ empty = last(b) == b;
+ if (!binbit)
+ assert(empty);
+ else if (!empty)
+ assert(binbit);
+ }
+
+ for (p = last(b); p != b; p = p->bk) {
+ /* each chunk claims to be free */
+ do_check_free_chunk(p);
+ size = chunksize(p);
+ total += size;
+ if (i >= 2) {
+ /* chunk belongs in bin */
+ idx = bin_index(size);
+ assert(idx == i);
+ /* lists are sorted */
+ assert(p->bk == b ||
+ (unsigned long)chunksize(p->bk) >= (unsigned long)chunksize(p));
+ }
+ /* chunk is followed by a legal chain of inuse chunks */
+ for (q = next_chunk(p);
+ (q != av->top && inuse(q) &&
+ (unsigned long)(chunksize(q)) >= MINSIZE);
+ q = next_chunk(q))
+ do_check_inuse_chunk(q);
+ }
+ }
+
+ /* top chunk is OK */
+ check_chunk(av->top);
+
+ /* sanity checks for statistics */
+
+ assert(total <= (unsigned long)(av->max_total_mem));
+ assert(av->n_mmaps >= 0);
+ assert(av->n_mmaps <= av->n_mmaps_max);
+ assert(av->n_mmaps <= av->max_n_mmaps);
+
+ assert((unsigned long)(av->sbrked_mem) <=
+ (unsigned long)(av->max_sbrked_mem));
+
+ assert((unsigned long)(av->mmapped_mem) <=
+ (unsigned long)(av->max_mmapped_mem));
+
+ assert((unsigned long)(av->max_total_mem) >=
+ (unsigned long)(av->mmapped_mem) + (unsigned long)(av->sbrked_mem));
+}
+#endif
+
+
+/* ----------- Routines dealing with system allocation -------------- */
+
+/*
+ sysmalloc handles malloc cases requiring more memory from the system.
+ On entry, it is assumed that av->top does not have enough
+ space to service request for nb bytes, thus requiring that av->top
+ be extended or replaced.
+*/
+
+#if __STD_C
+static Void_t* sYSMALLOc(INTERNAL_SIZE_T nb, mstate av)
+#else
+static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av;
+#endif
+{
+ mchunkptr old_top; /* incoming value of av->top */
+ INTERNAL_SIZE_T old_size; /* its size */
+ char* old_end; /* its end address */
+
+ long size; /* arg to first MORECORE or mmap call */
+ char* brk; /* return value from MORECORE */
+
+ long correction; /* arg to 2nd MORECORE call */
+ char* snd_brk; /* 2nd return val */
+
+ INTERNAL_SIZE_T front_misalign; /* unusable bytes at front of new space */
+ INTERNAL_SIZE_T end_misalign; /* partial page left at end of new space */
+ char* aligned_brk; /* aligned offset into brk */
+
+ mchunkptr p; /* the allocated/returned chunk */
+ mchunkptr remainder; /* remainder from allocation */
+ unsigned long remainder_size; /* its size */
+
+ unsigned long sum; /* for updating stats */
+
+ size_t pagemask = av->pagesize - 1;
+
+
+#if HAVE_MMAP
+
+ /*
+ If have mmap, and the request size meets the mmap threshold, and
+ the system supports mmap, and there are few enough currently
+ allocated mmapped regions, try to directly map this request
+ rather than expanding top.
+ */
+
+ if ((unsigned long)(nb) >= (unsigned long)(av->mmap_threshold) &&
+ (av->n_mmaps < av->n_mmaps_max)) {
+
+ char* mm; /* return value from mmap call*/
+
+ /*
+ Round up size to nearest page. For mmapped chunks, the overhead
+ is one SIZE_SZ unit larger than for normal chunks, because there
+ is no following chunk whose prev_size field could be used.
+ */
+ size = (nb + SIZE_SZ + MALLOC_ALIGN_MASK + pagemask) & ~pagemask;
+
+ /* Don't try if size wraps around 0 */
+ if ((unsigned long)(size) > (unsigned long)(nb)) {
+
+ mm = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE));
+
+ if (mm != (char*)(MORECORE_FAILURE)) {
+
+ /*
+ The offset to the start of the mmapped region is stored
+ in the prev_size field of the chunk. This allows us to adjust
+ returned start address to meet alignment requirements here
+ and in memalign(), and still be able to compute proper
+ address argument for later munmap in free() and realloc().
+ */
+
+ front_misalign = (INTERNAL_SIZE_T)chunk2mem(mm) & MALLOC_ALIGN_MASK;
+ if (front_misalign > 0) {
+ correction = MALLOC_ALIGNMENT - front_misalign;
+ p = (mchunkptr)(mm + correction);
+ p->prev_size = correction;
+ set_head(p, (size - correction) |IS_MMAPPED);
+ }
+ else {
+ p = (mchunkptr)mm;
+ set_head(p, size|IS_MMAPPED);
+ }
+
+ /* update statistics */
+
+ if (++av->n_mmaps > av->max_n_mmaps)
+ av->max_n_mmaps = av->n_mmaps;
+
+ sum = av->mmapped_mem += size;
+ if (sum > (unsigned long)(av->max_mmapped_mem))
+ av->max_mmapped_mem = sum;
+ sum += av->sbrked_mem;
+ if (sum > (unsigned long)(av->max_total_mem))
+ av->max_total_mem = sum;
+
+ check_chunk(p);
+
+ return chunk2mem(p);
+ }
+ }
+ }
+#endif
+
+ /* Record incoming configuration of top */
+
+ old_top = av->top;
+ old_size = chunksize(old_top);
+ old_end = (char*)(chunk_at_offset(old_top, old_size));
+
+ brk = snd_brk = (char*)(MORECORE_FAILURE);
+
+ /*
+ If not the first time through, we require old_size to be
+ at least MINSIZE and to have prev_inuse set.
+ */
+
+ assert((old_top == initial_top(av) && old_size == 0) ||
+ ((unsigned long) (old_size) >= MINSIZE &&
+ prev_inuse(old_top)));
+
+ /* Precondition: not enough current space to satisfy nb request */
+ assert((unsigned long)(old_size) < (unsigned long)(nb + MINSIZE));
+
+ /* Precondition: all fastbins are consolidated */
+ assert(!have_fastchunks(av));
+
+
+ /* Request enough space for nb + pad + overhead */
+
+ size = nb + av->top_pad + MINSIZE;
+
+ /*
+ If contiguous, we can subtract out existing space that we hope to
+ combine with new space. We add it back later only if
+ we don't actually get contiguous space.
+ */
+
+ if (contiguous(av))
+ size -= old_size;
+
+ /*
+ Round to a multiple of page size.
+ If MORECORE is not contiguous, this ensures that we only call it
+ with whole-page arguments. And if MORECORE is contiguous and
+ this is not first time through, this preserves page-alignment of
+ previous calls. Otherwise, we correct to page-align below.
+ */
+
+ size = (size + pagemask) & ~pagemask;
+
+ /*
+ Don't try to call MORECORE if argument is so big as to appear
+ negative. Note that since mmap takes size_t arg, it may succeed
+ below even if we cannot call MORECORE.
+ */
+
+ if (size > 0)
+ brk = (char*)(MORECORE(size));
+
+ /*
+ If have mmap, try using it as a backup when MORECORE fails or
+ cannot be used. This is worth doing on systems that have "holes" in
+ address space, so sbrk cannot extend to give contiguous space, but
+ space is available elsewhere. Note that we ignore mmap max count
+ and threshold limits, since the space will not be used as a
+ segregated mmap region.
+ */
+
+#if HAVE_MMAP
+ if (brk == (char*)(MORECORE_FAILURE)) {
+
+ /* Cannot merge with old top, so add its size back in */
+ if (contiguous(av))
+ size = (size + old_size + pagemask) & ~pagemask;
+
+ /* If we are relying on mmap as backup, then use larger units */
+ if ((unsigned long)(size) < (unsigned long)(MMAP_AS_MORECORE_SIZE))
+ size = MMAP_AS_MORECORE_SIZE;
+
+ /* Don't try if size wraps around 0 */
+ if ((unsigned long)(size) > (unsigned long)(nb)) {
+
+ brk = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE));
+
+ if (brk != (char*)(MORECORE_FAILURE)) {
+
+ /* We do not need, and cannot use, another sbrk call to find end */
+ snd_brk = brk + size;
+
+ /*
+ Record that we no longer have a contiguous sbrk region.
+ After the first time mmap is used as backup, we do not
+ ever rely on contiguous space since this could incorrectly
+ bridge regions.
+ */
+ set_noncontiguous(av);
+ }
+ }
+ }
+#endif
+
+ if (brk != (char*)(MORECORE_FAILURE)) {
+ av->sbrked_mem += size;
+
+ /*
+ If MORECORE extends previous space, we can likewise extend top size.
+ */
+
+ if (brk == old_end && snd_brk == (char*)(MORECORE_FAILURE)) {
+ set_head(old_top, (size + old_size) | PREV_INUSE);
+ }
+
+ /*
+ Otherwise, make adjustments:
+
+ * If the first time through or noncontiguous, we need to call sbrk
+ just to find out where the end of memory lies.
+
+ * We need to ensure that all returned chunks from malloc will meet
+ MALLOC_ALIGNMENT
+
+ * If there was an intervening foreign sbrk, we need to adjust sbrk
+ request size to account for fact that we will not be able to
+ combine new space with existing space in old_top.
+
+ * Almost all systems internally allocate whole pages at a time, in
+ which case we might as well use the whole last page of request.
+ So we allocate enough more memory to hit a page boundary now,
+ which in turn causes future contiguous calls to page-align.
+ */
+
+ else {
+ front_misalign = 0;
+ end_misalign = 0;
+ correction = 0;
+ aligned_brk = brk;
+
+ /* handle contiguous cases */
+ if (contiguous(av)) {
+
+ /* Guarantee alignment of first new chunk made from this space */
+
+ front_misalign = (INTERNAL_SIZE_T)chunk2mem(brk) & MALLOC_ALIGN_MASK;
+ if (front_misalign > 0) {
+
+ /*
+ Skip over some bytes to arrive at an aligned position.
+ We don't need to specially mark these wasted front bytes.
+ They will never be accessed anyway because
+ prev_inuse of av->top (and any chunk created from its start)
+ is always true after initialization.
+ */
+
+ correction = MALLOC_ALIGNMENT - front_misalign;
+ aligned_brk += correction;
+ }
+
+ /*
+ If this isn't adjacent to existing space, then we will not
+ be able to merge with old_top space, so must add to 2nd request.
+ */
+
+ correction += old_size;
+
+ /* Extend the end address to hit a page boundary */
+ end_misalign = (INTERNAL_SIZE_T)(brk + size + correction);
+ correction += ((end_misalign + pagemask) & ~pagemask) - end_misalign;
+
+ assert(correction >= 0);
+ snd_brk = (char*)(MORECORE(correction));
+
+ /*
+ If can't allocate correction, try to at least find out current
+ brk. It might be enough to proceed without failing.
+
+ Note that if second sbrk did NOT fail, we assume that space
+ is contiguous with first sbrk. This is a safe assumption unless
+ program is multithreaded but doesn't use locks and a foreign sbrk
+ occurred between our first and second calls.
+ */
+
+ if (snd_brk == (char*)(MORECORE_FAILURE)) {
+ correction = 0;
+ snd_brk = (char*)(MORECORE(0));
+ }
+ }
+
+ /* handle non-contiguous cases */
+ else {
+ /* MORECORE/mmap must correctly align */
+ assert(((unsigned long)chunk2mem(brk) & MALLOC_ALIGN_MASK) == 0);
+
+ /* Find out current end of memory */
+ if (snd_brk == (char*)(MORECORE_FAILURE)) {
+ snd_brk = (char*)(MORECORE(0));
+ }
+ }
+
+ /* Adjust top based on results of second sbrk */
+ if (snd_brk != (char*)(MORECORE_FAILURE)) {
+ av->top = (mchunkptr)aligned_brk;
+ set_head(av->top, (snd_brk - aligned_brk + correction) | PREV_INUSE);
+ av->sbrked_mem += correction;
+
+ /*
+ If not the first time through, we either have a
+ gap due to foreign sbrk or a non-contiguous region. Insert a
+ double fencepost at old_top to prevent consolidation with space
+ we don't own. These fenceposts are artificial chunks that are
+ marked as inuse and are in any case too small to use. We need
+ two to make sizes and alignments work out.
+ */
+
+ if (old_size != 0) {
+ /*
+ Shrink old_top to insert fenceposts, keeping size a
+ multiple of MALLOC_ALIGNMENT. We know there is at least
+ enough space in old_top to do this.
+ */
+ old_size = (old_size - 3*SIZE_SZ) & ~MALLOC_ALIGN_MASK;
+ set_head(old_top, old_size | PREV_INUSE);
+
+ /*
+ Note that the following assignments completely overwrite
+ old_top when old_size was previously MINSIZE. This is
+ intentional. We need the fencepost, even if old_top otherwise gets
+ lost.
+ */
+ chunk_at_offset(old_top, old_size )->size =
+ SIZE_SZ|PREV_INUSE;
+
+ chunk_at_offset(old_top, old_size + SIZE_SZ)->size =
+ SIZE_SZ|PREV_INUSE;
+
+ /* If possible, release the rest. */
+ if (old_size >= MINSIZE) {
+ fREe(chunk2mem(old_top));
+ }
+
+ }
+ }
+ }
+
+ /* Update statistics */
+ sum = av->sbrked_mem;
+ if (sum > (unsigned long)(av->max_sbrked_mem))
+ av->max_sbrked_mem = sum;
+
+ sum += av->mmapped_mem;
+ if (sum > (unsigned long)(av->max_total_mem))
+ av->max_total_mem = sum;
+
+ check_malloc_state();
+
+ /* finally, do the allocation */
+ p = av->top;
+ size = chunksize(p);
+
+ /* check that one of the above allocation paths succeeded */
+ if ((unsigned long)(size) >= (unsigned long)(nb + MINSIZE)) {
+ remainder_size = size - nb;
+ remainder = chunk_at_offset(p, nb);
+ av->top = remainder;
+ set_head(p, nb | PREV_INUSE);
+ set_head(remainder, remainder_size | PREV_INUSE);
+ check_malloced_chunk(p, nb);
+ return chunk2mem(p);
+ }
+ }
+
+ /* catch all failure paths */
+ MALLOC_FAILURE_ACTION;
+ return 0;
+}
+
+
+/*
+ sYSTRIm is an inverse of sorts to sYSMALLOc. It gives memory back
+ to the system (via negative arguments to sbrk) if there is unused
+ memory at the `high' end of the malloc pool. It is called
+ automatically by free() when top space exceeds the trim
+ threshold. It is also called by the public malloc_trim routine. It
+ returns 1 if it actually released any memory, else 0.
+*/
+
+#if __STD_C
+static int sYSTRIm(size_t pad, mstate av)
+#else
+static int sYSTRIm(pad, av) size_t pad; mstate av;
+#endif
+{
+ long top_size; /* Amount of top-most memory */
+ long extra; /* Amount to release */
+ long released; /* Amount actually released */
+ char* current_brk; /* address returned by pre-check sbrk call */
+ char* new_brk; /* address returned by post-check sbrk call */
+ size_t pagesz;
+
+ pagesz = av->pagesize;
+ top_size = chunksize(av->top);
+
+ /* Release in pagesize units, keeping at least one page */
+ extra = ((top_size - pad - MINSIZE + (pagesz-1)) / pagesz - 1) * pagesz;
+
+ if (extra > 0) {
+
+ /*
+ Only proceed if end of memory is where we last set it.
+ This avoids problems if there were foreign sbrk calls.
+ */
+ current_brk = (char*)(MORECORE(0));
+ if (current_brk == (char*)(av->top) + top_size) {
+
+ /*
+ Attempt to release memory. We ignore MORECORE return value,
+ and instead call again to find out where new end of memory is.
+ This avoids problems if first call releases less than we asked,
+ of if failure somehow altered brk value. (We could still
+ encounter problems if it altered brk in some very bad way,
+ but the only thing we can do is adjust anyway, which will cause
+ some downstream failure.)
+ */
+
+ MORECORE(-extra);
+ new_brk = (char*)(MORECORE(0));
+
+ if (new_brk != (char*)MORECORE_FAILURE) {
+ released = (long)(current_brk - new_brk);
+
+ if (released != 0) {
+ /* Success. Adjust top. */
+ av->sbrked_mem -= released;
+ set_head(av->top, (top_size - released) | PREV_INUSE);
+ check_malloc_state();
+ return 1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+ ------------------------------ malloc ------------------------------
+*/
+
+#if __STD_C
+Void_t* mALLOc(size_t bytes)
+#else
+ Void_t* mALLOc(bytes) size_t bytes;
+#endif
+{
+ mstate av = get_malloc_state();
+
+ INTERNAL_SIZE_T nb; /* normalized request size */
+ unsigned int idx; /* associated bin index */
+ mbinptr bin; /* associated bin */
+ mfastbinptr* fb; /* associated fastbin */
+
+ mchunkptr victim; /* inspected/selected chunk */
+ INTERNAL_SIZE_T size; /* its size */
+ int victim_index; /* its bin index */
+
+ mchunkptr remainder; /* remainder from a split */
+ unsigned long remainder_size; /* its size */
+
+ unsigned int block; /* bit map traverser */
+ unsigned int bit; /* bit map traverser */
+ unsigned int map; /* current word of binmap */
+
+ mchunkptr fwd; /* misc temp for linking */
+ mchunkptr bck; /* misc temp for linking */
+
+ /*
+ Convert request size to internal form by adding SIZE_SZ bytes
+ overhead plus possibly more to obtain necessary alignment and/or
+ to obtain a size of at least MINSIZE, the smallest allocatable
+ size. Also, checked_request2size traps (returning 0) request sizes
+ that are so large that they wrap around zero when padded and
+ aligned.
+ */
+
+ checked_request2size(bytes, nb);
+
+ /*
+ If the size qualifies as a fastbin, first check corresponding bin.
+ This code is safe to execute even if av is not yet initialized, so we
+ can try it without checking, which saves some time on this fast path.
+ */
+
+ if ((unsigned long)(nb) <= (unsigned long)(av->max_fast)) {
+ fb = &(av->fastbins[(fastbin_index(nb))]);
+ if ( (victim = *fb) != 0) {
+ *fb = victim->fd;
+ check_remalloced_chunk(victim, nb);
+ return chunk2mem(victim);
+ }
+ }
+
+ /*
+ If a small request, check regular bin. Since these "smallbins"
+ hold one size each, no searching within bins is necessary.
+ (For a large request, we need to wait until unsorted chunks are
+ processed to find best fit. But for small ones, fits are exact
+ anyway, so we can check now, which is faster.)
+ */
+
+ if (in_smallbin_range(nb)) {
+ idx = smallbin_index(nb);
+ bin = bin_at(av,idx);
+
+ if ( (victim = last(bin)) != bin) {
+ if (victim == 0) /* initialization check */
+ malloc_consolidate(av);
+ else {
+ bck = victim->bk;
+ set_inuse_bit_at_offset(victim, nb);
+ bin->bk = bck;
+ bck->fd = bin;
+
+ check_malloced_chunk(victim, nb);
+ return chunk2mem(victim);
+ }
+ }
+ }
+
+ /*
+ If this is a large request, consolidate fastbins before continuing.
+ While it might look excessive to kill all fastbins before
+ even seeing if there is space available, this avoids
+ fragmentation problems normally associated with fastbins.
+ Also, in practice, programs tend to have runs of either small or
+ large requests, but less often mixtures, so consolidation is not
+ invoked all that often in most programs. And the programs that
+ it is called frequently in otherwise tend to fragment.
+ */
+
+ else {
+ idx = largebin_index(nb);
+ if (have_fastchunks(av))
+ malloc_consolidate(av);
+ }
+
+ /*
+ Process recently freed or remaindered chunks, taking one only if
+ it is exact fit, or, if this a small request, the chunk is remainder from
+ the most recent non-exact fit. Place other traversed chunks in
+ bins. Note that this step is the only place in any routine where
+ chunks are placed in bins.
+
+ The outer loop here is needed because we might not realize until
+ near the end of malloc that we should have consolidated, so must
+ do so and retry. This happens at most once, and only when we would
+ otherwise need to expand memory to service a "small" request.
+ */
+
+ for(;;) {
+
+ while ( (victim = unsorted_chunks(av)->bk) != unsorted_chunks(av)) {
+ bck = victim->bk;
+ size = chunksize(victim);
+
+ /*
+ If a small request, try to use last remainder if it is the
+ only chunk in unsorted bin. This helps promote locality for
+ runs of consecutive small requests. This is the only
+ exception to best-fit, and applies only when there is
+ no exact fit for a small chunk.
+ */
+
+ if (in_smallbin_range(nb) &&
+ bck == unsorted_chunks(av) &&
+ victim == av->last_remainder &&
+ (unsigned long)(size) > (unsigned long)(nb + MINSIZE)) {
+
+ /* split and reattach remainder */
+ remainder_size = size - nb;
+ remainder = chunk_at_offset(victim, nb);
+ unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder;
+ av->last_remainder = remainder;
+ remainder->bk = remainder->fd = unsorted_chunks(av);
+
+ set_head(victim, nb | PREV_INUSE);
+ set_head(remainder, remainder_size | PREV_INUSE);
+ set_foot(remainder, remainder_size);
+
+ check_malloced_chunk(victim, nb);
+ return chunk2mem(victim);
+ }
+
+ /* remove from unsorted list */
+ unsorted_chunks(av)->bk = bck;
+ bck->fd = unsorted_chunks(av);
+
+ /* Take now instead of binning if exact fit */
+
+ if (size == nb) {
+ set_inuse_bit_at_offset(victim, size);
+ check_malloced_chunk(victim, nb);
+ return chunk2mem(victim);
+ }
+
+ /* place chunk in bin */
+
+ if (in_smallbin_range(size)) {
+ victim_index = smallbin_index(size);
+ bck = bin_at(av, victim_index);
+ fwd = bck->fd;
+ }
+ else {
+ victim_index = largebin_index(size);
+ bck = bin_at(av, victim_index);
+ fwd = bck->fd;
+
+ /* maintain large bins in sorted order */
+ if (fwd != bck) {
+ size |= PREV_INUSE; /* Or with inuse bit to speed comparisons */
+ /* if smaller than smallest, bypass loop below */
+ if ((unsigned long)(size) <= (unsigned long)(bck->bk->size)) {
+ fwd = bck;
+ bck = bck->bk;
+ }
+ else {
+ while ((unsigned long)(size) < (unsigned long)(fwd->size))
+ fwd = fwd->fd;
+ bck = fwd->bk;
+ }
+ }
+ }
+
+ mark_bin(av, victim_index);
+ victim->bk = bck;
+ victim->fd = fwd;
+ fwd->bk = victim;
+ bck->fd = victim;
+ }
+
+ /*
+ If a large request, scan through the chunks of current bin in
+ sorted order to find smallest that fits. This is the only step
+ where an unbounded number of chunks might be scanned without doing
+ anything useful with them. However the lists tend to be short.
+ */
+
+ if (!in_smallbin_range(nb)) {
+ bin = bin_at(av, idx);
+
+ /* skip scan if empty or largest chunk is too small */
+ if ((victim = last(bin)) != bin &&
+ (unsigned long)(first(bin)->size) >= (unsigned long)(nb)) {
+
+ while (((unsigned long)(size = chunksize(victim)) <
+ (unsigned long)(nb)))
+ victim = victim->bk;
+
+ remainder_size = size - nb;
+ unlink(victim, bck, fwd);
+
+ /* Exhaust */
+ if (remainder_size < MINSIZE) {
+ set_inuse_bit_at_offset(victim, size);
+ check_malloced_chunk(victim, nb);
+ return chunk2mem(victim);
+ }
+ /* Split */
+ else {
+ remainder = chunk_at_offset(victim, nb);
+ unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder;
+ remainder->bk = remainder->fd = unsorted_chunks(av);
+ set_head(victim, nb | PREV_INUSE);
+ set_head(remainder, remainder_size | PREV_INUSE);
+ set_foot(remainder, remainder_size);
+ check_malloced_chunk(victim, nb);
+ return chunk2mem(victim);
+ }
+ }
+ }
+
+ /*
+ Search for a chunk by scanning bins, starting with next largest
+ bin. This search is strictly by best-fit; i.e., the smallest
+ (with ties going to approximately the least recently used) chunk
+ that fits is selected.
+
+ The bitmap avoids needing to check that most blocks are nonempty.
+ The particular case of skipping all bins during warm-up phases
+ when no chunks have been returned yet is faster than it might look.
+ */
+
+ ++idx;
+ bin = bin_at(av,idx);
+ block = idx2block(idx);
+ map = av->binmap[block];
+ bit = idx2bit(idx);
+
+ for (;;) {
+
+ /* Skip rest of block if there are no more set bits in this block. */
+ if (bit > map || bit == 0) {
+ do {
+ if (++block >= BINMAPSIZE) /* out of bins */
+ goto use_top;
+ } while ( (map = av->binmap[block]) == 0);
+
+ bin = bin_at(av, (block << BINMAPSHIFT));
+ bit = 1;
+ }
+
+ /* Advance to bin with set bit. There must be one. */
+ while ((bit & map) == 0) {
+ bin = next_bin(bin);
+ bit <<= 1;
+ assert(bit != 0);
+ }
+
+ /* Inspect the bin. It is likely to be non-empty */
+ victim = last(bin);
+
+ /* If a false alarm (empty bin), clear the bit. */
+ if (victim == bin) {
+ av->binmap[block] = map &= ~bit; /* Write through */
+ bin = next_bin(bin);
+ bit <<= 1;
+ }
+
+ else {
+ size = chunksize(victim);
+
+ /* We know the first chunk in this bin is big enough to use. */
+ assert((unsigned long)(size) >= (unsigned long)(nb));
+
+ remainder_size = size - nb;
+
+ /* unlink */
+ bck = victim->bk;
+ bin->bk = bck;
+ bck->fd = bin;
+
+ /* Exhaust */
+ if (remainder_size < MINSIZE) {
+ set_inuse_bit_at_offset(victim, size);
+ check_malloced_chunk(victim, nb);
+ return chunk2mem(victim);
+ }
+
+ /* Split */
+ else {
+ remainder = chunk_at_offset(victim, nb);
+
+ unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder;
+ remainder->bk = remainder->fd = unsorted_chunks(av);
+ /* advertise as last remainder */
+ if (in_smallbin_range(nb))
+ av->last_remainder = remainder;
+
+ set_head(victim, nb | PREV_INUSE);
+ set_head(remainder, remainder_size | PREV_INUSE);
+ set_foot(remainder, remainder_size);
+ check_malloced_chunk(victim, nb);
+ return chunk2mem(victim);
+ }
+ }
+ }
+
+ use_top:
+ /*
+ If large enough, split off the chunk bordering the end of memory
+ (held in av->top). Note that this is in accord with the best-fit
+ search rule. In effect, av->top is treated as larger (and thus
+ less well fitting) than any other available chunk since it can
+ be extended to be as large as necessary (up to system
+ limitations).
+
+ We require that av->top always exists (i.e., has size >=
+ MINSIZE) after initialization, so if it would otherwise be
+ exhuasted by current request, it is replenished. (The main
+ reason for ensuring it exists is that we may need MINSIZE space
+ to put in fenceposts in sysmalloc.)
+ */
+
+ victim = av->top;
+ size = chunksize(victim);
+
+ if ((unsigned long)(size) >= (unsigned long)(nb + MINSIZE)) {
+ remainder_size = size - nb;
+ remainder = chunk_at_offset(victim, nb);
+ av->top = remainder;
+ set_head(victim, nb | PREV_INUSE);
+ set_head(remainder, remainder_size | PREV_INUSE);
+
+ check_malloced_chunk(victim, nb);
+ return chunk2mem(victim);
+ }
+
+ /*
+ If there is space available in fastbins, consolidate and retry,
+ to possibly avoid expanding memory. This can occur only if nb is
+ in smallbin range so we didn't consolidate upon entry.
+ */
+
+ else if (have_fastchunks(av)) {
+ assert(in_smallbin_range(nb));
+ malloc_consolidate(av);
+ idx = smallbin_index(nb); /* restore original bin index */
+ }
+
+ /*
+ Otherwise, relay to handle system-dependent cases
+ */
+ else
+ return sYSMALLOc(nb, av);
+ }
+}
+
+/*
+ ------------------------------ free ------------------------------
+*/
+
+#if __STD_C
+void fREe(Void_t* mem)
+#else
+void fREe(mem) Void_t* mem;
+#endif
+{
+ mstate av = get_malloc_state();
+
+ mchunkptr p; /* chunk corresponding to mem */
+ INTERNAL_SIZE_T size; /* its size */
+ mfastbinptr* fb; /* associated fastbin */
+ mchunkptr nextchunk; /* next contiguous chunk */
+ INTERNAL_SIZE_T nextsize; /* its size */
+ int nextinuse; /* true if nextchunk is used */
+ INTERNAL_SIZE_T prevsize; /* size of previous contiguous chunk */
+ mchunkptr bck; /* misc temp for linking */
+ mchunkptr fwd; /* misc temp for linking */
+
+
+ /* free(0) has no effect */
+ if (mem != 0) {
+ p = mem2chunk(mem);
+ size = chunksize(p);
+
+ check_inuse_chunk(p);
+
+ /*
+ If eligible, place chunk on a fastbin so it can be found
+ and used quickly in malloc.
+ */
+
+ if ((unsigned long)(size) <= (unsigned long)(av->max_fast)
+
+#if TRIM_FASTBINS
+ /*
+ If TRIM_FASTBINS set, don't place chunks
+ bordering top into fastbins
+ */
+ && (chunk_at_offset(p, size) != av->top)
+#endif
+ ) {
+
+ set_fastchunks(av);
+ fb = &(av->fastbins[fastbin_index(size)]);
+ p->fd = *fb;
+ *fb = p;
+ }
+
+ /*
+ Consolidate other non-mmapped chunks as they arrive.
+ */
+
+ else if (!chunk_is_mmapped(p)) {
+ nextchunk = chunk_at_offset(p, size);
+ nextsize = chunksize(nextchunk);
+
+ /* consolidate backward */
+ if (!prev_inuse(p)) {
+ prevsize = p->prev_size;
+ size += prevsize;
+ p = chunk_at_offset(p, -((long) prevsize));
+ unlink(p, bck, fwd);
+ }
+
+ if (nextchunk != av->top) {
+ /* get and clear inuse bit */
+ nextinuse = inuse_bit_at_offset(nextchunk, nextsize);
+ set_head(nextchunk, nextsize);
+
+ /* consolidate forward */
+ if (!nextinuse) {
+ unlink(nextchunk, bck, fwd);
+ size += nextsize;
+ }
+
+ /*
+ Place the chunk in unsorted chunk list. Chunks are
+ not placed into regular bins until after they have
+ been given one chance to be used in malloc.
+ */
+
+ bck = unsorted_chunks(av);
+ fwd = bck->fd;
+ p->bk = bck;
+ p->fd = fwd;
+ bck->fd = p;
+ fwd->bk = p;
+
+ set_head(p, size | PREV_INUSE);
+ set_foot(p, size);
+
+ check_free_chunk(p);
+ }
+
+ /*
+ If the chunk borders the current high end of memory,
+ consolidate into top
+ */
+
+ else {
+ size += nextsize;
+ set_head(p, size | PREV_INUSE);
+ av->top = p;
+ check_chunk(p);
+ }
+
+ /*
+ If freeing a large space, consolidate possibly-surrounding
+ chunks. Then, if the total unused topmost memory exceeds trim
+ threshold, ask malloc_trim to reduce top.
+
+ Unless max_fast is 0, we don't know if there are fastbins
+ bordering top, so we cannot tell for sure whether threshold
+ has been reached unless fastbins are consolidated. But we
+ don't want to consolidate on each free. As a compromise,
+ consolidation is performed if FASTBIN_CONSOLIDATION_THRESHOLD
+ is reached.
+ */
+
+ if ((unsigned long)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD) {
+ if (have_fastchunks(av))
+ malloc_consolidate(av);
+
+#ifndef MORECORE_CANNOT_TRIM
+ if ((unsigned long)(chunksize(av->top)) >=
+ (unsigned long)(av->trim_threshold))
+ sYSTRIm(av->top_pad, av);
+#endif
+ }
+
+ }
+ /*
+ If the chunk was allocated via mmap, release via munmap()
+ Note that if HAVE_MMAP is false but chunk_is_mmapped is
+ true, then user must have overwritten memory. There's nothing
+ we can do to catch this error unless DEBUG is set, in which case
+ check_inuse_chunk (above) will have triggered error.
+ */
+
+ else {
+#if HAVE_MMAP
+ int ret;
+ INTERNAL_SIZE_T offset = p->prev_size;
+ av->n_mmaps--;
+ av->mmapped_mem -= (size + offset);
+ ret = munmap((char*)p - offset, size + offset);
+ /* munmap returns non-zero on failure */
+ assert(ret == 0);
+#endif
+ }
+ }
+}
+
+/*
+ ------------------------- malloc_consolidate -------------------------
+
+ malloc_consolidate is a specialized version of free() that tears
+ down chunks held in fastbins. Free itself cannot be used for this
+ purpose since, among other things, it might place chunks back onto
+ fastbins. So, instead, we need to use a minor variant of the same
+ code.
+
+ Also, because this routine needs to be called the first time through
+ malloc anyway, it turns out to be the perfect place to trigger
+ initialization code.
+*/
+
+#if __STD_C
+static void malloc_consolidate(mstate av)
+#else
+static void malloc_consolidate(av) mstate av;
+#endif
+{
+ mfastbinptr* fb; /* current fastbin being consolidated */
+ mfastbinptr* maxfb; /* last fastbin (for loop control) */
+ mchunkptr p; /* current chunk being consolidated */
+ mchunkptr nextp; /* next chunk to consolidate */
+ mchunkptr unsorted_bin; /* bin header */
+ mchunkptr first_unsorted; /* chunk to link to */
+
+ /* These have same use as in free() */
+ mchunkptr nextchunk;
+ INTERNAL_SIZE_T size;
+ INTERNAL_SIZE_T nextsize;
+ INTERNAL_SIZE_T prevsize;
+ int nextinuse;
+ mchunkptr bck;
+ mchunkptr fwd;
+
+ /*
+ If max_fast is 0, we know that av hasn't
+ yet been initialized, in which case do so below
+ */
+
+ if (av->max_fast != 0) {
+ clear_fastchunks(av);
+
+ unsorted_bin = unsorted_chunks(av);
+
+ /*
+ Remove each chunk from fast bin and consolidate it, placing it
+ then in unsorted bin. Among other reasons for doing this,
+ placing in unsorted bin avoids needing to calculate actual bins
+ until malloc is sure that chunks aren't immediately going to be
+ reused anyway.
+ */
+
+ maxfb = &(av->fastbins[fastbin_index(av->max_fast)]);
+ fb = &(av->fastbins[0]);
+ do {
+ if ( (p = *fb) != 0) {
+ *fb = 0;
+
+ do {
+ check_inuse_chunk(p);
+ nextp = p->fd;
+
+ /* Slightly streamlined version of consolidation code in free() */
+ size = p->size & ~PREV_INUSE;
+ nextchunk = chunk_at_offset(p, size);
+ nextsize = chunksize(nextchunk);
+
+ if (!prev_inuse(p)) {
+ prevsize = p->prev_size;
+ size += prevsize;
+ p = chunk_at_offset(p, -((long) prevsize));
+ unlink(p, bck, fwd);
+ }
+
+ if (nextchunk != av->top) {
+ nextinuse = inuse_bit_at_offset(nextchunk, nextsize);
+ set_head(nextchunk, nextsize);
+
+ if (!nextinuse) {
+ size += nextsize;
+ unlink(nextchunk, bck, fwd);
+ }
+
+ first_unsorted = unsorted_bin->fd;
+ unsorted_bin->fd = p;
+ first_unsorted->bk = p;
+
+ set_head(p, size | PREV_INUSE);
+ p->bk = unsorted_bin;
+ p->fd = first_unsorted;
+ set_foot(p, size);
+ }
+
+ else {
+ size += nextsize;
+ set_head(p, size | PREV_INUSE);
+ av->top = p;
+ }
+
+ } while ( (p = nextp) != 0);
+
+ }
+ } while (fb++ != maxfb);
+ }
+ else {
+ malloc_init_state(av);
+ check_malloc_state();
+ }
+}
+
+/*
+ ------------------------------ realloc ------------------------------
+*/
+
+
+#if __STD_C
+Void_t* rEALLOc(Void_t* oldmem, size_t bytes)
+#else
+Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
+#endif
+{
+ mstate av = get_malloc_state();
+
+ INTERNAL_SIZE_T nb; /* padded request size */
+
+ mchunkptr oldp; /* chunk corresponding to oldmem */
+ INTERNAL_SIZE_T oldsize; /* its size */
+
+ mchunkptr newp; /* chunk to return */
+ INTERNAL_SIZE_T newsize; /* its size */
+ Void_t* newmem; /* corresponding user mem */
+
+ mchunkptr next; /* next contiguous chunk after oldp */
+
+ mchunkptr remainder; /* extra space at end of newp */
+ unsigned long remainder_size; /* its size */
+
+ mchunkptr bck; /* misc temp for linking */
+ mchunkptr fwd; /* misc temp for linking */
+
+ unsigned long copysize; /* bytes to copy */
+ unsigned int ncopies; /* INTERNAL_SIZE_T words to copy */
+ INTERNAL_SIZE_T* s; /* copy source */
+ INTERNAL_SIZE_T* d; /* copy destination */
+
+
+#ifdef REALLOC_ZERO_BYTES_FREES
+ if (bytes == 0) {
+ fREe(oldmem);
+ return 0;
+ }
+#endif
+
+ /* realloc of null is supposed to be same as malloc */
+ if (oldmem == 0) return mALLOc(bytes);
+
+ checked_request2size(bytes, nb);
+
+ oldp = mem2chunk(oldmem);
+ oldsize = chunksize(oldp);
+
+ check_inuse_chunk(oldp);
+
+ if (!chunk_is_mmapped(oldp)) {
+
+ if ((unsigned long)(oldsize) >= (unsigned long)(nb)) {
+ /* already big enough; split below */
+ newp = oldp;
+ newsize = oldsize;
+ }
+
+ else {
+ next = chunk_at_offset(oldp, oldsize);
+
+ /* Try to expand forward into top */
+ if (next == av->top &&
+ (unsigned long)(newsize = oldsize + chunksize(next)) >=
+ (unsigned long)(nb + MINSIZE)) {
+ set_head_size(oldp, nb);
+ av->top = chunk_at_offset(oldp, nb);
+ set_head(av->top, (newsize - nb) | PREV_INUSE);
+ return chunk2mem(oldp);
+ }
+
+ /* Try to expand forward into next chunk; split off remainder below */
+ else if (next != av->top &&
+ !inuse(next) &&
+ (unsigned long)(newsize = oldsize + chunksize(next)) >=
+ (unsigned long)(nb)) {
+ newp = oldp;
+ unlink(next, bck, fwd);
+ }
+
+ /* allocate, copy, free */
+ else {
+ newmem = mALLOc(nb - MALLOC_ALIGN_MASK);
+ if (newmem == 0)
+ return 0; /* propagate failure */
+
+ newp = mem2chunk(newmem);
+ newsize = chunksize(newp);
+
+ /*
+ Avoid copy if newp is next chunk after oldp.
+ */
+ if (newp == next) {
+ newsize += oldsize;
+ newp = oldp;
+ }
+ else {
+ /*
+ Unroll copy of <= 36 bytes (72 if 8byte sizes)
+ We know that contents have an odd number of
+ INTERNAL_SIZE_T-sized words; minimally 3.
+ */
+
+ copysize = oldsize - SIZE_SZ;
+ s = (INTERNAL_SIZE_T*)(oldmem);
+ d = (INTERNAL_SIZE_T*)(newmem);
+ ncopies = copysize / sizeof(INTERNAL_SIZE_T);
+ assert(ncopies >= 3);
+
+ if (ncopies > 9)
+ MALLOC_COPY(d, s, copysize);
+
+ else {
+ *(d+0) = *(s+0);
+ *(d+1) = *(s+1);
+ *(d+2) = *(s+2);
+ if (ncopies > 4) {
+ *(d+3) = *(s+3);
+ *(d+4) = *(s+4);
+ if (ncopies > 6) {
+ *(d+5) = *(s+5);
+ *(d+6) = *(s+6);
+ if (ncopies > 8) {
+ *(d+7) = *(s+7);
+ *(d+8) = *(s+8);
+ }
+ }
+ }
+ }
+
+ fREe(oldmem);
+ check_inuse_chunk(newp);
+ return chunk2mem(newp);
+ }
+ }
+ }
+
+ /* If possible, free extra space in old or extended chunk */
+
+ assert((unsigned long)(newsize) >= (unsigned long)(nb));
+
+ remainder_size = newsize - nb;
+
+ if (remainder_size < MINSIZE) { /* not enough extra to split off */
+ set_head_size(newp, newsize);
+ set_inuse_bit_at_offset(newp, newsize);
+ }
+ else { /* split remainder */
+ remainder = chunk_at_offset(newp, nb);
+ set_head_size(newp, nb);
+ set_head(remainder, remainder_size | PREV_INUSE);
+ /* Mark remainder as inuse so free() won't complain */
+ set_inuse_bit_at_offset(remainder, remainder_size);
+ fREe(chunk2mem(remainder));
+ }
+
+ check_inuse_chunk(newp);
+ return chunk2mem(newp);
+ }
+
+ /*
+ Handle mmap cases
+ */
+
+ else {
+#if HAVE_MMAP
+
+#if HAVE_MREMAP
+ INTERNAL_SIZE_T offset = oldp->prev_size;
+ size_t pagemask = av->pagesize - 1;
+ char *cp;
+ unsigned long sum;
+
+ /* Note the extra SIZE_SZ overhead */
+ newsize = (nb + offset + SIZE_SZ + pagemask) & ~pagemask;
+
+ /* don't need to remap if still within same page */
+ if (oldsize == newsize - offset)
+ return oldmem;
+
+ cp = (char*)mremap((char*)oldp - offset, oldsize + offset, newsize, 1);
+
+ if (cp != (char*)MORECORE_FAILURE) {
+
+ newp = (mchunkptr)(cp + offset);
+ set_head(newp, (newsize - offset)|IS_MMAPPED);
+
+ assert(aligned_OK(chunk2mem(newp)));
+ assert((newp->prev_size == offset));
+
+ /* update statistics */
+ sum = av->mmapped_mem += newsize - oldsize;
+ if (sum > (unsigned long)(av->max_mmapped_mem))
+ av->max_mmapped_mem = sum;
+ sum += av->sbrked_mem;
+ if (sum > (unsigned long)(av->max_total_mem))
+ av->max_total_mem = sum;
+
+ return chunk2mem(newp);
+ }
+#endif
+
+ /* Note the extra SIZE_SZ overhead. */
+ if ((unsigned long)(oldsize) >= (unsigned long)(nb + SIZE_SZ))
+ newmem = oldmem; /* do nothing */
+ else {
+ /* Must alloc, copy, free. */
+ newmem = mALLOc(nb - MALLOC_ALIGN_MASK);
+ if (newmem != 0) {
+ MALLOC_COPY(newmem, oldmem, oldsize - 2*SIZE_SZ);
+ fREe(oldmem);
+ }
+ }
+ return newmem;
+
+#else
+ /* If !HAVE_MMAP, but chunk_is_mmapped, user must have overwritten mem */
+ check_malloc_state();
+ MALLOC_FAILURE_ACTION;
+ return 0;
+#endif
+ }
+}
+
+/*
+ ------------------------------ memalign ------------------------------
+*/
+
+#if __STD_C
+Void_t* mEMALIGn(size_t alignment, size_t bytes)
+#else
+Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
+#endif
+{
+ INTERNAL_SIZE_T nb; /* padded request size */
+ char* m; /* memory returned by malloc call */
+ mchunkptr p; /* corresponding chunk */
+ char* brk; /* alignment point within p */
+ mchunkptr newp; /* chunk to return */
+ INTERNAL_SIZE_T newsize; /* its size */
+ INTERNAL_SIZE_T leadsize; /* leading space before alignment point */
+ mchunkptr remainder; /* spare room at end to split off */
+ unsigned long remainder_size; /* its size */
+ INTERNAL_SIZE_T size;
+
+ /* If need less alignment than we give anyway, just relay to malloc */
+
+ if (alignment <= MALLOC_ALIGNMENT) return mALLOc(bytes);
+
+ /* Otherwise, ensure that it is at least a minimum chunk size */
+
+ if (alignment < MINSIZE) alignment = MINSIZE;
+
+ /* Make sure alignment is power of 2 (in case MINSIZE is not). */
+ if ((alignment & (alignment - 1)) != 0) {
+ size_t a = MALLOC_ALIGNMENT * 2;
+ while ((unsigned long)a < (unsigned long)alignment) a <<= 1;
+ alignment = a;
+ }
+
+ checked_request2size(bytes, nb);
+
+ /*
+ Strategy: find a spot within that chunk that meets the alignment
+ request, and then possibly free the leading and trailing space.
+ */
+
+
+ /* Call malloc with worst case padding to hit alignment. */
+
+ m = (char*)(mALLOc(nb + alignment + MINSIZE));
+
+ if (m == 0) return 0; /* propagate failure */
+
+ p = mem2chunk(m);
+
+ if ((((unsigned long)(m)) % alignment) != 0) { /* misaligned */
+
+ /*
+ Find an aligned spot inside chunk. Since we need to give back
+ leading space in a chunk of at least MINSIZE, if the first
+ calculation places us at a spot with less than MINSIZE leader,
+ we can move to the next aligned spot -- we've allocated enough
+ total room so that this is always possible.
+ */
+
+ brk = (char*)mem2chunk(((unsigned long)(m + alignment - 1)) &
+ -((signed long) alignment));
+ if ((unsigned long)(brk - (char*)(p)) < MINSIZE)
+ brk += alignment;
+
+ newp = (mchunkptr)brk;
+ leadsize = brk - (char*)(p);
+ newsize = chunksize(p) - leadsize;
+
+ /* For mmapped chunks, just adjust offset */
+ if (chunk_is_mmapped(p)) {
+ newp->prev_size = p->prev_size + leadsize;
+ set_head(newp, newsize|IS_MMAPPED);
+ return chunk2mem(newp);
+ }
+
+ /* Otherwise, give back leader, use the rest */
+ set_head(newp, newsize | PREV_INUSE);
+ set_inuse_bit_at_offset(newp, newsize);
+ set_head_size(p, leadsize);
+ fREe(chunk2mem(p));
+ p = newp;
+
+ assert (newsize >= nb &&
+ (((unsigned long)(chunk2mem(p))) % alignment) == 0);
+ }
+
+ /* Also give back spare room at the end */
+ if (!chunk_is_mmapped(p)) {
+ size = chunksize(p);
+ if ((unsigned long)(size) > (unsigned long)(nb + MINSIZE)) {
+ remainder_size = size - nb;
+ remainder = chunk_at_offset(p, nb);
+ set_head(remainder, remainder_size | PREV_INUSE);
+ set_head_size(p, nb);
+ fREe(chunk2mem(remainder));
+ }
+ }
+
+ check_inuse_chunk(p);
+ return chunk2mem(p);
+}
+
+/*
+ ------------------------------ calloc ------------------------------
+*/
+
+#if __STD_C
+Void_t* cALLOc(size_t n_elements, size_t elem_size)
+#else
+Void_t* cALLOc(n_elements, elem_size) size_t n_elements; size_t elem_size;
+#endif
+{
+ mchunkptr p;
+ unsigned long clearsize;
+ unsigned long nclears;
+ INTERNAL_SIZE_T* d;
+
+ Void_t* mem = mALLOc(n_elements * elem_size);
+
+ if (mem != 0) {
+ p = mem2chunk(mem);
+
+#if MMAP_CLEARS
+ if (!chunk_is_mmapped(p)) /* don't need to clear mmapped space */
+#endif
+ {
+ /*
+ Unroll clear of <= 36 bytes (72 if 8byte sizes)
+ We know that contents have an odd number of
+ INTERNAL_SIZE_T-sized words; minimally 3.
+ */
+
+ d = (INTERNAL_SIZE_T*)mem;
+ clearsize = chunksize(p) - SIZE_SZ;
+ nclears = clearsize / sizeof(INTERNAL_SIZE_T);
+ assert(nclears >= 3);
+
+ if (nclears > 9)
+ MALLOC_ZERO(d, clearsize);
+
+ else {
+ *(d+0) = 0;
+ *(d+1) = 0;
+ *(d+2) = 0;
+ if (nclears > 4) {
+ *(d+3) = 0;
+ *(d+4) = 0;
+ if (nclears > 6) {
+ *(d+5) = 0;
+ *(d+6) = 0;
+ if (nclears > 8) {
+ *(d+7) = 0;
+ *(d+8) = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+ return mem;
+}
+
+/*
+ ------------------------------ cfree ------------------------------
+*/
+
+#if __STD_C
+void cFREe(Void_t *mem)
+#else
+void cFREe(mem) Void_t *mem;
+#endif
+{
+ fREe(mem);
+}
+
+/*
+ ------------------------- independent_calloc -------------------------
+*/
+
+#if __STD_C
+Void_t** iCALLOc(size_t n_elements, size_t elem_size, Void_t* chunks[])
+#else
+Void_t** iCALLOc(n_elements, elem_size, chunks) size_t n_elements; size_t elem_size; Void_t* chunks[];
+#endif
+{
+ size_t sz = elem_size; /* serves as 1-element array */
+ /* opts arg of 3 means all elements are same size, and should be cleared */
+ return iALLOc(n_elements, &sz, 3, chunks);
+}
+
+/*
+ ------------------------- independent_comalloc -------------------------
+*/
+
+#if __STD_C
+Void_t** iCOMALLOc(size_t n_elements, size_t sizes[], Void_t* chunks[])
+#else
+Void_t** iCOMALLOc(n_elements, sizes, chunks) size_t n_elements; size_t sizes[]; Void_t* chunks[];
+#endif
+{
+ return iALLOc(n_elements, sizes, 0, chunks);
+}
+
+
+/*
+ ------------------------------ ialloc ------------------------------
+ ialloc provides common support for independent_X routines, handling all of
+ the combinations that can result.
+
+ The opts arg has:
+ bit 0 set if all elements are same size (using sizes[0])
+ bit 1 set if elements should be zeroed
+*/
+
+
+#if __STD_C
+static Void_t** iALLOc(size_t n_elements,
+ size_t* sizes,
+ int opts,
+ Void_t* chunks[])
+#else
+static Void_t** iALLOc(n_elements, sizes, opts, chunks) size_t n_elements; size_t* sizes; int opts; Void_t* chunks[];
+#endif
+{
+ mstate av = get_malloc_state();
+ INTERNAL_SIZE_T element_size; /* chunksize of each element, if all same */
+ INTERNAL_SIZE_T contents_size; /* total size of elements */
+ INTERNAL_SIZE_T array_size; /* request size of pointer array */
+ Void_t* mem; /* malloced aggregate space */
+ mchunkptr p; /* corresponding chunk */
+ INTERNAL_SIZE_T remainder_size; /* remaining bytes while splitting */
+ Void_t** marray; /* either "chunks" or malloced ptr array */
+ mchunkptr array_chunk; /* chunk for malloced ptr array */
+ int mmx; /* to disable mmap */
+ INTERNAL_SIZE_T size;
+ size_t i;
+
+ /* Ensure initialization/consolidation */
+ if (have_fastchunks(av)) malloc_consolidate(av);
+
+ /* compute array length, if needed */
+ if (chunks != 0) {
+ if (n_elements == 0)
+ return chunks; /* nothing to do */
+ marray = chunks;
+ array_size = 0;
+ }
+ else {
+ /* if empty req, must still return chunk representing empty array */
+ if (n_elements == 0)
+ return (Void_t**) mALLOc(0);
+ marray = 0;
+ array_size = request2size(n_elements * (sizeof(Void_t*)));
+ }
+
+ /* compute total element size */
+ if (opts & 0x1) { /* all-same-size */
+ element_size = request2size(*sizes);
+ contents_size = n_elements * element_size;
+ }
+ else { /* add up all the sizes */
+ element_size = 0;
+ contents_size = 0;
+ for (i = 0; i != n_elements; ++i)
+ contents_size += request2size(sizes[i]);
+ }
+
+ /* subtract out alignment bytes from total to minimize overallocation */
+ size = contents_size + array_size - MALLOC_ALIGN_MASK;
+
+ /*
+ Allocate the aggregate chunk.
+ But first disable mmap so malloc won't use it, since
+ we would not be able to later free/realloc space internal
+ to a segregated mmap region.
+ */
+ mmx = av->n_mmaps_max; /* disable mmap */
+ av->n_mmaps_max = 0;
+ mem = mALLOc(size);
+ av->n_mmaps_max = mmx; /* reset mmap */
+ if (mem == 0)
+ return 0;
+
+ p = mem2chunk(mem);
+ assert(!chunk_is_mmapped(p));
+ remainder_size = chunksize(p);
+
+ if (opts & 0x2) { /* optionally clear the elements */
+ MALLOC_ZERO(mem, remainder_size - SIZE_SZ - array_size);
+ }
+
+ /* If not provided, allocate the pointer array as final part of chunk */
+ if (marray == 0) {
+ array_chunk = chunk_at_offset(p, contents_size);
+ marray = (Void_t**) (chunk2mem(array_chunk));
+ set_head(array_chunk, (remainder_size - contents_size) | PREV_INUSE);
+ remainder_size = contents_size;
+ }
+
+ /* split out elements */
+ for (i = 0; ; ++i) {
+ marray[i] = chunk2mem(p);
+ if (i != n_elements-1) {
+ if (element_size != 0)
+ size = element_size;
+ else
+ size = request2size(sizes[i]);
+ remainder_size -= size;
+ set_head(p, size | PREV_INUSE);
+ p = chunk_at_offset(p, size);
+ }
+ else { /* the final element absorbs any overallocation slop */
+ set_head(p, remainder_size | PREV_INUSE);
+ break;
+ }
+ }
+
+#if DEBUG
+ if (marray != chunks) {
+ /* final element must have exactly exhausted chunk */
+ if (element_size != 0)
+ assert(remainder_size == element_size);
+ else
+ assert(remainder_size == request2size(sizes[i]));
+ check_inuse_chunk(mem2chunk(marray));
+ }
+
+ for (i = 0; i != n_elements; ++i)
+ check_inuse_chunk(mem2chunk(marray[i]));
+#endif
+
+ return marray;
+}
+
+
+/*
+ ------------------------------ valloc ------------------------------
+*/
+
+#if __STD_C
+Void_t* vALLOc(size_t bytes)
+#else
+Void_t* vALLOc(bytes) size_t bytes;
+#endif
+{
+ /* Ensure initialization/consolidation */
+ mstate av = get_malloc_state();
+ if (have_fastchunks(av)) malloc_consolidate(av);
+ return mEMALIGn(av->pagesize, bytes);
+}
+
+/*
+ ------------------------------ pvalloc ------------------------------
+*/
+
+
+#if __STD_C
+Void_t* pVALLOc(size_t bytes)
+#else
+Void_t* pVALLOc(bytes) size_t bytes;
+#endif
+{
+ mstate av = get_malloc_state();
+ size_t pagesz;
+
+ /* Ensure initialization/consolidation */
+ if (have_fastchunks(av)) malloc_consolidate(av);
+ pagesz = av->pagesize;
+ return mEMALIGn(pagesz, (bytes + pagesz - 1) & ~(pagesz - 1));
+}
+
+
+/*
+ ------------------------------ malloc_trim ------------------------------
+*/
+
+#if __STD_C
+int mTRIm(size_t pad)
+#else
+int mTRIm(pad) size_t pad;
+#endif
+{
+ mstate av = get_malloc_state();
+ /* Ensure initialization/consolidation */
+ malloc_consolidate(av);
+
+#ifndef MORECORE_CANNOT_TRIM
+ return sYSTRIm(pad, av);
+#else
+ return 0;
+#endif
+}
+
+
+/*
+ ------------------------- malloc_usable_size -------------------------
+*/
+
+#if __STD_C
+size_t mUSABLe(Void_t* mem)
+#else
+size_t mUSABLe(mem) Void_t* mem;
+#endif
+{
+ mchunkptr p;
+ if (mem != 0) {
+ p = mem2chunk(mem);
+ if (chunk_is_mmapped(p))
+ return chunksize(p) - 2*SIZE_SZ;
+ else if (inuse(p))
+ return chunksize(p) - SIZE_SZ;
+ }
+ return 0;
+}
+
+/*
+ ------------------------------ mallinfo ------------------------------
+*/
+
+struct mallinfo mALLINFo()
+{
+ mstate av = get_malloc_state();
+ struct mallinfo mi;
+ int i;
+ mbinptr b;
+ mchunkptr p;
+ INTERNAL_SIZE_T avail;
+ INTERNAL_SIZE_T fastavail;
+ int nblocks;
+ int nfastblocks;
+
+ /* Ensure initialization */
+ if (av->top == 0) malloc_consolidate(av);
+
+ check_malloc_state();
+
+ /* Account for top */
+ avail = chunksize(av->top);
+ nblocks = 1; /* top always exists */
+
+ /* traverse fastbins */
+ nfastblocks = 0;
+ fastavail = 0;
+
+ for (i = 0; i < NFASTBINS; ++i) {
+ for (p = av->fastbins[i]; p != 0; p = p->fd) {
+ ++nfastblocks;
+ fastavail += chunksize(p);
+ }
+ }
+
+ avail += fastavail;
+
+ /* traverse regular bins */
+ for (i = 1; i < NBINS; ++i) {
+ b = bin_at(av, i);
+ for (p = last(b); p != b; p = p->bk) {
+ ++nblocks;
+ avail += chunksize(p);
+ }
+ }
+
+ mi.smblks = nfastblocks;
+ mi.ordblks = nblocks;
+ mi.fordblks = avail;
+ mi.uordblks = av->sbrked_mem - avail;
+ mi.arena = av->sbrked_mem;
+ mi.hblks = av->n_mmaps;
+ mi.hblkhd = av->mmapped_mem;
+ mi.fsmblks = fastavail;
+ mi.keepcost = chunksize(av->top);
+ mi.usmblks = av->max_total_mem;
+ return mi;
+}
+
+/*
+ ------------------------------ malloc_stats ------------------------------
+*/
+
+void mSTATs()
+{
+ struct mallinfo mi = mALLINFo();
+
+#ifdef WIN32
+ {
+ unsigned long free, reserved, committed;
+ vminfo (&free, &reserved, &committed);
+ fprintf(stderr, "free bytes = %10lu\n",
+ free);
+ fprintf(stderr, "reserved bytes = %10lu\n",
+ reserved);
+ fprintf(stderr, "committed bytes = %10lu\n",
+ committed);
+ }
+#endif
+
+
+ fprintf(stderr, "max system bytes = %10lu\n",
+ (unsigned long)(mi.usmblks));
+ fprintf(stderr, "system bytes = %10lu\n",
+ (unsigned long)(mi.arena + mi.hblkhd));
+ fprintf(stderr, "in use bytes = %10lu\n",
+ (unsigned long)(mi.uordblks + mi.hblkhd));
+
+
+#ifdef WIN32
+ {
+ unsigned long kernel, user;
+ if (cpuinfo (TRUE, &kernel, &user)) {
+ fprintf(stderr, "kernel ms = %10lu\n",
+ kernel);
+ fprintf(stderr, "user ms = %10lu\n",
+ user);
+ }
+ }
+#endif
+}
+
+
+/*
+ ------------------------------ mallopt ------------------------------
+*/
+
+#if __STD_C
+int mALLOPt(int param_number, int value)
+#else
+int mALLOPt(param_number, value) int param_number; int value;
+#endif
+{
+ mstate av = get_malloc_state();
+ /* Ensure initialization/consolidation */
+ malloc_consolidate(av);
+
+ switch(param_number) {
+ case M_MXFAST:
+ if (value >= 0 && value <= MAX_FAST_SIZE) {
+ set_max_fast(av, value);
+ return 1;
+ }
+ else
+ return 0;
+
+ case M_TRIM_THRESHOLD:
+ av->trim_threshold = value;
+ return 1;
+
+ case M_TOP_PAD:
+ av->top_pad = value;
+ return 1;
+
+ case M_MMAP_THRESHOLD:
+ av->mmap_threshold = value;
+ return 1;
+
+ case M_MMAP_MAX:
+#if !HAVE_MMAP
+ if (value != 0)
+ return 0;
+#endif
+ av->n_mmaps_max = value;
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+
+/*
+ -------------------- Alternative MORECORE functions --------------------
+*/
+
+
+/*
+ General Requirements for MORECORE.
+
+ The MORECORE function must have the following properties:
+
+ If MORECORE_CONTIGUOUS is false:
+
+ * MORECORE must allocate in multiples of pagesize. It will
+ only be called with arguments that are multiples of pagesize.
+
+ * MORECORE(0) must return an address that is at least
+ MALLOC_ALIGNMENT aligned. (Page-aligning always suffices.)
+
+ else (i.e. If MORECORE_CONTIGUOUS is true):
+
+ * Consecutive calls to MORECORE with positive arguments
+ return increasing addresses, indicating that space has been
+ contiguously extended.
+
+ * MORECORE need not allocate in multiples of pagesize.
+ Calls to MORECORE need not have args of multiples of pagesize.
+
+ * MORECORE need not page-align.
+
+ In either case:
+
+ * MORECORE may allocate more memory than requested. (Or even less,
+ but this will generally result in a malloc failure.)
+
+ * MORECORE must not allocate memory when given argument zero, but
+ instead return one past the end address of memory from previous
+ nonzero call. This malloc does NOT call MORECORE(0)
+ until at least one call with positive arguments is made, so
+ the initial value returned is not important.
+
+ * Even though consecutive calls to MORECORE need not return contiguous
+ addresses, it must be OK for malloc'ed chunks to span multiple
+ regions in those cases where they do happen to be contiguous.
+
+ * MORECORE need not handle negative arguments -- it may instead
+ just return MORECORE_FAILURE when given negative arguments.
+ Negative arguments are always multiples of pagesize. MORECORE
+ must not misinterpret negative args as large positive unsigned
+ args. You can suppress all such calls from even occurring by defining
+ MORECORE_CANNOT_TRIM,
+
+ There is some variation across systems about the type of the
+ argument to sbrk/MORECORE. If size_t is unsigned, then it cannot
+ actually be size_t, because sbrk supports negative args, so it is
+ normally the signed type of the same width as size_t (sometimes
+ declared as "intptr_t", and sometimes "ptrdiff_t"). It doesn't much
+ matter though. Internally, we use "long" as arguments, which should
+ work across all reasonable possibilities.
+
+ Additionally, if MORECORE ever returns failure for a positive
+ request, and HAVE_MMAP is true, then mmap is used as a noncontiguous
+ system allocator. This is a useful backup strategy for systems with
+ holes in address spaces -- in this case sbrk cannot contiguously
+ expand the heap, but mmap may be able to map noncontiguous space.
+
+ If you'd like mmap to ALWAYS be used, you can define MORECORE to be
+ a function that always returns MORECORE_FAILURE.
+
+ If you are using this malloc with something other than sbrk (or its
+ emulation) to supply memory regions, you probably want to set
+ MORECORE_CONTIGUOUS as false. As an example, here is a custom
+ allocator kindly contributed for pre-OSX macOS. It uses virtually
+ but not necessarily physically contiguous non-paged memory (locked
+ in, present and won't get swapped out). You can use it by
+ uncommenting this section, adding some #includes, and setting up the
+ appropriate defines above:
+
+ #define MORECORE osMoreCore
+ #define MORECORE_CONTIGUOUS 0
+
+ There is also a shutdown routine that should somehow be called for
+ cleanup upon program exit.
+
+ #define MAX_POOL_ENTRIES 100
+ #define MINIMUM_MORECORE_SIZE (64 * 1024)
+ static int next_os_pool;
+ void *our_os_pools[MAX_POOL_ENTRIES];
+
+ void *osMoreCore(int size)
+ {
+ void *ptr = 0;
+ static void *sbrk_top = 0;
+
+ if (size > 0)
+ {
+ if (size < MINIMUM_MORECORE_SIZE)
+ size = MINIMUM_MORECORE_SIZE;
+ if (CurrentExecutionLevel() == kTaskLevel)
+ ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0);
+ if (ptr == 0)
+ {
+ return (void *) MORECORE_FAILURE;
+ }
+ // save ptrs so they can be freed during cleanup
+ our_os_pools[next_os_pool] = ptr;
+ next_os_pool++;
+ ptr = (void *) ((((unsigned long) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK);
+ sbrk_top = (char *) ptr + size;
+ return ptr;
+ }
+ else if (size < 0)
+ {
+ // we don't currently support shrink behavior
+ return (void *) MORECORE_FAILURE;
+ }
+ else
+ {
+ return sbrk_top;
+ }
+ }
+
+ // cleanup any allocated memory pools
+ // called as last thing before shutting down driver
+
+ void osCleanupMem(void)
+ {
+ void **ptr;
+
+ for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++)
+ if (*ptr)
+ {
+ PoolDeallocate(*ptr);
+ *ptr = 0;
+ }
+ }
+
+*/
+
+
+/*
+ --------------------------------------------------------------
+
+ Emulation of sbrk for win32.
+ Donated by J. Walter <Walter@GeNeSys-e.de>.
+ For additional information about this code, and malloc on Win32, see
+ http://www.genesys-e.de/jwalter/
+*/
+
+
+#ifdef WIN32
+
+#ifdef _DEBUG
+/* #define TRACE */
+#endif
+
+/* Support for USE_MALLOC_LOCK */
+#ifdef USE_MALLOC_LOCK
+
+/* Wait for spin lock */
+static int slwait (int *sl) {
+ while (InterlockedCompareExchange ((void **) sl, (void *) 1, (void *) 0) != 0)
+ Sleep (0);
+ return 0;
+}
+
+/* Release spin lock */
+static int slrelease (int *sl) {
+ InterlockedExchange (sl, 0);
+ return 0;
+}
+
+#ifdef NEEDED
+/* Spin lock for emulation code */
+static int g_sl;
+#endif
+
+#endif /* USE_MALLOC_LOCK */
+
+/* getpagesize for windows */
+static long getpagesize (void) {
+ static long g_pagesize = 0;
+ if (! g_pagesize) {
+ SYSTEM_INFO system_info;
+ GetSystemInfo (&system_info);
+ g_pagesize = system_info.dwPageSize;
+ }
+ return g_pagesize;
+}
+static long getregionsize (void) {
+ static long g_regionsize = 0;
+ if (! g_regionsize) {
+ SYSTEM_INFO system_info;
+ GetSystemInfo (&system_info);
+ g_regionsize = system_info.dwAllocationGranularity;
+ }
+ return g_regionsize;
+}
+
+/* A region list entry */
+typedef struct _region_list_entry {
+ void *top_allocated;
+ void *top_committed;
+ void *top_reserved;
+ long reserve_size;
+ struct _region_list_entry *previous;
+} region_list_entry;
+
+/* Allocate and link a region entry in the region list */
+static int region_list_append (region_list_entry **last, void *base_reserved, long reserve_size) {
+ region_list_entry *next = HeapAlloc (GetProcessHeap (), 0, sizeof (region_list_entry));
+ if (! next)
+ return FALSE;
+ next->top_allocated = (char *) base_reserved;
+ next->top_committed = (char *) base_reserved;
+ next->top_reserved = (char *) base_reserved + reserve_size;
+ next->reserve_size = reserve_size;
+ next->previous = *last;
+ *last = next;
+ return TRUE;
+}
+/* Free and unlink the last region entry from the region list */
+static int region_list_remove (region_list_entry **last) {
+ region_list_entry *previous = (*last)->previous;
+ if (! HeapFree (GetProcessHeap (), sizeof (region_list_entry), *last))
+ return FALSE;
+ *last = previous;
+ return TRUE;
+}
+
+#define CEIL(size,to) (((size)+(to)-1)&~((to)-1))
+#define FLOOR(size,to) ((size)&~((to)-1))
+
+#define SBRK_SCALE 0
+/* #define SBRK_SCALE 1 */
+/* #define SBRK_SCALE 2 */
+/* #define SBRK_SCALE 4 */
+
+/* sbrk for windows */
+static void *sbrk (long size) {
+ static long g_pagesize, g_my_pagesize;
+ static long g_regionsize, g_my_regionsize;
+ static region_list_entry *g_last;
+ void *result = (void *) MORECORE_FAILURE;
+#ifdef TRACE
+ printf ("sbrk %d\n", size);
+#endif
+#if defined (USE_MALLOC_LOCK) && defined (NEEDED)
+ /* Wait for spin lock */
+ slwait (&g_sl);
+#endif
+ /* First time initialization */
+ if (! g_pagesize) {
+ g_pagesize = getpagesize ();
+ g_my_pagesize = g_pagesize << SBRK_SCALE;
+ }
+ if (! g_regionsize) {
+ g_regionsize = getregionsize ();
+ g_my_regionsize = g_regionsize << SBRK_SCALE;
+ }
+ if (! g_last) {
+ if (! region_list_append (&g_last, 0, 0))
+ goto sbrk_exit;
+ }
+ /* Assert invariants */
+ assert (g_last);
+ assert ((char *) g_last->top_reserved - g_last->reserve_size <= (char *) g_last->top_allocated &&
+ g_last->top_allocated <= g_last->top_committed);
+ assert ((char *) g_last->top_reserved - g_last->reserve_size <= (char *) g_last->top_committed &&
+ g_last->top_committed <= g_last->top_reserved &&
+ (unsigned) g_last->top_committed % g_pagesize == 0);
+ assert ((unsigned) g_last->top_reserved % g_regionsize == 0);
+ assert ((unsigned) g_last->reserve_size % g_regionsize == 0);
+ /* Allocation requested? */
+ if (size >= 0) {
+ /* Allocation size is the requested size */
+ long allocate_size = size;
+ /* Compute the size to commit */
+ long to_commit = (char *) g_last->top_allocated + allocate_size - (char *) g_last->top_committed;
+ /* Do we reach the commit limit? */
+ if (to_commit > 0) {
+ /* Round size to commit */
+ long commit_size = CEIL (to_commit, g_my_pagesize);
+ /* Compute the size to reserve */
+ long to_reserve = (char *) g_last->top_committed + commit_size - (char *) g_last->top_reserved;
+ /* Do we reach the reserve limit? */
+ if (to_reserve > 0) {
+ /* Compute the remaining size to commit in the current region */
+ long remaining_commit_size = (char *) g_last->top_reserved - (char *) g_last->top_committed;
+ if (remaining_commit_size > 0) {
+ /* Assert preconditions */
+ assert ((unsigned) g_last->top_committed % g_pagesize == 0);
+ assert (0 < remaining_commit_size && remaining_commit_size % g_pagesize == 0); {
+ /* Commit this */
+ void *base_committed = VirtualAlloc (g_last->top_committed, remaining_commit_size,
+ MEM_COMMIT, PAGE_READWRITE);
+ /* Check returned pointer for consistency */
+ if (base_committed != g_last->top_committed)
+ goto sbrk_exit;
+ /* Assert postconditions */
+ assert ((unsigned) base_committed % g_pagesize == 0);
+#ifdef TRACE
+ printf ("Commit %p %d\n", base_committed, remaining_commit_size);
+#endif
+ /* Adjust the regions commit top */
+ g_last->top_committed = (char *) base_committed + remaining_commit_size;
+ }
+ } {
+ /* Now we are going to search and reserve. */
+ int contiguous = -1;
+ int found = FALSE;
+ MEMORY_BASIC_INFORMATION memory_info;
+ void *base_reserved;
+ long reserve_size;
+ do {
+ /* Assume contiguous memory */
+ contiguous = TRUE;
+ /* Round size to reserve */
+ reserve_size = CEIL (to_reserve, g_my_regionsize);
+ /* Start with the current region's top */
+ memory_info.BaseAddress = g_last->top_reserved;
+ /* Assert preconditions */
+ assert ((unsigned) memory_info.BaseAddress % g_pagesize == 0);
+ assert (0 < reserve_size && reserve_size % g_regionsize == 0);
+ while (VirtualQuery (memory_info.BaseAddress, &memory_info, sizeof (memory_info))) {
+ /* Assert postconditions */
+ assert ((unsigned) memory_info.BaseAddress % g_pagesize == 0);
+#ifdef TRACE
+ printf ("Query %p %d %s\n", memory_info.BaseAddress, memory_info.RegionSize,
+ memory_info.State == MEM_FREE ? "FREE":
+ (memory_info.State == MEM_RESERVE ? "RESERVED":
+ (memory_info.State == MEM_COMMIT ? "COMMITTED": "?")));
+#endif
+ /* Region is free, well aligned and big enough: we are done */
+ if (memory_info.State == MEM_FREE &&
+ (unsigned) memory_info.BaseAddress % g_regionsize == 0 &&
+ memory_info.RegionSize >= (unsigned) reserve_size) {
+ found = TRUE;
+ break;
+ }
+ /* From now on we can't get contiguous memory! */
+ contiguous = FALSE;
+ /* Recompute size to reserve */
+ reserve_size = CEIL (allocate_size, g_my_regionsize);
+ memory_info.BaseAddress = (char *) memory_info.BaseAddress + memory_info.RegionSize;
+ /* Assert preconditions */
+ assert ((unsigned) memory_info.BaseAddress % g_pagesize == 0);
+ assert (0 < reserve_size && reserve_size % g_regionsize == 0);
+ }
+ /* Search failed? */
+ if (! found)
+ goto sbrk_exit;
+ /* Assert preconditions */
+ assert ((unsigned) memory_info.BaseAddress % g_regionsize == 0);
+ assert (0 < reserve_size && reserve_size % g_regionsize == 0);
+ /* Try to reserve this */
+ base_reserved = VirtualAlloc (memory_info.BaseAddress, reserve_size,
+ MEM_RESERVE, PAGE_NOACCESS);
+ if (! base_reserved) {
+ int rc = GetLastError ();
+ if (rc != ERROR_INVALID_ADDRESS)
+ goto sbrk_exit;
+ }
+ /* A null pointer signals (hopefully) a race condition with another thread. */
+ /* In this case, we try again. */
+ } while (! base_reserved);
+ /* Check returned pointer for consistency */
+ if (memory_info.BaseAddress && base_reserved != memory_info.BaseAddress)
+ goto sbrk_exit;
+ /* Assert postconditions */
+ assert ((unsigned) base_reserved % g_regionsize == 0);
+#ifdef TRACE
+ printf ("Reserve %p %d\n", base_reserved, reserve_size);
+#endif
+ /* Did we get contiguous memory? */
+ if (contiguous) {
+ long start_size = (char *) g_last->top_committed - (char *) g_last->top_allocated;
+ /* Adjust allocation size */
+ allocate_size -= start_size;
+ /* Adjust the regions allocation top */
+ g_last->top_allocated = g_last->top_committed;
+ /* Recompute the size to commit */
+ to_commit = (char *) g_last->top_allocated + allocate_size - (char *) g_last->top_committed;
+ /* Round size to commit */
+ commit_size = CEIL (to_commit, g_my_pagesize);
+ }
+ /* Append the new region to the list */
+ if (! region_list_append (&g_last, base_reserved, reserve_size))
+ goto sbrk_exit;
+ /* Didn't we get contiguous memory? */
+ if (! contiguous) {
+ /* Recompute the size to commit */
+ to_commit = (char *) g_last->top_allocated + allocate_size - (char *) g_last->top_committed;
+ /* Round size to commit */
+ commit_size = CEIL (to_commit, g_my_pagesize);
+ }
+ }
+ }
+ /* Assert preconditions */
+ assert ((unsigned) g_last->top_committed % g_pagesize == 0);
+ assert (0 < commit_size && commit_size % g_pagesize == 0); {
+ /* Commit this */
+ void *base_committed = VirtualAlloc (g_last->top_committed, commit_size,
+ MEM_COMMIT, PAGE_READWRITE);
+ /* Check returned pointer for consistency */
+ if (base_committed != g_last->top_committed)
+ goto sbrk_exit;
+ /* Assert postconditions */
+ assert ((unsigned) base_committed % g_pagesize == 0);
+#ifdef TRACE
+ printf ("Commit %p %d\n", base_committed, commit_size);
+#endif
+ /* Adjust the regions commit top */
+ g_last->top_committed = (char *) base_committed + commit_size;
+ }
+ }
+ /* Adjust the regions allocation top */
+ g_last->top_allocated = (char *) g_last->top_allocated + allocate_size;
+ result = (char *) g_last->top_allocated - size;
+ /* Deallocation requested? */
+ } else if (size < 0) {
+ long deallocate_size = - size;
+ /* As long as we have a region to release */
+ while ((char *) g_last->top_allocated - deallocate_size < (char *) g_last->top_reserved - g_last->reserve_size) {
+ /* Get the size to release */
+ long release_size = g_last->reserve_size;
+ /* Get the base address */
+ void *base_reserved = (char *) g_last->top_reserved - release_size;
+ /* Assert preconditions */
+ assert ((unsigned) base_reserved % g_regionsize == 0);
+ assert (0 < release_size && release_size % g_regionsize == 0); {
+ /* Release this */
+ int rc = VirtualFree (base_reserved, 0,
+ MEM_RELEASE);
+ /* Check returned code for consistency */
+ if (! rc)
+ goto sbrk_exit;
+#ifdef TRACE
+ printf ("Release %p %d\n", base_reserved, release_size);
+#endif
+ }
+ /* Adjust deallocation size */
+ deallocate_size -= (char *) g_last->top_allocated - (char *) base_reserved;
+ /* Remove the old region from the list */
+ if (! region_list_remove (&g_last))
+ goto sbrk_exit;
+ } {
+ /* Compute the size to decommit */
+ long to_decommit = (char *) g_last->top_committed - ((char *) g_last->top_allocated - deallocate_size);
+ if (to_decommit >= g_my_pagesize) {
+ /* Compute the size to decommit */
+ long decommit_size = FLOOR (to_decommit, g_my_pagesize);
+ /* Compute the base address */
+ void *base_committed = (char *) g_last->top_committed - decommit_size;
+ /* Assert preconditions */
+ assert ((unsigned) base_committed % g_pagesize == 0);
+ assert (0 < decommit_size && decommit_size % g_pagesize == 0); {
+ /* Decommit this */
+ int rc = VirtualFree ((char *) base_committed, decommit_size,
+ MEM_DECOMMIT);
+ /* Check returned code for consistency */
+ if (! rc)
+ goto sbrk_exit;
+#ifdef TRACE
+ printf ("Decommit %p %d\n", base_committed, decommit_size);
+#endif
+ }
+ /* Adjust deallocation size and regions commit and allocate top */
+ deallocate_size -= (char *) g_last->top_allocated - (char *) base_committed;
+ g_last->top_committed = base_committed;
+ g_last->top_allocated = base_committed;
+ }
+ }
+ /* Adjust regions allocate top */
+ g_last->top_allocated = (char *) g_last->top_allocated - deallocate_size;
+ /* Check for underflow */
+ if ((char *) g_last->top_reserved - g_last->reserve_size > (char *) g_last->top_allocated ||
+ g_last->top_allocated > g_last->top_committed) {
+ /* Adjust regions allocate top */
+ g_last->top_allocated = (char *) g_last->top_reserved - g_last->reserve_size;
+ goto sbrk_exit;
+ }
+ result = g_last->top_allocated;
+ }
+ /* Assert invariants */
+ assert (g_last);
+ assert ((char *) g_last->top_reserved - g_last->reserve_size <= (char *) g_last->top_allocated &&
+ g_last->top_allocated <= g_last->top_committed);
+ assert ((char *) g_last->top_reserved - g_last->reserve_size <= (char *) g_last->top_committed &&
+ g_last->top_committed <= g_last->top_reserved &&
+ (unsigned) g_last->top_committed % g_pagesize == 0);
+ assert ((unsigned) g_last->top_reserved % g_regionsize == 0);
+ assert ((unsigned) g_last->reserve_size % g_regionsize == 0);
+
+sbrk_exit:
+#if defined (USE_MALLOC_LOCK) && defined (NEEDED)
+ /* Release spin lock */
+ slrelease (&g_sl);
+#endif
+ return result;
+}
+
+/* mmap for windows */
+static void *mmap (void *ptr, long size, long prot, long type, long handle, long arg) {
+ static long g_pagesize;
+ static long g_regionsize;
+#ifdef TRACE
+ printf ("mmap %d\n", size);
+#endif
+#if defined (USE_MALLOC_LOCK) && defined (NEEDED)
+ /* Wait for spin lock */
+ slwait (&g_sl);
+#endif
+ /* First time initialization */
+ if (! g_pagesize)
+ g_pagesize = getpagesize ();
+ if (! g_regionsize)
+ g_regionsize = getregionsize ();
+ /* Assert preconditions */
+ assert ((unsigned) ptr % g_regionsize == 0);
+ assert (size % g_pagesize == 0);
+ /* Allocate this */
+ ptr = VirtualAlloc (ptr, size,
+ MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE);
+ if (! ptr) {
+ ptr = (void *) MORECORE_FAILURE;
+ goto mmap_exit;
+ }
+ /* Assert postconditions */
+ assert ((unsigned) ptr % g_regionsize == 0);
+#ifdef TRACE
+ printf ("Commit %p %d\n", ptr, size);
+#endif
+mmap_exit:
+#if defined (USE_MALLOC_LOCK) && defined (NEEDED)
+ /* Release spin lock */
+ slrelease (&g_sl);
+#endif
+ return ptr;
+}
+
+/* munmap for windows */
+static long munmap (void *ptr, long size) {
+ static long g_pagesize;
+ static long g_regionsize;
+ int rc = MUNMAP_FAILURE;
+#ifdef TRACE
+ printf ("munmap %p %d\n", ptr, size);
+#endif
+#if defined (USE_MALLOC_LOCK) && defined (NEEDED)
+ /* Wait for spin lock */
+ slwait (&g_sl);
+#endif
+ /* First time initialization */
+ if (! g_pagesize)
+ g_pagesize = getpagesize ();
+ if (! g_regionsize)
+ g_regionsize = getregionsize ();
+ /* Assert preconditions */
+ assert ((unsigned) ptr % g_regionsize == 0);
+ assert (size % g_pagesize == 0);
+ /* Free this */
+ if (! VirtualFree (ptr, 0,
+ MEM_RELEASE))
+ goto munmap_exit;
+ rc = 0;
+#ifdef TRACE
+ printf ("Release %p %d\n", ptr, size);
+#endif
+munmap_exit:
+#if defined (USE_MALLOC_LOCK) && defined (NEEDED)
+ /* Release spin lock */
+ slrelease (&g_sl);
+#endif
+ return rc;
+}
+
+static void vminfo (unsigned long *free, unsigned long *reserved, unsigned long *committed) {
+ MEMORY_BASIC_INFORMATION memory_info;
+ memory_info.BaseAddress = 0;
+ *free = *reserved = *committed = 0;
+ while (VirtualQuery (memory_info.BaseAddress, &memory_info, sizeof (memory_info))) {
+ switch (memory_info.State) {
+ case MEM_FREE:
+ *free += memory_info.RegionSize;
+ break;
+ case MEM_RESERVE:
+ *reserved += memory_info.RegionSize;
+ break;
+ case MEM_COMMIT:
+ *committed += memory_info.RegionSize;
+ break;
+ }
+ memory_info.BaseAddress = (char *) memory_info.BaseAddress + memory_info.RegionSize;
+ }
+}
+
+static int cpuinfo (int whole, unsigned long *kernel, unsigned long *user) {
+ if (whole) {
+ __int64 creation64, exit64, kernel64, user64;
+ int rc = GetProcessTimes (GetCurrentProcess (),
+ (FILETIME *) &creation64,
+ (FILETIME *) &exit64,
+ (FILETIME *) &kernel64,
+ (FILETIME *) &user64);
+ if (! rc) {
+ *kernel = 0;
+ *user = 0;
+ return FALSE;
+ }
+ *kernel = (unsigned long) (kernel64 / 10000);
+ *user = (unsigned long) (user64 / 10000);
+ return TRUE;
+ } else {
+ __int64 creation64, exit64, kernel64, user64;
+ int rc = GetThreadTimes (GetCurrentThread (),
+ (FILETIME *) &creation64,
+ (FILETIME *) &exit64,
+ (FILETIME *) &kernel64,
+ (FILETIME *) &user64);
+ if (! rc) {
+ *kernel = 0;
+ *user = 0;
+ return FALSE;
+ }
+ *kernel = (unsigned long) (kernel64 / 10000);
+ *user = (unsigned long) (user64 / 10000);
+ return TRUE;
+ }
+}
+
+#endif /* WIN32 */
+
+/* ------------------------------------------------------------
+History:
+
+ V2.7.0 Sun Mar 11 14:14:06 2001 Doug Lea (dl at gee)
+ * Introduce independent_comalloc and independent_calloc.
+ Thanks to Michael Pachos for motivation and help.
+ * Make optional .h file available
+ * Allow > 2GB requests on 32bit systems.
+ * new WIN32 sbrk, mmap, munmap, lock code from <Walter@GeNeSys-e.de>.
+ Thanks also to Andreas Mueller <a.mueller at paradatec.de>,
+ and Anonymous.
+ * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for
+ helping test this.)
+ * memalign: check alignment arg
+ * realloc: don't try to shift chunks backwards, since this
+ leads to more fragmentation in some programs and doesn't
+ seem to help in any others.
+ * Collect all cases in malloc requiring system memory into sYSMALLOc
+ * Use mmap as backup to sbrk
+ * Place all internal state in malloc_state
+ * Introduce fastbins (although similar to 2.5.1)
+ * Many minor tunings and cosmetic improvements
+ * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK
+ * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS
+ Thanks to Tony E. Bennett <tbennett@nvidia.com> and others.
+ * Include errno.h to support default failure action.
+
+ V2.6.6 Sun Dec 5 07:42:19 1999 Doug Lea (dl at gee)
+ * return null for negative arguments
+ * Added Several WIN32 cleanups from Martin C. Fong <mcfong at yahoo.com>
+ * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h'
+ (e.g. WIN32 platforms)
+ * Cleanup header file inclusion for WIN32 platforms
+ * Cleanup code to avoid Microsoft Visual C++ compiler complaints
+ * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing
+ memory allocation routines
+ * Set 'malloc_getpagesize' for WIN32 platforms (needs more work)
+ * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to
+ usage of 'assert' in non-WIN32 code
+ * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to
+ avoid infinite loop
+ * Always call 'fREe()' rather than 'free()'
+
+ V2.6.5 Wed Jun 17 15:57:31 1998 Doug Lea (dl at gee)
+ * Fixed ordering problem with boundary-stamping
+
+ V2.6.3 Sun May 19 08:17:58 1996 Doug Lea (dl at gee)
+ * Added pvalloc, as recommended by H.J. Liu
+ * Added 64bit pointer support mainly from Wolfram Gloger
+ * Added anonymously donated WIN32 sbrk emulation
+ * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen
+ * malloc_extend_top: fix mask error that caused wastage after
+ foreign sbrks
+ * Add linux mremap support code from HJ Liu
+
+ V2.6.2 Tue Dec 5 06:52:55 1995 Doug Lea (dl at gee)
+ * Integrated most documentation with the code.
+ * Add support for mmap, with help from
+ Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
+ * Use last_remainder in more cases.
+ * Pack bins using idea from colin@nyx10.cs.du.edu
+ * Use ordered bins instead of best-fit threshhold
+ * Eliminate block-local decls to simplify tracing and debugging.
+ * Support another case of realloc via move into top
+ * Fix error occuring when initial sbrk_base not word-aligned.
+ * Rely on page size for units instead of SBRK_UNIT to
+ avoid surprises about sbrk alignment conventions.
+ * Add mallinfo, mallopt. Thanks to Raymond Nijssen
+ (raymond@es.ele.tue.nl) for the suggestion.
+ * Add `pad' argument to malloc_trim and top_pad mallopt parameter.
+ * More precautions for cases where other routines call sbrk,
+ courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
+ * Added macros etc., allowing use in linux libc from
+ H.J. Lu (hjl@gnu.ai.mit.edu)
+ * Inverted this history list
+
+ V2.6.1 Sat Dec 2 14:10:57 1995 Doug Lea (dl at gee)
+ * Re-tuned and fixed to behave more nicely with V2.6.0 changes.
+ * Removed all preallocation code since under current scheme
+ the work required to undo bad preallocations exceeds
+ the work saved in good cases for most test programs.
+ * No longer use return list or unconsolidated bins since
+ no scheme using them consistently outperforms those that don't
+ given above changes.
+ * Use best fit for very large chunks to prevent some worst-cases.
+ * Added some support for debugging
+
+ V2.6.0 Sat Nov 4 07:05:23 1995 Doug Lea (dl at gee)
+ * Removed footers when chunks are in use. Thanks to
+ Paul Wilson (wilson@cs.texas.edu) for the suggestion.
+
+ V2.5.4 Wed Nov 1 07:54:51 1995 Doug Lea (dl at gee)
+ * Added malloc_trim, with help from Wolfram Gloger
+ (wmglo@Dent.MED.Uni-Muenchen.DE).
+
+ V2.5.3 Tue Apr 26 10:16:01 1994 Doug Lea (dl at g)
+
+ V2.5.2 Tue Apr 5 16:20:40 1994 Doug Lea (dl at g)
+ * realloc: try to expand in both directions
+ * malloc: swap order of clean-bin strategy;
+ * realloc: only conditionally expand backwards
+ * Try not to scavenge used bins
+ * Use bin counts as a guide to preallocation
+ * Occasionally bin return list chunks in first scan
+ * Add a few optimizations from colin@nyx10.cs.du.edu
+
+ V2.5.1 Sat Aug 14 15:40:43 1993 Doug Lea (dl at g)
+ * faster bin computation & slightly different binning
+ * merged all consolidations to one part of malloc proper
+ (eliminating old malloc_find_space & malloc_clean_bin)
+ * Scan 2 returns chunks (not just 1)
+ * Propagate failure in realloc if malloc returns 0
+ * Add stuff to allow compilation on non-ANSI compilers
+ from kpv@research.att.com
+
+ V2.5 Sat Aug 7 07:41:59 1993 Doug Lea (dl at g.oswego.edu)
+ * removed potential for odd address access in prev_chunk
+ * removed dependency on getpagesize.h
+ * misc cosmetics and a bit more internal documentation
+ * anticosmetics: mangled names in macros to evade debugger strangeness
+ * tested on sparc, hp-700, dec-mips, rs6000
+ with gcc & native cc (hp, dec only) allowing
+ Detlefs & Zorn comparison study (in SIGPLAN Notices.)
+
+ Trial version Fri Aug 28 13:14:29 1992 Doug Lea (dl at g.oswego.edu)
+ * Based loosely on libg++-1.2X malloc. (It retains some of the overall
+ structure of old version, but most details differ.)
+
+*/
diff --git a/libbanshee/engine/nonspec.c b/libbanshee/engine/nonspec.c
new file mode 100644
index 00000000000..96e0652d2cb
--- /dev/null
+++ b/libbanshee/engine/nonspec.c
@@ -0,0 +1,852 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include "banshee.h"
+#include "flowrow-sort.h"
+#include "flowrow-var.h"
+#include "setif-sort.h"
+#include "setif-var.h"
+#include "setst-sort.h"
+#include "setst-var.h"
+#include "term-sort.h"
+#include "term-var.h"
+
+struct constructor
+{
+ sort_kind sort;
+ int type;
+ int arity;
+ char *name;
+ sig_elt *sig;
+};
+
+typedef struct constructor *constructor;
+
+typedef enum
+{
+ vnc_pos,
+ vnc_neg,
+ vnc_non
+} vnc_kind;
+
+struct sig_elt
+{
+ vnc_kind variance;
+ sort_kind sort;
+};
+
+typedef struct sig_elt sig_elt;
+
+typedef struct proj_pat
+{
+ sort_kind sort;
+ int type;
+ stamp st;
+ int i;
+ gen_e exp;
+ vnc_kind variance;
+ constructor c;
+} *proj_pat;
+
+
+typedef struct cons_expr
+{
+ sort_kind sort;
+ int type;
+ stamp st;
+ int arity;
+ char *name;
+ sig_elt *sig;
+ gen_e *exps;
+} * cons_expr;
+
+
+static int new_type()
+{
+ static int type = 10;
+ int ret = type;
+ if (type > 2000)
+ {
+ fprintf(stderr, "Exceeded maximum number of constructors\n");
+ assert(0);
+ }
+ type += 2;
+ return ret;
+}
+
+static bool fixed_sort(sort_kind s)
+{
+ return !(s == sort_term || s == sort_set);
+}
+
+/*
+ Convention : constructor types are even, pats are odd.
+ The smallest specialized type is 10.
+*/
+static bool setif_is_pat(gen_e e)
+{
+ int type = ((setif_term)e)->type;
+ return ( (type & 1) && (type > 10) );
+}
+
+static bool setst_is_pat(gen_e e)
+{
+ int type = ((setst_term)e)->type;
+ return ( (type & 1) && (type > 10) );
+}
+
+static gen_e get_proj_var(sort_kind s, bool large)
+{
+ switch (s)
+ {
+ case setif_sort:
+ {
+ if (large)
+ return (gen_e)sv_fresh_large(get_sort_region(setif_sort),NULL);
+ else return (gen_e)sv_fresh(get_sort_region(setif_sort),NULL);
+ }
+ break;
+ case setst_sort:
+ {
+ if (large)
+ return (gen_e)st_fresh_large(get_sort_region(setst_sort),NULL);
+ else return (gen_e)st_fresh(get_sort_region(setst_sort),NULL);
+ }
+ break;
+ case flowrow_sort:
+ {
+ if (large)
+ return (gen_e)fv_fresh_large(get_sort_region(flowrow_sort),NULL);
+ else return (gen_e)fv_fresh(get_sort_region(flowrow_sort),NULL);
+ }
+ break;
+ case term_sort:
+ {
+ if (large)
+ return (gen_e)tv_fresh_large(get_sort_region(term_sort),NULL);
+ else return (gen_e)tv_fresh(get_sort_region(term_sort),NULL)
+ }
+ break;
+ default:
+ {
+ fail("Unmatched sort in get_proj_var\n");
+ return NULL;
+ }
+ break;
+ }
+
+ return NULL;
+}
+
+static gen_e get_sort_zero(sort_kind s)
+{
+switch (s)
+ {
+ case setif_sort:
+ return setif_zero();
+ case setst_sort:
+ return setst_zero();
+ case flowrow_sort:
+ return flowrow_zero();
+ case term_sort:
+ return term_zero();
+ default:
+ fail("Unmatched sort in get_sort_zero\n");
+ return NULL;
+ }
+ return NULL;
+}
+
+static gen_e get_sort_one(sort_kind s)
+{
+switch (s)
+ {
+ case setif_sort:
+ return setif_one();
+ case setst_sort:
+ return setst_one();
+ case flowrow_sort:
+ return flowrow_one();
+ case term_sort:
+ return term_one();
+ default:
+ fail("Unmatched sort in get_sort_zero\n");
+ return NULL;
+ }
+ return NULL;
+}
+
+static region get_sort_region(sort s)
+{
+ switch (s)
+ {
+ case setif_sort:
+ return setif_region;
+ case setst_sort:
+ return setst_region;
+ case flowrow_sort:
+ return flowrow_region;
+ case term_sort:
+ return term_region:
+ default:
+ fail("Unmatched sort in get_sort_region\n");
+ return NULL;
+ }
+ return NULL;
+}
+
+static term_hash get_sort_hash(sort s)
+{
+ switch (s)
+ {
+ case setif_sort:
+ return setif_hash;
+ case setst_sort:
+ return setst_hash;
+ case flowrow_sort:
+ return flowrow_hash;
+ case term_sort:
+ return term_hash:
+ default:
+ fail("Unmatched sort in get_sort_hash\n");
+ return NULL;
+ }
+ return NULL;
+}
+
+constructor make_constructor(const char *name,sort_kind sort, sig_elt s[],
+ int arity)
+{
+ constructor c = ralloc(expr_region,struct constructor);
+ sig_elt *sig = rarrayalloc(expr_region,arity,sig_elt);
+
+ c->type = new_type();
+
+ if (arity)
+ {
+ memcpy(sig,s,sizeof(sig_elt)*arity);
+ }
+
+ if ( fixed_sort(sort) )
+ failure("Specified sort does not allow constructor types\n");
+
+ c->sort = sort;
+ c->arity = arity;
+ c->name = rstrdup(expr_region,name);
+ c->sig = sig;
+
+ return c;
+}
+
+gen_e constructor_expr(constructor c, gen_e exps[], int arity)
+{
+ cons_expr result;
+ int i;
+ region sort_region = get_sort_region(c->sort);
+ term_hash sort_hash = get_sort_hash(c->sort);
+
+ stamp *st = rarrayalloc(sort_region,arity + 1,stamp);
+ st[0] = c->type;
+
+ // Dynamic arity check
+ if(arity != c->arity)
+ failure("Signature mismatch\n");
+
+ // Dynamic sort checks
+ for (i = 0; i < arity; i++)
+ {
+ if ( c->sig[i].sort != exps[i]->sort)
+ failure(stderr,"Signature mismatch\n");
+ st[i+1] = exps[i]->st;
+ }
+
+ // Hash-consing of terms
+ if (!(result = term_hash_find(sort_hash,st,arity+1)) || arity == 0 )
+ {
+ gen_e *e = rarrayalloc(sort_region,arity,gen_e);
+
+ if (arity)
+ memcpy(e,exps,sizeof(gen_e)*arity);
+ else
+ e = NULL;
+
+ result = ralloc(sort_region,struct cons_expr);
+ result->type = st[0];
+ result->st = stamp_fresh();
+ result->sort = c->sort;
+ result->arity = c->arity;
+ result->name = c->name;
+ result->sig = c->sig;
+ result->exps = e;
+
+ term_hash_insert(expr_hash,result,st,arity+1);
+ }
+
+ return (gen_e)result;
+}
+
+static gen_e proj_pat(constructor c, int i, gen_e e)
+{
+ proj_pat pat;
+ region sort_region = get_sort_region(e->sort);
+ term_hash sort_hash = get_sort_hash(e->sort);
+
+ stamp s[3];
+ s[0] = c->type + 1;
+ s[1] = e->st;
+ s[2] = i;
+
+ if (! (pat = term_hash_find(sort_hash,s,3)) )
+ {
+ pat = ralloc(sort_region,struct proj_pat);
+ pat->type = s[0];
+ pat->st = stamp_fresh();
+ pat->sort = c->sort;
+ pat->exp = e;
+ pat->variance = c->sig[i].variance;
+ pat->c = c;
+ pat->i = i;
+ term_hash_insert(sort_hash,pat,s,3);
+ }
+
+ return (gen_e)pat;
+}
+
+gen_e setif_proj_pat(constructor c,int i,gen_e e)
+{
+ return proj_pat(c,i,e);
+}
+
+gen_e setst_proj_pat(constructor c, int i, gen_e e)
+{
+ return proj_pat(c,i,e);
+}
+
+gen_e setif_proj(constructor c, int i, gen_e e)
+{
+ setif_var v;
+ gen_e proj_var, proj;
+
+ gen_e nonspec_get_proj(gen_e_list arg1)
+ {
+ proj_pat pat;
+ gen_e_list_scanner scan;
+ gen_e temp;
+
+ gen_e_list_scan(arg1,&scan);
+ while (gen_e_list_next(&scan,&temp))
+ {
+ pat = (proj_pat)temp;
+ if ( pat_match(pat->type,c->type) && i == pat->i )
+ return pat->exp;
+ }
+ return NULL;
+ }
+
+ if (e->sort != setif_sort)
+ {
+ failure("Sort check : setif_proj\n");
+ }
+
+ else if (i < 0 || i > c->arity)
+ {
+ failure("Signature mismatch\n");
+ }
+
+ else if (setif_is_zero(e))
+ return get_sort_zero(c->sig[i].sort);
+
+ else if ( ((setif_term)e)->type == c->type )
+ {
+ cons_expr constructed = (cons_expr)e;
+ return constructed->exps[i];
+ }
+
+ else if (setif_is_var(e))
+ {
+ v = (setif_var)e;
+ if ( (proj = sv_get_ub_proj(v,nonspec_get_proj)) )
+ {
+ return proj;
+ }
+ else
+ {
+ gen_e pat;
+ gen_e_list_scanner scan;
+ gen_e lb;
+ proj_var = get_proj_var(c->sig[i].sort,FALSE);
+ pat = setif_proj_pat(c,i,proj_var);
+ sv_add_ub_proj(sort_region,v,pat);
+
+ gen_e_list_scan(sv_get_lbs(v),&scan);
+ while (gen_e_list_next(&scan,&lb))
+ {
+ setif_inclusion(lb,pat);
+ }
+ return proj_var;
+ }
+ }
+
+ else if (setif_is_union(e))
+ {
+ if( (proj = nonspec_get_proj(setif_get_proj_cache(e))) )
+ return proj;
+ else
+ {
+ gen_e pat;
+ proj_var = get_proj_var(c->sig[i].sort,FALSE);
+ pat = setif_proj_pat(c,i,proj_var);
+
+ setif_set_proj_cache(e,pat);
+
+ setif_inclusion(e,pat);
+ return proj_var;
+ }
+ }
+ else
+ {
+ gen_e pat;
+ proj_var = get_proj_var(c->sig[i].sort,FALSE);
+ pat = setif_proj_pat(c,i,proj_var);
+ setif_inclusion(e,pat);
+ return proj_var;
+ }
+}
+
+gen_e setst_proj(constructor c, int i, gen_e e)
+{
+ setst_var v;
+ gen_e proj_var, proj;
+
+ gen_e nonspec_get_proj(gen_e_list arg1)
+ {
+ proj_pat pat;
+ gen_e_list_scanner scan;
+ gen_e temp;
+
+ gen_e_list_scan(arg1,&scan);
+ while (gen_e_list_next(&scan,&temp))
+ {
+ pat = (proj_pat)temp;
+ if ( pat_match(pat->type,c->type) && i == pat->i )
+ return pat->exp;
+ }
+ return NULL;
+ }
+
+ if (e->sort != setst_sort)
+ {
+ failure("Sort check : setst_proj\n");
+ }
+
+ else if (i < 0 || i > c->arity)
+ {
+ failure("Signature mismatch\n");
+ }
+
+ else if (setst_is_zero(e))
+ return get_sort_zero(c->sig[i].sort);
+
+ else if ( ((setst_term)e)->type == c->type )
+ {
+ cons_expr constructed = (cons_expr)e;
+ return constructed->exps[i];
+ }
+
+ else if (setst_is_var(e))
+ {
+ v = (setst_var)e;
+ if ( (proj = sv_get_ub_proj(v,nonspec_get_proj)) )
+ {
+ return proj;
+ }
+ else
+ {
+ gen_e pat;
+ gen_e_list_scanner scan;
+ gen_e lb;
+ proj_var = get_proj_var(c->sig[i].sort,FALSE);
+ pat = setst_proj_pat(c,i,proj_var);
+ sv_add_ub_proj(sort_region,v,pat);
+
+ gen_e_list_scan(sv_get_lbs(v),&scan);
+ while (gen_e_list_next(&scan,&lb))
+ {
+ setst_inclusion(lb,pat);
+ }
+ return proj_var;
+ }
+ }
+
+ else if (setst_is_union(e))
+ {
+ if( (proj = nonspec_get_proj(setst_get_proj_cache(e))) )
+ return proj;
+ else
+ {
+ gen_e pat;
+ proj_var = get_proj_var(c->sig[i].sort,FALSE);
+ pat = setst_proj_pat(c,i,proj_var);
+
+ setst_set_proj_cache(e,pat);
+
+ setst_inclusion(e,pat);
+ return proj_var;
+ }
+ }
+ else
+ {
+ gen_e pat;
+ proj_var = get_proj_var(c->sig[i].sort,FALSE);
+ pat = setst_proj_pat(c,i,proj_var);
+ setst_inclusion(e,pat);
+ return proj_var;
+ }
+}
+
+static void setif_con_match(gen_e e1, gen_e e2)
+{
+ // Case where e1 is a constructor expression and e2 is a proj_pat
+ if (pat_match(((setif_term)e2)->type,((setif_term)e1)->type))
+ {
+ cons_expr c = (cons_expr)e1;
+ proj_pat p = (proj_pat)e2;
+ int i = p->i;
+
+ if (c->sig[i].variance == vnc_pos)
+ call_inclusion_fn(c->exps[i],p->exp);
+ else if (c->sig[i].variance == vnc_neg)
+ call_inclusion_fn(p->exp,c->exps[i]);
+ else
+ call_unify_fn(c->exps[i],p->exp);
+ }
+ else if (setif_is_pat(e2))
+ {
+ return;
+ }
+
+ // Case where e1 and e2 are constructor expressions
+ else
+ {
+ cons_expr c1 = (cons_expr)e1,
+ c2 = (cons_expr)e2;
+
+ if (c1->type != c2->type)
+ failure("Constructor mismatch\n");
+ else
+ {
+ int i;
+ for (i = 0; i < c1->arity; i++)
+ {
+ if (c1->sig[i].variance == vnc_pos)
+ call_inclusion_fn(e1,e2);
+ else if (c1->sig[i].variance == vnc_neg)
+ call_inclusion_fn(e2,e1);
+ else
+ call_unify_fn(e1,e2);
+ }
+
+ }
+ }
+}
+
+static void setst_con_match(gen_e e1, gen_e e2)
+{
+ // Case where e1 is a constructor expression and e2 is a proj_pat
+ if (pat_match(((setst_term)e2)->type,((setst_term)e1)->type))
+ {
+ cons_expr c = (cons_expr)e1;
+ proj_pat p = (proj_pat)e2;
+ int i = p->i;
+
+ if (c->sig[i].variance == vnc_pos)
+ call_inclusion_fn(c->exps[i],p->exp);
+ else if (c->sig[i].variance == vnc_neg)
+ call_inclusion_fn(p->exp,c->exps[i]);
+ else
+ call_unify_fn(c->exps[i],p->exp);
+ }
+ else if (setst_is_pat(e2))
+ {
+ return;
+ }
+
+ // Case where e1 and e2 are constructor expressions
+ else
+ {
+ cons_expr c1 = (cons_expr)e1,
+ c2 = (cons_expr)e2;
+
+ if (c1->type != c2->type)
+ failure("Constructor mismatch\n");
+ else
+ {
+ int i;
+ for (i = 0; i < c1->arity; i++)
+ {
+ if (c1->sig[i].variance == vnc_pos)
+ call_inclusion_fn(e1,e2);
+ else if (c1->sig[i].variance == vnc_neg)
+ call_inclusion_fn(e2,e1);
+ else
+ call_unify_fn(e1,e2);
+ }
+
+ }
+ }
+}
+
+// given x <= proj(c,i,e)
+// proj_merge(region,e,get_proj_i_arg,fresh_large_fn_ptr,
+// sort_inclusion_fn_ptr,set_inclusion)
+static bool nonspec_res_proj(set_var v1,gen_e e2)
+{
+ proj_pat projection_pat = (proj_pat)e2;
+
+ gen_e setif_get_proj(gen_e_list arg1)
+ {
+ gen_e_list_scanner scan;
+ gen_e temp;
+ proj_pat pat;
+
+ gen_e_list_scan(arg1,&scan);
+ while(gen_e_list_next(&scan,&temp))
+ {
+ pat = (proj_pat)temp;
+ if ( pat->type == ((setif_term)e2)->type &&
+ pat->i == ((proj_pat)e2)->i)
+ return pat->exp;
+ }
+ return NULL;
+ }
+
+ gen_e fresh_large(void)
+ {
+ return get_proj_var( ((proj_pat)e2)->exp->sort,TRUE);
+ }
+
+ bool sort_inclusion(gen_e e1, gen_e e2)
+ {
+ if ( projection_pat->variance == vnc_pos )
+ return call_inclusion_fn(e1,e2);
+ else if ( projection_pat->variance == vnc_neg)
+ return call_inclusion_fn(e2,e1);
+ else
+ return call_unify_fn(e1,e2);
+ }
+
+ gen_e proj_con(gen_e e)
+ {
+ return make_proj_pat( ((proj_pat)e2)->c, ((proj_pat)e2)->i,e);
+ }
+
+ return setif_proj_merge(setif_region,v1,((proj_pat)e2)->exp,
+ setif_get_proj,proj_con,
+ fresh_large,sort_inclusion,
+ call_setif_inclusion);
+
+}
+
+
+void call_setif_inclusion(gen_e e1,gen_e e2)
+{
+ setif_inclusion(setif_con_match,setif_res_proj,e1,e2);
+}
+
+void call_setif_unify(gen_e e1, gen_e e2)
+{
+ setif_inclusion(setif_con_match,setif_res_proj,e1,e2);
+ setif_inclusion(setif_con_match,setif_res_proj,e2,e1);
+}
+
+void call_setst_inclusion(gen_e e1, gen_e e2)
+{
+ setst_inclusion(setst_con_match,e1,e2);
+}
+
+void call_setst_unify(gen_e e1, gen_e e2)
+{
+ setst_inclusion(setst_con_match,e1,e2);
+ setst_inclusion(setst_con_match,e2,e1);
+}
+
+void call_flowrow_inclusion(gen_e e1,gen_e e2)
+{
+
+ if ( (e1->sort != flowrow_sort) || (e2->sort != flowrow_sort) )
+ failure("Constraint system is not well-sorted\n");
+
+ if ( flowrow_base_sort(e1) != flowrow_base_sert(e2))
+ failure("Constraint system is not well-sorted\n");
+
+
+ flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,e1,e2);
+}
+
+void call_flowrow_unify(gen_e e1, gen_e e2)
+{
+ flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,e1,e2);
+ flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,e2,e1);
+}
+
+static void term_con_match(gen_e e1, gen_e e2)
+{
+ cons_expr c1 = (cons_expr)e1,
+ c2 = (cons_expr)e2;
+
+ if (c1->type != c2->type)
+ failure("Constructor mismatch\n");
+ else
+ {
+ int i;
+ for (i = 0; i < c1->arity; i++)
+ {
+ call_unify_fn(e1,e2);
+ }
+
+ }
+}
+
+static void term_occurs(term_var v, gen_e e)
+{
+ gen_e ecr = term_get_ecr(e);
+
+ if (((gen_term)ecr)->type == VAR_TYPE)
+ return ( term_get_stamp((gen_e)v) == term_get_stamp(e) );
+
+ else if (((gen_term)ecr)->type >= 10)
+ {
+ cons_expr c_e = (cons_expr) e;
+ int i;
+ for (int i = 0; i < arity; i++)
+ {
+ if (term_occurs(v,c->exps[i]))
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+void call_term_unify(gen_e e1, gen_e e2)
+{
+ term_unify(term_con_match,term_occurs,e1,e2);
+}
+
+void call_term_cunify(gen_e e1, gen_e e2)
+{
+ term_cunify(term_con_match,term_occurs,e1,e2);
+}
+
+
+static void call_inclusion_fn(gen_e e1, gen_e e2)
+{
+ switch (e1->sort)
+ {
+ case sort_setif:
+ {
+ setif_inclusion(setif_con_match,setif_res_proj,e1,e2);
+ }
+ break;
+ case sort_setst:
+ {
+ setst_inclusion(setst_con_match,e1,e2);
+ }
+ break;
+ case sort_term:
+ {
+ term_unify(term_con_match,term_occurs,e1,e2);
+ }
+ break;
+ case sort_row:
+ {
+ /* TODO */
+ flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,e1,e2);
+ }
+ break;
+ default :
+ fail("Unmatched sort in call inclusion\n");
+ }
+}
+
+static bool call_unify_fn(gen_e e1, gen_e e2)
+{
+
+ switch (e1->sort)
+ {
+ case sort_setif:
+ {
+ setif_inclusion(setif_con_match,setif_res_proj,e1,e2);
+ setif_inclusion(setif_con_match,setif_res_proj,e2,e1);
+ }
+ break;
+ case sort_setst:
+ {
+ setst_inclusion(setst_con_match,e1,e2);
+ setst_inclusion(setst_con_match,e2,e1);
+ }
+ break;
+ case sort_term:
+ {
+ term_unify(term_con_match,term_occurs,e1,e2);
+ }
+ break;
+ case sort_row:
+ {
+ /* TODO */
+ flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,e1,e2);
+ flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,e2,e1);
+ }
+ break;
+ default :
+ fail("Unmatched sort in call inclusion\n");
+ }
+}
+
+void nonspec_init(void)
+{
+ banshee_init();
+ setif_init();
+ setst_init();
+ flowrow_init();
+}
+
+void nonspec_reset(void)
+{
+ flowrow_reset();
+ setst_reset();
+ setif_reset();
+ banshee_reset();
+}
+
+void expr_print(FILE *f,gen_e e)
+{
+
+}
diff --git a/libbanshee/engine/nonspec.h b/libbanshee/engine/nonspec.h
new file mode 100644
index 00000000000..bfa3b9d8b90
--- /dev/null
+++ b/libbanshee/engine/nonspec.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef NONSPEC_H
+#define NONSPEC_H
+
+#include <stdio.h>
+
+EXTERN_C_BEGIN
+
+typedef enum
+{
+ vnc_pos,
+ vnc_neg,
+ vnc_non
+} vnc_kind;
+
+struct sig_elt
+{
+ vnc_kind variance;
+ sort_kind sort;
+};
+
+typedef struct sig_elt sig_elt;
+typedef struct constructor *constructor;
+
+struct flowrow_field
+{
+ char *label;
+ gen_e expr;
+};
+
+DECLARE_LIST(flowrow_map,flowrow_field)
+
+/*
+ Flags
+*/
+extern bool flag_merge_projections;
+extern bool flag_eliminate_cycles;
+extern bool flag_occurs_check;
+
+/*
+ Operations for building terms
+*/
+
+/* Defines a new constructor for sort s with the given signature */
+constructor make_constructor(const char *name,sort_kind sort, sig_elt[],
+ int arity);
+
+/* Build the term c(exps[0]....exps[n]) */
+gen_e constructor_expr(constructor c, gen_e exps[], int arity);
+
+/* make a constant of sort s */
+gen_e setif_constant(const char *name);
+
+gen_e setst_constant(const char *name);
+
+gen_e term_constant(const char *name);
+
+/* Creates a projection pattern projpat(c,i,e) */
+gen_e setif_proj_pat(constructor c,int i,gen_e e);
+
+gen_e setst_proj_pat(constructor c, int i, gen_e e);
+
+/* Adds a constraint e <= projpat(c,i,fv) where fv is a fresh variable */
+gen_e setif_proj(constructor c, int i, gen_e e);
+
+gen_e setst_proj(constructor c, int i, gen_e e);
+
+/* Make a new variable of sort s */
+gen_e setif_fresh(const char *name);
+
+gen_e term_fresh(const char *name);
+
+gen_e flowrow_fresh(const char *name);
+
+gen_e setst_fresh(const char *name);
+
+/* Operations for unions */
+
+gen_e setif_union(gen_e exps[]);
+
+gen_e setif_inter(gen_e exps[]);
+
+gen_e setst_union(gen_e exps[]);
+
+gen_e setst_inter(gen_e exps[]);
+
+/* Empty set of sort s */
+gen_e setif_zero(void);
+
+gen_e setst_zero(void);
+
+gen_e flowrow_zero(sort_kind base_sort);
+
+gen_e term_zero(void);
+
+/* Universal set of sort s */
+gen_e setif_one(void);
+
+gen_e setst_one(void);
+
+gen_e flowrow_one(sort_kind base_sort);
+
+gen_e term_one(void);
+
+/*
+ Operations for building flowrows
+*/
+
+/* Closed flowrow of base sort s */
+gen_e flowrow_abs(sort_kind base_sort);
+
+/* Wild flowrow of base sort s */
+gen_e flowrow_wild(sort_kind base_sort);
+
+/* Build a flowrow of <l : e>_fields o <rest> */
+gen_e flowrow_row(flowrow_map fields, gen_e rest);
+
+/*
+ Inclusion functions
+*/
+void call_setif_inclusion(gen_e e1,gen_e e2);
+void call_setif_unify(gen_e e1, gen_e e2);
+
+void call_setst_inclusion(gen_e e1, gen_e e2);
+void call_setst_unify(gen_e e1, gen_e e2);
+
+void call_flowrow_inclusion(gen_e e1,gen_e e2);
+void call_flowrow_unify(gen_e e1, gen_e e2);
+
+void call_term_unify(gen_e e1, gen_e e2);
+void call_term_cunify(gen_e e1, gen_e e2);
+
+/*
+ Extracting solutions
+ */
+struct decon
+{
+ int arity;
+ gen_e[1];
+};
+struct decon deconstruct_expr(constructor c,gen_e e);
+
+gen_e_list setif_tlb(gen_e e);
+
+gen_e_list setst_tlb(gen_e e);
+
+gen_e term_get_ecr(gen_e e);
+
+gen_e flowrow_extract_field(const char *label,gen_e row);
+flowrow_map flowrow_extract_fields(gen_e row);
+gen_e flowrow_extract_rest(gen_e row);
+
+void nonspec_init(void);
+void nonspec_reset(void);
+
+void expr_print(FILE *f,gen_e e);
+
+EXTERN_C_END
+
+#endif /* NONSPEC_H */
diff --git a/libbanshee/engine/setif-sort.c b/libbanshee/engine/setif-sort.c
new file mode 100644
index 00000000000..0350018dfcd
--- /dev/null
+++ b/libbanshee/engine/setif-sort.c
@@ -0,0 +1,1141 @@
+/*
+ * Copyright (c) 2000-2004
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <assert.h>
+#include <setjmp.h>
+#include "regions.h"
+#include "bounds.h"
+#include "jcollection.h"
+#include "setif-sort.h"
+#include "util.h"
+
+bool flag_eliminate_cycles = TRUE;
+bool flag_merge_projections = TRUE;
+
+struct setif_union_ /* extends gen_e */
+{
+#ifdef NONSPEC
+ sort_kind sort;
+#endif
+ int type;
+ stamp st;
+ gen_e_list exprs;
+ gen_e_list proj_cache;
+};
+
+struct setif_inter_ /* extends gen_e */
+{
+#ifdef NONSPEC
+ sort_kind sort;
+#endif
+ int type;
+ stamp st;
+ gen_e_list exprs;
+};
+
+struct setif_constant_ /* extends gen_e */
+{
+#ifdef NONSPEC
+ sort_kind sort;
+#endif
+ int type;
+ stamp st;
+ char *name;
+};
+
+typedef struct setif_inter_ *setif_inter_;
+typedef struct setif_union_ *setif_union_;
+typedef struct setif_constant_ *setif_constant_;
+
+static setif_var_list setif_vars;
+static region tlb_cache_region;
+static setif_var_list tlb_var_cache;
+static jcoll_dict tlb_dict;
+
+
+region setif_region;
+term_hash setif_hash;
+struct setif_stats setif_stats;
+
+stamp setif_get_stamp(gen_e e)
+{
+#ifdef NONSPEC
+ assert(e->sort == setif_sort);
+#endif
+
+ if ( ((setif_term)e)->type == VAR_TYPE)
+ return sv_get_stamp( (setif_var)e );
+
+ else
+ return ((setif_term)e)->st;
+}
+
+static void tlv_lower_aux(jmp_buf buf,stamp st, gen_e e)
+{
+ if ( setif_is_var(e) && (setif_get_stamp(e) > st) )
+ longjmp(buf,1);
+
+ else if (setif_is_union(e))
+ {
+ gen_e temp;
+ gen_e_list exprs = ((setif_union_)e)->exprs;
+ gen_e_list_scanner scan;
+
+ gen_e_list_scan(exprs,&scan);
+ while (gen_e_list_next(&scan,&temp))
+ tlv_lower_aux(buf,st,temp);
+ }
+}
+
+static bool tlv_lower(stamp st, gen_e e)
+{
+ jmp_buf buf;
+ int higher;
+
+ higher = setjmp(buf);
+ if (higher)
+ return FALSE;
+
+ tlv_lower_aux(buf,st,e);
+
+ return TRUE;
+}
+
+static void invalidate_tlb_cache(void) deletes
+{
+ assert(tlb_cache_region);
+
+ setif_var_list_app(tlb_var_cache,sv_clear_tlb_cache);
+ jcoll_delete_dict(tlb_dict);
+ deleteregion_ptr(&tlb_cache_region);
+
+ tlb_cache_region = newregion();
+ tlb_dict = jcoll_create_dict(tlb_cache_region,setif_get_stamp);
+ tlb_var_cache = new_setif_var_list(tlb_cache_region);
+}
+
+static void set_tlb_cache(setif_var v, jcoll j)
+{
+ setif_var_list_cons(v,tlb_var_cache);
+ sv_set_tlb_cache(v,j);
+}
+
+/*
+ A constraint e1 <= e2 is l-inductive iff e2 is a variable x and
+ for each y in tlv(e1), stamp(y) < stamp(x)
+*/
+static bool l_inductive(gen_e e1, gen_e e2)
+{
+ if (setif_is_var(e2) && tlv_lower(setif_get_stamp(e2), e1))
+ return TRUE;
+
+ else return FALSE;
+}
+
+/*
+ A constraint e1 <= e2 is r-inductive iff e1 is a variable x and
+ for each y in tlv(e2), stamp(y) < stamp(x)
+*/
+static bool r_inductive(gen_e e1, gen_e e2)
+{
+ if (setif_is_var(e1) && tlv_lower(setif_get_stamp(e1), e2))
+ return TRUE;
+
+ else return FALSE;
+}
+
+static bool eq(gen_e e1, gen_e e2)
+{
+ return ( setif_get_stamp(e1) == setif_get_stamp(e2) );
+}
+
+gen_e_list setif_get_union(gen_e e)
+{
+ assert ( ((setif_term)e)->type == UNION_TYPE);
+
+ return ( (setif_union_) e)->exprs;
+}
+
+gen_e_list setif_get_inter(gen_e e)
+{
+ assert ( ((setif_term)e)->type == INTER_TYPE);
+
+ return ( (setif_inter_) e)->exprs;
+}
+
+static setif_var_list search_ubs(region r, setif_var v1, setif_var goal)
+{
+ bool found = FALSE;
+ setif_var_list cycle;
+
+ static void search_ubs_aux(setif_var v)
+ {
+ assert(! found);
+
+ if (sv_eq (v, goal))
+ {
+ found = TRUE;
+ return;
+ }
+ else if (sv_lt(v,goal))
+ {
+ return;
+ }
+ else
+ {
+ gen_e_list_scanner scan;
+ gen_e ub;
+ gen_e_list ubs = sv_get_ubs(v);
+
+ gen_e_list_scan(ubs,&scan);
+ while (gen_e_list_next(&scan,&ub))
+ {
+ if (setif_is_var(ub))
+ {
+ search_ubs_aux((setif_var)ub);
+ if (found)
+ {
+ setif_var_list_cons(v,cycle);
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ found = FALSE;
+ cycle = new_setif_var_list(r);
+ search_ubs_aux(v1);
+
+ return cycle;
+}
+
+static setif_var_list search_lbs(region r, setif_var v1, setif_var goal)
+{
+ bool found;
+ setif_var_list cycle;
+
+ static void search_lbs_aux(setif_var v)
+ {
+ assert (! found);
+ if (sv_eq(v,goal))
+ {
+ found = TRUE;
+ return;
+ }
+ else if (sv_lt(v,goal))
+ {
+ return;
+ }
+ else
+ {
+ gen_e_list_scanner scan;
+ gen_e lb;
+ gen_e_list lbs = sv_get_lbs(v);
+
+ gen_e_list_scan(lbs,&scan);
+ while (gen_e_list_next(&scan,&lb))
+ {
+ if (setif_is_var(lb))
+ {
+ search_lbs_aux((setif_var)lb);
+ if (found)
+ {
+ setif_var_list_cons(v,cycle);
+ return;
+ }
+ }
+ }
+ }
+
+ }
+
+ found = FALSE;
+ cycle = new_setif_var_list(r);
+ search_lbs_aux(v1);
+
+ return cycle;
+}
+
+static setif_var_list cycle_detect(region r,setif_var v1,setif_var v2)
+{
+ if (sv_union_component(v1,v2))
+ return new_setif_var_list(r);
+
+ else
+ {
+ setif_stats.cycles_searched_forward++;
+ return search_ubs(r, v2, v1);
+ }
+}
+
+
+static setif_var_list cycle_detect_rev(region r, setif_var v1, setif_var v2)
+{
+ if (sv_union_component(v1,v2))
+ return new_setif_var_list(r);
+
+ else
+ {
+ setif_stats.cycles_searched_backward++;
+ return search_lbs(r, v1, v2);
+ }
+}
+
+void setif_inclusion(con_match_fn_ptr con_match, res_proj_fn_ptr res_proj,
+ gen_e e1, gen_e e2) deletes
+{
+
+ static void collapse_cycle_lower(region r, setif_var witness,
+ setif_var_list cycle) deletes
+ {
+ gen_e lb;
+ gen_e_list_scanner scan_bounds;
+ setif_var_list_scanner scan_cycle;
+ setif_var var;
+
+#ifndef NDEBUG
+ stamp lowest = sv_get_stamp(witness);
+#endif
+ bounds b = bounds_create(r);
+
+ /* Collect all lower bounds in the cycle, and add transitive edges */
+ setif_var_list_scan(cycle,&scan_cycle);
+ while(setif_var_list_next(&scan_cycle,&var))
+ {
+ assert( sv_get_stamp(var) > lowest);
+ gen_e_list_scan(sv_get_lbs(var),&scan_bounds);
+ while(gen_e_list_next(&scan_bounds,&lb))
+ bounds_add(b,lb,setif_get_stamp(lb));
+ }
+
+ sv_unify(witness,cycle);
+ assert(sv_get_stamp(witness) == lowest);
+
+ gen_e_list_scan(bounds_exprs(b),&scan_bounds);
+ while (gen_e_list_next(&scan_bounds,&lb))
+ setif_inclusion(con_match,res_proj,lb, (gen_e) witness);
+
+ bounds_delete(b);
+ invalidate_tlb_cache();
+
+ setif_stats.cycles_collapsed_backward++;
+ setif_stats.cycles_length_backward += setif_var_list_length(cycle);
+ }
+
+ static void collapse_cycle_upper(region r, setif_var witness,
+ setif_var_list cycle) deletes
+ {
+ gen_e ub;
+ gen_e_list_scanner scan_bounds;
+ setif_var_list_scanner scan_cycle;
+ setif_var var;
+
+#ifndef NDEBUG
+ stamp lowest = sv_get_stamp(witness);
+#endif
+ bounds b = bounds_create(r);
+
+ /* Collect all upper bounds in the cycle, and add transitive edges */
+ setif_var_list_scan(cycle,&scan_cycle);
+ while(setif_var_list_next(&scan_cycle,&var))
+ {
+ assert( sv_get_stamp(var) > lowest);
+
+ gen_e_list_scan(sv_get_ubs(var),&scan_bounds);
+ while(gen_e_list_next(&scan_bounds,&ub))
+ bounds_add(b,ub,setif_get_stamp(ub));
+
+ gen_e_list_scan(sv_get_ub_projs(var),&scan_bounds);
+ while(gen_e_list_next(&scan_bounds,&ub))
+ bounds_add(b,ub,setif_get_stamp(ub));
+ }
+
+ sv_unify(witness,cycle);
+ assert(sv_get_stamp(witness) == lowest);
+
+ gen_e_list_scan(bounds_exprs(b),&scan_bounds);
+ while (gen_e_list_next(&scan_bounds,&ub))
+ setif_inclusion(con_match,res_proj,(gen_e) witness, ub);
+
+ bounds_delete(b);
+ invalidate_tlb_cache();
+
+ setif_stats.cycles_collapsed_forward++;
+ setif_stats.cycles_length_backward += setif_var_list_length(cycle);
+ }
+
+ static void update_lower_bound(setif_var v, gen_e e) deletes
+ {
+ if (sv_add_lb(v,e,setif_get_stamp(e)))
+ {
+ if (setif_is_var(e))
+ setif_stats.redundant_succ++;
+
+ else
+ setif_stats.redundant_source++;
+ }
+
+ else
+ {
+ gen_e_list_scanner scan;
+ gen_e ub;
+
+ if (setif_is_var(e))
+ setif_stats.added_succ++;
+ else
+ setif_stats.added_source++;
+
+ invalidate_tlb_cache();
+
+ gen_e_list_scan(sv_get_ubs(v),&scan);
+ while(gen_e_list_next(&scan,&ub))
+ setif_inclusion(con_match,res_proj,e,ub);
+
+ gen_e_list_scan(sv_get_ub_projs(v),&scan);
+ while (gen_e_list_next(&scan,&ub))
+ setif_inclusion(con_match,res_proj,e,ub);
+
+ }
+
+ }
+
+ static void update_upper_bound(setif_var v, gen_e e) deletes
+ {
+ if (sv_add_ub(v,e,setif_get_stamp(e)))
+ {
+ if (setif_is_var(e))
+ setif_stats.redundant_pred++;
+
+ else
+ setif_stats.redundant_sink++;
+ }
+
+ else
+ {
+ gen_e_list_scanner scan;
+ gen_e lb;
+
+ if (setif_is_var(e))
+ setif_stats.added_pred++;
+ else
+ setif_stats.added_sink++;
+
+ invalidate_tlb_cache();
+
+ gen_e_list_scan(sv_get_lbs(v),&scan);
+ while (gen_e_list_next(&scan,&lb))
+ setif_inclusion(con_match,res_proj,lb,e);
+
+ }
+
+ }
+
+
+ if (eq(e1,e2))
+ return;
+
+ else if ( setif_is_zero(e1) || setif_is_one(e2) )
+ return;
+
+ /* c <= d */
+ else if ( setif_is_constant(e1) && setif_is_constant(e2) )
+ {
+
+ failure("Inconsistent system of constraints\n");
+ return;
+ }
+
+ else if ( setif_is_union(e1) )
+ {
+ gen_e_list_scanner scan;
+ gen_e temp;
+
+ gen_e_list exprs = setif_get_union(e1);
+
+ gen_e_list_scan(exprs,&scan);
+ while (gen_e_list_next(&scan,&temp))
+ {
+ setif_inclusion(con_match,res_proj,temp,e2);
+ }
+
+ return;
+ }
+
+ else if ( setif_is_inter(e2) )
+ {
+ gen_e_list_scanner scan;
+ gen_e temp;
+
+ gen_e_list exprs = setif_get_inter(e2);
+
+ gen_e_list_scan(exprs,&scan);
+ while (gen_e_list_next(&scan,&temp))
+ {
+ setif_inclusion(con_match,res_proj,e1,temp);
+ }
+
+ return;
+ }
+
+ else if ( l_inductive(e1,e2) ) /* _ <= 'x */
+ {
+ setif_var v2 = ((setif_var)e2);
+
+ if (setif_is_var(e1))
+ {
+ setif_var v1 = ((setif_var)e1);
+
+ if (flag_eliminate_cycles)
+ {
+ region scratch = newregion();
+ setif_var_list cycle = cycle_detect(scratch,v1,v2);
+
+ if (! setif_var_list_empty(cycle))
+ collapse_cycle_upper(scratch,v1,cycle);
+ else
+ update_lower_bound(v2,e1);
+
+ deleteregion(scratch);
+ }
+
+ else
+ update_lower_bound(v2,e1);
+ }
+ else /* e1 is a source */
+ update_lower_bound(v2,e1);
+ }
+
+ else if ( r_inductive(e1,e2) ) /* 'x <= _ */
+ {
+ setif_var v1 = ((setif_var)e1);
+
+ if (setif_is_var(e2))
+ {
+ setif_var v2 = ((setif_var)e2);
+
+ if (flag_eliminate_cycles)
+ {
+ region scratch = newregion();
+ setif_var_list cycle = cycle_detect_rev(scratch,v1,v2);
+
+ if (! setif_var_list_empty(cycle))
+ collapse_cycle_lower(scratch,v2,cycle);
+ else
+ update_upper_bound(v1,e2);
+
+ deleteregion(scratch);
+ }
+
+ else
+ update_upper_bound(v1,e2);
+ }
+ else /* e2 is a sink */
+ {
+ if (flag_merge_projections && res_proj(v1,e2))
+ return;
+ else
+ update_upper_bound(v1,e2);
+ }
+ }
+
+ else /* c(...) <= c(...) or c(...) <= projpat(c,i,e) */
+ {
+ con_match(e1,e2);
+ return;
+ }
+
+}
+
+#ifdef NONSPEC
+static struct setif_term zero = {setif_sort,ZERO_TYPE,ZERO_TYPE};
+static struct setif_term one = {setif_sort,ONE_TYPE,ONE_TYPE};
+#else
+static struct setif_term zero = {ZERO_TYPE,ZERO_TYPE};
+static struct setif_term one = {ONE_TYPE,ONE_TYPE};
+#endif /* NONSPEC */
+
+gen_e setif_zero(void)
+{
+ return (gen_e)&zero;
+}
+
+gen_e setif_one(void)
+{
+ return (gen_e)&one;
+}
+
+gen_e setif_fresh(const char *name)
+{
+ setif_var result = sv_fresh(setif_region,name);
+ setif_var_list_cons(result,setif_vars);
+
+ setif_stats.fresh++;
+ return (gen_e)result;
+}
+
+gen_e setif_fresh_large(const char *name)
+{
+ setif_var result = sv_fresh_large(setif_region,name);
+ setif_var_list_cons(result,setif_vars);
+
+ setif_stats.fresh_large++;
+ return (gen_e)result;
+}
+
+gen_e setif_fresh_small(const char *name)
+{
+ setif_var result = sv_fresh_small(setif_region,name);
+ setif_var_list_cons(result,setif_vars);
+
+ setif_stats.fresh_small++;
+ return (gen_e)result;
+}
+
+gen_e setif_constant(const char *str) deletes
+{
+ stamp st[2];
+ gen_e result;
+ char *name = rstrdup(setif_region,str);
+
+ assert (str != NULL);
+
+ st[0] = CONSTANT_TYPE;
+ st[1] = stamp_string(name);
+
+ if ( (result = term_hash_find(setif_hash,st,2)) == NULL)
+ {
+ setif_constant_ c = ralloc(setif_region, struct setif_constant_);
+#ifdef NONSPEC
+ c->sort = setif_sort;
+#endif
+ c->type = CONSTANT_TYPE;
+ c->st = stamp_fresh();
+ c->name = name;
+
+ result = (gen_e) c;
+ term_hash_insert(setif_hash,result,st,2);
+
+ setif_stats.distinct_constants++;
+
+ return result;
+ }
+
+ else
+ {
+ setif_stats.hashed_constants++;
+ return result;
+ }
+}
+
+static bool filter_zero(const gen_e e)
+{
+ return (!setif_is_zero(e));
+}
+
+
+static bool filter_one(const gen_e e)
+{
+ return (!setif_is_one(e));
+}
+
+gen_e setif_union(gen_e_list exprs) deletes
+{
+ gen_e_list filtered = gen_e_list_filter(setif_region,exprs,filter_zero);
+
+ if ( gen_e_list_empty(filtered) )
+ {
+ setif_stats.filtered_unions++;
+ return setif_zero();
+ }
+ else if (gen_e_list_length(filtered) == 1)
+ {
+ setif_stats.filtered_unions++;
+ return gen_e_list_head(filtered);
+ }
+
+ else
+ {
+ int i = 0;
+ gen_e temp,result;
+ gen_e_list_scanner scan;
+ stamp st[ gen_e_list_length(filtered) + 1 ];
+
+ st[0] = UNION_TYPE;
+
+ gen_e_list_scan(filtered,&scan);
+ while (gen_e_list_next(&scan,&temp))
+ {
+ st[++i] = setif_get_stamp(temp);
+ }
+
+ if ( (result =
+ term_hash_find(setif_hash,st,gen_e_list_length(filtered)+1))
+ == NULL )
+ {
+ struct setif_union_ *u = ralloc(setif_region,struct setif_union_);
+
+ u->type = UNION_TYPE;
+ u->st = stamp_fresh();
+ u->proj_cache = new_gen_e_list(setif_region);
+ u->exprs = filtered;
+
+ result = (gen_e)u;
+ term_hash_insert(setif_hash,result,st,gen_e_list_length(filtered)+1);
+
+ setif_stats.distinct_unions++;
+ return result;
+ }
+ else
+ {
+ setif_stats.hashed_unions++;
+ return result;
+ }
+ }
+}
+
+gen_e setif_inter(gen_e_list exprs) deletes
+{
+ gen_e_list filtered = gen_e_list_filter(setif_region,exprs,filter_one);
+
+ if ( gen_e_list_empty(filtered) )
+ {
+ setif_stats.filtered_intersections++;
+ return setif_one();
+ }
+ else if (gen_e_list_length(filtered) == 1)
+ {
+ setif_stats.filtered_intersections++;
+ return gen_e_list_head(filtered);
+ }
+
+ else
+ {
+ int i = 0;
+ gen_e temp,result;
+ gen_e_list_scanner scan;
+ stamp st[ gen_e_list_length(filtered) + 1 ];
+
+ st[0] = INTER_TYPE;
+
+ gen_e_list_scan(filtered,&scan);
+ while (gen_e_list_next(&scan,&temp))
+ {
+ st[++i] = setif_get_stamp(temp);
+ }
+
+ if ( (result =
+ term_hash_find(setif_hash,st,gen_e_list_length(filtered)+1))
+ == NULL )
+ {
+ struct setif_inter_ *u = ralloc(setif_region,struct setif_inter_);
+
+ u->type = UNION_TYPE;
+ u->st = stamp_fresh();
+ u->exprs = filtered;
+
+ result = (gen_e)u;
+ term_hash_insert(setif_hash,result,st,gen_e_list_length(filtered)+1);
+
+ setif_stats.distinct_intersections++;
+
+ return result;
+ }
+ else
+ {
+ setif_stats.hashed_intersections++;
+ return result;
+ }
+ }
+}
+
+bool setif_is_zero(gen_e e)
+{
+ return ((setif_term)e)->type == ZERO_TYPE;
+}
+
+bool setif_is_one(gen_e e)
+{
+ return ((setif_term)e)->type == ONE_TYPE;
+}
+
+bool setif_is_var(gen_e e)
+{
+ return ((setif_term)e)->type == VAR_TYPE;
+}
+
+bool setif_is_union(gen_e e)
+{
+ return ((setif_term)e)->type == UNION_TYPE;
+}
+
+bool setif_is_inter(gen_e e)
+{
+ return ((setif_term)e)->type == INTER_TYPE;
+}
+
+bool setif_is_constant(gen_e e)
+{
+ return ((setif_term)e)->type == CONSTANT_TYPE;
+}
+
+char *setif_get_constant_name(gen_e e)
+{
+ assert( ((setif_term)e)->type == CONSTANT_TYPE );
+
+ return ((setif_constant_)e)->name;
+}
+
+void setif_init(void)
+{
+ setif_region = newregion();
+ tlb_cache_region = newregion();
+ setif_vars = new_setif_var_list(setif_region);
+ tlb_var_cache = new_setif_var_list(tlb_cache_region);
+ setif_hash = make_term_hash(setif_region);
+ tlb_dict = jcoll_create_dict(tlb_cache_region,setif_get_stamp);
+}
+
+
+
+static void setif_reset_stats(void)
+{
+ setif_stats.fresh = 0;
+ setif_stats.fresh_small = 0;
+ setif_stats.fresh_large = 0;
+
+ setif_stats.distinct_constructors = 0;
+ setif_stats.hashed_constructors = 0;
+ setif_stats.distinct_constants = 0;
+ setif_stats.hashed_constants = 0;
+ setif_stats.distinct_unions = 0;
+ setif_stats.filtered_unions = 0;
+ setif_stats.hashed_unions = 0;
+ setif_stats.distinct_intersections = 0;
+ setif_stats.filtered_intersections = 0;
+ setif_stats.hashed_intersections = 0;
+
+ setif_stats.redundant_pred = 0;
+ setif_stats.redundant_succ = 0;
+ setif_stats.redundant_source = 0;
+ setif_stats.redundant_sink = 0;
+
+ setif_stats.added_pred = 0;
+ setif_stats.added_succ = 0;
+ setif_stats.added_source = 0;
+ setif_stats.added_sink = 0;
+
+ setif_stats.cycles_searched_forward = 0;
+ setif_stats.cycles_searched_backward = 0;
+
+ setif_stats.cycles_collapsed_forward = 0;
+ setif_stats.cycles_collapsed_backward = 0;
+
+ setif_stats.cycles_length_forward = 0;
+ setif_stats.cycles_length_backward = 0;
+}
+
+void setif_reset(void) deletes
+{
+ term_hash_delete(setif_hash);
+ invalidate_tlb_cache();
+ deleteregion_ptr(&setif_region);
+ deleteregion_ptr(&tlb_cache_region);
+
+ setif_reset_stats();
+
+ setif_region = newregion();
+ tlb_cache_region = newregion();
+ setif_vars = new_setif_var_list(setif_region);
+ tlb_var_cache = new_setif_var_list(tlb_cache_region);
+ setif_hash = make_term_hash(setif_region);
+}
+
+static jcoll tlb_aux(gen_e e)
+{
+ if (setif_is_var(e))
+ {
+ setif_var v = (setif_var)e;
+
+ if ( sv_get_tlb_cache(v) != NULL)
+ return sv_get_tlb_cache(v);
+
+ else
+ {
+ jcoll result;
+ gen_e_list sources = new_gen_e_list(tlb_cache_region);
+ jcoll_list jvars = new_jcoll_list(tlb_cache_region);
+ gen_e_list_scanner scan;
+ gen_e lb;
+
+ gen_e_list_scan(sv_get_lbs(v),&scan);
+ while (gen_e_list_next(&scan,&lb))
+ {
+ if (setif_is_var(lb))
+ jcoll_list_cons(tlb_aux(lb),jvars);
+ else
+ gen_e_list_cons(lb,sources);
+ /* jsources = jcoll_jcons(tlb_cache_region,lb,jsources); */
+ }
+
+ if (! gen_e_list_empty(sources))
+ jcoll_list_cons(jcoll_create_chain(tlb_dict,sources),jvars);
+
+ result =
+ jcoll_jjoin(tlb_dict,jvars);
+
+ set_tlb_cache(v,result);
+ return result;
+ }
+ }
+ else if (setif_is_union(e))
+ {
+ gen_e_list_scanner scan;
+ gen_e temp;
+ jcoll_list jexprs = new_jcoll_list(tlb_cache_region);
+
+ gen_e_list_scan(setif_get_union(e),&scan);
+ while (gen_e_list_next(&scan,&temp))
+ {
+ jcoll_list_cons(tlb_aux(temp),jexprs);
+ }
+
+ return jcoll_jjoin(tlb_dict,jexprs);
+
+ }
+ else
+ {
+ failure("Unmatched case in setif tlb computation\n");
+ return NULL;
+ }
+}
+
+gen_e_list setif_tlb(gen_e e) deletes
+{
+ return jcoll_flatten(tlb_dict,tlb_aux(e));
+}
+
+void setif_set_proj_cache(gen_e e,gen_e elem)
+{
+ if (setif_is_union(e))
+ {
+ setif_union_ u = (setif_union_)e;
+ gen_e_list_cons(elem,u->proj_cache);
+ }
+}
+
+gen_e_list setif_get_proj_cache(gen_e e)
+{
+ if (setif_is_union(e))
+ {
+ setif_union_ u = (setif_union_)e;
+ return u->proj_cache;
+ }
+ else
+ {
+ failure("Term does not cache projections\n");
+ return NULL;
+ }
+}
+
+
+bool setif_proj_merge(setif_var v, gen_e se, get_proj_fn_ptr get_proj,
+ proj_con_fn_ptr proj_con,fresh_large_fn_ptr fresh_large,
+ incl_fn_ptr sort_incl, incl_fn_ptr set_incl) deletes
+{
+ gen_e proj;
+
+ if ((proj = sv_get_ub_proj(v,get_proj)) != NULL)
+ {
+ sort_incl(proj, se);
+ return TRUE;
+ }
+
+ else
+ {
+ gen_e_list_scanner scan;
+ gen_e lb;
+
+ gen_e proj_var;
+ gen_e proj_cons;
+
+ /* create a projection variable for this projection */
+ proj_var = fresh_large(NULL);
+
+ assert(setif_is_var(proj_var));
+
+ proj_cons = proj_con(proj_var);
+
+ sv_add_ub_proj(v, proj_cons);
+
+ /* apply the transitive rule to each of v's lower bounds */
+ gen_e_list_scan(sv_get_lbs(v),&scan);
+ while (gen_e_list_next(&scan,&lb))
+ {
+ set_incl(lb,proj_cons);
+ }
+
+ sort_incl(proj_var, se);
+ return TRUE;
+ }
+
+}
+
+
+void setif_print_stats(FILE *f)
+{
+ fprintf(f,"\n========== SetIF Var Stats ==========\n");
+ fprintf(f,"Fresh : %d\n",setif_stats.fresh);
+ fprintf(f,"Fresh Small : %d\n",setif_stats.fresh_small);
+ fprintf(f,"Fresh Large : %d\n",setif_stats.fresh_large);
+ fprintf(f,"Total : %d\n",setif_stats.fresh + setif_stats.fresh_small
+ + setif_stats.fresh_large);
+ fprintf(f,"\n========== SetIF Sort Stats ==========\n");
+ fprintf(f,"\n");
+ fprintf(f,"\n------------------------------\n");
+ fprintf(f,"Additions");
+ fprintf(f,"\n------------------------------\n");
+ fprintf(f,"Pred: %d\n",setif_stats.added_pred);
+ fprintf(f,"Succ: %d\n",setif_stats.added_succ);
+ fprintf(f,"Source: %d\n",setif_stats.added_source);
+ fprintf(f,"Sink: %d",setif_stats.added_sink);
+ fprintf(f,"\n------------------------------\n");
+ fprintf(f,"Total: %d",setif_stats.added_pred + setif_stats.added_succ
+ + setif_stats.added_source + setif_stats.added_sink);
+ fprintf(f,"\n");
+ fprintf(f,"\n------------------------------\n");
+ fprintf(f,"Redundant");
+ fprintf(f,"\n------------------------------\n");
+ fprintf(f,"Pred: %d\n",setif_stats.redundant_pred);
+ fprintf(f,"Succ: %d\n",setif_stats.redundant_succ);
+ fprintf(f,"Source: %d\n",setif_stats.redundant_source);
+ fprintf(f,"Sink: %d",setif_stats.redundant_sink);
+ fprintf(f,"\n------------------------------\n");
+ fprintf(f,"Total: %d\n",
+ setif_stats.redundant_pred+setif_stats.redundant_succ+setif_stats.redundant_source+setif_stats.redundant_sink);
+
+ fprintf(f,"\n");
+
+ fprintf(f,"\n------------------------------\n");
+ fprintf(f,"Forward Cycles");
+ fprintf(f,"\n------------------------------\n");
+ fprintf(f,"Collapsed: %d\n",setif_stats.cycles_collapsed_forward);
+ fprintf(f,"Searched: %d\n",setif_stats.cycles_searched_forward);
+ fprintf(f,"Hit rate: %f\n",
+ ((float)setif_stats.cycles_collapsed_forward)/((float)setif_stats.cycles_searched_forward));
+ fprintf(f,"Average Length: %f\n",
+ 1+((float)setif_stats.cycles_length_forward) / ((float)setif_stats.cycles_collapsed_forward));
+ fprintf(f,"\n");
+ fprintf(f,"\n------------------------------\n");
+ fprintf(f,"Reverse Cycles");
+ fprintf(f,"\n------------------------------\n");
+ fprintf(f,"Collapsed: %d\n",setif_stats.cycles_collapsed_backward);
+ fprintf(f,"Searched: %d\n",setif_stats.cycles_searched_backward);
+ fprintf(f,"Hit rate: %f\n",
+ ((float)setif_stats.cycles_collapsed_backward)/((float)setif_stats.cycles_searched_backward));
+ fprintf(f,"Average Length: %f\n",
+ 1+((float)setif_stats.cycles_length_backward) / ((float)setif_stats.cycles_collapsed_backward));
+ fprintf(f,"=====================================\n");
+}
+
+/*
+ for now, print stamps and types for sources and sinks.
+ must eventually rely on specialized code
+*/
+void setif_print_constraint_graph(FILE *f)
+{
+ setif_var_list_scanner scan;
+ gen_e_list_scanner scan_edges;
+ gen_e edge;
+ setif_var v;
+ dot_node n1,n2;
+ char temp_str[512];
+
+ graph_attr graph_style[3] = {{g_size,"\"8.5,11\""},
+ {g_center,"true"},
+ {g_orientation,"portrait"}};
+ edge_attr succ_edge[1] = {{e_style,"solid"}};
+ edge_attr pred_edge[1] = {{e_style,"dotted"}};
+
+ dot_start(f,"setif",TRUE,TRUE);
+ dot_global_graph_style(graph_style,3);
+
+ setif_var_list_scan(setif_vars,&scan);
+ while(setif_var_list_next(&scan,&v))
+ {
+ snprintf(temp_str,512,"%s:%ld",sv_get_name(v),sv_get_stamp(v));
+ n1 = dot_get_node(temp_str);
+ gen_e_list_scan(sv_get_lbs(v),&scan_edges);
+ while(gen_e_list_next(&scan_edges,&edge))
+ {
+ if (setif_is_var(edge))
+ {
+ snprintf(temp_str,512,"%s:%ld",sv_get_name((setif_var)edge),
+ setif_get_stamp(edge));
+ n2 = dot_get_node(temp_str);
+ }
+ else
+ {
+ snprintf(temp_str,512,"source:%ld",setif_get_stamp(edge));
+ n2 = dot_get_node(temp_str);
+ }
+ dot_styled_edge(n2,n1,pred_edge,1);
+ }
+
+ gen_e_list_scan(sv_get_ubs(v),&scan_edges);
+ while(gen_e_list_next(&scan_edges,&edge))
+ {
+ if (setif_is_var(edge))
+ {
+ snprintf(temp_str,512,"%s:%ld",sv_get_name((setif_var)edge),
+ setif_get_stamp(edge));
+ n2 = dot_get_node(temp_str);
+ }
+ else
+ {
+ snprintf(temp_str,512,"sink:%ld",setif_get_stamp(edge));
+ n2 = dot_get_node(temp_str);
+ }
+ dot_styled_edge(n1,n2,succ_edge,1);
+ }
+
+ gen_e_list_scan(sv_get_ub_projs(v),&scan_edges);
+ while(gen_e_list_next(&scan_edges,&edge))
+ {
+ snprintf(temp_str,512,"projpat:%ld",setif_get_stamp(edge));
+ n2 = dot_get_node(temp_str);
+ dot_styled_edge(n1,n2,succ_edge,1);
+ }
+
+ }
+
+ dot_end();
+}
+
diff --git a/libbanshee/engine/setif-sort.h b/libbanshee/engine/setif-sort.h
new file mode 100644
index 00000000000..7cfabc81752
--- /dev/null
+++ b/libbanshee/engine/setif-sort.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef SETIF_SORT_H
+#define SETIF_SORT_H
+
+#include <stdio.h>
+#include "banshee.h"
+#include "termhash.h"
+#include "setif-var.h"
+
+
+struct setif_term /* extends gen_e */
+{
+#ifdef NONSPEC
+ const sort_kind sort;
+#endif
+ const int type;
+ const stamp st;
+};
+
+typedef struct setif_term *setif_term;
+
+extern bool flag_merge_projections;
+extern bool flag_eliminate_cycles;
+
+extern region setif_region;
+extern term_hash setif_hash;
+
+typedef bool (*res_proj_fn_ptr) (setif_var v,gen_e proj) deletes;
+typedef gen_e (*proj_con_fn_ptr) (gen_e) deletes;
+
+stamp setif_get_stamp(gen_e e);
+void setif_inclusion(con_match_fn_ptr,res_proj_fn_ptr, gen_e, gen_e) deletes;
+
+bool setif_proj_merge(setif_var v, gen_e se, get_proj_fn_ptr get_proj,
+ proj_con_fn_ptr make_proj,fresh_large_fn_ptr fresh_var,
+ incl_fn_ptr sort_incl, incl_fn_ptr set_incl) deletes;
+
+gen_e setif_zero(void);
+gen_e setif_one(void);
+gen_e setif_fresh(const char *name);
+gen_e setif_fresh_large(const char *name);
+gen_e setif_fresh_small(const char *name);
+gen_e setif_constant(const char *name) deletes;
+gen_e setif_union(gen_e_list exprs) deletes;
+gen_e setif_inter(gen_e_list exprs) deletes;
+bool setif_is_zero(gen_e e);
+bool setif_is_one(gen_e e);
+bool setif_is_var(gen_e e);
+bool setif_is_union(gen_e e);
+bool setif_is_inter(gen_e e);
+bool setif_is_constant(gen_e e);
+char *setif_get_constant_name(gen_e e);
+
+gen_e_list setif_get_union(gen_e e);
+gen_e_list setif_get_inter(gen_e e);
+
+gen_e_list setif_tlb(gen_e e) deletes;
+
+void setif_set_proj_cache(gen_e e, gen_e elem);
+gen_e_list setif_get_proj_cache(gen_e e);
+
+void setif_init(void);
+void setif_reset(void) deletes;
+void setif_print_stats(FILE *f);
+void setif_print_constraint_graph(FILE *f);
+
+extern struct setif_stats setif_stats;
+struct setif_stats
+{
+ int fresh;
+ int fresh_small;
+ int fresh_large;
+
+ int distinct_constructors;
+ int hashed_constructors;
+ int distinct_constants;
+ int hashed_constants;
+ int distinct_unions;
+ int filtered_unions;
+ int hashed_unions;
+ int distinct_intersections;
+ int filtered_intersections;
+ int hashed_intersections;
+
+ int redundant_pred;
+ int redundant_succ;
+ int redundant_source;
+ int redundant_sink;
+
+ int added_pred;
+ int added_succ;
+ int added_source;
+ int added_sink;
+
+ int cycles_searched_forward;
+ int cycles_searched_backward;
+
+ int cycles_collapsed_forward;
+ int cycles_collapsed_backward;
+
+ int cycles_length_forward;
+ int cycles_length_backward;
+};
+
+#endif /* SETIF_SORT_H */
diff --git a/libbanshee/engine/setif-var.c b/libbanshee/engine/setif-var.c
new file mode 100644
index 00000000000..21941021284
--- /dev/null
+++ b/libbanshee/engine/setif-var.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include <regions.h>
+#include "setif-var.h"
+#include "ufind.h"
+#include "bounds.h"
+
+struct sv_info
+{
+ stamp st;
+ bounds sameregion lbs;
+ bounds sameregion ubs;
+ jcoll tlb_cache;
+ gen_e_list ub_projs;
+ const char *name;
+ uf_element component;
+};
+
+typedef struct sv_info *sv_info;
+
+DECLARE_UFIND(sv_elt,sv_info)
+
+DEFINE_UFIND(sv_elt,sv_info)
+
+DEFINE_LIST(setif_var_list,setif_var)
+
+#define get_info(v) (sv_elt_get_info((v)->elt))
+
+struct setif_var /* extends gen_e */
+{
+#ifdef NONSPEC
+ sort_kind sort;
+#endif
+ int type;
+ sv_elt elt;
+};
+
+bool sv_lt(setif_var v1, setif_var v2)
+{
+ return ( sv_get_stamp(v1) < sv_get_stamp(v2) );
+}
+
+bool sv_eq(setif_var v1, setif_var v2)
+{
+ return ( sv_get_stamp(v1) == sv_get_stamp(v2) );
+}
+
+static setif_var make_var(region r, const char *name, stamp st)
+{
+ setif_var result = ralloc(r, struct setif_var);
+ sv_info info = ralloc(r, struct sv_info);
+
+ info->st = st;
+ info->lbs = bounds_create(r);
+ info->ubs = bounds_create(r);
+ info->tlb_cache = NULL;
+ info->ub_projs = new_gen_e_list(r);
+ info->name = name ? rstrdup(r,name) : "fv";
+ info->component = new_uf_element(r, NULL);
+
+ result->type = VAR_TYPE;
+ result->elt = new_sv_elt(r,info);
+
+#ifdef NONSPEC
+ result->sort = setif_sort;
+#endif
+
+ return result;
+}
+
+setif_var sv_fresh(region r, const char *name)
+{
+ return make_var(r,name,stamp_fresh());
+}
+
+setif_var sv_fresh_large(region r, const char *name)
+{
+ return make_var(r,name,stamp_fresh_large());
+}
+
+setif_var sv_fresh_small(region r, const char *name)
+{
+ return make_var(r,name,stamp_fresh_small());
+}
+
+stamp sv_get_stamp(setif_var v)
+{
+ return get_info(v)->st;
+}
+
+const char *sv_get_name(setif_var v)
+{
+ return get_info(v)->name;
+}
+
+
+static sv_info combine(sv_info i1, sv_info i2)
+{
+ if (i1->st < i2->st)
+ return i1;
+ else return i2;
+}
+
+void sv_unify(setif_var v,setif_var_list vars)
+{
+ setif_var temp;
+ setif_var_list_scanner scan;
+
+ setif_var_list_scan(vars,&scan);
+
+ while (setif_var_list_next(&scan,&temp))
+ {
+ sv_elt_unify(combine,v->elt,temp->elt);
+ }
+}
+
+gen_e_list sv_get_lbs(setif_var v)
+{
+ return bounds_exprs(get_info(v)->lbs);
+}
+
+gen_e_list sv_get_ubs(setif_var v)
+{
+ return bounds_exprs(get_info(v)->ubs);
+}
+
+bool sv_add_ub(setif_var v, gen_e e, stamp s)
+{
+ return bounds_add(get_info(v)->ubs,e,s);
+}
+
+bool sv_add_lb(setif_var v, gen_e e, stamp s)
+{
+ return bounds_add(get_info(v)->lbs,e,s);
+}
+
+bool sv_is_ub(setif_var v, stamp s)
+{
+ bool self_edge = sv_get_stamp(v) == s,
+ in_bounds = bounds_query(get_info(v)->ubs,s);
+
+ return (self_edge || in_bounds);
+}
+
+bool sv_is_lb(setif_var v, stamp s)
+{
+
+ bool self_edge = sv_get_stamp(v) == s,
+ in_bounds = bounds_query(get_info(v)->lbs,s);
+
+ return (self_edge || in_bounds);
+
+}
+
+void sv_add_ub_proj(setif_var v, gen_e e)
+{
+ gen_e_list_cons(e,get_info(v)->ub_projs);
+}
+
+gen_e sv_get_ub_proj(setif_var v, get_proj_fn_ptr get_proj)
+{
+ return get_proj(get_info(v)->ub_projs);
+}
+
+gen_e_list sv_get_ub_projs(setif_var v)
+{
+ return get_info(v)->ub_projs;
+}
+
+
+bool sv_union_component(setif_var v1, setif_var v2)
+{
+ if (uf_eq(get_info(v1)->component,get_info(v2)->component))
+ return FALSE;
+
+ else
+ {
+ uf_union(get_info(v1)->component,get_info(v2)->component);
+ return TRUE;
+ }
+}
+
+void sv_set_tlb_cache(setif_var v, jcoll j)
+{
+ get_info(v)->tlb_cache = j;
+}
+
+jcoll sv_get_tlb_cache(setif_var v)
+{
+ return get_info(v)->tlb_cache;
+}
+
+void sv_clear_tlb_cache(setif_var v)
+{
+ get_info(v)->tlb_cache = NULL;
+}
diff --git a/libbanshee/engine/setif-var.h b/libbanshee/engine/setif-var.h
new file mode 100644
index 00000000000..6ded7363ae2
--- /dev/null
+++ b/libbanshee/engine/setif-var.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef SETIF_VAR_H
+#define SETIF_VAR_H
+
+#include "linkage.h"
+#include "banshee.h"
+#include "jcollection.h"
+
+EXTERN_C_BEGIN
+
+typedef struct setif_var *setif_var;
+
+DECLARE_LIST(setif_var_list,setif_var)
+
+bool sv_lt(setif_var v1, setif_var v2);
+bool sv_eq(setif_var v1, setif_var v2);
+setif_var sv_fresh(region r, const char *name);
+setif_var sv_fresh_large(region r, const char *name);
+setif_var sv_fresh_small(region r, const char *name);
+stamp sv_get_stamp(setif_var v);
+const char *sv_get_name(setif_var v);
+void sv_unify(setif_var v,setif_var_list vars);
+gen_e_list sv_get_lbs(setif_var v);
+gen_e_list sv_get_ubs(setif_var v);
+bool sv_add_ub(setif_var v, gen_e e, stamp st);
+bool sv_add_lb(setif_var v, gen_e e, stamp st);
+bool sv_is_ub(setif_var v, stamp st);
+bool sv_is_lb(setif_var v, stamp st);
+void sv_set_tlb_cache(setif_var v, jcoll j);
+jcoll sv_get_tlb_cache(setif_var v);
+void sv_clear_tlb_cache(setif_var v);
+void sv_add_ub_proj(setif_var v, gen_e e);
+
+gen_e sv_get_ub_proj(setif_var v, get_proj_fn_ptr get_proj);
+gen_e_list sv_get_ub_projs(setif_var v);
+
+bool sv_union_component(setif_var v1, setif_var v2);
+
+EXTERN_C_END
+
+
+#endif /* SETIF_VAR_H */
+
diff --git a/libbanshee/engine/setst-sort.c b/libbanshee/engine/setst-sort.c
new file mode 100644
index 00000000000..5d89817ed00
--- /dev/null
+++ b/libbanshee/engine/setst-sort.c
@@ -0,0 +1,907 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <regions.h>
+#include <assert.h>
+#include <stdio.h>
+#include "bounds.h"
+#include "setst-sort.h"
+
+
+struct setst_union_
+{
+#ifdef NONSPEC
+ sort_kind sort;
+#endif
+ int type;
+ stamp st;
+ gen_e_list exprs;
+ gen_e_list proj_cache;
+};
+
+struct setst_inter_
+{
+#ifdef NONSPEC
+ sort_kind sort;
+#endif
+ int type;
+ stamp st;
+ gen_e_list exprs;
+};
+
+struct setst_constant_
+{
+#ifdef NONSPEC
+ sort_kind sort;
+#endif
+ int type;
+ stamp st;
+ char *name;
+};
+
+typedef struct setst_inter_ *setst_inter_;
+typedef struct setst_union_ *setst_union_;
+typedef struct setst_constant_ *setst_constant_;
+
+static region tlb_cache_region;
+static jcoll_dict tlb_dict;
+static setst_var_list setst_vars;
+static bool setst_changed = FALSE;
+
+region setst_region;
+term_hash setst_hash;
+struct setst_stats setst_stats;
+
+stamp setst_get_stamp(gen_e e)
+{
+#ifdef NONSPEC
+ assert(e->sort == setst_sort);
+#endif
+
+ if ( ((setst_term)e)->type == VAR_TYPE)
+ return st_get_stamp( (setst_var)e );
+
+ else
+ return ((setst_term)e)->st;
+}
+
+static bool eq(gen_e e1, gen_e e2)
+{
+ return ( setst_get_stamp(e1) == setst_get_stamp(e2) );
+}
+
+static gen_e_list get_union(gen_e e)
+{
+ assert ( ((setst_term)e)->type == UNION_TYPE);
+
+ return ( (setst_union_) e)->exprs;
+}
+
+static gen_e_list get_inter(gen_e e)
+{
+ assert ( ((setst_term)e)->type == INTER_TYPE);
+
+ return ( (setst_inter_) e)->exprs;
+}
+
+static void update_lower_bound(setst_var v, gen_e e)
+{
+ if (setst_is_var(e))
+ {
+ if (st_add_lb(v,(setst_var)e))
+ {
+ setst_stats.redundant_var++;
+ }
+ else
+ {
+ setst_stats.added_var++;
+ setst_changed = TRUE;
+ }
+ }
+ else
+ {
+ if (st_add_source(v, e,setst_get_stamp(e)))
+ {
+ setst_stats.redundant_source++;
+ }
+ else
+ {
+ setst_stats.added_source++;
+ setst_changed = TRUE;
+ }
+ }
+
+}
+
+static void update_upper_bound(setst_var v, gen_e e)
+{
+ assert(! setst_is_var(e));
+
+ if (st_add_sink(v,e,setst_get_stamp(e)))
+ {
+ setst_stats.redundant_sink++;
+ }
+ else
+ {
+ setst_stats.added_sink++;
+ setst_changed = TRUE;
+ }
+}
+
+
+void setst_inclusion(con_match_fn_ptr con_match,gen_e e1, gen_e e2)
+{
+ if (eq(e1,e2))
+ return;
+
+ else if ( setst_is_zero(e1) || setst_is_one(e2) )
+ return;
+
+ else if (setst_is_union(e1))
+ {
+ gen_e_list_scanner scan;
+ gen_e temp;
+
+ gen_e_list exprs = get_union(e1);
+
+ gen_e_list_scan(exprs,&scan);
+ while (gen_e_list_next(&scan,&temp))
+ {
+ setst_inclusion(con_match,temp,e2);
+ }
+
+ return;
+ }
+
+ else if (setst_is_inter(e2))
+ {
+ gen_e_list_scanner scan;
+ gen_e temp;
+
+ gen_e_list exprs = get_inter(e2);
+
+ gen_e_list_scan(exprs,&scan);
+ while (gen_e_list_next(&scan,&temp))
+ {
+ setst_inclusion(con_match,e1,temp);
+ }
+
+ return;
+ }
+
+ else if (setst_is_var(e2))
+ {
+ setst_var v = (setst_var)e2;
+
+ update_lower_bound(v,e1);
+ }
+
+ else if (setst_is_var(e1))
+ {
+ setst_var v = (setst_var)e1;
+
+ update_upper_bound(v,e2);
+ }
+
+ else con_match(e1,e2);
+}
+
+#ifdef NONSPEC
+static struct setst_term zero = {ZERO_TYPE,setst_sort,ZERO_TYPE};
+static struct setst_term one = {ONE_TYPE,setst_sort,ONE_TYPE};
+#else
+static struct setst_term zero = {ZERO_TYPE,ZERO_TYPE};
+static struct setst_term one = {ONE_TYPE,ONE_TYPE};
+#endif /* NONSPEC */
+
+gen_e setst_zero(void)
+{
+ return (gen_e)&zero;
+}
+
+gen_e setst_one(void)
+{
+ return (gen_e)&one;
+}
+
+gen_e setst_fresh(const char *name)
+{
+ setst_var v = st_fresh(setst_region,name);
+ setst_var_list_cons(v,setst_vars);
+ return (gen_e)v;
+}
+
+gen_e setst_fresh_large(const char *name)
+{
+ setst_var v = st_fresh_large(setst_region,name);
+ setst_var_list_cons(v,setst_vars);
+ return (gen_e)v;
+}
+
+gen_e setst_fresh_small(const char *name)
+{
+ setst_var v = st_fresh_small(setst_region,name);
+ setst_var_list_cons(v,setst_vars);
+ return (gen_e)v;
+}
+
+gen_e setst_constant(const char *str) deletes
+{
+ stamp st[2];
+ gen_e result;
+ char *name = rstrdup(setst_region,str);
+
+ assert (str != NULL);
+
+ st[0] = CONSTANT_TYPE;
+ st[1] = stamp_string(name);
+
+ if ( (result = term_hash_find(setst_hash,st,2)) == NULL)
+ {
+ setst_constant_ c = ralloc(setst_region, struct setst_constant_);
+ c->type = CONSTANT_TYPE;
+ c->st = stamp_fresh();
+ c->name = name;
+
+ result = (gen_e) c;
+ term_hash_insert(setst_hash,result,st,2);
+
+ setst_stats.distinct_constants++;
+
+ return result;
+ }
+
+ else
+ {
+ setst_stats.hashed_constants++;
+ return result;
+ }
+}
+
+static bool filter_zero(const gen_e e)
+{
+ return (!setst_is_zero(e));
+}
+
+
+static bool filter_one(const gen_e e)
+{
+ return (!setst_is_one(e));
+}
+
+gen_e setst_union(gen_e_list exprs) deletes
+{
+ gen_e_list filtered = gen_e_list_filter(setst_region,exprs,filter_zero);
+
+ if ( gen_e_list_empty(filtered) )
+ {
+ setst_stats.filtered_unions++;
+ return setst_zero();
+ }
+ else if (gen_e_list_length(filtered) == 1)
+ {
+ setst_stats.filtered_unions++;
+ return gen_e_list_head(filtered);
+ }
+
+ else
+ {
+ int i = 0;
+ gen_e temp,result;
+ gen_e_list_scanner scan;
+ stamp st[ gen_e_list_length(filtered) + 1 ];
+
+ st[0] = UNION_TYPE;
+
+ gen_e_list_scan(filtered,&scan);
+ while (gen_e_list_next(&scan,&temp))
+ {
+ st[++i] = setst_get_stamp(temp);
+ }
+
+ if ( (result =
+ term_hash_find(setst_hash,st,gen_e_list_length(filtered)+1))
+ == NULL )
+ {
+ struct setst_union_ *u = ralloc(setst_region,struct setst_union_);
+
+ u->type = UNION_TYPE;
+ u->st = stamp_fresh();
+ u->proj_cache = new_gen_e_list(setst_region);
+ u->exprs = filtered;
+
+ result = (gen_e)u;
+ term_hash_insert(setst_hash,result,st,gen_e_list_length(filtered)+1);
+
+ setst_stats.distinct_unions++;
+ return result;
+ }
+ else
+ {
+ setst_stats.hashed_unions++;
+ return result;
+ }
+ }
+}
+
+gen_e setst_inter(gen_e_list exprs) deletes
+{
+ gen_e_list filtered = gen_e_list_filter(setst_region,exprs,filter_one);
+
+ if ( gen_e_list_empty(filtered) )
+ {
+ setst_stats.filtered_intersections++;
+ return setst_one();
+ }
+ else if (gen_e_list_length(filtered) == 1)
+ {
+ setst_stats.filtered_intersections++;
+ return gen_e_list_head(filtered);
+ }
+
+ else
+ {
+ int i = 0;
+ gen_e temp,result;
+ gen_e_list_scanner scan;
+ stamp st[ gen_e_list_length(filtered) + 1 ];
+
+ st[0] = INTER_TYPE;
+
+ gen_e_list_scan(filtered,&scan);
+ while (gen_e_list_next(&scan,&temp))
+ {
+ st[++i] = setst_get_stamp(temp);
+ }
+
+ if ( (result =
+ term_hash_find(setst_hash,st,gen_e_list_length(filtered)+1))
+ == NULL )
+ {
+ struct setst_inter_ *u = ralloc(setst_region,struct setst_inter_);
+
+ u->type = UNION_TYPE;
+ u->st = stamp_fresh();
+ u->exprs = filtered;
+
+ result = (gen_e)u;
+ term_hash_insert(setst_hash,result,st,gen_e_list_length(filtered)+1);
+
+ setst_stats.distinct_intersections++;
+
+ return result;
+ }
+ else
+ {
+ setst_stats.hashed_intersections++;
+ return result;
+ }
+ }
+}
+
+
+gen_e_list setst_get_union(gen_e e)
+{
+ assert (((setst_term)e)->type == UNION_TYPE);
+
+ return ((setst_union_)e)->exprs;
+}
+
+
+gen_e_list setst_get_inter(gen_e e)
+{
+ assert (((setst_term)e)->type == INTER_TYPE);
+
+ return ((setst_inter_)e)->exprs;
+}
+
+static void invalidate_tlb_cache(void)
+{
+ assert(tlb_cache_region);
+
+ jcoll_delete_dict(tlb_dict);
+ setst_var_list_app(setst_vars,st_clear_tlb_cache);
+ deleteregion_ptr(&tlb_cache_region);
+
+ tlb_cache_region = newregion();
+ tlb_dict = jcoll_create_dict(tlb_cache_region,setst_get_stamp);
+}
+
+static void set_tlb_cache(setst_var v,jcoll j)
+{
+ st_set_tlb_cache(v,j);
+}
+
+static void collect_sinks(bounds b,setst_var v)
+{
+ gen_e sink;
+ gen_e_list_scanner scan;
+
+ gen_e_list_scan(st_get_sinks(v),&scan);
+
+ while (gen_e_list_next(&scan,&sink))
+ {
+ bounds_add(b,sink,setst_get_stamp(sink));
+ }
+}
+
+static void collect_sources(bounds b, setst_var v)
+{
+ gen_e source;
+ gen_e_list_scanner scan;
+
+ gen_e_list_scan(st_get_sources(v),&scan);
+
+ while (gen_e_list_next(&scan,&source))
+ {
+ bounds_add(b,source,setst_get_stamp(source));
+ }
+}
+
+static void collect_lower_bounds(bounds b, setst_var v)
+{
+ setst_var lb;
+ setst_var_list_scanner scan;
+
+ setst_var_list_scan(st_get_lbs(v),&scan);
+
+ while (setst_var_list_next(&scan,&lb))
+ {
+ bounds_add(b,(gen_e)lb,st_get_stamp(lb));
+ }
+}
+
+static void apply_sources(setst_var witness, bounds sources)
+{
+ gen_e source;
+ gen_e_list_scanner scan;
+
+ gen_e_list_scan(bounds_exprs(sources),&scan);
+
+ while (gen_e_list_next(&scan,&source))
+ {
+ if ( st_add_source(witness,source,setst_get_stamp(source)))
+ setst_stats.redundant_source++;
+
+ else
+ setst_stats.added_source++;
+ }
+}
+
+static void apply_sinks(setst_var witness, bounds sinks)
+{
+ gen_e sink;
+ gen_e_list_scanner scan;
+
+ gen_e_list_scan(bounds_exprs(sinks),&scan);
+
+ while (gen_e_list_next(&scan,&sink))
+ {
+ if (st_add_sink(witness,sink,setst_get_stamp(sink)))
+ setst_stats.redundant_sink++;
+
+ else
+ setst_stats.added_sink++;
+ }
+}
+
+static void apply_lower_bounds(setst_var witness,bounds lower)
+{
+ gen_e lb;
+ gen_e_list_scanner scan;
+
+ gen_e_list_scan(bounds_exprs(lower),&scan);
+
+ while (gen_e_list_next(&scan,&lb))
+ {
+ if (st_add_lb(witness,(setst_var)lb))
+ setst_stats.redundant_var++;
+ else
+ setst_stats.added_var++;
+ }
+}
+
+static void collapse_cycle(setst_var witness, setst_var_list cycle) deletes
+{
+ setst_var_list_scanner var_scan;
+ setst_var temp;
+ region scratch_rgn = newregion();
+
+ bounds sources = bounds_create(scratch_rgn);
+ bounds sinks = bounds_create(scratch_rgn);
+ bounds lower = bounds_create(scratch_rgn);
+
+
+ setst_stats.cycles_collapsed++;
+
+ /* force at least another iteration */
+ setst_changed = TRUE;
+
+ /* collect all bounds */
+ setst_var_list_scan(cycle,&var_scan);
+ while (setst_var_list_next(&var_scan,&temp))
+ {
+ collect_sources(sources,temp);
+ collect_sinks(sinks,temp);
+ collect_lower_bounds(lower,temp);
+ }
+
+ /* unify all vars */
+ st_unify(witness,cycle);
+
+ /* add all bounds back */
+ apply_sources(witness,sources);
+ apply_sinks(witness,sinks);
+ apply_lower_bounds(witness,lower);
+
+ /* cleanup */
+ bounds_delete(sources);
+ bounds_delete(sinks);
+ bounds_delete(lower);
+ deleteregion(scratch_rgn);
+
+ /* remove self edges */
+ st_repair_bounds(witness);
+}
+/*
+static bool cycle_detect(setst_var goal, setst_var_list path,
+ setst_var_list *result)
+{
+ int pos = st_get_path_pos(goal);
+ setst_stats.cycles_searched++;
+
+ if (pos)
+ {
+ setst_var_list_scanner scan;
+ setst_var temp;
+ setst_var_list cycle = new_setst_var_list(tlb_cache_region);
+
+ setst_var_list_scan(path,&scan);
+ while(setst_var_list_next(&scan,&temp))
+ {
+ if (st_get_path_pos(temp) >= pos)
+ setst_var_list_cons(temp,cycle);
+ }
+
+ *result = cycle;
+ return TRUE;
+ }
+
+ else
+ return FALSE;
+}
+
+*/
+static bool cycle_detect(setst_var goal, setst_var_list path,
+ setst_var_list *result)
+{
+ setst_var_list cycle =
+ setst_var_list_reverse(setst_var_list_copy(tlb_cache_region,path));
+
+ setst_stats.cycles_searched++;
+
+ while (!setst_var_list_empty(cycle) &&
+ !eq((gen_e)setst_var_list_head(cycle),(gen_e)goal))
+ {
+ setst_var_list_tail(cycle);
+ }
+
+ if (setst_var_list_empty(cycle))
+ {
+ return FALSE;
+ }
+ else
+ {
+ *result = cycle;
+ return TRUE;
+ }
+}
+
+static jcoll tlb_aux(gen_e e,int path_len,setst_var_list path) deletes
+{
+ if (setst_is_var(e))
+ {
+ setst_var_list cycle;
+ setst_var v = (setst_var)e;
+ if ( cycle_detect(v,path,&cycle) )
+ {
+ setst_stats.cycles_length += setst_var_list_length(cycle);
+ collapse_cycle(v,cycle);
+ return NULL;
+ }
+ else
+ {
+ if (st_get_tlb_cache(v) != NULL)
+ return st_get_tlb_cache(v);
+ else
+ {
+ jcoll result;
+ setst_var_list_scanner scan;
+ setst_var lb;
+ jcoll_list jvars = new_jcoll_list(tlb_cache_region);
+
+ gen_e_list sources = gen_e_list_copy(tlb_cache_region,
+ st_get_sources(v));
+
+ st_set_path_pos(v,path_len);
+ setst_var_list_scan(st_get_lbs(v),&scan);
+ while (setst_var_list_next(&scan,&lb))
+ {
+ setst_var_list_cons(v,path);
+ jcoll_list_cons(tlb_aux((gen_e)lb,++path_len,path),
+ jvars);
+ setst_var_list_tail(path);
+ }
+
+ if (! gen_e_list_empty(sources))
+ jcoll_list_cons(jcoll_create_chain(tlb_dict,sources),
+ jvars);
+ result = jcoll_jjoin(tlb_dict,jvars);
+ set_tlb_cache(v,result);
+ st_set_path_pos(v,0);
+ return result;
+ }
+
+ }
+ }
+ else if (setst_is_union(e))
+ {
+ gen_e_list_scanner scan;
+ gen_e temp;
+ jcoll_list jexprs = new_jcoll_list(tlb_cache_region);
+
+ gen_e_list_scan(setst_get_union(e),&scan);
+ while (gen_e_list_next(&scan,&temp))
+ {
+ jcoll_list_cons(tlb_aux(temp,++path_len,path),jexprs);
+ }
+
+ return jcoll_jjoin(tlb_dict,jexprs);
+ }
+ else
+ {
+ fail("Unmatched case in setst tlb computation\n");
+ return NULL;
+ }
+}
+static gen_e_list tlb(gen_e e)
+{
+ return jcoll_flatten(tlb_dict,
+ tlb_aux(e,1,new_setst_var_list(tlb_cache_region)) );
+}
+static void match_sinks(incl_fn_ptr setst_incl)
+{
+ gen_e_list_scanner tlb_scanner, sink_scanner;
+ setst_var_list_scanner var_scanner;
+ setst_var v;
+ gen_e lb, sink;
+
+ setst_var_list_scan(setst_vars,&var_scanner);
+
+ while (setst_var_list_next(&var_scanner,&v))
+ {
+ gen_e_list tlbs = tlb((gen_e)v);
+ gen_e_list snks = st_get_sinks(v);
+
+
+ if(gen_e_list_empty(st_get_sinks(v)))
+ {
+ setst_stats.no_sinks++;
+ continue;
+ }
+ else if(st_get_seen(v))
+ {
+ setst_stats.incycle_vars++;
+ continue;
+ }
+ else if (gen_e_list_length(tlbs) == st_get_src_sz(v)
+ && gen_e_list_length(snks) == st_get_snk_sz(v) )
+ {
+ setst_stats.unchanged_vars++;
+ continue;
+ }
+ st_set_seen(v,TRUE);
+
+ st_set_src_sz(v,gen_e_list_length(tlbs));
+ st_set_snk_sz(v,gen_e_list_length(snks));
+
+ gen_e_list_scan(tlbs,&tlb_scanner);
+
+ while (gen_e_list_next(&tlb_scanner,&lb))
+ {
+ gen_e_list_scan(snks,&sink_scanner);
+
+ while (gen_e_list_next(&sink_scanner,&sink))
+ setst_incl(lb,sink);
+ }
+ }
+}
+static void iterate(incl_fn_ptr setst_incl)
+{
+ setst_var_list_scanner var_scanner;
+ setst_var v;
+ /* static int iterations = 0; */
+ setst_changed = FALSE;
+
+ setst_var_list_scan(setst_vars,&var_scanner);
+ while (setst_var_list_next(&var_scanner,&v))
+ {
+ st_set_seen(v,FALSE);
+ }
+
+ invalidate_tlb_cache();
+ match_sinks(setst_incl);
+
+ /* fprintf(stderr,"Iterations : %d\n",++iterations); */
+
+ if (setst_changed)
+ iterate(setst_incl);
+}
+gen_e_list setst_tlb(gen_e e,incl_fn_ptr setst_incl) deletes
+{
+ if (! setst_changed)
+ {
+ return tlb(e);
+ }
+ else
+ {
+ iterate(setst_incl);
+ return tlb(e);
+ }
+
+}
+
+void setst_set_proj_cache(gen_e e, gen_e elem)
+{
+ if (setst_is_union(e))
+ {
+ setst_union_ u = (setst_union_)e;
+ gen_e_list_cons(elem,u->proj_cache);
+ }
+}
+
+gen_e_list setst_get_proj_cache(gen_e e)
+{
+
+ if (setst_is_union(e))
+ {
+ setst_union_ u = (setst_union_)e;
+ return u->proj_cache;
+ }
+ else
+ {
+ fail("Term does not cache projections\n");
+ return NULL;
+ }
+}
+
+void setst_init(void)
+{
+ setst_region = newregion();
+ tlb_cache_region = newregion();
+ setst_hash = make_term_hash(setst_region);
+ setst_vars = new_setst_var_list(setst_region);
+ tlb_dict = jcoll_create_dict(tlb_cache_region,setst_get_stamp);
+}
+
+void setst_reset(void) deletes
+{
+ term_hash_delete(setst_hash);
+ deleteregion_ptr(&setst_region);
+
+ setst_region = newregion();
+ setst_hash = make_term_hash(setst_region);
+ setst_vars = new_setst_var_list(setst_region);
+ invalidate_tlb_cache();
+ setst_changed = FALSE;
+}
+
+bool setst_is_zero(gen_e e)
+{
+ return ((setst_term)e)->type == ZERO_TYPE;
+}
+
+bool setst_is_one(gen_e e)
+{
+ return ((setst_term)e)->type == ONE_TYPE;
+}
+
+bool setst_is_var(gen_e e)
+{
+ return ((setst_term)e)->type == VAR_TYPE;
+}
+
+bool setst_is_union(gen_e e)
+{
+ return ((setst_term)e)->type == UNION_TYPE;
+}
+
+bool setst_is_inter(gen_e e)
+{
+ return ((setst_term)e)->type == INTER_TYPE;
+}
+
+char *setst_get_constant_name(gen_e e)
+{
+ assert( ((setst_term)e)->type == CONSTANT_TYPE );
+
+ return ((setst_constant_)e)->name;
+}
+
+void setst_print_stats(FILE *f)
+{
+ fprintf(f,"\n========== SetST Var Stats ==========\n");
+ fprintf(f,"Fresh : %d\n",setst_stats.fresh);
+ fprintf(f,"Fresh Small : %d\n",setst_stats.fresh_small);
+ fprintf(f,"Fresh Large : %d\n",setst_stats.fresh_large);
+ fprintf(f,"Total : %d\n",setst_stats.fresh + setst_stats.fresh_small
+ + setst_stats.fresh_large);
+ fprintf(f,"\n========== SetST Sort Stats ==========\n");
+ fprintf(f,"\n");
+ fprintf(f,"\n------------------------------\n");
+ fprintf(f,"Additions");
+ fprintf(f,"\n------------------------------\n");
+ fprintf(f,"Var: %d\n",setst_stats.added_var);
+ fprintf(f,"Source: %d\n",setst_stats.added_source);
+ fprintf(f,"Sink: %d",setst_stats.added_sink);
+ fprintf(f,"\n------------------------------\n");
+ fprintf(f,"Total: %d",setst_stats.added_var + setst_stats.added_source
+ + setst_stats.added_sink);
+ fprintf(f,"\n");
+ fprintf(f,"\n------------------------------\n");
+ fprintf(f,"Redundant");
+ fprintf(f,"\n------------------------------\n");
+ fprintf(f,"Var: %d\n",setst_stats.redundant_var);
+ fprintf(f,"Source: %d\n",setst_stats.redundant_source);
+ fprintf(f,"Sink: %d",setst_stats.redundant_sink);
+ fprintf(f,"\n------------------------------\n");
+ fprintf(f,"Total: %d\n",
+ setst_stats.redundant_var + setst_stats.redundant_source
+ + setst_stats.redundant_sink);
+
+ fprintf(f,"\n");
+ fprintf(f,"\n------------------------------\n");
+ fprintf(f,"Iteration Optimizations");
+ fprintf(f,"\n------------------------------\n");
+ fprintf(f,"Skipped vars: %d\n",setst_stats.incycle_vars);
+ fprintf(f,"Unchanged vars: %d\n",setst_stats.unchanged_vars);
+ fprintf(f,"Vars w/o sinks: %d\n",setst_stats.no_sinks);
+ fprintf(f,"\n------------------------------\n");
+ fprintf(f,"Cycles");
+ fprintf(f,"\n------------------------------\n");
+ fprintf(f,"Collapsed: %d\n",setst_stats.cycles_collapsed);
+ fprintf(f,"Searched: %d\n",setst_stats.cycles_searched);
+ fprintf(f,"Hit rate: %f\n",
+ ((float)setst_stats.cycles_collapsed)/((float)setst_stats.cycles_searched));
+ fprintf(f,"Average Length: %f\n",
+ ((float)setst_stats.cycles_length) / ((float)setst_stats.cycles_collapsed));
+ fprintf(f,"=====================================\n");
+}
+
diff --git a/libbanshee/engine/setst-sort.h b/libbanshee/engine/setst-sort.h
new file mode 100644
index 00000000000..5aafde398cf
--- /dev/null
+++ b/libbanshee/engine/setst-sort.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef SETST_SORT_H
+#define SETST_SORT_H
+
+#include "banshee.h"
+#include "termhash.h"
+#include "setst-var.h"
+
+extern region setst_region;
+extern term_hash setst_hash;
+
+struct setst_term /* extends gen_e */
+{
+#ifdef NONSPEC
+ sort_kind sort;
+#endif
+ int type;
+ stamp st;
+};
+
+typedef struct setst_term *setst_term;
+
+stamp setst_get_stamp(gen_e e);
+void setst_inclusion(con_match_fn_ptr,gen_e, gen_e);
+
+gen_e setst_zero(void);
+gen_e setst_one(void);
+gen_e setst_fresh(const char *name);
+gen_e setst_fresh_large(const char *name);
+gen_e setst_fresh_small(const char *name);
+gen_e setst_constant(const char *name) deletes;
+gen_e setst_union(gen_e_list exprs) deletes;
+gen_e setst_inter(gen_e_list exprs) deletes;
+bool setst_is_zero(gen_e e);
+bool setst_is_one(gen_e e);
+bool setst_is_var(gen_e e);
+bool setst_is_union(gen_e e);
+bool setst_is_inter(gen_e e);
+bool setst_is_constant(gen_e e);
+
+char *setst_get_constant_name(gen_e e);
+gen_e_list setst_get_union(gen_e e);
+gen_e_list setst_get_inter(gen_e e);
+
+gen_e_list setst_tlb(gen_e e,incl_fn_ptr setst_incl) deletes;
+void setst_set_proj_cache(gen_e e, gen_e elem);
+gen_e_list setst_get_proj_cache(gen_e e);
+
+
+void setst_init(void);
+void setst_reset(void) deletes;
+void setst_print_stats(FILE *f);
+
+extern struct setst_stats setst_stats;
+
+struct setst_stats
+{
+ int fresh;
+ int fresh_large;
+ int fresh_small;
+
+ int distinct_constructors;
+ int hashed_constructors;
+ int distinct_constants;
+ int hashed_constants;
+ int distinct_unions;
+ int filtered_unions;
+ int hashed_unions;
+ int distinct_intersections;
+ int filtered_intersections;
+ int hashed_intersections;
+
+ int redundant_var;
+ int redundant_source;
+ int redundant_sink;
+
+ int added_var;
+ int added_source;
+ int added_sink;
+
+ int incycle_vars;
+ int unchanged_vars;
+ int no_sinks;
+
+ int cycles_searched;
+ int cycles_collapsed;
+ int cycles_length;
+};
+
+
+#endif /* SETST_SORT_H */
+
diff --git a/libbanshee/engine/setst-var.c b/libbanshee/engine/setst-var.c
new file mode 100644
index 00000000000..ba4c59eb5de
--- /dev/null
+++ b/libbanshee/engine/setst-var.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include <regions.h>
+#include "setst-var.h"
+#include "jcollection.h"
+#include "ufind.h"
+#include "bounds.h"
+
+struct st_info
+{
+ stamp st;
+ bounds lbs;
+ bounds sources;
+ bounds sinks;
+ jcoll tlb_cache;
+ const char *name;
+ bool seen;
+ int path_pos;
+ int src_sz;
+ int snk_sz;
+};
+
+typedef struct st_info *st_info;
+
+DECLARE_UFIND(st_elt,st_info)
+
+DEFINE_UFIND(st_elt,st_info)
+
+DEFINE_LIST(setst_var_list,setst_var)
+
+#define get_info(v) (st_elt_get_info((v)->elt))
+
+struct setst_var /* extends gen_e */
+{
+#ifdef NONSPEC
+ sort_kind sort;
+#endif
+ int type;
+ st_elt elt;
+};
+
+bool st_eq(setst_var v1, setst_var v2)
+{
+ return (st_get_stamp(v1) == st_get_stamp(v2));
+}
+
+static setst_var make_var(region r, const char *name, stamp st)
+{
+ setst_var result = ralloc(r,struct setst_var);
+ st_info info = ralloc(r, struct st_info);
+
+ info->st = st;
+ info->lbs = bounds_create(r);
+ info->sources = bounds_create(r);
+ info->sinks = bounds_create(r);
+ info->tlb_cache = NULL;
+ info->name = name ? rstrdup(r,name) : "fv";
+ info->seen = FALSE;
+ info->path_pos = 0;
+ info->src_sz = 0;
+ info->snk_sz = 0;
+
+ result->type = VAR_TYPE;
+ result->elt = new_st_elt(r,info);
+
+
+#ifdef NONSPEC
+ result->sort = setst_sort;
+#endif
+
+ return result;
+}
+
+setst_var st_fresh(region r, const char *name)
+{
+ return make_var(r,name,stamp_fresh());
+}
+
+setst_var st_fresh_large(region r, const char *name)
+{
+ return make_var(r,name,stamp_fresh_large());
+}
+
+setst_var st_fresh_small(region r, const char *name)
+{
+ return make_var(r,name,stamp_fresh_small());
+}
+
+stamp st_get_stamp(setst_var v)
+{
+ return get_info(v)->st;
+}
+
+const char *st_get_name(setst_var v)
+{
+ return get_info(v)->name;
+}
+
+void st_unify(setst_var v,setst_var_list vars)
+{
+ setst_var temp;
+ setst_var_list_scanner scan;
+
+ setst_var_list_scan(vars,&scan);
+
+ while (setst_var_list_next(&scan,&temp))
+ {
+ st_elt_union(v->elt,temp->elt);
+ }
+}
+
+setst_var_list st_get_lbs(setst_var v)
+{
+ return (setst_var_list)bounds_exprs(get_info(v)->lbs);
+}
+
+gen_e_list st_get_sources(setst_var v)
+{
+ return bounds_exprs(get_info(v)->sources);
+}
+
+gen_e_list st_get_sinks(setst_var v)
+{
+ return bounds_exprs(get_info(v)->sinks);
+}
+
+bool st_add_lb(setst_var v, setst_var lb)
+{
+ return bounds_add(get_info(v)->lbs,(gen_e)lb,st_get_stamp(lb));
+}
+
+bool st_add_source(setst_var v, gen_e source, stamp s)
+{
+ return bounds_add(get_info(v)->sources,source,s);
+}
+
+bool st_add_sink(setst_var v, gen_e sink, stamp s)
+{
+ return bounds_add(get_info(v)->sinks,sink,s);
+}
+
+jcoll st_get_tlb_cache(setst_var v)
+{
+ return get_info(v)->tlb_cache;
+}
+
+void st_set_tlb_cache(setst_var v, jcoll j)
+{
+ get_info(v)->tlb_cache = j;
+}
+
+void st_clear_tlb_cache(setst_var v)
+{
+ get_info(v)->tlb_cache = NULL;
+}
+
+gen_e st_get_ub_proj(setst_var v, get_proj_fn_ptr get_proj)
+{
+ return get_proj(st_get_sinks(v));
+}
+static setst_var neq_temp;
+static bool neq (const setst_var v2)
+{
+ return (!(st_get_stamp (neq_temp) == st_get_stamp (v2)));
+}
+void st_repair_bounds(setst_var v1)
+{
+ setst_var_list lbs;
+ neq_temp = v1;
+ lbs = setst_var_list_filter2(st_get_lbs(v1),neq);
+
+ bounds_set(get_info(v1)->lbs,(gen_e_list)lbs);
+}
+
+void st_set_path_pos(setst_var v, int pos)
+{
+ get_info(v)->path_pos = pos;
+}
+
+int st_get_path_pos(setst_var v)
+{
+ return get_info(v)->path_pos;
+}
+
+void st_set_seen(setst_var v, bool b)
+{
+ get_info(v)->seen = b;
+}
+
+bool st_get_seen(setst_var v)
+{
+ return get_info(v)->seen;
+}
+
+void st_set_src_sz(setst_var v, int size)
+{
+ get_info(v)->src_sz = size;
+}
+
+int st_get_src_sz(setst_var v)
+{
+ return get_info(v)->src_sz;
+}
+
+void st_set_snk_sz(setst_var v, int size)
+{
+ get_info(v)->snk_sz = size;
+}
+
+int st_get_snk_sz(setst_var v)
+{
+ return get_info(v)->snk_sz;
+}
+
+
+
+
+
+
diff --git a/libbanshee/engine/setst-var.h b/libbanshee/engine/setst-var.h
new file mode 100644
index 00000000000..6ef2f84a005
--- /dev/null
+++ b/libbanshee/engine/setst-var.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef SETST_VAR_H
+#define SETST_VAR_H
+
+#include "linkage.h"
+#include "banshee.h"
+#include "jcollection.h"
+
+EXTERN_C_BEGIN
+
+typedef struct setst_var *setst_var;
+
+DECLARE_LIST(setst_var_list,setst_var)
+
+bool st_eq(setst_var v1, setst_var v2);
+setst_var st_fresh(region r, const char *name);
+setst_var st_fresh_large(region r, const char *name);
+setst_var st_fresh_small(region r, const char *name);
+stamp st_get_stamp(setst_var v);
+const char *st_get_name(setst_var v);
+void st_unify(setst_var v,setst_var_list vars);
+setst_var_list st_get_lbs(setst_var v);
+gen_e_list st_get_sources(setst_var v);
+gen_e_list st_get_sinks(setst_var v);
+gen_e st_get_ub_proj(setst_var v, get_proj_fn_ptr get_proj);
+bool st_add_lb(setst_var v, setst_var lb);
+bool st_add_source(setst_var v, gen_e source, stamp s);
+bool st_add_sink(setst_var v, gen_e sink, stamp s);
+
+void st_set_path_pos(setst_var v, int pos);
+int st_get_path_pos(setst_var v);
+void st_set_seen(setst_var v, bool b);
+bool st_get_seen(setst_var v);
+void st_set_src_sz(setst_var v, int size);
+int st_get_src_sz(setst_var v);
+void st_set_snk_sz(setst_var v, int size);
+int st_get_snk_sz(setst_var v);
+
+jcoll st_get_tlb_cache(setst_var v);
+void st_set_tlb_cache(setst_var v, jcoll j);
+void st_clear_tlb_cache(setst_var v);
+
+void st_repair_bounds(setst_var v);
+
+EXTERN_C_END
+
+#endif /* SETST_VAR_H */
+
diff --git a/libbanshee/engine/stamp.c b/libbanshee/engine/stamp.c
new file mode 100644
index 00000000000..8a1f5a95faf
--- /dev/null
+++ b/libbanshee/engine/stamp.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include "stamp.h"
+#include "util.h"
+#include "hash.h"
+#include "list.h"
+#define INITIAL_SIZE 32
+#define INITIAL1 0
+#define INITIAL2 2000
+#define INITIAL3 536870911
+#define MIN -1073741824 /* -2^30 */
+#define MAX 1073741824 /* 2^30 */
+
+static hash_table str_hash;
+static region str_hash_rgn;
+
+static int count1 = INITIAL1, count2 = INITIAL2, count3 = INITIAL3;
+static int bounds1 = MIN, bounds2 = 536870911, bounds3 = MAX;
+
+static inline stamp check1(int i)
+{
+ if (i <= bounds1)
+ fail ("Unable to create stamp with small index\n");
+ return i;
+}
+
+static inline stamp check2(int i)
+{
+ if (i > bounds2)
+ fail ("Unable to create a stamp with regular index\n");
+ return i;
+}
+
+static inline stamp check3(int i)
+{
+ if (i >= bounds3)
+ fail ("Unable to create a stamp with large index\n");
+ return i;
+}
+
+stamp stamp_fresh(void)
+{
+ return (check2(++count2));
+}
+
+stamp stamp_fresh_small(void)
+{
+ return (check1(--count1));
+}
+
+stamp stamp_fresh_large(void)
+{
+ return (check3(++count3));
+}
+
+stamp stamp_string(const char *str) deletes
+{
+ long st;
+ assert(str_hash != NULL);
+
+ if (! hash_table_lookup(str_hash,(hash_key)str, (void *)(char *) &st))
+ {
+ st = stamp_fresh();
+ (void)hash_table_insert(str_hash,(hash_key)str,(hash_data) st);
+ }
+ return st;
+}
+
+void stamp_reset(void) deletes
+{
+ count1 = INITIAL1;
+ count2 = INITIAL2;
+ count3 = INITIAL3;
+ hash_table_reset(str_hash);
+ deleteregion_ptr(&str_hash_rgn);
+}
+
+
+
+void stamp_init(void)
+{
+ str_hash_rgn = newregion();
+ str_hash = make_string_hash_table(str_hash_rgn,INITIAL_SIZE,FALSE);
+
+}
+#if 0
+const char *stamp_to_str(region r,stamp st)
+{
+ return inttostr(r,st);
+}
+#endif
diff --git a/libbanshee/engine/stamp.h b/libbanshee/engine/stamp.h
new file mode 100644
index 00000000000..52c55598327
--- /dev/null
+++ b/libbanshee/engine/stamp.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef STAMP_H
+#define STAMP_H
+
+#include <regions.h>
+#include "linkage.h"
+
+EXTERN_C_BEGIN
+
+typedef long stamp;
+
+stamp stamp_fresh(void);
+stamp stamp_fresh_small(void);
+stamp stamp_fresh_large(void);
+
+stamp stamp_string(const char *) deletes;
+
+const char *stamp_to_str(region r,stamp st);
+
+void stamp_reset(void) deletes;
+void stamp_init(void);
+
+EXTERN_C_END
+
+#endif /* STAMP_H */
+
+
+
diff --git a/libbanshee/engine/term-sort.c b/libbanshee/engine/term-sort.c
new file mode 100644
index 00000000000..7503f296338
--- /dev/null
+++ b/libbanshee/engine/term-sort.c
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <regions.h>
+#include <assert.h>
+#include <ansidecl.h>
+#include "term-sort.h"
+
+struct term_constant_ /* extends gen_e */
+{
+#ifdef NONSPEC
+ sort_kind sort;
+#endif
+ int type;
+ stamp st;
+ char *name;
+};
+
+typedef struct term_constant_ *term_constant_;
+
+region term_sort_region;
+term_hash term_sort_hash;
+bool flag_occurs_check = FALSE;
+
+struct term_stats term_stats;
+
+stamp term_get_stamp(gen_e e)
+{
+ if ( ((gen_term)e)->type == VAR_TYPE )
+ return ((gen_term)term_get_ecr(e))->st;
+ else
+ return ((gen_term)e)->st;
+}
+
+gen_e term_fresh(const char *name)
+{
+ term_stats.fresh++;
+ return (gen_e)tv_fresh(term_sort_region,name);
+}
+
+gen_e term_fresh_large(const char *name)
+{
+ term_stats.fresh_large++;
+ return (gen_e)tv_fresh_large(term_sort_region,name);
+}
+
+gen_e term_fresh_small(const char *name)
+{
+ term_stats.fresh_small++;
+ return (gen_e)tv_fresh_small(term_sort_region,name);
+}
+
+
+#ifdef NONSPEC
+static struct gen_term zero = {ZERO_TYPE,term_sort,ZERO_TYPE};
+static struct gen_term one = {ONE_TYPE,term_sort,ONE_TYPE};
+#else
+static struct gen_term zero = {ZERO_TYPE,ZERO_TYPE};
+static struct gen_term one = {ONE_TYPE,ONE_TYPE};
+#endif /* NONSPEC */
+
+gen_e term_zero(void)
+{
+ return (gen_e)&zero;
+}
+
+gen_e term_one(void)
+{
+ return (gen_e)&one;
+}
+
+
+gen_e term_constant(const char *str)
+{
+ stamp st[2];
+ gen_e result;
+ char *name = rstrdup(term_sort_region,str);
+
+ assert (str != NULL);
+
+ st[0] = CONSTANT_TYPE;
+ st[1] = stamp_string(name);
+
+ if ( (result = term_hash_find(term_sort_hash,st,2)) == NULL)
+ {
+ term_constant_ c = ralloc(term_sort_region, struct term_constant_);
+ c->type = CONSTANT_TYPE;
+ c->st = stamp_fresh();
+ c->name = name;
+
+ result = (gen_e) c;
+ term_hash_insert(term_sort_hash,result,st,2);
+
+ return result;
+ }
+
+ else
+ {
+ return result;
+ }
+
+}
+
+static bool term_is_bottom(gen_e e)
+{
+ return (term_is_zero(e) || term_is_var(e));
+}
+
+bool term_is_zero(gen_e e)
+{
+ return ( ((gen_term)term_get_ecr(e))->type == ZERO_TYPE);
+}
+
+bool term_is_one(gen_e e)
+{
+ return ( ((gen_term)term_get_ecr(e))->type == ONE_TYPE);
+}
+
+bool term_is_var(gen_e e)
+{
+ return ( ((gen_term)term_get_ecr(e))->type == VAR_TYPE);
+}
+
+bool term_is_constant(gen_e e)
+{
+ return ( ((gen_term)term_get_ecr(e))->type == CONSTANT_TYPE);
+}
+
+char *term_get_constant_name(gen_e e)
+{
+ gen_e ecr = term_get_ecr(e);
+ if(! term_is_constant(ecr))
+ return NULL;
+ else
+ return ((term_constant_)ecr)->name;
+}
+
+gen_e term_get_ecr(gen_e e)
+{
+ if (((gen_term)e)->type == VAR_TYPE)
+ return tv_get_ecr((term_var)e);
+ else return e;
+}
+
+static void fire_pending(term_var v, gen_e e,
+ con_match_fn_ptr con_match,
+ occurs_check_fn_ptr occurs)
+{
+ gen_e_list_scanner scan;
+ gen_e temp;
+
+ gen_e_list_scan(tv_get_pending(v),&scan);
+ while (gen_e_list_next(&scan,&temp))
+ {
+ term_unify(con_match,occurs,temp,e);
+ }
+}
+
+static bool eq(gen_e e1, gen_e e2)
+{
+ return term_get_ecr(e1) == term_get_ecr(e2);
+}
+
+void term_unify(con_match_fn_ptr con_match, occurs_check_fn_ptr occurs,
+ gen_e a, gen_e b)
+{
+ gen_e e1 = term_get_ecr(a),
+ e2 = term_get_ecr(b);
+
+ if ( eq(e1,e2) )
+ {
+ return;
+ }
+ if (term_is_constant(e1) && term_is_constant(e2))
+ {
+ failure("Inconsistent system of constraints\n");
+ }
+ else if (term_is_var(e1))
+ {
+ term_var v = (term_var)e1;
+
+
+ if (! term_is_bottom(e2))
+ fire_pending(v,e2,con_match,occurs);
+
+ if (term_is_var(e2))
+ tv_unify_vars(v,(term_var)e2);
+ else /* v = e2, e2 is not a var */
+ {
+ if (occurs(v,e2))
+ failure("Unify terms: occurs check failed\n");
+ tv_unify(v,e2);
+ }
+ }
+ else if (term_is_var(e2))
+ {
+ term_var v = (term_var)e2;
+
+ if (! term_is_bottom(e2))
+ fire_pending(v,e1,con_match,occurs);
+
+ /* v = e1, e1 is not a var */
+ if (occurs(v,e1))
+ failure("Unify terms: occurs check failed\n");
+ tv_unify(v,e1);
+
+ }
+ else con_match(e1,e2);
+}
+
+void term_cunify(con_match_fn_ptr con_match, occurs_check_fn_ptr occurs,
+ gen_e e1, gen_e e2)
+{
+ if (term_is_bottom(e1) && term_is_var(e1))
+ {
+ term_var v1 = (term_var)e1;
+ tv_add_pending(v1,e2);
+ }
+ else
+ {
+ term_unify(con_match,occurs,e1,e2);
+ }
+}
+
+static void term_reset_stats(void)
+{
+ term_stats.fresh = 0;
+ term_stats.fresh_small = 0;
+ term_stats.fresh_large = 0;
+}
+
+void term_print_stats(FILE *f)
+{
+ fprintf(f,"\n========== Term Var Stats ==========\n");
+ fprintf(f,"Fresh : %d\n",term_stats.fresh);
+ fprintf(f,"Fresh Small : %d\n",term_stats.fresh_small);
+ fprintf(f,"Fresh Large : %d\n",term_stats.fresh_large);
+ fprintf(f,"=====================================\n");
+}
+
+/* TODO */
+void term_print_constraint_graph(FILE *f ATTRIBUTE_UNUSED)
+{
+}
+
+void term_init(void)
+{
+ term_sort_region = newregion();
+ term_sort_hash = make_term_hash(term_sort_region);
+}
+
+void term_reset(void)
+{
+ term_hash_delete(term_sort_hash);
+ deleteregion_ptr(&term_sort_region);
+
+ term_reset_stats();
+
+ term_sort_region = newregion();
+ term_sort_hash = make_term_hash(term_sort_region);
+}
+
+
+
diff --git a/libbanshee/engine/term-sort.h b/libbanshee/engine/term-sort.h
new file mode 100644
index 00000000000..21a5dc5cff1
--- /dev/null
+++ b/libbanshee/engine/term-sort.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef TERM_SORT_H
+#define TERM_SORT_H
+
+#include <stdio.h>
+#include "banshee.h"
+#include "termhash.h"
+#include "term-var.h"
+
+EXTERN_C_BEGIN
+
+extern bool flag_occurs_check;
+extern region term_sort_region;
+extern term_hash term_sort_hash;
+
+struct gen_term /* extends gen_e */
+{
+#ifdef NONSPEC
+ const sort_kind sort;
+#endif
+ const int type;
+ const stamp st;
+};
+
+typedef struct gen_term *gen_term;
+
+/* return TRUE if v occurs in e, fals otherwise */
+typedef bool (* occurs_check_fn_ptr) (term_var v, gen_e e);
+
+stamp term_get_stamp(gen_e e);
+
+gen_e term_fresh(const char *name);
+gen_e term_fresh_large(const char *name);
+gen_e term_fresh_small(const char *name);
+gen_e term_zero(void);
+gen_e term_one(void);
+gen_e term_constant(const char *name);
+
+bool term_is_zero(gen_e e);
+bool term_is_one(gen_e e);
+bool term_is_var(gen_e e);
+bool term_is_constant(gen_e e);
+
+char *term_get_constant_name(gen_e e);
+gen_e term_get_ecr(gen_e e);
+
+void term_unify(con_match_fn_ptr con_match, occurs_check_fn_ptr occurs,
+ gen_e e1, gen_e e2);
+void term_cunify(con_match_fn_ptr con_match, occurs_check_fn_ptr occurs,
+ gen_e e1, gen_e e2);
+
+void term_print_stats(FILE *f);
+void term_print_constraint_graph(FILE *f);
+
+void term_init(void);
+void term_reset(void);
+
+extern struct term_stats term_stats;
+
+struct term_stats
+{
+ int fresh;
+ int fresh_small;
+ int fresh_large;
+};
+
+EXTERN_C_END
+
+#endif /* TERM_SORT_H */
+
+
+
diff --git a/libbanshee/engine/term-var.c b/libbanshee/engine/term-var.c
new file mode 100644
index 00000000000..9b8e2059871
--- /dev/null
+++ b/libbanshee/engine/term-var.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <regions.h>
+#include <assert.h>
+#include "ufind.h"
+#include "term-var.h"
+
+DECLARE_UFIND(tv_elt,gen_e)
+
+DEFINE_UFIND(tv_elt,gen_e)
+
+DEFINE_LIST(term_var_list,term_var)
+
+struct term_var
+{
+#ifdef NONSPEC
+ sort_kind sort;
+#endif
+ int type;
+ stamp st;
+ gen_e_list pending;
+ const char *name;
+ tv_elt elt;
+};
+
+static term_var make_var(region r, const char *name, stamp st)
+{
+ term_var result = ralloc(r, struct term_var);
+ gen_e info = (gen_e) result;
+
+ result->type = VAR_TYPE;
+ result->st = st;
+ result->pending = new_gen_e_list(r);
+ result->name = name ? rstrdup(r,name) : "fv";
+ result->elt = new_tv_elt(r,info);
+
+ return result;
+}
+
+term_var tv_fresh(region r, const char *name)
+{
+ return make_var(r,name,stamp_fresh());
+}
+
+term_var tv_fresh_small(region r, const char *name)
+{
+ return make_var(r,name,stamp_fresh_small());
+}
+
+term_var tv_fresh_large(region r, const char *name)
+{
+ return make_var(r,name,stamp_fresh_large());
+}
+
+static term_var tv_get_v_ecr(term_var v)
+{
+ term_var ecr = (term_var)tv_get_ecr(v);
+ assert (ecr->type == VAR_TYPE); /* this is a hack, but should be ok */
+
+ return ecr;
+}
+
+const char *tv_get_name(term_var v)
+{
+ return tv_get_v_ecr(v)->name;
+}
+
+gen_e_list tv_get_pending(term_var v)
+{
+ return tv_get_v_ecr(v)->pending;
+}
+
+void tv_add_pending(term_var v,gen_e e)
+{
+ gen_e_list_cons(e,tv_get_v_ecr(v)->pending);
+}
+
+void tv_unify(term_var v, gen_e e)
+{
+ tv_elt_update(v->elt,e);
+
+ assert(tv_get_ecr(v) == e);
+}
+
+static gen_e tv_combine(gen_e e1, gen_e e2)
+{
+ term_var v1 = (term_var)e1,
+ v2 = (term_var)e2;
+
+ if (! (v1 == v2) )
+ gen_e_list_append(tv_get_pending(v1), tv_get_pending(v2));
+
+ return e1;
+}
+
+void tv_unify_vars(term_var v1, term_var v2)
+{
+ tv_elt_unify(tv_combine,v1->elt, v2->elt);
+}
+
+gen_e tv_get_ecr(term_var v)
+{
+ return tv_elt_get_info(v->elt);
+}
diff --git a/libbanshee/engine/term-var.h b/libbanshee/engine/term-var.h
new file mode 100644
index 00000000000..1ca035ff8c6
--- /dev/null
+++ b/libbanshee/engine/term-var.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef TERM_VAR_H
+#define TERM_VAR_H
+
+#include "linkage.h"
+#include "banshee.h"
+
+EXTERN_C_BEGIN
+
+typedef struct term_var *term_var;
+
+DECLARE_LIST(term_var_list,term_var)
+
+term_var tv_fresh(region r, const char *name);
+term_var tv_fresh_small(region r, const char *name);
+term_var tv_fresh_large(region r, const char *name);
+
+const char *tv_get_name(term_var v);
+
+gen_e_list tv_get_pending(term_var v);
+void tv_add_pending(term_var v,gen_e e);
+
+void tv_unify(term_var v, gen_e e);
+void tv_unify_vars(term_var v1, term_var v2);
+
+gen_e tv_get_ecr(term_var v);
+
+
+EXTERN_C_END
+
+#endif /* TERM_VAR_H */
diff --git a/libbanshee/engine/termhash.c b/libbanshee/engine/termhash.c
new file mode 100644
index 00000000000..b42f9ba7304
--- /dev/null
+++ b/libbanshee/engine/termhash.c
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include "termhash.h"
+#include "hash.h"
+#include "termhash.h"
+#include "util.h"
+
+#define UB(n) ((1<<n)-1)
+#define CAP(n) (1<<n)
+#define INITIAL_TABLE_SIZE 8 /* the initial table size is 2^8 */
+
+/* An individual entry in the table consists of an array of stamps */
+/* (same arity as the expr's constructor) in addition to the expr */
+/* itself. */
+typedef struct hash_entry *hash_entry;
+
+/* A term_bucket is a list of entries (an list of exprs that have */
+/* collided after hashing) */
+typedef struct term_bucket *term_bucket;
+
+struct hash_entry
+{
+ int length;
+ stamp *stamps;
+ gen_e e;
+};
+
+struct term_bucket
+{
+ hash_entry entry;
+ struct term_bucket *next;
+};
+
+#define scan_term_bucket(b,var) for(var = b; var; var = var->next)
+
+/* size: initial_table_size + number of rehashes */
+/* capacity: 2^size (for array size) */
+/* ub: 2^size-1 (for array indexing) */
+/* inserts: num of elements inserted into the array */
+struct term_hash
+{
+ term_bucket * term_buckets;
+ region rgn;
+ int ub;
+ int size;
+ int capacity;
+ int inserts;
+};
+
+static int hash(int ub, stamp stamps[], int len);
+static void post_insert(term_hash tab) deletes;
+static void rehash(term_hash tab) deletes;
+static void reinsert(term_hash tab, term_bucket b);
+static void insert(term_hash tab, gen_e e, stamp * stamps, int len);
+static void insert_entry(term_hash tab, struct hash_entry *entry);
+static gen_e walk(term_bucket b, stamp * stamps, int len);
+
+static const int primes[] =
+ { 83, 1789, 5189, 5449, 5659, 6703, 7517, 7699, 8287, 8807, 9067, 9587,
+ 10627, 10939, 11239};
+/*
+static const int prime_1 = 83;
+static const int prime_2 = 1789;
+*/
+static const int initial_table_size = INITIAL_TABLE_SIZE;
+
+term_hash make_term_hash(region rgn)
+{
+ int ub, n;
+ int i;
+
+ region r;
+
+ term_hash tab = ralloc(rgn, struct term_hash);
+
+ r = newregion();
+ ub = UB(initial_table_size);
+ n = CAP(initial_table_size);
+
+
+ tab->term_buckets = rarrayalloc(r, n, term_bucket);
+
+ for (i = 0; i < n; i++)
+ {
+ tab->term_buckets[i] = NULL;
+ }
+
+ tab->rgn = r;
+ tab->ub = ub;
+ tab->size = initial_table_size;
+ tab->capacity = n;
+ tab->inserts = 0;
+ return tab;
+}
+
+void term_hash_delete(term_hash tab) deletes
+{
+ deleteregion(tab->rgn);
+}
+
+gen_e term_hash_find(term_hash tab, stamp stamps[], int len)
+{
+ int hash_val;
+
+ term_bucket b;
+ hash_val = hash(tab->ub, stamps, len);
+ b = tab->term_buckets[hash_val];
+ return walk(b, stamps, len);
+}
+
+static gen_e walk(term_bucket b, stamp stamps[], int len)
+{
+ term_bucket cur;
+ scan_term_bucket(b,cur)
+ {
+ if (len == cur->entry->length
+ && (memcmp(stamps, cur->entry->stamps, sizeof(int)*len) == 0) )
+ return cur->entry->e;
+ }
+ return NULL;
+}
+
+/* Should call t_hash_find to see if a gen_e with the given stamp */
+/* signature is already in the table. If so, insert should return */
+/* true and do nothing. */
+bool term_hash_insert(term_hash tab, gen_e e, stamp * stamps, int len) deletes
+{
+ if (term_hash_find(tab, stamps, len) != NULL)
+ {
+ return TRUE;
+ }
+ insert(tab, e, stamps, len);
+ post_insert(tab);
+ return FALSE;
+}
+
+
+/* Insert an expression e represented by the given stamp array into */
+/* the hash table. */
+static void insert(term_hash tab, gen_e e, stamp stamps[], int len)
+{
+ hash_entry entry;
+ stamp * stamp_cpy;
+ int i;
+
+
+ entry = ralloc(tab->rgn, struct hash_entry);
+
+ stamp_cpy = rarrayalloc(tab->rgn, len, stamp);
+ for (i = 0; i < len; i++)
+ {
+ stamp_cpy[i] = stamps[i];
+ }
+
+ entry->length = len;
+ entry->stamps = stamp_cpy;
+ entry->e = e;
+ insert_entry(tab, entry);
+}
+
+static void insert_entry(term_hash tab, hash_entry entry)
+{
+ int hash_val;
+
+ term_bucket b, new_term_bucket;
+ hash_val = hash(tab->ub, entry->stamps, entry->length);
+ b = tab->term_buckets[hash_val];
+ new_term_bucket = ralloc(tab->rgn, struct term_bucket);
+
+ new_term_bucket->entry = entry;
+ new_term_bucket->next = b;
+ tab->term_buckets[hash_val] = new_term_bucket;
+}
+
+static void post_insert(term_hash tab) deletes
+{
+ if (tab->capacity == ++tab->inserts)
+ {
+ rehash(tab);
+ }
+}
+
+/* Double the size of the hash table and reinsert all of the elements. */
+static void rehash(term_hash tab) deletes
+{
+ region old_rgn;
+ term_bucket * old_term_buckets;
+ int i;
+ int old_table_size = tab->capacity;
+
+ old_term_buckets = tab->term_buckets;
+ tab->capacity *= 2;
+ tab->ub = UB(++tab->size);
+ old_rgn = tab->rgn;
+ tab->rgn = newregion();
+
+
+ tab->term_buckets = rarrayalloc(tab->rgn, tab->capacity, term_bucket);
+ for (i = 0; i < old_table_size; i++)
+ {
+ if (old_term_buckets[i] != NULL && old_term_buckets[i]->entry != NULL)
+ reinsert(tab, old_term_buckets[i]);
+ }
+
+ deleteregion(old_rgn);
+
+
+}
+
+static void reinsert(term_hash tab, term_bucket b)
+{
+ term_bucket cur;
+ scan_term_bucket(b,cur)
+ insert(tab, cur->entry->e, cur->entry->stamps, cur->entry->length);
+}
+
+static int hash(int ub, stamp stamps[], int len)
+{
+ int i, n;
+
+ n = 0;
+ for (i = 0; i < len; i++)
+ {
+ n = (n + (primes[i % 15] * abs(stamps[i]))) & ub;
+ }
+ return n;
+}
+
+
+
+
+
+
diff --git a/libbanshee/engine/termhash.h b/libbanshee/engine/termhash.h
new file mode 100644
index 00000000000..777adc3fd16
--- /dev/null
+++ b/libbanshee/engine/termhash.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef TERMHASH_H
+#define TERMHASH_H
+
+#include "banshee.h"
+#include "stamp.h"
+#include "bool.h"
+
+typedef struct term_hash *term_hash;
+
+term_hash make_term_hash(region r);
+
+gen_e term_hash_find(term_hash h, stamp *st,int length);
+
+bool term_hash_insert(term_hash h, gen_e e, stamp *st, int length) deletes;
+
+void term_hash_delete(term_hash h) deletes;
+
+#endif /* TERMHASH_H */
diff --git a/libbanshee/engine/ufind.c b/libbanshee/engine/ufind.c
new file mode 100644
index 00000000000..545171812bb
--- /dev/null
+++ b/libbanshee/engine/ufind.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include "ufind.h"
+#include "assert.h"
+
+
+enum uf_type {uf_ecr,uf_link};
+typedef enum uf_type uf_type;
+
+struct uf_element
+{
+ uf_type type;
+ int rank;
+ void *info;
+ struct uf_element *link;
+};
+
+struct uf_element *new_uf_element(region r, void *info)
+{
+ struct uf_element *result;
+
+ result = ralloc(r, struct uf_element);
+
+ result->type = uf_ecr;
+ result->rank = 0;
+ result->info = info;
+ result->link = NULL;
+
+ return result;
+}
+
+static struct uf_element *find(struct uf_element *e)
+{
+
+ if (e->type == uf_ecr)
+ return e;
+
+ else if (e->link->type == uf_link)
+ {
+ struct uf_element *temp = e->link;
+
+ e->link = e->link->link;
+
+ return find(temp);
+ }
+
+ else
+ return e->link;
+}
+
+bool uf_union(struct uf_element *a, struct uf_element *b)
+{
+ struct uf_element *e1 = find(a);
+ struct uf_element *e2 = find(b);
+
+ if ( e1 == e2 )
+ return FALSE;
+
+ else if (e1->rank < e2->rank)
+ {
+ e1->type = uf_link;
+ e1->link = e2;
+
+ return TRUE;
+ }
+
+ else if (e1->rank > e2->rank)
+ {
+ e2->type = uf_link;
+ e2->link = e1;
+
+ return TRUE;
+ }
+
+ else
+ {
+ e2->rank++;
+
+ e1->type = uf_link;
+ e1->link = e2;
+
+ return TRUE;
+ }
+
+}
+
+bool uf_unify(combine_fn_ptr combine,
+ struct uf_element *a, struct uf_element *b)
+{
+ struct uf_element *e1 = find(a);
+ struct uf_element *e2 = find(b);
+
+ if ( e1 == e2 )
+ return FALSE;
+
+ else if (e1->rank < e2->rank)
+ {
+ e2->info = combine(e2->info,e1->info);
+ e1->type = uf_link;
+ e1->link = e2;
+
+ return TRUE;
+ }
+
+ else if (e1->rank > e2->rank)
+ {
+ e1->info = combine(e1->info,e2->info);
+ e2->type = uf_link;
+ e2->link = e1;
+
+ return TRUE;
+ }
+
+ else
+ {
+ e2->info = combine(e2->info, e1->info);
+
+ e2->rank++;
+ e1->type = uf_link;
+ e1->link = e2;
+
+ return TRUE;
+ }
+}
+
+
+
+void *uf_get_info(struct uf_element *e)
+{
+ return find(e)->info;
+}
+
+
+bool uf_eq(struct uf_element *e1,struct uf_element *e2)
+{
+ return (find(e1) == find(e2));
+}
+
+void uf_update(struct uf_element *e,uf_info i)
+{
+ find(e)->info = i;
+}
+
+
+
+
+
+
diff --git a/libbanshee/engine/ufind.h b/libbanshee/engine/ufind.h
new file mode 100644
index 00000000000..5068530114e
--- /dev/null
+++ b/libbanshee/engine/ufind.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef UFIND_H
+#define UFIND_H
+
+#include <regions.h>
+#include "linkage.h"
+#include "bool.h"
+
+EXTERN_C_BEGIN
+
+struct uf_element;
+
+typedef struct uf_element *uf_element;
+typedef void *uf_info;
+
+typedef uf_info (*combine_fn_ptr)(uf_info,uf_info);
+
+struct uf_element *new_uf_element(region r,uf_info i);
+uf_info uf_get_info(struct uf_element *);
+bool uf_unify(combine_fn_ptr,struct uf_element *,struct uf_element *);
+bool uf_union(struct uf_element *,struct uf_element *);
+bool uf_eq(struct uf_element *,struct uf_element *);
+void uf_update(struct uf_element *,uf_info i);
+
+#define DECLARE_UFIND(name,type) \
+typedef struct name *name; \
+typedef type (* name ## _combine_fn_ptr)(type info1,type info2); \
+name new_ ## name(region r, type info); \
+type name ## _get_info(name); \
+bool name ## _unify(name ## _combine_fn_ptr,name e1, name e2); \
+bool name ## _union(name e1, name e2); \
+bool name ## _eq(name e1, name e2); \
+void name ## _update(name e1, type info);
+
+#define DEFINE_UFIND(name,type) \
+name new_ ## name(region r, type info) \
+{ \
+ return (name)new_uf_element(r,info);\
+}\
+type name ## _get_info(name elem) \
+{ \
+ return (type)uf_get_info((struct uf_element *)elem);\
+} \
+bool name ## _unify(name ## _combine_fn_ptr cmb,name e1, name e2) \
+{ \
+ return uf_unify((combine_fn_ptr)cmb,(struct uf_element *)e1,(struct uf_element *)e2); \
+} \
+bool name ## _union(name e1, name e2) \
+{ \
+ return uf_union((struct uf_element *)e1,(struct uf_element *)e2); \
+}\
+bool name ## _eq(name e1, name e2) \
+{ \
+ return uf_eq((struct uf_element *)e1,(struct uf_element *)e2); \
+} \
+void name ##_update(name e1, type info) \
+{ \
+ uf_update((struct uf_element *)e1,(uf_info)info); \
+} \
+
+EXTERN_C_END
+
+#endif /* UFIND_H */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libbanshee/engine/util.c b/libbanshee/engine/util.c
new file mode 100644
index 00000000000..8989956b70a
--- /dev/null
+++ b/libbanshee/engine/util.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <ctype.h>
+#include <math.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include "buffer.h"
+#include "util.h"
+
+/* Panic with a message */
+static void vfail(const char *fmt, va_list args) __attribute__((__noreturn__));
+
+static void vfail(const char *fmt, va_list args)
+{
+ vfprintf(stderr, fmt, args);
+ fflush(stdin);
+ fflush(stderr);
+ fflush(stdout);
+ sync();
+ fsync(STDIN_FILENO);
+ fsync(STDERR_FILENO);
+ fsync(STDOUT_FILENO);
+ abort();
+ while (1); /* Work around stupid gcc-2.96-85 bug */
+}
+
+/* Panic with a nice message */
+void __fail(const char *file, unsigned int line,
+ const char *func __attribute__((unused)),
+ const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ fprintf(stderr, "\n%s:%u ", file, line);
+ vfail(fmt, args);
+}
+
+#ifndef HAVE_VARIADIC_MACROS
+/* Panic with a not-quite-as-nice message */
+void fail(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vfail(fmt, args);
+}
+#endif
+
+void failure(const char *message)
+{
+ fprintf(stderr,message);
+ exit(1);
+}
+
+/* Concatenate 2 strings, allocating space in r for the result */
+char *rstrcat(region r, const char *s1, const char *s2)
+{
+ char *result = rarrayalloc(r, strlen(s1)+strlen(s2)+1, char);
+ result[0] = '\0';
+ strcat(result, s1);
+ strcat(result, s2);
+ return result;
+}
+
+/* Concatenate n strings, allocating space in r for the result. The
+ last argument should be a null pointer. */
+char *rstrscat(region r, ...)
+{
+ char *result;
+ int len = 0;
+ const char *s;
+ va_list args;
+
+ va_start(args, r);
+ while ((s = va_arg(args, const char *)))
+ len += strlen(s);
+ result = rarrayalloc(r, len+1, char);
+ result[0] = '\0';
+
+ va_start(args, r);
+ while ((s = va_arg(args, const char *)))
+ strcat(result, s);
+
+ return result;
+}
+#if 0
+/* Convert an integer to a string, storing the result in r */
+const char *inttostr(region r, int i)
+{
+ char *result;
+ int width;
+
+ if (i == 0)
+ width = 1;
+ else
+ width = (int) (floor(log10(abs((double) i))) + 1);
+ if (i<0) width++;
+
+ printf("i=%d, width=%d\n", i, width);
+ assert(width >0);
+
+ result = rarrayalloc(r, width + 1, char);
+ if (snprintf(result, width + 1, "%d", i) == -1) {
+ printf("i=%d, width=%d\n", i, width);
+ fail ("inttostr width wrong\n");
+ }
+ return result;
+}
+#endif
+
+/* sprintf a string, allocating space in r for the result */
+char *rsprintf(region r, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ return rvsprintf(r, fmt, args);
+}
+
+char *rvsprintf(region r, const char *fmt, va_list args)
+{
+ growbuf buf = growbuf_new(r, 100);
+ gvprintf(buf, fmt, args);
+ return growbuf_contents(buf);
+}
+
+/* Space for the ASCII representation of a pointer -- 2 hex chars per
+ byte, plus 3 chars for 0x prefix and trailing \0 */
+#define PTR_ASCII_SIZE ((int) (3 + sizeof(void *)*2))
+
+/* Convert a pointer to an ascii string with leading 0x. Re-uses
+ internal buffer. */
+char *ptr_to_ascii(void *ptr) {
+ static char addr[PTR_ASCII_SIZE];
+ int nchars;
+
+ nchars = snprintf(addr, PTR_ASCII_SIZE, "%p", ptr);
+ if (nchars == -1 || nchars >= PTR_ASCII_SIZE)
+ fail("Unable to convert ptr to ascii (need %d bytes, have %d)\n",
+ nchars, PTR_ASCII_SIZE);
+ return addr;
+}
+
+/* Convert a pointer to an integer */
+long ptr_hash(void *ptr)
+{
+ return (long) ptr;
+}
+
+/* Return TRUE iff ptr1 == ptr2 */
+bool ptr_eq(void *ptr1, void *ptr2)
+{
+ return ptr1 == ptr2;
+}
+
+/* Return TRUE iff s1 == s2 */
+bool str_eq(const char *s1, const char *s2)
+{
+ return (strcmp(s1, s2) == 0);
+}
+
+/* A total ordering on pointers. Returns 0 if ptr1 = ptr2, a value <0
+ if ptr1 < ptr2, or a value >0 if ptr1 > ptr2. */
+int ptr_cmp(const void *ptr1, const void *ptr2)
+{
+ return (char *) ptr1 - (char *) ptr2;
+}
+
+int min(int a, int b) { if (a < b) return a; else return b; }
+int max(int a, int b) { if (a < b) return b; else return a; }
+/* int abs(int a) { if (a < 0) return -a; else return a; } */
diff --git a/libbanshee/engine/util.h b/libbanshee/engine/util.h
new file mode 100644
index 00000000000..1d13147da08
--- /dev/null
+++ b/libbanshee/engine/util.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2000-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef UTIL_H
+#define UTIL_H
+
+#include <assert.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <regions.h>
+#include "compiler.h"
+#include "linkage.h"
+#include "bool.h"
+
+
+EXTERN_C_BEGIN
+
+#ifdef HAVE_VARIADIC_MACROS
+#define fail(args...) __fail(__FILE__, __LINE__, __FUNCTION__, args)
+#else
+void fail(const char *fmt, ...);
+#endif
+
+void __fail(const char *file, unsigned int line,
+ const char *func, const char *fmt, ...) __attribute__ ((__noreturn__));
+
+
+/* insist(action) is like assert(action), but action may have
+ side-effects */
+#ifdef NDEBUG
+# define insist(action) (action)
+#else
+# define insist assert
+#endif
+
+#ifdef NDEBUG
+# define insistnot(action) (action)
+#else
+# define insistnot(action) assert(!(action))
+#endif
+
+void failure(const char *message);
+
+/* Concatenate 2 strings, allocating space in r for the result */
+char *rstrcat(region, const char *, const char *);
+
+/* Concatenate n strings, allocating space in r for the result. The
+ last argument should be a null pointer. */
+char *rstrscat(region, ...);
+
+/* Convert an integer to a string, storing the result in r */
+const char *inttostr(region r, int);
+
+/* sprintf a string, allocating space in r for the result */
+char *rsprintf(region r, const char *fmt, ...);
+char *rvsprintf(region r, const char *fmt, va_list args);
+
+/* Convert a pointer to an ascii string with leading 0x. Re-uses
+ internal buffer. */
+char *ptr_to_ascii(void *ptr);
+
+/* Convert a pointer to an integer */
+long ptr_hash(void *ptr);
+
+/* Return TRUE iff ptr1 == ptr2 */
+bool ptr_eq(void *ptr1, void *ptr2);
+
+/* Return TRUE iff s1 == s2 */
+bool str_eq(const char *s1, const char *s2);
+
+/* A total ordering on pointers. Returns 0 if ptr1 = ptr2, a value <0
+ if ptr1 < ptr2, or a value >0 if ptr1 > ptr2. */
+int ptr_cmp(const void *ptr1, const void *ptr2);
+
+extern inline int min(int, int);
+extern inline int max(int, int);
+extern inline int min(int a, int b) { if (a < b) return a; else return b; }
+extern inline int max(int a, int b) { if (a < b) return b; else return a; }
+EXTERN_C_END
+
+#endif
diff --git a/libbanshee/libcompat/Makefile.am b/libbanshee/libcompat/Makefile.am
new file mode 100644
index 00000000000..dae6ac0052f
--- /dev/null
+++ b/libbanshee/libcompat/Makefile.am
@@ -0,0 +1,4 @@
+AM_CFLAGS = -I$(srcdir)/../engine -I$(srcdir)/../include -I. -Ddeletes= -Dtraditional= -Dsameregion= -Dparentptr= @ac_libbanshee_warn_cflags@
+noinst_LIBRARIES = libbansheecompat.a
+libbansheecompat_a_SOURCES = regions.c radix-tree.c
+
diff --git a/libbanshee/libcompat/Makefile.in b/libbanshee/libcompat/Makefile.in
new file mode 100644
index 00000000000..48e4249ee3d
--- /dev/null
+++ b/libbanshee/libcompat/Makefile.in
@@ -0,0 +1,365 @@
+# Makefile.in generated by automake 1.7.6 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+ac_libbanshee_warn_cflags = @ac_libbanshee_warn_cflags@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build_alias = @build_alias@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+AM_CFLAGS = -I$(srcdir)/../engine -I$(srcdir)/../include -I. -Ddeletes= -Dtraditional= -Dsameregion= -Dparentptr= @ac_libbanshee_warn_cflags@
+noinst_LIBRARIES = libbansheecompat.a
+libbansheecompat_a_SOURCES = regions.c radix-tree.c
+subdir = libcompat
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+
+libbansheecompat_a_AR = $(AR) cru
+libbansheecompat_a_LIBADD =
+am_libbansheecompat_a_OBJECTS = regions.$(OBJEXT) radix-tree.$(OBJEXT)
+libbansheecompat_a_OBJECTS = $(am_libbansheecompat_a_OBJECTS)
+
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/../depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/radix-tree.Po ./$(DEPDIR)/regions.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = $(libbansheecompat_a_SOURCES)
+DIST_COMMON = Makefile.am Makefile.in
+SOURCES = $(libbansheecompat_a_SOURCES)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu libcompat/Makefile
+Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+
+AR = ar
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libbansheecompat.a: $(libbansheecompat_a_OBJECTS) $(libbansheecompat_a_DEPENDENCIES)
+ -rm -f libbansheecompat.a
+ $(libbansheecompat_a_AR) libbansheecompat.a $(libbansheecompat_a_OBJECTS) $(libbansheecompat_a_LIBADD)
+ $(RANLIB) libbansheecompat.a
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radix-tree.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regions.Po@am__quote@
+
+distclean-depend:
+ -rm -rf ./$(DEPDIR)
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@ fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@ fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
+uninstall-info-am:
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$tags$$unique" \
+ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique
+
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkinstalldirs) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES)
+
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+
+distclean-am: clean-am distclean-compile distclean-depend \
+ distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-noinstLIBRARIES ctags distclean distclean-compile \
+ distclean-depend distclean-generic distclean-tags distdir dvi \
+ dvi-am info info-am install install-am install-data \
+ install-data-am install-exec install-exec-am install-info \
+ install-info-am install-man install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+ uninstall-am uninstall-info-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libbanshee/libcompat/alloc.c b/libbanshee/libcompat/alloc.c
new file mode 100644
index 00000000000..7f2cfd369b2
--- /dev/null
+++ b/libbanshee/libcompat/alloc.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 1999-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+/* TBD: recover unusued portions of pages for use as individual pages */
+
+#include <stddef.h>
+#include "regions.h"
+
+static void alloc_block(region r, struct allocator *a, struct ablock *blk,
+ void **p1, int s1, int a1, void **p2, int s2, int a2,
+ size_t blksize, int needsclear)
+{
+ struct page *newp;
+ char *mem1, *mem2;
+
+ mem1 = PALIGN(blk->allocfrom, a1);
+ mem2 = PALIGN(mem1 + s1, a2);
+
+ /* Can't use last byte of page (pointers to the byte after an object are
+ valid) */
+ if (mem2 + s2 >= blk->base + blksize)
+ {
+ if (blksize == RPAGESIZE)
+ {
+ newp = alloc_single_page(a->pages);
+ a->pages = newp;
+ blk->allocfrom = (char *)newp + offsetof(struct page, previous);
+ set_region(newp, 1, r);
+ }
+ else
+ {
+ newp = alloc_pages(blksize >> RPAGELOG, a->bigpages);
+ a->bigpages = newp;
+ blk->allocfrom = (char *)newp + offsetof(struct page, previous);
+ set_region(newp, blksize >> RPAGELOG, r);
+ }
+ blk->base = (char *)newp;
+
+ if (needsclear)
+ preclear(blk->allocfrom, blksize - (blk->allocfrom - (char *)newp));
+ mem1 = PALIGN(blk->allocfrom, a1);
+ mem2 = PALIGN(mem1 + s1, a2);
+ }
+
+ ASSERT_INUSE(blk->base, r);
+ blk->allocfrom = mem2 + s2;
+
+ *p1 = mem1;
+ *p2 = mem2;
+}
+
+void qalloc(region r, struct allocator *a, void **p1, int s1, int a1,
+ void **p2, int s2, int a2, int needsclear)
+{
+ struct page *p;
+ char *mem;
+ int npages;
+ int n = ALIGN(s1, a2) + s2; /* Yes, this is correct (see alloc_block) */
+
+ if (n <= RPAGESIZE / K)
+ {
+ alloc_block(r, a, &a->page, p1, s1, a1, p2, s2, a2, RPAGESIZE,
+ needsclear);
+ return;
+ }
+ if (n <= RPAGESIZE)
+ {
+ alloc_block(r, a, &a->superpage, p1, s1, a1, p2, s2, a2,
+ K * RPAGESIZE, needsclear);
+ return;
+ }
+ if (n <= RPAGESIZE * K)
+ {
+ alloc_block(r, a, &a->hyperpage, p1, s1, a1, p2, s2, a2,
+ K * K * RPAGESIZE, needsclear);
+ return;
+ }
+
+ npages = (n + ALIGN(offsetof(struct page, previous), a1) + RPAGESIZE - 1)
+ >> RPAGELOG;
+ p = alloc_pages(npages, a->bigpages);
+ a->bigpages = p;
+ set_region(p, npages, r);
+
+ mem = (char *)p + offsetof(struct page, previous);
+ *p1 = PALIGN(mem, a1);
+ *p2 = PALIGN((char *) *p1 + s1, a2);
+ if (needsclear)
+ preclear(*p2, s2);
+}
+
+void free_all_pages(region r, struct allocator *a)
+/* Assumes freepages_lock held */
+{
+ struct page *p, *next;
+
+ for (p = a->pages; p; p = next)
+ {
+ next = p->next;
+ free_single_page(r, p);
+ }
+ for (p = a->bigpages; p; p = next)
+ {
+ next = p->next;
+ free_pages(r, p);
+ }
+}
diff --git a/libbanshee/libcompat/pages.c b/libbanshee/libcompat/pages.c
new file mode 100644
index 00000000000..9e85e9baef0
--- /dev/null
+++ b/libbanshee/libcompat/pages.c
@@ -0,0 +1,459 @@
+/*
+ * Copyright (c) 1999-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#include <limits.h>
+
+typedef __rcintptr pageid;
+
+#if 0
+#define FREEPAGE ((region)-1) /* Id of a free page */
+#else
+#define FREEPAGE (&zeroregion)
+#endif
+#ifdef NMEMDEBUG
+#define ASSERT_FREE(p)
+#define ASSERT_INUSE(p, r)
+#else
+#define ASSERT_FREE(p) assert(regionof(p) == FREEPAGE)
+#ifdef DUPLICATES
+#define ASSERT_INUSE(p, r) assert(regionof(p) == r->base)
+#else
+#define ASSERT_INUSE(p, r) assert(regionof(p) == r)
+#endif
+#endif
+
+/* Page allocator for region-based memory management */
+/* TBD: special free list for size == K ?? */
+
+#define PAGECOUNTBITS (CHAR_BIT * sizeof(pageid) - 1)
+
+struct page
+{
+ /* Next page in region or in free list */
+ struct page *next;
+
+ /* Doubly linked list of pages sorted by address */
+ struct page *next_address, *prev_address;
+
+ /* number of pages in this allocation unit. Negative for free pages. */
+ pageid pagecount : PAGECOUNTBITS;
+
+ unsigned int free : 1;
+
+ /* Only in free pages not in the single_pages list */
+ struct page *previous;
+};
+
+/* The pages are kept in a single list sorted by address via the
+ next_address and prev_address fields. The first page's prev_address and
+ the last page's next_address fields points to pages_byaddress.
+ page_byaddress.next_address is the first page
+ page_byaddress.prev_address is the last page
+
+ This list is used for coalescing operations.
+*/
+static struct page pages_byaddress;
+
+struct page *alloc_single_page(struct page *next);
+void free_single_page(region r, struct page *p);
+
+struct page *alloc_pages(int n, struct page *next);
+void free_pages(region r, struct page *p);
+
+
+/* a list of free individual pages */
+struct page *single_pages;
+
+/* free pages (not including those in single_pages) */
+struct page *unused_pages;
+
+static void init_pages(void)
+{
+ pages_byaddress.next_address = &pages_byaddress;
+ pages_byaddress.prev_address = &pages_byaddress;
+}
+
+static void insertbefore_address(struct page *p, struct page *before)
+{
+ p->prev_address = before->prev_address;
+ p->next_address = before;
+ before->prev_address = p;
+ p->prev_address->next_address = p;
+}
+
+static void unlink_address(struct page *p)
+{
+ p->prev_address->next_address = p->next_address;
+ p->next_address->prev_address = p->prev_address;
+}
+
+static void addbyaddress(struct page *p)
+{
+ struct page *address_scan;
+
+ /* Warning: this is slow. Calls to it should not be frequent (once app
+ reaches a steady state of memory usage). */
+
+ for (address_scan = pages_byaddress.next_address; ;
+ address_scan = address_scan->next_address)
+ if (p < address_scan || address_scan == &pages_byaddress)
+ {
+ insertbefore_address(p, address_scan);
+ return;
+ }
+}
+
+/* Doubly linked page list management */
+void addfront(struct page **list, struct page *p)
+/* Effects: Adds p to the front of doubly-linked list list */
+{
+ p->previous = NULL;
+ p->next = *list;
+ if (*list) (*list)->previous = p;
+ *list = p;
+}
+
+void unlink_page(struct page **list, struct page *p)
+/* Effects: Remove p from its doubly linked list */
+{
+ if (p->previous)
+ p->previous->next = p->next;
+ else
+ *list = p->next;
+ if (p->next)
+ p->next->previous = p->previous;
+}
+
+void *region_get_mem(size_t s)
+{
+ void *mem = malloc(s + RPAGESIZE - 1);
+
+ return (void *)ALIGN((__rcintptr)mem, RPAGESIZE);
+}
+
+/* Page to region map management */
+/* ----------------------------- */
+
+RADIX_TREE(__rcregionmap);
+
+static void set_page_region(pageid pagenb, region r)
+{
+ radix_tree_delete (&__rcregionmap, pagenb);
+ radix_tree_insert (&__rcregionmap, pagenb, r);
+}
+
+#define page_region(pagenb) (radix_tree_lookup (&__rcregionmap, (pagenb)))
+
+void set_region(struct page *p, int npages, region r)
+{
+ pageid pnb = PAGENB(p);
+
+ while (npages-- > 0)
+ set_page_region(pnb++, r);
+}
+
+/* Mark the memory range from 'from' (inclusive) to 'to' (exclusive)
+ as belonging to region with id 'rid' */
+void set_region_range(void *from, void *to, region r)
+{
+ pageid first = PAGENB(from), last = PAGENB((pageid)to - 1);
+
+ while (first <= last)
+ set_page_region(first++, r);
+}
+
+/* Multi-page allocation management */
+/* -------------------------------- */
+
+struct page *alloc_new(int n, struct page *next)
+/* Assumes freepages_lock held */
+{
+ struct page *newp = region_get_mem(n << RPAGELOG);
+
+ if (!newp)
+ {
+ if (nomem_h)
+ nomem_h();
+ abort();
+ }
+ assert(!((long)newp & (RPAGESIZE - 1)));
+
+ newp->next = next;
+ newp->pagecount = n;
+ newp->free = 0;
+ addbyaddress(newp);
+#ifndef NMEMDEBUG
+ {
+ pageid i, pnb = PAGENB(newp);
+
+ for (i = pnb; i < pnb + n; i++)
+ set_page_region(i, FREEPAGE);
+ }
+#endif
+
+ return newp;
+}
+
+struct page *alloc_split(struct page *split, int n, struct page *next)
+/* Assumes freepages_lock held */
+{
+#ifndef NMEMDEBUG
+ /* These pages had better be free */
+ pageid i, pnb = PAGENB(split);
+
+ assert(split->pagecount >= n);
+ for (i = pnb; i < pnb + split->pagecount; i++)
+ assert(page_region(i) == FREEPAGE);
+#endif
+ if (split->pagecount > n)
+ {
+ struct page *splitoff;
+
+ /* Keep first part of block */
+ split->pagecount -= n;
+ /* Return latter part of block */
+ splitoff = split;
+ split = (struct page *)((char *)split + (split->pagecount << RPAGELOG));
+
+ /* Update the by adress list */
+ insertbefore_address(split, splitoff->next_address);
+ }
+ else
+ {
+ /* remove split from list */
+ unlink_page(&unused_pages, split);
+ }
+ split->next = next;
+ split->pagecount = n;
+ split->free = 0;
+
+ return split;
+}
+
+struct page *alloc_pages(int n, struct page *next)
+{
+ struct page *best;
+ int bestn;
+ struct page *scan;
+
+ assert(n >= K);
+
+ scan = unused_pages;
+ /* Find first fit */
+ for (;;)
+ {
+ if (!scan)
+ return alloc_new(n, next);
+
+ if (scan->pagecount >= n) break;
+ scan = scan->next;
+ }
+
+ /* Now find best fit */
+ best = scan;
+ bestn = scan->pagecount;
+ for (;;)
+ {
+ scan = scan->next;
+ if (!scan)
+ return alloc_split(best, n, next);
+
+ if (scan->pagecount >=n && scan->pagecount < bestn)
+ {
+ best = scan;
+ bestn = scan->pagecount;
+ }
+ }
+}
+
+static void coalesce(struct page *p)
+{
+ struct page *prev = p->prev_address, *next;
+
+ p->free = 1;
+
+ /* Coalesce with predecessor ? */
+ if (prev->free && (char *)prev + (prev->pagecount << RPAGELOG) == (char *)p)
+ {
+ prev->pagecount += p->pagecount;
+ unlink_address(p);
+ p = prev;
+ }
+ else /* No, add to free pages list */
+ addfront(&unused_pages, p);
+
+ next = p->next_address;
+ /* Coalesce with successor ? */
+ if (next->free && (char *)p + (p->pagecount << RPAGELOG) == (char *)next)
+ {
+ unlink_page(&unused_pages, next);
+ p->pagecount += next->pagecount;
+ unlink_address(next);
+ }
+}
+
+void free_pages(region r, struct page *p)
+/* Assumes freepages_lock held */
+{
+#ifndef NMEMDEBUG
+ pageid i, pnb = PAGENB(p);
+
+ for (i = pnb; i < pnb + p->pagecount; i++)
+ {
+ assert(page_region(i) == r);
+ set_page_region(i, FREEPAGE);
+ }
+#endif
+
+ coalesce(p);
+}
+
+
+/* Single page management */
+/* ---------------------- */
+
+static int single_page_count;
+
+static void add_single_pages(struct page *base)
+/* Effects: Adds pages at base to the single_pages list */
+{
+ pageid n = base->pagecount;
+ struct page *prev = base->prev_address, *basenext = base->next_address,
+ *next;
+
+ single_page_count += n;
+
+ for (;;)
+ {
+ ASSERT_FREE(base);
+ base->free = 0; /* Not free so that coalesce won't steal these back */
+ base->prev_address = prev;
+ prev = base;
+ base->next = single_pages;
+ single_pages = base;
+ if (--n == 0)
+ break;
+ next = (struct page *)((char *)base + RPAGESIZE);
+ base->next_address = next;
+ base = next;
+ }
+ base->next_address = basenext;
+ basenext->prev_address = base;
+}
+
+void scavenge_single_pages(int n)
+{
+ /* Add n pages to the single_pages list */
+ struct page *scan, *best;
+ __rcintptr bestn;
+
+ /* Take any group in unused_pages that is <= n or < K.
+ Remember smallest entry > n too. This is sortof equivalent to
+ a best fit where we allow partial allocations to make up a whole */
+ best = NULL;
+ bestn = (__rcintptr)1 << (sizeof(__rcintptr) * CHAR_BIT - 2);
+ scan = unused_pages;
+ while (scan)
+ {
+ /* The pages < K can't be used for anything but single pages so we
+ might as well grab them even if they are a little too big */
+ if (scan->pagecount <= n || scan->pagecount < K)
+ {
+ struct page *adding = scan;
+
+ scan = scan->next;
+ n -= adding->pagecount;
+ unlink_page(&unused_pages, adding);
+ add_single_pages(adding);
+ if (n <= 0) return;
+ }
+ else
+ {
+ if (scan->pagecount < bestn)
+ {
+ bestn = scan->pagecount;
+ best = scan;
+ }
+ scan = scan->next;
+ }
+ }
+ /* Still not enough. Split the best block if there is one, allocate
+ new pages otherwise */
+ if (!best)
+ add_single_pages(alloc_new(n, NULL));
+ else if (best->pagecount - n < K)
+ {
+ unlink_page(&unused_pages, best);
+ add_single_pages(best);
+ }
+ else
+ add_single_pages(alloc_split(best, n, NULL));
+}
+
+struct page *alloc_single_page(struct page *next)
+{
+ struct page *p;
+
+ if (!single_pages)
+ {
+ scavenge_single_pages(PAGE_GROUP_SIZE);
+ }
+ ASSERT_FREE(single_pages);
+ p = single_pages;
+ single_pages = p->next;
+ p->next = next;
+
+ single_page_count--;
+
+ return p;
+}
+
+void free_single_page(region r, struct page *p)
+/* Assumes freepages_lock held */
+{
+#ifndef NMEMDEBUG
+ ASSERT_INUSE(p, r);
+ set_page_region(PAGENB(p), FREEPAGE);
+#endif
+
+ /* Once free list is big enough just coalesce the pages.
+ The actual threshold to use might merit further study (something
+ adaptive ? e.g., proportional to allocated single pages) */
+ if (single_page_count > PAGE_GROUP_SIZE * 2)
+ {
+ p->pagecount = 1;
+ coalesce(p);
+ }
+ else
+ {
+ p->next = single_pages;
+ single_pages = p;
+ single_page_count++;
+ }
+}
diff --git a/libbanshee/libcompat/profile.c b/libbanshee/libcompat/profile.c
new file mode 100644
index 00000000000..0a30a55e41e
--- /dev/null
+++ b/libbanshee/libcompat/profile.c
@@ -0,0 +1,521 @@
+/*
+ * Copyright (c) 1999-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <signal.h>
+#undef REGION_PROFILE
+#include "regions.h"
+#include "profile.h"
+
+typedef struct Alloc_info
+{
+ struct Alloc_info *next;
+ char *file;
+ int line;
+ unsigned long size;
+ unsigned long calls;
+} *ainfo;
+
+static ainfo ainfos = NULL;
+static region profile_region = NULL;
+
+/* perror(s) then exit */
+void pfail(const char *s)
+{
+ perror(s);
+ exit(EXIT_FAILURE);
+}
+
+/**************************************************************************
+ * *
+ * Log information about an allocation -- generic *
+ * *
+ **************************************************************************/
+
+static int registered_exit = 0;
+
+static ainfo find_ainfo(char *file, int line)
+{
+ ainfo ai;
+
+ for (ai = ainfos; ai; ai = ai->next)
+ if (line == ai->line && !strcmp(file, ai->file))
+ return ai;
+
+ if (!registered_exit)
+ {
+ if (atexit(profile))
+ fprintf(stderr, "Registration of profile at exit failed\n");
+ registered_exit = 1;
+ }
+
+ if (!profile_region)
+ profile_region = newregion();
+ ai = ralloc(profile_region, struct Alloc_info);
+ ai->file = file;
+ ai->line = line;
+ ai->size = 0;
+ ai->calls = 0;
+ ai->next = ainfos;
+ ainfos = ai;
+ return ai;
+}
+
+/**************************************************************************
+ * *
+ * Log information about an allocation -- GCC *
+ * *
+ * WARNING: This code uses __builtin_return_address, a non-portable *
+ * feature of gcc, to trace the call chain back. You'll also get ugly *
+ * output unless the addr2line (in GNU binutils) is installed. *
+ * *
+ * ANOTHER WARNING: The depths hard-coded in find_cinfo are only correct *
+ * if find_cinfo is inlined. Ack! *
+ * *
+ **************************************************************************/
+
+#define REGION_PROFILE_DEPTH 2
+#undef TRACE_STACK
+#if defined(__GNUC__) && defined(__OPTIMIZE__) && REGION_PROFILE_DEPTH > 1
+#define TRACE_STACK
+#endif
+
+#ifdef TRACE_STACK
+
+#if REGION_PROFILE_DEPTH > 6
+#error "REGION_PROFILE_DEPTH must be less than 6. See find_cinfo()."
+#endif
+
+typedef struct Call_info
+{
+ struct Call_info *next;
+ void **stack; /* Array holding the call chain */
+ unsigned long size;
+ unsigned long calls;
+} *cinfo;
+
+static cinfo cinfos = NULL;
+
+/* Find the current call chain and return a pointer to our status for
+ it, or allocate a new entry if there is none. */
+static cinfo find_cinfo(void)
+{
+ void *calls[REGION_PROFILE_DEPTH];
+ int i;
+ cinfo ci;
+
+ /* Compute the call chain. This is an awful hack. */
+ i = 0;
+ if (i < REGION_PROFILE_DEPTH)
+ calls[i++] = __builtin_return_address(1);
+ if (i < REGION_PROFILE_DEPTH)
+ calls[i++] = __builtin_return_address(2);
+ if (i < REGION_PROFILE_DEPTH)
+ calls[i++] = __builtin_return_address(3);
+ if (i < REGION_PROFILE_DEPTH)
+ calls[i++] = __builtin_return_address(4);
+ if (i < REGION_PROFILE_DEPTH)
+ calls[i++] = __builtin_return_address(5);
+ if (i < REGION_PROFILE_DEPTH)
+ calls[i++] = __builtin_return_address(6);
+ /* Add more if you want a higher call-depth (why would you?) */
+
+ /* Find it */
+ for (ci = cinfos; ci; ci = ci->next)
+ if (!memcmp(calls, ci->stack, REGION_PROFILE_DEPTH*sizeof(void *)))
+ return ci;
+
+ if (!profile_region)
+ profile_region = newregion();
+ ci = ralloc(profile_region, struct Call_info);
+ ci->stack = rarrayalloc(profile_region, REGION_PROFILE_DEPTH, void *);
+ memcpy(ci->stack, calls, REGION_PROFILE_DEPTH*sizeof(void *));
+ ci->size = 0;
+ ci->calls = 0;
+ ci->next = cinfos;
+ cinfos = ci;
+ return ci;
+
+}
+#endif
+
+static void add_alloc(char *file, int line, int size)
+{
+ ainfo ai = find_ainfo(file, line);
+ ai->calls++;
+ ai->size += size;
+#ifdef TRACE_STACK
+ {
+ cinfo ci;
+
+ ci = find_cinfo();
+ ci->calls++;
+ ci->size += size;
+ }
+#endif
+}
+
+/**************************************************************************
+ * *
+ * Intercept and log calls to region library *
+ * *
+ **************************************************************************/
+
+void *profile_typed_ralloc(region r, size_t size, type_t type, char *file,
+ int line)
+{
+ add_alloc(file, line, size);
+ return typed_ralloc(r, size, type);
+}
+
+void *profile_typed_rarrayalloc(region r, size_t n, size_t size, type_t type,
+ char *file, int line)
+{
+ add_alloc(file, line, n*size);
+ return typed_rarrayalloc(r, n, size, type);
+}
+
+void *profile_typed_rarrayextend(region r, void *old, size_t n, size_t size,
+ type_t type, char *file, int line)
+{
+ add_alloc(file, line, n*size); /* XXX: Fix */
+ return typed_rarrayextend(r, old, n, size, type);
+}
+
+char *profile_rstralloc(region r, size_t size, char *file, int line)
+{
+ add_alloc(file, line, size);
+ return rstralloc(r, size);
+}
+
+char *profile_rstralloc0(region r, size_t size, char *file, int line)
+{
+ add_alloc(file, line, size);
+ return rstralloc0(r, size);
+}
+
+char *profile_rstrdup(region r, const char *s, char *file, int line)
+{
+ add_alloc(file, line, strlen(s));
+ return rstrdup(r, s);
+}
+
+char *profile_rstrextend(region r, const char *old, size_t newsize,
+ char *file, int line)
+{
+ add_alloc(file, line, newsize); /* XXX: Fix */
+ return rstrextend(r, old, newsize);
+}
+
+char *profile_rstrextend0(region r, const char *old, size_t newsize,
+ char *file, int line)
+{
+ add_alloc(file, line, newsize); /* XXX: Fix */
+ return rstrextend0(r, old, newsize);
+}
+
+/**************************************************************************
+ * *
+ * Display results -- generic *
+ * *
+ **************************************************************************/
+
+static FILE *out = NULL;
+
+/* Generic list -- used for generic sorting. Note that next field is
+ at the top. */
+typedef struct List
+{
+ struct List *next;
+} *list;
+
+/* Sort a list. cmp should sort in reverse order. */
+static list sort_list(list l, int (*cmp)(const void *, const void *))
+{
+ list cur, result;
+ list *sorted;
+ int i, length;
+ region temp_region;
+
+ /* Compute length of list */
+ for (cur = l, length = 0; cur; cur = cur->next, length++);
+
+ temp_region = newregion();
+ sorted = rarrayalloc(temp_region, length, list *);
+ for (cur = l, i = 0; cur; cur = cur->next)
+ sorted[i++] = cur;
+ qsort(sorted, length, sizeof(list *), cmp);
+
+ result = NULL;
+ for (i = 0; i < length; i++)
+ {
+ cur = result;
+ result = sorted[i];
+ result->next = cur;
+ }
+ deleteregion(temp_region);
+ return result;
+}
+
+
+typedef struct File_info
+{
+ struct File_info *next;
+ char *file;
+ unsigned long size;
+ unsigned long calls;
+ unsigned long sites;
+} *finfo;
+
+static finfo finfos = NULL;
+
+static int finfo_cmp(const void *a, const void *b)
+{
+ finfo *afi = (finfo *) a;
+ finfo *bfi = (finfo *) b;
+ return (*afi)->size - (*bfi)->size; /* Reverse order */
+}
+
+static void print_finfos(void)
+{
+ finfo fi;
+ unsigned long size, sites, calls;
+
+ finfos = (finfo) sort_list((list) finfos, finfo_cmp);
+ size = sites = calls = 0;
+ fprintf(out, " Bytes | Sites | Calls | File\n");
+ fprintf(out, " ------------+-------+----------+---------------------\n");
+ for (fi = finfos; fi; fi = fi->next)
+ {
+ size += fi->size;
+ sites += fi->sites;
+ calls += fi->calls;
+ fprintf(out, " %12lu | %5lu | %8lu | %s\n",
+ fi->size, fi->sites, fi->calls, fi->file);
+ }
+ fprintf(out, " ------------+-------+----------+---------------------\n");
+ fprintf(out, " %12lu | %5lu | %8lu | Total\n",
+ size, sites, calls);
+
+}
+
+static int ainfo_cmp(const void *a, const void *b)
+{
+ ainfo *afi = (ainfo *) a;
+ ainfo *bfi = (ainfo *) b;
+ return (*afi)->size - (*bfi)->size; /* Reverse order */
+}
+
+static void print_ainfos(void)
+{
+ ainfo ai;
+
+ unsigned long size, calls;
+
+ ainfos = (ainfo) sort_list((list) ainfos, ainfo_cmp);
+ size = calls = 0;
+ fprintf(out, " Bytes | Calls | Site\n");
+ fprintf(out, " ------------+----------+---------------------\n");
+ for (ai = ainfos; ai; ai = ai->next)
+ {
+ size += ai->size;
+ calls += ai->calls;
+ fprintf(out, " %12lu | %8lu | %s:%d\n",
+ ai->size, ai->calls, ai->file, ai->line);
+ }
+ fprintf(out, " ------------+----------+---------------------\n");
+ fprintf(out, " %12lu | %8lu | Total\n",
+ size, calls);
+}
+
+static finfo find_finfo(char *file)
+{
+ finfo fi;
+
+ for (fi = finfos; fi; fi = fi->next)
+ if (!strcmp(file, fi->file))
+ return fi;
+
+ fi = ralloc(profile_region, struct File_info);
+ fi->file = file;
+ fi->size = 0;
+ fi->calls = 0;
+ fi->sites = 0;
+ fi->next = finfos;
+ finfos = fi;
+ return fi;
+}
+
+static void gather_finfo(void)
+{
+ ainfo ai;
+
+ for (ai = ainfos; ai; ai = ai->next)
+ {
+ finfo fi = find_finfo(ai->file);
+ fi->size += ai->size;
+ fi->calls += ai->calls;
+ fi->sites++;
+ }
+}
+
+/**************************************************************************
+ * *
+ * Display results -- GCC *
+ * *
+ **************************************************************************/
+
+#ifdef TRACE_STACK
+
+pid_t child_pid = 0;
+int child_in[2], child_out[2]; /* pipes to child process */
+
+static void start_prettiness(void)
+{
+ if (pipe(child_in) || pipe(child_out))
+ pfail("Unable to open pipe to child process");
+ if (!(child_pid = fork()))
+ {
+ /* Child process */
+ pid_t parent_pid;
+ char filename[64];
+
+ if (dup2(child_in[0], STDIN_FILENO) == -1)
+ pfail("Unable to open pipe from parent");
+ close(child_in[0]);
+ close(child_in[1]);
+ if (dup2(child_out[1], STDOUT_FILENO) == -1)
+ pfail("Unable to open pipe to parent");
+ close(child_out[0]);
+ close(child_out[1]);
+
+ parent_pid = getppid();
+ snprintf(filename, 64, "/proc/%d/exe", parent_pid);
+ filename[63] = '\0';
+ execlp("addr2line", "addr2line", "-s", "-e", filename, 0);
+ fprintf(stderr, "Unable to fork addr2line\n");
+ exit(EXIT_FAILURE);
+ }
+ else
+ {
+ close(child_in[0]);
+ close(child_out[1]);
+ }
+}
+
+/* Turn p into a file:line string */
+static char *prettify(void *p)
+{
+#define BUFSIZE 1024
+ static char buf[BUFSIZE];
+ int size;
+
+ /*printf("To child: %p\n", p);*/
+ size = snprintf(buf, BUFSIZE, "%p\n", p);
+ write(child_in[1], buf, size);
+ size = read(child_out[0], buf, BUFSIZE - 1);
+ if (!size)
+ pfail("Unable to read from child process");
+ buf[size-1] = '\0'; /* Kill \n */
+ /*printf("Read: [%s]\n", buf);*/
+ return buf;
+}
+
+static void end_prettiness(void)
+{
+ if (child_pid)
+ kill(child_pid, SIGHUP);
+}
+
+static int cinfo_cmp(const void *a, const void *b)
+{
+ cinfo *aci = (cinfo *) a;
+ cinfo *bci = (cinfo *) b;
+ return (*aci)->size - (*bci)->size; /* Reverse order */
+}
+
+/* Print the call chain information out to a file. */
+static void print_cinfos(void)
+{
+ cinfo ci;
+ unsigned long size, calls;
+ int i;
+
+ cinfos = (cinfo) sort_list((list) cinfos, cinfo_cmp);
+ size = calls = 0;
+ start_prettiness();
+ fprintf(out, " Bytes | Calls | Call Stack\n");
+ fprintf(out, " ------------+----------+---------------------\n");
+ for (ci = cinfos; ci; ci = ci->next)
+ {
+ size += ci->size;
+ calls += ci->calls;
+ fprintf(out, " %12lu | %8lu | ", ci->size, ci->calls);
+ for (i = 0; i < REGION_PROFILE_DEPTH; i++)
+ fprintf(out, "%s ", prettify(ci->stack[i]));
+ fprintf(out, "\n");
+ }
+ fprintf(out, " ------------+----------+---------------------\n");
+ fprintf(out, " %12lu | %8lu | Total\n",
+ size, calls);
+ end_prettiness();
+}
+#endif
+
+
+void profile(void)
+{
+ if (profile_region == NULL)
+ return;
+
+ gather_finfo();
+
+ if (!(out = fopen("profile.out", "w")))
+ pfail("Unable to open profile.out");
+
+ fprintf(out, "---------------------------\n");
+ fprintf(out, "Region Library Memory Usage\n");
+ fprintf(out, "---------------------------\n\n");
+
+ print_finfos();
+ fprintf(out, "\n");
+ print_ainfos();
+#ifdef TRACE_STACK
+ fprintf(out, "\n");
+ print_cinfos();
+#endif
+
+ fclose(out);
+}
diff --git a/libbanshee/libcompat/profile.h b/libbanshee/libcompat/profile.h
new file mode 100644
index 00000000000..b07034e2191
--- /dev/null
+++ b/libbanshee/libcompat/profile.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1999-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#ifndef PROFILE_H
+#define PROFILE_H
+
+/* Should only be included in regions.h and profile.c */
+
+void *profile_typed_ralloc(region r, size_t size, type_t type, char *file, int line);
+void *profile_typed_rarrayalloc(region r, size_t n, size_t size, type_t type, char *file, int line);
+void *profile_typed_rarrayextend(region r, void *old, size_t n, size_t size, type_t type, char *file, int line);
+char *profile_rstralloc(region r, size_t size, char *file, int line);
+char *profile_rstralloc0(region r, size_t size, char *file, int line);
+char *profile_rstrdup(region r, const char *s, char *file, int line);
+char *profile_rstrextend(region r, const char *old, size_t newsize, char *file, int line);
+char *profile_rstrextend0(region r, const char *old, size_t newsize, char *file, int line);
+
+#ifdef REGION_PROFILE
+#define typed_ralloc(r, size, type) profile_typed_ralloc(r, size, type, __FILE__, __LINE__)
+#define typed_rarrayalloc(r, n, size, type) profile_typed_rarrayalloc(r, n, size, type, __FILE__, __LINE__)
+#define typed_rarrayextend(r, old, n, size, type) profile_typed_rarrayextend(r, old, n, size, type, __FILE__, __LINE__)
+
+#define rstralloc(r, size) profile_rstralloc(r, size, __FILE__, __LINE__)
+#define rstralloc0(r, size) profile_rstralloc0(r, size, __FILE__, __LINE__)
+#define rstrdup(r, s) profile_rstrdup(r, s, __FILE__, __LINE__)
+
+#define rstrextend(r, old, newsize) profile_rstrextend(r, old, newsize, __FILE__, __LINE__)
+#define rstrextend0(r, old, newsize) profile_rstrextend0(r, old, newsize, __FILE__, __LINE__)
+#endif
+
+void profile(void);
+
+#endif
diff --git a/libbanshee/libcompat/radix-tree.c b/libbanshee/libcompat/radix-tree.c
new file mode 100644
index 00000000000..18f8929ad2d
--- /dev/null
+++ b/libbanshee/libcompat/radix-tree.c
@@ -0,0 +1,364 @@
+/*
+ * Modified to work in GCC in 2003 by Daniel Berlin
+ * Copyright (C) 2001 Momchil Velikov
+ * Portions Copyright (C) 2001 Christoph Hellwig
+ *
+ * This program 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 2, or (at
+ * your option) any later version.
+ *
+ * This program 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 program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include "radix-tree.h"
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
+/*
+ * Radix tree node definition.
+ */
+#define RADIX_TREE_MAP_SHIFT 6
+#define RADIX_TREE_MAP_SIZE (1UL << RADIX_TREE_MAP_SHIFT)
+#define RADIX_TREE_MAP_MASK (RADIX_TREE_MAP_SIZE-1)
+
+struct radix_tree_node {
+ unsigned int count;
+ void *slots[RADIX_TREE_MAP_SIZE];
+};
+
+struct radix_tree_path {
+ struct radix_tree_node *node, **slot;
+};
+
+#define RADIX_TREE_INDEX_BITS (8 /* CHAR_BIT */ * sizeof(unsigned long))
+#define RADIX_TREE_MAX_PATH (RADIX_TREE_INDEX_BITS/RADIX_TREE_MAP_SHIFT + 2)
+
+static unsigned long height_to_maxindex[RADIX_TREE_MAX_PATH];
+
+
+/*
+ * This assumes that the caller has performed appropriate preallocation, and
+ * that the caller has pinned this thread of control to the current CPU.
+ */
+static struct radix_tree_node *
+radix_tree_node_alloc(struct radix_tree_root *root)
+{
+ struct radix_tree_node *ret;
+
+ ret = (struct radix_tree_node *)
+ calloc (1, sizeof (struct radix_tree_node));
+ if (!ret)
+ abort ();
+ return ret;
+}
+
+static inline void
+radix_tree_node_free(struct radix_tree_node *node)
+{
+ free (node);
+}
+
+
+/*
+ * Return the maximum key which can be store into a
+ * radix tree with height HEIGHT.
+ */
+static inline unsigned long radix_tree_maxindex(unsigned int height)
+{
+ return height_to_maxindex[height];
+}
+
+/*
+ * Extend a radix tree so it can store key @index.
+ */
+static int radix_tree_extend(struct radix_tree_root *root, unsigned long index)
+{
+ struct radix_tree_node *node;
+ unsigned int height;
+
+ /* Figure out what the height should be. */
+ height = root->height + 1;
+ while (index > radix_tree_maxindex(height))
+ height++;
+
+ if (root->rnode) {
+ do {
+ if (!(node = radix_tree_node_alloc(root)))
+ return -ENOMEM;
+
+ /* Increase the height. */
+ node->slots[0] = root->rnode;
+ node->count = 1;
+ root->rnode = node;
+ root->height++;
+ } while (height > root->height);
+ } else
+ root->height = height;
+
+ return 0;
+}
+
+/**
+ * radix_tree_insert - insert into a radix tree
+ * @root: radix tree root
+ * @index: index key
+ * @item: item to insert
+ *
+ * Insert an item into the radix tree at position @index.
+ */
+int radix_tree_insert(struct radix_tree_root *root, unsigned long index,
+ void *item)
+{
+ struct radix_tree_node *node = NULL, *tmp, **slot;
+ unsigned int height, shift;
+ int error;
+
+ /* Make sure the tree is high enough. */
+ if (index > radix_tree_maxindex(root->height)) {
+ error = radix_tree_extend(root, index);
+ if (error)
+ return error;
+ }
+
+ slot = &root->rnode;
+ height = root->height;
+ shift = (height-1) * RADIX_TREE_MAP_SHIFT;
+
+ while (height > 0) {
+ if (*slot == NULL) {
+ /* Have to add a child node. */
+ if (!(tmp = radix_tree_node_alloc(root)))
+ return -ENOMEM;
+ *slot = tmp;
+ if (node)
+ node->count++;
+ }
+
+ /* Go a level down. */
+ node = *slot;
+ slot = (struct radix_tree_node **)
+ (node->slots + ((index >> shift) & RADIX_TREE_MAP_MASK));
+ shift -= RADIX_TREE_MAP_SHIFT;
+ height--;
+ }
+
+ if (*slot != NULL)
+ return -EEXIST;
+ if (node)
+ node->count++;
+
+ *slot = item;
+ return 0;
+}
+
+/**
+ * radix_tree_lookup - perform lookup operation on a radix tree
+ * @root: radix tree root
+ * @index: index key
+ *
+ * Lookup them item at the position @index in the radix tree @root.
+ */
+void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index)
+{
+ unsigned int height, shift;
+ struct radix_tree_node **slot;
+
+ height = root->height;
+ if (index > radix_tree_maxindex(height))
+ return NULL;
+
+ shift = (height-1) * RADIX_TREE_MAP_SHIFT;
+ slot = &root->rnode;
+
+ while (height > 0) {
+ if (*slot == NULL)
+ return NULL;
+
+ slot = (struct radix_tree_node **)
+ ((*slot)->slots + ((index >> shift) & RADIX_TREE_MAP_MASK));
+ shift -= RADIX_TREE_MAP_SHIFT;
+ height--;
+ }
+
+ return (void *) *slot;
+}
+
+static /* inline */ unsigned int
+__lookup(struct radix_tree_root *root, void **results, unsigned long index,
+ unsigned int max_items, unsigned long *next_index)
+{
+ unsigned int nr_found = 0;
+ unsigned int shift;
+ unsigned int height = root->height;
+ struct radix_tree_node *slot;
+
+ shift = (height-1) * RADIX_TREE_MAP_SHIFT;
+ slot = root->rnode;
+
+ while (height > 0) {
+ unsigned long i = (index >> shift) & RADIX_TREE_MAP_MASK;
+
+ for ( ; i < RADIX_TREE_MAP_SIZE; i++) {
+ if (slot->slots[i] != NULL)
+ break;
+ index &= ~((1 << shift) - 1);
+ index += 1 << shift;
+ if (index == 0)
+ goto out; /* 32-bit wraparound */
+ }
+ if (i == RADIX_TREE_MAP_SIZE)
+ goto out;
+ height--;
+ if (height == 0) { /* Bottom level: grab some items */
+ unsigned long j = index & RADIX_TREE_MAP_MASK;
+
+ for ( ; j < RADIX_TREE_MAP_SIZE; j++) {
+ index++;
+ if (slot->slots[j]) {
+ results[nr_found++] = slot->slots[j];
+ if (nr_found == max_items)
+ goto out;
+ }
+ }
+ }
+ shift -= RADIX_TREE_MAP_SHIFT;
+ slot = slot->slots[i];
+ }
+ out:
+ *next_index = index;
+ return nr_found;
+}
+
+/**
+ * radix_tree_gang_lookup - perform multiple lookup on a radix tree
+ * @root: radix tree root
+ * @results: where the results of the lookup are placed
+ * @first_index: start the lookup from this key
+ * @max_items: place up to this many items at *results
+ *
+ * Performs an index-ascending scan of the tree for present items. Places
+ * them at *@results and returns the number of items which were placed at
+ * *@results.
+ *
+ * The implementation is naive.
+ */
+unsigned int
+radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
+ unsigned long first_index, unsigned int max_items)
+{
+ const unsigned long max_index = radix_tree_maxindex(root->height);
+ unsigned long cur_index = first_index;
+ unsigned int ret = 0;
+
+ if (root->rnode == NULL)
+ goto out;
+ if (max_index == 0) { /* Bah. Special case */
+ if (first_index == 0) {
+ if (max_items > 0) {
+ *results = root->rnode;
+ ret = 1;
+ }
+ }
+ goto out;
+ }
+ while (ret < max_items) {
+ unsigned int nr_found;
+ unsigned long next_index; /* Index of next search */
+
+ if (cur_index > max_index)
+ break;
+ nr_found = __lookup(root, results + ret, cur_index,
+ max_items - ret, &next_index);
+ ret += nr_found;
+ if (next_index == 0)
+ break;
+ cur_index = next_index;
+ }
+ out:
+ return ret;
+}
+
+/**
+ * radix_tree_delete - delete an item from a radix tree
+ * @root: radix tree root
+ * @index: index key
+ *
+ * Remove the item at @index from the radix tree rooted at @root.
+ *
+ * Returns the address of the deleted item, or NULL if it was not present.
+ */
+void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
+{
+ struct radix_tree_path path[RADIX_TREE_MAX_PATH], *pathp = path;
+ unsigned int height, shift;
+ void *ret = NULL;
+
+ height = root->height;
+ if (index > radix_tree_maxindex(height))
+ goto out;
+
+ shift = (height-1) * RADIX_TREE_MAP_SHIFT;
+ pathp->node = NULL;
+ pathp->slot = &root->rnode;
+
+ while (height > 0) {
+ if (*pathp->slot == NULL)
+ goto out;
+
+ pathp[1].node = *pathp[0].slot;
+ pathp[1].slot = (struct radix_tree_node **)
+ (pathp[1].node->slots + ((index >> shift) & RADIX_TREE_MAP_MASK));
+ pathp++;
+ shift -= RADIX_TREE_MAP_SHIFT;
+ height--;
+ }
+
+ ret = *pathp[0].slot;
+ if (ret == NULL)
+ goto out;
+
+ *pathp[0].slot = NULL;
+ while (pathp[0].node && --pathp[0].node->count == 0) {
+ pathp--;
+ *pathp[0].slot = NULL;
+ radix_tree_node_free(pathp[1].node);
+ }
+
+ if (root->rnode == NULL)
+ root->height = 0; /* Empty tree, we can reset the height */
+ out:
+ return ret;
+}
+
+
+static unsigned long __maxindex(unsigned int height)
+{
+ unsigned int tmp = height * RADIX_TREE_MAP_SHIFT;
+ unsigned long index = (~0UL >> (RADIX_TREE_INDEX_BITS - tmp - 1)) >> 1;
+
+ if (tmp >= RADIX_TREE_INDEX_BITS)
+ index = ~0UL;
+ return index;
+}
+
+static void radix_tree_init_maxindex(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(height_to_maxindex); i++)
+ height_to_maxindex[i] = __maxindex(i);
+}
+
+void radix_tree_init(void)
+{
+ radix_tree_init_maxindex();
+}
diff --git a/libbanshee/libcompat/radix-tree.h b/libbanshee/libcompat/radix-tree.h
new file mode 100644
index 00000000000..a6b6dc185a3
--- /dev/null
+++ b/libbanshee/libcompat/radix-tree.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2001 Momchil Velikov
+ * Portions Copyright (C) 2001 Christoph Hellwig
+ *
+ * This program 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 2, or (at
+ * your option) any later version.
+ *
+ * This program 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 program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef _LINUX_RADIX_TREE_H
+#define _LINUX_RADIX_TREE_H
+
+
+struct radix_tree_node;
+
+struct radix_tree_root {
+ unsigned int height;
+ struct radix_tree_node *rnode;
+};
+
+#define RADIX_TREE_INIT() {0, NULL}
+
+#define RADIX_TREE(name) \
+ struct radix_tree_root name = RADIX_TREE_INIT()
+
+#define INIT_RADIX_TREE(root) \
+do { \
+ (root)->height = 0; \
+ (root)->rnode = NULL; \
+} while (0)
+
+extern int radix_tree_insert(struct radix_tree_root *, unsigned long, void *);
+extern void *radix_tree_lookup(struct radix_tree_root *, unsigned long);
+extern void *radix_tree_delete(struct radix_tree_root *, unsigned long);
+extern unsigned int radix_tree_gang_lookup(struct radix_tree_root *root,
+ void **results,
+ unsigned long first_index,
+ unsigned int max_items);
+extern void radix_tree_init(void);
+
+
+#endif /* _LINUX_RADIX_TREE_H */
diff --git a/libbanshee/libcompat/regions.c b/libbanshee/libcompat/regions.c
new file mode 100644
index 00000000000..6426fd68d1e
--- /dev/null
+++ b/libbanshee/libcompat/regions.c
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) 1999-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+/* Idea: clear on page alloc rather than individual alloc
+ Turns out not so good (on lcc at least, seems a wash on mudlle):
+ logically should be bad for small regions (less than a few pages)
+*/
+#undef PRECLEAR
+#undef REGION_PROFILE
+#include "regions.h"
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include "radix-tree.h"
+#define RPAGESIZE (1 << RPAGELOG)
+#define PAGE_GROUP_SIZE 32
+#define K 4
+#define MAXPAGE (1 << (32 - RPAGELOG))
+
+#define PAGENB(x) ((__rcintptr)(x) >> RPAGELOG)
+
+#define ALIGN(x, n) (((x) + ((n) - 1)) & ~((n) - 1))
+#define PALIGN(x, n) ((void *)ALIGN((__rcintptr)(x), n))
+#ifdef __GNUC__
+#define RALIGNMENT __alignof(double)
+#define PTRALIGNMENT __alignof(void *)
+#define ALIGNMENT_LONG __alignof(unsigned long)
+#else
+#define RALIGNMENT 8
+#define PTRALIGNMENT 4
+#define ALIGNMENT_LONG 4
+#endif
+
+typedef unsigned long __rcintptr;
+
+struct ablock {
+ char *base, *allocfrom;
+};
+
+struct allocator {
+ struct ablock page;
+ struct ablock superpage;
+ struct ablock hyperpage;
+ struct page *pages;
+ struct page *bigpages;
+};
+
+struct Region {
+ struct allocator normal;
+ struct Region *parent, *sibling, *children;
+};
+
+nomem_handler nomem_h;
+
+/* dummy region for NULL and malloc memory */
+struct Region zeroregion;
+
+static void clear(void *start, __rcintptr size)
+{
+ long *clear, *clearend;
+
+ clear = (long *)start;
+ clearend = (long *)((char *)start + size);
+ do *clear++ = 0;
+ while (clear < clearend) ;
+}
+
+#ifdef PRECLEAR
+#define preclear clear
+#define postclear(s, e)
+#else
+#define preclear(s, e)
+#define postclear clear
+#endif
+
+#include "pages.c"
+#include "alloc.c"
+
+static void nochildren(region r)
+{
+ if (r->children)
+ abort();
+}
+
+static void unlink_region(region r)
+{
+ region *scan;
+
+ scan = &r->parent->children;
+ while (*scan != r)
+ scan = &(*scan)->sibling;
+ *scan = (*scan)->sibling;
+}
+
+static void link_region(region r, region parent)
+{
+ r->sibling = parent->children;
+ r->parent = parent;
+ parent->children = r;
+}
+
+static int rstart;
+
+void initregion(region r)
+{
+ char *first =
+ (char *)r - rstart - offsetof(struct page, previous);
+
+ /* Start using page with region header as a pointer-containing page */
+ r->normal.page.base = first;
+ r->normal.page.allocfrom = (char *)(r + 1);
+
+ /* Guarantee failure for all other blocks */
+ r->normal.superpage.allocfrom = (char *)(K * RPAGESIZE + 1);
+ r->normal.hyperpage.allocfrom = (char *)(K * K * RPAGESIZE + 1);
+
+ /* Remember that r owns this page. */
+ r->normal.pages = (struct page *)first;
+ set_region(r->normal.pages, 1, r);
+}
+
+region newregion(void)
+{
+ return newsubregion(&zeroregion);
+}
+
+region newsubregion(region parent)
+{
+ char *first;
+ region r;
+
+ first = (char *)alloc_single_page(NULL);
+ preclear(first + offsetof(struct page, pagecount), RPAGESIZE - offsetof(struct page, pagecount));
+
+ /* stagger regions across cache lines a bit */
+ rstart += 64;
+ if (rstart > RPAGESIZE / K) rstart = 0;
+ r = (region)(first + rstart + offsetof(struct page, previous));
+ postclear(r, sizeof *r);
+ initregion(r);
+
+ link_region(r, parent);
+
+ return r;
+}
+
+void *typed_ralloc(region r, size_t size, type_t t)
+{
+ return rstralloc0(r, size);
+}
+
+void *typed_rarrayextend(region r, void *old, size_t n, size_t size, type_t t)
+{
+ return rstrextend0(r, old, n * size);
+}
+
+void *typed_rarrayalloc(region r, size_t n, size_t size, type_t t)
+{
+ return typed_ralloc(r, n * size, t);
+}
+
+char *rstralloc(region r, size_t size)
+{
+ void *mem, *dummy;
+
+ qalloc(r, &r->normal, &dummy, 0, 1, &mem, size, RALIGNMENT, 0);
+
+ return mem;
+}
+
+char *rstralloc0(region r, size_t size)
+{
+ char *mem;
+
+ mem = rstralloc(r, size);
+ clear(mem, size);
+
+ return mem;
+}
+
+char *rstrdup(region r, const char *s)
+{
+ char *news = rstralloc(r, strlen(s) + 1);
+
+ strcpy(news, s);
+
+ return news;
+}
+
+static char *internal_rstrextend(region r, const char *old, size_t newsize,
+ int needsclear)
+{
+ /* For now we don't attempt to extend the old storage area */
+ void *newmem, *hdr;
+ unsigned long *oldhdr, oldsize;
+
+ qalloc(r, &r->normal, &hdr, sizeof(unsigned long), ALIGNMENT_LONG,
+ &newmem, newsize, RALIGNMENT, 0);
+
+ /* If we don't do this we can't find the header: */
+ hdr = (char *)newmem - sizeof(unsigned long);
+
+ *(unsigned long *)hdr = newsize;
+
+ if (old)
+ {
+ oldhdr = (unsigned long *)(old - ALIGNMENT_LONG);
+ oldsize = *oldhdr;
+
+ if (oldsize > newsize)
+ oldsize = newsize;
+ else if (needsclear)
+ clear((char *) newmem + oldsize, newsize - oldsize);
+ memcpy(newmem, old, oldsize);
+ }
+ else if (needsclear)
+ clear(newmem, newsize);
+
+ return newmem;
+}
+
+char *rstrextend(region r, const char *old, size_t newsize)
+{
+ return internal_rstrextend(r, old, newsize, 0);
+}
+
+char *rstrextend0(region r, const char *old, size_t newsize)
+{
+ return internal_rstrextend(r, old, newsize, 1);
+}
+
+void typed_rarraycopy(void *to, void *from, size_t n, size_t size, type_t type)
+{
+ memcpy(to, from, n * size);
+}
+
+static void delregion(region r)
+{
+ nochildren(r);
+ free_all_pages(r, &r->normal);
+}
+
+void deleteregion(region r)
+{
+ unlink_region(r);
+ delregion(r);
+}
+
+void deleteregion_ptr(region *r)
+{
+ region tmp = *r;
+
+ *r = NULL;
+ deleteregion(tmp);
+}
+
+void deleteregion_array(int n, region *regions)
+{
+ int i;
+
+ for (i = 0; i < n; i++)
+ unlink_region(regions[i]);
+
+ for (i = 0; i < n; i++)
+ {
+ delregion(regions[i]);
+ regions[i] = NULL;
+ }
+}
+
+region regionof(void *ptr)
+{
+ return radix_tree_lookup (&__rcregionmap, (unsigned long)ptr >> RPAGELOG);
+}
+
+void region_init(void)
+{
+ static int initialized = 0;
+ radix_tree_init ();
+ if ( initialized )
+ return;
+ else
+ {
+ rstart = -64; /* Save 64 bytes of memory! (sometimes ;-)) */
+ init_pages();
+ }
+
+ initialized = 1;
+}
+
+nomem_handler set_nomem_handler(nomem_handler newhandler)
+{
+ nomem_handler oldh = nomem_h;
+
+ nomem_h = newhandler;
+
+ return oldh;
+}
+
+/*
+int region_main(int argc, char **argv, char **envp);
+
+int main(int argc, char **argv, char **envp)
+{
+ region_init();
+ return region_main(argc, argv, envp);
+}
+*/
+
+
+/* Debugging support */
+
+static FILE *out;
+
+static void printref(void *x)
+{
+/* if (x >= (void *)__rcregionmap && x < (void *)&__rcregionmap[MAXPAGE])
+ return;
+*/
+#ifdef RCPAIRS
+ if (x >= (void *)__rcregions && x < (void *)&__rcregions[MAXREGIONS])
+ return;
+
+#endif
+
+ fprintf(out, "info symbol 0x%p\n", x);
+}
+
+void findrefs(region r, void *from, void *to)
+{
+ char *f;
+
+ if (!out)
+ out = fopen("/dev/tty", "w");
+
+ for (f = PALIGN(from, PTRALIGNMENT); f < (char *)to; f += PTRALIGNMENT)
+ if (regionof(*(void **)f) == r)
+ printref(f);
+
+ fflush(out);
+}
+
+#ifdef sparc
+extern void _DYNAMIC, _end;
+
+void findgrefs(region r)
+{
+ findrefs(r, &_DYNAMIC, &_end);
+}
+#endif
+
+void findrrefs(region r, region from)
+{
+ struct page *p;
+
+ for (p = from->normal.pages; p; p = p->next)
+ findrefs(r, (char *)&p->previous, (char *)p + RPAGESIZE);
+
+ for (p = r->normal.bigpages; p; p = p->next)
+ findrefs(r, (char *)&p->previous, (char *)p + p->pagecount * RPAGESIZE);
+}
diff --git a/libbanshee/libcompat/regions.h b/libbanshee/libcompat/regions.h
new file mode 100644
index 00000000000..9f0231ddd82
--- /dev/null
+++ b/libbanshee/libcompat/regions.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1999-2001
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#ifndef REGIONS_H
+#define REGIONS_H
+
+#define RPAGELOG 13
+
+typedef struct Region *region;
+
+#include <stdlib.h>
+
+void region_init(void); /* You MUST call this function before using any
+ part of this library */
+
+region newregion(void);
+region newsubregion(region parent);
+
+typedef int type_t;
+#define rctypeof(type) 0
+
+/* Low-level alloc with dynamic type info */
+void *typed_ralloc(region r, size_t size, type_t type);
+void *typed_rarrayalloc(region r, size_t n, size_t size, type_t type);
+void *typed_rarrayextend(region r, void *old, size_t n, size_t size, type_t type);
+void typed_rarraycopy(void *to, void *from, size_t n, size_t size, type_t type);
+
+#define ralloc(r, type) typed_ralloc((r), sizeof(type), rctypeof(type))
+#define rarrayalloc(r, n, type) typed_rarrayalloc((r), (n), sizeof(type), rctypeof(type))
+#define rarrayextend(r, old, n, type) typed_rarrayextend((r), (old), (n), sizeof(type), rctypeof(type))
+#define rarraycopy(to, from, n, type) typed_rarraycopy((to), (from), (n), sizeof(type), rctypeof(type))
+
+char *rstralloc(region r, size_t size);
+char *rstralloc0(region r, size_t size);
+char *rstrdup(region r, const char *s);
+
+/* rstrextend is used to extend an old string. The string MUST have been
+ initially allocated by a call to rstrextend with old == NULL (you cannot
+ initially allocate the string with rstralloc) */
+char *rstrextend(region r, const char *old, size_t newsize);
+char *rstrextend0(region r, const char *old, size_t newsize);
+
+void deleteregion(region r);
+void deleteregion_ptr(region *r);
+void deleteregion_array(int n, region *regions);
+region regionof(void *ptr);
+
+typedef void (*nomem_handler)(void);
+nomem_handler set_nomem_handler(nomem_handler newhandler);
+
+/* Debugging support */
+void findrefs(region r, void *from, void *to);
+void findgrefs(region r);
+void findrrefs(region r, region from);
+
+#ifdef REGION_PROFILE
+#include "profile.h"
+#endif
+
+#endif
diff --git a/libbanshee/points-to/Makefile.am b/libbanshee/points-to/Makefile.am
new file mode 100644
index 00000000000..7f6e8c6cafc
--- /dev/null
+++ b/libbanshee/points-to/Makefile.am
@@ -0,0 +1,4 @@
+AM_CFLAGS = -I$(top_srcdir)/../include -I$(srcdir)/../libcompat -I$(srcdir)/../include -I$(srcdir)/.. -Ddeletes= -Dtraditional= -Dsameregion= -Dparentptr= @ac_libbanshee_warn_cflags@
+noinst_LIBRARIES = libandersen.a
+libandersen_a_SOURCES = andersen_terms.c
+
diff --git a/libbanshee/points-to/Makefile.in b/libbanshee/points-to/Makefile.in
new file mode 100644
index 00000000000..c18b844ee96
--- /dev/null
+++ b/libbanshee/points-to/Makefile.in
@@ -0,0 +1,364 @@
+# Makefile.in generated by automake 1.7.6 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+ac_libbanshee_warn_cflags = @ac_libbanshee_warn_cflags@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build_alias = @build_alias@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+AM_CFLAGS = -I$(top_srcdir)/../include -I$(srcdir)/../libcompat -I$(srcdir)/../include -I$(srcdir)/.. -Ddeletes= -Dtraditional= -Dsameregion= -Dparentptr= @ac_libbanshee_warn_cflags@
+noinst_LIBRARIES = libandersen.a
+libandersen_a_SOURCES = andersen_terms.c
+subdir = points-to
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+
+libandersen_a_AR = $(AR) cru
+libandersen_a_LIBADD =
+am_libandersen_a_OBJECTS = andersen_terms.$(OBJEXT)
+libandersen_a_OBJECTS = $(am_libandersen_a_OBJECTS)
+
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/../depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/andersen_terms.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = $(libandersen_a_SOURCES)
+DIST_COMMON = Makefile.am Makefile.in
+SOURCES = $(libandersen_a_SOURCES)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu points-to/Makefile
+Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+
+AR = ar
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libandersen.a: $(libandersen_a_OBJECTS) $(libandersen_a_DEPENDENCIES)
+ -rm -f libandersen.a
+ $(libandersen_a_AR) libandersen.a $(libandersen_a_OBJECTS) $(libandersen_a_LIBADD)
+ $(RANLIB) libandersen.a
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/andersen_terms.Po@am__quote@
+
+distclean-depend:
+ -rm -rf ./$(DEPDIR)
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@ fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@ fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
+uninstall-info-am:
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$tags$$unique" \
+ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique
+
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkinstalldirs) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES)
+
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+
+distclean-am: clean-am distclean-compile distclean-depend \
+ distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-noinstLIBRARIES ctags distclean distclean-compile \
+ distclean-depend distclean-generic distclean-tags distdir dvi \
+ dvi-am info info-am install install-am install-data \
+ install-data-am install-exec install-exec-am install-info \
+ install-info-am install-man install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+ uninstall-am uninstall-info-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libbanshee/points-to/andersen_terms.c b/libbanshee/points-to/andersen_terms.c
new file mode 100644
index 00000000000..9268a516ee8
--- /dev/null
+++ b/libbanshee/points-to/andersen_terms.c
@@ -0,0 +1,1363 @@
+/*
+
+DO NOT edit this file
+
+*/
+#include <engine/list.h>
+#include <regions.h>
+#include <engine/banshee.h>
+#include <assert.h>
+#include <stdio.h>
+#include <engine/bool.h>
+#include <engine/ufind.h>
+#include <string.h>
+#include <engine/setif-sort.h>
+#include <engine/flowrow-sort.h>
+#include <engine/setif-sort.h>
+
+#define REF_ 11
+#define REFPROJ0_ 12
+#define REFPROJ1_ 13
+#define REFPROJ2_ 14
+#define LAM_ 15
+#define LAMPROJ0_ 16
+#define LAMPROJ1_ 17
+#define LAMPROJ2_ 18
+
+typedef gen_e label_term;
+typedef gen_e_list label_term_list;
+
+typedef struct flowrow_field *argterm_field;
+typedef flowrow_map argterm_map;
+typedef gen_e argterm;
+
+typedef gen_e aterm;
+typedef gen_e_list aterm_list;
+
+
+stamp label_term_get_stamp(gen_e arg1);
+bool label_term_is_var(gen_e arg1);
+DECLARE_OPAQUE_LIST(label_term_list,gen_e)
+label_term label_term_zero(void);
+label_term label_term_one(void);
+label_term label_term_fresh(const char *name);
+label_term label_term_union(label_term_list exprs) deletes;
+label_term label_term_inter(label_term_list exprs) deletes;
+label_term label_term_constant(const char *name) deletes;
+bool label_term_is_constant(label_term e,const char *name);
+label_term_list label_term_tlb(label_term e) deletes;
+void label_term_inclusion(label_term e1,label_term e2) deletes;
+void label_term_unify(label_term e1,label_term e2) deletes;
+
+void label_term_print(FILE* arg1,label_term arg2) deletes;
+static bool label_term_res_proj(setif_var arg1,gen_e arg2) deletes;
+static void label_term_con_match(gen_e arg1,gen_e arg2) deletes;
+stamp argterm_get_stamp(gen_e arg1);
+bool argterm_is_var(gen_e arg1);
+DECLARE_OPAQUE_LIST(argterm_map,flowrow_field)
+void argterm_print(FILE *f,argterm row) deletes;
+stamp aterm_get_stamp(gen_e arg1);
+bool aterm_is_var(gen_e arg1);
+DECLARE_OPAQUE_LIST(aterm_list,gen_e)
+aterm aterm_zero(void);
+aterm aterm_one(void);
+aterm aterm_fresh(const char *name);
+aterm aterm_union(aterm_list exprs) deletes;
+aterm aterm_inter(aterm_list exprs) deletes;
+aterm aterm_constant(const char *name) deletes;
+bool aterm_is_constant(aterm e,const char *name);
+aterm_list aterm_tlb(aterm e) deletes;
+void aterm_inclusion(aterm e1,aterm e2) deletes;
+void aterm_unify(aterm e1,aterm e2) deletes;
+
+aterm ref(label_term arg1,aterm arg2,aterm arg3) deletes;
+struct ref_decon ref_decon(aterm arg1);
+struct ref_
+{
+int type;
+stamp st;
+label_term f0;
+aterm f1;
+aterm f2;
+};
+struct ref_decon
+{
+label_term f0;
+aterm f1;
+aterm f2;
+};
+struct refProj0_
+{
+int type;
+stamp st;
+label_term f0;
+};
+static gen_e ref_pat0_con(gen_e arg1) deletes;
+aterm ref_pat0(label_term arg1) deletes;
+struct refProj1_
+{
+int type;
+stamp st;
+aterm f0;
+};
+static gen_e ref_pat1_con(gen_e arg1) deletes;
+aterm ref_pat1(aterm arg1) deletes;
+struct refProj2_
+{
+int type;
+stamp st;
+aterm f0;
+};
+static gen_e ref_pat2_con(gen_e arg1) deletes;
+aterm ref_pat2(aterm arg1) deletes;
+aterm lam(label_term arg1,argterm arg2,aterm arg3) deletes;
+struct lam_decon lam_decon(aterm arg1);
+struct lam_
+{
+int type;
+stamp st;
+label_term f0;
+argterm f1;
+aterm f2;
+};
+struct lam_decon
+{
+label_term f0;
+argterm f1;
+aterm f2;
+};
+struct lamProj0_
+{
+int type;
+stamp st;
+label_term f0;
+};
+static gen_e lam_pat0_con(gen_e arg1) deletes;
+aterm lam_pat0(label_term arg1) deletes;
+struct lamProj1_
+{
+int type;
+stamp st;
+argterm f0;
+};
+static gen_e lam_pat1_con(gen_e arg1) deletes;
+aterm lam_pat1(argterm arg1) deletes;
+struct lamProj2_
+{
+int type;
+stamp st;
+aterm f0;
+};
+static gen_e lam_pat2_con(gen_e arg1) deletes;
+aterm lam_pat2(aterm arg1) deletes;
+void aterm_print(FILE* arg1,aterm arg2) deletes;
+static bool aterm_res_proj(setif_var arg1,gen_e arg2) deletes;
+static void aterm_con_match(gen_e arg1,gen_e arg2) deletes;
+
+stamp label_term_get_stamp(gen_e arg1)
+{
+return setif_get_stamp((gen_e)arg1);
+}
+
+bool label_term_is_var(gen_e arg1)
+{
+return setif_is_var((gen_e)arg1);
+}
+
+DEFINE_LIST(label_term_list,gen_e)
+label_term label_term_zero(void)
+{
+ return setif_zero();
+}
+
+label_term label_term_one(void)
+{
+ return setif_one();
+}
+
+label_term label_term_fresh(const char *name)
+{
+ return setif_fresh(name);
+}
+
+static label_term label_term_fresh_small(const char *name)
+{
+ return setif_fresh_small(name);
+}
+
+static label_term label_term_fresh_large(const char *name)
+{
+ return setif_fresh_large(name);
+}
+
+label_term label_term_union(label_term_list exprs) deletes
+{
+ return setif_union(exprs);
+}
+
+label_term label_term_inter(label_term_list exprs) deletes
+{
+ return setif_inter(exprs);
+}
+
+label_term label_term_constant(const char *name) deletes
+{
+ return setif_constant(name);
+}
+
+bool label_term_is_constant(label_term e, const char *name)
+{
+ if (setif_is_constant(e))
+return (! strcmp(name,setif_get_constant_name(e)));
+else return FALSE;
+}
+
+label_term_list label_term_tlb(label_term e) deletes
+{
+ return setif_tlb(e);
+}
+
+void label_term_inclusion(label_term e1, label_term e2) deletes
+{
+ setif_inclusion(label_term_con_match,label_term_res_proj,e1,e2);
+}
+
+static void label_term_inclusion_contra(label_term e1, label_term e2) deletes
+{
+ setif_inclusion(label_term_con_match,label_term_res_proj,e2,e1);
+}
+
+void label_term_unify(label_term e1, label_term e2) deletes
+{
+ setif_inclusion(label_term_con_match,label_term_res_proj,e1,e2);
+setif_inclusion(label_term_con_match,label_term_res_proj,e2,e1);
+}
+
+void label_term_print(FILE* arg1,label_term arg2) deletes
+{
+switch(((setif_term)arg2)->type)
+{
+case VAR_TYPE:
+fprintf(arg1,"%s",sv_get_name((setif_var)arg2));
+break;
+case ZERO_TYPE:
+fprintf(arg1,"0");
+break;
+case ONE_TYPE:
+fprintf(arg1,"1");
+break;
+case CONSTANT_TYPE:
+fprintf(arg1,setif_get_constant_name(arg2));
+break;
+case UNION_TYPE:
+{
+gen_e_list list = setif_get_union(arg2);
+gen_e_list_scanner scan;
+gen_e temp;
+gen_e_list_scan(list,&scan);
+if (gen_e_list_next(&scan,&temp))
+label_term_print(arg1,temp);
+while (gen_e_list_next(&scan,&temp))
+{
+fprintf(arg1," || ");
+label_term_print(arg1,temp);
+}
+
+}
+break;
+case INTER_TYPE:
+{
+gen_e_list list = setif_get_inter(arg2);
+gen_e_list_scanner scan;
+gen_e temp;
+gen_e_list_scan(list,&scan);
+if (gen_e_list_next(&scan,&temp))
+label_term_print(arg1,temp);
+while (gen_e_list_next(&scan,&temp))
+{
+fprintf(arg1," && ");
+label_term_print(arg1,temp);
+}
+
+}
+break;
+
+default:
+return ;
+}
+
+}
+
+static bool label_term_res_proj(setif_var arg1,gen_e arg2) deletes
+{
+switch(((setif_term)arg2)->type)
+{
+
+default:
+return FALSE;
+}
+
+return FALSE;
+}
+
+static void label_term_con_match(gen_e arg1,gen_e arg2) deletes
+{
+switch(((setif_term)arg1)->type)
+{
+
+default:
+failure("Inconsistent system of constraints\n");
+}
+
+return;
+}
+
+stamp argterm_get_stamp(gen_e arg1)
+{
+return flowrow_get_stamp((gen_e)arg1);
+}
+
+bool argterm_is_var(gen_e arg1)
+{
+return flowrow_is_var((gen_e)arg1);
+}
+
+DEFINE_LIST(argterm_map,flowrow_field)
+argterm_field argterm_make_field(const char *label, aterm expr)
+{
+ flowrow_field result = ralloc(flowrow_region, struct flowrow_field);
+result->label = rstrdup(flowrow_region,label);
+result->expr = (gen_e) expr;
+return result;
+}
+
+argterm argterm_zero(void)
+{
+ return flowrow_zero();
+}
+
+argterm argterm_one(void)
+{
+ return flowrow_one();
+}
+
+argterm argterm_abs(void)
+{
+return flowrow_abs();
+}
+
+argterm argterm_wild(void)
+{
+return flowrow_wild();
+}
+
+argterm argterm_fresh(const char *name)
+{
+return flowrow_fresh(name);
+}
+
+static argterm argterm_fresh_small(const char *name)
+{
+return flowrow_fresh_small(name);
+}
+
+static argterm argterm_fresh_large(const char *name)
+{
+return flowrow_fresh_large(name);
+}
+
+argterm argterm_row(argterm_map fields,argterm rest) deletes
+{
+return flowrow_row(aterm_get_stamp,fields,rest);
+}
+
+aterm argterm_extract_field(const char *field_name, argterm row)
+{
+return flowrow_extract_field(field_name,row);
+}
+
+argterm argterm_extract_rest(argterm row)
+{
+return flowrow_extract_rest(row);
+}
+
+argterm_map argterm_extract_fields(argterm row)
+{
+return flowrow_extract_fields(row);
+}
+
+void argterm_inclusion(argterm row1, argterm row2) deletes
+{
+flowrow_inclusion(aterm_fresh,aterm_get_stamp,aterm_inclusion,aterm_zero(), row1,row2);
+}
+
+static void argterm_inclusion_contra(argterm row1, argterm row2) deletes
+{
+flowrow_inclusion(aterm_fresh,aterm_get_stamp,aterm_inclusion,aterm_zero(), row2,row1);
+}
+
+void argterm_unify(argterm row1, argterm row2) deletes
+{
+argterm_inclusion(row1,row2);
+argterm_inclusion(row2,row1);
+}
+
+void argterm_print(FILE *f,argterm row) deletes
+{
+flowrow_print(f,aterm_get_stamp,aterm_print,row);
+}
+
+stamp aterm_get_stamp(gen_e arg1)
+{
+return setif_get_stamp((gen_e)arg1);
+}
+
+bool aterm_is_var(gen_e arg1)
+{
+return setif_is_var((gen_e)arg1);
+}
+
+DEFINE_LIST(aterm_list,gen_e)
+aterm aterm_zero(void)
+{
+ return setif_zero();
+}
+
+aterm aterm_one(void)
+{
+ return setif_one();
+}
+
+aterm aterm_fresh(const char *name)
+{
+ return setif_fresh(name);
+}
+
+static aterm aterm_fresh_small(const char *name)
+{
+ return setif_fresh_small(name);
+}
+
+static aterm aterm_fresh_large(const char *name)
+{
+ return setif_fresh_large(name);
+}
+
+aterm aterm_union(aterm_list exprs) deletes
+{
+ return setif_union(exprs);
+}
+
+aterm aterm_inter(aterm_list exprs) deletes
+{
+ return setif_inter(exprs);
+}
+
+aterm aterm_constant(const char *name) deletes
+{
+ return setif_constant(name);
+}
+
+bool aterm_is_constant(aterm e, const char *name)
+{
+ if (setif_is_constant(e))
+return (! strcmp(name,setif_get_constant_name(e)));
+else return FALSE;
+}
+
+aterm_list aterm_tlb(aterm e) deletes
+{
+ return setif_tlb(e);
+}
+
+void aterm_inclusion(aterm e1, aterm e2) deletes
+{
+ setif_inclusion(aterm_con_match,aterm_res_proj,e1,e2);
+}
+
+static void aterm_inclusion_contra(aterm e1, aterm e2) deletes
+{
+ setif_inclusion(aterm_con_match,aterm_res_proj,e2,e1);
+}
+
+void aterm_unify(aterm e1, aterm e2) deletes
+{
+ setif_inclusion(aterm_con_match,aterm_res_proj,e1,e2);
+setif_inclusion(aterm_con_match,aterm_res_proj,e2,e1);
+}
+
+bool aterm_is_ref(aterm e)
+{
+ return ((setif_term)e)->type == 11;
+}
+
+aterm ref(label_term arg1,aterm arg2,aterm arg3) deletes
+{
+struct ref_ *ret;
+stamp s[4];
+s[0] = REF_;
+s[1] = label_term_get_stamp((gen_e)arg1);
+s[2] = aterm_get_stamp((gen_e)arg2);
+s[3] = aterm_get_stamp((gen_e)arg3);
+if ((ret = (struct ref_ *)term_hash_find(setif_hash,s,4)) == NULL)
+{
+ret = ralloc(setif_region,struct ref_);
+ret->type = s[0];
+ret->st = stamp_fresh();
+ret->f0 = arg1;
+ret->f1 = arg2;
+ret->f2 = arg3;
+term_hash_insert(setif_hash,(gen_e)ret,s,4);
+}
+return (aterm)ret;
+}
+
+struct ref_decon ref_decon(aterm arg1)
+{
+if (((setif_term)arg1)->type == REF_)
+{
+struct ref_* c = (struct ref_ *)arg1;
+return (struct ref_decon){c->f0,c->f1,c->f2};
+
+}
+else
+return (struct ref_decon){NULL,NULL,NULL};
+}
+
+static gen_e get_ref_proj0_arg(gen_e_list arg1)
+{
+gen_e temp;
+gen_e_list_scanner scan;
+gen_e_list_scan(arg1,&scan);
+while (gen_e_list_next(&scan,&temp))
+{
+if (((setif_term)temp)->type == REFPROJ0_)
+return (gen_e)((struct refProj0_ * ) temp)->f0;
+}
+return NULL;
+}
+
+label_term ref_proj0(aterm arg1) deletes
+ {
+label_term c;
+if (setif_is_var(arg1))
+{
+setif_var v = (setif_var)arg1;
+c = (label_term)sv_get_ub_proj(v,get_ref_proj0_arg);
+if (c != NULL)
+return c;
+else
+{
+aterm e;
+gen_e lb;
+gen_e_list_scanner scan;
+c = label_term_fresh(NULL);
+e = ref_pat0(c);
+sv_add_ub_proj(v,e);
+gen_e_list_scan(sv_get_lbs(v),&scan);
+while (gen_e_list_next(&scan,&lb))
+{
+setif_inclusion(aterm_con_match,aterm_res_proj,lb,e);
+}
+return c;
+}
+}
+else if ( ((setif_term)arg1)->type == REF_)
+return ((struct ref_ * )arg1)->f0;
+else if ( setif_is_zero(arg1))
+return label_term_zero();
+else if ( setif_is_union(arg1))
+{
+c = get_ref_proj0_arg(setif_get_proj_cache(arg1));
+if (c != NULL)
+return c;
+else
+{
+aterm e;
+c = label_term_fresh(NULL);
+e = ref_pat0(c);
+setif_set_proj_cache(arg1,e);
+aterm_inclusion(arg1,e);
+return c;
+}
+}
+else
+{
+aterm e;
+c = label_term_fresh(NULL);
+e = ref_pat0(c);
+aterm_inclusion(arg1,e);
+return c;
+}
+}
+
+static gen_e ref_pat0_con(gen_e arg1) deletes
+{
+return (gen_e)ref_pat0((label_term)arg1);
+}
+
+aterm ref_pat0(label_term arg1) deletes
+{
+struct refProj0_* ret;
+stamp s[2];
+s[0] = REFPROJ0_;
+s[1] = label_term_get_stamp((gen_e)arg1);
+if ((ret = (struct refProj0_ *)term_hash_find(setif_hash,s,2)) == NULL)
+{
+ret = ralloc(setif_region,struct refProj0_);
+ret->type = REFPROJ0_;
+ret->st = stamp_fresh();
+ret->f0 = arg1;
+term_hash_insert(setif_hash,(gen_e)ret,s,2);
+}
+return (aterm)ret;
+}
+
+static gen_e get_ref_proj1_arg(gen_e_list arg1)
+{
+gen_e temp;
+gen_e_list_scanner scan;
+gen_e_list_scan(arg1,&scan);
+while (gen_e_list_next(&scan,&temp))
+{
+if (((setif_term)temp)->type == REFPROJ1_)
+return (gen_e)((struct refProj1_ * ) temp)->f0;
+}
+return NULL;
+}
+
+aterm ref_proj1(aterm arg1) deletes
+ {
+aterm c;
+if (setif_is_var(arg1))
+{
+setif_var v = (setif_var)arg1;
+c = (aterm)sv_get_ub_proj(v,get_ref_proj1_arg);
+if (c != NULL)
+return c;
+else
+{
+aterm e;
+gen_e lb;
+gen_e_list_scanner scan;
+c = aterm_fresh(NULL);
+e = ref_pat1(c);
+sv_add_ub_proj(v,e);
+gen_e_list_scan(sv_get_lbs(v),&scan);
+while (gen_e_list_next(&scan,&lb))
+{
+setif_inclusion(aterm_con_match,aterm_res_proj,lb,e);
+}
+return c;
+}
+}
+else if ( ((setif_term)arg1)->type == REF_)
+return ((struct ref_ * )arg1)->f1;
+else if ( setif_is_zero(arg1))
+return aterm_zero();
+else if ( setif_is_union(arg1))
+{
+c = get_ref_proj1_arg(setif_get_proj_cache(arg1));
+if (c != NULL)
+return c;
+else
+{
+aterm e;
+c = aterm_fresh(NULL);
+e = ref_pat1(c);
+setif_set_proj_cache(arg1,e);
+aterm_inclusion(arg1,e);
+return c;
+}
+}
+else
+{
+aterm e;
+c = aterm_fresh(NULL);
+e = ref_pat1(c);
+aterm_inclusion(arg1,e);
+return c;
+}
+}
+
+static gen_e ref_pat1_con(gen_e arg1) deletes
+{
+return (gen_e)ref_pat1((aterm)arg1);
+}
+
+aterm ref_pat1(aterm arg1) deletes
+{
+struct refProj1_* ret;
+stamp s[2];
+s[0] = REFPROJ1_;
+s[1] = aterm_get_stamp((gen_e)arg1);
+if ((ret = (struct refProj1_ *)term_hash_find(setif_hash,s,2)) == NULL)
+{
+ret = ralloc(setif_region,struct refProj1_);
+ret->type = REFPROJ1_;
+ret->st = stamp_fresh();
+ret->f0 = arg1;
+term_hash_insert(setif_hash,(gen_e)ret,s,2);
+}
+return (aterm)ret;
+}
+
+static gen_e get_ref_proj2_arg(gen_e_list arg1)
+{
+gen_e temp;
+gen_e_list_scanner scan;
+gen_e_list_scan(arg1,&scan);
+while (gen_e_list_next(&scan,&temp))
+{
+if (((setif_term)temp)->type == REFPROJ2_)
+return (gen_e)((struct refProj2_ * ) temp)->f0;
+}
+return NULL;
+}
+
+aterm ref_proj2(aterm arg1) deletes
+ {
+aterm c;
+if (setif_is_var(arg1))
+{
+setif_var v = (setif_var)arg1;
+c = (aterm)sv_get_ub_proj(v,get_ref_proj2_arg);
+if (c != NULL)
+return c;
+else
+{
+aterm e;
+gen_e lb;
+gen_e_list_scanner scan;
+c = aterm_fresh(NULL);
+e = ref_pat2(c);
+sv_add_ub_proj(v,e);
+gen_e_list_scan(sv_get_lbs(v),&scan);
+while (gen_e_list_next(&scan,&lb))
+{
+setif_inclusion(aterm_con_match,aterm_res_proj,lb,e);
+}
+return c;
+}
+}
+else if ( ((setif_term)arg1)->type == REF_)
+return ((struct ref_ * )arg1)->f2;
+else if ( setif_is_zero(arg1))
+return aterm_zero();
+else if ( setif_is_union(arg1))
+{
+c = get_ref_proj2_arg(setif_get_proj_cache(arg1));
+if (c != NULL)
+return c;
+else
+{
+aterm e;
+c = aterm_fresh(NULL);
+e = ref_pat2(c);
+setif_set_proj_cache(arg1,e);
+aterm_inclusion(arg1,e);
+return c;
+}
+}
+else
+{
+aterm e;
+c = aterm_fresh(NULL);
+e = ref_pat2(c);
+aterm_inclusion(arg1,e);
+return c;
+}
+}
+
+static gen_e ref_pat2_con(gen_e arg1) deletes
+{
+return (gen_e)ref_pat2((aterm)arg1);
+}
+
+aterm ref_pat2(aterm arg1) deletes
+{
+struct refProj2_* ret;
+stamp s[2];
+s[0] = REFPROJ2_;
+s[1] = aterm_get_stamp((gen_e)arg1);
+if ((ret = (struct refProj2_ *)term_hash_find(setif_hash,s,2)) == NULL)
+{
+ret = ralloc(setif_region,struct refProj2_);
+ret->type = REFPROJ2_;
+ret->st = stamp_fresh();
+ret->f0 = arg1;
+term_hash_insert(setif_hash,(gen_e)ret,s,2);
+}
+return (aterm)ret;
+}
+
+bool aterm_is_lam(aterm e)
+{
+ return ((setif_term)e)->type == 15;
+}
+
+aterm lam(label_term arg1,argterm arg2,aterm arg3) deletes
+{
+struct lam_ *ret;
+stamp s[4];
+s[0] = LAM_;
+s[1] = label_term_get_stamp((gen_e)arg1);
+s[2] = argterm_get_stamp((gen_e)arg2);
+s[3] = aterm_get_stamp((gen_e)arg3);
+if ((ret = (struct lam_ *)term_hash_find(setif_hash,s,4)) == NULL)
+{
+ret = ralloc(setif_region,struct lam_);
+ret->type = s[0];
+ret->st = stamp_fresh();
+ret->f0 = arg1;
+ret->f1 = arg2;
+ret->f2 = arg3;
+term_hash_insert(setif_hash,(gen_e)ret,s,4);
+}
+return (aterm)ret;
+}
+
+struct lam_decon lam_decon(aterm arg1)
+{
+if (((setif_term)arg1)->type == LAM_)
+{
+struct lam_* c = (struct lam_ *)arg1;
+return (struct lam_decon){c->f0,c->f1,c->f2};
+
+}
+else
+return (struct lam_decon){NULL,NULL,NULL};
+}
+
+static gen_e get_lam_proj0_arg(gen_e_list arg1)
+{
+gen_e temp;
+gen_e_list_scanner scan;
+gen_e_list_scan(arg1,&scan);
+while (gen_e_list_next(&scan,&temp))
+{
+if (((setif_term)temp)->type == LAMPROJ0_)
+return (gen_e)((struct lamProj0_ * ) temp)->f0;
+}
+return NULL;
+}
+
+label_term lam_proj0(aterm arg1) deletes
+ {
+label_term c;
+if (setif_is_var(arg1))
+{
+setif_var v = (setif_var)arg1;
+c = (label_term)sv_get_ub_proj(v,get_lam_proj0_arg);
+if (c != NULL)
+return c;
+else
+{
+aterm e;
+gen_e lb;
+gen_e_list_scanner scan;
+c = label_term_fresh(NULL);
+e = lam_pat0(c);
+sv_add_ub_proj(v,e);
+gen_e_list_scan(sv_get_lbs(v),&scan);
+while (gen_e_list_next(&scan,&lb))
+{
+setif_inclusion(aterm_con_match,aterm_res_proj,lb,e);
+}
+return c;
+}
+}
+else if ( ((setif_term)arg1)->type == LAM_)
+return ((struct lam_ * )arg1)->f0;
+else if ( setif_is_zero(arg1))
+return label_term_zero();
+else if ( setif_is_union(arg1))
+{
+c = get_lam_proj0_arg(setif_get_proj_cache(arg1));
+if (c != NULL)
+return c;
+else
+{
+aterm e;
+c = label_term_fresh(NULL);
+e = lam_pat0(c);
+setif_set_proj_cache(arg1,e);
+aterm_inclusion(arg1,e);
+return c;
+}
+}
+else
+{
+aterm e;
+c = label_term_fresh(NULL);
+e = lam_pat0(c);
+aterm_inclusion(arg1,e);
+return c;
+}
+}
+
+static gen_e lam_pat0_con(gen_e arg1) deletes
+{
+return (gen_e)lam_pat0((label_term)arg1);
+}
+
+aterm lam_pat0(label_term arg1) deletes
+{
+struct lamProj0_* ret;
+stamp s[2];
+s[0] = LAMPROJ0_;
+s[1] = label_term_get_stamp((gen_e)arg1);
+if ((ret = (struct lamProj0_ *)term_hash_find(setif_hash,s,2)) == NULL)
+{
+ret = ralloc(setif_region,struct lamProj0_);
+ret->type = LAMPROJ0_;
+ret->st = stamp_fresh();
+ret->f0 = arg1;
+term_hash_insert(setif_hash,(gen_e)ret,s,2);
+}
+return (aterm)ret;
+}
+
+static gen_e get_lam_proj1_arg(gen_e_list arg1)
+{
+gen_e temp;
+gen_e_list_scanner scan;
+gen_e_list_scan(arg1,&scan);
+while (gen_e_list_next(&scan,&temp))
+{
+if (((setif_term)temp)->type == LAMPROJ1_)
+return (gen_e)((struct lamProj1_ * ) temp)->f0;
+}
+return NULL;
+}
+
+argterm lam_proj1(aterm arg1) deletes
+ {
+argterm c;
+if (setif_is_var(arg1))
+{
+setif_var v = (setif_var)arg1;
+c = (argterm)sv_get_ub_proj(v,get_lam_proj1_arg);
+if (c != NULL)
+return c;
+else
+{
+aterm e;
+gen_e lb;
+gen_e_list_scanner scan;
+c = argterm_fresh(NULL);
+e = lam_pat1(c);
+sv_add_ub_proj(v,e);
+gen_e_list_scan(sv_get_lbs(v),&scan);
+while (gen_e_list_next(&scan,&lb))
+{
+setif_inclusion(aterm_con_match,aterm_res_proj,lb,e);
+}
+return c;
+}
+}
+else if ( ((setif_term)arg1)->type == LAM_)
+return ((struct lam_ * )arg1)->f1;
+else if ( setif_is_zero(arg1))
+return argterm_zero();
+else if ( setif_is_union(arg1))
+{
+c = get_lam_proj1_arg(setif_get_proj_cache(arg1));
+if (c != NULL)
+return c;
+else
+{
+aterm e;
+c = argterm_fresh(NULL);
+e = lam_pat1(c);
+setif_set_proj_cache(arg1,e);
+aterm_inclusion(arg1,e);
+return c;
+}
+}
+else
+{
+aterm e;
+c = argterm_fresh(NULL);
+e = lam_pat1(c);
+aterm_inclusion(arg1,e);
+return c;
+}
+}
+
+static gen_e lam_pat1_con(gen_e arg1) deletes
+{
+return (gen_e)lam_pat1((argterm)arg1);
+}
+
+aterm lam_pat1(argterm arg1) deletes
+{
+struct lamProj1_* ret;
+stamp s[2];
+s[0] = LAMPROJ1_;
+s[1] = argterm_get_stamp((gen_e)arg1);
+if ((ret = (struct lamProj1_ *)term_hash_find(setif_hash,s,2)) == NULL)
+{
+ret = ralloc(setif_region,struct lamProj1_);
+ret->type = LAMPROJ1_;
+ret->st = stamp_fresh();
+ret->f0 = arg1;
+term_hash_insert(setif_hash,(gen_e)ret,s,2);
+}
+return (aterm)ret;
+}
+
+static gen_e get_lam_proj2_arg(gen_e_list arg1)
+{
+gen_e temp;
+gen_e_list_scanner scan;
+gen_e_list_scan(arg1,&scan);
+while (gen_e_list_next(&scan,&temp))
+{
+if (((setif_term)temp)->type == LAMPROJ2_)
+return (gen_e)((struct lamProj2_ * ) temp)->f0;
+}
+return NULL;
+}
+
+aterm lam_proj2(aterm arg1) deletes
+ {
+aterm c;
+if (setif_is_var(arg1))
+{
+setif_var v = (setif_var)arg1;
+c = (aterm)sv_get_ub_proj(v,get_lam_proj2_arg);
+if (c != NULL)
+return c;
+else
+{
+aterm e;
+gen_e lb;
+gen_e_list_scanner scan;
+c = aterm_fresh(NULL);
+e = lam_pat2(c);
+sv_add_ub_proj(v,e);
+gen_e_list_scan(sv_get_lbs(v),&scan);
+while (gen_e_list_next(&scan,&lb))
+{
+setif_inclusion(aterm_con_match,aterm_res_proj,lb,e);
+}
+return c;
+}
+}
+else if ( ((setif_term)arg1)->type == LAM_)
+return ((struct lam_ * )arg1)->f2;
+else if ( setif_is_zero(arg1))
+return aterm_zero();
+else if ( setif_is_union(arg1))
+{
+c = get_lam_proj2_arg(setif_get_proj_cache(arg1));
+if (c != NULL)
+return c;
+else
+{
+aterm e;
+c = aterm_fresh(NULL);
+e = lam_pat2(c);
+setif_set_proj_cache(arg1,e);
+aterm_inclusion(arg1,e);
+return c;
+}
+}
+else
+{
+aterm e;
+c = aterm_fresh(NULL);
+e = lam_pat2(c);
+aterm_inclusion(arg1,e);
+return c;
+}
+}
+
+static gen_e lam_pat2_con(gen_e arg1) deletes
+{
+return (gen_e)lam_pat2((aterm)arg1);
+}
+
+aterm lam_pat2(aterm arg1) deletes
+{
+struct lamProj2_* ret;
+stamp s[2];
+s[0] = LAMPROJ2_;
+s[1] = aterm_get_stamp((gen_e)arg1);
+if ((ret = (struct lamProj2_ *)term_hash_find(setif_hash,s,2)) == NULL)
+{
+ret = ralloc(setif_region,struct lamProj2_);
+ret->type = LAMPROJ2_;
+ret->st = stamp_fresh();
+ret->f0 = arg1;
+term_hash_insert(setif_hash,(gen_e)ret,s,2);
+}
+return (aterm)ret;
+}
+
+void aterm_print(FILE* arg1,aterm arg2) deletes
+{
+switch(((setif_term)arg2)->type)
+{
+case VAR_TYPE:
+fprintf(arg1,"%s",sv_get_name((setif_var)arg2));
+break;
+case ZERO_TYPE:
+fprintf(arg1,"0");
+break;
+case ONE_TYPE:
+fprintf(arg1,"1");
+break;
+case CONSTANT_TYPE:
+fprintf(arg1,setif_get_constant_name(arg2));
+break;
+case UNION_TYPE:
+{
+gen_e_list list = setif_get_union(arg2);
+gen_e_list_scanner scan;
+gen_e temp;
+gen_e_list_scan(list,&scan);
+if (gen_e_list_next(&scan,&temp))
+aterm_print(arg1,temp);
+while (gen_e_list_next(&scan,&temp))
+{
+fprintf(arg1," || ");
+aterm_print(arg1,temp);
+}
+
+}
+break;
+case INTER_TYPE:
+{
+gen_e_list list = setif_get_inter(arg2);
+gen_e_list_scanner scan;
+gen_e temp;
+gen_e_list_scan(list,&scan);
+if (gen_e_list_next(&scan,&temp))
+aterm_print(arg1,temp);
+while (gen_e_list_next(&scan,&temp))
+{
+fprintf(arg1," && ");
+aterm_print(arg1,temp);
+}
+
+}
+break;
+case REF_:
+{
+fprintf(arg1,"ref(");
+label_term_print(arg1,((struct ref_ *)arg2)->f0);
+fprintf(arg1,",");
+aterm_print(arg1,((struct ref_ *)arg2)->f1);
+fprintf(arg1,",");
+aterm_print(arg1,((struct ref_ *)arg2)->f2);
+fprintf(arg1,")");
+
+}
+break;
+case LAM_:
+{
+fprintf(arg1,"lam(");
+label_term_print(arg1,((struct lam_ *)arg2)->f0);
+fprintf(arg1,",");
+argterm_print(arg1,((struct lam_ *)arg2)->f1);
+fprintf(arg1,",");
+aterm_print(arg1,((struct lam_ *)arg2)->f2);
+fprintf(arg1,")");
+
+}
+break;
+case REFPROJ0_:
+{
+fprintf(arg1,"Proj[ref,0,");
+label_term_print(arg1,((struct refProj0_ *)arg2)->f0);
+fprintf(arg1,"]");
+
+}
+break;
+case REFPROJ1_:
+{
+fprintf(arg1,"Proj[ref,1,");
+aterm_print(arg1,((struct refProj1_ *)arg2)->f0);
+fprintf(arg1,"]");
+
+}
+break;
+case REFPROJ2_:
+{
+fprintf(arg1,"Proj[ref,2,");
+aterm_print(arg1,((struct refProj2_ *)arg2)->f0);
+fprintf(arg1,"]");
+
+}
+break;
+case LAMPROJ0_:
+{
+fprintf(arg1,"Proj[lam,0,");
+label_term_print(arg1,((struct lamProj0_ *)arg2)->f0);
+fprintf(arg1,"]");
+
+}
+break;
+case LAMPROJ1_:
+{
+fprintf(arg1,"Proj[lam,1,");
+argterm_print(arg1,((struct lamProj1_ *)arg2)->f0);
+fprintf(arg1,"]");
+
+}
+break;
+case LAMPROJ2_:
+{
+fprintf(arg1,"Proj[lam,2,");
+aterm_print(arg1,((struct lamProj2_ *)arg2)->f0);
+fprintf(arg1,"]");
+
+}
+break;
+
+default:
+return ;
+}
+
+}
+
+static bool aterm_res_proj(setif_var arg1,gen_e arg2) deletes
+{
+switch(((setif_term)arg2)->type)
+{
+case REFPROJ0_:
+return setif_proj_merge(arg1,(gen_e)((struct refProj0_ *)arg2)->f0,get_ref_proj0_arg,ref_pat0_con,(fresh_large_fn_ptr)label_term_fresh_large,(incl_fn_ptr)label_term_inclusion,aterm_inclusion);
+break;
+case REFPROJ1_:
+return setif_proj_merge(arg1,(gen_e)((struct refProj1_ *)arg2)->f0,get_ref_proj1_arg,ref_pat1_con,(fresh_large_fn_ptr)aterm_fresh_large,(incl_fn_ptr)aterm_inclusion_contra,aterm_inclusion);
+break;
+case REFPROJ2_:
+return setif_proj_merge(arg1,(gen_e)((struct refProj2_ *)arg2)->f0,get_ref_proj2_arg,ref_pat2_con,(fresh_large_fn_ptr)aterm_fresh_large,(incl_fn_ptr)aterm_inclusion,aterm_inclusion);
+break;
+case LAMPROJ0_:
+return setif_proj_merge(arg1,(gen_e)((struct lamProj0_ *)arg2)->f0,get_lam_proj0_arg,lam_pat0_con,(fresh_large_fn_ptr)label_term_fresh_large,(incl_fn_ptr)label_term_inclusion,aterm_inclusion);
+break;
+case LAMPROJ1_:
+return setif_proj_merge(arg1,(gen_e)((struct lamProj1_ *)arg2)->f0,get_lam_proj1_arg,lam_pat1_con,(fresh_large_fn_ptr)argterm_fresh_large,(incl_fn_ptr)argterm_inclusion_contra,aterm_inclusion);
+break;
+case LAMPROJ2_:
+return setif_proj_merge(arg1,(gen_e)((struct lamProj2_ *)arg2)->f0,get_lam_proj2_arg,lam_pat2_con,(fresh_large_fn_ptr)aterm_fresh_large,(incl_fn_ptr)aterm_inclusion,aterm_inclusion);
+break;
+
+default:
+return FALSE;
+}
+
+return FALSE;
+}
+
+static void aterm_con_match(gen_e arg1,gen_e arg2) deletes
+{
+switch(((setif_term)arg1)->type)
+{
+case REF_:
+switch(((setif_term)arg2)->type)
+{
+case REF_:
+{
+label_term_inclusion(((struct ref_ *)arg1)->f0,((struct ref_ *)arg2)->f0);
+aterm_inclusion_contra(((struct ref_ *)arg1)->f1,((struct ref_ *)arg2)->f1);
+aterm_inclusion(((struct ref_ *)arg1)->f2,((struct ref_ *)arg2)->f2);
+
+}
+break;
+case REFPROJ0_:
+label_term_inclusion(((struct ref_ *)arg1)->f0,((struct refProj0_ *)arg2)->f0);
+break;
+case REFPROJ1_:
+aterm_inclusion_contra(((struct ref_ *)arg1)->f1,((struct refProj1_ *)arg2)->f0);
+break;
+case REFPROJ2_:
+aterm_inclusion(((struct ref_ *)arg1)->f2,((struct refProj2_ *)arg2)->f0);
+break;
+case LAMPROJ0_:
+return ;
+break;
+case LAMPROJ1_:
+return ;
+break;
+case LAMPROJ2_:
+return ;
+break;
+
+default:
+failure("Inconsistent system of constraints\n");
+}
+
+break;
+case LAM_:
+switch(((setif_term)arg2)->type)
+{
+case LAM_:
+{
+label_term_inclusion(((struct lam_ *)arg1)->f0,((struct lam_ *)arg2)->f0);
+argterm_inclusion_contra(((struct lam_ *)arg1)->f1,((struct lam_ *)arg2)->f1);
+aterm_inclusion(((struct lam_ *)arg1)->f2,((struct lam_ *)arg2)->f2);
+
+}
+break;
+case LAMPROJ0_:
+label_term_inclusion(((struct lam_ *)arg1)->f0,((struct lamProj0_ *)arg2)->f0);
+break;
+case LAMPROJ1_:
+argterm_inclusion_contra(((struct lam_ *)arg1)->f1,((struct lamProj1_ *)arg2)->f0);
+break;
+case LAMPROJ2_:
+aterm_inclusion(((struct lam_ *)arg1)->f2,((struct lamProj2_ *)arg2)->f0);
+break;
+case REFPROJ0_:
+return ;
+break;
+case REFPROJ1_:
+return ;
+break;
+case REFPROJ2_:
+return ;
+break;
+
+default:
+failure("Inconsistent system of constraints\n");
+}
+
+break;
+
+default:
+failure("Inconsistent system of constraints\n");
+}
+
+return;
+}
+
+void andersen_terms_init(void)
+{
+engine_init();
+setif_init();
+setif_init();
+flowrow_init();
+}
+
+void andersen_terms_reset(void) deletes
+{
+setif_reset();
+setif_reset();
+flowrow_reset();
+engine_reset();
+}
+
+void andersen_terms_stats(FILE * arg1)
+{
+engine_stats(arg1);
+}
+
+void andersen_terms_print_graph(FILE * arg1)
+{
+print_constraint_graphs(arg1);
+}
+
diff --git a/libbanshee/points-to/andersen_terms.h b/libbanshee/points-to/andersen_terms.h
new file mode 100644
index 00000000000..b893c573496
--- /dev/null
+++ b/libbanshee/points-to/andersen_terms.h
@@ -0,0 +1,100 @@
+/*
+
+DO NOT edit this file
+
+*/
+#ifndef ANDERSEN_TERMS_H
+#define ANDERSEN_TERMS_H
+#include <engine/list.h>
+#include <stdio.h>
+#include <engine/bool.h>
+
+
+typedef struct label_term_* label_term;
+typedef struct argterm_* argterm;
+typedef struct argterm_field_* argterm_field;
+typedef struct aterm_* aterm;
+
+extern bool flag_merge_projections;
+extern bool flag_eliminate_cycles;
+DECLARE_LIST(label_term_list,label_term)
+label_term label_term_zero(void);
+label_term label_term_one(void);
+label_term label_term_fresh(const char *name);
+label_term label_term_union(label_term_list exprs) ;
+label_term label_term_inter(label_term_list exprs) ;
+label_term label_term_constant(const char *name) ;
+bool label_term_is_constant(label_term e,const char *name);
+void label_term_inclusion(label_term e1,label_term e2) ;
+void label_term_unify(label_term e1,label_term e2) ;
+label_term_list label_term_tlb(label_term e) ;
+
+void label_term_print(FILE* arg1,label_term arg2) ;
+DECLARE_LIST(argterm_map,argterm_field)
+argterm_field argterm_make_field(const char *label,aterm expr);
+argterm argterm_zero(void);
+argterm argterm_one(void);
+argterm argterm_abs(void);
+argterm argterm_wild(void);
+argterm argterm_fresh(const char *name);
+argterm argterm_row(argterm_map fields,argterm rest) ;
+aterm argterm_extract_field(const char *field_name,argterm row);
+argterm argterm_extract_rest(argterm row);
+argterm_map argterm_extract_fields(argterm row);
+void argterm_inclusion(argterm row1,argterm row2) ;
+void argterm_unify(argterm row1,argterm row2) ;
+void argterm_print(FILE *f,argterm row) ;
+
+DECLARE_LIST(aterm_list,aterm)
+aterm aterm_zero(void);
+aterm aterm_one(void);
+aterm aterm_fresh(const char *name);
+aterm aterm_union(aterm_list exprs) ;
+aterm aterm_inter(aterm_list exprs) ;
+aterm aterm_constant(const char *name) ;
+bool aterm_is_constant(aterm e,const char *name);
+void aterm_inclusion(aterm e1,aterm e2) ;
+void aterm_unify(aterm e1,aterm e2) ;
+aterm_list aterm_tlb(aterm e) ;
+
+bool aterm_is_ref(aterm e);
+aterm ref(label_term arg1,aterm arg2,aterm arg3) ;
+struct ref_decon ref_decon(aterm arg1);
+struct ref_decon
+{
+label_term f0;
+aterm f1;
+aterm f2;
+};
+label_term ref_proj0(aterm arg1) ;
+aterm ref_pat0(label_term arg1) ;
+aterm ref_proj1(aterm arg1) ;
+aterm ref_pat1(aterm arg1) ;
+aterm ref_proj2(aterm arg1) ;
+aterm ref_pat2(aterm arg1) ;
+bool aterm_is_lam(aterm e);
+aterm lam(label_term arg1,argterm arg2,aterm arg3) ;
+struct lam_decon lam_decon(aterm arg1);
+struct lam_decon
+{
+label_term f0;
+argterm f1;
+aterm f2;
+};
+label_term lam_proj0(aterm arg1) ;
+aterm lam_pat0(label_term arg1) ;
+argterm lam_proj1(aterm arg1) ;
+aterm lam_pat1(argterm arg1) ;
+aterm lam_proj2(aterm arg1) ;
+aterm lam_pat2(aterm arg1) ;
+void aterm_print(FILE* arg1,aterm arg2) ;
+/*
+
+Init/reset engine, print constraint graphs
+
+*/
+void andersen_terms_init(void);
+void andersen_terms_reset(void) ;
+void andersen_terms_stats(FILE * arg1);
+void andersen_terms_print_graph(FILE * arg1);
+#endif
diff --git a/libbanshee/points-to/andersen_terms.spec b/libbanshee/points-to/andersen_terms.spec
new file mode 100644
index 00000000000..244f643f908
--- /dev/null
+++ b/libbanshee/points-to/andersen_terms.spec
@@ -0,0 +1,34 @@
+% Copyright (c) 2000-2001
+% The Regents of the University of California. All rights reserved.
+%
+% Redistribution and use in source and binary forms, with or without
+% modification, are permitted provided that the following conditions
+% are met:
+% 1. Redistributions of source code must retain the above copyright
+% notice, this list of conditions and the following disclaimer.
+% 2. Redistributions in binary form must reproduce the above copyright
+% notice, this list of conditions and the following disclaimer in the
+% documentation and/or other materials provided with the distribution.
+% 3. Neither the name of the University nor the names of its contributors
+% may be used to endorse or promote products derived from this software
+% without specific prior written permission.
+%
+% THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+% ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+% ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+% FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+% DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+% OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+% HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+% LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+% SUCH DAMAGE.
+
+specification andersen_terms : ANDERSEN_TERMS =
+ spec
+ data label_term : set
+ data aterm : set = ref of +label_term * -aterm * +aterm
+ | lam of +label_term * -argterm * +aterm
+ and argterm : row(aterm)
+ end
diff --git a/libbanshee/points-to/andersen_terms_st.spec b/libbanshee/points-to/andersen_terms_st.spec
new file mode 100644
index 00000000000..0984e001e5b
--- /dev/null
+++ b/libbanshee/points-to/andersen_terms_st.spec
@@ -0,0 +1,34 @@
+% Copyright (c) 2000-2001
+% The Regents of the University of California. All rights reserved.
+%
+% Redistribution and use in source and binary forms, with or without
+% modification, are permitted provided that the following conditions
+% are met:
+% 1. Redistributions of source code must retain the above copyright
+% notice, this list of conditions and the following disclaimer.
+% 2. Redistributions in binary form must reproduce the above copyright
+% notice, this list of conditions and the following disclaimer in the
+% documentation and/or other materials provided with the distribution.
+% 3. Neither the name of the University nor the names of its contributors
+% may be used to endorse or promote products derived from this software
+% without specific prior written permission.
+%
+% THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+% ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+% ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+% FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+% DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+% OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+% HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+% LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+% SUCH DAMAGE.
+
+specification andersen_terms : ANDERSEN_TERMS =
+ spec
+ data label_term : setST
+ data aterm : setST = ref of +label_term * -aterm * +aterm
+ | lam of +label_term * -argterm * +aterm
+ and argterm : row(aterm)
+ end
diff --git a/libbanshee/stamp-h.in b/libbanshee/stamp-h.in
new file mode 100644
index 00000000000..9788f70238c
--- /dev/null
+++ b/libbanshee/stamp-h.in
@@ -0,0 +1 @@
+timestamp
diff --git a/libffi/ChangeLog b/libffi/ChangeLog
index d43fd647d3d..47ddae9a98c 100644
--- a/libffi/ChangeLog
+++ b/libffi/ChangeLog
@@ -1,10 +1,30 @@
+2004-04-26 Joe Buck <jbuck@welsh-buck.org>
+
+ Bug 15093
+ * configure.ac: Test for existence of mmap and sys/mman.h before
+ checking blacklist. Fix suggested by Jim Wilson.
+ * configure: Regenerate.
+
+2004-04-26 Matt Austern <austern@apple.com>
+
+ * src/powerpc/darwin.S: Go through a non-lazy pointer for initial
+ FDE location.
+ * src/powerpc/darwin_closure.S: Likewise.
+
+2004-04-24 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * testsuite/libffi.call/cls_multi_schar.c (main): Fix initialization
+ error. Reported by Thomas Heller <theller@python.net>.
+ * testsuite/libffi.call/cls_multi_sshort.c (main): Likewise.
+ * testsuite/libffi.call/cls_multi_ushort.c (main): Likewise.
+
2004-03-20 Matthias Klose <doko@debian.org>
* src/pa/linux.S: Fix typo.
2004-03-19 Matthias Klose <doko@debian.org>
- * Makefile.am: Update
+ * Makefile.am: Update.
* Makefile.in: Regenerate.
* src/pa/ffi.h.in: Remove.
* src/pa/ffitarget.h: New file.
diff --git a/libffi/configure b/libffi/configure
index a40d6992a10..9a76fd1d79b 100755
--- a/libffi/configure
+++ b/libffi/configure
@@ -273,7 +273,44 @@ PACKAGE_VERSION='2.1'
PACKAGE_STRING='libffi 2.1'
PACKAGE_BUGREPORT='http://gcc.gnu.org/bugs.html'
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS multi_basedir build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE am__leading_dot CC ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CFLAGS CCAS CCASFLAGS LN_S RANLIB ac_ct_RANLIB LIBTOOL MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT TESTSUBDIR_TRUE TESTSUBDIR_FALSE AM_RUNTESTFLAGS MIPS_IRIX_TRUE MIPS_IRIX_FALSE MIPS_LINUX_TRUE MIPS_LINUX_FALSE SPARC_TRUE SPARC_FALSE X86_TRUE X86_FALSE X86_WIN32_TRUE X86_WIN32_FALSE ALPHA_TRUE ALPHA_FALSE IA64_TRUE IA64_FALSE M68K_TRUE M68K_FALSE POWERPC_TRUE POWERPC_FALSE POWERPC_AIX_TRUE POWERPC_AIX_FALSE POWERPC_DARWIN_TRUE POWERPC_DARWIN_FALSE ARM_TRUE ARM_FALSE S390_TRUE S390_FALSE X86_64_TRUE X86_64_FALSE SH_TRUE SH_FALSE SH64_TRUE SH64_FALSE PA_TRUE PA_FALSE CPP CPPFLAGS EGREP ALLOCA HAVE_LONG_DOUBLE TARGET TARGETDIR toolexecdir toolexeclibdir tool_include_dir gcc_version LIBOBJS LTLIBOBJS'
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS multi_basedir build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE am__leading_dot CC ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CFLAGS CCAS CCASFLAGS LN_S RANLIB ac_ct_RANLIB LIBTOOL MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT CPP CPPFLAGS EGREP TESTSUBDIR_TRUE TESTSUBDIR_FALSE AM_RUNTESTFLAGS MIPS_IRIX_TRUE MIPS_IRIX_FALSE MIPS_LINUX_TRUE MIPS_LINUX_FALSE SPARC_TRUE SPARC_FALSE X86_TRUE X86_FALSE X86_WIN32_TRUE X86_WIN32_FALSE ALPHA_TRUE ALPHA_FALSE IA64_TRUE IA64_FALSE M68K_TRUE M68K_FALSE POWERPC_TRUE POWERPC_FALSE POWERPC_AIX_TRUE POWERPC_AIX_FALSE POWERPC_DARWIN_TRUE POWERPC_DARWIN_FALSE ARM_TRUE ARM_FALSE S390_TRUE S390_FALSE X86_64_TRUE X86_64_FALSE SH_TRUE SH_FALSE SH64_TRUE SH64_FALSE PA_TRUE PA_FALSE ALLOCA HAVE_LONG_DOUBLE TARGET TARGETDIR toolexecdir toolexeclibdir tool_include_dir gcc_version LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@@ -925,7 +962,7 @@ esac
else
echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
fi
- cd "$ac_popdir"
+ cd $ac_popdir
done
fi
@@ -2409,7 +2446,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2467,7 +2505,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2583,7 +2622,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2637,7 +2677,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2682,7 +2723,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2726,7 +2768,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3788,7 +3831,7 @@ test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic"
case $host in
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 3791 "configure"' > conftest.$ac_ext
+ echo '#line 3834 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -3930,7 +3973,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -4099,6 +4143,746 @@ fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+ then ac_cv_prog_egrep='grep -E'
+ else ac_cv_prog_egrep='egrep'
+ fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_stdc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ exit(2);
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_Header=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+for ac_header in sys/mman.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------------- ##
+## Report this to http://gcc.gnu.org/bugs.html ##
+## ------------------------------------------- ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_func in mmap
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
if test $ac_cv_header_sys_mman_h != yes \
|| test $ac_cv_func_mmap != yes; then
ac_cv_func_mmap_file=no
@@ -4186,7 +4970,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -4488,256 +5273,6 @@ case x$TARGET in
*) ;;
esac
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
-echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
-fi
-if test -z "$CPP"; then
- if test "${ac_cv_prog_CPP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- # Double quotes because CPP needs to be expanded
- for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
- do
- ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether non-existent headers
- # can be detected and how.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- # Broken: success on invalid input.
-continue
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
- break
-fi
-
- done
- ac_cv_prog_CPP=$CPP
-
-fi
- CPP=$ac_cv_prog_CPP
-else
- ac_cv_prog_CPP=$CPP
-fi
-echo "$as_me:$LINENO: result: $CPP" >&5
-echo "${ECHO_T}$CPP" >&6
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether non-existent headers
- # can be detected and how.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- # Broken: success on invalid input.
-continue
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
- :
-else
- { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&5
-echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-echo "$as_me:$LINENO: checking for egrep" >&5
-echo $ECHO_N "checking for egrep... $ECHO_C" >&6
-if test "${ac_cv_prog_egrep+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if echo a | (grep -E '(a|b)') >/dev/null 2>&1
- then ac_cv_prog_egrep='grep -E'
- else ac_cv_prog_egrep='egrep'
- fi
-fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
-echo "${ECHO_T}$ac_cv_prog_egrep" >&6
- EGREP=$ac_cv_prog_egrep
-
-
echo "$as_me:$LINENO: checking for ANSI C header files" >&5
echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
if test "${ac_cv_header_stdc+set}" = set; then
@@ -4771,7 +5306,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -4972,7 +5508,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5035,7 +5572,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5116,7 +5654,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5257,7 +5796,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5394,7 +5934,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5464,7 +6005,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5551,7 +6093,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5592,7 +6135,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5760,7 +6304,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5826,7 +6371,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -6842,6 +7388,9 @@ s,@LIBTOOL@,$LIBTOOL,;t t
s,@MAINTAINER_MODE_TRUE@,$MAINTAINER_MODE_TRUE,;t t
s,@MAINTAINER_MODE_FALSE@,$MAINTAINER_MODE_FALSE,;t t
s,@MAINT@,$MAINT,;t t
+s,@CPP@,$CPP,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@EGREP@,$EGREP,;t t
s,@TESTSUBDIR_TRUE@,$TESTSUBDIR_TRUE,;t t
s,@TESTSUBDIR_FALSE@,$TESTSUBDIR_FALSE,;t t
s,@AM_RUNTESTFLAGS@,$AM_RUNTESTFLAGS,;t t
@@ -6879,9 +7428,6 @@ s,@SH64_TRUE@,$SH64_TRUE,;t t
s,@SH64_FALSE@,$SH64_FALSE,;t t
s,@PA_TRUE@,$PA_TRUE,;t t
s,@PA_FALSE@,$PA_FALSE,;t t
-s,@CPP@,$CPP,;t t
-s,@CPPFLAGS@,$CPPFLAGS,;t t
-s,@EGREP@,$EGREP,;t t
s,@ALLOCA@,$ALLOCA,;t t
s,@HAVE_LONG_DOUBLE@,$HAVE_LONG_DOUBLE,;t t
s,@TARGET@,$TARGET,;t t
@@ -7058,6 +7604,11 @@ esac
*) ac_INSTALL=$ac_top_builddir$INSTALL ;;
esac
+ if test x"$ac_file" != x-; then
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ rm -f "$ac_file"
+ fi
# Let's still pretend it is `configure' which instantiates (i.e., don't
# use $as_me), people would be surprised to read:
# /* config.h. Generated by config.status. */
@@ -7096,12 +7647,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
fi;;
esac
done` || { (exit 1); exit 1; }
-
- if test x"$ac_file" != x-; then
- { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
- rm -f "$ac_file"
- fi
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
sed "$ac_vpsub
diff --git a/libffi/configure.ac b/libffi/configure.ac
index 584a7d8a15f..c6be71c733a 100644
--- a/libffi/configure.ac
+++ b/libffi/configure.ac
@@ -37,6 +37,8 @@ AC_PROG_LIBTOOL
AM_MAINTAINER_MODE
+AC_CHECK_HEADERS(sys/mman.h)
+AC_CHECK_FUNCS(mmap)
AC_FUNC_MMAP_BLACKLIST
dnl The -no-testsuite modules omit the test subdir.
diff --git a/libffi/src/powerpc/darwin.S b/libffi/src/powerpc/darwin.S
index ad4824e2762..cbbac960d4a 100644
--- a/libffi/src/powerpc/darwin.S
+++ b/libffi/src/powerpc/darwin.S
@@ -187,7 +187,7 @@ LSFDE1:
.long L$set$1 ; FDE Length
LASFDE1:
.long LASFDE1-EH_frame1 ; FDE CIE offset
- .long LFB0-. ; FDE initial location
+ .long LLFB0$non_lazy_ptr-. ; FDE initial location
.set L$set$3,LFE1-LFB0
.long L$set$3 ; FDE address range
.byte 0x0 ; uleb128 0x0; Augmentation size
@@ -217,3 +217,7 @@ LASFDE1:
.byte 0x1c ; uleb128 0x1c
.align 2
LEFDE1:
+.data
+ .align 2
+LLFB0$non_lazy_ptr:
+ .long LFB0
diff --git a/libffi/src/powerpc/darwin_closure.S b/libffi/src/powerpc/darwin_closure.S
index 13ee81d6049..f608e6d0b9d 100644
--- a/libffi/src/powerpc/darwin_closure.S
+++ b/libffi/src/powerpc/darwin_closure.S
@@ -260,7 +260,7 @@ LSFDE1:
LASFDE1:
.long LASFDE1-EH_frame1 ; FDE CIE offset
- .long LFB1-. ; FDE initial location
+ .long LLFB1$non_lazy_ptr-. ; FDE initial location
.set L$set$3,LFE1-LFB1
.long L$set$3 ; FDE address range
.byte 0x0 ; uleb128 0x0; Augmentation size
@@ -298,3 +298,7 @@ LO$ffi_closure_helper_DARWIN:
L_ffi_closure_helper_DARWIN$lazy_ptr:
.indirect_symbol _ffi_closure_helper_DARWIN
.long dyld_stub_binding_helper
+.data
+ .align 2
+LLFB1$non_lazy_ptr:
+ .long LFB1
diff --git a/libffi/testsuite/libffi.call/cls_multi_schar.c b/libffi/testsuite/libffi.call/cls_multi_schar.c
index 6457336661f..30a89e6284e 100644
--- a/libffi/testsuite/libffi.call/cls_multi_schar.c
+++ b/libffi/testsuite/libffi.call/cls_multi_schar.c
@@ -55,7 +55,7 @@ int main (void)
args_dbl[0] = &a;
args_dbl[1] = &b;
- args_dbl[3] = NULL;
+ args_dbl[2] = NULL;
cl_arg_types[0] = &ffi_type_schar;
cl_arg_types[1] = &ffi_type_schar;
diff --git a/libffi/testsuite/libffi.call/cls_multi_sshort.c b/libffi/testsuite/libffi.call/cls_multi_sshort.c
index eaa15d8cdc1..e19c8b85dd8 100644
--- a/libffi/testsuite/libffi.call/cls_multi_sshort.c
+++ b/libffi/testsuite/libffi.call/cls_multi_sshort.c
@@ -55,7 +55,7 @@ int main (void)
args_dbl[0] = &a;
args_dbl[1] = &b;
- args_dbl[3] = NULL;
+ args_dbl[2] = NULL;
cl_arg_types[0] = &ffi_type_sshort;
cl_arg_types[1] = &ffi_type_sshort;
diff --git a/libffi/testsuite/libffi.call/cls_multi_ushort.c b/libffi/testsuite/libffi.call/cls_multi_ushort.c
index e6ae9aa0755..7ef7b005fae 100644
--- a/libffi/testsuite/libffi.call/cls_multi_ushort.c
+++ b/libffi/testsuite/libffi.call/cls_multi_ushort.c
@@ -55,7 +55,7 @@ int main (void)
args_dbl[0] = &a;
args_dbl[1] = &b;
- args_dbl[3] = NULL;
+ args_dbl[2] = NULL;
cl_arg_types[0] = &ffi_type_ushort;
cl_arg_types[1] = &ffi_type_ushort;
diff --git a/libgfortran/AUTHORS b/libgfortran/AUTHORS
new file mode 100644
index 00000000000..4926bede9c8
--- /dev/null
+++ b/libgfortran/AUTHORS
@@ -0,0 +1,2 @@
+Paul Brook <paul@nowt.org>
+Jeremy Sanders <jeremy@jeremysanders.net>
diff --git a/libgfortran/COPYING b/libgfortran/COPYING
new file mode 100644
index 00000000000..15a6fe93154
--- /dev/null
+++ b/libgfortran/COPYING
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
new file mode 100644
index 00000000000..bbf22d4d082
--- /dev/null
+++ b/libgfortran/ChangeLog
@@ -0,0 +1,769 @@
+2004-05-14 Bud Davis <bdavis9659@comcast.net>
+
+ PR fortran/15149
+ * libgfortan.h,intrinsics/random.c: Made random_seed visible.
+ * runtime/main.c(init): Call random_seed as part of MAIN init.
+
+2004-05-13 Tobias Schlüter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * io/format.c: (parse_format_list): No comma is required after
+ P descriptor.
+
+2004-05-13 Bud Davis <bdavis9659@comcast.net>
+
+ PR fortran/15204
+ * io/intrinsic/string_intrinsics.c (adjustr): rework logic.
+
+2004-05-06 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+ Steven Bosscher <stevenb@suse.de>
+
+ PR libfortran/15234
+ * libgfortran.h: Include <inttypes.h> if available.
+
+2004-05-03 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * io/unix.c (MAP_FAILED): Define if missing.
+ (mmap_alloc): Cast MAP_FAILED to char *.
+ (mmap_open): Likewise.
+
+2004-04-26 Bud Davis <bdavis9659@comcast.net>
+
+ * generated/_abs_i8.f90: New file.
+ * generated/_abs_c4.f90: New file.
+ * generated/_abs_c8.f90: New file.
+ * Makefile.am: Add them.
+ * Makefile.in: Regenerate.
+`
+2004-04-26 Bud Davis <bdavis9659@comcast.net>
+
+ PR fortran/14056
+ * generated/_abs_i4.f90: New file.
+ * Makefile.am: Add it.
+ * Makefile.in: Regenerate.
+
+2004-04-25 Bud Davis <bdavis9659@comcast.net>
+
+ PR fortran/14942
+ * io/list_read.c(list_formatted_read): finish consuming the
+ spaces and seperators at eoln to get ready for next item.
+
+2004-04-23 Bud Davis <bdavis9659@comcast.net>
+
+ PR fortran/15113
+ * io/read.c(read_a): Handle field width > destination and no field width.
+
+2004-04-22 Bud Davis <bdavis9659@comcast.net>
+
+ PR fortran/14906
+ * io/format.c (format_item): gracefully handle a ')'
+ when it is the first character encountered in the string.
+
+2004-04-11 Bud Davis <bdavis9659@comcast.net>
+
+ PR fortran/14904
+ * io/transfer.c (next_record): Update last_record when
+ more than one record is written to a direct access file
+ with one write statement.
+
+2004-04-11 Bud Davis <bdavis9659@comcast.net>
+
+ PR fortran/14901
+ * io/transfer.c (next_record_w) : No '\n' if internal.
+ * io/unix.c (empty_internal_buffer) : Init to spaces, not '\n'.
+
+2004-04-11 Bud Davis <bdavis9659@comcast.net>
+
+ * io.h (ioparm): Interface from FE is 32 bit, irregardless of offset_t.
+ Will need to change this later to support direct access files > 2gb.
+
+2004-04-03 Bud Davis <bdavis9659@comcast.net>
+
+ PR gfortran/14762
+ * io/transfer.c (next_record_r) : Skip to next record.
+
+2004-04-03 Bud Davis <bdavis9659@comcast.net>
+
+ PR gfortran/14836
+ * io/transfer.c (next_record): Update last_record for DIRECT
+
+2004-04-03 Bud Davis <bdavis9659@comcast.net>
+
+ PR gfortran/14837
+ * io/unix.c (find_file0): Use fd field of struct
+
+2004-04-03 Bud Davis <bdavis9659@comcast.net>
+
+ PR 14831
+ * io/inquire.c (inquire_via_unit): Changed return string for
+ BLANK=NULL. Use correct variable for ACTION.
+
+2004-04-01 Bud Davis <bdavis9659@comcast.net>
+
+ PR 14746
+ * io/read.c (read_f): Allow a decimal without a leading digit.
+ * io/write.c (output_float): remove a leading '0' to keep from
+ overflowing the field (F edit descriptor).
+
+2004-04-01 Bud Davis <bdavis9659@comcast.net>
+
+ PR gfortran/14565
+ * io/open.c (new_unit),
+ * io/io.h : new_unit is now visible
+ * io/transfer.c (data_transfer_init): open unit if no OPEN statement.
+ * io/transfer.c (data_transfer_init): remove compile warnings.
+ * io/rewind.c (st_rewind): ftruncate if writing.
+
+2004-03-24 Bud Davis <bdavis9659@comcast.net>
+
+ * write.c (write_l): Use extract_int for 'L' edit descriptor.
+
+2004-03-24 Bud Davis <bdavis9659@comcast.net>
+
+ PR 13919
+ * io/io.h (global_t):
+ * io/list_read.c (next_char,list_formatted_read,ist_formatted_read):
+ Move eof_jmp to a global structure.
+ * io/transfer.c(finalize_transfer) : Set up eof_jump for callers.
+
+2004-03-24 Bud Davis <bdavis9659@comcast.net>
+
+ * m4/cexp.m4 (csqrt): Actually use the passed value.
+ * generated/exp_c?.c: Regenerate.
+
+2004-03-24 Bud Davis <bdavis9659@comcast.net>
+
+ PR 12921
+ * io.h, transfer.c, open.c : recl_in changed from ptr to variable.
+ * open.c (new_unit): Moved test for positioned direct access error.
+ (init_units): Corrected calculation of max records.
+
+2004-02-06 Feng Wang <fengwang@nudt.edu.cn>
+
+ * Makefile.am: Add m4/dotprodc.m4. And fix spelling.
+ * Makefile.in: Regenerate.
+ * m4/dotprodc.m4: New file. Implement complex dot_product.
+ * m4/dotprod.m4: Delete the complex implementation.
+ * generated/dotprod_*: Update.
+
+2004-02-07 Bud Davis <bdavis9659@comcast.net>
+
+ * transfer.c (write_constant_string): Do not delete H's in hollerith
+ formats.
+
+2004-01-05 Andrew Pinski <apinski@apple.com>
+
+ * configure.in: Check for csin in -lmx also.
+ * configure: Regenerate.
+
+2004-01-01 Paul Brook <paul@codesourcery.com>
+
+ * io/list_read.c (find_nml_node): Make static.
+ (match_namelist_name): Ditto.
+ * io/read.c (convert_precision_real): Make static, fix spelling.
+ * io/transfer.c (extract_real): Remove unused prototype.
+ (st_set_nml_var): Make static.
+ * io/write.c (extract_real): Make static.
+
+2003-12-12 Huang Chun <chunhuang73@hotmal.com>
+
+ * intrinsics/string_intrinsics.c (string_index): Fix logics thinko.
+
+2003-12-05 Melvin Hadasht <melvin.hadasht@free.fr>
+
+ * io/transfer.c (data_transfer_init): Give a runtime error for list
+ formatted reads and writes from/to files opened for unformatted IO.
+
+2003-11-30 Paul Brook <paul@nowt.org>
+
+ * runtime/memory.c (push_context): Remove.
+ (pop_context): Remove.
+ * libgfortran.h: Remove prototypes.
+
+2003-11-27 Paul Brook <paul@nowt.org>
+
+ * runtime/memory.c (deallocate): Nullify pointer after freeing.
+
+2003-11-27 Paul Brook <paul@nowt.org>
+
+ * intrinsics/string_intrinsics.c: Use new memory allocation interface.
+ * libgfortran.h: Ditto.
+ * m4/in_pack.m4: Ditto.
+ * runtime/in_pack_generic.c: Ditto.
+ * runtime/memory.c: Ditto.
+
+2003-11-26 Richard Henderson <rth@redhat.com>
+
+ * m4/exponent.m4, m4/fraction.m4: New.
+ * m4/nearest.m4, m4/set_exponent.m4: New.
+ * generated/*: Update.
+ * Makefile.am: Add them.
+ (AM_CFLAGS): New. Use -std=gnu99.
+ * Makefile.in: Regenerate.
+
+2003-11-08 Paul Brook <paul@nowt.org>
+
+ PR fortran/12704
+ * m4/maxloc0.m4: Use default value of 1. Handle zero sized arrays.
+ * m4/maxloc1.m4: Ditto.
+ * m4/minloc0.m4: Ditto.
+ * m4/minloc1.m4: Ditto.
+ * m4/ifunction.m4: Set return value for zero sized arrays.
+ * m4/iforeach.m4: Ditto.
+ * m4/all.m4, m4/any.m4, m4/count.m4, m4/maxloc1.m4, m4/minloc1.m4,
+ m4/mxaval.m4, m4/minval.m4, m4/product.m4, m4/sum.m4: Ditto.
+ * generated/*: Update.
+
+2003-10-30 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ PR fortran/12702
+ * io/list_read.c (eat_spaces): Treat tab as space.
+
+2003-10-30 Lars Segerlund <Lars.Segerlund@comsys.se>
+
+ * intrinsics/random.c: Add reference to paper containing algorithm.
+ (random_seed): Extra error checking and proper handling of arrays.
+ (arandom_r4, arandom_r8): Implement.
+
+2003-10-29 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ PR fortran/12703
+ * runtime/memory.c (allocate_size): Allow allocation
+ of zero-sized objects.
+
+2003-10-29 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ PR fortran/12701
+ * open.c (new_unit): Open without a file name opens
+ a file with name fort.<unit>.
+
+2003-10-12 Feng Wang <wf_cs@yahoo.com>
+
+ * intrinsics/cshift0.c: New file.
+ * m4/cshift1.m4: New file
+ * generated/cshift*.c: New files.
+ * Makefile.am: Add them.
+ * Makefile.in: Regenerate.
+
+2003-10-12 XiaoQiang Zhang <zhangapache@yahoo.com>
+
+ * io/list_read.c (read_character): Remove unwanted call to free_saved.
+
+2003-10-11 Huang Chun <jiwang@mail.edu.cn>
+
+ * intrinsics/string_intrinsics.c (string_trim): New function.
+ (string_repeat): New function.
+
+2003-10-11 Paul Brook <paul@nowt.org>
+
+ * intrinsics/dprod_r8.f90: New file.
+ * Makefile.am (gfor_specific_src): Add it.
+ (gfor_built_specific_src): Rename from gfor_build_specific_c.
+ Add new intrinsics.
+ (gfor_specific2_src): Rename from gfor_built_specific2_c.
+ Add new intrinsics.
+ * Makefile.in: Regenerate.
+ * generated/_aint_*.f90: New files.
+ * generated/_anint*.f90: New files.
+ * generated/_atan2*.f90: New files.
+ * generated/_mod*.f90: New files.
+
+2003-09-20 Kejia Zhao <kejia_zh@yahoo.com.cn>
+
+ * intrinsics/selected_kind.f90: New file.
+ * Makefile.am: Add it.
+ * Makefile.in: regenerate.
+
+2003-09-19 Lars Segerlund <Lars.Segerlund@comsys.se>
+ Paul Brook <paul@nowt.org>
+
+ * intrinsics/random.c: New file.
+ * Makefile.am (gfor_hemper_src): Add it.
+ (gfor_specific_c): Fix typo.
+
+2003-09-19 Paul Brook <paul@nowt.org>
+
+ * All: rename g95->gfc.
+
+2003-09-18 XiaoQiang Zhang <zhangapache@yahoo.com>
+
+ * io/write.c (output_float): Fix bug of FMT_E, Add comments.
+
+2003-09-09 XiaoQiang Zhang <zhangapache@yahoo.com>
+
+ * io/write.c (write_float): Dectection of positive infinite number,
+ Not a Number(NaN) and negative infinite number.
+ (ioutput_float): Bug fix for FMT_E and FMT_D processing to
+ output a very_very small number ( < 0.1e-100 ).
+
+2003-09-07 XiaoQiang Zhang <zhangapache@yahoo.com>
+
+ * libgfortran.h (xtoa, itoa): Parameter modified.
+ * io/io.h (namelist_info): Declaration to support namelist I/O
+ (st_parameter): Add namelist related component
+ (ionml, empty_internal_buffer, st_set_nml_var_int,
+ st_set_nml_var_float, st_set_nml_var_char, st_set_nml_var_complex,
+ st_set_nml_var_log): Declaration
+ (set_integer, set_integer): Parameter changed
+ * io/format.c (free_nodes): Fix annoying bug of lefting "deallocated"
+ fnodes
+ (parse_format_list): Fix bug about FMT_SLASH
+ * io/list_read.c (push_char): Totally clear old saved_string, zeroize
+ newly allocated saved_string
+ (next_char): Add detection of End_Of_Line support
+ (convert_integer): Now can process 64 bits interger
+ (read_real): Bug fixed
+ (init_at_eol, find_nml_node, match_namelist_name): Add new functions
+ (match_namelist_name): New implemention
+ * io/lock.c (ionml): New global variable
+ (library_end): Free memory in ionml
+ * io/open.c (st_open): Variable initializtion
+ * io/read.c (max_value): 64 bits interger support
+ (convert_precsion_real): New procedure to replace "strtod" with more
+ features
+ (read_f, read_radix): Input bug fix
+ * io/transfer.c: (sf_seen_eor): New static variable
+ (read_sf): Zeroize base buffer; fix bugs: single read statement can
+ not get input in mutli line when read from stdin
+ (formatted_transfer): Fix bug of FMT_O, FMT_B, FMT_Z for INTEGER type
+ request
+ (data_transfer_init): Clear internal buffer for Internel File I/O.
+ Internal File now worked. Detect some error condition for namelist.
+ Some minor bug fix
+ (next_record_w): Internal file and Namelist I/O support.
+ (st_set_nml_var, st_set_nml_var_float, st_set_nml_var_char,
+ st_set_nml_var_complex, st_set_nml_var_log): Implemention.
+ * io/unit.c (implicit_unit): Deletion
+ (get_unit): Now cannot open a unit implicitly.
+ * io/unix.c (mmap_alloc): Fix fatal error in calculating the length of
+ mapped buffer.
+ (mem_alloc_r_at): Internal file I/O support added
+ (empty_internal_buffer): New function
+ * io/write.c (extract_int): Support 64 bits interger processing
+ (output_float): Varibale initialization
+ (write_float): Infinite real number detection.
+ (write_int): 64 bits integer I/O support
+ (write_decimal): New function to output decimal number
+ (otoa, btoa): Better implemention and 64 bits interger support
+ (namelist_write): New function
+ * runtime/error.c (itoa, xtoa): Better implemention and 64 bits
+ interger support
+
+2003-08-15 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+
+ * libgfortran.h (os_error, runtime_error,internal_error, sys_exit,
+ get_mem ): Add attribute.
+ * intrinsics/spread_generic.c (__spread): Fix spelling.
+ * io/inquire.c (inquire_via_filename): Add const.
+ * io/io.h (sys_exit): Add attribute.
+ * io/io.h (move_pos_offset): Add move_pos_offset.
+ * io/io.h (compare_file_filename, inquire_sequential, inquire_direct,
+ inquire_formatted, inquire_unformatted, inquire_read, inquire_write,
+ inquire_readwrite, convert_real, write_a, write_b, write_d, write_e,
+ write_en, write_es, write_f, write_i, write_l, write_o, write_x,
+ write_z): Add const.
+ * io/read.c (convert_real): Add const.
+ * io/transfer.c (type_name): Add const.
+ * io/unix.c (unpack_filename, compare_file_filename,inquire_sequential,
+ inquire_direct, inquire_formatted, inquire_unformatted, inquire_access,
+ inquire_read, inquire_write, inquire_readwrite): Add const.
+ * io/write.c (output_float): Remove unused variable.
+ * io/write.c (write_a, extract_int, extract_real, output_float,
+ write_float, write_int, write_i, write_b, write_o, write_z, write_d,
+ write_e, write_f, write_en, write_es, write_logical, write_integer,
+ write_character, write_real, write_complex): Add const.
+ * runtime/error.c (rtoa): Remove unused variable.
+ * runtime/select.c (select_string): Add const.
+ * runtime/stop.c (stop_string): Add const.
+
+2003-08-10 Paul Brook <paul@nowt.org>
+
+ * Makefile.am (gfor_helper_src): Add intrinsics/abort.c.
+ (FFLAGS): Add -fno-underscoring.
+ * Makefile.in: Regenerate.
+ * intrinsics/abort.c: New file.
+
+2003-08-10 Erik Schnetter <schnetter@uni-tuebingen.de>
+
+ * fmain.c (main): Do not call init and cleanup; call set_args instead.
+ * libgfortran.h (init, cleanup): Remove declarations.
+ (set_args): Add declaration.
+ * runtime/main.c (init, cleanup): Make them static, and give them
+ the constructor and destructor attributes.
+ (set_args): New function.
+
+2003-08-10 Paul Brook <paul@nowt.org>
+
+ * intrinsics/strinf_intrinsics.c (compare_string): Return value based
+ on which string is longest.
+
+2003-08-10 Paul Brook <paul@nowt.org>
+
+ * Makefile.am (EXTRA_DIST): Remove old files.
+ * Makefile.in: Regenerate.
+
+2003-07-26 Paul Brook <paul@nowt.org>
+
+ Rename library to libgfortran.
+ * libgfortran.h: Change prefix to _libgfortran_.
+
+2003-07-24 Paul Brook <paul@nowt.org>
+
+ * configure.in: Don't pull in system libtool. Use toplevel
+ auxiliary files.
+
+2003-07-22 Paul Brook <paul@nowt.org>
+
+ Regenerate all configury files.
+
+2003-07-09 Chun Huang <compiler@sohu.com>
+
+ * intrinsics/string_intrinsic.c (string_scan): New function.
+ (string_verify): New function.
+
+2003-06-25 Paul Brook <paul@nowt.org>
+
+ * io/unix.c (mem_alloc_r_at, mem_alloc_w_at): Advance logical_offset.
+ (mem_seek): Don't bother setting physical_offset.
+
+2003-06-20 Paul Brook <paul@nowt.org>
+
+ * libgfor.h (stop_numeric): Declare.
+ * runtime/pause.c: New file.
+ * Makefile.am: Add it.
+
+2003-06-08 Paul Brook <paul@nowt.org>
+
+ * m4/cexp.m4 (cabs): Use correct typed version.
+ (csqrt): New function.
+
+2003-06-07 Canqun Yang <canqun@yahoo.com.cn>
+
+ Spotted by Benjamin and Tobias:
+ * io/list_read.c: Add Separator '\t'.
+ (parse_real, read_real): Accept real values starting with an optional
+ sign follows a decimal point.
+
+2003-06-06 Steven Bosscher <steven@gcc.gnu.org>
+
+ * Makefile.am: Don't put cmath objects in subdir.
+ * configure.in: Rename MATHOBJ to MATH_OBJ.
+
+2003-06-02 Kejia Zhao <Kejia_zh@yahoo.com.cn>
+
+ * intrinsics/associated.c: New file.
+ * Makefile.am: Add it. Regenerate Makefile.in.
+ * libgfor.h: Define g95_array_void, G95_DESCRIPTOR_DATA, and
+ G95_DESCRIPTOR_DTYPE.
+
+2003-06-01 Canqun Yang <canqun@yahoo.com.cn>
+
+ * io/write.c (calcuate_exp): Rewrite it to avoid overflow.
+ (calculate_G_format): Rewrite it to eliminate an infinte loop and set
+ the scale_factor to 0 for F editing.
+
+2003-05-11 Tobias Schlüter <innenminister@gmx.de>
+
+ * libgfor.h: Only include stdint.h if it exists.
+
+2003-05-07 Paul Brook <paul@nowt.org>
+
+ * libgfor.h: Use stdint.h types.
+ * intrinsics/ishift.c: Ditto.
+ * runtime/memory.c (malloc_t): Reorder fields for better alignment.
+
+2003-05-05 Steven Bosscher <steven@gcc.gnu.org>
+
+ * libgfor.h (offsetof): Define if nobody else does.
+ * runtime/memory.c (HEADER_SIZE): Use it.
+
+2003-05-01 Tobias Schlüter <innenminister@gmx.de>
+
+ * configure.in: Require autoconf 2.54.
+
+2003-04-28 Tobias Schlüter <innenminister@gmx.de>
+ Paul Brook <paul@nowt.org>
+
+ * intrinsics/reshape_generic.c: Copy the whole element, not just the
+ first byte.
+ * m4/transpose.m4: New file.
+ * Makefile.am: Add them.
+ Regenerate generated files.
+
+2003-04-18 Steven Bosscher <steven@gcc.gnu.org>
+
+ * io/format.c (parse_format_list): Allow 'X' without integer
+ prefix. This is an extension. Interpretation is '1X'.
+
+2003-04-18 Tobias Schlüter <Tobias.Schlueter@physik.uni-muenchen.de>
+
+ * io/format.c (parse_format_list): Allow '0P'.
+
+2003-04-18 Steven Bosscher <steven@gcc.gnu.org>
+
+ * Makefile.in: Re-regenerate for automake 1.7.3.
+
+2003-04-18 Canqun Yang <canqun@yahoo.com.cn>
+
+ Port implementation for CHARACTER SELECT from Andy's tree.
+ * runtime/select.c: New file
+ * Makefile.am: Add it.
+ * Makefile.in: Regenerate.
+
+2003-04-17 Xiaoqiang Zhang <zhangapache@yahoo.com>
+
+ * io/transfer.c (formatted_transfer): Modified
+ * io/unix.c (move_pos_offset): New Function.
+ * io/format.c (parse_format_list): Modified.
+
+2003-04-15 Xiaoqiang Zhang <zhangapache@yahoo.com>
+
+ * io/write.c (write_float,write_real): New implemention of
+ FMT_G and default float editing.
+ (calculate_exp,calculate_G_format,output_float): New Function.
+ (write_float,write_real,write_logical): Modified
+ * libgfor.h (default_rtoa): Remove Declaration.
+ * runtime/error.c (default_rtoa): Remove Function.
+
+2003-04-15 Steven Bosscher <steven@gcc.gnu.org>
+
+ Spotted by Yang:
+ * io/write.c (extract_real): Add missing break statement.
+
+2003-04-13 Steven Bosscher <steven@gcc.gnu.org>
+
+ * cpu_time.c: Make sure we have a definition of HZ. Don't
+ rely on CLOCKS_PER_SEC, it is always 1000000, on any system.
+
+2003-04-13 Steven Bosscher <steven@gcc.gnu.org>
+ Paul Brook <paul@nowt.org>
+
+ * configure.in: Check for process time headers and GETTIMEOFDAY.
+ * makefile.am: Add intrinsics/cpu_time.c.
+ * acinclude.m4: New file.
+ * intrinsics/cpu_time.c: New file.
+ * m4/dotprodl.m4: Fix typo.
+ Regenerate generated files.
+
+2003-04-11 Xiaoqiang Zhang <zhangapache@yahoo.com>
+
+ * io/write.c (extract_real): Ouput floating point value.
+ (write_float): New Function.
+ (write_e, write_f, write_en, write_es): Modified
+ * io/transfer.c (formatted_transfer): Modified.
+ * libgfor.h (default_rtoa): Declaration.
+ (rtoa): Declaration.
+ * runtime/error.c (default_rtoa): New Function.
+ (rtoa): New Function.
+
+2003-04-05 Paul Brook <paul@nowt.org>
+
+ * intrinsics/spread_generic.c: New file.
+ * Makefile.am: Add it. Regenerate Makefile.in.
+
+2003-03-29 Paul Brook <paul@nowt.org>
+
+ * intrinsics/pack_generic.c: New file.
+ * intrinsics/unpack_generic.c: New file.
+ * Makefile.am: Add them. Regenerate Makefile.in.
+
+2003-03-25 Paul Brook <paul@nowt.org>
+
+ * intrinsics/eoshift0.c: New file.
+ * intrinsics/eoshift2.c: New file.
+ * m4/eoshift1.m4: New file.
+ * m4/eoshift3.m4: New file.
+ * Makefile.am: Add them.
+ * in_unpack_generic.c: Initialize src.
+ Regenerate generated files.
+
+2003-03-14 Paul Brook <paul@nowt.org>
+
+ * m4/shape.m4: Work properly with array temporaries.
+ * m4/in_pack.m4: Skip redundant checks for array temporaries.
+ * runtime/in_pack_generic.c: Ditto.
+
+2003-03-12 Paul Brook <paul@nowt.org>
+
+ * m4/shape.m4: Work properly with noncontiguous arrays.
+
+2003-03-08 Paul Brook <paul@nowt.org>
+
+ * m4/in_pack.m4: Correctly handle zero sized and assumed size arrays.
+ * runtime/in_pack_generic.c: Ditto.
+
+2003-02-08 Paul Brook <paul@nowt.org>
+
+ * intrinsics/reshape_generic.c: Use runtime_error to report errors.
+ * io/close.c (st_close): Return void.
+ * io/open.c (st_open): Return void.
+ * libgfor.h (g95_array_char): Declare.
+ (internal_malloc_size): Ditto.
+ (internal_pack*, internal_unpack*): Ditto.
+ * m4/in_pack.m4: Allocate storage if neccessary. Fix logic for packed
+ arrays.
+ * m4/in_unpack.m4: Include file fixes.
+ * m4/reshape.m4: Increment the correct source pointer.
+ * Makefile.am (maxloc): Fix typo.
+ * runtime/in_pack_generic.c: Call optimized functions. Allocate
+ storage if neccessary. Fix logic for packed arrays.
+ * runtime/in_unpack_generic.c: Call optimized functions.
+ * runtime/main.c: Use runtime_error to report errors.
+ * memory.c (internal_malloc_size): Make non-static.
+
+2003-02-02 Arnaud Desitter <arnaud.desitter@geography.oxford.ac.uk>
+
+ * reshape_packed.c, lock.c: Add #include <string.h>.
+ * libgfor.h, format.c, inquire.c, io.h, transfer.c, unix.c,
+ environ.c, error.c, memory.c, string.c: Add const.
+ * error.c (show_locus): Add void.
+
+2003-02-21 Paul Brook <paul@nowt.org>
+
+ * m4/in_pack.m4: Avoid returning const * parameter.
+ * Makefile.am: Only regenerate files in maintainer mode.
+
+2003-02-20 Paul Brook <paul@nowt.org>
+
+ Add array repacking support functions.
+ * m4/in_pack.m4, m4/in_unpack.m4: New files.
+ * runtime/in_pack_generic.c, runtime/in_unpack_generic.c: New files.
+ * Makefile.am: Build them. Regenerate configury files.
+ * generated/: New directory for generated files (need to move
+ everything else there).
+
+2003-02-07 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
+
+ * m4/cexp.m4: Fix typo.
+
+2003-01-26 Paul Brook <paul@nowt.org>
+
+ * intrinsics/: Add missing generated files.
+
+2003-01-26 Paul Brook <paul@nowt.org>
+
+ * Makefile.am: Put -I before the filename.
+
+2003-01-24 Paul Brook <paul@nowt.org>
+
+ * configure.in: Add AM_MAINTAINER_MODE.
+
+2003-01-23 Paul Brook <paul@nowt.org>
+
+ * configure.in, Makefile.am: Modify to work with unmodified autoconf
+ and auotmake.
+ Also regenerate other configury files.
+
+2003-01-21 Paul Brook <paul@nowt.org>
+
+ * io/read.c: Don't use stdint.h, it doesn't exist on cygwin.
+
+2003-01-20 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * io/read.c (read_f): Don't use alloca, but safe get_mem instead.
+ Don't include "alloca.h".
+
+2003-01-20 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * intrinsics/string.c: Rename to intrinsics/string_intrinsics.c.
+ * Makefile.am: Adjust file name.
+ * Makefile.in: Regenerate.
+ * gfortypes.h: Kill, include everything in...
+ * libgfor.h: ...here. Include config.h
+ * fmain.c, intrinsics/ishftc.c, intrinsic/reshape_generic.c,
+ intrinsics/reshape_i4.c, intrinsics/reshape_i8.c,
+ intrinsics/reshape_packed.c, intrinsics/size.c,
+ m4/reshape.m4, runtime/main.c, runtime/memory.c: Use macro
+ for prefix for all functions instead of hardcoded.
+
+2003-01-19 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * io/lock.c (library_end): Propagate library return
+ code.
+
+2003-01-19 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ Port fixes from Andy's tree:
+ * io/read.c (read_decimal): Reverse sense of overflow
+ comparison during integer reads.
+ * io/format.c (revert): Fix comment.
+ (next_format): Fix format revision.
+ * io/unix.c: Fix and simplify mmap version of stream
+ functions.
+
+2003-01-11 Paul Brook <paul@nowt.org>
+
+ * configure, Makefile.in: Regenerate.
+
+2003-01-11 Paul Brook <paul@nowt.org>
+
+ * runtime/stop.c: Rewrite.
+
+2003-01-08 Paul Brook <paul@nowt.org>
+
+ * configure, Makefile.in: Regenerate.
+
+2003-01-05 Paul Brook <paul@nowt.org>
+
+ * (*.m4) Move to m4/.
+ * intrinsics/string.c (_gfor_string_index): New Function.
+
+2002-12-29 Paul Brook <paul@nowt.org>
+
+ * intrinsics/reshape.*: New files.
+ * gcc_config.patch: Update to new GCC configure system.
+
+2002-10-10 Paul Brook <paul@nowt.org>
+
+ * intrinsics/size.c: New file.
+ * intrinsics/shape.m4: New file.
+ * Makefile.am: Add above files.
+
+2002-10-02 Paul Brook <paul@nowt.org>
+
+ * fmain.c (main): Move here.
+ * libgfor.c: From here.
+ * libgfor.h (gfor_init, gfor_runtime_cleanup): Declare.
+ * Makefile.am: Build libgforbegin.
+ * gcc_config.patch: Remove stray -march=athlon.
+ * dotprodl.m4: Fix use of L8_TO_L4 macro.
+ * ifunction.m4: Move variable declarations to allow compilation with
+ gcc < 3.0
+ * specific.m4, specific4.m4: Fix typo typecode->type_code.
+ * README: Document use of patch -p1.
+
+2002-09-12 Paul Brook <paul@nowt.org>
+
+ * math/*: Add complex math library functions.
+ * intrinsics/specific(2).m4: Generate Specific intrinsic functions.
+ * Makefile.am: Add details for above.
+ * configure.in: Use AC_PROG_F95. Test for the presence of csin.
+
+2002-09-09 Paul Brook <paul@nowt.org>
+
+ * libgfor.c (determine_endianness): Use an array rather than a struct.
+ * intrinsics/dotprod*, matmul*: Implement DOT_PRODUCT and MATMUL.
+
+2002-09-09 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * libgfor.c: Add fatal signal handler.
+ Romove superfluous abort() calls.
+
+2002-09-07 Paul Brook <paul@nowt.org>
+
+ * Makefile.am, intrinsics: Major rewrite.
+
+2002-09-02 Paul Brook <paul@nowt.org>
+
+ * Makefile.am: Added -I$(srcdir) to m4 rule.
+
+2002-08-30 Paul Brook <paul@nowt.org>
+
+ * io/*: Integrated libgforio.
+ * Makefile.am, configure.in: Make compatable with GCC. Build code for
+ intrinsics in the intrisics directory.
+ * intrinsics/intrinsics.m4: Move here. Strip directories from the
+ filename. Add 'and' and 'all' intrinsics.
+
+2002-08-17 Paul Brook <paul@nowt.org>
+
+ * ALL: First release as more than just a single file
diff --git a/libgfortran/INSTALL b/libgfortran/INSTALL
new file mode 100644
index 00000000000..33391e47413
--- /dev/null
+++ b/libgfortran/INSTALL
@@ -0,0 +1 @@
+This should be installed as part of GCC. If not, you're on your own.
diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am
new file mode 100644
index 00000000000..5213ca9883c
--- /dev/null
+++ b/libgfortran/Makefile.am
@@ -0,0 +1,464 @@
+## Process this file with automake to produce Makefile.in
+
+## We like to use C99 routines when available. This makes sure that
+## __STDC_VERSION__ is set such that libc includes make them available.
+AM_CFLAGS = -std=gnu99
+
+lib_LTLIBRARIES = libgfortran.la libgfortranbegin.la
+
+## This should really go in the compiler lib dir, not the system lib dir.
+libgfortranbegin_la_SOURCES = fmain.c
+libgfortranbegin_la_LDFLAGS = -static
+
+INCLUDES = -I$(srcdir)/io
+
+libgfortranincludedir = $(includedir)/gforio
+
+gfor_io_src= \
+io/backspace.c \
+io/close.c \
+io/endfile.c \
+io/format.c \
+io/inquire.c \
+io/list_read.c \
+io/lock.c \
+io/open.c \
+io/read.c \
+io/rewind.c \
+io/transfer.c \
+io/unit.c \
+io/unix.c \
+io/write.c
+
+gfor_io_headers= \
+io/io.h
+
+gfor_helper_src= \
+intrinsics/associated.c \
+intrinsics/abort.c \
+intrinsics/cpu_time.c \
+intrinsics/cshift0.c \
+intrinsics/eoshift0.c \
+intrinsics/eoshift2.c \
+intrinsics/ishftc.c \
+intrinsics/pack_generic.c \
+intrinsics/size.c \
+intrinsics/spread_generic.c \
+intrinsics/string_intrinsics.c \
+intrinsics/random.c \
+intrinsics/reshape_generic.c \
+intrinsics/reshape_packed.c \
+intrinsics/selected_kind.f90 \
+intrinsics/transpose_generic.c \
+intrinsics/unpack_generic.c \
+runtime/in_pack_generic.c \
+runtime/in_unpack_generic.c
+
+gfor_src= \
+runtime/environ.c \
+runtime/error.c \
+runtime/main.c \
+runtime/memory.c \
+runtime/pause.c \
+runtime/stop.c \
+runtime/string.c \
+runtime/select.c \
+gfortypes.h \
+libgfortran.h
+
+i_all_c= \
+generated/all_l4.c \
+generated/all_l8.c
+
+i_any_c= \
+generated/any_l4.c \
+generated/any_l8.c
+
+i_count_c= \
+generated/count_4_l4.c \
+generated/count_8_l4.c \
+generated/count_4_l8.c \
+generated/count_8_l8.c
+
+i_maxloc0_c= \
+generated/maxloc0_4_i4.c \
+generated/maxloc0_8_i4.c \
+generated/maxloc0_4_i8.c \
+generated/maxloc0_8_i8.c \
+generated/maxloc0_4_r4.c \
+generated/maxloc0_8_r4.c \
+generated/maxloc0_4_r8.c \
+generated/maxloc0_8_r8.c
+
+i_maxloc1_c= \
+generated/maxloc1_4_i4.c \
+generated/maxloc1_8_i4.c \
+generated/maxloc1_4_i8.c \
+generated/maxloc1_8_i8.c \
+generated/maxloc1_4_r4.c \
+generated/maxloc1_8_r4.c \
+generated/maxloc1_4_r8.c \
+generated/maxloc1_8_r8.c
+
+i_maxval_c= \
+generated/maxval_i4.c \
+generated/maxval_i8.c \
+generated/maxval_r4.c \
+generated/maxval_r8.c
+
+i_minloc0_c= \
+generated/minloc0_4_i4.c \
+generated/minloc0_8_i4.c \
+generated/minloc0_4_i8.c \
+generated/minloc0_8_i8.c \
+generated/minloc0_4_r4.c \
+generated/minloc0_8_r4.c \
+generated/minloc0_4_r8.c \
+generated/minloc0_8_r8.c
+
+i_minloc1_c= \
+generated/minloc1_4_i4.c \
+generated/minloc1_8_i4.c \
+generated/minloc1_4_i8.c \
+generated/minloc1_8_i8.c \
+generated/minloc1_4_r4.c \
+generated/minloc1_8_r4.c \
+generated/minloc1_4_r8.c \
+generated/minloc1_8_r8.c
+
+i_minval_c= \
+generated/minval_i4.c \
+generated/minval_i8.c \
+generated/minval_r4.c \
+generated/minval_r8.c
+
+i_sum_c= \
+generated/sum_i4.c \
+generated/sum_i8.c \
+generated/sum_r4.c \
+generated/sum_r8.c \
+generated/sum_c4.c \
+generated/sum_c8.c
+
+i_product_c= \
+generated/product_i4.c \
+generated/product_i8.c \
+generated/product_r4.c \
+generated/product_r8.c \
+generated/product_c4.c \
+generated/product_c8.c
+
+i_dotprod_c= \
+generated/dotprod_i4.c \
+generated/dotprod_i8.c \
+generated/dotprod_r4.c \
+generated/dotprod_r8.c
+
+i_dotprodl_c= \
+generated/dotprod_l4.c \
+generated/dotprod_l8.c
+
+i_dotprodc_c= \
+generated/dotprod_c4.c \
+generated/dotprod_c8.c
+
+i_matmul_c= \
+generated/matmul_i4.c \
+generated/matmul_i8.c \
+generated/matmul_r4.c \
+generated/matmul_r8.c \
+generated/matmul_c4.c \
+generated/matmul_c8.c
+
+i_matmull_c= \
+generated/matmul_l4.c \
+generated/matmul_l8.c
+
+i_transpose_c= \
+generated/transpose_i4.c \
+generated/transpose_i8.c
+
+i_shape_c= \
+generated/shape_i4.c \
+generated/shape_i8.c
+
+i_reshape_c= \
+generated/reshape_i4.c \
+generated/reshape_i8.c
+
+i_eoshift1_c= \
+generated/eoshift1_4.c \
+generated/eoshift1_8.c
+
+i_eoshift3_c= \
+generated/eoshift3_4.c \
+generated/eoshift3_8.c
+
+i_cshift1_c= \
+generated/cshift1_4.c \
+generated/cshift1_8.c
+
+in_pack_c = \
+generated/in_pack_i4.c \
+generated/in_pack_i8.c
+
+in_unpack_c = \
+generated/in_unpack_i4.c \
+generated/in_unpack_i8.c
+
+i_exponent_c = \
+generated/exponent_r4.c \
+generated/exponent_r8.c
+
+i_fraction_c = \
+generated/fraction_r4.c \
+generated/fraction_r8.c
+
+i_nearest_c = \
+generated/nearest_r4.c \
+generated/nearest_r8.c
+
+i_set_exponent_c = \
+generated/set_exponent_r4.c \
+generated/set_exponent_r8.c
+
+m4_files= m4/iparm.m4 m4/ifunction.m4 m4/iforeach.m4 m4/types.m4 m4/all.m4 \
+ m4/any.m4 m4/count.m4 m4/maxloc0.m4 m4/maxloc1.m4 m4/maxval.m4 \
+ m4/minloc0.m4 m4/minloc1.m4 m4/minval.m4 m4/product.m4 m4/sum.m4 \
+ m4/dotprod.m4 m4/dotprodl.m4 m4/dotprodc.m4 m4/matmul.m4 m4/matmull.m4 \
+ m4/ctrig.m4 m4/cexp.m4 m4/chyp.m4 m4/mtype.m4 \
+ m4/specific.m4 m4/specific2.m4 m4/head.m4 m4/shape.m4 m4/reshape.m4 \
+ m4/transpose.m4 m4/eoshift1.m4 m4/eoshift3.m4 m4/exponent.m4 \
+ m4/fraction.m4 m4/nearest.m4 m4/set_exponent.m4
+
+gfor_built_src= $(i_all_c) $(i_any_c) $(i_count_c) $(i_maxloc0_c) \
+ $(i_maxloc1_c) $(i_maxval_c) $(i_minloc0_c) $(i_minloc1_c) $(i_minval_c) \
+ $(i_product_c) $(i_sum_c) $(i_dotprod_c) $(i_dotprodl_c) $(i_dotprodc_c) \
+ $(i_matmul_c) $(i_matmull_c) $(i_transpose_c) $(i_shape_c) $(i_eoshift1_c) \
+ $(i_eoshift3_c) $(i_cshift1_c) $(i_reshape_c) $(in_pack_c) $(in_unpack_c) \
+ $(i_exponent_c) $(i_fraction_c) $(i_nearest_c) $(i_set_exponent_c)
+
+# We only use these if libm doesn't contain complex math functions.
+
+gfor_math_trig_c= \
+generated/trig_c4.c \
+generated/trig_c8.c
+gfor_math_exp_c= \
+generated/exp_c4.c \
+generated/exp_c8.c
+gfor_math_hyp_c= \
+generated/hyp_c4.c \
+generated/hyp_c8.c
+
+gfor_math_trig_obj= \
+trig_c4.lo \
+trig_c8.lo
+gfor_math_exp_obj= \
+exp_c4.lo \
+exp_c8.lo
+gfor_math_hyp_obj= \
+hyp_c4.lo \
+hyp_c8.lo
+
+# Machine generated specifics
+gfor_built_specific_src= \
+generated/_abs_c4.f90 \
+generated/_abs_c8.f90 \
+generated/_abs_i4.f90 \
+generated/_abs_i8.f90 \
+generated/_abs_r4.f90 \
+generated/_abs_r8.f90 \
+generated/_exp_r4.f90 \
+generated/_exp_r8.f90 \
+generated/_exp_c4.f90 \
+generated/_exp_c8.f90 \
+generated/_log_r4.f90 \
+generated/_log_r8.f90 \
+generated/_log_c4.f90 \
+generated/_log_c8.f90 \
+generated/_log10_r4.f90 \
+generated/_log10_r8.f90 \
+generated/_sqrt_r4.f90 \
+generated/_sqrt_r8.f90 \
+generated/_sqrt_c4.f90 \
+generated/_sqrt_c8.f90 \
+generated/_asin_r4.f90 \
+generated/_asin_r8.f90 \
+generated/_acos_r4.f90 \
+generated/_acos_r8.f90 \
+generated/_atan_r4.f90 \
+generated/_atan_r8.f90 \
+generated/_sin_r4.f90 \
+generated/_sin_r8.f90 \
+generated/_sin_c4.f90 \
+generated/_sin_c8.f90 \
+generated/_cos_r4.f90 \
+generated/_cos_r8.f90 \
+generated/_cos_c4.f90 \
+generated/_cos_c8.f90 \
+generated/_tan_r4.f90 \
+generated/_tan_r8.f90 \
+generated/_sinh_r4.f90 \
+generated/_sinh_r8.f90 \
+generated/_cosh_r4.f90 \
+generated/_cosh_r8.f90 \
+generated/_tanh_r4.f90 \
+generated/_tanh_r8.f90 \
+generated/_conjg_c4.f90 \
+generated/_conjg_c8.f90 \
+generated/_aint_r4.f90 \
+generated/_aint_r8.f90 \
+generated/_anint_r4.f90 \
+generated/_anint_r8.f90
+
+gfor_built_specific2_src= \
+generated/_sign_i4.f90 \
+generated/_sign_i8.f90 \
+generated/_sign_r4.f90 \
+generated/_sign_r8.f90 \
+generated/_dim_i4.f90 \
+generated/_dim_i8.f90 \
+generated/_dim_r4.f90 \
+generated/_dim_r8.f90 \
+generated/_atan2_r4.f90 \
+generated/_atan2_r8.f90 \
+generated/_mod_i4.f90 \
+generated/_mod_i8.f90 \
+generated/_mod_r4.f90 \
+generated/_mod_r8.f90
+#specific intrinsics requiring manal code
+#gfor_specific_c= \
+intrinsics/_aimag.c \
+intrinsics/_cabs.c \
+foo
+
+gfor_specific_src= \
+$(gfor_built_specific_src) \
+$(gfor_built_specific2_src) \
+intrinsics/dprod_r8.f90
+
+gfor_cmath_src= $(gfor_math_trig_c) $(gfor_math_exp_c) $(gfor_math_hyp_c)
+gfor_cmath_obj= $(gfor_math_trig_obj) $(gfor_math_exp_obj) \
+ $(gfor_math_hyp_obj)
+
+BUILT_SOURCES=$(gfor_built_src) $(gfor_cmath_src) $(gfor_built_specific_src) \
+ $(gfor_built_specific2_src)
+libgfortran_la_SOURCES = $(gfor_src) $(gfor_built_src) $(gfor_io_src) \
+ $(gfor_helper_src) $(gfor_io_headers) $(gfor_specific_src)
+
+EXTRA_libgfortran_la_SOURCES = $(gfor_cmath_src)
+
+libgfortran_la_LIBADD = @MATH_OBJ@
+libgfortran_la_DEPENDENCIES = @MATH_OBJ@
+
+I_M4_DEPS=m4/iparm.m4 m4/types.m4
+I_M4_DEPS0=$(I_M4_DEPS) m4/iforeach.m4
+I_M4_DEPS1=$(I_M4_DEPS) m4/ifunction.m4
+
+## A 'normal' build shouldn't need to regenerate these
+## so we only include them in maintainer mode
+
+if MAINTAINER_MODE
+$(i_all_c): m4/all.m4 $(I_M4_DEPS1)
+ m4 -Dfile=$@ -I$(srcdir)/m4 all.m4 > $@
+
+$(i_any_c): m4/any.m4 $(I_M4_DEPS1)
+ m4 -Dfile=$@ -I$(srcdir)/m4 any.m4> $@
+
+$(i_count_c): m4/count.m4 $(I_M4_DEPS1)
+ m4 -Dfile=$@ -I$(srcdir)/m4 count.m4> $@
+
+$(i_maxloc0_c): m4/maxloc0.m4 $(I_M4_DEPS0)
+ m4 -Dfile=$@ -I$(srcdir)/m4 maxloc0.m4 > $@
+
+$(i_maxloc1_c): m4/maxloc1.m4 $(I_M4_DEPS1)
+ m4 -Dfile=$@ -I$(srcdir)/m4 maxloc1.m4 > $@
+
+$(i_maxval_c): m4/maxval.m4 $(I_M4_DEPS1)
+ m4 -Dfile=$@ -I$(srcdir)/m4 maxval.m4 > $@
+
+$(i_minloc0_c): m4/minloc0.m4 $(I_M4_DEPS0)
+ m4 -Dfile=$@ -I$(srcdir)/m4 minloc0.m4 > $@
+
+$(i_minloc1_c): m4/minloc1.m4 $(I_M4_DEPS1)
+ m4 -Dfile=$@ -I$(srcdir)/m4 minloc1.m4 > $@
+
+$(i_minval_c): m4/minval.m4 $(I_M4_DEPS1)
+ m4 -Dfile=$@ -I$(srcdir)/m4 minval.m4 > $@
+
+$(i_product_c): m4/product.m4 $(I_M4_DEPS1)
+ m4 -Dfile=$@ -I$(srcdir)/m4 product.m4 > $@
+
+$(i_sum_c): m4/sum.m4 $(I_M4_DEPS1)
+ m4 -Dfile=$@ -I$(srcdir)/m4 sum.m4 > $@
+
+$(i_dotprod_c): m4/dotprod.m4 $(I_M4_DEPS)
+ m4 -Dfile=$@ -I$(srcdir)/m4 dotprod.m4 > $@
+
+$(i_dotprodl_c): m4/dotprodl.m4 $(I_M4_DEPS)
+ m4 -Dfile=$@ -I$(srcdir)/m4 dotprodl.m4 > $@
+
+$(i_dotprodc_c): m4/dotprodc.m4 $(I_M4_DEPS)
+ m4 -Dfile=$@ -I$(srcdir)/m4 dotprodc.m4 > $@
+
+$(i_matmul_c): m4/matmul.m4 $(I_M4_DEPS)
+ m4 -Dfile=$@ -I$(srcdir)/m4 matmul.m4 > $@
+
+$(i_matmull_c): m4/matmull.m4 $(I_M4_DEPS)
+ m4 -Dfile=$@ -I$(srcdir)/m4 matmull.m4 > $@
+
+$(i_transpose_c): m4/transpose.m4 $(I_M4_DEPS)
+ m4 -Dfile=$@ -I$(srcdir)/m4 transpose.m4 > $@
+
+$(i_shape_c): m4/shape.m4 $(I_M4_DEPS)
+ m4 -Dfile=$@ -I$(srcdir)/m4 shape.m4 > $@
+
+$(i_reshape_c): m4/reshape.m4 $(I_M4_DEPS)
+ m4 -Dfile=$@ -I$(srcdir)/m4 reshape.m4 > $@
+
+$(i_eoshift1_c): m4/eoshift1.m4 $(I_M4_DEPS)
+ m4 -Dfile=$@ -I$(srcdir)/m4 eoshift1.m4 > $@
+
+$(i_eoshift3_c): m4/eoshift3.m4 $(I_M4_DEPS)
+ m4 -Dfile=$@ -I$(srcdir)/m4 eoshift3.m4 > $@
+
+$(i_cshift1_c): m4/cshift1.m4 $(I_M4_DEPS)
+ m4 -Dfile=$@ -I$(srcdir)/m4 cshift1.m4 > $@
+
+$(in_pack_c): m4/in_pack.m4 $(I_M4_DEPS)
+ m4 -Dfile=$@ -I$(srcdir)/m4 in_pack.m4 > $@
+
+$(in_unpack_c): m4/in_unpack.m4 $(I_M4_DEPS)
+ m4 -Dfile=$@ -I$(srcdir)/m4 in_unpack.m4 > $@
+
+$(i_exponent_c): m4/exponent.m4 m4/mtype.m4
+ m4 -Dfile=$@ -I$(srcdir)/m4 exponent.m4 > $@
+
+$(i_fraction_c): m4/fraction.m4 m4/mtype.m4
+ m4 -Dfile=$@ -I$(srcdir)/m4 fraction.m4 > $@
+
+$(i_nearest_c): m4/nearest.m4 m4/mtype.m4
+ m4 -Dfile=$@ -I$(srcdir)/m4 nearest.m4 > $@
+
+$(i_set_exponent_c): m4/set_exponent.m4 m4/mtype.m4
+ m4 -Dfile=$@ -I$(srcdir)/m4 set_exponent.m4 > $@
+
+$(gfor_math_trig_c): m4/ctrig.m4 m4/mtype.m4
+ m4 -Dfile=$@ -I$(srcdir)/m4 ctrig.m4 > $@
+
+$(gfor_math_exp_c): m4/cexp.m4 m4/mtype.m4
+ m4 -Dfile=$@ -I$(srcdir)/m4 cexp.m4 > $@
+
+$(gfor_math_hyp_c): m4/chyp.m4 m4/mtype.m4
+ m4 -Dfile=$@ -I$(srcdir)/m4 chyp.m4 > $@
+
+$(gfor_built_specific_src): m4/specific.m4 m4/head.m4
+ m4 -Dfile=$@ -I$(srcdir)/m4 specific.m4 > $@
+
+$(gfor_built_specific2_src): m4/specific2.m4 m4/head.m4
+ m4 -Dfile=$@ -I$(srcdir)/m4 specific2.m4 > $@
+## end of maintainer mode only rules
+endif
+
+EXTRA_DIST = $(m4_files)
+
diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in
new file mode 100644
index 00000000000..9803454c4d8
--- /dev/null
+++ b/libgfortran/Makefile.in
@@ -0,0 +1,5479 @@
+# Makefile.in generated by automake 1.8.2 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+SOURCES = $(libgfortran_la_SOURCES) $(EXTRA_libgfortran_la_SOURCES) $(libgfortranbegin_la_SOURCES)
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = .
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+DIST_COMMON = README $(am__configure_deps) $(srcdir)/../config.guess \
+ $(srcdir)/../config.sub $(srcdir)/../depcomp \
+ $(srcdir)/../install-sh $(srcdir)/../ltmain.sh \
+ $(srcdir)/../missing $(srcdir)/../mkinstalldirs \
+ $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(srcdir)/config.h.in $(top_srcdir)/configure AUTHORS COPYING \
+ ChangeLog INSTALL NEWS
+subdir = .
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/../libtool.m4 $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno configure.status.lineno
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+am__installdirs = $(DESTDIR)$(libdir)
+libLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(lib_LTLIBRARIES)
+am__objects_1 = environ.lo error.lo main.lo memory.lo pause.lo stop.lo \
+ string.lo select.lo
+am__objects_2 = all_l4.lo all_l8.lo
+am__objects_3 = any_l4.lo any_l8.lo
+am__objects_4 = count_4_l4.lo count_8_l4.lo count_4_l8.lo \
+ count_8_l8.lo
+am__objects_5 = maxloc0_4_i4.lo maxloc0_8_i4.lo maxloc0_4_i8.lo \
+ maxloc0_8_i8.lo maxloc0_4_r4.lo maxloc0_8_r4.lo \
+ maxloc0_4_r8.lo maxloc0_8_r8.lo
+am__objects_6 = maxloc1_4_i4.lo maxloc1_8_i4.lo maxloc1_4_i8.lo \
+ maxloc1_8_i8.lo maxloc1_4_r4.lo maxloc1_8_r4.lo \
+ maxloc1_4_r8.lo maxloc1_8_r8.lo
+am__objects_7 = maxval_i4.lo maxval_i8.lo maxval_r4.lo maxval_r8.lo
+am__objects_8 = minloc0_4_i4.lo minloc0_8_i4.lo minloc0_4_i8.lo \
+ minloc0_8_i8.lo minloc0_4_r4.lo minloc0_8_r4.lo \
+ minloc0_4_r8.lo minloc0_8_r8.lo
+am__objects_9 = minloc1_4_i4.lo minloc1_8_i4.lo minloc1_4_i8.lo \
+ minloc1_8_i8.lo minloc1_4_r4.lo minloc1_8_r4.lo \
+ minloc1_4_r8.lo minloc1_8_r8.lo
+am__objects_10 = minval_i4.lo minval_i8.lo minval_r4.lo minval_r8.lo
+am__objects_11 = product_i4.lo product_i8.lo product_r4.lo \
+ product_r8.lo product_c4.lo product_c8.lo
+am__objects_12 = sum_i4.lo sum_i8.lo sum_r4.lo sum_r8.lo sum_c4.lo \
+ sum_c8.lo
+am__objects_13 = dotprod_i4.lo dotprod_i8.lo dotprod_r4.lo \
+ dotprod_r8.lo
+am__objects_14 = dotprod_l4.lo dotprod_l8.lo
+am__objects_15 = dotprod_c4.lo dotprod_c8.lo
+am__objects_16 = matmul_i4.lo matmul_i8.lo matmul_r4.lo matmul_r8.lo \
+ matmul_c4.lo matmul_c8.lo
+am__objects_17 = matmul_l4.lo matmul_l8.lo
+am__objects_18 = transpose_i4.lo transpose_i8.lo
+am__objects_19 = shape_i4.lo shape_i8.lo
+am__objects_20 = eoshift1_4.lo eoshift1_8.lo
+am__objects_21 = eoshift3_4.lo eoshift3_8.lo
+am__objects_22 = cshift1_4.lo cshift1_8.lo
+am__objects_23 = reshape_i4.lo reshape_i8.lo
+am__objects_24 = in_pack_i4.lo in_pack_i8.lo
+am__objects_25 = in_unpack_i4.lo in_unpack_i8.lo
+am__objects_26 = exponent_r4.lo exponent_r8.lo
+am__objects_27 = fraction_r4.lo fraction_r8.lo
+am__objects_28 = nearest_r4.lo nearest_r8.lo
+am__objects_29 = set_exponent_r4.lo set_exponent_r8.lo
+am__objects_30 = $(am__objects_2) $(am__objects_3) $(am__objects_4) \
+ $(am__objects_5) $(am__objects_6) $(am__objects_7) \
+ $(am__objects_8) $(am__objects_9) $(am__objects_10) \
+ $(am__objects_11) $(am__objects_12) $(am__objects_13) \
+ $(am__objects_14) $(am__objects_15) $(am__objects_16) \
+ $(am__objects_17) $(am__objects_18) $(am__objects_19) \
+ $(am__objects_20) $(am__objects_21) $(am__objects_22) \
+ $(am__objects_23) $(am__objects_24) $(am__objects_25) \
+ $(am__objects_26) $(am__objects_27) $(am__objects_28) \
+ $(am__objects_29)
+am__objects_31 = backspace.lo close.lo endfile.lo format.lo inquire.lo \
+ list_read.lo lock.lo open.lo read.lo rewind.lo transfer.lo \
+ unit.lo unix.lo write.lo
+am__objects_32 = associated.lo abort.lo cpu_time.lo cshift0.lo \
+ eoshift0.lo eoshift2.lo ishftc.lo pack_generic.lo size.lo \
+ spread_generic.lo string_intrinsics.lo random.lo \
+ reshape_generic.lo reshape_packed.lo selected_kind.lo \
+ transpose_generic.lo unpack_generic.lo in_pack_generic.lo \
+ in_unpack_generic.lo
+am__objects_33 =
+am__objects_34 = _abs_c4.lo _abs_c8.lo _abs_i4.lo _abs_i8.lo \
+ _abs_r4.lo _abs_r8.lo _exp_r4.lo _exp_r8.lo _exp_c4.lo \
+ _exp_c8.lo _log_r4.lo _log_r8.lo _log_c4.lo _log_c8.lo \
+ _log10_r4.lo _log10_r8.lo _sqrt_r4.lo _sqrt_r8.lo _sqrt_c4.lo \
+ _sqrt_c8.lo _asin_r4.lo _asin_r8.lo _acos_r4.lo _acos_r8.lo \
+ _atan_r4.lo _atan_r8.lo _sin_r4.lo _sin_r8.lo _sin_c4.lo \
+ _sin_c8.lo _cos_r4.lo _cos_r8.lo _cos_c4.lo _cos_c8.lo \
+ _tan_r4.lo _tan_r8.lo _sinh_r4.lo _sinh_r8.lo _cosh_r4.lo \
+ _cosh_r8.lo _tanh_r4.lo _tanh_r8.lo _conjg_c4.lo _conjg_c8.lo \
+ _aint_r4.lo _aint_r8.lo _anint_r4.lo _anint_r8.lo
+am__objects_35 = _sign_i4.lo _sign_i8.lo _sign_r4.lo _sign_r8.lo \
+ _dim_i4.lo _dim_i8.lo _dim_r4.lo _dim_r8.lo _atan2_r4.lo \
+ _atan2_r8.lo _mod_i4.lo _mod_i8.lo _mod_r4.lo _mod_r8.lo
+am__objects_36 = $(am__objects_34) $(am__objects_35) dprod_r8.lo
+am_libgfortran_la_OBJECTS = $(am__objects_1) $(am__objects_30) \
+ $(am__objects_31) $(am__objects_32) $(am__objects_33) \
+ $(am__objects_36)
+libgfortran_la_OBJECTS = $(am_libgfortran_la_OBJECTS)
+libgfortranbegin_la_LIBADD =
+am_libgfortranbegin_la_OBJECTS = fmain.lo
+libgfortranbegin_la_OBJECTS = $(am_libgfortranbegin_la_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
+depcomp = $(SHELL) $(top_srcdir)/../depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/abort.Plo ./$(DEPDIR)/all_l4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/all_l8.Plo ./$(DEPDIR)/any_l4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/any_l8.Plo ./$(DEPDIR)/associated.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/backspace.Plo ./$(DEPDIR)/close.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/count_4_l4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/count_4_l8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/count_8_l4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/count_8_l8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/cpu_time.Plo ./$(DEPDIR)/cshift0.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/cshift1_4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/cshift1_8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/dotprod_c4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/dotprod_c8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/dotprod_i4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/dotprod_i8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/dotprod_l4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/dotprod_l8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/dotprod_r4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/dotprod_r8.Plo ./$(DEPDIR)/endfile.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/environ.Plo ./$(DEPDIR)/eoshift0.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/eoshift1_4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/eoshift1_8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/eoshift2.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/eoshift3_4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/eoshift3_8.Plo ./$(DEPDIR)/error.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/exp_c4.Plo ./$(DEPDIR)/exp_c8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/exponent_r4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/exponent_r8.Plo ./$(DEPDIR)/fmain.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/format.Plo ./$(DEPDIR)/fraction_r4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/fraction_r8.Plo ./$(DEPDIR)/hyp_c4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/hyp_c8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/in_pack_generic.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/in_pack_i4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/in_pack_i8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/in_unpack_generic.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/in_unpack_i4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/in_unpack_i8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/inquire.Plo ./$(DEPDIR)/ishftc.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/list_read.Plo ./$(DEPDIR)/lock.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/main.Plo ./$(DEPDIR)/matmul_c4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/matmul_c8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/matmul_i4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/matmul_i8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/matmul_l4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/matmul_l8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/matmul_r4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/matmul_r8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/maxloc0_4_i4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/maxloc0_4_i8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/maxloc0_4_r4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/maxloc0_4_r8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/maxloc0_8_i4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/maxloc0_8_i8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/maxloc0_8_r4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/maxloc0_8_r8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/maxloc1_4_i4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/maxloc1_4_i8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/maxloc1_4_r4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/maxloc1_4_r8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/maxloc1_8_i4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/maxloc1_8_i8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/maxloc1_8_r4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/maxloc1_8_r8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/maxval_i4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/maxval_i8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/maxval_r4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/maxval_r8.Plo ./$(DEPDIR)/memory.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/minloc0_4_i4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/minloc0_4_i8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/minloc0_4_r4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/minloc0_4_r8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/minloc0_8_i4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/minloc0_8_i8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/minloc0_8_r4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/minloc0_8_r8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/minloc1_4_i4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/minloc1_4_i8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/minloc1_4_r4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/minloc1_4_r8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/minloc1_8_i4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/minloc1_8_i8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/minloc1_8_r4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/minloc1_8_r8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/minval_i4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/minval_i8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/minval_r4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/minval_r8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/nearest_r4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/nearest_r8.Plo ./$(DEPDIR)/open.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/pack_generic.Plo ./$(DEPDIR)/pause.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/product_c4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/product_c8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/product_i4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/product_i8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/product_r4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/product_r8.Plo ./$(DEPDIR)/random.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/read.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/reshape_generic.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/reshape_i4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/reshape_i8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/reshape_packed.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/rewind.Plo ./$(DEPDIR)/select.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/set_exponent_r4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/set_exponent_r8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/shape_i4.Plo ./$(DEPDIR)/shape_i8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/size.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/spread_generic.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/stop.Plo ./$(DEPDIR)/string.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/string_intrinsics.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/sum_c4.Plo ./$(DEPDIR)/sum_c8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/sum_i4.Plo ./$(DEPDIR)/sum_i8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/sum_r4.Plo ./$(DEPDIR)/sum_r8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/transfer.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/transpose_generic.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/transpose_i4.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/transpose_i8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/trig_c4.Plo ./$(DEPDIR)/trig_c8.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/unit.Plo ./$(DEPDIR)/unix.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/unpack_generic.Plo \
+@AMDEP_TRUE@ ./$(DEPDIR)/write.Plo
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+F77COMPILE = $(F77) $(AM_FFLAGS) $(FFLAGS)
+LTF77COMPILE = $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS)
+F77LD = $(F77)
+F77LINK = $(LIBTOOL) --mode=link $(F77LD) $(AM_FFLAGS) $(FFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libgfortran_la_SOURCES) $(EXTRA_libgfortran_la_SOURCES) \
+ $(libgfortranbegin_la_SOURCES)
+DIST_SOURCES = $(libgfortran_la_SOURCES) \
+ $(EXTRA_libgfortran_la_SOURCES) $(libgfortranbegin_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ { test ! -d $(distdir) \
+ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -fr $(distdir); }; }
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+MATH_OBJ = @MATH_OBJ@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_F77 = @ac_ct_F77@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+AM_CFLAGS = -std=gnu99
+lib_LTLIBRARIES = libgfortran.la libgfortranbegin.la
+libgfortranbegin_la_SOURCES = fmain.c
+libgfortranbegin_la_LDFLAGS = -static
+INCLUDES = -I$(srcdir)/io
+libgfortranincludedir = $(includedir)/gforio
+gfor_io_src = \
+io/backspace.c \
+io/close.c \
+io/endfile.c \
+io/format.c \
+io/inquire.c \
+io/list_read.c \
+io/lock.c \
+io/open.c \
+io/read.c \
+io/rewind.c \
+io/transfer.c \
+io/unit.c \
+io/unix.c \
+io/write.c
+
+gfor_io_headers = \
+io/io.h
+
+gfor_helper_src = \
+intrinsics/associated.c \
+intrinsics/abort.c \
+intrinsics/cpu_time.c \
+intrinsics/cshift0.c \
+intrinsics/eoshift0.c \
+intrinsics/eoshift2.c \
+intrinsics/ishftc.c \
+intrinsics/pack_generic.c \
+intrinsics/size.c \
+intrinsics/spread_generic.c \
+intrinsics/string_intrinsics.c \
+intrinsics/random.c \
+intrinsics/reshape_generic.c \
+intrinsics/reshape_packed.c \
+intrinsics/selected_kind.f90 \
+intrinsics/transpose_generic.c \
+intrinsics/unpack_generic.c \
+runtime/in_pack_generic.c \
+runtime/in_unpack_generic.c
+
+gfor_src = \
+runtime/environ.c \
+runtime/error.c \
+runtime/main.c \
+runtime/memory.c \
+runtime/pause.c \
+runtime/stop.c \
+runtime/string.c \
+runtime/select.c \
+gfortypes.h \
+libgfortran.h
+
+i_all_c = \
+generated/all_l4.c \
+generated/all_l8.c
+
+i_any_c = \
+generated/any_l4.c \
+generated/any_l8.c
+
+i_count_c = \
+generated/count_4_l4.c \
+generated/count_8_l4.c \
+generated/count_4_l8.c \
+generated/count_8_l8.c
+
+i_maxloc0_c = \
+generated/maxloc0_4_i4.c \
+generated/maxloc0_8_i4.c \
+generated/maxloc0_4_i8.c \
+generated/maxloc0_8_i8.c \
+generated/maxloc0_4_r4.c \
+generated/maxloc0_8_r4.c \
+generated/maxloc0_4_r8.c \
+generated/maxloc0_8_r8.c
+
+i_maxloc1_c = \
+generated/maxloc1_4_i4.c \
+generated/maxloc1_8_i4.c \
+generated/maxloc1_4_i8.c \
+generated/maxloc1_8_i8.c \
+generated/maxloc1_4_r4.c \
+generated/maxloc1_8_r4.c \
+generated/maxloc1_4_r8.c \
+generated/maxloc1_8_r8.c
+
+i_maxval_c = \
+generated/maxval_i4.c \
+generated/maxval_i8.c \
+generated/maxval_r4.c \
+generated/maxval_r8.c
+
+i_minloc0_c = \
+generated/minloc0_4_i4.c \
+generated/minloc0_8_i4.c \
+generated/minloc0_4_i8.c \
+generated/minloc0_8_i8.c \
+generated/minloc0_4_r4.c \
+generated/minloc0_8_r4.c \
+generated/minloc0_4_r8.c \
+generated/minloc0_8_r8.c
+
+i_minloc1_c = \
+generated/minloc1_4_i4.c \
+generated/minloc1_8_i4.c \
+generated/minloc1_4_i8.c \
+generated/minloc1_8_i8.c \
+generated/minloc1_4_r4.c \
+generated/minloc1_8_r4.c \
+generated/minloc1_4_r8.c \
+generated/minloc1_8_r8.c
+
+i_minval_c = \
+generated/minval_i4.c \
+generated/minval_i8.c \
+generated/minval_r4.c \
+generated/minval_r8.c
+
+i_sum_c = \
+generated/sum_i4.c \
+generated/sum_i8.c \
+generated/sum_r4.c \
+generated/sum_r8.c \
+generated/sum_c4.c \
+generated/sum_c8.c
+
+i_product_c = \
+generated/product_i4.c \
+generated/product_i8.c \
+generated/product_r4.c \
+generated/product_r8.c \
+generated/product_c4.c \
+generated/product_c8.c
+
+i_dotprod_c = \
+generated/dotprod_i4.c \
+generated/dotprod_i8.c \
+generated/dotprod_r4.c \
+generated/dotprod_r8.c
+
+i_dotprodl_c = \
+generated/dotprod_l4.c \
+generated/dotprod_l8.c
+
+i_dotprodc_c = \
+generated/dotprod_c4.c \
+generated/dotprod_c8.c
+
+i_matmul_c = \
+generated/matmul_i4.c \
+generated/matmul_i8.c \
+generated/matmul_r4.c \
+generated/matmul_r8.c \
+generated/matmul_c4.c \
+generated/matmul_c8.c
+
+i_matmull_c = \
+generated/matmul_l4.c \
+generated/matmul_l8.c
+
+i_transpose_c = \
+generated/transpose_i4.c \
+generated/transpose_i8.c
+
+i_shape_c = \
+generated/shape_i4.c \
+generated/shape_i8.c
+
+i_reshape_c = \
+generated/reshape_i4.c \
+generated/reshape_i8.c
+
+i_eoshift1_c = \
+generated/eoshift1_4.c \
+generated/eoshift1_8.c
+
+i_eoshift3_c = \
+generated/eoshift3_4.c \
+generated/eoshift3_8.c
+
+i_cshift1_c = \
+generated/cshift1_4.c \
+generated/cshift1_8.c
+
+in_pack_c = \
+generated/in_pack_i4.c \
+generated/in_pack_i8.c
+
+in_unpack_c = \
+generated/in_unpack_i4.c \
+generated/in_unpack_i8.c
+
+i_exponent_c = \
+generated/exponent_r4.c \
+generated/exponent_r8.c
+
+i_fraction_c = \
+generated/fraction_r4.c \
+generated/fraction_r8.c
+
+i_nearest_c = \
+generated/nearest_r4.c \
+generated/nearest_r8.c
+
+i_set_exponent_c = \
+generated/set_exponent_r4.c \
+generated/set_exponent_r8.c
+
+m4_files = m4/iparm.m4 m4/ifunction.m4 m4/iforeach.m4 m4/types.m4 m4/all.m4 \
+ m4/any.m4 m4/count.m4 m4/maxloc0.m4 m4/maxloc1.m4 m4/maxval.m4 \
+ m4/minloc0.m4 m4/minloc1.m4 m4/minval.m4 m4/product.m4 m4/sum.m4 \
+ m4/dotprod.m4 m4/dotprodl.m4 m4/dotprodc.m4 m4/matmul.m4 m4/matmull.m4 \
+ m4/ctrig.m4 m4/cexp.m4 m4/chyp.m4 m4/mtype.m4 \
+ m4/specific.m4 m4/specific2.m4 m4/head.m4 m4/shape.m4 m4/reshape.m4 \
+ m4/transpose.m4 m4/eoshift1.m4 m4/eoshift3.m4 m4/exponent.m4 \
+ m4/fraction.m4 m4/nearest.m4 m4/set_exponent.m4
+
+gfor_built_src = $(i_all_c) $(i_any_c) $(i_count_c) $(i_maxloc0_c) \
+ $(i_maxloc1_c) $(i_maxval_c) $(i_minloc0_c) $(i_minloc1_c) $(i_minval_c) \
+ $(i_product_c) $(i_sum_c) $(i_dotprod_c) $(i_dotprodl_c) $(i_dotprodc_c) \
+ $(i_matmul_c) $(i_matmull_c) $(i_transpose_c) $(i_shape_c) $(i_eoshift1_c) \
+ $(i_eoshift3_c) $(i_cshift1_c) $(i_reshape_c) $(in_pack_c) $(in_unpack_c) \
+ $(i_exponent_c) $(i_fraction_c) $(i_nearest_c) $(i_set_exponent_c)
+
+
+# We only use these if libm doesn't contain complex math functions.
+gfor_math_trig_c = \
+generated/trig_c4.c \
+generated/trig_c8.c
+
+gfor_math_exp_c = \
+generated/exp_c4.c \
+generated/exp_c8.c
+
+gfor_math_hyp_c = \
+generated/hyp_c4.c \
+generated/hyp_c8.c
+
+gfor_math_trig_obj = \
+trig_c4.lo \
+trig_c8.lo
+
+gfor_math_exp_obj = \
+exp_c4.lo \
+exp_c8.lo
+
+gfor_math_hyp_obj = \
+hyp_c4.lo \
+hyp_c8.lo
+
+
+# Machine generated specifics
+gfor_built_specific_src = \
+generated/_abs_c4.f90 \
+generated/_abs_c8.f90 \
+generated/_abs_i4.f90 \
+generated/_abs_i8.f90 \
+generated/_abs_r4.f90 \
+generated/_abs_r8.f90 \
+generated/_exp_r4.f90 \
+generated/_exp_r8.f90 \
+generated/_exp_c4.f90 \
+generated/_exp_c8.f90 \
+generated/_log_r4.f90 \
+generated/_log_r8.f90 \
+generated/_log_c4.f90 \
+generated/_log_c8.f90 \
+generated/_log10_r4.f90 \
+generated/_log10_r8.f90 \
+generated/_sqrt_r4.f90 \
+generated/_sqrt_r8.f90 \
+generated/_sqrt_c4.f90 \
+generated/_sqrt_c8.f90 \
+generated/_asin_r4.f90 \
+generated/_asin_r8.f90 \
+generated/_acos_r4.f90 \
+generated/_acos_r8.f90 \
+generated/_atan_r4.f90 \
+generated/_atan_r8.f90 \
+generated/_sin_r4.f90 \
+generated/_sin_r8.f90 \
+generated/_sin_c4.f90 \
+generated/_sin_c8.f90 \
+generated/_cos_r4.f90 \
+generated/_cos_r8.f90 \
+generated/_cos_c4.f90 \
+generated/_cos_c8.f90 \
+generated/_tan_r4.f90 \
+generated/_tan_r8.f90 \
+generated/_sinh_r4.f90 \
+generated/_sinh_r8.f90 \
+generated/_cosh_r4.f90 \
+generated/_cosh_r8.f90 \
+generated/_tanh_r4.f90 \
+generated/_tanh_r8.f90 \
+generated/_conjg_c4.f90 \
+generated/_conjg_c8.f90 \
+generated/_aint_r4.f90 \
+generated/_aint_r8.f90 \
+generated/_anint_r4.f90 \
+generated/_anint_r8.f90
+
+gfor_built_specific2_src = \
+generated/_sign_i4.f90 \
+generated/_sign_i8.f90 \
+generated/_sign_r4.f90 \
+generated/_sign_r8.f90 \
+generated/_dim_i4.f90 \
+generated/_dim_i8.f90 \
+generated/_dim_r4.f90 \
+generated/_dim_r8.f90 \
+generated/_atan2_r4.f90 \
+generated/_atan2_r8.f90 \
+generated/_mod_i4.f90 \
+generated/_mod_i8.f90 \
+generated/_mod_r4.f90 \
+generated/_mod_r8.f90
+
+#specific intrinsics requiring manal code
+#gfor_specific_c= \
+#intrinsics/_aimag.c \
+#intrinsics/_cabs.c \
+#foo
+gfor_specific_src = \
+$(gfor_built_specific_src) \
+$(gfor_built_specific2_src) \
+intrinsics/dprod_r8.f90
+
+gfor_cmath_src = $(gfor_math_trig_c) $(gfor_math_exp_c) $(gfor_math_hyp_c)
+gfor_cmath_obj = $(gfor_math_trig_obj) $(gfor_math_exp_obj) \
+ $(gfor_math_hyp_obj)
+
+BUILT_SOURCES = $(gfor_built_src) $(gfor_cmath_src) $(gfor_built_specific_src) \
+ $(gfor_built_specific2_src)
+
+libgfortran_la_SOURCES = $(gfor_src) $(gfor_built_src) $(gfor_io_src) \
+ $(gfor_helper_src) $(gfor_io_headers) $(gfor_specific_src)
+
+EXTRA_libgfortran_la_SOURCES = $(gfor_cmath_src)
+libgfortran_la_LIBADD = @MATH_OBJ@
+libgfortran_la_DEPENDENCIES = @MATH_OBJ@
+I_M4_DEPS = m4/iparm.m4 m4/types.m4
+I_M4_DEPS0 = $(I_M4_DEPS) m4/iforeach.m4
+I_M4_DEPS1 = $(I_M4_DEPS) m4/ifunction.m4
+EXTRA_DIST = $(m4_files)
+all: $(BUILT_SOURCES) config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .f90 .lo .o .obj
+am--refresh:
+ @:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \
+ cd $(srcdir) && $(AUTOMAKE) --gnu \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+
+config.h: stamp-h1
+ @if test ! -f $@; then \
+ rm -f stamp-h1; \
+ $(MAKE) stamp-h1; \
+ else :; fi
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+ @rm -f stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_srcdir) && $(AUTOHEADER)
+ rm -f stamp-h1
+ touch $@
+
+distclean-hdr:
+ -rm -f config.h stamp-h1
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkdir_p) $(DESTDIR)$(libdir)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f="`echo $$p | sed -e 's|^.*/||'`"; \
+ echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f"; \
+ $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ p="`echo $$p | sed -e 's|^.*/||'`"; \
+ echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p"; \
+ $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" = "$$p" && dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libgfortran.la: $(libgfortran_la_OBJECTS) $(libgfortran_la_DEPENDENCIES)
+ $(F77LINK) -rpath $(libdir) $(libgfortran_la_LDFLAGS) $(libgfortran_la_OBJECTS) $(libgfortran_la_LIBADD) $(LIBS)
+libgfortranbegin.la: $(libgfortranbegin_la_OBJECTS) $(libgfortranbegin_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libgfortranbegin_la_LDFLAGS) $(libgfortranbegin_la_OBJECTS) $(libgfortranbegin_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/abort.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/all_l4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/all_l8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/any_l4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/any_l8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/associated.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backspace.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/close.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/count_4_l4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/count_4_l8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/count_8_l4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/count_8_l8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu_time.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cshift0.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cshift1_4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cshift1_8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dotprod_c4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dotprod_c8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dotprod_i4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dotprod_i8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dotprod_l4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dotprod_l8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dotprod_r4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dotprod_r8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/endfile.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/environ.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eoshift0.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eoshift1_4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eoshift1_8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eoshift2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eoshift3_4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eoshift3_8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exp_c4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exp_c8.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)/fmain.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/format.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fraction_r4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fraction_r8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hyp_c4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hyp_c8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/in_pack_generic.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/in_pack_i4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/in_pack_i8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/in_unpack_generic.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/in_unpack_i4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/in_unpack_i8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inquire.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ishftc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list_read.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lock.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matmul_c4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matmul_c8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matmul_i4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matmul_i8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matmul_l4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matmul_l8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matmul_r4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matmul_r8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxloc0_4_i4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxloc0_4_i8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxloc0_4_r4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxloc0_4_r8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxloc0_8_i4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxloc0_8_i8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxloc0_8_r4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxloc0_8_r8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxloc1_4_i4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxloc1_4_i8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxloc1_4_r4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxloc1_4_r8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxloc1_8_i4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxloc1_8_i8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxloc1_8_r4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxloc1_8_r8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxval_i4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxval_i8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxval_r4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxval_r8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memory.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minloc0_4_i4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minloc0_4_i8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minloc0_4_r4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minloc0_4_r8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minloc0_8_i4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minloc0_8_i8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minloc0_8_r4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minloc0_8_r8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minloc1_4_i4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minloc1_4_i8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minloc1_4_r4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minloc1_4_r8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minloc1_8_i4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minloc1_8_i8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minloc1_8_r4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minloc1_8_r8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minval_i4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minval_i8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minval_r4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minval_r8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nearest_r4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nearest_r8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/open.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pack_generic.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pause.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/product_c4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/product_c8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/product_i4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/product_i8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/product_r4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/product_r8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/read.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reshape_generic.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reshape_i4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reshape_i8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reshape_packed.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rewind.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/select.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_exponent_r4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_exponent_r8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shape_i4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shape_i8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/size.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spread_generic.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stop.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string_intrinsics.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sum_c4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sum_c8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sum_i4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sum_i8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sum_r4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sum_r8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transfer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transpose_generic.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transpose_i4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transpose_i8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trig_c4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trig_c8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unit.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unpack_generic.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/write.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+environ.o: runtime/environ.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT environ.o -MD -MP -MF "$(DEPDIR)/environ.Tpo" -c -o environ.o `test -f 'runtime/environ.c' || echo '$(srcdir)/'`runtime/environ.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/environ.Tpo" "$(DEPDIR)/environ.Po"; else rm -f "$(DEPDIR)/environ.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/environ.c' object='environ.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/environ.Po' tmpdepfile='$(DEPDIR)/environ.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o environ.o `test -f 'runtime/environ.c' || echo '$(srcdir)/'`runtime/environ.c
+
+environ.obj: runtime/environ.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT environ.obj -MD -MP -MF "$(DEPDIR)/environ.Tpo" -c -o environ.obj `if test -f 'runtime/environ.c'; then $(CYGPATH_W) 'runtime/environ.c'; else $(CYGPATH_W) '$(srcdir)/runtime/environ.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/environ.Tpo" "$(DEPDIR)/environ.Po"; else rm -f "$(DEPDIR)/environ.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/environ.c' object='environ.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/environ.Po' tmpdepfile='$(DEPDIR)/environ.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o environ.obj `if test -f 'runtime/environ.c'; then $(CYGPATH_W) 'runtime/environ.c'; else $(CYGPATH_W) '$(srcdir)/runtime/environ.c'; fi`
+
+environ.lo: runtime/environ.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT environ.lo -MD -MP -MF "$(DEPDIR)/environ.Tpo" -c -o environ.lo `test -f 'runtime/environ.c' || echo '$(srcdir)/'`runtime/environ.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/environ.Tpo" "$(DEPDIR)/environ.Plo"; else rm -f "$(DEPDIR)/environ.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/environ.c' object='environ.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/environ.Plo' tmpdepfile='$(DEPDIR)/environ.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o environ.lo `test -f 'runtime/environ.c' || echo '$(srcdir)/'`runtime/environ.c
+
+error.o: runtime/error.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT error.o -MD -MP -MF "$(DEPDIR)/error.Tpo" -c -o error.o `test -f 'runtime/error.c' || echo '$(srcdir)/'`runtime/error.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/error.Tpo" "$(DEPDIR)/error.Po"; else rm -f "$(DEPDIR)/error.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/error.c' object='error.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/error.Po' tmpdepfile='$(DEPDIR)/error.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o error.o `test -f 'runtime/error.c' || echo '$(srcdir)/'`runtime/error.c
+
+error.obj: runtime/error.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT error.obj -MD -MP -MF "$(DEPDIR)/error.Tpo" -c -o error.obj `if test -f 'runtime/error.c'; then $(CYGPATH_W) 'runtime/error.c'; else $(CYGPATH_W) '$(srcdir)/runtime/error.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/error.Tpo" "$(DEPDIR)/error.Po"; else rm -f "$(DEPDIR)/error.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/error.c' object='error.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/error.Po' tmpdepfile='$(DEPDIR)/error.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o error.obj `if test -f 'runtime/error.c'; then $(CYGPATH_W) 'runtime/error.c'; else $(CYGPATH_W) '$(srcdir)/runtime/error.c'; fi`
+
+error.lo: runtime/error.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT error.lo -MD -MP -MF "$(DEPDIR)/error.Tpo" -c -o error.lo `test -f 'runtime/error.c' || echo '$(srcdir)/'`runtime/error.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/error.Tpo" "$(DEPDIR)/error.Plo"; else rm -f "$(DEPDIR)/error.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/error.c' object='error.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/error.Plo' tmpdepfile='$(DEPDIR)/error.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o error.lo `test -f 'runtime/error.c' || echo '$(srcdir)/'`runtime/error.c
+
+main.o: runtime/main.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT main.o -MD -MP -MF "$(DEPDIR)/main.Tpo" -c -o main.o `test -f 'runtime/main.c' || echo '$(srcdir)/'`runtime/main.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/main.Tpo" "$(DEPDIR)/main.Po"; else rm -f "$(DEPDIR)/main.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/main.c' object='main.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/main.Po' tmpdepfile='$(DEPDIR)/main.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o main.o `test -f 'runtime/main.c' || echo '$(srcdir)/'`runtime/main.c
+
+main.obj: runtime/main.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT main.obj -MD -MP -MF "$(DEPDIR)/main.Tpo" -c -o main.obj `if test -f 'runtime/main.c'; then $(CYGPATH_W) 'runtime/main.c'; else $(CYGPATH_W) '$(srcdir)/runtime/main.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/main.Tpo" "$(DEPDIR)/main.Po"; else rm -f "$(DEPDIR)/main.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/main.c' object='main.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/main.Po' tmpdepfile='$(DEPDIR)/main.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o main.obj `if test -f 'runtime/main.c'; then $(CYGPATH_W) 'runtime/main.c'; else $(CYGPATH_W) '$(srcdir)/runtime/main.c'; fi`
+
+main.lo: runtime/main.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT main.lo -MD -MP -MF "$(DEPDIR)/main.Tpo" -c -o main.lo `test -f 'runtime/main.c' || echo '$(srcdir)/'`runtime/main.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/main.Tpo" "$(DEPDIR)/main.Plo"; else rm -f "$(DEPDIR)/main.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/main.c' object='main.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/main.Plo' tmpdepfile='$(DEPDIR)/main.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o main.lo `test -f 'runtime/main.c' || echo '$(srcdir)/'`runtime/main.c
+
+memory.o: runtime/memory.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memory.o -MD -MP -MF "$(DEPDIR)/memory.Tpo" -c -o memory.o `test -f 'runtime/memory.c' || echo '$(srcdir)/'`runtime/memory.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/memory.Tpo" "$(DEPDIR)/memory.Po"; else rm -f "$(DEPDIR)/memory.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/memory.c' object='memory.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/memory.Po' tmpdepfile='$(DEPDIR)/memory.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memory.o `test -f 'runtime/memory.c' || echo '$(srcdir)/'`runtime/memory.c
+
+memory.obj: runtime/memory.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memory.obj -MD -MP -MF "$(DEPDIR)/memory.Tpo" -c -o memory.obj `if test -f 'runtime/memory.c'; then $(CYGPATH_W) 'runtime/memory.c'; else $(CYGPATH_W) '$(srcdir)/runtime/memory.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/memory.Tpo" "$(DEPDIR)/memory.Po"; else rm -f "$(DEPDIR)/memory.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/memory.c' object='memory.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/memory.Po' tmpdepfile='$(DEPDIR)/memory.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memory.obj `if test -f 'runtime/memory.c'; then $(CYGPATH_W) 'runtime/memory.c'; else $(CYGPATH_W) '$(srcdir)/runtime/memory.c'; fi`
+
+memory.lo: runtime/memory.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT memory.lo -MD -MP -MF "$(DEPDIR)/memory.Tpo" -c -o memory.lo `test -f 'runtime/memory.c' || echo '$(srcdir)/'`runtime/memory.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/memory.Tpo" "$(DEPDIR)/memory.Plo"; else rm -f "$(DEPDIR)/memory.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/memory.c' object='memory.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/memory.Plo' tmpdepfile='$(DEPDIR)/memory.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o memory.lo `test -f 'runtime/memory.c' || echo '$(srcdir)/'`runtime/memory.c
+
+pause.o: runtime/pause.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pause.o -MD -MP -MF "$(DEPDIR)/pause.Tpo" -c -o pause.o `test -f 'runtime/pause.c' || echo '$(srcdir)/'`runtime/pause.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/pause.Tpo" "$(DEPDIR)/pause.Po"; else rm -f "$(DEPDIR)/pause.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/pause.c' object='pause.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/pause.Po' tmpdepfile='$(DEPDIR)/pause.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pause.o `test -f 'runtime/pause.c' || echo '$(srcdir)/'`runtime/pause.c
+
+pause.obj: runtime/pause.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pause.obj -MD -MP -MF "$(DEPDIR)/pause.Tpo" -c -o pause.obj `if test -f 'runtime/pause.c'; then $(CYGPATH_W) 'runtime/pause.c'; else $(CYGPATH_W) '$(srcdir)/runtime/pause.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/pause.Tpo" "$(DEPDIR)/pause.Po"; else rm -f "$(DEPDIR)/pause.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/pause.c' object='pause.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/pause.Po' tmpdepfile='$(DEPDIR)/pause.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pause.obj `if test -f 'runtime/pause.c'; then $(CYGPATH_W) 'runtime/pause.c'; else $(CYGPATH_W) '$(srcdir)/runtime/pause.c'; fi`
+
+pause.lo: runtime/pause.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pause.lo -MD -MP -MF "$(DEPDIR)/pause.Tpo" -c -o pause.lo `test -f 'runtime/pause.c' || echo '$(srcdir)/'`runtime/pause.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/pause.Tpo" "$(DEPDIR)/pause.Plo"; else rm -f "$(DEPDIR)/pause.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/pause.c' object='pause.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/pause.Plo' tmpdepfile='$(DEPDIR)/pause.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pause.lo `test -f 'runtime/pause.c' || echo '$(srcdir)/'`runtime/pause.c
+
+stop.o: runtime/stop.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stop.o -MD -MP -MF "$(DEPDIR)/stop.Tpo" -c -o stop.o `test -f 'runtime/stop.c' || echo '$(srcdir)/'`runtime/stop.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/stop.Tpo" "$(DEPDIR)/stop.Po"; else rm -f "$(DEPDIR)/stop.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/stop.c' object='stop.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/stop.Po' tmpdepfile='$(DEPDIR)/stop.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o stop.o `test -f 'runtime/stop.c' || echo '$(srcdir)/'`runtime/stop.c
+
+stop.obj: runtime/stop.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stop.obj -MD -MP -MF "$(DEPDIR)/stop.Tpo" -c -o stop.obj `if test -f 'runtime/stop.c'; then $(CYGPATH_W) 'runtime/stop.c'; else $(CYGPATH_W) '$(srcdir)/runtime/stop.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/stop.Tpo" "$(DEPDIR)/stop.Po"; else rm -f "$(DEPDIR)/stop.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/stop.c' object='stop.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/stop.Po' tmpdepfile='$(DEPDIR)/stop.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o stop.obj `if test -f 'runtime/stop.c'; then $(CYGPATH_W) 'runtime/stop.c'; else $(CYGPATH_W) '$(srcdir)/runtime/stop.c'; fi`
+
+stop.lo: runtime/stop.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stop.lo -MD -MP -MF "$(DEPDIR)/stop.Tpo" -c -o stop.lo `test -f 'runtime/stop.c' || echo '$(srcdir)/'`runtime/stop.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/stop.Tpo" "$(DEPDIR)/stop.Plo"; else rm -f "$(DEPDIR)/stop.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/stop.c' object='stop.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/stop.Plo' tmpdepfile='$(DEPDIR)/stop.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o stop.lo `test -f 'runtime/stop.c' || echo '$(srcdir)/'`runtime/stop.c
+
+string.o: runtime/string.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT string.o -MD -MP -MF "$(DEPDIR)/string.Tpo" -c -o string.o `test -f 'runtime/string.c' || echo '$(srcdir)/'`runtime/string.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/string.Tpo" "$(DEPDIR)/string.Po"; else rm -f "$(DEPDIR)/string.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/string.c' object='string.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/string.Po' tmpdepfile='$(DEPDIR)/string.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o string.o `test -f 'runtime/string.c' || echo '$(srcdir)/'`runtime/string.c
+
+string.obj: runtime/string.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT string.obj -MD -MP -MF "$(DEPDIR)/string.Tpo" -c -o string.obj `if test -f 'runtime/string.c'; then $(CYGPATH_W) 'runtime/string.c'; else $(CYGPATH_W) '$(srcdir)/runtime/string.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/string.Tpo" "$(DEPDIR)/string.Po"; else rm -f "$(DEPDIR)/string.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/string.c' object='string.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/string.Po' tmpdepfile='$(DEPDIR)/string.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o string.obj `if test -f 'runtime/string.c'; then $(CYGPATH_W) 'runtime/string.c'; else $(CYGPATH_W) '$(srcdir)/runtime/string.c'; fi`
+
+string.lo: runtime/string.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT string.lo -MD -MP -MF "$(DEPDIR)/string.Tpo" -c -o string.lo `test -f 'runtime/string.c' || echo '$(srcdir)/'`runtime/string.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/string.Tpo" "$(DEPDIR)/string.Plo"; else rm -f "$(DEPDIR)/string.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/string.c' object='string.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/string.Plo' tmpdepfile='$(DEPDIR)/string.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o string.lo `test -f 'runtime/string.c' || echo '$(srcdir)/'`runtime/string.c
+
+select.o: runtime/select.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT select.o -MD -MP -MF "$(DEPDIR)/select.Tpo" -c -o select.o `test -f 'runtime/select.c' || echo '$(srcdir)/'`runtime/select.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/select.Tpo" "$(DEPDIR)/select.Po"; else rm -f "$(DEPDIR)/select.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/select.c' object='select.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/select.Po' tmpdepfile='$(DEPDIR)/select.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o select.o `test -f 'runtime/select.c' || echo '$(srcdir)/'`runtime/select.c
+
+select.obj: runtime/select.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT select.obj -MD -MP -MF "$(DEPDIR)/select.Tpo" -c -o select.obj `if test -f 'runtime/select.c'; then $(CYGPATH_W) 'runtime/select.c'; else $(CYGPATH_W) '$(srcdir)/runtime/select.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/select.Tpo" "$(DEPDIR)/select.Po"; else rm -f "$(DEPDIR)/select.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/select.c' object='select.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/select.Po' tmpdepfile='$(DEPDIR)/select.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o select.obj `if test -f 'runtime/select.c'; then $(CYGPATH_W) 'runtime/select.c'; else $(CYGPATH_W) '$(srcdir)/runtime/select.c'; fi`
+
+select.lo: runtime/select.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT select.lo -MD -MP -MF "$(DEPDIR)/select.Tpo" -c -o select.lo `test -f 'runtime/select.c' || echo '$(srcdir)/'`runtime/select.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/select.Tpo" "$(DEPDIR)/select.Plo"; else rm -f "$(DEPDIR)/select.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/select.c' object='select.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/select.Plo' tmpdepfile='$(DEPDIR)/select.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o select.lo `test -f 'runtime/select.c' || echo '$(srcdir)/'`runtime/select.c
+
+all_l4.o: generated/all_l4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT all_l4.o -MD -MP -MF "$(DEPDIR)/all_l4.Tpo" -c -o all_l4.o `test -f 'generated/all_l4.c' || echo '$(srcdir)/'`generated/all_l4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/all_l4.Tpo" "$(DEPDIR)/all_l4.Po"; else rm -f "$(DEPDIR)/all_l4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/all_l4.c' object='all_l4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/all_l4.Po' tmpdepfile='$(DEPDIR)/all_l4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o all_l4.o `test -f 'generated/all_l4.c' || echo '$(srcdir)/'`generated/all_l4.c
+
+all_l4.obj: generated/all_l4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT all_l4.obj -MD -MP -MF "$(DEPDIR)/all_l4.Tpo" -c -o all_l4.obj `if test -f 'generated/all_l4.c'; then $(CYGPATH_W) 'generated/all_l4.c'; else $(CYGPATH_W) '$(srcdir)/generated/all_l4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/all_l4.Tpo" "$(DEPDIR)/all_l4.Po"; else rm -f "$(DEPDIR)/all_l4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/all_l4.c' object='all_l4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/all_l4.Po' tmpdepfile='$(DEPDIR)/all_l4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o all_l4.obj `if test -f 'generated/all_l4.c'; then $(CYGPATH_W) 'generated/all_l4.c'; else $(CYGPATH_W) '$(srcdir)/generated/all_l4.c'; fi`
+
+all_l4.lo: generated/all_l4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT all_l4.lo -MD -MP -MF "$(DEPDIR)/all_l4.Tpo" -c -o all_l4.lo `test -f 'generated/all_l4.c' || echo '$(srcdir)/'`generated/all_l4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/all_l4.Tpo" "$(DEPDIR)/all_l4.Plo"; else rm -f "$(DEPDIR)/all_l4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/all_l4.c' object='all_l4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/all_l4.Plo' tmpdepfile='$(DEPDIR)/all_l4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o all_l4.lo `test -f 'generated/all_l4.c' || echo '$(srcdir)/'`generated/all_l4.c
+
+all_l8.o: generated/all_l8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT all_l8.o -MD -MP -MF "$(DEPDIR)/all_l8.Tpo" -c -o all_l8.o `test -f 'generated/all_l8.c' || echo '$(srcdir)/'`generated/all_l8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/all_l8.Tpo" "$(DEPDIR)/all_l8.Po"; else rm -f "$(DEPDIR)/all_l8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/all_l8.c' object='all_l8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/all_l8.Po' tmpdepfile='$(DEPDIR)/all_l8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o all_l8.o `test -f 'generated/all_l8.c' || echo '$(srcdir)/'`generated/all_l8.c
+
+all_l8.obj: generated/all_l8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT all_l8.obj -MD -MP -MF "$(DEPDIR)/all_l8.Tpo" -c -o all_l8.obj `if test -f 'generated/all_l8.c'; then $(CYGPATH_W) 'generated/all_l8.c'; else $(CYGPATH_W) '$(srcdir)/generated/all_l8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/all_l8.Tpo" "$(DEPDIR)/all_l8.Po"; else rm -f "$(DEPDIR)/all_l8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/all_l8.c' object='all_l8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/all_l8.Po' tmpdepfile='$(DEPDIR)/all_l8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o all_l8.obj `if test -f 'generated/all_l8.c'; then $(CYGPATH_W) 'generated/all_l8.c'; else $(CYGPATH_W) '$(srcdir)/generated/all_l8.c'; fi`
+
+all_l8.lo: generated/all_l8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT all_l8.lo -MD -MP -MF "$(DEPDIR)/all_l8.Tpo" -c -o all_l8.lo `test -f 'generated/all_l8.c' || echo '$(srcdir)/'`generated/all_l8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/all_l8.Tpo" "$(DEPDIR)/all_l8.Plo"; else rm -f "$(DEPDIR)/all_l8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/all_l8.c' object='all_l8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/all_l8.Plo' tmpdepfile='$(DEPDIR)/all_l8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o all_l8.lo `test -f 'generated/all_l8.c' || echo '$(srcdir)/'`generated/all_l8.c
+
+any_l4.o: generated/any_l4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT any_l4.o -MD -MP -MF "$(DEPDIR)/any_l4.Tpo" -c -o any_l4.o `test -f 'generated/any_l4.c' || echo '$(srcdir)/'`generated/any_l4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/any_l4.Tpo" "$(DEPDIR)/any_l4.Po"; else rm -f "$(DEPDIR)/any_l4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/any_l4.c' object='any_l4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/any_l4.Po' tmpdepfile='$(DEPDIR)/any_l4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o any_l4.o `test -f 'generated/any_l4.c' || echo '$(srcdir)/'`generated/any_l4.c
+
+any_l4.obj: generated/any_l4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT any_l4.obj -MD -MP -MF "$(DEPDIR)/any_l4.Tpo" -c -o any_l4.obj `if test -f 'generated/any_l4.c'; then $(CYGPATH_W) 'generated/any_l4.c'; else $(CYGPATH_W) '$(srcdir)/generated/any_l4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/any_l4.Tpo" "$(DEPDIR)/any_l4.Po"; else rm -f "$(DEPDIR)/any_l4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/any_l4.c' object='any_l4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/any_l4.Po' tmpdepfile='$(DEPDIR)/any_l4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o any_l4.obj `if test -f 'generated/any_l4.c'; then $(CYGPATH_W) 'generated/any_l4.c'; else $(CYGPATH_W) '$(srcdir)/generated/any_l4.c'; fi`
+
+any_l4.lo: generated/any_l4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT any_l4.lo -MD -MP -MF "$(DEPDIR)/any_l4.Tpo" -c -o any_l4.lo `test -f 'generated/any_l4.c' || echo '$(srcdir)/'`generated/any_l4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/any_l4.Tpo" "$(DEPDIR)/any_l4.Plo"; else rm -f "$(DEPDIR)/any_l4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/any_l4.c' object='any_l4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/any_l4.Plo' tmpdepfile='$(DEPDIR)/any_l4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o any_l4.lo `test -f 'generated/any_l4.c' || echo '$(srcdir)/'`generated/any_l4.c
+
+any_l8.o: generated/any_l8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT any_l8.o -MD -MP -MF "$(DEPDIR)/any_l8.Tpo" -c -o any_l8.o `test -f 'generated/any_l8.c' || echo '$(srcdir)/'`generated/any_l8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/any_l8.Tpo" "$(DEPDIR)/any_l8.Po"; else rm -f "$(DEPDIR)/any_l8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/any_l8.c' object='any_l8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/any_l8.Po' tmpdepfile='$(DEPDIR)/any_l8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o any_l8.o `test -f 'generated/any_l8.c' || echo '$(srcdir)/'`generated/any_l8.c
+
+any_l8.obj: generated/any_l8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT any_l8.obj -MD -MP -MF "$(DEPDIR)/any_l8.Tpo" -c -o any_l8.obj `if test -f 'generated/any_l8.c'; then $(CYGPATH_W) 'generated/any_l8.c'; else $(CYGPATH_W) '$(srcdir)/generated/any_l8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/any_l8.Tpo" "$(DEPDIR)/any_l8.Po"; else rm -f "$(DEPDIR)/any_l8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/any_l8.c' object='any_l8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/any_l8.Po' tmpdepfile='$(DEPDIR)/any_l8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o any_l8.obj `if test -f 'generated/any_l8.c'; then $(CYGPATH_W) 'generated/any_l8.c'; else $(CYGPATH_W) '$(srcdir)/generated/any_l8.c'; fi`
+
+any_l8.lo: generated/any_l8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT any_l8.lo -MD -MP -MF "$(DEPDIR)/any_l8.Tpo" -c -o any_l8.lo `test -f 'generated/any_l8.c' || echo '$(srcdir)/'`generated/any_l8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/any_l8.Tpo" "$(DEPDIR)/any_l8.Plo"; else rm -f "$(DEPDIR)/any_l8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/any_l8.c' object='any_l8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/any_l8.Plo' tmpdepfile='$(DEPDIR)/any_l8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o any_l8.lo `test -f 'generated/any_l8.c' || echo '$(srcdir)/'`generated/any_l8.c
+
+count_4_l4.o: generated/count_4_l4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT count_4_l4.o -MD -MP -MF "$(DEPDIR)/count_4_l4.Tpo" -c -o count_4_l4.o `test -f 'generated/count_4_l4.c' || echo '$(srcdir)/'`generated/count_4_l4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/count_4_l4.Tpo" "$(DEPDIR)/count_4_l4.Po"; else rm -f "$(DEPDIR)/count_4_l4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/count_4_l4.c' object='count_4_l4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/count_4_l4.Po' tmpdepfile='$(DEPDIR)/count_4_l4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o count_4_l4.o `test -f 'generated/count_4_l4.c' || echo '$(srcdir)/'`generated/count_4_l4.c
+
+count_4_l4.obj: generated/count_4_l4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT count_4_l4.obj -MD -MP -MF "$(DEPDIR)/count_4_l4.Tpo" -c -o count_4_l4.obj `if test -f 'generated/count_4_l4.c'; then $(CYGPATH_W) 'generated/count_4_l4.c'; else $(CYGPATH_W) '$(srcdir)/generated/count_4_l4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/count_4_l4.Tpo" "$(DEPDIR)/count_4_l4.Po"; else rm -f "$(DEPDIR)/count_4_l4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/count_4_l4.c' object='count_4_l4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/count_4_l4.Po' tmpdepfile='$(DEPDIR)/count_4_l4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o count_4_l4.obj `if test -f 'generated/count_4_l4.c'; then $(CYGPATH_W) 'generated/count_4_l4.c'; else $(CYGPATH_W) '$(srcdir)/generated/count_4_l4.c'; fi`
+
+count_4_l4.lo: generated/count_4_l4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT count_4_l4.lo -MD -MP -MF "$(DEPDIR)/count_4_l4.Tpo" -c -o count_4_l4.lo `test -f 'generated/count_4_l4.c' || echo '$(srcdir)/'`generated/count_4_l4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/count_4_l4.Tpo" "$(DEPDIR)/count_4_l4.Plo"; else rm -f "$(DEPDIR)/count_4_l4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/count_4_l4.c' object='count_4_l4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/count_4_l4.Plo' tmpdepfile='$(DEPDIR)/count_4_l4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o count_4_l4.lo `test -f 'generated/count_4_l4.c' || echo '$(srcdir)/'`generated/count_4_l4.c
+
+count_8_l4.o: generated/count_8_l4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT count_8_l4.o -MD -MP -MF "$(DEPDIR)/count_8_l4.Tpo" -c -o count_8_l4.o `test -f 'generated/count_8_l4.c' || echo '$(srcdir)/'`generated/count_8_l4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/count_8_l4.Tpo" "$(DEPDIR)/count_8_l4.Po"; else rm -f "$(DEPDIR)/count_8_l4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/count_8_l4.c' object='count_8_l4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/count_8_l4.Po' tmpdepfile='$(DEPDIR)/count_8_l4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o count_8_l4.o `test -f 'generated/count_8_l4.c' || echo '$(srcdir)/'`generated/count_8_l4.c
+
+count_8_l4.obj: generated/count_8_l4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT count_8_l4.obj -MD -MP -MF "$(DEPDIR)/count_8_l4.Tpo" -c -o count_8_l4.obj `if test -f 'generated/count_8_l4.c'; then $(CYGPATH_W) 'generated/count_8_l4.c'; else $(CYGPATH_W) '$(srcdir)/generated/count_8_l4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/count_8_l4.Tpo" "$(DEPDIR)/count_8_l4.Po"; else rm -f "$(DEPDIR)/count_8_l4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/count_8_l4.c' object='count_8_l4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/count_8_l4.Po' tmpdepfile='$(DEPDIR)/count_8_l4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o count_8_l4.obj `if test -f 'generated/count_8_l4.c'; then $(CYGPATH_W) 'generated/count_8_l4.c'; else $(CYGPATH_W) '$(srcdir)/generated/count_8_l4.c'; fi`
+
+count_8_l4.lo: generated/count_8_l4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT count_8_l4.lo -MD -MP -MF "$(DEPDIR)/count_8_l4.Tpo" -c -o count_8_l4.lo `test -f 'generated/count_8_l4.c' || echo '$(srcdir)/'`generated/count_8_l4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/count_8_l4.Tpo" "$(DEPDIR)/count_8_l4.Plo"; else rm -f "$(DEPDIR)/count_8_l4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/count_8_l4.c' object='count_8_l4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/count_8_l4.Plo' tmpdepfile='$(DEPDIR)/count_8_l4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o count_8_l4.lo `test -f 'generated/count_8_l4.c' || echo '$(srcdir)/'`generated/count_8_l4.c
+
+count_4_l8.o: generated/count_4_l8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT count_4_l8.o -MD -MP -MF "$(DEPDIR)/count_4_l8.Tpo" -c -o count_4_l8.o `test -f 'generated/count_4_l8.c' || echo '$(srcdir)/'`generated/count_4_l8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/count_4_l8.Tpo" "$(DEPDIR)/count_4_l8.Po"; else rm -f "$(DEPDIR)/count_4_l8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/count_4_l8.c' object='count_4_l8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/count_4_l8.Po' tmpdepfile='$(DEPDIR)/count_4_l8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o count_4_l8.o `test -f 'generated/count_4_l8.c' || echo '$(srcdir)/'`generated/count_4_l8.c
+
+count_4_l8.obj: generated/count_4_l8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT count_4_l8.obj -MD -MP -MF "$(DEPDIR)/count_4_l8.Tpo" -c -o count_4_l8.obj `if test -f 'generated/count_4_l8.c'; then $(CYGPATH_W) 'generated/count_4_l8.c'; else $(CYGPATH_W) '$(srcdir)/generated/count_4_l8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/count_4_l8.Tpo" "$(DEPDIR)/count_4_l8.Po"; else rm -f "$(DEPDIR)/count_4_l8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/count_4_l8.c' object='count_4_l8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/count_4_l8.Po' tmpdepfile='$(DEPDIR)/count_4_l8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o count_4_l8.obj `if test -f 'generated/count_4_l8.c'; then $(CYGPATH_W) 'generated/count_4_l8.c'; else $(CYGPATH_W) '$(srcdir)/generated/count_4_l8.c'; fi`
+
+count_4_l8.lo: generated/count_4_l8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT count_4_l8.lo -MD -MP -MF "$(DEPDIR)/count_4_l8.Tpo" -c -o count_4_l8.lo `test -f 'generated/count_4_l8.c' || echo '$(srcdir)/'`generated/count_4_l8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/count_4_l8.Tpo" "$(DEPDIR)/count_4_l8.Plo"; else rm -f "$(DEPDIR)/count_4_l8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/count_4_l8.c' object='count_4_l8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/count_4_l8.Plo' tmpdepfile='$(DEPDIR)/count_4_l8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o count_4_l8.lo `test -f 'generated/count_4_l8.c' || echo '$(srcdir)/'`generated/count_4_l8.c
+
+count_8_l8.o: generated/count_8_l8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT count_8_l8.o -MD -MP -MF "$(DEPDIR)/count_8_l8.Tpo" -c -o count_8_l8.o `test -f 'generated/count_8_l8.c' || echo '$(srcdir)/'`generated/count_8_l8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/count_8_l8.Tpo" "$(DEPDIR)/count_8_l8.Po"; else rm -f "$(DEPDIR)/count_8_l8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/count_8_l8.c' object='count_8_l8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/count_8_l8.Po' tmpdepfile='$(DEPDIR)/count_8_l8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o count_8_l8.o `test -f 'generated/count_8_l8.c' || echo '$(srcdir)/'`generated/count_8_l8.c
+
+count_8_l8.obj: generated/count_8_l8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT count_8_l8.obj -MD -MP -MF "$(DEPDIR)/count_8_l8.Tpo" -c -o count_8_l8.obj `if test -f 'generated/count_8_l8.c'; then $(CYGPATH_W) 'generated/count_8_l8.c'; else $(CYGPATH_W) '$(srcdir)/generated/count_8_l8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/count_8_l8.Tpo" "$(DEPDIR)/count_8_l8.Po"; else rm -f "$(DEPDIR)/count_8_l8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/count_8_l8.c' object='count_8_l8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/count_8_l8.Po' tmpdepfile='$(DEPDIR)/count_8_l8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o count_8_l8.obj `if test -f 'generated/count_8_l8.c'; then $(CYGPATH_W) 'generated/count_8_l8.c'; else $(CYGPATH_W) '$(srcdir)/generated/count_8_l8.c'; fi`
+
+count_8_l8.lo: generated/count_8_l8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT count_8_l8.lo -MD -MP -MF "$(DEPDIR)/count_8_l8.Tpo" -c -o count_8_l8.lo `test -f 'generated/count_8_l8.c' || echo '$(srcdir)/'`generated/count_8_l8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/count_8_l8.Tpo" "$(DEPDIR)/count_8_l8.Plo"; else rm -f "$(DEPDIR)/count_8_l8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/count_8_l8.c' object='count_8_l8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/count_8_l8.Plo' tmpdepfile='$(DEPDIR)/count_8_l8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o count_8_l8.lo `test -f 'generated/count_8_l8.c' || echo '$(srcdir)/'`generated/count_8_l8.c
+
+maxloc0_4_i4.o: generated/maxloc0_4_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_4_i4.o -MD -MP -MF "$(DEPDIR)/maxloc0_4_i4.Tpo" -c -o maxloc0_4_i4.o `test -f 'generated/maxloc0_4_i4.c' || echo '$(srcdir)/'`generated/maxloc0_4_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_4_i4.Tpo" "$(DEPDIR)/maxloc0_4_i4.Po"; else rm -f "$(DEPDIR)/maxloc0_4_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_4_i4.c' object='maxloc0_4_i4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_4_i4.Po' tmpdepfile='$(DEPDIR)/maxloc0_4_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_4_i4.o `test -f 'generated/maxloc0_4_i4.c' || echo '$(srcdir)/'`generated/maxloc0_4_i4.c
+
+maxloc0_4_i4.obj: generated/maxloc0_4_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_4_i4.obj -MD -MP -MF "$(DEPDIR)/maxloc0_4_i4.Tpo" -c -o maxloc0_4_i4.obj `if test -f 'generated/maxloc0_4_i4.c'; then $(CYGPATH_W) 'generated/maxloc0_4_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc0_4_i4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_4_i4.Tpo" "$(DEPDIR)/maxloc0_4_i4.Po"; else rm -f "$(DEPDIR)/maxloc0_4_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_4_i4.c' object='maxloc0_4_i4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_4_i4.Po' tmpdepfile='$(DEPDIR)/maxloc0_4_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_4_i4.obj `if test -f 'generated/maxloc0_4_i4.c'; then $(CYGPATH_W) 'generated/maxloc0_4_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc0_4_i4.c'; fi`
+
+maxloc0_4_i4.lo: generated/maxloc0_4_i4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_4_i4.lo -MD -MP -MF "$(DEPDIR)/maxloc0_4_i4.Tpo" -c -o maxloc0_4_i4.lo `test -f 'generated/maxloc0_4_i4.c' || echo '$(srcdir)/'`generated/maxloc0_4_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_4_i4.Tpo" "$(DEPDIR)/maxloc0_4_i4.Plo"; else rm -f "$(DEPDIR)/maxloc0_4_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_4_i4.c' object='maxloc0_4_i4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_4_i4.Plo' tmpdepfile='$(DEPDIR)/maxloc0_4_i4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_4_i4.lo `test -f 'generated/maxloc0_4_i4.c' || echo '$(srcdir)/'`generated/maxloc0_4_i4.c
+
+maxloc0_8_i4.o: generated/maxloc0_8_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_8_i4.o -MD -MP -MF "$(DEPDIR)/maxloc0_8_i4.Tpo" -c -o maxloc0_8_i4.o `test -f 'generated/maxloc0_8_i4.c' || echo '$(srcdir)/'`generated/maxloc0_8_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_8_i4.Tpo" "$(DEPDIR)/maxloc0_8_i4.Po"; else rm -f "$(DEPDIR)/maxloc0_8_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_8_i4.c' object='maxloc0_8_i4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_8_i4.Po' tmpdepfile='$(DEPDIR)/maxloc0_8_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_8_i4.o `test -f 'generated/maxloc0_8_i4.c' || echo '$(srcdir)/'`generated/maxloc0_8_i4.c
+
+maxloc0_8_i4.obj: generated/maxloc0_8_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_8_i4.obj -MD -MP -MF "$(DEPDIR)/maxloc0_8_i4.Tpo" -c -o maxloc0_8_i4.obj `if test -f 'generated/maxloc0_8_i4.c'; then $(CYGPATH_W) 'generated/maxloc0_8_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc0_8_i4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_8_i4.Tpo" "$(DEPDIR)/maxloc0_8_i4.Po"; else rm -f "$(DEPDIR)/maxloc0_8_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_8_i4.c' object='maxloc0_8_i4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_8_i4.Po' tmpdepfile='$(DEPDIR)/maxloc0_8_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_8_i4.obj `if test -f 'generated/maxloc0_8_i4.c'; then $(CYGPATH_W) 'generated/maxloc0_8_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc0_8_i4.c'; fi`
+
+maxloc0_8_i4.lo: generated/maxloc0_8_i4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_8_i4.lo -MD -MP -MF "$(DEPDIR)/maxloc0_8_i4.Tpo" -c -o maxloc0_8_i4.lo `test -f 'generated/maxloc0_8_i4.c' || echo '$(srcdir)/'`generated/maxloc0_8_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_8_i4.Tpo" "$(DEPDIR)/maxloc0_8_i4.Plo"; else rm -f "$(DEPDIR)/maxloc0_8_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_8_i4.c' object='maxloc0_8_i4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_8_i4.Plo' tmpdepfile='$(DEPDIR)/maxloc0_8_i4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_8_i4.lo `test -f 'generated/maxloc0_8_i4.c' || echo '$(srcdir)/'`generated/maxloc0_8_i4.c
+
+maxloc0_4_i8.o: generated/maxloc0_4_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_4_i8.o -MD -MP -MF "$(DEPDIR)/maxloc0_4_i8.Tpo" -c -o maxloc0_4_i8.o `test -f 'generated/maxloc0_4_i8.c' || echo '$(srcdir)/'`generated/maxloc0_4_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_4_i8.Tpo" "$(DEPDIR)/maxloc0_4_i8.Po"; else rm -f "$(DEPDIR)/maxloc0_4_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_4_i8.c' object='maxloc0_4_i8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_4_i8.Po' tmpdepfile='$(DEPDIR)/maxloc0_4_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_4_i8.o `test -f 'generated/maxloc0_4_i8.c' || echo '$(srcdir)/'`generated/maxloc0_4_i8.c
+
+maxloc0_4_i8.obj: generated/maxloc0_4_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_4_i8.obj -MD -MP -MF "$(DEPDIR)/maxloc0_4_i8.Tpo" -c -o maxloc0_4_i8.obj `if test -f 'generated/maxloc0_4_i8.c'; then $(CYGPATH_W) 'generated/maxloc0_4_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc0_4_i8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_4_i8.Tpo" "$(DEPDIR)/maxloc0_4_i8.Po"; else rm -f "$(DEPDIR)/maxloc0_4_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_4_i8.c' object='maxloc0_4_i8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_4_i8.Po' tmpdepfile='$(DEPDIR)/maxloc0_4_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_4_i8.obj `if test -f 'generated/maxloc0_4_i8.c'; then $(CYGPATH_W) 'generated/maxloc0_4_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc0_4_i8.c'; fi`
+
+maxloc0_4_i8.lo: generated/maxloc0_4_i8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_4_i8.lo -MD -MP -MF "$(DEPDIR)/maxloc0_4_i8.Tpo" -c -o maxloc0_4_i8.lo `test -f 'generated/maxloc0_4_i8.c' || echo '$(srcdir)/'`generated/maxloc0_4_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_4_i8.Tpo" "$(DEPDIR)/maxloc0_4_i8.Plo"; else rm -f "$(DEPDIR)/maxloc0_4_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_4_i8.c' object='maxloc0_4_i8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_4_i8.Plo' tmpdepfile='$(DEPDIR)/maxloc0_4_i8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_4_i8.lo `test -f 'generated/maxloc0_4_i8.c' || echo '$(srcdir)/'`generated/maxloc0_4_i8.c
+
+maxloc0_8_i8.o: generated/maxloc0_8_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_8_i8.o -MD -MP -MF "$(DEPDIR)/maxloc0_8_i8.Tpo" -c -o maxloc0_8_i8.o `test -f 'generated/maxloc0_8_i8.c' || echo '$(srcdir)/'`generated/maxloc0_8_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_8_i8.Tpo" "$(DEPDIR)/maxloc0_8_i8.Po"; else rm -f "$(DEPDIR)/maxloc0_8_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_8_i8.c' object='maxloc0_8_i8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_8_i8.Po' tmpdepfile='$(DEPDIR)/maxloc0_8_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_8_i8.o `test -f 'generated/maxloc0_8_i8.c' || echo '$(srcdir)/'`generated/maxloc0_8_i8.c
+
+maxloc0_8_i8.obj: generated/maxloc0_8_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_8_i8.obj -MD -MP -MF "$(DEPDIR)/maxloc0_8_i8.Tpo" -c -o maxloc0_8_i8.obj `if test -f 'generated/maxloc0_8_i8.c'; then $(CYGPATH_W) 'generated/maxloc0_8_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc0_8_i8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_8_i8.Tpo" "$(DEPDIR)/maxloc0_8_i8.Po"; else rm -f "$(DEPDIR)/maxloc0_8_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_8_i8.c' object='maxloc0_8_i8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_8_i8.Po' tmpdepfile='$(DEPDIR)/maxloc0_8_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_8_i8.obj `if test -f 'generated/maxloc0_8_i8.c'; then $(CYGPATH_W) 'generated/maxloc0_8_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc0_8_i8.c'; fi`
+
+maxloc0_8_i8.lo: generated/maxloc0_8_i8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_8_i8.lo -MD -MP -MF "$(DEPDIR)/maxloc0_8_i8.Tpo" -c -o maxloc0_8_i8.lo `test -f 'generated/maxloc0_8_i8.c' || echo '$(srcdir)/'`generated/maxloc0_8_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_8_i8.Tpo" "$(DEPDIR)/maxloc0_8_i8.Plo"; else rm -f "$(DEPDIR)/maxloc0_8_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_8_i8.c' object='maxloc0_8_i8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_8_i8.Plo' tmpdepfile='$(DEPDIR)/maxloc0_8_i8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_8_i8.lo `test -f 'generated/maxloc0_8_i8.c' || echo '$(srcdir)/'`generated/maxloc0_8_i8.c
+
+maxloc0_4_r4.o: generated/maxloc0_4_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_4_r4.o -MD -MP -MF "$(DEPDIR)/maxloc0_4_r4.Tpo" -c -o maxloc0_4_r4.o `test -f 'generated/maxloc0_4_r4.c' || echo '$(srcdir)/'`generated/maxloc0_4_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_4_r4.Tpo" "$(DEPDIR)/maxloc0_4_r4.Po"; else rm -f "$(DEPDIR)/maxloc0_4_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_4_r4.c' object='maxloc0_4_r4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_4_r4.Po' tmpdepfile='$(DEPDIR)/maxloc0_4_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_4_r4.o `test -f 'generated/maxloc0_4_r4.c' || echo '$(srcdir)/'`generated/maxloc0_4_r4.c
+
+maxloc0_4_r4.obj: generated/maxloc0_4_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_4_r4.obj -MD -MP -MF "$(DEPDIR)/maxloc0_4_r4.Tpo" -c -o maxloc0_4_r4.obj `if test -f 'generated/maxloc0_4_r4.c'; then $(CYGPATH_W) 'generated/maxloc0_4_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc0_4_r4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_4_r4.Tpo" "$(DEPDIR)/maxloc0_4_r4.Po"; else rm -f "$(DEPDIR)/maxloc0_4_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_4_r4.c' object='maxloc0_4_r4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_4_r4.Po' tmpdepfile='$(DEPDIR)/maxloc0_4_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_4_r4.obj `if test -f 'generated/maxloc0_4_r4.c'; then $(CYGPATH_W) 'generated/maxloc0_4_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc0_4_r4.c'; fi`
+
+maxloc0_4_r4.lo: generated/maxloc0_4_r4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_4_r4.lo -MD -MP -MF "$(DEPDIR)/maxloc0_4_r4.Tpo" -c -o maxloc0_4_r4.lo `test -f 'generated/maxloc0_4_r4.c' || echo '$(srcdir)/'`generated/maxloc0_4_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_4_r4.Tpo" "$(DEPDIR)/maxloc0_4_r4.Plo"; else rm -f "$(DEPDIR)/maxloc0_4_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_4_r4.c' object='maxloc0_4_r4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_4_r4.Plo' tmpdepfile='$(DEPDIR)/maxloc0_4_r4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_4_r4.lo `test -f 'generated/maxloc0_4_r4.c' || echo '$(srcdir)/'`generated/maxloc0_4_r4.c
+
+maxloc0_8_r4.o: generated/maxloc0_8_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_8_r4.o -MD -MP -MF "$(DEPDIR)/maxloc0_8_r4.Tpo" -c -o maxloc0_8_r4.o `test -f 'generated/maxloc0_8_r4.c' || echo '$(srcdir)/'`generated/maxloc0_8_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_8_r4.Tpo" "$(DEPDIR)/maxloc0_8_r4.Po"; else rm -f "$(DEPDIR)/maxloc0_8_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_8_r4.c' object='maxloc0_8_r4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_8_r4.Po' tmpdepfile='$(DEPDIR)/maxloc0_8_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_8_r4.o `test -f 'generated/maxloc0_8_r4.c' || echo '$(srcdir)/'`generated/maxloc0_8_r4.c
+
+maxloc0_8_r4.obj: generated/maxloc0_8_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_8_r4.obj -MD -MP -MF "$(DEPDIR)/maxloc0_8_r4.Tpo" -c -o maxloc0_8_r4.obj `if test -f 'generated/maxloc0_8_r4.c'; then $(CYGPATH_W) 'generated/maxloc0_8_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc0_8_r4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_8_r4.Tpo" "$(DEPDIR)/maxloc0_8_r4.Po"; else rm -f "$(DEPDIR)/maxloc0_8_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_8_r4.c' object='maxloc0_8_r4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_8_r4.Po' tmpdepfile='$(DEPDIR)/maxloc0_8_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_8_r4.obj `if test -f 'generated/maxloc0_8_r4.c'; then $(CYGPATH_W) 'generated/maxloc0_8_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc0_8_r4.c'; fi`
+
+maxloc0_8_r4.lo: generated/maxloc0_8_r4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_8_r4.lo -MD -MP -MF "$(DEPDIR)/maxloc0_8_r4.Tpo" -c -o maxloc0_8_r4.lo `test -f 'generated/maxloc0_8_r4.c' || echo '$(srcdir)/'`generated/maxloc0_8_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_8_r4.Tpo" "$(DEPDIR)/maxloc0_8_r4.Plo"; else rm -f "$(DEPDIR)/maxloc0_8_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_8_r4.c' object='maxloc0_8_r4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_8_r4.Plo' tmpdepfile='$(DEPDIR)/maxloc0_8_r4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_8_r4.lo `test -f 'generated/maxloc0_8_r4.c' || echo '$(srcdir)/'`generated/maxloc0_8_r4.c
+
+maxloc0_4_r8.o: generated/maxloc0_4_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_4_r8.o -MD -MP -MF "$(DEPDIR)/maxloc0_4_r8.Tpo" -c -o maxloc0_4_r8.o `test -f 'generated/maxloc0_4_r8.c' || echo '$(srcdir)/'`generated/maxloc0_4_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_4_r8.Tpo" "$(DEPDIR)/maxloc0_4_r8.Po"; else rm -f "$(DEPDIR)/maxloc0_4_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_4_r8.c' object='maxloc0_4_r8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_4_r8.Po' tmpdepfile='$(DEPDIR)/maxloc0_4_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_4_r8.o `test -f 'generated/maxloc0_4_r8.c' || echo '$(srcdir)/'`generated/maxloc0_4_r8.c
+
+maxloc0_4_r8.obj: generated/maxloc0_4_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_4_r8.obj -MD -MP -MF "$(DEPDIR)/maxloc0_4_r8.Tpo" -c -o maxloc0_4_r8.obj `if test -f 'generated/maxloc0_4_r8.c'; then $(CYGPATH_W) 'generated/maxloc0_4_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc0_4_r8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_4_r8.Tpo" "$(DEPDIR)/maxloc0_4_r8.Po"; else rm -f "$(DEPDIR)/maxloc0_4_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_4_r8.c' object='maxloc0_4_r8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_4_r8.Po' tmpdepfile='$(DEPDIR)/maxloc0_4_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_4_r8.obj `if test -f 'generated/maxloc0_4_r8.c'; then $(CYGPATH_W) 'generated/maxloc0_4_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc0_4_r8.c'; fi`
+
+maxloc0_4_r8.lo: generated/maxloc0_4_r8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_4_r8.lo -MD -MP -MF "$(DEPDIR)/maxloc0_4_r8.Tpo" -c -o maxloc0_4_r8.lo `test -f 'generated/maxloc0_4_r8.c' || echo '$(srcdir)/'`generated/maxloc0_4_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_4_r8.Tpo" "$(DEPDIR)/maxloc0_4_r8.Plo"; else rm -f "$(DEPDIR)/maxloc0_4_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_4_r8.c' object='maxloc0_4_r8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_4_r8.Plo' tmpdepfile='$(DEPDIR)/maxloc0_4_r8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_4_r8.lo `test -f 'generated/maxloc0_4_r8.c' || echo '$(srcdir)/'`generated/maxloc0_4_r8.c
+
+maxloc0_8_r8.o: generated/maxloc0_8_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_8_r8.o -MD -MP -MF "$(DEPDIR)/maxloc0_8_r8.Tpo" -c -o maxloc0_8_r8.o `test -f 'generated/maxloc0_8_r8.c' || echo '$(srcdir)/'`generated/maxloc0_8_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_8_r8.Tpo" "$(DEPDIR)/maxloc0_8_r8.Po"; else rm -f "$(DEPDIR)/maxloc0_8_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_8_r8.c' object='maxloc0_8_r8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_8_r8.Po' tmpdepfile='$(DEPDIR)/maxloc0_8_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_8_r8.o `test -f 'generated/maxloc0_8_r8.c' || echo '$(srcdir)/'`generated/maxloc0_8_r8.c
+
+maxloc0_8_r8.obj: generated/maxloc0_8_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_8_r8.obj -MD -MP -MF "$(DEPDIR)/maxloc0_8_r8.Tpo" -c -o maxloc0_8_r8.obj `if test -f 'generated/maxloc0_8_r8.c'; then $(CYGPATH_W) 'generated/maxloc0_8_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc0_8_r8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_8_r8.Tpo" "$(DEPDIR)/maxloc0_8_r8.Po"; else rm -f "$(DEPDIR)/maxloc0_8_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_8_r8.c' object='maxloc0_8_r8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_8_r8.Po' tmpdepfile='$(DEPDIR)/maxloc0_8_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_8_r8.obj `if test -f 'generated/maxloc0_8_r8.c'; then $(CYGPATH_W) 'generated/maxloc0_8_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc0_8_r8.c'; fi`
+
+maxloc0_8_r8.lo: generated/maxloc0_8_r8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc0_8_r8.lo -MD -MP -MF "$(DEPDIR)/maxloc0_8_r8.Tpo" -c -o maxloc0_8_r8.lo `test -f 'generated/maxloc0_8_r8.c' || echo '$(srcdir)/'`generated/maxloc0_8_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc0_8_r8.Tpo" "$(DEPDIR)/maxloc0_8_r8.Plo"; else rm -f "$(DEPDIR)/maxloc0_8_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc0_8_r8.c' object='maxloc0_8_r8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc0_8_r8.Plo' tmpdepfile='$(DEPDIR)/maxloc0_8_r8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc0_8_r8.lo `test -f 'generated/maxloc0_8_r8.c' || echo '$(srcdir)/'`generated/maxloc0_8_r8.c
+
+maxloc1_4_i4.o: generated/maxloc1_4_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_4_i4.o -MD -MP -MF "$(DEPDIR)/maxloc1_4_i4.Tpo" -c -o maxloc1_4_i4.o `test -f 'generated/maxloc1_4_i4.c' || echo '$(srcdir)/'`generated/maxloc1_4_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_4_i4.Tpo" "$(DEPDIR)/maxloc1_4_i4.Po"; else rm -f "$(DEPDIR)/maxloc1_4_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_4_i4.c' object='maxloc1_4_i4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_4_i4.Po' tmpdepfile='$(DEPDIR)/maxloc1_4_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_4_i4.o `test -f 'generated/maxloc1_4_i4.c' || echo '$(srcdir)/'`generated/maxloc1_4_i4.c
+
+maxloc1_4_i4.obj: generated/maxloc1_4_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_4_i4.obj -MD -MP -MF "$(DEPDIR)/maxloc1_4_i4.Tpo" -c -o maxloc1_4_i4.obj `if test -f 'generated/maxloc1_4_i4.c'; then $(CYGPATH_W) 'generated/maxloc1_4_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc1_4_i4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_4_i4.Tpo" "$(DEPDIR)/maxloc1_4_i4.Po"; else rm -f "$(DEPDIR)/maxloc1_4_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_4_i4.c' object='maxloc1_4_i4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_4_i4.Po' tmpdepfile='$(DEPDIR)/maxloc1_4_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_4_i4.obj `if test -f 'generated/maxloc1_4_i4.c'; then $(CYGPATH_W) 'generated/maxloc1_4_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc1_4_i4.c'; fi`
+
+maxloc1_4_i4.lo: generated/maxloc1_4_i4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_4_i4.lo -MD -MP -MF "$(DEPDIR)/maxloc1_4_i4.Tpo" -c -o maxloc1_4_i4.lo `test -f 'generated/maxloc1_4_i4.c' || echo '$(srcdir)/'`generated/maxloc1_4_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_4_i4.Tpo" "$(DEPDIR)/maxloc1_4_i4.Plo"; else rm -f "$(DEPDIR)/maxloc1_4_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_4_i4.c' object='maxloc1_4_i4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_4_i4.Plo' tmpdepfile='$(DEPDIR)/maxloc1_4_i4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_4_i4.lo `test -f 'generated/maxloc1_4_i4.c' || echo '$(srcdir)/'`generated/maxloc1_4_i4.c
+
+maxloc1_8_i4.o: generated/maxloc1_8_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_8_i4.o -MD -MP -MF "$(DEPDIR)/maxloc1_8_i4.Tpo" -c -o maxloc1_8_i4.o `test -f 'generated/maxloc1_8_i4.c' || echo '$(srcdir)/'`generated/maxloc1_8_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_8_i4.Tpo" "$(DEPDIR)/maxloc1_8_i4.Po"; else rm -f "$(DEPDIR)/maxloc1_8_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_8_i4.c' object='maxloc1_8_i4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_8_i4.Po' tmpdepfile='$(DEPDIR)/maxloc1_8_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_8_i4.o `test -f 'generated/maxloc1_8_i4.c' || echo '$(srcdir)/'`generated/maxloc1_8_i4.c
+
+maxloc1_8_i4.obj: generated/maxloc1_8_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_8_i4.obj -MD -MP -MF "$(DEPDIR)/maxloc1_8_i4.Tpo" -c -o maxloc1_8_i4.obj `if test -f 'generated/maxloc1_8_i4.c'; then $(CYGPATH_W) 'generated/maxloc1_8_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc1_8_i4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_8_i4.Tpo" "$(DEPDIR)/maxloc1_8_i4.Po"; else rm -f "$(DEPDIR)/maxloc1_8_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_8_i4.c' object='maxloc1_8_i4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_8_i4.Po' tmpdepfile='$(DEPDIR)/maxloc1_8_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_8_i4.obj `if test -f 'generated/maxloc1_8_i4.c'; then $(CYGPATH_W) 'generated/maxloc1_8_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc1_8_i4.c'; fi`
+
+maxloc1_8_i4.lo: generated/maxloc1_8_i4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_8_i4.lo -MD -MP -MF "$(DEPDIR)/maxloc1_8_i4.Tpo" -c -o maxloc1_8_i4.lo `test -f 'generated/maxloc1_8_i4.c' || echo '$(srcdir)/'`generated/maxloc1_8_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_8_i4.Tpo" "$(DEPDIR)/maxloc1_8_i4.Plo"; else rm -f "$(DEPDIR)/maxloc1_8_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_8_i4.c' object='maxloc1_8_i4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_8_i4.Plo' tmpdepfile='$(DEPDIR)/maxloc1_8_i4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_8_i4.lo `test -f 'generated/maxloc1_8_i4.c' || echo '$(srcdir)/'`generated/maxloc1_8_i4.c
+
+maxloc1_4_i8.o: generated/maxloc1_4_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_4_i8.o -MD -MP -MF "$(DEPDIR)/maxloc1_4_i8.Tpo" -c -o maxloc1_4_i8.o `test -f 'generated/maxloc1_4_i8.c' || echo '$(srcdir)/'`generated/maxloc1_4_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_4_i8.Tpo" "$(DEPDIR)/maxloc1_4_i8.Po"; else rm -f "$(DEPDIR)/maxloc1_4_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_4_i8.c' object='maxloc1_4_i8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_4_i8.Po' tmpdepfile='$(DEPDIR)/maxloc1_4_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_4_i8.o `test -f 'generated/maxloc1_4_i8.c' || echo '$(srcdir)/'`generated/maxloc1_4_i8.c
+
+maxloc1_4_i8.obj: generated/maxloc1_4_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_4_i8.obj -MD -MP -MF "$(DEPDIR)/maxloc1_4_i8.Tpo" -c -o maxloc1_4_i8.obj `if test -f 'generated/maxloc1_4_i8.c'; then $(CYGPATH_W) 'generated/maxloc1_4_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc1_4_i8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_4_i8.Tpo" "$(DEPDIR)/maxloc1_4_i8.Po"; else rm -f "$(DEPDIR)/maxloc1_4_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_4_i8.c' object='maxloc1_4_i8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_4_i8.Po' tmpdepfile='$(DEPDIR)/maxloc1_4_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_4_i8.obj `if test -f 'generated/maxloc1_4_i8.c'; then $(CYGPATH_W) 'generated/maxloc1_4_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc1_4_i8.c'; fi`
+
+maxloc1_4_i8.lo: generated/maxloc1_4_i8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_4_i8.lo -MD -MP -MF "$(DEPDIR)/maxloc1_4_i8.Tpo" -c -o maxloc1_4_i8.lo `test -f 'generated/maxloc1_4_i8.c' || echo '$(srcdir)/'`generated/maxloc1_4_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_4_i8.Tpo" "$(DEPDIR)/maxloc1_4_i8.Plo"; else rm -f "$(DEPDIR)/maxloc1_4_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_4_i8.c' object='maxloc1_4_i8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_4_i8.Plo' tmpdepfile='$(DEPDIR)/maxloc1_4_i8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_4_i8.lo `test -f 'generated/maxloc1_4_i8.c' || echo '$(srcdir)/'`generated/maxloc1_4_i8.c
+
+maxloc1_8_i8.o: generated/maxloc1_8_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_8_i8.o -MD -MP -MF "$(DEPDIR)/maxloc1_8_i8.Tpo" -c -o maxloc1_8_i8.o `test -f 'generated/maxloc1_8_i8.c' || echo '$(srcdir)/'`generated/maxloc1_8_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_8_i8.Tpo" "$(DEPDIR)/maxloc1_8_i8.Po"; else rm -f "$(DEPDIR)/maxloc1_8_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_8_i8.c' object='maxloc1_8_i8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_8_i8.Po' tmpdepfile='$(DEPDIR)/maxloc1_8_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_8_i8.o `test -f 'generated/maxloc1_8_i8.c' || echo '$(srcdir)/'`generated/maxloc1_8_i8.c
+
+maxloc1_8_i8.obj: generated/maxloc1_8_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_8_i8.obj -MD -MP -MF "$(DEPDIR)/maxloc1_8_i8.Tpo" -c -o maxloc1_8_i8.obj `if test -f 'generated/maxloc1_8_i8.c'; then $(CYGPATH_W) 'generated/maxloc1_8_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc1_8_i8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_8_i8.Tpo" "$(DEPDIR)/maxloc1_8_i8.Po"; else rm -f "$(DEPDIR)/maxloc1_8_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_8_i8.c' object='maxloc1_8_i8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_8_i8.Po' tmpdepfile='$(DEPDIR)/maxloc1_8_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_8_i8.obj `if test -f 'generated/maxloc1_8_i8.c'; then $(CYGPATH_W) 'generated/maxloc1_8_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc1_8_i8.c'; fi`
+
+maxloc1_8_i8.lo: generated/maxloc1_8_i8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_8_i8.lo -MD -MP -MF "$(DEPDIR)/maxloc1_8_i8.Tpo" -c -o maxloc1_8_i8.lo `test -f 'generated/maxloc1_8_i8.c' || echo '$(srcdir)/'`generated/maxloc1_8_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_8_i8.Tpo" "$(DEPDIR)/maxloc1_8_i8.Plo"; else rm -f "$(DEPDIR)/maxloc1_8_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_8_i8.c' object='maxloc1_8_i8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_8_i8.Plo' tmpdepfile='$(DEPDIR)/maxloc1_8_i8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_8_i8.lo `test -f 'generated/maxloc1_8_i8.c' || echo '$(srcdir)/'`generated/maxloc1_8_i8.c
+
+maxloc1_4_r4.o: generated/maxloc1_4_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_4_r4.o -MD -MP -MF "$(DEPDIR)/maxloc1_4_r4.Tpo" -c -o maxloc1_4_r4.o `test -f 'generated/maxloc1_4_r4.c' || echo '$(srcdir)/'`generated/maxloc1_4_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_4_r4.Tpo" "$(DEPDIR)/maxloc1_4_r4.Po"; else rm -f "$(DEPDIR)/maxloc1_4_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_4_r4.c' object='maxloc1_4_r4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_4_r4.Po' tmpdepfile='$(DEPDIR)/maxloc1_4_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_4_r4.o `test -f 'generated/maxloc1_4_r4.c' || echo '$(srcdir)/'`generated/maxloc1_4_r4.c
+
+maxloc1_4_r4.obj: generated/maxloc1_4_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_4_r4.obj -MD -MP -MF "$(DEPDIR)/maxloc1_4_r4.Tpo" -c -o maxloc1_4_r4.obj `if test -f 'generated/maxloc1_4_r4.c'; then $(CYGPATH_W) 'generated/maxloc1_4_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc1_4_r4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_4_r4.Tpo" "$(DEPDIR)/maxloc1_4_r4.Po"; else rm -f "$(DEPDIR)/maxloc1_4_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_4_r4.c' object='maxloc1_4_r4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_4_r4.Po' tmpdepfile='$(DEPDIR)/maxloc1_4_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_4_r4.obj `if test -f 'generated/maxloc1_4_r4.c'; then $(CYGPATH_W) 'generated/maxloc1_4_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc1_4_r4.c'; fi`
+
+maxloc1_4_r4.lo: generated/maxloc1_4_r4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_4_r4.lo -MD -MP -MF "$(DEPDIR)/maxloc1_4_r4.Tpo" -c -o maxloc1_4_r4.lo `test -f 'generated/maxloc1_4_r4.c' || echo '$(srcdir)/'`generated/maxloc1_4_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_4_r4.Tpo" "$(DEPDIR)/maxloc1_4_r4.Plo"; else rm -f "$(DEPDIR)/maxloc1_4_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_4_r4.c' object='maxloc1_4_r4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_4_r4.Plo' tmpdepfile='$(DEPDIR)/maxloc1_4_r4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_4_r4.lo `test -f 'generated/maxloc1_4_r4.c' || echo '$(srcdir)/'`generated/maxloc1_4_r4.c
+
+maxloc1_8_r4.o: generated/maxloc1_8_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_8_r4.o -MD -MP -MF "$(DEPDIR)/maxloc1_8_r4.Tpo" -c -o maxloc1_8_r4.o `test -f 'generated/maxloc1_8_r4.c' || echo '$(srcdir)/'`generated/maxloc1_8_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_8_r4.Tpo" "$(DEPDIR)/maxloc1_8_r4.Po"; else rm -f "$(DEPDIR)/maxloc1_8_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_8_r4.c' object='maxloc1_8_r4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_8_r4.Po' tmpdepfile='$(DEPDIR)/maxloc1_8_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_8_r4.o `test -f 'generated/maxloc1_8_r4.c' || echo '$(srcdir)/'`generated/maxloc1_8_r4.c
+
+maxloc1_8_r4.obj: generated/maxloc1_8_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_8_r4.obj -MD -MP -MF "$(DEPDIR)/maxloc1_8_r4.Tpo" -c -o maxloc1_8_r4.obj `if test -f 'generated/maxloc1_8_r4.c'; then $(CYGPATH_W) 'generated/maxloc1_8_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc1_8_r4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_8_r4.Tpo" "$(DEPDIR)/maxloc1_8_r4.Po"; else rm -f "$(DEPDIR)/maxloc1_8_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_8_r4.c' object='maxloc1_8_r4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_8_r4.Po' tmpdepfile='$(DEPDIR)/maxloc1_8_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_8_r4.obj `if test -f 'generated/maxloc1_8_r4.c'; then $(CYGPATH_W) 'generated/maxloc1_8_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc1_8_r4.c'; fi`
+
+maxloc1_8_r4.lo: generated/maxloc1_8_r4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_8_r4.lo -MD -MP -MF "$(DEPDIR)/maxloc1_8_r4.Tpo" -c -o maxloc1_8_r4.lo `test -f 'generated/maxloc1_8_r4.c' || echo '$(srcdir)/'`generated/maxloc1_8_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_8_r4.Tpo" "$(DEPDIR)/maxloc1_8_r4.Plo"; else rm -f "$(DEPDIR)/maxloc1_8_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_8_r4.c' object='maxloc1_8_r4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_8_r4.Plo' tmpdepfile='$(DEPDIR)/maxloc1_8_r4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_8_r4.lo `test -f 'generated/maxloc1_8_r4.c' || echo '$(srcdir)/'`generated/maxloc1_8_r4.c
+
+maxloc1_4_r8.o: generated/maxloc1_4_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_4_r8.o -MD -MP -MF "$(DEPDIR)/maxloc1_4_r8.Tpo" -c -o maxloc1_4_r8.o `test -f 'generated/maxloc1_4_r8.c' || echo '$(srcdir)/'`generated/maxloc1_4_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_4_r8.Tpo" "$(DEPDIR)/maxloc1_4_r8.Po"; else rm -f "$(DEPDIR)/maxloc1_4_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_4_r8.c' object='maxloc1_4_r8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_4_r8.Po' tmpdepfile='$(DEPDIR)/maxloc1_4_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_4_r8.o `test -f 'generated/maxloc1_4_r8.c' || echo '$(srcdir)/'`generated/maxloc1_4_r8.c
+
+maxloc1_4_r8.obj: generated/maxloc1_4_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_4_r8.obj -MD -MP -MF "$(DEPDIR)/maxloc1_4_r8.Tpo" -c -o maxloc1_4_r8.obj `if test -f 'generated/maxloc1_4_r8.c'; then $(CYGPATH_W) 'generated/maxloc1_4_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc1_4_r8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_4_r8.Tpo" "$(DEPDIR)/maxloc1_4_r8.Po"; else rm -f "$(DEPDIR)/maxloc1_4_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_4_r8.c' object='maxloc1_4_r8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_4_r8.Po' tmpdepfile='$(DEPDIR)/maxloc1_4_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_4_r8.obj `if test -f 'generated/maxloc1_4_r8.c'; then $(CYGPATH_W) 'generated/maxloc1_4_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc1_4_r8.c'; fi`
+
+maxloc1_4_r8.lo: generated/maxloc1_4_r8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_4_r8.lo -MD -MP -MF "$(DEPDIR)/maxloc1_4_r8.Tpo" -c -o maxloc1_4_r8.lo `test -f 'generated/maxloc1_4_r8.c' || echo '$(srcdir)/'`generated/maxloc1_4_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_4_r8.Tpo" "$(DEPDIR)/maxloc1_4_r8.Plo"; else rm -f "$(DEPDIR)/maxloc1_4_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_4_r8.c' object='maxloc1_4_r8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_4_r8.Plo' tmpdepfile='$(DEPDIR)/maxloc1_4_r8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_4_r8.lo `test -f 'generated/maxloc1_4_r8.c' || echo '$(srcdir)/'`generated/maxloc1_4_r8.c
+
+maxloc1_8_r8.o: generated/maxloc1_8_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_8_r8.o -MD -MP -MF "$(DEPDIR)/maxloc1_8_r8.Tpo" -c -o maxloc1_8_r8.o `test -f 'generated/maxloc1_8_r8.c' || echo '$(srcdir)/'`generated/maxloc1_8_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_8_r8.Tpo" "$(DEPDIR)/maxloc1_8_r8.Po"; else rm -f "$(DEPDIR)/maxloc1_8_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_8_r8.c' object='maxloc1_8_r8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_8_r8.Po' tmpdepfile='$(DEPDIR)/maxloc1_8_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_8_r8.o `test -f 'generated/maxloc1_8_r8.c' || echo '$(srcdir)/'`generated/maxloc1_8_r8.c
+
+maxloc1_8_r8.obj: generated/maxloc1_8_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_8_r8.obj -MD -MP -MF "$(DEPDIR)/maxloc1_8_r8.Tpo" -c -o maxloc1_8_r8.obj `if test -f 'generated/maxloc1_8_r8.c'; then $(CYGPATH_W) 'generated/maxloc1_8_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc1_8_r8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_8_r8.Tpo" "$(DEPDIR)/maxloc1_8_r8.Po"; else rm -f "$(DEPDIR)/maxloc1_8_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_8_r8.c' object='maxloc1_8_r8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_8_r8.Po' tmpdepfile='$(DEPDIR)/maxloc1_8_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_8_r8.obj `if test -f 'generated/maxloc1_8_r8.c'; then $(CYGPATH_W) 'generated/maxloc1_8_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxloc1_8_r8.c'; fi`
+
+maxloc1_8_r8.lo: generated/maxloc1_8_r8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxloc1_8_r8.lo -MD -MP -MF "$(DEPDIR)/maxloc1_8_r8.Tpo" -c -o maxloc1_8_r8.lo `test -f 'generated/maxloc1_8_r8.c' || echo '$(srcdir)/'`generated/maxloc1_8_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxloc1_8_r8.Tpo" "$(DEPDIR)/maxloc1_8_r8.Plo"; else rm -f "$(DEPDIR)/maxloc1_8_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxloc1_8_r8.c' object='maxloc1_8_r8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxloc1_8_r8.Plo' tmpdepfile='$(DEPDIR)/maxloc1_8_r8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxloc1_8_r8.lo `test -f 'generated/maxloc1_8_r8.c' || echo '$(srcdir)/'`generated/maxloc1_8_r8.c
+
+maxval_i4.o: generated/maxval_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxval_i4.o -MD -MP -MF "$(DEPDIR)/maxval_i4.Tpo" -c -o maxval_i4.o `test -f 'generated/maxval_i4.c' || echo '$(srcdir)/'`generated/maxval_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxval_i4.Tpo" "$(DEPDIR)/maxval_i4.Po"; else rm -f "$(DEPDIR)/maxval_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxval_i4.c' object='maxval_i4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxval_i4.Po' tmpdepfile='$(DEPDIR)/maxval_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxval_i4.o `test -f 'generated/maxval_i4.c' || echo '$(srcdir)/'`generated/maxval_i4.c
+
+maxval_i4.obj: generated/maxval_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxval_i4.obj -MD -MP -MF "$(DEPDIR)/maxval_i4.Tpo" -c -o maxval_i4.obj `if test -f 'generated/maxval_i4.c'; then $(CYGPATH_W) 'generated/maxval_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxval_i4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxval_i4.Tpo" "$(DEPDIR)/maxval_i4.Po"; else rm -f "$(DEPDIR)/maxval_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxval_i4.c' object='maxval_i4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxval_i4.Po' tmpdepfile='$(DEPDIR)/maxval_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxval_i4.obj `if test -f 'generated/maxval_i4.c'; then $(CYGPATH_W) 'generated/maxval_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxval_i4.c'; fi`
+
+maxval_i4.lo: generated/maxval_i4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxval_i4.lo -MD -MP -MF "$(DEPDIR)/maxval_i4.Tpo" -c -o maxval_i4.lo `test -f 'generated/maxval_i4.c' || echo '$(srcdir)/'`generated/maxval_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxval_i4.Tpo" "$(DEPDIR)/maxval_i4.Plo"; else rm -f "$(DEPDIR)/maxval_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxval_i4.c' object='maxval_i4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxval_i4.Plo' tmpdepfile='$(DEPDIR)/maxval_i4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxval_i4.lo `test -f 'generated/maxval_i4.c' || echo '$(srcdir)/'`generated/maxval_i4.c
+
+maxval_i8.o: generated/maxval_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxval_i8.o -MD -MP -MF "$(DEPDIR)/maxval_i8.Tpo" -c -o maxval_i8.o `test -f 'generated/maxval_i8.c' || echo '$(srcdir)/'`generated/maxval_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxval_i8.Tpo" "$(DEPDIR)/maxval_i8.Po"; else rm -f "$(DEPDIR)/maxval_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxval_i8.c' object='maxval_i8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxval_i8.Po' tmpdepfile='$(DEPDIR)/maxval_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxval_i8.o `test -f 'generated/maxval_i8.c' || echo '$(srcdir)/'`generated/maxval_i8.c
+
+maxval_i8.obj: generated/maxval_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxval_i8.obj -MD -MP -MF "$(DEPDIR)/maxval_i8.Tpo" -c -o maxval_i8.obj `if test -f 'generated/maxval_i8.c'; then $(CYGPATH_W) 'generated/maxval_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxval_i8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxval_i8.Tpo" "$(DEPDIR)/maxval_i8.Po"; else rm -f "$(DEPDIR)/maxval_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxval_i8.c' object='maxval_i8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxval_i8.Po' tmpdepfile='$(DEPDIR)/maxval_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxval_i8.obj `if test -f 'generated/maxval_i8.c'; then $(CYGPATH_W) 'generated/maxval_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxval_i8.c'; fi`
+
+maxval_i8.lo: generated/maxval_i8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxval_i8.lo -MD -MP -MF "$(DEPDIR)/maxval_i8.Tpo" -c -o maxval_i8.lo `test -f 'generated/maxval_i8.c' || echo '$(srcdir)/'`generated/maxval_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxval_i8.Tpo" "$(DEPDIR)/maxval_i8.Plo"; else rm -f "$(DEPDIR)/maxval_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxval_i8.c' object='maxval_i8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxval_i8.Plo' tmpdepfile='$(DEPDIR)/maxval_i8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxval_i8.lo `test -f 'generated/maxval_i8.c' || echo '$(srcdir)/'`generated/maxval_i8.c
+
+maxval_r4.o: generated/maxval_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxval_r4.o -MD -MP -MF "$(DEPDIR)/maxval_r4.Tpo" -c -o maxval_r4.o `test -f 'generated/maxval_r4.c' || echo '$(srcdir)/'`generated/maxval_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxval_r4.Tpo" "$(DEPDIR)/maxval_r4.Po"; else rm -f "$(DEPDIR)/maxval_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxval_r4.c' object='maxval_r4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxval_r4.Po' tmpdepfile='$(DEPDIR)/maxval_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxval_r4.o `test -f 'generated/maxval_r4.c' || echo '$(srcdir)/'`generated/maxval_r4.c
+
+maxval_r4.obj: generated/maxval_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxval_r4.obj -MD -MP -MF "$(DEPDIR)/maxval_r4.Tpo" -c -o maxval_r4.obj `if test -f 'generated/maxval_r4.c'; then $(CYGPATH_W) 'generated/maxval_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxval_r4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxval_r4.Tpo" "$(DEPDIR)/maxval_r4.Po"; else rm -f "$(DEPDIR)/maxval_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxval_r4.c' object='maxval_r4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxval_r4.Po' tmpdepfile='$(DEPDIR)/maxval_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxval_r4.obj `if test -f 'generated/maxval_r4.c'; then $(CYGPATH_W) 'generated/maxval_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxval_r4.c'; fi`
+
+maxval_r4.lo: generated/maxval_r4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxval_r4.lo -MD -MP -MF "$(DEPDIR)/maxval_r4.Tpo" -c -o maxval_r4.lo `test -f 'generated/maxval_r4.c' || echo '$(srcdir)/'`generated/maxval_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxval_r4.Tpo" "$(DEPDIR)/maxval_r4.Plo"; else rm -f "$(DEPDIR)/maxval_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxval_r4.c' object='maxval_r4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxval_r4.Plo' tmpdepfile='$(DEPDIR)/maxval_r4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxval_r4.lo `test -f 'generated/maxval_r4.c' || echo '$(srcdir)/'`generated/maxval_r4.c
+
+maxval_r8.o: generated/maxval_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxval_r8.o -MD -MP -MF "$(DEPDIR)/maxval_r8.Tpo" -c -o maxval_r8.o `test -f 'generated/maxval_r8.c' || echo '$(srcdir)/'`generated/maxval_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxval_r8.Tpo" "$(DEPDIR)/maxval_r8.Po"; else rm -f "$(DEPDIR)/maxval_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxval_r8.c' object='maxval_r8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxval_r8.Po' tmpdepfile='$(DEPDIR)/maxval_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxval_r8.o `test -f 'generated/maxval_r8.c' || echo '$(srcdir)/'`generated/maxval_r8.c
+
+maxval_r8.obj: generated/maxval_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxval_r8.obj -MD -MP -MF "$(DEPDIR)/maxval_r8.Tpo" -c -o maxval_r8.obj `if test -f 'generated/maxval_r8.c'; then $(CYGPATH_W) 'generated/maxval_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxval_r8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxval_r8.Tpo" "$(DEPDIR)/maxval_r8.Po"; else rm -f "$(DEPDIR)/maxval_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxval_r8.c' object='maxval_r8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxval_r8.Po' tmpdepfile='$(DEPDIR)/maxval_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxval_r8.obj `if test -f 'generated/maxval_r8.c'; then $(CYGPATH_W) 'generated/maxval_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/maxval_r8.c'; fi`
+
+maxval_r8.lo: generated/maxval_r8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maxval_r8.lo -MD -MP -MF "$(DEPDIR)/maxval_r8.Tpo" -c -o maxval_r8.lo `test -f 'generated/maxval_r8.c' || echo '$(srcdir)/'`generated/maxval_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/maxval_r8.Tpo" "$(DEPDIR)/maxval_r8.Plo"; else rm -f "$(DEPDIR)/maxval_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/maxval_r8.c' object='maxval_r8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/maxval_r8.Plo' tmpdepfile='$(DEPDIR)/maxval_r8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o maxval_r8.lo `test -f 'generated/maxval_r8.c' || echo '$(srcdir)/'`generated/maxval_r8.c
+
+minloc0_4_i4.o: generated/minloc0_4_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_4_i4.o -MD -MP -MF "$(DEPDIR)/minloc0_4_i4.Tpo" -c -o minloc0_4_i4.o `test -f 'generated/minloc0_4_i4.c' || echo '$(srcdir)/'`generated/minloc0_4_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_4_i4.Tpo" "$(DEPDIR)/minloc0_4_i4.Po"; else rm -f "$(DEPDIR)/minloc0_4_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_4_i4.c' object='minloc0_4_i4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_4_i4.Po' tmpdepfile='$(DEPDIR)/minloc0_4_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_4_i4.o `test -f 'generated/minloc0_4_i4.c' || echo '$(srcdir)/'`generated/minloc0_4_i4.c
+
+minloc0_4_i4.obj: generated/minloc0_4_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_4_i4.obj -MD -MP -MF "$(DEPDIR)/minloc0_4_i4.Tpo" -c -o minloc0_4_i4.obj `if test -f 'generated/minloc0_4_i4.c'; then $(CYGPATH_W) 'generated/minloc0_4_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc0_4_i4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_4_i4.Tpo" "$(DEPDIR)/minloc0_4_i4.Po"; else rm -f "$(DEPDIR)/minloc0_4_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_4_i4.c' object='minloc0_4_i4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_4_i4.Po' tmpdepfile='$(DEPDIR)/minloc0_4_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_4_i4.obj `if test -f 'generated/minloc0_4_i4.c'; then $(CYGPATH_W) 'generated/minloc0_4_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc0_4_i4.c'; fi`
+
+minloc0_4_i4.lo: generated/minloc0_4_i4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_4_i4.lo -MD -MP -MF "$(DEPDIR)/minloc0_4_i4.Tpo" -c -o minloc0_4_i4.lo `test -f 'generated/minloc0_4_i4.c' || echo '$(srcdir)/'`generated/minloc0_4_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_4_i4.Tpo" "$(DEPDIR)/minloc0_4_i4.Plo"; else rm -f "$(DEPDIR)/minloc0_4_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_4_i4.c' object='minloc0_4_i4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_4_i4.Plo' tmpdepfile='$(DEPDIR)/minloc0_4_i4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_4_i4.lo `test -f 'generated/minloc0_4_i4.c' || echo '$(srcdir)/'`generated/minloc0_4_i4.c
+
+minloc0_8_i4.o: generated/minloc0_8_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_8_i4.o -MD -MP -MF "$(DEPDIR)/minloc0_8_i4.Tpo" -c -o minloc0_8_i4.o `test -f 'generated/minloc0_8_i4.c' || echo '$(srcdir)/'`generated/minloc0_8_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_8_i4.Tpo" "$(DEPDIR)/minloc0_8_i4.Po"; else rm -f "$(DEPDIR)/minloc0_8_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_8_i4.c' object='minloc0_8_i4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_8_i4.Po' tmpdepfile='$(DEPDIR)/minloc0_8_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_8_i4.o `test -f 'generated/minloc0_8_i4.c' || echo '$(srcdir)/'`generated/minloc0_8_i4.c
+
+minloc0_8_i4.obj: generated/minloc0_8_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_8_i4.obj -MD -MP -MF "$(DEPDIR)/minloc0_8_i4.Tpo" -c -o minloc0_8_i4.obj `if test -f 'generated/minloc0_8_i4.c'; then $(CYGPATH_W) 'generated/minloc0_8_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc0_8_i4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_8_i4.Tpo" "$(DEPDIR)/minloc0_8_i4.Po"; else rm -f "$(DEPDIR)/minloc0_8_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_8_i4.c' object='minloc0_8_i4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_8_i4.Po' tmpdepfile='$(DEPDIR)/minloc0_8_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_8_i4.obj `if test -f 'generated/minloc0_8_i4.c'; then $(CYGPATH_W) 'generated/minloc0_8_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc0_8_i4.c'; fi`
+
+minloc0_8_i4.lo: generated/minloc0_8_i4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_8_i4.lo -MD -MP -MF "$(DEPDIR)/minloc0_8_i4.Tpo" -c -o minloc0_8_i4.lo `test -f 'generated/minloc0_8_i4.c' || echo '$(srcdir)/'`generated/minloc0_8_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_8_i4.Tpo" "$(DEPDIR)/minloc0_8_i4.Plo"; else rm -f "$(DEPDIR)/minloc0_8_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_8_i4.c' object='minloc0_8_i4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_8_i4.Plo' tmpdepfile='$(DEPDIR)/minloc0_8_i4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_8_i4.lo `test -f 'generated/minloc0_8_i4.c' || echo '$(srcdir)/'`generated/minloc0_8_i4.c
+
+minloc0_4_i8.o: generated/minloc0_4_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_4_i8.o -MD -MP -MF "$(DEPDIR)/minloc0_4_i8.Tpo" -c -o minloc0_4_i8.o `test -f 'generated/minloc0_4_i8.c' || echo '$(srcdir)/'`generated/minloc0_4_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_4_i8.Tpo" "$(DEPDIR)/minloc0_4_i8.Po"; else rm -f "$(DEPDIR)/minloc0_4_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_4_i8.c' object='minloc0_4_i8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_4_i8.Po' tmpdepfile='$(DEPDIR)/minloc0_4_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_4_i8.o `test -f 'generated/minloc0_4_i8.c' || echo '$(srcdir)/'`generated/minloc0_4_i8.c
+
+minloc0_4_i8.obj: generated/minloc0_4_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_4_i8.obj -MD -MP -MF "$(DEPDIR)/minloc0_4_i8.Tpo" -c -o minloc0_4_i8.obj `if test -f 'generated/minloc0_4_i8.c'; then $(CYGPATH_W) 'generated/minloc0_4_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc0_4_i8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_4_i8.Tpo" "$(DEPDIR)/minloc0_4_i8.Po"; else rm -f "$(DEPDIR)/minloc0_4_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_4_i8.c' object='minloc0_4_i8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_4_i8.Po' tmpdepfile='$(DEPDIR)/minloc0_4_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_4_i8.obj `if test -f 'generated/minloc0_4_i8.c'; then $(CYGPATH_W) 'generated/minloc0_4_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc0_4_i8.c'; fi`
+
+minloc0_4_i8.lo: generated/minloc0_4_i8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_4_i8.lo -MD -MP -MF "$(DEPDIR)/minloc0_4_i8.Tpo" -c -o minloc0_4_i8.lo `test -f 'generated/minloc0_4_i8.c' || echo '$(srcdir)/'`generated/minloc0_4_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_4_i8.Tpo" "$(DEPDIR)/minloc0_4_i8.Plo"; else rm -f "$(DEPDIR)/minloc0_4_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_4_i8.c' object='minloc0_4_i8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_4_i8.Plo' tmpdepfile='$(DEPDIR)/minloc0_4_i8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_4_i8.lo `test -f 'generated/minloc0_4_i8.c' || echo '$(srcdir)/'`generated/minloc0_4_i8.c
+
+minloc0_8_i8.o: generated/minloc0_8_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_8_i8.o -MD -MP -MF "$(DEPDIR)/minloc0_8_i8.Tpo" -c -o minloc0_8_i8.o `test -f 'generated/minloc0_8_i8.c' || echo '$(srcdir)/'`generated/minloc0_8_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_8_i8.Tpo" "$(DEPDIR)/minloc0_8_i8.Po"; else rm -f "$(DEPDIR)/minloc0_8_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_8_i8.c' object='minloc0_8_i8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_8_i8.Po' tmpdepfile='$(DEPDIR)/minloc0_8_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_8_i8.o `test -f 'generated/minloc0_8_i8.c' || echo '$(srcdir)/'`generated/minloc0_8_i8.c
+
+minloc0_8_i8.obj: generated/minloc0_8_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_8_i8.obj -MD -MP -MF "$(DEPDIR)/minloc0_8_i8.Tpo" -c -o minloc0_8_i8.obj `if test -f 'generated/minloc0_8_i8.c'; then $(CYGPATH_W) 'generated/minloc0_8_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc0_8_i8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_8_i8.Tpo" "$(DEPDIR)/minloc0_8_i8.Po"; else rm -f "$(DEPDIR)/minloc0_8_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_8_i8.c' object='minloc0_8_i8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_8_i8.Po' tmpdepfile='$(DEPDIR)/minloc0_8_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_8_i8.obj `if test -f 'generated/minloc0_8_i8.c'; then $(CYGPATH_W) 'generated/minloc0_8_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc0_8_i8.c'; fi`
+
+minloc0_8_i8.lo: generated/minloc0_8_i8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_8_i8.lo -MD -MP -MF "$(DEPDIR)/minloc0_8_i8.Tpo" -c -o minloc0_8_i8.lo `test -f 'generated/minloc0_8_i8.c' || echo '$(srcdir)/'`generated/minloc0_8_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_8_i8.Tpo" "$(DEPDIR)/minloc0_8_i8.Plo"; else rm -f "$(DEPDIR)/minloc0_8_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_8_i8.c' object='minloc0_8_i8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_8_i8.Plo' tmpdepfile='$(DEPDIR)/minloc0_8_i8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_8_i8.lo `test -f 'generated/minloc0_8_i8.c' || echo '$(srcdir)/'`generated/minloc0_8_i8.c
+
+minloc0_4_r4.o: generated/minloc0_4_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_4_r4.o -MD -MP -MF "$(DEPDIR)/minloc0_4_r4.Tpo" -c -o minloc0_4_r4.o `test -f 'generated/minloc0_4_r4.c' || echo '$(srcdir)/'`generated/minloc0_4_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_4_r4.Tpo" "$(DEPDIR)/minloc0_4_r4.Po"; else rm -f "$(DEPDIR)/minloc0_4_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_4_r4.c' object='minloc0_4_r4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_4_r4.Po' tmpdepfile='$(DEPDIR)/minloc0_4_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_4_r4.o `test -f 'generated/minloc0_4_r4.c' || echo '$(srcdir)/'`generated/minloc0_4_r4.c
+
+minloc0_4_r4.obj: generated/minloc0_4_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_4_r4.obj -MD -MP -MF "$(DEPDIR)/minloc0_4_r4.Tpo" -c -o minloc0_4_r4.obj `if test -f 'generated/minloc0_4_r4.c'; then $(CYGPATH_W) 'generated/minloc0_4_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc0_4_r4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_4_r4.Tpo" "$(DEPDIR)/minloc0_4_r4.Po"; else rm -f "$(DEPDIR)/minloc0_4_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_4_r4.c' object='minloc0_4_r4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_4_r4.Po' tmpdepfile='$(DEPDIR)/minloc0_4_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_4_r4.obj `if test -f 'generated/minloc0_4_r4.c'; then $(CYGPATH_W) 'generated/minloc0_4_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc0_4_r4.c'; fi`
+
+minloc0_4_r4.lo: generated/minloc0_4_r4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_4_r4.lo -MD -MP -MF "$(DEPDIR)/minloc0_4_r4.Tpo" -c -o minloc0_4_r4.lo `test -f 'generated/minloc0_4_r4.c' || echo '$(srcdir)/'`generated/minloc0_4_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_4_r4.Tpo" "$(DEPDIR)/minloc0_4_r4.Plo"; else rm -f "$(DEPDIR)/minloc0_4_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_4_r4.c' object='minloc0_4_r4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_4_r4.Plo' tmpdepfile='$(DEPDIR)/minloc0_4_r4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_4_r4.lo `test -f 'generated/minloc0_4_r4.c' || echo '$(srcdir)/'`generated/minloc0_4_r4.c
+
+minloc0_8_r4.o: generated/minloc0_8_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_8_r4.o -MD -MP -MF "$(DEPDIR)/minloc0_8_r4.Tpo" -c -o minloc0_8_r4.o `test -f 'generated/minloc0_8_r4.c' || echo '$(srcdir)/'`generated/minloc0_8_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_8_r4.Tpo" "$(DEPDIR)/minloc0_8_r4.Po"; else rm -f "$(DEPDIR)/minloc0_8_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_8_r4.c' object='minloc0_8_r4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_8_r4.Po' tmpdepfile='$(DEPDIR)/minloc0_8_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_8_r4.o `test -f 'generated/minloc0_8_r4.c' || echo '$(srcdir)/'`generated/minloc0_8_r4.c
+
+minloc0_8_r4.obj: generated/minloc0_8_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_8_r4.obj -MD -MP -MF "$(DEPDIR)/minloc0_8_r4.Tpo" -c -o minloc0_8_r4.obj `if test -f 'generated/minloc0_8_r4.c'; then $(CYGPATH_W) 'generated/minloc0_8_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc0_8_r4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_8_r4.Tpo" "$(DEPDIR)/minloc0_8_r4.Po"; else rm -f "$(DEPDIR)/minloc0_8_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_8_r4.c' object='minloc0_8_r4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_8_r4.Po' tmpdepfile='$(DEPDIR)/minloc0_8_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_8_r4.obj `if test -f 'generated/minloc0_8_r4.c'; then $(CYGPATH_W) 'generated/minloc0_8_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc0_8_r4.c'; fi`
+
+minloc0_8_r4.lo: generated/minloc0_8_r4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_8_r4.lo -MD -MP -MF "$(DEPDIR)/minloc0_8_r4.Tpo" -c -o minloc0_8_r4.lo `test -f 'generated/minloc0_8_r4.c' || echo '$(srcdir)/'`generated/minloc0_8_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_8_r4.Tpo" "$(DEPDIR)/minloc0_8_r4.Plo"; else rm -f "$(DEPDIR)/minloc0_8_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_8_r4.c' object='minloc0_8_r4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_8_r4.Plo' tmpdepfile='$(DEPDIR)/minloc0_8_r4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_8_r4.lo `test -f 'generated/minloc0_8_r4.c' || echo '$(srcdir)/'`generated/minloc0_8_r4.c
+
+minloc0_4_r8.o: generated/minloc0_4_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_4_r8.o -MD -MP -MF "$(DEPDIR)/minloc0_4_r8.Tpo" -c -o minloc0_4_r8.o `test -f 'generated/minloc0_4_r8.c' || echo '$(srcdir)/'`generated/minloc0_4_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_4_r8.Tpo" "$(DEPDIR)/minloc0_4_r8.Po"; else rm -f "$(DEPDIR)/minloc0_4_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_4_r8.c' object='minloc0_4_r8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_4_r8.Po' tmpdepfile='$(DEPDIR)/minloc0_4_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_4_r8.o `test -f 'generated/minloc0_4_r8.c' || echo '$(srcdir)/'`generated/minloc0_4_r8.c
+
+minloc0_4_r8.obj: generated/minloc0_4_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_4_r8.obj -MD -MP -MF "$(DEPDIR)/minloc0_4_r8.Tpo" -c -o minloc0_4_r8.obj `if test -f 'generated/minloc0_4_r8.c'; then $(CYGPATH_W) 'generated/minloc0_4_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc0_4_r8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_4_r8.Tpo" "$(DEPDIR)/minloc0_4_r8.Po"; else rm -f "$(DEPDIR)/minloc0_4_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_4_r8.c' object='minloc0_4_r8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_4_r8.Po' tmpdepfile='$(DEPDIR)/minloc0_4_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_4_r8.obj `if test -f 'generated/minloc0_4_r8.c'; then $(CYGPATH_W) 'generated/minloc0_4_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc0_4_r8.c'; fi`
+
+minloc0_4_r8.lo: generated/minloc0_4_r8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_4_r8.lo -MD -MP -MF "$(DEPDIR)/minloc0_4_r8.Tpo" -c -o minloc0_4_r8.lo `test -f 'generated/minloc0_4_r8.c' || echo '$(srcdir)/'`generated/minloc0_4_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_4_r8.Tpo" "$(DEPDIR)/minloc0_4_r8.Plo"; else rm -f "$(DEPDIR)/minloc0_4_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_4_r8.c' object='minloc0_4_r8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_4_r8.Plo' tmpdepfile='$(DEPDIR)/minloc0_4_r8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_4_r8.lo `test -f 'generated/minloc0_4_r8.c' || echo '$(srcdir)/'`generated/minloc0_4_r8.c
+
+minloc0_8_r8.o: generated/minloc0_8_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_8_r8.o -MD -MP -MF "$(DEPDIR)/minloc0_8_r8.Tpo" -c -o minloc0_8_r8.o `test -f 'generated/minloc0_8_r8.c' || echo '$(srcdir)/'`generated/minloc0_8_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_8_r8.Tpo" "$(DEPDIR)/minloc0_8_r8.Po"; else rm -f "$(DEPDIR)/minloc0_8_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_8_r8.c' object='minloc0_8_r8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_8_r8.Po' tmpdepfile='$(DEPDIR)/minloc0_8_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_8_r8.o `test -f 'generated/minloc0_8_r8.c' || echo '$(srcdir)/'`generated/minloc0_8_r8.c
+
+minloc0_8_r8.obj: generated/minloc0_8_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_8_r8.obj -MD -MP -MF "$(DEPDIR)/minloc0_8_r8.Tpo" -c -o minloc0_8_r8.obj `if test -f 'generated/minloc0_8_r8.c'; then $(CYGPATH_W) 'generated/minloc0_8_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc0_8_r8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_8_r8.Tpo" "$(DEPDIR)/minloc0_8_r8.Po"; else rm -f "$(DEPDIR)/minloc0_8_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_8_r8.c' object='minloc0_8_r8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_8_r8.Po' tmpdepfile='$(DEPDIR)/minloc0_8_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_8_r8.obj `if test -f 'generated/minloc0_8_r8.c'; then $(CYGPATH_W) 'generated/minloc0_8_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc0_8_r8.c'; fi`
+
+minloc0_8_r8.lo: generated/minloc0_8_r8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc0_8_r8.lo -MD -MP -MF "$(DEPDIR)/minloc0_8_r8.Tpo" -c -o minloc0_8_r8.lo `test -f 'generated/minloc0_8_r8.c' || echo '$(srcdir)/'`generated/minloc0_8_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc0_8_r8.Tpo" "$(DEPDIR)/minloc0_8_r8.Plo"; else rm -f "$(DEPDIR)/minloc0_8_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc0_8_r8.c' object='minloc0_8_r8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc0_8_r8.Plo' tmpdepfile='$(DEPDIR)/minloc0_8_r8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc0_8_r8.lo `test -f 'generated/minloc0_8_r8.c' || echo '$(srcdir)/'`generated/minloc0_8_r8.c
+
+minloc1_4_i4.o: generated/minloc1_4_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_4_i4.o -MD -MP -MF "$(DEPDIR)/minloc1_4_i4.Tpo" -c -o minloc1_4_i4.o `test -f 'generated/minloc1_4_i4.c' || echo '$(srcdir)/'`generated/minloc1_4_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_4_i4.Tpo" "$(DEPDIR)/minloc1_4_i4.Po"; else rm -f "$(DEPDIR)/minloc1_4_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_4_i4.c' object='minloc1_4_i4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_4_i4.Po' tmpdepfile='$(DEPDIR)/minloc1_4_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_4_i4.o `test -f 'generated/minloc1_4_i4.c' || echo '$(srcdir)/'`generated/minloc1_4_i4.c
+
+minloc1_4_i4.obj: generated/minloc1_4_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_4_i4.obj -MD -MP -MF "$(DEPDIR)/minloc1_4_i4.Tpo" -c -o minloc1_4_i4.obj `if test -f 'generated/minloc1_4_i4.c'; then $(CYGPATH_W) 'generated/minloc1_4_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc1_4_i4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_4_i4.Tpo" "$(DEPDIR)/minloc1_4_i4.Po"; else rm -f "$(DEPDIR)/minloc1_4_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_4_i4.c' object='minloc1_4_i4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_4_i4.Po' tmpdepfile='$(DEPDIR)/minloc1_4_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_4_i4.obj `if test -f 'generated/minloc1_4_i4.c'; then $(CYGPATH_W) 'generated/minloc1_4_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc1_4_i4.c'; fi`
+
+minloc1_4_i4.lo: generated/minloc1_4_i4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_4_i4.lo -MD -MP -MF "$(DEPDIR)/minloc1_4_i4.Tpo" -c -o minloc1_4_i4.lo `test -f 'generated/minloc1_4_i4.c' || echo '$(srcdir)/'`generated/minloc1_4_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_4_i4.Tpo" "$(DEPDIR)/minloc1_4_i4.Plo"; else rm -f "$(DEPDIR)/minloc1_4_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_4_i4.c' object='minloc1_4_i4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_4_i4.Plo' tmpdepfile='$(DEPDIR)/minloc1_4_i4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_4_i4.lo `test -f 'generated/minloc1_4_i4.c' || echo '$(srcdir)/'`generated/minloc1_4_i4.c
+
+minloc1_8_i4.o: generated/minloc1_8_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_8_i4.o -MD -MP -MF "$(DEPDIR)/minloc1_8_i4.Tpo" -c -o minloc1_8_i4.o `test -f 'generated/minloc1_8_i4.c' || echo '$(srcdir)/'`generated/minloc1_8_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_8_i4.Tpo" "$(DEPDIR)/minloc1_8_i4.Po"; else rm -f "$(DEPDIR)/minloc1_8_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_8_i4.c' object='minloc1_8_i4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_8_i4.Po' tmpdepfile='$(DEPDIR)/minloc1_8_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_8_i4.o `test -f 'generated/minloc1_8_i4.c' || echo '$(srcdir)/'`generated/minloc1_8_i4.c
+
+minloc1_8_i4.obj: generated/minloc1_8_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_8_i4.obj -MD -MP -MF "$(DEPDIR)/minloc1_8_i4.Tpo" -c -o minloc1_8_i4.obj `if test -f 'generated/minloc1_8_i4.c'; then $(CYGPATH_W) 'generated/minloc1_8_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc1_8_i4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_8_i4.Tpo" "$(DEPDIR)/minloc1_8_i4.Po"; else rm -f "$(DEPDIR)/minloc1_8_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_8_i4.c' object='minloc1_8_i4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_8_i4.Po' tmpdepfile='$(DEPDIR)/minloc1_8_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_8_i4.obj `if test -f 'generated/minloc1_8_i4.c'; then $(CYGPATH_W) 'generated/minloc1_8_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc1_8_i4.c'; fi`
+
+minloc1_8_i4.lo: generated/minloc1_8_i4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_8_i4.lo -MD -MP -MF "$(DEPDIR)/minloc1_8_i4.Tpo" -c -o minloc1_8_i4.lo `test -f 'generated/minloc1_8_i4.c' || echo '$(srcdir)/'`generated/minloc1_8_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_8_i4.Tpo" "$(DEPDIR)/minloc1_8_i4.Plo"; else rm -f "$(DEPDIR)/minloc1_8_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_8_i4.c' object='minloc1_8_i4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_8_i4.Plo' tmpdepfile='$(DEPDIR)/minloc1_8_i4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_8_i4.lo `test -f 'generated/minloc1_8_i4.c' || echo '$(srcdir)/'`generated/minloc1_8_i4.c
+
+minloc1_4_i8.o: generated/minloc1_4_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_4_i8.o -MD -MP -MF "$(DEPDIR)/minloc1_4_i8.Tpo" -c -o minloc1_4_i8.o `test -f 'generated/minloc1_4_i8.c' || echo '$(srcdir)/'`generated/minloc1_4_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_4_i8.Tpo" "$(DEPDIR)/minloc1_4_i8.Po"; else rm -f "$(DEPDIR)/minloc1_4_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_4_i8.c' object='minloc1_4_i8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_4_i8.Po' tmpdepfile='$(DEPDIR)/minloc1_4_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_4_i8.o `test -f 'generated/minloc1_4_i8.c' || echo '$(srcdir)/'`generated/minloc1_4_i8.c
+
+minloc1_4_i8.obj: generated/minloc1_4_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_4_i8.obj -MD -MP -MF "$(DEPDIR)/minloc1_4_i8.Tpo" -c -o minloc1_4_i8.obj `if test -f 'generated/minloc1_4_i8.c'; then $(CYGPATH_W) 'generated/minloc1_4_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc1_4_i8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_4_i8.Tpo" "$(DEPDIR)/minloc1_4_i8.Po"; else rm -f "$(DEPDIR)/minloc1_4_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_4_i8.c' object='minloc1_4_i8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_4_i8.Po' tmpdepfile='$(DEPDIR)/minloc1_4_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_4_i8.obj `if test -f 'generated/minloc1_4_i8.c'; then $(CYGPATH_W) 'generated/minloc1_4_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc1_4_i8.c'; fi`
+
+minloc1_4_i8.lo: generated/minloc1_4_i8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_4_i8.lo -MD -MP -MF "$(DEPDIR)/minloc1_4_i8.Tpo" -c -o minloc1_4_i8.lo `test -f 'generated/minloc1_4_i8.c' || echo '$(srcdir)/'`generated/minloc1_4_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_4_i8.Tpo" "$(DEPDIR)/minloc1_4_i8.Plo"; else rm -f "$(DEPDIR)/minloc1_4_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_4_i8.c' object='minloc1_4_i8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_4_i8.Plo' tmpdepfile='$(DEPDIR)/minloc1_4_i8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_4_i8.lo `test -f 'generated/minloc1_4_i8.c' || echo '$(srcdir)/'`generated/minloc1_4_i8.c
+
+minloc1_8_i8.o: generated/minloc1_8_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_8_i8.o -MD -MP -MF "$(DEPDIR)/minloc1_8_i8.Tpo" -c -o minloc1_8_i8.o `test -f 'generated/minloc1_8_i8.c' || echo '$(srcdir)/'`generated/minloc1_8_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_8_i8.Tpo" "$(DEPDIR)/minloc1_8_i8.Po"; else rm -f "$(DEPDIR)/minloc1_8_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_8_i8.c' object='minloc1_8_i8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_8_i8.Po' tmpdepfile='$(DEPDIR)/minloc1_8_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_8_i8.o `test -f 'generated/minloc1_8_i8.c' || echo '$(srcdir)/'`generated/minloc1_8_i8.c
+
+minloc1_8_i8.obj: generated/minloc1_8_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_8_i8.obj -MD -MP -MF "$(DEPDIR)/minloc1_8_i8.Tpo" -c -o minloc1_8_i8.obj `if test -f 'generated/minloc1_8_i8.c'; then $(CYGPATH_W) 'generated/minloc1_8_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc1_8_i8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_8_i8.Tpo" "$(DEPDIR)/minloc1_8_i8.Po"; else rm -f "$(DEPDIR)/minloc1_8_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_8_i8.c' object='minloc1_8_i8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_8_i8.Po' tmpdepfile='$(DEPDIR)/minloc1_8_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_8_i8.obj `if test -f 'generated/minloc1_8_i8.c'; then $(CYGPATH_W) 'generated/minloc1_8_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc1_8_i8.c'; fi`
+
+minloc1_8_i8.lo: generated/minloc1_8_i8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_8_i8.lo -MD -MP -MF "$(DEPDIR)/minloc1_8_i8.Tpo" -c -o minloc1_8_i8.lo `test -f 'generated/minloc1_8_i8.c' || echo '$(srcdir)/'`generated/minloc1_8_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_8_i8.Tpo" "$(DEPDIR)/minloc1_8_i8.Plo"; else rm -f "$(DEPDIR)/minloc1_8_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_8_i8.c' object='minloc1_8_i8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_8_i8.Plo' tmpdepfile='$(DEPDIR)/minloc1_8_i8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_8_i8.lo `test -f 'generated/minloc1_8_i8.c' || echo '$(srcdir)/'`generated/minloc1_8_i8.c
+
+minloc1_4_r4.o: generated/minloc1_4_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_4_r4.o -MD -MP -MF "$(DEPDIR)/minloc1_4_r4.Tpo" -c -o minloc1_4_r4.o `test -f 'generated/minloc1_4_r4.c' || echo '$(srcdir)/'`generated/minloc1_4_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_4_r4.Tpo" "$(DEPDIR)/minloc1_4_r4.Po"; else rm -f "$(DEPDIR)/minloc1_4_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_4_r4.c' object='minloc1_4_r4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_4_r4.Po' tmpdepfile='$(DEPDIR)/minloc1_4_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_4_r4.o `test -f 'generated/minloc1_4_r4.c' || echo '$(srcdir)/'`generated/minloc1_4_r4.c
+
+minloc1_4_r4.obj: generated/minloc1_4_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_4_r4.obj -MD -MP -MF "$(DEPDIR)/minloc1_4_r4.Tpo" -c -o minloc1_4_r4.obj `if test -f 'generated/minloc1_4_r4.c'; then $(CYGPATH_W) 'generated/minloc1_4_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc1_4_r4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_4_r4.Tpo" "$(DEPDIR)/minloc1_4_r4.Po"; else rm -f "$(DEPDIR)/minloc1_4_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_4_r4.c' object='minloc1_4_r4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_4_r4.Po' tmpdepfile='$(DEPDIR)/minloc1_4_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_4_r4.obj `if test -f 'generated/minloc1_4_r4.c'; then $(CYGPATH_W) 'generated/minloc1_4_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc1_4_r4.c'; fi`
+
+minloc1_4_r4.lo: generated/minloc1_4_r4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_4_r4.lo -MD -MP -MF "$(DEPDIR)/minloc1_4_r4.Tpo" -c -o minloc1_4_r4.lo `test -f 'generated/minloc1_4_r4.c' || echo '$(srcdir)/'`generated/minloc1_4_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_4_r4.Tpo" "$(DEPDIR)/minloc1_4_r4.Plo"; else rm -f "$(DEPDIR)/minloc1_4_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_4_r4.c' object='minloc1_4_r4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_4_r4.Plo' tmpdepfile='$(DEPDIR)/minloc1_4_r4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_4_r4.lo `test -f 'generated/minloc1_4_r4.c' || echo '$(srcdir)/'`generated/minloc1_4_r4.c
+
+minloc1_8_r4.o: generated/minloc1_8_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_8_r4.o -MD -MP -MF "$(DEPDIR)/minloc1_8_r4.Tpo" -c -o minloc1_8_r4.o `test -f 'generated/minloc1_8_r4.c' || echo '$(srcdir)/'`generated/minloc1_8_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_8_r4.Tpo" "$(DEPDIR)/minloc1_8_r4.Po"; else rm -f "$(DEPDIR)/minloc1_8_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_8_r4.c' object='minloc1_8_r4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_8_r4.Po' tmpdepfile='$(DEPDIR)/minloc1_8_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_8_r4.o `test -f 'generated/minloc1_8_r4.c' || echo '$(srcdir)/'`generated/minloc1_8_r4.c
+
+minloc1_8_r4.obj: generated/minloc1_8_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_8_r4.obj -MD -MP -MF "$(DEPDIR)/minloc1_8_r4.Tpo" -c -o minloc1_8_r4.obj `if test -f 'generated/minloc1_8_r4.c'; then $(CYGPATH_W) 'generated/minloc1_8_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc1_8_r4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_8_r4.Tpo" "$(DEPDIR)/minloc1_8_r4.Po"; else rm -f "$(DEPDIR)/minloc1_8_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_8_r4.c' object='minloc1_8_r4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_8_r4.Po' tmpdepfile='$(DEPDIR)/minloc1_8_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_8_r4.obj `if test -f 'generated/minloc1_8_r4.c'; then $(CYGPATH_W) 'generated/minloc1_8_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc1_8_r4.c'; fi`
+
+minloc1_8_r4.lo: generated/minloc1_8_r4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_8_r4.lo -MD -MP -MF "$(DEPDIR)/minloc1_8_r4.Tpo" -c -o minloc1_8_r4.lo `test -f 'generated/minloc1_8_r4.c' || echo '$(srcdir)/'`generated/minloc1_8_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_8_r4.Tpo" "$(DEPDIR)/minloc1_8_r4.Plo"; else rm -f "$(DEPDIR)/minloc1_8_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_8_r4.c' object='minloc1_8_r4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_8_r4.Plo' tmpdepfile='$(DEPDIR)/minloc1_8_r4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_8_r4.lo `test -f 'generated/minloc1_8_r4.c' || echo '$(srcdir)/'`generated/minloc1_8_r4.c
+
+minloc1_4_r8.o: generated/minloc1_4_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_4_r8.o -MD -MP -MF "$(DEPDIR)/minloc1_4_r8.Tpo" -c -o minloc1_4_r8.o `test -f 'generated/minloc1_4_r8.c' || echo '$(srcdir)/'`generated/minloc1_4_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_4_r8.Tpo" "$(DEPDIR)/minloc1_4_r8.Po"; else rm -f "$(DEPDIR)/minloc1_4_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_4_r8.c' object='minloc1_4_r8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_4_r8.Po' tmpdepfile='$(DEPDIR)/minloc1_4_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_4_r8.o `test -f 'generated/minloc1_4_r8.c' || echo '$(srcdir)/'`generated/minloc1_4_r8.c
+
+minloc1_4_r8.obj: generated/minloc1_4_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_4_r8.obj -MD -MP -MF "$(DEPDIR)/minloc1_4_r8.Tpo" -c -o minloc1_4_r8.obj `if test -f 'generated/minloc1_4_r8.c'; then $(CYGPATH_W) 'generated/minloc1_4_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc1_4_r8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_4_r8.Tpo" "$(DEPDIR)/minloc1_4_r8.Po"; else rm -f "$(DEPDIR)/minloc1_4_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_4_r8.c' object='minloc1_4_r8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_4_r8.Po' tmpdepfile='$(DEPDIR)/minloc1_4_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_4_r8.obj `if test -f 'generated/minloc1_4_r8.c'; then $(CYGPATH_W) 'generated/minloc1_4_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc1_4_r8.c'; fi`
+
+minloc1_4_r8.lo: generated/minloc1_4_r8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_4_r8.lo -MD -MP -MF "$(DEPDIR)/minloc1_4_r8.Tpo" -c -o minloc1_4_r8.lo `test -f 'generated/minloc1_4_r8.c' || echo '$(srcdir)/'`generated/minloc1_4_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_4_r8.Tpo" "$(DEPDIR)/minloc1_4_r8.Plo"; else rm -f "$(DEPDIR)/minloc1_4_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_4_r8.c' object='minloc1_4_r8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_4_r8.Plo' tmpdepfile='$(DEPDIR)/minloc1_4_r8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_4_r8.lo `test -f 'generated/minloc1_4_r8.c' || echo '$(srcdir)/'`generated/minloc1_4_r8.c
+
+minloc1_8_r8.o: generated/minloc1_8_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_8_r8.o -MD -MP -MF "$(DEPDIR)/minloc1_8_r8.Tpo" -c -o minloc1_8_r8.o `test -f 'generated/minloc1_8_r8.c' || echo '$(srcdir)/'`generated/minloc1_8_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_8_r8.Tpo" "$(DEPDIR)/minloc1_8_r8.Po"; else rm -f "$(DEPDIR)/minloc1_8_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_8_r8.c' object='minloc1_8_r8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_8_r8.Po' tmpdepfile='$(DEPDIR)/minloc1_8_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_8_r8.o `test -f 'generated/minloc1_8_r8.c' || echo '$(srcdir)/'`generated/minloc1_8_r8.c
+
+minloc1_8_r8.obj: generated/minloc1_8_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_8_r8.obj -MD -MP -MF "$(DEPDIR)/minloc1_8_r8.Tpo" -c -o minloc1_8_r8.obj `if test -f 'generated/minloc1_8_r8.c'; then $(CYGPATH_W) 'generated/minloc1_8_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc1_8_r8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_8_r8.Tpo" "$(DEPDIR)/minloc1_8_r8.Po"; else rm -f "$(DEPDIR)/minloc1_8_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_8_r8.c' object='minloc1_8_r8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_8_r8.Po' tmpdepfile='$(DEPDIR)/minloc1_8_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_8_r8.obj `if test -f 'generated/minloc1_8_r8.c'; then $(CYGPATH_W) 'generated/minloc1_8_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/minloc1_8_r8.c'; fi`
+
+minloc1_8_r8.lo: generated/minloc1_8_r8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minloc1_8_r8.lo -MD -MP -MF "$(DEPDIR)/minloc1_8_r8.Tpo" -c -o minloc1_8_r8.lo `test -f 'generated/minloc1_8_r8.c' || echo '$(srcdir)/'`generated/minloc1_8_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minloc1_8_r8.Tpo" "$(DEPDIR)/minloc1_8_r8.Plo"; else rm -f "$(DEPDIR)/minloc1_8_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minloc1_8_r8.c' object='minloc1_8_r8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minloc1_8_r8.Plo' tmpdepfile='$(DEPDIR)/minloc1_8_r8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minloc1_8_r8.lo `test -f 'generated/minloc1_8_r8.c' || echo '$(srcdir)/'`generated/minloc1_8_r8.c
+
+minval_i4.o: generated/minval_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minval_i4.o -MD -MP -MF "$(DEPDIR)/minval_i4.Tpo" -c -o minval_i4.o `test -f 'generated/minval_i4.c' || echo '$(srcdir)/'`generated/minval_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minval_i4.Tpo" "$(DEPDIR)/minval_i4.Po"; else rm -f "$(DEPDIR)/minval_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minval_i4.c' object='minval_i4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minval_i4.Po' tmpdepfile='$(DEPDIR)/minval_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minval_i4.o `test -f 'generated/minval_i4.c' || echo '$(srcdir)/'`generated/minval_i4.c
+
+minval_i4.obj: generated/minval_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minval_i4.obj -MD -MP -MF "$(DEPDIR)/minval_i4.Tpo" -c -o minval_i4.obj `if test -f 'generated/minval_i4.c'; then $(CYGPATH_W) 'generated/minval_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/minval_i4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minval_i4.Tpo" "$(DEPDIR)/minval_i4.Po"; else rm -f "$(DEPDIR)/minval_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minval_i4.c' object='minval_i4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minval_i4.Po' tmpdepfile='$(DEPDIR)/minval_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minval_i4.obj `if test -f 'generated/minval_i4.c'; then $(CYGPATH_W) 'generated/minval_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/minval_i4.c'; fi`
+
+minval_i4.lo: generated/minval_i4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minval_i4.lo -MD -MP -MF "$(DEPDIR)/minval_i4.Tpo" -c -o minval_i4.lo `test -f 'generated/minval_i4.c' || echo '$(srcdir)/'`generated/minval_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minval_i4.Tpo" "$(DEPDIR)/minval_i4.Plo"; else rm -f "$(DEPDIR)/minval_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minval_i4.c' object='minval_i4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minval_i4.Plo' tmpdepfile='$(DEPDIR)/minval_i4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minval_i4.lo `test -f 'generated/minval_i4.c' || echo '$(srcdir)/'`generated/minval_i4.c
+
+minval_i8.o: generated/minval_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minval_i8.o -MD -MP -MF "$(DEPDIR)/minval_i8.Tpo" -c -o minval_i8.o `test -f 'generated/minval_i8.c' || echo '$(srcdir)/'`generated/minval_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minval_i8.Tpo" "$(DEPDIR)/minval_i8.Po"; else rm -f "$(DEPDIR)/minval_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minval_i8.c' object='minval_i8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minval_i8.Po' tmpdepfile='$(DEPDIR)/minval_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minval_i8.o `test -f 'generated/minval_i8.c' || echo '$(srcdir)/'`generated/minval_i8.c
+
+minval_i8.obj: generated/minval_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minval_i8.obj -MD -MP -MF "$(DEPDIR)/minval_i8.Tpo" -c -o minval_i8.obj `if test -f 'generated/minval_i8.c'; then $(CYGPATH_W) 'generated/minval_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/minval_i8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minval_i8.Tpo" "$(DEPDIR)/minval_i8.Po"; else rm -f "$(DEPDIR)/minval_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minval_i8.c' object='minval_i8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minval_i8.Po' tmpdepfile='$(DEPDIR)/minval_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minval_i8.obj `if test -f 'generated/minval_i8.c'; then $(CYGPATH_W) 'generated/minval_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/minval_i8.c'; fi`
+
+minval_i8.lo: generated/minval_i8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minval_i8.lo -MD -MP -MF "$(DEPDIR)/minval_i8.Tpo" -c -o minval_i8.lo `test -f 'generated/minval_i8.c' || echo '$(srcdir)/'`generated/minval_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minval_i8.Tpo" "$(DEPDIR)/minval_i8.Plo"; else rm -f "$(DEPDIR)/minval_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minval_i8.c' object='minval_i8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minval_i8.Plo' tmpdepfile='$(DEPDIR)/minval_i8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minval_i8.lo `test -f 'generated/minval_i8.c' || echo '$(srcdir)/'`generated/minval_i8.c
+
+minval_r4.o: generated/minval_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minval_r4.o -MD -MP -MF "$(DEPDIR)/minval_r4.Tpo" -c -o minval_r4.o `test -f 'generated/minval_r4.c' || echo '$(srcdir)/'`generated/minval_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minval_r4.Tpo" "$(DEPDIR)/minval_r4.Po"; else rm -f "$(DEPDIR)/minval_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minval_r4.c' object='minval_r4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minval_r4.Po' tmpdepfile='$(DEPDIR)/minval_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minval_r4.o `test -f 'generated/minval_r4.c' || echo '$(srcdir)/'`generated/minval_r4.c
+
+minval_r4.obj: generated/minval_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minval_r4.obj -MD -MP -MF "$(DEPDIR)/minval_r4.Tpo" -c -o minval_r4.obj `if test -f 'generated/minval_r4.c'; then $(CYGPATH_W) 'generated/minval_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/minval_r4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minval_r4.Tpo" "$(DEPDIR)/minval_r4.Po"; else rm -f "$(DEPDIR)/minval_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minval_r4.c' object='minval_r4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minval_r4.Po' tmpdepfile='$(DEPDIR)/minval_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minval_r4.obj `if test -f 'generated/minval_r4.c'; then $(CYGPATH_W) 'generated/minval_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/minval_r4.c'; fi`
+
+minval_r4.lo: generated/minval_r4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minval_r4.lo -MD -MP -MF "$(DEPDIR)/minval_r4.Tpo" -c -o minval_r4.lo `test -f 'generated/minval_r4.c' || echo '$(srcdir)/'`generated/minval_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minval_r4.Tpo" "$(DEPDIR)/minval_r4.Plo"; else rm -f "$(DEPDIR)/minval_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minval_r4.c' object='minval_r4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minval_r4.Plo' tmpdepfile='$(DEPDIR)/minval_r4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minval_r4.lo `test -f 'generated/minval_r4.c' || echo '$(srcdir)/'`generated/minval_r4.c
+
+minval_r8.o: generated/minval_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minval_r8.o -MD -MP -MF "$(DEPDIR)/minval_r8.Tpo" -c -o minval_r8.o `test -f 'generated/minval_r8.c' || echo '$(srcdir)/'`generated/minval_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minval_r8.Tpo" "$(DEPDIR)/minval_r8.Po"; else rm -f "$(DEPDIR)/minval_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minval_r8.c' object='minval_r8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minval_r8.Po' tmpdepfile='$(DEPDIR)/minval_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minval_r8.o `test -f 'generated/minval_r8.c' || echo '$(srcdir)/'`generated/minval_r8.c
+
+minval_r8.obj: generated/minval_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minval_r8.obj -MD -MP -MF "$(DEPDIR)/minval_r8.Tpo" -c -o minval_r8.obj `if test -f 'generated/minval_r8.c'; then $(CYGPATH_W) 'generated/minval_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/minval_r8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minval_r8.Tpo" "$(DEPDIR)/minval_r8.Po"; else rm -f "$(DEPDIR)/minval_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minval_r8.c' object='minval_r8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minval_r8.Po' tmpdepfile='$(DEPDIR)/minval_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minval_r8.obj `if test -f 'generated/minval_r8.c'; then $(CYGPATH_W) 'generated/minval_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/minval_r8.c'; fi`
+
+minval_r8.lo: generated/minval_r8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT minval_r8.lo -MD -MP -MF "$(DEPDIR)/minval_r8.Tpo" -c -o minval_r8.lo `test -f 'generated/minval_r8.c' || echo '$(srcdir)/'`generated/minval_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/minval_r8.Tpo" "$(DEPDIR)/minval_r8.Plo"; else rm -f "$(DEPDIR)/minval_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/minval_r8.c' object='minval_r8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/minval_r8.Plo' tmpdepfile='$(DEPDIR)/minval_r8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o minval_r8.lo `test -f 'generated/minval_r8.c' || echo '$(srcdir)/'`generated/minval_r8.c
+
+product_i4.o: generated/product_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT product_i4.o -MD -MP -MF "$(DEPDIR)/product_i4.Tpo" -c -o product_i4.o `test -f 'generated/product_i4.c' || echo '$(srcdir)/'`generated/product_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/product_i4.Tpo" "$(DEPDIR)/product_i4.Po"; else rm -f "$(DEPDIR)/product_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/product_i4.c' object='product_i4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/product_i4.Po' tmpdepfile='$(DEPDIR)/product_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o product_i4.o `test -f 'generated/product_i4.c' || echo '$(srcdir)/'`generated/product_i4.c
+
+product_i4.obj: generated/product_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT product_i4.obj -MD -MP -MF "$(DEPDIR)/product_i4.Tpo" -c -o product_i4.obj `if test -f 'generated/product_i4.c'; then $(CYGPATH_W) 'generated/product_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/product_i4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/product_i4.Tpo" "$(DEPDIR)/product_i4.Po"; else rm -f "$(DEPDIR)/product_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/product_i4.c' object='product_i4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/product_i4.Po' tmpdepfile='$(DEPDIR)/product_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o product_i4.obj `if test -f 'generated/product_i4.c'; then $(CYGPATH_W) 'generated/product_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/product_i4.c'; fi`
+
+product_i4.lo: generated/product_i4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT product_i4.lo -MD -MP -MF "$(DEPDIR)/product_i4.Tpo" -c -o product_i4.lo `test -f 'generated/product_i4.c' || echo '$(srcdir)/'`generated/product_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/product_i4.Tpo" "$(DEPDIR)/product_i4.Plo"; else rm -f "$(DEPDIR)/product_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/product_i4.c' object='product_i4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/product_i4.Plo' tmpdepfile='$(DEPDIR)/product_i4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o product_i4.lo `test -f 'generated/product_i4.c' || echo '$(srcdir)/'`generated/product_i4.c
+
+product_i8.o: generated/product_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT product_i8.o -MD -MP -MF "$(DEPDIR)/product_i8.Tpo" -c -o product_i8.o `test -f 'generated/product_i8.c' || echo '$(srcdir)/'`generated/product_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/product_i8.Tpo" "$(DEPDIR)/product_i8.Po"; else rm -f "$(DEPDIR)/product_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/product_i8.c' object='product_i8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/product_i8.Po' tmpdepfile='$(DEPDIR)/product_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o product_i8.o `test -f 'generated/product_i8.c' || echo '$(srcdir)/'`generated/product_i8.c
+
+product_i8.obj: generated/product_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT product_i8.obj -MD -MP -MF "$(DEPDIR)/product_i8.Tpo" -c -o product_i8.obj `if test -f 'generated/product_i8.c'; then $(CYGPATH_W) 'generated/product_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/product_i8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/product_i8.Tpo" "$(DEPDIR)/product_i8.Po"; else rm -f "$(DEPDIR)/product_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/product_i8.c' object='product_i8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/product_i8.Po' tmpdepfile='$(DEPDIR)/product_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o product_i8.obj `if test -f 'generated/product_i8.c'; then $(CYGPATH_W) 'generated/product_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/product_i8.c'; fi`
+
+product_i8.lo: generated/product_i8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT product_i8.lo -MD -MP -MF "$(DEPDIR)/product_i8.Tpo" -c -o product_i8.lo `test -f 'generated/product_i8.c' || echo '$(srcdir)/'`generated/product_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/product_i8.Tpo" "$(DEPDIR)/product_i8.Plo"; else rm -f "$(DEPDIR)/product_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/product_i8.c' object='product_i8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/product_i8.Plo' tmpdepfile='$(DEPDIR)/product_i8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o product_i8.lo `test -f 'generated/product_i8.c' || echo '$(srcdir)/'`generated/product_i8.c
+
+product_r4.o: generated/product_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT product_r4.o -MD -MP -MF "$(DEPDIR)/product_r4.Tpo" -c -o product_r4.o `test -f 'generated/product_r4.c' || echo '$(srcdir)/'`generated/product_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/product_r4.Tpo" "$(DEPDIR)/product_r4.Po"; else rm -f "$(DEPDIR)/product_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/product_r4.c' object='product_r4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/product_r4.Po' tmpdepfile='$(DEPDIR)/product_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o product_r4.o `test -f 'generated/product_r4.c' || echo '$(srcdir)/'`generated/product_r4.c
+
+product_r4.obj: generated/product_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT product_r4.obj -MD -MP -MF "$(DEPDIR)/product_r4.Tpo" -c -o product_r4.obj `if test -f 'generated/product_r4.c'; then $(CYGPATH_W) 'generated/product_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/product_r4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/product_r4.Tpo" "$(DEPDIR)/product_r4.Po"; else rm -f "$(DEPDIR)/product_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/product_r4.c' object='product_r4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/product_r4.Po' tmpdepfile='$(DEPDIR)/product_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o product_r4.obj `if test -f 'generated/product_r4.c'; then $(CYGPATH_W) 'generated/product_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/product_r4.c'; fi`
+
+product_r4.lo: generated/product_r4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT product_r4.lo -MD -MP -MF "$(DEPDIR)/product_r4.Tpo" -c -o product_r4.lo `test -f 'generated/product_r4.c' || echo '$(srcdir)/'`generated/product_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/product_r4.Tpo" "$(DEPDIR)/product_r4.Plo"; else rm -f "$(DEPDIR)/product_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/product_r4.c' object='product_r4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/product_r4.Plo' tmpdepfile='$(DEPDIR)/product_r4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o product_r4.lo `test -f 'generated/product_r4.c' || echo '$(srcdir)/'`generated/product_r4.c
+
+product_r8.o: generated/product_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT product_r8.o -MD -MP -MF "$(DEPDIR)/product_r8.Tpo" -c -o product_r8.o `test -f 'generated/product_r8.c' || echo '$(srcdir)/'`generated/product_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/product_r8.Tpo" "$(DEPDIR)/product_r8.Po"; else rm -f "$(DEPDIR)/product_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/product_r8.c' object='product_r8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/product_r8.Po' tmpdepfile='$(DEPDIR)/product_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o product_r8.o `test -f 'generated/product_r8.c' || echo '$(srcdir)/'`generated/product_r8.c
+
+product_r8.obj: generated/product_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT product_r8.obj -MD -MP -MF "$(DEPDIR)/product_r8.Tpo" -c -o product_r8.obj `if test -f 'generated/product_r8.c'; then $(CYGPATH_W) 'generated/product_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/product_r8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/product_r8.Tpo" "$(DEPDIR)/product_r8.Po"; else rm -f "$(DEPDIR)/product_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/product_r8.c' object='product_r8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/product_r8.Po' tmpdepfile='$(DEPDIR)/product_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o product_r8.obj `if test -f 'generated/product_r8.c'; then $(CYGPATH_W) 'generated/product_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/product_r8.c'; fi`
+
+product_r8.lo: generated/product_r8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT product_r8.lo -MD -MP -MF "$(DEPDIR)/product_r8.Tpo" -c -o product_r8.lo `test -f 'generated/product_r8.c' || echo '$(srcdir)/'`generated/product_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/product_r8.Tpo" "$(DEPDIR)/product_r8.Plo"; else rm -f "$(DEPDIR)/product_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/product_r8.c' object='product_r8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/product_r8.Plo' tmpdepfile='$(DEPDIR)/product_r8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o product_r8.lo `test -f 'generated/product_r8.c' || echo '$(srcdir)/'`generated/product_r8.c
+
+product_c4.o: generated/product_c4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT product_c4.o -MD -MP -MF "$(DEPDIR)/product_c4.Tpo" -c -o product_c4.o `test -f 'generated/product_c4.c' || echo '$(srcdir)/'`generated/product_c4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/product_c4.Tpo" "$(DEPDIR)/product_c4.Po"; else rm -f "$(DEPDIR)/product_c4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/product_c4.c' object='product_c4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/product_c4.Po' tmpdepfile='$(DEPDIR)/product_c4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o product_c4.o `test -f 'generated/product_c4.c' || echo '$(srcdir)/'`generated/product_c4.c
+
+product_c4.obj: generated/product_c4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT product_c4.obj -MD -MP -MF "$(DEPDIR)/product_c4.Tpo" -c -o product_c4.obj `if test -f 'generated/product_c4.c'; then $(CYGPATH_W) 'generated/product_c4.c'; else $(CYGPATH_W) '$(srcdir)/generated/product_c4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/product_c4.Tpo" "$(DEPDIR)/product_c4.Po"; else rm -f "$(DEPDIR)/product_c4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/product_c4.c' object='product_c4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/product_c4.Po' tmpdepfile='$(DEPDIR)/product_c4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o product_c4.obj `if test -f 'generated/product_c4.c'; then $(CYGPATH_W) 'generated/product_c4.c'; else $(CYGPATH_W) '$(srcdir)/generated/product_c4.c'; fi`
+
+product_c4.lo: generated/product_c4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT product_c4.lo -MD -MP -MF "$(DEPDIR)/product_c4.Tpo" -c -o product_c4.lo `test -f 'generated/product_c4.c' || echo '$(srcdir)/'`generated/product_c4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/product_c4.Tpo" "$(DEPDIR)/product_c4.Plo"; else rm -f "$(DEPDIR)/product_c4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/product_c4.c' object='product_c4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/product_c4.Plo' tmpdepfile='$(DEPDIR)/product_c4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o product_c4.lo `test -f 'generated/product_c4.c' || echo '$(srcdir)/'`generated/product_c4.c
+
+product_c8.o: generated/product_c8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT product_c8.o -MD -MP -MF "$(DEPDIR)/product_c8.Tpo" -c -o product_c8.o `test -f 'generated/product_c8.c' || echo '$(srcdir)/'`generated/product_c8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/product_c8.Tpo" "$(DEPDIR)/product_c8.Po"; else rm -f "$(DEPDIR)/product_c8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/product_c8.c' object='product_c8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/product_c8.Po' tmpdepfile='$(DEPDIR)/product_c8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o product_c8.o `test -f 'generated/product_c8.c' || echo '$(srcdir)/'`generated/product_c8.c
+
+product_c8.obj: generated/product_c8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT product_c8.obj -MD -MP -MF "$(DEPDIR)/product_c8.Tpo" -c -o product_c8.obj `if test -f 'generated/product_c8.c'; then $(CYGPATH_W) 'generated/product_c8.c'; else $(CYGPATH_W) '$(srcdir)/generated/product_c8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/product_c8.Tpo" "$(DEPDIR)/product_c8.Po"; else rm -f "$(DEPDIR)/product_c8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/product_c8.c' object='product_c8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/product_c8.Po' tmpdepfile='$(DEPDIR)/product_c8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o product_c8.obj `if test -f 'generated/product_c8.c'; then $(CYGPATH_W) 'generated/product_c8.c'; else $(CYGPATH_W) '$(srcdir)/generated/product_c8.c'; fi`
+
+product_c8.lo: generated/product_c8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT product_c8.lo -MD -MP -MF "$(DEPDIR)/product_c8.Tpo" -c -o product_c8.lo `test -f 'generated/product_c8.c' || echo '$(srcdir)/'`generated/product_c8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/product_c8.Tpo" "$(DEPDIR)/product_c8.Plo"; else rm -f "$(DEPDIR)/product_c8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/product_c8.c' object='product_c8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/product_c8.Plo' tmpdepfile='$(DEPDIR)/product_c8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o product_c8.lo `test -f 'generated/product_c8.c' || echo '$(srcdir)/'`generated/product_c8.c
+
+sum_i4.o: generated/sum_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sum_i4.o -MD -MP -MF "$(DEPDIR)/sum_i4.Tpo" -c -o sum_i4.o `test -f 'generated/sum_i4.c' || echo '$(srcdir)/'`generated/sum_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sum_i4.Tpo" "$(DEPDIR)/sum_i4.Po"; else rm -f "$(DEPDIR)/sum_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/sum_i4.c' object='sum_i4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sum_i4.Po' tmpdepfile='$(DEPDIR)/sum_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sum_i4.o `test -f 'generated/sum_i4.c' || echo '$(srcdir)/'`generated/sum_i4.c
+
+sum_i4.obj: generated/sum_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sum_i4.obj -MD -MP -MF "$(DEPDIR)/sum_i4.Tpo" -c -o sum_i4.obj `if test -f 'generated/sum_i4.c'; then $(CYGPATH_W) 'generated/sum_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/sum_i4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sum_i4.Tpo" "$(DEPDIR)/sum_i4.Po"; else rm -f "$(DEPDIR)/sum_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/sum_i4.c' object='sum_i4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sum_i4.Po' tmpdepfile='$(DEPDIR)/sum_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sum_i4.obj `if test -f 'generated/sum_i4.c'; then $(CYGPATH_W) 'generated/sum_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/sum_i4.c'; fi`
+
+sum_i4.lo: generated/sum_i4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sum_i4.lo -MD -MP -MF "$(DEPDIR)/sum_i4.Tpo" -c -o sum_i4.lo `test -f 'generated/sum_i4.c' || echo '$(srcdir)/'`generated/sum_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sum_i4.Tpo" "$(DEPDIR)/sum_i4.Plo"; else rm -f "$(DEPDIR)/sum_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/sum_i4.c' object='sum_i4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sum_i4.Plo' tmpdepfile='$(DEPDIR)/sum_i4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sum_i4.lo `test -f 'generated/sum_i4.c' || echo '$(srcdir)/'`generated/sum_i4.c
+
+sum_i8.o: generated/sum_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sum_i8.o -MD -MP -MF "$(DEPDIR)/sum_i8.Tpo" -c -o sum_i8.o `test -f 'generated/sum_i8.c' || echo '$(srcdir)/'`generated/sum_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sum_i8.Tpo" "$(DEPDIR)/sum_i8.Po"; else rm -f "$(DEPDIR)/sum_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/sum_i8.c' object='sum_i8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sum_i8.Po' tmpdepfile='$(DEPDIR)/sum_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sum_i8.o `test -f 'generated/sum_i8.c' || echo '$(srcdir)/'`generated/sum_i8.c
+
+sum_i8.obj: generated/sum_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sum_i8.obj -MD -MP -MF "$(DEPDIR)/sum_i8.Tpo" -c -o sum_i8.obj `if test -f 'generated/sum_i8.c'; then $(CYGPATH_W) 'generated/sum_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/sum_i8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sum_i8.Tpo" "$(DEPDIR)/sum_i8.Po"; else rm -f "$(DEPDIR)/sum_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/sum_i8.c' object='sum_i8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sum_i8.Po' tmpdepfile='$(DEPDIR)/sum_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sum_i8.obj `if test -f 'generated/sum_i8.c'; then $(CYGPATH_W) 'generated/sum_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/sum_i8.c'; fi`
+
+sum_i8.lo: generated/sum_i8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sum_i8.lo -MD -MP -MF "$(DEPDIR)/sum_i8.Tpo" -c -o sum_i8.lo `test -f 'generated/sum_i8.c' || echo '$(srcdir)/'`generated/sum_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sum_i8.Tpo" "$(DEPDIR)/sum_i8.Plo"; else rm -f "$(DEPDIR)/sum_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/sum_i8.c' object='sum_i8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sum_i8.Plo' tmpdepfile='$(DEPDIR)/sum_i8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sum_i8.lo `test -f 'generated/sum_i8.c' || echo '$(srcdir)/'`generated/sum_i8.c
+
+sum_r4.o: generated/sum_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sum_r4.o -MD -MP -MF "$(DEPDIR)/sum_r4.Tpo" -c -o sum_r4.o `test -f 'generated/sum_r4.c' || echo '$(srcdir)/'`generated/sum_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sum_r4.Tpo" "$(DEPDIR)/sum_r4.Po"; else rm -f "$(DEPDIR)/sum_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/sum_r4.c' object='sum_r4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sum_r4.Po' tmpdepfile='$(DEPDIR)/sum_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sum_r4.o `test -f 'generated/sum_r4.c' || echo '$(srcdir)/'`generated/sum_r4.c
+
+sum_r4.obj: generated/sum_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sum_r4.obj -MD -MP -MF "$(DEPDIR)/sum_r4.Tpo" -c -o sum_r4.obj `if test -f 'generated/sum_r4.c'; then $(CYGPATH_W) 'generated/sum_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/sum_r4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sum_r4.Tpo" "$(DEPDIR)/sum_r4.Po"; else rm -f "$(DEPDIR)/sum_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/sum_r4.c' object='sum_r4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sum_r4.Po' tmpdepfile='$(DEPDIR)/sum_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sum_r4.obj `if test -f 'generated/sum_r4.c'; then $(CYGPATH_W) 'generated/sum_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/sum_r4.c'; fi`
+
+sum_r4.lo: generated/sum_r4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sum_r4.lo -MD -MP -MF "$(DEPDIR)/sum_r4.Tpo" -c -o sum_r4.lo `test -f 'generated/sum_r4.c' || echo '$(srcdir)/'`generated/sum_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sum_r4.Tpo" "$(DEPDIR)/sum_r4.Plo"; else rm -f "$(DEPDIR)/sum_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/sum_r4.c' object='sum_r4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sum_r4.Plo' tmpdepfile='$(DEPDIR)/sum_r4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sum_r4.lo `test -f 'generated/sum_r4.c' || echo '$(srcdir)/'`generated/sum_r4.c
+
+sum_r8.o: generated/sum_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sum_r8.o -MD -MP -MF "$(DEPDIR)/sum_r8.Tpo" -c -o sum_r8.o `test -f 'generated/sum_r8.c' || echo '$(srcdir)/'`generated/sum_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sum_r8.Tpo" "$(DEPDIR)/sum_r8.Po"; else rm -f "$(DEPDIR)/sum_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/sum_r8.c' object='sum_r8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sum_r8.Po' tmpdepfile='$(DEPDIR)/sum_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sum_r8.o `test -f 'generated/sum_r8.c' || echo '$(srcdir)/'`generated/sum_r8.c
+
+sum_r8.obj: generated/sum_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sum_r8.obj -MD -MP -MF "$(DEPDIR)/sum_r8.Tpo" -c -o sum_r8.obj `if test -f 'generated/sum_r8.c'; then $(CYGPATH_W) 'generated/sum_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/sum_r8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sum_r8.Tpo" "$(DEPDIR)/sum_r8.Po"; else rm -f "$(DEPDIR)/sum_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/sum_r8.c' object='sum_r8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sum_r8.Po' tmpdepfile='$(DEPDIR)/sum_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sum_r8.obj `if test -f 'generated/sum_r8.c'; then $(CYGPATH_W) 'generated/sum_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/sum_r8.c'; fi`
+
+sum_r8.lo: generated/sum_r8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sum_r8.lo -MD -MP -MF "$(DEPDIR)/sum_r8.Tpo" -c -o sum_r8.lo `test -f 'generated/sum_r8.c' || echo '$(srcdir)/'`generated/sum_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sum_r8.Tpo" "$(DEPDIR)/sum_r8.Plo"; else rm -f "$(DEPDIR)/sum_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/sum_r8.c' object='sum_r8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sum_r8.Plo' tmpdepfile='$(DEPDIR)/sum_r8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sum_r8.lo `test -f 'generated/sum_r8.c' || echo '$(srcdir)/'`generated/sum_r8.c
+
+sum_c4.o: generated/sum_c4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sum_c4.o -MD -MP -MF "$(DEPDIR)/sum_c4.Tpo" -c -o sum_c4.o `test -f 'generated/sum_c4.c' || echo '$(srcdir)/'`generated/sum_c4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sum_c4.Tpo" "$(DEPDIR)/sum_c4.Po"; else rm -f "$(DEPDIR)/sum_c4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/sum_c4.c' object='sum_c4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sum_c4.Po' tmpdepfile='$(DEPDIR)/sum_c4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sum_c4.o `test -f 'generated/sum_c4.c' || echo '$(srcdir)/'`generated/sum_c4.c
+
+sum_c4.obj: generated/sum_c4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sum_c4.obj -MD -MP -MF "$(DEPDIR)/sum_c4.Tpo" -c -o sum_c4.obj `if test -f 'generated/sum_c4.c'; then $(CYGPATH_W) 'generated/sum_c4.c'; else $(CYGPATH_W) '$(srcdir)/generated/sum_c4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sum_c4.Tpo" "$(DEPDIR)/sum_c4.Po"; else rm -f "$(DEPDIR)/sum_c4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/sum_c4.c' object='sum_c4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sum_c4.Po' tmpdepfile='$(DEPDIR)/sum_c4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sum_c4.obj `if test -f 'generated/sum_c4.c'; then $(CYGPATH_W) 'generated/sum_c4.c'; else $(CYGPATH_W) '$(srcdir)/generated/sum_c4.c'; fi`
+
+sum_c4.lo: generated/sum_c4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sum_c4.lo -MD -MP -MF "$(DEPDIR)/sum_c4.Tpo" -c -o sum_c4.lo `test -f 'generated/sum_c4.c' || echo '$(srcdir)/'`generated/sum_c4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sum_c4.Tpo" "$(DEPDIR)/sum_c4.Plo"; else rm -f "$(DEPDIR)/sum_c4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/sum_c4.c' object='sum_c4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sum_c4.Plo' tmpdepfile='$(DEPDIR)/sum_c4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sum_c4.lo `test -f 'generated/sum_c4.c' || echo '$(srcdir)/'`generated/sum_c4.c
+
+sum_c8.o: generated/sum_c8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sum_c8.o -MD -MP -MF "$(DEPDIR)/sum_c8.Tpo" -c -o sum_c8.o `test -f 'generated/sum_c8.c' || echo '$(srcdir)/'`generated/sum_c8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sum_c8.Tpo" "$(DEPDIR)/sum_c8.Po"; else rm -f "$(DEPDIR)/sum_c8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/sum_c8.c' object='sum_c8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sum_c8.Po' tmpdepfile='$(DEPDIR)/sum_c8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sum_c8.o `test -f 'generated/sum_c8.c' || echo '$(srcdir)/'`generated/sum_c8.c
+
+sum_c8.obj: generated/sum_c8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sum_c8.obj -MD -MP -MF "$(DEPDIR)/sum_c8.Tpo" -c -o sum_c8.obj `if test -f 'generated/sum_c8.c'; then $(CYGPATH_W) 'generated/sum_c8.c'; else $(CYGPATH_W) '$(srcdir)/generated/sum_c8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sum_c8.Tpo" "$(DEPDIR)/sum_c8.Po"; else rm -f "$(DEPDIR)/sum_c8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/sum_c8.c' object='sum_c8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sum_c8.Po' tmpdepfile='$(DEPDIR)/sum_c8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sum_c8.obj `if test -f 'generated/sum_c8.c'; then $(CYGPATH_W) 'generated/sum_c8.c'; else $(CYGPATH_W) '$(srcdir)/generated/sum_c8.c'; fi`
+
+sum_c8.lo: generated/sum_c8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sum_c8.lo -MD -MP -MF "$(DEPDIR)/sum_c8.Tpo" -c -o sum_c8.lo `test -f 'generated/sum_c8.c' || echo '$(srcdir)/'`generated/sum_c8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sum_c8.Tpo" "$(DEPDIR)/sum_c8.Plo"; else rm -f "$(DEPDIR)/sum_c8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/sum_c8.c' object='sum_c8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sum_c8.Plo' tmpdepfile='$(DEPDIR)/sum_c8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sum_c8.lo `test -f 'generated/sum_c8.c' || echo '$(srcdir)/'`generated/sum_c8.c
+
+dotprod_i4.o: generated/dotprod_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_i4.o -MD -MP -MF "$(DEPDIR)/dotprod_i4.Tpo" -c -o dotprod_i4.o `test -f 'generated/dotprod_i4.c' || echo '$(srcdir)/'`generated/dotprod_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_i4.Tpo" "$(DEPDIR)/dotprod_i4.Po"; else rm -f "$(DEPDIR)/dotprod_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_i4.c' object='dotprod_i4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_i4.Po' tmpdepfile='$(DEPDIR)/dotprod_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_i4.o `test -f 'generated/dotprod_i4.c' || echo '$(srcdir)/'`generated/dotprod_i4.c
+
+dotprod_i4.obj: generated/dotprod_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_i4.obj -MD -MP -MF "$(DEPDIR)/dotprod_i4.Tpo" -c -o dotprod_i4.obj `if test -f 'generated/dotprod_i4.c'; then $(CYGPATH_W) 'generated/dotprod_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/dotprod_i4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_i4.Tpo" "$(DEPDIR)/dotprod_i4.Po"; else rm -f "$(DEPDIR)/dotprod_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_i4.c' object='dotprod_i4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_i4.Po' tmpdepfile='$(DEPDIR)/dotprod_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_i4.obj `if test -f 'generated/dotprod_i4.c'; then $(CYGPATH_W) 'generated/dotprod_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/dotprod_i4.c'; fi`
+
+dotprod_i4.lo: generated/dotprod_i4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_i4.lo -MD -MP -MF "$(DEPDIR)/dotprod_i4.Tpo" -c -o dotprod_i4.lo `test -f 'generated/dotprod_i4.c' || echo '$(srcdir)/'`generated/dotprod_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_i4.Tpo" "$(DEPDIR)/dotprod_i4.Plo"; else rm -f "$(DEPDIR)/dotprod_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_i4.c' object='dotprod_i4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_i4.Plo' tmpdepfile='$(DEPDIR)/dotprod_i4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_i4.lo `test -f 'generated/dotprod_i4.c' || echo '$(srcdir)/'`generated/dotprod_i4.c
+
+dotprod_i8.o: generated/dotprod_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_i8.o -MD -MP -MF "$(DEPDIR)/dotprod_i8.Tpo" -c -o dotprod_i8.o `test -f 'generated/dotprod_i8.c' || echo '$(srcdir)/'`generated/dotprod_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_i8.Tpo" "$(DEPDIR)/dotprod_i8.Po"; else rm -f "$(DEPDIR)/dotprod_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_i8.c' object='dotprod_i8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_i8.Po' tmpdepfile='$(DEPDIR)/dotprod_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_i8.o `test -f 'generated/dotprod_i8.c' || echo '$(srcdir)/'`generated/dotprod_i8.c
+
+dotprod_i8.obj: generated/dotprod_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_i8.obj -MD -MP -MF "$(DEPDIR)/dotprod_i8.Tpo" -c -o dotprod_i8.obj `if test -f 'generated/dotprod_i8.c'; then $(CYGPATH_W) 'generated/dotprod_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/dotprod_i8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_i8.Tpo" "$(DEPDIR)/dotprod_i8.Po"; else rm -f "$(DEPDIR)/dotprod_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_i8.c' object='dotprod_i8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_i8.Po' tmpdepfile='$(DEPDIR)/dotprod_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_i8.obj `if test -f 'generated/dotprod_i8.c'; then $(CYGPATH_W) 'generated/dotprod_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/dotprod_i8.c'; fi`
+
+dotprod_i8.lo: generated/dotprod_i8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_i8.lo -MD -MP -MF "$(DEPDIR)/dotprod_i8.Tpo" -c -o dotprod_i8.lo `test -f 'generated/dotprod_i8.c' || echo '$(srcdir)/'`generated/dotprod_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_i8.Tpo" "$(DEPDIR)/dotprod_i8.Plo"; else rm -f "$(DEPDIR)/dotprod_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_i8.c' object='dotprod_i8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_i8.Plo' tmpdepfile='$(DEPDIR)/dotprod_i8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_i8.lo `test -f 'generated/dotprod_i8.c' || echo '$(srcdir)/'`generated/dotprod_i8.c
+
+dotprod_r4.o: generated/dotprod_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_r4.o -MD -MP -MF "$(DEPDIR)/dotprod_r4.Tpo" -c -o dotprod_r4.o `test -f 'generated/dotprod_r4.c' || echo '$(srcdir)/'`generated/dotprod_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_r4.Tpo" "$(DEPDIR)/dotprod_r4.Po"; else rm -f "$(DEPDIR)/dotprod_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_r4.c' object='dotprod_r4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_r4.Po' tmpdepfile='$(DEPDIR)/dotprod_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_r4.o `test -f 'generated/dotprod_r4.c' || echo '$(srcdir)/'`generated/dotprod_r4.c
+
+dotprod_r4.obj: generated/dotprod_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_r4.obj -MD -MP -MF "$(DEPDIR)/dotprod_r4.Tpo" -c -o dotprod_r4.obj `if test -f 'generated/dotprod_r4.c'; then $(CYGPATH_W) 'generated/dotprod_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/dotprod_r4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_r4.Tpo" "$(DEPDIR)/dotprod_r4.Po"; else rm -f "$(DEPDIR)/dotprod_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_r4.c' object='dotprod_r4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_r4.Po' tmpdepfile='$(DEPDIR)/dotprod_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_r4.obj `if test -f 'generated/dotprod_r4.c'; then $(CYGPATH_W) 'generated/dotprod_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/dotprod_r4.c'; fi`
+
+dotprod_r4.lo: generated/dotprod_r4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_r4.lo -MD -MP -MF "$(DEPDIR)/dotprod_r4.Tpo" -c -o dotprod_r4.lo `test -f 'generated/dotprod_r4.c' || echo '$(srcdir)/'`generated/dotprod_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_r4.Tpo" "$(DEPDIR)/dotprod_r4.Plo"; else rm -f "$(DEPDIR)/dotprod_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_r4.c' object='dotprod_r4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_r4.Plo' tmpdepfile='$(DEPDIR)/dotprod_r4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_r4.lo `test -f 'generated/dotprod_r4.c' || echo '$(srcdir)/'`generated/dotprod_r4.c
+
+dotprod_r8.o: generated/dotprod_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_r8.o -MD -MP -MF "$(DEPDIR)/dotprod_r8.Tpo" -c -o dotprod_r8.o `test -f 'generated/dotprod_r8.c' || echo '$(srcdir)/'`generated/dotprod_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_r8.Tpo" "$(DEPDIR)/dotprod_r8.Po"; else rm -f "$(DEPDIR)/dotprod_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_r8.c' object='dotprod_r8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_r8.Po' tmpdepfile='$(DEPDIR)/dotprod_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_r8.o `test -f 'generated/dotprod_r8.c' || echo '$(srcdir)/'`generated/dotprod_r8.c
+
+dotprod_r8.obj: generated/dotprod_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_r8.obj -MD -MP -MF "$(DEPDIR)/dotprod_r8.Tpo" -c -o dotprod_r8.obj `if test -f 'generated/dotprod_r8.c'; then $(CYGPATH_W) 'generated/dotprod_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/dotprod_r8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_r8.Tpo" "$(DEPDIR)/dotprod_r8.Po"; else rm -f "$(DEPDIR)/dotprod_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_r8.c' object='dotprod_r8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_r8.Po' tmpdepfile='$(DEPDIR)/dotprod_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_r8.obj `if test -f 'generated/dotprod_r8.c'; then $(CYGPATH_W) 'generated/dotprod_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/dotprod_r8.c'; fi`
+
+dotprod_r8.lo: generated/dotprod_r8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_r8.lo -MD -MP -MF "$(DEPDIR)/dotprod_r8.Tpo" -c -o dotprod_r8.lo `test -f 'generated/dotprod_r8.c' || echo '$(srcdir)/'`generated/dotprod_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_r8.Tpo" "$(DEPDIR)/dotprod_r8.Plo"; else rm -f "$(DEPDIR)/dotprod_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_r8.c' object='dotprod_r8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_r8.Plo' tmpdepfile='$(DEPDIR)/dotprod_r8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_r8.lo `test -f 'generated/dotprod_r8.c' || echo '$(srcdir)/'`generated/dotprod_r8.c
+
+dotprod_l4.o: generated/dotprod_l4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_l4.o -MD -MP -MF "$(DEPDIR)/dotprod_l4.Tpo" -c -o dotprod_l4.o `test -f 'generated/dotprod_l4.c' || echo '$(srcdir)/'`generated/dotprod_l4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_l4.Tpo" "$(DEPDIR)/dotprod_l4.Po"; else rm -f "$(DEPDIR)/dotprod_l4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_l4.c' object='dotprod_l4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_l4.Po' tmpdepfile='$(DEPDIR)/dotprod_l4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_l4.o `test -f 'generated/dotprod_l4.c' || echo '$(srcdir)/'`generated/dotprod_l4.c
+
+dotprod_l4.obj: generated/dotprod_l4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_l4.obj -MD -MP -MF "$(DEPDIR)/dotprod_l4.Tpo" -c -o dotprod_l4.obj `if test -f 'generated/dotprod_l4.c'; then $(CYGPATH_W) 'generated/dotprod_l4.c'; else $(CYGPATH_W) '$(srcdir)/generated/dotprod_l4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_l4.Tpo" "$(DEPDIR)/dotprod_l4.Po"; else rm -f "$(DEPDIR)/dotprod_l4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_l4.c' object='dotprod_l4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_l4.Po' tmpdepfile='$(DEPDIR)/dotprod_l4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_l4.obj `if test -f 'generated/dotprod_l4.c'; then $(CYGPATH_W) 'generated/dotprod_l4.c'; else $(CYGPATH_W) '$(srcdir)/generated/dotprod_l4.c'; fi`
+
+dotprod_l4.lo: generated/dotprod_l4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_l4.lo -MD -MP -MF "$(DEPDIR)/dotprod_l4.Tpo" -c -o dotprod_l4.lo `test -f 'generated/dotprod_l4.c' || echo '$(srcdir)/'`generated/dotprod_l4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_l4.Tpo" "$(DEPDIR)/dotprod_l4.Plo"; else rm -f "$(DEPDIR)/dotprod_l4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_l4.c' object='dotprod_l4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_l4.Plo' tmpdepfile='$(DEPDIR)/dotprod_l4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_l4.lo `test -f 'generated/dotprod_l4.c' || echo '$(srcdir)/'`generated/dotprod_l4.c
+
+dotprod_l8.o: generated/dotprod_l8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_l8.o -MD -MP -MF "$(DEPDIR)/dotprod_l8.Tpo" -c -o dotprod_l8.o `test -f 'generated/dotprod_l8.c' || echo '$(srcdir)/'`generated/dotprod_l8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_l8.Tpo" "$(DEPDIR)/dotprod_l8.Po"; else rm -f "$(DEPDIR)/dotprod_l8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_l8.c' object='dotprod_l8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_l8.Po' tmpdepfile='$(DEPDIR)/dotprod_l8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_l8.o `test -f 'generated/dotprod_l8.c' || echo '$(srcdir)/'`generated/dotprod_l8.c
+
+dotprod_l8.obj: generated/dotprod_l8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_l8.obj -MD -MP -MF "$(DEPDIR)/dotprod_l8.Tpo" -c -o dotprod_l8.obj `if test -f 'generated/dotprod_l8.c'; then $(CYGPATH_W) 'generated/dotprod_l8.c'; else $(CYGPATH_W) '$(srcdir)/generated/dotprod_l8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_l8.Tpo" "$(DEPDIR)/dotprod_l8.Po"; else rm -f "$(DEPDIR)/dotprod_l8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_l8.c' object='dotprod_l8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_l8.Po' tmpdepfile='$(DEPDIR)/dotprod_l8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_l8.obj `if test -f 'generated/dotprod_l8.c'; then $(CYGPATH_W) 'generated/dotprod_l8.c'; else $(CYGPATH_W) '$(srcdir)/generated/dotprod_l8.c'; fi`
+
+dotprod_l8.lo: generated/dotprod_l8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_l8.lo -MD -MP -MF "$(DEPDIR)/dotprod_l8.Tpo" -c -o dotprod_l8.lo `test -f 'generated/dotprod_l8.c' || echo '$(srcdir)/'`generated/dotprod_l8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_l8.Tpo" "$(DEPDIR)/dotprod_l8.Plo"; else rm -f "$(DEPDIR)/dotprod_l8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_l8.c' object='dotprod_l8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_l8.Plo' tmpdepfile='$(DEPDIR)/dotprod_l8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_l8.lo `test -f 'generated/dotprod_l8.c' || echo '$(srcdir)/'`generated/dotprod_l8.c
+
+dotprod_c4.o: generated/dotprod_c4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_c4.o -MD -MP -MF "$(DEPDIR)/dotprod_c4.Tpo" -c -o dotprod_c4.o `test -f 'generated/dotprod_c4.c' || echo '$(srcdir)/'`generated/dotprod_c4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_c4.Tpo" "$(DEPDIR)/dotprod_c4.Po"; else rm -f "$(DEPDIR)/dotprod_c4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_c4.c' object='dotprod_c4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_c4.Po' tmpdepfile='$(DEPDIR)/dotprod_c4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_c4.o `test -f 'generated/dotprod_c4.c' || echo '$(srcdir)/'`generated/dotprod_c4.c
+
+dotprod_c4.obj: generated/dotprod_c4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_c4.obj -MD -MP -MF "$(DEPDIR)/dotprod_c4.Tpo" -c -o dotprod_c4.obj `if test -f 'generated/dotprod_c4.c'; then $(CYGPATH_W) 'generated/dotprod_c4.c'; else $(CYGPATH_W) '$(srcdir)/generated/dotprod_c4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_c4.Tpo" "$(DEPDIR)/dotprod_c4.Po"; else rm -f "$(DEPDIR)/dotprod_c4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_c4.c' object='dotprod_c4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_c4.Po' tmpdepfile='$(DEPDIR)/dotprod_c4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_c4.obj `if test -f 'generated/dotprod_c4.c'; then $(CYGPATH_W) 'generated/dotprod_c4.c'; else $(CYGPATH_W) '$(srcdir)/generated/dotprod_c4.c'; fi`
+
+dotprod_c4.lo: generated/dotprod_c4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_c4.lo -MD -MP -MF "$(DEPDIR)/dotprod_c4.Tpo" -c -o dotprod_c4.lo `test -f 'generated/dotprod_c4.c' || echo '$(srcdir)/'`generated/dotprod_c4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_c4.Tpo" "$(DEPDIR)/dotprod_c4.Plo"; else rm -f "$(DEPDIR)/dotprod_c4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_c4.c' object='dotprod_c4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_c4.Plo' tmpdepfile='$(DEPDIR)/dotprod_c4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_c4.lo `test -f 'generated/dotprod_c4.c' || echo '$(srcdir)/'`generated/dotprod_c4.c
+
+dotprod_c8.o: generated/dotprod_c8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_c8.o -MD -MP -MF "$(DEPDIR)/dotprod_c8.Tpo" -c -o dotprod_c8.o `test -f 'generated/dotprod_c8.c' || echo '$(srcdir)/'`generated/dotprod_c8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_c8.Tpo" "$(DEPDIR)/dotprod_c8.Po"; else rm -f "$(DEPDIR)/dotprod_c8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_c8.c' object='dotprod_c8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_c8.Po' tmpdepfile='$(DEPDIR)/dotprod_c8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_c8.o `test -f 'generated/dotprod_c8.c' || echo '$(srcdir)/'`generated/dotprod_c8.c
+
+dotprod_c8.obj: generated/dotprod_c8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_c8.obj -MD -MP -MF "$(DEPDIR)/dotprod_c8.Tpo" -c -o dotprod_c8.obj `if test -f 'generated/dotprod_c8.c'; then $(CYGPATH_W) 'generated/dotprod_c8.c'; else $(CYGPATH_W) '$(srcdir)/generated/dotprod_c8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_c8.Tpo" "$(DEPDIR)/dotprod_c8.Po"; else rm -f "$(DEPDIR)/dotprod_c8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_c8.c' object='dotprod_c8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_c8.Po' tmpdepfile='$(DEPDIR)/dotprod_c8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_c8.obj `if test -f 'generated/dotprod_c8.c'; then $(CYGPATH_W) 'generated/dotprod_c8.c'; else $(CYGPATH_W) '$(srcdir)/generated/dotprod_c8.c'; fi`
+
+dotprod_c8.lo: generated/dotprod_c8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dotprod_c8.lo -MD -MP -MF "$(DEPDIR)/dotprod_c8.Tpo" -c -o dotprod_c8.lo `test -f 'generated/dotprod_c8.c' || echo '$(srcdir)/'`generated/dotprod_c8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/dotprod_c8.Tpo" "$(DEPDIR)/dotprod_c8.Plo"; else rm -f "$(DEPDIR)/dotprod_c8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/dotprod_c8.c' object='dotprod_c8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/dotprod_c8.Plo' tmpdepfile='$(DEPDIR)/dotprod_c8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dotprod_c8.lo `test -f 'generated/dotprod_c8.c' || echo '$(srcdir)/'`generated/dotprod_c8.c
+
+matmul_i4.o: generated/matmul_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_i4.o -MD -MP -MF "$(DEPDIR)/matmul_i4.Tpo" -c -o matmul_i4.o `test -f 'generated/matmul_i4.c' || echo '$(srcdir)/'`generated/matmul_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_i4.Tpo" "$(DEPDIR)/matmul_i4.Po"; else rm -f "$(DEPDIR)/matmul_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_i4.c' object='matmul_i4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_i4.Po' tmpdepfile='$(DEPDIR)/matmul_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_i4.o `test -f 'generated/matmul_i4.c' || echo '$(srcdir)/'`generated/matmul_i4.c
+
+matmul_i4.obj: generated/matmul_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_i4.obj -MD -MP -MF "$(DEPDIR)/matmul_i4.Tpo" -c -o matmul_i4.obj `if test -f 'generated/matmul_i4.c'; then $(CYGPATH_W) 'generated/matmul_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/matmul_i4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_i4.Tpo" "$(DEPDIR)/matmul_i4.Po"; else rm -f "$(DEPDIR)/matmul_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_i4.c' object='matmul_i4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_i4.Po' tmpdepfile='$(DEPDIR)/matmul_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_i4.obj `if test -f 'generated/matmul_i4.c'; then $(CYGPATH_W) 'generated/matmul_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/matmul_i4.c'; fi`
+
+matmul_i4.lo: generated/matmul_i4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_i4.lo -MD -MP -MF "$(DEPDIR)/matmul_i4.Tpo" -c -o matmul_i4.lo `test -f 'generated/matmul_i4.c' || echo '$(srcdir)/'`generated/matmul_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_i4.Tpo" "$(DEPDIR)/matmul_i4.Plo"; else rm -f "$(DEPDIR)/matmul_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_i4.c' object='matmul_i4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_i4.Plo' tmpdepfile='$(DEPDIR)/matmul_i4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_i4.lo `test -f 'generated/matmul_i4.c' || echo '$(srcdir)/'`generated/matmul_i4.c
+
+matmul_i8.o: generated/matmul_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_i8.o -MD -MP -MF "$(DEPDIR)/matmul_i8.Tpo" -c -o matmul_i8.o `test -f 'generated/matmul_i8.c' || echo '$(srcdir)/'`generated/matmul_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_i8.Tpo" "$(DEPDIR)/matmul_i8.Po"; else rm -f "$(DEPDIR)/matmul_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_i8.c' object='matmul_i8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_i8.Po' tmpdepfile='$(DEPDIR)/matmul_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_i8.o `test -f 'generated/matmul_i8.c' || echo '$(srcdir)/'`generated/matmul_i8.c
+
+matmul_i8.obj: generated/matmul_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_i8.obj -MD -MP -MF "$(DEPDIR)/matmul_i8.Tpo" -c -o matmul_i8.obj `if test -f 'generated/matmul_i8.c'; then $(CYGPATH_W) 'generated/matmul_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/matmul_i8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_i8.Tpo" "$(DEPDIR)/matmul_i8.Po"; else rm -f "$(DEPDIR)/matmul_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_i8.c' object='matmul_i8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_i8.Po' tmpdepfile='$(DEPDIR)/matmul_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_i8.obj `if test -f 'generated/matmul_i8.c'; then $(CYGPATH_W) 'generated/matmul_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/matmul_i8.c'; fi`
+
+matmul_i8.lo: generated/matmul_i8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_i8.lo -MD -MP -MF "$(DEPDIR)/matmul_i8.Tpo" -c -o matmul_i8.lo `test -f 'generated/matmul_i8.c' || echo '$(srcdir)/'`generated/matmul_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_i8.Tpo" "$(DEPDIR)/matmul_i8.Plo"; else rm -f "$(DEPDIR)/matmul_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_i8.c' object='matmul_i8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_i8.Plo' tmpdepfile='$(DEPDIR)/matmul_i8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_i8.lo `test -f 'generated/matmul_i8.c' || echo '$(srcdir)/'`generated/matmul_i8.c
+
+matmul_r4.o: generated/matmul_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_r4.o -MD -MP -MF "$(DEPDIR)/matmul_r4.Tpo" -c -o matmul_r4.o `test -f 'generated/matmul_r4.c' || echo '$(srcdir)/'`generated/matmul_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_r4.Tpo" "$(DEPDIR)/matmul_r4.Po"; else rm -f "$(DEPDIR)/matmul_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_r4.c' object='matmul_r4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_r4.Po' tmpdepfile='$(DEPDIR)/matmul_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_r4.o `test -f 'generated/matmul_r4.c' || echo '$(srcdir)/'`generated/matmul_r4.c
+
+matmul_r4.obj: generated/matmul_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_r4.obj -MD -MP -MF "$(DEPDIR)/matmul_r4.Tpo" -c -o matmul_r4.obj `if test -f 'generated/matmul_r4.c'; then $(CYGPATH_W) 'generated/matmul_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/matmul_r4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_r4.Tpo" "$(DEPDIR)/matmul_r4.Po"; else rm -f "$(DEPDIR)/matmul_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_r4.c' object='matmul_r4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_r4.Po' tmpdepfile='$(DEPDIR)/matmul_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_r4.obj `if test -f 'generated/matmul_r4.c'; then $(CYGPATH_W) 'generated/matmul_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/matmul_r4.c'; fi`
+
+matmul_r4.lo: generated/matmul_r4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_r4.lo -MD -MP -MF "$(DEPDIR)/matmul_r4.Tpo" -c -o matmul_r4.lo `test -f 'generated/matmul_r4.c' || echo '$(srcdir)/'`generated/matmul_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_r4.Tpo" "$(DEPDIR)/matmul_r4.Plo"; else rm -f "$(DEPDIR)/matmul_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_r4.c' object='matmul_r4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_r4.Plo' tmpdepfile='$(DEPDIR)/matmul_r4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_r4.lo `test -f 'generated/matmul_r4.c' || echo '$(srcdir)/'`generated/matmul_r4.c
+
+matmul_r8.o: generated/matmul_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_r8.o -MD -MP -MF "$(DEPDIR)/matmul_r8.Tpo" -c -o matmul_r8.o `test -f 'generated/matmul_r8.c' || echo '$(srcdir)/'`generated/matmul_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_r8.Tpo" "$(DEPDIR)/matmul_r8.Po"; else rm -f "$(DEPDIR)/matmul_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_r8.c' object='matmul_r8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_r8.Po' tmpdepfile='$(DEPDIR)/matmul_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_r8.o `test -f 'generated/matmul_r8.c' || echo '$(srcdir)/'`generated/matmul_r8.c
+
+matmul_r8.obj: generated/matmul_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_r8.obj -MD -MP -MF "$(DEPDIR)/matmul_r8.Tpo" -c -o matmul_r8.obj `if test -f 'generated/matmul_r8.c'; then $(CYGPATH_W) 'generated/matmul_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/matmul_r8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_r8.Tpo" "$(DEPDIR)/matmul_r8.Po"; else rm -f "$(DEPDIR)/matmul_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_r8.c' object='matmul_r8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_r8.Po' tmpdepfile='$(DEPDIR)/matmul_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_r8.obj `if test -f 'generated/matmul_r8.c'; then $(CYGPATH_W) 'generated/matmul_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/matmul_r8.c'; fi`
+
+matmul_r8.lo: generated/matmul_r8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_r8.lo -MD -MP -MF "$(DEPDIR)/matmul_r8.Tpo" -c -o matmul_r8.lo `test -f 'generated/matmul_r8.c' || echo '$(srcdir)/'`generated/matmul_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_r8.Tpo" "$(DEPDIR)/matmul_r8.Plo"; else rm -f "$(DEPDIR)/matmul_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_r8.c' object='matmul_r8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_r8.Plo' tmpdepfile='$(DEPDIR)/matmul_r8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_r8.lo `test -f 'generated/matmul_r8.c' || echo '$(srcdir)/'`generated/matmul_r8.c
+
+matmul_c4.o: generated/matmul_c4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_c4.o -MD -MP -MF "$(DEPDIR)/matmul_c4.Tpo" -c -o matmul_c4.o `test -f 'generated/matmul_c4.c' || echo '$(srcdir)/'`generated/matmul_c4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_c4.Tpo" "$(DEPDIR)/matmul_c4.Po"; else rm -f "$(DEPDIR)/matmul_c4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_c4.c' object='matmul_c4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_c4.Po' tmpdepfile='$(DEPDIR)/matmul_c4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_c4.o `test -f 'generated/matmul_c4.c' || echo '$(srcdir)/'`generated/matmul_c4.c
+
+matmul_c4.obj: generated/matmul_c4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_c4.obj -MD -MP -MF "$(DEPDIR)/matmul_c4.Tpo" -c -o matmul_c4.obj `if test -f 'generated/matmul_c4.c'; then $(CYGPATH_W) 'generated/matmul_c4.c'; else $(CYGPATH_W) '$(srcdir)/generated/matmul_c4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_c4.Tpo" "$(DEPDIR)/matmul_c4.Po"; else rm -f "$(DEPDIR)/matmul_c4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_c4.c' object='matmul_c4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_c4.Po' tmpdepfile='$(DEPDIR)/matmul_c4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_c4.obj `if test -f 'generated/matmul_c4.c'; then $(CYGPATH_W) 'generated/matmul_c4.c'; else $(CYGPATH_W) '$(srcdir)/generated/matmul_c4.c'; fi`
+
+matmul_c4.lo: generated/matmul_c4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_c4.lo -MD -MP -MF "$(DEPDIR)/matmul_c4.Tpo" -c -o matmul_c4.lo `test -f 'generated/matmul_c4.c' || echo '$(srcdir)/'`generated/matmul_c4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_c4.Tpo" "$(DEPDIR)/matmul_c4.Plo"; else rm -f "$(DEPDIR)/matmul_c4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_c4.c' object='matmul_c4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_c4.Plo' tmpdepfile='$(DEPDIR)/matmul_c4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_c4.lo `test -f 'generated/matmul_c4.c' || echo '$(srcdir)/'`generated/matmul_c4.c
+
+matmul_c8.o: generated/matmul_c8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_c8.o -MD -MP -MF "$(DEPDIR)/matmul_c8.Tpo" -c -o matmul_c8.o `test -f 'generated/matmul_c8.c' || echo '$(srcdir)/'`generated/matmul_c8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_c8.Tpo" "$(DEPDIR)/matmul_c8.Po"; else rm -f "$(DEPDIR)/matmul_c8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_c8.c' object='matmul_c8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_c8.Po' tmpdepfile='$(DEPDIR)/matmul_c8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_c8.o `test -f 'generated/matmul_c8.c' || echo '$(srcdir)/'`generated/matmul_c8.c
+
+matmul_c8.obj: generated/matmul_c8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_c8.obj -MD -MP -MF "$(DEPDIR)/matmul_c8.Tpo" -c -o matmul_c8.obj `if test -f 'generated/matmul_c8.c'; then $(CYGPATH_W) 'generated/matmul_c8.c'; else $(CYGPATH_W) '$(srcdir)/generated/matmul_c8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_c8.Tpo" "$(DEPDIR)/matmul_c8.Po"; else rm -f "$(DEPDIR)/matmul_c8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_c8.c' object='matmul_c8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_c8.Po' tmpdepfile='$(DEPDIR)/matmul_c8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_c8.obj `if test -f 'generated/matmul_c8.c'; then $(CYGPATH_W) 'generated/matmul_c8.c'; else $(CYGPATH_W) '$(srcdir)/generated/matmul_c8.c'; fi`
+
+matmul_c8.lo: generated/matmul_c8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_c8.lo -MD -MP -MF "$(DEPDIR)/matmul_c8.Tpo" -c -o matmul_c8.lo `test -f 'generated/matmul_c8.c' || echo '$(srcdir)/'`generated/matmul_c8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_c8.Tpo" "$(DEPDIR)/matmul_c8.Plo"; else rm -f "$(DEPDIR)/matmul_c8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_c8.c' object='matmul_c8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_c8.Plo' tmpdepfile='$(DEPDIR)/matmul_c8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_c8.lo `test -f 'generated/matmul_c8.c' || echo '$(srcdir)/'`generated/matmul_c8.c
+
+matmul_l4.o: generated/matmul_l4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_l4.o -MD -MP -MF "$(DEPDIR)/matmul_l4.Tpo" -c -o matmul_l4.o `test -f 'generated/matmul_l4.c' || echo '$(srcdir)/'`generated/matmul_l4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_l4.Tpo" "$(DEPDIR)/matmul_l4.Po"; else rm -f "$(DEPDIR)/matmul_l4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_l4.c' object='matmul_l4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_l4.Po' tmpdepfile='$(DEPDIR)/matmul_l4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_l4.o `test -f 'generated/matmul_l4.c' || echo '$(srcdir)/'`generated/matmul_l4.c
+
+matmul_l4.obj: generated/matmul_l4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_l4.obj -MD -MP -MF "$(DEPDIR)/matmul_l4.Tpo" -c -o matmul_l4.obj `if test -f 'generated/matmul_l4.c'; then $(CYGPATH_W) 'generated/matmul_l4.c'; else $(CYGPATH_W) '$(srcdir)/generated/matmul_l4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_l4.Tpo" "$(DEPDIR)/matmul_l4.Po"; else rm -f "$(DEPDIR)/matmul_l4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_l4.c' object='matmul_l4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_l4.Po' tmpdepfile='$(DEPDIR)/matmul_l4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_l4.obj `if test -f 'generated/matmul_l4.c'; then $(CYGPATH_W) 'generated/matmul_l4.c'; else $(CYGPATH_W) '$(srcdir)/generated/matmul_l4.c'; fi`
+
+matmul_l4.lo: generated/matmul_l4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_l4.lo -MD -MP -MF "$(DEPDIR)/matmul_l4.Tpo" -c -o matmul_l4.lo `test -f 'generated/matmul_l4.c' || echo '$(srcdir)/'`generated/matmul_l4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_l4.Tpo" "$(DEPDIR)/matmul_l4.Plo"; else rm -f "$(DEPDIR)/matmul_l4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_l4.c' object='matmul_l4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_l4.Plo' tmpdepfile='$(DEPDIR)/matmul_l4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_l4.lo `test -f 'generated/matmul_l4.c' || echo '$(srcdir)/'`generated/matmul_l4.c
+
+matmul_l8.o: generated/matmul_l8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_l8.o -MD -MP -MF "$(DEPDIR)/matmul_l8.Tpo" -c -o matmul_l8.o `test -f 'generated/matmul_l8.c' || echo '$(srcdir)/'`generated/matmul_l8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_l8.Tpo" "$(DEPDIR)/matmul_l8.Po"; else rm -f "$(DEPDIR)/matmul_l8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_l8.c' object='matmul_l8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_l8.Po' tmpdepfile='$(DEPDIR)/matmul_l8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_l8.o `test -f 'generated/matmul_l8.c' || echo '$(srcdir)/'`generated/matmul_l8.c
+
+matmul_l8.obj: generated/matmul_l8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_l8.obj -MD -MP -MF "$(DEPDIR)/matmul_l8.Tpo" -c -o matmul_l8.obj `if test -f 'generated/matmul_l8.c'; then $(CYGPATH_W) 'generated/matmul_l8.c'; else $(CYGPATH_W) '$(srcdir)/generated/matmul_l8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_l8.Tpo" "$(DEPDIR)/matmul_l8.Po"; else rm -f "$(DEPDIR)/matmul_l8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_l8.c' object='matmul_l8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_l8.Po' tmpdepfile='$(DEPDIR)/matmul_l8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_l8.obj `if test -f 'generated/matmul_l8.c'; then $(CYGPATH_W) 'generated/matmul_l8.c'; else $(CYGPATH_W) '$(srcdir)/generated/matmul_l8.c'; fi`
+
+matmul_l8.lo: generated/matmul_l8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT matmul_l8.lo -MD -MP -MF "$(DEPDIR)/matmul_l8.Tpo" -c -o matmul_l8.lo `test -f 'generated/matmul_l8.c' || echo '$(srcdir)/'`generated/matmul_l8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/matmul_l8.Tpo" "$(DEPDIR)/matmul_l8.Plo"; else rm -f "$(DEPDIR)/matmul_l8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/matmul_l8.c' object='matmul_l8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/matmul_l8.Plo' tmpdepfile='$(DEPDIR)/matmul_l8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o matmul_l8.lo `test -f 'generated/matmul_l8.c' || echo '$(srcdir)/'`generated/matmul_l8.c
+
+transpose_i4.o: generated/transpose_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT transpose_i4.o -MD -MP -MF "$(DEPDIR)/transpose_i4.Tpo" -c -o transpose_i4.o `test -f 'generated/transpose_i4.c' || echo '$(srcdir)/'`generated/transpose_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/transpose_i4.Tpo" "$(DEPDIR)/transpose_i4.Po"; else rm -f "$(DEPDIR)/transpose_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/transpose_i4.c' object='transpose_i4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/transpose_i4.Po' tmpdepfile='$(DEPDIR)/transpose_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o transpose_i4.o `test -f 'generated/transpose_i4.c' || echo '$(srcdir)/'`generated/transpose_i4.c
+
+transpose_i4.obj: generated/transpose_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT transpose_i4.obj -MD -MP -MF "$(DEPDIR)/transpose_i4.Tpo" -c -o transpose_i4.obj `if test -f 'generated/transpose_i4.c'; then $(CYGPATH_W) 'generated/transpose_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/transpose_i4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/transpose_i4.Tpo" "$(DEPDIR)/transpose_i4.Po"; else rm -f "$(DEPDIR)/transpose_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/transpose_i4.c' object='transpose_i4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/transpose_i4.Po' tmpdepfile='$(DEPDIR)/transpose_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o transpose_i4.obj `if test -f 'generated/transpose_i4.c'; then $(CYGPATH_W) 'generated/transpose_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/transpose_i4.c'; fi`
+
+transpose_i4.lo: generated/transpose_i4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT transpose_i4.lo -MD -MP -MF "$(DEPDIR)/transpose_i4.Tpo" -c -o transpose_i4.lo `test -f 'generated/transpose_i4.c' || echo '$(srcdir)/'`generated/transpose_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/transpose_i4.Tpo" "$(DEPDIR)/transpose_i4.Plo"; else rm -f "$(DEPDIR)/transpose_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/transpose_i4.c' object='transpose_i4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/transpose_i4.Plo' tmpdepfile='$(DEPDIR)/transpose_i4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o transpose_i4.lo `test -f 'generated/transpose_i4.c' || echo '$(srcdir)/'`generated/transpose_i4.c
+
+transpose_i8.o: generated/transpose_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT transpose_i8.o -MD -MP -MF "$(DEPDIR)/transpose_i8.Tpo" -c -o transpose_i8.o `test -f 'generated/transpose_i8.c' || echo '$(srcdir)/'`generated/transpose_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/transpose_i8.Tpo" "$(DEPDIR)/transpose_i8.Po"; else rm -f "$(DEPDIR)/transpose_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/transpose_i8.c' object='transpose_i8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/transpose_i8.Po' tmpdepfile='$(DEPDIR)/transpose_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o transpose_i8.o `test -f 'generated/transpose_i8.c' || echo '$(srcdir)/'`generated/transpose_i8.c
+
+transpose_i8.obj: generated/transpose_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT transpose_i8.obj -MD -MP -MF "$(DEPDIR)/transpose_i8.Tpo" -c -o transpose_i8.obj `if test -f 'generated/transpose_i8.c'; then $(CYGPATH_W) 'generated/transpose_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/transpose_i8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/transpose_i8.Tpo" "$(DEPDIR)/transpose_i8.Po"; else rm -f "$(DEPDIR)/transpose_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/transpose_i8.c' object='transpose_i8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/transpose_i8.Po' tmpdepfile='$(DEPDIR)/transpose_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o transpose_i8.obj `if test -f 'generated/transpose_i8.c'; then $(CYGPATH_W) 'generated/transpose_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/transpose_i8.c'; fi`
+
+transpose_i8.lo: generated/transpose_i8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT transpose_i8.lo -MD -MP -MF "$(DEPDIR)/transpose_i8.Tpo" -c -o transpose_i8.lo `test -f 'generated/transpose_i8.c' || echo '$(srcdir)/'`generated/transpose_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/transpose_i8.Tpo" "$(DEPDIR)/transpose_i8.Plo"; else rm -f "$(DEPDIR)/transpose_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/transpose_i8.c' object='transpose_i8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/transpose_i8.Plo' tmpdepfile='$(DEPDIR)/transpose_i8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o transpose_i8.lo `test -f 'generated/transpose_i8.c' || echo '$(srcdir)/'`generated/transpose_i8.c
+
+shape_i4.o: generated/shape_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shape_i4.o -MD -MP -MF "$(DEPDIR)/shape_i4.Tpo" -c -o shape_i4.o `test -f 'generated/shape_i4.c' || echo '$(srcdir)/'`generated/shape_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/shape_i4.Tpo" "$(DEPDIR)/shape_i4.Po"; else rm -f "$(DEPDIR)/shape_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/shape_i4.c' object='shape_i4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/shape_i4.Po' tmpdepfile='$(DEPDIR)/shape_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shape_i4.o `test -f 'generated/shape_i4.c' || echo '$(srcdir)/'`generated/shape_i4.c
+
+shape_i4.obj: generated/shape_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shape_i4.obj -MD -MP -MF "$(DEPDIR)/shape_i4.Tpo" -c -o shape_i4.obj `if test -f 'generated/shape_i4.c'; then $(CYGPATH_W) 'generated/shape_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/shape_i4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/shape_i4.Tpo" "$(DEPDIR)/shape_i4.Po"; else rm -f "$(DEPDIR)/shape_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/shape_i4.c' object='shape_i4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/shape_i4.Po' tmpdepfile='$(DEPDIR)/shape_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shape_i4.obj `if test -f 'generated/shape_i4.c'; then $(CYGPATH_W) 'generated/shape_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/shape_i4.c'; fi`
+
+shape_i4.lo: generated/shape_i4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shape_i4.lo -MD -MP -MF "$(DEPDIR)/shape_i4.Tpo" -c -o shape_i4.lo `test -f 'generated/shape_i4.c' || echo '$(srcdir)/'`generated/shape_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/shape_i4.Tpo" "$(DEPDIR)/shape_i4.Plo"; else rm -f "$(DEPDIR)/shape_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/shape_i4.c' object='shape_i4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/shape_i4.Plo' tmpdepfile='$(DEPDIR)/shape_i4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shape_i4.lo `test -f 'generated/shape_i4.c' || echo '$(srcdir)/'`generated/shape_i4.c
+
+shape_i8.o: generated/shape_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shape_i8.o -MD -MP -MF "$(DEPDIR)/shape_i8.Tpo" -c -o shape_i8.o `test -f 'generated/shape_i8.c' || echo '$(srcdir)/'`generated/shape_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/shape_i8.Tpo" "$(DEPDIR)/shape_i8.Po"; else rm -f "$(DEPDIR)/shape_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/shape_i8.c' object='shape_i8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/shape_i8.Po' tmpdepfile='$(DEPDIR)/shape_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shape_i8.o `test -f 'generated/shape_i8.c' || echo '$(srcdir)/'`generated/shape_i8.c
+
+shape_i8.obj: generated/shape_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shape_i8.obj -MD -MP -MF "$(DEPDIR)/shape_i8.Tpo" -c -o shape_i8.obj `if test -f 'generated/shape_i8.c'; then $(CYGPATH_W) 'generated/shape_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/shape_i8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/shape_i8.Tpo" "$(DEPDIR)/shape_i8.Po"; else rm -f "$(DEPDIR)/shape_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/shape_i8.c' object='shape_i8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/shape_i8.Po' tmpdepfile='$(DEPDIR)/shape_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shape_i8.obj `if test -f 'generated/shape_i8.c'; then $(CYGPATH_W) 'generated/shape_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/shape_i8.c'; fi`
+
+shape_i8.lo: generated/shape_i8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shape_i8.lo -MD -MP -MF "$(DEPDIR)/shape_i8.Tpo" -c -o shape_i8.lo `test -f 'generated/shape_i8.c' || echo '$(srcdir)/'`generated/shape_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/shape_i8.Tpo" "$(DEPDIR)/shape_i8.Plo"; else rm -f "$(DEPDIR)/shape_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/shape_i8.c' object='shape_i8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/shape_i8.Plo' tmpdepfile='$(DEPDIR)/shape_i8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shape_i8.lo `test -f 'generated/shape_i8.c' || echo '$(srcdir)/'`generated/shape_i8.c
+
+eoshift1_4.o: generated/eoshift1_4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eoshift1_4.o -MD -MP -MF "$(DEPDIR)/eoshift1_4.Tpo" -c -o eoshift1_4.o `test -f 'generated/eoshift1_4.c' || echo '$(srcdir)/'`generated/eoshift1_4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/eoshift1_4.Tpo" "$(DEPDIR)/eoshift1_4.Po"; else rm -f "$(DEPDIR)/eoshift1_4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/eoshift1_4.c' object='eoshift1_4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/eoshift1_4.Po' tmpdepfile='$(DEPDIR)/eoshift1_4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eoshift1_4.o `test -f 'generated/eoshift1_4.c' || echo '$(srcdir)/'`generated/eoshift1_4.c
+
+eoshift1_4.obj: generated/eoshift1_4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eoshift1_4.obj -MD -MP -MF "$(DEPDIR)/eoshift1_4.Tpo" -c -o eoshift1_4.obj `if test -f 'generated/eoshift1_4.c'; then $(CYGPATH_W) 'generated/eoshift1_4.c'; else $(CYGPATH_W) '$(srcdir)/generated/eoshift1_4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/eoshift1_4.Tpo" "$(DEPDIR)/eoshift1_4.Po"; else rm -f "$(DEPDIR)/eoshift1_4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/eoshift1_4.c' object='eoshift1_4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/eoshift1_4.Po' tmpdepfile='$(DEPDIR)/eoshift1_4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eoshift1_4.obj `if test -f 'generated/eoshift1_4.c'; then $(CYGPATH_W) 'generated/eoshift1_4.c'; else $(CYGPATH_W) '$(srcdir)/generated/eoshift1_4.c'; fi`
+
+eoshift1_4.lo: generated/eoshift1_4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eoshift1_4.lo -MD -MP -MF "$(DEPDIR)/eoshift1_4.Tpo" -c -o eoshift1_4.lo `test -f 'generated/eoshift1_4.c' || echo '$(srcdir)/'`generated/eoshift1_4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/eoshift1_4.Tpo" "$(DEPDIR)/eoshift1_4.Plo"; else rm -f "$(DEPDIR)/eoshift1_4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/eoshift1_4.c' object='eoshift1_4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/eoshift1_4.Plo' tmpdepfile='$(DEPDIR)/eoshift1_4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eoshift1_4.lo `test -f 'generated/eoshift1_4.c' || echo '$(srcdir)/'`generated/eoshift1_4.c
+
+eoshift1_8.o: generated/eoshift1_8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eoshift1_8.o -MD -MP -MF "$(DEPDIR)/eoshift1_8.Tpo" -c -o eoshift1_8.o `test -f 'generated/eoshift1_8.c' || echo '$(srcdir)/'`generated/eoshift1_8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/eoshift1_8.Tpo" "$(DEPDIR)/eoshift1_8.Po"; else rm -f "$(DEPDIR)/eoshift1_8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/eoshift1_8.c' object='eoshift1_8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/eoshift1_8.Po' tmpdepfile='$(DEPDIR)/eoshift1_8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eoshift1_8.o `test -f 'generated/eoshift1_8.c' || echo '$(srcdir)/'`generated/eoshift1_8.c
+
+eoshift1_8.obj: generated/eoshift1_8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eoshift1_8.obj -MD -MP -MF "$(DEPDIR)/eoshift1_8.Tpo" -c -o eoshift1_8.obj `if test -f 'generated/eoshift1_8.c'; then $(CYGPATH_W) 'generated/eoshift1_8.c'; else $(CYGPATH_W) '$(srcdir)/generated/eoshift1_8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/eoshift1_8.Tpo" "$(DEPDIR)/eoshift1_8.Po"; else rm -f "$(DEPDIR)/eoshift1_8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/eoshift1_8.c' object='eoshift1_8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/eoshift1_8.Po' tmpdepfile='$(DEPDIR)/eoshift1_8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eoshift1_8.obj `if test -f 'generated/eoshift1_8.c'; then $(CYGPATH_W) 'generated/eoshift1_8.c'; else $(CYGPATH_W) '$(srcdir)/generated/eoshift1_8.c'; fi`
+
+eoshift1_8.lo: generated/eoshift1_8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eoshift1_8.lo -MD -MP -MF "$(DEPDIR)/eoshift1_8.Tpo" -c -o eoshift1_8.lo `test -f 'generated/eoshift1_8.c' || echo '$(srcdir)/'`generated/eoshift1_8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/eoshift1_8.Tpo" "$(DEPDIR)/eoshift1_8.Plo"; else rm -f "$(DEPDIR)/eoshift1_8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/eoshift1_8.c' object='eoshift1_8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/eoshift1_8.Plo' tmpdepfile='$(DEPDIR)/eoshift1_8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eoshift1_8.lo `test -f 'generated/eoshift1_8.c' || echo '$(srcdir)/'`generated/eoshift1_8.c
+
+eoshift3_4.o: generated/eoshift3_4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eoshift3_4.o -MD -MP -MF "$(DEPDIR)/eoshift3_4.Tpo" -c -o eoshift3_4.o `test -f 'generated/eoshift3_4.c' || echo '$(srcdir)/'`generated/eoshift3_4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/eoshift3_4.Tpo" "$(DEPDIR)/eoshift3_4.Po"; else rm -f "$(DEPDIR)/eoshift3_4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/eoshift3_4.c' object='eoshift3_4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/eoshift3_4.Po' tmpdepfile='$(DEPDIR)/eoshift3_4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eoshift3_4.o `test -f 'generated/eoshift3_4.c' || echo '$(srcdir)/'`generated/eoshift3_4.c
+
+eoshift3_4.obj: generated/eoshift3_4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eoshift3_4.obj -MD -MP -MF "$(DEPDIR)/eoshift3_4.Tpo" -c -o eoshift3_4.obj `if test -f 'generated/eoshift3_4.c'; then $(CYGPATH_W) 'generated/eoshift3_4.c'; else $(CYGPATH_W) '$(srcdir)/generated/eoshift3_4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/eoshift3_4.Tpo" "$(DEPDIR)/eoshift3_4.Po"; else rm -f "$(DEPDIR)/eoshift3_4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/eoshift3_4.c' object='eoshift3_4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/eoshift3_4.Po' tmpdepfile='$(DEPDIR)/eoshift3_4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eoshift3_4.obj `if test -f 'generated/eoshift3_4.c'; then $(CYGPATH_W) 'generated/eoshift3_4.c'; else $(CYGPATH_W) '$(srcdir)/generated/eoshift3_4.c'; fi`
+
+eoshift3_4.lo: generated/eoshift3_4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eoshift3_4.lo -MD -MP -MF "$(DEPDIR)/eoshift3_4.Tpo" -c -o eoshift3_4.lo `test -f 'generated/eoshift3_4.c' || echo '$(srcdir)/'`generated/eoshift3_4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/eoshift3_4.Tpo" "$(DEPDIR)/eoshift3_4.Plo"; else rm -f "$(DEPDIR)/eoshift3_4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/eoshift3_4.c' object='eoshift3_4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/eoshift3_4.Plo' tmpdepfile='$(DEPDIR)/eoshift3_4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eoshift3_4.lo `test -f 'generated/eoshift3_4.c' || echo '$(srcdir)/'`generated/eoshift3_4.c
+
+eoshift3_8.o: generated/eoshift3_8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eoshift3_8.o -MD -MP -MF "$(DEPDIR)/eoshift3_8.Tpo" -c -o eoshift3_8.o `test -f 'generated/eoshift3_8.c' || echo '$(srcdir)/'`generated/eoshift3_8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/eoshift3_8.Tpo" "$(DEPDIR)/eoshift3_8.Po"; else rm -f "$(DEPDIR)/eoshift3_8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/eoshift3_8.c' object='eoshift3_8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/eoshift3_8.Po' tmpdepfile='$(DEPDIR)/eoshift3_8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eoshift3_8.o `test -f 'generated/eoshift3_8.c' || echo '$(srcdir)/'`generated/eoshift3_8.c
+
+eoshift3_8.obj: generated/eoshift3_8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eoshift3_8.obj -MD -MP -MF "$(DEPDIR)/eoshift3_8.Tpo" -c -o eoshift3_8.obj `if test -f 'generated/eoshift3_8.c'; then $(CYGPATH_W) 'generated/eoshift3_8.c'; else $(CYGPATH_W) '$(srcdir)/generated/eoshift3_8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/eoshift3_8.Tpo" "$(DEPDIR)/eoshift3_8.Po"; else rm -f "$(DEPDIR)/eoshift3_8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/eoshift3_8.c' object='eoshift3_8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/eoshift3_8.Po' tmpdepfile='$(DEPDIR)/eoshift3_8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eoshift3_8.obj `if test -f 'generated/eoshift3_8.c'; then $(CYGPATH_W) 'generated/eoshift3_8.c'; else $(CYGPATH_W) '$(srcdir)/generated/eoshift3_8.c'; fi`
+
+eoshift3_8.lo: generated/eoshift3_8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eoshift3_8.lo -MD -MP -MF "$(DEPDIR)/eoshift3_8.Tpo" -c -o eoshift3_8.lo `test -f 'generated/eoshift3_8.c' || echo '$(srcdir)/'`generated/eoshift3_8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/eoshift3_8.Tpo" "$(DEPDIR)/eoshift3_8.Plo"; else rm -f "$(DEPDIR)/eoshift3_8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/eoshift3_8.c' object='eoshift3_8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/eoshift3_8.Plo' tmpdepfile='$(DEPDIR)/eoshift3_8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eoshift3_8.lo `test -f 'generated/eoshift3_8.c' || echo '$(srcdir)/'`generated/eoshift3_8.c
+
+cshift1_4.o: generated/cshift1_4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cshift1_4.o -MD -MP -MF "$(DEPDIR)/cshift1_4.Tpo" -c -o cshift1_4.o `test -f 'generated/cshift1_4.c' || echo '$(srcdir)/'`generated/cshift1_4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/cshift1_4.Tpo" "$(DEPDIR)/cshift1_4.Po"; else rm -f "$(DEPDIR)/cshift1_4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/cshift1_4.c' object='cshift1_4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/cshift1_4.Po' tmpdepfile='$(DEPDIR)/cshift1_4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cshift1_4.o `test -f 'generated/cshift1_4.c' || echo '$(srcdir)/'`generated/cshift1_4.c
+
+cshift1_4.obj: generated/cshift1_4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cshift1_4.obj -MD -MP -MF "$(DEPDIR)/cshift1_4.Tpo" -c -o cshift1_4.obj `if test -f 'generated/cshift1_4.c'; then $(CYGPATH_W) 'generated/cshift1_4.c'; else $(CYGPATH_W) '$(srcdir)/generated/cshift1_4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/cshift1_4.Tpo" "$(DEPDIR)/cshift1_4.Po"; else rm -f "$(DEPDIR)/cshift1_4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/cshift1_4.c' object='cshift1_4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/cshift1_4.Po' tmpdepfile='$(DEPDIR)/cshift1_4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cshift1_4.obj `if test -f 'generated/cshift1_4.c'; then $(CYGPATH_W) 'generated/cshift1_4.c'; else $(CYGPATH_W) '$(srcdir)/generated/cshift1_4.c'; fi`
+
+cshift1_4.lo: generated/cshift1_4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cshift1_4.lo -MD -MP -MF "$(DEPDIR)/cshift1_4.Tpo" -c -o cshift1_4.lo `test -f 'generated/cshift1_4.c' || echo '$(srcdir)/'`generated/cshift1_4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/cshift1_4.Tpo" "$(DEPDIR)/cshift1_4.Plo"; else rm -f "$(DEPDIR)/cshift1_4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/cshift1_4.c' object='cshift1_4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/cshift1_4.Plo' tmpdepfile='$(DEPDIR)/cshift1_4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cshift1_4.lo `test -f 'generated/cshift1_4.c' || echo '$(srcdir)/'`generated/cshift1_4.c
+
+cshift1_8.o: generated/cshift1_8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cshift1_8.o -MD -MP -MF "$(DEPDIR)/cshift1_8.Tpo" -c -o cshift1_8.o `test -f 'generated/cshift1_8.c' || echo '$(srcdir)/'`generated/cshift1_8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/cshift1_8.Tpo" "$(DEPDIR)/cshift1_8.Po"; else rm -f "$(DEPDIR)/cshift1_8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/cshift1_8.c' object='cshift1_8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/cshift1_8.Po' tmpdepfile='$(DEPDIR)/cshift1_8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cshift1_8.o `test -f 'generated/cshift1_8.c' || echo '$(srcdir)/'`generated/cshift1_8.c
+
+cshift1_8.obj: generated/cshift1_8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cshift1_8.obj -MD -MP -MF "$(DEPDIR)/cshift1_8.Tpo" -c -o cshift1_8.obj `if test -f 'generated/cshift1_8.c'; then $(CYGPATH_W) 'generated/cshift1_8.c'; else $(CYGPATH_W) '$(srcdir)/generated/cshift1_8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/cshift1_8.Tpo" "$(DEPDIR)/cshift1_8.Po"; else rm -f "$(DEPDIR)/cshift1_8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/cshift1_8.c' object='cshift1_8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/cshift1_8.Po' tmpdepfile='$(DEPDIR)/cshift1_8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cshift1_8.obj `if test -f 'generated/cshift1_8.c'; then $(CYGPATH_W) 'generated/cshift1_8.c'; else $(CYGPATH_W) '$(srcdir)/generated/cshift1_8.c'; fi`
+
+cshift1_8.lo: generated/cshift1_8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cshift1_8.lo -MD -MP -MF "$(DEPDIR)/cshift1_8.Tpo" -c -o cshift1_8.lo `test -f 'generated/cshift1_8.c' || echo '$(srcdir)/'`generated/cshift1_8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/cshift1_8.Tpo" "$(DEPDIR)/cshift1_8.Plo"; else rm -f "$(DEPDIR)/cshift1_8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/cshift1_8.c' object='cshift1_8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/cshift1_8.Plo' tmpdepfile='$(DEPDIR)/cshift1_8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cshift1_8.lo `test -f 'generated/cshift1_8.c' || echo '$(srcdir)/'`generated/cshift1_8.c
+
+reshape_i4.o: generated/reshape_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT reshape_i4.o -MD -MP -MF "$(DEPDIR)/reshape_i4.Tpo" -c -o reshape_i4.o `test -f 'generated/reshape_i4.c' || echo '$(srcdir)/'`generated/reshape_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/reshape_i4.Tpo" "$(DEPDIR)/reshape_i4.Po"; else rm -f "$(DEPDIR)/reshape_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/reshape_i4.c' object='reshape_i4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/reshape_i4.Po' tmpdepfile='$(DEPDIR)/reshape_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o reshape_i4.o `test -f 'generated/reshape_i4.c' || echo '$(srcdir)/'`generated/reshape_i4.c
+
+reshape_i4.obj: generated/reshape_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT reshape_i4.obj -MD -MP -MF "$(DEPDIR)/reshape_i4.Tpo" -c -o reshape_i4.obj `if test -f 'generated/reshape_i4.c'; then $(CYGPATH_W) 'generated/reshape_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/reshape_i4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/reshape_i4.Tpo" "$(DEPDIR)/reshape_i4.Po"; else rm -f "$(DEPDIR)/reshape_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/reshape_i4.c' object='reshape_i4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/reshape_i4.Po' tmpdepfile='$(DEPDIR)/reshape_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o reshape_i4.obj `if test -f 'generated/reshape_i4.c'; then $(CYGPATH_W) 'generated/reshape_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/reshape_i4.c'; fi`
+
+reshape_i4.lo: generated/reshape_i4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT reshape_i4.lo -MD -MP -MF "$(DEPDIR)/reshape_i4.Tpo" -c -o reshape_i4.lo `test -f 'generated/reshape_i4.c' || echo '$(srcdir)/'`generated/reshape_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/reshape_i4.Tpo" "$(DEPDIR)/reshape_i4.Plo"; else rm -f "$(DEPDIR)/reshape_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/reshape_i4.c' object='reshape_i4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/reshape_i4.Plo' tmpdepfile='$(DEPDIR)/reshape_i4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o reshape_i4.lo `test -f 'generated/reshape_i4.c' || echo '$(srcdir)/'`generated/reshape_i4.c
+
+reshape_i8.o: generated/reshape_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT reshape_i8.o -MD -MP -MF "$(DEPDIR)/reshape_i8.Tpo" -c -o reshape_i8.o `test -f 'generated/reshape_i8.c' || echo '$(srcdir)/'`generated/reshape_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/reshape_i8.Tpo" "$(DEPDIR)/reshape_i8.Po"; else rm -f "$(DEPDIR)/reshape_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/reshape_i8.c' object='reshape_i8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/reshape_i8.Po' tmpdepfile='$(DEPDIR)/reshape_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o reshape_i8.o `test -f 'generated/reshape_i8.c' || echo '$(srcdir)/'`generated/reshape_i8.c
+
+reshape_i8.obj: generated/reshape_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT reshape_i8.obj -MD -MP -MF "$(DEPDIR)/reshape_i8.Tpo" -c -o reshape_i8.obj `if test -f 'generated/reshape_i8.c'; then $(CYGPATH_W) 'generated/reshape_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/reshape_i8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/reshape_i8.Tpo" "$(DEPDIR)/reshape_i8.Po"; else rm -f "$(DEPDIR)/reshape_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/reshape_i8.c' object='reshape_i8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/reshape_i8.Po' tmpdepfile='$(DEPDIR)/reshape_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o reshape_i8.obj `if test -f 'generated/reshape_i8.c'; then $(CYGPATH_W) 'generated/reshape_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/reshape_i8.c'; fi`
+
+reshape_i8.lo: generated/reshape_i8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT reshape_i8.lo -MD -MP -MF "$(DEPDIR)/reshape_i8.Tpo" -c -o reshape_i8.lo `test -f 'generated/reshape_i8.c' || echo '$(srcdir)/'`generated/reshape_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/reshape_i8.Tpo" "$(DEPDIR)/reshape_i8.Plo"; else rm -f "$(DEPDIR)/reshape_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/reshape_i8.c' object='reshape_i8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/reshape_i8.Plo' tmpdepfile='$(DEPDIR)/reshape_i8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o reshape_i8.lo `test -f 'generated/reshape_i8.c' || echo '$(srcdir)/'`generated/reshape_i8.c
+
+in_pack_i4.o: generated/in_pack_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT in_pack_i4.o -MD -MP -MF "$(DEPDIR)/in_pack_i4.Tpo" -c -o in_pack_i4.o `test -f 'generated/in_pack_i4.c' || echo '$(srcdir)/'`generated/in_pack_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/in_pack_i4.Tpo" "$(DEPDIR)/in_pack_i4.Po"; else rm -f "$(DEPDIR)/in_pack_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/in_pack_i4.c' object='in_pack_i4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/in_pack_i4.Po' tmpdepfile='$(DEPDIR)/in_pack_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o in_pack_i4.o `test -f 'generated/in_pack_i4.c' || echo '$(srcdir)/'`generated/in_pack_i4.c
+
+in_pack_i4.obj: generated/in_pack_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT in_pack_i4.obj -MD -MP -MF "$(DEPDIR)/in_pack_i4.Tpo" -c -o in_pack_i4.obj `if test -f 'generated/in_pack_i4.c'; then $(CYGPATH_W) 'generated/in_pack_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/in_pack_i4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/in_pack_i4.Tpo" "$(DEPDIR)/in_pack_i4.Po"; else rm -f "$(DEPDIR)/in_pack_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/in_pack_i4.c' object='in_pack_i4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/in_pack_i4.Po' tmpdepfile='$(DEPDIR)/in_pack_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o in_pack_i4.obj `if test -f 'generated/in_pack_i4.c'; then $(CYGPATH_W) 'generated/in_pack_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/in_pack_i4.c'; fi`
+
+in_pack_i4.lo: generated/in_pack_i4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT in_pack_i4.lo -MD -MP -MF "$(DEPDIR)/in_pack_i4.Tpo" -c -o in_pack_i4.lo `test -f 'generated/in_pack_i4.c' || echo '$(srcdir)/'`generated/in_pack_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/in_pack_i4.Tpo" "$(DEPDIR)/in_pack_i4.Plo"; else rm -f "$(DEPDIR)/in_pack_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/in_pack_i4.c' object='in_pack_i4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/in_pack_i4.Plo' tmpdepfile='$(DEPDIR)/in_pack_i4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o in_pack_i4.lo `test -f 'generated/in_pack_i4.c' || echo '$(srcdir)/'`generated/in_pack_i4.c
+
+in_pack_i8.o: generated/in_pack_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT in_pack_i8.o -MD -MP -MF "$(DEPDIR)/in_pack_i8.Tpo" -c -o in_pack_i8.o `test -f 'generated/in_pack_i8.c' || echo '$(srcdir)/'`generated/in_pack_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/in_pack_i8.Tpo" "$(DEPDIR)/in_pack_i8.Po"; else rm -f "$(DEPDIR)/in_pack_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/in_pack_i8.c' object='in_pack_i8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/in_pack_i8.Po' tmpdepfile='$(DEPDIR)/in_pack_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o in_pack_i8.o `test -f 'generated/in_pack_i8.c' || echo '$(srcdir)/'`generated/in_pack_i8.c
+
+in_pack_i8.obj: generated/in_pack_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT in_pack_i8.obj -MD -MP -MF "$(DEPDIR)/in_pack_i8.Tpo" -c -o in_pack_i8.obj `if test -f 'generated/in_pack_i8.c'; then $(CYGPATH_W) 'generated/in_pack_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/in_pack_i8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/in_pack_i8.Tpo" "$(DEPDIR)/in_pack_i8.Po"; else rm -f "$(DEPDIR)/in_pack_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/in_pack_i8.c' object='in_pack_i8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/in_pack_i8.Po' tmpdepfile='$(DEPDIR)/in_pack_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o in_pack_i8.obj `if test -f 'generated/in_pack_i8.c'; then $(CYGPATH_W) 'generated/in_pack_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/in_pack_i8.c'; fi`
+
+in_pack_i8.lo: generated/in_pack_i8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT in_pack_i8.lo -MD -MP -MF "$(DEPDIR)/in_pack_i8.Tpo" -c -o in_pack_i8.lo `test -f 'generated/in_pack_i8.c' || echo '$(srcdir)/'`generated/in_pack_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/in_pack_i8.Tpo" "$(DEPDIR)/in_pack_i8.Plo"; else rm -f "$(DEPDIR)/in_pack_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/in_pack_i8.c' object='in_pack_i8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/in_pack_i8.Plo' tmpdepfile='$(DEPDIR)/in_pack_i8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o in_pack_i8.lo `test -f 'generated/in_pack_i8.c' || echo '$(srcdir)/'`generated/in_pack_i8.c
+
+in_unpack_i4.o: generated/in_unpack_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT in_unpack_i4.o -MD -MP -MF "$(DEPDIR)/in_unpack_i4.Tpo" -c -o in_unpack_i4.o `test -f 'generated/in_unpack_i4.c' || echo '$(srcdir)/'`generated/in_unpack_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/in_unpack_i4.Tpo" "$(DEPDIR)/in_unpack_i4.Po"; else rm -f "$(DEPDIR)/in_unpack_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/in_unpack_i4.c' object='in_unpack_i4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/in_unpack_i4.Po' tmpdepfile='$(DEPDIR)/in_unpack_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o in_unpack_i4.o `test -f 'generated/in_unpack_i4.c' || echo '$(srcdir)/'`generated/in_unpack_i4.c
+
+in_unpack_i4.obj: generated/in_unpack_i4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT in_unpack_i4.obj -MD -MP -MF "$(DEPDIR)/in_unpack_i4.Tpo" -c -o in_unpack_i4.obj `if test -f 'generated/in_unpack_i4.c'; then $(CYGPATH_W) 'generated/in_unpack_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/in_unpack_i4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/in_unpack_i4.Tpo" "$(DEPDIR)/in_unpack_i4.Po"; else rm -f "$(DEPDIR)/in_unpack_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/in_unpack_i4.c' object='in_unpack_i4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/in_unpack_i4.Po' tmpdepfile='$(DEPDIR)/in_unpack_i4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o in_unpack_i4.obj `if test -f 'generated/in_unpack_i4.c'; then $(CYGPATH_W) 'generated/in_unpack_i4.c'; else $(CYGPATH_W) '$(srcdir)/generated/in_unpack_i4.c'; fi`
+
+in_unpack_i4.lo: generated/in_unpack_i4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT in_unpack_i4.lo -MD -MP -MF "$(DEPDIR)/in_unpack_i4.Tpo" -c -o in_unpack_i4.lo `test -f 'generated/in_unpack_i4.c' || echo '$(srcdir)/'`generated/in_unpack_i4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/in_unpack_i4.Tpo" "$(DEPDIR)/in_unpack_i4.Plo"; else rm -f "$(DEPDIR)/in_unpack_i4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/in_unpack_i4.c' object='in_unpack_i4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/in_unpack_i4.Plo' tmpdepfile='$(DEPDIR)/in_unpack_i4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o in_unpack_i4.lo `test -f 'generated/in_unpack_i4.c' || echo '$(srcdir)/'`generated/in_unpack_i4.c
+
+in_unpack_i8.o: generated/in_unpack_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT in_unpack_i8.o -MD -MP -MF "$(DEPDIR)/in_unpack_i8.Tpo" -c -o in_unpack_i8.o `test -f 'generated/in_unpack_i8.c' || echo '$(srcdir)/'`generated/in_unpack_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/in_unpack_i8.Tpo" "$(DEPDIR)/in_unpack_i8.Po"; else rm -f "$(DEPDIR)/in_unpack_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/in_unpack_i8.c' object='in_unpack_i8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/in_unpack_i8.Po' tmpdepfile='$(DEPDIR)/in_unpack_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o in_unpack_i8.o `test -f 'generated/in_unpack_i8.c' || echo '$(srcdir)/'`generated/in_unpack_i8.c
+
+in_unpack_i8.obj: generated/in_unpack_i8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT in_unpack_i8.obj -MD -MP -MF "$(DEPDIR)/in_unpack_i8.Tpo" -c -o in_unpack_i8.obj `if test -f 'generated/in_unpack_i8.c'; then $(CYGPATH_W) 'generated/in_unpack_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/in_unpack_i8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/in_unpack_i8.Tpo" "$(DEPDIR)/in_unpack_i8.Po"; else rm -f "$(DEPDIR)/in_unpack_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/in_unpack_i8.c' object='in_unpack_i8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/in_unpack_i8.Po' tmpdepfile='$(DEPDIR)/in_unpack_i8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o in_unpack_i8.obj `if test -f 'generated/in_unpack_i8.c'; then $(CYGPATH_W) 'generated/in_unpack_i8.c'; else $(CYGPATH_W) '$(srcdir)/generated/in_unpack_i8.c'; fi`
+
+in_unpack_i8.lo: generated/in_unpack_i8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT in_unpack_i8.lo -MD -MP -MF "$(DEPDIR)/in_unpack_i8.Tpo" -c -o in_unpack_i8.lo `test -f 'generated/in_unpack_i8.c' || echo '$(srcdir)/'`generated/in_unpack_i8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/in_unpack_i8.Tpo" "$(DEPDIR)/in_unpack_i8.Plo"; else rm -f "$(DEPDIR)/in_unpack_i8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/in_unpack_i8.c' object='in_unpack_i8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/in_unpack_i8.Plo' tmpdepfile='$(DEPDIR)/in_unpack_i8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o in_unpack_i8.lo `test -f 'generated/in_unpack_i8.c' || echo '$(srcdir)/'`generated/in_unpack_i8.c
+
+exponent_r4.o: generated/exponent_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT exponent_r4.o -MD -MP -MF "$(DEPDIR)/exponent_r4.Tpo" -c -o exponent_r4.o `test -f 'generated/exponent_r4.c' || echo '$(srcdir)/'`generated/exponent_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/exponent_r4.Tpo" "$(DEPDIR)/exponent_r4.Po"; else rm -f "$(DEPDIR)/exponent_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/exponent_r4.c' object='exponent_r4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/exponent_r4.Po' tmpdepfile='$(DEPDIR)/exponent_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o exponent_r4.o `test -f 'generated/exponent_r4.c' || echo '$(srcdir)/'`generated/exponent_r4.c
+
+exponent_r4.obj: generated/exponent_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT exponent_r4.obj -MD -MP -MF "$(DEPDIR)/exponent_r4.Tpo" -c -o exponent_r4.obj `if test -f 'generated/exponent_r4.c'; then $(CYGPATH_W) 'generated/exponent_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/exponent_r4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/exponent_r4.Tpo" "$(DEPDIR)/exponent_r4.Po"; else rm -f "$(DEPDIR)/exponent_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/exponent_r4.c' object='exponent_r4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/exponent_r4.Po' tmpdepfile='$(DEPDIR)/exponent_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o exponent_r4.obj `if test -f 'generated/exponent_r4.c'; then $(CYGPATH_W) 'generated/exponent_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/exponent_r4.c'; fi`
+
+exponent_r4.lo: generated/exponent_r4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT exponent_r4.lo -MD -MP -MF "$(DEPDIR)/exponent_r4.Tpo" -c -o exponent_r4.lo `test -f 'generated/exponent_r4.c' || echo '$(srcdir)/'`generated/exponent_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/exponent_r4.Tpo" "$(DEPDIR)/exponent_r4.Plo"; else rm -f "$(DEPDIR)/exponent_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/exponent_r4.c' object='exponent_r4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/exponent_r4.Plo' tmpdepfile='$(DEPDIR)/exponent_r4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o exponent_r4.lo `test -f 'generated/exponent_r4.c' || echo '$(srcdir)/'`generated/exponent_r4.c
+
+exponent_r8.o: generated/exponent_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT exponent_r8.o -MD -MP -MF "$(DEPDIR)/exponent_r8.Tpo" -c -o exponent_r8.o `test -f 'generated/exponent_r8.c' || echo '$(srcdir)/'`generated/exponent_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/exponent_r8.Tpo" "$(DEPDIR)/exponent_r8.Po"; else rm -f "$(DEPDIR)/exponent_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/exponent_r8.c' object='exponent_r8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/exponent_r8.Po' tmpdepfile='$(DEPDIR)/exponent_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o exponent_r8.o `test -f 'generated/exponent_r8.c' || echo '$(srcdir)/'`generated/exponent_r8.c
+
+exponent_r8.obj: generated/exponent_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT exponent_r8.obj -MD -MP -MF "$(DEPDIR)/exponent_r8.Tpo" -c -o exponent_r8.obj `if test -f 'generated/exponent_r8.c'; then $(CYGPATH_W) 'generated/exponent_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/exponent_r8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/exponent_r8.Tpo" "$(DEPDIR)/exponent_r8.Po"; else rm -f "$(DEPDIR)/exponent_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/exponent_r8.c' object='exponent_r8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/exponent_r8.Po' tmpdepfile='$(DEPDIR)/exponent_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o exponent_r8.obj `if test -f 'generated/exponent_r8.c'; then $(CYGPATH_W) 'generated/exponent_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/exponent_r8.c'; fi`
+
+exponent_r8.lo: generated/exponent_r8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT exponent_r8.lo -MD -MP -MF "$(DEPDIR)/exponent_r8.Tpo" -c -o exponent_r8.lo `test -f 'generated/exponent_r8.c' || echo '$(srcdir)/'`generated/exponent_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/exponent_r8.Tpo" "$(DEPDIR)/exponent_r8.Plo"; else rm -f "$(DEPDIR)/exponent_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/exponent_r8.c' object='exponent_r8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/exponent_r8.Plo' tmpdepfile='$(DEPDIR)/exponent_r8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o exponent_r8.lo `test -f 'generated/exponent_r8.c' || echo '$(srcdir)/'`generated/exponent_r8.c
+
+fraction_r4.o: generated/fraction_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fraction_r4.o -MD -MP -MF "$(DEPDIR)/fraction_r4.Tpo" -c -o fraction_r4.o `test -f 'generated/fraction_r4.c' || echo '$(srcdir)/'`generated/fraction_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/fraction_r4.Tpo" "$(DEPDIR)/fraction_r4.Po"; else rm -f "$(DEPDIR)/fraction_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/fraction_r4.c' object='fraction_r4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/fraction_r4.Po' tmpdepfile='$(DEPDIR)/fraction_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fraction_r4.o `test -f 'generated/fraction_r4.c' || echo '$(srcdir)/'`generated/fraction_r4.c
+
+fraction_r4.obj: generated/fraction_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fraction_r4.obj -MD -MP -MF "$(DEPDIR)/fraction_r4.Tpo" -c -o fraction_r4.obj `if test -f 'generated/fraction_r4.c'; then $(CYGPATH_W) 'generated/fraction_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/fraction_r4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/fraction_r4.Tpo" "$(DEPDIR)/fraction_r4.Po"; else rm -f "$(DEPDIR)/fraction_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/fraction_r4.c' object='fraction_r4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/fraction_r4.Po' tmpdepfile='$(DEPDIR)/fraction_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fraction_r4.obj `if test -f 'generated/fraction_r4.c'; then $(CYGPATH_W) 'generated/fraction_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/fraction_r4.c'; fi`
+
+fraction_r4.lo: generated/fraction_r4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fraction_r4.lo -MD -MP -MF "$(DEPDIR)/fraction_r4.Tpo" -c -o fraction_r4.lo `test -f 'generated/fraction_r4.c' || echo '$(srcdir)/'`generated/fraction_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/fraction_r4.Tpo" "$(DEPDIR)/fraction_r4.Plo"; else rm -f "$(DEPDIR)/fraction_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/fraction_r4.c' object='fraction_r4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/fraction_r4.Plo' tmpdepfile='$(DEPDIR)/fraction_r4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fraction_r4.lo `test -f 'generated/fraction_r4.c' || echo '$(srcdir)/'`generated/fraction_r4.c
+
+fraction_r8.o: generated/fraction_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fraction_r8.o -MD -MP -MF "$(DEPDIR)/fraction_r8.Tpo" -c -o fraction_r8.o `test -f 'generated/fraction_r8.c' || echo '$(srcdir)/'`generated/fraction_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/fraction_r8.Tpo" "$(DEPDIR)/fraction_r8.Po"; else rm -f "$(DEPDIR)/fraction_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/fraction_r8.c' object='fraction_r8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/fraction_r8.Po' tmpdepfile='$(DEPDIR)/fraction_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fraction_r8.o `test -f 'generated/fraction_r8.c' || echo '$(srcdir)/'`generated/fraction_r8.c
+
+fraction_r8.obj: generated/fraction_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fraction_r8.obj -MD -MP -MF "$(DEPDIR)/fraction_r8.Tpo" -c -o fraction_r8.obj `if test -f 'generated/fraction_r8.c'; then $(CYGPATH_W) 'generated/fraction_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/fraction_r8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/fraction_r8.Tpo" "$(DEPDIR)/fraction_r8.Po"; else rm -f "$(DEPDIR)/fraction_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/fraction_r8.c' object='fraction_r8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/fraction_r8.Po' tmpdepfile='$(DEPDIR)/fraction_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fraction_r8.obj `if test -f 'generated/fraction_r8.c'; then $(CYGPATH_W) 'generated/fraction_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/fraction_r8.c'; fi`
+
+fraction_r8.lo: generated/fraction_r8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fraction_r8.lo -MD -MP -MF "$(DEPDIR)/fraction_r8.Tpo" -c -o fraction_r8.lo `test -f 'generated/fraction_r8.c' || echo '$(srcdir)/'`generated/fraction_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/fraction_r8.Tpo" "$(DEPDIR)/fraction_r8.Plo"; else rm -f "$(DEPDIR)/fraction_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/fraction_r8.c' object='fraction_r8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/fraction_r8.Plo' tmpdepfile='$(DEPDIR)/fraction_r8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fraction_r8.lo `test -f 'generated/fraction_r8.c' || echo '$(srcdir)/'`generated/fraction_r8.c
+
+nearest_r4.o: generated/nearest_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nearest_r4.o -MD -MP -MF "$(DEPDIR)/nearest_r4.Tpo" -c -o nearest_r4.o `test -f 'generated/nearest_r4.c' || echo '$(srcdir)/'`generated/nearest_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/nearest_r4.Tpo" "$(DEPDIR)/nearest_r4.Po"; else rm -f "$(DEPDIR)/nearest_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/nearest_r4.c' object='nearest_r4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/nearest_r4.Po' tmpdepfile='$(DEPDIR)/nearest_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nearest_r4.o `test -f 'generated/nearest_r4.c' || echo '$(srcdir)/'`generated/nearest_r4.c
+
+nearest_r4.obj: generated/nearest_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nearest_r4.obj -MD -MP -MF "$(DEPDIR)/nearest_r4.Tpo" -c -o nearest_r4.obj `if test -f 'generated/nearest_r4.c'; then $(CYGPATH_W) 'generated/nearest_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/nearest_r4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/nearest_r4.Tpo" "$(DEPDIR)/nearest_r4.Po"; else rm -f "$(DEPDIR)/nearest_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/nearest_r4.c' object='nearest_r4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/nearest_r4.Po' tmpdepfile='$(DEPDIR)/nearest_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nearest_r4.obj `if test -f 'generated/nearest_r4.c'; then $(CYGPATH_W) 'generated/nearest_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/nearest_r4.c'; fi`
+
+nearest_r4.lo: generated/nearest_r4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nearest_r4.lo -MD -MP -MF "$(DEPDIR)/nearest_r4.Tpo" -c -o nearest_r4.lo `test -f 'generated/nearest_r4.c' || echo '$(srcdir)/'`generated/nearest_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/nearest_r4.Tpo" "$(DEPDIR)/nearest_r4.Plo"; else rm -f "$(DEPDIR)/nearest_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/nearest_r4.c' object='nearest_r4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/nearest_r4.Plo' tmpdepfile='$(DEPDIR)/nearest_r4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nearest_r4.lo `test -f 'generated/nearest_r4.c' || echo '$(srcdir)/'`generated/nearest_r4.c
+
+nearest_r8.o: generated/nearest_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nearest_r8.o -MD -MP -MF "$(DEPDIR)/nearest_r8.Tpo" -c -o nearest_r8.o `test -f 'generated/nearest_r8.c' || echo '$(srcdir)/'`generated/nearest_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/nearest_r8.Tpo" "$(DEPDIR)/nearest_r8.Po"; else rm -f "$(DEPDIR)/nearest_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/nearest_r8.c' object='nearest_r8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/nearest_r8.Po' tmpdepfile='$(DEPDIR)/nearest_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nearest_r8.o `test -f 'generated/nearest_r8.c' || echo '$(srcdir)/'`generated/nearest_r8.c
+
+nearest_r8.obj: generated/nearest_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nearest_r8.obj -MD -MP -MF "$(DEPDIR)/nearest_r8.Tpo" -c -o nearest_r8.obj `if test -f 'generated/nearest_r8.c'; then $(CYGPATH_W) 'generated/nearest_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/nearest_r8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/nearest_r8.Tpo" "$(DEPDIR)/nearest_r8.Po"; else rm -f "$(DEPDIR)/nearest_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/nearest_r8.c' object='nearest_r8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/nearest_r8.Po' tmpdepfile='$(DEPDIR)/nearest_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nearest_r8.obj `if test -f 'generated/nearest_r8.c'; then $(CYGPATH_W) 'generated/nearest_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/nearest_r8.c'; fi`
+
+nearest_r8.lo: generated/nearest_r8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nearest_r8.lo -MD -MP -MF "$(DEPDIR)/nearest_r8.Tpo" -c -o nearest_r8.lo `test -f 'generated/nearest_r8.c' || echo '$(srcdir)/'`generated/nearest_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/nearest_r8.Tpo" "$(DEPDIR)/nearest_r8.Plo"; else rm -f "$(DEPDIR)/nearest_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/nearest_r8.c' object='nearest_r8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/nearest_r8.Plo' tmpdepfile='$(DEPDIR)/nearest_r8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nearest_r8.lo `test -f 'generated/nearest_r8.c' || echo '$(srcdir)/'`generated/nearest_r8.c
+
+set_exponent_r4.o: generated/set_exponent_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT set_exponent_r4.o -MD -MP -MF "$(DEPDIR)/set_exponent_r4.Tpo" -c -o set_exponent_r4.o `test -f 'generated/set_exponent_r4.c' || echo '$(srcdir)/'`generated/set_exponent_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/set_exponent_r4.Tpo" "$(DEPDIR)/set_exponent_r4.Po"; else rm -f "$(DEPDIR)/set_exponent_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/set_exponent_r4.c' object='set_exponent_r4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/set_exponent_r4.Po' tmpdepfile='$(DEPDIR)/set_exponent_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o set_exponent_r4.o `test -f 'generated/set_exponent_r4.c' || echo '$(srcdir)/'`generated/set_exponent_r4.c
+
+set_exponent_r4.obj: generated/set_exponent_r4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT set_exponent_r4.obj -MD -MP -MF "$(DEPDIR)/set_exponent_r4.Tpo" -c -o set_exponent_r4.obj `if test -f 'generated/set_exponent_r4.c'; then $(CYGPATH_W) 'generated/set_exponent_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/set_exponent_r4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/set_exponent_r4.Tpo" "$(DEPDIR)/set_exponent_r4.Po"; else rm -f "$(DEPDIR)/set_exponent_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/set_exponent_r4.c' object='set_exponent_r4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/set_exponent_r4.Po' tmpdepfile='$(DEPDIR)/set_exponent_r4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o set_exponent_r4.obj `if test -f 'generated/set_exponent_r4.c'; then $(CYGPATH_W) 'generated/set_exponent_r4.c'; else $(CYGPATH_W) '$(srcdir)/generated/set_exponent_r4.c'; fi`
+
+set_exponent_r4.lo: generated/set_exponent_r4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT set_exponent_r4.lo -MD -MP -MF "$(DEPDIR)/set_exponent_r4.Tpo" -c -o set_exponent_r4.lo `test -f 'generated/set_exponent_r4.c' || echo '$(srcdir)/'`generated/set_exponent_r4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/set_exponent_r4.Tpo" "$(DEPDIR)/set_exponent_r4.Plo"; else rm -f "$(DEPDIR)/set_exponent_r4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/set_exponent_r4.c' object='set_exponent_r4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/set_exponent_r4.Plo' tmpdepfile='$(DEPDIR)/set_exponent_r4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o set_exponent_r4.lo `test -f 'generated/set_exponent_r4.c' || echo '$(srcdir)/'`generated/set_exponent_r4.c
+
+set_exponent_r8.o: generated/set_exponent_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT set_exponent_r8.o -MD -MP -MF "$(DEPDIR)/set_exponent_r8.Tpo" -c -o set_exponent_r8.o `test -f 'generated/set_exponent_r8.c' || echo '$(srcdir)/'`generated/set_exponent_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/set_exponent_r8.Tpo" "$(DEPDIR)/set_exponent_r8.Po"; else rm -f "$(DEPDIR)/set_exponent_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/set_exponent_r8.c' object='set_exponent_r8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/set_exponent_r8.Po' tmpdepfile='$(DEPDIR)/set_exponent_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o set_exponent_r8.o `test -f 'generated/set_exponent_r8.c' || echo '$(srcdir)/'`generated/set_exponent_r8.c
+
+set_exponent_r8.obj: generated/set_exponent_r8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT set_exponent_r8.obj -MD -MP -MF "$(DEPDIR)/set_exponent_r8.Tpo" -c -o set_exponent_r8.obj `if test -f 'generated/set_exponent_r8.c'; then $(CYGPATH_W) 'generated/set_exponent_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/set_exponent_r8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/set_exponent_r8.Tpo" "$(DEPDIR)/set_exponent_r8.Po"; else rm -f "$(DEPDIR)/set_exponent_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/set_exponent_r8.c' object='set_exponent_r8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/set_exponent_r8.Po' tmpdepfile='$(DEPDIR)/set_exponent_r8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o set_exponent_r8.obj `if test -f 'generated/set_exponent_r8.c'; then $(CYGPATH_W) 'generated/set_exponent_r8.c'; else $(CYGPATH_W) '$(srcdir)/generated/set_exponent_r8.c'; fi`
+
+set_exponent_r8.lo: generated/set_exponent_r8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT set_exponent_r8.lo -MD -MP -MF "$(DEPDIR)/set_exponent_r8.Tpo" -c -o set_exponent_r8.lo `test -f 'generated/set_exponent_r8.c' || echo '$(srcdir)/'`generated/set_exponent_r8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/set_exponent_r8.Tpo" "$(DEPDIR)/set_exponent_r8.Plo"; else rm -f "$(DEPDIR)/set_exponent_r8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/set_exponent_r8.c' object='set_exponent_r8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/set_exponent_r8.Plo' tmpdepfile='$(DEPDIR)/set_exponent_r8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o set_exponent_r8.lo `test -f 'generated/set_exponent_r8.c' || echo '$(srcdir)/'`generated/set_exponent_r8.c
+
+backspace.o: io/backspace.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backspace.o -MD -MP -MF "$(DEPDIR)/backspace.Tpo" -c -o backspace.o `test -f 'io/backspace.c' || echo '$(srcdir)/'`io/backspace.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/backspace.Tpo" "$(DEPDIR)/backspace.Po"; else rm -f "$(DEPDIR)/backspace.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/backspace.c' object='backspace.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/backspace.Po' tmpdepfile='$(DEPDIR)/backspace.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o backspace.o `test -f 'io/backspace.c' || echo '$(srcdir)/'`io/backspace.c
+
+backspace.obj: io/backspace.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backspace.obj -MD -MP -MF "$(DEPDIR)/backspace.Tpo" -c -o backspace.obj `if test -f 'io/backspace.c'; then $(CYGPATH_W) 'io/backspace.c'; else $(CYGPATH_W) '$(srcdir)/io/backspace.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/backspace.Tpo" "$(DEPDIR)/backspace.Po"; else rm -f "$(DEPDIR)/backspace.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/backspace.c' object='backspace.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/backspace.Po' tmpdepfile='$(DEPDIR)/backspace.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o backspace.obj `if test -f 'io/backspace.c'; then $(CYGPATH_W) 'io/backspace.c'; else $(CYGPATH_W) '$(srcdir)/io/backspace.c'; fi`
+
+backspace.lo: io/backspace.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backspace.lo -MD -MP -MF "$(DEPDIR)/backspace.Tpo" -c -o backspace.lo `test -f 'io/backspace.c' || echo '$(srcdir)/'`io/backspace.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/backspace.Tpo" "$(DEPDIR)/backspace.Plo"; else rm -f "$(DEPDIR)/backspace.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/backspace.c' object='backspace.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/backspace.Plo' tmpdepfile='$(DEPDIR)/backspace.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o backspace.lo `test -f 'io/backspace.c' || echo '$(srcdir)/'`io/backspace.c
+
+close.o: io/close.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT close.o -MD -MP -MF "$(DEPDIR)/close.Tpo" -c -o close.o `test -f 'io/close.c' || echo '$(srcdir)/'`io/close.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/close.Tpo" "$(DEPDIR)/close.Po"; else rm -f "$(DEPDIR)/close.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/close.c' object='close.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/close.Po' tmpdepfile='$(DEPDIR)/close.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o close.o `test -f 'io/close.c' || echo '$(srcdir)/'`io/close.c
+
+close.obj: io/close.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT close.obj -MD -MP -MF "$(DEPDIR)/close.Tpo" -c -o close.obj `if test -f 'io/close.c'; then $(CYGPATH_W) 'io/close.c'; else $(CYGPATH_W) '$(srcdir)/io/close.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/close.Tpo" "$(DEPDIR)/close.Po"; else rm -f "$(DEPDIR)/close.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/close.c' object='close.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/close.Po' tmpdepfile='$(DEPDIR)/close.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o close.obj `if test -f 'io/close.c'; then $(CYGPATH_W) 'io/close.c'; else $(CYGPATH_W) '$(srcdir)/io/close.c'; fi`
+
+close.lo: io/close.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT close.lo -MD -MP -MF "$(DEPDIR)/close.Tpo" -c -o close.lo `test -f 'io/close.c' || echo '$(srcdir)/'`io/close.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/close.Tpo" "$(DEPDIR)/close.Plo"; else rm -f "$(DEPDIR)/close.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/close.c' object='close.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/close.Plo' tmpdepfile='$(DEPDIR)/close.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o close.lo `test -f 'io/close.c' || echo '$(srcdir)/'`io/close.c
+
+endfile.o: io/endfile.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT endfile.o -MD -MP -MF "$(DEPDIR)/endfile.Tpo" -c -o endfile.o `test -f 'io/endfile.c' || echo '$(srcdir)/'`io/endfile.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/endfile.Tpo" "$(DEPDIR)/endfile.Po"; else rm -f "$(DEPDIR)/endfile.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/endfile.c' object='endfile.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/endfile.Po' tmpdepfile='$(DEPDIR)/endfile.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o endfile.o `test -f 'io/endfile.c' || echo '$(srcdir)/'`io/endfile.c
+
+endfile.obj: io/endfile.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT endfile.obj -MD -MP -MF "$(DEPDIR)/endfile.Tpo" -c -o endfile.obj `if test -f 'io/endfile.c'; then $(CYGPATH_W) 'io/endfile.c'; else $(CYGPATH_W) '$(srcdir)/io/endfile.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/endfile.Tpo" "$(DEPDIR)/endfile.Po"; else rm -f "$(DEPDIR)/endfile.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/endfile.c' object='endfile.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/endfile.Po' tmpdepfile='$(DEPDIR)/endfile.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o endfile.obj `if test -f 'io/endfile.c'; then $(CYGPATH_W) 'io/endfile.c'; else $(CYGPATH_W) '$(srcdir)/io/endfile.c'; fi`
+
+endfile.lo: io/endfile.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT endfile.lo -MD -MP -MF "$(DEPDIR)/endfile.Tpo" -c -o endfile.lo `test -f 'io/endfile.c' || echo '$(srcdir)/'`io/endfile.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/endfile.Tpo" "$(DEPDIR)/endfile.Plo"; else rm -f "$(DEPDIR)/endfile.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/endfile.c' object='endfile.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/endfile.Plo' tmpdepfile='$(DEPDIR)/endfile.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o endfile.lo `test -f 'io/endfile.c' || echo '$(srcdir)/'`io/endfile.c
+
+format.o: io/format.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT format.o -MD -MP -MF "$(DEPDIR)/format.Tpo" -c -o format.o `test -f 'io/format.c' || echo '$(srcdir)/'`io/format.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/format.Tpo" "$(DEPDIR)/format.Po"; else rm -f "$(DEPDIR)/format.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/format.c' object='format.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/format.Po' tmpdepfile='$(DEPDIR)/format.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o format.o `test -f 'io/format.c' || echo '$(srcdir)/'`io/format.c
+
+format.obj: io/format.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT format.obj -MD -MP -MF "$(DEPDIR)/format.Tpo" -c -o format.obj `if test -f 'io/format.c'; then $(CYGPATH_W) 'io/format.c'; else $(CYGPATH_W) '$(srcdir)/io/format.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/format.Tpo" "$(DEPDIR)/format.Po"; else rm -f "$(DEPDIR)/format.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/format.c' object='format.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/format.Po' tmpdepfile='$(DEPDIR)/format.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o format.obj `if test -f 'io/format.c'; then $(CYGPATH_W) 'io/format.c'; else $(CYGPATH_W) '$(srcdir)/io/format.c'; fi`
+
+format.lo: io/format.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT format.lo -MD -MP -MF "$(DEPDIR)/format.Tpo" -c -o format.lo `test -f 'io/format.c' || echo '$(srcdir)/'`io/format.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/format.Tpo" "$(DEPDIR)/format.Plo"; else rm -f "$(DEPDIR)/format.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/format.c' object='format.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/format.Plo' tmpdepfile='$(DEPDIR)/format.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o format.lo `test -f 'io/format.c' || echo '$(srcdir)/'`io/format.c
+
+inquire.o: io/inquire.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT inquire.o -MD -MP -MF "$(DEPDIR)/inquire.Tpo" -c -o inquire.o `test -f 'io/inquire.c' || echo '$(srcdir)/'`io/inquire.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/inquire.Tpo" "$(DEPDIR)/inquire.Po"; else rm -f "$(DEPDIR)/inquire.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/inquire.c' object='inquire.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/inquire.Po' tmpdepfile='$(DEPDIR)/inquire.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o inquire.o `test -f 'io/inquire.c' || echo '$(srcdir)/'`io/inquire.c
+
+inquire.obj: io/inquire.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT inquire.obj -MD -MP -MF "$(DEPDIR)/inquire.Tpo" -c -o inquire.obj `if test -f 'io/inquire.c'; then $(CYGPATH_W) 'io/inquire.c'; else $(CYGPATH_W) '$(srcdir)/io/inquire.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/inquire.Tpo" "$(DEPDIR)/inquire.Po"; else rm -f "$(DEPDIR)/inquire.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/inquire.c' object='inquire.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/inquire.Po' tmpdepfile='$(DEPDIR)/inquire.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o inquire.obj `if test -f 'io/inquire.c'; then $(CYGPATH_W) 'io/inquire.c'; else $(CYGPATH_W) '$(srcdir)/io/inquire.c'; fi`
+
+inquire.lo: io/inquire.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT inquire.lo -MD -MP -MF "$(DEPDIR)/inquire.Tpo" -c -o inquire.lo `test -f 'io/inquire.c' || echo '$(srcdir)/'`io/inquire.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/inquire.Tpo" "$(DEPDIR)/inquire.Plo"; else rm -f "$(DEPDIR)/inquire.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/inquire.c' object='inquire.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/inquire.Plo' tmpdepfile='$(DEPDIR)/inquire.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o inquire.lo `test -f 'io/inquire.c' || echo '$(srcdir)/'`io/inquire.c
+
+list_read.o: io/list_read.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT list_read.o -MD -MP -MF "$(DEPDIR)/list_read.Tpo" -c -o list_read.o `test -f 'io/list_read.c' || echo '$(srcdir)/'`io/list_read.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/list_read.Tpo" "$(DEPDIR)/list_read.Po"; else rm -f "$(DEPDIR)/list_read.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/list_read.c' object='list_read.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/list_read.Po' tmpdepfile='$(DEPDIR)/list_read.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o list_read.o `test -f 'io/list_read.c' || echo '$(srcdir)/'`io/list_read.c
+
+list_read.obj: io/list_read.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT list_read.obj -MD -MP -MF "$(DEPDIR)/list_read.Tpo" -c -o list_read.obj `if test -f 'io/list_read.c'; then $(CYGPATH_W) 'io/list_read.c'; else $(CYGPATH_W) '$(srcdir)/io/list_read.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/list_read.Tpo" "$(DEPDIR)/list_read.Po"; else rm -f "$(DEPDIR)/list_read.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/list_read.c' object='list_read.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/list_read.Po' tmpdepfile='$(DEPDIR)/list_read.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o list_read.obj `if test -f 'io/list_read.c'; then $(CYGPATH_W) 'io/list_read.c'; else $(CYGPATH_W) '$(srcdir)/io/list_read.c'; fi`
+
+list_read.lo: io/list_read.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT list_read.lo -MD -MP -MF "$(DEPDIR)/list_read.Tpo" -c -o list_read.lo `test -f 'io/list_read.c' || echo '$(srcdir)/'`io/list_read.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/list_read.Tpo" "$(DEPDIR)/list_read.Plo"; else rm -f "$(DEPDIR)/list_read.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/list_read.c' object='list_read.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/list_read.Plo' tmpdepfile='$(DEPDIR)/list_read.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o list_read.lo `test -f 'io/list_read.c' || echo '$(srcdir)/'`io/list_read.c
+
+lock.o: io/lock.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lock.o -MD -MP -MF "$(DEPDIR)/lock.Tpo" -c -o lock.o `test -f 'io/lock.c' || echo '$(srcdir)/'`io/lock.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lock.Tpo" "$(DEPDIR)/lock.Po"; else rm -f "$(DEPDIR)/lock.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/lock.c' object='lock.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/lock.Po' tmpdepfile='$(DEPDIR)/lock.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lock.o `test -f 'io/lock.c' || echo '$(srcdir)/'`io/lock.c
+
+lock.obj: io/lock.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lock.obj -MD -MP -MF "$(DEPDIR)/lock.Tpo" -c -o lock.obj `if test -f 'io/lock.c'; then $(CYGPATH_W) 'io/lock.c'; else $(CYGPATH_W) '$(srcdir)/io/lock.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lock.Tpo" "$(DEPDIR)/lock.Po"; else rm -f "$(DEPDIR)/lock.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/lock.c' object='lock.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/lock.Po' tmpdepfile='$(DEPDIR)/lock.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lock.obj `if test -f 'io/lock.c'; then $(CYGPATH_W) 'io/lock.c'; else $(CYGPATH_W) '$(srcdir)/io/lock.c'; fi`
+
+lock.lo: io/lock.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lock.lo -MD -MP -MF "$(DEPDIR)/lock.Tpo" -c -o lock.lo `test -f 'io/lock.c' || echo '$(srcdir)/'`io/lock.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lock.Tpo" "$(DEPDIR)/lock.Plo"; else rm -f "$(DEPDIR)/lock.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/lock.c' object='lock.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/lock.Plo' tmpdepfile='$(DEPDIR)/lock.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lock.lo `test -f 'io/lock.c' || echo '$(srcdir)/'`io/lock.c
+
+open.o: io/open.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT open.o -MD -MP -MF "$(DEPDIR)/open.Tpo" -c -o open.o `test -f 'io/open.c' || echo '$(srcdir)/'`io/open.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/open.Tpo" "$(DEPDIR)/open.Po"; else rm -f "$(DEPDIR)/open.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/open.c' object='open.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/open.Po' tmpdepfile='$(DEPDIR)/open.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o open.o `test -f 'io/open.c' || echo '$(srcdir)/'`io/open.c
+
+open.obj: io/open.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT open.obj -MD -MP -MF "$(DEPDIR)/open.Tpo" -c -o open.obj `if test -f 'io/open.c'; then $(CYGPATH_W) 'io/open.c'; else $(CYGPATH_W) '$(srcdir)/io/open.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/open.Tpo" "$(DEPDIR)/open.Po"; else rm -f "$(DEPDIR)/open.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/open.c' object='open.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/open.Po' tmpdepfile='$(DEPDIR)/open.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o open.obj `if test -f 'io/open.c'; then $(CYGPATH_W) 'io/open.c'; else $(CYGPATH_W) '$(srcdir)/io/open.c'; fi`
+
+open.lo: io/open.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT open.lo -MD -MP -MF "$(DEPDIR)/open.Tpo" -c -o open.lo `test -f 'io/open.c' || echo '$(srcdir)/'`io/open.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/open.Tpo" "$(DEPDIR)/open.Plo"; else rm -f "$(DEPDIR)/open.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/open.c' object='open.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/open.Plo' tmpdepfile='$(DEPDIR)/open.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o open.lo `test -f 'io/open.c' || echo '$(srcdir)/'`io/open.c
+
+read.o: io/read.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT read.o -MD -MP -MF "$(DEPDIR)/read.Tpo" -c -o read.o `test -f 'io/read.c' || echo '$(srcdir)/'`io/read.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/read.Tpo" "$(DEPDIR)/read.Po"; else rm -f "$(DEPDIR)/read.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/read.c' object='read.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/read.Po' tmpdepfile='$(DEPDIR)/read.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o read.o `test -f 'io/read.c' || echo '$(srcdir)/'`io/read.c
+
+read.obj: io/read.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT read.obj -MD -MP -MF "$(DEPDIR)/read.Tpo" -c -o read.obj `if test -f 'io/read.c'; then $(CYGPATH_W) 'io/read.c'; else $(CYGPATH_W) '$(srcdir)/io/read.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/read.Tpo" "$(DEPDIR)/read.Po"; else rm -f "$(DEPDIR)/read.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/read.c' object='read.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/read.Po' tmpdepfile='$(DEPDIR)/read.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o read.obj `if test -f 'io/read.c'; then $(CYGPATH_W) 'io/read.c'; else $(CYGPATH_W) '$(srcdir)/io/read.c'; fi`
+
+read.lo: io/read.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT read.lo -MD -MP -MF "$(DEPDIR)/read.Tpo" -c -o read.lo `test -f 'io/read.c' || echo '$(srcdir)/'`io/read.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/read.Tpo" "$(DEPDIR)/read.Plo"; else rm -f "$(DEPDIR)/read.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/read.c' object='read.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/read.Plo' tmpdepfile='$(DEPDIR)/read.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o read.lo `test -f 'io/read.c' || echo '$(srcdir)/'`io/read.c
+
+rewind.o: io/rewind.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rewind.o -MD -MP -MF "$(DEPDIR)/rewind.Tpo" -c -o rewind.o `test -f 'io/rewind.c' || echo '$(srcdir)/'`io/rewind.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/rewind.Tpo" "$(DEPDIR)/rewind.Po"; else rm -f "$(DEPDIR)/rewind.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/rewind.c' object='rewind.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/rewind.Po' tmpdepfile='$(DEPDIR)/rewind.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rewind.o `test -f 'io/rewind.c' || echo '$(srcdir)/'`io/rewind.c
+
+rewind.obj: io/rewind.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rewind.obj -MD -MP -MF "$(DEPDIR)/rewind.Tpo" -c -o rewind.obj `if test -f 'io/rewind.c'; then $(CYGPATH_W) 'io/rewind.c'; else $(CYGPATH_W) '$(srcdir)/io/rewind.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/rewind.Tpo" "$(DEPDIR)/rewind.Po"; else rm -f "$(DEPDIR)/rewind.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/rewind.c' object='rewind.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/rewind.Po' tmpdepfile='$(DEPDIR)/rewind.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rewind.obj `if test -f 'io/rewind.c'; then $(CYGPATH_W) 'io/rewind.c'; else $(CYGPATH_W) '$(srcdir)/io/rewind.c'; fi`
+
+rewind.lo: io/rewind.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rewind.lo -MD -MP -MF "$(DEPDIR)/rewind.Tpo" -c -o rewind.lo `test -f 'io/rewind.c' || echo '$(srcdir)/'`io/rewind.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/rewind.Tpo" "$(DEPDIR)/rewind.Plo"; else rm -f "$(DEPDIR)/rewind.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/rewind.c' object='rewind.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/rewind.Plo' tmpdepfile='$(DEPDIR)/rewind.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rewind.lo `test -f 'io/rewind.c' || echo '$(srcdir)/'`io/rewind.c
+
+transfer.o: io/transfer.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT transfer.o -MD -MP -MF "$(DEPDIR)/transfer.Tpo" -c -o transfer.o `test -f 'io/transfer.c' || echo '$(srcdir)/'`io/transfer.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/transfer.Tpo" "$(DEPDIR)/transfer.Po"; else rm -f "$(DEPDIR)/transfer.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/transfer.c' object='transfer.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/transfer.Po' tmpdepfile='$(DEPDIR)/transfer.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o transfer.o `test -f 'io/transfer.c' || echo '$(srcdir)/'`io/transfer.c
+
+transfer.obj: io/transfer.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT transfer.obj -MD -MP -MF "$(DEPDIR)/transfer.Tpo" -c -o transfer.obj `if test -f 'io/transfer.c'; then $(CYGPATH_W) 'io/transfer.c'; else $(CYGPATH_W) '$(srcdir)/io/transfer.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/transfer.Tpo" "$(DEPDIR)/transfer.Po"; else rm -f "$(DEPDIR)/transfer.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/transfer.c' object='transfer.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/transfer.Po' tmpdepfile='$(DEPDIR)/transfer.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o transfer.obj `if test -f 'io/transfer.c'; then $(CYGPATH_W) 'io/transfer.c'; else $(CYGPATH_W) '$(srcdir)/io/transfer.c'; fi`
+
+transfer.lo: io/transfer.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT transfer.lo -MD -MP -MF "$(DEPDIR)/transfer.Tpo" -c -o transfer.lo `test -f 'io/transfer.c' || echo '$(srcdir)/'`io/transfer.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/transfer.Tpo" "$(DEPDIR)/transfer.Plo"; else rm -f "$(DEPDIR)/transfer.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/transfer.c' object='transfer.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/transfer.Plo' tmpdepfile='$(DEPDIR)/transfer.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o transfer.lo `test -f 'io/transfer.c' || echo '$(srcdir)/'`io/transfer.c
+
+unit.o: io/unit.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unit.o -MD -MP -MF "$(DEPDIR)/unit.Tpo" -c -o unit.o `test -f 'io/unit.c' || echo '$(srcdir)/'`io/unit.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/unit.Tpo" "$(DEPDIR)/unit.Po"; else rm -f "$(DEPDIR)/unit.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/unit.c' object='unit.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/unit.Po' tmpdepfile='$(DEPDIR)/unit.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unit.o `test -f 'io/unit.c' || echo '$(srcdir)/'`io/unit.c
+
+unit.obj: io/unit.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unit.obj -MD -MP -MF "$(DEPDIR)/unit.Tpo" -c -o unit.obj `if test -f 'io/unit.c'; then $(CYGPATH_W) 'io/unit.c'; else $(CYGPATH_W) '$(srcdir)/io/unit.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/unit.Tpo" "$(DEPDIR)/unit.Po"; else rm -f "$(DEPDIR)/unit.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/unit.c' object='unit.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/unit.Po' tmpdepfile='$(DEPDIR)/unit.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unit.obj `if test -f 'io/unit.c'; then $(CYGPATH_W) 'io/unit.c'; else $(CYGPATH_W) '$(srcdir)/io/unit.c'; fi`
+
+unit.lo: io/unit.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unit.lo -MD -MP -MF "$(DEPDIR)/unit.Tpo" -c -o unit.lo `test -f 'io/unit.c' || echo '$(srcdir)/'`io/unit.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/unit.Tpo" "$(DEPDIR)/unit.Plo"; else rm -f "$(DEPDIR)/unit.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/unit.c' object='unit.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/unit.Plo' tmpdepfile='$(DEPDIR)/unit.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unit.lo `test -f 'io/unit.c' || echo '$(srcdir)/'`io/unit.c
+
+unix.o: io/unix.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix.o -MD -MP -MF "$(DEPDIR)/unix.Tpo" -c -o unix.o `test -f 'io/unix.c' || echo '$(srcdir)/'`io/unix.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/unix.Tpo" "$(DEPDIR)/unix.Po"; else rm -f "$(DEPDIR)/unix.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/unix.c' object='unix.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/unix.Po' tmpdepfile='$(DEPDIR)/unix.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix.o `test -f 'io/unix.c' || echo '$(srcdir)/'`io/unix.c
+
+unix.obj: io/unix.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix.obj -MD -MP -MF "$(DEPDIR)/unix.Tpo" -c -o unix.obj `if test -f 'io/unix.c'; then $(CYGPATH_W) 'io/unix.c'; else $(CYGPATH_W) '$(srcdir)/io/unix.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/unix.Tpo" "$(DEPDIR)/unix.Po"; else rm -f "$(DEPDIR)/unix.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/unix.c' object='unix.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/unix.Po' tmpdepfile='$(DEPDIR)/unix.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix.obj `if test -f 'io/unix.c'; then $(CYGPATH_W) 'io/unix.c'; else $(CYGPATH_W) '$(srcdir)/io/unix.c'; fi`
+
+unix.lo: io/unix.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unix.lo -MD -MP -MF "$(DEPDIR)/unix.Tpo" -c -o unix.lo `test -f 'io/unix.c' || echo '$(srcdir)/'`io/unix.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/unix.Tpo" "$(DEPDIR)/unix.Plo"; else rm -f "$(DEPDIR)/unix.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/unix.c' object='unix.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/unix.Plo' tmpdepfile='$(DEPDIR)/unix.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unix.lo `test -f 'io/unix.c' || echo '$(srcdir)/'`io/unix.c
+
+write.o: io/write.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT write.o -MD -MP -MF "$(DEPDIR)/write.Tpo" -c -o write.o `test -f 'io/write.c' || echo '$(srcdir)/'`io/write.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/write.Tpo" "$(DEPDIR)/write.Po"; else rm -f "$(DEPDIR)/write.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/write.c' object='write.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/write.Po' tmpdepfile='$(DEPDIR)/write.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o write.o `test -f 'io/write.c' || echo '$(srcdir)/'`io/write.c
+
+write.obj: io/write.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT write.obj -MD -MP -MF "$(DEPDIR)/write.Tpo" -c -o write.obj `if test -f 'io/write.c'; then $(CYGPATH_W) 'io/write.c'; else $(CYGPATH_W) '$(srcdir)/io/write.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/write.Tpo" "$(DEPDIR)/write.Po"; else rm -f "$(DEPDIR)/write.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/write.c' object='write.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/write.Po' tmpdepfile='$(DEPDIR)/write.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o write.obj `if test -f 'io/write.c'; then $(CYGPATH_W) 'io/write.c'; else $(CYGPATH_W) '$(srcdir)/io/write.c'; fi`
+
+write.lo: io/write.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT write.lo -MD -MP -MF "$(DEPDIR)/write.Tpo" -c -o write.lo `test -f 'io/write.c' || echo '$(srcdir)/'`io/write.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/write.Tpo" "$(DEPDIR)/write.Plo"; else rm -f "$(DEPDIR)/write.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/write.c' object='write.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/write.Plo' tmpdepfile='$(DEPDIR)/write.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o write.lo `test -f 'io/write.c' || echo '$(srcdir)/'`io/write.c
+
+associated.o: intrinsics/associated.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT associated.o -MD -MP -MF "$(DEPDIR)/associated.Tpo" -c -o associated.o `test -f 'intrinsics/associated.c' || echo '$(srcdir)/'`intrinsics/associated.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/associated.Tpo" "$(DEPDIR)/associated.Po"; else rm -f "$(DEPDIR)/associated.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/associated.c' object='associated.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/associated.Po' tmpdepfile='$(DEPDIR)/associated.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o associated.o `test -f 'intrinsics/associated.c' || echo '$(srcdir)/'`intrinsics/associated.c
+
+associated.obj: intrinsics/associated.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT associated.obj -MD -MP -MF "$(DEPDIR)/associated.Tpo" -c -o associated.obj `if test -f 'intrinsics/associated.c'; then $(CYGPATH_W) 'intrinsics/associated.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/associated.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/associated.Tpo" "$(DEPDIR)/associated.Po"; else rm -f "$(DEPDIR)/associated.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/associated.c' object='associated.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/associated.Po' tmpdepfile='$(DEPDIR)/associated.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o associated.obj `if test -f 'intrinsics/associated.c'; then $(CYGPATH_W) 'intrinsics/associated.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/associated.c'; fi`
+
+associated.lo: intrinsics/associated.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT associated.lo -MD -MP -MF "$(DEPDIR)/associated.Tpo" -c -o associated.lo `test -f 'intrinsics/associated.c' || echo '$(srcdir)/'`intrinsics/associated.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/associated.Tpo" "$(DEPDIR)/associated.Plo"; else rm -f "$(DEPDIR)/associated.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/associated.c' object='associated.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/associated.Plo' tmpdepfile='$(DEPDIR)/associated.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o associated.lo `test -f 'intrinsics/associated.c' || echo '$(srcdir)/'`intrinsics/associated.c
+
+abort.o: intrinsics/abort.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT abort.o -MD -MP -MF "$(DEPDIR)/abort.Tpo" -c -o abort.o `test -f 'intrinsics/abort.c' || echo '$(srcdir)/'`intrinsics/abort.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/abort.Tpo" "$(DEPDIR)/abort.Po"; else rm -f "$(DEPDIR)/abort.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/abort.c' object='abort.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/abort.Po' tmpdepfile='$(DEPDIR)/abort.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o abort.o `test -f 'intrinsics/abort.c' || echo '$(srcdir)/'`intrinsics/abort.c
+
+abort.obj: intrinsics/abort.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT abort.obj -MD -MP -MF "$(DEPDIR)/abort.Tpo" -c -o abort.obj `if test -f 'intrinsics/abort.c'; then $(CYGPATH_W) 'intrinsics/abort.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/abort.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/abort.Tpo" "$(DEPDIR)/abort.Po"; else rm -f "$(DEPDIR)/abort.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/abort.c' object='abort.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/abort.Po' tmpdepfile='$(DEPDIR)/abort.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o abort.obj `if test -f 'intrinsics/abort.c'; then $(CYGPATH_W) 'intrinsics/abort.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/abort.c'; fi`
+
+abort.lo: intrinsics/abort.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT abort.lo -MD -MP -MF "$(DEPDIR)/abort.Tpo" -c -o abort.lo `test -f 'intrinsics/abort.c' || echo '$(srcdir)/'`intrinsics/abort.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/abort.Tpo" "$(DEPDIR)/abort.Plo"; else rm -f "$(DEPDIR)/abort.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/abort.c' object='abort.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/abort.Plo' tmpdepfile='$(DEPDIR)/abort.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o abort.lo `test -f 'intrinsics/abort.c' || echo '$(srcdir)/'`intrinsics/abort.c
+
+cpu_time.o: intrinsics/cpu_time.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpu_time.o -MD -MP -MF "$(DEPDIR)/cpu_time.Tpo" -c -o cpu_time.o `test -f 'intrinsics/cpu_time.c' || echo '$(srcdir)/'`intrinsics/cpu_time.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/cpu_time.Tpo" "$(DEPDIR)/cpu_time.Po"; else rm -f "$(DEPDIR)/cpu_time.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/cpu_time.c' object='cpu_time.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/cpu_time.Po' tmpdepfile='$(DEPDIR)/cpu_time.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpu_time.o `test -f 'intrinsics/cpu_time.c' || echo '$(srcdir)/'`intrinsics/cpu_time.c
+
+cpu_time.obj: intrinsics/cpu_time.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpu_time.obj -MD -MP -MF "$(DEPDIR)/cpu_time.Tpo" -c -o cpu_time.obj `if test -f 'intrinsics/cpu_time.c'; then $(CYGPATH_W) 'intrinsics/cpu_time.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/cpu_time.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/cpu_time.Tpo" "$(DEPDIR)/cpu_time.Po"; else rm -f "$(DEPDIR)/cpu_time.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/cpu_time.c' object='cpu_time.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/cpu_time.Po' tmpdepfile='$(DEPDIR)/cpu_time.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpu_time.obj `if test -f 'intrinsics/cpu_time.c'; then $(CYGPATH_W) 'intrinsics/cpu_time.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/cpu_time.c'; fi`
+
+cpu_time.lo: intrinsics/cpu_time.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpu_time.lo -MD -MP -MF "$(DEPDIR)/cpu_time.Tpo" -c -o cpu_time.lo `test -f 'intrinsics/cpu_time.c' || echo '$(srcdir)/'`intrinsics/cpu_time.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/cpu_time.Tpo" "$(DEPDIR)/cpu_time.Plo"; else rm -f "$(DEPDIR)/cpu_time.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/cpu_time.c' object='cpu_time.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/cpu_time.Plo' tmpdepfile='$(DEPDIR)/cpu_time.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpu_time.lo `test -f 'intrinsics/cpu_time.c' || echo '$(srcdir)/'`intrinsics/cpu_time.c
+
+cshift0.o: intrinsics/cshift0.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cshift0.o -MD -MP -MF "$(DEPDIR)/cshift0.Tpo" -c -o cshift0.o `test -f 'intrinsics/cshift0.c' || echo '$(srcdir)/'`intrinsics/cshift0.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/cshift0.Tpo" "$(DEPDIR)/cshift0.Po"; else rm -f "$(DEPDIR)/cshift0.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/cshift0.c' object='cshift0.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/cshift0.Po' tmpdepfile='$(DEPDIR)/cshift0.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cshift0.o `test -f 'intrinsics/cshift0.c' || echo '$(srcdir)/'`intrinsics/cshift0.c
+
+cshift0.obj: intrinsics/cshift0.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cshift0.obj -MD -MP -MF "$(DEPDIR)/cshift0.Tpo" -c -o cshift0.obj `if test -f 'intrinsics/cshift0.c'; then $(CYGPATH_W) 'intrinsics/cshift0.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/cshift0.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/cshift0.Tpo" "$(DEPDIR)/cshift0.Po"; else rm -f "$(DEPDIR)/cshift0.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/cshift0.c' object='cshift0.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/cshift0.Po' tmpdepfile='$(DEPDIR)/cshift0.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cshift0.obj `if test -f 'intrinsics/cshift0.c'; then $(CYGPATH_W) 'intrinsics/cshift0.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/cshift0.c'; fi`
+
+cshift0.lo: intrinsics/cshift0.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cshift0.lo -MD -MP -MF "$(DEPDIR)/cshift0.Tpo" -c -o cshift0.lo `test -f 'intrinsics/cshift0.c' || echo '$(srcdir)/'`intrinsics/cshift0.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/cshift0.Tpo" "$(DEPDIR)/cshift0.Plo"; else rm -f "$(DEPDIR)/cshift0.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/cshift0.c' object='cshift0.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/cshift0.Plo' tmpdepfile='$(DEPDIR)/cshift0.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cshift0.lo `test -f 'intrinsics/cshift0.c' || echo '$(srcdir)/'`intrinsics/cshift0.c
+
+eoshift0.o: intrinsics/eoshift0.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eoshift0.o -MD -MP -MF "$(DEPDIR)/eoshift0.Tpo" -c -o eoshift0.o `test -f 'intrinsics/eoshift0.c' || echo '$(srcdir)/'`intrinsics/eoshift0.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/eoshift0.Tpo" "$(DEPDIR)/eoshift0.Po"; else rm -f "$(DEPDIR)/eoshift0.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/eoshift0.c' object='eoshift0.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/eoshift0.Po' tmpdepfile='$(DEPDIR)/eoshift0.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eoshift0.o `test -f 'intrinsics/eoshift0.c' || echo '$(srcdir)/'`intrinsics/eoshift0.c
+
+eoshift0.obj: intrinsics/eoshift0.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eoshift0.obj -MD -MP -MF "$(DEPDIR)/eoshift0.Tpo" -c -o eoshift0.obj `if test -f 'intrinsics/eoshift0.c'; then $(CYGPATH_W) 'intrinsics/eoshift0.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/eoshift0.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/eoshift0.Tpo" "$(DEPDIR)/eoshift0.Po"; else rm -f "$(DEPDIR)/eoshift0.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/eoshift0.c' object='eoshift0.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/eoshift0.Po' tmpdepfile='$(DEPDIR)/eoshift0.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eoshift0.obj `if test -f 'intrinsics/eoshift0.c'; then $(CYGPATH_W) 'intrinsics/eoshift0.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/eoshift0.c'; fi`
+
+eoshift0.lo: intrinsics/eoshift0.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eoshift0.lo -MD -MP -MF "$(DEPDIR)/eoshift0.Tpo" -c -o eoshift0.lo `test -f 'intrinsics/eoshift0.c' || echo '$(srcdir)/'`intrinsics/eoshift0.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/eoshift0.Tpo" "$(DEPDIR)/eoshift0.Plo"; else rm -f "$(DEPDIR)/eoshift0.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/eoshift0.c' object='eoshift0.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/eoshift0.Plo' tmpdepfile='$(DEPDIR)/eoshift0.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eoshift0.lo `test -f 'intrinsics/eoshift0.c' || echo '$(srcdir)/'`intrinsics/eoshift0.c
+
+eoshift2.o: intrinsics/eoshift2.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eoshift2.o -MD -MP -MF "$(DEPDIR)/eoshift2.Tpo" -c -o eoshift2.o `test -f 'intrinsics/eoshift2.c' || echo '$(srcdir)/'`intrinsics/eoshift2.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/eoshift2.Tpo" "$(DEPDIR)/eoshift2.Po"; else rm -f "$(DEPDIR)/eoshift2.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/eoshift2.c' object='eoshift2.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/eoshift2.Po' tmpdepfile='$(DEPDIR)/eoshift2.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eoshift2.o `test -f 'intrinsics/eoshift2.c' || echo '$(srcdir)/'`intrinsics/eoshift2.c
+
+eoshift2.obj: intrinsics/eoshift2.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eoshift2.obj -MD -MP -MF "$(DEPDIR)/eoshift2.Tpo" -c -o eoshift2.obj `if test -f 'intrinsics/eoshift2.c'; then $(CYGPATH_W) 'intrinsics/eoshift2.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/eoshift2.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/eoshift2.Tpo" "$(DEPDIR)/eoshift2.Po"; else rm -f "$(DEPDIR)/eoshift2.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/eoshift2.c' object='eoshift2.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/eoshift2.Po' tmpdepfile='$(DEPDIR)/eoshift2.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eoshift2.obj `if test -f 'intrinsics/eoshift2.c'; then $(CYGPATH_W) 'intrinsics/eoshift2.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/eoshift2.c'; fi`
+
+eoshift2.lo: intrinsics/eoshift2.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eoshift2.lo -MD -MP -MF "$(DEPDIR)/eoshift2.Tpo" -c -o eoshift2.lo `test -f 'intrinsics/eoshift2.c' || echo '$(srcdir)/'`intrinsics/eoshift2.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/eoshift2.Tpo" "$(DEPDIR)/eoshift2.Plo"; else rm -f "$(DEPDIR)/eoshift2.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/eoshift2.c' object='eoshift2.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/eoshift2.Plo' tmpdepfile='$(DEPDIR)/eoshift2.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eoshift2.lo `test -f 'intrinsics/eoshift2.c' || echo '$(srcdir)/'`intrinsics/eoshift2.c
+
+ishftc.o: intrinsics/ishftc.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ishftc.o -MD -MP -MF "$(DEPDIR)/ishftc.Tpo" -c -o ishftc.o `test -f 'intrinsics/ishftc.c' || echo '$(srcdir)/'`intrinsics/ishftc.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/ishftc.Tpo" "$(DEPDIR)/ishftc.Po"; else rm -f "$(DEPDIR)/ishftc.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/ishftc.c' object='ishftc.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/ishftc.Po' tmpdepfile='$(DEPDIR)/ishftc.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ishftc.o `test -f 'intrinsics/ishftc.c' || echo '$(srcdir)/'`intrinsics/ishftc.c
+
+ishftc.obj: intrinsics/ishftc.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ishftc.obj -MD -MP -MF "$(DEPDIR)/ishftc.Tpo" -c -o ishftc.obj `if test -f 'intrinsics/ishftc.c'; then $(CYGPATH_W) 'intrinsics/ishftc.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/ishftc.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/ishftc.Tpo" "$(DEPDIR)/ishftc.Po"; else rm -f "$(DEPDIR)/ishftc.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/ishftc.c' object='ishftc.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/ishftc.Po' tmpdepfile='$(DEPDIR)/ishftc.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ishftc.obj `if test -f 'intrinsics/ishftc.c'; then $(CYGPATH_W) 'intrinsics/ishftc.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/ishftc.c'; fi`
+
+ishftc.lo: intrinsics/ishftc.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ishftc.lo -MD -MP -MF "$(DEPDIR)/ishftc.Tpo" -c -o ishftc.lo `test -f 'intrinsics/ishftc.c' || echo '$(srcdir)/'`intrinsics/ishftc.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/ishftc.Tpo" "$(DEPDIR)/ishftc.Plo"; else rm -f "$(DEPDIR)/ishftc.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/ishftc.c' object='ishftc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/ishftc.Plo' tmpdepfile='$(DEPDIR)/ishftc.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ishftc.lo `test -f 'intrinsics/ishftc.c' || echo '$(srcdir)/'`intrinsics/ishftc.c
+
+pack_generic.o: intrinsics/pack_generic.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pack_generic.o -MD -MP -MF "$(DEPDIR)/pack_generic.Tpo" -c -o pack_generic.o `test -f 'intrinsics/pack_generic.c' || echo '$(srcdir)/'`intrinsics/pack_generic.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/pack_generic.Tpo" "$(DEPDIR)/pack_generic.Po"; else rm -f "$(DEPDIR)/pack_generic.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/pack_generic.c' object='pack_generic.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/pack_generic.Po' tmpdepfile='$(DEPDIR)/pack_generic.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pack_generic.o `test -f 'intrinsics/pack_generic.c' || echo '$(srcdir)/'`intrinsics/pack_generic.c
+
+pack_generic.obj: intrinsics/pack_generic.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pack_generic.obj -MD -MP -MF "$(DEPDIR)/pack_generic.Tpo" -c -o pack_generic.obj `if test -f 'intrinsics/pack_generic.c'; then $(CYGPATH_W) 'intrinsics/pack_generic.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/pack_generic.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/pack_generic.Tpo" "$(DEPDIR)/pack_generic.Po"; else rm -f "$(DEPDIR)/pack_generic.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/pack_generic.c' object='pack_generic.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/pack_generic.Po' tmpdepfile='$(DEPDIR)/pack_generic.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pack_generic.obj `if test -f 'intrinsics/pack_generic.c'; then $(CYGPATH_W) 'intrinsics/pack_generic.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/pack_generic.c'; fi`
+
+pack_generic.lo: intrinsics/pack_generic.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pack_generic.lo -MD -MP -MF "$(DEPDIR)/pack_generic.Tpo" -c -o pack_generic.lo `test -f 'intrinsics/pack_generic.c' || echo '$(srcdir)/'`intrinsics/pack_generic.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/pack_generic.Tpo" "$(DEPDIR)/pack_generic.Plo"; else rm -f "$(DEPDIR)/pack_generic.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/pack_generic.c' object='pack_generic.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/pack_generic.Plo' tmpdepfile='$(DEPDIR)/pack_generic.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pack_generic.lo `test -f 'intrinsics/pack_generic.c' || echo '$(srcdir)/'`intrinsics/pack_generic.c
+
+size.o: intrinsics/size.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT size.o -MD -MP -MF "$(DEPDIR)/size.Tpo" -c -o size.o `test -f 'intrinsics/size.c' || echo '$(srcdir)/'`intrinsics/size.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/size.Tpo" "$(DEPDIR)/size.Po"; else rm -f "$(DEPDIR)/size.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/size.c' object='size.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/size.Po' tmpdepfile='$(DEPDIR)/size.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o size.o `test -f 'intrinsics/size.c' || echo '$(srcdir)/'`intrinsics/size.c
+
+size.obj: intrinsics/size.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT size.obj -MD -MP -MF "$(DEPDIR)/size.Tpo" -c -o size.obj `if test -f 'intrinsics/size.c'; then $(CYGPATH_W) 'intrinsics/size.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/size.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/size.Tpo" "$(DEPDIR)/size.Po"; else rm -f "$(DEPDIR)/size.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/size.c' object='size.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/size.Po' tmpdepfile='$(DEPDIR)/size.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o size.obj `if test -f 'intrinsics/size.c'; then $(CYGPATH_W) 'intrinsics/size.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/size.c'; fi`
+
+size.lo: intrinsics/size.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT size.lo -MD -MP -MF "$(DEPDIR)/size.Tpo" -c -o size.lo `test -f 'intrinsics/size.c' || echo '$(srcdir)/'`intrinsics/size.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/size.Tpo" "$(DEPDIR)/size.Plo"; else rm -f "$(DEPDIR)/size.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/size.c' object='size.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/size.Plo' tmpdepfile='$(DEPDIR)/size.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o size.lo `test -f 'intrinsics/size.c' || echo '$(srcdir)/'`intrinsics/size.c
+
+spread_generic.o: intrinsics/spread_generic.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT spread_generic.o -MD -MP -MF "$(DEPDIR)/spread_generic.Tpo" -c -o spread_generic.o `test -f 'intrinsics/spread_generic.c' || echo '$(srcdir)/'`intrinsics/spread_generic.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/spread_generic.Tpo" "$(DEPDIR)/spread_generic.Po"; else rm -f "$(DEPDIR)/spread_generic.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/spread_generic.c' object='spread_generic.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/spread_generic.Po' tmpdepfile='$(DEPDIR)/spread_generic.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o spread_generic.o `test -f 'intrinsics/spread_generic.c' || echo '$(srcdir)/'`intrinsics/spread_generic.c
+
+spread_generic.obj: intrinsics/spread_generic.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT spread_generic.obj -MD -MP -MF "$(DEPDIR)/spread_generic.Tpo" -c -o spread_generic.obj `if test -f 'intrinsics/spread_generic.c'; then $(CYGPATH_W) 'intrinsics/spread_generic.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/spread_generic.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/spread_generic.Tpo" "$(DEPDIR)/spread_generic.Po"; else rm -f "$(DEPDIR)/spread_generic.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/spread_generic.c' object='spread_generic.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/spread_generic.Po' tmpdepfile='$(DEPDIR)/spread_generic.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o spread_generic.obj `if test -f 'intrinsics/spread_generic.c'; then $(CYGPATH_W) 'intrinsics/spread_generic.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/spread_generic.c'; fi`
+
+spread_generic.lo: intrinsics/spread_generic.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT spread_generic.lo -MD -MP -MF "$(DEPDIR)/spread_generic.Tpo" -c -o spread_generic.lo `test -f 'intrinsics/spread_generic.c' || echo '$(srcdir)/'`intrinsics/spread_generic.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/spread_generic.Tpo" "$(DEPDIR)/spread_generic.Plo"; else rm -f "$(DEPDIR)/spread_generic.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/spread_generic.c' object='spread_generic.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/spread_generic.Plo' tmpdepfile='$(DEPDIR)/spread_generic.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o spread_generic.lo `test -f 'intrinsics/spread_generic.c' || echo '$(srcdir)/'`intrinsics/spread_generic.c
+
+string_intrinsics.o: intrinsics/string_intrinsics.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT string_intrinsics.o -MD -MP -MF "$(DEPDIR)/string_intrinsics.Tpo" -c -o string_intrinsics.o `test -f 'intrinsics/string_intrinsics.c' || echo '$(srcdir)/'`intrinsics/string_intrinsics.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/string_intrinsics.Tpo" "$(DEPDIR)/string_intrinsics.Po"; else rm -f "$(DEPDIR)/string_intrinsics.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/string_intrinsics.c' object='string_intrinsics.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/string_intrinsics.Po' tmpdepfile='$(DEPDIR)/string_intrinsics.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o string_intrinsics.o `test -f 'intrinsics/string_intrinsics.c' || echo '$(srcdir)/'`intrinsics/string_intrinsics.c
+
+string_intrinsics.obj: intrinsics/string_intrinsics.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT string_intrinsics.obj -MD -MP -MF "$(DEPDIR)/string_intrinsics.Tpo" -c -o string_intrinsics.obj `if test -f 'intrinsics/string_intrinsics.c'; then $(CYGPATH_W) 'intrinsics/string_intrinsics.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/string_intrinsics.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/string_intrinsics.Tpo" "$(DEPDIR)/string_intrinsics.Po"; else rm -f "$(DEPDIR)/string_intrinsics.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/string_intrinsics.c' object='string_intrinsics.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/string_intrinsics.Po' tmpdepfile='$(DEPDIR)/string_intrinsics.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o string_intrinsics.obj `if test -f 'intrinsics/string_intrinsics.c'; then $(CYGPATH_W) 'intrinsics/string_intrinsics.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/string_intrinsics.c'; fi`
+
+string_intrinsics.lo: intrinsics/string_intrinsics.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT string_intrinsics.lo -MD -MP -MF "$(DEPDIR)/string_intrinsics.Tpo" -c -o string_intrinsics.lo `test -f 'intrinsics/string_intrinsics.c' || echo '$(srcdir)/'`intrinsics/string_intrinsics.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/string_intrinsics.Tpo" "$(DEPDIR)/string_intrinsics.Plo"; else rm -f "$(DEPDIR)/string_intrinsics.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/string_intrinsics.c' object='string_intrinsics.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/string_intrinsics.Plo' tmpdepfile='$(DEPDIR)/string_intrinsics.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o string_intrinsics.lo `test -f 'intrinsics/string_intrinsics.c' || echo '$(srcdir)/'`intrinsics/string_intrinsics.c
+
+random.o: intrinsics/random.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT random.o -MD -MP -MF "$(DEPDIR)/random.Tpo" -c -o random.o `test -f 'intrinsics/random.c' || echo '$(srcdir)/'`intrinsics/random.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/random.Tpo" "$(DEPDIR)/random.Po"; else rm -f "$(DEPDIR)/random.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/random.c' object='random.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/random.Po' tmpdepfile='$(DEPDIR)/random.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o random.o `test -f 'intrinsics/random.c' || echo '$(srcdir)/'`intrinsics/random.c
+
+random.obj: intrinsics/random.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT random.obj -MD -MP -MF "$(DEPDIR)/random.Tpo" -c -o random.obj `if test -f 'intrinsics/random.c'; then $(CYGPATH_W) 'intrinsics/random.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/random.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/random.Tpo" "$(DEPDIR)/random.Po"; else rm -f "$(DEPDIR)/random.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/random.c' object='random.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/random.Po' tmpdepfile='$(DEPDIR)/random.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o random.obj `if test -f 'intrinsics/random.c'; then $(CYGPATH_W) 'intrinsics/random.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/random.c'; fi`
+
+random.lo: intrinsics/random.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT random.lo -MD -MP -MF "$(DEPDIR)/random.Tpo" -c -o random.lo `test -f 'intrinsics/random.c' || echo '$(srcdir)/'`intrinsics/random.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/random.Tpo" "$(DEPDIR)/random.Plo"; else rm -f "$(DEPDIR)/random.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/random.c' object='random.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/random.Plo' tmpdepfile='$(DEPDIR)/random.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o random.lo `test -f 'intrinsics/random.c' || echo '$(srcdir)/'`intrinsics/random.c
+
+reshape_generic.o: intrinsics/reshape_generic.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT reshape_generic.o -MD -MP -MF "$(DEPDIR)/reshape_generic.Tpo" -c -o reshape_generic.o `test -f 'intrinsics/reshape_generic.c' || echo '$(srcdir)/'`intrinsics/reshape_generic.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/reshape_generic.Tpo" "$(DEPDIR)/reshape_generic.Po"; else rm -f "$(DEPDIR)/reshape_generic.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/reshape_generic.c' object='reshape_generic.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/reshape_generic.Po' tmpdepfile='$(DEPDIR)/reshape_generic.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o reshape_generic.o `test -f 'intrinsics/reshape_generic.c' || echo '$(srcdir)/'`intrinsics/reshape_generic.c
+
+reshape_generic.obj: intrinsics/reshape_generic.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT reshape_generic.obj -MD -MP -MF "$(DEPDIR)/reshape_generic.Tpo" -c -o reshape_generic.obj `if test -f 'intrinsics/reshape_generic.c'; then $(CYGPATH_W) 'intrinsics/reshape_generic.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/reshape_generic.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/reshape_generic.Tpo" "$(DEPDIR)/reshape_generic.Po"; else rm -f "$(DEPDIR)/reshape_generic.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/reshape_generic.c' object='reshape_generic.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/reshape_generic.Po' tmpdepfile='$(DEPDIR)/reshape_generic.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o reshape_generic.obj `if test -f 'intrinsics/reshape_generic.c'; then $(CYGPATH_W) 'intrinsics/reshape_generic.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/reshape_generic.c'; fi`
+
+reshape_generic.lo: intrinsics/reshape_generic.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT reshape_generic.lo -MD -MP -MF "$(DEPDIR)/reshape_generic.Tpo" -c -o reshape_generic.lo `test -f 'intrinsics/reshape_generic.c' || echo '$(srcdir)/'`intrinsics/reshape_generic.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/reshape_generic.Tpo" "$(DEPDIR)/reshape_generic.Plo"; else rm -f "$(DEPDIR)/reshape_generic.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/reshape_generic.c' object='reshape_generic.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/reshape_generic.Plo' tmpdepfile='$(DEPDIR)/reshape_generic.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o reshape_generic.lo `test -f 'intrinsics/reshape_generic.c' || echo '$(srcdir)/'`intrinsics/reshape_generic.c
+
+reshape_packed.o: intrinsics/reshape_packed.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT reshape_packed.o -MD -MP -MF "$(DEPDIR)/reshape_packed.Tpo" -c -o reshape_packed.o `test -f 'intrinsics/reshape_packed.c' || echo '$(srcdir)/'`intrinsics/reshape_packed.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/reshape_packed.Tpo" "$(DEPDIR)/reshape_packed.Po"; else rm -f "$(DEPDIR)/reshape_packed.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/reshape_packed.c' object='reshape_packed.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/reshape_packed.Po' tmpdepfile='$(DEPDIR)/reshape_packed.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o reshape_packed.o `test -f 'intrinsics/reshape_packed.c' || echo '$(srcdir)/'`intrinsics/reshape_packed.c
+
+reshape_packed.obj: intrinsics/reshape_packed.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT reshape_packed.obj -MD -MP -MF "$(DEPDIR)/reshape_packed.Tpo" -c -o reshape_packed.obj `if test -f 'intrinsics/reshape_packed.c'; then $(CYGPATH_W) 'intrinsics/reshape_packed.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/reshape_packed.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/reshape_packed.Tpo" "$(DEPDIR)/reshape_packed.Po"; else rm -f "$(DEPDIR)/reshape_packed.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/reshape_packed.c' object='reshape_packed.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/reshape_packed.Po' tmpdepfile='$(DEPDIR)/reshape_packed.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o reshape_packed.obj `if test -f 'intrinsics/reshape_packed.c'; then $(CYGPATH_W) 'intrinsics/reshape_packed.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/reshape_packed.c'; fi`
+
+reshape_packed.lo: intrinsics/reshape_packed.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT reshape_packed.lo -MD -MP -MF "$(DEPDIR)/reshape_packed.Tpo" -c -o reshape_packed.lo `test -f 'intrinsics/reshape_packed.c' || echo '$(srcdir)/'`intrinsics/reshape_packed.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/reshape_packed.Tpo" "$(DEPDIR)/reshape_packed.Plo"; else rm -f "$(DEPDIR)/reshape_packed.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/reshape_packed.c' object='reshape_packed.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/reshape_packed.Plo' tmpdepfile='$(DEPDIR)/reshape_packed.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o reshape_packed.lo `test -f 'intrinsics/reshape_packed.c' || echo '$(srcdir)/'`intrinsics/reshape_packed.c
+
+transpose_generic.o: intrinsics/transpose_generic.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT transpose_generic.o -MD -MP -MF "$(DEPDIR)/transpose_generic.Tpo" -c -o transpose_generic.o `test -f 'intrinsics/transpose_generic.c' || echo '$(srcdir)/'`intrinsics/transpose_generic.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/transpose_generic.Tpo" "$(DEPDIR)/transpose_generic.Po"; else rm -f "$(DEPDIR)/transpose_generic.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/transpose_generic.c' object='transpose_generic.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/transpose_generic.Po' tmpdepfile='$(DEPDIR)/transpose_generic.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o transpose_generic.o `test -f 'intrinsics/transpose_generic.c' || echo '$(srcdir)/'`intrinsics/transpose_generic.c
+
+transpose_generic.obj: intrinsics/transpose_generic.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT transpose_generic.obj -MD -MP -MF "$(DEPDIR)/transpose_generic.Tpo" -c -o transpose_generic.obj `if test -f 'intrinsics/transpose_generic.c'; then $(CYGPATH_W) 'intrinsics/transpose_generic.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/transpose_generic.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/transpose_generic.Tpo" "$(DEPDIR)/transpose_generic.Po"; else rm -f "$(DEPDIR)/transpose_generic.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/transpose_generic.c' object='transpose_generic.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/transpose_generic.Po' tmpdepfile='$(DEPDIR)/transpose_generic.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o transpose_generic.obj `if test -f 'intrinsics/transpose_generic.c'; then $(CYGPATH_W) 'intrinsics/transpose_generic.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/transpose_generic.c'; fi`
+
+transpose_generic.lo: intrinsics/transpose_generic.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT transpose_generic.lo -MD -MP -MF "$(DEPDIR)/transpose_generic.Tpo" -c -o transpose_generic.lo `test -f 'intrinsics/transpose_generic.c' || echo '$(srcdir)/'`intrinsics/transpose_generic.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/transpose_generic.Tpo" "$(DEPDIR)/transpose_generic.Plo"; else rm -f "$(DEPDIR)/transpose_generic.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/transpose_generic.c' object='transpose_generic.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/transpose_generic.Plo' tmpdepfile='$(DEPDIR)/transpose_generic.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o transpose_generic.lo `test -f 'intrinsics/transpose_generic.c' || echo '$(srcdir)/'`intrinsics/transpose_generic.c
+
+unpack_generic.o: intrinsics/unpack_generic.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unpack_generic.o -MD -MP -MF "$(DEPDIR)/unpack_generic.Tpo" -c -o unpack_generic.o `test -f 'intrinsics/unpack_generic.c' || echo '$(srcdir)/'`intrinsics/unpack_generic.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/unpack_generic.Tpo" "$(DEPDIR)/unpack_generic.Po"; else rm -f "$(DEPDIR)/unpack_generic.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/unpack_generic.c' object='unpack_generic.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/unpack_generic.Po' tmpdepfile='$(DEPDIR)/unpack_generic.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unpack_generic.o `test -f 'intrinsics/unpack_generic.c' || echo '$(srcdir)/'`intrinsics/unpack_generic.c
+
+unpack_generic.obj: intrinsics/unpack_generic.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unpack_generic.obj -MD -MP -MF "$(DEPDIR)/unpack_generic.Tpo" -c -o unpack_generic.obj `if test -f 'intrinsics/unpack_generic.c'; then $(CYGPATH_W) 'intrinsics/unpack_generic.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/unpack_generic.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/unpack_generic.Tpo" "$(DEPDIR)/unpack_generic.Po"; else rm -f "$(DEPDIR)/unpack_generic.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/unpack_generic.c' object='unpack_generic.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/unpack_generic.Po' tmpdepfile='$(DEPDIR)/unpack_generic.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unpack_generic.obj `if test -f 'intrinsics/unpack_generic.c'; then $(CYGPATH_W) 'intrinsics/unpack_generic.c'; else $(CYGPATH_W) '$(srcdir)/intrinsics/unpack_generic.c'; fi`
+
+unpack_generic.lo: intrinsics/unpack_generic.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unpack_generic.lo -MD -MP -MF "$(DEPDIR)/unpack_generic.Tpo" -c -o unpack_generic.lo `test -f 'intrinsics/unpack_generic.c' || echo '$(srcdir)/'`intrinsics/unpack_generic.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/unpack_generic.Tpo" "$(DEPDIR)/unpack_generic.Plo"; else rm -f "$(DEPDIR)/unpack_generic.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/unpack_generic.c' object='unpack_generic.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/unpack_generic.Plo' tmpdepfile='$(DEPDIR)/unpack_generic.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unpack_generic.lo `test -f 'intrinsics/unpack_generic.c' || echo '$(srcdir)/'`intrinsics/unpack_generic.c
+
+in_pack_generic.o: runtime/in_pack_generic.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT in_pack_generic.o -MD -MP -MF "$(DEPDIR)/in_pack_generic.Tpo" -c -o in_pack_generic.o `test -f 'runtime/in_pack_generic.c' || echo '$(srcdir)/'`runtime/in_pack_generic.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/in_pack_generic.Tpo" "$(DEPDIR)/in_pack_generic.Po"; else rm -f "$(DEPDIR)/in_pack_generic.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/in_pack_generic.c' object='in_pack_generic.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/in_pack_generic.Po' tmpdepfile='$(DEPDIR)/in_pack_generic.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o in_pack_generic.o `test -f 'runtime/in_pack_generic.c' || echo '$(srcdir)/'`runtime/in_pack_generic.c
+
+in_pack_generic.obj: runtime/in_pack_generic.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT in_pack_generic.obj -MD -MP -MF "$(DEPDIR)/in_pack_generic.Tpo" -c -o in_pack_generic.obj `if test -f 'runtime/in_pack_generic.c'; then $(CYGPATH_W) 'runtime/in_pack_generic.c'; else $(CYGPATH_W) '$(srcdir)/runtime/in_pack_generic.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/in_pack_generic.Tpo" "$(DEPDIR)/in_pack_generic.Po"; else rm -f "$(DEPDIR)/in_pack_generic.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/in_pack_generic.c' object='in_pack_generic.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/in_pack_generic.Po' tmpdepfile='$(DEPDIR)/in_pack_generic.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o in_pack_generic.obj `if test -f 'runtime/in_pack_generic.c'; then $(CYGPATH_W) 'runtime/in_pack_generic.c'; else $(CYGPATH_W) '$(srcdir)/runtime/in_pack_generic.c'; fi`
+
+in_pack_generic.lo: runtime/in_pack_generic.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT in_pack_generic.lo -MD -MP -MF "$(DEPDIR)/in_pack_generic.Tpo" -c -o in_pack_generic.lo `test -f 'runtime/in_pack_generic.c' || echo '$(srcdir)/'`runtime/in_pack_generic.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/in_pack_generic.Tpo" "$(DEPDIR)/in_pack_generic.Plo"; else rm -f "$(DEPDIR)/in_pack_generic.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/in_pack_generic.c' object='in_pack_generic.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/in_pack_generic.Plo' tmpdepfile='$(DEPDIR)/in_pack_generic.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o in_pack_generic.lo `test -f 'runtime/in_pack_generic.c' || echo '$(srcdir)/'`runtime/in_pack_generic.c
+
+in_unpack_generic.o: runtime/in_unpack_generic.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT in_unpack_generic.o -MD -MP -MF "$(DEPDIR)/in_unpack_generic.Tpo" -c -o in_unpack_generic.o `test -f 'runtime/in_unpack_generic.c' || echo '$(srcdir)/'`runtime/in_unpack_generic.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/in_unpack_generic.Tpo" "$(DEPDIR)/in_unpack_generic.Po"; else rm -f "$(DEPDIR)/in_unpack_generic.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/in_unpack_generic.c' object='in_unpack_generic.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/in_unpack_generic.Po' tmpdepfile='$(DEPDIR)/in_unpack_generic.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o in_unpack_generic.o `test -f 'runtime/in_unpack_generic.c' || echo '$(srcdir)/'`runtime/in_unpack_generic.c
+
+in_unpack_generic.obj: runtime/in_unpack_generic.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT in_unpack_generic.obj -MD -MP -MF "$(DEPDIR)/in_unpack_generic.Tpo" -c -o in_unpack_generic.obj `if test -f 'runtime/in_unpack_generic.c'; then $(CYGPATH_W) 'runtime/in_unpack_generic.c'; else $(CYGPATH_W) '$(srcdir)/runtime/in_unpack_generic.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/in_unpack_generic.Tpo" "$(DEPDIR)/in_unpack_generic.Po"; else rm -f "$(DEPDIR)/in_unpack_generic.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/in_unpack_generic.c' object='in_unpack_generic.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/in_unpack_generic.Po' tmpdepfile='$(DEPDIR)/in_unpack_generic.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o in_unpack_generic.obj `if test -f 'runtime/in_unpack_generic.c'; then $(CYGPATH_W) 'runtime/in_unpack_generic.c'; else $(CYGPATH_W) '$(srcdir)/runtime/in_unpack_generic.c'; fi`
+
+in_unpack_generic.lo: runtime/in_unpack_generic.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT in_unpack_generic.lo -MD -MP -MF "$(DEPDIR)/in_unpack_generic.Tpo" -c -o in_unpack_generic.lo `test -f 'runtime/in_unpack_generic.c' || echo '$(srcdir)/'`runtime/in_unpack_generic.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/in_unpack_generic.Tpo" "$(DEPDIR)/in_unpack_generic.Plo"; else rm -f "$(DEPDIR)/in_unpack_generic.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/in_unpack_generic.c' object='in_unpack_generic.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/in_unpack_generic.Plo' tmpdepfile='$(DEPDIR)/in_unpack_generic.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o in_unpack_generic.lo `test -f 'runtime/in_unpack_generic.c' || echo '$(srcdir)/'`runtime/in_unpack_generic.c
+
+trig_c4.o: generated/trig_c4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT trig_c4.o -MD -MP -MF "$(DEPDIR)/trig_c4.Tpo" -c -o trig_c4.o `test -f 'generated/trig_c4.c' || echo '$(srcdir)/'`generated/trig_c4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/trig_c4.Tpo" "$(DEPDIR)/trig_c4.Po"; else rm -f "$(DEPDIR)/trig_c4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/trig_c4.c' object='trig_c4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/trig_c4.Po' tmpdepfile='$(DEPDIR)/trig_c4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o trig_c4.o `test -f 'generated/trig_c4.c' || echo '$(srcdir)/'`generated/trig_c4.c
+
+trig_c4.obj: generated/trig_c4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT trig_c4.obj -MD -MP -MF "$(DEPDIR)/trig_c4.Tpo" -c -o trig_c4.obj `if test -f 'generated/trig_c4.c'; then $(CYGPATH_W) 'generated/trig_c4.c'; else $(CYGPATH_W) '$(srcdir)/generated/trig_c4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/trig_c4.Tpo" "$(DEPDIR)/trig_c4.Po"; else rm -f "$(DEPDIR)/trig_c4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/trig_c4.c' object='trig_c4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/trig_c4.Po' tmpdepfile='$(DEPDIR)/trig_c4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o trig_c4.obj `if test -f 'generated/trig_c4.c'; then $(CYGPATH_W) 'generated/trig_c4.c'; else $(CYGPATH_W) '$(srcdir)/generated/trig_c4.c'; fi`
+
+trig_c4.lo: generated/trig_c4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT trig_c4.lo -MD -MP -MF "$(DEPDIR)/trig_c4.Tpo" -c -o trig_c4.lo `test -f 'generated/trig_c4.c' || echo '$(srcdir)/'`generated/trig_c4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/trig_c4.Tpo" "$(DEPDIR)/trig_c4.Plo"; else rm -f "$(DEPDIR)/trig_c4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/trig_c4.c' object='trig_c4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/trig_c4.Plo' tmpdepfile='$(DEPDIR)/trig_c4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o trig_c4.lo `test -f 'generated/trig_c4.c' || echo '$(srcdir)/'`generated/trig_c4.c
+
+trig_c8.o: generated/trig_c8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT trig_c8.o -MD -MP -MF "$(DEPDIR)/trig_c8.Tpo" -c -o trig_c8.o `test -f 'generated/trig_c8.c' || echo '$(srcdir)/'`generated/trig_c8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/trig_c8.Tpo" "$(DEPDIR)/trig_c8.Po"; else rm -f "$(DEPDIR)/trig_c8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/trig_c8.c' object='trig_c8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/trig_c8.Po' tmpdepfile='$(DEPDIR)/trig_c8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o trig_c8.o `test -f 'generated/trig_c8.c' || echo '$(srcdir)/'`generated/trig_c8.c
+
+trig_c8.obj: generated/trig_c8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT trig_c8.obj -MD -MP -MF "$(DEPDIR)/trig_c8.Tpo" -c -o trig_c8.obj `if test -f 'generated/trig_c8.c'; then $(CYGPATH_W) 'generated/trig_c8.c'; else $(CYGPATH_W) '$(srcdir)/generated/trig_c8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/trig_c8.Tpo" "$(DEPDIR)/trig_c8.Po"; else rm -f "$(DEPDIR)/trig_c8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/trig_c8.c' object='trig_c8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/trig_c8.Po' tmpdepfile='$(DEPDIR)/trig_c8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o trig_c8.obj `if test -f 'generated/trig_c8.c'; then $(CYGPATH_W) 'generated/trig_c8.c'; else $(CYGPATH_W) '$(srcdir)/generated/trig_c8.c'; fi`
+
+trig_c8.lo: generated/trig_c8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT trig_c8.lo -MD -MP -MF "$(DEPDIR)/trig_c8.Tpo" -c -o trig_c8.lo `test -f 'generated/trig_c8.c' || echo '$(srcdir)/'`generated/trig_c8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/trig_c8.Tpo" "$(DEPDIR)/trig_c8.Plo"; else rm -f "$(DEPDIR)/trig_c8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/trig_c8.c' object='trig_c8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/trig_c8.Plo' tmpdepfile='$(DEPDIR)/trig_c8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o trig_c8.lo `test -f 'generated/trig_c8.c' || echo '$(srcdir)/'`generated/trig_c8.c
+
+exp_c4.o: generated/exp_c4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT exp_c4.o -MD -MP -MF "$(DEPDIR)/exp_c4.Tpo" -c -o exp_c4.o `test -f 'generated/exp_c4.c' || echo '$(srcdir)/'`generated/exp_c4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/exp_c4.Tpo" "$(DEPDIR)/exp_c4.Po"; else rm -f "$(DEPDIR)/exp_c4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/exp_c4.c' object='exp_c4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/exp_c4.Po' tmpdepfile='$(DEPDIR)/exp_c4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o exp_c4.o `test -f 'generated/exp_c4.c' || echo '$(srcdir)/'`generated/exp_c4.c
+
+exp_c4.obj: generated/exp_c4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT exp_c4.obj -MD -MP -MF "$(DEPDIR)/exp_c4.Tpo" -c -o exp_c4.obj `if test -f 'generated/exp_c4.c'; then $(CYGPATH_W) 'generated/exp_c4.c'; else $(CYGPATH_W) '$(srcdir)/generated/exp_c4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/exp_c4.Tpo" "$(DEPDIR)/exp_c4.Po"; else rm -f "$(DEPDIR)/exp_c4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/exp_c4.c' object='exp_c4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/exp_c4.Po' tmpdepfile='$(DEPDIR)/exp_c4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o exp_c4.obj `if test -f 'generated/exp_c4.c'; then $(CYGPATH_W) 'generated/exp_c4.c'; else $(CYGPATH_W) '$(srcdir)/generated/exp_c4.c'; fi`
+
+exp_c4.lo: generated/exp_c4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT exp_c4.lo -MD -MP -MF "$(DEPDIR)/exp_c4.Tpo" -c -o exp_c4.lo `test -f 'generated/exp_c4.c' || echo '$(srcdir)/'`generated/exp_c4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/exp_c4.Tpo" "$(DEPDIR)/exp_c4.Plo"; else rm -f "$(DEPDIR)/exp_c4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/exp_c4.c' object='exp_c4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/exp_c4.Plo' tmpdepfile='$(DEPDIR)/exp_c4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o exp_c4.lo `test -f 'generated/exp_c4.c' || echo '$(srcdir)/'`generated/exp_c4.c
+
+exp_c8.o: generated/exp_c8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT exp_c8.o -MD -MP -MF "$(DEPDIR)/exp_c8.Tpo" -c -o exp_c8.o `test -f 'generated/exp_c8.c' || echo '$(srcdir)/'`generated/exp_c8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/exp_c8.Tpo" "$(DEPDIR)/exp_c8.Po"; else rm -f "$(DEPDIR)/exp_c8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/exp_c8.c' object='exp_c8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/exp_c8.Po' tmpdepfile='$(DEPDIR)/exp_c8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o exp_c8.o `test -f 'generated/exp_c8.c' || echo '$(srcdir)/'`generated/exp_c8.c
+
+exp_c8.obj: generated/exp_c8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT exp_c8.obj -MD -MP -MF "$(DEPDIR)/exp_c8.Tpo" -c -o exp_c8.obj `if test -f 'generated/exp_c8.c'; then $(CYGPATH_W) 'generated/exp_c8.c'; else $(CYGPATH_W) '$(srcdir)/generated/exp_c8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/exp_c8.Tpo" "$(DEPDIR)/exp_c8.Po"; else rm -f "$(DEPDIR)/exp_c8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/exp_c8.c' object='exp_c8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/exp_c8.Po' tmpdepfile='$(DEPDIR)/exp_c8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o exp_c8.obj `if test -f 'generated/exp_c8.c'; then $(CYGPATH_W) 'generated/exp_c8.c'; else $(CYGPATH_W) '$(srcdir)/generated/exp_c8.c'; fi`
+
+exp_c8.lo: generated/exp_c8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT exp_c8.lo -MD -MP -MF "$(DEPDIR)/exp_c8.Tpo" -c -o exp_c8.lo `test -f 'generated/exp_c8.c' || echo '$(srcdir)/'`generated/exp_c8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/exp_c8.Tpo" "$(DEPDIR)/exp_c8.Plo"; else rm -f "$(DEPDIR)/exp_c8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/exp_c8.c' object='exp_c8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/exp_c8.Plo' tmpdepfile='$(DEPDIR)/exp_c8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o exp_c8.lo `test -f 'generated/exp_c8.c' || echo '$(srcdir)/'`generated/exp_c8.c
+
+hyp_c4.o: generated/hyp_c4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hyp_c4.o -MD -MP -MF "$(DEPDIR)/hyp_c4.Tpo" -c -o hyp_c4.o `test -f 'generated/hyp_c4.c' || echo '$(srcdir)/'`generated/hyp_c4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/hyp_c4.Tpo" "$(DEPDIR)/hyp_c4.Po"; else rm -f "$(DEPDIR)/hyp_c4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/hyp_c4.c' object='hyp_c4.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/hyp_c4.Po' tmpdepfile='$(DEPDIR)/hyp_c4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hyp_c4.o `test -f 'generated/hyp_c4.c' || echo '$(srcdir)/'`generated/hyp_c4.c
+
+hyp_c4.obj: generated/hyp_c4.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hyp_c4.obj -MD -MP -MF "$(DEPDIR)/hyp_c4.Tpo" -c -o hyp_c4.obj `if test -f 'generated/hyp_c4.c'; then $(CYGPATH_W) 'generated/hyp_c4.c'; else $(CYGPATH_W) '$(srcdir)/generated/hyp_c4.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/hyp_c4.Tpo" "$(DEPDIR)/hyp_c4.Po"; else rm -f "$(DEPDIR)/hyp_c4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/hyp_c4.c' object='hyp_c4.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/hyp_c4.Po' tmpdepfile='$(DEPDIR)/hyp_c4.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hyp_c4.obj `if test -f 'generated/hyp_c4.c'; then $(CYGPATH_W) 'generated/hyp_c4.c'; else $(CYGPATH_W) '$(srcdir)/generated/hyp_c4.c'; fi`
+
+hyp_c4.lo: generated/hyp_c4.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hyp_c4.lo -MD -MP -MF "$(DEPDIR)/hyp_c4.Tpo" -c -o hyp_c4.lo `test -f 'generated/hyp_c4.c' || echo '$(srcdir)/'`generated/hyp_c4.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/hyp_c4.Tpo" "$(DEPDIR)/hyp_c4.Plo"; else rm -f "$(DEPDIR)/hyp_c4.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/hyp_c4.c' object='hyp_c4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/hyp_c4.Plo' tmpdepfile='$(DEPDIR)/hyp_c4.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hyp_c4.lo `test -f 'generated/hyp_c4.c' || echo '$(srcdir)/'`generated/hyp_c4.c
+
+hyp_c8.o: generated/hyp_c8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hyp_c8.o -MD -MP -MF "$(DEPDIR)/hyp_c8.Tpo" -c -o hyp_c8.o `test -f 'generated/hyp_c8.c' || echo '$(srcdir)/'`generated/hyp_c8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/hyp_c8.Tpo" "$(DEPDIR)/hyp_c8.Po"; else rm -f "$(DEPDIR)/hyp_c8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/hyp_c8.c' object='hyp_c8.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/hyp_c8.Po' tmpdepfile='$(DEPDIR)/hyp_c8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hyp_c8.o `test -f 'generated/hyp_c8.c' || echo '$(srcdir)/'`generated/hyp_c8.c
+
+hyp_c8.obj: generated/hyp_c8.c
+@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hyp_c8.obj -MD -MP -MF "$(DEPDIR)/hyp_c8.Tpo" -c -o hyp_c8.obj `if test -f 'generated/hyp_c8.c'; then $(CYGPATH_W) 'generated/hyp_c8.c'; else $(CYGPATH_W) '$(srcdir)/generated/hyp_c8.c'; fi`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/hyp_c8.Tpo" "$(DEPDIR)/hyp_c8.Po"; else rm -f "$(DEPDIR)/hyp_c8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/hyp_c8.c' object='hyp_c8.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/hyp_c8.Po' tmpdepfile='$(DEPDIR)/hyp_c8.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hyp_c8.obj `if test -f 'generated/hyp_c8.c'; then $(CYGPATH_W) 'generated/hyp_c8.c'; else $(CYGPATH_W) '$(srcdir)/generated/hyp_c8.c'; fi`
+
+hyp_c8.lo: generated/hyp_c8.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hyp_c8.lo -MD -MP -MF "$(DEPDIR)/hyp_c8.Tpo" -c -o hyp_c8.lo `test -f 'generated/hyp_c8.c' || echo '$(srcdir)/'`generated/hyp_c8.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/hyp_c8.Tpo" "$(DEPDIR)/hyp_c8.Plo"; else rm -f "$(DEPDIR)/hyp_c8.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='generated/hyp_c8.c' object='hyp_c8.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/hyp_c8.Plo' tmpdepfile='$(DEPDIR)/hyp_c8.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hyp_c8.lo `test -f 'generated/hyp_c8.c' || echo '$(srcdir)/'`generated/hyp_c8.c
+
+.f90.o:
+ $(F77COMPILE) -c -o $@ $<
+
+.f90.obj:
+ $(F77COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.f90.lo:
+ $(LTF77COMPILE) -c -o $@ $<
+
+selected_kind.o: intrinsics/selected_kind.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o selected_kind.o `test -f 'intrinsics/selected_kind.f90' || echo '$(srcdir)/'`intrinsics/selected_kind.f90
+
+selected_kind.obj: intrinsics/selected_kind.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o selected_kind.obj `if test -f 'intrinsics/selected_kind.f90'; then $(CYGPATH_W) 'intrinsics/selected_kind.f90'; else $(CYGPATH_W) '$(srcdir)/intrinsics/selected_kind.f90'; fi`
+
+selected_kind.lo: intrinsics/selected_kind.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o selected_kind.lo `test -f 'intrinsics/selected_kind.f90' || echo '$(srcdir)/'`intrinsics/selected_kind.f90
+
+_abs_c4.o: generated/_abs_c4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _abs_c4.o `test -f 'generated/_abs_c4.f90' || echo '$(srcdir)/'`generated/_abs_c4.f90
+
+_abs_c4.obj: generated/_abs_c4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _abs_c4.obj `if test -f 'generated/_abs_c4.f90'; then $(CYGPATH_W) 'generated/_abs_c4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_abs_c4.f90'; fi`
+
+_abs_c4.lo: generated/_abs_c4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _abs_c4.lo `test -f 'generated/_abs_c4.f90' || echo '$(srcdir)/'`generated/_abs_c4.f90
+
+_abs_c8.o: generated/_abs_c8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _abs_c8.o `test -f 'generated/_abs_c8.f90' || echo '$(srcdir)/'`generated/_abs_c8.f90
+
+_abs_c8.obj: generated/_abs_c8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _abs_c8.obj `if test -f 'generated/_abs_c8.f90'; then $(CYGPATH_W) 'generated/_abs_c8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_abs_c8.f90'; fi`
+
+_abs_c8.lo: generated/_abs_c8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _abs_c8.lo `test -f 'generated/_abs_c8.f90' || echo '$(srcdir)/'`generated/_abs_c8.f90
+
+_abs_i4.o: generated/_abs_i4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _abs_i4.o `test -f 'generated/_abs_i4.f90' || echo '$(srcdir)/'`generated/_abs_i4.f90
+
+_abs_i4.obj: generated/_abs_i4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _abs_i4.obj `if test -f 'generated/_abs_i4.f90'; then $(CYGPATH_W) 'generated/_abs_i4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_abs_i4.f90'; fi`
+
+_abs_i4.lo: generated/_abs_i4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _abs_i4.lo `test -f 'generated/_abs_i4.f90' || echo '$(srcdir)/'`generated/_abs_i4.f90
+
+_abs_i8.o: generated/_abs_i8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _abs_i8.o `test -f 'generated/_abs_i8.f90' || echo '$(srcdir)/'`generated/_abs_i8.f90
+
+_abs_i8.obj: generated/_abs_i8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _abs_i8.obj `if test -f 'generated/_abs_i8.f90'; then $(CYGPATH_W) 'generated/_abs_i8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_abs_i8.f90'; fi`
+
+_abs_i8.lo: generated/_abs_i8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _abs_i8.lo `test -f 'generated/_abs_i8.f90' || echo '$(srcdir)/'`generated/_abs_i8.f90
+
+_abs_r4.o: generated/_abs_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _abs_r4.o `test -f 'generated/_abs_r4.f90' || echo '$(srcdir)/'`generated/_abs_r4.f90
+
+_abs_r4.obj: generated/_abs_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _abs_r4.obj `if test -f 'generated/_abs_r4.f90'; then $(CYGPATH_W) 'generated/_abs_r4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_abs_r4.f90'; fi`
+
+_abs_r4.lo: generated/_abs_r4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _abs_r4.lo `test -f 'generated/_abs_r4.f90' || echo '$(srcdir)/'`generated/_abs_r4.f90
+
+_abs_r8.o: generated/_abs_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _abs_r8.o `test -f 'generated/_abs_r8.f90' || echo '$(srcdir)/'`generated/_abs_r8.f90
+
+_abs_r8.obj: generated/_abs_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _abs_r8.obj `if test -f 'generated/_abs_r8.f90'; then $(CYGPATH_W) 'generated/_abs_r8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_abs_r8.f90'; fi`
+
+_abs_r8.lo: generated/_abs_r8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _abs_r8.lo `test -f 'generated/_abs_r8.f90' || echo '$(srcdir)/'`generated/_abs_r8.f90
+
+_exp_r4.o: generated/_exp_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _exp_r4.o `test -f 'generated/_exp_r4.f90' || echo '$(srcdir)/'`generated/_exp_r4.f90
+
+_exp_r4.obj: generated/_exp_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _exp_r4.obj `if test -f 'generated/_exp_r4.f90'; then $(CYGPATH_W) 'generated/_exp_r4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_exp_r4.f90'; fi`
+
+_exp_r4.lo: generated/_exp_r4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _exp_r4.lo `test -f 'generated/_exp_r4.f90' || echo '$(srcdir)/'`generated/_exp_r4.f90
+
+_exp_r8.o: generated/_exp_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _exp_r8.o `test -f 'generated/_exp_r8.f90' || echo '$(srcdir)/'`generated/_exp_r8.f90
+
+_exp_r8.obj: generated/_exp_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _exp_r8.obj `if test -f 'generated/_exp_r8.f90'; then $(CYGPATH_W) 'generated/_exp_r8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_exp_r8.f90'; fi`
+
+_exp_r8.lo: generated/_exp_r8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _exp_r8.lo `test -f 'generated/_exp_r8.f90' || echo '$(srcdir)/'`generated/_exp_r8.f90
+
+_exp_c4.o: generated/_exp_c4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _exp_c4.o `test -f 'generated/_exp_c4.f90' || echo '$(srcdir)/'`generated/_exp_c4.f90
+
+_exp_c4.obj: generated/_exp_c4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _exp_c4.obj `if test -f 'generated/_exp_c4.f90'; then $(CYGPATH_W) 'generated/_exp_c4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_exp_c4.f90'; fi`
+
+_exp_c4.lo: generated/_exp_c4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _exp_c4.lo `test -f 'generated/_exp_c4.f90' || echo '$(srcdir)/'`generated/_exp_c4.f90
+
+_exp_c8.o: generated/_exp_c8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _exp_c8.o `test -f 'generated/_exp_c8.f90' || echo '$(srcdir)/'`generated/_exp_c8.f90
+
+_exp_c8.obj: generated/_exp_c8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _exp_c8.obj `if test -f 'generated/_exp_c8.f90'; then $(CYGPATH_W) 'generated/_exp_c8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_exp_c8.f90'; fi`
+
+_exp_c8.lo: generated/_exp_c8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _exp_c8.lo `test -f 'generated/_exp_c8.f90' || echo '$(srcdir)/'`generated/_exp_c8.f90
+
+_log_r4.o: generated/_log_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _log_r4.o `test -f 'generated/_log_r4.f90' || echo '$(srcdir)/'`generated/_log_r4.f90
+
+_log_r4.obj: generated/_log_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _log_r4.obj `if test -f 'generated/_log_r4.f90'; then $(CYGPATH_W) 'generated/_log_r4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_log_r4.f90'; fi`
+
+_log_r4.lo: generated/_log_r4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _log_r4.lo `test -f 'generated/_log_r4.f90' || echo '$(srcdir)/'`generated/_log_r4.f90
+
+_log_r8.o: generated/_log_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _log_r8.o `test -f 'generated/_log_r8.f90' || echo '$(srcdir)/'`generated/_log_r8.f90
+
+_log_r8.obj: generated/_log_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _log_r8.obj `if test -f 'generated/_log_r8.f90'; then $(CYGPATH_W) 'generated/_log_r8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_log_r8.f90'; fi`
+
+_log_r8.lo: generated/_log_r8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _log_r8.lo `test -f 'generated/_log_r8.f90' || echo '$(srcdir)/'`generated/_log_r8.f90
+
+_log_c4.o: generated/_log_c4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _log_c4.o `test -f 'generated/_log_c4.f90' || echo '$(srcdir)/'`generated/_log_c4.f90
+
+_log_c4.obj: generated/_log_c4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _log_c4.obj `if test -f 'generated/_log_c4.f90'; then $(CYGPATH_W) 'generated/_log_c4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_log_c4.f90'; fi`
+
+_log_c4.lo: generated/_log_c4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _log_c4.lo `test -f 'generated/_log_c4.f90' || echo '$(srcdir)/'`generated/_log_c4.f90
+
+_log_c8.o: generated/_log_c8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _log_c8.o `test -f 'generated/_log_c8.f90' || echo '$(srcdir)/'`generated/_log_c8.f90
+
+_log_c8.obj: generated/_log_c8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _log_c8.obj `if test -f 'generated/_log_c8.f90'; then $(CYGPATH_W) 'generated/_log_c8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_log_c8.f90'; fi`
+
+_log_c8.lo: generated/_log_c8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _log_c8.lo `test -f 'generated/_log_c8.f90' || echo '$(srcdir)/'`generated/_log_c8.f90
+
+_log10_r4.o: generated/_log10_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _log10_r4.o `test -f 'generated/_log10_r4.f90' || echo '$(srcdir)/'`generated/_log10_r4.f90
+
+_log10_r4.obj: generated/_log10_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _log10_r4.obj `if test -f 'generated/_log10_r4.f90'; then $(CYGPATH_W) 'generated/_log10_r4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_log10_r4.f90'; fi`
+
+_log10_r4.lo: generated/_log10_r4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _log10_r4.lo `test -f 'generated/_log10_r4.f90' || echo '$(srcdir)/'`generated/_log10_r4.f90
+
+_log10_r8.o: generated/_log10_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _log10_r8.o `test -f 'generated/_log10_r8.f90' || echo '$(srcdir)/'`generated/_log10_r8.f90
+
+_log10_r8.obj: generated/_log10_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _log10_r8.obj `if test -f 'generated/_log10_r8.f90'; then $(CYGPATH_W) 'generated/_log10_r8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_log10_r8.f90'; fi`
+
+_log10_r8.lo: generated/_log10_r8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _log10_r8.lo `test -f 'generated/_log10_r8.f90' || echo '$(srcdir)/'`generated/_log10_r8.f90
+
+_sqrt_r4.o: generated/_sqrt_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sqrt_r4.o `test -f 'generated/_sqrt_r4.f90' || echo '$(srcdir)/'`generated/_sqrt_r4.f90
+
+_sqrt_r4.obj: generated/_sqrt_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sqrt_r4.obj `if test -f 'generated/_sqrt_r4.f90'; then $(CYGPATH_W) 'generated/_sqrt_r4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_sqrt_r4.f90'; fi`
+
+_sqrt_r4.lo: generated/_sqrt_r4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sqrt_r4.lo `test -f 'generated/_sqrt_r4.f90' || echo '$(srcdir)/'`generated/_sqrt_r4.f90
+
+_sqrt_r8.o: generated/_sqrt_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sqrt_r8.o `test -f 'generated/_sqrt_r8.f90' || echo '$(srcdir)/'`generated/_sqrt_r8.f90
+
+_sqrt_r8.obj: generated/_sqrt_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sqrt_r8.obj `if test -f 'generated/_sqrt_r8.f90'; then $(CYGPATH_W) 'generated/_sqrt_r8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_sqrt_r8.f90'; fi`
+
+_sqrt_r8.lo: generated/_sqrt_r8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sqrt_r8.lo `test -f 'generated/_sqrt_r8.f90' || echo '$(srcdir)/'`generated/_sqrt_r8.f90
+
+_sqrt_c4.o: generated/_sqrt_c4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sqrt_c4.o `test -f 'generated/_sqrt_c4.f90' || echo '$(srcdir)/'`generated/_sqrt_c4.f90
+
+_sqrt_c4.obj: generated/_sqrt_c4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sqrt_c4.obj `if test -f 'generated/_sqrt_c4.f90'; then $(CYGPATH_W) 'generated/_sqrt_c4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_sqrt_c4.f90'; fi`
+
+_sqrt_c4.lo: generated/_sqrt_c4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sqrt_c4.lo `test -f 'generated/_sqrt_c4.f90' || echo '$(srcdir)/'`generated/_sqrt_c4.f90
+
+_sqrt_c8.o: generated/_sqrt_c8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sqrt_c8.o `test -f 'generated/_sqrt_c8.f90' || echo '$(srcdir)/'`generated/_sqrt_c8.f90
+
+_sqrt_c8.obj: generated/_sqrt_c8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sqrt_c8.obj `if test -f 'generated/_sqrt_c8.f90'; then $(CYGPATH_W) 'generated/_sqrt_c8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_sqrt_c8.f90'; fi`
+
+_sqrt_c8.lo: generated/_sqrt_c8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sqrt_c8.lo `test -f 'generated/_sqrt_c8.f90' || echo '$(srcdir)/'`generated/_sqrt_c8.f90
+
+_asin_r4.o: generated/_asin_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _asin_r4.o `test -f 'generated/_asin_r4.f90' || echo '$(srcdir)/'`generated/_asin_r4.f90
+
+_asin_r4.obj: generated/_asin_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _asin_r4.obj `if test -f 'generated/_asin_r4.f90'; then $(CYGPATH_W) 'generated/_asin_r4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_asin_r4.f90'; fi`
+
+_asin_r4.lo: generated/_asin_r4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _asin_r4.lo `test -f 'generated/_asin_r4.f90' || echo '$(srcdir)/'`generated/_asin_r4.f90
+
+_asin_r8.o: generated/_asin_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _asin_r8.o `test -f 'generated/_asin_r8.f90' || echo '$(srcdir)/'`generated/_asin_r8.f90
+
+_asin_r8.obj: generated/_asin_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _asin_r8.obj `if test -f 'generated/_asin_r8.f90'; then $(CYGPATH_W) 'generated/_asin_r8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_asin_r8.f90'; fi`
+
+_asin_r8.lo: generated/_asin_r8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _asin_r8.lo `test -f 'generated/_asin_r8.f90' || echo '$(srcdir)/'`generated/_asin_r8.f90
+
+_acos_r4.o: generated/_acos_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _acos_r4.o `test -f 'generated/_acos_r4.f90' || echo '$(srcdir)/'`generated/_acos_r4.f90
+
+_acos_r4.obj: generated/_acos_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _acos_r4.obj `if test -f 'generated/_acos_r4.f90'; then $(CYGPATH_W) 'generated/_acos_r4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_acos_r4.f90'; fi`
+
+_acos_r4.lo: generated/_acos_r4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _acos_r4.lo `test -f 'generated/_acos_r4.f90' || echo '$(srcdir)/'`generated/_acos_r4.f90
+
+_acos_r8.o: generated/_acos_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _acos_r8.o `test -f 'generated/_acos_r8.f90' || echo '$(srcdir)/'`generated/_acos_r8.f90
+
+_acos_r8.obj: generated/_acos_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _acos_r8.obj `if test -f 'generated/_acos_r8.f90'; then $(CYGPATH_W) 'generated/_acos_r8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_acos_r8.f90'; fi`
+
+_acos_r8.lo: generated/_acos_r8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _acos_r8.lo `test -f 'generated/_acos_r8.f90' || echo '$(srcdir)/'`generated/_acos_r8.f90
+
+_atan_r4.o: generated/_atan_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _atan_r4.o `test -f 'generated/_atan_r4.f90' || echo '$(srcdir)/'`generated/_atan_r4.f90
+
+_atan_r4.obj: generated/_atan_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _atan_r4.obj `if test -f 'generated/_atan_r4.f90'; then $(CYGPATH_W) 'generated/_atan_r4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_atan_r4.f90'; fi`
+
+_atan_r4.lo: generated/_atan_r4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _atan_r4.lo `test -f 'generated/_atan_r4.f90' || echo '$(srcdir)/'`generated/_atan_r4.f90
+
+_atan_r8.o: generated/_atan_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _atan_r8.o `test -f 'generated/_atan_r8.f90' || echo '$(srcdir)/'`generated/_atan_r8.f90
+
+_atan_r8.obj: generated/_atan_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _atan_r8.obj `if test -f 'generated/_atan_r8.f90'; then $(CYGPATH_W) 'generated/_atan_r8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_atan_r8.f90'; fi`
+
+_atan_r8.lo: generated/_atan_r8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _atan_r8.lo `test -f 'generated/_atan_r8.f90' || echo '$(srcdir)/'`generated/_atan_r8.f90
+
+_sin_r4.o: generated/_sin_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sin_r4.o `test -f 'generated/_sin_r4.f90' || echo '$(srcdir)/'`generated/_sin_r4.f90
+
+_sin_r4.obj: generated/_sin_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sin_r4.obj `if test -f 'generated/_sin_r4.f90'; then $(CYGPATH_W) 'generated/_sin_r4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_sin_r4.f90'; fi`
+
+_sin_r4.lo: generated/_sin_r4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sin_r4.lo `test -f 'generated/_sin_r4.f90' || echo '$(srcdir)/'`generated/_sin_r4.f90
+
+_sin_r8.o: generated/_sin_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sin_r8.o `test -f 'generated/_sin_r8.f90' || echo '$(srcdir)/'`generated/_sin_r8.f90
+
+_sin_r8.obj: generated/_sin_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sin_r8.obj `if test -f 'generated/_sin_r8.f90'; then $(CYGPATH_W) 'generated/_sin_r8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_sin_r8.f90'; fi`
+
+_sin_r8.lo: generated/_sin_r8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sin_r8.lo `test -f 'generated/_sin_r8.f90' || echo '$(srcdir)/'`generated/_sin_r8.f90
+
+_sin_c4.o: generated/_sin_c4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sin_c4.o `test -f 'generated/_sin_c4.f90' || echo '$(srcdir)/'`generated/_sin_c4.f90
+
+_sin_c4.obj: generated/_sin_c4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sin_c4.obj `if test -f 'generated/_sin_c4.f90'; then $(CYGPATH_W) 'generated/_sin_c4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_sin_c4.f90'; fi`
+
+_sin_c4.lo: generated/_sin_c4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sin_c4.lo `test -f 'generated/_sin_c4.f90' || echo '$(srcdir)/'`generated/_sin_c4.f90
+
+_sin_c8.o: generated/_sin_c8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sin_c8.o `test -f 'generated/_sin_c8.f90' || echo '$(srcdir)/'`generated/_sin_c8.f90
+
+_sin_c8.obj: generated/_sin_c8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sin_c8.obj `if test -f 'generated/_sin_c8.f90'; then $(CYGPATH_W) 'generated/_sin_c8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_sin_c8.f90'; fi`
+
+_sin_c8.lo: generated/_sin_c8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sin_c8.lo `test -f 'generated/_sin_c8.f90' || echo '$(srcdir)/'`generated/_sin_c8.f90
+
+_cos_r4.o: generated/_cos_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _cos_r4.o `test -f 'generated/_cos_r4.f90' || echo '$(srcdir)/'`generated/_cos_r4.f90
+
+_cos_r4.obj: generated/_cos_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _cos_r4.obj `if test -f 'generated/_cos_r4.f90'; then $(CYGPATH_W) 'generated/_cos_r4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_cos_r4.f90'; fi`
+
+_cos_r4.lo: generated/_cos_r4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _cos_r4.lo `test -f 'generated/_cos_r4.f90' || echo '$(srcdir)/'`generated/_cos_r4.f90
+
+_cos_r8.o: generated/_cos_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _cos_r8.o `test -f 'generated/_cos_r8.f90' || echo '$(srcdir)/'`generated/_cos_r8.f90
+
+_cos_r8.obj: generated/_cos_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _cos_r8.obj `if test -f 'generated/_cos_r8.f90'; then $(CYGPATH_W) 'generated/_cos_r8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_cos_r8.f90'; fi`
+
+_cos_r8.lo: generated/_cos_r8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _cos_r8.lo `test -f 'generated/_cos_r8.f90' || echo '$(srcdir)/'`generated/_cos_r8.f90
+
+_cos_c4.o: generated/_cos_c4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _cos_c4.o `test -f 'generated/_cos_c4.f90' || echo '$(srcdir)/'`generated/_cos_c4.f90
+
+_cos_c4.obj: generated/_cos_c4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _cos_c4.obj `if test -f 'generated/_cos_c4.f90'; then $(CYGPATH_W) 'generated/_cos_c4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_cos_c4.f90'; fi`
+
+_cos_c4.lo: generated/_cos_c4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _cos_c4.lo `test -f 'generated/_cos_c4.f90' || echo '$(srcdir)/'`generated/_cos_c4.f90
+
+_cos_c8.o: generated/_cos_c8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _cos_c8.o `test -f 'generated/_cos_c8.f90' || echo '$(srcdir)/'`generated/_cos_c8.f90
+
+_cos_c8.obj: generated/_cos_c8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _cos_c8.obj `if test -f 'generated/_cos_c8.f90'; then $(CYGPATH_W) 'generated/_cos_c8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_cos_c8.f90'; fi`
+
+_cos_c8.lo: generated/_cos_c8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _cos_c8.lo `test -f 'generated/_cos_c8.f90' || echo '$(srcdir)/'`generated/_cos_c8.f90
+
+_tan_r4.o: generated/_tan_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _tan_r4.o `test -f 'generated/_tan_r4.f90' || echo '$(srcdir)/'`generated/_tan_r4.f90
+
+_tan_r4.obj: generated/_tan_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _tan_r4.obj `if test -f 'generated/_tan_r4.f90'; then $(CYGPATH_W) 'generated/_tan_r4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_tan_r4.f90'; fi`
+
+_tan_r4.lo: generated/_tan_r4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _tan_r4.lo `test -f 'generated/_tan_r4.f90' || echo '$(srcdir)/'`generated/_tan_r4.f90
+
+_tan_r8.o: generated/_tan_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _tan_r8.o `test -f 'generated/_tan_r8.f90' || echo '$(srcdir)/'`generated/_tan_r8.f90
+
+_tan_r8.obj: generated/_tan_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _tan_r8.obj `if test -f 'generated/_tan_r8.f90'; then $(CYGPATH_W) 'generated/_tan_r8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_tan_r8.f90'; fi`
+
+_tan_r8.lo: generated/_tan_r8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _tan_r8.lo `test -f 'generated/_tan_r8.f90' || echo '$(srcdir)/'`generated/_tan_r8.f90
+
+_sinh_r4.o: generated/_sinh_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sinh_r4.o `test -f 'generated/_sinh_r4.f90' || echo '$(srcdir)/'`generated/_sinh_r4.f90
+
+_sinh_r4.obj: generated/_sinh_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sinh_r4.obj `if test -f 'generated/_sinh_r4.f90'; then $(CYGPATH_W) 'generated/_sinh_r4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_sinh_r4.f90'; fi`
+
+_sinh_r4.lo: generated/_sinh_r4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sinh_r4.lo `test -f 'generated/_sinh_r4.f90' || echo '$(srcdir)/'`generated/_sinh_r4.f90
+
+_sinh_r8.o: generated/_sinh_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sinh_r8.o `test -f 'generated/_sinh_r8.f90' || echo '$(srcdir)/'`generated/_sinh_r8.f90
+
+_sinh_r8.obj: generated/_sinh_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sinh_r8.obj `if test -f 'generated/_sinh_r8.f90'; then $(CYGPATH_W) 'generated/_sinh_r8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_sinh_r8.f90'; fi`
+
+_sinh_r8.lo: generated/_sinh_r8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sinh_r8.lo `test -f 'generated/_sinh_r8.f90' || echo '$(srcdir)/'`generated/_sinh_r8.f90
+
+_cosh_r4.o: generated/_cosh_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _cosh_r4.o `test -f 'generated/_cosh_r4.f90' || echo '$(srcdir)/'`generated/_cosh_r4.f90
+
+_cosh_r4.obj: generated/_cosh_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _cosh_r4.obj `if test -f 'generated/_cosh_r4.f90'; then $(CYGPATH_W) 'generated/_cosh_r4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_cosh_r4.f90'; fi`
+
+_cosh_r4.lo: generated/_cosh_r4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _cosh_r4.lo `test -f 'generated/_cosh_r4.f90' || echo '$(srcdir)/'`generated/_cosh_r4.f90
+
+_cosh_r8.o: generated/_cosh_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _cosh_r8.o `test -f 'generated/_cosh_r8.f90' || echo '$(srcdir)/'`generated/_cosh_r8.f90
+
+_cosh_r8.obj: generated/_cosh_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _cosh_r8.obj `if test -f 'generated/_cosh_r8.f90'; then $(CYGPATH_W) 'generated/_cosh_r8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_cosh_r8.f90'; fi`
+
+_cosh_r8.lo: generated/_cosh_r8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _cosh_r8.lo `test -f 'generated/_cosh_r8.f90' || echo '$(srcdir)/'`generated/_cosh_r8.f90
+
+_tanh_r4.o: generated/_tanh_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _tanh_r4.o `test -f 'generated/_tanh_r4.f90' || echo '$(srcdir)/'`generated/_tanh_r4.f90
+
+_tanh_r4.obj: generated/_tanh_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _tanh_r4.obj `if test -f 'generated/_tanh_r4.f90'; then $(CYGPATH_W) 'generated/_tanh_r4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_tanh_r4.f90'; fi`
+
+_tanh_r4.lo: generated/_tanh_r4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _tanh_r4.lo `test -f 'generated/_tanh_r4.f90' || echo '$(srcdir)/'`generated/_tanh_r4.f90
+
+_tanh_r8.o: generated/_tanh_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _tanh_r8.o `test -f 'generated/_tanh_r8.f90' || echo '$(srcdir)/'`generated/_tanh_r8.f90
+
+_tanh_r8.obj: generated/_tanh_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _tanh_r8.obj `if test -f 'generated/_tanh_r8.f90'; then $(CYGPATH_W) 'generated/_tanh_r8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_tanh_r8.f90'; fi`
+
+_tanh_r8.lo: generated/_tanh_r8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _tanh_r8.lo `test -f 'generated/_tanh_r8.f90' || echo '$(srcdir)/'`generated/_tanh_r8.f90
+
+_conjg_c4.o: generated/_conjg_c4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _conjg_c4.o `test -f 'generated/_conjg_c4.f90' || echo '$(srcdir)/'`generated/_conjg_c4.f90
+
+_conjg_c4.obj: generated/_conjg_c4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _conjg_c4.obj `if test -f 'generated/_conjg_c4.f90'; then $(CYGPATH_W) 'generated/_conjg_c4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_conjg_c4.f90'; fi`
+
+_conjg_c4.lo: generated/_conjg_c4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _conjg_c4.lo `test -f 'generated/_conjg_c4.f90' || echo '$(srcdir)/'`generated/_conjg_c4.f90
+
+_conjg_c8.o: generated/_conjg_c8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _conjg_c8.o `test -f 'generated/_conjg_c8.f90' || echo '$(srcdir)/'`generated/_conjg_c8.f90
+
+_conjg_c8.obj: generated/_conjg_c8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _conjg_c8.obj `if test -f 'generated/_conjg_c8.f90'; then $(CYGPATH_W) 'generated/_conjg_c8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_conjg_c8.f90'; fi`
+
+_conjg_c8.lo: generated/_conjg_c8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _conjg_c8.lo `test -f 'generated/_conjg_c8.f90' || echo '$(srcdir)/'`generated/_conjg_c8.f90
+
+_aint_r4.o: generated/_aint_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _aint_r4.o `test -f 'generated/_aint_r4.f90' || echo '$(srcdir)/'`generated/_aint_r4.f90
+
+_aint_r4.obj: generated/_aint_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _aint_r4.obj `if test -f 'generated/_aint_r4.f90'; then $(CYGPATH_W) 'generated/_aint_r4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_aint_r4.f90'; fi`
+
+_aint_r4.lo: generated/_aint_r4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _aint_r4.lo `test -f 'generated/_aint_r4.f90' || echo '$(srcdir)/'`generated/_aint_r4.f90
+
+_aint_r8.o: generated/_aint_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _aint_r8.o `test -f 'generated/_aint_r8.f90' || echo '$(srcdir)/'`generated/_aint_r8.f90
+
+_aint_r8.obj: generated/_aint_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _aint_r8.obj `if test -f 'generated/_aint_r8.f90'; then $(CYGPATH_W) 'generated/_aint_r8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_aint_r8.f90'; fi`
+
+_aint_r8.lo: generated/_aint_r8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _aint_r8.lo `test -f 'generated/_aint_r8.f90' || echo '$(srcdir)/'`generated/_aint_r8.f90
+
+_anint_r4.o: generated/_anint_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _anint_r4.o `test -f 'generated/_anint_r4.f90' || echo '$(srcdir)/'`generated/_anint_r4.f90
+
+_anint_r4.obj: generated/_anint_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _anint_r4.obj `if test -f 'generated/_anint_r4.f90'; then $(CYGPATH_W) 'generated/_anint_r4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_anint_r4.f90'; fi`
+
+_anint_r4.lo: generated/_anint_r4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _anint_r4.lo `test -f 'generated/_anint_r4.f90' || echo '$(srcdir)/'`generated/_anint_r4.f90
+
+_anint_r8.o: generated/_anint_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _anint_r8.o `test -f 'generated/_anint_r8.f90' || echo '$(srcdir)/'`generated/_anint_r8.f90
+
+_anint_r8.obj: generated/_anint_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _anint_r8.obj `if test -f 'generated/_anint_r8.f90'; then $(CYGPATH_W) 'generated/_anint_r8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_anint_r8.f90'; fi`
+
+_anint_r8.lo: generated/_anint_r8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _anint_r8.lo `test -f 'generated/_anint_r8.f90' || echo '$(srcdir)/'`generated/_anint_r8.f90
+
+_sign_i4.o: generated/_sign_i4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sign_i4.o `test -f 'generated/_sign_i4.f90' || echo '$(srcdir)/'`generated/_sign_i4.f90
+
+_sign_i4.obj: generated/_sign_i4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sign_i4.obj `if test -f 'generated/_sign_i4.f90'; then $(CYGPATH_W) 'generated/_sign_i4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_sign_i4.f90'; fi`
+
+_sign_i4.lo: generated/_sign_i4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sign_i4.lo `test -f 'generated/_sign_i4.f90' || echo '$(srcdir)/'`generated/_sign_i4.f90
+
+_sign_i8.o: generated/_sign_i8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sign_i8.o `test -f 'generated/_sign_i8.f90' || echo '$(srcdir)/'`generated/_sign_i8.f90
+
+_sign_i8.obj: generated/_sign_i8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sign_i8.obj `if test -f 'generated/_sign_i8.f90'; then $(CYGPATH_W) 'generated/_sign_i8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_sign_i8.f90'; fi`
+
+_sign_i8.lo: generated/_sign_i8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sign_i8.lo `test -f 'generated/_sign_i8.f90' || echo '$(srcdir)/'`generated/_sign_i8.f90
+
+_sign_r4.o: generated/_sign_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sign_r4.o `test -f 'generated/_sign_r4.f90' || echo '$(srcdir)/'`generated/_sign_r4.f90
+
+_sign_r4.obj: generated/_sign_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sign_r4.obj `if test -f 'generated/_sign_r4.f90'; then $(CYGPATH_W) 'generated/_sign_r4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_sign_r4.f90'; fi`
+
+_sign_r4.lo: generated/_sign_r4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sign_r4.lo `test -f 'generated/_sign_r4.f90' || echo '$(srcdir)/'`generated/_sign_r4.f90
+
+_sign_r8.o: generated/_sign_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sign_r8.o `test -f 'generated/_sign_r8.f90' || echo '$(srcdir)/'`generated/_sign_r8.f90
+
+_sign_r8.obj: generated/_sign_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sign_r8.obj `if test -f 'generated/_sign_r8.f90'; then $(CYGPATH_W) 'generated/_sign_r8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_sign_r8.f90'; fi`
+
+_sign_r8.lo: generated/_sign_r8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _sign_r8.lo `test -f 'generated/_sign_r8.f90' || echo '$(srcdir)/'`generated/_sign_r8.f90
+
+_dim_i4.o: generated/_dim_i4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _dim_i4.o `test -f 'generated/_dim_i4.f90' || echo '$(srcdir)/'`generated/_dim_i4.f90
+
+_dim_i4.obj: generated/_dim_i4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _dim_i4.obj `if test -f 'generated/_dim_i4.f90'; then $(CYGPATH_W) 'generated/_dim_i4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_dim_i4.f90'; fi`
+
+_dim_i4.lo: generated/_dim_i4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _dim_i4.lo `test -f 'generated/_dim_i4.f90' || echo '$(srcdir)/'`generated/_dim_i4.f90
+
+_dim_i8.o: generated/_dim_i8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _dim_i8.o `test -f 'generated/_dim_i8.f90' || echo '$(srcdir)/'`generated/_dim_i8.f90
+
+_dim_i8.obj: generated/_dim_i8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _dim_i8.obj `if test -f 'generated/_dim_i8.f90'; then $(CYGPATH_W) 'generated/_dim_i8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_dim_i8.f90'; fi`
+
+_dim_i8.lo: generated/_dim_i8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _dim_i8.lo `test -f 'generated/_dim_i8.f90' || echo '$(srcdir)/'`generated/_dim_i8.f90
+
+_dim_r4.o: generated/_dim_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _dim_r4.o `test -f 'generated/_dim_r4.f90' || echo '$(srcdir)/'`generated/_dim_r4.f90
+
+_dim_r4.obj: generated/_dim_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _dim_r4.obj `if test -f 'generated/_dim_r4.f90'; then $(CYGPATH_W) 'generated/_dim_r4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_dim_r4.f90'; fi`
+
+_dim_r4.lo: generated/_dim_r4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _dim_r4.lo `test -f 'generated/_dim_r4.f90' || echo '$(srcdir)/'`generated/_dim_r4.f90
+
+_dim_r8.o: generated/_dim_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _dim_r8.o `test -f 'generated/_dim_r8.f90' || echo '$(srcdir)/'`generated/_dim_r8.f90
+
+_dim_r8.obj: generated/_dim_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _dim_r8.obj `if test -f 'generated/_dim_r8.f90'; then $(CYGPATH_W) 'generated/_dim_r8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_dim_r8.f90'; fi`
+
+_dim_r8.lo: generated/_dim_r8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _dim_r8.lo `test -f 'generated/_dim_r8.f90' || echo '$(srcdir)/'`generated/_dim_r8.f90
+
+_atan2_r4.o: generated/_atan2_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _atan2_r4.o `test -f 'generated/_atan2_r4.f90' || echo '$(srcdir)/'`generated/_atan2_r4.f90
+
+_atan2_r4.obj: generated/_atan2_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _atan2_r4.obj `if test -f 'generated/_atan2_r4.f90'; then $(CYGPATH_W) 'generated/_atan2_r4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_atan2_r4.f90'; fi`
+
+_atan2_r4.lo: generated/_atan2_r4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _atan2_r4.lo `test -f 'generated/_atan2_r4.f90' || echo '$(srcdir)/'`generated/_atan2_r4.f90
+
+_atan2_r8.o: generated/_atan2_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _atan2_r8.o `test -f 'generated/_atan2_r8.f90' || echo '$(srcdir)/'`generated/_atan2_r8.f90
+
+_atan2_r8.obj: generated/_atan2_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _atan2_r8.obj `if test -f 'generated/_atan2_r8.f90'; then $(CYGPATH_W) 'generated/_atan2_r8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_atan2_r8.f90'; fi`
+
+_atan2_r8.lo: generated/_atan2_r8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _atan2_r8.lo `test -f 'generated/_atan2_r8.f90' || echo '$(srcdir)/'`generated/_atan2_r8.f90
+
+_mod_i4.o: generated/_mod_i4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _mod_i4.o `test -f 'generated/_mod_i4.f90' || echo '$(srcdir)/'`generated/_mod_i4.f90
+
+_mod_i4.obj: generated/_mod_i4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _mod_i4.obj `if test -f 'generated/_mod_i4.f90'; then $(CYGPATH_W) 'generated/_mod_i4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_mod_i4.f90'; fi`
+
+_mod_i4.lo: generated/_mod_i4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _mod_i4.lo `test -f 'generated/_mod_i4.f90' || echo '$(srcdir)/'`generated/_mod_i4.f90
+
+_mod_i8.o: generated/_mod_i8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _mod_i8.o `test -f 'generated/_mod_i8.f90' || echo '$(srcdir)/'`generated/_mod_i8.f90
+
+_mod_i8.obj: generated/_mod_i8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _mod_i8.obj `if test -f 'generated/_mod_i8.f90'; then $(CYGPATH_W) 'generated/_mod_i8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_mod_i8.f90'; fi`
+
+_mod_i8.lo: generated/_mod_i8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _mod_i8.lo `test -f 'generated/_mod_i8.f90' || echo '$(srcdir)/'`generated/_mod_i8.f90
+
+_mod_r4.o: generated/_mod_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _mod_r4.o `test -f 'generated/_mod_r4.f90' || echo '$(srcdir)/'`generated/_mod_r4.f90
+
+_mod_r4.obj: generated/_mod_r4.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _mod_r4.obj `if test -f 'generated/_mod_r4.f90'; then $(CYGPATH_W) 'generated/_mod_r4.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_mod_r4.f90'; fi`
+
+_mod_r4.lo: generated/_mod_r4.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _mod_r4.lo `test -f 'generated/_mod_r4.f90' || echo '$(srcdir)/'`generated/_mod_r4.f90
+
+_mod_r8.o: generated/_mod_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _mod_r8.o `test -f 'generated/_mod_r8.f90' || echo '$(srcdir)/'`generated/_mod_r8.f90
+
+_mod_r8.obj: generated/_mod_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _mod_r8.obj `if test -f 'generated/_mod_r8.f90'; then $(CYGPATH_W) 'generated/_mod_r8.f90'; else $(CYGPATH_W) '$(srcdir)/generated/_mod_r8.f90'; fi`
+
+_mod_r8.lo: generated/_mod_r8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o _mod_r8.lo `test -f 'generated/_mod_r8.f90' || echo '$(srcdir)/'`generated/_mod_r8.f90
+
+dprod_r8.o: intrinsics/dprod_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o dprod_r8.o `test -f 'intrinsics/dprod_r8.f90' || echo '$(srcdir)/'`intrinsics/dprod_r8.f90
+
+dprod_r8.obj: intrinsics/dprod_r8.f90
+ $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o dprod_r8.obj `if test -f 'intrinsics/dprod_r8.f90'; then $(CYGPATH_W) 'intrinsics/dprod_r8.f90'; else $(CYGPATH_W) '$(srcdir)/intrinsics/dprod_r8.f90'; fi`
+
+dprod_r8.lo: intrinsics/dprod_r8.f90
+ $(LIBTOOL) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS) -c -o dprod_r8.lo `test -f 'intrinsics/dprod_r8.f90' || echo '$(srcdir)/'`intrinsics/dprod_r8.f90
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$tags$$unique" \
+ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ mkdir $(distdir)
+ $(mkdir_p) $(distdir)/.. $(distdir)/m4
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+ -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r $(distdir)
+dist-gzip: distdir
+ $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+dist-bzip2: distdir
+ $(AMTAR) chof - $(distdir) | bzip2 -9 -c >$(distdir).tar.bz2
+ $(am__remove_distdir)
+
+dist-tarZ: distdir
+ $(AMTAR) chof - $(distdir) | compress -c >$(distdir).tar.Z
+ $(am__remove_distdir)
+
+dist-shar: distdir
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__remove_distdir)
+
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__remove_distdir)
+
+dist dist-all: distdir
+ $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf - ;;\
+ *.tar.bz2*) \
+ bunzip2 -c $(distdir).tar.bz2 | $(AMTAR) xf - ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(AMTAR) xf - ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir); chmod a+w $(distdir)
+ mkdir $(distdir)/_build
+ mkdir $(distdir)/_inst
+ chmod a-w $(distdir)
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && cd $(distdir)/_build \
+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && $(mkdir_p) "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck
+ $(am__remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'
+distuninstallcheck:
+ @cd $(distuninstallcheck_dir) \
+ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(LTLIBRARIES) config.h
+installdirs:
+ $(mkdir_p) $(DESTDIR)$(libdir)
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-hdr distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-libLTLIBRARIES
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES
+
+.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \
+ clean-generic clean-libLTLIBRARIES clean-libtool ctags dist \
+ dist-all dist-bzip2 dist-gzip dist-shar dist-tarZ dist-zip \
+ distcheck distclean distclean-compile distclean-generic \
+ distclean-hdr distclean-libtool distclean-tags distcleancheck \
+ distdir distuninstallcheck dvi dvi-am html html-am info \
+ info-am install install-am install-data install-data-am \
+ install-exec install-exec-am install-info install-info-am \
+ install-libLTLIBRARIES install-man install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-info-am \
+ uninstall-libLTLIBRARIES
+
+
+@MAINTAINER_MODE_TRUE@$(i_all_c): m4/all.m4 $(I_M4_DEPS1)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 all.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_any_c): m4/any.m4 $(I_M4_DEPS1)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 any.m4> $@
+
+@MAINTAINER_MODE_TRUE@$(i_count_c): m4/count.m4 $(I_M4_DEPS1)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 count.m4> $@
+
+@MAINTAINER_MODE_TRUE@$(i_maxloc0_c): m4/maxloc0.m4 $(I_M4_DEPS0)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 maxloc0.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_maxloc1_c): m4/maxloc1.m4 $(I_M4_DEPS1)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 maxloc1.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_maxval_c): m4/maxval.m4 $(I_M4_DEPS1)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 maxval.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_minloc0_c): m4/minloc0.m4 $(I_M4_DEPS0)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 minloc0.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_minloc1_c): m4/minloc1.m4 $(I_M4_DEPS1)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 minloc1.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_minval_c): m4/minval.m4 $(I_M4_DEPS1)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 minval.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_product_c): m4/product.m4 $(I_M4_DEPS1)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 product.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_sum_c): m4/sum.m4 $(I_M4_DEPS1)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 sum.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_dotprod_c): m4/dotprod.m4 $(I_M4_DEPS)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 dotprod.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_dotprodl_c): m4/dotprodl.m4 $(I_M4_DEPS)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 dotprodl.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_dotprodc_c): m4/dotprodc.m4 $(I_M4_DEPS)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 dotprodc.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_matmul_c): m4/matmul.m4 $(I_M4_DEPS)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 matmul.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_matmull_c): m4/matmull.m4 $(I_M4_DEPS)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 matmull.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_transpose_c): m4/transpose.m4 $(I_M4_DEPS)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 transpose.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_shape_c): m4/shape.m4 $(I_M4_DEPS)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 shape.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_reshape_c): m4/reshape.m4 $(I_M4_DEPS)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 reshape.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_eoshift1_c): m4/eoshift1.m4 $(I_M4_DEPS)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 eoshift1.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_eoshift3_c): m4/eoshift3.m4 $(I_M4_DEPS)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 eoshift3.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_cshift1_c): m4/cshift1.m4 $(I_M4_DEPS)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 cshift1.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(in_pack_c): m4/in_pack.m4 $(I_M4_DEPS)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 in_pack.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(in_unpack_c): m4/in_unpack.m4 $(I_M4_DEPS)
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 in_unpack.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_exponent_c): m4/exponent.m4 m4/mtype.m4
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 exponent.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_fraction_c): m4/fraction.m4 m4/mtype.m4
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 fraction.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_nearest_c): m4/nearest.m4 m4/mtype.m4
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 nearest.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(i_set_exponent_c): m4/set_exponent.m4 m4/mtype.m4
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 set_exponent.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(gfor_math_trig_c): m4/ctrig.m4 m4/mtype.m4
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 ctrig.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(gfor_math_exp_c): m4/cexp.m4 m4/mtype.m4
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 cexp.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(gfor_math_hyp_c): m4/chyp.m4 m4/mtype.m4
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 chyp.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(gfor_built_specific_src): m4/specific.m4 m4/head.m4
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 specific.m4 > $@
+
+@MAINTAINER_MODE_TRUE@$(gfor_built_specific2_src): m4/specific2.m4 m4/head.m4
+@MAINTAINER_MODE_TRUE@ m4 -Dfile=$@ -I$(srcdir)/m4 specific2.m4 > $@
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libgfortran/NEWS b/libgfortran/NEWS
new file mode 100644
index 00000000000..96c59e5d663
--- /dev/null
+++ b/libgfortran/NEWS
@@ -0,0 +1 @@
+No Gnus is good Gnus
diff --git a/libgfortran/README b/libgfortran/README
new file mode 100644
index 00000000000..1a5de1d0436
--- /dev/null
+++ b/libgfortran/README
@@ -0,0 +1,14 @@
+This is the GNU Fortran 95 Runtime library (libgfortran).
+It is intended to be compiled as part of GCC.
+
+Programs must be linked with "-lgfortran -lm". The 'gfortran' driver does this
+automatically.
+
+You'll need to apply gcc_config.patch to your top level GCC source directory.
+This tells the the GCC configure system about libgfor. This patch can confuse
+patch as it contains a filename with a '-' in it. use "patch -p1" to avoid this
+problem.
+
+For more information about GNU Fortran 95, see http://gcc-g95.sourceforge.net
+
+Paul Brook <paul@nowt.org>
diff --git a/libgfortran/acinclude.m4 b/libgfortran/acinclude.m4
new file mode 100644
index 00000000000..8e6b1bc79b4
--- /dev/null
+++ b/libgfortran/acinclude.m4
@@ -0,0 +1,85 @@
+dnl Check:
+dnl * If we have gettimeofday;
+dnl * If we have struct timezone for use in calling it;
+dnl * If calling it with a timezone pointer actually works -- this is deemed
+dnl obsolete or undefined on some systems which say you should use a null
+dnl pointer -- and undefine HAVE_TIMEZONE if so;
+dnl * Whether it only takes one arg.
+AC_DEFUN([LIBGFOR_GETTIMEOFDAY], [
+ AC_CHECK_FUNCS(gettimeofday)
+ if test "$ac_cv_func_gettimeofday" = yes; then
+ AC_CACHE_CHECK([for struct timezone], gfor_cv_struct_timezone,
+ [AC_TRY_COMPILE([#include <sys/time.h>],
+ [struct timezone tz;],
+ gfor_cv_struct_timezone=yes, gfor_cv_struct_timezone=no)])
+ if test $gfor_cv_struct_timezone = yes; then
+ dnl It may be that we can't call gettimeofday with a non-null pointer.
+ dnl In that case we'll lie about struct timezone.
+ AC_TRY_RUN([
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+main ()
+{
+ struct timeval time;
+ struct timezone dummy;
+ if (gettimeofday (&time, &dummy))
+ exit (1);
+ else
+ exit (0);
+}],
+ [gfor_have_struct_timezone=yes], [gfor_have_struct_timezone=no],
+ [gfor_have_struct_timezone=yes])
+ if test $gfor_have_struct_timezone = yes; then
+ AC_DEFINE(HAVE_TIMEZONE, 1, [Do we have struct timezone])
+ fi
+ fi
+ AC_REQUIRE([AC_HEADER_TIME])
+ AC_CACHE_CHECK(whether gettimeofday can accept two arguments,
+ emacs_cv_gettimeofday_two_arguments,
+ AC_TRY_LINK([
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+ ],
+ [
+ struct timeval time;
+#ifdef HAVE_TIMEZONE
+ struct timezone dummy;
+#define DUMMY &dummy
+#else
+#define DUMMY NULL
+#endif
+ gettimeofday (&time, DUMMY);],
+ emacs_cv_gettimeofday_two_arguments=yes,
+ emacs_cv_gettimeofday_two_arguments=no))
+ if test $emacs_cv_gettimeofday_two_arguments = no; then
+ AC_DEFINE(GETTIMEOFDAY_ONE_ARGUMENT, 1,
+ [Does gettimeofday take a single argument])
+ fi
+ fi])
+
+sinclude(../libtool.m4)
+dnl The lines below arrange for aclocal not to bring an installed
+dnl libtool.m4 into aclocal.m4, while still arranging for automake to
+dnl add a definition of LIBTOOL to Makefile.in.
+ifelse(,,,[AC_SUBST(LIBTOOL)
+AC_DEFUN([AM_PROG_LIBTOOL])
+AC_DEFUN([AC_LIBTOOL_DLOPEN])
+AC_DEFUN([AC_PROG_LD])
+])
+
diff --git a/libgfortran/aclocal.m4 b/libgfortran/aclocal.m4
new file mode 100644
index 00000000000..45216f1a196
--- /dev/null
+++ b/libgfortran/aclocal.m4
@@ -0,0 +1,958 @@
+# generated automatically by aclocal 1.8.2 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+# Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# -*- Autoconf -*-
+# Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+# Generated from amversion.in; do not edit by hand.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.8"])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION so it can be traced.
+# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+ [AM_AUTOMAKE_VERSION([1.8.2])])
+
+# AM_AUX_DIR_EXPAND
+
+# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 6
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])
+AC_SUBST([$1_FALSE])
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.])
+fi])])
+
+# serial 6 -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+# Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
+ [$1], CXX, [depcc="$CXX" am_compiler_list=],
+ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ : > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored.
+ if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+#serial 2
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[for mf in $CONFIG_FILES; do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # So let's grep whole file.
+ if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue
+ # Extract the definition of DEP_FILES from the Makefile without
+ # running `make'.
+ DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n -e '/^U = / s///p' < "$mf"`
+ test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+ # We invoke sed twice because it is the simplest approach to
+ # changing $(DEPDIR) to its actual value in the expansion.
+ for file in `sed -n -e '
+ /^DEP_FILES = .*\\\\$/ {
+ s/^DEP_FILES = //
+ :loop
+ s/\\\\$//
+ p
+ n
+ /\\\\$/ b loop
+ p
+ }
+ /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+done
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 7
+
+# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS.
+AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# This macro actually does too much some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 11
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.58])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+ test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_MISSING_PROG(AMTAR, tar)
+AM_PROG_INSTALL_SH
+AM_PROG_INSTALL_STRIP
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_CC],
+ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_CXX],
+ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+])
+])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $1 | $1:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+
+# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+AC_SUBST(install_sh)])
+
+# -*- Autoconf -*-
+# Copyright (C) 2003 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 1
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure.
+# From Jim Meyering
+
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004
+# Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 3
+
+AC_DEFUN([AM_MAINTAINER_MODE],
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode is disabled by default
+ AC_ARG_ENABLE(maintainer-mode,
+[ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ USE_MAINTAINER_MODE=$enableval,
+ USE_MAINTAINER_MODE=no)
+ AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+ AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes])
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST(MAINT)dnl
+]
+)
+
+AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 2
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+ am__include=include
+ am__quote=
+ _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ fi
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# -*- Autoconf -*-
+
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 3
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
+
+# Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
+# created by `make install' are always world readable, even if the
+# installer happens to have an overly restrictive umask (e.g. 077).
+# This was a mistake. There are at least two reasons why we must not
+# use `-m 0755':
+# - it causes special bits like SGID to be ignored,
+# - it may be too restrictive (some setups expect 775 directories).
+#
+# Do not use -m 0755 and let people choose whatever they expect by
+# setting umask.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[if mkdir -p -- . 2>/dev/null; then
+ # Keeping the `.' argument allows $(mkdir_p) to be used without
+ # argument. Indeed, we sometimes output rules like
+ # $(mkdir_p) $(somedir)
+ # where $(somedir) is conditionally defined.
+ # (`test -n '$(somedir)' && $(mkdir_p) $(somedir)' is a more
+ # expensive solution, as it forces Make to start a sub-shell.)
+ mkdir_p='mkdir -p -- .'
+else
+ # On NextStep and OpenStep, the `mkdir' command does not
+ # recognize any option. It will interpret all options as
+ # directories to create, and then abort because `.' already
+ # exists.
+ for d in ./-p ./--;
+ do
+ test -d $d && rmdir $d
+ done
+ # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
+ if test -f "$ac_aux_dir/mkinstalldirs"; then
+ mkdir_p='$(mkinstalldirs)'
+ else
+ mkdir_p='$(install_sh) -d'
+ fi
+fi
+AC_SUBST([mkdir_p])])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 2
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 3
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# AM_PROG_INSTALL_STRIP
+
+# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+
+# This program 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 2, or (at your option)
+# any later version.
+
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+m4_include([acinclude.m4])
diff --git a/libgfortran/config.h.in b/libgfortran/config.h.in
new file mode 100644
index 00000000000..1c686978abf
--- /dev/null
+++ b/libgfortran/config.h.in
@@ -0,0 +1,106 @@
+/* config.h.in. Generated from configure.in by autoheader. */
+
+/* Does gettimeofday take a single argument */
+#undef GETTIMEOFDAY_ONE_ARGUMENT
+
+/* complex.h exists */
+#undef HAVE_COMPLEX_H
+
+/* Define to 1 if you have the `getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define to 1 if you have the `getrusage' function. */
+#undef HAVE_GETRUSAGE
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <math.h> header file. */
+#undef HAVE_MATH_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#undef HAVE_STDDEF_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#undef HAVE_STDIO_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/params.h> header file. */
+#undef HAVE_SYS_PARAMS_H
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/times.h> header file. */
+#undef HAVE_SYS_TIMES_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the `times' function. */
+#undef HAVE_TIMES
+
+/* Do we have struct timezone */
+#undef HAVE_TIMEZONE
+
+/* Define to 1 if you have the <time.h> header file. */
+#undef HAVE_TIME_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to `long' if <sys/types.h> does not define. */
+#undef off_t
diff --git a/libgfortran/configure b/libgfortran/configure
new file mode 100755
index 00000000000..099ab80a610
--- /dev/null
+++ b/libgfortran/configure
@@ -0,0 +1,8133 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59 for GNU Fortran Runtime Library 0.2.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete. It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME='GNU Fortran Runtime Library'
+PACKAGE_TARNAME='libgfortran'
+PACKAGE_VERSION='0.2'
+PACKAGE_STRING='GNU Fortran Runtime Library 0.2'
+PACKAGE_BUGREPORT=''
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT enable_shared enable_static CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE F77 FFLAGS ac_ct_F77 CPP EGREP MATH_OBJ AR RANLIB ac_ct_RANLIB build build_cpu build_vendor build_os host host_cpu host_vendor host_os LN_S LIBTOOL LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_option in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ eval "enable_$ac_feature=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_$ac_feature='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_$ac_package='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package | sed 's/-/_/g'`
+ eval "with_$ac_package=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+ eval "$ac_envvar='$ac_optarg'"
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+ localstatedir libdir includedir oldincludedir infodir mandir
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$0" : 'X\(//\)[^/]' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+ { (exit 1); exit 1; }; }
+ else
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+ fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+ { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+ { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_F77_set=${F77+set}
+ac_env_F77_value=$F77
+ac_cv_env_F77_set=${F77+set}
+ac_cv_env_F77_value=$F77
+ac_env_FFLAGS_set=${FFLAGS+set}
+ac_env_FFLAGS_value=$FFLAGS
+ac_cv_env_FFLAGS_set=${FFLAGS+set}
+ac_cv_env_FFLAGS_value=$FFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures GNU Fortran Runtime Library 0.2 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+ cat <<_ACEOF
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --infodir=DIR info documentation [PREFIX/info]
+ --mandir=DIR man documentation [PREFIX/man]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of GNU Fortran Runtime Library 0.2:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer
+ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors
+ --enable-cmath Include complex math functions
+ --enable-shared=PKGS build shared libraries default=yes
+ --enable-static=PKGS build static libraries default=yes
+ --enable-fast-install=PKGS optimize for fast installation default=yes
+ --disable-libtool-lock avoid locking (might break parallel builds)
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-gnu-ld assume the C compiler uses GNU ld default=no
+ --with-pic try to use only PIC/non-PIC objects default=use both
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
+ headers in a nonstandard directory <include dir>
+ F77 Fortran 77 compiler command
+ FFLAGS Fortran 77 compiler flags
+ CPP C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ ac_popdir=`pwd`
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d $ac_dir || continue
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+ cd $ac_dir
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f $ac_srcdir/configure.gnu; then
+ echo
+ $SHELL $ac_srcdir/configure.gnu --help=recursive
+ elif test -f $ac_srcdir/configure; then
+ echo
+ $SHELL $ac_srcdir/configure --help=recursive
+ elif test -f $ac_srcdir/configure.ac ||
+ test -f $ac_srcdir/configure.in; then
+ echo
+ $ac_configure --help
+ else
+ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi
+ cd "$ac_popdir"
+ done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+ cat <<\_ACEOF
+GNU Fortran Runtime Library configure 0.2
+generated by GNU Autoconf 2.59
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by GNU Fortran Runtime Library $as_me 0.2, which was
+generated by GNU Autoconf 2.59. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo = `(hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+ # Get rid of the leading space.
+ ac_sep=" "
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+{
+ (set) 2>&1 |
+ case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ sed -n \
+ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+ ;;
+ *)
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+}
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ sed "/^$/d" confdefs.h | sort
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ echo "$as_me: caught signal $ac_signal"
+ echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core &&
+ rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+ ' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . $cache_file;;
+ *) . ./$cache_file;;
+ esac
+ fi
+else
+ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+ sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+ eval ac_new_val="\$ac_env_${ac_var}_value"
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
+echo "$as_me: former value: $ac_old_val" >&2;}
+ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
+echo "$as_me: current value: $ac_new_val" >&2;}
+ ac_cache_corrupted=:
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+am__api_version="1.8"
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f $ac_dir/shtool; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+ ./ | .// | /cC/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+done
+
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL=$ac_install_sh
+ fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo "$as_me:$LINENO: checking whether build environment is sane" >&5
+echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" >&5
+echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ { { echo "$as_me:$LINENO: error: newly created file is older than distributed files!
+Check your system clock" >&5
+echo "$as_me: error: newly created file is older than distributed files!
+Check your system clock" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,$program_prefix,;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$,$program_suffix,;$program_transform_name"
+# Double any \ or $. echo might interpret backslashes.
+# By default was `s,x,x', remove it if useless.
+cat <<\_ACEOF >conftest.sed
+s/[\\$]/&&/g;s/;s,x,x,$//
+_ACEOF
+program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
+rm conftest.sed
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5
+echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if mkdir -p -- . 2>/dev/null; then
+ # Keeping the `.' argument allows $(mkdir_p) to be used without
+ # argument. Indeed, we sometimes output rules like
+ # $(mkdir_p) $(somedir)
+ # where $(somedir) is conditionally defined.
+ # (`test -n '$(somedir)' && $(mkdir_p) $(somedir)' is a more
+ # expensive solution, as it forces Make to start a sub-shell.)
+ mkdir_p='mkdir -p -- .'
+else
+ # On NextStep and OpenStep, the `mkdir' command does not
+ # recognize any option. It will interpret all options as
+ # directories to create, and then abort because `.' already
+ # exists.
+ for d in ./-p ./--;
+ do
+ test -d $d && rmdir $d
+ done
+ # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
+ if test -f "$ac_aux_dir/mkinstalldirs"; then
+ mkdir_p='$(mkinstalldirs)'
+ else
+ mkdir_p='$(install_sh) -d'
+ fi
+fi
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AWK+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$AWK" && break
+done
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.make <<\_ACEOF
+all:
+ @echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+ SET_MAKE=
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+ test -f $srcdir/config.status; then
+ { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
+echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='libgfortran'
+ VERSION='0.2'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_STRIP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ STRIP=$ac_ct_STRIP
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+
+
+
+ ac_config_headers="$ac_config_headers config.h"
+
+echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6
+ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+ enableval="$enable_maintainer_mode"
+ USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi;
+ echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5
+echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6
+
+
+if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+
+
+
+
+# check for compiler
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$ac_ct_CC" && break
+done
+
+ CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+ "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+ (eval $ac_compiler --version </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+ (eval $ac_compiler -v </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+ (eval $ac_compiler -V </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+ (eval $ac_link_default) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Find the output, starting from the most likely. This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+ ;;
+ conftest.$ac_ext )
+ # This is the source file.
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ # FIXME: I believe we export ac_cv_exeext for Libtool,
+ # but it would be cool to find out if it's true. Does anybody
+ # maintain Libtool? --akim.
+ export ac_cv_exeext
+ break;;
+ * )
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ export ac_cv_exeext
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_compiler_gnu=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std1 is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std1. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX 10.20 and later -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+ x|xno)
+ echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+ *)
+ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+ CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C. Since we use `exit',
+# in C++ we need to declare it. In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+ choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ for ac_declaration in \
+ '' \
+ 'extern "C" void std::exit (int) throw (); using std::exit;' \
+ 'extern "C" void std::exit (int); using std::exit;' \
+ 'extern "C" void exit (int) throw ();' \
+ 'extern "C" void exit (int);' \
+ 'void exit (int);'
+do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+ echo '#ifdef __cplusplus' >>confdefs.h
+ echo $ac_declaration >>confdefs.h
+ echo '#endif' >>confdefs.h
+fi
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+ ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
+echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+ am__include=include
+ am__quote=
+ _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ fi
+fi
+
+
+echo "$as_me:$LINENO: result: $_am_result" >&5
+echo "${ECHO_T}$_am_result" >&6
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then
+ enableval="$enable_dependency_tracking"
+
+fi;
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+
+
+if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+
+
+depcc="$CC" am_compiler_list=
+
+echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ : > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored.
+ if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
+echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+
+
+if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+if test "x$GCC" = "xyes"; then
+ CFLAGS="$CFLAGS -Wall"
+fi
+
+# We need gfortran to compile parts of the library
+# We can't use AC_PROG_F77 because it expects a fully working gfortran.
+#AC_PROG_F77(gfortran)
+F77="$GFORTRAN"
+ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in gfortran
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_F77+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$F77"; then
+ ac_cv_prog_F77="$F77" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_F77="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+F77=$ac_cv_prog_F77
+if test -n "$F77"; then
+ echo "$as_me:$LINENO: result: $F77" >&5
+echo "${ECHO_T}$F77" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$F77" && break
+ done
+fi
+if test -z "$F77"; then
+ ac_ct_F77=$F77
+ for ac_prog in gfortran
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_F77+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_F77"; then
+ ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_F77="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_F77=$ac_cv_prog_ac_ct_F77
+if test -n "$ac_ct_F77"; then
+ echo "$as_me:$LINENO: result: $ac_ct_F77" >&5
+echo "${ECHO_T}$ac_ct_F77" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$ac_ct_F77" && break
+done
+
+ F77=$ac_ct_F77
+fi
+
+
+# Provide some information about the compiler.
+echo "$as_me:2983:" \
+ "checking for Fortran 77 compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+ (eval $ac_compiler --version </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+ (eval $ac_compiler -v </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+ (eval $ac_compiler -V </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+rm -f a.out
+
+# If we don't use `.F' as extension, the preprocessor is not run on the
+# input file. (Note that this only needs to work for GNU compilers.)
+ac_save_ext=$ac_ext
+ac_ext=F
+echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6
+if test "${ac_cv_f77_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+ program main
+#ifndef __GNUC__
+ choke me
+#endif
+
+ end
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_compiler_gnu=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_f77_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6
+ac_ext=$ac_save_ext
+ac_test_FFLAGS=${FFLAGS+set}
+ac_save_FFLAGS=$FFLAGS
+FFLAGS=
+echo "$as_me:$LINENO: checking whether $F77 accepts -g" >&5
+echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_f77_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ FFLAGS=-g
+cat >conftest.$ac_ext <<_ACEOF
+ program main
+
+ end
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_f77_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_f77_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5
+echo "${ECHO_T}$ac_cv_prog_f77_g" >&6
+if test "$ac_test_FFLAGS" = set; then
+ FFLAGS=$ac_save_FFLAGS
+elif test $ac_cv_prog_f77_g = yes; then
+ if test "x$ac_cv_f77_compiler_gnu" = xyes; then
+ FFLAGS="-g -O2"
+ else
+ FFLAGS="-g"
+ fi
+else
+ if test "x$ac_cv_f77_compiler_gnu" = xyes; then
+ FFLAGS="-O2"
+ else
+ FFLAGS=
+ fi
+fi
+
+G77=`test $ac_compiler_gnu = yes && echo yes`
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+FFLAGS="$FFLAGS -Wall -fno-repack-arrays -fno-underscoring"
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+ then ac_cv_prog_egrep='grep -E'
+ else ac_cv_prog_egrep='egrep'
+ fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_stdc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ exit(2);
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_Header=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+for ac_header in stdlib.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------------------------ ##
+## Report this to the GNU Fortran Runtime Library lists. ##
+## ------------------------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_func in getpagesize
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+echo "$as_me:$LINENO: checking for working mmap" >&5
+echo $ECHO_N "checking for working mmap... $ECHO_C" >&6
+if test "${ac_cv_func_mmap_fixed_mapped+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_mmap_fixed_mapped=no
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+/* malloc might have been renamed as rpl_malloc. */
+#undef malloc
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+ Here is a matrix of mmap possibilities:
+ mmap private not fixed
+ mmap private fixed at somewhere currently unmapped
+ mmap private fixed at somewhere already mapped
+ mmap shared not fixed
+ mmap shared fixed at somewhere currently unmapped
+ mmap shared fixed at somewhere already mapped
+ For private mappings, we should verify that changes cannot be read()
+ back from the file, nor mmap's back from the file at a different
+ address. (There have been systems where private was not correctly
+ implemented like the infamous i386 svr4.0, and systems where the
+ VM page cache was not coherent with the file system buffer cache
+ like early versions of FreeBSD and possibly contemporary NetBSD.)
+ For shared mappings, we should conversely verify that changes get
+ propagated back to all the places they're supposed to be.
+
+ Grep wants private fixed already mapped.
+ The main things grep needs to know about mmap are:
+ * does it exist and is it safe to write into the mmap'd area
+ * how to use it (BSD variants) */
+
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#if !STDC_HEADERS && !HAVE_STDLIB_H
+char *malloc ();
+#endif
+
+/* This mess was copied from the GNU getpagesize.h. */
+#if !HAVE_GETPAGESIZE
+/* Assume that all systems that can run configure have sys/param.h. */
+# if !HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# if HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+int
+main ()
+{
+ char *data, *data2, *data3;
+ int i, pagesize;
+ int fd;
+
+ pagesize = getpagesize ();
+
+ /* First, make a file with some known garbage in it. */
+ data = (char *) malloc (pagesize);
+ if (!data)
+ exit (1);
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand ();
+ umask (0);
+ fd = creat ("conftest.mmap", 0600);
+ if (fd < 0)
+ exit (1);
+ if (write (fd, data, pagesize) != pagesize)
+ exit (1);
+ close (fd);
+
+ /* Next, try to mmap the file at a fixed address which already has
+ something else allocated at it. If we can, also make sure that
+ we see the same garbage. */
+ fd = open ("conftest.mmap", O_RDWR);
+ if (fd < 0)
+ exit (1);
+ data2 = (char *) malloc (2 * pagesize);
+ if (!data2)
+ exit (1);
+ data2 += (pagesize - ((long) data2 & (pagesize - 1))) & (pagesize - 1);
+ if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, fd, 0L))
+ exit (1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ exit (1);
+
+ /* Finally, make sure that changes to the mapped area do not
+ percolate back to the file as seen by read(). (This is a bug on
+ some variants of i386 svr4.0.) */
+ for (i = 0; i < pagesize; ++i)
+ *(data2 + i) = *(data2 + i) + 1;
+ data3 = (char *) malloc (pagesize);
+ if (!data3)
+ exit (1);
+ if (read (fd, data3, pagesize) != pagesize)
+ exit (1);
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data3 + i))
+ exit (1);
+ close (fd);
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_mmap_fixed_mapped=yes
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_mmap_fixed_mapped" >&5
+echo "${ECHO_T}$ac_cv_func_mmap_fixed_mapped" >&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_MMAP 1
+_ACEOF
+
+fi
+rm -f conftest.mmap
+
+echo "$as_me:$LINENO: checking for off_t" >&5
+echo $ECHO_N "checking for off_t... $ECHO_C" >&6
+if test "${ac_cv_type_off_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((off_t *) 0)
+ return 0;
+if (sizeof (off_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_off_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_off_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5
+echo "${ECHO_T}$ac_cv_type_off_t" >&6
+if test $ac_cv_type_off_t = yes; then
+ :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define off_t long
+_ACEOF
+
+fi
+
+
+# Check for install
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+ ./ | .// | /cC/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+done
+
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL=$ac_install_sh
+ fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+# check header files
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_stdc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ exit(2);
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+
+
+
+
+
+
+for ac_header in stdlib.h stdio.h string.h stddef.h math.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------------------------ ##
+## Report this to the GNU Fortran Runtime Library lists. ##
+## ------------------------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+
+for ac_header in time.h sys/params.h sys/time.h sys/times.h sys/resource.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------------------------ ##
+## Report this to the GNU Fortran Runtime Library lists. ##
+## ------------------------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+if test "${ac_cv_header_complex_h+set}" = set; then
+ echo "$as_me:$LINENO: checking for complex.h" >&5
+echo $ECHO_N "checking for complex.h... $ECHO_C" >&6
+if test "${ac_cv_header_complex_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_complex_h" >&5
+echo "${ECHO_T}$ac_cv_header_complex_h" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking complex.h usability" >&5
+echo $ECHO_N "checking complex.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <complex.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking complex.h presence" >&5
+echo $ECHO_N "checking complex.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <complex.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: complex.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: complex.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: complex.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: complex.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: complex.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: complex.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: complex.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: complex.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: complex.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: complex.h: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: complex.h: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: complex.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: complex.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: complex.h: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: complex.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: complex.h: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------------------------ ##
+## Report this to the GNU Fortran Runtime Library lists. ##
+## ------------------------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for complex.h" >&5
+echo $ECHO_N "checking for complex.h... $ECHO_C" >&6
+if test "${ac_cv_header_complex_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_header_complex_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_complex_h" >&5
+echo "${ECHO_T}$ac_cv_header_complex_h" >&6
+
+fi
+if test $ac_cv_header_complex_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_COMPLEX_H 1
+_ACEOF
+
+fi
+
+
+# Check for complex math functions
+echo "$as_me:$LINENO: checking for csin in -lm" >&5
+echo $ECHO_N "checking for csin in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_csin+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char csin ();
+int
+main ()
+{
+csin ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_m_csin=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_csin=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_m_csin" >&5
+echo "${ECHO_T}$ac_cv_lib_m_csin" >&6
+if test $ac_cv_lib_m_csin = yes; then
+ need_math="no"
+else
+ need_math="yes"
+fi
+
+
+# Check for complex math functions in -lmx also
+echo "$as_me:$LINENO: checking for csin in -lmx" >&5
+echo $ECHO_N "checking for csin in -lmx... $ECHO_C" >&6
+if test "${ac_cv_lib_mx_csin+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lmx $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char csin ();
+int
+main ()
+{
+csin ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_mx_csin=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_mx_csin=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_mx_csin" >&5
+echo "${ECHO_T}$ac_cv_lib_mx_csin" >&6
+if test $ac_cv_lib_mx_csin = yes; then
+ need_math="no"
+else
+ need_math="yes"
+fi
+
+
+
+
+for ac_func in getrusage times
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# Let the user override this
+# Check whether --enable-cmath or --disable-cmath was given.
+if test "${enable_cmath+set}" = set; then
+ enableval="$enable_cmath"
+ need_math=$enableval
+fi;
+if test "$need_math" = "yes"; then
+ { echo "$as_me:$LINENO: Including complex math functions in libgfor" >&5
+echo "$as_me: Including complex math functions in libgfor" >&6;};
+ extra_math_obj='$(gfor_cmath_obj)'
+fi
+
+MATH_OBJ="$extra_math_obj"
+
+
+echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5
+echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6
+if test "${ac_cv_header_time+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_time=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_time=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5
+echo "${ECHO_T}$ac_cv_header_time" >&6
+if test $ac_cv_header_time = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TIME_WITH_SYS_TIME 1
+_ACEOF
+
+fi
+
+
+
+for ac_func in gettimeofday
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ if test "$ac_cv_func_gettimeofday" = yes; then
+ echo "$as_me:$LINENO: checking for struct timezone" >&5
+echo $ECHO_N "checking for struct timezone... $ECHO_C" >&6
+if test "${gfor_cv_struct_timezone+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/time.h>
+int
+main ()
+{
+struct timezone tz;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ gfor_cv_struct_timezone=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gfor_cv_struct_timezone=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $gfor_cv_struct_timezone" >&5
+echo "${ECHO_T}$gfor_cv_struct_timezone" >&6
+ if test $gfor_cv_struct_timezone = yes; then
+ if test "$cross_compiling" = yes; then
+ gfor_have_struct_timezone=yes
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+main ()
+{
+ struct timeval time;
+ struct timezone dummy;
+ if (gettimeofday (&time, &dummy))
+ exit (1);
+ else
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ gfor_have_struct_timezone=yes
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+gfor_have_struct_timezone=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+ if test $gfor_have_struct_timezone = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_TIMEZONE 1
+_ACEOF
+
+ fi
+ fi
+
+ echo "$as_me:$LINENO: checking whether gettimeofday can accept two arguments" >&5
+echo $ECHO_N "checking whether gettimeofday can accept two arguments... $ECHO_C" >&6
+if test "${emacs_cv_gettimeofday_two_arguments+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+
+int
+main ()
+{
+
+ struct timeval time;
+#ifdef HAVE_TIMEZONE
+ struct timezone dummy;
+#define DUMMY &dummy
+#else
+#define DUMMY NULL
+#endif
+ gettimeofday (&time, DUMMY);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ emacs_cv_gettimeofday_two_arguments=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+emacs_cv_gettimeofday_two_arguments=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $emacs_cv_gettimeofday_two_arguments" >&5
+echo "${ECHO_T}$emacs_cv_gettimeofday_two_arguments" >&6
+ if test $emacs_cv_gettimeofday_two_arguments = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define GETTIMEOFDAY_ONE_ARGUMENT 1
+_ACEOF
+
+ fi
+ fi
+
+test "$AR" || AR=ar
+
+if test "$RANLIB"; then :
+
+else
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ RANLIB=$ac_ct_RANLIB
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+fi
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ p=${PACKAGE-default}
+case $enableval in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_shared=yes
+fi;
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+ enableval="$enable_static"
+ p=${PACKAGE-default}
+case $enableval in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_static=yes
+fi;
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+ enableval="$enable_fast_install"
+ p=${PACKAGE-default}
+case $enableval in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_fast_install=yes
+fi;
+# Make sure we can run config.sub.
+$ac_config_sub sun4 >/dev/null 2>&1 ||
+ { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
+echo "$as_me: error: cannot run $ac_config_sub" >&2;}
+ { (exit 1); exit 1; }; }
+
+echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6
+if test "${ac_cv_build+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_build_alias=$build_alias
+test -z "$ac_cv_build_alias" &&
+ ac_cv_build_alias=`$ac_config_guess`
+test -z "$ac_cv_build_alias" &&
+ { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+ { (exit 1); exit 1; }; }
+ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
+ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6
+build=$ac_cv_build
+build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6
+if test "${ac_cv_host+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_host_alias=$host_alias
+test -z "$ac_cv_host_alias" &&
+ ac_cv_host_alias=$ac_cv_build_alias
+ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
+ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6
+host=$ac_cv_host
+host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval="$with_gnu_ld"
+ test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi;
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo "$as_me:$LINENO: checking for ld used by GCC" >&5
+echo $ECHO_N "checking for ld used by GCC... $ECHO_C" >&6
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ echo "$as_me:$LINENO: checking for GNU ld" >&5
+echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6
+else
+ echo "$as_me:$LINENO: checking for non-GNU ld" >&5
+echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6
+fi
+if test "${lt_cv_path_LD+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ echo "$as_me:$LINENO: result: $LD" >&5
+echo "${ECHO_T}$LD" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
+echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
+ { (exit 1); exit 1; }; }
+echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
+echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
+if test "${lt_cv_prog_gnu_ld+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ lt_cv_prog_gnu_ld=yes
+else
+ lt_cv_prog_gnu_ld=no
+fi
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
+echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5
+echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6
+if test "${lt_cv_ld_reload_flag+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5
+echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6
+reload_flag=$lt_cv_ld_reload_flag
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5
+echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6
+if test "${lt_cv_path_NM+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/${ac_tool_prefix}nm
+ if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ else
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi
+fi
+
+NM="$lt_cv_path_NM"
+echo "$as_me:$LINENO: result: $NM" >&5
+echo "${ECHO_T}$NM" >&6
+
+echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+ echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6
+fi
+
+echo "$as_me:$LINENO: checking how to recognise dependant libraries" >&5
+echo $ECHO_N "checking how to recognise dependant libraries... $ECHO_C" >&6
+if test "${lt_cv_deplibs_check_method+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [regex]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi4*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin* | mingw* |pw32*)
+ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ # this will be overwritten by pass_all, but leave it in just in case
+ lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ case "$host_os" in
+ rhapsody* | darwin1.012)
+ lt_cv_file_magic_test_file='/System/Library/Frameworks/System.framework/System'
+ ;;
+ *) # Darwin 1.3 on
+ lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib'
+ ;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* )
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20*|hpux11*)
+ case $host_cpu in
+ hppa*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ esac
+ ;;
+
+irix5* | irix6*)
+ case $host_os in
+ irix5*)
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+ ;;
+ *)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"
+ ;;
+ esac
+ lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+ case $host_cpu in
+ alpha* | mips* | hppa* | i*86 | powerpc* | sparc* | ia64* )
+ lt_cv_deplibs_check_method=pass_all ;;
+ *)
+ # glibc up to 2.1.1 does not perform some relocations on ARM
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;;
+ esac
+ lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$'
+ fi
+ ;;
+
+newsos6)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+osf3* | osf4* | osf5*)
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method='file_magic COFF format alpha shared library'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sco3.2v5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+
+sysv5uw[78]* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ case $host_vendor in
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ esac
+ ;;
+esac
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5
+echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+
+
+
+
+# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
+
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5
+echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $MAGIC_CMD in
+ /*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+ ;;
+ *)
+ ac_save_MAGIC_CMD="$MAGIC_CMD"
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="/usr/bin:$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/${ac_tool_prefix}file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ egrep "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ MAGIC_CMD="$ac_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
+echo "${ECHO_T}$MAGIC_CMD" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ echo "$as_me:$LINENO: checking for file" >&5
+echo $ECHO_N "checking for file... $ECHO_C" >&6
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $MAGIC_CMD in
+ /*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+ ;;
+ *)
+ ac_save_MAGIC_CMD="$MAGIC_CMD"
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="/usr/bin:$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ egrep "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ MAGIC_CMD="$ac_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
+echo "${ECHO_T}$MAGIC_CMD" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ RANLIB=$ac_ct_RANLIB
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_STRIP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ STRIP=$ac_ct_STRIP
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$GCC" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$lt_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+ enableval="$enable_libtool_lock"
+
+fi;
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+
+# Check whether --with-pic or --without-pic was given.
+if test "${with_pic+set}" = set; then
+ withval="$with_pic"
+ pic_mode="$withval"
+else
+ pic_mode=default
+fi;
+test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic"
+test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line 6309 "configure"' > conftest.$ac_ext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ case "`/usr/bin/file conftest.o`" in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ case $host in
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ ppc64-*linux*|powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5
+echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6
+if test "${lt_cv_cc_needs_belf+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ lt_cv_cc_needs_belf=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+lt_cv_cc_needs_belf=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5
+echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+
+esac
+
+
+# Save cache, so that ltconfig can load it
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+ (set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+} |
+ sed '
+ t clear
+ : clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+ if test -w $cache_file; then
+ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+ cat confcache >$cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+AR="$AR" LTCC="$CC" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \
+AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \
+objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \
+deplibs_check_method="$deplibs_check_method" file_magic_cmd="$file_magic_cmd" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \
+|| { { echo "$as_me:$LINENO: error: libtool configure failed" >&5
+echo "$as_me: error: libtool configure failed" >&2;}
+ { (exit 1); exit 1; }; }
+
+# Reload cache, that may have been modified by ltconfig
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . $cache_file;;
+ *) . ./$cache_file;;
+ esac
+ fi
+else
+ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh $ac_aux_dir/ltcf-c.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+
+
+
+
+
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.make <<\_ACEOF
+all:
+ @echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+ SET_MAKE=
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+ ./ | .// | /cC/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+done
+
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL=$ac_install_sh
+ fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+ ac_config_files="$ac_config_files Makefile"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+ (set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+} |
+ sed '
+ t clear
+ : clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+ if test -w $cache_file; then
+ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+ cat confcache >$cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[ ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[ ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_i=`echo "$ac_i" |
+ sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+ # 2. Add them.
+ ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling. Logging --version etc. is OK.
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by GNU Fortran Runtime Library $as_me 0.2, which was
+generated by GNU Autoconf 2.59. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+ echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+ echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+ echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+ echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+GNU Fortran Runtime Library config.status 0.2
+configured by $0, generated by GNU Autoconf 2.59,
+ with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value. By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "x$1" : 'x\([^=]*\)='`
+ ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ -*)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ *) # This is not an option, so the user has probably given explicit
+ # arguments.
+ ac_option=$1
+ ac_need_defaults=false;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --vers* | -V )
+ echo "$ac_cs_version"; exit 0 ;;
+ --he | --h)
+ # Conflict between --help and --header
+ { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; };;
+ --help | --hel | -h )
+ echo "$ac_cs_usage"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+ ac_need_defaults=false;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1" ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+ echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+ exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+#
+# INIT-COMMANDS section.
+#
+
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+_ACEOF
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+ case "$ac_config_target" in
+ # Handling of arguments.
+ "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+ trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./confstat$$-$RANDOM
+ (umask 077 && mkdir $tmp)
+} ||
+{
+ echo "$me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+ # Protect against being on the right side of a sed subst in config.status.
+ sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+ s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@CYGPATH_W@,$CYGPATH_W,;t t
+s,@PACKAGE@,$PACKAGE,;t t
+s,@VERSION@,$VERSION,;t t
+s,@ACLOCAL@,$ACLOCAL,;t t
+s,@AUTOCONF@,$AUTOCONF,;t t
+s,@AUTOMAKE@,$AUTOMAKE,;t t
+s,@AUTOHEADER@,$AUTOHEADER,;t t
+s,@MAKEINFO@,$MAKEINFO,;t t
+s,@AMTAR@,$AMTAR,;t t
+s,@install_sh@,$install_sh,;t t
+s,@STRIP@,$STRIP,;t t
+s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t
+s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t
+s,@mkdir_p@,$mkdir_p,;t t
+s,@AWK@,$AWK,;t t
+s,@SET_MAKE@,$SET_MAKE,;t t
+s,@am__leading_dot@,$am__leading_dot,;t t
+s,@MAINTAINER_MODE_TRUE@,$MAINTAINER_MODE_TRUE,;t t
+s,@MAINTAINER_MODE_FALSE@,$MAINTAINER_MODE_FALSE,;t t
+s,@MAINT@,$MAINT,;t t
+s,@enable_shared@,$enable_shared,;t t
+s,@enable_static@,$enable_static,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@DEPDIR@,$DEPDIR,;t t
+s,@am__include@,$am__include,;t t
+s,@am__quote@,$am__quote,;t t
+s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t
+s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t
+s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t
+s,@CCDEPMODE@,$CCDEPMODE,;t t
+s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t
+s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t
+s,@F77@,$F77,;t t
+s,@FFLAGS@,$FFLAGS,;t t
+s,@ac_ct_F77@,$ac_ct_F77,;t t
+s,@CPP@,$CPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@MATH_OBJ@,$MATH_OBJ,;t t
+s,@AR@,$AR,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@build@,$build,;t t
+s,@build_cpu@,$build_cpu,;t t
+s,@build_vendor@,$build_vendor,;t t
+s,@build_os@,$build_os,;t t
+s,@host@,$host,;t t
+s,@host_cpu@,$host_cpu,;t t
+s,@host_vendor@,$host_vendor,;t t
+s,@host_os@,$host_os,;t t
+s,@LN_S@,$LN_S,;t t
+s,@LIBTOOL@,$LIBTOOL,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+ cat >>$CONFIG_STATUS <<\_ACEOF
+ # Split the substitutions into bite-sized pieces for seds with
+ # small command number limits, like on Digital OSF/1 and HP-UX.
+ ac_max_sed_lines=48
+ ac_sed_frag=1 # Number of current file.
+ ac_beg=1 # First line for current file.
+ ac_end=$ac_max_sed_lines # Line after last line for current file.
+ ac_more_lines=:
+ ac_sed_cmds=
+ while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ else
+ sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ fi
+ if test ! -s $tmp/subs.frag; then
+ ac_more_lines=false
+ else
+ # The purpose of the label and of the branching condition is to
+ # speed up the sed processing (if there are no `@' at all, there
+ # is no need to browse any of the substitutions).
+ # These are the two extra sed commands mentioned above.
+ (echo ':t
+ /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+ fi
+ ac_sed_frag=`expr $ac_sed_frag + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_lines`
+ fi
+ done
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+ fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
+ esac
+
+ # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+ esac
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ configure_input=
+ else
+ configure_input="$ac_file. "
+ fi
+ configure_input=$configure_input"Generated from `echo $ac_file_in |
+ sed 's,.*/,,'` by configure."
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ echo "$f";;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo "$f"
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo "$srcdir/$f"
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+
+ if test x"$ac_file" != x-; then
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ rm -f "$ac_file"
+ fi
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+ rm -f $tmp/stdin
+ if test x"$ac_file" != x-; then
+ mv $tmp/out $ac_file
+ else
+ cat $tmp/out
+ rm -f $tmp/out
+ fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='[ ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
+ esac
+
+ test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ # Do quote $f, to prevent DOS paths from being IFS'd.
+ echo "$f";;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo "$f"
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo "$srcdir/$f"
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+ # Remove the trailing spaces.
+ sed 's/[ ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h. The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status. Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless. Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo ' :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+ # Write a limited-size here document to $tmp/defines.sed.
+ echo ' cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+ # Speed up: don't consider the non `#define' lines.
+ echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS
+ # Work around the forget-to-reset-the-flag bug.
+ echo 't clr' >>$CONFIG_STATUS
+ echo ': clr' >>$CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+ echo 'CEOF
+ sed -f $tmp/defines.sed $tmp/in >$tmp/out
+ rm -f $tmp/in
+ mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+ rm -f conftest.defines
+ mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo ' fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo ' # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+ # Write a limited-size here document to $tmp/undefs.sed.
+ echo ' cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+ # Speed up: don't consider the non `#undef'
+ echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS
+ # Work around the forget-to-reset-the-flag bug.
+ echo 't clr' >>$CONFIG_STATUS
+ echo ': clr' >>$CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+ echo 'CEOF
+ sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+ rm -f $tmp/in
+ mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+ rm -f conftest.undefs
+ mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ echo "/* Generated by configure. */" >$tmp/config.h
+ else
+ echo "/* $ac_file. Generated by configure. */" >$tmp/config.h
+ fi
+ cat $tmp/in >>$tmp/config.h
+ rm -f $tmp/in
+ if test x"$ac_file" != x-; then
+ if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+ { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ rm -f $ac_file
+ mv $tmp/config.h $ac_file
+ fi
+ else
+ cat $tmp/config.h
+ rm -f $tmp/config.h
+ fi
+# Compute $ac_file's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $ac_file | $ac_file:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null ||
+$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X$ac_file : 'X\(//\)[^/]' \| \
+ X$ac_file : 'X\(//\)$' \| \
+ X$ac_file : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X$ac_file |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`/stamp-h$_am_stamp_count
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_COMMANDS section.
+#
+for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue
+ ac_dest=`echo "$ac_file" | sed 's,:.*,,'`
+ ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
+$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_dest" : 'X\(//\)[^/]' \| \
+ X"$ac_dest" : 'X\(//\)$' \| \
+ X"$ac_dest" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_dest" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
+
+
+ { echo "$as_me:$LINENO: executing $ac_dest commands" >&5
+echo "$as_me: executing $ac_dest commands" >&6;}
+ case $ac_dest in
+ depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # So let's grep whole file.
+ if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+ dirpart=`(dirname "$mf") 2>/dev/null ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue
+ # Extract the definition of DEP_FILES from the Makefile without
+ # running `make'.
+ DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n -e '/^U = / s///p' < "$mf"`
+ test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+ # We invoke sed twice because it is the simplest approach to
+ # changing $(DEPDIR) to its actual value in the expansion.
+ for file in `sed -n -e '
+ /^DEP_FILES = .*\\\\$/ {
+ s/^DEP_FILES = //
+ :loop
+ s/\\\\$//
+ p
+ n
+ /\\\\$/ b loop
+ p
+ }
+ /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`(dirname "$file") 2>/dev/null ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p $dirpart/$fdir
+ else
+ as_dir=$dirpart/$fdir
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5
+echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+done
+ ;;
+ esac
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
+
+
diff --git a/libgfortran/configure.in b/libgfortran/configure.in
new file mode 100644
index 00000000000..63e5cf8b5e4
--- /dev/null
+++ b/libgfortran/configure.in
@@ -0,0 +1,88 @@
+dnl configure.in for libgfor
+dnl Copyright Free Software Foundation
+dnl Released under the LGPL
+
+dnl The rest of gcc uses autoconf 2.13, but we really need more, hence:
+AC_PREREQ(2.54)
+
+AC_INIT([GNU Fortran Runtime Library], 0.2,,[libgfortran])
+AM_INIT_AUTOMAKE()
+AM_CONFIG_HEADER(config.h)
+AM_MAINTAINER_MODE
+
+AC_SUBST(enable_shared)
+AC_SUBST(enable_static)
+
+# check for compiler
+AC_PROG_CC
+dnl Add -Wall if using gcc
+if test "x$GCC" = "xyes"; then
+ CFLAGS="$CFLAGS -Wall"
+fi
+
+# We need gfortran to compile parts of the library
+# We can't use AC_PROG_F77 because it expects a fully working gfortran.
+#AC_PROG_F77(gfortran)
+F77="$GFORTRAN"
+AC_PROG_F77(gfortran)
+FFLAGS="$FFLAGS -Wall -fno-repack-arrays -fno-underscoring"
+
+AC_FUNC_MMAP
+AC_TYPE_OFF_T
+
+# Check for install
+AC_PROG_INSTALL
+
+# check header files
+AC_STDC_HEADERS
+AC_HAVE_HEADERS(stdlib.h stdio.h string.h stddef.h math.h unistd.h)
+AC_CHECK_HEADERS(time.h sys/params.h sys/time.h sys/times.h sys/resource.h)
+AC_CHECK_HEADER([complex.h],[AC_DEFINE([HAVE_COMPLEX_H], [1], [complex.h exists])])
+# Check for complex math functions
+AC_CHECK_LIB([m],[csin],[need_math="no"],[need_math="yes"])
+
+# Check for complex math functions in -lmx also
+AC_CHECK_LIB([mx],[csin],[need_math="no"],[need_math="yes"])
+
+dnl Checks for library functions.
+AC_CHECK_FUNCS(getrusage times)
+
+# Let the user override this
+AC_ARG_ENABLE(cmath,
+ AC_HELP_STRING([--enable-cmath],[Include complex math functions]),
+ [need_math=$enableval])
+if test "$need_math" = "yes"; then
+ AC_MSG_NOTICE([Including complex math functions in libgfor]);
+ extra_math_obj='$(gfor_cmath_obj)'
+fi
+
+AC_SUBST([MATH_OBJ],["$extra_math_obj"])
+
+dnl The standard autoconf HAVE_STRUCT_TIMEZONE doesn't actually check
+dnl for struct timezone, as you might think. We also need to check how
+dnl to call gettimeofday if we have it.
+LIBGFOR_GETTIMEOFDAY
+
+dnl These should be inherited in the recursive make, but ensure they are
+dnl defined:
+test "$AR" || AR=ar
+AC_SUBST(AR)
+if test "$RANLIB"; then :
+ AC_SUBST(RANLIB)
+else
+ AC_PROG_RANLIB
+fi
+
+dnl Don't pull is system libtool.m4, it conflicts with the gcc version.
+dnl if test "$LIBTOOL"; then :
+dnl AC_SUBST(LIBTOOL)
+dnl else
+dnl AC_PROG_LIBTOOL
+dnl fi
+AM_PROG_LIBTOOL
+
+AC_PROG_MAKE_SET
+AC_PROG_INSTALL
+
+AC_OUTPUT(Makefile)
+
diff --git a/libgfortran/fmain.c b/libgfortran/fmain.c
new file mode 100644
index 00000000000..ec621256df1
--- /dev/null
+++ b/libgfortran/fmain.c
@@ -0,0 +1,22 @@
+#include "config.h"
+#include "libgfortran.h"
+
+/* The main Fortran program actually is a function, called MAIN__.
+ We call it from the main() function in this file. */
+void MAIN__ (void);
+
+/* Main procedure for fortran programs. All we do is set up the environment
+ for the Fortran program. */
+int
+main (int argc, char *argv[])
+{
+ /* Set up the runtime environment. */
+ set_args (argc, argv);
+
+ /* Call the Fortran main program. Internally this is a function
+ called MAIN__ */
+ MAIN__ ();
+
+ /* Bye-bye! */
+ return 0;
+}
diff --git a/libgfortran/generated/_abs_c4.f90 b/libgfortran/generated/_abs_c4.f90
new file mode 100644
index 00000000000..ed5e3c15693
--- /dev/null
+++ b/libgfortran/generated/_abs_c4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__abs_c4 (parm)
+ complex (kind=4), intent (in) :: parm
+ complex (kind=4) :: specific__abs_c4
+
+ specific__abs_c4 = abs (parm)
+end function
diff --git a/libgfortran/generated/_abs_c8.f90 b/libgfortran/generated/_abs_c8.f90
new file mode 100644
index 00000000000..714064cd8a1
--- /dev/null
+++ b/libgfortran/generated/_abs_c8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__abs_c8 (parm)
+ complex (kind=8), intent (in) :: parm
+ complex (kind=8) :: specific__abs_c8
+
+ specific__abs_c8 = abs (parm)
+end function
diff --git a/libgfortran/generated/_abs_i4.f90 b/libgfortran/generated/_abs_i4.f90
new file mode 100644
index 00000000000..146ec072bd8
--- /dev/null
+++ b/libgfortran/generated/_abs_i4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__abs_i4 (parm)
+ integer (kind=4), intent (in) :: parm
+ integer (kind=4) :: specific__abs_i4
+
+ specific__abs_i4 = abs (parm)
+end function
diff --git a/libgfortran/generated/_abs_i8.f90 b/libgfortran/generated/_abs_i8.f90
new file mode 100644
index 00000000000..033ec30e94c
--- /dev/null
+++ b/libgfortran/generated/_abs_i8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__abs_i8 (parm)
+ integer (kind=8), intent (in) :: parm
+ integer (kind=8) :: specific__abs_i8
+
+ specific__abs_i8 = abs (parm)
+end function
diff --git a/libgfortran/generated/_abs_r4.f90 b/libgfortran/generated/_abs_r4.f90
new file mode 100644
index 00000000000..18f3f6b2ccf
--- /dev/null
+++ b/libgfortran/generated/_abs_r4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__abs_r4 (parm)
+ real (kind=4), intent (in) :: parm
+ real (kind=4) :: specific__abs_r4
+
+ specific__abs_r4 = abs (parm)
+end function
diff --git a/libgfortran/generated/_abs_r8.f90 b/libgfortran/generated/_abs_r8.f90
new file mode 100644
index 00000000000..3dc1c8b3e84
--- /dev/null
+++ b/libgfortran/generated/_abs_r8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__abs_r8 (parm)
+ real (kind=8), intent (in) :: parm
+ real (kind=8) :: specific__abs_r8
+
+ specific__abs_r8 = abs (parm)
+end function
diff --git a/libgfortran/generated/_acos_r4.f90 b/libgfortran/generated/_acos_r4.f90
new file mode 100644
index 00000000000..2f49b3093c2
--- /dev/null
+++ b/libgfortran/generated/_acos_r4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__acos_r4 (parm)
+ real (kind=4), intent (in) :: parm
+ real (kind=4) :: specific__acos_r4
+
+ specific__acos_r4 = acos (parm)
+end function
diff --git a/libgfortran/generated/_acos_r8.f90 b/libgfortran/generated/_acos_r8.f90
new file mode 100644
index 00000000000..d285c4566d6
--- /dev/null
+++ b/libgfortran/generated/_acos_r8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__acos_r8 (parm)
+ real (kind=8), intent (in) :: parm
+ real (kind=8) :: specific__acos_r8
+
+ specific__acos_r8 = acos (parm)
+end function
diff --git a/libgfortran/generated/_aint_r4.f90 b/libgfortran/generated/_aint_r4.f90
new file mode 100644
index 00000000000..5c2b641707b
--- /dev/null
+++ b/libgfortran/generated/_aint_r4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__aint_r4 (parm)
+ real (kind=4), intent (in) :: parm
+ real (kind=4) :: specific__aint_r4
+
+ specific__aint_r4 = aint (parm)
+end function
diff --git a/libgfortran/generated/_aint_r8.f90 b/libgfortran/generated/_aint_r8.f90
new file mode 100644
index 00000000000..65c675458c3
--- /dev/null
+++ b/libgfortran/generated/_aint_r8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__aint_r8 (parm)
+ real (kind=8), intent (in) :: parm
+ real (kind=8) :: specific__aint_r8
+
+ specific__aint_r8 = aint (parm)
+end function
diff --git a/libgfortran/generated/_anint_r4.f90 b/libgfortran/generated/_anint_r4.f90
new file mode 100644
index 00000000000..9056f0077d9
--- /dev/null
+++ b/libgfortran/generated/_anint_r4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__anint_r4 (parm)
+ real (kind=4), intent (in) :: parm
+ real (kind=4) :: specific__anint_r4
+
+ specific__anint_r4 = anint (parm)
+end function
diff --git a/libgfortran/generated/_anint_r8.f90 b/libgfortran/generated/_anint_r8.f90
new file mode 100644
index 00000000000..46d87e07934
--- /dev/null
+++ b/libgfortran/generated/_anint_r8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__anint_r8 (parm)
+ real (kind=8), intent (in) :: parm
+ real (kind=8) :: specific__anint_r8
+
+ specific__anint_r8 = anint (parm)
+end function
diff --git a/libgfortran/generated/_asin_r4.f90 b/libgfortran/generated/_asin_r4.f90
new file mode 100644
index 00000000000..bf4dfa48304
--- /dev/null
+++ b/libgfortran/generated/_asin_r4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__asin_r4 (parm)
+ real (kind=4), intent (in) :: parm
+ real (kind=4) :: specific__asin_r4
+
+ specific__asin_r4 = asin (parm)
+end function
diff --git a/libgfortran/generated/_asin_r8.f90 b/libgfortran/generated/_asin_r8.f90
new file mode 100644
index 00000000000..37adbc64a68
--- /dev/null
+++ b/libgfortran/generated/_asin_r8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__asin_r8 (parm)
+ real (kind=8), intent (in) :: parm
+ real (kind=8) :: specific__asin_r8
+
+ specific__asin_r8 = asin (parm)
+end function
diff --git a/libgfortran/generated/_atan2_r4.f90 b/libgfortran/generated/_atan2_r4.f90
new file mode 100644
index 00000000000..fddda221f12
--- /dev/null
+++ b/libgfortran/generated/_atan2_r4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__atan2_r4 (p1, p2)
+ real (kind=4), intent (in) :: p1, p2
+ real (kind=4) :: specific__atan2_r4
+
+ specific__atan2_r4 = atan2 (p1, p2)
+end function
diff --git a/libgfortran/generated/_atan2_r8.f90 b/libgfortran/generated/_atan2_r8.f90
new file mode 100644
index 00000000000..76ec23c0ad4
--- /dev/null
+++ b/libgfortran/generated/_atan2_r8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__atan2_r8 (p1, p2)
+ real (kind=8), intent (in) :: p1, p2
+ real (kind=8) :: specific__atan2_r8
+
+ specific__atan2_r8 = atan2 (p1, p2)
+end function
diff --git a/libgfortran/generated/_atan_r4.f90 b/libgfortran/generated/_atan_r4.f90
new file mode 100644
index 00000000000..0918d7f3f12
--- /dev/null
+++ b/libgfortran/generated/_atan_r4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__atan_r4 (parm)
+ real (kind=4), intent (in) :: parm
+ real (kind=4) :: specific__atan_r4
+
+ specific__atan_r4 = atan (parm)
+end function
diff --git a/libgfortran/generated/_atan_r8.f90 b/libgfortran/generated/_atan_r8.f90
new file mode 100644
index 00000000000..71fe2e730c2
--- /dev/null
+++ b/libgfortran/generated/_atan_r8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__atan_r8 (parm)
+ real (kind=8), intent (in) :: parm
+ real (kind=8) :: specific__atan_r8
+
+ specific__atan_r8 = atan (parm)
+end function
diff --git a/libgfortran/generated/_conjg_c4.f90 b/libgfortran/generated/_conjg_c4.f90
new file mode 100644
index 00000000000..3d799ffd372
--- /dev/null
+++ b/libgfortran/generated/_conjg_c4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__conjg_c4 (parm)
+ complex (kind=4), intent (in) :: parm
+ complex (kind=4) :: specific__conjg_c4
+
+ specific__conjg_c4 = conjg (parm)
+end function
diff --git a/libgfortran/generated/_conjg_c8.f90 b/libgfortran/generated/_conjg_c8.f90
new file mode 100644
index 00000000000..a8d4957c369
--- /dev/null
+++ b/libgfortran/generated/_conjg_c8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__conjg_c8 (parm)
+ complex (kind=8), intent (in) :: parm
+ complex (kind=8) :: specific__conjg_c8
+
+ specific__conjg_c8 = conjg (parm)
+end function
diff --git a/libgfortran/generated/_cos_c4.f90 b/libgfortran/generated/_cos_c4.f90
new file mode 100644
index 00000000000..40f772a96fe
--- /dev/null
+++ b/libgfortran/generated/_cos_c4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__cos_c4 (parm)
+ complex (kind=4), intent (in) :: parm
+ complex (kind=4) :: specific__cos_c4
+
+ specific__cos_c4 = cos (parm)
+end function
diff --git a/libgfortran/generated/_cos_c8.f90 b/libgfortran/generated/_cos_c8.f90
new file mode 100644
index 00000000000..7ae0d1ed7e3
--- /dev/null
+++ b/libgfortran/generated/_cos_c8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__cos_c8 (parm)
+ complex (kind=8), intent (in) :: parm
+ complex (kind=8) :: specific__cos_c8
+
+ specific__cos_c8 = cos (parm)
+end function
diff --git a/libgfortran/generated/_cos_r4.f90 b/libgfortran/generated/_cos_r4.f90
new file mode 100644
index 00000000000..186900ed05a
--- /dev/null
+++ b/libgfortran/generated/_cos_r4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__cos_r4 (parm)
+ real (kind=4), intent (in) :: parm
+ real (kind=4) :: specific__cos_r4
+
+ specific__cos_r4 = cos (parm)
+end function
diff --git a/libgfortran/generated/_cos_r8.f90 b/libgfortran/generated/_cos_r8.f90
new file mode 100644
index 00000000000..6842d9109f0
--- /dev/null
+++ b/libgfortran/generated/_cos_r8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__cos_r8 (parm)
+ real (kind=8), intent (in) :: parm
+ real (kind=8) :: specific__cos_r8
+
+ specific__cos_r8 = cos (parm)
+end function
diff --git a/libgfortran/generated/_cosh_r4.f90 b/libgfortran/generated/_cosh_r4.f90
new file mode 100644
index 00000000000..2e40c85f2f1
--- /dev/null
+++ b/libgfortran/generated/_cosh_r4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__cosh_r4 (parm)
+ real (kind=4), intent (in) :: parm
+ real (kind=4) :: specific__cosh_r4
+
+ specific__cosh_r4 = cosh (parm)
+end function
diff --git a/libgfortran/generated/_cosh_r8.f90 b/libgfortran/generated/_cosh_r8.f90
new file mode 100644
index 00000000000..ef1ab85b0d0
--- /dev/null
+++ b/libgfortran/generated/_cosh_r8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__cosh_r8 (parm)
+ real (kind=8), intent (in) :: parm
+ real (kind=8) :: specific__cosh_r8
+
+ specific__cosh_r8 = cosh (parm)
+end function
diff --git a/libgfortran/generated/_dim_i4.f90 b/libgfortran/generated/_dim_i4.f90
new file mode 100644
index 00000000000..e46a34f46ff
--- /dev/null
+++ b/libgfortran/generated/_dim_i4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__dim_i4 (p1, p2)
+ integer (kind=4), intent (in) :: p1, p2
+ integer (kind=4) :: specific__dim_i4
+
+ specific__dim_i4 = dim (p1, p2)
+end function
diff --git a/libgfortran/generated/_dim_i8.f90 b/libgfortran/generated/_dim_i8.f90
new file mode 100644
index 00000000000..fa823280b83
--- /dev/null
+++ b/libgfortran/generated/_dim_i8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__dim_i8 (p1, p2)
+ integer (kind=8), intent (in) :: p1, p2
+ integer (kind=8) :: specific__dim_i8
+
+ specific__dim_i8 = dim (p1, p2)
+end function
diff --git a/libgfortran/generated/_dim_r4.f90 b/libgfortran/generated/_dim_r4.f90
new file mode 100644
index 00000000000..1841ae7a033
--- /dev/null
+++ b/libgfortran/generated/_dim_r4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__dim_r4 (p1, p2)
+ real (kind=4), intent (in) :: p1, p2
+ real (kind=4) :: specific__dim_r4
+
+ specific__dim_r4 = dim (p1, p2)
+end function
diff --git a/libgfortran/generated/_dim_r8.f90 b/libgfortran/generated/_dim_r8.f90
new file mode 100644
index 00000000000..8de846adce2
--- /dev/null
+++ b/libgfortran/generated/_dim_r8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__dim_r8 (p1, p2)
+ real (kind=8), intent (in) :: p1, p2
+ real (kind=8) :: specific__dim_r8
+
+ specific__dim_r8 = dim (p1, p2)
+end function
diff --git a/libgfortran/generated/_exp_c4.f90 b/libgfortran/generated/_exp_c4.f90
new file mode 100644
index 00000000000..530be220218
--- /dev/null
+++ b/libgfortran/generated/_exp_c4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__exp_c4 (parm)
+ complex (kind=4), intent (in) :: parm
+ complex (kind=4) :: specific__exp_c4
+
+ specific__exp_c4 = exp (parm)
+end function
diff --git a/libgfortran/generated/_exp_c8.f90 b/libgfortran/generated/_exp_c8.f90
new file mode 100644
index 00000000000..933c5606253
--- /dev/null
+++ b/libgfortran/generated/_exp_c8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__exp_c8 (parm)
+ complex (kind=8), intent (in) :: parm
+ complex (kind=8) :: specific__exp_c8
+
+ specific__exp_c8 = exp (parm)
+end function
diff --git a/libgfortran/generated/_exp_r4.f90 b/libgfortran/generated/_exp_r4.f90
new file mode 100644
index 00000000000..ec56a495c45
--- /dev/null
+++ b/libgfortran/generated/_exp_r4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__exp_r4 (parm)
+ real (kind=4), intent (in) :: parm
+ real (kind=4) :: specific__exp_r4
+
+ specific__exp_r4 = exp (parm)
+end function
diff --git a/libgfortran/generated/_exp_r8.f90 b/libgfortran/generated/_exp_r8.f90
new file mode 100644
index 00000000000..fcd8d7d15a4
--- /dev/null
+++ b/libgfortran/generated/_exp_r8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__exp_r8 (parm)
+ real (kind=8), intent (in) :: parm
+ real (kind=8) :: specific__exp_r8
+
+ specific__exp_r8 = exp (parm)
+end function
diff --git a/libgfortran/generated/_log10_r4.f90 b/libgfortran/generated/_log10_r4.f90
new file mode 100644
index 00000000000..0d0d854db41
--- /dev/null
+++ b/libgfortran/generated/_log10_r4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__log10_r4 (parm)
+ real (kind=4), intent (in) :: parm
+ real (kind=4) :: specific__log10_r4
+
+ specific__log10_r4 = log10 (parm)
+end function
diff --git a/libgfortran/generated/_log10_r8.f90 b/libgfortran/generated/_log10_r8.f90
new file mode 100644
index 00000000000..360e9b59c54
--- /dev/null
+++ b/libgfortran/generated/_log10_r8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__log10_r8 (parm)
+ real (kind=8), intent (in) :: parm
+ real (kind=8) :: specific__log10_r8
+
+ specific__log10_r8 = log10 (parm)
+end function
diff --git a/libgfortran/generated/_log_c4.f90 b/libgfortran/generated/_log_c4.f90
new file mode 100644
index 00000000000..615c00a0272
--- /dev/null
+++ b/libgfortran/generated/_log_c4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__log_c4 (parm)
+ complex (kind=4), intent (in) :: parm
+ complex (kind=4) :: specific__log_c4
+
+ specific__log_c4 = log (parm)
+end function
diff --git a/libgfortran/generated/_log_c8.f90 b/libgfortran/generated/_log_c8.f90
new file mode 100644
index 00000000000..38c757cb1b9
--- /dev/null
+++ b/libgfortran/generated/_log_c8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__log_c8 (parm)
+ complex (kind=8), intent (in) :: parm
+ complex (kind=8) :: specific__log_c8
+
+ specific__log_c8 = log (parm)
+end function
diff --git a/libgfortran/generated/_log_r4.f90 b/libgfortran/generated/_log_r4.f90
new file mode 100644
index 00000000000..5cbe7d1a92e
--- /dev/null
+++ b/libgfortran/generated/_log_r4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__log_r4 (parm)
+ real (kind=4), intent (in) :: parm
+ real (kind=4) :: specific__log_r4
+
+ specific__log_r4 = log (parm)
+end function
diff --git a/libgfortran/generated/_log_r8.f90 b/libgfortran/generated/_log_r8.f90
new file mode 100644
index 00000000000..7e0491297fd
--- /dev/null
+++ b/libgfortran/generated/_log_r8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__log_r8 (parm)
+ real (kind=8), intent (in) :: parm
+ real (kind=8) :: specific__log_r8
+
+ specific__log_r8 = log (parm)
+end function
diff --git a/libgfortran/generated/_mod_i4.f90 b/libgfortran/generated/_mod_i4.f90
new file mode 100644
index 00000000000..396502960d0
--- /dev/null
+++ b/libgfortran/generated/_mod_i4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__mod_i4 (p1, p2)
+ integer (kind=4), intent (in) :: p1, p2
+ integer (kind=4) :: specific__mod_i4
+
+ specific__mod_i4 = mod (p1, p2)
+end function
diff --git a/libgfortran/generated/_mod_i8.f90 b/libgfortran/generated/_mod_i8.f90
new file mode 100644
index 00000000000..57552abb569
--- /dev/null
+++ b/libgfortran/generated/_mod_i8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__mod_i8 (p1, p2)
+ integer (kind=8), intent (in) :: p1, p2
+ integer (kind=8) :: specific__mod_i8
+
+ specific__mod_i8 = mod (p1, p2)
+end function
diff --git a/libgfortran/generated/_mod_r4.f90 b/libgfortran/generated/_mod_r4.f90
new file mode 100644
index 00000000000..6fe164fa645
--- /dev/null
+++ b/libgfortran/generated/_mod_r4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__mod_r4 (p1, p2)
+ real (kind=4), intent (in) :: p1, p2
+ real (kind=4) :: specific__mod_r4
+
+ specific__mod_r4 = mod (p1, p2)
+end function
diff --git a/libgfortran/generated/_mod_r8.f90 b/libgfortran/generated/_mod_r8.f90
new file mode 100644
index 00000000000..4857a66130b
--- /dev/null
+++ b/libgfortran/generated/_mod_r8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__mod_r8 (p1, p2)
+ real (kind=8), intent (in) :: p1, p2
+ real (kind=8) :: specific__mod_r8
+
+ specific__mod_r8 = mod (p1, p2)
+end function
diff --git a/libgfortran/generated/_sign_i4.f90 b/libgfortran/generated/_sign_i4.f90
new file mode 100644
index 00000000000..db695b19ac7
--- /dev/null
+++ b/libgfortran/generated/_sign_i4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__sign_i4 (p1, p2)
+ integer (kind=4), intent (in) :: p1, p2
+ integer (kind=4) :: specific__sign_i4
+
+ specific__sign_i4 = sign (p1, p2)
+end function
diff --git a/libgfortran/generated/_sign_i8.f90 b/libgfortran/generated/_sign_i8.f90
new file mode 100644
index 00000000000..d46ebb7ca49
--- /dev/null
+++ b/libgfortran/generated/_sign_i8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__sign_i8 (p1, p2)
+ integer (kind=8), intent (in) :: p1, p2
+ integer (kind=8) :: specific__sign_i8
+
+ specific__sign_i8 = sign (p1, p2)
+end function
diff --git a/libgfortran/generated/_sign_r4.f90 b/libgfortran/generated/_sign_r4.f90
new file mode 100644
index 00000000000..fe68f510f11
--- /dev/null
+++ b/libgfortran/generated/_sign_r4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__sign_r4 (p1, p2)
+ real (kind=4), intent (in) :: p1, p2
+ real (kind=4) :: specific__sign_r4
+
+ specific__sign_r4 = sign (p1, p2)
+end function
diff --git a/libgfortran/generated/_sign_r8.f90 b/libgfortran/generated/_sign_r8.f90
new file mode 100644
index 00000000000..3a0f109fdd6
--- /dev/null
+++ b/libgfortran/generated/_sign_r8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__sign_r8 (p1, p2)
+ real (kind=8), intent (in) :: p1, p2
+ real (kind=8) :: specific__sign_r8
+
+ specific__sign_r8 = sign (p1, p2)
+end function
diff --git a/libgfortran/generated/_sin_c4.f90 b/libgfortran/generated/_sin_c4.f90
new file mode 100644
index 00000000000..7d9cb36e5a3
--- /dev/null
+++ b/libgfortran/generated/_sin_c4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__sin_c4 (parm)
+ complex (kind=4), intent (in) :: parm
+ complex (kind=4) :: specific__sin_c4
+
+ specific__sin_c4 = sin (parm)
+end function
diff --git a/libgfortran/generated/_sin_c8.f90 b/libgfortran/generated/_sin_c8.f90
new file mode 100644
index 00000000000..d9d929628eb
--- /dev/null
+++ b/libgfortran/generated/_sin_c8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__sin_c8 (parm)
+ complex (kind=8), intent (in) :: parm
+ complex (kind=8) :: specific__sin_c8
+
+ specific__sin_c8 = sin (parm)
+end function
diff --git a/libgfortran/generated/_sin_r4.f90 b/libgfortran/generated/_sin_r4.f90
new file mode 100644
index 00000000000..f531afc774e
--- /dev/null
+++ b/libgfortran/generated/_sin_r4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__sin_r4 (parm)
+ real (kind=4), intent (in) :: parm
+ real (kind=4) :: specific__sin_r4
+
+ specific__sin_r4 = sin (parm)
+end function
diff --git a/libgfortran/generated/_sin_r8.f90 b/libgfortran/generated/_sin_r8.f90
new file mode 100644
index 00000000000..d385d5c365a
--- /dev/null
+++ b/libgfortran/generated/_sin_r8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__sin_r8 (parm)
+ real (kind=8), intent (in) :: parm
+ real (kind=8) :: specific__sin_r8
+
+ specific__sin_r8 = sin (parm)
+end function
diff --git a/libgfortran/generated/_sinh_r4.f90 b/libgfortran/generated/_sinh_r4.f90
new file mode 100644
index 00000000000..24f1fa80154
--- /dev/null
+++ b/libgfortran/generated/_sinh_r4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__sinh_r4 (parm)
+ real (kind=4), intent (in) :: parm
+ real (kind=4) :: specific__sinh_r4
+
+ specific__sinh_r4 = sinh (parm)
+end function
diff --git a/libgfortran/generated/_sinh_r8.f90 b/libgfortran/generated/_sinh_r8.f90
new file mode 100644
index 00000000000..6b166de8d22
--- /dev/null
+++ b/libgfortran/generated/_sinh_r8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__sinh_r8 (parm)
+ real (kind=8), intent (in) :: parm
+ real (kind=8) :: specific__sinh_r8
+
+ specific__sinh_r8 = sinh (parm)
+end function
diff --git a/libgfortran/generated/_sqrt_c4.f90 b/libgfortran/generated/_sqrt_c4.f90
new file mode 100644
index 00000000000..2377f25b498
--- /dev/null
+++ b/libgfortran/generated/_sqrt_c4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__sqrt_c4 (parm)
+ complex (kind=4), intent (in) :: parm
+ complex (kind=4) :: specific__sqrt_c4
+
+ specific__sqrt_c4 = sqrt (parm)
+end function
diff --git a/libgfortran/generated/_sqrt_c8.f90 b/libgfortran/generated/_sqrt_c8.f90
new file mode 100644
index 00000000000..c32da20f164
--- /dev/null
+++ b/libgfortran/generated/_sqrt_c8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__sqrt_c8 (parm)
+ complex (kind=8), intent (in) :: parm
+ complex (kind=8) :: specific__sqrt_c8
+
+ specific__sqrt_c8 = sqrt (parm)
+end function
diff --git a/libgfortran/generated/_sqrt_r4.f90 b/libgfortran/generated/_sqrt_r4.f90
new file mode 100644
index 00000000000..62416e79d34
--- /dev/null
+++ b/libgfortran/generated/_sqrt_r4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__sqrt_r4 (parm)
+ real (kind=4), intent (in) :: parm
+ real (kind=4) :: specific__sqrt_r4
+
+ specific__sqrt_r4 = sqrt (parm)
+end function
diff --git a/libgfortran/generated/_sqrt_r8.f90 b/libgfortran/generated/_sqrt_r8.f90
new file mode 100644
index 00000000000..3928cd46383
--- /dev/null
+++ b/libgfortran/generated/_sqrt_r8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__sqrt_r8 (parm)
+ real (kind=8), intent (in) :: parm
+ real (kind=8) :: specific__sqrt_r8
+
+ specific__sqrt_r8 = sqrt (parm)
+end function
diff --git a/libgfortran/generated/_tan_r4.f90 b/libgfortran/generated/_tan_r4.f90
new file mode 100644
index 00000000000..aaf26b19175
--- /dev/null
+++ b/libgfortran/generated/_tan_r4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__tan_r4 (parm)
+ real (kind=4), intent (in) :: parm
+ real (kind=4) :: specific__tan_r4
+
+ specific__tan_r4 = tan (parm)
+end function
diff --git a/libgfortran/generated/_tan_r8.f90 b/libgfortran/generated/_tan_r8.f90
new file mode 100644
index 00000000000..eca6d228355
--- /dev/null
+++ b/libgfortran/generated/_tan_r8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__tan_r8 (parm)
+ real (kind=8), intent (in) :: parm
+ real (kind=8) :: specific__tan_r8
+
+ specific__tan_r8 = tan (parm)
+end function
diff --git a/libgfortran/generated/_tanh_r4.f90 b/libgfortran/generated/_tanh_r4.f90
new file mode 100644
index 00000000000..b027ed6c251
--- /dev/null
+++ b/libgfortran/generated/_tanh_r4.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__tanh_r4 (parm)
+ real (kind=4), intent (in) :: parm
+ real (kind=4) :: specific__tanh_r4
+
+ specific__tanh_r4 = tanh (parm)
+end function
diff --git a/libgfortran/generated/_tanh_r8.f90 b/libgfortran/generated/_tanh_r8.f90
new file mode 100644
index 00000000000..a5bbf18fefd
--- /dev/null
+++ b/libgfortran/generated/_tanh_r8.f90
@@ -0,0 +1,29 @@
+! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.
+
+
+elemental function specific__tanh_r8 (parm)
+ real (kind=8), intent (in) :: parm
+ real (kind=8) :: specific__tanh_r8
+
+ specific__tanh_r8 = tanh (parm)
+end function
diff --git a/libgfortran/generated/all_l4.c b/libgfortran/generated/all_l4.c
new file mode 100644
index 00000000000..5bfeeab328e
--- /dev/null
+++ b/libgfortran/generated/all_l4.c
@@ -0,0 +1,133 @@
+/* Implementation of the ALL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+
+void
+__all_l4 (gfc_array_l4 * retarray, gfc_array_l4 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_LOGICAL_4 *base;
+ GFC_LOGICAL_4 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_LOGICAL_4 *src;
+ GFC_LOGICAL_4 result;
+ src = base;
+ {
+
+ /* Return true only if all the elements are set. */
+ result = 1;
+ if (len <= 0)
+ *dest = 1;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (! *src)
+ {
+ result = 0;
+ break;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/all_l8.c b/libgfortran/generated/all_l8.c
new file mode 100644
index 00000000000..b47b128dbba
--- /dev/null
+++ b/libgfortran/generated/all_l8.c
@@ -0,0 +1,133 @@
+/* Implementation of the ALL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+
+void
+__all_l8 (gfc_array_l8 * retarray, gfc_array_l8 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_LOGICAL_8 *base;
+ GFC_LOGICAL_8 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_LOGICAL_8 *src;
+ GFC_LOGICAL_8 result;
+ src = base;
+ {
+
+ /* Return true only if all the elements are set. */
+ result = 1;
+ if (len <= 0)
+ *dest = 1;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (! *src)
+ {
+ result = 0;
+ break;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/any_l4.c b/libgfortran/generated/any_l4.c
new file mode 100644
index 00000000000..6abb9025e11
--- /dev/null
+++ b/libgfortran/generated/any_l4.c
@@ -0,0 +1,133 @@
+/* Implementation of the ANY intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+
+void
+__any_l4 (gfc_array_l4 * retarray, gfc_array_l4 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_LOGICAL_4 *base;
+ GFC_LOGICAL_4 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_LOGICAL_4 *src;
+ GFC_LOGICAL_4 result;
+ src = base;
+ {
+
+ result = 0;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ /* Return true if any of the elements are set. */
+ if (*src)
+ {
+ result = 1;
+ break;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/any_l8.c b/libgfortran/generated/any_l8.c
new file mode 100644
index 00000000000..20e0c4693a0
--- /dev/null
+++ b/libgfortran/generated/any_l8.c
@@ -0,0 +1,133 @@
+/* Implementation of the ANY intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+
+void
+__any_l8 (gfc_array_l8 * retarray, gfc_array_l8 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_LOGICAL_8 *base;
+ GFC_LOGICAL_8 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_LOGICAL_8 *src;
+ GFC_LOGICAL_8 result;
+ src = base;
+ {
+
+ result = 0;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ /* Return true if any of the elements are set. */
+ if (*src)
+ {
+ result = 1;
+ break;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/count_4_l4.c b/libgfortran/generated/count_4_l4.c
new file mode 100644
index 00000000000..959c8b8a371
--- /dev/null
+++ b/libgfortran/generated/count_4_l4.c
@@ -0,0 +1,129 @@
+/* Implementation of the COUNT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+
+void
+__count_4_l4 (gfc_array_i4 * retarray, gfc_array_l4 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_LOGICAL_4 *base;
+ GFC_INTEGER_4 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_LOGICAL_4 *src;
+ GFC_INTEGER_4 result;
+ src = base;
+ {
+
+ result = 0;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src)
+ result++;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/count_4_l8.c b/libgfortran/generated/count_4_l8.c
new file mode 100644
index 00000000000..3879e9bee78
--- /dev/null
+++ b/libgfortran/generated/count_4_l8.c
@@ -0,0 +1,129 @@
+/* Implementation of the COUNT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+
+void
+__count_4_l8 (gfc_array_i4 * retarray, gfc_array_l8 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_LOGICAL_8 *base;
+ GFC_INTEGER_4 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_LOGICAL_8 *src;
+ GFC_INTEGER_4 result;
+ src = base;
+ {
+
+ result = 0;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src)
+ result++;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/count_8_l4.c b/libgfortran/generated/count_8_l4.c
new file mode 100644
index 00000000000..67b6ec32280
--- /dev/null
+++ b/libgfortran/generated/count_8_l4.c
@@ -0,0 +1,129 @@
+/* Implementation of the COUNT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+
+void
+__count_8_l4 (gfc_array_i8 * retarray, gfc_array_l4 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_LOGICAL_4 *base;
+ GFC_INTEGER_8 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_LOGICAL_4 *src;
+ GFC_INTEGER_8 result;
+ src = base;
+ {
+
+ result = 0;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src)
+ result++;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/count_8_l8.c b/libgfortran/generated/count_8_l8.c
new file mode 100644
index 00000000000..93d6c2d281a
--- /dev/null
+++ b/libgfortran/generated/count_8_l8.c
@@ -0,0 +1,129 @@
+/* Implementation of the COUNT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+
+void
+__count_8_l8 (gfc_array_i8 * retarray, gfc_array_l8 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_LOGICAL_8 *base;
+ GFC_INTEGER_8 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_LOGICAL_8 *src;
+ GFC_INTEGER_8 result;
+ src = base;
+ {
+
+ result = 0;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src)
+ result++;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/cshift1_4.c b/libgfortran/generated/cshift1_4.c
new file mode 100644
index 00000000000..9375074db2a
--- /dev/null
+++ b/libgfortran/generated/cshift1_4.c
@@ -0,0 +1,170 @@
+/* Implementation of the CSHIFT intrinsic
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Feng Wang <wf_cs@yahoo.com>
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "libgfortran.h"
+
+void
+__cshift1_4 (const gfc_array_char * ret, const gfc_array_char * array,
+ const gfc_array_i4 * h, const GFC_INTEGER_4 * pwhich)
+{
+ /* r.* indicates the return array. */
+ index_type rstride[GFC_MAX_DIMENSIONS - 1];
+ index_type rstride0;
+ index_type roffset;
+ char *rptr;
+ char *dest;
+ /* s.* indicates the source array. */
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride0;
+ index_type soffset;
+ const char *sptr;
+ const char *src;
+ /* h.* indicates the shift array. */
+ index_type hstride[GFC_MAX_DIMENSIONS - 1];
+ index_type hstride0;
+ const GFC_INTEGER_4 *hptr;
+
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type dim;
+ index_type size;
+ index_type len;
+ index_type n;
+ int which;
+ GFC_INTEGER_4 sh;
+
+ if (pwhich)
+ which = *pwhich - 1;
+ else
+ which = 0;
+
+ if (which < 0 || (which + 1) > GFC_DESCRIPTOR_RANK (array))
+ runtime_error ("Argument 'DIM' is out of range in call to 'CSHIFT'");
+
+ size = GFC_DESCRIPTOR_SIZE (ret);
+
+ extent[0] = 1;
+ count[0] = 0;
+ size = GFC_DESCRIPTOR_SIZE (array);
+ n = 0;
+
+/* Initialized for avoiding compiler warnings. */
+ roffset = size;
+ soffset = size;
+ len = 0;
+
+ for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
+ {
+ if (dim == which)
+ {
+ roffset = ret->dim[dim].stride * size;
+ if (roffset == 0)
+ roffset = size;
+ soffset = array->dim[dim].stride * size;
+ if (soffset == 0)
+ soffset = size;
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ }
+ else
+ {
+ count[n] = 0;
+ extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ rstride[n] = ret->dim[dim].stride * size;
+ sstride[n] = array->dim[dim].stride * size;
+
+ hstride[n] = h->dim[n].stride;
+ n++;
+ }
+ }
+ if (sstride[0] == 0)
+ sstride[0] = size;
+ if (rstride[0] == 0)
+ rstride[0] = size;
+ if (hstride[0] == 0)
+ hstride[0] = 1;
+
+ dim = GFC_DESCRIPTOR_RANK (array);
+ rstride0 = rstride[0];
+ sstride0 = sstride[0];
+ hstride0 = hstride[0];
+ rptr = ret->data;
+ sptr = array->data;
+ hptr = h->data;
+
+ while (rptr)
+ {
+ /* Do the shift for this dimension. */
+ sh = *hptr;
+ sh = (div (sh, len)).rem;
+ if (sh < 0)
+ sh += len;
+
+ src = &sptr[sh * soffset];
+ dest = rptr;
+
+ for (n = 0; n < len; n++)
+ {
+ memcpy (dest, src, size);
+ dest += roffset;
+ if (n == len - sh - 1)
+ src = sptr;
+ else
+ src += soffset;
+ }
+
+ /* Advance to the next section. */
+ rptr += rstride0;
+ sptr += sstride0;
+ hptr += hstride0;
+ count[0]++;
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ rptr -= rstride[n] * extent[n];
+ sptr -= sstride[n] * extent[n];
+ hptr -= hstride[n] * extent[n];
+ n++;
+ if (n >= dim - 1)
+ {
+ /* Break out of the loop. */
+ rptr = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ rptr += rstride[n];
+ sptr += sstride[n];
+ hptr += hstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/cshift1_8.c b/libgfortran/generated/cshift1_8.c
new file mode 100644
index 00000000000..7303d560440
--- /dev/null
+++ b/libgfortran/generated/cshift1_8.c
@@ -0,0 +1,170 @@
+/* Implementation of the CSHIFT intrinsic
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Feng Wang <wf_cs@yahoo.com>
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "libgfortran.h"
+
+void
+__cshift1_8 (const gfc_array_char * ret, const gfc_array_char * array,
+ const gfc_array_i8 * h, const GFC_INTEGER_8 * pwhich)
+{
+ /* r.* indicates the return array. */
+ index_type rstride[GFC_MAX_DIMENSIONS - 1];
+ index_type rstride0;
+ index_type roffset;
+ char *rptr;
+ char *dest;
+ /* s.* indicates the source array. */
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride0;
+ index_type soffset;
+ const char *sptr;
+ const char *src;
+ /* h.* indicates the shift array. */
+ index_type hstride[GFC_MAX_DIMENSIONS - 1];
+ index_type hstride0;
+ const GFC_INTEGER_8 *hptr;
+
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type dim;
+ index_type size;
+ index_type len;
+ index_type n;
+ int which;
+ GFC_INTEGER_8 sh;
+
+ if (pwhich)
+ which = *pwhich - 1;
+ else
+ which = 0;
+
+ if (which < 0 || (which + 1) > GFC_DESCRIPTOR_RANK (array))
+ runtime_error ("Argument 'DIM' is out of range in call to 'CSHIFT'");
+
+ size = GFC_DESCRIPTOR_SIZE (ret);
+
+ extent[0] = 1;
+ count[0] = 0;
+ size = GFC_DESCRIPTOR_SIZE (array);
+ n = 0;
+
+/* Initialized for avoiding compiler warnings. */
+ roffset = size;
+ soffset = size;
+ len = 0;
+
+ for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
+ {
+ if (dim == which)
+ {
+ roffset = ret->dim[dim].stride * size;
+ if (roffset == 0)
+ roffset = size;
+ soffset = array->dim[dim].stride * size;
+ if (soffset == 0)
+ soffset = size;
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ }
+ else
+ {
+ count[n] = 0;
+ extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ rstride[n] = ret->dim[dim].stride * size;
+ sstride[n] = array->dim[dim].stride * size;
+
+ hstride[n] = h->dim[n].stride;
+ n++;
+ }
+ }
+ if (sstride[0] == 0)
+ sstride[0] = size;
+ if (rstride[0] == 0)
+ rstride[0] = size;
+ if (hstride[0] == 0)
+ hstride[0] = 1;
+
+ dim = GFC_DESCRIPTOR_RANK (array);
+ rstride0 = rstride[0];
+ sstride0 = sstride[0];
+ hstride0 = hstride[0];
+ rptr = ret->data;
+ sptr = array->data;
+ hptr = h->data;
+
+ while (rptr)
+ {
+ /* Do the shift for this dimension. */
+ sh = *hptr;
+ sh = (div (sh, len)).rem;
+ if (sh < 0)
+ sh += len;
+
+ src = &sptr[sh * soffset];
+ dest = rptr;
+
+ for (n = 0; n < len; n++)
+ {
+ memcpy (dest, src, size);
+ dest += roffset;
+ if (n == len - sh - 1)
+ src = sptr;
+ else
+ src += soffset;
+ }
+
+ /* Advance to the next section. */
+ rptr += rstride0;
+ sptr += sstride0;
+ hptr += hstride0;
+ count[0]++;
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ rptr -= rstride[n] * extent[n];
+ sptr -= sstride[n] * extent[n];
+ hptr -= hstride[n] * extent[n];
+ n++;
+ if (n >= dim - 1)
+ {
+ /* Break out of the loop. */
+ rptr = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ rptr += rstride[n];
+ sptr += sstride[n];
+ hptr += hstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/dotprod_c4.c b/libgfortran/generated/dotprod_c4.c
new file mode 100644
index 00000000000..9812ab4e3c8
--- /dev/null
+++ b/libgfortran/generated/dotprod_c4.c
@@ -0,0 +1,67 @@
+/* Implementation of the DOT_PRODUCT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+ and Feng Wang <fengwang@nudt.edu.cn>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+typedef GFC_ARRAY_DESCRIPTOR(GFC_MAX_DIMENSIONS, char) char_array;
+
+/* Both parameters will already have been converted to the result type. */
+GFC_COMPLEX_4
+__dot_product_c4 (gfc_array_c4 * a, gfc_array_c4 * b)
+{
+ GFC_COMPLEX_4 *pa;
+ GFC_COMPLEX_4 *pb;
+ GFC_COMPLEX_4 res;
+ GFC_COMPLEX_4 conjga;
+ index_type count;
+ index_type astride;
+ index_type bstride;
+
+ assert (GFC_DESCRIPTOR_RANK (a) == 1
+ && GFC_DESCRIPTOR_RANK (b) == 1);
+
+ if (a->dim[0].stride == 0)
+ a->dim[0].stride = 1;
+ if (b->dim[0].stride == 0)
+ b->dim[0].stride = 1;
+
+ astride = a->dim[0].stride;
+ bstride = b->dim[0].stride;
+ count = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ res = 0;
+ pa = a->data;
+ pb = b->data;
+
+ while (count--)
+ {
+ COMPLEX_ASSIGN(conjga, REALPART (*pa), -IMAGPART (*pa));
+ res += conjga * *pb;
+ pa += astride;
+ pb += bstride;
+ }
+
+ return res;
+}
+
diff --git a/libgfortran/generated/dotprod_c8.c b/libgfortran/generated/dotprod_c8.c
new file mode 100644
index 00000000000..fde18021400
--- /dev/null
+++ b/libgfortran/generated/dotprod_c8.c
@@ -0,0 +1,67 @@
+/* Implementation of the DOT_PRODUCT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+ and Feng Wang <fengwang@nudt.edu.cn>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+typedef GFC_ARRAY_DESCRIPTOR(GFC_MAX_DIMENSIONS, char) char_array;
+
+/* Both parameters will already have been converted to the result type. */
+GFC_COMPLEX_8
+__dot_product_c8 (gfc_array_c8 * a, gfc_array_c8 * b)
+{
+ GFC_COMPLEX_8 *pa;
+ GFC_COMPLEX_8 *pb;
+ GFC_COMPLEX_8 res;
+ GFC_COMPLEX_8 conjga;
+ index_type count;
+ index_type astride;
+ index_type bstride;
+
+ assert (GFC_DESCRIPTOR_RANK (a) == 1
+ && GFC_DESCRIPTOR_RANK (b) == 1);
+
+ if (a->dim[0].stride == 0)
+ a->dim[0].stride = 1;
+ if (b->dim[0].stride == 0)
+ b->dim[0].stride = 1;
+
+ astride = a->dim[0].stride;
+ bstride = b->dim[0].stride;
+ count = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ res = 0;
+ pa = a->data;
+ pb = b->data;
+
+ while (count--)
+ {
+ COMPLEX_ASSIGN(conjga, REALPART (*pa), -IMAGPART (*pa));
+ res += conjga * *pb;
+ pa += astride;
+ pb += bstride;
+ }
+
+ return res;
+}
+
diff --git a/libgfortran/generated/dotprod_i4.c b/libgfortran/generated/dotprod_i4.c
new file mode 100644
index 00000000000..374d9251300
--- /dev/null
+++ b/libgfortran/generated/dotprod_i4.c
@@ -0,0 +1,64 @@
+/* Implementation of the DOT_PRODUCT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+typedef GFC_ARRAY_DESCRIPTOR(GFC_MAX_DIMENSIONS, char) char_array;
+
+/* Both parameters will already have been converted to the result type. */
+GFC_INTEGER_4
+__dot_product_i4 (gfc_array_i4 * a, gfc_array_i4 * b)
+{
+ GFC_INTEGER_4 *pa;
+ GFC_INTEGER_4 *pb;
+ GFC_INTEGER_4 res;
+ index_type count;
+ index_type astride;
+ index_type bstride;
+
+ assert (GFC_DESCRIPTOR_RANK (a) == 1
+ && GFC_DESCRIPTOR_RANK (b) == 1);
+
+ if (a->dim[0].stride == 0)
+ a->dim[0].stride = 1;
+ if (b->dim[0].stride == 0)
+ b->dim[0].stride = 1;
+
+ astride = a->dim[0].stride;
+ bstride = b->dim[0].stride;
+ count = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ res = 0;
+ pa = a->data;
+ pb = b->data;
+
+ while (count--)
+ {
+ res += *pa * *pb;
+ pa += astride;
+ pb += bstride;
+ }
+
+ return res;
+}
+
diff --git a/libgfortran/generated/dotprod_i8.c b/libgfortran/generated/dotprod_i8.c
new file mode 100644
index 00000000000..6702a1d489c
--- /dev/null
+++ b/libgfortran/generated/dotprod_i8.c
@@ -0,0 +1,64 @@
+/* Implementation of the DOT_PRODUCT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+typedef GFC_ARRAY_DESCRIPTOR(GFC_MAX_DIMENSIONS, char) char_array;
+
+/* Both parameters will already have been converted to the result type. */
+GFC_INTEGER_8
+__dot_product_i8 (gfc_array_i8 * a, gfc_array_i8 * b)
+{
+ GFC_INTEGER_8 *pa;
+ GFC_INTEGER_8 *pb;
+ GFC_INTEGER_8 res;
+ index_type count;
+ index_type astride;
+ index_type bstride;
+
+ assert (GFC_DESCRIPTOR_RANK (a) == 1
+ && GFC_DESCRIPTOR_RANK (b) == 1);
+
+ if (a->dim[0].stride == 0)
+ a->dim[0].stride = 1;
+ if (b->dim[0].stride == 0)
+ b->dim[0].stride = 1;
+
+ astride = a->dim[0].stride;
+ bstride = b->dim[0].stride;
+ count = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ res = 0;
+ pa = a->data;
+ pb = b->data;
+
+ while (count--)
+ {
+ res += *pa * *pb;
+ pa += astride;
+ pb += bstride;
+ }
+
+ return res;
+}
+
diff --git a/libgfortran/generated/dotprod_l4.c b/libgfortran/generated/dotprod_l4.c
new file mode 100644
index 00000000000..292c0386cd1
--- /dev/null
+++ b/libgfortran/generated/dotprod_l4.c
@@ -0,0 +1,74 @@
+/* Implementation of the DOT_PRODUCT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+GFC_LOGICAL_4
+__dot_product_l4 (gfc_array_l4 * a, gfc_array_l4 * b)
+{
+ GFC_LOGICAL_4 *pa;
+ GFC_LOGICAL_4 *pb;
+ index_type count;
+ index_type astride;
+ index_type bstride;
+
+ assert (GFC_DESCRIPTOR_RANK (a) == 1
+ && GFC_DESCRIPTOR_RANK (b) == 1);
+
+ if (a->dim[0].stride == 0)
+ a->dim[0].stride = 1;
+ if (b->dim[0].stride == 0)
+ b->dim[0].stride = 1;
+
+ astride = a->dim[0].stride;
+ bstride = b->dim[0].stride;
+ count = a->dim[0].ubound + 1 - a->dim[0].lbound;
+
+ pa = a->data;
+ if (GFC_DESCRIPTOR_SIZE (a) != 4)
+ {
+ assert (GFC_DESCRIPTOR_SIZE (a) == 8);
+ pa = GFOR_POINTER_L8_TO_L4 (pa);
+ astride <<= 1;
+ }
+ pb = b->data;
+ if (GFC_DESCRIPTOR_SIZE (b) != 4)
+ {
+ assert (GFC_DESCRIPTOR_SIZE (b) == 8);
+ pb = GFOR_POINTER_L8_TO_L4 (pb);
+ bstride <<= 1;
+ }
+
+ while (count--)
+ {
+ if (*pa && *pb)
+ return 1;
+
+ pa += astride;
+ pb += bstride;
+ }
+
+ return 0;
+}
+
diff --git a/libgfortran/generated/dotprod_l8.c b/libgfortran/generated/dotprod_l8.c
new file mode 100644
index 00000000000..4316607a3e5
--- /dev/null
+++ b/libgfortran/generated/dotprod_l8.c
@@ -0,0 +1,74 @@
+/* Implementation of the DOT_PRODUCT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+GFC_LOGICAL_8
+__dot_product_l8 (gfc_array_l4 * a, gfc_array_l4 * b)
+{
+ GFC_LOGICAL_4 *pa;
+ GFC_LOGICAL_4 *pb;
+ index_type count;
+ index_type astride;
+ index_type bstride;
+
+ assert (GFC_DESCRIPTOR_RANK (a) == 1
+ && GFC_DESCRIPTOR_RANK (b) == 1);
+
+ if (a->dim[0].stride == 0)
+ a->dim[0].stride = 1;
+ if (b->dim[0].stride == 0)
+ b->dim[0].stride = 1;
+
+ astride = a->dim[0].stride;
+ bstride = b->dim[0].stride;
+ count = a->dim[0].ubound + 1 - a->dim[0].lbound;
+
+ pa = a->data;
+ if (GFC_DESCRIPTOR_SIZE (a) != 4)
+ {
+ assert (GFC_DESCRIPTOR_SIZE (a) == 8);
+ pa = GFOR_POINTER_L8_TO_L4 (pa);
+ astride <<= 1;
+ }
+ pb = b->data;
+ if (GFC_DESCRIPTOR_SIZE (b) != 4)
+ {
+ assert (GFC_DESCRIPTOR_SIZE (b) == 8);
+ pb = GFOR_POINTER_L8_TO_L4 (pb);
+ bstride <<= 1;
+ }
+
+ while (count--)
+ {
+ if (*pa && *pb)
+ return 1;
+
+ pa += astride;
+ pb += bstride;
+ }
+
+ return 0;
+}
+
diff --git a/libgfortran/generated/dotprod_r4.c b/libgfortran/generated/dotprod_r4.c
new file mode 100644
index 00000000000..1edfea36e6e
--- /dev/null
+++ b/libgfortran/generated/dotprod_r4.c
@@ -0,0 +1,64 @@
+/* Implementation of the DOT_PRODUCT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+typedef GFC_ARRAY_DESCRIPTOR(GFC_MAX_DIMENSIONS, char) char_array;
+
+/* Both parameters will already have been converted to the result type. */
+GFC_REAL_4
+__dot_product_r4 (gfc_array_r4 * a, gfc_array_r4 * b)
+{
+ GFC_REAL_4 *pa;
+ GFC_REAL_4 *pb;
+ GFC_REAL_4 res;
+ index_type count;
+ index_type astride;
+ index_type bstride;
+
+ assert (GFC_DESCRIPTOR_RANK (a) == 1
+ && GFC_DESCRIPTOR_RANK (b) == 1);
+
+ if (a->dim[0].stride == 0)
+ a->dim[0].stride = 1;
+ if (b->dim[0].stride == 0)
+ b->dim[0].stride = 1;
+
+ astride = a->dim[0].stride;
+ bstride = b->dim[0].stride;
+ count = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ res = 0;
+ pa = a->data;
+ pb = b->data;
+
+ while (count--)
+ {
+ res += *pa * *pb;
+ pa += astride;
+ pb += bstride;
+ }
+
+ return res;
+}
+
diff --git a/libgfortran/generated/dotprod_r8.c b/libgfortran/generated/dotprod_r8.c
new file mode 100644
index 00000000000..bf35710272b
--- /dev/null
+++ b/libgfortran/generated/dotprod_r8.c
@@ -0,0 +1,64 @@
+/* Implementation of the DOT_PRODUCT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+typedef GFC_ARRAY_DESCRIPTOR(GFC_MAX_DIMENSIONS, char) char_array;
+
+/* Both parameters will already have been converted to the result type. */
+GFC_REAL_8
+__dot_product_r8 (gfc_array_r8 * a, gfc_array_r8 * b)
+{
+ GFC_REAL_8 *pa;
+ GFC_REAL_8 *pb;
+ GFC_REAL_8 res;
+ index_type count;
+ index_type astride;
+ index_type bstride;
+
+ assert (GFC_DESCRIPTOR_RANK (a) == 1
+ && GFC_DESCRIPTOR_RANK (b) == 1);
+
+ if (a->dim[0].stride == 0)
+ a->dim[0].stride = 1;
+ if (b->dim[0].stride == 0)
+ b->dim[0].stride = 1;
+
+ astride = a->dim[0].stride;
+ bstride = b->dim[0].stride;
+ count = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ res = 0;
+ pa = a->data;
+ pb = b->data;
+
+ while (count--)
+ {
+ res += *pa * *pb;
+ pa += astride;
+ pb += bstride;
+ }
+
+ return res;
+}
+
diff --git a/libgfortran/generated/eoshift1_4.c b/libgfortran/generated/eoshift1_4.c
new file mode 100644
index 00000000000..05b1af682e0
--- /dev/null
+++ b/libgfortran/generated/eoshift1_4.c
@@ -0,0 +1,178 @@
+/* Implementation of the EOSHIFT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "libgfortran.h"
+
+static const char zeros[16] =
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+void
+__eoshift1_4 (const gfc_array_char * ret, const gfc_array_char * array,
+ const gfc_array_i4 * h, const char * pbound, const GFC_INTEGER_4 * pwhich)
+{
+ /* r.* indicates the return array. */
+ index_type rstride[GFC_MAX_DIMENSIONS - 1];
+ index_type rstride0;
+ index_type roffset;
+ char *rptr;
+ char *dest;
+ /* s.* indicates the source array. */
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride0;
+ index_type soffset;
+ const char *sptr;
+ const char *src;
+ /* h.* indicates the shift array. */
+ index_type hstride[GFC_MAX_DIMENSIONS - 1];
+ index_type hstride0;
+ const GFC_INTEGER_4 *hptr;
+
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type dim;
+ index_type size;
+ index_type len;
+ index_type n;
+ int which;
+ GFC_INTEGER_4 sh;
+ GFC_INTEGER_4 delta;
+
+ if (pwhich)
+ which = *pwhich - 1;
+ else
+ which = 0;
+
+ if (!pbound)
+ pbound = zeros;
+
+ size = GFC_DESCRIPTOR_SIZE (ret);
+
+ extent[0] = 1;
+ count[0] = 0;
+ size = GFC_DESCRIPTOR_SIZE (array);
+ n = 0;
+ for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
+ {
+ if (dim == which)
+ {
+ roffset = ret->dim[dim].stride * size;
+ if (roffset == 0)
+ roffset = size;
+ soffset = array->dim[dim].stride * size;
+ if (soffset == 0)
+ soffset = size;
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ }
+ else
+ {
+ count[n] = 0;
+ extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ rstride[n] = ret->dim[dim].stride * size;
+ sstride[n] = array->dim[dim].stride * size;
+
+ hstride[n] = h->dim[n].stride;
+ n++;
+ }
+ }
+ if (sstride[0] == 0)
+ sstride[0] = size;
+ if (rstride[0] == 0)
+ rstride[0] = size;
+ if (hstride[0] == 0)
+ hstride[0] = 1;
+
+ dim = GFC_DESCRIPTOR_RANK (array);
+ rstride0 = rstride[0];
+ sstride0 = sstride[0];
+ hstride0 = hstride[0];
+ rptr = ret->data;
+ sptr = array->data;
+ hptr = h->data;
+
+ while (rptr)
+ {
+ /* Do the shift for this dimension. */
+ sh = *hptr;
+ delta = (sh >= 0) ? sh: -sh;
+ if (sh > 0)
+ {
+ src = &sptr[delta * soffset];
+ dest = rptr;
+ }
+ else
+ {
+ src = sptr;
+ dest = &rptr[delta * roffset];
+ }
+ for (n = 0; n < len - delta; n++)
+ {
+ memcpy (dest, src, size);
+ dest += roffset;
+ src += soffset;
+ }
+ if (sh < 0)
+ dest = rptr;
+ n = delta;
+
+ while (n--)
+ {
+ memcpy (dest, pbound, size);
+ dest += roffset;
+ }
+
+ /* Advance to the next section. */
+ rptr += rstride0;
+ sptr += sstride0;
+ hptr += hstride0;
+ count[0]++;
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ rptr -= rstride[n] * extent[n];
+ sptr -= sstride[n] * extent[n];
+ hptr -= hstride[n] * extent[n];
+ n++;
+ if (n >= dim - 1)
+ {
+ /* Break out of the loop. */
+ rptr = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ rptr += rstride[n];
+ sptr += sstride[n];
+ hptr += hstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/eoshift1_8.c b/libgfortran/generated/eoshift1_8.c
new file mode 100644
index 00000000000..f74c022f178
--- /dev/null
+++ b/libgfortran/generated/eoshift1_8.c
@@ -0,0 +1,178 @@
+/* Implementation of the EOSHIFT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "libgfortran.h"
+
+static const char zeros[16] =
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+void
+__eoshift1_8 (const gfc_array_char * ret, const gfc_array_char * array,
+ const gfc_array_i8 * h, const char * pbound, const GFC_INTEGER_8 * pwhich)
+{
+ /* r.* indicates the return array. */
+ index_type rstride[GFC_MAX_DIMENSIONS - 1];
+ index_type rstride0;
+ index_type roffset;
+ char *rptr;
+ char *dest;
+ /* s.* indicates the source array. */
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride0;
+ index_type soffset;
+ const char *sptr;
+ const char *src;
+ /* h.* indicates the shift array. */
+ index_type hstride[GFC_MAX_DIMENSIONS - 1];
+ index_type hstride0;
+ const GFC_INTEGER_8 *hptr;
+
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type dim;
+ index_type size;
+ index_type len;
+ index_type n;
+ int which;
+ GFC_INTEGER_8 sh;
+ GFC_INTEGER_8 delta;
+
+ if (pwhich)
+ which = *pwhich - 1;
+ else
+ which = 0;
+
+ if (!pbound)
+ pbound = zeros;
+
+ size = GFC_DESCRIPTOR_SIZE (ret);
+
+ extent[0] = 1;
+ count[0] = 0;
+ size = GFC_DESCRIPTOR_SIZE (array);
+ n = 0;
+ for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
+ {
+ if (dim == which)
+ {
+ roffset = ret->dim[dim].stride * size;
+ if (roffset == 0)
+ roffset = size;
+ soffset = array->dim[dim].stride * size;
+ if (soffset == 0)
+ soffset = size;
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ }
+ else
+ {
+ count[n] = 0;
+ extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ rstride[n] = ret->dim[dim].stride * size;
+ sstride[n] = array->dim[dim].stride * size;
+
+ hstride[n] = h->dim[n].stride;
+ n++;
+ }
+ }
+ if (sstride[0] == 0)
+ sstride[0] = size;
+ if (rstride[0] == 0)
+ rstride[0] = size;
+ if (hstride[0] == 0)
+ hstride[0] = 1;
+
+ dim = GFC_DESCRIPTOR_RANK (array);
+ rstride0 = rstride[0];
+ sstride0 = sstride[0];
+ hstride0 = hstride[0];
+ rptr = ret->data;
+ sptr = array->data;
+ hptr = h->data;
+
+ while (rptr)
+ {
+ /* Do the shift for this dimension. */
+ sh = *hptr;
+ delta = (sh >= 0) ? sh: -sh;
+ if (sh > 0)
+ {
+ src = &sptr[delta * soffset];
+ dest = rptr;
+ }
+ else
+ {
+ src = sptr;
+ dest = &rptr[delta * roffset];
+ }
+ for (n = 0; n < len - delta; n++)
+ {
+ memcpy (dest, src, size);
+ dest += roffset;
+ src += soffset;
+ }
+ if (sh < 0)
+ dest = rptr;
+ n = delta;
+
+ while (n--)
+ {
+ memcpy (dest, pbound, size);
+ dest += roffset;
+ }
+
+ /* Advance to the next section. */
+ rptr += rstride0;
+ sptr += sstride0;
+ hptr += hstride0;
+ count[0]++;
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ rptr -= rstride[n] * extent[n];
+ sptr -= sstride[n] * extent[n];
+ hptr -= hstride[n] * extent[n];
+ n++;
+ if (n >= dim - 1)
+ {
+ /* Break out of the loop. */
+ rptr = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ rptr += rstride[n];
+ sptr += sstride[n];
+ hptr += hstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/eoshift3_4.c b/libgfortran/generated/eoshift3_4.c
new file mode 100644
index 00000000000..07c2d9e965e
--- /dev/null
+++ b/libgfortran/generated/eoshift3_4.c
@@ -0,0 +1,193 @@
+/* Implementation of the EOSHIFT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "libgfortran.h"
+
+static const char zeros[16] =
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+void
+__eoshift3_4 (gfc_array_char * ret, gfc_array_char * array,
+ gfc_array_i4 * h, const gfc_array_char * bound, GFC_INTEGER_4 * pwhich)
+{
+ /* r.* indicates the return array. */
+ index_type rstride[GFC_MAX_DIMENSIONS - 1];
+ index_type rstride0;
+ index_type roffset;
+ char *rptr;
+ char *dest;
+ /* s.* indicates the source array. */
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride0;
+ index_type soffset;
+ const char *sptr;
+ const char *src;
+ /* h.* indicates the shift array. */
+ index_type hstride[GFC_MAX_DIMENSIONS - 1];
+ index_type hstride0;
+ const GFC_INTEGER_4 *hptr;
+ /* b.* indicates the bound array. */
+ index_type bstride[GFC_MAX_DIMENSIONS - 1];
+ index_type bstride0;
+ const char *bptr;
+
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type dim;
+ index_type size;
+ index_type len;
+ index_type n;
+ int which;
+ GFC_INTEGER_4 sh;
+ GFC_INTEGER_4 delta;
+
+ if (pwhich)
+ which = *pwhich - 1;
+ else
+ which = 0;
+
+ size = GFC_DESCRIPTOR_SIZE (ret);
+
+ extent[0] = 1;
+ count[0] = 0;
+ size = GFC_DESCRIPTOR_SIZE (array);
+ n = 0;
+ for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
+ {
+ if (dim == which)
+ {
+ roffset = ret->dim[dim].stride * size;
+ if (roffset == 0)
+ roffset = size;
+ soffset = array->dim[dim].stride * size;
+ if (soffset == 0)
+ soffset = size;
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ }
+ else
+ {
+ count[n] = 0;
+ extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ rstride[n] = ret->dim[dim].stride * size;
+ sstride[n] = array->dim[dim].stride * size;
+
+ hstride[n] = h->dim[n].stride;
+ if (bound)
+ bstride[n] = bound->dim[n].stride;
+ else
+ bstride[n] = 0;
+ n++;
+ }
+ }
+ if (sstride[0] == 0)
+ sstride[0] = size;
+ if (rstride[0] == 0)
+ rstride[0] = size;
+ if (hstride[0] == 0)
+ hstride[0] = 1;
+ if (bound && bstride[0] == 0)
+ bstride[0] = size;
+
+ dim = GFC_DESCRIPTOR_RANK (array);
+ rstride0 = rstride[0];
+ sstride0 = sstride[0];
+ hstride0 = hstride[0];
+ bstride0 = bstride[0];
+ rptr = ret->data;
+ sptr = array->data;
+ hptr = h->data;
+ if (bound)
+ bptr = bound->data;
+ else
+ bptr = zeros;
+
+ while (rptr)
+ {
+ /* Do the shift for this dimension. */
+ sh = *hptr;
+ delta = (sh >= 0) ? sh: -sh;
+ if (sh > 0)
+ {
+ src = &sptr[delta * soffset];
+ dest = rptr;
+ }
+ else
+ {
+ src = sptr;
+ dest = &rptr[delta * roffset];
+ }
+ for (n = 0; n < len - delta; n++)
+ {
+ memcpy (dest, src, size);
+ dest += roffset;
+ src += soffset;
+ }
+ if (sh < 0)
+ dest = rptr;
+ n = delta;
+
+ while (n--)
+ {
+ memcpy (dest, bptr, size);
+ dest += roffset;
+ }
+
+ /* Advance to the next section. */
+ rptr += rstride0;
+ sptr += sstride0;
+ hptr += hstride0;
+ bptr += bstride0;
+ count[0]++;
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ rptr -= rstride[n] * extent[n];
+ sptr -= sstride[n] * extent[n];
+ hptr -= hstride[n] * extent[n];
+ bptr -= bstride[n] * extent[n];
+ n++;
+ if (n >= dim - 1)
+ {
+ /* Break out of the loop. */
+ rptr = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ rptr += rstride[n];
+ sptr += sstride[n];
+ hptr += hstride[n];
+ bptr += bstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/eoshift3_8.c b/libgfortran/generated/eoshift3_8.c
new file mode 100644
index 00000000000..fcb161df39a
--- /dev/null
+++ b/libgfortran/generated/eoshift3_8.c
@@ -0,0 +1,193 @@
+/* Implementation of the EOSHIFT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "libgfortran.h"
+
+static const char zeros[16] =
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+void
+__eoshift3_8 (gfc_array_char * ret, gfc_array_char * array,
+ gfc_array_i8 * h, const gfc_array_char * bound, GFC_INTEGER_8 * pwhich)
+{
+ /* r.* indicates the return array. */
+ index_type rstride[GFC_MAX_DIMENSIONS - 1];
+ index_type rstride0;
+ index_type roffset;
+ char *rptr;
+ char *dest;
+ /* s.* indicates the source array. */
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride0;
+ index_type soffset;
+ const char *sptr;
+ const char *src;
+ /* h.* indicates the shift array. */
+ index_type hstride[GFC_MAX_DIMENSIONS - 1];
+ index_type hstride0;
+ const GFC_INTEGER_8 *hptr;
+ /* b.* indicates the bound array. */
+ index_type bstride[GFC_MAX_DIMENSIONS - 1];
+ index_type bstride0;
+ const char *bptr;
+
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type dim;
+ index_type size;
+ index_type len;
+ index_type n;
+ int which;
+ GFC_INTEGER_8 sh;
+ GFC_INTEGER_8 delta;
+
+ if (pwhich)
+ which = *pwhich - 1;
+ else
+ which = 0;
+
+ size = GFC_DESCRIPTOR_SIZE (ret);
+
+ extent[0] = 1;
+ count[0] = 0;
+ size = GFC_DESCRIPTOR_SIZE (array);
+ n = 0;
+ for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
+ {
+ if (dim == which)
+ {
+ roffset = ret->dim[dim].stride * size;
+ if (roffset == 0)
+ roffset = size;
+ soffset = array->dim[dim].stride * size;
+ if (soffset == 0)
+ soffset = size;
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ }
+ else
+ {
+ count[n] = 0;
+ extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ rstride[n] = ret->dim[dim].stride * size;
+ sstride[n] = array->dim[dim].stride * size;
+
+ hstride[n] = h->dim[n].stride;
+ if (bound)
+ bstride[n] = bound->dim[n].stride;
+ else
+ bstride[n] = 0;
+ n++;
+ }
+ }
+ if (sstride[0] == 0)
+ sstride[0] = size;
+ if (rstride[0] == 0)
+ rstride[0] = size;
+ if (hstride[0] == 0)
+ hstride[0] = 1;
+ if (bound && bstride[0] == 0)
+ bstride[0] = size;
+
+ dim = GFC_DESCRIPTOR_RANK (array);
+ rstride0 = rstride[0];
+ sstride0 = sstride[0];
+ hstride0 = hstride[0];
+ bstride0 = bstride[0];
+ rptr = ret->data;
+ sptr = array->data;
+ hptr = h->data;
+ if (bound)
+ bptr = bound->data;
+ else
+ bptr = zeros;
+
+ while (rptr)
+ {
+ /* Do the shift for this dimension. */
+ sh = *hptr;
+ delta = (sh >= 0) ? sh: -sh;
+ if (sh > 0)
+ {
+ src = &sptr[delta * soffset];
+ dest = rptr;
+ }
+ else
+ {
+ src = sptr;
+ dest = &rptr[delta * roffset];
+ }
+ for (n = 0; n < len - delta; n++)
+ {
+ memcpy (dest, src, size);
+ dest += roffset;
+ src += soffset;
+ }
+ if (sh < 0)
+ dest = rptr;
+ n = delta;
+
+ while (n--)
+ {
+ memcpy (dest, bptr, size);
+ dest += roffset;
+ }
+
+ /* Advance to the next section. */
+ rptr += rstride0;
+ sptr += sstride0;
+ hptr += hstride0;
+ bptr += bstride0;
+ count[0]++;
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ rptr -= rstride[n] * extent[n];
+ sptr -= sstride[n] * extent[n];
+ hptr -= hstride[n] * extent[n];
+ bptr -= bstride[n] * extent[n];
+ n++;
+ if (n >= dim - 1)
+ {
+ /* Break out of the loop. */
+ rptr = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ rptr += rstride[n];
+ sptr += sstride[n];
+ hptr += hstride[n];
+ bptr += bstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/exp_c4.c b/libgfortran/generated/exp_c4.c
new file mode 100644
index 00000000000..d95213446ee
--- /dev/null
+++ b/libgfortran/generated/exp_c4.c
@@ -0,0 +1,139 @@
+/* Complex exponential functions
+ Copyright 2002, 2004 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include <math.h>
+#include "libgfortran.h"
+
+
+/* z = a + ib */
+/* Absolute value. */
+GFC_REAL_4
+cabsf (GFC_COMPLEX_4 z)
+{
+ return hypotf (REALPART (z), IMAGPART (z));
+}
+
+/* Complex argument. The angle made with the +ve real axis. Range 0-2pi. */
+GFC_REAL_4
+cargf (GFC_COMPLEX_4 z)
+{
+ GFC_REAL_4 arg;
+
+ arg = atan2f (IMAGPART (z), REALPART (z));
+ if (arg < 0)
+ return arg + 2 * M_PI;
+ else
+ return arg;
+}
+
+/* exp(z) = exp(a)*(cos(b) + isin(b)) */
+GFC_COMPLEX_4
+cexpf (GFC_COMPLEX_4 z)
+{
+ GFC_REAL_4 a;
+ GFC_REAL_4 b;
+ GFC_COMPLEX_4 v;
+
+ a = REALPART (z);
+ b = IMAGPART (z);
+ COMPLEX_ASSIGN (v, cosf (b), sinf (b));
+ return expf (a) * v;
+}
+
+/* log(z) = log (cabs(z)) + i*carg(z) */
+GFC_COMPLEX_4
+clogf (GFC_COMPLEX_4 z)
+{
+ GFC_COMPLEX_4 v;
+
+ COMPLEX_ASSIGN (v, logf (cabsf (z)), cargf (z));
+ return v;
+}
+
+/* log10(z) = log10 (cabs(z)) + i*carg(z) */
+GFC_COMPLEX_4
+clog10f (GFC_COMPLEX_4 z)
+{
+ GFC_COMPLEX_4 v;
+
+ COMPLEX_ASSIGN (v, log10f (cabsf (z)), cargf (z));
+ return v;
+}
+
+/* pow(base, power) = cexp (power * clog (base)) */
+GFC_COMPLEX_4
+cpowf (GFC_COMPLEX_4 base, GFC_COMPLEX_4 power)
+{
+ return cexpf (power * clogf (base));
+}
+
+/* sqrt(z). Algorithm pulled from glibc. */
+GFC_COMPLEX_4
+csqrtf (GFC_COMPLEX_4 z)
+{
+ GFC_REAL_4 re;
+ GFC_REAL_4 im;
+ GFC_COMPLEX_4 v;
+
+ re = REALPART (z);
+ im = IMAGPART (z);
+ if (im == 0.0)
+ {
+ if (re < 0.0)
+ {
+ COMPLEX_ASSIGN (v, 0.0, copysignf (sqrtf (-re), im));
+ }
+ else
+ {
+ COMPLEX_ASSIGN (v, fabsf (sqrt (re)),
+ copysignf (0.0, im));
+ }
+ }
+ else if (re == 0.0)
+ {
+ GFC_REAL_4 r;
+
+ r = sqrtf (0.5 * fabs (im));
+
+ COMPLEX_ASSIGN (v, copysignf (r, im), r);
+ }
+ else
+ {
+ GFC_REAL_4 d, r, s;
+
+ d = hypotf (re, im);
+ /* Use the identity 2 Re res Im res = Im x
+ to avoid cancellation error in d +/- Re x. */
+ if (re > 0)
+ {
+ r = sqrtf (0.5 * d + 0.5 * re);
+ s = (0.5 * im) / r;
+ }
+ else
+ {
+ s = sqrtf (0.5 * d - 0.5 * re);
+ r = fabsf ((0.5 * im) / s);
+ }
+
+ COMPLEX_ASSIGN (v, r, copysignf (s, im));
+ }
+ return v;
+}
+
diff --git a/libgfortran/generated/exp_c8.c b/libgfortran/generated/exp_c8.c
new file mode 100644
index 00000000000..74cbbdc5145
--- /dev/null
+++ b/libgfortran/generated/exp_c8.c
@@ -0,0 +1,139 @@
+/* Complex exponential functions
+ Copyright 2002, 2004 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include <math.h>
+#include "libgfortran.h"
+
+
+/* z = a + ib */
+/* Absolute value. */
+GFC_REAL_8
+cabs (GFC_COMPLEX_8 z)
+{
+ return hypot (REALPART (z), IMAGPART (z));
+}
+
+/* Complex argument. The angle made with the +ve real axis. Range 0-2pi. */
+GFC_REAL_8
+carg (GFC_COMPLEX_8 z)
+{
+ GFC_REAL_8 arg;
+
+ arg = atan2 (IMAGPART (z), REALPART (z));
+ if (arg < 0)
+ return arg + 2 * M_PI;
+ else
+ return arg;
+}
+
+/* exp(z) = exp(a)*(cos(b) + isin(b)) */
+GFC_COMPLEX_8
+cexp (GFC_COMPLEX_8 z)
+{
+ GFC_REAL_8 a;
+ GFC_REAL_8 b;
+ GFC_COMPLEX_8 v;
+
+ a = REALPART (z);
+ b = IMAGPART (z);
+ COMPLEX_ASSIGN (v, cos (b), sin (b));
+ return exp (a) * v;
+}
+
+/* log(z) = log (cabs(z)) + i*carg(z) */
+GFC_COMPLEX_8
+clog (GFC_COMPLEX_8 z)
+{
+ GFC_COMPLEX_8 v;
+
+ COMPLEX_ASSIGN (v, log (cabs (z)), carg (z));
+ return v;
+}
+
+/* log10(z) = log10 (cabs(z)) + i*carg(z) */
+GFC_COMPLEX_8
+clog10 (GFC_COMPLEX_8 z)
+{
+ GFC_COMPLEX_8 v;
+
+ COMPLEX_ASSIGN (v, log10 (cabs (z)), carg (z));
+ return v;
+}
+
+/* pow(base, power) = cexp (power * clog (base)) */
+GFC_COMPLEX_8
+cpow (GFC_COMPLEX_8 base, GFC_COMPLEX_8 power)
+{
+ return cexp (power * clog (base));
+}
+
+/* sqrt(z). Algorithm pulled from glibc. */
+GFC_COMPLEX_8
+csqrt (GFC_COMPLEX_8 z)
+{
+ GFC_REAL_8 re;
+ GFC_REAL_8 im;
+ GFC_COMPLEX_8 v;
+
+ re = REALPART (z);
+ im = IMAGPART (z);
+ if (im == 0.0)
+ {
+ if (re < 0.0)
+ {
+ COMPLEX_ASSIGN (v, 0.0, copysign (sqrt (-re), im));
+ }
+ else
+ {
+ COMPLEX_ASSIGN (v, fabs (sqrt (re)),
+ copysign (0.0, im));
+ }
+ }
+ else if (re == 0.0)
+ {
+ GFC_REAL_8 r;
+
+ r = sqrt (0.5 * fabs (im));
+
+ COMPLEX_ASSIGN (v, copysign (r, im), r);
+ }
+ else
+ {
+ GFC_REAL_8 d, r, s;
+
+ d = hypot (re, im);
+ /* Use the identity 2 Re res Im res = Im x
+ to avoid cancellation error in d +/- Re x. */
+ if (re > 0)
+ {
+ r = sqrt (0.5 * d + 0.5 * re);
+ s = (0.5 * im) / r;
+ }
+ else
+ {
+ s = sqrt (0.5 * d - 0.5 * re);
+ r = fabs ((0.5 * im) / s);
+ }
+
+ COMPLEX_ASSIGN (v, r, copysign (s, im));
+ }
+ return v;
+}
+
diff --git a/libgfortran/generated/exponent_r4.c b/libgfortran/generated/exponent_r4.c
new file mode 100644
index 00000000000..34e76b65edb
--- /dev/null
+++ b/libgfortran/generated/exponent_r4.c
@@ -0,0 +1,31 @@
+/* Implementation of the EXPONENT intrinsic
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@redhat.com>.
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include <math.h>
+#include "libgfortran.h"
+
+
+GFC_INTEGER_4
+prefix(exponent_r4) (GFC_REAL_4 s)
+{
+ int ret;
+ frexpf (s, &ret);
+ return ret;
+}
diff --git a/libgfortran/generated/exponent_r8.c b/libgfortran/generated/exponent_r8.c
new file mode 100644
index 00000000000..8a4101efd66
--- /dev/null
+++ b/libgfortran/generated/exponent_r8.c
@@ -0,0 +1,31 @@
+/* Implementation of the EXPONENT intrinsic
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@redhat.com>.
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include <math.h>
+#include "libgfortran.h"
+
+
+GFC_INTEGER_4
+prefix(exponent_r8) (GFC_REAL_8 s)
+{
+ int ret;
+ frexp (s, &ret);
+ return ret;
+}
diff --git a/libgfortran/generated/fraction_r4.c b/libgfortran/generated/fraction_r4.c
new file mode 100644
index 00000000000..a86e8292c71
--- /dev/null
+++ b/libgfortran/generated/fraction_r4.c
@@ -0,0 +1,30 @@
+/* Implementation of the FRACTION intrinsic
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@redhat.com>.
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include <math.h>
+#include "libgfortran.h"
+
+
+GFC_REAL_4
+prefix(fraction_r4) (GFC_REAL_4 s)
+{
+ int dummy_exp;
+ return frexpf (s, &dummy_exp);
+}
diff --git a/libgfortran/generated/fraction_r8.c b/libgfortran/generated/fraction_r8.c
new file mode 100644
index 00000000000..613c6ac702c
--- /dev/null
+++ b/libgfortran/generated/fraction_r8.c
@@ -0,0 +1,30 @@
+/* Implementation of the FRACTION intrinsic
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@redhat.com>.
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include <math.h>
+#include "libgfortran.h"
+
+
+GFC_REAL_8
+prefix(fraction_r8) (GFC_REAL_8 s)
+{
+ int dummy_exp;
+ return frexp (s, &dummy_exp);
+}
diff --git a/libgfortran/generated/hyp_c4.c b/libgfortran/generated/hyp_c4.c
new file mode 100644
index 00000000000..ac6c1e03131
--- /dev/null
+++ b/libgfortran/generated/hyp_c4.c
@@ -0,0 +1,71 @@
+/* Complex hyperbolic functions
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include <math.h>
+#include "libgfortran.h"
+
+
+/* Complex number z = a + ib. */
+
+/* sinh(z) = sinh(a)cos(b) + icosh(a)sin(b) */
+GFC_COMPLEX_4
+csinhf (GFC_COMPLEX_4 a)
+{
+ GFC_REAL_4 r;
+ GFC_REAL_4 i;
+ GFC_COMPLEX_4 v;
+
+ r = REALPART (a);
+ i = IMAGPART (a);
+ COMPLEX_ASSIGN (v, sinhf (r) * cosf (i), coshf (r) * sinf (i));
+ return v;
+}
+
+/* cosh(z) = cosh(a)cos(b) - isinh(a)sin(b) */
+GFC_COMPLEX_4
+ccoshf (GFC_COMPLEX_4 a)
+{
+ GFC_REAL_4 r;
+ GFC_REAL_4 i;
+ GFC_COMPLEX_4 v;
+
+ r = REALPART (a);
+ i = IMAGPART (a);
+ COMPLEX_ASSIGN (v, coshf (r) * cosf (i), - (sinhf (r) * sinf (i)));
+ return v;
+}
+
+/* tanh(z) = (tanh(a) + itan(b)) / (1 - itanh(a)tan(b)) */
+GFC_COMPLEX_4
+ctanhf (GFC_COMPLEX_4 a)
+{
+ GFC_REAL_4 rt;
+ GFC_REAL_4 it;
+ GFC_COMPLEX_4 n;
+ GFC_COMPLEX_4 d;
+
+ rt = tanhf (REALPART (a));
+ it = tanf (IMAGPART (a));
+ COMPLEX_ASSIGN (n, rt, it);
+ COMPLEX_ASSIGN (d, 1, - (rt * it));
+
+ return n / d;
+}
+
diff --git a/libgfortran/generated/hyp_c8.c b/libgfortran/generated/hyp_c8.c
new file mode 100644
index 00000000000..b3793054941
--- /dev/null
+++ b/libgfortran/generated/hyp_c8.c
@@ -0,0 +1,71 @@
+/* Complex hyperbolic functions
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include <math.h>
+#include "libgfortran.h"
+
+
+/* Complex number z = a + ib. */
+
+/* sinh(z) = sinh(a)cos(b) + icosh(a)sin(b) */
+GFC_COMPLEX_8
+csinh (GFC_COMPLEX_8 a)
+{
+ GFC_REAL_8 r;
+ GFC_REAL_8 i;
+ GFC_COMPLEX_8 v;
+
+ r = REALPART (a);
+ i = IMAGPART (a);
+ COMPLEX_ASSIGN (v, sinh (r) * cos (i), cosh (r) * sin (i));
+ return v;
+}
+
+/* cosh(z) = cosh(a)cos(b) - isinh(a)sin(b) */
+GFC_COMPLEX_8
+ccosh (GFC_COMPLEX_8 a)
+{
+ GFC_REAL_8 r;
+ GFC_REAL_8 i;
+ GFC_COMPLEX_8 v;
+
+ r = REALPART (a);
+ i = IMAGPART (a);
+ COMPLEX_ASSIGN (v, cosh (r) * cos (i), - (sinh (r) * sin (i)));
+ return v;
+}
+
+/* tanh(z) = (tanh(a) + itan(b)) / (1 - itanh(a)tan(b)) */
+GFC_COMPLEX_8
+ctanh (GFC_COMPLEX_8 a)
+{
+ GFC_REAL_8 rt;
+ GFC_REAL_8 it;
+ GFC_COMPLEX_8 n;
+ GFC_COMPLEX_8 d;
+
+ rt = tanh (REALPART (a));
+ it = tan (IMAGPART (a));
+ COMPLEX_ASSIGN (n, rt, it);
+ COMPLEX_ASSIGN (d, 1, - (rt * it));
+
+ return n / d;
+}
+
diff --git a/libgfortran/generated/in_pack_i4.c b/libgfortran/generated/in_pack_i4.c
new file mode 100644
index 00000000000..f11295718fc
--- /dev/null
+++ b/libgfortran/generated/in_pack_i4.c
@@ -0,0 +1,115 @@
+/* Helper function for repacking arrays.
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfortran; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+
+/* Allocates a block of memory with internal_malloc if the array needs
+ repacking. */
+
+GFC_INTEGER_4 *
+internal_pack_4 (gfc_array_i4 * source)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type stride[GFC_MAX_DIMENSIONS - 1];
+ index_type stride0;
+ index_type dim;
+ index_type ssize;
+ const GFC_INTEGER_4 *src;
+ GFC_INTEGER_4 *dest;
+ GFC_INTEGER_4 *destptr;
+ int n;
+ int packed;
+
+ if (source->dim[0].stride == 0)
+ {
+ source->dim[0].stride = 1;
+ return source->data;
+ }
+
+ dim = GFC_DESCRIPTOR_RANK (source);
+ ssize = 1;
+ packed = 1;
+ for (n = 0; n < dim; n++)
+ {
+ count[n] = 0;
+ stride[n] = source->dim[n].stride;
+ extent[n] = source->dim[n].ubound + 1 - source->dim[n].lbound;
+ if (extent[n] <= 0)
+ {
+ /* Do nothing. */
+ packed = 1;
+ break;
+ }
+
+ if (ssize != stride[n])
+ packed = 0;
+
+ ssize *= extent[n];
+ }
+
+ if (packed)
+ return source->data;
+
+ /* Allocate storage for the destination. */
+ destptr = (GFC_INTEGER_4 *)internal_malloc_size (ssize * 4);
+ dest = destptr;
+ src = source->data;
+ stride0 = stride[0];
+
+
+ while (src)
+ {
+ /* Copy the data. */
+ *(dest++) = *src;
+ /* Advance to the next element. */
+ src += stride0;
+ count[0]++;
+ /* Advance to the next source element. */
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ src -= stride[n] * extent[n];
+ n++;
+ if (n == dim)
+ {
+ src = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ src += stride[n];
+ }
+ }
+ }
+ return destptr;
+}
+
diff --git a/libgfortran/generated/in_pack_i8.c b/libgfortran/generated/in_pack_i8.c
new file mode 100644
index 00000000000..82609272e4a
--- /dev/null
+++ b/libgfortran/generated/in_pack_i8.c
@@ -0,0 +1,115 @@
+/* Helper function for repacking arrays.
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfortran; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+
+/* Allocates a block of memory with internal_malloc if the array needs
+ repacking. */
+
+GFC_INTEGER_8 *
+internal_pack_8 (gfc_array_i8 * source)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type stride[GFC_MAX_DIMENSIONS - 1];
+ index_type stride0;
+ index_type dim;
+ index_type ssize;
+ const GFC_INTEGER_8 *src;
+ GFC_INTEGER_8 *dest;
+ GFC_INTEGER_8 *destptr;
+ int n;
+ int packed;
+
+ if (source->dim[0].stride == 0)
+ {
+ source->dim[0].stride = 1;
+ return source->data;
+ }
+
+ dim = GFC_DESCRIPTOR_RANK (source);
+ ssize = 1;
+ packed = 1;
+ for (n = 0; n < dim; n++)
+ {
+ count[n] = 0;
+ stride[n] = source->dim[n].stride;
+ extent[n] = source->dim[n].ubound + 1 - source->dim[n].lbound;
+ if (extent[n] <= 0)
+ {
+ /* Do nothing. */
+ packed = 1;
+ break;
+ }
+
+ if (ssize != stride[n])
+ packed = 0;
+
+ ssize *= extent[n];
+ }
+
+ if (packed)
+ return source->data;
+
+ /* Allocate storage for the destination. */
+ destptr = (GFC_INTEGER_8 *)internal_malloc_size (ssize * 8);
+ dest = destptr;
+ src = source->data;
+ stride0 = stride[0];
+
+
+ while (src)
+ {
+ /* Copy the data. */
+ *(dest++) = *src;
+ /* Advance to the next element. */
+ src += stride0;
+ count[0]++;
+ /* Advance to the next source element. */
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ src -= stride[n] * extent[n];
+ n++;
+ if (n == dim)
+ {
+ src = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ src += stride[n];
+ }
+ }
+ }
+ return destptr;
+}
+
diff --git a/libgfortran/generated/in_unpack_i4.c b/libgfortran/generated/in_unpack_i4.c
new file mode 100644
index 00000000000..b0b7e7bc06d
--- /dev/null
+++ b/libgfortran/generated/in_unpack_i4.c
@@ -0,0 +1,102 @@
+/* Helper function for repacking arrays.
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "libgfortran.h"
+
+void
+internal_unpack_4 (gfc_array_i4 * d, const GFC_INTEGER_4 * src)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type stride[GFC_MAX_DIMENSIONS - 1];
+ index_type stride0;
+ index_type dim;
+ index_type dsize;
+ GFC_INTEGER_4 *dest;
+ int n;
+
+ dest = d->data;
+ if (src == dest || !src)
+ return;
+
+ if (d->dim[0].stride == 0)
+ d->dim[0].stride = 1;
+
+ dim = GFC_DESCRIPTOR_RANK (d);
+ dsize = 1;
+ for (n = 0; n < dim; n++)
+ {
+ count[n] = 0;
+ stride[n] = d->dim[n].stride;
+ extent[n] = d->dim[n].ubound + 1 - d->dim[n].lbound;
+ if (extent[n] <= 0)
+ abort ();
+
+ if (dsize == stride[n])
+ dsize *= extent[n];
+ else
+ dsize = 0;
+ }
+
+ if (dsize != 0)
+ {
+ memcpy (dest, src, dsize * 4);
+ return;
+ }
+
+ stride0 = stride[0];
+
+ while (dest)
+ {
+ /* Copy the data. */
+ *dest = *(src++);
+ /* Advance to the next element. */
+ dest += stride0;
+ count[0]++;
+ /* Advance to the next source element. */
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ dest -= stride[n] * extent[n];
+ n++;
+ if (n == dim)
+ {
+ dest = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ dest += stride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/in_unpack_i8.c b/libgfortran/generated/in_unpack_i8.c
new file mode 100644
index 00000000000..962c05b6caa
--- /dev/null
+++ b/libgfortran/generated/in_unpack_i8.c
@@ -0,0 +1,102 @@
+/* Helper function for repacking arrays.
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "libgfortran.h"
+
+void
+internal_unpack_8 (gfc_array_i8 * d, const GFC_INTEGER_8 * src)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type stride[GFC_MAX_DIMENSIONS - 1];
+ index_type stride0;
+ index_type dim;
+ index_type dsize;
+ GFC_INTEGER_8 *dest;
+ int n;
+
+ dest = d->data;
+ if (src == dest || !src)
+ return;
+
+ if (d->dim[0].stride == 0)
+ d->dim[0].stride = 1;
+
+ dim = GFC_DESCRIPTOR_RANK (d);
+ dsize = 1;
+ for (n = 0; n < dim; n++)
+ {
+ count[n] = 0;
+ stride[n] = d->dim[n].stride;
+ extent[n] = d->dim[n].ubound + 1 - d->dim[n].lbound;
+ if (extent[n] <= 0)
+ abort ();
+
+ if (dsize == stride[n])
+ dsize *= extent[n];
+ else
+ dsize = 0;
+ }
+
+ if (dsize != 0)
+ {
+ memcpy (dest, src, dsize * 8);
+ return;
+ }
+
+ stride0 = stride[0];
+
+ while (dest)
+ {
+ /* Copy the data. */
+ *dest = *(src++);
+ /* Advance to the next element. */
+ dest += stride0;
+ count[0]++;
+ /* Advance to the next source element. */
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ dest -= stride[n] * extent[n];
+ n++;
+ if (n == dim)
+ {
+ dest = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ dest += stride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/matmul_c4.c b/libgfortran/generated/matmul_c4.c
new file mode 100644
index 00000000000..beb4453024e
--- /dev/null
+++ b/libgfortran/generated/matmul_c4.c
@@ -0,0 +1,138 @@
+/* Implementation of the MATMUL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+/* Dimensions: retarray(x,y) a(x, count) b(count,y).
+ Either a or b can be rank 1. In this case x or y is 1. */
+void
+__matmul_c4 (gfc_array_c4 * retarray, gfc_array_c4 * a, gfc_array_c4 * b)
+{
+ GFC_COMPLEX_4 *abase;
+ GFC_COMPLEX_4 *bbase;
+ GFC_COMPLEX_4 *dest;
+ GFC_COMPLEX_4 res;
+ index_type rxstride;
+ index_type rystride;
+ index_type xcount;
+ index_type ycount;
+ index_type xstride;
+ index_type ystride;
+ index_type x;
+ index_type y;
+
+ GFC_COMPLEX_4 *pa;
+ GFC_COMPLEX_4 *pb;
+ index_type astride;
+ index_type bstride;
+ index_type count;
+ index_type n;
+
+ assert (GFC_DESCRIPTOR_RANK (a) == 2
+ || GFC_DESCRIPTOR_RANK (b) == 2);
+ abase = a->data;
+ bbase = b->data;
+ dest = retarray->data;
+
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (a->dim[0].stride == 0)
+ a->dim[0].stride = 1;
+ if (b->dim[0].stride == 0)
+ b->dim[0].stride = 1;
+
+
+ if (GFC_DESCRIPTOR_RANK (retarray) == 1)
+ {
+ rxstride = retarray->dim[0].stride;
+ rystride = rxstride;
+ }
+ else
+ {
+ rxstride = retarray->dim[0].stride;
+ rystride = retarray->dim[1].stride;
+ }
+
+ /* If we have rank 1 parameters, zero the absent stride, and set the size to
+ one. */
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ astride = a->dim[0].stride;
+ count = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ xstride = 0;
+ rxstride = 0;
+ xcount = 1;
+ }
+ else
+ {
+ astride = a->dim[1].stride;
+ count = a->dim[1].ubound + 1 - a->dim[1].lbound;
+ xstride = a->dim[0].stride;
+ xcount = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ }
+ if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ bstride = b->dim[0].stride;
+ assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound);
+ ystride = 0;
+ rystride = 0;
+ ycount = 1;
+ }
+ else
+ {
+ bstride = b->dim[0].stride;
+ assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound);
+ ystride = b->dim[1].stride;
+ ycount = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ }
+
+ for (y = 0; y < ycount; y++)
+ {
+ for (x = 0; x < xcount; x++)
+ {
+ /* Do the summation for this element. For real and integer types
+ this is the same as DOT_PRODUCT. For complex types we use do
+ a*b, not conjg(a)*b. */
+ pa = abase;
+ pb = bbase;
+ res = 0;
+
+ for (n = 0; n < count; n++)
+ {
+ res += *pa * *pb;
+ pa += astride;
+ pb += bstride;
+ }
+
+ *dest = res;
+
+ dest += rxstride;
+ abase += xstride;
+ }
+ abase -= xstride * xcount;
+ bbase += ystride;
+ dest += rystride - (rxstride * xcount);
+ }
+}
+
diff --git a/libgfortran/generated/matmul_c8.c b/libgfortran/generated/matmul_c8.c
new file mode 100644
index 00000000000..a306764d4b9
--- /dev/null
+++ b/libgfortran/generated/matmul_c8.c
@@ -0,0 +1,138 @@
+/* Implementation of the MATMUL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+/* Dimensions: retarray(x,y) a(x, count) b(count,y).
+ Either a or b can be rank 1. In this case x or y is 1. */
+void
+__matmul_c8 (gfc_array_c8 * retarray, gfc_array_c8 * a, gfc_array_c8 * b)
+{
+ GFC_COMPLEX_8 *abase;
+ GFC_COMPLEX_8 *bbase;
+ GFC_COMPLEX_8 *dest;
+ GFC_COMPLEX_8 res;
+ index_type rxstride;
+ index_type rystride;
+ index_type xcount;
+ index_type ycount;
+ index_type xstride;
+ index_type ystride;
+ index_type x;
+ index_type y;
+
+ GFC_COMPLEX_8 *pa;
+ GFC_COMPLEX_8 *pb;
+ index_type astride;
+ index_type bstride;
+ index_type count;
+ index_type n;
+
+ assert (GFC_DESCRIPTOR_RANK (a) == 2
+ || GFC_DESCRIPTOR_RANK (b) == 2);
+ abase = a->data;
+ bbase = b->data;
+ dest = retarray->data;
+
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (a->dim[0].stride == 0)
+ a->dim[0].stride = 1;
+ if (b->dim[0].stride == 0)
+ b->dim[0].stride = 1;
+
+
+ if (GFC_DESCRIPTOR_RANK (retarray) == 1)
+ {
+ rxstride = retarray->dim[0].stride;
+ rystride = rxstride;
+ }
+ else
+ {
+ rxstride = retarray->dim[0].stride;
+ rystride = retarray->dim[1].stride;
+ }
+
+ /* If we have rank 1 parameters, zero the absent stride, and set the size to
+ one. */
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ astride = a->dim[0].stride;
+ count = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ xstride = 0;
+ rxstride = 0;
+ xcount = 1;
+ }
+ else
+ {
+ astride = a->dim[1].stride;
+ count = a->dim[1].ubound + 1 - a->dim[1].lbound;
+ xstride = a->dim[0].stride;
+ xcount = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ }
+ if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ bstride = b->dim[0].stride;
+ assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound);
+ ystride = 0;
+ rystride = 0;
+ ycount = 1;
+ }
+ else
+ {
+ bstride = b->dim[0].stride;
+ assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound);
+ ystride = b->dim[1].stride;
+ ycount = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ }
+
+ for (y = 0; y < ycount; y++)
+ {
+ for (x = 0; x < xcount; x++)
+ {
+ /* Do the summation for this element. For real and integer types
+ this is the same as DOT_PRODUCT. For complex types we use do
+ a*b, not conjg(a)*b. */
+ pa = abase;
+ pb = bbase;
+ res = 0;
+
+ for (n = 0; n < count; n++)
+ {
+ res += *pa * *pb;
+ pa += astride;
+ pb += bstride;
+ }
+
+ *dest = res;
+
+ dest += rxstride;
+ abase += xstride;
+ }
+ abase -= xstride * xcount;
+ bbase += ystride;
+ dest += rystride - (rxstride * xcount);
+ }
+}
+
diff --git a/libgfortran/generated/matmul_i4.c b/libgfortran/generated/matmul_i4.c
new file mode 100644
index 00000000000..44b30a4e140
--- /dev/null
+++ b/libgfortran/generated/matmul_i4.c
@@ -0,0 +1,138 @@
+/* Implementation of the MATMUL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+/* Dimensions: retarray(x,y) a(x, count) b(count,y).
+ Either a or b can be rank 1. In this case x or y is 1. */
+void
+__matmul_i4 (gfc_array_i4 * retarray, gfc_array_i4 * a, gfc_array_i4 * b)
+{
+ GFC_INTEGER_4 *abase;
+ GFC_INTEGER_4 *bbase;
+ GFC_INTEGER_4 *dest;
+ GFC_INTEGER_4 res;
+ index_type rxstride;
+ index_type rystride;
+ index_type xcount;
+ index_type ycount;
+ index_type xstride;
+ index_type ystride;
+ index_type x;
+ index_type y;
+
+ GFC_INTEGER_4 *pa;
+ GFC_INTEGER_4 *pb;
+ index_type astride;
+ index_type bstride;
+ index_type count;
+ index_type n;
+
+ assert (GFC_DESCRIPTOR_RANK (a) == 2
+ || GFC_DESCRIPTOR_RANK (b) == 2);
+ abase = a->data;
+ bbase = b->data;
+ dest = retarray->data;
+
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (a->dim[0].stride == 0)
+ a->dim[0].stride = 1;
+ if (b->dim[0].stride == 0)
+ b->dim[0].stride = 1;
+
+
+ if (GFC_DESCRIPTOR_RANK (retarray) == 1)
+ {
+ rxstride = retarray->dim[0].stride;
+ rystride = rxstride;
+ }
+ else
+ {
+ rxstride = retarray->dim[0].stride;
+ rystride = retarray->dim[1].stride;
+ }
+
+ /* If we have rank 1 parameters, zero the absent stride, and set the size to
+ one. */
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ astride = a->dim[0].stride;
+ count = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ xstride = 0;
+ rxstride = 0;
+ xcount = 1;
+ }
+ else
+ {
+ astride = a->dim[1].stride;
+ count = a->dim[1].ubound + 1 - a->dim[1].lbound;
+ xstride = a->dim[0].stride;
+ xcount = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ }
+ if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ bstride = b->dim[0].stride;
+ assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound);
+ ystride = 0;
+ rystride = 0;
+ ycount = 1;
+ }
+ else
+ {
+ bstride = b->dim[0].stride;
+ assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound);
+ ystride = b->dim[1].stride;
+ ycount = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ }
+
+ for (y = 0; y < ycount; y++)
+ {
+ for (x = 0; x < xcount; x++)
+ {
+ /* Do the summation for this element. For real and integer types
+ this is the same as DOT_PRODUCT. For complex types we use do
+ a*b, not conjg(a)*b. */
+ pa = abase;
+ pb = bbase;
+ res = 0;
+
+ for (n = 0; n < count; n++)
+ {
+ res += *pa * *pb;
+ pa += astride;
+ pb += bstride;
+ }
+
+ *dest = res;
+
+ dest += rxstride;
+ abase += xstride;
+ }
+ abase -= xstride * xcount;
+ bbase += ystride;
+ dest += rystride - (rxstride * xcount);
+ }
+}
+
diff --git a/libgfortran/generated/matmul_i8.c b/libgfortran/generated/matmul_i8.c
new file mode 100644
index 00000000000..1ca78276478
--- /dev/null
+++ b/libgfortran/generated/matmul_i8.c
@@ -0,0 +1,138 @@
+/* Implementation of the MATMUL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+/* Dimensions: retarray(x,y) a(x, count) b(count,y).
+ Either a or b can be rank 1. In this case x or y is 1. */
+void
+__matmul_i8 (gfc_array_i8 * retarray, gfc_array_i8 * a, gfc_array_i8 * b)
+{
+ GFC_INTEGER_8 *abase;
+ GFC_INTEGER_8 *bbase;
+ GFC_INTEGER_8 *dest;
+ GFC_INTEGER_8 res;
+ index_type rxstride;
+ index_type rystride;
+ index_type xcount;
+ index_type ycount;
+ index_type xstride;
+ index_type ystride;
+ index_type x;
+ index_type y;
+
+ GFC_INTEGER_8 *pa;
+ GFC_INTEGER_8 *pb;
+ index_type astride;
+ index_type bstride;
+ index_type count;
+ index_type n;
+
+ assert (GFC_DESCRIPTOR_RANK (a) == 2
+ || GFC_DESCRIPTOR_RANK (b) == 2);
+ abase = a->data;
+ bbase = b->data;
+ dest = retarray->data;
+
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (a->dim[0].stride == 0)
+ a->dim[0].stride = 1;
+ if (b->dim[0].stride == 0)
+ b->dim[0].stride = 1;
+
+
+ if (GFC_DESCRIPTOR_RANK (retarray) == 1)
+ {
+ rxstride = retarray->dim[0].stride;
+ rystride = rxstride;
+ }
+ else
+ {
+ rxstride = retarray->dim[0].stride;
+ rystride = retarray->dim[1].stride;
+ }
+
+ /* If we have rank 1 parameters, zero the absent stride, and set the size to
+ one. */
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ astride = a->dim[0].stride;
+ count = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ xstride = 0;
+ rxstride = 0;
+ xcount = 1;
+ }
+ else
+ {
+ astride = a->dim[1].stride;
+ count = a->dim[1].ubound + 1 - a->dim[1].lbound;
+ xstride = a->dim[0].stride;
+ xcount = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ }
+ if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ bstride = b->dim[0].stride;
+ assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound);
+ ystride = 0;
+ rystride = 0;
+ ycount = 1;
+ }
+ else
+ {
+ bstride = b->dim[0].stride;
+ assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound);
+ ystride = b->dim[1].stride;
+ ycount = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ }
+
+ for (y = 0; y < ycount; y++)
+ {
+ for (x = 0; x < xcount; x++)
+ {
+ /* Do the summation for this element. For real and integer types
+ this is the same as DOT_PRODUCT. For complex types we use do
+ a*b, not conjg(a)*b. */
+ pa = abase;
+ pb = bbase;
+ res = 0;
+
+ for (n = 0; n < count; n++)
+ {
+ res += *pa * *pb;
+ pa += astride;
+ pb += bstride;
+ }
+
+ *dest = res;
+
+ dest += rxstride;
+ abase += xstride;
+ }
+ abase -= xstride * xcount;
+ bbase += ystride;
+ dest += rystride - (rxstride * xcount);
+ }
+}
+
diff --git a/libgfortran/generated/matmul_l4.c b/libgfortran/generated/matmul_l4.c
new file mode 100644
index 00000000000..f141b651000
--- /dev/null
+++ b/libgfortran/generated/matmul_l4.c
@@ -0,0 +1,151 @@
+/* Implementation of the MATMUL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+/* Dimensions: retarray(x,y) a(x, count) b(count,y).
+ Either a or b can be rank 1. In this case x or y is 1. */
+void
+__matmul_l4 (gfc_array_l4 * retarray, gfc_array_l4 * a, gfc_array_l4 * b)
+{
+ GFC_INTEGER_4 *abase;
+ GFC_INTEGER_4 *bbase;
+ GFC_LOGICAL_4 *dest;
+ index_type rxstride;
+ index_type rystride;
+ index_type xcount;
+ index_type ycount;
+ index_type xstride;
+ index_type ystride;
+ index_type x;
+ index_type y;
+
+ GFC_INTEGER_4 *pa;
+ GFC_INTEGER_4 *pb;
+ index_type astride;
+ index_type bstride;
+ index_type count;
+ index_type n;
+
+ assert (GFC_DESCRIPTOR_RANK (a) == 2
+ || GFC_DESCRIPTOR_RANK (b) == 2);
+ abase = a->data;
+ if (GFC_DESCRIPTOR_SIZE (a) != 4)
+ {
+ assert (GFC_DESCRIPTOR_SIZE (a) == 8);
+ abase = GFOR_POINTER_L8_TO_L4 (abase);
+ astride <<= 1;
+ }
+ bbase = b->data;
+ if (GFC_DESCRIPTOR_SIZE (b) != 4)
+ {
+ assert (GFC_DESCRIPTOR_SIZE (b) == 8);
+ bbase = GFOR_POINTER_L8_TO_L4 (bbase);
+ bstride <<= 1;
+ }
+ dest = retarray->data;
+
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (a->dim[0].stride == 0)
+ a->dim[0].stride = 1;
+ if (b->dim[0].stride == 0)
+ b->dim[0].stride = 1;
+
+
+ if (GFC_DESCRIPTOR_RANK (retarray) == 1)
+ {
+ rxstride = retarray->dim[0].stride;
+ rystride = rxstride;
+ }
+ else
+ {
+ rxstride = retarray->dim[0].stride;
+ rystride = retarray->dim[1].stride;
+ }
+
+ /* If we have rank 1 parameters, zero the absent stride, and set the size to
+ one. */
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ astride = a->dim[0].stride;
+ count = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ xstride = 0;
+ rxstride = 0;
+ xcount = 1;
+ }
+ else
+ {
+ astride = a->dim[1].stride;
+ count = a->dim[1].ubound + 1 - a->dim[1].lbound;
+ xstride = a->dim[0].stride;
+ xcount = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ }
+ if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ bstride = b->dim[0].stride;
+ assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound);
+ ystride = 0;
+ rystride = 0;
+ ycount = 1;
+ }
+ else
+ {
+ bstride = b->dim[0].stride;
+ assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound);
+ ystride = b->dim[1].stride;
+ ycount = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ }
+
+ for (y = 0; y < ycount; y++)
+ {
+ for (x = 0; x < xcount; x++)
+ {
+ /* Do the summation for this element. For real and integer types
+ this is the same as DOT_PRODUCT. For complex types we use do
+ a*b, not conjg(a)*b. */
+ pa = abase;
+ pb = bbase;
+ *dest = 0;
+
+ for (n = 0; n < count; n++)
+ {
+ if (*pa && *pb)
+ {
+ *dest = 1;
+ break;
+ }
+ pa += astride;
+ pb += bstride;
+ }
+
+ dest += rxstride;
+ abase += xstride;
+ }
+ abase -= xstride * xcount;
+ bbase += ystride;
+ dest += rystride - (rxstride * xcount);
+ }
+}
+
diff --git a/libgfortran/generated/matmul_l8.c b/libgfortran/generated/matmul_l8.c
new file mode 100644
index 00000000000..49243afd9ad
--- /dev/null
+++ b/libgfortran/generated/matmul_l8.c
@@ -0,0 +1,151 @@
+/* Implementation of the MATMUL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+/* Dimensions: retarray(x,y) a(x, count) b(count,y).
+ Either a or b can be rank 1. In this case x or y is 1. */
+void
+__matmul_l8 (gfc_array_l8 * retarray, gfc_array_l4 * a, gfc_array_l4 * b)
+{
+ GFC_INTEGER_4 *abase;
+ GFC_INTEGER_4 *bbase;
+ GFC_LOGICAL_8 *dest;
+ index_type rxstride;
+ index_type rystride;
+ index_type xcount;
+ index_type ycount;
+ index_type xstride;
+ index_type ystride;
+ index_type x;
+ index_type y;
+
+ GFC_INTEGER_4 *pa;
+ GFC_INTEGER_4 *pb;
+ index_type astride;
+ index_type bstride;
+ index_type count;
+ index_type n;
+
+ assert (GFC_DESCRIPTOR_RANK (a) == 2
+ || GFC_DESCRIPTOR_RANK (b) == 2);
+ abase = a->data;
+ if (GFC_DESCRIPTOR_SIZE (a) != 4)
+ {
+ assert (GFC_DESCRIPTOR_SIZE (a) == 8);
+ abase = GFOR_POINTER_L8_TO_L4 (abase);
+ astride <<= 1;
+ }
+ bbase = b->data;
+ if (GFC_DESCRIPTOR_SIZE (b) != 4)
+ {
+ assert (GFC_DESCRIPTOR_SIZE (b) == 8);
+ bbase = GFOR_POINTER_L8_TO_L4 (bbase);
+ bstride <<= 1;
+ }
+ dest = retarray->data;
+
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (a->dim[0].stride == 0)
+ a->dim[0].stride = 1;
+ if (b->dim[0].stride == 0)
+ b->dim[0].stride = 1;
+
+
+ if (GFC_DESCRIPTOR_RANK (retarray) == 1)
+ {
+ rxstride = retarray->dim[0].stride;
+ rystride = rxstride;
+ }
+ else
+ {
+ rxstride = retarray->dim[0].stride;
+ rystride = retarray->dim[1].stride;
+ }
+
+ /* If we have rank 1 parameters, zero the absent stride, and set the size to
+ one. */
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ astride = a->dim[0].stride;
+ count = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ xstride = 0;
+ rxstride = 0;
+ xcount = 1;
+ }
+ else
+ {
+ astride = a->dim[1].stride;
+ count = a->dim[1].ubound + 1 - a->dim[1].lbound;
+ xstride = a->dim[0].stride;
+ xcount = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ }
+ if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ bstride = b->dim[0].stride;
+ assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound);
+ ystride = 0;
+ rystride = 0;
+ ycount = 1;
+ }
+ else
+ {
+ bstride = b->dim[0].stride;
+ assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound);
+ ystride = b->dim[1].stride;
+ ycount = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ }
+
+ for (y = 0; y < ycount; y++)
+ {
+ for (x = 0; x < xcount; x++)
+ {
+ /* Do the summation for this element. For real and integer types
+ this is the same as DOT_PRODUCT. For complex types we use do
+ a*b, not conjg(a)*b. */
+ pa = abase;
+ pb = bbase;
+ *dest = 0;
+
+ for (n = 0; n < count; n++)
+ {
+ if (*pa && *pb)
+ {
+ *dest = 1;
+ break;
+ }
+ pa += astride;
+ pb += bstride;
+ }
+
+ dest += rxstride;
+ abase += xstride;
+ }
+ abase -= xstride * xcount;
+ bbase += ystride;
+ dest += rystride - (rxstride * xcount);
+ }
+}
+
diff --git a/libgfortran/generated/matmul_r4.c b/libgfortran/generated/matmul_r4.c
new file mode 100644
index 00000000000..dea706bb7d1
--- /dev/null
+++ b/libgfortran/generated/matmul_r4.c
@@ -0,0 +1,138 @@
+/* Implementation of the MATMUL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+/* Dimensions: retarray(x,y) a(x, count) b(count,y).
+ Either a or b can be rank 1. In this case x or y is 1. */
+void
+__matmul_r4 (gfc_array_r4 * retarray, gfc_array_r4 * a, gfc_array_r4 * b)
+{
+ GFC_REAL_4 *abase;
+ GFC_REAL_4 *bbase;
+ GFC_REAL_4 *dest;
+ GFC_REAL_4 res;
+ index_type rxstride;
+ index_type rystride;
+ index_type xcount;
+ index_type ycount;
+ index_type xstride;
+ index_type ystride;
+ index_type x;
+ index_type y;
+
+ GFC_REAL_4 *pa;
+ GFC_REAL_4 *pb;
+ index_type astride;
+ index_type bstride;
+ index_type count;
+ index_type n;
+
+ assert (GFC_DESCRIPTOR_RANK (a) == 2
+ || GFC_DESCRIPTOR_RANK (b) == 2);
+ abase = a->data;
+ bbase = b->data;
+ dest = retarray->data;
+
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (a->dim[0].stride == 0)
+ a->dim[0].stride = 1;
+ if (b->dim[0].stride == 0)
+ b->dim[0].stride = 1;
+
+
+ if (GFC_DESCRIPTOR_RANK (retarray) == 1)
+ {
+ rxstride = retarray->dim[0].stride;
+ rystride = rxstride;
+ }
+ else
+ {
+ rxstride = retarray->dim[0].stride;
+ rystride = retarray->dim[1].stride;
+ }
+
+ /* If we have rank 1 parameters, zero the absent stride, and set the size to
+ one. */
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ astride = a->dim[0].stride;
+ count = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ xstride = 0;
+ rxstride = 0;
+ xcount = 1;
+ }
+ else
+ {
+ astride = a->dim[1].stride;
+ count = a->dim[1].ubound + 1 - a->dim[1].lbound;
+ xstride = a->dim[0].stride;
+ xcount = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ }
+ if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ bstride = b->dim[0].stride;
+ assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound);
+ ystride = 0;
+ rystride = 0;
+ ycount = 1;
+ }
+ else
+ {
+ bstride = b->dim[0].stride;
+ assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound);
+ ystride = b->dim[1].stride;
+ ycount = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ }
+
+ for (y = 0; y < ycount; y++)
+ {
+ for (x = 0; x < xcount; x++)
+ {
+ /* Do the summation for this element. For real and integer types
+ this is the same as DOT_PRODUCT. For complex types we use do
+ a*b, not conjg(a)*b. */
+ pa = abase;
+ pb = bbase;
+ res = 0;
+
+ for (n = 0; n < count; n++)
+ {
+ res += *pa * *pb;
+ pa += astride;
+ pb += bstride;
+ }
+
+ *dest = res;
+
+ dest += rxstride;
+ abase += xstride;
+ }
+ abase -= xstride * xcount;
+ bbase += ystride;
+ dest += rystride - (rxstride * xcount);
+ }
+}
+
diff --git a/libgfortran/generated/matmul_r8.c b/libgfortran/generated/matmul_r8.c
new file mode 100644
index 00000000000..dfe4841615a
--- /dev/null
+++ b/libgfortran/generated/matmul_r8.c
@@ -0,0 +1,138 @@
+/* Implementation of the MATMUL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+/* Dimensions: retarray(x,y) a(x, count) b(count,y).
+ Either a or b can be rank 1. In this case x or y is 1. */
+void
+__matmul_r8 (gfc_array_r8 * retarray, gfc_array_r8 * a, gfc_array_r8 * b)
+{
+ GFC_REAL_8 *abase;
+ GFC_REAL_8 *bbase;
+ GFC_REAL_8 *dest;
+ GFC_REAL_8 res;
+ index_type rxstride;
+ index_type rystride;
+ index_type xcount;
+ index_type ycount;
+ index_type xstride;
+ index_type ystride;
+ index_type x;
+ index_type y;
+
+ GFC_REAL_8 *pa;
+ GFC_REAL_8 *pb;
+ index_type astride;
+ index_type bstride;
+ index_type count;
+ index_type n;
+
+ assert (GFC_DESCRIPTOR_RANK (a) == 2
+ || GFC_DESCRIPTOR_RANK (b) == 2);
+ abase = a->data;
+ bbase = b->data;
+ dest = retarray->data;
+
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (a->dim[0].stride == 0)
+ a->dim[0].stride = 1;
+ if (b->dim[0].stride == 0)
+ b->dim[0].stride = 1;
+
+
+ if (GFC_DESCRIPTOR_RANK (retarray) == 1)
+ {
+ rxstride = retarray->dim[0].stride;
+ rystride = rxstride;
+ }
+ else
+ {
+ rxstride = retarray->dim[0].stride;
+ rystride = retarray->dim[1].stride;
+ }
+
+ /* If we have rank 1 parameters, zero the absent stride, and set the size to
+ one. */
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ astride = a->dim[0].stride;
+ count = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ xstride = 0;
+ rxstride = 0;
+ xcount = 1;
+ }
+ else
+ {
+ astride = a->dim[1].stride;
+ count = a->dim[1].ubound + 1 - a->dim[1].lbound;
+ xstride = a->dim[0].stride;
+ xcount = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ }
+ if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ bstride = b->dim[0].stride;
+ assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound);
+ ystride = 0;
+ rystride = 0;
+ ycount = 1;
+ }
+ else
+ {
+ bstride = b->dim[0].stride;
+ assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound);
+ ystride = b->dim[1].stride;
+ ycount = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ }
+
+ for (y = 0; y < ycount; y++)
+ {
+ for (x = 0; x < xcount; x++)
+ {
+ /* Do the summation for this element. For real and integer types
+ this is the same as DOT_PRODUCT. For complex types we use do
+ a*b, not conjg(a)*b. */
+ pa = abase;
+ pb = bbase;
+ res = 0;
+
+ for (n = 0; n < count; n++)
+ {
+ res += *pa * *pb;
+ pa += astride;
+ pb += bstride;
+ }
+
+ *dest = res;
+
+ dest += rxstride;
+ abase += xstride;
+ }
+ abase -= xstride * xcount;
+ bbase += ystride;
+ dest += rystride - (rxstride * xcount);
+ }
+}
+
diff --git a/libgfortran/generated/maxloc0_4_i4.c b/libgfortran/generated/maxloc0_4_i4.c
new file mode 100644
index 00000000000..94f6f4f7080
--- /dev/null
+++ b/libgfortran/generated/maxloc0_4_i4.c
@@ -0,0 +1,230 @@
+/* Implementation of the MAXLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+
+void
+__maxloc0_4_i4 (gfc_array_i4 * retarray, gfc_array_i4 *array)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_4 *base;
+ GFC_INTEGER_4 *dest;
+ index_type rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_INTEGER_4 maxval;
+
+ maxval = -GFC_INTEGER_4_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*base > maxval)
+ {
+ maxval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ }
+ }
+ }
+ }
+}
+
+void
+__mmaxloc0_4_i4 (gfc_array_i4 * retarray, gfc_array_i4 *array, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type mstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_4 *dest;
+ GFC_INTEGER_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ assert (GFC_DESCRIPTOR_RANK (mask) == rank);
+
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_INTEGER_4 maxval;
+
+ maxval = -GFC_INTEGER_4_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*mbase && *base > maxval)
+ {
+ maxval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ }
+ }
+ }
+ }
+}
diff --git a/libgfortran/generated/maxloc0_4_i8.c b/libgfortran/generated/maxloc0_4_i8.c
new file mode 100644
index 00000000000..f5fb1ea55db
--- /dev/null
+++ b/libgfortran/generated/maxloc0_4_i8.c
@@ -0,0 +1,230 @@
+/* Implementation of the MAXLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+
+void
+__maxloc0_4_i8 (gfc_array_i4 * retarray, gfc_array_i8 *array)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_8 *base;
+ GFC_INTEGER_4 *dest;
+ index_type rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_INTEGER_8 maxval;
+
+ maxval = -GFC_INTEGER_8_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*base > maxval)
+ {
+ maxval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ }
+ }
+ }
+ }
+}
+
+void
+__mmaxloc0_4_i8 (gfc_array_i4 * retarray, gfc_array_i8 *array, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type mstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_4 *dest;
+ GFC_INTEGER_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ assert (GFC_DESCRIPTOR_RANK (mask) == rank);
+
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_INTEGER_8 maxval;
+
+ maxval = -GFC_INTEGER_8_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*mbase && *base > maxval)
+ {
+ maxval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ }
+ }
+ }
+ }
+}
diff --git a/libgfortran/generated/maxloc0_4_r4.c b/libgfortran/generated/maxloc0_4_r4.c
new file mode 100644
index 00000000000..cb77fa6eeca
--- /dev/null
+++ b/libgfortran/generated/maxloc0_4_r4.c
@@ -0,0 +1,230 @@
+/* Implementation of the MAXLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+
+void
+__maxloc0_4_r4 (gfc_array_i4 * retarray, gfc_array_r4 *array)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_REAL_4 *base;
+ GFC_INTEGER_4 *dest;
+ index_type rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_REAL_4 maxval;
+
+ maxval = -GFC_REAL_4_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*base > maxval)
+ {
+ maxval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ }
+ }
+ }
+ }
+}
+
+void
+__mmaxloc0_4_r4 (gfc_array_i4 * retarray, gfc_array_r4 *array, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type mstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_4 *dest;
+ GFC_REAL_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ assert (GFC_DESCRIPTOR_RANK (mask) == rank);
+
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_REAL_4 maxval;
+
+ maxval = -GFC_REAL_4_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*mbase && *base > maxval)
+ {
+ maxval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ }
+ }
+ }
+ }
+}
diff --git a/libgfortran/generated/maxloc0_4_r8.c b/libgfortran/generated/maxloc0_4_r8.c
new file mode 100644
index 00000000000..9491823b908
--- /dev/null
+++ b/libgfortran/generated/maxloc0_4_r8.c
@@ -0,0 +1,230 @@
+/* Implementation of the MAXLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+
+void
+__maxloc0_4_r8 (gfc_array_i4 * retarray, gfc_array_r8 *array)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_REAL_8 *base;
+ GFC_INTEGER_4 *dest;
+ index_type rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_REAL_8 maxval;
+
+ maxval = -GFC_REAL_8_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*base > maxval)
+ {
+ maxval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ }
+ }
+ }
+ }
+}
+
+void
+__mmaxloc0_4_r8 (gfc_array_i4 * retarray, gfc_array_r8 *array, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type mstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_4 *dest;
+ GFC_REAL_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ assert (GFC_DESCRIPTOR_RANK (mask) == rank);
+
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_REAL_8 maxval;
+
+ maxval = -GFC_REAL_8_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*mbase && *base > maxval)
+ {
+ maxval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ }
+ }
+ }
+ }
+}
diff --git a/libgfortran/generated/maxloc0_8_i4.c b/libgfortran/generated/maxloc0_8_i4.c
new file mode 100644
index 00000000000..c851bc408e9
--- /dev/null
+++ b/libgfortran/generated/maxloc0_8_i4.c
@@ -0,0 +1,230 @@
+/* Implementation of the MAXLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+
+void
+__maxloc0_8_i4 (gfc_array_i8 * retarray, gfc_array_i4 *array)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_4 *base;
+ GFC_INTEGER_8 *dest;
+ index_type rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_INTEGER_4 maxval;
+
+ maxval = -GFC_INTEGER_4_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*base > maxval)
+ {
+ maxval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ }
+ }
+ }
+ }
+}
+
+void
+__mmaxloc0_8_i4 (gfc_array_i8 * retarray, gfc_array_i4 *array, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type mstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_8 *dest;
+ GFC_INTEGER_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ assert (GFC_DESCRIPTOR_RANK (mask) == rank);
+
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_INTEGER_4 maxval;
+
+ maxval = -GFC_INTEGER_4_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*mbase && *base > maxval)
+ {
+ maxval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ }
+ }
+ }
+ }
+}
diff --git a/libgfortran/generated/maxloc0_8_i8.c b/libgfortran/generated/maxloc0_8_i8.c
new file mode 100644
index 00000000000..6a151a22073
--- /dev/null
+++ b/libgfortran/generated/maxloc0_8_i8.c
@@ -0,0 +1,230 @@
+/* Implementation of the MAXLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+
+void
+__maxloc0_8_i8 (gfc_array_i8 * retarray, gfc_array_i8 *array)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_8 *base;
+ GFC_INTEGER_8 *dest;
+ index_type rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_INTEGER_8 maxval;
+
+ maxval = -GFC_INTEGER_8_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*base > maxval)
+ {
+ maxval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ }
+ }
+ }
+ }
+}
+
+void
+__mmaxloc0_8_i8 (gfc_array_i8 * retarray, gfc_array_i8 *array, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type mstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_8 *dest;
+ GFC_INTEGER_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ assert (GFC_DESCRIPTOR_RANK (mask) == rank);
+
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_INTEGER_8 maxval;
+
+ maxval = -GFC_INTEGER_8_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*mbase && *base > maxval)
+ {
+ maxval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ }
+ }
+ }
+ }
+}
diff --git a/libgfortran/generated/maxloc0_8_r4.c b/libgfortran/generated/maxloc0_8_r4.c
new file mode 100644
index 00000000000..dc4d3b6cff5
--- /dev/null
+++ b/libgfortran/generated/maxloc0_8_r4.c
@@ -0,0 +1,230 @@
+/* Implementation of the MAXLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+
+void
+__maxloc0_8_r4 (gfc_array_i8 * retarray, gfc_array_r4 *array)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_REAL_4 *base;
+ GFC_INTEGER_8 *dest;
+ index_type rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_REAL_4 maxval;
+
+ maxval = -GFC_REAL_4_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*base > maxval)
+ {
+ maxval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ }
+ }
+ }
+ }
+}
+
+void
+__mmaxloc0_8_r4 (gfc_array_i8 * retarray, gfc_array_r4 *array, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type mstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_8 *dest;
+ GFC_REAL_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ assert (GFC_DESCRIPTOR_RANK (mask) == rank);
+
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_REAL_4 maxval;
+
+ maxval = -GFC_REAL_4_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*mbase && *base > maxval)
+ {
+ maxval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ }
+ }
+ }
+ }
+}
diff --git a/libgfortran/generated/maxloc0_8_r8.c b/libgfortran/generated/maxloc0_8_r8.c
new file mode 100644
index 00000000000..00525645460
--- /dev/null
+++ b/libgfortran/generated/maxloc0_8_r8.c
@@ -0,0 +1,230 @@
+/* Implementation of the MAXLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+
+void
+__maxloc0_8_r8 (gfc_array_i8 * retarray, gfc_array_r8 *array)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_REAL_8 *base;
+ GFC_INTEGER_8 *dest;
+ index_type rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_REAL_8 maxval;
+
+ maxval = -GFC_REAL_8_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*base > maxval)
+ {
+ maxval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ }
+ }
+ }
+ }
+}
+
+void
+__mmaxloc0_8_r8 (gfc_array_i8 * retarray, gfc_array_r8 *array, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type mstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_8 *dest;
+ GFC_REAL_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ assert (GFC_DESCRIPTOR_RANK (mask) == rank);
+
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_REAL_8 maxval;
+
+ maxval = -GFC_REAL_8_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*mbase && *base > maxval)
+ {
+ maxval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ }
+ }
+ }
+ }
+}
diff --git a/libgfortran/generated/maxloc1_4_i4.c b/libgfortran/generated/maxloc1_4_i4.c
new file mode 100644
index 00000000000..4f412099412
--- /dev/null
+++ b/libgfortran/generated/maxloc1_4_i4.c
@@ -0,0 +1,266 @@
+/* Implementation of the MAXLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+void
+__maxloc1_4_i4 (gfc_array_i4 * retarray, gfc_array_i4 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_4 *base;
+ GFC_INTEGER_4 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_INTEGER_4 *src;
+ GFC_INTEGER_4 result;
+ src = base;
+ {
+
+ GFC_INTEGER_4 maxval;
+ maxval = -GFC_INTEGER_4_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src > maxval)
+ {
+ maxval = *src;
+ result = (GFC_INTEGER_4)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mmaxloc1_4_i4 (gfc_array_i4 * retarray, gfc_array_i4 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_4 *dest;
+ GFC_INTEGER_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_INTEGER_4 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_4 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ GFC_INTEGER_4 maxval;
+ maxval = -GFC_INTEGER_4_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src > maxval)
+ {
+ maxval = *src;
+ result = (GFC_INTEGER_4)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/maxloc1_4_i8.c b/libgfortran/generated/maxloc1_4_i8.c
new file mode 100644
index 00000000000..f5dd241d7b7
--- /dev/null
+++ b/libgfortran/generated/maxloc1_4_i8.c
@@ -0,0 +1,266 @@
+/* Implementation of the MAXLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+void
+__maxloc1_4_i8 (gfc_array_i4 * retarray, gfc_array_i8 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_8 *base;
+ GFC_INTEGER_4 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_INTEGER_8 *src;
+ GFC_INTEGER_4 result;
+ src = base;
+ {
+
+ GFC_INTEGER_8 maxval;
+ maxval = -GFC_INTEGER_8_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src > maxval)
+ {
+ maxval = *src;
+ result = (GFC_INTEGER_4)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mmaxloc1_4_i8 (gfc_array_i4 * retarray, gfc_array_i8 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_4 *dest;
+ GFC_INTEGER_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_INTEGER_8 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_4 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ GFC_INTEGER_8 maxval;
+ maxval = -GFC_INTEGER_8_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src > maxval)
+ {
+ maxval = *src;
+ result = (GFC_INTEGER_4)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/maxloc1_4_r4.c b/libgfortran/generated/maxloc1_4_r4.c
new file mode 100644
index 00000000000..503cf6ad201
--- /dev/null
+++ b/libgfortran/generated/maxloc1_4_r4.c
@@ -0,0 +1,266 @@
+/* Implementation of the MAXLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+void
+__maxloc1_4_r4 (gfc_array_i4 * retarray, gfc_array_r4 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_4 *base;
+ GFC_INTEGER_4 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_REAL_4 *src;
+ GFC_INTEGER_4 result;
+ src = base;
+ {
+
+ GFC_REAL_4 maxval;
+ maxval = -GFC_REAL_4_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src > maxval)
+ {
+ maxval = *src;
+ result = (GFC_INTEGER_4)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mmaxloc1_4_r4 (gfc_array_i4 * retarray, gfc_array_r4 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_4 *dest;
+ GFC_REAL_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_REAL_4 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_4 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ GFC_REAL_4 maxval;
+ maxval = -GFC_REAL_4_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src > maxval)
+ {
+ maxval = *src;
+ result = (GFC_INTEGER_4)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/maxloc1_4_r8.c b/libgfortran/generated/maxloc1_4_r8.c
new file mode 100644
index 00000000000..08445db76e9
--- /dev/null
+++ b/libgfortran/generated/maxloc1_4_r8.c
@@ -0,0 +1,266 @@
+/* Implementation of the MAXLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+void
+__maxloc1_4_r8 (gfc_array_i4 * retarray, gfc_array_r8 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_8 *base;
+ GFC_INTEGER_4 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_REAL_8 *src;
+ GFC_INTEGER_4 result;
+ src = base;
+ {
+
+ GFC_REAL_8 maxval;
+ maxval = -GFC_REAL_8_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src > maxval)
+ {
+ maxval = *src;
+ result = (GFC_INTEGER_4)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mmaxloc1_4_r8 (gfc_array_i4 * retarray, gfc_array_r8 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_4 *dest;
+ GFC_REAL_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_REAL_8 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_4 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ GFC_REAL_8 maxval;
+ maxval = -GFC_REAL_8_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src > maxval)
+ {
+ maxval = *src;
+ result = (GFC_INTEGER_4)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/maxloc1_8_i4.c b/libgfortran/generated/maxloc1_8_i4.c
new file mode 100644
index 00000000000..5ec2525a9c2
--- /dev/null
+++ b/libgfortran/generated/maxloc1_8_i4.c
@@ -0,0 +1,266 @@
+/* Implementation of the MAXLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+void
+__maxloc1_8_i4 (gfc_array_i8 * retarray, gfc_array_i4 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_4 *base;
+ GFC_INTEGER_8 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_INTEGER_4 *src;
+ GFC_INTEGER_8 result;
+ src = base;
+ {
+
+ GFC_INTEGER_4 maxval;
+ maxval = -GFC_INTEGER_4_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src > maxval)
+ {
+ maxval = *src;
+ result = (GFC_INTEGER_8)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mmaxloc1_8_i4 (gfc_array_i8 * retarray, gfc_array_i4 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_8 *dest;
+ GFC_INTEGER_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_INTEGER_4 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_8 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ GFC_INTEGER_4 maxval;
+ maxval = -GFC_INTEGER_4_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src > maxval)
+ {
+ maxval = *src;
+ result = (GFC_INTEGER_8)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/maxloc1_8_i8.c b/libgfortran/generated/maxloc1_8_i8.c
new file mode 100644
index 00000000000..8f7203b8654
--- /dev/null
+++ b/libgfortran/generated/maxloc1_8_i8.c
@@ -0,0 +1,266 @@
+/* Implementation of the MAXLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+void
+__maxloc1_8_i8 (gfc_array_i8 * retarray, gfc_array_i8 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_8 *base;
+ GFC_INTEGER_8 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_INTEGER_8 *src;
+ GFC_INTEGER_8 result;
+ src = base;
+ {
+
+ GFC_INTEGER_8 maxval;
+ maxval = -GFC_INTEGER_8_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src > maxval)
+ {
+ maxval = *src;
+ result = (GFC_INTEGER_8)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mmaxloc1_8_i8 (gfc_array_i8 * retarray, gfc_array_i8 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_8 *dest;
+ GFC_INTEGER_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_INTEGER_8 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_8 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ GFC_INTEGER_8 maxval;
+ maxval = -GFC_INTEGER_8_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src > maxval)
+ {
+ maxval = *src;
+ result = (GFC_INTEGER_8)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/maxloc1_8_r4.c b/libgfortran/generated/maxloc1_8_r4.c
new file mode 100644
index 00000000000..2e80e4b3429
--- /dev/null
+++ b/libgfortran/generated/maxloc1_8_r4.c
@@ -0,0 +1,266 @@
+/* Implementation of the MAXLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+void
+__maxloc1_8_r4 (gfc_array_i8 * retarray, gfc_array_r4 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_4 *base;
+ GFC_INTEGER_8 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_REAL_4 *src;
+ GFC_INTEGER_8 result;
+ src = base;
+ {
+
+ GFC_REAL_4 maxval;
+ maxval = -GFC_REAL_4_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src > maxval)
+ {
+ maxval = *src;
+ result = (GFC_INTEGER_8)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mmaxloc1_8_r4 (gfc_array_i8 * retarray, gfc_array_r4 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_8 *dest;
+ GFC_REAL_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_REAL_4 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_8 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ GFC_REAL_4 maxval;
+ maxval = -GFC_REAL_4_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src > maxval)
+ {
+ maxval = *src;
+ result = (GFC_INTEGER_8)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/maxloc1_8_r8.c b/libgfortran/generated/maxloc1_8_r8.c
new file mode 100644
index 00000000000..611ef048564
--- /dev/null
+++ b/libgfortran/generated/maxloc1_8_r8.c
@@ -0,0 +1,266 @@
+/* Implementation of the MAXLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+void
+__maxloc1_8_r8 (gfc_array_i8 * retarray, gfc_array_r8 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_8 *base;
+ GFC_INTEGER_8 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_REAL_8 *src;
+ GFC_INTEGER_8 result;
+ src = base;
+ {
+
+ GFC_REAL_8 maxval;
+ maxval = -GFC_REAL_8_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src > maxval)
+ {
+ maxval = *src;
+ result = (GFC_INTEGER_8)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mmaxloc1_8_r8 (gfc_array_i8 * retarray, gfc_array_r8 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_8 *dest;
+ GFC_REAL_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_REAL_8 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_8 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ GFC_REAL_8 maxval;
+ maxval = -GFC_REAL_8_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src > maxval)
+ {
+ maxval = *src;
+ result = (GFC_INTEGER_8)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/maxval_i4.c b/libgfortran/generated/maxval_i4.c
new file mode 100644
index 00000000000..78802553c25
--- /dev/null
+++ b/libgfortran/generated/maxval_i4.c
@@ -0,0 +1,255 @@
+/* Implementation of the MAXVAL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include "libgfortran.h"
+
+
+void
+__maxval_i4 (gfc_array_i4 * retarray, gfc_array_i4 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_4 *base;
+ GFC_INTEGER_4 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_INTEGER_4 *src;
+ GFC_INTEGER_4 result;
+ src = base;
+ {
+
+ result = -GFC_INTEGER_4_HUGE;
+ if (len <= 0)
+ *dest = -GFC_INTEGER_4_HUGE;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src > result)
+ result = *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mmaxval_i4 (gfc_array_i4 * retarray, gfc_array_i4 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_4 *dest;
+ GFC_INTEGER_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_INTEGER_4 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_4 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ result = -GFC_INTEGER_4_HUGE;
+ if (len <= 0)
+ *dest = -GFC_INTEGER_4_HUGE;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src > result)
+ result = *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/maxval_i8.c b/libgfortran/generated/maxval_i8.c
new file mode 100644
index 00000000000..af433ea5dc2
--- /dev/null
+++ b/libgfortran/generated/maxval_i8.c
@@ -0,0 +1,255 @@
+/* Implementation of the MAXVAL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include "libgfortran.h"
+
+
+void
+__maxval_i8 (gfc_array_i8 * retarray, gfc_array_i8 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_8 *base;
+ GFC_INTEGER_8 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_INTEGER_8 *src;
+ GFC_INTEGER_8 result;
+ src = base;
+ {
+
+ result = -GFC_INTEGER_8_HUGE;
+ if (len <= 0)
+ *dest = -GFC_INTEGER_8_HUGE;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src > result)
+ result = *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mmaxval_i8 (gfc_array_i8 * retarray, gfc_array_i8 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_8 *dest;
+ GFC_INTEGER_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_INTEGER_8 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_8 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ result = -GFC_INTEGER_8_HUGE;
+ if (len <= 0)
+ *dest = -GFC_INTEGER_8_HUGE;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src > result)
+ result = *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/maxval_r4.c b/libgfortran/generated/maxval_r4.c
new file mode 100644
index 00000000000..3877b323b0f
--- /dev/null
+++ b/libgfortran/generated/maxval_r4.c
@@ -0,0 +1,255 @@
+/* Implementation of the MAXVAL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include "libgfortran.h"
+
+
+void
+__maxval_r4 (gfc_array_r4 * retarray, gfc_array_r4 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_4 *base;
+ GFC_REAL_4 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_REAL_4 *src;
+ GFC_REAL_4 result;
+ src = base;
+ {
+
+ result = -GFC_REAL_4_HUGE;
+ if (len <= 0)
+ *dest = -GFC_REAL_4_HUGE;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src > result)
+ result = *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mmaxval_r4 (gfc_array_r4 * retarray, gfc_array_r4 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_4 *dest;
+ GFC_REAL_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_REAL_4 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_REAL_4 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ result = -GFC_REAL_4_HUGE;
+ if (len <= 0)
+ *dest = -GFC_REAL_4_HUGE;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src > result)
+ result = *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/maxval_r8.c b/libgfortran/generated/maxval_r8.c
new file mode 100644
index 00000000000..b5c01062e6a
--- /dev/null
+++ b/libgfortran/generated/maxval_r8.c
@@ -0,0 +1,255 @@
+/* Implementation of the MAXVAL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include "libgfortran.h"
+
+
+void
+__maxval_r8 (gfc_array_r8 * retarray, gfc_array_r8 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_8 *base;
+ GFC_REAL_8 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_REAL_8 *src;
+ GFC_REAL_8 result;
+ src = base;
+ {
+
+ result = -GFC_REAL_8_HUGE;
+ if (len <= 0)
+ *dest = -GFC_REAL_8_HUGE;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src > result)
+ result = *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mmaxval_r8 (gfc_array_r8 * retarray, gfc_array_r8 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_8 *dest;
+ GFC_REAL_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_REAL_8 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_REAL_8 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ result = -GFC_REAL_8_HUGE;
+ if (len <= 0)
+ *dest = -GFC_REAL_8_HUGE;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src > result)
+ result = *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/minloc0_4_i4.c b/libgfortran/generated/minloc0_4_i4.c
new file mode 100644
index 00000000000..5407f4cb63c
--- /dev/null
+++ b/libgfortran/generated/minloc0_4_i4.c
@@ -0,0 +1,230 @@
+/* Implementation of the MINLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+
+void
+__minloc0_4_i4 (gfc_array_i4 * retarray, gfc_array_i4 *array)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_4 *base;
+ GFC_INTEGER_4 *dest;
+ index_type rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_INTEGER_4 minval;
+
+ minval = GFC_INTEGER_4_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*base < minval)
+ {
+ minval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ }
+ }
+ }
+ }
+}
+
+void
+__mminloc0_4_i4 (gfc_array_i4 * retarray, gfc_array_i4 *array, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type mstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_4 *dest;
+ GFC_INTEGER_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ assert (GFC_DESCRIPTOR_RANK (mask) == rank);
+
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_INTEGER_4 minval;
+
+ minval = GFC_INTEGER_4_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*mbase && *base < minval)
+ {
+ minval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ }
+ }
+ }
+ }
+}
diff --git a/libgfortran/generated/minloc0_4_i8.c b/libgfortran/generated/minloc0_4_i8.c
new file mode 100644
index 00000000000..b0c58293eb8
--- /dev/null
+++ b/libgfortran/generated/minloc0_4_i8.c
@@ -0,0 +1,230 @@
+/* Implementation of the MINLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+
+void
+__minloc0_4_i8 (gfc_array_i4 * retarray, gfc_array_i8 *array)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_8 *base;
+ GFC_INTEGER_4 *dest;
+ index_type rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_INTEGER_8 minval;
+
+ minval = GFC_INTEGER_8_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*base < minval)
+ {
+ minval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ }
+ }
+ }
+ }
+}
+
+void
+__mminloc0_4_i8 (gfc_array_i4 * retarray, gfc_array_i8 *array, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type mstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_4 *dest;
+ GFC_INTEGER_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ assert (GFC_DESCRIPTOR_RANK (mask) == rank);
+
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_INTEGER_8 minval;
+
+ minval = GFC_INTEGER_8_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*mbase && *base < minval)
+ {
+ minval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ }
+ }
+ }
+ }
+}
diff --git a/libgfortran/generated/minloc0_4_r4.c b/libgfortran/generated/minloc0_4_r4.c
new file mode 100644
index 00000000000..175f9c8967b
--- /dev/null
+++ b/libgfortran/generated/minloc0_4_r4.c
@@ -0,0 +1,230 @@
+/* Implementation of the MINLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+
+void
+__minloc0_4_r4 (gfc_array_i4 * retarray, gfc_array_r4 *array)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_REAL_4 *base;
+ GFC_INTEGER_4 *dest;
+ index_type rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_REAL_4 minval;
+
+ minval = GFC_REAL_4_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*base < minval)
+ {
+ minval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ }
+ }
+ }
+ }
+}
+
+void
+__mminloc0_4_r4 (gfc_array_i4 * retarray, gfc_array_r4 *array, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type mstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_4 *dest;
+ GFC_REAL_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ assert (GFC_DESCRIPTOR_RANK (mask) == rank);
+
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_REAL_4 minval;
+
+ minval = GFC_REAL_4_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*mbase && *base < minval)
+ {
+ minval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ }
+ }
+ }
+ }
+}
diff --git a/libgfortran/generated/minloc0_4_r8.c b/libgfortran/generated/minloc0_4_r8.c
new file mode 100644
index 00000000000..01f44a570f5
--- /dev/null
+++ b/libgfortran/generated/minloc0_4_r8.c
@@ -0,0 +1,230 @@
+/* Implementation of the MINLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+
+void
+__minloc0_4_r8 (gfc_array_i4 * retarray, gfc_array_r8 *array)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_REAL_8 *base;
+ GFC_INTEGER_4 *dest;
+ index_type rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_REAL_8 minval;
+
+ minval = GFC_REAL_8_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*base < minval)
+ {
+ minval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ }
+ }
+ }
+ }
+}
+
+void
+__mminloc0_4_r8 (gfc_array_i4 * retarray, gfc_array_r8 *array, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type mstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_4 *dest;
+ GFC_REAL_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ assert (GFC_DESCRIPTOR_RANK (mask) == rank);
+
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_REAL_8 minval;
+
+ minval = GFC_REAL_8_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*mbase && *base < minval)
+ {
+ minval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ }
+ }
+ }
+ }
+}
diff --git a/libgfortran/generated/minloc0_8_i4.c b/libgfortran/generated/minloc0_8_i4.c
new file mode 100644
index 00000000000..0d4410338d7
--- /dev/null
+++ b/libgfortran/generated/minloc0_8_i4.c
@@ -0,0 +1,230 @@
+/* Implementation of the MINLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+
+void
+__minloc0_8_i4 (gfc_array_i8 * retarray, gfc_array_i4 *array)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_4 *base;
+ GFC_INTEGER_8 *dest;
+ index_type rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_INTEGER_4 minval;
+
+ minval = GFC_INTEGER_4_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*base < minval)
+ {
+ minval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ }
+ }
+ }
+ }
+}
+
+void
+__mminloc0_8_i4 (gfc_array_i8 * retarray, gfc_array_i4 *array, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type mstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_8 *dest;
+ GFC_INTEGER_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ assert (GFC_DESCRIPTOR_RANK (mask) == rank);
+
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_INTEGER_4 minval;
+
+ minval = GFC_INTEGER_4_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*mbase && *base < minval)
+ {
+ minval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ }
+ }
+ }
+ }
+}
diff --git a/libgfortran/generated/minloc0_8_i8.c b/libgfortran/generated/minloc0_8_i8.c
new file mode 100644
index 00000000000..83ef0399dac
--- /dev/null
+++ b/libgfortran/generated/minloc0_8_i8.c
@@ -0,0 +1,230 @@
+/* Implementation of the MINLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+
+void
+__minloc0_8_i8 (gfc_array_i8 * retarray, gfc_array_i8 *array)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_8 *base;
+ GFC_INTEGER_8 *dest;
+ index_type rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_INTEGER_8 minval;
+
+ minval = GFC_INTEGER_8_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*base < minval)
+ {
+ minval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ }
+ }
+ }
+ }
+}
+
+void
+__mminloc0_8_i8 (gfc_array_i8 * retarray, gfc_array_i8 *array, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type mstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_8 *dest;
+ GFC_INTEGER_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ assert (GFC_DESCRIPTOR_RANK (mask) == rank);
+
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_INTEGER_8 minval;
+
+ minval = GFC_INTEGER_8_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*mbase && *base < minval)
+ {
+ minval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ }
+ }
+ }
+ }
+}
diff --git a/libgfortran/generated/minloc0_8_r4.c b/libgfortran/generated/minloc0_8_r4.c
new file mode 100644
index 00000000000..36868e40333
--- /dev/null
+++ b/libgfortran/generated/minloc0_8_r4.c
@@ -0,0 +1,230 @@
+/* Implementation of the MINLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+
+void
+__minloc0_8_r4 (gfc_array_i8 * retarray, gfc_array_r4 *array)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_REAL_4 *base;
+ GFC_INTEGER_8 *dest;
+ index_type rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_REAL_4 minval;
+
+ minval = GFC_REAL_4_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*base < minval)
+ {
+ minval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ }
+ }
+ }
+ }
+}
+
+void
+__mminloc0_8_r4 (gfc_array_i8 * retarray, gfc_array_r4 *array, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type mstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_8 *dest;
+ GFC_REAL_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ assert (GFC_DESCRIPTOR_RANK (mask) == rank);
+
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_REAL_4 minval;
+
+ minval = GFC_REAL_4_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*mbase && *base < minval)
+ {
+ minval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ }
+ }
+ }
+ }
+}
diff --git a/libgfortran/generated/minloc0_8_r8.c b/libgfortran/generated/minloc0_8_r8.c
new file mode 100644
index 00000000000..5f0c48a68ae
--- /dev/null
+++ b/libgfortran/generated/minloc0_8_r8.c
@@ -0,0 +1,230 @@
+/* Implementation of the MINLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+
+void
+__minloc0_8_r8 (gfc_array_i8 * retarray, gfc_array_r8 *array)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_REAL_8 *base;
+ GFC_INTEGER_8 *dest;
+ index_type rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_REAL_8 minval;
+
+ minval = GFC_REAL_8_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*base < minval)
+ {
+ minval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ }
+ }
+ }
+ }
+}
+
+void
+__mminloc0_8_r8 (gfc_array_i8 * retarray, gfc_array_r8 *array, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type mstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ GFC_INTEGER_8 *dest;
+ GFC_REAL_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ assert (GFC_DESCRIPTOR_RANK (mask) == rank);
+
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+
+ GFC_REAL_8 minval;
+
+ minval = GFC_REAL_8_HUGE;
+
+ while (base)
+ {
+ {
+ /* Implementation start. */
+
+ if (*mbase && *base < minval)
+ {
+ minval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }
+ /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ }
+ }
+ }
+ }
+}
diff --git a/libgfortran/generated/minloc1_4_i4.c b/libgfortran/generated/minloc1_4_i4.c
new file mode 100644
index 00000000000..b3e56f0cc60
--- /dev/null
+++ b/libgfortran/generated/minloc1_4_i4.c
@@ -0,0 +1,266 @@
+/* Implementation of the MINLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+void
+__minloc1_4_i4 (gfc_array_i4 * retarray, gfc_array_i4 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_4 *base;
+ GFC_INTEGER_4 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_INTEGER_4 *src;
+ GFC_INTEGER_4 result;
+ src = base;
+ {
+
+ GFC_INTEGER_4 minval;
+ minval = GFC_INTEGER_4_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src < minval)
+ {
+ minval = *src;
+ result = (GFC_INTEGER_4)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mminloc1_4_i4 (gfc_array_i4 * retarray, gfc_array_i4 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_4 *dest;
+ GFC_INTEGER_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_INTEGER_4 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_4 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ GFC_INTEGER_4 minval;
+ minval = GFC_INTEGER_4_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src < minval)
+ {
+ minval = *src;
+ result = (GFC_INTEGER_4)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/minloc1_4_i8.c b/libgfortran/generated/minloc1_4_i8.c
new file mode 100644
index 00000000000..b2fce929561
--- /dev/null
+++ b/libgfortran/generated/minloc1_4_i8.c
@@ -0,0 +1,266 @@
+/* Implementation of the MINLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+void
+__minloc1_4_i8 (gfc_array_i4 * retarray, gfc_array_i8 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_8 *base;
+ GFC_INTEGER_4 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_INTEGER_8 *src;
+ GFC_INTEGER_4 result;
+ src = base;
+ {
+
+ GFC_INTEGER_8 minval;
+ minval = GFC_INTEGER_8_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src < minval)
+ {
+ minval = *src;
+ result = (GFC_INTEGER_4)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mminloc1_4_i8 (gfc_array_i4 * retarray, gfc_array_i8 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_4 *dest;
+ GFC_INTEGER_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_INTEGER_8 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_4 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ GFC_INTEGER_8 minval;
+ minval = GFC_INTEGER_8_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src < minval)
+ {
+ minval = *src;
+ result = (GFC_INTEGER_4)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/minloc1_4_r4.c b/libgfortran/generated/minloc1_4_r4.c
new file mode 100644
index 00000000000..d7f9ff6a627
--- /dev/null
+++ b/libgfortran/generated/minloc1_4_r4.c
@@ -0,0 +1,266 @@
+/* Implementation of the MINLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+void
+__minloc1_4_r4 (gfc_array_i4 * retarray, gfc_array_r4 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_4 *base;
+ GFC_INTEGER_4 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_REAL_4 *src;
+ GFC_INTEGER_4 result;
+ src = base;
+ {
+
+ GFC_REAL_4 minval;
+ minval = GFC_REAL_4_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src < minval)
+ {
+ minval = *src;
+ result = (GFC_INTEGER_4)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mminloc1_4_r4 (gfc_array_i4 * retarray, gfc_array_r4 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_4 *dest;
+ GFC_REAL_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_REAL_4 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_4 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ GFC_REAL_4 minval;
+ minval = GFC_REAL_4_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src < minval)
+ {
+ minval = *src;
+ result = (GFC_INTEGER_4)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/minloc1_4_r8.c b/libgfortran/generated/minloc1_4_r8.c
new file mode 100644
index 00000000000..66146ae5d8b
--- /dev/null
+++ b/libgfortran/generated/minloc1_4_r8.c
@@ -0,0 +1,266 @@
+/* Implementation of the MINLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+void
+__minloc1_4_r8 (gfc_array_i4 * retarray, gfc_array_r8 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_8 *base;
+ GFC_INTEGER_4 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_REAL_8 *src;
+ GFC_INTEGER_4 result;
+ src = base;
+ {
+
+ GFC_REAL_8 minval;
+ minval = GFC_REAL_8_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src < minval)
+ {
+ minval = *src;
+ result = (GFC_INTEGER_4)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mminloc1_4_r8 (gfc_array_i4 * retarray, gfc_array_r8 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_4 *dest;
+ GFC_REAL_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_REAL_8 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_4 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ GFC_REAL_8 minval;
+ minval = GFC_REAL_8_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src < minval)
+ {
+ minval = *src;
+ result = (GFC_INTEGER_4)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/minloc1_8_i4.c b/libgfortran/generated/minloc1_8_i4.c
new file mode 100644
index 00000000000..a5edad58492
--- /dev/null
+++ b/libgfortran/generated/minloc1_8_i4.c
@@ -0,0 +1,266 @@
+/* Implementation of the MINLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+void
+__minloc1_8_i4 (gfc_array_i8 * retarray, gfc_array_i4 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_4 *base;
+ GFC_INTEGER_8 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_INTEGER_4 *src;
+ GFC_INTEGER_8 result;
+ src = base;
+ {
+
+ GFC_INTEGER_4 minval;
+ minval = GFC_INTEGER_4_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src < minval)
+ {
+ minval = *src;
+ result = (GFC_INTEGER_8)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mminloc1_8_i4 (gfc_array_i8 * retarray, gfc_array_i4 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_8 *dest;
+ GFC_INTEGER_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_INTEGER_4 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_8 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ GFC_INTEGER_4 minval;
+ minval = GFC_INTEGER_4_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src < minval)
+ {
+ minval = *src;
+ result = (GFC_INTEGER_8)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/minloc1_8_i8.c b/libgfortran/generated/minloc1_8_i8.c
new file mode 100644
index 00000000000..55f1ce268f0
--- /dev/null
+++ b/libgfortran/generated/minloc1_8_i8.c
@@ -0,0 +1,266 @@
+/* Implementation of the MINLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+void
+__minloc1_8_i8 (gfc_array_i8 * retarray, gfc_array_i8 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_8 *base;
+ GFC_INTEGER_8 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_INTEGER_8 *src;
+ GFC_INTEGER_8 result;
+ src = base;
+ {
+
+ GFC_INTEGER_8 minval;
+ minval = GFC_INTEGER_8_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src < minval)
+ {
+ minval = *src;
+ result = (GFC_INTEGER_8)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mminloc1_8_i8 (gfc_array_i8 * retarray, gfc_array_i8 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_8 *dest;
+ GFC_INTEGER_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_INTEGER_8 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_8 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ GFC_INTEGER_8 minval;
+ minval = GFC_INTEGER_8_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src < minval)
+ {
+ minval = *src;
+ result = (GFC_INTEGER_8)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/minloc1_8_r4.c b/libgfortran/generated/minloc1_8_r4.c
new file mode 100644
index 00000000000..3f7eb16bf78
--- /dev/null
+++ b/libgfortran/generated/minloc1_8_r4.c
@@ -0,0 +1,266 @@
+/* Implementation of the MINLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+void
+__minloc1_8_r4 (gfc_array_i8 * retarray, gfc_array_r4 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_4 *base;
+ GFC_INTEGER_8 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_REAL_4 *src;
+ GFC_INTEGER_8 result;
+ src = base;
+ {
+
+ GFC_REAL_4 minval;
+ minval = GFC_REAL_4_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src < minval)
+ {
+ minval = *src;
+ result = (GFC_INTEGER_8)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mminloc1_8_r4 (gfc_array_i8 * retarray, gfc_array_r4 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_8 *dest;
+ GFC_REAL_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_REAL_4 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_8 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ GFC_REAL_4 minval;
+ minval = GFC_REAL_4_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src < minval)
+ {
+ minval = *src;
+ result = (GFC_INTEGER_8)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/minloc1_8_r8.c b/libgfortran/generated/minloc1_8_r8.c
new file mode 100644
index 00000000000..19cb41d7acc
--- /dev/null
+++ b/libgfortran/generated/minloc1_8_r8.c
@@ -0,0 +1,266 @@
+/* Implementation of the MINLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"
+
+
+void
+__minloc1_8_r8 (gfc_array_i8 * retarray, gfc_array_r8 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_8 *base;
+ GFC_INTEGER_8 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_REAL_8 *src;
+ GFC_INTEGER_8 result;
+ src = base;
+ {
+
+ GFC_REAL_8 minval;
+ minval = GFC_REAL_8_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src < minval)
+ {
+ minval = *src;
+ result = (GFC_INTEGER_8)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mminloc1_8_r8 (gfc_array_i8 * retarray, gfc_array_r8 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_8 *dest;
+ GFC_REAL_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_REAL_8 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_8 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ GFC_REAL_8 minval;
+ minval = GFC_REAL_8_HUGE;
+ result = 1;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src < minval)
+ {
+ minval = *src;
+ result = (GFC_INTEGER_8)n + 1;
+ }
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/minval_i4.c b/libgfortran/generated/minval_i4.c
new file mode 100644
index 00000000000..0bd7f5698c1
--- /dev/null
+++ b/libgfortran/generated/minval_i4.c
@@ -0,0 +1,255 @@
+/* Implementation of the MINVAL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include "libgfortran.h"
+
+
+void
+__minval_i4 (gfc_array_i4 * retarray, gfc_array_i4 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_4 *base;
+ GFC_INTEGER_4 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_INTEGER_4 *src;
+ GFC_INTEGER_4 result;
+ src = base;
+ {
+
+ result = GFC_INTEGER_4_HUGE;
+ if (len <= 0)
+ *dest = GFC_INTEGER_4_HUGE;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src < result)
+ result = *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mminval_i4 (gfc_array_i4 * retarray, gfc_array_i4 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_4 *dest;
+ GFC_INTEGER_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_INTEGER_4 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_4 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ result = GFC_INTEGER_4_HUGE;
+ if (len <= 0)
+ *dest = GFC_INTEGER_4_HUGE;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src < result)
+ result = *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/minval_i8.c b/libgfortran/generated/minval_i8.c
new file mode 100644
index 00000000000..7f686f33658
--- /dev/null
+++ b/libgfortran/generated/minval_i8.c
@@ -0,0 +1,255 @@
+/* Implementation of the MINVAL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include "libgfortran.h"
+
+
+void
+__minval_i8 (gfc_array_i8 * retarray, gfc_array_i8 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_8 *base;
+ GFC_INTEGER_8 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_INTEGER_8 *src;
+ GFC_INTEGER_8 result;
+ src = base;
+ {
+
+ result = GFC_INTEGER_8_HUGE;
+ if (len <= 0)
+ *dest = GFC_INTEGER_8_HUGE;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src < result)
+ result = *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mminval_i8 (gfc_array_i8 * retarray, gfc_array_i8 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_8 *dest;
+ GFC_INTEGER_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_INTEGER_8 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_8 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ result = GFC_INTEGER_8_HUGE;
+ if (len <= 0)
+ *dest = GFC_INTEGER_8_HUGE;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src < result)
+ result = *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/minval_r4.c b/libgfortran/generated/minval_r4.c
new file mode 100644
index 00000000000..2ea19e451d3
--- /dev/null
+++ b/libgfortran/generated/minval_r4.c
@@ -0,0 +1,255 @@
+/* Implementation of the MINVAL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include "libgfortran.h"
+
+
+void
+__minval_r4 (gfc_array_r4 * retarray, gfc_array_r4 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_4 *base;
+ GFC_REAL_4 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_REAL_4 *src;
+ GFC_REAL_4 result;
+ src = base;
+ {
+
+ result = GFC_REAL_4_HUGE;
+ if (len <= 0)
+ *dest = GFC_REAL_4_HUGE;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src < result)
+ result = *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mminval_r4 (gfc_array_r4 * retarray, gfc_array_r4 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_4 *dest;
+ GFC_REAL_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_REAL_4 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_REAL_4 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ result = GFC_REAL_4_HUGE;
+ if (len <= 0)
+ *dest = GFC_REAL_4_HUGE;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src < result)
+ result = *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/minval_r8.c b/libgfortran/generated/minval_r8.c
new file mode 100644
index 00000000000..4ed8ce1d0aa
--- /dev/null
+++ b/libgfortran/generated/minval_r8.c
@@ -0,0 +1,255 @@
+/* Implementation of the MINVAL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include "libgfortran.h"
+
+
+void
+__minval_r8 (gfc_array_r8 * retarray, gfc_array_r8 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_8 *base;
+ GFC_REAL_8 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_REAL_8 *src;
+ GFC_REAL_8 result;
+ src = base;
+ {
+
+ result = GFC_REAL_8_HUGE;
+ if (len <= 0)
+ *dest = GFC_REAL_8_HUGE;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ if (*src < result)
+ result = *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mminval_r8 (gfc_array_r8 * retarray, gfc_array_r8 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_8 *dest;
+ GFC_REAL_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_REAL_8 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_REAL_8 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ result = GFC_REAL_8_HUGE;
+ if (len <= 0)
+ *dest = GFC_REAL_8_HUGE;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc && *src < result)
+ result = *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/nearest_r4.c b/libgfortran/generated/nearest_r4.c
new file mode 100644
index 00000000000..cafc02f21f2
--- /dev/null
+++ b/libgfortran/generated/nearest_r4.c
@@ -0,0 +1,38 @@
+/* Implementation of the NEAREST intrinsic
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@redhat.com>.
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include <math.h>
+#include <float.h>
+#include "libgfortran.h"
+
+
+GFC_REAL_4
+prefix(nearest_r4) (GFC_REAL_4 s, GFC_REAL_4 dir)
+{
+ dir = copysignf (__builtin_inff (), dir);
+ if (FLT_EVAL_METHOD != 0)
+ {
+ /* ??? Work around glibc bug on x86. */
+ volatile GFC_REAL_4 r = nextafterf (s, dir);
+ return r;
+ }
+ else
+ return nextafterf (s, dir);
+}
diff --git a/libgfortran/generated/nearest_r8.c b/libgfortran/generated/nearest_r8.c
new file mode 100644
index 00000000000..54a374546df
--- /dev/null
+++ b/libgfortran/generated/nearest_r8.c
@@ -0,0 +1,38 @@
+/* Implementation of the NEAREST intrinsic
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@redhat.com>.
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include <math.h>
+#include <float.h>
+#include "libgfortran.h"
+
+
+GFC_REAL_8
+prefix(nearest_r8) (GFC_REAL_8 s, GFC_REAL_8 dir)
+{
+ dir = copysign (__builtin_inf (), dir);
+ if (FLT_EVAL_METHOD != 0)
+ {
+ /* ??? Work around glibc bug on x86. */
+ volatile GFC_REAL_8 r = nextafter (s, dir);
+ return r;
+ }
+ else
+ return nextafter (s, dir);
+}
diff --git a/libgfortran/generated/product_c4.c b/libgfortran/generated/product_c4.c
new file mode 100644
index 00000000000..b12a047d7a6
--- /dev/null
+++ b/libgfortran/generated/product_c4.c
@@ -0,0 +1,253 @@
+/* Implementation of the PRODUCT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+
+void
+__product_c4 (gfc_array_c4 * retarray, gfc_array_c4 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_COMPLEX_4 *base;
+ GFC_COMPLEX_4 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_COMPLEX_4 *src;
+ GFC_COMPLEX_4 result;
+ src = base;
+ {
+
+ result = 1;
+ if (len <= 0)
+ *dest = 1;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ result *= *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mproduct_c4 (gfc_array_c4 * retarray, gfc_array_c4 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_COMPLEX_4 *dest;
+ GFC_COMPLEX_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_COMPLEX_4 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_COMPLEX_4 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ result = 1;
+ if (len <= 0)
+ *dest = 1;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc)
+ result *= *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/product_c8.c b/libgfortran/generated/product_c8.c
new file mode 100644
index 00000000000..6e88972109a
--- /dev/null
+++ b/libgfortran/generated/product_c8.c
@@ -0,0 +1,253 @@
+/* Implementation of the PRODUCT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+
+void
+__product_c8 (gfc_array_c8 * retarray, gfc_array_c8 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_COMPLEX_8 *base;
+ GFC_COMPLEX_8 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_COMPLEX_8 *src;
+ GFC_COMPLEX_8 result;
+ src = base;
+ {
+
+ result = 1;
+ if (len <= 0)
+ *dest = 1;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ result *= *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mproduct_c8 (gfc_array_c8 * retarray, gfc_array_c8 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_COMPLEX_8 *dest;
+ GFC_COMPLEX_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_COMPLEX_8 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_COMPLEX_8 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ result = 1;
+ if (len <= 0)
+ *dest = 1;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc)
+ result *= *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/product_i4.c b/libgfortran/generated/product_i4.c
new file mode 100644
index 00000000000..229087f6941
--- /dev/null
+++ b/libgfortran/generated/product_i4.c
@@ -0,0 +1,253 @@
+/* Implementation of the PRODUCT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+
+void
+__product_i4 (gfc_array_i4 * retarray, gfc_array_i4 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_4 *base;
+ GFC_INTEGER_4 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_INTEGER_4 *src;
+ GFC_INTEGER_4 result;
+ src = base;
+ {
+
+ result = 1;
+ if (len <= 0)
+ *dest = 1;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ result *= *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mproduct_i4 (gfc_array_i4 * retarray, gfc_array_i4 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_4 *dest;
+ GFC_INTEGER_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_INTEGER_4 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_4 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ result = 1;
+ if (len <= 0)
+ *dest = 1;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc)
+ result *= *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/product_i8.c b/libgfortran/generated/product_i8.c
new file mode 100644
index 00000000000..16ef0a05b3c
--- /dev/null
+++ b/libgfortran/generated/product_i8.c
@@ -0,0 +1,253 @@
+/* Implementation of the PRODUCT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+
+void
+__product_i8 (gfc_array_i8 * retarray, gfc_array_i8 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_8 *base;
+ GFC_INTEGER_8 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_INTEGER_8 *src;
+ GFC_INTEGER_8 result;
+ src = base;
+ {
+
+ result = 1;
+ if (len <= 0)
+ *dest = 1;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ result *= *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mproduct_i8 (gfc_array_i8 * retarray, gfc_array_i8 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_8 *dest;
+ GFC_INTEGER_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_INTEGER_8 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_8 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ result = 1;
+ if (len <= 0)
+ *dest = 1;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc)
+ result *= *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/product_r4.c b/libgfortran/generated/product_r4.c
new file mode 100644
index 00000000000..5761b2ed86d
--- /dev/null
+++ b/libgfortran/generated/product_r4.c
@@ -0,0 +1,253 @@
+/* Implementation of the PRODUCT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+
+void
+__product_r4 (gfc_array_r4 * retarray, gfc_array_r4 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_4 *base;
+ GFC_REAL_4 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_REAL_4 *src;
+ GFC_REAL_4 result;
+ src = base;
+ {
+
+ result = 1;
+ if (len <= 0)
+ *dest = 1;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ result *= *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mproduct_r4 (gfc_array_r4 * retarray, gfc_array_r4 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_4 *dest;
+ GFC_REAL_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_REAL_4 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_REAL_4 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ result = 1;
+ if (len <= 0)
+ *dest = 1;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc)
+ result *= *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/product_r8.c b/libgfortran/generated/product_r8.c
new file mode 100644
index 00000000000..d00c970e61f
--- /dev/null
+++ b/libgfortran/generated/product_r8.c
@@ -0,0 +1,253 @@
+/* Implementation of the PRODUCT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+
+void
+__product_r8 (gfc_array_r8 * retarray, gfc_array_r8 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_8 *base;
+ GFC_REAL_8 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_REAL_8 *src;
+ GFC_REAL_8 result;
+ src = base;
+ {
+
+ result = 1;
+ if (len <= 0)
+ *dest = 1;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ result *= *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__mproduct_r8 (gfc_array_r8 * retarray, gfc_array_r8 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_8 *dest;
+ GFC_REAL_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_REAL_8 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_REAL_8 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ result = 1;
+ if (len <= 0)
+ *dest = 1;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc)
+ result *= *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/reshape_i4.c b/libgfortran/generated/reshape_i4.c
new file mode 100644
index 00000000000..7da866cf5d0
--- /dev/null
+++ b/libgfortran/generated/reshape_i4.c
@@ -0,0 +1,225 @@
+/* Implementation of the RESHAPE
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+typedef GFC_ARRAY_DESCRIPTOR(1, index_type) shape_type;
+
+/* The shape parameter is ignored. We can currently deduce the shape from the
+ return array. */
+void
+__reshape_4 (gfc_array_i4 * ret, gfc_array_i4 * source, shape_type * shape,
+ gfc_array_i4 * pad, shape_type * order)
+{
+ /* r.* indicates the return array. */
+ index_type rcount[GFC_MAX_DIMENSIONS - 1];
+ index_type rextent[GFC_MAX_DIMENSIONS - 1];
+ index_type rstride[GFC_MAX_DIMENSIONS - 1];
+ index_type rstride0;
+ index_type rdim;
+ index_type rsize;
+ GFC_INTEGER_4 *rptr;
+ /* s.* indicates the source array. */
+ index_type scount[GFC_MAX_DIMENSIONS - 1];
+ index_type sextent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride0;
+ index_type sdim;
+ index_type ssize;
+ const GFC_INTEGER_4 *sptr;
+ /* p.* indicates the pad array. */
+ index_type pcount[GFC_MAX_DIMENSIONS - 1];
+ index_type pextent[GFC_MAX_DIMENSIONS - 1];
+ index_type pstride[GFC_MAX_DIMENSIONS - 1];
+ index_type pdim;
+ index_type psize;
+ const GFC_INTEGER_4 *pptr;
+
+ const GFC_INTEGER_4 *src;
+ int n;
+ int dim;
+
+ if (ret->dim[0].stride == 0)
+ ret->dim[0].stride = 1;
+ if (source->dim[0].stride == 0)
+ source->dim[0].stride = 1;
+ if (shape->dim[0].stride == 0)
+ shape->dim[0].stride = 1;
+ if (pad && pad->dim[0].stride == 0)
+ pad->dim[0].stride = 1;
+ if (order && order->dim[0].stride == 0)
+ order->dim[0].stride = 1;
+
+ rdim = GFC_DESCRIPTOR_RANK (ret);
+ rsize = 1;
+ for (n = 0; n < rdim; n++)
+ {
+ if (order)
+ dim = order->data[n * order->dim[0].stride] - 1;
+ else
+ dim = n;
+
+ rcount[n] = 0;
+ rstride[n] = ret->dim[dim].stride;
+ rextent[n] = ret->dim[dim].ubound + 1 - ret->dim[dim].lbound;
+
+ if (rextent[n] != shape->data[dim * shape->dim[0].stride])
+ runtime_error ("shape and target do not conform");
+
+ if (rsize == rstride[n])
+ rsize *= rextent[n];
+ else
+ rsize = 0;
+ if (rextent[dim] <= 0)
+ return;
+ }
+
+ sdim = GFC_DESCRIPTOR_RANK (source);
+ ssize = 1;
+ for (n = 0; n < sdim; n++)
+ {
+ scount[n] = 0;
+ sstride[n] = source->dim[n].stride;
+ sextent[n] = source->dim[n].ubound + 1 - source->dim[n].lbound;
+ if (sextent[n] <= 0)
+ abort ();
+
+ if (ssize == sstride[n])
+ ssize *= sextent[n];
+ else
+ ssize = 0;
+ }
+
+ if (pad)
+ {
+ if (pad->dim[0].stride == 0)
+ pad->dim[0].stride = 1;
+ pdim = GFC_DESCRIPTOR_RANK (pad);
+ psize = 1;
+ for (n = 0; n < pdim; n++)
+ {
+ pcount[n] = 0;
+ pstride[n] = pad->dim[n].stride;
+ pextent[n] = pad->dim[n].ubound + 1 - pad->dim[n].lbound;
+ if (pextent[n] <= 0)
+ abort ();
+ if (psize == pstride[n])
+ psize *= pextent[n];
+ else
+ psize = 0;
+ }
+ pptr = pad->data;
+ }
+ else
+ {
+ pdim = 0;
+ psize = 1;
+ pptr = NULL;
+ }
+
+ if (rsize != 0 && ssize != 0 && psize != 0)
+ {
+ rsize *= 4;
+ ssize *= 4;
+ psize *= 4;
+ reshape_packed ((char *)ret->data, rsize, (char *)source->data,
+ ssize, pad ? (char *)pad->data : NULL, psize);
+ return;
+ }
+ rptr = ret->data;
+ src = sptr = source->data;
+ rstride0 = rstride[0];
+ sstride0 = sstride[0];
+
+ while (rptr)
+ {
+ /* Select between the source and pad arrays. */
+ *rptr = *src;
+ /* Advance to the next element. */
+ rptr += rstride0;
+ src += sstride0;
+ rcount[0]++;
+ scount[0]++;
+ /* Advance to the next destination element. */
+ n = 0;
+ while (rcount[n] == rextent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ rcount[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ rptr -= rstride[n] * rextent[n];
+ n++;
+ if (n == rdim)
+ {
+ /* Break out of the loop. */
+ rptr = NULL;
+ break;
+ }
+ else
+ {
+ rcount[n]++;
+ rptr += rstride[n];
+ }
+ }
+ /* Advance to the next source element. */
+ n = 0;
+ while (scount[n] == sextent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ scount[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ src -= sstride[n] * sextent[n];
+ n++;
+ if (n == sdim)
+ {
+ if (sptr && pad)
+ {
+ /* Switch to the pad array. */
+ sptr = NULL;
+ sdim = pdim;
+ for (dim = 0; dim < pdim; dim++)
+ {
+ scount[dim] = pcount[dim];
+ sextent[dim] = pextent[dim];
+ sstride[dim] = pstride[dim];
+ sstride0 = sstride[0];
+ }
+ }
+ /* We now start again from the beginning of the pad array. */
+ src = pptr;
+ break;
+ }
+ else
+ {
+ scount[n]++;
+ src += sstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/reshape_i8.c b/libgfortran/generated/reshape_i8.c
new file mode 100644
index 00000000000..f4e40197d82
--- /dev/null
+++ b/libgfortran/generated/reshape_i8.c
@@ -0,0 +1,225 @@
+/* Implementation of the RESHAPE
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+typedef GFC_ARRAY_DESCRIPTOR(1, index_type) shape_type;
+
+/* The shape parameter is ignored. We can currently deduce the shape from the
+ return array. */
+void
+__reshape_8 (gfc_array_i8 * ret, gfc_array_i8 * source, shape_type * shape,
+ gfc_array_i8 * pad, shape_type * order)
+{
+ /* r.* indicates the return array. */
+ index_type rcount[GFC_MAX_DIMENSIONS - 1];
+ index_type rextent[GFC_MAX_DIMENSIONS - 1];
+ index_type rstride[GFC_MAX_DIMENSIONS - 1];
+ index_type rstride0;
+ index_type rdim;
+ index_type rsize;
+ GFC_INTEGER_8 *rptr;
+ /* s.* indicates the source array. */
+ index_type scount[GFC_MAX_DIMENSIONS - 1];
+ index_type sextent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride0;
+ index_type sdim;
+ index_type ssize;
+ const GFC_INTEGER_8 *sptr;
+ /* p.* indicates the pad array. */
+ index_type pcount[GFC_MAX_DIMENSIONS - 1];
+ index_type pextent[GFC_MAX_DIMENSIONS - 1];
+ index_type pstride[GFC_MAX_DIMENSIONS - 1];
+ index_type pdim;
+ index_type psize;
+ const GFC_INTEGER_8 *pptr;
+
+ const GFC_INTEGER_8 *src;
+ int n;
+ int dim;
+
+ if (ret->dim[0].stride == 0)
+ ret->dim[0].stride = 1;
+ if (source->dim[0].stride == 0)
+ source->dim[0].stride = 1;
+ if (shape->dim[0].stride == 0)
+ shape->dim[0].stride = 1;
+ if (pad && pad->dim[0].stride == 0)
+ pad->dim[0].stride = 1;
+ if (order && order->dim[0].stride == 0)
+ order->dim[0].stride = 1;
+
+ rdim = GFC_DESCRIPTOR_RANK (ret);
+ rsize = 1;
+ for (n = 0; n < rdim; n++)
+ {
+ if (order)
+ dim = order->data[n * order->dim[0].stride] - 1;
+ else
+ dim = n;
+
+ rcount[n] = 0;
+ rstride[n] = ret->dim[dim].stride;
+ rextent[n] = ret->dim[dim].ubound + 1 - ret->dim[dim].lbound;
+
+ if (rextent[n] != shape->data[dim * shape->dim[0].stride])
+ runtime_error ("shape and target do not conform");
+
+ if (rsize == rstride[n])
+ rsize *= rextent[n];
+ else
+ rsize = 0;
+ if (rextent[dim] <= 0)
+ return;
+ }
+
+ sdim = GFC_DESCRIPTOR_RANK (source);
+ ssize = 1;
+ for (n = 0; n < sdim; n++)
+ {
+ scount[n] = 0;
+ sstride[n] = source->dim[n].stride;
+ sextent[n] = source->dim[n].ubound + 1 - source->dim[n].lbound;
+ if (sextent[n] <= 0)
+ abort ();
+
+ if (ssize == sstride[n])
+ ssize *= sextent[n];
+ else
+ ssize = 0;
+ }
+
+ if (pad)
+ {
+ if (pad->dim[0].stride == 0)
+ pad->dim[0].stride = 1;
+ pdim = GFC_DESCRIPTOR_RANK (pad);
+ psize = 1;
+ for (n = 0; n < pdim; n++)
+ {
+ pcount[n] = 0;
+ pstride[n] = pad->dim[n].stride;
+ pextent[n] = pad->dim[n].ubound + 1 - pad->dim[n].lbound;
+ if (pextent[n] <= 0)
+ abort ();
+ if (psize == pstride[n])
+ psize *= pextent[n];
+ else
+ psize = 0;
+ }
+ pptr = pad->data;
+ }
+ else
+ {
+ pdim = 0;
+ psize = 1;
+ pptr = NULL;
+ }
+
+ if (rsize != 0 && ssize != 0 && psize != 0)
+ {
+ rsize *= 8;
+ ssize *= 8;
+ psize *= 8;
+ reshape_packed ((char *)ret->data, rsize, (char *)source->data,
+ ssize, pad ? (char *)pad->data : NULL, psize);
+ return;
+ }
+ rptr = ret->data;
+ src = sptr = source->data;
+ rstride0 = rstride[0];
+ sstride0 = sstride[0];
+
+ while (rptr)
+ {
+ /* Select between the source and pad arrays. */
+ *rptr = *src;
+ /* Advance to the next element. */
+ rptr += rstride0;
+ src += sstride0;
+ rcount[0]++;
+ scount[0]++;
+ /* Advance to the next destination element. */
+ n = 0;
+ while (rcount[n] == rextent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ rcount[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ rptr -= rstride[n] * rextent[n];
+ n++;
+ if (n == rdim)
+ {
+ /* Break out of the loop. */
+ rptr = NULL;
+ break;
+ }
+ else
+ {
+ rcount[n]++;
+ rptr += rstride[n];
+ }
+ }
+ /* Advance to the next source element. */
+ n = 0;
+ while (scount[n] == sextent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ scount[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ src -= sstride[n] * sextent[n];
+ n++;
+ if (n == sdim)
+ {
+ if (sptr && pad)
+ {
+ /* Switch to the pad array. */
+ sptr = NULL;
+ sdim = pdim;
+ for (dim = 0; dim < pdim; dim++)
+ {
+ scount[dim] = pcount[dim];
+ sextent[dim] = pextent[dim];
+ sstride[dim] = pstride[dim];
+ sstride0 = sstride[0];
+ }
+ }
+ /* We now start again from the beginning of the pad array. */
+ src = pptr;
+ break;
+ }
+ else
+ {
+ scount[n]++;
+ src += sstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/generated/set_exponent_r4.c b/libgfortran/generated/set_exponent_r4.c
new file mode 100644
index 00000000000..32717e22305
--- /dev/null
+++ b/libgfortran/generated/set_exponent_r4.c
@@ -0,0 +1,30 @@
+/* Implementation of the SET_EXPONENT intrinsic
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@redhat.com>.
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include <math.h>
+#include "libgfortran.h"
+
+
+GFC_REAL_4
+prefix(set_exponent_r4) (GFC_REAL_4 s, GFC_INTEGER_4 i)
+{
+ int dummy_exp;
+ return scalbnf (frexpf (s, &dummy_exp), i);
+}
diff --git a/libgfortran/generated/set_exponent_r8.c b/libgfortran/generated/set_exponent_r8.c
new file mode 100644
index 00000000000..ad2a97d837b
--- /dev/null
+++ b/libgfortran/generated/set_exponent_r8.c
@@ -0,0 +1,30 @@
+/* Implementation of the SET_EXPONENT intrinsic
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@redhat.com>.
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include <math.h>
+#include "libgfortran.h"
+
+
+GFC_REAL_8
+prefix(set_exponent_r8) (GFC_REAL_8 s, GFC_INTEGER_4 i)
+{
+ int dummy_exp;
+ return scalbn (frexp (s, &dummy_exp), i);
+}
diff --git a/libgfortran/generated/shape_i4.c b/libgfortran/generated/shape_i4.c
new file mode 100644
index 00000000000..03446912f61
--- /dev/null
+++ b/libgfortran/generated/shape_i4.c
@@ -0,0 +1,43 @@
+/* Implementation of the SHAPE intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+void
+__shape_4 (gfc_array_i4 * ret, const gfc_array_i4 * array)
+{
+ int n;
+ index_type stride;
+
+ stride = ret->dim[0].stride;
+ if (stride == 0)
+ stride = 1;
+
+ for (n = 0; n < GFC_DESCRIPTOR_RANK (array); n++)
+ {
+ ret->data[n * stride] =
+ array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+}
+
diff --git a/libgfortran/generated/shape_i8.c b/libgfortran/generated/shape_i8.c
new file mode 100644
index 00000000000..bd7490016ae
--- /dev/null
+++ b/libgfortran/generated/shape_i8.c
@@ -0,0 +1,43 @@
+/* Implementation of the SHAPE intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+void
+__shape_8 (gfc_array_i8 * ret, const gfc_array_i8 * array)
+{
+ int n;
+ index_type stride;
+
+ stride = ret->dim[0].stride;
+ if (stride == 0)
+ stride = 1;
+
+ for (n = 0; n < GFC_DESCRIPTOR_RANK (array); n++)
+ {
+ ret->data[n * stride] =
+ array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+}
+
diff --git a/libgfortran/generated/sum_c4.c b/libgfortran/generated/sum_c4.c
new file mode 100644
index 00000000000..a6e05b2a4c9
--- /dev/null
+++ b/libgfortran/generated/sum_c4.c
@@ -0,0 +1,252 @@
+/* Implementation of the SUM intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+
+void
+__sum_c4 (gfc_array_c4 * retarray, gfc_array_c4 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_COMPLEX_4 *base;
+ GFC_COMPLEX_4 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_COMPLEX_4 *src;
+ GFC_COMPLEX_4 result;
+ src = base;
+ {
+
+ result = 0;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ result += *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__msum_c4 (gfc_array_c4 * retarray, gfc_array_c4 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_COMPLEX_4 *dest;
+ GFC_COMPLEX_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_COMPLEX_4 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_COMPLEX_4 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ result = 0;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc)
+ result += *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
diff --git a/libgfortran/generated/sum_c8.c b/libgfortran/generated/sum_c8.c
new file mode 100644
index 00000000000..f65002a091b
--- /dev/null
+++ b/libgfortran/generated/sum_c8.c
@@ -0,0 +1,252 @@
+/* Implementation of the SUM intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+
+void
+__sum_c8 (gfc_array_c8 * retarray, gfc_array_c8 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_COMPLEX_8 *base;
+ GFC_COMPLEX_8 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_COMPLEX_8 *src;
+ GFC_COMPLEX_8 result;
+ src = base;
+ {
+
+ result = 0;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ result += *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__msum_c8 (gfc_array_c8 * retarray, gfc_array_c8 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_COMPLEX_8 *dest;
+ GFC_COMPLEX_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_COMPLEX_8 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_COMPLEX_8 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ result = 0;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc)
+ result += *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
diff --git a/libgfortran/generated/sum_i4.c b/libgfortran/generated/sum_i4.c
new file mode 100644
index 00000000000..a15e0d4804f
--- /dev/null
+++ b/libgfortran/generated/sum_i4.c
@@ -0,0 +1,252 @@
+/* Implementation of the SUM intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+
+void
+__sum_i4 (gfc_array_i4 * retarray, gfc_array_i4 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_4 *base;
+ GFC_INTEGER_4 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_INTEGER_4 *src;
+ GFC_INTEGER_4 result;
+ src = base;
+ {
+
+ result = 0;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ result += *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__msum_i4 (gfc_array_i4 * retarray, gfc_array_i4 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_4 *dest;
+ GFC_INTEGER_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_INTEGER_4 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_4 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ result = 0;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc)
+ result += *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
diff --git a/libgfortran/generated/sum_i8.c b/libgfortran/generated/sum_i8.c
new file mode 100644
index 00000000000..2ad5f4ac822
--- /dev/null
+++ b/libgfortran/generated/sum_i8.c
@@ -0,0 +1,252 @@
+/* Implementation of the SUM intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+
+void
+__sum_i8 (gfc_array_i8 * retarray, gfc_array_i8 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_8 *base;
+ GFC_INTEGER_8 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_INTEGER_8 *src;
+ GFC_INTEGER_8 result;
+ src = base;
+ {
+
+ result = 0;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ result += *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__msum_i8 (gfc_array_i8 * retarray, gfc_array_i8 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_INTEGER_8 *dest;
+ GFC_INTEGER_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_INTEGER_8 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_INTEGER_8 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ result = 0;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc)
+ result += *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
diff --git a/libgfortran/generated/sum_r4.c b/libgfortran/generated/sum_r4.c
new file mode 100644
index 00000000000..3b637183256
--- /dev/null
+++ b/libgfortran/generated/sum_r4.c
@@ -0,0 +1,252 @@
+/* Implementation of the SUM intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+
+void
+__sum_r4 (gfc_array_r4 * retarray, gfc_array_r4 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_4 *base;
+ GFC_REAL_4 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_REAL_4 *src;
+ GFC_REAL_4 result;
+ src = base;
+ {
+
+ result = 0;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ result += *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__msum_r4 (gfc_array_r4 * retarray, gfc_array_r4 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_4 *dest;
+ GFC_REAL_4 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_REAL_4 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_REAL_4 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ result = 0;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc)
+ result += *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
diff --git a/libgfortran/generated/sum_r8.c b/libgfortran/generated/sum_r8.c
new file mode 100644
index 00000000000..3aa550bbe8f
--- /dev/null
+++ b/libgfortran/generated/sum_r8.c
@@ -0,0 +1,252 @@
+/* Implementation of the SUM intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+
+void
+__sum_r8 (gfc_array_r8 * retarray, gfc_array_r8 *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_8 *base;
+ GFC_REAL_8 *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ GFC_REAL_8 *src;
+ GFC_REAL_8 result;
+ src = base;
+ {
+
+ result = 0;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+
+ result += *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
+
+void
+__msum_r8 (gfc_array_r8 * retarray, gfc_array_r8 * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ GFC_REAL_8 *dest;
+ GFC_REAL_8 *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ GFC_REAL_8 *src;
+ GFC_LOGICAL_4 *msrc;
+ GFC_REAL_8 result;
+ src = base;
+ msrc = mbase;
+ {
+
+ result = 0;
+ if (len <= 0)
+ *dest = 0;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+
+ if (*msrc)
+ result += *src;
+ }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}
diff --git a/libgfortran/generated/transpose_i4.c b/libgfortran/generated/transpose_i4.c
new file mode 100644
index 00000000000..184243f21d4
--- /dev/null
+++ b/libgfortran/generated/transpose_i4.c
@@ -0,0 +1,69 @@
+/* Implementation of the TRANSPOSE intrinsic
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Tobias Schlüter
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <assert.h>
+#include "libgfortran.h"
+
+void
+__transpose_4 (gfc_array_i4 * ret, gfc_array_i4 * source)
+{
+ /* r.* indicates the return array. */
+ index_type rxstride, rystride;
+ GFC_INTEGER_4 *rptr;
+ /* s.* indicates the source array. */
+ index_type sxstride, systride;
+ const GFC_INTEGER_4 *sptr;
+
+ index_type xcount, ycount;
+ index_type x, y;
+
+ assert (GFC_DESCRIPTOR_RANK (source) == 2);
+
+ if (ret->dim[0].stride == 0)
+ ret->dim[0].stride = 1;
+ if (source->dim[0].stride == 0)
+ source->dim[0].stride = 1;
+
+ sxstride = source->dim[0].stride;
+ systride = source->dim[1].stride;
+ xcount = source->dim[0].ubound + 1 - source->dim[0].lbound;
+ ycount = source->dim[1].ubound + 1 - source->dim[1].lbound;
+
+ rxstride = ret->dim[0].stride;
+ rystride = ret->dim[1].stride;
+
+ rptr = ret->data;
+ sptr = source->data;
+
+ for (y=0; y < ycount; y++)
+ {
+ for (x=0; x < xcount; x++)
+ {
+ *rptr = *sptr;
+
+ sptr += sxstride;
+ rptr += rystride;
+ }
+ sptr += systride - (sxstride * xcount);
+ rptr += rxstride - (rystride * xcount);
+ }
+}
diff --git a/libgfortran/generated/transpose_i8.c b/libgfortran/generated/transpose_i8.c
new file mode 100644
index 00000000000..2dcaa000889
--- /dev/null
+++ b/libgfortran/generated/transpose_i8.c
@@ -0,0 +1,69 @@
+/* Implementation of the TRANSPOSE intrinsic
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Tobias Schlüter
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <assert.h>
+#include "libgfortran.h"
+
+void
+__transpose_8 (gfc_array_i8 * ret, gfc_array_i8 * source)
+{
+ /* r.* indicates the return array. */
+ index_type rxstride, rystride;
+ GFC_INTEGER_8 *rptr;
+ /* s.* indicates the source array. */
+ index_type sxstride, systride;
+ const GFC_INTEGER_8 *sptr;
+
+ index_type xcount, ycount;
+ index_type x, y;
+
+ assert (GFC_DESCRIPTOR_RANK (source) == 2);
+
+ if (ret->dim[0].stride == 0)
+ ret->dim[0].stride = 1;
+ if (source->dim[0].stride == 0)
+ source->dim[0].stride = 1;
+
+ sxstride = source->dim[0].stride;
+ systride = source->dim[1].stride;
+ xcount = source->dim[0].ubound + 1 - source->dim[0].lbound;
+ ycount = source->dim[1].ubound + 1 - source->dim[1].lbound;
+
+ rxstride = ret->dim[0].stride;
+ rystride = ret->dim[1].stride;
+
+ rptr = ret->data;
+ sptr = source->data;
+
+ for (y=0; y < ycount; y++)
+ {
+ for (x=0; x < xcount; x++)
+ {
+ *rptr = *sptr;
+
+ sptr += sxstride;
+ rptr += rystride;
+ }
+ sptr += systride - (sxstride * xcount);
+ rptr += rxstride - (rystride * xcount);
+ }
+}
diff --git a/libgfortran/generated/trig_c4.c b/libgfortran/generated/trig_c4.c
new file mode 100644
index 00000000000..14d12c40144
--- /dev/null
+++ b/libgfortran/generated/trig_c4.c
@@ -0,0 +1,71 @@
+/* Complex trig functions
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include <math.h>
+#include "libgfortran.h"
+
+
+/* Complex number z = a + ib. */
+
+/* sin(z) = sin(a)cosh(b) + icos(a)sinh(b) */
+GFC_COMPLEX_4
+csinf (GFC_COMPLEX_4 a)
+{
+ GFC_REAL_4 r;
+ GFC_REAL_4 i;
+ GFC_COMPLEX_4 v;
+
+ r = REALPART (a);
+ i = IMAGPART (a);
+ COMPLEX_ASSIGN (v, sinf (r) * coshf (i), cosf (r) * sinhf (i));
+ return v;
+}
+
+/* cos(z) = cos(a)cosh(b) - isin(a)sinh(b) */
+GFC_COMPLEX_4
+ccosf (GFC_COMPLEX_4 a)
+{
+ GFC_REAL_4 r;
+ GFC_REAL_4 i;
+ GFC_COMPLEX_4 v;
+
+ r = REALPART (a);
+ i = IMAGPART (a);
+ COMPLEX_ASSIGN (v, cosf (r) * coshf (i), - (sinf (r) * sinhf (i)));
+ return v;
+}
+
+/* tan(z) = (tan(a) + itanh(b)) / (1 - itan(a)tanh(b)) */
+GFC_COMPLEX_4
+ctanf (GFC_COMPLEX_4 a)
+{
+ GFC_REAL_4 rt;
+ GFC_REAL_4 it;
+ GFC_COMPLEX_4 n;
+ GFC_COMPLEX_4 d;
+
+ rt = tanf (REALPART (a));
+ it = tanhf (IMAGPART (a));
+ COMPLEX_ASSIGN (n, rt, it);
+ COMPLEX_ASSIGN (d , 1, - (rt * it));
+
+ return n / d;
+}
+
diff --git a/libgfortran/generated/trig_c8.c b/libgfortran/generated/trig_c8.c
new file mode 100644
index 00000000000..cea4872bdfc
--- /dev/null
+++ b/libgfortran/generated/trig_c8.c
@@ -0,0 +1,71 @@
+/* Complex trig functions
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include <math.h>
+#include "libgfortran.h"
+
+
+/* Complex number z = a + ib. */
+
+/* sin(z) = sin(a)cosh(b) + icos(a)sinh(b) */
+GFC_COMPLEX_8
+csin (GFC_COMPLEX_8 a)
+{
+ GFC_REAL_8 r;
+ GFC_REAL_8 i;
+ GFC_COMPLEX_8 v;
+
+ r = REALPART (a);
+ i = IMAGPART (a);
+ COMPLEX_ASSIGN (v, sin (r) * cosh (i), cos (r) * sinh (i));
+ return v;
+}
+
+/* cos(z) = cos(a)cosh(b) - isin(a)sinh(b) */
+GFC_COMPLEX_8
+ccos (GFC_COMPLEX_8 a)
+{
+ GFC_REAL_8 r;
+ GFC_REAL_8 i;
+ GFC_COMPLEX_8 v;
+
+ r = REALPART (a);
+ i = IMAGPART (a);
+ COMPLEX_ASSIGN (v, cos (r) * cosh (i), - (sin (r) * sinh (i)));
+ return v;
+}
+
+/* tan(z) = (tan(a) + itanh(b)) / (1 - itan(a)tanh(b)) */
+GFC_COMPLEX_8
+ctan (GFC_COMPLEX_8 a)
+{
+ GFC_REAL_8 rt;
+ GFC_REAL_8 it;
+ GFC_COMPLEX_8 n;
+ GFC_COMPLEX_8 d;
+
+ rt = tan (REALPART (a));
+ it = tanh (IMAGPART (a));
+ COMPLEX_ASSIGN (n, rt, it);
+ COMPLEX_ASSIGN (d , 1, - (rt * it));
+
+ return n / d;
+}
+
diff --git a/libgfortran/intrinsics/abort.c b/libgfortran/intrinsics/abort.c
new file mode 100644
index 00000000000..26a25362a7d
--- /dev/null
+++ b/libgfortran/intrinsics/abort.c
@@ -0,0 +1,31 @@
+/* Implementation of the ABORT intrinsic.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "libgfortran.h"
+#include <assert.h>
+
+
+void prefix(abort) (void);
+
+void prefix(abort) ()
+{
+ abort ();
+}
+
diff --git a/libgfortran/intrinsics/associated.c b/libgfortran/intrinsics/associated.c
new file mode 100644
index 00000000000..ba52a205d12
--- /dev/null
+++ b/libgfortran/intrinsics/associated.c
@@ -0,0 +1,50 @@
+/* Implementation of the ASSOCIATED intrinsic
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by kejia Zhao (CCRG) <kejia_zh@yahoo.com.cn>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "libgfortran.h"
+
+#define associated prefix(associated)
+
+enum { FALSE = 0, TRUE = 1 };
+
+
+GFC_LOGICAL_4
+associated (const gfc_array_void *pointer, const gfc_array_void *target)
+{
+ int n, rank;
+
+ if (GFC_DESCRIPTOR_DATA (pointer) != GFC_DESCRIPTOR_DATA (target))
+ return FALSE;
+ if (GFC_DESCRIPTOR_DTYPE (pointer) != GFC_DESCRIPTOR_DTYPE (target))
+ return FALSE;
+
+ rank = GFC_DESCRIPTOR_RANK (pointer);
+ for (n = 0; n < rank; n++)
+ {
+ if (pointer->dim[n].stride != target->dim[n].stride)
+ return FALSE;
+ if ((pointer->dim[n].ubound - pointer->dim[n].lbound)
+ != (target->dim[n].ubound - target->dim[n].lbound))
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/libgfortran/intrinsics/cpu_time.c b/libgfortran/intrinsics/cpu_time.c
new file mode 100644
index 00000000000..9fd954b9a71
--- /dev/null
+++ b/libgfortran/intrinsics/cpu_time.c
@@ -0,0 +1,116 @@
+/* Implementation of the CPU_TIME intrinsic.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <sys/types.h>
+#include "libgfortran.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* The CPU_TIME intrinsic to "compare different algorithms on the same
+ computer or discover which parts are the most expensive", so we
+ need a way to get the CPU time with the finest resolution possible.
+ We can only be accurate up to microseconds.
+
+ As usual with UNIX systems, unfortunately no single way is
+ available for all systems. */
+
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# ifdef HAVE_TIME_H
+# include <time.h>
+# endif
+# endif
+#endif
+
+/* The most accurate way to get the CPU time is getrusage ().
+ If we have times(), that's good enough, too. */
+#if defined (HAVE_GETRUSAGE) && defined (HAVE_SYS_RESOURCE_H)
+# include <sys/resource.h>
+#else
+/* For times(), we _must_ know the number of clock ticks per second. */
+# if defined (HAVE_TIMES) && (defined (HZ) || defined (_SC_CLK_TCK) || defined (CLK_TCK))
+# ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# endif
+# include <sys/times.h>
+# ifndef HZ
+# if defined _SC_CLK_TCK
+# define HZ sysconf(_SC_CLK_TCK)
+# else
+# define HZ CLK_TCK
+# endif
+# endif
+# endif /* HAVE_TIMES etc. */
+#endif /* HAVE_GETRUSAGE && HAVE_SYS_RESOURCE_H */
+
+#if defined (__GNUC__) && (__GNUC__ >= 3)
+# define ATTRIBUTE_ALWAYS_INLINE __attribute__ ((__always_inline__))
+#else
+# define ATTRIBUTE_ALWAYS_INLINE
+#endif
+
+static inline void __cpu_time_1 (long *, long *) ATTRIBUTE_ALWAYS_INLINE;
+
+/* Helper function for the actual implementation of the CPU_TIME
+ intrnsic. Returns a CPU time in microseconds or -1 if no CPU time
+ could be computed. */
+static inline void
+__cpu_time_1 (long *sec, long *usec)
+{
+#if defined (HAVE_GETRUSAGE) && defined (HAVE_SYS_RESOURCE_H)
+ struct rusage usage;
+ getrusage (0, &usage);
+ *sec = usage.ru_utime.tv_sec + usage.ru_stime.tv_sec;
+ *usec = usage.ru_utime.tv_usec + usage.ru_stime.tv_usec;
+#else /* ! HAVE_GETRUSAGE || ! HAVE_SYS_RESOURCE_H */
+#ifdef HAVE_TIMES
+ struct tms buf;
+ times (&buf);
+ *sec = 0;
+ *usec = (buf.tms_utime + buf.tms_stime) * (1000000 / HZ);
+#else /* ! HAVE_TIMES */
+ /* We have nothing to go on. Return -1. */
+ *sec = -1;
+ *usec = 0;
+#endif /* HAVE_TIMES */
+#endif /* HAVE_GETRUSAGE */
+}
+
+#undef CPU_TIME
+#define CPU_TIME(KIND) \
+void prefix(cpu_time_##KIND) (GFC_REAL_##KIND *__time) \
+{ \
+ long sec, usec; \
+ __cpu_time_1 (&sec, &usec); \
+ *__time = (GFC_REAL_##KIND) sec + \
+ ((GFC_REAL_##KIND) usec) * 1.e-6; \
+}
+
+CPU_TIME(4)
+CPU_TIME(8)
+
diff --git a/libgfortran/intrinsics/cshift0.c b/libgfortran/intrinsics/cshift0.c
new file mode 100644
index 00000000000..5a2c8caabe4
--- /dev/null
+++ b/libgfortran/intrinsics/cshift0.c
@@ -0,0 +1,169 @@
+/* Generic implementation of the CSHIFT intrinsic
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Feng Wang <wf_cs@yahoo.com>
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "libgfortran.h"
+
+/* TODO: make this work for large shifts when
+ sizeof(int) < sizeof (index_type). */
+
+static void
+__cshift0 (const gfc_array_char * ret, const gfc_array_char * array,
+ int shift, int which)
+{
+ /* r.* indicates the return array. */
+ index_type rstride[GFC_MAX_DIMENSIONS - 1];
+ index_type rstride0;
+ index_type roffset;
+ char *rptr;
+ char *dest;
+ /* s.* indicates the source array. */
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride0;
+ index_type soffset;
+ const char *sptr;
+ const char *src;
+
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type dim;
+ index_type size;
+ index_type len;
+ index_type n;
+
+ if (which < 1 || which > GFC_DESCRIPTOR_RANK (array))
+ runtime_error ("Argument 'DIM' is out of range in call to 'CSHIFT'");
+
+ size = GFC_DESCRIPTOR_SIZE (ret);
+
+ which = which - 1;
+
+ extent[0] = 1;
+ count[0] = 0;
+ size = GFC_DESCRIPTOR_SIZE (array);
+ n = 0;
+
+/* Initialized for avoiding compiler warnings. */
+ roffset = size;
+ soffset = size;
+ len = 0;
+
+ for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
+ {
+ if (dim == which)
+ {
+ roffset = ret->dim[dim].stride * size;
+ if (roffset == 0)
+ roffset = size;
+ soffset = array->dim[dim].stride * size;
+ if (soffset == 0)
+ soffset = size;
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ }
+ else
+ {
+ count[n] = 0;
+ extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ rstride[n] = ret->dim[dim].stride * size;
+ sstride[n] = array->dim[dim].stride * size;
+ n++;
+ }
+ }
+ if (sstride[0] == 0)
+ sstride[0] = size;
+ if (rstride[0] == 0)
+ rstride[0] = size;
+
+ dim = GFC_DESCRIPTOR_RANK (array);
+ rstride0 = rstride[0];
+ sstride0 = sstride[0];
+ rptr = ret->data;
+ sptr = array->data;
+
+ shift = (div (shift, len)).rem;
+ if (shift < 0)
+ shift += len;
+
+ while (rptr)
+ {
+ /* Do the shift for this dimension. */
+ src = &sptr[shift * soffset];
+ dest = rptr;
+ for (n = 0; n < len; n++)
+ {
+ memcpy (dest, src, size);
+ dest += roffset;
+ if (n == len - shift - 1)
+ src = sptr;
+ else
+ src += soffset;
+ }
+
+ /* Advance to the next section. */
+ rptr += rstride0;
+ sptr += sstride0;
+ count[0]++;
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ rptr -= rstride[n] * extent[n];
+ sptr -= sstride[n] * extent[n];
+ n++;
+ if (n >= dim - 1)
+ {
+ /* Break out of the loop. */
+ rptr = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ rptr += rstride[n];
+ sptr += sstride[n];
+ }
+ }
+ }
+}
+
+
+void
+__cshift0_4 (const gfc_array_char * ret, const gfc_array_char * array,
+ const GFC_INTEGER_4 * pshift, const GFC_INTEGER_4 * pdim)
+{
+ __cshift0 (ret, array, *pshift, pdim ? *pdim : 1);
+}
+
+
+void
+__cshift0_8 (const gfc_array_char * ret, const gfc_array_char * array,
+ const GFC_INTEGER_8 * pshift, const GFC_INTEGER_8 * pdim)
+{
+ __cshift0 (ret, array, *pshift, pdim ? *pdim : 1);
+}
+
diff --git a/libgfortran/intrinsics/dprod_r8.f90 b/libgfortran/intrinsics/dprod_r8.f90
new file mode 100644
index 00000000000..d0f2063d142
--- /dev/null
+++ b/libgfortran/intrinsics/dprod_r8.f90
@@ -0,0 +1,27 @@
+! Copyright 2003 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfortran).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+
+
+elemental function specific__dprod_r8 (p1, p2)
+ real (kind=4), intent (in) :: p1, p2
+ real (kind=8) :: specific__dprod_r8
+
+ specific__dprod_r8 = dprod (p1, p2)
+end function
diff --git a/libgfortran/intrinsics/eoshift0.c b/libgfortran/intrinsics/eoshift0.c
new file mode 100644
index 00000000000..f86f4bd883f
--- /dev/null
+++ b/libgfortran/intrinsics/eoshift0.c
@@ -0,0 +1,188 @@
+/* Generic implementation of the RESHAPE intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "libgfortran.h"
+
+static const char zeros[16] =
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+/* TODO: make this work for large shifts when
+ sizeof(int) < sizeof (index_type). */
+
+static void
+__eoshift0 (const gfc_array_char * ret, const gfc_array_char * array,
+ int shift, const char * pbound, int which)
+{
+ /* r.* indicates the return array. */
+ index_type rstride[GFC_MAX_DIMENSIONS - 1];
+ index_type rstride0;
+ index_type roffset;
+ char *rptr;
+ char *dest;
+ /* s.* indicates the source array. */
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride0;
+ index_type soffset;
+ const char *sptr;
+ const char *src;
+
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type dim;
+ index_type size;
+ index_type len;
+ index_type n;
+
+ if (!pbound)
+ pbound = zeros;
+
+ size = GFC_DESCRIPTOR_SIZE (ret);
+
+ which = which - 1;
+
+ extent[0] = 1;
+ count[0] = 0;
+ size = GFC_DESCRIPTOR_SIZE (array);
+ n = 0;
+ for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
+ {
+ if (dim == which)
+ {
+ roffset = ret->dim[dim].stride * size;
+ if (roffset == 0)
+ roffset = size;
+ soffset = array->dim[dim].stride * size;
+ if (soffset == 0)
+ soffset = size;
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ }
+ else
+ {
+ count[n] = 0;
+ extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ rstride[n] = ret->dim[dim].stride * size;
+ sstride[n] = array->dim[dim].stride * size;
+ n++;
+ }
+ }
+ if (sstride[0] == 0)
+ sstride[0] = size;
+ if (rstride[0] == 0)
+ rstride[0] = size;
+
+ dim = GFC_DESCRIPTOR_RANK (array);
+ rstride0 = rstride[0];
+ sstride0 = sstride[0];
+ rptr = ret->data;
+ sptr = array->data;
+ if (shift > 0)
+ len = len - shift;
+ else
+ len = len + shift;
+
+ while (rptr)
+ {
+ /* Do the shift for this dimension. */
+ if (shift > 0)
+ {
+ src = &sptr[shift * soffset];
+ dest = rptr;
+ }
+ else
+ {
+ src = sptr;
+ dest = &rptr[-shift * roffset];
+ }
+ for (n = 0; n < len; n++)
+ {
+ memcpy (dest, src, size);
+ dest += roffset;
+ src += soffset;
+ }
+ if (shift >= 0)
+ {
+ n = shift;
+ }
+ else
+ {
+ dest = rptr;
+ n = -shift;
+ }
+
+ while (n--)
+ {
+ memcpy (dest, pbound, size);
+ dest += roffset;
+ }
+
+ /* Advance to the next section. */
+ rptr += rstride0;
+ sptr += sstride0;
+ count[0]++;
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ rptr -= rstride[n] * extent[n];
+ sptr -= sstride[n] * extent[n];
+ n++;
+ if (n >= dim - 1)
+ {
+ /* Break out of the loop. */
+ rptr = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ rptr += rstride[n];
+ sptr += sstride[n];
+ }
+ }
+ }
+}
+
+
+void
+__eoshift0_4 (const gfc_array_char * ret, const gfc_array_char * array,
+ const GFC_INTEGER_4 * pshift, const char * pbound,
+ const GFC_INTEGER_4 * pdim)
+{
+ __eoshift0 (ret, array, *pshift, pbound, pdim ? *pdim : 1);
+}
+
+
+void
+__eoshift0_8 (const gfc_array_char * ret, const gfc_array_char * array,
+ const GFC_INTEGER_8 * pshift, const char * pbound,
+ const GFC_INTEGER_8 * pdim)
+{
+ __eoshift0 (ret, array, *pshift, pbound, pdim ? *pdim : 1);
+}
+
diff --git a/libgfortran/intrinsics/eoshift2.c b/libgfortran/intrinsics/eoshift2.c
new file mode 100644
index 00000000000..038588f78d2
--- /dev/null
+++ b/libgfortran/intrinsics/eoshift2.c
@@ -0,0 +1,204 @@
+/* Generic implementation of the RESHAPE intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "libgfortran.h"
+
+static const char zeros[16] =
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+/* TODO: make this work for large shifts when
+ sizeof(int) < sizeof (index_type). */
+
+static void
+__eoshift2 (const gfc_array_char * ret, const gfc_array_char * array,
+ int shift, const gfc_array_char * bound, int which)
+{
+ /* r.* indicates the return array. */
+ index_type rstride[GFC_MAX_DIMENSIONS - 1];
+ index_type rstride0;
+ index_type roffset;
+ char *rptr;
+ char *dest;
+ /* s.* indicates the source array. */
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride0;
+ index_type soffset;
+ const char *sptr;
+ const char *src;
+ /* b.* indicates the bound array. */
+ index_type bstride[GFC_MAX_DIMENSIONS - 1];
+ index_type bstride0;
+ const char *bptr;
+
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type dim;
+ index_type size;
+ index_type len;
+ index_type n;
+
+ size = GFC_DESCRIPTOR_SIZE (ret);
+
+ which = which - 1;
+
+ extent[0] = 1;
+ count[0] = 0;
+ size = GFC_DESCRIPTOR_SIZE (array);
+ n = 0;
+ for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
+ {
+ if (dim == which)
+ {
+ roffset = ret->dim[dim].stride * size;
+ if (roffset == 0)
+ roffset = size;
+ soffset = array->dim[dim].stride * size;
+ if (soffset == 0)
+ soffset = size;
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ }
+ else
+ {
+ count[n] = 0;
+ extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ rstride[n] = ret->dim[dim].stride * size;
+ sstride[n] = array->dim[dim].stride * size;
+ if (bound)
+ bstride[n] = bound->dim[n].stride * size;
+ else
+ bstride[n] = 0;
+ n++;
+ }
+ }
+ if (sstride[0] == 0)
+ sstride[0] = size;
+ if (rstride[0] == 0)
+ rstride[0] = size;
+ if (bound && bstride[0] == 0)
+ bstride[0] = size;
+
+ dim = GFC_DESCRIPTOR_RANK (array);
+ rstride0 = rstride[0];
+ sstride0 = sstride[0];
+ bstride0 = bstride[0];
+ rptr = ret->data;
+ sptr = array->data;
+ if (bound)
+ bptr = bound->data;
+ else
+ bptr = zeros;
+
+ if (shift > 0)
+ len = len - shift;
+ else
+ len = len + shift;
+
+ while (rptr)
+ {
+ /* Do the shift for this dimension. */
+ if (shift > 0)
+ {
+ src = &sptr[shift * soffset];
+ dest = rptr;
+ }
+ else
+ {
+ src = sptr;
+ dest = &rptr[-shift * roffset];
+ }
+ for (n = 0; n < len; n++)
+ {
+ memcpy (dest, src, size);
+ dest += roffset;
+ src += soffset;
+ }
+ if (shift >= 0)
+ {
+ n = shift;
+ }
+ else
+ {
+ dest = rptr;
+ n = -shift;
+ }
+
+ while (n--)
+ {
+ memcpy (dest, bptr, size);
+ dest += roffset;
+ }
+
+ /* Advance to the next section. */
+ rptr += rstride0;
+ sptr += sstride0;
+ bptr += bstride0;
+ count[0]++;
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ rptr -= rstride[n] * extent[n];
+ sptr -= sstride[n] * extent[n];
+ bptr -= bstride[n] * extent[n];
+ n++;
+ if (n >= dim - 1)
+ {
+ /* Break out of the loop. */
+ rptr = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ rptr += rstride[n];
+ sptr += sstride[n];
+ bptr += bstride[n];
+ }
+ }
+ }
+}
+
+
+void
+__eoshift2_4 (const gfc_array_char * ret, const gfc_array_char * array,
+ const GFC_INTEGER_4 * pshift, const gfc_array_char * bound,
+ const GFC_INTEGER_4 * pdim)
+{
+ __eoshift2 (ret, array, *pshift, bound, pdim ? *pdim : 1);
+}
+
+
+void
+__eoshift2_8 (const gfc_array_char * ret, const gfc_array_char * array,
+ const GFC_INTEGER_8 * pshift, const gfc_array_char * bound,
+ const GFC_INTEGER_8 * pdim)
+{
+ __eoshift2 (ret, array, *pshift, bound, pdim ? *pdim : 1);
+}
+
diff --git a/libgfortran/intrinsics/ishftc.c b/libgfortran/intrinsics/ishftc.c
new file mode 100644
index 00000000000..0bb3d422eb2
--- /dev/null
+++ b/libgfortran/intrinsics/ishftc.c
@@ -0,0 +1,64 @@
+/* Implementation of ishftc intrinsic.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "libgfortran.h"
+
+#define ishftc4 prefix(ishftc4)
+GFC_INTEGER_4 ishftc4 (GFC_INTEGER_4, GFC_INTEGER_4, GFC_INTEGER_4);
+
+#define ishftc8 prefix(ishftc8)
+GFC_INTEGER_8 ishftc8 (GFC_INTEGER_8, GFC_INTEGER_8, GFC_INTEGER_8);
+
+GFC_INTEGER_4
+ishftc4 (GFC_INTEGER_4 i, GFC_INTEGER_4 shift, GFC_INTEGER_4 size)
+{
+ GFC_INTEGER_4 mask;
+ GFC_UINTEGER_4 bits;
+
+ if (shift < 0)
+ shift = shift + size;
+
+ if (shift == 0 || shift == size)
+ return i;
+
+ mask = (~(GFC_INTEGER_4)0) << size;
+ bits = i & ~mask;
+ return (i & mask) | (bits >> (size - shift)) | ((i << shift) & ~mask);
+}
+
+
+GFC_INTEGER_8
+ishftc8 (GFC_INTEGER_8 i, GFC_INTEGER_8 shift, GFC_INTEGER_8 size)
+{
+ GFC_INTEGER_8 mask;
+ GFC_UINTEGER_8 bits;
+
+ if (shift < 0)
+ shift = shift + size;
+
+ if (shift == 0 || shift == size)
+ return i;
+
+ mask = (~(GFC_INTEGER_8)0) << size;
+ bits = i & ~mask;
+ return (i & mask) | (bits >> (size - shift)) | ((i << shift) & ~mask);
+}
+
diff --git a/libgfortran/intrinsics/pack_generic.c b/libgfortran/intrinsics/pack_generic.c
new file mode 100644
index 00000000000..08c022e4e74
--- /dev/null
+++ b/libgfortran/intrinsics/pack_generic.c
@@ -0,0 +1,146 @@
+/* Generic implementation of the RESHAPE intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "libgfortran.h"
+
+void
+__pack (const gfc_array_char * ret, const gfc_array_char * array,
+ const gfc_array_l4 * mask, const gfc_array_char * vector)
+{
+ /* r.* indicates the return array. */
+ index_type rstride0;
+ char *rptr;
+ /* s.* indicates the source array. */
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type sstride0;
+ const char *sptr;
+ /* m.* indicates the mask array. */
+ index_type mstride[GFC_MAX_DIMENSIONS];
+ index_type mstride0;
+ const GFC_LOGICAL_4 *mptr;
+
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type n;
+ index_type dim;
+ index_type size;
+ index_type nelem;
+
+ size = GFC_DESCRIPTOR_SIZE (array);
+ dim = GFC_DESCRIPTOR_RANK (array);
+ for (n = 0; n < dim; n++)
+ {
+ count[n] = 0;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ sstride[n] = array->dim[n].stride * size;
+ mstride[n] = mask->dim[n].stride;
+ }
+ if (sstride[0] == 0)
+ sstride[0] = size;
+ if (mstride[0] == 0)
+ mstride[0] = 1;
+
+ rstride0 = ret->dim[0].stride * size;
+ if (rstride0 == 0)
+ rstride0 = size;
+ sstride0 = sstride[0];
+ mstride0 = mstride[0];
+ rptr = ret->data;
+ sptr = array->data;
+ mptr = mask->data;
+
+ /* Use the same loop for both logical types. */
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ if (GFC_DESCRIPTOR_SIZE (mask) != 8)
+ runtime_error ("Funny sized logical array");
+ for (n = 0; n < dim; n++)
+ mstride[n] <<= 1;
+ mstride0 <<= 1;
+ mptr = GFOR_POINTER_L8_TO_L4 (mptr);
+ }
+
+ while (sptr)
+ {
+ /* Test this element. */
+ if (*mptr)
+ {
+ /* Add it. */
+ memcpy (rptr, sptr, size);
+ rptr += rstride0;
+ }
+ /* Advance to the next element. */
+ sptr += sstride0;
+ mptr += mstride0;
+ count[0]++;
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ sptr -= sstride[n] * extent[n];
+ mptr -= mstride[n] * extent[n];
+ n++;
+ if (n >= dim)
+ {
+ /* Break out of the loop. */
+ sptr = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ sptr += sstride[n];
+ mptr += mstride[n];
+ }
+ }
+ }
+
+ /* Add any remaining elements from VECTOR. */
+ if (vector)
+ {
+ n = vector->dim[0].ubound + 1 - vector->dim[0].lbound;
+ nelem = ((rptr - ret->data) / rstride0);
+ if (n > nelem)
+ {
+ sstride0 = vector->dim[0].stride * size;
+ if (sstride0 == 0)
+ sstride0 = size;
+
+ sptr = vector->data + sstride0 * nelem;
+ n -= nelem;
+ while (n--)
+ {
+ memcpy (rptr, sptr, size);
+ rptr += rstride0;
+ sptr += sstride0;
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/intrinsics/random.c b/libgfortran/intrinsics/random.c
new file mode 100644
index 00000000000..120c9517fa2
--- /dev/null
+++ b/libgfortran/intrinsics/random.c
@@ -0,0 +1,361 @@
+/* Implementation of the RANDOM intrinsics
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Lars Segerlund <seger@linuxmail.org>
+
+ The algorithm was taken from the paper :
+
+ Mersenne Twister: 623-dimensionally equidistributed
+ uniform pseudorandom generator.
+
+ by: Makoto Matsumoto
+ Takuji Nishimura
+
+ Which appeared in the: ACM Transactions on Modelling and Computer
+ Simulations: Special Issue on Uniform Random Number
+ Generation. ( Early in 1998 ).
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+/*Use the 'big' generator by default ( period -> 2**19937 ). */
+
+#define MT19937
+
+/* Define the necessary constants for the algorithm. */
+
+#ifdef MT19937
+enum constants
+{
+ N = 624, M = 397, R = 19, TU = 11, TS = 7, TT = 15, TL = 17
+};
+#define M_A 0x9908B0DF
+#define T_B 0x9D2C5680
+#define T_C 0xEFC60000
+#else
+enum constants
+{
+ N = 351, M = 175, R = 19, TU = 11, TS = 7, TT = 15, TL = 17
+};
+#define M_A 0xE4BD75F5
+#define T_B 0x655E5280
+#define T_C 0xFFD58000
+#endif
+
+static int i = N;
+static unsigned int seed[N];
+
+/* This is the routine which handles the seeding of the generator,
+ and also reading and writing of the seed. */
+
+void
+random_seed (GFC_INTEGER_4 * size, const gfc_array_i4 * put,
+ const gfc_array_i4 * get)
+{
+ /* Initialize the seed in system dependent manner. */
+ if (get == NULL && put == NULL && size == NULL)
+ {
+ int fd;
+ fd = open ("/dev/urandom", O_RDONLY);
+ if (fd == 0)
+ {
+ /* We dont have urandom. */
+ GFC_UINTEGER_4 s = (GFC_UINTEGER_4) seed;
+ for (i = 0; i < N; i++)
+ {
+ s = s * 29943829 - 1;
+ seed[i] = s;
+ }
+ }
+ else
+ {
+ /* Using urandom, might have a length issue. */
+ read (fd, &seed[0], sizeof (GFC_UINTEGER_4) * N);
+ close (fd);
+ }
+ return;
+ }
+
+ /* Return the size of the seed */
+ if (size != NULL)
+ {
+ *size = N;
+ return;
+ }
+
+ /* if we have gotten to this pount we have a get or put
+ * now we check it the array fulfills the demands in the standard .
+ */
+
+ /* Set the seed to PUT data */
+ if (put != NULL)
+ {
+ /* if the rank of the array is not 1 abort */
+ if (GFC_DESCRIPTOR_RANK (put) != 1)
+ abort ();
+
+ /* if the array is too small abort */
+ if (((put->dim[0].ubound + 1 - put->dim[0].lbound)) < N)
+ abort ();
+
+ /* If this is the case the array is a temporary */
+ if (get->dim[0].stride == 0)
+ return;
+
+ /* This code now should do correct strides. */
+ for (i = 0; i < N; i++)
+ seed[i] = put->data[i * put->dim[0].stride];
+ }
+
+ /* Return the seed to GET data */
+ if (get != NULL)
+ {
+ /* if the rank of the array is not 1 abort */
+ if (GFC_DESCRIPTOR_RANK (get) != 1)
+ abort ();
+
+ /* if the array is too small abort */
+ if (((get->dim[0].ubound + 1 - get->dim[0].lbound)) < N)
+ abort ();
+
+ /* If this is the case the array is a temporary */
+ if (get->dim[0].stride == 0)
+ return;
+
+ /* This code now should do correct strides. */
+ for (i = 0; i < N; i++)
+ get->data[i * get->dim[0].stride] = seed[i];
+ }
+}
+
+/* Here is the internal routine which generates the random numbers
+ in 'batches' based upon the need for a new batch.
+ It's an integer based routine known as 'Mersenne Twister'.
+ This implementation still lacks 'tempering' and a good verification,
+ but gives very good metrics. */
+
+static void
+random_generate (void)
+{
+ /* 32 bits. */
+ GFC_UINTEGER_4 y;
+
+ /* Generate batch of N. */
+ int k, m;
+ for (k = 0, m = M; k < N - 1; k++)
+ {
+ y = (seed[k] & (-1 << R)) | (seed[k + 1] & ((1u << R) - 1));
+ seed[k] = seed[m] ^ (y >> 1) ^ (-(GFC_INTEGER_4) (y & 1) & M_A);
+ if (++m >= N)
+ m = 0;
+ }
+
+ y = (seed[N - 1] & (-1 << R)) | (seed[0] & ((1u << R) - 1));
+ seed[N - 1] = seed[M - 1] ^ (y >> 1) ^ (-(GFC_INTEGER_4) (y & 1) & M_A);
+ i = 0;
+}
+
+/* A routine to return a REAL(KIND=4). */
+
+#define random_r4 prefix(random_r4)
+void
+random_r4 (GFC_REAL_4 * harv)
+{
+ /* Regenerate if we need to. */
+ if (i >= N)
+ random_generate ();
+
+ /* Convert uint32 to REAL(KIND=4). */
+ *harv = (GFC_REAL_4) ((GFC_REAL_4) (GFC_UINTEGER_4) seed[i++] /
+ (GFC_REAL_4) (~(GFC_UINTEGER_4) 0));
+}
+
+/* A routine to return a REAL(KIND=8). */
+
+#define random_r8 prefix(random_r8)
+void
+random_r8 (GFC_REAL_8 * harv)
+{
+ /* Regenerate if we need to, may waste one 32-bit value. */
+ if ((i + 1) >= N)
+ random_generate ();
+
+ /* Convert two uint32 to a REAL(KIND=8). */
+ *harv = ((GFC_REAL_8) ((((GFC_UINTEGER_8) seed[i+1]) << 32) + seed[i])) /
+ (GFC_REAL_8) (~(GFC_UINTEGER_8) 0);
+ i += 2;
+}
+
+/* Code to handle arrays will follow here. */
+
+/* REAL(KIND=4) REAL array. */
+
+#define arandom_r4 prefix(arandom_r4)
+void
+arandom_r4 (gfc_array_r4 * harv)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type stride[GFC_MAX_DIMENSIONS - 1];
+ index_type stride0;
+ index_type dim;
+ GFC_REAL_4 *dest;
+ int n;
+
+ dest = harv->data;
+
+ if (harv->dim[0].stride == 0)
+ harv->dim[0].stride = 1;
+
+ dim = GFC_DESCRIPTOR_RANK (harv);
+
+ for (n = 0; n < dim; n++)
+ {
+ count[n] = 0;
+ stride[n] = harv->dim[n].stride;
+ extent[n] = harv->dim[n].ubound + 1 - harv->dim[n].lbound;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ stride0 = stride[0];
+
+ while (dest)
+ {
+ /* Set the elements. */
+
+ /* regenerate if we need to */
+ if (i >= N)
+ random_generate ();
+
+ /* Convert uint32 to float in a hopefully g95 compiant manner */
+ *dest = (GFC_REAL_4) ((GFC_REAL_4) (GFC_UINTEGER_4) seed[i++] /
+ (GFC_REAL_4) (~(GFC_UINTEGER_4) 0));
+
+ /* Advance to the next element. */
+ dest += stride0;
+ count[0]++;
+ /* Advance to the next source element. */
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension,
+ reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products,
+ but this is a less
+ frequently used path so proabably not worth it. */
+ dest -= stride[n] * extent[n];
+ n++;
+ if (n == dim)
+ {
+ dest = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ dest += stride[n];
+ }
+ }
+ }
+}
+
+/* REAL(KIND=8) array. */
+
+#define arandom_r8 prefix(arandom_r8)
+void
+arandom_r8 (gfc_array_r8 * harv)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type stride[GFC_MAX_DIMENSIONS - 1];
+ index_type stride0;
+ index_type dim;
+ GFC_REAL_8 *dest;
+ int n;
+
+ dest = harv->data;
+
+ if (harv->dim[0].stride == 0)
+ harv->dim[0].stride = 1;
+
+ dim = GFC_DESCRIPTOR_RANK (harv);
+
+ for (n = 0; n < dim; n++)
+ {
+ count[n] = 0;
+ stride[n] = harv->dim[n].stride;
+ extent[n] = harv->dim[n].ubound + 1 - harv->dim[n].lbound;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ stride0 = stride[0];
+
+ while (dest)
+ {
+ /* Set the elements. */
+
+ /* regenerate if we need to, may waste one 32-bit value */
+ if ((i + 1) >= N)
+ random_generate ();
+
+ /* Convert two uint32 to a REAL(KIND=8). */
+ *dest = ((GFC_REAL_8) ((((GFC_UINTEGER_8) seed[i+1]) << 32) + seed[i])) /
+ (GFC_REAL_8) (~(GFC_UINTEGER_8) 0);
+ i += 2;
+
+ /* Advance to the next element. */
+ dest += stride0;
+ count[0]++;
+ /* Advance to the next source element. */
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension,
+ reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products,
+ but this is a less
+ frequently used path so proabably not worth it. */
+ dest -= stride[n] * extent[n];
+ n++;
+ if (n == dim)
+ {
+ dest = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ dest += stride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/intrinsics/reshape_generic.c b/libgfortran/intrinsics/reshape_generic.c
new file mode 100644
index 00000000000..ca6f6aacd00
--- /dev/null
+++ b/libgfortran/intrinsics/reshape_generic.c
@@ -0,0 +1,231 @@
+/* Generic implementation of the RESHAPE intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+typedef GFC_ARRAY_DESCRIPTOR(1, index_type) shape_type;
+typedef GFC_ARRAY_DESCRIPTOR(GFC_MAX_DIMENSIONS, char) parray;
+
+
+/* The shape parameter is ignored. We can currently deduce the shape from the
+ return array. */
+
+void
+__reshape (parray * ret, parray * source, shape_type * shape,
+ parray * pad, shape_type * order)
+{
+ /* r.* indicates the return array. */
+ index_type rcount[GFC_MAX_DIMENSIONS - 1];
+ index_type rextent[GFC_MAX_DIMENSIONS - 1];
+ index_type rstride[GFC_MAX_DIMENSIONS - 1];
+ index_type rstride0;
+ index_type rdim;
+ index_type rsize;
+ char *rptr;
+ /* s.* indicates the source array. */
+ index_type scount[GFC_MAX_DIMENSIONS - 1];
+ index_type sextent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride0;
+ index_type sdim;
+ index_type ssize;
+ const char *sptr;
+ /* p.* indicates the pad array. */
+ index_type pcount[GFC_MAX_DIMENSIONS - 1];
+ index_type pextent[GFC_MAX_DIMENSIONS - 1];
+ index_type pstride[GFC_MAX_DIMENSIONS - 1];
+ index_type pdim;
+ index_type psize;
+ const char *pptr;
+
+ const char *src;
+ int n;
+ int dim;
+ int size;
+
+ size = GFC_DESCRIPTOR_SIZE (ret);
+ if (ret->dim[0].stride == 0)
+ ret->dim[0].stride = 1;
+ if (source->dim[0].stride == 0)
+ source->dim[0].stride = 1;
+ if (shape->dim[0].stride == 0)
+ shape->dim[0].stride = 1;
+ if (pad && pad->dim[0].stride == 0)
+ pad->dim[0].stride = 1;
+ if (order && order->dim[0].stride == 0)
+ order->dim[0].stride = 1;
+
+ rdim = GFC_DESCRIPTOR_RANK (ret);
+ rsize = 1;
+ for (n = 0; n < rdim; n++)
+ {
+ if (order)
+ dim = order->data[n * order->dim[0].stride] - 1;
+ else
+ dim = n;
+
+ rcount[n] = 0;
+ rstride[n] = ret->dim[dim].stride;
+ rextent[n] = ret->dim[dim].ubound + 1 - ret->dim[dim].lbound;
+
+ if (rextent[n] != shape->data[dim * shape->dim[0].stride])
+ runtime_error ("shape and target do not conform");
+
+ if (rsize == rstride[n])
+ rsize *= rextent[n];
+ else
+ rsize = 0;
+ if (rextent[dim] <= 0)
+ return;
+ }
+
+ sdim = GFC_DESCRIPTOR_RANK (source);
+ ssize = 1;
+ for (n = 0; n < sdim; n++)
+ {
+ scount[n] = 0;
+ sstride[n] = source->dim[n].stride;
+ sextent[n] = source->dim[n].ubound + 1 - source->dim[n].lbound;
+ if (sextent[n] <= 0)
+ abort ();
+
+ if (rsize == sstride[n])
+ ssize *= sextent[n];
+ else
+ ssize = 0;
+ }
+
+ if (pad)
+ {
+ if (pad->dim[0].stride == 0)
+ pad->dim[0].stride = 1;
+ pdim = GFC_DESCRIPTOR_RANK (pad);
+ psize = 1;
+ for (n = 0; n < pdim; n++)
+ {
+ pcount[n] = 0;
+ pstride[n] = pad->dim[n].stride;
+ pextent[n] = pad->dim[n].ubound + 1 - pad->dim[n].lbound;
+ if (pextent[n] <= 0)
+ abort ();
+ if (psize == pstride[n])
+ psize *= pextent[n];
+ else
+ rsize = 0;
+ }
+ pptr = pad->data;
+ }
+ else
+ {
+ pdim = 0;
+ psize = 1;
+ pptr = NULL;
+ }
+
+ if (rsize != 0 && ssize != 0 && psize != 0)
+ {
+ rsize *= size;
+ ssize *= size;
+ psize *= size;
+ reshape_packed (ret->data, rsize, source->data, ssize,
+ pad ? pad->data : NULL, psize);
+ return;
+ }
+ rptr = ret->data;
+ src = sptr = source->data;
+ rstride0 = rstride[0] * size;
+ sstride0 = sstride[0] * size;
+
+ while (rptr)
+ {
+ /* Select between the source and pad arrays. */
+ memcpy(rptr, src, size);
+ /* Advance to the next element. */
+ rptr += rstride0;
+ src += sstride0;
+ rcount[0]++;
+ scount[0]++;
+ /* Advance to the next destination element. */
+ n = 0;
+ while (rcount[n] == rextent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ rcount[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ rptr -= rstride[n] * rextent[n] * size;
+ n++;
+ if (n == rdim)
+ {
+ /* Break out of the loop. */
+ rptr = NULL;
+ break;
+ }
+ else
+ {
+ rcount[n]++;
+ rptr += rstride[n] * size;
+ }
+ }
+ /* Advance to the next source element. */
+ n = 0;
+ while (scount[n] == sextent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ scount[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ src -= sstride[n] * sextent[n] * size;
+ n++;
+ if (n == sdim)
+ {
+ if (sptr && pad)
+ {
+ /* Switch to the pad array. */
+ sptr = NULL;
+ sdim = pdim;
+ for (dim = 0; dim < pdim; dim++)
+ {
+ scount[dim] = pcount[dim];
+ sextent[dim] = pextent[dim];
+ sstride[dim] = pstride[dim];
+ sstride0 = sstride[0] * size;
+ }
+ }
+ /* We now start again from the beginning of the pad array. */
+ src = pptr;
+ break;
+ }
+ else
+ {
+ scount[n]++;
+ sptr += sstride[n] * size;
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/intrinsics/reshape_packed.c b/libgfortran/intrinsics/reshape_packed.c
new file mode 100644
index 00000000000..eef885feb85
--- /dev/null
+++ b/libgfortran/intrinsics/reshape_packed.c
@@ -0,0 +1,46 @@
+/* Implementation of the RESHAPE intrinsic for packed arrays
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "libgfortran.h"
+
+#include <string.h>
+
+/* Reshape function where all arrays are packed. Basically just memcpy. */
+
+void
+reshape_packed (char * ret, index_type rsize, const char * source,
+ index_type ssize, const char * pad, index_type psize)
+{
+ index_type size;
+
+ size = (rsize > ssize) ? ssize : rsize;
+ memcpy (ret, source, size);
+ ret += size;
+ rsize -= size;
+ while (rsize > 0)
+ {
+ size = (rsize > psize) ? psize : rsize;
+ memcpy (ret, pad, size);
+ ret += size;
+ rsize -= size;
+ }
+}
diff --git a/libgfortran/intrinsics/selected_kind.f90 b/libgfortran/intrinsics/selected_kind.f90
new file mode 100644
index 00000000000..62d11c7f596
--- /dev/null
+++ b/libgfortran/intrinsics/selected_kind.f90
@@ -0,0 +1,90 @@
+! Copyright 2003 Free Software Foundation, Inc.
+! Contributed by Kejia Zhao <kejia_zh@yahoo.com.cn>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+
+function selected_int_kind (r)
+ implicit none
+ integer, intent (in) :: r
+ integer :: selected_int_kind
+ integer :: i
+ ! Integer kind_range table
+ integer, parameter :: c = 4
+ type :: int_info
+ integer :: kind
+ integer :: range
+ end type int_info
+ type (int_info), parameter :: int_infos (c) = &
+ (/int_info (1, range (0_1)), &
+ int_info (2, range (0_2)), &
+ int_info (4, range (0_4)), &
+ int_info (8, range (0_8))/)
+
+ do i = 1, c
+ if (r <= int_infos (i) % range) then
+ selected_int_kind = int_infos (i) % kind
+ return
+ end if
+ end do
+ selected_int_kind = -1
+ return
+end function
+
+function selected_real_kind (p, r)
+ implicit none
+ integer, optional, intent (in) :: p, r
+ integer :: selected_real_kind
+ integer :: i, p2, r2
+ logical :: found_p, found_r
+ ! Real kind_precision_range table
+ integer, parameter :: c = 2
+ type :: real_info
+ integer :: kind
+ integer :: precision
+ integer :: range
+ end type real_info
+ type (real_info) :: real_infos (c) = &
+ (/real_info (4, precision (0.0_4), range (0.0_4)), &
+ real_info (8, precision (0.0_8), range (0.0_8))/)
+
+ selected_real_kind = 0
+ p2 = 0
+ r2 = 0
+ found_p = .false.
+ found_r = .false.
+
+ if (present (p)) p2 = p
+ if (present (r)) r2 = r
+
+ ! Assumes each type has a greater precision and range than previous one.
+
+ do i = 1, c
+ if (p2 <= real_infos (i) % precision) found_p = .true.
+ if (r2 <= real_infos (i) % range) found_r = .true.
+ if (found_p .and. found_r) then
+ selected_real_kind = real_infos (i) % kind
+ return
+ end if
+ end do
+
+ if (.not. (found_p)) selected_real_kind = selected_real_kind - 1
+ if (.not. (found_r)) selected_real_kind = selected_real_kind - 2
+
+ return
+end function
diff --git a/libgfortran/intrinsics/size.c b/libgfortran/intrinsics/size.c
new file mode 100644
index 00000000000..5664c304988
--- /dev/null
+++ b/libgfortran/intrinsics/size.c
@@ -0,0 +1,56 @@
+/* Implementation of the size intrinsic.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "libgfortran.h"
+
+typedef GFC_ARRAY_DESCRIPTOR (GFC_MAX_DIMENSIONS, void) array_t;
+
+#define size0 prefix(size0)
+index_type size0 (const array_t * array)
+{
+ int n;
+ index_type size;
+ index_type len;
+
+ size = 1;
+ for (n = 0; n < GFC_DESCRIPTOR_RANK (array); n++)
+ {
+ len = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ if (len < 0)
+ len = 0;
+ size *= len;
+ }
+ return size;
+}
+
+#define size1 prefix(size1)
+index_type size1 (const array_t * array, index_type dim)
+{
+ index_type size;
+
+ dim--;
+
+ size = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (size < 0)
+ size = 0;
+ return size;
+}
+
diff --git a/libgfortran/intrinsics/spread_generic.c b/libgfortran/intrinsics/spread_generic.c
new file mode 100644
index 00000000000..a789c98448b
--- /dev/null
+++ b/libgfortran/intrinsics/spread_generic.c
@@ -0,0 +1,118 @@
+/* Generic implementation of the RESHAPE intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "libgfortran.h"
+
+void
+__spread (const gfc_array_char * ret, const gfc_array_char * source,
+ const index_type * along, const index_type * pncopies)
+{
+ /* r.* indicates the return array. */
+ index_type rstride[GFC_MAX_DIMENSIONS - 1];
+ index_type rstride0;
+ index_type rdelta;
+ char *rptr;
+ char *dest;
+ /* s.* indicates the source array. */
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride0;
+ const char *sptr;
+
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type n;
+ index_type dim;
+ index_type size;
+ index_type ncopies;
+
+ size = GFC_DESCRIPTOR_SIZE (source);
+ dim = 0;
+ for (n = 0; n < GFC_DESCRIPTOR_RANK (ret); n++)
+ {
+ if (n == *along - 1)
+ {
+ rdelta = ret->dim[n].stride * size;
+ }
+ else
+ {
+ count[dim] = 0;
+ extent[dim] = source->dim[dim].ubound + 1 - source->dim[dim].lbound;
+ sstride[dim] = source->dim[dim].stride * size;
+ rstride[dim] = ret->dim[n].stride * size;
+ dim++;
+ }
+ }
+ dim = GFC_DESCRIPTOR_RANK (source);
+ if (sstride[0] == 0)
+ sstride[0] = size;
+ if (rstride[0] == 0)
+ rstride[0] = size;
+
+ sstride0 = sstride[0];
+ rstride0 = rstride[0];
+ rptr = ret->data;
+ sptr = source->data;
+ ncopies = *pncopies;
+
+ while (sptr)
+ {
+ /* Spread this element. */
+ dest = rptr;
+ for (n = 0; n < ncopies; n++)
+ {
+ memcpy (dest, sptr, size);
+ dest += rdelta;
+ }
+ /* Advance to the next element. */
+ sptr += sstride0;
+ rptr += rstride0;
+ count[0]++;
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so probably not worth it. */
+ sptr -= sstride[n] * extent[n];
+ rptr -= rstride[n] * extent[n];
+ n++;
+ if (n >= dim)
+ {
+ /* Break out of the loop. */
+ sptr = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ sptr += sstride[n];
+ rptr += rstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/intrinsics/string_intrinsics.c b/libgfortran/intrinsics/string_intrinsics.c
new file mode 100644
index 00000000000..2cd07a2b77b
--- /dev/null
+++ b/libgfortran/intrinsics/string_intrinsics.c
@@ -0,0 +1,393 @@
+/* String intrinsics helper functions.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+/* Unlike what the name of this file suggests, we don't actually
+ implement the Fortran intrinsics here. At least, not with the
+ names they have in the standard. The functions here provide all
+ the support we need for the standard string intrinsics, and the
+ compiler translates the actual intrinsics calls to calls to
+ functions in this file. */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "libgfortran.h"
+
+
+/* String functions. */
+
+#define copy_string prefix(copy_string)
+void copy_string (GFC_INTEGER_4, char *, GFC_INTEGER_4, const char *);
+
+#define concat_string prefix(concat_string)
+void concat_string (GFC_INTEGER_4, char *,
+ GFC_INTEGER_4, const char *,
+ GFC_INTEGER_4, const char *);
+
+#define string_len_trim prefix(string_len_trim)
+GFC_INTEGER_4 string_len_trim (GFC_INTEGER_4, const char *);
+
+#define adjustl prefix(adjustl)
+void adjustl (char *, GFC_INTEGER_4, const char *);
+
+#define adjustr prefix(adjustr)
+void adjustr (char *, GFC_INTEGER_4, const char *);
+
+#define string_index prefix(string_index)
+GFC_INTEGER_4 string_index (GFC_INTEGER_4, const char *, GFC_INTEGER_4,
+ const char *, GFC_LOGICAL_4);
+
+#define string_scan prefix(string_scan)
+GFC_INTEGER_4 string_scan (GFC_INTEGER_4, const char *, GFC_INTEGER_4,
+ const char *, GFC_LOGICAL_4);
+
+#define string_verify prefix(string_verify)
+GFC_INTEGER_4 string_verify (GFC_INTEGER_4, const char *, GFC_INTEGER_4,
+ const char *, GFC_LOGICAL_4);
+
+#define string_trim prefix(string_trim)
+void string_trim (GFC_INTEGER_4 *, void **, GFC_INTEGER_4, const char *);
+
+#define string_repeat prefix(string_repeat)
+void string_repeat (char *, GFC_INTEGER_4, const char *, GFC_INTEGER_4);
+
+/* The two areas may overlap so we use memmove. */
+
+void
+copy_string (GFC_INTEGER_4 destlen, char * dest,
+ GFC_INTEGER_4 srclen, const char * src)
+{
+ if (srclen >= destlen)
+ {
+ /* This will truncate if too long. */
+ memmove (dest, src, destlen);
+ /*memcpy (dest, src, destlen);*/
+ }
+ else
+ {
+ memmove (dest, src, srclen);
+ /*memcpy (dest, src, srclen);*/
+ /* Pad with spaces. */
+ memset (&dest[srclen], ' ', destlen - srclen);
+ }
+}
+
+
+/* Strings of unequal length are extended with pad characters. */
+
+GFC_INTEGER_4
+compare_string (GFC_INTEGER_4 len1, const char * s1,
+ GFC_INTEGER_4 len2, const char * s2)
+{
+ int res;
+ const char *s;
+ int len;
+
+ res = strncmp (s1, s2, (len1 < len2) ? len1 : len2);
+ if (res != 0)
+ return res;
+
+ if (len1 == len2)
+ return 0;
+
+ if (len1 < len2)
+ {
+ len = len2 - len1;
+ s = &s2[len1];
+ res = -1;
+ }
+ else
+ {
+ len = len1 - len2;
+ s = &s1[len2];
+ res = 1;
+ }
+
+ while (len--)
+ {
+ if (*s != ' ')
+ {
+ if (*s > ' ')
+ return res;
+ else
+ return -res;
+ }
+ s++;
+ }
+
+ return 0;
+}
+
+
+/* The destination and source should not overlap. */
+
+void
+concat_string (GFC_INTEGER_4 destlen, char * dest,
+ GFC_INTEGER_4 len1, const char * s1,
+ GFC_INTEGER_4 len2, const char * s2)
+{
+ if (len1 >= destlen)
+ {
+ memcpy (dest, s1, destlen);
+ return;
+ }
+ memcpy (dest, s1, len1);
+ dest += len1;
+ destlen -= len1;
+
+ if (len2 >= destlen)
+ {
+ memcpy (dest, s2, destlen);
+ return;
+ }
+
+ memcpy (dest, s2, len2);
+ memset (&dest[len2], ' ', destlen - len2);
+}
+
+
+/* Return string with all trailing blanks removed. */
+
+void
+string_trim (GFC_INTEGER_4 * len, void ** dest, GFC_INTEGER_4 slen, const char * src)
+{
+ int i;
+
+ /* Determine length of result string. */
+ for (i = slen - 1; i >= 0; i--)
+ {
+ if (src[i] != ' ')
+ break;
+ }
+ *len = i + 1;
+
+ if (*len > 0)
+ {
+ /* Allocate space for result string. */
+ *dest = internal_malloc (*len);
+
+ /* copy string if necessary. */
+ memmove (*dest, src, *len);
+ }
+}
+
+
+/* The length of a string not including trailing blanks. */
+
+GFC_INTEGER_4
+string_len_trim (GFC_INTEGER_4 len, const char * s)
+{
+ int i;
+
+ for (i = len - 1; i >= 0; i--)
+ {
+ if (s[i] != ' ')
+ break;
+ }
+ return i + 1;
+}
+
+
+/* Find a substring within a string. */
+
+GFC_INTEGER_4
+string_index (GFC_INTEGER_4 slen, const char * str, GFC_INTEGER_4 sslen,
+ const char * sstr, GFC_LOGICAL_4 back)
+{
+ int start;
+ int last;
+ int i;
+ int delta;
+
+ if (sslen == 0)
+ return 1;
+
+ if (!back)
+ {
+ last = slen + 1 - sslen;
+ start = 0;
+ delta = 1;
+ }
+ else
+ {
+ last = -1;
+ start = slen - sslen;
+ delta = -1;
+ }
+ i = 0;
+ for (; start != last; start+= delta)
+ {
+ for (i = 0; i < sslen; i++)
+ {
+ if (str[start + i] != sstr[i])
+ break;
+ }
+ if (i == sslen)
+ return (start + 1);
+ }
+ return 0;
+}
+
+
+/* Remove leading blanks from a string, padding at end. The src and dest
+ should not overlap. */
+
+void
+adjustl (char *dest, GFC_INTEGER_4 len, const char *src)
+{
+ int i;
+
+ i = 0;
+ while (i<len && src[i] == ' ')
+ i++;
+
+ if (i < len)
+ memcpy (dest, &src[i], len - i);
+ if (i > 0)
+ memset (&dest[len - i], ' ', i);
+}
+
+
+/* Remove trailing blanks from a string. */
+
+void
+adjustr (char *dest, GFC_INTEGER_4 len, const char *src)
+{
+ int i;
+
+ i = len;
+ while (i > 0 && src[i - 1] == ' ')
+ i--;
+
+ if (i < len)
+ memset (dest, ' ', len - i);
+ memcpy (dest + (len - i), src, i );
+}
+
+
+/* Scan a string for any one of the characters in a set of characters. */
+
+GFC_INTEGER_4
+string_scan (GFC_INTEGER_4 slen, const char * str, GFC_INTEGER_4 setlen,
+ const char * set, GFC_LOGICAL_4 back)
+{
+ int start;
+ int last;
+ int i;
+ int delta;
+
+ if (slen == 0 || setlen == 0)
+ return 0;
+
+ if (back)
+ {
+ last = 0;
+ start = slen - 1;
+ delta = -1;
+ }
+ else
+ {
+ last = slen - 1;
+ start = 0;
+ delta = 1;
+ }
+
+ i = 0;
+ for (; start != last; start += delta)
+ {
+ for (i = 0; i < setlen; i++)
+ {
+ if (str[start] == set[i])
+ return (start + 1);
+ }
+ }
+
+ return 0;
+}
+
+
+/* Verify that a set of characters contains all the characters in a
+ string by indentifying the position of the first character in a
+ characters that dose not appear in a given set of characters. */
+
+GFC_INTEGER_4
+string_verify (GFC_INTEGER_4 slen, const char * str, GFC_INTEGER_4 setlen,
+ const char * set, GFC_LOGICAL_4 back)
+{
+ int start;
+ int last;
+ int i;
+ int delta;
+
+ if (slen == 0)
+ return 0;
+
+ if (back)
+ {
+ last = 0;
+ start = slen - 1;
+ delta = -1;
+ }
+ else
+ {
+ last = slen - 1;
+ start = 0;
+ delta = 1;
+ }
+ i = 0;
+ for (; start != last; start += delta)
+ {
+ for (i = 0; i < setlen; i++)
+ {
+ if (str[start] == set[i])
+ break;
+ }
+ if (i == setlen)
+ return (start + 1);
+ }
+
+ return 0;
+}
+
+
+/* Concatenate several copies of a string. */
+
+void
+string_repeat (char * dest, GFC_INTEGER_4 slen,
+ const char * src, GFC_INTEGER_4 ncopies)
+{
+ int i;
+
+ /* See if ncopies is valid. */
+ if (ncopies < 0)
+ {
+ /* The error is already reported. */
+ runtime_error ("Augument NCOPIES is negative.");
+ }
+
+ /* Copy characters. */
+ for (i = 0; i < ncopies; i++)
+ {
+ memmove (dest + (i * slen), src, slen);
+ }
+}
+
diff --git a/libgfortran/intrinsics/transpose_generic.c b/libgfortran/intrinsics/transpose_generic.c
new file mode 100644
index 00000000000..d72ae5a4b81
--- /dev/null
+++ b/libgfortran/intrinsics/transpose_generic.c
@@ -0,0 +1,74 @@
+/* Implementation of the TRANSPOSE intrinsic
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Tobias Schlüter
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "libgfortran.h"
+
+void
+__transpose (gfc_array_char * ret, gfc_array_char * source)
+{
+ /* r.* indicates the return array. */
+ index_type rxstride, rystride;
+ char *rptr;
+ /* s.* indicates the source array. */
+ index_type sxstride, systride;
+ const char *sptr;
+
+ index_type xcount, ycount;
+ index_type x, y;
+ index_type size;
+
+ assert (GFC_DESCRIPTOR_RANK (source) == 2
+ && GFC_DESCRIPTOR_RANK (ret) == 2);
+
+ size = GFC_DESCRIPTOR_SIZE (source);
+ sxstride = source->dim[0].stride * size;
+ if (sxstride == 0)
+ sxstride = size;
+ systride = source->dim[1].stride * size;
+ xcount = source->dim[0].ubound + 1 - source->dim[0].lbound;
+ ycount = source->dim[1].ubound + 1 - source->dim[1].lbound;
+
+ rxstride = ret->dim[0].stride * size;
+ if (rxstride == 0)
+ rxstride = size;
+ rystride = ret->dim[1].stride * size;
+
+ rptr = ret->data;
+ sptr = source->data;
+
+ for (y = 0; y < ycount; y++)
+ {
+ for (x = 0; x < xcount; x++)
+ {
+ memcpy (rptr, sptr, size);
+
+ sptr += sxstride;
+ rptr += rystride;
+ }
+ sptr += systride - (sxstride * xcount);
+ rptr += rxstride - (rystride * xcount);
+ }
+}
+
diff --git a/libgfortran/intrinsics/unpack_generic.c b/libgfortran/intrinsics/unpack_generic.c
new file mode 100644
index 00000000000..3d02a3e6060
--- /dev/null
+++ b/libgfortran/intrinsics/unpack_generic.c
@@ -0,0 +1,154 @@
+/* Generic implementation of the RESHAPE intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "libgfortran.h"
+
+void
+__unpack1 (const gfc_array_char * ret, const gfc_array_char * vector,
+ const gfc_array_l4 * mask, const gfc_array_char * field)
+{
+ /* r.* indicates the return array. */
+ index_type rstride[GFC_MAX_DIMENSIONS];
+ index_type rstride0;
+ char *rptr;
+ /* v.* indicates the vector array. */
+ index_type vstride0;
+ char *vptr;
+ /* f.* indicates the field array. */
+ index_type fstride[GFC_MAX_DIMENSIONS];
+ index_type fstride0;
+ const char *fptr;
+ /* m.* indicates the mask array. */
+ index_type mstride[GFC_MAX_DIMENSIONS];
+ index_type mstride0;
+ const GFC_LOGICAL_4 *mptr;
+
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type n;
+ index_type dim;
+ index_type size;
+ index_type fsize;
+
+ size = GFC_DESCRIPTOR_SIZE (ret);
+ /* A field element size of 0 actually means this is a scalar. */
+ fsize = GFC_DESCRIPTOR_SIZE (field);
+ dim = GFC_DESCRIPTOR_RANK (ret);
+ for (n = 0; n < dim; n++)
+ {
+ count[n] = 0;
+ extent[n] = ret->dim[n].ubound + 1 - ret->dim[n].lbound;
+ rstride[n] = ret->dim[n].stride * size;
+ fstride[n] = field->dim[n].stride * fsize;
+ mstride[n] = mask->dim[n].stride;
+ }
+ if (rstride[0] == 0)
+ rstride[0] = size;
+ if (fstride[0] == 0)
+ fstride[0] = fsize;
+ if (mstride[0] == 0)
+ mstride[0] = 1;
+
+ vstride0 = vector->dim[0].stride * size;
+ if (vstride0 == 0)
+ vstride0 = size;
+ rstride0 = rstride[0];
+ fstride0 = fstride[0];
+ mstride0 = mstride[0];
+ rptr = ret->data;
+ fptr = field->data;
+ mptr = mask->data;
+ vptr = vector->data;
+
+
+ /* Use the same loop for both logical types. */
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ if (GFC_DESCRIPTOR_SIZE (mask) != 8)
+ runtime_error ("Funny sized logical array");
+ for (n = 0; n < dim; n++)
+ mstride[n] <<= 1;
+ mstride0 <<= 1;
+ mptr = GFOR_POINTER_L8_TO_L4 (mptr);
+ }
+
+ while (rptr)
+ {
+ if (*mptr)
+ {
+ /* From vector. */
+ memcpy (rptr, vptr, size);
+ vptr += vstride0;
+ }
+ else
+ {
+ /* From field. */
+ memcpy (rptr, fptr, size);
+ }
+ /* Advance to the next element. */
+ rptr += rstride0;
+ fptr += fstride0;
+ mptr += mstride0;
+ count[0]++;
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ rptr -= rstride[n] * extent[n];
+ fptr -= fstride[n] * extent[n];
+ mptr -= mstride[n] * extent[n];
+ n++;
+ if (n >= dim)
+ {
+ /* Break out of the loop. */
+ rptr = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ rptr += rstride[n];
+ fptr += fstride[n];
+ mptr += mstride[n];
+ }
+ }
+ }
+}
+
+void
+__unpack0 (const gfc_array_char * ret, const gfc_array_char * vector,
+ const gfc_array_l4 * mask, char * field)
+{
+ gfc_array_char tmp;
+
+ tmp.dtype = 0;
+ tmp.data = field;
+ __unpack1 (ret, vector, mask, &tmp);
+}
+
diff --git a/libgfortran/io/backspace.c b/libgfortran/io/backspace.c
new file mode 100644
index 00000000000..7502f1d4863
--- /dev/null
+++ b/libgfortran/io/backspace.c
@@ -0,0 +1,160 @@
+/* Copyright (C) 2002-2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran 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 2, or (at your option)
+any later version.
+
+Libgfortran 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 Libgfortran; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "libgfortran.h"
+#include "io.h"
+
+/* backspace.c -- Implement the BACKSPACE statement */
+
+/* formatted_backspace(void)-- Move the file back one line. The
+ * current position is after the newline that terminates the previous
+ * record, and we have to sift backwards to find the newline before
+ * that or the start of the file, whichever comes first. */
+
+#define READ_CHUNK 4096
+
+static void
+formatted_backspace (void)
+{
+ offset_t base;
+ char *p;
+ int n;
+
+ base = file_position (current_unit->s) - 1;
+
+ do
+ {
+ n = (base < READ_CHUNK) ? base : READ_CHUNK;
+ base -= n;
+
+ p = salloc_r_at (current_unit->s, &n, base);
+ if (p == NULL)
+ goto io_error;
+
+ /* Because we've moved backwords from the current position, it
+ * should not be possible to get a short read. Because it isn't
+ * clear what to do about such thing, we ignore the possibility. */
+
+ /* There is no memrchr() in the C library, so we have to do it
+ * ourselves. */
+
+ n--;
+ while (n >= 0)
+ {
+ if (p[n] == '\n')
+ {
+ base += n + 1;
+ goto done;
+ }
+
+ n--;
+ }
+
+ }
+ while (base != 0);
+
+/* base is the new pointer. Seek to it exactly */
+
+done:
+ if (sseek (current_unit->s, base) == FAILURE)
+ goto io_error;
+ current_unit->last_record--;
+
+ return;
+
+io_error:
+ generate_error (ERROR_OS, NULL);
+}
+
+
+/* unformatted_backspace()-- Move the file backwards for an
+ * unformatted sequential file. We are guaranteed to be between
+ * records on entry and we have to shift to the previous record. */
+
+static void
+unformatted_backspace (void)
+{
+ offset_t *p, new;
+ int length;
+
+ length = sizeof (offset_t);
+
+ p = (offset_t *) salloc_r_at (current_unit->s, &length,
+ file_position (current_unit->s) - length);
+ if (p == NULL)
+ goto io_error;
+
+ new = file_position (current_unit->s) - *p - length;
+ if (sseek (current_unit->s, new) == FAILURE)
+ goto io_error;
+
+ current_unit->last_record--;
+ return;
+
+io_error:
+ generate_error (ERROR_OS, NULL);
+}
+
+
+void
+st_backspace (void)
+{
+ unit_t *u;
+
+ library_start ();
+
+ u = find_unit (ioparm.unit);
+ if (u == NULL)
+ {
+ generate_error (ERROR_BAD_UNIT, NULL);
+ goto done;
+ }
+
+ current_unit = u;
+
+ /* Ignore direct access. Non-advancing I/O is only allowed for
+ * formatted sequential I/O and the next direct access transfer
+ * repositions the file anyway. */
+
+ if (u->flags.access == ACCESS_DIRECT)
+ goto done;
+
+ /* Check for special cases involving the ENDFILE record first */
+
+ if (u->endfile == AFTER_ENDFILE)
+ u->endfile = AT_ENDFILE;
+ else
+ {
+ if (u->current_record)
+ next_record (1);
+
+ if (file_position (u->s) == 0)
+ goto done; /* Common special case */
+
+ if (u->flags.form == FORM_UNFORMATTED)
+ formatted_backspace ();
+ else
+ unformatted_backspace ();
+ }
+
+done:
+ library_end ();
+}
diff --git a/libgfortran/io/close.c b/libgfortran/io/close.c
new file mode 100644
index 00000000000..9e2a5a398ce
--- /dev/null
+++ b/libgfortran/io/close.c
@@ -0,0 +1,70 @@
+/* Copyright (C) 2002-2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran 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 2, or (at your option)
+any later version.
+
+Libgfortran 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 Libgfortran; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "libgfortran.h"
+#include "io.h"
+
+typedef enum
+{ CLOSE_DELETE, CLOSE_KEEP, CLOSE_UNSPECIFIED }
+close_status;
+
+static st_option status_opt[] = {
+ {"keep", CLOSE_KEEP},
+ {"delete", CLOSE_DELETE},
+ {NULL}
+};
+
+
+void
+st_close (void)
+{
+ close_status status;
+ unit_t *u;
+
+ library_start ();
+
+ status = (ioparm.status == NULL) ? CLOSE_UNSPECIFIED :
+ find_option (ioparm.status, ioparm.status_len, status_opt,
+ "Bad STATUS parameter in CLOSE statement");
+
+ if (ioparm.library_return != LIBRARY_OK)
+ return;
+
+ u = find_unit (ioparm.unit);
+ if (u != NULL)
+ {
+ if (u->flags.status == STATUS_SCRATCH)
+ {
+ if (status == CLOSE_KEEP)
+ generate_error (ERROR_BAD_OPTION,
+ "Can't KEEP a scratch file on CLOSE");
+ }
+ else
+ {
+ if (status == CLOSE_DELETE)
+ delete_file (u);
+ }
+
+ close_unit (u);
+ }
+
+ library_end ();
+}
diff --git a/libgfortran/io/endfile.c b/libgfortran/io/endfile.c
new file mode 100644
index 00000000000..56f81f09909
--- /dev/null
+++ b/libgfortran/io/endfile.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 2002-2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran 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 2, or (at your option)
+any later version.
+
+Libgfortran 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 Libgfortran; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "libgfortran.h"
+#include "io.h"
+
+/* endfile.c-- Implement the ENDFILE statement */
+
+void
+st_endfile (void)
+{
+ unit_t *u;
+
+ library_start ();
+
+ u = get_unit (0);
+ if (u != NULL)
+ {
+ current_unit = u; /* next_record() needs this set */
+ if (u->current_record)
+ next_record (1);
+
+ struncate (u->s);
+ u->endfile = AFTER_ENDFILE;
+ }
+
+ library_end ();
+}
diff --git a/libgfortran/io/format.c b/libgfortran/io/format.c
new file mode 100644
index 00000000000..0be913c59b9
--- /dev/null
+++ b/libgfortran/io/format.c
@@ -0,0 +1,1285 @@
+/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran 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 2, or (at your option)
+any later version.
+
+Libgfortran 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 Libgfortran; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+/* format.c-- parse a FORMAT string into a binary format suitable for
+ * interpretation during I/O statements */
+
+#include "config.h"
+#include <ctype.h>
+#include <string.h>
+#include "libgfortran.h"
+#include "io.h"
+
+
+
+/* Number of format nodes that we can store statically before we have
+ * to resort to dynamic allocation. The root node is array[0]. */
+
+#define FARRAY_SIZE 200
+
+static fnode *avail, array[FARRAY_SIZE];
+
+/* Local variables for checking format strings. The saved_token is
+ * used to back up by a single format token during the parsing process. */
+
+static char *format_string, *string;
+static const char *error;
+static format_token saved_token;
+static int value, format_string_len, reversion_ok;
+
+static fnode *saved_format, colon_node = { FMT_COLON };
+
+/* Error messages */
+
+static char posint_required[] = "Positive width required in format",
+ period_required[] = "Period required in format",
+ nonneg_required[] = "Nonnegative width required in format",
+ unexpected_element[] = "Unexpected element in format",
+ unexpected_end[] = "Unexpected end of format string",
+ bad_string[] = "Unterminated character constant in format",
+ bad_hollerith[] = "Hollerith constant extends past the end of the format",
+ reversion_error[] = "Exhausted data descriptors in format";
+
+
+/* next_char()-- Return the next character in the format string.
+ * Returns -1 when the string is done. If the literal flag is set,
+ * spaces are significant, otherwise they are not. */
+
+static int
+next_char (int literal)
+{
+ int c;
+
+ do
+ {
+ if (format_string_len == 0)
+ return -1;
+
+ format_string_len--;
+ c = toupper (*format_string++);
+ }
+ while (c == ' ' && !literal);
+
+ return c;
+}
+
+
+/* unget_char()-- Back up one character position. */
+
+#define unget_char() { format_string--; format_string_len++; }
+
+
+/* get_fnode()-- Allocate a new format node, inserting it into the
+ * current singly linked list. These are initially allocated from the
+ * static buffer. */
+
+static fnode *
+get_fnode (fnode ** head, fnode ** tail, format_token t)
+{
+ fnode *f;
+
+ if (avail - array >= FARRAY_SIZE)
+ f = get_mem (sizeof (fnode));
+ else
+ {
+ f = avail++;
+ memset (f, '\0', sizeof (fnode));
+ }
+
+ if (*head == NULL)
+ *head = *tail = f;
+ else
+ {
+ (*tail)->next = f;
+ *tail = f;
+ }
+
+ f->format = t;
+ f->repeat = -1;
+ f->source = format_string;
+ return f;
+}
+
+
+/* free_fnode()-- Recursive function to free the given fnode and
+ * everything it points to. We only have to actually free something
+ * if it is outside of the static array. */
+
+static void
+free_fnode (fnode * f)
+{
+ fnode *next;
+
+ for (; f; f = next)
+ {
+ next = f->next;
+
+ if (f->format == FMT_LPAREN)
+ free_fnode (f->u.child);
+ if (f < array || f >= array + FARRAY_SIZE)
+ free_mem (f);
+ }
+}
+
+
+/* free_fnodes()-- Free the current tree of fnodes. We only have to
+ * traverse the tree if some nodes were allocated dynamically. */
+
+void
+free_fnodes (void)
+{
+
+ if (avail - array >= FARRAY_SIZE)
+ free_fnode (&array[0]);
+
+ avail = array;
+ memset(array, 0, sizeof(avail[0]) * FARRAY_SIZE);
+}
+
+
+/* format_lex()-- Simple lexical analyzer for getting the next token
+ * in a FORMAT string. We support a one-level token pushback in the
+ * saved_token variable. */
+
+static format_token
+format_lex (void)
+{
+ format_token token;
+ int negative_flag;
+ char c, delim;
+
+ if (saved_token != FMT_NONE)
+ {
+ token = saved_token;
+ saved_token = FMT_NONE;
+ return token;
+ }
+
+ negative_flag = 0;
+ c = next_char (0);
+
+ switch (c)
+ {
+ case '-':
+ negative_flag = 1;
+ /* Fall Through */
+
+ case '+':
+ c = next_char (0);
+ if (!isdigit (c))
+ {
+ token = FMT_UNKNOWN;
+ break;
+ }
+
+ value = c - '0';
+
+ for (;;)
+ {
+ c = next_char (0);
+ if (!isdigit (c))
+ break;
+
+ value = 10 * value + c - '0';
+ }
+
+ unget_char ();
+
+ if (negative_flag)
+ value = -value;
+ token = FMT_SIGNED_INT;
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ value = c - '0';
+
+ for (;;)
+ {
+ c = next_char (0);
+ if (!isdigit (c))
+ break;
+
+ value = 10 * value + c - '0';
+ }
+
+ unget_char ();
+ token = (value == 0) ? FMT_ZERO : FMT_POSINT;
+ break;
+
+ case '.':
+ token = FMT_PERIOD;
+ break;
+
+ case ',':
+ token = FMT_COMMA;
+ break;
+
+ case ':':
+ token = FMT_COLON;
+ break;
+
+ case '/':
+ token = FMT_SLASH;
+ break;
+
+ case '$':
+ token = FMT_DOLLAR;
+ break;
+
+ case 'T':
+ switch (next_char (0))
+ {
+ case 'L':
+ token = FMT_TL;
+ break;
+ case 'R':
+ token = FMT_TR;
+ break;
+ default:
+ token = FMT_T;
+ unget_char ();
+ break;
+ }
+
+ break;
+
+ case '(':
+ token = FMT_LPAREN;
+ break;
+
+ case ')':
+ token = FMT_RPAREN;
+ break;
+
+ case 'X':
+ token = FMT_X;
+ break;
+
+ case 'S':
+ switch (next_char (0))
+ {
+ case 'S':
+ token = FMT_SS;
+ break;
+ case 'P':
+ token = FMT_SP;
+ break;
+ default:
+ token = FMT_S;
+ unget_char ();
+ break;
+ }
+
+ break;
+
+ case 'B':
+ switch (next_char (0))
+ {
+ case 'N':
+ token = FMT_BN;
+ break;
+ case 'Z':
+ token = FMT_BZ;
+ break;
+ default:
+ token = FMT_B;
+ unget_char ();
+ break;
+ }
+
+ break;
+
+ case '\'':
+ case '"':
+ delim = c;
+
+ string = format_string;
+ value = 0; /* This is the length of the string */
+
+ for (;;)
+ {
+ c = next_char (1);
+ if (c == -1)
+ {
+ token = FMT_BADSTRING;
+ error = bad_string;
+ break;
+ }
+
+ if (c == delim)
+ {
+ c = next_char (1);
+
+ if (c == -1)
+ {
+ token = FMT_BADSTRING;
+ error = bad_string;
+ break;
+ }
+
+ if (c != delim)
+ {
+ unget_char ();
+ token = FMT_STRING;
+ break;
+ }
+ }
+
+ value++;
+ }
+
+ break;
+
+ case 'P':
+ token = FMT_P;
+ break;
+
+ case 'I':
+ token = FMT_I;
+ break;
+
+ case 'O':
+ token = FMT_O;
+ break;
+
+ case 'Z':
+ token = FMT_Z;
+ break;
+
+ case 'F':
+ token = FMT_F;
+ break;
+
+ case 'E':
+ switch (next_char (0))
+ {
+ case 'N':
+ token = FMT_EN;
+ break;
+ case 'S':
+ token = FMT_ES;
+ break;
+ default:
+ token = FMT_E;
+ unget_char ();
+ break;
+ }
+
+ break;
+
+ case 'G':
+ token = FMT_G;
+ break;
+
+ case 'H':
+ token = FMT_H;
+ break;
+
+ case 'L':
+ token = FMT_L;
+ break;
+
+ case 'A':
+ token = FMT_A;
+ break;
+
+ case 'D':
+ token = FMT_D;
+ break;
+
+ case -1:
+ token = FMT_END;
+ break;
+
+ default:
+ token = FMT_UNKNOWN;
+ break;
+ }
+
+ return token;
+}
+
+
+/* parse_format_list()-- Parse a format list. Assumes that a left
+ * paren has already been seen. Returns a list representing the
+ * parenthesis node which contains the rest of the list. */
+
+static fnode *
+parse_format_list (void)
+{
+ fnode *head, *tail;
+ format_token t, u, t2;
+ int repeat;
+
+ head = tail = NULL;
+
+/* Get the next format item */
+
+format_item:
+ t = format_lex ();
+ switch (t)
+ {
+ case FMT_POSINT:
+ repeat = value;
+
+ t = format_lex ();
+ switch (t)
+ {
+ case FMT_LPAREN:
+ get_fnode (&head, &tail, FMT_LPAREN);
+ tail->repeat = repeat;
+ tail->u.child = parse_format_list ();
+ if (error != NULL)
+ goto finished;
+
+ goto between_desc;
+
+ case FMT_SLASH:
+ get_fnode (&head, &tail, FMT_SLASH);
+ tail->repeat = repeat;
+ goto optional_comma;
+
+ case FMT_X:
+ get_fnode (&head, &tail, FMT_X);
+ tail->repeat = 1;
+ tail->u.k = value;
+ goto between_desc;
+
+ case FMT_P:
+ goto p_descriptor;
+
+ default:
+ goto data_desc;
+ }
+
+ case FMT_LPAREN:
+ get_fnode (&head, &tail, FMT_LPAREN);
+ tail->repeat = 1;
+ tail->u.child = parse_format_list ();
+ if (error != NULL)
+ goto finished;
+
+ goto between_desc;
+
+ case FMT_SIGNED_INT: /* Signed integer can only precede a P format. */
+ case FMT_ZERO: /* Same for zero. */
+ t = format_lex ();
+ if (t != FMT_P)
+ {
+ error = "Expected P edit descriptor in format";
+ goto finished;
+ }
+
+ p_descriptor:
+ get_fnode (&head, &tail, FMT_P);
+ tail->u.k = value;
+
+ t = format_lex ();
+ if (t == FMT_F || t == FMT_EN || t == FMT_ES || t == FMT_D
+ || t == FMT_G || t == FMT_E)
+ {
+ repeat = 1;
+ goto data_desc;
+ }
+
+ saved_token = t;
+ goto optional_comma;
+
+ case FMT_P: /* P and X require a prior number */
+ error = "P descriptor requires leading scale factor";
+ goto finished;
+
+ case FMT_X:
+/*
+ EXTENSION!
+
+ If we would be pedantic in the library, we would have to reject
+ an X descriptor without an integer prefix:
+
+ error = "X descriptor requires leading space count";
+ goto finished;
+
+ However, this is an extension supported by many Fortran compilers,
+ including Cray, HP, AIX, and IRIX. Therefore, we allow it in the
+ runtime library, and make the front end reject it if the compiler
+ is in pedantic mode. The interpretation of 'X' is '1X'.
+*/
+ get_fnode (&head, &tail, FMT_X);
+ tail->repeat = 1;
+ tail->u.k = 1;
+ goto between_desc;
+
+ case FMT_STRING:
+ get_fnode (&head, &tail, FMT_STRING);
+
+ tail->u.string.p = string;
+ tail->u.string.length = value;
+ tail->repeat = 1;
+ goto between_desc;
+
+ case FMT_S:
+ case FMT_SS:
+ case FMT_SP:
+ case FMT_BN:
+ case FMT_BZ:
+ get_fnode (&head, &tail, t);
+ goto between_desc;
+
+ case FMT_COLON:
+ get_fnode (&head, &tail, FMT_COLON);
+ goto optional_comma;
+
+ case FMT_SLASH:
+ get_fnode (&head, &tail, FMT_SLASH);
+ tail->repeat = 1;
+ tail->u.r = 1;
+ goto optional_comma;
+
+ case FMT_DOLLAR:
+ get_fnode (&head, &tail, FMT_DOLLAR);
+ goto between_desc;
+
+ case FMT_T:
+ case FMT_TL:
+ case FMT_TR:
+ t2 = format_lex ();
+ if (t2 != FMT_POSINT)
+ {
+ error = posint_required;
+ goto finished;
+ }
+ get_fnode (&head, &tail, t);
+ tail->u.n = value;
+ tail->repeat = 1;
+ goto between_desc;
+
+ case FMT_I:
+ case FMT_B:
+ case FMT_O:
+ case FMT_Z:
+ case FMT_E:
+ case FMT_EN:
+ case FMT_ES:
+ case FMT_D:
+ case FMT_L:
+ case FMT_A:
+ case FMT_F:
+ case FMT_G:
+ repeat = 1;
+ goto data_desc;
+
+ case FMT_H:
+ get_fnode (&head, &tail, FMT_STRING);
+
+ if (format_string_len < 1)
+ {
+ error = bad_hollerith;
+ goto finished;
+ }
+
+ tail->u.string.p = format_string;
+ tail->u.string.length = 1;
+ tail->repeat = 1;
+
+ format_string++;
+ format_string_len--;
+
+ goto between_desc;
+
+ case FMT_END:
+ error = unexpected_end;
+ goto finished;
+
+ case FMT_BADSTRING:
+ goto finished;
+
+ case FMT_RPAREN:
+ goto finished;
+
+ default:
+ error = unexpected_element;
+ goto finished;
+ }
+
+/* In this state, t must currently be a data descriptor. Deal with
+ * things that can/must follow the descriptor */
+
+data_desc:
+ switch (t)
+ {
+ case FMT_P:
+ t = format_lex ();
+ if (t == FMT_POSINT)
+ {
+ error = "Repeat count cannot follow P descriptor";
+ goto finished;
+ }
+
+ saved_token = t;
+ get_fnode (&head, &tail, FMT_P);
+
+ goto optional_comma;
+
+ case FMT_L:
+ t = format_lex ();
+ if (t != FMT_POSINT)
+ {
+ error = posint_required;
+ goto finished;
+ }
+
+ get_fnode (&head, &tail, FMT_L);
+ tail->u.n = value;
+ tail->repeat = repeat;
+ break;
+
+ case FMT_A:
+ t = format_lex ();
+ if (t != FMT_POSINT)
+ {
+ saved_token = t;
+ value = -1; /* Width not present */
+ }
+
+ get_fnode (&head, &tail, FMT_A);
+ tail->repeat = repeat;
+ tail->u.n = value;
+ break;
+
+ case FMT_D:
+ case FMT_E:
+ case FMT_F:
+ case FMT_G:
+ case FMT_EN:
+ case FMT_ES:
+ get_fnode (&head, &tail, t);
+ tail->repeat = repeat;
+
+ u = format_lex ();
+ if (t == FMT_F || g.mode == WRITING)
+ {
+ if (u != FMT_POSINT && u != FMT_ZERO)
+ {
+ error = nonneg_required;
+ goto finished;
+ }
+ }
+ else
+ {
+ if (u != FMT_POSINT)
+ {
+ error = posint_required;
+ goto finished;
+ }
+ }
+
+ tail->u.real.w = value;
+ t2 = t;
+ t = format_lex ();
+ if (t != FMT_PERIOD)
+ {
+ error = period_required;
+ goto finished;
+ }
+
+ t = format_lex ();
+ if (t != FMT_ZERO && t != FMT_POSINT)
+ {
+ error = nonneg_required;
+ goto finished;
+ }
+
+ tail->u.real.d = value;
+
+ if (t == FMT_D || t == FMT_F)
+ break;
+
+ tail->u.real.e = -1;
+
+/* Look for optional exponent */
+
+ t = format_lex ();
+ if (t != FMT_E)
+ saved_token = t;
+ else
+ {
+ t = format_lex ();
+ if (t != FMT_POSINT)
+ {
+ error = "Positive exponent width required in format";
+ goto finished;
+ }
+
+ tail->u.real.e = value;
+ }
+
+ break;
+
+ case FMT_H:
+ if (repeat > format_string_len)
+ {
+ error = bad_hollerith;
+ goto finished;
+ }
+
+ get_fnode (&head, &tail, FMT_STRING);
+
+ tail->u.string.p = format_string;
+ tail->u.string.length = repeat;
+ tail->repeat = 1;
+
+ format_string += value;
+ format_string_len -= repeat;
+
+ break;
+
+ case FMT_I:
+ case FMT_B:
+ case FMT_O:
+ case FMT_Z:
+ get_fnode (&head, &tail, t);
+ tail->repeat = repeat;
+
+ t = format_lex ();
+
+ if (g.mode == READING)
+ {
+ if (t != FMT_POSINT)
+ {
+ error = posint_required;
+ goto finished;
+ }
+ }
+ else
+ {
+ if (t != FMT_ZERO && t != FMT_POSINT)
+ {
+ error = nonneg_required;
+ goto finished;
+ }
+ }
+
+ tail->u.integer.w = value;
+ tail->u.integer.m = -1;
+
+ t = format_lex ();
+ if (t != FMT_PERIOD)
+ {
+ saved_token = t;
+ }
+ else
+ {
+ t = format_lex ();
+ if (t != FMT_ZERO && t != FMT_POSINT)
+ {
+ error = nonneg_required;
+ goto finished;
+ }
+
+ tail->u.integer.m = value;
+ }
+
+ if (tail->u.integer.w != 0 && tail->u.integer.m > tail->u.integer.w)
+ {
+ error = "Minimum digits exceeds field width";
+ goto finished;
+ }
+
+ break;
+
+ default:
+ error = unexpected_element;
+ goto finished;
+ }
+
+/* Between a descriptor and what comes next */
+between_desc:
+ t = format_lex ();
+ switch (t)
+ {
+ case FMT_COMMA:
+ goto format_item;
+
+ case FMT_RPAREN:
+ goto finished;
+
+ case FMT_SLASH:
+ get_fnode (&head, &tail, FMT_SLASH);
+ tail->repeat = 1;
+
+ /* Fall Through */
+
+ case FMT_COLON:
+ goto optional_comma;
+
+ case FMT_END:
+ error = unexpected_end;
+ goto finished;
+
+ default:
+ error = "Missing comma in format";
+ goto finished;
+ }
+
+/* Optional comma is a weird between state where we've just finished
+ * reading a colon, slash or P descriptor. */
+
+optional_comma:
+ t = format_lex ();
+ switch (t)
+ {
+ case FMT_COMMA:
+ break;
+
+ case FMT_RPAREN:
+ goto finished;
+
+ default: /* Assume that we have another format item */
+ saved_token = t;
+ break;
+ }
+
+ goto format_item;
+
+finished:
+ return head;
+}
+
+
+/* format_error()-- Generate an error message for a format statement.
+ * If the node that gives the location of the error is NULL, the error
+ * is assumed to happen at parse time, and the current location of the
+ * parser is shown.
+ *
+ * After freeing any dynamically allocated fnodes, generate a message
+ * showing where the problem is. We take extra care to print only the
+ * relevant part of the format if it is longer than a standard 80
+ * column display. */
+
+void
+format_error (fnode * f, const char *message)
+{
+ int width, i, j, offset;
+ char *p, buffer[300];
+
+ if (f != NULL)
+ format_string = f->source;
+
+ free_fnodes ();
+
+ st_sprintf (buffer, "%s\n", message);
+
+ j = format_string - ioparm.format;
+
+ offset = (j > 60) ? j - 40 : 0;
+
+ j -= offset;
+ width = ioparm.format_len - offset;
+
+ if (width > 80)
+ width = 80;
+
+ /* Show the format */
+
+ p = strchr (buffer, '\0');
+
+ memcpy (p, ioparm.format + offset, width);
+
+ p += width;
+ *p++ = '\n';
+
+ /* Show where the problem is */
+
+ for (i = 1; i < j; i++)
+ *p++ = ' ';
+
+ *p++ = '^';
+ *p = '\0';
+
+ generate_error (ERROR_FORMAT, buffer);
+}
+
+
+/* parse_format()-- Parse a format string. */
+
+void
+parse_format (void)
+{
+
+ format_string = ioparm.format;
+ format_string_len = ioparm.format_len;
+
+ saved_token = FMT_NONE;
+ error = NULL;
+
+/* Initialize variables used during traversal of the tree */
+
+ reversion_ok = 0;
+ g.reversion_flag = 0;
+ saved_format = NULL;
+
+/* Allocate the first format node as the root of the tree */
+
+ avail = array;
+
+ avail->format = FMT_LPAREN;
+ avail->repeat = 1;
+ avail++;
+
+ if (format_lex () == FMT_LPAREN)
+ array[0].u.child = parse_format_list ();
+ else
+ error = "Missing initial left parenthesis in format";
+
+ if (error)
+ format_error (NULL, error);
+}
+
+
+/* revert()-- Do reversion of the format. Control reverts to the left
+ * parenthesis that matches the rightmost right parenthesis. From our
+ * tree structure, we are looking for the rightmost parenthesis node
+ * at the second level, the first level always being a single
+ * parenthesis node. If this node doesn't exit, we use the top
+ * level. */
+
+static void
+revert (void)
+{
+ fnode *f, *r;
+
+ g.reversion_flag = 1;
+
+ r = NULL;
+
+ for (f = array[0].u.child; f; f = f->next)
+ if (f->format == FMT_LPAREN)
+ r = f;
+
+ /* If r is NULL because no node was found, the whole tree will be used */
+
+ array[0].current = r;
+ array[0].count = 0;
+}
+
+
+/* next_format0()-- Get the next format node without worrying about
+ * reversion. Returns NULL when we hit the end of the list.
+ * Parenthesis nodes are incremented after the list has been
+ * exhausted, other nodes are incremented before they are returned. */
+
+static fnode *
+next_format0 (fnode * f)
+{
+ fnode *r;
+
+ if (f == NULL)
+ return NULL;
+
+ if (f->format != FMT_LPAREN)
+ {
+ f->count++;
+ if (f->count <= f->repeat)
+ return f;
+
+ f->count = 0;
+ return NULL;
+ }
+
+ /* Deal with a parenthesis node */
+
+ for (; f->count < f->repeat; f->count++)
+ {
+ if (f->current == NULL)
+ f->current = f->u.child;
+
+ for (; f->current != NULL; f->current = f->current->next)
+ {
+ r = next_format0 (f->current);
+ if (r != NULL)
+ return r;
+ }
+ }
+
+ f->count = 0;
+ return NULL;
+}
+
+
+/* next_format()-- Return the next format node. If the format list
+ * ends up being exhausted, we do reversion. Reversion is only
+ * allowed if the we've seen a data descriptor since the
+ * initialization or the last reversion. We return NULL if the there
+ * are no more data descriptors to return (which is an error
+ * condition). */
+
+fnode *
+next_format (void)
+{
+ format_token t;
+ fnode *f;
+
+ if (saved_format != NULL)
+ { /* Deal with a pushed-back format node */
+ f = saved_format;
+ saved_format = NULL;
+ goto done;
+ }
+
+ f = next_format0 (&array[0]);
+ if (f == NULL)
+ {
+ if (!reversion_ok)
+ {
+ return NULL;
+ }
+
+ reversion_ok = 0;
+ revert ();
+
+ f = next_format0 (&array[0]);
+ if (f == NULL)
+ {
+ format_error (NULL, reversion_error);
+ return NULL;
+ }
+
+ /* Push the first reverted token and return a colon node in case
+ * there are no more data items. */
+
+ saved_format = f;
+ return &colon_node;
+ }
+
+ /* If this is a data edit descriptor, then reversion has become OK. */
+
+done:
+ t = f->format;
+
+ if (!reversion_ok &&
+ (t == FMT_I || t == FMT_B || t == FMT_O || t == FMT_Z || t == FMT_F ||
+ t == FMT_E || t == FMT_EN || t == FMT_ES || t == FMT_G || t == FMT_L ||
+ t == FMT_A || t == FMT_D))
+ reversion_ok = 1;
+ return f;
+}
+
+
+/* unget_format()-- Push the given format back so that it will be
+ * returned on the next call to next_format() without affecting
+ * counts. This is necessary when we've encountered a data
+ * descriptor, but don't know what the data item is yet. The format
+ * node is pushed back, and we return control to the main program,
+ * which calls the library back with the data item (or not). */
+
+void
+unget_format (fnode * f)
+{
+
+ saved_format = f;
+}
+
+
+
+
+#if 0
+
+static void dump_format1 (fnode * f);
+
+/* dump_format0()-- Dump a single format node */
+
+void
+dump_format0 (fnode * f)
+{
+ char *p;
+ int i;
+
+ switch (f->format)
+ {
+ case FMT_COLON:
+ st_printf (" :");
+ break;
+ case FMT_SLASH:
+ st_printf (" %d/", f->u.r);
+ break;
+ case FMT_DOLLAR:
+ st_printf (" $");
+ break;
+ case FMT_T:
+ st_printf (" T%d", f->u.n);
+ break;
+ case FMT_TR:
+ st_printf (" TR%d", f->u.n);
+ break;
+ case FMT_TL:
+ st_printf (" TL%d", f->u.n);
+ break;
+ case FMT_X:
+ st_printf (" %dX", f->u.n);
+ break;
+ case FMT_S:
+ st_printf (" S");
+ break;
+ case FMT_SS:
+ st_printf (" SS");
+ break;
+ case FMT_SP:
+ st_printf (" SP");
+ break;
+
+ case FMT_LPAREN:
+ if (f->repeat == 1)
+ st_printf (" (");
+ else
+ st_printf (" %d(", f->repeat);
+
+ dump_format1 (f->u.child);
+ st_printf (" )");
+ break;
+
+ case FMT_STRING:
+ st_printf (" '");
+ p = f->u.string.p;
+ for (i = f->u.string.length; i > 0; i--)
+ st_printf ("%c", *p++);
+
+ st_printf ("'");
+ break;
+
+ case FMT_P:
+ st_printf (" %dP", f->u.k);
+ break;
+ case FMT_I:
+ st_printf (" %dI%d.%d", f->repeat, f->u.integer.w, f->u.integer.m);
+ break;
+
+ case FMT_B:
+ st_printf (" %dB%d.%d", f->repeat, f->u.integer.w, f->u.integer.m);
+ break;
+
+ case FMT_O:
+ st_printf (" %dO%d.%d", f->repeat, f->u.integer.w, f->u.integer.m);
+ break;
+
+ case FMT_Z:
+ st_printf (" %dZ%d.%d", f->repeat, f->u.integer.w, f->u.integer.m);
+ break;
+
+ case FMT_BN:
+ st_printf (" BN");
+ break;
+ case FMT_BZ:
+ st_printf (" BZ");
+ break;
+ case FMT_D:
+ st_printf (" %dD%d.%d", f->repeat, f->u.real.w, f->u.real.d);
+ break;
+
+ case FMT_EN:
+ st_printf (" %dEN%d.%dE%d", f->repeat, f->u.real.w, f->u.real.d,
+ f->u.real.e);
+ break;
+
+ case FMT_ES:
+ st_printf (" %dES%d.%dE%d", f->repeat, f->u.real.w, f->u.real.d,
+ f->u.real.e);
+ break;
+
+ case FMT_F:
+ st_printf (" %dF%d.%d", f->repeat, f->u.real.w, f->u.real.d);
+ break;
+
+ case FMT_E:
+ st_printf (" %dE%d.%dE%d", f->repeat, f->u.real.w, f->u.real.d,
+ f->u.real.e);
+ break;
+
+ case FMT_G:
+ st_printf (" %dG%d.%dE%d", f->repeat, f->u.real.w, f->u.real.d,
+ f->u.real.e);
+ break;
+
+ case FMT_L:
+ st_printf (" %dL%d", f->repeat, f->u.w);
+ break;
+ case FMT_A:
+ st_printf (" %dA%d", f->repeat, f->u.w);
+ break;
+
+ default:
+ st_printf (" ???");
+ break;
+ }
+}
+
+
+/* dump_format1()-- Dump a string of format nodes */
+
+static void
+dump_format1 (fnode * f)
+{
+
+ for (; f; f = f->next)
+ dump_format1 (f);
+}
+
+/* dump_format()-- Dump the whole format node tree */
+
+void
+dump_format (void)
+{
+
+ st_printf ("format = ");
+ dump_format0 (&array[0]);
+ st_printf ("\n");
+}
+
+
+void
+next_test (void)
+{
+ fnode *f;
+ int i;
+
+ for (i = 0; i < 20; i++)
+ {
+ f = next_format ();
+ if (f == NULL)
+ {
+ st_printf ("No format!\n");
+ break;
+ }
+
+ dump_format1 (f);
+ st_printf ("\n");
+ }
+}
+
+#endif
diff --git a/libgfortran/io/inquire.c b/libgfortran/io/inquire.c
new file mode 100644
index 00000000000..88e805ec96f
--- /dev/null
+++ b/libgfortran/io/inquire.c
@@ -0,0 +1,371 @@
+/* Copyright (C) 2002-2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran 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 2, or (at your option)
+any later version.
+
+Libgfortran 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 Libgfortran; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+/* Implement the non-IOLENGTH variant of the INQUIRY statement */
+
+#include "config.h"
+#include "libgfortran.h"
+#include "io.h"
+
+
+static char undefined[] = "UNDEFINED";
+
+
+/* inquire_via_unit()-- Inquiry via unit number. The unit might not exist. */
+
+static void
+inquire_via_unit (unit_t * u)
+{
+ const char *p;
+
+ if (ioparm.exist != NULL)
+ *ioparm.exist = (u != NULL);
+
+ if (ioparm.opened != NULL)
+ *ioparm.opened = (u != NULL);
+
+ if (ioparm.number != NULL)
+ *ioparm.number = (u != NULL) ? u->unit_number : -1;
+
+ if (ioparm.named != NULL)
+ *ioparm.named = (u != NULL && u->flags.status != STATUS_SCRATCH);
+
+ if (ioparm.name != NULL && u != NULL && u->flags.status != STATUS_SCRATCH)
+ fstrcpy (ioparm.name, ioparm.name_len, u->file, u->file_len);
+
+ if (ioparm.access != NULL)
+ {
+ if (u == NULL)
+ p = undefined;
+ else
+ switch (u->flags.access)
+ {
+ case ACCESS_SEQUENTIAL:
+ p = "SEQUENTIAL";
+ break;
+ case ACCESS_DIRECT:
+ p = "DIRECT";
+ break;
+ default:
+ internal_error ("inquire_via_unit(): Bad access");
+ }
+
+ cf_strcpy (ioparm.access, ioparm.access_len, p);
+ }
+
+ if (ioparm.sequential != NULL)
+ {
+ p = (u == NULL) ? inquire_sequential (NULL, 0) :
+ inquire_sequential (u->file, u->file_len);
+
+ cf_strcpy (ioparm.sequential, ioparm.sequential_len, p);
+ }
+
+ if (ioparm.direct != NULL)
+ {
+ p = (u == NULL) ? inquire_direct (NULL, 0) :
+ inquire_direct (u->file, u->file_len);
+
+ cf_strcpy (ioparm.direct, ioparm.direct_len, p);
+ }
+
+ if (ioparm.form != NULL)
+ {
+ if (u == NULL)
+ p = undefined;
+ else
+ switch (u->flags.form)
+ {
+ case FORM_FORMATTED:
+ p = "FORMATTED";
+ break;
+ case FORM_UNFORMATTED:
+ p = "UNFORMATTED";
+ break;
+ default:
+ internal_error ("inquire_via_unit(): Bad form");
+ }
+
+ cf_strcpy (ioparm.form, ioparm.form_len, p);
+ }
+
+ if (ioparm.formatted != NULL)
+ {
+ p = (u == NULL) ? inquire_formatted (NULL, 0) :
+ inquire_formatted (u->file, u->file_len);
+
+ cf_strcpy (ioparm.formatted, ioparm.formatted_len, p);
+ }
+
+ if (ioparm.unformatted != NULL)
+ {
+ p = (u == NULL) ? inquire_unformatted (NULL, 0) :
+ inquire_unformatted (u->file, u->file_len);
+
+ cf_strcpy (ioparm.unformatted, ioparm.unformatted_len, p);
+ }
+
+ if (ioparm.recl_out != NULL)
+ *ioparm.recl_out = (u != NULL) ? u->recl : 0;
+
+ if (ioparm.nextrec != NULL)
+ *ioparm.nextrec = (u != NULL) ? u->last_record + 1 : 0;
+
+ if (ioparm.blank != NULL)
+ {
+ if (u == NULL)
+ p = undefined;
+ else
+ switch (u->flags.blank)
+ {
+ case BLANK_NULL:
+ p = "NULL";
+ break;
+ case BLANK_ZERO:
+ p = "ZERO";
+ break;
+ default:
+ internal_error ("inquire_via_unit(): Bad blank");
+ }
+
+ cf_strcpy (ioparm.blank, ioparm.blank_len, p);
+ }
+
+ if (ioparm.position != NULL)
+ {
+ if (u == NULL || u->flags.access == ACCESS_DIRECT)
+ p = undefined;
+ else
+ {
+ p = NULL; /* TODO: Try to decode what the standard says... */
+ }
+
+ cf_strcpy (ioparm.blank, ioparm.blank_len, p);
+ }
+
+ if (ioparm.action != NULL)
+ {
+ if (u == NULL)
+ p = undefined;
+ else
+ switch (u->flags.action)
+ {
+ case ACTION_READ:
+ p = "READ";
+ break;
+ case ACTION_WRITE:
+ p = "WRITE";
+ break;
+ case ACTION_READWRITE:
+ p = "READWRITE";
+ break;
+ default:
+ internal_error ("inquire_via_unit(): Bad action");
+ }
+
+ cf_strcpy (ioparm.action, ioparm.action_len, p);
+ }
+
+ if (ioparm.read != NULL)
+ {
+ p = (u == NULL) ? inquire_read (NULL, 0) :
+ inquire_read (u->file, u->file_len);
+
+ cf_strcpy (ioparm.read, ioparm.read_len, p);
+ }
+
+ if (ioparm.write != NULL)
+ {
+ p = (u == NULL) ? inquire_write (NULL, 0) :
+ inquire_write (u->file, u->file_len);
+
+ cf_strcpy (ioparm.write, ioparm.write_len, p);
+ }
+
+ if (ioparm.readwrite != NULL)
+ {
+ p = (u == NULL) ? inquire_readwrite (NULL, 0) :
+ inquire_readwrite (u->file, u->file_len);
+
+ cf_strcpy (ioparm.readwrite, ioparm.readwrite_len, p);
+ }
+
+ if (ioparm.delim != NULL)
+ {
+ if (u == NULL || u->flags.form != FORM_FORMATTED)
+ p = undefined;
+ else
+ switch (u->flags.delim)
+ {
+ case DELIM_NONE:
+ p = "NONE";
+ break;
+ case DELIM_QUOTE:
+ p = "QUOTE";
+ break;
+ case DELIM_APOSTROPHE:
+ p = "APOSTROPHE";
+ break;
+ default:
+ internal_error ("inquire_via_unit(): Bad delim");
+ }
+
+ cf_strcpy (ioparm.access, ioparm.access_len, p);
+ }
+
+ if (ioparm.pad != NULL)
+ {
+ if (u == NULL || u->flags.form != FORM_FORMATTED)
+ p = undefined;
+ else
+ switch (u->flags.pad)
+ {
+ case PAD_NO:
+ p = "NO";
+ break;
+ case PAD_YES:
+ p = "YES";
+ break;
+ default:
+ internal_error ("inquire_via_unit(): Bad pad");
+ }
+
+ cf_strcpy (ioparm.pad, ioparm.pad_len, p);
+ }
+}
+
+
+/* inquire_via_filename()-- Inquiry via filename. This subroutine is
+ * only used if the filename is *not* connected to a unit number. */
+
+static void
+inquire_via_filename (void)
+{
+ const char *p;
+
+ if (ioparm.exist != NULL)
+ *ioparm.exist = file_exists ();
+
+ if (ioparm.opened != NULL)
+ *ioparm.opened = 0;
+
+ if (ioparm.number != NULL)
+ *ioparm.number = -1;
+
+ if (ioparm.named != NULL)
+ *ioparm.named = 1;
+
+ if (ioparm.name != NULL)
+ fstrcpy (ioparm.name, ioparm.name_len, ioparm.file, ioparm.file_len);
+
+ if (ioparm.access != NULL)
+ cf_strcpy (ioparm.access, ioparm.access_len, undefined);
+
+ if (ioparm.sequential != NULL)
+ {
+ p = inquire_sequential (ioparm.file, ioparm.file_len);
+ cf_strcpy (ioparm.sequential, ioparm.sequential_len, p);
+ }
+
+ if (ioparm.direct != NULL)
+ {
+ p = inquire_direct (ioparm.file, ioparm.file_len);
+ cf_strcpy (ioparm.direct, ioparm.direct_len, p);
+ }
+
+ if (ioparm.form != NULL)
+ cf_strcpy (ioparm.form, ioparm.form_len, undefined);
+
+ if (ioparm.formatted != NULL)
+ {
+ p = inquire_formatted (ioparm.file, ioparm.file_len);
+ cf_strcpy (ioparm.formatted, ioparm.formatted_len, p);
+ }
+
+ if (ioparm.unformatted != NULL)
+ {
+ p = inquire_unformatted (ioparm.file, ioparm.file_len);
+ cf_strcpy (ioparm.unformatted, ioparm.unformatted_len, p);
+ }
+
+ if (ioparm.recl_out != NULL)
+ *ioparm.recl_out = 0;
+
+ if (ioparm.nextrec != NULL)
+ *ioparm.nextrec = 0;
+
+ if (ioparm.blank != NULL)
+ cf_strcpy (ioparm.blank, ioparm.blank_len, undefined);
+
+ if (ioparm.position != NULL)
+ cf_strcpy (ioparm.position, ioparm.position_len, undefined);
+
+ if (ioparm.access != NULL)
+ cf_strcpy (ioparm.access, ioparm.access_len, undefined);
+
+ if (ioparm.read != NULL)
+ {
+ p = inquire_read (ioparm.file, ioparm.file_len);
+ cf_strcpy (ioparm.read, ioparm.read_len, p);
+ }
+
+ if (ioparm.write != NULL)
+ {
+ p = inquire_write (ioparm.file, ioparm.file_len);
+ cf_strcpy (ioparm.write, ioparm.write_len, p);
+ }
+
+ if (ioparm.readwrite != NULL)
+ {
+ p = inquire_read (ioparm.file, ioparm.file_len);
+ cf_strcpy (ioparm.readwrite, ioparm.readwrite_len, p);
+ }
+
+ if (ioparm.delim != NULL)
+ cf_strcpy (ioparm.delim, ioparm.delim_len, undefined);
+
+ if (ioparm.pad != NULL)
+ cf_strcpy (ioparm.pad, ioparm.pad_len, undefined);
+
+}
+
+
+
+void
+st_inquire (void)
+{
+ unit_t *u;
+
+ library_start ();
+
+ if (ioparm.file == NULL)
+ inquire_via_unit (find_unit (ioparm.unit));
+ else
+ {
+ u = find_file ();
+ if (u == NULL)
+ inquire_via_filename ();
+ else
+ inquire_via_unit (u);
+ }
+
+ library_end ();
+}
diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h
new file mode 100644
index 00000000000..3b01912f09a
--- /dev/null
+++ b/libgfortran/io/io.h
@@ -0,0 +1,653 @@
+/* Copyright (C) 2002-2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran 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 2, or (at your option)
+any later version.
+
+Libgfortran 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 Libgfortran; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#ifndef GFOR_IO_H
+#define GFOR_IO_H
+
+/* IO library include. */
+
+#include <setjmp.h>
+#include "libgfortran.h"
+#define DEFAULT_TEMPDIR "/var/tmp"
+
+/* Basic types used in data transfers. */
+
+typedef enum
+{ BT_NULL, BT_INTEGER, BT_LOGICAL, BT_CHARACTER, BT_REAL,
+ BT_COMPLEX
+}
+bt;
+
+
+typedef enum
+{ SUCCESS = 1, FAILURE }
+try;
+
+typedef struct stream
+{
+ char *(*alloc_w_at) (struct stream *, int *, offset_t);
+ char *(*alloc_r_at) (struct stream *, int *, offset_t);
+ try (*sfree) (struct stream *);
+ try (*close) (struct stream *);
+ try (*seek) (struct stream *, offset_t);
+ try (*truncate) (struct stream *);
+}
+stream;
+
+
+/* Macros for doing file I/O given a stream. */
+
+#define sfree(s) ((s)->sfree)(s)
+#define sclose(s) ((s)->close)(s)
+
+#define salloc_r(s, len) ((s)->alloc_r_at)(s, len, -1)
+#define salloc_w(s, len) ((s)->alloc_w_at)(s, len, -1)
+
+#define salloc_r_at(s, len, where) ((s)->alloc_r_at)(s, len, where)
+#define salloc_w_at(s, len, where) ((s)->alloc_w_at)(s, len, where)
+
+#define sseek(s, pos) ((s)->seek)(s, pos)
+#define struncate(s) ((s)->truncate)(s)
+
+/* Namelist represent object */
+/*
+ Namelist Records
+ &groupname object=value [,object=value].../
+ or
+ &groupname object=value [,object=value]...&groupname
+
+ Even more complex, during the execution of a program containing a
+ namelist READ statement, you can specify a question mark character(?)
+ or a question mark character preceded by an equal sign(=?) to get
+ the information of the namelist group. By '?', the name of variables
+ in the namelist will be displayed, by '=?', the name and value of
+ variables will be displayed.
+
+ All these requirements need a new data structure to record all info
+ about the namelist.
+*/
+
+typedef struct namelist_type
+{
+ char * var_name;
+ void * mem_pos;
+ int value_acquired;
+ int len;
+ bt type;
+ struct namelist_type * next;
+}
+namelist_info;
+
+/* Options for the OPEN statement. */
+
+typedef enum
+{ ACCESS_SEQUENTIAL, ACCESS_DIRECT,
+ ACCESS_UNSPECIFIED
+}
+unit_access;
+
+typedef enum
+{ ACTION_READ, ACTION_WRITE, ACTION_READWRITE,
+ ACTION_UNSPECIFIED
+}
+unit_action;
+
+typedef enum
+{ BLANK_NULL, BLANK_ZERO, BLANK_UNSPECIFIED }
+unit_blank;
+
+typedef enum
+{ DELIM_NONE, DELIM_APOSTROPHE, DELIM_QUOTE,
+ DELIM_UNSPECIFIED
+}
+unit_delim;
+
+typedef enum
+{ FORM_FORMATTED, FORM_UNFORMATTED, FORM_UNSPECIFIED }
+unit_form;
+
+typedef enum
+{ POSITION_ASIS, POSITION_REWIND, POSITION_APPEND,
+ POSITION_UNSPECIFIED
+}
+unit_position;
+
+typedef enum
+{ STATUS_UNKNOWN, STATUS_OLD, STATUS_NEW, STATUS_SCRATCH,
+ STATUS_REPLACE, STATUS_UNSPECIFIED
+}
+unit_status;
+
+typedef enum
+{ PAD_YES, PAD_NO, PAD_UNSPECIFIED }
+unit_pad;
+
+typedef enum
+{ ADVANCE_YES, ADVANCE_NO, ADVANCE_UNSPECIFIED }
+unit_advance;
+
+
+
+/* Statement parameters. These are all the things that can appear in
+ an I/O statement. Some are inputs and some are outputs, but none
+ are both. All of these values are initially zeroed and are zeroed
+ at the end of a library statement. The relevant values need to be
+ set before entry to an I/O statement. This structure needs to be
+ duplicated by the back end. */
+
+typedef struct
+{
+ int unit;
+ int err, end, eor, list_format; /* These are flags, not values. */
+
+/* Return values from library statements. These are returned only if
+ the labels are specified in the statement itself and the condition
+ occurs. In most cases, none of the labels are specified and the
+ return value does not have to be checked. Must be consistent with
+ the front end. */
+
+ enum
+ {
+ LIBRARY_OK = 0,
+ LIBRARY_ERROR,
+ LIBRARY_END,
+ LIBRARY_EOR
+ }
+ library_return;
+
+ int *iostat, *exist, *opened, *number, *named, rec, *nextrec, *size;
+
+ int recl_in;
+ int *recl_out;
+
+ char *file;
+ int file_len;
+ char *status;
+ int status_len;
+ char *access;
+ int access_len;
+ char *form;
+ int form_len;
+ char *blank;
+ int blank_len;
+ char *position;
+ int position_len;
+ char *action;
+ int action_len;
+ char *delim;
+ int delim_len;
+ char *pad;
+ int pad_len;
+ char *format;
+ int format_len;
+ char *advance;
+ int advance_len;
+ char *name;
+ int name_len;
+ char *internal_unit;
+ int internal_unit_len;
+ char *sequential;
+ int sequential_len;
+ char *direct;
+ int direct_len;
+ char *formatted;
+ int formatted_len;
+ char *unformatted;
+ int unformatted_len;
+ char *read;
+ int read_len;
+ char *write;
+ int write_len;
+ char *readwrite;
+ int readwrite_len;
+
+/* namelist related data */
+ char * namelist_name;
+ int namelist_name_len;
+ int namelist_read_mode;
+}
+st_parameter;
+
+
+
+#define ioparm prefix(ioparm)
+extern st_parameter ioparm;
+
+#define ionml prefix(ionml)
+extern namelist_info * ionml;
+
+typedef struct
+{
+ unit_access access;
+ unit_action action;
+ unit_blank blank;
+ unit_delim delim;
+ unit_form form;
+ int is_notpadded;
+ unit_position position;
+ unit_status status;
+ unit_pad pad;
+}
+unit_flags;
+
+
+/* The default value of record length is defined here. This value can
+ be overriden by the OPEN statement or by an environment variable. */
+
+#define DEFAULT_RECL 10000
+
+
+typedef struct unit_t
+{
+ int unit_number;
+
+ stream *s;
+
+ struct unit_t *left, *right; /* Treap links. */
+ int priority;
+
+ int read_bad, current_record;
+ enum
+ { NO_ENDFILE, AT_ENDFILE, AFTER_ENDFILE }
+ endfile;
+
+ unit_flags flags;
+ offset_t recl, last_record, maxrec, bytes_left;
+
+ /* recl -- Record length of the file.
+ last_record -- Last record number read or written
+ maxrec -- Maximum record number in a direct access file
+ bytes_left -- Bytes left in current record. */
+
+ int file_len;
+ char file[1]; /* Filename is allocated at the end of the structure. */
+}
+unit_t;
+
+/* Global variables. Putting these in a structure makes it easier to
+ maintain, particularly with the constraint of a prefix. */
+
+typedef struct
+{
+ int in_library; /* Nonzero if a library call is being processed. */
+ int size; /* Bytes processed by the current data-transfer statement. */
+ offset_t max_offset; /* Maximum file offset. */
+ int item_count; /* Item number in a formatted data transfer. */
+ int reversion_flag; /* Format reversion has occurred. */
+ int first_item;
+
+ unit_t *unit_root;
+ int seen_dollar;
+
+ enum {READING, WRITING} mode;
+
+ unit_blank blank_status;
+ enum {SIGN_S, SIGN_SS, SIGN_SP} sign_status;
+ int scale_factor;
+ jmp_buf eof_jump;
+}
+global_t;
+
+
+#define g prefix(g)
+extern global_t g;
+
+
+#define current_unit prefix(current_unit)
+extern unit_t *current_unit;
+
+/* Format tokens. Only about half of these can be stored in the
+ format nodes. */
+
+typedef enum
+{
+ FMT_NONE = 0, FMT_UNKNOWN, FMT_SIGNED_INT, FMT_ZERO, FMT_POSINT, FMT_PERIOD,
+ FMT_COMMA, FMT_COLON, FMT_SLASH, FMT_DOLLAR, FMT_T, FMT_TR, FMT_TL,
+ FMT_LPAREN, FMT_RPAREN, FMT_X, FMT_S, FMT_SS, FMT_SP, FMT_STRING,
+ FMT_BADSTRING, FMT_P, FMT_I, FMT_B, FMT_BN, FMT_BZ, FMT_O, FMT_Z, FMT_F,
+ FMT_E, FMT_EN, FMT_ES, FMT_G, FMT_L, FMT_A, FMT_D, FMT_H, FMT_END
+}
+format_token;
+
+
+/* Format nodes. A format string is converted into a tree of these
+ structures, which is traversed as part of a data transfer statement. */
+
+typedef struct fnode
+{
+ format_token format;
+ int repeat;
+ struct fnode *next;
+ char *source;
+
+ union
+ {
+ struct
+ {
+ int w, d, e;
+ }
+ real;
+
+ struct
+ {
+ int length;
+ char *p;
+ }
+ string;
+
+ struct
+ {
+ int w, m;
+ }
+ integer;
+
+ int w;
+ int k;
+ int r;
+ int n;
+
+ struct fnode *child;
+ }
+ u;
+
+ /* Members for traversing the tree during data transfer. */
+
+ int count;
+ struct fnode *current;
+
+}
+fnode;
+
+
+/* unix.c */
+
+#define sys_exit prefix(sys_exit)
+void sys_exit (int) __attribute__ ((noreturn));
+
+#define move_pos_offset prefix(move_pos_offset)
+int move_pos_offset (stream *, int);
+
+#define get_oserror prefix(get_oserror)
+const char *get_oserror (void);
+
+#define compare_files prefix(compare_files)
+int compare_files (stream *, stream *);
+
+#define init_error_stream prefix(init_error_stream)
+stream *init_error_stream (void);
+
+#define open_external prefix(open_external)
+stream *open_external (unit_action, unit_status);
+
+#define open_internal prefix(open_internal)
+stream *open_internal (char *, int);
+
+#define input_stream prefix(input_stream)
+stream *input_stream (void);
+
+#define output_stream prefix(output_stream)
+stream *output_stream (void);
+
+#define compare_file_filename prefix(compare_file_filename)
+int compare_file_filename (stream *, const char *, int);
+
+#define find_file prefix(find_file)
+unit_t *find_file (void);
+
+#define stream_at_bof prefix(stream_at_bof)
+int stream_at_bof (stream *);
+
+#define stream_at_eof prefix(stream_at_eof)
+int stream_at_eof (stream *);
+
+#define delete_file prefix(delete_file)
+int delete_file (unit_t *);
+
+#define file_exists prefix(file_exists)
+int file_exists (void);
+
+#define inquire_sequential prefix(inquire_sequential)
+const char *inquire_sequential (const char *, int);
+
+#define inquire_direct prefix(inquire_direct)
+const char *inquire_direct (const char *, int);
+
+#define inquire_formatted prefix(inquire_formatted)
+const char *inquire_formatted (const char *, int);
+
+#define inquire_unformatted prefix(inquire_unformatted)
+const char *inquire_unformatted (const char *, int);
+
+#define inquire_read prefix(inquire_read)
+const char *inquire_read (const char *, int);
+
+#define inquire_write prefix(inquire_write)
+const char *inquire_write (const char *, int);
+
+#define inquire_readwrite prefix(inquire_readwrite)
+const char *inquire_readwrite (const char *, int);
+
+#define file_length prefix(file_length)
+offset_t file_length (stream *);
+
+#define file_position prefix(file_position)
+offset_t file_position (stream *);
+
+#define is_seekable prefix(is_seekable)
+int is_seekable (stream *);
+
+#define empty_internal_buffer prefix(empty_internal_buffer)
+void empty_internal_buffer(stream *);
+
+
+/* unit.c */
+
+#define insert_unit prefix(insert_unix)
+void insert_unit (unit_t *);
+
+#define close_unit prefix(close_unit)
+int close_unit (unit_t *);
+
+#define is_internal_unit prefix(is_internal_unit)
+int is_internal_unit (void);
+
+#define find_unit prefix(find_unit)
+unit_t *find_unit (int);
+
+#define get_unit prefix(get_unit)
+unit_t *get_unit (int);
+
+/* open.c */
+
+#define test_endfile prefix(test_endfile)
+void test_endfile (unit_t *);
+
+#define new_unit prefix(new_unit)
+void new_unit (unit_flags *);
+
+/* format.c */
+
+#define parse_format prefix(parse_format)
+void parse_format (void);
+
+#define next_format prefix(next_format)
+fnode *next_format (void);
+
+#define unget_format prefix(unget_format)
+void unget_format (fnode *);
+
+#define format_error prefix(format_error)
+void format_error (fnode *, const char *);
+
+#define free_fnodes prefix(free_fnodes)
+void free_fnodes (void);
+
+/* transfer.c */
+
+#define SCRATCH_SIZE 300
+
+#define scratch prefix(scratch)
+extern char scratch[];
+
+#define type_name prefix(type_name)
+const char *type_name (bt);
+
+#define read_block prefix(read_block)
+void *read_block (int *);
+
+#define write_block prefix(write_block)
+void *write_block (int);
+
+#define transfer_integer prefix(transfer_integer)
+void transfer_integer (void *, int);
+
+#define transfer_real prefix(transfer_real)
+void transfer_real (void *, int);
+
+#define transfer_logical prefix(transfer_logical)
+void transfer_logical (void *, int);
+
+#define transfer_character prefix(transfer_character)
+void transfer_character (void *, int);
+
+#define transfer_complex prefix(transfer_complex)
+void transfer_complex (void *, int);
+
+#define next_record prefix(next_record)
+void next_record (int);
+
+#define st_set_nml_var_int prefix(st_set_nml_var_int)
+void st_set_nml_var_int (void * , char * , int , int );
+
+#define st_set_nml_var_float prefix(st_set_nml_var_float)
+void st_set_nml_var_float (void * , char * , int , int );
+
+#define st_set_nml_var_char prefix(st_set_nml_var_char)
+void st_set_nml_var_char (void * , char * , int , int );
+
+#define st_set_nml_var_complex prefix(st_set_nml_var_complex)
+void st_set_nml_var_complex (void * , char * , int , int );
+
+#define st_set_nml_var_log prefix(st_set_nml_var_log)
+void st_set_nml_var_log (void * , char * , int , int );
+
+/* read.c */
+
+#define set_integer prefix(set_integer)
+void set_integer (void *, int64_t, int);
+
+#define max_value prefix(max_value)
+uint64_t max_value (int, int);
+
+#define convert_real prefix(convert_real)
+int convert_real (void *, const char *, int);
+
+#define read_a prefix(read_a)
+void read_a (fnode *, char *, int);
+
+#define read_f prefix(read_f)
+void read_f (fnode *, char *, int);
+
+#define read_l prefix(read_l)
+void read_l (fnode *, char *, int);
+
+#define read_x prefix(read_x)
+void read_x (fnode *);
+
+#define read_radix prefix(read_radix)
+void read_radix (fnode *, char *, int, int);
+
+#define read_decimal prefix(read_decimal)
+void read_decimal (fnode *, char *, int);
+
+/* list_read.c */
+
+#define list_formatted_read prefix(list_formatted_read)
+void list_formatted_read (bt, void *, int);
+
+#define finish_list_read prefix(finish_list_read)
+void finish_list_read (void);
+
+#define init_at_eol prefix(init_at_eol)
+void init_at_eol();
+
+#define namelist_read prefix(namelist_read)
+void namelist_read();
+
+#define namelist_write prefix(namelist_write)
+void namelist_write();
+
+/* write.c */
+
+#define write_a prefix(write_a)
+void write_a (fnode *, const char *, int);
+
+#define write_b prefix(write_b)
+void write_b (fnode *, const char *, int);
+
+#define write_d prefix(write_d)
+void write_d (fnode *, const char *, int);
+
+#define write_e prefix(write_e)
+void write_e (fnode *, const char *, int);
+
+#define write_en prefix(write_en)
+void write_en (fnode *, const char *, int);
+
+#define write_es prefix(write_es)
+void write_es (fnode *, const char *, int);
+
+#define write_f prefix(write_f)
+void write_f (fnode *, const char *, int);
+
+#define write_i prefix(write_i)
+void write_i (fnode *, const char *, int);
+
+#define write_l prefix(write_l)
+void write_l (fnode *, char *, int);
+
+#define write_o prefix(write_o)
+void write_o (fnode *, const char *, int);
+
+#define write_x prefix(write_x)
+void write_x (fnode *);
+
+#define write_z prefix(write_z)
+void write_z (fnode *, const char *, int);
+
+#define list_formatted_write prefix(list_formatted_write)
+void list_formatted_write (bt, void *, int);
+
+
+#define st_open prefix(st_open)
+#define st_close prefix(st_close)
+#define st_inquire prefix(st_inquire)
+#define st_rewind prefix(st_rewind)
+#define st_read prefix(st_read)
+#define st_read_done prefix(st_read_done)
+#define st_write prefix(st_write)
+#define st_write_done prefix(st_write_done)
+#define st_backspace prefix(st_backspace)
+#define st_endfile prefix(st_endfile)
+
+
+void __MAIN (void);
+
+#endif
diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c
new file mode 100644
index 00000000000..2b62d31007c
--- /dev/null
+++ b/libgfortran/io/list_read.c
@@ -0,0 +1,1531 @@
+/* Copyright (C) 2002-2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran 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 2, or (at your option)
+any later version.
+
+Libgfortran 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 Libgfortran; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+#include "config.h"
+#include <string.h>
+#include <ctype.h>
+#include "libgfortran.h"
+#include "io.h"
+
+
+/* List directed input. Several parsing subroutines are practically
+ * reimplemented from formatted input, the reason being that there are
+ * all kinds of small differences between formatted and list directed
+ * parsing. */
+
+
+/* Subroutines for reading characters from the input. Because a
+ * repeat count is ambiguous with an integer, we have to read the
+ * whole digit string before seeing if there is a '*' which signals
+ * the repeat count. Since we can have a lot of potential leading
+ * zeros, we have to be able to back up by arbitrary amount. Because
+ * the input might not be seekable, we have to buffer the data
+ * ourselves. Data is buffered in scratch[] until it becomes too
+ * large, after which we start allocating memory on the heap. */
+
+static int repeat_count, saved_length, saved_used, input_complete, at_eol;
+static int comma_flag, namelist_mode;
+
+static char last_char, *saved_string;
+static bt saved_type;
+
+
+
+/* Storage area for values except for strings. Must be large enough
+ * to hold a complex value (two reals) of the largest kind */
+
+static char value[20];
+
+#define CASE_DIGITS case '0': case '1': case '2': case '3': case '4': \
+ case '5': case '6': case '7': case '8': case '9'
+
+#define CASE_SEPARATORS case ' ': case ',': case '/': case '\n': case '\t'
+
+/* This macro assumes that we're operating on a variable */
+
+#define is_separator(c) (c == '/' || c == ',' || c == '\n' || c == ' ' \
+ || c == '\t')
+
+/* Maximum repeat count. Less than ten times the maximum signed int32. */
+
+#define MAX_REPEAT 200000000
+
+
+/* push_char()-- Save a character to a string buffer, enlarging it as
+ * necessary. */
+
+static void
+push_char (char c)
+{
+ char *new;
+
+ if (saved_string == NULL)
+ {
+ saved_string = scratch;
+ memset (saved_string,0,SCRATCH_SIZE);
+ saved_length = SCRATCH_SIZE;
+ saved_used = 0;
+ }
+
+ if (saved_used >= saved_length)
+ {
+ saved_length = 2 * saved_length;
+ new = get_mem (2 * saved_length);
+
+ memset (new,0,2 * saved_length);
+
+ memcpy (new, saved_string, saved_used);
+ if (saved_string != scratch)
+ free_mem (saved_string);
+
+ saved_string = new;
+ }
+
+ saved_string[saved_used++] = c;
+}
+
+
+/* free_saved()-- Free the input buffer if necessary. */
+
+static void
+free_saved (void)
+{
+
+ if (saved_string == NULL)
+ return;
+
+ if (saved_string != scratch)
+ free_mem (saved_string);
+
+ saved_string = NULL;
+}
+
+
+static char
+next_char (void)
+{
+ int length;
+ char c, *p;
+
+ if (last_char != '\0')
+ {
+ at_eol = 0;
+ c = last_char;
+ last_char = '\0';
+ goto done;
+ }
+
+ length = 1;
+
+ p = salloc_r (current_unit->s, &length);
+ if (p == NULL)
+ {
+ generate_error (ERROR_OS, NULL);
+ return '\0';
+ }
+
+ if (length == 0)
+ longjmp (g.eof_jump, 1);
+ c = *p;
+
+done:
+ at_eol = (c == '\n');
+ return c;
+}
+
+
+/* unget_char()-- Push a character back onto the input */
+
+static void
+unget_char (char c)
+{
+
+ last_char = c;
+}
+
+
+/* eat_spaces()-- Skip over spaces in the input. Returns the nonspace
+ * character that terminated the eating and also places it back on the
+ * input. */
+
+static char
+eat_spaces (void)
+{
+ char c;
+
+ do
+ {
+ c = next_char ();
+ }
+ while (c == ' ' || c == '\t');
+
+ unget_char (c);
+ return c;
+}
+
+
+/* eat_separator()-- Skip over a separator. Technically, we don't
+ * always eat the whole separator. This is because if we've processed
+ * the last input item, then a separator is unnecessary. Plus the
+ * fact that operating systems usually deliver console input on a line
+ * basis.
+ *
+ * The upshot is that if we see a newline as part of reading a
+ * separator, we stop reading. If there are more input items, we
+ * continue reading the separator with finish_separator() which takes
+ * care of the fact that we may or may not have seen a comma as part
+ * of the separator. */
+
+static void
+eat_separator (void)
+{
+ char c;
+
+ eat_spaces ();
+ comma_flag = 0;
+
+ c = next_char ();
+ switch (c)
+ {
+ case ',':
+ comma_flag = 1;
+ eat_spaces ();
+ break;
+
+ case '/':
+ input_complete = 1;
+ next_record (0);
+ break;
+
+ case '\n':
+ break;
+
+ case '!':
+ if (namelist_mode)
+ { /* Eat a namelist comment */
+ do
+ c = next_char ();
+ while (c != '\n');
+
+ break;
+ }
+
+ /* Fall Through */
+
+ default:
+ unget_char (c);
+ break;
+ }
+}
+
+
+/* finish_separator()-- Finish processing a separator that was
+ * interrupted by a newline. If we're here, then another data item is
+ * present, so we finish what we started on the previous line. */
+
+static void
+finish_separator (void)
+{
+ char c;
+
+restart:
+ eat_spaces ();
+
+ c = next_char ();
+ switch (c)
+ {
+ case ',':
+ if (comma_flag)
+ unget_char (c);
+ else
+ {
+ c = eat_spaces ();
+ if (c == '\n')
+ goto restart;
+ }
+
+ break;
+
+ case '/':
+ input_complete = 1;
+ next_record (0);
+ break;
+
+ case '\n':
+ goto restart;
+
+ case '!':
+ if (namelist_mode)
+ {
+ do
+ c = next_char ();
+ while (c != '\n');
+
+ goto restart;
+ }
+
+ default:
+ unget_char (c);
+ break;
+ }
+}
+
+
+/* convert_integer()-- Convert an unsigned string to an integer. The
+ * length value is -1 if we are working on a repeat count. Returns
+ * nonzero if we have a range problem. As a side effect, frees the
+ * saved_string. */
+
+static int
+convert_integer (int length, int negative)
+{
+ char c, *buffer, message[100];
+ int m;
+ int64_t v, max, max10;
+
+ buffer = saved_string;
+ v = 0;
+
+ max = (length == -1) ? MAX_REPEAT : max_value (length, 1);
+ max10 = max / 10;
+
+ for (;;)
+ {
+ c = *buffer++;
+ if (c == '\0')
+ break;
+ c -= '0';
+
+ if (v > max10)
+ goto overflow;
+ v = 10 * v;
+
+ if (v > max - c)
+ goto overflow;
+ v += c;
+ }
+
+ m = 0;
+
+ if (length != -1)
+ {
+ if (negative)
+ v = -v;
+ set_integer (value, v, length);
+ }
+ else
+ {
+ repeat_count = v;
+
+ if (repeat_count == 0)
+ {
+ st_sprintf (message, "Zero repeat count in item %d of list input",
+ g.item_count);
+
+ generate_error (ERROR_READ_VALUE, message);
+ m = 1;
+ }
+ }
+
+ free_saved ();
+ return m;
+
+overflow:
+ if (length == -1)
+ st_sprintf (message, "Repeat count overflow in item %d of list input",
+ g.item_count);
+ else
+ st_sprintf (message, "Integer overflow while reading item %d",
+ g.item_count);
+
+ free_saved ();
+ generate_error (ERROR_READ_VALUE, message);
+
+ return 1;
+}
+
+
+/* parse_repeat()-- Parse a repeat count for logical and complex
+ * values which cannot begin with a digit. Returns nonzero if we are
+ * done, zero if we should continue on. */
+
+static int
+parse_repeat (void)
+{
+ char c, message[100];
+ int repeat;
+
+ c = next_char ();
+ switch (c)
+ {
+ CASE_DIGITS:
+ repeat = c - '0';
+ break;
+
+ CASE_SEPARATORS:
+ unget_char (c);
+ eat_separator ();
+ return 1;
+
+ default:
+ unget_char (c);
+ return 0;
+ }
+
+ for (;;)
+ {
+ c = next_char ();
+ switch (c)
+ {
+ CASE_DIGITS:
+ repeat = 10 * repeat + c - '0';
+
+ if (repeat > MAX_REPEAT)
+ {
+ st_sprintf (message,
+ "Repeat count overflow in item %d of list input",
+ g.item_count);
+
+ generate_error (ERROR_READ_VALUE, message);
+ return 1;
+ }
+
+ break;
+
+ case '*':
+ if (repeat == 0)
+ {
+ st_sprintf (message,
+ "Zero repeat count in item %d of list input",
+ g.item_count);
+
+ generate_error (ERROR_READ_VALUE, message);
+ return 1;
+ }
+
+ goto done;
+
+ default:
+ goto bad_repeat;
+ }
+ }
+
+done:
+ repeat_count = repeat;
+ return 0;
+
+bad_repeat:
+ st_sprintf (message, "Bad repeat count in item %d of list input",
+ g.item_count);
+
+ generate_error (ERROR_READ_VALUE, message);
+ return 1;
+}
+
+
+/* read_logical()-- Read a logical character on the input */
+
+static void
+read_logical (int length)
+{
+ char c, message[100];
+ int v;
+
+ if (parse_repeat ())
+ return;
+
+ c = next_char ();
+ switch (c)
+ {
+ case 't':
+ case 'T':
+ v = 1;
+ break;
+ case 'f':
+ case 'F':
+ v = 0;
+ break;
+
+ case '.':
+ c = next_char ();
+ switch (c)
+ {
+ case 't':
+ case 'T':
+ v = 1;
+ break;
+ case 'f':
+ case 'F':
+ v = 0;
+ break;
+ default:
+ goto bad_logical;
+ }
+
+ break;
+
+ CASE_SEPARATORS:
+ unget_char (c);
+ eat_separator ();
+ return; /* Null value */
+
+ default:
+ goto bad_logical;
+ }
+
+ saved_type = BT_LOGICAL;
+ saved_length = length;
+
+ /* Eat trailing garbage */
+
+ do
+ {
+ c = next_char ();
+ }
+ while (!is_separator (c));
+
+ unget_char (c);
+ eat_separator ();
+ free_saved ();
+ set_integer ((int *) value, v, length);
+
+ return;
+
+bad_logical:
+ st_sprintf (message, "Bad logical value while reading item %d",
+ g.item_count);
+
+ generate_error (ERROR_READ_VALUE, message);
+}
+
+
+/* read_integer()-- Reading integers is tricky because we can actually
+ * be reading a repeat count. We have to store the characters in a
+ * buffer because we could be reading an integer that is larger than the
+ * default int used for repeat counts. */
+
+static void
+read_integer (int length)
+{
+ char c, message[100];
+ int negative;
+
+ negative = 0;
+
+ c = next_char ();
+ switch (c)
+ {
+ case '-':
+ negative = 1;
+ /* Fall through */
+
+ case '+':
+ c = next_char ();
+ goto get_integer;
+
+ CASE_SEPARATORS: /* Single null */
+ unget_char (c);
+ eat_separator ();
+ return;
+
+ CASE_DIGITS:
+ push_char (c);
+ break;
+
+ default:
+ goto bad_integer;
+ }
+
+ /* Take care of what may be a repeat count */
+
+ for (;;)
+ {
+ c = next_char ();
+ switch (c)
+ {
+ CASE_DIGITS:
+ push_char (c);
+ break;
+
+ case '*':
+ push_char ('\0');
+ goto repeat;
+
+ CASE_SEPARATORS: /* Not a repeat count */
+ goto done;
+
+ default:
+ goto bad_integer;
+ }
+ }
+
+repeat:
+ if (convert_integer (-1, 0))
+ return;
+
+/* Get the real integer */
+
+ c = next_char ();
+ switch (c)
+ {
+ CASE_DIGITS:
+ break;
+
+ CASE_SEPARATORS:
+ unget_char (c);
+ eat_separator ();
+ return;
+
+ case '-':
+ negative = 1;
+ /* Fall through */
+
+ case '+':
+ c = next_char ();
+ break;
+ }
+
+get_integer:
+ if (!isdigit (c))
+ goto bad_integer;
+ push_char (c);
+
+ for (;;)
+ {
+ c = next_char ();
+ switch (c)
+ {
+ CASE_DIGITS:
+ push_char (c);
+ break;
+
+ CASE_SEPARATORS:
+ goto done;
+
+ default:
+ goto bad_integer;
+ }
+ }
+
+bad_integer:
+ free_saved ();
+
+ st_sprintf (message, "Bad integer for item %d in list input", g.item_count);
+ generate_error (ERROR_READ_VALUE, message);
+
+ return;
+
+done:
+ unget_char (c);
+ eat_separator ();
+
+ push_char ('\0');
+ if (convert_integer (length, negative))
+ {
+ free_saved ();
+ return;
+ }
+
+ free_saved ();
+ saved_type = BT_INTEGER;
+}
+
+
+/* read_character()-- Read a character variable */
+
+static void
+read_character (int length)
+{
+ char c, quote, message[100];
+
+ quote = ' '; /* Space means no quote character */
+
+ c = next_char ();
+ switch (c)
+ {
+ CASE_DIGITS:
+ push_char (c);
+ break;
+
+ CASE_SEPARATORS:
+ unget_char (c); /* NULL value */
+ eat_separator ();
+ return;
+
+ case '"':
+ case '\'':
+ quote = c;
+ goto get_string;
+
+ default:
+ push_char (c);
+ goto get_string;
+ }
+
+/* Deal with a possible repeat count */
+
+ for (;;)
+ {
+ c = next_char ();
+ switch (c)
+ {
+ CASE_DIGITS:
+ push_char (c);
+ break;
+
+ CASE_SEPARATORS:
+ unget_char (c);
+ goto done; /* String was only digits! */
+
+ case '*':
+ push_char ('\0');
+ goto got_repeat;
+
+ default:
+ push_char (c);
+ goto get_string; /* Not a repeat count after all */
+ }
+ }
+
+got_repeat:
+ if (convert_integer (-1, 0))
+ return;
+
+ /* Now get the real string */
+
+ c = next_char ();
+ switch (c)
+ {
+ CASE_SEPARATORS:
+ unget_char (c); /* repeated NULL values */
+ eat_separator ();
+ return;
+
+ case '"':
+ case '\'':
+ quote = c;
+ break;
+
+ default:
+ push_char (c);
+ break;
+ }
+
+get_string:
+ for (;;)
+ {
+ c = next_char ();
+ switch (c)
+ {
+ case '"':
+ case '\'':
+ if (c != quote)
+ {
+ push_char (c);
+ break;
+ }
+
+ /* See if we have a doubled quote character or the end of the string */
+
+ c = next_char ();
+ if (c == quote)
+ {
+ push_char (quote);
+ break;
+ }
+
+ unget_char (c);
+ goto done;
+
+ CASE_SEPARATORS:
+ if (quote == ' ')
+ {
+ unget_char (c);
+ goto done;
+ }
+
+ if (c != '\n')
+ push_char (c);
+ break;
+
+ default:
+ push_char (c);
+ break;
+ }
+ }
+
+/* At this point, we have to have a separator, or else the string is invalid */
+
+done:
+ c = next_char ();
+ if (is_separator (c))
+ {
+ unget_char (c);
+ eat_separator ();
+ saved_type = BT_CHARACTER;
+ }
+ else
+ {
+ free_saved ();
+ st_sprintf (message, "Invalid string input in item %d", g.item_count);
+ generate_error (ERROR_READ_VALUE, message);
+ }
+}
+
+
+/* parse_real()-- Parse a component of a complex constant or a real
+ * number that we are sure is already there. This is a straight real
+ * number parser. */
+
+static int
+parse_real (void *buffer, int length)
+{
+ char c, message[100];
+ int m, seen_dp;
+
+ c = next_char ();
+ if (c == '-' || c == '+')
+ {
+ push_char (c);
+ c = next_char ();
+ }
+
+ if (!isdigit (c) && c != '.')
+ goto bad;
+
+ push_char (c);
+
+ seen_dp = (c == '.') ? 1 : 0;
+
+ for (;;)
+ {
+ c = next_char ();
+ switch (c)
+ {
+ CASE_DIGITS:
+ push_char (c);
+ break;
+
+ case '.':
+ if (seen_dp)
+ goto bad;
+
+ seen_dp = 1;
+ push_char (c);
+ break;
+
+ case 'e':
+ case 'E':
+ case 'd':
+ case 'D':
+ push_char ('e');
+ goto exp1;
+
+ case '-':
+ case '+':
+ push_char ('e');
+ push_char (c);
+ c = next_char ();
+ goto exp2;
+
+ CASE_SEPARATORS:
+ unget_char (c);
+ goto done;
+
+ default:
+ goto done;
+ }
+ }
+
+exp1:
+ c = next_char ();
+ if (c != '-' && c != '+')
+ push_char ('+');
+ else
+ {
+ push_char (c);
+ c = next_char ();
+ }
+
+exp2:
+ if (!isdigit (c))
+ goto bad;
+ push_char (c);
+
+ for (;;)
+ {
+ c = next_char ();
+ switch (c)
+ {
+ CASE_DIGITS:
+ push_char (c);
+ break;
+
+ CASE_SEPARATORS:
+ unget_char (c);
+ goto done;
+
+ default:
+ goto done;
+ }
+ }
+
+done:
+ unget_char (c);
+ push_char ('\0');
+
+ m = convert_real (buffer, saved_string, length);
+ free_saved ();
+
+ return m;
+
+bad:
+ free_saved ();
+ st_sprintf (message, "Bad floating point number for item %d", g.item_count);
+ generate_error (ERROR_READ_VALUE, message);
+
+ return 1;
+}
+
+
+/* read_complex()-- Reading a complex number is straightforward
+ * because we can tell what it is right away. */
+
+static void
+read_complex (int length)
+{
+ char message[100];
+ char c;
+
+ if (parse_repeat ())
+ return;
+
+ c = next_char ();
+ switch (c)
+ {
+ case '(':
+ break;
+
+ CASE_SEPARATORS:
+ unget_char (c);
+ eat_separator ();
+ return;
+
+ default:
+ goto bad_complex;
+ }
+
+ eat_spaces ();
+ if (parse_real (value, length))
+ return;
+
+ eat_spaces ();
+ if (next_char () != ',')
+ goto bad_complex;
+
+ eat_spaces ();
+ if (parse_real (value + length, length))
+ return;
+
+ eat_spaces ();
+ if (next_char () != ')')
+ goto bad_complex;
+
+ c = next_char ();
+ if (!is_separator (c))
+ goto bad_complex;
+
+ unget_char (c);
+ eat_separator ();
+
+ free_saved ();
+ saved_type = BT_COMPLEX;
+ return;
+
+bad_complex:
+ st_sprintf (message, "Bad complex value in item %d of list input",
+ g.item_count);
+
+ generate_error (ERROR_READ_VALUE, message);
+}
+
+
+/* read_real()-- Parse a real number with a possible repeat count. */
+
+static void
+read_real (int length)
+{
+ char c, message[100];
+ int seen_dp;
+
+ seen_dp = 0;
+
+ c = next_char ();
+ switch (c)
+ {
+ CASE_DIGITS:
+ push_char (c);
+ break;
+
+ case '.':
+ push_char (c);
+ seen_dp = 1;
+ break;
+
+ case '+':
+ case '-':
+ goto got_sign;
+
+ CASE_SEPARATORS:
+ unget_char (c); /* Single null */
+ eat_separator ();
+ return;
+
+ default:
+ goto bad_real;
+ }
+
+ /* Get the digit string that might be a repeat count */
+
+ for (;;)
+ {
+ c = next_char ();
+ switch (c)
+ {
+ CASE_DIGITS:
+ push_char (c);
+ break;
+
+ case '.':
+ if (seen_dp)
+ goto bad_real;
+
+ seen_dp = 1;
+ push_char (c);
+ goto real_loop;
+
+ case 'E':
+ case 'e':
+ case 'D':
+ case 'd':
+ goto exp1;
+
+ case '+':
+ case '-':
+ push_char ('e');
+ push_char (c);
+ c = next_char ();
+ goto exp2;
+
+ case '*':
+ push_char ('\0');
+ goto got_repeat;
+
+ CASE_SEPARATORS:
+ if (c != '\n')
+ unget_char (c); /* Real number that is just a digit-string */
+ goto done;
+
+ default:
+ goto bad_real;
+ }
+ }
+
+got_repeat:
+ if (convert_integer (-1, 0))
+ return;
+
+/* Now get the number itself */
+
+ c = next_char ();
+ if (is_separator (c))
+ { /* Repeated null value */
+ unget_char (c);
+ eat_separator ();
+ return;
+ }
+
+ if (c != '-' && c != '+')
+ push_char ('+');
+ else
+ {
+ got_sign:
+ push_char (c);
+ c = next_char ();
+ }
+
+ if (!isdigit (c) && c != '.')
+ goto bad_real;
+
+ if (c == '.')
+ {
+ if (seen_dp)
+ goto bad_real;
+ else
+ seen_dp = 1;
+ }
+
+ push_char (c);
+
+real_loop:
+ for (;;)
+ {
+ c = next_char ();
+ switch (c)
+ {
+ CASE_DIGITS:
+ push_char (c);
+ break;
+
+ CASE_SEPARATORS:
+ goto done;
+
+ case '.':
+ if (seen_dp)
+ goto bad_real;
+
+ seen_dp = 1;
+ push_char (c);
+ break;
+
+ case 'E':
+ case 'e':
+ case 'D':
+ case 'd':
+ goto exp1;
+
+ case '+':
+ case '-':
+ push_char ('e');
+ push_char (c);
+ c = next_char ();
+ goto exp2;
+
+ default:
+ goto bad_real;
+ }
+ }
+
+exp1:
+ push_char ('e');
+
+ c = next_char ();
+ if (c != '+' && c != '-')
+ push_char ('+');
+ else
+ {
+ push_char (c);
+ c = next_char ();
+ }
+
+exp2:
+ if (!isdigit (c))
+ goto bad_real;
+ push_char (c);
+
+ for (;;)
+ {
+ c = next_char ();
+
+ switch (c)
+ {
+ CASE_DIGITS:
+ push_char (c);
+ break;
+
+ CASE_SEPARATORS:
+ unget_char (c);
+ eat_separator ();
+ goto done;
+
+ default:
+ goto bad_real;
+ }
+ }
+
+done:
+ push_char ('\0');
+ if (convert_real (value, saved_string, length))
+ return;
+
+ free_saved ();
+ saved_type = BT_REAL;
+ return;
+
+bad_real:
+ st_sprintf (message, "Bad real number in item %d of list input",
+ g.item_count);
+
+ generate_error (ERROR_READ_VALUE, message);
+}
+
+
+/* check_type()-- Check the current type against the saved type to
+ * make sure they are compatible. Returns nonzero if incompatible. */
+
+static int
+check_type (bt type, int len)
+{
+ char message[100];
+
+ if (saved_type != BT_NULL && saved_type != type)
+ {
+ st_sprintf (message, "Read type %s where %s was expected for item %d",
+ type_name (saved_type), type_name (type), g.item_count);
+
+ generate_error (ERROR_READ_VALUE, message);
+ return 1;
+ }
+
+ if (saved_type == BT_NULL || saved_type == BT_CHARACTER)
+ return 0;
+
+ if (saved_length != len)
+ {
+ st_sprintf (message,
+ "Read kind %d %s where kind %d is required for item %d",
+ saved_length, type_name (saved_type), len, g.item_count);
+ generate_error (ERROR_READ_VALUE, message);
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/* list_formatted_read()-- Top level data transfer subroutine for list
+ * reads. Because we have to deal with repeat counts, the data item
+ * is always saved after reading, usually in the value[] array. If a
+ * repeat count is greater than one, we copy the data item multiple
+ * times. */
+
+void
+list_formatted_read (bt type, void *p, int len)
+{
+ char c;
+ int m;
+
+ namelist_mode = 0;
+
+ if (setjmp (g.eof_jump))
+ {
+ generate_error (ERROR_END, NULL);
+ return;
+ }
+
+ if (g.first_item)
+ {
+ g.first_item = 0;
+ input_complete = 0;
+ repeat_count = 1;
+ at_eol = 0;
+
+ c = eat_spaces ();
+ if (is_separator (c))
+ { /* Found a null value */
+ eat_separator ();
+ repeat_count = 0;
+ if (at_eol)
+ finish_separator ();
+ else
+ return;
+ }
+
+ }
+ else
+ {
+ if (input_complete)
+ return;
+
+ if (repeat_count > 0)
+ {
+ if (check_type (type, len))
+ return;
+ goto set_value;
+ }
+
+ if (at_eol)
+ finish_separator ();
+ else
+ eat_spaces ();
+
+ saved_type = BT_NULL;
+ repeat_count = 1;
+ }
+
+
+ switch (type)
+ {
+ case BT_INTEGER:
+ read_integer (len);
+ break;
+ case BT_LOGICAL:
+ read_logical (len);
+ break;
+ case BT_CHARACTER:
+ read_character (len);
+ break;
+ case BT_REAL:
+ read_real (len);
+ break;
+ case BT_COMPLEX:
+ read_complex (len);
+ break;
+ default:
+ internal_error ("Bad type for list read");
+ }
+
+ if (saved_type != BT_CHARACTER && saved_type != BT_NULL)
+ saved_length = len;
+
+ if (ioparm.library_return != LIBRARY_OK)
+ return;
+
+set_value:
+ switch (saved_type)
+ {
+ case BT_COMPLEX:
+ len = 2 * len;
+ /* Fall through */
+
+ case BT_INTEGER:
+ case BT_REAL:
+ case BT_LOGICAL:
+ memcpy (p, value, len);
+ break;
+
+ case BT_CHARACTER:
+ m = (len < saved_used) ? len : saved_used;
+ memcpy (p, saved_string, m);
+
+ if (m < len)
+ memset (((char *) p) + m, ' ', len - m);
+ break;
+
+ case BT_NULL:
+ break;
+ }
+
+ if (--repeat_count <= 0)
+ free_saved ();
+}
+
+void
+init_at_eol()
+{
+ at_eol = 0;
+}
+
+/* finish_list_read()-- Finish a list read */
+
+void
+finish_list_read (void)
+{
+ char c;
+
+ free_saved ();
+
+ if (at_eol)
+ {
+ at_eol = 0;
+ return;
+ }
+
+
+ do
+ {
+ c = next_char ();
+ }
+ while (c != '\n');
+}
+
+static namelist_info *
+find_nml_node (char * var_name)
+{
+ namelist_info * t = ionml;
+ while (t != NULL)
+ {
+ if (strcmp (var_name,t->var_name) == 0)
+ {
+ t->value_acquired = 1;
+ return t;
+ }
+ t = t->next;
+ }
+ return NULL;
+}
+
+static void
+match_namelist_name (char *name, int len)
+{
+ int name_len;
+ char c;
+ char * namelist_name = name;
+
+ name_len = 0;
+ /* Match the name of the namelist */
+
+ if (tolower (next_char ()) != tolower (namelist_name[name_len++]))
+ {
+ wrong_name:
+ generate_error (ERROR_READ_VALUE, "Wrong namelist name found");
+ return;
+ }
+
+ while (name_len < len)
+ {
+ c = next_char ();
+ if (tolower (c) != tolower (namelist_name[name_len++]))
+ goto wrong_name;
+ }
+}
+
+
+/********************************************************************
+ Namelist reads
+********************************************************************/
+
+/* namelist_read()-- Process a namelist read. This subroutine
+ * initializes things, positions to the first element and */
+
+void
+namelist_read (void)
+{
+ char c;
+ int name_matched, next_name ;
+ namelist_info * nl;
+ int len, m;
+ void * p;
+
+ namelist_mode = 1;
+
+ if (setjmp (g.eof_jump))
+ {
+ generate_error (ERROR_END, NULL);
+ return;
+ }
+
+restart:
+ c = next_char ();
+ switch (c)
+ {
+ case ' ':
+ goto restart;
+ case '!':
+ do
+ c = next_char ();
+ while (c != '\n');
+
+ goto restart;
+
+ case '&':
+ break;
+
+ default:
+ generate_error (ERROR_READ_VALUE, "Invalid character in namelist");
+ return;
+ }
+
+ /* Match the name of the namelist */
+ match_namelist_name(ioparm.namelist_name, ioparm.namelist_name_len);
+
+ /* Ready to read namelist elements */
+ for (;;)
+ {
+ c = next_char ();
+ switch (c)
+ {
+ case '&':
+ match_namelist_name("end",3);
+ return;
+ case '\\':
+ return;
+ case ' ':
+ case '\n':
+ case '\t':
+ break;
+ case ',':
+ next_name = 1;
+ break;
+
+ case '=':
+ name_matched = 1;
+ nl = find_nml_node (saved_string);
+ if (nl == NULL)
+ internal_error ("Can not found a valid namelist var!");
+ free_saved();
+
+ len = nl->len;
+ p = nl->mem_pos;
+ switch (nl->type)
+ {
+ case BT_INTEGER:
+ read_integer (len);
+ break;
+ case BT_LOGICAL:
+ read_logical (len);
+ break;
+ case BT_CHARACTER:
+ read_character (len);
+ break;
+ case BT_REAL:
+ read_real (len);
+ break;
+ case BT_COMPLEX:
+ read_complex (len);
+ break;
+ default:
+ internal_error ("Bad type for namelist read");
+ }
+
+ switch (saved_type)
+ {
+ case BT_COMPLEX:
+ len = 2 * len;
+ /* Fall through */
+
+ case BT_INTEGER:
+ case BT_REAL:
+ case BT_LOGICAL:
+ memcpy (p, value, len);
+ break;
+
+ case BT_CHARACTER:
+ m = (len < saved_used) ? len : saved_used;
+ memcpy (p, saved_string, m);
+
+ if (m < len)
+ memset (((char *) p) + m, ' ', len - m);
+ break;
+
+ case BT_NULL:
+ break;
+ }
+
+ break;
+
+ default :
+ push_char(c);
+ break;
+ }
+ }
+}
+
diff --git a/libgfortran/io/lock.c b/libgfortran/io/lock.c
new file mode 100644
index 00000000000..1d3f06912e0
--- /dev/null
+++ b/libgfortran/io/lock.c
@@ -0,0 +1,84 @@
+/* Thread/recursion locking
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org> and Andy Vaught
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <string.h>
+#include "libgfortran.h"
+#include "io.h"
+
+st_parameter ioparm;
+namelist_info * ionml;
+global_t g;
+
+
+/* library_start()-- Called with a library call is entered. */
+
+void
+library_start (void)
+{
+
+ if (g.in_library)
+ internal_error ("Recursive library calls not allowed");
+
+/* The in_library flag indicates whether we're currently processing a
+ * library call. Some calls leave immediately, but READ and WRITE
+ * processing return control to the caller but are still considered to
+ * stay within the library. */
+
+ g.in_library = 1;
+
+ if (ioparm.iostat != NULL && ioparm.library_return == LIBRARY_OK)
+ *ioparm.iostat = ERROR_OK;
+
+ ioparm.library_return = LIBRARY_OK;
+}
+
+
+/* library_end()-- Called when a library call is complete in order to
+ * clean up for the next call. */
+
+void
+library_end (void)
+{
+ int t;
+ namelist_info * t1, *t2;
+
+ g.in_library = 0;
+ filename = NULL;
+ line = 0;
+
+ t = ioparm.library_return;
+ if (ionml != NULL)
+ {
+ t1 = ionml;
+ while (t1 != NULL)
+ {
+ t2 = t1;
+ t1 = t1->next;
+ free_mem (t2);
+ }
+ }
+
+ ionml = NULL;
+ memset (&ioparm, '\0', sizeof (ioparm));
+ ioparm.library_return = t;
+}
+
diff --git a/libgfortran/io/open.c b/libgfortran/io/open.c
new file mode 100644
index 00000000000..e6fa50d776a
--- /dev/null
+++ b/libgfortran/io/open.c
@@ -0,0 +1,528 @@
+
+/* Copyright (C) 2002-2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran 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 2, or (at your option)
+any later version.
+
+Libgfortran 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 Libgfortran; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include "libgfortran.h"
+#include "io.h"
+
+
+static st_option access_opt[] = {
+ {"sequential", ACCESS_SEQUENTIAL},
+ {"direct", ACCESS_DIRECT},
+ {NULL}
+}, action_opt[] =
+{
+ {
+ "read", ACTION_READ}
+ ,
+ {
+ "write", ACTION_WRITE}
+ ,
+ {
+ "readwrite", ACTION_READWRITE}
+ ,
+ {
+ NULL}
+}
+
+, blank_opt[] =
+{
+ {
+ "null", BLANK_NULL}
+ ,
+ {
+ "zero", BLANK_ZERO}
+ ,
+ {
+ NULL}
+}
+
+, delim_opt[] =
+{
+ {
+ "none", DELIM_NONE}
+ ,
+ {
+ "apostrophe", DELIM_APOSTROPHE}
+ ,
+ {
+ "quote", DELIM_QUOTE}
+ ,
+ {
+ NULL}
+}
+
+, form_opt[] =
+{
+ {
+ "formatted", FORM_FORMATTED}
+ ,
+ {
+ "unformatted", FORM_UNFORMATTED}
+ ,
+ {
+ NULL}
+}
+
+, position_opt[] =
+{
+ {
+ "asis", POSITION_ASIS}
+ ,
+ {
+ "rewind", POSITION_REWIND}
+ ,
+ {
+ "append", POSITION_APPEND}
+ ,
+ {
+ NULL}
+}
+
+, status_opt[] =
+{
+ {
+ "unknown", STATUS_UNKNOWN}
+ ,
+ {
+ "old", STATUS_OLD}
+ ,
+ {
+ "new", STATUS_NEW}
+ ,
+ {
+ "replace", STATUS_REPLACE}
+ ,
+ {
+ "scratch", STATUS_SCRATCH}
+ ,
+ {
+ NULL}
+}
+
+, pad_opt[] =
+{
+ {
+ "yes", PAD_YES}
+ ,
+ {
+ "no", PAD_NO}
+ ,
+ {
+ NULL}
+};
+
+
+/* test_endfile()-- Given a unit, test to see if the file is
+ * positioned at the terminal point, and if so, change state from
+ * NO_ENDFILE flag to AT_ENDFILE. This prevents us from changing the
+ * state from AFTER_ENDFILE to AT_ENDFILE. */
+
+void
+test_endfile (unit_t * u)
+{
+
+ if (u->endfile == NO_ENDFILE && file_length (u->s) == file_position (u->s))
+ u->endfile = AT_ENDFILE;
+}
+
+
+/* edit_modes()-- Change the modes of a file, those that are allowed
+ * to be changed. */
+
+static void
+edit_modes (unit_t * u, unit_flags * flags)
+{
+
+ /* Complain about attempts to change the unchangeable */
+
+ if (flags->status != STATUS_UNSPECIFIED &&
+ u->flags.status != flags->position)
+ generate_error (ERROR_BAD_OPTION,
+ "Cannot change STATUS parameter in OPEN statement");
+
+ if (flags->access != ACCESS_UNSPECIFIED && u->flags.access != flags->access)
+ generate_error (ERROR_BAD_OPTION,
+ "Cannot change ACCESS parameter in OPEN statement");
+
+ if (flags->form != FORM_UNSPECIFIED && u->flags.form != flags->form)
+ generate_error (ERROR_BAD_OPTION,
+ "Cannot change FORM parameter in OPEN statement");
+
+ if (ioparm.recl_in != 0 && ioparm.recl_in != u->recl)
+ generate_error (ERROR_BAD_OPTION,
+ "Cannot change RECL parameter in OPEN statement");
+
+ if (flags->action != ACTION_UNSPECIFIED && u->flags.access != flags->access)
+ generate_error (ERROR_BAD_OPTION,
+ "Cannot change ACTION parameter in OPEN statement");
+
+ /* Status must be OLD if present */
+
+ if (flags->status != STATUS_UNSPECIFIED && flags->status != STATUS_OLD)
+ generate_error (ERROR_BAD_OPTION,
+ "OPEN statement must have a STATUS of OLD");
+
+ if (u->flags.form == FORM_UNFORMATTED)
+ {
+ if (flags->delim != DELIM_UNSPECIFIED)
+ generate_error (ERROR_OPTION_CONFLICT,
+ "DELIM parameter conflicts with UNFORMATTED form in "
+ "OPEN statement");
+
+ if (flags->blank != BLANK_UNSPECIFIED)
+ generate_error (ERROR_OPTION_CONFLICT,
+ "BLANK parameter conflicts with UNFORMATTED form in "
+ "OPEN statement");
+
+ if (flags->pad != PAD_UNSPECIFIED)
+ generate_error (ERROR_OPTION_CONFLICT,
+ "PAD paramter conflicts with UNFORMATTED form in "
+ "OPEN statement");
+ }
+
+ if (ioparm.library_return == LIBRARY_OK)
+ { /* Change the changeable */
+ if (flags->blank != BLANK_UNSPECIFIED)
+ u->flags.blank = flags->blank;
+ if (flags->delim != DELIM_UNSPECIFIED)
+ u->flags.delim = flags->delim;
+ if (flags->pad != PAD_UNSPECIFIED)
+ u->flags.pad = flags->pad;
+ }
+
+ /* Reposition the file if necessary. */
+
+ switch (flags->position)
+ {
+ case POSITION_UNSPECIFIED:
+ case POSITION_ASIS:
+ break;
+
+ case POSITION_REWIND:
+ if (sseek (u->s, 0) == FAILURE)
+ goto seek_error;
+
+ u->current_record = 0;
+ u->last_record = 0;
+
+ test_endfile (u); /* We might be at the end */
+ break;
+
+ case POSITION_APPEND:
+ if (sseek (u->s, file_length (u->s)) == FAILURE)
+ goto seek_error;
+
+ u->current_record = 0;
+ u->endfile = AT_ENDFILE; /* We are at the end */
+ break;
+
+ seek_error:
+ generate_error (ERROR_OS, NULL);
+ break;
+ }
+}
+
+
+/* new_unit()-- Open an unused unit */
+
+void
+new_unit (unit_flags * flags)
+{
+ unit_t *u;
+ stream *s;
+ char tmpname[5 /* fort. */ + 10 /* digits of unit number */ + 1 /* 0 */];
+
+ /* Change unspecifieds to defaults */
+
+ if (flags->access == ACCESS_UNSPECIFIED)
+ flags->access = ACCESS_SEQUENTIAL;
+
+ if (flags->action == ACTION_UNSPECIFIED)
+ flags->action = ACTION_READWRITE; /* Processor dependent */
+
+ if (flags->form == FORM_UNSPECIFIED)
+ flags->form = (flags->access == ACCESS_SEQUENTIAL)
+ ? FORM_FORMATTED : FORM_UNFORMATTED;
+
+
+ if (flags->delim == DELIM_UNSPECIFIED)
+ flags->delim = DELIM_NONE;
+ else
+ {
+ if (flags->form == FORM_UNFORMATTED)
+ {
+ generate_error (ERROR_OPTION_CONFLICT,
+ "DELIM parameter conflicts with UNFORMATTED form in "
+ "OPEN statement");
+ goto cleanup;
+ }
+ }
+
+ if (flags->blank == BLANK_UNSPECIFIED)
+ flags->blank = BLANK_NULL;
+ else
+ {
+ if (flags->form == FORM_UNFORMATTED)
+ {
+ generate_error (ERROR_OPTION_CONFLICT,
+ "BLANK parameter conflicts with UNFORMATTED form in "
+ "OPEN statement");
+ goto cleanup;
+ }
+ }
+
+ if (flags->pad == PAD_UNSPECIFIED)
+ flags->pad = PAD_YES;
+ else
+ {
+ if (flags->form == FORM_UNFORMATTED)
+ {
+ generate_error (ERROR_OPTION_CONFLICT,
+ "PAD paramter conflicts with UNFORMATTED form in "
+ "OPEN statement");
+ goto cleanup;
+ }
+ }
+
+ if (flags->position != POSITION_ASIS && flags->access == ACCESS_DIRECT)
+ {
+ generate_error (ERROR_OPTION_CONFLICT,
+ "ACCESS parameter conflicts with SEQUENTIAL access in "
+ "OPEN statement");
+ goto cleanup;
+ }
+ else
+ if (flags->position == POSITION_UNSPECIFIED)
+ flags->position = POSITION_ASIS;
+
+
+ if (flags->status == STATUS_UNSPECIFIED)
+ flags->status = STATUS_UNKNOWN;
+
+ /* Checks */
+
+ if (flags->access == ACCESS_DIRECT && ioparm.recl_in == 0)
+ {
+ generate_error (ERROR_MISSING_OPTION,
+ "Missing RECL parameter in OPEN statement");
+ goto cleanup;
+ }
+
+ if (ioparm.recl_in != 0 && ioparm.recl_in <= 0)
+ {
+ generate_error (ERROR_BAD_OPTION,
+ "RECL parameter is non-positive in OPEN statement");
+ goto cleanup;
+ }
+
+ switch (flags->status)
+ {
+ case STATUS_SCRATCH:
+ if (ioparm.file == NULL)
+ break;
+
+ generate_error (ERROR_BAD_OPTION,
+ "FILE parameter must not be present in OPEN statement");
+ return;
+
+ case STATUS_OLD:
+ case STATUS_NEW:
+ case STATUS_REPLACE:
+ case STATUS_UNKNOWN:
+ if (ioparm.file != NULL)
+ break;
+
+ ioparm.file = tmpname;
+ ioparm.file_len = sprintf(ioparm.file, "fort.%d", ioparm.unit);
+ break;
+
+ default:
+ internal_error ("new_unit(): Bad status");
+ }
+
+ /* Make sure the file isn't already open someplace else */
+
+ if (find_file () != NULL)
+ {
+ generate_error (ERROR_ALREADY_OPEN, NULL);
+ goto cleanup;
+ }
+
+ /* Open file */
+
+ s = open_external (flags->action, flags->status);
+ if (s == NULL)
+ {
+ generate_error (ERROR_OS, NULL);
+ goto cleanup;
+ }
+
+ if (flags->status == STATUS_NEW || flags->status == STATUS_REPLACE)
+ flags->status = STATUS_OLD;
+
+ /* Create the unit structure */
+
+ u = get_mem (sizeof (unit_t) + ioparm.file_len);
+
+ u->unit_number = ioparm.unit;
+ u->s = s;
+ u->flags = *flags;
+
+ /* Unspecified recl ends up with a processor dependent value */
+
+ u->recl = (ioparm.recl_in != 0) ? ioparm.recl_in : DEFAULT_RECL;
+ u->last_record = 0;
+ u->current_record = 0;
+
+ /* If the file is direct access, calculate the maximum record number
+ * via a division now instead of letting the multiplication overflow
+ * later. */
+
+ if (flags->access == ACCESS_DIRECT)
+ u->maxrec = g.max_offset / u->recl;
+
+ memmove (u->file, ioparm.file, ioparm.file_len);
+ u->file_len = ioparm.file_len;
+
+ insert_unit (u);
+
+ /* The file is now connected. Errors after this point leave the
+ * file connected. Curiously, the standard requires that the
+ * position specifier be ignored for new files so a newly connected
+ * file starts out that the initial point. We still need to figure
+ * out if the file is at the end or not. */
+
+ test_endfile (u);
+
+cleanup:
+
+ /* Free memory associated with a temporary filename */
+
+ if (flags->status == STATUS_SCRATCH)
+ free_mem (ioparm.file);
+}
+
+
+/* already_open()-- Open a unit which is already open. This involves
+ * changing the modes or closing what is there now and opening the new
+ * file. */
+
+static void
+already_open (unit_t * u, unit_flags * flags)
+{
+
+ if (ioparm.file == NULL)
+ {
+ edit_modes (u, flags);
+ return;
+ }
+
+ /* If the file is connected to something else, close it and open a
+ * new unit */
+
+ if (!compare_file_filename (u->s, ioparm.file, ioparm.file_len))
+ {
+ if (close_unit (u))
+ {
+ generate_error (ERROR_OS, "Error closing file in OPEN statement");
+ return;
+ }
+
+ new_unit (flags);
+ return;
+ }
+
+ edit_modes (u, flags);
+}
+
+
+/*************/
+/* open file */
+
+void
+st_open (void)
+{
+ unit_flags flags;
+ unit_t *u = NULL;
+
+ library_start ();
+
+ /* Decode options */
+
+ flags.access = (ioparm.access == NULL) ? ACCESS_UNSPECIFIED :
+ find_option (ioparm.access, ioparm.access_len, access_opt,
+ "Bad ACCESS parameter in OPEN statement");
+
+ flags.action = (ioparm.action == NULL) ? ACTION_UNSPECIFIED :
+ find_option (ioparm.action, ioparm.action_len, action_opt,
+ "Bad ACTION parameter in OPEN statement");
+
+ flags.blank = (ioparm.blank == NULL) ? BLANK_UNSPECIFIED :
+ find_option (ioparm.blank, ioparm.blank_len, blank_opt,
+ "Bad BLANK parameter in OPEN statement");
+
+ flags.delim = (ioparm.delim == NULL) ? DELIM_UNSPECIFIED :
+ find_option (ioparm.delim, ioparm.delim_len, delim_opt,
+ "Bad DELIM parameter in OPEN statement");
+
+ flags.pad = (ioparm.pad == NULL) ? PAD_UNSPECIFIED :
+ find_option (ioparm.pad, ioparm.pad_len, pad_opt,
+ "Bad PAD parameter in OPEN statement");
+
+ flags.form = (ioparm.form == NULL) ? FORM_UNSPECIFIED :
+ find_option (ioparm.form, ioparm.form_len, form_opt,
+ "Bad FORM parameter in OPEN statement");
+
+ flags.position = (ioparm.position == NULL) ? POSITION_UNSPECIFIED :
+ find_option (ioparm.position, ioparm.position_len, position_opt,
+ "Bad POSITION parameter in OPEN statement");
+
+ flags.status = (ioparm.status == NULL) ? STATUS_UNSPECIFIED :
+ find_option (ioparm.status, ioparm.status_len, status_opt,
+ "Bad STATUS parameter in OPEN statement");
+
+ if (ioparm.unit < 0)
+ generate_error (ERROR_BAD_OPTION, "Bad unit number in OPEN statement");
+
+ if (flags.position != POSITION_UNSPECIFIED &&
+ u->flags.access == ACCESS_DIRECT)
+ generate_error (ERROR_BAD_OPTION,
+ "Cannot use POSITION with direct access files");
+
+ if (flags.position == POSITION_UNSPECIFIED)
+ flags.position = POSITION_ASIS;
+
+ if (ioparm.library_return != LIBRARY_OK)
+ return;
+
+ u = find_unit (ioparm.unit);
+
+ if (u == NULL)
+ new_unit (&flags);
+ else
+ already_open (u, &flags);
+
+ library_end ();
+}
diff --git a/libgfortran/io/read.c b/libgfortran/io/read.c
new file mode 100644
index 00000000000..3ce9f1d3a1a
--- /dev/null
+++ b/libgfortran/io/read.c
@@ -0,0 +1,793 @@
+/* Copyright (C) 2002-2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran 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 2, or (at your option)
+any later version.
+
+Libgfortran 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 Libgfortran; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+#include "config.h"
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include "libgfortran.h"
+#include "io.h"
+
+/* read.c -- Deal with formatted reads */
+
+/* set_integer()-- All of the integer assignments come here to
+ * actually place the value into memory. */
+
+void
+set_integer (void *dest, int64_t value, int length)
+{
+
+ switch (length)
+ {
+ case 8:
+ *((int64_t *) dest) = value;
+ break;
+ case 4:
+ *((int32_t *) dest) = value;
+ break;
+ case 2:
+ *((int16_t *) dest) = value;
+ break;
+ case 1:
+ *((int8_t *) dest) = value;
+ break;
+ default:
+ internal_error ("Bad integer kind");
+ }
+}
+
+
+/* max_value()-- Given a length (kind), return the maximum signed or
+ * unsigned value */
+
+uint64_t
+max_value (int length, int signed_flag)
+{
+ uint64_t value;
+
+ switch (length)
+ {
+ case 8:
+ value = signed_flag ? 0x7fffffffffffffff : 0xffffffffffffffff;
+ break;
+ case 4:
+ value = signed_flag ? 0x7fffffff : 0xffffffff;
+ break;
+ case 2:
+ value = signed_flag ? 0x7fff : 0xffff;
+ break;
+ case 1:
+ value = signed_flag ? 0x7f : 0xff;
+ break;
+ default:
+ internal_error ("Bad integer kind");
+ }
+
+ return value;
+}
+
+
+/* convert_real()-- Convert a character representation of a floating
+ * point number to the machine number. Returns nonzero if there is a
+ * range problem during conversion. TODO: handle not-a-numbers and
+ * infinities. Handling of kind 4 is probably wrong because of double
+ * rounding. */
+
+int
+convert_real (void *dest, const char *buffer, int length)
+{
+
+ errno = 0;
+
+ switch (length)
+ {
+ case 4:
+ *((float *) dest) = (float) strtod (buffer, NULL);
+ break;
+ case 8:
+ *((double *) dest) = strtod (buffer, NULL);
+ break;
+ default:
+ internal_error ("Bad real number kind");
+ }
+
+ if (errno != 0)
+ {
+ generate_error (ERROR_READ_VALUE,
+ "Range error during floating point read");
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+convert_precision_real (void *dest, int sign,
+ char *buffer, int length, int exponent)
+{
+ int w, new_dp_pos, i, slen, k, dp;
+ char * p, c;
+ double fval;
+ float tf;
+
+ fval =0.0;
+ tf = 0.0;
+ dp = 0;
+ new_dp_pos = 0;
+
+ slen = strlen (buffer);
+ w = slen;
+ p = buffer;
+
+/* for (i = w - 1; i > 0; i --)
+ {
+ if (buffer[i] == '0' || buffer[i] == 0)
+ buffer[i] = 0;
+ else
+ break;
+ }
+*/
+ for (i = 0; i < w; i++)
+ {
+ if (buffer[i] == '.')
+ break;
+ }
+
+ new_dp_pos = i;
+ new_dp_pos += exponent;
+
+ while (w > 0)
+ {
+ c = *p;
+ switch (c)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ fval = fval * 10.0 + c - '0';
+ p++;
+ w--;
+ break;
+
+ case '.':
+ dp = 1;
+ p++;
+ w--;
+ break;
+
+ default:
+ p++;
+ w--;
+ break;
+ }
+ }
+
+ if (sign)
+ fval = - fval;
+
+ i = new_dp_pos - slen + dp;
+ k = abs(i);
+ tf = 1.0;
+
+ while (k > 0)
+ {
+ tf *= 10.0 ;
+ k -- ;
+ }
+
+ if (fval != 0.0)
+ {
+ if (i < 0)
+ {
+ fval = fval / tf;
+ }
+ else
+ {
+ fval = fval * tf;
+ }
+ }
+
+ switch (length)
+ {
+ case 4:
+ *((float *) dest) = (float)fval;
+ break;
+ case 8:
+ *((double *) dest) = fval;
+ break;
+ default:
+ internal_error ("Bad real number kind");
+ }
+
+ return 0;
+}
+
+
+/* read_l()-- Read a logical value */
+
+void
+read_l (fnode * f, char *dest, int length)
+{
+ char *p;
+ int w;
+
+ w = f->u.w;
+ p = read_block (&w);
+ if (p == NULL)
+ return;
+
+ while (*p == ' ')
+ {
+ if (--w == 0)
+ goto bad;
+ p++;
+ }
+
+ if (*p == '.')
+ {
+ if (--w == 0)
+ goto bad;
+ p++;
+ }
+
+ switch (*p)
+ {
+ case 't':
+ case 'T':
+ set_integer (dest, 1, length);
+ break;
+ case 'f':
+ case 'F':
+ set_integer (dest, 0, length);
+ break;
+ default:
+ bad:
+ generate_error (ERROR_READ_VALUE, "Bad value on logical read");
+ break;
+ }
+}
+
+
+/* read_a()-- Read a character record. This one is pretty easy. */
+
+void
+read_a (fnode * f, char *p, int length)
+{
+ char *source;
+ int w, m, n;
+
+ w = f->u.w;
+ if (w == -1) /* '(A)' edit descriptor */
+ w = length;
+
+ source = read_block (&w);
+ if (source == NULL)
+ return;
+ if (w > length)
+ source += (w - length);
+
+ m = (w > length) ? length : w;
+ memcpy (p, source, m);
+
+ n = length - w;
+ if (n > 0)
+ memset (p + m, ' ', n);
+}
+
+
+/* eat_leading_spaces()-- Given a character pointer and a width,
+ * ignore the leading spaces. */
+
+static char *
+eat_leading_spaces (int *width, char *p)
+{
+
+ for (;;)
+ {
+ if (*width == 0 || *p != ' ')
+ break;
+
+ (*width)--;
+ p++;
+ }
+
+ return p;
+}
+
+
+static char
+next_char (char **p, int *w)
+{
+ char c, *q;
+
+ if (*w == 0)
+ return '\0';
+
+ q = *p;
+ c = *q++;
+ *p = q;
+
+ (*w)--;
+
+ if (c != ' ')
+ return c;
+ if (g.blank_status == BLANK_ZERO)
+ return '0';
+
+ /* At this point, the rest of the field has to be trailing blanks */
+
+ while (*w > 0)
+ {
+ if (*q++ != ' ')
+ return '?';
+ (*w)--;
+ }
+
+ *p = q;
+ return '\0';
+}
+
+
+/* read_decimal()-- Read a decimal integer value. The values here are
+ * signed values. */
+
+void
+read_decimal (fnode * f, char *dest, int length)
+{
+ unsigned value, maxv, maxv_10;
+ int v, w, negative;
+ char c, *p;
+
+ w = f->u.w;
+ p = read_block (&w);
+ if (p == NULL)
+ return;
+
+ p = eat_leading_spaces (&w, p);
+ if (w == 0)
+ {
+ set_integer (dest, 0, length);
+ return;
+ }
+
+ maxv = max_value (length, 1);
+ maxv_10 = maxv / 10;
+
+ negative = 0;
+ value = 0;
+
+ switch (*p)
+ {
+ case '-':
+ negative = 1;
+ /* Fall through */
+
+ case '+':
+ p++;
+ if (--w == 0)
+ goto bad;
+ /* Fall through */
+
+ default:
+ break;
+ }
+
+ /* At this point we have a digit-string */
+ value = 0;
+
+ for (;;)
+ {
+ c = next_char (&p, &w);
+ if (c == '\0')
+ break;
+
+ if (c < '0' || c > '9')
+ goto bad;
+
+ if (value > maxv_10)
+ goto overflow;
+
+ c -= '0';
+ value = 10 * value;
+
+ if (value > maxv - c)
+ goto overflow;
+ value += c;
+ }
+
+ v = (signed int) value;
+ if (negative)
+ v = -v;
+
+ set_integer (dest, v, length);
+ return;
+
+bad:
+ generate_error (ERROR_READ_VALUE, "Bad value during integer read");
+ return;
+
+overflow:
+ generate_error (ERROR_READ_OVERFLOW,
+ "Value overflowed during integer read");
+ return;
+}
+
+
+/* read_radix()-- This function reads values for non-decimal radixes.
+ * The difference here is that we treat the values here as unsigned
+ * values for the purposes of overflow. If minus sign is present and
+ * the top bit is set, the value will be incorrect. */
+
+void
+read_radix (fnode * f, char *dest, int length, int radix)
+{
+ unsigned value, maxv, maxv_r;
+ int v, w, negative;
+ char c, *p;
+
+ w = f->u.w;
+ p = read_block (&w);
+ if (p == NULL)
+ return;
+
+ p = eat_leading_spaces (&w, p);
+ if (w == 0)
+ {
+ set_integer (dest, 0, length);
+ return;
+ }
+
+ maxv = max_value (length, 0);
+ maxv_r = maxv / radix;
+
+ negative = 0;
+ value = 0;
+
+ switch (*p)
+ {
+ case '-':
+ negative = 1;
+ /* Fall through */
+
+ case '+':
+ p++;
+ if (--w == 0)
+ goto bad;
+ /* Fall through */
+
+ default:
+ break;
+ }
+
+ /* At this point we have a digit-string */
+ value = 0;
+
+ for (;;)
+ {
+ c = next_char (&p, &w);
+ if (c == '\0')
+ break;
+
+ switch (radix)
+ {
+ case 2:
+ if (c < '0' || c > '1')
+ goto bad;
+ break;
+
+ case 8:
+ if (c < '0' || c > '7')
+ goto bad;
+ break;
+
+ case 16:
+ switch (c)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ break;
+
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ c = c - 'a' + '9' + 1;
+ break;
+
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ c = c - 'A' + '9' + 1;
+ break;
+
+ default:
+ goto bad;
+ }
+
+ break;
+ }
+
+ if (value > maxv_r)
+ goto overflow;
+
+ c -= '0';
+ value = radix * value;
+
+ if (maxv - c < value)
+ goto overflow;
+ value += c;
+ }
+
+ v = (signed int) value;
+ if (negative)
+ v = -v;
+
+ set_integer (dest, v, length);
+ return;
+
+bad:
+ generate_error (ERROR_READ_VALUE, "Bad value during integer read");
+ return;
+
+overflow:
+ generate_error (ERROR_READ_OVERFLOW,
+ "Value overflowed during integer read");
+ return;
+}
+
+
+/* read_f()-- Read a floating point number with F-style editing, which
+ * is what all of the other floating point descriptors behave as. The
+ * tricky part is that optional spaces are allowed after an E or D,
+ * and the implicit decimal point if a decimal point is not present in
+ * the input. */
+
+void
+read_f (fnode * f, char *dest, int length)
+{
+ int w, seen_dp, exponent;
+ int exponent_sign, val_sign;
+ char *p, *buffer, *n;
+
+ val_sign = 0;
+ seen_dp = 0;
+ w = f->u.w;
+ p = read_block (&w);
+ if (p == NULL)
+ return;
+
+ p = eat_leading_spaces (&w, p);
+ if (w == 0)
+ {
+ switch (length)
+ {
+ case 4:
+ *((float *) dest) = 0.0;
+ break;
+
+ case 8:
+ *((double *) dest) = 0.0;
+ break;
+ }
+
+ return;
+ }
+
+ if (w + 2 < SCRATCH_SIZE)
+ buffer = scratch;
+ else
+ buffer = get_mem (w + 2);
+
+ memset(buffer, 0, w + 2);
+
+ n = buffer;
+
+ /* Optional sign */
+
+ if (*p == '-' || *p == '+')
+ {
+ if (*p == '-')
+ val_sign = 1;
+ p++;
+
+ if (--w == 0)
+ goto bad_float;
+ }
+
+ exponent_sign = 1;
+
+ /* A digit (or a '.') is required at this point */
+
+ if (!isdigit (*p) && *p != '.')
+ goto bad_float;
+
+ while (w > 0)
+ {
+ switch (*p)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ *n++ = *p++;
+ w--;
+ break;
+
+ case '.':
+ if (seen_dp)
+ goto bad_float;
+ seen_dp = 1;
+
+ *n++ = *p++;
+ w--;
+ break;
+
+ case ' ':
+ if (g.blank_status == BLANK_ZERO)
+ *n++ = '0';
+ p++;
+ w--;
+ break;
+
+ case '-':
+ exponent_sign = -1;
+ /* Fall through */
+
+ case '+':
+ p++;
+ w--;
+ goto exp2;
+
+ case 'd':
+ case 'e':
+ case 'D':
+ case 'E':
+ p++;
+ w--;
+ goto exp1;
+
+ default:
+ goto bad_float;
+ }
+ }
+
+/* No exponent has been seen, so we use the current scale factor */
+
+ exponent = -g.scale_factor;
+ goto done;
+
+bad_float:
+ generate_error (ERROR_READ_VALUE, "Bad value during floating point read");
+ if (buffer != scratch)
+ free_mem (buffer);
+ return;
+
+/* At this point the start of an exponent has been found */
+
+exp1:
+ while (w > 0 && *p == ' ')
+ {
+ w--;
+ p++;
+ }
+
+ switch (*p)
+ {
+ case '-':
+ exponent_sign = -1;
+ /* Fall through */
+
+ case '+':
+ p++;
+ w--;
+ break;
+ }
+
+ if (w == 0)
+ goto bad_float;
+
+/* At this point a digit string is required. We calculate the value
+ * of the exponent in order to take account of the scale factor and
+ * the d parameter before explict conversion takes place. */
+
+exp2:
+ if (!isdigit (*p))
+ goto bad_float;
+
+ exponent = *p - '0';
+ p++;
+ w--;
+
+ while (w > 0 && isdigit (*p))
+ {
+ exponent = 10 * exponent + *p - '0';
+ if (exponent > 999999)
+ goto bad_float;
+
+ p++;
+ w--;
+ }
+
+ /* Only allow trailing blanks */
+
+ while (w > 0)
+ {
+ if (*p != ' ')
+ goto bad_float;
+ p++;
+ w--;
+ }
+
+ exponent = exponent * exponent_sign;
+
+done:
+ if (!seen_dp)
+ exponent -= f->u.real.d;
+
+ /* The number is syntactically correct and ready for conversion.
+ * The only thing that can go wrong at this point is overflow or
+ * underflow. */
+
+ convert_precision_real (dest, val_sign, buffer, length, exponent);
+
+ if (buffer != scratch)
+ free_mem (buffer);
+
+ return;
+}
+
+
+/* read_x()-- Deal with the X/TR descriptor. We just read some data
+ * and never look at it. */
+
+void
+read_x (fnode * f)
+{
+ int n;
+
+ n = f->u.n;
+ read_block (&n);
+}
diff --git a/libgfortran/io/rewind.c b/libgfortran/io/rewind.c
new file mode 100644
index 00000000000..d068853cf3a
--- /dev/null
+++ b/libgfortran/io/rewind.c
@@ -0,0 +1,56 @@
+
+/* Copyright (C) 2002-2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran 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 2, or (at your option)
+any later version.
+
+Libgfortran 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 Libgfortran; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "libgfortran.h"
+#include "io.h"
+
+/* rewind.c-- Implement the rewind statement */
+
+void
+st_rewind (void)
+{
+ unit_t *u;
+
+ library_start ();
+
+ u = find_unit (ioparm.unit);
+ if (u != NULL)
+ {
+ if (u->flags.access != ACCESS_SEQUENTIAL)
+ generate_error (ERROR_BAD_OPTION,
+ "Cannot REWIND a file opened for DIRECT access");
+ else
+ {
+ if (g.mode==WRITING)
+ struncate(u->s);
+ u->last_record = 0;
+ if (sseek (u->s, 0) == FAILURE)
+ generate_error (ERROR_OS, NULL);
+
+ u->endfile = NO_ENDFILE;
+ u->current_record = 0;
+ test_endfile (u);
+ }
+ }
+
+ library_end ();
+}
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
new file mode 100644
index 00000000000..b1f0ef10598
--- /dev/null
+++ b/libgfortran/io/transfer.c
@@ -0,0 +1,1498 @@
+
+/* Copyright (C) 2002-2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran 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 2, or (at your option)
+any later version.
+
+Libgfortran 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 Libgfortran; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+/* transfer.c -- Top level handling of data transfer statements. */
+
+#include "config.h"
+#include <string.h>
+#include "libgfortran.h"
+#include "io.h"
+
+
+/* Calling conventions: Data transfer statements are unlike other
+ * library calls in that they extend over several calls.
+
+ * The first call is always a call to st_read() or st_write(). These
+ * subroutines return no status unless a namelist read or write is
+ * being done, in which case there is the usual status. No further
+ * calls are necessary in this case.
+ *
+ * For other sorts of data transfer, there are zero or more data
+ * transfer statement that depend on the format of the data transfer
+ * statement.
+ *
+ * transfer_integer
+ * transfer_logical
+ * transfer_character
+ * transfer_real
+ * transfer_complex
+ *
+ * These subroutines do not return status.
+ *
+ * The last call is a call to st_[read|write]_done(). While
+ * something can easily go wrong with the initial st_read() or
+ * st_write(), an error inhibits any data from actually being
+ * transferred.
+ */
+
+unit_t *current_unit;
+static int sf_seen_eor = 0;
+
+char scratch[SCRATCH_SIZE];
+static char *line_buffer = NULL;
+
+static unit_advance advance_status;
+
+static st_option advance_opt[] = {
+ {"yes", ADVANCE_YES},
+ {"no", ADVANCE_NO},
+ {NULL}
+};
+
+
+static void (*transfer) (bt, void *, int);
+
+
+typedef enum
+{ FORMATTED_SEQUENTIAL, UNFORMATTED_SEQUENTIAL,
+ FORMATTED_DIRECT, UNFORMATTED_DIRECT
+}
+file_mode;
+
+
+static file_mode
+current_mode (void)
+{
+ file_mode m;
+
+ if (current_unit->flags.access == ACCESS_DIRECT)
+ {
+ m = current_unit->flags.form == FORM_FORMATTED ?
+ FORMATTED_DIRECT : UNFORMATTED_DIRECT;
+ }
+ else
+ {
+ m = current_unit->flags.form == FORM_FORMATTED ?
+ FORMATTED_SEQUENTIAL : UNFORMATTED_SEQUENTIAL;
+ }
+
+ return m;
+}
+
+
+/* Mid level data transfer statements. These subroutines do reading
+ * and writing in the style of salloc_r()/salloc_w() within the
+ * current record. */
+
+/* read_sf()-- When reading sequential formatted records we have a
+ * problem. We don't know how long the line is until we read the
+ * trailing newline, and we don't want to read too much. If we read
+ * too much, we might have to do a physical seek backwards depending
+ * on how much data is present, and devices like terminals aren't
+ * seekable and would cause an I/O error.
+ *
+ * Given this, the solution is to read a byte at a time, stopping if
+ * we hit the newline. For small locations, we use a static buffer.
+ * For larger allocations, we are forced to allocate memory on the
+ * heap. Hopefully this won't happen very often. */
+
+static char *
+read_sf (int *length)
+{
+ static char data[SCRATCH_SIZE];
+ char *base, *p, *q;
+ int n, unity;
+
+ if (*length > SCRATCH_SIZE)
+ p = base = line_buffer = get_mem (*length);
+ else
+ p = base = data;
+
+ memset(base,'\0',*length);
+
+ current_unit->bytes_left = options.default_recl;
+ unity = 1;
+ n = 0;
+
+ do
+ {
+ if (is_internal_unit())
+ {
+ /* unity may be modified inside salloc_r if is_internal_unit() is true */
+ unity = 1;
+ }
+
+ q = salloc_r (current_unit->s, &unity);
+ if (q == NULL)
+ break;
+
+ if (*q == '\n')
+ {
+ if (current_unit->unit_number == options.stdin_unit)
+ {
+ if (n <= 0)
+ continue;
+ }
+ /* Unexpected end of line */
+ if (current_unit->flags.pad == PAD_NO)
+ {
+ generate_error (ERROR_EOR, NULL);
+ return NULL;
+ }
+
+ current_unit->bytes_left = 0;
+ *length = n;
+ sf_seen_eor = 1;
+ break;
+ }
+
+ n++;
+ *p++ = *q;
+ sf_seen_eor = 0;
+ }
+ while (n < *length);
+
+ return base;
+}
+
+
+/* read_block()-- Function for reading the next couple of bytes from
+ * the current file, advancing the current position. We return a
+ * pointer to a buffer containing the bytes. We return NULL on end of
+ * record or end of file.
+ *
+ * If the read is short, then it is because the current record does not
+ * have enough data to satisfy the read request and the file was
+ * opened with PAD=YES. The caller must assume tailing spaces for
+ * short reads. */
+
+void *
+read_block (int *length)
+{
+ char *source;
+ int nread;
+
+ if (current_unit->flags.form == FORM_FORMATTED &&
+ current_unit->flags.access == ACCESS_SEQUENTIAL)
+ return read_sf (length); /* Special case */
+
+ if (current_unit->bytes_left < *length)
+ {
+ if (current_unit->flags.pad == PAD_NO)
+ {
+ generate_error (ERROR_EOR, NULL); /* Not enough data left */
+ return NULL;
+ }
+
+ *length = current_unit->bytes_left;
+ }
+
+ current_unit->bytes_left -= *length;
+
+ nread = *length;
+ source = salloc_r (current_unit->s, &nread);
+
+ if (ioparm.size != NULL)
+ *ioparm.size += nread;
+
+ if (nread != *length)
+ { /* Short read, this shouldn't happen */
+ if (current_unit->flags.pad == PAD_YES)
+ *length = nread;
+ else
+ {
+ generate_error (ERROR_EOR, NULL);
+ source = NULL;
+ }
+ }
+
+ return source;
+}
+
+
+/* write_block()-- Function for writing a block of bytes to the
+ * current file at the current position, advancing the file pointer.
+ * We are given a length and return a pointer to a buffer that the
+ * caller must (completely) fill in. Returns NULL on error. */
+
+void *
+write_block (int length)
+{
+ char *dest;
+
+ if (!is_internal_unit() && current_unit->bytes_left < length)
+ {
+ generate_error (ERROR_EOR, NULL);
+ return NULL;
+ }
+
+ current_unit->bytes_left -= length;
+ dest = salloc_w (current_unit->s, &length);
+
+ if (ioparm.size != NULL)
+ *ioparm.size += length;
+
+ return dest;
+}
+
+
+/* unformatted_read()-- Master function for unformatted reads. */
+
+static void
+unformatted_read (bt type, void *dest, int length)
+{
+ void *source;
+ int w;
+ w = length;
+ source = read_block (&w);
+
+ if (source != NULL)
+ {
+ memcpy (dest, source, w);
+ if (length != w)
+ memset (((char *) dest) + w, ' ', length - w);
+ }
+}
+
+static void
+unformatted_write (bt type, void *source, int length)
+{
+ void *dest;
+ dest = write_block (length);
+ if (dest != NULL)
+ memcpy (dest, source, length);
+}
+
+
+/* type_name()-- Return a pointer to the name of a type. */
+
+const char *
+type_name (bt type)
+{
+ const char *p;
+
+ switch (type)
+ {
+ case BT_INTEGER:
+ p = "INTEGER";
+ break;
+ case BT_LOGICAL:
+ p = "LOGICAL";
+ break;
+ case BT_CHARACTER:
+ p = "CHARACTER";
+ break;
+ case BT_REAL:
+ p = "REAL";
+ break;
+ case BT_COMPLEX:
+ p = "COMPLEX";
+ break;
+ default:
+ internal_error ("type_name(): Bad type");
+ }
+
+ return p;
+}
+
+
+/* write_constant_string()-- write a constant string to the output.
+ * This is complicated because the string can have doubled delimiters
+ * in it. The length in the format node is the true length. */
+
+static void
+write_constant_string (fnode * f)
+{
+ char c, delimiter, *p, *q;
+ int length;
+
+ length = f->u.string.length;
+ if (length == 0)
+ return;
+
+ p = write_block (length);
+ if (p == NULL)
+ return;
+
+ q = f->u.string.p;
+ delimiter = q[-1];
+
+ for (; length > 0; length--)
+ {
+ c = *p++ = *q++;
+ if (c == delimiter && c != 'H')
+ q++; /* Skip the doubled delimiter */
+ }
+}
+
+
+/* require_type()-- Given actual and expected types in a formatted
+ * data transfer, make sure they agree. If not, an error message is
+ * generated. Returns nonzero if something went wrong. */
+
+static int
+require_type (bt expected, bt actual, fnode * f)
+{
+ char buffer[100];
+
+ if (actual == expected)
+ return 0;
+
+ st_sprintf (buffer, "Expected %s for item %d in formatted transfer, got %s",
+ type_name (expected), g.item_count, type_name (actual));
+
+ format_error (f, buffer);
+ return 1;
+}
+
+
+/* formatted_transfer()-- This subroutine is the main loop for a
+ * formatted data transfer statement. It would be natural to
+ * implement this as a coroutine with the user program, but C makes
+ * that awkward. We loop, processesing format elements. When we
+ * actually have to transfer data instead of just setting flags, we
+ * return control to the user program which calls a subroutine that
+ * supplies the address and type of the next element, then comes back
+ * here to process it. */
+
+static void
+formatted_transfer (bt type, void *p, int len)
+{
+ int pos ,m ;
+ fnode *f;
+ int i, n;
+ int consume_data_flag;
+
+ /* Change a complex data item into a pair of reals */
+
+ n = (p == NULL) ? 0 : ((type != BT_COMPLEX) ? 1 : 2);
+ if (type == BT_COMPLEX)
+ type = BT_REAL;
+
+ /* If reversion has occurred and there is another real data item,
+ * then we have to move to the next record */
+
+ if (g.reversion_flag && n > 0)
+ {
+ g.reversion_flag = 0;
+ next_record (0);
+ }
+ for (;;)
+ {
+ consume_data_flag = 1 ;
+ if (ioparm.library_return != LIBRARY_OK)
+ break;
+
+ f = next_format ();
+ if (f == NULL)
+ return; /* No data descriptors left (already raised) */
+
+ switch (f->format)
+ {
+ case FMT_I:
+ if (n == 0)
+ goto need_data;
+ if (require_type (BT_INTEGER, type, f))
+ return;
+
+ if (g.mode == READING)
+ read_decimal (f, p, len);
+ else
+ write_i (f, p, len);
+
+ break;
+
+ case FMT_B:
+ if (n == 0)
+ goto need_data;
+ if (require_type (BT_INTEGER, type, f))
+ return;
+
+ if (g.mode == READING)
+ read_radix (f, p, len, 2);
+ else
+ write_b (f, p, len);
+
+ break;
+
+ case FMT_O:
+ if (n == 0)
+ goto need_data;
+
+ if (g.mode == READING)
+ read_radix (f, p, len, 8);
+ else
+ write_o (f, p, len);
+
+ break;
+
+ case FMT_Z:
+ if (n == 0)
+ goto need_data;
+
+ if (g.mode == READING)
+ read_radix (f, p, len, 16);
+ else
+ write_z (f, p, len);
+
+ break;
+
+ case FMT_A:
+ if (n == 0)
+ goto need_data;
+ if (require_type (BT_CHARACTER, type, f))
+ return;
+
+ if (g.mode == READING)
+ read_a (f, p, len);
+ else
+ write_a (f, p, len);
+
+ break;
+
+ case FMT_L:
+ if (n == 0)
+ goto need_data;
+
+ if (g.mode == READING)
+ read_l (f, p, len);
+ else
+ write_l (f, p, len);
+
+ break;
+
+ case FMT_D:
+ if (n == 0)
+ goto need_data;
+ if (require_type (BT_REAL, type, f))
+ return;
+
+ if (g.mode == READING)
+ read_f (f, p, len);
+ else
+ write_d (f, p, len);
+
+ break;
+
+ case FMT_E:
+ if (n == 0)
+ goto need_data;
+ if (require_type (BT_REAL, type, f))
+ return;
+
+ if (g.mode == READING)
+ read_f (f, p, len);
+ else
+ write_e (f, p, len);
+ break;
+
+ case FMT_EN:
+ if (n == 0)
+ goto need_data;
+ if (require_type (BT_REAL, type, f))
+ return;
+
+ if (g.mode == READING)
+ read_f (f, p, len);
+ else
+ write_en (f, p, len);
+
+ break;
+
+ case FMT_ES:
+ if (n == 0)
+ goto need_data;
+ if (require_type (BT_REAL, type, f))
+ return;
+
+ if (g.mode == READING)
+ read_f (f, p, len);
+ else
+ write_es (f, p, len);
+
+ break;
+
+ case FMT_F:
+ if (n == 0)
+ goto need_data;
+ if (require_type (BT_REAL, type, f))
+ return;
+
+ if (g.mode == READING)
+ read_f (f, p, len);
+ else
+ write_f (f, p, len);
+
+ break;
+
+ case FMT_G:
+ if (n == 0)
+ goto need_data;
+ if (g.mode == READING)
+ switch (type)
+ {
+ case BT_INTEGER:
+ read_decimal (f, p, len);
+ break;
+ case BT_LOGICAL:
+ read_l (f, p, len);
+ break;
+ case BT_CHARACTER:
+ read_a (f, p, len);
+ break;
+ case BT_REAL:
+ read_f (f, p, len);
+ break;
+ default:
+ goto bad_type;
+ }
+ else
+ switch (type)
+ {
+ case BT_INTEGER:
+ write_i (f, p, len);
+ break;
+ case BT_LOGICAL:
+ write_l (f, p, len);
+ break;
+ case BT_CHARACTER:
+ write_a (f, p, len);
+ break;
+ case BT_REAL:
+ write_d (f, p, len);
+ break;
+ default:
+ bad_type:
+ internal_error ("formatted_transfer(): Bad type");
+ }
+
+ break;
+
+ case FMT_STRING:
+ consume_data_flag = 0 ;
+ if (g.mode == READING)
+ {
+ format_error (f, "Constant string in input format");
+ return;
+ }
+ write_constant_string (f);
+ break;
+
+ /* Format codes that don't transfer data */
+ case FMT_X:
+ case FMT_TR:
+ consume_data_flag = 0 ;
+ if (g.mode == READING)
+ read_x (f);
+ else
+ write_x (f);
+
+ break;
+
+ case FMT_T:
+ pos = f->u.n ;
+ pos= current_unit->recl - current_unit->bytes_left - pos;
+ /* fall through */
+
+ case FMT_TL:
+ consume_data_flag = 0 ;
+ pos = f->u.n ;
+
+ if (pos < 0 || pos >= current_unit->recl )
+ {
+ generate_error (ERROR_EOR, "T Or TL edit position error");
+ break ;
+ }
+ m = pos - (current_unit->recl - current_unit->bytes_left);
+
+ if (m == 0)
+ break;
+
+ if (m > 0)
+ {
+ f->u.n = m;
+ if (g.mode == READING)
+ read_x (f);
+ else
+ write_x (f);
+ }
+ if (m < 0)
+ {
+ move_pos_offset (current_unit->s,m);
+ }
+
+ break;
+
+ case FMT_S:
+ consume_data_flag = 0 ;
+ g.sign_status = SIGN_S;
+ break;
+
+ case FMT_SS:
+ consume_data_flag = 0 ;
+ g.sign_status = SIGN_SS;
+ break;
+
+ case FMT_SP:
+ consume_data_flag = 0 ;
+ g.sign_status = SIGN_SP;
+ break;
+
+ case FMT_BN:
+ consume_data_flag = 0 ;
+ g.blank_status = BLANK_NULL;
+ break;
+
+ case FMT_BZ:
+ consume_data_flag = 0 ;
+ g.blank_status = BLANK_ZERO;
+ break;
+
+ case FMT_P:
+ consume_data_flag = 0 ;
+ g.scale_factor = f->u.k;
+ break;
+
+ case FMT_DOLLAR:
+ consume_data_flag = 0 ;
+ g.seen_dollar = 1;
+ break;
+
+ case FMT_SLASH:
+ consume_data_flag = 0 ;
+ for (i = 0; i < f->repeat; i++)
+ next_record (0);
+
+ break;
+
+ case FMT_COLON:
+ /* A colon descriptor causes us to exit this loop (in particular
+ * preventing another / descriptor from being processed) unless there
+ * is another data item to be transferred. */
+ consume_data_flag = 0 ;
+ if (n == 0)
+ return;
+ break;
+
+ default:
+ internal_error ("Bad format node");
+ }
+
+ /* Free a buffer that we had to allocate during a sequential
+ * formatted read of a block that was larger than the static
+ * buffer. */
+
+ if (line_buffer != NULL)
+ {
+ free_mem (line_buffer);
+ line_buffer = NULL;
+ }
+
+ /* Adjust the item count and data pointer */
+
+ if ((consume_data_flag > 0) && (n > 0))
+ {
+ n--;
+ p = ((char *) p) + len;
+ }
+ }
+
+ return;
+
+/* Come here when we need a data descriptor but don't have one. We
+ * push the current format node back onto the input, then return and
+ * let the user program call us back with the data. */
+
+need_data:
+ unget_format (f);
+}
+
+
+
+/* Data transfer entry points. The type of the data entity is
+ * implicit in the subroutine call. This prevents us from having to
+ * share a common enum with the compiler. */
+
+void
+transfer_integer (void *p, int kind)
+{
+
+ g.item_count++;
+ if (ioparm.library_return != LIBRARY_OK)
+ return;
+ transfer (BT_INTEGER, p, kind);
+}
+
+
+void
+transfer_real (void *p, int kind)
+{
+
+ g.item_count++;
+ if (ioparm.library_return != LIBRARY_OK)
+ return;
+ transfer (BT_REAL, p, kind);
+}
+
+
+void
+transfer_logical (void *p, int kind)
+{
+
+ g.item_count++;
+ if (ioparm.library_return != LIBRARY_OK)
+ return;
+ transfer (BT_LOGICAL, p, kind);
+}
+
+
+void
+transfer_character (void *p, int len)
+{
+
+ g.item_count++;
+ if (ioparm.library_return != LIBRARY_OK)
+ return;
+ transfer (BT_CHARACTER, p, len);
+}
+
+
+void
+transfer_complex (void *p, int kind)
+{
+
+ g.item_count++;
+ if (ioparm.library_return != LIBRARY_OK)
+ return;
+ transfer (BT_COMPLEX, p, kind);
+}
+
+
+/* us_read()-- Preposition a sequential unformatted file while reading. */
+
+static void
+us_read (void)
+{
+ offset_t *p;
+ int n;
+
+ n = sizeof (offset_t);
+ p = (offset_t *) salloc_r (current_unit->s, &n);
+
+ if (p == NULL || n != sizeof (offset_t))
+ {
+ generate_error (ERROR_BAD_US, NULL);
+ return;
+ }
+
+ current_unit->bytes_left = *p;
+}
+
+
+/* us_write()-- Preposition a sequential unformatted file while
+ * writing. This amount to writing a bogus length that will be filled
+ * in later. */
+
+static void
+us_write (void)
+{
+ offset_t *p;
+ int length;
+
+ length = sizeof (offset_t);
+ p = (offset_t *) salloc_w (current_unit->s, &length);
+
+ if (p == NULL)
+ {
+ generate_error (ERROR_OS, NULL);
+ return;
+ }
+
+ *p = 0; /* Bogus value for now */
+ if (sfree (current_unit->s) == FAILURE)
+ generate_error (ERROR_OS, NULL);
+
+ current_unit->bytes_left = current_unit->recl;
+}
+
+
+/* pre_position()-- position to the next record prior to transfer. We
+ * are assumed to be before the next record. We also calculate the
+ * bytes in the next record. */
+
+static void
+pre_position (void)
+{
+
+ if (current_unit->current_record)
+ return; /* Already positioned */
+
+ switch (current_mode ())
+ {
+ case UNFORMATTED_SEQUENTIAL:
+ if (g.mode == READING)
+ us_read ();
+ else
+ us_write ();
+
+ break;
+
+ case FORMATTED_SEQUENTIAL:
+ case FORMATTED_DIRECT:
+ case UNFORMATTED_DIRECT:
+ current_unit->bytes_left = current_unit->recl;
+ break;
+ }
+
+ current_unit->current_record = 1;
+}
+
+
+/* data_transfer_init()-- Initialize things for a data transfer. This
+ * code is common for both reading and writing. */
+
+static void
+data_transfer_init (int read_flag)
+{
+ unit_flags u_flags; /* used for creating a unit if needed */
+
+ g.mode = read_flag ? READING : WRITING;
+
+ if (ioparm.size != NULL)
+ *ioparm.size = 0; /* Initialize the count */
+
+ current_unit = get_unit (read_flag);
+ if (current_unit == NULL)
+ { /* open the unit with some default flags */
+ memset (&u_flags, '\0', sizeof (u_flags));
+ u_flags.access = ACCESS_SEQUENTIAL;
+ u_flags.action = ACTION_READWRITE;
+ u_flags.form = FORM_UNSPECIFIED;
+ u_flags.delim = DELIM_UNSPECIFIED;
+ u_flags.blank = BLANK_UNSPECIFIED;
+ u_flags.pad = PAD_UNSPECIFIED;
+ u_flags.status = STATUS_UNKNOWN;
+ new_unit(&u_flags);
+ current_unit = get_unit (read_flag);
+ }
+
+ if (current_unit == NULL)
+ return;
+
+ if (is_internal_unit() && g.mode==WRITING)
+ empty_internal_buffer (current_unit->s);
+
+ /* Check the action */
+
+ if (read_flag && current_unit->flags.action == ACTION_WRITE)
+ generate_error (ERROR_BAD_ACTION,
+ "Cannot read from file opened for WRITE");
+
+ if (!read_flag && current_unit->flags.action == ACTION_READ)
+ generate_error (ERROR_BAD_ACTION, "Cannot write to file opened for READ");
+
+ if (ioparm.library_return != LIBRARY_OK)
+ return;
+
+ /* Check the format */
+
+ if (ioparm.format)
+ parse_format ();
+
+ if (ioparm.library_return != LIBRARY_OK)
+ return;
+
+ if (current_unit->flags.form == FORM_UNFORMATTED
+ && (ioparm.format != NULL || ioparm.list_format))
+ generate_error (ERROR_OPTION_CONFLICT,
+ "Format present for UNFORMATTED data transfer");
+
+ if (ioparm.namelist_name != NULL && ionml != NULL)
+ {
+ if(ioparm.format != NULL)
+ generate_error (ERROR_OPTION_CONFLICT,
+ "A format cannot be specified with a namelist");
+ }
+ else if (current_unit->flags.form == FORM_FORMATTED &&
+ ioparm.format == NULL && !ioparm.list_format)
+ generate_error (ERROR_OPTION_CONFLICT,
+ "Missing format for FORMATTED data transfer");
+
+
+ if (is_internal_unit () && current_unit->flags.form == FORM_UNFORMATTED)
+ generate_error (ERROR_OPTION_CONFLICT,
+ "Internal file cannot be accessed by UNFORMATTED data transfer");
+
+ /* Check the record number */
+
+ if (current_unit->flags.access == ACCESS_DIRECT && ioparm.rec == 0)
+ {
+ generate_error (ERROR_MISSING_OPTION,
+ "Direct access data transfer requires record number");
+ return;
+ }
+
+ if (current_unit->flags.access == ACCESS_SEQUENTIAL && ioparm.rec != 0)
+ {
+ generate_error (ERROR_OPTION_CONFLICT,
+ "Record number not allowed for sequential access data transfer");
+ return;
+ }
+
+ /* Process the ADVANCE option */
+
+ advance_status = (ioparm.advance == NULL) ? ADVANCE_UNSPECIFIED :
+ find_option (ioparm.advance, ioparm.advance_len, advance_opt,
+ "Bad ADVANCE parameter in data transfer statement");
+
+ if (advance_status != ADVANCE_UNSPECIFIED)
+ {
+ if (current_unit->flags.access == ACCESS_DIRECT)
+ generate_error (ERROR_OPTION_CONFLICT,
+ "ADVANCE specification conflicts with sequential access");
+
+ if (is_internal_unit ())
+ generate_error (ERROR_OPTION_CONFLICT,
+ "ADVANCE specification conflicts with internal file");
+
+ if (ioparm.format == NULL || ioparm.list_format)
+ generate_error (ERROR_OPTION_CONFLICT,
+ "ADVANCE specification requires an explicit format");
+ }
+
+ if (read_flag)
+ {
+ if (ioparm.eor != 0 && advance_status == ADVANCE_NO)
+ generate_error (ERROR_MISSING_OPTION,
+ "EOR specification requires an ADVANCE specification of NO");
+
+ if (ioparm.size != NULL && advance_status != ADVANCE_NO)
+ generate_error (ERROR_MISSING_OPTION,
+ "SIZE specification requires an ADVANCE specification of NO");
+
+ }
+ else
+ { /* Write constraints */
+
+ if (ioparm.end != 0)
+ generate_error (ERROR_OPTION_CONFLICT,
+ "END specification cannot appear in a write statement");
+
+ if (ioparm.eor != 0)
+ generate_error (ERROR_OPTION_CONFLICT,
+ "EOR specification cannot appear in a write statement");
+
+ if (ioparm.size != 0)
+ generate_error (ERROR_OPTION_CONFLICT,
+ "SIZE specification cannot appear in a write statement");
+ }
+
+ if (advance_status == ADVANCE_UNSPECIFIED)
+ advance_status = ADVANCE_YES;
+ if (ioparm.library_return != LIBRARY_OK)
+ return;
+
+ /* Sanity checks on the record number */
+
+ if (ioparm.rec)
+ {
+ if (ioparm.rec <= 0)
+ {
+ generate_error (ERROR_BAD_OPTION, "Record number must be positive");
+ return;
+ }
+
+ if (ioparm.rec >= current_unit->maxrec)
+ {
+ generate_error (ERROR_BAD_OPTION, "Record number too large");
+ return;
+ }
+
+ /* Position the file */
+
+ if (sseek (current_unit->s,
+ (ioparm.rec - 1) * current_unit->recl) == FAILURE)
+ generate_error (ERROR_OS, NULL);
+ }
+
+ /* Set the initial value of flags */
+
+ g.blank_status = current_unit->flags.blank;
+ g.sign_status = SIGN_S;
+ g.scale_factor = 0;
+ g.seen_dollar = 0;
+ g.first_item = 1;
+ g.item_count = 0;
+
+ pre_position ();
+
+ /* Set up the subroutine that will handle the transfers */
+
+ if (read_flag)
+ {
+ if (current_unit->flags.form == FORM_UNFORMATTED)
+ transfer = unformatted_read;
+ else
+ {
+ if (ioparm.list_format)
+ {
+ transfer = list_formatted_read;
+ init_at_eol();
+ }
+ else
+ transfer = formatted_transfer;
+ }
+ }
+ else
+ {
+ if (current_unit->flags.form == FORM_UNFORMATTED)
+ transfer = unformatted_write;
+ else
+ {
+ if (ioparm.list_format)
+ transfer = list_formatted_write;
+ else
+ transfer = formatted_transfer;
+ }
+ }
+
+ /* Make sure that we don't do a read after a nonadvancing write */
+
+ if (read_flag)
+ {
+ if (current_unit->read_bad)
+ {
+ generate_error (ERROR_BAD_OPTION,
+ "Cannot READ after a nonadvancing WRITE");
+ return;
+ }
+ }
+ else
+ {
+ if (advance_status == ADVANCE_YES)
+ current_unit->read_bad = 1;
+ }
+
+ /* Start the data transfer if we are doing a formatted transfer */
+ if (current_unit->flags.form == FORM_FORMATTED && !ioparm.list_format
+ && ioparm.namelist_name == NULL && ionml == NULL)
+
+ formatted_transfer (0, NULL, 0);
+
+}
+
+
+/* next_record_r()-- Space to the next record for read mode. If the
+ * file is not seekable, we read MAX_READ chunks until we get to the
+ * right position. */
+
+#define MAX_READ 4096
+
+static void
+next_record_r (int done)
+{
+ int rlength, length;
+ offset_t new;
+ char *p;
+
+ switch (current_mode ())
+ {
+ case UNFORMATTED_SEQUENTIAL:
+ current_unit->bytes_left += sizeof (offset_t); /* Skip over tail */
+
+ /* Fall through */
+
+ case FORMATTED_DIRECT:
+ case UNFORMATTED_DIRECT:
+ if (current_unit->bytes_left == 0)
+ break;
+
+ if (is_seekable (current_unit->s))
+ {
+ new = file_position (current_unit->s) + current_unit->bytes_left;
+
+ /* Direct access files do not generate END conditions, only I/O errors */
+
+ if (sseek (current_unit->s, new) == FAILURE)
+ generate_error (ERROR_OS, NULL);
+
+ }
+ else
+ { /* Seek by reading data */
+ while (current_unit->bytes_left > 0)
+ {
+ rlength = length = (MAX_READ > current_unit->bytes_left) ?
+ MAX_READ : current_unit->bytes_left;
+
+ p = salloc_r (current_unit->s, &rlength);
+ if (p == NULL)
+ {
+ generate_error (ERROR_OS, NULL);
+ break;
+ }
+
+ current_unit->bytes_left -= length;
+ }
+ }
+
+ break;
+
+ case FORMATTED_SEQUENTIAL:
+ length = 1;
+ if (sf_seen_eor && done)
+ break;
+
+ do
+ {
+ p = salloc_r (current_unit->s, &length);
+
+ /*In case of internal file, there may not be any '\n'.*/
+ if (is_internal_unit() && p == NULL)
+ {
+ break;
+ }
+
+ if (p == NULL)
+ {
+ generate_error (ERROR_OS, NULL);
+ break;
+ }
+
+ if (length == 0)
+ {
+ current_unit->endfile = AT_ENDFILE;
+ break;
+ }
+ }
+ while (*p != '\n');
+
+ break;
+ }
+
+ if (current_unit->flags.access == ACCESS_SEQUENTIAL)
+ test_endfile (current_unit);
+}
+
+
+/* next_record_w()-- Position to the next record in write mode */
+
+static void
+next_record_w (int done)
+{
+ offset_t c, m;
+ int length;
+ char *p;
+
+ switch (current_mode ())
+ {
+ case FORMATTED_DIRECT:
+ case UNFORMATTED_DIRECT:
+ if (current_unit->bytes_left == 0)
+ break;
+
+ length = current_unit->bytes_left;
+
+ p = salloc_w (current_unit->s, &length);
+ if (p == NULL)
+ goto io_error;
+
+ memset (p, ' ', current_unit->bytes_left);
+ if (sfree (current_unit->s) == FAILURE)
+ goto io_error;
+
+ break;
+
+ case UNFORMATTED_SEQUENTIAL:
+ m = current_unit->recl - current_unit->bytes_left; /* Bytes written */
+ c = file_position (current_unit->s);
+
+ length = sizeof (offset_t);
+
+ /* Write the length tail */
+
+ p = salloc_w (current_unit->s, &length);
+ if (p == NULL)
+ goto io_error;
+
+ *((offset_t *) p) = m;
+ if (sfree (current_unit->s) == FAILURE)
+ goto io_error;
+
+ /* Seek to the head and overwrite the bogus length with the real length */
+
+ p = salloc_w_at (current_unit->s, &length, c - m - length);
+ if (p == NULL)
+ generate_error (ERROR_OS, NULL);
+
+ *((offset_t *) p) = m;
+ if (sfree (current_unit->s) == FAILURE)
+ goto io_error;
+
+ /* Seek past the end of the current record */
+
+ if (sseek (current_unit->s, c + sizeof (offset_t)) == FAILURE)
+ goto io_error;
+
+ break;
+
+ case FORMATTED_SEQUENTIAL:
+ length = 1;
+ p = salloc_w (current_unit->s, &length);
+
+ if (!is_internal_unit())
+ {
+ if (p)
+ *p = '\n'; /* no CR for internal writes */
+ else
+ goto io_error;
+ }
+
+ if (sfree (current_unit->s) == FAILURE)
+ goto io_error;
+
+ break;
+
+ io_error:
+ generate_error (ERROR_OS, NULL);
+ break;
+ }
+}
+
+
+/* next_record()-- Position to the next record, which means moving to
+ * the end of the current record. This can happen under several
+ * different conditions. If the done flag is not set, we get ready to
+ * process the next record. */
+
+void
+next_record (int done)
+{
+
+ current_unit->read_bad = 0;
+
+ if (g.mode == READING)
+ next_record_r (done);
+ else
+ next_record_w (done);
+
+ current_unit->current_record = 0;
+ if (current_unit->flags.access == ACCESS_DIRECT)
+ current_unit->last_record = file_position (current_unit->s)
+ / current_unit->recl;
+ else
+ current_unit->last_record++;
+
+ if (!done)
+ pre_position ();
+}
+
+
+/* Finalize the current data transfer. For a nonadvancing transfer,
+ * this means advancing to the next record. */
+
+static void
+finalize_transfer (void)
+{
+
+ if (setjmp (g.eof_jump))
+ {
+ generate_error (ERROR_END, NULL);
+ return;
+ }
+
+ if ((ionml != NULL) && (ioparm.namelist_name != NULL))
+ {
+ if (ioparm.namelist_read_mode)
+ namelist_read();
+ else
+ namelist_write();
+ }
+
+ transfer = NULL;
+ if (current_unit == NULL)
+ return;
+
+ if (ioparm.list_format && g.mode == READING)
+ finish_list_read ();
+ else
+ {
+ free_fnodes ();
+
+ if (advance_status == ADVANCE_NO)
+ return;
+ next_record (1);
+ current_unit->current_record = 0;
+ }
+
+ sfree (current_unit->s);
+}
+
+
+/* The READ statement */
+
+void
+st_read (void)
+{
+
+ library_start ();
+
+ data_transfer_init (1);
+
+ /* Handle complications dealing with the endfile record. It is
+ * significant that this is the only place where ERROR_END is
+ * generated. Reading an end of file elsewhere is either end of
+ * record or an I/O error. */
+
+ if (current_unit->flags.access == ACCESS_SEQUENTIAL)
+ switch (current_unit->endfile)
+ {
+ case NO_ENDFILE:
+ break;
+
+ case AT_ENDFILE:
+ if (!is_internal_unit())
+ {
+ generate_error (ERROR_END, NULL);
+ current_unit->endfile = AFTER_ENDFILE;
+ }
+ break;
+
+ case AFTER_ENDFILE:
+ generate_error (ERROR_ENDFILE, NULL);
+ break;
+ }
+}
+
+
+void
+st_read_done (void)
+{
+ finalize_transfer ();
+
+ library_end ();
+}
+
+
+void
+st_write (void)
+{
+
+ library_start ();
+ data_transfer_init (0);
+}
+
+
+void
+st_write_done (void)
+{
+
+ finalize_transfer ();
+
+ /* Deal with endfile conditions associated with sequential files */
+
+ if (current_unit != NULL && current_unit->flags.access == ACCESS_SEQUENTIAL)
+ switch (current_unit->endfile)
+ {
+ case AT_ENDFILE: /* Remain at the endfile record */
+ break;
+
+ case AFTER_ENDFILE:
+ current_unit->endfile = AT_ENDFILE; /* Just at it now */
+ break;
+
+ case NO_ENDFILE: /* Get rid of whatever is after this record */
+ if (struncate (current_unit->s) == FAILURE)
+ generate_error (ERROR_OS, NULL);
+
+ current_unit->endfile = AT_ENDFILE;
+ break;
+ }
+
+ library_end ();
+}
+
+
+static void
+st_set_nml_var (void * var_addr, char * var_name, int var_name_len,
+ int kind, bt type)
+{
+ namelist_info *t1 = NULL, *t2 = NULL;
+ namelist_info *nml = (namelist_info *) get_mem (sizeof(
+ namelist_info ));
+ nml->mem_pos = var_addr;
+ nml->var_name = (char*) get_mem (var_name_len+1);
+ strncpy (nml->var_name,var_name,var_name_len);
+ nml->var_name[var_name_len] = 0;
+ nml->len = kind;
+ nml->type = type;
+
+ nml->next = NULL;
+
+ if (ionml == NULL)
+ ionml = nml;
+ else
+ {
+ t1 = ionml;
+ while (t1 != NULL)
+ {
+ t2 = t1;
+ t1 = t1->next;
+ }
+ t2->next = nml;
+ }
+}
+
+void
+st_set_nml_var_int (void * var_addr, char * var_name, int var_name_len,
+ int kind)
+{
+ st_set_nml_var (var_addr, var_name, var_name_len, kind, BT_INTEGER);
+}
+
+void
+st_set_nml_var_float (void * var_addr, char * var_name, int var_name_len,
+ int kind)
+{
+ st_set_nml_var (var_addr, var_name, var_name_len, kind, BT_REAL);
+}
+
+void
+st_set_nml_var_char (void * var_addr, char * var_name, int var_name_len,
+ int kind)
+{
+ st_set_nml_var (var_addr, var_name, var_name_len, kind, BT_CHARACTER);
+}
+
+void
+st_set_nml_var_complex (void * var_addr, char * var_name, int var_name_len,
+ int kind)
+{
+ st_set_nml_var (var_addr, var_name, var_name_len, kind, BT_COMPLEX);
+}
+
+void
+st_set_nml_var_log (void * var_addr, char * var_name, int var_name_len,
+ int kind)
+{
+ st_set_nml_var (var_addr, var_name, var_name_len, kind, BT_LOGICAL);
+}
+
diff --git a/libgfortran/io/unit.c b/libgfortran/io/unit.c
new file mode 100644
index 00000000000..87f9095b731
--- /dev/null
+++ b/libgfortran/io/unit.c
@@ -0,0 +1,380 @@
+/* Copyright (C) 2002-2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran 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 2, or (at your option)
+any later version.
+
+Libgfortran 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 Libgfortran; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <string.h>
+#include "libgfortran.h"
+#include "io.h"
+
+
+/* Subroutines related to units */
+
+
+#define CACHE_SIZE 3
+static unit_t internal_unit, *unit_cache[CACHE_SIZE];
+
+
+/* This implementation is based on Stefan Nilsson's article in the
+ * July 1997 Doctor Dobb's Journal, "Treaps in Java". */
+
+/* pseudo_random()-- Simple linear congruential pseudorandom number
+ * generator. The period of this generator is 44071, which is plenty
+ * for our purposes. */
+
+static int
+pseudo_random (void)
+{
+ static int x0 = 5341;
+
+ x0 = (22611 * x0 + 10) % 44071;
+ return x0;
+}
+
+
+/* rotate_left()-- Rotate the treap left */
+
+static unit_t *
+rotate_left (unit_t * t)
+{
+ unit_t *temp;
+
+ temp = t->right;
+ t->right = t->right->left;
+ temp->left = t;
+
+ return temp;
+}
+
+
+/* rotate_right()-- Rotate the treap right */
+
+static unit_t *
+rotate_right (unit_t * t)
+{
+ unit_t *temp;
+
+ temp = t->left;
+ t->left = t->left->right;
+ temp->right = t;
+
+ return temp;
+}
+
+
+
+static int
+compare (int a, int b)
+{
+
+ if (a < b)
+ return -1;
+ if (a > b)
+ return 1;
+
+ return 0;
+}
+
+
+/* insert()-- Recursive insertion function. Returns the updated treap. */
+
+static unit_t *
+insert (unit_t * new, unit_t * t)
+{
+ int c;
+
+ if (t == NULL)
+ return new;
+
+ c = compare (new->unit_number, t->unit_number);
+
+ if (c < 0)
+ {
+ t->left = insert (new, t->left);
+ if (t->priority < t->left->priority)
+ t = rotate_right (t);
+ }
+
+ if (c > 0)
+ {
+ t->right = insert (new, t->right);
+ if (t->priority < t->right->priority)
+ t = rotate_left (t);
+ }
+
+ if (c == 0)
+ internal_error ("insert(): Duplicate key found!");
+
+ return t;
+}
+
+
+/* insert_unit()-- Given a new node, insert it into the treap. It is
+ * an error to insert a key that already exists. */
+
+void
+insert_unit (unit_t * new)
+{
+
+ new->priority = pseudo_random ();
+ g.unit_root = insert (new, g.unit_root);
+}
+
+
+static unit_t *
+delete_root (unit_t * t)
+{
+ unit_t *temp;
+
+ if (t->left == NULL)
+ return t->right;
+ if (t->right == NULL)
+ return t->left;
+
+ if (t->left->priority > t->right->priority)
+ {
+ temp = rotate_right (t);
+ temp->right = delete_root (t);
+ }
+ else
+ {
+ temp = rotate_left (t);
+ temp->left = delete_root (t);
+ }
+
+ return temp;
+}
+
+
+/* delete_treap()-- Delete an element from a tree. The 'old' value
+ * does not necessarily have to point to the element to be deleted, it
+ * must just point to a treap structure with the key to be deleted.
+ * Returns the new root node of the tree. */
+
+static unit_t *
+delete_treap (unit_t * old, unit_t * t)
+{
+ int c;
+
+ if (t == NULL)
+ return NULL;
+
+ c = compare (old->unit_number, t->unit_number);
+
+ if (c < 0)
+ t->left = delete_treap (old, t->left);
+ if (c > 0)
+ t->right = delete_treap (old, t->right);
+ if (c == 0)
+ t = delete_root (t);
+
+ return t;
+}
+
+
+/* delete_unit()-- Delete a unit from a tree */
+
+static void
+delete_unit (unit_t * old)
+{
+
+ g.unit_root = delete_treap (old, g.unit_root);
+}
+
+
+/* find_unit()-- Given an integer, return a pointer to the unit
+ * structure. Returns NULL if the unit does not exist. */
+
+unit_t *
+find_unit (int n)
+{
+ unit_t *p;
+ int c;
+
+ for (c = 0; c < CACHE_SIZE; c++)
+ if (unit_cache[c] != NULL && unit_cache[c]->unit_number == n)
+ {
+ p = unit_cache[c];
+ return p;
+ }
+
+ p = g.unit_root;
+ while (p != NULL)
+ {
+ c = compare (n, p->unit_number);
+ if (c < 0)
+ p = p->left;
+ if (c > 0)
+ p = p->right;
+ if (c == 0)
+ break;
+ }
+
+ if (p != NULL)
+ {
+ for (c = 0; c < CACHE_SIZE - 1; c++)
+ unit_cache[c] = unit_cache[c + 1];
+
+ unit_cache[CACHE_SIZE - 1] = p;
+ }
+
+ return p;
+}
+
+/* get_unit()-- Returns the unit structure associated with the integer
+ * unit or the internal file. */
+
+unit_t *
+get_unit (int read_flag)
+{
+ unit_t *u;
+
+ if (ioparm.internal_unit != NULL)
+ {
+ internal_unit.s =
+ open_internal (ioparm.internal_unit, ioparm.internal_unit_len);
+
+ /* Set flags for the internal unit */
+
+ internal_unit.flags.access = ACCESS_SEQUENTIAL;
+ internal_unit.flags.action = ACTION_READWRITE;
+ internal_unit.flags.form = FORM_FORMATTED;
+ internal_unit.flags.delim = DELIM_NONE;
+
+ return &internal_unit;
+ }
+
+ /* Has to be an external unit */
+
+ u = find_unit (ioparm.unit);
+ if (u != NULL)
+ return u;
+
+ return NULL;
+}
+
+
+/* is_internal_unit()-- Determine if the current unit is internal or
+ * not */
+
+int
+is_internal_unit ()
+{
+
+ return current_unit == &internal_unit;
+}
+
+
+
+/*************************/
+/* Initialize everything */
+
+void
+init_units (void)
+{
+ offset_t m, n;
+ unit_t *u;
+ int i;
+
+ if (options.stdin_unit >= 0)
+ { /* STDIN */
+ u = get_mem (sizeof (unit_t));
+
+ u->unit_number = options.stdin_unit;
+ u->s = input_stream ();
+
+ u->flags.action = ACTION_READ;
+
+ u->flags.access = ACCESS_SEQUENTIAL;
+ u->flags.form = FORM_FORMATTED;
+ u->flags.status = STATUS_OLD;
+ u->flags.blank = BLANK_ZERO;
+ u->flags.position = POSITION_ASIS;
+
+ u->recl = options.default_recl;
+ u->endfile = NO_ENDFILE;
+
+ insert_unit (u);
+ }
+
+ if (options.stdout_unit >= 0)
+ { /* STDOUT */
+ u = get_mem (sizeof (unit_t));
+
+ u->unit_number = options.stdout_unit;
+ u->s = output_stream ();
+
+ u->flags.action = ACTION_WRITE;
+
+ u->flags.access = ACCESS_SEQUENTIAL;
+ u->flags.form = FORM_FORMATTED;
+ u->flags.status = STATUS_OLD;
+ u->flags.blank = BLANK_ZERO;
+ u->flags.position = POSITION_ASIS;
+
+ u->recl = options.default_recl;
+ u->endfile = AT_ENDFILE;
+
+ insert_unit (u);
+ }
+
+ /* Calculate the maximum file offset in a portable manner.
+ * max will be the largest signed number for the type offset_t.
+ *
+ * set a 1 in the LSB and keep a running sum, stopping at MSB-1 bit. */
+
+ g.max_offset = 0;
+ for (i=0; i < sizeof(g.max_offset) * 8 - 1; i++)
+ g.max_offset = g.max_offset + ((offset_t) 1 << i);
+
+}
+
+
+/* close_unit()-- Close a unit. The stream is closed, and any memory
+ * associated with the stream is freed. Returns nonzero on I/O error. */
+
+int
+close_unit (unit_t * u)
+{
+ int i, rc;
+
+ for (i = 0; i < CACHE_SIZE; i++)
+ if (unit_cache[i] == u)
+ unit_cache[i] = NULL;
+
+ rc = (u->s == NULL) ? 0 : sclose (u->s) == FAILURE;
+
+ delete_unit (u);
+ free_mem (u);
+
+ return rc;
+}
+
+
+/* close_units()-- Delete units on completion. We just keep deleting
+ * the root of the treap until there is nothing left. */
+
+void
+close_units (void)
+{
+
+ while (g.unit_root != NULL)
+ close_unit (g.unit_root);
+}
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
new file mode 100644
index 00000000000..185608aba33
--- /dev/null
+++ b/libgfortran/io/unix.c
@@ -0,0 +1,1432 @@
+/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran 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 2, or (at your option)
+any later version.
+
+Libgfortran 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 Libgfortran; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Unix stream I/O module */
+
+#include "config.h"
+#include <stdlib.h>
+#include <limits.h>
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <sys/mman.h>
+#include <string.h>
+#include <errno.h>
+
+#include "libgfortran.h"
+#include "io.h"
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *) -1)
+#endif
+
+/* This implementation of stream I/O is based on the paper:
+ *
+ * "Exploiting the advantages of mapped files for stream I/O",
+ * O. Krieger, M. Stumm and R. Umrau, "Proceedings of the 1992 Winter
+ * USENIX conference", p. 27-42.
+ *
+ * It differs in a number of ways from the version described in the
+ * paper. First of all, threads are not an issue during I/O and we
+ * also don't have to worry about having multiple regions, since
+ * fortran's I/O model only allows you to be one place at a time.
+ *
+ * On the other hand, we have to be able to writing at the end of a
+ * stream, read from the start of a stream or read and write blocks of
+ * bytes from an arbitrary position. After opening a file, a pointer
+ * to a stream structure is returned, which is used to handle file
+ * accesses until the file is closed.
+ *
+ * salloc_at_r(stream, len, where)-- Given a stream pointer, return a
+ * pointer to a block of memory that mirror the file at position
+ * 'where' that is 'len' bytes long. The len integer is updated to
+ * reflect how many bytes were actually read. The only reason for a
+ * short read is end of file. The file pointer is updated. The
+ * pointer is valid until the next call to salloc_*.
+ *
+ * salloc_at_w(stream, len, where)-- Given the stream pointer, returns
+ * a pointer to a block of memory that is updated to reflect the state
+ * of the file. The length of the buffer is always equal to that
+ * requested. The buffer must be completely set by the caller. When
+ * data has been written, the sfree() function must be called to
+ * indicate that the caller is done writing data to the buffer. This
+ * may or may not cause a physical write.
+ *
+ * Short forms of these are salloc_r() and salloc_w() which drop the
+ * 'where' parameter and use the current file pointer. */
+
+
+#define BUFFER_SIZE 8192
+
+typedef struct
+{
+ stream st;
+
+ int fd;
+ offset_t buffer_offset; /* File offset of the start of the buffer */
+ offset_t physical_offset; /* Current physical file offset */
+ offset_t logical_offset; /* Current logical file offset */
+ offset_t dirty_offset; /* Start of modified bytes in buffer */
+ offset_t file_length; /* Length of the file, -1 if not seekable. */
+
+ char *buffer;
+ int len; /* Physical length of the current buffer */
+ int active; /* Length of valid bytes in the buffer */
+
+ int prot;
+ int ndirty; /* Dirty bytes starting at dirty_offset */
+
+ unsigned unbuffered:1, mmaped:1;
+
+ char small_buffer[BUFFER_SIZE];
+
+}
+unix_stream;
+
+/*move_pos_offset()-- Move the record pointer right or left
+ *relative to current position */
+
+int
+move_pos_offset (stream* st, int pos_off)
+{
+ unix_stream * str = (unix_stream*)st;
+ if (pos_off < 0)
+ {
+ str->active += pos_off;
+ if (str->active < 0)
+ str->active = 0;
+
+ str->logical_offset += pos_off;
+
+ if (str->dirty_offset+str->ndirty > str->logical_offset)
+ {
+ if (str->ndirty + pos_off > 0)
+ str->ndirty += pos_off ;
+ else
+ {
+ str->dirty_offset += pos_off + pos_off;
+ str->ndirty = 0 ;
+ }
+ }
+
+ return pos_off ;
+ }
+ return 0 ;
+}
+
+
+/* fix_fd()-- Given a file descriptor, make sure it is not one of the
+ * standard descriptors, returning a non-standard descriptor. If the
+ * user specifies that system errors should go to standard output,
+ * then closes standard output, we don't want the system errors to a
+ * file that has been given file descriptor 1 or 0. We want to send
+ * the error to the invalid descriptor. */
+
+static int
+fix_fd (int fd)
+{
+ int input, output, error;
+
+ input = output = error = 0;
+
+/* Unix allocates the lowest descriptors first, so a loop is not
+ * required, but this order is. */
+
+ if (fd == STDIN_FILENO)
+ {
+ fd = dup (fd);
+ input = 1;
+ }
+ if (fd == STDOUT_FILENO)
+ {
+ fd = dup (fd);
+ output = 1;
+ }
+ if (fd == STDERR_FILENO)
+ {
+ fd = dup (fd);
+ error = 1;
+ }
+
+ if (input)
+ close (STDIN_FILENO);
+ if (output)
+ close (STDOUT_FILENO);
+ if (error)
+ close (STDERR_FILENO);
+
+ return fd;
+}
+
+
+/* write()-- Write a buffer to a descriptor, allowing for short writes */
+
+static int
+writen (int fd, char *buffer, int len)
+{
+ int n, n0;
+
+ n0 = len;
+
+ while (len > 0)
+ {
+ n = write (fd, buffer, len);
+ if (n < 0)
+ return n;
+
+ buffer += n;
+ len -= n;
+ }
+
+ return n0;
+}
+
+
+#if 0
+/* readn()-- Read bytes into a buffer, allowing for short reads. If
+ * fewer than len bytes are returned, it is because we've hit the end
+ * of file. */
+
+static int
+readn (int fd, char *buffer, int len)
+{
+ int nread, n;
+
+ nread = 0;
+
+ while (len > 0)
+ {
+ n = read (fd, buffer, len);
+ if (n < 0)
+ return n;
+
+ if (n == 0)
+ return nread;
+
+ buffer += n;
+ nread += n;
+ len -= n;
+ }
+
+ return nread;
+}
+#endif
+
+
+/* get_oserror()-- Get the most recent operating system error. For
+ * unix, this is errno. */
+
+const char *
+get_oserror (void)
+{
+
+ return strerror (errno);
+}
+
+
+/* sys_exit()-- Terminate the program with an exit code */
+
+void
+sys_exit (int code)
+{
+
+ exit (code);
+}
+
+
+
+/*********************************************************************
+ File descriptor stream functions
+*********************************************************************/
+
+/* fd_flush()-- Write bytes that need to be written */
+
+static try
+fd_flush (unix_stream * s)
+{
+
+ if (s->ndirty == 0)
+ return SUCCESS;;
+
+ if (s->physical_offset != s->dirty_offset &&
+ lseek (s->fd, s->dirty_offset, SEEK_SET) < 0)
+ return FAILURE;
+
+ if (writen (s->fd, s->buffer + (s->dirty_offset - s->buffer_offset),
+ s->ndirty) < 0)
+ return FAILURE;
+
+ s->physical_offset = s->dirty_offset + s->ndirty;
+ if (s->physical_offset > s->file_length)
+ s->file_length = s->physical_offset;
+ s->ndirty = 0;
+
+ return SUCCESS;
+}
+
+
+/* fd_alloc()-- Arrange a buffer such that the salloc() request can be
+ * satisfied. This subroutine gets the buffer ready for whatever is
+ * to come next. */
+
+static void
+fd_alloc (unix_stream * s, offset_t where, int *len)
+{
+ char *new_buffer;
+ int n, read_len;
+
+ if (*len <= BUFFER_SIZE)
+ {
+ new_buffer = s->small_buffer;
+ read_len = BUFFER_SIZE;
+ }
+ else
+ {
+ new_buffer = get_mem (*len);
+ read_len = *len;
+ }
+
+ /* Salvage bytes currently within the buffer. This is important for
+ * devices that cannot seek. */
+
+ if (s->buffer != NULL && s->buffer_offset <= where &&
+ where <= s->buffer_offset + s->active)
+ {
+
+ n = s->active - (where - s->buffer_offset);
+ memmove (new_buffer, s->buffer + (where - s->buffer_offset), n);
+
+ s->active = n;
+ }
+ else
+ { /* new buffer starts off empty */
+ s->active = 0;
+ }
+
+ s->buffer_offset = where;
+
+ /* free the old buffer if necessary */
+
+ if (s->buffer != NULL && s->buffer != s->small_buffer)
+ free_mem (s->buffer);
+
+ s->buffer = new_buffer;
+ s->len = read_len;
+ s->mmaped = 0;
+}
+
+
+/* fd_alloc_r_at()-- Allocate a stream buffer for reading. Either
+ * we've already buffered the data or we need to load it. Returns
+ * NULL on I/O error. */
+
+static char *
+fd_alloc_r_at (unix_stream * s, int *len, offset_t where)
+{
+ offset_t m;
+ int n;
+
+ if (where == -1)
+ where = s->logical_offset;
+
+ if (s->buffer != NULL && s->buffer_offset <= where &&
+ where + *len <= s->buffer_offset + s->active)
+ {
+
+ /* Return a position within the current buffer */
+
+ s->logical_offset = where + *len;
+ return s->buffer + where - s->buffer_offset;
+ }
+
+ fd_alloc (s, where, len);
+
+ m = where + s->active;
+
+ if (s->physical_offset != m && lseek (s->fd, m, SEEK_SET) < 0)
+ return NULL;
+
+ n = read (s->fd, s->buffer + s->active, s->len - s->active);
+ if (n < 0)
+ return NULL;
+
+ s->physical_offset = where + n;
+
+ s->active += n;
+ if (s->active < *len)
+ *len = s->active; /* Bytes actually available */
+
+ s->logical_offset = where + *len;
+
+ return s->buffer;
+}
+
+
+/* fd_alloc_w_at()-- Allocate a stream buffer for writing. Either
+ * we've already buffered the data or we need to load it. */
+
+static char *
+fd_alloc_w_at (unix_stream * s, int *len, offset_t where)
+{
+ offset_t n;
+
+ if (where == -1)
+ where = s->logical_offset;
+
+ if (s->buffer == NULL || s->buffer_offset > where ||
+ where + *len > s->buffer_offset + s->len)
+ {
+
+ if (fd_flush (s) == FAILURE)
+ return NULL;
+ fd_alloc (s, where, len);
+ }
+
+ /* Return a position within the current buffer */
+
+ if (s->ndirty == 0)
+ { /* First write into a clean buffer */
+ s->dirty_offset = where;
+ s->ndirty = *len;
+ }
+ else
+ {
+ if (s->dirty_offset + s->ndirty == where)
+ s->ndirty += *len;
+ else
+ fd_flush (s); /* Can't combine two dirty blocks */
+ }
+
+ s->logical_offset = where + *len;
+
+ n = s->logical_offset - s->buffer_offset;
+ if (n > s->active)
+ s->active = n;
+
+ return s->buffer + where - s->buffer_offset;
+}
+
+
+static try
+fd_sfree (unix_stream * s)
+{
+
+ if (s->ndirty != 0 &&
+ (s->buffer != s->small_buffer || options.all_unbuffered ||
+ s->unbuffered))
+ return fd_flush (s);
+
+ return SUCCESS;
+}
+
+
+static int
+fd_seek (unix_stream * s, offset_t offset)
+{
+
+ s->physical_offset = s->logical_offset = offset;
+
+ return (lseek (s->fd, offset, SEEK_SET) < 0) ? FAILURE : SUCCESS;
+}
+
+
+/* truncate_file()-- Given a unit, truncate the file at the current
+ * position. Sets the physical location to the new end of the file.
+ * Returns nonzero on error. */
+
+static try
+fd_truncate (unix_stream * s)
+{
+
+ if (ftruncate (s->fd, s->logical_offset))
+ return FAILURE;
+
+ s->physical_offset = s->file_length = s->logical_offset;
+
+ if (lseek (s->fd, s->file_length, SEEK_SET) == -1)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+
+static try
+fd_close (unix_stream * s)
+{
+
+ if (fd_flush (s) == FAILURE)
+ return FAILURE;
+
+ if (s->buffer != NULL && s->buffer != s->small_buffer)
+ free_mem (s->buffer);
+
+ if (close (s->fd) < 0)
+ return FAILURE;
+
+ free_mem (s);
+
+ return SUCCESS;
+}
+
+
+static void
+fd_open (unix_stream * s)
+{
+
+ if (isatty (s->fd))
+ s->unbuffered = 1;
+
+ s->st.alloc_r_at = (void *) fd_alloc_r_at;
+ s->st.alloc_w_at = (void *) fd_alloc_w_at;
+ s->st.sfree = (void *) fd_sfree;
+ s->st.close = (void *) fd_close;
+ s->st.seek = (void *) fd_seek;
+ s->st.truncate = (void *) fd_truncate;
+
+ s->buffer = NULL;
+}
+
+
+/*********************************************************************
+ mmap stream functions
+
+ Because mmap() is not capable of extending a file, we have to keep
+ track of how long the file is. We also have to be able to detect end
+ of file conditions. If there are multiple writers to the file (which
+ can only happen outside the current program), things will get
+ confused. Then again, things will get confused anyway.
+
+*********************************************************************/
+
+#if HAVE_MMAP
+
+static int page_size, page_mask;
+
+/* mmap_flush()-- Deletes a memory mapping if something is mapped. */
+
+static try
+mmap_flush (unix_stream * s)
+{
+
+ if (!s->mmaped)
+ return fd_flush (s);
+
+ if (s->buffer == NULL)
+ return SUCCESS;
+
+ if (munmap (s->buffer, s->active))
+ return FAILURE;
+
+ s->buffer = NULL;
+ s->active = 0;
+
+ return SUCCESS;
+}
+
+
+/* mmap_alloc()-- mmap() a section of the file. The whole section is
+ * guaranteed to be mappable. */
+
+static try
+mmap_alloc (unix_stream * s, offset_t where, int *len)
+{
+ offset_t offset;
+ int length;
+ char *p;
+
+ if (mmap_flush (s) == FAILURE)
+ return FAILURE;
+
+ offset = where & page_mask; /* Round down to the next page */
+
+ length = ((where - offset) & page_mask) + 2 * page_size;
+
+ p = mmap (NULL, length, s->prot, MAP_SHARED, s->fd, offset);
+ if (p == (char *) MAP_FAILED)
+ return FAILURE;
+
+ s->mmaped = 1;
+ s->buffer = p;
+ s->buffer_offset = offset;
+ s->active = length;
+
+ return SUCCESS;
+}
+
+
+static char *
+mmap_alloc_r_at (unix_stream * s, int *len, offset_t where)
+{
+ offset_t m;
+
+ if (where == -1)
+ where = s->logical_offset;
+
+ m = where + *len;
+
+ if ((s->buffer == NULL || s->buffer_offset > where ||
+ m > s->buffer_offset + s->active) &&
+ mmap_alloc (s, where, len) == FAILURE)
+ return NULL;
+
+ if (m > s->file_length)
+ {
+ *len = s->file_length - s->logical_offset;
+ s->logical_offset = s->file_length;
+ }
+ else
+ s->logical_offset = m;
+
+ return s->buffer + (where - s->buffer_offset);
+}
+
+
+static char *
+mmap_alloc_w_at (unix_stream * s, int *len, offset_t where)
+{
+ if (where == -1)
+ where = s->logical_offset;
+
+ /* If we're extending the file, we have to use file descriptor
+ * methods. */
+
+ if (where + *len > s->file_length)
+ {
+ if (s->mmaped)
+ mmap_flush (s);
+ return fd_alloc_w_at (s, len, where);
+ }
+
+ if ((s->buffer == NULL || s->buffer_offset > where ||
+ where + *len > s->buffer_offset + s->active) &&
+ mmap_alloc (s, where, len) == FAILURE)
+ return NULL;
+
+ s->logical_offset = where + *len;
+
+ return s->buffer + where - s->buffer_offset;
+}
+
+
+static int
+mmap_seek (unix_stream * s, offset_t offset)
+{
+
+ s->logical_offset = offset;
+ return SUCCESS;
+}
+
+
+static try
+mmap_close (unix_stream * s)
+{
+ try t;
+
+ t = mmap_flush (s);
+
+ if (close (s->fd) < 0)
+ t = FAILURE;
+ free_mem (s);
+
+ return t;
+}
+
+
+static try
+mmap_sfree (unix_stream * s)
+{
+
+ return SUCCESS;
+}
+
+
+/* mmap_open()-- mmap_specific open. If the particular file cannot be
+ * mmap()-ed, we fall back to the file descriptor functions. */
+
+static try
+mmap_open (unix_stream * s)
+{
+ char *p;
+ int i;
+
+ page_size = getpagesize ();
+ page_mask = ~0;
+
+ p = mmap (0, page_size, s->prot, MAP_SHARED, s->fd, 0);
+ if (p == (char *) MAP_FAILED)
+ {
+ fd_open (s);
+ return SUCCESS;
+ }
+
+ munmap (p, page_size);
+
+ i = page_size >> 1;
+ while (i != 0)
+ {
+ page_mask <<= 1;
+ i >>= 1;
+ }
+
+ s->st.alloc_r_at = (void *) mmap_alloc_r_at;
+ s->st.alloc_w_at = (void *) mmap_alloc_w_at;
+ s->st.sfree = (void *) mmap_sfree;
+ s->st.close = (void *) mmap_close;
+ s->st.seek = (void *) mmap_seek;
+ s->st.truncate = (void *) fd_truncate;
+
+ if (lseek (s->fd, s->file_length, SEEK_SET) < 0)
+ return FAILURE;
+
+ return SUCCESS;
+}
+
+#endif
+
+
+/*********************************************************************
+ memory stream functions - These are used for internal files
+
+ The idea here is that a single stream structure is created and all
+ requests must be satisfied from it. The location and size of the
+ buffer is the character variable supplied to the READ or WRITE
+ statement.
+
+*********************************************************************/
+
+
+static char *
+mem_alloc_r_at (unix_stream * s, int *len, offset_t where)
+{
+ offset_t n;
+
+ if (where == -1)
+ where = s->logical_offset;
+
+ if (where < s->buffer_offset || where > s->buffer_offset + s->active)
+ return NULL;
+
+ if (is_internal_unit() && where + *len > s->file_length)
+ return NULL;
+
+ s->logical_offset = where + *len;
+
+ n = (where - s->buffer_offset) - s->active;
+ if (*len > n)
+ *len = n;
+
+ return s->buffer + (where - s->buffer_offset);
+}
+
+
+static char *
+mem_alloc_w_at (unix_stream * s, int *len, offset_t where)
+{
+ offset_t m;
+
+ if (where == -1)
+ where = s->logical_offset;
+
+ m = where + *len;
+
+ if (where < s->buffer_offset || m > s->buffer_offset + s->active)
+ return NULL;
+
+ s->logical_offset = m;
+
+ return s->buffer + (where - s->buffer_offset);
+}
+
+
+static int
+mem_seek (unix_stream * s, offset_t offset)
+{
+
+ if (offset > s->file_length)
+ {
+ errno = ESPIPE;
+ return FAILURE;
+ }
+
+ s->logical_offset = offset;
+ return SUCCESS;
+}
+
+
+static int
+mem_truncate (unix_stream * s)
+{
+
+ return SUCCESS;
+}
+
+
+static try
+mem_close (unix_stream * s)
+{
+
+ return SUCCESS;
+}
+
+
+static try
+mem_sfree (unix_stream * s)
+{
+
+ return SUCCESS;
+}
+
+
+
+/*********************************************************************
+ Public functions -- A reimplementation of this module needs to
+ define functional equivalents of the following.
+*********************************************************************/
+
+/* empty_internal_buffer()-- Zero the buffer of Internal file */
+
+void
+empty_internal_buffer(stream *strm)
+{
+ unix_stream * s = (unix_stream *) strm;
+ memset(s->buffer, ' ', s->file_length);
+}
+
+/* open_internal()-- Returns a stream structure from an internal file */
+
+stream *
+open_internal (char *base, int length)
+{
+ unix_stream *s;
+
+ s = get_mem (sizeof (unix_stream));
+
+ s->buffer = base;
+ s->buffer_offset = 0;
+
+ s->logical_offset = 0;
+ s->active = s->file_length = length;
+
+ s->st.alloc_r_at = (void *) mem_alloc_r_at;
+ s->st.alloc_w_at = (void *) mem_alloc_w_at;
+ s->st.sfree = (void *) mem_sfree;
+ s->st.close = (void *) mem_close;
+ s->st.seek = (void *) mem_seek;
+ s->st.truncate = (void *) mem_truncate;
+
+ return (stream *) s;
+}
+
+
+/* fd_to_stream()-- Given an open file descriptor, build a stream
+ * around it. */
+
+static stream *
+fd_to_stream (int fd, int prot)
+{
+ struct stat statbuf;
+ unix_stream *s;
+
+ s = get_mem (sizeof (unix_stream));
+
+ s->fd = fd;
+ s->buffer_offset = 0;
+ s->physical_offset = 0;
+ s->logical_offset = 0;
+ s->prot = prot;
+
+ /* Get the current length of the file. */
+
+ fstat (fd, &statbuf);
+ s->file_length = S_ISREG (statbuf.st_mode) ? statbuf.st_size : -1;
+
+#if HAVE_MMAP
+ mmap_open (s);
+#else
+ fd_open (s);
+#endif
+
+ return (stream *) s;
+}
+
+
+/* unpack_filename()-- Given a fortran string and a pointer to a
+ * buffer that is PATH_MAX characters, convert the fortran string to a
+ * C string in the buffer. Returns nonzero if this is not possible. */
+
+static int
+unpack_filename (char *cstring, const char *fstring, int len)
+{
+
+ len = fstrlen (fstring, len);
+ if (len >= PATH_MAX)
+ return 1;
+
+ memmove (cstring, fstring, len);
+ cstring[len] = '\0';
+
+ return 0;
+}
+
+
+/* tempfile()-- Generate a temporary filename for a scratch file and
+ * open it. mkstemp() opens the file for reading and writing, but the
+ * library mode prevents anything that is not allowed. The descriptor
+ * is returns, which is less than zero on error. The template is
+ * pointed to by ioparm.file, which is copied into the unit structure
+ * and freed later. */
+
+static int
+tempfile (void)
+{
+ const char *tempdir;
+ char *template;
+ int fd;
+
+ tempdir = getenv ("GFORTRAN_TMPDIR");
+ if (tempdir == NULL)
+ tempdir = getenv ("TMP");
+ if (tempdir == NULL)
+ tempdir = DEFAULT_TEMPDIR;
+
+ template = get_mem (strlen (tempdir) + 20);
+
+ st_sprintf (template, "%s/gfortantmpXXXXXX", tempdir);
+
+ fd = mkstemp (template);
+
+ if (fd < 0)
+ free_mem (template);
+ else
+ {
+ ioparm.file = template;
+ ioparm.file_len = strlen (template); /* Don't include trailing nul */
+ }
+
+ return fd;
+}
+
+
+/* regular_file()-- Open a regular file. Returns the descriptor, which is less than zero on error. */
+
+static int
+regular_file (unit_action action, unit_status status)
+{
+ char path[PATH_MAX + 1];
+ struct stat statbuf;
+ int mode;
+
+ if (unpack_filename (path, ioparm.file, ioparm.file_len))
+ {
+ errno = ENOENT; /* Fake an OS error */
+ return -1;
+ }
+
+ mode = 0;
+
+ switch (action)
+ {
+ case ACTION_READ:
+ mode = O_RDONLY;
+ break;
+
+ case ACTION_WRITE:
+ mode = O_WRONLY;
+ break;
+
+ case ACTION_READWRITE:
+ mode = O_RDWR;
+ break;
+
+ default:
+ internal_error ("regular_file(): Bad action");
+ }
+
+ switch (status)
+ {
+ case STATUS_NEW:
+ mode |= O_CREAT | O_EXCL;
+ break;
+
+ case STATUS_OLD: /* file must exist, so check for its existence */
+ if (stat (path, &statbuf) < 0)
+ return -1;
+ break;
+
+ case STATUS_UNKNOWN:
+ case STATUS_SCRATCH:
+ mode |= O_CREAT;
+ break;
+
+ case STATUS_REPLACE:
+ mode |= O_TRUNC;
+ break;
+
+ default:
+ internal_error ("regular_file(): Bad status");
+ }
+
+ // mode |= O_LARGEFILE;
+
+ return open (path, mode,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+}
+
+
+/* open_external()-- Open an external file, unix specific version.
+ * Returns NULL on operating system error. */
+
+stream *
+open_external (unit_action action, unit_status status)
+{
+ int fd, prot;
+
+ fd =
+ (status == STATUS_SCRATCH) ? tempfile () : regular_file (action, status);
+
+ if (fd < 0)
+ return NULL;
+ fd = fix_fd (fd);
+
+ switch (action)
+ {
+ case ACTION_READ:
+ prot = PROT_READ;
+ break;
+
+ case ACTION_WRITE:
+ prot = PROT_WRITE;
+ break;
+
+ case ACTION_READWRITE:
+ prot = PROT_READ | PROT_WRITE;
+ break;
+
+ default:
+ internal_error ("open_external(): Bad action");
+ }
+
+ /* If this is a scratch file, we can unlink it now and the file will
+ * go away when it is closed. */
+
+ if (status == STATUS_SCRATCH)
+ unlink (ioparm.file);
+
+ return fd_to_stream (fd, prot);
+}
+
+
+/* input_stream()-- Return a stream pointer to the default input stream.
+ * Called on initialization. */
+
+stream *
+input_stream (void)
+{
+
+ return fd_to_stream (STDIN_FILENO, PROT_READ);
+}
+
+
+/* output_stream()-- Return a stream pointer to the default input stream.
+ * Called on initialization. */
+
+stream *
+output_stream (void)
+{
+
+ return fd_to_stream (STDOUT_FILENO, PROT_WRITE);
+}
+
+
+/* init_error_stream()-- Return a pointer to the error stream. This
+ * subroutine is called when the stream is needed, rather than at
+ * initialization. We want to work even if memory has been seriously
+ * corrupted. */
+
+stream *
+init_error_stream (void)
+{
+ static unix_stream error;
+
+ memset (&error, '\0', sizeof (error));
+
+ error.fd = options.use_stderr ? STDERR_FILENO : STDOUT_FILENO;
+
+ error.st.alloc_w_at = (void *) fd_alloc_w_at;
+ error.st.sfree = (void *) fd_sfree;
+
+ error.unbuffered = 1;
+ error.buffer = error.small_buffer;
+
+ return (stream *) & error;
+}
+
+
+/* compare_file_filename()-- Given an open stream and a fortran string
+ * that is a filename, figure out if the file is the same as the
+ * filename. */
+
+int
+compare_file_filename (stream * s, const char *name, int len)
+{
+ char path[PATH_MAX + 1];
+ struct stat st1, st2;
+
+ if (unpack_filename (path, name, len))
+ return 0; /* Can't be the same */
+
+ /* If the filename doesn't exist, then there is no match with the
+ * existing file. */
+
+ if (stat (path, &st1) < 0)
+ return 0;
+
+ fstat (((unix_stream *) s)->fd, &st2);
+
+ return (st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino);
+}
+
+
+/* find_file0()-- Recursive work function for find_file() */
+
+static unit_t *
+find_file0 (unit_t * u, struct stat *st1)
+{
+ struct stat st2;
+ unit_t *v;
+
+ if (u == NULL)
+ return NULL;
+
+ if (fstat (((unix_stream *) u->s)->fd, &st2) >= 0 &&
+ st1->st_dev == st2.st_dev && st1->st_ino == st2.st_ino)
+ return u;
+
+ v = find_file0 (u->left, st1);
+ if (v != NULL)
+ return v;
+
+ v = find_file0 (u->right, st1);
+ if (v != NULL)
+ return v;
+
+ return NULL;
+}
+
+
+/* find_file()-- Take the current filename and see if there is a unit
+ * that has the file already open. Returns a pointer to the unit if so. */
+
+unit_t *
+find_file (void)
+{
+ char path[PATH_MAX + 1];
+ struct stat statbuf;
+
+ if (unpack_filename (path, ioparm.file, ioparm.file_len))
+ return NULL;
+
+ if (stat (path, &statbuf) < 0)
+ return NULL;
+
+ return find_file0 (g.unit_root, &statbuf);
+}
+
+
+/* stream_at_bof()-- Returns nonzero if the stream is at the beginning
+ * of the file. */
+
+int
+stream_at_bof (stream * s)
+{
+ unix_stream *us;
+
+ us = (unix_stream *) s;
+
+ if (!us->mmaped)
+ return 0; /* File is not seekable */
+
+ return us->logical_offset == 0;
+}
+
+
+/* stream_at_eof()-- Returns nonzero if the stream is at the beginning
+ * of the file. */
+
+int
+stream_at_eof (stream * s)
+{
+ unix_stream *us;
+
+ us = (unix_stream *) s;
+
+ if (!us->mmaped)
+ return 0; /* File is not seekable */
+
+ return us->logical_offset == us->dirty_offset;
+}
+
+
+/* delete_file()-- Given a unit structure, delete the file associated
+ * with the unit. Returns nonzero if something went wrong. */
+
+int
+delete_file (unit_t * u)
+{
+ char path[PATH_MAX + 1];
+
+ if (unpack_filename (path, u->file, u->file_len))
+ { /* Shouldn't be possible */
+ errno = ENOENT;
+ return 1;
+ }
+
+ return unlink (path);
+}
+
+
+/* file_exists()-- Returns nonzero if the current filename exists on
+ * the system */
+
+int
+file_exists (void)
+{
+ char path[PATH_MAX + 1];
+ struct stat statbuf;
+
+ if (unpack_filename (path, ioparm.file, ioparm.file_len))
+ return 0;
+
+ if (stat (path, &statbuf) < 0)
+ return 0;
+
+ return 1;
+}
+
+
+
+static const char *yes = "YES", *no = "NO", *unknown = "UNKNOWN";
+
+/* inquire_sequential()-- Given a fortran string, determine if the
+ * file is suitable for sequential access. Returns a C-style
+ * string. */
+
+const char *
+inquire_sequential (const char *string, int len)
+{
+ char path[PATH_MAX + 1];
+ struct stat statbuf;
+
+ if (string == NULL ||
+ unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
+ return unknown;
+
+ if (S_ISREG (statbuf.st_mode) ||
+ S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
+ return yes;
+
+ if (S_ISDIR (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
+ return no;
+
+ return unknown;
+}
+
+
+/* inquire_direct()-- Given a fortran string, determine if the file is
+ * suitable for direct access. Returns a C-style string. */
+
+const char *
+inquire_direct (const char *string, int len)
+{
+ char path[PATH_MAX + 1];
+ struct stat statbuf;
+
+ if (string == NULL ||
+ unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
+ return unknown;
+
+ if (S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
+ return yes;
+
+ if (S_ISDIR (statbuf.st_mode) ||
+ S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
+ return no;
+
+ return unknown;
+}
+
+
+/* inquire_formatted()-- Given a fortran string, determine if the file
+ * is suitable for formatted form. Returns a C-style string. */
+
+const char *
+inquire_formatted (const char *string, int len)
+{
+ char path[PATH_MAX + 1];
+ struct stat statbuf;
+
+ if (string == NULL ||
+ unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
+ return unknown;
+
+ if (S_ISREG (statbuf.st_mode) ||
+ S_ISBLK (statbuf.st_mode) ||
+ S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
+ return yes;
+
+ if (S_ISDIR (statbuf.st_mode))
+ return no;
+
+ return unknown;
+}
+
+
+/* inquire_unformatted()-- Given a fortran string, determine if the file
+ * is suitable for unformatted form. Returns a C-style string. */
+
+const char *
+inquire_unformatted (const char *string, int len)
+{
+
+ return inquire_formatted (string, len);
+}
+
+
+/* inquire_access()-- Given a fortran string, determine if the file is
+ * suitable for access. */
+
+static const char *
+inquire_access (const char *string, int len, int mode)
+{
+ char path[PATH_MAX + 1];
+
+ if (string == NULL || unpack_filename (path, string, len) ||
+ access (path, mode) < 0)
+ return no;
+
+ return yes;
+}
+
+
+/* inquire_read()-- Given a fortran string, determine if the file is
+ * suitable for READ access. */
+
+const char *
+inquire_read (const char *string, int len)
+{
+
+ return inquire_access (string, len, R_OK);
+}
+
+
+/* inquire_write()-- Given a fortran string, determine if the file is
+ * suitable for READ access. */
+
+const char *
+inquire_write (const char *string, int len)
+{
+
+ return inquire_access (string, len, W_OK);
+}
+
+
+/* inquire_readwrite()-- Given a fortran string, determine if the file is
+ * suitable for read and write access. */
+
+const char *
+inquire_readwrite (const char *string, int len)
+{
+
+ return inquire_access (string, len, R_OK | W_OK);
+}
+
+
+/* file_length()-- Return the file length in bytes, -1 if unknown */
+
+offset_t
+file_length (stream * s)
+{
+
+ return ((unix_stream *) s)->file_length;
+}
+
+
+/* file_position()-- Return the current position of the file */
+
+offset_t
+file_position (stream * s)
+{
+
+ return ((unix_stream *) s)->logical_offset;
+}
+
+
+/* is_seekable()-- Return nonzero if the stream is seekable, zero if
+ * it is not */
+
+int
+is_seekable (stream * s)
+{
+
+ return ((unix_stream *) s)->mmaped;
+}
+
+
+/* How files are stored: This is an operating-system specific issue,
+ and therefore belongs here. There are three cases to consider.
+
+ Direct Access:
+ Records are written as block of bytes corresponding to the record
+ length of the file. This goes for both formatted and unformatted
+ records. Positioning is done explicitly for each data transfer,
+ so positioning is not much of an issue.
+
+ Sequential Formatted:
+ Records are separated by newline characters. The newline character
+ is prohibited from appearing in a string. If it does, this will be
+ messed up on the next read. End of file is also the end of a record.
+
+ Sequential Unformatted:
+ In this case, we are merely copying bytes to and from main storage,
+ yet we need to keep track of varying record lengths. We adopt
+ the solution used by f2c. Each record contains a pair of length
+ markers:
+
+ Length of record n in bytes
+ Data of record n
+ Length of record n in bytes
+
+ Length of record n+1 in bytes
+ Data of record n+1
+ Length of record n+1 in bytes
+
+ The length is stored at the end of a record to allow backspacing to the
+ previous record. Between data transfer statements, the file pointer
+ is left pointing to the first length of the current record.
+
+ ENDFILE records are never explicitly stored.
+
+*/
diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c
new file mode 100644
index 00000000000..dd44f6e5f72
--- /dev/null
+++ b/libgfortran/io/write.c
@@ -0,0 +1,1129 @@
+/* Copyright (C) 2002-2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran 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 2, or (at your option)
+any later version.
+
+Libgfortran 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 Libgfortran; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <string.h>
+#include <float.h>
+#include "libgfortran.h"
+#include "io.h"
+#include <stdio.h>
+
+
+#define star_fill(p, n) memset(p, '*', n)
+
+
+typedef enum
+{ SIGN_NONE, SIGN_MINUS, SIGN_PLUS }
+sign_t;
+
+
+void
+write_a (fnode * f, const char *source, int len)
+{
+ int wlen;
+ char *p;
+
+ wlen = f->u.string.length < 0 ? len : f->u.string.length;
+
+ p = write_block (wlen);
+ if (p == NULL)
+ return;
+
+ if (wlen < len)
+ memcpy (p, source, wlen);
+ else
+ {
+ memcpy (p, source, len);
+ memset (p + len, ' ', wlen - len);
+ }
+}
+
+static int64_t
+extract_int (const void *p, int len)
+{
+ int64_t i = 0;
+
+ if (p == NULL)
+ return i;
+
+ switch (len)
+ {
+ case 1:
+ i = *((const int8_t *) p);
+ break;
+ case 2:
+ i = *((const int16_t *) p);
+ break;
+ case 4:
+ i = *((const int32_t *) p);
+ break;
+ case 8:
+ i = *((const int64_t *) p);
+ break;
+ default:
+ internal_error ("bad integer kind");
+ }
+
+ return i;
+}
+
+static double
+extract_real (const void *p, int len)
+{
+ double i = 0.0;
+ switch (len)
+ {
+ case 4:
+ i = *((const float *) p);
+ break;
+ case 8:
+ i = *((const double *) p);
+ break;
+ default:
+ internal_error ("bad real kind");
+ }
+ return i;
+
+}
+
+
+/* calculate sign()-- Given a flag that indicate if a value is
+ * negative or not, return a sign_t that gives the sign that we need
+ * to produce. */
+
+static sign_t
+calculate_sign (int negative_flag)
+{
+ sign_t s = SIGN_NONE;
+
+ if (negative_flag)
+ s = SIGN_MINUS;
+ else
+ switch (g.sign_status)
+ {
+ case SIGN_SP:
+ s = SIGN_PLUS;
+ break;
+ case SIGN_SS:
+ s = SIGN_NONE;
+ break;
+ case SIGN_S:
+ s = options.optional_plus ? SIGN_PLUS : SIGN_NONE;
+ break;
+ }
+
+ return s;
+}
+
+
+/* calculate_exp()-- returns the value of 10**d. */
+
+static double
+calculate_exp (int d)
+{
+ int i;
+ double r = 1.0;
+
+ for (i = 0; i< (d >= 0 ? d : -d); i++)
+ r *= 10;
+
+ r = (d >= 0) ? r : 1.0 / r;
+
+ return r;
+}
+
+
+/* calculate_G_format()-- geneate corresponding I/O format for
+ FMT_G output.
+ The rules to translate FMT_G to FMT_E or FNT_F from DEC fortran
+ LRM (table 11-2, Chapter 11, "I/O Formatting", P11-25) is:
+
+ Data Magnitude Equivalent Conversion
+ 0< m < 0.1-0.5*10**(-d-1) Ew.d[Ee]
+ m = 0 F(w-n).(d-1), n' '
+ 0.1-0.5*10**(-d-1)<= m < 1-0.5*10**(-d) F(w-n).d, n' '
+ 1-0.5*10**(-d)<= m < 10-0.5*10**(-d+1) F(w-n).(d-1), n' '
+ 10-0.5*10**(-d+1)<= m < 100-0.5*10**(-d+2) F(w-n).(d-2), n' '
+ ................ ..........
+ 10**(d-1)-0.5*10**(-1)<= m <10**d-0.5 F(w-n).0,n(' ')
+ m >= 10**d-0.5 Ew.d[Ee]
+
+ notes: for Gw.d , n' ' means 4 blanks
+ for Gw.dEe, n' ' means e+2 blanks */
+
+static fnode *
+calculate_G_format (fnode *f, double value, int len, int *num_blank)
+{
+ int e = f->u.real.e;
+ int d = f->u.real.d;
+ int w = f->u.real.w;
+ fnode *newf;
+ double m, exp_d;
+ int low, high, mid;
+ int ubound, lbound;
+
+ newf = get_mem (sizeof (fnode));
+
+ /* Absolute value. */
+ m = (value > 0.0) ? value : -value;
+
+ /* In case of the two data magnitude ranges,
+ generate E editing, Ew.d[Ee]. */
+ exp_d = calculate_exp (d);
+ if ((m > 0.0 && m < 0.1 - 0.05 / (double) exp_d)
+ || (m >= (double) exp_d - 0.5 ))
+ {
+ newf->format = FMT_E;
+ newf->u.real.w = w;
+ newf->u.real.d = d;
+ newf->u.real.e = e;
+ *num_blank = e + 2;
+ return newf;
+ }
+
+ /* Use binary search to find the data magnitude range. */
+ mid = 0;
+ low = 0;
+ high = d + 1;
+ lbound = 0;
+ ubound = d + 1;
+
+ while (low <= high)
+ {
+ double temp;
+ mid = (low + high) / 2;
+
+ /* 0.1 * 10**mid - 0.5 * 10**(mid-d-1) */
+ temp = 0.1 * calculate_exp (mid) - 0.5 * calculate_exp (mid - d - 1);
+
+ if (m < temp)
+ {
+ ubound = mid;
+ if (ubound == lbound + 1)
+ break;
+ high = mid - 1;
+ }
+ else if (m > temp)
+ {
+ lbound = mid;
+ if (ubound == lbound + 1)
+ {
+ mid ++;
+ break;
+ }
+ low = mid + 1;
+ }
+ else
+ break;
+ }
+
+ /* Generate the F editing. F(w-4).(-(mid-d-1)), 4' '. */
+ newf->format = FMT_F;
+ newf->u.real.w = f->u.real.w - 4;
+
+ /* Special case. */
+ if (m == 0.0)
+ newf->u.real.d = d - 1;
+ else
+ newf->u.real.d = - (mid - d - 1);
+
+ *num_blank = 4;
+
+ /* For F editing, the scale factor is ignored. */
+ g.scale_factor = 0;
+ return newf;
+}
+
+
+/* output_float() -- output a real number according to its format
+ which is FMT_G free */
+
+static void
+output_float (fnode *f, double value, int len)
+{
+ int w, d, e, e_new;
+ int digits;
+ int nsign, nblank, nesign;
+ int sca, neval, itmp;
+ char *p;
+ const char *q, *intstr, *base;
+ double n;
+ format_token ft;
+ char exp_char = 'E';
+ int with_exp = 1;
+ int scale_flag = 1 ;
+ double minv = 0.0, maxv = 0.0;
+ sign_t sign = SIGN_NONE, esign = SIGN_NONE;
+
+ int intval = 0, intlen = 0;
+ int j;
+
+ /* EXP value for this number */
+ neval = 0;
+
+ /* Width of EXP and it's sign*/
+ nesign = 0;
+
+ ft = f->format;
+ w = f->u.real.w;
+ d = f->u.real.d + 1;
+
+ /* Width of the EXP */
+ e = 0;
+
+ sca = g.scale_factor;
+ n = value;
+
+ sign = calculate_sign (n < 0.0);
+ if (n < 0)
+ n = -n;
+
+ /* Width of the sign for the whole number */
+ nsign = (sign == SIGN_NONE ? 0 : 1);
+
+ digits = 0;
+ if (ft != FMT_F)
+ {
+ e = f->u.real.e;
+ }
+ if (ft == FMT_F || ft == FMT_E || ft == FMT_D)
+ {
+ if (ft == FMT_F)
+ scale_flag = 0;
+ if (ft == FMT_D)
+ exp_char = 'D' ;
+ minv = 0.1;
+ maxv = 1.0;
+
+ /* Here calculate the new val of the number with consideration
+ of Globle Scale value */
+ while (sca > 0)
+ {
+ minv *= 10.0;
+ maxv *= 10.0;
+ n *= 10.0;
+ sca -- ;
+ neval --;
+ }
+
+ /* Now calculate the new Exp value for this number */
+ sca = g.scale_factor;
+ while(sca >= 1)
+ {
+ sca /= 10;
+ digits ++ ;
+ }
+ }
+
+ if (ft == FMT_EN )
+ {
+ minv = 1.0;
+ maxv = 1000.0;
+ }
+ if (ft == FMT_ES)
+ {
+ minv = 1.0;
+ maxv = 10.0;
+ }
+
+ /* OK, let's scale the number to appropriate range */
+ while (scale_flag && n > 0.0 && n < minv)
+ {
+ if (n < minv)
+ {
+ n = n * 10.0 ;
+ neval --;
+ }
+ }
+ while (scale_flag && n > 0.0 && n > maxv)
+ {
+ if (n > maxv)
+ {
+ n = n / 10.0 ;
+ neval ++;
+ }
+ }
+
+ /* It is time to process the EXP part of the number.
+ Value of 'nesign' is 0 unless following codes is executed.
+ */
+ if (ft != FMT_F)
+ {
+ /* Sign of the EXP value */
+ if (neval >= 0)
+ esign = SIGN_PLUS;
+ else
+ {
+ esign = SIGN_MINUS;
+ neval = - neval ;
+ }
+
+ /* Width of the EXP*/
+ e_new = 0;
+ j = neval;
+ while (j > 0)
+ {
+ j = j / 10;
+ e_new ++ ;
+ }
+ if (e <= e_new)
+ e = e_new;
+
+ /* Got the width of EXP */
+ if (e < digits)
+ e = digits ;
+
+ /* Minimum value of the width would be 2 */
+ if (e < 2)
+ e = 2;
+
+ nesign = 1 ; /* We must give a position for the 'exp_char' */
+ if (e > 0)
+ nesign = e + nesign + (esign != SIGN_NONE ? 1 : 0);
+ }
+
+
+ intval = n;
+ intstr = itoa (intval);
+ intlen = strlen (intstr);
+
+ q = rtoa (n, len, d);
+ digits = strlen (q);
+
+ /* Select a width if none was specified. */
+ if (w <= 0)
+ w = digits + nsign;
+
+ p = write_block (w);
+ if (p == NULL)
+ return;
+
+ base = p;
+
+ nblank = w - (nsign + intlen + d + nesign);
+ if (nblank == -1 && ft != FMT_F)
+ {
+ with_exp = 0;
+ nesign -= 1;
+ nblank = w - (nsign + intlen + d + nesign);
+ }
+ /* don't let a leading '0' cause field overflow */
+ if (nblank == -1 && ft == FMT_F && q[0] == '0')
+ {
+ q++;
+ nblank = 0;
+ }
+
+ if (nblank < 0)
+ {
+ star_fill (p, w);
+ goto done;
+ }
+ memset (p, ' ', nblank);
+ p += nblank;
+
+ switch (sign)
+ {
+ case SIGN_PLUS:
+ *p++ = '+';
+ break;
+ case SIGN_MINUS:
+ *p++ = '-';
+ break;
+ case SIGN_NONE:
+ break;
+ }
+
+ memcpy (p, q, intlen + d + 1);
+ p += intlen + d;
+
+ if (nesign > 0)
+ {
+ if (with_exp)
+ *p++ = exp_char;
+ switch (esign)
+ {
+ case SIGN_PLUS:
+ *p++ = '+';
+ break;
+ case SIGN_MINUS:
+ *p++ = '-';
+ break;
+ case SIGN_NONE:
+ break;
+ }
+ q = itoa (neval);
+ digits = strlen (q);
+
+ for (itmp = 0; itmp < e - digits; itmp++)
+ *p++ = '0';
+ memcpy (p, q, digits);
+ p[digits] = 0;
+ }
+
+done:
+ return ;
+}
+
+void
+write_l (fnode * f, char *source, int len)
+{
+ char *p;
+ int64_t n;
+
+ p = write_block (f->u.w);
+ if (p == NULL)
+ return;
+
+ memset (p, ' ', f->u.w - 1);
+ n = extract_int (source, len);
+ p[f->u.w - 1] = (n) ? 'T' : 'F';
+}
+
+/* write_float() -- output a real number according to its format */
+
+static void
+write_float (fnode *f, const char *source, int len)
+{
+ double n;
+ int nb =0, res;
+ char * p, fin;
+ fnode *f2 = NULL;
+
+ n = extract_real (source, len);
+
+ if (f->format != FMT_B && f->format != FMT_O && f->format != FMT_Z)
+ {
+ res = finite (n);
+ if (res == 0)
+ {
+ nb = f->u.real.w;
+ if (nb <= 4)
+ nb = 4;
+ p = write_block (nb);
+ memset (p, ' ' , 1);
+
+ res = isinf (n);
+ if (res != 0)
+ {
+ if (res > 0)
+ fin = '+';
+ else
+ fin = '-';
+
+ memset (p + 1, fin, nb - 1);
+ }
+ else
+ sprintf(p + 1, "NaN");
+ return;
+ }
+ }
+
+ if (f->format != FMT_G)
+ {
+ output_float (f, n, len);
+ }
+ else
+ {
+ f2 = calculate_G_format(f, n, len, &nb);
+ output_float (f2, n, len);
+ if (f2 != NULL)
+ free_mem(f2);
+
+ if (nb > 0)
+ {
+ p = write_block (nb);
+ memset (p, ' ', nb);
+ }
+ }
+}
+
+
+static void
+write_int (fnode *f, const char *source, int len, char *(*conv) (uint64_t))
+{
+ uint32_t ns =0;
+ uint64_t n = 0;
+ int w, m, digits, nzero, nblank;
+ char *p, *q;
+
+ w = f->u.integer.w;
+ m = f->u.integer.m;
+
+ n = extract_int (source, len);
+
+ /* Special case */
+
+ if (m == 0 && n == 0)
+ {
+ if (w == 0)
+ w = 1;
+
+ p = write_block (w);
+ if (p == NULL)
+ return;
+
+ memset (p, ' ', w);
+ goto done;
+ }
+
+
+ if (len < 8)
+ {
+ ns = n;
+ q = conv (ns);
+ }
+ else
+ q = conv (n);
+
+ digits = strlen (q);
+
+ /* Select a width if none was specified. The idea here is to always
+ * print something. */
+
+ if (w == 0)
+ w = ((digits < m) ? m : digits);
+
+ p = write_block (w);
+ if (p == NULL)
+ return;
+
+ nzero = 0;
+ if (digits < m)
+ nzero = m - digits;
+
+ /* See if things will work */
+
+ nblank = w - (nzero + digits);
+
+ if (nblank < 0)
+ {
+ star_fill (p, w);
+ goto done;
+ }
+
+ memset (p, ' ', nblank);
+ p += nblank;
+
+ memset (p, '0', nzero);
+ p += nzero;
+
+ memcpy (p, q, digits);
+
+done:
+ return;
+}
+
+static void
+write_decimal (fnode *f, const char *source, int len, char *(*conv) (int64_t))
+{
+ int64_t n = 0;
+ int w, m, digits, nsign, nzero, nblank;
+ char *p, *q;
+ sign_t sign;
+
+ w = f->u.integer.w;
+ m = f->u.integer.m;
+
+ n = extract_int (source, len);
+
+ /* Special case */
+
+ if (m == 0 && n == 0)
+ {
+ if (w == 0)
+ w = 1;
+
+ p = write_block (w);
+ if (p == NULL)
+ return;
+
+ memset (p, ' ', w);
+ goto done;
+ }
+
+ sign = calculate_sign (n < 0);
+ if (n < 0)
+ n = -n;
+
+ nsign = sign == SIGN_NONE ? 0 : 1;
+ q = conv (n);
+
+ digits = strlen (q);
+
+ /* Select a width if none was specified. The idea here is to always
+ * print something. */
+
+ if (w == 0)
+ w = ((digits < m) ? m : digits) + nsign;
+
+ p = write_block (w);
+ if (p == NULL)
+ return;
+
+ nzero = 0;
+ if (digits < m)
+ nzero = m - digits;
+
+ /* See if things will work */
+
+ nblank = w - (nsign + nzero + digits);
+
+ if (nblank < 0)
+ {
+ star_fill (p, w);
+ goto done;
+ }
+
+ memset (p, ' ', nblank);
+ p += nblank;
+
+ switch (sign)
+ {
+ case SIGN_PLUS:
+ *p++ = '+';
+ break;
+ case SIGN_MINUS:
+ *p++ = '-';
+ break;
+ case SIGN_NONE:
+ break;
+ }
+
+ memset (p, '0', nzero);
+ p += nzero;
+
+ memcpy (p, q, digits);
+
+done:
+ return;
+}
+
+
+/* otoa()-- Convert unsigned octal to ascii */
+
+static char *
+otoa (uint64_t n)
+{
+ char *p;
+
+ if (n == 0)
+ {
+ scratch[0] = '0';
+ scratch[1] = '\0';
+ return scratch;
+ }
+
+ p = scratch + sizeof (SCRATCH_SIZE) - 1;
+ *p-- = '\0';
+
+ while (n != 0)
+ {
+ *p = '0' + (n & 7);
+ p -- ;
+ n >>= 3;
+ }
+
+ return ++p;
+}
+
+
+/* btoa()-- Convert unsigned binary to ascii */
+
+static char *
+btoa (uint64_t n)
+{
+ char *p;
+
+ if (n == 0)
+ {
+ scratch[0] = '0';
+ scratch[1] = '\0';
+ return scratch;
+ }
+
+ p = scratch + sizeof (SCRATCH_SIZE) - 1;
+ *p-- = '\0';
+
+ while (n != 0)
+ {
+ *p-- = '0' + (n & 1);
+ n >>= 1;
+ }
+
+ return ++p;
+}
+
+
+void
+write_i (fnode * f, const char *p, int len)
+{
+
+ write_decimal (f, p, len, (void *) itoa);
+}
+
+
+void
+write_b (fnode * f, const char *p, int len)
+{
+
+ write_int (f, p, len, btoa);
+}
+
+
+void
+write_o (fnode * f, const char *p, int len)
+{
+
+ write_int (f, p, len, otoa);
+}
+
+void
+write_z (fnode * f, const char *p, int len)
+{
+
+ write_int (f, p, len, xtoa);
+}
+
+
+void
+write_d (fnode *f, const char *p, int len)
+{
+ write_float (f, p, len);
+}
+
+
+void
+write_e (fnode *f, const char *p, int len)
+{
+ write_float (f, p, len);
+}
+
+
+void
+write_f (fnode *f, const char *p, int len)
+{
+ write_float (f, p, len);
+}
+
+
+void
+write_en (fnode *f, const char *p, int len)
+{
+ write_float (f, p, len);
+}
+
+
+void
+write_es (fnode *f, const char *p, int len)
+{
+ write_float (f, p, len);
+}
+
+
+/* write_x()-- Take care of the X/TR descriptor */
+
+void
+write_x (fnode * f)
+{
+ char *p;
+
+ p = write_block (f->u.n);
+ if (p == NULL)
+ return;
+
+ memset (p, ' ', f->u.n);
+}
+
+
+/* List-directed writing */
+
+
+/* write_char()-- Write a single character to the output. Returns
+ * nonzero if something goes wrong. */
+
+static int
+write_char (char c)
+{
+ char *p;
+
+ p = write_block (1);
+ if (p == NULL)
+ return 1;
+
+ *p = c;
+
+ return 0;
+}
+
+
+/* write_logical()-- Write a list-directed logical value */
+/* Default logical output should be L2
+ according to DEC fortran Manual. */
+static void
+write_logical (const char *source, int length)
+{
+ write_char (' ');
+ write_char (extract_int (source, length) ? 'T' : 'F');
+}
+
+
+/* write_integer()-- Write a list-directed integer value. */
+
+static void
+write_integer (const char *source, int length)
+{
+ char *p;
+ const char *q;
+ int digits;
+ int width = 12;
+
+ q = itoa (extract_int (source, length));
+
+ digits = strlen (q);
+
+ if(width < digits )
+ width = digits ;
+ p = write_block (width) ;
+
+ memset(p ,' ', width - digits) ;
+ memcpy (p + width - digits, q, digits);
+}
+
+
+/* write_character()-- Write a list-directed string. We have to worry
+ * about delimiting the strings if the file has been opened in that
+ * mode. */
+
+static void
+write_character (const char *source, int length)
+{
+ int i, extra;
+ char *p, d;
+
+ switch (current_unit->flags.delim)
+ {
+ case DELIM_APOSTROPHE:
+ d = '\'';
+ break;
+ case DELIM_QUOTE:
+ d = '"';
+ break;
+ default:
+ d = ' ';
+ break;
+ }
+
+ if (d == ' ')
+ extra = 0;
+ else
+ {
+ extra = 2;
+
+ for (i = 0; i < length; i++)
+ if (source[i] == d)
+ extra++;
+ }
+
+ p = write_block (length + extra);
+ if (p == NULL)
+ return;
+
+ if (d == ' ')
+ memcpy (p, source, length);
+ else
+ {
+ *p++ = d;
+
+ for (i = 0; i < length; i++)
+ {
+ *p++ = source[i];
+ if (source[i] == d)
+ *p++ = d;
+ }
+
+ *p = d;
+ }
+}
+
+
+/* Output the Real number with default format.
+ According to DEC fortran LRM, default format for
+ REAL(4) is 1PG15.7E2, and for REAL(8) is 1PG25.15E3 */
+
+static void
+write_real (const char *source, int length)
+{
+ fnode f ;
+ int org_scale = g.scale_factor;
+ f.format = FMT_G;
+ g.scale_factor = 1;
+ if (length < 8)
+ {
+ f.u.real.w = 15;
+ f.u.real.d = 7;
+ f.u.real.e = 2;
+ }
+ else
+ {
+ f.u.real.w = 24;
+ f.u.real.d = 15;
+ f.u.real.e = 3;
+ }
+ write_float (&f, source , length);
+ g.scale_factor = org_scale;
+}
+
+
+static void
+write_complex (const char *source, int len)
+{
+
+ if (write_char ('('))
+ return;
+ write_real (source, len);
+
+ if (write_char (','))
+ return;
+ write_real (source + len, len);
+
+ write_char (')');
+}
+
+
+/* write_separator()-- Write the separator between items. */
+
+static void
+write_separator (void)
+{
+ char *p;
+
+ p = write_block (options.separator_len);
+ if (p == NULL)
+ return;
+
+ memcpy (p, options.separator, options.separator_len);
+}
+
+
+/* list_formatted_write()-- Write an item with list formatting.
+ * TODO: handle skipping to the next record correctly, particularly
+ * with strings. */
+
+void
+list_formatted_write (bt type, void *p, int len)
+{
+ static int char_flag;
+
+ if (current_unit == NULL)
+ return;
+
+ if (g.first_item)
+ {
+ g.first_item = 0;
+ char_flag = 0;
+ }
+ else
+ {
+ if (type != BT_CHARACTER || !char_flag ||
+ current_unit->flags.delim != DELIM_NONE)
+ write_separator ();
+ }
+
+ switch (type)
+ {
+ case BT_INTEGER:
+ write_integer (p, len);
+ break;
+ case BT_LOGICAL:
+ write_logical (p, len);
+ break;
+ case BT_CHARACTER:
+ write_character (p, len);
+ break;
+ case BT_REAL:
+ write_real (p, len);
+ break;
+ case BT_COMPLEX:
+ write_complex (p, len);
+ break;
+ default:
+ internal_error ("list_formatted_write(): Bad type");
+ }
+
+ char_flag = (type == BT_CHARACTER);
+}
+
+void
+namelist_write (void)
+{
+ namelist_info * t1, *t2;
+ int len,num;
+ void * p;
+
+ num = 0;
+ write_character("&",1);
+ write_character (ioparm.namelist_name, ioparm.namelist_name_len);
+ write_character("\n",1);
+
+ if (ionml != NULL)
+ {
+ t1 = ionml;
+ while (t1 != NULL)
+ {
+ num ++;
+ t2 = t1;
+ t1 = t1->next;
+ write_character(t2->var_name, strlen(t2->var_name));
+ write_character("=",1);
+ len = t2->len;
+ p = t2->mem_pos;
+ switch (t2->type)
+ {
+ case BT_INTEGER:
+ write_integer (p, len);
+ break;
+ case BT_LOGICAL:
+ write_logical (p, len);
+ break;
+ case BT_CHARACTER:
+ write_character (p, len);
+ break;
+ case BT_REAL:
+ write_real (p, len);
+ break;
+ case BT_COMPLEX:
+ write_complex (p, len);
+ break;
+ default:
+ internal_error ("Bad type for namelist write");
+ }
+ write_character(",",1);
+ if (num > 5)
+ {
+ num = 0;
+ write_character("\n",1);
+ }
+ }
+ }
+ write_character("/",1);
+
+}
+
diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h
new file mode 100644
index 00000000000..112fd075dcf
--- /dev/null
+++ b/libgfortran/libgfortran.h
@@ -0,0 +1,406 @@
+/* Common declarations for all of libgfor.
+ Copyright 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>, and
+ Andy Vaught <andy@xena.eas.asu.edu>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+#ifndef LIBGFOR_H
+#define LIBGFOR_H
+
+#include <math.h>
+#include <stddef.h>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846264338327
+#endif
+
+#include "config.h"
+
+#if HAVE_COMPLEX_H
+# include <complex.h>
+#else
+#define complex __complex__
+#endif
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+typedef off_t offset_t;
+
+#ifndef NULL
+#define NULL (void *) 0
+#endif
+
+#ifndef __GNUC__
+#define __attribute__(x)
+#endif
+
+/* For a library, a standard prefix is a requirement in order to
+ partition the namespace. It's ugly to look at and a pain to type,
+ so we hide it behind macros. */
+#define prefix(x) _gfortran_ ## x
+
+/* The only reliable way to get the offset of a field in a struct
+ in a system independent way is via this macro. */
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) 0)->MEMBER)
+#endif
+
+/* TODO: find the C99 version of these an move into above ifdef. */
+#define REALPART(z) (__real__(z))
+#define IMAGPART(z) (__imag__(z))
+#define COMPLEX_ASSIGN(z_, r_, i_) {__real__(z_) = (r_); __imag__(z_) = (i_);}
+
+typedef int32_t GFC_INTEGER_4;
+typedef int64_t GFC_INTEGER_8;
+typedef uint32_t GFC_UINTEGER_4;
+typedef uint64_t GFC_UINTEGER_8;
+typedef GFC_INTEGER_4 GFC_LOGICAL_4;
+typedef GFC_INTEGER_8 GFC_LOGICAL_8;
+typedef float GFC_REAL_4;
+typedef double GFC_REAL_8;
+typedef complex float GFC_COMPLEX_4;
+typedef complex double GFC_COMPLEX_8;
+
+typedef size_t index_type;
+
+/* This will be 0 on little-endian machines and one on big-endian machines. */
+#define l8_to_l4_offset prefix(l8_to_l4_offset)
+extern int l8_to_l4_offset;
+
+#define GFOR_POINTER_L8_TO_L4(p8) \
+ (l8_to_l4_offset + (GFC_LOGICAL_4 *)(p8))
+
+#define GFC_INTEGER_4_HUGE \
+ (GFC_INTEGER_4)((((GFC_UINTEGER_4)1) << 31) - 1)
+#define GFC_INTEGER_8_HUGE \
+ (GFC_INTEGER_8)((((GFC_UINTEGER_8)1) << 63) - 1)
+#define GFC_REAL_4_HUGE FLT_MAX
+#define GFC_REAL_8_HUGE DBL_MAX
+
+#ifndef GFC_MAX_DIMENSIONS
+#define GFC_MAX_DIMENSIONS 7
+#endif
+
+typedef struct descriptor_dimension
+{
+ index_type stride;
+ index_type lbound;
+ index_type ubound;
+}
+descriptor_dimension;
+
+#define GFC_ARRAY_DESCRIPTOR(r, type) \
+struct {\
+ type *data;\
+ type *base;\
+ index_type dtype;\
+ descriptor_dimension dim[r];\
+}
+
+/* Commonly used array descriptor types. */
+typedef GFC_ARRAY_DESCRIPTOR (GFC_MAX_DIMENSIONS, void) gfc_array_void;
+typedef GFC_ARRAY_DESCRIPTOR (GFC_MAX_DIMENSIONS, char) gfc_array_char;
+typedef GFC_ARRAY_DESCRIPTOR (GFC_MAX_DIMENSIONS, GFC_INTEGER_4) gfc_array_i4;
+typedef GFC_ARRAY_DESCRIPTOR (GFC_MAX_DIMENSIONS, GFC_INTEGER_8) gfc_array_i8;
+typedef GFC_ARRAY_DESCRIPTOR (GFC_MAX_DIMENSIONS, GFC_REAL_4) gfc_array_r4;
+typedef GFC_ARRAY_DESCRIPTOR (GFC_MAX_DIMENSIONS, GFC_REAL_8) gfc_array_r8;
+typedef GFC_ARRAY_DESCRIPTOR (GFC_MAX_DIMENSIONS, GFC_COMPLEX_4) gfc_array_c4;
+typedef GFC_ARRAY_DESCRIPTOR (GFC_MAX_DIMENSIONS, GFC_COMPLEX_8) gfc_array_c8;
+typedef GFC_ARRAY_DESCRIPTOR (GFC_MAX_DIMENSIONS, GFC_LOGICAL_4) gfc_array_l4;
+typedef GFC_ARRAY_DESCRIPTOR (GFC_MAX_DIMENSIONS, GFC_LOGICAL_8) gfc_array_l8;
+
+#define GFC_DTYPE_RANK_MASK 0x07
+#define GFC_DTYPE_TYPE_SHIFT 3
+#define GFC_DTYPE_TYPE_MASK 0x38
+#define GFC_DTYPE_SIZE_SHIFT 6
+
+enum
+{
+ GFC_DTYPE_UNKNOWN = 0,
+ GFC_DTYPE_INTEGER,
+ /* TODO: recognize logical types. */
+ GFC_DTYPE_LOGICAL,
+ GFC_DTYPE_REAL,
+ GFC_DTYPE_COMPLEX,
+ GFC_DTYPE_DERIVED,
+ GFC_DTYPE_CHARACTER
+};
+
+#define GFC_DESCRIPTOR_RANK(desc) ((desc)->dtype & GFC_DTYPE_RANK_MASK)
+#define GFC_DESCRIPTOR_TYPE(desc) (((desc)->dtype & GFC_DTYPE_TYPE_MASK) \
+ >> GFC_DTYPE_TYPE_SHIFT)
+#define GFC_DESCRIPTOR_SIZE(desc) ((desc)->dtype >> GFC_DTYPE_SIZE_SHIFT)
+#define GFC_DESCRIPTOR_DATA(desc) ((desc)->data)
+#define GFC_DESCRIPTOR_DTYPE(desc) ((desc)->dtype)
+
+/* Runtime library include. */
+#define stringize(x) expand_macro(x)
+#define expand_macro(x) # x
+
+/* Runtime options structure. */
+
+typedef struct
+{
+ int stdin_unit, stdout_unit, optional_plus;
+ int allocate_init_flag, allocate_init_value;
+ int locus;
+
+ int separator_len;
+ const char *separator;
+
+ int mem_check;
+ int use_stderr, all_unbuffered, default_recl;
+
+ int fpu_round, fpu_precision, fpu_invalid, fpu_denormal, fpu_zerodiv,
+ fpu_overflow, fpu_underflow, fpu_precision_loss;
+
+ int sighup, sigint;
+}
+options_t;
+
+
+#define options prefix(options)
+extern options_t options;
+
+
+/* Structure for statement options. */
+
+typedef struct
+{
+ const char *name;
+ int value;
+}
+st_option;
+
+/* Runtime errors. The EOR and EOF errors are required to be negative. */
+
+typedef enum
+{
+ ERROR_FIRST = -3, /* Marker for the first error. */
+ ERROR_EOR = -2,
+ ERROR_END = -1,
+ ERROR_OK = 0, /* Indicates success, must be zero. */
+ ERROR_OS, /* Operating system error, more info in errno. */
+ ERROR_OPTION_CONFLICT,
+ ERROR_BAD_OPTION,
+ ERROR_MISSING_OPTION,
+ ERROR_ALREADY_OPEN,
+ ERROR_BAD_UNIT,
+ ERROR_FORMAT,
+ ERROR_BAD_ACTION,
+ ERROR_ENDFILE,
+ ERROR_BAD_US,
+ ERROR_READ_VALUE,
+ ERROR_READ_OVERFLOW,
+ ERROR_LAST /* Not a real error, the last error # + 1. */
+}
+error_codes;
+
+
+/* The filename and line number don't go inside the globals structure.
+ They are set by the rest of the program and must be linked to. */
+
+#define line prefix(line)
+extern unsigned line; /* Location of the current libray call (optional). */
+
+#define filename prefix(filename)
+extern char *filename;
+
+
+/* main.c */
+
+#define library_start prefix(library_start)
+void library_start (void);
+
+#define library_end prefix(library_end)
+void library_end (void);
+
+#define set_args prefix(set_args)
+void set_args (int, char **);
+
+#define get_args prefix(get_args)
+void get_args (int *, char ***);
+
+
+/* error.c */
+#define rtoa prefix(rtoa)
+char *rtoa (double f, int length, int oprec);
+
+#define itoa prefix(itoa)
+char *itoa (int64_t);
+
+#define xtoa prefix(xtoa)
+char *xtoa (uint64_t);
+
+#define os_error prefix(os_error)
+void os_error (const char *) __attribute__ ((noreturn));
+
+#define show_locus prefix(show_locus)
+void show_locus (void);
+
+#define runtime_error prefix(runtime_error)
+void runtime_error (const char *) __attribute__ ((noreturn));
+
+#define internal_error prefix(internal_error)
+void internal_error (const char *) __attribute__ ((noreturn));
+
+#define get_oserror prefix(get_oserror)
+const char *get_oserror (void);
+
+#define write_error prefix(write_error)
+void write_error (const char *);
+
+#define sys_exit prefix(sys_exit)
+void sys_exit (int) __attribute__ ((noreturn));
+
+#define st_printf prefix(st_printf)
+int st_printf (const char *, ...) __attribute__ ((format (printf, 1, 2)));
+
+#define st_sprintf prefix(st_sprintf)
+void st_sprintf (char *, const char *, ...) __attribute__ ((format (printf, 2, 3)));
+
+#define translate_error prefix(translate_error)
+const char *translate_error (int);
+
+#define generate_error prefix(generate_error)
+void generate_error (int, const char *);
+
+
+/* memory.c */
+
+#define memory_init prefix(memory_init)
+void memory_init (void);
+
+#define runtime_cleanup prefix(runtime_cleanup)
+void runtime_cleanup (void);
+
+#define get_mem prefix(get_mem)
+void *get_mem (size_t) __attribute__ ((malloc));
+
+#define free_mem prefix(free_mem)
+void free_mem (void *);
+
+#define internal_malloc_size prefix(internal_malloc_size)
+void *internal_malloc_size (size_t);
+
+#define internal_malloc prefix(internal_malloc)
+void *internal_malloc (GFC_INTEGER_4);
+
+#define internal_malloc64 prefix(internal_malloc64)
+void *internal_malloc64 (GFC_INTEGER_8);
+
+#define internal_free prefix(internal_free)
+void internal_free (void *);
+
+#define allocate prefix(allocate)
+void allocate (void **, GFC_INTEGER_4, GFC_INTEGER_4 *);
+
+#define allocate64 prefix(allocate64)
+void allocate64 (void **, GFC_INTEGER_8, GFC_INTEGER_4 *);
+
+#define deallocate prefix(deallocate)
+void deallocate (void **, GFC_INTEGER_4 *);
+
+
+/* environ.c */
+
+#define check_buffered prefix(check_buffered)
+int check_buffered (int);
+
+#define init_variables prefix(init_variables)
+void init_variables (void);
+
+#define show_variables prefix(show_variables)
+void show_variables (void);
+
+
+/* string.c */
+
+#define find_option prefix(find_option)
+int find_option (const char *, int, st_option *, const char *);
+
+#define fstrlen prefix(fstrlen)
+int fstrlen (const char *, int);
+
+#define fstrcpy prefix(fstrcpy)
+void fstrcpy (char *, int, const char *, int);
+
+#define cf_strcpy prefix(cf_strcpy)
+void cf_strcpy (char *, int, const char *);
+
+/* io.c */
+
+#define init_units prefix(init_units)
+void init_units (void);
+
+#define close_units prefix(close_units)
+void close_units (void);
+
+/* stop.c */
+#define stop_numeric prefix(stop_numeric)
+void stop_numeric (GFC_INTEGER_4);
+
+/* reshape_packed.c */
+#define reshape_packed prefix(reshape_packed)
+void reshape_packed (char *, index_type, const char *, index_type,
+ const char *, index_type);
+
+/* Repacking functions. */
+#define internal_pack prefix(internal_pack)
+void *internal_pack (gfc_array_char *);
+
+#define internal_unpack prefix(internal_unpack)
+void internal_unpack (gfc_array_char *, const void *);
+
+#define internal_pack_4 prefix(internal_pack_4)
+GFC_INTEGER_4 *internal_pack_4 (gfc_array_i4 *);
+
+#define internal_pack_8 prefix(internal_pack_8)
+GFC_INTEGER_8 *internal_pack_8 (gfc_array_i8 *);
+
+#define internal_unpack_4 prefix(internal_unpack_4)
+void internal_unpack_4 (gfc_array_i4 *, const GFC_INTEGER_4 *);
+
+#define internal_unpack_8 prefix(internal_unpack_8)
+void internal_unpack_8 (gfc_array_i8 *, const GFC_INTEGER_8 *);
+
+/* string_intrinsics.c */
+
+#define compare_string prefix(compare_string)
+GFC_INTEGER_4 compare_string (GFC_INTEGER_4, const char *,
+ GFC_INTEGER_4, const char *);
+
+/* random.c */
+
+#define random_seed prefix(random_seed)
+void random_seed (GFC_INTEGER_4 * size, const gfc_array_i4 * put,
+ const gfc_array_i4 * get);
+
+#endif
+
diff --git a/libgfortran/m4/all.m4 b/libgfortran/m4/all.m4
new file mode 100644
index 00000000000..61a45ac345a
--- /dev/null
+++ b/libgfortran/m4/all.m4
@@ -0,0 +1,37 @@
+`/* Implementation of the ALL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"'
+
+include(iparm.m4)dnl
+include(ifunction.m4)dnl
+ARRAY_FUNCTION(1,
+` /* Return true only if all the elements are set. */
+ result = 1;',
+` if (! *src)
+ {
+ result = 0;
+ break;
+ }')
+
diff --git a/libgfortran/m4/any.m4 b/libgfortran/m4/any.m4
new file mode 100644
index 00000000000..cb79022a9e5
--- /dev/null
+++ b/libgfortran/m4/any.m4
@@ -0,0 +1,37 @@
+`/* Implementation of the ANY intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"'
+
+include(iparm.m4)dnl
+include(ifunction.m4)dnl
+ARRAY_FUNCTION(0,
+` result = 0;',
+` /* Return true if any of the elements are set. */
+ if (*src)
+ {
+ result = 1;
+ break;
+ }')
+
diff --git a/libgfortran/m4/cexp.m4 b/libgfortran/m4/cexp.m4
new file mode 100644
index 00000000000..1d22b089a92
--- /dev/null
+++ b/libgfortran/m4/cexp.m4
@@ -0,0 +1,140 @@
+`/* Complex exponential functions
+ Copyright 2002, 2004 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include <math.h>
+#include "libgfortran.h"'
+
+include(`mtype.m4')dnl
+
+/* z = a + ib */
+/* Absolute value. */
+real_type
+cabs`'q (complex_type z)
+{
+ return hypot`'q (REALPART (z), IMAGPART (z));
+}
+
+/* Complex argument. The angle made with the +ve real axis. Range 0-2pi. */
+real_type
+carg`'q (complex_type z)
+{
+ real_type arg;
+
+ arg = atan2`'q (IMAGPART (z), REALPART (z));
+ if (arg < 0)
+ return arg + 2 * M_PI;
+ else
+ return arg;
+}
+
+/* exp(z) = exp(a)*(cos(b) + isin(b)) */
+complex_type
+cexp`'q (complex_type z)
+{
+ real_type a;
+ real_type b;
+ complex_type v;
+
+ a = REALPART (z);
+ b = IMAGPART (z);
+ COMPLEX_ASSIGN (v, cos`'q (b), sin`'q (b));
+ return exp`'q (a) * v;
+}
+
+/* log(z) = log (cabs(z)) + i*carg(z) */
+complex_type
+clog`'q (complex_type z)
+{
+ complex_type v;
+
+ COMPLEX_ASSIGN (v, log`'q (cabs`'q (z)), carg`'q (z));
+ return v;
+}
+
+/* log10(z) = log10 (cabs(z)) + i*carg(z) */
+complex_type
+clog10`'q (complex_type z)
+{
+ complex_type v;
+
+ COMPLEX_ASSIGN (v, log10`'q (cabs`'q (z)), carg`'q (z));
+ return v;
+}
+
+/* pow(base, power) = cexp (power * clog (base)) */
+complex_type
+cpow`'q (complex_type base, complex_type power)
+{
+ return cexp`'q (power * clog`'q (base));
+}
+
+/* sqrt(z). Algorithm pulled from glibc. */
+complex_type
+csqrt`'q (complex_type z)
+{
+ real_type re;
+ real_type im;
+ complex_type v;
+
+ re = REALPART (z);
+ im = IMAGPART (z);
+ if (im == 0.0)
+ {
+ if (re < 0.0)
+ {
+ COMPLEX_ASSIGN (v, 0.0, copysign`'q (sqrt`'q (-re), im));
+ }
+ else
+ {
+ COMPLEX_ASSIGN (v, fabs`'q (sqrt (re)),
+ copysign`'q (0.0, im));
+ }
+ }
+ else if (re == 0.0)
+ {
+ real_type r;
+
+ r = sqrt`'q (0.5 * fabs (im));
+
+ COMPLEX_ASSIGN (v, copysign`'q (r, im), r);
+ }
+ else
+ {
+ real_type d, r, s;
+
+ d = hypot`'q (re, im);
+ /* Use the identity 2 Re res Im res = Im x
+ to avoid cancellation error in d +/- Re x. */
+ if (re > 0)
+ {
+ r = sqrt`'q (0.5 * d + 0.5 * re);
+ s = (0.5 * im) / r;
+ }
+ else
+ {
+ s = sqrt`'q (0.5 * d - 0.5 * re);
+ r = fabs`'q ((0.5 * im) / s);
+ }
+
+ COMPLEX_ASSIGN (v, r, copysign`'q (s, im));
+ }
+ return v;
+}
+
diff --git a/libgfortran/m4/chyp.m4 b/libgfortran/m4/chyp.m4
new file mode 100644
index 00000000000..f6ee972ea52
--- /dev/null
+++ b/libgfortran/m4/chyp.m4
@@ -0,0 +1,72 @@
+`/* Complex hyperbolic functions
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include <math.h>
+#include "libgfortran.h"'
+
+include(`mtype.m4')dnl
+
+/* Complex number z = a + ib. */
+
+/* sinh(z) = sinh(a)cos(b) + icosh(a)sin(b) */
+complex_type
+csinh`'q (complex_type a)
+{
+ real_type r;
+ real_type i;
+ complex_type v;
+
+ r = REALPART (a);
+ i = IMAGPART (a);
+ COMPLEX_ASSIGN (v, sinh`'q (r) * cos`'q (i), cosh`'q (r) * sin`'q (i));
+ return v;
+}
+
+/* cosh(z) = cosh(a)cos(b) - isinh(a)sin(b) */
+complex_type
+ccosh`'q (complex_type a)
+{
+ real_type r;
+ real_type i;
+ complex_type v;
+
+ r = REALPART (a);
+ i = IMAGPART (a);
+ COMPLEX_ASSIGN (v, cosh`'q (r) * cos`'q (i), - (sinh`'q (r) * sin`'q (i)));
+ return v;
+}
+
+/* tanh(z) = (tanh(a) + itan(b)) / (1 - itanh(a)tan(b)) */
+complex_type
+ctanh`'q (complex_type a)
+{
+ real_type rt;
+ real_type it;
+ complex_type n;
+ complex_type d;
+
+ rt = tanh`'q (REALPART (a));
+ it = tan`'q (IMAGPART (a));
+ COMPLEX_ASSIGN (n, rt, it);
+ COMPLEX_ASSIGN (d, 1, - (rt * it));
+
+ return n / d;
+}
+
diff --git a/libgfortran/m4/count.m4 b/libgfortran/m4/count.m4
new file mode 100644
index 00000000000..a5ea4735a9d
--- /dev/null
+++ b/libgfortran/m4/count.m4
@@ -0,0 +1,33 @@
+`/* Implementation of the COUNT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"'
+
+include(iparm.m4)dnl
+include(ifunction.m4)dnl
+ARRAY_FUNCTION(0,
+` result = 0;',
+` if (*src)
+ result++;')
+
diff --git a/libgfortran/m4/cshift1.m4 b/libgfortran/m4/cshift1.m4
new file mode 100644
index 00000000000..382537b7029
--- /dev/null
+++ b/libgfortran/m4/cshift1.m4
@@ -0,0 +1,175 @@
+`/* Implementation of the CSHIFT intrinsic
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Feng Wang <wf_cs@yahoo.com>
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "libgfortran.h"'
+include(types.m4)dnl
+define(htype_kind, regexp(file, `_\([0-9]+\)\.', `\1'))dnl
+define(htype_code,`i'rtype_name)dnl
+define(htype,get_arraytype(i,htype_kind))dnl
+define(htype_name, get_typename(i,htype_kind))dnl
+
+void
+`__cshift1_'htype_kind (const gfc_array_char * ret, const gfc_array_char * array,
+ const htype * h, const htype_name * pwhich)
+{
+ /* r.* indicates the return array. */
+ index_type rstride[GFC_MAX_DIMENSIONS - 1];
+ index_type rstride0;
+ index_type roffset;
+ char *rptr;
+ char *dest;
+ /* s.* indicates the source array. */
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride0;
+ index_type soffset;
+ const char *sptr;
+ const char *src;
+` /* h.* indicates the shift array. */'
+ index_type hstride[GFC_MAX_DIMENSIONS - 1];
+ index_type hstride0;
+ const htype_name *hptr;
+
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type dim;
+ index_type size;
+ index_type len;
+ index_type n;
+ int which;
+ htype_name sh;
+
+ if (pwhich)
+ which = *pwhich - 1;
+ else
+ which = 0;
+
+ if (which < 0 || (which + 1) > GFC_DESCRIPTOR_RANK (array))
+ runtime_error ("Argument 'DIM' is out of range in call to 'CSHIFT'");
+
+ size = GFC_DESCRIPTOR_SIZE (ret);
+
+ extent[0] = 1;
+ count[0] = 0;
+ size = GFC_DESCRIPTOR_SIZE (array);
+ n = 0;
+
+`/* Initialized for avoiding compiler warnings. */'
+ roffset = size;
+ soffset = size;
+ len = 0;
+
+ for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
+ {
+ if (dim == which)
+ {
+ roffset = ret->dim[dim].stride * size;
+ if (roffset == 0)
+ roffset = size;
+ soffset = array->dim[dim].stride * size;
+ if (soffset == 0)
+ soffset = size;
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ }
+ else
+ {
+ count[n] = 0;
+ extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ rstride[n] = ret->dim[dim].stride * size;
+ sstride[n] = array->dim[dim].stride * size;
+
+ hstride[n] = h->dim[n].stride;
+ n++;
+ }
+ }
+ if (sstride[0] == 0)
+ sstride[0] = size;
+ if (rstride[0] == 0)
+ rstride[0] = size;
+ if (hstride[0] == 0)
+ hstride[0] = 1;
+
+ dim = GFC_DESCRIPTOR_RANK (array);
+ rstride0 = rstride[0];
+ sstride0 = sstride[0];
+ hstride0 = hstride[0];
+ rptr = ret->data;
+ sptr = array->data;
+ hptr = h->data;
+
+ while (rptr)
+ {
+` /* Do the shift for this dimension. */'
+ sh = *hptr;
+ sh = (div (sh, len)).rem;
+ if (sh < 0)
+ sh += len;
+
+ src = &sptr[sh * soffset];
+ dest = rptr;
+
+ for (n = 0; n < len; n++)
+ {
+ memcpy (dest, src, size);
+ dest += roffset;
+ if (n == len - sh - 1)
+ src = sptr;
+ else
+ src += soffset;
+ }
+
+ /* Advance to the next section. */
+ rptr += rstride0;
+ sptr += sstride0;
+ hptr += hstride0;
+ count[0]++;
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ rptr -= rstride[n] * extent[n];
+ sptr -= sstride[n] * extent[n];
+ hptr -= hstride[n] * extent[n];
+ n++;
+ if (n >= dim - 1)
+ {
+ /* Break out of the loop. */
+ rptr = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ rptr += rstride[n];
+ sptr += sstride[n];
+ hptr += hstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/m4/ctrig.m4 b/libgfortran/m4/ctrig.m4
new file mode 100644
index 00000000000..d35e4500934
--- /dev/null
+++ b/libgfortran/m4/ctrig.m4
@@ -0,0 +1,72 @@
+`/* Complex trig functions
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include <math.h>
+#include "libgfortran.h"'
+
+include(`mtype.m4')dnl
+
+/* Complex number z = a + ib. */
+
+/* sin(z) = sin(a)cosh(b) + icos(a)sinh(b) */
+complex_type
+csin`'q (complex_type a)
+{
+ real_type r;
+ real_type i;
+ complex_type v;
+
+ r = REALPART (a);
+ i = IMAGPART (a);
+ COMPLEX_ASSIGN (v, sin`'q (r) * cosh`'q (i), cos`'q (r) * sinh`'q (i));
+ return v;
+}
+
+/* cos(z) = cos(a)cosh(b) - isin(a)sinh(b) */
+complex_type
+ccos`'q (complex_type a)
+{
+ real_type r;
+ real_type i;
+ complex_type v;
+
+ r = REALPART (a);
+ i = IMAGPART (a);
+ COMPLEX_ASSIGN (v, cos`'q (r) * cosh`'q (i), - (sin`'q (r) * sinh`'q (i)));
+ return v;
+}
+
+/* tan(z) = (tan(a) + itanh(b)) / (1 - itan(a)tanh(b)) */
+complex_type
+ctan`'q (complex_type a)
+{
+ real_type rt;
+ real_type it;
+ complex_type n;
+ complex_type d;
+
+ rt = tan`'q (REALPART (a));
+ it = tanh`'q (IMAGPART (a));
+ COMPLEX_ASSIGN (n, rt, it);
+ COMPLEX_ASSIGN (d , 1, - (rt * it));
+
+ return n / d;
+}
+
diff --git a/libgfortran/m4/dotprod.m4 b/libgfortran/m4/dotprod.m4
new file mode 100644
index 00000000000..051475f6c00
--- /dev/null
+++ b/libgfortran/m4/dotprod.m4
@@ -0,0 +1,71 @@
+`/* Implementation of the DOT_PRODUCT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"'
+include(types.m4)dnl
+define(rtype_code, regexp(file, `_\([ir][0-9]+\)\.', `\1'))dnl
+define(rtype_letter,substr(rtype_code, 0, 1))dnl
+define(rtype_kind, substr(rtype_code, 1))dnl
+define(rtype,get_arraytype(rtype_letter,rtype_kind))dnl
+define(rtype_name, get_typename(rtype_letter, rtype_kind))dnl
+
+typedef GFC_ARRAY_DESCRIPTOR(GFC_MAX_DIMENSIONS, char) char_array;
+
+/* Both parameters will already have been converted to the result type. */
+rtype_name
+`__dot_product_'rtype_code (rtype * a, rtype * b)
+{
+ rtype_name *pa;
+ rtype_name *pb;
+ rtype_name res;
+ index_type count;
+ index_type astride;
+ index_type bstride;
+
+ assert (GFC_DESCRIPTOR_RANK (a) == 1
+ && GFC_DESCRIPTOR_RANK (b) == 1);
+
+ if (a->dim[0].stride == 0)
+ a->dim[0].stride = 1;
+ if (b->dim[0].stride == 0)
+ b->dim[0].stride = 1;
+
+ astride = a->dim[0].stride;
+ bstride = b->dim[0].stride;
+ count = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ res = 0;
+ pa = a->data;
+ pb = b->data;
+sinclude(`dotprod_asm_'rtype_code`.m4')dnl
+
+ while (count--)
+ {
+ res += *pa * *pb;
+ pa += astride;
+ pb += bstride;
+ }
+
+ return res;
+}
+
diff --git a/libgfortran/m4/dotprodc.m4 b/libgfortran/m4/dotprodc.m4
new file mode 100644
index 00000000000..0e77c0abfed
--- /dev/null
+++ b/libgfortran/m4/dotprodc.m4
@@ -0,0 +1,74 @@
+`/* Implementation of the DOT_PRODUCT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+ and Feng Wang <fengwang@nudt.edu.cn>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"'
+include(types.m4)dnl
+define(rtype_code, regexp(file, `_\(c[0-9]+\)\.', `\1'))dnl
+define(rtype_letter,substr(rtype_code, 0, 1))dnl
+define(rtype_kind, substr(rtype_code, 1))dnl
+define(rtype,get_arraytype(rtype_letter,rtype_kind))dnl
+define(rtype_name, get_typename(rtype_letter, rtype_kind))dnl
+
+typedef GFC_ARRAY_DESCRIPTOR(GFC_MAX_DIMENSIONS, char) char_array;
+
+/* Both parameters will already have been converted to the result type. */
+rtype_name
+`__dot_product_'rtype_code (rtype * a, rtype * b)
+{
+ rtype_name *pa;
+ rtype_name *pb;
+ rtype_name res;
+ rtype_name conjga;
+ index_type count;
+ index_type astride;
+ index_type bstride;
+
+ assert (GFC_DESCRIPTOR_RANK (a) == 1
+ && GFC_DESCRIPTOR_RANK (b) == 1);
+
+ if (a->dim[0].stride == 0)
+ a->dim[0].stride = 1;
+ if (b->dim[0].stride == 0)
+ b->dim[0].stride = 1;
+
+ astride = a->dim[0].stride;
+ bstride = b->dim[0].stride;
+ count = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ res = 0;
+ pa = a->data;
+ pb = b->data;
+sinclude(`dotprod_asm_'rtype_code`.m4')dnl
+
+ while (count--)
+ {
+ COMPLEX_ASSIGN(conjga, REALPART (*pa), -IMAGPART (*pa));
+ res += conjga * *pb;
+ pa += astride;
+ pb += bstride;
+ }
+
+ return res;
+}
+
diff --git a/libgfortran/m4/dotprodl.m4 b/libgfortran/m4/dotprodl.m4
new file mode 100644
index 00000000000..7cbe6000471
--- /dev/null
+++ b/libgfortran/m4/dotprodl.m4
@@ -0,0 +1,79 @@
+`/* Implementation of the DOT_PRODUCT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"'
+include(types.m4)dnl
+define(rtype_kind, regexp(file, `_l\([0-9]+\)\.', `\1'))dnl
+define(rtype_code,`l'rtype_kind)dnl
+define(rtype,get_arraytype(l,rtype_kind))dnl
+define(rtype_name, get_typename(l, rtype_kind))dnl
+
+rtype_name
+`__dot_product_'rtype_code (gfc_array_l4 * a, gfc_array_l4 * b)
+{
+ GFC_LOGICAL_4 *pa;
+ GFC_LOGICAL_4 *pb;
+ index_type count;
+ index_type astride;
+ index_type bstride;
+
+ assert (GFC_DESCRIPTOR_RANK (a) == 1
+ && GFC_DESCRIPTOR_RANK (b) == 1);
+
+ if (a->dim[0].stride == 0)
+ a->dim[0].stride = 1;
+ if (b->dim[0].stride == 0)
+ b->dim[0].stride = 1;
+
+ astride = a->dim[0].stride;
+ bstride = b->dim[0].stride;
+ count = a->dim[0].ubound + 1 - a->dim[0].lbound;
+
+ pa = a->data;
+ if (GFC_DESCRIPTOR_SIZE (a) != 4)
+ {
+ assert (GFC_DESCRIPTOR_SIZE (a) == 8);
+ pa = GFOR_POINTER_L8_TO_L4 (pa);
+ astride <<= 1;
+ }
+ pb = b->data;
+ if (GFC_DESCRIPTOR_SIZE (b) != 4)
+ {
+ assert (GFC_DESCRIPTOR_SIZE (b) == 8);
+ pb = GFOR_POINTER_L8_TO_L4 (pb);
+ bstride <<= 1;
+ }
+
+ while (count--)
+ {
+ if (*pa && *pb)
+ return 1;
+
+ pa += astride;
+ pb += bstride;
+ }
+
+ return 0;
+}
+
diff --git a/libgfortran/m4/eoshift1.m4 b/libgfortran/m4/eoshift1.m4
new file mode 100644
index 00000000000..304d0038578
--- /dev/null
+++ b/libgfortran/m4/eoshift1.m4
@@ -0,0 +1,183 @@
+`/* Implementation of the EOSHIFT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "libgfortran.h"'
+include(types.m4)dnl
+define(htype_kind, regexp(file, `_\([0-9]+\)\.', `\1'))dnl
+define(htype_code,`i'rtype_name)dnl
+define(htype,get_arraytype(i,htype_kind))dnl
+define(htype_name, get_typename(i,htype_kind))dnl
+
+static const char zeros[16] =
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+void
+`__eoshift1_'htype_kind (const gfc_array_char * ret, const gfc_array_char * array,
+ const htype * h, const char * pbound, const htype_name * pwhich)
+{
+ /* r.* indicates the return array. */
+ index_type rstride[GFC_MAX_DIMENSIONS - 1];
+ index_type rstride0;
+ index_type roffset;
+ char *rptr;
+ char *dest;
+ /* s.* indicates the source array. */
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride0;
+ index_type soffset;
+ const char *sptr;
+ const char *src;
+` /* h.* indicates the shift array. */'
+ index_type hstride[GFC_MAX_DIMENSIONS - 1];
+ index_type hstride0;
+ const htype_name *hptr;
+
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type dim;
+ index_type size;
+ index_type len;
+ index_type n;
+ int which;
+ htype_name sh;
+ htype_name delta;
+
+ if (pwhich)
+ which = *pwhich - 1;
+ else
+ which = 0;
+
+ if (!pbound)
+ pbound = zeros;
+
+ size = GFC_DESCRIPTOR_SIZE (ret);
+
+ extent[0] = 1;
+ count[0] = 0;
+ size = GFC_DESCRIPTOR_SIZE (array);
+ n = 0;
+ for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
+ {
+ if (dim == which)
+ {
+ roffset = ret->dim[dim].stride * size;
+ if (roffset == 0)
+ roffset = size;
+ soffset = array->dim[dim].stride * size;
+ if (soffset == 0)
+ soffset = size;
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ }
+ else
+ {
+ count[n] = 0;
+ extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ rstride[n] = ret->dim[dim].stride * size;
+ sstride[n] = array->dim[dim].stride * size;
+
+ hstride[n] = h->dim[n].stride;
+ n++;
+ }
+ }
+ if (sstride[0] == 0)
+ sstride[0] = size;
+ if (rstride[0] == 0)
+ rstride[0] = size;
+ if (hstride[0] == 0)
+ hstride[0] = 1;
+
+ dim = GFC_DESCRIPTOR_RANK (array);
+ rstride0 = rstride[0];
+ sstride0 = sstride[0];
+ hstride0 = hstride[0];
+ rptr = ret->data;
+ sptr = array->data;
+ hptr = h->data;
+
+ while (rptr)
+ {
+` /* Do the shift for this dimension. */'
+ sh = *hptr;
+ delta = (sh >= 0) ? sh: -sh;
+ if (sh > 0)
+ {
+ src = &sptr[delta * soffset];
+ dest = rptr;
+ }
+ else
+ {
+ src = sptr;
+ dest = &rptr[delta * roffset];
+ }
+ for (n = 0; n < len - delta; n++)
+ {
+ memcpy (dest, src, size);
+ dest += roffset;
+ src += soffset;
+ }
+ if (sh < 0)
+ dest = rptr;
+ n = delta;
+
+ while (n--)
+ {
+ memcpy (dest, pbound, size);
+ dest += roffset;
+ }
+
+ /* Advance to the next section. */
+ rptr += rstride0;
+ sptr += sstride0;
+ hptr += hstride0;
+ count[0]++;
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ rptr -= rstride[n] * extent[n];
+ sptr -= sstride[n] * extent[n];
+ hptr -= hstride[n] * extent[n];
+ n++;
+ if (n >= dim - 1)
+ {
+ /* Break out of the loop. */
+ rptr = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ rptr += rstride[n];
+ sptr += sstride[n];
+ hptr += hstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/m4/eoshift3.m4 b/libgfortran/m4/eoshift3.m4
new file mode 100644
index 00000000000..b86a80c41ca
--- /dev/null
+++ b/libgfortran/m4/eoshift3.m4
@@ -0,0 +1,198 @@
+`/* Implementation of the EOSHIFT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "libgfortran.h"'
+include(types.m4)dnl
+define(htype_kind, regexp(file, `_\([0-9]+\)\.', `\1'))dnl
+define(htype_code,`i'rtype_name)dnl
+define(htype,get_arraytype(i,htype_kind))dnl
+define(htype_name, get_typename(i,htype_kind))dnl
+
+static const char zeros[16] =
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+void
+`__eoshift3_'htype_kind (gfc_array_char * ret, gfc_array_char * array,
+ htype * h, const gfc_array_char * bound, htype_name * pwhich)
+{
+ /* r.* indicates the return array. */
+ index_type rstride[GFC_MAX_DIMENSIONS - 1];
+ index_type rstride0;
+ index_type roffset;
+ char *rptr;
+ char *dest;
+ /* s.* indicates the source array. */
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride0;
+ index_type soffset;
+ const char *sptr;
+ const char *src;
+` /* h.* indicates the shift array. */'
+ index_type hstride[GFC_MAX_DIMENSIONS - 1];
+ index_type hstride0;
+ const htype_name *hptr;
+ /* b.* indicates the bound array. */
+ index_type bstride[GFC_MAX_DIMENSIONS - 1];
+ index_type bstride0;
+ const char *bptr;
+
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type dim;
+ index_type size;
+ index_type len;
+ index_type n;
+ int which;
+ htype_name sh;
+ htype_name delta;
+
+ if (pwhich)
+ which = *pwhich - 1;
+ else
+ which = 0;
+
+ size = GFC_DESCRIPTOR_SIZE (ret);
+
+ extent[0] = 1;
+ count[0] = 0;
+ size = GFC_DESCRIPTOR_SIZE (array);
+ n = 0;
+ for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
+ {
+ if (dim == which)
+ {
+ roffset = ret->dim[dim].stride * size;
+ if (roffset == 0)
+ roffset = size;
+ soffset = array->dim[dim].stride * size;
+ if (soffset == 0)
+ soffset = size;
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ }
+ else
+ {
+ count[n] = 0;
+ extent[n] = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ rstride[n] = ret->dim[dim].stride * size;
+ sstride[n] = array->dim[dim].stride * size;
+
+ hstride[n] = h->dim[n].stride;
+ if (bound)
+ bstride[n] = bound->dim[n].stride;
+ else
+ bstride[n] = 0;
+ n++;
+ }
+ }
+ if (sstride[0] == 0)
+ sstride[0] = size;
+ if (rstride[0] == 0)
+ rstride[0] = size;
+ if (hstride[0] == 0)
+ hstride[0] = 1;
+ if (bound && bstride[0] == 0)
+ bstride[0] = size;
+
+ dim = GFC_DESCRIPTOR_RANK (array);
+ rstride0 = rstride[0];
+ sstride0 = sstride[0];
+ hstride0 = hstride[0];
+ bstride0 = bstride[0];
+ rptr = ret->data;
+ sptr = array->data;
+ hptr = h->data;
+ if (bound)
+ bptr = bound->data;
+ else
+ bptr = zeros;
+
+ while (rptr)
+ {
+` /* Do the shift for this dimension. */'
+ sh = *hptr;
+ delta = (sh >= 0) ? sh: -sh;
+ if (sh > 0)
+ {
+ src = &sptr[delta * soffset];
+ dest = rptr;
+ }
+ else
+ {
+ src = sptr;
+ dest = &rptr[delta * roffset];
+ }
+ for (n = 0; n < len - delta; n++)
+ {
+ memcpy (dest, src, size);
+ dest += roffset;
+ src += soffset;
+ }
+ if (sh < 0)
+ dest = rptr;
+ n = delta;
+
+ while (n--)
+ {
+ memcpy (dest, bptr, size);
+ dest += roffset;
+ }
+
+ /* Advance to the next section. */
+ rptr += rstride0;
+ sptr += sstride0;
+ hptr += hstride0;
+ bptr += bstride0;
+ count[0]++;
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ rptr -= rstride[n] * extent[n];
+ sptr -= sstride[n] * extent[n];
+ hptr -= hstride[n] * extent[n];
+ bptr -= bstride[n] * extent[n];
+ n++;
+ if (n >= dim - 1)
+ {
+ /* Break out of the loop. */
+ rptr = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ rptr += rstride[n];
+ sptr += sstride[n];
+ hptr += hstride[n];
+ bptr += bstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/m4/exponent.m4 b/libgfortran/m4/exponent.m4
new file mode 100644
index 00000000000..510f763292d
--- /dev/null
+++ b/libgfortran/m4/exponent.m4
@@ -0,0 +1,32 @@
+`/* Implementation of the EXPONENT intrinsic
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@redhat.com>.
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include <math.h>
+#include "libgfortran.h"'
+
+include(`mtype.m4')dnl
+
+GFC_INTEGER_4
+prefix(exponent_r`'kind) (real_type s)
+{
+ int ret;
+ frexp`'q (s, &ret);
+ return ret;
+}
diff --git a/libgfortran/m4/fraction.m4 b/libgfortran/m4/fraction.m4
new file mode 100644
index 00000000000..c453e78ac41
--- /dev/null
+++ b/libgfortran/m4/fraction.m4
@@ -0,0 +1,31 @@
+`/* Implementation of the FRACTION intrinsic
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@redhat.com>.
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include <math.h>
+#include "libgfortran.h"'
+
+include(`mtype.m4')dnl
+
+real_type
+prefix(fraction_r`'kind) (real_type s)
+{
+ int dummy_exp;
+ return frexp`'q (s, &dummy_exp);
+}
diff --git a/libgfortran/m4/head.m4 b/libgfortran/m4/head.m4
new file mode 100644
index 00000000000..0b2f9eeaa63
--- /dev/null
+++ b/libgfortran/m4/head.m4
@@ -0,0 +1,21 @@
+`! Copyright 2002 Free Software Foundation, Inc.
+! Contributed by Paul Brook <paul@nowt.org>
+!
+!This file is part of the GNU Fortran 95 runtime library (libgfor).
+!
+!GNU libgfor is free software; you can redistribute it and/or
+!modify it under the terms of the GNU Lesser General Public
+!License as published by the Free Software Foundation; either
+!version 2.1 of the License, or (at your option) any later version.
+!
+!GNU libgfor 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 Lesser General Public License for more details.
+!
+!You should have received a copy of the GNU Lesser General Public
+!License along with libgfor; see the file COPYING. If not,
+!write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+!Boston, MA 02111-1307, USA.
+!
+!This file is machine generated.'
diff --git a/libgfortran/m4/iforeach.m4 b/libgfortran/m4/iforeach.m4
new file mode 100644
index 00000000000..2397036ba72
--- /dev/null
+++ b/libgfortran/m4/iforeach.m4
@@ -0,0 +1,196 @@
+dnl Support macro file for intrinsic functions.
+dnl Contains the generic sections of the array functions.
+dnl This file is part of the GNU Fortran 95 Runtime Library (libgfortran)
+dnl Distributed under the GNU LGPL. See COPYING for details.
+define(START_FOREACH_FUNCTION,
+`void
+`__'name`'rtype_qual`_'type_code (rtype * retarray, atype *array)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ type_name *base;
+ rtype_name *dest;
+ index_type rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+')dnl
+define(START_FOREACH_BLOCK,
+` while (base)
+ {
+ {
+ /* Implementation start. */
+')dnl
+define(FINISH_FOREACH_FUNCTION,
+` /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ }
+ }
+ }
+ }
+}')dnl
+define(START_MASKED_FOREACH_FUNCTION,
+`void
+`__m'name`'rtype_qual`_'type_code (rtype * retarray, atype *array, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type sstride[GFC_MAX_DIMENSIONS];
+ index_type mstride[GFC_MAX_DIMENSIONS];
+ index_type dstride;
+ rtype_name *dest;
+ type_name *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ index_type n;
+
+ rank = GFC_DESCRIPTOR_RANK (array);
+ assert (rank > 0);
+ assert (GFC_DESCRIPTOR_RANK (retarray) == 1);
+ assert (retarray->dim[0].ubound + 1 - retarray->dim[0].lbound == rank);
+ assert (GFC_DESCRIPTOR_RANK (mask) == rank);
+
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ dstride = retarray->dim[0].stride;
+ dest = retarray->data;
+ for (n = 0; n < rank; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ count[n] = 0;
+ if (extent[n] <= 0)
+ {
+ /* Set the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 0;
+ return;
+ }
+ }
+
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+
+ /* Initialize the return value. */
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = 1;
+ {
+')dnl
+define(START_MASKED_FOREACH_BLOCK, `START_FOREACH_BLOCK')dnl
+define(FINISH_MASKED_FOREACH_FUNCTION,
+` /* Implementation end. */
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the loop. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ }
+ }
+ }
+ }
+}')dnl
+define(FOREACH_FUNCTION,
+`START_FOREACH_FUNCTION
+$1
+START_FOREACH_BLOCK
+$2
+FINISH_FOREACH_FUNCTION')dnl
+define(MASKED_FOREACH_FUNCTION,
+`START_MASKED_FOREACH_FUNCTION
+$1
+START_MASKED_FOREACH_BLOCK
+$2
+FINISH_MASKED_FOREACH_FUNCTION')dnl
diff --git a/libgfortran/m4/ifunction.m4 b/libgfortran/m4/ifunction.m4
new file mode 100644
index 00000000000..95445846185
--- /dev/null
+++ b/libgfortran/m4/ifunction.m4
@@ -0,0 +1,256 @@
+dnl Support macro file for intrinsic functions.
+dnl Contains the generic sections of the array functions.
+dnl This file is part of the GNU Fortran 95 Runtime Library (libgfortran)
+dnl Distributed under the GNU LGPL. See COPYING for details.
+dnl
+dnl Pass the implementation for a single section as the parameter to
+dnl {MASK_}ARRAY_FUNCTION.
+dnl The variables base, delta, and len describe the input section.
+dnl For masked section the mask is described by mbase and mdelta.
+dnl These should not be modified. The result should be stored in *dest.
+dnl The names count, extent, sstride, dstride, base, dest, rank, dim
+dnl retarray, array, pdim and mstride should not be used.
+dnl The variable n is declared as index_type and may be used.
+dnl Other variable declarations may be placed at the start of the code,
+dnl The types of the array parameter and the return value are
+dnl type_name and rtype_name respectively.
+dnl Execution should be allowed to continue to the end of the block.
+dnl You should not return or break from the inner loop of the implementation.
+dnl Care should also be taken to avoid using the names defined in iparm.m4
+define(START_ARRAY_FUNCTION,
+`void
+`__'name`'rtype_qual`_'type_code (rtype * retarray, atype *array, index_type *pdim)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ type_name *base;
+ rtype_name *dest;
+ index_type rank;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type dim;
+
+ /* Make dim zero based to avoid confusion. */
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ delta = array->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ len = 0;
+ }
+
+ base = array->data;
+ dest = retarray->data;
+
+ while (base)
+ {
+ type_name *src;
+ rtype_name result;
+ src = base;
+ {
+')dnl
+define(START_ARRAY_BLOCK,
+` if (len <= 0)
+ *dest = '$1`;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta)
+ {
+')dnl
+define(FINISH_ARRAY_FUNCTION,
+ ` }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}')dnl
+define(START_MASKED_ARRAY_FUNCTION,
+`void
+`__m'name`'rtype_qual`_'type_code (rtype * retarray, atype * array, index_type *pdim, gfc_array_l4 * mask)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type dstride[GFC_MAX_DIMENSIONS - 1];
+ index_type mstride[GFC_MAX_DIMENSIONS - 1];
+ rtype_name *dest;
+ type_name *base;
+ GFC_LOGICAL_4 *mbase;
+ int rank;
+ int dim;
+ index_type n;
+ index_type len;
+ index_type delta;
+ index_type mdelta;
+
+ dim = (*pdim) - 1;
+ rank = GFC_DESCRIPTOR_RANK (array) - 1;
+ assert (rank == GFC_DESCRIPTOR_RANK (retarray));
+ if (array->dim[0].stride == 0)
+ array->dim[0].stride = 1;
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+
+ len = array->dim[dim].ubound + 1 - array->dim[dim].lbound;
+ if (len <= 0)
+ return;
+ delta = array->dim[dim].stride;
+ mdelta = mask->dim[dim].stride;
+
+ for (n = 0; n < dim; n++)
+ {
+ sstride[n] = array->dim[n].stride;
+ mstride[n] = mask->dim[n].stride;
+ extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+ for (n = dim; n < rank; n++)
+ {
+ sstride[n] = array->dim[n + 1].stride;
+ mstride[n] = mask->dim[n + 1].stride;
+ extent[n] =
+ array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound;
+ }
+
+ for (n = 0; n < rank; n++)
+ {
+ count[n] = 0;
+ dstride[n] = retarray->dim[n].stride;
+ if (extent[n] <= 0)
+ return;
+ }
+
+ dest = retarray->data;
+ base = array->data;
+ mbase = mask->data;
+
+ if (GFC_DESCRIPTOR_SIZE (mask) != 4)
+ {
+ /* This allows the same loop to be used for all logical types. */
+ assert (GFC_DESCRIPTOR_SIZE (mask) == 8);
+ for (n = 0; n < rank; n++)
+ mstride[n] <<= 1;
+ mdelta <<= 1;
+ mbase = (GFOR_POINTER_L8_TO_L4 (mbase));
+ }
+
+ while (base)
+ {
+ type_name *src;
+ GFC_LOGICAL_4 *msrc;
+ rtype_name result;
+ src = base;
+ msrc = mbase;
+ {
+')dnl
+define(START_MASKED_ARRAY_BLOCK,
+` if (len <= 0)
+ *dest = '$1`;
+ else
+ {
+ for (n = 0; n < len; n++, src += delta, msrc += mdelta)
+ {
+')dnl
+define(FINISH_MASKED_ARRAY_FUNCTION,
+` }
+ *dest = result;
+ }
+ }
+ /* Advance to the next element. */
+ count[0]++;
+ base += sstride[0];
+ mbase += mstride[0];
+ dest += dstride[0];
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ base -= sstride[n] * extent[n];
+ mbase -= mstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+ n++;
+ if (n == rank)
+ {
+ /* Break out of the look. */
+ base = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ base += sstride[n];
+ mbase += mstride[n];
+ dest += dstride[n];
+ }
+ }
+ }
+}')dnl
+define(ARRAY_FUNCTION,
+`START_ARRAY_FUNCTION
+$2
+START_ARRAY_BLOCK($1)
+$3
+FINISH_ARRAY_FUNCTION')dnl
+define(MASKED_ARRAY_FUNCTION,
+`START_MASKED_ARRAY_FUNCTION
+$2
+START_MASKED_ARRAY_BLOCK($1)
+$3
+FINISH_MASKED_ARRAY_FUNCTION')dnl
diff --git a/libgfortran/m4/in_pack.m4 b/libgfortran/m4/in_pack.m4
new file mode 100644
index 00000000000..4998ed5f2db
--- /dev/null
+++ b/libgfortran/m4/in_pack.m4
@@ -0,0 +1,122 @@
+`/* Helper function for repacking arrays.
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfortran; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"'
+include(types.m4)dnl
+define(rtype_kind, regexp(file, `_.\([0-9]+\)\.', `\1'))dnl
+define(rtype_letter, regexp(file, `_\(.\)[0-9]+\.', `\1'))dnl
+define(rtype_code,rtype_letter`'rtype_name)dnl
+define(rtype,get_arraytype(rtype_letter,rtype_kind))dnl
+define(rtype_name, get_typename(rtype_letter, rtype_kind))dnl
+
+
+/* Allocates a block of memory with internal_malloc if the array needs
+ repacking. */
+
+dnl Only the kind (ie size) is used to name the function.
+rtype_name *
+`internal_pack_'rtype_kind (rtype * source)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type stride[GFC_MAX_DIMENSIONS - 1];
+ index_type stride0;
+ index_type dim;
+ index_type ssize;
+ const rtype_name *src;
+ rtype_name *dest;
+ rtype_name *destptr;
+ int n;
+ int packed;
+
+ if (source->dim[0].stride == 0)
+ {
+ source->dim[0].stride = 1;
+ return source->data;
+ }
+
+ dim = GFC_DESCRIPTOR_RANK (source);
+ ssize = 1;
+ packed = 1;
+ for (n = 0; n < dim; n++)
+ {
+ count[n] = 0;
+ stride[n] = source->dim[n].stride;
+ extent[n] = source->dim[n].ubound + 1 - source->dim[n].lbound;
+ if (extent[n] <= 0)
+ {
+ /* Do nothing. */
+ packed = 1;
+ break;
+ }
+
+ if (ssize != stride[n])
+ packed = 0;
+
+ ssize *= extent[n];
+ }
+
+ if (packed)
+ return source->data;
+
+ /* Allocate storage for the destination. */
+ destptr = (rtype_name *)internal_malloc_size (ssize * rtype_kind);
+ dest = destptr;
+ src = source->data;
+ stride0 = stride[0];
+
+
+ while (src)
+ {
+ /* Copy the data. */
+ *(dest++) = *src;
+ /* Advance to the next element. */
+ src += stride0;
+ count[0]++;
+ /* Advance to the next source element. */
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ src -= stride[n] * extent[n];
+ n++;
+ if (n == dim)
+ {
+ src = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ src += stride[n];
+ }
+ }
+ }
+ return destptr;
+}
+
diff --git a/libgfortran/m4/in_unpack.m4 b/libgfortran/m4/in_unpack.m4
new file mode 100644
index 00000000000..fe344ca7d31
--- /dev/null
+++ b/libgfortran/m4/in_unpack.m4
@@ -0,0 +1,109 @@
+`/* Helper function for repacking arrays.
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "libgfortran.h"'
+include(types.m4)dnl
+define(rtype_kind, regexp(file, `_.\([0-9]+\)\.', `\1'))dnl
+define(rtype_letter, regexp(file, `_\(.\)[0-9]+\.', `\1'))dnl
+define(rtype_code,rtype_letter`'rtype_name)dnl
+define(rtype,get_arraytype(rtype_letter,rtype_kind))dnl
+define(rtype_name, get_typename(rtype_letter, rtype_kind))dnl
+
+dnl Only the kind (ie size) is used to name the function.
+void
+`internal_unpack_'rtype_kind (rtype * d, const rtype_name * src)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type stride[GFC_MAX_DIMENSIONS - 1];
+ index_type stride0;
+ index_type dim;
+ index_type dsize;
+ rtype_name *dest;
+ int n;
+
+ dest = d->data;
+ if (src == dest || !src)
+ return;
+
+ if (d->dim[0].stride == 0)
+ d->dim[0].stride = 1;
+
+ dim = GFC_DESCRIPTOR_RANK (d);
+ dsize = 1;
+ for (n = 0; n < dim; n++)
+ {
+ count[n] = 0;
+ stride[n] = d->dim[n].stride;
+ extent[n] = d->dim[n].ubound + 1 - d->dim[n].lbound;
+ if (extent[n] <= 0)
+ abort ();
+
+ if (dsize == stride[n])
+ dsize *= extent[n];
+ else
+ dsize = 0;
+ }
+
+ if (dsize != 0)
+ {
+ memcpy (dest, src, dsize * rtype_kind);
+ return;
+ }
+
+ stride0 = stride[0];
+
+ while (dest)
+ {
+ /* Copy the data. */
+ *dest = *(src++);
+ /* Advance to the next element. */
+ dest += stride0;
+ count[0]++;
+ /* Advance to the next source element. */
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ dest -= stride[n] * extent[n];
+ n++;
+ if (n == dim)
+ {
+ dest = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ dest += stride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/m4/iparm.m4 b/libgfortran/m4/iparm.m4
new file mode 100644
index 00000000000..6cbd7b247a8
--- /dev/null
+++ b/libgfortran/m4/iparm.m4
@@ -0,0 +1,26 @@
+dnl Support macro file for intrinsic functions.
+dnl Works out all the function types from the filename.
+dnl This file is part of the GNU Fortran 95 Runtime Library (libgfortran)
+dnl Distributed under the GNU LGPL. See COPYING for details.
+dnl M4 macro file to get type names from filenames
+include(`types.m4')
+define(type_letter, regexp(file, `_\([irlc]\)[^_]*$', \1))dnl
+define(type_kind, regexp(file, `_[irlc]\([0-9]*\)[^_]*$', \1))dnl
+define(rtype_kind, regexp(file, `_\([0-9]*\)_[irlc][0-9]*[^_]*$', `\1'))dnl
+define(type_code, type_letter`'type_kind)dnl
+define(type_name, get_typename(type_letter,type_kind))dnl
+define(atype, get_arraytype(type_letter,type_kind))dnl
+ifelse(rtype_kind,,
+`define(rtype_letter,type_letter)dnl
+define(rtype_name, type_name)dnl
+define(rtype_code, type_code)dnl
+define(rtype, atype)dnl
+define(rtype_qual,`')dnl
+',
+`define(rtype_letter,i)dnl
+define(rtype_name, get_typename(rtype_letter,rtype_kind))dnl
+define(rtype, get_arraytype(rtype_letter,rtype_kind))dnl
+define(rtype_qual,`_'rtype_kind)dnl
+')dnl
+define(type_max, type_name`_HUGE')dnl
+define(type_min, `-'type_max)dnl
diff --git a/libgfortran/m4/matmul.m4 b/libgfortran/m4/matmul.m4
new file mode 100644
index 00000000000..fcf63a6504e
--- /dev/null
+++ b/libgfortran/m4/matmul.m4
@@ -0,0 +1,145 @@
+`/* Implementation of the MATMUL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"'
+include(types.m4)dnl
+define(rtype_code, regexp(file, `_\([irc][0-9]+\)\.', `\1'))dnl
+define(rtype_letter,substr(rtype_code, 0, 1))dnl
+define(rtype_kind, substr(rtype_code, 1))dnl
+define(rtype,get_arraytype(rtype_letter,rtype_kind))dnl
+define(rtype_name, get_typename(rtype_letter, rtype_kind))dnl
+
+/* Dimensions: retarray(x,y) a(x, count) b(count,y).
+ Either a or b can be rank 1. In this case x or y is 1. */
+void
+`__matmul_'rtype_code (rtype * retarray, rtype * a, rtype * b)
+{
+ rtype_name *abase;
+ rtype_name *bbase;
+ rtype_name *dest;
+ rtype_name res;
+ index_type rxstride;
+ index_type rystride;
+ index_type xcount;
+ index_type ycount;
+ index_type xstride;
+ index_type ystride;
+ index_type x;
+ index_type y;
+
+ rtype_name *pa;
+ rtype_name *pb;
+ index_type astride;
+ index_type bstride;
+ index_type count;
+ index_type n;
+
+ assert (GFC_DESCRIPTOR_RANK (a) == 2
+ || GFC_DESCRIPTOR_RANK (b) == 2);
+ abase = a->data;
+ bbase = b->data;
+ dest = retarray->data;
+
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (a->dim[0].stride == 0)
+ a->dim[0].stride = 1;
+ if (b->dim[0].stride == 0)
+ b->dim[0].stride = 1;
+
+sinclude(`matmul_asm_'rtype_code`.m4')dnl
+
+ if (GFC_DESCRIPTOR_RANK (retarray) == 1)
+ {
+ rxstride = retarray->dim[0].stride;
+ rystride = rxstride;
+ }
+ else
+ {
+ rxstride = retarray->dim[0].stride;
+ rystride = retarray->dim[1].stride;
+ }
+
+ /* If we have rank 1 parameters, zero the absent stride, and set the size to
+ one. */
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ astride = a->dim[0].stride;
+ count = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ xstride = 0;
+ rxstride = 0;
+ xcount = 1;
+ }
+ else
+ {
+ astride = a->dim[1].stride;
+ count = a->dim[1].ubound + 1 - a->dim[1].lbound;
+ xstride = a->dim[0].stride;
+ xcount = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ }
+ if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ bstride = b->dim[0].stride;
+ assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound);
+ ystride = 0;
+ rystride = 0;
+ ycount = 1;
+ }
+ else
+ {
+ bstride = b->dim[0].stride;
+ assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound);
+ ystride = b->dim[1].stride;
+ ycount = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ }
+
+ for (y = 0; y < ycount; y++)
+ {
+ for (x = 0; x < xcount; x++)
+ {
+ /* Do the summation for this element. For real and integer types
+ this is the same as DOT_PRODUCT. For complex types we use do
+ a*b, not conjg(a)*b. */
+ pa = abase;
+ pb = bbase;
+ res = 0;
+
+ for (n = 0; n < count; n++)
+ {
+ res += *pa * *pb;
+ pa += astride;
+ pb += bstride;
+ }
+
+ *dest = res;
+
+ dest += rxstride;
+ abase += xstride;
+ }
+ abase -= xstride * xcount;
+ bbase += ystride;
+ dest += rystride - (rxstride * xcount);
+ }
+}
+
diff --git a/libgfortran/m4/matmull.m4 b/libgfortran/m4/matmull.m4
new file mode 100644
index 00000000000..e522a93faef
--- /dev/null
+++ b/libgfortran/m4/matmull.m4
@@ -0,0 +1,157 @@
+`/* Implementation of the MATMUL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"'
+include(types.m4)dnl
+define(rtype_kind, regexp(file, `_l\([0-9]+\)\.', `\1'))dnl
+define(rtype_code,`l'rtype_kind)dnl
+define(rtype,get_arraytype(l,rtype_kind))dnl
+define(rtype_name, get_typename(l, rtype_kind))dnl
+
+/* Dimensions: retarray(x,y) a(x, count) b(count,y).
+ Either a or b can be rank 1. In this case x or y is 1. */
+void
+`__matmul_'rtype_code (rtype * retarray, gfc_array_l4 * a, gfc_array_l4 * b)
+{
+ GFC_INTEGER_4 *abase;
+ GFC_INTEGER_4 *bbase;
+ rtype_name *dest;
+ index_type rxstride;
+ index_type rystride;
+ index_type xcount;
+ index_type ycount;
+ index_type xstride;
+ index_type ystride;
+ index_type x;
+ index_type y;
+
+ GFC_INTEGER_4 *pa;
+ GFC_INTEGER_4 *pb;
+ index_type astride;
+ index_type bstride;
+ index_type count;
+ index_type n;
+
+ assert (GFC_DESCRIPTOR_RANK (a) == 2
+ || GFC_DESCRIPTOR_RANK (b) == 2);
+ abase = a->data;
+ if (GFC_DESCRIPTOR_SIZE (a) != 4)
+ {
+ assert (GFC_DESCRIPTOR_SIZE (a) == 8);
+ abase = GFOR_POINTER_L8_TO_L4 (abase);
+ astride <<= 1;
+ }
+ bbase = b->data;
+ if (GFC_DESCRIPTOR_SIZE (b) != 4)
+ {
+ assert (GFC_DESCRIPTOR_SIZE (b) == 8);
+ bbase = GFOR_POINTER_L8_TO_L4 (bbase);
+ bstride <<= 1;
+ }
+ dest = retarray->data;
+
+ if (retarray->dim[0].stride == 0)
+ retarray->dim[0].stride = 1;
+ if (a->dim[0].stride == 0)
+ a->dim[0].stride = 1;
+ if (b->dim[0].stride == 0)
+ b->dim[0].stride = 1;
+
+sinclude(`matmul_asm_'rtype_code`.m4')dnl
+
+ if (GFC_DESCRIPTOR_RANK (retarray) == 1)
+ {
+ rxstride = retarray->dim[0].stride;
+ rystride = rxstride;
+ }
+ else
+ {
+ rxstride = retarray->dim[0].stride;
+ rystride = retarray->dim[1].stride;
+ }
+
+ /* If we have rank 1 parameters, zero the absent stride, and set the size to
+ one. */
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ astride = a->dim[0].stride;
+ count = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ xstride = 0;
+ rxstride = 0;
+ xcount = 1;
+ }
+ else
+ {
+ astride = a->dim[1].stride;
+ count = a->dim[1].ubound + 1 - a->dim[1].lbound;
+ xstride = a->dim[0].stride;
+ xcount = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ }
+ if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ bstride = b->dim[0].stride;
+ assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound);
+ ystride = 0;
+ rystride = 0;
+ ycount = 1;
+ }
+ else
+ {
+ bstride = b->dim[0].stride;
+ assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound);
+ ystride = b->dim[1].stride;
+ ycount = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ }
+
+ for (y = 0; y < ycount; y++)
+ {
+ for (x = 0; x < xcount; x++)
+ {
+ /* Do the summation for this element. For real and integer types
+ this is the same as DOT_PRODUCT. For complex types we use do
+ a*b, not conjg(a)*b. */
+ pa = abase;
+ pb = bbase;
+ *dest = 0;
+
+ for (n = 0; n < count; n++)
+ {
+ if (*pa && *pb)
+ {
+ *dest = 1;
+ break;
+ }
+ pa += astride;
+ pb += bstride;
+ }
+
+ dest += rxstride;
+ abase += xstride;
+ }
+ abase -= xstride * xcount;
+ bbase += ystride;
+ dest += rystride - (rxstride * xcount);
+ }
+}
+
diff --git a/libgfortran/m4/maxloc0.m4 b/libgfortran/m4/maxloc0.m4
new file mode 100644
index 00000000000..89ecacb9656
--- /dev/null
+++ b/libgfortran/m4/maxloc0.m4
@@ -0,0 +1,54 @@
+`/* Implementation of the MAXLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"'
+
+include(iparm.m4)dnl
+include(iforeach.m4)dnl
+
+FOREACH_FUNCTION(
+` type_name maxval;
+
+ maxval = type_min;'
+,
+` if (*base > maxval)
+ {
+ maxval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }')
+
+MASKED_FOREACH_FUNCTION(
+` type_name maxval;
+
+ maxval = type_min;'
+,
+` if (*mbase && *base > maxval)
+ {
+ maxval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }')
diff --git a/libgfortran/m4/maxloc1.m4 b/libgfortran/m4/maxloc1.m4
new file mode 100644
index 00000000000..0eb259f9c6d
--- /dev/null
+++ b/libgfortran/m4/maxloc1.m4
@@ -0,0 +1,50 @@
+`/* Implementation of the MAXLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"'
+
+include(iparm.m4)dnl
+include(ifunction.m4)dnl
+ARRAY_FUNCTION(0,
+` type_name maxval;
+ maxval = type_min;
+ result = 1;',
+` if (*src > maxval)
+ {
+ maxval = *src;
+ result = (rtype_name)n + 1;
+ }')
+
+MASKED_ARRAY_FUNCTION(0,
+` type_name maxval;
+ maxval = type_min;
+ result = 1;',
+` if (*msrc && *src > maxval)
+ {
+ maxval = *src;
+ result = (rtype_name)n + 1;
+ }')
+
diff --git a/libgfortran/m4/maxval.m4 b/libgfortran/m4/maxval.m4
new file mode 100644
index 00000000000..b6a5666aae1
--- /dev/null
+++ b/libgfortran/m4/maxval.m4
@@ -0,0 +1,39 @@
+`/* Implementation of the MAXVAL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include "libgfortran.h"'
+
+include(iparm.m4)dnl
+include(ifunction.m4)dnl
+ARRAY_FUNCTION(type_min,
+` result = type_min;',
+` if (*src > result)
+ result = *src;')
+
+MASKED_ARRAY_FUNCTION(type_min,
+` result = type_min;',
+` if (*msrc && *src > result)
+ result = *src;')
+
diff --git a/libgfortran/m4/minloc0.m4 b/libgfortran/m4/minloc0.m4
new file mode 100644
index 00000000000..5411418b68a
--- /dev/null
+++ b/libgfortran/m4/minloc0.m4
@@ -0,0 +1,54 @@
+`/* Implementation of the MINLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"'
+
+include(iparm.m4)dnl
+include(iforeach.m4)dnl
+
+FOREACH_FUNCTION(
+` type_name minval;
+
+ minval = type_max;'
+,
+` if (*base < minval)
+ {
+ minval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }')
+
+MASKED_FOREACH_FUNCTION(
+` type_name minval;
+
+ minval = type_max;'
+,
+` if (*mbase && *base < minval)
+ {
+ minval = *base;
+ for (n = 0; n < rank; n++)
+ dest[n * dstride] = count[n] + 1;
+ }')
diff --git a/libgfortran/m4/minloc1.m4 b/libgfortran/m4/minloc1.m4
new file mode 100644
index 00000000000..e3101c63861
--- /dev/null
+++ b/libgfortran/m4/minloc1.m4
@@ -0,0 +1,50 @@
+`/* Implementation of the MINLOC intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <limits.h>
+#include "libgfortran.h"'
+
+include(iparm.m4)dnl
+include(ifunction.m4)dnl
+ARRAY_FUNCTION(0,
+` type_name minval;
+ minval = type_max;
+ result = 1;',
+` if (*src < minval)
+ {
+ minval = *src;
+ result = (rtype_name)n + 1;
+ }')
+
+MASKED_ARRAY_FUNCTION(0,
+` type_name minval;
+ minval = type_max;
+ result = 1;',
+` if (*msrc && *src < minval)
+ {
+ minval = *src;
+ result = (rtype_name)n + 1;
+ }')
+
diff --git a/libgfortran/m4/minval.m4 b/libgfortran/m4/minval.m4
new file mode 100644
index 00000000000..2c1be2b88f9
--- /dev/null
+++ b/libgfortran/m4/minval.m4
@@ -0,0 +1,39 @@
+`/* Implementation of the MINVAL intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include "libgfortran.h"'
+
+include(iparm.m4)dnl
+include(ifunction.m4)dnl
+ARRAY_FUNCTION(type_max,
+` result = type_max;',
+` if (*src < result)
+ result = *src;')
+
+MASKED_ARRAY_FUNCTION(type_max,
+` result = type_max;',
+` if (*msrc && *src < result)
+ result = *src;')
+
diff --git a/libgfortran/m4/mtype.m4 b/libgfortran/m4/mtype.m4
new file mode 100644
index 00000000000..84bf39f3561
--- /dev/null
+++ b/libgfortran/m4/mtype.m4
@@ -0,0 +1,5 @@
+dnl Get type kind from filename.
+define(kind,regexp(file, `_.\([0-9]+\).c$', `\1'))dnl
+define(complex_type, `GFC_COMPLEX_'kind)dnl
+define(real_type, `GFC_REAL_'kind)dnl
+define(q,ifelse(kind,4,f,ifelse(kind,8,`',`_'kind)))dnl
diff --git a/libgfortran/m4/nearest.m4 b/libgfortran/m4/nearest.m4
new file mode 100644
index 00000000000..5168d99c8e2
--- /dev/null
+++ b/libgfortran/m4/nearest.m4
@@ -0,0 +1,39 @@
+`/* Implementation of the NEAREST intrinsic
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@redhat.com>.
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include <math.h>
+#include <float.h>
+#include "libgfortran.h"'
+
+include(`mtype.m4')dnl
+
+real_type
+prefix(nearest_r`'kind) (real_type s, real_type dir)
+{
+ dir = copysign`'q (__builtin_inf`'q (), dir);
+ if (FLT_EVAL_METHOD != 0)
+ {
+ /* ??? Work around glibc bug on x86. */
+ volatile real_type r = nextafter`'q (s, dir);
+ return r;
+ }
+ else
+ return nextafter`'q (s, dir);
+}
diff --git a/libgfortran/m4/product.m4 b/libgfortran/m4/product.m4
new file mode 100644
index 00000000000..bef9b8184eb
--- /dev/null
+++ b/libgfortran/m4/product.m4
@@ -0,0 +1,37 @@
+`/* Implementation of the PRODUCT intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"'
+
+include(iparm.m4)dnl
+include(ifunction.m4)dnl
+ARRAY_FUNCTION(1,
+` result = 1;',
+` result *= *src;')
+
+MASKED_ARRAY_FUNCTION(1,
+` result = 1;',
+` if (*msrc)
+ result *= *src;')
+
diff --git a/libgfortran/m4/reshape.m4 b/libgfortran/m4/reshape.m4
new file mode 100644
index 00000000000..b8143fe24af
--- /dev/null
+++ b/libgfortran/m4/reshape.m4
@@ -0,0 +1,232 @@
+`/* Implementation of the RESHAPE
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"'
+include(types.m4)dnl
+define(rtype_kind, regexp(file, `_.\([0-9]+\)\.', `\1'))dnl
+define(rtype_letter, regexp(file, `_\(.\)[0-9]+\.', `\1'))dnl
+define(rtype_code,rtype_letter`'rtype_name)dnl
+define(rtype,get_arraytype(rtype_letter,rtype_kind))dnl
+define(rtype_name, get_typename(rtype_letter, rtype_kind))dnl
+
+typedef GFC_ARRAY_DESCRIPTOR(1, index_type) shape_type;
+
+/* The shape parameter is ignored. We can currently deduce the shape from the
+ return array. */
+dnl Only the kind (ie size) is used to name the function.
+void
+`__reshape_'rtype_kind (rtype * ret, rtype * source, shape_type * shape,
+ rtype * pad, shape_type * order)
+{
+ /* r.* indicates the return array. */
+ index_type rcount[GFC_MAX_DIMENSIONS - 1];
+ index_type rextent[GFC_MAX_DIMENSIONS - 1];
+ index_type rstride[GFC_MAX_DIMENSIONS - 1];
+ index_type rstride0;
+ index_type rdim;
+ index_type rsize;
+ rtype_name *rptr;
+ /* s.* indicates the source array. */
+ index_type scount[GFC_MAX_DIMENSIONS - 1];
+ index_type sextent[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride[GFC_MAX_DIMENSIONS - 1];
+ index_type sstride0;
+ index_type sdim;
+ index_type ssize;
+ const rtype_name *sptr;
+ /* p.* indicates the pad array. */
+ index_type pcount[GFC_MAX_DIMENSIONS - 1];
+ index_type pextent[GFC_MAX_DIMENSIONS - 1];
+ index_type pstride[GFC_MAX_DIMENSIONS - 1];
+ index_type pdim;
+ index_type psize;
+ const rtype_name *pptr;
+
+ const rtype_name *src;
+ int n;
+ int dim;
+
+ if (ret->dim[0].stride == 0)
+ ret->dim[0].stride = 1;
+ if (source->dim[0].stride == 0)
+ source->dim[0].stride = 1;
+ if (shape->dim[0].stride == 0)
+ shape->dim[0].stride = 1;
+ if (pad && pad->dim[0].stride == 0)
+ pad->dim[0].stride = 1;
+ if (order && order->dim[0].stride == 0)
+ order->dim[0].stride = 1;
+
+ rdim = GFC_DESCRIPTOR_RANK (ret);
+ rsize = 1;
+ for (n = 0; n < rdim; n++)
+ {
+ if (order)
+ dim = order->data[n * order->dim[0].stride] - 1;
+ else
+ dim = n;
+
+ rcount[n] = 0;
+ rstride[n] = ret->dim[dim].stride;
+ rextent[n] = ret->dim[dim].ubound + 1 - ret->dim[dim].lbound;
+
+ if (rextent[n] != shape->data[dim * shape->dim[0].stride])
+ runtime_error ("shape and target do not conform");
+
+ if (rsize == rstride[n])
+ rsize *= rextent[n];
+ else
+ rsize = 0;
+ if (rextent[dim] <= 0)
+ return;
+ }
+
+ sdim = GFC_DESCRIPTOR_RANK (source);
+ ssize = 1;
+ for (n = 0; n < sdim; n++)
+ {
+ scount[n] = 0;
+ sstride[n] = source->dim[n].stride;
+ sextent[n] = source->dim[n].ubound + 1 - source->dim[n].lbound;
+ if (sextent[n] <= 0)
+ abort ();
+
+ if (ssize == sstride[n])
+ ssize *= sextent[n];
+ else
+ ssize = 0;
+ }
+
+ if (pad)
+ {
+ if (pad->dim[0].stride == 0)
+ pad->dim[0].stride = 1;
+ pdim = GFC_DESCRIPTOR_RANK (pad);
+ psize = 1;
+ for (n = 0; n < pdim; n++)
+ {
+ pcount[n] = 0;
+ pstride[n] = pad->dim[n].stride;
+ pextent[n] = pad->dim[n].ubound + 1 - pad->dim[n].lbound;
+ if (pextent[n] <= 0)
+ abort ();
+ if (psize == pstride[n])
+ psize *= pextent[n];
+ else
+ psize = 0;
+ }
+ pptr = pad->data;
+ }
+ else
+ {
+ pdim = 0;
+ psize = 1;
+ pptr = NULL;
+ }
+
+ if (rsize != 0 && ssize != 0 && psize != 0)
+ {
+ rsize *= rtype_kind;
+ ssize *= rtype_kind;
+ psize *= rtype_kind;
+ reshape_packed ((char *)ret->data, rsize, (char *)source->data,
+ ssize, pad ? (char *)pad->data : NULL, psize);
+ return;
+ }
+ rptr = ret->data;
+ src = sptr = source->data;
+ rstride0 = rstride[0];
+ sstride0 = sstride[0];
+
+ while (rptr)
+ {
+ /* Select between the source and pad arrays. */
+ *rptr = *src;
+ /* Advance to the next element. */
+ rptr += rstride0;
+ src += sstride0;
+ rcount[0]++;
+ scount[0]++;
+ /* Advance to the next destination element. */
+ n = 0;
+ while (rcount[n] == rextent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ rcount[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ rptr -= rstride[n] * rextent[n];
+ n++;
+ if (n == rdim)
+ {
+ /* Break out of the loop. */
+ rptr = NULL;
+ break;
+ }
+ else
+ {
+ rcount[n]++;
+ rptr += rstride[n];
+ }
+ }
+ /* Advance to the next source element. */
+ n = 0;
+ while (scount[n] == sextent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ scount[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ src -= sstride[n] * sextent[n];
+ n++;
+ if (n == sdim)
+ {
+ if (sptr && pad)
+ {
+ /* Switch to the pad array. */
+ sptr = NULL;
+ sdim = pdim;
+ for (dim = 0; dim < pdim; dim++)
+ {
+ scount[dim] = pcount[dim];
+ sextent[dim] = pextent[dim];
+ sstride[dim] = pstride[dim];
+ sstride0 = sstride[0];
+ }
+ }
+ /* We now start again from the beginning of the pad array. */
+ src = pptr;
+ break;
+ }
+ else
+ {
+ scount[n]++;
+ src += sstride[n];
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/m4/set_exponent.m4 b/libgfortran/m4/set_exponent.m4
new file mode 100644
index 00000000000..352a129865e
--- /dev/null
+++ b/libgfortran/m4/set_exponent.m4
@@ -0,0 +1,31 @@
+`/* Implementation of the SET_EXPONENT intrinsic
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@redhat.com>.
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include <math.h>
+#include "libgfortran.h"'
+
+include(`mtype.m4')dnl
+
+real_type
+prefix(set_exponent_r`'kind) (real_type s, GFC_INTEGER_4 i)
+{
+ int dummy_exp;
+ return scalbn`'q (frexp`'q (s, &dummy_exp), i);
+}
diff --git a/libgfortran/m4/shape.m4 b/libgfortran/m4/shape.m4
new file mode 100644
index 00000000000..826077eabe7
--- /dev/null
+++ b/libgfortran/m4/shape.m4
@@ -0,0 +1,48 @@
+`/* Implementation of the SHAPE intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"'
+include(types.m4)dnl
+define(rtype_kind, regexp(file, `_i\([0-9]+\)\.', `\1'))dnl
+define(rtype_code,`i'rtype_name)dnl
+define(rtype,get_arraytype(i,rtype_kind))dnl
+define(rtype_name, get_typename(i, rtype_kind))dnl
+
+void
+`__shape_'rtype_kind (rtype * ret, const rtype * array)
+{
+ int n;
+ index_type stride;
+
+ stride = ret->dim[0].stride;
+ if (stride == 0)
+ stride = 1;
+
+ for (n = 0; n < GFC_DESCRIPTOR_RANK (array); n++)
+ {
+ ret->data[n * stride] =
+ array->dim[n].ubound + 1 - array->dim[n].lbound;
+ }
+}
+
diff --git a/libgfortran/m4/specific.m4 b/libgfortran/m4/specific.m4
new file mode 100644
index 00000000000..bf88857ccf1
--- /dev/null
+++ b/libgfortran/m4/specific.m4
@@ -0,0 +1,16 @@
+include(head.m4)
+define(type_code,regexp(file,`_\([ircl][0-9]+\).f90',`\1'))dnl
+define(type_letter,substr(type_code, 0, 1))dnl
+define(type_kind,substr(type_code, 1))dnl
+define(get_typename2, `$1 (kind=$2)')dnl
+define(get_typename, `get_typename2(ifelse($1,i,integer,ifelse($1,r,real,ifelse($1,l,logical,ifelse($1,c,complex,unknown)))),`$2')')dnl
+define(type_name, get_typename(type_letter,type_kind))dnl
+define(name, regexp(regexp(file, `[^/]*$', `\&'), `^_\([^_]*\)_', `\1'))dnl
+define(function_name,`specific__'name`_'type_code)dnl
+
+elemental function function_name (parm)
+ type_name, intent (in) :: parm
+ type_name :: function_name
+
+ function_name = name (parm)
+end function
diff --git a/libgfortran/m4/specific2.m4 b/libgfortran/m4/specific2.m4
new file mode 100644
index 00000000000..ca0d831f5e0
--- /dev/null
+++ b/libgfortran/m4/specific2.m4
@@ -0,0 +1,16 @@
+include(head.m4)
+define(type_code,regexp(file,`_\([ircl][0-9]+\).f90',`\1'))dnl
+define(type_letter,substr(type_code, 0, 1))dnl
+define(type_kind,substr(type_code, 1))dnl
+define(get_typename2, `$1 (kind=$2)')dnl
+define(get_typename, `get_typename2(ifelse($1,i,integer,ifelse($1,r,real,ifelse($1,l,logical,ifelse($1,c,complex,unknown)))),`$2')')dnl
+define(type_name, get_typename(type_letter,type_kind))dnl
+define(name, regexp(regexp(file, `[^/]*$', `\&'), `^_\([^_]*\)_', `\1'))dnl
+define(function_name,`specific__'name`_'type_code)dnl
+
+elemental function function_name (p1, p2)
+ type_name, intent (in) :: p1, p2
+ type_name :: function_name
+
+ function_name = name (p1, p2)
+end function
diff --git a/libgfortran/m4/sum.m4 b/libgfortran/m4/sum.m4
new file mode 100644
index 00000000000..0ea3477bf87
--- /dev/null
+++ b/libgfortran/m4/sum.m4
@@ -0,0 +1,36 @@
+`/* Implementation of the SUM intrinsic
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfortran 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "libgfortran.h"'
+
+include(iparm.m4)dnl
+include(ifunction.m4)dnl
+ARRAY_FUNCTION(0,
+` result = 0;',
+` result += *src;')
+
+MASKED_ARRAY_FUNCTION(0,
+` result = 0;',
+` if (*msrc)
+ result += *src;')
diff --git a/libgfortran/m4/transpose.m4 b/libgfortran/m4/transpose.m4
new file mode 100644
index 00000000000..35df64bf347
--- /dev/null
+++ b/libgfortran/m4/transpose.m4
@@ -0,0 +1,75 @@
+`/* Implementation of the TRANSPOSE intrinsic
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Tobias Schlüter
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <assert.h>
+#include "libgfortran.h"'
+include(types.m4)dnl
+define(rtype_kind, regexp(file, `_.\([0-9]+\)\.', `\1'))dnl
+define(rtype_letter, regexp(file, `_\(.\)[0-9]+\.', `\1'))dnl
+define(rtype_code,rtype_letter`'rtype_name)dnl
+define(rtype,get_arraytype(rtype_letter,rtype_kind))dnl
+define(rtype_name, get_typename(rtype_letter, rtype_kind))dnl
+
+void
+`__transpose_'rtype_kind (rtype * ret, rtype * source)
+{
+ /* r.* indicates the return array. */
+ index_type rxstride, rystride;
+ rtype_name *rptr;
+ /* s.* indicates the source array. */
+ index_type sxstride, systride;
+ const rtype_name *sptr;
+
+ index_type xcount, ycount;
+ index_type x, y;
+
+ assert (GFC_DESCRIPTOR_RANK (source) == 2);
+
+ if (ret->dim[0].stride == 0)
+ ret->dim[0].stride = 1;
+ if (source->dim[0].stride == 0)
+ source->dim[0].stride = 1;
+
+ sxstride = source->dim[0].stride;
+ systride = source->dim[1].stride;
+ xcount = source->dim[0].ubound + 1 - source->dim[0].lbound;
+ ycount = source->dim[1].ubound + 1 - source->dim[1].lbound;
+
+ rxstride = ret->dim[0].stride;
+ rystride = ret->dim[1].stride;
+
+ rptr = ret->data;
+ sptr = source->data;
+
+ for (y=0; y < ycount; y++)
+ {
+ for (x=0; x < xcount; x++)
+ {
+ *rptr = *sptr;
+
+ sptr += sxstride;
+ rptr += rystride;
+ }
+ sptr += systride - (sxstride * xcount);
+ rptr += rxstride - (rystride * xcount);
+ }
+}
diff --git a/libgfortran/m4/types.m4 b/libgfortran/m4/types.m4
new file mode 100644
index 00000000000..cb808290c08
--- /dev/null
+++ b/libgfortran/m4/types.m4
@@ -0,0 +1,4 @@
+define(get_typename2, `GFC_$1_$2')dnl
+define(get_typename, `get_typename2(ifelse($1,i,INTEGER,ifelse($1,r,REAL,ifelse($1,l,LOGICAL,ifelse($1,c,COMPLEX,unknown)))),`$2')')dnl
+define(get_arraytype, `gfc_array_$1$2')dnl
+define(name, regexp(regexp(file, `[^/]*$', `\&'), `^\([^_]*\)_', `\1'))dnl
diff --git a/libgfortran/runtime/environ.c b/libgfortran/runtime/environ.c
new file mode 100644
index 00000000000..71419616920
--- /dev/null
+++ b/libgfortran/runtime/environ.c
@@ -0,0 +1,678 @@
+/* Copyright (C) 2002-2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor 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 2, or (at your option)
+any later version.
+
+Libgfor 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 libgfor; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "libgfortran.h"
+#include "../io/io.h"
+
+
+/* Environment scanner. Examine the environment for controlling minor
+ * aspects of the program's execution. Our philosophy here that the
+ * environment should not prevent the program from running, so an
+ * environment variable with a messed-up value will be interpreted in
+ * the default way.
+ *
+ * Most of the environment is checked early in the startup sequence,
+ * but other variables are checked during execution of the user's
+ * program. */
+
+options_t options;
+
+extern char **environ;
+
+typedef struct variable
+{
+ const char *name;
+ int value, *var;
+ void (*init) (struct variable *);
+ void (*show) (struct variable *);
+ const char *desc;
+ int bad;
+}
+variable;
+
+
+/* print_spaces()-- Print a particular number of spaces */
+
+static void
+print_spaces (int n)
+{
+ char buffer[80];
+ int i;
+
+ if (n <= 0)
+ return;
+
+ for (i = 0; i < n; i++)
+ buffer[i] = ' ';
+
+ buffer[i] = '\0';
+
+ st_printf (buffer);
+}
+
+
+/* var_source()-- Return a string that describes where the value of a
+ * variable comes from */
+
+static const char *
+var_source (variable * v)
+{
+
+ if (getenv (v->name) == NULL)
+ return "Default";
+
+ if (v->bad)
+ return "Bad ";
+
+ return "Set ";
+}
+
+
+/* init_integer()-- Initialize an integer environment variable */
+
+static void
+init_integer (variable * v)
+{
+ char *p, *q;
+
+ p = getenv (v->name);
+ if (p == NULL)
+ goto set_default;
+
+ for (q = p; *q; q++)
+ if (!isdigit (*q))
+ {
+ v->bad = 1;
+ goto set_default;
+ }
+
+ *v->var = atoi (p);
+ return;
+
+set_default:
+ *v->var = v->value;
+ return;
+}
+
+
+/* show_integer()-- Show an integer environment variable */
+
+static void
+show_integer (variable * v)
+{
+
+ st_printf ("%s %d\n", var_source (v), *v->var);
+}
+
+
+/* init_boolean()-- Initialize a boolean environment variable. We
+ * only look at the first letter of the variable. */
+
+static void
+init_boolean (variable * v)
+{
+ char *p;
+
+ p = getenv (v->name);
+ if (p == NULL)
+ goto set_default;
+
+ if (*p == '1' || *p == 'Y' || *p == 'y')
+ {
+ *v->var = 1;
+ return;
+ }
+
+ if (*p == '0' || *p == 'N' || *p == 'n')
+ {
+ *v->var = 0;
+ return;
+ }
+
+ v->bad = 1;
+
+set_default:
+ *v->var = v->value;
+ return;
+}
+
+
+/* show_boolean()-- Show a boolean environment variable */
+
+static void
+show_boolean (variable * v)
+{
+
+ st_printf ("%s %s\n", var_source (v), *v->var ? "Yes" : "No");
+}
+
+
+/* init_mem()-- Initialize environment variables that have to do with
+ * how memory from an ALLOCATE statement is filled. A single flag
+ * enables filling and a second variable gives the value that is used
+ * to initialize the memory. */
+
+static void
+init_mem (variable * v)
+{
+ int offset, n;
+ char *p;
+
+ p = getenv (v->name);
+
+ options.allocate_init_flag = 0; /* The default */
+
+ if (p == NULL)
+ return;
+
+ if (strcasecmp (p, "NONE") == 0)
+ return;
+
+ /* IEEE-754 Quiet Not-a-Number that will work for single and double
+ * precision. Look for the 'f95' mantissa in debug dumps. */
+
+ if (strcasecmp (p, "NaN") == 0)
+ {
+ options.allocate_init_flag = 1;
+ options.allocate_init_value = 0xfff80f95;
+ return;
+ }
+
+ /* Interpret the string as a hexadecimal constant */
+
+ n = 0;
+ while (*p)
+ {
+ if (!isxdigit (*p))
+ {
+ v->bad = 1;
+ return;
+ }
+
+ offset = '0';
+ if (islower (*p))
+ offset = 'a';
+ if (isupper (*p))
+ offset = 'A';
+
+ n = (n << 4) | (*p++ - offset);
+ }
+
+ options.allocate_init_flag = 1;
+ options.allocate_init_value = n;
+}
+
+
+static void
+show_mem (variable * v)
+{
+ char *p;
+
+ p = getenv (v->name);
+
+ st_printf ("%s ", var_source (v));
+
+ if (options.allocate_init_flag)
+ st_printf ("0x%x", options.allocate_init_value);
+
+ st_printf ("\n");
+}
+
+
+static void
+init_sep (variable * v)
+{
+ int seen_comma;
+ char *p;
+
+ p = getenv (v->name);
+ if (p == NULL)
+ goto set_default;
+
+ v->bad = 1;
+ options.separator = p;
+ options.separator_len = strlen (p);
+
+ /* Make sure the separator is valid */
+
+ if (options.separator_len == 0)
+ goto set_default;
+ seen_comma = 0;
+
+ while (*p)
+ {
+ if (*p == ',')
+ {
+ if (seen_comma)
+ goto set_default;
+ seen_comma = 1;
+ p++;
+ continue;
+ }
+
+ if (*p++ != ' ')
+ goto set_default;
+ }
+
+ v->bad = 0;
+ return;
+
+set_default:
+ options.separator = " ";
+ options.separator_len = 1;
+}
+
+
+static void
+show_sep (variable * v)
+{
+
+ st_printf ("%s \"%s\"\n", var_source (v), options.separator);
+}
+
+
+static void
+init_string (variable * v)
+{
+}
+
+static void
+show_string (variable * v)
+{
+ const char *p;
+
+ p = getenv (v->name);
+ if (p == NULL)
+ p = "";
+
+ st_printf ("%s \"%s\"\n", var_source (v), p);
+}
+
+
+/* Structure for associating names and values. */
+
+typedef struct
+{
+ const char *name;
+ int value;
+}
+choice;
+
+
+enum
+{ FP_ROUND_NEAREST, FP_ROUND_UP, FP_ROUND_DOWN, FP_ROUND_ZERO };
+
+static choice rounding[] = {
+ {"NEAREST", FP_ROUND_NEAREST},
+ {"UP", FP_ROUND_UP},
+ {"DOWN", FP_ROUND_DOWN},
+ {"ZERO", FP_ROUND_ZERO},
+ {NULL}
+}, precision[] =
+{
+ {
+ "24", 1}
+ ,
+ {
+ "53", 2}
+ ,
+ {
+ "64", 0}
+ ,
+ {
+ NULL}
+}
+
+, signal_choices[] =
+{
+ {
+ "IGNORE", 1}
+ ,
+ {
+ "ABORT", 0}
+ ,
+ {
+ NULL}
+};
+
+
+static void
+init_choice (variable * v, choice * c)
+{
+ char *p;
+
+ p = getenv (v->name);
+ if (p == NULL)
+ goto set_default;
+
+ for (; c->name; c++)
+ if (strcasecmp (c->name, p) == 0)
+ break;
+
+ if (c->name == NULL)
+ {
+ v->bad = 1;
+ goto set_default;
+ }
+
+ *v->var = c->value;
+ return;
+
+set_default:
+ *v->var = v->value;
+}
+
+
+static void
+show_choice (variable * v, choice * c)
+{
+
+ st_printf ("%s ", var_source (v));
+
+ for (; c->name; c++)
+ if (c->value == *v->var)
+ break;
+
+ if (c->name)
+ st_printf ("%s\n", c->name);
+ else
+ st_printf ("(Unknown)\n");
+
+}
+
+
+static void
+init_round (variable * v)
+{
+ init_choice (v, rounding);
+}
+static void
+show_round (variable * v)
+{
+ show_choice (v, rounding);
+}
+
+static void
+init_precision (variable * v)
+{
+ init_choice (v, precision);
+}
+static void
+show_precision (variable * v)
+{
+ show_choice (v, precision);
+}
+
+static void
+init_signal (variable * v)
+{
+ init_choice (v, signal_choices);
+}
+static void
+show_signal (variable * v)
+{
+ show_choice (v, signal_choices);
+}
+
+
+static variable variable_table[] = {
+ {"GFORTRAN_STDIN_UNIT", 5, &options.stdin_unit, init_integer, show_integer,
+ "Unit number that will be preconnected to standard input\n"
+ "(No preconnection if negative)"},
+
+ {"GFORTRAN_STDOUT_UNIT", 6, &options.stdout_unit, init_integer,
+ show_integer,
+ "Unit number that will be preconnected to standard output\n"
+ "(No preconnection if negative)"},
+
+ {"GFORTRAN_USE_STDERR", 1, &options.use_stderr, init_boolean,
+ show_boolean,
+ "Sends library output to standard error instead of standard output."},
+
+ {"GFORTRAN_TMPDIR", 0, NULL, init_string, show_string,
+ "Directory for scratch files. Overrides the TMP environment variable\n"
+ "If TMP is not set " DEFAULT_TEMPDIR " is used."},
+
+ {"GFORTRAN_UNBUFFERED_ALL", 0, &options.all_unbuffered, init_boolean,
+ show_boolean,
+ "If TRUE, all output is unbuffered. This will slow down large writes "
+ "but can be\nuseful for forcing data to be displayed immediately."},
+
+ {"GFORTRAN_SHOW_LOCUS", 1, &options.locus, init_boolean, show_boolean,
+ "If TRUE, print filename and line number where runtime errors happen."},
+
+/* GFORTRAN_NAME_xx (where xx is a unit number) gives the names of files
+ * preconnected to those units. */
+
+/* GFORTRAN_UNBUFFERED_xx (where xx is a unit number) gives a boolean that is used
+ * to turn off buffering for that unit. */
+
+ {"GFORTRAN_OPTIONAL_PLUS", 0, &options.optional_plus, init_boolean, show_boolean,
+ "Print optional plus signs in numbers where permitted. Default FALSE."},
+
+ {"GFORTRAN_DEFAULT_RECL", DEFAULT_RECL, &options.default_recl,
+ init_integer, show_integer,
+ "Default maximum record length for sequential files. Most useful for\n"
+ "adjusting line length of preconnected units. Default "
+ stringize (DEFAULT_RECL)},
+
+ {"GFORTRAN_LIST_SEPARATOR", 0, NULL, init_sep, show_sep,
+ "Separatator to use when writing list output. May contain any number of "
+ "spaces\nand at most one comma. Default is a single space."},
+
+ /* Memory related controls */
+
+ {"GFORTRAN_MEM_INIT", 0, NULL, init_mem, show_mem,
+ "How to initialize allocated memory. Default value is NONE for no "
+ "initialization\n(faster), NAN for a Not-a-Number with the mantissa "
+ "0x40f95 or a custom\nhexadecimal value"},
+
+ {"GFORTRAN_MEM_CHECK", 0, &options.mem_check, init_boolean, show_boolean,
+ "Whether memory still allocated will be reported when the program ends."},
+
+ /* Signal handling (Unix). */
+
+ {"GFORTRAN_SIGHUP", 0, &options.sighup, init_signal, show_signal,
+ "Whether the program will IGNORE or ABORT on SIGHUP."},
+
+ {"GFORTRAN_SIGINT", 0, &options.sigint, init_signal, show_signal,
+ "Whether the program will IGNORE or ABORT on SIGINT."},
+
+ /* Floating point control */
+
+ {"GFORTRAN_FPU_ROUND", 0, &options.fpu_round, init_round, show_round,
+ "Set floating point rounding. Values are NEAREST, UP, DOWN, ZERO."},
+
+ {"GFORTRAN_FPU_PRECISION", 0, &options.fpu_precision, init_precision,
+ show_precision,
+ "Precision of intermediate results. Values are 24, 53 and 64."},
+
+ {"GFORTRAN_FPU_INVALID", 1, &options.fpu_invalid, init_boolean,
+ show_boolean,
+ "Raise a floating point exception on invalid FP operation."},
+
+ {"GFORTRAN_FPU_DENORMAL", 1, &options.fpu_denormal, init_boolean,
+ show_boolean,
+ "Raise a floating point exception when denormal numbers are encountered."},
+
+ {"GFORTRAN_FPU_ZERO", 0, &options.fpu_zerodiv, init_boolean, show_boolean,
+ "Raise a floating point exception when dividing by zero."},
+
+ {"GFORTRAN_FPU_OVERFLOW", 0, &options.fpu_overflow, init_boolean,
+ show_boolean,
+ "Raise a floating point exception on overflow."},
+
+ {"GFORTRAN_FPU_UNDERFLOW", 0, &options.fpu_underflow, init_boolean,
+ show_boolean,
+ "Raise a floating point exception on underflow."},
+
+ {"GFORTRAN_FPU_PRECISION", 0, &options.fpu_precision_loss, init_boolean,
+ show_boolean,
+ "Raise a floating point exception on precision loss."},
+
+ {NULL}
+};
+
+
+/* init_variables()-- Initialize most runtime variables from
+ * environment variables. */
+
+void
+init_variables (void)
+{
+ variable *v;
+
+ for (v = variable_table; v->name; v++)
+ v->init (v);
+}
+
+
+/* check_buffered()-- Given an unit number n, determine if an override
+ * for the stream exists. Returns zero for unbuffered, one for
+ * buffered or two for not set. */
+
+int
+check_buffered (int n)
+{
+ char name[40];
+ variable v;
+ int rv;
+
+ if (options.all_unbuffered)
+ return 0;
+
+ strcpy (name, "GFORTRAN_UNBUFFERED_");
+ strcat (name, itoa (n));
+
+ v.name = name;
+ v.value = 2;
+ v.var = &rv;
+
+ init_boolean (&v);
+
+ return rv;
+}
+
+
+/* pattern_scan()-- Given an environment string, check that the name
+ * has the same name as the pattern followed by an integer. On a
+ * match, a pointer to the value is returned and the integer pointed
+ * to by n is updated. Returns NULL on no match. */
+
+static char *
+pattern_scan (char *env, const char *pattern, int *n)
+{
+ char *p;
+ size_t len;
+
+ len = strlen (pattern);
+ if (strncasecmp (env, pattern, len) != 0)
+ return NULL;
+ p = env + len;
+
+ if (!isdigit (*p))
+ return NULL;
+
+ while (isdigit (*p))
+ p++;
+
+ if (*p != '=')
+ return NULL;
+
+ *p = '\0';
+ *n = atoi (env + len);
+ *p++ = '=';
+
+ return p;
+}
+
+
+void
+show_variables (void)
+{
+ char *p, **e;
+ variable *v;
+ int n;
+/* TODO: print version number. */
+ st_printf ("GNU Fortran 95 runtime library version "
+ "UNKNOWN" "\n\n");
+
+ st_printf ("Environment variables:\n");
+ st_printf ("----------------------\n");
+
+ for (v = variable_table; v->name; v++)
+ {
+ n = st_printf ("%s", v->name);
+ print_spaces (25 - n);
+
+ if (v->show == show_integer)
+ st_printf ("Integer ");
+ else if (v->show == show_boolean)
+ st_printf ("Boolean ");
+ else
+ st_printf ("String ");
+
+ v->show (v);
+ st_printf ("%s\n\n", v->desc);
+ }
+
+ st_printf ("\nDefault unit names (GFORTRAN_NAME_x):\n");
+
+ for (e = environ; *e; e++)
+ {
+ p = pattern_scan (*e, "GFORTRAN_NAME_", &n);
+ if (p == NULL)
+ continue;
+ st_printf ("GFORTRAN_NAME_%d %s\n", n, p);
+ }
+
+ st_printf ("\nUnit buffering overrides (GFORTRAN_UNBUFFERED_x):\n");
+ for (e = environ; *e; e++)
+ {
+ p = pattern_scan (*e, "GFORTRAN_UNBUFFERED_", &n);
+ if (p == NULL)
+ continue;
+
+ st_printf ("GFORTRAN_UNBUFFERED_%d = %s\n", n, p);
+ }
+
+ /* System error codes */
+
+ st_printf ("\nRuntime error codes:");
+ st_printf ("\n--------------------\n");
+
+ for (n = ERROR_FIRST + 1; n < ERROR_LAST; n++)
+ if (n < 0 || n > 9)
+ st_printf ("%d %s\n", n, translate_error (n));
+ else
+ st_printf (" %d %s\n", n, translate_error (n));
+
+ st_printf ("\nCommand line arguments:\n");
+ st_printf (" --help Print this list\n");
+
+ /* st_printf(" --resume <dropfile> Resume program execution from dropfile\n"); */
+
+ sys_exit (0);
+}
diff --git a/libgfortran/runtime/error.c b/libgfortran/runtime/error.c
new file mode 100644
index 00000000000..8cd980dff9a
--- /dev/null
+++ b/libgfortran/runtime/error.c
@@ -0,0 +1,538 @@
+/* Copyright (C) 2002-2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor 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 2, or (at your option)
+any later version.
+
+Libgfor 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 libgfor; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+#include "config.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+#include "libgfortran.h"
+#include "../io/io.h"
+
+/* Error conditions. The tricky part here is printing a message when
+ * it is the I/O subsystem that is severely wounded. Our goal is to
+ * try and print something making the fewest assumptions possible,
+ * then try to clean up before actually exiting.
+ *
+ * The following exit conditions are defined:
+ * 0 Normal program exit.
+ * 1 Terminated because of operating system error.
+ * 2 Error in the runtime library
+ * 3 Internal error in runtime library
+ * 4 Error during error processing (very bad)
+ *
+ * Other error returns are reserved for the STOP statement with a numeric code.
+ */
+
+/* locus variables. These are optionally set by a caller before a
+ * library subroutine is called. They are always cleared on exit so
+ * that files that report loci and those that do not can be linked
+ * together without reporting an erroneous position. */
+
+char *filename;
+unsigned line;
+
+static char buffer[32]; /* buffer for integer/ascii conversions */
+
+/* rtoa()-- Real to ascii conversion for base 10 and below.
+ * Returns a pointer to a static buffer. */
+
+char *
+rtoa (double f, int length, int oprec)
+{
+ double n = f;
+ double fval, minval;
+ int negative, prec;
+ unsigned k;
+ char formats[16];
+
+ prec = 0;
+ negative = 0;
+ if (n < 0.0)
+ {
+ negative = 1;
+ n = -n;
+ }
+
+ if (length >= 8)
+ minval = FLT_MIN;
+ else
+ minval = DBL_MIN;
+
+
+ if (n <= minval)
+ {
+ buffer[0] = '0';
+ buffer[1] = '.';
+ for (k = 2; k < 28 ; k++)
+ buffer[k] = '0';
+ buffer[k+1] = '\0';
+ return buffer;
+ }
+ fval = n;
+ while (fval > 1.0)
+ {
+ fval = fval / 10.0;
+ prec ++;
+ }
+
+ prec = sizeof (buffer) - 2 - prec;
+ if (prec > 20)
+ prec = 20;
+ prec = prec > oprec ? oprec : prec ;
+
+ if (negative)
+ sprintf (formats, "-%%.%df", prec);
+ else
+ sprintf (formats, "%%.%df", prec);
+
+ sprintf (buffer, formats, n);
+ return buffer;
+}
+
+
+/* Returns a pointer to a static buffer. */
+
+char *
+itoa (int64_t n)
+{
+ int negative;
+ char *p;
+
+ if (n == 0)
+ {
+ buffer[0] = '0';
+ buffer[1] = '\0';
+ return buffer;
+ }
+
+ negative = 0;
+ if (n < 0)
+ {
+ negative = 1;
+ n = -n;
+ }
+
+ p = buffer + sizeof (buffer) - 1;
+ *p-- = '\0';
+
+ while (n != 0)
+ {
+ *p-- = '0' + (n % 10);
+ n /= 10;
+ }
+
+ if (negative)
+ *p-- = '-';
+ return ++p;
+}
+
+
+/* xtoa()-- Integer to hexadecimal conversion. Returns a pointer to a
+ * static buffer. */
+
+char *
+xtoa (uint64_t n)
+{
+ int digit;
+ char *p;
+
+ if (n == 0)
+ {
+ buffer[0] = '0';
+ buffer[1] = '\0';
+ return buffer;
+ }
+
+ p = buffer + sizeof (buffer) - 1;
+ *p-- = '\0';
+
+ while (n != 0)
+ {
+ digit = n & 0xF;
+ if (digit > 9)
+ digit += 'A' - '0' - 10;
+
+ *p-- = '0' + digit;
+ n >>= 4;
+ }
+
+ return ++p;
+}
+
+
+/* st_printf()-- simple printf() function for streams that handles the
+ * formats %d, %s and %c. This function handles printing of error
+ * messages that originate within the library itself, not from a user
+ * program. */
+
+int
+st_printf (const char *format, ...)
+{
+ int count, total;
+ va_list arg;
+ char *p, *q;
+ stream *s;
+
+ total = 0;
+ s = init_error_stream ();
+ va_start (arg, format);
+
+ for (;;)
+ {
+ count = 0;
+
+ while (format[count] != '%' && format[count] != '\0')
+ count++;
+
+ if (count != 0)
+ {
+ p = salloc_w (s, &count);
+ memmove (p, format, count);
+ sfree (s);
+ }
+
+ total += count;
+ format += count;
+ if (*format++ == '\0')
+ break;
+
+ switch (*format)
+ {
+ case 'c':
+ count = 1;
+
+ p = salloc_w (s, &count);
+ *p = (char) va_arg (arg, int);
+
+ sfree (s);
+ break;
+
+ case 'd':
+ q = itoa (va_arg (arg, int));
+ count = strlen (q);
+
+ p = salloc_w (s, &count);
+ memmove (p, q, count);
+ sfree (s);
+ break;
+
+ case 'x':
+ q = xtoa (va_arg (arg, unsigned));
+ count = strlen (q);
+
+ p = salloc_w (s, &count);
+ memmove (p, q, count);
+ sfree (s);
+ break;
+
+ case 's':
+ q = va_arg (arg, char *);
+ count = strlen (q);
+
+ p = salloc_w (s, &count);
+ memmove (p, q, count);
+ sfree (s);
+ break;
+
+ case '\0':
+ return total;
+
+ default:
+ count = 2;
+ p = salloc_w (s, &count);
+ p[0] = format[-1];
+ p[1] = format[0];
+ sfree (s);
+ break;
+ }
+
+ total += count;
+ format++;
+ }
+
+ va_end (arg);
+ return total;
+}
+
+
+/* st_sprintf()-- Simple sprintf() for formatting memory buffers. */
+
+void
+st_sprintf (char *buffer, const char *format, ...)
+{
+ va_list arg;
+ char c, *p;
+ int count;
+
+ va_start (arg, format);
+
+ for (;;)
+ {
+ c = *format++;
+ if (c != '%')
+ {
+ *buffer++ = c;
+ if (c == '\0')
+ break;
+ continue;
+ }
+
+ c = *format++;
+ switch (c)
+ {
+ case 'c':
+ *buffer++ = (char) va_arg (arg, int);
+ break;
+
+ case 'd':
+ p = itoa (va_arg (arg, int));
+ count = strlen (p);
+
+ memcpy (buffer, p, count);
+ buffer += count;
+ break;
+
+ case 's':
+ p = va_arg (arg, char *);
+ count = strlen (p);
+
+ memcpy (buffer, p, count);
+ buffer += count;
+ break;
+
+ default:
+ *buffer++ = c;
+ }
+ }
+
+ va_end (arg);
+}
+
+
+/* show_locus()-- Print a line number and filename describing where
+ * something went wrong */
+
+void
+show_locus (void)
+{
+
+ if (!options.locus || filename == NULL)
+ return;
+
+ st_printf ("At line %d of file %s\n", line, filename);
+}
+
+
+/* recursion_check()-- It's possible for additional errors to occur
+ * during fatal error processing. We detect this condition here and
+ * exit with code 4 immediately. */
+
+#define MAGIC 0x20DE8101
+
+static void
+recursion_check (void)
+{
+ static int magic = 0;
+
+ if (magic == MAGIC)
+ sys_exit (4); /* Don't even try to print something at this point */
+
+ magic = MAGIC;
+}
+
+
+/* os_error()-- Operating system error. We get a message from the
+ * operating system, show it and leave. Some operating system errors
+ * are caught and processed by the library. If not, we come here. */
+
+void
+os_error (const char *message)
+{
+
+ recursion_check ();
+
+ show_locus ();
+ st_printf ("Operating system error: %s\n%s\n", get_oserror (), message);
+
+ sys_exit (1);
+}
+
+
+/* void runtime_error()-- These are errors associated with an
+ * invalid fortran program. */
+
+void
+runtime_error (const char *message)
+{
+
+ recursion_check ();
+
+ show_locus ();
+ st_printf ("Fortran runtime error: %s\n", message);
+
+ sys_exit (2);
+}
+
+
+/* void internal_error()-- These are this-can't-happen errors
+ * that indicate something deeply wrong. */
+
+void
+internal_error (const char *message)
+{
+
+ recursion_check ();
+
+ show_locus ();
+ st_printf ("Internal Error: %s\n", message);
+ sys_exit (3);
+}
+
+
+/* translate_error()-- Given an integer error code, return a string
+ * describing the error. */
+
+const char *
+translate_error (int code)
+{
+ const char *p;
+
+ switch (code)
+ {
+ case ERROR_EOR:
+ p = "End of record";
+ break;
+
+ case ERROR_END:
+ p = "End of file";
+ break;
+
+ case ERROR_OK:
+ p = "Successful return";
+ break;
+
+ case ERROR_OS:
+ p = "Operating system error";
+ break;
+
+ case ERROR_BAD_OPTION:
+ p = "Bad statement option";
+ break;
+
+ case ERROR_MISSING_OPTION:
+ p = "Missing statement option";
+ break;
+
+ case ERROR_OPTION_CONFLICT:
+ p = "Conflicting statement options";
+ break;
+
+ case ERROR_ALREADY_OPEN:
+ p = "File already opened in another unit";
+ break;
+
+ case ERROR_BAD_UNIT:
+ p = "Unattached unit";
+ break;
+
+ case ERROR_FORMAT:
+ p = "FORMAT error";
+ break;
+
+ case ERROR_BAD_ACTION:
+ p = "Incorrect ACTION specified";
+ break;
+
+ case ERROR_ENDFILE:
+ p = "Read past ENDFILE record";
+ break;
+
+ case ERROR_BAD_US:
+ p = "Corrupt unformatted sequential file";
+ break;
+
+ case ERROR_READ_VALUE:
+ p = "Bad value during read";
+ break;
+
+ case ERROR_READ_OVERFLOW:
+ p = "Numeric overflow on read";
+ break;
+
+ default:
+ p = "Unknown error code";
+ break;
+ }
+
+ return p;
+}
+
+
+/* generate_error()-- Come here when an error happens. This
+ * subroutine is called if it is possible to continue on after the
+ * error. If an IOSTAT variable exists, we set it. If the IOSTAT or
+ * ERR label is present, we return, otherwise we terminate the program
+ * after print a message. The error code is always required but the
+ * message parameter can be NULL, in which case a string describing
+ * the most recent operating system error is used. */
+
+void
+generate_error (int family, const char *message)
+{
+
+ if (ioparm.iostat != NULL)
+ {
+ *ioparm.iostat = family;
+ return;
+ }
+
+ switch (family)
+ {
+ case ERROR_EOR:
+ ioparm.library_return = LIBRARY_EOR;
+ if (ioparm.eor != 0)
+ return;
+ break;
+
+ case ERROR_END:
+ ioparm.library_return = LIBRARY_END;
+ if (ioparm.end != 0)
+ return;
+ break;
+
+ default:
+ ioparm.library_return = LIBRARY_ERROR;
+ break;
+ }
+
+ if (ioparm.err != 0)
+ return;
+
+ /* Terminate the program */
+
+ if (message == NULL)
+ message =
+ (family == ERROR_OS) ? get_oserror () : translate_error (family);
+
+ runtime_error (message);
+}
diff --git a/libgfortran/runtime/in_pack_generic.c b/libgfortran/runtime/in_pack_generic.c
new file mode 100644
index 00000000000..8af4f3f0eb7
--- /dev/null
+++ b/libgfortran/runtime/in_pack_generic.c
@@ -0,0 +1,123 @@
+/* Generic helper function for repacking arrays.
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "libgfortran.h"
+
+void *
+internal_pack (gfc_array_char * source)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type stride[GFC_MAX_DIMENSIONS - 1];
+ index_type stride0;
+ index_type dim;
+ index_type ssize;
+ const char *src;
+ char *dest;
+ void *destptr;
+ int n;
+ int packed;
+ index_type size;
+
+ if (source->dim[0].stride == 0)
+ {
+ source->dim[0].stride = 1;
+ return source->data;
+ }
+
+ size = GFC_DESCRIPTOR_SIZE (source);
+ switch (size)
+ {
+ case 4:
+ return internal_pack_4 ((gfc_array_i4 *)source);
+
+ case 8:
+ return internal_pack_8 ((gfc_array_i8 *)source);
+ }
+
+ dim = GFC_DESCRIPTOR_RANK (source);
+ ssize = 1;
+ packed = 1;
+ for (n = 0; n < dim; n++)
+ {
+ count[n] = 0;
+ stride[n] = source->dim[n].stride;
+ extent[n] = source->dim[n].ubound + 1 - source->dim[n].lbound;
+ if (extent[n] <= 0)
+ {
+ /* Do nothing. */
+ packed = 1;
+ break;
+ }
+
+ if (ssize != stride[n])
+ packed = 0;
+
+ ssize *= extent[n];
+ }
+
+ if (packed)
+ return source->data;
+
+ /* Allocate storage for the destination. */
+ destptr = internal_malloc_size (ssize * size);
+ dest = (char *)destptr;
+ src = source->data;
+ stride0 = stride[0] * size;
+
+ while (src)
+ {
+ /* Copy the data. */
+ memcpy(dest, src, size);
+ /* Advance to the next element. */
+ dest += size;
+ src += stride0;
+ count[0]++;
+ /* Advance to the next source element. */
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ src -= stride[n] * extent[n] * size;
+ n++;
+ if (n == dim)
+ {
+ src = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ src += stride[n] * size;
+ }
+ }
+ }
+ return destptr;
+}
+
diff --git a/libgfortran/runtime/in_unpack_generic.c b/libgfortran/runtime/in_unpack_generic.c
new file mode 100644
index 00000000000..82a6771906f
--- /dev/null
+++ b/libgfortran/runtime/in_unpack_generic.c
@@ -0,0 +1,120 @@
+/* Generic helper function for repacking arrays.
+ Copyright 2003 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Ligbfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "libgfortran.h"
+
+void
+internal_unpack (gfc_array_char * d, const void * s)
+{
+ index_type count[GFC_MAX_DIMENSIONS - 1];
+ index_type extent[GFC_MAX_DIMENSIONS - 1];
+ index_type stride[GFC_MAX_DIMENSIONS - 1];
+ index_type stride0;
+ index_type dim;
+ index_type dsize;
+ char *dest;
+ const char *src;
+ int n;
+ int size;
+
+ dest = d->data;
+ /* This check may be redundant, but do it anyway. */
+ if (s == dest || !s)
+ return;
+
+ size = GFC_DESCRIPTOR_SIZE (d);
+ switch (size)
+ {
+ case 4:
+ internal_unpack_4 ((gfc_array_i4 *)d, (const GFC_INTEGER_4 *)s);
+ return;
+
+ case 8:
+ internal_unpack_8 ((gfc_array_i8 *)d, (const GFC_INTEGER_8 *)s);
+ return;
+ }
+
+ if (d->dim[0].stride == 0)
+ d->dim[0].stride = 1;
+
+ dim = GFC_DESCRIPTOR_RANK (d);
+ dsize = 1;
+ for (n = 0; n < dim; n++)
+ {
+ count[n] = 0;
+ stride[n] = d->dim[n].stride;
+ extent[n] = d->dim[n].ubound + 1 - d->dim[n].lbound;
+ if (extent[n] <= 0)
+ abort ();
+
+ if (dsize == stride[n])
+ dsize *= extent[n];
+ else
+ dsize = 0;
+ }
+
+ src = s;
+
+ if (dsize != 0)
+ {
+ memcpy (dest, src, dsize * size);
+ return;
+ }
+
+ stride0 = stride[0] * size;
+
+ while (dest)
+ {
+ /* Copy the data. */
+ memcpy (dest, src, size);
+ /* Advance to the next element. */
+ src += size;
+ dest += stride0;
+ count[0]++;
+ /* Advance to the next source element. */
+ n = 0;
+ while (count[n] == extent[n])
+ {
+ /* When we get to the end of a dimension, reset it and increment
+ the next dimension. */
+ count[n] = 0;
+ /* We could precalculate these products, but this is a less
+ frequently used path so proabably not worth it. */
+ dest -= stride[n] * extent[n] * size;
+ n++;
+ if (n == dim)
+ {
+ dest = NULL;
+ break;
+ }
+ else
+ {
+ count[n]++;
+ dest += stride[n] * size;
+ }
+ }
+ }
+}
+
diff --git a/libgfortran/runtime/main.c b/libgfortran/runtime/main.c
new file mode 100644
index 00000000000..e3eaf2b2ffc
--- /dev/null
+++ b/libgfortran/runtime/main.c
@@ -0,0 +1,115 @@
+/* Copyright (C) 2002-2003 Free Software Foundation, Inc.
+ Contributed by Andy Vaught and Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor 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 2, or (at your option)
+any later version.
+
+Libgfor 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 libgfor; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <stddef.h>
+
+#include "libgfortran.h"
+
+/* This is the offset (in bytes) required to cast from logical(8)* to
+ logical(4)*. and still get the same result. Will be 0 for little-endian
+ machines and 4 for big-endian machines. */
+int l8_to_l4_offset;
+
+
+/* Figure out endianness for this machine. */
+
+#define detetmine_endianness prefix(determine_endianness)
+static void
+determine_endianness (void)
+{
+ union
+ {
+ GFC_LOGICAL_8 l8;
+ GFC_LOGICAL_4 l4[2];
+ } u;
+
+ u.l8 = 1;
+ if (u.l4[0])
+ l8_to_l4_offset = 0;
+ else if (u.l4[1])
+ l8_to_l4_offset = 1;
+ else
+ runtime_error ("Unable to determine machine endianness");
+}
+
+
+static int argc_save;
+static char **argv_save;
+
+/* Set the saved values of the command line arguments. */
+
+void
+set_args (int argc, char **argv)
+{
+ argc_save = argc;
+ argv_save = argv;
+}
+
+/* Retrieve the saved values of the command line arguments. */
+
+void
+get_args (int *argc, char ***argv)
+{
+
+ *argc = argc_save;
+ *argv = argv_save;
+}
+
+
+/* Initialize the runtime library. */
+
+static void __attribute__((constructor))
+init (void)
+{
+ /* Figure out the machine endianness. */
+ determine_endianness ();
+
+ /* Must be first */
+ init_variables ();
+
+ init_units ();
+
+#ifdef DEBUG
+ /* Check for special command lines. */
+
+ if (argc > 1 && strcmp (argv[1], "--help") == 0)
+ show_variables ();
+
+/* if (argc > 1 && strcmp(argv[1], "--resume") == 0) resume(); */
+#endif
+
+ memory_init ();
+ random_seed(NULL,NULL,NULL);
+
+}
+
+
+/* Cleanup the runtime library. */
+
+static void __attribute__((destructor))
+cleanup ()
+{
+ close_units ();
+}
+
diff --git a/libgfortran/runtime/memory.c b/libgfortran/runtime/memory.c
new file mode 100644
index 00000000000..ca5eb15244b
--- /dev/null
+++ b/libgfortran/runtime/memory.c
@@ -0,0 +1,312 @@
+/* Memory mamagement routines.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <stdlib.h>
+#include "libgfortran.h"
+
+/* If GFC_CLEAR_MEMORY is defined, the memory allocation routines will
+ return memory that is guaranteed to be set to zero. This can have
+ a severe efficiency penalty, so it should never be set if good
+ performance is desired, but it can help when you're debugging code. */
+#define GFC_CLEAR_MEMORY
+
+/* If GFC_CHECK_MEMORY is defined, we do some sanity checks at runtime.
+ This causes small overhead, but again, it also helps debugging. */
+#define GFC_CHECK_MEMORY
+
+/* We use a double linked list of these structures to keep track of
+ the memory we allocate internally. We could also use this for user
+ allocated memory (ALLOCATE/DEALLOCATE). This should be stored in a
+ seperate list. */
+#define malloc_t prefix(malloc_t)
+typedef struct malloc_t
+{
+ int magic;
+ int marker;
+ struct malloc_t *prev, *next;
+
+ /* The start of the block. */
+ void *data;
+}
+malloc_t;
+
+/* We try to make sure we don't get memory corruption by checking for
+ a magic number. */
+#define GFC_MALLOC_MAGIC 0x4d353941 /* "G95M" */
+
+#define HEADER_SIZE offsetof (malloc_t, data)
+#define DATA_POINTER(pheader) (&((pheader)->data))
+#define DATA_HEADER(pdata) ((malloc_t *)((char *) (pdata) - HEADER_SIZE))
+
+/* The root of the circular double linked list for compiler generated
+ malloc calls. */
+static malloc_t mem_root;
+
+
+void
+memory_init (void)
+{
+
+ /* The root should never be used directly, so don't set the magic. */
+ mem_root.magic = 0;
+ mem_root.next = &mem_root;
+ mem_root.prev = &mem_root;
+ mem_root.marker = 0;
+}
+
+
+/* Doesn't actually do any cleaning up, just throws an error if something
+ has got out of sync somewhere. */
+
+void
+runtime_cleanup (void)
+{
+ /* Make sure all memory we've allocated is freed on exit. */
+ if (mem_root.next != &mem_root)
+ runtime_error ("Unfreed memory on program termination");
+}
+
+
+
+void *
+get_mem (size_t n)
+{
+ void *p;
+
+#ifdef GFC_CLEAR_MEMORY
+ p = (void *) calloc (n, 1);
+#else
+#define temp malloc
+#undef malloc
+ p = (void *) malloc (n);
+#define malloc temp
+#undef temp
+#endif
+ if (p == NULL)
+ os_error ("Memory allocation failed");
+
+ return p;
+}
+
+
+void
+free_mem (void *p)
+{
+
+ free (p);
+}
+
+
+/* Allocates a block of memory with a size of N bytes. N does not
+ include the size of the header. */
+
+static malloc_t *
+malloc_with_header (size_t n)
+{
+ malloc_t *newmem;
+
+ n = n + HEADER_SIZE;
+
+ newmem = (malloc_t *) get_mem (n);
+
+ if (newmem)
+ {
+ newmem->magic = GFC_MALLOC_MAGIC;
+ newmem->marker = 0;
+ }
+
+ return newmem;
+}
+
+
+/* Allocate memory for internal (compiler generated) use. */
+
+void *
+internal_malloc_size (size_t size)
+{
+ malloc_t *newmem;
+
+ newmem = malloc_with_header (size);
+
+ if (!newmem)
+ os_error ("Out of memory.");
+
+ /* Add to end of list. */
+ newmem->next = &mem_root;
+ newmem->prev = mem_root.prev;
+ mem_root.prev->next = newmem;
+ mem_root.prev = newmem;
+
+ return DATA_POINTER (newmem);
+}
+
+
+void *
+internal_malloc (GFC_INTEGER_4 size)
+{
+#ifdef GFC_CHECK_MEMORY
+ /* Under normal circumstances, this is _never_ going to happen! */
+ if (size <= 0)
+ runtime_error ("Attempt to allocate a non-positive amount of memory.");
+
+#endif
+ return internal_malloc_size ((size_t) size);
+}
+
+
+void *
+internal_malloc64 (GFC_INTEGER_8 size)
+{
+#ifdef GFC_CHECK_MEMORY
+ /* Under normal circumstances, this is _never_ going to happen! */
+ if (size <= 0)
+ runtime_error ("Attempt to allocate a non-positive amount of memory.");
+#endif
+ return internal_malloc_size ((size_t) size);
+}
+
+
+/* Free internally allocated memory. Pointer is NULLified. Also used to
+ free user allocated memory. */
+/* TODO: keep a list of previously allocated blocks and reuse them. */
+
+void
+internal_free (void *mem)
+{
+ malloc_t *m;
+
+ if (!mem)
+ runtime_error ("Internal: Possible double free of temporary.");
+
+ m = DATA_HEADER (mem);
+
+ if (m->magic != GFC_MALLOC_MAGIC)
+ runtime_error ("Internal: No magic memblock marker. "
+ "Possible memory corruption");
+
+ /* Move markers up the chain, so they don't get lost. */
+ m->prev->marker += m->marker;
+ /* Remove from list. */
+ m->prev->next = m->next;
+ m->next->prev = m->prev;
+
+ free (m);
+}
+
+
+/* User-allocate, one call for each member of the alloc-list of an
+ ALLOCATE statement. */
+
+static void
+allocate_size (void **mem, size_t size, GFC_INTEGER_4 * stat)
+{
+ malloc_t *newmem;
+
+ if (!mem)
+ runtime_error ("Internal: NULL mem pointer in ALLOCATE.");
+
+ newmem = malloc_with_header (size);
+ if (!newmem)
+ {
+ if (stat)
+ {
+ *stat = 1;
+ return;
+ }
+ else
+ runtime_error ("ALLOCATE: Out of memory.");
+ }
+
+ /* We don't keep a list of these at the moment, so just link to itself. */
+ newmem->next = newmem;
+ newmem->prev = newmem;
+
+ (*mem) = DATA_POINTER (newmem);
+
+ if (stat)
+ *stat = 0;
+}
+
+
+void
+allocate (void **mem, GFC_INTEGER_4 size, GFC_INTEGER_4 * stat)
+{
+
+ if (size < 0)
+ {
+ runtime_error ("Attempt to allocate negative amount of memory. "
+ "Possible integer overflow");
+ abort ();
+ }
+
+ allocate_size (mem, (size_t) size, stat);
+}
+
+
+void
+allocate64 (void **mem, GFC_INTEGER_8 size, GFC_INTEGER_4 * stat)
+{
+
+ if (size < 0)
+ {
+ runtime_error
+ ("ALLOCATE64: Attempt to allocate negative amount of memory. "
+ "Possible integer overflow");
+ abort ();
+ }
+
+ allocate_size (mem, (size_t) size, stat);
+}
+
+
+/* User-deallocate; pointer is NULLified. */
+
+void
+deallocate (void **mem, GFC_INTEGER_4 * stat)
+{
+
+ if (!mem)
+ runtime_error ("Internal: NULL mem pointer in ALLOCATE.");
+
+ if (!*mem)
+ {
+ if (stat)
+ {
+ *stat = 1;
+ return;
+ }
+ else
+ {
+ runtime_error
+ ("Internal: Attempt to DEALLOCATE unallocated memory.");
+ abort ();
+ }
+ }
+
+ /* Just use the internal routine. */
+ internal_free (*mem);
+ *mem = NULL;
+
+ if (stat)
+ *stat = 0;
+}
+
diff --git a/libgfortran/runtime/pause.c b/libgfortran/runtime/pause.c
new file mode 100644
index 00000000000..9b8447f66c9
--- /dev/null
+++ b/libgfortran/runtime/pause.c
@@ -0,0 +1,71 @@
+/* Implementation of the STOP statement.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <string.h>
+#include <stdio.h>
+
+#include "libgfortran.h"
+
+#define pause_numeric prefix(pause_numeric)
+#define pause_string prefix(pause_string)
+
+static void
+do_pause (void)
+{
+ char buff[4];
+ st_printf ("To resume execution, type go. "
+ "Other input will terminate the job.\n");
+
+ fgets(buff, 4, stdin);
+ if (strncmp(buff, "go\n", 3) != 0)
+ stop_numeric (-1);
+ st_printf ("RESUMED\n");
+}
+
+/* A numeric or blank STOP statement. */
+void
+pause_numeric (GFC_INTEGER_4 code)
+{
+ show_locus ();
+
+ if (code == -1)
+ st_printf ("PAUSE\n");
+ else
+ st_printf ("PAUSE %d\n", (int)code);
+
+ do_pause ();
+}
+
+
+void
+pause_string (char *string, GFC_INTEGER_4 len)
+{
+ show_locus ();
+
+ st_printf ("PAUSE ");
+ while (len--)
+ st_printf ("%c", *(string++));
+ st_printf ("\n");
+
+ do_pause ();
+}
+
diff --git a/libgfortran/runtime/select.c b/libgfortran/runtime/select.c
new file mode 100644
index 00000000000..5ee873aefcb
--- /dev/null
+++ b/libgfortran/runtime/select.c
@@ -0,0 +1,125 @@
+/* Implement the SELECT statement for character variables.
+ Contributed by Andy Vaught
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor 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 2, or (at your option)
+any later version.
+
+Libgfor 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 libgfor; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "libgfortran.h"
+
+typedef struct
+{
+ char *low;
+ int low_len;
+ char *high;
+ int high_len;
+ void *address;
+}
+select_struct;
+
+
+#define select_string prefix(select_string)
+
+
+/* select_string()-- Given a selector string and a table of
+ * select_struct structures, return the address to jump to. */
+
+void *select_string (select_struct *table, int table_len, void *default_jump,
+ const char *selector, int selector_len)
+{
+ select_struct *t;
+ int i, low, high, mid;
+
+ if (table_len == 0)
+ return default_jump;
+
+ /* Record the default address if present */
+
+ if (table->low == NULL && table->high == NULL)
+ {
+ default_jump = table->address;
+
+ table++;
+ table_len--;
+ if (table_len == 0)
+ return default_jump;
+ }
+
+ /* Try the high and low bounds if present. */
+
+ if (table->low == NULL)
+ {
+ if (compare_string (table->high_len, table->high,
+ selector_len, selector) >= 0)
+ return table->address;
+
+ table++;
+ table_len--;
+ if (table_len == 0)
+ return default_jump;
+ }
+
+ t = table + table_len - 1;
+
+ if (t->high == NULL)
+ {
+ if (compare_string (t->low_len, t->low,
+ selector_len, selector) <= 0)
+ return t->address;
+
+ table_len--;
+ if (table_len == 0)
+ return default_jump;
+ }
+
+ /* At this point, the only table entries are bounded entries. Find
+ the right entry with a binary chop. */
+
+ low = -1;
+ high = table_len;
+
+ while (low + 1 < high)
+ {
+ mid = (low + high) / 2;
+
+ t = table + mid;
+ i = compare_string (t->low_len, t->low, selector_len, selector);
+
+ if (i == 0)
+ return t->address;
+
+ if (i < 0)
+ low = mid;
+ else
+ high = mid;
+ }
+
+ /* The string now lies between the low indeces of the now-adjacent
+ high and low entries. Because it is less than the low entry of
+ 'high', it can't be that one. If low is still -1, then no
+ entries match. Otherwise, we have to check the high entry of
+ 'low'. */
+
+ if (low == -1)
+ return default_jump;
+
+ t = table + low;
+ if (compare_string (selector_len, selector,
+ t->high_len, t->high) <= 0)
+ return t->address;
+
+ return default_jump;
+}
diff --git a/libgfortran/runtime/stop.c b/libgfortran/runtime/stop.c
new file mode 100644
index 00000000000..bc901bbad96
--- /dev/null
+++ b/libgfortran/runtime/stop.c
@@ -0,0 +1,56 @@
+/* Implementation of the STOP statement.
+ Copyright 2002 Free Software Foundation, Inc.
+ Contributed by Paul Brook <paul@nowt.org>
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+Libgfor 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with libgfor; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <string.h>
+
+#include "libgfortran.h"
+
+#define stop_string prefix(stop_string)
+
+/* A numeric or blank STOP statement. */
+void
+stop_numeric (GFC_INTEGER_4 code)
+{
+ show_locus ();
+
+ if (code == -1)
+ st_printf ("STOP\n");
+ else
+ st_printf ("STOP %d\n", (int)code);
+
+ sys_exit (code);
+}
+
+
+void
+stop_string (const char *string, GFC_INTEGER_4 len)
+{
+ show_locus ();
+
+ st_printf ("STOP ");
+ while (len--)
+ st_printf ("%c", *(string++));
+ st_printf ("\n");
+
+ sys_exit (0);
+}
+
diff --git a/libgfortran/runtime/string.c b/libgfortran/runtime/string.c
new file mode 100644
index 00000000000..bcd60928da6
--- /dev/null
+++ b/libgfortran/runtime/string.c
@@ -0,0 +1,120 @@
+/* Copyright (C) 2002-2003 Free Software Foundation, Inc.
+ Contributed by Paul Brook
+
+This file is part of the GNU Fortran 95 runtime library (libgfor).
+
+Libgfor 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 2, or (at your option)
+any later version.
+
+Libgfor 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 libgfor; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include <string.h>
+
+#include "libgfortran.h"
+
+
+/* Compare a C-style string with a fortran style string in a case-insensitive
+ manner. Used for decoding string options to various statements. Returns
+ zero if not equal, nonzero if equal. */
+
+static int
+compare0 (const char *s1, int s1_len, const char *s2)
+{
+ int i;
+
+ if (strncasecmp (s1, s2, s1_len) != 0)
+ return 0;
+
+ /* The rest of s1 needs to be blanks for equality. */
+
+ for (i = strlen (s2); i < s1_len; i++)
+ if (s1[i] != ' ')
+ return 0;
+
+ return 1;
+}
+
+
+/* Given a fortran string, return its length exclusive of the trailing
+ spaces. */
+int
+fstrlen (const char *string, int len)
+{
+
+ for (len--; len >= 0; len--)
+ if (string[len] != ' ')
+ break;
+
+ return len + 1;
+}
+
+
+
+void
+fstrcpy (char *dest, int destlen, const char *src, int srclen)
+{
+
+ if (srclen >= destlen)
+ {
+ /* This will truncate if too long. */
+ memcpy (dest, src, destlen);
+ }
+ else
+ {
+ memcpy (dest, src, srclen);
+ /* Pad with spaces. */
+ memset (&dest[srclen], ' ', destlen - srclen);
+ }
+}
+
+
+void
+cf_strcpy (char *dest, int dest_len, const char *src)
+{
+ int src_len;
+
+ src_len = strlen (src);
+
+ if (src_len >= dest_len)
+ {
+ /* This will truncate if too long. */
+ memcpy (dest, src, dest_len);
+ }
+ else
+ {
+ memcpy (dest, src, src_len);
+ /* Pad with spaces. */
+ memset (&dest[src_len], ' ', dest_len - src_len);
+ }
+}
+
+
+/* Given a fortran string and an array of st_option structures, search through
+ the array to find a match. If the option is not found, we generate an error
+ if no default is provided. */
+
+int
+find_option (const char *s1, int s1_len, st_option * opts,
+ const char *error_message)
+{
+
+ for (; opts->name; opts++)
+ if (compare0 (s1, s1_len, opts->name))
+ return opts->value;
+
+ generate_error (ERROR_BAD_OPTION, error_message);
+
+ return -1;
+}
+
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index 661ca4b45b9..82547e29bfe 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,37 @@
+2004-04-29 Douglas B Rupp <rupp@gnat.com>
+
+ * mkstemps.c (mkstemps) [VMS]: Remove special open option. Update
+ copyright.
+
+2004-04-26 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * configure.ac (UNSIGNED_64BIT_TYPE): Unquote the definition.
+ * configure: Regenerate.
+
+2004-04-22 Richard Henderson <rth@redhat.com>
+
+ * hashtab.c: Include limits.h, stdint.h, ansidecl.h.
+ (CHAR_BIT): Provide default.
+ (struct prime_ent, prime_tab): New.
+ (higher_prime_index): Rename from higher_prime_number, return index.
+ (htab_mod_1): New.
+ (htab_mod, htab_mod_m2): Use it.
+ (htab_create_alloc, htab_create_alloc_ex): Store prime index.
+ (htab_expand): Likewise.
+ * configure.ac: Check for stdint.h.
+ (UNSIGNED_64BIT_TYPE): New define and checks to fill it in.
+ * config.in, configure: Rebuild.
+
+2004-04-13 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * strerror.c: Include config.h, and redefine sys_nerr and
+ sys_errlist, before including ansidecl.h and libiberty.h.
+
+2004-04-13 Jeff Law <law@redhat.com>
+
+ * hashtab.c (htab_remove_elt_with_hash): New function.
+ (htab_remove_elt): Implement in terms of htab_remove_elt_with_hash.
+
2004-03-31 Richard Henderson <rth@redhat.com>
* hashtab.c (htab_size): Move to top of file; mark inline.
diff --git a/libiberty/config.in b/libiberty/config.in
index 99ee0826708..3cce9aa1979 100644
--- a/libiberty/config.in
+++ b/libiberty/config.in
@@ -353,6 +353,9 @@
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
+/* Define to an unsigned 64-bit type available in the compiler. */
+#undef UNSIGNED_64BIT_TYPE
+
/* whether byteorder is bigendian */
#undef WORDS_BIGENDIAN
diff --git a/libiberty/configure b/libiberty/configure
index 374d11b9321..e44984c1fbe 100755
--- a/libiberty/configure
+++ b/libiberty/configure
@@ -1305,6 +1305,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
# This works around the fact that libtool configuration may change LD
# for this particular configuration, but some shells, instead of
# keeping the changes in LD private, export them just because LD is
@@ -3538,7 +3539,8 @@ host_makefile_frag=${frag}
-for ac_header in sys/file.h sys/param.h limits.h stdlib.h malloc.h string.h unistd.h strings.h sys/time.h time.h sys/resource.h sys/stat.h sys/mman.h fcntl.h alloca.h sys/pstat.h sys/sysmp.h sys/sysinfo.h machine/hal_sysinfo.h sys/table.h sys/sysctl.h sys/systemcfg.h
+
+for ac_header in sys/file.h sys/param.h limits.h stdlib.h malloc.h string.h unistd.h strings.h sys/time.h time.h sys/resource.h sys/stat.h sys/mman.h fcntl.h alloca.h sys/pstat.h sys/sysmp.h sys/sysinfo.h machine/hal_sysinfo.h sys/table.h sys/sysctl.h sys/systemcfg.h stdint.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_header" >&5
@@ -4102,6 +4104,170 @@ _ACEOF
fi
+
+# Look for a 64-bit type.
+echo "$as_me:$LINENO: checking for a 64-bit type" >&5
+echo $ECHO_N "checking for a 64-bit type... $ECHO_C" >&6
+if test "${liberty_cv_uint64+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+int
+main ()
+{
+extern uint64_t foo;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ liberty_cv_uint64=uint64_t
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+int
+main ()
+{
+extern char foo[sizeof(long) * CHAR_BIT >= 64 ? 1 : -1];
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ liberty_cv_uint64="unsigned long"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+int
+main ()
+{
+extern char foo[sizeof(long long) * CHAR_BIT >= 64 ? 1 : -1];
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ liberty_cv_uint64="unsigned long long"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+liberty_cv_uint64=none
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+echo "$as_me:$LINENO: result: $liberty_cv_uint64" >&5
+echo "${ECHO_T}$liberty_cv_uint64" >&6
+if test "$liberty_cv_uint64" != none; then
+
+cat >>confdefs.h <<_ACEOF
+#define UNSIGNED_64BIT_TYPE $liberty_cv_uint64
+_ACEOF
+
+fi
+
# Given the above check, we always have uintptr_t or a fallback
# definition. So define HAVE_UINTPTR_T in case any imported code
# relies on it.
@@ -6601,7 +6767,9 @@ LIBOBJS="$L"
# We need multilib support, but only if configuring for the target.
ac_config_files="$ac_config_files Makefile testsuite/Makefile"
+
ac_config_commands="$ac_config_commands default"
+
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
diff --git a/libiberty/configure.ac b/libiberty/configure.ac
index 39bfb51e416..42fe85d2e6f 100644
--- a/libiberty/configure.ac
+++ b/libiberty/configure.ac
@@ -159,13 +159,47 @@ AC_SUBST_FILE(host_makefile_frag)
# It's OK to check for header files. Although the compiler may not be
# able to link anything, it had better be able to at least compile
# something.
-AC_CHECK_HEADERS(sys/file.h sys/param.h limits.h stdlib.h malloc.h string.h unistd.h strings.h sys/time.h time.h sys/resource.h sys/stat.h sys/mman.h fcntl.h alloca.h sys/pstat.h sys/sysmp.h sys/sysinfo.h machine/hal_sysinfo.h sys/table.h sys/sysctl.h sys/systemcfg.h)
+AC_CHECK_HEADERS(sys/file.h sys/param.h limits.h stdlib.h malloc.h string.h unistd.h strings.h sys/time.h time.h sys/resource.h sys/stat.h sys/mman.h fcntl.h alloca.h sys/pstat.h sys/sysmp.h sys/sysinfo.h machine/hal_sysinfo.h sys/table.h sys/sysctl.h sys/systemcfg.h stdint.h)
AC_HEADER_SYS_WAIT
AC_HEADER_TIME
libiberty_AC_DECLARE_ERRNO
AC_CHECK_TYPE(uintptr_t, unsigned long)
+
+# Look for a 64-bit type.
+AC_MSG_CHECKING([for a 64-bit type])
+AC_CACHE_VAL(liberty_cv_uint64,
+[AC_TRY_COMPILE(
+[#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif],
+[extern uint64_t foo;],
+liberty_cv_uint64=uint64_t,
+[AC_TRY_COMPILE(
+[#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif],
+[extern char foo[sizeof(long) * CHAR_BIT >= 64 ? 1 : -1];],
+liberty_cv_uint64="unsigned long",
+[AC_TRY_COMPILE(
+[#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif],
+[extern char foo[sizeof(long long) * CHAR_BIT >= 64 ? 1 : -1];],
+liberty_cv_uint64="unsigned long long", liberty_cv_uint64=none)])])])
+AC_MSG_RESULT($liberty_cv_uint64)
+if test "$liberty_cv_uint64" != none; then
+ AC_DEFINE_UNQUOTED(UNSIGNED_64BIT_TYPE, $liberty_cv_uint64,
+ [Define to an unsigned 64-bit type available in the compiler.])
+fi
+
# Given the above check, we always have uintptr_t or a fallback
# definition. So define HAVE_UINTPTR_T in case any imported code
# relies on it.
diff --git a/libiberty/hashtab.c b/libiberty/hashtab.c
index f7751664f04..6e7a44b9c91 100644
--- a/libiberty/hashtab.c
+++ b/libiberty/hashtab.c
@@ -1,5 +1,6 @@
/* An expandable hash tables datatype.
- Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by Vladimir Makarov (vmakarov@cygnus.com).
This file is part of the libiberty library.
@@ -40,20 +41,29 @@ Boston, MA 02111-1307, USA. */
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
-
#ifdef HAVE_STRING_H
#include <string.h>
#endif
-
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
#include <stdio.h>
#include "libiberty.h"
+#include "ansidecl.h"
#include "hashtab.h"
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
/* This macro defines reserved value for empty table entry. */
#define EMPTY_ENTRY ((PTR) 0)
@@ -63,7 +73,10 @@ Boston, MA 02111-1307, USA. */
#define DELETED_ENTRY ((PTR) 1)
-static unsigned long higher_prime_number PARAMS ((unsigned long));
+static unsigned int higher_prime_index PARAMS ((unsigned long));
+static hashval_t htab_mod_1 PARAMS ((hashval_t, hashval_t, hashval_t, int));
+static hashval_t htab_mod PARAMS ((hashval_t, htab_t));
+static hashval_t htab_mod_m2 PARAMS ((hashval_t, htab_t));
static hashval_t hash_pointer PARAMS ((const void *));
static int eq_pointer PARAMS ((const void *, const void *));
static int htab_expand PARAMS ((htab_t));
@@ -75,69 +88,117 @@ static PTR *find_empty_slot_for_expand PARAMS ((htab_t, hashval_t));
htab_hash htab_hash_pointer = hash_pointer;
htab_eq htab_eq_pointer = eq_pointer;
-/* The following function returns a nearest prime number which is
- greater than N, and near a power of two. */
+/* Table of primes and multiplicative inverses.
+
+ Note that these are not minimally reduced inverses. Unlike when generating
+ code to divide by a constant, we want to be able to use the same algorithm
+ all the time. All of these inverses (are implied to) have bit 32 set.
+
+ For the record, here's the function that computed the table; it's a
+ vastly simplified version of the function of the same name from gcc. */
+
+#if 0
+unsigned int
+ceil_log2 (unsigned int x)
+{
+ int i;
+ for (i = 31; i >= 0 ; --i)
+ if (x > (1u << i))
+ return i+1;
+ abort ();
+}
+
+unsigned int
+choose_multiplier (unsigned int d, unsigned int *mlp, unsigned char *shiftp)
+{
+ unsigned long long mhigh;
+ double nx;
+ int lgup, post_shift;
+ int pow, pow2;
+ int n = 32, precision = 32;
+
+ lgup = ceil_log2 (d);
+ pow = n + lgup;
+ pow2 = n + lgup - precision;
+
+ nx = ldexp (1.0, pow) + ldexp (1.0, pow2);
+ mhigh = nx / d;
+
+ *shiftp = lgup - 1;
+ *mlp = mhigh;
+ return mhigh >> 32;
+}
+#endif
-static unsigned long
-higher_prime_number (n)
+struct prime_ent
+{
+ hashval_t prime;
+ hashval_t inv;
+ hashval_t inv_m2; /* inverse of prime-2 */
+ hashval_t shift;
+};
+
+static struct prime_ent const prime_tab[] = {
+ { 7, 0x24924925, 0x9999999b, 2 },
+ { 13, 0x3b13b13c, 0x745d1747, 3 },
+ { 31, 0x08421085, 0x1a7b9612, 4 },
+ { 61, 0x0c9714fc, 0x15b1e5f8, 5 },
+ { 127, 0x02040811, 0x0624dd30, 6 },
+ { 251, 0x05197f7e, 0x073260a5, 7 },
+ { 509, 0x01824366, 0x02864fc8, 8 },
+ { 1021, 0x00c0906d, 0x014191f7, 9 },
+ { 2039, 0x0121456f, 0x0161e69e, 10 },
+ { 4093, 0x00300902, 0x00501908, 11 },
+ { 8191, 0x00080041, 0x00180241, 12 },
+ { 16381, 0x000c0091, 0x00140191, 13 },
+ { 32749, 0x002605a5, 0x002a06e6, 14 },
+ { 65521, 0x000f00e2, 0x00110122, 15 },
+ { 131071, 0x00008001, 0x00018003, 16 },
+ { 262139, 0x00014002, 0x0001c004, 17 },
+ { 524287, 0x00002001, 0x00006001, 18 },
+ { 1048573, 0x00003001, 0x00005001, 19 },
+ { 2097143, 0x00004801, 0x00005801, 20 },
+ { 4194301, 0x00000c01, 0x00001401, 21 },
+ { 8388593, 0x00001e01, 0x00002201, 22 },
+ { 16777213, 0x00000301, 0x00000501, 23 },
+ { 33554393, 0x00001381, 0x00001481, 24 },
+ { 67108859, 0x00000141, 0x000001c1, 25 },
+ { 134217689, 0x000004e1, 0x00000521, 26 },
+ { 268435399, 0x00000391, 0x000003b1, 27 },
+ { 536870909, 0x00000019, 0x00000029, 28 },
+ { 1073741789, 0x0000008d, 0x00000095, 29 },
+ { 2147483647, 0x00000003, 0x00000007, 30 },
+ /* Avoid "decimal constant so large it is unsigned" for 4294967291. */
+ { 0xfffffffb, 0x00000006, 0x00000008, 31 }
+};
+
+/* The following function returns an index into the above table of the
+ nearest prime number which is greater than N, and near a power of two. */
+
+static unsigned int
+higher_prime_index (n)
unsigned long n;
{
- /* These are primes that are near, but slightly smaller than, a
- power of two. */
- static const unsigned long primes[] = {
- (unsigned long) 7,
- (unsigned long) 13,
- (unsigned long) 31,
- (unsigned long) 61,
- (unsigned long) 127,
- (unsigned long) 251,
- (unsigned long) 509,
- (unsigned long) 1021,
- (unsigned long) 2039,
- (unsigned long) 4093,
- (unsigned long) 8191,
- (unsigned long) 16381,
- (unsigned long) 32749,
- (unsigned long) 65521,
- (unsigned long) 131071,
- (unsigned long) 262139,
- (unsigned long) 524287,
- (unsigned long) 1048573,
- (unsigned long) 2097143,
- (unsigned long) 4194301,
- (unsigned long) 8388593,
- (unsigned long) 16777213,
- (unsigned long) 33554393,
- (unsigned long) 67108859,
- (unsigned long) 134217689,
- (unsigned long) 268435399,
- (unsigned long) 536870909,
- (unsigned long) 1073741789,
- (unsigned long) 2147483647,
- /* 4294967291L */
- ((unsigned long) 2147483647) + ((unsigned long) 2147483644),
- };
-
- const unsigned long *low = &primes[0];
- const unsigned long *high = &primes[sizeof(primes) / sizeof(primes[0])];
+ unsigned int low = 0;
+ unsigned int high = sizeof(prime_tab) / sizeof(prime_tab[0]);
while (low != high)
{
- const unsigned long *mid = low + (high - low) / 2;
- if (n > *mid)
+ unsigned int mid = low + (high - low) / 2;
+ if (n > prime_tab[mid].prime)
low = mid + 1;
else
high = mid;
}
/* If we've run out of primes, abort. */
- if (n > *low)
+ if (n > prime_tab[low].prime)
{
fprintf (stderr, "Cannot find prime bigger than %lu\n", n);
abort ();
}
- return *low;
+ return low;
}
/* Returns a hash code for P. */
@@ -177,6 +238,36 @@ htab_elements (htab)
return htab->n_elements - htab->n_deleted;
}
+/* Return X % Y. */
+
+static inline hashval_t
+htab_mod_1 (x, y, inv, shift)
+ hashval_t x, y, inv;
+ int shift;
+{
+ /* The multiplicative inverses computed above are for 32-bit types, and
+ requires that we be able to compute a highpart multiply. */
+#ifdef UNSIGNED_64BIT_TYPE
+ __extension__ typedef UNSIGNED_64BIT_TYPE ull;
+ if (sizeof (hashval_t) * CHAR_BIT <= 32)
+ {
+ hashval_t t1, t2, t3, t4, q, r;
+
+ t1 = ((ull)x * inv) >> 32;
+ t2 = x - t1;
+ t3 = t2 >> 1;
+ t4 = t1 + t3;
+ q = t4 >> shift;
+ r = x - (q * y);
+
+ return r;
+ }
+#endif
+
+ /* Otherwise just use the native division routines. */
+ return x % y;
+}
+
/* Compute the primary hash for HASH given HTAB's current size. */
static inline hashval_t
@@ -184,7 +275,8 @@ htab_mod (hash, htab)
hashval_t hash;
htab_t htab;
{
- return hash % htab_size (htab);
+ const struct prime_ent *p = &prime_tab[htab->size_prime_index];
+ return htab_mod_1 (hash, p->prime, p->inv, p->shift);
}
/* Compute the secondary hash for HASH given HTAB's current size. */
@@ -194,7 +286,8 @@ htab_mod_m2 (hash, htab)
hashval_t hash;
htab_t htab;
{
- return 1 + hash % (htab_size (htab) - 2);
+ const struct prime_ent *p = &prime_tab[htab->size_prime_index];
+ return 1 + htab_mod_1 (hash, p->prime - 2, p->inv_m2, p->shift);
}
/* This function creates table with length slightly longer than given
@@ -212,8 +305,11 @@ htab_create_alloc (size, hash_f, eq_f, del_f, alloc_f, free_f)
htab_free free_f;
{
htab_t result;
+ unsigned int size_prime_index;
+
+ size_prime_index = higher_prime_index (size);
+ size = prime_tab[size_prime_index].prime;
- size = higher_prime_number (size);
result = (htab_t) (*alloc_f) (1, sizeof (struct htab));
if (result == NULL)
return NULL;
@@ -225,6 +321,7 @@ htab_create_alloc (size, hash_f, eq_f, del_f, alloc_f, free_f)
return NULL;
}
result->size = size;
+ result->size_prime_index = size_prime_index;
result->hash_f = hash_f;
result->eq_f = eq_f;
result->del_f = del_f;
@@ -248,8 +345,11 @@ htab_create_alloc_ex (size, hash_f, eq_f, del_f, alloc_arg, alloc_f,
htab_free_with_arg free_f;
{
htab_t result;
+ unsigned int size_prime_index;
+
+ size_prime_index = higher_prime_index (size);
+ size = prime_tab[size_prime_index].prime;
- size = higher_prime_number (size);
result = (htab_t) (*alloc_f) (alloc_arg, 1, sizeof (struct htab));
if (result == NULL)
return NULL;
@@ -261,6 +361,7 @@ htab_create_alloc_ex (size, hash_f, eq_f, del_f, alloc_arg, alloc_f,
return NULL;
}
result->size = size;
+ result->size_prime_index = size_prime_index;
result->hash_f = hash_f;
result->eq_f = eq_f;
result->del_f = del_f;
@@ -412,19 +513,27 @@ htab_expand (htab)
PTR *olimit;
PTR *p;
PTR *nentries;
- size_t nsize;
+ size_t nsize, osize, elts;
+ unsigned int oindex, nindex;
oentries = htab->entries;
- olimit = oentries + htab->size;
+ oindex = htab->size_prime_index;
+ osize = htab->size;
+ olimit = oentries + osize;
+ elts = htab_elements (htab);
/* Resize only when table after removal of unused elements is either
too full or too empty. */
- if ((htab->n_elements - htab->n_deleted) * 2 > htab->size
- || ((htab->n_elements - htab->n_deleted) * 8 < htab->size
- && htab->size > 32))
- nsize = higher_prime_number ((htab->n_elements - htab->n_deleted) * 2);
+ if (elts * 2 > osize || (elts * 8 < osize && osize > 32))
+ {
+ nindex = higher_prime_index (elts * 2);
+ nsize = prime_tab[nindex].prime;
+ }
else
- nsize = htab->size;
+ {
+ nindex = oindex;
+ nsize = osize;
+ }
if (htab->alloc_with_arg_f != NULL)
nentries = (PTR *) (*htab->alloc_with_arg_f) (htab->alloc_arg, nsize,
@@ -435,7 +544,7 @@ htab_expand (htab)
return 0;
htab->entries = nentries;
htab->size = nsize;
-
+ htab->size_prime_index = nindex;
htab->n_elements -= htab->n_deleted;
htab->n_deleted = 0;
@@ -600,17 +709,31 @@ htab_find_slot (htab, element, insert)
}
/* This function deletes an element with the given value from hash
+ table (the hash is computed from the element). If there is no matching
+ element in the hash table, this function does nothing. */
+
+void
+htab_remove_elt (htab, element)
+ htab_t htab;
+ PTR element;
+{
+ htab_remove_elt_with_hash (htab, element, (*htab->hash_f) (element));
+}
+
+
+/* This function deletes an element with the given value from hash
table. If there is no matching element in the hash table, this
function does nothing. */
void
-htab_remove_elt (htab, element)
+htab_remove_elt_with_hash (htab, element, hash)
htab_t htab;
PTR element;
+ hashval_t hash;
{
PTR *slot;
- slot = htab_find_slot (htab, element, NO_INSERT);
+ slot = htab_find_slot_with_hash (htab, element, hash, NO_INSERT);
if (*slot == EMPTY_ENTRY)
return;
diff --git a/libiberty/mkstemps.c b/libiberty/mkstemps.c
index 1f6600a15b9..94edf78755b 100644
--- a/libiberty/mkstemps.c
+++ b/libiberty/mkstemps.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1996, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1996, 1998, 2004 Free Software Foundation, Inc.
This file is derived from mkstemp.c from the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -121,11 +121,7 @@ mkstemps (template, suffix_len)
v /= 62;
XXXXXX[5] = letters[v % 62];
-#ifdef VMS
- fd = open (template, O_RDWR|O_CREAT|O_EXCL, 0600, "fop=tmd");
-#else
fd = open (template, O_RDWR|O_CREAT|O_EXCL, 0600);
-#endif
if (fd >= 0)
/* The file does not exist. */
return fd;
diff --git a/libiberty/strerror.c b/libiberty/strerror.c
index 83a5992b4dd..c0edb47e0c8 100644
--- a/libiberty/strerror.c
+++ b/libiberty/strerror.c
@@ -2,9 +2,6 @@
Written by Fred Fish. fnf@cygnus.com
This file is in the public domain. --Per Bothner. */
-#include "ansidecl.h"
-#include "libiberty.h"
-
#include "config.h"
#ifdef HAVE_SYS_ERRLIST
@@ -17,6 +14,9 @@
#define sys_errlist sys_errlist__
#endif
+#include "ansidecl.h"
+#include "libiberty.h"
+
#include <stdio.h>
#include <errno.h>
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 787119bde05..18ce1f5aa85 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,1937 @@
+2004-10-06 Tom Tromey <tromey@redhat.com>
+
+ * link.cc (ensure_method_table_complete): Ensure superclass
+ Miranda methods installed.
+
+ * include/java-interp.h (class _Jv_JNIMethod): Added
+ JV_MARKOBJ_DECL as a friend.
+ * interpret.cc (ncode): Allocate jni_arg_types field with GC.
+ * boehm.cc (_Jv_MarkObj): Skip abstract methods when marking
+ interpreter method structures. Mark jni_arg_types of JNI
+ methods.
+
+ * defineclass.cc (parse): Use JV_STATE_READ.
+ * java/lang/Class.h (JV_STATE_READ): New enum value.
+
+2004-10-05 Tom Tromey <tromey@redhat.com>
+
+ * link.cc (resolve_pool_entry): Add signature info to missing
+ method's information.
+
+ * gnu/gcj/util/Debug.java (Debug(int,boolean)): New constructor.
+ * gnu/gcj/util/natDebug.cc (_Jv_StaticDeepDebug): New function.
+
+2004-10-04 Tom Tromey <tromey@redhat.com>
+
+ * boehm.cc (_Jv_MarkObj): Correctly indicate base pointer when
+ marking IDT.
+
+2004-09-29 Tom Tromey <tromey@redhat.com>
+
+ * Makefile.am (libgcj_la_SOURCES): Mention link.cc, not
+ resolve.cc.
+ * include/jvm.h (class _Jv_Linker): Renamed from _Jv_Resolver.
+ * jni.cc: Use _Jv_Linker.
+ * interpret.cc: Use _Jv_Linker.
+ * java/lang/reflect/natField.cc (getType): Use _Jv_Linker.
+ * java/lang/natClassLoader.cc: Use _Jv_Linker.
+ * java/lang/natVMClassLoader.cc (resolveClass): Use _Jv_Linker.
+ * java/lang/Class.h: Use _Jv_Linker.
+ * java/lang/natClass.cc (initializeClass): Use _Jv_Linker.
+ * resolve.cc: Renamed ...
+ * link.cc: ... here. Use _Jv_Linker.
+ * defineclass.cc (checkExtends): Use _Jv_Linker.
+
+2004-09-17 Tom Tromey <tromey@redhat.com>
+
+ * defineclass.cc (handleCodeAttribute): Don't reference
+ `deferred'.
+ (handleMethodsEnd): Likewise.
+ * include/java-interp.h (_Jv_MethodBase::deferred): Removed
+ field.
+ (_Jv_Defer_Resolution): Don't declare or define.
+ * interpret.cc (do_create_ncode): Don't resolve deferred method
+ pointers.
+ * java/lang/Class.h (_Jv_Defer_Resolution): Don't declare.
+ * resolve.cc (link_symbol_table): No need to defer resolution.
+
+2004-09-14 Tom Tromey <tromey@redhat.com>
+
+ * boehm.cc (MAYBE_MARK): Remove unused `Exit' argument.
+ (_Jv_MarkObj): Updated.
+ (_Jv_MarkArray): Likewise.
+
+ * include/jvm.h (StringClass): Removed.
+ * jni.cc (_Jv_JNI_ThrowNew): Don't use StringClass.
+ * interpret.cc (_Jv_InitField): Don't use StringClass.
+ * java/lang/natString.cc (_Jv_StringFindSlot): Don't use
+ StringClass.
+ (rehash): Likewise
+ (intern): Likewise.
+ (_Jv_FinalizeString): Likewise.
+ (_Jv_NewStringUtf8Const): Likewise.
+ (equals): Likewise.
+ * prims.cc (JvConvertArgv): Don't use StringClass.
+
+ * gcj/field.h (struct _Jv_Field): Don't mention COMPACT_FIELDS.
+ * resolve.cc (ensure_fields_laid_out): Don't mention
+ COMPACT_FIELDS.
+ * defineclass.cc (handleField): Don't mention COMPACT_FIELDS.
+ * boehm.cc (_Jv_MarkObj): Don't mention COMPACT_FIELDS.
+
+ * java/lang/reflect/natField.cc (getType): Use resolve_field.
+ * java/lang/natVMClassLoader.cc (resolveClass): New native
+ implementation.
+ (linkClass0): Removed.
+ (markClassErrorState0): Likewise.
+ * java/lang/natClassLoader.cc: Include execution.h. Moved class
+ preparation code to resolve.cc.
+ (_Jv_RegisterClassHookDefault): Set class's execution engine if
+ not already set.
+ (_Jv_FindClass): Use wait_for_state.
+ (_Jv_NewArrayClass): Likewise. Simplified permissions setting.
+ * java/lang/natClass.cc (_Jv_IsInstanceOf): Include execution.h.
+ Moved interface table and class preparation code to resolve.cc.
+ (finalize): Rewrote.
+ (initializeClass): Simplified locking and class preparation.
+ * java/lang/VMClassLoader.java (linkClass0): Removed.
+ (markClassErrorState0): Likewise.
+ (resolveClass): Now native.
+ (transformException): New method.
+ * java/lang/Class.h (getSuperclass): Don't try to resolve super
+ reference.
+ (getInterface): Likewise.
+ (size): Likewise.
+ (set_state): New method.
+ (Class): Updated friend declarations.
+ (verify): Field now private.
+ (engine): New field.
+ * include/jvm.h (class _Jv_Resolver): New class declaration.
+ (_Jv_ResolveField): Removed declaration.
+ (_Jv_CheckAccessNoInit): Likewise.
+ (_Jv_isBinaryCompatible): Removed.
+ * include/java-interp.h (class _Jv_MethodBase): Updated friend
+ declarations.
+ (class _Jv_InterpMethod): Likewise.
+ (class _Jv_InterpClass): Likewise.
+ (class _Jv_JNIMethod): Likewise.
+ * include/execution.h: New file.
+ * gnu/gcj/runtime/natSharedLibLoader.cc: Include execution.h.
+ (_Jv_sharedlib_register_hook): Set `engine' on loaded class.
+ Register class after setting fields.
+ * resolve.cc: Include execution.h, VerifyError.h. Moved
+ interpreter-specific code to interpret.cc.
+ (uaddr): New location.
+ (struct aligner): Likewise.
+ (ALIGNOF): Likewise.
+ (INITIAL_IOFFSETS_LEN): Interface dispatch code moved here.
+ (INITIAL_IFACES_LEN): Likewise.
+ (null_idt): Likewise.
+ (_Jv_GetMethodString): Likewise.
+ (_Jv_ThrowNoSuchMethodError): Likewise.
+ (_Jv_abstractMethodError): Likewise.
+ (_Jv_Resolver::get_alignment_from_class): Renamed.
+ (_Jv_Resolver::resolve_field): Likewise.
+ (_Jv_Resolver::resolve_pool_entry): Likewise.
+ (_Jv_Resolver::resolve_class_ref): Likewise.
+ (_Jv_Resolver::prepare_constant_time_tables): Likewise.
+ (_Jv_Resolver::indexof): Likewise.
+ (_Jv_Resolver::get_interfaces): Likewise.
+ (_Jv_Resolver::generate_itable): Likewise.
+ (_Jv_Resolver::append_partial_itable): Likewise.
+ (_Jv_Resolver::find_iindex): Likewise.
+ (_Jv_Resolver::link_symbol_table): Likewise.
+ (_Jv_Resolver::link_exception_table): Likewise.
+ (_Jv_Resolver::layout_interface_methods): Likewise.
+ (_Jv_Resolver::layout_vtable_methods): Likewise.
+ (_Jv_Resolver::set_vtable_entries): Likewise.
+ (_Jv_Resolver::make_vtable): Likewise.
+ (_Jv_Resolver::ensure_fields_laid_out): Likewise.
+ (_Jv_Resolver::ensure_class_linked): Likewise.
+ (_Jv_Resolver::ensure_supers_installed): Likewise.
+ (_Jv_Resolver::add_miranda_methods): Likewise.
+ (_Jv_Resolver::ensure_method_table_complete): Likewise.
+ (_Jv_Resolver::verify_class): Likewise.
+ (_Jv_Resolver::wait_for_state): Likewise.
+ * prims.cc (_Jv_soleCompiledEngine): New global.
+ (_Jv_CheckAccess): Use _Jv_IsAssignableFromSlow.
+ (_Jv_CheckAccessNoInit): Removed.
+ * jni.cc (_Jv_JNI_GetAnyFieldID): Use resolve_field.
+ * interpret.cc: Include platform.h, ClassFormatError.h,
+ Modifier.h, execution.h.
+ (_Jv_soleInterpreterEngine): New global.
+ (compile): Use resolve_pool_entry.
+ (run): Likewise.
+ (_Jv_InitField): New location.
+ (skip_one_type): Likewise.
+ (get_ffi_type_from_signature): Likewise.
+ (_Jv_count_arguments): Likewise.
+ (init_cif): Likewise.
+ (ncode_closure): Likewise.
+ (ffi_closure_fun): Likewise.
+ (ncode): Likewise.
+ (throw_class_format_error): Likewise.
+ (throw_class_format_error): Likewise.
+ (_Jv_InterpreterEngine::do_verify): New method.
+ (_Jv_InterpreterEngine::do_create_ncode): Likewise.
+ (_Jv_InterpreterEngine::do_allocate_static_fields): Likewise.
+ (_Jv_InterpreterEngine::do_resolve_method): Likewise.
+ * defineclass.cc: Include execution.h.
+ (_Jv_ClassReader): Initialize size_in_bytes, vtable_method_count,
+ engine.
+ (checkExtends): Ensure superclass has supers installed.
+ (_Jv_ClassNameSamePackage): Clarify usage constraints.
+ * boehm.cc (GC_enable, GC_disable): Declare at top of file.
+ (_Jv_MarkObj): Unconditionally mark vtable. Mark interface
+ dispatch tables.
+
+2004-09-13 Tom Tromey <tromey@redhat.com>
+
+ * mauve-libgcj: List some classes we don't have.
+
+2004-09-10 Andrew Haley <aph@redhat.com>
+
+ * java/lang/Class.h (_Jv_getInterfaceMethod(): new friend.
+ * java/lang/natClass.cc (initializeClass): Check itable.
+ (_Jv_getInterfaceMethod): New.
+ (_Jv_LinkSymbolTable): Rewrite code that handles inerface calls.
+ Check that an interface method isn't called with invokevirtual.
+
+ * java/lang/natClass.cc (_Jv_LayoutVTableMethods): Make sure
+ super_meth is virtual.
+
+2004-09-01 Tom Tromey <tromey@redhat.com>
+
+ * java/lang/Class.h (_Jv_CheckAccessNoInit): Declare as friend.
+ * java/lang/natClass.cc (_Jv_LayoutVTableMethods): Use
+ _Jv_CheckAccessNoInit.
+ * include/jvm.h (_Jv_CheckAccessNoInit): Declare.
+ * prims.cc (_Jv_CheckAccessNoInit): New method.
+
+ * java/lang/reflect/natMethod.cc (invoke): Check access against
+ declaring class, not object's class.
+ * java/lang/natClass.cc (_Jv_LookupDeclaredMethod): Added another
+ argument.
+ (_Jv_LayoutVTableMethods): Perform checks of accessibility of
+ overridden method.
+ * java/lang/Class.h (_Jv_LookupDeclaredMethod): Added another
+ argument.
+
+2004-08-30 Andrew Haley <aph@redhat.com>
+
+ * java/lang/natClass.cc (_Jv_CheckAssignment): Catch
+ ClassNotFoundException.
+ Throw NoClassDefFoundError.
+
+ * java/lang/natClassLoader.cc (_Jv_FindClassInCache): Remove call
+ to klass->verify() from here ...
+ (_Jv_PrepareCompiledClass): ...and put it here.
+
+2004-08-27 Andrew Haley <aph@redhat.com>
+
+ * java/lang/natClassLoader.cc (_Jv_FindClassInCache): Call
+ klass->verify().
+ * java/lang/natClass.cc (_Jv_LinkSymbolTable): Add debugging.
+ (_Jv_LinkSymbolTable): Call Jv_LayoutClass on target class.
+
+2004-08-27 Tom Tromey <tromey@redhat.com>
+
+ * java/lang/Class.h (_Jv_IsAssignableFromSlow): Declare as
+ friend.
+ * java/lang/natClass.cc (_Jv_CheckAssignment): New function.
+ (_Jv_IsAssignableFromSlow): New function.
+ Include VerifyError.h.
+ * include/jvm.h (_Jv_CheckAssignment): Declare.
+
+2004-08-18 Andrew Haley <aph@redhat.com>
+
+ * java/lang/VMCompiler.java (loadSharedLibrary): Add className
+ argument. Pass it to findClass instead of fileName.
+ (compileClass): Pass class name to loadSharedLibrary.
+
+2004-06-22 Andrew Haley <aph@redhat.com>
+
+ * testsuite/libjava.compile/compile.exp: Force indirect dispatch.
+
+2004-06-15 Andrew Haley <aph@redhat.com>
+
+ * java/lang/natSystem.cc (getenv0): Don't assume environment
+ variable is Latin 1 coded.
+
+2004-06-07 Andrew Haley <aph@redhat.com>
+
+ * java/lang/System.java: (getenv0): New method.
+ (getenv): Add security check. Do the right thing.
+ * java/lang/natSystem.cc (getenv0): New method.
+
+2004-04-19 Andrew Haley <aph@redhat.com>
+
+ * gnu/gcj/runtime/NameFinder.java: Call waitFor() on the processes
+ we destroy.
+
+ * gnu/java/net/natPlainSocketImplPosix.cc (read): The value byte
+ is returned as an int in the range 0 to 255.
+
+2004-08-13 Tom Tromey <tromey@redhat.com>
+
+ * java/lang/natClass.cc (_Jv_LinkSymbolTable): Prepare the target
+ class if it is interpreted.
+
+2004-08-12 Tom Tromey <tromey@redhat.com>
+
+ * java/lang/natClassLoader.cc (_Jv_WaitForState): Updated.
+ * java/lang/Class.h (_Jv_ResolveClassRef): Updated declaration.
+ (Class::getSuperclass): Updated.
+ (Class::getInterfaces): Likewise.
+ (Class::size): Updated.
+ (_Jv_LayoutClass): Updated declaration.
+ * java/lang/natClass.cc (_Jv_ResolveClassRef): Changed interface.
+ Synchronize on class.
+ (_Jv_LayoutClass): Changed interface.
+ (initializeClass): Updated.
+ (_Jv_LinkSymbolTable): Likewise.
+
+ * java/lang/Class.h (Class::_Jv_isBinaryCompatible): Declare as
+ friend.
+ * java/lang/natClassLoader.cc (_Jv_WaitForState): Use
+ _Jv_isBinaryCompatible.
+ * java/lang/natClass.cc (initializeClass): Use
+ _Jv_isBinaryCompatible.
+ (_Jv_LinkSymbolTable): Likewise.
+ * include/jvm.h (_Jv_isBinaryCompatible): New function.
+
+2004-08-11 Tom Tromey <tromey@redhat.com>
+
+ * gcj/javaprims.h: Regenerated.
+ * java/lang/natClassLoader.cc (getClassLoader0): Removed.
+ (_registerClass): Likewise.
+ * Makefile.in: Rebuilt.
+ * Makefile.am (core_java_source_files): Added VMCompiler.
+ * java/lang/Compiler.java: Rewrote in terms of VMCompiler.
+ * java/lang/VMCompiler.java: New file.
+ * gnu/gcj/runtime/SharedLibHelper.java (findClass): Removed
+ `verbose' code.
+ (copyFile): Don't use fully-qualified name.
+ (h): Removed.
+ * java/lang/natVMClassLoader.cc: Include VMCompiler.h.
+ (defineClass): Use VMCompiler.
+ * java/lang/ClassLoader.java (defineClass): Removed jit
+ compilation code and `verbose' code.
+ (getClassLoader0): Removed.
+ (_registerClass): Likewise.
+ (SharedLibHelpers): Removed.
+
+2004-08-10 Tom Tromey <tromey@redhat.com>
+
+ * java/net/URLClassLoader.java (URLLoader(URLClassLoader, URL,
+ URL)): New constructor.
+ (SoURLLoader): Likewise.
+ (JarURLLoader): Create SoURLLoader with override URL.
+
+2004-08-10 Mark Wielaard <mark@klomp.org>
+
+ * Makefile.in: Rebuilt.
+ * Makefile.am (interpret.lo): New rule.
+
+2004-08-05 Andrew Haley <aph@redhat.com>
+
+ * java/net/URLClassLoader.java (JarURLLoader.JarURLLoader): Look
+ aside for "GCJLIBS" in directory where jarfiles are loaded.
+ (JarURLLoader.getClass): New method.
+ (JarURLLoader.toString): New method.
+ (FileResource.toString): New method.
+ * java/lang/natClassLoader.cc (_Jv_RegisterClassHookDefault):
+ Remove "Duplicate class registration: " bug.
+ (_registerClass): New method.
+ * java/lang/natClass.cc (_Jv_LinkSymbolTable): Check method index.
+ (_Jv_LinkSymbolTable): Call _Jv_LayoutClass().
+ Add debugging.
+ (_Jv_LayoutClass): Use getSuperclass() rather than directly
+ accessing the field.
+ * java/lang/ClassLoader.java (SharedLibHelpers): New variable.
+ (defineClass): Call gcj to JIT-compile a class.
+ (_registerClass): New method.
+ * gnu/gcj/runtime/SharedLibHelper.java (findHelper): A shared
+ library name can refer to more than one loaded library, so use a
+ Set of SharedLibHelpers.
+ If a shared library is already loaded, take a copy.
+ (copyFile): New function.
+
+ * testsuite/libjava.compile/compile.exp: Force
+ -findirect-dispatch.
+
+ * java/security/BasicPermission.java: Remove bogus checks.
+
+ * java/lang/System.java (getenv0): New method.
+ * java/lang/natSystem.cc (getenv0): New method.
+
+2004-05-24 Andrew Haley <aph@redhat.com>
+
+ * java/lang/natClass.cc (_Jv_LayoutClass): Remove warning message.
+
+2004-04-20 Bryce McKinlay <mckinlay@redhat.com>
+
+ * Merged with HEAD as of 20040514. Diff against
+ gcj-abi-2-merge-20040514.
+
+2004-04-16 Andrew Haley <aph@redhat.com>
+
+ * java/lang/natClassLoader.cc (_Jv_WaitForState): Call
+ _Jv_LayoutClass.
+ (_Jv_PrepareCompiledClass): Cast address to uaddr for comparison.
+ (_Jv_PrepareCompiledClass): If we throw an exception during
+ preparation, restore state.
+ (ClassLoader::getClassLoader0): New method.
+
+ * java/lang/natClass.cc (get_alignment_from_class): Moved here
+ from resolve.cc.
+ (ALIGNOF): Use offsetof, not __alignof__.
+ (_Jv_ResolveClassRef): Resolve a reference to a class in a
+ constant pool.
+ (getInterfaces): Emit debug output if interface hasn't been
+ resolved.
+ (initializeClass): Call _Jv_LayoutClass.
+ (_Jv_LinkSymbolTable): Add debugging output.
+ (_Jv_LinkSymbolTable): NoClassDefFoundError if target_class isn't
+ found.
+ (_Jv_LinkSymbolTable): Call _Jv_PrepareClass.
+ (_Jv_LinkSymbolTable): Pass the real class loader to
+ _Jv_FindClass.
+ (_Jv_linkExceptionClassTable): Don't throw if we fail to find an
+ exception class.
+ (_Jv_LinkSymbolTable): Assert if we find a static field reference
+ to an interpreted class.
+ (_Jv_LayoutVTableMethods): Use klass->getSuperclass to get the
+ superclass.
+ (_Jv_LayoutClass): Moved here; it was part of _Jv_PrepareClass in
+ resolve.cc.
+
+ * java/lang/VMSecurityManager.java: Check for the system class
+ loader as well as loader != null.
+
+ * java/lang/SecurityManager.java (checkPermission): Remove
+ security check.
+ (checkRead): Likewise.
+ (checkConnect): Likewise.
+
+ * java/lang/ClassLoader.java (loadClass): Include all class
+ loaders in stack trace string.
+ Look for class in "gcjlib.so" in the same directory.
+ (getSystemClassLoader) Use getClassLoader0.
+ (getClassLoader0): New native method.
+
+ * java/lang/Class.h (getSuperclass): New method.
+ (getInterface): New method.
+ (size): Lay out class if needed.
+ (firstMethodIndex): New method.
+ (Jv_ResolveClassRef): New declaration.
+ (_Jv_LinkSymbolTable): New declaration.
+
+ * java/io/ObjectOutputStream.java: Add DEBUG statements
+ everywhere.
+ (dumpElementln): New method.
+ (depth): New field.
+ * java/io/ObjectInputStream.java (MyIOException): new, for
+ debugging.
+ Everywhere: use MyIOException rather than IOException.
+ Indent debugging output to make nesting visible.
+ (currentClassLoader): Make native
+ (callersClassLoader): New field.
+ (depth): New field.
+ * java/io/natObjectInputStream.cc (getCallersClassLoader): New
+ method.
+
+ (readObject): ENDBLOCKDATA is generated if the class has a write
+ method, not if it has a read method.
+
+ * include/jvm.h (_Jv_CallAnyMethodA): Add new arg, iface.
+
+ * gnu/javax/rmi/CORBA/DelegateFactory.java: Use the
+ getContextClassLoader form the current thread after our own class
+ loader.
+
+ * gnu/gcj/runtime/SharedLibHelper.java (findClass): Class loader
+ debugging.
+ (toString): New method.
+
+ * verify.cc (class _Jv_BytecodeVerifier): Don't directly access
+ interfaces array.
+
+ * resolve.cc (_Jv_PrepareMissingMethods): If interface looks like
+ a constant pool entry, resolve it now.
+ (_Jv_PrepareClass): Break out part of this function to Jv_LayoutClass
+ in natClass.cc.
+ Move get_alignment_from_class to natClass.cc.
+
+ * prims.cc (_Jv_AllocObjectNoFinalizer): Use size field from class.
+ (_Jv_AllocObjectNoInitNoFinalizer): Likewise.
+
+ * defineclass.cc (checkExtends): Don't access superclass field
+ directly.
+
+ * Makefile.in: regenerate.
+
+ * gnu/gcj/util/natDebug.cc: New
+ * gnu/gcj/util/Debug.java: New.
+
+ * Makefile.am (java/io/ObjectInputStream.lo): Use
+ -fno-optimize-sibling-calls.
+
+ * java/lang/reflect/natMethod.cc (_Jv_CallAnyMethodA): Use
+ _Jv_LookupInterfaceMethodIdx to calculate the address of a method
+ in an interface.
+ * include/jvm.h (_Jv_CallAnyMethodA): Add new arg: iface.
+
+2004-05-14 Steven Augart <augart@watson.ibm.com>
+
+ * include/jni.h (_Jv_func): Removed.
+ (struct JNINativeInterface): Use `void *' for reserved slots.
+ (struct JNIInvokeInterface): Likewise.
+
+2004-05-11 Michael Koch <konqueror@gmx.de>
+
+ * gnu/java/net/natPlainSocketImplPosix.cc
+ (read): Fixed typo in expression.
+
+2004-05-10 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * testsuite/lib/libjava.exp (libjava_invoke): Add new argument
+ ld_library_additions. Adjust all calls to libjava_invoke to match
+ the new argument.
+
+ * testsuite/libjava.jni/jni.exp (gcj_jni_test_one): Pass stdc++
+ path to cxxflagslist.
+ Pass path of libstdc++ to libjava_invoke.
+
+ * testsuite/libjava.jar/jar.exp (gcj_jar_inerpret): Adjust
+ libjava_invoke arguments.
+
+2004-05-10 Ranjit Mathew <rmathew@hotmail.com>
+
+ * testsuite/libjava.jacks/jacks.xfail: Update to reflect the current
+ reality.
+
+2004-05-07 Ranjit Mathew <rmathew@gmail.com>
+
+ * testsuite/libjava.jni/jni.exp (gcj_jni_test_one): Don't link the
+ main binary against the JNI shared library.
+
+2004-05-07 Jerry Quinn <jlquinn@optonline.net>
+
+ * java/util/SimpleTimeZone.java (startTimeMode, endTimeMode,
+ WALL_TIME, STANDARD_TIME, UTC_TIME): New members.
+ (SimpleTimeZone): Tweak docs. Add new variation.
+ (setStartRule,setEndRule): Add new variations. Use
+ startTimeMode and endTimeMode.
+
+2004-05-07 Jerry Quinn <jlquinn@optonline.net>
+
+ * java/util/Calendar.java (getActualMinimum,
+ getActualMaximum): Remove abstract. Implement.
+
+2004-05-06 Bryce McKinlay <mckinlay@redhat.com>
+
+ Run the jni tests using the interpreter.
+ * testsuite/libjava.jni/jni.exp (gcj_jni_compile_c_to_so): Append
+ options_cxx to shared lib compile command.
+ (gcj_jni_test_one): Pass cxxflags to gcj_jni_compile_c_to_so, so
+ they are used to link the shared lib, not the main binary.
+ Use libjava_invoke to run gij.
+
+2004-05-06 Michael Koch <konqueror@gmx.de>
+
+ * java/util/logging/Level.java
+ (parse): Use == instead of String.equals().
+
+2004-05-06 Bryce McKinlay <mckinlay@redhat.com>
+
+ * defineclass.cc (_Jv_ClassReader::prepare_pool_entry): Use
+ verify_field_signature and verify_method_signature, not
+ _Jv_VerifyFieldSignature and _Jv_VerifyMethodSigntature.
+ (_Jv_ClassReader::handleField): Likewise.
+ (_Jv_ClassReader::handleMethod): Likewise.
+
+2004-05-06 Michael Koch <konqueror@gmx.de>
+
+ * javax/swing/table/TableColumn.java:
+ Reformated.
+
+2004-05-06 Michael Koch <konqueror@gmx.de>
+
+ * javax/imageio/spi/ImageReaderWriterSpi.java
+ (ImageReaderWriterSpi): Made it public.
+ * javax/imageio/stream/ImageInputStream.java:
+ Clean up imports.
+
+2004-05-06 Michael Koch <konqueror@gmx.de>
+
+ * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c:
+ Removed empty line.
+
+2004-05-06 Michael Koch <konqueror@gmx.de>
+
+ * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c,
+ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.c:
+ New files.
+ * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c:
+ Include gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.h.
+ * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c:
+ Moved GtkCheckboxGroupPeer_dispose and GtkCheckboxGroupPeer_remove to
+ their own source file.
+ * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c:
+ Moved GtkGenericPeer_dispose and GtkComponentPeer_requestFocus to
+ their own source file. Removed GtkComponentPeer_gtkWidgetSetUsize.
+ * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c
+ (create): Define variable on top of function.
+ * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c
+ (menu_pos): Prototyped.
+ * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c
+ (setTitle): Removed.
+ * jni/gtk-peer/gthread-jni.c
+ (gdk_threads_wake): Removed.
+ * Makefile.am (gtk_c_source_files): Added new files
+ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c and
+ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.c.
+ * Makefile.in: Regenerated.
+
+2004-05-05 Bryce McKinlay <mckinlay@redhat.com>
+
+ * testsuite/libjava.jni/pr11951.java: Add missing System.loadLibrary()
+ call.
+
+2004-05-05 Mark Wielaard <mark@klomp.org>
+
+ * javax/swing/AbstractButton.java: Replace special HTML entities with
+ ASCII equivalent.
+ * javax/swing/DefaultBoundedRangeModel.java: Likewise.
+ * javax/swing/DefaultButtonModel.java: Likewise.
+ * javax/swing/DefaultListModel.java: Likewise.
+ * javax/swing/JList.java: Likewise.
+ * javax/swing/JSlider.java: Likewise.
+ * javax/swing/ListModel.java: Likewise.
+ * javax/swing/Popup.java: Likewise.
+ * javax/swing/SwingUtilities.java: Likewise.
+
+2004-05-05 Michael Koch <konqueror@gmx.de>
+
+ * javax/swing/AbstractButton.java,
+ javax/swing/ActionMap.java,
+ javax/swing/DefaultButtonModel.java,
+ javax/swing/DefaultListModel.java,
+ javax/swing/ImageIcon.java,
+ javax/swing/JComboBox.java,
+ javax/swing/JComponent.java,
+ javax/swing/JFrame.java,
+ javax/swing/JInternalFrame.java,
+ javax/swing/JMenuBar.java,
+ javax/swing/JMenuItem.java,
+ javax/swing/JOptionPane.java,
+ javax/swing/JProgressBar.java,
+ javax/swing/JRootPane.java,
+ javax/swing/JScrollBar.java,
+ javax/swing/JScrollPane.java,
+ javax/swing/JSeparator.java,
+ javax/swing/JSlider.java,
+ javax/swing/JTabbedPane.java,
+ javax/swing/JTable.java,
+ javax/swing/JTextField.java,
+ javax/swing/JToolBar.java,
+ javax/swing/JToolTip.java,
+ javax/swing/JTree.java,
+ javax/swing/JViewport.java,
+ javax/swing/JWindow.java,
+ javax/swing/KeyStroke.java,
+ javax/swing/LookAndFeel.java,
+ javax/swing/SwingUtilities.java,
+ javax/swing/Timer.java,
+ javax/swing/ToolTipManager.java,
+ javax/swing/UIDefaults.java,
+ javax/swing/border/TitledBorder.java,
+ javax/swing/filechooser/FileSystemView.java,
+ javax/swing/plaf/basic/BasicButtonListener.java,
+ javax/swing/plaf/basic/BasicButtonUI.java,
+ javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java,
+ javax/swing/plaf/basic/BasicGraphicsUtils.java,
+ javax/swing/plaf/basic/BasicLabelUI.java,
+ javax/swing/plaf/basic/BasicMenuItemUI.java,
+ javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java,
+ javax/swing/plaf/basic/BasicRootPaneUI.java,
+ javax/swing/plaf/basic/BasicScrollBarUI.java,
+ javax/swing/plaf/basic/BasicScrollPaneUI.java,
+ javax/swing/plaf/basic/BasicSliderUI.java,
+ javax/swing/plaf/basic/BasicTabbedPaneUI.java,
+ javax/swing/plaf/basic/BasicToggleButtonUI.java,
+ javax/swing/table/JTableHeader.java,
+ javax/swing/text/AbstractDocument.java,
+ javax/swing/text/DefaultCaret.java,
+ javax/swing/text/StyledEditorKit.java,
+ javax/swing/tree/DefaultTreeCellEditor.java:
+ Cleaned up imports.
+
+2004-05-05 Michael Koch <konqueror@gmx.de>
+
+ * java/util/prefs/AbstractPreferences.java
+ (AbstractPreferences): Added parenthesis for clarity.
+ Closes classpath bug #7940.
+
+2004-05-05 Tom Tromey <tromey@redhat.com>
+
+ * javax/naming/CompoundName.java (endsWith): Look at correct
+ element of source name.
+
+2004-05-05 Mark Wielaard <mark@klomp.org>
+
+ Reported by f.haeglsperger@gmx.de [classpath patch #2485]
+ * java/util/HashMap.java (rehash): Add entry at start of bucket.
+
+2004-05-05 Tom Tromey <tromey@redhat.com>
+
+ * java/io/BufferedReader.java (skip): Removed unused
+ variable.
+
+2004-05-05 Michael Koch <konqueror@gmx.de>
+
+ * java/awt/FileDialog.java: Import java.io.Serializable explicitly.
+
+2004-05-05 Dalibor Topic <robilad@kaffe.org>
+
+ * java/text/AttributedString.java,
+ java/text/AttributedStringIterator.java,
+ java/text/Collator.java,
+ java/text/DecimalFormatSymbols.java,
+ java/text/NumberFormat.java,
+ java/text/RuleBasedCollator.java:
+ Cleaned up imports.
+
+2004-05-05 Tom Tromey <tromey@redhat.com>
+
+ * java/text/Format.java: Cleaned up imports.
+ * java/text/DecimalFormat.java: Cleaned up imports.
+ * java/security/SecureRandom.java: Cleaned up imports.
+ (SecureRandom): Removed unused variable.
+ * java/security/UnresolvedPermission.java: Cleaned up imports.
+ * java/util/Date.java (parse): Removed unused variable.
+ * java/util/ResourceBundle.java: Cleaned up imports.
+ (getBundle): Removed unused variable.
+ (tryBundle): Likewise.
+ * java/util/regex/Pattern.java (Pattern): Removed unused constructor.
+
+2004-05-05 Guilhem Lavaux <guilhem@kaffe.org>
+
+ * java/text/SimpleDateFormat.java:
+ (formatWithAttribute): New method. It implements
+ the formatting process with attributes.
+ (format): Use formatWithAttribute.
+ (formatToCharacterIterator): New method. Use
+ formatWithAttribute.
+
+2004-05-05 Guilhem Lavaux <guilhem@kaffe.org>
+
+ * java/text/MessageFormat.java:
+ (class Field): New class.
+ (formatToCharacterIterator): New method.
+ (format): Use formatInternal now.
+ (formatInternal): New method. String formatter should
+ be done here (with attributes). Attributes merging supported.
+ (parse): More documentation.
+ (getFormatsByArgumentIndex): New method.
+ (setFormatByArgumentIndex): New method.
+ (setFormatsByArgumentIndex): New method.
+
+2004-05-05 Guilhem Lavaux <guilhem@kaffe.org>
+
+ * java/text/DecimalFormat.java
+ (MAXIMUM_INTEGER_DIGITS): New constant to keep the numeric value 309.
+ (applyPatternWithSymbols): Use MAXIMUM_INTEGER_DIGITS.
+ (parse): Fixed handling of exponentiation notation and grouping.
+
+2004-05-05 Guilhem Lavaux <guilhem@kaffe.org>
+
+ * java/text/DecimalFormat.java
+ (scanFix): Build attribute array. Fixed error reporting.
+ (applyPatternWithSymbols): Store attributes for the prefix and
+ suffix.
+ (formatInternal): New method. Changed the way the string is
+ computed. Implemented attributes. Cleant up rounding in
+ exponential notation.
+ (format): Use formatInternal.
+ (formatToCharacterIterator): New method.
+ (exponentRound, negativePrefixRanges, positivePrefixRanges,
+ negativePrefixAttrs, positivePrefixAttrs, negativeSuffixRanges,
+ positiveSuffixRanges, negativeSuffixAttrs, positiveSuffixAttrs):
+ New fields.
+
+2004-05-04 Dalibor Topic <robilad@kaffe.org>
+
+ * java/security/interfaces/DSAKeyPairGenerator.java,
+ java/security/interfaces/DSAPrivateKey.java,
+ java/security/interfaces/DSAPublicKey.java,
+ java/security/interfaces/RSAPrivateKey.java,
+ java/security/interfaces/RSAPublicKey.java:
+ Cleaned up imports.
+
+2004-05-04 Michael Koch <konqueror@gmx.de>
+
+ * java/nio/ByteBuffer.java,
+ java/nio/CharBuffer.java,
+ java/nio/DoubleBuffer.java,
+ java/nio/FloatBuffer.java,
+ java/nio/IntBuffer.java,
+ java/nio/LongBuffer.java,
+ java/nio/ShortBuffer.java:
+ (compareTo): Fixed bogus implementation in all buffer classes.
+
+2004-05-04 Ingo Proetel <proetel@aicas.com>
+
+ * java/awt/image/ColorModel.java (getRGBdefault): Default ColorModel has
+ 32 bit pixels not 8 bit pixels.
+ (isCompatibleRaster): Added javadoc comment.
+
+2004-05-04 Ingo Proetel <proetel@aicas.com>
+
+ * java/awt/image/ComponentSampleModel.java (setDataSamples):Do not reset
+ scanline stride.
+
+2004-05-04 Ingo Proetel <proetel@aicas.com>
+
+ * java/awt/ColorPaintContext.java (<init>): Added ColorModel to signature.
+ (getColorModel): Return the actual color model.
+ (getRaster): Implemented.
+ (ColorRaster): New inner class.
+ * java/awt/SystemColor.java (createContext): Use ColorModel when creating
+ a PaintContext.
+ * java/awt/Color.java (<init>): Make exception more verbose.
+ (createContext): Use ColorModel when creating a PaintContext.
+
+2004-05-04 Michael Koch <konqueror@gmx.de>
+
+ * gnu/java/text/CharacterBreakIterator.java
+ (previous): Removed unused variable.
+
+2004-05-04 Guilhem Lavaux <guilhem@kaffe.org>
+
+ * gnu/java/text/FormatBuffer.java,
+ gnu/java/text/AttributedFormatBuffer.java,
+ gnu/java/text/StringFormatBuffer.java: New classes to implement
+ attributed iterators in java.text.
+ * gnu/java/text/FormatCharacterIterator.java: Moved
+ from java/text as it is an internal class.
+ * java/text/FormatCharacterIterator.java: Removed.
+ * java/text/Format.java:
+ Import gnu.java.text.FormatCharacterIterator.
+ * Makefile.am (java_source_files): Added new files.
+ * Makefile.in: Regenerated.
+
+
+2004-05-04 Mark Wielaard <mark@klomp.org>
+
+ * gnu/java/nio/channels/FileChannelImpl.java (finalize): New method.
+
+2004-05-03 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * Makefile.am (WARNINGS): Replace -W with the more speaking -Wextra.
+ * Makefile.in: Rebuilt.
+
+2004-05-03 Mark Wielaard <mark@klomp.org>
+
+ * gnu/java/security/der/DERReader.java: Call static methods staticly.
+ * java/awt/TextComponent.java (select): Use selectionEnd parameter.
+ * java/net/URL.java
+ (set(String, String, int, String, String, String, String, String)):
+ Assign this.file to path or path + "?" + query.
+ * java/util/Arrays.java: Call static methods staticly.
+ * java/util/zip/ZipEntry.java: Likewise.
+ * javax/swing/plaf/basic/BasicArrowButton.java (setDirection): Assign
+ dir to this.direction.
+ * javax/swing/table/DefaultTableCellRenderer.java (noFocusBorder):
+ Assign static field only once.
+ (DefaultTableCellRenderer): Don't reassign noFocusBorder each time.
+
+2004-05-03 Mark Wielaard <mark@klomp.org>
+
+ * gnu/java/awt/peer/gtk/GtkTextAreaPeer.java (minimumSize): Removed
+ unused variables hScrollbarHeight and vScrollbarWidth.
+ (preferredSize): Likewise.
+ * gnu/java/security/provider/DSAParameters.java (engineToString):
+ Removed unused call to System.getProperty("line.seperator");
+ * java/security/Security.java (loadProviders): Return result.
+
+2004-05-03 Tom Tromey <tromey@redhat.com>
+
+ * java/net/URLStreamHandler.java (toExternalForm): Removed
+ unused variables.
+ unused constructor.
+ * java/math/BigDecimal.java (divide): Removed unused variable.
+ * java/lang/Throwable.java: Cleaned up imports.
+ * java/lang/ClassLoader.java: Cleaned up imports.
+ * java/io/FilePermission.java (implies): Removed unused
+ variable.
+ * java/awt/TextComponent.java: Removed unused import.
+ * gnu/java/util/prefs/NodeReader.java: Cleaned up imports.
+ * gnu/java/util/DoubleEnumeration.java: Removed unused import.
+ * gnu/java/text/WordBreakIterator.java: Removed unused import.
+ * gnu/java/text/SentenceBreakIterator.java: Removed unused
+ import.
+ * gnu/java/text/LineBreakIterator.java: Removed unused import.
+ * gnu/java/text/CharacterBreakIterator.java: Removed
+ unused import.
+ * gnu/java/security/provider/DSAKeyPairGenerator.java:
+ Cleaned up imports.
+ * gnu/java/security/der/DERWriter.java: Cleaned up imports.
+ * gnu/java/nio/charset/UTF_16Decoder.java (put): Removed
+ unused method.
+ * gnu/java/nio/SocketChannelImpl.java: Cleaned up imports.
+ * gnu/java/nio/FileLockImpl.java: Cleaned up imports.
+ * gnu/java/io/Base64InputStream.java: Cleaned up imports.
+ * gnu/java/beans/info/ComponentBeanInfo.java: Cleaned up imports.
+ * gnu/classpath/ServiceFactory.java: Cleaned up imports.
+ (lookupProviders): Removed unused variable.
+ (loadNextServiceProvider): Likewise.
+ * gnu/java/beans/BeanInfoEmbryo.java: Cleaned up imports.
+
+2004-05-03 Michael Koch <konqueror@gmx.de>
+
+ Fixes PR libgcj/14695:
+ * java/net/NetworkInterface.java
+ (getByName): Return null when no interface was found.
+
+2004-04-30 Ranjit Mathew <rmathew@hotmail.com>
+ Tom Tromey <tromey@redhat.com>
+
+ * testsuite/libjava.jni/jni.exp (gcj_jni_compile_c_to_so): Use
+ additional option "-Wmissing-prototypes" for compiling C sources.
+ Print actual filename for pass/fail rather than $name.c.
+ * testsuite/libjava.jni/PR15133.java: New testcase file.
+ * testsuite/libjava.jni/PR15133.c: Likewise.
+ * testsuite/libjava.jni/PR15133.out: Likewise.
+
+2004-04-30 Roger Sayle <roger@eyesopen.com>
+
+ * testsuite/libjava.lang/MathBuiltin.java: Add tests for acos, asin,
+ ceil and floor.
+
+2004-04-25 Ranjit Mathew <rmathew@hotmail.com>
+
+ * testsuite/libjava.jacks/jacks.exp (gcj_jacks_write): Explicitly
+ limit the maximum heap size to avoid unnecessary thrashing.
+
+2004-04-24 Jerry Quinn <jlquinn@optonline.net>
+
+ * java/text/CollationElementIterator.java (reset): Reset
+ lookahead variables.
+
+2004-04-23 Mark Wielaard <mark@klomp.org>
+
+ * jni/classpath/jcl.c: Changed C++ comments into C comments.
+
+2004-04-23 Dalibor Topic <robilad@kaffe.org>
+
+ * java/sql/DriverManager.java:
+ Cleaned up imports.
+
+2004-04-23 Michael Koch <konqueror@gmx.de>
+
+ * java/net/URL.java
+ (hashcode): Don't initialize with default value explicitely.
+ (getContent): Removed redundant "final" keyword.
+ (openStream): Likewise.
+ (getURLStreamHandler): Fixed coding style.
+ * java/net/URLConnection.java
+ (defaultAllowUserInteraction): Don't initialize with default value
+ explicitely.
+ (connected): Likewise.
+ (doOutput): Likewise.
+ (ifModifiedSince): Likewise.
+ (dateformats_initialized): Likewise.
+ (setURLStreamHander): Use StreamTokenizer where it belongs to.
+
+2004-04-23 Michael Koch <konqueror@gmx.de>
+
+ * gnu/java/nio/channels/FileChannelImpl.java
+ (SET, CUR): Unused, removed.
+ (read): Implement here directly.
+ (implRead): Removed.
+ (write): Implement here directly.
+ (implWrite): Removed.
+
+2004-04-23 Dalibor Topic <robilad@kaffe.org>
+
+ * javax/rmi/CORBA/PortableRemoteObjectDelegate.java,
+ javax/rmi/CORBA/Stub.java,
+ javax/rmi/CORBA/Util.java,
+ javax/rmi/CORBA/ValueHandler.java,
+ javax/rmi/CORBA/ValueHandler.java,
+ javax/rmi/PortableRemoteObject.java:
+ Cleaned up imports.
+
+2004-04-23 Dalibor Topic <robilad@kaffe.org>
+
+ * java/util/jar/JarFile.java,
+ java/util/jar/JarInputStream.java,
+ java/util/jar/JarOutputStream.java,
+ java/util/jar/Manifest.java:
+ Cleaned up imports.
+
+2004-04-23 Dalibor Topic <robilad@kaffe.org>
+
+ * java/util/ArrayList.java,
+ java/util/Calendar.java,
+ java/util/Currency.java,
+ java/util/HashMap.java,
+ java/util/HashSet.java,
+ java/util/Hashtable.java,
+ java/util/LinkedList.java,
+ java/util/Properties.java,
+ java/util/PropertyPermission.java,
+ java/util/TimeZone.java,
+ java/util/TreeMap.java,
+ java/util/TreeSet.java,
+ java/util/Vector.java,
+ java/util/WeakHashMap.java:
+ Cleaned up imports.
+
+2004-04-23 Dalibor Topic <robilad@kaffe.org>
+
+ * java/util/logging/FileHandler.java,
+ java/util/logging/Formatter.java,
+ java/util/logging/Handler.java,
+ java/util/logging/Logger.java,
+ java/util/logging/SimpleFormatter.java,
+ java/util/logging/XMLFormatter.java:
+ Cleaned up imports.
+
+2004-04-22 Mark Wielaard <mark@klomp.org>
+
+ * Makefile.am (PEDANTIC_CFLAGS): New -ansi -pedantic -Wall
+ -Wno-long-long flags variable.
+ (gtk_c_files): Use PEDANTIC_CFLAGS.
+ * Makefile.in: Regenerated.
+
+2004-04-22 Mark Wielaard <mark@klomp.org>
+
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c:
+ Changed C++ comments into C comments.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c:
+ Likewise.
+
+2004-04-22 Michael Koch <konqueror@gmx.de>
+
+ * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c:
+ Merged copyright year with GNU classpath.
+
+2004-04-22 Dalibor Topic <robilad@kaffe.org>
+
+ * javax/security/auth/x500/X500Principal.java:
+ Cleaned up imports.
+
+2004-04-22 Dalibor Topic <robilad@kaffe.org>
+
+ * javax/swing/JSlider.java:
+ Fixed HTML tags in comments.
+
+2004-04-22 Dalibor Topic <robilad@kaffe.org>
+
+ * javax/accessibility/AccessibleText.java:
+ Cleaned up imports.
+
+2004-04-22 Jeroen Frijters <jeroen@sumatra.nl>
+
+ * java/net/URLStreamHandler.java
+ (parseURL): Convert the file path to using '/' instead of native
+ file separator.
+
+2004-04-22 Guilhem Lavaux <guilhem@kaffe.org>
+
+ * java/net/URL.java
+ (userInfo): New field.
+ (URL): Set authority to the right value.
+ (setURL): Fixed authority and file initialization.
+ * java/net/URLStreamHandler.java
+ (parseURL): Take care of the query tag. Build authority.
+ (toExternalForm): Fixed URL building using authority.
+
+2004-04-22 Michael Koch <konqueror@gmx.de>
+
+ * java/net/Socket.java
+ (impl): Made package-private.
+ * java/net/ServerSocket.java
+ (implAccept): Access Socket.impl field directly.
+
+2004-04-22 Dalibor Topic <robilad@kaffe.org>
+
+ * java/util/prefs/Preferences.java,
+ java/util/prefs/InvalidPreferencesFormatException.java,
+ java/util/prefs/BackingStoreException.java,
+ java/util/prefs/AbstractPreferences.java:
+ Cleaned up imports.
+
+2004-04-22 Dalibor Topic <robilad@kaffe.org>
+
+ * java/util/regex/Matcher.java,
+ java/util/regex/Pattern.java:
+ Cleaned up imports.
+
+2004-04-22 Michael Koch <konqueror@gmx.de>
+
+ * java/nio/charset/IllegalCharsetNameException.java
+ (charsetName): Made private.
+ (IllegalCharsetNameException): Added @param tag to javadoc.
+ (getCharsetName): Added @return tag to javadoc.
+ * java/nio/charset/MalformedInputException.java
+ (MalformedInputException): Added @param tag to javadoc.
+ (getInputLength): Revised method description, added @return tag.
+ (getMessage): Added @return tag.
+
+2004-04-22 Jerry Quinn <jlquinn@optonline.net>
+
+ * java/awt/Font.java (deriveFont): Implement missing variants.
+ * gnu/java/awt/peer/ClasspathFontPeer.java (deriveFont): Implement
+ missing variants.
+
+2004-04-21 Bryce McKinlay <mckinlay@redhat.com>
+
+ * java/lang/natClass.cc (_Jv_LayoutInterfaceMethods): New method.
+ Set method->index values for interface methods to their itable index.
+ (initializeClass): Call _Jv_LayoutInterfaceMethods.
+
+2004-04-21 Michael Koch <konqueror@gmx.de>
+
+ * java/nio/DirectByteBufferImpl.java
+ (shiftDown): Made static, give address as argument and
+ provide a convenience method that overwrites shiftDown in
+ ByteBufferImpl and calls the native shiftDown.
+ * java/nio/MappedByteBufferImpl.java
+ (): Use optimized method in DirectByteBufferImpl.
+ * java/nio/natDirectByteBufferImpl.cc
+ (shiftDown): Changed method signature. Removed usage of array_offset.
+
+2004-04-21 Michael Koch <konqueror@gmx.de>
+
+ * gnu/java/net/natPlainSocketImplPosix.cc
+ (SocketInputStream::read): Make sure returned data is a byte value.
+
+2004-04-21 Michael Koch <konqueror@gmx.de>
+
+ * gnu/classpath/ServiceFactory.java,
+ gnu/classpath/ServiceProviderLoadingAction.java,
+ javax/imageio/ImageReader.java,
+ javax/imageio/ImageTranscoder.java,
+ javax/imageio/ImageWriter.java,
+ javax/imageio/package.html,
+ javax/imageio/spi/IIOServiceProvider.java,
+ javax/imageio/spi/ImageInputStreamSpi.java,
+ javax/imageio/spi/ImageOutputStreamSpi.java,
+ javax/imageio/spi/ImageReaderWriterSpi.java,
+ javax/imageio/spi/ImageTranscoderSpi.java,
+ javax/imageio/spi/RegisterableService.java,
+ javax/imageio/spi/ServiceRegistry.java,
+ javax/imageio/spi/package.html,
+ javax/imageio/stream/IIOByteBuffer.java,
+ javax/imageio/stream/ImageInputStream.java,
+ javax/imageio/stream/ImageOutputStream.java,
+ javax/imageio/stream/package.html:
+ New files.
+ * Makefile.am
+ (ordinary_java_source_files): Added
+ gnu/classpath/ServiceFactory.java and
+ gnu/classpath/ServiceProviderLoadingAction.java.
+ (javax_source_files): Added
+ javax/imageio/ImageReader.java,
+ javax/imageio/ImageTranscoder.java,
+ javax/imageio/ImageWriter.java,
+ javax/imageio/spi/IIOServiceProvider.java,
+ javax/imageio/spi/ImageInputStreamSpi.java,
+ javax/imageio/spi/ImageOutputStreamSpi.java,
+ javax/imageio/spi/ImageReaderWriterSpi.java,
+ javax/imageio/spi/ImageTranscoderSpi.java,
+ javax/imageio/spi/RegisterableService.java,
+ javax/imageio/spi/ServiceRegistry.java,
+ javax/imageio/stream/IIOByteBuffer.java,
+ javax/imageio/stream/ImageInputStream.java and
+ javax/imageio/stream/ImageOutputStream.java.
+ * Makefile.in: Regenerated.
+
+2004-04-21 Michael Koch <konqueror@gmx.de>
+
+ * java/util/Properties.java
+ (load): Fix wrongly merged fix.
+
+2004-04-21 Mark Wielaard <mark@klomp.org>
+
+ * native/jni/gtk-peer/gthread-jni.c (maybe_rethrow): Explicitly
+ malloc and free buf.
+
+2004-04-21 Dalibor Topic <robilad@kaffe.org>
+
+ * javax/naming/AuthenticationException.java,
+ javax/naming/AuthenticationNotSupportedException.java,
+ javax/naming/CannotProceedException.java,
+ javax/naming/CommunicationException.java,
+ javax/naming/CompoundName.java,
+ javax/naming/ConfigurationException.java,
+ javax/naming/ContextNotEmptyException.java,
+ javax/naming/InitialContext.java,
+ javax/naming/InsufficientResourcesException.java,
+ javax/naming/InterruptedNamingException.java,
+ javax/naming/LimitExceededException.java,
+ javax/naming/LinkException.java,
+ javax/naming/LinkLoopException.java,
+ javax/naming/LinkRef.java,
+ javax/naming/MalformedLinkException.java,
+ javax/naming/Name.java,
+ javax/naming/NameAlreadyBoundException.java,
+ javax/naming/NameNotFoundException.java,
+ javax/naming/NamingSecurityException.java,
+ javax/naming/NoInitialContextException.java,
+ javax/naming/NoPermissionException.java,
+ javax/naming/NotContextException.java,
+ javax/naming/PartialResultException.java,
+ javax/naming/ReferralException.java,
+ javax/naming/ServiceUnavailableException.java,
+ javax/naming/SizeLimitExceededException.java,
+ javax/naming/TimeLimitExceededException.java,
+ javax/naming/directory/Attribute.java,
+ javax/naming/directory/Attributes.java,
+ javax/naming/directory/SearchResult.java,
+ javax/naming/event/NamingExceptionEvent.java,
+ javax/naming/spi/ResolveResult.java:
+ Cleaned up imports.
+
+2004-04-21 Mark Wielaard <mark@klomp.org>
+
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c:
+ Changed C++ comments into C comments. Removed commented out code.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c:
+ Likewise.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c:
+ Likewise.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c:
+ Likewise.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c:
+ Likewise.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextComponentPeer.c:
+ Likewise.
+ * native/jni/gtk-peer/gthread-jni.c:
+ Likewise.
+
+2004-04-21 Mark Wielaard <mark@klomp.org>
+
+ * javax/awt/JFrame.java: Implement WindowConstants. Remove final
+ static fields defined in interface.
+ * javax/awt/JDialog.java: Likewise.
+ (JDialog): Make constructors public.
+ (getDefaultCloseOperation): Make public.
+ (processWindowEvent): Call System.exit(0) when EXIT_ON_CLOSE set.
+ (setDefaultCloseOperation): Make public. Check argument. Add API doc.
+ * javax/swing/JViewport.java (JViewport): Make constructor public.
+
+2004-04-21 Michael Koch <konqueror@gmx.de>
+
+ * java/util/Map.java
+ (Entry): Removed redundant "static" modifier.
+ * java/text/AttributedCharacterIterator.java:
+ Updated copyright year.
+
+2004-04-20 Michael Koch <konqueror@gmx.de>
+
+ * javax/naming/directory/SearchControls.java:
+ Don't explicitely extend java.lang.Object.
+ * javax/naming/spi/DirStateFactory.java:
+ Merged copyright year with GNU classpath.
+
+2004-04-20 Michael Koch <konqueror@gmx.de>
+
+ * java/nio/channels/Channels.java:
+ Merged coding style with GNU classpath.
+
+2004-04-20 Michael Koch <konqueror@gmx.de>
+
+ * java/net/ServerSocket.java
+ Merged coding style from GNU classpath.
+
+2004-04-20 Michael Koch <konqueror@gmx.de>
+
+ * java/io/BufferedWriter.java:
+ Reordered variables to be at top of the class.
+ (localFlush): Removed redundant final keyword.
+
+2004-04-20 Ingo Proetel <proetel@aicas.com>
+
+ * java/awt/event/MouseEvent.java (<init>): fixed field assignment
+
+2004-04-20 Jeroen Frijters <jeroen@frijters.net>
+
+ * java/text/DecimalFormat.java (scanFix): Removed suffix check
+ for percent and permill check.
+
+2004-04-20 Guilhem Lavaux <guilhem@kaffe.org>
+
+ * java/text/FieldPosition.java
+ (FieldPosition) Constructor now behaves as it should according
+ to the java documentation.
+
+2004-04-20 Mark Wielaard <mark@klomp.org>
+
+ * java/util/Properties.java: Use the word umlaut, not &auml; in api
+ documentation.
+
+2004-04-20 Michael Koch <konqueror@gmx.de>
+
+ * java/nio/Buffer.java,
+ java/nio/channels/AlreadyConnectedException.java,
+ java/nio/channels/AsynchronousCloseException.java,
+ java/nio/channels/ByteChannel.java,
+ java/nio/channels/CancelledKeyException.java,
+ java/nio/channels/Channel.java,
+ java/nio/channels/Channels.java,
+ java/nio/channels/ClosedByInterruptException.java,
+ java/nio/channels/ClosedChannelException.java,
+ java/nio/channels/ClosedSelectorException.java,
+ java/nio/channels/ConnectionPendingException.java,
+ java/nio/channels/DatagramChannel.java,
+ java/nio/channels/FileChannel.java,
+ java/nio/channels/FileLock.java,
+ java/nio/channels/FileLockInterruptionException.java,
+ java/nio/channels/GatheringByteChannel.java,
+ java/nio/channels/IllegalBlockingModeException.java,
+ java/nio/channels/IllegalSelectorException.java,
+ java/nio/channels/InterruptibleChannel.java,
+ java/nio/channels/NoConnectionPendingException.java,
+ java/nio/channels/NonReadableChannelException.java,
+ java/nio/channels/NonWritableChannelException.java,
+ java/nio/channels/NotYetBoundException.java,
+ java/nio/channels/NotYetConnectedException.java,
+ java/nio/channels/OverlappingFileLockException.java,
+ java/nio/channels/Pipe.java,
+ java/nio/channels/ReadableByteChannel.java,
+ java/nio/channels/ScatteringByteChannel.java,
+ java/nio/channels/SelectableChannel.java,
+ java/nio/channels/SelectionKey.java,
+ java/nio/channels/Selector.java,
+ java/nio/channels/ServerSocketChannel.java,
+ java/nio/channels/SocketChannel.java,
+ java/nio/channels/UnresolvedAddressException.java,
+ java/nio/channels/UnsupportedAddressTypeException.java,
+ java/nio/channels/WritableByteChannel.java,
+ java/nio/channels/spi/AbstractInterruptibleChannel.java,
+ java/nio/channels/spi/AbstractSelectableChannel.java,
+ java/nio/channels/spi/AbstractSelectionKey.java,
+ java/nio/channels/spi/AbstractSelector.java,
+ java/nio/channels/spi/SelectorProvider.java,
+ java/nio/charset/spi/CharsetProvider.java:
+ Fixed javadocs and jalopied all over java.nio.
+
+2004-04-20 Michael Koch <konqueror@gmx.de>
+
+ * java/nio/ByteBufferImpl.java,
+ java/nio/CharBufferImpl.java,
+ java/nio/DirectByteBufferImpl.java,
+ java/nio/DoubleBufferImpl.java,
+ java/nio/DoubleViewBufferImpl.java,
+ java/nio/FloatBufferImpl.java,
+ java/nio/FloatViewBufferImpl.java,
+ java/nio/IntBufferImpl.java,
+ java/nio/IntViewBufferImpl.java,
+ java/nio/LongBufferImpl.java,
+ java/nio/LongViewBufferImpl.java,
+ java/nio/MappedByteBufferImpl.java,
+ java/nio/ShortBufferImpl.java,
+ java/nio/ShortViewBufferImpl.java:
+ Made sure all classes are final and removed final keyword from all
+ methods.
+
+2004-04-20 Michael Koch <konqueror@gmx.de>
+
+ * java/rmi/MarshalledObject.java,
+ java/rmi/Naming.java,
+ java/rmi/RemoteException.java,
+ java/rmi/activation/ActivationException.java,
+ java/rmi/server/ServerCloneException.java,
+ java/security/AccessController.java,
+ java/security/AlgorithmParameterGenerator.java,
+ java/security/AlgorithmParameters.java,
+ java/security/CodeSource.java,
+ java/security/Identity.java,
+ java/security/IdentityScope.java,
+ java/security/KeyPairGenerator.java,
+ java/security/KeyStore.java,
+ java/security/Security.java,
+ java/security/Signature.java,
+ java/security/SignatureSpi.java,
+ java/security/SignedObject.java,
+ java/security/spec/DSAParameterSpec.java,
+ java/security/spec/DSAPrivateKeySpec.java,
+ java/security/spec/DSAPublicKeySpec.java,
+ java/sql/Array.java,
+ java/sql/DatabaseMetaData.java,
+ java/sql/ResultSet.java,
+ java/text/ChoiceFormat.java,
+ java/text/CollationElementIterator.java,
+ java/text/CollationKey.java,
+ java/text/Collator.java,
+ java/text/DateFormat.java,
+ java/text/DateFormatSymbols.java,
+ java/text/DecimalFormatSymbols.java,
+ java/text/Format.java,
+ java/text/ParsePosition.java,
+ java/text/RuleBasedCollator.java,
+ java/text/SimpleDateFormat.java,
+ java/text/StringCharacterIterator.java,
+ java/util/Collections.java,
+ java/util/PropertyResourceBundle.java,
+ java/util/ResourceBundle.java,
+ java/util/StringTokenizer.java,
+ java/util/jar/Attributes.java,
+ java/util/logging/ConsoleHandler.java,
+ java/util/logging/LogManager.java,
+ java/util/logging/MemoryHandler.java,
+ java/util/logging/SocketHandler.java,
+ javax/naming/NamingException.java:
+ Fixed javadoc, coding style and argument names all over.
+
+2004-04-20 Jeroen Frijters <jeroen@frijters.net>
+
+ * java/io/FileDescriptor.java: (FileDescriptor) Added public
+ constructor. (valid) Added null check.
+
+2004-04-20 Guilhem Lavaux <guilhem@kaffe.org>
+
+ Reported by Nektarios Papadopoulos <npapadop@inaccessnetworks.com>
+ * java/io/FileOutputStream.java
+ (FileOutputStream) Reorganized constructors. Constructors now
+ check whether the given path is directory.
+
+2004-04-20 Michael Koch <konqueror@gmx.de>
+
+ * java/net/Authenticator.java,
+ java/net/BindException.java,
+ java/net/ConnectException.java,
+ java/net/ContentHandler.java,
+ java/net/ContentHandlerFactory.java,
+ java/net/DatagramPacket.java,
+ java/net/DatagramSocket.java,
+ java/net/DatagramSocketImpl.java,
+ java/net/DatagramSocketImplFactory.java,
+ java/net/FileNameMap.java,
+ java/net/HttpURLConnection.java,
+ java/net/Inet4Address.java,
+ java/net/Inet6Address.java,
+ java/net/InetAddress.java,
+ java/net/InetSocketAddress.java,
+ java/net/JarURLConnection.java,
+ java/net/MalformedURLException.java,
+ java/net/MulticastSocket.java,
+ java/net/NetPermission.java,
+ java/net/NetworkInterface.java,
+ java/net/NoRouteToHostException.java,
+ java/net/PasswordAuthentication.java,
+ java/net/PortUnreachableException.java,
+ java/net/ProtocolException.java,
+ java/net/ServerSocket.java,
+ java/net/Socket.java,
+ java/net/SocketAddress.java,
+ java/net/SocketException.java,
+ java/net/SocketImpl.java,
+ java/net/SocketImplFactory.java,
+ java/net/SocketOptions.java,
+ java/net/SocketPermission.java,
+ java/net/SocketTimeoutException.java,
+ java/net/URI.java,
+ java/net/URISyntaxException.java,
+ java/net/URL.java,
+ java/net/URLClassLoader.java,
+ java/net/URLConnection.java,
+ java/net/URLDecoder.java,
+ java/net/URLEncoder.java,
+ java/net/URLStreamHandler.java,
+ java/net/URLStreamHandlerFactory.java,
+ java/net/UnknownHostException.java,
+ java/net/UnknownServiceException.java:
+ Fixed javadocs, coding style and argument names all over.
+
+2004-04-20 Michael Koch <konqueror@gmx.de>
+
+ * java/lang/Byte.java,
+ java/lang/CharSequence.java,
+ java/lang/ClassLoader.java,
+ java/lang/Compiler.java,
+ java/lang/Double.java,
+ java/lang/Float.java,
+ java/lang/Integer.java,
+ java/lang/Long.java,
+ java/lang/Math.java,
+ java/lang/Number.java,
+ java/lang/Package.java,
+ java/lang/Runtime.java,
+ java/lang/RuntimePermission.java,
+ java/lang/SecurityManager.java,
+ java/lang/Short.java,
+ java/lang/StringBuffer.java,
+ java/lang/System.java,
+ java/lang/ThreadGroup.java,
+ java/lang/Throwable.java,
+ java/lang/reflect/InvocationHandler.java,
+ java/lang/reflect/Proxy.java:
+ Fixed javadocs, coding style and argument names all over.
+
+2004-04-20 Michael Koch <konqueror@gmx.de>
+
+ * java/io/BufferedWriter.java,
+ java/io/ByteArrayInputStream.java,
+ java/io/CharArrayWriter.java,
+ java/io/DataInput.java,
+ java/io/DataInputStream.java,
+ java/io/File.java,
+ java/io/FilterInputStream.java,
+ java/io/InputStream.java,
+ java/io/InputStreamReader.java,
+ java/io/ObjectInputStream.java,
+ java/io/ObjectStreamClass.java,
+ java/io/PipedInputStream.java,
+ java/io/PipedReader.java,
+ java/io/PushbackInputStream.java,
+ java/io/PushbackReader.java,
+ java/io/RandomAccessFile.java,
+ java/io/SerializablePermission.java,
+ java/io/StreamTokenizer.java,
+ java/io/StringWriter.java,
+ java/io/WriteAbortedException.java,
+ java/io/Writer.java:
+ Fixed javadocs all over, rename arguments to match javadocs,
+ fixed coding style.
+
+2004-04-20 Ingo Proetel <proetel@aicas.com>
+
+ * java/awt/FontMetrics.java:
+ (charsWidth): fixed accumulation of total_width
+ (getWidth): simple default implementation
+ * java/awt/Polygon.java (getBoundingBox): Use correct y-coordinate
+ in Rectangle constructor.
+ * java/awt/image/Raster.java (toString): Added method.
+ * java/awt/image/SampleModel.java (<init>): Added error cause
+ information to thrown exception.
+ * java/awt/image/SinglePixelPackedSampleModel.java (getDataElements):
+ New method.
+ (setDataElements): New method.
+ (setPixels): New method.
+ (toString): New method.
+
+2004-04-20 Sascha Brawer <brawer@dandelis.ch>
+
+ * java/awt/image/ComponentColorModel.java
+ (createCompatibleSampleModel): Return PixelInterleavedSampleModel
+ for TYPE_BYTE and TYPE_USHORT transferTypes, in order to pass the
+ Mauve tests on this method. Improved documentation.
+
+2004-04-20 Michael Koch <konqueror@gmx.de>
+
+ * javax/swing/JLayeredPane.java,
+ javax/swing/plaf/BorderUIResource.java,
+ javax/swing/plaf/ComponentUI.java,
+ javax/swing/undo/CompoundEdit.java,
+ javax/swing/undo/StateEdit.java:
+ Fixed HTML tags in javadocs all over.
+
+2004-04-20 Michael Koch <konqueror@gmx.de>
+
+ * javax/print/attribute/EnumSyntax.java
+ (getOffset): Made protected.
+ * javax/print/attribute/HashAttributeSet.java
+ (HashAttributeSet): Likewise.
+ * javax/print/attribute/ResolutionSyntax.java
+ (getFeedResolution): Fixed typo in exception name.
+ (getCrossFeedResolution): Likewise.
+ * javax/print/attribute/SetOfIntegerSyntax.java
+ (SetOfIntegerSyntax): Fixed HTML entities in javadoc.
+ * javax/print/attribute/TextSyntax.java
+ (TextSyntax): Handle locale correctly.
+ (hashCode): Calc better hashcode value.
+ (equals): Fixed @return tag.
+ (toString): New method.
+
+2004-04-20 Michael Koch <konqueror@gmx.de>
+
+ * gnu/java/nio/FileLockImpl.java
+ (static): Removed, not needed anymore.
+ * gnu/java/nio/channels/FileChannelImpl.java
+ (FileChannelImpl): Made final.
+ (mode): Made private.
+ (READ, WRITE, APPEND): Made public.
+ (EXCL, SYNC, DSYNC): Likewise.
+ (static): Load native JNI library, when needed.
+ (length): Unused, removed.
+ (available): Made public.
+ (implPosition): Throws IOException.
+ (seek): Likewise.
+ (implTruncate): Likewise.
+ (unlock): Likewise.
+ (lock): Likewise.
+
+2004-04-20 Michael Koch <konqueror@gmx.de>
+
+ * java/awt/AWTPermission.java,
+ java/awt/Component.java,
+ java/awt/ComponentOrientation.java,,
+ java/awt/Dialog.java,
+ java/awt/FontMetrics.java,
+ java/awt/Graphics.java,
+ java/awt/datatransfer/DataFlavor.java,
+ java/beans/Introspector.java,
+ java/beans/PropertyEditor.java,
+ java/beans/PropertyEditorManager.java,
+ java/beans/beancontext/BeanContextServiceProvider.java:
+ Fixed HTML tags in javadocs all over.
+
+2004-04-20 Mark Wielaard <mark@klomp.org>
+
+ * gnu/java/awt/peer/gtk/GtkFontPeer.java: Use fallback when
+ MissingResourceException is thrown.
+ * gnu/java/awt/peer/gtk/GtkToolkit.java (getFontPeer): Don't return
+ null when a MissingResourceException is thrown. Should never happen.
+
+2004-04-20 Sascha Brawer <brawer@dandelis.ch>
+
+ * java/awt/image/DataBufferShort.java,
+ java/awt/image/DataBufferFloat.java,
+ java/awt/image/DataBufferDouble.java,
+ java/awt/image/PixelInterleavedSampleModel.java: New files.
+ * gnu/java/awt/Buffers.java (createBuffer, createBufferFromData,
+ getData): Added support for TYPE_SHORT, TYPE_FLOAT and TYPE_DOUBLE.
+
+2004-04-20 Michael Koch <konqueror@gmx.de>
+
+ * Makefile.am (java_source_files): Added
+ java/awt/image/DataBufferDouble.java,
+ java/awt/image/DataBufferFloat.java,
+ java/awt/image/DataBufferShort.java and
+ java/awt/image/PixelInterleavedSampleModel.java.
+ * Makefile.in: Regenerated.
+
+2004-04-19 Bryce McKinlay <mckinlay@redhat.com>
+
+ * gcj/cni.h (JvAllocObject): Remove these obsolete,
+ undocumented CNI calls.
+ * include/java-interp.h (_Jv_InterpClass): No longer
+ extends java.lang.Class.
+ * java/lang/Class.h (Class): Add new field `aux_info'.
+ * boehm.cc (_Jv_MarkObj): Update java.lang.Class marking.
+ * defineclass.cc: Remove Class<->_Jv_InterpClass casts.
+ Use Class->aux_info instead.
+ * jni.cc (_Jv_JNI_AllocObject): Use _Jv_AllocObject.
+ * resolve.cc: Remove Class<->_Jv_InterpClass casts.
+ Use Class->aux_info instead.
+ * java/io/natObjectInputStream.cc (allocateObject): Use
+ _Jv_AllocObject.
+ * java/lang/natClass.cc (newInstance): Likewise.
+ * java/lang/natClassLoader.cc (_Jv_NewClass): Likewise.
+ * java/lang/natObject.cc (clone): Likewise.
+ * java/lang/reflect/natMethod.cc (_Jv_CallAnyMethodA): Likewise.
+ * java/lang/natVMClassLoader.cc (defineClass): Don't use
+ JvAllocObject. Allocate klass->aux_info here for interpreted
+ class.
+
+2004-04-17 Mark Wielaard <mark@klomp.org>
+
+ * javax/swing/JToggleButton.java (ToggleButtonModel):
+ Make public static inner class.
+ * javax/swing/JTabbedPane.java (setComponentAt):
+ Call Page.setComponent().
+ (SCROLL_TAB_LAYOUT): Make public, value is 1.
+ (WRAP_TAB_LAYOUT): Make public, value is 0.
+ * javax/swing/plaf/basic/BasicTabbedPaneUI.java (ScrollingButton):
+ Make private static inner class.
+
+2004-04-16 Bryce McKinlay <mckinlay@redhat.com>
+
+ * interpret.cc (_Jv_InterpMethod::run): Update _Jv_AllocObject
+ arguments to match new signature. Remove FIXME comments.
+
+2004-04-09 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * gnu/java/awt/peer/gtk/GtkPanelPeer.java (connectSignals):
+ Remove method.
+ * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.c: Remove
+ unused code.
+
+2004-04-02 Olga Rodimina <rodimina@redhat.com>
+
+ * Makefile.am: Added new file.
+ * Makefile.in: Regenerate.
+ * javax/swing/ImageIcon.java:
+ (ImageIcon(file)): set description of the icon
+ to the file name
+ * javax/swing/JCheckBoxMenuItem.java:
+ Mostly Implemented. Work in progress.
+ * javax/swing/JRadioButtonMenuItem.java:
+ Reimplement constructors to use JToggleButtonModel.
+ * javax/swing/plaf/basic/BasicIconFactory.java:
+ (getCheckBoxMenuItemIcon): return check box
+ icon.
+ * javax/swing/plaf/basic/BasicMenuItemUI.java:
+ paint menu item selected only when it is armed and
+ pressed.
+
+2004-04-02 David Jee <djee@redhat.com>
+
+ * gnu/java/awt/peer/gtk/GtkMenuItemPeer.java
+ (GtkMenuItemPeer): Only connect signals if this isn't a Menu peer.
+ * java/awt/Component.java
+ (add): Set the parent of the popup as this component.
+ * java/awt/PopupMenu.java
+ (addNotify): Create popup menu when peer is null.
+ (show): Call addNotify() if peer is null.
+ * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c
+ (Java_gnu_java_awt_peer_gtk_GtkPopupMenuPeer_show): Set the button
+ argument for gtk_menu_popup() as zero. This causes the popup menu to
+ respond to any mouse button.
+
+2004-03-31 Olga Rodimina <rodimina@redhat.com>
+
+ * Makefile.am: Added new file.
+ * Makefile.in: Regenerate.
+ * javax/swing/JRadioButtonMenuItem.java:
+ Implemented.
+ * javax/swing/plaf/basic/BasicIconFactory.java:
+ (getRadioButtonMenuItemIcon): Return
+ radio button icon.
+ * javax/swing/plaf/basic/BasicMenuItemUI.java:
+ (getPreferredSize): Add size of checkIcon if it
+ exists.
+ (installDefaults): Don't initialize checkIcon.
+ It's value will be set in subclasses.
+ (uninstallDefaults): remove uninstallation of
+ checkIcon.
+ (paint): Moved code to paintMenuItem().
+ (paintMenuItem): Implemented.
+ * javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java:
+ UI delegate for JRadioButtonMenuItem.
+
+2004-03-29 Olga Rodimina <rodimina@redhat.com>
+
+ * javax/swing/plaf/basic/BasicMenuItemUI.java:
+ Corrected position of the accelerator.
+
+2004-03-29 Olga Rodimina <rodimina@redhat.com>
+
+ * Makefile.am: Added new file.
+ * Makefile.in: Regenerate.
+ * javax/swing/JMenuItem.java: Partly
+ implemented. Work in progress
+ * javax/swing/plaf/basic/BasicLookAndFeel.java:
+ Changed default value of acceleratorDelimiter.
+ * javax/swing/plaf/basic/BasicMenuItemUI.java:
+ New class. Partly implemented.
+
+2004-03-26 Mark Wielaard <mark@klomp.org>
+
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c
+ (item_activate): Declare label before use.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
+ (gtkSetFont): Removed unused variable label.
+ (addExposeFilter): Declare variables before use.
+ (removeExposeFilter): Likewise.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c
+ (ok_clicked): Declare str_fileName before use.
+
+2004-03-26 David Jee <djee@redhat.com>
+
+ * gnu/java/awt/peer/gtk/GtkMenuPeer.java
+ (addSeparator): Remove.
+ * java/awt/Menu.java
+ (separator): Remove static final MenuItem field.
+ (separatorLabel): New static final String field.
+ (addSeparator): Do not use peer method; use add(MenuItem) instead.
+ Use separatorLabel to denote that it is a separator.
+ (insertSeparator): Create a new MenuItem with separatorLabel, instead
+ of reusing the static separator instance, because a MenuItem instance
+ can't be added more than once without being cloned.
+ * java/awt/peer/MenuPeer.java
+ (addSeparator): Remove from interface.
+
+2004-03-26 David Jee <djee@redhat.com>
+
+ * gnu/java/awt/peer/gtk/GtkMenuItemPeer.java
+ (connectSignals): New native method declaration.
+ (GtkMenuItemPeer): Connect signals if the parent is a Menu.
+ * java/awt/MenuItem.java
+ (getActionCommand): Return the label if the action command is not set.
+ * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c
+ (Java_gnu_java_awt_peer_gtk_GtkMenuBarPeer_addMenu): Use
+ gtk_menu_shell_append().
+ * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c
+ (item_activate): Fix argument type.
+ (Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_create): Do not connect
+ signal here.
+ (Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_connectSignals): New
+ method.
+ * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c
+ (Java_gnu_java_awt_peer_gtk_GtkMenuPeer_create): Check if a label is
+ given. Add the menu widget's top-level GtkWindow to the global window
+ group, so it can grab the pointer.
+ (Java_gnu_java_awt_peer_gtk_GtkMenuPeer_addItem): Use
+ gtk_menu_shell_append().
+
+2004-03-23 Graydon Hoare <graydon@redhat.com>
+
+ * java/text/AttributedString.java
+ (addAttribute): Fix off-by-one.
+ (getIterator): Likewise.
+ * java/text/AttributedStringIterator.java
+ (getRunLimit): Correct logic.
+ (getRunStart): Likewise.
+ (getAttribute): Fix inequality.
+ (getAttributes): Likewise.
+ * testsuite/libjava.mauve/xfails: Remove AttributedString xfail.
+
+2004-03-23 Kim Ho <kho@redhat.com>
+
+ * javax/swing/plaf/basic/BasicTabbedPaneUI.java:
+ (calculateSizes): Return real width and height.
+
+2004-03-23 Kim Ho <kho@redhat.com>
+
+ * javax/swing/plaf/basic/BasicTabbedPaneUI.java
+ (calculateTabRects): Set the selectedRun before
+ trying to rotate tabs.
+
+2004-03-23 Kim Ho <kho@redhat.com>
+
+ * Makefile.am: New file
+ * Makefile.in: Regenerate
+ * java/awt/Graphics.java: (drawRect):
+ Draw to the correct point.
+ * javax/swing/DefaultSingleSelectionModel.java
+ (isSelected): Return true if the selected index
+ is not -1.
+ * javax/swing/JLabel.java: Do not change mnemonic
+ index if text is null.
+ * javax/swing/JProgressBar.java: Use JComponent's
+ EventListenerList.
+ * javax/swing/JScrollBar.java: Ditto.
+ * javax/swing/JSlider.java: Ditto.
+ * javax/swing/JTabbedPane.java: Reimplement.
+ * javax/swing/plaf/basic/BasicLookAndFeel.java:
+ Add defaults for TabbedPane.
+ * javax/swing/plaf/basic/BasicArrowButton.java:
+ Implement
+ * javax/swing/plaf/basic/BasicProgressBarUI.java:
+ (paintDeterminate): Don't paint String if it's
+ empty.
+ (paintIndeterminate): ditto.
+ * javax/swing/plaf/basic/BasicTabbedPaneUI.java:
+ Reimplement.
+
+2004-03-19 Michael Koch <konqueror@gmx.de>
+
+ * java/awt/image/AffineTransformOp.java
+ (AffineTransformOp): Made public.
+ * javax/swing/JComponent.java
+ (listenerList): Made protected.
+ (accessibleContext): Likewise.
+ * javax/swing/JList.java
+ (valueChanged): Dont use internal fields of ListSelectionEvent.
+ * javax/swing/JViewport.java
+ (getView): Dont use internal fields of Component.
+ (addImpl): Likewise.
+ * javax/swing/Timer.java
+ (isRunning): Made public.
+ (start): Likewise.
+ (stop): Likewise.
+ * javax/swing/UIDefaults.java
+ (getInt): Made public.
+ * javax/swing/plaf/basic/BasicListUI.java
+ (mousePressed): Dont use internal fields of MouseEvent.
+ (propertyChanged): Dont use internal fields of PropertyChangeEvent.
+ * javax/swing/plaf/basic/BasicScrollBarUI.java
+ (arrowIcon): Made static.
+ * javax/swing/plaf/basic/BasicViewportUI.java
+ (stateChanged): Dont use internal field on ChangeEvent.
+ * javax/swing/text/JTextComponent.java
+ (getUI): Call UIManager.getUI().
+ (updateUI): Use getUI().
+
+2004-03-19 Graydon Hoare <graydon@redhat.com>
+
+ * javax/swing/JComponent.java: Turn off double buffer by default.
+ * javax/swing/plaf/basic/BasicViewportUI.java: Clear rects before painting.
+ * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
+ (Java_gnu_java_awt_peer_gtk_GdkGraphics2D_gdkDrawDrawable):
+ Use cairo to copy areas.
+ (Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClip):
+ Initialize and set clip region.
+
+2004-03-15 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * java/applet/Applet.java (preferredSize): Override deprecated
+ variant of getPreferredSize.
+ (minimumSize): Override deprecated variant of getMinimumSize.
+
+2004-03-15 Olga Rodimina <rodimina@redhat.com>
+
+ * gnu/java/awt/peer/gtk/GdkGraphics2D.java
+ (drawImage(img,xform,bgcolor,obs)): New Method.
+ Helper function that every drawImage method will
+ use.
+ (drawRaster): Added new parameter, bgcolor. All
+ transparent pixels are changed to bgcolor before
+ image is drawn.
+ (drawRenderedImage): Fixed to use changed drawRaster().
+ (drawImage(image,xform,obs): Fixed to use new helper function
+ (drawImage(image,op,x,y)): Ditto.
+ (drawImage (img,x,y,observer)): Ditto.
+ ((PainterThread) bgcolor): New Field.
+ ((PainterThread) (setPixels)): Changed all transparent pixels
+ to bgcolor.
+ (drawImage(img,x,y,width,height,bgcolor,observer)):
+ Fixed FIXME - all the transparent pixels are
+ changed to the specified bgcolor.
+ (drawImage(img, x, y, width, height, observer): Changed to
+ use function above.
+ (drawImage (img,dx1,dy1,dx2,dy2,sx1,sy1,sx2,sy2,bgcolor,observer)):
+ Fixed FIXME- changed all transparent pixels to bgcolor.
+ (drawImage (img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, observer)):
+ Changed to use function above.
+
+2004-03-14 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * java/applet/Applet.java (dimensions): New field.
+ (getDimensions): New method.
+ (getPreferredSize): Call getDimensions.
+ (getMinimumSize): Likewise.
+
+2004-03-13 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * jni/classpath/jcl.c: Include stdlib.h, not malloc.h.
+ * jni/classpath/jnilink.c: Likewise.
+
+ * java/applet/Applet.java (getPreferredSize): New method.
+ (getMinimumSize): New method.
+
+2004-04-15 Bryce McKinlay <mckinlay@redhat.com>
+
+ * prims.cc (_Jv_AllocObject): Remove `size' argument.
+ (_Jv_AllocObjectNoFinalizer): Likewise.
+ (_Jv_AllocObjectNoInitNoFinalizer): Likewise.
+ (_Jv_AllocPtrFreeObject): Likewise.
+ (_Jv_AllocString): Moved from natString.cc. Call collector interface
+ directly even in the JVMPI case.
+ * gcj/cni.h (JvAllocObject): Remove `size' argument from
+ _Jv_AllocObject calls.
+ * gcj/javaprims.h: Update prototypes.
+ * gnu/gcj/natCore.cc (_Jv_create_core): Use `new', not _Jv_AllocObject.
+ * java/lang/Class.h: Update _Jv_AllocObject friend prototype.
+ * java/lang/natString.cc (_Jv_AllocString): Move to prims.cc.
+
+2004-04-14 Andrew Haley <aph@redhat.com>
+ Bryce McKinlay <mckinlay@redhat.com>
+
+ * java/lang/reflect/natMethod.cc (_Jv_CallAnyMethodA): Use
+ _Jv_LookupInterfaceMethodIdx for calls to interfaces.
+ * include/jvm.h (_Jv_CallAnyMethodA): Add new `iface' arg.
+
+ * testsuite/libjava.lang/InvokeInterface.java: New file.
+ * testsuite/libjava.lang/InvokeInterface.out: New file.
+
2004-04-09 Ranjit Mathew <rmathew@hotmail.com>
* java/lang/VMThrowable.java (getStackTrace): Pass trace as-is to
diff --git a/libjava/Makefile.am b/libjava/Makefile.am
index ddec112c38c..c652faea53f 100644
--- a/libjava/Makefile.am
+++ b/libjava/Makefile.am
@@ -103,7 +103,7 @@ JAVAC = $(GCJ_WITH_FLAGS) -C
GCC_UNWIND_INCLUDE = @GCC_UNWIND_INCLUDE@
-WARNINGS = -W -Wall
+WARNINGS = -Wextra -Wall
## We need _GNU_SOURCE defined for some Linux builds. It doesn't hurt
## to always define it.
AM_CXXFLAGS = -fno-rtti -fnon-call-exceptions $(THREADCXXFLAGS) \
@@ -120,6 +120,9 @@ else
AM_CFLAGS = @LIBGCJ_CFLAGS@
endif
+## Extra CFLAGS used for JNI C sources shared with GNU Classpath.
+PEDANTIC_CFLAGS = -ansi -pedantic -Wall -Wno-long-long
+
JCFLAGS = -g
JC1FLAGS = @LIBGCJ_JAVAFLAGS@ $(GCJFLAGS)
@@ -149,7 +152,7 @@ javao_files = $(java_source_files:.java=.lo) \
x_javao_files = $(x_java_source_files:.java=.lo)
libgcj_la_SOURCES = prims.cc jni.cc exception.cc \
- resolve.cc defineclass.cc interpret.cc verify.cc \
+ link.cc defineclass.cc interpret.cc verify.cc \
$(nat_source_files)
EXTRA_libgcj_la_SOURCES = boehm.cc nogc.cc posix-threads.cc no-threads.cc \
win32-threads.cc posix.cc win32.cc $(c_source_files) \
@@ -188,6 +191,7 @@ jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c \
+jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c \
@@ -196,6 +200,7 @@ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c \
+jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImagePainter.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c \
@@ -465,15 +470,24 @@ $(nat_files) $(x_nat_files): %.lo: %.cc
$(c_files): %.lo: %.c
$(LTCOMPILE) -c -o $@ $<
+## A special rule for interpret.lo for the time being. Our current
+## approach to stack-trace handling is fragile and will not work with
+## unit-at-a-time. So, for now we disable it. This will be fixed by
+## a larger patch in the future.
+interpret.lo: interpret.cc
+ $(LTCXXCOMPILE) -fno-unit-at-a-time -c -o $@ $<
+
$(extra_cc_files): %.lo: %.cc
$(LTCXXCOMPILE) -c -o $@ $<
$(c_files): java/lang/fdlibm.h java/lang/ieeefp.h java/lang/mprec.h
## FIXME: see above
+## These JNI C files are shared with GNU Classpath which needs PEDANTIC_CFLAGS.
$(gtk_c_files): %.lo: %.c
$(LTCOMPILE) -c -Ijniinclude -I$(srcdir)/jni/classpath -I$(srcdir)/jni/gtk-peer \
- $(GTK_CFLAGS) $(LIBART_CFLAGS) $(CAIRO_LIBS) $(PANGOFT2_LIBS) -o $@ $<
+ $(PEDANTIC_CFLAGS) $(GTK_CFLAGS) $(LIBART_CFLAGS) \
+ $(CAIRO_LIBS) $(PANGOFT2_LIBS) -o $@ $<
$(gtk_c_files): $(gtk_c_headers)
@@ -493,6 +507,9 @@ $(gtk_awt_peer_sources:.java=.lo): %.lo: %.java
gnu/gcj/runtime/StackTrace.lo: gnu/gcj/runtime/StackTrace.java
$(GCJCOMPILE) -fno-optimize-sibling-calls -o $@ $<
+java/io/ObjectInputStream.lo: java/io/ObjectInputStream.java
+ $(GCJCOMPILE) -fno-optimize-sibling-calls -o $@ $<
+
## Pass the list of object files to libtool in a temporary file to
## avoid tripping platform command line length limits.
libgcj.la: $(libgcj_la_OBJECTS) $(libgcj_la_DEPENDENCIES)
@@ -1113,7 +1130,10 @@ java/awt/image/ComponentColorModel.java \
java/awt/image/ComponentSampleModel.java \
java/awt/image/DataBuffer.java \
java/awt/image/DataBufferByte.java \
+java/awt/image/DataBufferDouble.java \
+java/awt/image/DataBufferFloat.java \
java/awt/image/DataBufferInt.java \
+java/awt/image/DataBufferShort.java \
java/awt/image/DataBufferUShort.java \
java/awt/image/DirectColorModel.java \
java/awt/image/ImageConsumer.java \
@@ -1121,6 +1141,7 @@ java/awt/image/ImageObserver.java \
java/awt/image/ImageProducer.java \
java/awt/image/IndexColorModel.java \
java/awt/image/PackedColorModel.java \
+java/awt/image/PixelInterleavedSampleModel.java \
java/awt/image/Raster.java \
java/awt/image/RasterOp.java \
java/awt/image/SampleModel.java \
@@ -1326,17 +1347,21 @@ javax/swing/border/TitledBorder.java \
javax/swing/GrayFilter.java \
javax/swing/AbstractAction.java \
javax/swing/AbstractButton.java \
+javax/swing/plaf/basic/BasicArrowButton.java \
javax/swing/plaf/basic/BasicButtonListener.java \
javax/swing/plaf/basic/BasicButtonUI.java \
javax/swing/plaf/basic/BasicCheckBoxUI.java \
javax/swing/plaf/basic/BasicGraphicsUtils.java \
javax/swing/plaf/basic/BasicLabelUI.java \
javax/swing/plaf/basic/BasicListUI.java \
+javax/swing/plaf/basic/BasicMenuItemUI.java \
javax/swing/plaf/basic/BasicOptionPaneUI.java \
javax/swing/plaf/basic/BasicPanelUI.java \
javax/swing/plaf/basic/BasicProgressBarUI.java \
javax/swing/plaf/basic/BasicRootPaneUI.java \
javax/swing/plaf/basic/BasicRadioButtonUI.java \
+javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java \
+javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java \
javax/swing/plaf/basic/BasicScrollBarUI.java \
javax/swing/plaf/basic/BasicScrollPaneUI.java \
javax/swing/plaf/basic/BasicSeparatorUI.java \
@@ -1740,6 +1765,19 @@ javax/accessibility/AccessibleTable.java \
javax/accessibility/AccessibleTableModelChange.java \
javax/accessibility/AccessibleText.java \
javax/accessibility/AccessibleValue.java \
+javax/imageio/ImageReader.java \
+javax/imageio/ImageTranscoder.java \
+javax/imageio/ImageWriter.java \
+javax/imageio/spi/IIOServiceProvider.java \
+javax/imageio/spi/ImageInputStreamSpi.java \
+javax/imageio/spi/ImageOutputStreamSpi.java \
+javax/imageio/spi/ImageReaderWriterSpi.java \
+javax/imageio/spi/ImageTranscoderSpi.java \
+javax/imageio/spi/RegisterableService.java \
+javax/imageio/spi/ServiceRegistry.java \
+javax/imageio/stream/IIOByteBuffer.java \
+javax/imageio/stream/ImageInputStream.java \
+javax/imageio/stream/ImageOutputStream.java \
javax/naming/directory/Attribute.java \
javax/naming/directory/AttributeInUseException.java \
javax/naming/directory/AttributeModificationException.java \
@@ -2005,6 +2043,7 @@ java/lang/UnsupportedOperationException.java \
java/lang/VerifyError.java \
java/lang/VirtualMachineError.java \
java/lang/VMClassLoader.java \
+java/lang/VMCompiler.java \
java/lang/VMSecurityManager.java \
java/lang/VMThrowable.java \
java/lang/Void.java \
@@ -2179,6 +2218,8 @@ java/util/regex/PatternSyntaxException.java
## awt_java_source_files. If the .java file has a hand-maintained
## header, please list it in special_java_source_files.
ordinary_java_source_files = $(core_java_source_files) \
+gnu/classpath/ServiceFactory.java \
+gnu/classpath/ServiceProviderLoadingAction.java \
gnu/gcj/Core.java \
gnu/gcj/RawData.java \
gnu/gcj/io/DefaultMimeTypes.java \
@@ -2195,6 +2236,7 @@ gnu/gcj/runtime/SharedLibLoader.java \
gnu/gcj/runtime/StackTrace.java \
gnu/gcj/runtime/StringBuffer.java \
gnu/gcj/runtime/VMClassLoader.java \
+gnu/gcj/util/Debug.java \
gnu/java/io/ASN1ParsingException.java \
gnu/java/io/Base64InputStream.java \
gnu/java/io/ClassLoaderObjectInputStream.java \
@@ -2441,10 +2483,14 @@ gnu/java/security/x509/X500DistinguishedName.java \
gnu/java/security/x509/X509Certificate.java \
gnu/java/security/x509/X509CRLEntry.java \
gnu/java/security/x509/X509CRL.java \
+gnu/java/text/AttributedFormatBuffer.java \
gnu/java/text/BaseBreakIterator.java \
gnu/java/text/CharacterBreakIterator.java \
+gnu/java/text/FormatBuffer.java \
+gnu/java/text/FormatCharacterIterator.java \
gnu/java/text/LineBreakIterator.java \
gnu/java/text/SentenceBreakIterator.java \
+gnu/java/text/StringFormatBuffer.java \
gnu/java/text/WordBreakIterator.java \
gnu/java/util/DoubleEnumeration.java \
gnu/java/util/EmptyEnumeration.java \
@@ -2784,7 +2830,6 @@ java/text/DecimalFormat.java \
java/text/DecimalFormatSymbols.java \
java/text/FieldPosition.java \
java/text/Format.java \
-java/text/FormatCharacterIterator.java \
java/text/MessageFormat.java \
java/text/NumberFormat.java \
java/text/ParseException.java \
@@ -2865,6 +2910,7 @@ gnu/gcj/runtime/natSharedLibLoader.cc \
gnu/gcj/runtime/natStackTrace.cc \
gnu/gcj/runtime/natStringBuffer.cc \
gnu/gcj/runtime/natVMClassLoader.cc \
+gnu/gcj/util/natDebug.cc \
gnu/java/awt/natEmbeddedWindow.cc \
gnu/java/net/natPlainDatagramSocketImpl.cc \
gnu/java/net/natPlainSocketImpl.cc \
diff --git a/libjava/Makefile.in b/libjava/Makefile.in
index c23863a1526..d0d0e0de6a7 100644
--- a/libjava/Makefile.in
+++ b/libjava/Makefile.in
@@ -211,7 +211,7 @@ JAVAC = $(GCJ_WITH_FLAGS) -C
GCC_UNWIND_INCLUDE = @GCC_UNWIND_INCLUDE@
-WARNINGS = -W -Wall
+WARNINGS = -Wextra -Wall
AM_CXXFLAGS = -fno-rtti -fnon-call-exceptions $(THREADCXXFLAGS) \
-fdollars-in-identifiers \
-Wswitch-enum \
@@ -222,6 +222,8 @@ AM_CXXFLAGS = -fno-rtti -fnon-call-exceptions $(THREADCXXFLAGS) \
@USING_GCC_TRUE@AM_CFLAGS = @USING_GCC_TRUE@@LIBGCJ_CFLAGS@ $(WARNINGS)
@USING_GCC_FALSE@AM_CFLAGS = @USING_GCC_FALSE@@LIBGCJ_CFLAGS@
+PEDANTIC_CFLAGS = -ansi -pedantic -Wall -Wno-long-long
+
JCFLAGS = -g
JC1FLAGS = @LIBGCJ_JAVAFLAGS@ $(GCJFLAGS)
@@ -243,7 +245,7 @@ javao_files = $(java_source_files:.java=.lo) \
x_javao_files = $(x_java_source_files:.java=.lo)
libgcj_la_SOURCES = prims.cc jni.cc exception.cc \
- resolve.cc defineclass.cc interpret.cc verify.cc \
+ link.cc defineclass.cc interpret.cc verify.cc \
$(nat_source_files)
EXTRA_libgcj_la_SOURCES = boehm.cc nogc.cc posix-threads.cc no-threads.cc \
@@ -280,6 +282,7 @@ jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c \
+jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c \
@@ -288,6 +291,7 @@ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c \
+jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImagePainter.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.c \
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c \
@@ -795,7 +799,10 @@ java/awt/image/ComponentColorModel.java \
java/awt/image/ComponentSampleModel.java \
java/awt/image/DataBuffer.java \
java/awt/image/DataBufferByte.java \
+java/awt/image/DataBufferDouble.java \
+java/awt/image/DataBufferFloat.java \
java/awt/image/DataBufferInt.java \
+java/awt/image/DataBufferShort.java \
java/awt/image/DataBufferUShort.java \
java/awt/image/DirectColorModel.java \
java/awt/image/ImageConsumer.java \
@@ -803,6 +810,7 @@ java/awt/image/ImageObserver.java \
java/awt/image/ImageProducer.java \
java/awt/image/IndexColorModel.java \
java/awt/image/PackedColorModel.java \
+java/awt/image/PixelInterleavedSampleModel.java \
java/awt/image/Raster.java \
java/awt/image/RasterOp.java \
java/awt/image/SampleModel.java \
@@ -1008,17 +1016,21 @@ javax/swing/border/TitledBorder.java \
javax/swing/GrayFilter.java \
javax/swing/AbstractAction.java \
javax/swing/AbstractButton.java \
+javax/swing/plaf/basic/BasicArrowButton.java \
javax/swing/plaf/basic/BasicButtonListener.java \
javax/swing/plaf/basic/BasicButtonUI.java \
javax/swing/plaf/basic/BasicCheckBoxUI.java \
javax/swing/plaf/basic/BasicGraphicsUtils.java \
javax/swing/plaf/basic/BasicLabelUI.java \
javax/swing/plaf/basic/BasicListUI.java \
+javax/swing/plaf/basic/BasicMenuItemUI.java \
javax/swing/plaf/basic/BasicOptionPaneUI.java \
javax/swing/plaf/basic/BasicPanelUI.java \
javax/swing/plaf/basic/BasicProgressBarUI.java \
javax/swing/plaf/basic/BasicRootPaneUI.java \
javax/swing/plaf/basic/BasicRadioButtonUI.java \
+javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java \
+javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java \
javax/swing/plaf/basic/BasicScrollBarUI.java \
javax/swing/plaf/basic/BasicScrollPaneUI.java \
javax/swing/plaf/basic/BasicSeparatorUI.java \
@@ -1424,6 +1436,19 @@ javax/accessibility/AccessibleTable.java \
javax/accessibility/AccessibleTableModelChange.java \
javax/accessibility/AccessibleText.java \
javax/accessibility/AccessibleValue.java \
+javax/imageio/ImageReader.java \
+javax/imageio/ImageTranscoder.java \
+javax/imageio/ImageWriter.java \
+javax/imageio/spi/IIOServiceProvider.java \
+javax/imageio/spi/ImageInputStreamSpi.java \
+javax/imageio/spi/ImageOutputStreamSpi.java \
+javax/imageio/spi/ImageReaderWriterSpi.java \
+javax/imageio/spi/ImageTranscoderSpi.java \
+javax/imageio/spi/RegisterableService.java \
+javax/imageio/spi/ServiceRegistry.java \
+javax/imageio/stream/IIOByteBuffer.java \
+javax/imageio/stream/ImageInputStream.java \
+javax/imageio/stream/ImageOutputStream.java \
javax/naming/directory/Attribute.java \
javax/naming/directory/AttributeInUseException.java \
javax/naming/directory/AttributeModificationException.java \
@@ -1685,6 +1710,7 @@ java/lang/UnsupportedOperationException.java \
java/lang/VerifyError.java \
java/lang/VirtualMachineError.java \
java/lang/VMClassLoader.java \
+java/lang/VMCompiler.java \
java/lang/VMSecurityManager.java \
java/lang/VMThrowable.java \
java/lang/Void.java \
@@ -1854,6 +1880,8 @@ java/util/regex/PatternSyntaxException.java
ordinary_java_source_files = $(core_java_source_files) \
+gnu/classpath/ServiceFactory.java \
+gnu/classpath/ServiceProviderLoadingAction.java \
gnu/gcj/Core.java \
gnu/gcj/RawData.java \
gnu/gcj/io/DefaultMimeTypes.java \
@@ -1870,6 +1898,7 @@ gnu/gcj/runtime/SharedLibLoader.java \
gnu/gcj/runtime/StackTrace.java \
gnu/gcj/runtime/StringBuffer.java \
gnu/gcj/runtime/VMClassLoader.java \
+gnu/gcj/util/Debug.java \
gnu/java/io/ASN1ParsingException.java \
gnu/java/io/Base64InputStream.java \
gnu/java/io/ClassLoaderObjectInputStream.java \
@@ -2116,10 +2145,14 @@ gnu/java/security/x509/X500DistinguishedName.java \
gnu/java/security/x509/X509Certificate.java \
gnu/java/security/x509/X509CRLEntry.java \
gnu/java/security/x509/X509CRL.java \
+gnu/java/text/AttributedFormatBuffer.java \
gnu/java/text/BaseBreakIterator.java \
gnu/java/text/CharacterBreakIterator.java \
+gnu/java/text/FormatBuffer.java \
+gnu/java/text/FormatCharacterIterator.java \
gnu/java/text/LineBreakIterator.java \
gnu/java/text/SentenceBreakIterator.java \
+gnu/java/text/StringFormatBuffer.java \
gnu/java/text/WordBreakIterator.java \
gnu/java/util/DoubleEnumeration.java \
gnu/java/util/EmptyEnumeration.java \
@@ -2459,7 +2492,6 @@ java/text/DecimalFormat.java \
java/text/DecimalFormatSymbols.java \
java/text/FieldPosition.java \
java/text/Format.java \
-java/text/FormatCharacterIterator.java \
java/text/MessageFormat.java \
java/text/NumberFormat.java \
java/text/ParseException.java \
@@ -2539,6 +2571,7 @@ gnu/gcj/runtime/natSharedLibLoader.cc \
gnu/gcj/runtime/natStackTrace.cc \
gnu/gcj/runtime/natStringBuffer.cc \
gnu/gcj/runtime/natVMClassLoader.cc \
+gnu/gcj/util/natDebug.cc \
gnu/java/awt/natEmbeddedWindow.cc \
gnu/java/net/natPlainDatagramSocketImpl.cc \
gnu/java/net/natPlainSocketImpl.cc \
@@ -2709,8 +2742,8 @@ X_CFLAGS = @X_CFLAGS@
X_LIBS = @X_LIBS@
X_EXTRA_LIBS = @X_EXTRA_LIBS@
X_PRE_LIBS = @X_PRE_LIBS@
-libgcj_la_OBJECTS = prims.lo jni.lo exception.lo resolve.lo \
-defineclass.lo interpret.lo verify.lo gnu/gcj/natCore.lo \
+libgcj_la_OBJECTS = prims.lo jni.lo exception.lo link.lo defineclass.lo \
+interpret.lo verify.lo gnu/gcj/natCore.lo \
gnu/gcj/convert/JIS0208_to_Unicode.lo \
gnu/gcj/convert/JIS0212_to_Unicode.lo gnu/gcj/convert/Unicode_to_JIS.lo \
gnu/gcj/convert/natIconv.lo gnu/gcj/convert/natInput_EUCJIS.lo \
@@ -2720,7 +2753,7 @@ gnu/gcj/io/shs.lo gnu/gcj/runtime/natFinalizerThread.lo \
gnu/gcj/runtime/natFirstThread.lo gnu/gcj/runtime/natNameFinder.lo \
gnu/gcj/runtime/natSharedLibLoader.lo gnu/gcj/runtime/natStackTrace.lo \
gnu/gcj/runtime/natStringBuffer.lo gnu/gcj/runtime/natVMClassLoader.lo \
-gnu/java/awt/natEmbeddedWindow.lo \
+gnu/gcj/util/natDebug.lo gnu/java/awt/natEmbeddedWindow.lo \
gnu/java/net/natPlainDatagramSocketImpl.lo \
gnu/java/net/natPlainSocketImpl.lo \
gnu/java/net/protocol/core/natCoreInputStream.lo \
@@ -2831,6 +2864,7 @@ lib_gnu_java_awt_peer_gtk_la_DEPENDENCIES =
@GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.lo \
@GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.lo \
@GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.lo \
+@GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.lo \
@GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.lo \
@GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.lo \
@GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.lo \
@@ -2839,6 +2873,7 @@ lib_gnu_java_awt_peer_gtk_la_DEPENDENCIES =
@GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.lo \
@GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.lo \
@GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.lo \
+@GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.lo \
@GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImagePainter.lo \
@GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.lo \
@GTK_CAIRO_FALSE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.lo \
@@ -2913,6 +2948,7 @@ lib_gnu_java_awt_peer_gtk_la_DEPENDENCIES =
@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.lo \
@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.lo \
@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.lo \
+@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.lo \
@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.lo \
@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.lo \
@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.lo \
@@ -2921,6 +2957,7 @@ lib_gnu_java_awt_peer_gtk_la_DEPENDENCIES =
@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.lo \
@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.lo \
@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.lo \
+@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.lo \
@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImagePainter.lo \
@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.lo \
@GTK_CAIRO_TRUE@jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.lo \
@@ -3002,9 +3039,10 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/gnu/awt/xlib/XGraphicsConfiguration.P \
.deps/gnu/awt/xlib/XOffScreenImage.P .deps/gnu/awt/xlib/XPanelPeer.P \
.deps/gnu/awt/xlib/XToolkit.P .deps/gnu/classpath/Configuration.P \
-.deps/gnu/gcj/Core.P .deps/gnu/gcj/RawData.P \
-.deps/gnu/gcj/convert/BytesToUnicode.P .deps/gnu/gcj/convert/Convert.P \
-.deps/gnu/gcj/convert/IOConverter.P \
+.deps/gnu/classpath/ServiceFactory.P \
+.deps/gnu/classpath/ServiceProviderLoadingAction.P .deps/gnu/gcj/Core.P \
+.deps/gnu/gcj/RawData.P .deps/gnu/gcj/convert/BytesToUnicode.P \
+.deps/gnu/gcj/convert/Convert.P .deps/gnu/gcj/convert/IOConverter.P \
.deps/gnu/gcj/convert/Input_8859_1.P \
.deps/gnu/gcj/convert/Input_ASCII.P \
.deps/gnu/gcj/convert/Input_EUCJIS.P \
@@ -3044,7 +3082,8 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/gnu/gcj/runtime/natSharedLibLoader.P \
.deps/gnu/gcj/runtime/natStackTrace.P \
.deps/gnu/gcj/runtime/natStringBuffer.P \
-.deps/gnu/gcj/runtime/natVMClassLoader.P .deps/gnu/gcj/xlib/Clip.P \
+.deps/gnu/gcj/runtime/natVMClassLoader.P .deps/gnu/gcj/util/Debug.P \
+.deps/gnu/gcj/util/natDebug.P .deps/gnu/gcj/xlib/Clip.P \
.deps/gnu/gcj/xlib/Colormap.P .deps/gnu/gcj/xlib/Display.P \
.deps/gnu/gcj/xlib/Drawable.P .deps/gnu/gcj/xlib/Font.P \
.deps/gnu/gcj/xlib/GC.P .deps/gnu/gcj/xlib/Pixmap.P \
@@ -3384,10 +3423,14 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/gnu/java/security/x509/X509CRL.P \
.deps/gnu/java/security/x509/X509CRLEntry.P \
.deps/gnu/java/security/x509/X509Certificate.P \
+.deps/gnu/java/text/AttributedFormatBuffer.P \
.deps/gnu/java/text/BaseBreakIterator.P \
.deps/gnu/java/text/CharacterBreakIterator.P \
+.deps/gnu/java/text/FormatBuffer.P \
+.deps/gnu/java/text/FormatCharacterIterator.P \
.deps/gnu/java/text/LineBreakIterator.P \
.deps/gnu/java/text/SentenceBreakIterator.P \
+.deps/gnu/java/text/StringFormatBuffer.P \
.deps/gnu/java/text/WordBreakIterator.P \
.deps/gnu/java/util/DoubleEnumeration.P \
.deps/gnu/java/util/EmptyEnumeration.P \
@@ -3587,7 +3630,10 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/java/awt/image/ComponentSampleModel.P \
.deps/java/awt/image/CropImageFilter.P \
.deps/java/awt/image/DataBuffer.P .deps/java/awt/image/DataBufferByte.P \
+.deps/java/awt/image/DataBufferDouble.P \
+.deps/java/awt/image/DataBufferFloat.P \
.deps/java/awt/image/DataBufferInt.P \
+.deps/java/awt/image/DataBufferShort.P \
.deps/java/awt/image/DataBufferUShort.P \
.deps/java/awt/image/DirectColorModel.P \
.deps/java/awt/image/FilteredImageSource.P \
@@ -3599,6 +3645,7 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/java/awt/image/MemoryImageSource.P \
.deps/java/awt/image/PackedColorModel.P \
.deps/java/awt/image/PixelGrabber.P \
+.deps/java/awt/image/PixelInterleavedSampleModel.P \
.deps/java/awt/image/RGBImageFilter.P .deps/java/awt/image/Raster.P \
.deps/java/awt/image/RasterFormatException.P \
.deps/java/awt/image/RasterOp.P .deps/java/awt/image/RenderedImage.P \
@@ -3775,10 +3822,10 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/java/lang/UnknownError.P .deps/java/lang/UnsatisfiedLinkError.P \
.deps/java/lang/UnsupportedClassVersionError.P \
.deps/java/lang/UnsupportedOperationException.P \
-.deps/java/lang/VMClassLoader.P .deps/java/lang/VMSecurityManager.P \
-.deps/java/lang/VMThrowable.P .deps/java/lang/VerifyError.P \
-.deps/java/lang/VirtualMachineError.P .deps/java/lang/Void.P \
-.deps/java/lang/dtoa.P .deps/java/lang/e_acos.P \
+.deps/java/lang/VMClassLoader.P .deps/java/lang/VMCompiler.P \
+.deps/java/lang/VMSecurityManager.P .deps/java/lang/VMThrowable.P \
+.deps/java/lang/VerifyError.P .deps/java/lang/VirtualMachineError.P \
+.deps/java/lang/Void.P .deps/java/lang/dtoa.P .deps/java/lang/e_acos.P \
.deps/java/lang/e_asin.P .deps/java/lang/e_atan2.P \
.deps/java/lang/e_exp.P .deps/java/lang/e_fmod.P \
.deps/java/lang/e_log.P .deps/java/lang/e_pow.P \
@@ -4118,7 +4165,6 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/java/text/DateFormat.P .deps/java/text/DateFormatSymbols.P \
.deps/java/text/DecimalFormat.P .deps/java/text/DecimalFormatSymbols.P \
.deps/java/text/FieldPosition.P .deps/java/text/Format.P \
-.deps/java/text/FormatCharacterIterator.P \
.deps/java/text/MessageFormat.P .deps/java/text/NumberFormat.P \
.deps/java/text/ParseException.P .deps/java/text/ParsePosition.P \
.deps/java/text/RuleBasedCollator.P .deps/java/text/SimpleDateFormat.P \
@@ -4221,6 +4267,18 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/javax/accessibility/AccessibleTableModelChange.P \
.deps/javax/accessibility/AccessibleText.P \
.deps/javax/accessibility/AccessibleValue.P \
+.deps/javax/imageio/ImageReader.P .deps/javax/imageio/ImageTranscoder.P \
+.deps/javax/imageio/ImageWriter.P \
+.deps/javax/imageio/spi/IIOServiceProvider.P \
+.deps/javax/imageio/spi/ImageInputStreamSpi.P \
+.deps/javax/imageio/spi/ImageOutputStreamSpi.P \
+.deps/javax/imageio/spi/ImageReaderWriterSpi.P \
+.deps/javax/imageio/spi/ImageTranscoderSpi.P \
+.deps/javax/imageio/spi/RegisterableService.P \
+.deps/javax/imageio/spi/ServiceRegistry.P \
+.deps/javax/imageio/stream/IIOByteBuffer.P \
+.deps/javax/imageio/stream/ImageInputStream.P \
+.deps/javax/imageio/stream/ImageOutputStream.P \
.deps/javax/naming/AuthenticationException.P \
.deps/javax/naming/AuthenticationNotSupportedException.P \
.deps/javax/naming/BinaryRefAddr.P .deps/javax/naming/Binding.P \
@@ -4533,18 +4591,22 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/javax/swing/plaf/TextUI.P .deps/javax/swing/plaf/ToolBarUI.P \
.deps/javax/swing/plaf/ToolTipUI.P .deps/javax/swing/plaf/TreeUI.P \
.deps/javax/swing/plaf/UIResource.P .deps/javax/swing/plaf/ViewportUI.P \
+.deps/javax/swing/plaf/basic/BasicArrowButton.P \
.deps/javax/swing/plaf/basic/BasicBorders.P \
.deps/javax/swing/plaf/basic/BasicButtonListener.P \
.deps/javax/swing/plaf/basic/BasicButtonUI.P \
+.deps/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.P \
.deps/javax/swing/plaf/basic/BasicCheckBoxUI.P \
.deps/javax/swing/plaf/basic/BasicGraphicsUtils.P \
.deps/javax/swing/plaf/basic/BasicIconFactory.P \
.deps/javax/swing/plaf/basic/BasicLabelUI.P \
.deps/javax/swing/plaf/basic/BasicListUI.P \
.deps/javax/swing/plaf/basic/BasicLookAndFeel.P \
+.deps/javax/swing/plaf/basic/BasicMenuItemUI.P \
.deps/javax/swing/plaf/basic/BasicOptionPaneUI.P \
.deps/javax/swing/plaf/basic/BasicPanelUI.P \
.deps/javax/swing/plaf/basic/BasicProgressBarUI.P \
+.deps/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.P \
.deps/javax/swing/plaf/basic/BasicRadioButtonUI.P \
.deps/javax/swing/plaf/basic/BasicRootPaneUI.P \
.deps/javax/swing/plaf/basic/BasicScrollBarUI.P \
@@ -4645,6 +4707,7 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.P \
.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.P \
.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.P \
+.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.P \
.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.P \
.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.P \
.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.P \
@@ -4653,6 +4716,7 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.P \
.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.P \
.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.P \
+.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.P \
.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImagePainter.P \
.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.P \
.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.P \
@@ -4670,8 +4734,8 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.P \
.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.P \
.deps/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.P \
-.deps/jni/gtk-peer/gthread-jni.P .deps/no-threads.P .deps/nogc.P \
-.deps/org/w3c/dom/Attr.P .deps/org/w3c/dom/CDATASection.P \
+.deps/jni/gtk-peer/gthread-jni.P .deps/link.P .deps/no-threads.P \
+.deps/nogc.P .deps/org/w3c/dom/Attr.P .deps/org/w3c/dom/CDATASection.P \
.deps/org/w3c/dom/CharacterData.P .deps/org/w3c/dom/Comment.P \
.deps/org/w3c/dom/DOMException.P .deps/org/w3c/dom/DOMImplementation.P \
.deps/org/w3c/dom/Document.P .deps/org/w3c/dom/DocumentFragment.P \
@@ -4709,8 +4773,8 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/org/xml/sax/helpers/XMLFilterImpl.P \
.deps/org/xml/sax/helpers/XMLReaderAdapter.P \
.deps/org/xml/sax/helpers/XMLReaderFactory.P .deps/posix-threads.P \
-.deps/posix.P .deps/prims.P .deps/resolve.P .deps/verify.P \
-.deps/win32-threads.P .deps/win32.P
+.deps/posix.P .deps/prims.P .deps/verify.P .deps/win32-threads.P \
+.deps/win32.P
SOURCES = $(libgcj_la_SOURCES) $(EXTRA_libgcj_la_SOURCES) $(lib_org_xml_sax_la_SOURCES) $(lib_org_w3c_dom_la_SOURCES) $(lib_gnu_java_awt_peer_gtk_la_SOURCES) $(lib_gnu_awt_xlib_la_SOURCES) $(EXTRA_lib_gnu_awt_xlib_la_SOURCES) $(jv_convert_SOURCES) $(EXTRA_jv_convert_SOURCES) $(gij_SOURCES) $(rmic_SOURCES) $(EXTRA_rmic_SOURCES) $(rmiregistry_SOURCES) $(EXTRA_rmiregistry_SOURCES) $(gen_from_JIS_SOURCES) $(EXTRA_gen_from_JIS_SOURCES)
OBJECTS = $(libgcj_la_OBJECTS) $(lib_org_xml_sax_la_OBJECTS) $(lib_org_w3c_dom_la_OBJECTS) $(lib_gnu_java_awt_peer_gtk_la_OBJECTS) $(lib_gnu_awt_xlib_la_OBJECTS) $(jv_convert_OBJECTS) $(gij_OBJECTS) $(rmic_OBJECTS) $(rmiregistry_OBJECTS) $(gen_from_JIS_OBJECTS)
@@ -5325,6 +5389,9 @@ $(nat_files) $(x_nat_files): %.lo: %.cc
$(c_files): %.lo: %.c
$(LTCOMPILE) -c -o $@ $<
+interpret.lo: interpret.cc
+ $(LTCXXCOMPILE) -fno-unit-at-a-time -c -o $@ $<
+
$(extra_cc_files): %.lo: %.cc
$(LTCXXCOMPILE) -c -o $@ $<
@@ -5332,7 +5399,8 @@ $(c_files): java/lang/fdlibm.h java/lang/ieeefp.h java/lang/mprec.h
$(gtk_c_files): %.lo: %.c
$(LTCOMPILE) -c -Ijniinclude -I$(srcdir)/jni/classpath -I$(srcdir)/jni/gtk-peer \
- $(GTK_CFLAGS) $(LIBART_CFLAGS) $(CAIRO_LIBS) $(PANGOFT2_LIBS) -o $@ $<
+ $(PEDANTIC_CFLAGS) $(GTK_CFLAGS) $(LIBART_CFLAGS) \
+ $(CAIRO_LIBS) $(PANGOFT2_LIBS) -o $@ $<
$(gtk_c_files): $(gtk_c_headers)
@@ -5345,6 +5413,9 @@ $(gtk_awt_peer_sources:.java=.lo): %.lo: %.java
gnu/gcj/runtime/StackTrace.lo: gnu/gcj/runtime/StackTrace.java
$(GCJCOMPILE) -fno-optimize-sibling-calls -o $@ $<
+java/io/ObjectInputStream.lo: java/io/ObjectInputStream.java
+ $(GCJCOMPILE) -fno-optimize-sibling-calls -o $@ $<
+
libgcj.la: $(libgcj_la_OBJECTS) $(libgcj_la_DEPENDENCIES)
@echo Creating list of files to link...
@: $(call write_entries_to_file,$(libgcj_la_OBJECTS) $(libgcj_la_LIBADD),libgcj.objectlist)
diff --git a/libjava/boehm.cc b/libjava/boehm.cc
index 642f451f92e..db8e98c0d66 100644
--- a/libjava/boehm.cc
+++ b/libjava/boehm.cc
@@ -1,6 +1,6 @@
// boehm.cc - interface between libjava and Boehm GC.
-/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
This file is part of libgcj.
@@ -38,9 +38,13 @@ extern "C"
// These aren't declared in any Boehm GC header.
void GC_finalize_all (void);
ptr_t GC_debug_generic_malloc (size_t size, int k, GC_EXTRA_PARAMS);
+
+ // From boehm's misc.c
+ void GC_enable();
+ void GC_disable();
};
-#define MAYBE_MARK(Obj, Top, Limit, Source, Exit) \
+#define MAYBE_MARK(Obj, Top, Limit, Source) \
Top=GC_MARK_AND_PUSH((GC_PTR)Obj, Top, Limit, (GC_PTR *)Source)
// `kind' index used when allocating Java arrays.
@@ -83,11 +87,11 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /* env */)
# ifndef JV_HASH_SYNCHRONIZATION
// Every object has a sync_info pointer.
p = (ptr_t) obj->sync_info;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, obj, o1label);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, obj);
# endif
// Mark the object's class.
p = (ptr_t) klass;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, obj, o2label);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, obj);
if (__builtin_expect (klass == &java::lang::Class::class$, false))
{
@@ -106,33 +110,35 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /* env */)
jclass c = (jclass) addr;
p = (ptr_t) c->name;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, c3label);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
p = (ptr_t) c->superclass;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, c4label);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
for (int i = 0; i < c->constants.size; ++i)
{
/* FIXME: We could make this more precise by using the tags -KKT */
p = (ptr_t) c->constants.data[i].p;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, c5label);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
}
#ifdef INTERPRETER
if (_Jv_IsInterpretedClass (c))
{
p = (ptr_t) c->constants.tags;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, c5alabel);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
p = (ptr_t) c->constants.data;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, c5blabel);
- p = (ptr_t) c->vtable;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, c5clabel);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
}
#endif
+ // The vtable might be allocated even for compiled code.
+ p = (ptr_t) c->vtable;
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
+
// If the class is an array, then the methods field holds a
// pointer to the element class. If the class is primitive,
// then the methods field holds a pointer to the array class.
p = (ptr_t) c->methods;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, c6label);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
// The vtable might have been set, but the rest of the class
// could still be uninitialized. If this is the case, then
@@ -148,34 +154,30 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /* env */)
for (int i = 0; i < c->method_count; ++i)
{
p = (ptr_t) c->methods[i].name;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c,
- cm1label);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
p = (ptr_t) c->methods[i].signature;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c,
- cm2label);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
}
}
// Mark all the fields.
p = (ptr_t) c->fields;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, c8label);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
for (int i = 0; i < c->field_count; ++i)
{
_Jv_Field* field = &c->fields[i];
-#ifndef COMPACT_FIELDS
p = (ptr_t) field->name;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, c8alabel);
-#endif
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
p = (ptr_t) field->type;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, c8blabel);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
// For the interpreter, we also need to mark the memory
// containing static members
if ((field->flags & java::lang::reflect::Modifier::STATIC))
{
p = (ptr_t) field->u.addr;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, c8clabel);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
// also, if the static member is a reference,
// mark also the value pointed to. We check for isResolved
@@ -185,67 +187,110 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /* env */)
{
jobject val = *(jobject*) field->u.addr;
p = (ptr_t) val;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit,
- c, c8elabel);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
}
}
}
p = (ptr_t) c->vtable;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, c9label);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
p = (ptr_t) c->interfaces;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, cAlabel);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
for (int i = 0; i < c->interface_count; ++i)
{
p = (ptr_t) c->interfaces[i];
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, cClabel);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
}
p = (ptr_t) c->loader;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, cBlabel);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
+
+ // The dispatch tables can be allocated at runtime.
+ p = (ptr_t) c->ancestors;
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
+ if (c->idt)
+ {
+ p = (ptr_t) c->idt;
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
+
+ if (c->isInterface())
+ {
+ p = (ptr_t) c->idt->iface.ioffsets;
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c->idt);
+ }
+ else if (! c->isPrimitive())
+ {
+ // This field is only valid for ordinary classes.
+ p = (ptr_t) c->idt->cls.itable;
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c->idt);
+ }
+ }
+
p = (ptr_t) c->arrayclass;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, cDlabel);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
p = (ptr_t) c->protectionDomain;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, cPlabel);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
p = (ptr_t) c->hack_signers;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, cSlabel);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
+ p = (ptr_t) c->aux_info;
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
#ifdef INTERPRETER
if (_Jv_IsInterpretedClass (c))
{
- _Jv_InterpClass* ic = (_Jv_InterpClass*) c;
+ _Jv_InterpClass* ic = (_Jv_InterpClass*) c->aux_info;
p = (ptr_t) ic->interpreted_methods;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, ic, cElabel);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, ic);
for (int i = 0; i < c->method_count; i++)
{
+ // The interpreter installs a heap-allocated trampoline
+ // here, so we'll mark it.
+ p = (ptr_t) c->methods[i].ncode;
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c);
+
+ using namespace java::lang::reflect;
+
+ // Mark the direct-threaded code. Note a subtlety here:
+ // when we add Miranda methods to a class, we don't
+ // resize its interpreted_methods array. If we try to
+ // reference one of these methods, we may crash.
+ // However, we know these are all abstract, and we know
+ // that abstract methods have nothing useful in this
+ // array. So, we skip all abstract methods to avoid the
+ // problem. FIXME: this is pretty obscure, it may be
+ // better to add a methods to the execution engine and
+ // resize the array.
+ if ((c->methods[i].accflags & Modifier::ABSTRACT) != 0)
+ continue;
+
p = (ptr_t) ic->interpreted_methods[i];
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, ic, \
- cFlabel);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, ic);
- // Mark the direct-threaded code.
- if ((c->methods[i].accflags
- & java::lang::reflect::Modifier::NATIVE) == 0)
+ if ((c->methods[i].accflags & Modifier::NATIVE) != 0)
+ {
+ _Jv_JNIMethod *jm
+ = (_Jv_JNIMethod *) ic->interpreted_methods[i];
+ if (jm)
+ {
+ p = (ptr_t) jm->jni_arg_types;
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, p);
+ }
+ }
+ else
{
_Jv_InterpMethod *im
= (_Jv_InterpMethod *) ic->interpreted_methods[i];
if (im)
{
p = (ptr_t) im->prepared;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, ic, \
- cFlabel);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, ic);
}
}
-
- // The interpreter installs a heap-allocated trampoline
- // here, so we'll mark it.
- p = (ptr_t) c->methods[i].ncode;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c,
- cm3label);
}
p = (ptr_t) ic->field_initializers;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, ic, cGlabel);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, ic);
}
#endif
@@ -272,8 +317,7 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /* env */)
{
jobject val = JvGetObjectField (obj, field);
p = (ptr_t) val;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit,
- obj, elabel);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, obj);
}
field = field->getNextField ();
}
@@ -306,17 +350,17 @@ _Jv_MarkArray (void *addr, void *msp, void *msl, void * /*env*/)
# ifndef JV_HASH_SYNCHRONIZATION
// Every object has a sync_info pointer.
p = (ptr_t) array->sync_info;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, array, e1label);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, array);
# endif
// Mark the object's class.
p = (ptr_t) klass;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, &(dt -> clas), o2label);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, &(dt -> clas));
for (int i = 0; i < JvGetArrayLength (array); ++i)
{
jobject obj = elements (array)[i];
p = (ptr_t) obj;
- MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, array, e2label);
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, array);
}
return mark_stack_ptr;
@@ -488,10 +532,6 @@ _Jv_GCSetMaximumHeapSize (size_t size)
GC_set_max_heap_size ((GC_word) size);
}
-// From boehm's misc.c
-extern "C" void GC_enable();
-extern "C" void GC_disable();
-
void
_Jv_DisableGC (void)
{
diff --git a/libjava/defineclass.cc b/libjava/defineclass.cc
index 2e8b4d97434..063f312a389 100644
--- a/libjava/defineclass.cc
+++ b/libjava/defineclass.cc
@@ -1,6 +1,6 @@
// defineclass.cc - defining a class from .class format.
-/* Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
This file is part of libgcj.
@@ -25,6 +25,7 @@ details. */
#include <stdlib.h>
#include <java-cpool.h>
#include <gcj/cni.h>
+#include <execution.h>
#include <java/lang/Class.h>
#include <java/lang/Float.h>
@@ -96,7 +97,10 @@ struct _Jv_ClassReader {
unsigned int *offsets;
// the class to define (see java-interp.h)
- _Jv_InterpClass *def;
+ jclass def;
+
+ // the classes associated interpreter data.
+ _Jv_InterpClass *def_interp;
/* check that the given number of input bytes are available */
inline void check (int num)
@@ -221,7 +225,11 @@ struct _Jv_ClassReader {
bytes = (unsigned char*) (elements (data)+offset);
len = length;
pos = 0;
- def = (_Jv_InterpClass*) klass;
+ def = klass;
+ def->size_in_bytes = -1;
+ def->vtable_method_count = -1;
+ def->engine = &_Jv_soleInterpreterEngine;
+ def_interp = (_Jv_InterpClass *) def->aux_info;
}
/** and here goes the parser members defined out-of-line */
@@ -330,10 +338,9 @@ _Jv_ClassReader::parse ()
if (pos != len)
throw_class_format_error ("unused data before end of file");
- // tell everyone we're done.
- def->state = JV_STATE_LOADED;
+ // Tell everyone we're done.
+ def->state = JV_STATE_READ;
def->notifyAll ();
-
}
void _Jv_ClassReader::read_constpool ()
@@ -772,9 +779,9 @@ _Jv_ClassReader::prepare_pool_entry (int index, unsigned char this_tag)
name_index, type_index);
if (this_tag == JV_CONSTANT_Fieldref)
- _Jv_VerifyFieldSignature (pool_data[type_index].utf8);
+ verify_field_signature (pool_data[type_index].utf8);
else
- _Jv_VerifyMethodSignature (pool_data[type_index].utf8);
+ verify_method_signature (pool_data[type_index].utf8);
_Jv_Utf8Const* name = pool_data[name_index].utf8;
@@ -943,23 +950,25 @@ _Jv_ClassReader::handleClassBegin
def->notifyAll ();
}
-///// implements the checks described in sect. 5.3.5.3
+///// Implements the checks described in sect. 5.3.5.3
void
_Jv_ClassReader::checkExtends (jclass sub, jclass super)
{
using namespace java::lang::reflect;
- // having an interface or a final class as a superclass is no good
+ _Jv_Linker::wait_for_state (super, JV_STATE_LOADING);
+
+ // Having an interface or a final class as a superclass is no good.
if ((super->accflags & (Modifier::INTERFACE | Modifier::FINAL)) != 0)
{
throw_incompatible_class_change_error (sub->getName ());
}
- // if the super class is not public, we need to check some more
+ // If the super class is not public, we need to check some more.
if ((super->accflags & Modifier::PUBLIC) == 0)
{
- // With package scope, the classes must have the same
- // class loader.
+ // With package scope, the classes must have the same class
+ // loader.
if ( sub->loader != super->loader
|| !_Jv_ClassNameSamePackage (sub->name, super->name))
{
@@ -967,7 +976,7 @@ _Jv_ClassReader::checkExtends (jclass sub, jclass super)
}
}
- for (; super != 0; super = super->superclass)
+ for (; super != 0; super = super->getSuperclass ())
{
if (super == sub)
throw_class_circularity_error (sub->getName ());
@@ -1047,10 +1056,10 @@ void _Jv_ClassReader::handleFieldsBegin (int count)
def->fields = (_Jv_Field*)
_Jv_AllocBytes (count * sizeof (_Jv_Field));
def->field_count = count;
- def->field_initializers = (_Jv_ushort*)
+ def_interp->field_initializers = (_Jv_ushort*)
_Jv_AllocBytes (count * sizeof (_Jv_ushort));
for (int i = 0; i < count; i++)
- def->field_initializers[i] = (_Jv_ushort) 0;
+ def_interp->field_initializers[i] = (_Jv_ushort) 0;
}
void _Jv_ClassReader::handleField (int field_no,
@@ -1065,11 +1074,7 @@ void _Jv_ClassReader::handleField (int field_no,
_Jv_Field *field = &def->fields[field_no];
_Jv_Utf8Const *field_name = pool_data[name].utf8;
-#ifndef COMPACT_FIELDS
field->name = field_name;
-#else
- field->nameIndex = name;
-#endif
// Ignore flags we don't know about.
field->flags = flags & Modifier::ALL_FLAGS;
@@ -1103,7 +1108,7 @@ void _Jv_ClassReader::handleField (int field_no,
}
if (verify)
- _Jv_VerifyFieldSignature (sig);
+ verify_field_signature (sig);
// field->type is really a jclass, but while it is still
// unresolved we keep an _Jv_Utf8Const* instead.
@@ -1133,7 +1138,7 @@ void _Jv_ClassReader::handleConstantValueAttribute (int field_index,
throw_class_format_error ("field has multiple ConstantValue attributes");
field->flags |= _Jv_FIELD_CONSTANT_VALUE;
- def->field_initializers[field_index] = value;
+ def_interp->field_initializers[field_index] = value;
/* type check the initializer */
@@ -1153,7 +1158,7 @@ void _Jv_ClassReader::handleFieldsEnd ()
int low = 0;
int high = def->field_count-1;
_Jv_Field *fields = def->fields;
- _Jv_ushort *inits = def->field_initializers;
+ _Jv_ushort *inits = def_interp->field_initializers;
// this is kind of a raw version of quicksort.
while (low < high)
@@ -1195,13 +1200,13 @@ _Jv_ClassReader::handleMethodsBegin (int count)
{
def->methods = (_Jv_Method *) _Jv_AllocBytes (sizeof (_Jv_Method) * count);
- def->interpreted_methods
+ def_interp->interpreted_methods
= (_Jv_MethodBase **) _Jv_AllocBytes (sizeof (_Jv_MethodBase *)
* count);
for (int i = 0; i < count; i++)
{
- def->interpreted_methods[i] = 0;
+ def_interp->interpreted_methods[i] = 0;
def->methods[i].index = (_Jv_ushort) -1;
}
@@ -1240,7 +1245,7 @@ void _Jv_ClassReader::handleMethod
else
verify_identifier (method->name);
- _Jv_VerifyMethodSignature (method->signature);
+ verify_method_signature (method->signature);
for (int i = 0; i < mth_index; ++i)
{
@@ -1270,7 +1275,6 @@ void _Jv_ClassReader::handleCodeAttribute
_Jv_InterpMethod *method =
(_Jv_InterpMethod*) (_Jv_AllocBytes (size));
- method->deferred = NULL;
method->max_stack = max_stack;
method->max_locals = max_locals;
method->code_length = code_length;
@@ -1284,7 +1288,7 @@ void _Jv_ClassReader::handleCodeAttribute
(void*) (bytes+code_start),
code_length);
- def->interpreted_methods[method_index] = method;
+ def_interp->interpreted_methods[method_index] = method;
if ((method->self->accflags & java::lang::reflect::Modifier::STATIC))
{
@@ -1301,7 +1305,7 @@ void _Jv_ClassReader::handleExceptionTableEntry
int start_pc, int end_pc, int handler_pc, int catch_type)
{
_Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *>
- (def->interpreted_methods[method_index]);
+ (def_interp->interpreted_methods[method_index]);
_Jv_InterpException *exc = method->exceptions ();
exc[exc_index].start_pc.i = start_pc;
@@ -1319,7 +1323,7 @@ void _Jv_ClassReader::handleMethodsEnd ()
_Jv_Method *method = &def->methods[i];
if ((method->accflags & Modifier::NATIVE) != 0)
{
- if (def->interpreted_methods[i] != 0)
+ if (def_interp->interpreted_methods[i] != 0)
throw_class_format_error ("code provided for native method");
else
{
@@ -1328,8 +1332,7 @@ void _Jv_ClassReader::handleMethodsEnd ()
m->defining_class = def;
m->self = method;
m->function = NULL;
- def->interpreted_methods[i] = m;
- m->deferred = NULL;
+ def_interp->interpreted_methods[i] = m;
if ((method->accflags & Modifier::STATIC))
{
@@ -1344,12 +1347,12 @@ void _Jv_ClassReader::handleMethodsEnd ()
}
else if ((method->accflags & Modifier::ABSTRACT) != 0)
{
- if (def->interpreted_methods[i] != 0)
+ if (def_interp->interpreted_methods[i] != 0)
throw_class_format_error ("code provided for abstract method");
}
else
{
- if (def->interpreted_methods[i] == 0)
+ if (def_interp->interpreted_methods[i] == 0)
throw_class_format_error ("method with no code");
}
}
@@ -1621,7 +1624,7 @@ _Jv_VerifyClassName (_Jv_Utf8Const *name)
}
/* Returns true, if NAME1 and NAME2 represent classes in the same
- package. */
+ package. Neither NAME2 nor NAME2 may name an array type. */
bool
_Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2)
{
diff --git a/libjava/gcj/Makefile.in b/libjava/gcj/Makefile.in
index 9a262ce62d2..edf5497b95c 100644
--- a/libjava/gcj/Makefile.in
+++ b/libjava/gcj/Makefile.in
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
-# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -260,7 +260,7 @@ TAGS: $(HEADERS) $(SOURCES) libgcj-config.h.in $(TAGS_DEPENDENCIES) $(LISP)
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)libgcj-config.h.in$$unique$(LISP)$$tags" \
- || (cd $(srcdir) && etags -o $$here/TAGS $(ETAGS_ARGS) $$tags libgcj-config.h.in $$unique $(LISP))
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags libgcj-config.h.in $$unique $(LISP) -o $$here/TAGS)
mostlyclean-tags:
diff --git a/libjava/gcj/cni.h b/libjava/gcj/cni.h
index 3790dc4d564..59cf673b092 100644
--- a/libjava/gcj/cni.h
+++ b/libjava/gcj/cni.h
@@ -20,18 +20,6 @@ details. */
#include <string.h>
-extern inline jobject
-JvAllocObject (jclass cls)
-{
- return _Jv_AllocObject (cls, cls->size());
-}
-
-extern inline jobject
-JvAllocObject (jclass cls, jsize sz)
-{
- return _Jv_AllocObject (cls, sz);
-}
-
extern "C" jstring _Jv_NewStringUTF (const char *bytes);
extern "C" void _Jv_InitClass (jclass);
diff --git a/libjava/gcj/field.h b/libjava/gcj/field.h
index 9279c832964..0827658117c 100644
--- a/libjava/gcj/field.h
+++ b/libjava/gcj/field.h
@@ -1,6 +1,6 @@
// field.h - Header file for fieldID instances. -*- c++ -*-
-/* Copyright (C) 1998, 1999, 2000 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2004 Free Software Foundation
This file is part of libgcj.
@@ -21,9 +21,7 @@ details. */
struct _Jv_Field
{
-#ifndef COMPACT_FIELDS
struct _Jv_Utf8Const* name;
-#endif
/* The type of the field, if isResolved().
If !isResolved(): The fields's signature as a (Utf8Const*). */
@@ -31,11 +29,7 @@ struct _Jv_Field
_Jv_ushort flags;
-#ifdef COMPACT_FIELDS
- jshort nameIndex; /* offset in class's name table */
-#else
_Jv_ushort bsize; /* not really needed ... */
-#endif
union {
jint boffset; /* offset in bytes for instance field */
@@ -82,13 +76,8 @@ struct _Jv_Field
return flags & java::lang::reflect::Modifier::ALL_FLAGS;
}
-#ifdef COMPACT_FIELDS
- _Jv_Utf8Const * getNameUtf8Const (jclass cls)
- { return clas->fieldNames + nameIndex; }
-#else
_Jv_Utf8Const * getNameUtf8Const (jclass) { return name; }
#endif
-#endif
};
#ifdef __cplusplus
diff --git a/libjava/gcj/javaprims.h b/libjava/gcj/javaprims.h
index 60f99cfdeda..65525fe45ac 100644
--- a/libjava/gcj/javaprims.h
+++ b/libjava/gcj/javaprims.h
@@ -1,6 +1,6 @@
// javaprims.h - Main external header file for libgcj. -*- c++ -*-
-/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
This file is part of libgcj.
@@ -83,6 +83,7 @@ extern "Java"
class LineNumberInputStream;
class LineNumberReader;
class MemberComparator;
+ class MyIOException;
class NotActiveException;
class NotSerializableException;
class ObjectInput;
@@ -211,6 +212,7 @@ extern "Java"
class UnsupportedClassVersionError;
class UnsupportedOperationException;
class VMClassLoader;
+ class VMCompiler;
class VMSecurityManager;
class VMThrowable;
class VerifyError;
@@ -450,17 +452,17 @@ struct _Jv_JNIEnv;
typedef struct _Jv_Field *jfieldID;
typedef struct _Jv_Method *jmethodID;
-extern "C" jobject _Jv_AllocObject (jclass, jint) __attribute__((__malloc__));
-extern "C" jobject _Jv_AllocObjectNoFinalizer (jclass, jint) __attribute__((__malloc__));
-extern "C" jobject _Jv_AllocObjectNoInitNoFinalizer (jclass, jint) __attribute__((__malloc__));
+extern "C" jobject _Jv_AllocObject (jclass) __attribute__((__malloc__));
+extern "C" jobject _Jv_AllocObjectNoFinalizer (jclass) __attribute__((__malloc__));
+extern "C" jobject _Jv_AllocObjectNoInitNoFinalizer (jclass) __attribute__((__malloc__));
#ifdef JV_HASH_SYNCHRONIZATION
- extern "C" jobject _Jv_AllocPtrFreeObject (jclass, jint)
+ extern "C" jobject _Jv_AllocPtrFreeObject (jclass)
__attribute__((__malloc__));
#else
// Collector still needs to scan sync_info
- static inline jobject _Jv_AllocPtrFreeObject (jclass klass, jint sz)
+ static inline jobject _Jv_AllocPtrFreeObject (jclass klass)
{
- return _Jv_AllocObject(klass, sz);
+ return _Jv_AllocObject(klass);
}
#endif
extern "C" jboolean _Jv_IsInstanceOf(jobject, jclass);
diff --git a/libjava/gnu/classpath/ServiceFactory.java b/libjava/gnu/classpath/ServiceFactory.java
new file mode 100644
index 00000000000..5d1493414d0
--- /dev/null
+++ b/libjava/gnu/classpath/ServiceFactory.java
@@ -0,0 +1,572 @@
+/* ServiceFactory.java -- Factory for plug-in services.
+ Copyright (C) 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.classpath;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+
+/**
+ * A factory for plug-ins that conform to a service provider
+ * interface. This is a general mechanism that gets used by a number
+ * of packages in the Java API. For instance, {@link
+ * java.nio.charset.spi.CharsetProvider} allows to write custom
+ * encoders and decoders for character sets, {@link
+ * javax.imageio.spi.ImageReaderSpi} allows to support custom image
+ * formats, and {@link javax.print.PrintService} makes it possible to
+ * write custom printer drivers.
+ *
+ * <p>The plug-ins are concrete implementations of the service
+ * provider interface, which is defined as an interface or an abstract
+ * class. The implementation classes must be public and have a public
+ * constructor that takes no arguments.
+ *
+ * <p>Plug-ins are usually deployed in JAR files. A JAR that provides
+ * an implementation of a service must declare this in a resource file
+ * whose name is the fully qualified service name and whose location
+ * is the directory <code>META-INF/services</code>. This UTF-8 encoded
+ * text file lists, on separate lines, the fully qualified names of
+ * the concrete implementations. Thus, one JAR file can provide an
+ * arbitrary number of implementations for an arbitrary count of
+ * service provider interfaces.
+ *
+ * <p><b>Example</b>
+ *
+ * <p>For example, a JAR might provide two implementations of the
+ * service provider interface <code>org.foo.ThinkService</code>,
+ * namely <code>com.acme.QuickThinker</code> and
+ * <code>com.acme.DeepThinker</code>. The code for <code>QuickThinker</code>
+ * woud look as follows:
+ *
+ * <pre>
+ * package com.acme;
+ *
+ * &#x2f;**
+ * * Provices a super-quick, but not very deep implementation of ThinkService.
+ * *&#x2f;
+ * public class QuickThinker
+ * implements org.foo.ThinkService
+ * {
+ * &#x2f;**
+ * * Constructs a new QuickThinker. The service factory (which is
+ * * part of the Java environment) calls this no-argument constructor
+ * * when it looks up the available implementations of ThinkService.
+ * *
+ * * &lt;p&gt;Note that an application might query all available
+ * * ThinkService providers, but use just one of them. Therefore,
+ * * constructing an instance should be very inexpensive. For example,
+ * * large data structures should only be allocated when the service
+ * * actually gets used.
+ * *&#x2f;
+ * public QuickThinker()
+ * {
+ * }
+ *
+ * &#x2f;**
+ * * Returns the speed of this ThinkService in thoughts per second.
+ * * Applications can choose among the available service providers
+ * * based on this value.
+ * *&#x2f;
+ * public double getSpeed()
+ * {
+ * return 314159.2654;
+ * }
+ *
+ * &#x2f;**
+ * * Produces a thought. While the returned thoughts are not very
+ * * deep, they are generated in very short time.
+ * *&#x2f;
+ * public Thought think()
+ * {
+ * return null;
+ * }
+ * }
+ * </pre>
+ *
+ * <p>The code for <code>com.acme.DeepThinker</code> is left as an
+ * exercise to the reader.
+ *
+ * <p>Acme&#x2019;s <code>ThinkService</code> plug-in gets deployed as
+ * a JAR file. Besides the bytecode and resources for
+ * <code>QuickThinker</code> and <code>DeepThinker</code>, it also
+ * contains the text file
+ * <code>META-INF/services/org.foo.ThinkService</code>:
+ *
+ * <pre>
+ * # Available implementations of org.foo.ThinkService
+ * com.acme.QuickThinker
+ * com.acme.DeepThinker
+ * </pre>
+ *
+ * <p><b>Thread Safety</b>
+ *
+ * <p>It is safe to use <code>ServiceFactory</code> from multiple
+ * concurrent threads without external synchronization.
+ *
+ * <p><b>Note for User Applications</b>
+ *
+ * <p>User applications that want to load plug-ins should not directly
+ * use <code>gnu.classpath.ServiceFactory</code>, because this class
+ * is only available in Java environments that are based on GNU
+ * Classpath. Instead, it is recommended that user applications call
+ * {@link
+ * javax.imageio.spi.ServiceRegistry#lookupProviders(Class)}. This API
+ * is actually independent of image I/O, and it is available on every
+ * environment.
+ *
+ * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a>
+ */
+public final class ServiceFactory
+{
+ /**
+ * A logger that gets informed when a service gets loaded, or
+ * when there is a problem with loading a service.
+ *
+ * <p>Because {@link java.util.logging.Logger#getLogger(String)}
+ * is thread-safe, we do not need to worry about synchronization
+ * here.
+ */
+ private static final Logger LOGGER = Logger.getLogger("gnu.classpath");
+
+
+ /**
+ * Declared private in order to prevent constructing instances of
+ * this utility class.
+ */
+ private ServiceFactory()
+ {
+ }
+
+
+ /**
+ * Finds service providers that are implementing the specified
+ * Service Provider Interface.
+ *
+ * <p><b>On-demand loading:</b> Loading and initializing service
+ * providers is delayed as much as possible. The rationale is that
+ * typical clients will iterate through the set of installed service
+ * providers until one is found that matches some criteria (like
+ * supported formats, or quality of service). In such scenarios, it
+ * might make sense to install only the frequently needed service
+ * providers on the local machine. More exotic providers can be put
+ * onto a server; the server will only be contacted when no suitable
+ * service could be found locally.
+ *
+ * <p><b>Security considerations:</b> Any loaded service providers
+ * are loaded through the specified ClassLoader, or the system
+ * ClassLoader if <code>classLoader</code> is
+ * <code>null</code>. When <code>lookupProviders</code> is called,
+ * the current {@link AccessControlContext} gets recorded. This
+ * captured security context will determine the permissions when
+ * services get loaded via the <code>next()</code> method of the
+ * returned <code>Iterator</code>.
+ *
+ * @param spi the service provider interface which must be
+ * implemented by any loaded service providers.
+ *
+ * @param loader the class loader that will be used to load the
+ * service providers, or <code>null</code> for the system class
+ * loader. For using the context class loader, see {@link
+ * #lookupProviders(Class)}.
+ *
+ * @return an iterator over instances of <code>spi</code>.
+ *
+ * @throws IllegalArgumentException if <code>spi</code> is
+ * <code>null</code>.
+ */
+ public static Iterator lookupProviders(Class spi,
+ ClassLoader loader)
+ {
+ String resourceName;
+ Enumeration urls;
+
+ if (spi == null)
+ throw new IllegalArgumentException();
+
+ if (loader == null)
+ loader = ClassLoader.getSystemClassLoader();
+
+ resourceName = "META-INF/services/" + spi.getName();
+ try
+ {
+ urls = loader.getResources(resourceName);
+ }
+ catch (IOException ioex)
+ {
+ /* If an I/O error occurs here, we cannot provide any service
+ * providers. In this case, we simply return an iterator that
+ * does not return anything (no providers installed).
+ */
+ log(Level.WARNING, "cannot access {0}", resourceName, ioex);
+ return Collections.EMPTY_LIST.iterator();
+ }
+
+ return new ServiceIterator(spi, urls, loader,
+ AccessController.getContext());
+ }
+
+
+ /**
+ * Finds service providers that are implementing the specified
+ * Service Provider Interface, using the context class loader
+ * for loading providers.
+ *
+ * @param spi the service provider interface which must be
+ * implemented by any loaded service providers.
+ *
+ * @return an iterator over instances of <code>spi</code>.
+ *
+ * @throws IllegalArgumentException if <code>spi</code> is
+ * <code>null</code>.
+ *
+ * @see #lookupProviders(Class, ClassLoader)
+ */
+ public static Iterator lookupProviders(Class spi)
+ {
+ ClassLoader ctxLoader;
+
+ ctxLoader = Thread.currentThread().getContextClassLoader();
+ return lookupProviders(spi, ctxLoader);
+ }
+
+
+ /**
+ * An iterator over service providers that are listed in service
+ * provider configuration files, which get passed as an Enumeration
+ * of URLs. This is a helper class for {@link
+ * ServiceFactory#lookupProviders}.
+ *
+ * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a>
+ */
+ private static final class ServiceIterator
+ implements Iterator
+ {
+ /**
+ * The service provider interface (usually an interface, sometimes
+ * an abstract class) which the services must implement.
+ */
+ private final Class spi;
+
+
+ /**
+ * An Enumeration<URL> over the URLs that contain a resource
+ * <code>META-INF/services/&lt;org.foo.SomeService&gt;</code>,
+ * as returned by {@link ClassLoader#getResources(String)}.
+ */
+ private final Enumeration urls;
+
+
+ /**
+ * The class loader used for loading service providers.
+ */
+ private final ClassLoader loader;
+
+
+ /**
+ * The security context used when loading and initializing service
+ * providers. We want to load and initialize all plug-in service
+ * providers under the same security context, namely the one that
+ * was active when {@link #lookupProviders} has been called.
+ */
+ private final AccessControlContext securityContext;
+
+
+ /**
+ * A reader for the current file listing class names of service
+ * implementors, or <code>null</code> when the last reader has
+ * been fetched.
+ */
+ private BufferedReader reader;
+
+
+ /**
+ * The URL currently being processed. This is only used for
+ * emitting error messages.
+ */
+ private URL currentURL;
+
+
+ /**
+ * The service provider that will be returned by the next call to
+ * {@link #next()}, or <code>null</code> if the iterator has
+ * already returned all service providers.
+ */
+ private Object nextProvider;
+
+
+ /**
+ * Constructs an Iterator that loads and initializes services on
+ * demand.
+ *
+ * @param spi the service provider interface which the services
+ * must implement. Usually, this is a Java interface type, but it
+ * might also be an abstract class or even a concrete superclass.
+ *
+ * @param urls an Enumeration<URL> over the URLs that contain a
+ * resource
+ * <code>META-INF/services/&lt;org.foo.SomeService&gt;</code>, as
+ * determined by {@link ClassLoader#getResources(String)}.
+ *
+ * @param loader the ClassLoader that gets used for loading
+ * service providers.
+ *
+ * @param securityContext the security context to use when loading
+ * and initializing service providers.
+ */
+ ServiceIterator(Class spi, Enumeration urls, ClassLoader loader,
+ AccessControlContext securityContext)
+ {
+ this.spi = spi;
+ this.urls = urls;
+ this.loader = loader;
+ this.securityContext = securityContext;
+ this.nextProvider = loadNextServiceProvider();
+ }
+
+
+ /**
+ * @throws NoSuchElementException if {@link #hasNext} returns
+ * <code>false</code>.
+ */
+ public Object next()
+ {
+ Object result;
+
+ if (!hasNext())
+ throw new NoSuchElementException();
+
+ result = nextProvider;
+ nextProvider = loadNextServiceProvider();
+ return result;
+ }
+
+
+ public boolean hasNext()
+ {
+ return nextProvider != null;
+ }
+
+
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+
+ private Object loadNextServiceProvider()
+ {
+ String line;
+
+ if (reader == null)
+ advanceReader();
+
+ for (;;)
+ {
+ /* If we have reached the last provider list, we cannot
+ * retrieve any further lines.
+ */
+ if (reader == null)
+ return null;
+
+ try
+ {
+ line = reader.readLine();
+ }
+ catch (IOException readProblem)
+ {
+ log(Level.WARNING, "IOException upon reading {0}", currentURL,
+ readProblem);
+ line = null;
+ }
+
+ /* When we are at the end of one list of services,
+ * switch over to the next one.
+ */
+ if (line == null)
+ {
+ advanceReader();
+ continue;
+ }
+
+
+ // Skip whitespace at the beginning and end of each line.
+ line = line.trim();
+
+ // Skip empty lines.
+ if (line.length() == 0)
+ continue;
+
+ // Skip comment lines.
+ if (line.charAt(0) == '#')
+ continue;
+
+ try
+ {
+ log(Level.FINE,
+ "Loading service provider \"{0}\", specified"
+ + " by \"META-INF/services/{1}\" in {2}.",
+ new Object[] { line, spi.getName(), currentURL },
+ null);
+
+ /* Load the class in the security context that was
+ * active when calling lookupProviders.
+ */
+ return AccessController.doPrivileged(
+ new ServiceProviderLoadingAction(spi, line, loader),
+ securityContext);
+ }
+ catch (Exception ex)
+ {
+ String msg = "Cannot load service provider class \"{0}\","
+ + " specified by \"META-INF/services/{1}\" in {2}";
+ if (ex instanceof PrivilegedActionException
+ && ex.getCause() instanceof ClassCastException)
+ msg = "Service provider class \"{0}\" is not an instance"
+ + " of \"{1}\". Specified"
+ + " by \"META-INF/services/{1}\" in {2}.";
+
+ log(Level.WARNING, msg,
+ new Object[] { line, spi.getName(), currentURL },
+ ex);
+ continue;
+ }
+ }
+ }
+
+
+ private void advanceReader()
+ {
+ do
+ {
+ if (reader != null)
+ {
+ try
+ {
+ reader.close();
+ log(Level.FINE, "closed {0}", currentURL, null);
+ }
+ catch (Exception ex)
+ {
+ log(Level.WARNING, "cannot close {0}", currentURL, ex);
+ }
+ reader = null;
+ currentURL = null;
+ }
+
+ if (!urls.hasMoreElements())
+ return;
+
+ currentURL = (URL) urls.nextElement();
+ try
+ {
+ reader = new BufferedReader(new InputStreamReader(
+ currentURL.openStream(), "UTF-8"));
+ log(Level.FINE, "opened {0}", currentURL, null);
+ }
+ catch (Exception ex)
+ {
+ log(Level.WARNING, "cannot open {0}", currentURL, ex);
+ }
+ }
+ while (reader == null);
+ }
+ }
+
+
+ /**
+ * Passes a log message to the <code>java.util.logging</code>
+ * framework. This call returns very quickly if no log message will
+ * be produced, so there is not much overhead in the standard case.
+ *
+ * @param the severity of the message, for instance {@link
+ * Level#WARNING}.
+ *
+ * @param msg the log message, for instance <code>&#x201c;Could not
+ * load {0}.&#x201d;</code>
+ *
+ * @param param the parameter(s) for the log message, or
+ * <code>null</code> if <code>msg</code> does not specify any
+ * parameters. If <code>param</code> is not an array, an array with
+ * <code>param</code> as its single element gets passed to the
+ * logging framework.
+ *
+ * @param t a Throwable that is associated with the log record, or
+ * <code>null</code> if the log message is not associated with a
+ * Throwable.
+ */
+ private static void log(Level level, String msg, Object param, Throwable t)
+ {
+ LogRecord rec;
+
+ // Return quickly if no log message will be produced.
+ if (!LOGGER.isLoggable(level))
+ return;
+
+ rec = new LogRecord(level, msg);
+ if (param != null && param.getClass().isArray())
+ rec.setParameters((Object[]) param);
+ else
+ rec.setParameters(new Object[] { param });
+
+ rec.setThrown(t);
+
+ // While java.util.logging can sometimes infer the class and
+ // method of the caller, this automatic inference is not reliable
+ // on highly optimizing VMs. Also, log messages make more sense to
+ // developers when they display a public method in a public class;
+ // otherwise, they might feel tempted to figure out the internals
+ // of ServiceFactory in order to understand the problem.
+ rec.setSourceClassName(ServiceFactory.class.getName());
+ rec.setSourceMethodName("lookupProviders");
+
+ LOGGER.log(rec);
+ }
+}
diff --git a/libjava/gnu/classpath/ServiceProviderLoadingAction.java b/libjava/gnu/classpath/ServiceProviderLoadingAction.java
new file mode 100644
index 00000000000..4832c9712f3
--- /dev/null
+++ b/libjava/gnu/classpath/ServiceProviderLoadingAction.java
@@ -0,0 +1,149 @@
+/* ServiceProviderLoadingAction.java -- Action for loading plug-in services.
+ Copyright (C) 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.classpath;
+
+import java.security.PrivilegedExceptionAction;
+
+/**
+ * A privileged action for creating a new instance of a service
+ * provider.
+ *
+ * <p>Class loading and instantiation is encapsulated in a
+ * <code>PriviledgedAction</code> in order to restrict the loaded
+ * service providers to the {@link java.security.AccessControlContext}
+ * that was active when {@link
+ * gnu.classpath.ServiceFactory#lookupProviders} was called, even
+ * though the actual loading is delayed to the time when the provider
+ * is actually needed.
+ *
+ * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a>
+ */
+final class ServiceProviderLoadingAction
+ implements PrivilegedExceptionAction
+{
+ /**
+ * The interface to which the loaded service provider implementation
+ * must conform. Usually, this is a Java interface type, but it
+ * might also be an abstract class or even a concrete class.
+ */
+ private final Class spi;
+
+
+ /**
+ * The fully qualified name of the class that gets loaded when
+ * this action is executed.
+ */
+ private final String providerName;
+
+
+ /**
+ * The ClassLoader that gets used for loading the service provider
+ * class.
+ */
+ private final ClassLoader loader;
+
+
+ /**
+ * Constructs a privileged action for loading a service provider.
+ *
+ * @param spi the interface to which the loaded service provider
+ * implementation must conform. Usually, this is a Java interface
+ * type, but it might also be an abstract class or even a concrete
+ * superclass.
+ *
+ * @param providerName the fully qualified name of the class that
+ * gets loaded when this action is executed.
+ *
+ * @param loader the ClassLoader that gets used for loading the
+ * service provider class.
+ *
+ * @throws IllegalArgumentException if <code>spi</code>,
+ * <code>providerName</code> or <code>loader</code> is
+ * <code>null</code>.
+ */
+ ServiceProviderLoadingAction(Class spi, String providerName,
+ ClassLoader loader)
+ {
+ if (spi == null || providerName == null || loader == null)
+ throw new IllegalArgumentException();
+
+ this.spi = spi;
+ this.providerName = providerName;
+ this.loader = loader;
+ }
+
+
+ /**
+ * Loads an implementation class for a service provider, and creates
+ * a new instance of the loaded class by invoking its public
+ * no-argument constructor.
+ *
+ * @return a new instance of the class whose name was passed as
+ * <code>providerName</code> to the constructor.
+ *
+ * @throws ClassCastException if the service provider does not
+ * implement the <code>spi</code> interface that was passed to the
+ * constructor.
+ *
+ * @throws IllegalAccessException if the service provider class or
+ * its no-argument constructor are not <code>public</code>.
+ *
+ * @throws InstantiationException if the service provider class is
+ * <code>abstract</code>, an interface, a primitive type, an array
+ * class, or void; or if service provider class does not have a
+ * no-argument constructor; or if there some other problem with
+ * creating a new instance of the service provider.
+ */
+ public Object run()
+ throws Exception
+ {
+ Class loadedClass;
+ Object serviceProvider;
+
+ loadedClass = loader.loadClass(providerName);
+ serviceProvider = loadedClass.newInstance();
+
+ // Ensure that the loaded provider is actually implementing
+ // the service provider interface.
+ if (!spi.isInstance(serviceProvider))
+ throw new ClassCastException(spi.getName());
+
+ return serviceProvider;
+ }
+}
diff --git a/libjava/gnu/gcj/natCore.cc b/libjava/gnu/gcj/natCore.cc
index 91b02479fd8..bb3fd57f6fb 100644
--- a/libjava/gnu/gcj/natCore.cc
+++ b/libjava/gnu/gcj/natCore.cc
@@ -96,8 +96,7 @@ _Jv_create_core (_Jv_core_chain *node, jstring name)
gnu::gcj::Core *core = NULL;
if (node)
{
- core = (gnu::gcj::Core *) _Jv_AllocObject(&gnu::gcj::Core::class$,
- sizeof (gnu::gcj::Core));
+ core = new gnu::gcj::Core ();
core->ptr = (gnu::gcj::RawData *) node->data;
core->length = node->data_length;
}
diff --git a/libjava/gnu/gcj/runtime/SharedLibHelper.java b/libjava/gnu/gcj/runtime/SharedLibHelper.java
index 9e170a120be..cdb84500daa 100644
--- a/libjava/gnu/gcj/runtime/SharedLibHelper.java
+++ b/libjava/gnu/gcj/runtime/SharedLibHelper.java
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2003 Free Software Foundation
+/* Copyright (C) 2001, 2003, 2004 Free Software Foundation
This file is part of libgcj.
@@ -13,6 +13,12 @@ import java.net.MalformedURLException;
import java.util.HashMap;
import java.security.*;
import gnu.gcj.Core;
+import java.util.Set;
+import java.util.Iterator;
+import java.util.HashSet;
+import java.util.HashMap;
+import java.nio.channels.FileChannel;
+import java.io.*;
public class SharedLibHelper
{
@@ -36,34 +42,82 @@ public class SharedLibHelper
{
synchronized (map)
{
- WeakReference ref = (WeakReference) map.get(libname);
- if (ref != null)
- return (SharedLibHelper) ref.get();
+ Set s = (Set)map.get(libname);
+ if (s == null)
+ return null;
+ for (Iterator i=s.iterator(); i.hasNext();)
+ {
+ WeakReference ref = (WeakReference)i.next();
+ if (ref != null)
+ return (SharedLibHelper) ref.get();
+ }
return null;
}
}
+ static void copyFile (File in, File out) throws IOException
+ {
+ FileChannel source = new FileInputStream(in).getChannel();
+ FileChannel destination = new FileOutputStream(out).getChannel();
+ source.transferTo(0, source.size(), destination);
+ source.close();
+ destination.close();
+ }
+
public static SharedLibHelper findHelper (ClassLoader loader, String libname,
CodeSource source)
{
synchronized (map)
{
SharedLibHelper result;
- WeakReference ref = (WeakReference) map.get(libname);
- if (ref != null)
+ Set s = (Set)map.get(libname);
+ if (s == null)
+ {
+ s = new HashSet();
+ map.put(libname, s);
+ }
+ else
{
- result = (SharedLibHelper) ref.get();
- if (result != null)
+ for (Iterator i=s.iterator(); i.hasNext();)
{
- if (result.loader != loader)
- // FIXME
- throw new UnknownError();
- return result;
+ WeakReference ref = (WeakReference)i.next();
+ if (ref != null)
+ {
+ result = (SharedLibHelper) ref.get();
+ if (result != null)
+ {
+ // A match succeeds if the library is already
+ // loaded by LOADER or any of its ancestors.
+ ClassLoader l = loader;
+ do
+ {
+ if (result.loader == l)
+ return result;
+ l = l.getParent();
+ }
+ while (l != null);
+ }
+ }
}
- }
+ // Oh dear. We've already mapped this shared library, but
+ // with a different class loader. We need to copy it.
+ try
+ {
+ File copy
+ = File.createTempFile(new File(libname).getName(),
+ ".so", new File ("/tmp"));
+ File src = new File(libname);
+ copyFile (src, copy);
+ libname = copy.getPath();
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
result = new SharedLibHelper(libname, loader, source, 0);
- map.put(libname, new WeakReference(result));
+ s.add(new WeakReference(result));
return result;
}
}
@@ -107,6 +161,11 @@ public class SharedLibHelper
native boolean hasResource(String name);
native void init();
+ public String toString ()
+ {
+ return "shared object " + baseName;
+ }
+
/** Called during dlopen's processing of the init section. */
void registerClass(String name, Class cls)
{
diff --git a/libjava/gnu/gcj/runtime/natSharedLibLoader.cc b/libjava/gnu/gcj/runtime/natSharedLibLoader.cc
index 46eef755a09..833a8bebb6d 100644
--- a/libjava/gnu/gcj/runtime/natSharedLibLoader.cc
+++ b/libjava/gnu/gcj/runtime/natSharedLibLoader.cc
@@ -1,6 +1,6 @@
// natSharedLibLoader.cc - Implementation of SharedLibHelper native methods.
-/* Copyright (C) 2001, 2003 Free Software Foundation
+/* Copyright (C) 2001, 2003, 2004 Free Software Foundation
This file is part of libgcj.
@@ -12,6 +12,8 @@ details. */
#include <gcj/cni.h>
#include <jvm.h>
+#include <execution.h>
+
#include <gnu/gcj/runtime/SharedLibHelper.h>
#include <java/io/IOException.h>
#include <java/lang/UnsupportedOperationException.h>
@@ -30,9 +32,10 @@ typedef void (*CoreHookFunc) (_Jv_core_chain *);
void
_Jv_sharedlib_register_hook (jclass cls)
{
- curHelper->registerClass(cls->getName(), cls);
cls->protectionDomain = curHelper->domain;
cls->loader = curLoader;
+ cls->engine = &_Jv_soleCompiledEngine;
+ curHelper->registerClass(cls->getName(), cls);
}
static void
diff --git a/libjava/gnu/gcj/util/Debug.java b/libjava/gnu/gcj/util/Debug.java
new file mode 100644
index 00000000000..568de7a0e7e
--- /dev/null
+++ b/libjava/gnu/gcj/util/Debug.java
@@ -0,0 +1,225 @@
+/* Copyright (C) 2004 Free Software Foundation
+
+This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+/* Utility methods that allow an object to be converted to a textual
+ representation on an OutputStream. The intention here is that this
+ class be used for debugging, so we provide information about all
+ fields, public or otherwise. */
+
+package gnu.gcj.util;
+
+import java.lang.reflect.*;
+import java.io.*;
+import java.util.*;
+
+class Debug
+{
+ private final PrintStream p;
+ private final int maxdepth;
+ private final int maxArrayLength;
+ private final boolean printStaticFields;
+ private int depth;
+
+ Debug(PrintStream writer, int maxdepth, int maxArrayLength, boolean printStaticFields)
+ {
+ p = writer;
+ this.maxdepth = maxdepth;
+ this.maxArrayLength = maxArrayLength;
+ this.printStaticFields = printStaticFields;
+ }
+
+ Debug(PrintStream writer)
+ {
+ this(writer, 0, 10, false);
+ }
+
+ Debug(int maxdepth, boolean printStaticFields)
+ {
+ this(new PrintStream
+ (new FileOutputStream(FileDescriptor.err), true),
+ maxdepth,
+ maxdepth > 0 ? 1000 : 10, printStaticFields);
+ }
+
+ Debug(int maxdepth)
+ {
+ this(maxdepth, false);
+ }
+
+ Debug()
+ {
+ this(0, false);
+ }
+
+ private final void indent()
+ {
+ for (int i = 0; i < depth; i++)
+ p.print(" ");
+ }
+
+ private final java.util.IdentityHashMap h =
+ new java.util.IdentityHashMap();
+
+ private static native Field[] getDeclaredFields(Class c);
+ private static native Object getField(Object o, Field f);
+ private static native long getAddr(Object o);
+
+ // Return an array containing all the fields of a class and its
+ // superclasses.
+ private Field[] internalGetFields(Class c)
+ {
+ HashSet set = new HashSet();
+ set.addAll(Arrays.asList(getDeclaredFields(c)));
+ Class[] interfaces = c.getInterfaces();
+ for (int i = 0; i < interfaces.length; i++)
+ set.addAll(Arrays.asList(internalGetFields(interfaces[i])));
+ Class superClass = c.getSuperclass();
+ if (superClass != null)
+ set.addAll(Arrays.asList(internalGetFields(superClass)));
+ return (Field[])set.toArray(new Field[set.size()]);
+ }
+
+ // FIXME: We could just use getClass() here, but this is a
+ // workaround for a C++ bug that is causing getClass() to be
+ // miscompiled.
+ static private Class getItsClass(Object O)
+ {
+ return O.getClass();
+ }
+
+ // Print a reasonably readable textual representation of an object
+ // on our OutputStream. Objects are only printed once, no matter
+ // how many references point to them.
+ private void print(Object O)
+ {
+ int savedDepth = depth;
+ h.put(O, O);
+ try
+ {
+ Class C = getItsClass(O);
+ p.print(C.getName() + "@");
+ p.println(Long.toHexString(getAddr(O)));
+
+ if (C.isArray())
+ {
+ indent(); p.println("{");
+ depth++;
+ indent();
+ C = C.getComponentType();
+
+ int len = Array.getLength(O);
+ for (int i = 0; i < len; i++)
+ {
+ Object thing = Array.get(O, i);
+ print0(thing, C);
+ p.print(", ");
+ if (i > maxArrayLength)
+ {
+ p.print("...");
+ break;
+ }
+ }
+ depth--;
+ p.println();
+ indent(); p.print("}");
+ return;
+ }
+
+ indent(); p.println("{");
+ depth++;
+ if (C == java.lang.Class.class)
+ {
+ indent();
+ p.println ("class = " + O.toString() + ",");
+ }
+ else if (C == java.lang.reflect.Field.class)
+ {
+ indent();
+ p.println ("<field> = \"" + O.toString() + "\",");
+ }
+ else if (C == java.lang.String.class)
+ {
+ indent();
+ p.println ("<string> = \"" + O.toString() + "\",");
+ }
+ Field[] f = internalGetFields(C);
+ for (int i = 0; i < f.length; i++)
+ {
+ Class type = f[i].getType();
+ boolean isStatic = (f[i].getModifiers() & Modifier.STATIC) != 0;
+
+ if (isStatic && ! printStaticFields)
+ continue;
+
+ indent();
+ if (isStatic)
+ p.print("static ");
+ p.print(type.getName() +" " +f[i].getName() + " = ");
+ Object thing = getField(O, f[i]);
+ print0(thing, type);
+ p.println(",");
+ }
+ depth--;
+ indent(); p.print("}");
+ }
+ catch (Throwable t)
+ {
+ p.print("error: 0x" + Long.toHexString(getAddr(O)) + ";");
+ depth = savedDepth;
+ }
+ }
+
+ private void print0(Object thing, Class C)
+ {
+ try
+ {
+ if (thing == null)
+ {
+ p.print("null");
+ return;
+ }
+ else if (C == gnu.gcj.RawData.class)
+ {
+ }
+ else if (C.isPrimitive())
+ {
+ if (getItsClass(thing) == Character.class)
+ p.print("'" + thing + "'");
+ else
+ p.print(thing);
+ return;
+ }
+ else if (getItsClass(thing) == String.class)
+ {
+ p.print("\"" + thing + "\"");
+ return;
+ }
+ else if (depth < maxdepth && h.get(thing) == null)
+ {
+ depth++;
+ print(thing);
+ depth--;
+ return;
+ }
+ }
+ catch (Throwable t)
+ {
+ }
+
+ // The default cation: just print the address.
+ p.print("0x"+ Long.toHexString(getAddr(thing)));
+ }
+
+ // Print the textual representation of an object on System.err.
+ public void write(Object O)
+ {
+ depth = 0;
+ print(O);
+ p.flush();
+ }
+}
diff --git a/libjava/gnu/gcj/util/natDebug.cc b/libjava/gnu/gcj/util/natDebug.cc
new file mode 100644
index 00000000000..0fa98d63762
--- /dev/null
+++ b/libjava/gnu/gcj/util/natDebug.cc
@@ -0,0 +1,118 @@
+// natDebug -- C++ side of Debug
+
+/* Copyright (C) 2004 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <stddef.h>
+#include <gcj/cni.h>
+#include <gcj/field.h>
+#include <gcj/javaprims.h>
+#include <java/lang/reflect/Field.h>
+#include <java/lang/Class.h>
+#include <java/lang/Byte.h>
+#include <java/lang/Short.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Long.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/Character.h>
+#include <java/lang/IllegalArgumentException.h>
+
+#include <gnu/gcj/util/Debug.h>
+
+jlong
+gnu::gcj::util::Debug::getAddr (::java::lang::Object *o)
+{
+ return (jlong)(size_t)o;
+}
+
+JArray< ::java::lang::reflect::Field *> *
+gnu::gcj::util::Debug::getDeclaredFields (::java::lang::Class *c)
+{
+ return c->getDeclaredFields (false);
+}
+
+static void *
+::getField (::java::lang::Object *obj,
+ ::java::lang::reflect::Field *field)
+{
+ using namespace java::lang::reflect;
+
+ jfieldID fld = _Jv_FromReflectedField (field);
+ _Jv_ushort flags = fld->getModifiers();
+
+ if (flags & Modifier::STATIC)
+ {
+ jclass fldClass = field->getDeclaringClass ();
+ JvInitClass(fldClass);
+ return (void*) fld->u.addr;
+ }
+ else
+ {
+ return (void*) ((char*) obj + fld->getOffset ());
+ }
+}
+
+::java::lang::Object *
+gnu::gcj::util::Debug::getField (::java::lang::Object *o,
+ ::java::lang::reflect::Field *field)
+{
+ void *addr = ::getField (o, field);
+
+ jclass type = field->getType();
+ if (! type->isPrimitive ())
+ return * (jobject*) addr;
+ if (type == JvPrimClass (double))
+ return new java::lang::Double (* (jdouble*) addr);
+ if (type == JvPrimClass (float))
+ return new java::lang::Float (* (jfloat*) addr);
+ if (type == JvPrimClass (long))
+ return new java::lang::Long (* (jlong*) addr);
+ if (type == JvPrimClass (int))
+ return new java::lang::Integer (* (jint*) addr);
+ if (type == JvPrimClass (short))
+ return new java::lang::Short (* (jshort*) addr);
+ if (type == JvPrimClass (byte))
+ return new java::lang::Byte (* (jbyte*) addr);
+ if (type == JvPrimClass (char))
+ return new java::lang::Character (* (jchar*) addr);
+ if (type == JvPrimClass (boolean))
+ {
+ _Jv_InitClass (&java::lang::Boolean::class$);
+ if (* (jboolean*) addr)
+ return java::lang::Boolean::TRUE;
+ else
+ return java::lang::Boolean::FALSE;
+ }
+ throw new java::lang::IllegalArgumentException;
+}
+
+/* A simple method of printing an object that can be called from a
+ debugger. */
+extern "C"
+void
+_Jv_Debug (void *p)
+{
+ (new ::gnu::gcj::util::Debug ())->write ((jobject)p);
+}
+
+extern "C"
+void
+_Jv_DeepDebug (void *p, int depth)
+{
+ (new ::gnu::gcj::util::Debug (depth))->write ((jobject)p);
+}
+
+extern "C"
+void
+_Jv_StaticDeepDebug (void *p, int depth)
+{
+ (new ::gnu::gcj::util::Debug (depth, true))->write ((jobject)p);
+}
diff --git a/libjava/gnu/java/awt/BitwiseXORComposite.java b/libjava/gnu/java/awt/BitwiseXORComposite.java
index 675c225bbfa..dd4f015b42a 100644
--- a/libjava/gnu/java/awt/BitwiseXORComposite.java
+++ b/libjava/gnu/java/awt/BitwiseXORComposite.java
@@ -232,7 +232,7 @@ public class BitwiseXORComposite
WritableRaster dstOut)
{
int aX, bX, dstX, aY, bY, dstY, width, height;
- int xorPixel, transferType;
+ int xorPixel;
int[] srcLine, dstLine;
aX = src.getMinX();
diff --git a/libjava/gnu/java/awt/Buffers.java b/libjava/gnu/java/awt/Buffers.java
index 24fe2cef242..3f254749e0b 100644
--- a/libjava/gnu/java/awt/Buffers.java
+++ b/libjava/gnu/java/awt/Buffers.java
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002 Free Software Foundation
+/* Copyright (C) 2000, 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -83,10 +83,16 @@ public final class Buffers
{
case DataBuffer.TYPE_BYTE:
return new DataBufferByte(size, numBanks);
+ case DataBuffer.TYPE_SHORT:
+ return new DataBufferShort(size, numBanks);
case DataBuffer.TYPE_USHORT:
return new DataBufferUShort(size, numBanks);
case DataBuffer.TYPE_INT:
return new DataBufferInt(size, numBanks);
+ case DataBuffer.TYPE_FLOAT:
+ return new DataBufferFloat(size, numBanks);
+ case DataBuffer.TYPE_DOUBLE:
+ return new DataBufferDouble(size, numBanks);
default:
throw new UnsupportedOperationException();
}
@@ -106,10 +112,16 @@ public final class Buffers
{
case DataBuffer.TYPE_BYTE:
return new DataBufferByte((byte[]) data, size);
+ case DataBuffer.TYPE_SHORT:
+ return new DataBufferShort((short[]) data, size);
case DataBuffer.TYPE_USHORT:
return new DataBufferUShort((short[]) data, size);
case DataBuffer.TYPE_INT:
return new DataBufferInt((int[]) data, size);
+ case DataBuffer.TYPE_FLOAT:
+ return new DataBufferFloat((float[]) data, size);
+ case DataBuffer.TYPE_DOUBLE:
+ return new DataBufferDouble((double[]) data, size);
default:
throw new UnsupportedOperationException();
}
@@ -126,10 +138,22 @@ public final class Buffers
{
if (buffer instanceof DataBufferByte)
return ((DataBufferByte) buffer).getData();
+
+ if (buffer instanceof DataBufferShort)
+ return ((DataBufferShort) buffer).getData();
+
if (buffer instanceof DataBufferUShort)
return ((DataBufferUShort) buffer).getData();
+
if (buffer instanceof DataBufferInt)
return ((DataBufferInt) buffer).getData();
+
+ if (buffer instanceof DataBufferFloat)
+ return ((DataBufferFloat) buffer).getData();
+
+ if (buffer instanceof DataBufferDouble)
+ return ((DataBufferDouble) buffer).getData();
+
throw new ClassCastException("Unknown data buffer type");
}
@@ -149,6 +173,11 @@ public final class Buffers
from = ((DataBufferByte) src).getData();
if (dest == null) dest = new byte[length+destOffset];
}
+ else if (src instanceof DataBufferShort)
+ {
+ from = ((DataBufferShort) src).getData();
+ if (dest == null) dest = new short[length+destOffset];
+ }
else if (src instanceof DataBufferUShort)
{
from = ((DataBufferUShort) src).getData();
@@ -159,6 +188,16 @@ public final class Buffers
from = ((DataBufferInt) src).getData();
if (dest == null) dest = new int[length+destOffset];
}
+ else if (src instanceof DataBufferFloat)
+ {
+ from = ((DataBufferFloat) src).getData();
+ if (dest == null) dest = new float[length+destOffset];
+ }
+ else if (src instanceof DataBufferDouble)
+ {
+ from = ((DataBufferDouble) src).getData();
+ if (dest == null) dest = new double[length+destOffset];
+ }
else
{
throw new ClassCastException("Unknown data buffer type");
diff --git a/libjava/gnu/java/awt/peer/ClasspathFontPeer.java b/libjava/gnu/java/awt/peer/ClasspathFontPeer.java
index 287c271ba2f..6b753aa15ec 100644
--- a/libjava/gnu/java/awt/peer/ClasspathFontPeer.java
+++ b/libjava/gnu/java/awt/peer/ClasspathFontPeer.java
@@ -1,5 +1,5 @@
/* ClasspathFontPeer.java -- Font peer used by GNU Classpath.
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -395,6 +395,23 @@ public abstract class ClasspathFontPeer
}
/**
+ * Implementation of {@link Font#deriveFont(int, float)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public Font deriveFont (Font font, int style, float size)
+ {
+ Map attrs = new HashMap ();
+ getStandardAttributes (attrs);
+ copyStyleToAttrs (style, attrs);
+ copySizeToAttrs (size, attrs);
+ return tk().getFont (logicalName, attrs);
+ }
+
+ /**
* Implementation of {@link Font#deriveFont(float)}
*
* @param font the font this peer is being called from. This may be
@@ -444,6 +461,22 @@ public abstract class ClasspathFontPeer
}
/**
+ * Implementation of {@link Font#deriveFont(AffineTransform)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public Font deriveFont (Font font, AffineTransform t)
+ {
+ Map attrs = new HashMap ();
+ getStandardAttributes (attrs);
+ copyTransformToAttrs (t, attrs);
+ return tk().getFont (logicalName, attrs);
+ }
+
+ /**
* Implementation of {@link Font#deriveFont(Map)}
*
* @param font the font this peer is being called from. This may be
diff --git a/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java b/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java
index 8bae336c4de..633eb096483 100644
--- a/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java
+++ b/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java
@@ -201,7 +201,7 @@ public class GdkGraphics2D extends Graphics2D
// draw current buffered image to the pixmap associated
// with it.
- drawImage (bimage, new AffineTransform (1,0,0,1,0,0), null);
+ drawImage (bimage, new AffineTransform (1,0,0,1,0,0), bg, null);
}
@@ -440,6 +440,69 @@ public class GdkGraphics2D extends Graphics2D
}
+ private boolean drawImage(Image img,
+ AffineTransform xform,
+ Color bgcolor,
+ ImageObserver obs)
+ {
+ if (img instanceof GtkOffScreenImage &&
+ img.getGraphics () instanceof GdkGraphics2D &&
+ (xform == null
+ || xform.getType () == AffineTransform.TYPE_IDENTITY
+ || xform.getType () == AffineTransform.TYPE_TRANSLATION)
+ )
+ {
+ // we are being asked to flush a double buffer from Gdk
+ GdkGraphics2D g2 = (GdkGraphics2D) img.getGraphics ();
+ gdkDrawDrawable (g2, (int)xform.getTranslateX(), (int)xform.getTranslateY());
+
+ if (isBufferedImageGraphics ())
+ updateBufferedImage();
+
+ return true;
+ }
+ else
+ {
+
+ // In this case, xform is an AffineTransform that transforms bounding
+ // box of the specified image from image space to user space. However
+ // when we pass this transform to cairo, cairo will use this transform
+ // to map "user coordinates" to "pixel" coordinates, which is the
+ // other way around. Therefore to get the "user -> pixel" transform
+ // that cairo wants from "image -> user" transform that we currently
+ // have, we will need to invert the transformation matrix.
+
+ AffineTransform invertedXform = new AffineTransform();
+
+ try
+ {
+ invertedXform = xform.createInverse();
+ if (img instanceof BufferedImage)
+ {
+ // draw an image which has actually been loaded
+ // into memory fully
+
+ BufferedImage b = (BufferedImage) img;
+ return drawRaster (b.getColorModel (),
+ b.getData (),
+ invertedXform,
+ bgcolor);
+ }
+ else
+ {
+ // begin progressive loading in a separate thread
+ new PainterThread (this, img, invertedXform, bgcolor);
+ return false;
+ }
+ }
+ catch (NoninvertibleTransformException e)
+ {
+ throw new ImagingOpException("Unable to invert transform "
+ + xform.toString());
+ }
+ }
+ }
+
//////////////////////////////////////////////////
////// Implementation of Graphics2D Methods //////
@@ -965,7 +1028,8 @@ public class GdkGraphics2D extends Graphics2D
}
private boolean drawRaster (ColorModel cm, Raster r,
- AffineTransform imageToUser)
+ AffineTransform imageToUser,
+ Color bgcolor)
{
if (r == null)
return false;
@@ -1012,6 +1076,18 @@ public class GdkGraphics2D extends Graphics2D
pixels = pixels2;
}
+ // change all transparent pixels in the image to the
+ // specified bgcolor
+
+ if (bgcolor != null)
+ {
+ for (int i = 0; i < pixels.length; i++)
+ {
+ if (cm.getAlpha (pixels[i]) == 0)
+ pixels[i] = bgcolor.getRGB ();
+ }
+ }
+
stateSave ();
translate (x, y);
drawPixels (pixels, r.getWidth (), r.getHeight (), r.getWidth (), i2u);
@@ -1026,7 +1102,7 @@ public class GdkGraphics2D extends Graphics2D
public void drawRenderedImage(RenderedImage image,
AffineTransform xform)
{
- drawRaster (image.getColorModel(), image.getData(), xform);
+ drawRaster (image.getColorModel(), image.getData(), xform, bg);
}
public void drawRenderableImage(RenderableImage image,
@@ -1039,60 +1115,7 @@ public class GdkGraphics2D extends Graphics2D
AffineTransform xform,
ImageObserver obs)
{
- if (img instanceof GtkOffScreenImage &&
- img.getGraphics () instanceof GdkGraphics2D &&
- (xform == null
- || xform.getType () == AffineTransform.TYPE_IDENTITY
- || xform.getType () == AffineTransform.TYPE_TRANSLATION)
- )
- {
- // we are being asked to flush a double buffer from Gdk
- GdkGraphics2D g2 = (GdkGraphics2D) img.getGraphics ();
- gdkDrawDrawable (g2, (int)xform.getTranslateX(), (int)xform.getTranslateY());
-
- if (isBufferedImageGraphics ())
- updateBufferedImage();
-
- return true;
- }
- else
- {
-
- // In this case, xform is an AffineTransform that transforms bounding
- // box of the specified image from image space to user space. However
- // when we pass this transform to cairo, cairo will use this transform
- // to map "user coordinates" to "pixel" coordinates, which is the
- // other way around. Therefore to get the "user -> pixel" transform
- // that cairo wants from "image -> user" transform that we currently
- // have, we will need to invert the transformation matrix.
-
- AffineTransform invertedXform = new AffineTransform();
-
- try
- {
- invertedXform = xform.createInverse();
- if (img instanceof BufferedImage)
- {
- // draw an image which has actually been loaded
- // into memory fully
- BufferedImage b = (BufferedImage) img;
- return drawRaster (b.getColorModel (),
- b.getData (),
- invertedXform);
- }
- else
- {
- // begin progressive loading in a separate thread
- new PainterThread (this, img, invertedXform);
- return false;
- }
- }
- catch (NoninvertibleTransformException e)
- {
- throw new ImagingOpException("Unable to invert transform "
- + xform.toString());
- }
- }
+ return drawImage(img, xform, bg, obs);
}
public void drawImage(BufferedImage image,
@@ -1101,13 +1124,13 @@ public class GdkGraphics2D extends Graphics2D
int y)
{
Image filtered = op.filter(image, null);
- drawImage(filtered, new AffineTransform(1f,0f,0f,1f,x,y), null);
+ drawImage(filtered, new AffineTransform(1f,0f,0f,1f,x,y), bg, null);
}
public boolean drawImage (Image img, int x, int y,
ImageObserver observer)
{
- return drawImage(img, new AffineTransform(1f,0f,0f,1f,x,y), observer);
+ return drawImage(img, new AffineTransform(1f,0f,0f,1f,x,y), bg, observer);
}
@@ -1130,11 +1153,14 @@ public class GdkGraphics2D extends Graphics2D
Image image;
ColorModel defaultModel;
AffineTransform xform;
+ Color bgcolor;
- public PainterThread (GdkGraphics2D g, Image im, AffineTransform xf)
+ public PainterThread (GdkGraphics2D g, Image im,
+ AffineTransform xf, Color bg)
{
image = im;
xform = xf;
+ bgcolor = bg;
this.gr = (GdkGraphics2D) g.create ();
new Thread (this).start ();
}
@@ -1184,6 +1210,18 @@ public class GdkGraphics2D extends Graphics2D
else
pixels2 = pixels;
+ // change all transparent pixels in the image to the
+ // specified bgcolor
+
+ if (bgcolor != null)
+ {
+ for (int i = 0; i < pixels2.length; i++)
+ {
+ if (model.getAlpha (pixels2[i]) == 0)
+ pixels2[i] = bgcolor.getRGB ();
+ }
+ }
+
double[] xf = new double[6];
xform.getMatrix(xf);
gr.drawPixels (pixels2, w, h, scansize, xf);
@@ -1347,40 +1385,27 @@ public class GdkGraphics2D extends Graphics2D
Color bgcolor, ImageObserver observer)
{
- // FIXME: change all the transparent pixels in the image to
- // bgcolor.
-
- return drawImage (img, x, y, width, height, observer);
- }
-
- public boolean drawImage (Image img, int x, int y, int width, int height,
- ImageObserver observer)
- {
-
double scaleX = width / (double) img.getWidth (observer);
double scaleY = height / (double) img.getHeight (observer);
return drawImage (img,
new AffineTransform(scaleX, 0f, 0f, scaleY, x, y),
+ bgcolor,
observer);
}
- public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2,
- int sx1, int sy1, int sx2, int sy2,
- Color bgcolor, ImageObserver observer)
+ public boolean drawImage (Image img, int x, int y, int width, int height,
+ ImageObserver observer)
{
-
- // FIXME: change all transparent pixels in the image to
- // bgcolor
-
- return drawImage (img, dx1, dy1, dx2, dy2,
- sx1, sy1, sx2, sy2, observer);
+
+ return drawImage (img, x, y, width, height, bg, observer);
+
}
public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2,
int sx1, int sy1, int sx2, int sy2,
- ImageObserver observer)
+ Color bgcolor, ImageObserver observer)
{
Image subImage;
@@ -1420,8 +1445,18 @@ public class GdkGraphics2D extends Graphics2D
}
return drawImage(subImage, new AffineTransform(scaleX, 0, 0,
- scaleY, dx1, dy1),
- observer);
+ scaleY, dx1, dy1),
+ bgcolor,
+ observer);
+ }
+
+ public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2,
+ int sx1, int sy1, int sx2, int sy2,
+ ImageObserver observer)
+ {
+
+ return drawImage (img, dx1, dy1, dx2, dy2,
+ sx1, sy1, sx2, sy2, bg, observer);
}
public void drawOval(int x, int y, int width, int height)
diff --git a/libjava/gnu/java/awt/peer/gtk/GtkFontPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkFontPeer.java
index 1ab7bc13420..5de3301270d 100644
--- a/libjava/gnu/java/awt/peer/gtk/GtkFontPeer.java
+++ b/libjava/gnu/java/awt/peer/gtk/GtkFontPeer.java
@@ -43,6 +43,7 @@ import java.awt.geom.*;
import java.awt.font.*;
import java.util.Locale;
import java.util.ResourceBundle;
+import java.util.MissingResourceException;
import java.text.*;
import gnu.java.awt.peer.ClasspathFontPeer;
@@ -74,9 +75,20 @@ public class GtkFontPeer extends ClasspathFontPeer
{
super(name, style, size);
+ String Xname = null;
if (bundle != null)
- Xname = bundle.getString (name.toLowerCase () + "." + style);
- else
+ {
+ try
+ {
+ Xname = bundle.getString (name.toLowerCase () + "." + style);
+ }
+ catch (MissingResourceException mre)
+ {
+ // ignored
+ }
+ }
+
+ if (Xname == null)
{
String weight;
String slant;
@@ -98,6 +110,8 @@ public class GtkFontPeer extends ClasspathFontPeer
Xname = "-*-*-" + weight + "-" + slant + "-normal-*-*-" + size + "-*-*-" + spacing + "-*-*-*";
}
+
+ this.Xname = Xname;
}
public String getXLFD ()
diff --git a/libjava/gnu/java/awt/peer/gtk/GtkMenuItemPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkMenuItemPeer.java
index 4e338f64967..55581d1c64e 100644
--- a/libjava/gnu/java/awt/peer/gtk/GtkMenuItemPeer.java
+++ b/libjava/gnu/java/awt/peer/gtk/GtkMenuItemPeer.java
@@ -50,6 +50,7 @@ public class GtkMenuItemPeer extends GtkMenuComponentPeer
implements MenuItemPeer
{
native void create (String label);
+ public native void connectSignals ();
public GtkMenuItemPeer (MenuItem item)
{
@@ -57,6 +58,9 @@ public class GtkMenuItemPeer extends GtkMenuComponentPeer
create (item.getLabel ());
setEnabled (item.isEnabled ());
setParent (item);
+
+ if (item.getParent() instanceof Menu && ! (item instanceof Menu))
+ connectSignals();
}
void setParent (MenuItem item)
diff --git a/libjava/gnu/java/awt/peer/gtk/GtkMenuPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkMenuPeer.java
index a5fcae720c3..9b3f678856e 100644
--- a/libjava/gnu/java/awt/peer/gtk/GtkMenuPeer.java
+++ b/libjava/gnu/java/awt/peer/gtk/GtkMenuPeer.java
@@ -95,10 +95,5 @@ public class GtkMenuPeer extends GtkMenuItemPeer
addItem (item, key, shiftModifier);
}
- public void addSeparator ()
- {
- addItem (new MenuItem ("-"));
- }
-
native public void delItem (int index);
}
diff --git a/libjava/gnu/java/awt/peer/gtk/GtkPanelPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkPanelPeer.java
index 4f77994931d..70aab2ca59d 100644
--- a/libjava/gnu/java/awt/peer/gtk/GtkPanelPeer.java
+++ b/libjava/gnu/java/awt/peer/gtk/GtkPanelPeer.java
@@ -46,7 +46,6 @@ public class GtkPanelPeer extends GtkContainerPeer
{
native void create ();
native void connectJObject ();
- native void connectSignals ();
public GtkPanelPeer (Panel p)
{
diff --git a/libjava/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java
index e31a481537f..63d6fa86fe1 100644
--- a/libjava/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java
+++ b/libjava/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java
@@ -105,8 +105,6 @@ public class GtkTextAreaPeer extends GtkTextComponentPeer
public Dimension minimumSize (int rows, int cols)
{
TextArea ta = ((TextArea) awtComponent);
- int hScrollbarHeight = 0;
- int vScrollbarWidth = 0;
int height = 0;
int width = 0;
@@ -137,8 +135,6 @@ public class GtkTextAreaPeer extends GtkTextComponentPeer
public Dimension preferredSize (int rows, int cols)
{
TextArea ta = ((TextArea) awtComponent);
- int hScrollbarHeight = 0;
- int vScrollbarWidth = 0;
int height = 0;
int width = 0;
diff --git a/libjava/gnu/java/awt/peer/gtk/GtkToolkit.java b/libjava/gnu/java/awt/peer/gtk/GtkToolkit.java
index 1d961f2d5b7..ed1c567624b 100644
--- a/libjava/gnu/java/awt/peer/gtk/GtkToolkit.java
+++ b/libjava/gnu/java/awt/peer/gtk/GtkToolkit.java
@@ -377,12 +377,8 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
*/
private FontPeer getFontPeer (String name, int style, int size)
{
- try {
- GtkFontPeer fp = new GtkFontPeer (name, style, size);
- return fp;
- } catch (MissingResourceException ex) {
- return null;
- }
+ GtkFontPeer fp = new GtkFontPeer (name, style, size);
+ return fp;
}
/**
diff --git a/libjava/gnu/java/beans/BeanInfoEmbryo.java b/libjava/gnu/java/beans/BeanInfoEmbryo.java
index 473aa790cba..16738fe6048 100644
--- a/libjava/gnu/java/beans/BeanInfoEmbryo.java
+++ b/libjava/gnu/java/beans/BeanInfoEmbryo.java
@@ -38,10 +38,17 @@ exception statement from your version. */
package gnu.java.beans;
-import java.beans.*;
-import java.util.*;
-import gnu.java.lang.*;
-import java.lang.reflect.*;
+import java.beans.BeanDescriptor;
+import java.beans.BeanInfo;
+import java.beans.EventSetDescriptor;
+import java.beans.IndexedPropertyDescriptor;
+import java.beans.MethodDescriptor;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
/**
** A BeanInfoEmbryo accumulates information about a Bean
diff --git a/libjava/gnu/java/beans/info/ComponentBeanInfo.java b/libjava/gnu/java/beans/info/ComponentBeanInfo.java
index fce476149a9..877a18d65d2 100644
--- a/libjava/gnu/java/beans/info/ComponentBeanInfo.java
+++ b/libjava/gnu/java/beans/info/ComponentBeanInfo.java
@@ -38,8 +38,9 @@ exception statement from your version. */
package gnu.java.beans.info;
-import gnu.java.beans.*;
-import java.beans.*;
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.beans.SimpleBeanInfo;
/** BeanInfo class for java.awt.Component.
** This provides a few properties, but that's
diff --git a/libjava/gnu/java/io/Base64InputStream.java b/libjava/gnu/java/io/Base64InputStream.java
index 0879e945962..3780e952837 100644
--- a/libjava/gnu/java/io/Base64InputStream.java
+++ b/libjava/gnu/java/io/Base64InputStream.java
@@ -39,9 +39,8 @@ exception statement from your version. */
package gnu.java.io;
import java.io.FilterInputStream;
-import java.io.InputStream;
import java.io.IOException;
-import java.io.EOFException;
+import java.io.InputStream;
/**
* A filter input stream that decodes data encoded in the Base-64
diff --git a/libjava/gnu/java/net/natPlainSocketImplPosix.cc b/libjava/gnu/java/net/natPlainSocketImplPosix.cc
index 1dbc90d6010..7fd4fe04d6f 100644
--- a/libjava/gnu/java/net/natPlainSocketImplPosix.cc
+++ b/libjava/gnu/java/net/natPlainSocketImplPosix.cc
@@ -380,7 +380,7 @@ gnu::java::net::PlainSocketImpl$SocketInputStream::read(void)
jbyte data;
if (read_helper (this$0->native_fd, this$0->timeout, &data, 1) == 1)
- return data;
+ return data & 0xFF;
return -1;
}
diff --git a/libjava/gnu/java/nio/FileLockImpl.java b/libjava/gnu/java/nio/FileLockImpl.java
index 23f67b8ded2..bba5880e22c 100644
--- a/libjava/gnu/java/nio/FileLockImpl.java
+++ b/libjava/gnu/java/nio/FileLockImpl.java
@@ -38,27 +38,17 @@ exception statement from your version. */
package gnu.java.nio;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.nio.channels.*;
-import gnu.classpath.Configuration;
import gnu.java.nio.channels.FileChannelImpl;
+import java.io.IOException;
+import java.nio.channels.FileLock;
+
/**
* @author Michael Koch
* @since 1.4
*/
public class FileLockImpl extends FileLock
{
- static
- {
- // load the shared library needed for native methods.
- if (Configuration.INIT_LOAD_LIBRARY)
- {
- System.loadLibrary ("javanio");
- }
- }
-
private FileChannelImpl ch;
public FileLockImpl (FileChannelImpl channel, long position,
diff --git a/libjava/gnu/java/nio/SocketChannelImpl.java b/libjava/gnu/java/nio/SocketChannelImpl.java
index d4dd6e05653..c67b7cb7bb7 100644
--- a/libjava/gnu/java/nio/SocketChannelImpl.java
+++ b/libjava/gnu/java/nio/SocketChannelImpl.java
@@ -38,12 +38,12 @@ exception statement from your version. */
package gnu.java.nio;
-import java.io.InputStream;
+import gnu.java.net.PlainSocketImpl;
+
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
-import java.net.InetAddress;
import java.net.InetSocketAddress;
-import gnu.java.net.PlainSocketImpl;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketTimeoutException;
@@ -53,13 +53,12 @@ import java.nio.channels.ClosedChannelException;
import java.nio.channels.ConnectionPendingException;
import java.nio.channels.NoConnectionPendingException;
import java.nio.channels.NotYetConnectedException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
import java.nio.channels.UnresolvedAddressException;
import java.nio.channels.UnsupportedAddressTypeException;
-import java.nio.channels.SocketChannel;
-import java.nio.channels.Selector;
-import java.nio.channels.SelectionKey;
import java.nio.channels.spi.SelectorProvider;
-import gnu.classpath.Configuration;
public final class SocketChannelImpl extends SocketChannel
{
diff --git a/libjava/gnu/java/nio/channels/FileChannelImpl.java b/libjava/gnu/java/nio/channels/FileChannelImpl.java
index b5e5ffe6b67..f4686b26d4f 100644
--- a/libjava/gnu/java/nio/channels/FileChannelImpl.java
+++ b/libjava/gnu/java/nio/channels/FileChannelImpl.java
@@ -39,12 +39,19 @@ exception statement from your version. */
package gnu.java.nio.channels;
import gnu.classpath.Configuration;
-import gnu.gcj.RawData;
import gnu.java.nio.FileLockImpl;
-import java.io.*;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
-import java.nio.channels.*;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.nio.channels.NonReadableChannelException;
+import java.nio.channels.NonWritableChannelException;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.WritableByteChannel;
/**
* This file is not user visible !
@@ -53,23 +60,29 @@ import java.nio.channels.*;
* Instances of this class are created by invoking getChannel
* Upon a Input/Output/RandomAccessFile object.
*/
-
-public class FileChannelImpl extends FileChannel
+public final class FileChannelImpl extends FileChannel
{
- int mode;
- // These are WHENCE values for seek.
- static final int SET = 0;
- static final int CUR = 1;
-
// These are mode values for open().
- static final int READ = 1;
- static final int WRITE = 2;
- static final int APPEND = 4;
+ public static final int READ = 1;
+ public static final int WRITE = 2;
+ public static final int APPEND = 4;
// EXCL is used only when making a temp file.
- static final int EXCL = 8;
- static final int SYNC = 16;
- static final int DSYNC = 32;
+ public static final int EXCL = 8;
+ public static final int SYNC = 16;
+ public static final int DSYNC = 32;
+
+ private static native void init();
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javanio");
+ }
+
+ init();
+ }
/**
* This is the actual native file descriptor value
@@ -81,8 +94,8 @@ public class FileChannelImpl extends FileChannel
// efficient way to accomplish that.
private int fd = -1;
- int length;
private long pos;
+ private int mode;
public FileChannelImpl ()
{
@@ -95,8 +108,17 @@ public class FileChannelImpl extends FileChannel
this.mode = mode;
}
- private static native void init();
- static { init (); }
+ /* Used by init() (native code) */
+ FileChannelImpl (int fd, int mode)
+ {
+ this.fd = fd;
+ this.mode = mode;
+ }
+
+ protected void finalize() throws Throwable
+ {
+ close();
+ }
public static FileChannelImpl in;
public static FileChannelImpl out;
@@ -104,19 +126,12 @@ public class FileChannelImpl extends FileChannel
private native int open (String path, int mode) throws FileNotFoundException;
- /** Attach to an already-opened file. */
- public FileChannelImpl (int desc, int mode)
- {
- fd = desc;
- this.mode = mode;
- }
-
- native int available () throws IOException;
- private native long implPosition ();
- private native void seek (long newPosition);
- private native void implTruncate (long size);
+ public native int available () throws IOException;
+ private native long implPosition () throws IOException;
+ private native void seek (long newPosition) throws IOException;
+ private native void implTruncate (long size) throws IOException;
- public native void unlock (long pos, long len);
+ public native void unlock (long pos, long len) throws IOException;
public native long size () throws IOException;
@@ -124,7 +139,15 @@ public class FileChannelImpl extends FileChannel
public int read (ByteBuffer dst) throws IOException
{
- return implRead (dst);
+ int result;
+ byte[] buffer = new byte [dst.remaining ()];
+
+ result = read (buffer, 0, buffer.length);
+
+ if (result > 0)
+ dst.put (buffer, 0, result);
+
+ return result;
}
public int read (ByteBuffer dst, long position)
@@ -134,25 +157,12 @@ public class FileChannelImpl extends FileChannel
throw new IllegalArgumentException ();
long oldPosition = implPosition ();
position (position);
- int result = implRead (dst);
+ int result = read(dst);
position (oldPosition);
return result;
}
- private int implRead (ByteBuffer dst) throws IOException
- {
- int result;
- byte[] buffer = new byte [dst.remaining ()];
-
- result = read (buffer, 0, buffer.length);
-
- if (result > 0)
- dst.put (buffer, 0, result);
-
- return result;
- }
-
public native int read ()
throws IOException;
@@ -174,7 +184,20 @@ public class FileChannelImpl extends FileChannel
public int write (ByteBuffer src) throws IOException
{
- return implWrite (src);
+ int len = src.remaining ();
+ if (src.hasArray())
+ {
+ byte[] buffer = src.array();
+ write(buffer, src.arrayOffset() + src.position(), len);
+ }
+ else
+ {
+ // Use a more efficient native method! FIXME!
+ byte[] buffer = new byte [len];
+ src.get (buffer, 0, len);
+ write (buffer, 0, len);
+ }
+ return len;
}
public int write (ByteBuffer src, long position)
@@ -194,30 +217,12 @@ public class FileChannelImpl extends FileChannel
oldPosition = implPosition ();
seek (position);
- result = implWrite (src);
+ result = write(src);
seek (oldPosition);
return result;
}
- private int implWrite (ByteBuffer src) throws IOException
- {
- int len = src.remaining ();
- if (src.hasArray())
- {
- byte[] buffer = src.array();
- write(buffer, src.arrayOffset() + src.position(), len);
- }
- else
- {
- // Use a more efficient native method! FIXME!
- byte[] buffer = new byte [len];
- src.get (buffer, 0, len);
- write (buffer, 0, len);
- }
- return len;
- }
-
public native void write (byte[] buffer, int offset, int length)
throws IOException;
@@ -350,7 +355,7 @@ public class FileChannelImpl extends FileChannel
* Otherwise return false.
*/
private native boolean lock(long position, long size,
- boolean shared, boolean wait);
+ boolean shared, boolean wait) throws IOException;
public FileLock lock (long position, long size, boolean shared)
throws IOException
diff --git a/libjava/gnu/java/nio/charset/UTF_16Decoder.java b/libjava/gnu/java/nio/charset/UTF_16Decoder.java
index c8e474d5741..6ff9c2893da 100644
--- a/libjava/gnu/java/nio/charset/UTF_16Decoder.java
+++ b/libjava/gnu/java/nio/charset/UTF_16Decoder.java
@@ -144,24 +144,6 @@ final class UTF_16Decoder extends CharsetDecoder
}
}
- /**
- * Writes <code>c</code> to <code>out</code> in the byte order
- * specified by <code>byteOrder</code>.
- **/
- private void put (ByteBuffer out, char c)
- {
- if (byteOrder == BIG_ENDIAN)
- {
- out.put ((byte) (c >> 8));
- out.put ((byte) (c & 0xFF));
- }
- else
- {
- out.put ((byte) (c & 0xFF));
- out.put ((byte) (c >> 8));
- }
- }
-
protected void implReset ()
{
byteOrder = originalByteOrder;
diff --git a/libjava/gnu/java/security/der/DERReader.java b/libjava/gnu/java/security/der/DERReader.java
index 3020b8b2d1a..3915b071165 100644
--- a/libjava/gnu/java/security/der/DERReader.java
+++ b/libjava/gnu/java/security/der/DERReader.java
@@ -335,7 +335,7 @@ public class DERReader implements DER
Integer.parseInt(str.substring( 6, 8)), // hour
Integer.parseInt(str.substring( 8, 10))); // minute
if (date.length() == 12);
- calendar.set(calendar.SECOND,
+ calendar.set(Calendar.SECOND,
Integer.parseInt(str.substring(10, 12)));
}
catch (NumberFormatException nfe)
@@ -362,13 +362,13 @@ public class DERReader implements DER
case 18:
case 17:
case 16:
- calendar.set(calendar.MILLISECOND,
+ calendar.set(Calendar.MILLISECOND,
Integer.parseInt(date.substring(15)));
case 14:
- calendar.set(calendar.SECOND,
+ calendar.set(Calendar.SECOND,
Integer.parseInt(date.substring(12, 14)));
case 12:
- calendar.set(calendar.MINUTE,
+ calendar.set(Calendar.MINUTE,
Integer.parseInt(date.substring(10, 12)));
}
}
diff --git a/libjava/gnu/java/security/der/DERWriter.java b/libjava/gnu/java/security/der/DERWriter.java
index ec3e3df339d..4e679ec802c 100644
--- a/libjava/gnu/java/security/der/DERWriter.java
+++ b/libjava/gnu/java/security/der/DERWriter.java
@@ -38,28 +38,23 @@ exception statement from your version. */
package gnu.java.security.der;
+import gnu.java.security.OID;
+
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
-
import java.math.BigInteger;
-
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
-
import java.text.SimpleDateFormat;
-
-import java.util.BitSet;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;
-import gnu.java.security.OID;
-
/**
* Methods that allow various Java types to be written as a DER
* (Distinguished Encoding Rules) stream to the specified output stream.
diff --git a/libjava/gnu/java/security/provider/DSAKeyPairGenerator.java b/libjava/gnu/java/security/provider/DSAKeyPairGenerator.java
index 72f7b0eeddb..d4dff167164 100644
--- a/libjava/gnu/java/security/provider/DSAKeyPairGenerator.java
+++ b/libjava/gnu/java/security/provider/DSAKeyPairGenerator.java
@@ -39,20 +39,18 @@ exception statement from your version. */
package gnu.java.security.provider;
import java.math.BigInteger;
-import java.security.AlgorithmParameters;
import java.security.AlgorithmParameterGenerator;
-import java.security.KeyPairGeneratorSpi;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
import java.security.KeyPair;
+import java.security.KeyPairGeneratorSpi;
import java.security.SecureRandom;
-import java.security.InvalidParameterException;
-import java.security.InvalidAlgorithmParameterException;
import java.security.interfaces.DSAParams;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.DSAParameterSpec;
import java.util.Random;
-import gnu.java.security.util.Prime;
-
public class DSAKeyPairGenerator extends KeyPairGeneratorSpi
implements java.security.interfaces.DSAKeyPairGenerator
{
diff --git a/libjava/gnu/java/security/provider/DSAParameters.java b/libjava/gnu/java/security/provider/DSAParameters.java
index 31c0d5e8e8e..3773308c26e 100644
--- a/libjava/gnu/java/security/provider/DSAParameters.java
+++ b/libjava/gnu/java/security/provider/DSAParameters.java
@@ -154,7 +154,6 @@ public byte[] engineGetEncoded(String format)
public String engineToString()
{
- String lineSeparator = System.getProperty("line.seperator");
return ("q: " + q + " p: " + p + " g: " + g);
}
diff --git a/libjava/gnu/java/text/AttributedFormatBuffer.java b/libjava/gnu/java/text/AttributedFormatBuffer.java
new file mode 100644
index 00000000000..a02f8a1bc97
--- /dev/null
+++ b/libjava/gnu/java/text/AttributedFormatBuffer.java
@@ -0,0 +1,247 @@
+/* AttributedFormatBuffer.java -- Implements an attributed FormatBuffer.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+package gnu.java.text;
+
+import java.text.AttributedCharacterIterator;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * This class is an implementation of a FormatBuffer with attributes.
+ *
+ * @author Guilhem Lavaux <guilhem@kaffe.org>
+ * @date April 10, 2004
+ */
+public class AttributedFormatBuffer implements FormatBuffer
+{
+ private StringBuffer buffer;
+ private ArrayList ranges;
+ private ArrayList attributes;
+ private int[] a_ranges;
+ private HashMap[] a_attributes;
+ private int startingRange;
+ AttributedCharacterIterator.Attribute defaultAttr;
+
+ /**
+ * This constructor accepts a StringBuffer. If the buffer contains
+ * already some characters they will not be attributed.
+ */
+ public AttributedFormatBuffer(StringBuffer buffer)
+ {
+ this.buffer = buffer;
+ this.ranges = new ArrayList();
+ this.attributes = new ArrayList();
+ this.defaultAttr = null;
+ if (buffer.length() != 0)
+ {
+ this.startingRange = buffer.length();
+ addAttribute(buffer.length(), null);
+ }
+ else
+ this.startingRange = -1;
+ }
+
+ public AttributedFormatBuffer(int prebuffer)
+ {
+ this(new StringBuffer(prebuffer));
+ }
+
+ public AttributedFormatBuffer()
+ {
+ this(10);
+ }
+
+ /**
+ * This method is a helper function for formatters. Given a set of ranges
+ * and attributes it adds exactly one attribute for the range of characters
+ * comprised between the last entry in 'ranges' and the specified new range.
+ *
+ * @param new_range A new range to insert in the list.
+ * @param new_attribute A new attribute to insert in the list.
+ */
+ private final void addAttribute(int new_range, AttributedCharacterIterator.Attribute attr)
+ {
+ HashMap map;
+
+ if (attr != null)
+ {
+ map = new HashMap();
+ map.put(attr, attr);
+ attributes.add(map);
+ }
+ else
+ attributes.add(null);
+
+ ranges.add(new Integer(new_range));
+ }
+
+ public void append(String s)
+ {
+ if (startingRange < 0)
+ startingRange = 0;
+ buffer.append(s);
+ }
+
+ public void append(String s, AttributedCharacterIterator.Attribute attr)
+ {
+ setDefaultAttribute(attr);
+ startingRange = buffer.length();
+ append(s);
+ setDefaultAttribute(null);
+ }
+
+ public void append(String s, int[] ranges, HashMap[] attrs)
+ {
+ int curPos = buffer.length();
+
+ setDefaultAttribute(null);
+ if (ranges != null)
+ {
+ for (int i = 0; i < ranges.length; i++)
+ {
+ this.ranges.add(new Integer(ranges[i] + curPos));
+ this.attributes.add(attrs[i]);
+ }
+ }
+ startingRange = buffer.length();
+ buffer.append(s);
+ }
+
+ public void append(char c)
+ {
+ if (startingRange < 0)
+ startingRange = buffer.length();
+ buffer.append(c);
+ }
+
+ public void append(char c, AttributedCharacterIterator.Attribute attr)
+ {
+ setDefaultAttribute(attr);
+ buffer.append(c);
+ setDefaultAttribute(null);
+ }
+
+ public void setDefaultAttribute(AttributedCharacterIterator.Attribute attr)
+ {
+ if (attr == defaultAttr)
+ return;
+
+ int currentPos = buffer.length();
+
+ if (startingRange != currentPos && startingRange >= 0)
+ {
+ addAttribute(currentPos, defaultAttr);
+ }
+ defaultAttr = attr;
+ startingRange = currentPos;
+ }
+
+ public AttributedCharacterIterator.Attribute getDefaultAttribute()
+ {
+ return defaultAttr;
+ }
+
+ public void cutTail(int length)
+ {
+ buffer.setLength(buffer.length()-length);
+ }
+
+ public int length()
+ {
+ return buffer.length();
+ }
+
+ public void clear()
+ {
+ buffer.setLength(0);
+ ranges.clear();
+ attributes.clear();
+ defaultAttr = null;
+ startingRange = -1;
+ }
+
+ /**
+ * This method synchronizes the state of the attribute array.
+ * After calling it you may call {@link #getDefaultAttribute()}.
+ */
+ public void sync()
+ {
+ if (startingRange < 0 || startingRange == buffer.length())
+ return;
+
+ addAttribute(buffer.length(), defaultAttr);
+
+ a_ranges = new int[ranges.size()];
+ for (int i = 0; i < a_ranges.length; i++)
+ a_ranges[i] = ((Integer)(ranges.get (i))).intValue();
+
+ a_attributes = new HashMap[attributes.size()];
+ System.arraycopy(attributes.toArray(), 0, a_attributes, 0, a_attributes.length);
+ }
+
+ /**
+ * This method returns the internal StringBuffer describing
+ * the attributed string.
+ *
+ * @return An instance of StringBuffer which contains the string.
+ */
+ public StringBuffer getBuffer()
+ {
+ return buffer;
+ }
+
+ /**
+ * This method returns the ranges for the attributes.
+ *
+ * @return An array of int describing the ranges.
+ */
+ public int[] getRanges()
+ {
+ return a_ranges;
+ }
+
+ /**
+ * This method returns the array containing the map on the
+ * attributes.
+ *
+ * @return An array of {@link java.util.Map} containing the attributes.
+ */
+ public HashMap[] getAttributes()
+ {
+ return a_attributes;
+ }
+}
diff --git a/libjava/gnu/java/text/CharacterBreakIterator.java b/libjava/gnu/java/text/CharacterBreakIterator.java
index 2febace8301..5d2036c3551 100644
--- a/libjava/gnu/java/text/CharacterBreakIterator.java
+++ b/libjava/gnu/java/text/CharacterBreakIterator.java
@@ -38,7 +38,6 @@ exception statement from your version. */
package gnu.java.text;
-import java.text.BreakIterator;
import java.text.CharacterIterator;
/**
@@ -161,7 +160,6 @@ public class CharacterBreakIterator extends BaseBreakIterator
if (iter.getIndex() == iter.getBeginIndex())
return DONE;
- int start = iter.getBeginIndex();
while (iter.getIndex() >= iter.getBeginIndex())
{
char c = iter.previous();
diff --git a/libjava/gnu/java/text/FormatBuffer.java b/libjava/gnu/java/text/FormatBuffer.java
new file mode 100644
index 00000000000..addfcbe5c1c
--- /dev/null
+++ b/libjava/gnu/java/text/FormatBuffer.java
@@ -0,0 +1,136 @@
+/* FormatBuffer.java -- General interface to build attributed strings.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+package gnu.java.text;
+
+import java.text.AttributedCharacterIterator;
+import java.util.HashMap;
+
+/**
+ * This interface describes a modifiable buffer which contains attributed
+ * characters. The implementation may or may not implements attributes. It
+ * aims to greatly simplify and clarify the implementation of java.text
+ * formatters. The buffer may be appended or have its tail cut. It may also
+ * be completely cleant up.
+ *
+ * @author Guilhem Lavaux <guilhem@kaffe.org>
+ * @date April 10, 2004
+ */
+public interface FormatBuffer
+{
+ /**
+ * This method appends a simple string to the buffer. This part of
+ * the buffer will be attributed using the default attribute.
+ *
+ * @param s The string to append to the buffer.
+ */
+ public void append(String s);
+
+ /**
+ * This method appends a simple string to the buffer. This part of
+ * the buffer will have the specified attribute (and only this one).
+ * The default attribute may be changed after calling this method.
+ *
+ * @param s The string to append to the buffer.
+ * @param attr Attribute to use for the string in the buffer.
+ */
+ public void append(String s, AttributedCharacterIterator.Attribute attr);
+
+ /**
+ * This method appends a simple string to the buffer. This part of
+ * the buffer will be attributed using the specified ranges and attributes.
+ * To have an example on how to specify ranges see {@link gnu.java.text.FormatCharacterIterator}.
+ *
+ * @param s The string to append to the buffer.
+ * @param ranges The ranges describing how the attributes should be applied
+ * to the string.
+ * @param attrs The attributes of the string in the buffer.
+ */
+ public void append(String s, int[] ranges, HashMap[] attrs);
+
+ /**
+ * This method appends a simple char to the buffer. This part of
+ * the buffer will be attributed using the default attribute.
+ *
+ * @param c The character to append to the buffer.
+ */
+ public void append(char c);
+
+ /**
+ * This method appends a simple character to the buffer. This part of
+ * the buffer will have the specified attribute (and only this one).
+ * The default attribute may be changed after calling this method.
+ *
+ * @param c The character to append to the buffer.
+ * @param attr Attribute to use for the character in the buffer.
+ */
+ public void append(char c, AttributedCharacterIterator.Attribute attr);
+
+ /**
+ * This method changes the current default attribute for the next string
+ * or character which will be appended to the buffer.
+ *
+ * @param attr The attribute which will be used by default.
+ */
+ public void setDefaultAttribute(AttributedCharacterIterator.Attribute attr);
+
+ /**
+ * This method returns the current default attribute for the buffer.
+ *
+ * @return The default attribute for the buffer.
+ */
+ public AttributedCharacterIterator.Attribute getDefaultAttribute();
+
+ /**
+ * This method cuts the last characters of the buffer. The number of
+ * characters to cut is given by "length".
+ *
+ * @param length Number of characters to cut at the end of the buffer.
+ */
+ public void cutTail(int length);
+
+ /**
+ * This method resets completely the buffer.
+ */
+ public void clear();
+
+ /**
+ * This method returns the number of character in the buffer.
+ *
+ * @return The number of character in the buffer.
+ */
+ public int length();
+}
diff --git a/libjava/gnu/java/text/FormatCharacterIterator.java b/libjava/gnu/java/text/FormatCharacterIterator.java
new file mode 100644
index 00000000000..116198bdc13
--- /dev/null
+++ b/libjava/gnu/java/text/FormatCharacterIterator.java
@@ -0,0 +1,534 @@
+/* FormatCharacter.java -- Implementation of AttributedCharacterIterator for
+ formatters.
+ Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+package gnu.java.text;
+
+import gnu.classpath.Configuration;
+
+import java.text.AttributedCharacterIterator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+/**
+ * This class should not be put public and it is only intended to the
+ * classes of the java.text package. Its aim is to build a segmented
+ * character iterator by appending strings and adding attributes to
+ * portions of strings. The code intends to do some optimization
+ * concerning memory consumption and attribute access but at the
+ * end it is only an AttributedCharacterIterator.
+ *
+ * @author Guilhem Lavaux <guilhem@kaffe.org>
+ * @date November 22, 2003
+ */
+public class FormatCharacterIterator implements AttributedCharacterIterator
+{
+ private String formattedString;
+ private int charIndex;
+ private int attributeIndex;
+ private int[] ranges;
+ private HashMap[] attributes;
+
+ /**
+ * This constructor builds an empty iterated strings. The attributes
+ * are empty and so is the string. However you may append strings
+ * and attributes to this iterator.
+ */
+ public FormatCharacterIterator()
+ {
+ formattedString = "";
+ ranges = new int[0];
+ attributes = new HashMap[0];
+ }
+
+ /**
+ * This constructor take a string <code>s</code>, a set of ranges
+ * and the corresponding attributes. This is used to build an iterator.
+ * The array <code>ranges</code> should be formatted as follow:
+ * each element of <code>ranges</code> specifies the index in the string
+ * until which the corresponding map of attributes at the same position
+ * is applied. For example, if you have:
+ * <pre>
+ * s = "hello";
+ * ranges = new int[] { 2, 6 };
+ * attributes = new HashMap[2];
+ * </pre>
+ * <code>"he"</code> will have the attributes <code>attributes[0]</code>,
+ * <code>"llo"</code> the <code>attributes[1]</code>.
+ */
+ public FormatCharacterIterator (String s, int[] ranges, HashMap[] attributes)
+ {
+ formattedString = s;
+ this.ranges = ranges;
+ this.attributes = attributes;
+ }
+
+ /*
+ * The following methods are inherited from AttributedCharacterIterator,
+ * and thus are already documented.
+ */
+
+ public Set getAllAttributeKeys()
+ {
+ if (attributes != null && attributes[attributeIndex] != null)
+ return attributes[attributeIndex].keySet();
+ else
+ return new HashSet();
+ }
+
+ public Map getAttributes()
+ {
+ if (attributes != null && attributes[attributeIndex] != null)
+ return attributes[attributeIndex];
+ else
+ return new HashMap();
+ }
+
+ public Object getAttribute (AttributedCharacterIterator.Attribute attrib)
+ {
+ if (attributes != null && attributes[attributeIndex] != null)
+ return attributes[attributeIndex].get (attrib);
+ else
+ return null;
+ }
+
+ public int getRunLimit(Set reqAttrs)
+ {
+ if (attributes == null)
+ return formattedString.length();
+
+ int currentAttrIndex = attributeIndex;
+ Set newKeys;
+
+ do
+ {
+ currentAttrIndex++;
+ if (currentAttrIndex == attributes.length)
+ return formattedString.length();
+ if (attributes[currentAttrIndex] == null)
+ break;
+ newKeys = attributes[currentAttrIndex].keySet();
+ }
+ while (newKeys.containsAll (reqAttrs));
+
+ return ranges[currentAttrIndex-1];
+ }
+
+ public int getRunLimit (AttributedCharacterIterator.Attribute attribute)
+ {
+ Set s = new HashSet();
+
+ s.add (attribute);
+ return getRunLimit (s);
+ }
+
+ public int getRunLimit()
+ {
+ if (attributes == null)
+ return formattedString.length();
+ if (attributes[attributeIndex] == null)
+ {
+ for (int i=attributeIndex+1;i<attributes.length;i++)
+ if (attributes[i] != null)
+ return ranges[i-1];
+ return formattedString.length();
+ }
+
+ return getRunLimit (attributes[attributeIndex].keySet());
+ }
+
+ public int getRunStart (Set reqAttrs)
+ {
+ if (attributes == null)
+ return formattedString.length();
+
+ int currentAttrIndex = attributeIndex;
+ Set newKeys = null;
+
+ do
+ {
+ if (currentAttrIndex == 0)
+ return 0;
+
+ currentAttrIndex--;
+ if (attributes[currentAttrIndex] == null)
+ break;
+ newKeys = attributes[currentAttrIndex].keySet();
+ }
+ while (newKeys.containsAll (reqAttrs));
+
+ return (currentAttrIndex > 0) ? ranges[currentAttrIndex-1] : 0;
+ }
+
+ public int getRunStart()
+ {
+ if (attributes == null)
+ return 0;
+
+ if (attributes[attributeIndex] == null)
+ {
+ for (int i=attributeIndex;i>0;i--)
+ if (attributes[i] != null)
+ return ranges[attributeIndex-1];
+ return 0;
+ }
+
+ return getRunStart (attributes[attributeIndex].keySet());
+ }
+
+ public int getRunStart (AttributedCharacterIterator.Attribute attribute)
+ {
+ Set s = new HashSet();
+
+ s.add (attribute);
+ return getRunStart (s);
+ }
+
+ public Object clone()
+ {
+ return new FormatCharacterIterator (formattedString, ranges, attributes);
+ }
+
+ /*
+ * The following methods are inherited from CharacterIterator and thus
+ * are already documented.
+ */
+
+ public char current()
+ {
+ return formattedString.charAt (charIndex);
+ }
+
+ public char first()
+ {
+ charIndex = 0;
+ attributeIndex = 0;
+ return formattedString.charAt (0);
+ }
+
+ public int getBeginIndex()
+ {
+ return 0;
+ }
+
+ public int getEndIndex()
+ {
+ return formattedString.length();
+ }
+
+ public int getIndex()
+ {
+ return charIndex;
+ }
+
+ public char last()
+ {
+ charIndex = formattedString.length()-1;
+ if (attributes != null)
+ attributeIndex = attributes.length-1;
+ return formattedString.charAt (charIndex);
+ }
+
+ public char next()
+ {
+ charIndex++;
+ if (charIndex >= formattedString.length())
+ {
+ charIndex = getEndIndex();
+ return DONE;
+ }
+ if (attributes != null)
+ {
+ if (charIndex >= ranges[attributeIndex])
+ attributeIndex++;
+ }
+ return formattedString.charAt (charIndex);
+ }
+
+ public char previous()
+ {
+ charIndex--;
+ if (charIndex < 0)
+ {
+ charIndex = 0;
+ return DONE;
+ }
+
+ if (attributes != null)
+ {
+ if (charIndex < ranges[attributeIndex])
+ attributeIndex--;
+ }
+ return formattedString.charAt (charIndex);
+ }
+
+ public char setIndex (int position)
+ {
+ if (position < 0 || position > formattedString.length())
+ throw new IllegalArgumentException ("position is out of range");
+
+ charIndex = position;
+ if (attributes != null)
+ {
+ for (attributeIndex=0;attributeIndex<attributes.length;
+ attributeIndex++)
+ if (ranges[attributeIndex] > charIndex)
+ break;
+ attributeIndex--;
+ }
+ if (charIndex == formattedString.length())
+ return DONE;
+ else
+ return formattedString.charAt (charIndex);
+ }
+
+ /**
+ * This method merge the specified attributes and ranges with the
+ * internal tables. This method is in charge of the optimization
+ * of tables. Two following sets of attributes are never the same.
+ *
+ * @see #FormatCharacterIterator()
+ *
+ * @param attributes the new array attributes to apply to the string.
+ */
+ public void mergeAttributes (HashMap[] attributes, int[] ranges)
+ {
+ Vector new_ranges = new Vector();
+ Vector new_attributes = new Vector();
+ int i = 0, j = 0;
+
+ debug("merging " + attributes.length + " attrs");
+
+ while (i < this.ranges.length && j < ranges.length)
+ {
+ if (this.attributes[i] != null)
+ {
+ new_attributes.add (this.attributes[i]);
+ if (attributes[j] != null)
+ this.attributes[i].putAll (attributes[j]);
+ }
+ else
+ {
+ new_attributes.add (attributes[j]);
+ }
+ if (this.ranges[i] == ranges[j])
+ {
+ new_ranges.add (new Integer (ranges[j]));
+ i++;
+ j++;
+ }
+ else if (this.ranges[i] < ranges[j])
+ {
+ new_ranges.add (new Integer (this.ranges[i]));
+ i++;
+ }
+ else
+ {
+ new_ranges.add (new Integer (ranges[j]));
+ j++;
+ }
+ }
+
+ if (i != this.ranges.length)
+ {
+ for (;i<this.ranges.length;i++)
+ {
+ new_attributes.add (this.attributes[i]);
+ new_ranges.add (new Integer (this.ranges[i]));
+ }
+ }
+ if (j != ranges.length)
+ {
+ for (;j<ranges.length;j++)
+ {
+ new_attributes.add (attributes[j]);
+ new_ranges.add (new Integer (ranges[j]));
+ }
+ }
+
+ this.attributes = new HashMap[new_attributes.size()];
+ this.ranges = new int[new_ranges.size()];
+ System.arraycopy (new_attributes.toArray(), 0, this.attributes,
+ 0, this.attributes.length);
+
+ for (i=0;i<new_ranges.size();i++)
+ {
+ this.ranges[i] = ((Integer)new_ranges.elementAt (i)).intValue();
+ }
+
+ dumpTable();
+ }
+
+ /**
+ * This method appends to the internal attributed string the attributed
+ * string contained in the specified iterator.
+ *
+ * @param iterator the iterator which contains the attributed string to
+ * append to this iterator.
+ */
+ public void append (AttributedCharacterIterator iterator)
+ {
+ char c = iterator.first();
+ Vector more_ranges = new Vector();
+ Vector more_attributes = new Vector();
+
+ do
+ {
+ formattedString = formattedString + String.valueOf (c);
+ // TODO: Reduce the size of the output array.
+ more_attributes.add (iterator.getAttributes());
+ more_ranges.add (new Integer (formattedString.length()));
+ // END TOOD
+ c = iterator.next();
+ }
+ while (c != DONE);
+
+ HashMap[] new_attributes = new HashMap[attributes.length
+ + more_attributes.size()];
+ int[] new_ranges = new int[ranges.length + more_ranges.size()];
+
+ System.arraycopy (attributes, 0, new_attributes, 0, attributes.length);
+ System.arraycopy (more_attributes.toArray(), 0, new_attributes,
+ attributes.length, more_attributes.size());
+
+ System.arraycopy (ranges, 0, new_ranges, 0, ranges.length);
+ Object[] new_ranges_array = more_ranges.toArray();
+ for (int i = 0; i < more_ranges.size();i++)
+ new_ranges[i+ranges.length] = ((Integer) new_ranges_array[i]).intValue();
+
+ attributes = new_attributes;
+ ranges = new_ranges;
+ }
+
+ /**
+ * This method appends an attributed string which attributes are specified
+ * directly in the calling parameters.
+ *
+ * @param text The string to append.
+ * @param local_attributes The attributes to put on this string in the
+ * iterator. If it is <code>null</code> the string will simply have no
+ * attributes.
+ */
+ public void append (String text, HashMap local_attributes)
+ {
+ int[] new_ranges = new int[ranges.length+1];
+ HashMap[] new_attributes = new HashMap[attributes.length+1];
+
+ formattedString += text;
+ System.arraycopy (attributes, 0, new_attributes, 0, attributes.length);
+ System.arraycopy (ranges, 0, new_ranges, 0, ranges.length);
+ new_ranges[ranges.length] = formattedString.length();
+ new_attributes[attributes.length] = local_attributes;
+
+ ranges = new_ranges;
+ attributes = new_attributes;
+ }
+
+ /**
+ * This method appends a string without attributes. It is completely
+ * equivalent to call {@link #append(String,HashMap)} with local_attributes
+ * equal to <code>null</code>.
+ *
+ * @param text The string to append to the iterator.
+ */
+ public void append (String text)
+ {
+ append (text, null);
+ }
+
+ /**
+ * This method adds a set of attributes to a range of character. The
+ * bounds are always inclusive. In the case many attributes have to
+ * be added it is advised to directly use {@link #mergeAttributes([Ljava.util.HashMap;[I}
+ *
+ * @param attributes Attributes to merge into the iterator.
+ * @param range_start Lower bound of the range of characters which will receive the
+ * attribute.
+ * @param range_end Upper bound of the range of characters which will receive the
+ * attribute.
+ *
+ * @throws IllegalArgumentException if ranges are out of bounds.
+ */
+ public void addAttributes(HashMap attributes, int range_start, int range_end)
+ {
+ if (range_start == 0)
+ mergeAttributes(new HashMap[] { attributes }, new int[] { range_end });
+ else
+ mergeAttributes(new HashMap[] { null, attributes }, new int[] { range_start, range_end });
+ }
+
+ final private void debug(String s)
+ {
+ if (Configuration.DEBUG)
+ System.out.println(s);
+ }
+
+ final private void dumpTable()
+ {
+ int start_range = 0;
+
+ if (!Configuration.DEBUG)
+ return;
+
+ System.out.println("Dumping internal table:");
+ for (int i = 0; i < ranges.length; i++)
+ {
+ System.out.print("\t" + start_range + " => " + ranges[i] + ":");
+ if (attributes[i] == null)
+ System.out.println("null");
+ else
+ {
+ Set keyset = attributes[i].keySet();
+ if (keyset != null)
+ {
+ Iterator keys = keyset.iterator();
+
+ while (keys.hasNext())
+ System.out.print(" " + keys.next());
+ }
+ else
+ System.out.println("keySet null");
+ System.out.println();
+ }
+ }
+ System.out.println();
+ System.out.flush();
+ }
+}
diff --git a/libjava/gnu/java/text/LineBreakIterator.java b/libjava/gnu/java/text/LineBreakIterator.java
index 59c45d7bdca..e1cb49c7d56 100644
--- a/libjava/gnu/java/text/LineBreakIterator.java
+++ b/libjava/gnu/java/text/LineBreakIterator.java
@@ -38,7 +38,6 @@ exception statement from your version. */
package gnu.java.text;
-import java.text.BreakIterator;
import java.text.CharacterIterator;
/**
diff --git a/libjava/gnu/java/text/SentenceBreakIterator.java b/libjava/gnu/java/text/SentenceBreakIterator.java
index 62b99f0fbf8..405bbc5408d 100644
--- a/libjava/gnu/java/text/SentenceBreakIterator.java
+++ b/libjava/gnu/java/text/SentenceBreakIterator.java
@@ -38,7 +38,6 @@ exception statement from your version. */
package gnu.java.text;
-import java.text.BreakIterator;
import java.text.CharacterIterator;
/**
diff --git a/libjava/gnu/java/text/StringFormatBuffer.java b/libjava/gnu/java/text/StringFormatBuffer.java
new file mode 100644
index 00000000000..ec0ed86417e
--- /dev/null
+++ b/libjava/gnu/java/text/StringFormatBuffer.java
@@ -0,0 +1,121 @@
+/* StringFormatBuffer.java -- Implements FormatBuffer using StringBuffer.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+package gnu.java.text;
+
+import java.text.AttributedCharacterIterator;
+import java.util.HashMap;
+
+/**
+ * This class is an implementation of a FormatBuffer without attributes.
+ *
+ * @author Guilhem Lavaux <guilhem@kaffe.org>
+ * @date April 10, 2004
+ */
+public class StringFormatBuffer implements FormatBuffer
+{
+ private StringBuffer buffer;
+ private AttributedCharacterIterator.Attribute defaultAttr;
+
+ public StringFormatBuffer(int prebuffer)
+ {
+ buffer = new StringBuffer(prebuffer);
+ }
+
+ public StringFormatBuffer(StringBuffer buffer)
+ {
+ this.buffer = buffer;
+ }
+
+ public void append(String s)
+ {
+ buffer.append(s);
+ }
+
+ public void append(String s, AttributedCharacterIterator.Attribute attr)
+ {
+ buffer.append(s);
+ }
+
+ public void append(String s, int[] ranges, HashMap[] attrs)
+ {
+ buffer.append(s);
+ }
+
+ public void append(char c)
+ {
+ buffer.append(c);
+ }
+
+ public void append(char c, AttributedCharacterIterator.Attribute attr)
+ {
+ buffer.append(c);
+ }
+
+ public void setDefaultAttribute(AttributedCharacterIterator.Attribute attr)
+ {
+ defaultAttr = attr;
+ }
+
+ public AttributedCharacterIterator.Attribute getDefaultAttribute()
+ {
+ return defaultAttr;
+ }
+
+ public void cutTail(int length)
+ {
+ buffer.setLength(buffer.length()-length);
+ }
+
+ public int length()
+ {
+ return buffer.length();
+ }
+
+ public void clear()
+ {
+ buffer.setLength(0);
+ }
+
+ /**
+ * This method returns the internal {@link java.lang.StringBuffer} which
+ * contains the string of character.
+ */
+ public StringBuffer getBuffer()
+ {
+ return buffer;
+ }
+}
diff --git a/libjava/gnu/java/text/WordBreakIterator.java b/libjava/gnu/java/text/WordBreakIterator.java
index 3b6aae8c854..39dbefe6e50 100644
--- a/libjava/gnu/java/text/WordBreakIterator.java
+++ b/libjava/gnu/java/text/WordBreakIterator.java
@@ -38,7 +38,6 @@ exception statement from your version. */
package gnu.java.text;
-import java.text.BreakIterator;
import java.text.CharacterIterator;
/**
diff --git a/libjava/gnu/java/util/DoubleEnumeration.java b/libjava/gnu/java/util/DoubleEnumeration.java
index fd033a356f8..21eb605e792 100644
--- a/libjava/gnu/java/util/DoubleEnumeration.java
+++ b/libjava/gnu/java/util/DoubleEnumeration.java
@@ -37,7 +37,6 @@ exception statement from your version. */
package gnu.java.util;
-import java.io.*;
import java.util.Enumeration;
import java.util.NoSuchElementException;
diff --git a/libjava/gnu/java/util/prefs/NodeReader.java b/libjava/gnu/java/util/prefs/NodeReader.java
index 6c9fdc9ec06..e343b6b2b5c 100644
--- a/libjava/gnu/java/util/prefs/NodeReader.java
+++ b/libjava/gnu/java/util/prefs/NodeReader.java
@@ -38,13 +38,13 @@ exception statement from your version. */
package gnu.java.util.prefs;
import java.io.BufferedReader;
+import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.io.InputStream;
-import java.io.IOException;
import java.io.Reader;
-
-import java.util.prefs.*;
+import java.util.prefs.InvalidPreferencesFormatException;
+import java.util.prefs.Preferences;
+import java.util.prefs.PreferencesFactory;
/**
* Reads and imports preferences nodes from files.
diff --git a/libjava/gnu/javax/rmi/CORBA/DelegateFactory.java b/libjava/gnu/javax/rmi/CORBA/DelegateFactory.java
index bf6f9e64c01..63c7d5a5d48 100644
--- a/libjava/gnu/javax/rmi/CORBA/DelegateFactory.java
+++ b/libjava/gnu/javax/rmi/CORBA/DelegateFactory.java
@@ -54,23 +54,33 @@ public class DelegateFactory
String dcname = System.getProperty("javax.rmi.CORBA." + type + "Class");
if (dcname == null)
{
- //throw new DelegateException
- // ("no javax.rmi.CORBA.XXXClass property sepcified.");
- dcname = "gnu.javax.rmi.CORBA." + type + "DelegateImpl";
+ //throw new DelegateException
+ // ("no javax.rmi.CORBA.XXXClass property sepcified.");
+ dcname = "gnu.javax.rmi.CORBA." + type + "DelegateImpl";
}
try
{
- Class dclass = Class.forName(dcname,
- true,
- Thread.currentThread().getContextClassLoader());
- r = dclass.newInstance();
- cache.put(type, r);
- return r;
+ Class dclass;
+ try
+ {
+ dclass = Class.forName(dcname);
+ }
+ catch (ClassNotFoundException c)
+ {
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ if (loader != null)
+ dclass = Class.forName(dcname, true, loader);
+ else
+ throw c;
+ }
+ r = dclass.newInstance();
+ cache.put(type, r);
+ return r;
}
catch(Exception e)
{
- throw new GetDelegateInstanceException
- ("Exception when trying to get delegate instance:" + dcname, e);
+ throw new GetDelegateInstanceException
+ ("Exception when trying to get delegate instance:" + dcname, e);
}
}
}
diff --git a/libjava/include/Makefile.in b/libjava/include/Makefile.in
index e1e0955509a..8ac15bbf292 100644
--- a/libjava/include/Makefile.in
+++ b/libjava/include/Makefile.in
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
-# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -241,7 +241,7 @@ TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP)
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \
- || (cd $(srcdir) && etags -o $$here/TAGS $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP))
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS)
mostlyclean-tags:
diff --git a/libjava/include/execution.h b/libjava/include/execution.h
new file mode 100644
index 00000000000..9366c350a86
--- /dev/null
+++ b/libjava/include/execution.h
@@ -0,0 +1,140 @@
+// execution.h - Execution engines. -*- c++ -*-
+
+/* Copyright (C) 2004 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#ifndef __JAVA_EXECUTION_H__
+#define __JAVA_EXECUTION_H__
+
+// This represents one execution engine. Note that we use function
+// pointers and not virtual methods to avoid calls to
+// __cxa_call_unexpected and the like.
+struct _Jv_ExecutionEngine
+{
+ public:
+
+ void (*unregister) (jclass);
+ // FIXME: probably should handle this elsewhere, see how
+ // interpreter does it.
+ bool (*need_resolve_string_fields) ();
+ void (*verify) (jclass);
+ void (*allocate_static_fields) (jclass, int);
+ void (*create_ncode) (jclass);
+ _Jv_ResolvedMethod *(*resolve_method) (_Jv_Method *, jclass,
+ jboolean, jint);
+};
+
+// This handles all gcj-compiled code, including BC ABI.
+struct _Jv_CompiledEngine : public _Jv_ExecutionEngine
+{
+ public:
+
+ static void do_unregister (jclass)
+ {
+ }
+
+ static bool do_need_resolve_string_fields ()
+ {
+ return true;
+ }
+
+ static void do_verify (jclass klass)
+ {
+ if (klass->verify)
+ {
+ klass->verify(klass->getClassLoaderInternal());
+ klass->verify = NULL;
+ }
+ }
+
+ static _Jv_ResolvedMethod *do_resolve_method (_Jv_Method *, jclass,
+ jboolean, jint)
+ {
+ return NULL;
+ }
+
+ static void do_allocate_static_fields (jclass, int)
+ {
+ // Compiled classes don't need this.
+ }
+
+ static void do_create_ncode (jclass)
+ {
+ // Not needed.
+ }
+
+ _Jv_CompiledEngine ()
+ {
+ unregister = do_unregister;
+ need_resolve_string_fields = do_need_resolve_string_fields;
+ verify = do_verify;
+ allocate_static_fields = do_allocate_static_fields;
+ create_ncode = do_create_ncode;
+ resolve_method = do_resolve_method;
+ }
+
+ // These operators make it so we don't have to link in libstdc++.
+ void *operator new (size_t bytes)
+ {
+ return _Jv_Malloc(bytes);
+ }
+
+ void operator delete (void *mem)
+ {
+ _Jv_Free(mem);
+ }
+};
+
+// This handles interpreted code.
+class _Jv_InterpreterEngine : public _Jv_ExecutionEngine
+{
+ public:
+
+ static void do_verify (jclass);
+ static void do_allocate_static_fields (jclass, int);
+ static void do_create_ncode (jclass);
+ static _Jv_ResolvedMethod *do_resolve_method (_Jv_Method *, jclass,
+ jboolean, jint);
+
+ static bool do_need_resolve_string_fields ()
+ {
+ return false;
+ }
+
+ static void do_unregister(jclass klass)
+ {
+ _Jv_UnregisterClass(klass);
+ }
+
+ _Jv_InterpreterEngine ()
+ {
+ unregister = do_unregister;
+ need_resolve_string_fields = do_need_resolve_string_fields;
+ verify = do_verify;
+ allocate_static_fields = do_allocate_static_fields;
+ create_ncode = do_create_ncode;
+ resolve_method = do_resolve_method;
+ }
+
+ // These operators make it so we don't have to link in libstdc++.
+ void *operator new (size_t bytes)
+ {
+ return _Jv_Malloc(bytes);
+ }
+
+ void operator delete (void *mem)
+ {
+ _Jv_Free(mem);
+ }
+};
+
+
+extern _Jv_InterpreterEngine _Jv_soleInterpreterEngine;
+extern _Jv_CompiledEngine _Jv_soleCompiledEngine;
+
+#endif // __JAVA_EXECUTION_H__
diff --git a/libjava/include/java-interp.h b/libjava/include/java-interp.h
index 94acfae281f..85a78c05334 100644
--- a/libjava/include/java-interp.h
+++ b/libjava/include/java-interp.h
@@ -1,6 +1,6 @@
// java-interp.h - Header file for the bytecode interpreter. -*- c++ -*-
-/* Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
This file is part of libgcj.
@@ -22,7 +22,6 @@ details. */
#include <java/lang/Class.h>
#include <java/lang/ClassLoader.h>
#include <java/lang/reflect/Modifier.h>
-#include <gnu/gcj/runtime/StackTrace.h>
extern "C" {
#include <ffi.h>
@@ -80,7 +79,7 @@ class _Jv_MethodBase
{
protected:
// The class which defined this method.
- _Jv_InterpClass *defining_class;
+ jclass defining_class;
// The method description.
_Jv_Method *self;
@@ -88,11 +87,7 @@ protected:
// Size of raw arguments.
_Jv_ushort args_raw_size;
- // Chain of addresses to fill in. See _Jv_Defer_Resolution.
- void *deferred;
-
- friend void _Jv_Defer_Resolution (void *cl, _Jv_Method *meth, void **);
- friend void _Jv_PrepareClass(jclass);
+ friend class _Jv_InterpreterEngine;
public:
_Jv_Method *get_method ()
@@ -150,22 +145,22 @@ class _Jv_InterpMethod : public _Jv_MethodBase
friend class _Jv_BytecodeVerifier;
friend class gnu::gcj::runtime::NameFinder;
friend class gnu::gcj::runtime::StackTrace;
-
- friend void _Jv_PrepareClass(jclass);
+ friend class _Jv_InterpreterEngine;
+
#ifdef JV_MARKOBJ_DECL
friend JV_MARKOBJ_DECL;
#endif
};
-class _Jv_InterpClass : public java::lang::Class
+class _Jv_InterpClass
{
_Jv_MethodBase **interpreted_methods;
_Jv_ushort *field_initializers;
friend class _Jv_ClassReader;
friend class _Jv_InterpMethod;
- friend void _Jv_PrepareClass(jclass);
+ friend class _Jv_InterpreterEngine;
friend void _Jv_PrepareMissingMethods (jclass base2, jclass iface_class);
friend void _Jv_InitField (jobject, jclass, int);
#ifdef JV_MARKOBJ_DECL
@@ -173,33 +168,8 @@ class _Jv_InterpClass : public java::lang::Class
#endif
friend _Jv_MethodBase ** _Jv_GetFirstMethod (_Jv_InterpClass *klass);
- friend void _Jv_Defer_Resolution (void *cl, _Jv_Method *meth, void **);
};
-// We have an interpreted class CL and we're trying to find the
-// address of the ncode of a method METH. That interpreted class
-// hasn't yet been prepared, so we defer fixups until they are ready.
-// To do this, we create a chain of fixups that will be resolved by
-// _Jv_PrepareClass.
-extern inline void
-_Jv_Defer_Resolution (void *cl, _Jv_Method *meth, void **address)
-{
- int i;
- _Jv_InterpClass *self = (_Jv_InterpClass *)cl;
- for (i = 0; i < self->method_count; i++)
- {
- _Jv_Method *m = &self->methods[i];
- if (m == meth)
- {
- _Jv_MethodBase *imeth = self->interpreted_methods[i];
- *address = imeth->deferred;
- imeth->deferred = address;
- return;
- }
- }
- return;
-}
-
extern inline _Jv_MethodBase **
_Jv_GetFirstMethod (_Jv_InterpClass *klass)
{
@@ -237,7 +207,11 @@ class _Jv_JNIMethod : public _Jv_MethodBase
void *ncode ();
friend class _Jv_ClassReader;
- friend void _Jv_PrepareClass(jclass);
+ friend class _Jv_InterpreterEngine;
+
+#ifdef JV_MARKOBJ_DECL
+ friend JV_MARKOBJ_DECL;
+#endif
public:
// FIXME: this is ugly.
diff --git a/libjava/include/jni.h b/libjava/include/jni.h
index 4e39e646f51..51fa7cbe1f6 100644
--- a/libjava/include/jni.h
+++ b/libjava/include/jni.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation
This file is part of libgcj.
@@ -240,12 +240,6 @@ typedef union jvalue
jobject l;
} jvalue;
-#ifdef __cplusplus
-typedef void * (*_Jv_func) (...);
-#else
-typedef void * (*_Jv_func) ();
-#endif
-
/* This structure is used when registering native methods. */
typedef struct
{
@@ -256,10 +250,10 @@ typedef struct
struct JNINativeInterface
{
- _Jv_func reserved0;
- _Jv_func reserved1;
- _Jv_func reserved2;
- _Jv_func reserved3;
+ void *reserved0;
+ void *reserved1;
+ void *reserved2;
+ void *reserved3;
jint (JNICALL *GetVersion) (JNIEnv *);
jclass (JNICALL *DefineClass) (JNIEnv *, const char *,
@@ -1574,9 +1568,9 @@ public:
struct JNIInvokeInterface
{
- _Jv_func reserved0;
- _Jv_func reserved1;
- _Jv_func reserved2;
+ void *reserved0;
+ void *reserved1;
+ void *reserved2;
jint (JNICALL *DestroyJavaVM) (JavaVM *);
jint (JNICALL *AttachCurrentThread) (JavaVM *, void **, void *);
diff --git a/libjava/include/jvm.h b/libjava/include/jvm.h
index ee7792b0788..f45ed34d264 100644
--- a/libjava/include/jvm.h
+++ b/libjava/include/jvm.h
@@ -1,6 +1,6 @@
// jvm.h - Header file for private implementation information. -*- c++ -*-
-/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
This file is part of libgcj.
@@ -225,9 +225,6 @@ inline _Jv_TempUTFString::~_Jv_TempUTFString ()
char utfstr##_buf[utfstr##_len <= 256 ? utfstr##_len : 0]; \
_Jv_TempUTFString utfstr(utfstr##thejstr, sizeof(utfstr##_buf)==0 ? 0 : utfstr##_buf)
-// FIXME: remove this define.
-#define StringClass java::lang::String::class$
-
namespace gcj
{
/* Some constants used during lookup of special class methods. */
@@ -240,6 +237,38 @@ namespace gcj
extern bool runtimeInitialized;
}
+// This class handles all aspects of class preparation and linking.
+class _Jv_Linker
+{
+private:
+ static void prepare_constant_time_tables(jclass);
+ static jshort get_interfaces(jclass, _Jv_ifaces *);
+ static void link_symbol_table(jclass);
+ static void link_exception_table(jclass);
+ static void layout_interface_methods(jclass);
+ static void layout_vtable_methods(jclass);
+ static void set_vtable_entries(jclass, _Jv_VTable *, jboolean *);
+ static void make_vtable(jclass);
+ static void ensure_fields_laid_out(jclass);
+ static void ensure_class_linked(jclass);
+ static void ensure_supers_installed(jclass);
+ static void add_miranda_methods(jclass, jclass);
+ static void ensure_method_table_complete(jclass);
+ static void verify_class(jclass);
+ static jshort find_iindex(jclass *, jshort *, jshort);
+ static jshort indexof(void *, void **, jshort);
+ static int get_alignment_from_class(jclass);
+ static void generate_itable(jclass, _Jv_ifaces *, jshort *);
+ static jshort append_partial_itable(jclass, jclass, void **, jshort);
+
+public:
+
+ static void resolve_class_ref (jclass, jclass *);
+ static void wait_for_state(jclass, int);
+ static _Jv_word resolve_pool_entry (jclass, int);
+ static void resolve_field (_Jv_Field *, java::lang::ClassLoader *);
+};
+
/* Type of pointer used as finalizer. */
typedef void _Jv_FinalizerFunc (jobject);
@@ -401,11 +430,12 @@ extern "C" void *_Jv_LookupInterfaceMethod (jclass klass, Utf8Const *name,
extern "C" void *_Jv_LookupInterfaceMethodIdx (jclass klass, jclass iface,
int meth_idx);
extern "C" void _Jv_CheckArrayStore (jobject array, jobject obj);
+extern "C" void _Jv_CheckAssignment (java::lang::ClassLoader *,
+ _Jv_Utf8Const *, _Jv_Utf8Const *);
extern "C" void _Jv_RegisterClass (jclass klass);
extern "C" void _Jv_RegisterClasses (jclass *classes);
extern "C" void _Jv_RegisterResource (void *vptr);
extern void _Jv_UnregisterClass (_Jv_Utf8Const*, java::lang::ClassLoader*);
-extern void _Jv_ResolveField (_Jv_Field *, java::lang::ClassLoader*);
extern jclass _Jv_FindClass (_Jv_Utf8Const *name,
java::lang::ClassLoader *loader);
@@ -422,7 +452,8 @@ extern jboolean _Jv_CheckAccess (jclass self_klass, jclass other_klass,
extern jobject _Jv_CallAnyMethodA (jobject obj, jclass return_type,
jmethodID meth, jboolean is_constructor,
JArray<jclass> *parameter_types,
- jobjectArray args);
+ jobjectArray args,
+ jclass iface = NULL);
union jvalue;
extern void _Jv_CallAnyMethodA (jobject obj,
@@ -433,7 +464,8 @@ extern void _Jv_CallAnyMethodA (jobject obj,
JArray<jclass> *parameter_types,
jvalue *args,
jvalue *result,
- jboolean is_jni_call = true);
+ jboolean is_jni_call = true,
+ jclass iface = NULL);
extern jobject _Jv_NewMultiArray (jclass, jint ndims, jint* dims)
__attribute__((__malloc__));
diff --git a/libjava/interpret.cc b/libjava/interpret.cc
index 5fd2c2b5869..91c49e6097a 100644
--- a/libjava/interpret.cc
+++ b/libjava/interpret.cc
@@ -1,6 +1,6 @@
// interpret.cc - Code for the interpreter
-/* Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
This file is part of libgcj.
@@ -11,6 +11,7 @@ details. */
/* Author: Kresten Krab Thorup <krab@gnu.org> */
#include <config.h>
+#include <platform.h>
// Define this to get the direct-threaded interpreter. If undefined,
// we revert to a basic bytecode interpreter. The former is faster
@@ -38,9 +39,15 @@ details. */
#include <java/lang/Thread.h>
#include <java-insns.h>
#include <java-signal.h>
+#include <java/lang/ClassFormatError.h>
+#include <execution.h>
+#include <java/lang/reflect/Modifier.h>
#ifdef INTERPRETER
+// Execution engine for interpreted code.
+_Jv_InterpreterEngine _Jv_soleInterpreterEngine;
+
#include <stdlib.h>
using namespace gcj;
@@ -54,6 +61,11 @@ static void throw_null_pointer_exception ()
__attribute__ ((__noreturn__));
#endif
+static void throw_class_format_error (jstring msg)
+ __attribute__ ((__noreturn__));
+static void throw_class_format_error (char *msg)
+ __attribute__ ((__noreturn__));
+
extern "C" double __ieee754_fmod (double,double);
// This represents a single slot in the "compiled" form of the
@@ -750,8 +762,9 @@ _Jv_InterpMethod::compile (const void * const *insn_targets)
exc[i].start_pc.p = &insns[pc_mapping[exc[i].start_pc.i]];
exc[i].end_pc.p = &insns[pc_mapping[exc[i].end_pc.i]];
exc[i].handler_pc.p = &insns[pc_mapping[exc[i].handler_pc.i]];
- jclass handler = (_Jv_ResolvePoolEntry (defining_class,
- exc[i].handler_type.i)).clazz;
+ jclass handler
+ = (_Jv_Linker::resolve_pool_entry (defining_class,
+ exc[i].handler_type.i)).clazz;
exc[i].handler_type.p = handler;
}
@@ -1086,13 +1099,14 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
{
int index = GET2U ();
- /* _Jv_ResolvePoolEntry returns immediately if the value already
- * is resolved. If we want to clutter up the code here to gain
- * a little performance, then we can check the corresponding bit
- * JV_CONSTANT_ResolvedFlag in the tag directly. For now, I
- * don't think it is worth it. */
+ /* _Jv_Linker::resolve_pool_entry returns immediately if the
+ * value already is resolved. If we want to clutter up the
+ * code here to gain a little performance, then we can check
+ * the corresponding bit JV_CONSTANT_ResolvedFlag in the tag
+ * directly. For now, I don't think it is worth it. */
- rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
+ rmeth = (_Jv_Linker::resolve_pool_entry (defining_class,
+ index)).rmethod;
sp -= rmeth->stack_item_count;
// We don't use NULLCHECK here because we can't rely on that
@@ -2391,7 +2405,7 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
insn_getstatic:
{
jint fieldref_index = GET2U ();
- _Jv_ResolvePoolEntry (defining_class, fieldref_index);
+ _Jv_Linker::resolve_pool_entry (defining_class, fieldref_index);
_Jv_Field *field = pool_data[fieldref_index].field;
if ((field->flags & Modifier::STATIC) == 0)
@@ -2478,7 +2492,7 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
insn_getfield:
{
jint fieldref_index = GET2U ();
- _Jv_ResolvePoolEntry (defining_class, fieldref_index);
+ _Jv_Linker::resolve_pool_entry (defining_class, fieldref_index);
_Jv_Field *field = pool_data[fieldref_index].field;
if ((field->flags & Modifier::STATIC) != 0)
@@ -2593,7 +2607,7 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
insn_putstatic:
{
jint fieldref_index = GET2U ();
- _Jv_ResolvePoolEntry (defining_class, fieldref_index);
+ _Jv_Linker::resolve_pool_entry (defining_class, fieldref_index);
_Jv_Field *field = pool_data[fieldref_index].field;
jclass type = field->type;
@@ -2680,7 +2694,7 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
insn_putfield:
{
jint fieldref_index = GET2U ();
- _Jv_ResolvePoolEntry (defining_class, fieldref_index);
+ _Jv_Linker::resolve_pool_entry (defining_class, fieldref_index);
_Jv_Field *field = pool_data[fieldref_index].field;
jclass type = field->type;
@@ -2806,7 +2820,8 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
{
int index = GET2U ();
- rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
+ rmeth = (_Jv_Linker::resolve_pool_entry (defining_class,
+ index)).rmethod;
sp -= rmeth->stack_item_count;
@@ -2844,7 +2859,8 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
{
int index = GET2U ();
- rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
+ rmeth = (_Jv_Linker::resolve_pool_entry (defining_class,
+ index)).rmethod;
sp -= rmeth->stack_item_count;
@@ -2873,7 +2889,8 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
{
int index = GET2U ();
- rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
+ rmeth = (_Jv_Linker::resolve_pool_entry (defining_class,
+ index)).rmethod;
sp -= rmeth->stack_item_count;
@@ -2916,12 +2933,9 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
insn_new:
{
int index = GET2U ();
- jclass klass = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
- // We initialize here because otherwise `size_in_bytes' may
- // not be set correctly, leading us to pass `0' as the size.
- // FIXME: fix in the allocator? There is a PR for this.
- _Jv_InitClass (klass);
- jobject res = _Jv_AllocObject (klass, klass->size_in_bytes);
+ jclass klass = (_Jv_Linker::resolve_pool_entry (defining_class,
+ index)).clazz;
+ jobject res = _Jv_AllocObject (klass);
PUSHA (res);
#ifdef DIRECT_THREADED
@@ -2935,7 +2949,7 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
new_resolved:
{
jclass klass = (jclass) AVAL ();
- jobject res = _Jv_AllocObject (klass, klass->size_in_bytes);
+ jobject res = _Jv_AllocObject (klass);
PUSHA (res);
}
NEXT_INSN;
@@ -2953,7 +2967,8 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
insn_anewarray:
{
int index = GET2U ();
- jclass klass = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
+ jclass klass = (_Jv_Linker::resolve_pool_entry (defining_class,
+ index)).clazz;
int size = POPI();
jobject result = _Jv_NewObjectArray (size, klass, 0);
PUSHA (result);
@@ -2995,7 +3010,8 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
{
jobject value = POPA();
jint index = GET2U ();
- jclass to = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
+ jclass to = (_Jv_Linker::resolve_pool_entry (defining_class,
+ index)).clazz;
if (value != NULL && ! to->isInstance (value))
throw new java::lang::ClassCastException (to->getName());
@@ -3025,7 +3041,8 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
{
jobject value = POPA();
jint index = GET2U ();
- jclass to = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
+ jclass to = (_Jv_Linker::resolve_pool_entry (defining_class,
+ index)).clazz;
PUSHI (to->isInstance (value));
#ifdef DIRECT_THREADED
@@ -3087,7 +3104,8 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
int dim = GET1U ();
jclass type
- = (_Jv_ResolvePoolEntry (defining_class, kind_index)).clazz;
+ = (_Jv_Linker::resolve_pool_entry (defining_class,
+ kind_index)).clazz;
jint *sizes = (jint*) __builtin_alloca (sizeof (jint)*dim);
for (int i = dim - 1; i >= 0; i--)
@@ -3184,8 +3202,8 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
#else
jclass handler = NULL;
if (exc[i].handler_type.i != 0)
- handler = (_Jv_ResolvePoolEntry (defining_class,
- exc[i].handler_type.i)).clazz;
+ handler = (_Jv_Linker::resolve_pool_entry (defining_class,
+ exc[i].handler_type.i)).clazz;
#endif /* DIRECT_THREADED */
if (handler == NULL || handler->isAssignableFrom (exc_class))
@@ -3238,4 +3256,526 @@ throw_null_pointer_exception ()
}
#endif
+/** Do static initialization for fields with a constant initializer */
+void
+_Jv_InitField (jobject obj, jclass klass, int index)
+{
+ using namespace java::lang::reflect;
+
+ if (obj != 0 && klass == 0)
+ klass = obj->getClass ();
+
+ if (!_Jv_IsInterpretedClass (klass))
+ return;
+
+ _Jv_InterpClass *iclass = (_Jv_InterpClass*)klass->aux_info;
+
+ _Jv_Field * field = (&klass->fields[0]) + index;
+
+ if (index > klass->field_count)
+ throw_internal_error ("field out of range");
+
+ int init = iclass->field_initializers[index];
+ if (init == 0)
+ return;
+
+ _Jv_Constants *pool = &klass->constants;
+ int tag = pool->tags[init];
+
+ if (! field->isResolved ())
+ throw_internal_error ("initializing unresolved field");
+
+ if (obj==0 && ((field->flags & Modifier::STATIC) == 0))
+ throw_internal_error ("initializing non-static field with no object");
+
+ void *addr = 0;
+
+ if ((field->flags & Modifier::STATIC) != 0)
+ addr = (void*) field->u.addr;
+ else
+ addr = (void*) (((char*)obj) + field->u.boffset);
+
+ switch (tag)
+ {
+ case JV_CONSTANT_String:
+ {
+ jstring str;
+ str = _Jv_NewStringUtf8Const (pool->data[init].utf8);
+ pool->data[init].string = str;
+ pool->tags[init] = JV_CONSTANT_ResolvedString;
+ }
+ /* fall through */
+
+ case JV_CONSTANT_ResolvedString:
+ if (! (field->type == &java::lang::String::class$
+ || field->type == &java::lang::Class::class$))
+ throw_class_format_error ("string initialiser to non-string field");
+
+ *(jstring*)addr = pool->data[init].string;
+ break;
+
+ case JV_CONSTANT_Integer:
+ {
+ int value = pool->data[init].i;
+
+ if (field->type == JvPrimClass (boolean))
+ *(jboolean*)addr = (jboolean)value;
+
+ else if (field->type == JvPrimClass (byte))
+ *(jbyte*)addr = (jbyte)value;
+
+ else if (field->type == JvPrimClass (char))
+ *(jchar*)addr = (jchar)value;
+
+ else if (field->type == JvPrimClass (short))
+ *(jshort*)addr = (jshort)value;
+
+ else if (field->type == JvPrimClass (int))
+ *(jint*)addr = (jint)value;
+
+ else
+ throw_class_format_error ("erroneous field initializer");
+ }
+ break;
+
+ case JV_CONSTANT_Long:
+ if (field->type != JvPrimClass (long))
+ throw_class_format_error ("erroneous field initializer");
+
+ *(jlong*)addr = _Jv_loadLong (&pool->data[init]);
+ break;
+
+ case JV_CONSTANT_Float:
+ if (field->type != JvPrimClass (float))
+ throw_class_format_error ("erroneous field initializer");
+
+ *(jfloat*)addr = pool->data[init].f;
+ break;
+
+ case JV_CONSTANT_Double:
+ if (field->type != JvPrimClass (double))
+ throw_class_format_error ("erroneous field initializer");
+
+ *(jdouble*)addr = _Jv_loadDouble (&pool->data[init]);
+ break;
+
+ default:
+ throw_class_format_error ("erroneous field initializer");
+ }
+}
+
+inline static unsigned char*
+skip_one_type (unsigned char* ptr)
+{
+ int ch = *ptr++;
+
+ while (ch == '[')
+ {
+ ch = *ptr++;
+ }
+
+ if (ch == 'L')
+ {
+ do { ch = *ptr++; } while (ch != ';');
+ }
+
+ return ptr;
+}
+
+static ffi_type*
+get_ffi_type_from_signature (unsigned char* ptr)
+{
+ switch (*ptr)
+ {
+ case 'L':
+ case '[':
+ return &ffi_type_pointer;
+ break;
+
+ case 'Z':
+ // On some platforms a bool is a byte, on others an int.
+ if (sizeof (jboolean) == sizeof (jbyte))
+ return &ffi_type_sint8;
+ else
+ {
+ JvAssert (sizeof (jbyte) == sizeof (jint));
+ return &ffi_type_sint32;
+ }
+ break;
+
+ case 'B':
+ return &ffi_type_sint8;
+ break;
+
+ case 'C':
+ return &ffi_type_uint16;
+ break;
+
+ case 'S':
+ return &ffi_type_sint16;
+ break;
+
+ case 'I':
+ return &ffi_type_sint32;
+ break;
+
+ case 'J':
+ return &ffi_type_sint64;
+ break;
+
+ case 'F':
+ return &ffi_type_float;
+ break;
+
+ case 'D':
+ return &ffi_type_double;
+ break;
+
+ case 'V':
+ return &ffi_type_void;
+ break;
+ }
+
+ throw_internal_error ("unknown type in signature");
+}
+
+/* this function yields the number of actual arguments, that is, if the
+ * function is non-static, then one is added to the number of elements
+ * found in the signature */
+
+int
+_Jv_count_arguments (_Jv_Utf8Const *signature,
+ jboolean staticp)
+{
+ unsigned char *ptr = (unsigned char*) signature->data;
+ int arg_count = staticp ? 0 : 1;
+
+ /* first, count number of arguments */
+
+ // skip '('
+ ptr++;
+
+ // count args
+ while (*ptr != ')')
+ {
+ ptr = skip_one_type (ptr);
+ arg_count += 1;
+ }
+
+ return arg_count;
+}
+
+/* This beast will build a cif, given the signature. Memory for
+ * the cif itself and for the argument types must be allocated by the
+ * caller.
+ */
+
+static int
+init_cif (_Jv_Utf8Const* signature,
+ int arg_count,
+ jboolean staticp,
+ ffi_cif *cif,
+ ffi_type **arg_types,
+ ffi_type **rtype_p)
+{
+ unsigned char *ptr = (unsigned char*) signature->data;
+
+ int arg_index = 0; // arg number
+ int item_count = 0; // stack-item count
+
+ // setup receiver
+ if (!staticp)
+ {
+ arg_types[arg_index++] = &ffi_type_pointer;
+ item_count += 1;
+ }
+
+ // skip '('
+ ptr++;
+
+ // assign arg types
+ while (*ptr != ')')
+ {
+ arg_types[arg_index++] = get_ffi_type_from_signature (ptr);
+
+ if (*ptr == 'J' || *ptr == 'D')
+ item_count += 2;
+ else
+ item_count += 1;
+
+ ptr = skip_one_type (ptr);
+ }
+
+ // skip ')'
+ ptr++;
+ ffi_type *rtype = get_ffi_type_from_signature (ptr);
+
+ ptr = skip_one_type (ptr);
+ if (ptr != (unsigned char*)signature->data + signature->length)
+ throw_internal_error ("did not find end of signature");
+
+ if (ffi_prep_cif (cif, FFI_DEFAULT_ABI,
+ arg_count, rtype, arg_types) != FFI_OK)
+ throw_internal_error ("ffi_prep_cif failed");
+
+ if (rtype_p != NULL)
+ *rtype_p = rtype;
+
+ return item_count;
+}
+
+#if FFI_NATIVE_RAW_API
+# define FFI_PREP_RAW_CLOSURE ffi_prep_raw_closure
+# define FFI_RAW_SIZE ffi_raw_size
+#else
+# define FFI_PREP_RAW_CLOSURE ffi_prep_java_raw_closure
+# define FFI_RAW_SIZE ffi_java_raw_size
+#endif
+
+/* we put this one here, and not in interpret.cc because it
+ * calls the utility routines _Jv_count_arguments
+ * which are static to this module. The following struct defines the
+ * layout we use for the stubs, it's only used in the ncode method. */
+
+typedef struct {
+ ffi_raw_closure closure;
+ ffi_cif cif;
+ ffi_type *arg_types[0];
+} ncode_closure;
+
+typedef void (*ffi_closure_fun) (ffi_cif*,void*,ffi_raw*,void*);
+
+void *
+_Jv_InterpMethod::ncode ()
+{
+ using namespace java::lang::reflect;
+
+ if (self->ncode != 0)
+ return self->ncode;
+
+ jboolean staticp = (self->accflags & Modifier::STATIC) != 0;
+ int arg_count = _Jv_count_arguments (self->signature, staticp);
+
+ ncode_closure *closure =
+ (ncode_closure*)_Jv_AllocBytes (sizeof (ncode_closure)
+ + arg_count * sizeof (ffi_type*));
+
+ init_cif (self->signature,
+ arg_count,
+ staticp,
+ &closure->cif,
+ &closure->arg_types[0],
+ NULL);
+
+ ffi_closure_fun fun;
+
+ args_raw_size = FFI_RAW_SIZE (&closure->cif);
+
+ JvAssert ((self->accflags & Modifier::NATIVE) == 0);
+
+ if ((self->accflags & Modifier::SYNCHRONIZED) != 0)
+ {
+ if (staticp)
+ fun = (ffi_closure_fun)&_Jv_InterpMethod::run_synch_class;
+ else
+ fun = (ffi_closure_fun)&_Jv_InterpMethod::run_synch_object;
+ }
+ else
+ {
+ if (staticp)
+ fun = (ffi_closure_fun)&_Jv_InterpMethod::run_class;
+ else
+ fun = (ffi_closure_fun)&_Jv_InterpMethod::run_normal;
+ }
+
+ FFI_PREP_RAW_CLOSURE (&closure->closure,
+ &closure->cif,
+ fun,
+ (void*)this);
+
+ self->ncode = (void*)closure;
+ return self->ncode;
+}
+
+void *
+_Jv_JNIMethod::ncode ()
+{
+ using namespace java::lang::reflect;
+
+ if (self->ncode != 0)
+ return self->ncode;
+
+ jboolean staticp = (self->accflags & Modifier::STATIC) != 0;
+ int arg_count = _Jv_count_arguments (self->signature, staticp);
+
+ ncode_closure *closure =
+ (ncode_closure*)_Jv_AllocBytes (sizeof (ncode_closure)
+ + arg_count * sizeof (ffi_type*));
+
+ ffi_type *rtype;
+ init_cif (self->signature,
+ arg_count,
+ staticp,
+ &closure->cif,
+ &closure->arg_types[0],
+ &rtype);
+
+ ffi_closure_fun fun;
+
+ args_raw_size = FFI_RAW_SIZE (&closure->cif);
+
+ // Initialize the argument types and CIF that represent the actual
+ // underlying JNI function.
+ int extra_args = 1;
+ if ((self->accflags & Modifier::STATIC))
+ ++extra_args;
+ jni_arg_types = (ffi_type **) _Jv_AllocBytes ((extra_args + arg_count)
+ * sizeof (ffi_type *));
+ int offset = 0;
+ jni_arg_types[offset++] = &ffi_type_pointer;
+ if ((self->accflags & Modifier::STATIC))
+ jni_arg_types[offset++] = &ffi_type_pointer;
+ memcpy (&jni_arg_types[offset], &closure->arg_types[0],
+ arg_count * sizeof (ffi_type *));
+
+ if (ffi_prep_cif (&jni_cif, _Jv_platform_ffi_abi,
+ extra_args + arg_count, rtype,
+ jni_arg_types) != FFI_OK)
+ throw_internal_error ("ffi_prep_cif failed for JNI function");
+
+ JvAssert ((self->accflags & Modifier::NATIVE) != 0);
+
+ // FIXME: for now we assume that all native methods for
+ // interpreted code use JNI.
+ fun = (ffi_closure_fun) &_Jv_JNIMethod::call;
+
+ FFI_PREP_RAW_CLOSURE (&closure->closure,
+ &closure->cif,
+ fun,
+ (void*) this);
+
+ self->ncode = (void *) closure;
+ return self->ncode;
+}
+
+static void
+throw_class_format_error (jstring msg)
+{
+ throw (msg
+ ? new java::lang::ClassFormatError (msg)
+ : new java::lang::ClassFormatError);
+}
+
+static void
+throw_class_format_error (char *msg)
+{
+ throw_class_format_error (JvNewStringLatin1 (msg));
+}
+
+
+void
+_Jv_InterpreterEngine::do_verify (jclass klass)
+{
+ _Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;
+ for (int i = 0; i < klass->method_count; i++)
+ {
+ _Jv_MethodBase *imeth = iclass->interpreted_methods[i];
+ if ((klass->methods[i].accflags & java::lang::reflect::Modifier::NATIVE)
+ == 0)
+ {
+ _Jv_InterpMethod *im = reinterpret_cast<_Jv_InterpMethod *> (imeth);
+ _Jv_VerifyMethod (im);
+ }
+ }
+}
+
+void
+_Jv_InterpreterEngine::do_create_ncode (jclass klass)
+{
+ _Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;
+ for (int i = 0; i < klass->method_count; i++)
+ {
+ // Just skip abstract methods. This is particularly important
+ // because we don't resize the interpreted_methods array when
+ // miranda methods are added to it.
+ if ((klass->methods[i].accflags
+ & java::lang::reflect::Modifier::ABSTRACT)
+ != 0)
+ continue;
+
+ _Jv_MethodBase *imeth = iclass->interpreted_methods[i];
+
+ if ((klass->methods[i].accflags & java::lang::reflect::Modifier::NATIVE)
+ != 0)
+ {
+ // You might think we could use a virtual `ncode' method in
+ // the _Jv_MethodBase and unify the native and non-native
+ // cases. Well, we can't, because we don't allocate these
+ // objects using `new', and thus they don't get a vtable.
+ _Jv_JNIMethod *jnim = reinterpret_cast<_Jv_JNIMethod *> (imeth);
+ klass->methods[i].ncode = jnim->ncode ();
+ }
+ else if (imeth != 0) // it could be abstract
+ {
+ _Jv_InterpMethod *im = reinterpret_cast<_Jv_InterpMethod *> (imeth);
+ klass->methods[i].ncode = im->ncode ();
+ }
+ }
+}
+
+void
+_Jv_InterpreterEngine::do_allocate_static_fields (jclass klass,
+ int static_size)
+{
+ _Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;
+
+ char *static_data = (char *) _Jv_AllocBytes (static_size);
+ memset (static_data, 0, static_size);
+
+ for (int i = 0; i < klass->field_count; i++)
+ {
+ _Jv_Field *field = &klass->fields[i];
+
+ if ((field->flags & java::lang::reflect::Modifier::STATIC) != 0)
+ {
+ field->u.addr = static_data + field->u.boffset;
+
+ if (iclass->field_initializers[i] != 0)
+ {
+ _Jv_Linker::resolve_field (field, klass->loader);
+ _Jv_InitField (0, klass, i);
+ }
+ }
+ }
+
+ // Now we don't need the field_initializers anymore, so let the
+ // collector get rid of it.
+ iclass->field_initializers = 0;
+}
+
+_Jv_ResolvedMethod *
+_Jv_InterpreterEngine::do_resolve_method (_Jv_Method *method, jclass klass,
+ jboolean staticp, jint vtable_index)
+{
+ int arg_count = _Jv_count_arguments (method->signature, staticp);
+
+ _Jv_ResolvedMethod* result = (_Jv_ResolvedMethod*)
+ _Jv_AllocBytes (sizeof (_Jv_ResolvedMethod)
+ + arg_count*sizeof (ffi_type*));
+
+ result->stack_item_count
+ = init_cif (method->signature,
+ arg_count,
+ staticp,
+ &result->cif,
+ &result->arg_types[0],
+ NULL);
+
+ result->vtable_index = vtable_index;
+ result->method = method;
+ result->klass = klass;
+
+ return result;
+}
+
#endif // INTERPRETER
diff --git a/libjava/java/applet/Applet.java b/libjava/java/applet/Applet.java
index 5990c6392da..27c8aafb7fb 100644
--- a/libjava/java/applet/Applet.java
+++ b/libjava/java/applet/Applet.java
@@ -78,6 +78,11 @@ public class Applet extends Panel
private transient AppletStub stub;
/**
+ * The dimensions passed to this applet through its HTML tag.
+ */
+ private transient Dimension dimensions;
+
+ /**
* The accessibility context for this applet.
*
* @serial the accessibleContext for this
@@ -457,6 +462,41 @@ public class Applet extends Panel
s.defaultReadObject();
}
+ private Dimension getDimensions ()
+ {
+ if (dimensions == null)
+ {
+ int width = Integer.parseInt(stub.getParameter("width"));
+ int height = Integer.parseInt(stub.getParameter("height"));
+
+ dimensions = new Dimension(width, height);
+ }
+
+ return dimensions;
+ }
+
+ /**
+ * Returns an instance of {@link Dimension} representing the
+ * applet's width and height parameters.
+ *
+ * @return the applet's preferred size
+ */
+ public Dimension preferredSize()
+ {
+ return getDimensions ();
+ }
+
+ /**
+ * Returns an instance of {@link Dimension} representing the
+ * applet's width and height parameters.
+ *
+ * @return the applet's minimum size
+ */
+ public Dimension minimumSize()
+ {
+ return getDimensions ();
+ }
+
/**
* This class provides accessibility support for Applets, and is the
* runtime type returned by {@link #getAccessibleContext()}.
diff --git a/libjava/java/awt/AWTPermission.java b/libjava/java/awt/AWTPermission.java
index 993c60d50d4..b5ba63d58d0 100644
--- a/libjava/java/awt/AWTPermission.java
+++ b/libjava/java/awt/AWTPermission.java
@@ -79,7 +79,7 @@ import java.security.BasicPermission;
* <tr>
* <td><code>fullScreenExclusive</code></td>
* <td>enter full-screen exclusive mode</td>
- * <td>malicious code could masquerade as a trusted program</td><tr>
+ * <td>malicious code could masquerade as a trusted program</td></tr>
* </table>
*
* @author Tom Tromey <tromey@redhat.com>
diff --git a/libjava/java/awt/Color.java b/libjava/java/awt/Color.java
index e6eb03e8f0a..c41117a6e33 100644
--- a/libjava/java/awt/Color.java
+++ b/libjava/java/awt/Color.java
@@ -319,7 +319,12 @@ public class Color implements Paint, Serializable
{
if ((red & 255) != red || (green & 255) != green || (blue & 255) != blue
|| (alpha & 255) != alpha)
- throw new IllegalArgumentException("Bad RGB values");
+ throw new IllegalArgumentException("Bad RGB values"
+ +" red=0x"+Integer.toHexString(red)
+ +" green=0x"+Integer.toHexString(green)
+ +" blue=0x"+Integer.toHexString(blue)
+ +" alpha=0x"+Integer.toHexString(alpha) );
+
value = (alpha << 24) | (red << 16) | (green << 8) | blue;
falpha = 1;
cs = null;
@@ -950,7 +955,7 @@ public class Color implements Paint, Serializable
* object, regardless of the parameters. Subclasses, however, may have a
* mutable result.
*
- * @param cm the requested color model, ignored
+ * @param cm the requested color model
* @param deviceBounds the bounding box in device coordinates, ignored
* @param userBounds the bounding box in user coordinates, ignored
* @param xform the bounds transformation, ignored
@@ -962,8 +967,8 @@ public class Color implements Paint, Serializable
AffineTransform xform,
RenderingHints hints)
{
- if (context == null)
- context = new ColorPaintContext(value);
+ if (context == null || !context.getColorModel().equals(cm))
+ context = new ColorPaintContext(cm,value);
return context;
}
diff --git a/libjava/java/awt/ColorPaintContext.java b/libjava/java/awt/ColorPaintContext.java
index a365812a866..9fdfe61962d 100644
--- a/libjava/java/awt/ColorPaintContext.java
+++ b/libjava/java/awt/ColorPaintContext.java
@@ -1,5 +1,5 @@
/* ColorPaintContext.java -- context for painting solid colors
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -55,15 +55,31 @@ class ColorPaintContext implements PaintContext
* SystemColor.
*/
final int color;
+ final ColorModel colorModel;
+ private ColorRaster cachedRaster;
+
+
/**
* Create the context for a given color.
*
- * @param c the solid color to use
+ * @param c The solid color to use.
*/
- ColorPaintContext(int c)
+ ColorPaintContext(int colorRGB)
{
- color = c;
+ this(ColorModel.getRGBdefault(), colorRGB);
+ }
+
+ /**
+ * Create the context for a given color.
+ *
+ * @param cm The color model of this context.
+ * @param c The solid color to use.
+ */
+ ColorPaintContext(ColorModel cm,int colorRGB)
+ {
+ color = colorRGB;
+ colorModel = cm;
}
/**
@@ -75,14 +91,13 @@ class ColorPaintContext implements PaintContext
}
/**
- * Return the color model of this context. This ignores the model passed
- * in the request, since colors are always in sRGB.
+ * Return the color model of this context.
*
* @return the context color model
*/
public ColorModel getColorModel()
{
- return ColorModel.getRGBdefault();
+ return colorModel;
}
/**
@@ -94,10 +109,87 @@ class ColorPaintContext implements PaintContext
* @param h the height, in device space
* @return a raster for the given area and color
*/
- public Raster getRaster(int x, int y, int w, int h)
+ public Raster getRaster(int x, int y, int width, int height)
+ {
+ if( cachedRaster == null
+ || cachedRaster.getWidth() < width
+ || cachedRaster.getHeight() < height)
+ {
+ cachedRaster = new ColorRaster(colorModel, 0, 0, width, height, color);
+ }
+ return cachedRaster.createChild(0 ,0 ,width ,height ,x ,y , null);
+ }
+
+ /**
+ * A ColorRaster is a raster that is completely filled with one color. The
+ * data layout is taken from the color model given to the constructor.
+ */
+ private class ColorRaster extends Raster
{
- // XXX Implement. Sun uses undocumented implementation class
- // sun.awt.image.IntegerInterleavedRaster.
- throw new Error("not implemented");
+
+ /**
+ * Create a raster that is compaltible with the given color model and
+ * filled with the given color.
+ * @param cm The color model for this raster.
+ * @param x The smallest horizontal corrdinate in the raster.
+ * @param y The smallest vertical coordinate in the raster.
+ * @param width The width of the raster.
+ * @param height The height of the raster.
+ * @param rgbPixel The RGB value of the color for this raster.
+ */
+ ColorRaster(ColorModel cm,int x, int y, int width, int height, int rgbPixel)
+ {
+ super(cm.createCompatibleSampleModel(width,height),new Point(x,y));
+ Object pixel = cm.getDataElements(rgbPixel,null);
+ getSampleModel().setDataElements(0, 0,
+ width, height,
+ multiplyData(pixel,null,width*height),
+ dataBuffer);
+ }
+
+
+
+ private Object multiplyData(Object src, Object dest, int factor)
+ {
+ Object from;
+ int srcLength = 0;
+ if (src instanceof byte[])
+ {
+ srcLength = ((byte[])src).length;
+
+ if (dest == null) dest = new byte[factor * srcLength];
+ }
+ else if (src instanceof short[])
+ {
+ srcLength = ((short[])src).length;
+ if (dest == null) dest = new short[factor * srcLength];
+ }
+ else if (src instanceof int[])
+ {
+ srcLength = ((int[]) src).length;
+ if (dest == null) dest = new int[factor * srcLength];
+ }
+ else
+ {
+ throw new ClassCastException("Unknown data buffer type");
+ }
+
+ System.arraycopy(src,0,dest,0,srcLength);
+
+ int count = 1;
+ while(count*2 < factor)
+ {
+ System.arraycopy(dest, 0, dest, count * srcLength, count*srcLength);
+ count *= 2;
+ }
+
+ if(factor > count)
+ System.arraycopy(dest,0, dest, count * srcLength,
+ (factor - count) * srcLength );
+
+ return dest;
+ }
+
}
+
} // class ColorPaintContext
diff --git a/libjava/java/awt/Component.java b/libjava/java/awt/Component.java
index 8c75ba06eb2..d52818af683 100644
--- a/libjava/java/awt/Component.java
+++ b/libjava/java/awt/Component.java
@@ -105,7 +105,7 @@ import javax.accessibility.AccessibleStateSet;
* in inner classes, rather than using this object itself as the listener, if
* external objects do not need to save the state of this object.
*
- * <p><pre>
+ * <pre>
* import java.awt.*;
* import java.awt.event.*;
* import java.io.Serializable;
@@ -127,6 +127,7 @@ import javax.accessibility.AccessibleStateSet;
* aButton.addActionListener(new MyActionListener());
* }
* }
+ * </pre>
*
* <p>Status: Incomplete. The event dispatch mechanism is implemented. All
* other methods defined in the J2SE 1.3 API javadoc exist, but are mostly
@@ -3816,6 +3817,12 @@ public abstract class Component
if (popups == null)
popups = new Vector();
popups.add(popup);
+
+ if (popup.parent != null)
+ popup.parent.remove(popup);
+ popup.parent = this;
+ if (peer != null)
+ popup.addNotify();
}
/**
diff --git a/libjava/java/awt/ComponentOrientation.java b/libjava/java/awt/ComponentOrientation.java
index 8d3a40c8599..02cf5967ff2 100644
--- a/libjava/java/awt/ComponentOrientation.java
+++ b/libjava/java/awt/ComponentOrientation.java
@@ -171,13 +171,15 @@ public final class ComponentOrientation implements Serializable
}
/**
- * Gets an orientation from a resource bundle. This tries the following:<ol>
+ * Gets an orientation from a resource bundle. This tries the following:
+ *
+ * <ul>
* <li>Use the key "Orientation" to find an instance of ComponentOrientation
* in the bundle.</li>
* <li>Get the locale of the resource bundle, and get the orientation of
* that locale.</li>
- * <li>Give up and get the orientation of the default locale.<li>
- * <ol>
+ * <li>Give up and get the orientation of the default locale.</li>
+ * </ul>
*
* @param bdl the bundle to use
* @return the orientation
diff --git a/libjava/java/awt/Dialog.java b/libjava/java/awt/Dialog.java
index 5516ff906d0..6bfb80c8563 100644
--- a/libjava/java/awt/Dialog.java
+++ b/libjava/java/awt/Dialog.java
@@ -123,8 +123,8 @@ Dialog(Frame parent)
* parent and modality, that is resizable and which has no title.
*
* @param parent The parent frame of this dialog box.
- * @param modal <true> if this dialog box is modal, <code>false</code>
- * otherwise.
+ * @param modal <code>true</code> if this dialog box is modal,
+ * <code>false</code> otherwise.
*
* @exception IllegalArgumentException If the owner's GraphicsConfiguration
* is not from a screen device, or if owner is null. This exception is always
@@ -164,8 +164,8 @@ Dialog(Frame parent, String title)
*
* @param parent The parent frame of this dialog box.
* @param title The title string for this dialog box.
- * @param modal <true> if this dialog box is modal, <code>false</code>
- * otherwise.
+ * @param modal <code>true</code> if this dialog box is modal,
+ * <code>false</code> otherwise.
*
* @exception IllegalArgumentException If owner is null or
* GraphicsEnvironment.isHeadless() returns true.
@@ -183,8 +183,8 @@ Dialog(Frame parent, String title, boolean modal)
*
* @param parent The parent frame of this dialog box.
* @param title The title string for this dialog box.
- * @param modal <true> if this dialog box is modal, <code>false</code>
- * otherwise.
+ * @param modal <code>true</code> if this dialog box is modal,
+ * <code>false</code> otherwise.
* @param gc The <code>GraphicsConfiguration</code> object to use.
*
* @exception IllegalArgumentException If owner is null, the
diff --git a/libjava/java/awt/FileDialog.java b/libjava/java/awt/FileDialog.java
index 24a621084b9..854d092f016 100644
--- a/libjava/java/awt/FileDialog.java
+++ b/libjava/java/awt/FileDialog.java
@@ -41,6 +41,7 @@ package java.awt;
import java.awt.peer.FileDialogPeer;
import java.awt.peer.DialogPeer;
import java.io.FilenameFilter;
+import java.io.Serializable;
/**
* This class implements a file selection dialog box widget.
@@ -48,7 +49,7 @@ import java.io.FilenameFilter;
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey <tromey@redhat.com>
*/
-public class FileDialog extends Dialog implements java.io.Serializable
+public class FileDialog extends Dialog implements Serializable
{
/*
diff --git a/libjava/java/awt/Font.java b/libjava/java/awt/Font.java
index 42f9f7b85eb..4c70c735797 100644
--- a/libjava/java/awt/Font.java
+++ b/libjava/java/awt/Font.java
@@ -1,5 +1,5 @@
/* Font.java -- Font object
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -650,6 +650,22 @@ private static final long serialVersionUID = -4206021311591459213L;
/**
* Produces a new {@link Font} based on the current font, adjusted to a
+ * new size and style.
+ *
+ * @param style The style of the newly created font.
+ * @param size The size of the newly created font.
+ *
+ * @return A clone of the current font, with the specified size and style.
+ *
+ * @since 1.2
+ */
+ public Font deriveFont (int style, float size)
+{
+ return peer.deriveFont (this, style, size);
+}
+
+/**
+ * Produces a new {@link Font} based on the current font, adjusted to a
* new size.
*
* @param size The size of the newly created font.
@@ -702,6 +718,27 @@ private static final long serialVersionUID = -4206021311591459213L;
}
/**
+ * Produces a new {@link Font} based on the current font, subjected
+ * to a new affine transformation.
+ *
+ * @param a The transformation to apply.
+ *
+ * @return A clone of the current font, with the specified transform.
+ *
+ * @throws IllegalArgumentException If transformation is
+ * <code>null</code>.
+ *
+ * @since 1.2
+ */
+ public Font deriveFont (AffineTransform a)
+{
+ if (a == null)
+ throw new IllegalArgumentException ("Affine transformation is null");
+
+ return peer.deriveFont (this, a);
+}
+
+/**
* Produces a new {@link Font} based on the current font, adjusted to a
* new set of attributes.
*
diff --git a/libjava/java/awt/FontMetrics.java b/libjava/java/awt/FontMetrics.java
index a7f76e03ae7..cb76f507909 100644
--- a/libjava/java/awt/FontMetrics.java
+++ b/libjava/java/awt/FontMetrics.java
@@ -47,12 +47,12 @@ package java.awt;
* least the following methods:
* <p>
* <ul>
- * <li>getAscent
- * <li>getDescent
- * <li>getLeading()
- * <li>getMaxAdvance()
- * <li>charWidth(char)
- * <li>charsWidth(char[], int, int)
+ * <li>getAscent()</li>
+ * <li>getDescent()</li>
+ * <li>getLeading()</li>
+ * <li>getMaxAdvance()</li>
+ * <li>charWidth(char)</li>
+ * <li>charsWidth(char[], int, int)</li>
* </ul>
*
* @author Aaron M. Renn (arenn@urbanophile.com)
@@ -292,8 +292,7 @@ charsWidth(char buf[], int offset, int len)
{
int total_width = 0;
for (int i = offset; i < len; i++)
- total_width = charWidth(buf[i]);
-
+ total_width += charWidth(buf[i]);
return(total_width);
}
@@ -328,7 +327,12 @@ bytesWidth(byte buf[], int offset, int len)
public int[]
getWidths()
{
- return(new int[256]);
+ int [] result = new int[256];
+ for(char i = 0; i < 256; i++)
+ {
+ result[i]= charWidth(i);
+ }
+ return(result);
}
/*************************************************************************/
@@ -347,3 +351,4 @@ toString()
} // class FontMetrics
+
diff --git a/libjava/java/awt/Graphics.java b/libjava/java/awt/Graphics.java
index c225b521a04..d2207ead1c3 100644
--- a/libjava/java/awt/Graphics.java
+++ b/libjava/java/awt/Graphics.java
@@ -1,5 +1,5 @@
/* Graphics.java -- Abstract Java drawing class
- Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -417,7 +417,7 @@ draw3DRect(int x, int y, int width, int height, boolean raised)
drawLine(x1, y2, x1, y1);
setColor(br);
drawLine(x2, y1, x2, y2);
- drawLine(x2, y1, x1, y2);
+ drawLine(x2, y2, x1, y2);
setColor(color);
}
diff --git a/libjava/java/awt/Menu.java b/libjava/java/awt/Menu.java
index 74478fbca75..c6c4f214dce 100644
--- a/libjava/java/awt/Menu.java
+++ b/libjava/java/awt/Menu.java
@@ -82,7 +82,7 @@ private boolean isHelpMenu;
// From the serialization spec. FIXME: what should it be?
private int menuSerializedDataVersion;
-static final MenuItem separator = new MenuItem("-");
+static final String separatorLabel = "-";
/*************************************************************************/
@@ -295,8 +295,7 @@ insert(String label, int index)
public void
addSeparator()
{
- if (peer != null)
- ((MenuPeer) peer).addSeparator();
+ add(new MenuItem(separatorLabel));
}
/*************************************************************************/
@@ -314,7 +313,7 @@ addSeparator()
public void
insertSeparator(int index)
{
- insert(separator, index);
+ insert(new MenuItem(separatorLabel), index);
}
/*************************************************************************/
diff --git a/libjava/java/awt/MenuItem.java b/libjava/java/awt/MenuItem.java
index cfdfafcc881..4defc38279e 100644
--- a/libjava/java/awt/MenuItem.java
+++ b/libjava/java/awt/MenuItem.java
@@ -310,7 +310,10 @@ deleteShortcut()
public String
getActionCommand()
{
- return(actionCommand);
+ if (actionCommand == null)
+ return label;
+ else
+ return actionCommand;
}
/*************************************************************************/
diff --git a/libjava/java/awt/Polygon.java b/libjava/java/awt/Polygon.java
index e91144c8812..96c370aafc1 100644
--- a/libjava/java/awt/Polygon.java
+++ b/libjava/java/awt/Polygon.java
@@ -294,7 +294,7 @@ public class Polygon implements Shape, Serializable
else if (y > maxy)
maxy = y;
}
- bounds = new Rectangle (minx, maxy, maxx - minx, maxy - miny);
+ bounds = new Rectangle (minx, miny, maxx - minx, maxy - miny);
}
return bounds;
}
diff --git a/libjava/java/awt/PopupMenu.java b/libjava/java/awt/PopupMenu.java
index cde79e3f109..83ffb35a85e 100644
--- a/libjava/java/awt/PopupMenu.java
+++ b/libjava/java/awt/PopupMenu.java
@@ -105,7 +105,7 @@ PopupMenu(String label)
public void
addNotify()
{
- if (peer != null)
+ if (peer == null)
peer = getToolkit ().createPopupMenu (this);
super.addNotify ();
}
@@ -123,6 +123,8 @@ addNotify()
public void
show(Component component, int x, int y)
{
+ if (getPeer() == null)
+ this.addNotify();
PopupMenuPeer pmp = (PopupMenuPeer)getPeer();
if (pmp != null)
{
diff --git a/libjava/java/awt/SystemColor.java b/libjava/java/awt/SystemColor.java
index c6bffe2101a..5217677b722 100644
--- a/libjava/java/awt/SystemColor.java
+++ b/libjava/java/awt/SystemColor.java
@@ -427,7 +427,7 @@ public final class SystemColor extends Color implements Serializable
* as the system color is solid, the context does not need any of the
* passed parameters to do its job.
*
- * @param cm the requested color model, ignored
+ * @param cm the requested color model
* @param deviceBounds the bounding box in device coordinates, ignored
* @param userBounds the bounding box in user coordinates, ignored
* @param xform the bounds transformation, ignored
@@ -441,8 +441,8 @@ public final class SystemColor extends Color implements Serializable
{
Toolkit.getDefaultToolkit().loadSystemColors(colors);
int color = colors[value] | ALPHA_MASK;
- if (context == null || color != context.color)
- context = new ColorPaintContext(color);
+ if (context == null || color != context.color || !context.getColorModel().equals(cm))
+ context = new ColorPaintContext(cm,color);
return context;
}
diff --git a/libjava/java/awt/TextComponent.java b/libjava/java/awt/TextComponent.java
index f0c5d6f54b2..0a410a44b9f 100644
--- a/libjava/java/awt/TextComponent.java
+++ b/libjava/java/awt/TextComponent.java
@@ -41,7 +41,6 @@ package java.awt;
import java.awt.event.TextEvent;
import java.awt.event.TextListener;
import java.awt.peer.TextComponentPeer;
-import java.awt.peer.ComponentPeer;
import java.io.Serializable;
import java.util.EventListener;
@@ -234,11 +233,11 @@ setSelectionEnd(int selectionEnd)
* specified start and end positions. Illegal values for these
* positions are silently fixed.
*
- * @param startSelection The new start position for the selected text.
- * @param endSelection The new end position for the selected text.
+ * @param selectionStart The new start position for the selected text.
+ * @param selectionEnd The new end position for the selected text.
*/
public synchronized void
-select(int selectionStart, int endSelection)
+select(int selectionStart, int selectionEnd)
{
if (selectionStart < 0)
selectionStart = 0;
diff --git a/libjava/java/awt/datatransfer/DataFlavor.java b/libjava/java/awt/datatransfer/DataFlavor.java
index d911bab7146..3ec21911929 100644
--- a/libjava/java/awt/datatransfer/DataFlavor.java
+++ b/libjava/java/awt/datatransfer/DataFlavor.java
@@ -270,7 +270,7 @@ DataFlavor(Class representationClass, String humanPresentableName)
/**
* Initializes a new instance of <code>DataFlavor</code> with the
* specified MIME type and description. If the MIME type has a
- * "class=<rep class>" parameter then the representation class will
+ * "class=&lt;rep class&gt;" parameter then the representation class will
* be the class name specified. Otherwise the class defaults to
* <code>java.io.InputStream</code>. If the human readable name
* is not specified (<code>null</code>) then the human readable name
@@ -319,7 +319,7 @@ getRepresentationClassFromMime(String mimeString, ClassLoader classLoader)
/**
* Initializes a new instance of <code>DataFlavor</code> with the
* specified MIME type and description. If the MIME type has a
- * "class=<rep class>" parameter then the representation class will
+ * "class=&lt;rep class&gt;" parameter then the representation class will
* be the class name specified. Otherwise the class defaults to
* <code>java.io.InputStream</code>. If the human readable name
* is not specified (<code>null</code>) then the human readable name
@@ -709,10 +709,10 @@ equals(DataFlavor flavor)
* are met:
* <p>
* <ul>
- * <li>The object is not <code>null</code>.
- * <li>The object is an instance of <code>DataFlavor</code>.
+ * <li>The object is not <code>null</code>.</li>
+ * <li>The object is an instance of <code>DataFlavor</code>.</li>
* <li>The object's MIME type and representation class are equal to
- * this object's.
+ * this object's.</li>
* </ul>
*
* @param obj The <code>Object</code> to test against.
diff --git a/libjava/java/awt/event/MouseEvent.java b/libjava/java/awt/event/MouseEvent.java
index 5010eb9d920..ac8804c24d3 100644
--- a/libjava/java/awt/event/MouseEvent.java
+++ b/libjava/java/awt/event/MouseEvent.java
@@ -220,11 +220,11 @@ public class MouseEvent extends InputEvent
if ((modifiers & EventModifier.OLD_MASK) != 0)
{
if ((modifiers & BUTTON1_MASK) != 0)
- button = BUTTON1;
+ this.button = BUTTON1;
else if ((modifiers & BUTTON2_MASK) != 0)
- button = BUTTON2;
+ this.button = BUTTON2;
else if ((modifiers & BUTTON3_MASK) != 0)
- button = BUTTON3;
+ this.button = BUTTON3;
}
}
diff --git a/libjava/java/awt/image/ColorModel.java b/libjava/java/awt/image/ColorModel.java
index 767b83f7dd0..c73f4fd4e58 100644
--- a/libjava/java/awt/image/ColorModel.java
+++ b/libjava/java/awt/image/ColorModel.java
@@ -166,7 +166,7 @@ public abstract class ColorModel implements Transparency
*/
public static ColorModel getRGBdefault()
{
- return new DirectColorModel(8, 0xff0000, 0xff00, 0xff, 0xff000000);
+ return new DirectColorModel(32, 0xff0000, 0xff00, 0xff, 0xff000000);
}
public final boolean hasAlpha()
@@ -597,7 +597,11 @@ public abstract class ColorModel implements Transparency
return null;
}
- // Typically overridden
+ /**
+ * Checks if the given raster has a compatible data-layout (SampleModel).
+ * @param raster The Raster to test.
+ * @return true if raster is compatible.
+ */
public boolean isCompatibleRaster(Raster raster)
{
SampleModel sampleModel = raster.getSampleModel();
diff --git a/libjava/java/awt/image/ComponentColorModel.java b/libjava/java/awt/image/ComponentColorModel.java
index cc96ab15516..24d8b8ea685 100644
--- a/libjava/java/awt/image/ComponentColorModel.java
+++ b/libjava/java/awt/image/ComponentColorModel.java
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002 Free Software Foundation
+/* Copyright (C) 2000, 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -292,19 +292,56 @@ public class ComponentColorModel extends ColorModel
return Raster.createWritableRaster(sm, origin);
}
+
+ /**
+ * Creates a <code>SampleModel</code> whose arrangement of pixel
+ * data is compatible to this <code>ColorModel</code>.
+ *
+ * @param w the number of pixels in the horizontal direction.
+ * @param h the number of pixels in the vertical direction.
+ */
public SampleModel createCompatibleSampleModel(int w, int h)
{
- int pixelStride = getNumComponents();
-
- /* TODO: Maybe we don't need to create a new offset array each
- time, but rather use the same array every time. */
- int[] bandOffsets = new int[pixelStride];
- for (int i=0; i<pixelStride; i++) bandOffsets[i] = i;
- return new ComponentSampleModel(transferType, w, h,
- pixelStride, pixelStride*w,
- bandOffsets);
+ int pixelStride, scanlineStride;
+ int[] bandOffsets;
+
+ pixelStride = getNumComponents();
+ scanlineStride = pixelStride * w;
+
+ /* We might be able to re-use the same bandOffsets array among
+ * multiple calls to this method. However, this optimization does
+ * not seem worthwile because setting up descriptive data
+ * structures (such as SampleModels) is neglectible in comparision
+ * to shuffling around masses of pixel data.
+ */
+ bandOffsets = new int[pixelStride];
+ for (int i = 0; i < pixelStride; i++)
+ bandOffsets[i] = i;
+
+ /* FIXME: Think about whether it would make sense to return the
+ * possibly more efficient PixelInterleavedSampleModel for other
+ * transferTypes as well. It seems unlikely that this would break
+ * any user applications, so the Mauve tests on this method
+ * might be too restrictive.
+ */
+ switch (transferType)
+ {
+ case DataBuffer.TYPE_BYTE:
+ case DataBuffer.TYPE_USHORT:
+ return new PixelInterleavedSampleModel(transferType, w, h,
+ pixelStride,
+ scanlineStride,
+ bandOffsets);
+
+ default:
+ return new ComponentSampleModel(transferType, w, h,
+ pixelStride,
+ scanlineStride,
+ bandOffsets);
+ }
}
+
public boolean isCompatibleSampleModel(SampleModel sm)
{
return
diff --git a/libjava/java/awt/image/ComponentSampleModel.java b/libjava/java/awt/image/ComponentSampleModel.java
index 0a40161adeb..c7b08b919e5 100644
--- a/libjava/java/awt/image/ComponentSampleModel.java
+++ b/libjava/java/awt/image/ComponentSampleModel.java
@@ -349,7 +349,7 @@ public class ComponentSampleModel extends SampleModel
if (scanlineStride == rowSize)
{
// Collapse scan lines:
- scanlineStride = rowSize *= h;
+ rowSize *= h;
h = 1;
}
diff --git a/libjava/java/awt/image/DataBufferDouble.java b/libjava/java/awt/image/DataBufferDouble.java
new file mode 100644
index 00000000000..b1291f4165b
--- /dev/null
+++ b/libjava/java/awt/image/DataBufferDouble.java
@@ -0,0 +1,174 @@
+/* Copyright (C) 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+/* This is one of several classes that are nearly identical. Maybe we
+ should have a central template and generate all these files. This
+ is one of the cases where templates or macros would have been
+ useful to have in Java.
+
+ This file has been created using search-replace. My only fear is
+ that these classes will grow out-of-sync as of a result of changes
+ that are not propagated to the other files. As always, mirroring
+ code is a maintenance nightmare. */
+
+/**
+ * @since 1.4
+ *
+ * @author <a href="mailto:rolfwr@ii.uib.no">Rolf W. Rasmussen</a>
+ * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a>
+ */
+public final class DataBufferDouble
+ extends DataBuffer
+{
+ private double[] data;
+ private double[][] bankData;
+
+ public DataBufferDouble(int size)
+ {
+ super(TYPE_DOUBLE, size);
+ data = new double[size];
+ }
+
+ public DataBufferDouble(int size, int numBanks)
+ {
+ super(TYPE_DOUBLE, size, numBanks);
+ bankData = new double[numBanks][size];
+ data = bankData[0];
+ }
+
+ public DataBufferDouble(double[] dataArray, int size)
+ {
+ super(TYPE_DOUBLE, size);
+ data = dataArray;
+ }
+
+ public DataBufferDouble(double[] dataArray, int size, int offset)
+ {
+ super(TYPE_DOUBLE, size, 1, offset);
+ data = dataArray;
+ }
+
+ public DataBufferDouble(double[][] dataArray, int size)
+ {
+ super(TYPE_DOUBLE, size, dataArray.length);
+ bankData = dataArray;
+ data = bankData[0];
+ }
+
+ public DataBufferDouble(double[][] dataArray, int size, int[] offsets)
+ {
+ super(TYPE_DOUBLE, size, dataArray.length, offsets);
+ bankData = dataArray;
+ data = bankData[0];
+ }
+
+ public double[] getData()
+ {
+ return data;
+ }
+
+ public double[] getData(int bank)
+ {
+ return bankData[bank];
+ }
+
+ public double[][] getBankData()
+ {
+ return bankData;
+ }
+
+ public int getElem(int i)
+ {
+ return (int) data[i+offset];
+ }
+
+ public int getElem(int bank, int i)
+ {
+ return (int) bankData[bank][i+offsets[bank]];
+ }
+
+ public void setElem(int i, int val)
+ {
+ data[i+offset] = (double) val;
+ }
+
+ public void setElem(int bank, int i, int val)
+ {
+ bankData[bank][i+offsets[bank]] = (double) val;
+ }
+
+ public float getElemFloat(int i)
+ {
+ return (float) data[i+offset];
+ }
+
+ public float getElemFloat(int bank, int i)
+ {
+ return (float) bankData[bank][i+offsets[bank]];
+ }
+
+ public void setElemFloat(int i, float val)
+ {
+ data[i+offset] = val;
+ }
+
+ public void setElemFloat(int bank, int i, float val)
+ {
+ bankData[bank][i+offsets[bank]] = val;
+ }
+
+ public double getElemDouble(int i)
+ {
+ return data[i + offset];
+ }
+
+ public double getElemDouble(int bank, int i)
+ {
+ return bankData[bank][i + offsets[bank]];
+ }
+
+ public void setElemDouble(int i, double val)
+ {
+ data[i + offset] = val;
+ }
+
+ public void setElemDouble(int bank, int i, double val)
+ {
+ bankData[bank][i + offsets[bank]] = val;
+ }
+}
diff --git a/libjava/java/awt/image/DataBufferFloat.java b/libjava/java/awt/image/DataBufferFloat.java
new file mode 100644
index 00000000000..b2d88c16b8b
--- /dev/null
+++ b/libjava/java/awt/image/DataBufferFloat.java
@@ -0,0 +1,172 @@
+/* Copyright (C) 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+/* This is one of several classes that are nearly identical. Maybe we
+ should have a central template and generate all these files. This
+ is one of the cases where templates or macros would have been
+ useful to have in Java.
+
+ This file has been created using search-replace. My only fear is
+ that these classes will grow out-of-sync as of a result of changes
+ that are not propagated to the other files. As always, mirroring
+ code is a maintenance nightmare. */
+
+/**
+ * @author <a href="mailto:rolfwr@ii.uib.no">Rolf W. Rasmussen</a>
+ * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a>
+ */
+public final class DataBufferFloat
+ extends DataBuffer
+{
+ private float[] data;
+ private float[][] bankData;
+
+ public DataBufferFloat(int size)
+ {
+ super(TYPE_FLOAT, size);
+ data = new float[size];
+ }
+
+ public DataBufferFloat(int size, int numBanks)
+ {
+ super(TYPE_FLOAT, size, numBanks);
+ bankData = new float[numBanks][size];
+ data = bankData[0];
+ }
+
+ public DataBufferFloat(float[] dataArray, int size)
+ {
+ super(TYPE_FLOAT, size);
+ data = dataArray;
+ }
+
+ public DataBufferFloat(float[] dataArray, int size, int offset)
+ {
+ super(TYPE_FLOAT, size, 1, offset);
+ data = dataArray;
+ }
+
+ public DataBufferFloat(float[][] dataArray, int size)
+ {
+ super(TYPE_FLOAT, size, dataArray.length);
+ bankData = dataArray;
+ data = bankData[0];
+ }
+
+ public DataBufferFloat(float[][] dataArray, int size, int[] offsets)
+ {
+ super(TYPE_FLOAT, size, dataArray.length, offsets);
+ bankData = dataArray;
+ data = bankData[0];
+ }
+
+ public float[] getData()
+ {
+ return data;
+ }
+
+ public float[] getData(int bank)
+ {
+ return bankData[bank];
+ }
+
+ public float[][] getBankData()
+ {
+ return bankData;
+ }
+
+ public int getElem(int i)
+ {
+ return (int) data[i+offset];
+ }
+
+ public int getElem(int bank, int i)
+ {
+ return (int) bankData[bank][i+offsets[bank]];
+ }
+
+ public void setElem(int i, int val)
+ {
+ data[i+offset] = (float) val;
+ }
+
+ public void setElem(int bank, int i, int val)
+ {
+ bankData[bank][i+offsets[bank]] = (float) val;
+ }
+
+ public float getElemFloat(int i)
+ {
+ return data[i+offset];
+ }
+
+ public float getElemFloat(int bank, int i)
+ {
+ return bankData[bank][i+offsets[bank]];
+ }
+
+ public void setElemFloat(int i, float val)
+ {
+ data[i+offset] = val;
+ }
+
+ public void setElemFloat(int bank, int i, float val)
+ {
+ bankData[bank][i+offsets[bank]] = val;
+ }
+
+ public double getElemDouble(int i)
+ {
+ return getElemFloat(i);
+ }
+
+ public double getElemDouble(int bank, int i)
+ {
+ return getElemFloat(bank, i);
+ }
+
+ public void setElemDouble(int i, double val)
+ {
+ setElemFloat(i, (float) val);
+ }
+
+ public void setElemDouble(int bank, int i, double val)
+ {
+ setElemFloat(bank, i, (float) val);
+ }
+}
diff --git a/libjava/java/awt/image/DataBufferShort.java b/libjava/java/awt/image/DataBufferShort.java
new file mode 100644
index 00000000000..7a5c3942423
--- /dev/null
+++ b/libjava/java/awt/image/DataBufferShort.java
@@ -0,0 +1,130 @@
+/* Copyright (C) 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+/* This is one of several classes that are nearly identical. Maybe we
+ should have a central template and generate all these files. This
+ is one of the cases where templates or macros would have been
+ useful to have in Java.
+
+ This file has been created using search-replace. My only fear is
+ that these classes will grow out-of-sync as of a result of changes
+ that are not propagated to the other files. As always, mirroring
+ code is a maintenance nightmare. */
+
+/**
+ * @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
+ */
+public final class DataBufferShort extends DataBuffer
+{
+ private short[] data;
+ private short[][] bankData;
+
+ public DataBufferShort(int size)
+ {
+ super(TYPE_SHORT, size);
+ data = new short[size];
+ }
+
+ public DataBufferShort(int size, int numBanks)
+ {
+ super(TYPE_SHORT, size, numBanks);
+ bankData = new short[numBanks][size];
+ data = bankData[0];
+ }
+
+ public DataBufferShort(short[] dataArray, int size)
+ {
+ super(TYPE_SHORT, size);
+ data = dataArray;
+ }
+
+ public DataBufferShort(short[] dataArray, int size, int offset)
+ {
+ super(TYPE_SHORT, size, 1, offset);
+ data = dataArray;
+ }
+
+ public DataBufferShort(short[][] dataArray, int size)
+ {
+ super(TYPE_SHORT, size, dataArray.length);
+ bankData = dataArray;
+ data = bankData[0];
+ }
+
+ public DataBufferShort(short[][] dataArray, int size, int[] offsets)
+ {
+ super(TYPE_SHORT, size, dataArray.length, offsets);
+ bankData = dataArray;
+ data = bankData[0];
+ }
+
+ public short[] getData()
+ {
+ return data;
+ }
+
+ public short[] getData(int bank)
+ {
+ return bankData[bank];
+ }
+
+ public short[][] getBankData()
+ {
+ return bankData;
+ }
+
+ public int getElem(int i)
+ {
+ return data[i+offset];
+ }
+
+ public int getElem(int bank, int i)
+ {
+ return bankData[bank][i+offsets[bank]];
+ }
+
+ public void setElem(int i, int val)
+ {
+ data[i+offset] = (short) val;
+ }
+
+ public void setElem(int bank, int i, int val)
+ {
+ bankData[bank][i+offsets[bank]] = (short) val;
+ }
+}
diff --git a/libjava/java/awt/image/PixelInterleavedSampleModel.java b/libjava/java/awt/image/PixelInterleavedSampleModel.java
new file mode 100644
index 00000000000..d17a68d9ae3
--- /dev/null
+++ b/libjava/java/awt/image/PixelInterleavedSampleModel.java
@@ -0,0 +1,98 @@
+/* PixelInterleavedSampleModel.java
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.awt.image;
+
+
+/**
+ * A <code>SampleModel</code> that uses exactly one element of the
+ * raster&#x2019;s {@link DataBuffer} per pixel, holds all bands in a
+ * single bank, and stores band data in pixel-interleaved manner.
+ *
+ * @since 1.2
+ *
+ * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a>
+ */
+public class PixelInterleavedSampleModel
+ extends ComponentSampleModel
+{
+ public PixelInterleavedSampleModel(int dataType, int width, int height,
+ int pixelStride, int scanlineStride,
+ int[] bandOffsets)
+ {
+ super(dataType, width, height, pixelStride, scanlineStride,
+ bandOffsets);
+ }
+
+
+ /**
+ * Creates a new <code>SampleModel</code> that is like this one, but
+ * uses the specified width and height.
+ *
+ * @param width the number of pixels in the horizontal direction.
+ *
+ * @param height the number of pixels in the vertical direction.
+ */
+ public SampleModel createCompatibleSampleModel(int width, int height)
+ {
+ return new PixelInterleavedSampleModel(dataType, width, height,
+ pixelStride, scanlineStride,
+ bandOffsets);
+ }
+
+
+ /**
+ * Creates a new <code>SampleModel</code> that is like this one, but
+ * uses only a subset of its bands.
+ *
+ * @param bands an array whose elements indicate which bands shall
+ * be part of the subset. For example, <code>[0, 2, 3]</code> would
+ * create a SampleModel containing bands #0, #2 and #3.
+ */
+ public SampleModel createSubsetSampleModel(int[] bands)
+ {
+ int[] subOffsets;
+
+ subOffsets = new int[bands.length];
+ for (int i = 0; i < bands.length; i++)
+ subOffsets[i] = bandOffsets[bands[i]];
+
+ return new PixelInterleavedSampleModel(dataType, width, height,
+ pixelStride, scanlineStride,
+ subOffsets);
+ }
+}
diff --git a/libjava/java/awt/image/Raster.java b/libjava/java/awt/image/Raster.java
index ff6033a6a03..4fd194e2a9e 100644
--- a/libjava/java/awt/image/Raster.java
+++ b/libjava/java/awt/image/Raster.java
@@ -452,4 +452,25 @@ public class Raster
y-sampleModelTranslateY,
w, h, b, dArray, dataBuffer);
}
+
+ /**
+ * Create a String representing the stat of this Raster.
+ * @return A String representing the stat of this Raster.
+ * @see java.lang.Object#toString()
+ */
+ public String toString()
+ {
+ StringBuffer result = new StringBuffer();
+
+ result.append(getClass().getName());
+ result.append("[(");
+ result.append(minX).append(",").append(minY).append("), ");
+ result.append(width).append(" x ").append(height).append(",");
+ result.append(sampleModel).append(",");
+ result.append(dataBuffer);
+ result.append("]");
+
+ return result.toString();
+ }
+
}
diff --git a/libjava/java/awt/image/SampleModel.java b/libjava/java/awt/image/SampleModel.java
index 219a871d42c..a5d65ff20fe 100644
--- a/libjava/java/awt/image/SampleModel.java
+++ b/libjava/java/awt/image/SampleModel.java
@@ -58,7 +58,9 @@ public abstract class SampleModel
public SampleModel(int dataType, int w, int h, int numBands)
{
- if ((w<=0) || (h<=0)) throw new IllegalArgumentException();
+ if ((w <= 0) || (h <= 0))
+ throw new IllegalArgumentException((w <= 0 ? " width<=0" : " width is ok")
+ +(h <= 0 ? " height<=0" : " height is ok"));
// FIXME: How can an int be greater than Integer.MAX_VALUE?
// FIXME: How do we identify an unsupported data type?
@@ -68,7 +70,7 @@ public abstract class SampleModel
this.height = h;
this.numBands = numBands;
}
-
+
public final int getWidth()
{
return width;
diff --git a/libjava/java/awt/image/SinglePixelPackedSampleModel.java b/libjava/java/awt/image/SinglePixelPackedSampleModel.java
index 3affe055411..578500dbd0a 100644
--- a/libjava/java/awt/image/SinglePixelPackedSampleModel.java
+++ b/libjava/java/awt/image/SinglePixelPackedSampleModel.java
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002, 2003 Free Software Foundation
+/* Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -162,6 +162,63 @@ public class SinglePixelPackedSampleModel extends SampleModel
1 // length
);
}
+
+ /**
+ * This is a more efficient implementation of the default implementation in the super
+ * class.
+ * @param x The x-coordinate of the pixel rectangle to store in <code>obj</code>.
+ * @param y The y-coordinate of the pixel rectangle to store in <code>obj</code>.
+ * @param w The width of the pixel rectangle to store in <code>obj</code>.
+ * @param h The height of the pixel rectangle to store in <code>obj</code>.
+ * @param obj The primitive array to store the pixels into or null to force creation.
+ * @param data The DataBuffer that is the source of the pixel data.
+ * @return The primitive array containing the pixel data.
+ * @see java.awt.image.SampleModel#getDataElements(int, int, int, int, java.lang.Object, java.awt.image.DataBuffer)
+ */
+ public Object getDataElements(int x, int y, int w, int h, Object obj,
+ DataBuffer data)
+ {
+ int size = w*h;
+ int dataSize = size;
+ Object pixelData = null;
+ switch (getTransferType())
+ {
+ case DataBuffer.TYPE_BYTE:
+ pixelData = ((DataBufferByte) data).getData();
+ if (obj == null) obj = new byte[dataSize];
+ break;
+ case DataBuffer.TYPE_USHORT:
+ pixelData = ((DataBufferUShort) data).getData();
+ if (obj == null) obj = new short[dataSize];
+ break;
+ case DataBuffer.TYPE_INT:
+ pixelData = ((DataBufferInt) data).getData();
+ if (obj == null) obj = new int[dataSize];
+ break;
+ default:
+ // Seems like the only sensible thing to do.
+ throw new ClassCastException();
+ }
+ if(x==0 && scanlineStride == w)
+ {
+ // The full width need to be copied therefore we can copy in one shot.
+ System.arraycopy(pixelData, scanlineStride*y + data.getOffset(), obj, 0, size);
+ }
+ else
+ {
+ // Since we do not need the full width we need to copy line by line.
+ int outOffset = 0;
+ int dataOffset = scanlineStride*y + x + data.getOffset();
+ for (int yy = y; yy<(y+h); yy++)
+ {
+ System.arraycopy(pixelData, dataOffset, obj, outOffset, w);
+ dataOffset += scanlineStride;
+ outOffset += w;
+ }
+ }
+ return obj;
+ }
+
public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
{
@@ -201,7 +258,51 @@ public class SinglePixelPackedSampleModel extends SampleModel
int samples = data.getElem(offset);
return (samples & bitMasks[b]) >>> bitOffsets[b];
}
-
+
+ /**
+ * This method implements a more efficient way to set data elements than the default
+ * implementation of the super class. It sets the data elements line by line instead
+ * of pixel by pixel.
+ * @param x The x-coordinate of the data elements in <code>obj</code>.
+ * @param y The y-coordinate of the data elements in <code>obj</code>.
+ * @param w The width of the data elements in <code>obj</code>.
+ * @param h The height of the data elements in <code>obj</code>.
+ * @param obj The primitive array containing the data elements to set.
+ * @param data The DataBuffer to store the data elements into.
+ * @see java.awt.image.SampleModel#setDataElements(int, int, int, int, java.lang.Object, java.awt.image.DataBuffer)
+ */
+ public void setDataElements(int x, int y, int w, int h,
+ Object obj, DataBuffer data)
+ {
+
+ Object pixelData;
+ switch (getTransferType())
+ {
+ case DataBuffer.TYPE_BYTE:
+ pixelData = ((DataBufferByte) data).getData();
+ break;
+ case DataBuffer.TYPE_USHORT:
+ pixelData = ((DataBufferUShort) data).getData();
+ break;
+ case DataBuffer.TYPE_INT:
+ pixelData = ((DataBufferInt) data).getData();
+ break;
+ default:
+ // Seems like the only sensible thing to do.
+ throw new ClassCastException();
+ }
+
+ int inOffset = 0;
+ int dataOffset = scanlineStride*y + x + data.getOffset();
+ for (int yy=y; yy<(y+h); yy++)
+ {
+ System.arraycopy(obj,inOffset,pixelData,dataOffset,w);
+ dataOffset += scanlineStride;
+ inOffset += w;
+ }
+ }
+
+
public void setDataElements(int x, int y, Object obj, DataBuffer data)
{
int offset = scanlineStride*y + x + data.getOffset();
@@ -273,6 +374,39 @@ public class SinglePixelPackedSampleModel extends SampleModel
data.setElem(offset, samples);
}
+ /**
+ * This method implements a more efficient way to set pixels than the default
+ * implementation of the super class. It copies the pixel components directly
+ * from the input array instead of creating a intermediate buffer.
+ * @param x The x-coordinate of the pixel rectangle in <code>obj</code>.
+ * @param y The y-coordinate of the pixel rectangle in <code>obj</code>.
+ * @param w The width of the pixel rectangle in <code>obj</code>.
+ * @param h The height of the pixel rectangle in <code>obj</code>.
+ * @param obj The primitive array containing the pixels to set.
+ * @param data The DataBuffer to store the pixels into.
+ * @see java.awt.image.SampleModel#setPixels(int, int, int, int, int[], java.awt.image.DataBuffer)
+ */
+ public void setPixels(int x, int y, int w, int h, int[] iArray,
+ DataBuffer data)
+ {
+ int inOffset = 0;
+ int[] pixel = new int[numBands];
+ for (int yy=y; yy<(y+h); yy++)
+ {
+ int offset = scanlineStride*yy + x;
+ for (int xx=x; xx<(x+w); xx++)
+ {
+ int samples = 0;
+ for (int b=0; b<numBands; b++)
+ samples |= (iArray[inOffset+b] << bitOffsets[b]) & bitMasks[b];
+ data.setElem(0, offset, samples);
+ inOffset += numBands;
+ offset += 1;
+ }
+ }
+ }
+
+
public void setSample(int x, int y, int b, int s, DataBuffer data)
{
int offset = scanlineStride*y + x;
@@ -282,4 +416,24 @@ public class SinglePixelPackedSampleModel extends SampleModel
samples |= (s << bitOffsets[b]) & bitMask;
data.setElem(offset, samples);
}
+
+ /**
+ * Creates a String with some information about this SampleModel.
+ * @return A String describing this SampleModel.
+ * @see java.lang.Object#toString()
+ */
+ public String toString()
+ {
+ StringBuffer result = new StringBuffer();
+ result.append(getClass().getName());
+ result.append("[");
+ result.append("scanlineStride=").append(scanlineStride);
+ for(int i=0; i < bitMasks.length; i+=1)
+ {
+ result.append(", mask[").append(i).append("]=0x").append(Integer.toHexString(bitMasks[i]));
+ }
+
+ result.append("]");
+ return result.toString();
+ }
}
diff --git a/libjava/java/awt/peer/MenuPeer.java b/libjava/java/awt/peer/MenuPeer.java
index 67f213fda03..0b15914d05b 100644
--- a/libjava/java/awt/peer/MenuPeer.java
+++ b/libjava/java/awt/peer/MenuPeer.java
@@ -43,7 +43,6 @@ import java.awt.MenuItem;
public interface MenuPeer extends MenuItemPeer
{
void addItem (MenuItem item);
- void addSeparator ();
void delItem (int index);
}
diff --git a/libjava/java/beans/Introspector.java b/libjava/java/beans/Introspector.java
index 078f98eb37c..b3f67c521ba 100644
--- a/libjava/java/beans/Introspector.java
+++ b/libjava/java/beans/Introspector.java
@@ -65,7 +65,7 @@ import gnu.java.lang.ClassHelper;
* When you call getBeanInfo(class c), the Introspector
* first searches for BeanInfo class to see if you
* provided any explicit information. It searches for a
- * class named <bean class name>BeanInfo in different
+ * class named &lt;bean class name&gt;BeanInfo in different
* packages, first searching the bean class's package
* and then moving on to search the beanInfoSearchPath.<P>
*
@@ -113,14 +113,14 @@ import gnu.java.lang.ClassHelper;
* type &lt;type&gt;. There may also be a
* <CODE>public &lt;type&gt;[] getXXX()</CODE> and a
* <CODE>public void setXXX(&lt;type&gt;)</CODE>
- * method as well.</CODE></LI>
+ * method as well.</LI>
* <LI>If there is a
* <CODE>public void setXXX(int,&lt;type&gt;)</CODE>
* method, then it is a write-only indexed property of
* type &lt;type&gt;. There may also be a
* <CODE>public &lt;type&gt;[] getXXX()</CODE> and a
* <CODE>public void setXXX(&lt;type&gt;)</CODE>
- * method as well.</CODE></LI>
+ * method as well.</LI>
* <LI>If there is a
* <CODE>public &lt;type&gt; getXXX()</CODE> method,
* then XXX is a read-only property of type
diff --git a/libjava/java/beans/PropertyEditor.java b/libjava/java/beans/PropertyEditor.java
index 18b1a890e24..5cc3f6ab05f 100644
--- a/libjava/java/beans/PropertyEditor.java
+++ b/libjava/java/beans/PropertyEditor.java
@@ -77,7 +77,7 @@ package java.beans;
** have isPaintable() return true and implement the paintValue() method.
** This method does not determine in any way how the value is edited;
** merely how it is displayed.</LI>
- ** <LU>Let the caller of the PropertyEditor give the user a text input. Do
+ ** <LI>Let the caller of the PropertyEditor give the user a text input. Do
** this by returning a non-null String from getAsText(). If you support
** text input, you *must* support setAsText().</LI>
** <LI>Give the caller a set of possible values, such as "true"/"false", that
diff --git a/libjava/java/beans/PropertyEditorManager.java b/libjava/java/beans/PropertyEditorManager.java
index aa0e1776dea..85c9ba5d8dc 100644
--- a/libjava/java/beans/PropertyEditorManager.java
+++ b/libjava/java/beans/PropertyEditorManager.java
@@ -60,19 +60,20 @@ import java.awt.Font;
* already registered; if it is, that property editor is
* used. Next it takes the type's classname and appends
* "Editor" to it, and searches first in the class's
- * package and then in the property editor search path.<P>
+ * package and then in the property editor search path.
*
- * Default property editors are provided for:<P>
- * <OL>
- * <LI>boolean, byte, short, int, long, float, and double</LI>
- * <LI>java.lang.String</LI>
- * <LI>java.awt.Color</LI>
- * <LI>java.awt.Font</LI>
- * <OL>
+ * <p>Default property editors are provided for:</p>
+ *
+ * <ol>
+ * <li>boolean, byte, short, int, long, float, and double</li>
+ * <li>java.lang.String</li>
+ * <li>java.awt.Color</li>
+ * <li>java.awt.Font</li>
+ * </ol>
*
- * <STRONG>Spec Suggestion:</STRONG> Perhaps an editor for
+ * <p><strong>Spec Suggestion:</strong> Perhaps an editor for
* Filename or something like it should be provided. As well
- * as char.
+ * as char.</p>
*
* @author John Keiser
* @since 1.1
diff --git a/libjava/java/beans/beancontext/BeanContextServiceProvider.java b/libjava/java/beans/beancontext/BeanContextServiceProvider.java
index de9c7de8f6e..cc2c935b382 100644
--- a/libjava/java/beans/beancontext/BeanContextServiceProvider.java
+++ b/libjava/java/beans/beancontext/BeanContextServiceProvider.java
@@ -62,14 +62,12 @@ import java.util.Iterator;
public interface BeanContextServiceProvider {
/**
* Get a service.
- * Called from <code>BeanContextServices.getService().
- * <P>
+ * Called from <code>BeanContextServices.getService()</code>.
*
- * If the requested service class is not available, or if this
+ * <p>If the requested service class is not available, or if this
* <code>BeanContextServiceProvider</code> chooses not honor the
* request for some reason, then this method will return
- * <code>null</code>.
- * <P>
+ * <code>null</code>.</p>
*
* This method may throw unchecked exceptions, so watch out.
*
diff --git a/libjava/java/io/BufferedReader.java b/libjava/java/io/BufferedReader.java
index 9175d4e89f9..444b66de408 100644
--- a/libjava/java/io/BufferedReader.java
+++ b/libjava/java/io/BufferedReader.java
@@ -533,12 +533,13 @@ public class BufferedReader extends Reader
// skip the '\n' for us). By doing this, we'll have to back up pos.
// That's easier than trying to keep track of whether we've skipped
// one element or not.
- int ch;
if (pos > limit)
- if ((ch = read()) < 0)
- return 0;
- else
- --pos;
+ {
+ if (read() < 0)
+ return 0;
+ else
+ --pos;
+ }
int avail = limit - pos;
diff --git a/libjava/java/io/BufferedWriter.java b/libjava/java/io/BufferedWriter.java
index b35ca6ea390..009bdccc144 100644
--- a/libjava/java/io/BufferedWriter.java
+++ b/libjava/java/io/BufferedWriter.java
@@ -44,21 +44,44 @@ package java.io;
*/
/**
- * This class accumulates chars written in a buffer instead of immediately
- * writing the data to the underlying output sink. The chars are instead
- * as one large block when the buffer is filled, or when the stream is
- * closed or explicitly flushed. This mode operation can provide a more
- * efficient mechanism for writing versus doing numerous small unbuffered
- * writes.
- *
- * @author Aaron M. Renn (arenn@urbanophile.com)
- * @author Tom Tromey <tromey@cygnus.com>
- * @date September 25, 1998
- */
-
+ * This class accumulates chars written in a buffer instead of immediately
+ * writing the data to the underlying output sink. The chars are instead
+ * as one large block when the buffer is filled, or when the stream is
+ * closed or explicitly flushed. This mode operation can provide a more
+ * efficient mechanism for writing versus doing numerous small unbuffered
+ * writes.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @date September 25, 1998
+ */
public class BufferedWriter extends Writer
{
/**
+ * This is the default buffer size
+ */
+ private static final int DEFAULT_BUFFER_SIZE = 8192;
+
+ /**
+ * This is the underlying <code>Writer</code> to which this object
+ * sends its output.
+ */
+ private Writer out;
+
+ /**
+ * This is the internal char array used for buffering output before
+ * writing it.
+ */
+ char[] buffer;
+
+ /**
+ * This is the number of chars that are currently in the buffer and
+ * are waiting to be written to the underlying stream. It always points to
+ * the index into the buffer where the next char of data will be stored
+ */
+ int count;
+
+ /**
* This method initializes a new <code>BufferedWriter</code> instance
* that will write to the specified subordinate <code>Writer</code>
* and which will use a default buffer size of 8192 chars.
@@ -78,18 +101,20 @@ public class BufferedWriter extends Writer
* @param out The underlying <code>Writer</code> to write data to
* @param size The size of the internal buffer
*/
- public BufferedWriter (Writer ox, int size)
+ public BufferedWriter (Writer out, int size)
{
- super (ox);
- out = ox;
- buffer = new char[size];
- count = 0;
+ super(out);
+ this.out = out;
+ this.buffer = new char[size];
+ this.count = 0;
}
/**
* This method flushes any remaining buffered chars then closes the
* underlying output stream. Any further attempts to write to this stream
* may throw an exception
+ *
+ * @exception IOException If an error occurs.
*/
public void close () throws IOException
{
@@ -138,7 +163,7 @@ public class BufferedWriter extends Writer
* is filled as a result of this write request, it will be flushed to the
* underlying output stream.
*
- * @param b The char of data to be written, passed as an int
+ * @param oneChar The char of data to be written, passed as an int
*
* @exception IOException If an error occurs
*/
@@ -226,7 +251,7 @@ public class BufferedWriter extends Writer
}
// This should only be called with the lock held.
- private final void localFlush () throws IOException
+ private void localFlush () throws IOException
{
if (count > 0)
{
@@ -234,28 +259,4 @@ public class BufferedWriter extends Writer
count = 0;
}
}
-
- /**
- * This is the underlying <code>Writer</code> to which this object
- * sends its output.
- */
- private Writer out;
-
- /**
- * This is the internal char array used for buffering output before
- * writing it.
- */
- char[] buffer;
-
- /**
- * This is the number of chars that are currently in the buffer and
- * are waiting to be written to the underlying stream. It always points to
- * the index into the buffer where the next char of data will be stored
- */
- int count;
-
- /**
- * This is the default buffer size
- */
- private static final int DEFAULT_BUFFER_SIZE = 8192;
}
diff --git a/libjava/java/io/ByteArrayInputStream.java b/libjava/java/io/ByteArrayInputStream.java
index 6a5f2c61897..45a09a77b5d 100644
--- a/libjava/java/io/ByteArrayInputStream.java
+++ b/libjava/java/io/ByteArrayInputStream.java
@@ -83,7 +83,7 @@ public class ByteArrayInputStream extends InputStream
* bytes supplied to the reader. Please use caution in changing the
* contents of the buffer while this stream is open.
*
- * @param buf The byte array buffer this stream will read from.
+ * @param buffer The byte array buffer this stream will read from.
*/
public ByteArrayInputStream(byte[] buffer)
{
@@ -105,7 +105,7 @@ public class ByteArrayInputStream extends InputStream
* bytes supplied to the reader. Please use caution in changing the
* contents of the buffer while this stream is open.
*
- * @param buf The byte array buffer this stream will read from.
+ * @param buffer The byte array buffer this stream will read from.
* @param offset The index into the buffer to start reading bytes from
* @param length The number of bytes to read from the buffer
*/
@@ -146,12 +146,12 @@ public class ByteArrayInputStream extends InputStream
* position 0 in the stream. This is in constrast to some other
* stream types where there is no default mark position.
*
- * @param readlimit The number of bytes this stream must remember.
+ * @param readLimit The number of bytes this stream must remember.
* This parameter is ignored.
*/
- public synchronized void mark(int readAheadLimit)
+ public synchronized void mark(int readLimit)
{
- // readAheadLimit is ignored per Java Class Lib. book, p.220.
+ // readLimit is ignored per Java Class Lib. book, p.220.
mark = pos;
}
@@ -197,19 +197,19 @@ public class ByteArrayInputStream extends InputStream
* <p>
* This method does not block.
*
- * @param buf The array into which the bytes read should be stored.
+ * @param buffer The array into which the bytes read should be stored.
* @param offset The offset into the array to start storing bytes
- * @param len The requested number of bytes to read
+ * @param length The requested number of bytes to read
*
* @return The actual number of bytes read, or -1 if end of stream.
*/
- public synchronized int read(byte[] b, int off, int len)
+ public synchronized int read(byte[] buffer, int offset, int length)
{
if (pos >= count)
return -1;
- int numBytes = Math.min(count - pos, len);
- System.arraycopy(buf, pos, b, off, numBytes);
+ int numBytes = Math.min(count - pos, length);
+ System.arraycopy(buf, pos, buffer, offset, numBytes);
pos += numBytes;
return numBytes;
}
@@ -234,17 +234,17 @@ public class ByteArrayInputStream extends InputStream
* position the stream at the end of the buffer. The actual number
* of bytes skipped is returned.
*
- * @param num_bytes The requested number of bytes to skip
+ * @param num The requested number of bytes to skip
*
* @return The actual number of bytes skipped.
*/
- public synchronized long skip(long n)
+ public synchronized long skip(long num)
{
// Even though the var numBytes is a long, in reality it can never
// be larger than an int since the result of subtracting 2 positive
// ints will always fit in an int. Since we have to return a long
// anyway, numBytes might as well just be a long.
- long numBytes = Math.min((long) (count - pos), n < 0 ? 0L : n);
+ long numBytes = Math.min((long) (count - pos), num < 0 ? 0L : num);
pos += numBytes;
return numBytes;
}
diff --git a/libjava/java/io/CharArrayWriter.java b/libjava/java/io/CharArrayWriter.java
index e9413f04072..106fd9ee2df 100644
--- a/libjava/java/io/CharArrayWriter.java
+++ b/libjava/java/io/CharArrayWriter.java
@@ -50,8 +50,8 @@ package java.io;
* following two properties:
* <p>
* <ul>
- * <li><xmp>gnu.java.io.CharArrayWriter.initialBufferSize</xmp>
- * <li><xmp>gnu.java.io.CharArrayWriter.bufferIncrementSize</xmp>
+ * <li><xmp>gnu.java.io.CharArrayWriter.initialBufferSize</xmp></li>
+ * <li><xmp>gnu.java.io.CharArrayWriter.bufferIncrementSize</xmp></li>
* </ul>
* <p>
* There is a constructor that specified the initial buffer size and
diff --git a/libjava/java/io/DataInput.java b/libjava/java/io/DataInput.java
index 2d92006618a..52cd246110d 100644
--- a/libjava/java/io/DataInput.java
+++ b/libjava/java/io/DataInput.java
@@ -360,7 +360,7 @@ public interface DataInput
* patterns which indicate a two byte character encoding, then they would be
* converted to a Java <code>char</code> like so:
* <p>
- * <code>(char)(((byte1 & 0x1F) << 6) + (byte2 & 0x3F))</code>
+ * <code>(char)(((byte1 &amp; 0x1F) &lt;&lt; 6) + (byte2 &amp; 0x3F))</code>
* <p>
* If the first byte has a 1110 as its high order bits, then the
* character consists of three bytes. The bits that make up the character
@@ -375,19 +375,19 @@ public interface DataInput
* then they would be converted to a Java <code>char</code> like so:
*
* <code>
- * (char)(((byte1 & 0x0F) << 12) + ((byte2 & 0x3F) + (byte3 & 0x3F))
+ * (char)(((byte1 &amp; 0x0F) &lt;&lt; 12) + ((byte2 &amp; 0x3F) + (byte3 &amp; 0x3F))
* </code>
*
* Note that all characters are encoded in the method that requires the
* fewest number of bytes with the exception of the character with the
- * value of <code>\<llll>u0000</code> which is encoded as two bytes.
+ * value of <code>\&lt;llll&gt;u0000</code> which is encoded as two bytes.
* This is a modification of the UTF standard used to prevent C language
* style <code>NUL</code> values from appearing in the byte stream.
* <p>
* This method can read data that was written by an object implementing the
* <code>writeUTF()</code> method in <code>DataOutput</code>.
*
- * @returns The <code>String</code> read
+ * @return The <code>String</code> read
*
* @exception EOFException If end of file is reached before reading the
* String
diff --git a/libjava/java/io/DataInputStream.java b/libjava/java/io/DataInputStream.java
index 6b4b1d74ead..b33cbe756ba 100644
--- a/libjava/java/io/DataInputStream.java
+++ b/libjava/java/io/DataInputStream.java
@@ -277,16 +277,16 @@ public class DataInputStream extends FilterInputStream implements DataInput
* buffer
* @exception IOException If any other error occurs
*/
- public final void readFully (byte[] b, int off, int len) throws IOException
+ public final void readFully (byte[] buf, int offset, int len) throws IOException
{
while (len > 0)
{
// in.read will block until some data is available.
- int numread = in.read (b, off, len);
+ int numread = in.read (buf, offset, len);
if (numread < 0)
throw new EOFException ();
len -= numread;
- off += numread;
+ offset += numread;
}
}
diff --git a/libjava/java/io/File.java b/libjava/java/io/File.java
index b4951ecc806..53ae529c6fe 100644
--- a/libjava/java/io/File.java
+++ b/libjava/java/io/File.java
@@ -1,5 +1,6 @@
/* File.java -- Class representing a file on disk
- Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004
+ Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -121,7 +122,7 @@ public class File implements Serializable, Comparable
{
if (Configuration.INIT_LOAD_LIBRARY)
{
- System.loadLibrary ("javaio");
+ System.loadLibrary("javaio");
}
init_native();
@@ -187,7 +188,7 @@ public class File implements Serializable, Comparable
* the path of this <code>File</code> object if an only if that file
* does not already exist.
* <p>
- * A <code>SecurityManager</code>checkWrite</code> check is done prior
+ * A <code>SecurityManager.checkWrite</code> check is done prior
* to performing this action.
*
* @return <code>true</code> if the file was created, <code>false</code> if
@@ -224,7 +225,7 @@ public class File implements Serializable, Comparable
SecurityManager s = System.getSecurityManager();
if (s != null)
- s.checkDelete (path);
+ s.checkDelete(path);
return performDelete();
}
@@ -244,7 +245,7 @@ public class File implements Serializable, Comparable
* @return <code>true</code> if the two objects are equal,
* <code>false</code> otherwise.
*/
- public boolean equals (Object obj)
+ public boolean equals(Object obj)
{
if (! (obj instanceof File))
return false;
@@ -252,9 +253,9 @@ public class File implements Serializable, Comparable
File other = (File) obj;
if (caseSensitive)
- return path.equals (other.path);
+ return path.equals(other.path);
else
- return path.equalsIgnoreCase (other.path);
+ return path.equalsIgnoreCase(other.path);
}
/**
@@ -277,7 +278,7 @@ public class File implements Serializable, Comparable
*
* @param name The path name of the file
*/
- public File (String name)
+ public File(String name)
{
path = normalizePath (name);
}
@@ -354,7 +355,7 @@ public class File implements Serializable, Comparable
* @param dirPath The path to the directory the file resides in
* @param name The name of the file
*/
- public File (String dirPath, String name)
+ public File(String dirPath, String name)
{
if (name == null)
throw new NullPointerException();
@@ -381,7 +382,7 @@ public class File implements Serializable, Comparable
* @param directory The directory this file resides in
* @param name The name of the file
*/
- public File (File directory, String name)
+ public File(File directory, String name)
{
this (directory == null ? null : directory.path, name);
}
@@ -448,7 +449,7 @@ public class File implements Serializable, Comparable
*/
public File getAbsoluteFile()
{
- return new File (getAbsolutePath());
+ return new File(getAbsolutePath());
}
/**
@@ -479,7 +480,7 @@ public class File implements Serializable, Comparable
*/
public File getCanonicalFile() throws IOException
{
- return new File (getCanonicalPath());
+ return new File(getCanonicalPath());
}
/**
@@ -591,7 +592,7 @@ public class File implements Serializable, Comparable
public File getParentFile()
{
String parent = getParent();
- return parent != null ? new File (parent) : null;
+ return parent != null ? new File(parent) : null;
}
/**
@@ -748,7 +749,7 @@ public class File implements Serializable, Comparable
* @exception SecurityException If read access is not allowed to the
* directory by the <code>SecurityManager</code>
*/
- public String[] list (FilenameFilter filter)
+ public String[] list(FilenameFilter filter)
{
checkRead();
return (String[]) performList (filter, null, String.class);
@@ -826,7 +827,7 @@ public class File implements Serializable, Comparable
*
* @since 1.2
*/
- public File[] listFiles (FilenameFilter filter)
+ public File[] listFiles(FilenameFilter filter)
{
checkRead();
return (File[]) performList (filter, null, File.class);
@@ -856,7 +857,7 @@ public class File implements Serializable, Comparable
*
* @since 1.2
*/
- public File[] listFiles (FileFilter filter)
+ public File[] listFiles(FileFilter filter)
{
checkRead();
return (File[]) performList (null, filter, File.class);
@@ -982,8 +983,8 @@ public class File implements Serializable, Comparable
*
* @since 1.2
*/
- public static File createTempFile (String prefix, String suffix,
- File directory)
+ public static File createTempFile(String prefix, String suffix,
+ File directory)
throws IOException
{
// Grab the system temp directory if necessary
@@ -1005,7 +1006,7 @@ public class File implements Serializable, Comparable
// Check if prefix is at least 3 characters long
if (prefix.length() < 3)
- throw new IllegalArgumentException ("Prefix too short: " + prefix);
+ throw new IllegalArgumentException("Prefix too short: " + prefix);
// Set default value of suffix
if (suffix == null)
@@ -1146,10 +1147,10 @@ public class File implements Serializable, Comparable
* this operation
* @exception IOException If an error occurs
*/
- public static File createTempFile (String prefix, String suffix)
+ public static File createTempFile(String prefix, String suffix)
throws IOException
{
- return createTempFile (prefix, suffix, null);
+ return createTempFile(prefix, suffix, null);
}
/**
@@ -1168,7 +1169,7 @@ public class File implements Serializable, Comparable
*
* @since 1.2
*/
- public int compareTo (File other)
+ public int compareTo(File other)
{
if (caseSensitive)
return path.compareTo (other.path);
@@ -1197,9 +1198,9 @@ public class File implements Serializable, Comparable
*
* @since 1.2
*/
- public int compareTo (Object obj)
+ public int compareTo(Object obj)
{
- return compareTo ((File) obj);
+ return compareTo((File) obj);
}
/*
@@ -1219,7 +1220,7 @@ public class File implements Serializable, Comparable
* @exception SecurityException If write access is not allowed to the
* file by the <code>SecurityMananger</code>.
*/
- public synchronized boolean renameTo (File dest)
+ public synchronized boolean renameTo(File dest)
{
SecurityManager s = System.getSecurityManager();
String sname = getName();
@@ -1253,7 +1254,7 @@ public class File implements Serializable, Comparable
*
* @since 1.2
*/
- public boolean setLastModified (long time)
+ public boolean setLastModified(long time)
{
if (time < 0)
throw new IllegalArgumentException("Negative modification time: " + time);
@@ -1268,7 +1269,7 @@ public class File implements Serializable, Comparable
SecurityManager s = System.getSecurityManager();
if (s != null)
- s.checkWrite (path);
+ s.checkWrite(path);
}
private void checkRead()
@@ -1277,7 +1278,7 @@ public class File implements Serializable, Comparable
SecurityManager s = System.getSecurityManager();
if (s != null)
- s.checkRead (path);
+ s.checkRead(path);
}
/**
@@ -1299,13 +1300,13 @@ public class File implements Serializable, Comparable
FileDeleter.add (this);
}
- private void writeObject (ObjectOutputStream oos) throws IOException
+ private void writeObject(ObjectOutputStream oos) throws IOException
{
oos.defaultWriteObject();
- oos.writeChar (separatorChar);
+ oos.writeChar(separatorChar);
}
- private void readObject (ObjectInputStream ois)
+ private void readObject(ObjectInputStream ois)
throws ClassNotFoundException, IOException
{
ois.defaultReadObject();
@@ -1315,7 +1316,7 @@ public class File implements Serializable, Comparable
char oldSeparatorChar = ois.readChar();
if (oldSeparatorChar != separatorChar)
- path = path.replace (oldSeparatorChar, separatorChar);
+ path = path.replace(oldSeparatorChar, separatorChar);
}
} // class File
diff --git a/libjava/java/io/FileDescriptor.java b/libjava/java/io/FileDescriptor.java
index be86593e76d..35a478509fc 100644
--- a/libjava/java/io/FileDescriptor.java
+++ b/libjava/java/io/FileDescriptor.java
@@ -83,6 +83,14 @@ public final class FileDescriptor
/**
* This method is used to initialize an invalid FileDescriptor object.
*/
+ public FileDescriptor()
+ {
+ channel = null;
+ }
+
+ /**
+ * This method is used to initialize a FileDescriptor object.
+ */
FileDescriptor(ByteChannel channel)
{
this.channel = channel;
@@ -125,6 +133,6 @@ public final class FileDescriptor
*/
public boolean valid ()
{
- return channel.isOpen();
+ return channel != null && channel.isOpen();
}
}
diff --git a/libjava/java/io/FileOutputStream.java b/libjava/java/io/FileOutputStream.java
index a8c4b765ed2..8942871e43a 100644
--- a/libjava/java/io/FileOutputStream.java
+++ b/libjava/java/io/FileOutputStream.java
@@ -81,13 +81,7 @@ public class FileOutputStream extends OutputStream
public FileOutputStream (String path, boolean append)
throws SecurityException, FileNotFoundException
{
- SecurityManager s = System.getSecurityManager();
- if (s != null)
- s.checkWrite(path);
- ch = new FileChannelImpl (path, (append
- ? FileChannelImpl.WRITE
- | FileChannelImpl.APPEND
- : FileChannelImpl.WRITE));
+ this (new File(path), append);
}
/**
@@ -130,7 +124,7 @@ public class FileOutputStream extends OutputStream
public FileOutputStream (File file)
throws SecurityException, FileNotFoundException
{
- this (file.getPath(), false);
+ this (file, false);
}
/**
@@ -156,7 +150,17 @@ public class FileOutputStream extends OutputStream
public FileOutputStream (File file, boolean append)
throws FileNotFoundException
{
- this (file.getPath(), append);
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkWrite(file.getPath());
+
+ if (file.isDirectory())
+ throw new FileNotFoundException(file.getPath() + " is a directory");
+
+ ch = new FileChannelImpl (file.getPath(), (append
+ ? FileChannelImpl.WRITE
+ | FileChannelImpl.APPEND
+ : FileChannelImpl.WRITE));
}
/**
diff --git a/libjava/java/io/FilePermission.java b/libjava/java/io/FilePermission.java
index a26f8c70f87..c34a2ecf9b2 100644
--- a/libjava/java/io/FilePermission.java
+++ b/libjava/java/io/FilePermission.java
@@ -229,7 +229,6 @@ public final class FilePermission extends Permission implements Serializable
return false;
/* Make sure there are no subdirectories specified
underneath this one */
- String sub2 = f2.substring(sub1.length()+1);
if(f2.substring(sub1.length()+1).indexOf(File.separatorChar)
!= -1)
return false;
diff --git a/libjava/java/io/FilterInputStream.java b/libjava/java/io/FilterInputStream.java
index fe45d33e368..c81259bd25b 100644
--- a/libjava/java/io/FilterInputStream.java
+++ b/libjava/java/io/FilterInputStream.java
@@ -104,7 +104,7 @@ public class FilterInputStream extends InputStream
*/
public boolean markSupported()
{
- return(in.markSupported());
+ return in.markSupported();
}
/**
@@ -126,7 +126,7 @@ public class FilterInputStream extends InputStream
*/
public int available() throws IOException
{
- return(in.available());
+ return in.available();
}
/**
@@ -138,9 +138,9 @@ public class FilterInputStream extends InputStream
*
* @exception IOException If an error occurs
*/
- public long skip(long num_bytes) throws IOException
+ public long skip(long numBytes) throws IOException
{
- return(in.skip(num_bytes));
+ return in.skip(numBytes);
}
/**
@@ -152,7 +152,7 @@ public class FilterInputStream extends InputStream
*/
public int read() throws IOException
{
- return(in.read());
+ return in.read();
}
/**
@@ -170,7 +170,7 @@ public class FilterInputStream extends InputStream
*/
public int read(byte[] buf) throws IOException
{
- return(read(buf, 0, buf.length));
+ return read(buf, 0, buf.length);
}
/**
@@ -186,7 +186,7 @@ public class FilterInputStream extends InputStream
*/
public int read(byte[] buf, int offset, int len) throws IOException
{
- return(in.read(buf, offset, len));
+ return in.read(buf, offset, len);
}
/**
@@ -200,6 +200,4 @@ public class FilterInputStream extends InputStream
{
in.close();
}
-
-} // class FilterInputStream
-
+}
diff --git a/libjava/java/io/InputStream.java b/libjava/java/io/InputStream.java
index 34068c628bb..610ccf1f177 100644
--- a/libjava/java/io/InputStream.java
+++ b/libjava/java/io/InputStream.java
@@ -105,7 +105,7 @@ public abstract class InputStream
* @param readLimit The number of bytes that can be read before the
* mark becomes invalid
*/
- public void mark(int readlimit)
+ public void mark(int readLimit)
{
// Do nothing
}
@@ -117,7 +117,7 @@ public abstract class InputStream
* point.
* <p>
* This method always returns <code>false</code> in this class, but
- * subclasses can override this method to return </code>true</code>
+ * subclasses can override this method to return <code>true</code>
* if they support mark/reset functionality.
*
* @return <code>true</code> if mark/reset functionality is
diff --git a/libjava/java/io/InputStreamReader.java b/libjava/java/io/InputStreamReader.java
index 07be132510b..3ebbb4ec9e4 100644
--- a/libjava/java/io/InputStreamReader.java
+++ b/libjava/java/io/InputStreamReader.java
@@ -56,18 +56,18 @@ import gnu.gcj.convert.*;
* Here is a list of standard encoding names that may be available:
* <p>
* <ul>
- * <li>8859_1 (ISO-8859-1/Latin-1)
- * <li>8859_2 (ISO-8859-2/Latin-2)
- * <li>8859_3 (ISO-8859-3/Latin-3)
- * <li>8859_4 (ISO-8859-4/Latin-4)
- * <li>8859_5 (ISO-8859-5/Latin-5)
- * <li>8859_6 (ISO-8859-6/Latin-6)
- * <li>8859_7 (ISO-8859-7/Latin-7)
- * <li>8859_8 (ISO-8859-8/Latin-8)
- * <li>8859_9 (ISO-8859-9/Latin-9)
- * <li>ASCII (7-bit ASCII)
- * <li>UTF8 (UCS Transformation Format-8)
- * <li>More later
+ * <li>8859_1 (ISO-8859-1/Latin-1)</li>
+ * <li>8859_2 (ISO-8859-2/Latin-2)</li>
+ * <li>8859_3 (ISO-8859-3/Latin-3)</li>
+ * <li>8859_4 (ISO-8859-4/Latin-4)</li>
+ * <li>8859_5 (ISO-8859-5/Latin-5)</li>
+ * <li>8859_6 (ISO-8859-6/Latin-6)</li>
+ * <li>8859_7 (ISO-8859-7/Latin-7)</li>
+ * <li>8859_8 (ISO-8859-8/Latin-8)</li>
+ * <li>8859_9 (ISO-8859-9/Latin-9)</li>
+ * <li>ASCII (7-bit ASCII)</li>
+ * <li>UTF8 (UCS Transformation Format-8)</li>
+ * <li>More later</li>
* </ul>
* <p>
* It is recommended that applications do not use
@@ -170,7 +170,7 @@ public class InputStreamReader extends Reader
* by this object. If the stream has been closed, this method is allowed
* to return <code>null</code>.
*
- * @param The current encoding name
+ * @return The current encoding name
*/
public String getEncoding()
{
@@ -296,5 +296,4 @@ public class InputStreamReader extends Reader
return count;
}
}
-} // class InputStreamReader
-
+}
diff --git a/libjava/java/io/ObjectInputStream.java b/libjava/java/io/ObjectInputStream.java
index 0c5b020bbab..304d0f576d1 100644
--- a/libjava/java/io/ObjectInputStream.java
+++ b/libjava/java/io/ObjectInputStream.java
@@ -38,23 +38,33 @@ exception statement from your version. */
package java.io;
+import gnu.classpath.Configuration;
+import gnu.java.io.ObjectIdentityWrapper;
+
import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
-import java.security.PrivilegedAction;
-import java.security.AccessController;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Vector;
-import gnu.java.io.ObjectIdentityWrapper;
-import gnu.java.lang.reflect.TypeSignature;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
-
-import gnu.classpath.Configuration;
+class MyIOException extends IOException
+{
+ MyIOException (String s)
+ {
+ super(s);
+ if (Configuration.DEBUG)
+ {
+ String val = System.getProperty("gcj.dumpobjects");
+ if (val != null && !val.equals(""))
+ System.out.println (this);
+ }
+ }
+}
public class ObjectInputStream extends InputStream
implements ObjectInput, ObjectStreamConstants
@@ -124,6 +134,15 @@ public class ObjectInputStream extends InputStream
*/
public final Object readObject() throws ClassNotFoundException, IOException
{
+ if (callersClassLoader == null)
+ {
+ callersClassLoader = getCallersClassLoader ();
+ if (Configuration.DEBUG)
+ {
+ dumpElementln ("CallersClassLoader = " + callersClassLoader);
+ }
+ }
+
if (this.useSubclassMethod)
return readObjectOverride();
@@ -138,6 +157,9 @@ public class ObjectInputStream extends InputStream
this.isDeserializing = true;
byte marker = this.realInputStream.readByte();
+
+ depth += 2;
+
if(dump) dumpElement("MARKER: 0x" + Integer.toHexString(marker) + " ");
try
@@ -155,9 +177,9 @@ public class ObjectInputStream extends InputStream
case TC_BLOCKDATALONG:
{
if (marker == TC_BLOCKDATALONG)
- if(dump) dumpElementln("BLOCKDATALONG");
+ { if(dump) dumpElementln("BLOCKDATALONG"); }
else
- if(dump) dumpElementln("BLOCKDATA");
+ { if(dump) dumpElementln("BLOCKDATA"); }
readNextBlock(marker);
throw new StreamCorruptedException("Unexpected blockData");
}
@@ -211,7 +233,7 @@ public class ObjectInputStream extends InputStream
{
byte b = this.realInputStream.readByte();
if (b != TC_ENDBLOCKDATA)
- throw new IOException("Data annotated to class was not consumed." + b);
+ throw new MyIOException("Data annotated to class was not consumed." + b);
}
else
is_consumed = false;
@@ -229,7 +251,7 @@ public class ObjectInputStream extends InputStream
{
byte b = this.realInputStream.readByte();
if (b != TC_ENDBLOCKDATA)
- throw new IOException("Data annotated to class was not consumed." + b);
+ throw new MyIOException("Data annotated to class was not consumed." + b);
}
else
is_consumed = false;
@@ -262,7 +284,7 @@ public class ObjectInputStream extends InputStream
readArrayElements(array, componentType);
if(dump)
for (int i = 0, len = Array.getLength(array); i < len; i++)
- dumpElementln(" ELEMENT[" + i + "]=" + Array.get(array, i));
+ dumpElementln(" ELEMENT[" + i + "]=" + Array.get(array, i));
ret_val = processResolution(null, array, handle);
break;
}
@@ -323,6 +345,9 @@ public class ObjectInputStream extends InputStream
Object obj = newObject(clazz, osc.firstNonSerializableParent);
int handle = assignNewHandle(obj);
+ Object prevObject = this.currentObject;
+ ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass;
+
this.currentObject = obj;
ObjectStreamClass[] hierarchy =
inputGetObjectStreamClasses(clazz);
@@ -345,34 +370,42 @@ public class ObjectInputStream extends InputStream
boolean oldmode = setBlockDataMode(true);
callReadMethod(readObjectMethod, this.currentObjectStreamClass.forClass(), obj);
setBlockDataMode(oldmode);
+ }
+ else
+ {
+ readFields(obj, currentObjectStreamClass);
+ }
+
+ if (this.currentObjectStreamClass.hasWriteMethod())
+ {
if(dump) dumpElement("ENDBLOCKDATA? ");
try
{
- // FIXME: XXX: This try block is to catch EOF which is
- // thrown for some objects. That indicates a bug in the logic.
+ // FIXME: XXX: This try block is to
+ // catch EOF which is thrown for some
+ // objects. That indicates a bug in
+ // the logic.
+
if (this.realInputStream.readByte() != TC_ENDBLOCKDATA)
- throw new IOException
+ throw new MyIOException
("No end of block data seen for class with readObject (ObjectInputStream) method.");
if(dump) dumpElementln("yes");
}
- catch (EOFException e)
- {
- if(dump) dumpElementln("no, got EOFException");
- }
+// catch (EOFException e)
+// {
+// if(dump) dumpElementln("no, got EOFException");
+// }
catch (IOException e)
{
if(dump) dumpElementln("no, got IOException");
}
}
- else
- {
- readFields(obj, currentObjectStreamClass);
- }
}
- this.currentObject = null;
- this.currentObjectStreamClass = null;
+ this.currentObject = prevObject;
+ this.currentObjectStreamClass = prevObjectStreamClass;
ret_val = processResolution(osc, obj, handle);
+
break;
}
@@ -392,7 +425,7 @@ public class ObjectInputStream extends InputStream
}
default:
- throw new IOException("Unknown marker on stream: " + marker);
+ throw new MyIOException("Unknown marker on stream: " + marker);
}
}
finally
@@ -400,6 +433,8 @@ public class ObjectInputStream extends InputStream
setBlockDataMode(old_mode);
this.isDeserializing = was_deserializing;
+
+ depth -= 2;
if (! was_deserializing)
{
@@ -714,7 +749,7 @@ public class ObjectInputStream extends InputStream
protected Class resolveClass(ObjectStreamClass osc)
throws ClassNotFoundException, IOException
{
- return Class.forName(osc.getName(), true, currentLoader());
+ return Class.forName(osc.getName(), true, callersClassLoader);
}
/**
@@ -1806,11 +1841,9 @@ public class ObjectInputStream extends InputStream
* @param sm SecurityManager instance which should be called.
* @return The current class loader in the calling stack.
*/
- private static ClassLoader currentClassLoader (SecurityManager sm)
- {
- // FIXME: This is too simple.
- return ClassLoader.getSystemClassLoader ();
- }
+ private static native ClassLoader currentClassLoader (SecurityManager sm);
+
+ private native ClassLoader getCallersClassLoader();
private void callReadMethod (Method readObject, Class klass, Object obj) throws IOException
{
@@ -1868,14 +1901,21 @@ public class ObjectInputStream extends InputStream
private static boolean dump = false && Configuration.DEBUG;
+ private ClassLoader callersClassLoader;
+
+ private int depth = 0;
+
private void dumpElement (String msg)
- {
+ {
System.out.print(msg);
}
private void dumpElementln (String msg)
{
System.out.println(msg);
+ for (int i = 0; i < depth; i++)
+ System.out.print (" ");
+ System.out.print (Thread.currentThread() + ": ");
}
static
diff --git a/libjava/java/io/ObjectOutputStream.java b/libjava/java/io/ObjectOutputStream.java
index b60f3b6a100..92fe64e28e7 100644
--- a/libjava/java/io/ObjectOutputStream.java
+++ b/libjava/java/io/ObjectOutputStream.java
@@ -172,10 +172,26 @@ public class ObjectOutputStream extends OutputStream
{
if (useSubclassMethod)
{
+ if (Configuration.DEBUG)
+ {
+ String val = System.getProperty("gcj.dumpobjects");
+ if (val != null && !val.equals(""))
+ dumpElementln ("WRITE OVERRIDE: " + obj);
+ }
+
writeObjectOverride(obj);
return;
}
+ if (Configuration.DEBUG)
+ {
+ String val = System.getProperty("gcj.dumpobjects");
+ if (val != null && !val.equals(""))
+ dumpElementln ("WRITE: " + obj);
+ }
+
+ depth += 2;
+
boolean was_serializing = isSerializing;
boolean old_mode = setBlockDataMode(false);
try
@@ -318,6 +334,8 @@ public class ObjectOutputStream extends OutputStream
if (obj instanceof Serializable)
{
+ Object prevObject = this.currentObject;
+ ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass;
currentObject = obj;
ObjectStreamClass[] hierarchy =
ObjectStreamClass.getObjectStreamClasses(clazz);
@@ -329,17 +347,22 @@ public class ObjectOutputStream extends OutputStream
fieldsAlreadyWritten = false;
if (currentObjectStreamClass.hasWriteMethod())
{
+ dumpElementln ("WRITE METHOD CALLED FOR: " + obj);
setBlockDataMode(true);
callWriteMethod(obj, currentObjectStreamClass);
setBlockDataMode(false);
realOutput.writeByte(TC_ENDBLOCKDATA);
+ dumpElementln ("WRITE ENDBLOCKDATA FOR: " + obj);
}
else
- writeFields(obj, currentObjectStreamClass);
+ {
+ dumpElementln ("WRITE FIELDS CALLED FOR: " + obj);
+ writeFields(obj, currentObjectStreamClass);
+ }
}
- currentObject = null;
- currentObjectStreamClass = null;
+ this.currentObject = prevObject;
+ this.currentObjectStreamClass = prevObjectStreamClass;
currentPutField = null;
break;
}
@@ -360,12 +383,22 @@ public class ObjectOutputStream extends OutputStream
setBlockDataMode(false);
try
{
+ if (Configuration.DEBUG)
+ {
+ e.printStackTrace(System.out);
+ }
writeObject(e);
}
catch (IOException ioe)
{
- throw new StreamCorruptedException
- ("Exception " + ioe + " thrown while exception was being written to stream.");
+ StreamCorruptedException ex =
+ new StreamCorruptedException
+ (ioe + " thrown while exception was being written to stream.");
+ if (Configuration.DEBUG)
+ {
+ ex.printStackTrace(System.out);
+ }
+ throw ex;
}
reset (true);
@@ -375,6 +408,15 @@ public class ObjectOutputStream extends OutputStream
{
isSerializing = was_serializing;
setBlockDataMode(old_mode);
+ depth -= 2;
+
+ if (Configuration.DEBUG)
+ {
+ String val = System.getProperty("gcj.dumpobjects");
+ if (val != null && !val.equals(""))
+ dumpElementln ("END: " + obj);
+ }
+
}
}
@@ -1171,6 +1213,14 @@ public class ObjectOutputStream extends OutputStream
field_name = fields[i].getName();
type = fields[i].getType();
+ if (Configuration.DEBUG)
+ {
+ String val = System.getProperty("gcj.dumpobjects");
+ if (val != null && !val.equals(""))
+ dumpElementln ("WRITE FIELD: " + field_name + " type=" + type);
+ }
+
+
if (type == Boolean.TYPE)
realOutput.writeBoolean(getBooleanField(obj, osc.forClass(), field_name));
else if (type == Byte.TYPE)
@@ -1512,6 +1562,14 @@ public class ObjectOutputStream extends OutputStream
return m;
}
+ private void dumpElementln (String msg)
+ {
+ for (int i = 0; i < depth; i++)
+ System.out.print (" ");
+ System.out.print (Thread.currentThread() + ": ");
+ System.out.println(msg);
+ }
+
// this value comes from 1.2 spec, but is used in 1.1 as well
private final static int BUFFER_SIZE = 1024;
@@ -1534,6 +1592,8 @@ public class ObjectOutputStream extends OutputStream
private int protocolVersion;
private boolean useSubclassMethod;
+ private int depth = 0;
+
static
{
if (Configuration.INIT_LOAD_LIBRARY)
diff --git a/libjava/java/io/ObjectStreamClass.java b/libjava/java/io/ObjectStreamClass.java
index d080f280ba9..ee23f5996b5 100644
--- a/libjava/java/io/ObjectStreamClass.java
+++ b/libjava/java/io/ObjectStreamClass.java
@@ -104,17 +104,17 @@ public class ObjectStreamClass implements Serializable
}
}
-
/**
* Returns the name of the class that this
* <code>ObjectStreamClass</code> represents.
+ *
+ * @return the name of the class.
*/
public String getName()
{
return name;
}
-
/**
* Returns the class that this <code>ObjectStreamClass</code>
* represents. Null could be returned if this
@@ -129,24 +129,27 @@ public class ObjectStreamClass implements Serializable
return clazz;
}
-
/**
* Returns the serial version stream-unique identifier for the class
* represented by this <code>ObjectStreamClass</code>. This SUID is
* either defined by the class as <code>static final long
* serialVersionUID</code> or is calculated as specified in
* Javasoft's "Object Serialization Specification" XXX: add reference
+ *
+ * @return the serial version UID.
*/
public long getSerialVersionUID()
{
return uid;
}
-
- // Returns the serializable (non-static and non-transient) Fields
- // of the class represented by this ObjectStreamClass. The Fields
- // are sorted by name.
- // XXX doc
+ /**
+ * Returns the serializable (non-static and non-transient) Fields
+ * of the class represented by this ObjectStreamClass. The Fields
+ * are sorted by name.
+ *
+ * @return the fields.
+ */
public ObjectStreamField[] getFields()
{
ObjectStreamField[] copy = new ObjectStreamField[ fields.length ];
@@ -154,7 +157,6 @@ public class ObjectStreamClass implements Serializable
return copy;
}
-
// XXX doc
// Can't do binary search since fields is sorted by name and
// primitiveness.
@@ -166,7 +168,6 @@ public class ObjectStreamClass implements Serializable
return null;
}
-
/**
* Returns a textual representation of this
* <code>ObjectStreamClass</code> object including the name of the
@@ -181,7 +182,6 @@ public class ObjectStreamClass implements Serializable
return "java.io.ObjectStreamClass< " + name + ", " + uid + " >";
}
-
// Returns true iff the class that this ObjectStreamClass represents
// has the following method:
//
diff --git a/libjava/java/io/PipedInputStream.java b/libjava/java/io/PipedInputStream.java
index bf7730a85c4..91fca676fd9 100644
--- a/libjava/java/io/PipedInputStream.java
+++ b/libjava/java/io/PipedInputStream.java
@@ -277,7 +277,7 @@ public class PipedInputStream extends InputStream
* @param offset The index into the buffer at which to start writing.
* @param len The maximum number of bytes to read.
*
- * @exception IOException If <code>close()/code> was called on this Piped
+ * @exception IOException If <code>close()</code> was called on this Piped
* InputStream.
*/
public synchronized int read(byte[] buf, int offset, int len)
diff --git a/libjava/java/io/PipedReader.java b/libjava/java/io/PipedReader.java
index ec135427d09..3991ba94e45 100644
--- a/libjava/java/io/PipedReader.java
+++ b/libjava/java/io/PipedReader.java
@@ -256,7 +256,7 @@ public class PipedReader extends Reader
* @param offset The index into the buffer at which to start writing.
* @param len The maximum number of chars to read.
*
- * @exception IOException If <code>close()/code> was called on this Piped
+ * @exception IOException If <code>close()</code> was called on this Piped
* Reader.
*/
public int read(char[] buf, int offset, int len)
diff --git a/libjava/java/io/PushbackInputStream.java b/libjava/java/io/PushbackInputStream.java
index 778babd2c0b..379677d6613 100644
--- a/libjava/java/io/PushbackInputStream.java
+++ b/libjava/java/io/PushbackInputStream.java
@@ -263,7 +263,7 @@ public class PushbackInputStream extends FilterInputStream
/**
* This method pushed back bytes from the passed in array into the
* pushback buffer. The bytes from <code>b[offset]</code> to
- * <cdoe>b[offset + len]</code> are pushed in reverse order so that
+ * <code>b[offset + len]</code> are pushed in reverse order so that
* the next byte read from the stream after this operation will be
* <code>b[offset]</code> followed by <code>b[offset + 1]</code>,
* etc.
diff --git a/libjava/java/io/PushbackReader.java b/libjava/java/io/PushbackReader.java
index 4b442e52c6f..cc2473a6c34 100644
--- a/libjava/java/io/PushbackReader.java
+++ b/libjava/java/io/PushbackReader.java
@@ -266,33 +266,34 @@ public class PushbackReader extends FilterReader
* of the chars requested, the remaining chars are read from the
* underlying stream.
*
- * @param buf The array into which the chars read should be stored
+ * @param buffer The array into which the chars read should be stored
* @param offset The offset into the array to start storing chars
- * @param len The requested number of chars to read
+ * @param length The requested number of chars to read
*
* @return The actual number of chars read, or -1 if end of stream.
*
* @exception IOException If an error occurs.
*/
- public synchronized int read(char[] b, int offset, int len) throws IOException
+ public synchronized int read(char[] buffer, int offset, int length)
+ throws IOException
{
synchronized (lock)
{
if (buf == null)
throw new IOException("stream closed");
- if (offset < 0 || len < 0 || offset + len > b.length)
+ if (offset < 0 || length < 0 || offset + length > buffer.length)
throw new ArrayIndexOutOfBoundsException();
- int numBytes = Math.min(buf.length - pos, len);
+ int numBytes = Math.min(buf.length - pos, length);
if (numBytes > 0)
{
- System.arraycopy (buf, pos, b, offset, numBytes);
+ System.arraycopy (buf, pos, buffer, offset, numBytes);
pos += numBytes;
return numBytes;
}
- return super.read(b, offset, len);
+ return super.read(buffer, offset, length);
}
}
@@ -353,30 +354,30 @@ public class PushbackReader extends FilterReader
* If the pushback buffer cannot hold all of the requested chars, an
* exception is thrown.
*
- * @param buf The char array to be pushed back
+ * @param buffer The char array to be pushed back
* @param offset The index into the array where the chars to be push start
- * @param len The number of chars to be pushed.
+ * @param length The number of chars to be pushed.
*
* @exception IOException If the pushback buffer is full
*/
- public synchronized void unread(char[] b, int offset, int len)
+ public synchronized void unread(char[] buffer, int offset, int length)
throws IOException
{
synchronized (lock)
{
if (buf == null)
throw new IOException("stream closed");
- if (pos < len)
+ if (pos < length)
throw new IOException("Pushback buffer is full");
// Note the order that these chars are being added is the opposite
// of what would be done if they were added to the buffer one at a time.
// See the Java Class Libraries book p. 1397.
- System.arraycopy(b, offset, buf, pos - len, len);
+ System.arraycopy(buffer, offset, buf, pos - length, length);
// Don't put this into the arraycopy above, an exception might be thrown
// and in that case we don't want to modify pos.
- pos -= len;
+ pos -= length;
}
}
}
diff --git a/libjava/java/io/RandomAccessFile.java b/libjava/java/io/RandomAccessFile.java
index f79c624755c..c20549c12df 100644
--- a/libjava/java/io/RandomAccessFile.java
+++ b/libjava/java/io/RandomAccessFile.java
@@ -318,12 +318,12 @@ public class RandomAccessFile implements DataOutput, DataInput
* significant byte first (i.e., "big endian") regardless of the native
* host byte ordering.
* <p>
- * As an example, if <code>byte1</code> and code{byte2</code> represent
+ * As an example, if <code>byte1</code> and <code>byte2</code> represent
* the first
* and second byte read from the stream respectively, they will be
* transformed to a <code>char</code> in the following manner:
* <p>
- * <code>(char)(((byte1 & 0xFF) << 8) | (byte2 & 0xFF)</code>
+ * <code>(char)(((byte1 &amp; 0xFF) &lt;&lt; 8) | (byte2 &amp; 0xFF)</code>
* <p>
* This method can read a <code>char</code> written by an object
* implementing the
@@ -539,12 +539,12 @@ public class RandomAccessFile implements DataOutput, DataInput
* significant byte first (i.e., "big endian") regardless of the native
* host byte ordering.
* <p>
- * As an example, if <code>byte1</code> and code{byte2</code>
+ * As an example, if <code>byte1</code> and <code>byte2</code>
* represent the first
* and second byte read from the stream respectively, they will be
* transformed to a <code>short</code> in the following manner:
* <p>
- * <code>(short)(((byte1 & 0xFF) << 8) | (byte2 & 0xFF)</code>
+ * <code>(short)(((byte1 &amp; 0xFF) &lt;&lt; 8) | (byte2 &amp; 0xFF)</code>
* <p>
* The value returned is in the range of -32768 to 32767.
* <p>
diff --git a/libjava/java/io/SerializablePermission.java b/libjava/java/io/SerializablePermission.java
index d27dcf42667..1d2636bc19b 100644
--- a/libjava/java/io/SerializablePermission.java
+++ b/libjava/java/io/SerializablePermission.java
@@ -48,9 +48,9 @@ import java.security.BasicPermission;
* There are currently two allowable permission names for this class:
* <ul>
* <li><code>enableSubclassImplementation</code> - Allows a subclass to
- * override the default serialization behavior of objects.
+ * override the default serialization behavior of objects.</li>
* <li><code>enableSubstitution</code> - Allows substitution of one object
- * for another during serialization or deserialization.
+ * for another during serialization or deserialization.</li>
* </ul>
*
* @see java.security.BasicPermission
diff --git a/libjava/java/io/StreamTokenizer.java b/libjava/java/io/StreamTokenizer.java
index a77b699ff17..5c777b3723c 100644
--- a/libjava/java/io/StreamTokenizer.java
+++ b/libjava/java/io/StreamTokenizer.java
@@ -73,12 +73,12 @@ public class StreamTokenizer
* The rules are as follows:
* <ul>
* <li>For a token consisting of a single ordinary character, this is the
- * value of that character.
- * <li>For a quoted string, this is the value of the quote character
- * <li>For a word, this is TT_WORD
- * <li>For a number, this is TT_NUMBER
- * <li>For the end of the line, this is TT_EOL
- * <li>For the end of the stream, this is TT_EOF
+ * value of that character.</li>
+ * <li>For a quoted string, this is the value of the quote character</li>
+ * <li>For a word, this is TT_WORD</li>
+ * <li>For a number, this is TT_NUMBER</li>
+ * <li>For the end of the line, this is TT_EOL</li>
+ * <li>For the end of the stream, this is TT_EOF</li>
* </ul>
*/
public int ttype = TT_NONE;
@@ -141,13 +141,13 @@ public class StreamTokenizer
* following manner:
* <ul>
* <li>The values 'A' through 'Z', 'a' through 'z' and 0xA0 through 0xFF
- * are initialized as alphabetic
- * <li>The values 0x00 through 0x20 are initialized as whitespace
- * <li>The values '\'' and '"' are initialized as quote characters
- * <li>'/' is a comment character
- * <li>Numbers will be parsed
- * <li>EOL is not treated as significant
- * <li>C and C++ (//) comments are not recognized
+ * are initialized as alphabetic</li>
+ * <li>The values 0x00 through 0x20 are initialized as whitespace</li>
+ * <li>The values '\'' and '"' are initialized as quote characters</li>
+ * <li>'/' is a comment character</li>
+ * <li>Numbers will be parsed</li>
+ * <li>EOL is not treated as significant</li>
+ * <li>C and C++ (//) comments are not recognized</li>
* </ul>
*
* @param in The <code>Reader</code> to read chars from
@@ -251,13 +251,13 @@ public class StreamTokenizer
* returns it. It also can set <code>sval</code> or <code>nval</code>
* as described below. The parsing strategy is as follows:
* <ul>
- * <li>Skip any whitespace characters.
+ * <li>Skip any whitespace characters.</li>
* <li>If a numeric character is encountered, attempt to parse a numeric
* value. Leading '-' characters indicate a numeric only if followed by
* another non-'-' numeric. The value of the numeric token is terminated
* by either the first non-numeric encountered, or the second occurrence of
* '-' or '.'. The token type returned is TT_NUMBER and <code>nval</code>
- * is set to the value parsed.
+ * is set to the value parsed.</li>
* <li>If an alphabetic character is parsed, all subsequent characters
* are read until the first non-alphabetic or non-numeric character is
* encountered. The token type returned is TT_WORD and the value parsed
@@ -266,10 +266,10 @@ public class StreamTokenizer
* sequence terminates a word only if EOL signficance has been turned on.
* The start of a comment also terminates a word. Any character with a
* non-alphabetic and non-numeric attribute (such as white space, a quote,
- * or a commet) are treated as non-alphabetic and terminate the word.
+ * or a commet) are treated as non-alphabetic and terminate the word.</li>
* <li>If a comment character is parsed, then all remaining characters on
* the current line are skipped and another token is parsed. Any EOL or
- * EOF's encountered are not discarded, but rather terminate the comment.
+ * EOF's encountered are not discarded, but rather terminate the comment.</li>
* <li>If a quote character is parsed, then all characters up to the
* second occurrence of the same quote character are parsed into a
* <code>String</code>. This <code>String</code> is stored as
@@ -280,18 +280,18 @@ public class StreamTokenizer
* (carriage return), \" (double quote), \' (single quote), \\
* (backslash), \XXX (octal esacpe)) are converted to the appropriate
* char values. Invalid esacape sequences are left in untranslated.
- * Unicode characters like ('\ u0000') are not recognized.
+ * Unicode characters like ('\ u0000') are not recognized. </li>
* <li>If the C++ comment sequence "//" is encountered, and the parser
* is configured to handle that sequence, then the remainder of the line
* is skipped and another token is read exactly as if a character with
- * the comment attribute was encountered.
+ * the comment attribute was encountered.</li>
* <li>If the C comment sequence "/*" is encountered, and the parser
* is configured to handle that sequence, then all characters up to and
* including the comment terminator sequence are discarded and another
- * token is parsed.
+ * token is parsed.</li>
* <li>If all cases above are not met, then the character is an ordinary
* character that is parsed as a token by itself. The char encountered
- * is returned as the token type.
+ * is returned as the token type.</li>
* </ul>
*
* @return The token type
@@ -635,15 +635,15 @@ public class StreamTokenizer
* 'x' is determined as follows.
* <p>
* <ul>
- * <li>If no token has been read, then 'x' is "NOTHING" and 'n' is 0
- * <li>If <code>ttype</code> is TT_EOF, then 'x' is "EOF"
- * <li>If <code>ttype</code> is TT_EOL, then 'x' is "EOL"
- * <li>If <code>ttype</code> is TT_WORD, then 'x' is <code>sval</code>
+ * <li>If no token has been read, then 'x' is "NOTHING" and 'n' is 0</li>
+ * <li>If <code>ttype</code> is TT_EOF, then 'x' is "EOF"</li>
+ * <li>If <code>ttype</code> is TT_EOL, then 'x' is "EOL"</li>
+ * <li>If <code>ttype</code> is TT_WORD, then 'x' is <code>sval</code></li>
* <li>If <code>ttype</code> is TT_NUMBER, then 'x' is "n=strnval" where
- * 'strnval' is <code>String.valueOf(nval)</code>.
+ * 'strnval' is <code>String.valueOf(nval)</code>.</li>
* <li>If <code>ttype</code> is a quote character, then 'x' is
- * <code>sval</code>
- * <li>For all other cases, 'x' is <code>ttype</code>
+ * <code>sval</code></li>
+ * <li>For all other cases, 'x' is <code>ttype</code></li>
* </ul>
*/
public String toString()
diff --git a/libjava/java/io/StringWriter.java b/libjava/java/io/StringWriter.java
index 660ef166a2e..c5aab8d157c 100644
--- a/libjava/java/io/StringWriter.java
+++ b/libjava/java/io/StringWriter.java
@@ -60,6 +60,8 @@ public class StringWriter extends Writer
/**
* This method closes the stream. The contents of the internal buffer
* can still be retrieved, but future writes are not guaranteed to work.
+ *
+ * @exception IOException If an error orrurs.
*/
public void close () throws IOException
{
diff --git a/libjava/java/io/WriteAbortedException.java b/libjava/java/io/WriteAbortedException.java
index 0204862ef14..7b683854d3d 100644
--- a/libjava/java/io/WriteAbortedException.java
+++ b/libjava/java/io/WriteAbortedException.java
@@ -81,7 +81,7 @@ public class WriteAbortedException extends ObjectStreamException
/**
* This method returns a message indicating what went wrong, in this
* format:
- * <code>super.getMessage() + (detail == null ? "" : "; " + detail)<code>.
+ * <code>super.getMessage() + (detail == null ? "" : "; " + detail)</code>.
*
* @return the chained message
*/
diff --git a/libjava/java/io/Writer.java b/libjava/java/io/Writer.java
index f3d6eaa7392..60939c8ce99 100644
--- a/libjava/java/io/Writer.java
+++ b/libjava/java/io/Writer.java
@@ -75,8 +75,8 @@ public abstract class Writer
* This method initializes a <code>Writer</code> that will synchronize
* on the specified <code>Object</code>.
*
- * @param obj The <code>Object</code> to use for synchronizing critical
- * sections
+ * @param lock The <code>Object</code> to use for synchronizing critical
+ * sections
*/
protected Writer(Object lock)
{
@@ -157,7 +157,7 @@ public abstract class Writer
*
* @param str The <code>String</code> whose chars are to be written.
*
- * @param IOException If an error occurs
+ * @exception IOException If an error occurs
*/
public void write(String str) throws IOException
{
diff --git a/libjava/java/io/natObjectInputStream.cc b/libjava/java/io/natObjectInputStream.cc
index 8b84e7e3199..9da4910aa06 100644
--- a/libjava/java/io/natObjectInputStream.cc
+++ b/libjava/java/io/natObjectInputStream.cc
@@ -19,6 +19,8 @@ details. */
#include <java/lang/Class.h>
#include <java/lang/reflect/Modifier.h>
#include <java/lang/reflect/Method.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/SecurityManager.h>
#ifdef DEBUG
#include <java/lang/System.h>
@@ -38,7 +40,7 @@ java::io::ObjectInputStream::allocateObject (jclass klass)
obj = NULL;
else
{
- obj = JvAllocObject (klass);
+ obj = _Jv_AllocObject (klass);
}
}
catch (jthrowable t)
@@ -69,3 +71,33 @@ java::io::ObjectInputStream::callConstructor (jclass klass, jobject obj)
+ m->offset);
_Jv_CallAnyMethodA (obj, JvPrimClass (void), meth, false, arg_types, NULL);
}
+
+java::lang::ClassLoader*
+java::io::ObjectInputStream::getCallersClassLoader ()
+{
+ java::lang::ClassLoader *loader = NULL;
+ gnu::gcj::runtime::StackTrace *t
+ = new gnu::gcj::runtime::StackTrace(4);
+ java::lang::Class *klass = NULL;
+ try
+ {
+ for (int i = 2; !klass; i++)
+ {
+ klass = t->classAt (i);
+ }
+ loader = klass->getClassLoaderInternal();
+ }
+ catch (::java::lang::ArrayIndexOutOfBoundsException *e)
+ {
+ // FIXME: RuntimeError
+ }
+
+ return loader;
+}
+
+java::lang::ClassLoader*
+java::io::ObjectInputStream::currentClassLoader (::java::lang::SecurityManager *sm)
+{
+ return sm->currentClassLoader ();
+}
+
diff --git a/libjava/java/lang/Byte.java b/libjava/java/lang/Byte.java
index 7605ad70ef4..641c5cc8ee1 100644
--- a/libjava/java/lang/Byte.java
+++ b/libjava/java/lang/Byte.java
@@ -147,7 +147,7 @@ public final class Byte extends Number implements Comparable
*
* @param s the <code>String</code> to convert
* @param radix the radix (base) to use in the conversion
- * @return the <code>String</code> argument converted to </code>byte</code>
+ * @return the <code>String</code> argument converted to <code>byte</code>
* @throws NumberFormatException if <code>s</code> cannot be parsed as a
* <code>byte</code>
*/
diff --git a/libjava/java/lang/CharSequence.java b/libjava/java/lang/CharSequence.java
index d46bd9d3813..5f5147b0bdd 100644
--- a/libjava/java/lang/CharSequence.java
+++ b/libjava/java/lang/CharSequence.java
@@ -78,7 +78,7 @@ public interface CharSequence
int length();
/**
- * Returns a new <code>CharSequence</char> of the indicated range.
+ * Returns a new <code>CharSequence</code> of the indicated range.
*
* @param begin the start index (inclusive)
* @param end the end index (exclusive)
diff --git a/libjava/java/lang/Class.h b/libjava/java/lang/Class.h
index 1577628cb98..3a19011cd80 100644
--- a/libjava/java/lang/Class.h
+++ b/libjava/java/lang/Class.h
@@ -1,6 +1,6 @@
// Class.h - Header file for java.lang.Class. -*- c++ -*-
-/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
This file is part of libgcj.
@@ -39,14 +39,15 @@ enum
JV_STATE_PRELOADING = 1, // Can do _Jv_FindClass.
JV_STATE_LOADING = 3, // Has super installed.
- JV_STATE_LOADED = 5, // Is complete.
-
+ JV_STATE_READ = 4, // Has been completely defined.
+ JV_STATE_LOADED = 5, // Has Miranda methods defined.
+
JV_STATE_COMPILED = 6, // This was a compiled class.
JV_STATE_PREPARED = 7, // Layout & static init done.
JV_STATE_LINKED = 9, // Strings interned.
- JV_STATE_IN_PROGRESS = 10, // <Clinit> running.
+ JV_STATE_IN_PROGRESS = 10, // <clinit> running.
JV_STATE_ERROR = 12,
@@ -57,6 +58,9 @@ struct _Jv_Field;
struct _Jv_VTable;
union _Jv_word;
struct _Jv_ArrayVTable;
+class _Jv_ExecutionEngine;
+class _Jv_CompiledEngine;
+class _Jv_InterpreterEngine;
struct _Jv_Constants
{
@@ -207,9 +211,14 @@ public:
void setSigners(JArray<jobject> *);
inline jclass getSuperclass (void)
- {
- return superclass;
- }
+ {
+ return superclass;
+ }
+
+ inline jclass getInterface (jint n)
+ {
+ return interfaces[n];
+ }
inline jboolean isArray (void)
{
@@ -242,9 +251,16 @@ public:
// FIXME: this probably shouldn't be public.
jint size (void)
- {
- return size_in_bytes;
- }
+ {
+ return size_in_bytes;
+ }
+
+ // The index of the first method we declare ourself (as opposed to
+ // inheriting).
+ inline jint firstMethodIndex (void)
+ {
+ return vtable_method_count - method_count;
+ }
// finalization
void finalize ();
@@ -263,14 +279,6 @@ private:
static jstring getPackagePortion (jstring);
- // Friend functions implemented in natClass.cc.
- friend _Jv_Method *_Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
- _Jv_Utf8Const *signature);
- friend jboolean _Jv_IsAssignableFrom(jclass, jclass);
- friend jboolean _Jv_InterfaceAssignableFrom (jclass, jclass);
- friend void *_Jv_LookupInterfaceMethodIdx (jclass klass, jclass iface,
- int method_idx);
-
inline friend void
_Jv_InitClass (jclass klass)
{
@@ -279,14 +287,30 @@ private:
klass->initializeClass ();
}
+ void set_state (jint nstate)
+ {
+ state = nstate;
+ notifyAll ();
+ }
+
+ // Friend functions implemented in natClass.cc.
+ friend _Jv_Method *_Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
+ _Jv_Utf8Const *signature);
+ friend jboolean _Jv_IsAssignableFrom(jclass, jclass);
+ friend jboolean _Jv_InterfaceAssignableFrom (jclass, jclass);
+ friend void *_Jv_LookupInterfaceMethodIdx (jclass klass, jclass iface,
+ int method_idx);
+ friend jboolean _Jv_IsAssignableFromSlow(jclass, jclass);
+
friend _Jv_Method* _Jv_LookupDeclaredMethod (jclass, _Jv_Utf8Const *,
- _Jv_Utf8Const*);
+ _Jv_Utf8Const*,
+ jclass * = 0);
friend jfieldID JvGetFirstInstanceField (jclass);
friend jint JvNumInstanceFields (jclass);
friend jfieldID JvGetFirstStaticField (jclass);
friend jint JvNumStaticFields (jclass);
- friend jobject _Jv_AllocObject (jclass, jint);
+ friend jobject _Jv_AllocObject (jclass);
friend void *_Jv_AllocObj (jint, jclass);
friend void *_Jv_AllocPtrFreeObj (jint, jclass);
friend void *_Jv_AllocArray (jint, jclass);
@@ -310,7 +334,6 @@ private:
friend class java::io::ObjectInputStream;
friend class java::io::ObjectStreamClass;
- friend void _Jv_WaitForState (jclass, int);
friend void _Jv_RegisterClasses (jclass *classes);
friend void _Jv_RegisterClassHookDefault (jclass klass);
friend void _Jv_RegisterInitiatingLoader (jclass,java::lang::ClassLoader*);
@@ -332,20 +355,23 @@ private:
friend void _Jv_InitPrimClass (jclass, char *, char, int, _Jv_ArrayVTable *);
friend void _Jv_PrepareCompiledClass (jclass);
- friend void _Jv_PrepareConstantTimeTables (jclass);
friend jshort _Jv_GetInterfaces (jclass, _Jv_ifaces *);
friend void _Jv_GenerateITable (jclass, _Jv_ifaces *, jshort *);
friend jstring _Jv_GetMethodString(jclass, _Jv_Utf8Const *);
friend jshort _Jv_AppendPartialITable (jclass, jclass, void **, jshort);
friend jshort _Jv_FindIIndex (jclass *, jshort *, jshort);
friend void _Jv_LinkSymbolTable (jclass);
- friend void _Jv_LayoutVTableMethods (jclass klass);
+ friend void _Jv_LayoutInterfaceMethods (jclass);
friend void _Jv_SetVTableEntries (jclass, _Jv_VTable *, jboolean *);
friend void _Jv_MakeVTable (jclass);
friend void _Jv_linkExceptionClassTable (jclass);
friend jboolean _Jv_CheckAccess (jclass self_klass, jclass other_klass,
jint flags);
+
+ friend bool _Jv_getInterfaceMethod(jclass, jclass&, int&,
+ const _Jv_Utf8Const*,
+ const _Jv_Utf8Const*);
// Return array class corresponding to element type KLASS, creating it if
// necessary.
@@ -362,18 +388,13 @@ private:
#ifdef INTERPRETER
friend jboolean _Jv_IsInterpretedClass (jclass);
- friend void _Jv_InitField (jobject, jclass, _Jv_Field*);
friend void _Jv_InitField (jobject, jclass, int);
- friend _Jv_word _Jv_ResolvePoolEntry (jclass, int);
friend _Jv_Method *_Jv_SearchMethodInClass (jclass cls, jclass klass,
_Jv_Utf8Const *method_name,
_Jv_Utf8Const *method_signature);
- friend void _Jv_PrepareClass (jclass);
friend void _Jv_PrepareMissingMethods (jclass base, jclass iface_class);
- friend void _Jv_Defer_Resolution (void *cl, _Jv_Method *meth, void **);
-
friend class _Jv_ClassReader;
friend class _Jv_InterpClass;
friend class _Jv_InterpMethod;
@@ -387,6 +408,11 @@ private:
friend class gnu::gcj::runtime::StackTrace;
friend class java::io::VMObjectStreamClass;
+ friend class _Jv_Linker;
+ friend class _Jv_ExecutionEngine;
+ friend class _Jv_CompiledEngine;
+ friend class _Jv_InterpreterEngine;
+
friend void _Jv_sharedlib_register_hook (jclass klass);
// Chain for class pool.
@@ -421,8 +447,12 @@ private:
_Jv_OffsetTable *otable;
// Offset table symbols.
_Jv_MethodSymbol *otable_syms;
+ // Address table
_Jv_AddressTable *atable;
_Jv_MethodSymbol *atable_syms;
+ // Interface table
+ _Jv_AddressTable *itable;
+ _Jv_MethodSymbol *itable_syms;
_Jv_CatchClass *catch_classes;
// Interfaces implemented by this class.
jclass *interfaces;
@@ -445,10 +475,17 @@ private:
jclass arrayclass;
// Security Domain to which this class belongs (or null).
java::security::ProtectionDomain *protectionDomain;
+ // Pointer to verify method for this class.
+ void (*verify)(java::lang::ClassLoader *loader);
// Signers of this class (or null).
JArray<jobject> *hack_signers;
// Used by Jv_PopClass and _Jv_PushClass to communicate with StackTrace.
jclass chain;
+ // Additional data, specific to the generator (JIT, native,
+ // interpreter) of this class.
+ void *aux_info;
+ // Execution engine.
+ _Jv_ExecutionEngine *engine;
};
#endif /* __JAVA_LANG_CLASS_H__ */
diff --git a/libjava/java/lang/ClassLoader.java b/libjava/java/lang/ClassLoader.java
index 7bbd6412554..31fe1193264 100644
--- a/libjava/java/lang/ClassLoader.java
+++ b/libjava/java/lang/ClassLoader.java
@@ -1,5 +1,5 @@
/* ClassLoader.java -- responsible for loading classes into the VM
- Copyright (C) 1998, 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,9 +38,11 @@ exception statement from your version. */
package java.lang;
-import java.io.InputStream;
+import gnu.java.util.DoubleEnumeration;
+import gnu.java.util.EmptyEnumeration;
+
import java.io.IOException;
-import java.lang.reflect.Constructor;
+import java.io.InputStream;
import java.net.URL;
import java.security.CodeSource;
import java.security.PermissionCollection;
@@ -49,8 +51,6 @@ import java.security.ProtectionDomain;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
-import gnu.java.util.DoubleEnumeration;
-import gnu.java.util.EmptyEnumeration;
/**
* The ClassLoader is a way of customizing the way Java gets its classes
@@ -249,7 +249,7 @@ public abstract class ClassLoader
* it. Calls <code>loadClass(name, false)</code>.
*
* <p>Subclasses should not override this method but should override
- * <code>findClass()</code> which is called by this method.
+ * <code>findClass()</code> which is called by this method.</p>
*
* @param name the name of the class relative to this ClassLoader
* @return the loaded class
@@ -266,14 +266,14 @@ public abstract class ClassLoader
* out if the class has already been loaded through this classloader by
* calling <code>findLoadedClass()</code>. Then it calls
* <code>loadClass()</code> on the parent classloader (or when there is
- * no parent it uses the VM bootclassloader)</code>). If the class is still
+ * no parent it uses the VM bootclassloader). If the class is still
* not loaded it tries to create a new class by calling
* <code>findClass()</code>. Finally when <code>resolve</code> is
* <code>true</code> it also calls <code>resolveClass()</code> on the
* newly loaded class.
*
* <p>Subclasses should not override this method but should override
- * <code>findClass()</code> which is called by this method.
+ * <code>findClass()</code> which is called by this method.</p>
*
* @param name the fully qualified name of the class to load
* @param resolve whether or not to resolve the class
@@ -288,6 +288,8 @@ public abstract class ClassLoader
if (c != null)
return c;
+ ClassNotFoundException ex = null;
+
// Can the class be loaded by a parent?
try
{
@@ -304,9 +306,20 @@ public abstract class ClassLoader
}
catch (ClassNotFoundException e)
{
+ ex = e;
}
// Still not found, we have to do it ourself.
- c = findClass(name);
+ try
+ {
+ c = findClass(name);
+ }
+ catch (ClassNotFoundException cause)
+ {
+ if (ex != null)
+ throw new ClassNotFoundException(ex.toString(), cause);
+ else
+ throw cause;
+ }
if (resolve)
resolveClass(c);
return c;
@@ -384,7 +397,7 @@ public abstract class ClassLoader
* <code>findClass()</code> implementation. The name should use '.'
* separators, and discard the trailing ".class". The default protection
* domain has the permissions of
- * <code>Policy.getPolicy().getPermissions(new CodeSource(null, null))<code>.
+ * <code>Policy.getPolicy().getPermissions(new CodeSource(null, null))</code>.
*
* @param name the name to give the class, or null if unknown
* @param data the data representing the classfile, in classfile format
@@ -407,7 +420,7 @@ public abstract class ClassLoader
* Helper to define a class using a string of bytes. Subclasses should call
* this method from their <code>findClass()</code> implementation. If the
* domain is null, the default of
- * <code>Policy.getPolicy().getPermissions(new CodeSource(null, null))<code>
+ * <code>Policy.getPolicy().getPermissions(new CodeSource(null, null))</code>
* is used. Once a class has been defined in a package, all further classes
* in that package must have the same set of certificates or a
* SecurityException is thrown.
@@ -435,8 +448,9 @@ public abstract class ClassLoader
domain = defaultProtectionDomain;
if (! initialized)
throw new SecurityException("attempt to define class from uninitialized class loader");
+
Class retval = VMClassLoader.defineClass(this, name, data,
- offset, len, domain);
+ offset, len, domain);
loadedClasses.put(retval.getName(), retval);
return retval;
}
@@ -475,6 +489,7 @@ public abstract class ClassLoader
* <code>null</code>. A security check may be performed on
* <code>RuntimePermission("getClassLoader")</code>.
*
+ * @return the parent <code>ClassLoader</code>
* @throws SecurityException if the security check fails
* @since 1.2
*/
@@ -554,13 +569,13 @@ public abstract class ClassLoader
* multiple resources with the same name that come from multiple locations.
* It can also occur that a parent classloader offers a resource with a
* certain name and the child classloader also offers a resource with that
- * same name. <code>getResource() only offers the first resource (of the
+ * same name. <code>getResource()</code> only offers the first resource (of the
* parent) with a given name. This method lists all resources with the
* same name. The name should use '/' as path separators.
*
* <p>The Enumeration is created by first calling <code>getResources()</code>
* on the parent classloader and then calling <code>findResources()</code>
- * on this classloader.
+ * on this classloader.</p>
*
* @param name the resource name
* @return an enumaration of all resources found
diff --git a/libjava/java/lang/Compiler.java b/libjava/java/lang/Compiler.java
index 2d98811d1f4..858f63ee993 100644
--- a/libjava/java/lang/Compiler.java
+++ b/libjava/java/lang/Compiler.java
@@ -1,5 +1,5 @@
/* Compiler.java -- placeholder for Java-to-native runtime compilers
- Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2001, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -76,12 +76,11 @@ public final class Compiler
*/
public static boolean compileClass(Class oneClass)
{
- // Never succeed.
- return false;
+ return VMCompiler.compileClass(oneClass);
}
/**
- * Compile the classes whose name matches <code>classNames/code>.
+ * Compile the classes whose name matches <code>classNames</code>.
*
* @param classNames the name of classes to compile
* @return <code>false</code> if no compiler is available or
@@ -90,8 +89,7 @@ public final class Compiler
*/
public static boolean compileClasses(String classNames)
{
- // Note the incredibly lame interface. Always fail.
- return false;
+ return VMCompiler.compileClasses(classNames);
}
/**
@@ -105,8 +103,7 @@ public final class Compiler
*/
public static Object command(Object arg)
{
- // Our implementation defines this to a no-op.
- return null;
+ return VMCompiler.command(arg);
}
/**
@@ -116,6 +113,7 @@ public final class Compiler
*/
public static void enable()
{
+ VMCompiler.enable();
}
/**
@@ -124,5 +122,6 @@ public final class Compiler
*/
public static void disable()
{
+ VMCompiler.disable();
}
}
diff --git a/libjava/java/lang/Double.java b/libjava/java/lang/Double.java
index 95ee4ecb775..be393b6b4b9 100644
--- a/libjava/java/lang/Double.java
+++ b/libjava/java/lang/Double.java
@@ -1,5 +1,6 @@
/* Double.java -- object wrapper for double
- Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -35,7 +36,6 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.lang;
import gnu.classpath.Configuration;
@@ -243,7 +243,7 @@ public final class Double extends Number implements Comparable
* @see #NEGATIVE_INFINITY
* @since 1.2
*/
- public static native double parseDouble(String s);
+ public static native double parseDouble(String str);
/**
* Return <code>true</code> if the <code>double</code> has the same
@@ -392,9 +392,9 @@ public final class Double extends Number implements Comparable
* <code>Double.NaN</code> as equal, but treats <code>0.0</code> and
* <code>-0.0</code> as unequal.
*
- * <p>Note that <code>d1.equals(d2)<code> is identical to
+ * <p>Note that <code>d1.equals(d2)</code> is identical to
* <code>doubleToLongBits(d1.doubleValue()) ==
- * doubleToLongBits(d2.doubleValue())<code>.
+ * doubleToLongBits(d2.doubleValue())</code>.
*
* @param obj the object to compare
* @return whether the objects are semantically equal
diff --git a/libjava/java/lang/Float.java b/libjava/java/lang/Float.java
index 78dab61572a..d59912168da 100644
--- a/libjava/java/lang/Float.java
+++ b/libjava/java/lang/Float.java
@@ -1,5 +1,6 @@
/* Float.java -- object wrapper for float
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -239,11 +240,11 @@ public final class Float extends Number implements Comparable
* @see #NEGATIVE_INFINITY
* @since 1.2
*/
- public static float parseFloat(String s)
+ public static float parseFloat(String str)
{
// XXX Rounding parseDouble() causes some errors greater than 1 ulp from
// the infinitely precise decimal.
- return (float) Double.parseDouble(s);
+ return (float) Double.parseDouble(str);
}
/**
@@ -390,9 +391,9 @@ public final class Float extends Number implements Comparable
* <code>Float.NaN</code> as equal, but treats <code>0.0</code> and
* <code>-0.0</code> as unequal.
*
- * <p>Note that <code>f1.equals(f2)<code> is identical to
+ * <p>Note that <code>f1.equals(f2)</code> is identical to
* <code>floatToIntBits(f1.floatValue()) ==
- * floatToIntBits(f2.floatValue())<code>.
+ * floatToIntBits(f2.floatValue())</code>.
*
* @param obj the object to compare
* @return whether the objects are semantically equal
diff --git a/libjava/java/lang/Integer.java b/libjava/java/lang/Integer.java
index f9d901804f7..9c8329dbd83 100644
--- a/libjava/java/lang/Integer.java
+++ b/libjava/java/lang/Integer.java
@@ -220,9 +220,9 @@ public final class Integer extends Number implements Comparable
* within <code>MIN_VALUE</code> to <code>MAX_VALUE</code>, inclusive.
* Unlike Double.parseDouble, you may not have a leading '+'.
*
- * @param s the <code>String</code> to convert
+ * @param str the <code>String</code> to convert
* @param radix the radix (base) to use in the conversion
- * @return the <code>String</code> argument converted to </code>int</code>
+ * @return the <code>String</code> argument converted to <code>int</code>
* @throws NumberFormatException if <code>s</code> cannot be parsed as an
* <code>int</code>
*/
@@ -414,7 +414,7 @@ public final class Integer extends Number implements Comparable
* interpret the value of the property.
*
* @param nm the name of the system property
- * @param val the default value
+ * @param def the default value
* @return the value of the system property, or the default
* @throws SecurityException if accessing the system property is forbidden
* @see System#getProperty(String)
@@ -461,7 +461,7 @@ public final class Integer extends Number implements Comparable
* Finally, the value must be in the range <code>MIN_VALUE</code> to
* <code>MAX_VALUE</code>, or an exception is thrown.
*
- * @param s the <code>String</code> to interpret
+ * @param str the <code>String</code> to interpret
* @return the value of the String as an <code>Integer</code>
* @throws NumberFormatException if <code>s</code> cannot be parsed as a
* <code>int</code>
diff --git a/libjava/java/lang/Long.java b/libjava/java/lang/Long.java
index 1420e58d6c4..012cc9c93e7 100644
--- a/libjava/java/lang/Long.java
+++ b/libjava/java/lang/Long.java
@@ -223,9 +223,9 @@ public final class Long extends Number implements Comparable
* 'L' as the last character is only valid in radices 22 or greater, where
* it is a digit and not a type indicator.
*
- * @param s the <code>String</code> to convert
+ * @param str the <code>String</code> to convert
* @param radix the radix (base) to use in the conversion
- * @return the <code>String</code> argument converted to </code>long</code>
+ * @return the <code>String</code> argument converted to <code>long</code>
* @throws NumberFormatException if <code>s</code> cannot be parsed as a
* <code>long</code>
*/
@@ -306,7 +306,7 @@ public final class Long extends Number implements Comparable
* <code>MAX_VALUE</code>, or an exception is thrown. Note that you cannot
* use a trailing 'l' or 'L', unlike in Java source code.
*
- * @param s the <code>String</code> to interpret
+ * @param str the <code>String</code> to interpret
* @return the value of the String as a <code>Long</code>
* @throws NumberFormatException if <code>s</code> cannot be parsed as a
* <code>long</code>
@@ -455,7 +455,7 @@ public final class Long extends Number implements Comparable
* interpret the value of the property.
*
* @param nm the name of the system property
- * @param val the default value
+ * @param def the default value
* @return the value of the system property, or the default
* @throws SecurityException if accessing the system property is forbidden
* @see System#getProperty(String)
diff --git a/libjava/java/lang/Math.java b/libjava/java/lang/Math.java
index e41eca7ce1a..5c9a39bff0f 100644
--- a/libjava/java/lang/Math.java
+++ b/libjava/java/lang/Math.java
@@ -564,7 +564,7 @@ public final class Math
/**
* Take the nearest integer to the argument. This is equivalent to
- * <code>(int) Math.floor(a + 0.5f). If the argument is NaN, the result
+ * <code>(int) Math.floor(a + 0.5f)</code>. If the argument is NaN, the result
* is 0; otherwise if the argument is outside the range of int, the result
* will be Integer.MIN_VALUE or Integer.MAX_VALUE, as appropriate.
*
diff --git a/libjava/java/lang/Number.java b/libjava/java/lang/Number.java
index eb230b060ca..54bb1f763e5 100644
--- a/libjava/java/lang/Number.java
+++ b/libjava/java/lang/Number.java
@@ -69,7 +69,7 @@ public abstract class Number implements Serializable
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
- 'u', 'v', 'w', 'x', 'y', 'z'
+ 'u', 'v', 'w', 'x', 'y', 'z',
};
/**
diff --git a/libjava/java/lang/Package.java b/libjava/java/lang/Package.java
index 3045b50c2f1..3ccdbb1e642 100644
--- a/libjava/java/lang/Package.java
+++ b/libjava/java/lang/Package.java
@@ -227,7 +227,10 @@ public class Package
* <code>getSpecificationVersion</code>.
*
* @param version the (minimal) desired version of the specification
- * @throws NumberFormatException if either version string is invalid
+ *
+ * @return true if the version is compatible, false otherwise
+ *
+ * @Throws NumberFormatException if either version string is invalid
* @throws NullPointerException if either version string is null
*/
public boolean isCompatibleWith(String version)
diff --git a/libjava/java/lang/Runtime.java b/libjava/java/lang/Runtime.java
index 5c6037ed8a7..e14cd192f40 100644
--- a/libjava/java/lang/Runtime.java
+++ b/libjava/java/lang/Runtime.java
@@ -95,8 +95,9 @@ public class Runtime
* System.loadLibrary calls Runtime.getRuntime, triggering initialization
* Runtime.<clinit> calls Properties.<init>, triggering initialization
* Dictionary, Hashtable, and Properties have no dependencies
- * Runtime.<clinit> calls insertSystemProperties; the VM must make sure
- * that there are not any harmful dependencies
+ * Runtime.<clinit> calls VMRuntime.insertSystemProperties, triggering
+ * initialization of VMRuntime; the VM must make sure that there are
+ * not any harmful dependencies
* Runtime.<clinit> calls Runtime.<init>
* Runtime.<init> calls StringTokenizer.<init>, triggering initialization
* StringTokenizer has no dependencies
@@ -170,13 +171,13 @@ public class Runtime
*
* <p>First, all shutdown hooks are run, in unspecified order, and
* concurrently. Next, if finalization on exit has been enabled, all pending
- * finalizers are run. Finally, the system calls <code>halt</code>.
+ * finalizers are run. Finally, the system calls <code>halt</code>.</p>
*
* <p>If this is run a second time after shutdown has already started, there
* are two actions. If shutdown hooks are still executing, it blocks
* indefinitely. Otherwise, if the status is nonzero it halts immediately;
* if it is zero, it blocks indefinitely. This is typically called by
- * <code>System.exit</code>.
+ * <code>System.exit</code>.</p>
*
* @param status the status to exit with
* @throws SecurityException if permission is denied
@@ -285,23 +286,23 @@ public class Runtime
* <code>System.exit</code> was invoked), or when the user terminates
* the virtual machine (such as by typing ^C, or logging off). There is
* a security check to add hooks,
- * <code>RuntimePermission("shutdownHooks")<code>.
+ * <code>RuntimePermission("shutdownHooks")</code>.
*
* <p>The hook must be an initialized, but unstarted Thread. The threads
* are run concurrently, and started in an arbitrary order; and user
* threads or daemons may still be running. Once shutdown hooks have
* started, they must all complete, or else you must use <code>halt</code>,
* to actually finish the shutdown sequence. Attempts to modify hooks
- * after shutdown has started result in IllegalStateExceptions.
+ * after shutdown has started result in IllegalStateExceptions.</p>
*
* <p>It is imperative that you code shutdown hooks defensively, as you
* do not want to deadlock, and have no idea what other hooks will be
* running concurrently. It is also a good idea to finish quickly, as the
- * virtual machine really wants to shut down!
+ * virtual machine really wants to shut down!</p>
*
* <p>There are no guarantees that such hooks will run, as there are ways
* to forcibly kill a process. But in such a drastic case, shutdown hooks
- * would do little for you in the first place.
+ * would do little for you in the first place.</p>
*
* @param hook an initialized, unstarted Thread
* @throws IllegalArgumentException if the hook is already registered or run
@@ -334,7 +335,7 @@ public class Runtime
/**
* De-register a shutdown hook. As when you registered it, there is a
* security check to remove hooks,
- * <code>RuntimePermission("shutdownHooks")<code>.
+ * <code>RuntimePermission("shutdownHooks")</code>.
*
* @param hook the hook to remove
* @return true if the hook was successfully removed, false if it was not
@@ -408,7 +409,7 @@ public class Runtime
/**
* Create a new subprocess with the specified command line. Calls
- * <code>exec(cmdline, null, null)<code>. A security check is performed,
+ * <code>exec(cmdline, null, null)</code>. A security check is performed,
* <code>checkExec</code>.
*
* @param cmdline the command to call
@@ -635,9 +636,11 @@ public class Runtime
* <code>System.mapLibraryName(libname)</code>. There may be a security
* check, of <code>checkLink</code>.
*
- * @param filename the file to load
+ * @param libname the library to load
+ *
* @throws SecurityException if permission is denied
* @throws UnsatisfiedLinkError if the library is not found
+ *
* @see System#mapLibraryName(String)
* @see ClassLoader#findLibrary(String)
*/
diff --git a/libjava/java/lang/RuntimePermission.java b/libjava/java/lang/RuntimePermission.java
index 0b5b5f87842..b6adf383804 100644
--- a/libjava/java/lang/RuntimePermission.java
+++ b/libjava/java/lang/RuntimePermission.java
@@ -118,7 +118,7 @@ import java.security.BasicPermission;
* access to in the system</td>
* <td>rogue code can stop arbitrary threads</td></tr>
* <tr>
- * <td><code>modifyThreadGroup</td>
+ * <td><code>modifyThreadGroup</code></td>
* <td>allows the application to modify thread groups using any of the
* methods <code>destroy</code>, <code>resume</code>,
* <code>setDaemon</code>, <code>setMaxPriority</code>,
@@ -141,7 +141,7 @@ import java.security.BasicPermission;
* <td>rogue code can write files, including viruses, and can modify the
* virtual machine binary; if not just fill up the disk</td></tr>
* <tr>
- * <td><code>loadLibrary.<code><em>library name</em></td>
+ * <td><code>loadLibrary.</code><em>library name</em></td>
* <td>dynamic linking of the named library</td>
* <td>native code can bypass many security checks of pure Java</td></tr>
* <tr>
diff --git a/libjava/java/lang/SecurityManager.java b/libjava/java/lang/SecurityManager.java
index 8740a2e4287..972b312d943 100644
--- a/libjava/java/lang/SecurityManager.java
+++ b/libjava/java/lang/SecurityManager.java
@@ -86,7 +86,7 @@ import java.util.PropertyPermission;
* // now, in worker thread
* if (sm != null)
* sm.checkPermission(permission, context);
- * <pre>
+ * </pre>
*
* <p>Permissions fall into these categories: File, Socket, Net, Security,
* Runtime, Property, AWT, Reflect, and Serializable. Each of these
@@ -174,13 +174,15 @@ public class SecurityManager
* Find the ClassLoader of the first non-system class on the execution
* stack. A non-system class is one whose ClassLoader is not equal to
* {@link ClassLoader#getSystemClassLoader()} or its ancestors. This
- * will return null in three cases:<br><nl>
+ * will return null in three cases:
+ *
+ * <ul>
* <li>All methods on the stack are from system classes</li>
* <li>All methods on the stack up to the first "privileged" caller, as
* created by {@link AccessController.doPrivileged(PrivilegedAction)},
* are from system classes</li>
* <li>A check of <code>java.security.AllPermission</code> succeeds.</li>
- * </nl>
+ * </ul>
*
* @return the most recent non-system ClassLoader on the execution stack
* @deprecated use {@link #checkPermission(Permission)} instead
@@ -194,13 +196,15 @@ public class SecurityManager
* Find the first non-system class on the execution stack. A non-system
* class is one whose ClassLoader is not equal to
* {@link ClassLoader#getSystemClassLoader()} or its ancestors. This
- * will return null in three cases:<br><nl>
+ * will return null in three cases:
+ *
+ * <ul>
* <li>All methods on the stack are from system classes</li>
* <li>All methods on the stack up to the first "privileged" caller, as
* created by {@link AccessController.doPrivileged(PrivilegedAction)},
* are from system classes</li>
* <li>A check of <code>java.security.AllPermission</code> succeeds.</li>
- * </nl>
+ * </ul>
*
* @return the most recent non-system Class on the execution stack
* @deprecated use {@link #checkPermission(Permission)} instead
@@ -231,13 +235,15 @@ public class SecurityManager
* Get the depth on the execution stack of the most recent non-system class.
* A non-system class is one whose ClassLoader is not equal to
* {@link ClassLoader#getSystemClassLoader()} or its ancestors. This
- * will return -1 in three cases:<br><nl>
+ * will return -1 in three cases:
+ *
+ * <ul>
* <li>All methods on the stack are from system classes</li>
* <li>All methods on the stack up to the first "privileged" caller, as
* created by {@link AccessController.doPrivileged(PrivilegedAction)},
* are from system classes</li>
* <li>A check of <code>java.security.AllPermission</code> succeeds.</li>
- * </nl>
+ * </ul>
*
* @return the index of the most recent non-system Class on the stack
* @deprecated use {@link #checkPermission(Permission)} instead
@@ -318,7 +324,7 @@ public class SecurityManager
public void checkPermission(Permission perm)
{
// XXX Should be: AccessController.checkPermission(perm);
- throw new SecurityException("Operation not allowed");
+ //.throw new SecurityException("Operation not allowed");
}
/**
@@ -365,8 +371,8 @@ public class SecurityManager
* Check if the current thread is allowed to modify another Thread. This is
* called by Thread.stop(), suspend(), resume(), interrupt(), destroy(),
* setPriority(), setName(), and setDaemon(). The default implementation
- * checks <code>RuntimePermission("modifyThread") on system threads (ie.
- * threads in ThreadGroup with a null parent), and returns silently on
+ * checks <code>RuntimePermission("modifyThread")</code> on system threads
+ * (ie. threads in ThreadGroup with a null parent), and returns silently on
* other threads.
*
* <p>If you override this, you must do two things. First, call
@@ -375,9 +381,9 @@ public class SecurityManager
* <code>RuntimePermission("modifyThread")</code>, return silently, so that
* core classes (the Classpath library!) can modify any thread.
*
- * @param t the other Thread to check
+ * @param thread the other Thread to check
* @throws SecurityException if permission is denied
- * @throws NullPointerException if t is null
+ * @throws NullPointerException if thread is null
* @see Thread#stop()
* @see Thread#suspend()
* @see Thread#resume()
@@ -385,9 +391,10 @@ public class SecurityManager
* @see Thread#setName(String)
* @see Thread#setDaemon(boolean)
*/
- public void checkAccess(Thread t)
+ public void checkAccess(Thread thread)
{
- if (t.group != null && t.group.getParent() != null)
+ if (thread.getThreadGroup() != null
+ && thread.getThreadGroup().getParent() != null)
checkPermission(new RuntimePermission("modifyThread"));
}
@@ -397,8 +404,8 @@ public class SecurityManager
* ThreadGroup.ThreadGroup() (to add this ThreadGroup to a parent),
* ThreadGroup.stop(), suspend(), resume(), interrupt(), destroy(),
* setDaemon(), and setMaxPriority(). The default implementation
- * checks <code>RuntimePermission("modifyThread") on the system group (ie.
- * the one with a null parent), and returns silently on other groups.
+ * checks <code>RuntimePermission("modifyThread")</code> on the system group
+ * (ie. the one with a null parent), and returns silently on other groups.
*
* <p>If you override this, you must do two things. First, call
* <code>super.checkAccess(t)</code>, to make sure you are not relaxing
@@ -546,7 +553,7 @@ public class SecurityManager
// throw new SecurityException("Missing context");
// AccessControlContext ac = (AccessControlContext) context;
// ac.checkPermission(new FilePermission(filename, "read"));
- throw new SecurityException("Cannot read files via file names.");
+ // throw new SecurityException("Cannot read files via file names.");
}
/**
@@ -650,13 +657,15 @@ public class SecurityManager
* @param host the host to connect to
* @param port the port to connect on
* @param context the context to determine access for
+ *
* @throws SecurityException if permission is denied, or if context is
* not an AccessControlContext
* @throws NullPointerException if host is null
+ *
* @see #getSecurityContext()
* @see AccessControlContext#checkPermission(Permission)
*/
- public void checkConnect(String host, int port, Object securityContext)
+ public void checkConnect(String host, int port, Object context)
{
// XXX Should be:
// if (! (context instanceof AccessControlContext))
@@ -668,7 +677,7 @@ public class SecurityManager
// // Use the toString() hack to do the null check.
// ac.checkPermission(new SocketPermission(host.toString + ":" +port,
// "connect"));
- throw new SecurityException("Cannot make network connections.");
+ // throw new SecurityException("Cannot make network connections.");
}
/**
@@ -775,9 +784,12 @@ public class SecurityManager
* you override this, call <code>super.checkPropertyAccess</code> rather
* than throwing an exception.
*
+ * @param key the key of the property to check
+ *
* @throws SecurityException if permission is denied
* @throws NullPointerException if key is null
* @throws IllegalArgumentException if key is ""
+ *
* @see System#getProperty(String)
*/
public void checkPropertyAccess(String key)
diff --git a/libjava/java/lang/Short.java b/libjava/java/lang/Short.java
index 54e36a5f65c..1a82e3edf36 100644
--- a/libjava/java/lang/Short.java
+++ b/libjava/java/lang/Short.java
@@ -60,13 +60,13 @@ public final class Short extends Number implements Comparable
/**
* The minimum value a <code>short</code> can represent is -32768 (or
- * -2<sup>15</sup).
+ * -2<sup>15</sup>).
*/
public static final short MIN_VALUE = -32768;
/**
* The minimum value a <code>short</code> can represent is 32767 (or
- * 2<sup>15</sup).
+ * 2<sup>15</sup>).
*/
public static final short MAX_VALUE = 32767;
@@ -144,7 +144,7 @@ public final class Short extends Number implements Comparable
*
* @param s the <code>String</code> to convert
* @param radix the radix (base) to use in the conversion
- * @return the <code>String</code> argument converted to </code>short</code>
+ * @return the <code>String</code> argument converted to <code>short</code>
* @throws NumberFormatException if <code>s</code> cannot be parsed as a
* <code>short</code>
*/
diff --git a/libjava/java/lang/StringBuffer.java b/libjava/java/lang/StringBuffer.java
index 293b97d076e..d5bd45eaa54 100644
--- a/libjava/java/lang/StringBuffer.java
+++ b/libjava/java/lang/StringBuffer.java
@@ -396,7 +396,7 @@ public final class StringBuffer implements Serializable, CharSequence
/**
* Append the <code>char</code> to this <code>StringBuffer</code>.
*
- * @param c the <code>char</code> to append
+ * @param ch the <code>char</code> to append
* @return this <code>StringBuffer</code>
*/
public synchronized StringBuffer append(char ch)
diff --git a/libjava/java/lang/System.java b/libjava/java/lang/System.java
index 63881046d5d..284dead0ce7 100644
--- a/libjava/java/lang/System.java
+++ b/libjava/java/lang/System.java
@@ -310,51 +310,53 @@ public final class System
*
* <p>The required properties include:
* <dl>
- * <dt>java.version <dd>Java version number
- * <dt>java.vendor <dd>Java vendor specific string
- * <dt>java.vendor.url <dd>Java vendor URL
- * <dt>java.home <dd>Java installation directory
- * <dt>java.vm.specification.version <dd>VM Spec version
- * <dt>java.vm.specification.vendor <dd>VM Spec vendor
- * <dt>java.vm.specification.name <dd>VM Spec name
- * <dt>java.vm.version <dd>VM implementation version
- * <dt>java.vm.vendor <dd>VM implementation vendor
- * <dt>java.vm.name <dd>VM implementation name
- * <dt>java.specification.version <dd>Java Runtime Environment version
- * <dt>java.specification.vendor <dd>Java Runtime Environment vendor
- * <dt>java.specification.name <dd>Java Runtime Environment name
- * <dt>java.class.version <dd>Java class version number
- * <dt>java.class.path <dd>Java classpath
- * <dt>java.library.path <dd>Path for finding Java libraries
- * <dt>java.io.tmpdir <dd>Default temp file path
- * <dt>java.compiler <dd>Name of JIT to use
- * <dt>java.ext.dirs <dd>Java extension path
- * <dt>os.name <dd>Operating System Name
- * <dt>os.arch <dd>Operating System Architecture
- * <dt>os.version <dd>Operating System Version
- * <dt>file.separator <dd>File separator ("/" on Unix)
- * <dt>path.separator <dd>Path separator (":" on Unix)
- * <dt>line.separator <dd>Line separator ("\n" on Unix)
- * <dt>user.name <dd>User account name
- * <dt>user.home <dd>User home directory
- * <dt>user.dir <dd>User's current working directory
+ * <dt>java.version</dt> <dd>Java version number</dd>
+ * <dt>java.vendor</dt> <dd>Java vendor specific string</dd>
+ * <dt>java.vendor.url</dt> <dd>Java vendor URL</dd>
+ * <dt>java.home</dt> <dd>Java installation directory</dd>
+ * <dt>java.vm.specification.version</dt> <dd>VM Spec version</dd>
+ * <dt>java.vm.specification.vendor</dt> <dd>VM Spec vendor</dd>
+ * <dt>java.vm.specification.name</dt> <dd>VM Spec name</dd>
+ * <dt>java.vm.version</dt> <dd>VM implementation version</dd>
+ * <dt>java.vm.vendor</dt> <dd>VM implementation vendor</dd>
+ * <dt>java.vm.name</dt> <dd>VM implementation name</dd>
+ * <dt>java.specification.version</dt> <dd>Java Runtime Environment version</dd>
+ * <dt>java.specification.vendor</dt> <dd>Java Runtime Environment vendor</dd>
+ * <dt>java.specification.name</dt> <dd>Java Runtime Environment name</dd>
+ * <dt>java.class.version</dt> <dd>Java class version number</dd>
+ * <dt>java.class.path</dt> <dd>Java classpath</dd>
+ * <dt>java.library.path</dt> <dd>Path for finding Java libraries</dd>
+ * <dt>java.io.tmpdir</dt> <dd>Default temp file path</dd>
+ * <dt>java.compiler</dt> <dd>Name of JIT to use</dd>
+ * <dt>java.ext.dirs</dt> <dd>Java extension path</dd>
+ * <dt>os.name</dt> <dd>Operating System Name</dd>
+ * <dt>os.arch</dt> <dd>Operating System Architecture</dd>
+ * <dt>os.version</dt> <dd>Operating System Version</dd>
+ * <dt>file.separator</dt> <dd>File separator ("/" on Unix)</dd>
+ * <dt>path.separator</dt> <dd>Path separator (":" on Unix)</dd>
+ * <dt>line.separator</dt> <dd>Line separator ("\n" on Unix)</dd>
+ * <dt>user.name</dt> <dd>User account name</dd>
+ * <dt>user.home</dt> <dd>User home directory</dd>
+ * <dt>user.dir</dt> <dd>User's current working directory</dd>
* </dl>
*
* In addition, gnu defines several other properties, where ? stands for
* each character in '0' through '9':
* <dl>
- * <dl> gnu.classpath.vm.shortname <dd> Succinct version of the VM name;
- * used for finding property files in file system
- * <dl> gnu.classpath.home.url <dd> Base URL; used for finding
- * property files in file system
- * <dt> gnu.cpu.endian <dd>big or little
- * <dt> gnu.java.io.encoding_scheme_alias.ISO-8859-? <dd>8859_?
- * <dt> gnu.java.io.encoding_scheme_alias.iso-8859-? <dd>8859_?
- * <dt> gnu.java.io.encoding_scheme_alias.iso8859_? <dd>8859_?
- * <dt> gnu.java.io.encoding_scheme_alias.iso-latin-_? <dd>8859_?
- * <dt> gnu.java.io.encoding_scheme_alias.latin? <dd>8859_?
- * <dt> gnu.java.io.encoding_scheme_alias.UTF-8 <dd>UTF8
- * <dt> gnu.java.io.encoding_scheme_alias.utf-8 <dd>UTF8
+ * <dt>gnu.classpath.home</dt> <dd>Path to the classpath libraries.</dd>
+ * <dt>gnu.classpath.version</dt> <dd>Version of the classpath libraries.</dd>
+ * <dt>gnu.classpath.vm.shortname</dt> <dd>Succinct version of the VM name;
+ * used for finding property files in file system</dd>
+ * <dt>gnu.classpath.home.url</dt> <dd> Base URL; used for finding
+ * property files in file system</dd>
+ * <dt>gnu.cpu.endian</dt> <dd>big or little</dd>
+ * <dt>gnu.java.io.encoding_scheme_alias.ISO-8859-?</dt> <dd>8859_?</dd>
+ * <dt>gnu.java.io.encoding_scheme_alias.iso-8859-?</dt> <dd>8859_?</dd>
+ * <dt>gnu.java.io.encoding_scheme_alias.iso8859_?</dt> <dd>8859_?</dd>
+ * <dt>gnu.java.io.encoding_scheme_alias.iso-latin-_?</dt> <dd>8859_?</dd>
+ * <dt>gnu.java.io.encoding_scheme_alias.latin?</dt> <dd>8859_?</dd>
+ * <dt>gnu.java.io.encoding_scheme_alias.UTF-8</dt> <dd>UTF8</dd>
+ * <dt>gnu.java.io.encoding_scheme_alias.utf-8</dt> <dd>UTF8</dd>
* </dl>
*
* @return the system properties, will never be null
@@ -599,4 +601,11 @@ public final class System
* @see #setErr(PrintStream)
*/
private static native void setErr0(PrintStream err);
+
+ /**
+ * Gets the value of an environment variable.
+ *
+ * @see #getenv(String)
+ */
+ static native String getenv0(String name);
} // class System
diff --git a/libjava/java/lang/ThreadGroup.java b/libjava/java/lang/ThreadGroup.java
index f0172630371..89aff3f0249 100644
--- a/libjava/java/lang/ThreadGroup.java
+++ b/libjava/java/lang/ThreadGroup.java
@@ -238,16 +238,16 @@ public class ThreadGroup
* Check whether this ThreadGroup is an ancestor of the specified
* ThreadGroup, or if they are the same.
*
- * @param g the group to test on
+ * @param group the group to test on
* @return whether this ThreadGroup is a parent of the specified group
*/
- public final boolean parentOf(ThreadGroup tg)
+ public final boolean parentOf(ThreadGroup group)
{
- while (tg != null)
+ while (group != null)
{
- if (tg == this)
+ if (group == this)
return true;
- tg = tg.parent;
+ group = group.parent;
}
return false;
}
@@ -535,7 +535,7 @@ public class ThreadGroup
* manner.
*
* @param thread the thread that exited
- * @param exception the uncaught exception
+ * @param t the uncaught throwable
* @throws NullPointerException if t is null
* @see ThreadDeath
* @see System#err
diff --git a/libjava/java/lang/Throwable.java b/libjava/java/lang/Throwable.java
index 62db8fd0d2d..1f236b085ed 100644
--- a/libjava/java/lang/Throwable.java
+++ b/libjava/java/lang/Throwable.java
@@ -37,13 +37,9 @@ exception statement from your version. */
package java.lang;
-import java.io.Serializable;
-import java.io.PrintWriter;
import java.io.PrintStream;
-import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
-import java.io.IOException;
-import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.Serializable;
/**
* Throwable is the superclass of all exceptions that can be raised.
@@ -392,7 +388,7 @@ public class Throwable implements Serializable
* then a line starting with three spaces and the string "... X more" is
* printed, where X is the number of remaining stackframes.
*
- * @param w the PrintWriter to write the trace to
+ * @param pw the PrintWriter to write the trace to
* @since 1.1
*/
public void printStackTrace (PrintWriter pw)
diff --git a/libjava/java/lang/VMClassLoader.java b/libjava/java/lang/VMClassLoader.java
index ac7a05e3cd9..8f78f9bb666 100644
--- a/libjava/java/lang/VMClassLoader.java
+++ b/libjava/java/lang/VMClassLoader.java
@@ -97,44 +97,31 @@ final class VMClassLoader
ProtectionDomain pd)
throws ClassFormatError;
- static final native void linkClass0 (Class klass);
- static final native void markClassErrorState0 (Class klass);
-
/**
* Helper to resolve all references to other classes from this class.
*
* @param c the class to resolve
*/
- static final void resolveClass(Class clazz)
+ static final native void resolveClass(Class clazz);
+
+ static final void transformException(Class clazz, Throwable x)
{
- synchronized (clazz)
+ LinkageError e;
+ if (x instanceof LinkageError)
+ e = (LinkageError) x;
+ else if (x instanceof ClassNotFoundException)
{
- try
- {
- linkClass0 (clazz);
- }
- catch (Throwable x)
- {
- markClassErrorState0 (clazz);
-
- LinkageError e;
- if (x instanceof LinkageError)
- e = (LinkageError) x;
- else if (x instanceof ClassNotFoundException)
- {
- e = new NoClassDefFoundError("while resolving class: "
- + clazz.getName());
- e.initCause (x);
- }
- else
- {
- e = new LinkageError ("unexpected exception during linking: "
- + clazz.getName());
- e.initCause (x);
- }
- throw e;
- }
+ e = new NoClassDefFoundError("while resolving class: "
+ + clazz.getName());
+ e.initCause (x);
+ }
+ else
+ {
+ e = new LinkageError ("unexpected exception during linking: "
+ + clazz.getName());
+ e.initCause (x);
}
+ throw e;
}
/**
diff --git a/libjava/java/lang/VMCompiler.java b/libjava/java/lang/VMCompiler.java
new file mode 100644
index 00000000000..fa4be84d735
--- /dev/null
+++ b/libjava/java/lang/VMCompiler.java
@@ -0,0 +1,259 @@
+/* VMClassLoader.java -- Reference implementation of compiler interface
+ Copyright (C) 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.security.MessageDigest;
+import java.security.ProtectionDomain;
+import java.util.WeakHashMap;
+import java.util.HashSet;
+import gnu.gcj.runtime.SharedLibHelper;
+
+/**
+ * This class is just a per-VM reflection of java.lang.Compiler.
+ * All methods are defined identically.
+ */
+final class VMCompiler
+{
+ // True if we want to use gcj-jit.
+ public static boolean useCompiler = true;
+
+ // True if we're able to use gcj-jit.
+ public static final boolean canUseCompiler;
+
+ // Compiler to use.
+ public static String gcjJitCompiler;
+
+ // Compiler options.
+ public static String gcjJitCompilerOptions;
+
+ // Temporary directory to use.
+ public static String gcjJitTmpdir;
+
+ // This maps a ClassLoader to a set of SharedLibHelper objects that
+ // it has used. We do things this way to ensure that a
+ // SharedLibHelper is collected if and only if the ClassLoader is.
+ private static WeakHashMap sharedHelperMap = new WeakHashMap();
+
+ static
+ {
+ gcjJitCompiler = System.getProperty("gnu.gcj.jit.compiler");
+ if (gcjJitCompiler == null)
+ canUseCompiler = false;
+ else
+ {
+ gcjJitCompilerOptions = System.getProperty("gnu.gcj.jit.options",
+ "-g");
+ gcjJitTmpdir = System.getProperty("gnu.gcj.jit.cachedir");
+ // Note that we *don't* choose java.io.tmpdir as a default --
+ // that would allow easy attacks against the VM.
+ if (gcjJitTmpdir == null)
+ canUseCompiler = false;
+ else
+ canUseCompiler = true;
+ }
+ }
+
+ /**
+ * Don't allow new `Compiler's to be made.
+ */
+ private VMCompiler()
+ {
+ }
+
+ private static Class loadSharedLibrary(ClassLoader loader,
+ String fileName,
+ ProtectionDomain domain,
+ String className)
+ {
+ Class c = null;
+ SharedLibHelper helper
+ = SharedLibHelper.findHelper (loader, fileName, domain.getCodeSource());
+ c = helper.findClass (className);
+ if (c != null)
+ {
+ HashSet hs = (HashSet) sharedHelperMap.get(loader);
+ if (hs == null)
+ {
+ hs = new HashSet();
+ sharedHelperMap.put(loader, hs);
+ }
+ hs.add(helper);
+ }
+ return c;
+ }
+
+ /**
+ * Compile a class given the bytes for it. Returns the Class, or
+ * null if compilation failed or otherwise could not be done.
+ */
+ public static Class compileClass(ClassLoader loader,
+ String name, byte[] data,
+ int offset, int len,
+ ProtectionDomain domain)
+ {
+ if (! useCompiler || ! canUseCompiler)
+ return null;
+
+ try
+ {
+ // FIXME: Make sure that the class represented by the
+ // bytes in DATA really is the class named in NAME. Make
+ // sure it's not "java.*".
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ byte digest[] = md.digest(data);
+ StringBuffer hexBytes = new StringBuffer(gcjJitTmpdir);
+ hexBytes.append(File.separatorChar);
+ int digestLength = digest.length;
+ for (int i = 0; i < digestLength; ++i)
+ hexBytes.append(Integer.toHexString(digest[i] & 0xff));
+
+ // FIXME: use System.mapLibraryName?
+ // I'm thinking we should use that, plus a class specified
+ // via a property that determines lookup policy.
+ File soFile = new File(hexBytes + ".so");
+ if (soFile.isFile())
+ return loadSharedLibrary (loader, soFile.toString(), domain,
+ name);
+
+ File classFile = new File(hexBytes + ".class");
+ classFile.delete();
+ if (classFile.createNewFile() != true)
+ return null;
+
+ FileOutputStream f = new FileOutputStream (classFile);
+ // FIXME: race condition if bytes change... ?
+ f.write(data, offset, len);
+
+ // Invoke the compiler.
+ StringBuffer command = new StringBuffer(gcjJitCompiler);
+ command.append(" ");
+ command.append(classFile);
+ command.append(" ");
+ command.append(gcjJitCompilerOptions);
+ // These options are required.
+ command.append(" -findirect-dispatch -fjni -shared -fPIC -o ");
+ command.append(soFile);
+ Process p = Runtime.getRuntime().exec(command.toString());
+
+ // Read the process' stderr into a string.
+ StringBuffer err = new StringBuffer();
+ InputStreamReader stderr = new InputStreamReader (p.getErrorStream());
+ char[] inBuf = new char[500];
+ int bytesRead;
+ while ((bytesRead = stderr.read (inBuf)) != -1)
+ err.append(inBuf, 0, bytesRead);
+
+ if (p.waitFor() != 0)
+ {
+ // FIXME: we could log err.toString() somewhere...
+ return null;
+ }
+
+ return loadSharedLibrary(loader, soFile.toString(), domain, name);
+ }
+ catch (Exception _)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Compile the class named by <code>oneClass</code>.
+ *
+ * @param oneClass the class to compile
+ * @return <code>false</code> if no compiler is available or
+ * compilation failed, <code>true</code> if compilation succeeded
+ * @throws NullPointerException if oneClass is null
+ */
+ public static boolean compileClass(Class oneClass)
+ {
+ // Never succeed.
+ return false;
+ }
+
+ /**
+ * Compile the classes whose name matches <code>classNames</code>.
+ *
+ * @param classNames the name of classes to compile
+ * @return <code>false</code> if no compiler is available or
+ * compilation failed, <code>true</code> if compilation succeeded
+ * @throws NullPointerException if classNames is null
+ */
+ public static boolean compileClasses(String classNames)
+ {
+ // Note the incredibly lame interface. Always fail.
+ return false;
+ }
+
+ /**
+ * This method examines the argument and performs an operation
+ * according to the compilers documentation. No specific operation
+ * is required.
+ *
+ * @param arg a compiler-specific argument
+ * @return a compiler-specific value, including null
+ * @throws NullPointerException if the compiler doesn't like a null arg
+ */
+ public static Object command(Object arg)
+ {
+ // Our implementation defines this to a no-op.
+ return null;
+ }
+
+ /**
+ * Calling <code>Compiler.enable()</code> will cause the compiler
+ * to resume operation if it was previously disabled; provided that a
+ * compiler even exists.
+ */
+ public static void enable()
+ {
+ useCompiler = true;
+ }
+
+ /**
+ * Calling <code>Compiler.disable()</code> will cause the compiler
+ * to be suspended; provided that a compiler even exists.
+ */
+ public static void disable()
+ {
+ useCompiler = false;
+ }
+}
diff --git a/libjava/java/lang/VMSecurityManager.java b/libjava/java/lang/VMSecurityManager.java
index f6f0645ac75..604f8ecb428 100644
--- a/libjava/java/lang/VMSecurityManager.java
+++ b/libjava/java/lang/VMSecurityManager.java
@@ -54,11 +54,12 @@ class VMSecurityManager
// The docs above are wrong. See the online docs.
// FIXME this implementation is a bit wrong too -- the docs say we
// must also consider ancestors of the system class loader.
+ ClassLoader systemClassLoader = VMClassLoader.getSystemClassLoader();
Class[] classStack = getClassContext ();
for (int i = 0; i < classStack.length; i++)
{
ClassLoader loader = classStack[i].getClassLoader();
- if (loader != null)
+ if (loader != null && loader != systemClassLoader)
return loader;
}
diff --git a/libjava/java/lang/natClass.cc b/libjava/java/lang/natClass.cc
index c11d2a15340..72ef0095be2 100644
--- a/libjava/java/lang/natClass.cc
+++ b/libjava/java/lang/natClass.cc
@@ -14,6 +14,7 @@ details. */
#include <limits.h>
#include <string.h>
#include <stddef.h>
+#include <stdio.h>
#pragma implementation "Class.h"
@@ -56,9 +57,13 @@ details. */
#include <gcj/method.h>
#include <gnu/gcj/runtime/MethodRef.h>
#include <gnu/gcj/RawData.h>
+#include <java/lang/VerifyError.h>
#include <java-cpool.h>
#include <java-interp.h>
+#include <java-assert.h>
+#include <execution.h>
+
using namespace gcj;
@@ -485,7 +490,12 @@ java::lang::Class::getInterfaces (void)
jobjectArray r = JvNewObjectArray (interface_count, getClass (), NULL);
jobject *data = elements (r);
for (int i = 0; i < interface_count; ++i)
- data[i] = interfaces[i];
+ {
+ typedef unsigned int uaddr __attribute__ ((mode (pointer)));
+ data[i] = interfaces[i];
+ if ((uaddr)data[i] < (uaddr)constants.size)
+ fprintf (stderr, "ERROR !!!\n");
+ }
return reinterpret_cast<JArray<jclass> *> (r);
}
@@ -495,7 +505,8 @@ java::lang::Class::_getMethod (jstring name, JArray<jclass> *param_types)
jstring partial_sig = getSignature (param_types, false);
jint p_len = partial_sig->length();
_Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name);
- for (Class *klass = this; klass; klass = klass->getSuperclass())
+
+ for (Class *klass = this; klass; klass = klass->getSuperclass())
{
int i = klass->isPrimitive () ? 0 : klass->method_count;
while (--i >= 0)
@@ -691,7 +702,7 @@ java::lang::Class::newInstance (void)
if (! meth)
throw new java::lang::InstantiationException (getName());
- jobject r = JvAllocObject (this);
+ jobject r = _Jv_AllocObject (this);
((void (*) (jobject)) meth->ncode) (r);
return r;
}
@@ -699,10 +710,7 @@ java::lang::Class::newInstance (void)
void
java::lang::Class::finalize (void)
{
-#ifdef INTERPRETER
- JvAssert (_Jv_IsInterpretedClass (this));
- _Jv_UnregisterClass (this);
-#endif
+ engine->unregister(this);
}
// This implements the initialization process for a class. From Spec
@@ -710,67 +718,37 @@ java::lang::Class::finalize (void)
void
java::lang::Class::initializeClass (void)
{
- // short-circuit to avoid needless locking.
+ // Short-circuit to avoid needless locking.
if (state == JV_STATE_DONE)
return;
- // Step 1.
- _Jv_MonitorEnter (this);
+ // Step 1. We introduce a new scope so we can synchronize more
+ // easily.
+ {
+ JvSynchronize sync (this);
- if (state < JV_STATE_LINKED)
- {
-#ifdef INTERPRETER
- if (_Jv_IsInterpretedClass (this))
- {
- // this can throw exceptions, so exit the monitor as a precaution.
- _Jv_MonitorExit (this);
- java::lang::VMClassLoader::resolveClass (this);
- _Jv_MonitorEnter (this);
- }
- else
-#endif
- {
- _Jv_PrepareCompiledClass (this);
- }
- }
+ if (state < JV_STATE_LINKED)
+ java::lang::VMClassLoader::resolveClass (this);
- // Step 2.
- java::lang::Thread *self = java::lang::Thread::currentThread();
- // FIXME: `self' can be null at startup. Hence this nasty trick.
- self = (java::lang::Thread *) ((long) self | 1);
- while (state == JV_STATE_IN_PROGRESS && thread && thread != self)
- wait ();
+ // Step 2.
+ java::lang::Thread *self = java::lang::Thread::currentThread();
+ self = (java::lang::Thread *) ((long) self | 1);
+ while (state == JV_STATE_IN_PROGRESS && thread && thread != self)
+ wait ();
- // Steps 3 & 4.
- if (state == JV_STATE_DONE)
- {
- _Jv_MonitorExit (this);
+ // Steps 3 & 4.
+ if (state == JV_STATE_DONE || state == JV_STATE_IN_PROGRESS)
return;
- }
- if (state == JV_STATE_IN_PROGRESS)
- {
- _Jv_MonitorExit (this);
-
- /* Initialization in progress. The class is linked now,
- so ensure internal tables are built. */
- _Jv_PrepareConstantTimeTables (this);
- _Jv_MakeVTable(this);
- _Jv_LinkSymbolTable(this);
-
- return;
- }
- // Step 5.
- if (state == JV_STATE_ERROR)
- {
- _Jv_MonitorExit (this);
+ // Step 5.
+ if (state == JV_STATE_ERROR)
throw new java::lang::NoClassDefFoundError (getName());
- }
- // Step 6.
- thread = self;
- state = JV_STATE_IN_PROGRESS;
- _Jv_MonitorExit (this);
+ // Step 6.
+ thread = self;
+ _Jv_Linker::wait_for_state (this, JV_STATE_LINKED);
+ state = JV_STATE_IN_PROGRESS;
+ }
// Step 7.
if (! isInterface () && superclass)
@@ -782,24 +760,13 @@ java::lang::Class::initializeClass (void)
catch (java::lang::Throwable *except)
{
// Caught an exception.
- _Jv_MonitorEnter (this);
+ JvSynchronize sync (this);
state = JV_STATE_ERROR;
notifyAll ();
- _Jv_MonitorExit (this);
throw except;
}
}
- _Jv_PrepareConstantTimeTables (this);
-
- if (vtable == NULL)
- _Jv_MakeVTable(this);
-
- if (otable || atable)
- _Jv_LinkSymbolTable(this);
-
- _Jv_linkExceptionClassTable (this);
-
// Steps 8, 9, 10, 11.
try
{
@@ -821,17 +788,91 @@ java::lang::Class::initializeClass (void)
except = t;
}
}
- _Jv_MonitorEnter (this);
+
+ JvSynchronize sync (this);
state = JV_STATE_ERROR;
notifyAll ();
- _Jv_MonitorExit (this);
throw except;
}
- _Jv_MonitorEnter (this);
+ JvSynchronize sync (this);
state = JV_STATE_DONE;
notifyAll ();
- _Jv_MonitorExit (this);
+}
+
+// Only used by serialization
+java::lang::reflect::Field *
+java::lang::Class::getPrivateField (jstring name)
+{
+ int hash = name->hashCode ();
+
+ java::lang::reflect::Field* rfield;
+ for (int i = 0; i < field_count; i++)
+ {
+ _Jv_Field *field = &fields[i];
+ if (! _Jv_equal (field->name, name, hash))
+ continue;
+ rfield = new java::lang::reflect::Field ();
+ rfield->offset = (char*) field - (char*) fields;
+ rfield->declaringClass = this;
+ rfield->name = name;
+ return rfield;
+ }
+ jclass superclass = getSuperclass();
+ if (superclass == NULL)
+ return NULL;
+ rfield = superclass->getPrivateField(name);
+ for (int i = 0; i < interface_count && rfield == NULL; ++i)
+ rfield = interfaces[i]->getPrivateField (name);
+ return rfield;
+}
+
+// Only used by serialization
+java::lang::reflect::Method *
+java::lang::Class::getPrivateMethod (jstring name, JArray<jclass> *param_types)
+{
+ jstring partial_sig = getSignature (param_types, false);
+ jint p_len = partial_sig->length();
+ _Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name);
+ for (Class *klass = this; klass; klass = klass->getSuperclass())
+ {
+ int i = klass->isPrimitive () ? 0 : klass->method_count;
+ while (--i >= 0)
+ {
+ if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name)
+ && _Jv_equaln (klass->methods[i].signature, partial_sig, p_len))
+ {
+ // Found it.
+ using namespace java::lang::reflect;
+
+ Method *rmethod = new Method ();
+ rmethod->offset = ((char *) (&klass->methods[i])
+ - (char *) klass->methods);
+ rmethod->declaringClass = klass;
+ return rmethod;
+ }
+ }
+ }
+ throw new java::lang::NoSuchMethodException (name);
+}
+
+// Private accessor method for Java code to retrieve the protection domain.
+java::security::ProtectionDomain *
+java::lang::Class::getProtectionDomain0 ()
+{
+ return protectionDomain;
+}
+
+JArray<jobject> *
+java::lang::Class::getSigners()
+{
+ return hack_signers;
+}
+
+void
+java::lang::Class::setSigners(JArray<jobject> *s)
+{
+ hack_signers = s;
}
@@ -857,14 +898,19 @@ _Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
_Jv_Method *
_Jv_LookupDeclaredMethod (jclass klass, _Jv_Utf8Const *name,
- _Jv_Utf8Const *signature)
+ _Jv_Utf8Const *signature,
+ jclass *declarer_result)
{
for (; klass; klass = klass->getSuperclass())
{
_Jv_Method *meth = _Jv_GetMethodLocal (klass, name, signature);
if (meth)
- return meth;
+ {
+ if (declarer_result)
+ *declarer_result = klass;
+ return meth;
+ }
}
return NULL;
@@ -1085,887 +1131,122 @@ _Jv_CheckArrayStore (jobject arr, jobject obj)
}
}
-#define INITIAL_IOFFSETS_LEN 4
-#define INITIAL_IFACES_LEN 4
-
-static _Jv_IDispatchTable null_idt = { {SHRT_MAX, 0, NULL} };
-
-// Generate tables for constant-time assignment testing and interface
-// method lookup. This implements the technique described by Per Bothner
-// <per@bothner.com> on the java-discuss mailing list on 1999-09-02:
-// http://gcc.gnu.org/ml/java/1999-q3/msg00377.html
-void
-_Jv_PrepareConstantTimeTables (jclass klass)
-{
- if (klass->isPrimitive () || klass->isInterface ())
- return;
-
- // Short-circuit in case we've been called already.
- if ((klass->idt != NULL) || klass->depth != 0)
- return;
-
- // Calculate the class depth and ancestor table. The depth of a class
- // is how many "extends" it is removed from Object. Thus the depth of
- // java.lang.Object is 0, but the depth of java.io.FilterOutputStream
- // is 2. Depth is defined for all regular and array classes, but not
- // interfaces or primitive types.
-
- jclass klass0 = klass;
- jboolean has_interfaces = 0;
- while (klass0 != &java::lang::Object::class$)
- {
- has_interfaces += klass0->interface_count;
- klass0 = klass0->superclass;
- klass->depth++;
- }
-
- // We do class member testing in constant time by using a small table
- // of all the ancestor classes within each class. The first element is
- // a pointer to the current class, and the rest are pointers to the
- // classes ancestors, ordered from the current class down by decreasing
- // depth. We do not include java.lang.Object in the table of ancestors,
- // since it is redundant.
-
- klass->ancestors = (jclass *) _Jv_Malloc (klass->depth * sizeof (jclass));
- klass0 = klass;
- for (int index = 0; index < klass->depth; index++)
- {
- klass->ancestors[index] = klass0;
- klass0 = klass0->superclass;
- }
-
- if (java::lang::reflect::Modifier::isAbstract (klass->accflags))
- return;
-
- // Optimization: If class implements no interfaces, use a common
- // predefined interface table.
- if (!has_interfaces)
- {
- klass->idt = &null_idt;
- return;
- }
-
- klass->idt =
- (_Jv_IDispatchTable *) _Jv_Malloc (sizeof (_Jv_IDispatchTable));
-
- _Jv_ifaces ifaces;
-
- ifaces.count = 0;
- ifaces.len = INITIAL_IFACES_LEN;
- ifaces.list = (jclass *) _Jv_Malloc (ifaces.len * sizeof (jclass *));
-
- int itable_size = _Jv_GetInterfaces (klass, &ifaces);
-
- if (ifaces.count > 0)
- {
- klass->idt->cls.itable =
- (void **) _Jv_Malloc (itable_size * sizeof (void *));
- klass->idt->cls.itable_length = itable_size;
-
- jshort *itable_offsets =
- (jshort *) _Jv_Malloc (ifaces.count * sizeof (jshort));
-
- _Jv_GenerateITable (klass, &ifaces, itable_offsets);
-
- jshort cls_iindex =
- _Jv_FindIIndex (ifaces.list, itable_offsets, ifaces.count);
-
- for (int i=0; i < ifaces.count; i++)
- {
- ifaces.list[i]->idt->iface.ioffsets[cls_iindex] =
- itable_offsets[i];
- }
-
- klass->idt->cls.iindex = cls_iindex;
-
- _Jv_Free (ifaces.list);
- _Jv_Free (itable_offsets);
- }
- else
- {
- klass->idt->cls.iindex = SHRT_MAX;
- }
-}
-
-// Return index of item in list, or -1 if item is not present.
-inline jshort
-_Jv_IndexOf (void *item, void **list, jshort list_len)
+jboolean
+_Jv_IsAssignableFromSlow (jclass target, jclass source)
{
- for (int i=0; i < list_len; i++)
+ // First, strip arrays.
+ while (target->isArray ())
{
- if (list[i] == item)
- return i;
+ // If target is array, source must be as well.
+ if (! source->isArray ())
+ return false;
+ target = target->getComponentType ();
+ source = source->getComponentType ();
}
- return -1;
-}
-
-// Find all unique interfaces directly or indirectly implemented by klass.
-// Returns the size of the interface dispatch table (itable) for klass, which
-// is the number of unique interfaces plus the total number of methods that
-// those interfaces declare. May extend ifaces if required.
-jshort
-_Jv_GetInterfaces (jclass klass, _Jv_ifaces *ifaces)
-{
- jshort result = 0;
-
- for (int i=0; i < klass->interface_count; i++)
- {
- jclass iface = klass->interfaces[i];
-
- /* Make sure interface is linked. */
- _Jv_WaitForState(iface, JV_STATE_LINKED);
- if (_Jv_IndexOf (iface, (void **) ifaces->list, ifaces->count) == -1)
- {
- if (ifaces->count + 1 >= ifaces->len)
- {
- /* Resize ifaces list */
- ifaces->len = ifaces->len * 2;
- ifaces->list = (jclass *) _Jv_Realloc (ifaces->list,
- ifaces->len * sizeof(jclass));
- }
- ifaces->list[ifaces->count] = iface;
- ifaces->count++;
+ // Quick success.
+ if (target == &java::lang::Object::class$)
+ return true;
- result += _Jv_GetInterfaces (klass->interfaces[i], ifaces);
- }
- }
-
- if (klass->isInterface())
+ do
{
- result += klass->method_count + 1;
- }
- else
- {
- if (klass->superclass)
- {
- result += _Jv_GetInterfaces (klass->superclass, ifaces);
- }
+ if (source == target)
+ return true;
+
+ if (target->isPrimitive () || source->isPrimitive ())
+ return false;
+
+ if (target->isInterface ())
+ {
+ for (int i = 0; i < source->interface_count; ++i)
+ {
+ // We use a recursive call because we also need to
+ // check superinterfaces.
+ if (_Jv_IsAssignableFromSlow (target, source->getInterface (i)))
+ return true;
+ }
+ }
+ source = source->getSuperclass ();
}
- return result;
-}
+ while (source != NULL);
-// Fill out itable in klass, resolving method declarations in each ifaces.
-// itable_offsets is filled out with the position of each iface in itable,
-// such that itable[itable_offsets[n]] == ifaces.list[n].
-void
-_Jv_GenerateITable (jclass klass, _Jv_ifaces *ifaces, jshort *itable_offsets)
-{
- void **itable = klass->idt->cls.itable;
- jshort itable_pos = 0;
-
- for (int i=0; i < ifaces->count; i++)
- {
- jclass iface = ifaces->list[i];
- itable_offsets[i] = itable_pos;
- itable_pos = _Jv_AppendPartialITable (klass, iface, itable, itable_pos);
-
- /* Create interface dispatch table for iface */
- if (iface->idt == NULL)
- {
- iface->idt =
- (_Jv_IDispatchTable *) _Jv_Malloc (sizeof (_Jv_IDispatchTable));
-
- // The first element of ioffsets is its length (itself included).
- jshort *ioffsets =
- (jshort *) _Jv_Malloc (INITIAL_IOFFSETS_LEN * sizeof (jshort));
- ioffsets[0] = INITIAL_IOFFSETS_LEN;
- for (int i=1; i < INITIAL_IOFFSETS_LEN; i++)
- ioffsets[i] = -1;
-
- iface->idt->iface.ioffsets = ioffsets;
- }
- }
-}
-
-// Format method name for use in error messages.
-jstring
-_Jv_GetMethodString (jclass klass, _Jv_Utf8Const *name)
-{
- jstring r = JvNewStringUTF (klass->name->data);
- r = r->concat (JvNewStringUTF ("."));
- r = r->concat (JvNewStringUTF (name->data));
- return r;
-}
-
-void
-_Jv_ThrowNoSuchMethodError ()
-{
- throw new java::lang::NoSuchMethodError;
+ return false;
}
-// Each superinterface of a class (i.e. each interface that the class
-// directly or indirectly implements) has a corresponding "Partial
-// Interface Dispatch Table" whose size is (number of methods + 1) words.
-// The first word is a pointer to the interface (i.e. the java.lang.Class
-// instance for that interface). The remaining words are pointers to the
-// actual methods that implement the methods declared in the interface,
-// in order of declaration.
-//
-// Append partial interface dispatch table for "iface" to "itable", at
-// position itable_pos.
-// Returns the offset at which the next partial ITable should be appended.
-jshort
-_Jv_AppendPartialITable (jclass klass, jclass iface, void **itable,
- jshort pos)
+// Check that SOURCE is assignment compatible with DEST. Both are
+// loaded with the indicated class loader. Neither is prepared.
+// Throws appropriate exception, usually VerifyError, on failure.
+void
+_Jv_CheckAssignment (java::lang::ClassLoader *loader,
+ _Jv_Utf8Const *source_name,
+ _Jv_Utf8Const *dest_name)
{
- using namespace java::lang::reflect;
+ jclass source = _Jv_FindClassFromSignature (source_name->data, loader);
+ jclass dest = _Jv_FindClassFromSignature (dest_name->data, loader);
- itable[pos++] = (void *) iface;
- _Jv_Method *meth;
-
- for (int j=0; j < iface->method_count; j++)
+ if (! _Jv_IsAssignableFromSlow (dest, source))
{
- meth = NULL;
- for (jclass cl = klass; cl; cl = cl->getSuperclass())
- {
- meth = _Jv_GetMethodLocal (cl, iface->methods[j].name,
- iface->methods[j].signature);
-
- if (meth)
- break;
- }
-
- if (meth && (meth->name->data[0] == '<'))
- {
- // leave a placeholder in the itable for hidden init methods.
- itable[pos] = NULL;
- }
- else if (meth)
- {
- if (Modifier::isStatic(meth->accflags))
- throw new java::lang::IncompatibleClassChangeError
- (_Jv_GetMethodString (klass, meth->name));
- if (Modifier::isAbstract(meth->accflags))
- throw new java::lang::AbstractMethodError
- (_Jv_GetMethodString (klass, meth->name));
- if (! Modifier::isPublic(meth->accflags))
- throw new java::lang::IllegalAccessError
- (_Jv_GetMethodString (klass, meth->name));
-
- itable[pos] = meth->ncode;
- }
- else
- {
- // The method doesn't exist in klass. Binary compatibility rules
- // permit this, so we delay the error until runtime using a pointer
- // to a method which throws an exception.
- itable[pos] = (void *) _Jv_ThrowNoSuchMethodError;
- }
- pos++;
+ using namespace java::lang;
+ StringBuffer *sb = new StringBuffer();
+ sb->append(dest->getName());
+ sb->append(JvNewStringLatin1(" isn't assignable from "));
+ sb->append(source->getName());
+ throw new VerifyError(sb->toString());
}
-
- return pos;
}
-static _Jv_Mutex_t iindex_mutex;
-static bool iindex_mutex_initialized = false;
-
-// We need to find the correct offset in the Class Interface Dispatch
-// Table for a given interface. Once we have that, invoking an interface
-// method just requires combining the Method's index in the interface
-// (known at compile time) to get the correct method. Doing a type test
-// (cast or instanceof) is the same problem: Once we have a possible Partial
-// Interface Dispatch Table, we just compare the first element to see if it
-// matches the desired interface. So how can we find the correct offset?
-// Our solution is to keep a vector of candiate offsets in each interface
-// (idt->iface.ioffsets), and in each class we have an index
-// (idt->cls.iindex) used to select the correct offset from ioffsets.
+// Lookup an interface method by name. This is very similar to
+// purpose to _getMethod, but the interfaces are quite different. It
+// might be a good idea for _getMethod to call this function.
//
-// Calculate and return iindex for a new class.
-// ifaces is a vector of num interfaces that the class implements.
-// offsets[j] is the offset in the interface dispatch table for the
-// interface corresponding to ifaces[j].
-// May extend the interface ioffsets if required.
-jshort
-_Jv_FindIIndex (jclass *ifaces, jshort *offsets, jshort num)
+// Return true of the method is found, with the class in FOUND_CLASS
+// and the index in INDEX.
+bool
+_Jv_getInterfaceMethod (jclass search_class, jclass &found_class, int &index,
+ const _Jv_Utf8Const *utf_name,
+ const _Jv_Utf8Const *utf_sig)
{
- int i;
- int j;
-
- // Acquire a global lock to prevent itable corruption in case of multiple
- // classes that implement an intersecting set of interfaces being linked
- // simultaneously. We can assume that the mutex will be initialized
- // single-threaded.
- if (! iindex_mutex_initialized)
- {
- _Jv_MutexInit (&iindex_mutex);
- iindex_mutex_initialized = true;
- }
-
- _Jv_MutexLock (&iindex_mutex);
-
- for (i=1;; i++) /* each potential position in ioffsets */
+ for (jclass klass = search_class; klass; klass = klass->getSuperclass())
{
- for (j=0;; j++) /* each iface */
- {
- if (j >= num)
- goto found;
- if (i >= ifaces[j]->idt->iface.ioffsets[0])
- continue;
- int ioffset = ifaces[j]->idt->iface.ioffsets[i];
- /* We can potentially share this position with another class. */
- if (ioffset >= 0 && ioffset != offsets[j])
- break; /* Nope. Try next i. */
- }
- }
- found:
- for (j = 0; j < num; j++)
- {
- int len = ifaces[j]->idt->iface.ioffsets[0];
- if (i >= len)
- {
- /* Resize ioffsets. */
- int newlen = 2 * len;
- if (i >= newlen)
- newlen = i + 3;
- jshort *old_ioffsets = ifaces[j]->idt->iface.ioffsets;
- jshort *new_ioffsets = (jshort *) _Jv_Realloc (old_ioffsets,
- newlen * sizeof(jshort));
- new_ioffsets[0] = newlen;
-
- while (len < newlen)
- new_ioffsets[len++] = -1;
-
- ifaces[j]->idt->iface.ioffsets = new_ioffsets;
- }
- ifaces[j]->idt->iface.ioffsets[i] = offsets[j];
- }
-
- _Jv_MutexUnlock (&iindex_mutex);
-
- return i;
-}
-
-// Only used by serialization
-java::lang::reflect::Field *
-java::lang::Class::getPrivateField (jstring name)
-{
- int hash = name->hashCode ();
-
- java::lang::reflect::Field* rfield;
- for (int i = 0; i < field_count; i++)
- {
- _Jv_Field *field = &fields[i];
- if (! _Jv_equal (field->name, name, hash))
- continue;
- rfield = new java::lang::reflect::Field ();
- rfield->offset = (char*) field - (char*) fields;
- rfield->declaringClass = this;
- rfield->name = name;
- return rfield;
- }
- jclass superclass = getSuperclass();
- if (superclass == NULL)
- return NULL;
- rfield = superclass->getPrivateField(name);
- for (int i = 0; i < interface_count && rfield == NULL; ++i)
- rfield = interfaces[i]->getPrivateField (name);
- return rfield;
-}
-
-// Only used by serialization
-java::lang::reflect::Method *
-java::lang::Class::getPrivateMethod (jstring name, JArray<jclass> *param_types)
-{
- jstring partial_sig = getSignature (param_types, false);
- jint p_len = partial_sig->length();
- _Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name);
- for (Class *klass = this; klass; klass = klass->getSuperclass())
- {
- int i = klass->isPrimitive () ? 0 : klass->method_count;
+ // FIXME: Throw an exception?
+ if (!klass->isInterface ())
+ return false;
+
+ int i = klass->method_count;
while (--i >= 0)
{
if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name)
- && _Jv_equaln (klass->methods[i].signature, partial_sig, p_len))
+ && _Jv_equalUtf8Consts (klass->methods[i].signature, utf_sig))
{
// Found it.
using namespace java::lang::reflect;
- Method *rmethod = new Method ();
- rmethod->offset = ((char *) (&klass->methods[i])
- - (char *) klass->methods);
- rmethod->declaringClass = klass;
- return rmethod;
- }
- }
- }
- throw new java::lang::NoSuchMethodException (name);
-}
-
-// Private accessor method for Java code to retrieve the protection domain.
-java::security::ProtectionDomain *
-java::lang::Class::getProtectionDomain0 ()
-{
- return protectionDomain;
-}
-
-JArray<jobject> *
-java::lang::Class::getSigners()
-{
- return hack_signers;
-}
-
-void
-java::lang::Class::setSigners(JArray<jobject> *s)
-{
- hack_signers = s;
-}
-
-// Functions for indirect dispatch (symbolic virtual binding) support.
-
-// There are two tables, atable and otable. atable is an array of
-// addresses, and otable is an array of offsets, and these are used
-// for static and virtual members respectively.
-
-// {a,o}table_syms is an array of _Jv_MethodSymbols. Each such symbol
-// is a tuple of {classname, member name, signature}.
-// _Jv_LinkSymbolTable() scans these two arrays and fills in the
-// corresponding atable and otable with the addresses of static
-// members and the offsets of virtual members.
-
-// The offset (in bytes) for each resolved method or field is placed
-// at the corresponding position in the virtual method offset table
-// (klass->otable).
-
-// The same otable and atable may be shared by many classes.
-
-void
-_Jv_LinkSymbolTable(jclass klass)
-{
- //// FIXME: Need to lock the tables ////
-
- int index = 0;
- _Jv_MethodSymbol sym;
- if (klass->otable == NULL
- || klass->otable->state != 0)
- goto atable;
-
- klass->otable->state = 1;
-
- for (index = 0; sym = klass->otable_syms[index], sym.name != NULL; index++)
- {
- // FIXME: Why are we passing NULL as the class loader?
- jclass target_class = _Jv_FindClass (sym.class_name, NULL);
- _Jv_Method *meth = NULL;
-
- const _Jv_Utf8Const *signature = sym.signature;
-
- {
- static char *bounce = (char *)_Jv_ThrowNoSuchMethodError;
- ptrdiff_t offset = (char *)(klass->vtable) - bounce;
- klass->otable->offsets[index] = offset;
- }
-
- if (target_class == NULL)
- continue;
-
- if (target_class->isInterface())
- {
- // FIXME: This does not yet fully conform to binary compatibility
- // rules. It will break if a declaration is moved into a
- // superinterface.
- for (jclass cls = target_class; cls != 0; cls = cls->getSuperclass ())
- {
- for (int i=0; i < cls->method_count; i++)
- {
- meth = &cls->methods[i];
- if (_Jv_equalUtf8Consts (sym.name, meth->name)
- && _Jv_equalUtf8Consts (signature, meth->signature))
- {
- klass->otable->offsets[index] = i + 1;
- goto found;
- }
- }
-
- }
- found:
- continue;
- }
-
- // We're looking for a field or a method, and we can tell
- // which is needed by looking at the signature.
- if (signature->length >= 2
- && signature->data[0] == '(')
- {
- // If the target class does not have a vtable_method_count yet,
- // then we can't tell the offsets for its methods, so we must lay
- // it out now.
- if (target_class->vtable_method_count == -1)
- {
- JvSynchronize sync (target_class);
- _Jv_LayoutVTableMethods (target_class);
- }
-
- meth = _Jv_LookupDeclaredMethod(target_class, sym.name,
- sym.signature);
-
- if (meth != NULL)
- {
- klass->otable->offsets[index] =
- _Jv_VTable::idx_to_offset (meth->index);
- }
-
- continue;
- }
-
- // try fields
- {
- _Jv_Field *the_field = NULL;
-
- for (jclass cls = target_class; cls != 0; cls = cls->getSuperclass ())
- {
- for (int i = 0; i < cls->field_count; i++)
- {
- _Jv_Field *field = &cls->fields[i];
- if (! _Jv_equalUtf8Consts (field->name, sym.name))
- continue;
-
- // FIXME: What access checks should we perform here?
-// if (_Jv_CheckAccess (klass, cls, field->flags))
-// {
-
- if (!field->isResolved ())
- _Jv_ResolveField (field, cls->loader);
-
-// if (field_type != 0 && field->type != field_type)
-// throw new java::lang::LinkageError
-// (JvNewStringLatin1
-// ("field type mismatch with different loaders"));
-
- the_field = field;
- goto end_of_field_search;
- }
- }
- end_of_field_search:
- if (the_field != NULL)
- {
- if (the_field->flags & 0x0008 /* Modifier::STATIC */)
- {
- throw new java::lang::IncompatibleClassChangeError;
- }
- else
- {
- klass->otable->offsets[index] = the_field->u.boffset;
- }
- }
- else
- {
- throw new java::lang::NoSuchFieldError
- (_Jv_NewStringUtf8Const (sym.name));
- }
- }
- }
-
- atable:
- if (klass->atable == NULL
- || klass->atable->state != 0)
- return;
-
- klass->atable->state = 1;
-
- for (index = 0; sym = klass->atable_syms[index], sym.name != NULL; index++)
- {
- // FIXME: Why are we passing NULL as the class loader?
- jclass target_class = _Jv_FindClass (sym.class_name, NULL);
- _Jv_Method *meth = NULL;
- const _Jv_Utf8Const *signature = sym.signature;
-
- // ??? Setting this pointer to null will at least get us a
- // NullPointerException
- klass->atable->addresses[index] = NULL;
-
- if (target_class == NULL)
- continue;
-
- // We're looking for a static field or a static method, and we
- // can tell which is needed by looking at the signature.
- if (signature->length >= 2
- && signature->data[0] == '(')
- {
- // If the target class does not have a vtable_method_count yet,
- // then we can't tell the offsets for its methods, so we must lay
- // it out now.
- if (target_class->vtable_method_count == -1)
- {
- JvSynchronize sync (target_class);
- _Jv_LayoutVTableMethods (target_class);
- }
-
- meth = _Jv_LookupDeclaredMethod(target_class, sym.name,
- sym.signature);
-
- if (meth != NULL)
- {
- if (meth->ncode) // Maybe abstract?
- klass->atable->addresses[index] = meth->ncode;
-#ifdef INTERPRETER
- else if (_Jv_IsInterpretedClass (target_class))
- _Jv_Defer_Resolution (target_class, meth,
- &klass->atable->addresses[index]);
-#endif
- }
- else
- klass->atable->addresses[index] = (void *)_Jv_ThrowNoSuchMethodError;
-
- continue;
- }
-
- // try fields
- {
- _Jv_Field *the_field = NULL;
-
- for (jclass cls = target_class; cls != 0; cls = cls->getSuperclass ())
- {
- for (int i = 0; i < cls->field_count; i++)
- {
- _Jv_Field *field = &cls->fields[i];
- if (! _Jv_equalUtf8Consts (field->name, sym.name))
- continue;
-
- // FIXME: What access checks should we perform here?
-// if (_Jv_CheckAccess (klass, cls, field->flags))
-// {
-
- if (!field->isResolved ())
- _Jv_ResolveField (field, cls->loader);
-
-// if (field_type != 0 && field->type != field_type)
-// throw new java::lang::LinkageError
-// (JvNewStringLatin1
-// ("field type mismatch with different loaders"));
-
- the_field = field;
- goto end_of_static_field_search;
- }
- }
- end_of_static_field_search:
- if (the_field != NULL)
- {
- if (the_field->flags & 0x0008 /* Modifier::STATIC */)
- {
- klass->atable->addresses[index] = the_field->u.addr;
- }
- else
- {
- throw new java::lang::IncompatibleClassChangeError;
- }
- }
- else
- {
- throw new java::lang::NoSuchFieldError
- (_Jv_NewStringUtf8Const (sym.name));
- }
- }
- }
-}
-
-
-// For each catch_record in the list of caught classes, fill in the
-// address field.
-void
-_Jv_linkExceptionClassTable (jclass self)
-{
- struct _Jv_CatchClass *catch_record = self->catch_classes;
- if (!catch_record || catch_record->classname)
- return;
- catch_record++;
- while (catch_record->classname)
- {
- jclass target_class = _Jv_FindClass (catch_record->classname,
- self->getClassLoaderInternal ());
- *catch_record->address = target_class;
- catch_record++;
- }
- self->catch_classes->classname = (_Jv_Utf8Const *)-1;
-}
-
-// This is put in empty vtable slots.
-static void
-_Jv_abstractMethodError (void)
-{
- throw new java::lang::AbstractMethodError();
-}
-
-// Prepare virtual method declarations in KLASS, and any superclasses as
-// required, by determining their vtable index, setting method->index, and
-// finally setting the class's vtable_method_count. Must be called with the
-// lock for KLASS held.
-void
-_Jv_LayoutVTableMethods (jclass klass)
-{
- if (klass->vtable != NULL || klass->isInterface()
- || klass->vtable_method_count != -1)
- return;
-
- jclass superclass = klass->superclass;
-
- typedef unsigned int uaddr __attribute__ ((mode (pointer)));
+ // FIXME: Method must be public. Throw an exception?
+ if (! Modifier::isPublic (klass->methods[i].accflags))
+ break;
- // If superclass looks like a constant pool entry,
- // resolve it now.
- if ((uaddr)superclass < (uaddr)klass->constants.size)
- {
- if (klass->state < JV_STATE_LINKED)
- {
- _Jv_Utf8Const *name = klass->constants.data[(int)superclass].utf8;
- superclass = _Jv_FindClass (name, klass->loader);
- if (! superclass)
- {
- jstring str = _Jv_NewStringUTF (name->data);
- throw new java::lang::NoClassDefFoundError (str);
+ found_class = klass;
+ // Interface method indexes count from 1.
+ index = i+1;
+ return true;
}
}
- else
- superclass = klass->constants.data[(int)superclass].clazz;
- }
-
- if (superclass != NULL && superclass->vtable_method_count == -1)
- {
- JvSynchronize sync (superclass);
- _Jv_LayoutVTableMethods (superclass);
- }
-
- int index = (superclass == NULL ? 0 : superclass->vtable_method_count);
-
- for (int i = 0; i < klass->method_count; ++i)
- {
- _Jv_Method *meth = &klass->methods[i];
- _Jv_Method *super_meth = NULL;
-
- if (! _Jv_isVirtualMethod (meth))
- continue;
-
- // FIXME: Must check that we don't override:
- // - Package-private method where superclass is in different package.
- // - Final or less-accessible declaration in superclass (check binary
- // spec, do we allocate new vtable entry or put throw node in vtable?)
- // - Static or private method in superclass.
-
- if (superclass != NULL)
- {
- super_meth = _Jv_LookupDeclaredMethod (superclass, meth->name,
- meth->signature);
- }
-
- if (super_meth)
- meth->index = super_meth->index;
- else
- meth->index = index++;
}
- klass->vtable_method_count = index;
-}
-
-// Set entries in VTABLE for virtual methods declared in KLASS. If
-// KLASS has an immediate abstract parent, recursively do its methods
-// first. FLAGS is used to determine which slots we've actually set.
-void
-_Jv_SetVTableEntries (jclass klass, _Jv_VTable *vtable, jboolean *flags)
-{
- using namespace java::lang::reflect;
-
- jclass superclass = klass->getSuperclass();
-
- if (superclass != NULL && (superclass->getModifiers() & Modifier::ABSTRACT))
- _Jv_SetVTableEntries (superclass, vtable, flags);
-
- for (int i = klass->method_count - 1; i >= 0; i--)
- {
- _Jv_Method *meth = &klass->methods[i];
- if (meth->index == (_Jv_ushort) -1)
- continue;
- if ((meth->accflags & Modifier::ABSTRACT))
- {
- vtable->set_method(meth->index, (void *) &_Jv_abstractMethodError);
- flags[meth->index] = false;
- }
- else
- {
- vtable->set_method(meth->index, meth->ncode);
- flags[meth->index] = true;
- }
- }
-}
-
-// Allocate and lay out the virtual method table for KLASS. This will also
-// cause vtables to be generated for any non-abstract superclasses, and
-// virtual method layout to occur for any abstract superclasses. Must be
-// called with monitor lock for KLASS held.
-void
-_Jv_MakeVTable (jclass klass)
-{
- using namespace java::lang::reflect;
-
- if (klass->vtable != NULL || klass->isInterface()
- || (klass->accflags & Modifier::ABSTRACT))
- return;
-
- // out before we can create a vtable.
- if (klass->vtable_method_count == -1)
- _Jv_LayoutVTableMethods (klass);
-
- // Allocate the new vtable.
- _Jv_VTable *vtable = _Jv_VTable::new_vtable (klass->vtable_method_count);
- klass->vtable = vtable;
-
- jboolean flags[klass->vtable_method_count];
- for (int i = 0; i < klass->vtable_method_count; ++i)
- flags[i] = false;
-
- // Copy the vtable of the closest non-abstract superclass.
- jclass superclass = klass->superclass;
- if (superclass != NULL)
+ // If we haven't found a match, and this class is an interface, then
+ // check all the superinterfaces.
+ if (search_class->isInterface())
{
- while ((superclass->accflags & Modifier::ABSTRACT) != 0)
- superclass = superclass->superclass;
-
- if (superclass->vtable == NULL)
- {
- JvSynchronize sync (superclass);
- _Jv_MakeVTable (superclass);
- }
-
- for (int i = 0; i < superclass->vtable_method_count; ++i)
+ for (int i = 0; i < search_class->interface_count; ++i)
{
- vtable->set_method (i, superclass->vtable->get_method (i));
- flags[i] = true;
+ using namespace java::lang::reflect;
+ bool found = _Jv_getInterfaceMethod (search_class->interfaces[i],
+ found_class, index,
+ utf_name, utf_sig);
+ if (found)
+ return true;
}
}
- // Set the class pointer and GC descriptor.
- vtable->clas = klass;
- vtable->gc_descr = _Jv_BuildGCDescr (klass);
-
- // For each virtual declared in klass and any immediate abstract
- // superclasses, set new vtable entry or override an old one.
- _Jv_SetVTableEntries (klass, vtable, flags);
-
- // It is an error to have an abstract method in a concrete class.
- if (! (klass->accflags & Modifier::ABSTRACT))
- {
- for (int i = 0; i < klass->vtable_method_count; ++i)
- if (! flags[i])
- {
- using namespace java::lang;
- while (klass != NULL)
- {
- for (int j = 0; j < klass->method_count; ++j)
- {
- if (klass->methods[i].index == i)
- {
- StringBuffer *buf = new StringBuffer ();
- buf->append (_Jv_NewStringUtf8Const (klass->methods[i].name));
- buf->append ((jchar) ' ');
- buf->append (_Jv_NewStringUtf8Const (klass->methods[i].signature));
- throw new AbstractMethodError (buf->toString ());
- }
- }
- klass = klass->getSuperclass ();
- }
- // Couldn't find the name, which is weird.
- // But we still must throw the error.
- throw new AbstractMethodError ();
- }
- }
+ return false;
}
diff --git a/libjava/java/lang/natClassLoader.cc b/libjava/java/lang/natClassLoader.cc
index f5f37faf58b..c6437a794e1 100644
--- a/libjava/java/lang/natClassLoader.cc
+++ b/libjava/java/lang/natClassLoader.cc
@@ -17,6 +17,7 @@ details. */
#include <gcj/cni.h>
#include <jvm.h>
+#include <execution.h>
#include <java-threads.h>
#include <java-interp.h>
@@ -32,6 +33,7 @@ details. */
#include <java/lang/ClassNotFoundException.h>
#include <java/lang/ClassCircularityError.h>
#include <java/lang/IncompatibleClassChangeError.h>
+#include <java/lang/ClassFormatError.h>
#include <java/lang/VirtualMachineError.h>
#include <java/lang/VMClassLoader.h>
#include <java/lang/reflect/Modifier.h>
@@ -40,141 +42,6 @@ details. */
#include <java/io/Serializable.h>
#include <java/lang/Cloneable.h>
-void
-_Jv_WaitForState (jclass klass, int state)
-{
- if (klass->state >= state)
- return;
-
- _Jv_MonitorEnter (klass) ;
-
- if (state == JV_STATE_LINKED)
- {
- // Must call _Jv_PrepareCompiledClass while holding the class
- // mutex.
-#ifdef INTERPRETER
- if (_Jv_IsInterpretedClass (klass))
- _Jv_PrepareClass (klass);
-#endif
- _Jv_PrepareCompiledClass (klass);
- _Jv_MonitorExit (klass);
- return;
- }
-
- java::lang::Thread *self = java::lang::Thread::currentThread();
-
- // this is similar to the strategy for class initialization.
- // if we already hold the lock, just leave.
- while (klass->state <= state
- && klass->thread
- && klass->thread != self)
- klass->wait ();
-
- _Jv_MonitorExit (klass);
-
- if (klass->state == JV_STATE_ERROR)
- throw new java::lang::LinkageError;
-}
-
-typedef unsigned int uaddr __attribute__ ((mode (pointer)));
-
-/** This function does class-preparation for compiled classes.
- NOTE: It contains replicated functionality from
- _Jv_ResolvePoolEntry, and this is intentional, since that function
- lives in resolve.cc which is entirely conditionally compiled.
- */
-void
-_Jv_PrepareCompiledClass (jclass klass)
-{
- if (klass->state >= JV_STATE_LINKED)
- return;
-
- // Short-circuit, so that mutually dependent classes are ok.
- klass->state = JV_STATE_LINKED;
-
- _Jv_Constants *pool = &klass->constants;
-
- // Resolve class constants first, since other constant pool
- // entries may rely on these.
- for (int index = 1; index < pool->size; ++index)
- {
- if (pool->tags[index] == JV_CONSTANT_Class)
- {
- _Jv_Utf8Const *name = pool->data[index].utf8;
-
- jclass found;
- if (name->data[0] == '[')
- found = _Jv_FindClassFromSignature (&name->data[0],
- klass->loader);
- else
- found = _Jv_FindClass (name, klass->loader);
-
- if (! found)
- {
- jstring str = _Jv_NewStringUTF (name->data);
- throw new java::lang::NoClassDefFoundError (str);
- }
-
- pool->data[index].clazz = found;
- pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
- }
- }
-
- // If superclass looks like a constant pool entry,
- // resolve it now.
- if ((uaddr) klass->superclass < pool->size)
- klass->superclass = pool->data[(int) klass->superclass].clazz;
-
- // Likewise for interfaces.
- for (int i = 0; i < klass->interface_count; i++)
- if ((uaddr) klass->interfaces[i] < pool->size)
- klass->interfaces[i] = pool->data[(int) klass->interfaces[i]].clazz;
-
- // Resolve the remaining constant pool entries.
- for (int index = 1; index < pool->size; ++index)
- {
- if (pool->tags[index] == JV_CONSTANT_String)
- {
- jstring str;
-
- str = _Jv_NewStringUtf8Const (pool->data[index].utf8);
- pool->data[index].o = str;
- pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
- }
- }
-
-#ifdef INTERPRETER
- // FIXME: although the comment up top says that this function is
- // only called for compiled classes, it is actually called for every
- // class.
- if (! _Jv_IsInterpretedClass (klass))
- {
-#endif /* INTERPRETER */
- jfieldID f = JvGetFirstStaticField (klass);
- for (int n = JvNumStaticFields (klass); n > 0; --n)
- {
- int mod = f->getModifiers ();
- // If we have a static String field with a non-null initial
- // value, we know it points to a Utf8Const.
- _Jv_ResolveField(f, klass->loader);
- if (f->getClass () == &java::lang::String::class$
- && java::lang::reflect::Modifier::isStatic (mod))
- {
- jstring *strp = (jstring *) f->u.addr;
- if (*strp)
- *strp = _Jv_NewStringUtf8Const ((_Jv_Utf8Const *) *strp);
- }
- f = f->getNextField ();
- }
-#ifdef INTERPRETER
- }
-#endif /* INTERPRETER */
-
- klass->notifyAll ();
-
- _Jv_PushClass (klass);
-}
-
//
// A single class can have many "initiating" class loaders,
@@ -206,6 +73,8 @@ static _Jv_LoaderInfo *initiated_classes[HASH_LEN];
static jclass loaded_classes[HASH_LEN];
// This is the root of a linked list of classes
+static jclass stack_head;
+
@@ -308,11 +177,6 @@ _Jv_RegisterClasses (jclass *classes)
jclass klass = *classes;
(*_Jv_RegisterClassHook) (klass);
-
- // registering a compiled class causes
- // it to be immediately "prepared".
- if (klass->state == JV_STATE_NOTHING)
- klass->state = JV_STATE_COMPILED;
}
}
@@ -323,6 +187,10 @@ _Jv_RegisterClassHookDefault (jclass klass)
jclass check_class = loaded_classes[hash];
+ // The BC ABI makes this check unnecessary: we always resolve all
+ // data references via the appropriate class loader, so the kludge
+ // that required this check has gone.
+#if 0
// If the class is already registered, don't re-register it.
while (check_class != NULL)
{
@@ -348,7 +216,11 @@ _Jv_RegisterClassHookDefault (jclass klass)
check_class = check_class->next;
}
+#endif
+ // FIXME: this is really bogus!
+ if (! klass->engine)
+ klass->engine = &_Jv_soleCompiledEngine;
klass->next = loaded_classes[hash];
loaded_classes[hash] = klass;
}
@@ -409,7 +281,7 @@ _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
{
// we need classes to be in the hash while
// we're loading, so that they can refer to themselves.
- _Jv_WaitForState (klass, JV_STATE_LOADED);
+ _Jv_Linker::wait_for_state (klass, JV_STATE_LOADED);
}
return klass;
@@ -419,7 +291,7 @@ jclass
_Jv_NewClass (_Jv_Utf8Const *name, jclass superclass,
java::lang::ClassLoader *loader)
{
- jclass ret = (jclass) JvAllocObject (&java::lang::Class::class$);
+ jclass ret = (jclass) _Jv_AllocObject (&java::lang::Class::class$);
ret->name = name;
ret->superclass = superclass;
ret->loader = loader;
@@ -522,7 +394,7 @@ _Jv_NewArrayClass (jclass element, java::lang::ClassLoader *loader,
// cache one and reuse it. It is not necessary to synchronize this.
if (!array_idt)
{
- _Jv_PrepareConstantTimeTables (array_class);
+ _Jv_Linker::wait_for_state(array_class, JV_STATE_PREPARED);
array_idt = array_class->idt;
array_depth = array_class->depth;
array_ancestors = array_class->ancestors;
@@ -536,19 +408,19 @@ _Jv_NewArrayClass (jclass element, java::lang::ClassLoader *loader,
using namespace java::lang::reflect;
{
- // Array classes are "abstract final"...
- _Jv_ushort accflags = Modifier::FINAL | Modifier::ABSTRACT;
- // ... and inherit accessibility from element type, per vmspec 5.3.3.2
- accflags |= (element->accflags & Modifier::PUBLIC);
- accflags |= (element->accflags & Modifier::PROTECTED);
- accflags |= (element->accflags & Modifier::PRIVATE);
+ // Array classes are "abstract final" and inherit accessibility
+ // from element type, per vmspec 5.3.3.2
+ _Jv_ushort accflags = (Modifier::FINAL | Modifier::ABSTRACT
+ | (element->accflags
+ & (Modifier::PUBLIC | Modifier::PROTECTED
+ | Modifier::PRIVATE)));
array_class->accflags = accflags;
}
// An array class has no visible instance fields. "length" is invisible to
// reflection.
- // say this class is initialized and ready to go!
+ // Say this class is initialized and ready to go!
array_class->state = JV_STATE_DONE;
// vmspec, section 5.3.3 describes this
@@ -558,8 +430,6 @@ _Jv_NewArrayClass (jclass element, java::lang::ClassLoader *loader,
element->arrayclass = array_class;
}
-static jclass stack_head;
-
// These two functions form a stack of classes. When a class is loaded
// it is pushed onto the stack by the class loader; this is so that
// StackTrace can quickly determine which classes have been loaded.
diff --git a/libjava/java/lang/natObject.cc b/libjava/java/lang/natObject.cc
index 8618bf2c7a3..5855fc18934 100644
--- a/libjava/java/lang/natObject.cc
+++ b/libjava/java/lang/natObject.cc
@@ -98,7 +98,7 @@ java::lang::Object::clone (void)
throw new CloneNotSupportedException;
size = klass->size();
- r = JvAllocObject (klass, size);
+ r = _Jv_AllocObject (klass);
}
memcpy ((void *) r, (void *) this, size);
diff --git a/libjava/java/lang/natString.cc b/libjava/java/lang/natString.cc
index 8217f703995..00bf61b6bb8 100644
--- a/libjava/java/lang/natString.cc
+++ b/libjava/java/lang/natString.cc
@@ -1,6 +1,6 @@
// natString.cc - Implementation of java.lang.String native methods.
-/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
This file is part of libgcj.
@@ -56,7 +56,7 @@ static int strhash_size = 0; /* Number of slots available in strhash.
jstring*
_Jv_StringFindSlot (jchar* data, jint len, jint hash)
{
- JvSynchronize sync (&StringClass);
+ JvSynchronize sync (&java::lang::String::class$);
int start_index = hash & (strhash_size - 1);
int deleted_index = -1;
@@ -119,7 +119,7 @@ _Jv_StringGetSlot (jstring str)
void
java::lang::String::rehash()
{
- JvSynchronize sync (&StringClass);
+ JvSynchronize sync (&java::lang::String::class$);
if (strhash == NULL)
{
@@ -166,7 +166,7 @@ java::lang::String::rehash()
jstring
java::lang::String::intern()
{
- JvSynchronize sync (&StringClass);
+ JvSynchronize sync (&java::lang::String::class$);
if (3 * strhash_count >= 2 * strhash_size)
rehash();
jstring* ptr = _Jv_StringGetSlot(this);
@@ -193,7 +193,7 @@ java::lang::String::intern()
void
_Jv_FinalizeString (jobject obj)
{
- JvSynchronize sync (&StringClass);
+ JvSynchronize sync (&java::lang::String::class$);
// We might not actually have intern()d any strings at all, if
// we're being called from Reference.
@@ -285,7 +285,7 @@ _Jv_NewStringUtf8Const (Utf8Const* str)
}
chrs -= length;
- JvSynchronize sync (&StringClass);
+ JvSynchronize sync (&java::lang::String::class$);
if (3 * strhash_count >= 2 * strhash_size)
java::lang::String::rehash();
jstring* ptr = _Jv_StringFindSlot (chrs, length, hash);
@@ -402,30 +402,6 @@ java::lang::String::valueOf (jint num)
}
jstring
-_Jv_AllocString(jsize len)
-{
- jsize sz = sizeof(java::lang::String) + len * sizeof(jchar);
-
- // We assert that for strings allocated this way, the data field
- // will always point to the object itself. Thus there is no reason
- // for the garbage collector to scan any of it.
- // Furthermore, we're about to overwrite the string data, so
- // initialization of the object is not an issue.
-#ifdef ENABLE_JVMPI
- jstring obj = (jstring) _Jv_AllocPtrFreeObject(&StringClass, sz);
-#else
- // Class needs no initialization, and there is no finalizer, so
- // we can go directly to the collector's allocator interface.
- jstring obj = (jstring) _Jv_AllocPtrFreeObj(sz, &StringClass);
-#endif
- obj->data = obj;
- obj->boffset = sizeof(java::lang::String);
- obj->count = len;
- obj->cachedHashCode = 0;
- return obj;
-}
-
-jstring
_Jv_NewString(const jchar *chars, jsize len)
{
jstring str = _Jv_AllocString(len);
@@ -550,7 +526,7 @@ java::lang::String::equals(jobject anObject)
return false;
if (anObject == this)
return true;
- if (anObject->getClass() != &StringClass)
+ if (anObject->getClass() != &java::lang::String::class$)
return false;
jstring other = (jstring) anObject;
if (count != other->count)
diff --git a/libjava/java/lang/natSystem.cc b/libjava/java/lang/natSystem.cc
index 4a08bb138bf..251e2a85d1e 100644
--- a/libjava/java/lang/natSystem.cc
+++ b/libjava/java/lang/natSystem.cc
@@ -130,6 +130,19 @@ java::lang::System::identityHashCode (jobject obj)
return _Jv_HashCode (obj);
}
+jstring
+java::lang::System::getenv0 (jstring name)
+{
+ jint len = _Jv_GetStringUTFLength (name);
+ char buf[len + 1];
+ jsize total = JvGetStringUTFRegion (name, 0, name->length(), buf);
+ buf[total] = '\0';
+ const char *value = ::getenv (buf);
+ if (value == NULL)
+ return NULL;
+ return JvNewStringUTF (value);
+}
+
jboolean
java::lang::System::isWordsBigEndian (void)
{
diff --git a/libjava/java/lang/natVMClassLoader.cc b/libjava/java/lang/natVMClassLoader.cc
index 8de0a70669e..b22e1267c13 100644
--- a/libjava/java/lang/natVMClassLoader.cc
+++ b/libjava/java/lang/natVMClassLoader.cc
@@ -22,6 +22,7 @@ details. */
#include <java-interp.h>
#include <java/lang/VMClassLoader.h>
+#include <java/lang/VMCompiler.h>
#include <gnu/gcj/runtime/VMClassLoader.h>
#include <java/lang/ClassLoader.h>
#include <java/lang/Class.h>
@@ -29,6 +30,21 @@ details. */
#include <java/security/ProtectionDomain.h>
#include <java/lang/ClassFormatError.h>
+void
+java::lang::VMClassLoader::resolveClass (jclass klass)
+{
+ JvSynchronize sync (klass);
+ try
+ {
+ _Jv_Linker::wait_for_state (klass, JV_STATE_LINKED);
+ }
+ catch (java::lang::Throwable *x)
+ {
+ klass->set_state(JV_STATE_ERROR);
+ transformException(klass, x);
+ }
+}
+
java::lang::Class *
java::lang::VMClassLoader::defineClass (java::lang::ClassLoader *loader,
jstring name,
@@ -37,72 +53,64 @@ java::lang::VMClassLoader::defineClass (java::lang::ClassLoader *loader,
jint length,
java::security::ProtectionDomain *pd)
{
-#ifdef INTERPRETER
- jclass klass;
- klass = (jclass) JvAllocObject (&java::lang::Class::class$,
- sizeof (_Jv_InterpClass));
-
- // Synchronize on the class, so that it is not attempted initialized
- // until we're done loading.
- JvSynchronize sync (klass);
-
- // Record the defining loader. For the system class loader, we
- // record NULL.
- if (loader != java::lang::ClassLoader::getSystemClassLoader())
- klass->loader = loader;
+ jclass klass = VMCompiler::compileClass(loader, name, data,
+ offset, length, pd);
- if (name != 0)
+ if (klass != NULL)
+ {
+ JvSynchronize sync (&java::lang::Class::class$);
+ _Jv_RegisterClass (klass);
+ }
+#ifdef INTERPRETER
+ else
{
- _Jv_Utf8Const *name2 = _Jv_makeUtf8Const (name);
+ klass = new java::lang::Class ();
+ klass->aux_info = (void *) _Jv_AllocBytes (sizeof (_Jv_InterpClass));
- if (! _Jv_VerifyClassName (name2))
- throw new java::lang::ClassFormatError
- (JvNewStringLatin1 ("erroneous class name"));
+ // Synchronize on the class, so that it is not attempted initialized
+ // until we're done loading.
+ JvSynchronize sync (klass);
- klass->name = name2;
- }
+ // Record the defining loader. For the system class loader, we
+ // record NULL.
+ if (loader != java::lang::ClassLoader::getSystemClassLoader())
+ klass->loader = loader;
- try
- {
- _Jv_DefineClass (klass, data, offset, length);
- }
- catch (java::lang::Throwable *ex)
- {
- klass->state = JV_STATE_ERROR;
- klass->notifyAll ();
+ if (name != 0)
+ {
+ _Jv_Utf8Const *name2 = _Jv_makeUtf8Const (name);
- _Jv_UnregisterClass (klass);
+ if (! _Jv_VerifyClassName (name2))
+ throw new java::lang::ClassFormatError
+ (JvNewStringLatin1 ("erroneous class name"));
- // If EX is not a ClassNotFoundException, that's ok, because we
- // account for the possibility in defineClass().
- throw ex;
- }
-
- klass->protectionDomain = pd;
+ klass->name = name2;
+ }
- // if everything proceeded sucessfully, we're loaded.
- JvAssert (klass->state == JV_STATE_LOADED);
+ try
+ {
+ _Jv_DefineClass (klass, data, offset, length);
+ }
+ catch (java::lang::Throwable *ex)
+ {
+ klass->state = JV_STATE_ERROR;
+ klass->notifyAll ();
- return klass;
+ _Jv_UnregisterClass (klass);
-#else // INTERPRETER
+ // If EX is not a ClassNotFoundException, that's ok, because we
+ // account for the possibility in defineClass().
+ throw ex;
+ }
- return 0;
-#endif
-}
+ klass->protectionDomain = pd;
-// Finish linking a class. Only called from ClassLoader::resolveClass.
-void
-java::lang::VMClassLoader::linkClass0 (java::lang::Class *klass)
-{
- _Jv_WaitForState (klass, JV_STATE_LINKED);
-}
+ // if everything proceeded sucessfully, we're loaded.
+ JvAssert (klass->state == JV_STATE_LOADED);
+ }
+#endif // INTERPRETER
-void
-java::lang::VMClassLoader::markClassErrorState0 (java::lang::Class *klass)
-{
- klass->state = JV_STATE_ERROR;
- klass->notifyAll ();
+ return klass;
}
java::lang::ClassLoader *
diff --git a/libjava/java/lang/reflect/InvocationHandler.java b/libjava/java/lang/reflect/InvocationHandler.java
index 91907e280c7..514d943f5ee 100644
--- a/libjava/java/lang/reflect/InvocationHandler.java
+++ b/libjava/java/lang/reflect/InvocationHandler.java
@@ -49,37 +49,38 @@ package java.lang.reflect;
* interface. But in order for the proxy instance to do any good, it
* needs to know what to do when interface methods are invoked! So,
* this interface is basically a cool wrapper that provides runtime
- * code generation needed by proxy instances.<p>
+ * code generation needed by proxy instances.
*
- * While this interface was designed for use by Proxy, it will also
- * work on any object in general.<p>
+ * <p>While this interface was designed for use by Proxy, it will also
+ * work on any object in general.</p>
*
- * Hints for implementing this class:<br>
+ * <p>Hints for implementing this class:</p>
+ *
* <ul>
- * <li>Don't forget that Object.equals, Object.hashCode, and
- * Object.toString will call this handler. In particular,
- * a naive call to proxy.equals, proxy.hashCode, or proxy.toString
- * will put you in an infinite loop. And remember that string
- * concatenation also invokes toString.</li>
- * <li>Obey the contract of the Method object you are handling, or
- * the proxy instance will be forced to throw a
- * {@link NullPointerException}, {@link ClassCastException},
- * or {@link UndeclaredThrowableException}.</li>
- * <li>Be prepared to wrap/unwrap primitives as necessary.</li>
- * <li>The Method object may be owned by a different interface than
- * what was actually used as the qualifying type of the method
- * invocation in the Java source code. This means that it might
- * not always be safe to throw an exception listed as belonging
- * to the method's throws clause.</li>
+ * <li>Don't forget that Object.equals, Object.hashCode, and
+ * Object.toString will call this handler. In particular,
+ * a naive call to proxy.equals, proxy.hashCode, or proxy.toString
+ * will put you in an infinite loop. And remember that string
+ * concatenation also invokes toString.</li>
+ * <li>Obey the contract of the Method object you are handling, or
+ * the proxy instance will be forced to throw a
+ * {@link NullPointerException}, {@link ClassCastException},
+ * or {@link UndeclaredThrowableException}.</li>
+ * <li>Be prepared to wrap/unwrap primitives as necessary.</li>
+ * <li>The Method object may be owned by a different interface than
+ * what was actually used as the qualifying type of the method
+ * invocation in the Java source code. This means that it might
+ * not always be safe to throw an exception listed as belonging
+ * to the method's throws clause.</li>
* </ul>
*
* <p><small>For a fun time, create an InvocationHandler that handles the
- * methods of a proxy instance of the InvocationHandler interface!</small>
+ * methods of a proxy instance of the InvocationHandler interface!</small></p>
*
* @see Proxy
* @see UndeclaredThrowableException
*
- * @author Eric Blake <ebb9@email.byu.edu>
+ * @author Eric Blake (ebb9@email.byu.edu)
* @since 1.3
* @status updated to 1.4
*/
diff --git a/libjava/java/lang/reflect/Proxy.java b/libjava/java/lang/reflect/Proxy.java
index 03b2a45645c..56d7aeb7ce9 100644
--- a/libjava/java/lang/reflect/Proxy.java
+++ b/libjava/java/lang/reflect/Proxy.java
@@ -211,35 +211,36 @@ public class Proxy implements Serializable
* Returns the proxy {@link Class} for the given ClassLoader and array
* of interfaces, dynamically generating it if necessary.
*
- * There are several restrictions on this method, the violation of
+ * <p>There are several restrictions on this method, the violation of
* which will result in an IllegalArgumentException or
- * NullPointerException:
+ * NullPointerException:</p>
+ *
* <ul>
- * <li>All objects in `interfaces' must represent distinct interfaces.
- * Classes, primitive types, null, and duplicates are forbidden.</li>
- * <li>The interfaces must be visible in the specified ClassLoader.
- * In other words, for each interface i:
- * <code>Class.forName(i.getName(), false, loader) == i</code>
- * must be true.</li>
- * <li>All non-public interfaces (if any) must reside in the same
- * package, or the proxy class would be non-instantiable. If
- * there are no non-public interfaces, the package of the proxy
- * class is unspecified.</li>
- * <li>All interfaces must be compatible - if two declare a method
- * with the same name and parameters, the return type must be
- * the same and the throws clause of the proxy class will be
- * the maximal subset of subclasses of the throws clauses for
- * each method that is overridden.</li>
- * <li>VM constraints limit the number of interfaces a proxy class
- * may directly implement (however, the indirect inheritance
- * of {@link Serializable} does not count against this limit).
- * Even though most VMs can theoretically have 65535
- * superinterfaces for a class, the actual limit is smaller
- * because a class's constant pool is limited to 65535 entries,
- * and not all entries can be interfaces.</li>
- * </ul><p>
+ * <li>All objects in `interfaces' must represent distinct interfaces.
+ * Classes, primitive types, null, and duplicates are forbidden.</li>
+ * <li>The interfaces must be visible in the specified ClassLoader.
+ * In other words, for each interface i:
+ * <code>Class.forName(i.getName(), false, loader) == i</code>
+ * must be true.</li>
+ * <li>All non-public interfaces (if any) must reside in the same
+ * package, or the proxy class would be non-instantiable. If
+ * there are no non-public interfaces, the package of the proxy
+ * class is unspecified.</li>
+ * <li>All interfaces must be compatible - if two declare a method
+ * with the same name and parameters, the return type must be
+ * the same and the throws clause of the proxy class will be
+ * the maximal subset of subclasses of the throws clauses for
+ * each method that is overridden.</li>
+ * <li>VM constraints limit the number of interfaces a proxy class
+ * may directly implement (however, the indirect inheritance
+ * of {@link Serializable} does not count against this limit).
+ * Even though most VMs can theoretically have 65535
+ * superinterfaces for a class, the actual limit is smaller
+ * because a class's constant pool is limited to 65535 entries,
+ * and not all entries can be interfaces.</li>
+ * </ul>
*
- * Note that different orders of interfaces produce distinct classes.
+ * <p>Note that different orders of interfaces produce distinct classes.</p>
*
* @param loader the class loader to define the proxy class in; null
* implies the bootstrap class loader
diff --git a/libjava/java/lang/reflect/natField.cc b/libjava/java/lang/reflect/natField.cc
index 469cf74de8e..7eb032227ab 100644
--- a/libjava/java/lang/reflect/natField.cc
+++ b/libjava/java/lang/reflect/natField.cc
@@ -1,6 +1,6 @@
// natField.cc - Implementation of java.lang.reflect.Field native methods.
-/* Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004 Free Software Foundation
This file is part of libgcj.
@@ -47,7 +47,7 @@ java::lang::reflect::Field::getType ()
{
jfieldID fld = _Jv_FromReflectedField (this);
JvSynchronize sync (declaringClass);
- _Jv_ResolveField (fld, declaringClass->getClassLoaderInternal ());
+ _Jv_Linker::resolve_field (fld, declaringClass->getClassLoaderInternal ());
return fld->type;
}
diff --git a/libjava/java/lang/reflect/natMethod.cc b/libjava/java/lang/reflect/natMethod.cc
index 736103b63dd..3439bd93c52 100644
--- a/libjava/java/lang/reflect/natMethod.cc
+++ b/libjava/java/lang/reflect/natMethod.cc
@@ -1,6 +1,6 @@
// natMethod.cc - Native code for Method class.
-/* Copyright (C) 1998, 1999, 2000, 2001 , 2002, 2003 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001 , 2002, 2003, 2004 Free Software Foundation
This file is part of libgcj.
@@ -143,26 +143,23 @@ jobject
java::lang::reflect::Method::invoke (jobject obj, jobjectArray args)
{
using namespace java::lang::reflect;
+ jclass iface = NULL;
if (parameter_types == NULL)
getType ();
jmethodID meth = _Jv_FromReflectedMethod (this);
- jclass objClass;
-
if (Modifier::isStatic(meth->accflags))
{
// We have to initialize a static class. It is safe to do this
// here and not in _Jv_CallAnyMethodA because JNI initializes a
// class whenever a method lookup is done.
_Jv_InitClass (declaringClass);
- objClass = declaringClass;
}
else
{
- objClass = JV_CLASS (obj);
-
+ jclass objClass = JV_CLASS (obj);
if (! _Jv_IsAssignableFrom (declaringClass, objClass))
throw new java::lang::IllegalArgumentException;
}
@@ -184,12 +181,15 @@ java::lang::reflect::Method::invoke (jobject obj, jobjectArray args)
{
}
- if (! _Jv_CheckAccess(caller, objClass, meth->accflags))
+ if (! _Jv_CheckAccess(caller, declaringClass, meth->accflags))
throw new IllegalAccessException;
}
+ if (declaringClass->isInterface())
+ iface = declaringClass;
+
return _Jv_CallAnyMethodA (obj, return_type, meth, false,
- parameter_types, args);
+ parameter_types, args, iface);
}
jint
@@ -341,7 +341,8 @@ _Jv_CallAnyMethodA (jobject obj,
JArray<jclass> *parameter_types,
jvalue *args,
jvalue *result,
- jboolean is_jni_call)
+ jboolean is_jni_call,
+ jclass iface)
{
using namespace java::lang::reflect;
@@ -375,7 +376,7 @@ _Jv_CallAnyMethodA (jobject obj,
// the JDK 1.2 docs specify that the new object must be allocated
// before argument conversions are done.
if (is_constructor)
- obj = JvAllocObject (return_type);
+ obj = _Jv_AllocObject (return_type);
const int size_per_arg = sizeof(jvalue);
ffi_cif cif;
@@ -478,7 +479,10 @@ _Jv_CallAnyMethodA (jobject obj,
&& (_Jv_ushort)-1 != meth->index)
{
_Jv_VTable *vtable = *(_Jv_VTable **) obj;
- ncode = vtable->get_method (meth->index);
+ if (iface == NULL)
+ ncode = vtable->get_method (meth->index);
+ else
+ ncode = _Jv_LookupInterfaceMethodIdx (vtable->clas, iface, meth->index);
}
else
{
@@ -553,7 +557,8 @@ _Jv_CallAnyMethodA (jobject obj,
jmethodID meth,
jboolean is_constructor,
JArray<jclass> *parameter_types,
- jobjectArray args)
+ jobjectArray args,
+ jclass iface)
{
if (parameter_types->length == 0 && args == NULL)
{
@@ -621,7 +626,7 @@ _Jv_CallAnyMethodA (jobject obj,
_Jv_CallAnyMethodA (obj, return_type, meth, is_constructor,
_Jv_isVirtualMethod (meth),
parameter_types, argvals, &ret_value,
- false);
+ false, iface);
jobject r;
#define VAL(Wrapper, Field) (new Wrapper (ret_value.Field))
diff --git a/libjava/java/math/BigDecimal.java b/libjava/java/math/BigDecimal.java
index f9965add4c1..401ebe95d3c 100644
--- a/libjava/java/math/BigDecimal.java
+++ b/libjava/java/math/BigDecimal.java
@@ -271,7 +271,6 @@ public class BigDecimal extends Number implements Comparable
return newScale == 0 ? ZERO : new BigDecimal (ZERO.intVal, newScale);
// Ensure that pow gets a non-negative value.
- int valScale = val.scale;
BigInteger valIntVal = val.intVal;
int power = newScale - (scale - val.scale);
if (power < 0)
diff --git a/libjava/java/net/Authenticator.java b/libjava/java/net/Authenticator.java
index 7592b525a50..8a951cb2dfd 100644
--- a/libjava/java/net/Authenticator.java
+++ b/libjava/java/net/Authenticator.java
@@ -7,7 +7,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -37,18 +37,19 @@ exception statement from your version. */
package java.net;
+
/**
* This abstract class provides a model for obtaining authentication
* information (in the form of a username and password) required by
* some network operations (such as hitting a password protected
* web site).
* <p>
- * To make use of this feature, a programmer must create a subclass
+ * To make use of this feature, a programmer must create a subclass
* that knows how to obtain the necessary info. An example
- * would be a class that popped up a dialog box to prompt the user.
- * After creating an instance of that subclass, the static
- * <code>setDefault</code> method of this class is called to set up
- * that instance as the object to use on subsequent calls to obtain
+ * would be a class that popped up a dialog box to prompt the user.
+ * After creating an instance of that subclass, the static
+ * <code>setDefault</code> method of this class is called to set up
+ * that instance as the object to use on subsequent calls to obtain
* authorization.
*
* @since 1.2
@@ -106,8 +107,8 @@ public abstract class Authenticator
*/
/**
- * This method sets the default <code>Authenticator</code> object (an
- * instance of a subclass of <code>Authenticator</code>) to use when
+ * This method sets the default <code>Authenticator</code> object (an
+ * instance of a subclass of <code>Authenticator</code>) to use when
* prompting the user for
* information. Note that this method checks to see if the caller is
* allowed to set this value (the "setDefaultAuthenticator" permission)
@@ -115,9 +116,9 @@ public abstract class Authenticator
*
* @param defAuth The new default <code>Authenticator</code> object to use
*
- * @exception SecurityException If the caller does not have permission
+ * @exception SecurityException If the caller does not have permission
* to perform this operation
- */
+ */
public static void setDefault(Authenticator defAuth)
{
SecurityManager sm = System.getSecurityManager();
@@ -125,38 +126,40 @@ public abstract class Authenticator
sm.checkPermission(new NetPermission("setDefaultAuthenticator"));
defaultAuthenticator = defAuth;
- }
+ }
/**
* This method is called whenever a username and password for a given
* network operation is required. First, a security check is made to see
* if the caller has the "requestPasswordAuthentication"
* permission. If not, the method thows an exception. If there is no
- * default <code>Authenticator</code> object, the method then returns
- * <code>null</code>. Otherwise, the default authenticators's instance
+ * default <code>Authenticator</code> object, the method then returns
+ * <code>null</code>. Otherwise, the default authenticators's instance
* variables are initialized and it's <code>getPasswordAuthentication</code>
* method is called to get the actual authentication information to return.
*
* @param addr The address requesting authentication
* @param port The port requesting authentication
* @param protocol The protocol requesting authentication
- * @param prompt The prompt to display to the user when requesting
+ * @param prompt The prompt to display to the user when requesting
* authentication info
* @param scheme The authentication scheme in use
- *
- * @return A <code>PasswordAuthentication</code> object with the user's
+ *
+ * @return A <code>PasswordAuthentication</code> object with the user's
* authentication info.
*
- * @exception SecurityException If the caller does not have permission to
+ * @exception SecurityException If the caller does not have permission to
* perform this operation
- */
- public static PasswordAuthentication
- requestPasswordAuthentication(InetAddress addr, int port, String protocol,
- String prompt, String scheme)
+ */
+ public static PasswordAuthentication requestPasswordAuthentication(InetAddress addr,
+ int port,
+ String protocol,
+ String prompt,
+ String scheme)
throws SecurityException
{
- return(requestPasswordAuthentication (null, addr, port, protocol,
- prompt, scheme));
+ return requestPasswordAuthentication(null, addr, port, protocol, prompt,
+ scheme);
}
/**
@@ -175,21 +178,24 @@ public abstract class Authenticator
* @param addr The address requesting authentication
* @param port The port requesting authentication
* @param protocol The protocol requesting authentication
- * @param prompt The prompt to display to the user when requesting
+ * @param prompt The prompt to display to the user when requesting
* authentication info
* @param scheme The authentication scheme in use
*
- * @return A <code>PasswordAuthentication</code> object with the user's
+ * @return A <code>PasswordAuthentication</code> object with the user's
* authentication info.
*
- * @exception SecurityException If the caller does not have permission to
+ * @exception SecurityException If the caller does not have permission to
* perform this operation
*
* @since 1.4
*/
- public static PasswordAuthentication
- requestPasswordAuthentication(String host, InetAddress addr, int port,
- String protocol, String prompt, String scheme)
+ public static PasswordAuthentication requestPasswordAuthentication(String host,
+ InetAddress addr,
+ int port,
+ String protocol,
+ String prompt,
+ String scheme)
throws SecurityException
{
SecurityManager sm = System.getSecurityManager();
@@ -197,7 +203,7 @@ public abstract class Authenticator
sm.checkPermission(new NetPermission("requestPasswordAuthentication"));
if (defaultAuthenticator == null)
- return(null);
+ return null;
defaultAuthenticator.host = host;
defaultAuthenticator.addr = addr;
@@ -206,7 +212,7 @@ public abstract class Authenticator
defaultAuthenticator.prompt = prompt;
defaultAuthenticator.scheme = scheme;
- return(defaultAuthenticator.getPasswordAuthentication());
+ return defaultAuthenticator.getPasswordAuthentication();
}
/*
@@ -232,7 +238,7 @@ public abstract class Authenticator
*/
protected final InetAddress getRequestingSite()
{
- return(addr);
+ return addr;
}
/**
@@ -240,24 +246,24 @@ public abstract class Authenticator
* or <code>null</code> if not available.
*
* @return The name of the host requesting authentication, or
- * </code>null</code> if it is not available.
+ * <code>null</code> if it is not available.
*
* @since 1.4
*/
protected final String getRequestingHost()
{
- return(host);
+ return host;
}
/**
- * This method returns the port of the site that is requesting
+ * This method returns the port of the site that is requesting
* authentication.
*
* @return The requesting port
*/
protected final int getRequestingPort()
{
- return(port);
+ return port;
}
/**
@@ -268,18 +274,18 @@ public abstract class Authenticator
*/
protected final String getRequestingProtocol()
{
- return(protocol);
+ return protocol;
}
/**
- * Returns the prompt that should be used when requesting authentication
+ * Returns the prompt that should be used when requesting authentication
* information from the user
- *
+ *
* @return The user prompt
*/
protected final String getRequestingPrompt()
{
- return(prompt);
+ return prompt;
}
/**
@@ -289,7 +295,7 @@ public abstract class Authenticator
*/
protected final String getRequestingScheme()
{
- return(scheme);
+ return scheme;
}
/**
@@ -302,8 +308,6 @@ public abstract class Authenticator
*/
protected PasswordAuthentication getPasswordAuthentication()
{
- return(null);
+ return null;
}
-
} // class Authenticator
-
diff --git a/libjava/java/net/BindException.java b/libjava/java/net/BindException.java
index cfc36b312f6..00885e8f21c 100644
--- a/libjava/java/net/BindException.java
+++ b/libjava/java/net/BindException.java
@@ -37,6 +37,7 @@ exception statement from your version. */
package java.net;
+
/**
* This exception indicates that an error occurred while attempting to bind
* socket to a particular port.
diff --git a/libjava/java/net/ConnectException.java b/libjava/java/net/ConnectException.java
index e731858ca19..2dd35e72d0f 100644
--- a/libjava/java/net/ConnectException.java
+++ b/libjava/java/net/ConnectException.java
@@ -35,9 +35,9 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.net;
+
/**
* This exception indicates that an error occurred while attempting to
* connect to a remote host. Often this indicates that the remote host
diff --git a/libjava/java/net/ContentHandler.java b/libjava/java/net/ContentHandler.java
index ed746984775..5e3de23d4dc 100644
--- a/libjava/java/net/ContentHandler.java
+++ b/libjava/java/net/ContentHandler.java
@@ -7,7 +7,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -47,11 +47,11 @@ import java.io.IOException;
/**
* This is an abstract class that is the superclass for classes that read
- * objects from URL's. Calling the <code>getContent()</code> method in the
- * <code>URL</code> class or the <code>URLConnection</code> class will cause
- * an instance of a subclass of <code>ContentHandler</code> to be created for
- * the MIME type of the object being downloaded from the URL. Thus, this
- * class is seldom needed by applications/applets directly, but only
+ * objects from URL's. Calling the <code>getContent()</code> method in the
+ * <code>URL</code> class or the <code>URLConnection</code> class will cause
+ * an instance of a subclass of <code>ContentHandler</code> to be created for
+ * the MIME type of the object being downloaded from the URL. Thus, this
+ * class is seldom needed by applications/applets directly, but only
* indirectly through methods in other classes.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
@@ -66,8 +66,8 @@ public abstract class ContentHandler
/**
* Default, no-argument constructor.
*/
- public ContentHandler()
- {
+ public ContentHandler()
+ {
}
/*
@@ -75,10 +75,10 @@ public abstract class ContentHandler
*/
/**
- * This method reads from the <code>InputStream</code> of the passed in URL
- * connection and uses the data downloaded to create an <code>Object</code>
- * represening the content. For example, if the URL is pointing to a GIF
- * file, this method might return an <code>Image</code> object. This method
+ * This method reads from the <code>InputStream</code> of the passed in URL
+ * connection and uses the data downloaded to create an <code>Object</code>
+ * represening the content. For example, if the URL is pointing to a GIF
+ * file, this method might return an <code>Image</code> object. This method
* must be implemented by subclasses.
*
* @param urlc A <code>URLConnection</code> object to read data from.
@@ -87,16 +87,16 @@ public abstract class ContentHandler
*
* @exception IOException If an error occurs
*/
- public abstract Object getContent(URLConnection urlc)
+ public abstract Object getContent(URLConnection urlc)
throws IOException;
/**
* This method reads from the <code>InputStream</code> of the passed in URL
* connection and uses the data downloaded to create an <code>Object</code>
- * represening the content. For example, if the URL is pointing to a GIF
- * file, this method might return an <code>Image</code> object. This method
+ * represening the content. For example, if the URL is pointing to a GIF
+ * file, this method might return an <code>Image</code> object. This method
* must be implemented by subclasses. This method uses the list of
- * supplied classes as candidate types. If the data read doesn't match
+ * supplied classes as candidate types. If the data read doesn't match
* any of the supplied type, <code>null</code> is returned.
*
* @param urlc A <code>URLConnection</code> object to read data from.
@@ -113,15 +113,14 @@ public abstract class ContentHandler
public Object getContent(URLConnection urlc, Class[] classes)
throws IOException
{
- Object obj = getContent (urlc);
+ Object obj = getContent(urlc);
for (int i = 0; i < classes.length; i++)
{
- if (classes [i].isInstance (obj))
- return obj;
+ if (classes[i].isInstance(obj))
+ return obj;
}
return null;
}
-
} // class ContentHandler
diff --git a/libjava/java/net/ContentHandlerFactory.java b/libjava/java/net/ContentHandlerFactory.java
index 7310f569678..cdfbca285d3 100644
--- a/libjava/java/net/ContentHandlerFactory.java
+++ b/libjava/java/net/ContentHandlerFactory.java
@@ -7,7 +7,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -35,18 +35,17 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.net;
+
/**
* Written using on-line Java Platform 1.2 API Specification, as well
* as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
* Status: Believed complete and correct.
*/
-
/**
- * This interface maps MIME types to <code>ContentHandler</code> objects.
- * It consists of one method that, when passed a MIME type, returns a
+ * This interface maps MIME types to <code>ContentHandler</code> objects.
+ * It consists of one method that, when passed a MIME type, returns a
* handler for that type.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
@@ -63,6 +62,4 @@ public interface ContentHandlerFactory
* @return The <code>ContentHandler</code> for the passed in MIME type
*/
ContentHandler createContentHandler(String mimeType);
-
} // interface ContentHandlerFactory
-
diff --git a/libjava/java/net/DatagramPacket.java b/libjava/java/net/DatagramPacket.java
index f23364cd0af..8ff64435c2b 100644
--- a/libjava/java/net/DatagramPacket.java
+++ b/libjava/java/net/DatagramPacket.java
@@ -7,7 +7,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -37,6 +37,7 @@ exception statement from your version. */
package java.net;
+
/*
* Written using on-line Java Platform 1.2 API Specification, as well
* as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
@@ -86,7 +87,7 @@ public final class DatagramPacket
* The maximal length of the buffer.
*/
int maxlen;
-
+
/**
* The address to which the packet should be sent or from which it
* was received.
@@ -134,14 +135,14 @@ public final class DatagramPacket
*
* @param buf A buffer containing the data to send
* @param offset The offset into the buffer to start writing from.
- * @param len The length of the buffer (must be &lt;= buf.length)
- * @param addr The address to send to
+ * @param length The length of the buffer (must be &lt;= buf.length)
+ * @param address The address to send to
* @param port The port to send to
*
* @since 1.2
*/
public DatagramPacket(byte[] buf, int offset, int length,
- InetAddress address, int port)
+ InetAddress address, int port)
{
setData(buf, offset, length);
setAddress(address);
@@ -177,8 +178,7 @@ public final class DatagramPacket
* @since 1.4
*/
public DatagramPacket(byte[] buf, int offset, int length,
- SocketAddress address)
- throws SocketException
+ SocketAddress address) throws SocketException
{
if (! (address instanceof InetSocketAddress))
throw new IllegalArgumentException("unsupported address type");
@@ -272,16 +272,16 @@ public final class DatagramPacket
/**
* This sets the address to which the data packet will be transmitted.
*
- * @param addr The destination address
+ * @param address The destination address
*
* @since 1.1
*/
- public synchronized void setAddress(InetAddress iaddr)
+ public synchronized void setAddress(InetAddress address)
{
- if (iaddr == null)
+ if (address == null)
throw new NullPointerException("Null address");
- address = iaddr;
+ this.address = address;
}
/**
@@ -291,12 +291,12 @@ public final class DatagramPacket
*
* @since 1.1
*/
- public synchronized void setPort(int iport)
+ public synchronized void setPort(int port)
{
- if (iport < 0 || iport > 65535)
- throw new IllegalArgumentException("Invalid port: " + iport);
+ if (port < 0 || port > 65535)
+ throw new IllegalArgumentException("Invalid port: " + port);
- port = iport;
+ this.port = port;
}
/**
@@ -324,12 +324,12 @@ public final class DatagramPacket
* will be sent to/is coming from
*
* @return The socket address of the remote host
- *
+ *
* @since 1.4
*/
public SocketAddress getSocketAddress()
{
- return new InetSocketAddress (address, port);
+ return new InetSocketAddress(address, port);
}
/**
@@ -360,7 +360,6 @@ public final class DatagramPacket
public synchronized void setData(byte[] buf, int offset, int length)
{
// This form of setData must be used if offset is to be changed.
-
if (buf == null)
throw new NullPointerException("Null buffer");
if (offset < 0)
@@ -372,7 +371,7 @@ public final class DatagramPacket
}
/**
- * Sets the length of the data in the buffer.
+ * Sets the length of the data in the buffer.
*
* @param length The new length. (Where len &lt;= buf.length)
*
@@ -387,7 +386,7 @@ public final class DatagramPacket
throw new IllegalArgumentException("Invalid length: " + length);
if (offset + length > buffer.length)
throw new IllegalArgumentException("Potential buffer overflow - offset: "
- + offset + " length: " + length);
+ + offset + " length: " + length);
this.length = length;
this.maxlen = length;
diff --git a/libjava/java/net/DatagramSocket.java b/libjava/java/net/DatagramSocket.java
index 895db94fa52..2808d82428b 100644
--- a/libjava/java/net/DatagramSocket.java
+++ b/libjava/java/net/DatagramSocket.java
@@ -7,7 +7,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -35,7 +35,6 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.net;
import gnu.java.net.PlainDatagramSocketImpl;
@@ -44,24 +43,23 @@ import java.io.IOException;
import java.nio.channels.DatagramChannel;
import java.nio.channels.IllegalBlockingModeException;
+
/**
* Written using on-line Java Platform 1.2 API Specification, as well
* as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
* Status: Believed complete and correct.
*/
-
/**
- * This class models a connectionless datagram socket that sends
+ * This class models a connectionless datagram socket that sends
* individual packets of data across the network. In the TCP/IP world,
* this means UDP. Datagram packets do not have guaranteed delivery,
* or any guarantee about the order the data will be received on the
* remote host.
- *
+ *
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Warren Levy (warrenl@cygnus.com)
* @date May 3, 1999.
*/
-
public class DatagramSocket
{
/**
@@ -69,7 +67,7 @@ public class DatagramSocket
* variable is null, a default factory is used.
*/
private static DatagramSocketImplFactory factory;
-
+
/**
* This is the implementation object used by this socket.
*/
@@ -96,15 +94,15 @@ public class DatagramSocket
private boolean bound;
/**
- * Creates a <code>DatagramSocket</code> from a specified
+ * Creates a <code>DatagramSocket</code> from a specified
* <code>DatagramSocketImpl</code> instance
*
- * @param impl The <code>DatagramSocketImpl</code> the socket will be
+ * @param impl The <code>DatagramSocketImpl</code> the socket will be
* created from
- *
+ *
* @since 1.4
*/
- protected DatagramSocket (DatagramSocketImpl impl)
+ protected DatagramSocket(DatagramSocketImpl impl)
{
if (impl == null)
throw new NullPointerException("impl may not be null");
@@ -115,7 +113,7 @@ public class DatagramSocket
}
/**
- * Initializes a new instance of <code>DatagramSocket</code> that binds to
+ * Initializes a new instance of <code>DatagramSocket</code> that binds to
* a random port and every address on the local machine.
*
* @exception SocketException If an error occurs.
@@ -128,7 +126,7 @@ public class DatagramSocket
}
/**
- * Initializes a new instance of <code>DatagramSocket</code> that binds to
+ * Initializes a new instance of <code>DatagramSocket</code> that binds to
* the specified port and every address on the local machine.
*
* @param port The local port number to bind to.
@@ -143,7 +141,7 @@ public class DatagramSocket
}
/**
- * Initializes a new instance of <code>DatagramSocket</code> that binds to
+ * Initializes a new instance of <code>DatagramSocket</code> that binds to
* the specified local port and address.
*
* @param port The local port number to bind to.
@@ -159,7 +157,7 @@ public class DatagramSocket
}
/**
- * Initializes a new instance of <code>DatagramSocket</code> that binds to
+ * Initializes a new instance of <code>DatagramSocket</code> that binds to
* the specified local port and address.
*
* @param address The local address and port number to bind to.
@@ -170,35 +168,36 @@ public class DatagramSocket
*
* @since 1.4
*/
- public DatagramSocket (SocketAddress address) throws SocketException
+ public DatagramSocket(SocketAddress address) throws SocketException
{
String propVal = System.getProperty("impl.prefix");
if (propVal == null || propVal.equals(""))
impl = new PlainDatagramSocketImpl();
else
try
- {
- impl = (DatagramSocketImpl) Class.forName
- ("java.net." + propVal + "DatagramSocketImpl").newInstance();
- }
+ {
+ impl =
+ (DatagramSocketImpl) Class.forName("java.net." + propVal
+ + "DatagramSocketImpl")
+ .newInstance();
+ }
catch (Exception e)
- {
- System.err.println("Could not instantiate class: java.net." +
- propVal + "DatagramSocketImpl");
+ {
+ System.err.println("Could not instantiate class: java.net."
+ + propVal + "DatagramSocketImpl");
impl = new PlainDatagramSocketImpl();
- }
+ }
if (address != null)
bind(address);
}
-
+
// This needs to be accessible from java.net.MulticastSocket
- DatagramSocketImpl getImpl()
- throws SocketException
+ DatagramSocketImpl getImpl() throws SocketException
{
try
{
- if (!implCreated)
+ if (! implCreated)
{
impl.create();
implCreated = true;
@@ -211,7 +210,7 @@ public class DatagramSocket
throw new SocketException(e.getMessage());
}
}
-
+
/**
* Closes this datagram socket.
*/
@@ -219,7 +218,7 @@ public class DatagramSocket
{
if (isClosed())
return;
-
+
try
{
getImpl().close();
@@ -247,10 +246,10 @@ public class DatagramSocket
}
/**
- * This method returns the remote address to which this socket is
+ * This method returns the remote address to which this socket is
* connected. If this socket is not connected, then this method will
* return <code>null</code>.
- *
+ *
* @return The remote address.
*
* @since 1.2
@@ -264,7 +263,7 @@ public class DatagramSocket
* This method returns the remote port to which this socket is
* connected. If this socket is not connected, then this method will
* return -1.
- *
+ *
* @return The remote port.
*
* @since 1.2
@@ -276,7 +275,7 @@ public class DatagramSocket
/**
* Returns the local address this datagram socket is bound to.
- *
+ *
* @return The local address is the socket is bound or null
*
* @since 1.1
@@ -285,16 +284,17 @@ public class DatagramSocket
{
if (isClosed())
return null;
-
+
InetAddress localAddr;
-
+
try
{
- localAddr = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
+ localAddr =
+ (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
SecurityManager s = System.getSecurityManager();
if (s != null)
- s.checkConnect (localAddr.getHostName(), -1);
+ s.checkConnect(localAddr.getHostName(), -1);
}
catch (SecurityException e)
{
@@ -303,7 +303,7 @@ public class DatagramSocket
catch (SocketException e)
{
// This cannot happen as we are bound.
- return null;
+ return null;
}
return localAddr;
@@ -318,7 +318,7 @@ public class DatagramSocket
{
if (isClosed())
return -1;
-
+
try
{
return getImpl().getLocalPort();
@@ -337,7 +337,7 @@ public class DatagramSocket
* @return The current timeout in milliseconds.
*
* @exception SocketException If an error occurs.
- *
+ *
* @since 1.1
*/
public synchronized int getSoTimeout() throws SocketException
@@ -347,7 +347,7 @@ public class DatagramSocket
Object buf = getImpl().getOption(SocketOptions.SO_TIMEOUT);
- if (buf instanceof Integer)
+ if (buf instanceof Integer)
return ((Integer) buf).intValue();
throw new SocketException("unexpected type");
@@ -368,7 +368,7 @@ public class DatagramSocket
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
if (timeout < 0)
throw new IllegalArgumentException("Invalid timeout: " + timeout);
@@ -390,7 +390,7 @@ public class DatagramSocket
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
Object buf = getImpl().getOption(SocketOptions.SO_SNDBUF);
if (buf instanceof Integer)
@@ -415,10 +415,10 @@ public class DatagramSocket
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
if (size < 0)
throw new IllegalArgumentException("Buffer size is less than 0");
-
+
getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer(size));
}
@@ -439,7 +439,7 @@ public class DatagramSocket
throw new SocketException("socket is closed");
Object buf = getImpl().getOption(SocketOptions.SO_RCVBUF);
-
+
if (buf instanceof Integer)
return ((Integer) buf).intValue();
@@ -455,7 +455,7 @@ public class DatagramSocket
*
* @exception SocketException If an error occurs.
* @exception IllegalArgumentException If size is 0 or negative.
- *
+ *
* @since 1.2
*/
public void setReceiveBufferSize(int size) throws SocketException
@@ -474,7 +474,7 @@ public class DatagramSocket
* When a datagram socket is connected, it will only send or receive
* packets to and from the host to which it is connected. A multicast
* socket that is connected may only send and not receive packets.
- *
+ *
* @param address The address to connect this socket to.
* @param port The port to connect this socket to.
*
@@ -488,10 +488,10 @@ public class DatagramSocket
public void connect(InetAddress address, int port)
{
if (address == null)
- throw new IllegalArgumentException ("Connect address may not be null");
+ throw new IllegalArgumentException("Connect address may not be null");
if ((port < 1) || (port > 65535))
- throw new IllegalArgumentException ("Port number is illegal: " + port);
+ throw new IllegalArgumentException("Port number is illegal: " + port);
SecurityManager sm = System.getSecurityManager();
if (sm != null)
@@ -499,13 +499,13 @@ public class DatagramSocket
try
{
- getImpl().connect (address, port);
- remoteAddress = address;
- remotePort = port;
+ getImpl().connect(address, port);
+ remoteAddress = address;
+ remotePort = port;
}
catch (SocketException e)
{
- // This means simply not connected or connect not implemented.
+ // This means simply not connected or connect not implemented.
}
}
@@ -513,12 +513,12 @@ public class DatagramSocket
* This method disconnects this socket from the address/port it was
* connected to. If the socket was not connected in the first place,
* this method does nothing.
- *
+ *
* @since 1.2
*/
public void disconnect()
{
- if (!isConnected())
+ if (! isConnected())
return;
try
@@ -559,22 +559,20 @@ public class DatagramSocket
{
if (isClosed())
throw new SocketException("socket is closed");
-
- if (remoteAddress != null
- && remoteAddress.isMulticastAddress())
+
+ if (remoteAddress != null && remoteAddress.isMulticastAddress())
throw new IOException
- ("Socket connected to a multicast address my not receive");
+ ("Socket connected to a multicast address my not receive");
- if (getChannel() != null
- && !getChannel().isBlocking ()
- && !((DatagramChannelImpl) getChannel()).isInChannelOperation())
- throw new IllegalBlockingModeException ();
+ if (getChannel() != null && ! getChannel().isBlocking()
+ && ! ((DatagramChannelImpl) getChannel()).isInChannelOperation())
+ throw new IllegalBlockingModeException();
getImpl().receive(p);
SecurityManager s = System.getSecurityManager();
- if (s != null && isConnected ())
- s.checkAccept (p.getAddress().getHostName (), p.getPort ());
+ if (s != null && isConnected())
+ s.checkAccept(p.getAddress().getHostName(), p.getPort());
}
/**
@@ -596,33 +594,31 @@ public class DatagramSocket
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
// JDK1.2: Don't do security checks if socket is connected; see jdk1.2 api.
SecurityManager s = System.getSecurityManager();
- if (s != null && !isConnected ())
+ if (s != null && ! isConnected())
{
- InetAddress addr = p.getAddress();
- if (addr.isMulticastAddress())
- s.checkMulticast(addr);
- else
- s.checkConnect(addr.getHostAddress(), p.getPort());
+ InetAddress addr = p.getAddress();
+ if (addr.isMulticastAddress())
+ s.checkMulticast(addr);
+ else
+ s.checkConnect(addr.getHostAddress(), p.getPort());
}
- if (isConnected ())
+ if (isConnected())
{
- if (p.getAddress () != null && (remoteAddress != p.getAddress () ||
- remotePort != p.getPort ()))
- throw new IllegalArgumentException (
- "DatagramPacket address does not match remote address" );
+ if (p.getAddress() != null
+ && (remoteAddress != p.getAddress() || remotePort != p.getPort()))
+ throw new IllegalArgumentException
+ ("DatagramPacket address does not match remote address");
}
-
+
// FIXME: if this is a subclass of MulticastSocket,
// use getTimeToLive for TTL val.
-
- if (getChannel() != null
- && !getChannel().isBlocking ()
- && !((DatagramChannelImpl) getChannel()).isInChannelOperation())
- throw new IllegalBlockingModeException ();
+ if (getChannel() != null && ! getChannel().isBlocking()
+ && ! ((DatagramChannelImpl) getChannel()).isInChannelOperation())
+ throw new IllegalBlockingModeException();
getImpl().send(p);
}
@@ -639,12 +635,11 @@ public class DatagramSocket
*
* @since 1.4
*/
- public void bind (SocketAddress address)
- throws SocketException
+ public void bind(SocketAddress address) throws SocketException
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
if (! (address instanceof InetSocketAddress))
throw new IllegalArgumentException("unsupported address type");
@@ -654,32 +649,32 @@ public class DatagramSocket
if (port < 0 || port > 65535)
throw new IllegalArgumentException("Invalid port: " + port);
- SecurityManager s = System.getSecurityManager ();
+ SecurityManager s = System.getSecurityManager();
if (s != null)
s.checkListen(port);
if (addr == null)
addr = InetAddress.ANY_IF;
-
+
try
{
- getImpl().bind(port, addr);
+ getImpl().bind(port, addr);
bound = true;
}
catch (SocketException exception)
{
- getImpl().close();
- throw exception;
+ getImpl().close();
+ throw exception;
}
catch (RuntimeException exception)
{
- getImpl().close();
- throw exception;
+ getImpl().close();
+ throw exception;
}
catch (Error error)
{
- getImpl().close();
- throw error;
+ getImpl().close();
+ throw error;
}
}
@@ -687,7 +682,7 @@ public class DatagramSocket
* Checks if the datagram socket is closed.
*
* @return True if socket is closed, false otherwise.
- *
+ *
* @since 1.4
*/
public boolean isClosed()
@@ -697,9 +692,9 @@ public class DatagramSocket
/**
* Returns the datagram channel assoziated with this datagram socket.
- *
+ *
* @return The associated <code>DatagramChannel</code> object or null
- *
+ *
* @since 1.4
*/
public DatagramChannel getChannel()
@@ -717,23 +712,23 @@ public class DatagramSocket
*
* @since 1.4
*/
- public void connect (SocketAddress address) throws SocketException
+ public void connect(SocketAddress address) throws SocketException
{
if (isClosed())
throw new SocketException("socket is closed");
-
- if ( !(address instanceof InetSocketAddress) )
+
+ if (! (address instanceof InetSocketAddress))
throw new IllegalArgumentException("unsupported address type");
InetSocketAddress tmp = (InetSocketAddress) address;
connect(tmp.getAddress(), tmp.getPort());
}
-
+
/**
* Returns the binding state of the socket.
- *
+ *
* @return True if socket bound, false otherwise.
- *
+ *
* @since 1.4
*/
public boolean isBound()
@@ -743,9 +738,9 @@ public class DatagramSocket
/**
* Returns the connection state of the socket.
- *
+ *
* @return True if socket is connected, false otherwise.
- *
+ *
* @since 1.4
*/
public boolean isConnected()
@@ -756,32 +751,32 @@ public class DatagramSocket
/**
* Returns the SocketAddress of the host this socket is conneted to
* or null if this socket is not connected.
- *
+ *
* @return The socket address of the remote host if connected or null
- *
+ *
* @since 1.4
*/
public SocketAddress getRemoteSocketAddress()
{
- if (!isConnected ())
+ if (! isConnected())
return null;
- return new InetSocketAddress (remoteAddress, remotePort);
+ return new InetSocketAddress(remoteAddress, remotePort);
}
/**
* Returns the local SocketAddress this socket is bound to.
*
* @return The local SocketAddress or null if the socket is not bound.
- *
+ *
* @since 1.4
*/
public SocketAddress getLocalSocketAddress()
{
- if (!isBound())
+ if (! isBound())
return null;
-
- return new InetSocketAddress (getLocalAddress(), getLocalPort());
+
+ return new InetSocketAddress(getLocalAddress(), getLocalPort());
}
/**
@@ -798,7 +793,7 @@ public class DatagramSocket
if (isClosed())
throw new SocketException("socket is closed");
- getImpl().setOption (SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
+ getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
}
/**
@@ -807,7 +802,7 @@ public class DatagramSocket
* @return True if SO_REUSEADDR is set on the socket, false otherwise.
*
* @exception SocketException If an error occurs.
- *
+ *
* @since 1.4
*/
public boolean getReuseAddress() throws SocketException
@@ -815,8 +810,8 @@ public class DatagramSocket
if (isClosed())
throw new SocketException("socket is closed");
- Object buf = getImpl().getOption (SocketOptions.SO_REUSEADDR);
-
+ Object buf = getImpl().getOption(SocketOptions.SO_REUSEADDR);
+
if (buf instanceof Boolean)
return ((Boolean) buf).booleanValue();
@@ -825,7 +820,7 @@ public class DatagramSocket
/**
* Enables/Disables SO_BROADCAST
- *
+ *
* @param enable True if SO_BROADCAST should be enabled, false otherwise.
*
* @exception SocketException If an error occurs
@@ -842,11 +837,11 @@ public class DatagramSocket
/**
* Checks if SO_BROADCAST is enabled
- *
+ *
* @return Whether SO_BROADCAST is set
*
* @exception SocketException If an error occurs
- *
+ *
* @since 1.4
*/
public boolean getBroadcast() throws SocketException
@@ -855,7 +850,7 @@ public class DatagramSocket
throw new SocketException("socket is closed");
Object buf = getImpl().getOption(SocketOptions.SO_BROADCAST);
-
+
if (buf instanceof Boolean)
return ((Boolean) buf).booleanValue();
@@ -871,11 +866,10 @@ public class DatagramSocket
* @exception IllegalArgumentException If tc value is illegal
*
* @see DatagramSocket#getTrafficClass()
- *
+ *
* @since 1.4
*/
- public void setTrafficClass(int tc)
- throws SocketException
+ public void setTrafficClass(int tc) throws SocketException
{
if (isClosed())
throw new SocketException("socket is closed");
@@ -883,25 +877,25 @@ public class DatagramSocket
if (tc < 0 || tc > 255)
throw new IllegalArgumentException();
- getImpl().setOption (SocketOptions.IP_TOS, new Integer (tc));
+ getImpl().setOption(SocketOptions.IP_TOS, new Integer(tc));
}
-
+
/**
* Returns the current traffic class
- *
+ *
* @return The current traffic class.
*
* @see DatagramSocket#setTrafficClass(int tc)
*
* @exception SocketException If an error occurs
- *
+ *
* @since 1.4
*/
public int getTrafficClass() throws SocketException
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
Object buf = getImpl().getOption(SocketOptions.IP_TOS);
if (buf instanceof Integer)
@@ -909,7 +903,7 @@ public class DatagramSocket
throw new SocketException("unexpected type");
}
-
+
/**
* Sets the datagram socket implementation factory for the application
*
@@ -920,11 +914,11 @@ public class DatagramSocket
* @exception SecurityException If a security manager exists and its
* checkSetFactory method doesn't allow the operation
*/
- public static void setDatagramSocketImplFactory
- (DatagramSocketImplFactory fac) throws IOException
+ public static void setDatagramSocketImplFactory(DatagramSocketImplFactory fac)
+ throws IOException
{
if (factory != null)
- throw new SocketException ("DatagramSocketImplFactory already defined");
+ throw new SocketException("DatagramSocketImplFactory already defined");
SecurityManager sm = System.getSecurityManager();
if (sm != null)
diff --git a/libjava/java/net/DatagramSocketImpl.java b/libjava/java/net/DatagramSocketImpl.java
index 891c8d183b5..0c21e2410d8 100644
--- a/libjava/java/net/DatagramSocketImpl.java
+++ b/libjava/java/net/DatagramSocketImpl.java
@@ -1,5 +1,5 @@
/* DatagramSocketImpl.java -- Abstract class for UDP socket implementations
- Copyright (C) 1998, 1999 2000, 2001,
+ Copyright (C) 1998, 1999 2000, 2001,
2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -36,11 +36,11 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.net;
-import java.io.IOException;
import java.io.FileDescriptor;
+import java.io.IOException;
+
/**
* This abstract class models a datagram socket implementation. An
@@ -58,7 +58,6 @@ import java.io.FileDescriptor;
*/
public abstract class DatagramSocketImpl implements SocketOptions
{
-
/**
* The local port to which this socket is bound
*/
@@ -103,7 +102,7 @@ public abstract class DatagramSocketImpl implements SocketOptions
* Takes a peek at the next packet received in order to retrieve the
* address of the sender
*
- * @param i The <code>InetAddress</code> to fill in with the information
+ * @param i The <code>InetAddress</code> to fill in with the information
* about the sender if the next packet
*
* @return The port number of the sender of the packet
@@ -118,19 +117,19 @@ public abstract class DatagramSocketImpl implements SocketOptions
/**
* Takes a peek at the next packet received. This packet is not consumed.
* With the next peekData/receive operation this packet will be read again.
- *
+ *
* @param p The <code>DatagramPacket</code> to fill in with the data sent.
*
* @return The port number of the sender of the packet.
- *
+ *
* @exception IOException If an error occurs
* @exception PortUnreachableException May be thrown if the socket is
* connected to a currently unreachable destination. Note, there is no
* guarantee that the exception will be thrown.
- *
+ *
* @since 1.4
*/
- protected abstract int peekData (DatagramPacket p) throws IOException;
+ protected abstract int peekData(DatagramPacket p) throws IOException;
/**
* Transmits the specified packet of data to the network. The destination
@@ -169,17 +168,18 @@ public abstract class DatagramSocketImpl implements SocketOptions
*
* @since 1.4
*/
- protected void connect (InetAddress address, int port) throws SocketException
+ protected void connect(InetAddress address, int port)
+ throws SocketException
{
// This method has to be overwritten by real implementations
}
/**
* Disconnects the socket.
- *
+ *
* @since 1.4
*/
- protected void disconnect ()
+ protected void disconnect()
{
// This method has to be overwritten by real implementations
}
@@ -199,8 +199,11 @@ public abstract class DatagramSocketImpl implements SocketOptions
* This method returns the current Time to Live (TTL) setting on this
* socket. <b>Use <code>getTimeToLive()</code></b> instead.
*
+ * @return the current time-to-live
+ *
* @exception IOException If an error occurs
- * @deprecated
+ *
+ * @deprecated // FIXME: when ?
*/
protected abstract byte getTTL() throws IOException;
@@ -218,6 +221,8 @@ public abstract class DatagramSocketImpl implements SocketOptions
* This method returns the current Time to Live (TTL) setting on this
* socket.
*
+ * @return the current time-to-live
+ *
* @exception IOException If an error occurs
*/
protected abstract int getTimeToLive() throws IOException;
@@ -242,35 +247,37 @@ public abstract class DatagramSocketImpl implements SocketOptions
/**
* Causes this socket to join the specified multicast group on a specified
- * device
- *
+ * device
+ *
* @param mcastaddr The address to leave
* @param netIf The specified network interface to join the group at
*
* @exception IOException If an error occurs
- *
+ *
* @since 1.4
*/
- protected abstract void joinGroup (SocketAddress mcastaddr,
- NetworkInterface netIf)
+ protected abstract void joinGroup(SocketAddress mcastaddr,
+ NetworkInterface netIf)
throws IOException;
/**
* Leaves a multicast group
- *
+ *
* @param mcastaddr The address to join
* @param netIf The specified network interface to leave the group at
*
* @exception IOException If an error occurs
- *
+ *
* @since 1.4
*/
- protected abstract void leaveGroup (SocketAddress mcastaddr,
- NetworkInterface netIf)
+ protected abstract void leaveGroup(SocketAddress mcastaddr,
+ NetworkInterface netIf)
throws IOException;
-
+
/**
* Returns the FileDescriptor for this socket
+ *
+ * @return the file descriptor associated with this socket
*/
protected FileDescriptor getFileDescriptor()
{
@@ -279,6 +286,8 @@ public abstract class DatagramSocketImpl implements SocketOptions
/**
* Returns the local port this socket is bound to
+ *
+ * @return the local port
*/
protected int getLocalPort()
{
diff --git a/libjava/java/net/DatagramSocketImplFactory.java b/libjava/java/net/DatagramSocketImplFactory.java
index 45bb18919ac..16a0a2ec1aa 100644
--- a/libjava/java/net/DatagramSocketImplFactory.java
+++ b/libjava/java/net/DatagramSocketImplFactory.java
@@ -7,7 +7,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -37,12 +37,12 @@ exception statement from your version. */
package java.net;
+
/** Written using on-line Java Platform 1.4 API Specification.
* Status: Believed complete and correct.
*/
-
/**
- * This interface defines one method which returns a
+ * This interface defines one method which returns a
* <code>DatagramSocketImpl</code> object.
* This should not be needed by ordinary applications.
*
@@ -57,5 +57,4 @@ public interface DatagramSocketImplFactory
* @return A DatagramSocketImpl object
*/
DatagramSocketImpl createDatagramSocketImpl();
-
} // interface DatagramSocketImplFactory
diff --git a/libjava/java/net/FileNameMap.java b/libjava/java/net/FileNameMap.java
index c6c50000c77..fbc6059c564 100644
--- a/libjava/java/net/FileNameMap.java
+++ b/libjava/java/net/FileNameMap.java
@@ -7,7 +7,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -35,15 +35,14 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.net;
+
/**
* Written using on-line Java Platform 1.2 API Specification, as well
* as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
* Status: Believed complete and correct.
*/
-
/**
* This interface has one method which, when passed a filename, returns
* the MIME type associated with that filename.
@@ -63,6 +62,4 @@ public interface FileNameMap
* @return The MIME type for the filename passed in.
*/
String getContentTypeFor(String filename);
-
} // interface FileNameMap
-
diff --git a/libjava/java/net/HttpURLConnection.java b/libjava/java/net/HttpURLConnection.java
index 6d5fdfcef6a..e603d2b929d 100644
--- a/libjava/java/net/HttpURLConnection.java
+++ b/libjava/java/net/HttpURLConnection.java
@@ -8,7 +8,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -17,7 +17,7 @@ General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-02111-1307 USA.
+02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
@@ -36,14 +36,14 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.net;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.PushbackInputStream;
import java.security.Permission;
+
/*
* Written using on-line Java Platform 1.2 API Specification, as well
* as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
@@ -51,12 +51,12 @@ import java.security.Permission;
*/
/**
- * This class provides a common abstract implementation for those
+ * This class provides a common abstract implementation for those
* URL connection classes that will connect using the HTTP protocol.
* In addition to the functionality provided by the URLConnection
* class, it defines constants for HTTP return code values and
* methods for setting the HTTP request method and determining whether
- * or not to follow redirects.
+ * or not to follow redirects.
*
* @since 1.1
*
@@ -73,27 +73,27 @@ public abstract class HttpURLConnection extends URLConnection
* beware of using this value
*/
static final int HTTP_CONTINUE = 100;
-
+
/**
* Indicates the request succeeded.
*/
- public static final int HTTP_OK = 200;
+ public static final int HTTP_OK = 200;
/**
* The requested resource has been created.
*/
- public static final int HTTP_CREATED = 201;
+ public static final int HTTP_CREATED = 201;
/**
* The request has been accepted for processing but has not completed.
* There is no guarantee that the requested action will actually ever
* be completed succesfully, but everything is ok so far.
*/
- public static final int HTTP_ACCEPTED = 202;
+ public static final int HTTP_ACCEPTED = 202;
/**
* The meta-information returned in the header is not the actual data
- * from the original server, but may be from a local or other copy.
+ * from the original server, but may be from a local or other copy.
* Normally this still indicates a successful completion.
*/
public static final int HTTP_NOT_AUTHORITATIVE = 203;
@@ -102,20 +102,19 @@ public abstract class HttpURLConnection extends URLConnection
* The server performed the request, but there is no data to send
* back. This indicates that the user's display should not be changed.
*/
- public static final int HTTP_NO_CONTENT = 204;
+ public static final int HTTP_NO_CONTENT = 204;
/**
* The server performed the request, but there is no data to sent back,
* however, the user's display should be "reset" to clear out any form
* fields entered.
*/
- public static final int HTTP_RESET = 205;
+ public static final int HTTP_RESET = 205;
/**
* The server completed the partial GET request for the resource.
*/
- public static final int HTTP_PARTIAL = 206;
-
+ public static final int HTTP_PARTIAL = 206;
/* HTTP Redirection Response Codes */
@@ -123,22 +122,22 @@ public abstract class HttpURLConnection extends URLConnection
* There is a list of choices available for the requested resource.
*/
public static final int HTTP_MULT_CHOICE = 300;
-
+
/**
* The resource has been permanently moved to a new location.
*/
public static final int HTTP_MOVED_PERM = 301;
-
+
/**
* The resource requested has been temporarily moved to a new location.
*/
public static final int HTTP_MOVED_TEMP = 302;
-
+
/**
* The response to the request issued is available at another location.
*/
public static final int HTTP_SEE_OTHER = 303;
-
+
/**
* The document has not been modified since the criteria specified in
* a conditional GET.
@@ -149,64 +148,63 @@ public abstract class HttpURLConnection extends URLConnection
* The requested resource needs to be accessed through a proxy.
*/
public static final int HTTP_USE_PROXY = 305;
-
-
+
/* HTTP Client Error Response Codes */
/**
* The request was misformed or could not be understood.
*/
public static final int HTTP_BAD_REQUEST = 400;
-
+
/**
* The request made requires user authorization. Try again with
* a correct authentication header.
*/
public static final int HTTP_UNAUTHORIZED = 401;
-
+
/**
* Code reserved for future use - I hope way in the future.
*/
public static final int HTTP_PAYMENT_REQUIRED = 402;
-
+
/**
* There is no permission to access the requested resource.
*/
public static final int HTTP_FORBIDDEN = 403;
-
+
/**
* The requested resource was not found.
*/
public static final int HTTP_NOT_FOUND = 404;
-
+
/**
* The specified request method is not allowed for this resource.
*/
public static final int HTTP_BAD_METHOD = 405;
-
+
/**
* Based on the input headers sent, the resource returned in response
* to the request would not be acceptable to the client.
*/
public static final int HTTP_NOT_ACCEPTABLE = 406;
-
+
/**
* The client must authenticate with a proxy prior to attempting this
* request.
*/
public static final int HTTP_PROXY_AUTH = 407;
-
+
/**
* The request timed out.
*/
public static final int HTTP_CLIENT_TIMEOUT = 408;
-
+
/**
* There is a conflict between the current state of the resource and the
* requested action.
*/
public static final int HTTP_CONFLICT = 409;
-
+
/**
* The requested resource is no longer available. This ususally indicates
* a permanent condition.
@@ -218,28 +216,27 @@ public abstract class HttpURLConnection extends URLConnection
* supplied.
*/
public static final int HTTP_LENGTH_REQUIRED = 411;
-
+
/**
* A client specified pre-condition was not met on the server.
*/
public static final int HTTP_PRECON_FAILED = 412;
-
+
/**
* The request sent was too large for the server to handle.
*/
public static final int HTTP_ENTITY_TOO_LARGE = 413;
-
+
/**
* The name of the resource specified was too long.
*/
public static final int HTTP_REQ_TOO_LONG = 414;
-
+
/**
* The request is in a format not supported by the requested resource.
*/
public static final int HTTP_UNSUPPORTED_TYPE = 415;
-
/* HTTP Server Error Response Codes */
/**
@@ -247,16 +244,16 @@ public abstract class HttpURLConnection extends URLConnection
*
* @deprecated
*/
- public static final int HTTP_SERVER_ERROR = 500;
+ public static final int HTTP_SERVER_ERROR = 500;
/**
* The server encountered an unexpected error (such as a CGI script crash)
* that prevents the request from being fulfilled.
*/
- public static final int HTTP_INTERNAL_ERROR = 500;
+ public static final int HTTP_INTERNAL_ERROR = 500;
/**
- * The server does not support the requested functionality.
+ * The server does not support the requested functionality.
* @since 1.3
*/
public static final int HTTP_NOT_IMPLEMENTED = 501;
@@ -294,8 +291,8 @@ public abstract class HttpURLConnection extends URLConnection
/**
* This is a list of valid request methods, separated by "|" characters.
*/
- private static String valid_methods
- = "|GET|POST|HEAD|OPTIONS|PUT|DELETE|TRACE|";
+ private static String valid_methods =
+ "|GET|POST|HEAD|OPTIONS|PUT|DELETE|TRACE|";
// Instance Variables
@@ -312,7 +309,7 @@ public abstract class HttpURLConnection extends URLConnection
/**
* The response message string received from the server.
*/
- protected String responseMessage = null;
+ protected String responseMessage;
/**
* If this instance should follow redirect requests.
@@ -324,7 +321,7 @@ public abstract class HttpURLConnection extends URLConnection
* Used by <code>getResponseCode()</code> and
* <code>getResponseMessage()</code>.
*/
- private boolean gotResponseVals = false;
+ private boolean gotResponseVals;
/**
* Create an HttpURLConnection for the specified URL
@@ -335,16 +332,16 @@ public abstract class HttpURLConnection extends URLConnection
{
super(url);
}
-
- /**
+
+ /**
* Closes the connection to the server.
*/
public abstract void disconnect();
- /**
+ /**
* Returns a boolean indicating whether or not this connection is going
* through a proxy
- *
+ *
* @return true if through a proxy, false otherwise
*/
public abstract boolean usingProxy();
@@ -370,7 +367,7 @@ public abstract class HttpURLConnection extends URLConnection
}
/**
- * Returns a boolean indicating whether or not HTTP redirects will
+ * Returns a boolean indicating whether or not HTTP redirects will
* automatically be followed or not.
*
* @return true if redirects will be followed, false otherwise
@@ -383,16 +380,20 @@ public abstract class HttpURLConnection extends URLConnection
/**
* Returns the value of this HttpURLConnection's instanceFollowRedirects
* field
+ *
+ * @return true if following redirects is enabled, false otherwise
*/
- public boolean getInstanceFollowRedirects ()
+ public boolean getInstanceFollowRedirects()
{
return instanceFollowRedirects;
}
/**
* Sets the value of this HttpURLConnection's instanceFollowRedirects field
+ *
+ * @param follow true to enable following redirects, false otherwise
*/
- public void setInstanceFollowRedirects (boolean follow)
+ public void setInstanceFollowRedirects(boolean follow)
{
instanceFollowRedirects = follow;
}
@@ -401,6 +402,8 @@ public abstract class HttpURLConnection extends URLConnection
* Set the method for the URL request, one of:
* GET POST HEAD OPTIONS PUT DELETE TRACE are legal
*
+ * @param method the method to use
+ *
* @exception ProtocolException If the method cannot be reset or if the
* requested method isn't valid for HTTP
*/
@@ -414,7 +417,6 @@ public abstract class HttpURLConnection extends URLConnection
this.method = method;
else
throw new ProtocolException("Invalid HTTP request method: " + method);
-
}
/**
@@ -439,7 +441,7 @@ public abstract class HttpURLConnection extends URLConnection
*/
public int getResponseCode() throws IOException
{
- if (!gotResponseVals)
+ if (! gotResponseVals)
getResponseVals();
return responseCode;
}
@@ -455,7 +457,7 @@ public abstract class HttpURLConnection extends URLConnection
*/
public String getResponseMessage() throws IOException
{
- if (!gotResponseVals)
+ if (! gotResponseVals)
getResponseVals();
return responseMessage;
}
@@ -464,9 +466,9 @@ public abstract class HttpURLConnection extends URLConnection
{
// getHeaderField() will connect for us, but do it here first in
// order to pick up IOExceptions.
- if (!connected)
+ if (! connected)
connect();
-
+
gotResponseVals = true;
// If responseCode not yet explicitly set by subclass
@@ -474,7 +476,7 @@ public abstract class HttpURLConnection extends URLConnection
{
// Response is the first header received from the connection.
String respField = getHeaderField(0);
-
+
if (respField == null || ! respField.startsWith("HTTP/"))
{
// Set to default values on failure.
@@ -483,7 +485,8 @@ public abstract class HttpURLConnection extends URLConnection
return;
}
- int firstSpc, nextSpc;
+ int firstSpc;
+ int nextSpc;
firstSpc = respField.indexOf(' ');
nextSpc = respField.indexOf(' ', firstSpc + 1);
responseMessage = respField.substring(nextSpc + 1);
@@ -505,6 +508,8 @@ public abstract class HttpURLConnection extends URLConnection
* Returns a permission object representing the permission necessary to make
* the connection represented by this object
*
+ * @return the permission necessary for this connection
+ *
* @exception IOException If an error occurs
*/
public Permission getPermission() throws IOException
@@ -514,9 +519,9 @@ public abstract class HttpURLConnection extends URLConnection
int port = url.getPort();
if (port == -1)
port = 80;
-
+
host = host + ":" + port;
-
+
return new SocketPermission(host, "connect");
}
@@ -529,52 +534,56 @@ public abstract class HttpURLConnection extends URLConnection
*
* @return An <code>InputStream</code> for reading error data.
*/
- public InputStream getErrorStream ()
+ public InputStream getErrorStream()
{
- if (!connected)
- return(null);
-
+ if (! connected)
+ return (null);
+
int code;
- try
+ try
{
code = getResponseCode();
}
- catch(IOException e)
+ catch (IOException e)
{
code = -1;
}
-
+
if (code == -1)
- return(null);
-
- if (((code/100) != 4) || ((code/100) != 5))
- return(null);
-
+ return (null);
+
+ if (((code / 100) != 4) || ((code / 100) != 5))
+ return (null);
+
try
{
PushbackInputStream pbis = new PushbackInputStream(getInputStream());
-
+
int i = pbis.read();
if (i == -1)
- return(null);
-
+ return (null);
+
pbis.unread(i);
- return(pbis);
+ return (pbis);
}
- catch(IOException e)
+ catch (IOException e)
{
- return(null);
+ return (null);
}
}
/**
* Returns the value of the named field parsed as date
+ *
+ * @param key the key of the header field
+ * @param value the default value if the header field is not present
+ *
+ * @return the value of the header field
*/
- public long getHeaderFieldDate (String key, long value)
+ public long getHeaderFieldDate(String key, long value)
{
// FIXME: implement this correctly
// http://www.w3.org/Protocols/HTTP-NG/ng-notes.txt
-
- return super.getHeaderFieldDate (key, value);
+ return super.getHeaderFieldDate(key, value);
}
}
diff --git a/libjava/java/net/Inet4Address.java b/libjava/java/net/Inet4Address.java
index 76abfc3fce4..0a583efc9c6 100644
--- a/libjava/java/net/Inet4Address.java
+++ b/libjava/java/net/Inet4Address.java
@@ -7,7 +7,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -35,12 +35,12 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.net;
import java.io.ObjectStreamException;
import java.util.Arrays;
+
/**
* @author Michael Koch
* @date August 3, 2002.
@@ -53,7 +53,6 @@ import java.util.Arrays;
* RFC 2365 (http://www.ietf.org/rfc/rfc2365.txt)
* Status: Believed complete and correct.
*/
-
public final class Inet4Address extends InetAddress
{
static final long serialVersionUID = 3286316764910316507L;
@@ -61,20 +60,20 @@ public final class Inet4Address extends InetAddress
/**
* needed for serialization
*/
- private Object writeReplace () throws ObjectStreamException
+ private Object writeReplace() throws ObjectStreamException
{
- return new InetAddress (addr, hostName);
+ return new InetAddress(addr, hostName);
}
/**
* Creates a Inet4Address
- *
+ *
* @param addr The IP address
* @param host The Hostname
*/
Inet4Address(byte[] addr, String host)
{
- super (addr, host);
+ super(addr, host);
}
/**
@@ -82,37 +81,37 @@ public final class Inet4Address extends InetAddress
*
* @since 1.1
*/
- public boolean isMulticastAddress ()
+ public boolean isMulticastAddress()
{
- return (addr [0] & 0xF0) == 0xE0;
+ return (addr[0] & 0xF0) == 0xE0;
}
-
+
/**
* Checks if this address is a loopback address
*/
- public boolean isLoopbackAddress ()
+ public boolean isLoopbackAddress()
{
- return addr [0] == 0x7F;
+ return addr[0] == 0x7F;
}
-
+
/**
* Checks if this address is a wildcard address
*
* @since 1.4
*/
- public boolean isAnyLocalAddress ()
+ public boolean isAnyLocalAddress()
{
byte[] anylocal = { 0, 0, 0, 0 };
-
+
return Arrays.equals(addr, anylocal);
}
/**
* Checks if this address is a link local address
- *
+ *
* @since 1.4
*/
- public boolean isLinkLocalAddress ()
+ public boolean isLinkLocalAddress()
{
// XXX: This seems to not exist with IPv4 addresses
return false;
@@ -120,36 +119,36 @@ public final class Inet4Address extends InetAddress
/**
* Checks if this address is a site local address
- *
+ *
* @since 1.4
*/
- public boolean isSiteLocalAddress ()
+ public boolean isSiteLocalAddress()
{
// 10.0.0.0/8
- if (addr [0] == 0x0A)
+ if (addr[0] == 0x0A)
return true;
// XXX: Suns JDK 1.4.1 (on Linux) seems to have a bug here:
// it says 172.16.0.0 - 172.255.255.255 are site local addresses
//
// 172.16.0.0/12
- if (addr [0] == 0xAC && (addr [1] & 0xF0) == 0x01)
+ if (addr[0] == 0xAC && (addr[1] & 0xF0) == 0x01)
return true;
// 192.168.0.0/16
- if (addr [0] == 0xC0 && addr [1] == 0xA8)
+ if (addr[0] == 0xC0 && addr[1] == 0xA8)
return true;
-
+
// XXX: Do we need to check more addresses here ?
return false;
}
/**
* Checks if this multicast address has global scope
- *
+ *
* @since 1.4
*/
- public boolean isMCGlobal ()
+ public boolean isMCGlobal()
{
// XXX: This seems to net exist with IPv4 addresses
return false;
@@ -157,120 +156,118 @@ public final class Inet4Address extends InetAddress
/**
* Checks if this multicast address has node scope
- *
+ *
* @since 1.4
*/
- public boolean isMCNodeLocal ()
+ public boolean isMCNodeLocal()
{
// XXX: This seems to net exist with IPv4 addresses
return false;
}
-
+
/**
* Checks if this multicast address has link scope
- *
+ *
* @since 1.4
*/
- public boolean isMCLinkLocal ()
+ public boolean isMCLinkLocal()
{
- if (!isMulticastAddress ())
+ if (! isMulticastAddress())
return false;
-
- return (addr [0] == 0xE0)
- && (addr [1] == 0x00)
- && (addr [2] == 0x00);
+
+ return (addr[0] == 0xE0) && (addr[1] == 0x00) && (addr[2] == 0x00);
}
-
+
/**
* Checks if this multicast address has site scope
- *
+ *
* @since 1.4
*/
- public boolean isMCSiteLocal ()
+ public boolean isMCSiteLocal()
{
// XXX: This seems to net exist with IPv4 addresses
return false;
}
-
+
/**
* Checks if this multicast address has organization scope
- *
+ *
* @since 1.4
*/
- public boolean isMCOrgLocal ()
+ public boolean isMCOrgLocal()
{
// XXX: This seems to net exist with IPv4 addresses
return false;
}
-
+
/**
* Returns the address of the current instance
*/
- public byte[] getAddress ()
+ public byte[] getAddress()
{
return addr;
}
-
+
/**
* Returns the address as string
- *
+ *
* @since 1.0.2
*/
- public String getHostAddress ()
+ public String getHostAddress()
{
- StringBuffer sbuf = new StringBuffer (40);
+ StringBuffer sbuf = new StringBuffer(40);
int len = addr.length;
int i = 0;
-
- for ( ; ; )
+
+ for (;;)
{
- sbuf.append (addr [i] & 0xFF);
+ sbuf.append(addr[i] & 0xFF);
i++;
-
+
if (i == len)
break;
-
- sbuf.append ('.');
+
+ sbuf.append('.');
}
-
- return sbuf.toString ();
+
+ return sbuf.toString();
}
-
+
/**
* Computes the hashcode of the instance
*/
- public int hashCode ()
+ public int hashCode()
{
int hash = 0;
int len = addr.length;
int i = len > 4 ? len - 4 : 0;
-
- for ( ; i < len; i++)
- hash = (hash << 8) | (addr [i] & 0xFF);
-
+
+ for (; i < len; i++)
+ hash = (hash << 8) | (addr[i] & 0xFF);
+
return hash;
}
-
+
/**
* Compare the current Inet4Address instance with obj
- *
+ *
* @param obj Object to compare with
*/
- public boolean equals (Object obj)
+ public boolean equals(Object obj)
{
if (! (obj instanceof InetAddress))
return false;
-
+
byte[] addr1 = addr;
byte[] addr2 = ((InetAddress) obj).addr;
-
+
if (addr1.length != addr2.length)
return false;
-
- for (int i = addr1.length; --i >= 0; )
- if (addr1 [i] != addr2 [i])
- return false;
-
+
+ for (int i = addr1.length; --i >= 0;)
+ if (addr1[i] != addr2[i])
+ return false;
+
return true;
}
} // class Inet4Address
diff --git a/libjava/java/net/Inet6Address.java b/libjava/java/net/Inet6Address.java
index c3418c654a9..5d527359980 100644
--- a/libjava/java/net/Inet6Address.java
+++ b/libjava/java/net/Inet6Address.java
@@ -7,7 +7,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -35,11 +35,11 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.net;
import java.util.Arrays;
+
/**
* @author Michael Koch
* @date August 3, 2002.
@@ -50,7 +50,6 @@ import java.util.Arrays;
* RFC 1884 (http://www.ietf.org/rfc/rfc1884.txt)
* Status: Believed complete and correct.
*/
-
public final class Inet6Address extends InetAddress
{
static final long serialVersionUID = 6880410070516793377L;
@@ -59,213 +58,210 @@ public final class Inet6Address extends InetAddress
* Needed for serialization
*/
byte[] ipaddress;
-
+
/**
* Create an Inet6Address object
*
* @param addr The IP address
* @param host The hostname
*/
- Inet6Address (byte[] addr, String host)
+ Inet6Address(byte[] addr, String host)
{
- super (addr, host);
+ super(addr, host);
this.ipaddress = addr;
}
/**
* Utility routine to check if the InetAddress is an IP multicast address
- *
+ *
* @since 1.1
*/
- public boolean isMulticastAddress ()
+ public boolean isMulticastAddress()
{
- return ipaddress [0] == 0xFF;
+ return ipaddress[0] == 0xFF;
}
-
+
/**
* Utility routine to check if the InetAddress in a wildcard address
- *
+ *
* @since 1.4
*/
- public boolean isAnyLocalAddress ()
+ public boolean isAnyLocalAddress()
{
- byte[] anylocal = { 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0 };
-
+ byte[] anylocal = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
return Arrays.equals(ipaddress, anylocal);
}
-
+
/**
* Utility routine to check if the InetAddress is a loopback address
- *
+ *
* @since 1.4
*/
- public boolean isLoopbackAddress ()
+ public boolean isLoopbackAddress()
{
- byte[] loopback = { 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1 };
-
+ byte[] loopback = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
+
return Arrays.equals(ipaddress, loopback);
}
/**
* Utility routine to check if the InetAddress is an link local address
- *
+ *
* @since 1.4
*/
- public boolean isLinkLocalAddress ()
+ public boolean isLinkLocalAddress()
{
- return ipaddress [0] == 0xFA;
+ return ipaddress[0] == 0xFA;
}
/**
* Utility routine to check if the InetAddress is a site local address
- *
+ *
* @since 1.4
*/
- public boolean isSiteLocalAddress ()
+ public boolean isSiteLocalAddress()
{
- return ipaddress [0] == 0xFB;
+ return ipaddress[0] == 0xFB;
}
/**
* Utility routine to check if the multicast address has global scope
- *
+ *
* @since 1.4
*/
- public boolean isMCGlobal ()
+ public boolean isMCGlobal()
{
- if (!isMulticastAddress ())
+ if (! isMulticastAddress())
return false;
-
- return (ipaddress [1] & 0x0F) == 0xE;
+
+ return (ipaddress[1] & 0x0F) == 0xE;
}
/**
* Utility routine to check if the multicast address has node scope
- *
+ *
* @since 1.4
*/
- public boolean isMCNodeLocal ()
+ public boolean isMCNodeLocal()
{
- if (!isMulticastAddress ())
+ if (! isMulticastAddress())
return false;
-
- return (ipaddress [1] & 0x0F) == 0x1;
+
+ return (ipaddress[1] & 0x0F) == 0x1;
}
/**
* Utility routine to check if the multicast address has link scope
- *
+ *
* @since 1.4
*/
- public boolean isMCLinkLocal ()
+ public boolean isMCLinkLocal()
{
- if (!isMulticastAddress ())
+ if (! isMulticastAddress())
return false;
-
- return (ipaddress [1] & 0x0F) == 0x2;
+
+ return (ipaddress[1] & 0x0F) == 0x2;
}
/**
* Utility routine to check if the multicast address has site scope
- *
+ *
* @since 1.4
*/
- public boolean isMCSiteLocal ()
+ public boolean isMCSiteLocal()
{
- if (!isMulticastAddress ())
+ if (! isMulticastAddress())
return false;
-
- return (ipaddress [1] & 0x0F) == 0x5;
+
+ return (ipaddress[1] & 0x0F) == 0x5;
}
/**
* Utility routine to check if the multicast address has organization scope
- *
+ *
* @since 1.4
*/
- public boolean isMCOrgLocal ()
+ public boolean isMCOrgLocal()
{
- if (!isMulticastAddress ())
+ if (! isMulticastAddress())
return false;
-
- return (ipaddress [1] & 0x0F) == 0x8;
+
+ return (ipaddress[1] & 0x0F) == 0x8;
}
-
+
/**
* Returns the raw IP address of this InetAddress object. The result is in
* network byte order: the highest order byte of the address is i
* n getAddress()[0]
*/
- public byte[] getAddress ()
+ public byte[] getAddress()
{
return ipaddress;
}
-
+
/**
* Returns the IP address string in textual presentation
*/
- public String getHostAddress ()
+ public String getHostAddress()
{
- StringBuffer sbuf = new StringBuffer (40);
+ StringBuffer sbuf = new StringBuffer(40);
for (int i = 0; i < 16; i += 2)
{
- int x = ((ipaddress [i] & 0xFF) << 8) | (ipaddress [i + 1] & 0xFF);
- boolean empty = sbuf.length () == 0;
-
- if (empty)
- {
- if (i > 0)
- sbuf.append ("::");
- }
- else
- sbuf.append (':');
-
- if (x != 0 || i >= 14)
- sbuf.append (Integer.toHexString (x));
+ int x = ((ipaddress[i] & 0xFF) << 8) | (ipaddress[i + 1] & 0xFF);
+ boolean empty = sbuf.length() == 0;
+
+ if (empty)
+ {
+ if (i > 0)
+ sbuf.append("::");
+ }
+ else
+ sbuf.append(':');
+
+ if (x != 0 || i >= 14)
+ sbuf.append(Integer.toHexString(x));
}
-
- return sbuf.toString ();
+
+ return sbuf.toString();
}
/**
* Returns a hashcode for this IP address
*/
- public int hashCode ()
+ public int hashCode()
{
- return super.hashCode ();
+ return super.hashCode();
}
-
+
/**
* Compares this object against the specified object
*/
- public boolean equals (Object obj)
+ public boolean equals(Object obj)
{
if (! (obj instanceof Inet6Address))
return false;
Inet6Address tmp = (Inet6Address) obj;
- return super.equals (tmp)
- && this.ipaddress == tmp.ipaddress;
+ return super.equals(tmp) && this.ipaddress == tmp.ipaddress;
}
-
+
/**
* Utility routine to check if the InetAddress is an
* IPv4 compatible IPv6 address
*
* @since 1.4
*/
- public boolean isIPv4CompatibleAddress ()
+ public boolean isIPv4CompatibleAddress()
{
- if (ipaddress [0] != 0x00 || ipaddress [1] != 0x00 ||
- ipaddress [2] != 0x00 || ipaddress [3] != 0x00 ||
- ipaddress [4] != 0x00 || ipaddress [5] != 0x00 ||
- ipaddress [6] != 0x00 || ipaddress [7] != 0x00 ||
- ipaddress [8] != 0x00 || ipaddress [9] != 0x00 ||
- ipaddress [10] != 0x00 || ipaddress [11] != 0x00)
+ if (ipaddress[0] != 0x00 || ipaddress[1] != 0x00 || ipaddress[2] != 0x00
+ || ipaddress[3] != 0x00 || ipaddress[4] != 0x00
+ || ipaddress[5] != 0x00 || ipaddress[6] != 0x00
+ || ipaddress[7] != 0x00 || ipaddress[8] != 0x00
+ || ipaddress[9] != 0x00 || ipaddress[10] != 0x00
+ || ipaddress[11] != 0x00)
return false;
return true;
diff --git a/libjava/java/net/InetAddress.java b/libjava/java/net/InetAddress.java
index 126348b412e..6d57566a1b3 100644
--- a/libjava/java/net/InetAddress.java
+++ b/libjava/java/net/InetAddress.java
@@ -7,7 +7,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -35,7 +35,6 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.net;
import gnu.classpath.Configuration;
@@ -63,7 +62,7 @@ import java.io.Serializable;
public class InetAddress implements Serializable
{
private static final long serialVersionUID = 3286316764910316507L;
-
+
/**
* Dummy InetAddress, used to bind socket to any (all) network interfaces.
*/
@@ -101,7 +100,7 @@ public class InetAddress implements Serializable
* The name of the host for this address.
*/
String hostName;
-
+
/**
* The field 'family' seems to be the AF_ value.
* FIXME: Much of the code in the other java.net classes does not make
@@ -118,7 +117,7 @@ public class InetAddress implements Serializable
*
* @param ipaddr The IP number of this address as an array of bytes
*/
- InetAddress (byte[] address)
+ InetAddress(byte[] address)
{
this (address, null);
}
@@ -131,7 +130,7 @@ public class InetAddress implements Serializable
* @param ipaddr The IP number of this address as an array of bytes
* @param hostname The hostname of this IP address.
*/
- InetAddress (byte[] address, String hostname)
+ InetAddress(byte[] address, String hostname)
{
addr = address;
hostName = hostname;
@@ -153,8 +152,8 @@ public class InetAddress implements Serializable
{
// Mask against high order bits of 1110
if (addr.length == 4)
- return (addr [0] & 0xF0) == 0xE0;
-
+ return (addr[0] & 0xF0) == 0xE0;
+
// Mask against high order bits of 11111111
if (addr.length == 16)
return addr [0] == (byte) 0xFF;
@@ -164,68 +163,62 @@ public class InetAddress implements Serializable
/**
* Utility routine to check if the InetAddress in a wildcard address
- *
+ *
* @since 1.4
*/
public boolean isAnyLocalAddress()
{
// This is the IPv4 implementation.
// Any class derived from InetAddress should override this.
- return equals (ANY_IF);
+ return equals(ANY_IF);
}
/**
* Utility routine to check if the InetAddress is a loopback address
- *
+ *
* @since 1.4
*/
public boolean isLoopbackAddress()
{
// This is the IPv4 implementation.
// Any class derived from InetAddress should override this.
-
- return addr [0] == 0x7F;
+ return addr[0] == 0x7F;
}
/**
* Utility routine to check if InetAddress is a link local address
- *
+ *
* @since 1.4
*/
public boolean isLinkLocalAddress()
{
// This is the IPv4 implementation.
// Any class derived from InetAddress should override this.
-
// XXX: This seems to not exist with IPv4 addresses
return false;
}
/**
* Utility routine to check if InetAddress is a site local address
- *
+ *
* @since 1.4
*/
public boolean isSiteLocalAddress()
{
// This is the IPv4 implementation.
// Any class derived from InetAddress should override this.
-
// 10.0.0.0/8
- if (addr [0] == 0x0A)
+ if (addr[0] == 0x0A)
return true;
// XXX: Suns JDK 1.4.1 (on Linux) seems to have a bug here:
// it says 172.16.0.0 - 172.255.255.255 are site local addresses
-
// 172.16.0.0/12
- if (addr [0] == 0xAC
- && (addr [1] & 0xF0) == 0x01)
+ if (addr[0] == 0xAC && (addr[1] & 0xF0) == 0x01)
return true;
// 192.168.0.0/16
- if (addr [0] == 0xC0
- && addr [1] == 0xA8)
+ if (addr[0] == 0xC0 && addr[1] == 0xA8)
return true;
// XXX: Do we need to check more addresses here ?
@@ -234,48 +227,43 @@ public class InetAddress implements Serializable
/**
* Utility routine to check if InetAddress is a global multicast address
- *
+ *
* @since 1.4
*/
public boolean isMCGlobal()
{
// This is the IPv4 implementation.
// Any class derived from InetAddress should override this.
-
// XXX: This seems to not exist with IPv4 addresses
return false;
}
/**
* Utility reoutine to check if InetAddress is a node local multicast address
- *
+ *
* @since 1.4
*/
public boolean isMCNodeLocal()
{
// This is the IPv4 implementation.
// Any class derived from InetAddress should override this.
-
// XXX: This seems to not exist with IPv4 addresses
return false;
}
/**
* Utility reoutine to check if InetAddress is a link local multicast address
- *
+ *
* @since 1.4
*/
public boolean isMCLinkLocal()
{
// This is the IPv4 implementation.
// Any class derived from InetAddress should override this.
-
- if (!isMulticastAddress())
+ if (! isMulticastAddress())
return false;
- return (addr [0] == 0xE0
- && addr [1] == 0x00
- && addr [2] == 0x00);
+ return (addr[0] == 0xE0 && addr[1] == 0x00 && addr[2] == 0x00);
}
/**
@@ -287,7 +275,6 @@ public class InetAddress implements Serializable
{
// This is the IPv4 implementation.
// Any class derived from InetAddress should override this.
-
// XXX: This seems to not exist with IPv4 addresses
return false;
}
@@ -295,14 +282,13 @@ public class InetAddress implements Serializable
/**
* Utility reoutine to check if InetAddress is a organization local
* multicast address
- *
+ *
* @since 1.4
*/
public boolean isMCOrgLocal()
{
// This is the IPv4 implementation.
// Any class derived from InetAddress should override this.
-
// XXX: This seems to not exist with IPv4 addresses
return false;
}
@@ -384,7 +370,7 @@ public class InetAddress implements Serializable
}
/**
- * Returns the IP address of this object as a String. The address is in
+ * Returns the IP address of this object as a String. The address is in
* the dotted octet notation, for example, "127.0.0.1".
*
* @return The IP address of this object in String form
@@ -393,7 +379,8 @@ public class InetAddress implements Serializable
*/
public String getHostAddress()
{
- StringBuffer sb = new StringBuffer (40);
+ StringBuffer sb = new StringBuffer(40);
+
int len = addr.length;
int i = 0;
@@ -440,7 +427,7 @@ public class InetAddress implements Serializable
sb.append ('.');
}
-
+
return sb.toString();
}
@@ -457,10 +444,10 @@ public class InetAddress implements Serializable
int hash = 0;
int len = addr.length;
int i = len > 4 ? len - 4 : 0;
-
- for ( ; i < len; i++)
+
+ for (; i < len; i++)
hash = (hash << 8) | (addr[i] & 0xFF);
-
+
return hash;
}
@@ -474,11 +461,11 @@ public class InetAddress implements Serializable
* @return true if the passed in object's address is equal to this one's,
* false otherwise
*/
- public boolean equals (Object obj)
+ public boolean equals(Object obj)
{
if (! (obj instanceof InetAddress))
return false;
-
+
// "The Java Class Libraries" 2nd edition says "If a machine has
// multiple names instances of InetAddress for different name of
// that same machine are not equal. This is because they have
@@ -486,14 +473,14 @@ public class InetAddress implements Serializable
// JDK 1.2 API documentation. A little experimentation
// shows that the latter is correct.
byte[] addr2 = ((InetAddress) obj).addr;
-
+
if (addr.length != addr2.length)
return false;
-
+
for (int i = 0; i < addr.length; i++)
- if (addr [i] != addr2 [i])
+ if (addr[i] != addr2[i])
return false;
-
+
return true;
}
@@ -508,12 +495,12 @@ public class InetAddress implements Serializable
{
String host;
String address = getHostAddress();
-
+
if (hostName != null)
host = hostName;
else
host = address;
-
+
return host + "/" + address;
}
@@ -529,10 +516,10 @@ public class InetAddress implements Serializable
*
* @since 1.4
*/
- public static InetAddress getByAddress (byte[] addr)
+ public static InetAddress getByAddress(byte[] addr)
throws UnknownHostException
{
- return getByAddress (null, addr);
+ return getByAddress(null, addr);
}
/**
@@ -546,18 +533,18 @@ public class InetAddress implements Serializable
*
* @since 1.4
*/
- public static InetAddress getByAddress (String host, byte[] addr)
+ public static InetAddress getByAddress(String host, byte[] addr)
throws UnknownHostException
{
if (addr.length == 4)
- return new Inet4Address (addr, host);
+ return new Inet4Address(addr, host);
if (addr.length == 16)
- return new Inet6Address (addr, host);
-
- throw new UnknownHostException ("IP address has illegal length");
+ return new Inet6Address(addr, host);
+
+ throw new UnknownHostException("IP address has illegal length");
}
-
+
/**
* If host is a valid numeric IP address, return the numeric address.
* Otherwise, return null.
@@ -578,7 +565,7 @@ public class InetAddress implements Serializable
* the InetAddress array returned from GetAllByName.
*
* @param hostname The name of the desired host, or null for the local machine.
- *
+ *
* @return The address of the host as an InetAddress object.
*
* @exception UnknownHostException If no IP address for the host could
@@ -586,19 +573,19 @@ public class InetAddress implements Serializable
* @exception SecurityException If a security manager exists and its
* checkConnect method doesn't allow the operation
*/
- public static InetAddress getByName (String hostname)
+ public static InetAddress getByName(String hostname)
throws UnknownHostException
{
SecurityManager s = System.getSecurityManager();
if (s != null)
- s.checkConnect (hostname, -1);
-
+ s.checkConnect(hostname, -1);
+
// Default to current host if necessary
if (hostname == null || hostname.length() == 0)
return getLocalHost();
// Assume that the host string is an IP address
- byte[] address = aton (hostname);
+ byte[] address = aton(hostname);
if (address != null)
{
if (address.length == 4)
@@ -619,10 +606,10 @@ public class InetAddress implements Serializable
else
throw new UnknownHostException ("Address has invalid length");
}
-
+
// Try to resolve the host by DNS
- InetAddress[] addresses = getAllByName (hostname);
- return addresses [0];
+ InetAddress[] addresses = getAllByName(hostname);
+ return addresses[0];
}
/**
@@ -632,22 +619,22 @@ public class InetAddress implements Serializable
* dotted decimal format such as "127.0.0.1". If the value is null, the
* hostname of the local machine is supplied by default.
*
- * @param @param hostname The name of the desired host, or null for the
+ * @param hostname The name of the desired host, or null for the
* local machine.
*
* @return All addresses of the host as an array of InetAddress objects.
- *
+ *
* @exception UnknownHostException If no IP address for the host could
* be found
* @exception SecurityException If a security manager exists and its
* checkConnect method doesn't allow the operation
*/
- public static InetAddress[] getAllByName (String hostname)
+ public static InetAddress[] getAllByName(String hostname)
throws UnknownHostException
{
SecurityManager s = System.getSecurityManager();
if (s != null)
- s.checkConnect (hostname, -1);
+ s.checkConnect(hostname, -1);
// Check if hostname is an IP address
byte[] address = aton (hostname);
@@ -657,7 +644,7 @@ public class InetAddress implements Serializable
result [0] = new InetAddress (address, null);
return result;
}
-
+
// Try to resolve the hostname by DNS
return lookup (hostname, null, true);
}
@@ -747,17 +734,17 @@ public class InetAddress implements Serializable
{
// FIXME: implement this
}
-
- private void readObject (ObjectInputStream ois)
+
+ private void readObject(ObjectInputStream ois)
throws IOException, ClassNotFoundException
{
ois.defaultReadObject();
- addr = new byte [4];
- addr [3] = (byte) address;
-
+ addr = new byte[4];
+ addr[3] = (byte) address;
+
for (int i = 2; i >= 0; --i)
- addr [i] = (byte) (address >>= 8);
-
+ addr[i] = (byte) (address >>= 8);
+
// Ignore family from serialized data. Since the saved address is 32 bits
// the deserialized object will have an IPv4 address i.e. AF_INET family.
// FIXME: An alternative is to call the aton method on the deserialized
@@ -766,16 +753,16 @@ public class InetAddress implements Serializable
family = getFamily (addr);
}
- private void writeObject (ObjectOutputStream oos) throws IOException
+ private void writeObject(ObjectOutputStream oos) throws IOException
{
// Build a 32 bit address from the last 4 bytes of a 4 byte IPv4 address
// or a 16 byte IPv6 address.
int len = addr.length;
int i = len - 4;
-
+
for (; i < len; i++)
- address = address << 8 | (((int) addr [i]) & 0xFF);
-
+ address = address << 8 | (((int) addr[i]) & 0xFF);
+
oos.defaultWriteObject();
}
}
diff --git a/libjava/java/net/InetSocketAddress.java b/libjava/java/net/InetSocketAddress.java
index f0a27e3c3be..5dc63dcd0db 100644
--- a/libjava/java/net/InetSocketAddress.java
+++ b/libjava/java/net/InetSocketAddress.java
@@ -1,4 +1,4 @@
-/* InetSocketAddress.java --
+/* InetSocketAddress.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,21 +37,21 @@ exception statement from your version. */
package java.net;
-/**
+
+/**
* InetSocketAddress instances represent socket addresses
* in the java.nio package. They encapsulate a InetAddress and
* a port number.
*
* @since 1.4
*/
-
public class InetSocketAddress extends SocketAddress
{
/**
* Compatible with JDK 1.4+
*/
private static final long serialVersionUID = 5076001401234631237L;
-
+
/**
* Name of host.
*/
@@ -66,10 +66,10 @@ public class InetSocketAddress extends SocketAddress
* Port of host.
*/
private int port;
-
+
/**
* Constructs an InetSocketAddress instance.
- *
+ *
* @param addr Address of the socket
* @param port Port if the socket
*
@@ -79,34 +79,33 @@ public class InetSocketAddress extends SocketAddress
throws IllegalArgumentException
{
if (port < 0 || port > 65535)
- throw new IllegalArgumentException ("Bad port number: " + port);
+ throw new IllegalArgumentException("Bad port number: " + port);
if (addr == null)
addr = InetAddress.ANY_IF;
-
+
this.addr = addr;
this.port = port;
- this.hostname = addr.getHostName ();
+ this.hostname = addr.getHostName();
}
/**
* Constructs an InetSocketAddress instance.
- *
+ *
* @param port Port if the socket
*
* @exception IllegalArgumentException If the port number is illegal
*/
- public InetSocketAddress(int port)
- throws IllegalArgumentException
+ public InetSocketAddress(int port) throws IllegalArgumentException
{
- this ((InetAddress) null, port);
+ this((InetAddress) null, port);
}
/**
* Constructs an InetSocketAddress instance.
*
- * @param addr Address of the socket
- * @param port Port if the socket
+ * @param hostname The hostname for the socket address
+ * @param port The port for the socket address
*
* @exception IllegalArgumentException If the port number is illegal
*/
@@ -114,49 +113,48 @@ public class InetSocketAddress extends SocketAddress
throws IllegalArgumentException
{
if (hostname == null)
- throw new IllegalArgumentException ("Null host name value");
-
+ throw new IllegalArgumentException("Null host name value");
+
if (port < 0 || port > 65535)
- throw new IllegalArgumentException ("Bad port number: " + port);
+ throw new IllegalArgumentException("Bad port number: " + port);
this.port = port;
this.hostname = hostname;
try
{
- this.addr = InetAddress.getByName(hostname);
+ this.addr = InetAddress.getByName(hostname);
}
catch (Exception e) // UnknownHostException, SecurityException
{
- this.addr = null;
+ this.addr = null;
}
}
-
- /**
+
+ /**
* Test if obj is a <code>InetSocketAddress</code> and
* has the same address and port
*
* @param obj The obj to compare this address with.
*
- * @return True if obj is equal.
+ * @return True if obj is equal.
*/
- public final boolean equals (Object obj)
+ public final boolean equals(Object obj)
{
// InetSocketAddress objects are equal when addr and port are equal.
// The hostname may differ.
-
if (obj instanceof InetSocketAddress)
{
- InetSocketAddress sa = (InetSocketAddress) obj;
-
- if (addr == null && sa.addr != null)
- return false;
- else if (addr == null && sa.addr == null)
- return hostname.equals (sa.hostname) && sa.port == port;
- else
- return addr.equals (sa.addr) && sa.port == port;
+ InetSocketAddress sa = (InetSocketAddress) obj;
+
+ if (addr == null && sa.addr != null)
+ return false;
+ else if (addr == null && sa.addr == null)
+ return hostname.equals(sa.hostname) && sa.port == port;
+ else
+ return addr.equals(sa.addr) && sa.port == port;
}
-
+
return false;
}
@@ -190,7 +188,7 @@ public class InetSocketAddress extends SocketAddress
{
return port;
}
-
+
/**
* Returns the hashcode of the <code>InetSocketAddress</code>
*
@@ -210,7 +208,7 @@ public class InetSocketAddress extends SocketAddress
{
return addr == null;
}
-
+
/**
* Returns the <code>InetSocketAddress</code> as string
*
diff --git a/libjava/java/net/JarURLConnection.java b/libjava/java/net/JarURLConnection.java
index 87d9db36f1c..96f214da8ac 100644
--- a/libjava/java/net/JarURLConnection.java
+++ b/libjava/java/net/JarURLConnection.java
@@ -7,7 +7,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -35,24 +35,24 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.net;
import java.io.IOException;
+import java.security.cert.Certificate;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
-import java.security.cert.Certificate;
+
/**
* This abstract class represents a common superclass for implementations
* of jar URL's. A jar URL is a special type of URL that allows JAR
* files on remote systems to be accessed. It has the form:
* <p>
- * jar:<standard URL pointing to jar file>!/file/within/jarfile
+ * jar:&lt;standard URL pointing to jar filei&gt;!/file/within/jarfile
* <p> for example:
* <p>
* jar:http://www.urbanophile.com/java/foo.jar!/com/urbanophile/bar.class
@@ -96,30 +96,29 @@ public abstract class JarURLConnection extends URLConnection
/**
* Creates a JarURLConnection from an URL object
*
- * @param URL url The URL object for this connection.
+ * @param url The URL object for this connection.
*
* @exception MalformedURLException If url is invalid
*
* @specnote This constructor is protected since JDK 1.4
*/
- protected JarURLConnection (URL url)
- throws MalformedURLException
+ protected JarURLConnection(URL url) throws MalformedURLException
{
- super (url);
+ super(url);
- if (!url.getProtocol().equals ("jar"))
- throw new MalformedURLException (url + ": Not jar protocol.");
+ if (! url.getProtocol().equals("jar"))
+ throw new MalformedURLException(url + ": Not jar protocol.");
String spec = url.getFile();
- int bang = spec.indexOf ("!/");
+ int bang = spec.indexOf("!/");
if (bang == -1)
- throw new MalformedURLException (url + ": No `!/' in spec.");
+ throw new MalformedURLException(url + ": No `!/' in spec.");
// Extract the url for the jar itself.
- jarFileURL = new URL (spec.substring (0, bang));
+ jarFileURL = new URL(spec.substring(0, bang));
// Get the name of the entry, if any.
- entryName = spec.length() == (bang + 2) ? null : spec.substring (bang + 2);
+ entryName = spec.length() == (bang + 2) ? null : spec.substring(bang + 2);
}
/**
@@ -128,7 +127,7 @@ public abstract class JarURLConnection extends URLConnection
*
* @return The remote URL
*/
- public URL getJarFileURL ()
+ public URL getJarFileURL()
{
return jarFileURL;
}
@@ -140,19 +139,19 @@ public abstract class JarURLConnection extends URLConnection
*
* @return The entry name.
*/
- public String getEntryName ()
+ public String getEntryName()
{
return entryName;
}
/**
- * Returns the entry in this jar file specified by the URL.
- *
+ * Returns the entry in this jar file specified by the URL.
+ *
* @return The jar entry
*
* @exception IOException If an error occurs
*/
- public JarEntry getJarEntry () throws IOException
+ public JarEntry getJarEntry() throws IOException
{
JarFile jarfile = null;
@@ -203,7 +202,7 @@ public abstract class JarURLConnection extends URLConnection
*
* @exception IOException If an error occurs
*/
- public abstract JarFile getJarFile () throws IOException;
+ public abstract JarFile getJarFile() throws IOException;
/**
* Returns an array of Certificate objects for the jar file entry specified
@@ -213,10 +212,10 @@ public abstract class JarURLConnection extends URLConnection
*
* @exception IOException If an error occurs
*/
- public Certificate[] getCertificates () throws IOException
+ public Certificate[] getCertificates() throws IOException
{
JarEntry entry = getJarEntry();
-
+
return entry != null ? entry.getCertificates() : null;
}
@@ -228,10 +227,10 @@ public abstract class JarURLConnection extends URLConnection
*
* @exception IOException If an error occurs
*/
- public Attributes getMainAttributes () throws IOException
+ public Attributes getMainAttributes() throws IOException
{
Manifest manifest = getManifest();
-
+
return manifest != null ? manifest.getMainAttributes() : null;
}
@@ -244,7 +243,7 @@ public abstract class JarURLConnection extends URLConnection
*
* @exception IOException If an error occurs
*/
- public Attributes getAttributes () throws IOException
+ public Attributes getAttributes() throws IOException
{
JarEntry entry = getJarEntry();
@@ -259,7 +258,7 @@ public abstract class JarURLConnection extends URLConnection
*
* @exception IOException If an error occurs
*/
- public Manifest getManifest () throws IOException
+ public Manifest getManifest() throws IOException
{
JarFile file = getJarFile();
diff --git a/libjava/java/net/MalformedURLException.java b/libjava/java/net/MalformedURLException.java
index 9cfae9aa5e5..c9a50fa8650 100644
--- a/libjava/java/net/MalformedURLException.java
+++ b/libjava/java/net/MalformedURLException.java
@@ -39,6 +39,7 @@ package java.net;
import java.io.IOException;
+
/**
* This exception indicates that a URL passed to an object was not in a
* valid format.
diff --git a/libjava/java/net/MulticastSocket.java b/libjava/java/net/MulticastSocket.java
index 28b76b365ee..c177531f22f 100644
--- a/libjava/java/net/MulticastSocket.java
+++ b/libjava/java/net/MulticastSocket.java
@@ -8,7 +8,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -41,21 +41,21 @@ package java.net;
import java.io.IOException;
import java.util.Enumeration;
+
/**
* Written using on-line Java Platform 1.2 API Specification, as well
* as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
* Status: Believed complete and correct.
*/
-
/**
* This class models a multicast UDP socket. A multicast address is a
- * class D internet address (one whose most significant bits are 1110).
+ * class D internet address (one whose most significant bits are 1110).
* A multicast group consists of a multicast address and a well known
* port number. All members of the group listening on that address and
* port will receive all the broadcasts to the group.
* <p>
- * Please note that applets are not allowed to use multicast sockets
- *
+ * Please note that applets are not allowed to use multicast sockets
+ *
* Written using on-line Java Platform 1.2 API Specification, as well
* as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
* Status: Believed complete and correct.
@@ -111,10 +111,10 @@ public class MulticastSocket extends DatagramSocket
if (address != null)
bind(address);
}
-
+
/**
* Returns the interface being used for multicast packets
- *
+ *
* @return The multicast interface
*
* @exception SocketException If an error occurs
@@ -131,7 +131,7 @@ public class MulticastSocket extends DatagramSocket
* Returns the current value of the "Time to Live" option. This is the
* number of hops a packet can make before it "expires". This method id
* deprecated. Use <code>getTimeToLive</code> instead.
- *
+ *
* @return The TTL value
*
* @exception IOException If an error occurs
@@ -153,8 +153,8 @@ public class MulticastSocket extends DatagramSocket
/**
* Returns the current value of the "Time to Live" option. This is the
- * number of hops a packet can make before it "expires".
- *
+ * number of hops a packet can make before it "expires".
+ *
* @return The TTL value
*
* @exception IOException If an error occurs
@@ -189,12 +189,12 @@ public class MulticastSocket extends DatagramSocket
/**
* Sets the local network interface used to send multicast messages
*
- * @param netIF The local network interface used to send multicast messages
- *
+ * @param netIf The local network interface used to send multicast messages
+ *
* @exception SocketException If an error occurs
- *
+ *
* @see MulticastSocket#getNetworkInterface()
- *
+ *
* @since 1.4
*/
public void setNetworkInterface(NetworkInterface netIf)
@@ -203,13 +203,13 @@ public class MulticastSocket extends DatagramSocket
if (isClosed())
throw new SocketException("socket is closed");
- Enumeration e = netIf.getInetAddresses ();
+ Enumeration e = netIf.getInetAddresses();
- if (!e.hasMoreElements ())
+ if (! e.hasMoreElements())
throw new SocketException("no network devices found");
- InetAddress address = (InetAddress) e.nextElement ();
- getImpl().setOption (SocketOptions.IP_MULTICAST_IF, address);
+ InetAddress address = (InetAddress) e.nextElement();
+ getImpl().setOption(SocketOptions.IP_MULTICAST_IF, address);
}
/**
@@ -220,18 +220,17 @@ public class MulticastSocket extends DatagramSocket
* @exception SocketException If an error occurs
*
* @see MulticastSocket#setNetworkInterface(NetworkInterface netIf)
- *
+ *
* @since 1.4
*/
- public NetworkInterface getNetworkInterface()
- throws SocketException
+ public NetworkInterface getNetworkInterface() throws SocketException
{
if (isClosed())
throw new SocketException("socket is closed");
InetAddress address =
- (InetAddress) getImpl().getOption (SocketOptions.IP_MULTICAST_IF);
- NetworkInterface netIf = NetworkInterface.getByInetAddress (address);
+ (InetAddress) getImpl().getOption(SocketOptions.IP_MULTICAST_IF);
+ NetworkInterface netIf = NetworkInterface.getByInetAddress(address);
return netIf;
}
@@ -239,7 +238,7 @@ public class MulticastSocket extends DatagramSocket
/**
* Disable/Enable local loopback of multicast packets. The option is used by
* the platform's networking code as a hint for setting whether multicast
- * data will be looped back to the local socket.
+ * data will be looped back to the local socket.
*
* Because this option is a hint, applications that want to verify what
* loopback mode is set to should call #getLoopbackMode
@@ -255,12 +254,15 @@ public class MulticastSocket extends DatagramSocket
if (isClosed())
throw new SocketException("socket is closed");
- getImpl().setOption (SocketOptions.IP_MULTICAST_LOOP, Boolean.valueOf(disable));
+ getImpl().setOption(SocketOptions.IP_MULTICAST_LOOP,
+ Boolean.valueOf(disable));
}
/**
- * Checks if local loopback mode is enabled or not
+ * Checks if local loopback mode is enabled
*
+ * @return true if loopback mode is enabled, false otherwise
+ *
* @exception SocketException If an error occurs
*
* @since 1.4
@@ -270,11 +272,11 @@ public class MulticastSocket extends DatagramSocket
if (isClosed())
throw new SocketException("socket is closed");
- Object buf = getImpl().getOption (SocketOptions.IP_MULTICAST_LOOP);
+ Object buf = getImpl().getOption(SocketOptions.IP_MULTICAST_LOOP);
if (buf instanceof Boolean)
return ((Boolean) buf).booleanValue();
-
+
throw new SocketException("unexpected type");
}
@@ -303,12 +305,12 @@ public class MulticastSocket extends DatagramSocket
/**
* Sets the "Time to Live" value for a socket. The value must be between
- * 1 and 255.
+ * 1 and 255.
*
* @param ttl The new TTL value
*
* @exception IOException If an error occurs
- *
+ *
* @since 1.2
*/
public void setTimeToLive(int ttl) throws IOException
@@ -323,10 +325,10 @@ public class MulticastSocket extends DatagramSocket
}
/**
- * Joins the specified mulitcast group.
+ * Joins the specified multicast group.
+ *
+ * @param mcastaddr The address of the group to join
*
- * @param addr The address of the group to join
- *
* @exception IOException If an error occurs
* @exception SecurityException If a security manager exists and its
* checkMulticast method doesn't allow the operation
@@ -349,7 +351,7 @@ public class MulticastSocket extends DatagramSocket
/**
* Leaves the specified multicast group
*
- * @param addr The address of the group to leave
+ * @param mcastaddr The address of the group to leave
*
* @exception IOException If an error occurs
* @exception SecurityException If a security manager exists and its
@@ -377,7 +379,7 @@ public class MulticastSocket extends DatagramSocket
* @param netIf The local network interface to receive the multicast
* messages on or null to defer the interface set by #setInterface or
* #setNetworkInterface
- *
+ *
* @exception IOException If an error occurs
* @exception IllegalArgumentException If address type is not supported
* @exception SecurityException If a security manager exists and its
@@ -395,26 +397,26 @@ public class MulticastSocket extends DatagramSocket
throw new SocketException("socket is closed");
if (! (mcastaddr instanceof InetSocketAddress))
- throw new IllegalArgumentException ("SocketAddress type not supported");
+ throw new IllegalArgumentException("SocketAddress type not supported");
InetSocketAddress tmp = (InetSocketAddress) mcastaddr;
-
- if (! tmp.getAddress ().isMulticastAddress ())
- throw new IOException ("Not a Multicast address");
- SecurityManager s = System.getSecurityManager ();
+ if (! tmp.getAddress().isMulticastAddress())
+ throw new IOException("Not a Multicast address");
+
+ SecurityManager s = System.getSecurityManager();
if (s != null)
- s.checkMulticast (tmp.getAddress ());
+ s.checkMulticast(tmp.getAddress());
- getImpl().joinGroup (mcastaddr, netIf);
+ getImpl().joinGroup(mcastaddr, netIf);
}
-
+
/**
* Leaves the specified mulitcast group on a specified interface.
*
* @param mcastaddr The multicast address to leave
* @param netIf The local networki interface or null to defer to the
- * interface set by setInterface or setNetworkInterface
+ * interface set by setInterface or setNetworkInterface
*
* @exception IOException If an error occurs
* @exception IllegalArgumentException If address type is not supported
@@ -433,17 +435,17 @@ public class MulticastSocket extends DatagramSocket
throw new SocketException("socket is closed");
InetSocketAddress tmp = (InetSocketAddress) mcastaddr;
-
- if (! tmp.getAddress ().isMulticastAddress ())
- throw new IOException ("Not a Multicast address");
- SecurityManager s = System.getSecurityManager ();
+ if (! tmp.getAddress().isMulticastAddress())
+ throw new IOException("Not a Multicast address");
+
+ SecurityManager s = System.getSecurityManager();
if (s != null)
- s.checkMulticast (tmp.getAddress ());
+ s.checkMulticast(tmp.getAddress());
- getImpl().leaveGroup (mcastaddr, netIf);
+ getImpl().leaveGroup(mcastaddr, netIf);
}
-
+
/**
* Sends a packet of data to a multicast address with a TTL that is
* different from the default TTL on this socket. The default TTL for
@@ -458,7 +460,8 @@ public class MulticastSocket extends DatagramSocket
*
* @deprecated
*/
- public synchronized void send(DatagramPacket p, byte ttl) throws IOException
+ public synchronized void send(DatagramPacket packet, byte ttl)
+ throws IOException
{
if (isClosed())
throw new SocketException("socket is closed");
@@ -466,18 +469,18 @@ public class MulticastSocket extends DatagramSocket
SecurityManager s = System.getSecurityManager();
if (s != null)
{
- InetAddress addr = p.getAddress();
- if (addr.isMulticastAddress())
- s.checkPermission (new SocketPermission
- (addr.getHostName () + p.getPort (),
- "accept,connect"));
- else
- s.checkConnect(addr.getHostAddress(), p.getPort());
+ InetAddress addr = packet.getAddress();
+ if (addr.isMulticastAddress())
+ s.checkPermission(new SocketPermission(addr.getHostName()
+ + packet.getPort(),
+ "accept,connect"));
+ else
+ s.checkConnect(addr.getHostAddress(), packet.getPort());
}
int oldttl = getImpl().getTimeToLive();
getImpl().setTimeToLive(((int) ttl) & 0xFF);
- getImpl().send(p);
+ getImpl().send(packet);
getImpl().setTimeToLive(oldttl);
}
-} // class MulticastSocket
+}
diff --git a/libjava/java/net/NetPermission.java b/libjava/java/net/NetPermission.java
index 6b796be7f04..38a15c48ab7 100644
--- a/libjava/java/net/NetPermission.java
+++ b/libjava/java/net/NetPermission.java
@@ -39,22 +39,23 @@ package java.net;
import java.security.BasicPermission;
+
/**
* This class is used to model miscellaneous network permissions. It is
- * a subclass of <code>BasicPermission</code>. This means that it models a
- * "boolean" permission. One that you either have or do not have. Thus
- * there is no permitted action list associated with this object.
+ * a subclass of <code>BasicPermission</code>. This means that it models a
+ * "boolean" permission. One that you either have or do not have. Thus
+ * there is no permitted action list associated with this object.
*
* The following permission names are defined for this class:
- *
+ *
* <ul>
* <li>setDefaultAuthenticator - Grants the ability to install a facility
- * to collect username and password information when requested by a
- * web site or proxy server.
+ * to collect username and password information when requested by a
+ * web site or proxy server.</li>
* <li>requestPasswordAuthentication - Grants the ability to ask the
- * authentication facility for the user's password.
- * <li>specifyStreamHandler - Grants the permission to specify the
- * stream handler class used when loading from a URL.
+ * authentication facility for the user's password.</li>
+ * <li>specifyStreamHandler - Grants the permission to specify the
+ * stream handler class used when loading from a URL.</li>
* </ul>
*
* @author Aaron M. Renn (arenn@urbanophile.com)
@@ -75,8 +76,8 @@ public final class NetPermission extends BasicPermission
}
/**
- * Initializes a new instance of <code>NetPermission</code> with the
- * specified name and perms. Note that the perms field is irrelevant and is
+ * Initializes a new instance of <code>NetPermission</code> with the
+ * specified name and perms. Note that the perms field is irrelevant and is
* ignored. This constructor should never need to be used.
*
* @param name The name of this permission
diff --git a/libjava/java/net/NetworkInterface.java b/libjava/java/net/NetworkInterface.java
index f6d37489836..ab6d7b4263f 100644
--- a/libjava/java/net/NetworkInterface.java
+++ b/libjava/java/net/NetworkInterface.java
@@ -7,7 +7,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -41,6 +41,7 @@ import gnu.classpath.Configuration;
import java.util.Enumeration;
import java.util.Vector;
+
/**
* This class models a network interface on the host computer. A network
* interface contains a name (typically associated with a specific
@@ -54,25 +55,22 @@ import java.util.Vector;
public final class NetworkInterface
{
static
- {
- if (Configuration.INIT_LOAD_LIBRARY)
- {
- System.loadLibrary ("javanet");
- }
- }
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ System.loadLibrary("javanet");
+ }
private String name;
-
private Vector inetAddresses;
- private NetworkInterface (String name, InetAddress address)
+ private NetworkInterface(String name, InetAddress address)
{
this.name = name;
- this.inetAddresses = new Vector (1, 1);
- this.inetAddresses.add (address);
+ this.inetAddresses = new Vector(1, 1);
+ this.inetAddresses.add(address);
}
- private native static Vector getRealNetworkInterfaces ()
+ private static native Vector getRealNetworkInterfaces()
throws SocketException;
/**
@@ -80,45 +78,45 @@ public final class NetworkInterface
*
* @return The name of the interface.
*/
- public String getName ()
+ public String getName()
{
return name;
}
/**
* Returns all available addresses of the network interface
- *
+ *
* If a @see SecurityManager is available all addresses are checked
* with @see SecurityManager::checkConnect() if they are available.
- * Only <code>InetAddresses</code> are returned where the security manager
+ * Only <code>InetAddresses</code> are returned where the security manager
* doesn't throw an exception.
- *
+ *
* @return An enumeration of all addresses.
*/
- public Enumeration getInetAddresses ()
+ public Enumeration getInetAddresses()
{
- SecurityManager s = System.getSecurityManager ();
+ SecurityManager s = System.getSecurityManager();
if (s == null)
- return inetAddresses.elements ();
+ return inetAddresses.elements();
- Vector tmpInetAddresses = new Vector (1, 1);
+ Vector tmpInetAddresses = new Vector(1, 1);
- for (Enumeration addresses = inetAddresses.elements ();
- addresses.hasMoreElements (); )
+ for (Enumeration addresses = inetAddresses.elements();
+ addresses.hasMoreElements();)
{
- InetAddress addr = (InetAddress) addresses.nextElement ();
+ InetAddress addr = (InetAddress) addresses.nextElement();
try
{
- s.checkConnect (addr.getHostAddress (), 58000);
- tmpInetAddresses.add (addr);
+ s.checkConnect(addr.getHostAddress(), 58000);
+ tmpInetAddresses.add(addr);
}
catch (SecurityException e)
{
}
- }
+ }
- return tmpInetAddresses.elements ();
+ return tmpInetAddresses.elements();
}
/**
@@ -126,34 +124,37 @@ public final class NetworkInterface
*
* @return The display name of the interface
*/
- public String getDisplayName ()
+ public String getDisplayName()
{
return name;
}
/**
- * Returns an network interface by name
+ * Returns an network interface by name
*
- * @param name The name of the interface to return
+ * @param name The name of the interface to return
+ *
+ * @return a <code>NetworkInterface</code> object representing the interface,
+ * or null if there is no interface with that name.
*
- * @exception SocketException If an error occurs
- * @exception NullPointerException If the specified name is null
+ * @exception SocketException If an error occurs
+ * @exception NullPointerException If the specified name is null
*/
- public static NetworkInterface getByName (String name)
+ public static NetworkInterface getByName(String name)
throws SocketException
{
- Vector networkInterfaces = getRealNetworkInterfaces ();
+ Vector networkInterfaces = getRealNetworkInterfaces();
- for (Enumeration e = networkInterfaces.elements ();
- e.hasMoreElements (); )
+ for (Enumeration e = networkInterfaces.elements(); e.hasMoreElements();)
{
- NetworkInterface tmp = (NetworkInterface) e.nextElement ();
-
- if (name.equals (tmp.getName ()))
- return tmp;
+ NetworkInterface tmp = (NetworkInterface) e.nextElement();
+
+ if (name.equals(tmp.getName()))
+ return tmp;
}
- throw new SocketException ("no network interface with this name exists");
+ // No interface with the given name found.
+ return null;
}
/**
@@ -164,26 +165,25 @@ public final class NetworkInterface
* @exception SocketException If an error occurs
* @exception NullPointerException If the specified addess is null
*/
- public static NetworkInterface getByInetAddress (InetAddress addr)
+ public static NetworkInterface getByInetAddress(InetAddress addr)
throws SocketException
{
- Vector networkInterfaces = getRealNetworkInterfaces ();
-
- for (Enumeration interfaces = networkInterfaces.elements ();
- interfaces.hasMoreElements (); )
+ Vector networkInterfaces = getRealNetworkInterfaces();
+
+ for (Enumeration interfaces = networkInterfaces.elements();
+ interfaces.hasMoreElements();)
{
- NetworkInterface tmp = (NetworkInterface) interfaces.nextElement ();
-
- for (Enumeration addresses = tmp.inetAddresses.elements ();
- addresses.hasMoreElements (); )
- {
- if (addr.equals ((InetAddress) addresses.nextElement ()))
- return tmp;
- }
+ NetworkInterface tmp = (NetworkInterface) interfaces.nextElement();
+
+ for (Enumeration addresses = tmp.inetAddresses.elements();
+ addresses.hasMoreElements();)
+ {
+ if (addr.equals((InetAddress) addresses.nextElement()))
+ return tmp;
+ }
}
- throw new SocketException (
- "no network interface is bound to such an IP address");
+ throw new SocketException("no network interface is bound to such an IP address");
}
/**
@@ -191,8 +191,7 @@ public final class NetworkInterface
*
* @exception SocketException If an error occurs
*/
- public static Enumeration getNetworkInterfaces ()
- throws SocketException
+ public static Enumeration getNetworkInterfaces() throws SocketException
{
Vector networkInterfaces = getRealNetworkInterfaces();
@@ -206,44 +205,43 @@ public final class NetworkInterface
* Checks if the current instance is equal to obj
*
* @param obj The object to compare with
- */
- public boolean equals (Object obj)
+ */
+ public boolean equals(Object obj)
{
- if (!(obj instanceof NetworkInterface))
+ if (! (obj instanceof NetworkInterface))
return false;
-
+
NetworkInterface tmp = (NetworkInterface) obj;
- return (name.equals (tmp.name)
- && inetAddresses.equals (tmp.inetAddresses));
+ return (name.equals(tmp.name) && inetAddresses.equals(tmp.inetAddresses));
}
/**
* Returns the hashcode of the current instance
*/
- public int hashCode ()
+ public int hashCode()
{
// FIXME: hash correctly
- return name.hashCode () + inetAddresses.hashCode ();
+ return name.hashCode() + inetAddresses.hashCode();
}
/**
* Returns a string representation of the interface
*/
- public String toString ()
+ public String toString()
{
// FIXME: check if this is correct
String result;
- String separator = System.getProperty ("line.separator");
+ String separator = System.getProperty("line.separator");
- result = "name: " + getDisplayName () + " (" + getName () +
- ") addresses:" + separator;
+ result =
+ "name: " + getDisplayName() + " (" + getName() + ") addresses:"
+ + separator;
- for (Enumeration e = inetAddresses.elements ();
- e.hasMoreElements (); )
+ for (Enumeration e = inetAddresses.elements(); e.hasMoreElements();)
{
- InetAddress address = (InetAddress) e.nextElement ();
- result += address.toString () + ";" + separator;
+ InetAddress address = (InetAddress) e.nextElement();
+ result += address.toString() + ";" + separator;
}
return result;
diff --git a/libjava/java/net/NoRouteToHostException.java b/libjava/java/net/NoRouteToHostException.java
index 2f7fb7276d7..d1338938659 100644
--- a/libjava/java/net/NoRouteToHostException.java
+++ b/libjava/java/net/NoRouteToHostException.java
@@ -35,9 +35,9 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.net;
+
/**
* This exception indicates that there is no TCP/IP route to the requested
* host. This is often due to a misconfigured routing table.
diff --git a/libjava/java/net/PasswordAuthentication.java b/libjava/java/net/PasswordAuthentication.java
index 97554e3dde4..910803a8f3a 100644
--- a/libjava/java/net/PasswordAuthentication.java
+++ b/libjava/java/net/PasswordAuthentication.java
@@ -7,7 +7,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -37,6 +37,7 @@ exception statement from your version. */
package java.net;
+
/**
* This class serves a container for username/password pairs.
*
@@ -50,7 +51,7 @@ public final class PasswordAuthentication
*/
/**
- * The username
+ * The username
*/
private String username;
@@ -66,7 +67,7 @@ public final class PasswordAuthentication
*/
/**
- * Creates a new <code>PasswordAuthentication</code> object from the
+ * Creates a new <code>PasswordAuthentication</code> object from the
* specified username and password.
*
* @param username The username for this object
@@ -91,9 +92,9 @@ public final class PasswordAuthentication
*/
public String getUserName()
{
- return(username);
+ return (username);
}
-
+
/**
* Returns the password associated with this object
*
@@ -101,8 +102,6 @@ public final class PasswordAuthentication
*/
public char[] getPassword()
{
- return(password);
+ return (password);
}
-
} // class PasswordAuthentication
-
diff --git a/libjava/java/net/PortUnreachableException.java b/libjava/java/net/PortUnreachableException.java
index b6abfe95a92..def02636e58 100644
--- a/libjava/java/net/PortUnreachableException.java
+++ b/libjava/java/net/PortUnreachableException.java
@@ -37,6 +37,7 @@ exception statement from your version. */
package java.net;
+
/**
* This exception signals that an ICMP port unreachable datagram has been
* received.
@@ -69,4 +70,3 @@ public class PortUnreachableException extends SocketException
super(message);
}
} // class PortUnreachableException
-
diff --git a/libjava/java/net/ProtocolException.java b/libjava/java/net/ProtocolException.java
index c50bbcf6e8f..d058113495e 100644
--- a/libjava/java/net/ProtocolException.java
+++ b/libjava/java/net/ProtocolException.java
@@ -39,6 +39,7 @@ package java.net;
import java.io.IOException;
+
/**
* This exception indicates that some sort of low level protocol
* exception occurred. Look in the descriptive message (if any) for
diff --git a/libjava/java/net/ServerSocket.java b/libjava/java/net/ServerSocket.java
index be3f8008d86..e507f0b3b09 100644
--- a/libjava/java/net/ServerSocket.java
+++ b/libjava/java/net/ServerSocket.java
@@ -8,7 +8,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -36,7 +36,6 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.net;
import gnu.java.net.PlainSocketImpl;
@@ -44,6 +43,7 @@ import java.io.IOException;
import java.nio.channels.IllegalBlockingModeException;
import java.nio.channels.ServerSocketChannel;
+
/* Written using on-line Java Platform 1.2 API Specification.
* Status: I believe all methods are implemented.
*/
@@ -55,7 +55,7 @@ import java.nio.channels.ServerSocketChannel;
* server sockets are ready to communicate with one another utilizing
* whatever application layer protocol they desire.
*
- * As with the <code>Socket</code> class, most instance methods of this class
+ * As with the <code>Socket</code> class, most instance methods of this class
* simply redirect their calls to an implementation class.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
@@ -78,34 +78,36 @@ public class ServerSocket
* True if socket is bound.
*/
private boolean bound;
-
+
/*
* This constructor is only used by java.nio.
*/
+
// FIXME: Workaround a bug in gcj.
//ServerSocket (PlainSocketImpl impl) throws IOException
- ServerSocket (SocketImpl impl) throws IOException
+ ServerSocket(SocketImpl impl) throws IOException
{
if (impl == null)
throw new NullPointerException("impl may not be null");
this.impl = impl;
- this.impl.create (true);
+ this.impl.create(true);
}
/*
* This method is only used by java.nio.
*/
+
// FIXME: Workaround a bug in gcj.
//PlainSocketImpl getImpl()
SocketImpl getImpl()
{
return impl;
}
-
+
/**
* Constructor that simply sets the implementation.
- *
+ *
* @exception IOException If an error occurs
*
* @specnote This constructor is public since JDK 1.4
@@ -126,13 +128,12 @@ public class ServerSocket
* connection queue on this socket will be set to 50.
*
* @param port The port number to bind to
- *
+ *
* @exception IOException If an error occurs
* @exception SecurityException If a security manager exists and its
* checkListen method doesn't allow the operation
*/
- public ServerSocket (int port)
- throws IOException
+ public ServerSocket(int port) throws IOException
{
this(port, 50);
}
@@ -150,8 +151,7 @@ public class ServerSocket
* @exception SecurityException If a security manager exists and its
* checkListen method doesn't allow the operation
*/
- public ServerSocket (int port, int backlog)
- throws IOException
+ public ServerSocket(int port, int backlog) throws IOException
{
this(port, backlog, null);
}
@@ -173,13 +173,13 @@ public class ServerSocket
*
* @since 1.1
*/
- public ServerSocket (int port, int backlog, InetAddress bindAddr)
+ public ServerSocket(int port, int backlog, InetAddress bindAddr)
throws IOException
{
this();
// bind/listen socket
- bind (new InetSocketAddress (bindAddr, port), backlog);
+ bind(new InetSocketAddress(bindAddr, port), backlog);
}
/**
@@ -191,21 +191,20 @@ public class ServerSocket
* @exception IllegalArgumentException If address type is not supported
* @exception SecurityException If a security manager exists and its
* checkListen method doesn't allow the operation
- *
+ *
* @since 1.4
*/
- public void bind (SocketAddress endpoint)
- throws IOException
+ public void bind(SocketAddress endpoint) throws IOException
{
- bind (endpoint, 50);
+ bind(endpoint, 50);
}
-
+
/**
* Binds the server socket to a specified socket address
*
* @param endpoint The socket address to bind to
* @param backlog The length of the pending connection queue
- *
+ *
* @exception IOException If an error occurs
* @exception IllegalArgumentException If address type is not supported
* @exception SecurityException If a security manager exists and its
@@ -213,26 +212,27 @@ public class ServerSocket
*
* @since 1.4
*/
- public void bind (SocketAddress endpoint, int backlog) throws IOException
+ public void bind(SocketAddress endpoint, int backlog)
+ throws IOException
{
if (isClosed())
throw new SocketException("ServerSocket is closed");
-
+
if (! (endpoint instanceof InetSocketAddress))
- throw new IllegalArgumentException ("Address type not supported");
+ throw new IllegalArgumentException("Address type not supported");
InetSocketAddress tmp = (InetSocketAddress) endpoint;
- SecurityManager s = System.getSecurityManager ();
+ SecurityManager s = System.getSecurityManager();
if (s != null)
- s.checkListen (tmp.getPort ());
+ s.checkListen(tmp.getPort());
InetAddress addr = tmp.getAddress();
-
+
// Initialize addr with 0.0.0.0.
if (addr == null)
addr = InetAddress.ANY_IF;
-
+
try
{
impl.bind(addr, tmp.getPort());
@@ -241,21 +241,21 @@ public class ServerSocket
}
catch (IOException exception)
{
- close();
- throw exception;
+ close();
+ throw exception;
}
catch (RuntimeException exception)
{
- close();
- throw exception;
+ close();
+ throw exception;
}
catch (Error error)
{
- close();
- throw error;
+ close();
+ throw error;
}
}
-
+
/**
* This method returns the local address to which this socket is bound
*
@@ -263,17 +263,17 @@ public class ServerSocket
*/
public InetAddress getInetAddress()
{
- if (!isBound())
+ if (! isBound())
return null;
-
+
try
{
- return (InetAddress) impl.getOption (SocketOptions.SO_BINDADDR);
+ return (InetAddress) impl.getOption(SocketOptions.SO_BINDADDR);
}
catch (SocketException e)
{
- // This never happens as we are bound.
- return null;
+ // This never happens as we are bound.
+ return null;
}
}
@@ -284,30 +284,34 @@ public class ServerSocket
*/
public int getLocalPort()
{
- if (!isBound())
+ if (! isBound())
return -1;
-
+
return impl.getLocalPort();
}
/**
* Returns the local socket address
*
+ * @return the local socket address, null if not bound
+ *
* @since 1.4
*/
public SocketAddress getLocalSocketAddress()
{
- if (!isBound())
+ if (! isBound())
return null;
-
+
return new InetSocketAddress(getInetAddress(), getLocalPort());
}
/**
- * Accepts a new connection and returns a connected <code>Socket</code>
- * instance representing that connection. This method will block until a
+ * Accepts a new connection and returns a connected <code>Socket</code>
+ * instance representing that connection. This method will block until a
* connection is available.
*
+ * @return socket object for the just accepted connection
+ *
* @exception IOException If an error occurs
* @exception SecurityException If a security manager exists and its
* checkListen method doesn't allow the operation
@@ -316,17 +320,17 @@ public class ServerSocket
* @exception SocketTimeoutException If a timeout was previously set with
* setSoTimeout and the timeout has been reached
*/
- public Socket accept () throws IOException
+ public Socket accept() throws IOException
{
- SecurityManager sm = System.getSecurityManager ();
+ SecurityManager sm = System.getSecurityManager();
if (sm != null)
- sm.checkListen (impl.getLocalPort ());
+ sm.checkListen(impl.getLocalPort());
Socket socket = new Socket();
-
+
try
{
- implAccept(socket);
+ implAccept(socket);
}
catch (IOException e)
{
@@ -337,15 +341,15 @@ public class ServerSocket
catch (IOException e2)
{
}
-
+
throw e;
}
-
+
return socket;
}
/**
- * This protected method is used to help subclasses override
+ * This protected method is used to help subclasses override
* <code>ServerSocket.accept()</code>. The passed in socket will be
* connected when this method returns.
*
@@ -357,22 +361,21 @@ public class ServerSocket
*
* @since 1.1
*/
- protected final void implAccept (Socket socket)
- throws IOException
+ protected final void implAccept(Socket socket) throws IOException
{
if (isClosed())
throw new SocketException("ServerSocket is closed");
-
+
// The Sun spec says that if we have an associated channel and
// it is in non-blocking mode, we throw an IllegalBlockingModeException.
// However, in our implementation if the channel itself initiated this
// operation, then we must honor it regardless of its blocking mode.
- if (getChannel() != null
- && !getChannel().isBlocking ()
- && !((PlainSocketImpl) getImpl()).isInChannelOperation())
- throw new IllegalBlockingModeException ();
-
- impl.accept(socket.getImpl());
+ if (getChannel() != null && ! getChannel().isBlocking()
+ && ! ((PlainSocketImpl) getImpl()).isInChannelOperation())
+ throw new IllegalBlockingModeException();
+
+ impl.accept(socket.impl);
+ socket.implCreated = true;
}
/**
@@ -380,11 +383,11 @@ public class ServerSocket
*
* @exception IOException If an error occurs
*/
- public void close () throws IOException
+ public void close() throws IOException
{
if (isClosed())
return;
-
+
impl.close();
impl = null;
bound = false;
@@ -399,6 +402,8 @@ public class ServerSocket
*
* The socket only has a ServerSocketChannel if its created
* by ServerSocketChannel.open.
+ *
+ * @return the associated socket channel, null if none exists
*
* @since 1.4
*/
@@ -409,6 +414,8 @@ public class ServerSocket
/**
* Returns true when the socket is bound, otherwise false
+ *
+ * @return true if socket is bound, false otherwise
*
* @since 1.4
*/
@@ -419,6 +426,8 @@ public class ServerSocket
/**
* Returns true if the socket is closed, otherwise false
+ *
+ * @return true if socket is closed, false otherwise
*
* @since 1.4
*/
@@ -429,7 +438,7 @@ public class ServerSocket
/**
* Sets the value of SO_TIMEOUT. A value of 0 implies that SO_TIMEOUT is
- * disabled (ie, operations never time out). This is the number of
+ * disabled (ie, operations never time out). This is the number of
* milliseconds a socket operation can block before an
* InterruptedIOException is thrown.
*
@@ -439,11 +448,11 @@ public class ServerSocket
*
* @since 1.1
*/
- public void setSoTimeout (int timeout) throws SocketException
+ public void setSoTimeout(int timeout) throws SocketException
{
if (isClosed())
throw new SocketException("ServerSocket is closed");
-
+
if (timeout < 0)
throw new IllegalArgumentException("SO_TIMEOUT value must be >= 0");
@@ -462,135 +471,135 @@ public class ServerSocket
*
* @since 1.1
*/
- public int getSoTimeout () throws IOException
+ public int getSoTimeout() throws IOException
{
if (isClosed())
throw new SocketException("ServerSocket is closed");
-
+
Object timeout = impl.getOption(SocketOptions.SO_TIMEOUT);
- if (!(timeout instanceof Integer))
+ if (! (timeout instanceof Integer))
throw new IOException("Internal Error");
- return ((Integer)timeout).intValue();
+ return ((Integer) timeout).intValue();
}
/**
* Enables/Disables the SO_REUSEADDR option
+ *
+ * @param on true if SO_REUSEADDR should be enabled, false otherwise
*
* @exception SocketException If an error occurs
- *
+ *
* @since 1.4
*/
- public void setReuseAddress (boolean on)
- throws SocketException
+ public void setReuseAddress(boolean on) throws SocketException
{
if (isClosed())
throw new SocketException("ServerSocket is closed");
-
- impl.setOption (SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
+
+ impl.setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
}
/**
* Checks if the SO_REUSEADDR option is enabled
- *
+ *
+ * @return true if SO_REUSEADDR is set, false otherwise
+ *
* @exception SocketException If an error occurs
- *
+ *
* @since 1.4
*/
- public boolean getReuseAddress()
- throws SocketException
+ public boolean getReuseAddress() throws SocketException
{
if (isClosed())
throw new SocketException("ServerSocket is closed");
-
- Object reuseaddr = impl.getOption (SocketOptions.SO_REUSEADDR);
- if (!(reuseaddr instanceof Boolean))
- throw new SocketException ("Internal Error");
-
- return ((Boolean) reuseaddr).booleanValue ();
+ Object reuseaddr = impl.getOption(SocketOptions.SO_REUSEADDR);
+
+ if (! (reuseaddr instanceof Boolean))
+ throw new SocketException("Internal Error");
+
+ return ((Boolean) reuseaddr).booleanValue();
}
/**
* This method sets the value for the system level socket option
* SO_RCVBUF to the specified value. Note that valid values for this
* option are specific to a given operating system.
- *
+ *
* @param size The new receive buffer size.
- *
+ *
* @exception SocketException If an error occurs or Socket is not connected
* @exception IllegalArgumentException If size is 0 or negative
*
* @since 1.4
*/
- public void setReceiveBufferSize (int size)
- throws SocketException
+ public void setReceiveBufferSize(int size) throws SocketException
{
if (isClosed())
throw new SocketException("ServerSocket is closed");
-
+
if (size <= 0)
- throw new IllegalArgumentException ("SO_RCVBUF value must be > 0");
+ throw new IllegalArgumentException("SO_RCVBUF value must be > 0");
- impl.setOption (SocketOptions.SO_RCVBUF, new Integer (size));
+ impl.setOption(SocketOptions.SO_RCVBUF, new Integer(size));
}
/**
* This method returns the value of the system level socket option
* SO_RCVBUF, which is used by the operating system to tune buffer
* sizes for data transfers.
- *
+ *
* @return The receive buffer size.
- *
+ *
* @exception SocketException If an error occurs or Socket is not connected
- *
+ *
* @since 1.4
*/
- public int getReceiveBufferSize ()
- throws SocketException
+ public int getReceiveBufferSize() throws SocketException
{
if (isClosed())
throw new SocketException("ServerSocket is closed");
-
- Object buf = impl.getOption (SocketOptions.SO_RCVBUF);
- if (!(buf instanceof Integer))
- throw new SocketException ("Internal Error: Unexpected type");
-
- return ((Integer) buf).intValue ();
+ Object buf = impl.getOption(SocketOptions.SO_RCVBUF);
+
+ if (! (buf instanceof Integer))
+ throw new SocketException("Internal Error: Unexpected type");
+
+ return ((Integer) buf).intValue();
}
/**
- * Returns the value of this socket as a <code>String</code>.
+ * Returns the value of this socket as a <code>String</code>.
*
* @return This socket represented as a <code>String</code>.
*/
- public String toString ()
+ public String toString()
{
- if (!isBound())
+ if (! isBound())
return "ServerSocket[unbound]";
-
- return ("ServerSocket[addr=" + getInetAddress()
- + ",port=" + impl.getPort()
- + ",localport=" + impl.getLocalPort()
- + "]");
+
+ return ("ServerSocket[addr=" + getInetAddress() + ",port="
+ + impl.getPort() + ",localport=" + impl.getLocalPort() + "]");
}
/**
- * Sets the <code>SocketImplFactory</code> for all
+ * Sets the <code>SocketImplFactory</code> for all
* <code>ServerSocket</code>'s. This may only be done
* once per virtual machine. Subsequent attempts will generate an
* exception. Note that a <code>SecurityManager</code> check is made prior
* to setting the factory. If insufficient privileges exist to set the
* factory, an exception will be thrown
*
+ * @param fac the factory to set
+ *
* @exception SecurityException If this operation is not allowed by the
* <code>SecurityManager</code>.
* @exception SocketException If the factory object is already defined
* @exception IOException If any other error occurs
*/
- public static synchronized void setSocketFactory (SocketImplFactory fac)
+ public static synchronized void setSocketFactory(SocketImplFactory fac)
throws IOException
{
factory = fac;
diff --git a/libjava/java/net/Socket.java b/libjava/java/net/Socket.java
index 4c14e8d99b3..43c6f3c3d50 100644
--- a/libjava/java/net/Socket.java
+++ b/libjava/java/net/Socket.java
@@ -8,7 +8,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -36,15 +36,15 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.net;
import gnu.java.net.PlainSocketImpl;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
-import java.nio.channels.SocketChannel;
import java.nio.channels.IllegalBlockingModeException;
+import java.nio.channels.SocketChannel;
+
/* Written using on-line Java Platform 1.2 API Specification.
* Status: I believe all methods are implemented.
@@ -56,11 +56,11 @@ import java.nio.channels.IllegalBlockingModeException;
* <p>
* This class does not actually do any work. Instead, it redirects all of
* its calls to a socket implementation object which implements the
- * <code>SocketImpl</code> interface. The implementation class is
- * instantiated by factory class that implements the
+ * <code>SocketImpl</code> interface. The implementation class is
+ * instantiated by factory class that implements the
* <code>SocketImplFactory interface</code>. A default
* factory is provided, however the factory may be set by a call to
- * the <code>setSocketImplFactory</code> method. Note that this may only be
+ * the <code>setSocketImplFactory</code> method. Note that this may only be
* done once per virtual machine. If a subsequent attempt is made to set the
* factory, a <code>SocketException</code> will be thrown.
*
@@ -78,12 +78,15 @@ public class Socket
/**
* The implementation object to which calls are redirected
*/
- private SocketImpl impl;
+ // package-private because ServerSocket.implAccept() needs to access it.
+ SocketImpl impl;
/**
- * True if socket implementation was created by calling their create() method.
+ * True if socket implementation was created by calling their
+ * create() method.
*/
- private boolean implCreated;
+ // package-private because ServerSocket.implAccept() needs to access it.
+ boolean implCreated;
/**
* True if the socket is bound.
@@ -101,14 +104,14 @@ public class Socket
private boolean outputShutdown;
/**
- * Initializes a new instance of <code>Socket</code> object without
- * connecting to a remote host. This useful for subclasses of socket that
+ * Initializes a new instance of <code>Socket</code> object without
+ * connecting to a remote host. This useful for subclasses of socket that
* might want this behavior.
*
* @specnote This constructor is public since JDK 1.4
* @since 1.1
*/
- public Socket ()
+ public Socket()
{
if (factory != null)
impl = factory.createSocketImpl();
@@ -119,7 +122,7 @@ public class Socket
/**
* Initializes a new instance of <code>Socket</code> object without
* connecting to a remote host. This is useful for subclasses of socket
- * that might want this behavior.
+ * that might want this behavior.
* <p>
* Additionally, this socket will be created using the supplied
* implementation class instead the default class or one returned by a
@@ -133,7 +136,7 @@ public class Socket
*
* @since 1.1
*/
- protected Socket (SocketImpl impl) throws SocketException
+ protected Socket(SocketImpl impl) throws SocketException
{
if (impl == null)
this.impl = new PlainSocketImpl();
@@ -142,7 +145,7 @@ public class Socket
}
/**
- * Initializes a new instance of <code>Socket</code> and connects to the
+ * Initializes a new instance of <code>Socket</code> and connects to the
* hostname and port specified as arguments.
*
* @param host The name of the host to connect to
@@ -154,14 +157,14 @@ public class Socket
* @exception SecurityException If a security manager exists and its
* checkConnect method doesn't allow the operation
*/
- public Socket (String host, int port)
+ public Socket(String host, int port)
throws UnknownHostException, IOException
{
this(InetAddress.getByName(host), port, null, 0, true);
}
/**
- * Initializes a new instance of <code>Socket</code> and connects to the
+ * Initializes a new instance of <code>Socket</code> and connects to the
* address and port number specified as arguments.
*
* @param address The address to connect to
@@ -171,15 +174,14 @@ public class Socket
* @exception SecurityException If a security manager exists and its
* checkConnect method doesn't allow the operation
*/
- public Socket (InetAddress address, int port)
- throws IOException
+ public Socket(InetAddress address, int port) throws IOException
{
this(address, port, null, 0, true);
}
/**
- * Initializes a new instance of <code>Socket</code> that connects to the
- * named host on the specified port and binds to the specified local address
+ * Initializes a new instance of <code>Socket</code> that connects to the
+ * named host on the specified port and binds to the specified local address
* and port.
*
* @param host The name of the remote host to connect to.
@@ -194,15 +196,15 @@ public class Socket
*
* @since 1.1
*/
- public Socket (String host, int port,
- InetAddress localAddr, int localPort) throws IOException
+ public Socket(String host, int port, InetAddress localAddr, int localPort)
+ throws IOException
{
this(InetAddress.getByName(host), port, localAddr, localPort, true);
}
/**
- * Initializes a new instance of <code>Socket</code> and connects to the
- * address and port number specified as arguments, plus binds to the
+ * Initializes a new instance of <code>Socket</code> and connects to the
+ * address and port number specified as arguments, plus binds to the
* specified local address and port.
*
* @param address The remote address to connect to
@@ -216,16 +218,16 @@ public class Socket
*
* @since 1.1
*/
- public Socket (InetAddress address, int port,
- InetAddress localAddr, int localPort) throws IOException
+ public Socket(InetAddress address, int port, InetAddress localAddr,
+ int localPort) throws IOException
{
this(address, port, localAddr, localPort, true);
}
/**
- * Initializes a new instance of <code>Socket</code> and connects to the
- * hostname and port specified as arguments. If the stream argument is set
- * to <code>true</code>, then a stream socket is created. If it is
+ * Initializes a new instance of <code>Socket</code> and connects to the
+ * hostname and port specified as arguments. If the stream argument is set
+ * to <code>true</code>, then a stream socket is created. If it is
* <code>false</code>, a datagram socket is created.
*
* @param host The name of the host to connect to
@@ -240,20 +242,21 @@ public class Socket
* @deprecated Use the <code>DatagramSocket</code> class to create
* datagram oriented sockets.
*/
- public Socket (String host, int port, boolean stream) throws IOException
+ public Socket(String host, int port, boolean stream)
+ throws IOException
{
this(InetAddress.getByName(host), port, null, 0, stream);
}
/**
- * Initializes a new instance of <code>Socket</code> and connects to the
- * address and port number specified as arguments. If the stream param is
- * <code>true</code>, a stream socket will be created, otherwise a datagram
+ * Initializes a new instance of <code>Socket</code> and connects to the
+ * address and port number specified as arguments. If the stream param is
+ * <code>true</code>, a stream socket will be created, otherwise a datagram
* socket is created.
*
* @param host The address to connect to
* @param port The port number to connect to
- * @param stream <code>true</code> to create a stream socket,
+ * @param stream <code>true</code> to create a stream socket,
* <code>false</code> to create a datagram socket.
*
* @exception IOException If an error occurs
@@ -263,7 +266,8 @@ public class Socket
* @deprecated Use the <code>DatagramSocket</code> class to create
* datagram oriented sockets.
*/
- public Socket (InetAddress host, int port, boolean stream) throws IOException
+ public Socket(InetAddress host, int port, boolean stream)
+ throws IOException
{
this(host, port, null, 0, stream);
}
@@ -296,11 +300,11 @@ public class Socket
// bind socket
SocketAddress bindaddr =
- laddr == null ? null : new InetSocketAddress (laddr, lport);
- bind (bindaddr);
-
+ laddr == null ? null : new InetSocketAddress(laddr, lport);
+ bind(bindaddr);
+
// connect socket
- connect (new InetSocketAddress (raddr, rport));
+ connect(new InetSocketAddress(raddr, rport));
// FIXME: JCL p. 1586 says if localPort is unspecified, bind to any port,
// i.e. '0' and if localAddr is unspecified, use getLocalAddress() as
@@ -308,12 +312,11 @@ public class Socket
}
// This has to be accessible from java.net.ServerSocket.
- SocketImpl getImpl()
- throws SocketException
+ SocketImpl getImpl() throws SocketException
{
try
{
- if (!implCreated)
+ if (! implCreated)
{
impl.create(true);
implCreated = true;
@@ -336,10 +339,10 @@ public class Socket
* @exception SecurityException If a security manager exists and its
* checkConnect method doesn't allow the operation
* @exception IllegalArgumentException If the address type is not supported
- *
+ *
* @since 1.4
*/
- public void bind (SocketAddress bindpoint) throws IOException
+ public void bind(SocketAddress bindpoint) throws IOException
{
if (isClosed())
throw new SocketException("socket is closed");
@@ -347,36 +350,36 @@ public class Socket
// XXX: JDK 1.4.1 API documentation says that if bindpoint is null the
// socket will be bound to an ephemeral port and a valid local address.
if (bindpoint == null)
- bindpoint = new InetSocketAddress (InetAddress.ANY_IF, 0);
-
- if ( !(bindpoint instanceof InetSocketAddress))
- throw new IllegalArgumentException ();
+ bindpoint = new InetSocketAddress(InetAddress.ANY_IF, 0);
+
+ if (! (bindpoint instanceof InetSocketAddress))
+ throw new IllegalArgumentException();
InetSocketAddress tmp = (InetSocketAddress) bindpoint;
-
+
// bind to address/port
try
{
- getImpl().bind (tmp.getAddress(), tmp.getPort());
+ getImpl().bind(tmp.getAddress(), tmp.getPort());
bound = true;
}
catch (IOException exception)
{
- close ();
- throw exception;
+ close();
+ throw exception;
}
catch (RuntimeException exception)
{
- close ();
- throw exception;
+ close();
+ throw exception;
}
catch (Error error)
{
- close ();
- throw error;
+ close();
+ throw error;
}
}
-
+
/**
* Connects the socket with a remote address.
*
@@ -386,13 +389,12 @@ public class Socket
* @exception IllegalArgumentException If the addess type is not supported
* @exception IllegalBlockingModeException If this socket has an associated
* channel, and the channel is in non-blocking mode
- *
+ *
* @since 1.4
*/
- public void connect (SocketAddress endpoint)
- throws IOException
+ public void connect(SocketAddress endpoint) throws IOException
{
- connect (endpoint, 0);
+ connect(endpoint, 0);
}
/**
@@ -401,7 +403,7 @@ public class Socket
* until established or an error occurs.
*
* @param endpoint The address to connect to
- * @param timeout The length of the timeout in milliseconds, or
+ * @param timeout The length of the timeout in milliseconds, or
* 0 to indicate no timeout.
*
* @exception IOException If an error occurs
@@ -409,15 +411,15 @@ public class Socket
* @exception IllegalBlockingModeException If this socket has an associated
* channel, and the channel is in non-blocking mode
* @exception SocketTimeoutException If the timeout is reached
- *
+ *
* @since 1.4
*/
- public void connect (SocketAddress endpoint, int timeout)
+ public void connect(SocketAddress endpoint, int timeout)
throws IOException
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
if (! (endpoint instanceof InetSocketAddress))
throw new IllegalArgumentException("unsupported address type");
@@ -425,32 +427,31 @@ public class Socket
// it is in non-blocking mode, we throw an IllegalBlockingModeException.
// However, in our implementation if the channel itself initiated this
// operation, then we must honor it regardless of its blocking mode.
- if (getChannel() != null
- && !getChannel().isBlocking ()
- && !((PlainSocketImpl) getImpl()).isInChannelOperation())
- throw new IllegalBlockingModeException ();
-
- if (!isBound ())
- bind (null);
+ if (getChannel() != null && ! getChannel().isBlocking()
+ && ! ((PlainSocketImpl) getImpl()).isInChannelOperation())
+ throw new IllegalBlockingModeException();
+
+ if (! isBound())
+ bind(null);
try
{
- getImpl().connect (endpoint, timeout);
+ getImpl().connect(endpoint, timeout);
}
catch (IOException exception)
{
- close ();
- throw exception;
+ close();
+ throw exception;
}
catch (RuntimeException exception)
{
- close ();
- throw exception;
+ close();
+ throw exception;
}
catch (Error error)
{
- close ();
- throw error;
+ close();
+ throw error;
}
}
@@ -460,9 +461,9 @@ public class Socket
*
* @return The remote address this socket is connected to
*/
- public InetAddress getInetAddress ()
+ public InetAddress getInetAddress()
{
- if (!isConnected())
+ if (! isConnected())
return null;
try
@@ -485,20 +486,20 @@ public class Socket
*
* @since 1.1
*/
- public InetAddress getLocalAddress ()
+ public InetAddress getLocalAddress()
{
InetAddress addr = null;
-
+
try
{
- addr = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
+ addr = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
}
- catch(SocketException e)
+ catch (SocketException e)
{
- // (hopefully) shouldn't happen
- // throw new java.lang.InternalError
- // ("Error in PlainSocketImpl.getOption");
- return null;
+ // (hopefully) shouldn't happen
+ // throw new java.lang.InternalError
+ // ("Error in PlainSocketImpl.getOption");
+ return null;
}
// FIXME: According to libgcj, checkConnect() is supposed to be called
@@ -519,9 +520,9 @@ public class Socket
*
* @return The remote port this socket is connected to
*/
- public int getPort ()
+ public int getPort()
{
- if (!isConnected())
+ if (! isConnected())
return 0;
try
@@ -543,11 +544,11 @@ public class Socket
*
* @return The local port
*/
- public int getLocalPort ()
+ public int getLocalPort()
{
- if (!isBound())
+ if (! isBound())
return -1;
-
+
try
{
if (getImpl() != null)
@@ -562,21 +563,22 @@ public class Socket
}
/**
- * If the socket is already bound this returns the local SocketAddress,
- * otherwise null
+ * Returns local socket address.
+ *
+ * @return the local socket address, null if not bound
*
* @since 1.4
*/
public SocketAddress getLocalSocketAddress()
{
- if (!isBound())
+ if (! isBound())
return null;
-
- InetAddress addr = getLocalAddress ();
+
+ InetAddress addr = getLocalAddress();
try
{
- return new InetSocketAddress (addr, getImpl().getLocalPort());
+ return new InetSocketAddress(addr, getImpl().getLocalPort());
}
catch (SocketException e)
{
@@ -586,19 +588,21 @@ public class Socket
}
/**
- * If the socket is already connected this returns the remote SocketAddress,
- * otherwise null
+ * Returns the remote socket address.
+ *
+ * @return the remote socket address, null of not connected
*
* @since 1.4
*/
public SocketAddress getRemoteSocketAddress()
{
- if (!isConnected ())
+ if (! isConnected())
return null;
try
{
- return new InetSocketAddress (getImpl().getInetAddress (), getImpl().getPort ());
+ return new InetSocketAddress(getImpl().getInetAddress(),
+ getImpl().getPort());
}
catch (SocketException e)
{
@@ -614,14 +618,14 @@ public class Socket
*
* @exception IOException If an error occurs or Socket is not connected
*/
- public InputStream getInputStream () throws IOException
+ public InputStream getInputStream() throws IOException
{
if (isClosed())
throw new SocketException("socket is closed");
-
- if (!isConnected())
+
+ if (! isConnected())
throw new IOException("not connected");
-
+
return getImpl().getInputStream();
}
@@ -632,42 +636,42 @@ public class Socket
*
* @exception IOException If an error occurs or Socket is not connected
*/
- public OutputStream getOutputStream () throws IOException
+ public OutputStream getOutputStream() throws IOException
{
if (isClosed())
throw new SocketException("socket is closed");
-
- if (!isConnected())
+
+ if (! isConnected())
throw new IOException("not connected");
-
+
return getImpl().getOutputStream();
}
/**
- * Sets the TCP_NODELAY option on the socket.
+ * Sets the TCP_NODELAY option on the socket.
*
* @param on true to enable, false to disable
- *
+ *
* @exception SocketException If an error occurs or Socket is not connected
*
* @since 1.1
*/
- public void setTcpNoDelay (boolean on) throws SocketException
+ public void setTcpNoDelay(boolean on) throws SocketException
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
getImpl().setOption(SocketOptions.TCP_NODELAY, Boolean.valueOf(on));
}
/**
- * Tests whether or not the TCP_NODELAY option is set on the socket.
+ * Tests whether or not the TCP_NODELAY option is set on the socket.
* Returns true if enabled, false if disabled. When on it disables the
* Nagle algorithm which means that packets are always send immediatly and
* never merged together to reduce network trafic.
*
* @return Whether or not TCP_NODELAY is set
- *
+ *
* @exception SocketException If an error occurs or Socket not connected
*
* @since 1.1
@@ -676,17 +680,17 @@ public class Socket
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
Object on = getImpl().getOption(SocketOptions.TCP_NODELAY);
-
+
if (on instanceof Boolean)
- return(((Boolean)on).booleanValue());
+ return (((Boolean) on).booleanValue());
else
throw new SocketException("Internal Error");
}
/**
- * Sets the value of the SO_LINGER option on the socket. If the
+ * Sets the value of the SO_LINGER option on the socket. If the
* SO_LINGER option is set on a socket and there is still data waiting to
* be sent when the socket is closed, then the close operation will block
* until either that data is delivered or until the timeout period
@@ -694,7 +698,7 @@ public class Socket
* (platform specific?)
*
* @param on true to enable SO_LINGER, false to disable
- * @param linger The SO_LINGER timeout in hundreths of a second or -1 if
+ * @param linger The SO_LINGER timeout in hundreths of a second or -1 if
* SO_LINGER not set.
*
* @exception SocketException If an error occurs or Socket not connected
@@ -706,25 +710,23 @@ public class Socket
{
if (isClosed())
throw new SocketException("socket is closed");
-
- if (on == true)
+
+ if (on)
{
- if (linger < 0)
- throw new IllegalArgumentException("SO_LINGER must be >= 0");
+ if (linger < 0)
+ throw new IllegalArgumentException("SO_LINGER must be >= 0");
- if (linger > 65535)
- linger = 65535;
+ if (linger > 65535)
+ linger = 65535;
- getImpl().setOption(SocketOptions.SO_LINGER, new Integer(linger));
+ getImpl().setOption(SocketOptions.SO_LINGER, new Integer(linger));
}
else
- {
- getImpl().setOption(SocketOptions.SO_LINGER, Boolean.valueOf(false));
- }
+ getImpl().setOption(SocketOptions.SO_LINGER, Boolean.valueOf(false));
}
/**
- * Returns the value of the SO_LINGER option on the socket. If the
+ * Returns the value of the SO_LINGER option on the socket. If the
* SO_LINGER option is set on a socket and there is still data waiting to
* be sent when the socket is closed, then the close operation will block
* until either that data is delivered or until the timeout period
@@ -732,7 +734,7 @@ public class Socket
* of a second (platform specific?)) if SO_LINGER is set, or -1 if
* SO_LINGER is not set.
*
- * @return The SO_LINGER timeout in hundreths of a second or -1
+ * @return The SO_LINGER timeout in hundreths of a second or -1
* if SO_LINGER not set
*
* @exception SocketException If an error occurs or Socket is not connected
@@ -743,11 +745,11 @@ public class Socket
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
Object linger = getImpl().getOption(SocketOptions.SO_LINGER);
if (linger instanceof Integer)
- return(((Integer)linger).intValue());
+ return (((Integer) linger).intValue());
else
return -1;
}
@@ -762,78 +764,78 @@ public class Socket
*
* @since 1.4
*/
- public void sendUrgentData (int data) throws IOException
+ public void sendUrgentData(int data) throws IOException
{
if (isClosed())
throw new SocketException("socket is closed");
-
- getImpl().sendUrgentData (data);
+
+ getImpl().sendUrgentData(data);
}
/**
* Enables/disables the SO_OOBINLINE option
- *
- * @param on True if SO_OOBLINE should be enabled
- *
+ *
+ * @param on True if SO_OOBLINE should be enabled
+ *
* @exception SocketException If an error occurs
- *
+ *
* @since 1.4
*/
- public void setOOBInline (boolean on) throws SocketException
+ public void setOOBInline(boolean on) throws SocketException
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
getImpl().setOption(SocketOptions.SO_OOBINLINE, Boolean.valueOf(on));
}
/**
* Returns the current setting of the SO_OOBINLINE option for this socket
- *
+ *
* @return True if SO_OOBINLINE is set, false otherwise.
*
* @exception SocketException If an error occurs
- *
+ *
* @since 1.4
*/
- public boolean getOOBInline () throws SocketException
+ public boolean getOOBInline() throws SocketException
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
Object buf = getImpl().getOption(SocketOptions.SO_OOBINLINE);
if (buf instanceof Boolean)
- return(((Boolean)buf).booleanValue());
+ return (((Boolean) buf).booleanValue());
else
throw new SocketException("Internal Error: Unexpected type");
}
-
+
/**
* Sets the value of the SO_TIMEOUT option on the socket. If this value
* is set, and an read/write is performed that does not complete within
* the timeout period, a short count is returned (or an EWOULDBLOCK signal
* would be sent in Unix if no data had been read). A value of 0 for
- * this option implies that there is no timeout (ie, operations will
+ * this option implies that there is no timeout (ie, operations will
* block forever). On systems that have separate read and write timeout
* values, this method returns the read timeout. This
* value is in milliseconds.
*
- * @param timeout The length of the timeout in milliseconds, or
+ * @param timeout The length of the timeout in milliseconds, or
* 0 to indicate no timeout.
*
* @exception SocketException If an error occurs or Socket not connected
*
* @since 1.1
*/
- public synchronized void setSoTimeout (int timeout) throws SocketException
+ public synchronized void setSoTimeout(int timeout) throws SocketException
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
if (timeout < 0)
throw new IllegalArgumentException("SO_TIMEOUT value must be >= 0");
-
+
getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
}
@@ -842,26 +844,26 @@ public class Socket
* is set, and an read/write is performed that does not complete within
* the timeout period, a short count is returned (or an EWOULDBLOCK signal
* would be sent in Unix if no data had been read). A value of 0 for
- * this option implies that there is no timeout (ie, operations will
+ * this option implies that there is no timeout (ie, operations will
* block forever). On systems that have separate read and write timeout
* values, this method returns the read timeout. This
* value is in thousandths of a second (implementation specific?).
*
- * @return The length of the timeout in thousandth's of a second or 0
+ * @return The length of the timeout in thousandth's of a second or 0
* if not set
*
* @exception SocketException If an error occurs or Socket not connected
*
* @since 1.1
*/
- public synchronized int getSoTimeout () throws SocketException
+ public synchronized int getSoTimeout() throws SocketException
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
Object timeout = getImpl().getOption(SocketOptions.SO_TIMEOUT);
if (timeout instanceof Integer)
- return(((Integer)timeout).intValue());
+ return (((Integer) timeout).intValue());
else
return 0;
}
@@ -878,14 +880,14 @@ public class Socket
*
* @since 1.2
*/
- public void setSendBufferSize (int size) throws SocketException
+ public void setSendBufferSize(int size) throws SocketException
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
if (size <= 0)
throw new IllegalArgumentException("SO_SNDBUF value must be > 0");
-
+
getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer(size));
}
@@ -900,15 +902,15 @@ public class Socket
*
* @since 1.2
*/
- public int getSendBufferSize () throws SocketException
+ public int getSendBufferSize() throws SocketException
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
Object buf = getImpl().getOption(SocketOptions.SO_SNDBUF);
if (buf instanceof Integer)
- return(((Integer)buf).intValue());
+ return (((Integer) buf).intValue());
else
throw new SocketException("Internal Error: Unexpected type");
}
@@ -925,14 +927,14 @@ public class Socket
*
* @since 1.2
*/
- public void setReceiveBufferSize (int size) throws SocketException
+ public void setReceiveBufferSize(int size) throws SocketException
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
if (size <= 0)
throw new IllegalArgumentException("SO_RCVBUF value must be > 0");
-
+
getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
}
@@ -947,15 +949,15 @@ public class Socket
*
* @since 1.2
*/
- public int getReceiveBufferSize () throws SocketException
+ public int getReceiveBufferSize() throws SocketException
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
Object buf = getImpl().getOption(SocketOptions.SO_RCVBUF);
if (buf instanceof Integer)
- return(((Integer)buf).intValue());
+ return (((Integer) buf).intValue());
else
throw new SocketException("Internal Error: Unexpected type");
}
@@ -970,11 +972,11 @@ public class Socket
*
* @since 1.3
*/
- public void setKeepAlive (boolean on) throws SocketException
+ public void setKeepAlive(boolean on) throws SocketException
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
getImpl().setOption(SocketOptions.SO_KEEPALIVE, Boolean.valueOf(on));
}
@@ -988,15 +990,15 @@ public class Socket
*
* @since 1.3
*/
- public boolean getKeepAlive () throws SocketException
+ public boolean getKeepAlive() throws SocketException
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
Object buf = getImpl().getOption(SocketOptions.SO_KEEPALIVE);
if (buf instanceof Boolean)
- return(((Boolean)buf).booleanValue());
+ return (((Boolean) buf).booleanValue());
else
throw new SocketException("Internal Error: Unexpected type");
}
@@ -1006,11 +1008,11 @@ public class Socket
*
* @exception IOException If an error occurs
*/
- public synchronized void close () throws IOException
+ public synchronized void close() throws IOException
{
if (isClosed())
return;
-
+
getImpl().close();
impl = null;
bound = false;
@@ -1024,15 +1026,14 @@ public class Socket
*
* @return The <code>String</code> representation of this <code>Socket</code>
*/
- public String toString ()
+ public String toString()
{
try
{
if (isConnected())
- return ("Socket[addr=" + getImpl().getInetAddress()
- + ",port=" + getImpl().getPort()
- + ",localport=" + getImpl().getLocalPort()
- + "]");
+ return ("Socket[addr=" + getImpl().getInetAddress() + ",port="
+ + getImpl().getPort() + ",localport="
+ + getImpl().getLocalPort() + "]");
}
catch (SocketException e)
{
@@ -1043,19 +1044,21 @@ public class Socket
}
/**
- * Sets the <code>SocketImplFactory</code>. This may be done only once per
- * virtual machine. Subsequent attempts will generate a
+ * Sets the <code>SocketImplFactory</code>. This may be done only once per
+ * virtual machine. Subsequent attempts will generate a
* <code>SocketException</code>. Note that a <code>SecurityManager</code>
- * check is made prior to setting the factory. If
- * insufficient privileges exist to set the factory, then an
+ * check is made prior to setting the factory. If
+ * insufficient privileges exist to set the factory, then an
* <code>IOException</code> will be thrown.
*
+ * @param fac the factory to set
+ *
* @exception SecurityException If the <code>SecurityManager</code> does
* not allow this operation.
* @exception SocketException If the SocketImplFactory is already defined
* @exception IOException If any other error occurs
*/
- public static synchronized void setSocketImplFactory (SocketImplFactory fac)
+ public static synchronized void setSocketImplFactory(SocketImplFactory fac)
throws IOException
{
// See if already set
@@ -1084,7 +1087,7 @@ public class Socket
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
getImpl().shutdownInput();
inputShutdown = true;
}
@@ -1100,7 +1103,7 @@ public class Socket
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
getImpl().shutdownOutput();
outputShutdown = true;
}
@@ -1108,7 +1111,8 @@ public class Socket
/**
* Returns the socket channel associated with this socket.
*
- * It returns null if no associated socket exists.
+ * @return the associated socket channel,
+ * null if no associated channel exists
*
* @since 1.4
*/
@@ -1126,55 +1130,57 @@ public class Socket
*
* @since 1.4
*/
- public boolean getReuseAddress () throws SocketException
+ public boolean getReuseAddress() throws SocketException
{
if (isClosed())
throw new SocketException("socket is closed");
-
- Object reuseaddr = getImpl().getOption (SocketOptions.SO_REUSEADDR);
- if (!(reuseaddr instanceof Boolean))
- throw new SocketException ("Internal Error");
+ Object reuseaddr = getImpl().getOption(SocketOptions.SO_REUSEADDR);
- return ((Boolean) reuseaddr).booleanValue ();
+ if (! (reuseaddr instanceof Boolean))
+ throw new SocketException("Internal Error");
+
+ return ((Boolean) reuseaddr).booleanValue();
}
/**
* Enables/Disables the SO_REUSEADDR option
*
- * @param reuseAddress True if SO_REUSEADDR should be set.
- *
+ * @param reuseAddress true if SO_REUSEADDR should be enabled,
+ * false otherwise
+ *
* @exception SocketException If an error occurs
*
* @since 1.4
*/
- public void setReuseAddress (boolean on) throws SocketException
+ public void setReuseAddress(boolean reuseAddress) throws SocketException
{
- getImpl().setOption (SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
+ getImpl().setOption(SocketOptions.SO_REUSEADDR,
+ Boolean.valueOf(reuseAddress));
}
/**
* Returns the current traffic class
*
* @return The current traffic class.
- *
+ *
* @exception SocketException If an error occurs
*
* @see Socket#setTrafficClass(int tc)
*
* @since 1.4
*/
- public int getTrafficClass () throws SocketException
+ public int getTrafficClass() throws SocketException
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
Object obj = getImpl().getOption(SocketOptions.IP_TOS);
if (obj instanceof Integer)
- return ((Integer) obj).intValue ();
+ return ((Integer) obj).intValue();
else
- throw new SocketException ("Unexpected type");
+ throw new SocketException("Unexpected type");
}
/**
@@ -1189,15 +1195,15 @@ public class Socket
*
* @since 1.4
*/
- public void setTrafficClass (int tc) throws SocketException
+ public void setTrafficClass(int tc) throws SocketException
{
if (isClosed())
throw new SocketException("socket is closed");
-
+
if (tc < 0 || tc > 255)
throw new IllegalArgumentException();
- getImpl().setOption (SocketOptions.IP_TOS, new Integer (tc));
+ getImpl().setOption(SocketOptions.IP_TOS, new Integer(tc));
}
/**
@@ -1207,11 +1213,11 @@ public class Socket
*
* @since 1.4
*/
- public boolean isConnected ()
+ public boolean isConnected()
{
try
{
- return getImpl().getInetAddress () != null;
+ return getImpl().getInetAddress() != null;
}
catch (SocketException e)
{
@@ -1226,19 +1232,19 @@ public class Socket
*
* @since 1.4
*/
- public boolean isBound ()
+ public boolean isBound()
{
return bound;
}
/**
* Checks if the socket is closed.
- *
+ *
* @return True if socket is closed, false otherwise.
*
* @since 1.4
*/
- public boolean isClosed ()
+ public boolean isClosed()
{
return impl == null;
}
@@ -1247,10 +1253,10 @@ public class Socket
* Checks if the socket's input stream is shutdown
*
* @return True if input is shut down.
- *
+ *
* @since 1.4
*/
- public boolean isInputShutdown ()
+ public boolean isInputShutdown()
{
return inputShutdown;
}
@@ -1259,10 +1265,10 @@ public class Socket
* Checks if the socket's output stream is shutdown
*
* @return True if output is shut down.
- *
+ *
* @since 1.4
*/
- public boolean isOutputShutdown ()
+ public boolean isOutputShutdown()
{
return outputShutdown;
}
diff --git a/libjava/java/net/SocketAddress.java b/libjava/java/net/SocketAddress.java
index f3e67d84cc0..d8239a41695 100644
--- a/libjava/java/net/SocketAddress.java
+++ b/libjava/java/net/SocketAddress.java
@@ -1,4 +1,4 @@
-/* SocketAddress.java --
+/* SocketAddress.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,7 +39,8 @@ package java.net;
import java.io.Serializable;
-/**
+
+/**
* Abstract base class for InetSocketAddress.
* InetSocketAddress is to my knowledge the only derived
* class. [Ronald]
diff --git a/libjava/java/net/SocketException.java b/libjava/java/net/SocketException.java
index 6494cae9d3e..6b863606630 100644
--- a/libjava/java/net/SocketException.java
+++ b/libjava/java/net/SocketException.java
@@ -39,6 +39,7 @@ package java.net;
import java.io.IOException;
+
/**
* This exception indicates that a generic error occurred related to an
* operation on a socket. Check the descriptive message (if any) for
diff --git a/libjava/java/net/SocketImpl.java b/libjava/java/net/SocketImpl.java
index e43b49ed599..8cfb9ef5a1d 100644
--- a/libjava/java/net/SocketImpl.java
+++ b/libjava/java/net/SocketImpl.java
@@ -36,14 +36,14 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.net;
import java.io.FileDescriptor;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
+
/* Written using on-line Java Platform 1.2 API Specification.
* Believed complete and correct.
*/
@@ -113,7 +113,8 @@ public abstract class SocketImpl implements SocketOptions
*
* @exception IOException If an error occurs
*/
- protected abstract void connect(String host, int port) throws IOException;
+ protected abstract void connect(String host, int port)
+ throws IOException;
/**
* Connects to the remote address and port specified as arguments.
@@ -153,7 +154,8 @@ public abstract class SocketImpl implements SocketOptions
*
* @exception IOException If an error occurs
*/
- protected abstract void bind(InetAddress host, int port) throws IOException;
+ protected abstract void bind(InetAddress host, int port)
+ throws IOException;
/**
* Starts listening for connections on a socket. The backlog parameter
@@ -220,26 +222,38 @@ public abstract class SocketImpl implements SocketOptions
*
* @return A FileDescriptor for this socket.
*/
- protected FileDescriptor getFileDescriptor() { return fd; }
+ protected FileDescriptor getFileDescriptor()
+ {
+ return fd;
+ }
/**
* Returns the remote address this socket is connected to
*
* @return The remote address
*/
- protected InetAddress getInetAddress() { return address; }
+ protected InetAddress getInetAddress()
+ {
+ return address;
+ }
/**
* Returns the remote port this socket is connected to
*
* @return The remote port
*/
- protected int getPort() { return port; }
+ protected int getPort()
+ {
+ return port;
+ }
/**
* Returns true or false when this socket supports sending urgent data
* or not.
*
+ * @return true if the socket implementation supports sending urgent data,
+ * false otherwise
+ *
* @since 1.4
*/
protected boolean supportsUrgentData()
@@ -248,7 +262,7 @@ public abstract class SocketImpl implements SocketOptions
// sending urgend data.
return false;
}
-
+
/**
* Sends one byte of urgent data to the socket.
*
@@ -258,15 +272,17 @@ public abstract class SocketImpl implements SocketOptions
*
* @since 1.4
*/
- protected abstract void sendUrgentData(int data)
- throws IOException;
-
+ protected abstract void sendUrgentData(int data) throws IOException;
+
/**
* Returns the local port this socket is bound to
*
* @return The local port
*/
- protected int getLocalPort() { return localport; }
+ protected int getLocalPort()
+ {
+ return localport;
+ }
/**
* Returns a <code>String</code> representing the remote host and port of
@@ -276,10 +292,9 @@ public abstract class SocketImpl implements SocketOptions
*/
public String toString()
{
- return "[addr=" + ((address == null) ? "0.0.0.0/0.0.0.0" :
- address.toString())
- + ",port=" + port
- + ",localport=" + localport + "]";
+ return "[addr="
+ + ((address == null) ? "0.0.0.0/0.0.0.0" : address.toString())
+ + ",port=" + port + ",localport=" + localport + "]";
}
/**
@@ -288,9 +303,9 @@ public abstract class SocketImpl implements SocketOptions
*
* @exception IOException if an error occurs
*/
- protected void shutdownInput () throws IOException
+ protected void shutdownInput() throws IOException
{
- throw new IOException ("Not implemented in this socket class");
+ throw new IOException("Not implemented in this socket class");
}
/**
@@ -299,8 +314,8 @@ public abstract class SocketImpl implements SocketOptions
*
* @exception IOException if an error occurs
*/
- protected void shutdownOutput () throws IOException
+ protected void shutdownOutput() throws IOException
{
- throw new IOException ("Not implemented in this socket class");
+ throw new IOException("Not implemented in this socket class");
}
}
diff --git a/libjava/java/net/SocketImplFactory.java b/libjava/java/net/SocketImplFactory.java
index 26074119ea1..84e92a521f1 100644
--- a/libjava/java/net/SocketImplFactory.java
+++ b/libjava/java/net/SocketImplFactory.java
@@ -7,7 +7,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -35,13 +35,12 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.net;
+
/** Written using on-line Java Platform 1.2 API Specification.
* Status: Believed complete and correct.
*/
-
/**
* This interface defines one method which returns a <code>SocketImpl</code>
* object. This should not be needed by ordinary applications.
@@ -57,6 +56,4 @@ public interface SocketImplFactory
* @return A <code>SocketImpl</code> object
*/
SocketImpl createSocketImpl();
-
} // interface SocketImplFactory
-
diff --git a/libjava/java/net/SocketOptions.java b/libjava/java/net/SocketOptions.java
index 149d7b73ff1..7ccd887cc68 100644
--- a/libjava/java/net/SocketOptions.java
+++ b/libjava/java/net/SocketOptions.java
@@ -1,5 +1,5 @@
/* SocketOptions.java -- Implements options for sockets (duh!)
- Copyright (C) 1998, 1999, 2000, 2001,
+ Copyright (C) 1998, 1999, 2000, 2001,
2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -8,7 +8,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -38,15 +38,15 @@ exception statement from your version. */
package java.net;
+
/**
* Written using on-line Java Platform 1.2 API Specification.
* Status: Believed complete and correct.
*/
-
/**
- * This interface is used by <code>SocketImpl</code> and
+ * This interface is used by <code>SocketImpl</code> and
* <code>DatagramSocketImpl</code> to implement options
- * on sockets.
+ * on sockets.
*
* @since 1.2
*
@@ -163,6 +163,4 @@ public interface SocketOptions
* @exception SocketException If an error occurs
*/
Object getOption(int optionId) throws SocketException;
-
} // interface SocketOptions
-
diff --git a/libjava/java/net/SocketPermission.java b/libjava/java/net/SocketPermission.java
index 35006173828..e9d1402a7d4 100644
--- a/libjava/java/net/SocketPermission.java
+++ b/libjava/java/net/SocketPermission.java
@@ -1,5 +1,5 @@
/* SocketPermission.java -- Class modeling permissions for socket operations
- Copyright (C) 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -41,6 +41,7 @@ import java.io.Serializable;
import java.security.Permission;
import java.security.PermissionCollection;
+
/**
* This class models a specific set of permssions for connecting to a
* host. There are two elements to this, the host/port combination and
@@ -64,18 +65,20 @@ import java.security.PermissionCollection;
* value for a port (respectively) is used by default. Here are some
* examples:
* <p><ul>
- * <li>8080 - Represents port 8080 only
- * <li>2000-3000 - Represents ports 2000 through 3000 inclusive
- * <li>-4000 - Represents ports 0 through 4000 inclusive
- * <li>1024- - Represents ports 1024 through 65535 inclusive
+ * <li>8080 - Represents port 8080 only</li>
+ * <li>2000-3000 - Represents ports 2000 through 3000 inclusive</li>
+ * <li>-4000 - Represents ports 0 through 4000 inclusive</li>
+ * <li>1024- - Represents ports 1024 through 65535 inclusive</li>
* </ul><p>
* The permission list is a comma separated list of individual permissions.
* These individual permissions are:
* <p>
- * accept<br>
- * connect<br>
- * listen<br>
- * resolve<br>
+ * <pre>
+ * accept
+ * connect
+ * listen
+ * resolve
+ * </pre>
* <p>
* The "listen" permission is only relevant if the host is localhost. If
* any permission at all is specified, then resolve permission is implied to
@@ -103,12 +106,12 @@ import java.security.PermissionCollection;
*
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
-public final class SocketPermission extends Permission
- implements Serializable
+public final class SocketPermission extends Permission implements Serializable
{
static final long serialVersionUID = -7204263841984476862L;
// FIXME: Needs serialization work, including readObject/writeObject methods.
+
/**
* A hostname/port combination as described above
*/
@@ -120,7 +123,7 @@ public final class SocketPermission extends Permission
private String actions;
/**
- * Initializes a new instance of <code>SocketPermission</code> with the
+ * Initializes a new instance of <code>SocketPermission</code> with the
* specified host/port combination and actions string.
*
* @param hostport The hostname/port number combination
@@ -136,18 +139,18 @@ public final class SocketPermission extends Permission
/**
* Tests this object for equality against another. This will be true if
- * and only if the passed object is an instance of
- * <code>SocketPermission</code> and both its hostname/port combination
+ * and only if the passed object is an instance of
+ * <code>SocketPermission</code> and both its hostname/port combination
* and permissions string are identical.
*
* @param obj The object to test against for equality
*
- * @return <code>true</code> if object is equal to this object,
+ * @return <code>true</code> if object is equal to this object,
* <code>false</code> otherwise.
*/
public boolean equals(Object obj)
{
- if (!(obj instanceof SocketPermission))
+ if (! (obj instanceof SocketPermission))
return (false);
if (((SocketPermission) obj).hostport.equals(hostport))
@@ -158,7 +161,7 @@ public final class SocketPermission extends Permission
}
/**
- * Returns a hash code value for this object. Overrides the
+ * Returns a hash code value for this object. Overrides the
* <code>Permission.hashCode()</code>.
*
* @return A hash code
@@ -192,21 +195,21 @@ public final class SocketPermission extends Permission
if (actions.indexOf("listen") != -1)
if (found)
- sb.append(",listen");
+ sb.append(",listen");
else
- {
+ {
sb.append("listen");
found = true;
- }
+ }
if (actions.indexOf("accept") != -1)
if (found)
sb.append(",accept");
else
- {
+ {
sb.append("accept");
found = true;
- }
+ }
if (found)
sb.append(",resolve");
@@ -231,25 +234,27 @@ public final class SocketPermission extends Permission
/**
* Returns true if the permission object passed it is implied by the
- * this permission. This will be true if
- * <p><ul>
- * <li>The argument is of type <code>SocketPermission</code>
- * <li>The actions list of the argument are in this object's actions
- * <li>The port range of the argument is within this objects port range
- * <li>The hostname is equal to or a subset of this objects hostname
+ * this permission. This will be true if:
+ *
+ * <ul>
+ * <li>The argument is of type <code>SocketPermission</code></li>
+ * <li>The actions list of the argument are in this object's actions</li>
+ * <li>The port range of the argument is within this objects port range</li>
+ * <li>The hostname is equal to or a subset of this objects hostname</li>
* </ul>
- * <p>
- * The argument's hostname will be a subset of this object's hostname if:
- * <p><ul>
- * <li>The argument's hostname or IP address is equal to this object's.
- * <li>The argument's canonical hostname is equal to this object's.
+ *
+ * <p>The argument's hostname will be a subset of this object's hostname if:</p>
+ *
+ * <ul>
+ * <li>The argument's hostname or IP address is equal to this object's.</li>
+ * <li>The argument's canonical hostname is equal to this object's.</li>
* <li>The argument's canonical name matches this domains hostname with
- * wildcards
+ * wildcards</li>
* </ul>
*
* @param perm The <code>Permission</code> to check against
*
- * @return <code>true</code> if the <code>Permission</code> is implied by
+ * @return <code>true</code> if the <code>Permission</code> is implied by
* this object, <code>false</code> otherwise.
*/
public boolean implies(Permission perm)
@@ -266,72 +271,78 @@ public final class SocketPermission extends Permission
String ourlist = getActions();
String theirlist = p.getActions();
- if (!ourlist.startsWith(theirlist))
+ if (! ourlist.startsWith(theirlist))
return (false);
// Now check ports
- int ourfirstport = 0, ourlastport = 0, theirfirstport = 0, theirlastport =
- 0;
+ int ourfirstport = 0;
+
+ // Now check ports
+ int ourlastport = 0;
+
+ // Now check ports
+ int theirfirstport = 0;
+
+ // Now check ports
+ int theirlastport = 0;
// Get ours
if (hostport.indexOf(":") == -1)
{
- ourfirstport = 0;
- ourlastport = 65535;
+ ourfirstport = 0;
+ ourlastport = 65535;
}
else
{
- // FIXME: Needs bulletproofing.
- // This will dump if hostport if all sorts of bad data was passed to
- // the constructor
- String range = hostport.substring(hostport.indexOf(":") + 1);
- if (range.startsWith("-"))
- ourfirstport = 0;
- else if (range.indexOf("-") == -1)
- ourfirstport = Integer.parseInt(range);
- else
- ourfirstport =
- Integer.parseInt(range.substring(0, range.indexOf("-")));
-
- if (range.endsWith("-"))
- ourlastport = 65535;
- else if (range.indexOf("-") == -1)
- ourlastport = Integer.parseInt(range);
- else
- ourlastport =
- Integer.parseInt(range.
- substring(range.indexOf("-") + 1,
- range.length()));
+ // FIXME: Needs bulletproofing.
+ // This will dump if hostport if all sorts of bad data was passed to
+ // the constructor
+ String range = hostport.substring(hostport.indexOf(":") + 1);
+ if (range.startsWith("-"))
+ ourfirstport = 0;
+ else if (range.indexOf("-") == -1)
+ ourfirstport = Integer.parseInt(range);
+ else
+ ourfirstport =
+ Integer.parseInt(range.substring(0, range.indexOf("-")));
+
+ if (range.endsWith("-"))
+ ourlastport = 65535;
+ else if (range.indexOf("-") == -1)
+ ourlastport = Integer.parseInt(range);
+ else
+ ourlastport =
+ Integer.parseInt(range.substring(range.indexOf("-") + 1,
+ range.length()));
}
// Get theirs
if (p.hostport.indexOf(":") == -1)
{
- theirfirstport = 0;
- ourlastport = 65535;
+ theirfirstport = 0;
+ ourlastport = 65535;
}
else
{
- // This will dump if hostport if all sorts of bad data was passed to
- // the constructor
- String range = p.hostport.substring(hostport.indexOf(":") + 1);
- if (range.startsWith("-"))
- theirfirstport = 0;
- else if (range.indexOf("-") == -1)
- theirfirstport = Integer.parseInt(range);
- else
- theirfirstport =
- Integer.parseInt(range.substring(0, range.indexOf("-")));
-
- if (range.endsWith("-"))
- theirlastport = 65535;
- else if (range.indexOf("-") == -1)
- theirlastport = Integer.parseInt(range);
- else
- theirlastport =
- Integer.parseInt(range.
- substring(range.indexOf("-") + 1,
- range.length()));
+ // This will dump if hostport if all sorts of bad data was passed to
+ // the constructor
+ String range = p.hostport.substring(hostport.indexOf(":") + 1);
+ if (range.startsWith("-"))
+ theirfirstport = 0;
+ else if (range.indexOf("-") == -1)
+ theirfirstport = Integer.parseInt(range);
+ else
+ theirfirstport =
+ Integer.parseInt(range.substring(0, range.indexOf("-")));
+
+ if (range.endsWith("-"))
+ theirlastport = 65535;
+ else if (range.indexOf("-") == -1)
+ theirlastport = Integer.parseInt(range);
+ else
+ theirlastport =
+ Integer.parseInt(range.substring(range.indexOf("-") + 1,
+ range.length()));
}
// Now check them
@@ -339,7 +350,10 @@ public final class SocketPermission extends Permission
return (false);
// Finally we can check the hosts
- String ourhost, theirhost;
+ String ourhost;
+
+ // Finally we can check the hosts
+ String theirhost;
// Get ours
if (hostport.indexOf(":") == -1)
@@ -358,20 +372,23 @@ public final class SocketPermission extends Permission
return (true);
// Try the canonical names
- String ourcanonical = null, theircanonical = null;
+ String ourcanonical = null;
+
+ // Try the canonical names
+ String theircanonical = null;
try
{
- ourcanonical = InetAddress.getByName(ourhost).getHostName();
- theircanonical = InetAddress.getByName(theirhost).getHostName();
+ ourcanonical = InetAddress.getByName(ourhost).getHostName();
+ theircanonical = InetAddress.getByName(theirhost).getHostName();
}
catch (UnknownHostException e)
{
- // Who didn't resolve? Just assume current address is canonical enough
- // Is this ok to do?
- if (ourcanonical == null)
- ourcanonical = ourhost;
- if (theircanonical == null)
- theircanonical = theirhost;
+ // Who didn't resolve? Just assume current address is canonical enough
+ // Is this ok to do?
+ if (ourcanonical == null)
+ ourcanonical = ourhost;
+ if (theircanonical == null)
+ theircanonical = theirhost;
}
if (ourcanonical.equals(theircanonical))
@@ -380,9 +397,9 @@ public final class SocketPermission extends Permission
// Well, last chance. Try for a wildcard
if (ourhost.indexOf("*.") != -1)
{
- String wild_domain = ourhost.substring(ourhost.indexOf("*" + 1));
- if (theircanonical.endsWith(wild_domain))
- return (true);
+ String wild_domain = ourhost.substring(ourhost.indexOf("*" + 1));
+ if (theircanonical.endsWith(wild_domain))
+ return (true);
}
// Didn't make it
diff --git a/libjava/java/net/SocketTimeoutException.java b/libjava/java/net/SocketTimeoutException.java
index e3895518d19..e375065b344 100644
--- a/libjava/java/net/SocketTimeoutException.java
+++ b/libjava/java/net/SocketTimeoutException.java
@@ -39,6 +39,7 @@ package java.net;
import java.io.InterruptedIOException;
+
/**
* This exception signals that a socket read or accept timed out.
*
diff --git a/libjava/java/net/URI.java b/libjava/java/net/URI.java
index e1d833a072d..b456f71d2dd 100644
--- a/libjava/java/net/URI.java
+++ b/libjava/java/net/URI.java
@@ -7,7 +7,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -44,14 +44,14 @@ import java.io.Serializable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+
/**
* @author Ito Kazumitsu (ito.kazumitsu@hitachi-cable.co.jp)
* @author Dalibor Topic (robilad@kaffe.org)
* @author Michael Koch (konqueror@gmx.de)
* @since 1.4
*/
-public final class URI
- implements Comparable, Serializable
+public final class URI implements Comparable, Serializable
{
static final long serialVersionUID = -6052424284110960213L;
@@ -70,11 +70,14 @@ public final class URI
private static final String RFC2396_DIGIT = "0123456789";
private static final String RFC2396_LOWALPHA = "abcdefghijklmnopqrstuvwxyz";
private static final String RFC2396_UPALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- private static final String RFC2396_ALPHA = RFC2396_LOWALPHA + RFC2396_UPALPHA;
+ private static final String RFC2396_ALPHA =
+ RFC2396_LOWALPHA + RFC2396_UPALPHA;
private static final String RFC2396_ALPHANUM = RFC2396_DIGIT + RFC2396_ALPHA;
private static final String RFC2396_MARK = "-_.!~*'()";
- private static final String RFC2396_UNRESERVED = RFC2396_ALPHANUM + RFC2396_MARK;
- private static final String RFC2396_REG_NAME = RFC2396_UNRESERVED + "$,;:@&=+";
+ private static final String RFC2396_UNRESERVED =
+ RFC2396_ALPHANUM + RFC2396_MARK;
+ private static final String RFC2396_REG_NAME =
+ RFC2396_UNRESERVED + "$,;:@&=+";
private static final String RFC2396_PCHAR = RFC2396_UNRESERVED + ":@&=+$,";
private static final String RFC2396_SEGMENT = RFC2396_PCHAR + ";";
private static final String RFC2396_PATH_SEGMENTS = RFC2396_SEGMENT + "/";
@@ -108,7 +111,6 @@ public final class URI
* Index of fragment component in parsed URI.
*/
private static final int FRAGMENT_GROUP = 10;
-
private String scheme;
private String rawSchemeSpecificPart;
private String schemeSpecificPart;
@@ -126,17 +128,17 @@ public final class URI
private String rawFragment;
private String fragment;
- private void readObject (ObjectInputStream is)
+ private void readObject(ObjectInputStream is)
throws ClassNotFoundException, IOException
{
}
- private void writeObject (ObjectOutputStream is)
- throws IOException
+ private void writeObject(ObjectOutputStream is) throws IOException
{
}
- private static String getURIGroup (Matcher match, int group) {
+ private static String getURIGroup(Matcher match, int group)
+ {
String matched = match.group(group);
return matched.length() == 0 ? null : matched;
}
@@ -148,23 +150,22 @@ public final class URI
*
* @exception URISyntaxException If the given string violates RFC 2396
*/
- private void parseURI (String str)
- throws URISyntaxException
+ private void parseURI(String str) throws URISyntaxException
{
Pattern pattern = Pattern.compile(URI_REGEXP);
Matcher matcher = pattern.matcher(str);
if (matcher.matches())
{
scheme = getURIGroup(matcher, SCHEME_GROUP);
- rawSchemeSpecificPart = getURIGroup(matcher, SCHEME_SPEC_PART_GROUP);
+ rawSchemeSpecificPart = getURIGroup(matcher, SCHEME_SPEC_PART_GROUP);
rawAuthority = getURIGroup(matcher, AUTHORITY_GROUP);
rawPath = getURIGroup(matcher, PATH_GROUP);
rawQuery = getURIGroup(matcher, QUERY_GROUP);
rawFragment = getURIGroup(matcher, FRAGMENT_GROUP);
}
else
- throw new URISyntaxException(str,
- "doesn't match URI regular expression");
+ throw new URISyntaxException(str, "doesn't match URI regular expression");
+
// We must eagerly unquote the parts, because this is the only time
// we may throw an exception.
schemeSpecificPart = unquote(rawSchemeSpecificPart);
@@ -184,35 +185,39 @@ public final class URI
* @exception URISyntaxException If the given string contains invalid
* escape sequences.
*/
- private static String unquote (String str)
- throws URISyntaxException
+ private static String unquote(String str) throws URISyntaxException
{
if (str == null)
return null;
byte[] buf = new byte[str.length()];
int pos = 0;
- for (int i = 0; i < str.length(); i++) {
- char c = str.charAt(i);
- if (c > 127)
+ for (int i = 0; i < str.length(); i++)
+ {
+ char c = str.charAt(i);
+ if (c > 127)
throw new URISyntaxException(str, "Invalid character");
- if (c == '%') {
- if (i + 2 >= str.length())
- throw new URISyntaxException(str, "Invalid quoted character");
- String hex = "0123456789ABCDEF";
- int hi = hex.indexOf(str.charAt(++i));
- int lo = hex.indexOf(str.charAt(++i));
- if (lo < 0 || hi < 0)
- throw new URISyntaxException(str, "Invalid quoted character");
- buf[pos++] = (byte)(hi * 16 + lo);
- } else {
- buf[pos++] = (byte)c;
+ if (c == '%')
+ {
+ if (i + 2 >= str.length())
+ throw new URISyntaxException(str, "Invalid quoted character");
+ String hex = "0123456789ABCDEF";
+ int hi = hex.indexOf(str.charAt(++i));
+ int lo = hex.indexOf(str.charAt(++i));
+ if (lo < 0 || hi < 0)
+ throw new URISyntaxException(str, "Invalid quoted character");
+ buf[pos++] = (byte) (hi * 16 + lo);
+ }
+ else
+ buf[pos++] = (byte) c;
+ }
+ try
+ {
+ return new String(buf, 0, pos, "utf-8");
+ }
+ catch (java.io.UnsupportedEncodingException x2)
+ {
+ throw (Error) new InternalError().initCause(x2);
}
- }
- try {
- return new String(buf, 0, pos, "utf-8");
- } catch (java.io.UnsupportedEncodingException x2) {
- throw (Error)new InternalError().initCause(x2);
- }
}
/**
@@ -223,10 +228,11 @@ public final class URI
* UTF-8 character.
*
* @param str The string to quote
- *
+ *
* @return The quoted string.
*/
- private static String quote (String str) {
+ private static String quote(String str)
+ {
// FIXME: unimplemented.
return str;
}
@@ -239,10 +245,11 @@ public final class URI
* UTF-8 character.
*
* @param str The string to quote
- *
+ *
* @return The quoted string.
*/
- private static String quoteAuthority (String str) {
+ private static String quoteAuthority(String str)
+ {
// Technically, we should be using RFC2396_AUTHORITY, but
// it contains no additional characters.
return quote(str, RFC2396_REG_NAME);
@@ -257,37 +264,39 @@ public final class URI
*
* @param str The string to quote
* @param legalCharacters The set of legal characters
- *
+ *
* @return The quoted string.
*/
- private static String quote (String str, String legalCharacters)
+ private static String quote(String str, String legalCharacters)
{
StringBuffer sb = new StringBuffer(str.length());
- for (int i = 0; i < str.length(); i++) {
- char c = str.charAt(i);
- if (legalCharacters.indexOf(c) == -1) {
- String hex = "0123456789ABCDEF";
- if (c <= 127) {
- sb.append('%')
- .append(hex.charAt(c / 16))
- .append(hex.charAt(c % 16));
- } else {
- try {
- // this is far from optimal, but it works
- byte[] utf8 = str.substring(i, i + 1).getBytes("utf-8");
- for (int j = 0; j < utf8.length; j++) {
- sb.append('%')
- .append(hex.charAt((utf8[j] & 0xff) / 16))
- .append(hex.charAt((utf8[j] & 0xff) % 16));
- }
- } catch (java.io.UnsupportedEncodingException x) {
- throw (Error)new InternalError().initCause(x);
+ for (int i = 0; i < str.length(); i++)
+ {
+ char c = str.charAt(i);
+ if (legalCharacters.indexOf(c) == -1)
+ {
+ String hex = "0123456789ABCDEF";
+ if (c <= 127)
+ sb.append('%').append(hex.charAt(c / 16)).append(hex.charAt(c % 16));
+ else
+ {
+ try
+ {
+ // this is far from optimal, but it works
+ byte[] utf8 = str.substring(i, i + 1).getBytes("utf-8");
+ for (int j = 0; j < utf8.length; j++)
+ sb.append('%').append(hex.charAt((utf8[j] & 0xff) / 16))
+ .append(hex.charAt((utf8[j] & 0xff) % 16));
+ }
+ catch (java.io.UnsupportedEncodingException x)
+ {
+ throw (Error) new InternalError().initCause(x);
+ }
+ }
}
- }
- } else {
- sb.append(c);
+ else
+ sb.append(c);
}
- }
return sb.toString();
}
@@ -299,10 +308,11 @@ public final class URI
* UTF-8 character.
*
* @param str The string to quote
- *
+ *
* @return The quoted string.
*/
- private static String quoteHost (String str) {
+ private static String quoteHost(String str)
+ {
// FIXME: unimplemented.
return str;
}
@@ -315,10 +325,11 @@ public final class URI
* UTF-8 character.
*
* @param str The string to quote
- *
+ *
* @return The quoted string.
*/
- private static String quotePath (String str) {
+ private static String quotePath(String str)
+ {
// Technically, we should be using RFC2396_PATH, but
// it contains no additional characters.
return quote(str, RFC2396_PATH_SEGMENTS);
@@ -332,10 +343,11 @@ public final class URI
* UTF-8 character.
*
* @param str The string to quote
- *
+ *
* @return The quoted string.
*/
- private static String quoteUserInfo (String str) {
+ private static String quoteUserInfo(String str)
+ {
// FIXME: unimplemented.
return str;
}
@@ -348,12 +360,11 @@ public final class URI
* @exception URISyntaxException If the given string violates RFC 2396
* @exception NullPointerException If str is null
*/
- public URI (String str)
- throws URISyntaxException
+ public URI(String str) throws URISyntaxException
{
parseURI(str);
}
-
+
/**
* Create an URI from the given components
*
@@ -367,19 +378,19 @@ public final class URI
*
* @exception URISyntaxException If the given string violates RFC 2396
*/
- public URI (String scheme, String userInfo, String host, int port,
- String path, String query, String fragment)
+ public URI(String scheme, String userInfo, String host, int port,
+ String path, String query, String fragment)
throws URISyntaxException
{
- this((scheme == null ? "" : scheme + ":" )
- + (userInfo == null && host == null && port == -1 ? "" : "//")
- + (userInfo == null ? "" : quoteUserInfo(userInfo) + "@")
- + (host == null ? "" : quoteHost(host))
- + (port == -1 ? "" : ":" + String.valueOf(port))
- + (path == null ? "" : quotePath(path))
- + (query == null ? "" : "?" + quote(query))
- + (fragment == null ? "" : "#" + quote(fragment)));
-
+ this((scheme == null ? "" : scheme + ":")
+ + (userInfo == null && host == null && port == -1 ? "" : "//")
+ + (userInfo == null ? "" : quoteUserInfo(userInfo) + "@")
+ + (host == null ? "" : quoteHost(host))
+ + (port == -1 ? "" : ":" + String.valueOf(port))
+ + (path == null ? "" : quotePath(path))
+ + (query == null ? "" : "?" + quote(query))
+ + (fragment == null ? "" : "#" + quote(fragment)));
+
parseServerAuthority();
}
@@ -394,15 +405,14 @@ public final class URI
*
* @exception URISyntaxException If the given string violates RFC 2396
*/
- public URI (String scheme, String authority, String path, String query,
- String fragment)
- throws URISyntaxException
+ public URI(String scheme, String authority, String path, String query,
+ String fragment) throws URISyntaxException
{
this((scheme == null ? "" : scheme + ":")
- + (authority == null ? "" : "//" + quoteAuthority(authority))
- + (path == null ? "" : quotePath(path))
- + (query == null ? "" : "?" + quote(query))
- + (fragment == null ? "" : "#" + quote(fragment)));
+ + (authority == null ? "" : "//" + quoteAuthority(authority))
+ + (path == null ? "" : quotePath(path))
+ + (query == null ? "" : "?" + quote(query))
+ + (fragment == null ? "" : "#" + quote(fragment)));
}
/**
@@ -415,7 +425,7 @@ public final class URI
*
* @exception URISyntaxException If the given string violates RFC 2396
*/
- public URI (String scheme, String host, String path, String fragment)
+ public URI(String scheme, String host, String path, String fragment)
throws URISyntaxException
{
this(scheme, null, host, -1, path, null, fragment);
@@ -430,12 +440,12 @@ public final class URI
*
* @exception URISyntaxException If the given string violates RFC 2396
*/
- public URI (String scheme, String ssp, String fragment)
+ public URI(String scheme, String ssp, String fragment)
throws URISyntaxException
{
this((scheme == null ? "" : scheme + ":")
- + (ssp == null ? "" : quote(ssp))
- + (fragment == null ? "" : "#" + quote(fragment)));
+ + (ssp == null ? "" : quote(ssp))
+ + (fragment == null ? "" : "#" + quote(fragment)));
}
/**
@@ -446,16 +456,16 @@ public final class URI
* @exception IllegalArgumentException If the given string violates RFC 2396
* @exception NullPointerException If str is null
*/
- public static URI create (String str)
+ public static URI create(String str)
{
try
{
return new URI(str);
}
- catch(URISyntaxException e)
+ catch (URISyntaxException e)
{
- throw (IllegalArgumentException)
- new IllegalArgumentException().initCause(e);
+ throw (IllegalArgumentException) new IllegalArgumentException()
+ .initCause(e);
}
}
@@ -465,8 +475,7 @@ public final class URI
*
* @exception URISyntaxException If the given string violates RFC 2396
*/
- public URI parseServerAuthority ()
- throws URISyntaxException
+ public URI parseServerAuthority() throws URISyntaxException
{
return null;
}
@@ -474,7 +483,7 @@ public final class URI
/**
* Returns a normalizes versions of the URI
*/
- public URI normalize ()
+ public URI normalize()
{
return null;
}
@@ -489,8 +498,8 @@ public final class URI
*
* @exception NullPointerException If uri is null
*/
- public URI resolve (URI uri)
- {
+ public URI resolve(URI uri)
+ {
if (uri.isAbsolute())
return uri;
if (uri.isOpaque())
@@ -505,35 +514,34 @@ public final class URI
try
{
- if (fragment != null &&
- path != null && path.equals("") &&
- scheme == null && authority == null && query == null)
+ if (fragment != null && path != null && path.equals("")
+ && scheme == null && authority == null && query == null)
return new URI(this.scheme, this.schemeSpecificPart, fragment);
- if (authority == null)
+ if (authority == null)
{
- authority = this.authority;
- if (path == null)
+ authority = this.authority;
+ if (path == null)
path = "";
- if (!(path.startsWith("/")))
+ if (! (path.startsWith("/")))
{
- StringBuffer basepath = new StringBuffer(this.path);
- int i = this.path.lastIndexOf('/');
+ StringBuffer basepath = new StringBuffer(this.path);
+ int i = this.path.lastIndexOf('/');
- if (i >= 0)
- basepath.delete(i+1, basepath.length());
+ if (i >= 0)
+ basepath.delete(i + 1, basepath.length());
- basepath.append(path);
- path = basepath.toString();
- // FIXME We must normalize the path here.
- // Normalization process omitted.
+ basepath.append(path);
+ path = basepath.toString();
+ // FIXME We must normalize the path here.
+ // Normalization process omitted.
}
}
- return new URI(this.scheme, authority, path, query, fragment);
+ return new URI(this.scheme, authority, path, query, fragment);
}
catch (URISyntaxException e)
{
- return null;
+ return null;
}
}
@@ -548,8 +556,7 @@ public final class URI
* violates RFC 2396
* @exception NullPointerException If uri is null
*/
- public URI resolve (String str)
- throws IllegalArgumentException
+ public URI resolve(String str) throws IllegalArgumentException
{
return resolve(create(str));
}
@@ -563,7 +570,7 @@ public final class URI
*
* @exception NullPointerException If uri is null
*/
- public URI relativize (URI uri)
+ public URI relativize(URI uri)
{
return null;
}
@@ -575,8 +582,7 @@ public final class URI
* not be found, or if some other error occurred while constructing the URL
* @exception IllegalArgumentException If the URI is not absolute
*/
- public URL toURL ()
- throws IllegalArgumentException, MalformedURLException
+ public URL toURL() throws IllegalArgumentException, MalformedURLException
{
if (isAbsolute())
return new URL(this.toString());
@@ -587,7 +593,7 @@ public final class URI
/**
* Returns the scheme of the URI
*/
- public String getScheme ()
+ public String getScheme()
{
return scheme;
}
@@ -595,7 +601,7 @@ public final class URI
/**
* Tells whether this URI is absolute or not
*/
- public boolean isAbsolute ()
+ public boolean isAbsolute()
{
return (scheme != null);
}
@@ -603,16 +609,16 @@ public final class URI
/**
* Tell whether this URI is opaque or not
*/
- public boolean isOpaque ()
+ public boolean isOpaque()
{
- return ((scheme != null) && !(schemeSpecificPart.startsWith("/")));
+ return ((scheme != null) && ! (schemeSpecificPart.startsWith("/")));
}
/**
* Returns the raw scheme specific part of this URI.
* The scheme-specific part is never undefined, though it may be empty
*/
- public String getRawSchemeSpecificPart ()
+ public String getRawSchemeSpecificPart()
{
return rawSchemeSpecificPart;
}
@@ -620,7 +626,7 @@ public final class URI
/**
* Returns the decoded scheme specific part of this URI.
*/
- public String getSchemeSpecificPart ()
+ public String getSchemeSpecificPart()
{
return schemeSpecificPart;
}
@@ -628,7 +634,7 @@ public final class URI
/**
* Returns the rae authority part of this URI
*/
- public String getRawAuthority ()
+ public String getRawAuthority()
{
return rawAuthority;
}
@@ -636,7 +642,7 @@ public final class URI
/**
* Returns the decoded authority part of this URI
*/
- public String getAuthority ()
+ public String getAuthority()
{
return authority;
}
@@ -644,7 +650,7 @@ public final class URI
/**
* Returns the raw user info part of this URI
*/
- public String getRawUserInfo ()
+ public String getRawUserInfo()
{
return rawUserInfo;
}
@@ -652,7 +658,7 @@ public final class URI
/**
* Returns the decoded user info part of this URI
*/
- public String getUserInfo ()
+ public String getUserInfo()
{
return userInfo;
}
@@ -660,7 +666,7 @@ public final class URI
/**
* Returns the hostname of the URI
*/
- public String getHost ()
+ public String getHost()
{
return host;
}
@@ -668,7 +674,7 @@ public final class URI
/**
* Returns the port number of the URI
*/
- public int getPort ()
+ public int getPort()
{
return port;
}
@@ -676,7 +682,7 @@ public final class URI
/**
* Returns the raw path part of this URI
*/
- public String getRawPath ()
+ public String getRawPath()
{
return rawPath;
}
@@ -684,7 +690,7 @@ public final class URI
/**
* Returns the path of the URI
*/
- public String getPath ()
+ public String getPath()
{
return path;
}
@@ -692,7 +698,7 @@ public final class URI
/**
* Returns the raw query part of this URI
*/
- public String getRawQuery ()
+ public String getRawQuery()
{
return rawQuery;
}
@@ -700,7 +706,7 @@ public final class URI
/**
* Returns the query of the URI
*/
- public String getQuery ()
+ public String getQuery()
{
return query;
}
@@ -708,7 +714,7 @@ public final class URI
/**
* Return the raw fragment part of this URI
*/
- public String getRawFragment ()
+ public String getRawFragment()
{
return rawFragment;
}
@@ -716,7 +722,7 @@ public final class URI
/**
* Returns the fragment of the URI
*/
- public String getFragment ()
+ public String getFragment()
{
return fragment;
}
@@ -734,7 +740,7 @@ public final class URI
/**
* Computes the hascode of the URI
*/
- public int hashCode ()
+ public int hashCode()
{
return 0;
}
@@ -746,8 +752,7 @@ public final class URI
*
* @exception ClassCastException If given object ist not an URI
*/
- public int compareTo (Object obj)
- throws ClassCastException
+ public int compareTo(Object obj) throws ClassCastException
{
return 0;
}
@@ -755,19 +760,19 @@ public final class URI
/**
* Returns the URI as string
*/
- public String toString ()
+ public String toString()
{
return (getScheme() == null ? "" : getScheme() + ":")
- + (getRawAuthority() == null ? "" : "//" + getRawAuthority())
- + (getRawPath() == null ? "" : getRawPath())
- + (getRawQuery() == null ? "" : "?" + getRawQuery())
- + (getRawFragment() == null ? "" : "#" + getRawFragment());
+ + (getRawAuthority() == null ? "" : "//" + getRawAuthority())
+ + (getRawPath() == null ? "" : getRawPath())
+ + (getRawQuery() == null ? "" : "?" + getRawQuery())
+ + (getRawFragment() == null ? "" : "#" + getRawFragment());
}
/**
* Returns the URI as US-ASCII string
*/
- public String toASCIIString ()
+ public String toASCIIString()
{
return "";
}
diff --git a/libjava/java/net/URISyntaxException.java b/libjava/java/net/URISyntaxException.java
index cf725665e88..89a0be69823 100644
--- a/libjava/java/net/URISyntaxException.java
+++ b/libjava/java/net/URISyntaxException.java
@@ -37,6 +37,7 @@ exception statement from your version. */
package java.net;
+
/**
* This exception is thrown when a String cannot be parsed as a URI.
*
@@ -137,7 +138,7 @@ public class URISyntaxException extends Exception
*/
public String getMessage()
{
- return super.getMessage() + (index >= 0 ? " at index " + index : "")
- + ": " + input;
+ return (super.getMessage() + (index >= 0 ? " at index " + index : "")
+ + ": " + input);
}
}
diff --git a/libjava/java/net/URL.java b/libjava/java/net/URL.java
index 85f0efba579..623f6601770 100644
--- a/libjava/java/net/URL.java
+++ b/libjava/java/net/URL.java
@@ -7,7 +7,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -35,18 +35,18 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.net;
import gnu.java.net.URLParseError;
-import java.io.InputStream;
import java.io.IOException;
-import java.io.Serializable;
+import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
+import java.io.Serializable;
import java.util.HashMap;
import java.util.StringTokenizer;
+
/*
* Written using on-line Java Platform 1.2 API Specification, as well
* as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
@@ -56,7 +56,7 @@ import java.util.StringTokenizer;
/**
* This final class represents an Internet Uniform Resource Locator (URL).
* For details on the syntax of URL's and what they can be used for,
- * refer to RFC 1738, available from <a
+ * refer to RFC 1738, available from <a
* href="http://ds.internic.net/rfcs/rfc1738.txt">
* http://ds.internic.net/rfcs/rfc1738.txt</a>
* <p>
@@ -74,7 +74,7 @@ import java.util.StringTokenizer;
* This chaining is done via the system property java.protocol.handler.pkgs
* If this property is set, it is assumed to be a "|" separated list of
* package names in which to attempt locating protocol handlers. The
- * protocol handler is searched for by appending the string
+ * protocol handler is searched for by appending the string
* ".&lt;protocol&gt;.Handler" to each packed in the list until a hander is
* found. If a protocol handler is not found in this list of packages, or if
* the property does not exist, then the default protocol handler of
@@ -87,7 +87,7 @@ import java.util.StringTokenizer;
* <p>
* Here is an example of how URL searches for protocol handlers. Assume
* the value of java.protocol.handler.pkgs is "com.foo|com.bar" and the
- * URL is "news://comp.lang.java.programmer". URL would looking the
+ * URL is "news://comp.lang.java.programmer". URL would looking the
* following places for protocol handlers:
* <p><pre>
* com.foo.news.Handler
@@ -122,7 +122,7 @@ public final class URL implements Serializable
{
private static final String DEFAULT_SEARCH_PATH =
"gnu.java.net.protocol|sun.net.www.protocol";
-
+
/**
* The name of the protocol for this URL.
* The protocol is always stored in lower case.
@@ -141,10 +141,15 @@ public final class URL implements Serializable
private String host;
/**
+ * The user information necessary to establish the connection.
+ */
+ private String userInfo;
+
+ /**
* The port number of this protocol or -1 if the port number used is
* the default for this protocol.
*/
- private int port = -1; // Initialize for constructor using context.
+ private int port = -1; // Initialize for constructor using context.
/**
* The "file" portion of the URL. It is defined as <code>path[?query]</code>.
@@ -159,7 +164,7 @@ public final class URL implements Serializable
/**
* This is the hashCode for this URL
*/
- private int hashCode = 0;
+ private int hashCode;
/**
* The protocol handler in use for this URL
@@ -171,7 +176,6 @@ public final class URL implements Serializable
* where we keep track of it.
*/
private static URLStreamHandlerFactory factory;
-
private static final long serialVersionUID = -7627629688361524110L;
/**
@@ -187,18 +191,18 @@ public final class URL implements Serializable
static
{
- String s = System.getProperty ("gnu.java.net.nocache_protocol_handlers");
-
+ String s = System.getProperty("gnu.java.net.nocache_protocol_handlers");
+
if (s == null)
- cache_handlers = true;
+ cache_handlers = true;
else
- cache_handlers = false;
+ cache_handlers = false;
}
/**
* Constructs a URL and loads a protocol handler for the values passed as
* arguments.
- *
+ *
* @param protocol The protocol for this URL ("http", "ftp", etc)
* @param host The hostname or IP address to connect to
* @param port The port number to use, or -1 to use the protocol's
@@ -231,11 +235,10 @@ public final class URL implements Serializable
this(protocol, host, -1, file, null);
}
-
/**
* This method initializes a new instance of <code>URL</code> with the
* specified protocol, host, port, and file. Additionally, this method
- * allows the caller to specify a protocol handler to use instead of
+ * allows the caller to specify a protocol handler to use instead of
* the default. If this handler is specified, the caller must have
* the "specifyStreamHandler" permission (see <code>NetPermission</code>)
* or a <code>SecurityException</code> will be thrown.
@@ -254,9 +257,8 @@ public final class URL implements Serializable
*
* @since 1.2
*/
- public URL (String protocol, String host, int port, String file,
- URLStreamHandler ph)
- throws MalformedURLException
+ public URL(String protocol, String host, int port, String file,
+ URLStreamHandler ph) throws MalformedURLException
{
if (protocol == null)
throw new MalformedURLException("null protocol");
@@ -266,20 +268,22 @@ public final class URL implements Serializable
{
SecurityManager s = System.getSecurityManager();
if (s != null)
- s.checkPermission (new NetPermission ("specifyStreamHandler"));
+ s.checkPermission(new NetPermission("specifyStreamHandler"));
- this.ph = ph;
+ this.ph = ph;
}
else
this.ph = getURLStreamHandler(protocol);
if (this.ph == null)
- throw new MalformedURLException (
- "Protocol handler not found: " + protocol);
+ throw new MalformedURLException("Protocol handler not found: "
+ + protocol);
this.host = host;
this.port = port;
- this.authority = null;
+ this.authority = (host != null) ? host : "";
+ if (port >= 0)
+ this.authority += ":" + port;
int hashAt = file.indexOf('#');
if (hashAt < 0)
@@ -292,7 +296,7 @@ public final class URL implements Serializable
this.file = file.substring(0, hashAt);
this.ref = file.substring(hashAt + 1);
}
- hashCode = hashCode(); // Used for serialization.
+ hashCode = hashCode(); // Used for serialization.
}
/**
@@ -325,7 +329,7 @@ public final class URL implements Serializable
* @param context The context on which to parse the specification
* @param spec The string to parse an URL
*
- * @exception MalformedURLException If a protocol handler cannot be found
+ * @exception MalformedURLException If a protocol handler cannot be found
* for the URL cannot be parsed
*/
public URL(URL context, String spec) throws MalformedURLException
@@ -340,7 +344,7 @@ public final class URL implements Serializable
* not present the URL are inheritied from the context URL. This allows
* relative URL's to be easily constructed. If the context argument is
* null, then a complete URL must be specified in the URL string.
- * If the protocol parsed out of the URL is different
+ * If the protocol parsed out of the URL is different
* from the context URL's protocol, then then URL String is also
* expected to be a complete URL.
* <p>
@@ -372,7 +376,7 @@ public final class URL implements Serializable
* The relative URL need not specify all the components of a URL.
* If the protocol, host name, or port number is missing, the value
* is inherited from the context. A bare file component is appended
- * to the context's file. The optional anchor is not inherited.
+ * to the context's file. The optional anchor is not inherited.
*/
// If this is an absolute URL, then ignore context completely.
@@ -380,13 +384,13 @@ public final class URL implements Serializable
// right after the "://". The second colon is for an optional port value
// and implies that the host from the context is used if available.
int colon;
- if ((colon = spec.indexOf("://", 1)) > 0 &&
- ! spec.regionMatches(colon, "://:", 0, 4))
+ if ((colon = spec.indexOf("://", 1)) > 0
+ && ! spec.regionMatches(colon, "://:", 0, 4))
context = null;
int slash;
- if ((colon = spec.indexOf(':')) > 0 &&
- (colon < (slash = spec.indexOf('/')) || slash < 0))
+ if ((colon = spec.indexOf(':')) > 0
+ && (colon < (slash = spec.indexOf('/')) || slash < 0))
{
// Protocol specified in spec string.
protocol = spec.substring(0, colon).toLowerCase();
@@ -412,26 +416,27 @@ public final class URL implements Serializable
file = context.file;
if (file == null || file.length() == 0)
file = "/";
- authority = context.authority;
+ authority = context.authority;
}
- else // Protocol NOT specified in spec. and no context available.
- throw new
- MalformedURLException("Absolute URL required with null context");
+ else // Protocol NOT specified in spec. and no context available.
+
+
+ throw new MalformedURLException("Absolute URL required with null context");
if (ph != null)
{
- SecurityManager s = System.getSecurityManager ();
+ SecurityManager s = System.getSecurityManager();
if (s != null)
- s.checkPermission (new NetPermission ("specifyStreamHandler"));
+ s.checkPermission(new NetPermission("specifyStreamHandler"));
- this.ph = ph;
+ this.ph = ph;
}
else
this.ph = getURLStreamHandler(protocol);
if (this.ph == null)
throw new MalformedURLException("Protocol handler not found: "
- + protocol);
+ + protocol);
// JDK 1.2 doc for parseURL specifically states that any '#' ref
// is to be excluded by passing the 'limit' as the indexOf the '#'
@@ -441,35 +446,35 @@ public final class URL implements Serializable
try
{
this.ph.parseURL(this, spec, colon + 1,
- hashAt < 0 ? spec.length() : hashAt);
+ hashAt < 0 ? spec.length() : hashAt);
}
catch (URLParseError e)
{
throw new MalformedURLException(e.getMessage());
}
-
+
if (hashAt >= 0)
ref = spec.substring(hashAt + 1);
- hashCode = hashCode(); // Used for serialization.
+ hashCode = hashCode(); // Used for serialization.
}
/**
* Test another URL for equality with this one. This will be true only if
- * the argument is non-null and all of the fields in the URL's match
+ * the argument is non-null and all of the fields in the URL's match
* exactly (ie, protocol, host, port, file, and ref). Overrides
* Object.equals(), implemented by calling the equals method of the handler.
*
- * @param url The URL to compare with
+ * @param obj The URL to compare with
*
* @return true if the URL is equal, false otherwise
*/
- public boolean equals (Object obj)
+ public boolean equals(Object obj)
{
if (! (obj instanceof URL))
return false;
- return ph.equals (this, (URL) obj);
+ return ph.equals(this, (URL) obj);
}
/**
@@ -482,7 +487,7 @@ public final class URL implements Serializable
*
* @since 1.3
*/
- public final Object getContent() throws IOException
+ public Object getContent() throws IOException
{
return openConnection().getContent();
}
@@ -496,7 +501,7 @@ public final class URL implements Serializable
*
* @exception IOException If an error occurs
*/
- public final Object getContent (Class[] classes) throws IOException
+ public Object getContent(Class[] classes) throws IOException
{
// FIXME: implement this
return getContent();
@@ -519,7 +524,7 @@ public final class URL implements Serializable
* character.
*
* @return The path specified in this URL.
- *
+ *
* @since 1.3
*/
public String getPath()
@@ -532,7 +537,7 @@ public final class URL implements Serializable
* Returns the authority of the URL
*
* @return The authority specified in this URL.
- *
+ *
* @since 1.3
*/
public String getAuthority()
@@ -602,7 +607,7 @@ public final class URL implements Serializable
*
* @return the user at a particular host or null when no user defined.
*/
- public String getUserInfo ()
+ public String getUserInfo()
{
int at = (host == null) ? -1 : host.indexOf('@');
return at < 0 ? null : host.substring(0, at);
@@ -614,7 +619,7 @@ public final class URL implements Serializable
*
* @return the query part of the file, or null when there is no query part.
*/
- public String getQuery ()
+ public String getQuery()
{
int quest = (file == null) ? -1 : file.indexOf('?');
return quest < 0 ? null : file.substring(quest + 1, file.length());
@@ -628,9 +633,9 @@ public final class URL implements Serializable
public int hashCode()
{
if (hashCode != 0)
- return hashCode; // Use cached value if available.
+ return hashCode; // Use cached value if available.
else
- return ph.hashCode (this);
+ return ph.hashCode(this);
}
/**
@@ -652,10 +657,10 @@ public final class URL implements Serializable
* from that connection
*
* @return An <code>InputStream</code> for this URL.
- *
+ *
* @exception IOException If an error occurs
*/
- public final InputStream openStream() throws IOException
+ public InputStream openStream() throws IOException
{
return openConnection().getInputStream();
}
@@ -670,9 +675,9 @@ public final class URL implements Serializable
*
* @return true if URL matches this URL's file, false otherwise
*/
- public boolean sameFile(URL other)
+ public boolean sameFile(URL url)
{
- return ph.sameFile(this, other);
+ return ph.sameFile(this, url);
}
/**
@@ -688,7 +693,7 @@ public final class URL implements Serializable
* @param ref The anchor portion of this URL.
*/
protected void set(String protocol, String host, int port, String file,
- String ref)
+ String ref)
{
// TBD: Theoretically, a poorly written StreamHandler could pass an
// invalid protocol. It will cause the handler to be set to null
@@ -696,12 +701,18 @@ public final class URL implements Serializable
// be aware of this.
this.ph = getURLStreamHandler(protocol);
this.protocol = protocol.toLowerCase();
- this.authority = null;
+ this.authority = "";
this.port = port;
this.host = host;
this.file = file;
this.ref = ref;
- hashCode = hashCode(); // Used for serialization.
+
+ if (host != null)
+ this.authority += host;
+ if (port >= 0)
+ this.authority += ":" + port;
+
+ hashCode = hashCode(); // Used for serialization.
}
/**
@@ -720,9 +731,8 @@ public final class URL implements Serializable
*
* @since 1.3
*/
- protected void set(String protocol, String host, int port,
- String authority, String userInfo,
- String path, String query, String ref)
+ protected void set(String protocol, String host, int port, String authority,
+ String userInfo, String path, String query, String ref)
{
// TBD: Theoretically, a poorly written StreamHandler could pass an
// invalid protocol. It will cause the handler to be set to null
@@ -730,17 +740,16 @@ public final class URL implements Serializable
// be aware of this.
this.ph = getURLStreamHandler(protocol);
this.protocol = protocol.toLowerCase();
- if (userInfo == null)
- this.host = host;
- else
- this.host = userInfo + "@" + host;
+ this.host = host;
+ this.userInfo = userInfo;
this.port = port;
+ this.authority = authority;
if (query == null)
this.file = path;
else
this.file = path + "?" + query;
this.ref = ref;
- hashCode = hashCode(); // Used for serialization.
+ hashCode = hashCode(); // Used for serialization.
}
/**
@@ -754,8 +763,7 @@ public final class URL implements Serializable
* @exception SecurityException If a security manager exists and its
* checkSetFactory method doesn't allow the operation
*/
- public static synchronized void
- setURLStreamHandlerFactory(URLStreamHandlerFactory fac)
+ public static synchronized void setURLStreamHandlerFactory(URLStreamHandlerFactory fac)
{
if (factory != null)
throw new Error("URLStreamHandlerFactory already set");
@@ -782,7 +790,7 @@ public final class URL implements Serializable
/**
* Returns a String representing this URL. Identical to toExternalForm().
- * The value returned is created by the protocol handler's
+ * The value returned is created by the protocol handler's
* toExternalForm method. Overrides Object.toString()
*
* @return A string for this URL
@@ -801,28 +809,27 @@ public final class URL implements Serializable
*
* @return A URLStreamHandler for this protocol, or null when not found.
*/
- private static synchronized URLStreamHandler
- getURLStreamHandler (String protocol)
+ private static synchronized URLStreamHandler getURLStreamHandler(String protocol)
{
URLStreamHandler ph = null;
// First, see if a protocol handler is in our cache.
if (cache_handlers)
{
- if ((ph = (URLStreamHandler) ph_cache.get (protocol)) != null)
- return ph;
+ if ((ph = (URLStreamHandler) ph_cache.get(protocol)) != null)
+ return ph;
}
// If a non-default factory has been set, use it to find the protocol.
if (factory != null)
{
- ph = factory.createURLStreamHandler (protocol);
+ ph = factory.createURLStreamHandler(protocol);
}
- else if (protocol.equals ("core"))
+ else if (protocol.equals("core"))
{
ph = new gnu.java.net.protocol.core.Handler();
}
- else if (protocol.equals ("file"))
+ else if (protocol.equals("file"))
{
// This is an interesting case. It's tempting to think that we
// could call Class.forName ("gnu.java.net.protocol.file.Handler") to
@@ -850,42 +857,41 @@ public final class URL implements Serializable
// Tack our default package on at the ends.
if (ph_search_path != null)
- ph_search_path += "|" + DEFAULT_SEARCH_PATH;
+ ph_search_path += "|" + DEFAULT_SEARCH_PATH;
else
- ph_search_path = DEFAULT_SEARCH_PATH;
+ ph_search_path = DEFAULT_SEARCH_PATH;
// Finally loop through our search path looking for a match.
- StringTokenizer pkgPrefix = new StringTokenizer (ph_search_path, "|");
-
+ StringTokenizer pkgPrefix = new StringTokenizer(ph_search_path, "|");
+
do
- {
- String clsName = (pkgPrefix.nextToken() + "."
- + protocol + ".Handler");
-
- try
- {
- Object obj = Class.forName (clsName).newInstance();
-
- if (!(obj instanceof URLStreamHandler))
- continue;
- else
- ph = (URLStreamHandler) obj;
- }
- catch (Exception e)
- {
- // Can't instantiate; handler still null,
+ {
+ String clsName =
+ (pkgPrefix.nextToken() + "." + protocol + ".Handler");
+
+ try
+ {
+ Object obj = Class.forName(clsName).newInstance();
+
+ if (! (obj instanceof URLStreamHandler))
+ continue;
+ else
+ ph = (URLStreamHandler) obj;
+ }
+ catch (Exception e)
+ {
+ // Can't instantiate; handler still null,
// go on to next element.
- }
- }
- while ((! (ph instanceof URLStreamHandler))
- && pkgPrefix.hasMoreTokens());
+ }
+ }
+ while ((! (ph instanceof URLStreamHandler))
+ && pkgPrefix.hasMoreTokens());
}
// Update the hashtable with the new protocol handler.
- if (ph != null
- && cache_handlers)
+ if (ph != null && cache_handlers)
if (ph instanceof URLStreamHandler)
- ph_cache.put (protocol, ph);
+ ph_cache.put(protocol, ph);
else
ph = null;
diff --git a/libjava/java/net/URLClassLoader.java b/libjava/java/net/URLClassLoader.java
index e1c789ddd64..65e15ea3a6a 100644
--- a/libjava/java/net/URLClassLoader.java
+++ b/libjava/java/net/URLClassLoader.java
@@ -7,7 +7,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -35,7 +35,6 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.net;
import java.io.ByteArrayOutputStream;
@@ -43,24 +42,25 @@ import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilePermission;
-import java.io.InputStream;
import java.io.IOException;
-import java.security.AccessController;
+import java.io.InputStream;
import java.security.AccessControlContext;
+import java.security.AccessController;
import java.security.CodeSource;
-import java.security.SecureClassLoader;
-import java.security.PrivilegedAction;
import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
+import java.security.SecureClassLoader;
import java.security.cert.Certificate;
import java.util.Enumeration;
-import java.util.Vector;
import java.util.HashMap;
+import java.util.Vector;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import gnu.gcj.runtime.SharedLibHelper;
+
/**
* A secure class loader that can load classes and resources from
* multiple locations. Given an array of <code>URL</code>s this class
@@ -118,7 +118,6 @@ import gnu.gcj.runtime.SharedLibHelper;
* @author Mark Wielaard (mark@klomp.org)
* @author Wu Gansha (gansha.wu@intel.com)
*/
-
public class URLClassLoader extends SecureClassLoader
{
// Class Variables
@@ -130,7 +129,7 @@ public class URLClassLoader extends SecureClassLoader
* XXX - Keeps these loaders forever which prevents garbage collection.
*/
private static HashMap urlloaders = new HashMap();
-
+
/**
* A cache to store mappings between handler factory and its
* private protocol handler cache (also a HashMap), so we can avoid
@@ -144,12 +143,12 @@ public class URLClassLoader extends SecureClassLoader
private final Vector urls = new Vector();
/**
- * Store pre-parsed information for each url into this vector
- * each element is a URL loader, corresponding to the URL of
+ * Store pre-parsed information for each url into this vector
+ * each element is a URL loader, corresponding to the URL of
* the same index in "urls"
*/
private final Vector urlinfos = new Vector();
-
+
/** Factory used to get the protocol handlers of the URLs */
private final URLStreamHandlerFactory factory;
@@ -161,12 +160,12 @@ public class URLClassLoader extends SecureClassLoader
private final AccessControlContext securityContext;
// Helper classes
-
- /**
+
+ /**
* A <code>URLLoader</code> contains all logic to load resources from a
* given base <code>URL</code>.
*/
- static abstract class URLLoader
+ abstract static class URLLoader
{
/**
* Our classloader to get info from if needed.
@@ -189,9 +188,14 @@ public class URLClassLoader extends SecureClassLoader
URLLoader(URLClassLoader classloader, URL baseURL)
{
+ this(classloader, baseURL, baseURL);
+ }
+
+ URLLoader(URLClassLoader classloader, URL baseURL, URL overrideURL)
+ {
this.classloader = classloader;
this.baseURL = baseURL;
- this.noCertCodeSource = new CodeSource(baseURL, null);
+ this.noCertCodeSource = new CodeSource(overrideURL, null);
}
/**
@@ -223,14 +227,14 @@ public class URLClassLoader extends SecureClassLoader
}
}
- /**
+ /**
* A <code>Resource</code> represents a resource in some
* <code>URLLoader</code>. It also contains all information (e.g.,
* <code>URL</code>, <code>CodeSource</code>, <code>Manifest</code> and
* <code>InputStream</code>) that is necessary for loading resources
* and creating classes from a <code>URL</code>.
*/
- static abstract class Resource
+ abstract static class Resource
{
final URLLoader loader;
final String name;
@@ -285,10 +289,12 @@ public class URLClassLoader extends SecureClassLoader
* A <code>JarURLLoader</code> is a type of <code>URLLoader</code>
* only loading from jar url.
*/
- final static class JarURLLoader extends URLLoader
+ static final class JarURLLoader extends URLLoader
{
final JarFile jarfile; // The jar file for this url
- final URL baseJarURL; // Base jar: url for all resources loaded from jar
+ final URL baseJarURL; // Base jar: url for all resources loaded from jar
+
+ SoURLLoader soURLLoader;
public JarURLLoader(URLClassLoader classloader, URL baseURL)
{
@@ -302,6 +308,7 @@ public class URLClassLoader extends SecureClassLoader
sb.append("!/");
String jarURL = sb.toString();
+ this.soURLLoader = null;
URL baseJarURL = null;
JarFile jarfile = null;
try
@@ -310,13 +317,44 @@ public class URLClassLoader extends SecureClassLoader
= new URL(null, jarURL, classloader.getURLStreamHandler("jar"));
jarfile
= ((JarURLConnection) baseJarURL.openConnection()).getJarFile();
+
+ if (jarfile != null)
+ {
+ String fileName = baseURL.getFile();
+ if (fileName != null)
+ {
+ File f = new File(fileName);
+ String libDirName = f.getCanonicalFile().getParent()
+ + File.separator + "GCJLIBS";
+ File libDir = new File(libDirName);
+ if (libDir != null && (libDir.isDirectory()))
+ {
+ File soFile = new File (libDirName + File.separator + f.getName()
+ + ".so");
+ if (soFile != null && soFile.isFile())
+ this.soURLLoader
+ = new SoURLLoader (classloader, soFile.toURL(),
+ baseURL);
+ }
+ }
+ }
}
- catch (IOException ioe) { /* ignored */ }
+ catch (IOException ioe)
+ {
+ /* ignored */
+ }
this.baseJarURL = baseJarURL;
this.jarfile = jarfile;
}
+ Class getClass(String className)
+ {
+ if (soURLLoader != null)
+ return soURLLoader.getClass(className);
+ return null;
+ }
+
/** get resource with the name "name" in the jar url */
Resource getResource(String name)
{
@@ -324,29 +362,34 @@ public class URLClassLoader extends SecureClassLoader
return null;
if (name.startsWith("/"))
- name = name.substring(1);
+ name = name.substring(1);
JarEntry je = jarfile.getJarEntry(name);
- if(je != null)
+ if (je != null)
return new JarURLResource(this, name, je);
else
return null;
}
+ public String toString ()
+ {
+ return "jarfile " + jarfile.getName();
+ }
+
Manifest getManifest()
{
try
- {
+ {
return (jarfile == null) ? null : jarfile.getManifest();
- }
+ }
catch (IOException ioe)
- {
+ {
return null;
- }
+ }
}
}
- final static class JarURLResource extends Resource
+ static final class JarURLResource extends Resource
{
private final JarEntry entry;
@@ -358,12 +401,12 @@ public class URLClassLoader extends SecureClassLoader
InputStream getInputStream() throws IOException
{
- return ((JarURLLoader)loader).jarfile.getInputStream(entry);
+ return ((JarURLLoader) loader).jarfile.getInputStream(entry);
}
int getLength()
{
- return (int)entry.getSize();
+ return (int) entry.getSize();
}
Certificate[] getCertificates()
@@ -374,25 +417,25 @@ public class URLClassLoader extends SecureClassLoader
URL getURL()
{
try
- {
- return new URL(((JarURLLoader)loader).baseJarURL, name,
- loader.classloader.getURLStreamHandler("jar"));
- }
- catch(MalformedURLException e)
- {
+ {
+ return new URL(((JarURLLoader) loader).baseJarURL, name,
+ loader.classloader.getURLStreamHandler("jar"));
+ }
+ catch (MalformedURLException e)
+ {
InternalError ie = new InternalError();
ie.initCause(e);
throw ie;
- }
+ }
}
}
/**
* Loader for remote directories.
*/
- final static class RemoteURLLoader extends URLLoader
+ static final class RemoteURLLoader extends URLLoader
{
- final private String protocol;
+ private final String protocol;
RemoteURLLoader(URLClassLoader classloader, URL url)
{
@@ -407,9 +450,9 @@ public class URLClassLoader extends SecureClassLoader
Resource getResource(String name)
{
try
- {
- URL url = new URL(baseURL, name,
- classloader.getURLStreamHandler(protocol));
+ {
+ URL url =
+ new URL(baseURL, name, classloader.getURLStreamHandler(protocol));
URLConnection connection = url.openConnection();
// Open the connection and check the stream
@@ -420,9 +463,9 @@ public class URLClassLoader extends SecureClassLoader
// We can do some extra checking if it is a http request
if (connection instanceof HttpURLConnection)
{
- int response
- = ((HttpURLConnection)connection).getResponseCode();
- if (response/100 != 2)
+ int response =
+ ((HttpURLConnection) connection).getResponseCode();
+ if (response / 100 != 2)
return null;
}
@@ -430,25 +473,25 @@ public class URLClassLoader extends SecureClassLoader
return new RemoteResource(this, name, url, stream, length);
else
return null;
- }
+ }
catch (IOException ioe)
- {
+ {
return null;
- }
+ }
}
}
/**
* A resource from some remote location.
*/
- final static class RemoteResource extends Resource
+ static final class RemoteResource extends Resource
{
- final private URL url;
- final private InputStream stream;
- final private int length;
+ private final URL url;
+ private final InputStream stream;
+ private final int length;
RemoteResource(RemoteURLLoader loader, String name, URL url,
- InputStream stream, int length)
+ InputStream stream, int length)
{
super(loader, name);
this.url = url;
@@ -482,7 +525,12 @@ public class URLClassLoader extends SecureClassLoader
SoURLLoader(URLClassLoader classloader, URL url)
{
- super(classloader, url);
+ this(classloader, url, url);
+ }
+
+ SoURLLoader(URLClassLoader classloader, URL url, URL overrideURL)
+ {
+ super(classloader, url, overrideURL);
helper = SharedLibHelper.findHelper(classloader, url.getFile(),
noCertCodeSource);
}
@@ -533,9 +581,9 @@ public class URLClassLoader extends SecureClassLoader
* A <code>FileURLLoader</code> is a type of <code>URLLoader</code>
* only loading from file url.
*/
- final static class FileURLLoader extends URLLoader
+ static final class FileURLLoader extends URLLoader
{
- File dir; //the file for this file url
+ File dir; //the file for this file url
FileURLLoader(URLClassLoader classloader, URL url)
{
@@ -547,13 +595,13 @@ public class URLClassLoader extends SecureClassLoader
Resource getResource(String name)
{
File file = new File(dir, name);
- if (file.exists() && !file.isDirectory())
+ if (file.exists() && ! file.isDirectory())
return new FileResource(this, name, file);
return null;
}
}
- final static class FileResource extends Resource
+ static final class FileResource extends Resource
{
final File file;
@@ -567,28 +615,33 @@ public class URLClassLoader extends SecureClassLoader
{
return new FileInputStream(file);
}
-
+
public int getLength()
{
- return (int)file.length();
+ return (int) file.length();
+ }
+
+ public String toString ()
+ {
+ return "file " +file.getAbsolutePath();
}
public URL getURL()
{
try
- {
+ {
return new URL(loader.baseURL, name,
- loader.classloader.getURLStreamHandler("file"));
- }
- catch(MalformedURLException e)
- {
+ loader.classloader.getURLStreamHandler("file"));
+ }
+ catch (MalformedURLException e)
+ {
InternalError ie = new InternalError();
ie.initCause(e);
throw ie;
- }
+ }
}
}
-
+
// Constructors
/**
@@ -642,7 +695,7 @@ public class URLClassLoader extends SecureClassLoader
* load classes and resources (after using the supplied parent ClassLoader).
* @exception SecurityException if the SecurityManager disallows the
* creation of a ClassLoader.
- * @exception SecurityException
+ * @exception SecurityException
* @param urls Locations that should be searched by this ClassLoader when
* resolving Classes or Resources.
* @param parent The parent class loader used before trying this class
@@ -672,7 +725,7 @@ public class URLClassLoader extends SecureClassLoader
* @param securityContext the security context of the unprivileged code.
*/
private URLClassLoader(ClassLoader parent,
- AccessControlContext securityContext)
+ AccessControlContext securityContext)
{
super(parent);
this.factory = null;
@@ -690,7 +743,7 @@ public class URLClassLoader extends SecureClassLoader
* protocol handlers of the supplied URLs.
* @exception SecurityException if the SecurityManager disallows the
* creation of a ClassLoader.
- * @exception SecurityException
+ * @exception SecurityException
* @param urls Locations that should be searched by this ClassLoader when
* resolving Classes or Resources.
* @param parent The parent class loader used before trying this class
@@ -698,9 +751,8 @@ public class URLClassLoader extends SecureClassLoader
* @param factory Used to get the protocol handler for the URLs.
* @see SecureClassLoader
*/
- public URLClassLoader(URL[] urls,
- ClassLoader parent,
- URLStreamHandlerFactory factory)
+ public URLClassLoader(URL[] urls, ClassLoader parent,
+ URLStreamHandlerFactory factory)
throws SecurityException
{
super(parent);
@@ -711,7 +763,7 @@ public class URLClassLoader extends SecureClassLoader
// If this factory is still not in factoryCache, add it,
// since we only support three protocols so far, 5 is enough
// for cache initial size
- synchronized(factoryCache)
+ synchronized (factoryCache)
{
if (factory != null && factoryCache.get(factory) == null)
factoryCache.put(factory, new HashMap(5));
@@ -731,14 +783,14 @@ public class URLClassLoader extends SecureClassLoader
private void addURLImpl(URL newUrl)
{
- synchronized(urlloaders)
+ synchronized (urlloaders)
{
if (newUrl == null)
return; // Silently ignore...
-
+
// Check global cache to see if there're already url loader
// for this url.
- URLLoader loader = (URLLoader)urlloaders.get(newUrl);
+ URLLoader loader = (URLLoader) urlloaders.get(newUrl);
if (loader == null)
{
String file = newUrl.getFile();
@@ -769,12 +821,10 @@ public class URLClassLoader extends SecureClassLoader
private void addURLs(URL[] newUrls)
{
for (int i = 0; i < newUrls.length; i++)
- {
addURLImpl(newUrls[i]);
- }
}
- /**
+ /**
* Defines a Package based on the given name and the supplied manifest
* information. The manifest indicates the tile, version and
* vendor information of the specification and implementation and wheter the
@@ -789,22 +839,16 @@ public class URLClassLoader extends SecureClassLoader
* @param url the code source url to seal the package
* @return the defined Package
*/
- protected Package definePackage(String name, Manifest manifest, URL url)
+ protected Package definePackage(String name, Manifest manifest, URL url)
throws IllegalArgumentException
{
Attributes attr = manifest.getMainAttributes();
- String specTitle =
- attr.getValue(Attributes.Name.SPECIFICATION_TITLE);
- String specVersion =
- attr.getValue(Attributes.Name.SPECIFICATION_VERSION);
- String specVendor =
- attr.getValue(Attributes.Name.SPECIFICATION_VENDOR);
- String implTitle =
- attr.getValue(Attributes.Name.IMPLEMENTATION_TITLE);
- String implVersion =
- attr.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
- String implVendor =
- attr.getValue(Attributes.Name.IMPLEMENTATION_VENDOR);
+ String specTitle = attr.getValue(Attributes.Name.SPECIFICATION_TITLE);
+ String specVersion = attr.getValue(Attributes.Name.SPECIFICATION_VERSION);
+ String specVendor = attr.getValue(Attributes.Name.SPECIFICATION_VENDOR);
+ String implTitle = attr.getValue(Attributes.Name.IMPLEMENTATION_TITLE);
+ String implVersion = attr.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
+ String implVendor = attr.getValue(Attributes.Name.IMPLEMENTATION_VENDOR);
// Look if the Manifest indicates that this package is sealed
// XXX - most likely not completely correct!
@@ -813,13 +857,11 @@ public class URLClassLoader extends SecureClassLoader
// But how do we get that jar manifest here?
String sealed = attr.getValue(Attributes.Name.SEALED);
if ("false".equals(sealed))
- {
// make sure that the URL is null so the package is not sealed
url = null;
- }
- return definePackage(name, specTitle, specVersion, specVendor,
- implTitle, implVersion, implVendor, url);
+ return definePackage(name, specTitle, specVersion, specVendor, implTitle,
+ implVersion, implVendor, url);
}
/**
@@ -857,7 +899,7 @@ public class URLClassLoader extends SecureClassLoader
// construct the class (and watch out for those nasty IOExceptions)
try
{
- byte [] data;
+ byte[] data;
InputStream in = resource.getInputStream();
int length = resource.getLength();
if (length != -1)
@@ -894,24 +936,24 @@ public class URLClassLoader extends SecureClassLoader
// Now get the CodeSource
final CodeSource source = resource.getCodeSource();
-
+
// Find out package name
String packageName = null;
int lastDot = className.lastIndexOf('.');
if (lastDot != -1)
packageName = className.substring(0, lastDot);
-
+
if (packageName != null && getPackage(packageName) == null)
{
// define the package
Manifest manifest = resource.loader.getManifest();
if (manifest == null)
- definePackage(packageName,
- null, null, null, null, null, null, null);
+ definePackage(packageName, null, null, null, null, null, null,
+ null);
else
definePackage(packageName, manifest, resource.loader.baseURL);
}
-
+
// And finally construct the class!
SecurityManager sm = System.getSecurityManager();
if (sm != null && securityContext != null)
@@ -928,9 +970,7 @@ public class URLClassLoader extends SecureClassLoader
}, securityContext);
}
else
- return defineClass(className, classData,
- 0, classData.length,
- source);
+ return defineClass(className, classData, 0, classData.length, source);
}
catch (IOException ioe)
{
@@ -950,10 +990,10 @@ public class URLClassLoader extends SecureClassLoader
int max = urls.size();
for (int i = 0; i < max; i++)
{
- URLLoader loader = (URLLoader)urlinfos.elementAt(i);
+ URLLoader loader = (URLLoader) urlinfos.elementAt(i);
if (loader == null)
continue;
-
+
Resource resource = loader.getResource(resourceName);
if (resource != null)
return resource;
@@ -972,7 +1012,7 @@ public class URLClassLoader extends SecureClassLoader
Resource resource = findURLResource(resourceName);
if (resource != null)
return resource.getURL();
-
+
// Resource not found
return null;
}
@@ -993,9 +1033,9 @@ public class URLClassLoader extends SecureClassLoader
synchronized (factoryCache)
{
// Check if there're handler for the same protocol in cache.
- HashMap cache = (HashMap)factoryCache.get(factory);
- handler = (URLStreamHandler)cache.get(protocol);
- if(handler == null)
+ HashMap cache = (HashMap) factoryCache.get(factory);
+ handler = (URLStreamHandler) cache.get(protocol);
+ if (handler == null)
{
// Add it to cache.
handler = factory.createURLStreamHandler(protocol);
@@ -1014,13 +1054,14 @@ public class URLClassLoader extends SecureClassLoader
* @return a (possible empty) enumeration of URLs where the resource can be
* found
*/
- public Enumeration findResources(String resourceName) throws IOException
+ public Enumeration findResources(String resourceName)
+ throws IOException
{
Vector resources = new Vector();
int max = urls.size();
for (int i = 0; i < max; i++)
{
- URLLoader loader = (URLLoader)urlinfos.elementAt(i);
+ URLLoader loader = (URLLoader) urlinfos.elementAt(i);
Resource resource = loader.getResource(resourceName);
if (resource != null)
resources.add(resource.getURL());
@@ -1052,16 +1093,16 @@ public class URLClassLoader extends SecureClassLoader
{
// XXX - This implementation does exactly as the Javadoc describes.
// But maybe we should/could use URLConnection.getPermissions()?
-
// First get the permissions that would normally be granted
PermissionCollection permissions = super.getPermissions(source);
-
+
// Now add any extra permissions depending on the URL location.
URL url = source.getLocation();
String protocol = url.getProtocol();
if (protocol.equals("file"))
{
String file = url.getFile();
+
// If the file end in / it must be an directory.
if (file.endsWith("/") || file.endsWith(File.separator))
{
@@ -1086,7 +1127,7 @@ public class URLClassLoader extends SecureClassLoader
return permissions;
}
-
+
/**
* Returns all the locations that this class loader currently uses the
* resolve classes and resource. This includes both the initially supplied
@@ -1109,7 +1150,7 @@ public class URLClassLoader extends SecureClassLoader
* @exception SecurityException when the calling code does not have
* permission to access the given <code>URL</code>s
*/
- public static URLClassLoader newInstance(URL urls[])
+ public static URLClassLoader newInstance(URL[] urls)
throws SecurityException
{
return newInstance(urls, null);
@@ -1127,8 +1168,7 @@ public class URLClassLoader extends SecureClassLoader
* @exception SecurityException when the calling code does not have
* permission to access the given <code>URL</code>s
*/
- public static URLClassLoader newInstance(URL urls[],
- final ClassLoader parent)
+ public static URLClassLoader newInstance(URL[] urls, final ClassLoader parent)
throws SecurityException
{
SecurityManager sm = System.getSecurityManager();
@@ -1137,21 +1177,21 @@ public class URLClassLoader extends SecureClassLoader
else
{
final Object securityContext = sm.getSecurityContext();
+
// XXX - What to do with anything else then an AccessControlContext?
- if (!(securityContext instanceof AccessControlContext))
- throw new SecurityException
- ("securityContext must be AccessControlContext: "
- + securityContext);
-
+ if (! (securityContext instanceof AccessControlContext))
+ throw new SecurityException("securityContext must be AccessControlContext: "
+ + securityContext);
+
URLClassLoader loader =
- (URLClassLoader)AccessController.doPrivileged(new PrivilegedAction()
- {
- public Object run()
+ (URLClassLoader) AccessController.doPrivileged(new PrivilegedAction()
{
- return new URLClassLoader
- (parent, (AccessControlContext)securityContext);
- }
- });
+ public Object run()
+ {
+ return new URLClassLoader(parent,
+ (AccessControlContext) securityContext);
+ }
+ });
loader.addURLs(urls);
return loader;
}
diff --git a/libjava/java/net/URLConnection.java b/libjava/java/net/URLConnection.java
index 6d63610be47..867a53450c8 100644
--- a/libjava/java/net/URLConnection.java
+++ b/libjava/java/net/URLConnection.java
@@ -7,7 +7,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -35,11 +35,10 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.net;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
import java.security.AllPermission;
import java.security.Permission;
@@ -53,13 +52,13 @@ import java.util.Map;
import java.util.StringTokenizer;
import gnu.gcj.io.MimeTypes;
+
/**
* Written using on-line Java Platform 1.2 API Specification, as well
* as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
* Status: One guessContentTypeFrom... methods not implemented.
* getContent method assumes content type from response; see comment there.
*/
-
/**
* This class models a connection that retrieves the information pointed
* to by a URL object. This is typically a connection to a remote node
@@ -99,18 +98,18 @@ public abstract class URLConnection
* instance and store it here.
*/
private static FileNameMap fileNameMap;
-
+
/**
* This is the ContentHandlerFactory set by the caller, if any
*/
private static ContentHandlerFactory factory;
-
+
/**
* This is the default value that will be used to determine whether or
* not user interaction should be allowed.
*/
- private static boolean defaultAllowUserInteraction = false;
-
+ private static boolean defaultAllowUserInteraction;
+
/**
* This is the default flag indicating whether or not to use caches to
* store the data returned from a server
@@ -127,18 +126,18 @@ public abstract class URLConnection
* Indicates whether or not a connection has been established to the
* destination specified in the URL
*/
- protected boolean connected = false;
-
+ protected boolean connected;
+
/**
* Indicates whether or not input can be read from this URL
*/
protected boolean doInput = true;
-
+
/**
* Indicates whether or not output can be sent to this URL
*/
- protected boolean doOutput = false;
-
+ protected boolean doOutput;
+
/**
* If this flag is set, the protocol is allowed to cache data whenever
* it can (caching is not guaranteed). If it is not set, the protocol
@@ -158,7 +157,7 @@ public abstract class URLConnection
* modified more recently than the date set in this variable. That date
* should be specified as the number of seconds since 1/1/1970 GMT.
*/
- protected long ifModifiedSince = 0L;
+ protected long ifModifiedSince;
/**
* This is the URL associated with this connection
@@ -166,8 +165,10 @@ public abstract class URLConnection
protected URL url;
private static Hashtable handlers = new Hashtable();
- private static SimpleDateFormat dateFormat1, dateFormat2, dateFormat3;
- private static boolean dateformats_initialized = false;
+ private static SimpleDateFormat dateFormat1;
+ private static SimpleDateFormat dateFormat2;
+ private static SimpleDateFormat dateFormat3;
+ private static boolean dateformats_initialized;
/**
* Creates a URL connection to a given URL. A real connection is not made.
@@ -188,6 +189,8 @@ public abstract class URLConnection
/**
* Establishes the actual connection to the URL associated with this
* connection object
+ *
+ * @exception IOException if an error occurs
*/
public abstract void connect() throws IOException;
@@ -230,7 +233,7 @@ public abstract class URLConnection
/**
* Returns the value of the content-encoding field or null if it is not
* known or not present.
- *
+ *
* @return The content-encoding field
*/
public String getContentEncoding()
@@ -295,7 +298,7 @@ public abstract class URLConnection
* Returns a String representing the value of the header field having
* the named key. Returns null if the header field does not exist.
*
- * @param The key of the header field
+ * @param name The key of the header field
*
* @return The value of the header field as a String
*/
@@ -307,7 +310,9 @@ public abstract class URLConnection
/**
* Returns a map of all sent header fields
- *
+ *
+ * @return all header fields
+ *
* @since 1.4
*/
public Map getHeaderFields()
@@ -330,18 +335,18 @@ public abstract class URLConnection
*/
public int getHeaderFieldInt(String name, int defaultValue)
{
- String value = getHeaderField (name);
-
+ String value = getHeaderField(name);
+
if (value == null)
return defaultValue;
try
{
- return Integer.parseInt (value);
+ return Integer.parseInt(value);
}
- catch (NumberFormatException e)
- {
- return defaultValue;
+ catch (NumberFormatException e)
+ {
+ return defaultValue;
}
}
@@ -357,25 +362,25 @@ public abstract class URLConnection
* @return Returns the date value of the header filed or the default value
* if the field is missing or malformed
*/
- public long getHeaderFieldDate (String name, long defaultValue)
+ public long getHeaderFieldDate(String name, long defaultValue)
{
if (! dateformats_initialized)
- initializeDateFormats ();
-
+ initializeDateFormats();
+
long result = defaultValue;
- String str = getHeaderField (name);
-
+ String str = getHeaderField(name);
+
if (str != null)
{
Date date;
- if ((date = dateFormat1.parse (str, new ParsePosition (0))) != null)
- result = date.getTime ();
- else if ((date = dateFormat2.parse (str, new ParsePosition (0))) != null)
- result = date.getTime ();
- else if ((date = dateFormat3.parse (str, new ParsePosition (0))) != null)
- result = date.getTime ();
+ if ((date = dateFormat1.parse(str, new ParsePosition(0))) != null)
+ result = date.getTime();
+ else if ((date = dateFormat2.parse(str, new ParsePosition(0))) != null)
+ result = date.getTime();
+ else if ((date = dateFormat3.parse(str, new ParsePosition(0))) != null)
+ result = date.getTime();
}
-
+
return result;
}
@@ -385,12 +390,12 @@ public abstract class URLConnection
* getHeaderField(int) method allows access to the corresponding value for
* this tag.
*
- * @param index The index into the header field list to retrieve the key for.
+ * @param index The index into the header field list to retrieve the key for.
*
* @return The header field key or null if index is past the end
* of the headers.
*/
- public String getHeaderFieldKey (int index)
+ public String getHeaderFieldKey(int index)
{
// Subclasses for specific protocols override this.
return null;
@@ -407,7 +412,7 @@ public abstract class URLConnection
* This class first determines the MIME type of the content, then creates
* a ContentHandler object to process the input. If the ContentHandlerFactory
* is set, then that object is called to load a content handler, otherwise
- * a class called gnu.java.net.content.<content_type> is tried.
+ * a class called gnu.java.net.content.&lt;content_type&gt; is tried.
* The default class will also be used if the content handler factory returns
* a null content handler.
*
@@ -436,6 +441,8 @@ public abstract class URLConnection
/**
* Retrieves the content of this URLConnection
*
+ * @param classes The allowed classes for the content
+ *
* @exception IOException If an error occurs
* @exception UnknownServiceException If the protocol does not support the
* content type
@@ -443,7 +450,7 @@ public abstract class URLConnection
public Object getContent(Class[] classes) throws IOException
{
// FIXME: implement this
- return getContent ();
+ return getContent();
}
/**
@@ -480,8 +487,8 @@ public abstract class URLConnection
public InputStream getInputStream() throws IOException
{
// Subclasses for specific protocols override this.
- throw new UnknownServiceException("Protocol " + url.getProtocol() +
- " does not support input.");
+ throw new UnknownServiceException("Protocol " + url.getProtocol()
+ + " does not support input.");
}
/**
@@ -496,14 +503,14 @@ public abstract class URLConnection
public OutputStream getOutputStream() throws IOException
{
// Subclasses for specific protocols override this.
- throw new UnknownServiceException("Protocol " + url.getProtocol() +
- " does not support output.");
+ throw new UnknownServiceException("Protocol " + url.getProtocol()
+ + " does not support output.");
}
/**
* The methods prints the value of this object as a String by calling the
* toString() method of its associated URL. Overrides Object.toString()
- *
+ *
* @return A String representation of this object
*/
public String toString()
@@ -515,7 +522,7 @@ public abstract class URLConnection
* Returns the value of a flag indicating whether or not input is going
* to be done for this connection. This default to true unless the
* doOutput flag is set to false, in which case this defaults to false.
- *
+ *
* @param input <code>true</code> if input is to be done,
* <code>false</code> otherwise
*
@@ -524,7 +531,7 @@ public abstract class URLConnection
public void setDoInput(boolean input)
{
if (connected)
- throw new IllegalStateException ("Already connected");
+ throw new IllegalStateException("Already connected");
doInput = input;
}
@@ -553,7 +560,7 @@ public abstract class URLConnection
public void setDoOutput(boolean output)
{
if (connected)
- throw new IllegalStateException ("Already connected");
+ throw new IllegalStateException("Already connected");
doOutput = output;
}
@@ -628,7 +635,7 @@ public abstract class URLConnection
public void setUseCaches(boolean usecaches)
{
if (connected)
- throw new IllegalStateException ("Already connected");
+ throw new IllegalStateException("Already connected");
useCaches = usecaches;
}
@@ -659,7 +666,7 @@ public abstract class URLConnection
public void setIfModifiedSince(long ifmodifiedsince)
{
if (connected)
- throw new IllegalStateException ("Already connected");
+ throw new IllegalStateException("Already connected");
ifModifiedSince = ifmodifiedsince;
}
@@ -695,9 +702,9 @@ public abstract class URLConnection
*
* @param use true to use caches if possible by default, false otherwise
*/
- public void setDefaultUseCaches(boolean defaultusecaches)
+ public void setDefaultUseCaches(boolean use)
{
- defaultUseCaches = defaultusecaches;
+ defaultUseCaches = use;
}
/**
@@ -705,23 +712,23 @@ public abstract class URLConnection
*
* @param key The name of the property
* @param value The value of the property
- *
+ *
* @exception IllegalStateException If already connected
* @exception NullPointerException If key is null
*
* @see URLConnection#getRequestProperty(String key)
* @see URLConnection#addRequestProperty(String key, String value)
- *
+ *
* @since 1.4
*/
public void setRequestProperty(String key, String value)
{
if (connected)
- throw new IllegalStateException ("Already connected");
+ throw new IllegalStateException("Already connected");
if (key == null)
- throw new NullPointerException ("key is null");
-
+ throw new NullPointerException("key is null");
+
// Do nothing unless overridden by subclasses that support setting
// header fields in the request.
}
@@ -735,20 +742,20 @@ public abstract class URLConnection
*
* @exception IllegalStateException If already connected
* @exception NullPointerException If key is null
- *
+ *
* @see URLConnection#getRequestProperty(String key)
* @see URLConnection#setRequestProperty(String key, String value)
- *
+ *
* @since 1.4
*/
public void addRequestProperty(String key, String value)
{
if (connected)
- throw new IllegalStateException ("Already connected");
+ throw new IllegalStateException("Already connected");
if (key == null)
- throw new NullPointerException ("key is null");
-
+ throw new NullPointerException("key is null");
+
// Do nothing unless overridden by subclasses that support adding
// header fields in the request.
}
@@ -768,7 +775,7 @@ public abstract class URLConnection
public String getRequestProperty(String key)
{
if (connected)
- throw new IllegalStateException ("Already connected");
+ throw new IllegalStateException("Already connected");
// Overridden by subclasses that support reading header fields from the
// request.
@@ -787,7 +794,7 @@ public abstract class URLConnection
public Map getRequestProperties()
{
if (connected)
- throw new IllegalStateException ("Already connected");
+ throw new IllegalStateException("Already connected");
// Overridden by subclasses that support reading header fields from the
// request.
@@ -807,7 +814,7 @@ public abstract class URLConnection
*
* @see URLConnection#setRequestProperty(String key, String value)
*/
- public static void setDefaultRequestProperty (String key, String value)
+ public static void setDefaultRequestProperty(String key, String value)
{
// This method does nothing since JDK 1.3.
}
@@ -820,7 +827,7 @@ public abstract class URLConnection
* @param key The request property to return the default value of
*
* @return The value of the default property or null if not available
- *
+ *
* @deprecated 1.3 The method getRequestProperty should be used instead.
* This method does nothing now.
*
@@ -844,10 +851,9 @@ public abstract class URLConnection
* @exception SecurityException If a security manager exists and its
* checkSetFactory method doesn't allow the operation
*/
- public static synchronized void setContentHandlerFactory
- (ContentHandlerFactory fac)
+ public static synchronized void setContentHandlerFactory(ContentHandlerFactory factory)
{
- if (factory != null)
+ if (URLConnection.factory != null)
throw new Error("ContentHandlerFactory already set");
// Throw an exception if an extant security mgr precludes
@@ -856,7 +862,7 @@ public abstract class URLConnection
if (s != null)
s.checkSetFactory();
- factory = fac;
+ URLConnection.factory = factory;
}
/**
@@ -895,7 +901,7 @@ public abstract class URLConnection
* Returns the MIME type of a stream based on the first few characters
* at the beginning of the stream. This routine can be used to determine
* the MIME type if a server is believed to be returning an incorrect
- * MIME type. This method returns "application/octet-stream" if it
+ * MIME type. This method returns "application/octet-stream" if it
* cannot determine the MIME type.
* <p>
* NOTE: Overriding MIME types sent from the server can be obnoxious
@@ -937,7 +943,7 @@ public abstract class URLConnection
*
* @exception SecurityException If a security manager exists and its
* checkSetFactory method doesn't allow the operation
- *
+ *
* @since 1.2
*/
public static void setFileNameMap(FileNameMap map)
@@ -987,7 +993,6 @@ public abstract class URLConnection
// Replace the '/' character in the content type with '.' and
// all other non-alphabetic, non-numeric characters with '_'.
- StringTokenizer pkgPrefix = new StringTokenizer(propVal, "|");
char[] cArray = contentType.toCharArray();
for (int i = 0; i < cArray.length; i++)
{
@@ -1001,6 +1006,7 @@ public abstract class URLConnection
String contentClass = new String(cArray);
// See if a class of this content type exists in any of the packages.
+ StringTokenizer pkgPrefix = new StringTokenizer(propVal, "|");
do
{
String facName = pkgPrefix.nextToken() + "." + contentClass;
@@ -1040,10 +1046,10 @@ public abstract class URLConnection
return;
Locale locale = new Locale("En", "Us", "Unix");
- dateFormat1 = new SimpleDateFormat("EEE, dd MMM yyyy hh:mm:ss 'GMT'",
- locale);
- dateFormat2 = new SimpleDateFormat("EEEE, dd-MMM-yy hh:mm:ss 'GMT'",
- locale);
+ dateFormat1 =
+ new SimpleDateFormat("EEE, dd MMM yyyy hh:mm:ss 'GMT'", locale);
+ dateFormat2 =
+ new SimpleDateFormat("EEEE, dd-MMM-yy hh:mm:ss 'GMT'", locale);
dateFormat3 = new SimpleDateFormat("EEE MMM d hh:mm:ss yyyy", locale);
dateformats_initialized = true;
}
diff --git a/libjava/java/net/URLDecoder.java b/libjava/java/net/URLDecoder.java
index 4fe77d3c933..d2c403a585f 100644
--- a/libjava/java/net/URLDecoder.java
+++ b/libjava/java/net/URLDecoder.java
@@ -7,7 +7,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -39,8 +39,9 @@ package java.net;
import java.io.UnsupportedEncodingException;
+
/**
- * This utility class contains static methods that converts a
+ * This utility class contains static methods that converts a
* string encoded in the x-www-form-urlencoded format to the original
* text. The x-www-form-urlencoded format replaces certain disallowed
* characters with encoded equivalents. All upper case and lower case
@@ -65,7 +66,7 @@ public class URLDecoder
/**
* Public contructor. Note that this class has only static methods.
*/
- public URLDecoder ()
+ public URLDecoder()
{
}
@@ -84,12 +85,12 @@ public class URLDecoder
{
try
{
- return decode(s, "UTF-8");
+ return decode(s, "UTF-8");
}
catch (UnsupportedEncodingException uee)
{
- // Should never happen since UTF-8 encoding should always be supported
- return s;
+ // Should never happen since UTF-8 encoding should always be supported
+ return s;
}
}
@@ -120,7 +121,7 @@ public class URLDecoder
{
// First convert all '+' characters to spaces.
String str = s.replace('+', ' ');
-
+
// Then go through the whole string looking for byte encoded characters
int i;
int start = 0;
@@ -134,12 +135,12 @@ public class URLDecoder
start = i;
// Get all consecutive encoded bytes
- while ((i+2 < length) && (str.charAt(i) == '%'))
+ while ((i + 2 < length) && (str.charAt(i) == '%'))
i += 3;
// Decode all these bytes
- if ((bytes == null) || (bytes.length < ((i-start)/3)))
- bytes = new byte[((i-start)/3)];
+ if ((bytes == null) || (bytes.length < ((i - start) / 3)))
+ bytes = new byte[((i - start) / 3)];
int index = 0;
try
@@ -147,7 +148,7 @@ public class URLDecoder
while (start < i)
{
String sub = str.substring(start + 1, start + 3);
- bytes[index] = (byte)Integer.parseInt(sub, 16);
+ bytes[index] = (byte) Integer.parseInt(sub, 16);
index++;
start += 3;
}
@@ -176,5 +177,4 @@ public class URLDecoder
return result.toString();
}
-
} // class URLDecoder
diff --git a/libjava/java/net/URLEncoder.java b/libjava/java/net/URLEncoder.java
index 24d0d25b6d8..fbabb0f89b8 100644
--- a/libjava/java/net/URLEncoder.java
+++ b/libjava/java/net/URLEncoder.java
@@ -7,7 +7,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -39,29 +39,30 @@ package java.net;
import java.io.UnsupportedEncodingException;
+
/*
* Written using on-line Java Platform 1.2/1.4 API Specification, as well
* as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
* Status: Believed complete and correct.
*/
- /**
- * This utility class contains static methods that converts a
- * string into a fully encoded URL string in x-www-form-urlencoded
- * format. This format replaces certain disallowed characters with
- * encoded equivalents. All upper case and lower case letters in the
- * US alphabet remain as is, the space character (' ') is replaced with
- * '+' sign, and all other characters are converted to a "%XX" format
- * where XX is the hexadecimal representation of that character in a
- * certain encoding (by default, the platform encoding, though the
- * standard is "UTF-8").
- * <p>
- * This method is very useful for encoding strings to be sent to CGI scripts
- *
- * @author Aaron M. Renn (arenn@urbanophile.com)
- * @author Warren Levy <warrenl@cygnus.com>
- * @author Mark Wielaard (mark@klomp.org)
- */
+/**
+ * This utility class contains static methods that converts a
+ * string into a fully encoded URL string in x-www-form-urlencoded
+ * format. This format replaces certain disallowed characters with
+ * encoded equivalents. All upper case and lower case letters in the
+ * US alphabet remain as is, the space character (' ') is replaced with
+ * '+' sign, and all other characters are converted to a "%XX" format
+ * where XX is the hexadecimal representation of that character in a
+ * certain encoding (by default, the platform encoding, though the
+ * standard is "UTF-8").
+ * <p>
+ * This method is very useful for encoding strings to be sent to CGI scripts
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @author Mark Wielaard (mark@klomp.org)
+ */
public class URLEncoder
{
/**
@@ -82,11 +83,11 @@ public class URLEncoder
{
// We default to 8859_1 for compatibility with the same
// default elsewhere in the library.
- return encode(s, System.getProperty("file.encoding", "8859_1"));
+ return encode(s, System.getProperty("file.encoding", "8859_1"));
}
catch (UnsupportedEncodingException uee)
{
- // Should never happen since default should always be supported
+ // Should never happen since default should always be supported
return s;
}
}
@@ -114,42 +115,42 @@ public class URLEncoder
StringBuffer result = new StringBuffer(length);
while (true)
- {
- while ( i < length && isSafe(s.charAt(i)) )
- i++;
-
- // Safe character can just be added
- result.append(s.substring(start, i));
-
- // Are we done?
- if (i >= length)
- return result.toString();
- else if (s.charAt(i) == ' ')
- {
- result.append('+'); // Replace space char with plus symbol.
+ {
+ while (i < length && isSafe(s.charAt(i)))
i++;
- }
- else
- {
- // Get all unsafe characters
- start = i;
- char c;
- while ( i < length && (c = s.charAt(i)) != ' ' && !isSafe(c) )
- i++;
- // Convert them to %XY encoded strings
- String unsafe = s.substring(start,i);
- byte bytes[] = unsafe.getBytes(encoding);
- for (int j = 0; j < bytes.length; j++)
- {
- result.append('%');
- int val = bytes[j];
- result.append(hex.charAt((val & 0xf0) >> 4));
- result.append(hex.charAt(val & 0x0f));
- }
- }
- start = i;
- }
+ // Safe character can just be added
+ result.append(s.substring(start, i));
+
+ // Are we done?
+ if (i >= length)
+ return result.toString();
+ else if (s.charAt(i) == ' ')
+ {
+ result.append('+'); // Replace space char with plus symbol.
+ i++;
+ }
+ else
+ {
+ // Get all unsafe characters
+ start = i;
+ char c;
+ while (i < length && (c = s.charAt(i)) != ' ' && ! isSafe(c))
+ i++;
+
+ // Convert them to %XY encoded strings
+ String unsafe = s.substring(start, i);
+ byte[] bytes = unsafe.getBytes(encoding);
+ for (int j = 0; j < bytes.length; j++)
+ {
+ result.append('%');
+ int val = bytes[j];
+ result.append(hex.charAt((val & 0xf0) >> 4));
+ result.append(hex.charAt(val & 0x0f));
+ }
+ }
+ start = i;
+ }
}
/**
@@ -160,17 +161,18 @@ public class URLEncoder
*/
private static boolean isSafe(char c)
{
- return ((c >= 'a' && c <= 'z') ||
- (c >= 'A' && c <= 'Z') ||
- (c >= '0' && c <= '9') ||
- c == '-' || c == '_' || c == '.' || c == '*');
+ return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
+ || (c >= '0' && c <= '9') || c == '-' || c == '_' || c == '.'
+ || c == '*');
}
/**
* Private constructor that does nothing. Included to avoid a default
* public constructor being created by the compiler.
*/
- private URLEncoder() { }
+ private URLEncoder()
+ {
+ }
/**
* Used to convert to hex. We don't use Integer.toHexString, since
@@ -179,4 +181,4 @@ public class URLEncoder
* leading 0.
*/
private static final String hex = "0123456789ABCDEF";
-} // class URLEncoder
+}
diff --git a/libjava/java/net/URLStreamHandler.java b/libjava/java/net/URLStreamHandler.java
index af4335f4f44..d224ff556e9 100644
--- a/libjava/java/net/URLStreamHandler.java
+++ b/libjava/java/net/URLStreamHandler.java
@@ -7,7 +7,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -35,11 +35,11 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.net;
-import java.io.IOException;
import java.io.File;
+import java.io.IOException;
+
/*
* Written using on-line Java Platform 1.2 API Specification, as well
@@ -57,7 +57,7 @@ import java.io.File;
* A protocol handler implementation should override the openConnection()
* method, and optionally override the parseURL() and toExternalForm()
* methods if necessary. (The default implementations will parse/write all
- * URL's in the same form as http URL's). A protocol specific subclass
+ * URL's in the same form as http URL's). A protocol specific subclass
* of URLConnection will most likely need to be created as well.
* <p>
* Note that the instance methods in this class are called as if they
@@ -71,7 +71,7 @@ import java.io.File;
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Warren Levy (warrenl@cygnus.com)
- *
+ *
* @see URL
*/
public abstract class URLStreamHandler
@@ -79,7 +79,7 @@ public abstract class URLStreamHandler
/**
* Creates a URLStreamHander
*/
- public URLStreamHandler ()
+ public URLStreamHandler()
{
}
@@ -96,7 +96,7 @@ public abstract class URLStreamHandler
*
* @exception IOException If an error occurs
*/
- protected abstract URLConnection openConnection(URL u)
+ protected abstract URLConnection openConnection(URL url)
throws IOException;
/**
@@ -109,8 +109,8 @@ public abstract class URLStreamHandler
* position of the "#" character, which separates the "file" portion of
* the URL from the "anchor" portion.
* <p>
- * This method assumes URL's are formatted like http protocol URL's, so
- * subclasses that implement protocols with URL's the follow a different
+ * This method assumes URL's are formatted like http protocol URL's, so
+ * subclasses that implement protocols with URL's the follow a different
* syntax should override this method. The lone exception is that if
* the protocol name set in the URL is "file", this method will accept
* an empty hostname (i.e., "file:///"), which is legal for that protocol
@@ -126,28 +126,39 @@ public abstract class URLStreamHandler
int port = url.getPort();
String file = url.getFile();
String ref = url.getRef();
+ String userInfo = url.getUserInfo();
+ String authority = url.getAuthority();
+ String query = null;
- if (spec.regionMatches (start, "//", 0, 2))
+ // On Windows we need to change \ to / for file URLs
+ if (url.getProtocol().equals("file"))
+ spec = spec.replace(File.separatorChar, '/');
+
+ if (spec.regionMatches(start, "//", 0, 2))
{
String genuineHost;
int hostEnd;
- int colon, at_host;
+ int colon;
+ int at_host;
start += 2;
- int slash = spec.indexOf ('/', start);
- if (slash >= 0)
+ int slash = spec.indexOf('/', start);
+ if (slash >= 0)
hostEnd = slash;
- else
+ else
hostEnd = end;
- host = spec.substring (start, hostEnd);
-
+ authority = host = spec.substring(start, hostEnd);
+
// We first need a genuine host name (with userinfo).
// So we check for '@': if it's present check the port in the
// section after '@' in the other case check it in the full string.
// P.S.: We don't care having '@' at the beginning of the string.
- if ((at_host = host.indexOf ('@')) >= 0)
- genuineHost = host.substring (at_host);
+ if ((at_host = host.indexOf('@')) >= 0)
+ {
+ genuineHost = host.substring(at_host);
+ userInfo = host.substring(0, at_host);
+ }
else
genuineHost = host;
@@ -157,70 +168,63 @@ public abstract class URLStreamHandler
// this is undocumented and likely an unintended side effect in 1.2
// so we'll be simple here and stick with "". Note that
// "http://" or "http:///" produce a "" host in JDK 1.2.
- if ((colon = genuineHost.indexOf (':')) >= 0)
+ if ((colon = genuineHost.indexOf(':')) >= 0)
{
try
{
- port = Integer.parseInt (genuineHost.substring (colon + 1));
+ port = Integer.parseInt(genuineHost.substring(colon + 1));
}
catch (NumberFormatException e)
{
; // Ignore invalid port values; port is already set to u's
// port.
}
+
// Now we must cut the port number in the original string.
if (at_host >= 0)
- host = host.substring (0, at_host + colon);
+ host = host.substring(0, at_host + colon);
else
- host = host.substring (0, colon);
+ host = host.substring(0, colon);
}
file = null;
start = hostEnd;
- }
- else if (host == null)
+ }
+ else if (host == null)
host = "";
if (file == null || file.length() == 0
- || (start < end && spec.charAt(start) == '/'))
+ || (start < end && spec.charAt(start) == '/'))
{
// No file context available; just spec for file.
// Or this is an absolute path name; ignore any file context.
file = spec.substring(start, end);
ref = null;
- }
+ }
else if (start < end)
{
- // Context is available, but only override it if there is a new file.
- char sepChar = '/';
- int lastSlash = file.lastIndexOf (sepChar);
- if (lastSlash < 0 && File.separatorChar != sepChar
- && url.getProtocol ().equals ("file"))
- {
- // On Windows, even '\' is allowed in a "file" URL.
- sepChar = File.separatorChar;
- lastSlash = file.lastIndexOf (sepChar);
- }
-
- file = file.substring(0, lastSlash)
- + sepChar + spec.substring (start, end);
-
- if (url.getProtocol ().equals ("file"))
- {
- // For "file" URLs constructed relative to a context, we
- // need to canonicalise the file path.
- try
- {
+ // Context is available, but only override it if there is a new file.
+ int lastSlash = file.lastIndexOf('/');
+
+ file =
+ file.substring(0, lastSlash) + '/' + spec.substring(start, end);
+
+ if (url.getProtocol().equals("file"))
+ {
+ // For "file" URLs constructed relative to a context, we
+ // need to canonicalise the file path.
+ try
+ {
boolean endsWithSlash = file.charAt(file.length() - 1) == '/';
- file = new File (file).getCanonicalPath ();
- if (endsWithSlash
- && file.charAt(file.length() - 1) != '/')
+ file = new File(file).getCanonicalPath();
+ file = file.replace(File.separatorChar, '/');
+ if (endsWithSlash && file.charAt(file.length() - 1) != '/')
file += '/';
- }
- catch (IOException e)
- {
+ }
+ catch (IOException e)
+ {
// Do nothing.
- }
- }
+ }
+ }
ref = null;
}
@@ -237,13 +241,23 @@ public abstract class URLStreamHandler
}
}
+ // We care about the query tag only if there is no reference at all.
+ if (ref == null)
+ {
+ int queryTag = file.indexOf('?');
+ if (queryTag != -1)
+ {
+ query = file.substring(queryTag + 1);
+ file = file.substring(0, queryTag);
+ }
+ }
+
// XXX - Classpath used to call PlatformHelper.toCanonicalForm() on
// the file part. It seems like overhead, but supposedly there is some
// benefit in windows based systems (it also lowercased the string).
-
- setURL(url, url.getProtocol(), host, port, file, ref);
+ setURL(url, url.getProtocol(), host, port, authority, userInfo, file, query, ref);
}
-
+
/*
* Canonicalize a filename.
*/
@@ -251,7 +265,6 @@ public abstract class URLStreamHandler
{
// XXX - GNU Classpath has an implementation that might be more appropriate
// for Windows based systems (gnu.java.io.PlatformHelper.toCanonicalForm)
-
int index;
// Replace "/./" with "/". This probably isn't very efficient in
@@ -270,7 +283,7 @@ public abstract class URLStreamHandler
else
break;
}
- return file;
+ return file;
}
/**
@@ -278,7 +291,7 @@ public abstract class URLStreamHandler
*
* @param url1 The first url
* @param url2 The second url to compare with the first
- *
+ *
* @return True if both URLs point to the same file, false otherwise.
*
* @specnote Now protected
@@ -287,19 +300,21 @@ public abstract class URLStreamHandler
{
if (url1 == url2)
return true;
+
// This comparison is very conservative. It assumes that any
// field can be null.
if (url1 == null || url2 == null)
return false;
- int p1 = url1.getPort ();
+ int p1 = url1.getPort();
if (p1 == -1)
- p1 = url1.ph.getDefaultPort ();
- int p2 = url2.getPort ();
+ p1 = url1.ph.getDefaultPort();
+ int p2 = url2.getPort();
if (p2 == -1)
- p2 = url2.ph.getDefaultPort ();
+ p2 = url2.ph.getDefaultPort();
if (p1 != p2)
return false;
- String s1, s2;
+ String s1;
+ String s2;
s1 = url1.getProtocol();
s2 = url2.getProtocol();
if (s1 != s2 && (s1 == null || ! s1.equals(s2)))
@@ -333,7 +348,7 @@ public abstract class URLStreamHandler
* #setURL(URL,String,String,int,String,String,String,String);
*/
protected void setURL(URL u, String protocol, String host, int port,
- String file, String ref)
+ String file, String ref)
{
u.set(protocol, host, port, file, ref);
}
@@ -355,8 +370,8 @@ public abstract class URLStreamHandler
* different from this one
*/
protected void setURL(URL u, String protocol, String host, int port,
- String authority, String userInfo, String path,
- String query, String ref)
+ String authority, String userInfo, String path,
+ String query, String ref)
{
u.set(protocol, host, port, authority, userInfo, path, query, ref);
}
@@ -372,32 +387,29 @@ public abstract class URLStreamHandler
*
* @return True if both given URLs are equal, false otherwise.
*/
- protected boolean equals (URL url1, URL url2)
+ protected boolean equals(URL url1, URL url2)
{
// This comparison is very conservative. It assumes that any
// field can be null.
- return (url1.getPort () == url2.getPort ()
- && ((url1.getProtocol () == null && url2.getProtocol () == null)
- || (url1.getProtocol () != null
- && url1.getProtocol ().equals (url2.getProtocol ())))
- && ((url1.getUserInfo () == null && url2.getUserInfo () == null)
- || (url1.getUserInfo () != null
- && url1.getUserInfo ().equals(url2.getUserInfo ())))
- && ((url1.getAuthority () == null && url2.getAuthority () == null)
- || (url1.getAuthority () != null
- && url1.getAuthority ().equals(url2.getAuthority ())))
- && ((url1.getHost () == null && url2.getHost () == null)
- || (url1.getHost () != null
- && url1.getHost ().equals(url2.getHost ())))
- && ((url1.getPath () == null && url2.getPath () == null)
- || (url1.getPath () != null
- && url1.getPath ().equals (url2.getPath ())))
- && ((url1.getQuery () == null && url2.getQuery () == null)
- || (url1.getQuery () != null
- && url1.getQuery ().equals(url2.getQuery ())))
- && ((url1.getRef () == null && url2.getRef () == null)
- || (url1.getRef () != null
- && url1.getRef ().equals(url2.getRef ()))));
+ return (url1.getPort() == url2.getPort()
+ && ((url1.getProtocol() == null && url2.getProtocol() == null)
+ || (url1.getProtocol() != null
+ && url1.getProtocol().equals(url2.getProtocol())))
+ && ((url1.getUserInfo() == null && url2.getUserInfo() == null)
+ || (url1.getUserInfo() != null
+ && url1.getUserInfo().equals(url2.getUserInfo())))
+ && ((url1.getAuthority() == null && url2.getAuthority() == null)
+ || (url1.getAuthority() != null
+ && url1.getAuthority().equals(url2.getAuthority())))
+ && ((url1.getHost() == null && url2.getHost() == null)
+ || (url1.getHost() != null && url1.getHost().equals(url2.getHost())))
+ && ((url1.getPath() == null && url2.getPath() == null)
+ || (url1.getPath() != null && url1.getPath().equals(url2.getPath())))
+ && ((url1.getQuery() == null && url2.getQuery() == null)
+ || (url1.getQuery() != null
+ && url1.getQuery().equals(url2.getQuery())))
+ && ((url1.getRef() == null && url2.getRef() == null)
+ || (url1.getRef() != null && url1.getRef().equals(url2.getRef()))));
}
/**
@@ -410,19 +422,19 @@ public abstract class URLStreamHandler
*
* @exception UnknownHostException If an unknown host is found
*/
- protected boolean hostsEqual (URL url1, URL url2)
+ protected boolean hostsEqual(URL url1, URL url2)
{
- InetAddress addr1 = getHostAddress (url1);
- InetAddress addr2 = getHostAddress (url2);
+ InetAddress addr1 = getHostAddress(url1);
+ InetAddress addr2 = getHostAddress(url2);
if (addr1 != null && addr2 != null)
- return addr1.equals (addr2);
+ return addr1.equals(addr2);
String host1 = url1.getHost();
String host2 = url2.getHost();
-
+
if (host1 != null && host2 != null)
- return host1.equalsIgnoreCase (host2);
+ return host1.equalsIgnoreCase(host2);
return host1 == null && host2 == null;
}
@@ -435,16 +447,16 @@ public abstract class URLStreamHandler
*
* @return The address of the hostname in url.
*/
- protected InetAddress getHostAddress (URL url)
+ protected InetAddress getHostAddress(URL url)
{
- String hostname = url.getHost ();
+ String hostname = url.getHost();
if (hostname.equals(""))
return null;
-
+
try
{
- return InetAddress.getByName (hostname);
+ return InetAddress.getByName(hostname);
}
catch (UnknownHostException e)
{
@@ -458,7 +470,7 @@ public abstract class URLStreamHandler
*
* @return The default port number.
*/
- protected int getDefaultPort ()
+ protected int getDefaultPort()
{
return -1;
}
@@ -468,15 +480,14 @@ public abstract class URLStreamHandler
* other protocols that have different requirements for hashCode calculation.
*
* @param url The URL to calc the hashcode for.
- *
+ *
* @return The hashcode for the given URL.
*/
- protected int hashCode (URL url)
+ protected int hashCode(URL url)
{
- return url.getProtocol ().hashCode () +
- ((url.getHost () == null) ? 0 : url.getHost ().hashCode ()) +
- url.getFile ().hashCode() +
- url.getPort ();
+ return url.getProtocol().hashCode()
+ + ((url.getHost() == null) ? 0 : url.getHost().hashCode())
+ + url.getFile().hashCode() + url.getPort();
}
/**
@@ -488,45 +499,35 @@ public abstract class URLStreamHandler
*
* @return A string representation of the url
*/
- protected String toExternalForm(URL u)
+ protected String toExternalForm(URL url)
{
- String protocol, host, file, ref, user;
- int port;
-
- protocol = u.getProtocol();
-
- // JDK 1.2 online doc infers that host could be null because it
- // explicitly states that file cannot be null, but is silent on host.
- host = u.getHost();
- if (host == null)
- host = "";
-
- port = u.getPort();
- file = u.getFile();
- ref = u.getRef();
- user = u.getUserInfo();
+ String protocol;
+ String file;
+ String ref;
+ String authority;
+
+ protocol = url.getProtocol();
+ authority = url.getAuthority();
+ if (authority == null)
+ authority = "";
+
+ file = url.getFile();
+ ref = url.getRef();
// Guess a reasonable size for the string buffer so we have to resize
// at most once.
- int size = protocol.length() + host.length() + file.length() + 24;
+ int size = protocol.length() + authority.length() + file.length() + 24;
StringBuffer sb = new StringBuffer(size);
- if (protocol.length() != 0)
+ if (protocol != null && protocol.length() > 0)
{
sb.append(protocol);
sb.append(":");
}
-
- if (host.length() != 0)
+
+ if (authority.length() != 0)
{
- sb.append("//");
- if (user != null && !"".equals(user))
- sb.append(user).append('@');
- sb.append(host);
-
- // Append port if port was in URL spec.
- if (port >= 0)
- sb.append(':').append(port);
+ sb.append("//").append(authority);
}
sb.append(file);
diff --git a/libjava/java/net/URLStreamHandlerFactory.java b/libjava/java/net/URLStreamHandlerFactory.java
index 268bddb4be0..f43828cc5e9 100644
--- a/libjava/java/net/URLStreamHandlerFactory.java
+++ b/libjava/java/net/URLStreamHandlerFactory.java
@@ -7,7 +7,7 @@ GNU Classpath 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 2, or (at your option)
any later version.
-
+
GNU Classpath 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
@@ -37,15 +37,15 @@ exception statement from your version. */
package java.net;
+
/**
* Written using on-line Java Platform 1.2 API Specification, as well
* as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
* Status: Believed complete and correct.
*/
-
/**
* This interface contains one method which maps the protocol portion of
- * a URL (eg, "http" in "http://www.urbanophile.com/arenn/") to a
+ * a URL (eg, "http" in "http://www.urbanophile.com/arenn/") to a
* <code>URLStreamHandler</code> object.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
@@ -54,14 +54,12 @@ package java.net;
public interface URLStreamHandlerFactory
{
/**
- * This method maps the protocol portion of a URL to a
+ * This method maps the protocol portion of a URL to a
* <code>URLStreamHandler</code> object.
*
* @param protocol The protocol name to map ("http", "ftp", etc).
*
* @return The <code>URLStreamHandler</code> for the specified protocol
*/
- URLStreamHandler createURLStreamHandler (String protocol);
-
+ URLStreamHandler createURLStreamHandler(String protocol);
} // interface URLStreamHandlerFactory
-
diff --git a/libjava/java/net/UnknownHostException.java b/libjava/java/net/UnknownHostException.java
index 46b70401f60..fefdadcd50f 100644
--- a/libjava/java/net/UnknownHostException.java
+++ b/libjava/java/net/UnknownHostException.java
@@ -39,6 +39,7 @@ package java.net;
import java.io.IOException;
+
/**
* This exception indicates that an attempt was made to reference a hostname
* or IP address that is not valid. This could possibly indicate that a
diff --git a/libjava/java/net/UnknownServiceException.java b/libjava/java/net/UnknownServiceException.java
index dfb7a44aa8e..8cf1909f774 100644
--- a/libjava/java/net/UnknownServiceException.java
+++ b/libjava/java/net/UnknownServiceException.java
@@ -39,6 +39,7 @@ package java.net;
import java.io.IOException;
+
/**
* Contrary to what you might think, this does not indicate that the
* TCP/IP service name specified was invalid. Instead it indicates that
diff --git a/libjava/java/nio/Buffer.java b/libjava/java/nio/Buffer.java
index 444d3d1c3ae..c24259f71ec 100644
--- a/libjava/java/nio/Buffer.java
+++ b/libjava/java/nio/Buffer.java
@@ -45,10 +45,11 @@ public abstract class Buffer
int pos = 0;
int mark = -1;
- // Creates a new Buffer.
- //
- // Should be package private.
- //
+ /**
+ * Creates a new Buffer.
+ *
+ * Should be package private.
+ */
Buffer (int capacity, int limit, int position, int mark)
{
if (capacity < 0)
@@ -69,6 +70,8 @@ public abstract class Buffer
/**
* Retrieves the capacity of the buffer.
+ *
+ * @return the capacity of the buffer
*/
public final int capacity ()
{
@@ -77,6 +80,8 @@ public abstract class Buffer
/**
* Clears the buffer.
+ *
+ * @return this buffer
*/
public final Buffer clear ()
{
@@ -88,6 +93,8 @@ public abstract class Buffer
/**
* Flips the buffer.
+ *
+ * @return this buffer
*/
public final Buffer flip ()
{
@@ -99,6 +106,9 @@ public abstract class Buffer
/**
* Tells whether the buffer has remaining data to read or not.
+ *
+ * @return true if the buffer contains remaining data to read,
+ * false otherwise
*/
public final boolean hasRemaining ()
{
@@ -107,11 +117,15 @@ public abstract class Buffer
/**
* Tells whether this buffer is read only or not.
+ *
+ * @return true if the buffer is read only, false otherwise
*/
public abstract boolean isReadOnly ();
/**
* Retrieves the current limit of the buffer.
+ *
+ * @return the limit of the buffer
*/
public final int limit ()
{
@@ -124,6 +138,8 @@ public abstract class Buffer
* @param newLimit The new limit value; must be non-negative and no larger
* than this buffer's capacity.
*
+ * @return this buffer
+ *
* @exception IllegalArgumentException If the preconditions on newLimit
* do not hold.
*/
@@ -144,6 +160,8 @@ public abstract class Buffer
/**
* Sets this buffer's mark at its position.
+ *
+ * @return this buffer
*/
public final Buffer mark ()
{
@@ -153,6 +171,8 @@ public abstract class Buffer
/**
* Retrieves the current position of this buffer.
+ *
+ * @return the current position of this buffer
*/
public final int position ()
{
@@ -165,7 +185,9 @@ public abstract class Buffer
*
* @param newPosition The new position value; must be non-negative and no
* larger than the current limit.
- *
+ *
+ * @return this buffer
+ *
* @exception IllegalArgumentException If the preconditions on newPosition
* do not hold
*/
@@ -183,6 +205,8 @@ public abstract class Buffer
/**
* Returns the number of elements between the current position and the limit.
+ *
+ * @return the number of remaining elements
*/
public final int remaining()
{
@@ -191,7 +215,9 @@ public abstract class Buffer
/**
* Resets this buffer's position to the previously-marked position.
- *
+ *
+ * @return this buffer
+ *
* @exception InvalidMarkException If the mark has not been set.
*/
public final Buffer reset()
@@ -206,6 +232,8 @@ public abstract class Buffer
/**
* Rewinds this buffer. The position is set to zero and the mark
* is discarded.
+ *
+ * @this buffer
*/
public final Buffer rewind()
{
diff --git a/libjava/java/nio/ByteBuffer.java b/libjava/java/nio/ByteBuffer.java
index 276b2dbcb81..8b43da57910 100644
--- a/libjava/java/nio/ByteBuffer.java
+++ b/libjava/java/nio/ByteBuffer.java
@@ -293,32 +293,27 @@ public abstract class ByteBuffer extends Buffer
*/
public int compareTo (Object obj)
{
- ByteBuffer a = (ByteBuffer) obj;
+ ByteBuffer other = (ByteBuffer) obj;
- if (a.remaining () != remaining ())
- return 1;
-
- if (! hasArray () ||
- ! a.hasArray ())
- {
- return 1;
- }
-
- int r = remaining ();
- int i1 = position ();
- int i2 = a.position ();
-
- for (int i = 0; i < r; i++)
+ int num = Math.min(remaining(), other.remaining());
+ int pos_this = position();
+ int pos_other = other.position();
+
+ for (int count = 0; count < num; count++)
{
- int t = (int) (get (i1) - a.get (i2));
-
- if (t != 0)
- {
- return (int) t;
- }
+ byte a = get(pos_this++);
+ byte b = other.get(pos_other++);
+
+ if (a == b)
+ continue;
+
+ if (a < b)
+ return -1;
+
+ return 1;
}
-
- return 0;
+
+ return remaining() - other.remaining();
}
/**
diff --git a/libjava/java/nio/ByteBufferImpl.java b/libjava/java/nio/ByteBufferImpl.java
index 5d3c3d31a86..f79ae630acb 100644
--- a/libjava/java/nio/ByteBufferImpl.java
+++ b/libjava/java/nio/ByteBufferImpl.java
@@ -131,7 +131,7 @@ final class ByteBufferImpl extends ByteBuffer
/**
* Relative get method. Reads the next <code>byte</code> from the buffer.
*/
- final public byte get ()
+ public byte get ()
{
byte result = backing_buffer [position () + array_offset];
position (position () + 1);
@@ -144,7 +144,7 @@ final class ByteBufferImpl extends ByteBuffer
*
* @exception ReadOnlyBufferException If this buffer is read-only.
*/
- final public ByteBuffer put (byte value)
+ public ByteBuffer put (byte value)
{
if (readOnly)
throw new ReadOnlyBufferException ();
@@ -162,7 +162,7 @@ final class ByteBufferImpl extends ByteBuffer
* @exception IndexOutOfBoundsException If index is negative or not smaller
* than the buffer's limit.
*/
- final public byte get (int index)
+ public byte get (int index)
{
return backing_buffer [index + array_offset];
}
@@ -175,7 +175,7 @@ final class ByteBufferImpl extends ByteBuffer
* than the buffer's limit.
* @exception ReadOnlyBufferException If this buffer is read-only.
*/
- final public ByteBuffer put (int index, byte value)
+ public ByteBuffer put (int index, byte value)
{
if (readOnly)
throw new ReadOnlyBufferException ();
@@ -184,133 +184,133 @@ final class ByteBufferImpl extends ByteBuffer
return this;
}
- final public char getChar ()
+ public char getChar ()
{
return ByteBufferHelper.getChar(this, order());
}
- final public ByteBuffer putChar (char value)
+ public ByteBuffer putChar (char value)
{
ByteBufferHelper.putChar(this, value, order());
return this;
}
- final public char getChar (int index)
+ public char getChar (int index)
{
return ByteBufferHelper.getChar(this, index, order());
}
- final public ByteBuffer putChar (int index, char value)
+ public ByteBuffer putChar (int index, char value)
{
ByteBufferHelper.putChar(this, index, value, order());
return this;
}
- final public short getShort ()
+ public short getShort ()
{
return ByteBufferHelper.getShort(this, order());
}
- final public ByteBuffer putShort (short value)
+ public ByteBuffer putShort (short value)
{
ByteBufferHelper.putShort(this, value, order());
return this;
}
- final public short getShort (int index)
+ public short getShort (int index)
{
return ByteBufferHelper.getShort(this, index, order());
}
- final public ByteBuffer putShort (int index, short value)
+ public ByteBuffer putShort (int index, short value)
{
ByteBufferHelper.putShort(this, index, value, order());
return this;
}
- final public int getInt ()
+ public int getInt ()
{
return ByteBufferHelper.getInt(this, order());
}
- final public ByteBuffer putInt (int value)
+ public ByteBuffer putInt (int value)
{
ByteBufferHelper.putInt(this, value, order());
return this;
}
- final public int getInt (int index)
+ public int getInt (int index)
{
return ByteBufferHelper.getInt(this, index, order());
}
- final public ByteBuffer putInt (int index, int value)
+ public ByteBuffer putInt (int index, int value)
{
ByteBufferHelper.putInt(this, index, value, order());
return this;
}
- final public long getLong ()
+ public long getLong ()
{
return ByteBufferHelper.getLong(this, order());
}
- final public ByteBuffer putLong (long value)
+ public ByteBuffer putLong (long value)
{
ByteBufferHelper.putLong (this, value, order());
return this;
}
- final public long getLong (int index)
+ public long getLong (int index)
{
return ByteBufferHelper.getLong (this, index, order());
}
- final public ByteBuffer putLong (int index, long value)
+ public ByteBuffer putLong (int index, long value)
{
ByteBufferHelper.putLong (this, index, value, order());
return this;
}
- final public float getFloat ()
+ public float getFloat ()
{
return ByteBufferHelper.getFloat (this, order());
}
- final public ByteBuffer putFloat (float value)
+ public ByteBuffer putFloat (float value)
{
ByteBufferHelper.putFloat (this, value, order());
return this;
}
- public final float getFloat (int index)
+ public float getFloat (int index)
{
return ByteBufferHelper.getFloat (this, index, order());
}
- final public ByteBuffer putFloat (int index, float value)
+ public ByteBuffer putFloat (int index, float value)
{
ByteBufferHelper.putFloat (this, index, value, order());
return this;
}
- final public double getDouble ()
+ public double getDouble ()
{
return ByteBufferHelper.getDouble (this, order());
}
- final public ByteBuffer putDouble (double value)
+ public ByteBuffer putDouble (double value)
{
ByteBufferHelper.putDouble (this, value, order());
return this;
}
- final public double getDouble (int index)
+ public double getDouble (int index)
{
return ByteBufferHelper.getDouble (this, index, order());
}
- final public ByteBuffer putDouble (int index, double value)
+ public ByteBuffer putDouble (int index, double value)
{
ByteBufferHelper.putDouble (this, index, value, order());
return this;
diff --git a/libjava/java/nio/CharBuffer.java b/libjava/java/nio/CharBuffer.java
index 3d488bad345..416ca834988 100644
--- a/libjava/java/nio/CharBuffer.java
+++ b/libjava/java/nio/CharBuffer.java
@@ -1,5 +1,5 @@
/* CharBuffer.java --
- Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -310,32 +310,27 @@ public abstract class CharBuffer extends Buffer
*/
public int compareTo (Object obj)
{
- CharBuffer a = (CharBuffer) obj;
+ CharBuffer other = (CharBuffer) obj;
- if (a.remaining () != remaining ())
- return 1;
-
- if (! hasArray () ||
- ! a.hasArray ())
- {
- return 1;
- }
-
- int r = remaining ();
- int i1 = position ();
- int i2 = a.position ();
-
- for (int i = 0; i < r; i++)
+ int num = Math.min(remaining(), other.remaining());
+ int pos_this = position();
+ int pos_other = other.position();
+
+ for (int count = 0; count < num; count++)
{
- int t = (int) (get (i1) - a.get (i2));
-
- if (t != 0)
- {
- return (int) t;
- }
+ char a = get(pos_this++);
+ char b = other.get(pos_other++);
+
+ if (a == b)
+ continue;
+
+ if (a < b)
+ return -1;
+
+ return 1;
}
-
- return 0;
+
+ return remaining() - other.remaining();
}
/**
diff --git a/libjava/java/nio/CharBufferImpl.java b/libjava/java/nio/CharBufferImpl.java
index aacc2cb2658..1a8dff1d07c 100644
--- a/libjava/java/nio/CharBufferImpl.java
+++ b/libjava/java/nio/CharBufferImpl.java
@@ -104,7 +104,7 @@ final class CharBufferImpl extends CharBuffer
return false;
}
- final public CharSequence subSequence (int start, int end)
+ public CharSequence subSequence (int start, int end)
{
if (start < 0
|| start > length ()
@@ -118,7 +118,7 @@ final class CharBufferImpl extends CharBuffer
/**
* Relative get method. Reads the next <code>char</code> from the buffer.
*/
- final public char get ()
+ public char get ()
{
char result = backing_buffer [position ()];
position (position () + 1);
@@ -131,7 +131,7 @@ final class CharBufferImpl extends CharBuffer
*
* @exception ReadOnlyBufferException If this buffer is read-only.
*/
- final public CharBuffer put (char value)
+ public CharBuffer put (char value)
{
if (readOnly)
throw new ReadOnlyBufferException ();
@@ -148,7 +148,7 @@ final class CharBufferImpl extends CharBuffer
* @exception IndexOutOfBoundsException If index is negative or not smaller
* than the buffer's limit.
*/
- final public char get (int index)
+ public char get (int index)
{
if (index < 0
|| index >= limit ())
@@ -165,7 +165,7 @@ final class CharBufferImpl extends CharBuffer
* than the buffer's limit.
* @exception ReadOnlyBufferException If this buffer is read-only.
*/
- final public CharBuffer put (int index, char value)
+ public CharBuffer put (int index, char value)
{
if (index < 0
|| index >= limit ())
@@ -178,7 +178,7 @@ final class CharBufferImpl extends CharBuffer
return this;
}
- final public ByteOrder order ()
+ public ByteOrder order ()
{
return ByteOrder.nativeOrder ();
}
diff --git a/libjava/java/nio/DirectByteBufferImpl.java b/libjava/java/nio/DirectByteBufferImpl.java
index ef88d34a701..be0fc52c07d 100644
--- a/libjava/java/nio/DirectByteBufferImpl.java
+++ b/libjava/java/nio/DirectByteBufferImpl.java
@@ -41,7 +41,7 @@ package java.nio;
import gnu.classpath.Configuration;
import gnu.gcj.RawData;
-class DirectByteBufferImpl extends ByteBuffer
+final class DirectByteBufferImpl extends ByteBuffer
{
static
{
@@ -136,15 +136,20 @@ class DirectByteBufferImpl extends ByteBuffer
return this;
}
- native void shiftDown (int dst_offset, int src_offset, int count);
+ static native void shiftDown(RawData address, int dst_offset, int src_offset, int count);
+ void shiftDown(int dst_offset, int src_offset, int count)
+ {
+ shiftDown(address, dst_offset, src_offset, count);
+ }
+
public ByteBuffer compact ()
{
int pos = position();
if (pos > 0)
{
int count = remaining();
- shiftDown(0, pos, count);
+ shiftDown(address, 0, pos, count);
position(count);
limit(capacity());
}
@@ -229,133 +234,133 @@ class DirectByteBufferImpl extends ByteBuffer
return new DoubleViewBufferImpl (this, remaining() >> 3);
}
- final public char getChar ()
+ public char getChar ()
{
return ByteBufferHelper.getChar(this, order());
}
- final public ByteBuffer putChar (char value)
+ public ByteBuffer putChar (char value)
{
ByteBufferHelper.putChar(this, value, order());
return this;
}
- final public char getChar (int index)
+ public char getChar (int index)
{
return ByteBufferHelper.getChar(this, index, order());
}
- final public ByteBuffer putChar (int index, char value)
+ public ByteBuffer putChar (int index, char value)
{
ByteBufferHelper.putChar(this, index, value, order());
return this;
}
- final public short getShort ()
+ public short getShort ()
{
return ByteBufferHelper.getShort(this, order());
}
- final public ByteBuffer putShort (short value)
+ public ByteBuffer putShort (short value)
{
ByteBufferHelper.putShort(this, value, order());
return this;
}
- final public short getShort (int index)
+ public short getShort (int index)
{
return ByteBufferHelper.getShort(this, index, order());
}
- final public ByteBuffer putShort (int index, short value)
+ public ByteBuffer putShort (int index, short value)
{
ByteBufferHelper.putShort(this, index, value, order());
return this;
}
- final public int getInt ()
+ public int getInt ()
{
return ByteBufferHelper.getInt(this, order());
}
- final public ByteBuffer putInt (int value)
+ public ByteBuffer putInt (int value)
{
ByteBufferHelper.putInt(this, value, order());
return this;
}
- final public int getInt (int index)
+ public int getInt (int index)
{
return ByteBufferHelper.getInt(this, index, order());
}
- final public ByteBuffer putInt (int index, int value)
+ public ByteBuffer putInt (int index, int value)
{
ByteBufferHelper.putInt(this, index, value, order());
return this;
}
- final public long getLong ()
+ public long getLong ()
{
return ByteBufferHelper.getLong(this, order());
}
- final public ByteBuffer putLong (long value)
+ public ByteBuffer putLong (long value)
{
ByteBufferHelper.putLong (this, value, order());
return this;
}
- final public long getLong (int index)
+ public long getLong (int index)
{
return ByteBufferHelper.getLong (this, index, order());
}
- final public ByteBuffer putLong (int index, long value)
+ public ByteBuffer putLong (int index, long value)
{
ByteBufferHelper.putLong (this, index, value, order());
return this;
}
- final public float getFloat ()
+ public float getFloat ()
{
return ByteBufferHelper.getFloat (this, order());
}
- final public ByteBuffer putFloat (float value)
+ public ByteBuffer putFloat (float value)
{
ByteBufferHelper.putFloat (this, value, order());
return this;
}
- public final float getFloat (int index)
+ public float getFloat (int index)
{
return ByteBufferHelper.getFloat (this, index, order());
}
- final public ByteBuffer putFloat (int index, float value)
+ public ByteBuffer putFloat (int index, float value)
{
ByteBufferHelper.putFloat (this, index, value, order());
return this;
}
- final public double getDouble ()
+ public double getDouble ()
{
return ByteBufferHelper.getDouble (this, order());
}
- final public ByteBuffer putDouble (double value)
+ public ByteBuffer putDouble (double value)
{
ByteBufferHelper.putDouble (this, value, order());
return this;
}
- final public double getDouble (int index)
+ public double getDouble (int index)
{
return ByteBufferHelper.getDouble (this, index, order());
}
- final public ByteBuffer putDouble (int index, double value)
+ public ByteBuffer putDouble (int index, double value)
{
ByteBufferHelper.putDouble (this, index, value, order());
return this;
diff --git a/libjava/java/nio/DoubleBuffer.java b/libjava/java/nio/DoubleBuffer.java
index d669c2138c4..1ad8baede02 100644
--- a/libjava/java/nio/DoubleBuffer.java
+++ b/libjava/java/nio/DoubleBuffer.java
@@ -1,5 +1,5 @@
/* DoubleBuffer.java --
- Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -265,32 +265,27 @@ public abstract class DoubleBuffer extends Buffer
*/
public int compareTo (Object obj)
{
- DoubleBuffer a = (DoubleBuffer) obj;
+ DoubleBuffer other = (DoubleBuffer) obj;
- if (a.remaining () != remaining ())
- return 1;
-
- if (! hasArray () ||
- ! a.hasArray ())
- {
- return 1;
- }
-
- int r = remaining ();
- int i1 = position ();
- int i2 = a.position ();
-
- for (int i = 0; i < r; i++)
+ int num = Math.min(remaining(), other.remaining());
+ int pos_this = position();
+ int pos_other = other.position();
+
+ for (int count = 0; count < num; count++)
{
- int t = (int) (get (i1) - a.get (i2));
-
- if (t != 0)
- {
- return (int) t;
- }
+ double a = get(pos_this++);
+ double b = other.get(pos_other++);
+
+ if (a == b)
+ continue;
+
+ if (a < b)
+ return -1;
+
+ return 1;
}
-
- return 0;
+
+ return remaining() - other.remaining();
}
/**
diff --git a/libjava/java/nio/DoubleBufferImpl.java b/libjava/java/nio/DoubleBufferImpl.java
index 2c425dceb30..81fde6db6e6 100644
--- a/libjava/java/nio/DoubleBufferImpl.java
+++ b/libjava/java/nio/DoubleBufferImpl.java
@@ -100,7 +100,7 @@ final class DoubleBufferImpl extends DoubleBuffer
/**
* Relative get method. Reads the next <code>double</code> from the buffer.
*/
- final public double get ()
+ public double get ()
{
double result = backing_buffer [position ()];
position (position () + 1);
@@ -113,7 +113,7 @@ final class DoubleBufferImpl extends DoubleBuffer
*
* @exception ReadOnlyBufferException If this buffer is read-only.
*/
- final public DoubleBuffer put (double value)
+ public DoubleBuffer put (double value)
{
if (readOnly)
throw new ReadOnlyBufferException ();
@@ -130,7 +130,7 @@ final class DoubleBufferImpl extends DoubleBuffer
* @exception IndexOutOfBoundsException If index is negative or not smaller
* than the buffer's limit.
*/
- final public double get (int index)
+ public double get (int index)
{
return backing_buffer [index];
}
@@ -143,7 +143,7 @@ final class DoubleBufferImpl extends DoubleBuffer
* than the buffer's limit.
* @exception ReadOnlyBufferException If this buffer is read-only.
*/
- final public DoubleBuffer put (int index, double value)
+ public DoubleBuffer put (int index, double value)
{
if (readOnly)
throw new ReadOnlyBufferException ();
@@ -152,7 +152,7 @@ final class DoubleBufferImpl extends DoubleBuffer
return this;
}
- final public ByteOrder order ()
+ public ByteOrder order ()
{
return ByteOrder.nativeOrder ();
}
diff --git a/libjava/java/nio/DoubleViewBufferImpl.java b/libjava/java/nio/DoubleViewBufferImpl.java
index 7df2f509b58..7b04e4ca108 100644
--- a/libjava/java/nio/DoubleViewBufferImpl.java
+++ b/libjava/java/nio/DoubleViewBufferImpl.java
@@ -38,7 +38,7 @@ exception statement from your version. */
package java.nio;
-class DoubleViewBufferImpl extends DoubleBuffer
+final class DoubleViewBufferImpl extends DoubleBuffer
{
/** Position in bb (i.e. a byte offset) where this buffer starts. */
private int offset;
diff --git a/libjava/java/nio/FloatBuffer.java b/libjava/java/nio/FloatBuffer.java
index 0c7b04dd0f5..ab87b7f898f 100644
--- a/libjava/java/nio/FloatBuffer.java
+++ b/libjava/java/nio/FloatBuffer.java
@@ -1,5 +1,5 @@
/* FloatBuffer.java --
- Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -265,32 +265,27 @@ public abstract class FloatBuffer extends Buffer
*/
public int compareTo (Object obj)
{
- FloatBuffer a = (FloatBuffer) obj;
+ FloatBuffer other = (FloatBuffer) obj;
- if (a.remaining () != remaining ())
- return 1;
-
- if (! hasArray () ||
- ! a.hasArray ())
- {
- return 1;
- }
-
- int r = remaining ();
- int i1 = position ();
- int i2 = a.position ();
-
- for (int i = 0; i < r; i++)
+ int num = Math.min(remaining(), other.remaining());
+ int pos_this = position();
+ int pos_other = other.position();
+
+ for (int count = 0; count < num; count++)
{
- int t = (int) (get (i1) - a.get (i2));
-
- if (t != 0)
- {
- return (int) t;
- }
+ float a = get(pos_this++);
+ float b = other.get(pos_other++);
+
+ if (a == b)
+ continue;
+
+ if (a < b)
+ return -1;
+
+ return 1;
}
-
- return 0;
+
+ return remaining() - other.remaining();
}
/**
diff --git a/libjava/java/nio/FloatBufferImpl.java b/libjava/java/nio/FloatBufferImpl.java
index 06584132499..47479845da6 100644
--- a/libjava/java/nio/FloatBufferImpl.java
+++ b/libjava/java/nio/FloatBufferImpl.java
@@ -100,7 +100,7 @@ final class FloatBufferImpl extends FloatBuffer
/**
* Relative get method. Reads the next <code>float</code> from the buffer.
*/
- final public float get ()
+ public float get ()
{
float result = backing_buffer [position ()];
position (position () + 1);
@@ -113,7 +113,7 @@ final class FloatBufferImpl extends FloatBuffer
*
* @exception ReadOnlyBufferException If this buffer is read-only.
*/
- final public FloatBuffer put (float value)
+ public FloatBuffer put (float value)
{
if (readOnly)
throw new ReadOnlyBufferException ();
@@ -130,7 +130,7 @@ final class FloatBufferImpl extends FloatBuffer
* @exception IndexOutOfBoundsException If index is negative or not smaller
* than the buffer's limit.
*/
- final public float get (int index)
+ public float get (int index)
{
return backing_buffer [index];
}
@@ -143,7 +143,7 @@ final class FloatBufferImpl extends FloatBuffer
* than the buffer's limit.
* @exception ReadOnlyBufferException If this buffer is read-only.
*/
- final public FloatBuffer put (int index, float value)
+ public FloatBuffer put (int index, float value)
{
if (readOnly)
throw new ReadOnlyBufferException ();
@@ -152,7 +152,7 @@ final class FloatBufferImpl extends FloatBuffer
return this;
}
- final public ByteOrder order ()
+ public ByteOrder order ()
{
return ByteOrder.nativeOrder ();
}
diff --git a/libjava/java/nio/FloatViewBufferImpl.java b/libjava/java/nio/FloatViewBufferImpl.java
index c4caf9bf322..08c59097d37 100644
--- a/libjava/java/nio/FloatViewBufferImpl.java
+++ b/libjava/java/nio/FloatViewBufferImpl.java
@@ -38,7 +38,7 @@ exception statement from your version. */
package java.nio;
-class FloatViewBufferImpl extends FloatBuffer
+final class FloatViewBufferImpl extends FloatBuffer
{
/** Position in bb (i.e. a byte offset) where this buffer starts. */
private int offset;
diff --git a/libjava/java/nio/IntBuffer.java b/libjava/java/nio/IntBuffer.java
index 469a344ea71..52d822aa81d 100644
--- a/libjava/java/nio/IntBuffer.java
+++ b/libjava/java/nio/IntBuffer.java
@@ -1,5 +1,5 @@
/* IntBuffer.java --
- Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -265,32 +265,27 @@ public abstract class IntBuffer extends Buffer
*/
public int compareTo (Object obj)
{
- IntBuffer a = (IntBuffer) obj;
+ IntBuffer other = (IntBuffer) obj;
- if (a.remaining () != remaining ())
- return 1;
-
- if (! hasArray () ||
- ! a.hasArray ())
- {
- return 1;
- }
-
- int r = remaining ();
- int i1 = position ();
- int i2 = a.position ();
-
- for (int i = 0; i < r; i++)
+ int num = Math.min(remaining(), other.remaining());
+ int pos_this = position();
+ int pos_other = other.position();
+
+ for (int count = 0; count < num; count++)
{
- int t = (int) (get (i1) - a.get (i2));
-
- if (t != 0)
- {
- return (int) t;
- }
+ int a = get(pos_this++);
+ int b = other.get(pos_other++);
+
+ if (a == b)
+ continue;
+
+ if (a < b)
+ return -1;
+
+ return 1;
}
-
- return 0;
+
+ return remaining() - other.remaining();
}
/**
diff --git a/libjava/java/nio/IntBufferImpl.java b/libjava/java/nio/IntBufferImpl.java
index f142827104a..a491c1105c4 100644
--- a/libjava/java/nio/IntBufferImpl.java
+++ b/libjava/java/nio/IntBufferImpl.java
@@ -100,7 +100,7 @@ final class IntBufferImpl extends IntBuffer
/**
* Relative get method. Reads the next <code>int</code> from the buffer.
*/
- final public int get ()
+ public int get ()
{
int result = backing_buffer [position ()];
position (position () + 1);
@@ -113,7 +113,7 @@ final class IntBufferImpl extends IntBuffer
*
* @exception ReadOnlyBufferException If this buffer is read-only.
*/
- final public IntBuffer put (int value)
+ public IntBuffer put (int value)
{
if (readOnly)
throw new ReadOnlyBufferException ();
@@ -130,7 +130,7 @@ final class IntBufferImpl extends IntBuffer
* @exception IndexOutOfBoundsException If index is negative or not smaller
* than the buffer's limit.
*/
- final public int get (int index)
+ public int get (int index)
{
return backing_buffer [index];
}
@@ -143,7 +143,7 @@ final class IntBufferImpl extends IntBuffer
* than the buffer's limit.
* @exception ReadOnlyBufferException If this buffer is read-only.
*/
- final public IntBuffer put (int index, int value)
+ public IntBuffer put (int index, int value)
{
if (readOnly)
throw new ReadOnlyBufferException ();
@@ -152,7 +152,7 @@ final class IntBufferImpl extends IntBuffer
return this;
}
- final public ByteOrder order ()
+ public ByteOrder order ()
{
return ByteOrder.nativeOrder ();
}
diff --git a/libjava/java/nio/IntViewBufferImpl.java b/libjava/java/nio/IntViewBufferImpl.java
index 3c8e8e61ca2..074953793be 100644
--- a/libjava/java/nio/IntViewBufferImpl.java
+++ b/libjava/java/nio/IntViewBufferImpl.java
@@ -38,7 +38,7 @@ exception statement from your version. */
package java.nio;
-class IntViewBufferImpl extends IntBuffer
+final class IntViewBufferImpl extends IntBuffer
{
/** Position in bb (i.e. a byte offset) where this buffer starts. */
private int offset;
diff --git a/libjava/java/nio/LongBuffer.java b/libjava/java/nio/LongBuffer.java
index 712e0b3b59a..1b420eb5ed4 100644
--- a/libjava/java/nio/LongBuffer.java
+++ b/libjava/java/nio/LongBuffer.java
@@ -1,5 +1,5 @@
/* LongBuffer.java --
- Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -265,32 +265,27 @@ public abstract class LongBuffer extends Buffer
*/
public int compareTo (Object obj)
{
- LongBuffer a = (LongBuffer) obj;
+ LongBuffer other = (LongBuffer) obj;
- if (a.remaining () != remaining ())
- return 1;
-
- if (! hasArray () ||
- ! a.hasArray ())
- {
- return 1;
- }
-
- int r = remaining ();
- int i1 = position ();
- int i2 = a.position ();
-
- for (int i = 0; i < r; i++)
+ int num = Math.min(remaining(), other.remaining());
+ int pos_this = position();
+ int pos_other = other.position();
+
+ for (int count = 0; count < num; count++)
{
- int t = (int) (get (i1) - a.get (i2));
-
- if (t != 0)
- {
- return (int) t;
- }
+ long a = get(pos_this++);
+ long b = other.get(pos_other++);
+
+ if (a == b)
+ continue;
+
+ if (a < b)
+ return -1;
+
+ return 1;
}
-
- return 0;
+
+ return remaining() - other.remaining();
}
/**
diff --git a/libjava/java/nio/LongBufferImpl.java b/libjava/java/nio/LongBufferImpl.java
index 7f99f336686..88a9d8c5415 100644
--- a/libjava/java/nio/LongBufferImpl.java
+++ b/libjava/java/nio/LongBufferImpl.java
@@ -100,7 +100,7 @@ final class LongBufferImpl extends LongBuffer
/**
* Relative get method. Reads the next <code>long</code> from the buffer.
*/
- final public long get ()
+ public long get ()
{
long result = backing_buffer [position ()];
position (position () + 1);
@@ -113,7 +113,7 @@ final class LongBufferImpl extends LongBuffer
*
* @exception ReadOnlyBufferException If this buffer is read-only.
*/
- final public LongBuffer put (long value)
+ public LongBuffer put (long value)
{
if (readOnly)
throw new ReadOnlyBufferException ();
@@ -130,7 +130,7 @@ final class LongBufferImpl extends LongBuffer
* @exception IndexOutOfBoundsException If index is negative or not smaller
* than the buffer's limit.
*/
- final public long get (int index)
+ public long get (int index)
{
return backing_buffer [index];
}
@@ -143,7 +143,7 @@ final class LongBufferImpl extends LongBuffer
* than the buffer's limit.
* @exception ReadOnlyBufferException If this buffer is read-only.
*/
- final public LongBuffer put (int index, long value)
+ public LongBuffer put (int index, long value)
{
if (readOnly)
throw new ReadOnlyBufferException ();
@@ -152,7 +152,7 @@ final class LongBufferImpl extends LongBuffer
return this;
}
- final public ByteOrder order ()
+ public ByteOrder order ()
{
return ByteOrder.nativeOrder ();
}
diff --git a/libjava/java/nio/LongViewBufferImpl.java b/libjava/java/nio/LongViewBufferImpl.java
index 9765de9cd0f..d1dd060d311 100644
--- a/libjava/java/nio/LongViewBufferImpl.java
+++ b/libjava/java/nio/LongViewBufferImpl.java
@@ -38,7 +38,7 @@ exception statement from your version. */
package java.nio;
-class LongViewBufferImpl extends LongBuffer
+final class LongViewBufferImpl extends LongBuffer
{
/** Position in bb (i.e. a byte offset) where this buffer starts. */
private int offset;
diff --git a/libjava/java/nio/MappedByteBufferImpl.java b/libjava/java/nio/MappedByteBufferImpl.java
index 52996c23df4..5932c99f6d0 100644
--- a/libjava/java/nio/MappedByteBufferImpl.java
+++ b/libjava/java/nio/MappedByteBufferImpl.java
@@ -39,10 +39,9 @@ exception statement from your version. */
package java.nio;
import java.io.IOException;
-import gnu.java.nio.channels.FileChannelImpl;
import gnu.gcj.RawData;
-class MappedByteBufferImpl extends MappedByteBuffer
+final class MappedByteBufferImpl extends MappedByteBuffer
{
boolean readOnly;
RawData address;
@@ -122,7 +121,8 @@ class MappedByteBufferImpl extends MappedByteBuffer
if (pos > 0)
{
int count = remaining();
- shiftDown(0, pos, count);
+ // Call shiftDown method optimized for direct buffers.
+ DirectByteBufferImpl.shiftDown(address, 0, pos, count);
position(count);
limit(capacity());
}
@@ -201,133 +201,133 @@ class MappedByteBufferImpl extends MappedByteBuffer
return new DoubleViewBufferImpl (this, remaining() >> 3);
}
- final public char getChar ()
+ public char getChar ()
{
return ByteBufferHelper.getChar(this, order());
}
- final public ByteBuffer putChar (char value)
+ public ByteBuffer putChar (char value)
{
ByteBufferHelper.putChar(this, value, order());
return this;
}
- final public char getChar (int index)
+ public char getChar (int index)
{
return ByteBufferHelper.getChar(this, index, order());
}
- final public ByteBuffer putChar (int index, char value)
+ public ByteBuffer putChar (int index, char value)
{
ByteBufferHelper.putChar(this, index, value, order());
return this;
}
- final public short getShort ()
+ public short getShort ()
{
return ByteBufferHelper.getShort(this, order());
}
- final public ByteBuffer putShort (short value)
+ public ByteBuffer putShort (short value)
{
ByteBufferHelper.putShort(this, value, order());
return this;
}
- final public short getShort (int index)
+ public short getShort (int index)
{
return ByteBufferHelper.getShort(this, index, order());
}
- final public ByteBuffer putShort (int index, short value)
+ public ByteBuffer putShort (int index, short value)
{
ByteBufferHelper.putShort(this, index, value, order());
return this;
}
- final public int getInt ()
+ public int getInt ()
{
return ByteBufferHelper.getInt(this, order());
}
- final public ByteBuffer putInt (int value)
+ public ByteBuffer putInt (int value)
{
ByteBufferHelper.putInt(this, value, order());
return this;
}
- final public int getInt (int index)
+ public int getInt (int index)
{
return ByteBufferHelper.getInt(this, index, order());
}
- final public ByteBuffer putInt (int index, int value)
+ public ByteBuffer putInt (int index, int value)
{
ByteBufferHelper.putInt(this, index, value, order());
return this;
}
- final public long getLong ()
+ public long getLong ()
{
return ByteBufferHelper.getLong(this, order());
}
- final public ByteBuffer putLong (long value)
+ public ByteBuffer putLong (long value)
{
ByteBufferHelper.putLong (this, value, order());
return this;
}
- final public long getLong (int index)
+ public long getLong (int index)
{
return ByteBufferHelper.getLong (this, index, order());
}
- final public ByteBuffer putLong (int index, long value)
+ public ByteBuffer putLong (int index, long value)
{
ByteBufferHelper.putLong (this, index, value, order());
return this;
}
- final public float getFloat ()
+ public float getFloat ()
{
return ByteBufferHelper.getFloat (this, order());
}
- final public ByteBuffer putFloat (float value)
+ public ByteBuffer putFloat (float value)
{
ByteBufferHelper.putFloat (this, value, order());
return this;
}
- public final float getFloat (int index)
+ public float getFloat (int index)
{
return ByteBufferHelper.getFloat (this, index, order());
}
- final public ByteBuffer putFloat (int index, float value)
+ public ByteBuffer putFloat (int index, float value)
{
ByteBufferHelper.putFloat (this, index, value, order());
return this;
}
- final public double getDouble ()
+ public double getDouble ()
{
return ByteBufferHelper.getDouble (this, order());
}
- final public ByteBuffer putDouble (double value)
+ public ByteBuffer putDouble (double value)
{
ByteBufferHelper.putDouble (this, value, order());
return this;
}
- final public double getDouble (int index)
+ public double getDouble (int index)
{
return ByteBufferHelper.getDouble (this, index, order());
}
- final public ByteBuffer putDouble (int index, double value)
+ public ByteBuffer putDouble (int index, double value)
{
ByteBufferHelper.putDouble (this, index, value, order());
return this;
diff --git a/libjava/java/nio/ShortBuffer.java b/libjava/java/nio/ShortBuffer.java
index 61097d04dd9..9f542769fac 100644
--- a/libjava/java/nio/ShortBuffer.java
+++ b/libjava/java/nio/ShortBuffer.java
@@ -1,5 +1,5 @@
/* ShortBuffer.java --
- Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -265,32 +265,27 @@ public abstract class ShortBuffer extends Buffer
*/
public int compareTo (Object obj)
{
- ShortBuffer a = (ShortBuffer) obj;
+ ShortBuffer other = (ShortBuffer) obj;
- if (a.remaining () != remaining ())
- return 1;
-
- if (! hasArray () ||
- ! a.hasArray ())
- {
- return 1;
- }
-
- int r = remaining ();
- int i1 = position ();
- int i2 = a.position ();
-
- for (int i = 0; i < r; i++)
+ int num = Math.min(remaining(), other.remaining());
+ int pos_this = position();
+ int pos_other = other.position();
+
+ for (int count = 0; count < num; count++)
{
- int t = (int) (get (i1) - a.get (i2));
-
- if (t != 0)
- {
- return (int) t;
- }
+ short a = get(pos_this++);
+ short b = other.get(pos_other++);
+
+ if (a == b)
+ continue;
+
+ if (a < b)
+ return -1;
+
+ return 1;
}
-
- return 0;
+
+ return remaining() - other.remaining();
}
/**
diff --git a/libjava/java/nio/ShortBufferImpl.java b/libjava/java/nio/ShortBufferImpl.java
index 938d5ce89d3..6871f096e9d 100644
--- a/libjava/java/nio/ShortBufferImpl.java
+++ b/libjava/java/nio/ShortBufferImpl.java
@@ -100,7 +100,7 @@ final class ShortBufferImpl extends ShortBuffer
/**
* Relative get method. Reads the next <code>short</code> from the buffer.
*/
- final public short get ()
+ public short get ()
{
short result = backing_buffer [position ()];
position (position () + 1);
@@ -113,7 +113,7 @@ final class ShortBufferImpl extends ShortBuffer
*
* @exception ReadOnlyBufferException If this buffer is read-only.
*/
- final public ShortBuffer put (short value)
+ public ShortBuffer put (short value)
{
if (readOnly)
throw new ReadOnlyBufferException ();
@@ -130,7 +130,7 @@ final class ShortBufferImpl extends ShortBuffer
* @exception IndexOutOfBoundsException If index is negative or not smaller
* than the buffer's limit.
*/
- final public short get (int index)
+ public short get (int index)
{
return backing_buffer [index];
}
@@ -143,7 +143,7 @@ final class ShortBufferImpl extends ShortBuffer
* than the buffer's limit.
* @exception ReadOnlyBufferException If this buffer is read-only.
*/
- final public ShortBuffer put (int index, short value)
+ public ShortBuffer put (int index, short value)
{
if (readOnly)
throw new ReadOnlyBufferException ();
@@ -152,7 +152,7 @@ final class ShortBufferImpl extends ShortBuffer
return this;
}
- final public ByteOrder order ()
+ public ByteOrder order ()
{
return ByteOrder.nativeOrder ();
}
diff --git a/libjava/java/nio/ShortViewBufferImpl.java b/libjava/java/nio/ShortViewBufferImpl.java
index 04d778578b0..26aabad519c 100644
--- a/libjava/java/nio/ShortViewBufferImpl.java
+++ b/libjava/java/nio/ShortViewBufferImpl.java
@@ -38,7 +38,7 @@ exception statement from your version. */
package java.nio;
-class ShortViewBufferImpl extends ShortBuffer
+final class ShortViewBufferImpl extends ShortBuffer
{
/** Position in bb (i.e. a byte offset) where this buffer starts. */
private int offset;
diff --git a/libjava/java/nio/channels/AlreadyConnectedException.java b/libjava/java/nio/channels/AlreadyConnectedException.java
index 740fdbc0ddd..775d2894da2 100644
--- a/libjava/java/nio/channels/AlreadyConnectedException.java
+++ b/libjava/java/nio/channels/AlreadyConnectedException.java
@@ -1,4 +1,4 @@
-/* AlreadyConnectedException.java --
+/* AlreadyConnectedException.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
diff --git a/libjava/java/nio/channels/AsynchronousCloseException.java b/libjava/java/nio/channels/AsynchronousCloseException.java
index ec4bbc7fd47..d6cfd48ee30 100644
--- a/libjava/java/nio/channels/AsynchronousCloseException.java
+++ b/libjava/java/nio/channels/AsynchronousCloseException.java
@@ -1,4 +1,4 @@
-/* AsynchronousCloseException.java --
+/* AsynchronousCloseException.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,6 +37,7 @@ exception statement from your version. */
package java.nio.channels;
+
/**
* @author Michael Koch
* @since 1.4
diff --git a/libjava/java/nio/channels/ByteChannel.java b/libjava/java/nio/channels/ByteChannel.java
index f4958be2bf7..75dd69f7279 100644
--- a/libjava/java/nio/channels/ByteChannel.java
+++ b/libjava/java/nio/channels/ByteChannel.java
@@ -1,4 +1,4 @@
-/* ByteChannel.java --
+/* ByteChannel.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,7 +37,7 @@ exception statement from your version. */
package java.nio.channels;
-public interface ByteChannel
- extends ReadableByteChannel, WritableByteChannel
+public interface ByteChannel extends ReadableByteChannel,
+ WritableByteChannel
{
}
diff --git a/libjava/java/nio/channels/CancelledKeyException.java b/libjava/java/nio/channels/CancelledKeyException.java
index cf3c5cc352c..00fb04c43c1 100644
--- a/libjava/java/nio/channels/CancelledKeyException.java
+++ b/libjava/java/nio/channels/CancelledKeyException.java
@@ -1,4 +1,4 @@
-/* CancelledKeyException.java --
+/* CancelledKeyException.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,6 +37,7 @@ exception statement from your version. */
package java.nio.channels;
+
/**
* @author Michael Koch
* @since 1.4
diff --git a/libjava/java/nio/channels/Channel.java b/libjava/java/nio/channels/Channel.java
index 86df85edb1b..fabe183be1f 100644
--- a/libjava/java/nio/channels/Channel.java
+++ b/libjava/java/nio/channels/Channel.java
@@ -1,4 +1,4 @@
-/* Channel.java --
+/* Channel.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,6 +39,7 @@ package java.nio.channels;
import java.io.IOException;
+
public interface Channel
{
/**
diff --git a/libjava/java/nio/channels/Channels.java b/libjava/java/nio/channels/Channels.java
index 896e1734d80..9eb2ec7bff6 100644
--- a/libjava/java/nio/channels/Channels.java
+++ b/libjava/java/nio/channels/Channels.java
@@ -1,4 +1,4 @@
-/* Channels.java --
+/* Channels.java --
Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -42,20 +42,21 @@ import gnu.java.nio.ChannelOutputStream;
import gnu.java.nio.InputStreamChannel;
import gnu.java.nio.OutputStreamChannel;
import gnu.java.nio.channels.FileChannelImpl;
-import java.io.InputStream;
-import java.io.OutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
+
/**
* @since 1.4
*/
-public final class Channels
+public final class Channels
{
/**
* Constructs a stream that reads bytes from the given channel.
@@ -70,7 +71,7 @@ public final class Channels
/**
* Constructs a stream that writes bytes to the given channel.
*/
- public static OutputStream newOutputStream(WritableByteChannel ch)
+ public static OutputStream newOutputStream(WritableByteChannel ch)
{
if (ch instanceof FileChannelImpl)
return newOutputStream((FileChannelImpl) ch);
@@ -78,8 +79,9 @@ public final class Channels
}
static native FileInputStream newInputStream(FileChannelImpl ch);
+
static native FileOutputStream newOutputStream(FileChannelImpl ch);
-
+
/**
* Constructs a channel that reads bytes from the given stream.
*/
@@ -93,17 +95,17 @@ public final class Channels
*/
public static WritableByteChannel newChannel(OutputStream out)
{
- return new OutputStreamChannel (out);
+ return new OutputStreamChannel(out);
}
/**
* Constructs a reader that decodes bytes from the given channel using the
* given decoder.
*/
- public static Reader newReader (ReadableByteChannel ch, CharsetDecoder dec,
- int minBufferCap)
+ public static Reader newReader(ReadableByteChannel ch, CharsetDecoder dec,
+ int minBufferCap)
{
- throw new Error ("not implemented");
+ throw new Error("not implemented");
}
/**
@@ -113,19 +115,19 @@ public final class Channels
* @exception UnsupportedCharsetException If no support for the named charset
* is available in this instance of the Java virtual machine.
*/
- public static Reader newReader (ReadableByteChannel ch, String csName)
+ public static Reader newReader(ReadableByteChannel ch, String csName)
{
- return newReader (ch, Charset.forName (csName).newDecoder (), -1);
+ return newReader(ch, Charset.forName(csName).newDecoder(), -1);
}
/**
* Constructs a writer that encodes characters using the given encoder and
* writes the resulting bytes to the given channel.
*/
- public static Writer newWriter (WritableByteChannel ch, CharsetEncoder enc,
- int minBufferCap)
+ public static Writer newWriter(WritableByteChannel ch, CharsetEncoder enc,
+ int minBufferCap)
{
- throw new Error ("not implemented");
+ throw new Error("not implemented");
}
/**
@@ -135,9 +137,8 @@ public final class Channels
* @exception UnsupportedCharsetException If no support for the named charset
* is available in this instance of the Java virtual machine.
*/
- public static Writer newWriter (WritableByteChannel ch,
- String csName)
+ public static Writer newWriter(WritableByteChannel ch, String csName)
{
- return newWriter (ch, Charset.forName (csName).newEncoder (), -1);
+ return newWriter(ch, Charset.forName(csName).newEncoder(), -1);
}
}
diff --git a/libjava/java/nio/channels/ClosedByInterruptException.java b/libjava/java/nio/channels/ClosedByInterruptException.java
index b99e016f17d..7a9e64c4f71 100644
--- a/libjava/java/nio/channels/ClosedByInterruptException.java
+++ b/libjava/java/nio/channels/ClosedByInterruptException.java
@@ -1,4 +1,4 @@
-/* ClosedByInterruptException.java --
+/* ClosedByInterruptException.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,6 +37,7 @@ exception statement from your version. */
package java.nio.channels;
+
/**
* @author Michael Koch
* @since 1.4
diff --git a/libjava/java/nio/channels/ClosedChannelException.java b/libjava/java/nio/channels/ClosedChannelException.java
index 353a8202647..876ad062f1f 100644
--- a/libjava/java/nio/channels/ClosedChannelException.java
+++ b/libjava/java/nio/channels/ClosedChannelException.java
@@ -1,4 +1,4 @@
-/* ClosedChannelException.java --
+/* ClosedChannelException.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,6 +39,7 @@ package java.nio.channels;
import java.io.IOException;
+
/**
* @author Michael Koch
* @since 1.4
diff --git a/libjava/java/nio/channels/ClosedSelectorException.java b/libjava/java/nio/channels/ClosedSelectorException.java
index 98a9d505ded..ae5421d053d 100644
--- a/libjava/java/nio/channels/ClosedSelectorException.java
+++ b/libjava/java/nio/channels/ClosedSelectorException.java
@@ -1,4 +1,4 @@
-/* ClosedSelectorException.java --
+/* ClosedSelectorException.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,6 +37,7 @@ exception statement from your version. */
package java.nio.channels;
+
/**
* @author Michael Koch
* @since 1.4
diff --git a/libjava/java/nio/channels/ConnectionPendingException.java b/libjava/java/nio/channels/ConnectionPendingException.java
index 876179c01b4..c224058f0f7 100644
--- a/libjava/java/nio/channels/ConnectionPendingException.java
+++ b/libjava/java/nio/channels/ConnectionPendingException.java
@@ -1,4 +1,4 @@
-/* ConnectionPendingException.java --
+/* ConnectionPendingException.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,6 +37,7 @@ exception statement from your version. */
package java.nio.channels;
+
/**
* @author Michael Koch
* @since 1.4
diff --git a/libjava/java/nio/channels/DatagramChannel.java b/libjava/java/nio/channels/DatagramChannel.java
index 4a7ac9825f7..9760b77123e 100644
--- a/libjava/java/nio/channels/DatagramChannel.java
+++ b/libjava/java/nio/channels/DatagramChannel.java
@@ -1,4 +1,4 @@
-/* DatagramChannel.java --
+/* DatagramChannel.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -44,19 +44,19 @@ import java.nio.ByteBuffer;
import java.nio.channels.spi.AbstractSelectableChannel;
import java.nio.channels.spi.SelectorProvider;
+
/**
* @since 1.4
*/
-public abstract class DatagramChannel
- extends AbstractSelectableChannel
+public abstract class DatagramChannel extends AbstractSelectableChannel
implements ByteChannel, ScatteringByteChannel, GatheringByteChannel
{
/**
* Initializes the channel.
*/
- protected DatagramChannel (SelectorProvider provider)
+ protected DatagramChannel(SelectorProvider provider)
{
- super (provider);
+ super(provider);
}
/**
@@ -64,40 +64,40 @@ public abstract class DatagramChannel
*
* @exception IOException If an error occurs
*/
- public static DatagramChannel open () throws IOException
+ public static DatagramChannel open() throws IOException
{
- return SelectorProvider.provider ().openDatagramChannel ();
+ return SelectorProvider.provider().openDatagramChannel();
}
-
+
/**
* Reads data from this channel.
*/
- public final long read (ByteBuffer[] dsts) throws IOException
+ public final long read(ByteBuffer[] dsts) throws IOException
{
long b = 0;
-
+
for (int i = 0; i < dsts.length; i++)
- b += read (dsts[i]);
-
+ b += read(dsts[i]);
+
return b;
}
-
+
/**
* Writes data to this channel.
*
* @exception IOException If an error occurs
* @exception NotYetConnectedException The channel's socket is not connected.
*/
- public final long write (ByteBuffer[] srcs) throws IOException
+ public final long write(ByteBuffer[] srcs) throws IOException
{
long b = 0;
-
- for (int i = 0;i < srcs.length; i++)
- b += write (srcs[i]);
-
+
+ for (int i = 0; i < srcs.length; i++)
+ b += write(srcs[i]);
+
return b;
}
-
+
/**
* Connects this channel's socket.
*
@@ -111,7 +111,7 @@ public abstract class DatagramChannel
* @exception SecurityException If a security manager has been installed and
* it does not permit datagrams to be sent to the given address.
*/
- public abstract DatagramChannel connect (SocketAddress remote)
+ public abstract DatagramChannel connect(SocketAddress remote)
throws IOException;
/**
@@ -119,7 +119,7 @@ public abstract class DatagramChannel
*
* @exception IOException If an error occurs
*/
- public abstract DatagramChannel disconnect () throws IOException;
+ public abstract DatagramChannel disconnect() throws IOException;
/**
* Tells whether or not this channel's socket is connected.
@@ -127,22 +127,22 @@ public abstract class DatagramChannel
* @exception IOException If an error occurs.
* @exception NotYetConnectedException The channel's socket is not connected.
*/
- public abstract boolean isConnected ();
-
+ public abstract boolean isConnected();
+
/**
* Reads data from this channel.
*/
- public abstract int read (ByteBuffer dst) throws IOException;
-
+ public abstract int read(ByteBuffer dst) throws IOException;
+
/**
* Reads data from this channel.
*
* @exception IOException If an error occurs.
* @exception NotYetConnectedException The channel's socket is not connected.
*/
- public abstract long read (ByteBuffer[] dsts, int offset, int length)
+ public abstract long read(ByteBuffer[] dsts, int offset, int length)
throws IOException;
-
+
/**
* Receives a datagram via this channel.
*
@@ -156,8 +156,9 @@ public abstract class DatagramChannel
* @exception SecurityException If a security manager has been installed and
* it does not permit datagrams to be sent to the given address.
*/
- public abstract SocketAddress receive (ByteBuffer dst) throws IOException;
-
+ public abstract SocketAddress receive(ByteBuffer dst)
+ throws IOException;
+
/**
* Sends a datagram via this channel.
*
@@ -171,29 +172,29 @@ public abstract class DatagramChannel
* @exception SecurityException If a security manager has been installed and
* it does not permit datagrams to be sent to the given address.
*/
- public abstract int send (ByteBuffer src, SocketAddress target)
+ public abstract int send(ByteBuffer src, SocketAddress target)
throws IOException;
-
+
/**
* Retrieves the channel's socket.
*/
- public abstract DatagramSocket socket ();
-
+ public abstract DatagramSocket socket();
+
/**
* Writes data to this channel.
*
* @exception IOException If an error occurs.
* @exception NotYetConnectedException The channel's socket is not connected.
*/
- public abstract int write (ByteBuffer src) throws IOException;
-
+ public abstract int write(ByteBuffer src) throws IOException;
+
/**
* Writes data to this channel.
*
* @exception IOException If an error occurs.
* @exception NotYetConnectedException The channel's socket is not connected.
*/
- public abstract long write (ByteBuffer[] srcs, int offset, int length)
+ public abstract long write(ByteBuffer[] srcs, int offset, int length)
throws IOException;
/**
@@ -202,8 +203,8 @@ public abstract class DatagramChannel
* @exception IOException If an error occurs.
* @exception NotYetConnectedException The channel's socket is not connected.
*/
- public final int validOps ()
+ public final int validOps()
{
return SelectionKey.OP_READ | SelectionKey.OP_WRITE;
- }
+ }
}
diff --git a/libjava/java/nio/channels/FileChannel.java b/libjava/java/nio/channels/FileChannel.java
index 6604e99744e..7e1a33173eb 100644
--- a/libjava/java/nio/channels/FileChannel.java
+++ b/libjava/java/nio/channels/FileChannel.java
@@ -1,4 +1,4 @@
-/* FileChannel.java --
+/* FileChannel.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -42,6 +42,7 @@ import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.spi.AbstractInterruptibleChannel;
+
/**
* @author Michael Koch
* @since 1.4
@@ -52,10 +53,9 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
public static class MapMode
{
int m;
-
- public static final MapMode READ_ONLY = new MapMode(0);
+ public static final MapMode READ_ONLY = new MapMode(0);
public static final MapMode READ_WRITE = new MapMode(1);
- public static final MapMode PRIVATE = new MapMode(2);
+ public static final MapMode PRIVATE = new MapMode(2);
/**
* Initializes the MapMode.
@@ -68,12 +68,12 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
/**
* Returns a string representation of the <code>MapMode</code> object.
*/
- public String toString()
+ public String toString()
{
if (this == READ_ONLY)
- return "READ_ONLY";
+ return "READ_ONLY";
else if (this == READ_WRITE)
- return "READ_WRITE";
+ return "READ_WRITE";
return "PRIVATE";
}
@@ -82,7 +82,7 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
/**
* Initializes the channel.
*/
- protected FileChannel ()
+ protected FileChannel()
{
}
@@ -102,34 +102,32 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
/**
* Return the size of the file thus far
- *
+ *
* @exception ClosedChannelException If this channel is closed.
*/
public abstract long size() throws IOException;
-
+
/**
* Writes data to the channel.
*
* @exception IOException If an I/O error occurs.
*/
- public final long write (ByteBuffer[] srcs) throws IOException
+ public final long write(ByteBuffer[] srcs) throws IOException
{
long result = 0;
-
+
for (int i = 0; i < srcs.length; i++)
- {
- result += write (srcs[i]);
- }
-
+ result += write(srcs[i]);
+
return result;
}
-
+
/**
* Writes data to the channel.
*
* @exception IOException If an I/O error occurs.
*/
- public abstract int write (ByteBuffer src) throws IOException;
+ public abstract int write(ByteBuffer src) throws IOException;
/**
* Writes data to the channel.
@@ -145,7 +143,8 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
* @exception NonWritableChannelException If this channel was not opened for
* writing.
*/
- public abstract int write (ByteBuffer srcs, long position) throws IOException;
+ public abstract int write(ByteBuffer srcs, long position)
+ throws IOException;
/**
* Writes data to the channel.
@@ -154,13 +153,13 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
*/
public abstract long write(ByteBuffer[] srcs, int offset, int length)
throws IOException;
-
+
/**
* Reads data from the channel.
*
* @exception IOException If an I/O error occurs.
*/
- public abstract long read (ByteBuffer[] dsts, int offset, int length)
+ public abstract long read(ByteBuffer[] dsts, int offset, int length)
throws IOException;
/**
@@ -168,14 +167,12 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
*
* @exception IOException If an I/O error occurs.
*/
- public final long read (ByteBuffer[] dsts) throws IOException
+ public final long read(ByteBuffer[] dsts) throws IOException
{
long result = 0;
-
+
for (int i = 0; i < dsts.length; i++)
- {
- read (dsts [i]);
- }
+ read(dsts[i]);
return result;
}
@@ -186,7 +183,7 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
* @exception IOException If an I/O error occurs.
*/
public abstract int read(ByteBuffer dst) throws IOException;
-
+
/**
* Reads data from the channel.
*
@@ -201,8 +198,9 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
* @exception NonReadableChannelException If this channel was not opened for
* reading.
*/
- public abstract int read(ByteBuffer dst, long position) throws IOException;
-
+ public abstract int read(ByteBuffer dst, long position)
+ throws IOException;
+
/**
* Closes the channel.
*
@@ -238,9 +236,9 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
* another thread is already blocked in this method and is attempting to lock
* an overlapping region.
*/
- public final FileLock lock () throws IOException
+ public final FileLock lock() throws IOException
{
- return lock (0, Long.MAX_VALUE, false);
+ return lock(0, Long.MAX_VALUE, false);
}
/**
@@ -263,7 +261,7 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
* @exception NonWritableChannelException If shared is false and this channel
* was not opened for writing.
*/
- public abstract FileLock lock (long position, long size, boolean shared)
+ public abstract FileLock lock(long position, long size, boolean shared)
throws IOException;
/**
@@ -276,9 +274,9 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
* another thread is already blocked in this method and is attempting to lock
* an overlapping region.
*/
- public final FileLock tryLock () throws IOException
+ public final FileLock tryLock() throws IOException
{
- return tryLock (0, Long.MAX_VALUE, false);
+ return tryLock(0, Long.MAX_VALUE, false);
}
/**
@@ -293,7 +291,7 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
* another thread is already blocked in this method and is attempting to lock
* an overlapping region.
*/
- public abstract FileLock tryLock (long position, long size, boolean shared)
+ public abstract FileLock tryLock(long position, long size, boolean shared)
throws IOException;
/**
@@ -302,7 +300,7 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
* @exception ClosedChannelException If this channel is closed.
* @exception IOException If an I/O error occurs.
*/
- public abstract long position () throws IOException;
+ public abstract long position() throws IOException;
/**
* Sets the position of the channel on the assoziated file.
@@ -311,7 +309,8 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
* @exception IllegalArgumentException If newPosition is negative.
* @exception IOException If an I/O error occurs.
*/
- public abstract FileChannel position (long newPosition) throws IOException;
+ public abstract FileChannel position(long newPosition)
+ throws IOException;
/**
* Transfers bytes from this channel's file to the given writable byte
@@ -331,8 +330,8 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
* @exception NonWritableChannelException If the target channel was not
* opened for writing.
*/
- public abstract long transferTo (long position, long count,
- WritableByteChannel target)
+ public abstract long transferTo(long position, long count,
+ WritableByteChannel target)
throws IOException;
/**
@@ -352,8 +351,8 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
* @exception NonWritableChannelException If this channel was not opened for
* writing.
*/
- public abstract long transferFrom (ReadableByteChannel src, long position,
- long count) throws IOException;
+ public abstract long transferFrom(ReadableByteChannel src, long position,
+ long count) throws IOException;
/**
* Truncates the channel's file at <code>size</code>.
@@ -364,5 +363,5 @@ public abstract class FileChannel extends AbstractInterruptibleChannel
* @exception NonWritableChannelException If this channel was not opened for
* writing.
*/
- public abstract FileChannel truncate (long size) throws IOException;
+ public abstract FileChannel truncate(long size) throws IOException;
}
diff --git a/libjava/java/nio/channels/FileLock.java b/libjava/java/nio/channels/FileLock.java
index 866ed3997d1..629f5ef79ec 100644
--- a/libjava/java/nio/channels/FileLock.java
+++ b/libjava/java/nio/channels/FileLock.java
@@ -1,4 +1,4 @@
-/* FileLock.java --
+/* FileLock.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,6 +39,7 @@ package java.nio.channels;
import java.io.IOException;
+
/**
* @since 1.4
*/
@@ -48,42 +49,41 @@ public abstract class FileLock
long position;
long size;
boolean shared;
-
+
/**
* Initializes the file lock.
*
* @exception IllegalArgumentException If the preconditions on the parameters do not hold
*/
- protected FileLock (FileChannel channel, long position, long size,
- boolean shared)
+ protected FileLock(FileChannel channel, long position, long size,
+ boolean shared)
{
- if (position < 0 ||
- size < 0)
- throw new IllegalArgumentException ();
+ if (position < 0 || size < 0)
+ throw new IllegalArgumentException();
this.channel = channel;
this.position = position;
this.size = size;
this.shared = shared;
}
-
+
/**
* Tells whether or not this lock is valid.
*/
public abstract boolean isValid();
-
+
/**
* Releases this lock.
*
* @exception IOException If an error occurs
* @exception ClosedChannelException If the locked channel is no longer open.
*/
- public abstract void release () throws IOException;
-
+ public abstract void release() throws IOException;
+
/**
* Returns the file channel upon whose file this lock is held.
*/
- public final FileChannel channel ()
+ public final FileChannel channel()
{
return channel;
}
@@ -91,15 +91,15 @@ public abstract class FileLock
/**
* Tells whether this lock is shared.
*/
- public final boolean isShared ()
+ public final boolean isShared()
{
return shared;
- }
+ }
/**
* Tells whether or not this lock overlaps the given lock range.
*/
- public final boolean overlaps (long position, long size)
+ public final boolean overlaps(long position, long size)
{
if (position > this.position + this.size)
return false;
@@ -114,15 +114,15 @@ public abstract class FileLock
* Returns the position within the file of the first byte of the
* locked region.
*/
- public final long position ()
+ public final long position()
{
return position;
}
-
+
/**
* Returns the size of the locked region in bytes.
*/
- public final long size ()
+ public final long size()
{
return size;
}
@@ -130,7 +130,7 @@ public abstract class FileLock
/**
* Returns a string describing the range, type, and validity of this lock.
*/
- public final String toString ()
+ public final String toString()
{
return "file-lock:pos=" + position + "size=" + size;
}
diff --git a/libjava/java/nio/channels/FileLockInterruptionException.java b/libjava/java/nio/channels/FileLockInterruptionException.java
index 563b0a08fe7..5caff170743 100644
--- a/libjava/java/nio/channels/FileLockInterruptionException.java
+++ b/libjava/java/nio/channels/FileLockInterruptionException.java
@@ -1,4 +1,4 @@
-/* FileLockInterruptionException.java --
+/* FileLockInterruptionException.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,6 +39,7 @@ package java.nio.channels;
import java.io.IOException;
+
/**
* @author Michael Koch
* @since 1.4
diff --git a/libjava/java/nio/channels/GatheringByteChannel.java b/libjava/java/nio/channels/GatheringByteChannel.java
index 1528e56175c..80f50c875fe 100644
--- a/libjava/java/nio/channels/GatheringByteChannel.java
+++ b/libjava/java/nio/channels/GatheringByteChannel.java
@@ -1,4 +1,4 @@
-/* GatheringByteChannel.java --
+/* GatheringByteChannel.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,11 +37,11 @@ exception statement from your version. */
package java.nio.channels;
-import java.nio.ByteBuffer;
import java.io.IOException;
+import java.nio.ByteBuffer;
-public interface GatheringByteChannel
- extends WritableByteChannel
+
+public interface GatheringByteChannel extends WritableByteChannel
{
/**
* Writes a sequence of bytes to this channel from a subsequence of
@@ -59,9 +59,9 @@ public interface GatheringByteChannel
* @exception NonWritableChannelException If this channel was not opened for
* writing
*/
- long write (ByteBuffer[] srcs, int offset, int length)
+ long write(ByteBuffer[] srcs, int offset, int length)
throws IOException;
-
+
/**
* Writes a sequence of bytes to this channel from the given buffers
*
@@ -75,5 +75,5 @@ public interface GatheringByteChannel
* @exception NonWritableChannelException If this channel was not opened for
* writing
*/
- long write (ByteBuffer[] srcs) throws IOException;
+ long write(ByteBuffer[] srcs) throws IOException;
}
diff --git a/libjava/java/nio/channels/IllegalBlockingModeException.java b/libjava/java/nio/channels/IllegalBlockingModeException.java
index dca8110059b..5b70c1f5814 100644
--- a/libjava/java/nio/channels/IllegalBlockingModeException.java
+++ b/libjava/java/nio/channels/IllegalBlockingModeException.java
@@ -1,4 +1,4 @@
-/* IllegalBlockingModeException.java --
+/* IllegalBlockingModeException.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,6 +37,7 @@ exception statement from your version. */
package java.nio.channels;
+
/**
* @author Michael Koch <konqueror@gmx.de>
* @since 1.4
diff --git a/libjava/java/nio/channels/IllegalSelectorException.java b/libjava/java/nio/channels/IllegalSelectorException.java
index 20465e56b1d..d1421e45653 100644
--- a/libjava/java/nio/channels/IllegalSelectorException.java
+++ b/libjava/java/nio/channels/IllegalSelectorException.java
@@ -1,4 +1,4 @@
-/* IllegalSelectorException.java --
+/* IllegalSelectorException.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,6 +37,7 @@ exception statement from your version. */
package java.nio.channels;
+
/**
* @author Michael Koch
* @since 1.4
diff --git a/libjava/java/nio/channels/InterruptibleChannel.java b/libjava/java/nio/channels/InterruptibleChannel.java
index 0b55e7619a5..ad4195efb0f 100644
--- a/libjava/java/nio/channels/InterruptibleChannel.java
+++ b/libjava/java/nio/channels/InterruptibleChannel.java
@@ -1,4 +1,4 @@
-/* InterruptibleChannel.java --
+/* InterruptibleChannel.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,6 +39,7 @@ package java.nio.channels;
import java.io.IOException;
+
public interface InterruptibleChannel extends Channel
{
/**
diff --git a/libjava/java/nio/channels/NoConnectionPendingException.java b/libjava/java/nio/channels/NoConnectionPendingException.java
index f859cf6f651..4dbe7f96a85 100644
--- a/libjava/java/nio/channels/NoConnectionPendingException.java
+++ b/libjava/java/nio/channels/NoConnectionPendingException.java
@@ -1,4 +1,4 @@
-/* NoConnectionPendingException.java --
+/* NoConnectionPendingException.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,6 +37,7 @@ exception statement from your version. */
package java.nio.channels;
+
/**
* @author Michael Koch
* @since 1.4
diff --git a/libjava/java/nio/channels/NonReadableChannelException.java b/libjava/java/nio/channels/NonReadableChannelException.java
index cb146bb5133..ff3bd4a9edf 100644
--- a/libjava/java/nio/channels/NonReadableChannelException.java
+++ b/libjava/java/nio/channels/NonReadableChannelException.java
@@ -1,4 +1,4 @@
-/* NonReadableChannelException.java --
+/* NonReadableChannelException.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,6 +37,7 @@ exception statement from your version. */
package java.nio.channels;
+
/**
* @author Michael Koch
* @since 1.4
diff --git a/libjava/java/nio/channels/NonWritableChannelException.java b/libjava/java/nio/channels/NonWritableChannelException.java
index a26af3537c2..363041ba97a 100644
--- a/libjava/java/nio/channels/NonWritableChannelException.java
+++ b/libjava/java/nio/channels/NonWritableChannelException.java
@@ -1,4 +1,4 @@
-/* NonWritableChannelException.java --
+/* NonWritableChannelException.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,6 +37,7 @@ exception statement from your version. */
package java.nio.channels;
+
/**
* @author Michael Koch
* @since 1.4
diff --git a/libjava/java/nio/channels/NotYetBoundException.java b/libjava/java/nio/channels/NotYetBoundException.java
index 0367b35e90d..167d5b5be64 100644
--- a/libjava/java/nio/channels/NotYetBoundException.java
+++ b/libjava/java/nio/channels/NotYetBoundException.java
@@ -1,4 +1,4 @@
-/* NotYetBoundException.java --
+/* NotYetBoundException.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,6 +37,7 @@ exception statement from your version. */
package java.nio.channels;
+
/**
* @author Michael Koch
* @since 1.4
diff --git a/libjava/java/nio/channels/NotYetConnectedException.java b/libjava/java/nio/channels/NotYetConnectedException.java
index 3c15369611b..671ad1a421d 100644
--- a/libjava/java/nio/channels/NotYetConnectedException.java
+++ b/libjava/java/nio/channels/NotYetConnectedException.java
@@ -1,4 +1,4 @@
-/* NotYetConnectedException.java --
+/* NotYetConnectedException.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,6 +37,7 @@ exception statement from your version. */
package java.nio.channels;
+
/**
* @author Michael Koch
* @since 1.4
diff --git a/libjava/java/nio/channels/OverlappingFileLockException.java b/libjava/java/nio/channels/OverlappingFileLockException.java
index 2f856d3ea73..d3435264dab 100644
--- a/libjava/java/nio/channels/OverlappingFileLockException.java
+++ b/libjava/java/nio/channels/OverlappingFileLockException.java
@@ -1,4 +1,4 @@
-/* OverlappingFileLockException.java --
+/* OverlappingFileLockException.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,6 +37,7 @@ exception statement from your version. */
package java.nio.channels;
+
/**
* @author Michael Koch
* @since 1.4
diff --git a/libjava/java/nio/channels/Pipe.java b/libjava/java/nio/channels/Pipe.java
index 939d7b52ad2..baee1fa563d 100644
--- a/libjava/java/nio/channels/Pipe.java
+++ b/libjava/java/nio/channels/Pipe.java
@@ -1,4 +1,4 @@
-/* Pipe.java --
+/* Pipe.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -41,22 +41,22 @@ import java.io.IOException;
import java.nio.channels.spi.AbstractSelectableChannel;
import java.nio.channels.spi.SelectorProvider;
+
/**
* @author Michael Koch
* @since 1.4
*/
public abstract class Pipe
{
- public abstract static class SinkChannel
- extends AbstractSelectableChannel
+ public abstract static class SinkChannel extends AbstractSelectableChannel
implements WritableByteChannel, GatheringByteChannel
{
/**
* Initializes the channel.
*/
- protected SinkChannel (SelectorProvider provider)
+ protected SinkChannel(SelectorProvider provider)
{
- super (provider);
+ super(provider);
}
/**
@@ -64,22 +64,21 @@ public abstract class Pipe
*
* The only valid operation on this channel is @see SelectionKey.OP_WRITE.
*/
- public final int validOps ()
+ public final int validOps()
{
return SelectionKey.OP_WRITE;
}
}
- public abstract static class SourceChannel
- extends AbstractSelectableChannel
+ public abstract static class SourceChannel extends AbstractSelectableChannel
implements ReadableByteChannel, ScatteringByteChannel
{
/**
* Initializes the channel.
*/
- protected SourceChannel (SelectorProvider provider)
+ protected SourceChannel(SelectorProvider provider)
{
- super (provider);
+ super(provider);
}
/**
@@ -87,7 +86,7 @@ public abstract class Pipe
*
* The only valid operation on this channel is @see SelectionKey.OP_READ.
*/
- public final int validOps ()
+ public final int validOps()
{
return SelectionKey.OP_READ;
}
@@ -102,12 +101,12 @@ public abstract class Pipe
/**
* Opens a pipe.
- *
+ *
* @exception IOException If an error occurs
*/
public static Pipe open() throws IOException
{
- return SelectorProvider.provider ().openPipe();
+ return SelectorProvider.provider().openPipe();
}
/**
@@ -118,5 +117,5 @@ public abstract class Pipe
/**
* Returns a pipe's source channel
*/
- public abstract Pipe.SourceChannel source();
+ public abstract Pipe.SourceChannel source();
}
diff --git a/libjava/java/nio/channels/ReadableByteChannel.java b/libjava/java/nio/channels/ReadableByteChannel.java
index f870e6bdfa8..fb39dcb582f 100644
--- a/libjava/java/nio/channels/ReadableByteChannel.java
+++ b/libjava/java/nio/channels/ReadableByteChannel.java
@@ -1,5 +1,5 @@
-/* ReadableByteChannel.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+/* ReadableByteChannel.java --
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,11 +40,16 @@ package java.nio.channels;
import java.io.IOException;
import java.nio.ByteBuffer;
+
public interface ReadableByteChannel extends Channel
{
/**
* Reads a sequence of bytes from this channel into the given buffer
*
+ * @param dst the buffer to put the read data into
+ *
+ * @return the numer of bytes read
+ *
* @exception AsynchronousCloseException If another thread closes this
* channel while the read operation is in progress
* @exception ClosedByInterruptException If another thread interrupts the
@@ -55,5 +60,5 @@ public interface ReadableByteChannel extends Channel
* @exception NonReadableChannelException If this channel was not opened for
* reading
*/
- int read (ByteBuffer dst) throws IOException;
+ int read(ByteBuffer dst) throws IOException;
}
diff --git a/libjava/java/nio/channels/ScatteringByteChannel.java b/libjava/java/nio/channels/ScatteringByteChannel.java
index bd8bb6cac4d..7c754065f97 100644
--- a/libjava/java/nio/channels/ScatteringByteChannel.java
+++ b/libjava/java/nio/channels/ScatteringByteChannel.java
@@ -1,4 +1,4 @@
-/* ScatteringByteChannel.java --
+/* ScatteringByteChannel.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,11 +37,11 @@ exception statement from your version. */
package java.nio.channels;
-import java.nio.ByteBuffer;
import java.io.IOException;
+import java.nio.ByteBuffer;
+
-public interface ScatteringByteChannel
- extends ReadableByteChannel
+public interface ScatteringByteChannel extends ReadableByteChannel
{
/**
* Reads a sequence of bytes from this channel into a subsequence of the
@@ -59,7 +59,7 @@ public interface ScatteringByteChannel
* @exception NonReadableChannelException If this channel was not opened for
* reading
*/
- long read (ByteBuffer[] srcs, int offset, int length)
+ long read(ByteBuffer[] srcs, int offset, int length)
throws IOException;
/**
@@ -75,5 +75,5 @@ public interface ScatteringByteChannel
* @exception NonReadableChannelException If this channel was not opened for
* reading
*/
- long read (ByteBuffer[] srcs) throws IOException;
+ long read(ByteBuffer[] srcs) throws IOException;
}
diff --git a/libjava/java/nio/channels/SelectableChannel.java b/libjava/java/nio/channels/SelectableChannel.java
index 72abac89654..de1e31d076b 100644
--- a/libjava/java/nio/channels/SelectableChannel.java
+++ b/libjava/java/nio/channels/SelectableChannel.java
@@ -1,4 +1,4 @@
-/* SelectableChannel.java --
+/* SelectableChannel.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -41,62 +41,62 @@ import java.io.IOException;
import java.nio.channels.spi.AbstractInterruptibleChannel;
import java.nio.channels.spi.SelectorProvider;
+
/**
* @author Michael Koch
* @since 1.4
*/
-public abstract class SelectableChannel
- extends AbstractInterruptibleChannel
+public abstract class SelectableChannel extends AbstractInterruptibleChannel
{
/**
* Initializes the channel.
*/
- protected SelectableChannel ()
+ protected SelectableChannel()
{
}
-
+
/**
* Returns the lock of this channel.
*/
- public abstract Object blockingLock ();
+ public abstract Object blockingLock();
/**
* Adjusts this channel's blocking mode.
- *
+ *
* @exception ClosedChannelException If this channel is closed.
* @exception IllegalBlockingModeException If block is true and this channel
* is registered with one or more selectors.
* @exception IOException If an error occurs.
*/
- public abstract SelectableChannel configureBlocking (boolean block)
+ public abstract SelectableChannel configureBlocking(boolean block)
throws IOException;
-
+
/**
* Tells whether this channel is blocking or not.
*/
- public abstract boolean isBlocking ();
-
+ public abstract boolean isBlocking();
+
/**
* Tells whether or not this channel is currently registered with
* any selectors.
*/
- public abstract boolean isRegistered ();
-
+ public abstract boolean isRegistered();
+
/**
* Retrieves the key representing the channel's registration with
* the given selector.
*/
- public abstract SelectionKey keyFor (Selector sel);
-
+ public abstract SelectionKey keyFor(Selector sel);
+
/**
* Returns the provider that created this channel.
*/
- public abstract SelectorProvider provider ();
-
+ public abstract SelectorProvider provider();
+
/**
* Registers this channel with the given selector,
* returning a selection key.
- *
+ *
* @exception CancelledKeyException If this channel is currently registered
* with the given selector but the corresponding key has already been cancelled
* @exception ClosedChannelException If this channel is closed.
@@ -108,12 +108,12 @@ public abstract class SelectableChannel
* @exception IllegalSelectorException If this channel was not created by
* the same provider as the given selector.
*/
- public final SelectionKey register (Selector sel, int ops)
+ public final SelectionKey register(Selector sel, int ops)
throws ClosedChannelException
{
- return register (sel, ops, null);
+ return register(sel, ops, null);
}
-
+
/**
* Registers this channel with the given selector,
* returning a selection key.
@@ -130,9 +130,9 @@ public abstract class SelectableChannel
* @exception IllegalSelectorException If this channel was not created by
* the same provider as the given selector.
*/
- public abstract SelectionKey register (Selector sel, int ops, Object att)
+ public abstract SelectionKey register(Selector sel, int ops, Object att)
throws ClosedChannelException;
-
+
/**
* Returns a set of valid operations on this channel.
*/
diff --git a/libjava/java/nio/channels/SelectionKey.java b/libjava/java/nio/channels/SelectionKey.java
index 39b66f1902a..95e7f26fce4 100644
--- a/libjava/java/nio/channels/SelectionKey.java
+++ b/libjava/java/nio/channels/SelectionKey.java
@@ -1,4 +1,4 @@
-/* SelectionKey.java --
+/* SelectionKey.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,128 +37,128 @@ exception statement from your version. */
package java.nio.channels;
+
/**
* @author Michael Koch
* @since 1.4
*/
public abstract class SelectionKey
{
- public static final int OP_ACCEPT = 16;
+ public static final int OP_ACCEPT = 16;
public static final int OP_CONNECT = 8;
- public static final int OP_READ = 1;
- public static final int OP_WRITE = 4;
-
+ public static final int OP_READ = 1;
+ public static final int OP_WRITE = 4;
Object attached;
-
+
/**
* Initializes the selection key.
*/
- protected SelectionKey ()
+ protected SelectionKey()
{
}
/**
* Attaches obj to the key and returns the old attached object.
*/
- public final Object attach (Object obj)
+ public final Object attach(Object obj)
{
Object old = attached;
attached = obj;
return old;
}
-
+
/**
* Returns the object attached to the key.
*/
- public final Object attachment ()
+ public final Object attachment()
{
return attached;
- }
+ }
/**
* Tests if the channel attached to this key is ready to accept
* a new socket connection.
- *
+ *
* @exception CancelledKeyException If this key has been cancelled
*/
- public final boolean isAcceptable ()
- {
- return (readyOps () & OP_ACCEPT) != 0;
+ public final boolean isAcceptable()
+ {
+ return (readyOps() & OP_ACCEPT) != 0;
}
/**
* Tests whether this key's channel has either finished,
* or failed to finish, its socket-connection operation.
- *
+ *
* @exception CancelledKeyException If this key has been cancelled
*/
- public final boolean isConnectable ()
+ public final boolean isConnectable()
{
- return (readyOps () & OP_CONNECT) != 0;
- }
-
+ return (readyOps() & OP_CONNECT) != 0;
+ }
+
/**
* Tests if the channel attached to the key is readable.
- *
+ *
* @exception CancelledKeyException If this key has been cancelled
*/
- public final boolean isReadable ()
+ public final boolean isReadable()
{
- return (readyOps () & OP_READ) != 0;
+ return (readyOps() & OP_READ) != 0;
}
-
+
/**
* Tests if the channel attached to the key is writable.
*
* @exception CancelledKeyException If this key has been cancelled
*/
- public final boolean isWritable ()
+ public final boolean isWritable()
{
- return (readyOps () & OP_WRITE) != 0;
+ return (readyOps() & OP_WRITE) != 0;
}
/**
* Requests that the registration of this key's channel with
* its selector be cancelled.
*/
- public abstract void cancel ();
-
+ public abstract void cancel();
+
/**
* return the channel attached to the key.
*/
- public abstract SelectableChannel channel ();
-
+ public abstract SelectableChannel channel();
+
/**
* Returns the key's interest set.
- *
+ *
* @exception CancelledKeyException If this key has been cancelled
*/
- public abstract int interestOps ();
-
+ public abstract int interestOps();
+
/**
* Sets this key's interest set to the given value.
- *
+ *
* @exception CancelledKeyException If this key has been cancelled
* @exception IllegalArgumentException If a bit in the set does not
* correspond to an operation that is supported by this key's channel,
* that is, if set &amp; ~(channel().validOps()) != 0
*/
- public abstract SelectionKey interestOps (int ops);
-
+ public abstract SelectionKey interestOps(int ops);
+
/**
* Tells whether or not this key is valid.
*/
- public abstract boolean isValid ();
-
+ public abstract boolean isValid();
+
/**
* Retrieves this key's ready-operation set.
- *
+ *
* @exception CancelledKeyException If this key has been cancelled
*/
- public abstract int readyOps ();
-
+ public abstract int readyOps();
+
/**
* Returns the selector for which this key was created.
*/
- public abstract Selector selector ();
+ public abstract Selector selector();
}
diff --git a/libjava/java/nio/channels/Selector.java b/libjava/java/nio/channels/Selector.java
index 695969b5b3a..0eee121e27d 100644
--- a/libjava/java/nio/channels/Selector.java
+++ b/libjava/java/nio/channels/Selector.java
@@ -1,4 +1,4 @@
-/* Selector.java --
+/* Selector.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -41,6 +41,7 @@ import java.io.IOException;
import java.nio.channels.spi.SelectorProvider;
import java.util.Set;
+
/**
* @author Michael Koch
* @since 1.4
@@ -53,81 +54,81 @@ public abstract class Selector
protected Selector()
{
}
-
+
/**
* Opens a selector.
- *
+ *
* @exception IOException If an error occurs
*/
- public static Selector open () throws IOException
+ public static Selector open() throws IOException
{
- return SelectorProvider.provider ().openSelector ();
+ return SelectorProvider.provider().openSelector();
}
/**
* Closes the selector.
- *
+ *
* @exception IOException If an error occurs
*/
- public abstract void close () throws IOException;
-
+ public abstract void close() throws IOException;
+
/**
* Tells whether the selector is open or not.
*/
- public abstract boolean isOpen ();
-
+ public abstract boolean isOpen();
+
/**
* Returns this selector's key set.
- *
+ *
* @exception ClosedSelectorException If this selector is closed.
*/
- public abstract Set keys ();
-
+ public abstract Set keys();
+
/**
* Returns the SelectorProvider that created the selector.
*/
- public abstract SelectorProvider provider ();
-
+ public abstract SelectorProvider provider();
+
/**
* Selects a set of keys whose corresponding channels are ready
* for I/O operations.
- *
+ *
* @exception ClosedSelectorException If this selector is closed.
* @exception IOException If an error occurs
*/
- public abstract int select () throws IOException;
-
+ public abstract int select() throws IOException;
+
/**
* Selects a set of keys whose corresponding channels are ready
* for I/O operations.
*
* @param timeout The timeout to use.
- *
+ *
* @exception ClosedSelectorException If this selector is closed.
* @exception IllegalArgumentException If the timeout value is negative.
* @exception IOException If an error occurs
*/
- public abstract int select (long timeout) throws IOException;
-
+ public abstract int select(long timeout) throws IOException;
+
/**
* Returns this selector's selected-key set.
- *
+ *
* @exception ClosedSelectorException If this selector is closed.
*/
- public abstract Set selectedKeys ();
-
+ public abstract Set selectedKeys();
+
/**
* Selects a set of keys whose corresponding channels are ready
* for I/O operations.
- *
+ *
* @exception ClosedSelectorException If this selector is closed.
* @exception IOException If an error occurs
*/
- public abstract int selectNow () throws IOException;
-
+ public abstract int selectNow() throws IOException;
+
/**
* Causes the first selection operation that has not yet returned to
* return immediately.
*/
- public abstract Selector wakeup ();
+ public abstract Selector wakeup();
}
diff --git a/libjava/java/nio/channels/ServerSocketChannel.java b/libjava/java/nio/channels/ServerSocketChannel.java
index a116731c602..4b9db4f6316 100644
--- a/libjava/java/nio/channels/ServerSocketChannel.java
+++ b/libjava/java/nio/channels/ServerSocketChannel.java
@@ -1,4 +1,4 @@
-/* ServerSocketChannel.java --
+/* ServerSocketChannel.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -35,29 +35,28 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.nio.channels;
-import java.nio.channels.spi.AbstractSelectableChannel;
-import java.nio.channels.spi.SelectorProvider;
import java.io.IOException;
import java.net.ServerSocket;
+import java.nio.channels.spi.AbstractSelectableChannel;
+import java.nio.channels.spi.SelectorProvider;
+
/**
* @author Michael Koch
* @since 1.4
*/
-public abstract class ServerSocketChannel
- extends AbstractSelectableChannel
+public abstract class ServerSocketChannel extends AbstractSelectableChannel
{
/**
* Initializes this channel.
*/
- protected ServerSocketChannel (SelectorProvider provider)
+ protected ServerSocketChannel(SelectorProvider provider)
{
- super (provider);
+ super(provider);
}
-
+
/**
* Accepts a connection made to this channel's socket.
*
@@ -72,28 +71,28 @@ public abstract class ServerSocketChannel
* @exception SecurityException If a security manager has been installed and
* it does not permit access to the remote endpoint of the new connection.
*/
- public abstract SocketChannel accept () throws IOException;
-
+ public abstract SocketChannel accept() throws IOException;
+
/**
* Retrieves the channels socket.
*/
- public abstract ServerSocket socket ();
-
+ public abstract ServerSocket socket();
+
/**
* Opens a server socket channel.
*
* @exception IOException If an error occurs
*/
- public static ServerSocketChannel open () throws IOException
+ public static ServerSocketChannel open() throws IOException
{
- return SelectorProvider.provider ().openServerSocketChannel ();
+ return SelectorProvider.provider().openServerSocketChannel();
}
/**
* Retrieves the valid operations for this channel.
*/
- public final int validOps ()
+ public final int validOps()
{
return SelectionKey.OP_ACCEPT;
- }
+ }
}
diff --git a/libjava/java/nio/channels/SocketChannel.java b/libjava/java/nio/channels/SocketChannel.java
index 93633002e51..933f866c9a5 100644
--- a/libjava/java/nio/channels/SocketChannel.java
+++ b/libjava/java/nio/channels/SocketChannel.java
@@ -1,4 +1,4 @@
-/* SocketChannel.java --
+/* SocketChannel.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,38 +37,39 @@ exception statement from your version. */
package java.nio.channels;
-import java.nio.channels.spi.AbstractSelectableChannel;
-import java.nio.channels.spi.SelectorProvider;
-import java.nio.ByteBuffer;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.spi.AbstractSelectableChannel;
+import java.nio.channels.spi.SelectorProvider;
+
/**
* @author Michael Koch
* @since 1.4
*/
-abstract public class SocketChannel extends AbstractSelectableChannel
+public abstract class SocketChannel extends AbstractSelectableChannel
implements ByteChannel, ScatteringByteChannel, GatheringByteChannel
{
/**
* Initializes this socket.
*/
- protected SocketChannel (SelectorProvider provider)
+ protected SocketChannel(SelectorProvider provider)
{
- super (provider);
+ super(provider);
}
-
+
/**
* Opens a socket channel.
*
* @exception IOException If an error occurs
*/
- public static SocketChannel open () throws IOException
+ public static SocketChannel open() throws IOException
{
- return SelectorProvider.provider ().openSocketChannel ();
+ return SelectorProvider.provider().openSocketChannel();
}
-
+
/**
* Opens a channel and connects it to a remote address.
*
@@ -84,55 +85,53 @@ abstract public class SocketChannel extends AbstractSelectableChannel
* @exception UnsupportedAddressTypeException If the type of the given remote
* address is not supported.
*/
- public static SocketChannel open (SocketAddress remote) throws IOException
+ public static SocketChannel open(SocketAddress remote)
+ throws IOException
{
- SocketChannel ch = open ();
+ SocketChannel ch = open();
ch.connect(remote);
return ch;
}
-
+
/**
* Reads data from the channel.
*
* @exception IOException If an error occurs
* @exception NotYetConnectedException If this channel is not yet connected.
*/
- public final long read (ByteBuffer[] dsts) throws IOException
+ public final long read(ByteBuffer[] dsts) throws IOException
{
long b = 0;
-
+
for (int i = 0; i < dsts.length; i++)
- {
- b += read (dsts [i]);
- }
-
+ b += read(dsts[i]);
+
return b;
}
-
+
/**
* Writes data to the channel.
*
* @exception IOException If an error occurs
* @exception NotYetConnectedException If this channel is not yet connected.
*/
- public final long write (ByteBuffer[] dsts) throws IOException
+ public final long write(ByteBuffer[] dsts) throws IOException
{
long b = 0;
- for (int i= 0; i < dsts.length; i++)
- {
- b += write (dsts [i]);
- }
-
+ for (int i = 0; i < dsts.length; i++)
+ b += write(dsts[i]);
+
return b;
- }
-
+ }
+
/**
* Retrieves the valid operations for this channel.
*/
- public final int validOps ()
+ public final int validOps()
{
- return SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE;
+ return SelectionKey.OP_CONNECT | SelectionKey.OP_READ
+ | SelectionKey.OP_WRITE;
}
/**
@@ -141,7 +140,7 @@ abstract public class SocketChannel extends AbstractSelectableChannel
* @exception IOException If an error occurs
* @exception NotYetConnectedException If this channel is not yet connected.
*/
- public abstract int read (ByteBuffer dst) throws IOException;
+ public abstract int read(ByteBuffer dst) throws IOException;
/**
* Connects the channel's socket to the remote address.
@@ -162,8 +161,9 @@ abstract public class SocketChannel extends AbstractSelectableChannel
* @exception UnsupportedAddressTypeException If the type of the given remote
* address is not supported.
*/
- public abstract boolean connect (SocketAddress remote) throws IOException;
-
+ public abstract boolean connect(SocketAddress remote)
+ throws IOException;
+
/**
* Finishes the process of connecting a socket channel.
*
@@ -176,46 +176,46 @@ abstract public class SocketChannel extends AbstractSelectableChannel
* @exception NoConnectionPendingException If this channel is not connected
* and a connection operation has not been initiated.
*/
- public abstract boolean finishConnect () throws IOException;
-
+ public abstract boolean finishConnect() throws IOException;
+
/**
* Tells whether or not the channel's socket is connected.
*/
- public abstract boolean isConnected ();
-
+ public abstract boolean isConnected();
+
/**
* Tells whether or not a connection operation is in progress on this channel.
*/
- public abstract boolean isConnectionPending ();
-
+ public abstract boolean isConnectionPending();
+
/**
* Reads data from the channel.
*
* @exception IOException If an error occurs
* @exception NotYetConnectedException If this channel is not yet connected.
*/
- public abstract long read (ByteBuffer[] dsts, int offset, int length)
+ public abstract long read(ByteBuffer[] dsts, int offset, int length)
throws IOException;
-
+
/**
* Retrieves the channel's socket.
*/
- public abstract Socket socket ();
-
+ public abstract Socket socket();
+
/**
* Writes data to the channel.
*
* @exception IOException If an error occurs
* @exception NotYetConnectedException If this channel is not yet connected.
*/
- public abstract int write (ByteBuffer src) throws IOException;
-
+ public abstract int write(ByteBuffer src) throws IOException;
+
/**
* Writes data to the channel.
*
* @exception IOException If an error occurs
* @exception NotYetConnectedException If this channel is not yet connected.
*/
- public abstract long write (ByteBuffer[] srcs, int offset, int length)
+ public abstract long write(ByteBuffer[] srcs, int offset, int length)
throws IOException;
}
diff --git a/libjava/java/nio/channels/UnresolvedAddressException.java b/libjava/java/nio/channels/UnresolvedAddressException.java
index 1cfdf970dca..f8e74a9d2f2 100644
--- a/libjava/java/nio/channels/UnresolvedAddressException.java
+++ b/libjava/java/nio/channels/UnresolvedAddressException.java
@@ -1,4 +1,4 @@
-/* UnresolvedAddressException.java --
+/* UnresolvedAddressException.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,6 +37,7 @@ exception statement from your version. */
package java.nio.channels;
+
/**
* @author Michael Koch
* @since 1.4
diff --git a/libjava/java/nio/channels/UnsupportedAddressTypeException.java b/libjava/java/nio/channels/UnsupportedAddressTypeException.java
index 824772a235b..adea4ed7060 100644
--- a/libjava/java/nio/channels/UnsupportedAddressTypeException.java
+++ b/libjava/java/nio/channels/UnsupportedAddressTypeException.java
@@ -1,4 +1,4 @@
-/* UnsupportedAddressTypeException.java --
+/* UnsupportedAddressTypeException.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,6 +37,7 @@ exception statement from your version. */
package java.nio.channels;
+
/**
* @author Michael Koch
* @since 1.4
diff --git a/libjava/java/nio/channels/WritableByteChannel.java b/libjava/java/nio/channels/WritableByteChannel.java
index 7b66f5d35a2..0cc6858a402 100644
--- a/libjava/java/nio/channels/WritableByteChannel.java
+++ b/libjava/java/nio/channels/WritableByteChannel.java
@@ -1,4 +1,4 @@
-/* WritableByteChannel.java --
+/* WritableByteChannel.java --
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,8 +40,8 @@ package java.nio.channels;
import java.io.IOException;
import java.nio.ByteBuffer;
-public interface WritableByteChannel
- extends Channel
+
+public interface WritableByteChannel extends Channel
{
/**
* Writes a sequence of bytes to this channel from the given buffer
@@ -56,5 +56,5 @@ public interface WritableByteChannel
* @exception NonWritableChannelException If this channel was not opened for
* writing
*/
- int write (ByteBuffer src) throws IOException;
+ int write(ByteBuffer src) throws IOException;
}
diff --git a/libjava/java/nio/channels/spi/AbstractInterruptibleChannel.java b/libjava/java/nio/channels/spi/AbstractInterruptibleChannel.java
index 5d9f886ac39..98eaf482a2e 100644
--- a/libjava/java/nio/channels/spi/AbstractInterruptibleChannel.java
+++ b/libjava/java/nio/channels/spi/AbstractInterruptibleChannel.java
@@ -1,5 +1,5 @@
/* AbstractInterruptibleChannel.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -42,6 +42,7 @@ import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.Channel;
import java.nio.channels.InterruptibleChannel;
+
/**
* @author Michael Koch
* @since 1.4
@@ -54,25 +55,25 @@ public abstract class AbstractInterruptibleChannel
/**
* Initializes the channel.
*/
- protected AbstractInterruptibleChannel ()
+ protected AbstractInterruptibleChannel()
{
}
/**
* Marks the beginning of an I/O operation that might block indefinitely.
*/
- protected final void begin ()
+ protected final void begin()
{
}
-
+
/**
* Closes the channel.
- *
+ *
* @exception IOException If an error occurs
*/
- public final void close () throws IOException
+ public final void close() throws IOException
{
- if (!closed)
+ if (! closed)
{
closed = true;
implCloseChannel();
@@ -81,29 +82,38 @@ public abstract class AbstractInterruptibleChannel
/**
* Marks the end of an I/O operation that might block indefinitely.
- *
+ *
+ * @param completed true if the task completed successfully,
+ * false otherwise
+ *
+ * @exception IOException if an error occurs
* @exception AsynchronousCloseException If the channel was asynchronously
* closed.
* @exception ClosedByInterruptException If the thread blocked in the
* I/O operation was interrupted.
*/
- protected final void end (boolean completed)
+ protected final void end(boolean completed)
throws AsynchronousCloseException
{
- }
+ // FIXME: check more here.
+
+ if (closed) throw new AsynchronousCloseException();
+ }
/**
* Closes the channel.
- *
+ *
* @exception IOException If an error occurs
*/
- protected abstract void implCloseChannel () throws IOException;
+ protected abstract void implCloseChannel() throws IOException;
/**
* Tells whether or not this channel is open.
+ *
+ * @return true if the channel is open, false otherwise
*/
- public final boolean isOpen ()
+ public final boolean isOpen()
{
- return !closed;
+ return ! closed;
}
}
diff --git a/libjava/java/nio/channels/spi/AbstractSelectableChannel.java b/libjava/java/nio/channels/spi/AbstractSelectableChannel.java
index a07485df85f..ccc48c93c95 100644
--- a/libjava/java/nio/channels/spi/AbstractSelectableChannel.java
+++ b/libjava/java/nio/channels/spi/AbstractSelectableChannel.java
@@ -43,9 +43,9 @@ import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.LinkedList;
-import java.util.List;
import java.util.ListIterator;
+
public abstract class AbstractSelectableChannel extends SelectableChannel
{
private boolean blocking = true;
@@ -55,8 +55,10 @@ public abstract class AbstractSelectableChannel extends SelectableChannel
/**
* Initializes the channel
+ *
+ * @param provider the provider that created this channel
*/
- protected AbstractSelectableChannel (SelectorProvider provider)
+ protected AbstractSelectableChannel(SelectorProvider provider)
{
this.provider = provider;
}
@@ -64,27 +66,35 @@ public abstract class AbstractSelectableChannel extends SelectableChannel
/**
* Retrieves the object upon which the configureBlocking and register
* methods synchronize.
+ *
+ * @return the blocking lock
*/
- public final Object blockingLock ()
+ public final Object blockingLock()
{
return LOCK;
}
-
+
/**
* Adjusts this channel's blocking mode.
+ *
+ * @param blocking true if blocking should be enabled, false otherwise
+ *
+ * @return this channel
+ *
+ * @exception IOException If an error occurs
*/
- public final SelectableChannel configureBlocking (boolean blocking)
+ public final SelectableChannel configureBlocking(boolean blocking)
throws IOException
{
synchronized (blockingLock())
{
- if (this.blocking != blocking)
- {
- implConfigureBlocking(blocking);
- this.blocking = blocking;
- }
+ if (this.blocking != blocking)
+ {
+ implConfigureBlocking(blocking);
+ this.blocking = blocking;
+ }
}
-
+
return this;
}
@@ -93,25 +103,34 @@ public abstract class AbstractSelectableChannel extends SelectableChannel
*
* @exception IOException If an error occurs
*/
- protected final void implCloseChannel () throws IOException
+ protected final void implCloseChannel() throws IOException
{
- implCloseSelectableChannel ();
+ implCloseSelectableChannel();
}
/**
* Closes this selectable channel.
+ *
+ * @exception IOException If an error occurs
*/
- protected abstract void implCloseSelectableChannel () throws IOException;
-
+ protected abstract void implCloseSelectableChannel()
+ throws IOException;
+
/**
* Adjusts this channel's blocking mode.
+ *
+ * @param blocking true if blocking should be enabled, false otherwise
+ *
+ * @exception IOException If an error occurs
*/
- protected abstract void implConfigureBlocking (boolean block)
+ protected abstract void implConfigureBlocking(boolean blocking)
throws IOException;
/**
* Tells whether or not every I/O operation on this channel will block
* until it completes.
+ *
+ * @return true of this channel is blocking, false otherwise
*/
public final boolean isBlocking()
{
@@ -121,87 +140,104 @@ public abstract class AbstractSelectableChannel extends SelectableChannel
/**
* Tells whether or not this channel is currently registered with
* any selectors.
+ *
+ * @return true if this channel is registered, false otherwise
*/
public final boolean isRegistered()
{
- return !keys.isEmpty();
+ return ! keys.isEmpty();
}
/**
* Retrieves the key representing the channel's registration with the
* given selector.
+ *
+ * @param selector the selector to get a selection key for
+ *
+ * @return the selection key this channel is registered with
*/
public final SelectionKey keyFor(Selector selector)
{
if (! isOpen())
return null;
-
+
try
{
- synchronized(blockingLock())
+ synchronized (blockingLock())
{
- return locate (selector);
+ return locate(selector);
}
}
catch (Exception e)
{
- return null;
+ return null;
}
}
/**
* Returns the provider that created this channel.
+ *
+ * @return the selector provider that created this channel
*/
- public final SelectorProvider provider ()
+ public final SelectorProvider provider()
{
return provider;
}
- private SelectionKey locate (Selector selector)
+ private SelectionKey locate(Selector selector)
{
- ListIterator it = keys.listIterator ();
-
- while (it.hasNext ())
+ ListIterator it = keys.listIterator();
+
+ while (it.hasNext())
{
- SelectionKey key = (SelectionKey) it.next();
-
- if (key.selector() == selector)
- return key;
+ SelectionKey key = (SelectionKey) it.next();
+
+ if (key.selector() == selector)
+ return key;
}
-
+
return null;
}
/**
* Registers this channel with the given selector, returning a selection key.
*
+ * @param selin the seletor to use
+ * @param ops the interested operations
+ * @param att an attachment for the returned selection key
+ *
+ * @return the registered selection key
+ *
* @exception ClosedChannelException If the channel is already closed.
*/
- public final SelectionKey register (Selector selin, int ops, Object att)
+ public final SelectionKey register(Selector selin, int ops, Object att)
throws ClosedChannelException
{
- if (!isOpen ())
+ if (! isOpen())
throw new ClosedChannelException();
+ if ((ops & ~validOps()) != 0)
+ throw new IllegalArgumentException();
+
SelectionKey key = null;
AbstractSelector selector = (AbstractSelector) selin;
synchronized (blockingLock())
{
- key = locate (selector);
+ key = locate(selector);
- if (key != null)
- {
+ if (key != null)
+ {
if (att != null)
- key.attach (att);
- }
- else
- {
- key = selector.register (this, ops, att);
-
- if (key != null)
- addSelectionKey (key);
- }
+ key.attach(att);
+ }
+ else
+ {
+ key = selector.register(this, ops, att);
+
+ if (key != null)
+ addSelectionKey(key);
+ }
}
return key;
diff --git a/libjava/java/nio/channels/spi/AbstractSelectionKey.java b/libjava/java/nio/channels/spi/AbstractSelectionKey.java
index 78e0a82cb4a..83d6421bcad 100644
--- a/libjava/java/nio/channels/spi/AbstractSelectionKey.java
+++ b/libjava/java/nio/channels/spi/AbstractSelectionKey.java
@@ -1,4 +1,4 @@
-/* AbstractSelectionKey.java --
+/* AbstractSelectionKey.java --
Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,38 +39,40 @@ package java.nio.channels.spi;
import java.nio.channels.SelectionKey;
+
/**
* @since 1.4
*/
-public abstract class AbstractSelectionKey
- extends SelectionKey
+public abstract class AbstractSelectionKey extends SelectionKey
{
- private boolean cancelled = false;
+ private boolean cancelled;
/**
* Initializes the key.
*/
- protected AbstractSelectionKey ()
+ protected AbstractSelectionKey()
{
}
/**
* Cancels this key.
*/
- public final void cancel ()
+ public final void cancel()
{
if (isValid())
{
((AbstractSelector) selector()).cancelKey(this);
- cancelled = true;
+ cancelled = true;
}
}
/**
* Tells whether this key is valid or not.
+ *
+ * @return true if this key is valid, false otherwise
*/
- public final boolean isValid ()
+ public final boolean isValid()
{
- return !cancelled;
+ return ! cancelled;
}
}
diff --git a/libjava/java/nio/channels/spi/AbstractSelector.java b/libjava/java/nio/channels/spi/AbstractSelector.java
index b657b5ea0d9..b1e206139d0 100644
--- a/libjava/java/nio/channels/spi/AbstractSelector.java
+++ b/libjava/java/nio/channels/spi/AbstractSelector.java
@@ -1,4 +1,4 @@
-/* AbstractSelector.java --
+/* AbstractSelector.java --
Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -35,49 +35,53 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package java.nio.channels.spi;
import java.io.IOException;
import java.nio.channels.ClosedSelectorException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
-import java.util.Set;
import java.util.HashSet;
+import java.util.Set;
+
public abstract class AbstractSelector extends Selector
{
- private boolean closed = false;
+ private boolean closed;
private SelectorProvider provider;
private HashSet cancelledKeys;
/**
* Initializes the slector.
+ *
+ * @param provider the provider that created this selector
*/
- protected AbstractSelector (SelectorProvider provider)
+ protected AbstractSelector(SelectorProvider provider)
{
this.provider = provider;
this.cancelledKeys = new HashSet();
}
-
+
/**
* Closes the channel.
- *
+ *
* @exception IOException If an error occurs
*/
- public final synchronized void close () throws IOException
+ public final synchronized void close() throws IOException
{
if (closed)
return;
-
+
implCloseSelector();
closed = true;
}
/**
* Tells whether this channel is open or not.
+ *
+ * @return true if channel is open, false otherwise.
*/
- public final boolean isOpen ()
+ public final boolean isOpen()
{
return ! closed;
}
@@ -95,21 +99,25 @@ public abstract class AbstractSelector extends Selector
protected final void end()
{
}
-
+
/**
* Returns the provider for this selector object.
+ *
+ * @return the SelectorProvider object that created this seletor
*/
- public final SelectorProvider provider ()
+ public final SelectorProvider provider()
{
return provider;
}
/**
* Returns the cancelled keys set.
+ *
+ * @return the cancelled keys set
*/
protected final Set cancelledKeys()
{
- if (!isOpen())
+ if (! isOpen())
throw new ClosedSelectorException();
return cancelledKeys;
@@ -118,8 +126,9 @@ public abstract class AbstractSelector extends Selector
/**
* Cancels a selection key.
*/
+
// This method is only called by AbstractSelectionKey.cancel().
- final void cancelKey (AbstractSelectionKey key)
+ final void cancelKey(AbstractSelectionKey key)
{
synchronized (cancelledKeys)
{
@@ -129,13 +138,29 @@ public abstract class AbstractSelector extends Selector
/**
* Closes the channel.
+ *
+ * @exception IOException if an error occurs
*/
- protected abstract void implCloseSelector () throws IOException;
+ protected abstract void implCloseSelector() throws IOException;
- protected abstract SelectionKey register (AbstractSelectableChannel ch,
- int ops, Object att);
+ /**
+ * Registers a channel for the selection process.
+ *
+ * @param ch the channel register
+ * @param ops the interested operations
+ * @param att an attachement to the selection key
+ *
+ * @return the registered selection key
+ */
+ protected abstract SelectionKey register(AbstractSelectableChannel ch,
+ int ops, Object att);
- protected final void deregister (AbstractSelectionKey key)
+ /**
+ * Deregisters the given selection key.
+ *
+ * @param key the key to deregister
+ */
+ protected final void deregister(AbstractSelectionKey key)
{
((AbstractSelectableChannel) key.channel()).removeSelectionKey(key);
}
diff --git a/libjava/java/nio/channels/spi/SelectorProvider.java b/libjava/java/nio/channels/spi/SelectorProvider.java
index 1de3e4f83cc..ac6e124704d 100644
--- a/libjava/java/nio/channels/spi/SelectorProvider.java
+++ b/libjava/java/nio/channels/spi/SelectorProvider.java
@@ -44,6 +44,7 @@ import java.nio.channels.Pipe;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
+
/**
* @author Michael Koch
* @since 1.4
@@ -51,76 +52,99 @@ import java.nio.channels.SocketChannel;
public abstract class SelectorProvider
{
private static SelectorProvider systemDefaultProvider;
-
+
/**
* Initializes the selector provider.
*
* @exception SecurityException If a security manager has been installed and
* it denies @see RuntimePermission ("selectorProvider").
*/
- protected SelectorProvider ()
+ protected SelectorProvider()
{
- SecurityManager sm = System.getSecurityManager ();
+ SecurityManager sm = System.getSecurityManager();
if (sm != null)
- sm.checkPermission (new RuntimePermission ("selectorProvider"));
+ sm.checkPermission(new RuntimePermission("selectorProvider"));
}
-
+
/**
* Opens a datagram channel.
+ *
+ * @return a new datagram channel object
+ *
+ * @exception IOException if an error occurs
*/
- public abstract DatagramChannel openDatagramChannel () throws IOException;
-
+ public abstract DatagramChannel openDatagramChannel()
+ throws IOException;
+
/**
* Opens a pipe.
+ *
+ * @return a new pipe object
+ *
+ * @exception IOException if an error occurs
*/
- public abstract Pipe openPipe () throws IOException;
-
+ public abstract Pipe openPipe() throws IOException;
+
/**
* Opens a selector.
+ *
+ * @return a new selector object
+ *
+ * @exception IOException if an error occurs
*/
- public abstract AbstractSelector openSelector () throws IOException;
-
+ public abstract AbstractSelector openSelector() throws IOException;
+
/**
* Opens a server socket channel.
+ *
+ * @return a new server socket channel object
+ *
+ * @exception IOException if an error occurs
*/
- public abstract ServerSocketChannel openServerSocketChannel ()
+ public abstract ServerSocketChannel openServerSocketChannel()
throws IOException;
-
+
/**
* Opens a socket channel.
+ *
+ * @return a new socket channel object
+ *
+ * @exception IOException if an error occurs
*/
- public abstract SocketChannel openSocketChannel () throws IOException;
-
+ public abstract SocketChannel openSocketChannel() throws IOException;
+
/**
* Returns the system-wide default selector provider for this invocation
* of the Java virtual machine.
+ *
+ * @return the default seletor provider
*/
- public static synchronized SelectorProvider provider ()
+ public static synchronized SelectorProvider provider()
{
if (systemDefaultProvider == null)
{
- String propertyValue =
- System.getProperty ("java.nio.channels.spi.SelectorProvider");
-
- if (propertyValue == null
- || propertyValue.equals (""))
- systemDefaultProvider = new SelectorProviderImpl();
- else
- {
- try
- {
- systemDefaultProvider = (SelectorProvider) Class.forName
- (propertyValue).newInstance();
- }
- catch (Exception e)
- {
- System.err.println ("Could not instantiate class: "
- + propertyValue);
- systemDefaultProvider = new SelectorProviderImpl();
- }
- }
+ String propertyValue =
+ System.getProperty("java.nio.channels.spi.SelectorProvider");
+
+ if (propertyValue == null || propertyValue.equals(""))
+ systemDefaultProvider = new SelectorProviderImpl();
+ else
+ {
+ try
+ {
+ systemDefaultProvider =
+ (SelectorProvider) Class.forName(propertyValue)
+ .newInstance();
+ }
+ catch (Exception e)
+ {
+ System.err.println("Could not instantiate class: "
+ + propertyValue);
+ systemDefaultProvider = new SelectorProviderImpl();
+ }
+ }
}
-
+
return systemDefaultProvider;
}
}
diff --git a/libjava/java/nio/charset/IllegalCharsetNameException.java b/libjava/java/nio/charset/IllegalCharsetNameException.java
index f46e63aa14f..8ee9c702e37 100644
--- a/libjava/java/nio/charset/IllegalCharsetNameException.java
+++ b/libjava/java/nio/charset/IllegalCharsetNameException.java
@@ -48,10 +48,12 @@ public class IllegalCharsetNameException extends IllegalArgumentException
*/
private static final long serialVersionUID = 1457525358470002989L;
- String charsetName;
+ private String charsetName;
/**
* Creates the exception
+ *
+ * @param charsetName name of the illegal charset
*/
public IllegalCharsetNameException (String charsetName)
{
@@ -61,6 +63,8 @@ public class IllegalCharsetNameException extends IllegalArgumentException
/**
* Retrieves the illegal charset name
+ *
+ * @return the illegal charset name
*/
public String getCharsetName ()
{
diff --git a/libjava/java/nio/charset/MalformedInputException.java b/libjava/java/nio/charset/MalformedInputException.java
index 692eed60f94..678c5bc64f9 100644
--- a/libjava/java/nio/charset/MalformedInputException.java
+++ b/libjava/java/nio/charset/MalformedInputException.java
@@ -46,6 +46,8 @@ public class MalformedInputException extends CharacterCodingException
/**
* Creates the exception
+ *
+ * @param inputLength the position of malformed input in the input stream
*/
public MalformedInputException (int inputLength)
{
@@ -54,7 +56,9 @@ public class MalformedInputException extends CharacterCodingException
}
/**
- * Retrieves the illegal charset name
+ * Retrieves the position of the malformed input in the input stream.
+ *
+ * @return the position
*/
public int getInputLength ()
{
@@ -63,6 +67,8 @@ public class MalformedInputException extends CharacterCodingException
/**
* Returns the detail message string of this throwable
+ *
+ * @return the message
*/
public String getMessage ()
{
diff --git a/libjava/java/nio/charset/spi/CharsetProvider.java b/libjava/java/nio/charset/spi/CharsetProvider.java
index 32346a0457c..1af7a8ef314 100644
--- a/libjava/java/nio/charset/spi/CharsetProvider.java
+++ b/libjava/java/nio/charset/spi/CharsetProvider.java
@@ -40,6 +40,7 @@ package java.nio.charset.spi;
import java.nio.charset.Charset;
import java.util.Iterator;
+
/**
* This class allows an implementor to provide additional character sets. The
* subclass must have a nullary constructor, and be attached to charset
@@ -82,6 +83,8 @@ public abstract class CharsetProvider
/**
* Returns the named charset, by canonical name or alias.
*
+ * @param name the name of the character
+ *
* @return the charset, or null if not supported
*/
public abstract Charset charsetForName(String name);
diff --git a/libjava/java/nio/natDirectByteBufferImpl.cc b/libjava/java/nio/natDirectByteBufferImpl.cc
index 94225c39885..88f53fc2bea 100644
--- a/libjava/java/nio/natDirectByteBufferImpl.cc
+++ b/libjava/java/nio/natDirectByteBufferImpl.cc
@@ -65,9 +65,9 @@ java::nio::DirectByteBufferImpl::adjustAddress (RawData* address, jint offset)
void
java::nio::DirectByteBufferImpl::shiftDown
-(jint dst_offset, jint src_offset, jint count)
+(RawData* address, jint dst_offset, jint src_offset, jint count)
{
- jbyte* dst = reinterpret_cast<jbyte*> (address) + array_offset + dst_offset;
- jbyte* src = reinterpret_cast<jbyte*> (address) + array_offset + src_offset;
+ jbyte* dst = reinterpret_cast<jbyte*> (address) + dst_offset;
+ jbyte* src = reinterpret_cast<jbyte*> (address) + src_offset;
::memmove(dst, src, count);
}
diff --git a/libjava/java/rmi/MarshalledObject.java b/libjava/java/rmi/MarshalledObject.java
index 0ba91580d1a..ef22310c7b1 100644
--- a/libjava/java/rmi/MarshalledObject.java
+++ b/libjava/java/rmi/MarshalledObject.java
@@ -1,5 +1,5 @@
/*
- Copyright (c) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+ Copyright (c) 1996, 1997, 1998, 1999, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -46,8 +46,7 @@ import gnu.java.rmi.RMIMarshalledObjectOutputStream;
/**
* FIXME - doc missing
*/
-public final class MarshalledObject
- extends Object implements Serializable
+public final class MarshalledObject implements Serializable
{
//The following fields are from Java API Documentation "Serialized form"
diff --git a/libjava/java/rmi/Naming.java b/libjava/java/rmi/Naming.java
index 1d2e68b982f..1a30c1f2c07 100644
--- a/libjava/java/rmi/Naming.java
+++ b/libjava/java/rmi/Naming.java
@@ -44,14 +44,16 @@ import java.rmi.registry.LocateRegistry;
public final class Naming {
-/** <pre>
+/**
* Looks for the remote object that is associated with the named service.
* Name and location is given in form of a URL without a scheme:
- *
- * //host:port/service-name
+ *
+ * <pre>
+ * //host:port/service-name
+ * </pre>
*
* The port is optional.
- * </pre>
+ *
* @param name the service name and location
* @return Remote-object that implements the named service
* @throws NotBoundException if no object implements the service
diff --git a/libjava/java/rmi/RemoteException.java b/libjava/java/rmi/RemoteException.java
index 17e38b30bd7..b28f0709099 100644
--- a/libjava/java/rmi/RemoteException.java
+++ b/libjava/java/rmi/RemoteException.java
@@ -99,7 +99,7 @@ public class RemoteException extends IOException
* This method returns a message indicating what went wrong, in this
* format:
* <code>super.getMessage() + (detail == null ? ""
- * : "; nested exception is:\n\t" + detail)<code>.
+ * : "; nested exception is:\n\t" + detail)</code>.
*
* @return the chained message
*/
diff --git a/libjava/java/rmi/activation/ActivationException.java b/libjava/java/rmi/activation/ActivationException.java
index a1ac7bd6a28..a335142ce47 100644
--- a/libjava/java/rmi/activation/ActivationException.java
+++ b/libjava/java/rmi/activation/ActivationException.java
@@ -94,7 +94,7 @@ public class ActivationException extends Exception
* This method returns a message indicating what went wrong, in this
* format:
* <code>super.getMessage() + (detail == null ? ""
- * : "; nested exception is:\n\t" + detail)<code>.
+ * : "; nested exception is:\n\t" + detail)</code>.
*
* @return the chained message
*/
diff --git a/libjava/java/rmi/server/ServerCloneException.java b/libjava/java/rmi/server/ServerCloneException.java
index faf43c8e29c..3334c8d95b2 100644
--- a/libjava/java/rmi/server/ServerCloneException.java
+++ b/libjava/java/rmi/server/ServerCloneException.java
@@ -89,7 +89,7 @@ public class ServerCloneException extends CloneNotSupportedException
* This method returns a message indicating what went wrong, in this
* format:
* <code>super.getMessage() + (detail == null ? ""
- * : "; nested exception is:\n\t" + detail)<code>.
+ * : "; nested exception is:\n\t" + detail)</code>.
*
* @return the chained message
*/
diff --git a/libjava/java/security/AccessController.java b/libjava/java/security/AccessController.java
index 41ca1cec5fb..66aed9e3898 100644
--- a/libjava/java/security/AccessController.java
+++ b/libjava/java/security/AccessController.java
@@ -1,5 +1,5 @@
/* AccessController.java --- Access control context and permission checker
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -91,7 +91,7 @@ public final class AccessController
*
* @param action the <code>PrivilegedAction</code> whose <code>run()</code>
* should be be called.
- * @returns the result of the <code>action.run()</code> method.
+ * @return the result of the <code>action.run()</code> method.
*/
public static Object doPrivileged(PrivilegedAction action)
{
@@ -110,7 +110,7 @@ public final class AccessController
* should be be called.
* @param context the <code>AccessControlContext</code> whose protection
* domains should be added to the protection domain of the calling class.
- * @returns the result of the <code>action.run()</code> method.
+ * @return the result of the <code>action.run()</code> method.
*/
public static Object doPrivileged(PrivilegedAction action,
AccessControlContext context)
@@ -130,7 +130,7 @@ public final class AccessController
*
* @param action the <code>PrivilegedExceptionAction</code> whose
* <code>run()</code> should be be called.
- * @returns the result of the <code>action.run()</code> method.
+ * @return the result of the <code>action.run()</code> method.
* @exception PrivilegedActionException wrapped around any exception that
* is thrown in the <code>run()</code> method.
*/
@@ -162,7 +162,7 @@ public final class AccessController
* <code>run()</code> should be be called.
* @param context the <code>AccessControlContext</code> whose protection
* domains should be added to the protection domain of the calling class.
- * @returns the result of the <code>action.run()</code> method.
+ * @return the result of the <code>action.run()</code> method.
* @exception PrivilegedActionException wrapped around any exception that
* is thrown in the <code>run()</code> method.
*/
diff --git a/libjava/java/security/AlgorithmParameterGenerator.java b/libjava/java/security/AlgorithmParameterGenerator.java
index 26a7790d37a..034302504f0 100644
--- a/libjava/java/security/AlgorithmParameterGenerator.java
+++ b/libjava/java/security/AlgorithmParameterGenerator.java
@@ -67,7 +67,7 @@ import gnu.java.security.Engine;
* system parameters, for example, the parameter generation values usually
* consist of the size of the prime modulus and the size of the random
* exponent, both specified in number of bits.</li>
- * <ul>
+ * </ul>
*
* <p>In case the client does not explicitly initialize the
* <code>AlgorithmParameterGenerator</code> (via a call to an <code>init()</code>
diff --git a/libjava/java/security/AlgorithmParameters.java b/libjava/java/security/AlgorithmParameters.java
index 07d76bb7bab..86298b9ea93 100644
--- a/libjava/java/security/AlgorithmParameters.java
+++ b/libjava/java/security/AlgorithmParameters.java
@@ -71,7 +71,7 @@ import gnu.java.security.Engine;
* parameter specification or parameter encoding.</p>
*
* <p>A transparent parameter specification is obtained from an
- * <ocde>AlgorithmParameters</code> object via a call to
+ * <code>AlgorithmParameters</code> object via a call to
* <code>getParameterSpec()</code>, and a byte encoding of the parameters is
* obtained via a call to <code>getEncoded()</code>.</p>
*
diff --git a/libjava/java/security/BasicPermission.java b/libjava/java/security/BasicPermission.java
index 0945f2d7faf..2b7a6759536 100644
--- a/libjava/java/security/BasicPermission.java
+++ b/libjava/java/security/BasicPermission.java
@@ -80,9 +80,8 @@ public abstract class BasicPermission extends Permission
private static final long serialVersionUID = 6279438298436773498L;
/**
- * Create a new instance with the specified permission name. If the name
- * is empty, or contains an illegal wildcard character, an exception is
- * thrown.
+ * Create a new instance with the specified permission name. If the
+ * name is empty an exception is thrown.
*
* @param name the name of this permission
* @throws NullPointerException if name is null
@@ -91,12 +90,17 @@ public abstract class BasicPermission extends Permission
public BasicPermission(String name)
{
super(name);
- if (name.indexOf("*") != -1)
- {
- if ((! name.endsWith(".*") && ! name.equals("*"))
- || name.indexOf("*") != name.lastIndexOf("*"))
- throw new IllegalArgumentException("Bad wildcard: " + name);
- }
+
+ // FIXME: this arg checking isn't in the spec, and Sun's JDK
+ // doesn't do it.
+
+// if (name.indexOf("*") != -1)
+// {
+// if ((! name.endsWith(".*") && ! name.equals("*"))
+// || name.indexOf("*") != name.lastIndexOf("*"))
+// throw new IllegalArgumentException("Bad wildcard: " + name);
+// }
+
if ("".equals(name))
throw new IllegalArgumentException("Empty name");
}
diff --git a/libjava/java/security/CodeSource.java b/libjava/java/security/CodeSource.java
index 36ee734efd3..35ec573cd9b 100644
--- a/libjava/java/security/CodeSource.java
+++ b/libjava/java/security/CodeSource.java
@@ -159,17 +159,22 @@ public class CodeSource implements Serializable
* object must have all the certifcates this object has (but may have more),
* and must have a location that is a subset of this object's. In order
* for this object to imply the specified object, the following must be
- * true:<ol>
+ * true:
+ *
+ * <ol>
* <li><em>codesource</em> must not be <code>null</code>.</li>
* <li>If <em>codesource</em> has a certificate list, all of it's
* certificates must be present in the certificate list of this
* code source.</li>
* <li>If this object does not have a <code>null</code> location, then
- * the following addtional tests must be passed.<ol>
+ * the following addtional tests must be passed.
+ *
+ * <ol>
* <li><em>codesource</em> must not have a <code>null</code>
* location.</li>
* <li><em>codesource</em>'s location must be equal to this object's
- * location, or<br><ul>
+ * location, or
+ * <ul>
* <li><em>codesource</em>'s location protocol, port, and ref (aka,
* anchor) must equal this objects</li>
* <li><em>codesource</em>'s location host must imply this object's
@@ -183,19 +188,21 @@ public class CodeSource implements Serializable
* location file must start with this object's location file
* with the '/' character appended to it.</li>
* </ul></li>
- * </ol>
+ * </ol></li>
* </ol>
*
* <p>For example, each of these locations imply the location
- * "http://java.sun.com/classes/foo.jar":<ul>
+ * "http://java.sun.com/classes/foo.jar":</p>
+ *
* <pre>
* http:
* http://*.sun.com/classes/*
* http://java.sun.com/classes/-
* http://java.sun.com/classes/foo.jar
* </pre>
- * Note that the code source with null location and null certificates implies
- * all other code sources.
+ *
+ * <p>Note that the code source with null location and null certificates implies
+ * all other code sources.</p>
*
* @param cs the <code>CodeSource</code> to test against this object
* @return true if this specified <code>CodeSource</code> is implied
@@ -245,7 +252,7 @@ public class CodeSource implements Serializable
/**
* This method returns a <code>String</code> that represents this object.
* The result is in the format <code>"(" + getLocation()</code> followed
- * by a space separated list of certificates (or "<no certificates>"),
+ * by a space separated list of certificates (or "&lt;no certificates&gt;"),
* followed by <code>")"</code>.
*
* @return a <code>String</code> for this object
diff --git a/libjava/java/security/Identity.java b/libjava/java/security/Identity.java
index 57ccc83e056..2e9ddea1a29 100644
--- a/libjava/java/security/Identity.java
+++ b/libjava/java/security/Identity.java
@@ -151,7 +151,7 @@ public abstract class Identity implements Principal, Serializable
* @throws KeyManagementException if another identity in the identity's scope
* has the same public key, or if another exception occurs.
* @throws SecurityException if a security manager exists and its
- * <code>checkSecurityAccess()<code> method doesn't allow setting the public
+ * <code>checkSecurityAccess()</code> method doesn't allow setting the public
* key.
* @see #getPublicKey()
* @see SecurityManager#checkSecurityAccess(String)
diff --git a/libjava/java/security/IdentityScope.java b/libjava/java/security/IdentityScope.java
index 88e00fc81c0..5965a00a122 100644
--- a/libjava/java/security/IdentityScope.java
+++ b/libjava/java/security/IdentityScope.java
@@ -123,7 +123,7 @@ public abstract class IdentityScope extends Identity
}
/**
- * <p>Sets the system's identity scope.</p>
+ * Sets the system's identity scope.
*
* <p>First, if there is a security manager, its <code>checkSecurityAccess()
* </code> method is called with <code>"setSystemScope"</code> as its argument
@@ -131,7 +131,7 @@ public abstract class IdentityScope extends Identity
*
* @param scope the scope to set.
* @throws SecurityException if a security manager exists and its
- * <code>checkSecurityAccess()<code> method doesn't allow setting the
+ * <code>checkSecurityAccess()</code> method doesn't allow setting the
* identity scope.
* @see #getSystemScope()
* @see SecurityManager#checkSecurityAccess(String)
diff --git a/libjava/java/security/KeyPairGenerator.java b/libjava/java/security/KeyPairGenerator.java
index b9b07852aa4..9a3a04d4ef8 100644
--- a/libjava/java/security/KeyPairGenerator.java
+++ b/libjava/java/security/KeyPairGenerator.java
@@ -56,43 +56,42 @@ import gnu.java.security.Engine;
* two is the initialization of the object:</p>
*
* <ul>
- * <li><b>Algorithm-Independent Initialization</b><br/>
- * All key pair generators share the concepts of a <i>keysize</i> and a
- * <i>source of randomness</i>. The <i>keysize</i> is interpreted differently
- * for different algorithms (e.g., in the case of the <i>DSA</i> algorithm,
- * the <i>keysize</i> corresponds to the length of the modulus). There is an
- * <code>initialize()</code> method in this <code>KeyPairGenerator</code>
- * class that takes these two universally shared types of arguments. There
- * is also one that takes just a <i>keysize</i> argument, and uses the
- * {@link SecureRandom} implementation of the highest-priority installed
- * provider as the <i>source of randomness</i>. (If none of the installed
- * providers supply an implementation of {@link SecureRandom}, a
- * system-provided source of randomness is used.)<br/><br/>
+ * <li><b>Algorithm-Independent Initialization</b><br/>
+ * All key pair generators share the concepts of a <i>keysize</i> and a
+ * <i>source of randomness</i>. The <i>keysize</i> is interpreted differently
+ * for different algorithms (e.g., in the case of the <i>DSA</i> algorithm,
+ * the <i>keysize</i> corresponds to the length of the modulus). There is an
+ * <code>initialize()</code> method in this <code>KeyPairGenerator</code>
+ * class that takes these two universally shared types of arguments. There
+ * is also one that takes just a <i>keysize</i> argument, and uses the
+ * {@link SecureRandom} implementation of the highest-priority installed
+ * provider as the <i>source of randomness</i>. (If none of the installed
+ * providers supply an implementation of {@link SecureRandom}, a
+ * system-provided source of randomness is used.)
*
- * Since no other parameters are specified when you call the above
- * algorithm-independent initialize methods, it is up to the provider what
- * to do about the algorithm-specific parameters (if any) to be associated
- * with each of the keys.<br/><br/>
+ * <p>Since no other parameters are specified when you call the above
+ * algorithm-independent initialize methods, it is up to the provider what
+ * to do about the algorithm-specific parameters (if any) to be associated
+ * with each of the keys.</p>
*
- * If the algorithm is the <i>DSA</i> algorithm, and the <i>keysize</i>
- * (modulus size) is <code>512</code>, <code>768</code>, or <code>1024</code>,
- * then the <b>GNU</b> provider uses a set of precomputed values for the
- * <code>p</code>, <code>q</code>, and <code>g</code> parameters. If the
- * <i>modulus size</i> is not one of the above values, the <b>GNU</b>
- * provider creates a new set of parameters. Other providers might have
- * precomputed parameter sets for more than just the three modulus sizes
- * mentioned above. Still others might not have a list of precomputed
- * parameters at all and instead always create new parameter sets.<br/></li>
- *
- * <li><b>Algorithm-Specific Initialization</b><br/>
- * For situations where a set of algorithm-specific parameters already
- * exists (e.g., so-called <i>community parameters</i> in <i>DSA</i>), there
- * are two initialize methods that have an {@link AlgorithmParameterSpec}
- * argument. One also has a {@link SecureRandom} argument, while the the
- * other uses the {@link SecureRandom} implementation of the highest-priority
- * installed provider as the source of randomness. (If none of the installed
- * providers supply an implementation of {@link SecureRandom}, a
- * system-provided source of randomness is used.)</li>
+ * <p>If the algorithm is the <i>DSA</i> algorithm, and the <i>keysize</i>
+ * (modulus size) is <code>512</code>, <code>768</code>, or <code>1024</code>,
+ * then the <b>GNU</b> provider uses a set of precomputed values for the
+ * <code>p</code>, <code>q</code>, and <code>g</code> parameters. If the
+ * <i>modulus size</i> is not one of the above values, the <b>GNU</b>
+ * provider creates a new set of parameters. Other providers might have
+ * precomputed parameter sets for more than just the three modulus sizes
+ * mentioned above. Still others might not have a list of precomputed
+ * parameters at all and instead always create new parameter sets.</p></li>
+ * <li><b>Algorithm-Specific Initialization</b><br/>
+ * For situations where a set of algorithm-specific parameters already
+ * exists (e.g., so-called <i>community parameters</i> in <i>DSA</i>), there
+ * are two initialize methods that have an {@link AlgorithmParameterSpec}
+ * argument. One also has a {@link SecureRandom} argument, while the the
+ * other uses the {@link SecureRandom} implementation of the highest-priority
+ * installed provider as the source of randomness. (If none of the installed
+ * providers supply an implementation of {@link SecureRandom}, a
+ * system-provided source of randomness is used.)</li>
* </ul>
*
* <p>In case the client does not explicitly initialize the
diff --git a/libjava/java/security/KeyStore.java b/libjava/java/security/KeyStore.java
index 5f0c159d7d2..4ca16a2290e 100644
--- a/libjava/java/security/KeyStore.java
+++ b/libjava/java/security/KeyStore.java
@@ -208,7 +208,7 @@ public class KeyStore
/**
* Returns the default KeyStore type. This method looks up the
- * type in <JAVA_HOME>/lib/security/java.security with the
+ * type in &lt;JAVA_HOME&gt;/lib/security/java.security with the
* property "keystore.type" or if that fails then "jks" .
*/
public static final String getDefaultType()
diff --git a/libjava/java/security/SecureRandom.java b/libjava/java/security/SecureRandom.java
index 56f4b22672c..d7fda7ba744 100644
--- a/libjava/java/security/SecureRandom.java
+++ b/libjava/java/security/SecureRandom.java
@@ -37,12 +37,11 @@ exception statement from your version. */
package java.security;
-import java.io.Serializable;
-import java.util.Random;
-import java.util.Enumeration;
-
import gnu.java.security.Engine;
+import java.util.Enumeration;
+import java.util.Random;
+
/**
* An interface to a cryptographically secure pseudo-random number
* generator (PRNG). Random (or at least unguessable) numbers are used
@@ -94,7 +93,7 @@ public class SecureRandom extends Random
String key;
String classname = null;
- int i, flag = 0;
+ int i;
Enumeration e;
for (i = 0; i < p.length; i++)
{
diff --git a/libjava/java/security/Security.java b/libjava/java/security/Security.java
index ef716150ab4..25cadcac465 100644
--- a/libjava/java/security/Security.java
+++ b/libjava/java/security/Security.java
@@ -1,5 +1,5 @@
/* Security.java --- Java base security class implementation
- Copyright (C) 1999, 2001, 2002, 2003, Free Software Foundation, Inc.
+ Copyright (C) 1999, 2001, 2002, 2003, 2004, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -59,7 +59,7 @@ import java.util.Vector;
*
* @author Mark Benvenuto <ivymccough@worldnet.att.net>
*/
-public final class Security extends Object
+public final class Security
{
private static final String ALG_ALIAS = "Alg.Alias.";
@@ -150,7 +150,7 @@ public final class Security extends Object
result = false;
}
- return false;
+ return result;
}
/**
@@ -670,7 +670,7 @@ public final class Security extends Object
outer: for (int r = 0; r < 3; r++) // guard against circularity
{
serviceDotAlgorithm = (svc+"."+String.valueOf(algo)).trim();
- inner: for (it = p.keySet().iterator(); it.hasNext(); )
+ for (it = p.keySet().iterator(); it.hasNext(); )
{
key = (String) it.next();
if (key.equalsIgnoreCase(serviceDotAlgorithm)) // eureka
diff --git a/libjava/java/security/Signature.java b/libjava/java/security/Signature.java
index 1e99a7bb3e0..bf614e388b3 100644
--- a/libjava/java/security/Signature.java
+++ b/libjava/java/security/Signature.java
@@ -83,20 +83,20 @@ import gnu.java.security.Engine;
* either signing data or verifying a signature:</p>
*
* <ol>
- * <li>Initialization, with either
- * <ul>
- * <li>a public key, which initializes the signature for verification
- * (see <code>initVerify()</code>), or</li>
- * <li>a private key (and optionally a Secure Random Number Generator),
- * which initializes the signature for signing (see
- * {@link #initSign(PrivateKey)} and {@link #initSign(PrivateKey, SecureRandom)}
- * ).</li>
- * </ul></li>
- * <li>Updating<br/>
- * Depending on the type of initialization, this will update the bytes to
- * be signed or verified. See the update methods.<br/></li>
- * <li>Signing or Verifying a signature on all updated bytes. See the
- * <code>sign()</code> methods and the <code>verify()</code> method.</li>
+ * <li>Initialization, with either
+ * <ul>
+ * <li>a public key, which initializes the signature for verification
+ * (see <code>initVerify()</code>), or</li>
+ * <li>a private key (and optionally a Secure Random Number Generator),
+ * which initializes the signature for signing (see
+ * {@link #initSign(PrivateKey)} and {@link #initSign(PrivateKey, SecureRandom)}
+ * ).</li>
+ * </ul></li>
+ * <li>Updating<br/>
+ * Depending on the type of initialization, this will update the bytes to
+ * be signed or verified. See the update methods.<br/></li>
+ * <li>Signing or Verifying a signature on all updated bytes. See the
+ * <code>sign()</code> methods and the <code>verify()</code> method.</li>
* </ol>
*
* <p>Note that this class is abstract and extends from {@link SignatureSpi} for
@@ -105,7 +105,7 @@ import gnu.java.security.Engine;
* superclass are intended for cryptographic service providers who wish to
* supply their own implementations of digital signature algorithms.
*
- * @author Mark Benvenuto <ivymccough@worldnet.att.net>
+ * @author Mark Benvenuto (ivymccough@worldnet.att.net)
*/
public abstract class Signature extends SignatureSpi
{
diff --git a/libjava/java/security/SignatureSpi.java b/libjava/java/security/SignatureSpi.java
index 7deafd6b041..bf2382d8e40 100644
--- a/libjava/java/security/SignatureSpi.java
+++ b/libjava/java/security/SignatureSpi.java
@@ -279,7 +279,7 @@ public abstract class SignatureSpi
* @param param the string name of the parameter.
* @return the object that represents the parameter value, or <code>null</code>
* if there is none.
- * @throws InvalidParameterException if <code>param<?code> is an invalid
+ * @throws InvalidParameterException if <code>param</code> is an invalid
* parameter for this engine, or another exception occurs while trying to get
* this parameter.
* @deprecated
diff --git a/libjava/java/security/SignedObject.java b/libjava/java/security/SignedObject.java
index 270936ba686..0d9f733e70d 100644
--- a/libjava/java/security/SignedObject.java
+++ b/libjava/java/security/SignedObject.java
@@ -98,7 +98,7 @@ import java.io.Serializable;
* <p>The signature algorithm can be, among others, the NIST standard <i>DSS</i>,
* using <i>DSA</i> and <i>SHA-1</i>. The algorithm is specified using the same
* convention as that for signatures. The <i>DSA</i> algorithm using the
- * </i>SHA-1</i> message digest algorithm can be specified, for example, as
+ * <i>SHA-1</i> message digest algorithm can be specified, for example, as
* <code>"SHA/DSA"</code> or <code>"SHA-1/DSA"</code> (they are equivalent). In
* the case of <i>RSA</i>, there are multiple choices for the message digest
* algorithm, so the signing algorithm could be specified as, for example,
diff --git a/libjava/java/security/UnresolvedPermission.java b/libjava/java/security/UnresolvedPermission.java
index 954b562c773..7efb35582fc 100644
--- a/libjava/java/security/UnresolvedPermission.java
+++ b/libjava/java/security/UnresolvedPermission.java
@@ -37,7 +37,6 @@ exception statement from your version. */
package java.security;
-import java.io.Serializable;
// All uses of Certificate in this file refer to the one in the listed
// package, not this one.
import java.security.cert.Certificate;
diff --git a/libjava/java/security/interfaces/DSAKeyPairGenerator.java b/libjava/java/security/interfaces/DSAKeyPairGenerator.java
index dc957a31881..59f3834cafa 100644
--- a/libjava/java/security/interfaces/DSAKeyPairGenerator.java
+++ b/libjava/java/security/interfaces/DSAKeyPairGenerator.java
@@ -1,5 +1,5 @@
/* DSAKeyPairGenerator.java -- Initialize a DSA key generator
- Copyright (C) 1998 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,8 +37,8 @@ exception statement from your version. */
package java.security.interfaces;
-import java.security.SecureRandom;
import java.security.InvalidParameterException;
+import java.security.SecureRandom;
/**
* This interface contains methods for intializing a Digital Signature
diff --git a/libjava/java/security/interfaces/DSAPrivateKey.java b/libjava/java/security/interfaces/DSAPrivateKey.java
index 201d54f2f30..4e6f13ddbe5 100644
--- a/libjava/java/security/interfaces/DSAPrivateKey.java
+++ b/libjava/java/security/interfaces/DSAPrivateKey.java
@@ -1,5 +1,5 @@
/* DSAPublicKey.java -- A Digital Signature Algorithm private key
- Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,8 +37,8 @@ exception statement from your version. */
package java.security.interfaces;
-import java.security.PrivateKey;
import java.math.BigInteger;
+import java.security.PrivateKey;
/**
* This interface models a Digital Signature Algorithm (DSA) private key
diff --git a/libjava/java/security/interfaces/DSAPublicKey.java b/libjava/java/security/interfaces/DSAPublicKey.java
index 74f24482dcf..aec1c606dcd 100644
--- a/libjava/java/security/interfaces/DSAPublicKey.java
+++ b/libjava/java/security/interfaces/DSAPublicKey.java
@@ -1,5 +1,5 @@
/* DSAPublicKey.java -- A Digital Signature Algorithm public key
- Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,8 +37,8 @@ exception statement from your version. */
package java.security.interfaces;
-import java.security.PublicKey;
import java.math.BigInteger;
+import java.security.PublicKey;
/**
* This interface models a Digital Signature Algorithm (DSA) public key
diff --git a/libjava/java/security/interfaces/RSAPrivateKey.java b/libjava/java/security/interfaces/RSAPrivateKey.java
index 34b9798b627..d287d67327a 100644
--- a/libjava/java/security/interfaces/RSAPrivateKey.java
+++ b/libjava/java/security/interfaces/RSAPrivateKey.java
@@ -1,5 +1,5 @@
/* RSAPrivateKey.java -- An RSA private key
- Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,8 +37,8 @@ exception statement from your version. */
package java.security.interfaces;
-import java.security.PrivateKey;
import java.math.BigInteger;
+import java.security.PrivateKey;
/**
* This interface provides access to information about an RSA private key.
diff --git a/libjava/java/security/interfaces/RSAPublicKey.java b/libjava/java/security/interfaces/RSAPublicKey.java
index b9b532cd9b0..22d64b1bb7a 100644
--- a/libjava/java/security/interfaces/RSAPublicKey.java
+++ b/libjava/java/security/interfaces/RSAPublicKey.java
@@ -1,5 +1,5 @@
/* RSAPublicKey.java -- An RSA public key
- Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,8 +37,8 @@ exception statement from your version. */
package java.security.interfaces;
-import java.security.PublicKey;
import java.math.BigInteger;
+import java.security.PublicKey;
/**
* This interface provides access to information about an RSA public key.
diff --git a/libjava/java/security/spec/DSAParameterSpec.java b/libjava/java/security/spec/DSAParameterSpec.java
index fa0ebce7a7a..5c7911f7420 100644
--- a/libjava/java/security/spec/DSAParameterSpec.java
+++ b/libjava/java/security/spec/DSAParameterSpec.java
@@ -1,5 +1,5 @@
/* DSAParameterSpec.java --- DSA Parameter Specificaton class
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -48,7 +48,7 @@ import java.math.BigInteger;
@author Mark Benvenuto
*/
-public class DSAParameterSpec extends Object implements AlgorithmParameterSpec, DSAParams
+public class DSAParameterSpec implements AlgorithmParameterSpec, DSAParams
{
private BigInteger p = null;
private BigInteger q = null;
diff --git a/libjava/java/security/spec/DSAPrivateKeySpec.java b/libjava/java/security/spec/DSAPrivateKeySpec.java
index b4025d61cb3..c148481ca50 100644
--- a/libjava/java/security/spec/DSAPrivateKeySpec.java
+++ b/libjava/java/security/spec/DSAPrivateKeySpec.java
@@ -1,5 +1,5 @@
/* DSAPrivateKeySpec.java --- DSA Private Key Specificaton class
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -47,7 +47,7 @@ import java.math.BigInteger;
@author Mark Benvenuto
*/
-public class DSAPrivateKeySpec extends Object implements KeySpec
+public class DSAPrivateKeySpec implements KeySpec
{
private BigInteger x = null;
private BigInteger p = null;
diff --git a/libjava/java/security/spec/DSAPublicKeySpec.java b/libjava/java/security/spec/DSAPublicKeySpec.java
index ef73371188a..687f8dd10fd 100644
--- a/libjava/java/security/spec/DSAPublicKeySpec.java
+++ b/libjava/java/security/spec/DSAPublicKeySpec.java
@@ -1,5 +1,5 @@
/* DSAPublicKeySpec.java --- DSA Public Key Specificaton class
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -47,7 +47,7 @@ import java.math.BigInteger;
@author Mark Benvenuto
*/
-public class DSAPublicKeySpec extends Object implements KeySpec
+public class DSAPublicKeySpec implements KeySpec
{
private BigInteger y = null;
private BigInteger p = null;
diff --git a/libjava/java/sql/Array.java b/libjava/java/sql/Array.java
index 0bb84cbe3d1..3246c86f8e8 100644
--- a/libjava/java/sql/Array.java
+++ b/libjava/java/sql/Array.java
@@ -165,13 +165,13 @@ public interface Array
/**
* This method returns a portion of the array as a <code>ResultSet</code>.
* The returned portion will start at <code>index</code> into the
- * array and up to <cod>count</code> elements will be returned.
- * <p>
- * Each row of the result set will have two columns. The first will be
+ * array and up to <code>count</code> elements will be returned.
+ *
+ * <p> Each row of the result set will have two columns. The first will be
* the index into the array of that row's contents. The second will be
* the actual value of that array element. The specified <code>Map</code>
* will be used to override selected default mappings of SQL types to
- * Java classes.
+ * Java classes.</p>
*
* @param offset The index into the array to start returning elements from.
* @param length The requested number of elements to return.
diff --git a/libjava/java/sql/DatabaseMetaData.java b/libjava/java/sql/DatabaseMetaData.java
index d3cfd7c2e54..cd20691b7d7 100644
--- a/libjava/java/sql/DatabaseMetaData.java
+++ b/libjava/java/sql/DatabaseMetaData.java
@@ -412,7 +412,7 @@ public interface DatabaseMetaData
* each table.
*
* @return <code>true</code> if the database uses a separate file for each
- * table </code>false</code> otherwise.
+ * table <code>false</code> otherwise.
*
* @exception SQLException If an error occurs.
*/
@@ -433,8 +433,8 @@ public interface DatabaseMetaData
* This method tests whether or not the database treats mixed case
* identifiers as all upper case.
*
- * @exception <code>true</code> if the database treats all identifiers as
- * upper case, <code>false</code> otherwise.
+ * @return <code>true</code> if the database treats all identifiers as
+ * upper case, <code>false</code> otherwise.
* @exception SQLException If an error occurs.
*/
boolean storesUpperCaseIdentifiers() throws SQLException;
@@ -443,8 +443,8 @@ public interface DatabaseMetaData
* This method tests whether or not the database treats mixed case
* identifiers as all lower case.
*
- * @exception <code>true</code> if the database treats all identifiers as
- * lower case, <code>false</code> otherwise.
+ * @return <code>true</code> if the database treats all identifiers as
+ * lower case, <code>false</code> otherwise.
* @exception SQLException If an error occurs.
*/
boolean storesLowerCaseIdentifiers() throws SQLException;
@@ -473,8 +473,8 @@ public interface DatabaseMetaData
* This method tests whether or not the database treats mixed case
* quoted identifiers as all upper case.
*
- * @exception <code>true</code> if the database treats all quoted identifiers
- * as upper case, <code>false</code> otherwise.
+ * @return <code>true</code> if the database treats all quoted identifiers
+ * as upper case, <code>false</code> otherwise.
* @exception SQLException If an error occurs.
*/
boolean storesUpperCaseQuotedIdentifiers() throws SQLException;
@@ -483,8 +483,8 @@ public interface DatabaseMetaData
* This method tests whether or not the database treats mixed case
* quoted identifiers as all lower case.
*
- * @exception <code>true</code> if the database treats all quoted identifiers
- * as lower case, <code>false</code> otherwise.
+ * @return <code>true</code> if the database treats all quoted identifiers
+ * as lower case, <code>false</code> otherwise.
* @exception SQLException If an error occurs.
*/
boolean storesLowerCaseQuotedIdentifiers() throws SQLException;
@@ -1377,18 +1377,18 @@ public interface DatabaseMetaData
* <p>
* <ol>
* <li>PROCEDURE_CAT - The catalog the procedure is in, which may be
- * <code>null</code>.
+ * <code>null</code>.</li>
* <li>PROCEDURE_SCHEM - The schema the procedures is in, which may be
- * <code>null</code>.
- * <li>PROCEDURE_NAME - The name of the procedure.
- * <li>Unused
- * <li>Unused
- * <li>Unused
- * <li>REMARKS - A description of the procedure
+ * <code>null</code>.</li>
+ * <li>PROCEDURE_NAME - The name of the procedure.</li>
+ * <li>Unused</li>
+ * <li>Unused</li>
+ * <li>Unused</li>
+ * <li>REMARKS - A description of the procedure</li>
* <li>PROCEDURE_TYPE - Indicates the return type of the procedure, which
* is one of the contstants defined in this class
* (<code>procedureResultUnknown</code>, <code>procedureNoResult</code>, or
- * <code>procedureReturnsResult</code>).
+ * <code>procedureReturnsResult</code>).</li>
* </ol>
*
* @param catalog The name of the catalog to return stored procedured from,
@@ -1409,27 +1409,27 @@ public interface DatabaseMetaData
* <p>
* <ol>
* <li>PROCEDURE_CAT - The catalog the procedure is in, which may be
- * <code>null</code>.
+ * <code>null</code>.</li>
* <li>PROCEDURE_SCHEM - The schema the procedures is in, which may be
- * <code>null</code>.
- * <li>PROCEDURE_NAME - The name of the procedure.
- * <li>COLUMN_NAME - The name of the column
+ * <code>null</code>.</li>
+ * <li>PROCEDURE_NAME - The name of the procedure.</li>
+ * <li>COLUMN_NAME - The name of the column</li>
* <li>COLUMN_TYPE - The type of the column, which will be one of the
* contants defined in this class (<code>procedureColumnUnknown</code>,
* <code>procedureColumnIn</code>, <code>procedureColumnInOut</code>,
* <code>procedureColumnOut</code>, <code>procedureColumnReturn</code>,
- * or <code>procedureColumnResult</code>).
+ * or <code>procedureColumnResult</code>).</li>
* <li>DATA_TYPE - The SQL type of the column. This is one of the constants
- * defined in <code>Types</code>.
- * <li>TYPE_NAME - The string name of the data type for this column.
- * <li>PRECISION - The precision of the column.
- * <li>LENGTH - The length of the column in bytes
- * <li>SCALE - The scale of the column.
- * <li>RADIX - The radix of the column.
+ * defined in <code>Types</code>.</li>
+ * <li>TYPE_NAME - The string name of the data type for this column.</li>
+ * <li>PRECISION - The precision of the column.</li>
+ * <li>LENGTH - The length of the column in bytes</li>
+ * <li>SCALE - The scale of the column.</li>
+ * <li>RADIX - The radix of the column.</li>
* <li>NULLABLE - Whether or not the column is NULLABLE. This is one of
* the constants defined in this class (<code>procedureNoNulls</code>,
- * <code>procedureNullable</code>, or <code>procedureNullableUnknown</code>)
- * <li>REMARKS - A description of the column.
+ * <code>procedureNullable</code>, or <code>procedureNullableUnknown</code>)</li>
+ * <li>REMARKS - A description of the column.</li>
* </ol>
*
* @param catalog The name of the catalog to return stored procedured from,
@@ -1448,14 +1448,14 @@ public interface DatabaseMetaData
/**
* This method returns a list of the requested table as a
* <code>ResultSet</code> with the following columns:
- * <p>
+ *
* <ol>
- * <li>TABLE_CAT - The catalog the table is in, which may be <code>null</code>.
- * <li>TABLE_SCHEM - The schema the table is in, which may be <code>null</code>.
- * <li>TABLE_NAME - The name of the table.
+ * <li>TABLE_CAT - The catalog the table is in, which may be <code>null</code>.</li>
+ * <li>TABLE_SCHEM - The schema the table is in, which may be <code>null</code>.</li>
+ * <li>TABLE_NAME - The name of the table.</li>
* <li>TABLE_TYPE - A string describing the table type. This will be one
- * of the values returned by the <code>getTableTypes()</code> method.
- * <li>REMARKS - Comments about the table.
+ * of the values returned by the <code>getTableTypes()</code> method.</li>
+ * <li>REMARKS - Comments about the table.</li>
* </ol>
*
* @param catalog The name of the catalog to return tables from,
@@ -1507,29 +1507,29 @@ public interface DatabaseMetaData
* <p>
* <ol>
* <li>TABLE_CAT - The catalog the table is in, which may be
- * <code>null</code>.
+ * <code>null</code>.</li>
* <li>TABLE_SCHEM - The schema the tables is in, which may be
- * <code>null</code>.
- * <li>TABLE_NAME - The name of the table.
- * <li>COLUMN_NAME - The name of the column
+ * <code>null</code>.</li>
+ * <li>TABLE_NAME - The name of the table.</li>
+ * <li>COLUMN_NAME - The name of the column</li>
* <li>DATA_TYPE - The SQL type of the column. This is one of the constants
- * defined in <code>Types</code>.
- * <li>TYPE_NAME - The string name of the data type for this column.
- * <li>COLUMN_SIZE - The size of the column.
- * <li>Unused
- * <li>NUM_PREC_RADIX - The radix of the column.
+ * defined in <code>Types</code>.</li>
+ * <li>TYPE_NAME - The string name of the data type for this column.</li>
+ * <li>COLUMN_SIZE - The size of the column.</li>
+ * <li>Unused</li>
+ * <li>NUM_PREC_RADIX - The radix of the column.</li>
* <li>NULLABLE - Whether or not the column is NULLABLE. This is one of
* the constants defined in this class (<code>tableNoNulls</code>,
- * <code>tableNullable</code>, or <code>tableNullableUnknown</code>)
- * <li>REMARKS - A description of the column.
- * <li>COLUMN_DEF - The default value for the column, may be <code>null</code>.
- * <li>SQL_DATA_TYPE - Unused
- * <li>SQL_DATETIME_SUB - Unused
+ * <code>tableNullable</code>, or <code>tableNullableUnknown</code>)</li>
+ * <li>REMARKS - A description of the column.</li>
+ * <li>COLUMN_DEF - The default value for the column, may be <code>null</code>.</li>
+ * <li>SQL_DATA_TYPE - Unused</li>
+ * <li>SQL_DATETIME_SUB - Unused</li>
* <li>CHAR_OCTET_LENGTH - For character columns, the maximum number of bytes
- * in the column.
- * <li>ORDINAL_POSITION - The index of the column in the table.
+ * in the column.</li>
+ * <li>ORDINAL_POSITION - The index of the column in the table.</li>
* <li>IS_NULLABLE - "NO" means no, "YES" means maybe, and an empty string
- * means unknown.
+ * means unknown.</li>
* </ol>
*
* @param catalog The name of the catalog to return table from,
@@ -1548,19 +1548,19 @@ public interface DatabaseMetaData
* This method returns the access rights that have been granted to the
* requested columns. This information is returned as a <code>ResultSet</code>
* with the following columns:
- * <p>
+ *
* <ol>
* <li>TABLE_CAT - The catalog the table is in, which may be
- * <code>null</code>.
+ * <code>null</code>.</li>
* <li>TABLE_SCHEM - The schema the tables is in, which may be
- * <code>null</code>.
- * <li>TABLE_NAME - The name of the table.
- * <li>COLUMN_NAME - The name of the column.
- * <li>GRANTOR - The entity that granted the access.
- * <li>GRANTEE - The entity granted the access.
- * <li>PRIVILEGE - The name of the privilege granted.
+ * <code>null</code>.</li>
+ * <li>TABLE_NAME - The name of the table.</li>
+ * <li>COLUMN_NAME - The name of the column.</li>
+ * <li>GRANTOR - The entity that granted the access.</li>
+ * <li>GRANTEE - The entity granted the access.</li>
+ * <li>PRIVILEGE - The name of the privilege granted.</li>
* <li>IS_GRANTABLE - "YES" if the grantee can grant the privilege to
- * others, "NO" if not, and <code>null</code> if unknown.
+ * others, "NO" if not, and <code>null</code> if unknown.</li>
* </ol>
*
* @param catalog The catalog to retrieve information from, or the empty string
@@ -1580,18 +1580,18 @@ public interface DatabaseMetaData
* This method returns the access rights that have been granted to the
* requested tables. This information is returned as a <code>ResultSet</code>
* with the following columns:
- * <p>
+ *
* <ol>
* <li>TABLE_CAT - The catalog the table is in, which may be
- * <code>null</code>.
+ * <code>null</code>.</li>
* <li>TABLE_SCHEM - The schema the tables is in, which may be
- * <code>null</code>.
- * <li>TABLE_NAME - The name of the table.
- * <li>GRANTOR - The entity that granted the access.
- * <li>GRANTEE - The entity granted the access.
- * <li>PRIVILEGE - The name of the privilege granted.
+ * <code>null</code>.</li>
+ * <li>TABLE_NAME - The name of the table.</li>
+ * <li>GRANTOR - The entity that granted the access.</li>
+ * <li>GRANTEE - The entity granted the access.</li>
+ * <li>PRIVILEGE - The name of the privilege granted.</li>
* <li>IS_GRANTABLE - "YES" if the grantee can grant the privilege to
- * others, "NO" if not, and <code>null</code> if unknown.
+ * others, "NO" if not, and <code>null</code> if unknown.</li>
* </ol>
*
* @param catalog The catalog to retrieve information from, or the empty string
@@ -1611,22 +1611,22 @@ public interface DatabaseMetaData
* This method returns the best set of columns for uniquely identifying
* a row. It returns this information as a <code>ResultSet</code> with
* the following columns:
- * <p>
+ *
* <ol>
* <li>SCOPE - The scope of the results returned. This is one of the
* constants defined in this class (<code>bestRowTemporary</code>,
- * <code>bestRowTransaction</code>, or <code>bestRowSession</code>).
- * <li>COLUMN_NAME - The name of the column.
+ * <code>bestRowTransaction</code>, or <code>bestRowSession</code>).</li>
+ * <li>COLUMN_NAME - The name of the column.</li>
* <li>DATA_TYPE - The SQL type of the column. This is one of the constants
- * defined in <code>Types</code>.
- * <li>TYPE_NAME - The string name of the data type for this column.
- * <li>COLUMN_SIZE - The precision of the columns
- * <li>BUFFER_LENGTH - Unused
- * <li>DECIMAL_DIGITS - The scale of the column.
+ * defined in <code>Types</code>.</li>
+ * <li>TYPE_NAME - The string name of the data type for this column.</li>
+ * <li>COLUMN_SIZE - The precision of the columns</li>
+ * <li>BUFFER_LENGTH - Unused</li>
+ * <li>DECIMAL_DIGITS - The scale of the column.</li>
* <li>PSEUDO_COLUMN - Whether or not the best row identifier is a
* pseudo_column. This is one of the constants defined in this class
* (<code>bestRowUnknown</code>, <code>bestRowNotPseudo</code>, or
- * <code>bestRowPseudo</code>).
+ * <code>bestRowPseudo</code>).</li>
* </ol>
*
* @param catalog The catalog to retrieve information from, or the empty string
@@ -1649,20 +1649,20 @@ public interface DatabaseMetaData
* This method returns the set of columns that are automatically updated
* when the row is update. It returns this information as a
* <code>ResultSet</code> with the following columns:
- * <p>
+ *
* <ol>
- * <li>SCOPE - Unused
- * <li>COLUMN_NAME - The name of the column.
+ * <li>SCOPE - Unused</li>
+ * <li>COLUMN_NAME - The name of the column.</li>
* <li>DATA_TYPE - The SQL type of the column. This is one of the constants
- * defined in <code>Types</code>.
- * <li>TYPE_NAME - The string name of the data type for this column.
- * <li>COLUMN_SIZE - The precision of the columns
- * <li>BUFFER_LENGTH - Unused
- * <li>DECIMAL_DIGITS - The scale of the column.
+ * defined in <code>Types</code>.</li>
+ * <li>TYPE_NAME - The string name of the data type for this column.</li>
+ * <li>COLUMN_SIZE - The precision of the columns</li>
+ * <li>BUFFER_LENGTH - Unused</li>
+ * <li>DECIMAL_DIGITS - The scale of the column.</li>
* <li>PSEUDO_COLUMN - Whether or not the best row identifier is a
* pseudo_column. This is one of the constants defined in this class
* (<code>versionRowUnknown</code>, <code>versionRowNotPseudo</code>, or
- * <code>versionRowPseudo</code>).
+ * <code>versionRowPseudo</code>).</li>
* </ol>
*
* @param catalog The catalog to retrieve information from, or the empty string
@@ -1681,14 +1681,14 @@ public interface DatabaseMetaData
/**
* This method returns a list of a table's primary key columns. These
* are returned as a <code>ResultSet</code> with the following columns.
- * <p>
+ *
* <ol>
- * <li>TABLE_CAT - The catalog of the table, which may be <code>null</code>.
- * <li>TABLE_SCHEM - The schema of the table, which may be <code>null</code>.
- * <li>TABLE_NAME - The name of the table.
- * <li>COLUMN_NAME - The name of the column.
- * <li>KEY_SEQ - The sequence number of the column within the primary key.
- * <li>PK_NAME - The name of the primary key, which may be <code>null</code>.
+ * <li>TABLE_CAT - The catalog of the table, which may be <code>null</code>.</li>
+ * <li>TABLE_SCHEM - The schema of the table, which may be <code>null</code>.</li>
+ * <li>TABLE_NAME - The name of the table.</li>
+ * <li>COLUMN_NAME - The name of the column.</li>
+ * <li>KEY_SEQ - The sequence number of the column within the primary key.</li>
+ * <li>PK_NAME - The name of the primary key, which may be <code>null</code>.</li>
* </ol>
*
* @param catalog The catalog to retrieve information from, or the empty string
@@ -1707,32 +1707,32 @@ public interface DatabaseMetaData
/**
* This method returns a list of the table's foreign keys. These are
* returned as a <code>ResultSet</code> with the following columns:
- * <p>
+ *
* <ol>
- * <li>PKTABLE_CAT - The catalog of the table the key was imported from.
- * <li>PKTABLE_SCHEM - The schema of the table the key was imported from.
- * <li>PKTABLE_NAME - The name of the table the key was imported from.
- * <li>PKCOLUMN_NAME - The name of the column that was imported.
- * <li>FKTABLE_CAT - The foreign key catalog name.
- * <li>FKTABLE_SCHEM - The foreign key schema name.
- * <li>FKTABLE_NAME - The foreign key table name.
- * <li>FKCOLUMN_NAME - The foreign key column name.
- * <li>KEY_SEQ - The sequence number of the column within the foreign key.
+ * <li>PKTABLE_CAT - The catalog of the table the key was imported from.</li>
+ * <li>PKTABLE_SCHEM - The schema of the table the key was imported from.</li>
+ * <li>PKTABLE_NAME - The name of the table the key was imported from.</li>
+ * <li>PKCOLUMN_NAME - The name of the column that was imported.</li>
+ * <li>FKTABLE_CAT - The foreign key catalog name.</li>
+ * <li>FKTABLE_SCHEM - The foreign key schema name.</li>
+ * <li>FKTABLE_NAME - The foreign key table name.</li>
+ * <li>FKCOLUMN_NAME - The foreign key column name.</li>
+ * <li>KEY_SEQ - The sequence number of the column within the foreign key.</li>
* <li>UPDATE_RULE - How the foreign key behaves when the primary key is
* updated. This is one of the constants defined in this class
* (<code>importedNoAction</code>, <code>importedKeyCascade</code>,
* <code>importedKeySetNull</code>, <code>importedKeySetDefault</code>, or
- * <code>importedKeyRestrict</code>).
+ * <code>importedKeyRestrict</code>).</li>
* <li>DELETE_RULE - How the foreign key behaves when the primary key is
* deleted. This is one of the constants defined in this class
* (<code>importedNoAction</code>, <code>importedKeyCascade</code>,
- * <code>importedKeySetNull</code>, or <code>importedKeySetDefault</code>)
- * <li>FK_NAME - The name of the foreign key.
- * <li>PK_NAME - The name of the primary key.
+ * <code>importedKeySetNull</code>, or <code>importedKeySetDefault</code>)</li>
+ * <li>FK_NAME - The name of the foreign key.</li>
+ * <li>PK_NAME - The name of the primary key.</li>
* <li>DEFERRABILITY - The deferrability value. This is one of the
* constants defined in this table (<code>importedKeyInitiallyDeferred</code>,
* <code>importedKeyInitiallyImmediate</code>, or
- * <code>importedKeyNotDeferrable</code>).
+ * <code>importedKeyNotDeferrable</code>).</li>
* </ol>
*
* @param catalog The catalog to retrieve information from, or the empty string
@@ -1753,32 +1753,32 @@ public interface DatabaseMetaData
* This method returns a list of the table's which use this table's
* primary key as a foreign key. The information is
* returned as a <code>ResultSet</code> with the following columns:
- * <p>
+ *
* <ol>
- * <li>PKTABLE_CAT - The catalog of the table the key was imported from.
- * <li>PKTABLE_SCHEM - The schema of the table the key was imported from.
- * <li>PKTABLE_NAME - The name of the table the key was imported from.
- * <li>PKCOLUMN_NAME - The name of the column that was imported.
- * <li>FKTABLE_CAT - The foreign key catalog name.
- * <li>FKTABLE_SCHEM - The foreign key schema name.
- * <li>FKTABLE_NAME - The foreign key table name.
- * <li>FKCOLUMN_NAME - The foreign key column name.
- * <li>KEY_SEQ - The sequence number of the column within the foreign key.
+ * <li>PKTABLE_CAT - The catalog of the table the key was imported from.</li>
+ * <li>PKTABLE_SCHEM - The schema of the table the key was imported from.</li>
+ * <li>PKTABLE_NAME - The name of the table the key was imported from.</li>
+ * <li>PKCOLUMN_NAME - The name of the column that was imported.</li>
+ * <li>FKTABLE_CAT - The foreign key catalog name.</li>
+ * <li>FKTABLE_SCHEM - The foreign key schema name.</li>
+ * <li>FKTABLE_NAME - The foreign key table name.</li>
+ * <li>FKCOLUMN_NAME - The foreign key column name.</li>
+ * <li>KEY_SEQ - The sequence number of the column within the foreign key.</li>
* <li>UPDATE_RULE - How the foreign key behaves when the primary key is
* updated. This is one of the constants defined in this class
* (<code>importedNoAction</code>, <code>importedKeyCascade</code>,
* <code>importedKeySetNull</code>, <code>importedKeySetDefault</code>, or
- * <code>importedKeyRestrict</code>).
+ * <code>importedKeyRestrict</code>).</li>
* <li>DELETE_RULE - How the foreign key behaves when the primary key is
* deleted. This is one of the constants defined in this class
* (<code>importedNoAction</code>, <code>importedKeyCascade</code>,
- * <code>importedKeySetNull</code>, or <code>importedKeySetDefault</code>)
- * <li>FK_NAME - The name of the foreign key.
- * <li>PK_NAME - The name of the primary key.
+ * <code>importedKeySetNull</code>, or <code>importedKeySetDefault</code>)</li>
+ * <li>FK_NAME - The name of the foreign key.</li>
+ * <li>PK_NAME - The name of the primary key.</li>
* <li>DEFERRABILITY - The deferrability value. This is one of the
* constants defined in this table (<code>importedKeyInitiallyDeferred</code>,
* <code>importedKeyInitiallyImmediate</code>, or
- * <code>importedKeyNotDeferrable</code>).
+ * <code>importedKeyNotDeferrable</code>).</li>
* </ol>
*
* @param catalog The catalog to retrieve information from, or the empty string
@@ -1797,32 +1797,32 @@ public interface DatabaseMetaData
* This method returns a description of how one table imports another
* table's primary key as a foreign key. The information is
* returned as a <code>ResultSet</code> with the following columns:
- * <p>
+ *
* <ol>
- * <li>PKTABLE_CAT - The catalog of the table the key was imported from.
- * <li>PKTABLE_SCHEM - The schema of the table the key was imported from.
- * <li>PKTABLE_NAME - The name of the table the key was imported from.
- * <li>PKCOLUMN_NAME - The name of the column that was imported.
- * <li>FKTABLE_CAT - The foreign key catalog name.
- * <li>FKTABLE_SCHEM - The foreign key schema name.
- * <li>FKTABLE_NAME - The foreign key table name.
- * <li>FKCOLUMN_NAME - The foreign key column name.
- * <li>KEY_SEQ - The sequence number of the column within the foreign key.
+ * <li>PKTABLE_CAT - The catalog of the table the key was imported from.</li>
+ * <li>PKTABLE_SCHEM - The schema of the table the key was imported from.</li>
+ * <li>PKTABLE_NAME - The name of the table the key was imported from.</li>
+ * <li>PKCOLUMN_NAME - The name of the column that was imported.</li>
+ * <li>FKTABLE_CAT - The foreign key catalog name.</li>
+ * <li>FKTABLE_SCHEM - The foreign key schema name.</li>
+ * <li>FKTABLE_NAME - The foreign key table name.</li>
+ * <li>FKCOLUMN_NAME - The foreign key column name.</li>
+ * <li>KEY_SEQ - The sequence number of the column within the foreign key.</li>
* <li>UPDATE_RULE - How the foreign key behaves when the primary key is
* updated. This is one of the constants defined in this class
* (<code>importedNoAction</code>, <code>importedKeyCascade</code>,
* <code>importedKeySetNull</code>, <code>importedKeySetDefault</code>, or
- * <code>importedKeyRestrict</code>).
+ * <code>importedKeyRestrict</code>).</li>
* <li>DELETE_RULE - How the foreign key behaves when the primary key is
* deleted. This is one of the constants defined in this class
* (<code>importedNoAction</code>, <code>importedKeyCascade</code>,
- * <code>importedKeySetNull</code>, or <code>importedKeySetDefault</code>)
- * <li>FK_NAME - The name of the foreign key.
- * <li>PK_NAME - The name of the primary key.
+ * <code>importedKeySetNull</code>, or <code>importedKeySetDefault</code>)</li>
+ * <li>FK_NAME - The name of the foreign key.</li>
+ * <li>PK_NAME - The name of the primary key.</li>
* <li>DEFERRABILITY - The deferrability value. This is one of the
* constants defined in this table (<code>importedKeyInitiallyDeferred</code>,
* <code>importedKeyInitiallyImmediate</code>, or
- * <code>importedKeyNotDeferrable</code>).
+ * <code>importedKeyNotDeferrable</code>).</li>
* </ol>
*
* @param primCatalog The catalog to retrieve information from, or the empty string
@@ -1850,36 +1850,36 @@ public interface DatabaseMetaData
* This method returns a list of the SQL types supported by this
* database. The information is returned as a <code>ResultSet</code>
* with the following columns:
- * <p>
+ *
* <ol>
- * <li>TYPE_NAME - The name of the data type.
+ * <li>TYPE_NAME - The name of the data type.</li>
* <li>DATA_TYPE - A data type constant from <code>Types</code> for this
- * type.
- * <li>PRECISION - The maximum precision of this type.
+ * type.</li>
+ * <li>PRECISION - The maximum precision of this type.</li>
* <li>LITERAL_PREFIX - Prefix value used to quote a literal, which may be
- * <code>null</code>.
+ * <code>null</code>.</li>
* <li>LITERAL_SUFFIX - Suffix value used to quote a literal, which may be
- * <code>null</code>.
+ * <code>null</code>.</li>
* <li>CREATE_PARAMS - The parameters used to create the type, which may be
- * <code>null</code>.
+ * <code>null</code>.</li>
* <li>NULLABLE - Whether or not this type supports NULL values. This will
* be one of the constants defined in this interface
* (<code>typeNoNulls</code>, <code>typeNullable</code>, or
- * <code>typeNullableUnknown</code>).
- * <li>CASE_SENSITIVE - Whether or not the value is case sensitive.
+ * <code>typeNullableUnknown</code>).</li>
+ * <li>CASE_SENSITIVE - Whether or not the value is case sensitive.</li>
* <li>SEARCHABLE - Whether or not "LIKE" expressions are supported in
* WHERE clauses for this type. This will be one of the constants defined
* in this interface (<code>typePredNone</code>, <code>typePredChar</code>,
- * <code>typePredBasic</code>, or <code>typeSearchable</code>).
- * <li>UNSIGNED_ATTRIBUTE - Is the value of this type unsigned.
- * <li>FIXED_PREC_SCALE - Whether or not this type can be used for money.
- * <li>AUTO_INCREMENT - Whether or not this type supports auto-incrementing.
- * <li>LOCAL_TYPE_NAME - A localized name for this data type.
- * <li>MINIMUM_SCALE - The minimum scale supported by this type.
- * <li>MAXIMUM_SCALE - The maximum scale supported by this type.
- * <li>SQL_DATA_TYPE - Unused.
- * <li>SQL_DATETIME_SUB - Unused.
- * <li>NUM_PREC_RADIX - The radix of this data type.
+ * <code>typePredBasic</code>, or <code>typeSearchable</code>).</li>
+ * <li>UNSIGNED_ATTRIBUTE - Is the value of this type unsigned.</li>
+ * <li>FIXED_PREC_SCALE - Whether or not this type can be used for money.</li>
+ * <li>AUTO_INCREMENT - Whether or not this type supports auto-incrementing.</li>
+ * <li>LOCAL_TYPE_NAME - A localized name for this data type.</li>
+ * <li>MINIMUM_SCALE - The minimum scale supported by this type.</li>
+ * <li>MAXIMUM_SCALE - The maximum scale supported by this type.</li>
+ * <li>SQL_DATA_TYPE - Unused.</li>
+ * <li>SQL_DATETIME_SUB - Unused.</li>
+ * <li>NUM_PREC_RADIX - The radix of this data type.</li>
* </ol>
*
* @return A <code>ResultSet</code> with the list of available data types.
@@ -1890,30 +1890,30 @@ public interface DatabaseMetaData
/**
* This method returns information about a tables indices and statistics.
* It is returned as a <code>ResultSet</code> with the following columns:
- * <p>
+ *
* <ol>
- * <li>TABLE_CAT - The catalog of the table, which may be <code>null</code>.
- * <li>TABLE_SCHEM - The schema of the table, which may be <code>null</code>.
- * <li>TABLE_NAME - The name of the table.
- * <li>NON_UNIQUE - Are index values non-unique?
- * <li>INDEX_QUALIFIER The index catalog, which may be <code>null</code>
- * <li>INDEX_NAME - The name of the index.
+ * <li>TABLE_CAT - The catalog of the table, which may be <code>null</code>.</li>
+ * <li>TABLE_SCHEM - The schema of the table, which may be <code>null</code>.</li>
+ * <li>TABLE_NAME - The name of the table.</li>
+ * <li>NON_UNIQUE - Are index values non-unique?</li>
+ * <li>INDEX_QUALIFIER The index catalog, which may be <code>null</code></li>
+ * <li>INDEX_NAME - The name of the index.</li>
* <li>TYPE - The type of index, which will be one of the constants defined
* in this interface (<code>tableIndexStatistic</code>,
* <code>tableIndexClustered</code>, <code>tableIndexHashed</code>, or
- * <code>tableIndexOther</code>).
+ * <code>tableIndexOther</code>).</li>
* <li>ORDINAL_POSITION - The sequence number of this column in the index.
- * This will be 0 when the index type is <code>tableIndexStatistic</code>.
- * <li>COLUMN_NAME - The name of this column in the index.
+ * This will be 0 when the index type is <code>tableIndexStatistic</code>.</li>
+ * <li>COLUMN_NAME - The name of this column in the index.</li>
* <li>ASC_OR_DESC - "A" for an ascending sort sequence, "D" for a
* descending sort sequence or <code>null</code> if a sort sequence is not
- * supported.
+ * supported.</li>
* <li>CARDINALITY - The number of unique rows in the index, or the number
- * of rows in the table if the index type is <code>tableIndexStatistic</code>.
+ * of rows in the table if the index type is <code>tableIndexStatistic</code>.</li>
* <li>PAGES - The number of pages used for the index, or the number of pages
- * in the table if the index type is <code>tableIndexStatistic</code>.
+ * in the table if the index type is <code>tableIndexStatistic</code>.</li>
* <li>FILTER_CONDITION - The filter condition for this index, which may be
- * <code>null</code>.
+ * <code>null</code>.</li>
* </ol>
*
* @param catalog The catalog to retrieve information from, or the empty string
@@ -2093,16 +2093,16 @@ public interface DatabaseMetaData
/**
* This method returns the list of user defined data types in use. These
* are returned as a <code>ResultSet</code> with the following columns:
- * <p>
+ *
* <ol>
- * <li>TYPE_CAT - The catalog name, which may be <code>null</code>.
- * <li>TYPE_SCEHM - The schema name, which may be <code>null</code>.
- * <li>TYPE_NAME - The user defined data type name.
- * <li>CLASS_NAME - The Java class name this type maps to.
+ * <li>TYPE_CAT - The catalog name, which may be <code>null</code>.</li>
+ * <li>TYPE_SCEHM - The schema name, which may be <code>null</code>.</li>
+ * <li>TYPE_NAME - The user defined data type name.</li>
+ * <li>CLASS_NAME - The Java class name this type maps to.</li>
* <li>DATA_TYPE - A type identifier from <code>Types</code> for this type.
* This will be one of <code>JAVA_OBJECT</code>, <code>STRUCT</code>, or
- * <code>DISTINCT</code>.
- * <li>REMARKS - Comments about this data type.
+ * <code>DISTINCT</code>.</li>
+ * <li>REMARKS - Comments about this data type.</li>
* </ol>
*
* @param catalog The catalog to retrieve information from, or the empty string
diff --git a/libjava/java/sql/DriverManager.java b/libjava/java/sql/DriverManager.java
index 649c5ae7339..695aab17778 100644
--- a/libjava/java/sql/DriverManager.java
+++ b/libjava/java/sql/DriverManager.java
@@ -1,5 +1,5 @@
/* DriverManager.java -- Manage JDBC drivers
- Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -41,8 +41,8 @@ import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Properties;
-import java.util.Vector;
import java.util.StringTokenizer;
+import java.util.Vector;
/**
* This class manages the JDBC drivers in the system. It maintains a
diff --git a/libjava/java/sql/ResultSet.java b/libjava/java/sql/ResultSet.java
index 46a6c65c3f7..bbc2bae137d 100644
--- a/libjava/java/sql/ResultSet.java
+++ b/libjava/java/sql/ResultSet.java
@@ -48,14 +48,14 @@ import java.util.Map;
/**
* This interface provides access to the data set returned by a SQL
* statement. An instance of this interface is returned by the various
- * execution methods in the <code>Statement</code.
- * <p>
- * This class models a cursor, which can be stepped through one row at a
+ * execution methods in the <code>Statement</code>.
+ *
+ * <p> This class models a cursor, which can be stepped through one row at a
* time. Methods are provided for accessing columns by column name or by
- * index.
- * <p>
- * Note that a result set is invalidated if the statement that returned
- * it is closed.
+ * index.</p>
+ *
+ * <p> Note that a result set is invalidated if the statement that returned
+ * it is closed.</p>
*
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
diff --git a/libjava/java/text/AttributedCharacterIterator.java b/libjava/java/text/AttributedCharacterIterator.java
index bcb2885e460..c1366adc4ad 100644
--- a/libjava/java/text/AttributedCharacterIterator.java
+++ b/libjava/java/text/AttributedCharacterIterator.java
@@ -1,5 +1,5 @@
/* AttributedCharacterIterator.java -- Iterate over attributes
- Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
diff --git a/libjava/java/text/AttributedString.java b/libjava/java/text/AttributedString.java
index a8eede813fc..8304cedf7bc 100644
--- a/libjava/java/text/AttributedString.java
+++ b/libjava/java/text/AttributedString.java
@@ -38,10 +38,10 @@ exception statement from your version. */
package java.text;
-import java.util.Iterator;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Hashtable;
-import java.util.HashSet;
+import java.util.Iterator;
import java.util.Map;
import java.util.Set;
@@ -219,26 +219,7 @@ AttributedString(AttributedCharacterIterator aci, int begin_index,
// Get the valid attribute list
Set all_attribs = aci.getAllAttributeKeys();
if (attributes != null)
- {
- Set valid_attribs = new HashSet();
- Iterator iter = all_attribs.iterator();
- while (iter.hasNext())
- {
- Object obj = iter.next();
-
- int i;
- for (i = 0; i < attributes.length; i++)
- if (obj.equals(attributes[0]))
- break;
-
- if (i == attributes.length)
- continue;
-
- valid_attribs.add(obj);
- }
-
- all_attribs = valid_attribs;
- }
+ all_attribs.retainAll(Arrays.asList(attributes));
// Loop through and extract the attributes
char c = aci.setIndex(begin_index);
@@ -320,7 +301,7 @@ AttributedString(AttributedCharacterIterator aci, int begin_index,
public void
addAttribute(AttributedCharacterIterator.Attribute attrib, Object value)
{
- addAttribute(attrib, value, 0, sci.getEndIndex() - 1);
+ addAttribute(attrib, value, 0, sci.getEndIndex());
}
/*************************************************************************/
@@ -389,8 +370,7 @@ addAttributes(Map attributes, int begin_index, int end_index)
public AttributedCharacterIterator
getIterator()
{
- return(new AttributedStringIterator(sci, attribs, 0, sci.getEndIndex() - 1,
- null));
+ return(new AttributedStringIterator(sci, attribs, 0, sci.getEndIndex(), null));
}
/*************************************************************************/
@@ -409,7 +389,7 @@ getIterator()
public AttributedCharacterIterator
getIterator(AttributedCharacterIterator.Attribute[] attributes)
{
- return(getIterator(attributes, 0, sci.getEndIndex() - 1));
+ return(getIterator(attributes, 0, sci.getEndIndex()));
}
/*************************************************************************/
diff --git a/libjava/java/text/AttributedStringIterator.java b/libjava/java/text/AttributedStringIterator.java
index 77c5981703d..ca20801141c 100644
--- a/libjava/java/text/AttributedStringIterator.java
+++ b/libjava/java/text/AttributedStringIterator.java
@@ -1,5 +1,5 @@
/* AttributedStringIterator.java -- Class to iterate over AttributedString
- Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,11 +38,11 @@ exception statement from your version. */
package java.text;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.Map;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
/**
* This class implements the AttributedCharacterIterator interface. It
@@ -221,39 +221,28 @@ getRunLimit(AttributedCharacterIterator.Attribute attrib)
public synchronized int
getRunLimit(Set attribute_set)
{
- int orig_index = ci.getIndex();
- int run_limit;
+ boolean hit = false;
+ int runLimit = ci.getEndIndex ();
+ int pos = ci.getIndex ();
- do
+ for (int i = 0; i < attribs.length; ++i)
{
- run_limit = ci.getIndex();
-
- Map attribute_map = getAttributes();
-
- boolean found = false;
- Iterator iter = attribute_set.iterator();
- while(iter.hasNext())
- if (!attribute_map.containsKey(iter.next()))
- {
- found = true;
- break;
- }
-
- if (found)
- break;
+ if (pos >= attribs[i].begin_index &&
+ pos <= attribs[i].end_index)
+ {
+ Iterator iter = attribute_set.iterator();
+ while(iter.hasNext())
+ if (attribs[i].attribs.containsKey(iter.next()))
+ {
+ hit = true;
+ runLimit = Math.min(runLimit, attribs[i].end_index);
+ }
+ }
}
- while (ci.next() != CharacterIterator.DONE);
-
- boolean hit_end = (ci.previous() == CharacterIterator.DONE);
-
- ci.setIndex(orig_index);
-
- if (run_limit == orig_index)
- return(-1); // No characters match the given attributes
-// else if (!hit_end)
-// --run_limit;
-
- return(run_limit);
+ if (hit)
+ return runLimit;
+ else
+ return -1;
}
/*************************************************************************/
@@ -281,35 +270,28 @@ getRunStart(AttributedCharacterIterator.Attribute attrib)
public int
getRunStart(Set attribute_set)
{
- int orig_index = ci.getIndex();
- int run_start;
+ boolean hit = false;
+ int runBegin = 0;
+ int pos = ci.getIndex ();
- do
+ for (int i = 0; i < attribs.length; ++i)
{
- run_start = ci.getIndex();
-
- Map attribute_map = getAttributes();
-
- Iterator iter = attribute_set.iterator();
- while(iter.hasNext())
- if (!attribute_map.containsKey(iter.next()))
- break;
-
- if (iter.hasNext())
- break;
+ if (pos >= attribs[i].begin_index &&
+ pos <= attribs[i].end_index)
+ {
+ Iterator iter = attribute_set.iterator();
+ while(iter.hasNext())
+ if (attribs[i].attribs.containsKey(iter.next()))
+ {
+ hit = true;
+ runBegin = Math.max(runBegin, attribs[i].begin_index);
+ }
+ }
}
- while (ci.previous() != CharacterIterator.DONE);
-
- boolean hit_beginning = (ci.previous() == CharacterIterator.DONE);
-
- ci.setIndex(orig_index);
-
- if (run_start == orig_index)
- return(-1); // No characters match the given attributes
- else if (!hit_beginning)
- ++run_start;
-
- return(run_start);
+ if (hit)
+ return runBegin;
+ else
+ return -1;
}
/*************************************************************************/
diff --git a/libjava/java/text/ChoiceFormat.java b/libjava/java/text/ChoiceFormat.java
index f7bdde1e294..f23bd128a5e 100644
--- a/libjava/java/text/ChoiceFormat.java
+++ b/libjava/java/text/ChoiceFormat.java
@@ -45,7 +45,7 @@ import java.util.Vector;
* To use this class, first specify two lists of formats and range terminators.
* These lists must be arrays of equal length. The format of index
* <code>i</code> will be selected for value <code>X</code> if
- * <code>terminator[i] <= X < limit[i + 1]</code>. If the value X is not
+ * <code>terminator[i] &lt;= X &lt; limit[i + 1]</code>. If the value X is not
* included in any range, then either the first or last format will be
* used depending on whether the value X falls outside the range.
* <p>
@@ -196,10 +196,10 @@ public class ChoiceFormat extends NumberFormat
* This method tests this object for equality with the specified
* object. This will be true if and only if:
* <ul>
- * <li>The specified object is not <code>null</code>.
- * <li>The specified object is an instance of <code>ChoiceFormat</code>.
+ * <li>The specified object is not <code>null</code>.</li>
+ * <li>The specified object is an instance of <code>ChoiceFormat</code>.</li>
* <li>The termination ranges and format strings are identical to
- * this object's.
+ * this object's. </li>
* </ul>
*
* @param obj The object to test for equality against.
diff --git a/libjava/java/text/CollationElementIterator.java b/libjava/java/text/CollationElementIterator.java
index 691d943d21b..1b5a6172e06 100644
--- a/libjava/java/text/CollationElementIterator.java
+++ b/libjava/java/text/CollationElementIterator.java
@@ -129,11 +129,13 @@ public final class CollationElementIterator
/**
* This method resets the internal position pointer to read from the
- * beginning of the <code>String again.
+ * beginning of the <code>String</code> again.
*/
public void reset()
{
textIndex = 0;
+ lookahead_set = false;
+ lookahead = 0;
}
/**
diff --git a/libjava/java/text/CollationKey.java b/libjava/java/text/CollationKey.java
index 8859b320463..abc28b22ebb 100644
--- a/libjava/java/text/CollationKey.java
+++ b/libjava/java/text/CollationKey.java
@@ -140,12 +140,12 @@ public final class CollationKey implements Comparable
* this object. This will be true if and only if:
* <p>
* <ul>
- * <li>The specified object must not be <code>null</code>
- * <li>The specified object is an instance of <code>CollationKey</code>.
+ * <li>The specified object must not be <code>null</code></li>
+ * <li>The specified object is an instance of <code>CollationKey</code>.</li>
* <li>The specified object was created from the same <code>Collator</code>
- * as this object.
+ * as this object.</li>
* <li>The specified object has the same source string and bit key as
- * this object.
+ * this object.</li>
* </ul>
*
* @param obj The <code>Object</code> to test for equality.
diff --git a/libjava/java/text/Collator.java b/libjava/java/text/Collator.java
index bb5a3449139..7944d9501e5 100644
--- a/libjava/java/text/Collator.java
+++ b/libjava/java/text/Collator.java
@@ -1,5 +1,5 @@
/* Collator.java -- Perform locale dependent String comparisons.
- Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,10 +38,10 @@ exception statement from your version. */
package java.text;
+import java.util.Comparator;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
-import java.util.Comparator;
/**
* This class is the abstract superclass of classes which perform
@@ -183,10 +183,10 @@ public abstract class Collator implements Comparator, Cloneable
* object. This will be true if and only if the following conditions are
* met:
* <ul>
- * <li>The specified object is not <code>null</code>.
- * <li>The specified object is an instance of <code>Collator</code>.
+ * <li>The specified object is not <code>null</code>.</li>
+ * <li>The specified object is an instance of <code>Collator</code>.</li>
* <li>The specified object has the same strength and decomposition
- * settings as this object.
+ * settings as this object.</li>
* </ul>
*
* @param obj The <code>Object</code> to test for equality against
diff --git a/libjava/java/text/DateFormat.java b/libjava/java/text/DateFormat.java
index 745a16b3ec2..0947b8058ad 100644
--- a/libjava/java/text/DateFormat.java
+++ b/libjava/java/text/DateFormat.java
@@ -196,9 +196,9 @@ public abstract class DateFormat extends Format implements Cloneable
* object:
* <P>
* <ul>
- * <li>Is not <code>null</code>.
- * <li>Is an instance of <code>DateFormat</code>.
- * <li>Has the same numberFormat field value as this object.
+ * <li>Is not <code>null</code>.</li>
+ * <li>Is an instance of <code>DateFormat</code>.</li>
+ * <li>Has the same numberFormat field value as this object.</li>
* </ul>
*
* @param obj The object to test for equality against.
diff --git a/libjava/java/text/DateFormatSymbols.java b/libjava/java/text/DateFormatSymbols.java
index 526f7120bcc..33a541bd1b7 100644
--- a/libjava/java/text/DateFormatSymbols.java
+++ b/libjava/java/text/DateFormatSymbols.java
@@ -245,11 +245,12 @@ public class DateFormatSymbols implements java.io.Serializable, Cloneable
* the array contains five values:
* <P>
* <ul>
- * <li>0 - The non-localized time zone id string.
- * <li>1 - The long name of the time zone (standard time).
- * <li>2 - The short name of the time zone (standard time).
- * <li>3 - The long name of the time zone (daylight savings time).
- * <li>4 - the short name of the time zone (daylight savings time).
+ * <li>0 - The non-localized time zone id string.</li>
+ * <li>1 - The long name of the time zone (standard time).</li>
+ * <li>2 - The short name of the time zone (standard time).</li>
+ * <li>3 - The long name of the time zone (daylight savings time).</li>
+ * <li>4 - the short name of the time zone (daylight savings time).</li>
+ * </ul>
*
* @return The list of time zone display strings.
*/
@@ -386,11 +387,12 @@ public class DateFormatSymbols implements java.io.Serializable, Cloneable
* the array contains five values:
* <P>
* <ul>
- * <li>0 - The non-localized time zone id string.
- * <li>1 - The long name of the time zone (standard time).
- * <li>2 - The short name of the time zone (standard time).
- * <li>3 - The long name of the time zone (daylight savings time).
- * <li>4 - the short name of the time zone (daylight savings time).
+ * <li>0 - The non-localized time zone id string.</li>
+ * <li>1 - The long name of the time zone (standard time).</li>
+ * <li>2 - The short name of the time zone (standard time).</li>
+ * <li>3 - The long name of the time zone (daylight savings time).</li>
+ * <li>4 - the short name of the time zone (daylight savings time).</li>
+ * </ul>
*
* @return The list of time zone display strings.
*/
@@ -438,15 +440,15 @@ public class DateFormatSymbols implements java.io.Serializable, Cloneable
* This will be true if and only if the specified object:
* <p>
* <ul>
- * <li> Is not <code>null</code>.
- * <li> Is an instance of <code>DateFormatSymbols</code>.
- * <li> Contains identical formatting symbols to this object.
+ * <li> Is not <code>null</code>.</li>
+ * <li> Is an instance of <code>DateFormatSymbols</code>.</li>
+ * <li> Contains identical formatting symbols to this object.</li>
* </ul>
*
* @param obj The <code>Object</code> to test for equality against.
*
* @return <code>true</code> if the specified object is equal to this one,
- * </code>false</code> otherwise.
+ * <code>false</code> otherwise.
*/
public boolean equals (Object obj)
{
diff --git a/libjava/java/text/DecimalFormat.java b/libjava/java/text/DecimalFormat.java
index 359ad5591b0..497a705670c 100644
--- a/libjava/java/text/DecimalFormat.java
+++ b/libjava/java/text/DecimalFormat.java
@@ -37,7 +37,13 @@ exception statement from your version. */
package java.text;
+import gnu.java.text.AttributedFormatBuffer;
+import gnu.java.text.FormatBuffer;
+import gnu.java.text.FormatCharacterIterator;
+import gnu.java.text.StringFormatBuffer;
+
import java.util.Currency;
+import java.util.HashMap;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
@@ -58,55 +64,66 @@ public class DecimalFormat extends NumberFormat
{
// This is a helper for applyPatternWithSymbols. It reads a prefix
// or a suffix. It can cause some side-effects.
- private final int scanFix (String pattern, int index, StringBuffer buf,
+ private final int scanFix (String pattern, int index, FormatBuffer buf,
String patChars, DecimalFormatSymbols syms,
boolean is_suffix)
{
int len = pattern.length();
- buf.setLength(0);
+ boolean quoteStarted = false;
+ buf.clear();
+
boolean multiplierSet = false;
while (index < len)
{
char c = pattern.charAt(index);
+
+ if (quoteStarted)
+ {
+ if (c == '\'')
+ quoteStarted = false;
+ else
+ buf.append(c);
+ index++;
+ continue;
+ }
+
if (c == '\'' && index + 1 < len
&& pattern.charAt(index + 1) == '\'')
{
buf.append(c);
- ++index;
+ index++;
}
- else if (c == '\'' && index + 2 < len
- && pattern.charAt(index + 2) == '\'')
+ else if (c == '\'')
{
- buf.append(pattern.charAt(index + 1));
- index += 2;
+ quoteStarted = true;
}
else if (c == '\u00a4')
{
if (index + 1 < len && pattern.charAt(index + 1) == '\u00a4')
{
- buf.append(syms.getInternationalCurrencySymbol());
- ++index;
+ buf.append(syms.getInternationalCurrencySymbol(), NumberFormat.Field.CURRENCY);
+ index++;
}
else
- buf.append(syms.getCurrencySymbol());
+ buf.append(syms.getCurrencySymbol(), NumberFormat.Field.CURRENCY);
}
- else if (is_suffix && c == syms.getPercent())
+ else if (c == syms.getPercent())
{
if (multiplierSet)
throw new IllegalArgumentException ("multiplier already set " +
"- index: " + index);
multiplierSet = true;
multiplier = 100;
- buf.append(c);
+ buf.append(c, NumberFormat.Field.PERCENT);
}
- else if (is_suffix && c == syms.getPerMill())
+ else if (c == syms.getPerMill())
{
if (multiplierSet)
throw new IllegalArgumentException ("multiplier already set " +
"- index: " + index);
multiplierSet = true;
multiplier = 1000;
- buf.append(c);
+ buf.append(c, NumberFormat.Field.PERMILLE);
}
else if (patChars.indexOf(c) != -1)
{
@@ -115,9 +132,12 @@ public class DecimalFormat extends NumberFormat
}
else
buf.append(c);
- ++index;
+ index++;
}
+ if (quoteStarted)
+ throw new IllegalArgumentException ("pattern is lacking a closing quote");
+
return index;
}
@@ -259,6 +279,16 @@ public class DecimalFormat extends NumberFormat
useExponentialNotation = true;
minExponentDigits = (byte) zeroCount;
}
+
+ maximumIntegerDigits = groupingSize;
+ groupingSize = 0;
+ if (maximumIntegerDigits > minimumIntegerDigits && maximumIntegerDigits > 0)
+ {
+ minimumIntegerDigits = 1;
+ exponentRound = maximumIntegerDigits;
+ }
+ else
+ exponentRound = 1;
}
return index;
@@ -300,21 +330,27 @@ public class DecimalFormat extends NumberFormat
useExponentialNotation = false;
groupingUsed = false;
maximumFractionDigits = 0;
- maximumIntegerDigits = 309;
+ maximumIntegerDigits = MAXIMUM_INTEGER_DIGITS;
minimumFractionDigits = 0;
minimumIntegerDigits = 1;
- StringBuffer buf = new StringBuffer ();
+ AttributedFormatBuffer buf = new AttributedFormatBuffer ();
String patChars = patternChars (syms);
int max = pattern.length();
int index = scanFix (pattern, 0, buf, patChars, syms, false);
- positivePrefix = buf.toString();
+ buf.sync();
+ positivePrefix = buf.getBuffer().toString();
+ positivePrefixRanges = buf.getRanges();
+ positivePrefixAttrs = buf.getAttributes();
index = scanFormat (pattern, index, patChars, syms, true);
index = scanFix (pattern, index, buf, patChars, syms, true);
- positiveSuffix = buf.toString();
+ buf.sync();
+ positiveSuffix = buf.getBuffer().toString();
+ positiveSuffixRanges = buf.getRanges();
+ positiveSuffixAttrs = buf.getAttributes();
if (index == pattern.length())
{
@@ -329,14 +365,20 @@ public class DecimalFormat extends NumberFormat
"expected - index: " + index);
index = scanFix (pattern, index + 1, buf, patChars, syms, false);
- negativePrefix = buf.toString();
+ buf.sync();
+ negativePrefix = buf.getBuffer().toString();
+ negativePrefixRanges = buf.getRanges();
+ negativePrefixAttrs = buf.getAttributes();
// We parse the negative format for errors but we don't let
// it side-effect this object.
index = scanFormat (pattern, index, patChars, syms, false);
index = scanFix (pattern, index, buf, patChars, syms, true);
- negativeSuffix = buf.toString();
+ buf.sync();
+ negativeSuffix = buf.getBuffer().toString();
+ negativeSuffixRanges = buf.getRanges();
+ negativeSuffixAttrs = buf.getAttributes();
if (index != pattern.length())
throw new IllegalArgumentException ("end of pattern expected " +
@@ -409,39 +451,43 @@ public class DecimalFormat extends NumberFormat
&& useExponentialNotation == dup.useExponentialNotation);
}
- public StringBuffer format (double number, StringBuffer dest,
- FieldPosition fieldPos)
+ protected void formatInternal (double number, FormatBuffer dest,
+ FieldPosition fieldPos)
{
// A very special case.
if (Double.isNaN(number))
{
dest.append(symbols.getNaN());
- if (fieldPos != null && fieldPos.getField() == INTEGER_FIELD)
+ if (fieldPos != null &&
+ (fieldPos.getField() == INTEGER_FIELD ||
+ fieldPos.getFieldAttribute() == NumberFormat.Field.INTEGER))
{
int index = dest.length();
fieldPos.setBeginIndex(index - symbols.getNaN().length());
fieldPos.setEndIndex(index);
}
- return dest;
+ return;
}
boolean is_neg = number < 0;
if (is_neg)
{
if (negativePrefix != null)
- dest.append(negativePrefix);
+ dest.append(negativePrefix, negativePrefixRanges, negativePrefixAttrs);
else
{
- dest.append(symbols.getMinusSign());
- dest.append(positivePrefix);
+ dest.append(symbols.getMinusSign(), NumberFormat.Field.SIGN);
+ dest.append(positivePrefix, positivePrefixRanges, positivePrefixAttrs);
}
number = - number;
}
else
- dest.append(positivePrefix);
+ dest.append(positivePrefix, positivePrefixRanges, positivePrefixAttrs);
int integerBeginIndex = dest.length();
int integerEndIndex = 0;
+ int zeroStart = symbols.getZeroDigit() - '0';
+
if (Double.isInfinite (number))
{
dest.append(symbols.getInfinity());
@@ -457,6 +503,7 @@ public class DecimalFormat extends NumberFormat
if (useExponentialNotation)
{
exponent = (long) Math.floor (Math.log(number) / Math.log(10));
+ exponent = exponent - (exponent % exponentRound);
if (minimumIntegerDigits > 0)
exponent -= minimumIntegerDigits - 1;
baseNumber = (number / Math.pow(10.0, exponent));
@@ -468,33 +515,57 @@ public class DecimalFormat extends NumberFormat
baseNumber += 5 * Math.pow(10.0, - maximumFractionDigits - 1);
int index = dest.length();
- double intPart = Math.floor(baseNumber);
- int count = 0;
- while (count < maximumIntegerDigits
- && (intPart > 0 || count < minimumIntegerDigits))
+ //double intPart = Math.floor(baseNumber);
+ String intPart = Long.toString((long)Math.floor(baseNumber));
+ int count, groupPosition = intPart.length();
+
+ dest.setDefaultAttribute(NumberFormat.Field.INTEGER);
+
+ for (count = 0; count < minimumIntegerDigits-intPart.length(); count++)
+ dest.append(symbols.getZeroDigit());
+
+ for (count = 0;
+ count < maximumIntegerDigits && count < intPart.length();
+ count++)
{
- long dig = (long) (intPart % 10);
- intPart = Math.floor(intPart / 10);
+ int dig = intPart.charAt(count);
// Append group separator if required.
- if (groupingUsed && count > 0 && groupingSize != 0 && count % groupingSize == 0)
- dest.insert(index, symbols.getGroupingSeparator());
-
- dest.insert(index, (char) (symbols.getZeroDigit() + dig));
+ if (groupingUsed && count > 0 && groupingSize != 0 && groupPosition % groupingSize == 0)
+ {
+ dest.append(symbols.getGroupingSeparator(), NumberFormat.Field.GROUPING_SEPARATOR);
+ dest.setDefaultAttribute(NumberFormat.Field.INTEGER);
+ }
+ dest.append((char) (zeroStart + dig));
- ++count;
+ groupPosition--;
}
+ dest.setDefaultAttribute(null);
integerEndIndex = dest.length();
-
+
int decimal_index = integerEndIndex;
int consecutive_zeros = 0;
int total_digits = 0;
+ int localMaximumFractionDigits = maximumFractionDigits;
+
+ if (useExponentialNotation)
+ localMaximumFractionDigits += minimumIntegerDigits - count;
+
// Strip integer part from NUMBER.
double fracPart = baseNumber - Math.floor(baseNumber);
+
+ if ( ((fracPart != 0 || minimumFractionDigits > 0) && localMaximumFractionDigits > 0)
+ || decimalSeparatorAlwaysShown)
+ {
+ dest.append (symbols.getDecimalSeparator(), NumberFormat.Field.DECIMAL_SEPARATOR);
+ }
+
+ int fraction_begin = dest.length();
+ dest.setDefaultAttribute(NumberFormat.Field.FRACTION);
for (count = 0;
- count < maximumFractionDigits
+ count < localMaximumFractionDigits
&& (fracPart != 0 || count < minimumFractionDigits);
++count)
{
@@ -517,61 +588,88 @@ public class DecimalFormat extends NumberFormat
total_digits - minimumFractionDigits);
if (extra_zeros > 0)
{
- dest.setLength(dest.length() - extra_zeros);
+ dest.cutTail(extra_zeros);
total_digits -= extra_zeros;
+ if (total_digits == 0 && !decimalSeparatorAlwaysShown)
+ dest.cutTail(1);
}
- // If required, add the decimal symbol.
- if (decimalSeparatorAlwaysShown
- || total_digits > 0)
+ if (fieldPos != null && fieldPos.getField() == FRACTION_FIELD)
{
- dest.insert(decimal_index, symbols.getDecimalSeparator());
- if (fieldPos != null && fieldPos.getField() == FRACTION_FIELD)
- {
- fieldPos.setBeginIndex(decimal_index + 1);
- fieldPos.setEndIndex(dest.length());
- }
+ fieldPos.setBeginIndex(fraction_begin);
+ fieldPos.setEndIndex(dest.length());
}
// Finally, print the exponent.
if (useExponentialNotation)
{
- dest.append(symbols.getExponential());
+ dest.append(symbols.getExponential(), NumberFormat.Field.EXPONENT_SYMBOL);
if (exponent < 0)
{
- dest.append (symbols.getMinusSign ());
+ dest.append (symbols.getMinusSign (), NumberFormat.Field.EXPONENT_SIGN);
exponent = - exponent;
}
index = dest.length();
+ dest.setDefaultAttribute(NumberFormat.Field.EXPONENT);
+ String exponentString = Long.toString ((long) exponent);
+
+ for (count = 0; count < minExponentDigits-exponentString.length();
+ count++)
+ dest.append((char) symbols.getZeroDigit());
+
for (count = 0;
- exponent > 0 || count < minExponentDigits;
+ count < exponentString.length();
++count)
{
- long dig = exponent % 10;
- exponent /= 10;
- dest.insert(index, (char) (symbols.getZeroDigit() + dig));
+ int dig = exponentString.charAt(count);
+ dest.append((char) (zeroStart + dig));
}
}
}
- if (fieldPos != null && fieldPos.getField() == INTEGER_FIELD)
+ if (fieldPos != null &&
+ (fieldPos.getField() == INTEGER_FIELD ||
+ fieldPos.getFieldAttribute() == NumberFormat.Field.INTEGER))
{
fieldPos.setBeginIndex(integerBeginIndex);
fieldPos.setEndIndex(integerEndIndex);
}
- dest.append((is_neg && negativeSuffix != null)
- ? negativeSuffix
- : positiveSuffix);
+ if (is_neg && negativeSuffix != null)
+ dest.append(negativeSuffix, negativeSuffixRanges, negativeSuffixAttrs);
+ else
+ dest.append(positiveSuffix, positiveSuffixRanges, positiveSuffixAttrs);
+ }
+
+ public StringBuffer format (double number, StringBuffer dest,
+ FieldPosition fieldPos)
+ {
+ formatInternal (number, new StringFormatBuffer(dest), fieldPos);
return dest;
}
+ public AttributedCharacterIterator formatToCharacterIterator (Object value)
+ {
+ AttributedFormatBuffer sbuf = new AttributedFormatBuffer();
+
+ if (value instanceof Number)
+ formatInternal(((Number) value).doubleValue(), sbuf, null);
+ else
+ throw new IllegalArgumentException
+ ("Cannot format given Object as a Number");
+
+ sbuf.sync();
+ return new FormatCharacterIterator(sbuf.getBuffer().toString(),
+ sbuf.getRanges(),
+ sbuf.getAttributes());
+ }
+
public StringBuffer format (long number, StringBuffer dest,
FieldPosition fieldPos)
{
// If using exponential notation, we just format as a double.
if (useExponentialNotation)
- return format ((double) number, dest, fieldPos);
+ return format ((double) number, dest, fieldPos);
boolean is_neg = number < 0;
if (is_neg)
@@ -701,14 +799,19 @@ public class DecimalFormat extends NumberFormat
public Number parse (String str, ParsePosition pos)
{
- // Our strategy is simple: copy the text into a buffer,
- // translating or omitting locale-specific information. Then
- // let Double or Long convert the number for us.
+ /*
+ * Our strategy is simple: copy the text into separate buffers: one for the int part,
+ * one for the fraction part and for the exponential part.
+ * We translate or omit locale-specific information.
+ * If exponential is sufficiently big we merge the fraction and int part and
+ * remove the '.' and then we use Long to convert the number. In the other
+ * case, we use Double to convert the full number.
+ */
boolean is_neg = false;
int index = pos.getIndex();
- StringBuffer buf = new StringBuffer ();
-
+ StringBuffer int_buf = new StringBuffer ();
+
// We have to check both prefixes, because one might be empty. We
// want to pick the longest prefix that matches.
boolean got_pos = str.startsWith(positivePrefix, index);
@@ -748,11 +851,17 @@ public class DecimalFormat extends NumberFormat
// FIXME: do we have to respect minimum digits?
// What about leading zeros? What about multiplier?
+ StringBuffer buf = int_buf;
+ StringBuffer frac_buf = null;
+ StringBuffer exp_buf = null;
int start_index = index;
int max = str.length();
- int last = index + maximumIntegerDigits;
+ int exp_index = -1;
+ int last = index + MAXIMUM_INTEGER_DIGITS;
+
if (last > 0 && max > last)
max = last;
+
char zero = symbols.getZeroDigit();
int last_group = -1;
boolean int_part = true;
@@ -771,12 +880,11 @@ public class DecimalFormat extends NumberFormat
pos.setErrorIndex(index);
return null;
}
- last_group = index;
+ last_group = index+1;
}
else if (c >= zero && c <= zero + 9)
{
buf.append((char) (c - zero + '0'));
- exp_part = false;
}
else if (parseIntegerOnly)
break;
@@ -789,14 +897,16 @@ public class DecimalFormat extends NumberFormat
pos.setErrorIndex(index);
return null;
}
- buf.append('.');
+ buf = frac_buf = new StringBuffer();
+ frac_buf.append('.');
int_part = false;
}
else if (c == symbols.getExponential())
{
- buf.append('E');
+ buf = exp_buf = new StringBuffer();
int_part = false;
exp_part = true;
+ exp_index = index+1;
}
else if (exp_part
&& (c == '+' || c == '-' || c == symbols.getMinusSign()))
@@ -840,16 +950,111 @@ public class DecimalFormat extends NumberFormat
}
String suffix = is_neg ? ns : positiveSuffix;
+ long multiplier = 1;
+ boolean use_long;
+
if (is_neg)
- buf.insert(0, '-');
+ int_buf.insert(0, '-');
+
+ // Now handle the exponential part if there is one.
+ if (exp_buf != null)
+ {
+ int exponent_value;
+
+ try
+ {
+ exponent_value = Integer.parseInt(exp_buf.toString());
+ }
+ catch (NumberFormatException x1)
+ {
+ pos.setErrorIndex(exp_index);
+ return null;
+ }
- String t = buf.toString();
+ if (frac_buf == null)
+ {
+ // We only have to add some zeros to the int part.
+ // Build a multiplier.
+ for (int i = 0; i < exponent_value; i++)
+ int_buf.append('0');
+
+ use_long = true;
+ }
+ else
+ {
+ boolean long_sufficient;
+
+ if (exponent_value < frac_buf.length()-1)
+ {
+ int lastNonNull = -1;
+ /* We have to check the fraction buffer: it may only be full of '0'
+ * or be sufficiently filled with it to convert the number into Long.
+ */
+ for (int i = 1; i < frac_buf.length(); i++)
+ if (frac_buf.charAt(i) != '0')
+ lastNonNull = i;
+
+ long_sufficient = (lastNonNull < 0 || lastNonNull <= exponent_value);
+ }
+ else
+ long_sufficient = true;
+
+ if (long_sufficient)
+ {
+ for (int i = 1; i < frac_buf.length() && i < exponent_value; i++)
+ int_buf.append(frac_buf.charAt(i));
+ for (int i = frac_buf.length()-1; i < exponent_value; i++)
+ int_buf.append('0');
+ use_long = true;
+ }
+ else
+ {
+ /*
+ * A long type is not sufficient, we build the full buffer to
+ * be parsed by Double.
+ */
+ int_buf.append(frac_buf);
+ int_buf.append('E');
+ int_buf.append(exp_buf);
+ use_long = false;
+ }
+ }
+ }
+ else
+ {
+ if (frac_buf != null)
+ {
+ /* Check whether the fraction buffer contains only '0' */
+ int i;
+ for (i = 1; i < frac_buf.length(); i++)
+ if (frac_buf.charAt(i) != '0')
+ break;
+
+ if (i != frac_buf.length())
+ {
+ use_long = false;
+ int_buf.append(frac_buf);
+ }
+ else
+ use_long = true;
+ }
+ else
+ use_long = true;
+ }
+
+ String t = int_buf.toString();
Number result = null;
- try
+ if (use_long)
{
- result = new Long (t);
+ try
+ {
+ result = new Long (t);
+ }
+ catch (NumberFormatException x1)
+ {
+ }
}
- catch (NumberFormatException x1)
+ else
{
try
{
@@ -964,7 +1169,7 @@ public class DecimalFormat extends NumberFormat
// digits. Past that we need hash marks up to the grouping
// separator (and one beyond).
int total_digits = Math.max(minimumIntegerDigits,
- groupingUsed ? groupingSize + 1: 0);
+ groupingUsed ? groupingSize + 1: groupingSize);
for (int i = 0; i < total_digits - minimumIntegerDigits; ++i)
mainPattern.append(syms.getDigit());
for (int i = total_digits - minimumIntegerDigits; i < total_digits; ++i)
@@ -1018,15 +1223,22 @@ public class DecimalFormat extends NumberFormat
return computePattern (nonLocalizedSymbols);
}
+ private static final int MAXIMUM_INTEGER_DIGITS = 309;
+
// These names are fixed by the serialization spec.
private boolean decimalSeparatorAlwaysShown;
private byte groupingSize;
private byte minExponentDigits;
+ private int exponentRound;
private int multiplier;
private String negativePrefix;
private String negativeSuffix;
private String positivePrefix;
private String positiveSuffix;
+ private int[] negativePrefixRanges, positivePrefixRanges;
+ private HashMap[] negativePrefixAttrs, positivePrefixAttrs;
+ private int[] negativeSuffixRanges, positiveSuffixRanges;
+ private HashMap[] negativeSuffixAttrs, positiveSuffixAttrs;
private int serialVersionOnStream = 1;
private DecimalFormatSymbols symbols;
private boolean useExponentialNotation;
diff --git a/libjava/java/text/DecimalFormatSymbols.java b/libjava/java/text/DecimalFormatSymbols.java
index 268fe2cf987..843b6020b3a 100644
--- a/libjava/java/text/DecimalFormatSymbols.java
+++ b/libjava/java/text/DecimalFormatSymbols.java
@@ -1,5 +1,5 @@
/* DecimalFormatSymbols.java -- Format symbols used by DecimalFormat
- Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,13 +38,13 @@ exception statement from your version. */
package java.text;
+import java.io.IOException;
+import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Currency;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
-import java.io.ObjectInputStream;
-import java.io.IOException;
/**
* This class is a container for the symbols used by
@@ -167,9 +167,9 @@ public final class DecimalFormatSymbols implements Cloneable, Serializable
* regard to the specified object:
* <p>
* <ul>
- * <li>It is not <code>null</code>.
- * <li>It is an instance of <code>DecimalFormatSymbols</code>
- * <li>All of its symbols are identical to the symbols in this object.
+ * <li>It is not <code>null</code>.</li>
+ * <li>It is an instance of <code>DecimalFormatSymbols</code>.</li>
+ * <li>All of its symbols are identical to the symbols in this object.</li>
* </ul>
*
* @return <code>true</code> if the specified object is equal to this
diff --git a/libjava/java/text/FieldPosition.java b/libjava/java/text/FieldPosition.java
index 74f806a2fbb..47cf7a146f4 100644
--- a/libjava/java/text/FieldPosition.java
+++ b/libjava/java/text/FieldPosition.java
@@ -72,13 +72,13 @@ public class FieldPosition
/**
* This method initializes a new instance of <code>FieldPosition</code>
* to have the specified field attribute. The attribute will be used as
- * an id.
+ * an id. It is formally equivalent to calling FieldPosition(field, -1).
*
* @param field The field format attribute.
*/
public FieldPosition (Format.Field field)
{
- this.field_attribute = field;
+ this(field, -1);
}
/**
diff --git a/libjava/java/text/Format.java b/libjava/java/text/Format.java
index f64951bb94c..7bc389eb71e 100644
--- a/libjava/java/text/Format.java
+++ b/libjava/java/text/Format.java
@@ -38,10 +38,7 @@ exception statement from your version. */
package java.text;
-import java.util.Set;
-import java.util.Map;
-import java.util.HashSet;
-import java.util.HashMap;
+import gnu.java.text.FormatCharacterIterator;
import java.io.Serializable;
/**
@@ -123,7 +120,7 @@ public abstract class Format implements Serializable, Cloneable
* This method parses a <code>String</code> and converts the parsed
* contents into an <code>Object</code>.
*
- * @param str The <code>String to parse.
+ * @param str The <code>String</code> to parse.
*
* @return The resulting <code>Object</code>.
*
diff --git a/libjava/java/text/MessageFormat.java b/libjava/java/text/MessageFormat.java
index 7bb7760c90e..2e1786da986 100644
--- a/libjava/java/text/MessageFormat.java
+++ b/libjava/java/text/MessageFormat.java
@@ -38,7 +38,11 @@ exception statement from your version. */
package java.text;
+import gnu.java.text.FormatCharacterIterator;
+
+import java.io.InvalidObjectException;
import java.util.Date;
+import java.util.HashMap;
import java.util.Locale;
import java.util.Vector;
@@ -145,6 +149,43 @@ public class MessageFormat extends Format
{
private static final long serialVersionUID = 6479157306784022952L;
+ public static class Field extends Format.Field
+ {
+ static final long serialVersionUID = 7899943957617360810L;
+
+ /**
+ * This is the attribute set for all characters produced
+ * by MessageFormat during a formatting.
+ */
+ public static final MessageFormat.Field ARGUMENT = new Field("argument");
+
+ // For deserialization
+ private Field()
+ {
+ super("");
+ }
+
+ private Field(String s)
+ {
+ super(s);
+ }
+
+ /**
+ * invoked to resolve the true static constant by
+ * comparing the deserialized object to know name.
+ *
+ * @return object constant
+ */
+ protected Object readResolve() throws InvalidObjectException
+ {
+ if (getName().equals(ARGUMENT.getName()))
+ return ARGUMENT;
+
+ throw new InvalidObjectException("no such MessageFormat field called " + getName());
+ }
+
+ }
+
// Helper that returns the text up to the next format opener. The
// text is put into BUFFER. Returns index of character after end of
// string. Throws IllegalArgumentException on error.
@@ -326,12 +367,28 @@ public class MessageFormat extends Format
* @param aPattern The pattern used when formatting.
* @param arguments The array containing the objects to be formatted.
*/
+ public AttributedCharacterIterator formatToCharacterIterator (Object arguments)
+ {
+ Object[] arguments_array = (Object[])arguments;
+ FormatCharacterIterator iterator = new FormatCharacterIterator();
+
+ formatInternal(arguments_array, new StringBuffer(), null, iterator);
+
+ return iterator;
+ }
+
+ /**
+ * A convinience method to format patterns.
+ *
+ * @param aPattern The pattern used when formatting.
+ * @param arguments The array containing the objects to be formatted.
+ */
public static String format (String pattern, Object arguments[])
{
MessageFormat mf = new MessageFormat (pattern);
StringBuffer sb = new StringBuffer ();
FieldPosition fp = new FieldPosition (NumberFormat.INTEGER_FIELD);
- return mf.format(arguments, sb, fp).toString();
+ return mf.formatInternal(arguments, sb, fp, null).toString();
}
/**
@@ -342,9 +399,18 @@ public class MessageFormat extends Format
* @param fp A FieldPosition object (it is ignored).
*/
public final StringBuffer format (Object arguments[], StringBuffer appendBuf,
- FieldPosition ignore)
+ FieldPosition fp)
+ {
+ return formatInternal(arguments, appendBuf, fp, null);
+ }
+
+ protected final StringBuffer formatInternal (Object arguments[], StringBuffer appendBuf,
+ FieldPosition fp,
+ FormatCharacterIterator output_iterator)
{
appendBuf.append(leader);
+ if (output_iterator != null)
+ output_iterator.append(leader);
for (int i = 0; i < elements.length; ++i)
{
@@ -352,8 +418,13 @@ public class MessageFormat extends Format
throw new IllegalArgumentException("Not enough arguments given");
Object thisArg = arguments[elements[i].argNumber];
+ AttributedCharacterIterator iterator = null;
Format formatter = null;
+
+ if (fp != null && i == fp.getField() && fp.getFieldAttribute() == Field.ARGUMENT)
+ fp.setBeginIndex(appendBuf.length());
+
if (elements[i].setFormat != null)
formatter = elements[i].setFormat;
else if (elements[i].format != null)
@@ -371,25 +442,56 @@ public class MessageFormat extends Format
else
appendBuf.append(thisArg);
+ if (fp != null && fp.getField() == i && fp.getFieldAttribute() == Field.ARGUMENT)
+ fp.setEndIndex(appendBuf.length());
+
if (formatter != null)
{
// Special-case ChoiceFormat.
if (formatter instanceof ChoiceFormat)
{
StringBuffer buf = new StringBuffer ();
- formatter.format(thisArg, buf, ignore);
+ formatter.format(thisArg, buf, fp);
MessageFormat mf = new MessageFormat ();
mf.setLocale(locale);
mf.applyPattern(buf.toString());
- mf.format(arguments, appendBuf, ignore);
+ mf.format(arguments, appendBuf, fp);
}
else
- formatter.format(thisArg, appendBuf, ignore);
+ {
+ if (output_iterator != null)
+ iterator = formatter.formatToCharacterIterator(thisArg);
+ else
+ formatter.format(thisArg, appendBuf, fp);
+ }
+
+ elements[i].format = formatter;
}
+ if (output_iterator != null)
+ {
+ HashMap hash_argument = new HashMap();
+ int position = output_iterator.getEndIndex();
+
+ hash_argument.put (MessageFormat.Field.ARGUMENT,
+ new Integer(elements[i].argNumber));
+
+
+ if (iterator != null)
+ {
+ output_iterator.append(iterator);
+ output_iterator.addAttributes(hash_argument, position,
+ output_iterator.getEndIndex());
+ }
+ else
+ output_iterator.append(thisArg.toString(), hash_argument);
+
+ output_iterator.append(elements[i].trailer);
+ }
+
appendBuf.append(elements[i].trailer);
}
-
+
return appendBuf;
}
@@ -398,10 +500,10 @@ public class MessageFormat extends Format
*
* @param source The object to be formatted.
* @param result The StringBuffer where the text is appened.
- * @param fp A FieldPosition object (it is ignored).
+ * @param fpos A FieldPosition object (it is ignored).
*/
public final StringBuffer format (Object singleArg, StringBuffer appendBuf,
- FieldPosition ignore)
+ FieldPosition fpos)
{
Object[] args;
@@ -416,7 +518,7 @@ public class MessageFormat extends Format
args = new Object[1];
args[0] = singleArg;
}
- return format (args, appendBuf, ignore);
+ return format (args, appendBuf, fpos);
}
/**
@@ -478,6 +580,15 @@ public class MessageFormat extends Format
applyPattern (pattern);
}
+ /**
+ * Parse a string <code>sourceStr</code> against the pattern specified
+ * to the MessageFormat constructor.
+ *
+ * @param sourceStr the string to be parsed.
+ * @param pos the current parse position (and eventually the error position).
+ * @return the array of parsed objects sorted according to their argument number
+ * in the pattern.
+ */
public Object[] parse (String sourceStr, ParsePosition pos)
{
// Check initial text.
@@ -628,6 +739,72 @@ public class MessageFormat extends Format
return pattern;
}
+ /**
+ * Return the formatters used sorted by argument index. It uses the
+ * internal table to fill in this array: if a format has been
+ * set using <code>setFormat</code> or <code>setFormatByArgumentIndex</code>
+ * then it returns it at the right index. If not it uses the detected
+ * formatters during a <code>format</code> call. If nothing is known
+ * about that argument index it just puts null at that position.
+ * To get useful informations you may have to call <code>format</code>
+ * at least once.
+ *
+ * @return an array of formatters sorted by argument index.
+ */
+ public Format[] getFormatsByArgumentIndex()
+ {
+ int argNumMax = 0;
+ // First, find the greatest argument number.
+ for (int i=0;i<elements.length;i++)
+ if (elements[i].argNumber > argNumMax)
+ argNumMax = elements[i].argNumber;
+
+ Format[] formats = new Format[argNumMax];
+ for (int i=0;i<elements.length;i++)
+ {
+ if (elements[i].setFormat != null)
+ formats[elements[i].argNumber] = elements[i].setFormat;
+ else if (elements[i].format != null)
+ formats[elements[i].argNumber] = elements[i].format;
+ }
+ return formats;
+ }
+
+ /**
+ * Set the format to used using the argument index number.
+ *
+ * @param argumentIndex the argument index.
+ * @param newFormat the format to use for this argument.
+ */
+ public void setFormatByArgumentIndex(int argumentIndex,
+ Format newFormat)
+ {
+ for (int i=0;i<elements.length;i++)
+ {
+ if (elements[i].argNumber == argumentIndex)
+ elements[i].setFormat = newFormat;
+ }
+ }
+
+ /**
+ * Set the format for argument using a specified array of formatters
+ * which is sorted according to the argument index. If the number of
+ * elements in the array is fewer than the number of arguments only
+ * the arguments specified by the array are touched.
+ *
+ * @param newFormats array containing the new formats to set.
+ *
+ * @throws NullPointerException if newFormats is null
+ */
+ public void setFormatsByArgumentIndex(Format[] newFormats)
+ {
+ for (int i=0;i<newFormats.length;i++)
+ {
+ // Nothing better than that can exist here.
+ setFormatByArgumentIndex(i, newFormats[i]);
+ }
+ }
+
// The pattern string.
private String pattern;
// The locale.
diff --git a/libjava/java/text/NumberFormat.java b/libjava/java/text/NumberFormat.java
index 42372908e39..6520f7524e0 100644
--- a/libjava/java/text/NumberFormat.java
+++ b/libjava/java/text/NumberFormat.java
@@ -38,8 +38,8 @@ exception statement from your version. */
package java.text;
-import java.io.InvalidObjectException;
import java.io.IOException;
+import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Currency;
diff --git a/libjava/java/text/ParsePosition.java b/libjava/java/text/ParsePosition.java
index 83e92689fd5..c6dffed8f59 100644
--- a/libjava/java/text/ParsePosition.java
+++ b/libjava/java/text/ParsePosition.java
@@ -116,10 +116,10 @@ public class ParsePosition
* all of the following conditions are met.
* <p>
* <ul>
- * <li>The specified object is not <code>null</code>.
- * <li>The specified object is an instance of <code>ParsePosition</code>.
+ * <li>The specified object is not <code>null</code>.</li>
+ * <li>The specified object is an instance of <code>ParsePosition</code>.</li>
* <li>The specified object has the same index and error index as
- * this object.
+ * this object.</li>
* </ul>
*
* @param obj The <code>Object</code> to test for equality against
diff --git a/libjava/java/text/RuleBasedCollator.java b/libjava/java/text/RuleBasedCollator.java
index 5b1dc0cfbed..64c2ac231f7 100644
--- a/libjava/java/text/RuleBasedCollator.java
+++ b/libjava/java/text/RuleBasedCollator.java
@@ -1,5 +1,5 @@
/* RuleBasedCollator.java -- Concrete Collator Class
- Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -56,9 +56,9 @@ import java.util.Vector;
* <p>
* Rules take the form of a <code>String</code> with the following syntax
* <ul>
- * <li> Modifier: '@'
- * <li> Relation: '&lt;' | ';' | ',' | '=' : <text>
- * <li> Reset: '&amp;' : <text>
+ * <li> Modifier: '@'</li>
+ * <li> Relation: '&lt;' | ';' | ',' | '=' : &lt;text&gt;</li>
+ * <li> Reset: '&amp;' : &lt;text&gt;</li>
* </ul>
* The modifier character indicates that accents sort backward as is the
* case with French. The modifier applies to all rules <b>after</b>
@@ -69,12 +69,12 @@ import java.util.Vector;
* the following meanings:
* <ul>
* <li>'&lt;' - The text argument is greater than the prior term at the primary
- * difference level.
+ * difference level.</li>
* <li>';' - The text argument is greater than the prior term at the secondary
- * difference level.
+ * difference level.</li>
* <li>',' - The text argument is greater than the prior term at the tertiary
- * difference level.
- * <li>'=' - The text argument is equal to the prior term
+ * difference level.</li>
+ * <li>'=' - The text argument is equal to the prior term</li>
* </ul>
* <p>
* As for the text argument itself, this is any sequence of Unicode
@@ -131,15 +131,15 @@ import java.util.Vector;
* A <code>ParseException</code> will be thrown for any of the following
* conditions:
* <ul>
- * <li>Unquoted punctuation characters in a text argument.
- * <li>A relational or reset operator not followed by a text argument
+ * <li>Unquoted punctuation characters in a text argument.</li>
+ * <li>A relational or reset operator not followed by a text argument</li>
* <li>A reset operator where the text argument is not present in
- * the previous rule string section.
+ * the previous rule string section.</li>
* </ul>
*
- * @author Aaron M. Renn <arenn@urbanophile.com>
- * @author Tom Tromey <tromey@cygnus.com>
- * @author Guilhem Lavaux <guilhem@kaffe.org>
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @author Guilhem Lavaux (guilhem@kaffe.org)
*/
public class RuleBasedCollator extends Collator
{
diff --git a/libjava/java/text/SimpleDateFormat.java b/libjava/java/text/SimpleDateFormat.java
index 89f84dde5c6..5f3614eefcf 100644
--- a/libjava/java/text/SimpleDateFormat.java
+++ b/libjava/java/text/SimpleDateFormat.java
@@ -39,16 +39,21 @@ exception statement from your version. */
package java.text;
+import gnu.java.text.AttributedFormatBuffer;
+import gnu.java.text.FormatBuffer;
+import gnu.java.text.FormatCharacterIterator;
+import gnu.java.text.StringFormatBuffer;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.Locale;
-import java.util.TimeZone;
import java.util.SimpleTimeZone;
-import java.io.ObjectInputStream;
-import java.io.IOException;
+import java.util.TimeZone;
/**
* SimpleDateFormat provides convenient methods for parsing and formatting
@@ -82,7 +87,7 @@ public class SimpleDateFormat extends DateFormat
// This string is specified in the JCL. We set it here rather than
// do a DateFormatSymbols(Locale.US).getLocalPatternChars() since
// someone could theoretically change those values (though unlikely).
- private static final String standardChars = "GyMdkHmsSEDFwWahKz";
+ private static final String standardChars = "GyMdkHmsSEDFwWahKzZ";
private void readObject(ObjectInputStream stream)
throws IOException, ClassNotFoundException
@@ -358,13 +363,13 @@ public class SimpleDateFormat extends DateFormat
* object. This will be true if and only if the specified object:
* <p>
* <ul>
- * <li>Is not <code>null</code>.
- * <li>Is an instance of <code>SimpleDateFormat</code>.
+ * <li>Is not <code>null</code>.</li>
+ * <li>Is an instance of <code>SimpleDateFormat</code>.</li>
* <li>Is equal to this object at the superclass (i.e., <code>DateFormat</code>)
- * level.
- * <li>Has the same formatting pattern.
- * <li>Is using the same formatting symbols.
- * <li>Is using the same century for two digit years.
+ * level.</li>
+ * <li>Has the same formatting pattern.</li>
+ * <li>Is using the same formatting symbols.</li>
+ * <li>Is using the same century for two digit years.</li>
* </ul>
*
* @param obj The object to compare for equality against.
@@ -411,109 +416,164 @@ public class SimpleDateFormat extends DateFormat
* appending to the specified StringBuffer. The input StringBuffer
* is returned as output for convenience.
*/
- public StringBuffer format(Date date, StringBuffer buffer, FieldPosition pos)
+ final private void formatWithAttribute(Date date, FormatBuffer buffer, FieldPosition pos)
{
String temp;
+ AttributedCharacterIterator.Attribute attribute;
calendar.setTime(date);
-
- // go through ArrayList, filling in fields where applicable, else toString
- Iterator i = tokens.iterator();
- while (i.hasNext()) {
- Object o = i.next();
- if (o instanceof FieldSizePair) {
- FieldSizePair p = (FieldSizePair) o;
- int beginIndex = buffer.length();
- switch (p.field) {
- case ERA_FIELD:
- buffer.append(formatData.eras[calendar.get(Calendar.ERA)]);
- break;
- case YEAR_FIELD:
- // If we have two digits, then we truncate. Otherwise, we
- // use the size of the pattern, and zero pad.
- if (p.size == 2)
- {
- temp = String.valueOf(calendar.get(Calendar.YEAR));
- buffer.append(temp.substring(temp.length() - 2));
- }
- else
- withLeadingZeros(calendar.get(Calendar.YEAR), p.size, buffer);
- break;
- case MONTH_FIELD:
- if (p.size < 3)
- withLeadingZeros(calendar.get(Calendar.MONTH)+1,p.size,buffer);
- else if (p.size < 4)
- buffer.append(formatData.shortMonths[calendar.get(Calendar.MONTH)]);
- else
- buffer.append(formatData.months[calendar.get(Calendar.MONTH)]);
- break;
- case DATE_FIELD:
- withLeadingZeros(calendar.get(Calendar.DATE),p.size,buffer);
- break;
- case HOUR_OF_DAY1_FIELD: // 1-24
- withLeadingZeros(((calendar.get(Calendar.HOUR_OF_DAY)+23)%24)+1,p.size,buffer);
- break;
- case HOUR_OF_DAY0_FIELD: // 0-23
- withLeadingZeros(calendar.get(Calendar.HOUR_OF_DAY),p.size,buffer);
- break;
- case MINUTE_FIELD:
- withLeadingZeros(calendar.get(Calendar.MINUTE),p.size,buffer);
- break;
- case SECOND_FIELD:
- withLeadingZeros(calendar.get(Calendar.SECOND),p.size,buffer);
- break;
- case MILLISECOND_FIELD:
- withLeadingZeros(calendar.get(Calendar.MILLISECOND),p.size,buffer);
- break;
- case DAY_OF_WEEK_FIELD:
- if (p.size < 4)
- buffer.append(formatData.shortWeekdays[calendar.get(Calendar.DAY_OF_WEEK)]);
- else
- buffer.append(formatData.weekdays[calendar.get(Calendar.DAY_OF_WEEK)]);
- break;
- case DAY_OF_YEAR_FIELD:
- withLeadingZeros(calendar.get(Calendar.DAY_OF_YEAR),p.size,buffer);
- break;
- case DAY_OF_WEEK_IN_MONTH_FIELD:
- withLeadingZeros(calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH),p.size,buffer);
- break;
- case WEEK_OF_YEAR_FIELD:
- withLeadingZeros(calendar.get(Calendar.WEEK_OF_YEAR),p.size,buffer);
- break;
- case WEEK_OF_MONTH_FIELD:
- withLeadingZeros(calendar.get(Calendar.WEEK_OF_MONTH),p.size,buffer);
- break;
- case AM_PM_FIELD:
- buffer.append(formatData.ampms[calendar.get(Calendar.AM_PM)]);
- break;
- case HOUR1_FIELD: // 1-12
- withLeadingZeros(((calendar.get(Calendar.HOUR)+11)%12)+1,p.size,buffer);
- break;
- case HOUR0_FIELD: // 0-11
- withLeadingZeros(calendar.get(Calendar.HOUR),p.size,buffer);
- break;
- case TIMEZONE_FIELD:
- TimeZone zone = calendar.getTimeZone();
- boolean isDST = calendar.get(Calendar.DST_OFFSET) != 0;
- // FIXME: XXX: This should be a localized time zone.
- String zoneID = zone.getDisplayName(isDST, p.size > 3 ? TimeZone.LONG : TimeZone.SHORT);
- buffer.append(zoneID);
- break;
- default:
- throw new IllegalArgumentException("Illegal pattern character");
- }
- if (pos != null && p.field == pos.getField())
+
+ // go through vector, filling in fields where applicable, else toString
+ Iterator iter = tokens.iterator();
+ while (iter.hasNext())
+ {
+ Object o = iter.next();
+ if (o instanceof FieldSizePair)
{
- pos.setBeginIndex(beginIndex);
- pos.setEndIndex(buffer.length());
- }
- } else {
- buffer.append(o.toString());
+ FieldSizePair p = (FieldSizePair) o;
+ int beginIndex = buffer.length();
+
+ switch (p.field)
+ {
+ case ERA_FIELD:
+ buffer.append (formatData.eras[calendar.get (Calendar.ERA)], DateFormat.Field.ERA);
+ break;
+ case YEAR_FIELD:
+ // If we have two digits, then we truncate. Otherwise, we
+ // use the size of the pattern, and zero pad.
+ buffer.setDefaultAttribute (DateFormat.Field.YEAR);
+ if (p.size == 2)
+ {
+ temp = String.valueOf (calendar.get (Calendar.YEAR));
+ buffer.append (temp.substring (temp.length() - 2));
+ }
+ else
+ withLeadingZeros (calendar.get (Calendar.YEAR), p.size, buffer);
+ break;
+ case MONTH_FIELD:
+ buffer.setDefaultAttribute (DateFormat.Field.MONTH);
+ if (p.size < 3)
+ withLeadingZeros (calendar.get (Calendar.MONTH) + 1, p.size, buffer);
+ else if (p.size < 4)
+ buffer.append (formatData.shortMonths[calendar.get (Calendar.MONTH)]);
+ else
+ buffer.append (formatData.months[calendar.get (Calendar.MONTH)]);
+ break;
+ case DATE_FIELD:
+ buffer.setDefaultAttribute (DateFormat.Field.DAY_OF_MONTH);
+ withLeadingZeros (calendar.get (Calendar.DATE), p.size, buffer);
+ break;
+ case HOUR_OF_DAY1_FIELD: // 1-24
+ buffer.setDefaultAttribute(DateFormat.Field.HOUR_OF_DAY1);
+ withLeadingZeros ( ((calendar.get (Calendar.HOUR_OF_DAY) + 23) % 24) + 1,
+ p.size, buffer);
+ break;
+ case HOUR_OF_DAY0_FIELD: // 0-23
+ buffer.setDefaultAttribute (DateFormat.Field.HOUR_OF_DAY0);
+ withLeadingZeros (calendar.get (Calendar.HOUR_OF_DAY), p.size, buffer);
+ break;
+ case MINUTE_FIELD:
+ buffer.setDefaultAttribute (DateFormat.Field.MINUTE);
+ withLeadingZeros (calendar.get (Calendar.MINUTE),
+ p.size, buffer);
+ break;
+ case SECOND_FIELD:
+ buffer.setDefaultAttribute (DateFormat.Field.SECOND);
+ withLeadingZeros(calendar.get (Calendar.SECOND),
+ p.size, buffer);
+ break;
+ case MILLISECOND_FIELD:
+ buffer.setDefaultAttribute (DateFormat.Field.MILLISECOND);
+ withLeadingZeros (calendar.get (Calendar.MILLISECOND), p.size, buffer);
+ break;
+ case DAY_OF_WEEK_FIELD:
+ buffer.setDefaultAttribute (DateFormat.Field.DAY_OF_WEEK);
+ if (p.size < 4)
+ buffer.append (formatData.shortWeekdays[calendar.get (Calendar.DAY_OF_WEEK)]);
+ else
+ buffer.append (formatData.weekdays[calendar.get (Calendar.DAY_OF_WEEK)]);
+ break;
+ case DAY_OF_YEAR_FIELD:
+ buffer.setDefaultAttribute (DateFormat.Field.DAY_OF_YEAR);
+ withLeadingZeros (calendar.get (Calendar.DAY_OF_YEAR), p.size, buffer);
+ break;
+ case DAY_OF_WEEK_IN_MONTH_FIELD:
+ buffer.setDefaultAttribute (DateFormat.Field.DAY_OF_WEEK_IN_MONTH);
+ withLeadingZeros (calendar.get (Calendar.DAY_OF_WEEK_IN_MONTH),
+ p.size, buffer);
+ break;
+ case WEEK_OF_YEAR_FIELD:
+ buffer.setDefaultAttribute (DateFormat.Field.WEEK_OF_YEAR);
+ withLeadingZeros (calendar.get (Calendar.WEEK_OF_YEAR),
+ p.size, buffer);
+ break;
+ case WEEK_OF_MONTH_FIELD:
+ buffer.setDefaultAttribute (DateFormat.Field.WEEK_OF_MONTH);
+ withLeadingZeros (calendar.get (Calendar.WEEK_OF_MONTH),
+ p.size, buffer);
+ break;
+ case AM_PM_FIELD:
+ buffer.setDefaultAttribute (DateFormat.Field.AM_PM);
+ buffer.append (formatData.ampms[calendar.get (Calendar.AM_PM)]);
+ break;
+ case HOUR1_FIELD: // 1-12
+ buffer.setDefaultAttribute (DateFormat.Field.HOUR1);
+ withLeadingZeros (((calendar.get (Calendar.HOUR) + 11) % 12) + 1, p.size, buffer);
+ break;
+ case HOUR0_FIELD: // 0-11
+ buffer.setDefaultAttribute (DateFormat.Field.HOUR0);
+ withLeadingZeros (calendar.get (Calendar.HOUR), p.size, buffer);
+ break;
+ case TIMEZONE_FIELD:
+ buffer.setDefaultAttribute (DateFormat.Field.TIME_ZONE);
+ TimeZone zone = calendar.getTimeZone();
+ boolean isDST = calendar.get (Calendar.DST_OFFSET) != 0;
+ // FIXME: XXX: This should be a localized time zone.
+ String zoneID = zone.getDisplayName (isDST, p.size > 3 ? TimeZone.LONG : TimeZone.SHORT);
+ buffer.append (zoneID);
+ break;
+ default:
+ throw new IllegalArgumentException ("Illegal pattern character " + p.field);
+ }
+ if (pos != null && (buffer.getDefaultAttribute() == pos.getFieldAttribute()
+ || p.field == pos.getField()))
+ {
+ pos.setBeginIndex(beginIndex);
+ pos.setEndIndex(buffer.length());
+ }
+ }
+ else
+ {
+ buffer.append(o.toString(), null);
+ }
}
- }
+ }
+
+ public StringBuffer format(Date date, StringBuffer buffer, FieldPosition pos)
+ {
+ formatWithAttribute(date, new StringFormatBuffer (buffer), pos);
+
return buffer;
}
- private void withLeadingZeros(int value, int length, StringBuffer buffer)
+ public AttributedCharacterIterator formatToCharacterIterator(Object date)
+ throws IllegalArgumentException
+ {
+ if (date == null)
+ throw new NullPointerException("null argument");
+ if (!(date instanceof Date))
+ throw new IllegalArgumentException("argument should be an instance of java.util.Date");
+
+ AttributedFormatBuffer buf = new AttributedFormatBuffer();
+ formatWithAttribute((Date)date, buf,
+ null);
+ buf.sync();
+
+ return new FormatCharacterIterator(buf.getBuffer().toString(),
+ buf.getRanges(),
+ buf.getAttributes());
+ }
+
+ private void withLeadingZeros(int value, int length, FormatBuffer buffer)
{
String valStr = String.valueOf(value);
for (length -= valStr.length(); length > 0; length--)
diff --git a/libjava/java/text/StringCharacterIterator.java b/libjava/java/text/StringCharacterIterator.java
index 7b7f46e7f59..44bac6b74a3 100644
--- a/libjava/java/text/StringCharacterIterator.java
+++ b/libjava/java/text/StringCharacterIterator.java
@@ -314,10 +314,10 @@ public final class StringCharacterIterator implements CharacterIterator
* object. This will be true if and only if the specified object:
* <p>
* <ul>
- * <li>is not <code>null</code>.
- * <li>is an instance of <code>StringCharacterIterator</code>
- * <li>has the same text as this object
- * <li>has the same beginning, ending, and current index as this object.
+ * <li>is not <code>null</code>.</li>
+ * <li>is an instance of <code>StringCharacterIterator</code></li>
+ * <li>has the same text as this object</li>
+ * <li>has the same beginning, ending, and current index as this object.</li>
* </ul>
*
* @param obj The object to test for equality against.
diff --git a/libjava/java/util/ArrayList.java b/libjava/java/util/ArrayList.java
index c6f6b86991d..a451f1e4c4a 100644
--- a/libjava/java/util/ArrayList.java
+++ b/libjava/java/util/ArrayList.java
@@ -1,6 +1,6 @@
/* ArrayList.java -- JDK1.2's answer to Vector; this is an array-backed
implementation of the List interface
- Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,11 +39,11 @@ exception statement from your version. */
package java.util;
-import java.lang.reflect.Array;
-import java.io.Serializable;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.reflect.Array;
/**
* An array-backed implementation of the List interface. This implements
diff --git a/libjava/java/util/Arrays.java b/libjava/java/util/Arrays.java
index 080b4b9cbf9..cc32d153900 100644
--- a/libjava/java/util/Arrays.java
+++ b/libjava/java/util/Arrays.java
@@ -2400,7 +2400,7 @@ public class Arrays
{
int size = a.length;
for (int i = 0; i < size; i++)
- if (this.equals(o, a[i]))
+ if (ArrayList.equals(o, a[i]))
return i;
return -1;
}
@@ -2409,7 +2409,7 @@ public class Arrays
{
int i = a.length;
while (--i >= 0)
- if (this.equals(o, a[i]))
+ if (ArrayList.equals(o, a[i]))
return i;
return -1;
}
diff --git a/libjava/java/util/Calendar.java b/libjava/java/util/Calendar.java
index 48624beb614..11b0aacf940 100644
--- a/libjava/java/util/Calendar.java
+++ b/libjava/java/util/Calendar.java
@@ -1,5 +1,5 @@
/* java.util.Calendar
- Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,11 +38,11 @@ exception statement from your version. */
package java.util;
-import java.lang.reflect.InvocationTargetException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
/**
* This class is an abstract base class for Calendars, which can be
@@ -926,8 +926,21 @@ public abstract class Calendar implements Serializable, Cloneable
* @return the actual minimum value.
* @since jdk1.2
*/
- // FIXME: XXX: Not abstract in JDK 1.2.
- public abstract int getActualMinimum(int field);
+ public int getActualMinimum(int field)
+ {
+ Calendar tmp = (Calendar)clone(); // To avoid restoring state
+ int min = tmp.getGreatestMinimum(field);
+ int end = tmp.getMinimum(field);
+ tmp.set(field, min);
+ for (; min > end; min--)
+ {
+ tmp.add(field, -1); // Try to get smaller
+ if (tmp.get(field) != min - 1)
+ break; // Done if not successful
+
+ }
+ return min;
+ }
/**
* Gets the actual maximum value that is allowed for the specified field.
@@ -936,8 +949,20 @@ public abstract class Calendar implements Serializable, Cloneable
* @return the actual maximum value.
* @since jdk1.2
*/
- // FIXME: XXX: Not abstract in JDK 1.2.
- public abstract int getActualMaximum(int field);
+ public int getActualMaximum(int field)
+ {
+ Calendar tmp = (Calendar)clone(); // To avoid restoring state
+ int max = tmp.getLeastMaximum(field);
+ int end = tmp.getMaximum(field);
+ tmp.set(field, max);
+ for (; max < end; max++)
+ {
+ tmp.add(field, 1);
+ if (tmp.get(field) != max + 1)
+ break;
+ }
+ return max;
+ }
/**
* Return a clone of this object.
diff --git a/libjava/java/util/Collections.java b/libjava/java/util/Collections.java
index 815afccc807..7e5ac6ec2c1 100644
--- a/libjava/java/util/Collections.java
+++ b/libjava/java/util/Collections.java
@@ -54,7 +54,7 @@ import java.io.Serializable;
* are not required, to throw the {@link UnsupportedOperationException} that
* the underlying collection would throw during an attempt at modification.
* For example,
- * <code>Collections.singleton("").addAll(Collections.EMPTY_SET)<code>
+ * <code>Collections.singleton("").addAll(Collections.EMPTY_SET)</code>
* does not throw a exception, even though addAll is an unsupported operation
* on a singleton; the reason for this is that addAll did not attempt to
* modify the set.
diff --git a/libjava/java/util/Currency.java b/libjava/java/util/Currency.java
index a742831e4c3..fa98927377b 100644
--- a/libjava/java/util/Currency.java
+++ b/libjava/java/util/Currency.java
@@ -1,5 +1,5 @@
/* Currency.java -- Representation of a currency
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,8 +37,6 @@ exception statement from your version. */
package java.util;
import java.io.Serializable;
-import java.util.ResourceBundle;
-import java.util.Locale;
import java.text.NumberFormat;
public final class Currency implements Serializable
diff --git a/libjava/java/util/Date.java b/libjava/java/util/Date.java
index c25b503dcde..43ae9699082 100644
--- a/libjava/java/util/Date.java
+++ b/libjava/java/util/Date.java
@@ -460,7 +460,6 @@ public class Date implements Cloneable, Comparable, java.io.Serializable
int curYear = 1900 + new Date().getYear();
int firstYear = curYear - 80;
year = firstYear / 100 * 100 + num;
- int yx = year;
if (year < firstYear)
year += 100;
}
diff --git a/libjava/java/util/HashMap.java b/libjava/java/util/HashMap.java
index fd6b658bcb7..fe4c8b06022 100644
--- a/libjava/java/util/HashMap.java
+++ b/libjava/java/util/HashMap.java
@@ -1,6 +1,6 @@
/* HashMap.java -- a class providing a basic hashtable data structure,
mapping Object --> Object
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,9 +40,9 @@ exception statement from your version. */
package java.util;
import java.io.IOException;
-import java.io.Serializable;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
+import java.io.Serializable;
// NOTE: This implementation is very similar to that of Hashtable. If you fix
// a bug in here, chances are you should make a similar change to the Hashtable
@@ -743,18 +743,9 @@ public class HashMap extends AbstractMap
{
int idx = hash(e.key);
HashEntry dest = buckets[idx];
-
- if (dest != null)
- {
- while (dest.next != null)
- dest = dest.next;
- dest.next = e;
- }
- else
- buckets[idx] = e;
-
HashEntry next = e.next;
- e.next = null;
+ e.next = buckets[idx];
+ buckets[idx] = e;
e = next;
}
}
diff --git a/libjava/java/util/HashSet.java b/libjava/java/util/HashSet.java
index 006db1e8603..caad3ad16e7 100644
--- a/libjava/java/util/HashSet.java
+++ b/libjava/java/util/HashSet.java
@@ -1,5 +1,5 @@
/* HashSet.java -- a class providing a HashMap-backed Set
- Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,9 +39,9 @@ exception statement from your version. */
package java.util;
import java.io.IOException;
-import java.io.Serializable;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
+import java.io.Serializable;
/**
* This class provides a HashMap-backed implementation of the Set interface.
diff --git a/libjava/java/util/Hashtable.java b/libjava/java/util/Hashtable.java
index 698871b5124..3f5ae4c18c7 100644
--- a/libjava/java/util/Hashtable.java
+++ b/libjava/java/util/Hashtable.java
@@ -1,6 +1,6 @@
/* Hashtable.java -- a class providing a basic hashtable data structure,
mapping Object --> Object
- Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,9 +39,9 @@ exception statement from your version. */
package java.util;
import java.io.IOException;
-import java.io.Serializable;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
+import java.io.Serializable;
// NOTE: This implementation is very similar to that of HashMap. If you fix
// a bug in here, chances are you should make a similar change to the HashMap
diff --git a/libjava/java/util/LinkedList.java b/libjava/java/util/LinkedList.java
index c891f8230f0..4789a387ad5 100644
--- a/libjava/java/util/LinkedList.java
+++ b/libjava/java/util/LinkedList.java
@@ -1,5 +1,5 @@
/* LinkedList.java -- Linked list implementation of the List interface
- Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,10 +37,10 @@ exception statement from your version. */
package java.util;
-import java.io.Serializable;
-import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
import java.lang.reflect.Array;
/**
diff --git a/libjava/java/util/Map.java b/libjava/java/util/Map.java
index 192e3cfd0da..f7643f92a5e 100644
--- a/libjava/java/util/Map.java
+++ b/libjava/java/util/Map.java
@@ -1,6 +1,6 @@
/* Map.java: interface Map -- An object that maps keys to values
interface Map.Entry -- an Entry in a Map
- Copyright (C) 1998, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -264,7 +264,7 @@ public interface Map
* @since 1.2
* @status updated to 1.4
*/
- static interface Entry
+ interface Entry
{
/**
* Get the key corresponding to this entry.
diff --git a/libjava/java/util/Properties.java b/libjava/java/util/Properties.java
index 2f4428958d4..eac90e490fb 100644
--- a/libjava/java/util/Properties.java
+++ b/libjava/java/util/Properties.java
@@ -1,5 +1,5 @@
/* Properties.java -- a set of persistent properties
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,14 +38,14 @@ exception statement from your version. */
package java.util;
+import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
-import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.io.PrintStream;
import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.PrintWriter;
/**
* A set of persistent properties, which can be saved or loaded from a stream.
@@ -188,17 +188,14 @@ label = Name:\\u0020</pre>
{
char c = 0;
int pos = 0;
- // If empty line or begins with a comment character, skip this line.
- if (line.length() == 0
- || line.charAt(0) == '#' || line.charAt(0) == '!')
- continue;
-
+ // Leading whitespaces must be deleted first.
while (pos < line.length()
&& Character.isWhitespace(c = line.charAt(pos)))
pos++;
- // If line is empty skip this line.
- if (pos == line.length())
+ // If empty line or begins with a comment character, skip this line.
+ if ((line.length() - pos) == 0
+ || line.charAt(pos) == '#' || line.charAt(pos) == '!')
continue;
// The characters up to the next Whitespace, ':', or '='
diff --git a/libjava/java/util/PropertyPermission.java b/libjava/java/util/PropertyPermission.java
index 0d439d888a7..ec2ca7abab6 100644
--- a/libjava/java/util/PropertyPermission.java
+++ b/libjava/java/util/PropertyPermission.java
@@ -1,5 +1,5 @@
/* PropertyPermission.java -- permission to get and set System properties
- Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,13 +38,13 @@ exception statement from your version. */
package java.util;
-import java.security.Permission;
-import java.security.BasicPermission;
-import java.security.PermissionCollection;
-import java.io.ObjectStreamField;
+import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
-import java.io.IOException;
+import java.io.ObjectStreamField;
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
/**
* This class represents the permission to access and modify a property.<br>
diff --git a/libjava/java/util/PropertyResourceBundle.java b/libjava/java/util/PropertyResourceBundle.java
index d873e134e62..9d556f2e4b6 100644
--- a/libjava/java/util/PropertyResourceBundle.java
+++ b/libjava/java/util/PropertyResourceBundle.java
@@ -54,7 +54,7 @@ import java.io.InputStream;
*
* If there is also a class for this resource and the same locale, the
* class will be chosen. The properties file should have the name of the
- * resource bundle, appended with the locale (e.g. <code>_de</code) and the
+ * resource bundle, appended with the locale (e.g. <code>_de</code> and the
* extension <code>.properties</code>. The file should have the same format
* as for <code>Properties.load()</code>
*
diff --git a/libjava/java/util/ResourceBundle.java b/libjava/java/util/ResourceBundle.java
index 7a4a282e773..264152a8cb7 100644
--- a/libjava/java/util/ResourceBundle.java
+++ b/libjava/java/util/ResourceBundle.java
@@ -42,7 +42,6 @@ import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.io.InputStream;
import java.io.IOException;
-import gnu.classpath.Configuration;
/**
* A resource bundle contains locale-specific data. If you need localized
@@ -51,7 +50,7 @@ import gnu.classpath.Configuration;
* <code>getObject</code> or <code>getString</code> on that bundle.
*
* <p>When a bundle is demanded for a specific locale, the ResourceBundle
- * is searched in following order (<i>def. language<i> stands for the
+ * is searched in following order (<i>def. language</i> stands for the
* two letter ISO language code of the default locale (see
* <code>Locale.getDefault()</code>).
*
@@ -251,18 +250,22 @@ public abstract class ResourceBundle
*
* <p>A sequence of candidate bundle names are generated, and tested in
* this order, where the suffix 1 means the string from the specified
- * locale, and the suffix 2 means the string from the default locale:<ul>
+ * locale, and the suffix 2 means the string from the default locale:</p>
+ *
+ * <ul>
* <li>baseName + "_" + language1 + "_" + country1 + "_" + variant1</li>
* <li>baseName + "_" + language1 + "_" + country1</li>
* <li>baseName + "_" + language1</li>
* <li>baseName + "_" + language2 + "_" + country2 + "_" + variant2</li>
* <li>baseName + "_" + language2 + "_" + country2</li>
- * <li>baseName + "_" + language2<li>
+ * <li>baseName + "_" + language2</li>
* <li>baseName</li>
* </ul>
*
* <p>In the sequence, entries with an empty string are ignored. Next,
- * <code>getBundle</code> tries to instantiate the resource bundle:<ul>
+ * <code>getBundle</code> tries to instantiate the resource bundle:</p>
+ *
+ * <ul>
* <li>First, an attempt is made to load a class in the specified classloader
* which is a subclass of ResourceBundle, and which has a public constructor
* with no arguments, via reflection.</li>
@@ -277,7 +280,7 @@ public abstract class ResourceBundle
* in the above sequence are tested in a similar manner, and if any results
* in a resource bundle, it is assigned as the parent of the first bundle
* using the <code>setParent</code> method (unless the first bundle already
- * has a parent).
+ * has a parent).</p>
*
* <p>For example, suppose the following class and property files are
* provided: MyResources.class, MyResources_fr_CH.properties,
@@ -286,10 +289,12 @@ public abstract class ResourceBundle
* all files are valid (that is, public non-abstract subclasses of
* ResourceBundle with public nullary constructors for the ".class" files,
* syntactically correct ".properties" files). The default locale is
- * Locale("en", "UK").
+ * Locale("en", "UK").</p>
*
* <p>Calling getBundle with the shown locale argument values instantiates
- * resource bundles from the following sources:<ul>
+ * resource bundles from the following sources:</p>
+ *
+ * <ul>
* <li>Locale("fr", "CH"): result MyResources_fr_CH.class, parent
* MyResources_fr.properties, parent MyResources.class</li>
* <li>Locale("fr", "FR"): result MyResources_fr.properties, parent
@@ -301,8 +306,9 @@ public abstract class ResourceBundle
* <li>Locale("es", "ES"): result MyResources_es_ES.class, parent
* MyResources.class</li>
* </ul>
- * The file MyResources_fr_CH.properties is never used because it is hidden
- * by MyResources_fr_CH.class.
+ *
+ * <p>The file MyResources_fr_CH.properties is never used because it is hidden
+ * by MyResources_fr_CH.class.</p>
*
* @param baseName the name of the ResourceBundle
* @param locale A locale
@@ -338,7 +344,6 @@ public abstract class ResourceBundle
else if (cache.containsKey(name))
{
Reference ref = (Reference) cache.get(name);
- ResourceBundle result = null;
// If REF is null, that means that we added a `null' value to
// the hash map. That means we failed to find the bundle
// previously, and we cached that fact. The JDK does this, so
@@ -433,7 +438,6 @@ public abstract class ResourceBundle
if (cache.containsKey(localizedName))
{
Reference ref = (Reference) cache.get(localizedName);
- ResourceBundle result = null;
// If REF is null, that means that we added a `null' value to
// the hash map. That means we failed to find the bundle
// previously, and we cached that fact. The JDK does this, so
diff --git a/libjava/java/util/SimpleTimeZone.java b/libjava/java/util/SimpleTimeZone.java
index 31b85e18972..71f92e88f34 100644
--- a/libjava/java/util/SimpleTimeZone.java
+++ b/libjava/java/util/SimpleTimeZone.java
@@ -1,5 +1,5 @@
/* java.util.SimpleTimeZone
- Copyright (C) 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -146,7 +146,15 @@ public class SimpleTimeZone extends TimeZone
* @serial
*/
private int startTime;
-
+
+ /**
+ * This variable specifies the mode that startTime is specified in. By
+ * default it is WALL_TIME, but can also be STANDARD_TIME or UTC_TIME. For
+ * startTime, STANDARD_TIME and WALL_TIME are equivalent.
+ * @serial
+ */
+ private int startTimeMode = WALL_TIME;
+
/**
* The month in which daylight savings ends. This is one of the
* constants Calendar.JANUARY, ..., Calendar.DECEMBER.
@@ -186,6 +194,13 @@ public class SimpleTimeZone extends TimeZone
private int endTime;
/**
+ * This variable specifies the mode that endTime is specified in. By
+ * default it is WALL_TIME, but can also be STANDARD_TIME or UTC_TIME.
+ * @serial
+ */
+ private int endTimeMode = WALL_TIME;
+
+ /**
* This variable points to a deprecated array from JDK 1.1. It is
* ignored in JDK 1.2 but streamed out for compatibility with JDK 1.1.
* The array contains the lengths of the months in the year and is
@@ -224,6 +239,23 @@ public class SimpleTimeZone extends TimeZone
private static final long serialVersionUID = -403250971215465050L;
/**
+ * Constant to indicate that start and end times are specified in standard
+ * time, without adjusting for daylight savings.
+ */
+ public static final int STANDARD_TIME = 1;
+
+ /**
+ * Constant to indicate that start and end times are specified in wall
+ * time, adjusting for daylight savings. This is the default.
+ */
+ public static final int WALL_TIME = 0;
+
+ /**
+ * Constant to indicate that start and end times are specified in UTC.
+ */
+ public static final int UTC_TIME = 2;
+
+ /**
* Create a <code>SimpleTimeZone</code> with the given time offset
* from GMT and without daylight savings.
* @param rawOffset the time offset from GMT in milliseconds.
@@ -283,7 +315,10 @@ public class SimpleTimeZone extends TimeZone
* @param endday A day in month or a day of week number, as
* described above.
* @param endDayOfWeek The end rule day of week; see above.
- * @param endTime A time in millis in standard time. */
+ * @param endTime A time in millis in standard time.
+ * @throws IllegalArgumentException if parameters are invalid or out of
+ * range.
+ */
public SimpleTimeZone(int rawOffset, String id,
int startMonth, int startDayOfWeekInMonth,
int startDayOfWeek, int startTime,
@@ -310,6 +345,7 @@ public class SimpleTimeZone extends TimeZone
*
* @param dstSavings the amount of savings for daylight savings
* time in milliseconds. This must be positive.
+ * @since 1.2
*/
public SimpleTimeZone(int rawOffset, String id,
int startMonth, int startDayOfWeekInMonth,
@@ -325,6 +361,51 @@ public class SimpleTimeZone extends TimeZone
}
/**
+ * This constructs a new SimpleTimeZone that supports a daylight savings
+ * rule. The parameter are the same as for the constructor above, except
+ * there are the additional startTimeMode, endTimeMode, and dstSavings
+ * parameters.
+ *
+ * @param startTimeMode the mode that start times are specified in. One of
+ * WALL_TIME, STANDARD_TIME, or UTC_TIME.
+ * @param endTimeMode the mode that end times are specified in. One of
+ * WALL_TIME, STANDARD_TIME, or UTC_TIME.
+ * @param dstSavings the amount of savings for daylight savings
+ * time in milliseconds. This must be positive.
+ * @throws IllegalArgumentException if parameters are invalid or out of
+ * range.
+ * @since 1.4
+ */
+ public SimpleTimeZone(int rawOffset, String id,
+ int startMonth, int startDayOfWeekInMonth,
+ int startDayOfWeek, int startTime, int startTimeMode,
+ int endMonth, int endDayOfWeekInMonth,
+ int endDayOfWeek, int endTime, int endTimeMode,
+ int dstSavings)
+ {
+ this.rawOffset = rawOffset;
+ setID(id);
+ useDaylight = true;
+
+ if (startTimeMode < WALL_TIME || startTimeMode > UTC_TIME)
+ throw new IllegalArgumentException("startTimeMode must be one of WALL_TIME, STANDARD_TIME, or UTC_TIME");
+ if (endTimeMode < WALL_TIME || endTimeMode > UTC_TIME)
+ throw new IllegalArgumentException("endTimeMode must be one of WALL_TIME, STANDARD_TIME, or UTC_TIME");
+ this.startTimeMode = startTimeMode;
+ this.endTimeMode = endTimeMode;
+
+ setStartRule(startMonth, startDayOfWeekInMonth,
+ startDayOfWeek, startTime);
+ setEndRule(endMonth, endDayOfWeekInMonth, endDayOfWeek, endTime);
+ if (startMonth == endMonth)
+ throw new IllegalArgumentException
+ ("startMonth and endMonth must be different");
+ this.startYear = 0;
+
+ this.dstSavings = dstSavings;
+ }
+
+ /**
* Sets the first year, where daylight savings applies. The daylight
* savings rule never apply for years in the BC era. Note that this
* is gregorian calendar specific.
@@ -400,18 +481,85 @@ public class SimpleTimeZone extends TimeZone
// of this method.
this.startDay = Math.abs(day);
this.startDayOfWeek = Math.abs(dayOfWeek);
- this.startTime = time;
+ if (this.startTimeMode == WALL_TIME || this.startTimeMode == STANDARD_TIME)
+ this.startTime = time;
+ else
+ // Convert from UTC to STANDARD
+ this.startTime = time + this.rawOffset;
+ useDaylight = true;
+ }
+
+ /**
+ * Sets the daylight savings start rule. You must also set the
+ * end rule with <code>setEndRule</code> or the result of
+ * getOffset is undefined. For the parameters see the ten-argument
+ * constructor above.
+ *
+ * Note that this API isn't incredibly well specified. It appears that the
+ * after flag must override the parameters, since normally, the day and
+ * dayofweek can select this. I.e., if day < 0 and dayOfWeek < 0, on or
+ * before mode is chosen. But if after == true, this implementation
+ * overrides the signs of the other arguments. And if dayOfWeek == 0, it
+ * falls back to the behavior in the other APIs. I guess this should be
+ * checked against Sun's implementation.
+ *
+ * @param month The month where daylight savings start, zero
+ * based. You should use the constants in Calendar.
+ * @param day A day of month or day of week in month.
+ * @param dayOfWeek The day of week where daylight savings start.
+ * @param time The time in milliseconds standard time where daylight
+ * savings start.
+ * @param after If true, day and dayOfWeek specify first day of week on or
+ * after day, else first day of week on or before.
+ * @since 1.2
+ * @see SimpleTimeZone
+ */
+ public void setStartRule(int month, int day, int dayOfWeek, int time, boolean after)
+ {
+ // FIXME: XXX: Validate that checkRule and offset processing work with on
+ // or before mode.
+ this.startDay = after ? Math.abs(day) : -Math.abs(day);
+ this.startDayOfWeek = after ? Math.abs(dayOfWeek) : -Math.abs(dayOfWeek);
+ this.startMode = (dayOfWeek != 0) ? (after ? DOW_GE_DOM_MODE : DOW_LE_DOM_MODE)
+ : checkRule(month, day, dayOfWeek);
+ this.startDay = Math.abs(this.startDay);
+ this.startDayOfWeek = Math.abs(this.startDayOfWeek);
+
+ this.startMonth = month;
+
+ if (this.startTimeMode == WALL_TIME || this.startTimeMode == STANDARD_TIME)
+ this.startTime = time;
+ else
+ // Convert from UTC to STANDARD
+ this.startTime = time + this.rawOffset;
useDaylight = true;
}
/**
+ * Sets the daylight savings start rule. You must also set the
+ * end rule with <code>setEndRule</code> or the result of
+ * getOffset is undefined. For the parameters see the ten-argument
+ * constructor above.
+ *
+ * @param month The month where daylight savings start, zero
+ * based. You should use the constants in Calendar.
+ * @param day A day of month or day of week in month.
+ * @param time The time in milliseconds standard time where daylight
+ * savings start.
+ * @see SimpleTimeZone
+ * @since 1.2
+ */
+ public void setStartRule(int month, int day, int time)
+ {
+ setStartRule(month, day, 0, time);
+ }
+
+ /**
* Sets the daylight savings end rule. You must also set the
* start rule with <code>setStartRule</code> or the result of
* getOffset is undefined. For the parameters see the ten-argument
* constructor above.
*
- * @param rawOffset The time offset from GMT.
- * @param id The identifier of this time zone.
* @param month The end month of daylight savings.
* @param day A day in month, or a day of week in month.
* @param dayOfWeek A day of week, when daylight savings ends.
@@ -426,11 +574,82 @@ public class SimpleTimeZone extends TimeZone
// of this method.
this.endDay = Math.abs(day);
this.endDayOfWeek = Math.abs(dayOfWeek);
- this.endTime = time;
+ if (this.endTimeMode == WALL_TIME)
+ this.endTime = time;
+ else if (this.endTimeMode == STANDARD_TIME)
+ // Convert from STANDARD to DST
+ this.endTime = time + this.dstSavings;
+ else
+ // Convert from UTC to DST
+ this.endTime = time + this.rawOffset + this.dstSavings;
+ useDaylight = true;
+ }
+
+ /**
+ * Sets the daylight savings end rule. You must also set the
+ * start rule with <code>setStartRule</code> or the result of
+ * getOffset is undefined. For the parameters see the ten-argument
+ * constructor above.
+ *
+ * Note that this API isn't incredibly well specified. It appears that the
+ * after flag must override the parameters, since normally, the day and
+ * dayofweek can select this. I.e., if day < 0 and dayOfWeek < 0, on or
+ * before mode is chosen. But if after == true, this implementation
+ * overrides the signs of the other arguments. And if dayOfWeek == 0, it
+ * falls back to the behavior in the other APIs. I guess this should be
+ * checked against Sun's implementation.
+ *
+ * @param month The end month of daylight savings.
+ * @param day A day in month, or a day of week in month.
+ * @param dayOfWeek A day of week, when daylight savings ends.
+ * @param time A time in millis in standard time.
+ * @param after If true, day and dayOfWeek specify first day of week on or
+ * after day, else first day of week on or before.
+ * @since 1.2
+ * @see #setStartRule
+ */
+ public void setEndRule(int month, int day, int dayOfWeek, int time, boolean after)
+ {
+ // FIXME: XXX: Validate that checkRule and offset processing work with on
+ // or before mode.
+ this.endDay = after ? Math.abs(day) : -Math.abs(day);
+ this.endDayOfWeek = after ? Math.abs(dayOfWeek) : -Math.abs(dayOfWeek);
+ this.endMode = (dayOfWeek != 0) ? (after ? DOW_GE_DOM_MODE : DOW_LE_DOM_MODE)
+ : checkRule(month, day, dayOfWeek);
+ this.endDay = Math.abs(this.endDay);
+ this.endDayOfWeek = Math.abs(endDayOfWeek);
+
+ this.endMonth = month;
+
+ if (this.endTimeMode == WALL_TIME)
+ this.endTime = time;
+ else if (this.endTimeMode == STANDARD_TIME)
+ // Convert from STANDARD to DST
+ this.endTime = time + this.dstSavings;
+ else
+ // Convert from UTC to DST
+ this.endTime = time + this.rawOffset + this.dstSavings;
useDaylight = true;
}
/**
+ * Sets the daylight savings end rule. You must also set the
+ * start rule with <code>setStartRule</code> or the result of
+ * getOffset is undefined. For the parameters see the ten-argument
+ * constructor above.
+ *
+ * @param month The end month of daylight savings.
+ * @param day A day in month, or a day of week in month.
+ * @param dayOfWeek A day of week, when daylight savings ends.
+ * @param time A time in millis in standard time.
+ * @see #setStartRule
+ */
+ public void setEndRule(int month, int day, int time)
+ {
+ setEndRule(month, day, 0, time);
+ }
+
+ /**
* Gets the time zone offset, for current date, modified in case of
* daylight savings. This is the offset to add to UTC to get the local
* time.
diff --git a/libjava/java/util/StringTokenizer.java b/libjava/java/util/StringTokenizer.java
index e7fc6fd00d2..472d8951e5d 100644
--- a/libjava/java/util/StringTokenizer.java
+++ b/libjava/java/util/StringTokenizer.java
@@ -196,7 +196,7 @@ public class StringTokenizer implements Enumeration
/**
* This does the same as hasMoreTokens. This is the
- * <code>Enumeration</code interface method.
+ * <code>Enumeration</code> interface method.
*
* @return true, if the next call of nextElement() will succeed
* @see #hasMoreTokens()
@@ -208,7 +208,7 @@ public class StringTokenizer implements Enumeration
/**
* This does the same as nextTokens. This is the
- * <code>Enumeration</code interface method.
+ * <code>Enumeration</code> interface method.
*
* @return the next token with respect to the current delimiter characters
* @throws NoSuchElementException if there are no more tokens
diff --git a/libjava/java/util/TimeZone.java b/libjava/java/util/TimeZone.java
index 2636956527d..504d34e7ffa 100644
--- a/libjava/java/util/TimeZone.java
+++ b/libjava/java/util/TimeZone.java
@@ -1,5 +1,5 @@
/* java.util.TimeZone
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,9 +38,10 @@ exception statement from your version. */
package java.util;
-import java.text.DateFormatSymbols;
import gnu.classpath.Configuration;
+import java.text.DateFormatSymbols;
+
/**
* This class represents a time zone offset and handles daylight savings.
*
diff --git a/libjava/java/util/TreeMap.java b/libjava/java/util/TreeMap.java
index 9426a0bc7f5..d3b67481511 100644
--- a/libjava/java/util/TreeMap.java
+++ b/libjava/java/util/TreeMap.java
@@ -1,6 +1,6 @@
/* TreeMap.java -- a class providing a basic Red-Black Tree data structure,
mapping Object --> Object
- Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,10 +39,10 @@ exception statement from your version. */
package java.util;
-import java.io.Serializable;
-import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
/**
* This class provides a red-black tree implementation of the SortedMap
diff --git a/libjava/java/util/TreeSet.java b/libjava/java/util/TreeSet.java
index bd625d158dd..f38357082d3 100644
--- a/libjava/java/util/TreeSet.java
+++ b/libjava/java/util/TreeSet.java
@@ -1,5 +1,5 @@
/* TreeSet.java -- a class providing a TreeMap-backed SortedSet
- Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,9 +39,9 @@ exception statement from your version. */
package java.util;
import java.io.IOException;
-import java.io.Serializable;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
+import java.io.Serializable;
/**
* This class provides a TreeMap-backed implementation of the SortedSet
diff --git a/libjava/java/util/Vector.java b/libjava/java/util/Vector.java
index 9cf8639fc3b..d72788e3018 100644
--- a/libjava/java/util/Vector.java
+++ b/libjava/java/util/Vector.java
@@ -1,5 +1,5 @@
/* Vector.java -- Class that provides growable arrays.
- Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,8 +37,8 @@ exception statement from your version. */
package java.util;
-import java.lang.reflect.Array;
import java.io.Serializable;
+import java.lang.reflect.Array;
/**
* The <code>Vector</code> classes implements growable arrays of Objects.
diff --git a/libjava/java/util/WeakHashMap.java b/libjava/java/util/WeakHashMap.java
index 4cce821c5ff..e76e4bac91f 100644
--- a/libjava/java/util/WeakHashMap.java
+++ b/libjava/java/util/WeakHashMap.java
@@ -1,6 +1,6 @@
/* WeakHashMap -- a hashtable that keeps only weak references
to its keys, allowing the virtual machine to reclaim them
- Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,8 +39,8 @@ exception statement from your version. */
package java.util;
-import java.lang.ref.WeakReference;
import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
/**
* A weak hash map has only weak references to the key. This means that it
diff --git a/libjava/java/util/jar/Attributes.java b/libjava/java/util/jar/Attributes.java
index ea203446eaa..06dc4f89fc5 100644
--- a/libjava/java/util/jar/Attributes.java
+++ b/libjava/java/util/jar/Attributes.java
@@ -85,17 +85,18 @@ public class Attributes implements Cloneable, Map
* attributes, applet attributes, extension identification attributes,
* package versioning and sealing attributes, file contents attributes,
* bean objects attribute and signing attributes. See the
- * <p>
- * The characters of a Name must obey the following restrictions:
+ *
+ * <p>The characters of a Name must obey the following restrictions:</p>
+ *
* <ul>
- * <li> Must contain at least one character
- * <li> The first character must be alphanumeric (a-z, A-Z, 0-9)
- * <li> All other characters must be alphanumeric, a '-' or a '_'
+ * <li>Must contain at least one character</li>
+ * <li>The first character must be alphanumeric (a-z, A-Z, 0-9)</li>
+ * <li>All other characters must be alphanumeric, a '-' or a '_'</li>
* </ul>
- * <p>
- * When comparing Names (with <code>equals</code>) all characters are
+ *
+ * <p>When comparing Names (with <code>equals</code>) all characters are
* converted to lowercase. But you can get the original case sensitive
- * string with the <code>toString()</code> method.
+ * string with the <code>toString()</code> method.</p>
*
* @since 1.2
* @author Mark Wielaard (mark@klomp.org)
@@ -145,15 +146,15 @@ public class Attributes implements Cloneable, Map
* Manifest manifest file with the following Names:
* <ul>
* <li> &lt;extension&gt;-Extension-Name:
- * unique name of the extension
+ * unique name of the extension</li>
* <li> &lt;extension&gt;-Specification-Version:
- * minimum specification version
+ * minimum specification version</li>
* <li> &lt;extension&gt;-Implementation-Version:
- * minimum implementation version
+ * minimum implementation version</li>
* <li> &lt;extension&gt;-Implementation-Vendor-Id:
- * unique id of implementation vendor
+ * unique id of implementation vendor</li>
* <li> &lt;extension&gt;-Implementation-URL:
- * where the latest version of the extension library can be found
+ * where the latest version of the extension library can be found</li>
* </ul>
*/
public static final Name EXTENSION_LIST = new Name("Extension-List");
diff --git a/libjava/java/util/jar/JarFile.java b/libjava/java/util/jar/JarFile.java
index 394b51af6d0..070b3375d19 100644
--- a/libjava/java/util/jar/JarFile.java
+++ b/libjava/java/util/jar/JarFile.java
@@ -1,5 +1,5 @@
/* JarFile.java - Representation of a jar file
- Copyright (C) 2000, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,14 +37,14 @@ exception statement from your version. */
package java.util.jar;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipException;
-import java.util.zip.ZipFile;
import java.io.File;
import java.io.FileNotFoundException;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.util.Enumeration;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
/**
* Representation of a jar file.
diff --git a/libjava/java/util/jar/JarInputStream.java b/libjava/java/util/jar/JarInputStream.java
index daf935fa70a..74649edbadb 100644
--- a/libjava/java/util/jar/JarInputStream.java
+++ b/libjava/java/util/jar/JarInputStream.java
@@ -1,5 +1,5 @@
/* JarInputStream.java - InputStream for reading jar files
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,8 +37,8 @@ exception statement from your version. */
package java.util.jar;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
diff --git a/libjava/java/util/jar/JarOutputStream.java b/libjava/java/util/jar/JarOutputStream.java
index 19009999e91..217e245c7ff 100644
--- a/libjava/java/util/jar/JarOutputStream.java
+++ b/libjava/java/util/jar/JarOutputStream.java
@@ -1,5 +1,5 @@
/* JarOutputStream.java - OutputStream for writing jar files
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,8 +37,8 @@ exception statement from your version. */
package java.util.jar;
-import java.io.OutputStream;
import java.io.IOException;
+import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
diff --git a/libjava/java/util/jar/Manifest.java b/libjava/java/util/jar/Manifest.java
index 9a153760ef8..ddc201b45b5 100644
--- a/libjava/java/util/jar/Manifest.java
+++ b/libjava/java/util/jar/Manifest.java
@@ -1,5 +1,5 @@
-/* Attributes.java -- Reads, writes and manipulaties jar manifest files
- Copyright (C) 2000 Free Software Foundation, Inc.
+/* Manifest.java -- Reads, writes and manipulaties jar manifest files
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -45,12 +45,9 @@ import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
-import java.io.Reader;
-import java.io.Writer;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
-import java.util.Set;
/**
* Reads, writes and manipulaties jar manifest files.
diff --git a/libjava/java/util/logging/ConsoleHandler.java b/libjava/java/util/logging/ConsoleHandler.java
index dd519b682f4..6d79c1dbfca 100644
--- a/libjava/java/util/logging/ConsoleHandler.java
+++ b/libjava/java/util/logging/ConsoleHandler.java
@@ -67,7 +67,7 @@ package java.util.logging;
*
* <li><code>java.util.logging.ConsoleHandler.encoding</code> - specifies
* the name of the character encoding. Default value:
- * the default platform encoding.
+ * the default platform encoding.</li>
*
* </ul>
*
diff --git a/libjava/java/util/logging/FileHandler.java b/libjava/java/util/logging/FileHandler.java
index b9f61109d3b..fe7afa25bcb 100644
--- a/libjava/java/util/logging/FileHandler.java
+++ b/libjava/java/util/logging/FileHandler.java
@@ -1,7 +1,7 @@
/* FileHandler.java
-- a class for publishing log messages to log files
-Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -41,9 +41,9 @@ exception statement from your version.
package java.util.logging;
-import java.io.IOException;
import java.io.File;
import java.io.FileOutputStream;
+import java.io.IOException;
/**
* A <code>FileHandler</code> publishes log records to a set of log
diff --git a/libjava/java/util/logging/Formatter.java b/libjava/java/util/logging/Formatter.java
index c4819695165..82753768f69 100644
--- a/libjava/java/util/logging/Formatter.java
+++ b/libjava/java/util/logging/Formatter.java
@@ -2,7 +2,7 @@
-- a class for formatting log messages by localizing message texts
and performing substitution of parameters
-Copyright (C) 2002 Free Software Foundation, Inc.
+Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -43,8 +43,8 @@ exception statement from your version.
package java.util.logging;
-import java.util.ResourceBundle;
import java.text.MessageFormat;
+import java.util.ResourceBundle;
/**
* A <code>Formatter</code> supports handlers by localizing
diff --git a/libjava/java/util/logging/Handler.java b/libjava/java/util/logging/Handler.java
index c0fb1cd653a..f74ed0ec6c0 100644
--- a/libjava/java/util/logging/Handler.java
+++ b/libjava/java/util/logging/Handler.java
@@ -1,7 +1,7 @@
/* Handler.java
-- a class for publishing log messages
-Copyright (C) 2002 Free Software Foundation, Inc.
+Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -43,7 +43,6 @@ exception statement from your version.
package java.util.logging;
import java.io.UnsupportedEncodingException;
-import java.security.AccessController;
/**
* A <code>Handler</code> publishes <code>LogRecords</code> to
diff --git a/libjava/java/util/logging/Level.java b/libjava/java/util/logging/Level.java
index ed497d537e0..e37f9cb5824 100644
--- a/libjava/java/util/logging/Level.java
+++ b/libjava/java/util/logging/Level.java
@@ -343,7 +343,7 @@ public class Level implements Serializable
for (int i = 0; i < knownLevels.length; i++)
{
- if (name.equals(knownLevels[i].name))
+ if (name == knownLevels[i].name)
return knownLevels[i];
}
diff --git a/libjava/java/util/logging/LogManager.java b/libjava/java/util/logging/LogManager.java
index 36216bc408b..24757089410 100644
--- a/libjava/java/util/logging/LogManager.java
+++ b/libjava/java/util/logging/LogManager.java
@@ -67,13 +67,12 @@ import java.lang.ref.WeakReference;
* <code>java.util.logging.LogManager</code> is initialized.
* The configuration process includes the subsequent steps:
*
- * <ol>
+ * <ul>
* <li>If the system property <code>java.util.logging.manager</code>
* is set to the name of a subclass of
* <code>java.util.logging.LogManager</code>, an instance of
* that subclass is created and becomes the global LogManager.
* Otherwise, a new instance of LogManager is created.</li>
- *
* <li>The <code>LogManager</code> constructor tries to create
* a new instance of the class specified by the system
* property <code>java.util.logging.config.class</code>.
@@ -91,14 +90,13 @@ import java.lang.ref.WeakReference;
* {@link #readConfiguration(java.io.InputStream)}.
* The name and location of this file are specified by the system
* property <code>java.util.logging.config.file</code>.</li>
- *
* <li>If the system property <code>java.util.logging.config.file</code>
* is not set, however, the contents of the URL
* "{gnu.classpath.home.url}/logging.properties" are passed to
* {@link #readConfiguration(java.io.InputStream)}.
* Here, "{gnu.classpath.home.url}" stands for the value of
* the system property <code>gnu.classpath.home.url</code>.</li>
- * </ol>
+ * </ul>
*
* @author Sascha Brawer (brawer@acm.org)
*/
@@ -259,10 +257,10 @@ public class LogManager
*
* @param logger the logger to be added.
*
- * @return <code>true<code>if <code>logger</code> was added,
+ * @return <code>true</code>if <code>logger</code> was added,
* <code>false</code> otherwise.
*
- * @throws NullPointerException if <code>name<code> is
+ * @throws NullPointerException if <code>name</code> is
* <code>null</code>.
*/
public synchronized boolean addLogger(Logger logger)
diff --git a/libjava/java/util/logging/Logger.java b/libjava/java/util/logging/Logger.java
index 3c194785c5f..b1e6ef5460e 100644
--- a/libjava/java/util/logging/Logger.java
+++ b/libjava/java/util/logging/Logger.java
@@ -1,7 +1,7 @@
/* Logger.java
-- a class for logging messages
-Copyright (C) 2002 Free Software Foundation, Inc.
+Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -42,9 +42,9 @@ exception statement from your version.
package java.util.logging;
-import java.util.ResourceBundle;
-import java.util.MissingResourceException;
import java.util.List;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
/**
* A Logger is used for logging information about events. Usually, there
diff --git a/libjava/java/util/logging/MemoryHandler.java b/libjava/java/util/logging/MemoryHandler.java
index 825a6fa86d6..3c18b527d18 100644
--- a/libjava/java/util/logging/MemoryHandler.java
+++ b/libjava/java/util/logging/MemoryHandler.java
@@ -35,10 +35,7 @@ module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
-exception statement from your version.
-
-*/
-
+exception statement from your version. */
package java.util.logging;
@@ -53,28 +50,22 @@ package java.util.logging;
* value, a default is taken without an exception being thrown.
*
* <ul>
- *
* <li><code>java.util.MemoryHandler.level</code> - specifies
* the initial severity level threshold. Default value:
* <code>Level.ALL</code>.</li>
- *
* <li><code>java.util.MemoryHandler.filter</code> - specifies
* the name of a Filter class. Default value: No Filter.</li>
- *
* <li><code>java.util.MemoryHandler.size</code> - specifies the
* maximum number of log records that are kept in the circular
* buffer. Default value: 1000.</li>
- *
* <li><code>java.util.MemoryHandler.push</code> - specifies the
* <code>pushLevel</code>. Default value:
* <code>Level.SEVERE</code>.</li>
- *
* <li><code>java.util.MemoryHandler.target</code> - specifies the
* name of a subclass of {@link Handler} that will be used as the
* target handler. There is no default value for this property;
* if it is not set, the no-argument MemoryHandler constructor
* will throw an exception.</li>
- *
* </ul>
*
* @author Sascha Brawer (brawer@acm.org)
diff --git a/libjava/java/util/logging/SimpleFormatter.java b/libjava/java/util/logging/SimpleFormatter.java
index aece9d40596..023e9a7fb89 100644
--- a/libjava/java/util/logging/SimpleFormatter.java
+++ b/libjava/java/util/logging/SimpleFormatter.java
@@ -1,7 +1,7 @@
/* SimpleFormatter.java
-- a class for formatting log records into short human-readable messages
-Copyright (C) 2002 Free Software Foundation, Inc.
+Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -42,8 +42,8 @@ exception statement from your version.
package java.util.logging;
-import java.util.Date;
import java.text.DateFormat;
+import java.util.Date;
/**
* A <code>SimpleFormatter</code> formats log records into
diff --git a/libjava/java/util/logging/SocketHandler.java b/libjava/java/util/logging/SocketHandler.java
index d9939a0f780..d4fc6e603c1 100644
--- a/libjava/java/util/logging/SocketHandler.java
+++ b/libjava/java/util/logging/SocketHandler.java
@@ -68,7 +68,7 @@ package java.util.logging;
*
* <li><code>java.util.SocketHandler.encoding</code> - specifies
* the name of the character encoding. Default value:
- * the default platform encoding.
+ * the default platform encoding.</li>
*
* <li><code>java.util.SocketHandler.host</code> - specifies
* the name of the host to which records are published.
diff --git a/libjava/java/util/logging/XMLFormatter.java b/libjava/java/util/logging/XMLFormatter.java
index 2de6c73c8b0..d8647177468 100644
--- a/libjava/java/util/logging/XMLFormatter.java
+++ b/libjava/java/util/logging/XMLFormatter.java
@@ -1,7 +1,7 @@
/* XMLFormatter.java
-- a class for formatting log messages into a standard XML format
-Copyright (C) 2002 Free Software Foundation, Inc.
+Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -42,10 +42,9 @@ exception statement from your version.
package java.util.logging;
+import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.ResourceBundle;
-import java.text.MessageFormat;
-import java.text.SimpleDateFormat;
/**
* An <code>XMLFormatter</code> formats LogRecords into
diff --git a/libjava/java/util/prefs/AbstractPreferences.java b/libjava/java/util/prefs/AbstractPreferences.java
index 4463c5e0370..876279c8c62 100644
--- a/libjava/java/util/prefs/AbstractPreferences.java
+++ b/libjava/java/util/prefs/AbstractPreferences.java
@@ -38,13 +38,14 @@ exception statement from your version. */
package java.util.prefs;
+import gnu.java.util.prefs.NodeWriter;
+
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
-import java.util.Iterator;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.TreeSet;
-import gnu.java.util.prefs.NodeWriter;
/**
* Partial implementation of a Preference node.
@@ -118,7 +119,7 @@ public abstract class AbstractPreferences extends Preferences {
throw new IllegalArgumentException("Illegal name argument '"
+ name
+ "' (parent is "
- + parent == null ? "" : "not "
+ + (parent == null ? "" : "not ")
+ "null)");
this.parent = parent;
this.name = name;
diff --git a/libjava/java/util/prefs/BackingStoreException.java b/libjava/java/util/prefs/BackingStoreException.java
index f2c6b4c8b31..2607142d0e8 100644
--- a/libjava/java/util/prefs/BackingStoreException.java
+++ b/libjava/java/util/prefs/BackingStoreException.java
@@ -38,9 +38,9 @@ exception statement from your version. */
package java.util.prefs;
-import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
import java.io.NotSerializableException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
/**
* Chained exception thrown when backing store fails. This exception is
diff --git a/libjava/java/util/prefs/InvalidPreferencesFormatException.java b/libjava/java/util/prefs/InvalidPreferencesFormatException.java
index e375db7ab1f..05996315261 100644
--- a/libjava/java/util/prefs/InvalidPreferencesFormatException.java
+++ b/libjava/java/util/prefs/InvalidPreferencesFormatException.java
@@ -38,9 +38,9 @@ exception statement from your version. */
package java.util.prefs;
-import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
import java.io.NotSerializableException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
/**
* Indicates reading prefs from stream failed. Thrown by the
diff --git a/libjava/java/util/prefs/Preferences.java b/libjava/java/util/prefs/Preferences.java
index ea65550af7e..ce8aacf176f 100644
--- a/libjava/java/util/prefs/Preferences.java
+++ b/libjava/java/util/prefs/Preferences.java
@@ -37,16 +37,15 @@ exception statement from your version. */
package java.util.prefs;
+import gnu.java.util.prefs.NodeReader;
+
+import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.io.IOException;
-
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
-import gnu.java.util.prefs.NodeReader;
-
/**
* Preference node containing key value entries and subnodes.
* <p>
diff --git a/libjava/java/util/regex/Matcher.java b/libjava/java/util/regex/Matcher.java
index 28835d294e3..8b2ac3e5def 100644
--- a/libjava/java/util/regex/Matcher.java
+++ b/libjava/java/util/regex/Matcher.java
@@ -38,7 +38,6 @@ exception statement from your version. */
package java.util.regex;
-import gnu.regexp.RE;
import gnu.regexp.REMatch;
/**
diff --git a/libjava/java/util/regex/Pattern.java b/libjava/java/util/regex/Pattern.java
index d30096049e5..174bdae5878 100644
--- a/libjava/java/util/regex/Pattern.java
+++ b/libjava/java/util/regex/Pattern.java
@@ -38,8 +38,8 @@ exception statement from your version. */
package java.util.regex;
import gnu.regexp.RE;
-import gnu.regexp.RESyntax;
import gnu.regexp.REException;
+import gnu.regexp.RESyntax;
import java.io.Serializable;
import java.util.ArrayList;
@@ -67,12 +67,6 @@ public class Pattern implements Serializable
private final RE re;
- private Pattern (String regex)
- throws PatternSyntaxException
- {
- this (regex, 0);
- }
-
private Pattern (String regex, int flags)
throws PatternSyntaxException
{
diff --git a/libjava/java/util/zip/ZipEntry.java b/libjava/java/util/zip/ZipEntry.java
index e2262812b9f..3f7f6435529 100644
--- a/libjava/java/util/zip/ZipEntry.java
+++ b/libjava/java/util/zip/ZipEntry.java
@@ -169,12 +169,12 @@ public class ZipEntry implements ZipConstants, Cloneable
synchronized (cal)
{
cal.setTime(new Date(time*1000L));
- dostime = (cal.get(cal.YEAR) - 1980 & 0x7f) << 25
- | (cal.get(cal.MONTH) + 1) << 21
- | (cal.get(cal.DAY_OF_MONTH)) << 16
- | (cal.get(cal.HOUR_OF_DAY)) << 11
- | (cal.get(cal.MINUTE)) << 5
- | (cal.get(cal.SECOND)) >> 1;
+ dostime = (cal.get(Calendar.YEAR) - 1980 & 0x7f) << 25
+ | (cal.get(Calendar.MONTH) + 1) << 21
+ | (cal.get(Calendar.DAY_OF_MONTH)) << 16
+ | (cal.get(Calendar.HOUR_OF_DAY)) << 11
+ | (cal.get(Calendar.MINUTE)) << 5
+ | (cal.get(Calendar.SECOND)) >> 1;
}
dostime = (int) (dostime / 1000L);
this.known |= KNOWN_TIME;
diff --git a/libjava/javax/accessibility/AccessibleText.java b/libjava/javax/accessibility/AccessibleText.java
index 14c324c7708..7c3d9a9ccd6 100644
--- a/libjava/javax/accessibility/AccessibleText.java
+++ b/libjava/javax/accessibility/AccessibleText.java
@@ -1,5 +1,5 @@
/* AccessibleText.java -- aids in accessibly manipulating text
- Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,8 +38,9 @@ exception statement from your version. */
package javax.accessibility;
-import java.awt.Rectangle;
import java.awt.Point;
+import java.awt.Rectangle;
+
import javax.swing.text.AttributeSet;
/**
diff --git a/libjava/javax/imageio/ImageReader.java b/libjava/javax/imageio/ImageReader.java
new file mode 100644
index 00000000000..75ae9ad6047
--- /dev/null
+++ b/libjava/javax/imageio/ImageReader.java
@@ -0,0 +1,46 @@
+/* ImageReader.java -- Decodes raster images.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.imageio;
+
+public abstract class ImageReader
+{
+ // FIXME: Incomplete. This class is merely present in order to allow
+ // compilation of the javax.imageio.spi package, for which GNU
+ // Classpath does provide an implementation.
+}
diff --git a/libjava/javax/imageio/ImageTranscoder.java b/libjava/javax/imageio/ImageTranscoder.java
new file mode 100644
index 00000000000..20c6959985e
--- /dev/null
+++ b/libjava/javax/imageio/ImageTranscoder.java
@@ -0,0 +1,46 @@
+/* ImageTranscoder.java -- Image metadata transcoder.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.imageio;
+
+public interface ImageTranscoder
+{
+ // FIXME: Incomplete. This interface is merely present in order to
+ // allow compilation of the javax.imageio.spi package, for which GNU
+ // Classpath does provide an implementation.
+}
diff --git a/libjava/javax/imageio/ImageWriter.java b/libjava/javax/imageio/ImageWriter.java
new file mode 100644
index 00000000000..7ef60c365aa
--- /dev/null
+++ b/libjava/javax/imageio/ImageWriter.java
@@ -0,0 +1,47 @@
+/* ImageWriter.java -- Encodes raster images.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.imageio;
+
+public abstract class ImageWriter
+ implements ImageTranscoder
+{
+ // FIXME: Incomplete. This class is merely present in order to allow
+ // compilation of the javax.imageio.spi package, for which GNU
+ // Classpath does provide an implementation.
+}
diff --git a/libjava/javax/imageio/package.html b/libjava/javax/imageio/package.html
new file mode 100644
index 00000000000..ed284b93cb0
--- /dev/null
+++ b/libjava/javax/imageio/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in javax.imageio package.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - javax.imageio</title></head>
+
+<body>
+<p></p>
+
+</body>
+</html>
diff --git a/libjava/javax/imageio/spi/IIOServiceProvider.java b/libjava/javax/imageio/spi/IIOServiceProvider.java
new file mode 100644
index 00000000000..bd0a449331c
--- /dev/null
+++ b/libjava/javax/imageio/spi/IIOServiceProvider.java
@@ -0,0 +1,163 @@
+/* IIOServiceProvider.java -- General service provider for image I/O.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.imageio.spi;
+
+import java.util.Locale;
+
+
+/**
+ * An abstract superclass for service providers that perform image I/O.
+ *
+ * @since 1.4
+ *
+ * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a>
+ */
+public abstract class IIOServiceProvider
+ implements RegisterableService
+{
+ /**
+ * The vendor of this service provider, or <code>null</code> if the
+ * subclass constructor did not set this field.
+ *
+ * @see #getVendorName()
+ */
+ protected String vendorName;
+
+
+ /**
+ * The version of this service provider, or <code>null</code> if the
+ * subclass constructor did not set this field.
+ *
+ * @see #getVersion()
+ */
+ protected String version;
+
+
+ /**
+ * Constructs a general <code>IIOServiceProvider</code>, given the
+ * vendor name and a version string.
+ *
+ * @throws IllegalArgumentException if <code>vendorName</code>
+ * or <code>version</code> is <code>null</code>.
+ */
+ public IIOServiceProvider(String vendorName, String version)
+ {
+ if (vendorName == null || version == null)
+ throw new IllegalArgumentException();
+
+ this.vendorName = vendorName;
+ this.version = version;
+ }
+
+
+ /**
+ * Constructs a general <code>IIOServiceProvider</code> without
+ * specifying a vendor name and a version string. The subclass
+ * constructor should set the {@link #vendorName} and {@link
+ * #version} to non-null values.
+ */
+ public IIOServiceProvider()
+ {
+ }
+
+
+ /**
+ * Informs this service provider that it has been registered in a
+ * {@link ServiceRegistry}. If this provider gets registered as an
+ * implementor for several service categories, its
+ * <code>onRegistration</code> method will be called multiple times.
+ * The default implementation does nothing.
+ *
+ * @param registry the registry to which this service provider has
+ * been added.
+ *
+ * @param category the service category for which this provider has
+ * been registered as an implementor.
+ */
+ public void onRegistration(ServiceRegistry registry, Class category)
+ {
+ }
+
+
+ /**
+ * Informs this service provider that it has been de-registered from
+ * a {@link ServiceRegistry}. If this provider had been registered
+ * as an implementor for several service categories, its
+ * <code>onDeregistration</code> method will be called multiple
+ * times. The default implementation does nothing.
+ *
+ * @param registry the registry from which this service provider has
+ * been removed.
+ *
+ * @param category the service category for which this provider has
+ * been registered as an implementor.
+ */
+ public void onDeregistration(ServiceRegistry registry, Class category)
+ {
+ }
+
+
+ /**
+ * Returns the name of the vendor of this service provider.
+ */
+ public String getVendorName()
+ {
+ return vendorName;
+ }
+
+
+ /**
+ * Returns an identifier string for the version of this service
+ * provider.
+ */
+ public String getVersion()
+ {
+ return version;
+ }
+
+
+ /**
+ * Returns a short description of this service provider that can be
+ * presented to a human user.
+ *
+ * @param locale the locale for which the description string should
+ * be localized.
+ */
+ public abstract String getDescription(Locale locale);
+}
diff --git a/libjava/javax/imageio/spi/ImageInputStreamSpi.java b/libjava/javax/imageio/spi/ImageInputStreamSpi.java
new file mode 100644
index 00000000000..b8d58547da1
--- /dev/null
+++ b/libjava/javax/imageio/spi/ImageInputStreamSpi.java
@@ -0,0 +1,144 @@
+/* ImageInputStreamSpi.java -- Service provider for image input streams.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.imageio.spi;
+
+import java.io.File;
+import java.io.IOException;
+import javax.imageio.stream.ImageInputStream;
+
+
+/**
+ * An abstract superclass for service providers that create
+ * {@linkplain javax.imageio.stream.ImageInputStream image input
+ * streams} for a file, URL, byte array or any other source.
+ *
+ * @since 1.4
+ *
+ * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a>
+ */
+public abstract class ImageInputStreamSpi
+ extends IIOServiceProvider
+{
+ /**
+ * Indicates which kind of input is processable by the streams
+ * created by {@link #createInputStreamInstance(Object)}.
+ */
+ protected Class inputClass;
+
+
+ /**
+ * Constructs a service provider for image input streams, given no
+ * parameters. It is up to the sub-class to set {@link #vendorName},
+ * {@link #version} and {@link #inputClass} to non-null values.
+ */
+ protected ImageInputStreamSpi()
+ {
+ }
+
+
+ /**
+ * Constructs a service provider for image input streams, given the
+ * vendor name and a version string.
+ *
+ * @throws IllegalArgumentException if <code>vendorName</code>
+ * or <code>version</code> is <code>null</code>.
+ */
+ public ImageInputStreamSpi(String vendorName, String version,
+ Class inputClass)
+ {
+ super(vendorName, version);
+ this.inputClass = inputClass;
+ }
+
+
+ /**
+ * Determines which kind of input is processable by the streams
+ * created by {@link #createInputStreamInstance(Object)}.
+ */
+ public Class getInputClass()
+ {
+ return inputClass;
+ }
+
+
+ /**
+ * Determines whether <code>ImageInputStreams</code> created
+ * by this service provider benefit from using a cache file.
+ *
+ * <p>The default behavior is to return <code>false</code>.
+ *
+ * @return <code>true</code> if the created streams are faster or
+ * need less memory when a cache file is being used;
+ * <code>false</code> if no positive effect results from the cache
+ * file.
+ */
+ public boolean canUseCacheFile()
+ {
+ return false;
+ }
+
+
+ /**
+ * Determines whether <code>ImageInputStreams</code> created
+ * by this service provider require the use of a cache file.
+ *
+ * <p>The default behavior is to return <code>false</code>.
+ *
+ * @return <code>true</code> if the created streams can only work
+ * when a cache file is being used; <code>false</code> if no cache
+ * file is needed.
+ */
+ public boolean needsCacheFile()
+ {
+ return false;
+ }
+
+
+ public abstract ImageInputStream createInputStreamInstance(Object input,
+ boolean useCache,
+ File cacheDir)
+ throws IOException;
+
+
+ public ImageInputStream createInputStreamInstance(Object input)
+ throws IOException
+ {
+ return createInputStreamInstance(input, canUseCacheFile(), null);
+ }
+}
diff --git a/libjava/javax/imageio/spi/ImageOutputStreamSpi.java b/libjava/javax/imageio/spi/ImageOutputStreamSpi.java
new file mode 100644
index 00000000000..aa287c31378
--- /dev/null
+++ b/libjava/javax/imageio/spi/ImageOutputStreamSpi.java
@@ -0,0 +1,143 @@
+/* ImageOutputStreamSpi.java -- Service provider for image output streams.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.imageio.spi;
+
+import java.io.File;
+import java.io.IOException;
+import javax.imageio.stream.ImageOutputStream;
+
+
+/**
+ * An abstract superclass for service providers that create
+ * {@linkplain javax.imageio.stream.ImageOutputStream image output
+ * streams} for a file, URL, byte array or any other target.
+ *
+ * @since 1.4
+ *
+ * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a>
+ */
+public abstract class ImageOutputStreamSpi
+ extends IIOServiceProvider
+{
+ /**
+ * Indicates which kind of output is produced by the streams
+ * created by {@link #createOutputStreamInstance(Object)}.
+ */
+ protected Class outputClass;
+
+
+ /**
+ * Constructs a service provider for image output streams, given no
+ * parameters. It is up to the sub-class to set {@link #vendorName},
+ * {@link #version} and {@link #outputClass} to non-null values.
+ */
+ protected ImageOutputStreamSpi()
+ {
+ }
+
+
+ /**
+ * Constructs a service provider for image output streams, given the
+ * vendor name, a version string and the kind of producable output.
+ *
+ * @throws IllegalArgumentException if <code>vendorName</code>
+ * or <code>version</code> is <code>null</code>.
+ */
+ public ImageOutputStreamSpi(String vendorName, String version,
+ Class outputClass)
+ {
+ super(vendorName, version);
+ this.outputClass = outputClass;
+ }
+
+
+ /**
+ * Determines which kind of output is produced by the streams
+ * created by {@link #createOutputStreamInstance(Object)}.
+ */
+ public Class getOutputClass()
+ {
+ return outputClass;
+ }
+
+
+ /**
+ * Determines whether <code>ImageOutputStreams</code> created
+ * by this service provider benefit from using a cache file.
+ *
+ * <p>The default behavior is to return <code>false</code>.
+ *
+ * @return <code>true</code> if the created streams are faster or
+ * need less memory when a cache file is being used;
+ * <code>false</code> if no positive effect results from the cache
+ * file.
+ */
+ public boolean canUseCacheFile()
+ {
+ return false;
+ }
+
+
+ /**
+ * Determines whether <code>ImageOutputStreams</code> created
+ * by this service provider require the use of a cache file.
+ *
+ * <p>The default behavior is to return <code>false</code>.
+ *
+ * @return <code>true</code> if the created streams can only work
+ * when a cache file is being used; <code>false</code> if no cache
+ * file is needed.
+ */
+ public boolean needsCacheFile()
+ {
+ return false;
+ }
+
+
+ public abstract ImageOutputStream createOutputStreamInstance(
+ Object output, boolean useCache, File cacheDir)
+ throws IOException;
+
+
+ public ImageOutputStream createOutputStreamInstance(Object output)
+ throws IOException
+ {
+ return createOutputStreamInstance(output, canUseCacheFile(), null);
+ }
+}
diff --git a/libjava/javax/imageio/spi/ImageReaderWriterSpi.java b/libjava/javax/imageio/spi/ImageReaderWriterSpi.java
new file mode 100644
index 00000000000..74dbb3859bb
--- /dev/null
+++ b/libjava/javax/imageio/spi/ImageReaderWriterSpi.java
@@ -0,0 +1,425 @@
+/* ImageReaderWriterSpi.java -- Superclass for image reader and writer spis.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.imageio.spi;
+
+
+/**
+ * An abstract superclass that contains the common parts of {@link
+ * javax.imageio.spi.ImageReaderSpi} and {@link
+ * javax.imageio.spi.ImageWriterSpi}.
+ *
+ * @since 1.4
+ *
+ * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a>
+ */
+public abstract class ImageReaderWriterSpi
+ extends IIOServiceProvider
+{
+ /**
+ * The human-readable, localized names of the supported image
+ * formats. This value should be non-<code>null</code> after
+ * construction.
+ *
+ * @see #getFormatNames()
+ */
+ protected String[] names;
+
+
+ /**
+ * The file suffixes of the supported image formats. This value
+ * should be non-<code>null</code> after construction.
+ *
+ * @see #getFileSuffixes()
+ */
+ protected String[] suffixes;
+
+
+ /**
+ * The MIME types of the supported image formats. This value
+ * should be non-<code>null</code> after construction.
+ *
+ * @see #getMIMETypes()
+ */
+ protected String[] MIMETypes;
+
+
+ /**
+ * The fully qualified name of the class that implements the {@link
+ * javax.imageio.ImageReader} or {@link javax.imageio.ImageWriter}
+ * interface. This value should be non-<code>null</code> after
+ * construction.
+ *
+ * @see #getPluginClassName()
+ */
+ protected String pluginClassName;
+
+
+ /**
+ * Indicates whether the per-stream {@linkplain
+ * javax.imageio.metadata.IIOMetadata metadata objects} associated
+ * with this plug-in support format
+ * <code>&#x201c;javax_imageio_1.0&#x201d;</code> in their
+ * <code>getAsTree</code> and <code>setAsTree</code> methods.
+ *
+ * @see #isStandardStreamMetadataFormatSupported()
+ */
+ protected boolean supportsStandardStreamMetadataFormat;
+
+
+ /**
+ * The name of the format that allows encoding all stream metadata
+ * without loss, or <code>null</code> if this plug-in does not
+ * provide a format that preserves all stream metadata.
+ */
+ protected String nativeStreamMetadataFormatName;
+
+ protected String nativeStreamMetadataFormatClassName;
+
+
+ /**
+ * The names of additional formats for encoding stream metadata,
+ * other than the {@linkplain
+ * #isStandardStreamMetadataFormatSupported() standard} and the
+ * {@linkplain #getNativeStreamMetadataFormatName() native} formats,
+ * or <code>null</code> if this plug-in does not provide any extra
+ * formats.
+ */
+ protected String[] extraStreamMetadataFormatNames;
+
+
+ protected String[] extraStreamMetadataFormatClassNames;
+
+
+ /**
+ * Indicates whether the per-image {@linkplain
+ * javax.imageio.metadata.IIOMetadata metadata objects} associated
+ * with this plug-in support format
+ * <code>&#x201c;javax_imageio_1.0&#x201d;</code> in their
+ * <code>getAsTree</code> and <code>setAsTree</code> methods.
+ *
+ * @see #isStandardImageMetadataFormatSupported()
+ */
+ protected boolean supportsStandardImageMetadataFormat;
+
+
+ /**
+ * The name of the format that allows encoding all image metadata
+ * without loss, or <code>null</code> if this plug-in does not
+ * provide a format that preserves all image metadata.
+ */
+ protected String nativeImageMetadataFormatName;
+
+ protected String nativeImageMetadataFormatClassName;
+
+
+ /**
+ * The names of additional formats for encoding image metadata,
+ * other than the {@linkplain
+ * #isStandardImageMetadataFormatSupported() standard} and the
+ * {@linkplain #getNativeImageMetadataFormatName() native} formats,
+ * or <code>null</code> if this plug-in does not provide any extra
+ * formats.
+ */
+ protected String[] extraImageMetadataFormatNames;
+
+
+ protected String[] extraImageMetadataFormatClassNames;
+
+
+ /**
+ * Constructs an <code>ImageReaderWriteSpi</code> instance, without
+ * specifying a number of parameters. Constructors of concrete
+ * subclasses must ensure that they set all inherited fields to
+ * meaningful values.
+ */
+ public ImageReaderWriterSpi()
+ {
+ }
+
+
+ /**
+ * Constructs an <code>ImageReaderWriteSpi</code> instance,
+ * specifying a number of parameters.
+ *
+ * @param names the human-readable, localized names of the supported
+ * image formats, for example <code>[&#x201c;Tagged Image File
+ * Format&#x201d;, &#x201c;Portable Network
+ * Graphics&#x201d;]</code>.
+ *
+ * @param suffixes the file suffixes of the supported image formats,
+ * for example <code>[&#x201c;tiff&#x201d;, &#x201c;tif&#x201d;,
+ * &#x201c;png&#x201d;]</code>.
+ *
+ * @param MIMETypes the MIME types of the supported image formats,
+ * for example <code>[&#x201c;image/tiff&#x201d;,
+ * &#x201c;image/png&#x201d;]</code>.
+ *
+ * @param pluginClassName the fully qualified name of the class that
+ * implements the {@link javax.imageio.ImageReader} or {@link
+ * javax.imageio.ImageWriter} interface.
+ *
+ * @param supportsStandardStreamMetadataFormat whether the
+ * per-stream {@linkplain javax.imageio.metadata.IIOMetadata
+ * metadata objects} associated with this plug-in support format
+ * <code>&#x201c;javax_imageio_1.0&#x201d;</code> in their
+ * <code>getAsTree</code> and <code>setAsTree</code> methods.
+ *
+ * @param nativeStreamMetadataFormatName the name of the format that
+ * allows encoding all stream metadata without loss, or
+ * <code>null</code> if this plug-in does not provide a format that
+ * preserves all stream metadata.
+ *
+ * @param extraStreamMetadataFormatNames the names of additional
+ * formats for encoding stream metadata, other than the {@linkplain
+ * #isStandardStreamMetadataFormatSupported() standard} and the
+ * {@linkplain #getNativeStreamMetadataFormatName() native} formats,
+ * or <code>null</code> if this plug-in does not provide any extra
+ * formats.
+ *
+ * @param supportsStandardImageMetadataFormat whether the per-image
+ * {@linkplain javax.imageio.metadata.IIOMetadata metadata objects}
+ * associated with this plug-in support format
+ * <code>&#x201c;javax_imageio_1.0&#x201d;</code> in their
+ * <code>getAsTree</code> and <code>setAsTree</code> methods.
+ *
+ * @param nativeImageMetadataFormatName the name of the format that
+ * allows encoding all image metadata without loss, or
+ * <code>null</code> if this plug-in does not provide a format that
+ * preserves all image metadata.
+ *
+ * @param extraImageMetadataFormatNames the names of additional
+ * formats for encoding image metadata, other than the {@linkplain
+ * #isStandardImageMetadataFormatSupported() standard} and the
+ * {@linkplain #getNativeImageMetadataFormatName() native} formats,
+ * or <code>null</code> if this plug-in does not provide any extra
+ * formats.
+ *
+ * @throws IllegalArgumentException if <code>vendorName</code>
+ * or <code>version</code> is <code>null</code>.
+ */
+ public ImageReaderWriterSpi(String vendorName, String version,
+ String[] names, String[] suffixes,
+ String[] MIMETypes, String pluginClassName,
+ boolean supportsStandardStreamMetadataFormat,
+ String nativeStreamMetadataFormatName,
+ String nativeStreamMetadataFormatClassName,
+ String[] extraStreamMetadataFormatNames,
+ String[] extraStreamMetadataFormatClassNames,
+ boolean supportsStandardImageMetadataFormat,
+ String nativeImageMetadataFormatName,
+ String nativeImageMetadataFormatClassName,
+ String[] extraImageMetadataFormatNames,
+ String[] extraImageMetadataFormatClassNames)
+ {
+ /* The inherited constructor will throw IllegalArgumentException
+ * if one of its arguments is null.
+ */
+ super(vendorName, version);
+
+ if (names == null || names.length == 0 || pluginClassName == null)
+ throw new IllegalArgumentException();
+
+ this.names = names;
+ this.suffixes = suffixes;
+ this.MIMETypes = MIMETypes;
+ this.pluginClassName = pluginClassName;
+
+ this.supportsStandardStreamMetadataFormat
+ = supportsStandardStreamMetadataFormat;
+
+ this.nativeStreamMetadataFormatName
+ = nativeStreamMetadataFormatName;
+
+ this.nativeStreamMetadataFormatClassName
+ = nativeStreamMetadataFormatClassName;
+
+ this.extraStreamMetadataFormatNames
+ = extraStreamMetadataFormatNames;
+
+ this.extraStreamMetadataFormatClassNames
+ = extraStreamMetadataFormatClassNames;
+
+ this.supportsStandardImageMetadataFormat
+ = supportsStandardImageMetadataFormat;
+
+ this.nativeImageMetadataFormatName
+ = nativeImageMetadataFormatName;
+
+ this.nativeImageMetadataFormatClassName
+ = nativeImageMetadataFormatClassName;
+
+ this.extraImageMetadataFormatNames
+ = extraImageMetadataFormatNames;
+
+ this.extraImageMetadataFormatClassNames
+ = extraImageMetadataFormatClassNames;
+ }
+
+
+ /**
+ * Returns the human-readable, localized names of the supported
+ * image formats. For example, a plug-in might return an array with
+ * the elements <code>[&#x201c;Tagged Image File Format&#x201d;,
+ * &#x201c;Portable Network Graphics&#x201d;]</code>.
+ */
+ public String[] getFormatNames()
+ {
+ return (String[]) names.clone();
+ }
+
+
+ /**
+ * Returns the file suffixes of the supported image formats, for
+ * example <code>[&#x201c;tiff&#x201d;, &#x201c;tif&#x201d;,
+ * &#x201c;png&#x201d;]</code>.
+ */
+ public String[] getFileSuffixes()
+ {
+ return suffixes;
+ }
+
+
+ /**
+ * Returns the MIME types of the supported image formats, for
+ * example <code>[&#x201c;image/tiff&#x201d;,
+ * &#x201c;image/png&#x201d;]</code>.
+ *
+ * @return an array of MIME type strings, or <code>null</code> if
+ * none of the supported formats has an associated MIME type.
+ */
+ public String[] getMIMETypes()
+ {
+ return MIMETypes;
+ }
+
+
+ /**
+ * Returns the fully qualified name of the class that implements the
+ * {@link javax.imageio.ImageReader} or {@link
+ * javax.imageio.ImageWriter} interface.
+ */
+ public String getPluginClassName()
+ {
+ return pluginClassName;
+ }
+
+
+ /**
+ * Returns whether the per-stream {@linkplain
+ * javax.imageio.metadata.IIOMetadata metadata objects} associated
+ * with this plug-in support format
+ * <code>&#x201c;javax_imageio_1.0&#x201d;</code> in their
+ * <code>getAsTree</code> and <code>setAsTree</code> methods.
+ */
+ public boolean isStandardStreamMetadataFormatSupported()
+ {
+ return supportsStandardStreamMetadataFormat;
+ }
+
+
+ /**
+ * Returns the name of the format that allows encoding all stream
+ * metadata without loss, or <code>null</code> if this plug-in does
+ * not provide a format that preserves all stream metadata.
+ *
+ * @see #getNativeImageMetadataFormatName()
+ */
+ public String getNativeStreamMetadataFormatName()
+ {
+ return nativeStreamMetadataFormatName;
+ }
+
+
+ /**
+ * Returns the names of additional formats for encoding stream
+ * metadata, other than the {@linkplain
+ * #isStandardStreamMetadataFormatSupported() standard} and the
+ * {@linkplain #getNativeStreamMetadataFormatName() native} formats,
+ * or <code>null</code> if this plug-in does not provide any extra
+ * formats.
+ *
+ * @see #getExtraImageMetadataFormatNames()
+ */
+ public String[] getExtraStreamMetadataFormatNames()
+ {
+ return extraStreamMetadataFormatNames;
+ }
+
+
+ /**
+ * Returns whether the per-image {@linkplain
+ * javax.imageio.metadata.IIOMetadata metadata objects} associated
+ * with this plug-in support format
+ * <code>&#x201c;javax_imageio_1.0&#x201d;</code> in their
+ * <code>getAsTree</code> and <code>setAsTree</code> methods.
+ */
+ public boolean isStandardImageMetadataFormatSupported()
+ {
+ return supportsStandardImageMetadataFormat;
+ }
+
+
+ /**
+ * Returns the name of the format that allows encoding all image
+ * metadata without loss, or <code>null</code> if this plug-in does
+ * not provide a format that preserves all image metadata.
+ *
+ * @see #getNativeStreamMetadataFormatName()
+ */
+ public String getNativeImageMetadataFormatName()
+ {
+ return nativeImageMetadataFormatName;
+ }
+
+
+ /**
+ * Returns the names of additional formats for encoding image
+ * metadata, other than the {@linkplain
+ * #isStandardImageMetadataFormatSupported() standard} and the
+ * {@linkplain #getNativeImageMetadataFormatName() native} formats,
+ * or <code>null</code> if this plug-in does not provide any extra
+ * formats.
+ *
+ * @see #getExtraStreamMetadataFormatNames()
+ */
+ public String[] getExtraImageMetadataFormatNames()
+ {
+ return extraImageMetadataFormatNames;
+ }
+}
diff --git a/libjava/javax/imageio/spi/ImageTranscoderSpi.java b/libjava/javax/imageio/spi/ImageTranscoderSpi.java
new file mode 100644
index 00000000000..85ca77d4639
--- /dev/null
+++ b/libjava/javax/imageio/spi/ImageTranscoderSpi.java
@@ -0,0 +1,84 @@
+/* ImageTranscoderSpi.java -- Factory for image metadata transcoders.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.imageio.spi;
+
+import javax.imageio.ImageTranscoder;
+
+
+/**
+ * An abstract superclass for service providers that create
+ * {@linkplain javax.imageio.ImageTranscoder image metadata
+ * transcoders}.
+ *
+ * @since 1.4
+ *
+ * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a>
+ */
+public abstract class ImageTranscoderSpi
+ extends IIOServiceProvider
+{
+ /**
+ * Constructs a service provider for image metadata transcoders,
+ * given no parameters. It is up to the sub-class to set {@link
+ * #vendorName} and {@link #version} to non-null values.
+ */
+ protected ImageTranscoderSpi()
+ {
+ }
+
+
+ /**
+ * Constructs a service provider for image metadata transcoders,
+ * given the vendor name and a version string.
+ *
+ * @throws IllegalArgumentException if <code>vendorName</code>
+ * or <code>version</code> is <code>null</code>.
+ */
+ public ImageTranscoderSpi(String vendorName, String version)
+ {
+ super(vendorName, version);
+ }
+
+
+ public abstract String getReaderServiceProviderName();
+
+ public abstract String getWriterServiceProviderName();
+
+ public abstract ImageTranscoder createTranscoderInstance();
+}
diff --git a/libjava/javax/imageio/spi/RegisterableService.java b/libjava/javax/imageio/spi/RegisterableService.java
new file mode 100644
index 00000000000..40cb05f81ac
--- /dev/null
+++ b/libjava/javax/imageio/spi/RegisterableService.java
@@ -0,0 +1,83 @@
+/* RegisterableService.java -- An interface for service providers.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.imageio.spi;
+
+
+/**
+ * An interface which service providers may optionally implement in
+ * order to get notified when they are added or removed from a {@link
+ * ServiceRegistry}.
+ *
+ * @since 1.4
+ *
+ * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a>
+ */
+public interface RegisterableService
+{
+ /**
+ * Informs this service provider that it has been registered in a
+ * {@link ServiceRegistry}. If this provider gets registered as an
+ * implementor for several service categories, its
+ * <code>onRegistration</code> method will be called multiple times.
+ *
+ * @param registry the registry to which this service provider has
+ * been added.
+ *
+ * @param category the service category for which this provider has
+ * been registered as an implementor.
+ */
+ void onRegistration(ServiceRegistry registry, Class category);
+
+
+ /**
+ * Informs this service provider that it has been de-registered from
+ * a {@link ServiceRegistry}. If this provider had been registered
+ * as an implementor for several service categories, its
+ * <code>onDeregistration</code> method will be called multiple
+ * times.
+ *
+ * @param registry the registry from which this service provider has
+ * been removed.
+ *
+ * @param category the service category for which this provider has
+ * been registered as an implementor.
+ */
+ void onDeregistration(ServiceRegistry registry, Class category);
+}
+
diff --git a/libjava/javax/imageio/spi/ServiceRegistry.java b/libjava/javax/imageio/spi/ServiceRegistry.java
new file mode 100644
index 00000000000..c41e1b5a75e
--- /dev/null
+++ b/libjava/javax/imageio/spi/ServiceRegistry.java
@@ -0,0 +1,948 @@
+/* ServiceRegistry.java -- A simple registry for service providers.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.imageio.spi;
+
+import java.util.*;
+import gnu.classpath.ServiceFactory;
+
+
+/**
+ * A registry for service providers.
+ *
+ * @since 1.4
+ *
+ * @author <a href="mailto:konqueror@gmx.de">Michael Koch</a>
+ * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a>
+ */
+public class ServiceRegistry
+{
+ /**
+ * The service categories of this registry.
+ *
+ * <p>Note that we expect that only very few categories will
+ * typically be used with a registry. The most common case will be
+ * one, it seems unlikely that any registry would contain more than
+ * five or six categories. Therefore, we intentionally avoid the
+ * overhead of a HashMap.
+ *
+ * @see #providers
+ */
+ private final Class[] categories;
+
+
+ /**
+ * The registered providers for each service category, indexed by
+ * the same index as the {@link #categories} array. If no provider
+ * is registered for a category, the array entry will be
+ * <code>null</code>.
+ *
+ * <p>Note that we expect that only very few providers will
+ * typically be registered for a category. The most common case will
+ * be one or two. Therefore, we intentionally avoid the overhead of
+ * a HashMap.
+ */
+ private final LinkedList[] providers;
+
+
+ /**
+ * The ordring constaints for each service category, indexed by the
+ * same index as the {@link #categories} array. The constraints for
+ * a service category are stored as a <code>Map&lt;Object,
+ * Set&lt;Object&gt;&gt;</code>, where the Map&#x2019;s values are
+ * those providers that need to come after the key. If no
+ * constraints are imposed on the providers of a category, the array
+ * entry will be <code>null</code>. If no constraints have been set
+ * whatsoever, <code>constraints</code> will be <code>null</code>.
+ *
+ * <p>Note that we expect that only very few constraints will
+ * typically be imposed on a category. The most common case will
+ * be zero.
+ */
+ private IdentityHashMap[] constraints;
+
+
+ /**
+ * Constructs a <code>ServiceRegistry</code> for the specified
+ * service categories.
+ *
+ * @throws IllegalArgumentException if <code>categories</code> is
+ * <code>null</code>, or if its {@link Iterator#next()} method
+ * returns <code>null</code>.
+ *
+ * @throws ClassCastException if <code>categories</code> does not
+ * iterate over instances of {@link java.lang.Class}.
+ */
+ public ServiceRegistry(Iterator categories)
+ {
+ ArrayList cats = new ArrayList(/* expected size */ 10);
+
+ if (categories == null)
+ throw new IllegalArgumentException();
+
+ while (categories.hasNext())
+ {
+ Class cat = (Class) categories.next();
+ if (cat == null)
+ throw new IllegalArgumentException();
+ cats.add(cat);
+ }
+
+ int numCats = cats.size();
+ this.categories = (Class[]) cats.toArray(new Class[numCats]);
+ this.providers = new LinkedList[numCats];
+ }
+
+
+ /**
+ * Finds service providers that are implementing the specified
+ * Service Provider Interface.
+ *
+ * <p><b>On-demand loading:</b> Loading and initializing service
+ * providers is delayed as much as possible. The rationale is that
+ * typical clients will iterate through the set of installed service
+ * providers until one is found that matches some criteria (like
+ * supported formats, or quality of service). In such scenarios, it
+ * might make sense to install only the frequently needed service
+ * providers on the local machine. More exotic providers can be put
+ * onto a server; the server will only be contacted when no suitable
+ * service could be found locally.
+ *
+ * <p><b>Security considerations:</b> Any loaded service providers
+ * are loaded through the specified ClassLoader, or the system
+ * ClassLoader if <code>classLoader</code> is
+ * <code>null</code>. When <code>lookupProviders</code> is called,
+ * the current {@link java.security.AccessControlContext} gets
+ * recorded. This captured security context will determine the
+ * permissions when services get loaded via the <code>next()</code>
+ * method of the returned <code>Iterator</code>.
+ *
+ * @param spi the service provider interface which must be
+ * implemented by any loaded service providers.
+ *
+ * @param loader the class loader that will be used to load the
+ * service providers, or <code>null</code> for the system class
+ * loader. For using the context class loader, see {@link
+ * #lookupProviders(Class)}.
+ *
+ * @return an iterator over instances of <code>spi</code>.
+ *
+ * @throws IllegalArgumentException if <code>spi</code> is
+ * <code>null</code>.
+ */
+ public static Iterator lookupProviders(Class spi,
+ ClassLoader loader)
+ {
+ return ServiceFactory.lookupProviders(spi, loader);
+ }
+
+
+ /**
+ * Finds service providers that are implementing the specified
+ * Service Provider Interface, using the context class loader
+ * for loading providers.
+ *
+ * @param spi the service provider interface which must be
+ * implemented by any loaded service providers.
+ *
+ * @return an iterator over instances of <code>spi</code>.
+ *
+ * @throws IllegalArgumentException if <code>spi</code> is
+ * <code>null</code>.
+ *
+ * @see #lookupProviders(Class, ClassLoader)
+ */
+ public static Iterator lookupProviders(Class spi)
+ {
+ return ServiceFactory.lookupProviders(spi);
+ }
+
+
+ /**
+ * Returns an iterator over all service categories.
+ *
+ * @return an unmodifiable {@link
+ * java.util.Iterator}&lt;{@link java.lang.Class}&gt;.
+ */
+ public Iterator getCategories()
+ {
+ return new Iterator()
+ {
+ int index = -1;
+
+ public boolean hasNext()
+ {
+ return index < categories.length - 1;
+ }
+
+ public Object next()
+ {
+ if (!hasNext())
+ throw new NoSuchElementException();
+
+ return categories[++index];
+ }
+
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+
+ /**
+ * Registers a provider for a service category which is specified by
+ * the class-internal category ID.
+ *
+ * @param provider the service provider to be registered.
+ *
+ * @param cat the service category, which is identified by an index
+ * into the {@link #categories} array.
+ *
+ * @return <code>true</code> if <code>provider</code> is the first
+ * provider that gets registered for the specified service category;
+ * <code>false</code> if other providers have already been
+ * registered for the same servide category.
+ *
+ * @throws IllegalArgumentException if <code>provider</code> is
+ * <code>null</code>.
+ *
+ * @throws ClassCastException if <code>provider</code> does not
+ * implement the specified service provider interface.
+ */
+ private synchronized boolean registerServiceProvider(Object provider,
+ int cat)
+ {
+ LinkedList provs;
+ boolean result;
+ Class category;
+
+ if (provider == null)
+ throw new IllegalArgumentException();
+
+ category = categories[cat];
+ if (!category.isInstance(provider))
+ throw new ClassCastException(category.getName());
+
+ provs = providers[cat];
+ if (provs == null)
+ {
+ result = true;
+ provs = providers[cat] = new LinkedList();
+ }
+ else
+ result = false;
+
+ provs.add(provider);
+ if (provider instanceof RegisterableService)
+ ((RegisterableService) provider).onRegistration(this, category);
+
+ return result;
+ }
+
+
+ /**
+ * Registers a provider for the specified service category.
+ *
+ * <p>If <code>provider</code> implements the {@link
+ * RegisterableService} interface, its {@link
+ * RegisterableService#onRegistration onRegistration} method is
+ * invoked in order to inform the provider about the addition to
+ * this registry.
+ *
+ * @param provider the service provider to be registered.
+ *
+ * @param category the service category under which
+ * <code>provider</code> shall be registered.
+ *
+ * @return <code>true</code> if <code>provider</code> is the first
+ * provider that gets registered for the specified service category;
+ * <code>false</code> if other providers have already been
+ * registered for the same servide category.
+ *
+ * @throws IllegalArgumentException if <code>provider</code> is
+ * <code>null</code>, or if <code>category</code> is not among the
+ * categories passed to the {@linkplain #ServiceRegistry(Iterator)
+ * constructor} of this ServiceRegistry.
+ *
+ * @throws ClassCastException if <code>provider</code> does not
+ * implement <code>category</code>.
+ */
+ public synchronized boolean registerServiceProvider(Object provider,
+ Class category)
+ {
+ for (int i = 0; i < categories.length; i++)
+ if (categories[i] == category)
+ return registerServiceProvider(provider, i);
+ throw new IllegalArgumentException();
+ }
+
+
+ /**
+ * Registers a provider under all service categories it
+ * implements.
+ *
+ * <p>If <code>provider</code> implements the {@link
+ * RegisterableService} interface, its {@link
+ * RegisterableService#onRegistration onRegistration} method is
+ * invoked in order to inform the provider about the addition to
+ * this registry. If <code>provider</code> implements several
+ * service categories, <code>onRegistration</code> gets called
+ * multiple times.
+ *
+ * @param provider the service provider to be registered.
+ *
+ * @throws IllegalArgumentException if <code>provider</code> is
+ * <code>null</code>, or if <code>provider</code> does not implement
+ * any of the service categories passed to the {@linkplain
+ * #ServiceRegistry(Iterator) constructor} of this ServiceRegistry.
+ */
+ public synchronized void registerServiceProvider(Object provider)
+ {
+ boolean ok = false;
+
+ if (provider == null)
+ throw new IllegalArgumentException();
+
+ for (int i = 0; i < categories.length; i++)
+ if (categories[i].isInstance(provider))
+ {
+ ok = true;
+ registerServiceProvider(provider, i);
+ }
+
+ if (!ok)
+ throw new IllegalArgumentException();
+ }
+
+
+ /**
+ * Registers a number of providers under all service categories they
+ * implement.
+ *
+ * <p>If a provider implements the {@link RegisterableService}
+ * interface, its {@link RegisterableService#onRegistration
+ * onRegistration} method is invoked in order to inform the provider
+ * about the addition to this registry. If <code>provider</code>
+ * implements several service categories,
+ * <code>onRegistration</code> gets called multiple times.
+ *
+ * @throws IllegalArgumentException if <code>providers</code> is
+ * <code>null</code>, if any iterated provider is <code>null</code>,
+ * or if some iterated provider does not implement any of the
+ * service categories passed to the {@linkplain
+ * #ServiceRegistry(Iterator) constructor} of this
+ * <code>ServiceRegistry</code>.
+ */
+ public synchronized void registerServiceProviders(Iterator providers)
+ {
+ if (providers == null)
+ throw new IllegalArgumentException();
+
+ while (providers.hasNext())
+ registerServiceProvider(providers.next());
+ }
+
+
+ /**
+ * De-registers a provider for a service category which is specified
+ * by the class-internal category ID.
+ *
+ * @param provider the service provider to be registered.
+ *
+ * @param cat the service category, which is identified by an index
+ * into the {@link #categories} array.
+ *
+ * @return <code>true</code> if <code>provider</code> was previously
+ * registered for the specified service category; <code>false</code>
+ * if if the provider had not been registered.
+ *
+ * @throws IllegalArgumentException if <code>provider</code> is
+ * <code>null</code>.
+ *
+ * @throws ClassCastException if <code>provider</code> does not
+ * implement the specified service provider interface.
+ */
+ private synchronized boolean deregisterServiceProvider(Object provider,
+ int cat)
+ {
+ LinkedList provs;
+ boolean result;
+ Class category;
+
+ if (provider == null)
+ throw new IllegalArgumentException();
+
+ category = categories[cat];
+ if (!category.isInstance(provider))
+ throw new ClassCastException(category.getName());
+
+ provs = providers[cat];
+ if (provs == null)
+ return false;
+
+ result = provs.remove(provider);
+ if (provs.isEmpty())
+ providers[cat] = null;
+
+ if (result && (provider instanceof RegisterableService))
+ ((RegisterableService) provider).onDeregistration(this, category);
+
+ return result;
+ }
+
+
+ /**
+ * De-registers a provider for the specified service category.
+ *
+ * <p>If <code>provider</code> implements the {@link
+ * RegisterableService} interface, its {@link
+ * RegisterableService#onDeregistration onDeregistration} method is
+ * invoked in order to inform the provider about the removal from
+ * this registry.
+ *
+ * @param provider the service provider to be de-registered.
+ *
+ * @param category the service category from which
+ * <code>provider</code> shall be de-registered.
+ *
+ * @return <code>true</code> if <code>provider</code> was previously
+ * registered for the specified service category; <code>false</code>
+ * if if the provider had not been registered.
+ *
+ * @throws IllegalArgumentException if <code>provider</code> is
+ * <code>null</code>, or if <code>category</code> is not among the
+ * categories passed to the {@linkplain #ServiceRegistry(Iterator)
+ * constructor} of this ServiceRegistry.
+ *
+ * @throws ClassCastException if <code>provider</code> does not
+ * implement <code>category</code>.
+ */
+ public synchronized boolean deregisterServiceProvider(Object provider,
+ Class category)
+ {
+ for (int i = 0; i < categories.length; i++)
+ if (categories[i] == category)
+ return deregisterServiceProvider(provider, i);
+ throw new IllegalArgumentException();
+ }
+
+
+ /**
+ * De-registers a provider from all service categories it
+ * implements.
+ *
+ * <p>If <code>provider</code> implements the {@link
+ * RegisterableService} interface, its {@link
+ * RegisterableService#onDeregistration onDeregistration} method is
+ * invoked in order to inform the provider about the removal from
+ * this registry. If <code>provider</code> implements several
+ * service categories, <code>onDeregistration</code> gets called
+ * multiple times.
+ *
+ * @param provider the service provider to be de-registered.
+ *
+ * @throws IllegalArgumentException if <code>provider</code> is
+ * <code>null</code>, or if <code>provider</code> does not implement
+ * any of the service categories passed to the {@linkplain
+ * #ServiceRegistry(Iterator) constructor} of this
+ * <code>ServiceRegistry</code>.
+ */
+ public synchronized void deregisterServiceProvider(Object provider)
+ {
+ boolean ok = false;
+
+ if (provider == null)
+ throw new IllegalArgumentException();
+
+ for (int i = 0; i < categories.length; i++)
+ if (categories[i].isInstance(provider))
+ {
+ ok = true;
+ deregisterServiceProvider(provider, i);
+ }
+
+ if (!ok)
+ throw new IllegalArgumentException();
+ }
+
+
+ /**
+ * De-registers all providers which have been registered for the
+ * specified service category.
+ *
+ * <p>If a provider implements the {@link RegisterableService}
+ * interface, its {@link RegisterableService#onDeregistration
+ * onDeregistration} method is invoked in order to inform the
+ * provider about the removal from this registry. If the provider
+ * implements several service categories,
+ * <code>onDeregistration</code> gets called multiple times.
+ *
+ * @param category the category whose registered providers will be
+ * de-registered.
+ *
+ * @throws IllegalArgumentException if <code>category</code> is not
+ * among the categories passed to the {@linkplain
+ * #ServiceRegistry(Iterator) constructor} of this
+ * <code>ServiceRegistry</code>.
+ */
+ public synchronized void deregisterAll(Class category)
+ {
+ boolean ok = false;
+
+ for (int i = 0; i < categories.length; i++)
+ {
+ if (categories[i] != category)
+ continue;
+
+ ok = true;
+ while (providers[i] != null)
+ deregisterServiceProvider(providers[i].get(0), i);
+ }
+
+ if (!ok)
+ throw new IllegalArgumentException();
+ }
+
+
+ /**
+ * De-registers all service providers.
+ *
+ * <p>If a provider implements the {@link RegisterableService}
+ * interface, its {@link RegisterableService#onDeregistration
+ * onDeregistration} method is invoked in order to inform the
+ * provider about the removal from this registry. If the provider
+ * implements several service categories,
+ * <code>onDeregistration</code> gets called multiple times.
+ */
+ public synchronized void deregisterAll()
+ {
+ for (int i = 0; i < categories.length; i++)
+ while (providers[i] != null)
+ deregisterServiceProvider(providers[i].get(0), i);
+ }
+
+
+ /**
+ * Called by the Virtual Machine when it detects that this
+ * <code>ServiceRegistry</code> has become garbage. De-registers all
+ * service providers, which will cause those that implement {@link
+ * RegisterableService} to receive a {@link
+ * RegisterableService#onDeregistration onDeregistration}
+ * notification.
+ */
+ public void finalize()
+ throws Throwable
+ {
+ super.finalize();
+ deregisterAll();
+ }
+
+
+ /**
+ * Determines whether a provider has been registered with this
+ * registry.
+ *
+ * @return <code>true</code> if <code>provider</code> has been
+ * registered under any service category; <code>false</code> if
+ * it is not registered.
+ *
+ * @throws IllegalArgumentException if <code>provider</code> is
+ * <code>null</code>.
+ */
+ public synchronized boolean contains(Object provider)
+ {
+ if (provider == null)
+ throw new IllegalArgumentException();
+
+ // Note that contains is rather unlikely to be ever called,
+ // so it would be wasteful to keep a special data structure
+ // (such as a HashSet) for making it a fast operation.
+ for (int i = 0; i < providers.length; i++)
+ {
+ // If provider does not implement categories[i],
+ // it would not have been possible to register it there.
+ // In that case, it would be pointless to look there.
+ if (!categories[i].isInstance(provider))
+ continue;
+
+ // But if the list of registered providers contains provider,
+ // we have found it.
+ LinkedList p = providers[i];
+ if (p != null && p.contains(provider))
+ return true;
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Returns the index in {@link #categories} occupied by the
+ * specified service category.
+ *
+ * @throws IllegalArgumentException if <code>category</code> is not
+ * among the categories passed to the {@linkplain
+ * #ServiceRegistry(Iterator) constructor} of this ServiceRegistry.
+ */
+ private int getCategoryID(Class category)
+ {
+ for (int i = 0; i < categories.length; i++)
+ if (categories[i] == category)
+ return i;
+
+ throw new IllegalArgumentException();
+ }
+
+
+ /**
+ * Retrieves all providers that have been registered for the
+ * specified service category.
+ *
+ * @param category the service category whose providers are
+ * to be retrieved.
+ *
+ * @param useOrdering <code>true</code> in order to retrieve the
+ * providers in an order imposed by the {@linkplain #setOrdering
+ * ordering constraints}; <code>false</code> in order to retrieve
+ * the providers in any order.
+ *
+ * @throws IllegalArgumentException if <code>category</code> is not
+ * among the categories passed to the {@linkplain
+ * #ServiceRegistry(Iterator) constructor} of this
+ * <code>ServiceRegistry</code>.
+ *
+ * @see #getServiceProviders(Class, Filter, boolean)
+ */
+ public Iterator getServiceProviders(Class category, boolean useOrdering)
+ {
+ return getServiceProviders(category, null, useOrdering);
+ }
+
+
+ /**
+ * Retrieves all providers that have been registered for the
+ * specified service category and that satisfy the criteria
+ * of a custom filter.
+ *
+ * @param category the service category whose providers are
+ * to be retrieved.
+ *
+ * @param filter a custom filter, or <code>null</code> to
+ * retrieve all registered providers for the specified
+ * category.
+ *
+ * @param useOrdering <code>true</code> in order to retrieve the
+ * providers in an order imposed by the {@linkplain #setOrdering
+ * ordering constraints}; <code>false</code> in order to retrieve
+ * the providers in any order.
+ *
+ * @throws IllegalArgumentException if <code>category</code> is not
+ * among the categories passed to the {@linkplain
+ * #ServiceRegistry(Iterator) constructor} of this
+ * <code>ServiceRegistry</code>.
+ */
+ public synchronized Iterator getServiceProviders(Class category,
+ Filter filter,
+ boolean useOrdering)
+ {
+ int catid;
+ LinkedList provs;
+ ArrayList result;
+
+ catid = getCategoryID(category);
+ provs = providers[catid];
+ if (provs == null)
+ return Collections.EMPTY_LIST.iterator();
+
+ result = new ArrayList(provs.size());
+ for (Iterator iter = provs.iterator(); iter.hasNext();)
+ {
+ Object provider = iter.next();
+ if (filter == null || filter.filter(provider))
+ result.add(provider);
+ }
+
+ // If we are supposed to obey ordering constraints, and
+ // if any constraints have been imposed on the specified
+ // service category, sort the result.
+ if (useOrdering && constraints != null)
+ {
+ final Map cons = constraints[catid];
+ if (cons != null)
+ Collections.sort(result, new Comparator()
+ {
+ public int compare(Object o1, Object o2)
+ {
+ Set s;
+
+ if (o1 == o2)
+ return 0;
+
+ s = (Set) cons.get(o1);
+ if (s != null && s.contains(o2))
+ return -1; // o1 < o2
+
+ s = (Set) cons.get(o2);
+ if (s != null && s.contains(o1))
+ return 1; // o1 > o2
+
+ return 0; // o1 == o2
+ }
+ });
+ }
+
+ return result.iterator();
+ }
+
+
+ /**
+ * Returns one of the service providers that is a subclass of the
+ * specified class.
+ *
+ * @param providerClass a class to search for.
+ */
+ public synchronized Object getServiceProviderByClass(Class providerClass)
+ {
+ if (providerClass == null)
+ throw new IllegalArgumentException();
+
+ // Note that the method getServiceProviderByClass is rather
+ // unlikely to be ever called, so it would be wasteful to keep a
+ // special data structure for making it a fast operation.
+ for (int cat = 0; cat < categories.length; cat++)
+ {
+ if (!categories[cat].isAssignableFrom(providerClass))
+ continue;
+
+ LinkedList provs = providers[cat];
+ if (provs == null)
+ continue;
+
+ for (Iterator iter = provs.iterator(); iter.hasNext();)
+ {
+ Object provider = iter.next();
+ if (providerClass.isInstance(provider))
+ return provider;
+ }
+ }
+
+ return null;
+ }
+
+
+ /**
+ * Adds an ordering constraint on service providers.
+ *
+ * @param category the service category to which an ordering
+ * constraint is to be added.
+ *
+ * @param first the provider which is supposed to come before
+ * <code>second</code>.
+ *
+ * @param second the provider which is supposed to come after
+ * <code>first</code>.
+ *
+ * @throws IllegalArgumentException if <code>first</code> and
+ * <code>second</code> are referring to the same object, or if one
+ * of them is <code>null</code>.
+ *
+ * @see #unsetOrdering
+ * @see #getServiceProviders(Class, Filter, boolean)
+ */
+ public synchronized boolean setOrdering(Class category,
+ Object firstProvider,
+ Object secondProvider)
+ {
+ return addConstraint(getCategoryID(category), firstProvider,
+ secondProvider);
+ }
+
+
+ /**
+ * Removes an ordering constraint on service providers.
+ *
+ * @param category the service category from which an ordering
+ * constraint is to be removed.
+ *
+ * @param first the provider which is supposed to come before
+ * <code>second</code>.
+ *
+ * @param second the provider which is supposed to come after
+ * <code>first</code>.
+ *
+ * @throws IllegalArgumentException if <code>first</code> and
+ * <code>second</code> are referring to the same object, or if one
+ * of them is <code>null</code>.
+ *
+ * @see #setOrdering
+ */
+ public synchronized boolean unsetOrdering(Class category,
+ Object firstProvider,
+ Object secondProvider)
+ {
+ return removeConstraint(getCategoryID(category),
+ firstProvider, secondProvider);
+ }
+
+
+ /**
+ * Adds an ordering constraint on service providers.
+ *
+ * @param catid the service category ID, which is the
+ * category&#x2019;s index into the {@link #categories} array.
+ *
+ * @param first the provider which is supposed to come before
+ * <code>second</code>.
+ *
+ * @param second the provider which is supposed to come after
+ * <code>first</code>.
+ *
+ * @throws IllegalArgumentException if <code>first</code> and
+ * <code>second</code> are referring to the same object, or if one
+ * of them is <code>null</code>.
+ */
+ private boolean addConstraint(int catid, Object first, Object second)
+ {
+ Set s;
+ IdentityHashMap cons;
+
+ // Also checks argument validity.
+ removeConstraint(catid, second, first);
+
+ if (constraints == null)
+ constraints = new IdentityHashMap[categories.length];
+ cons = constraints[catid];
+ if (cons == null)
+ cons = constraints[catid] = new IdentityHashMap();
+
+ s = (Set) cons.get(first);
+ if (s == null)
+ cons.put(first, s = new HashSet());
+ return s.add(second);
+ }
+
+
+ /**
+ * Removes an ordering constraint on service providers.
+ *
+ * @param catid the service category ID, which is the
+ * category&#x2019;s index into the {@link #categories} array.
+ *
+ * @param first the provider which is supposed to come before
+ * <code>second</code>.
+ *
+ * @param second the provider which is supposed to come after
+ * <code>first</code>.
+ *
+ * @throws IllegalArgumentException if <code>first</code> and
+ * <code>second</code> are referring to the same object, or if one
+ * of them is <code>null</code>.
+ */
+ private boolean removeConstraint(int catid, Object first, Object second)
+ {
+ Collection s;
+ IdentityHashMap cons;
+
+ if (first == null || second == null || first == second)
+ throw new IllegalArgumentException();
+
+ if (constraints == null)
+ return false;
+
+ cons = constraints[catid];
+ if (cons == null)
+ return false;
+
+ s = (Collection) cons.get(first);
+ if (s == null)
+ return false;
+
+ if (!s.remove(second))
+ return false;
+
+ // If we removed the last constraint for a service category,
+ // we can get free some memory.
+ if (cons.isEmpty())
+ {
+ constraints[catid] = null;
+ boolean anyConstraints = false;
+ for (int i = 0; i < constraints.length; i++)
+ {
+ if (constraints[i] != null)
+ {
+ anyConstraints = true;
+ break;
+ }
+ }
+ if (!anyConstraints)
+ constraints = null;
+ }
+
+ return true;
+ }
+
+
+ /**
+ * A filter for selecting service providers that match custom
+ * criteria.
+ *
+ * @see ServiceRegistry#getServiceProviders(Class, Filter,
+ * boolean)
+ *
+ * @since 1.4
+ *
+ * @author <a href="mailto:konqueror@gmx.de">Michael Koch</a>
+ * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a>
+ */
+ public static interface Filter
+ {
+ /**
+ * Checks whether the specified service provider matches the
+ * constraints of this Filter.
+ *
+ * @param provider the service provider in question.
+ *
+ * @return <code>true</code> if <code>provider</code> matches the
+ * criteria; <code>false</code> if it does not match.
+ */
+ boolean filter(Object provider);
+ };
+}
+
diff --git a/libjava/javax/imageio/spi/package.html b/libjava/javax/imageio/spi/package.html
new file mode 100644
index 00000000000..5c0779e6876
--- /dev/null
+++ b/libjava/javax/imageio/spi/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in javax.imageio.spi package.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - javax.imageio.spi</title></head>
+
+<body>
+<p></p>
+
+</body>
+</html>
diff --git a/libjava/javax/imageio/stream/IIOByteBuffer.java b/libjava/javax/imageio/stream/IIOByteBuffer.java
new file mode 100644
index 00000000000..c9e230f5f79
--- /dev/null
+++ b/libjava/javax/imageio/stream/IIOByteBuffer.java
@@ -0,0 +1,94 @@
+/* IIOByteBuffer.java
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.imageio.stream;
+
+/**
+ * A data structure for holding a reference to a byte array, an index
+ * into that array, and a number of bytes, that can be passed to one
+ * specific variant of the {@link
+ * javax.imageio.stream.ImageInputStream#readBytes(IIOByteBuffer, int)
+ * readBytes} method.
+ *
+ * @since 1.4
+ *
+ * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a>
+ */
+public class IIOByteBuffer
+{
+ private byte[] data;
+ private int offset;
+ private int length;
+
+ public IIOByteBuffer(byte[] data, int offset, int length)
+ {
+ this.data = data;
+ this.offset = offset;
+ this.length = length;
+ }
+
+ public byte[] getData()
+ {
+ return data;
+ }
+
+ public void setData(byte[] data)
+ {
+ this.data = data;
+ }
+
+ public int getOffset()
+ {
+ return offset;
+ }
+
+ public void setOffset(int offset)
+ {
+ this.offset = offset;
+ }
+
+ public int getLength()
+ {
+ return length;
+ }
+
+ public void setLength(int length)
+ {
+ this.length = length;
+ }
+}
diff --git a/libjava/javax/imageio/stream/ImageInputStream.java b/libjava/javax/imageio/stream/ImageInputStream.java
new file mode 100644
index 00000000000..d37231dd7a7
--- /dev/null
+++ b/libjava/javax/imageio/stream/ImageInputStream.java
@@ -0,0 +1,651 @@
+/* ImageInputStream.java
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.imageio.stream;
+
+import java.io.DataInput;
+import java.io.IOException;
+import java.nio.ByteOrder;
+
+
+/**
+ * An input stream for use by {@link javax.imageio.ImageReader
+ * ImageReaders}.
+ *
+ * @since 1.4
+ *
+ * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a>
+ */
+public interface ImageInputStream
+ extends DataInput
+{
+ void setByteOrder(ByteOrder order);
+
+ ByteOrder getByteOrder();
+
+ int read()
+ throws IOException;
+
+ int read(byte[] b)
+ throws IOException;
+
+ int read(byte[] b, int offset, int length)
+ throws IOException;
+
+
+ /**
+ * Reads up to a specified number of bytes, and modifies a
+ * {@link IIOByteBuffer} to hold the read data.
+ *
+ * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
+ * before any data is read.
+ *
+ * @param buf an <code>IIOByteBuffer</code> that will hold the read
+ * data.
+ *
+ * @param numBytes the maximum number of bytes to read.
+ *
+ * @throws IndexOutOfBoundsException if <code>numBytes</code> is
+ * negative.
+ *
+ * @throws NullPointerException if <code>buf</code> is
+ * <code>null</code>.
+ *
+ * @throws IOException if some general problem happens with
+ * accessing data.
+ */
+ void readBytes(IIOByteBuffer buf, int numBytes)
+ throws IOException;
+
+
+ /**
+ * Reads a byte and checks whether or not its value is zero.
+ *
+ * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
+ * before the byte is read.
+ *
+ * @throws EOFException if the input stream is at its end.
+ *
+ * @throws IOException if some general problem happens with
+ * accessing data.
+ *
+ * @see #readBit()
+ * @see #readByte()
+ * @see #readFully(byte[], int, int)
+ */
+ boolean readBoolean()
+ throws IOException;
+
+
+ /**
+ * Reads a signed byte.
+ *
+ * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
+ * before any data is read.
+ *
+ * @throws EOFException if the input stream is at its end.
+ *
+ * @throws IOException if some general problem happens with
+ * accessing data.
+ *
+ * @see #readUnsignedByte()
+ * @see #readFully(byte[], int, int)
+ */
+ byte readByte()
+ throws IOException;
+
+
+ /**
+ * Reads an unsigned byte.
+ *
+ * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
+ * before any data is read.
+ *
+ * @throws EOFException if the input stream is at its end.
+ *
+ * @throws IOException if some general problem happens with
+ * accessing data.
+ *
+ * @see #readByte()
+ * @see #readFully(byte[], int, int)
+ */
+ int readUnsignedByte()
+ throws IOException;
+
+
+ /**
+ * Reads an signed 16-bit integer. If necessary, the value gets
+ * converted from the stream&#x2019;s {@linkplain #getByteOrder()
+ * current byte order}.
+ *
+ * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
+ * before any data is read.
+ *
+ * @throws EOFException if the input stream ends before all two
+ * bytes were read.
+ *
+ * @throws IOException if some general problem happens with
+ * accessing data.
+ *
+ * @see #readUnsignedShort()
+ * @see #readChar()
+ * @see #readFully(short[], int, int)
+ */
+ short readShort()
+ throws IOException;
+
+
+ /**
+ * Reads an unsigned 16-bit integer. If necessary, the value gets
+ * converted from the stream&#x2019;s {@linkplain #getByteOrder()
+ * current byte order}.
+ *
+ * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
+ * before any data is read.
+ *
+ * <p>This method does the same as {@link #readChar()}.
+ *
+ * @throws EOFException if the input stream ends before all two
+ * bytes were read.
+ *
+ * @throws IOException if some general problem happens with
+ * accessing data.
+ *
+ * @see #readShort()
+ * @see #readChar()
+ * @see #readFully(char[], int, int)
+ */
+ int readUnsignedShort()
+ throws IOException;
+
+
+ /**
+ * Reads an unsigned 16-bit integer. If necessary, the value gets
+ * converted from the stream&#x2019;s {@linkplain #getByteOrder()
+ * current byte order}.
+ *
+ * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
+ * before any data is read.
+ *
+ * <p>This method does the same as {@link #readUnsignedShort()}.
+ *
+ * @throws EOFException if the input stream ends before all two
+ * bytes were read.
+ *
+ * @throws IOException if some general problem happens with
+ * accessing data.
+ *
+ * @see #readFully(char[], int, int)
+ */
+ char readChar()
+ throws IOException;
+
+
+ /**
+ * Reads a signed 32-bit integer. If necessary, the value gets
+ * converted from the stream&#x2019;s {@linkplain #getByteOrder()
+ * current byte order}.
+ *
+ * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
+ * before any data is read.
+ *
+ * @throws EOFException if the input stream ends before all four
+ * bytes were read.
+ *
+ * @throws IOException if some general problem happens with
+ * accessing data.
+ *
+ * @see #readUnsignedInt()
+ * @see #readFully(int[], int, int)
+ */
+ int readInt()
+ throws IOException;
+
+
+ /**
+ * Reads an unsigned 32-bit integer. If necessary, the value gets
+ * converted from the stream&#x2019;s {@linkplain #getByteOrder()
+ * current byte order}.
+ *
+ * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
+ * before any data is read.
+ *
+ * @throws EOFException if the input stream ends before all four
+ * bytes were read.
+ *
+ * @throws IOException if some general problem happens with
+ * accessing data.
+ *
+ * @see #readInt()
+ * @see #readFully(int[], int, int)
+ */
+ long readUnsignedInt()
+ throws IOException;
+
+
+ /**
+ * Reads a signed 64-bit integer. If necessary, the value gets
+ * converted from the stream&#x2019;s {@linkplain #getByteOrder()
+ * current byte order}.
+ *
+ * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
+ * before any data is read.
+ *
+ * @throws EOFException if the input stream ends before all eight
+ * bytes were read.
+ *
+ * @throws IOException if some general problem happens with
+ * accessing data.
+ *
+ * @see #readFully(long[], int, int)
+ */
+ long readLong()
+ throws IOException;
+
+
+ /**
+ * Reads an IEEE 32-bit single-precision floating point number. If
+ * necessary, the value gets converted from the stream&#x2019;s
+ * {@linkplain #getByteOrder() current byte order}.
+ *
+ * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
+ * before any data is read.
+ *
+ * @throws EOFException if the input stream ends before all four
+ * bytes were read.
+ *
+ * @throws IOException if some general problem happens with
+ * accessing data.
+ *
+ * @see #readFully(float[], int, int)
+ */
+ float readFloat()
+ throws IOException;
+
+
+ /**
+ * Reads an IEEE 64-bit double-precision floating point number. If
+ * necessary, the value gets converted from the stream&#x2019;s
+ * {@linkplain #getByteOrder() current byte order}.
+ *
+ * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
+ * before any data is read.
+ *
+ * @throws EOFException if the input stream ends before all eight
+ * bytes were read.
+ *
+ * @throws IOException if some general problem happens with
+ * accessing data.
+ *
+ * @see #readFully(double[], int, int)
+ */
+ double readDouble()
+ throws IOException;
+
+ String readLine()
+ throws IOException;
+
+ String readUTF()
+ throws IOException;
+
+
+ /**
+ * Reads a sequence of signed 8-bit integers into a
+ * <code>byte[]</code> array.
+ *
+ * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
+ * before any data is read.
+ *
+ * @param b an array for storing the read values.
+ *
+ * @param offset the index of the first element in <code>b</code>
+ * that will hold read data.
+ *
+ * @param numBytes the number of bytes to read.
+ *
+ * @throws IndexOutOfBoundsException if <code>offset</code> or
+ * <code>numBytes</code> is negative, or if <code>offset +
+ * numBytes</code> exceeds <code>b.length</code>.
+ *
+ * @throws NullPointerException if <code>b</code> is
+ * <code>null</code>.
+ *
+ * @throws EOFException if the input stream ends before all content
+ * was read.
+ *
+ * @throws IOException if some general problem happens with
+ * accessing data.
+ *
+ * @see #readByte()
+ */
+ void readFully(byte[] b, int offset, int numBytes)
+ throws IOException;
+
+
+ /**
+ * Reads a sequence of signed 8-bit integers into a
+ * <code>byte[]</code> array.
+ *
+ * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
+ * before any data is read.
+ *
+ * @param b an array for storing the read values.
+ *
+ * @throws NullPointerException if <code>b</code> is
+ * <code>null</code>.
+ *
+ * @throws EOFException if the input stream ends before all content
+ * was read.
+ *
+ * @throws IOException if some general problem happens with
+ * accessing data.
+ *
+ * @see #readByte()
+ * @see #readFully(byte[], int, int)
+ */
+ void readFully(byte[] b)
+ throws IOException;
+
+
+ /**
+ * Reads a sequence of signed 16-bit integers into a
+ * <code>short[]</code> array. If necessary, values are converted
+ * from the stream&#x2019;s {@linkplain #getByteOrder() current byte
+ * order}.
+ *
+ * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
+ * before any data is read.
+ *
+ * @param s an array for storing the read values.
+ *
+ * @param offset the index of the first element in <code>s</code>
+ * that will hold read data.
+ *
+ * @param numShorts the number of signed 16-bit integers to read
+ * (which is one half of the number of bytes).
+ *
+ * @throws IndexOutOfBoundsException if <code>offset</code> or
+ * <code>numShorts</code> is negative, or if <code>offset +
+ * numShorts</code> exceeds <code>s.length</code>.
+ *
+ * @throws NullPointerException if <code>s</code> is
+ * <code>null</code>.
+ *
+ * @throws EOFException if the input stream ends before all content
+ * was read.
+ *
+ * @throws IOException if some general problem happens with
+ * accessing data.
+ *
+ * @see #readShort()
+ */
+ void readFully(short[] s, int offset, int numShorts)
+ throws IOException;
+
+
+ /**
+ * Reads a sequence of unsigned 16-bit integers into a
+ * <code>char[]</code> array. If necessary, values are converted
+ * from the stream&#x2019;s {@linkplain #getByteOrder() current byte
+ * order}.
+ *
+ * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
+ * before any data is read.
+ *
+ * @param c an array for storing the read values.
+ *
+ * @param offset the index of the first element in <code>c</code>
+ * that will hold read data.
+ *
+ * @param numChars the number of unsigned 16-bit integers to read
+ * (which is one half of the number of bytes).
+ *
+ * @throws IndexOutOfBoundsException if <code>offset</code> or
+ * <code>numChars</code> is negative, or if <code>offset +
+ * numChars</code> exceeds <code>c.length</code>.
+ *
+ * @throws NullPointerException if <code>c</code> is
+ * <code>null</code>.
+ *
+ * @throws EOFException if the input stream ends before all content
+ * was read.
+ *
+ * @throws IOException if some general problem happens with
+ * accessing data.
+ *
+ * @see #readChar()
+ */
+ void readFully(char[] c, int offset, int numChars)
+ throws IOException;
+
+
+ /**
+ * Reads a sequence of signed 32-bit integers into a
+ * <code>long[]</code> array. If necessary, values are converted
+ * from the stream&#x2019;s {@linkplain #getByteOrder() current byte
+ * order}.
+ *
+ * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
+ * before any data is read.
+ *
+ * @param i an array for storing the read values.
+ *
+ * @param offset the index of the first element in <code>i</code>
+ * that will hold read data.
+ *
+ * @param numLongs the number of signed 32-bit integers to read
+ * (which is one fourth of the number of bytes).
+ *
+ * @throws IndexOutOfBoundsException if <code>offset</code> or
+ * <code>numInts</code> is negative, or if <code>offset +
+ * numInts</code> exceeds <code>i.length</code>.
+ *
+ * @throws NullPointerException if <code>i</code> is
+ * <code>null</code>.
+ *
+ * @throws EOFException if the input stream ends before all content
+ * was read.
+ *
+ * @throws IOException if some general problem happens with
+ * accessing data.
+ *
+ * @see #readInt()
+ */
+ void readFully(int[] i, int offset, int numInts)
+ throws IOException;
+
+
+ /**
+ * Reads a sequence of signed 64-bit integers into a
+ * <code>long[]</code> array. If necessary, values are converted
+ * from the stream&#x2019;s {@linkplain #getByteOrder() current byte
+ * order}.
+ *
+ * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
+ * before any data is read.
+ *
+ * @param l an array for storing the read values.
+ *
+ * @param offset the index of the first element in <code>l</code>
+ * that will hold read data.
+ *
+ * @param numLongs the number of signed 64-bit integers to read
+ * (which is one eight of the number of bytes).
+ *
+ * @throws IndexOutOfBoundsException if <code>offset</code> or
+ * <code>numLongs</code> is negative, or if <code>offset +
+ * numLongs</code> exceeds <code>l.length</code>.
+ *
+ * @throws NullPointerException if <code>l</code> is
+ * <code>null</code>.
+ *
+ * @throws EOFException if the input stream ends before all content
+ * was read.
+ *
+ * @throws IOException if some general problem happens with
+ * accessing data.
+ *
+ * @see #readLong()
+ */
+ void readFully(long[] l, int offset, int numLongs)
+ throws IOException;
+
+
+ /**
+ * Reads a sequence of IEEE 32-bit single-precision floating point
+ * numbers into a <code>float[]</code> array. If necessary, values
+ * are converted from the stream&#x2019;s {@linkplain
+ * #getByteOrder() current byte order}.
+ *
+ * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
+ * before any data is read.
+ *
+ * @param d an array for storing the read values.
+ *
+ * @param offset the index of the first element in <code>d</code>
+ * that will hold read data.
+ *
+ * @param numFloats the number of IEEE 32-bit single-precision
+ * floating point numbers to read (which is one fourth of the number
+ * of bytes).
+ *
+ * @throws IndexOutOfBoundsException if <code>offset</code> or
+ * <code>numFloats</code> is negative, or if <code>offset +
+ * numFloats</code> exceeds <code>f.length</code>.
+ *
+ * @throws NullPointerException if <code>f</code> is
+ * <code>null</code>.
+ *
+ * @throws EOFException if the input stream ends before all content
+ * was read.
+ *
+ * @throws IOException if some general problem happens with
+ * accessing data.
+ *
+ * @see #readFloat()
+ */
+ void readFully(float[] f, int offset, int numFloats)
+ throws IOException;
+
+
+ /**
+ * Reads a sequence of IEEE 64-bit double-precision floating point
+ * numbers into a <code>double[]</code> array. If necessary, values
+ * are converted from the stream&#x2019;s {@linkplain
+ * #getByteOrder() current byte order}.
+ *
+ * <p>The {@linkplain #getBitOffset() bit offset} is set to zero
+ * before any data is read.
+ *
+ * @param d an array for storing the read values.
+ *
+ * @param offset the index of the first element in <code>d</code>
+ * that will hold read data.
+ *
+ * @param numDoubles the number of IEEE 64-bit double-precision
+ * floating point numbers to read (which is one eight of the number
+ * of bytes).
+ *
+ * @throws IndexOutOfBoundsException if <code>offset</code> or
+ * <code>numDoubles</code> is negative, or if <code>offset +
+ * numDoubles</code> exceeds <code>d.length</code>.
+ *
+ * @throws NullPointerException if <code>d</code> is
+ * <code>null</code>.
+ *
+ * @throws EOFException if the input stream ends before all content
+ * was read.
+ *
+ * @throws IOException if some general problem happens with
+ * accessing data.
+ *
+ * @see #readDouble()
+ */
+ void readFully(double[] d, int offset, int numDoubles)
+ throws IOException;
+
+ long getStreamPosition()
+ throws IOException;
+
+ int getBitOffset()
+ throws IOException;
+
+ void setBitOffset(int bitOffset)
+ throws IOException;
+
+ int readBit()
+ throws IOException;
+
+ long readBits(int numBits)
+ throws IOException;
+
+ long length()
+ throws IOException;
+
+ int skipBytes(int numBytes)
+ throws IOException;
+
+ long skipBytes(long numBytes)
+ throws IOException;
+
+ void seek(long pos)
+ throws IOException;
+
+ void mark()
+ throws IOException;
+
+ void reset()
+ throws IOException;
+
+ void flushBefore(long pos)
+ throws IOException;
+
+ void flush()
+ throws IOException;
+
+ long getFlushedPosition();
+
+ boolean isCached();
+
+ boolean isCachedMemory();
+
+ boolean isCachedFile();
+
+ void close()
+ throws IOException;
+}
diff --git a/libjava/javax/imageio/stream/ImageOutputStream.java b/libjava/javax/imageio/stream/ImageOutputStream.java
new file mode 100644
index 00000000000..58a65944aa3
--- /dev/null
+++ b/libjava/javax/imageio/stream/ImageOutputStream.java
@@ -0,0 +1,58 @@
+/* ImageOutputStream.java
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.imageio.stream;
+
+import java.io.DataOutput;
+
+
+/**
+ * An output stream for use by {@link javax.imageio.ImageWriter
+ * ImageWriters}.
+ *
+ * @since 1.4
+ *
+ * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a>
+ */
+public interface ImageOutputStream
+ extends ImageInputStream, DataOutput
+{
+ // FIXME: Incomplete. This interface is merely present in order to
+ // allow compilation of the javax.imageio.spi package, for which GNU
+ // Classpath does provide an implementation.
+}
diff --git a/libjava/javax/imageio/stream/package.html b/libjava/javax/imageio/stream/package.html
new file mode 100644
index 00000000000..5449c123752
--- /dev/null
+++ b/libjava/javax/imageio/stream/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in javax.imageio.stream package.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. -->
+
+<html>
+<head><title>GNU Classpath - javax.imageio.stream</title></head>
+
+<body>
+<p></p>
+
+</body>
+</html>
diff --git a/libjava/javax/naming/AuthenticationException.java b/libjava/javax/naming/AuthenticationException.java
index 112dd612e6f..63bfb4b8eaa 100644
--- a/libjava/javax/naming/AuthenticationException.java
+++ b/libjava/javax/naming/AuthenticationException.java
@@ -1,5 +1,5 @@
/* AuthenticationException.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
public class AuthenticationException extends NamingSecurityException
{
diff --git a/libjava/javax/naming/AuthenticationNotSupportedException.java b/libjava/javax/naming/AuthenticationNotSupportedException.java
index 6409e6490fa..e14fed92e5c 100644
--- a/libjava/javax/naming/AuthenticationNotSupportedException.java
+++ b/libjava/javax/naming/AuthenticationNotSupportedException.java
@@ -1,5 +1,5 @@
/* AuthenticationNotSupportedException.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
public class AuthenticationNotSupportedException
extends NamingSecurityException
diff --git a/libjava/javax/naming/CannotProceedException.java b/libjava/javax/naming/CannotProceedException.java
index f98541876d9..0fe382b73aa 100644
--- a/libjava/javax/naming/CannotProceedException.java
+++ b/libjava/javax/naming/CannotProceedException.java
@@ -1,5 +1,5 @@
/* CannotProceedException.java --
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
import java.util.Hashtable;
/**
diff --git a/libjava/javax/naming/CommunicationException.java b/libjava/javax/naming/CommunicationException.java
index 8731be15acb..4a22922f1a5 100644
--- a/libjava/javax/naming/CommunicationException.java
+++ b/libjava/javax/naming/CommunicationException.java
@@ -1,5 +1,5 @@
/* CommunicationException.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
public class CommunicationException extends NamingException
{
diff --git a/libjava/javax/naming/CompoundName.java b/libjava/javax/naming/CompoundName.java
index 4df89e9af95..4908d1bed6d 100644
--- a/libjava/javax/naming/CompoundName.java
+++ b/libjava/javax/naming/CompoundName.java
@@ -1,5 +1,5 @@
/* CompoundName.java --
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,8 +40,8 @@ package javax.naming;
import java.io.Serializable;
import java.util.Enumeration;
-import java.util.Properties;
import java.util.NoSuchElementException;
+import java.util.Properties;
import java.util.Vector;
/**
@@ -264,7 +264,7 @@ public class CompoundName implements Name, Cloneable, Serializable
int delta = elts.size () - cn.elts.size ();
for (int i = 0; i < cn.elts.size (); ++i)
{
- String f = canonicalize ((String) elts.get (i));
+ String f = canonicalize ((String) elts.get (delta + i));
if (! f.equals (canonicalize ((String) cn.elts.get (i))))
return false;
}
diff --git a/libjava/javax/naming/ConfigurationException.java b/libjava/javax/naming/ConfigurationException.java
index 7df4603c5a0..f8dad9459ec 100644
--- a/libjava/javax/naming/ConfigurationException.java
+++ b/libjava/javax/naming/ConfigurationException.java
@@ -1,5 +1,5 @@
/* ConfigurationException.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
public class ConfigurationException extends NamingException
{
diff --git a/libjava/javax/naming/ContextNotEmptyException.java b/libjava/javax/naming/ContextNotEmptyException.java
index 74204db54ba..b77080c8f33 100644
--- a/libjava/javax/naming/ContextNotEmptyException.java
+++ b/libjava/javax/naming/ContextNotEmptyException.java
@@ -1,5 +1,5 @@
/* ContextNotEmptyException.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
public class ContextNotEmptyException extends NamingException
{
diff --git a/libjava/javax/naming/InitialContext.java b/libjava/javax/naming/InitialContext.java
index e2a1ac6b63f..889a79dde27 100644
--- a/libjava/javax/naming/InitialContext.java
+++ b/libjava/javax/naming/InitialContext.java
@@ -1,5 +1,5 @@
/* InitialContext.java --
- Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,14 +39,13 @@ exception statement from your version. */
package javax.naming;
import java.applet.Applet;
-import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
+
import javax.naming.spi.NamingManager;
public class InitialContext implements Context
diff --git a/libjava/javax/naming/InsufficientResourcesException.java b/libjava/javax/naming/InsufficientResourcesException.java
index 120033dd143..d2cb27fee6c 100644
--- a/libjava/javax/naming/InsufficientResourcesException.java
+++ b/libjava/javax/naming/InsufficientResourcesException.java
@@ -1,5 +1,5 @@
/* InsufficientResourcesException.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
public class InsufficientResourcesException extends NamingException
{
diff --git a/libjava/javax/naming/InterruptedNamingException.java b/libjava/javax/naming/InterruptedNamingException.java
index e5ad1f864af..d9e3d4c588f 100644
--- a/libjava/javax/naming/InterruptedNamingException.java
+++ b/libjava/javax/naming/InterruptedNamingException.java
@@ -1,5 +1,5 @@
/* InterruptedNamingException.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
public class InterruptedNamingException extends NamingException
{
diff --git a/libjava/javax/naming/LimitExceededException.java b/libjava/javax/naming/LimitExceededException.java
index 4bbbb0f496a..4fff2af2d0a 100644
--- a/libjava/javax/naming/LimitExceededException.java
+++ b/libjava/javax/naming/LimitExceededException.java
@@ -1,5 +1,5 @@
/* LimitExceededException.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
public class LimitExceededException extends NamingException
{
diff --git a/libjava/javax/naming/LinkException.java b/libjava/javax/naming/LinkException.java
index 46ea6bd0b14..2b0524d91eb 100644
--- a/libjava/javax/naming/LinkException.java
+++ b/libjava/javax/naming/LinkException.java
@@ -1,5 +1,5 @@
/* LinkException.java --
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
/**
* @author Warren Levy <warrenl@redhat.com>
diff --git a/libjava/javax/naming/LinkLoopException.java b/libjava/javax/naming/LinkLoopException.java
index 0c2bdddd876..43fc0ce1a1d 100644
--- a/libjava/javax/naming/LinkLoopException.java
+++ b/libjava/javax/naming/LinkLoopException.java
@@ -1,5 +1,5 @@
/* LinkLoopException.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
public class LinkLoopException extends LinkException
{
diff --git a/libjava/javax/naming/LinkRef.java b/libjava/javax/naming/LinkRef.java
index 51b0f1bf771..53597d38fc7 100644
--- a/libjava/javax/naming/LinkRef.java
+++ b/libjava/javax/naming/LinkRef.java
@@ -1,5 +1,5 @@
/* LinkRef.java --
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.io.Serializable;
/**
* @author Tom Tromey <tromey@redhat.com>
diff --git a/libjava/javax/naming/MalformedLinkException.java b/libjava/javax/naming/MalformedLinkException.java
index 5233e772365..56e13e054c1 100644
--- a/libjava/javax/naming/MalformedLinkException.java
+++ b/libjava/javax/naming/MalformedLinkException.java
@@ -1,5 +1,5 @@
/* MalformedLinkException.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
public class MalformedLinkException extends LinkException
{
diff --git a/libjava/javax/naming/Name.java b/libjava/javax/naming/Name.java
index f2dc17ffaf4..0d4a2ed53f6 100644
--- a/libjava/javax/naming/Name.java
+++ b/libjava/javax/naming/Name.java
@@ -1,5 +1,5 @@
/* Name.java -- Name build up from different components
- Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,8 +37,8 @@ exception statement from your version. */
package javax.naming;
-import java.util.Enumeration;
import java.io.Serializable;
+import java.util.Enumeration;
/**
* Interface descriping a name build up from different components.
diff --git a/libjava/javax/naming/NameAlreadyBoundException.java b/libjava/javax/naming/NameAlreadyBoundException.java
index 2b57436285a..dbde071bd96 100644
--- a/libjava/javax/naming/NameAlreadyBoundException.java
+++ b/libjava/javax/naming/NameAlreadyBoundException.java
@@ -1,5 +1,5 @@
/* NameAlreadyBoundException.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
public class NameAlreadyBoundException extends NamingException
{
diff --git a/libjava/javax/naming/NameNotFoundException.java b/libjava/javax/naming/NameNotFoundException.java
index cb22ab371e2..d0d1fff0094 100644
--- a/libjava/javax/naming/NameNotFoundException.java
+++ b/libjava/javax/naming/NameNotFoundException.java
@@ -1,5 +1,5 @@
/* NameNotFoundException.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
public class NameNotFoundException extends NamingException
{
diff --git a/libjava/javax/naming/NamingException.java b/libjava/javax/naming/NamingException.java
index 0cb2d5547cd..e0aef0a5e2f 100644
--- a/libjava/javax/naming/NamingException.java
+++ b/libjava/javax/naming/NamingException.java
@@ -93,7 +93,7 @@ public class NamingException extends Exception
/**
* Creates a new NamingException without a message. Does not set any of the
* <code>rootException</code>, <code>resolvedName</code>,
- * <code>resolvedObj</code> or <code>remainingObject,<code> fields.
+ * <code>resolvedObj</code> or <code>remainingObject</code> fields.
* These fields can be set later.
*/
public NamingException ()
@@ -104,7 +104,7 @@ public class NamingException extends Exception
/**
* Creates a new NamingException with a detailed message. Does not set
* the <code>rootException</code>, <code>resolvedName</code>,
- * <code>resolvedObj</code> or <code>remainingObject,<code> fields.
+ * <code>resolvedObj</code> or <code>remainingObject,</code> fields.
* These fields can be set later.
*/
public NamingException (String msg)
diff --git a/libjava/javax/naming/NamingSecurityException.java b/libjava/javax/naming/NamingSecurityException.java
index 5972f56b052..1860a0e0a2c 100644
--- a/libjava/javax/naming/NamingSecurityException.java
+++ b/libjava/javax/naming/NamingSecurityException.java
@@ -1,5 +1,5 @@
/* NamingSecurityException.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
public abstract class NamingSecurityException extends NamingException
{
diff --git a/libjava/javax/naming/NoInitialContextException.java b/libjava/javax/naming/NoInitialContextException.java
index a1220dfb879..7139fd2b2cf 100644
--- a/libjava/javax/naming/NoInitialContextException.java
+++ b/libjava/javax/naming/NoInitialContextException.java
@@ -1,5 +1,5 @@
/* NoInitialContextException.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
public class NoInitialContextException extends NamingException
{
diff --git a/libjava/javax/naming/NoPermissionException.java b/libjava/javax/naming/NoPermissionException.java
index 261b7ff2614..9de1c7a6908 100644
--- a/libjava/javax/naming/NoPermissionException.java
+++ b/libjava/javax/naming/NoPermissionException.java
@@ -1,5 +1,5 @@
/* NoPermissionException.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
public class NoPermissionException extends NamingSecurityException
{
diff --git a/libjava/javax/naming/NotContextException.java b/libjava/javax/naming/NotContextException.java
index 87edeb31967..d480eed20b5 100644
--- a/libjava/javax/naming/NotContextException.java
+++ b/libjava/javax/naming/NotContextException.java
@@ -1,5 +1,5 @@
/* NotContextException.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
public class NotContextException extends NamingException
{
diff --git a/libjava/javax/naming/PartialResultException.java b/libjava/javax/naming/PartialResultException.java
index 6f323d59dcf..2f5a0645f41 100644
--- a/libjava/javax/naming/PartialResultException.java
+++ b/libjava/javax/naming/PartialResultException.java
@@ -1,5 +1,5 @@
/* PartialResultException.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
public class PartialResultException extends NamingException
{
diff --git a/libjava/javax/naming/ReferralException.java b/libjava/javax/naming/ReferralException.java
index 1be6c6649e4..63e83030cd5 100644
--- a/libjava/javax/naming/ReferralException.java
+++ b/libjava/javax/naming/ReferralException.java
@@ -1,5 +1,5 @@
/* ReferralException.java --
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
import java.util.Hashtable;
/**
diff --git a/libjava/javax/naming/ServiceUnavailableException.java b/libjava/javax/naming/ServiceUnavailableException.java
index 43aee5354f7..389197a15cd 100644
--- a/libjava/javax/naming/ServiceUnavailableException.java
+++ b/libjava/javax/naming/ServiceUnavailableException.java
@@ -1,5 +1,5 @@
/* ServiceUnavailableException.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
public class ServiceUnavailableException extends NamingException
{
diff --git a/libjava/javax/naming/SizeLimitExceededException.java b/libjava/javax/naming/SizeLimitExceededException.java
index 5d4414f7bf4..aad7903e863 100644
--- a/libjava/javax/naming/SizeLimitExceededException.java
+++ b/libjava/javax/naming/SizeLimitExceededException.java
@@ -1,5 +1,5 @@
/* SizeLimitExceededException.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
public class SizeLimitExceededException extends LimitExceededException
{
diff --git a/libjava/javax/naming/TimeLimitExceededException.java b/libjava/javax/naming/TimeLimitExceededException.java
index dc8dadf1e33..5baf5bf9ec4 100644
--- a/libjava/javax/naming/TimeLimitExceededException.java
+++ b/libjava/javax/naming/TimeLimitExceededException.java
@@ -1,5 +1,5 @@
/* TimeLimitExceededException.java --
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming;
-import java.lang.Exception;
public class TimeLimitExceededException extends LimitExceededException
{
diff --git a/libjava/javax/naming/directory/Attribute.java b/libjava/javax/naming/directory/Attribute.java
index 48118b01294..f812f166284 100644
--- a/libjava/javax/naming/directory/Attribute.java
+++ b/libjava/javax/naming/directory/Attribute.java
@@ -1,5 +1,5 @@
/* Attribute.java --
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,8 +39,7 @@ exception statement from your version. */
package javax.naming.directory;
import java.io.Serializable;
-import javax.naming.Context;
-import javax.naming.Name;
+
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
diff --git a/libjava/javax/naming/directory/Attributes.java b/libjava/javax/naming/directory/Attributes.java
index f1c673a76ec..b0ee5cdc45e 100644
--- a/libjava/javax/naming/directory/Attributes.java
+++ b/libjava/javax/naming/directory/Attributes.java
@@ -1,5 +1,5 @@
/* Attributes.java --
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,8 +39,7 @@ exception statement from your version. */
package javax.naming.directory;
import java.io.Serializable;
-import javax.naming.Context;
-import javax.naming.Name;
+
import javax.naming.NamingEnumeration;
/**
diff --git a/libjava/javax/naming/directory/SearchControls.java b/libjava/javax/naming/directory/SearchControls.java
index 21b97403f65..2b040d91fff 100644
--- a/libjava/javax/naming/directory/SearchControls.java
+++ b/libjava/javax/naming/directory/SearchControls.java
@@ -1,5 +1,5 @@
/* SearchControls.java --
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -44,7 +44,7 @@ import java.io.Serializable;
* @date June 5, 2001
*/
-public class SearchControls extends Object implements Serializable
+public class SearchControls implements Serializable
{
public static final int OBJECT_SCOPE = 0;
public static final int ONELEVEL_SCOPE = 1;
diff --git a/libjava/javax/naming/directory/SearchResult.java b/libjava/javax/naming/directory/SearchResult.java
index 74c38876f70..eb4c182e21a 100644
--- a/libjava/javax/naming/directory/SearchResult.java
+++ b/libjava/javax/naming/directory/SearchResult.java
@@ -1,5 +1,5 @@
/* SearchResult.java --
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.naming.directory;
-import java.io.Serializable;
import javax.naming.Binding;
/**
diff --git a/libjava/javax/naming/event/NamingExceptionEvent.java b/libjava/javax/naming/event/NamingExceptionEvent.java
index 3cbb19fa2ef..17b71d92963 100644
--- a/libjava/javax/naming/event/NamingExceptionEvent.java
+++ b/libjava/javax/naming/event/NamingExceptionEvent.java
@@ -1,5 +1,5 @@
/* NamingExceptionEvent.java --
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,8 +39,7 @@ exception statement from your version. */
package javax.naming.event;
import java.util.EventObject;
-import javax.naming.Context;
-import javax.naming.Name;
+
import javax.naming.NamingException;
/**
diff --git a/libjava/javax/naming/spi/DirStateFactory.java b/libjava/javax/naming/spi/DirStateFactory.java
index 756a060b02c..67e790d47ad 100644
--- a/libjava/javax/naming/spi/DirStateFactory.java
+++ b/libjava/javax/naming/spi/DirStateFactory.java
@@ -1,5 +1,5 @@
/* DirStateFactory.java --
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
diff --git a/libjava/javax/naming/spi/ResolveResult.java b/libjava/javax/naming/spi/ResolveResult.java
index c1e3ad9930b..25dd8494e70 100644
--- a/libjava/javax/naming/spi/ResolveResult.java
+++ b/libjava/javax/naming/spi/ResolveResult.java
@@ -1,5 +1,5 @@
/* ResolveResult.java --
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,10 +39,10 @@ exception statement from your version. */
package javax.naming.spi;
import java.io.Serializable;
-import java.util.EventObject;
-import javax.naming.Name;
+
import javax.naming.CompositeName;
import javax.naming.InvalidNameException;
+import javax.naming.Name;
/**
* @author Warren Levy <warrenl@redhat.com>
diff --git a/libjava/javax/print/attribute/EnumSyntax.java b/libjava/javax/print/attribute/EnumSyntax.java
index 4a87c975a6f..aa82ccc6bb8 100644
--- a/libjava/javax/print/attribute/EnumSyntax.java
+++ b/libjava/javax/print/attribute/EnumSyntax.java
@@ -139,7 +139,7 @@ public abstract class EnumSyntax implements Cloneable, Serializable
return null;
}
- public int getOffset()
+ protected int getOffset()
{
return 0;
}
diff --git a/libjava/javax/print/attribute/HashAttributeSet.java b/libjava/javax/print/attribute/HashAttributeSet.java
index 63b4105cb42..af5b3d188f3 100644
--- a/libjava/javax/print/attribute/HashAttributeSet.java
+++ b/libjava/javax/print/attribute/HashAttributeSet.java
@@ -151,7 +151,7 @@ public class HashAttributeSet implements AttributeSet, Serializable
* @exception ClassCastException if any element of attributes is not an
* interface of interfaceName
*/
- public HashAttributeSet(AttributeSet attributes, Class interfaceName)
+ protected HashAttributeSet(AttributeSet attributes, Class interfaceName)
{
this(interfaceName);
diff --git a/libjava/javax/print/attribute/ResolutionSyntax.java b/libjava/javax/print/attribute/ResolutionSyntax.java
index 592d995df7d..4eba85499ff 100644
--- a/libjava/javax/print/attribute/ResolutionSyntax.java
+++ b/libjava/javax/print/attribute/ResolutionSyntax.java
@@ -104,7 +104,7 @@ public abstract class ResolutionSyntax
*
* @return the resolution
*
- * @exception IllegalArgumenException if units < 1
+ * @exception IllegalArgumentException if units < 1
*/
public int getCrossFeedResolution(int units)
{
@@ -130,7 +130,7 @@ public abstract class ResolutionSyntax
*
* @return the resolution
*
- * @exception IllegalArgumenException if units < 1
+ * @exception IllegalArgumentException if units < 1
*/
public int getFeedResolution(int units)
{
diff --git a/libjava/javax/print/attribute/SetOfIntegerSyntax.java b/libjava/javax/print/attribute/SetOfIntegerSyntax.java
index d4e7fde00c2..7c022125f45 100644
--- a/libjava/javax/print/attribute/SetOfIntegerSyntax.java
+++ b/libjava/javax/print/attribute/SetOfIntegerSyntax.java
@@ -148,8 +148,8 @@ public abstract class SetOfIntegerSyntax
* @param lowerBound the lower bound value
* @param upperBound the upper bound value
*
- * @exception IllegalArgumentException if lowerBound <= uppbound
- * and lowerBound < 0
+ * @exception IllegalArgumentException if lowerBound &lt;= upperbound
+ * and lowerBound &lt; 0
*/
protected SetOfIntegerSyntax(int lowerBound, int upperBound)
{
diff --git a/libjava/javax/print/attribute/TextSyntax.java b/libjava/javax/print/attribute/TextSyntax.java
index 51909be9803..ebad88b6541 100644
--- a/libjava/javax/print/attribute/TextSyntax.java
+++ b/libjava/javax/print/attribute/TextSyntax.java
@@ -1,5 +1,5 @@
/* TextSyntax.java --
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -57,12 +57,12 @@ public abstract class TextSyntax implements Cloneable, Serializable
* @param value the value for this syntax
* @param locale the locale to use
*
- * @exception NullPointerException if value is null
+ * @exception NullPointerException if value and/or locale is null
*/
protected TextSyntax(String value, Locale locale)
{
- if (value == null)
- throw new NullPointerException("value may not be null");
+ if (value == null || locale == null)
+ throw new NullPointerException("value and/or locale may not be null");
this.value = value;
this.locale = locale;
@@ -95,7 +95,7 @@ public abstract class TextSyntax implements Cloneable, Serializable
*/
public int hashCode()
{
- return value.hashCode() + locale.hashCode();
+ return value.hashCode() ^ locale.hashCode();
}
/**
@@ -103,7 +103,7 @@ public abstract class TextSyntax implements Cloneable, Serializable
*
* @param obj the object to test
*
- * @returns true if both objects are equal, false otherwise.
+ * @return true if both objects are equal, false otherwise.
*/
public boolean equals(Object obj)
{
@@ -115,4 +115,12 @@ public abstract class TextSyntax implements Cloneable, Serializable
return (value.equals(tmp.getValue())
&& locale.equals(tmp.getLocale()));
}
+
+ /**
+ * Returns a string representing the object.
+ */
+ public String toString()
+ {
+ return value;
+ }
}
diff --git a/libjava/javax/rmi/CORBA/PortableRemoteObjectDelegate.java b/libjava/javax/rmi/CORBA/PortableRemoteObjectDelegate.java
index a073cf4705c..7798a46668c 100644
--- a/libjava/javax/rmi/CORBA/PortableRemoteObjectDelegate.java
+++ b/libjava/javax/rmi/CORBA/PortableRemoteObjectDelegate.java
@@ -1,5 +1,5 @@
/* PortableRemoteObjectDelegate.java -- Interface supporting PortableRemoteObject
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,9 @@ exception statement from your version. */
package javax.rmi.CORBA;
-import java.rmi.*;
+import java.rmi.NoSuchObjectException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
/**
* A delegate is a singleton class that support delegation for method
diff --git a/libjava/javax/rmi/CORBA/Stub.java b/libjava/javax/rmi/CORBA/Stub.java
index c79b85cb46e..0ea10c9ee32 100644
--- a/libjava/javax/rmi/CORBA/Stub.java
+++ b/libjava/javax/rmi/CORBA/Stub.java
@@ -1,5 +1,5 @@
/* Stub.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,16 +38,14 @@ exception statement from your version. */
package javax.rmi.CORBA;
+import gnu.javax.rmi.CORBA.DelegateFactory;
+import gnu.javax.rmi.CORBA.GetDelegateInstanceException;
+
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.rmi.RemoteException;
-//import org.omg.CORBA.ORB;
-//import org.omg.CORBA_2_3.portable.ObjectImpl;
-//import org.omg.CORBA.portable.ObjectImpl;
-import gnu.javax.rmi.CORBA.DelegateFactory;
-import gnu.javax.rmi.CORBA.GetDelegateInstanceException;
public abstract class Stub extends ObjectImpl
implements Serializable
diff --git a/libjava/javax/rmi/CORBA/Util.java b/libjava/javax/rmi/CORBA/Util.java
index 45a189d97c5..34e05dafda2 100644
--- a/libjava/javax/rmi/CORBA/Util.java
+++ b/libjava/javax/rmi/CORBA/Util.java
@@ -1,5 +1,5 @@
/* Util.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,16 +38,14 @@ exception statement from your version. */
package javax.rmi.CORBA;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.lang.Object;
-import java.io.*;
-//import org.omg.CORBA.*;
-//import org.omg.CORBA.portable.InputStream;
-//import org.omg.CORBA.portable.OutputStream;
import gnu.javax.rmi.CORBA.DelegateFactory;
import gnu.javax.rmi.CORBA.GetDelegateInstanceException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
public class Util
{
diff --git a/libjava/javax/rmi/CORBA/UtilDelegate.java b/libjava/javax/rmi/CORBA/UtilDelegate.java
index 4d611bc8bfb..fac60d54236 100644
--- a/libjava/javax/rmi/CORBA/UtilDelegate.java
+++ b/libjava/javax/rmi/CORBA/UtilDelegate.java
@@ -38,9 +38,10 @@ exception statement from your version. */
package javax.rmi.CORBA;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.rmi.Remote;
import java.rmi.RemoteException;
-import java.io.*;
//import org.omg.CORBA.ORB;
//import org.omg.CORBA.SystemException;
//import org.omg.CORBA.portable.InputStream;
diff --git a/libjava/javax/rmi/CORBA/ValueHandler.java b/libjava/javax/rmi/CORBA/ValueHandler.java
index 3a008f18cca..fe980022191 100644
--- a/libjava/javax/rmi/CORBA/ValueHandler.java
+++ b/libjava/javax/rmi/CORBA/ValueHandler.java
@@ -1,5 +1,5 @@
/* ValueHandler.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,9 @@ exception statement from your version. */
package javax.rmi.CORBA;
-import java.io.*;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
//import org.omg.CORBA.portable.InputStream;
//import org.omg.CORBA.portable.OutputStream;
//import org.omg.SendingContext.RunTime;
diff --git a/libjava/javax/rmi/PortableRemoteObject.java b/libjava/javax/rmi/PortableRemoteObject.java
index ee40d9c9e74..f95dafd6b83 100644
--- a/libjava/javax/rmi/PortableRemoteObject.java
+++ b/libjava/javax/rmi/PortableRemoteObject.java
@@ -1,5 +1,5 @@
/* PortableRemoteObject.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,13 +38,14 @@ exception statement from your version. */
package javax.rmi;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.rmi.NoSuchObjectException;
import gnu.javax.rmi.CORBA.DelegateFactory;
import gnu.javax.rmi.CORBA.GetDelegateInstanceException;
+
+import java.rmi.NoSuchObjectException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
import javax.rmi.CORBA.PortableRemoteObjectDelegate;
-import javax.rmi.CORBA.Util;
public class PortableRemoteObject
implements Remote /* why doc doesn't say should implement Remote */
diff --git a/libjava/javax/security/auth/x500/X500Principal.java b/libjava/javax/security/auth/x500/X500Principal.java
index 036cab7f91a..6c7e79ee77b 100644
--- a/libjava/javax/security/auth/x500/X500Principal.java
+++ b/libjava/javax/security/auth/x500/X500Principal.java
@@ -1,5 +1,5 @@
/* X500Principal.java -- X.500 principal.
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,21 +38,16 @@ exception statement from your version. */
package javax.security.auth.x500;
-import java.io.ByteArrayInputStream;
+import gnu.java.security.x509.X500DistinguishedName;
+
import java.io.IOException;
import java.io.InputStream;
import java.io.NotActiveException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
-
import java.security.Principal;
-import java.util.HashSet;
-import java.util.LinkedList;
-
-import gnu.java.security.x509.X500DistinguishedName;
-
public final class X500Principal implements Principal, Serializable
{
private static final long serialVersionUID = -500463348111345721L;
diff --git a/libjava/javax/swing/AbstractButton.java b/libjava/javax/swing/AbstractButton.java
index de0be6350bb..b2d2c52b8c2 100644
--- a/libjava/javax/swing/AbstractButton.java
+++ b/libjava/javax/swing/AbstractButton.java
@@ -37,8 +37,6 @@ exception statement from your version. */
package javax.swing;
-import java.awt.AWTEvent;
-import java.awt.AWTEventMulticaster;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
@@ -51,12 +49,10 @@ import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
-import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
-import java.io.Serializable;
-import java.util.Vector;
import java.util.EventListener;
+
import javax.accessibility.AccessibleAction;
import javax.accessibility.AccessibleIcon;
import javax.accessibility.AccessibleRelationSet;
@@ -151,8 +147,8 @@ import javax.swing.text.AttributeSet;
*
* </ul>
*
- * @author Ronald Veldema (rveldema&064;cs.vu.nl)
- * @author Graydon Hoare (graydon&064;redhat.com)
+ * @author Ronald Veldema (rveldema@cs.vu.nl)
+ * @author Graydon Hoare (graydon@redhat.com)
*/
public abstract class AbstractButton extends JComponent
diff --git a/libjava/javax/swing/ActionMap.java b/libjava/javax/swing/ActionMap.java
index 940d1dfa13d..ce6086c2ecd 100644
--- a/libjava/javax/swing/ActionMap.java
+++ b/libjava/javax/swing/ActionMap.java
@@ -42,7 +42,6 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Arrays;
-import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
diff --git a/libjava/javax/swing/DefaultBoundedRangeModel.java b/libjava/javax/swing/DefaultBoundedRangeModel.java
index 8ca178dd551..3294c1d9e90 100644
--- a/libjava/javax/swing/DefaultBoundedRangeModel.java
+++ b/libjava/javax/swing/DefaultBoundedRangeModel.java
@@ -203,7 +203,7 @@ public class DefaultBoundedRangeModel
* Changes the current value of this bounded range model. In a
* scroll bar visualization of a {@link BoundedRangeModel}, the
* <code>value</code> is displayed as the position of the thumb;
- * changing the <code>value</code> of a scroll bar&#x2019;s model
+ * changing the <code>value</code> of a scroll bar's model
* thus moves the thumb to a different position.
*/
public void setValue(int value)
diff --git a/libjava/javax/swing/DefaultButtonModel.java b/libjava/javax/swing/DefaultButtonModel.java
index edffc39d6e5..a608de4488c 100644
--- a/libjava/javax/swing/DefaultButtonModel.java
+++ b/libjava/javax/swing/DefaultButtonModel.java
@@ -37,15 +37,13 @@ exception statement from your version. */
package javax.swing;
-import java.awt.AWTEvent;
-import java.awt.AWTEventMulticaster;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.Serializable;
import java.util.EventListener;
-import java.util.Vector;
+
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
@@ -73,7 +71,7 @@ import javax.swing.event.EventListenerList;
*
* In all other respects this class is just a container of boolean flags.
*
- * @author Graydon Hoare (graydon&064;redhat.com)
+ * @author Graydon Hoare (graydon@redhat.com)
*/
public class DefaultButtonModel implements ButtonModel, Serializable
{
diff --git a/libjava/javax/swing/DefaultListModel.java b/libjava/javax/swing/DefaultListModel.java
index 23f135b2f6b..53dd20cbc10 100644
--- a/libjava/javax/swing/DefaultListModel.java
+++ b/libjava/javax/swing/DefaultListModel.java
@@ -1,5 +1,5 @@
/* DefaultListModel.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.swing;
import java.util.Enumeration;
-import java.util.NoSuchElementException;
import java.util.Vector;
/**
@@ -48,7 +47,7 @@ import java.util.Vector;
* java.util.Vector}.
*
* @author Andrew Selkirk
- * @author Graydon Hoare (graydon&064;redhat.com)
+ * @author Graydon Hoare (graydon@redhat.com)
*/
public class DefaultListModel extends AbstractListModel
diff --git a/libjava/javax/swing/DefaultSingleSelectionModel.java b/libjava/javax/swing/DefaultSingleSelectionModel.java
index 86e43e1ac8c..e3f990d2f88 100644
--- a/libjava/javax/swing/DefaultSingleSelectionModel.java
+++ b/libjava/javax/swing/DefaultSingleSelectionModel.java
@@ -115,7 +115,7 @@ public class DefaultSingleSelectionModel
*/
public boolean isSelected ()
{
- return (index == -1);
+ return (index != -1);
}
/**
diff --git a/libjava/javax/swing/ImageIcon.java b/libjava/javax/swing/ImageIcon.java
index 872558d08dd..da271a51d3f 100644
--- a/libjava/javax/swing/ImageIcon.java
+++ b/libjava/javax/swing/ImageIcon.java
@@ -1,5 +1,5 @@
/* ImageIcon.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -41,12 +41,7 @@ package javax.swing;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Image;
-import java.awt.MediaTracker;
import java.awt.Toolkit;
-import java.io.Serializable;
-import java.net.URL;
-import javax.accessibility.Accessible;
-import javax.accessibility.AccessibleContext;
public class ImageIcon implements Icon
{
@@ -56,7 +51,10 @@ public class ImageIcon implements Icon
public ImageIcon(String s)
{
- this(s, "");
+ // if description is not specified, then file name becomes
+ // desciption for this icon
+
+ this(s, s);
}
public ImageIcon(String file,
diff --git a/libjava/javax/swing/JCheckBoxMenuItem.java b/libjava/javax/swing/JCheckBoxMenuItem.java
index cce8ec1ae34..968b25e9d41 100644
--- a/libjava/javax/swing/JCheckBoxMenuItem.java
+++ b/libjava/javax/swing/JCheckBoxMenuItem.java
@@ -39,206 +39,135 @@ package javax.swing;
import java.io.IOException;
import java.io.ObjectOutputStream;
+
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
-/**
- * JCheckBoxMenuItem
- * @author Andrew Selkirk
- * @version 1.0
- */
-public class JCheckBoxMenuItem extends JMenuItem implements SwingConstants, Accessible
-{
-
- //-------------------------------------------------------------
- // Classes ----------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * AccessibleJCheckBoxMenuItem
- */
- protected class AccessibleJCheckBoxMenuItem extends AccessibleJMenuItem {
-
- //-------------------------------------------------------------
- // Variables --------------------------------------------------
- //-------------------------------------------------------------
-
-
- //-------------------------------------------------------------
- // Initialization ---------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * Constructor AccessibleJCheckBoxMenuItem
- * @param component TODO
- */
- protected AccessibleJCheckBoxMenuItem(JCheckBoxMenuItem component) {
- super(component);
- // TODO
- } // AccessibleJCheckBoxMenuItem()
-
-
- //-------------------------------------------------------------
- // Methods ----------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * getAccessibleRole
- * @returns AccessibleRole
- */
- public AccessibleRole getAccessibleRole() {
- return AccessibleRole.CHECK_BOX;
- } // getAccessibleRole()
-
-
- } // AccessibleJCheckBoxMenuItem
-
-
- //-------------------------------------------------------------
- // Variables --------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * uiClassID
- */
- private static final String uiClassID = "CheckBoxMenuItemUI";
-
-
- //-------------------------------------------------------------
- // Initialization ---------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * Constructor JCheckBoxMenuItem
- */
- public JCheckBoxMenuItem() {
- // TODO
- } // JCheckBoxMenuItem()
-
- /**
- * Constructor JCheckBoxMenuItem
- * @param icon TODO
- */
- public JCheckBoxMenuItem(Icon icon) {
- // TODO
- } // JCheckBoxMenuItem()
-
- /**
- * Constructor JCheckBoxMenuItem
- * @param text TODO
- */
- public JCheckBoxMenuItem(String text) {
- // TODO
- } // JCheckBoxMenuItem()
-
- /**
- * Constructor JCheckBoxMenuItem
- * @param action TODO
- */
- public JCheckBoxMenuItem(Action action) {
- // TODO
- } // JCheckBoxMenuItem()
-
- /**
- * Constructor JCheckBoxMenuItem
- * @param text TODO
- * @param icon TODO
- */
- public JCheckBoxMenuItem(String text, Icon icon) {
- // TODO
- } // JCheckBoxMenuItem()
-
- /**
- * Constructor JCheckBoxMenuItem
- * @param text TODO
- * @param state TODO
- */
- public JCheckBoxMenuItem(String text, boolean state) {
- // TODO
- } // JCheckBoxMenuItem()
-
- /**
- * Constructor JCheckBoxMenuItem
- * @param text TODO
- * @param icon TODO
- * @param state TODO
- */
- public JCheckBoxMenuItem(String text, Icon icon, boolean state) {
- // TODO
- } // JCheckBoxMenuItem()
-
-
- //-------------------------------------------------------------
- // Methods ----------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * writeObject
- * @param stream TODO
- * @exception IOException TODO
- */
- private void writeObject(ObjectOutputStream stream) throws IOException {
- // TODO
- } // writeObject()
-
- /**
- * getUIClassID
- * @returns String
- */
- public String getUIClassID() {
- return uiClassID;
- } // getUIClassID()
-
- /**
- * getState
- * @returns boolean
- */
- public boolean getState() {
- return false; // TODO
- } // getState()
-
- /**
- * setState
- * @param state TODO
- */
- public synchronized void setState(boolean state) {
- // TODO
- } // setState()
-
- /**
- * getSelectedObjects
- * @returns Object[]
- */
- public Object[] getSelectedObjects() {
- return null; // TODO
- } // getSelectedObjects()
-
- /**
- * requestFocus
- */
- public void requestFocus() {
- // TODO
- } // requestFocus()
-
- /**
- * paramString
- * @returns String
- */
- protected String paramString() {
- return null; // TODO
- } // paramString()
-
- /**
- * getAccessibleContext
- * @returns AccessibleContext
- */
- public AccessibleContext getAccessibleContext() {
- if (accessibleContext == null) {
- accessibleContext = new AccessibleJCheckBoxMenuItem(this);
- } // if
- return accessibleContext;
- } // getAccessibleContext()
-
+public class JCheckBoxMenuItem extends JMenuItem implements SwingConstants,
+ Accessible
+{
+ //-------------------------------------------------------------
+ // Variables --------------------------------------------------
+ //-------------------------------------------------------------
+ private static final String uiClassID = "CheckBoxMenuItemUI";
+ private boolean state;
+ private Object[] selectedObjects;
+
+ //-------------------------------------------------------------
+ // Initialization ---------------------------------------------
+ //-------------------------------------------------------------
+ public JCheckBoxMenuItem()
+ {
+ this(null, null);
+ } // JCheckBoxMenuItem()
+
+ public JCheckBoxMenuItem(Icon icon)
+ {
+ this(null, icon);
+ } // JCheckBoxMenuItem()
+
+ public JCheckBoxMenuItem(String text)
+ {
+ this(text, null);
+ } // JCheckBoxMenuItem()
+
+ public JCheckBoxMenuItem(Action action)
+ {
+ this();
+ setAction(action);
+ } // JCheckBoxMenuItem()
+
+ public JCheckBoxMenuItem(String text, Icon icon)
+ {
+ this(text, icon, false);
+ } // JCheckBoxMenuItem()
+
+ public JCheckBoxMenuItem(String text, boolean state)
+ {
+ this(text, null, state);
+ } // JCheckBoxMenuItem()
+
+ public JCheckBoxMenuItem(String text, Icon icon, boolean state)
+ {
+ super(text, icon);
+ setModel(new JToggleButton.ToggleButtonModel());
+ this.state = state;
+ } // JCheckBoxMenuItem()
+
+ //-------------------------------------------------------------
+ // Methods ----------------------------------------------------
+ //-------------------------------------------------------------
+ private void writeObject(ObjectOutputStream stream) throws IOException
+ {
+ // TODO
+ } // writeObject()
+
+ public String getUIClassID()
+ {
+ return uiClassID;
+ } // getUIClassID()
+
+ public boolean getState()
+ {
+ return state;
+ } // getState()
+
+ public synchronized void setState(boolean state)
+ {
+ this.state = state;
+ } // setState()
+
+ public Object[] getSelectedObjects()
+ {
+ return selectedObjects;
+ } // getSelectedObjects()
+
+ public void requestFocus()
+ {
+ // TODO
+ } // requestFocus()
+
+ protected String paramString()
+ {
+ return "JCheckBoxMenuItem";
+ } // paramString()
+
+ public AccessibleContext getAccessibleContext()
+ {
+ if (accessibleContext == null)
+ {
+ accessibleContext = new AccessibleJCheckBoxMenuItem(this);
+ }
+
+ return accessibleContext;
+ } // getAccessibleContext()
+
+ //-------------------------------------------------------------
+ // Classes ----------------------------------------------------
+ //-------------------------------------------------------------
+ protected class AccessibleJCheckBoxMenuItem extends AccessibleJMenuItem
+ {
+ //-------------------------------------------------------------
+ // Variables --------------------------------------------------
+ //-------------------------------------------------------------
+ //-------------------------------------------------------------
+ // Initialization ---------------------------------------------
+ //-------------------------------------------------------------
+ protected AccessibleJCheckBoxMenuItem(JCheckBoxMenuItem component)
+ {
+ super(component);
+
+ // TODO
+ } // AccessibleJCheckBoxMenuItem()
+
+ //-------------------------------------------------------------
+ // Methods ----------------------------------------------------
+ //-------------------------------------------------------------
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.CHECK_BOX;
+ } // getAccessibleRole()
+ } // AccessibleJCheckBoxMenuItem
} // JCheckBoxMenuItem
diff --git a/libjava/javax/swing/JComboBox.java b/libjava/javax/swing/JComboBox.java
index b3c5ccf8834..acdbdc011e3 100644
--- a/libjava/javax/swing/JComboBox.java
+++ b/libjava/javax/swing/JComboBox.java
@@ -48,13 +48,12 @@ import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Vector;
+
import javax.accessibility.Accessible;
-import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleAction;
+import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleSelection;
-import javax.swing.event.MenuEvent;
-import javax.swing.event.MenuListener;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.PopupMenuListener;
diff --git a/libjava/javax/swing/JComponent.java b/libjava/javax/swing/JComponent.java
index c98f52dfb83..7b2261fa43b 100644
--- a/libjava/javax/swing/JComponent.java
+++ b/libjava/javax/swing/JComponent.java
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.swing;
-import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
@@ -55,7 +54,6 @@ import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
-import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.image.ImageObserver;
import java.awt.peer.LightweightPeer;
@@ -65,17 +63,16 @@ import java.beans.VetoableChangeListener;
import java.io.Serializable;
import java.util.EventListener;
import java.util.Hashtable;
-import java.util.Vector;
+
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
-import javax.accessibility.AccessibleExtendedComponent;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleStateSet;
+import javax.swing.border.Border;
import javax.swing.event.AncestorListener;
import javax.swing.event.EventListenerList;
-import javax.swing.border.Border;
-import javax.swing.plaf.ComponentUI;
import javax.swing.event.SwingPropertyChangeSupport;
+import javax.swing.plaf.ComponentUI;
/**
* Every component in swing inherits from this class (JLabel, JButton, etc).
@@ -100,7 +97,7 @@ public abstract class JComponent extends Container implements Serializable
Border border;
JToolTip tooltip;
String tool_tip_text;
- boolean use_double_buffer, opaque;
+ boolean use_double_buffer = false, opaque;
Image doubleBuffer;
int doubleBufferWidth = -1;
int doubleBufferHeight = -1;
diff --git a/libjava/javax/swing/JDialog.java b/libjava/javax/swing/JDialog.java
index 11f27b239e0..8d43b761d96 100644
--- a/libjava/javax/swing/JDialog.java
+++ b/libjava/javax/swing/JDialog.java
@@ -1,5 +1,5 @@
/* JDialog.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -57,12 +57,8 @@ import javax.accessibility.AccessibleContext;
*
* @author Ronald Veldema (rveldema@cs.vu.nl)
*/
-public class JDialog extends Dialog implements Accessible
+public class JDialog extends Dialog implements Accessible, WindowConstants
{
- public final static int HIDE_ON_CLOSE = 0;
- public final static int DISPOSE_ON_CLOSE = 1;
- public final static int DO_NOTHING_ON_CLOSE = 2;
-
protected AccessibleContext accessibleContext;
private int close_action = HIDE_ON_CLOSE;
@@ -75,42 +71,42 @@ public class JDialog extends Dialog implements Accessible
*
*************/
- JDialog(Frame owner)
+ public JDialog(Frame owner)
{
this(owner, "dialog");
}
- JDialog(Frame owner,
+ public JDialog(Frame owner,
String s)
{
this(owner, s, true);
}
- JDialog(Frame owner,
+ public JDialog(Frame owner,
String s,
boolean modeld)
{
super(owner, s, modeld);
}
- JDialog(Frame owner,
+ public JDialog(Frame owner,
// String s,
boolean modeld)
{
super(owner, "JDialog", modeld);
}
- JDialog(Dialog owner)
+ public JDialog(Dialog owner)
{
this(owner, "dialog");
}
- JDialog(Dialog owner,
+ public JDialog(Dialog owner,
String s)
{
this(owner, s, true);
}
- JDialog(Dialog owner,
+ public JDialog(Dialog owner,
String s,
boolean modeld)
{
@@ -221,18 +217,20 @@ public class JDialog extends Dialog implements Accessible
protected void processWindowEvent(WindowEvent e)
{
- // System.out.println("PROCESS_WIN_EV-1: " + e);
super.processWindowEvent(e);
- // System.out.println("PROCESS_WIN_EV-2: " + e);
switch (e.getID())
{
case WindowEvent.WINDOW_CLOSING:
{
switch(close_action)
{
+ case EXIT_ON_CLOSE:
+ {
+ System.exit(0);
+ break;
+ }
case DISPOSE_ON_CLOSE:
{
- System.out.println("user requested dispose on close");
dispose();
break;
}
@@ -258,8 +256,34 @@ public class JDialog extends Dialog implements Accessible
}
- void setDefaultCloseOperation(int operation)
- { close_action = operation; }
+ /**
+ * Defines what happens when this frame is closed. Can be one off
+ * <code>EXIT_ON_CLOSE</code>,
+ * <code>DISPOSE_ON_CLOSE</code>,
+ * <code>HIDE_ON_CLOSE</code> or
+ * <code>DO_NOTHING_ON_CLOSE</code>.
+ * The default is <code>HIDE_ON_CLOSE</code>.
+ * When <code>EXIT_ON_CLOSE</code> is specified this method calls
+ * <code>SecurityManager.checkExit(0)</code> which might throw a
+ * <code>SecurityException</code>. When the specified operation is
+ * not one of the above a <code>IllegalArgumentException</code> is
+ * thrown.
+ */
+ public void setDefaultCloseOperation(int operation)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null && operation == EXIT_ON_CLOSE)
+ sm.checkExit(0);
+
+ if (operation != EXIT_ON_CLOSE && operation != DISPOSE_ON_CLOSE
+ && operation != HIDE_ON_CLOSE && operation != DO_NOTHING_ON_CLOSE)
+ throw new IllegalArgumentException("operation = " + operation);
+
+ close_action = operation;
+ }
+
+ public int getDefaultCloseOperation()
+ { return close_action; }
protected String paramString()
{ return "JDialog"; }
diff --git a/libjava/javax/swing/JFrame.java b/libjava/javax/swing/JFrame.java
index 864f6bae4e0..1062c9603b7 100644
--- a/libjava/javax/swing/JFrame.java
+++ b/libjava/javax/swing/JFrame.java
@@ -1,5 +1,5 @@
/* JFrame.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -45,10 +45,10 @@ import java.awt.Container;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
-import java.awt.GraphicsConfiguration;
import java.awt.LayoutManager;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
+
import javax.accessibility.AccessibleContext;
/**
@@ -57,16 +57,11 @@ import javax.accessibility.AccessibleContext;
*
* @author Ronald Veldema (rveldema@cs.vu.nl)
*/
-public class JFrame extends Frame
+public class JFrame extends Frame implements WindowConstants
{
- public final static int HIDE_ON_CLOSE = 0;
- public final static int EXIT_ON_CLOSE = 1;
- public final static int DISPOSE_ON_CLOSE = 2;
- public final static int DO_NOTHING_ON_CLOSE = 3;
-
protected AccessibleContext accessibleContext;
- private int close_action = EXIT_ON_CLOSE;
+ private int close_action = HIDE_ON_CLOSE;
/***************************************************
@@ -192,7 +187,7 @@ public class JFrame extends Frame
return accessibleContext;
}
- int getDefaultCloseOperation()
+ public int getDefaultCloseOperation()
{ return close_action; }
@@ -212,7 +207,7 @@ public class JFrame extends Frame
{
case EXIT_ON_CLOSE:
{
- System.exit(1);
+ System.exit(0);
break;
}
case DISPOSE_ON_CLOSE:
@@ -241,8 +236,30 @@ public class JFrame extends Frame
}
}
-
- void setDefaultCloseOperation(int operation)
- { close_action = operation; }
+ /**
+ * Defines what happens when this frame is closed. Can be one off
+ * <code>EXIT_ON_CLOSE</code>,
+ * <code>DISPOSE_ON_CLOSE</code>,
+ * <code>HIDE_ON_CLOSE</code> or
+ * <code>DO_NOTHING_ON_CLOSE</code>.
+ * The default is <code>HIDE_ON_CLOSE</code>.
+ * When <code>EXIT_ON_CLOSE</code> is specified this method calls
+ * <code>SecurityManager.checkExit(0)</code> which might throw a
+ * <code>SecurityException</code>. When the specified operation is
+ * not one of the above a <code>IllegalArgumentException</code> is
+ * thrown.
+ */
+ public void setDefaultCloseOperation(int operation)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null && operation == EXIT_ON_CLOSE)
+ sm.checkExit(0);
+
+ if (operation != EXIT_ON_CLOSE && operation != DISPOSE_ON_CLOSE
+ && operation != HIDE_ON_CLOSE && operation != DO_NOTHING_ON_CLOSE)
+ throw new IllegalArgumentException("operation = " + operation);
+
+ close_action = operation;
+ }
}
diff --git a/libjava/javax/swing/JInternalFrame.java b/libjava/javax/swing/JInternalFrame.java
index 034050b6456..f005c91e309 100644
--- a/libjava/javax/swing/JInternalFrame.java
+++ b/libjava/javax/swing/JInternalFrame.java
@@ -1,5 +1,5 @@
/* JInternalFrame.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,9 +38,6 @@ exception statement from your version. */
package javax.swing;
-import java.awt.Component;
-import java.awt.Container;
-import javax.accessibility.Accessible;
public class JInternalFrame extends JComponent
/*implements Accessible, WindowConstants, RootPaneContainer*/
diff --git a/libjava/javax/swing/JLabel.java b/libjava/javax/swing/JLabel.java
index 19f992c2f7f..c6bc1bd3ca8 100644
--- a/libjava/javax/swing/JLabel.java
+++ b/libjava/javax/swing/JLabel.java
@@ -289,7 +289,7 @@ public class JLabel extends JComponent implements Accessible, SwingConstants
String oldText = labelText;
labelText = text;
firePropertyChange(TEXT_CHANGED_PROPERTY, oldText, labelText);
- if (labelText.length() <= underlinedChar)
+ if (labelText != null && labelText.length() <= underlinedChar)
setDisplayedMnemonicIndex(labelText.length() - 1);
}
}
diff --git a/libjava/javax/swing/JLayeredPane.java b/libjava/javax/swing/JLayeredPane.java
index e82089b25d3..7002b6e0c86 100644
--- a/libjava/javax/swing/JLayeredPane.java
+++ b/libjava/javax/swing/JLayeredPane.java
@@ -82,16 +82,15 @@ import javax.accessibility.Accessible;
* <dd>An offset into a layer's "logical drawing order". Layer position 0
* is drawn last. Layer position -1 is a synonym for the first layer
* position (the logical "bottom").</dd>
+ * </dl>
*
* <p><b>Note:</b> the layer numbering order is the <em>reverse</em> of the
* component indexing and position order</p>
*
* @author Graydon Hoare <graydon@redhat.com>
*/
-
public class JLayeredPane extends JComponent implements Accessible
{
-
public static String LAYER_PROPERTY = "LAYER_PROPERTY";
public static Integer FRAME_CONTENT_LAYER = new Integer (-30000);
diff --git a/libjava/javax/swing/JList.java b/libjava/javax/swing/JList.java
index 7ed776c0380..e8d2228bcdd 100644
--- a/libjava/javax/swing/JList.java
+++ b/libjava/javax/swing/JList.java
@@ -99,7 +99,7 @@ import javax.swing.plaf.ListUI;
* <tr><td>visibleRowCount </td><td>list </td><td>no </td></tr>
* </table>
*
- * @author Graydon Hoare (graydon&064;redhat.com)
+ * @author Graydon Hoare (graydon@redhat.com)
*/
public class JList extends JComponent implements Accessible, Scrollable
diff --git a/libjava/javax/swing/JMenuBar.java b/libjava/javax/swing/JMenuBar.java
index 24440db598a..fec19e694bd 100644
--- a/libjava/javax/swing/JMenuBar.java
+++ b/libjava/javax/swing/JMenuBar.java
@@ -1,5 +1,5 @@
/* JMenuBar.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,10 +38,6 @@ exception statement from your version. */
package javax.swing;
-import java.awt.Component;
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseEvent;
-import javax.accessibility.Accessible;
public class JMenuBar extends JComponent
{
diff --git a/libjava/javax/swing/JMenuItem.java b/libjava/javax/swing/JMenuItem.java
index db09f22972f..db06bc670e8 100644
--- a/libjava/javax/swing/JMenuItem.java
+++ b/libjava/javax/swing/JMenuItem.java
@@ -1,5 +1,5 @@
/* JMenuItem.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -45,6 +45,7 @@ import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
+
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
@@ -56,418 +57,259 @@ import javax.swing.event.MenuKeyEvent;
import javax.swing.event.MenuKeyListener;
import javax.swing.plaf.MenuItemUI;
-/**
- * JMenuItem
- * @author Andrew Selkirk
- * @version 1.0
- */
-public class JMenuItem extends AbstractButton implements Accessible, MenuElement {
-
- //-------------------------------------------------------------
- // Classes ----------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * AccessibleJMenuItem
- */
- protected class AccessibleJMenuItem extends AccessibleAbstractButton
- implements ChangeListener {
-
- //-------------------------------------------------------------
- // Variables --------------------------------------------------
- //-------------------------------------------------------------
-
-
- //-------------------------------------------------------------
- // Initialization ---------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * Constructor AccessibleJMenuItem
- * @param component TODO
- */
- AccessibleJMenuItem(JMenuItem component) {
- super(component);
- // TODO
- } // AccessibleJMenuItem()
-
-
- //-------------------------------------------------------------
- // Methods ----------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * stateChanged
- * @param event TODO
- */
- public void stateChanged(ChangeEvent event) {
- // TODO
- } // stateChanged()
-
- /**
- * getAccessibleRole
- * @returns AccessibleRole
- */
- public AccessibleRole getAccessibleRole() {
- return AccessibleRole.MENU_ITEM;
- } // getAccessibleRole()
-
-
- } // AccessibleJMenuItem
-
-
- //-------------------------------------------------------------
- // Variables --------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * uiClassID
- */
- private static final String uiClassID = "MenuItemUI";
-
- /**
- * accelerator
- */
- private KeyStroke accelerator;
-
-
- //-------------------------------------------------------------
- // Initialization ---------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * Constructor JMenuItem
- */
- public JMenuItem() {
- // TODO
- } // JMenuItem()
-
- /**
- * Constructor JMenuItem
- * @param icon TODO
- */
- public JMenuItem(Icon icon) {
- // TODO
- } // JMenuItem()
-
- /**
- * Constructor JMenuItem
- * @param text TODO
- */
- public JMenuItem(String text) {
- // TODO
- } // JMenuItem()
-
- /**
- * Constructor JMenuItem
- * @param action TODO
- */
- public JMenuItem(Action action) {
- // TODO
- } // JMenuItem()
-
- /**
- * Constructor JMenuItem
- * @param text TODO
- * @param icon TODO
- */
- public JMenuItem(String text, Icon icon) {
- // TODO
- } // JMenuItem()
-
- /**
- * Constructor JMenuItem
- * @param text TODO
- * @param mnemonic TODO
- */
- public JMenuItem(String text, int mnemonic) {
- // TODO
- } // JMenuItem()
-
-
- //-------------------------------------------------------------
- // Methods ----------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * readObject
- * @param stream TODO
- * @exception IOException TODO
- * @exception ClassNotFoundException TODO
- */
- private void readObject(ObjectInputStream stream)
- throws IOException, ClassNotFoundException {
- // TODO
- } // readObject()
-
- /**
- * writeObject
- * @param stream TODO
- * @exception IOException TODO
- */
- private void writeObject(ObjectOutputStream stream) throws IOException {
- // TODO
- } // writeObject()
-
- /**
- * init
- * @param text TODO
- * @param icon TODO
- */
- protected void init(String text, Icon icon) {
- // TODO
- } // init()
-
- /**
- * setUI
- * @param ui TODO
- */
- public void setUI(MenuItemUI ui) {
- super.setUI(ui);
- // TODO
- } // setUI()
-
- /**
- * updateUI
- */
- public void updateUI() {
- setUI((MenuItemUI) UIManager.get(this));
- invalidate();
- } // updateUI()
-
- /**
- * getUIClassID
- * @returns String
- */
- public String getUIClassID() {
- return uiClassID;
- } // getUIClassID()
-
- /**
- * isArmed
- * @returns boolean
- */
- public boolean isArmed() {
- return false; // TODO
- } // isArmed()
-
- /**
- * setArmed
- * @param armed TODO
- */
- public void setArmed(boolean armed) {
- // TODO
- } // setArmed()
-
- /**
- * setEnabled
- * @param enabled TODO
- */
- public void setEnabled(boolean enabled) {
- // TODO
- } // setEnabled()
-
- /**
- * getAccelerator
- * @returns KeyStroke
- */
- public KeyStroke getAccelerator() {
- return null; // TODO
- } // getAccelerator()
-
- /**
- * setAccelerator
- * @param keystroke TODO
- */
- public void setAccelerator(KeyStroke keystroke) {
- // TODO
- } // setAccelerator()
-
- /**
- * configurePropertiesFromAction
- * @param action TODO
- */
- protected void configurePropertiesFromAction(Action action) {
- // TODO
- } // configurePropertiesFromAction()
-
- /**
- * createActionPropertyChangeListener
- * @param action TODO
- * @returns PropertyChangeListener
- */
- protected PropertyChangeListener createActionPropertyChangeListener(Action action) {
- return null; // TODO
- } // createActionPropertyChangeListener()
-
- /**
- * processMouseEvent
- * @param event TODO
- * @param path TODO
- * @param manager TODO
- */
- public void processMouseEvent(MouseEvent event, MenuElement[] path,
- MenuSelectionManager manager) {
- // TODO
- } // processMouseEvent()
-
- /**
- * processKeyEvent
- * @param event TODO
- * @param path TODO
- * @param manager TODO
- */
- public void processKeyEvent(KeyEvent event, MenuElement[] path,
- MenuSelectionManager manager) {
- // TODO
- } // processKeyEvent()
-
- /**
- * processMenuDragMouseEvent
- * @param event TODO
- */
- public void processMenuDragMouseEvent(MenuDragMouseEvent event) {
- // TODO
- } // processMenuDragMouseEvent()
-
- /**
- * processMenuKeyEvent
- * @param event TODO
- */
- public void processMenuKeyEvent(MenuKeyEvent event) {
- // TODO
- } // processMenuKeyEvent()
-
- /**
- * fireMenuDragMouseEntered
- * @param event TODO
- */
- protected void fireMenuDragMouseEntered(MenuDragMouseEvent event) {
- // TODO
- } // fireMenuDragMouseEntered()
-
- /**
- * fireMenuDragMouseExited
- * @param event TODO
- */
- protected void fireMenuDragMouseExited(MenuDragMouseEvent event) {
- // TODO
- } // fireMenuDragMouseExited()
-
- /**
- * fireMenuDragMouseDragged
- * @param event TODO
- */
- protected void fireMenuDragMouseDragged(MenuDragMouseEvent event) {
- // TODO
- } // fireMenuDragMouseDragged()
-
- /**
- * fireMenuDragMouseReleased
- * @param event TODO
- */
- protected void fireMenuDragMouseReleased(MenuDragMouseEvent event) {
- // TODO
- } // fireMenuDragMouseReleased()
-
- /**
- * fireMenuKeyPressed
- * @param event TODO
- */
- protected void fireMenuKeyPressed(MenuKeyEvent event) {
- // TODO
- } // fireMenuKeyPressed()
-
- /**
- * fireMenuKeyReleased
- * @param event TODO
- */
- protected void fireMenuKeyReleased(MenuKeyEvent event) {
- // TODO
- } // fireMenuKeyReleased()
-
- /**
- * fireMenuKeyTyped
- * @param event TODO
- */
- protected void fireMenuKeyTyped(MenuKeyEvent event) {
- // TODO
- } // fireMenuKeyTyped()
-
- /**
- * menuSelectionChanged
- * @param changed TODO
- */
- public void menuSelectionChanged(boolean changed) {
- // TODO
- } // menuSelectionChanged()
-
- /**
- * getSubElements
- * @returns MenuElement[]
- */
- public MenuElement[] getSubElements() {
- return null; // TODO
- } // getSubElements()
-
- /**
- * getComponent
- * @returns Component
- */
- public Component getComponent() {
- return null; // TODO
- } // getComponent()
-
- /**
- * addMenuDragMouseListener
- * @param listener TODO
- */
- public void addMenuDragMouseListener(MenuDragMouseListener listener) {
- // TODO
- } // addMenuDragMouseListener()
-
- /**
- * removeMenuDragMouseListener
- * @param listener TODO
- */
- public void removeMenuDragMouseListener(MenuDragMouseListener listener) {
- // TODO
- } // removeMenuDragMouseListener()
-
- /**
- * addMenuKeyListener
- * @param listener TODO
- */
- public void addMenuKeyListener(MenuKeyListener listener) {
- // TODO
- } // addMenuKeyListener()
-
- /**
- * removeMenuKeyListener
- * @param listener TODO
- */
- public void removeMenuKeyListener(MenuKeyListener listener) {
- // TODO
- } // removeMenuKeyListener()
-
- /**
- * paramString
- * @returns String
- */
- protected String paramString() {
- return null; // TODO
- } // paramString()
-
- /**
- * getAccessibleContext
- * @returns AccessibleContext
- */
- public AccessibleContext getAccessibleContext() {
- if (accessibleContext == null) {
- accessibleContext = new AccessibleJMenuItem(this);
- } // if
- return accessibleContext;
- } // getAccessibleContext()
-
-
+public class JMenuItem extends AbstractButton implements Accessible,
+ MenuElement
+{
+ //-------------------------------------------------------------
+ // Variables --------------------------------------------------
+ //-------------------------------------------------------------
+ private static final String uiClassID = "MenuItemUI";
+ private KeyStroke accelerator;
+
+ //-------------------------------------------------------------
+ // Initialization ---------------------------------------------
+ //-------------------------------------------------------------
+ public JMenuItem()
+ {
+ this(null, null);
+ } // JMenuItem()
+
+ public JMenuItem(Icon icon)
+ {
+ this(null, icon);
+ } // JMenuItem()
+
+ public JMenuItem(String text)
+ {
+ this(text, null);
+ } // JMenuItem()
+
+ public JMenuItem(Action action)
+ {
+ // TODO
+ } // JMenuItem()
+
+ public JMenuItem(String text, Icon icon)
+ {
+ super(text, icon);
+ } // JMenuItem()
+
+ public JMenuItem(String text, int mnemonic)
+ {
+ super(text, null);
+ setMnemonic(mnemonic);
+ } // JMenuItem()
+
+ //-------------------------------------------------------------
+ // Methods ----------------------------------------------------
+ //-------------------------------------------------------------
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException
+ {
+ // TODO
+ } // readObject()
+
+ private void writeObject(ObjectOutputStream stream) throws IOException
+ {
+ // TODO
+ } // writeObject()
+
+ protected void init(String text, Icon icon)
+ {
+ // TODO
+ } // init()
+
+ public void setUI(MenuItemUI ui)
+ {
+ super.setUI(ui);
+ } // setUI()
+
+ public void updateUI()
+ {
+ MenuItemUI mi = ((MenuItemUI) UIManager.getUI(this));
+ setUI(mi);
+ invalidate();
+ } // updateUI()
+
+ public String getUIClassID()
+ {
+ return uiClassID;
+ } // getUIClassID()
+
+ public boolean isArmed()
+ {
+ return getModel().isArmed();
+ } // isArmed()
+
+ public void setArmed(boolean armed)
+ {
+ getModel().setArmed(armed);
+ } // setArmed()
+
+ public void setEnabled(boolean enabled)
+ {
+ setEnabled(enabled);
+ } // setEnabled()
+
+ public KeyStroke getAccelerator()
+ {
+ return accelerator;
+ } // getAccelerator()
+
+ public void setAccelerator(KeyStroke keystroke)
+ {
+ this.accelerator = keystroke;
+ } // setAccelerator()
+
+ protected void configurePropertiesFromAction(Action action)
+ {
+ super.configurePropertiesFromAction(action);
+
+ if (action == null)
+ setAccelerator(null);
+ else
+ setAccelerator((KeyStroke) (action.getValue(Action.ACCELERATOR_KEY)));
+
+ } // configurePropertiesFromAction()
+
+ protected PropertyChangeListener createActionPropertyChangeListener(Action action)
+ {
+ return null;
+ } // createActionPropertyChangeListener()
+
+ public void processMouseEvent(MouseEvent event, MenuElement[] path,
+ MenuSelectionManager manager)
+ {
+ // TODO
+ } // processMouseEvent()
+
+ public void processKeyEvent(KeyEvent event, MenuElement[] path,
+ MenuSelectionManager manager)
+ {
+ // TODO
+ } // processKeyEvent()
+
+ public void processMenuDragMouseEvent(MenuDragMouseEvent event)
+ {
+ } // processMenuDragMouseEvent()
+
+ public void processMenuKeyEvent(MenuKeyEvent event)
+ {
+ // TODO
+ } // processMenuKeyEvent()
+
+ protected void fireMenuDragMouseEntered(MenuDragMouseEvent event)
+ {
+ // TODO
+ } // fireMenuDragMouseEntered()
+
+ protected void fireMenuDragMouseExited(MenuDragMouseEvent event)
+ {
+ // TODO
+ } // fireMenuDragMouseExited()
+
+ protected void fireMenuDragMouseDragged(MenuDragMouseEvent event)
+ {
+ // TODO
+ } // fireMenuDragMouseDragged()
+
+ protected void fireMenuDragMouseReleased(MenuDragMouseEvent event)
+ {
+ // TODO
+ } // fireMenuDragMouseReleased()
+
+ protected void fireMenuKeyPressed(MenuKeyEvent event)
+ {
+ // TODO
+ } // fireMenuKeyPressed()
+
+ protected void fireMenuKeyReleased(MenuKeyEvent event)
+ {
+ // TODO
+ } // fireMenuKeyReleased()
+
+ protected void fireMenuKeyTyped(MenuKeyEvent event)
+ {
+ // TODO
+ } // fireMenuKeyTyped()
+
+ public void menuSelectionChanged(boolean changed)
+ {
+ // TODO
+ } // menuSelectionChanged()
+
+ public MenuElement[] getSubElements()
+ {
+ return null; // TODO
+ } // getSubElements()
+
+ public Component getComponent()
+ {
+ return null; // TODO
+ } // getComponent()
+
+ public void addMenuDragMouseListener(MenuDragMouseListener listener)
+ {
+ // TODO
+ } // addMenuDragMouseListener()
+
+ public void removeMenuDragMouseListener(MenuDragMouseListener listener)
+ {
+ } // removeMenuDragMouseListener()
+
+ public void addMenuKeyListener(MenuKeyListener listener)
+ {
+ } // addMenuKeyListener()
+
+ public void removeMenuKeyListener(MenuKeyListener listener)
+ {
+ } // removeMenuKeyListener()
+
+ protected String paramString()
+ {
+ return "JMenuItem";
+ } // paramString()
+
+ public AccessibleContext getAccessibleContext()
+ {
+ if (accessibleContext == null)
+ {
+ accessibleContext = new AccessibleJMenuItem(this);
+ }
+
+ return accessibleContext;
+ } // getAccessibleContext()
+
+ //-------------------------------------------------------------
+ // Classes ----------------------------------------------------
+ //-------------------------------------------------------------
+ protected class AccessibleJMenuItem extends AccessibleAbstractButton
+ implements ChangeListener
+ {
+ //-------------------------------------------------------------
+ // Variables --------------------------------------------------
+ //-------------------------------------------------------------
+ //-------------------------------------------------------------
+ // Initialization ---------------------------------------------
+ //-------------------------------------------------------------
+ AccessibleJMenuItem(JMenuItem component)
+ {
+ super(component);
+
+ // TODO
+ } // AccessibleJMenuItem()
+
+ //-------------------------------------------------------------
+ // Methods ----------------------------------------------------
+ //-------------------------------------------------------------
+ public void stateChanged(ChangeEvent event)
+ {
+ // TODO
+ } // stateChanged()
+
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.MENU_ITEM;
+ } // getAccessibleRole()
+ } // AccessibleJMenuItem
} // JMenuItem
diff --git a/libjava/javax/swing/JOptionPane.java b/libjava/javax/swing/JOptionPane.java
index 2992d2441a5..7df8ebd5d16 100644
--- a/libjava/javax/swing/JOptionPane.java
+++ b/libjava/javax/swing/JOptionPane.java
@@ -1,5 +1,5 @@
/* JOptionPane.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -42,7 +42,7 @@ import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Frame;
-import javax.accessibility.Accessible;
+
import javax.accessibility.AccessibleContext;
import javax.swing.plaf.OptionPaneUI;
diff --git a/libjava/javax/swing/JProgressBar.java b/libjava/javax/swing/JProgressBar.java
index f8bb4a5235b..79c5102fbfd 100644
--- a/libjava/javax/swing/JProgressBar.java
+++ b/libjava/javax/swing/JProgressBar.java
@@ -38,8 +38,7 @@ exception statement from your version. */
package javax.swing;
import java.awt.Graphics;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
+
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
@@ -47,7 +46,6 @@ import javax.accessibility.AccessibleStateSet;
import javax.accessibility.AccessibleValue;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
-import javax.swing.event.EventListenerList;
import javax.swing.plaf.ProgressBarUI;
@@ -185,9 +183,6 @@ public class JProgressBar extends JComponent implements SwingConstants,
/** Fired in a PropertyChangeEvent when the "indeterminate" property changes. */
public static final String INDETERMINATE_CHANGED_PROPERTY = "indeterminate";
- /** A list of ChangeListeners registered with this ProgressBar. */
- private transient EventListenerList changeListenerList;
-
/** Whether the ProgressBar is determinate. */
private transient boolean indeterminate = false;
@@ -260,7 +255,6 @@ public class JProgressBar extends JComponent implements SwingConstants,
this.orientation = orientation;
changeListener = createChangeListener();
model.addChangeListener(changeListener);
- changeListenerList = new EventListenerList();
updateUI();
}
@@ -275,7 +269,6 @@ public class JProgressBar extends JComponent implements SwingConstants,
this.model = model;
changeListener = createChangeListener();
model.addChangeListener(changeListener);
- changeListenerList = new EventListenerList();
updateUI();
}
@@ -511,7 +504,7 @@ public class JProgressBar extends JComponent implements SwingConstants,
*/
public void addChangeListener(ChangeListener listener)
{
- changeListenerList.add(ChangeListener.class, listener);
+ listenerList.add(ChangeListener.class, listener);
}
/**
@@ -521,7 +514,7 @@ public class JProgressBar extends JComponent implements SwingConstants,
*/
public void removeChangeListener(ChangeListener listener)
{
- changeListenerList.remove(ChangeListener.class, listener);
+ listenerList.remove(ChangeListener.class, listener);
}
/**
@@ -532,7 +525,7 @@ public class JProgressBar extends JComponent implements SwingConstants,
*/
public ChangeListener[] getChangeListeners()
{
- return (ChangeListener[]) changeListenerList.getListenerList();
+ return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
}
/**
@@ -542,7 +535,7 @@ public class JProgressBar extends JComponent implements SwingConstants,
*/
protected void fireStateChanged()
{
- Object[] changeListeners = changeListenerList.getListenerList();
+ Object[] changeListeners = listenerList.getListenerList();
if (changeEvent == null)
changeEvent = new ChangeEvent(this);
for (int i = changeListeners.length - 2; i >= 0; i -= 2)
diff --git a/libjava/javax/swing/JRadioButtonMenuItem.java b/libjava/javax/swing/JRadioButtonMenuItem.java
index e8623ba7542..cbaf7633d10 100644
--- a/libjava/javax/swing/JRadioButtonMenuItem.java
+++ b/libjava/javax/swing/JRadioButtonMenuItem.java
@@ -39,186 +39,118 @@ package javax.swing;
import java.io.IOException;
import java.io.ObjectOutputStream;
+
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
-/**
- * JRadioButtonMenuItem
- * @author Andrew Selkirk
- * @version 1.0
- */
+
public class JRadioButtonMenuItem extends JMenuItem implements Accessible
{
-
- //-------------------------------------------------------------
- // Classes ----------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * AccessibleJRadioButtonMenuItem
- */
- protected class AccessibleJRadioButtonMenuItem extends AccessibleJMenuItem {
-
- //-------------------------------------------------------------
- // Initialization ---------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * Constructor AccessibleJRadioButtonMenuItem
- * @param component TODO
- */
- protected AccessibleJRadioButtonMenuItem(JRadioButtonMenuItem component) {
- super(component);
- // TODO
- } // AccessibleJRadioButtonMenuItem()
-
-
- //-------------------------------------------------------------
- // Methods ----------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * getAccessibleRole
- * @returns AccessibleRole
- */
- public AccessibleRole getAccessibleRole() {
- return AccessibleRole.RADIO_BUTTON;
- } // getAccessibleRole()
-
-
- } // AccessibleJRadioButtonMenuItem
-
-
- //-------------------------------------------------------------
- // Variables --------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * uiClassID
- */
- private static final String uiClassID = "RadioButtonMenuItemUI";
-
-
- //-------------------------------------------------------------
- // Initialization ---------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * Constructor JRadioButtonMenuItem
- */
- public JRadioButtonMenuItem() {
- // TODO
- } // JRadioButtonMenuItem()
-
- /**
- * Constructor JRadioButtonMenuItem
- * @param icon TODO
- */
- public JRadioButtonMenuItem(Icon icon) {
- // TODO
- } // JRadioButtonMenuItem()
-
- /**
- * Constructor JRadioButtonMenuItem
- * @param text TODO
- */
- public JRadioButtonMenuItem(String text) {
- // TODO
- } // JRadioButtonMenuItem()
-
- /**
- * Constructor JRadioButtonMenuItem
- * @param action TODO
- */
- public JRadioButtonMenuItem(Action action) {
- // TODO
- } // JRadioButtonMenuItem()
-
- /**
- * Constructor JRadioButtonMenuItem
- * @param text TODO
- * @param icon TODO
- */
- public JRadioButtonMenuItem(String text, Icon icon) {
- // TODO
- } // JRadioButtonMenuItem()
-
- /**
- * Constructor JRadioButtonMenuItem
- * @param text TODO
- * @param selected TODO
- */
- public JRadioButtonMenuItem(String text, boolean selected) {
- // TODO
- } // JRadioButtonMenuItem()
-
- /**
- * Constructor JRadioButtonMenuItem
- * @param icon TODO
- * @param selected TODO
- */
- public JRadioButtonMenuItem(Icon icon, boolean selected) {
- // TODO
- } // JRadioButtonMenuItem()
-
- /**
- * Constructor JRadioButtonMenuItem
- * @param text TODO
- * @param icon TODO
- * @param selected TODO
- */
- public JRadioButtonMenuItem(String text, Icon icon, boolean selected) {
- // TODO
- } // JRadioButtonMenuItem()
-
-
- //-------------------------------------------------------------
- // Methods ----------------------------------------------------
- //-------------------------------------------------------------
-
- /**
- * writeObject
- * @param stream TODO
- * @exception IOException TODO
- */
- private void writeObject(ObjectOutputStream stream) throws IOException {
- // TODO
- } // writeObject()
-
- /**
- * getUIClassID
- * @returns String
- */
- public String getUIClassID() {
- return uiClassID;
- } // getUIClassID()
-
- /**
- * requestFocus
- */
- public void requestFocus() {
- // TODO
- } // requestFocus()
-
- /**
- * paramString
- * @returns String
- */
- protected String paramString() {
- return null; // TODO
- } // paramString()
-
- /**
- * getAccessibleContext
- * @returns AccessibleContext
- */
- public AccessibleContext getAccessibleContext() {
- if (accessibleContext == null) {
- accessibleContext = new AccessibleJRadioButtonMenuItem(this);
- } // if
- return accessibleContext;
- } // getAccessibleContext()
-
-
+ //-------------------------------------------------------------
+ // Variables --------------------------------------------------
+ //-------------------------------------------------------------
+ private static final String uiClassID = "RadioButtonMenuItemUI";
+
+ //-------------------------------------------------------------
+ // Initialization ---------------------------------------------
+ //-------------------------------------------------------------
+ public JRadioButtonMenuItem()
+ {
+ this(null, null);
+ } // JRadioButtonMenuItem()
+
+ public JRadioButtonMenuItem(Icon icon)
+ {
+ this(null, icon);
+ } // JRadioButtonMenuItem()
+
+ public JRadioButtonMenuItem(String text)
+ {
+ this(text, null);
+ } // JRadioButtonMenuItem()
+
+ public JRadioButtonMenuItem(Action action)
+ {
+ this();
+ setAction(action);
+ } // JRadioButtonMenuItem()
+
+ public JRadioButtonMenuItem(String text, Icon icon)
+ {
+ this(text, icon, false);
+ } // JRadioButtonMenuItem()
+
+ public JRadioButtonMenuItem(String text, boolean selected)
+ {
+ this(text, null, selected);
+ } // JRadioButtonMenuItem()
+
+ public JRadioButtonMenuItem(Icon icon, boolean selected)
+ {
+ this(null, icon, selected);
+ } // JRadioButtonMenuItem()
+
+ public JRadioButtonMenuItem(String text, Icon icon, boolean selected)
+ {
+ super(text, icon);
+ setModel(new JToggleButton.ToggleButtonModel());
+ model.setSelected(selected);
+ } // JRadioButtonMenuItem()
+
+ //-------------------------------------------------------------
+ // Methods ----------------------------------------------------
+ //-------------------------------------------------------------
+ private void writeObject(ObjectOutputStream stream) throws IOException
+ {
+ // TODO
+ } // writeObject()
+
+ public String getUIClassID()
+ {
+ return uiClassID;
+ } // getUIClassID()
+
+ public void requestFocus()
+ {
+ // TODO
+ } // requestFocus()
+
+ protected String paramString()
+ {
+ return "JRadioButtonMenuItem";
+ } // paramString()
+
+ public AccessibleContext getAccessibleContext()
+ {
+ if (accessibleContext == null)
+ {
+ accessibleContext = new AccessibleJRadioButtonMenuItem(this);
+ }
+ return accessibleContext;
+ } // getAccessibleContext()
+
+ //-------------------------------------------------------------
+ // Classes ----------------------------------------------------
+ //-------------------------------------------------------------
+ protected class AccessibleJRadioButtonMenuItem extends AccessibleJMenuItem
+ {
+ //-------------------------------------------------------------
+ // Initialization ---------------------------------------------
+ //-------------------------------------------------------------
+ protected AccessibleJRadioButtonMenuItem(JRadioButtonMenuItem component)
+ {
+ super(component);
+
+ // TODO
+ } // AccessibleJRadioButtonMenuItem()
+
+ //-------------------------------------------------------------
+ // Methods ----------------------------------------------------
+ //-------------------------------------------------------------
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.RADIO_BUTTON;
+ } // getAccessibleRole()
+ } // AccessibleJRadioButtonMenuItem
} // JRadioButtonMenuItem
diff --git a/libjava/javax/swing/JRootPane.java b/libjava/javax/swing/JRootPane.java
index e7ec0bf806f..4d869d41517 100644
--- a/libjava/javax/swing/JRootPane.java
+++ b/libjava/javax/swing/JRootPane.java
@@ -1,5 +1,5 @@
/* JRootPane.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -43,10 +43,6 @@ import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager;
-import java.awt.LayoutManager2;
-import java.io.Serializable;
-import javax.accessibility.Accessible;
-import javax.accessibility.AccessibleComponent;
/**
* This class is where JComponents are added to.
diff --git a/libjava/javax/swing/JScrollBar.java b/libjava/javax/swing/JScrollBar.java
index 7ee0510fdc9..5636cf3fadf 100644
--- a/libjava/javax/swing/JScrollBar.java
+++ b/libjava/javax/swing/JScrollBar.java
@@ -41,16 +41,14 @@ import java.awt.Adjustable;
import java.awt.Dimension;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
+
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleStateSet;
import javax.accessibility.AccessibleValue;
-import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
-import javax.swing.event.EventListenerList;
-import javax.swing.plaf.ProgressBarUI;
import javax.swing.plaf.ScrollBarUI;
@@ -176,12 +174,6 @@ public class JScrollBar extends JComponent implements Adjustable, Accessible
/** How much the thumb moves when moving in a unit. */
protected int unitIncrement = 1;
- /** A list of all ChangeListeners attached to the scroll bar. */
- private transient EventListenerList changeListenerList;
-
- /** A list of all AdjustmentListeners attached to the scroll bar. */
- private transient EventListenerList adjustmentListenerList;
-
/** The ChangeListener that listens to the model. */
private transient ChangeListener changeListener;
@@ -228,8 +220,6 @@ public class JScrollBar extends JComponent implements Adjustable, Accessible
+ " is not a legal orientation");
this.orientation = orientation;
changeListener = createChangeListener();
- changeListenerList = new EventListenerList();
- adjustmentListenerList = new EventListenerList();
model.addChangeListener(changeListener);
updateUI();
}
@@ -586,7 +576,7 @@ public class JScrollBar extends JComponent implements Adjustable, Accessible
*/
private void fireStateChanged()
{
- Object[] changeListeners = changeListenerList.getListenerList();
+ Object[] changeListeners = listenerList.getListenerList();
if (changeEvent == null)
changeEvent = new ChangeEvent(this);
for (int i = changeListeners.length - 2; i >= 0; i -= 2)
@@ -603,7 +593,7 @@ public class JScrollBar extends JComponent implements Adjustable, Accessible
*/
public void addChangeListener(ChangeListener listener)
{
- changeListenerList.add(ChangeListener.class, listener);
+ listenerList.add(ChangeListener.class, listener);
}
/**
@@ -613,7 +603,7 @@ public class JScrollBar extends JComponent implements Adjustable, Accessible
*/
public void removeChangeListener(ChangeListener listener)
{
- changeListenerList.remove(ChangeListener.class, listener);
+ listenerList.remove(ChangeListener.class, listener);
}
/**
@@ -624,7 +614,7 @@ public class JScrollBar extends JComponent implements Adjustable, Accessible
*/
public ChangeListener[] getChangeListeners()
{
- return (ChangeListener[]) changeListenerList.getListenerList();
+ return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
}
/**
@@ -634,7 +624,7 @@ public class JScrollBar extends JComponent implements Adjustable, Accessible
*/
public void addAdjustmentListener(AdjustmentListener listener)
{
- adjustmentListenerList.add(AdjustmentListener.class, listener);
+ listenerList.add(AdjustmentListener.class, listener);
}
/**
@@ -644,7 +634,7 @@ public class JScrollBar extends JComponent implements Adjustable, Accessible
*/
public void removeAdjustmentListener(AdjustmentListener listener)
{
- adjustmentListenerList.remove(AdjustmentListener.class, listener);
+ listenerList.remove(AdjustmentListener.class, listener);
}
/**
@@ -655,7 +645,7 @@ public class JScrollBar extends JComponent implements Adjustable, Accessible
*/
public AdjustmentListener[] getAdjustmentListeners()
{
- return (AdjustmentListener[]) adjustmentListenerList.getListenerList();
+ return (AdjustmentListener[]) listenerList.getListeners(AdjustmentListener.class);
}
/**
@@ -670,7 +660,7 @@ public class JScrollBar extends JComponent implements Adjustable, Accessible
*/
protected void fireAdjustmentValueChanged(int id, int type, int value)
{
- Object[] adjustmentListeners = adjustmentListenerList.getListenerList();
+ Object[] adjustmentListeners = listenerList.getListenerList();
AdjustmentEvent adjustmentEvent = new AdjustmentEvent(this,
AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
AdjustmentEvent.TRACK,
diff --git a/libjava/javax/swing/JScrollPane.java b/libjava/javax/swing/JScrollPane.java
index f31da048abf..b5c0da0542f 100644
--- a/libjava/javax/swing/JScrollPane.java
+++ b/libjava/javax/swing/JScrollPane.java
@@ -40,17 +40,16 @@ package javax.swing;
import java.awt.Component;
import java.awt.ComponentOrientation;
-import java.awt.LayoutManager;
import java.awt.Insets;
+import java.awt.LayoutManager;
import java.awt.Point;
import java.awt.Rectangle;
-import javax.swing.border.Border;
import javax.accessibility.Accessible;
+import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.ScrollPaneUI;
-import javax.swing.plaf.UIResource;
/**
* <table>
diff --git a/libjava/javax/swing/JSeparator.java b/libjava/javax/swing/JSeparator.java
index 224280b35a6..be0d205c7a0 100644
--- a/libjava/javax/swing/JSeparator.java
+++ b/libjava/javax/swing/JSeparator.java
@@ -37,8 +37,6 @@ exception statement from your version. */
package javax.swing;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
diff --git a/libjava/javax/swing/JSlider.java b/libjava/javax/swing/JSlider.java
index 203dc4a6197..7350ea4ee98 100644
--- a/libjava/javax/swing/JSlider.java
+++ b/libjava/javax/swing/JSlider.java
@@ -37,16 +37,14 @@ exception statement from your version. */
package javax.swing;
-import java.awt.ComponentOrientation;
-import java.awt.MenuContainer;
import java.awt.Dimension;
+import java.awt.MenuContainer;
import java.awt.image.ImageObserver;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;
+
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
@@ -54,7 +52,6 @@ import javax.accessibility.AccessibleStateSet;
import javax.accessibility.AccessibleValue;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
-import javax.swing.event.EventListenerList;
import javax.swing.plaf.SliderUI;
@@ -71,7 +68,7 @@ import javax.swing.plaf.SliderUI;
* </p>
*
* <table>
- * <tr><th> Property </td><th> Stored in </td><th> Bound? </td></tr>
+ * <tr><th> Property </th><th> Stored in </th><th> Bound? </th></tr>
* <tr><td> extent </td><td> model </td><td> no </td></tr>
* <tr><td> inverted </td><td> slider </td><td> yes </td></tr>
* <tr><td> labelTable </td><td> slider </td><td> yes </td></tr>
@@ -253,9 +250,6 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
*/
private transient Dictionary labelTable;
- /** A list of all ChangeListeners listening to this slider. */
- private transient EventListenerList changeListenerList;
-
/** The model used to describe the slider. */
protected BoundedRangeModel sliderModel;
@@ -342,7 +336,6 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
throw new IllegalArgumentException(orientation + " is not a legal orientation");
this.orientation = orientation;
changeListener = createChangeListener();
- changeListenerList = new EventListenerList();
sliderModel.addChangeListener(changeListener);
updateUI();
}
@@ -359,7 +352,6 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
else
sliderModel = model;
changeListener = createChangeListener();
- changeListenerList = new EventListenerList();
sliderModel.addChangeListener(changeListener);
updateUI();
}
@@ -419,7 +411,7 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
* This method returns a name to identify which look and feel class will be
* the UI delegate for the slider.
*
- * @return The L&F classID. "SliderUI"
+ * @return The Look and Feel classID. "SliderUI"
*/
public String getUIClassID()
{
@@ -453,7 +445,7 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
*/
public void addChangeListener(ChangeListener listener)
{
- changeListenerList.add(ChangeListener.class, listener);
+ listenerList.add(ChangeListener.class, listener);
}
/**
@@ -463,7 +455,7 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
*/
public void removeChangeListener(ChangeListener listener)
{
- changeListenerList.remove(ChangeListener.class, listener);
+ listenerList.remove(ChangeListener.class, listener);
}
/**
@@ -473,7 +465,7 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
*/
protected void fireStateChanged()
{
- Object[] changeListeners = changeListenerList.getListenerList();
+ Object[] changeListeners = listenerList.getListenerList();
if (changeEvent == null)
changeEvent = new ChangeEvent(this);
for (int i = changeListeners.length - 2; i >= 0; i -= 2)
@@ -491,7 +483,7 @@ public class JSlider extends JComponent implements SwingConstants, Accessible,
*/
public ChangeListener[] getChangeListeners()
{
- return (ChangeListener[]) changeListenerList.getListenerList();
+ return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
}
/**
diff --git a/libjava/javax/swing/JTabbedPane.java b/libjava/javax/swing/JTabbedPane.java
index a4ea931c100..e0ca953e226 100644
--- a/libjava/javax/swing/JTabbedPane.java
+++ b/libjava/javax/swing/JTabbedPane.java
@@ -1,5 +1,5 @@
-/* JTabbedPane.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+/* JTabbedPane.java --
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -35,98 +35,1446 @@ this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package javax.swing;
+import java.awt.Color;
import java.awt.Component;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.MouseEvent;
+import java.io.Serializable;
import java.util.Vector;
+
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleSelection;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.TabbedPaneUI;
+import javax.swing.plaf.UIResource;
+
-public class JTabbedPane extends JComponent implements Accessible, SwingConstants
+/**
+ * <p>
+ * This is a container for components. One component is displayed at a time.
+ * Users can switch between components by clicking on tabs.
+ * </p>
+ *
+ * <p>
+ * Tabs can be oriented in several ways. They can be above, below, left and
+ * right of the component. Tabs can either wrap around (by creating multiple
+ * rows of tabs) or they can be scrolled (where only a subset of the tabs
+ * can be seen at once). More tabs can be added by calling the
+ * add/addTab/insertTab methods.
+ * </p>
+ */
+public class JTabbedPane extends JComponent implements Serializable,
+ Accessible,
+ SwingConstants
{
- class Tab
+ /**
+ * DOCUMENT ME!
+ */
+ protected class AccessibleJTabbedPane extends JComponent.AccessibleJComponent
+ implements AccessibleSelection, ChangeListener
+ {
+ /**
+ * Creates a new AccessibleJTabbedPane object.
+ *
+ * @param c DOCUMENT ME!
+ */
+ public AccessibleJTabbedPane(JTabbedPane c)
+ {
+ super(c);
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param e DOCUMENT ME!
+ */
+ public void stateChanged(ChangeEvent e)
+ {
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ */
+ public AccessibleRole getAccessibleRole()
+ {
+ return null;
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ */
+ public int getAccessibleChildrenCount()
+ {
+ return 0;
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param i DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ */
+ public Accessible getAccessibleChild(int i)
+ {
+ return null;
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ */
+ public AccessibleSelection getAccessibleSelection()
+ {
+ return null;
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param p DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ */
+ public Accessible getAccessibleAt(Point p)
+ {
+ return null;
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ */
+ public int getAccessibleSelectionCount()
+ {
+ return 0;
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param i DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ */
+ public Accessible getAccessibleSelection(int i)
+ {
+ return null;
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param i DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ */
+ public boolean isAccessibleChildSelected(int i)
+ {
+ return false;
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param i DOCUMENT ME!
+ */
+ public void addAccessibleSelection(int i)
+ {
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param i DOCUMENT ME!
+ */
+ public void removeAccessibleSelection(int i)
+ {
+ }
+
+ /**
+ * DOCUMENT ME!
+ */
+ public void clearAccessibleSelection()
+ {
+ }
+
+ /**
+ * DOCUMENT ME!
+ */
+ public void selectAllAccessibleSelection()
+ {
+ }
+ }
+
+ /**
+ * A helper class that listens for changes to the model.
+ */
+ protected class ModelListener implements ChangeListener, Serializable
+ {
+ /**
+ * This method is called whenever the model is changed.
+ *
+ * @param e The ChangeEvent that is passed from the model.
+ */
+ public void stateChanged(ChangeEvent e)
{
- Icon icon;
- String name, descr;
- Component tab;
+ // Propagate to our listeners.
+ fireStateChanged();
+ }
+ }
+
+ /**
+ * A private class that holds all the information for each tab.
+ */
+ private class Page
+ {
+ /** The tooltip string. */
+ private String tip;
+
+ /** The component associated with the tab. */
+ private Component component;
+
+ /** The active icon associated with the tab. */
+ private transient Icon icon;
+
+ /** The disabled icon associated with the tab. */
+ private transient Icon disabledIcon;
+
+ /** The tab's enabled status. */
+ private transient boolean enabled = true;
- Tab(String name,
- Icon icon,
- Component tab,
- String descr)
- {
- this.name = name;
- this.icon = icon;
- this.tab = tab;
- this.descr = descr;
- }
+ /** The string painted on the tab. */
+ private transient String title;
+
+ /** The background color of the tab. */
+ private transient Color bg;
+
+ /** The foreground color of the tab. */
+ private transient Color fg;
+
+ /** The mnemonic associated with the tab. */
+ private transient int mnemonicKey;
+
+ /** The index of the underlined character in the string. */
+ private transient int underlinedChar = -1;
+
+ /**
+ * Creates a new data storage for the tab.
+ *
+ * @param title The string displayed on the tab.
+ * @param icon The active icon displayed on the tab.
+ * @param component The component associated with the tab.
+ * @param tip The tooltip associated with the tab.
+ */
+ protected Page(String title, Icon icon, Component component, String tip)
+ {
+ this.title = title;
+ this.icon = icon;
+ this.component = component;
+ this.tip = tip;
+ }
+
+ /**
+ * This method returns the component associated with the tab.
+ *
+ * @return The component associated with the tab.
+ */
+ public Component getComponent()
+ {
+ return component;
+ }
+
+ /**
+ * This method sets the component associated with the tab.
+ *
+ * @param c The component associated with the tab.
+ */
+ public void setComponent(Component c)
+ {
+ this.component = c;
+ }
+
+ /**
+ * This method returns the tooltip string.
+ *
+ * @return The tooltip string.
+ */
+ public String getTip()
+ {
+ return tip;
+ }
+
+ /**
+ * This method sets the tooltip string.
+ *
+ * @param tip The tooltip string.
+ */
+ public void setTip(String tip)
+ {
+ this.tip = tip;
+ }
+
+ /**
+ * This method returns the background color.
+ *
+ * @return The background color.
+ */
+ public Color getBackground()
+ {
+ return bg;
+ }
+
+ /**
+ * This method sets the background color.
+ *
+ * @param background The background color.
+ */
+ public void setBackground(Color background)
+ {
+ bg = background;
+ }
+
+ /**
+ * This method returns the foreground color.
+ *
+ * @return The foreground color.
+ */
+ public Color getForeground()
+ {
+ return fg;
+ }
+
+ /**
+ * This method sets the foreground color.
+ *
+ * @param foreground The foreground color.
+ */
+ public void setForeground(Color foreground)
+ {
+ fg = foreground;
+ }
+
+ /**
+ * This method returns the title associated with the tab.
+ *
+ * @return The title of the tab.
+ */
+ public String getTitle()
+ {
+ return title;
}
private static final long serialVersionUID = 1614381073220130939L;
-
- private Vector tabs = new Vector();
- public JTabbedPane()
+ /**
+ * This method sets the title of the tab.
+ *
+ * @param text The title of the tab.
+ */
+ public void setTitle(String text)
{
+ title = text;
+ if (title != null && title.length() <= underlinedChar)
+ setDisplayedMnemonicIndex(title.length() - 1);
}
- public void addTab(String name,
- Component panel)
+ /**
+ * This method returns the active icon.
+ *
+ * @return The active icon.
+ */
+ public Icon getIcon()
{
- addTab(name, null, panel, null);
+ return icon;
}
- public void addTab(String name,
- Icon icon,
- Component panel)
+
+ /**
+ * This method sets the active icon.
+ *
+ * @param icon The active icon.
+ */
+ public void setIcon(Icon icon)
{
- addTab(name, icon, panel, null);
+ this.icon = icon;
}
- public void addTab(String name,
- Icon icon,
- Component panel,
- String descr)
+
+ /**
+ * This method returns the disabled icon.
+ *
+ * @return The disabled icon.
+ */
+ public Icon getDisabledIcon()
{
- tabs.addElement(new Tab(name, icon, panel, descr));
+ if (disabledIcon == null && icon instanceof ImageIcon)
+ setDisabledIcon(icon);
+ return disabledIcon;
}
- public int getTabCount()
+ /**
+ * This method sets the disabled icon.
+ *
+ * @param disabledIcon The disabled icon.
+ */
+ public void setDisabledIcon(Icon disabledIcon)
{
- return tabs.size();
+ this.disabledIcon = disabledIcon;
}
- public Component getComponentAt(int i)
+
+ /**
+ * This method returns whether the tab is enabled.
+ *
+ * @return Whether the tab is enabled.
+ */
+ public boolean isEnabled()
{
- Tab t = (Tab) tabs.elementAt(i);
- return t.tab;
+ return enabled;
}
-
- public String getUIClassID()
- { return "TabbedPaneUI"; }
+ /**
+ * This method sets whether the tab is enabled.
+ *
+ * @param enabled Whether this tab is enabled.
+ */
+ public void setEnabled(boolean enabled)
+ {
+ this.enabled = enabled;
+ }
- public void setUI(TabbedPaneUI ui) {
- super.setUI(ui);
+ /**
+ * This method returns the mnemonic.
+ *
+ * @return The mnemonic.
+ */
+ public int getMnemonic()
+ {
+ return (int) mnemonicKey;
}
-
- public TabbedPaneUI getUI() {
- return (TabbedPaneUI)ui;
+
+ /**
+ * This method sets the mnemonic. If the title is set, it will update the
+ * mnemonicIndex.
+ *
+ * @param key The mnemonic.
+ */
+ public void setMnemonic(int key)
+ {
+ setMnemonic((char) key);
}
-
- public void updateUI()
+
+ /**
+ * This method sets the mnemonic. If the title is set, it will update the
+ * mnemonicIndex.
+ *
+ * @param aChar The mnemonic.
+ */
+ public void setMnemonic(char aChar)
{
- setUI((TabbedPaneUI)UIManager.getUI(this));
+ mnemonicKey = aChar;
+ if (title != null)
+ setDisplayedMnemonicIndex(title.indexOf(mnemonicKey));
}
-
- public AccessibleContext getAccessibleContext()
+
+ /**
+ * This method returns the mnemonicIndex.
+ *
+ * @return The mnemonicIndex.
+ */
+ public int getDisplayedMnemonicIndex()
{
- return null;
+ return underlinedChar;
}
-
- protected String paramString()
+
+ /**
+ * This method sets the mnemonicIndex.
+ *
+ * @param index The mnemonicIndex.
+ *
+ * @throws IllegalArgumentException If index less than -1 || index greater
+ * or equal to title.length.
+ */
+ public void setDisplayedMnemonicIndex(int index)
+ throws IllegalArgumentException
{
- return "JTabbedPane";
+ if (index < -1 || title != null && index >= title.length())
+ throw new IllegalArgumentException();
+
+ if (title == null || title.charAt(index) != mnemonicKey)
+ index = -1;
+
+ underlinedChar = index;
}
+ }
+
+ /** Fired in a PropertyChangeEvent when the "model" property changes. */
+ public static final String MODEL_CHANGED_PROPERTY = "model";
+
+ /**
+ * Fired in a PropertyChangeEvent when the "tabPlacement" property changes.
+ */
+ public static final String TAB_PLACEMENT_CHANGED_PROPERTY = "tabPlacement";
+
+ /**
+ * Fired in a PropertyChangeEvent when the "tabLayoutPolicy" property
+ * changes.
+ */
+ public static final String TAB_LAYOUT_POLICY_CHANGED_PROPERTY = "tabLayoutPolicy";
+
+ /** The changeEvent used to fire changes to listeners. */
+ protected ChangeEvent changeEvent;
+
+ /** The listener that listens to the model. */
+ protected ChangeListener changeListener;
+
+ /** The model that describes this JTabbedPane. */
+ protected SingleSelectionModel model;
+
+ /** Indicates that the TabbedPane is in scrolling mode. */
+ public static int SCROLL_TAB_LAYOUT = 1;
+
+ /** Indicates that the TabbedPane is in wrap mode. */
+ public static int WRAP_TAB_LAYOUT = 0;
+
+ /** The current tabPlacement of the TabbedPane. */
+ protected int tabPlacement = SwingConstants.TOP;
+
+ /** The current tabLayoutPolicy of the TabbedPane. */
+ private transient int layoutPolicy;
+
+ /** The list of tabs associated with the TabbedPane. */
+ transient Vector tabs = new Vector();
+
+ /**
+ * Creates a new JTabbedPane object with tabs on top and using wrap tab
+ * layout.
+ */
+ public JTabbedPane()
+ {
+ this(SwingConstants.TOP, WRAP_TAB_LAYOUT);
+ }
+
+ /**
+ * Creates a new JTabbedPane object using wrap tab layout and the given
+ * tabPlacement.
+ *
+ * @param tabPlacement Where the tabs will be placed.
+ */
+ public JTabbedPane(int tabPlacement)
+ {
+ this(tabPlacement, WRAP_TAB_LAYOUT);
+ }
+
+ /**
+ * Creates a new JTabbedPane object with the given tabPlacement and
+ * tabLayoutPolicy.
+ *
+ * @param tabPlacement Where the tabs will be placed.
+ * @param tabLayoutPolicy The way tabs will be placed.
+ *
+ * @throws IllegalArgumentException If tabLayoutPolicy or tabPlacement are
+ * not valid.
+ */
+ public JTabbedPane(int tabPlacement, int tabLayoutPolicy)
+ {
+ if (tabPlacement != TOP && tabPlacement != BOTTOM && tabPlacement != RIGHT
+ && tabPlacement != LEFT)
+ throw new IllegalArgumentException("tabPlacement is not valid.");
+ if (tabLayoutPolicy != SCROLL_TAB_LAYOUT
+ && tabLayoutPolicy != WRAP_TAB_LAYOUT)
+ throw new IllegalArgumentException("tabLayoutPolicy is not valid.");
+ this.tabPlacement = tabPlacement;
+ layoutPolicy = tabLayoutPolicy;
+
+ changeEvent = new ChangeEvent(this);
+ changeListener = createChangeListener();
+
+ model = new DefaultSingleSelectionModel();
+ model.addChangeListener(changeListener);
+
+ updateUI();
+ }
+
+ /**
+ * This method returns the UI used to display the JTabbedPane.
+ *
+ * @return The UI used to display the JTabbedPane.
+ */
+ public TabbedPaneUI getUI()
+ {
+ return (TabbedPaneUI) ui;
+ }
+
+ /**
+ * This method sets the UI used to display the JTabbedPane.
+ *
+ * @param ui The UI used to display the JTabbedPane.
+ */
+ public void setUI(TabbedPaneUI ui)
+ {
+ super.setUI(ui);
+ }
+
+ /**
+ * This method restores the UI to the defaults given by the UIManager.
+ */
+ public void updateUI()
+ {
+ setUI((TabbedPaneUI) UIManager.getUI(this));
+ invalidate();
+ }
+
+ /**
+ * This method returns a string identifier that is used to determine which
+ * UI will be used with the JTabbedPane.
+ *
+ * @return A string identifier for the UI.
+ */
+ public String getUIClassID()
+ {
+ return "TabbedPaneUI";
+ }
+
+ /**
+ * This method creates a ChangeListener that is used to listen to the model
+ * for events.
+ *
+ * @return A ChangeListener to listen to the model.
+ */
+ protected ChangeListener createChangeListener()
+ {
+ return new ModelListener();
+ }
+
+ /**
+ * This method adds a ChangeListener to the JTabbedPane.
+ *
+ * @param l The ChangeListener to add.
+ */
+ public void addChangeListener(ChangeListener l)
+ {
+ listenerList.add(ChangeListener.class, l);
+ }
+
+ /**
+ * This method removes a ChangeListener to the JTabbedPane.
+ *
+ * @param l The ChangeListener to remove.
+ */
+ public void removeChangeListener(ChangeListener l)
+ {
+ listenerList.remove(ChangeListener.class, l);
+ }
+
+ /**
+ * This method fires a ChangeEvent to all the JTabbedPane's ChangeListeners.
+ */
+ protected void fireStateChanged()
+ {
+ Object[] changeListeners = listenerList.getListenerList();
+ if (changeEvent == null)
+ changeEvent = new ChangeEvent(this);
+ for (int i = changeListeners.length - 2; i >= 0; i -= 2)
+ {
+ if (changeListeners[i] == ChangeListener.class)
+ ((ChangeListener) changeListeners[i + 1]).stateChanged(changeEvent);
+ }
+ }
+
+ /**
+ * This method returns all ChangeListeners registered with the JTabbedPane.
+ *
+ * @return The ChangeListeners registered with the JTabbedPane.
+ */
+ public ChangeListener[] getChangeListeners()
+ {
+ return (ChangeListener[]) super.getListeners(ChangeListener.class);
+ }
+
+ /**
+ * This method returns the model used with the JTabbedPane.
+ *
+ * @return The JTabbedPane's model.
+ */
+ public SingleSelectionModel getModel()
+ {
+ return model;
+ }
+
+ /**
+ * This method changes the model property of the JTabbedPane.
+ *
+ * @param model The new model to use with the JTabbedPane.
+ */
+ public void setModel(SingleSelectionModel model)
+ {
+ if (model != this.model)
+ {
+ SingleSelectionModel oldModel = this.model;
+ this.model.removeChangeListener(changeListener);
+ this.model = model;
+ this.model.addChangeListener(changeListener);
+ firePropertyChange(MODEL_CHANGED_PROPERTY, oldModel, this.model);
+ }
+ }
+
+ /**
+ * This method returns the tabPlacement.
+ *
+ * @return The tabPlacement used with the JTabbedPane.
+ */
+ public int getTabPlacement()
+ {
+ return tabPlacement;
+ }
+
+ /**
+ * This method changes the tabPlacement property of the JTabbedPane.
+ *
+ * @param tabPlacement The tabPlacement to use.
+ *
+ * @throws IllegalArgumentException If tabPlacement is not one of TOP,
+ * BOTTOM, LEFT, or RIGHT.
+ */
+ public void setTabPlacement(int tabPlacement)
+ {
+ if (tabPlacement != TOP && tabPlacement != BOTTOM && tabPlacement != RIGHT
+ && tabPlacement != LEFT)
+ throw new IllegalArgumentException("tabPlacement is not valid.");
+ if (tabPlacement != this.tabPlacement)
+ {
+ int oldPlacement = this.tabPlacement;
+ this.tabPlacement = tabPlacement;
+ firePropertyChange(TAB_PLACEMENT_CHANGED_PROPERTY, oldPlacement,
+ this.tabPlacement);
+ }
+ }
+
+ /**
+ * This method returns the tabLayoutPolicy.
+ *
+ * @return The tabLayoutPolicy.
+ */
+ public int getTabLayoutPolicy()
+ {
+ return layoutPolicy;
+ }
+
+ /**
+ * This method changes the tabLayoutPolicy property of the JTabbedPane.
+ *
+ * @param tabLayoutPolicy The tabLayoutPolicy to use.
+ *
+ * @throws IllegalArgumentException If tabLayoutPolicy is not one of
+ * SCROLL_TAB_LAYOUT or WRAP_TAB_LAYOUT.
+ */
+ public void setTabLayoutPolicy(int tabLayoutPolicy)
+ {
+ if (tabLayoutPolicy != SCROLL_TAB_LAYOUT
+ && tabLayoutPolicy != WRAP_TAB_LAYOUT)
+ throw new IllegalArgumentException("tabLayoutPolicy is not valid.");
+ if (tabLayoutPolicy != layoutPolicy)
+ {
+ int oldPolicy = layoutPolicy;
+ layoutPolicy = tabLayoutPolicy;
+ firePropertyChange(TAB_LAYOUT_POLICY_CHANGED_PROPERTY, oldPolicy,
+ layoutPolicy);
+ }
+ }
+
+ /**
+ * This method returns the index of the tab that is currently selected.
+ *
+ * @return The index of the selected tab.
+ */
+ public int getSelectedIndex()
+ {
+ return model.getSelectedIndex();
+ }
+
+ /**
+ * This method checks the index.
+ *
+ * @param index The index to check.
+ */
+ private void checkIndex(int index, int start, int end)
+ {
+ if (index < start || index >= end)
+ throw new IndexOutOfBoundsException("Index < " + start + " || Index >= " + end);
+ }
+
+ /**
+ * This method sets the selected index. This method
+ * will hide the old component and show the new component.
+ *
+ * @param index The index to set it at.
+ */
+ public void setSelectedIndex(int index)
+ {
+ checkIndex(index, -1, tabs.size());
+ if (index != getSelectedIndex())
+ {
+ if (getSelectedIndex() != -1)
+ getSelectedComponent().hide();
+ if (index != -1)
+ getComponentAt(index).show();
+ }
+ model.setSelectedIndex(index);
+ }
+
+ /**
+ * This method returns the component at the selected index.
+ *
+ * @return The component at the selected index.
+ */
+ public Component getSelectedComponent()
+ {
+ return getComponentAt(getSelectedIndex());
+ }
+
+ /**
+ * This method sets the component at the selected index.
+ *
+ * @param c The component associated with the selected index.
+ */
+ public void setSelectedComponent(Component c)
+ {
+ if (c.getParent() == this)
+ setSelectedIndex(indexOfComponent(c));
+ else
+ setComponentAt(getSelectedIndex(), c);
+ }
+
+ /**
+ * This method inserts tabs into JTabbedPane. This includes
+ * adding the component to the JTabbedPane and hiding it.
+ *
+ * @param title The title of the tab.
+ * @param icon The tab's icon.
+ * @param component The component associated with the tab.
+ * @param tip The tooltip for the tab.
+ * @param index The index to insert the tab at.
+ */
+ public void insertTab(String title, Icon icon, Component component,
+ String tip, int index)
+ {
+ Page p = new Page(title, icon, component, tip);
+ tabs.insertElementAt(p, index);
+
+ // Hide the component so we don't see it. Do it before we parent it
+ // so we don't trigger a repaint.
+ component.hide();
+ super.add(component);
+
+ if (getSelectedIndex() == -1)
+ setSelectedIndex(0);
+
+ layout();
+ }
+
+ /**
+ * This method adds a tab to the JTabbedPane.
+ *
+ * @param title The title of the tab.
+ * @param icon The icon for the tab.
+ * @param component The associated component.
+ * @param tip The associated tooltip.
+ */
+ public void addTab(String title, Icon icon, Component component, String tip)
+ {
+ insertTab(title, icon, component, tip, tabs.size());
+ }
+
+ /**
+ * This method adds a tab to the JTabbedPane.
+ *
+ * @param title The title of the tab.
+ * @param icon The icon for the tab.
+ * @param component The associated component.
+ */
+ public void addTab(String title, Icon icon, Component component)
+ {
+ insertTab(title, icon, component, null, tabs.size());
+ }
+
+ /**
+ * This method adds a tab to the JTabbedPane.
+ *
+ * @param title The title of the tab.
+ * @param component The associated component.
+ */
+ public void addTab(String title, Component component)
+ {
+ insertTab(title, null, component, null, tabs.size());
+ }
+
+ /**
+ * This method adds a tab to the JTabbedPane.
+ * The title of the tab is the Component's name.
+ * If the Component is an instance of UIResource, it doesn't
+ * add the tab and instead add the component directly to the
+ * JTabbedPane.
+ *
+ * @param component The associated component.
+ *
+ * @return The Component that was added.
+ */
+ public Component add(Component component)
+ {
+ if (component instanceof UIResource)
+ super.add(component);
+ else
+ insertTab(component.getName(), null, component, null, tabs.size());
+ return component;
+ }
+
+ /**
+ * This method adds a tab to the JTabbedPane.
+ * If the Component is an instance of UIResource, it doesn't
+ * add the tab and instead add the component directly to the
+ * JTabbedPane.
+ *
+ * @param title The title of the tab.
+ * @param component The associated component.
+ *
+ * @return The Component that was added.
+ */
+ public Component add(String title, Component component)
+ {
+ if (component instanceof UIResource)
+ super.add(component);
+ else
+ insertTab(title, null, component, null, tabs.size());
+ return component;
+ }
+
+ /**
+ * This method adds a tab to the JTabbedPane.
+ * If the Component is an instance of UIResource, it doesn't
+ * add the tab and instead add the component directly to the
+ * JTabbedPane.
+ *
+ * @param component The associated component.
+ * @param index The index to insert the tab at.
+ *
+ * @return The Component that was added.
+ */
+ public Component add(Component component, int index)
+ {
+ if (component instanceof UIResource)
+ super.add(component);
+ else
+ insertTab(component.getName(), null, component, null, index);
+ return component;
+ }
+
+ /**
+ * This method adds a tab to the JTabbedPane.
+ * If the Component is an instance of UIResource, it doesn't
+ * add the tab and instead add the component directly to the
+ * JTabbedPane. If the constraints object is an icon, it
+ * will be used as the tab's icon. If the constraints object
+ * is a string, we will use it as the title.
+ *
+ * @param component The associated component.
+ * @param constraints The constraints object.
+ */
+ public void add(Component component, Object constraints)
+ {
+ add(component, constraints, tabs.size());
+ }
+
+ /**
+ * This method adds a tab to the JTabbedPane.
+ * If the Component is an instance of UIResource, it doesn't
+ * add the tab and instead add the component directly to the
+ * JTabbedPane. If the constraints object is an icon, it
+ * will be used as the tab's icon. If the constraints object
+ * is a string, we will use it as the title.
+ *
+ * @param component The associated component.
+ * @param constraints The constraints object.
+ * @param index The index to insert the tab at.
+ */
+ public void add(Component component, Object constraints, int index)
+ {
+ if (component instanceof UIResource)
+ super.add(component);
+ else
+ {
+ if (constraints instanceof String)
+ insertTab((String) constraints, null, component, null, index);
+ else
+ insertTab(component.getName(),
+ (constraints instanceof Icon) ? (Icon) constraints : null,
+ component, null, index);
+ }
+ }
+
+ /**
+ * The tab and it's associated component are removed. After
+ * the component has been removed from the JTabbedPane, it's
+ * set visible to ensure that it can be seen.
+ *
+ * @param index The index of the tab to remove.
+ *
+ * @throws IndexOutOfBoundsException If the index is not in range.
+ */
+ public void removeTabAt(int index)
+ {
+ checkIndex(index, 0, tabs.size());
+ Component c = getComponentAt(index);
+ super.remove(c);
+ c.show();
+ tabs.remove(index);
+ }
+
+ /**
+ * This method removes the component from the JTabbedPane. After
+ * the component has been removed from the JTabbedPane, it's
+ * set visible to ensure that it can be seen.
+ *
+ * @param component The Component to remove.
+ */
+ public void remove(Component component)
+ {
+ // This simply removes the component.
+ int index = indexOfComponent(component);
+ super.remove(component);
+ component.show();
+ setComponentAt(index, null);
+ }
+
+ /**
+ * This method removes the tab and component from the JTabbedPane.
+ * It simply calls removeTabAt(int index).
+ *
+ * @param index The index of the tab to remove.
+ */
+ public void remove(int index)
+ {
+ removeTabAt(index);
+ }
+
+ /**
+ * This method removes all tabs and associated components
+ * from the JTabbedPane.
+ */
+ public void removeAll()
+ {
+ for (int i = tabs.size() - 1; i >= 0; i--)
+ removeTabAt(i);
+ }
+
+ /**
+ * This method returns how many tabs are in the JTabbedPane.
+ *
+ * @return The number of tabs in the JTabbedPane.
+ */
+ public int getTabCount()
+ {
+ return tabs.size();
+ }
+
+ /**
+ * This method returns the number of runs used
+ * to paint the JTabbedPane.
+ *
+ * @return The number of runs.
+ */
+ public int getTabRunCount()
+ {
+ return ((TabbedPaneUI) ui).getTabRunCount(this);
+ }
+
+ /**
+ * This method returns the tab title given the index.
+ *
+ * @param index The index of the tab.
+ *
+ * @return The title for the tab.
+ */
+ public String getTitleAt(int index)
+ {
+ checkIndex(index, 0, tabs.size());
+ return ((Page) tabs.elementAt(index)).getTitle();
+ }
+
+ /**
+ * This method returns the active icon given the index.
+ *
+ * @param index The index of the tab.
+ *
+ * @return The active icon for the tab.
+ */
+ public Icon getIconAt(int index)
+ {
+ checkIndex(index, 0, tabs.size());
+ return ((Page) tabs.elementAt(index)).getIcon();
+ }
+
+ /**
+ * This method returns the disabled icon given the index.
+ *
+ * @param index The index of the tab.
+ *
+ * @return The disabled icon for the tab.
+ */
+ public Icon getDisabledIconAt(int index)
+ {
+ checkIndex(index, 0, tabs.size());
+ return ((Page) tabs.elementAt(index)).getDisabledIcon();
+ }
+
+ /**
+ * This method returns the tooltip string for the tab.
+ *
+ * @param index The index of the tab.
+ *
+ * @return The tooltip string for the tab.
+ */
+ public String getToolTipTextAt(int index)
+ {
+ checkIndex(index, 0, tabs.size());
+ return ((Page) tabs.elementAt(index)).getTip();
+ }
+
+ /**
+ * This method returns the foreground color for the tab.
+ *
+ * @param index The index of the tab.
+ *
+ * @return The foreground color for the tab.
+ */
+ public Color getForegroundAt(int index)
+ {
+ checkIndex(index, 0, tabs.size());
+ return ((Page) tabs.elementAt(index)).getForeground();
+ }
+
+ /**
+ * This method returns the background color for the tab.
+ *
+ * @param index The index of the tab.
+ *
+ * @return The background color for the tab.
+ */
+ public Color getBackgroundAt(int index)
+ {
+ checkIndex(index, 0, tabs.size());
+ return ((Page) tabs.elementAt(index)).getBackground();
+ }
+
+ /**
+ * This method returns the component associated with the tab.
+ *
+ * @param index The index of the tab.
+ *
+ * @return The component associated with the tab.
+ */
+ public Component getComponentAt(int index)
+ {
+ checkIndex(index, 0, tabs.size());
+ return ((Page) tabs.elementAt(index)).getComponent();
+ }
+
+ /**
+ * This method returns whether this tab is enabled.
+ * Disabled tabs cannot be selected.
+ *
+ * @param index The index of the tab.
+ *
+ * @return Whether the tab is enabled.
+ */
+ public boolean isEnabledAt(int index)
+ {
+ checkIndex(index, 0, tabs.size());
+ return ((Page) tabs.elementAt(index)).isEnabled();
+ }
+
+ /**
+ * This method returns the mnemonic for the tab.
+ *
+ * @param tabIndex The index of the tab.
+ *
+ * @return The mnemonic for the tab.
+ */
+ public int getMnemonicAt(int tabIndex)
+ {
+ checkIndex(tabIndex, 0, tabs.size());
+ return ((Page) tabs.elementAt(tabIndex)).getMnemonic();
+ }
+
+ /**
+ * This method returns the mnemonic index for the tab.
+ *
+ * @param tabIndex The index of the tab.
+ *
+ * @return The mnemonic index for the tab.
+ */
+ public int getDisplayedMnemonicIndexAt(int tabIndex)
+ {
+ checkIndex(tabIndex, 0, tabs.size());
+ return ((Page) tabs.elementAt(tabIndex)).getDisplayedMnemonicIndex();
+ }
+
+ /**
+ * This method returns the bounds of the tab given
+ * the index.
+ *
+ * @param index The index of the tab.
+ *
+ * @return A rectangle describing the bounds of the tab.
+ */
+ public Rectangle getBoundsAt(int index)
+ {
+ checkIndex(index, 0, tabs.size());
+ return ((TabbedPaneUI) ui).getTabBounds(this, index);
+ }
+
+ /**
+ * This method sets the title of the tab.
+ *
+ * @param index The index of the tab.
+ * @param title The new title.
+ */
+ public void setTitleAt(int index, String title)
+ {
+ checkIndex(index, 0, tabs.size());
+ ((Page) tabs.elementAt(index)).setTitle(title);
+ }
+
+ /**
+ * This method sets the icon of the tab.
+ *
+ * @param index The index of the tab.
+ * @param icon The new icon.
+ */
+ public void setIconAt(int index, Icon icon)
+ {
+ checkIndex(index, 0, tabs.size());
+ ((Page) tabs.elementAt(index)).setIcon(icon);
+ }
+
+ /**
+ * This method sets the disabled icon of the tab.
+ *
+ * @param index The index of the tab.
+ * @param disabledIcon The new disabled icon.
+ */
+ public void setDisabledIconAt(int index, Icon disabledIcon)
+ {
+ checkIndex(index, 0, tabs.size());
+ ((Page) tabs.elementAt(index)).setDisabledIcon(disabledIcon);
+ }
+
+ /**
+ * This method sets the tooltip text of the tab.
+ *
+ * @param index The index of the tab.
+ * @param toolTipText The tooltip text.
+ */
+ public void setToolTipTextAt(int index, String toolTipText)
+ {
+ checkIndex(index, 0, tabs.size());
+ ((Page) tabs.elementAt(index)).setTip(toolTipText);
+ }
+
+ /**
+ * This method sets the background color of the tab.
+ *
+ * @param index The index of the tab.
+ * @param background The background color of the tab.
+ */
+ public void setBackgroundAt(int index, Color background)
+ {
+ checkIndex(index, 0, tabs.size());
+ ((Page) tabs.elementAt(index)).setBackground(background);
+ }
+
+ /**
+ * This method sets the foreground color of the tab.
+ *
+ * @param index The index of the tab.
+ * @param foreground The foreground color of the tab.
+ */
+ public void setForegroundAt(int index, Color foreground)
+ {
+ checkIndex(index, 0, tabs.size());
+ ((Page) tabs.elementAt(index)).setForeground(foreground);
+ }
+
+ /**
+ * This method sets whether the tab is enabled.
+ *
+ * @param index The index of the tab.
+ * @param enabled Whether the tab is enabled.
+ */
+ public void setEnabledAt(int index, boolean enabled)
+ {
+ checkIndex(index, 0, tabs.size());
+ ((Page) tabs.elementAt(index)).setEnabled(enabled);
+ }
+
+ /**
+ * This method sets the component associated with the tab.
+ *
+ * @param index The index of the tab.
+ * @param component The component associated with the tab.
+ */
+ public void setComponentAt(int index, Component component)
+ {
+ checkIndex(index, 0, tabs.size());
+ ((Page) tabs.elementAt(index)).setComponent(component);
+ }
+
+ /**
+ * This method sets the displayed mnemonic index of the tab.
+ *
+ * @param tabIndex The index of the tab.
+ * @param mnemonicIndex The mnemonic index.
+ */
+ public void setDisplayedMnemonicIndexAt(int tabIndex, int mnemonicIndex)
+ {
+ checkIndex(tabIndex, 0, tabs.size());
+ ((Page) tabs.elementAt(tabIndex)).setDisplayedMnemonicIndex(mnemonicIndex);
+ }
+
+ /**
+ * This method sets the mnemonic for the tab.
+ *
+ * @param tabIndex The index of the tab.
+ * @param mnemonic The mnemonic.
+ */
+ public void setMnemonicAt(int tabIndex, int mnemonic)
+ {
+ checkIndex(tabIndex, 0, tabs.size());
+ ((Page) tabs.elementAt(tabIndex)).setMnemonic(mnemonic);
+ }
+
+ /**
+ * This method finds the index of a tab given the title.
+ *
+ * @param title The title that belongs to a tab.
+ *
+ * @return The index of the tab that has the title or -1 if not found.
+ */
+ public int indexOfTab(String title)
+ {
+ int index = -1;
+ for (int i = 0; i < tabs.size(); i++)
+ {
+ if (((Page) tabs.elementAt(i)).getTitle().equals(title))
+ {
+ index = i;
+ break;
+ }
+ }
+ return index;
+ }
+
+ /**
+ * This method finds the index of a tab given the icon.
+ *
+ * @param icon The icon that belongs to a tab.
+ *
+ * @return The index of the tab that has the icon or -1 if not found.
+ */
+ public int indexOfTab(Icon icon)
+ {
+ int index = -1;
+ for (int i = 0; i < tabs.size(); i++)
+ {
+ if (((Page) tabs.elementAt(i)).getIcon() == icon)
+ {
+ index = i;
+ break;
+ }
+ }
+ return index;
+ }
+
+ /**
+ * This method finds the index of a tab given the component.
+ *
+ * @param component A component associated with a tab.
+ *
+ * @return The index of the tab that has this component or -1 if not found.
+ */
+ public int indexOfComponent(Component component)
+ {
+ int index = -1;
+ for (int i = 0; i < tabs.size(); i++)
+ {
+ if (((Page) tabs.elementAt(i)).getComponent() == component)
+ {
+ index = i;
+ break;
+ }
+ }
+ return index;
+ }
+
+ /**
+ * This method returns a tab index given an (x,y) location. The origin
+ * of the (x,y) pair will be the JTabbedPane's top left position. The
+ * tab returned will be the one that contains the point. This method is
+ * delegated to the UI.
+ *
+ * @param x The x coordinate of the point.
+ * @param y The y coordinate of the point.
+ *
+ * @return The index of the tab that contains the point.
+ */
+ public int indexAtLocation(int x, int y)
+ {
+ return ((TabbedPaneUI) ui).tabForCoordinate(this, x, y);
+ }
+
+ /**
+ * This method returns the tooltip text given a mouse event.
+ *
+ * @param event The mouse event.
+ *
+ * @return The tool tip text that is associated with this mouse event.
+ */
+ public String getToolTipText(MouseEvent event)
+ {
+ int index = indexAtLocation(event.getX(), event.getY());
+ return ((Page) tabs.elementAt(index)).getTip();
+ }
+
+ /**
+ * This method returns a string representation of this JTabbedPane. It
+ * is mainly used for debugging purposes.
+ *
+ * @return A string representation of this JTabbedPane.
+ */
+ protected String paramString()
+ {
+ return "JTabbedPane";
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleJTabbedPane(this);
+ return accessibleContext;
+ }
}
diff --git a/libjava/javax/swing/JTable.java b/libjava/javax/swing/JTable.java
index 55c6043ff8f..496ae99572c 100644
--- a/libjava/javax/swing/JTable.java
+++ b/libjava/javax/swing/JTable.java
@@ -1,5 +1,5 @@
/* JTable.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,25 +38,21 @@ exception statement from your version. */
package javax.swing;
-import java.awt.Color;
-import java.awt.Component;
import java.awt.Dimension;
import java.awt.Rectangle;
-import java.util.Hashtable;
import java.util.Vector;
+
import javax.accessibility.Accessible;
-import javax.swing.event.ChangeEvent;
import javax.swing.event.CellEditorListener;
+import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
-import javax.swing.table.JTableHeader;
-import javax.swing.table.TableModel;
-import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumnModel;
+import javax.swing.table.TableModel;
public class JTable extends JComponent
implements TableModelListener, Scrollable, TableColumnModelListener,
diff --git a/libjava/javax/swing/JTextField.java b/libjava/javax/swing/JTextField.java
index edc3ea7735b..95fceaf50c6 100644
--- a/libjava/javax/swing/JTextField.java
+++ b/libjava/javax/swing/JTextField.java
@@ -1,5 +1,5 @@
/* JTextField.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,9 +40,8 @@ package javax.swing;
import java.awt.event.ActionListener;
import java.util.Vector;
+
import javax.accessibility.AccessibleStateSet;
-import javax.swing.text.Document;
-import javax.swing.text.JTextComponent;
public class JTextField extends JEditorPane
{
diff --git a/libjava/javax/swing/JToggleButton.java b/libjava/javax/swing/JToggleButton.java
index 297bbc929fe..0977b00c6fe 100644
--- a/libjava/javax/swing/JToggleButton.java
+++ b/libjava/javax/swing/JToggleButton.java
@@ -1,5 +1,5 @@
/* JToggleButton.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -45,7 +45,7 @@ import javax.swing.plaf.ButtonUI;
public class JToggleButton extends AbstractButton implements Accessible
{
- public class ToggleButtonModel extends DefaultButtonModel
+ public static class ToggleButtonModel extends DefaultButtonModel
{
public void setPressed(boolean b)
{
diff --git a/libjava/javax/swing/JToolBar.java b/libjava/javax/swing/JToolBar.java
index 8dce3c14b02..ebc469212c8 100644
--- a/libjava/javax/swing/JToolBar.java
+++ b/libjava/javax/swing/JToolBar.java
@@ -37,14 +37,14 @@ exception statement from your version. */
package javax.swing;
-import java.awt.Dimension;
import java.awt.Component;
-import java.awt.Container;
+import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.io.ObjectOutputStream;
+
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
diff --git a/libjava/javax/swing/JToolTip.java b/libjava/javax/swing/JToolTip.java
index 54e09cf0c60..083bbad02da 100644
--- a/libjava/javax/swing/JToolTip.java
+++ b/libjava/javax/swing/JToolTip.java
@@ -1,5 +1,5 @@
/* JToolTip.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,7 +39,6 @@ exception statement from your version. */
package javax.swing;
import javax.accessibility.Accessible;
-import javax.accessibility.AccessibleContext;
public class JToolTip extends JComponent implements Accessible
{
diff --git a/libjava/javax/swing/JTree.java b/libjava/javax/swing/JTree.java
index bdf519b911e..ca86679d707 100644
--- a/libjava/javax/swing/JTree.java
+++ b/libjava/javax/swing/JTree.java
@@ -1,5 +1,5 @@
/* JTree.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,23 +40,10 @@ package javax.swing;
import java.awt.Dimension;
import java.awt.Rectangle;
-import java.io.Serializable;
-import java.util.Hashtable;
-import java.util.Vector;
+
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
-import javax.swing.event.TreeModelEvent;
-import javax.swing.event.TreeModelListener;
-import javax.swing.event.TreeSelectionEvent;
-import javax.swing.event.TreeSelectionListener;
import javax.swing.plaf.TreeUI;
-import javax.swing.tree.DefaultTreeSelectionModel;
-import javax.swing.tree.TreeCellEditor;
-import javax.swing.tree.TreeCellRenderer;
-import javax.swing.tree.TreeModel;
-import javax.swing.tree.TreeNode;
-import javax.swing.tree.TreePath;
-import javax.swing.tree.TreeSelectionModel;
public class JTree extends JComponent implements Scrollable, Accessible
{
diff --git a/libjava/javax/swing/JViewport.java b/libjava/javax/swing/JViewport.java
index 17e60f1a560..756d5edd555 100644
--- a/libjava/javax/swing/JViewport.java
+++ b/libjava/javax/swing/JViewport.java
@@ -1,5 +1,5 @@
/* JViewport.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,15 +39,12 @@ exception statement from your version. */
package javax.swing;
import java.awt.Component;
-import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
-import java.awt.Image;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
-import java.awt.image.ImageObserver;
-import javax.accessibility.Accessible;
+
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.ViewportUI;
@@ -121,7 +118,7 @@ public class JViewport extends JComponent
Point lastPaintPosition;
- JViewport()
+ public JViewport()
{
setOpaque(true);
updateUI();
diff --git a/libjava/javax/swing/JWindow.java b/libjava/javax/swing/JWindow.java
index 5edf5b25412..11760e92dd6 100644
--- a/libjava/javax/swing/JWindow.java
+++ b/libjava/javax/swing/JWindow.java
@@ -1,5 +1,5 @@
/* JWindow.java --
- Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -44,11 +44,11 @@ import java.awt.Container;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
-import java.awt.GraphicsConfiguration;
import java.awt.LayoutManager;
import java.awt.Window;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
+
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
diff --git a/libjava/javax/swing/KeyStroke.java b/libjava/javax/swing/KeyStroke.java
index c3053aa289e..743d3069d37 100644
--- a/libjava/javax/swing/KeyStroke.java
+++ b/libjava/javax/swing/KeyStroke.java
@@ -1,5 +1,5 @@
/* KeyStroke.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,7 +37,6 @@ exception statement from your version. */
package javax.swing;
-import java.awt.AWTKeyStroke;
import java.awt.event.KeyEvent;
import java.io.Serializable;
diff --git a/libjava/javax/swing/ListModel.java b/libjava/javax/swing/ListModel.java
index e11fc633c0e..1aa7bd20619 100644
--- a/libjava/javax/swing/ListModel.java
+++ b/libjava/javax/swing/ListModel.java
@@ -42,7 +42,7 @@ import javax.swing.event.ListDataListener;
* This is an interface to general list-like data, typically used as the
* model object of a {@link JList} component.
*
- * @author Graydon Hoare (graydon&064;redhat.com)
+ * @author Graydon Hoare (graydon@redhat.com)
*/
public interface ListModel
{
diff --git a/libjava/javax/swing/LookAndFeel.java b/libjava/javax/swing/LookAndFeel.java
index b841a178075..173d2fa825a 100644
--- a/libjava/javax/swing/LookAndFeel.java
+++ b/libjava/javax/swing/LookAndFeel.java
@@ -1,5 +1,5 @@
/* LookAndFeel.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package javax.swing;
-import java.awt.Component;
import javax.swing.text.JTextComponent;
public abstract class LookAndFeel
diff --git a/libjava/javax/swing/Popup.java b/libjava/javax/swing/Popup.java
index b1cb4460a49..1b8d08e3304 100644
--- a/libjava/javax/swing/Popup.java
+++ b/libjava/javax/swing/Popup.java
@@ -163,7 +163,7 @@ public class Popup
/**
- * Displays the popup&#x2019;s <code>JWindow</code> on the screen.
+ * Displays the popup's <code>JWindow</code> on the screen.
* Nothing happens if it is already visible.
*/
public void show()
@@ -173,7 +173,7 @@ public class Popup
/**
- * Removes the popup&#x2019;s <code>JWindow</code> from the
+ * Removes the popup's <code>JWindow</code> from the
* screen. Nothing happens if it is currently not visible.
*/
public void hide()
diff --git a/libjava/javax/swing/SwingUtilities.java b/libjava/javax/swing/SwingUtilities.java
index 36fe017c1ca..e75a95e0f24 100644
--- a/libjava/javax/swing/SwingUtilities.java
+++ b/libjava/javax/swing/SwingUtilities.java
@@ -1,5 +1,5 @@
/* SwingUtilities.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -41,7 +41,6 @@ import java.applet.Applet;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.Container;
-import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
@@ -51,11 +50,8 @@ import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.Window;
-import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.lang.reflect.InvocationTargetException;
-import javax.accessibility.Accessible;
-import javax.accessibility.AccessibleStateSet;
/**
@@ -63,7 +59,7 @@ import javax.accessibility.AccessibleStateSet;
* useful when drawing swing components, dispatching events, or calculating
* regions which need painting.
*
- * @author Graydon Hoare (graydon&064;redhat.com)
+ * @author Graydon Hoare (graydon@redhat.com)
*/
public class SwingUtilities implements SwingConstants
{
diff --git a/libjava/javax/swing/Timer.java b/libjava/javax/swing/Timer.java
index adb695a1035..fd88351f417 100644
--- a/libjava/javax/swing/Timer.java
+++ b/libjava/javax/swing/Timer.java
@@ -1,5 +1,5 @@
/* Timer.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -42,7 +42,7 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.Serializable;
import java.util.EventListener;
-import java.util.Vector;
+
import javax.swing.event.EventListenerList;
public class Timer implements Serializable
diff --git a/libjava/javax/swing/ToolTipManager.java b/libjava/javax/swing/ToolTipManager.java
index ba86f13cd4b..762d5d338b6 100644
--- a/libjava/javax/swing/ToolTipManager.java
+++ b/libjava/javax/swing/ToolTipManager.java
@@ -37,7 +37,6 @@ exception statement from your version. */
package javax.swing;
-import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
diff --git a/libjava/javax/swing/UIDefaults.java b/libjava/javax/swing/UIDefaults.java
index da23a54d344..8141399f549 100644
--- a/libjava/javax/swing/UIDefaults.java
+++ b/libjava/javax/swing/UIDefaults.java
@@ -1,5 +1,5 @@
/* UIDefaults.java -- database for all settings and interface bindings.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -44,17 +44,16 @@ import java.awt.Insets;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.Method;
-import java.lang.reflect.Constructor;
+import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
import java.util.LinkedList;
+import java.util.ListIterator;
import java.util.Locale;
-import java.util.Set;
-import java.util.HashSet;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
+import java.util.Set;
+
import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI;
diff --git a/libjava/javax/swing/border/TitledBorder.java b/libjava/javax/swing/border/TitledBorder.java
index 3b6a791630c..8b9fe2a73be 100644
--- a/libjava/javax/swing/border/TitledBorder.java
+++ b/libjava/javax/swing/border/TitledBorder.java
@@ -1,5 +1,5 @@
/* TitledBorder.java --
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -45,8 +45,8 @@ import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
-import java.awt.Rectangle;
import java.awt.Shape;
+
import javax.swing.UIManager;
diff --git a/libjava/javax/swing/filechooser/FileSystemView.java b/libjava/javax/swing/filechooser/FileSystemView.java
index 759149756fc..f224349a50b 100644
--- a/libjava/javax/swing/filechooser/FileSystemView.java
+++ b/libjava/javax/swing/filechooser/FileSystemView.java
@@ -1,5 +1,5 @@
/* FileSystemView.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,7 +40,6 @@ package javax.swing.filechooser;
import java.io.File;
import java.io.IOException;
-import javax.swing.Icon;
/**
* FileSystemView
diff --git a/libjava/javax/swing/plaf/BorderUIResource.java b/libjava/javax/swing/plaf/BorderUIResource.java
index a3f0db026fd..c0bb2402fe7 100644
--- a/libjava/javax/swing/plaf/BorderUIResource.java
+++ b/libjava/javax/swing/plaf/BorderUIResource.java
@@ -279,7 +279,7 @@ public class BorderUIResource
*
* <p><img src="../border/doc-files/BevelBorder-1.png"
* width="500" height="150"
- * alt="[An illustration showing raised and lowered BevelBorders]" />
+ * alt="[An illustration showing raised and lowered BevelBorders]" /></p>
*
* @param bevelType the desired appearance of the border. The value
* must be either {@link javax.swing.border.BevelBorder#RAISED}
@@ -300,7 +300,7 @@ public class BorderUIResource
*
* <p><img src="../border/doc-files/BevelBorder-2.png" width="500"
* height="150" alt="[An illustration showing BevelBorders that were
- * constructed with this method]" />
+ * constructed with this method]" /></p>
*
* @param bevelType the desired appearance of the border. The value
* must be either {@link javax.swing.border.BevelBorder#RAISED}
@@ -340,7 +340,7 @@ public class BorderUIResource
*
* <p><img src="../border/doc-files/BevelBorder-3.png" width="500"
* height="150" alt="[An illustration showing BevelBorders that
- * were constructed with this method]" />
+ * were constructed with this method]" /></p>
*
* @param bevelType the desired appearance of the border. The value
* must be either {@link javax.swing.border.BevelBorder#RAISED}
@@ -432,7 +432,7 @@ public class BorderUIResource
*
* <p><img src="../border/doc-files/EmptyBorder-1.png"
* width="290" height="200"
- * alt="[An illustration of EmptyBorder]" />
+ * alt="[An illustration of EmptyBorder]" /></p>
*
* @author Brian Jones (cbj@gnu.org)
* @author Sascha Brawer (brawer@dandelis.ch)
@@ -487,7 +487,7 @@ public class BorderUIResource
*
* <p><img src="../border/doc-files/EtchedBorder-1.png" width="500"
* height="200" alt="[An illustration of the two EtchedBorder
- * variants]" />
+ * variants]" /></p>
*
* @author Brian Jones (cbj@gnu.org)
* @author Sascha Brawer (brawer@dandelis.ch)
@@ -514,7 +514,7 @@ public class BorderUIResource
*
* <p><img src="../border/doc-files/EtchedBorder-1.png"
* width="500" height="200" alt="[An illustration of the two
- * EtchedBorder variants]" />
+ * EtchedBorder variants]" /></p>
*
* @param etchType the desired appearance of the border. The value
* must be either {@link javax.swing.border.EtchedBorder#RAISED}
@@ -555,7 +555,7 @@ public class BorderUIResource
*
* <p><img src="../border/doc-files/EtchedBorder-2.png" width="500"
* height="200" alt="[An illustration that shows which pixels get
- * painted in what color]" />
+ * painted in what color]" /></p>
*
* @param etchType the desired appearance of the border. The value
* must be either {@link javax.swing.border.EtchedBorder#RAISED}
@@ -588,7 +588,7 @@ public class BorderUIResource
* such as the borders provided by this class.
*
* <p><img src="../border/doc-files/LineBorder-1.png" width="500"
- * height="200" alt="[An illustration of two LineBorders] />
+ * height="200" alt="[An illustration of two LineBorders]" /></p>
*
* @author Brian Jones (cbj@gnu.org)
* @author Sascha Brawer (brawer@dandelis.ch)
@@ -643,7 +643,7 @@ public class BorderUIResource
* such as the borders provided by this class.
*
* <p><img src="../border/doc-files/MatteBorder-1.png" width="500"
- * height="150" alt="[An illustration of two MatteBorders] />
+ * height="150" alt="[An illustration of two MatteBorders]" /></p>
*
* @author Brian Jones (cbj@gnu.org)
* @author Sascha Brawer (brawer@dandelis.ch)
@@ -658,7 +658,7 @@ public class BorderUIResource
*
* <p><img src="../border/doc-files/MatteBorder-2.png" width="500"
* height="150" alt="[A picture of a MatteBorder made by this
- * constructor]" />
+ * constructor]" /></p>
*
* @param top the width of the border at its top edge.
* @param left the width of the border at its left edge.
@@ -680,7 +680,7 @@ public class BorderUIResource
*
* <p><img src="../border/doc-files/MatteBorder-4.png" width="500"
* height="150" alt="[A picture of a MatteBorder made by this
- * constructor]" />
+ * constructor]" /></p>
*
* @param top the width of the border at its top edge.
* @param left the width of the border at its left edge.
@@ -704,7 +704,7 @@ public class BorderUIResource
*
* <p><img src="../border/doc-files/MatteBorder-6.png" width="500"
* height="150" alt="[A picture of a MatteBorder made by this
- * constructor]" />
+ * constructor]" /></p>
*
* @param tileIcon an icon for tiling the border area.
*/
diff --git a/libjava/javax/swing/plaf/ComponentUI.java b/libjava/javax/swing/plaf/ComponentUI.java
index 5147ebb9609..a2ca1f00941 100644
--- a/libjava/javax/swing/plaf/ComponentUI.java
+++ b/libjava/javax/swing/plaf/ComponentUI.java
@@ -52,7 +52,7 @@ import javax.swing.JComponent;
*
* <p><img src="doc-files/ComponentUI-1.png" width="700" height="550"
* alt="[UML diagram illustrating the architecture for pluggable
- * look and feels]" />
+ * look and feels]" /></p>
*
* <p>Components such as {@link javax.swing.JSlider} do not directly
* implement operations related to the look and feel of the user
@@ -68,14 +68,14 @@ import javax.swing.JComponent;
* services. Soon before the end of its lifecycle, the
* <code>ComponentUI</code> will receive an {@link #uninstallUI}
* message, at which time the <code>ComponentUI</code> is expected to
- * undo any changes.
+ * undo any changes.</p>
*
* <p>Note that the <code>ui</code> of a <code>JComponent</code>
* changes whenever the user switches between look and feels. For
* example, the <code>ui</code> property of a <code>JSlider</code>
* could change from an instance of <code>MetalSliderUI</code> to an
* instance of <code>FooSliderUI</code>. This switch can happen at any
- * time, but it will always be performed from inside the Swing thread.
+ * time, but it will always be performed from inside the Swing thread.</p>
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
@@ -96,26 +96,24 @@ public abstract class ComponentUI
* The delegate object then receives an <code>installUI</code>
* message.
*
- * <p>This method should perform the following tasks:
- *
- * <ul><li>Set visual properties such as borders, fonts, colors, or
- * icons. However, no change should be performed for those
- * properties whose values have been directly set by the client
- * application. To allow the distinction, LookAndFeels are expected
- * to use values that implement the {@link UIResource} marker
- * interface, such as {@link BorderUIResource} or {@link
- * ColorUIResource}.</li>
+ * <p>This method should perform the following tasks:</p>
*
+ * <ul>
+ * <li>Set visual properties such as borders, fonts, colors, or
+ * icons. However, no change should be performed for those
+ * properties whose values have been directly set by the client
+ * application. To allow the distinction, LookAndFeels are expected
+ * to use values that implement the {@link UIResource} marker
+ * interface, such as {@link BorderUIResource} or {@link
+ * ColorUIResource}.</li>
* <li>If necessary, install a {@link java.awt.LayoutManager}.</li>
- *
* <li>Embed custom sub-components. For instance, the UI delegate
- * for a {@link javax.swing.JSplitPane} might install a special
- * component for the divider.</li>
- *
+ * for a {@link javax.swing.JSplitPane} might install a special
+ * component for the divider.</li>
* <li>Register event listeners.</li>
- *
* <li>Set up properties related to keyborad navigation, such as
- * mnemonics or focus traversal policies.</li></ul>
+ * mnemonics or focus traversal policies.</li>
+ * </ul>
*
* @param c the component for which this delegate will provide
* services.
diff --git a/libjava/javax/swing/plaf/basic/BasicArrowButton.java b/libjava/javax/swing/plaf/basic/BasicArrowButton.java
new file mode 100644
index 00000000000..cb2c99baf58
--- /dev/null
+++ b/libjava/javax/swing/plaf/basic/BasicArrowButton.java
@@ -0,0 +1,363 @@
+/* BasicArrowButton.java
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.SwingConstants;
+
+
+/**
+ * This class draws simple arrow buttons for the Basic Look and Feel.
+ */
+public class BasicArrowButton extends JButton implements SwingConstants
+{
+ /**
+ * A private helper class that draws icons.
+ */
+ private class arrowIcon implements Icon
+ {
+ /** The polygon that describes the icon. */
+ private Polygon arrow;
+
+ /** The size of the icon. */
+ private int size = 10;
+
+ /**
+ * Creates a new arrowIcon object using the given arrow polygon.
+ *
+ * @param arrow The polygon that describes the arrow.
+ */
+ public arrowIcon(Polygon arrow)
+ {
+ this.arrow = arrow;
+ }
+
+ /**
+ * Returns the height of the icon.
+ *
+ * @return The height of the icon.
+ */
+ public int getIconHeight()
+ {
+ return size;
+ }
+
+ /**
+ * Returns the width of the icon.
+ *
+ * @return The width of the icon.
+ */
+ public int getIconWidth()
+ {
+ return size;
+ }
+
+ /**
+ * Sets the size of the icon.
+ *
+ * @param size The size of the icon.
+ */
+ public void setSize(int size)
+ {
+ this.size = size;
+ }
+
+ /**
+ * Sets the arrow polygon.
+ *
+ * @param arrow The arrow polygon.
+ */
+ public void setArrow(Polygon arrow)
+ {
+ this.arrow = arrow;
+ }
+
+ /**
+ * Paints the icon.
+ *
+ * @param c The Component to paint for.
+ * @param g The Graphics object to draw with.
+ * @param x The X coordinate to draw at.
+ * @param y The Y coordinate to draw at.
+ */
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ Color arrowColor;
+ if (c.isEnabled())
+ arrowColor = darkShadow;
+ else
+ arrowColor = shadow;
+
+ paintIconImpl(g, x, y, arrowColor);
+ }
+
+ /**
+ * This method does the actual painting work.
+ *
+ * @param g The Graphics object to paint with.
+ * @param x The x coordinate to paint at.
+ * @param y The y coordinate to paint at.
+ * @param arrowColor The color to paint the arrow with.
+ */
+ public void paintIconImpl(Graphics g, int x, int y, Color arrowColor)
+ {
+ g.translate(x, y);
+
+ Color saved = g.getColor();
+
+ g.setColor(arrowColor);
+
+ g.fillPolygon(arrow);
+
+ g.setColor(saved);
+ g.translate(-x, -y);
+ }
+ }
+
+ /** The direction to point in. */
+ protected int direction;
+
+ /** The color the arrow is painted in if disabled and the bottom and
+ * right edges of the button. */
+ private transient Color shadow = Color.BLACK;
+
+ /** The color the arrow is painted in if enabled and the bottom and
+ * right edges of the button. */
+ private transient Color darkShadow = Color.BLACK;
+
+ /** The top and left edges of the button. */
+ private transient Color highlight = Color.BLACK;
+
+ /**
+ * Creates a new BasicArrowButton object.
+ *
+ * @param direction The direction the arrow points in.
+ */
+ public BasicArrowButton(int direction)
+ {
+ super();
+ setDirection(direction);
+ }
+
+ /**
+ * Creates a new BasicArrowButton object with the given colors and
+ * direction.
+ *
+ * @param direction The direction to point in.
+ * @param background The background color.
+ * @param shadow The shadow color.
+ * @param darkShadow The dark shadow color.
+ * @param highlight The highlight color.
+ */
+ public BasicArrowButton(int direction, Color background, Color shadow,
+ Color darkShadow, Color highlight)
+ {
+ this(direction);
+ setBackground(background);
+ this.shadow = shadow;
+ this.darkShadow = darkShadow;
+ this.highlight = highlight;
+ }
+
+ /**
+ * This method returns the direction of the arrow.
+ *
+ * @return The direction of the arrow.
+ */
+ public int getDirection()
+ {
+ return direction;
+ }
+
+ /**
+ * This method changes the direction of the arrow.
+ *
+ * @param dir The new direction of the arrow.
+ */
+ public void setDirection(int dir)
+ {
+ Polygon arrow = getArrow(dir, 10);
+ if (getIcon() == null)
+ setIcon(new arrowIcon(arrow));
+ else
+ ((arrowIcon) getIcon()).setArrow(arrow);
+ this.direction = dir;
+ }
+
+ /**
+ * This method paints the arrow button.
+ *
+ * @param g The Graphics object to paint with.
+ */
+ public void paint(Graphics g)
+ {
+ super.paint(g);
+ Rectangle bounds = getBounds();
+
+ Color saved = g.getColor();
+ g.setColor(highlight);
+
+ g.drawLine(bounds.x, bounds.y, bounds.x, bounds.y + bounds.height);
+ g.drawLine(bounds.x, bounds.y, bounds.x + bounds.width, bounds.y);
+
+ g.setColor(shadow);
+
+ g.drawLine(bounds.x + 1, bounds.y + bounds.height - 1,
+ bounds.x + bounds.width - 1, bounds.y + bounds.height - 1);
+ g.drawLine(bounds.x + bounds.width - 1, bounds.y + 1,
+ bounds.x + bounds.width - 1, bounds.y + bounds.height - 1);
+
+ g.setColor(darkShadow);
+
+ g.drawLine(bounds.x, bounds.y + bounds.height, bounds.x + bounds.width,
+ bounds.y + bounds.height);
+ g.drawLine(bounds.x + bounds.width, bounds.y, bounds.x + bounds.width,
+ bounds.y + bounds.height);
+
+ g.setColor(saved);
+ }
+
+ /**
+ * This method returns the preferred size of the arrow button.
+ *
+ * @return The preferred size.
+ */
+ public Dimension getPreferredSize()
+ {
+ return new Dimension(getIcon().getIconWidth(), getIcon().getIconHeight());
+ }
+
+ /**
+ * This method returns the minimum size of the arrow button.
+ *
+ * @return The minimum size.
+ */
+ public Dimension getMinimumSize()
+ {
+ return getPreferredSize();
+ }
+
+ /**
+ * This method returns the maximum size of the arrow button.
+ *
+ * @return The maximum size.
+ */
+ public Dimension getMaximumSize()
+ {
+ return getPreferredSize();
+ }
+
+ /**
+ * The method paints a triangle with the given size and direction at
+ * the given x and y coordinates.
+ *
+ * @param g The Graphics object to paint with.
+ * @param x The x coordinate to paint at.
+ * @param y The y coordinate to paint at.
+ * @param size The size of the icon.
+ * @param direction The direction of the icon.
+ * @param isEnabled Whether it is enabled.
+ */
+ public void paintTriangle(Graphics g, int x, int y, int size, int direction,
+ boolean isEnabled)
+ {
+ Polygon arrow = getArrow(direction, size);
+ arrowIcon arrowI = new arrowIcon(arrow);
+ arrowI.setSize(size);
+
+ Color arrowColor;
+ if (isEnabled())
+ arrowColor = darkShadow;
+ else
+ arrowColor = shadow;
+
+ arrowI.paintIconImpl(g, x, y, arrowColor);
+ }
+
+ /**
+ * This is a private helper that creates polygons for a given size
+ * and direction.
+ *
+ * @param direction The direction of the arrow.
+ * @param size The size of the arrow.
+ *
+ * @return A new arrow polygon.
+ */
+ private Polygon getArrow(int direction, int size)
+ {
+ Polygon arrow;
+ double dsize = (double) size;
+
+ int two = (int) (dsize * 2 / 10);
+ int three = (int) (dsize * 3 / 10);
+ int five = (int) (dsize * 5 / 10);
+ int seven = (int) (dsize * 7 / 10);
+ int eight = (int) (dsize * 8 / 10);
+ switch (direction)
+ {
+ case NORTH:
+ arrow = new Polygon(new int[] { two, five, eight },
+ new int[] { seven, three, seven }, 3);
+ break;
+ case SOUTH:
+ arrow = new Polygon(new int[] { two, five, eight },
+ new int[] { three, seven, three }, 3);
+ break;
+ case EAST:
+ case RIGHT:
+ arrow = new Polygon(new int[] { three, seven, three },
+ new int[] { two, five, eight }, 3);
+ break;
+ case WEST:
+ case LEFT:
+ arrow = new Polygon(new int[] { seven, three, seven },
+ new int[] { two, five, eight }, 3);
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid direction given.");
+ }
+ return arrow;
+ }
+}
diff --git a/libjava/javax/swing/plaf/basic/BasicButtonListener.java b/libjava/javax/swing/plaf/basic/BasicButtonListener.java
index 98b4c8b3c53..4dafc7e9f0b 100644
--- a/libjava/javax/swing/plaf/basic/BasicButtonListener.java
+++ b/libjava/javax/swing/plaf/basic/BasicButtonListener.java
@@ -45,13 +45,12 @@ import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
+
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
-import javax.swing.UIDefaults;
-import javax.swing.UIManager;
+import javax.swing.JComponent;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
-import javax.swing.JComponent;
public class BasicButtonListener
implements MouseListener, MouseMotionListener, FocusListener,
diff --git a/libjava/javax/swing/plaf/basic/BasicButtonUI.java b/libjava/javax/swing/plaf/basic/BasicButtonUI.java
index 5dbd17ecfa8..663050ee685 100644
--- a/libjava/javax/swing/plaf/basic/BasicButtonUI.java
+++ b/libjava/javax/swing/plaf/basic/BasicButtonUI.java
@@ -44,15 +44,9 @@ import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
-import java.awt.Stroke;
-import java.awt.Insets;
import java.awt.Rectangle;
-import java.awt.event.FocusListener;
-import java.awt.event.FocusAdapter;
-import java.awt.event.FocusEvent;
-import java.awt.event.InputEvent;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
+import java.awt.Stroke;
+
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.Icon;
@@ -60,7 +54,6 @@ import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
-import javax.swing.event.MouseInputListener;
import javax.swing.plaf.ButtonUI;
import javax.swing.plaf.ComponentUI;
diff --git a/libjava/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java b/libjava/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java
new file mode 100644
index 00000000000..84c8e392357
--- /dev/null
+++ b/libjava/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java
@@ -0,0 +1,75 @@
+/* BasicCheckBoxMenuItemUI.java
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.event.MouseEvent;
+
+import javax.swing.JComponent;
+import javax.swing.JMenuItem;
+import javax.swing.MenuElement;
+import javax.swing.MenuSelectionManager;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.plaf.ComponentUI;
+
+
+public class BasicCheckBoxMenuItemUI extends BasicMenuItemUI
+{
+ public static ComponentUI createUI(final JComponent c)
+ {
+ return new BasicCheckBoxMenuItemUI();
+ }
+
+ protected String getPropertyPrefix()
+ {
+ return null; // TODO
+ }
+
+ protected void installDefaults()
+ {
+ super.installDefaults();
+
+ UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+ checkIcon = defaults.getIcon("CheckBoxMenuItem.checkIcon");
+ }
+
+ void processMouseEvent(JMenuItem item, MouseEvent e, MenuElement[] path,
+ MenuSelectionManager manager)
+ {
+ }
+}
diff --git a/libjava/javax/swing/plaf/basic/BasicGraphicsUtils.java b/libjava/javax/swing/plaf/basic/BasicGraphicsUtils.java
index 1f2f7444db1..0645a373c2b 100644
--- a/libjava/javax/swing/plaf/basic/BasicGraphicsUtils.java
+++ b/libjava/javax/swing/plaf/basic/BasicGraphicsUtils.java
@@ -45,11 +45,9 @@ import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
-
import java.awt.font.FontRenderContext;
import java.awt.font.LineMetrics;
import java.awt.font.TextLayout;
-
import java.awt.geom.Rectangle2D;
import javax.swing.AbstractButton;
diff --git a/libjava/javax/swing/plaf/basic/BasicIconFactory.java b/libjava/javax/swing/plaf/basic/BasicIconFactory.java
index 39e86b6fbbc..ef071aa0b77 100644
--- a/libjava/javax/swing/plaf/basic/BasicIconFactory.java
+++ b/libjava/javax/swing/plaf/basic/BasicIconFactory.java
@@ -196,11 +196,11 @@ public class BasicIconFactory implements Serializable
}
public static Icon getCheckBoxMenuItemIcon()
{
- return new DummyIcon();
+ return getCheckBoxIcon();
}
public static Icon getRadioButtonMenuItemIcon()
{
- return new DummyIcon();
+ return getRadioButtonIcon();
}
public static Icon createEmptyFrameIcon()
{
diff --git a/libjava/javax/swing/plaf/basic/BasicLabelUI.java b/libjava/javax/swing/plaf/basic/BasicLabelUI.java
index 219c6fab02e..669c7063645 100644
--- a/libjava/javax/swing/plaf/basic/BasicLabelUI.java
+++ b/libjava/javax/swing/plaf/basic/BasicLabelUI.java
@@ -46,10 +46,10 @@ import java.awt.Insets;
import java.awt.Rectangle;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
+
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JLabel;
-import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
diff --git a/libjava/javax/swing/plaf/basic/BasicLookAndFeel.java b/libjava/javax/swing/plaf/basic/BasicLookAndFeel.java
index c4d3d80a77c..7a60c8e9336 100644
--- a/libjava/javax/swing/plaf/basic/BasicLookAndFeel.java
+++ b/libjava/javax/swing/plaf/basic/BasicLookAndFeel.java
@@ -501,7 +501,7 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"MenuBar.windowBindings", new Object[] {
"F10", "takeFocus"
},
- "MenuItem.acceleratorDelimiter", "+",
+ "MenuItem.acceleratorDelimiter", "-",
"MenuItem.acceleratorFont", new FontUIResource("Dialog", Font.PLAIN, 12),
"MenuItem.acceleratorForeground", new ColorUIResource(Color.black),
"MenuItem.acceleratorSelectionForeground", new ColorUIResource(Color.white),
@@ -703,9 +703,9 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"ctrl UP", "requestFocus",
"ctrl KP_UP", "requestFocus"
}),
- "TabbedPane.background", new ColorUIResource(Color.lightGray),
+ "TabbedPane.background", new ColorUIResource(Color.GRAY),
"TabbedPane.contentBorderInsets", new InsetsUIResource(2, 2, 3, 3),
- "TabbedPane.darkShadow", new ColorUIResource(Color.black),
+ "TabbedPane.darkShadow", new ColorUIResource(Color.darkGray),
"TabbedPane.focus", new ColorUIResource(Color.black),
"TabbedPane.focusInputMap", new UIDefaults.LazyInputMap(new Object[] {
"LEFT", "navigateLeft",
@@ -725,8 +725,10 @@ public abstract class BasicLookAndFeel extends LookAndFeel
"TabbedPane.lightHighlight", new ColorUIResource(Color.white),
"TabbedPane.selectedTabPadInsets", new InsetsUIResource(2, 2, 2, 1),
"TabbedPane.shadow", new ColorUIResource(Color.gray),
- "TabbedPane.tabAreaInsets", new InsetsUIResource(3, 2, 0, 2),
- "TabbedPane.tabInsets", new InsetsUIResource(0, 4, 1, 4),
+ "TabbedPane.tabbedPaneTabAreaInsets", new InsetsUIResource(3, 2, 1, 2),
+ "TabbedPane.tabbedPaneTabInsets", new InsetsUIResource(1, 4, 1, 4),
+ "TabbedPane.tabbedPaneContentBorderInsets", new InsetsUIResource(3, 2, 1, 2),
+ "TabbedPane.tabbedPaneTabPadInsets", new InsetsUIResource(1, 1, 1, 1),
"TabbedPane.tabRunOverlay", new Integer(2),
"TabbedPane.textIconGap", new Integer(4),
"Table.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] {
diff --git a/libjava/javax/swing/plaf/basic/BasicMenuItemUI.java b/libjava/javax/swing/plaf/basic/BasicMenuItemUI.java
new file mode 100644
index 00000000000..886ca9dbce6
--- /dev/null
+++ b/libjava/javax/swing/plaf/basic/BasicMenuItemUI.java
@@ -0,0 +1,632 @@
+/* BasicMenuItemUI.java
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
+
+import javax.swing.AbstractButton;
+import javax.swing.ButtonModel;
+import javax.swing.Icon;
+import javax.swing.JComponent;
+import javax.swing.JMenuItem;
+import javax.swing.KeyStroke;
+import javax.swing.MenuElement;
+import javax.swing.MenuSelectionManager;
+import javax.swing.SwingUtilities;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.event.MenuDragMouseEvent;
+import javax.swing.event.MenuDragMouseListener;
+import javax.swing.event.MenuKeyEvent;
+import javax.swing.event.MenuKeyListener;
+import javax.swing.event.MouseInputListener;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.MenuItemUI;
+
+
+public class BasicMenuItemUI extends MenuItemUI
+{
+ /** Font to be used when displaying menu item's accelerator. */
+ protected Font acceleratorFont;
+
+ /** Color to be used when displaying menu item's accelerator. */
+ protected Color acceleratorForeground;
+
+ /** Color to be used when displaying menu item's accelerator
+ * when menu item is selected.
+ */
+ protected Color acceleratorSelectionForeground;
+
+ /**
+ * Icon that is displayed after the text to indicated that this menu
+ * contains submenu.
+ */
+ protected Icon arrowIcon;
+
+ /**
+ * Icon that is displayed before the text. This icon is only used in
+ * JCheckBoxMenuItem or JRadioBoxMenuItem.
+ */
+ protected Icon checkIcon;
+
+ /** Number of spaces between icon and text. */
+ protected int defaultTextIconGap = 4;
+
+ /** Color of the text when menu item is disabled*/
+ protected Color disabledForeground;
+
+ /** The menu Drag mouse listener listening to the menu item. */
+ protected MenuDragMouseListener menuDragMouseListener;
+
+ /** The menu item itself*/
+ protected JMenuItem menuItem;
+
+ /** Menu Key listener listening to the menu item. */
+ protected MenuKeyListener menuKeyListener;
+
+ /** mouse input listener listening to menu item. */
+ protected MouseInputListener mouseInputListener;
+
+ /** Indicates if border should be painted */
+ protected boolean oldBorderPainted;
+
+ /** Color of text that is used when menu item is selected */
+ protected Color selectionBackground;
+
+ /** Color of the background that is used when menu item is selected.*/
+ protected Color selectionForeground;
+
+ /** String that separates description of the modifiers and the key*/
+ private String acceleratorDelimiter;
+
+ /** Number of spaces between accelerator and menu item's label. */
+ private int defaultAcceleratorLabelGap = 4;
+
+ // Constructor Summary
+ BasicMenuItemUI()
+ {
+ mouseInputListener = createMouseInputListener(menuItem);
+ menuDragMouseListener = createMenuDragMouseListener(menuItem);
+ menuKeyListener = createMenuKeyListener(menuItem);
+ }
+
+ // Method Summary
+ protected MenuDragMouseListener createMenuDragMouseListener(JComponent c)
+ {
+ return new MenuDragMouseHandler();
+ }
+
+ protected MenuKeyListener createMenuKeyListener(JComponent c)
+ {
+ return new MenuKeyHandler();
+ }
+
+ protected MouseInputListener createMouseInputListener(JComponent c)
+ {
+ return new MouseInputHandler();
+ }
+
+ public static ComponentUI createUI(JComponent c)
+ {
+ return new BasicMenuItemUI();
+ }
+
+ protected void doClick(MenuSelectionManager msm)
+ {
+ // TODO
+ }
+
+ public Dimension getMaximumSize(JComponent c)
+ {
+ // TODO
+ return null;
+ }
+
+ public Dimension getMinimumSize(JComponent c)
+ {
+ // TODO
+ return null;
+ }
+
+ public MenuElement[] getPath()
+ {
+ // TODO
+ return null;
+ }
+
+ protected Dimension getPreferredMenuItemSize(JComponent c, Icon checkIcon,
+ Icon arrowIcon,
+ int defaultTextIconGap)
+ {
+ // TODO
+ return null;
+ }
+
+ public Dimension getPreferredSize(JComponent c)
+ {
+ AbstractButton b = (AbstractButton) c;
+ Dimension d = BasicGraphicsUtils.getPreferredButtonSize(b,
+ defaultTextIconGap);
+
+ // if menu item has accelerator then take accelerator's size into account
+ // when calculating preferred size.
+
+ KeyStroke accelerator = ((JMenuItem) c).getAccelerator();
+ Rectangle rect;
+ if (accelerator != null)
+ {
+ rect = getAcceleratorRect(accelerator,
+ b.getToolkit().getFontMetrics(acceleratorFont));
+
+ // add width of accelerator's text
+ d.width = d.width + rect.width + defaultAcceleratorLabelGap;
+
+ // adjust the heigth of the preferred size if necessary
+ if (d.height < rect.height)
+ d.height = rect.height;
+ }
+
+ if (checkIcon != null)
+ {
+ d.width = d.width + checkIcon.getIconWidth() + defaultTextIconGap;
+ if (checkIcon.getIconHeight() > d.height)
+ d.height = checkIcon.getIconHeight();
+ }
+
+ return d;
+ }
+
+ protected String getPropertyPrefix()
+ {
+ // TODO
+ return null;
+ }
+
+ protected void installComponents(JMenuItem menuItem)
+ {
+ // TODO
+ }
+
+ protected void installDefaults()
+ {
+ UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+ menuItem.setBackground(defaults.getColor("MenuItem.background"));
+ menuItem.setBorder(defaults.getBorder("MenuItem.border"));
+ menuItem.setFont(defaults.getFont("MenuItem.font"));
+ menuItem.setForeground(defaults.getColor("MenuItem.foreground"));
+ menuItem.setMargin(defaults.getInsets("MenuItem.margin"));
+ acceleratorFont = defaults.getFont("MenuItem.acceleratorFont");
+ acceleratorForeground = defaults.getColor("MenuItem.acceleratorForeground");
+ acceleratorSelectionForeground = defaults.getColor("MenuItem.acceleratorSelectionForeground");
+ arrowIcon = defaults.getIcon("MenuItem.arrowIcon");
+ selectionBackground = defaults.getColor("MenuItem.selectionBackground");
+ selectionForeground = defaults.getColor("MenuItem.selectionForeground");
+ acceleratorDelimiter = defaults.getString("MenuItem.acceleratorDelimiter");
+ }
+
+ protected void installKeyboardActions()
+ {
+ // TODO
+ }
+
+ protected void installListeners()
+ {
+ menuItem.addMouseListener(mouseInputListener);
+ menuItem.addMenuDragMouseListener(menuDragMouseListener);
+ menuItem.addMenuKeyListener(menuKeyListener);
+ }
+
+ public void installUI(JComponent c)
+ {
+ super.installUI(c);
+ menuItem = (JMenuItem) c;
+ installDefaults();
+ installListeners();
+ }
+
+ public void paint(Graphics g, JComponent c)
+ {
+ paintMenuItem(g, c, checkIcon, arrowIcon, c.getBackground(),
+ c.getForeground(), defaultTextIconGap);
+ }
+
+ protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor)
+ {
+ Dimension size = getPreferredSize(menuItem);
+ Color foreground = g.getColor();
+ g.setColor(bgColor);
+ g.drawRect(0, 0, size.width, size.height);
+ g.setColor(foreground);
+ }
+
+ protected void paintMenuItem(Graphics g, JComponent c, Icon checkIcon,
+ Icon arrowIcon, Color background,
+ Color foreground, int defaultTextIconGap)
+ {
+ AbstractButton b = (AbstractButton) c;
+ Rectangle tr = new Rectangle(); // text rectangle
+ Rectangle ir = new Rectangle(); // icon rectangle
+ Rectangle vr = new Rectangle(); // view rectangle
+ Rectangle br = new Rectangle(); // border rectangle
+ Rectangle ar = new Rectangle(); // accelerator rectangle
+ Rectangle cr = new Rectangle(); // checkIcon rectangle
+
+ int vertAlign = b.getVerticalAlignment();
+ int horAlign = b.getHorizontalAlignment();
+ int vertTextPos = b.getVerticalTextPosition();
+ int horTextPos = b.getHorizontalTextPosition();
+
+ Font f = c.getFont();
+ g.setFont(f);
+ FontMetrics fm = g.getFontMetrics(f);
+ SwingUtilities.calculateInnerArea(b, br);
+ SwingUtilities.calculateInsetArea(br, b.getMargin(), vr);
+ paintBackground(g, (JMenuItem) c, c.getBackground());
+
+ if ((b.getModel().isArmed() && b.getModel().isPressed()))
+ {
+ if (((AbstractButton) b).isContentAreaFilled())
+ {
+ g.setColor(b.getBackground().darker());
+ g.fillRect(br.x, br.y, br.width, br.height);
+ }
+ }
+ else
+ {
+ if (((AbstractButton) b).isContentAreaFilled())
+ {
+ g.setColor(b.getBackground());
+ g.fillRect(br.x, br.y, br.width, br.height);
+ }
+ }
+
+
+ if (checkIcon != null)
+ {
+ SwingUtilities.layoutCompoundLabel(c, fm, null, checkIcon, vertAlign,
+ horAlign, vertTextPos, horTextPos,
+ vr, cr, tr, defaultTextIconGap);
+ checkIcon.paintIcon(c, g, cr.x, cr.y);
+
+ // We need to calculate position of the menu text and position of
+ // user menu icon if there exists one relative to the check icon.
+ // So we need to adjust view rectangle s.t. its starting point is at
+ // checkIcon.width + defaultTextIconGap.
+
+ vr.x = cr.x + cr.width + defaultTextIconGap;
+ }
+
+ if (arrowIcon != null)
+ {
+ // FIXME: if this menu contains a submenu, we need to draw arrow icon
+ // here as well
+ }
+
+
+ // paint text and user menu icon if it exists
+ SwingUtilities.layoutCompoundLabel(c, fm, b.getText(), b.getIcon(),
+ vertAlign, horAlign, vertTextPos,
+ horTextPos, vr, ir, tr,
+ defaultTextIconGap);
+
+ paintText(g, (JMenuItem) c, tr, b.getText());
+
+ // paint icon
+ // FIXME: should paint different icon at different button state's.
+ // i.e disabled icon when button is disabled.. etc.
+
+ /*
+ Icon i = b.getIcon();
+ if (i != null)
+ {
+ int x = ir.x;
+ int y = ir.y;
+ i.paintIcon(c, g, x, y);
+ }
+ */
+
+ // paint accelerator
+ String acceleratorText = "";
+ if (((JMenuItem) c).getAccelerator() != null)
+ {
+ acceleratorText = getAcceleratorText(((JMenuItem) c).getAccelerator());
+ fm = g.getFontMetrics(acceleratorFont);
+ ar.width = fm.stringWidth(acceleratorText);
+ ar.x = br.width - ar.width;
+ vr.x = br.width - ar.width;
+
+ SwingUtilities.layoutCompoundLabel(c, fm, acceleratorText, null,
+ vertAlign, horAlign, vertTextPos,
+ horTextPos, vr, ir, ar,
+ defaultTextIconGap);
+
+ paintAccelerator(g, (JMenuItem) c, ar, acceleratorText);
+
+ }
+
+ }
+
+ protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect,
+ String text)
+ {
+ Font f = menuItem.getFont();
+ g.setFont(f);
+ FontMetrics fm = g.getFontMetrics(f);
+ g.setColor(menuItem.getForeground());
+
+ BasicGraphicsUtils.drawString(g, text, 0, textRect.x,
+ textRect.y + fm.getAscent());
+ }
+
+ protected void uninstallComponents(JMenuItem menuItem)
+ {
+ // TODO
+ }
+
+ protected void uninstallDefaults()
+ {
+ menuItem.setForeground(null);
+ menuItem.setBackground(null);
+ menuItem.setBorder(null);
+ menuItem.setMargin(null);
+ menuItem.setBackground(null);
+ menuItem.setBorder(null);
+ menuItem.setFont(null);
+ menuItem.setForeground(null);
+ menuItem.setMargin(null);
+ acceleratorFont = null;
+ acceleratorForeground = null;
+ acceleratorSelectionForeground = null;
+ arrowIcon = null;
+ selectionBackground = null;
+ selectionForeground = null;
+ acceleratorDelimiter = null;
+ }
+
+ protected void uninstallKeyboardActions()
+ {
+ // TODO
+ }
+
+ protected void uninstallListeners()
+ {
+ menuItem.removeMouseListener(mouseInputListener);
+ menuItem.removeMenuDragMouseListener(menuDragMouseListener);
+ menuItem.removeMenuKeyListener(menuKeyListener);
+ }
+
+ public void uninstallUI(JComponent c)
+ {
+ uninstallListeners();
+ uninstallDefaults();
+ menuItem = null;
+ }
+
+ public void update(Graphics g, JComponent c)
+ {
+ // TODO
+ }
+
+ private String getAcceleratorText(KeyStroke accelerator)
+ {
+
+ // convert keystroke into string format
+
+ String modifiersText = "";
+ int modifiers = accelerator.getModifiers();
+ char keyChar = accelerator.getKeyChar();
+ int keyCode = accelerator.getKeyCode();
+
+ if (modifiers != 0)
+ modifiersText = KeyEvent.getKeyModifiersText(modifiers) +
+ acceleratorDelimiter;
+
+ if (keyCode == KeyEvent.VK_UNDEFINED)
+ return modifiersText + keyChar;
+ else
+ return modifiersText + KeyEvent.getKeyText(keyCode);
+ }
+
+ private Rectangle getAcceleratorRect(KeyStroke accelerator, FontMetrics fm)
+ {
+ int width = fm.stringWidth(getAcceleratorText(accelerator));
+ int height = fm.getHeight();
+ return new Rectangle(0, 0, width, height);
+ }
+
+ private void paintAccelerator(Graphics g, JMenuItem menuItem, Rectangle acceleratorRect,
+ String acceleratorText)
+ {
+ g.setFont(acceleratorFont);
+ FontMetrics fm = g.getFontMetrics(acceleratorFont);
+ g.setColor(acceleratorForeground);
+ BasicGraphicsUtils.drawString(g, acceleratorText, 0, acceleratorRect.x,
+ acceleratorRect.y + fm.getAscent());
+ }
+
+ protected class MouseInputHandler implements MouseInputListener
+ {
+ protected MouseInputHandler()
+ {
+ }
+
+ public void mouseClicked(MouseEvent e)
+ {
+ }
+
+ public void mouseDragged(MouseEvent e)
+ {
+ }
+
+ public void mouseEntered(MouseEvent e)
+ {
+ if (e.getSource() instanceof AbstractButton)
+ {
+ AbstractButton button = (AbstractButton) e.getSource();
+ ButtonModel model = button.getModel();
+
+ if (button.isRolloverEnabled())
+ {
+ model.setRollover(true);
+ }
+
+ if (model.isPressed() &&
+ ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0))
+ {
+ model.setArmed(true);
+ }
+ else
+ {
+ model.setArmed(false);
+ }
+ }
+ }
+
+ public void mouseExited(MouseEvent e)
+ {
+ if (e.getSource() instanceof AbstractButton)
+ {
+ AbstractButton button = (AbstractButton) e.getSource();
+ ButtonModel model = button.getModel();
+
+ if (button.isRolloverEnabled())
+ {
+ model.setRollover(false);
+ }
+
+ model.setArmed(false);
+ }
+ }
+
+ public void mouseMoved(MouseEvent e)
+ {
+ }
+
+ public void mousePressed(MouseEvent e)
+ {
+ if (e.getSource() instanceof AbstractButton)
+ {
+ AbstractButton button = (AbstractButton) e.getSource();
+ ButtonModel model = button.getModel();
+
+ if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0)
+ {
+ // It is important that these transitions happen in this order.
+ model.setArmed(true);
+ model.setPressed(true);
+ }
+ }
+ }
+
+ public void mouseReleased(MouseEvent e)
+ {
+
+ if (e.getSource() instanceof AbstractButton)
+ {
+ AbstractButton button = (AbstractButton) e.getSource();
+ ButtonModel model = button.getModel();
+
+ if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0)
+ {
+ // It is important that these transitions happen in this order.
+ model.setPressed(false);
+ model.setArmed(false);
+ }
+ }
+ }
+ }
+
+ protected class MenuDragMouseHandler implements MenuDragMouseListener
+ {
+ public void menuDragMouseDragged(MenuDragMouseEvent e)
+ {
+ // TODO
+ }
+
+ public void menuDragMouseEntered(MenuDragMouseEvent e)
+ {
+ // TODO
+ }
+
+ public void menuDragMouseExited(MenuDragMouseEvent e)
+ {
+ // TODO
+ }
+
+ public void menuDragMouseReleased(MenuDragMouseEvent e)
+ {
+ // TODO
+ }
+ }
+
+ protected class MenuKeyHandler implements MenuKeyListener
+ {
+ public void menuKeyPressed(MenuKeyEvent e)
+ {
+ // TODO
+ }
+
+ public void menuKeyReleased(MenuKeyEvent e)
+ {
+ // TODO
+ }
+
+ public void menuKeyTyped(MenuKeyEvent e)
+ {
+ // TODO
+ }
+ }
+
+ protected class PropertyChangeHandler
+ {
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ // TODO
+ }
+ }
+}
diff --git a/libjava/javax/swing/plaf/basic/BasicProgressBarUI.java b/libjava/javax/swing/plaf/basic/BasicProgressBarUI.java
index bf5cd0a7aa9..673c502a547 100644
--- a/libjava/javax/swing/plaf/basic/BasicProgressBarUI.java
+++ b/libjava/javax/swing/plaf/basic/BasicProgressBarUI.java
@@ -573,7 +573,7 @@ public class BasicProgressBarUI extends ProgressBarUI
}
}
- if (progressBar.isStringPainted())
+ if (progressBar.isStringPainted() && !progressBar.getString().equals(""))
paintString(g, 0, 0, or.width, or.height, amountFull, insets);
g.setColor(saved);
}
@@ -605,7 +605,7 @@ public class BasicProgressBarUI extends ProgressBarUI
g.setColor(c.getForeground());
g.fill3DRect(box.x, box.y, box.width, box.height, true);
- if (progressBar.isStringPainted())
+ if (progressBar.isStringPainted() && !progressBar.getString().equals(""))
paintString(g, 0, 0, or.width, or.height,
getAmountFull(insets, or.width, or.height), insets);
diff --git a/libjava/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java b/libjava/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java
new file mode 100644
index 00000000000..9a9f2e89c66
--- /dev/null
+++ b/libjava/javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java
@@ -0,0 +1,76 @@
+/* BasicRadioButtonMenuItemUI.java
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.swing.plaf.basic;
+
+import java.awt.event.MouseEvent;
+
+import javax.swing.JComponent;
+import javax.swing.JMenuItem;
+import javax.swing.MenuElement;
+import javax.swing.MenuSelectionManager;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.plaf.ComponentUI;
+
+
+public class BasicRadioButtonMenuItemUI extends BasicMenuItemUI
+{
+
+ public BasicRadioButtonMenuItemUI()
+ {
+ super();
+ UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+ checkIcon = defaults.getIcon("RadioButtonMenuItem.checkIcon");
+ }
+
+ public static ComponentUI createUI(JComponent b)
+ {
+ return new BasicRadioButtonMenuItemUI();
+ }
+
+ protected String getPropertyPrefix()
+ {
+ return null;
+ // TODO
+ }
+
+ void processMouseEvent(JMenuItem item, MouseEvent e, MenuElement[] path,
+ MenuSelectionManager manager)
+ {
+ }
+}
diff --git a/libjava/javax/swing/plaf/basic/BasicRootPaneUI.java b/libjava/javax/swing/plaf/basic/BasicRootPaneUI.java
index 70829d10f89..e6472160587 100644
--- a/libjava/javax/swing/plaf/basic/BasicRootPaneUI.java
+++ b/libjava/javax/swing/plaf/basic/BasicRootPaneUI.java
@@ -1,5 +1,5 @@
/* BasicPanelUI.java
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,9 +38,9 @@ exception statement from your version. */
package javax.swing.plaf.basic;
-import javax.swing.*;
-import javax.swing.plaf.*;
-import java.awt.*;
+import javax.swing.JComponent;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.RootPaneUI;
public class BasicRootPaneUI extends RootPaneUI
diff --git a/libjava/javax/swing/plaf/basic/BasicScrollBarUI.java b/libjava/javax/swing/plaf/basic/BasicScrollBarUI.java
index f0f56d30c79..d6b31a2bafa 100644
--- a/libjava/javax/swing/plaf/basic/BasicScrollBarUI.java
+++ b/libjava/javax/swing/plaf/basic/BasicScrollBarUI.java
@@ -41,8 +41,6 @@ import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.LayoutManager;
@@ -56,6 +54,7 @@ import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
+
import javax.swing.BoundedRangeModel;
import javax.swing.Icon;
import javax.swing.JButton;
diff --git a/libjava/javax/swing/plaf/basic/BasicScrollPaneUI.java b/libjava/javax/swing/plaf/basic/BasicScrollPaneUI.java
index 4f60fb48dc5..2148a92104e 100644
--- a/libjava/javax/swing/plaf/basic/BasicScrollPaneUI.java
+++ b/libjava/javax/swing/plaf/basic/BasicScrollPaneUI.java
@@ -40,8 +40,8 @@ package javax.swing.plaf.basic;
import java.awt.Dimension;
import java.awt.Graphics;
+
import javax.swing.JComponent;
-import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneLayout;
import javax.swing.plaf.ComponentUI;
diff --git a/libjava/javax/swing/plaf/basic/BasicSliderUI.java b/libjava/javax/swing/plaf/basic/BasicSliderUI.java
index 2ee481e317d..05e3bb334f2 100644
--- a/libjava/javax/swing/plaf/basic/BasicSliderUI.java
+++ b/libjava/javax/swing/plaf/basic/BasicSliderUI.java
@@ -40,7 +40,6 @@ package javax.swing.plaf.basic;
import java.awt.Color;
import java.awt.Component;
import java.awt.ComponentOrientation;
-import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
@@ -54,22 +53,20 @@ import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
-import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Dictionary;
import java.util.Enumeration;
-import javax.swing.JButton;
+
+import javax.swing.BoundedRangeModel;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JSlider;
-import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
-import javax.swing.BoundedRangeModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.MouseInputAdapter;
diff --git a/libjava/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/libjava/javax/swing/plaf/basic/BasicTabbedPaneUI.java
index bbdcfb5500a..4dcec822537 100644
--- a/libjava/javax/swing/plaf/basic/BasicTabbedPaneUI.java
+++ b/libjava/javax/swing/plaf/basic/BasicTabbedPaneUI.java
@@ -1,5 +1,5 @@
/* BasicTabbedPaneUI.java
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -28,82 +28,3006 @@ permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
+independent module, the terms and conditions of7 the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
package javax.swing.plaf.basic;
+import java.awt.Color;
import java.awt.Component;
+import java.awt.Container;
import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
import java.awt.Insets;
+import java.awt.LayoutManager;
+import java.awt.Point;
import java.awt.Rectangle;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import javax.swing.Icon;
import javax.swing.JComponent;
+import javax.swing.JPanel;
import javax.swing.JTabbedPane;
+import javax.swing.JViewport;
+import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.PanelUI;
import javax.swing.plaf.TabbedPaneUI;
+import javax.swing.plaf.UIResource;
+import javax.swing.text.View;
-public class BasicTabbedPaneUI extends TabbedPaneUI
- implements SwingConstants
+
+/**
+ * This is the Basic Look and Feel's UI delegate for JTabbedPane.
+ */
+public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
{
- public static ComponentUI createUI(final JComponent c)
+ /**
+ * A helper class that handles focus.
+ */
+ protected class FocusHandler extends FocusAdapter
+ {
+ /**
+ * This method is called when the component gains focus.
+ *
+ * @param e The FocusEvent.
+ */
+ public void focusGained(FocusEvent e)
+ {
+ // FIXME: Implement.
+ }
+
+ /**
+ * This method is called when the component loses focus.
+ *
+ * @param e The FocusEvent.
+ */
+ public void focusLost(FocusEvent e)
+ {
+ // FIXME: Implement.
+ }
+ }
+
+ /**
+ * A helper class for determining if mouse presses occur inside tabs and
+ * sets the index appropriately. In SCROLL_TAB_MODE, this class also
+ * handles the mouse clicks on the scrolling buttons.
+ */
+ protected class MouseHandler extends MouseAdapter
+ {
+ /**
+ * This method is called when the mouse is pressed. The index cannot
+ * change to a tab that is not enabled.
+ *
+ * @param e The MouseEvent.
+ */
+ public void mousePressed(MouseEvent e)
+ {
+ int x = e.getX();
+ int y = e.getY();
+ int tabCount = tabPane.getTabCount();
+
+ if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
+ {
+ if (e.getSource() == incrButton)
+ {
+ if (++currentScrollLocation >= tabCount)
+ currentScrollLocation = tabCount - 1;
+ if (currentScrollLocation == tabCount - 1)
+ incrButton.setEnabled(false);
+ else if (! decrButton.isEnabled())
+ decrButton.setEnabled(true);
+ tabPane.layout();
+ tabPane.repaint();
+ return;
+ }
+ else if (e.getSource() == decrButton)
+ {
+ if (--currentScrollLocation < 0)
+ currentScrollLocation = 0;
+ if (currentScrollLocation == 0)
+ decrButton.setEnabled(false);
+ else if (! incrButton.isEnabled())
+ incrButton.setEnabled(true);
+ tabPane.layout();
+ tabPane.repaint();
+ return;
+ }
+ }
+
+ int index = tabForCoordinate(tabPane, x, y);
+
+ // We need to check since there are areas where tabs cannot be
+ // e.g. in the inset area.
+ if (index != -1 && tabPane.isEnabledAt(index))
+ tabPane.setSelectedIndex(index);
+ }
+ }
+
+ /**
+ * This class handles PropertyChangeEvents fired from the JTabbedPane.
+ */
+ protected class PropertyChangeHandler implements PropertyChangeListener
+ {
+ /**
+ * This method is called whenever one of the properties of the JTabbedPane
+ * changes.
+ *
+ * @param e The PropertyChangeEvent.
+ */
+ public void propertyChange(PropertyChangeEvent e)
+ {
+ if (e.getPropertyName().equals(JTabbedPane.TAB_LAYOUT_POLICY_CHANGED_PROPERTY))
+ {
+ layoutManager = createLayoutManager();
+
+ tabPane.setLayout(layoutManager);
+ }
+ else if (e.getPropertyName().equals(JTabbedPane.TAB_PLACEMENT_CHANGED_PROPERTY)
+ && tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
+ {
+ incrButton = createIncreaseButton();
+ decrButton = createDecreaseButton();
+ }
+ tabPane.layout();
+ tabPane.repaint();
+ }
+ }
+
+ /**
+ * A LayoutManager responsible for placing all the tabs and the visible
+ * component inside the JTabbedPane. This class is only used for
+ * WRAP_TAB_LAYOUT.
+ */
+ protected class TabbedPaneLayout implements LayoutManager
+ {
+ /**
+ * This method is called when a component is added to the JTabbedPane.
+ *
+ * @param name The name of the component.
+ * @param comp The component being added.
+ */
+ public void addLayoutComponent(String name, Component comp)
+ {
+ // Do nothing.
+ }
+
+ /**
+ * This method is called when the rectangles need to be calculated. It
+ * also fixes the size of the visible component.
+ */
+ public void calculateLayoutInfo()
+ {
+ calculateTabRects(tabPane.getTabPlacement(), tabPane.getTabCount());
+
+ if (tabPane.getSelectedIndex() != -1)
+ {
+ Component visible = getVisibleComponent();
+ Insets insets = getContentBorderInsets(tabPane.getTabPlacement());
+ visible.setBounds(contentRect.x + insets.left,
+ contentRect.y + insets.top,
+ contentRect.width - insets.left - insets.right,
+ contentRect.height - insets.top - insets.bottom);
+ }
+ }
+
+ /**
+ * This method calculates the size of the the JTabbedPane.
+ *
+ * @param minimum Whether the JTabbedPane will try to be as small as it
+ * can.
+ *
+ * @return The desired size of the JTabbedPane.
+ */
+ protected Dimension calculateSize(boolean minimum)
+ {
+ int tabPlacement = tabPane.getTabPlacement();
+ int width = 0;
+ int height = 0;
+
+ int componentHeight = 0;
+ int componentWidth = 0;
+ Component c;
+ Dimension dims;
+ for (int i = 0; i < tabPane.getTabCount(); i++)
+ {
+ c = tabPane.getComponentAt(i);
+ if (c == null)
+ continue;
+ calcRect = c.getBounds();
+ dims = c.getPreferredSize();
+ if (dims != null)
+ {
+ componentHeight = Math.max(componentHeight, dims.height);
+ componentWidth = Math.max(componentWidth, dims.width);
+ }
+ }
+ Insets insets = tabPane.getInsets();
+
+ if (tabPlacement == SwingConstants.TOP
+ || tabPlacement == SwingConstants.BOTTOM)
+ {
+ width = calculateMaxTabWidth(tabPlacement) * tabPane.getTabCount();
+ calcRect = tabPane.getParent().getBounds();
+ width = Math.max(width, componentWidth);
+
+ int tabAreaHeight = preferredTabAreaHeight(tabPlacement, width);
+ height = tabAreaHeight + componentHeight;
+ }
+ else
+ {
+ height = calculateMaxTabHeight(tabPlacement) * tabPane.getTabCount();
+ calcRect = tabPane.getParent().getBounds();
+ height = Math.max(height, componentHeight);
+
+ int tabAreaWidth = preferredTabAreaWidth(tabPlacement, height);
+ width = tabAreaWidth + componentWidth;
+ }
+
+ return new Dimension(width, height);
+ }
+
+ // if tab placement is LEFT OR RIGHT, they share width.
+ // if tab placement is TOP OR BOTTOM, they share height
+ // PRE STEP: finds the default sizes for the labels as well as their locations.
+ // AND where they will be placed within the run system.
+ // 1. calls normalizeTab Runs.
+ // 2. calls rotate tab runs.
+ // 3. pads the tab runs.
+ // 4. pads the selected tab.
+
+ /**
+ * This method is called to calculate the tab rectangles. This method
+ * will calculate the size and position of all rectangles (taking into
+ * account which ones should be in which tab run). It will pad them and
+ * normalize them as necessary.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param tabCount The run the current selection is in.
+ */
+ protected void calculateTabRects(int tabPlacement, int tabCount)
+ {
+ if (tabCount == 0)
+ return;
+ assureRectsCreated(tabCount);
+
+ FontMetrics fm = getFontMetrics();
+ SwingUtilities.calculateInnerArea(tabPane, calcRect);
+ Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
+ Insets insets = tabPane.getInsets();
+ int max = 0;
+ int runs = 0;
+ int start = getTabRunIndent(tabPlacement, 1);
+ if (tabPlacement == SwingConstants.TOP
+ || tabPlacement == SwingConstants.BOTTOM)
+ {
+ int maxHeight = calculateMaxTabHeight(tabPlacement);
+
+ calcRect.width -= tabAreaInsets.left + tabAreaInsets.right;
+ max = calcRect.width + tabAreaInsets.left + insets.left;
+ start += tabAreaInsets.left + insets.left;
+ int width = 0;
+ int runWidth = start;
+
+ for (int i = 0; i < tabCount; i++)
+ {
+ width = calculateTabWidth(tabPlacement, i, fm);
+
+ if (runWidth + width > max)
+ {
+ runWidth = tabAreaInsets.left + insets.left
+ + getTabRunIndent(tabPlacement, ++runs);
+ rects[i] = new Rectangle(runWidth,
+ insets.top + tabAreaInsets.top,
+ width, maxHeight);
+ runWidth += width;
+ if (runs > tabRuns.length - 1)
+ expandTabRunsArray();
+ tabRuns[runs] = i;
+ }
+ else
+ {
+ rects[i] = new Rectangle(runWidth,
+ insets.top + tabAreaInsets.top,
+ width, maxHeight);
+ runWidth += width;
+ }
+ }
+ runs++;
+ tabAreaRect.width = tabPane.getWidth() - insets.left - insets.right;
+ tabAreaRect.height = runs * maxTabHeight
+ - (runs - 1) * tabRunOverlay
+ + tabAreaInsets.top + tabAreaInsets.bottom;
+ contentRect.width = tabAreaRect.width;
+ contentRect.height = tabPane.getHeight() - insets.top
+ - insets.bottom - tabAreaRect.height;
+ contentRect.x = insets.left;
+ tabAreaRect.x = insets.left;
+ if (tabPlacement == SwingConstants.BOTTOM)
+ {
+ contentRect.y = insets.top;
+ tabAreaRect.y = contentRect.y + contentRect.height;
+ }
+ else
+ {
+ tabAreaRect.y = insets.top;
+ contentRect.y = tabAreaRect.y + tabAreaRect.height;
+ }
+ }
+ else
+ {
+ int maxWidth = calculateMaxTabWidth(tabPlacement);
+ calcRect.height -= tabAreaInsets.top + tabAreaInsets.bottom;
+ max = calcRect.height + tabAreaInsets.top + insets.top;
+
+ int height = 0;
+ start += tabAreaInsets.top + insets.top;
+ int runHeight = start;
+
+ int fontHeight = fm.getHeight();
+
+ for (int i = 0; i < tabCount; i++)
+ {
+ height = calculateTabHeight(tabPlacement, i, fontHeight);
+ if (runHeight + height > max)
+ {
+ runHeight = tabAreaInsets.top + insets.top
+ + getTabRunIndent(tabPlacement, ++runs);
+ rects[i] = new Rectangle(insets.left + tabAreaInsets.left,
+ runHeight, maxWidth, height);
+ runHeight += height;
+ if (runs > tabRuns.length - 1)
+ expandTabRunsArray();
+ tabRuns[runs] = i;
+ }
+ else
+ {
+ rects[i] = new Rectangle(insets.left + tabAreaInsets.left,
+ runHeight, maxWidth, height);
+ runHeight += height;
+ }
+ }
+ runs++;
+
+ tabAreaRect.width = runs * maxTabWidth - (runs - 1) * tabRunOverlay
+ + tabAreaInsets.left + tabAreaInsets.right;
+ tabAreaRect.height = tabPane.getHeight() - insets.top
+ - insets.bottom;
+ tabAreaRect.y = insets.top;
+ contentRect.width = tabPane.getWidth() - insets.left - insets.right
+ - tabAreaRect.width;
+ contentRect.height = tabAreaRect.height;
+ contentRect.y = insets.top;
+ if (tabPlacement == SwingConstants.LEFT)
+ {
+ tabAreaRect.x = insets.left;
+ contentRect.x = tabAreaRect.x + tabAreaRect.width;
+ }
+ else
+ {
+ contentRect.x = insets.left;
+ tabAreaRect.x = contentRect.x + contentRect.width;
+ }
+ }
+ runCount = runs;
+
+ tabRuns[0] = 0;
+ normalizeTabRuns(tabPlacement, tabCount, start, max);
+ selectedRun = getRunForTab(tabCount, tabPane.getSelectedIndex());
+ if (shouldRotateTabRuns(tabPlacement))
+ rotateTabRuns(tabPlacement, selectedRun);
+
+ // Need to pad the runs and move them to the correct location.
+ for (int i = 0; i < runCount; i++)
+ {
+ int first = lastTabInRun(tabCount, getPreviousTabRun(i)) + 1;
+ if (first == tabCount)
+ first = 0;
+ int last = lastTabInRun(tabCount, i);
+ if (shouldPadTabRun(tabPlacement, i))
+ padTabRun(tabPlacement, first, last, max);
+
+ // Done padding, now need to move it.
+ if (tabPlacement == SwingConstants.TOP && i > 0)
+ {
+ for (int j = first; j <= last; j++)
+ rects[j].y += (runCount - i) * maxTabHeight
+ + (runCount - i) * tabRunOverlay;
+ }
+
+ if (tabPlacement == SwingConstants.BOTTOM)
+ {
+ int height = tabPane.getBounds().height - insets.bottom
+ - tabAreaInsets.bottom;
+ int adjustment;
+ if (i == 0)
+ adjustment = height - maxTabHeight;
+ else
+ adjustment = height - (runCount - i + 1) * maxTabHeight
+ - (runCount - i) * tabRunOverlay;
+
+ for (int j = first; j <= last; j++)
+ rects[j].y = adjustment;
+ }
+
+ if (tabPlacement == SwingConstants.LEFT && i > 0)
+ {
+ for (int j = first; j <= last; j++)
+ rects[j].x += (runCount - i) * maxTabWidth
+ - (runCount - i) * tabRunOverlay;
+ }
+
+ if (tabPlacement == SwingConstants.RIGHT)
+ {
+ int width = tabPane.getBounds().width - insets.right
+ - tabAreaInsets.right;
+ int adjustment;
+ if (i == 0)
+ adjustment = width - maxTabWidth;
+ else
+ adjustment = width - (runCount - i + 1) * maxTabWidth
+ + (runCount - i) * tabRunOverlay;
+
+ for (int j = first; j <= last; j++)
+ rects[j].x = adjustment;
+ }
+ }
+ padSelectedTab(tabPlacement, tabPane.getSelectedIndex());
+ }
+
+ /**
+ * This method is called when the JTabbedPane is laid out in
+ * WRAP_TAB_LAYOUT. It calls calculateLayoutInfo to find the positions
+ * of all its components.
+ *
+ * @param parent The Container to lay out.
+ */
+ public void layoutContainer(Container parent)
+ {
+ calculateLayoutInfo();
+ }
+
+ /**
+ * This method returns the minimum layout size for the given container.
+ *
+ * @param parent The container that is being sized.
+ *
+ * @return The minimum size.
+ */
+ public Dimension minimumLayoutSize(Container parent)
+ {
+ return calculateSize(false);
+ }
+
+ // If there is more free space in an adjacent run AND the tab in the run can fit in the
+ // adjacent run, move it. This method is not perfect, it is merely an approximation.
+ // If you play around with Sun's JTabbedPane, you'll see that
+ // it does do some pretty strange things with regards to not moving tabs
+ // that should be moved.
+ // start = the x position where the tabs will begin
+ // max = the maximum position of where the tabs can go to (tabAreaInsets.left + the width of the tab area)
+
+ /**
+ * This method tries to "even out" the number of tabs in each run based on
+ * their widths.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param tabCount The number of tabs.
+ * @param start The x position where the tabs will begin.
+ * @param max The maximum x position where the tab can run to.
+ */
+ protected void normalizeTabRuns(int tabPlacement, int tabCount, int start,
+ int max)
+ {
+ Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
+ if (tabPlacement == SwingUtilities.TOP
+ || tabPlacement == SwingUtilities.BOTTOM)
+ {
+ // We should only do this for runCount - 1, cause we can only shift that many times between
+ // runs.
+ for (int i = 1; i < runCount; i++)
+ {
+ Rectangle currRun = rects[lastTabInRun(tabCount, i)];
+ Rectangle nextRun = rects[lastTabInRun(tabCount, getNextTabRun(i))];
+ int spaceInCurr = currRun.x + currRun.width;
+ int spaceInNext = nextRun.x + nextRun.width;
+
+ int diffNow = spaceInCurr - spaceInNext;
+ int diffLater = (spaceInCurr - currRun.width)
+ - (spaceInNext + currRun.width);
+ while (Math.abs(diffLater) < Math.abs(diffNow)
+ && spaceInNext + currRun.width < max)
+ {
+ tabRuns[i]--;
+ spaceInNext += currRun.width;
+ spaceInCurr -= currRun.width;
+ currRun = rects[lastTabInRun(tabCount, i)];
+ diffNow = spaceInCurr - spaceInNext;
+ diffLater = (spaceInCurr - currRun.width)
+ - (spaceInNext + currRun.width);
+ }
+
+ // Fix the bounds.
+ int first = lastTabInRun(tabCount, i) + 1;
+ int last = lastTabInRun(tabCount, getNextTabRun(i));
+ int currX = tabAreaInsets.left;
+ for (int j = first; j <= last; j++)
+ {
+ rects[j].x = currX;
+ currX += rects[j].width;
+ }
+ }
+ }
+ else
+ {
+ for (int i = 1; i < runCount; i++)
+ {
+ Rectangle currRun = rects[lastTabInRun(tabCount, i)];
+ Rectangle nextRun = rects[lastTabInRun(tabCount, getNextTabRun(i))];
+ int spaceInCurr = currRun.y + currRun.height;
+ int spaceInNext = nextRun.y + nextRun.height;
+
+ int diffNow = spaceInCurr - spaceInNext;
+ int diffLater = (spaceInCurr - currRun.height)
+ - (spaceInNext + currRun.height);
+ while (Math.abs(diffLater) < Math.abs(diffNow)
+ && spaceInNext + currRun.height < max)
+ {
+ tabRuns[i]--;
+ spaceInNext += currRun.height;
+ spaceInCurr -= currRun.height;
+ currRun = rects[lastTabInRun(tabCount, i)];
+ diffNow = spaceInCurr - spaceInNext;
+ diffLater = (spaceInCurr - currRun.height)
+ - (spaceInNext + currRun.height);
+ }
+
+ int first = lastTabInRun(tabCount, i) + 1;
+ int last = lastTabInRun(tabCount, getNextTabRun(i));
+ int currY = tabAreaInsets.top;
+ for (int j = first; j <= last; j++)
+ {
+ rects[j].y = currY;
+ currY += rects[j].height;
+ }
+ }
+ }
+ }
+
+ /**
+ * This method pads the tab at the selected index by the selected tab pad
+ * insets (so that it looks larger).
+ *
+ * @param tabPlacement The placement of the tabs.
+ * @param selectedIndex The selected index.
+ */
+ protected void padSelectedTab(int tabPlacement, int selectedIndex)
{
- return new BasicTabbedPaneUI();
+ Insets insets = getSelectedTabPadInsets(tabPlacement);
+ rects[selectedIndex].x -= insets.left;
+ rects[selectedIndex].y -= insets.top;
+ rects[selectedIndex].width += insets.left + insets.right;
+ rects[selectedIndex].height += insets.top + insets.bottom;
}
-
- public void installUI(final JComponent c)
+
+ // If the tabs on the run don't fill the width of the window, make it fit now.
+ // start = starting index of the run
+ // end = last index of the run
+ // max = tabAreaInsets.left + width (or equivalent)
+ // assert start <= end.
+
+ /**
+ * This method makes each tab in the run larger so that the tabs expand
+ * to fill the runs width/height (depending on tabPlacement).
+ *
+ * @param tabPlacement The placement of the tabs.
+ * @param start The index of the first tab.
+ * @param end The last index of the tab
+ * @param max The amount of space in the run (width for TOP and BOTTOM
+ * tabPlacement).
+ */
+ protected void padTabRun(int tabPlacement, int start, int end, int max)
{
- super.installUI(c);
+ if (tabPlacement == SwingConstants.TOP
+ || tabPlacement == SwingConstants.BOTTOM)
+ {
+ int runWidth = rects[end].x + rects[end].width;
+ int spaceRemaining = max - runWidth;
+ int numTabs = end - start + 1;
+
+ // now divvy up the space.
+ int spaceAllocated = spaceRemaining / numTabs;
+ int currX = rects[start].x;
+ for (int i = start; i <= end; i++)
+ {
+ rects[i].x = currX;
+ rects[i].width += spaceAllocated;
+ currX += rects[i].width;
+ // This is used because since the spaceAllocated
+ // variable is an int, it rounds down. Sometimes,
+ // we don't fill an entire row, so we make it do
+ // so now.
+ if (i == end && rects[i].x + rects[i].width != max)
+ rects[i].width = max - rects[i].x;
+ }
+ }
+ else
+ {
+ int runHeight = rects[end].y + rects[end].height;
+ int spaceRemaining = max - runHeight;
+ int numTabs = end - start + 1;
+
+ int spaceAllocated = spaceRemaining / numTabs;
+ int currY = rects[start].y;
+ for (int i = start; i <= end; i++)
+ {
+ rects[i].y = currY;
+ rects[i].height += spaceAllocated;
+ currY += rects[i].height;
+ if (i == end && rects[i].y + rects[i].height != max)
+ rects[i].height = max - rects[i].y;
+ }
+ }
+ }
+
+ /**
+ * This method returns the preferred layout size for the given container.
+ *
+ * @param parent The container to size.
+ *
+ * @return The preferred layout size.
+ */
+ public Dimension preferredLayoutSize(Container parent)
+ {
+ return calculateSize(false);
}
-
- public Dimension getPreferredSize(JComponent c)
+
+ /**
+ * This method returns the preferred tab height given a tabPlacement and
+ * width.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param width The expected width.
+ *
+ * @return The preferred tab area height.
+ */
+ protected int preferredTabAreaHeight(int tabPlacement, int width)
{
- JTabbedPane p = (JTabbedPane) c;
+ if (tabPane.getTabCount() == 0)
+ return calculateTabAreaHeight(tabPlacement, 0, 0);
- Dimension d = new Dimension(50,50);
-
- for (int i=0;i<p.getTabCount();i++)
+ int runs = 0;
+ int runWidth = 0;
+ int tabWidth = 0;
+
+ FontMetrics fm = getFontMetrics();
+
+ Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
+ Insets insets = tabPane.getInsets();
+
+ // Only interested in width, this is a messed up rectangle now.
+ width -= tabAreaInsets.left + tabAreaInsets.right + insets.left
+ + insets.right;
+
+ // The reason why we can't use runCount:
+ // This method is only called to calculate the size request
+ // for the tabbedPane. However, this size request is dependent on
+ // our desired width. We need to find out what the height would
+ // be IF we got our desired width.
+ for (int i = 0; i < tabPane.getTabCount(); i++)
+ {
+ tabWidth = calculateTabWidth(tabPlacement, i, fm);
+ if (runWidth + tabWidth > width)
{
- Component comp = p.getComponentAt(i);
-
- Dimension pr = comp.getPreferredSize();
+ runWidth = tabWidth;
+ runs++;
+ }
+ else
+ runWidth += tabWidth;
+ }
+ runs++;
+
+ int maxTabHeight = calculateMaxTabHeight(tabPlacement);
+ int tabAreaHeight = calculateTabAreaHeight(tabPlacement, runs,
+ maxTabHeight);
+ return tabAreaHeight;
+ }
+
+ /**
+ * This method calculates the preferred tab area width given a tab
+ * placement and height.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param height The expected height.
+ *
+ * @return The preferred tab area width.
+ */
+ protected int preferredTabAreaWidth(int tabPlacement, int height)
+ {
+ if (tabPane.getTabCount() == 0)
+ return calculateTabAreaHeight(tabPlacement, 0, 0);
+
+ int runs = 0;
+ int runHeight = 0;
+ int tabHeight = 0;
+
+ FontMetrics fm = getFontMetrics();
+
+ Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
+ Insets insets = tabPane.getInsets();
- d.width = Math.max(d.width, comp.getWidth());
- d.height = Math.max(d.height, comp.getHeight());
+ height -= tabAreaInsets.top + tabAreaInsets.bottom + insets.top
+ + insets.bottom;
+ int fontHeight = fm.getHeight();
+
+ for (int i = 0; i < tabPane.getTabCount(); i++)
+ {
+ tabHeight = calculateTabHeight(tabPlacement, i, fontHeight);
+ if (runHeight + tabHeight > height)
+ {
+ runHeight = tabHeight;
+ runs++;
}
-
- Insets i = p.getInsets();
-
- d.width += i.left + i.right;
- d.height += i.top + i.bottom;
+ else
+ runHeight += tabHeight;
+ }
+ runs++;
+
+ int maxTabWidth = calculateMaxTabWidth(tabPlacement);
+ int tabAreaWidth = calculateTabAreaWidth(tabPlacement, runs, maxTabWidth);
+ return tabAreaWidth;
+ }
+
+ /**
+ * This method rotates the places each run in the correct place the
+ * tabRuns array. See the comment for tabRuns for how the runs are placed
+ * in the array.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param selectedRun The run the current selection is in.
+ */
+ protected void rotateTabRuns(int tabPlacement, int selectedRun)
+ {
+ if (selectedRun == 1 || selectedRun == -1)
+ return;
+ int[] newTabRuns = new int[tabRuns.length];
+ int currentRun = selectedRun;
+ int i = 1;
+ do
+ {
+ newTabRuns[i] = tabRuns[currentRun];
+ currentRun = getNextTabRun(currentRun);
+ i++;
+ }
+ while (i < runCount);
+ if (runCount > 1)
+ newTabRuns[0] = tabRuns[currentRun];
- int height_of_tabs = 25;
+ tabRuns = newTabRuns;
+ BasicTabbedPaneUI.this.selectedRun = 1;
+ }
- d.height += height_of_tabs;
+ /**
+ * This method is called when a component is removed from the
+ * JTabbedPane.
+ *
+ * @param comp The component removed.
+ */
+ public void removeLayoutComponent(Component comp)
+ {
+ // Do nothing.
+ }
+ }
- // FIXME: should be max of panes in p
- return d;
+ /**
+ * This class acts as the LayoutManager for the JTabbedPane in
+ * SCROLL_TAB_MODE.
+ */
+ private class TabbedPaneScrollLayout extends TabbedPaneLayout
+ {
+ /**
+ * This method returns the preferred layout size for the given container.
+ *
+ * @param parent The container to calculate a size for.
+ *
+ * @return The preferred layout size.
+ */
+ public Dimension preferredLayoutSize(Container parent)
+ {
+ return super.calculateSize(true);
}
-
- public Rectangle getTabBounds(JTabbedPane pane, int index)
+ /**
+ * This method returns the minimum layout size for the given container.
+ *
+ * @param parent The container to calculate a size for.
+ *
+ * @return The minimum layout size.
+ */
+ public Dimension minimumLayoutSize(Container parent)
{
- return null;
+ return super.calculateSize(true);
}
- public int getTabRunCount(JTabbedPane pane)
+ /**
+ * This method calculates the tab area height given a desired width.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param width The expected width.
+ *
+ * @return The tab area height given the width.
+ */
+ protected int preferredTabAreaHeight(int tabPlacement, int width)
{
- return 0;
+ if (tabPane.getTabCount() == 0)
+ return calculateTabAreaHeight(tabPlacement, 0, 0);
+
+ int runs = 1;
+
+ int maxTabHeight = calculateMaxTabHeight(tabPlacement);
+ int tabAreaHeight = calculateTabAreaHeight(tabPlacement, runs,
+ maxTabHeight);
+ return tabAreaHeight;
}
- public int tabForCoordinate(JTabbedPane pane, int x, int y)
+ /**
+ * This method calculates the tab area width given a desired height.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param height The expected height.
+ *
+ * @return The tab area width given the height.
+ */
+ protected int preferredTabAreaWidth(int tabPlacement, int height)
{
- return 0;
+ if (tabPane.getTabCount() == 0)
+ return calculateTabAreaHeight(tabPlacement, 0, 0);
+
+ int runs = 1;
+
+ int maxTabWidth = calculateMaxTabWidth(tabPlacement);
+ int tabAreaWidth = calculateTabAreaWidth(tabPlacement, runs, maxTabWidth);
+ return tabAreaWidth;
}
+
+ /**
+ * This method is called to calculate the tab rectangles. This method
+ * will calculate the size and position of all rectangles (taking into
+ * account which ones should be in which tab run). It will pad them and
+ * normalize them as necessary.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param tabCount The number of tabs.
+ */
+ protected void calculateTabRects(int tabPlacement, int tabCount)
+ {
+ if (tabCount == 0)
+ return;
+ assureRectsCreated(tabCount);
+
+ FontMetrics fm = getFontMetrics();
+ SwingUtilities.calculateInnerArea(tabPane, calcRect);
+ Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
+ Insets insets = tabPane.getInsets();
+ int max = 0;
+ int runs = 1;
+ int start = 0;
+ int top = 0;
+ if (tabPlacement == SwingConstants.TOP
+ || tabPlacement == SwingConstants.BOTTOM)
+ {
+ int maxHeight = calculateMaxTabHeight(tabPlacement);
+ calcRect.width -= tabAreaInsets.left + tabAreaInsets.right;
+ max = calcRect.width + tabAreaInsets.left + insets.left;
+ start = tabAreaInsets.left + insets.left;
+ int width = 0;
+ int runWidth = start;
+ top = insets.top + tabAreaInsets.top;
+ for (int i = 0; i < tabCount; i++)
+ {
+ width = calculateTabWidth(tabPlacement, i, fm);
+
+ rects[i] = new Rectangle(runWidth, top, width, maxHeight);
+ runWidth += width;
+ }
+ tabAreaRect.width = tabPane.getWidth() - insets.left - insets.right;
+ tabAreaRect.height = runs * maxTabHeight
+ - (runs - 1) * tabRunOverlay
+ + tabAreaInsets.top + tabAreaInsets.bottom;
+ contentRect.width = tabAreaRect.width;
+ contentRect.height = tabPane.getHeight() - insets.top
+ - insets.bottom - tabAreaRect.height;
+ contentRect.x = insets.left;
+ tabAreaRect.x = insets.left;
+ if (tabPlacement == SwingConstants.BOTTOM)
+ {
+ contentRect.y = insets.top;
+ tabAreaRect.y = contentRect.y + contentRect.height;
+ }
+ else
+ {
+ tabAreaRect.y = insets.top;
+ contentRect.y = tabAreaRect.y + tabAreaRect.height;
+ }
+ }
+ else
+ {
+ int maxWidth = calculateMaxTabWidth(tabPlacement);
+
+ calcRect.height -= tabAreaInsets.top + tabAreaInsets.bottom;
+ max = calcRect.height + tabAreaInsets.top;
+ int height = 0;
+ start = tabAreaInsets.top + insets.top;
+ int runHeight = start;
+ int fontHeight = fm.getHeight();
+ top = insets.left + tabAreaInsets.left;
+ for (int i = 0; i < tabCount; i++)
+ {
+ height = calculateTabHeight(tabPlacement, i, fontHeight);
+ rects[i] = new Rectangle(top, runHeight, maxWidth, height);
+ runHeight += height;
+ }
+ tabAreaRect.width = runs * maxTabWidth - (runs - 1) * tabRunOverlay
+ + tabAreaInsets.left + tabAreaInsets.right;
+ tabAreaRect.height = tabPane.getHeight() - insets.top
+ - insets.bottom;
+ tabAreaRect.y = insets.top;
+ contentRect.width = tabPane.getWidth() - insets.left - insets.right
+ - tabAreaRect.width;
+ contentRect.height = tabAreaRect.height;
+ contentRect.y = insets.top;
+ if (tabPlacement == SwingConstants.LEFT)
+ {
+ tabAreaRect.x = insets.left;
+ contentRect.x = tabAreaRect.x + tabAreaRect.width;
+ }
+ else
+ {
+ contentRect.x = insets.left;
+ tabAreaRect.x = contentRect.x + contentRect.width;
+ }
+ }
+ runCount = runs;
+
+ padSelectedTab(tabPlacement, tabPane.getSelectedIndex());
+ }
+
+ /**
+ * This method is called when the JTabbedPane is laid out in
+ * SCROLL_TAB_LAYOUT. It finds the position for all components in the
+ * JTabbedPane.
+ *
+ * @param pane The JTabbedPane to be laid out.
+ */
+ public void layoutContainer(Container pane)
+ {
+ super.layoutContainer(pane);
+ int tabCount = tabPane.getTabCount();
+ if (tabCount == 0)
+ return;
+ int tabPlacement = tabPane.getTabPlacement();
+ incrButton.hide();
+ decrButton.hide();
+ if (tabPlacement == SwingConstants.TOP
+ || tabPlacement == SwingConstants.BOTTOM)
+ {
+ if (tabAreaRect.x + tabAreaRect.width < rects[tabCount - 1].x
+ + rects[tabCount - 1].width)
+ {
+ Dimension incrDims = incrButton.getPreferredSize();
+ Dimension decrDims = decrButton.getPreferredSize();
+
+ decrButton.setBounds(tabAreaRect.x + tabAreaRect.width
+ - incrDims.width - decrDims.width,
+ tabAreaRect.y, decrDims.width,
+ tabAreaRect.height);
+ incrButton.setBounds(tabAreaRect.x + tabAreaRect.width
+ - incrDims.width, tabAreaRect.y,
+ decrDims.width, tabAreaRect.height);
+
+ tabAreaRect.width -= decrDims.width + incrDims.width;
+ incrButton.show();
+ decrButton.show();
+ }
+ }
+
+ if (tabPlacement == SwingConstants.LEFT
+ || tabPlacement == SwingConstants.RIGHT)
+ {
+ if (tabAreaRect.y + tabAreaRect.height < rects[tabCount - 1].y
+ + rects[tabCount - 1].height)
+ {
+ Dimension incrDims = incrButton.getPreferredSize();
+ Dimension decrDims = decrButton.getPreferredSize();
+
+ decrButton.setBounds(tabAreaRect.x,
+ tabAreaRect.y + tabAreaRect.height
+ - incrDims.height - decrDims.height,
+ tabAreaRect.width, decrDims.height);
+ incrButton.setBounds(tabAreaRect.x,
+ tabAreaRect.y + tabAreaRect.height
+ - incrDims.height, tabAreaRect.width,
+ incrDims.height);
+
+ tabAreaRect.height -= decrDims.height + incrDims.height;
+ incrButton.show();
+ decrButton.show();
+ }
+ }
+ viewport.setBounds(tabAreaRect.x, tabAreaRect.y, tabAreaRect.width,
+ tabAreaRect.height);
+ int tabC = tabPane.getTabCount() - 1;
+ if (tabCount > 0)
+ {
+ int w = Math.max(rects[tabC].width + rects[tabC].x, tabAreaRect.width);
+ int h = Math.max(rects[tabC].height, tabAreaRect.height);
+ Point p = findPointForIndex(currentScrollLocation);
+
+ // we want to cover that entire space so that borders that run under
+ // the tab area don't show up when we move the viewport around.
+ panel.setBounds(0, 0, w + p.x, h + p.y);
+ }
+ viewport.setViewPosition(findPointForIndex(currentScrollLocation));
+ }
+ }
+
+ /**
+ * This class handles ChangeEvents from the JTabbedPane.
+ */
+ protected class TabSelectionHandler implements ChangeListener
+ {
+ /**
+ * This method is called whenever a ChangeEvent is fired from the
+ * JTabbedPane.
+ *
+ * @param e The ChangeEvent fired.
+ */
+ public void stateChanged(ChangeEvent e)
+ {
+ selectedRun = getRunForTab(tabPane.getTabCount(),
+ tabPane.getSelectedIndex());
+ tabPane.layout();
+ tabPane.repaint();
+ }
+ }
+
+ /**
+ * This helper class is a JPanel that fits inside the ScrollViewport. This
+ * panel's sole job is to paint the tab rectangles inside the viewport so
+ * that it's clipped correctly.
+ */
+ private class ScrollingPanel extends JPanel
+ {
+ /**
+ * This is a private UI class for our panel.
+ */
+ private class ScrollingPanelUI extends BasicPanelUI
+ {
+ /**
+ * This method overrides the default paint method. It paints the tab
+ * rectangles for the JTabbedPane in the panel.
+ *
+ * @param g The Graphics object to paint with.
+ * @param c The JComponent to paint.
+ */
+ public void paint(Graphics g, JComponent c)
+ {
+ paintTabArea(g, tabPane.getTabPlacement(), tabPane.getSelectedIndex());
+ }
+ }
+
+ /**
+ * This method overrides the updateUI method. It makes the default UI for
+ * this ScrollingPanel to be a ScrollingPanelUI.
+ */
+ public void updateUI()
+ {
+ setUI((PanelUI) new ScrollingPanelUI());
+ }
+ }
+
+ /**
+ * This is a helper class that paints the panel that paints tabs. This
+ * custom JViewport is used so that the tabs painted in the panel will be
+ * clipped. This class implements UIResource so tabs are not added when
+ * this objects of this class are added to the JTabbedPane.
+ */
+ private class ScrollingViewport extends JViewport implements UIResource
+ {
+ /**
+ * This method is temporary until the viewport layouts are implemented.
+ * Need it because the flow layout it currently moves our panel around.
+ *
+ * @param g The graphics object to paint with.
+ */
+ public void paint(Graphics g)
+ {
+ // FIXME: Remove this as well.
+ int tabC = tabPane.getTabCount() - 1;
+ if (tabC + 1 > 0)
+ {
+ int w = Math.max(rects[tabC].width + rects[tabC].x, tabAreaRect.width);
+ int h = Math.max(rects[tabC].height, tabAreaRect.height);
+ Point p = findPointForIndex(currentScrollLocation);
+
+ // we want to cover that entire space so that borders that run under
+ // the tab area don't show up when we move the viewport around.
+ panel.setBounds(0, 0, w + p.x, h + p.y);
+ }
+
+ // FIXME: Remove when ViewportLayout is done.
+ setViewPosition(findPointForIndex(currentScrollLocation));
+ super.paint(g);
+ }
+ }
+
+ /**
+ * This is a helper class that implements UIResource so it is not added as a
+ * tab when an object of this class is added to the JTabbedPane.
+ */
+ private static class ScrollingButton extends BasicArrowButton
+ implements UIResource
+ {
+ /**
+ * Creates a ScrollingButton given the direction.
+ *
+ * @param dir The direction to point in.
+ */
+ public ScrollingButton(int dir)
+ {
+ super(dir);
+ }
+ }
+
+ /** The button that increments the current scroll location. */
+ private transient ScrollingButton incrButton;
+
+ /** The button that decrements the current scroll location. */
+ private transient ScrollingButton decrButton;
+
+ /** The viewport used to display the tabs. */
+ private transient ScrollingViewport viewport;
+
+ /** The panel inside the viewport that paints the tabs. */
+ private transient ScrollingPanel panel;
+
+ /** The starting visible tab in the run in SCROLL_TAB_MODE. */
+ private transient int currentScrollLocation;
+
+ /** A reusable rectangle. */
+ protected Rectangle calcRect;
+
+ /** An array of Rectangles keeping track of the tabs' area and position. */
+ protected Rectangle[] rects;
+
+ /** The insets around the content area. */
+ protected Insets contentBorderInsets;
+
+ /** The extra insets around the selected tab. */
+ protected Insets selectedTabPadInsets;
+
+ /** The insets around the tab area. */
+ protected Insets tabAreaInsets;
+
+ /** The insets around each and every tab. */
+ protected Insets tabInsets;
+
+ /**
+ * The outer bottom and right edge color for both the tab and content
+ * border.
+ */
+ protected Color darkShadow;
+
+ /** The color of the focus outline on the selected tab. */
+ protected Color focus;
+
+ /** FIXME: find a use for this. */
+ protected Color highlight;
+
+ /** The top and left edge color for both the tab and content border. */
+ protected Color lightHighlight;
+
+ /** The inner bottom and right edge color for the tab and content border. */
+ protected Color shadow;
+
+ /** The maximum tab height. */
+ protected int maxTabHeight;
+
+ /** The maximum tab width. */
+ protected int maxTabWidth;
+
+ /** The number of runs in the JTabbedPane. */
+ protected int runCount;
+
+ /** The index of the run that the selected index is in. */
+ protected int selectedRun;
+
+ /** The amount of space each run overlaps the previous by. */
+ protected int tabRunOverlay;
+
+ /** The gap between text and label */
+ protected int textIconGap;
+
+ // Keeps track of tab runs.
+ // The organization of this array is as follows (lots of experimentation to
+ // figure this out)
+ // index 0 = furthest away from the component area (aka outer run)
+ // index 1 = closest to component area (aka selected run)
+ // index > 1 = listed in order leading from selected run to outer run.
+ // each int in the array is the tab index + 1 (counting starts at 1)
+ // for the last tab in the run. (same as the rects array)
+
+ /** This array keeps track of which tabs are in which run. See above. */
+ protected int[] tabRuns;
+
+ /** Deprecated. This is the keystroke for moving down. */
+ protected KeyStroke downKey;
+
+ /** Deprecated. This is the keystroke for moving left. */
+ protected KeyStroke leftKey;
+
+ /** Deprecated. This is the keystroke for moving right. */
+ protected KeyStroke rightKey;
+
+ /** Deprecated. This is the keystroke for moving up. */
+ protected KeyStroke upKey;
+
+ /** The listener that listens for focus events. */
+ protected FocusListener focusListener;
+
+ /** The listener that listens for mouse events. */
+ protected MouseListener mouseListener;
+
+ /** The listener that listens for property change events. */
+ protected PropertyChangeListener propertyChangeListener;
+
+ /** The listener that listens for change events. */
+ protected ChangeListener tabChangeListener;
+
+ /** The tab pane that this UI paints. */
+ protected JTabbedPane tabPane;
+
+ /** The current layout manager for the tabPane. */
+ private transient LayoutManager layoutManager;
+
+ /** The rectangle that describes the tab area's position and size. */
+ private transient Rectangle tabAreaRect;
+
+ /** The rectangle that describes the content area's position and size. */
+ private transient Rectangle contentRect;
+
+ /**
+ * Creates a new BasicTabbedPaneUI object.
+ */
+ public BasicTabbedPaneUI()
+ {
+ super();
+ }
+
+ /**
+ * This method creates a ScrollingButton that points in the appropriate
+ * direction for an increasing button.
+ *
+ * @return The increase ScrollingButton.
+ */
+ private ScrollingButton createIncreaseButton()
+ {
+ if (incrButton == null)
+ incrButton = new ScrollingButton(SwingConstants.NORTH);
+ if (tabPane.getTabPlacement() == SwingConstants.TOP
+ || tabPane.getTabPlacement() == SwingConstants.BOTTOM)
+ incrButton.setDirection(SwingConstants.EAST);
+ else
+ incrButton.setDirection(SwingConstants.SOUTH);
+ return incrButton;
+ }
+
+ /**
+ * This method creates a ScrollingButton that points in the appropriate
+ * direction for a decreasing button.
+ *
+ * @return The decrease ScrollingButton.
+ */
+ private ScrollingButton createDecreaseButton()
+ {
+ if (decrButton == null)
+ decrButton = new ScrollingButton(SwingConstants.SOUTH);
+ if (tabPane.getTabPlacement() == SwingConstants.TOP
+ || tabPane.getTabPlacement() == SwingConstants.BOTTOM)
+ decrButton.setDirection(SwingConstants.WEST);
+ else
+ decrButton.setDirection(SwingConstants.NORTH);
+ return decrButton;
+ }
+
+ /**
+ * This method finds the point to set the view position at given the index
+ * of a tab. The tab will be the first visible tab in the run.
+ *
+ * @param index The index of the first visible tab.
+ *
+ * @return The position of the first visible tab.
+ */
+ private Point findPointForIndex(int index)
+ {
+ int tabPlacement = tabPane.getTabPlacement();
+ int selectedIndex = tabPane.getSelectedIndex();
+ Insets insets = getSelectedTabPadInsets(tabPlacement);
+ int w = 0;
+ int h = 0;
+
+ if (tabPlacement == TOP || tabPlacement == BOTTOM)
+ {
+ if (index > 0)
+ {
+ w += rects[index - 1].x + rects[index - 1].width;
+ if (index > selectedIndex)
+ w -= insets.left + insets.right;
+ }
+ }
+
+ else
+ {
+ if (index > 0)
+ {
+ h += rects[index - 1].y + rects[index - 1].height;
+ if (index > selectedIndex)
+ h -= insets.top + insets.bottom;
+ }
+ }
+
+ Point p = new Point(w, h);
+ return p;
+ }
+
+ /**
+ * This method creates a new BasicTabbedPaneUI.
+ *
+ * @param c The JComponent to create a UI for.
+ *
+ * @return A new BasicTabbedPaneUI.
+ */
+ public static ComponentUI createUI(JComponent c)
+ {
+ return new BasicTabbedPaneUI();
+ }
+
+ /**
+ * This method installs the UI for the given JComponent.
+ *
+ * @param c The JComponent to install the UI for.
+ */
+ public void installUI(JComponent c)
+ {
+ super.installUI(c);
+ if (c instanceof JTabbedPane)
+ {
+ tabPane = (JTabbedPane) c;
+
+ installComponents();
+ installDefaults();
+ installListeners();
+ installKeyboardActions();
+
+ layoutManager = createLayoutManager();
+ tabPane.setLayout(layoutManager);
+ tabPane.layout();
+ }
+ }
+
+ /**
+ * This method uninstalls the UI for the given JComponent.
+ *
+ * @param c The JComponent to uninstall the UI for.
+ */
+ public void uninstallUI(JComponent c)
+ {
+ layoutManager = null;
+
+ uninstallKeyboardActions();
+ uninstallListeners();
+ uninstallDefaults();
+ uninstallComponents();
+
+ tabPane = null;
+ }
+
+ /**
+ * This method creates the appropriate layout manager for the JTabbedPane's
+ * current tab layout policy. If the tab layout policy is
+ * SCROLL_TAB_LAYOUT, then all the associated components that need to be
+ * created will be done so now.
+ *
+ * @return A layout manager given the tab layout policy.
+ */
+ public LayoutManager createLayoutManager()
+ {
+ if (tabPane.getTabLayoutPolicy() == JTabbedPane.WRAP_TAB_LAYOUT)
+ return new TabbedPaneLayout();
+ else
+ {
+ incrButton = createIncreaseButton();
+ decrButton = createDecreaseButton();
+ viewport = new ScrollingViewport();
+ panel = new ScrollingPanel();
+ viewport.setView(panel);
+ tabPane.add(incrButton);
+ tabPane.add(decrButton);
+ tabPane.add(viewport);
+ currentScrollLocation = 0;
+ decrButton.setEnabled(false);
+ panel.addMouseListener(mouseListener);
+ incrButton.addMouseListener(mouseListener);
+ decrButton.addMouseListener(mouseListener);
+ viewport.setBackground(Color.LIGHT_GRAY);
+
+ return new TabbedPaneScrollLayout();
+ }
+ }
+
+ /**
+ * This method installs components for this JTabbedPane.
+ */
+ protected void installComponents()
+ {
+ // Nothing to be done.
+ }
+
+ /**
+ * This method uninstalls components for this JTabbedPane.
+ */
+ protected void uninstallComponents()
+ {
+ // Nothing to be done.
+ }
+
+ /**
+ * This method installs defaults for the Look and Feel.
+ */
+ protected void installDefaults()
+ {
+ UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+ tabPane.setFont(defaults.getFont("TabbedPane.font"));
+ tabPane.setForeground(defaults.getColor("TabbedPane.foreground"));
+ tabPane.setBackground(defaults.getColor("TabbedPane.background"));
+
+ highlight = defaults.getColor("TabbedPane.highlight");
+ lightHighlight = defaults.getColor("TabbedPane.lightHighlight");
+
+ shadow = defaults.getColor("TabbedPane.shadow");
+ darkShadow = defaults.getColor("TabbedPane.darkShadow");
+
+ focus = defaults.getColor("TabbedPane.focus");
+
+ textIconGap = defaults.getInt("TabbedPane.textIconGap");
+ tabRunOverlay = defaults.getInt("TabbedPane.tabRunOverlay");
+
+ tabInsets = defaults.getInsets("TabbedPane.tabbedPaneTabInsets");
+ selectedTabPadInsets = defaults.getInsets("TabbedPane.tabbedPaneTabPadInsets");
+ tabAreaInsets = defaults.getInsets("TabbedPane.tabbedPaneTabAreaInsets");
+ contentBorderInsets = defaults.getInsets("TabbedPane.tabbedPaneContentBorderInsets");
+
+ calcRect = new Rectangle();
+ tabRuns = new int[10];
+ tabAreaRect = new Rectangle();
+ contentRect = new Rectangle();
+ }
+
+ /**
+ * This method uninstalls defaults for the Look and Feel.
+ */
+ protected void uninstallDefaults()
+ {
+ calcRect = null;
+ tabAreaRect = null;
+ contentRect = null;
+ tabRuns = null;
+
+ contentBorderInsets = null;
+ tabAreaInsets = null;
+ selectedTabPadInsets = null;
+ tabInsets = null;
+
+ focus = null;
+ darkShadow = null;
+ shadow = null;
+ lightHighlight = null;
+ highlight = null;
+
+ tabPane.setBackground(null);
+ tabPane.setForeground(null);
+ tabPane.setFont(null);
+ }
+
+ /**
+ * This method creates and installs the listeners for this UI.
+ */
+ protected void installListeners()
+ {
+ mouseListener = createMouseListener();
+ tabChangeListener = createChangeListener();
+ propertyChangeListener = createPropertyChangeListener();
+ focusListener = createFocusListener();
+
+ tabPane.addMouseListener(mouseListener);
+ tabPane.addChangeListener(tabChangeListener);
+ tabPane.addPropertyChangeListener(propertyChangeListener);
+ tabPane.addFocusListener(focusListener);
+ }
+
+ /**
+ * This method removes and nulls the listeners for this UI.
+ */
+ protected void uninstallListeners()
+ {
+ tabPane.removeFocusListener(focusListener);
+ tabPane.removePropertyChangeListener(propertyChangeListener);
+ tabPane.removeChangeListener(tabChangeListener);
+ tabPane.removeMouseListener(mouseListener);
+
+ focusListener = null;
+ propertyChangeListener = null;
+ tabChangeListener = null;
+ mouseListener = null;
+ }
+
+ /**
+ * This method creates a new MouseListener.
+ *
+ * @return A new MouseListener.
+ */
+ protected MouseListener createMouseListener()
+ {
+ return new MouseHandler();
+ }
+
+ /**
+ * This method creates a new FocusListener.
+ *
+ * @return A new FocusListener.
+ */
+ protected FocusListener createFocusListener()
+ {
+ return new FocusHandler();
+ }
+
+ /**
+ * This method creates a new ChangeListener.
+ *
+ * @return A new ChangeListener.
+ */
+ protected ChangeListener createChangeListener()
+ {
+ return new TabSelectionHandler();
+ }
+
+ /**
+ * This method creates a new PropertyChangeListener.
+ *
+ * @return A new PropertyChangeListener.
+ */
+ protected PropertyChangeListener createPropertyChangeListener()
+ {
+ return new PropertyChangeHandler();
+ }
+
+ /**
+ * This method installs keyboard actions for the JTabbedPane.
+ */
+ protected void installKeyboardActions()
+ {
+ // FIXME: Implement.
+ }
+
+ /**
+ * This method uninstalls keyboard actions for the JTabbedPane.
+ */
+ protected void uninstallKeyboardActions()
+ {
+ // FIXME: Implement.
+ }
+
+ /**
+ * This method returns the preferred size of the JTabbedPane.
+ *
+ * @param c The JComponent to find a size for.
+ *
+ * @return The preferred size.
+ */
+ public Dimension getPreferredSize(JComponent c)
+ {
+ return layoutManager.preferredLayoutSize(tabPane);
+ }
+
+ /**
+ * This method returns the minimum size of the JTabbedPane.
+ *
+ * @param c The JComponent to find a size for.
+ *
+ * @return The minimum size.
+ */
+ public Dimension getMinimumSize(JComponent c)
+ {
+ return layoutManager.minimumLayoutSize(tabPane);
+ }
+
+ /**
+ * This method returns the maximum size of the JTabbedPane.
+ *
+ * @param c The JComponent to find a size for.
+ *
+ * @return The maximum size.
+ */
+ public Dimension getMaximumSize(JComponent c)
+ {
+ return getPreferredSize(c);
+ }
+
+ /**
+ * This method paints the JTabbedPane.
+ *
+ * @param g The Graphics object to paint with.
+ * @param c The JComponent to paint.
+ */
+ public void paint(Graphics g, JComponent c)
+ {
+ if (tabPane.getTabCount() == 0)
+ return;
+ if (tabPane.getTabLayoutPolicy() == JTabbedPane.WRAP_TAB_LAYOUT)
+ paintTabArea(g, tabPane.getTabPlacement(), tabPane.getSelectedIndex());
+ paintContentBorder(g, tabPane.getTabPlacement(), tabPane.getSelectedIndex());
+ }
+
+ /**
+ * This method paints the tab area. This includes painting the rectangles
+ * that make up the tabs.
+ *
+ * @param g The Graphics object to paint with.
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param selectedIndex The selected index.
+ */
+ protected void paintTabArea(Graphics g, int tabPlacement, int selectedIndex)
+ {
+ Rectangle ir = new Rectangle();
+ Rectangle tr = new Rectangle();
+
+ // Please note: the ordering of the painting is important.
+ // we WANT to paint the outermost run first and then work our way in.
+ int tabCount = tabPane.getTabCount();
+ int currRun = 1;
+ if (tabCount < 1)
+ return;
+
+ if (runCount > 1)
+ currRun = 0;
+ for (int i = 0; i < runCount; i++)
+ {
+ int first = lastTabInRun(tabCount, getPreviousTabRun(currRun)) + 1;
+ if (first == tabCount)
+ first = 0;
+ int last = lastTabInRun(tabCount, currRun);
+ for (int j = first; j <= last; j++)
+ {
+ if (j != selectedIndex)
+ paintTab(g, tabPlacement, rects, j, ir, tr);
+ }
+ currRun = getNextTabRun(currRun);
+ }
+ paintTab(g, tabPlacement, rects, selectedIndex, ir, tr);
+ }
+
+ /**
+ * This method paints an individual tab.
+ *
+ * @param g The Graphics object to paint with.
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param rects The array of rectangles that keep the size and position of
+ * the tabs.
+ * @param tabIndex The tab index to paint.
+ * @param iconRect The rectangle to use for the icon.
+ * @param textRect The rectangle to use for the text.
+ */
+ protected void paintTab(Graphics g, int tabPlacement, Rectangle[] rects,
+ int tabIndex, Rectangle iconRect, Rectangle textRect)
+ {
+ FontMetrics fm = getFontMetrics();
+ Icon icon = getIconForTab(tabIndex);
+ String title = tabPane.getTitleAt(tabIndex);
+ boolean isSelected = tabIndex == tabPane.getSelectedIndex();
+ calcRect = getTabBounds(tabPane, tabIndex);
+
+ int x = calcRect.x;
+ int y = calcRect.y;
+ int w = calcRect.width;
+ int h = calcRect.height;
+ if (getRunForTab(tabPane.getTabCount(), tabIndex) == 1)
+ {
+ Insets insets = getTabAreaInsets(tabPlacement);
+ switch (tabPlacement)
+ {
+ case TOP:
+ h += insets.bottom;
+ break;
+ case LEFT:
+ w += insets.right;
+ break;
+ case BOTTOM:
+ y -= insets.top;
+ h += insets.top;
+ break;
+ case RIGHT:
+ x -= insets.left;
+ w += insets.left;
+ break;
+ }
+ }
+
+ layoutLabel(tabPlacement, fm, tabIndex, title, icon, calcRect, iconRect,
+ textRect, isSelected);
+ paintTabBackground(g, tabPlacement, tabIndex, x, y, w, h, isSelected);
+ paintTabBorder(g, tabPlacement, tabIndex, x, y, w, h, isSelected);
+
+ // FIXME: Paint little folding corner and jagged edge clipped tab.
+ if (icon != null)
+ paintIcon(g, tabPlacement, tabIndex, icon, iconRect, isSelected);
+ if (title == null || ! title.equals(""))
+ paintText(g, tabPlacement, tabPane.getFont(), fm, tabIndex, title,
+ textRect, isSelected);
+ }
+
+ /**
+ * This method lays out the tab and finds the location to paint the icon
+ * and text.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param metrics The font metrics for the font to paint with.
+ * @param tabIndex The tab index to paint.
+ * @param title The string painted.
+ * @param icon The icon painted.
+ * @param tabRect The tab bounds.
+ * @param iconRect The calculated icon bounds.
+ * @param textRect The calculated text bounds.
+ * @param isSelected Whether this tab is selected.
+ */
+ protected void layoutLabel(int tabPlacement, FontMetrics metrics,
+ int tabIndex, String title, Icon icon,
+ Rectangle tabRect, Rectangle iconRect,
+ Rectangle textRect, boolean isSelected)
+ {
+ SwingUtilities.layoutCompoundLabel(metrics, title, icon,
+ SwingConstants.CENTER,
+ SwingConstants.CENTER,
+ SwingConstants.CENTER,
+ SwingConstants.CENTER, tabRect,
+ iconRect, textRect, textIconGap);
+
+ int shiftX = getTabLabelShiftX(tabPlacement, tabIndex, isSelected);
+ int shiftY = getTabLabelShiftY(tabPlacement, tabIndex, isSelected);
+
+ iconRect.x += shiftX;
+ iconRect.y += shiftY;
+
+ textRect.x += shiftX;
+ textRect.y += shiftY;
+ }
+
+ /**
+ * This method paints the icon.
+ *
+ * @param g The Graphics object to paint.
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param tabIndex The tab index to paint.
+ * @param icon The icon to paint.
+ * @param iconRect The bounds of the icon.
+ * @param isSelected Whether this tab is selected.
+ */
+ protected void paintIcon(Graphics g, int tabPlacement, int tabIndex,
+ Icon icon, Rectangle iconRect, boolean isSelected)
+ {
+ icon.paintIcon(tabPane, g, iconRect.x, iconRect.y);
+ }
+
+ /**
+ * This method paints the text for the given tab.
+ *
+ * @param g The Graphics object to paint with.
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param font The font to paint with.
+ * @param metrics The fontmetrics of the given font.
+ * @param tabIndex The tab index.
+ * @param title The string to paint.
+ * @param textRect The bounds of the string.
+ * @param isSelected Whether this tab is selected.
+ */
+ protected void paintText(Graphics g, int tabPlacement, Font font,
+ FontMetrics metrics, int tabIndex, String title,
+ Rectangle textRect, boolean isSelected)
+ {
+ View textView = getTextViewForTab(tabIndex);
+ if (textView != null)
+ {
+ textView.paint(g, textRect);
+ return;
+ }
+
+ Color fg = tabPane.getForegroundAt(tabIndex);
+ if (fg == null)
+ fg = tabPane.getForeground();
+ Color bg = tabPane.getBackgroundAt(tabIndex);
+ if (bg == null)
+ bg = tabPane.getBackground();
+
+ Color saved_color = g.getColor();
+ Font f = g.getFont();
+ g.setFont(font);
+
+ if (tabPane.isEnabledAt(tabIndex))
+ {
+ g.setColor(fg);
+
+ int mnemIndex = tabPane.getDisplayedMnemonicIndexAt(tabIndex);
+
+ if (mnemIndex != -1)
+ BasicGraphicsUtils.drawStringUnderlineCharAt(g, title, mnemIndex,
+ textRect.x,
+ textRect.y
+ + metrics.getAscent());
+ else
+ g.drawString(title, textRect.x, textRect.y + metrics.getAscent());
+ }
+ else
+ {
+ g.setColor(bg.brighter());
+
+ int mnemIndex = tabPane.getDisplayedMnemonicIndexAt(tabIndex);
+
+ if (mnemIndex != -1)
+ BasicGraphicsUtils.drawStringUnderlineCharAt(g, title, mnemIndex,
+ textRect.x, textRect.y);
+ else
+ g.drawString(title, textRect.x, textRect.y);
+
+ g.setColor(bg.darker());
+ if (mnemIndex != -1)
+ BasicGraphicsUtils.drawStringUnderlineCharAt(g, title, mnemIndex,
+ textRect.x + 1,
+ textRect.y + 1);
+ else
+ g.drawString(title, textRect.x + 1, textRect.y + 1);
+ }
+
+ g.setColor(saved_color);
+ g.setFont(f);
+ }
+
+ /**
+ * This method returns how much the label for the tab should shift in the X
+ * direction.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param tabIndex The tab index being painted.
+ * @param isSelected Whether this tab is selected.
+ *
+ * @return The amount the label should shift by in the X direction.
+ */
+ protected int getTabLabelShiftX(int tabPlacement, int tabIndex,
+ boolean isSelected)
+ {
+ // No reason to shift.
+ return 0;
+ }
+
+ /**
+ * This method returns how much the label for the tab should shift in the Y
+ * direction.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param tabIndex The tab index being painted.
+ * @param isSelected Whether this tab is selected.
+ *
+ * @return The amount the label should shift by in the Y direction.
+ */
+ protected int getTabLabelShiftY(int tabPlacement, int tabIndex,
+ boolean isSelected)
+ {
+ // No reason to shift.
+ return 0;
+ }
+
+ /**
+ * This method paints the focus rectangle around the selected tab.
+ *
+ * @param g The Graphics object to paint with.
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param rects The array of rectangles keeping track of size and position.
+ * @param tabIndex The tab index.
+ * @param iconRect The icon bounds.
+ * @param textRect The text bounds.
+ * @param isSelected Whether this tab is selected.
+ */
+ protected void paintFocusIndicator(Graphics g, int tabPlacement,
+ Rectangle[] rects, int tabIndex,
+ Rectangle iconRect, Rectangle textRect,
+ boolean isSelected)
+ {
+ Color saved = g.getColor();
+ calcRect = iconRect.union(textRect);
+
+ g.setColor(focus);
+
+ g.drawRect(calcRect.x, calcRect.y, calcRect.width, calcRect.height);
+
+ g.setColor(saved);
+ }
+
+ /**
+ * This method paints the border for an individual tab.
+ *
+ * @param g The Graphics object to paint with.
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param tabIndex The tab index.
+ * @param x The x position of the tab.
+ * @param y The y position of the tab.
+ * @param w The width of the tab.
+ * @param h The height of the tab.
+ * @param isSelected Whether the tab is selected.
+ */
+ protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex,
+ int x, int y, int w, int h, boolean isSelected)
+ {
+ Color saved = g.getColor();
+
+ if (! isSelected || tabPlacement != SwingConstants.TOP)
+ {
+ g.setColor(shadow);
+ g.drawLine(x + 1, y + h - 1, x + w - 1, y + h - 1);
+ g.setColor(darkShadow);
+ g.drawLine(x, y + h, x + w, y + h);
+ }
+
+ if (! isSelected || tabPlacement != SwingConstants.LEFT)
+ {
+ g.setColor(darkShadow);
+ g.drawLine(x + w, y, x + w, y + h);
+ g.setColor(shadow);
+ g.drawLine(x + w - 1, y + 1, x + w - 1, y + h - 1);
+ }
+
+ if (! isSelected || tabPlacement != SwingConstants.RIGHT)
+ {
+ g.setColor(lightHighlight);
+ g.drawLine(x, y, x, y + h);
+ }
+
+ if (! isSelected || tabPlacement != SwingConstants.BOTTOM)
+ {
+ g.setColor(lightHighlight);
+ g.drawLine(x, y, x + w, y);
+ }
+
+ g.setColor(saved);
+ }
+
+ /**
+ * This method paints the background for an individual tab.
+ *
+ * @param g The Graphics object to paint with.
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param tabIndex The tab index.
+ * @param x The x position of the tab.
+ * @param y The y position of the tab.
+ * @param w The width of the tab.
+ * @param h The height of the tab.
+ * @param isSelected Whether the tab is selected.
+ */
+ protected void paintTabBackground(Graphics g, int tabPlacement,
+ int tabIndex, int x, int y, int w, int h,
+ boolean isSelected)
+ {
+ Color saved = g.getColor();
+ if (isSelected)
+ g.setColor(Color.LIGHT_GRAY);
+ else
+ {
+ Color bg = tabPane.getBackgroundAt(tabIndex);
+ if (bg == null)
+ bg = tabPane.getBackground();
+ g.setColor(bg);
+ }
+
+ g.fillRect(x, y, w, h);
+
+ g.setColor(saved);
+ }
+
+ /**
+ * This method paints the border around the content area.
+ *
+ * @param g The Graphics object to paint with.
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param selectedIndex The index of the selected tab.
+ */
+ protected void paintContentBorder(Graphics g, int tabPlacement,
+ int selectedIndex)
+ {
+ Insets insets = getContentBorderInsets(tabPlacement);
+ int x = contentRect.x;
+ int y = contentRect.y;
+ int w = contentRect.width;
+ int h = contentRect.height;
+ paintContentBorderTopEdge(g, tabPlacement, selectedIndex, x, y, w, h);
+ paintContentBorderLeftEdge(g, tabPlacement, selectedIndex, x, y, w, h);
+ paintContentBorderBottomEdge(g, tabPlacement, selectedIndex, x, y, w, h);
+ paintContentBorderRightEdge(g, tabPlacement, selectedIndex, x, y, w, h);
+ }
+
+ /**
+ * This method paints the top edge of the content border.
+ *
+ * @param g The Graphics object to paint with.
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param selectedIndex The selected tab index.
+ * @param x The x coordinate for the content area.
+ * @param y The y coordinate for the content area.
+ * @param w The width of the content area.
+ * @param h The height of the content area.
+ */
+ protected void paintContentBorderTopEdge(Graphics g, int tabPlacement,
+ int selectedIndex, int x, int y,
+ int w, int h)
+ {
+ Color saved = g.getColor();
+ g.setColor(lightHighlight);
+
+ int startgap = rects[selectedIndex].x;
+ int endgap = rects[selectedIndex].x + rects[selectedIndex].width;
+
+ int diff = 0;
+
+ if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
+ {
+ Point p = findPointForIndex(currentScrollLocation);
+ diff = p.x;
+ }
+
+ if (tabPlacement == SwingConstants.TOP)
+ {
+ g.drawLine(x, y, startgap - diff, y);
+ g.drawLine(endgap - diff, y, x + w, y);
+ }
+ else
+ g.drawLine(x, y, x + w, y);
+
+ g.setColor(saved);
+ }
+
+ /**
+ * This method paints the left edge of the content border.
+ *
+ * @param g The Graphics object to paint with.
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param selectedIndex The selected tab index.
+ * @param x The x coordinate for the content area.
+ * @param y The y coordinate for the content area.
+ * @param w The width of the content area.
+ * @param h The height of the content area.
+ */
+ protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement,
+ int selectedIndex, int x, int y,
+ int w, int h)
+ {
+ Color saved = g.getColor();
+ g.setColor(lightHighlight);
+
+ int startgap = rects[selectedIndex].y;
+ int endgap = rects[selectedIndex].y + rects[selectedIndex].height;
+
+ int diff = 0;
+
+ if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
+ {
+ Point p = findPointForIndex(currentScrollLocation);
+ diff = p.y;
+ }
+
+ if (tabPlacement == SwingConstants.LEFT)
+ {
+ g.drawLine(x, y, x, startgap - diff);
+ g.drawLine(x, endgap - diff, x, y + h);
+ }
+ else
+ g.drawLine(x, y, x, y + h);
+
+ g.setColor(saved);
+ }
+
+ /**
+ * This method paints the bottom edge of the content border.
+ *
+ * @param g The Graphics object to paint with.
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param selectedIndex The selected tab index.
+ * @param x The x coordinate for the content area.
+ * @param y The y coordinate for the content area.
+ * @param w The width of the content area.
+ * @param h The height of the content area.
+ */
+ protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement,
+ int selectedIndex, int x, int y,
+ int w, int h)
+ {
+ Color saved = g.getColor();
+
+ int startgap = rects[selectedIndex].x;
+ int endgap = rects[selectedIndex].x + rects[selectedIndex].width;
+
+ int diff = 0;
+
+ if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
+ {
+ Point p = findPointForIndex(currentScrollLocation);
+ diff = p.x;
+ }
+
+ if (tabPlacement == SwingConstants.BOTTOM)
+ {
+ g.setColor(shadow);
+ g.drawLine(x + 1, y + h - 1, startgap - diff, y + h - 1);
+ g.drawLine(endgap - diff, y + h - 1, x + w - 1, y + h - 1);
+
+ g.setColor(darkShadow);
+ g.drawLine(x, y + h, startgap - diff, y + h);
+ g.drawLine(endgap - diff, y + h, x + w, y + h);
+ }
+ else
+ {
+ g.setColor(shadow);
+ g.drawLine(x + 1, y + h - 1, x + w - 1, y + h - 1);
+ g.setColor(darkShadow);
+ g.drawLine(x, y + h, x + w, y + h);
+ }
+
+ g.setColor(saved);
+ }
+
+ /**
+ * This method paints the right edge of the content border.
+ *
+ * @param g The Graphics object to paint with.
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param selectedIndex The selected tab index.
+ * @param x The x coordinate for the content area.
+ * @param y The y coordinate for the content area.
+ * @param w The width of the content area.
+ * @param h The height of the content area.
+ */
+ protected void paintContentBorderRightEdge(Graphics g, int tabPlacement,
+ int selectedIndex, int x, int y,
+ int w, int h)
+ {
+ Color saved = g.getColor();
+ int startgap = rects[selectedIndex].y;
+ int endgap = rects[selectedIndex].y + rects[selectedIndex].height;
+
+ int diff = 0;
+ if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
+ {
+ Point p = findPointForIndex(currentScrollLocation);
+ diff = p.y;
+ }
+
+ if (tabPlacement == SwingConstants.RIGHT)
+ {
+ g.setColor(shadow);
+ g.drawLine(x + w - 1, y + 1, x + w - 1, startgap - diff);
+ g.drawLine(x + w - 1, endgap - diff, x + w - 1, y + h - 1);
+
+ g.setColor(darkShadow);
+ g.drawLine(x + w, y, x + w, startgap - diff);
+ g.drawLine(x + w, endgap - diff, x + w, y + h);
+ }
+ else
+ {
+ g.setColor(shadow);
+ g.drawLine(x + w - 1, y + 1, x + w - 1, y + h - 1);
+ g.setColor(darkShadow);
+ g.drawLine(x + w, y, x + w, y + h);
+ }
+
+ g.setColor(saved);
+ }
+
+ /**
+ * This method returns the tab bounds for the given index.
+ *
+ * @param pane The JTabbedPane.
+ * @param i The index to look for.
+ *
+ * @return The bounds of the tab with the given index.
+ */
+ public Rectangle getTabBounds(JTabbedPane pane, int i)
+ {
+ return rects[i];
+ }
+
+ /**
+ * This method returns the number of runs.
+ *
+ * @param pane The JTabbedPane.
+ *
+ * @return The number of runs.
+ */
+ public int getTabRunCount(JTabbedPane pane)
+ {
+ return runCount;
+ }
+
+ /**
+ * This method returns the tab index given a coordinate.
+ *
+ * @param pane The JTabbedPane.
+ * @param x The x coordinate.
+ * @param y The y coordinate.
+ *
+ * @return The tab index that the coordinate lands in.
+ */
+ public int tabForCoordinate(JTabbedPane pane, int x, int y)
+ {
+ Point p = new Point(x, y);
+ int tabCount = tabPane.getTabCount();
+ int currRun = 1;
+ for (int i = 0; i < runCount; i++)
+ {
+ int first = lastTabInRun(tabCount, getPreviousTabRun(currRun)) + 1;
+ if (first == tabCount)
+ first = 0;
+ int last = lastTabInRun(tabCount, currRun);
+ for (int j = first; j <= last; j++)
+ {
+ if (getTabBounds(pane, j).contains(p))
+ return j;
+ }
+ currRun = getNextTabRun(currRun);
+ }
+ return -1;
+ }
+
+ /**
+ * This method returns the tab bounds in the given rectangle.
+ *
+ * @param tabIndex The index to get bounds for.
+ * @param dest The rectangle to store bounds in.
+ *
+ * @return The rectangle passed in.
+ */
+ protected Rectangle getTabBounds(int tabIndex, Rectangle dest)
+ {
+ dest.setBounds(getTabBounds(tabPane, tabIndex));
+ return dest;
+ }
+
+ /**
+ * This method returns the component that is shown in the content area.
+ *
+ * @return The component that is shown in the content area.
+ */
+ protected Component getVisibleComponent()
+ {
+ return tabPane.getComponentAt(tabPane.getSelectedIndex());
+ }
+
+ /**
+ * This method sets the visible component.
+ *
+ * @param component The component to be set visible.
+ */
+ protected void setVisibleComponent(Component component)
+ {
+ component.setVisible(true);
+ tabPane.setSelectedComponent(component);
+ }
+
+ /**
+ * This method assures that enough rectangles are created given the
+ * tabCount. The old array is copied to the new one.
+ *
+ * @param tabCount The number of tabs.
+ */
+ protected void assureRectsCreated(int tabCount)
+ {
+ if (rects == null)
+ rects = new Rectangle[tabCount];
+ if (tabCount == rects.length)
+ return;
+ else
+ {
+ int numToCopy = Math.min(tabCount, rects.length);
+ Rectangle[] tmp = new Rectangle[tabCount];
+ System.arraycopy(rects, 0, tmp, 0, numToCopy);
+ rects = tmp;
+ }
+ }
+
+ /**
+ * This method expands the tabRuns array to give it more room. The old array
+ * is copied to the new one.
+ */
+ protected void expandTabRunsArray()
+ {
+ // This method adds another 10 index positions to the tabRuns array.
+ if (tabRuns == null)
+ tabRuns = new int[10];
+ else
+ {
+ int[] newRuns = new int[tabRuns.length + 10];
+ System.arraycopy(tabRuns, 0, newRuns, 0, tabRuns.length);
+ tabRuns = newRuns;
+ }
+ }
+
+ /**
+ * This method returns which run a particular tab belongs to.
+ *
+ * @param tabCount The number of tabs.
+ * @param tabIndex The tab to find.
+ *
+ * @return The tabRuns index that it belongs to.
+ */
+ protected int getRunForTab(int tabCount, int tabIndex)
+ {
+ if (runCount == 1 && tabIndex < tabCount && tabIndex >= 0)
+ return 1;
+ for (int i = 0; i < runCount; i++)
+ {
+ int first = lastTabInRun(tabCount, getPreviousTabRun(i)) + 1;
+ if (first == tabCount)
+ first = 0;
+ int last = lastTabInRun(tabCount, i);
+ if (last >= tabIndex && first <= tabIndex)
+ return i;
+ }
+ return -1;
+ }
+
+ /**
+ * This method returns the index of the last tab in a run.
+ *
+ * @param tabCount The number of tabs.
+ * @param run The run to check.
+ *
+ * @return The last tab in the given run.
+ */
+ protected int lastTabInRun(int tabCount, int run)
+ {
+ if (tabRuns[run] == 0)
+ return tabCount - 1;
+ else
+ return tabRuns[run] - 1;
+ }
+
+ /**
+ * This method returns the tab run overlay.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ *
+ * @return The tab run overlay.
+ */
+ protected int getTabRunOverlay(int tabPlacement)
+ {
+ return tabRunOverlay;
+ }
+
+ /**
+ * This method returns the tab run indent. It is used in WRAP_TAB_LAYOUT and
+ * makes each tab run start indented by a certain amount.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param run The run to get indent for.
+ *
+ * @return The amount a run should be indented.
+ */
+ protected int getTabRunIndent(int tabPlacement, int run)
+ {
+ return 0;
+ }
+
+ /**
+ * This method returns whether a tab run should be padded.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param run The run to check.
+ *
+ * @return Whether the given run should be padded.
+ */
+ protected boolean shouldPadTabRun(int tabPlacement, int run)
+ {
+ return true;
+ }
+
+ /**
+ * This method returns whether the tab runs should be rotated.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ *
+ * @return Whether runs should be rotated.
+ */
+ protected boolean shouldRotateTabRuns(int tabPlacement)
+ {
+ return true;
+ }
+
+ /**
+ * This method returns an icon for the tab. If the tab is disabled, it
+ * should return the disabledIcon. If it is enabled, then it should return
+ * the default icon.
+ *
+ * @param tabIndex The tab index to get an icon for.
+ *
+ * @return The icon for the tab index.
+ */
+ protected Icon getIconForTab(int tabIndex)
+ {
+ if (tabPane.isEnabledAt(tabIndex))
+ return tabPane.getIconAt(tabIndex);
+ else
+ return tabPane.getDisabledIconAt(tabIndex);
+ }
+
+ /**
+ * This method returns a view that can paint the text for the label.
+ *
+ * @param tabIndex The tab index to get a view for.
+ *
+ * @return The view for the tab index.
+ */
+ protected View getTextViewForTab(int tabIndex)
+ {
+ return null;
+ }
+
+ /**
+ * This method returns the tab height, including insets, for the given index
+ * and fontheight.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param tabIndex The index of the tab to calculate.
+ * @param fontHeight The font height.
+ *
+ * @return This tab's height.
+ */
+ protected int calculateTabHeight(int tabPlacement, int tabIndex,
+ int fontHeight)
+ {
+ Icon icon = getIconForTab(tabIndex);
+ Insets insets = getTabInsets(tabPlacement, tabIndex);
+
+ if (icon != null)
+ {
+ Rectangle vr = new Rectangle();
+ Rectangle ir = new Rectangle();
+ Rectangle tr = new Rectangle();
+ layoutLabel(tabPlacement, getFontMetrics(), tabIndex,
+ tabPane.getTitleAt(tabIndex), icon, vr, ir, tr,
+ tabIndex == tabPane.getSelectedIndex());
+ calcRect = tr.union(ir);
+ }
+ else
+ calcRect.height = fontHeight;
+
+ calcRect.height += insets.top + insets.bottom;
+ return calcRect.height;
+ }
+
+ /**
+ * This method returns the max tab height.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ *
+ * @return The maximum tab height.
+ */
+ protected int calculateMaxTabHeight(int tabPlacement)
+ {
+ maxTabHeight = 0;
+
+ FontMetrics fm = getFontMetrics();
+ int fontHeight = fm.getHeight();
+
+ for (int i = 0; i < tabPane.getTabCount(); i++)
+ maxTabHeight = Math.max(calculateTabHeight(tabPlacement, i, fontHeight),
+ maxTabHeight);
+
+ return maxTabHeight;
+ }
+
+ /**
+ * This method calculates the tab width, including insets, for the given tab
+ * index and font metrics.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param tabIndex The tab index to calculate for.
+ * @param metrics The font's metrics.
+ *
+ * @return The tab width for the given index.
+ */
+ protected int calculateTabWidth(int tabPlacement, int tabIndex,
+ FontMetrics metrics)
+ {
+ Icon icon = getIconForTab(tabIndex);
+ Insets insets = getTabInsets(tabPlacement, tabIndex);
+
+ if (icon != null)
+ {
+ Rectangle vr = new Rectangle();
+ Rectangle ir = new Rectangle();
+ Rectangle tr = new Rectangle();
+ layoutLabel(tabPlacement, getFontMetrics(), tabIndex,
+ tabPane.getTitleAt(tabIndex), icon, vr, ir, tr,
+ tabIndex == tabPane.getSelectedIndex());
+ calcRect = tr.union(ir);
+ }
+ else
+ calcRect.width = metrics.stringWidth(tabPane.getTitleAt(tabIndex));
+
+ calcRect.width += insets.left + insets.right;
+ return calcRect.width;
+ }
+
+ /**
+ * This method calculates the max tab width.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ *
+ * @return The maximum tab width.
+ */
+ protected int calculateMaxTabWidth(int tabPlacement)
+ {
+ maxTabWidth = 0;
+
+ FontMetrics fm = getFontMetrics();
+
+ for (int i = 0; i < tabPane.getTabCount(); i++)
+ maxTabWidth = Math.max(calculateTabWidth(tabPlacement, i, fm),
+ maxTabWidth);
+
+ return maxTabWidth;
+ }
+
+ /**
+ * This method calculates the tab area height, including insets, for the
+ * given amount of runs and tab height.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param horizRunCount The number of runs.
+ * @param maxTabHeight The max tab height.
+ *
+ * @return The tab area height.
+ */
+ protected int calculateTabAreaHeight(int tabPlacement, int horizRunCount,
+ int maxTabHeight)
+ {
+ Insets insets = getTabAreaInsets(tabPlacement);
+ int tabAreaHeight = horizRunCount * maxTabHeight
+ - (horizRunCount - 1) * tabRunOverlay;
+
+ tabAreaHeight += insets.top + insets.bottom;
+
+ return tabAreaHeight;
+ }
+
+ /**
+ * This method calculates the tab area width, including insets, for the
+ * given amount of runs and tab width.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param vertRunCount The number of runs.
+ * @param maxTabWidth The max tab width.
+ *
+ * @return The tab area width.
+ */
+ protected int calculateTabAreaWidth(int tabPlacement, int vertRunCount,
+ int maxTabWidth)
+ {
+ Insets insets = getTabAreaInsets(tabPlacement);
+ int tabAreaWidth = vertRunCount * maxTabWidth
+ - (vertRunCount - 1) * tabRunOverlay;
+
+ tabAreaWidth += insets.left + insets.right;
+
+ return tabAreaWidth;
+ }
+
+ /**
+ * This method returns the tab insets appropriately rotated.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param tabIndex The tab index.
+ *
+ * @return The tab insets for the given index.
+ */
+ protected Insets getTabInsets(int tabPlacement, int tabIndex)
+ {
+ Insets target = new Insets(0, 0, 0, 0);
+ rotateInsets(tabInsets, target, tabPlacement);
+ return target;
+ }
+
+ /**
+ * This method returns the selected tab pad insets appropriately rotated.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ *
+ * @return The selected tab pad insets.
+ */
+ protected Insets getSelectedTabPadInsets(int tabPlacement)
+ {
+ Insets target = new Insets(0, 0, 0, 0);
+ rotateInsets(selectedTabPadInsets, target, tabPlacement);
+ return target;
+ }
+
+ /**
+ * This method returns the tab area insets appropriately rotated.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ *
+ * @return The tab area insets.
+ */
+ protected Insets getTabAreaInsets(int tabPlacement)
+ {
+ Insets target = new Insets(0, 0, 0, 0);
+ rotateInsets(tabAreaInsets, target, tabPlacement);
+ return target;
+ }
+
+ /**
+ * This method returns the content border insets appropriately rotated.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ *
+ * @return The content border insets.
+ */
+ protected Insets getContentBorderInsets(int tabPlacement)
+ {
+ Insets target = new Insets(0, 0, 0, 0);
+ rotateInsets(contentBorderInsets, target, tabPlacement);
+ return target;
+ }
+
+ /**
+ * This method returns the fontmetrics for the font of the JTabbedPane.
+ *
+ * @return The font metrics for the JTabbedPane.
+ */
+ protected FontMetrics getFontMetrics()
+ {
+ FontMetrics fm = tabPane.getToolkit().getFontMetrics(tabPane.getFont());
+ return fm;
+ }
+
+ /**
+ * This method navigates from the selected tab into the given direction. As
+ * a result, a new tab will be selected (if possible).
+ *
+ * @param direction The direction to navigate in.
+ */
+ protected void navigateSelectedTab(int direction)
+ {
+ int tabPlacement = tabPane.getTabPlacement();
+ if (tabPlacement == SwingConstants.TOP
+ || tabPlacement == SwingConstants.BOTTOM)
+ {
+ if (direction == SwingConstants.WEST)
+ selectPreviousTabInRun(tabPane.getSelectedIndex());
+ else if (direction == SwingConstants.EAST)
+ selectNextTabInRun(tabPane.getSelectedIndex());
+
+ else
+ {
+ int offset = getTabRunOffset(tabPlacement, tabPane.getTabCount(),
+ tabPane.getSelectedIndex(),
+ (tabPlacement == SwingConstants.RIGHT)
+ ? true : false);
+ selectAdjacentRunTab(tabPlacement, tabPane.getSelectedIndex(),
+ offset);
+ }
+ }
+ if (tabPlacement == SwingConstants.LEFT
+ || tabPlacement == SwingConstants.RIGHT)
+ {
+ if (direction == SwingConstants.NORTH)
+ selectPreviousTabInRun(tabPane.getSelectedIndex());
+ else if (direction == SwingConstants.SOUTH)
+ selectNextTabInRun(tabPane.getSelectedIndex());
+ else
+ {
+ int offset = getTabRunOffset(tabPlacement, tabPane.getTabCount(),
+ tabPane.getSelectedIndex(),
+ (tabPlacement == SwingConstants.RIGHT)
+ ? true : false);
+ selectAdjacentRunTab(tabPlacement, tabPane.getSelectedIndex(),
+ offset);
+ }
+ }
+ }
+
+ /**
+ * This method selects the next tab in the run.
+ *
+ * @param current The current selected index.
+ */
+ protected void selectNextTabInRun(int current)
+ {
+ tabPane.setSelectedIndex(getNextTabIndexInRun(tabPane.getTabCount(),
+ current));
+ }
+
+ /**
+ * This method selects the previous tab in the run.
+ *
+ * @param current The current selected index.
+ */
+ protected void selectPreviousTabInRun(int current)
+ {
+ tabPane.setSelectedIndex(getPreviousTabIndexInRun(tabPane.getTabCount(),
+ current));
+ }
+
+ /**
+ * This method selects the next tab (regardless of runs).
+ *
+ * @param current The current selected index.
+ */
+ protected void selectNextTab(int current)
+ {
+ tabPane.setSelectedIndex(getNextTabIndex(current));
+ }
+
+ /**
+ * This method selects the previous tab (regardless of runs).
+ *
+ * @param current The current selected index.
+ */
+ protected void selectPreviousTab(int current)
+ {
+ tabPane.setSelectedIndex(getPreviousTabIndex(current));
+ }
+
+ /**
+ * This method selects the correct tab given an offset from the current tab
+ * index. If the tab placement is TOP or BOTTOM, the offset will be in the
+ * y direction, otherwise, it will be in the x direction. A new coordinate
+ * will be found by adding the offset to the current location of the tab.
+ * The tab that the new location will be selected.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param tabIndex The tab to start from.
+ * @param offset The coordinate offset.
+ */
+ protected void selectAdjacentRunTab(int tabPlacement, int tabIndex,
+ int offset)
+ {
+ int x = rects[tabIndex].x + rects[tabIndex].width / 2;
+ int y = rects[tabIndex].y + rects[tabIndex].height / 2;
+
+ switch (tabPlacement)
+ {
+ case SwingConstants.TOP:
+ case SwingConstants.BOTTOM:
+ y += offset;
+ break;
+ case SwingConstants.RIGHT:
+ case SwingConstants.LEFT:
+ x += offset;
+ break;
+ }
+
+ int index = tabForCoordinate(tabPane, x, y);
+ if (index != -1)
+ tabPane.setSelectedIndex(index);
+ }
+
+ // This method is called when you press up/down to cycle through tab runs.
+ // it returns the distance (between the two runs' x/y position.
+ // where one run is the current selected run and the other run is the run in the
+ // direction of the scroll (dictated by the forward flag)
+ // the offset is an absolute value of the difference
+
+ /**
+ * This method calculates the offset distance for use in
+ * selectAdjacentRunTab. The offset returned will be a difference in the y
+ * coordinate between the run in the desired direction and the current run
+ * (for tabPlacement in TOP or BOTTOM). Use x coordinate for LEFT and
+ * RIGHT.
+ *
+ * @param tabPlacement The JTabbedPane's tab placement.
+ * @param tabCount The number of tabs.
+ * @param tabIndex The starting index.
+ * @param forward If forward, the run in the desired direction will be the
+ * next run.
+ *
+ * @return The offset between the two runs.
+ */
+ protected int getTabRunOffset(int tabPlacement, int tabCount, int tabIndex,
+ boolean forward)
+ {
+ int currRun = getRunForTab(tabCount, tabIndex);
+ int offset;
+ int nextRun = (forward) ? getNextTabRun(currRun) : getPreviousTabRun(currRun);
+ if (tabPlacement == SwingConstants.TOP
+ || tabPlacement == SwingConstants.BOTTOM)
+ offset = rects[lastTabInRun(tabCount, nextRun)].y
+ - rects[lastTabInRun(tabCount, currRun)].y;
+ else
+ offset = rects[lastTabInRun(tabCount, nextRun)].x
+ - rects[lastTabInRun(tabCount, currRun)].x;
+ return offset;
+ }
+
+ /**
+ * This method returns the previous tab index.
+ *
+ * @param base The index to start from.
+ *
+ * @return The previous tab index.
+ */
+ protected int getPreviousTabIndex(int base)
+ {
+ base--;
+ if (base < 0)
+ return tabPane.getTabCount() - 1;
+ return base;
+ }
+
+ /**
+ * This method returns the next tab index.
+ *
+ * @param base The index to start from.
+ *
+ * @return The next tab index.
+ */
+ protected int getNextTabIndex(int base)
+ {
+ base++;
+ if (base == tabPane.getTabCount())
+ return 0;
+ return base;
+ }
+
+ /**
+ * This method returns the next tab index in the run. If the next index is
+ * out of this run, it will return the starting tab index for the run.
+ *
+ * @param tabCount The number of tabs.
+ * @param base The index to start from.
+ *
+ * @return The next tab index in the run.
+ */
+ protected int getNextTabIndexInRun(int tabCount, int base)
+ {
+ int index = getNextTabIndex(base);
+ int run = getRunForTab(tabCount, base);
+ if (index == lastTabInRun(tabCount, run) + 1)
+ index = lastTabInRun(tabCount, getPreviousTabRun(run)) + 1;
+ return getNextTabIndex(base);
+ }
+
+ /**
+ * This method returns the previous tab index in the run. If the previous
+ * index is out of this run, it will return the last index for the run.
+ *
+ * @param tabCount The number of tabs.
+ * @param base The index to start from.
+ *
+ * @return The previous tab index in the run.
+ */
+ protected int getPreviousTabIndexInRun(int tabCount, int base)
+ {
+ int index = getPreviousTabIndex(base);
+ int run = getRunForTab(tabCount, base);
+ if (index == lastTabInRun(tabCount, getPreviousTabRun(run)))
+ index = lastTabInRun(tabCount, run);
+ return getPreviousTabIndex(base);
+ }
+
+ /**
+ * This method returns the index of the previous run.
+ *
+ * @param baseRun The run to start from.
+ *
+ * @return The index of the previous run.
+ */
+ protected int getPreviousTabRun(int baseRun)
+ {
+ if (getTabRunCount(tabPane) == 1)
+ return 1;
+
+ int prevRun = --baseRun;
+ if (prevRun < 0)
+ prevRun = getTabRunCount(tabPane) - 1;
+ return prevRun;
+ }
+
+ /**
+ * This method returns the index of the next run.
+ *
+ * @param baseRun The run to start from.
+ *
+ * @return The index of the next run.
+ */
+ protected int getNextTabRun(int baseRun)
+ {
+ if (getTabRunCount(tabPane) == 1)
+ return 1;
+
+ int nextRun = ++baseRun;
+ if (nextRun == getTabRunCount(tabPane))
+ nextRun = 0;
+ return nextRun;
+ }
+
+ /**
+ * This method rotates the insets given a direction to rotate them in.
+ * Target placement should be one of TOP, LEFT, BOTTOM, RIGHT. The rotated
+ * insets will be stored in targetInsets. Passing in TOP as the direction
+ * does nothing. Passing in LEFT switches top and left, right and bottom.
+ * Passing in BOTTOM switches top and bottom. Passing in RIGHT switches top
+ * for left, left for bottom, bottom for right, and right for top.
+ *
+ * @param topInsets The reference insets.
+ * @param targetInsets An Insets object to store the new insets.
+ * @param targetPlacement The rotation direction.
+ */
+ protected static void rotateInsets(Insets topInsets, Insets targetInsets,
+ int targetPlacement)
+ {
+ // Sun's version will happily throw an NPE if params are null,
+ // so I won't check it either.
+ switch (targetPlacement)
+ {
+ case SwingConstants.TOP:
+ targetInsets.top = topInsets.top;
+ targetInsets.left = topInsets.left;
+ targetInsets.right = topInsets.right;
+ targetInsets.bottom = topInsets.bottom;
+ break;
+ case SwingConstants.LEFT:
+ targetInsets.left = topInsets.top;
+ targetInsets.top = topInsets.left;
+ targetInsets.right = topInsets.bottom;
+ targetInsets.bottom = topInsets.right;
+ break;
+ case SwingConstants.BOTTOM:
+ targetInsets.top = topInsets.bottom;
+ targetInsets.bottom = topInsets.top;
+ targetInsets.left = topInsets.left;
+ targetInsets.right = topInsets.right;
+ break;
+ case SwingConstants.RIGHT:
+ targetInsets.top = topInsets.left;
+ targetInsets.left = topInsets.bottom;
+ targetInsets.bottom = topInsets.right;
+ targetInsets.right = topInsets.top;
+ break;
+ }
+ }
}
-
diff --git a/libjava/javax/swing/plaf/basic/BasicToggleButtonUI.java b/libjava/javax/swing/plaf/basic/BasicToggleButtonUI.java
index c6b3bdb0670..a319b0b4e02 100644
--- a/libjava/javax/swing/plaf/basic/BasicToggleButtonUI.java
+++ b/libjava/javax/swing/plaf/basic/BasicToggleButtonUI.java
@@ -38,10 +38,6 @@ exception statement from your version. */
package javax.swing.plaf.basic;
-import java.awt.Dimension;
-import java.awt.Graphics;
-import java.awt.Rectangle;
-import javax.swing.AbstractButton;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
diff --git a/libjava/javax/swing/plaf/basic/BasicViewportUI.java b/libjava/javax/swing/plaf/basic/BasicViewportUI.java
index f686ca08010..463865c5be9 100644
--- a/libjava/javax/swing/plaf/basic/BasicViewportUI.java
+++ b/libjava/javax/swing/plaf/basic/BasicViewportUI.java
@@ -127,6 +127,7 @@ public class BasicViewportUI extends ViewportUI
Point pos = v.getViewPosition();
Rectangle viewBounds = view.getBounds();
+ Rectangle portBounds = v.getBounds();
if (backingStoreImage == null
|| backingStoreWidth != viewBounds.width
@@ -138,6 +139,32 @@ public class BasicViewportUI extends ViewportUI
}
Graphics g2 = backingStoreImage.getGraphics();
+
+
+ if (c.getBackground() != null)
+ {
+ // fill the backing store background
+ java.awt.Color save = g2.getColor();
+ g2.setColor(c.getBackground());
+ g2.fillRect (0, 0, backingStoreWidth, backingStoreHeight);
+ g2.setColor(save);
+
+ // fill the viewport background
+ save = g.getColor();
+ g.setColor(c.getBackground());
+ g.fillRect (0, 0, portBounds.width, portBounds.height);
+ g.setColor(save);
+
+ }
+ else
+ {
+ // clear the backing store background
+ g2.clearRect(0, 0, backingStoreWidth, backingStoreHeight);
+
+ // clear the viewport background
+ g.clearRect(0, 0, portBounds.width, portBounds.height);
+ }
+
view.paint(g2);
g2 = null;
g.drawImage(backingStoreImage,
diff --git a/libjava/javax/swing/table/DefaultTableCellRenderer.java b/libjava/javax/swing/table/DefaultTableCellRenderer.java
index 6bd0ff57f59..563d9e60af2 100644
--- a/libjava/javax/swing/table/DefaultTableCellRenderer.java
+++ b/libjava/javax/swing/table/DefaultTableCellRenderer.java
@@ -54,7 +54,7 @@ public class DefaultTableCellRenderer extends JLabel
{
static final long serialVersionUID = 7878911414715528324L;
- protected static Border noFocusBorder;
+ protected static Border noFocusBorder = new EmptyBorder(0, 0, 0, 0);
public static class UIResource extends DefaultTableCellRenderer
implements javax.swing.plaf.UIResource
@@ -70,7 +70,6 @@ public class DefaultTableCellRenderer extends JLabel
public DefaultTableCellRenderer()
{
super();
- this.noFocusBorder = new EmptyBorder(0, 0, 0, 0);
}
/**
diff --git a/libjava/javax/swing/table/JTableHeader.java b/libjava/javax/swing/table/JTableHeader.java
index d747664cd12..6b486019532 100644
--- a/libjava/javax/swing/table/JTableHeader.java
+++ b/libjava/javax/swing/table/JTableHeader.java
@@ -1,5 +1,5 @@
/* JTableHeader.java
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,27 +38,8 @@ exception statement from your version. */
package javax.swing.table;
-import java.awt.Color;
-import java.awt.Cursor;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.event.FocusListener;
-import java.util.Locale;
-import javax.accessibility.Accessible;
-import javax.accessibility.AccessibleComponent;
-import javax.accessibility.AccessibleContext;
-import javax.accessibility.AccessibleRole;
-import javax.accessibility.AccessibleStateSet;
import javax.swing.JComponent;
import javax.swing.JTable;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.TableColumnModelEvent;
-import javax.swing.event.TableColumnModelListener;
-import javax.swing.plaf.TableHeaderUI;
public class JTableHeader extends JComponent
{
diff --git a/libjava/javax/swing/table/TableColumn.java b/libjava/javax/swing/table/TableColumn.java
index d228d8aae92..73313c6c7da 100644
--- a/libjava/javax/swing/table/TableColumn.java
+++ b/libjava/javax/swing/table/TableColumn.java
@@ -218,9 +218,10 @@ public class TableColumn implements Serializable
* @param oldValue TODO
* @param newValue TODO
*/
- private void firePropertyChange(String property, boolean oldValue, boolean newValue) {
+ private void firePropertyChange(String property, boolean oldValue, boolean newValue)
+ {
firePropertyChange(property, new Boolean(oldValue), new Boolean(newValue));
- } // firePropertyChange()
+ }
/**
* setModelIndex
diff --git a/libjava/javax/swing/text/AbstractDocument.java b/libjava/javax/swing/text/AbstractDocument.java
index 027b99d5cb5..6408b22cdfb 100644
--- a/libjava/javax/swing/text/AbstractDocument.java
+++ b/libjava/javax/swing/text/AbstractDocument.java
@@ -41,9 +41,9 @@ import java.util.Dictionary;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.Vector;
+
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
-import javax.swing.event.EventListenerList;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.tree.TreeNode;
diff --git a/libjava/javax/swing/text/DefaultCaret.java b/libjava/javax/swing/text/DefaultCaret.java
index 7fdc3fcc541..1c4607fce9f 100644
--- a/libjava/javax/swing/text/DefaultCaret.java
+++ b/libjava/javax/swing/text/DefaultCaret.java
@@ -41,16 +41,12 @@ import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
-import java.awt.Shape;
-import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
-import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
-import java.util.EventListener;
import java.util.Vector;
+
import javax.swing.event.ChangeListener;
-import javax.swing.event.EventListenerList;
public class DefaultCaret extends Rectangle implements Caret, FocusListener, MouseListener, MouseMotionListener
diff --git a/libjava/javax/swing/text/StyledEditorKit.java b/libjava/javax/swing/text/StyledEditorKit.java
index 8ec90662191..f237247a01f 100644
--- a/libjava/javax/swing/text/StyledEditorKit.java
+++ b/libjava/javax/swing/text/StyledEditorKit.java
@@ -41,11 +41,8 @@ import java.awt.Color;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Reader;
import java.io.Serializable;
-import java.io.Writer;
+
import javax.swing.Action;
import javax.swing.JEditorPane;
import javax.swing.event.CaretEvent;
diff --git a/libjava/javax/swing/tree/DefaultTreeCellEditor.java b/libjava/javax/swing/tree/DefaultTreeCellEditor.java
index 6d922a42437..bebdc6a9e64 100644
--- a/libjava/javax/swing/tree/DefaultTreeCellEditor.java
+++ b/libjava/javax/swing/tree/DefaultTreeCellEditor.java
@@ -1,5 +1,5 @@
/* DefaultTreeCellEditor.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -50,12 +50,12 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.EventObject;
+
import javax.swing.Icon;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.border.Border;
import javax.swing.event.CellEditorListener;
-import javax.swing.event.EventListenerList;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
diff --git a/libjava/javax/swing/undo/CompoundEdit.java b/libjava/javax/swing/undo/CompoundEdit.java
index 565a3279b20..730d5b253a1 100644
--- a/libjava/javax/swing/undo/CompoundEdit.java
+++ b/libjava/javax/swing/undo/CompoundEdit.java
@@ -45,17 +45,18 @@ import java.util.Vector;
* <code>UndoableEdits</code>.
*
* <p>The use of a <code>CompoundEdit</code> is divided in two separate
- * phases.
- *
- * <ol><li>In the first phase, the <code>CompoundEdit</code> is
- * initialized. After a new instance of <code>CompoundEdit</code> has
- * been created, {@link #addEdit(UndoableEdit)} is called for each
- * element of the compound. To terminate the initialization phase,
- * call {@link #end()}.</li>
+ * phases.</p>
*
+ * <ol>
+ * <li>In the first phase, the <code>CompoundEdit</code> is
+ * initialized. After a new instance of <code>CompoundEdit</code> has
+ * been created, {@link #addEdit(UndoableEdit)} is called for each
+ * element of the compound. To terminate the initialization phase,
+ * call {@link #end()}.</li>
* <li>In the second phase, the the <code>CompoundEdit</code> can be
- * used, typically by invoking {@link #undo()} and {@link
- * #redo()}.</li></ol>
+ * used, typically by invoking {@link #undo()} and
+ * {@link #redo()}.</li>
+ * </ol>
*
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
diff --git a/libjava/javax/swing/undo/StateEdit.java b/libjava/javax/swing/undo/StateEdit.java
index 00f1e2d830c..633807b7167 100644
--- a/libjava/javax/swing/undo/StateEdit.java
+++ b/libjava/javax/swing/undo/StateEdit.java
@@ -44,52 +44,54 @@ import java.util.Iterator;
/**
* A helper class, making it easy to support undo and redo.
*
- * <p>The following example shows how to use this class.
+ * <p>The following example shows how to use this class.</p>
*
- * <pre> Foo foo; // class Foo implements {@link StateEditable}
- * StateEdit edit;
+ * <pre>
+ * Foo foo; // class Foo implements {@link StateEditable}
+ * StateEdit edit;
*
- * edit = new StateEdit(foo, "Name Change");
- * foo.setName("Jane Doe");
- * edit.end();
- * undoManager.addEdit(edit);</pre>
+ * edit = new StateEdit(foo, "Name Change");
+ * foo.setName("Jane Doe");
+ * edit.end();
+ * undoManager.addEdit(edit);
+ * </pre>
*
* <p>If <code>Foo</code>&#x2019;s implementation of {@link
* StateEditable} considers the name as part of the editable state,
* the user can now choose &#x201c;Undo Name Change&#x201d; or
* &#x201c;Redo Name Change&#x201d; from the respective menu. No
- * further undo support is needed from the application.
+ * further undo support is needed from the application.</p>
*
- * <p>The following explains what happens in the example.
- *
- * <p><ol><li>When a <code>StateEdit</code> is created, the associated
- * {@link StateEditable} gets asked to store its state into a hash
- * table, {@link #preState}.</li>
+ * <p>The following explains what happens in the example.</p>
*
+ * <ol>
+ * <li>When a <code>StateEdit</code> is created, the associated
+ * {@link StateEditable} gets asked to store its state into a hash
+ * table, {@link #preState}.</li>
* <li>The application will now perform some changes to the edited
- * object. This typically happens by invoking methods on the edited
- * object.</li>
- *
+ * object. This typically happens by invoking methods on the edited
+ * object.</li>
* <li>The editing phase is terminated by invoking the {@link #end()}
- * method of the <code>StateEdit</code>. The <code>end()</code> method
- * does two things.
- *
- * <ul><li>The edited object receives a second request for storing
- * its state. This time, it will use a different hash table, {@link
- * #postState}.</li>
- *
- * <li>To increase efficiency, the <code>StateEdit</code> now removes
- * any entries from {@link #preState} and {@link #postState} that have
- * the same key, and whose values are equal. Equality is determined
- * by invoking the <code>equals</code> method inherited from
- * {@link java.lang.Object}.</li></ul></li>
+ * method of the <code>StateEdit</code>. The <code>end()</code> method
+ * does two things.
*
+ * <ul>
+ * <li>The edited object receives a second request for storing
+ * its state. This time, it will use a different hash table, {@link
+ * #postState}.</li>
+ * <li>To increase efficiency, the <code>StateEdit</code> now removes
+ * any entries from {@link #preState} and {@link #postState} that have
+ * the same key, and whose values are equal. Equality is determined
+ * by invoking the <code>equals</code> method inherited from
+ * {@link java.lang.Object}.</li>
+ * </ul></li>
* <li>When the user later chooses to undo the <code>StateEdit</code>,
* the edited object is asked to {@linkplain StateEditable#restoreState
* restore its state} from the {@link #preState} table. Similarly,
* when the user chooses to <i>redo</i> the <code>StateEdit</code>,
* the edited object gets asked to restore its state from the {@link
- * #postState}.</li></ol>
+ * #postState}.</li>
+ * </ol>
*
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
diff --git a/libjava/jni.cc b/libjava/jni.cc
index 3e8b11bbe8d..af30cf62a78 100644
--- a/libjava/jni.cc
+++ b/libjava/jni.cc
@@ -1,6 +1,6 @@
// jni.cc - JNI implementation, including the jump table.
-/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
This file is part of libgcj.
@@ -560,11 +560,12 @@ static jint
NULL);
jclass *elts = elements (argtypes);
- elts[0] = &StringClass;
+ elts[0] = &java::lang::String::class$;
Constructor *cons = clazz->getConstructor (argtypes);
- jobjectArray values = JvNewObjectArray (1, &StringClass, NULL);
+ jobjectArray values = JvNewObjectArray (1, &java::lang::String::class$,
+ NULL);
jobject *velts = elements (values);
velts[0] = JvNewStringUTF (message);
@@ -633,7 +634,7 @@ static jobject
if (clazz->isInterface() || Modifier::isAbstract(clazz->getModifiers()))
env->ex = new java::lang::InstantiationException ();
else
- obj = JvAllocObject (clazz);
+ obj = _Jv_AllocObject (clazz);
}
catch (jthrowable t)
{
@@ -1198,7 +1199,7 @@ static jfieldID
// The field might be resolved or it might not be. It
// is much simpler to always resolve it.
- _Jv_ResolveField (field, loader);
+ _Jv_Linker::resolve_field (field, loader);
if (_Jv_equalUtf8Consts (f_name, a_name)
&& field->getClass() == field_class)
return field;
diff --git a/libjava/jni/classpath/jcl.c b/libjava/jni/classpath/jcl.c
index 629d0716389..855c5938563 100644
--- a/libjava/jni/classpath/jcl.c
+++ b/libjava/jni/classpath/jcl.c
@@ -1,5 +1,5 @@
/* jcl.c
- Copyright (C) 1998 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,13 +37,17 @@ exception statement from your version. */
#include <stdio.h>
#include <jcl.h>
-#include <malloc.h>
+#include <stdlib.h>
#ifndef __GNUC__
#define __attribute__(x) /* nothing */
#endif
-static char errstr[4098]; // this way the memory is pre-allocated, so that we do not have to worry if we are out of memory.
+/*
+ * This way the memory is pre-allocated, so that we do not have to worry
+ * if we are out of memory.
+ */
+static char errstr[4098];
JNIEXPORT void JNICALL JCL_ThrowException(JNIEnv * env, char * className, char * errMsg) {
jclass excClass;
diff --git a/libjava/jni/classpath/jnilink.c b/libjava/jni/classpath/jnilink.c
index 0c244f285af..d92654161c8 100644
--- a/libjava/jni/classpath/jnilink.c
+++ b/libjava/jni/classpath/jnilink.c
@@ -1,5 +1,5 @@
/* JNILINK 1.1: JNI version.
- Copyright (C) 1998 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,7 +40,7 @@ exception statement from your version. */
#include <string.h>
#include <jcl.h>
-#include <malloc.h>
+#include <stdlib.h>
#define GETCLASS(c) *(jclass*)(c)
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
index f8ee342a033..a161ba49992 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
@@ -145,7 +145,7 @@ grab_current_drawable (GtkWidget *widget, GdkDrawable **draw, GdkWindow **win)
}
*draw = *win;
- gdk_window_get_internal_paint_info (*win, draw, 0, 0);
+ gdk_window_get_internal_paint_info (*win, draw, 0, 0);
g_object_ref (*draw);
}
@@ -349,7 +349,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__II
if (gr->debug) printf ("constructing offscreen drawable of size (%d,%d)\n",
width, height);
-
+
gr->drawable = (GdkDrawable *) gdk_pixmap_new (NULL, width, height,
gdk_rgb_get_visual ()->depth);
g_assert (gr->drawable != NULL);
@@ -371,9 +371,12 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__II
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_gdkDrawDrawable
(JNIEnv *env, jobject self, jobject other, jint x, jint y)
{
+ GdkRectangle clipRect;
struct graphics2d *src = NULL, *dst = NULL;
gint s_height, s_width, d_height, d_width, height, width;
+ cairo_matrix_t *matrix;
GdkGC *gc;
+ cairo_operator_t tmp_op;
src = (struct graphics2d *)NSA_GET_G2D_PTR (env, other);
dst = (struct graphics2d *)NSA_GET_G2D_PTR (env, self);
@@ -386,19 +389,33 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_gdkDrawDrawable
gdk_drawable_get_size (src->drawable, &s_width, &s_height);
gdk_drawable_get_size (dst->drawable, &d_width, &d_height);
width = min (s_width, d_width);
- height = min (s_width, d_height);
+ height = min (s_height, d_height);
+ gdk_threads_leave ();
- gc = gdk_gc_new (dst->drawable);
- g_assert (gc != NULL);
+ begin_drawing_operation(dst);
- gdk_draw_drawable(dst->drawable, gc, src->drawable,
- 0, 0, x, y, width, height);
- gdk_flush ();
+ matrix = cairo_matrix_create ();
+ cairo_surface_get_matrix (src->surface, matrix);
+ cairo_matrix_translate (matrix, (double)-x, (double)-y);
+ cairo_surface_set_matrix (src->surface, matrix);
- g_object_unref (gc);
+ tmp_op = cairo_current_operator (dst->cr);
+ cairo_set_operator(dst->cr, CAIRO_OPERATOR_SRC);
+ cairo_show_surface (dst->cr, src->surface, width, height);
+ cairo_set_operator(dst->cr, tmp_op);
- if (src->debug) printf ("copied %d x %d pixels from offscreen drawable\n", width, height);
+ cairo_matrix_translate (matrix, (double)x, (double)y);
+ cairo_surface_set_matrix (src->surface, matrix);
+ cairo_matrix_destroy (matrix);
+
+ end_drawing_operation(dst);
+
+ gdk_threads_enter ();
+ gdk_flush ();
gdk_threads_leave ();
+
+ if (src->debug) printf ("copied %d x %d pixels from offscreen drawable\n", width, height);
+
}
static jintArray
@@ -1215,7 +1232,8 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClip
gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
g_assert (gr != NULL);
if (gr->debug) printf ("cairo_clip\n");
- cairo_clip (gr->cr);
+ cairo_init_clip (gr->cr);
+ cairo_clip (gr->cr);
}
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSurfaceSetFilter
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c
new file mode 100644
index 00000000000..f88e2e8bcc3
--- /dev/null
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c
@@ -0,0 +1,75 @@
+/* gtkcheckboxgrouppeer.c -- Native implementation of GtkCheckboxGroupPeer
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.h"
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer_dispose
+ (JNIEnv *env, jobject obj)
+{
+ /* The actual underlying widget is owned by a different class. So
+ we just clean up the hash table here. */
+ NSA_DEL_PTR (env, obj);
+}
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer_remove
+ (JNIEnv *env, jobject obj, jobject checkbox)
+{
+ GtkRadioButton *button;
+ void *ptr;
+ GSList *list;
+
+ ptr = NSA_GET_PTR (env, checkbox);
+ gdk_threads_enter ();
+ button = GTK_RADIO_BUTTON (ptr);
+
+ /* Update the group to point to some other widget in the group. We
+ have to do this because Gtk doesn't have a separate object to
+ represent a radio button's group. */
+ for (list = gtk_radio_button_group (button); list != NULL;
+ list = list->next)
+ {
+ if (list->data != button)
+ break;
+ }
+
+ gdk_threads_leave ();
+
+ NSA_SET_PTR (env, obj, list ? list->data : NULL);
+}
+
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c
index 71600c082ca..153b17fe333 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c
@@ -37,7 +37,7 @@ exception statement from your version. */
#include "gtkpeer.h"
-#include "gnu_java_awt_peer_gtk_GtkMenuItemPeer.h"
+#include "gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.h"
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer_create
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c
index b0582cbe57b..b4654bb2e29 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c
@@ -1,5 +1,5 @@
/* gtkcheckboxpeer.c -- Native implementation of GtkCheckboxPeer
- Copyright (C) 1998, 1999, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -42,40 +42,6 @@ exception statement from your version. */
static void item_toggled (GtkToggleButton *item, jobject peer);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer_dispose
- (JNIEnv *env, jobject obj)
-{
- /* The actual underlying widget is owned by a different class. So
- we just clean up the hash table here. */
- NSA_DEL_PTR (env, obj);
-}
-
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer_remove
- (JNIEnv *env, jobject obj, jobject checkbox)
-{
- GtkRadioButton *button;
- void *ptr;
- GSList *list;
-
- ptr = NSA_GET_PTR (env, checkbox);
- gdk_threads_enter ();
- button = GTK_RADIO_BUTTON (ptr);
-
- /* Update the group to point to some other widget in the group. We
- have to do this because Gtk doesn't have a separate object to
- represent a radio button's group. */
- for (list = gtk_radio_button_group (button); list != NULL;
- list = list->next)
- {
- if (list->data != button)
- break;
- }
-
- gdk_threads_leave ();
-
- NSA_SET_PTR (env, obj, list ? list->data : NULL);
-}
-
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkCheckboxPeer_nativeCreate
(JNIEnv *env, jobject obj, jobject group, jboolean state)
@@ -230,7 +196,6 @@ Java_gnu_java_awt_peer_gtk_GtkCheckboxPeer_gtkSetLabel
static void
item_toggled (GtkToggleButton *item, jobject peer)
{
- //g_print ("toggled\n");
(*gdk_env)->CallVoidMethod (gdk_env, peer,
postItemEventID,
peer,
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c
index cc586a022d2..9b262d33d7d 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c
@@ -249,9 +249,10 @@ static void
item_activate (GtkItem *item __attribute__((unused)),
struct item_event_hook_info *ie)
{
+ jstring label;
gdk_threads_leave ();
- jstring label = (*gdk_env)->NewStringUTF (gdk_env, ie->label);
+ label = (*gdk_env)->NewStringUTF (gdk_env, ie->label);
(*gdk_env)->CallVoidMethod (gdk_env, ie->peer_obj,
choicePostItemEventID,
label,
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
index 3bb957c92ac..fecaff48243 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
@@ -1,5 +1,5 @@
/* gtkcomponentpeer.c -- Native implementation of GtkComponentPeer
- Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -43,24 +43,6 @@ exception statement from your version. */
static GtkWidget *find_fg_color_widget (GtkWidget *widget);
static GtkWidget *find_bg_color_widget (GtkWidget *widget);
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkGenericPeer_dispose
- (JNIEnv *env, jobject obj)
-{
- void *ptr;
-
- /* Remove entries from state tables */
- NSA_DEL_GLOBAL_REF (env, obj);
- ptr = NSA_DEL_PTR (env, obj);
-
- gdk_threads_enter ();
-
- /* For now the native state for any object must be a widget.
- However, a subclass could override dispose() if required. */
- gtk_widget_destroy (GTK_WIDGET (ptr));
-
- gdk_threads_leave ();
-}
-
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetCursor
(JNIEnv *env, jobject obj, jint type)
@@ -128,18 +110,6 @@ Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetCursor
gdk_threads_leave ();
}
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_requestFocus
- (JNIEnv *env, jobject obj)
-{
- void *ptr;
-
- ptr = NSA_GET_PTR (env, obj);
-
- gdk_threads_enter ();
- gtk_widget_grab_focus (GTK_WIDGET (ptr));
- gdk_threads_leave ();
-}
-
/*
* Find the origin of a widget's window.
*/
@@ -234,19 +204,6 @@ Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetGetPreferredDimensions
(*env)->ReleaseIntArrayElements (env, jdims, dims, 0);
}
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetUsize (JNIEnv *env,
- jobject obj, jint w, jint h)
-{
- void *ptr;
-
- ptr = NSA_GET_PTR (env, obj);
-
- gdk_threads_enter ();
- gtk_widget_set_usize (GTK_WIDGET (ptr), w, h);
- gdk_threads_leave ();
-}
-
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_setNativeBounds
(JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
{
@@ -386,7 +343,6 @@ Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkSetFont
{
const char *font_name;
void *ptr;
- GtkWidget *label;
PangoFontDescription *font_desc;
ptr = NSA_GET_PTR (env, obj);
@@ -611,10 +567,12 @@ Java_gnu_java_awt_peer_gtk_GtkComponentPeer_set__Ljava_lang_String_2Ljava_lang_O
gboolean
filter_expose_event_handler (GtkWidget *widget, GdkEvent *event, jobject peer)
{
- // Prevent the default event handler from getting this signal if applicable
- // FIXME: I came up with these filters by looking for patterns in the unwanted
- // expose events that are fed back to us from gtk/X. Perhaps there is
- // a way to prevent them from occuring in the first place.
+ /*
+ * Prevent the default event handler from getting this signal if applicable
+ * FIXME: I came up with these filters by looking for patterns in the unwanted
+ * expose events that are fed back to us from gtk/X. Perhaps there is
+ * a way to prevent them from occuring in the first place.
+ */
if (event->type == GDK_EXPOSE && (!GTK_IS_LAYOUT(widget)
|| event->any.window != widget->window))
{
@@ -623,8 +581,8 @@ filter_expose_event_handler (GtkWidget *widget, GdkEvent *event, jobject peer)
}
else
{
- // There may be non-expose events that are triggered while we're
- // painting a heavyweight peer.
+ /* There may be non-expose events that are triggered while we're
+ painting a heavyweight peer. */
return pre_event_handler(widget, event, peer);
}
}
@@ -632,17 +590,18 @@ filter_expose_event_handler (GtkWidget *widget, GdkEvent *event, jobject peer)
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_addExposeFilter
(JNIEnv *env, jobject obj)
{
- void *ptr = NSA_GET_PTR (env, obj);
- jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
- g_assert (gref);
GtkObject *filterobj;
GtkWidget *vbox, *layout;
GList *children;
+ void *ptr = NSA_GET_PTR (env, obj);
+ jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
+
+ g_assert (gref);
gdk_threads_enter ();
- // GtkFramePeer is built as a GtkLayout inside a GtkVBox inside a GtkWindow.
- // Events go to the GtkLayout layer, so we filter them there.
+ /* GtkFramePeer is built as a GtkLayout inside a GtkVBox inside a GtkWindow.
+ Events go to the GtkLayout layer, so we filter them there. */
if (GTK_IS_WINDOW(ptr))
{
children = gtk_container_get_children(GTK_CONTAINER(ptr));
@@ -675,17 +634,18 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_addExposeFilt
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_removeExposeFilter
(JNIEnv *env, jobject obj)
{
- void *ptr = NSA_GET_PTR (env, obj);
- jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
- g_assert (gref);
GtkObject *filterobj;
GtkWidget *vbox, *layout;
GList *children;
+ void *ptr = NSA_GET_PTR (env, obj);
+ jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
+
+ g_assert (gref);
gdk_threads_enter ();
- // GtkFramePeer is built as a GtkLayout inside a GtkVBox inside a GtkWindow.
- // Events go to the GtkLayout layer, so we filter them there.
+ /* GtkFramePeer is built as a GtkLayout inside a GtkVBox inside a GtkWindow.
+ Events go to the GtkLayout layer, so we filter them there. */
if (GTK_IS_WINDOW(ptr))
{
children = gtk_container_get_children(GTK_CONTAINER(ptr));
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c
index 95f73011186..efee7c8f1a2 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c
@@ -1,5 +1,5 @@
/* gtkevents.c -- GDK/GTK event handlers
- Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -934,9 +934,9 @@ pre_event_handler (GtkWidget *widget, GdkEvent *event, jobject peer)
click_count,
JNI_FALSE);
- // Generate an AWT click event only if the release occured in the
- // window it was pressed in, and the mouse has not been dragged since
- // the last time it was pressed.
+ /* Generate an AWT click event only if the release occured in the
+ window it was pressed in, and the mouse has not been dragged since
+ the last time it was pressed. */
gdk_window_get_size (event->any.window, &width, &height);
if (! hasBeenDragged
&& event->button.x >= 0
@@ -1038,11 +1038,11 @@ pre_event_handler (GtkWidget *widget, GdkEvent *event, jobject peer)
break;
case GDK_EXPOSE:
{
- // This filters out unwanted feedback expose events from gtk/X
- // when we explictly invalidate and update heavyweight components,
- // thus avoiding an infinite loop.
- // FIXME: I'm not quite sure why we're getting these expose events.
- // Maybe there is a way to avoid them?
+ /* This filters out unwanted feedback expose events from gtk/X
+ when we explictly invalidate and update heavyweight components,
+ thus avoiding an infinite loop.
+ FIXME: I'm not quite sure why we're getting these expose events.
+ Maybe there is a way to avoid them? */
if((event->any.window == widget->window && event->any.send_event)
|| GTK_IS_LAYOUT(widget))
{
@@ -1181,7 +1181,6 @@ attach_jobject (GdkWindow *window, jobject *obj)
| GDK_KEY_PRESS_MASK
| GDK_FOCUS_CHANGE_MASK);
- // g_print("storing obj %p property on window %p\n", obj, window);
gdk_property_change (window,
addr_atom,
type_atom,
@@ -1196,10 +1195,8 @@ connect_awt_hook (JNIEnv *env, jobject peer_obj, int nwindows, ...)
{
va_list ap;
jobject *obj;
- //void *ptr = NSA_GET_PTR (env, peer_obj);
obj = NSA_GET_GLOBAL_REF (env, peer_obj);
- //g_print("Connection obj %s\n", gtk_widget_get_name (GTK_WIDGET (ptr)));
g_assert (obj);
va_start (ap, nwindows);
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c
index 9e84dde1b6e..92e2de33205 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c
@@ -1,5 +1,5 @@
/* gtkfiledialogpeer.c -- Native implementation of GtkFileDialogPeer
- Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -156,7 +156,7 @@ window_closed (GtkDialog *dialog __attribute__((unused)),
static jmethodID disposeID;
void *ptr;
- // We only need this for the case when the user closed the window
+ /* We only need this for the case when the user closed the window. */
if (responseId != GTK_RESPONSE_DELETE_EVENT)
return;
@@ -186,6 +186,7 @@ ok_clicked (GtkButton *button __attribute__((unused)),
static jmethodID hideID;
void *ptr;
G_CONST_RETURN gchar *fileName;
+ jstring str_fileName;
ptr = NSA_GET_PTR (gdk_env, peer_obj);
@@ -204,7 +205,7 @@ ok_clicked (GtkButton *button __attribute__((unused)),
gdk_threads_leave ();
/* Set the Java object field 'file' with this value. */
- jstring str_fileName = (*gdk_env)->NewStringUTF (gdk_env, fileName);
+ str_fileName = (*gdk_env)->NewStringUTF (gdk_env, fileName);
(*gdk_env)->CallVoidMethod (gdk_env, peer_obj, gtkSetFilenameID, str_fileName);
/* We can hide the dialog now (and unblock show) */
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.c
new file mode 100644
index 00000000000..7b8babeb839
--- /dev/null
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.c
@@ -0,0 +1,59 @@
+/* gtkgenericpeer.c -- Native implementation of GtkGenericPeer
+ Copyright (C) 1998, 1999, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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 2, or (at your option)
+any later version.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkGenericPeer.h"
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkGenericPeer_dispose
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+
+ /* Remove entries from state tables */
+ NSA_DEL_GLOBAL_REF (env, obj);
+ ptr = NSA_DEL_PTR (env, obj);
+
+ gdk_threads_enter ();
+
+ /* For now the native state for any object must be a widget.
+ However, a subclass could override dispose() if required. */
+ gtk_widget_destroy (GTK_WIDGET (ptr));
+
+ gdk_threads_leave ();
+}
+
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c
index ac6f389f8d8..87ecafce991 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c
@@ -1,5 +1,5 @@
/* gtklistpeer.c -- Native implementation of GtkListPeer
- Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -324,7 +324,6 @@ item_select (GtkCList *list __attribute__((unused)),
GdkEventButton *event __attribute__((unused)),
jobject peer_obj)
{
- //g_print ("select_row\n");
(*gdk_env)->CallVoidMethod (gdk_env, peer_obj,
postListItemEventID,
row,
@@ -338,7 +337,6 @@ item_unselect (GtkCList *list __attribute__((unused)),
GdkEventButton *event __attribute__((unused)),
jobject peer_obj)
{
- //g_print ("unselect_row\n");
(*gdk_env)->CallVoidMethod (gdk_env, peer_obj,
postListItemEventID,
row,
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c
index 48509a5d341..8034f647300 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c
@@ -66,7 +66,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuBarPeer_addMenu
menu = NSA_GET_PTR (env, menupeer);
gdk_threads_enter ();
- gtk_menu_bar_append (GTK_MENU_BAR (mbar), GTK_WIDGET (menu));
+ gtk_menu_shell_append (GTK_MENU_SHELL (mbar), GTK_WIDGET (menu));
gdk_threads_leave ();
}
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c
index 4984760f917..70fc8095519 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c
@@ -41,18 +41,16 @@ exception statement from your version. */
#include "gnu_java_awt_peer_gtk_GtkComponentPeer.h"
static void item_activate (GtkMenuItem *item __attribute__((unused)),
- jobject *peer_obj);
+ jobject peer_obj);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_create
(JNIEnv *env, jobject obj, jstring label)
{
GtkWidget *widget;
const char *str;
- jobject *gref;
/* Create global reference and save it for future use */
NSA_SET_GLOBAL_REF (env, obj);
- gref = NSA_GET_GLOBAL_REF (env, obj);
str = (*env)->GetStringUTFChars (env, label, NULL);
@@ -63,10 +61,6 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_create
else
widget = gtk_menu_item_new_with_label (str);
- /* Connect activate hook */
- g_signal_connect (G_OBJECT (widget), "activate",
- GTK_SIGNAL_FUNC (item_activate), *gref);
-
gtk_widget_show (widget);
gdk_threads_leave ();
@@ -76,6 +70,22 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_create
NSA_SET_PTR (env, obj, widget);
}
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_connectSignals
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr = NSA_GET_PTR (env, obj);
+ jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
+ g_assert (gref);
+
+ gdk_threads_enter ();
+
+ g_signal_connect (G_OBJECT (ptr), "activate",
+ G_CALLBACK (item_activate), *gref);
+
+ gdk_threads_leave ();
+}
+
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_setLabel
(JNIEnv *env, jobject obj, jstring label)
{
@@ -104,9 +114,9 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_setLabel
}
static void
-item_activate (GtkMenuItem *item __attribute__((unused)), jobject *peer_obj)
+item_activate (GtkMenuItem *item __attribute__((unused)), jobject peer_obj)
{
- (*gdk_env)->CallVoidMethod (gdk_env, *peer_obj,
+ (*gdk_env)->CallVoidMethod (gdk_env, peer_obj,
postMenuActionEventID);
}
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c
index 63e6a740158..e6a8851fcf2 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c
@@ -1,5 +1,5 @@
/* gtkmenupeer.c -- Native implementation of GtkMenuPeer
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -89,7 +89,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuPeer_setupAccelGroup
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuPeer_create
(JNIEnv *env, jobject obj, jstring label)
{
- GtkWidget *menu_title, *menu;
+ GtkWidget *menu_title, *menu, *toplevel;
const char *str;
/* Create global reference and save it for future use */
@@ -101,10 +101,21 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuPeer_create
menu = gtk_menu_new ();
- menu_title = gtk_menu_item_new_with_label (str);
+ if (str != NULL)
+ menu_title = gtk_menu_item_new_with_label (str);
+ else
+ menu_title = gtk_menu_item_new();
+
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_title), menu);
- gtk_widget_show (menu);
+ /* Allow this menu to grab the pointer. */
+ toplevel = gtk_widget_get_toplevel (menu);
+ if (GTK_IS_WINDOW (toplevel))
+ {
+ gtk_window_group_add_window (global_gtk_window_group,
+ GTK_WINDOW(toplevel));
+ }
+
gtk_widget_show (menu_title);
NSA_SET_PTR (env, obj, menu_title);
@@ -125,8 +136,8 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuPeer_addItem
gdk_threads_enter ();
- menu = GTK_MENU (GTK_MENU_ITEM (ptr1)->submenu);
- gtk_menu_append (menu, GTK_WIDGET (ptr2));
+ menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(ptr1));
+ gtk_menu_shell_append (GTK_MENU_SHELL(menu), GTK_WIDGET (ptr2));
if (key)
{
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.c
index 62fff4d8afe..ca576437f04 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.c
@@ -58,14 +58,6 @@ Java_gnu_java_awt_peer_gtk_GtkPanelPeer_create
NSA_SET_PTR (env, obj, widget);
}
-typedef struct _GtkLayoutChild GtkLayoutChild;
-
-struct _GtkLayoutChild {
- GtkWidget *widget;
- gint x;
- gint y;
-};
-
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkPanelPeer_connectJObject
(JNIEnv *env, jobject obj)
@@ -80,59 +72,3 @@ Java_gnu_java_awt_peer_gtk_GtkPanelPeer_connectJObject
gdk_threads_leave ();
}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GtkPanelPeer_connectSignals
- (JNIEnv *env, jobject obj)
-{
- void *ptr = NSA_GET_PTR (env, obj);
- jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
- g_assert (gref);
-
- gdk_threads_enter ();
- gtk_widget_realize (GTK_WIDGET (ptr));
-
- /* FIXME: If we don't need this then remove this method. */
-/* g_signal_connect (G_OBJECT (ptr), "size_request", GTK_SIGNAL_FUNC (sr), */
-/* NULL); */
- gdk_threads_leave ();
-
- /* Connect the superclass signals. */
- Java_gnu_java_awt_peer_gtk_GtkComponentPeer_connectSignals (env, obj);
-}
-
-/* FIXME: The following doesn't seem to be used.
- Is not declared as a native function in GtkPanelPeer.java */
-/*
- * Make a new panel.
- */
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GtkPanelPeer_gtkPanelNew
- (JNIEnv *env, jobject obj, jobject parent_obj)
-{
- GtkWidget *layout;
- void *parent;
-
- /* Create global reference and save it for future use */
- NSA_SET_GLOBAL_REF (env, obj);
-
- parent = NSA_GET_PTR (env, parent_obj);
-
- gdk_threads_enter ();
-
- layout = gtk_layout_new (NULL, NULL);
-
- set_parent (layout, GTK_CONTAINER (parent));
-
- gtk_widget_realize (layout);
-
- connect_awt_hook (env, obj, 1, GTK_LAYOUT (layout)->bin_window);
-
- set_visible (layout, 1);
-
- gdk_threads_leave ();
-
- NSA_SET_PTR (env, obj, layout);
-}
-
-
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c
index c5a223037e0..ee12a7f77b1 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c
@@ -1,5 +1,5 @@
/* gtkpopupmenupeer.c -- Native implementation of GtkPopupMenuPeer
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,6 +39,8 @@ exception statement from your version. */
#include "gtkpeer.h"
#include "gnu_java_awt_peer_gtk_GtkPopupMenuPeer.h"
+void menu_pos (GtkMenu *, gint *, gint *, gboolean *, gpointer);
+
struct pos
{
gint x;
@@ -72,7 +74,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkPopupMenuPeer_show
gdk_threads_enter ();
gtk_menu_popup (GTK_MENU (GTK_MENU_ITEM (ptr)->submenu),
- NULL, NULL, menu_pos, p, 3, time);
+ NULL, NULL, menu_pos, p, 0, time);
gdk_threads_leave ();
g_free (p);
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextComponentPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextComponentPeer.c
index 2ec87f012ea..0d7d55562c5 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextComponentPeer.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextComponentPeer.c
@@ -1,5 +1,5 @@
/* gtktextcomponentpeer.c -- Native implementation of GtkTextComponentPeer
- Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -112,8 +112,8 @@ Java_gnu_java_awt_peer_gtk_GtkTextComponentPeer_getCaretPosition
{
void *ptr;
int pos = 0;
- GtkEditable *editable; // type of GtkEntry (TextField)
- GtkWidget *text = NULL; // type of GtkTextView (TextArea)
+ GtkEditable *editable; /* type of GtkEntry (TextField) */
+ GtkWidget *text = NULL; /* type of GtkTextView (TextArea) */
GtkTextBuffer *buf;
GtkTextMark *mark;
GtkTextIter iter;
@@ -157,8 +157,8 @@ Java_gnu_java_awt_peer_gtk_GtkTextComponentPeer_setCaretPosition
(JNIEnv *env, jobject obj, jint pos)
{
void *ptr;
- GtkEditable *editable; // type of GtkEntry (TextField)
- GtkWidget *text = NULL; // type of GtkTextView (TextArea)
+ GtkEditable *editable; /* type of GtkEntry (TextField) */
+ GtkWidget *text = NULL; /* type of GtkTextView (TextArea) */
GtkTextBuffer *buf;
GtkTextIter iter;
@@ -198,8 +198,8 @@ Java_gnu_java_awt_peer_gtk_GtkTextComponentPeer_getSelectionStart
{
void *ptr;
int pos = 0;
- GtkEditable *editable; // type of GtkEntry (TextField)
- GtkWidget *text = NULL; // type of GtkTextView (TextArea)
+ GtkEditable *editable; /* type of GtkEntry (TextField) */
+ GtkWidget *text = NULL; /* type of GtkTextView (TextArea) */
GtkTextBuffer *buf;
GtkTextIter start;
GtkTextIter end;
@@ -255,8 +255,8 @@ Java_gnu_java_awt_peer_gtk_GtkTextComponentPeer_getSelectionEnd
{
void *ptr;
int pos = 0;
- GtkEditable *editable; // type of GtkEntry (TextField)
- GtkWidget *text = NULL; // type of GtkTextView (TextArea)
+ GtkEditable *editable; /* type of GtkEntry (TextField) */
+ GtkWidget *text = NULL; /* type of GtkTextView (TextArea) */
GtkTextBuffer *buf;
GtkTextIter start;
GtkTextIter end;
@@ -311,8 +311,8 @@ Java_gnu_java_awt_peer_gtk_GtkTextComponentPeer_select
(JNIEnv *env, jobject obj, jint start, jint end)
{
void *ptr;
- GtkEditable *editable; // type of GtkEntry (TextField)
- GtkWidget *text = NULL; // type of GtkTextView (TextArea)
+ GtkEditable *editable; /* type of GtkEntry (TextField) */
+ GtkWidget *text = NULL; /* type of GtkTextView (TextArea) */
GtkTextBuffer *buf;
GtkTextIter iter;
@@ -357,8 +357,8 @@ Java_gnu_java_awt_peer_gtk_GtkTextComponentPeer_setEditable
(JNIEnv *env, jobject obj, jboolean state)
{
void *ptr;
- GtkEditable *editable; // type of GtkEntry (TextField)
- GtkWidget *text = NULL; // type of GtkTextView (TextArea)
+ GtkEditable *editable; /* type of GtkEntry (TextField) */
+ GtkWidget *text = NULL; /* type of GtkTextView (TextArea) */
ptr = NSA_GET_PTR (env, obj);
@@ -396,8 +396,8 @@ Java_gnu_java_awt_peer_gtk_GtkTextComponentPeer_getText
void *ptr;
char *contents = NULL;
jstring jcontents;
- GtkEditable *editable; // type of GtkEntry (TextField)
- GtkWidget *text = NULL; // type of GtkTextView (TextArea)
+ GtkEditable *editable; /* type of GtkEntry (TextField) */
+ GtkWidget *text = NULL; /* type of GtkTextView (TextArea) */
GtkTextBuffer *buf;
GtkTextIter start, end;
@@ -444,7 +444,7 @@ Java_gnu_java_awt_peer_gtk_GtkTextComponentPeer_setText
{
void *ptr;
const char *str;
- GtkWidget *text = NULL; // type of GtkTextView (TextArea)
+ GtkWidget *text = NULL; /* type of GtkTextView (TextArea) */
GtkTextBuffer *buf;
ptr = NSA_GET_PTR (env, obj);
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c
index 80d9d5bfb1b..619b48d593a 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c
@@ -284,28 +284,6 @@ Java_gnu_java_awt_peer_gtk_GtkWindowPeer_connectSignals
}
/*
- * Set a frame's title
- */
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GtkWindowPeer_setTitle
- (JNIEnv *env, jobject obj, jstring title)
-{
- void *ptr;
- const char *str;
-
- ptr = NSA_GET_PTR (env, obj);
-
- str = (*env)->GetStringUTFChars (env, title, NULL);
-
- gdk_threads_enter ();
- gtk_window_set_title (GTK_WINDOW (ptr), str);
- gdk_threads_leave ();
-
- (*env)->ReleaseStringUTFChars (env, title, str);
-}
-
-/*
* Lower the z-level of a window.
*/
diff --git a/libjava/jni/gtk-peer/gthread-jni.c b/libjava/jni/gtk-peer/gthread-jni.c
index a762b4e56ed..3dd5596b4bc 100644
--- a/libjava/jni/gtk-peer/gthread-jni.c
+++ b/libjava/jni/gtk-peer/gthread-jni.c
@@ -1,5 +1,5 @@
/* gthread-jni.c -- JNI threading routines for GLIB
- Copyright (C) 1998 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -91,28 +91,40 @@ JavaVM *gdk_vm;
static void maybe_rethrow(JNIEnv *gdk_env, char *message, char *file, int line) {
jthrowable cause;
- /* rethrow if an exception happened */
- if ((cause = (*gdk_env)->ExceptionOccurred(gdk_env)) != NULL) {
jstring jmessage;
- jclass obj_class;
+ jclass obj_class;
jobject obj;
jmethodID ctor;
-
- /* allocate local message in Java */
- int len = strlen(message) + strlen(file) + 25;
- char buf[ len ];
- bzero(buf, len);
- sprintf(buf, "%s (at %s:%d)", message, file, line);
- jmessage = (*gdk_env)->NewStringUTF(gdk_env, buf);
+ int len;
+ char *buf;
+
+ /* rethrow if an exception happened */
+ if ((cause = (*gdk_env)->ExceptionOccurred(gdk_env)) != NULL)
+ {
+
+ /* allocate local message in Java */
+ len = strlen(message) + strlen(file) + 25;
+ buf = (char *) malloc(len);
+ if (buf != NULL)
+ {
+ bzero(buf, len);
+ sprintf(buf, "%s (at %s:%d)", message, file, line);
+ jmessage = (*gdk_env)->NewStringUTF(gdk_env, buf);
+ free(buf);
+ }
+ else
+ jmessage = NULL;
- /* create RuntimeException wrapper object */
- obj_class = (*gdk_env)->FindClass (gdk_env, "java/lang/RuntimeException");
- ctor = (*gdk_env)->GetMethodID(gdk_env, obj_class, "<init>", "(Ljava/langString;Ljava/lang/Throwable)V");
- obj = (*gdk_env)->NewObject (gdk_env, obj_class, ctor, jmessage, cause);
-
- /* throw it */
- (*gdk_env)->Throw(gdk_env, (jthrowable)obj);
- }
+ /* create RuntimeException wrapper object */
+ obj_class = (*gdk_env)->FindClass (gdk_env,
+ "java/lang/RuntimeException");
+ ctor = (*gdk_env)->GetMethodID(gdk_env, obj_class, "<init>",
+ "(Ljava/langString;Ljava/lang/Throwable)V");
+ obj = (*gdk_env)->NewObject (gdk_env, obj_class, ctor, jmessage, cause);
+
+ /* throw it */
+ (*gdk_env)->Throw(gdk_env, (jthrowable)obj);
+ }
}
/* This macro is used to include a source location in the exception message */
@@ -204,7 +216,7 @@ static void g_mutex_lock_jni_impl (GMutex *mutex __attribute__((unused))) {
static gboolean g_mutex_trylock_jni_impl
(GMutex *mutex __attribute__((unused)))
{
- // Shall we implement this in a JikesRVM-specific way under a flag?
+ /* XXX Shall we implement this in a VM-specific way under a flag? */
return FALSE;
}
@@ -493,7 +505,3 @@ GThreadFunctions g_thread_jni_functions =
NULL
};
-/* ??? */
-void gdk_threads_wake () {
-
-}
diff --git a/libjava/libltdl/ChangeLog b/libjava/libltdl/ChangeLog
index 3193f5c1adb..e4134ab8901 100644
--- a/libjava/libltdl/ChangeLog
+++ b/libjava/libltdl/ChangeLog
@@ -1,3 +1,9 @@
+2004-05-03 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * acinclude.m4: Replace -W with more speaking -Wextra.
+ * aclocal.m4: Regenerate.
+ * configure: Regenerate.
+
2004-03-10 Kelley Cook <kcook@gcc.gnu.org>
* configure.ac: Bump AC_PREREQ to 2.59.
diff --git a/libjava/libltdl/acinclude.m4 b/libjava/libltdl/acinclude.m4
index ccb24e63a2f..47312e1bf21 100644
--- a/libjava/libltdl/acinclude.m4
+++ b/libjava/libltdl/acinclude.m4
@@ -4643,7 +4643,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
mvs*)
case $cc_basename in
cxx)
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Wextra c,exportall'
;;
*)
;;
diff --git a/libjava/libltdl/aclocal.m4 b/libjava/libltdl/aclocal.m4
index 31d8fbb6d42..ffc19a78403 100644
--- a/libjava/libltdl/aclocal.m4
+++ b/libjava/libltdl/aclocal.m4
@@ -4622,7 +4622,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
mvs*)
case $cc_basename in
cxx)
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Wextra c,exportall'
;;
*)
;;
diff --git a/libjava/libltdl/configure b/libjava/libltdl/configure
index 84b834dc09f..cbe58d2532a 100755
--- a/libjava/libltdl/configure
+++ b/libjava/libltdl/configure
@@ -11255,7 +11255,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
mvs*)
case $cc_basename in
cxx)
- lt_prog_compiler_pic_CXX='-W c,exportall'
+ lt_prog_compiler_pic_CXX='-Wextra c,exportall'
;;
*)
;;
diff --git a/libjava/link.cc b/libjava/link.cc
new file mode 100644
index 00000000000..3f2ab5b6a60
--- /dev/null
+++ b/libjava/link.cc
@@ -0,0 +1,1654 @@
+// resolve.cc - Code for linking and resolving classes and pool entries.
+
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+/* Author: Kresten Krab Thorup <krab@gnu.org> */
+
+#include <config.h>
+#include <platform.h>
+
+#include <java-interp.h>
+
+#include <jvm.h>
+#include <gcj/cni.h>
+#include <string.h>
+#include <java-cpool.h>
+#include <execution.h>
+#include <java/lang/Class.h>
+#include <java/lang/String.h>
+#include <java/lang/StringBuffer.h>
+#include <java/lang/Thread.h>
+#include <java/lang/InternalError.h>
+#include <java/lang/VirtualMachineError.h>
+#include <java/lang/VerifyError.h>
+#include <java/lang/NoSuchFieldError.h>
+#include <java/lang/NoSuchMethodError.h>
+#include <java/lang/ClassFormatError.h>
+#include <java/lang/IllegalAccessError.h>
+#include <java/lang/AbstractMethodError.h>
+#include <java/lang/NoClassDefFoundError.h>
+#include <java/lang/IncompatibleClassChangeError.h>
+#include <java/lang/VMClassLoader.h>
+#include <java/lang/reflect/Modifier.h>
+
+using namespace gcj;
+
+typedef unsigned int uaddr __attribute__ ((mode (pointer)));
+
+template<typename T>
+struct aligner
+{
+ char c;
+ T field;
+};
+
+#define ALIGNOF(TYPE) (offsetof (aligner<TYPE>, field))
+
+// This returns the alignment of a type as it would appear in a
+// structure. This can be different from the alignment of the type
+// itself. For instance on x86 double is 8-aligned but struct{double}
+// is 4-aligned.
+int
+_Jv_Linker::get_alignment_from_class (jclass klass)
+{
+ if (klass == JvPrimClass (byte))
+ return ALIGNOF (jbyte);
+ else if (klass == JvPrimClass (short))
+ return ALIGNOF (jshort);
+ else if (klass == JvPrimClass (int))
+ return ALIGNOF (jint);
+ else if (klass == JvPrimClass (long))
+ return ALIGNOF (jlong);
+ else if (klass == JvPrimClass (boolean))
+ return ALIGNOF (jboolean);
+ else if (klass == JvPrimClass (char))
+ return ALIGNOF (jchar);
+ else if (klass == JvPrimClass (float))
+ return ALIGNOF (jfloat);
+ else if (klass == JvPrimClass (double))
+ return ALIGNOF (jdouble);
+ else
+ return ALIGNOF (jobject);
+}
+
+void
+_Jv_Linker::resolve_field (_Jv_Field *field, java::lang::ClassLoader *loader)
+{
+ if (! field->isResolved ())
+ {
+ _Jv_Utf8Const *sig = (_Jv_Utf8Const*)field->type;
+ field->type = _Jv_FindClassFromSignature (sig->data, loader);
+ field->flags &= ~_Jv_FIELD_UNRESOLVED_FLAG;
+ }
+}
+
+_Jv_word
+_Jv_Linker::resolve_pool_entry (jclass klass, int index)
+{
+ using namespace java::lang::reflect;
+
+ _Jv_Constants *pool = &klass->constants;
+
+ if ((pool->tags[index] & JV_CONSTANT_ResolvedFlag) != 0)
+ return pool->data[index];
+
+ switch (pool->tags[index])
+ {
+ case JV_CONSTANT_Class:
+ {
+ _Jv_Utf8Const *name = pool->data[index].utf8;
+
+ jclass found;
+ if (name->data[0] == '[')
+ found = _Jv_FindClassFromSignature (&name->data[0],
+ klass->loader);
+ else
+ found = _Jv_FindClass (name, klass->loader);
+
+ if (! found)
+ {
+ jstring str = _Jv_NewStringUTF (name->data);
+ // This exception is specified in JLS 2nd Ed, section 5.1.
+ throw new java::lang::NoClassDefFoundError (str);
+ }
+
+ // Check accessibility, but first strip array types as
+ // _Jv_ClassNameSamePackage can't handle arrays.
+ jclass check;
+ for (check = found;
+ check && check->isArray();
+ check = check->getComponentType())
+ ;
+ if ((found->accflags & Modifier::PUBLIC) == Modifier::PUBLIC
+ || (_Jv_ClassNameSamePackage (check->name,
+ klass->name)))
+ {
+ pool->data[index].clazz = found;
+ pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
+ }
+ else
+ throw new java::lang::IllegalAccessError (found->getName());
+ }
+ break;
+
+ case JV_CONSTANT_String:
+ {
+ jstring str;
+ str = _Jv_NewStringUtf8Const (pool->data[index].utf8);
+ pool->data[index].o = str;
+ pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
+ }
+ break;
+
+ case JV_CONSTANT_Fieldref:
+ {
+ _Jv_ushort class_index, name_and_type_index;
+ _Jv_loadIndexes (&pool->data[index],
+ class_index,
+ name_and_type_index);
+ jclass owner = (resolve_pool_entry (klass, class_index)).clazz;
+
+ if (owner != klass)
+ _Jv_InitClass (owner);
+
+ _Jv_ushort name_index, type_index;
+ _Jv_loadIndexes (&pool->data[name_and_type_index],
+ name_index,
+ type_index);
+
+ _Jv_Utf8Const *field_name = pool->data[name_index].utf8;
+ _Jv_Utf8Const *field_type_name = pool->data[type_index].utf8;
+
+ // FIXME: The implementation of this function
+ // (_Jv_FindClassFromSignature) will generate an instance of
+ // _Jv_Utf8Const for each call if the field type is a class name
+ // (Lxx.yy.Z;). This may be too expensive to do for each and
+ // every fieldref being resolved. For now, we fix the problem by
+ // only doing it when we have a loader different from the class
+ // declaring the field.
+
+ jclass field_type = 0;
+
+ if (owner->loader != klass->loader)
+ field_type = _Jv_FindClassFromSignature (field_type_name->data,
+ klass->loader);
+
+ _Jv_Field* the_field = 0;
+
+ for (jclass cls = owner; cls != 0; cls = cls->getSuperclass ())
+ {
+ for (int i = 0; i < cls->field_count; i++)
+ {
+ _Jv_Field *field = &cls->fields[i];
+ if (! _Jv_equalUtf8Consts (field->name, field_name))
+ continue;
+
+ if (_Jv_CheckAccess (klass, cls, field->flags))
+ {
+ // Resolve the field using the class' own loader if
+ // necessary.
+
+ if (!field->isResolved ())
+ resolve_field (field, cls->loader);
+
+ if (field_type != 0 && field->type != field_type)
+ throw new java::lang::LinkageError
+ (JvNewStringLatin1
+ ("field type mismatch with different loaders"));
+
+ the_field = field;
+ goto end_of_field_search;
+ }
+ else
+ {
+ java::lang::StringBuffer *sb
+ = new java::lang::StringBuffer ();
+ sb->append(klass->getName());
+ sb->append(JvNewStringLatin1(": "));
+ sb->append(cls->getName());
+ sb->append(JvNewStringLatin1("."));
+ sb->append(_Jv_NewStringUtf8Const (field_name));
+ throw new java::lang::IllegalAccessError(sb->toString());
+ }
+ }
+ }
+
+ end_of_field_search:
+ if (the_field == 0)
+ {
+ java::lang::StringBuffer *sb = new java::lang::StringBuffer();
+ sb->append(JvNewStringLatin1("field "));
+ sb->append(owner->getName());
+ sb->append(JvNewStringLatin1("."));
+ sb->append(_Jv_NewStringUTF(field_name->data));
+ sb->append(JvNewStringLatin1(" was not found."));
+ throw
+ new java::lang::IncompatibleClassChangeError (sb->toString());
+ }
+
+ pool->data[index].field = the_field;
+ pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
+ }
+ break;
+
+ case JV_CONSTANT_Methodref:
+ case JV_CONSTANT_InterfaceMethodref:
+ {
+ _Jv_ushort class_index, name_and_type_index;
+ _Jv_loadIndexes (&pool->data[index],
+ class_index,
+ name_and_type_index);
+ jclass owner = (resolve_pool_entry (klass, class_index)).clazz;
+
+ if (owner != klass)
+ _Jv_InitClass (owner);
+
+ _Jv_ushort name_index, type_index;
+ _Jv_loadIndexes (&pool->data[name_and_type_index],
+ name_index,
+ type_index);
+
+ _Jv_Utf8Const *method_name = pool->data[name_index].utf8;
+ _Jv_Utf8Const *method_signature = pool->data[type_index].utf8;
+
+ _Jv_Method *the_method = 0;
+ jclass found_class = 0;
+
+ // First search the class itself.
+ the_method = _Jv_SearchMethodInClass (owner, klass,
+ method_name, method_signature);
+
+ if (the_method != 0)
+ {
+ found_class = owner;
+ goto end_of_method_search;
+ }
+
+ // If we are resolving an interface method, search the
+ // interface's superinterfaces (A superinterface is not an
+ // interface's superclass - a superinterface is implemented by
+ // the interface).
+ if (pool->tags[index] == JV_CONSTANT_InterfaceMethodref)
+ {
+ _Jv_ifaces ifaces;
+ ifaces.count = 0;
+ ifaces.len = 4;
+ ifaces.list = (jclass *) _Jv_Malloc (ifaces.len
+ * sizeof (jclass *));
+
+ get_interfaces (owner, &ifaces);
+
+ for (int i = 0; i < ifaces.count; i++)
+ {
+ jclass cls = ifaces.list[i];
+ the_method = _Jv_SearchMethodInClass (cls, klass, method_name,
+ method_signature);
+ if (the_method != 0)
+ {
+ found_class = cls;
+ break;
+ }
+ }
+
+ _Jv_Free (ifaces.list);
+
+ if (the_method != 0)
+ goto end_of_method_search;
+ }
+
+ // Finally, search superclasses.
+ for (jclass cls = owner->getSuperclass (); cls != 0;
+ cls = cls->getSuperclass ())
+ {
+ the_method = _Jv_SearchMethodInClass (cls, klass, method_name,
+ method_signature);
+ if (the_method != 0)
+ {
+ found_class = cls;
+ break;
+ }
+ }
+
+ end_of_method_search:
+
+ // FIXME: if (cls->loader != klass->loader), then we
+ // must actually check that the types of arguments
+ // correspond. That is, for each argument type, and
+ // the return type, doing _Jv_FindClassFromSignature
+ // with either loader should produce the same result,
+ // i.e., exactly the same jclass object. JVMS 5.4.3.3
+
+ if (the_method == 0)
+ {
+ java::lang::StringBuffer *sb = new java::lang::StringBuffer();
+ sb->append(JvNewStringLatin1("method "));
+ sb->append(owner->getName());
+ sb->append(JvNewStringLatin1("."));
+ sb->append(_Jv_NewStringUTF(method_name->data));
+ sb->append(JvNewStringLatin1(" with signature "));
+ sb->append(_Jv_NewStringUTF(method_signature->data));
+ sb->append(JvNewStringLatin1(" was not found."));
+ throw new java::lang::NoSuchMethodError (sb->toString());
+ }
+
+ int vtable_index = -1;
+ if (pool->tags[index] != JV_CONSTANT_InterfaceMethodref)
+ vtable_index = (jshort)the_method->index;
+
+ pool->data[index].rmethod
+ = klass->engine->resolve_method(the_method,
+ found_class,
+ ((the_method->accflags
+ & Modifier::STATIC) != 0),
+ vtable_index);
+ pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
+ }
+ break;
+ }
+ return pool->data[index];
+}
+
+// This function is used to lazily locate superclasses and
+// superinterfaces. This must be called with the class lock held.
+void
+_Jv_Linker::resolve_class_ref (jclass klass, jclass *classref)
+{
+ jclass ret = *classref;
+
+ // If superclass looks like a constant pool entry, resolve it now.
+ if (ret && (uaddr) ret < (uaddr) klass->constants.size)
+ {
+ if (klass->state < JV_STATE_LINKED)
+ {
+ _Jv_Utf8Const *name = klass->constants.data[(uaddr) *classref].utf8;
+ ret = _Jv_FindClass (name, klass->loader);
+ if (! ret)
+ {
+ jstring str = _Jv_NewStringUTF (name->data);
+ throw new java::lang::NoClassDefFoundError (str);
+ }
+ }
+ else
+ ret = klass->constants.data[(uaddr) classref].clazz;
+ *classref = ret;
+ }
+}
+
+// Find a method declared in the cls that is referenced from klass and
+// perform access checks.
+_Jv_Method *
+_Jv_SearchMethodInClass (jclass cls, jclass klass,
+ _Jv_Utf8Const *method_name,
+ _Jv_Utf8Const *method_signature)
+{
+ using namespace java::lang::reflect;
+
+ for (int i = 0; i < cls->method_count; i++)
+ {
+ _Jv_Method *method = &cls->methods[i];
+ if ( (!_Jv_equalUtf8Consts (method->name,
+ method_name))
+ || (!_Jv_equalUtf8Consts (method->signature,
+ method_signature)))
+ continue;
+
+ if (_Jv_CheckAccess (klass, cls, method->accflags))
+ return method;
+ else
+ {
+ java::lang::StringBuffer *sb = new java::lang::StringBuffer();
+ sb->append(klass->getName());
+ sb->append(JvNewStringLatin1(": "));
+ sb->append(cls->getName());
+ sb->append(JvNewStringLatin1("."));
+ sb->append(_Jv_NewStringUTF(method_name->data));
+ sb->append(_Jv_NewStringUTF(method_signature->data));
+ throw new java::lang::IllegalAccessError (sb->toString());
+ }
+ }
+ return 0;
+}
+
+
+#define INITIAL_IOFFSETS_LEN 4
+#define INITIAL_IFACES_LEN 4
+
+static _Jv_IDispatchTable null_idt = { {SHRT_MAX, 0, NULL} };
+
+// Generate tables for constant-time assignment testing and interface
+// method lookup. This implements the technique described by Per Bothner
+// <per@bothner.com> on the java-discuss mailing list on 1999-09-02:
+// http://gcc.gnu.org/ml/java/1999-q3/msg00377.html
+void
+_Jv_Linker::prepare_constant_time_tables (jclass klass)
+{
+ if (klass->isPrimitive () || klass->isInterface ())
+ return;
+
+ // Short-circuit in case we've been called already.
+ if ((klass->idt != NULL) || klass->depth != 0)
+ return;
+
+ // Calculate the class depth and ancestor table. The depth of a class
+ // is how many "extends" it is removed from Object. Thus the depth of
+ // java.lang.Object is 0, but the depth of java.io.FilterOutputStream
+ // is 2. Depth is defined for all regular and array classes, but not
+ // interfaces or primitive types.
+
+ jclass klass0 = klass;
+ jboolean has_interfaces = 0;
+ while (klass0 != &java::lang::Object::class$)
+ {
+ has_interfaces += klass0->interface_count;
+ klass0 = klass0->superclass;
+ klass->depth++;
+ }
+
+ // We do class member testing in constant time by using a small table
+ // of all the ancestor classes within each class. The first element is
+ // a pointer to the current class, and the rest are pointers to the
+ // classes ancestors, ordered from the current class down by decreasing
+ // depth. We do not include java.lang.Object in the table of ancestors,
+ // since it is redundant.
+
+ // FIXME: _Jv_AllocBytes
+ klass->ancestors = (jclass *) _Jv_Malloc (klass->depth
+ * sizeof (jclass));
+ klass0 = klass;
+ for (int index = 0; index < klass->depth; index++)
+ {
+ klass->ancestors[index] = klass0;
+ klass0 = klass0->superclass;
+ }
+
+ if ((klass->accflags & java::lang::reflect::Modifier::ABSTRACT) != 0)
+ return;
+
+ // Optimization: If class implements no interfaces, use a common
+ // predefined interface table.
+ if (!has_interfaces)
+ {
+ klass->idt = &null_idt;
+ return;
+ }
+
+ // FIXME: _Jv_AllocBytes
+ klass->idt =
+ (_Jv_IDispatchTable *) _Jv_Malloc (sizeof (_Jv_IDispatchTable));
+
+ _Jv_ifaces ifaces;
+ ifaces.count = 0;
+ ifaces.len = INITIAL_IFACES_LEN;
+ ifaces.list = (jclass *) _Jv_Malloc (ifaces.len * sizeof (jclass *));
+
+ int itable_size = get_interfaces (klass, &ifaces);
+
+ if (ifaces.count > 0)
+ {
+ klass->idt->cls.itable =
+ // FIXME: _Jv_AllocBytes
+ (void **) _Jv_Malloc (itable_size * sizeof (void *));
+ klass->idt->cls.itable_length = itable_size;
+
+ jshort *itable_offsets =
+ (jshort *) _Jv_Malloc (ifaces.count * sizeof (jshort));
+
+ generate_itable (klass, &ifaces, itable_offsets);
+
+ jshort cls_iindex = find_iindex (ifaces.list, itable_offsets,
+ ifaces.count);
+
+ for (int i = 0; i < ifaces.count; i++)
+ {
+ ifaces.list[i]->idt->iface.ioffsets[cls_iindex] =
+ itable_offsets[i];
+ }
+
+ klass->idt->cls.iindex = cls_iindex;
+
+ _Jv_Free (ifaces.list);
+ _Jv_Free (itable_offsets);
+ }
+ else
+ {
+ klass->idt->cls.iindex = SHRT_MAX;
+ }
+}
+
+// Return index of item in list, or -1 if item is not present.
+inline jshort
+_Jv_Linker::indexof (void *item, void **list, jshort list_len)
+{
+ for (int i=0; i < list_len; i++)
+ {
+ if (list[i] == item)
+ return i;
+ }
+ return -1;
+}
+
+// Find all unique interfaces directly or indirectly implemented by klass.
+// Returns the size of the interface dispatch table (itable) for klass, which
+// is the number of unique interfaces plus the total number of methods that
+// those interfaces declare. May extend ifaces if required.
+jshort
+_Jv_Linker::get_interfaces (jclass klass, _Jv_ifaces *ifaces)
+{
+ jshort result = 0;
+
+ for (int i = 0; i < klass->interface_count; i++)
+ {
+ jclass iface = klass->interfaces[i];
+
+ /* Make sure interface is linked. */
+ wait_for_state(iface, JV_STATE_LINKED);
+
+ if (indexof (iface, (void **) ifaces->list, ifaces->count) == -1)
+ {
+ if (ifaces->count + 1 >= ifaces->len)
+ {
+ /* Resize ifaces list */
+ ifaces->len = ifaces->len * 2;
+ ifaces->list
+ = (jclass *) _Jv_Realloc (ifaces->list,
+ ifaces->len * sizeof(jclass));
+ }
+ ifaces->list[ifaces->count] = iface;
+ ifaces->count++;
+
+ result += get_interfaces (klass->interfaces[i], ifaces);
+ }
+ }
+
+ if (klass->isInterface())
+ result += klass->method_count + 1;
+ else if (klass->superclass)
+ result += get_interfaces (klass->superclass, ifaces);
+ return result;
+}
+
+// Fill out itable in klass, resolving method declarations in each ifaces.
+// itable_offsets is filled out with the position of each iface in itable,
+// such that itable[itable_offsets[n]] == ifaces.list[n].
+void
+_Jv_Linker::generate_itable (jclass klass, _Jv_ifaces *ifaces,
+ jshort *itable_offsets)
+{
+ void **itable = klass->idt->cls.itable;
+ jshort itable_pos = 0;
+
+ for (int i = 0; i < ifaces->count; i++)
+ {
+ jclass iface = ifaces->list[i];
+ itable_offsets[i] = itable_pos;
+ itable_pos = append_partial_itable (klass, iface, itable, itable_pos);
+
+ /* Create interface dispatch table for iface */
+ if (iface->idt == NULL)
+ {
+ // FIXME: _Jv_AllocBytes
+ iface->idt
+ = (_Jv_IDispatchTable *) _Jv_Malloc (sizeof (_Jv_IDispatchTable));
+
+ // The first element of ioffsets is its length (itself included).
+ // FIXME: _Jv_AllocBytes
+ jshort *ioffsets = (jshort *) _Jv_Malloc (INITIAL_IOFFSETS_LEN
+ * sizeof (jshort));
+ ioffsets[0] = INITIAL_IOFFSETS_LEN;
+ for (int i = 1; i < INITIAL_IOFFSETS_LEN; i++)
+ ioffsets[i] = -1;
+
+ iface->idt->iface.ioffsets = ioffsets;
+ }
+ }
+}
+
+// Format method name for use in error messages.
+jstring
+_Jv_GetMethodString (jclass klass, _Jv_Utf8Const *name)
+{
+ jstring r = JvNewStringUTF (klass->name->data);
+ r = r->concat (JvNewStringUTF ("."));
+ r = r->concat (JvNewStringUTF (name->data));
+ return r;
+}
+
+void
+_Jv_ThrowNoSuchMethodError ()
+{
+ throw new java::lang::NoSuchMethodError;
+}
+
+// Each superinterface of a class (i.e. each interface that the class
+// directly or indirectly implements) has a corresponding "Partial
+// Interface Dispatch Table" whose size is (number of methods + 1) words.
+// The first word is a pointer to the interface (i.e. the java.lang.Class
+// instance for that interface). The remaining words are pointers to the
+// actual methods that implement the methods declared in the interface,
+// in order of declaration.
+//
+// Append partial interface dispatch table for "iface" to "itable", at
+// position itable_pos.
+// Returns the offset at which the next partial ITable should be appended.
+jshort
+_Jv_Linker::append_partial_itable (jclass klass, jclass iface,
+ void **itable, jshort pos)
+{
+ using namespace java::lang::reflect;
+
+ itable[pos++] = (void *) iface;
+ _Jv_Method *meth;
+
+ for (int j=0; j < iface->method_count; j++)
+ {
+ meth = NULL;
+ for (jclass cl = klass; cl; cl = cl->getSuperclass())
+ {
+ meth = _Jv_GetMethodLocal (cl, iface->methods[j].name,
+ iface->methods[j].signature);
+
+ if (meth)
+ break;
+ }
+
+ if (meth && (meth->name->data[0] == '<'))
+ {
+ // leave a placeholder in the itable for hidden init methods.
+ itable[pos] = NULL;
+ }
+ else if (meth)
+ {
+ if ((meth->accflags & Modifier::STATIC) != 0)
+ throw new java::lang::IncompatibleClassChangeError
+ (_Jv_GetMethodString (klass, meth->name));
+ if ((meth->accflags & Modifier::ABSTRACT) != 0)
+ throw new java::lang::AbstractMethodError
+ (_Jv_GetMethodString (klass, meth->name));
+ if ((meth->accflags & Modifier::PUBLIC) == 0)
+ throw new java::lang::IllegalAccessError
+ (_Jv_GetMethodString (klass, meth->name));
+
+ itable[pos] = meth->ncode;
+ }
+ else
+ {
+ // The method doesn't exist in klass. Binary compatibility rules
+ // permit this, so we delay the error until runtime using a pointer
+ // to a method which throws an exception.
+ itable[pos] = (void *) _Jv_ThrowNoSuchMethodError;
+ }
+ pos++;
+ }
+
+ return pos;
+}
+
+static _Jv_Mutex_t iindex_mutex;
+static bool iindex_mutex_initialized = false;
+
+// We need to find the correct offset in the Class Interface Dispatch
+// Table for a given interface. Once we have that, invoking an interface
+// method just requires combining the Method's index in the interface
+// (known at compile time) to get the correct method. Doing a type test
+// (cast or instanceof) is the same problem: Once we have a possible Partial
+// Interface Dispatch Table, we just compare the first element to see if it
+// matches the desired interface. So how can we find the correct offset?
+// Our solution is to keep a vector of candiate offsets in each interface
+// (idt->iface.ioffsets), and in each class we have an index
+// (idt->cls.iindex) used to select the correct offset from ioffsets.
+//
+// Calculate and return iindex for a new class.
+// ifaces is a vector of num interfaces that the class implements.
+// offsets[j] is the offset in the interface dispatch table for the
+// interface corresponding to ifaces[j].
+// May extend the interface ioffsets if required.
+jshort
+_Jv_Linker::find_iindex (jclass *ifaces, jshort *offsets, jshort num)
+{
+ int i;
+ int j;
+
+ // Acquire a global lock to prevent itable corruption in case of multiple
+ // classes that implement an intersecting set of interfaces being linked
+ // simultaneously. We can assume that the mutex will be initialized
+ // single-threaded.
+ if (! iindex_mutex_initialized)
+ {
+ _Jv_MutexInit (&iindex_mutex);
+ iindex_mutex_initialized = true;
+ }
+
+ _Jv_MutexLock (&iindex_mutex);
+
+ for (i=1;; i++) /* each potential position in ioffsets */
+ {
+ for (j=0;; j++) /* each iface */
+ {
+ if (j >= num)
+ goto found;
+ if (i >= ifaces[j]->idt->iface.ioffsets[0])
+ continue;
+ int ioffset = ifaces[j]->idt->iface.ioffsets[i];
+ /* We can potentially share this position with another class. */
+ if (ioffset >= 0 && ioffset != offsets[j])
+ break; /* Nope. Try next i. */
+ }
+ }
+ found:
+ for (j = 0; j < num; j++)
+ {
+ int len = ifaces[j]->idt->iface.ioffsets[0];
+ if (i >= len)
+ {
+ /* Resize ioffsets. */
+ int newlen = 2 * len;
+ if (i >= newlen)
+ newlen = i + 3;
+ jshort *old_ioffsets = ifaces[j]->idt->iface.ioffsets;
+ // FIXME: _Jv_AllocBytes
+ jshort *new_ioffsets = (jshort *) _Jv_Malloc (newlen
+ * sizeof(jshort));
+ memcpy (&new_ioffsets[1], &old_ioffsets[1], len * sizeof (jshort));
+ new_ioffsets[0] = newlen;
+
+ while (len < newlen)
+ new_ioffsets[len++] = -1;
+
+ ifaces[j]->idt->iface.ioffsets = new_ioffsets;
+ }
+ ifaces[j]->idt->iface.ioffsets[i] = offsets[j];
+ }
+
+ _Jv_MutexUnlock (&iindex_mutex);
+
+ return i;
+}
+
+
+// Functions for indirect dispatch (symbolic virtual binding) support.
+
+// There are three tables, atable otable and itable. atable is an
+// array of addresses, and otable is an array of offsets, and these
+// are used for static and virtual members respectively. itable is an
+// array of pairs {address, index} where each address is a pointer to
+// an interface.
+
+// {a,o,i}table_syms is an array of _Jv_MethodSymbols. Each such
+// symbol is a tuple of {classname, member name, signature}.
+
+// Set this to true to enable debugging of indirect dispatch tables/linking.
+static bool debug_link = false;
+
+// _Jv_LinkSymbolTable() scans these two arrays and fills in the
+// corresponding atable and otable with the addresses of static
+// members and the offsets of virtual members.
+
+// The offset (in bytes) for each resolved method or field is placed
+// at the corresponding position in the virtual method offset table
+// (klass->otable).
+
+// The same otable and atable may be shared by many classes.
+
+// This must be called while holding the class lock.
+
+void
+_Jv_Linker::link_symbol_table (jclass klass)
+{
+ int index = 0;
+ _Jv_MethodSymbol sym;
+ if (klass->otable == NULL
+ || klass->otable->state != 0)
+ goto atable;
+
+ klass->otable->state = 1;
+
+ if (debug_link)
+ fprintf (stderr, "Fixing up otable in %s:\n", klass->name->data);
+ for (index = 0;
+ (sym = klass->otable_syms[index]).class_name != NULL;
+ ++index)
+ {
+ jclass target_class = _Jv_FindClass (sym.class_name, klass->loader);
+ _Jv_Method *meth = NULL;
+
+ const _Jv_Utf8Const *signature = sym.signature;
+
+ {
+ static char *bounce = (char *)_Jv_ThrowNoSuchMethodError;
+ ptrdiff_t offset = (char *)(klass->vtable) - bounce;
+ klass->otable->offsets[index] = offset;
+ }
+
+ if (target_class == NULL)
+ throw new java::lang::NoClassDefFoundError
+ (_Jv_NewStringUTF (sym.class_name->data));
+
+ // We're looking for a field or a method, and we can tell
+ // which is needed by looking at the signature.
+ if (signature->length >= 2
+ && signature->data[0] == '(')
+ {
+ // Looks like someone is trying to invoke an interface method
+ if (target_class->isInterface())
+ {
+ using namespace java::lang;
+ StringBuffer *sb = new StringBuffer();
+ sb->append(JvNewStringLatin1("found interface "));
+ sb->append(target_class->getName());
+ sb->append(JvNewStringLatin1(" when searching for a class"));
+ throw new VerifyError(sb->toString());
+ }
+
+ // If the target class does not have a vtable_method_count yet,
+ // then we can't tell the offsets for its methods, so we must lay
+ // it out now.
+ wait_for_state(target_class, JV_STATE_PREPARED);
+
+ meth = _Jv_LookupDeclaredMethod(target_class, sym.name,
+ sym.signature);
+
+ if (meth != NULL)
+ {
+ int offset = _Jv_VTable::idx_to_offset (meth->index);
+ if (offset == -1)
+ JvFail ("Bad method index");
+ JvAssert (meth->index < target_class->vtable_method_count);
+ klass->otable->offsets[index] = offset;
+ }
+ if (debug_link)
+ fprintf (stderr, " offsets[%d] = %d (class %s@%p : %s(%s))\n",
+ index,
+ klass->otable->offsets[index],
+ (const char*)target_class->name->data,
+ target_class,
+ (const char*)sym.name->data,
+ (const char*)signature->data);
+ continue;
+ }
+
+ // try fields
+ {
+ _Jv_Field *the_field = NULL;
+
+ for (jclass cls = target_class; cls != 0; cls = cls->getSuperclass ())
+ {
+ for (int i = 0; i < cls->field_count; i++)
+ {
+ _Jv_Field *field = &cls->fields[i];
+ if (! _Jv_equalUtf8Consts (field->name, sym.name))
+ continue;
+
+ // FIXME: What access checks should we perform here?
+// if (_Jv_CheckAccess (klass, cls, field->flags))
+// {
+
+ wait_for_state(cls, JV_STATE_PREPARED);
+
+ if (!field->isResolved ())
+ resolve_field (field, cls->loader);
+
+// if (field_type != 0 && field->type != field_type)
+// throw new java::lang::LinkageError
+// (JvNewStringLatin1
+// ("field type mismatch with different loaders"));
+
+ the_field = field;
+ if (debug_link)
+ fprintf (stderr, " offsets[%d] = %d (class %s@%p : %s)\n",
+ index,
+ field->u.boffset,
+ (const char*)cls->name->data,
+ cls,
+ (const char*)field->name->data);
+ goto end_of_field_search;
+ }
+ }
+ end_of_field_search:
+ if (the_field != NULL)
+ {
+ if ((the_field->flags & java::lang::reflect::Modifier::STATIC))
+ throw new java::lang::IncompatibleClassChangeError;
+ else
+ klass->otable->offsets[index] = the_field->u.boffset;
+ }
+ else
+ {
+ throw new java::lang::NoSuchFieldError
+ (_Jv_NewStringUtf8Const (sym.name));
+ }
+ }
+ }
+
+ atable:
+ if (klass->atable == NULL || klass->atable->state != 0)
+ goto itable;
+
+ klass->atable->state = 1;
+
+ for (index = 0;
+ (sym = klass->atable_syms[index]).class_name != NULL;
+ ++index)
+ {
+ jclass target_class = _Jv_FindClass (sym.class_name, klass->loader);
+ _Jv_Method *meth = NULL;
+ const _Jv_Utf8Const *signature = sym.signature;
+
+ // ??? Setting this pointer to null will at least get us a
+ // NullPointerException
+ klass->atable->addresses[index] = NULL;
+
+ if (target_class == NULL)
+ throw new java::lang::NoClassDefFoundError
+ (_Jv_NewStringUTF (sym.class_name->data));
+
+ // We're looking for a static field or a static method, and we
+ // can tell which is needed by looking at the signature.
+ if (signature->length >= 2
+ && signature->data[0] == '(')
+ {
+ // If the target class does not have a vtable_method_count yet,
+ // then we can't tell the offsets for its methods, so we must lay
+ // it out now.
+ wait_for_state (target_class, JV_STATE_PREPARED);
+
+ // Interface methods cannot have bodies.
+ if (target_class->isInterface())
+ {
+ using namespace java::lang;
+ StringBuffer *sb = new StringBuffer();
+ sb->append(JvNewStringLatin1("class "));
+ sb->append(target_class->getName());
+ sb->append(JvNewStringLatin1(" is an interface: "
+ "class expected"));
+ throw new VerifyError(sb->toString());
+ }
+
+ meth = _Jv_LookupDeclaredMethod(target_class, sym.name,
+ sym.signature);
+
+ if (meth != NULL)
+ {
+ if (meth->ncode) // Maybe abstract?
+ {
+ klass->atable->addresses[index] = meth->ncode;
+ if (debug_link)
+ fprintf (stderr, " addresses[%d] = %p (class %s@%p : %s(%s))\n",
+ index,
+ &klass->atable->addresses[index],
+ (const char*)target_class->name->data,
+ klass,
+ (const char*)sym.name->data,
+ (const char*)signature->data);
+ }
+ }
+ else
+ klass->atable->addresses[index]
+ = (void *)_Jv_ThrowNoSuchMethodError;
+
+ continue;
+ }
+
+ // try fields
+ {
+ _Jv_Field *the_field = NULL;
+
+ for (jclass cls = target_class; cls != 0; cls = cls->getSuperclass ())
+ {
+ for (int i = 0; i < cls->field_count; i++)
+ {
+ _Jv_Field *field = &cls->fields[i];
+ if (! _Jv_equalUtf8Consts (field->name, sym.name))
+ continue;
+
+ // FIXME: What access checks should we perform here?
+// if (_Jv_CheckAccess (klass, cls, field->flags))
+// {
+
+ if (!field->isResolved ())
+ resolve_field (field, cls->loader);
+
+ wait_for_state(target_class, JV_STATE_PREPARED);
+
+// if (field_type != 0 && field->type != field_type)
+// throw new java::lang::LinkageError
+// (JvNewStringLatin1
+// ("field type mismatch with different loaders"));
+
+ the_field = field;
+ goto end_of_static_field_search;
+ }
+ }
+ end_of_static_field_search:
+ if (the_field != NULL)
+ {
+ if ((the_field->flags & java::lang::reflect::Modifier::STATIC))
+ klass->atable->addresses[index] = the_field->u.addr;
+ else
+ throw new java::lang::IncompatibleClassChangeError;
+ }
+ else
+ {
+ throw new java::lang::NoSuchFieldError
+ (_Jv_NewStringUtf8Const (sym.name));
+ }
+ }
+ }
+
+ itable:
+ if (klass->itable == NULL
+ || klass->itable->state != 0)
+ return;
+
+ klass->itable->state = 1;
+
+ for (index = 0;
+ (sym = klass->itable_syms[index]).class_name != NULL;
+ ++index)
+ {
+ jclass target_class = _Jv_FindClass (sym.class_name, klass->loader);
+ const _Jv_Utf8Const *signature = sym.signature;
+
+ jclass cls;
+ int i;
+
+ bool found = _Jv_getInterfaceMethod (target_class, cls, i,
+ sym.name, sym.signature);
+
+ if (found)
+ {
+ klass->itable->addresses[index * 2] = cls;
+ klass->itable->addresses[index * 2 + 1] = (void *) i;
+ if (debug_link)
+ {
+ fprintf (stderr, " interfaces[%d] = %p (interface %s@%p : %s(%s))\n",
+ index,
+ klass->itable->addresses[index * 2],
+ (const char*)cls->name->data,
+ cls,
+ (const char*)sym.name->data,
+ (const char*)signature->data);
+ fprintf (stderr, " [%d] = offset %d\n",
+ index + 1,
+ (int)klass->itable->addresses[index * 2 + 1]);
+ }
+
+ }
+ else
+ throw new java::lang::IncompatibleClassChangeError;
+ }
+
+}
+
+// For each catch_record in the list of caught classes, fill in the
+// address field.
+void
+_Jv_Linker::link_exception_table (jclass self)
+{
+ struct _Jv_CatchClass *catch_record = self->catch_classes;
+ if (!catch_record || catch_record->classname)
+ return;
+ catch_record++;
+ while (catch_record->classname)
+ {
+ try
+ {
+ jclass target_class
+ = _Jv_FindClass (catch_record->classname,
+ self->getClassLoaderInternal ());
+ *catch_record->address = target_class;
+ }
+ catch (::java::lang::Throwable *t)
+ {
+ // FIXME: We need to do something better here.
+ *catch_record->address = 0;
+ }
+ catch_record++;
+ }
+ self->catch_classes->classname = (_Jv_Utf8Const *)-1;
+}
+
+// This is put in empty vtable slots.
+static void
+_Jv_abstractMethodError (void)
+{
+ throw new java::lang::AbstractMethodError();
+}
+
+// Set itable method indexes for members of interface IFACE.
+void
+_Jv_Linker::layout_interface_methods (jclass iface)
+{
+ if (! iface->isInterface())
+ return;
+
+ // itable indexes start at 1.
+ // FIXME: Static initalizers currently get a NULL placeholder entry in the
+ // itable so they are also assigned an index here.
+ for (int i = 0; i < iface->method_count; i++)
+ iface->methods[i].index = i + 1;
+}
+
+// Prepare virtual method declarations in KLASS, and any superclasses
+// as required, by determining their vtable index, setting
+// method->index, and finally setting the class's vtable_method_count.
+// Must be called with the lock for KLASS held.
+void
+_Jv_Linker::layout_vtable_methods (jclass klass)
+{
+ if (klass->vtable != NULL || klass->isInterface()
+ || klass->vtable_method_count != -1)
+ return;
+
+ jclass superclass = klass->getSuperclass();
+
+ if (superclass != NULL && superclass->vtable_method_count == -1)
+ {
+ JvSynchronize sync (superclass);
+ layout_vtable_methods (superclass);
+ }
+
+ int index = (superclass == NULL ? 0 : superclass->vtable_method_count);
+
+ for (int i = 0; i < klass->method_count; ++i)
+ {
+ _Jv_Method *meth = &klass->methods[i];
+ _Jv_Method *super_meth = NULL;
+
+ if (! _Jv_isVirtualMethod (meth))
+ continue;
+
+ if (superclass != NULL)
+ {
+ jclass declarer;
+ super_meth = _Jv_LookupDeclaredMethod (superclass, meth->name,
+ meth->signature, &declarer);
+ // See if this method actually overrides the other method
+ // we've found.
+ if (super_meth)
+ {
+ if (! _Jv_isVirtualMethod (super_meth)
+ || ! _Jv_CheckAccess (klass, declarer,
+ super_meth->accflags))
+ super_meth = NULL;
+ else if ((super_meth->accflags
+ & java::lang::reflect::Modifier::FINAL) != 0)
+ {
+ using namespace java::lang;
+ StringBuffer *sb = new StringBuffer();
+ sb->append(JvNewStringLatin1("method "));
+ sb->append(_Jv_GetMethodString(klass, meth->name));
+ sb->append(JvNewStringLatin1(" overrides final method "));
+ sb->append(_Jv_GetMethodString(declarer, super_meth->name));
+ throw new VerifyError(sb->toString());
+ }
+ }
+ }
+
+ if (super_meth)
+ meth->index = super_meth->index;
+ else
+ meth->index = index++;
+ }
+
+ klass->vtable_method_count = index;
+}
+
+// Set entries in VTABLE for virtual methods declared in KLASS. If
+// KLASS has an immediate abstract parent, recursively do its methods
+// first. FLAGS is used to determine which slots we've actually set.
+void
+_Jv_Linker::set_vtable_entries (jclass klass, _Jv_VTable *vtable,
+ jboolean *flags)
+{
+ using namespace java::lang::reflect;
+
+ jclass superclass = klass->getSuperclass();
+
+ if (superclass != NULL && (superclass->getModifiers() & Modifier::ABSTRACT))
+ set_vtable_entries (superclass, vtable, flags);
+
+ for (int i = klass->method_count - 1; i >= 0; i--)
+ {
+ _Jv_Method *meth = &klass->methods[i];
+ if (meth->index == (_Jv_ushort) -1)
+ continue;
+ if ((meth->accflags & Modifier::ABSTRACT))
+ {
+ vtable->set_method(meth->index, (void *) &_Jv_abstractMethodError);
+ flags[meth->index] = false;
+ }
+ else
+ {
+ vtable->set_method(meth->index, meth->ncode);
+ flags[meth->index] = true;
+ }
+ }
+}
+
+// Allocate and lay out the virtual method table for KLASS. This will
+// also cause vtables to be generated for any non-abstract
+// superclasses, and virtual method layout to occur for any abstract
+// superclasses. Must be called with monitor lock for KLASS held.
+void
+_Jv_Linker::make_vtable (jclass klass)
+{
+ using namespace java::lang::reflect;
+
+ // If the vtable exists, or for interface classes, do nothing. All
+ // other classes, including abstract classes, need a vtable.
+ if (klass->vtable != NULL || klass->isInterface())
+ return;
+
+ // Ensure all the `ncode' entries are set.
+ klass->engine->create_ncode(klass);
+
+ // Class must be laid out before we can create a vtable.
+ if (klass->vtable_method_count == -1)
+ layout_vtable_methods (klass);
+
+ // Allocate the new vtable.
+ _Jv_VTable *vtable = _Jv_VTable::new_vtable (klass->vtable_method_count);
+ klass->vtable = vtable;
+
+ jboolean flags[klass->vtable_method_count];
+ for (int i = 0; i < klass->vtable_method_count; ++i)
+ flags[i] = false;
+
+ // Copy the vtable of the closest superclass.
+ jclass superclass = klass->superclass;
+ {
+ JvSynchronize sync (superclass);
+ make_vtable (superclass);
+ }
+ for (int i = 0; i < superclass->vtable_method_count; ++i)
+ {
+ vtable->set_method (i, superclass->vtable->get_method (i));
+ flags[i] = true;
+ }
+
+ // Set the class pointer and GC descriptor.
+ vtable->clas = klass;
+ vtable->gc_descr = _Jv_BuildGCDescr (klass);
+
+ // For each virtual declared in klass and any immediate abstract
+ // superclasses, set new vtable entry or override an old one.
+ set_vtable_entries (klass, vtable, flags);
+
+ // It is an error to have an abstract method in a concrete class.
+ if (! (klass->accflags & Modifier::ABSTRACT))
+ {
+ for (int i = 0; i < klass->vtable_method_count; ++i)
+ if (! flags[i])
+ {
+ using namespace java::lang;
+ while (klass != NULL)
+ {
+ for (int j = 0; j < klass->method_count; ++j)
+ {
+ if (klass->methods[i].index == i)
+ {
+ StringBuffer *buf = new StringBuffer ();
+ buf->append (_Jv_NewStringUtf8Const (klass->methods[i].name));
+ buf->append ((jchar) ' ');
+ buf->append (_Jv_NewStringUtf8Const (klass->methods[i].signature));
+ throw new AbstractMethodError (buf->toString ());
+ }
+ }
+ klass = klass->getSuperclass ();
+ }
+ // Couldn't find the name, which is weird.
+ // But we still must throw the error.
+ throw new AbstractMethodError ();
+ }
+ }
+}
+
+// Lay out the class, allocating space for static fields and computing
+// offsets of instance fields. The class lock must be held by the
+// caller.
+void
+_Jv_Linker::ensure_fields_laid_out (jclass klass)
+{
+ if (klass->size_in_bytes != -1)
+ return;
+
+ // Compute the alignment for this type by searching through the
+ // superclasses and finding the maximum required alignment. We
+ // could consider caching this in the Class.
+ int max_align = __alignof__ (java::lang::Object);
+ jclass super = klass->getSuperclass();
+ while (super != NULL)
+ {
+ // Ensure that our super has its super installed before
+ // recursing.
+ wait_for_state(super, JV_STATE_LOADING);
+ ensure_fields_laid_out(super);
+ int num = JvNumInstanceFields (super);
+ _Jv_Field *field = JvGetFirstInstanceField (super);
+ while (num > 0)
+ {
+ int field_align = get_alignment_from_class (field->type);
+ if (field_align > max_align)
+ max_align = field_align;
+ ++field;
+ --num;
+ }
+ super = super->getSuperclass();
+ }
+
+ int instance_size;
+ int static_size = 0;
+
+ // Although java.lang.Object is never interpreted, an interface can
+ // have a null superclass. Note that we have to lay out an
+ // interface because it might have static fields.
+ if (klass->superclass)
+ instance_size = klass->superclass->size();
+ else
+ instance_size = java::lang::Object::class$.size();
+
+ for (int i = 0; i < klass->field_count; i++)
+ {
+ int field_size;
+ int field_align;
+
+ _Jv_Field *field = &klass->fields[i];
+
+ if (! field->isRef ())
+ {
+ // It is safe to resolve the field here, since it's a
+ // primitive class, which does not cause loading to happen.
+ resolve_field (field, klass->loader);
+
+ field_size = field->type->size ();
+ field_align = get_alignment_from_class (field->type);
+ }
+ else
+ {
+ field_size = sizeof (jobject);
+ field_align = __alignof__ (jobject);
+ }
+
+ field->bsize = field_size;
+
+ if ((field->flags & java::lang::reflect::Modifier::STATIC))
+ {
+ if (field->u.addr == NULL)
+ {
+ // This computes an offset into a region we'll allocate
+ // shortly, and then add this offset to the start
+ // address.
+ static_size = ROUND (static_size, field_align);
+ field->u.boffset = static_size;
+ static_size += field_size;
+ }
+ }
+ else
+ {
+ instance_size = ROUND (instance_size, field_align);
+ field->u.boffset = instance_size;
+ instance_size += field_size;
+ if (field_align > max_align)
+ max_align = field_align;
+ }
+ }
+
+ if (static_size != 0)
+ klass->engine->allocate_static_fields (klass, static_size);
+
+ // Set the instance size for the class. Note that first we round it
+ // to the alignment required for this object; this keeps us in sync
+ // with our current ABI.
+ instance_size = ROUND (instance_size, max_align);
+ klass->size_in_bytes = instance_size;
+}
+
+// This takes the class to state JV_STATE_LINKED. The class lock must
+// be held when calling this.
+void
+_Jv_Linker::ensure_class_linked (jclass klass)
+{
+ if (klass->state >= JV_STATE_LINKED)
+ return;
+
+ int state = klass->state;
+ try
+ {
+ // Short-circuit, so that mutually dependent classes are ok.
+ klass->state = JV_STATE_LINKED;
+
+ _Jv_Constants *pool = &klass->constants;
+
+ // Resolve class constants first, since other constant pool
+ // entries may rely on these.
+ for (int index = 1; index < pool->size; ++index)
+ {
+ if (pool->tags[index] == JV_CONSTANT_Class)
+ resolve_pool_entry (klass, index);
+ }
+
+#if 0 // Should be redundant now
+ // If superclass looks like a constant pool entry,
+ // resolve it now.
+ if ((uaddr) klass->superclass < (uaddr) pool->size)
+ klass->superclass = pool->data[(int) klass->superclass].clazz;
+
+ // Likewise for interfaces.
+ for (int i = 0; i < klass->interface_count; i++)
+ {
+ if ((uaddr) klass->interfaces[i] < (uaddr) pool->size)
+ klass->interfaces[i]
+ = pool->data[(int) klass->interfaces[i]].clazz;
+ }
+#endif
+
+ // Resolve the remaining constant pool entries.
+ for (int index = 1; index < pool->size; ++index)
+ {
+ if (pool->tags[index] == JV_CONSTANT_String)
+ {
+ jstring str;
+
+ str = _Jv_NewStringUtf8Const (pool->data[index].utf8);
+ pool->data[index].o = str;
+ pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
+ }
+ }
+
+ if (klass->engine->need_resolve_string_fields())
+ {
+ jfieldID f = JvGetFirstStaticField (klass);
+ for (int n = JvNumStaticFields (klass); n > 0; --n)
+ {
+ int mod = f->getModifiers ();
+ // If we have a static String field with a non-null initial
+ // value, we know it points to a Utf8Const.
+ resolve_field(f, klass->loader);
+ if (f->getClass () == &java::lang::String::class$
+ && (mod & java::lang::reflect::Modifier::STATIC) != 0)
+ {
+ jstring *strp = (jstring *) f->u.addr;
+ if (*strp)
+ *strp = _Jv_NewStringUtf8Const ((_Jv_Utf8Const *) *strp);
+ }
+ f = f->getNextField ();
+ }
+ }
+
+ klass->notifyAll ();
+
+ _Jv_PushClass (klass);
+ }
+ catch (java::lang::Throwable *t)
+ {
+ klass->state = state;
+ throw t;
+ }
+}
+
+// This ensures that symbolic superclass and superinterface references
+// are resolved for the indicated class. This must be called with the
+// class lock held.
+void
+_Jv_Linker::ensure_supers_installed (jclass klass)
+{
+ resolve_class_ref (klass, &klass->superclass);
+ // An interface won't have a superclass.
+ if (klass->superclass)
+ wait_for_state (klass->superclass, JV_STATE_LOADING);
+
+ for (int i = 0; i < klass->interface_count; ++i)
+ {
+ resolve_class_ref (klass, &klass->interfaces[i]);
+ wait_for_state (klass->interfaces[i], JV_STATE_LOADING);
+ }
+}
+
+// This adds missing `Miranda methods' to a class.
+void
+_Jv_Linker::add_miranda_methods (jclass base, jclass iface_class)
+{
+ // Note that at this point, all our supers, and the supers of all
+ // our superclasses and superinterfaces, will have been installed.
+
+ for (int i = 0; i < iface_class->interface_count; ++i)
+ {
+ jclass interface = iface_class->interfaces[i];
+
+ for (int j = 0; j < interface->method_count; ++j)
+ {
+ _Jv_Method *meth = &interface->methods[j];
+ // Don't bother with <clinit>.
+ if (meth->name->data[0] == '<')
+ continue;
+ _Jv_Method *new_meth = _Jv_LookupDeclaredMethod (base, meth->name,
+ meth->signature);
+ if (! new_meth)
+ {
+ // We assume that such methods are very unlikely, so we
+ // just reallocate the method array each time one is
+ // found. This greatly simplifies the searching --
+ // otherwise we have to make sure that each such method
+ // found is really unique among all superinterfaces.
+ int new_count = base->method_count + 1;
+ _Jv_Method *new_m
+ = (_Jv_Method *) _Jv_AllocBytes (sizeof (_Jv_Method)
+ * new_count);
+ memcpy (new_m, base->methods,
+ sizeof (_Jv_Method) * base->method_count);
+
+ // Add new method.
+ new_m[base->method_count] = *meth;
+ new_m[base->method_count].index = (_Jv_ushort) -1;
+ new_m[base->method_count].accflags
+ |= java::lang::reflect::Modifier::INVISIBLE;
+
+ base->methods = new_m;
+ base->method_count = new_count;
+ }
+ }
+
+ add_miranda_methods (base, interface);
+ }
+}
+
+// This ensures that the class' method table is "complete". This must
+// be called with the class lock held.
+void
+_Jv_Linker::ensure_method_table_complete (jclass klass)
+{
+ if (klass->vtable != NULL || klass->isInterface())
+ return;
+
+ // We need our superclass to have its own Miranda methods installed.
+ wait_for_state (klass->getSuperclass (), JV_STATE_LOADED);
+
+ // A class might have so-called "Miranda methods". This is a method
+ // that is declared in an interface and not re-declared in an
+ // abstract class. Some compilers don't emit declarations for such
+ // methods in the class; this will give us problems since we expect
+ // a declaration for any method requiring a vtable entry. We handle
+ // this here by searching for such methods and constructing new
+ // internal declarations for them. Note that we do this
+ // unconditionally, and not just for abstract classes, to correctly
+ // account for cases where a class is modified to be concrete and
+ // still incorrectly inherits an abstract method.
+ add_miranda_methods (klass, klass);
+}
+
+// Verify a class. Must be called with class lock held.
+void
+_Jv_Linker::verify_class (jclass klass)
+{
+ klass->engine->verify(klass);
+}
+
+// FIXME: mention invariants and stuff.
+void
+_Jv_Linker::wait_for_state (jclass klass, int state)
+{
+ if (klass->state >= state)
+ return;
+
+ JvSynchronize sync (klass);
+
+ // This is similar to the strategy for class initialization. If we
+ // already hold the lock, just leave.
+ java::lang::Thread *self = java::lang::Thread::currentThread();
+ while (klass->state <= state
+ && klass->thread
+ && klass->thread != self)
+ klass->wait ();
+
+ java::lang::Thread *save = klass->thread;
+ klass->thread = self;
+
+ try
+ {
+ if (state >= JV_STATE_LOADING && klass->state < JV_STATE_LOADING)
+ {
+ ensure_supers_installed (klass);
+ klass->set_state(JV_STATE_LOADING);
+ }
+
+ if (state >= JV_STATE_LOADED && klass->state < JV_STATE_LOADED)
+ {
+ ensure_method_table_complete (klass);
+ klass->set_state(JV_STATE_LOADED);
+ }
+
+ if (state >= JV_STATE_PREPARED && klass->state < JV_STATE_PREPARED)
+ {
+ ensure_fields_laid_out (klass);
+ make_vtable (klass);
+ layout_interface_methods (klass);
+ prepare_constant_time_tables (klass);
+ klass->set_state(JV_STATE_PREPARED);
+ }
+
+ if (state >= JV_STATE_LINKED && klass->state < JV_STATE_LINKED)
+ {
+ ensure_class_linked (klass);
+ link_exception_table (klass);
+ link_symbol_table (klass);
+ klass->set_state(JV_STATE_LINKED);
+ }
+ }
+ catch (java::lang::Throwable *exc)
+ {
+ klass->thread = save;
+ klass->set_state(JV_STATE_ERROR);
+ throw exc;
+ }
+
+ klass->thread = save;
+
+ if (klass->state == JV_STATE_ERROR)
+ throw new java::lang::LinkageError;
+}
diff --git a/libjava/mauve-libgcj b/libjava/mauve-libgcj
index 807eed70fc6..33e4fa2029e 100644
--- a/libjava/mauve-libgcj
+++ b/libjava/mauve-libgcj
@@ -22,3 +22,10 @@ JDBC2.0
# The behaviour of the garbarge collector cannot be predicted.
# Note the . at the end so we do test java.lang.reflect
!java.lang.ref.
+
+!java.beans.EventHandler
+!java.beans.Expression
+!java.beans.Statement
+!java.text.CollationElementIterator
+!javax.print.DocFlavor
+!javax.swing.text.PlainDocument
diff --git a/libjava/prims.cc b/libjava/prims.cc
index 06791d388f3..0118111a396 100644
--- a/libjava/prims.cc
+++ b/libjava/prims.cc
@@ -61,11 +61,15 @@ details. */
#include <gnu/gcj/runtime/VMClassLoader.h>
#include <gnu/gcj/runtime/FinalizerThread.h>
#include <gnu/gcj/runtime/FirstThread.h>
+#include <execution.h>
#ifdef USE_LTDL
#include <ltdl.h>
#endif
+// Execution engine for compiled code.
+_Jv_CompiledEngine _Jv_soleCompiledEngine;
+
// We allocate a single OutOfMemoryError exception which we keep
// around for use if we run out of memory.
static java::lang::OutOfMemoryError *no_memory;
@@ -389,16 +393,15 @@ jvmpi_notify_alloc(jclass klass, jint size, jobject obj)
# define jvmpi_notify_alloc(klass,size,obj) /* do nothing */
#endif
-// Allocate a new object of class KLASS. SIZE is the size of the object
-// to allocate. You might think this is redundant, but it isn't; some
-// classes, such as String, aren't of fixed size.
+// Allocate a new object of class KLASS.
// First a version that assumes that we have no finalizer, and that
// the class is already initialized.
// If we know that JVMPI is disabled, this can be replaced by a direct call
// to the allocator for the appropriate GC.
jobject
-_Jv_AllocObjectNoInitNoFinalizer (jclass klass, jint size)
+_Jv_AllocObjectNoInitNoFinalizer (jclass klass)
{
+ jint size = klass->size ();
jobject obj = (jobject) _Jv_AllocObj (size, klass);
jvmpi_notify_alloc (klass, size, obj);
return obj;
@@ -406,9 +409,10 @@ _Jv_AllocObjectNoInitNoFinalizer (jclass klass, jint size)
// And now a version that initializes if necessary.
jobject
-_Jv_AllocObjectNoFinalizer (jclass klass, jint size)
+_Jv_AllocObjectNoFinalizer (jclass klass)
{
_Jv_InitClass (klass);
+ jint size = klass->size ();
jobject obj = (jobject) _Jv_AllocObj (size, klass);
jvmpi_notify_alloc (klass, size, obj);
return obj;
@@ -416,10 +420,10 @@ _Jv_AllocObjectNoFinalizer (jclass klass, jint size)
// And now the general version that registers a finalizer if necessary.
jobject
-_Jv_AllocObject (jclass klass, jint size)
+_Jv_AllocObject (jclass klass)
{
- jobject obj = _Jv_AllocObjectNoFinalizer (klass, size);
-
+ jobject obj = _Jv_AllocObjectNoFinalizer (klass);
+
// We assume that the compiler only generates calls to this routine
// if there really is an interesting finalizer.
// Unfortunately, we still have to the dynamic test, since there may
@@ -432,14 +436,62 @@ _Jv_AllocObject (jclass klass, jint size)
return obj;
}
+// Allocate a String, including variable length storage.
+jstring
+_Jv_AllocString(jsize len)
+{
+ using namespace java::lang;
+
+ jsize sz = sizeof(java::lang::String) + len * sizeof(jchar);
+
+ // We assert that for strings allocated this way, the data field
+ // will always point to the object itself. Thus there is no reason
+ // for the garbage collector to scan any of it.
+ // Furthermore, we're about to overwrite the string data, so
+ // initialization of the object is not an issue.
+
+ // String needs no initialization, and there is no finalizer, so
+ // we can go directly to the collector's allocator interface.
+ jstring obj = (jstring) _Jv_AllocPtrFreeObj(sz, &String::class$);
+
+ obj->data = obj;
+ obj->boffset = sizeof(java::lang::String);
+ obj->count = len;
+ obj->cachedHashCode = 0;
+
+#ifdef ENABLE_JVMPI
+ // Service JVMPI request.
+
+ if (__builtin_expect (_Jv_JVMPI_Notify_OBJECT_ALLOC != 0, false))
+ {
+ JVMPI_Event event;
+
+ event.event_type = JVMPI_EVENT_OBJECT_ALLOC;
+ event.env_id = NULL;
+ event.u.obj_alloc.arena_id = 0;
+ event.u.obj_alloc.class_id = (jobjectID) &String::class$;
+ event.u.obj_alloc.is_array = 0;
+ event.u.obj_alloc.size = sz;
+ event.u.obj_alloc.obj_id = (jobjectID) obj;
+
+ _Jv_DisableGC ();
+ (*_Jv_JVMPI_Notify_OBJECT_ALLOC) (&event);
+ _Jv_EnableGC ();
+ }
+#endif
+
+ return obj;
+}
+
// A version of the above that assumes the object contains no pointers,
// and requires no finalization. This can't happen if we need pointers
// to locks.
#ifdef JV_HASH_SYNCHRONIZATION
jobject
-_Jv_AllocPtrFreeObject (jclass klass, jint size)
+_Jv_AllocPtrFreeObject (jclass klass)
{
_Jv_InitClass (klass);
+ jint size = klass->size ();
jobject obj = (jobject) _Jv_AllocPtrFreeObj (size, klass);
@@ -707,7 +759,7 @@ JvConvertArgv (int argc, const char **argv)
{
if (argc < 0)
argc = 0;
- jobjectArray ar = JvNewObjectArray(argc, &StringClass, NULL);
+ jobjectArray ar = JvNewObjectArray(argc, &java::lang::String::class$, NULL);
jobject *ptr = elements(ar);
jbyteArray bytes = NULL;
for (int i = 0; i < argc; i++)
@@ -1180,7 +1232,7 @@ _Jv_CheckAccess (jclass self_klass, jclass other_klass, jint flags)
return ((self_klass == other_klass)
|| ((flags & Modifier::PUBLIC) != 0)
|| (((flags & Modifier::PROTECTED) != 0)
- && other_klass->isAssignableFrom (self_klass))
+ && _Jv_IsAssignableFromSlow (other_klass, self_klass))
|| (((flags & Modifier::PRIVATE) == 0)
&& _Jv_ClassNameSamePackage (self_klass->name,
other_klass->name)));
diff --git a/libjava/resolve.cc b/libjava/resolve.cc
deleted file mode 100644
index 5a859a73f6c..00000000000
--- a/libjava/resolve.cc
+++ /dev/null
@@ -1,1125 +0,0 @@
-// resolve.cc - Code for linking and resolving classes and pool entries.
-
-/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
-
- This file is part of libgcj.
-
-This software is copyrighted work licensed under the terms of the
-Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
-details. */
-
-/* Author: Kresten Krab Thorup <krab@gnu.org> */
-
-#include <config.h>
-#include <platform.h>
-
-#include <java-interp.h>
-
-#include <jvm.h>
-#include <gcj/cni.h>
-#include <string.h>
-#include <java-cpool.h>
-#include <java/lang/Class.h>
-#include <java/lang/String.h>
-#include <java/lang/StringBuffer.h>
-#include <java/lang/Thread.h>
-#include <java/lang/InternalError.h>
-#include <java/lang/VirtualMachineError.h>
-#include <java/lang/NoSuchFieldError.h>
-#include <java/lang/NoSuchMethodError.h>
-#include <java/lang/ClassFormatError.h>
-#include <java/lang/IllegalAccessError.h>
-#include <java/lang/AbstractMethodError.h>
-#include <java/lang/NoClassDefFoundError.h>
-#include <java/lang/IncompatibleClassChangeError.h>
-#include <java/lang/VMClassLoader.h>
-#include <java/lang/reflect/Modifier.h>
-
-using namespace gcj;
-
-void
-_Jv_ResolveField (_Jv_Field *field, java::lang::ClassLoader *loader)
-{
- if (! field->isResolved ())
- {
- _Jv_Utf8Const *sig = (_Jv_Utf8Const*)field->type;
- field->type = _Jv_FindClassFromSignature (sig->data, loader);
- field->flags &= ~_Jv_FIELD_UNRESOLVED_FLAG;
- }
-}
-
-#ifdef INTERPRETER
-
-static void throw_internal_error (char *msg)
- __attribute__ ((__noreturn__));
-static void throw_class_format_error (jstring msg)
- __attribute__ ((__noreturn__));
-static void throw_class_format_error (char *msg)
- __attribute__ ((__noreturn__));
-
-static int get_alignment_from_class (jclass);
-
-static _Jv_ResolvedMethod*
-_Jv_BuildResolvedMethod (_Jv_Method*,
- jclass,
- jboolean,
- jint);
-
-
-static void throw_incompatible_class_change_error (jstring msg)
-{
- throw new java::lang::IncompatibleClassChangeError (msg);
-}
-
-_Jv_word
-_Jv_ResolvePoolEntry (jclass klass, int index)
-{
- using namespace java::lang::reflect;
-
- _Jv_Constants *pool = &klass->constants;
-
- if ((pool->tags[index] & JV_CONSTANT_ResolvedFlag) != 0)
- return pool->data[index];
-
- switch (pool->tags[index]) {
- case JV_CONSTANT_Class:
- {
- _Jv_Utf8Const *name = pool->data[index].utf8;
-
- jclass found;
- if (name->data[0] == '[')
- found = _Jv_FindClassFromSignature (&name->data[0],
- klass->loader);
- else
- found = _Jv_FindClass (name, klass->loader);
-
- if (! found)
- {
- jstring str = _Jv_NewStringUTF (name->data);
- // This exception is specified in JLS 2nd Ed, section 5.1.
- throw new java::lang::NoClassDefFoundError (str);
- }
-
- if ((found->accflags & Modifier::PUBLIC) == Modifier::PUBLIC
- || (_Jv_ClassNameSamePackage (found->name,
- klass->name)))
- {
- pool->data[index].clazz = found;
- pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
- }
- else
- {
- throw new java::lang::IllegalAccessError (found->getName());
- }
- }
- break;
-
- case JV_CONSTANT_String:
- {
- jstring str;
- str = _Jv_NewStringUtf8Const (pool->data[index].utf8);
- pool->data[index].o = str;
- pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
- }
- break;
-
-
- case JV_CONSTANT_Fieldref:
- {
- _Jv_ushort class_index, name_and_type_index;
- _Jv_loadIndexes (&pool->data[index],
- class_index,
- name_and_type_index);
- jclass owner = (_Jv_ResolvePoolEntry (klass, class_index)).clazz;
-
- if (owner != klass)
- _Jv_InitClass (owner);
-
- _Jv_ushort name_index, type_index;
- _Jv_loadIndexes (&pool->data[name_and_type_index],
- name_index,
- type_index);
-
- _Jv_Utf8Const *field_name = pool->data[name_index].utf8;
- _Jv_Utf8Const *field_type_name = pool->data[type_index].utf8;
-
- // FIXME: The implementation of this function
- // (_Jv_FindClassFromSignature) will generate an instance of
- // _Jv_Utf8Const for each call if the field type is a class name
- // (Lxx.yy.Z;). This may be too expensive to do for each and
- // every fieldref being resolved. For now, we fix the problem by
- // only doing it when we have a loader different from the class
- // declaring the field.
-
- jclass field_type = 0;
-
- if (owner->loader != klass->loader)
- field_type = _Jv_FindClassFromSignature (field_type_name->data,
- klass->loader);
-
- _Jv_Field* the_field = 0;
-
- for (jclass cls = owner; cls != 0; cls = cls->getSuperclass ())
- {
- for (int i = 0; i < cls->field_count; i++)
- {
- _Jv_Field *field = &cls->fields[i];
- if (! _Jv_equalUtf8Consts (field->name, field_name))
- continue;
-
- if (_Jv_CheckAccess (klass, cls, field->flags))
- {
- /* resove the field using the class' own loader
- if necessary */
-
- if (!field->isResolved ())
- _Jv_ResolveField (field, cls->loader);
-
- if (field_type != 0 && field->type != field_type)
- throw new java::lang::LinkageError
- (JvNewStringLatin1
- ("field type mismatch with different loaders"));
-
- the_field = field;
- goto end_of_field_search;
- }
- else
- {
- java::lang::StringBuffer *sb
- = new java::lang::StringBuffer ();
- sb->append(klass->getName());
- sb->append(JvNewStringLatin1(": "));
- sb->append(cls->getName());
- sb->append(JvNewStringLatin1("."));
- sb->append(_Jv_NewStringUtf8Const (field_name));
- throw new java::lang::IllegalAccessError(sb->toString());
- }
- }
- }
-
- end_of_field_search:
- if (the_field == 0)
- {
- java::lang::StringBuffer *sb = new java::lang::StringBuffer();
- sb->append(JvNewStringLatin1("field "));
- sb->append(owner->getName());
- sb->append(JvNewStringLatin1("."));
- sb->append(_Jv_NewStringUTF(field_name->data));
- sb->append(JvNewStringLatin1(" was not found."));
- throw_incompatible_class_change_error(sb->toString());
- }
-
- pool->data[index].field = the_field;
- pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
- }
- break;
-
- case JV_CONSTANT_Methodref:
- case JV_CONSTANT_InterfaceMethodref:
- {
- _Jv_ushort class_index, name_and_type_index;
- _Jv_loadIndexes (&pool->data[index],
- class_index,
- name_and_type_index);
- jclass owner = (_Jv_ResolvePoolEntry (klass, class_index)).clazz;
-
- if (owner != klass)
- _Jv_InitClass (owner);
-
- _Jv_ushort name_index, type_index;
- _Jv_loadIndexes (&pool->data[name_and_type_index],
- name_index,
- type_index);
-
- _Jv_Utf8Const *method_name = pool->data[name_index].utf8;
- _Jv_Utf8Const *method_signature = pool->data[type_index].utf8;
-
- _Jv_Method *the_method = 0;
- jclass found_class = 0;
-
- // First search the class itself.
- the_method = _Jv_SearchMethodInClass (owner, klass,
- method_name, method_signature);
-
- if (the_method != 0)
- {
- found_class = owner;
- goto end_of_method_search;
- }
-
- // If we are resolving an interface method, search the
- // interface's superinterfaces (A superinterface is not an
- // interface's superclass - a superinterface is implemented by
- // the interface).
- if (pool->tags[index] == JV_CONSTANT_InterfaceMethodref)
- {
- _Jv_ifaces ifaces;
- ifaces.count = 0;
- ifaces.len = 4;
- ifaces.list = (jclass *) _Jv_Malloc (ifaces.len * sizeof (jclass *));
-
- _Jv_GetInterfaces (owner, &ifaces);
-
- for (int i = 0; i < ifaces.count; i++)
- {
- jclass cls = ifaces.list[i];
- the_method = _Jv_SearchMethodInClass (cls, klass, method_name,
- method_signature);
- if (the_method != 0)
- {
- found_class = cls;
- break;
- }
- }
-
- _Jv_Free (ifaces.list);
-
- if (the_method != 0)
- goto end_of_method_search;
- }
-
- // Finally, search superclasses.
- for (jclass cls = owner->getSuperclass (); cls != 0;
- cls = cls->getSuperclass ())
- {
- the_method = _Jv_SearchMethodInClass (cls, klass,
- method_name, method_signature);
- if (the_method != 0)
- {
- found_class = cls;
- break;
- }
- }
-
- end_of_method_search:
-
- // FIXME: if (cls->loader != klass->loader), then we
- // must actually check that the types of arguments
- // correspond. That is, for each argument type, and
- // the return type, doing _Jv_FindClassFromSignature
- // with either loader should produce the same result,
- // i.e., exactly the same jclass object. JVMS 5.4.3.3
-
- if (the_method == 0)
- {
- java::lang::StringBuffer *sb = new java::lang::StringBuffer();
- sb->append(JvNewStringLatin1("method "));
- sb->append(owner->getName());
- sb->append(JvNewStringLatin1("."));
- sb->append(_Jv_NewStringUTF(method_name->data));
- sb->append(JvNewStringLatin1(" was not found."));
- throw new java::lang::NoSuchMethodError (sb->toString());
- }
-
- int vtable_index = -1;
- if (pool->tags[index] != JV_CONSTANT_InterfaceMethodref)
- vtable_index = (jshort)the_method->index;
-
- pool->data[index].rmethod =
- _Jv_BuildResolvedMethod(the_method,
- found_class,
- (the_method->accflags & Modifier::STATIC) != 0,
- vtable_index);
- pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
- }
- break;
-
- }
-
- return pool->data[index];
-}
-
-// Find a method declared in the cls that is referenced from klass and
-// perform access checks.
-_Jv_Method *
-_Jv_SearchMethodInClass (jclass cls, jclass klass,
- _Jv_Utf8Const *method_name,
- _Jv_Utf8Const *method_signature)
-{
- using namespace java::lang::reflect;
-
- for (int i = 0; i < cls->method_count; i++)
- {
- _Jv_Method *method = &cls->methods[i];
- if ( (!_Jv_equalUtf8Consts (method->name,
- method_name))
- || (!_Jv_equalUtf8Consts (method->signature,
- method_signature)))
- continue;
-
- if (_Jv_CheckAccess (klass, cls, method->accflags))
- return method;
- else
- {
- java::lang::StringBuffer *sb = new java::lang::StringBuffer();
- sb->append(klass->getName());
- sb->append(JvNewStringLatin1(": "));
- sb->append(cls->getName());
- sb->append(JvNewStringLatin1("."));
- sb->append(_Jv_NewStringUTF(method_name->data));
- sb->append(_Jv_NewStringUTF(method_signature->data));
- throw new java::lang::IllegalAccessError (sb->toString());
- }
- }
- return 0;
-}
-
-// A helper for _Jv_PrepareClass. This adds missing `Miranda methods'
-// to a class.
-void
-_Jv_PrepareMissingMethods (jclass base2, jclass iface_class)
-{
- _Jv_InterpClass *base = reinterpret_cast<_Jv_InterpClass *> (base2);
- for (int i = 0; i < iface_class->interface_count; ++i)
- {
- for (int j = 0; j < iface_class->interfaces[i]->method_count; ++j)
- {
- _Jv_Method *meth = &iface_class->interfaces[i]->methods[j];
- // Don't bother with <clinit>.
- if (meth->name->data[0] == '<')
- continue;
- _Jv_Method *new_meth = _Jv_LookupDeclaredMethod (base, meth->name,
- meth->signature);
- if (! new_meth)
- {
- // We assume that such methods are very unlikely, so we
- // just reallocate the method array each time one is
- // found. This greatly simplifies the searching --
- // otherwise we have to make sure that each such method
- // found is really unique among all superinterfaces.
- int new_count = base->method_count + 1;
- _Jv_Method *new_m
- = (_Jv_Method *) _Jv_AllocBytes (sizeof (_Jv_Method)
- * new_count);
- memcpy (new_m, base->methods,
- sizeof (_Jv_Method) * base->method_count);
-
- // Add new method.
- new_m[base->method_count] = *meth;
- new_m[base->method_count].index = (_Jv_ushort) -1;
- new_m[base->method_count].accflags
- |= java::lang::reflect::Modifier::INVISIBLE;
-
- _Jv_MethodBase **new_im
- = (_Jv_MethodBase **) _Jv_AllocBytes (sizeof (_Jv_MethodBase *)
- * new_count);
- memcpy (new_im, base->interpreted_methods,
- sizeof (_Jv_MethodBase *) * base->method_count);
-
- base->methods = new_m;
- base->interpreted_methods = new_im;
- base->method_count = new_count;
- }
- }
-
- _Jv_PrepareMissingMethods (base, iface_class->interfaces[i]);
- }
-}
-
-void
-_Jv_PrepareClass(jclass klass)
-{
- using namespace java::lang::reflect;
-
- /*
- * The job of this function is to: 1) assign storage to fields, and 2)
- * build the vtable. static fields are assigned real memory, instance
- * fields are assigned offsets.
- *
- * NOTE: we have a contract with the garbage collector here. Static
- * reference fields must not be resolved, until after they have storage
- * assigned which is the check used by the collector to see if it
- * should indirect the static field reference and mark the object
- * pointed to.
- *
- * Most fields are resolved lazily (i.e. have their class-type
- * assigned) when they are accessed the first time by calling as part
- * of _Jv_ResolveField, which is allways called after _Jv_PrepareClass.
- * Static fields with initializers are resolved as part of this
- * function, as are fields with primitive types.
- */
-
- if (! _Jv_IsInterpretedClass (klass))
- return;
-
- if (klass->state >= JV_STATE_PREPARED)
- return;
-
- // Make sure super-class is linked. This involves taking a lock on
- // the super class, so we use the Java method resolveClass, which
- // will unlock it properly, should an exception happen. If there's
- // no superclass, do nothing -- Object will already have been
- // resolved.
-
- if (klass->superclass)
- java::lang::VMClassLoader::resolveClass (klass->superclass);
-
- _Jv_InterpClass *clz = (_Jv_InterpClass*)klass;
-
- /************ PART ONE: OBJECT LAYOUT ***************/
-
- // Compute the alignment for this type by searching through the
- // superclasses and finding the maximum required alignment. We
- // could consider caching this in the Class.
- int max_align = __alignof__ (java::lang::Object);
- jclass super = clz->superclass;
- while (super != NULL)
- {
- int num = JvNumInstanceFields (super);
- _Jv_Field *field = JvGetFirstInstanceField (super);
- while (num > 0)
- {
- int field_align = get_alignment_from_class (field->type);
- if (field_align > max_align)
- max_align = field_align;
- ++field;
- --num;
- }
- super = super->superclass;
- }
-
- int instance_size;
- int static_size = 0;
-
- // Although java.lang.Object is never interpreted, an interface can
- // have a null superclass. Note that we have to lay out an
- // interface because it might have static fields.
- if (clz->superclass)
- instance_size = clz->superclass->size();
- else
- instance_size = java::lang::Object::class$.size();
-
- for (int i = 0; i < clz->field_count; i++)
- {
- int field_size;
- int field_align;
-
- _Jv_Field *field = &clz->fields[i];
-
- if (! field->isRef ())
- {
- // it's safe to resolve the field here, since it's
- // a primitive class, which does not cause loading to happen.
- _Jv_ResolveField (field, clz->loader);
-
- field_size = field->type->size ();
- field_align = get_alignment_from_class (field->type);
- }
- else
- {
- field_size = sizeof (jobject);
- field_align = __alignof__ (jobject);
- }
-
-#ifndef COMPACT_FIELDS
- field->bsize = field_size;
-#endif
-
- if (field->flags & Modifier::STATIC)
- {
- /* this computes an offset into a region we'll allocate
- shortly, and then add this offset to the start address */
-
- static_size = ROUND (static_size, field_align);
- field->u.boffset = static_size;
- static_size += field_size;
- }
- else
- {
- instance_size = ROUND (instance_size, field_align);
- field->u.boffset = instance_size;
- instance_size += field_size;
- if (field_align > max_align)
- max_align = field_align;
- }
- }
-
- // Set the instance size for the class. Note that first we round it
- // to the alignment required for this object; this keeps us in sync
- // with our current ABI.
- instance_size = ROUND (instance_size, max_align);
- clz->size_in_bytes = instance_size;
-
- // allocate static memory
- if (static_size != 0)
- {
- char *static_data = (char*)_Jv_AllocBytes (static_size);
-
- memset (static_data, 0, static_size);
-
- for (int i = 0; i < clz->field_count; i++)
- {
- _Jv_Field *field = &clz->fields[i];
-
- if ((field->flags & Modifier::STATIC) != 0)
- {
- field->u.addr = static_data + field->u.boffset;
-
- if (clz->field_initializers[i] != 0)
- {
- _Jv_ResolveField (field, clz->loader);
- _Jv_InitField (0, clz, i);
- }
- }
- }
-
- // now we don't need the field_initializers anymore, so let the
- // collector get rid of it!
-
- clz->field_initializers = 0;
- }
-
- /************ PART TWO: VTABLE LAYOUT ***************/
-
- /* preparation: build the vtable stubs (even interfaces can)
- have code -- for static constructors. */
- for (int i = 0; i < clz->method_count; i++)
- {
- _Jv_MethodBase *imeth = clz->interpreted_methods[i];
-
- if ((clz->methods[i].accflags & Modifier::NATIVE) != 0)
- {
- // You might think we could use a virtual `ncode' method in
- // the _Jv_MethodBase and unify the native and non-native
- // cases. Well, we can't, because we don't allocate these
- // objects using `new', and thus they don't get a vtable.
- _Jv_JNIMethod *jnim = reinterpret_cast<_Jv_JNIMethod *> (imeth);
- clz->methods[i].ncode = jnim->ncode ();
- }
- else if (imeth != 0) // it could be abstract
- {
- _Jv_InterpMethod *im = reinterpret_cast<_Jv_InterpMethod *> (imeth);
- _Jv_VerifyMethod (im);
- clz->methods[i].ncode = im->ncode ();
-
- // Resolve ctable entries pointing to this method. See
- // _Jv_Defer_Resolution.
- void **code = (void **)imeth->deferred;
- while (code)
- {
- void **target = (void **)*code;
- *code = clz->methods[i].ncode;
- code = target;
- }
- }
- }
-
- if ((clz->accflags & Modifier::INTERFACE))
- {
- clz->state = JV_STATE_PREPARED;
- clz->notifyAll ();
- return;
- }
-
- // A class might have so-called "Miranda methods". This is a method
- // that is declared in an interface and not re-declared in an
- // abstract class. Some compilers don't emit declarations for such
- // methods in the class; this will give us problems since we expect
- // a declaration for any method requiring a vtable entry. We handle
- // this here by searching for such methods and constructing new
- // internal declarations for them. We only need to do this for
- // abstract classes.
- if ((clz->accflags & Modifier::ABSTRACT))
- _Jv_PrepareMissingMethods (clz, clz);
-
- clz->vtable_method_count = -1;
- _Jv_MakeVTable (clz);
-
- /* wooha! we're done. */
- clz->state = JV_STATE_PREPARED;
- clz->notifyAll ();
-}
-
-/** Do static initialization for fields with a constant initializer */
-void
-_Jv_InitField (jobject obj, jclass klass, int index)
-{
- using namespace java::lang::reflect;
-
- if (obj != 0 && klass == 0)
- klass = obj->getClass ();
-
- if (!_Jv_IsInterpretedClass (klass))
- return;
-
- _Jv_InterpClass *clz = (_Jv_InterpClass*)klass;
-
- _Jv_Field * field = (&clz->fields[0]) + index;
-
- if (index > clz->field_count)
- throw_internal_error ("field out of range");
-
- int init = clz->field_initializers[index];
- if (init == 0)
- return;
-
- _Jv_Constants *pool = &clz->constants;
- int tag = pool->tags[init];
-
- if (! field->isResolved ())
- throw_internal_error ("initializing unresolved field");
-
- if (obj==0 && ((field->flags & Modifier::STATIC) == 0))
- throw_internal_error ("initializing non-static field with no object");
-
- void *addr = 0;
-
- if ((field->flags & Modifier::STATIC) != 0)
- addr = (void*) field->u.addr;
- else
- addr = (void*) (((char*)obj) + field->u.boffset);
-
- switch (tag)
- {
- case JV_CONSTANT_String:
- {
- _Jv_MonitorEnter (clz);
- jstring str;
- str = _Jv_NewStringUtf8Const (pool->data[init].utf8);
- pool->data[init].string = str;
- pool->tags[init] = JV_CONSTANT_ResolvedString;
- _Jv_MonitorExit (clz);
- }
- /* fall through */
-
- case JV_CONSTANT_ResolvedString:
- if (! (field->type == &StringClass
- || field->type == &java::lang::Class::class$))
- throw_class_format_error ("string initialiser to non-string field");
-
- *(jstring*)addr = pool->data[init].string;
- break;
-
- case JV_CONSTANT_Integer:
- {
- int value = pool->data[init].i;
-
- if (field->type == JvPrimClass (boolean))
- *(jboolean*)addr = (jboolean)value;
-
- else if (field->type == JvPrimClass (byte))
- *(jbyte*)addr = (jbyte)value;
-
- else if (field->type == JvPrimClass (char))
- *(jchar*)addr = (jchar)value;
-
- else if (field->type == JvPrimClass (short))
- *(jshort*)addr = (jshort)value;
-
- else if (field->type == JvPrimClass (int))
- *(jint*)addr = (jint)value;
-
- else
- throw_class_format_error ("erroneous field initializer");
- }
- break;
-
- case JV_CONSTANT_Long:
- if (field->type != JvPrimClass (long))
- throw_class_format_error ("erroneous field initializer");
-
- *(jlong*)addr = _Jv_loadLong (&pool->data[init]);
- break;
-
- case JV_CONSTANT_Float:
- if (field->type != JvPrimClass (float))
- throw_class_format_error ("erroneous field initializer");
-
- *(jfloat*)addr = pool->data[init].f;
- break;
-
- case JV_CONSTANT_Double:
- if (field->type != JvPrimClass (double))
- throw_class_format_error ("erroneous field initializer");
-
- *(jdouble*)addr = _Jv_loadDouble (&pool->data[init]);
- break;
-
- default:
- throw_class_format_error ("erroneous field initializer");
- }
-}
-
-template<typename T>
-struct aligner
-{
- T field;
-};
-
-#define ALIGNOF(TYPE) (__alignof__ (((aligner<TYPE> *) 0)->field))
-
-// This returns the alignment of a type as it would appear in a
-// structure. This can be different from the alignment of the type
-// itself. For instance on x86 double is 8-aligned but struct{double}
-// is 4-aligned.
-static int
-get_alignment_from_class (jclass klass)
-{
- if (klass == JvPrimClass (byte))
- return ALIGNOF (jbyte);
- else if (klass == JvPrimClass (short))
- return ALIGNOF (jshort);
- else if (klass == JvPrimClass (int))
- return ALIGNOF (jint);
- else if (klass == JvPrimClass (long))
- return ALIGNOF (jlong);
- else if (klass == JvPrimClass (boolean))
- return ALIGNOF (jboolean);
- else if (klass == JvPrimClass (char))
- return ALIGNOF (jchar);
- else if (klass == JvPrimClass (float))
- return ALIGNOF (jfloat);
- else if (klass == JvPrimClass (double))
- return ALIGNOF (jdouble);
- else
- return ALIGNOF (jobject);
-}
-
-
-inline static unsigned char*
-skip_one_type (unsigned char* ptr)
-{
- int ch = *ptr++;
-
- while (ch == '[')
- {
- ch = *ptr++;
- }
-
- if (ch == 'L')
- {
- do { ch = *ptr++; } while (ch != ';');
- }
-
- return ptr;
-}
-
-static ffi_type*
-get_ffi_type_from_signature (unsigned char* ptr)
-{
- switch (*ptr)
- {
- case 'L':
- case '[':
- return &ffi_type_pointer;
- break;
-
- case 'Z':
- // On some platforms a bool is a byte, on others an int.
- if (sizeof (jboolean) == sizeof (jbyte))
- return &ffi_type_sint8;
- else
- {
- JvAssert (sizeof (jbyte) == sizeof (jint));
- return &ffi_type_sint32;
- }
- break;
-
- case 'B':
- return &ffi_type_sint8;
- break;
-
- case 'C':
- return &ffi_type_uint16;
- break;
-
- case 'S':
- return &ffi_type_sint16;
- break;
-
- case 'I':
- return &ffi_type_sint32;
- break;
-
- case 'J':
- return &ffi_type_sint64;
- break;
-
- case 'F':
- return &ffi_type_float;
- break;
-
- case 'D':
- return &ffi_type_double;
- break;
-
- case 'V':
- return &ffi_type_void;
- break;
- }
-
- throw_internal_error ("unknown type in signature");
-}
-
-/* this function yields the number of actual arguments, that is, if the
- * function is non-static, then one is added to the number of elements
- * found in the signature */
-
-int
-_Jv_count_arguments (_Jv_Utf8Const *signature,
- jboolean staticp)
-{
- unsigned char *ptr = (unsigned char*) signature->data;
- int arg_count = staticp ? 0 : 1;
-
- /* first, count number of arguments */
-
- // skip '('
- ptr++;
-
- // count args
- while (*ptr != ')')
- {
- ptr = skip_one_type (ptr);
- arg_count += 1;
- }
-
- return arg_count;
-}
-
-/* This beast will build a cif, given the signature. Memory for
- * the cif itself and for the argument types must be allocated by the
- * caller.
- */
-
-static int
-init_cif (_Jv_Utf8Const* signature,
- int arg_count,
- jboolean staticp,
- ffi_cif *cif,
- ffi_type **arg_types,
- ffi_type **rtype_p)
-{
- unsigned char *ptr = (unsigned char*) signature->data;
-
- int arg_index = 0; // arg number
- int item_count = 0; // stack-item count
-
- // setup receiver
- if (!staticp)
- {
- arg_types[arg_index++] = &ffi_type_pointer;
- item_count += 1;
- }
-
- // skip '('
- ptr++;
-
- // assign arg types
- while (*ptr != ')')
- {
- arg_types[arg_index++] = get_ffi_type_from_signature (ptr);
-
- if (*ptr == 'J' || *ptr == 'D')
- item_count += 2;
- else
- item_count += 1;
-
- ptr = skip_one_type (ptr);
- }
-
- // skip ')'
- ptr++;
- ffi_type *rtype = get_ffi_type_from_signature (ptr);
-
- ptr = skip_one_type (ptr);
- if (ptr != (unsigned char*)signature->data + signature->length)
- throw_internal_error ("did not find end of signature");
-
- if (ffi_prep_cif (cif, FFI_DEFAULT_ABI,
- arg_count, rtype, arg_types) != FFI_OK)
- throw_internal_error ("ffi_prep_cif failed");
-
- if (rtype_p != NULL)
- *rtype_p = rtype;
-
- return item_count;
-}
-
-#if FFI_NATIVE_RAW_API
-# define FFI_PREP_RAW_CLOSURE ffi_prep_raw_closure
-# define FFI_RAW_SIZE ffi_raw_size
-#else
-# define FFI_PREP_RAW_CLOSURE ffi_prep_java_raw_closure
-# define FFI_RAW_SIZE ffi_java_raw_size
-#endif
-
-/* we put this one here, and not in interpret.cc because it
- * calls the utility routines _Jv_count_arguments
- * which are static to this module. The following struct defines the
- * layout we use for the stubs, it's only used in the ncode method. */
-
-typedef struct {
- ffi_raw_closure closure;
- ffi_cif cif;
- ffi_type *arg_types[0];
-} ncode_closure;
-
-typedef void (*ffi_closure_fun) (ffi_cif*,void*,ffi_raw*,void*);
-
-void *
-_Jv_InterpMethod::ncode ()
-{
- using namespace java::lang::reflect;
-
- if (self->ncode != 0)
- return self->ncode;
-
- jboolean staticp = (self->accflags & Modifier::STATIC) != 0;
- int arg_count = _Jv_count_arguments (self->signature, staticp);
-
- ncode_closure *closure =
- (ncode_closure*)_Jv_AllocBytes (sizeof (ncode_closure)
- + arg_count * sizeof (ffi_type*));
-
- init_cif (self->signature,
- arg_count,
- staticp,
- &closure->cif,
- &closure->arg_types[0],
- NULL);
-
- ffi_closure_fun fun;
-
- args_raw_size = FFI_RAW_SIZE (&closure->cif);
-
- JvAssert ((self->accflags & Modifier::NATIVE) == 0);
-
- if ((self->accflags & Modifier::SYNCHRONIZED) != 0)
- {
- if (staticp)
- fun = (ffi_closure_fun)&_Jv_InterpMethod::run_synch_class;
- else
- fun = (ffi_closure_fun)&_Jv_InterpMethod::run_synch_object;
- }
- else
- {
- if (staticp)
- fun = (ffi_closure_fun)&_Jv_InterpMethod::run_class;
- else
- fun = (ffi_closure_fun)&_Jv_InterpMethod::run_normal;
- }
-
- FFI_PREP_RAW_CLOSURE (&closure->closure,
- &closure->cif,
- fun,
- (void*)this);
-
- self->ncode = (void*)closure;
- return self->ncode;
-}
-
-void *
-_Jv_JNIMethod::ncode ()
-{
- using namespace java::lang::reflect;
-
- if (self->ncode != 0)
- return self->ncode;
-
- jboolean staticp = (self->accflags & Modifier::STATIC) != 0;
- int arg_count = _Jv_count_arguments (self->signature, staticp);
-
- ncode_closure *closure =
- (ncode_closure*)_Jv_AllocBytes (sizeof (ncode_closure)
- + arg_count * sizeof (ffi_type*));
-
- ffi_type *rtype;
- init_cif (self->signature,
- arg_count,
- staticp,
- &closure->cif,
- &closure->arg_types[0],
- &rtype);
-
- ffi_closure_fun fun;
-
- args_raw_size = FFI_RAW_SIZE (&closure->cif);
-
- // Initialize the argument types and CIF that represent the actual
- // underlying JNI function.
- int extra_args = 1;
- if ((self->accflags & Modifier::STATIC))
- ++extra_args;
- jni_arg_types = (ffi_type **) _Jv_Malloc ((extra_args + arg_count)
- * sizeof (ffi_type *));
- int offset = 0;
- jni_arg_types[offset++] = &ffi_type_pointer;
- if ((self->accflags & Modifier::STATIC))
- jni_arg_types[offset++] = &ffi_type_pointer;
- memcpy (&jni_arg_types[offset], &closure->arg_types[0],
- arg_count * sizeof (ffi_type *));
-
- if (ffi_prep_cif (&jni_cif, _Jv_platform_ffi_abi,
- extra_args + arg_count, rtype,
- jni_arg_types) != FFI_OK)
- throw_internal_error ("ffi_prep_cif failed for JNI function");
-
- JvAssert ((self->accflags & Modifier::NATIVE) != 0);
-
- // FIXME: for now we assume that all native methods for
- // interpreted code use JNI.
- fun = (ffi_closure_fun) &_Jv_JNIMethod::call;
-
- FFI_PREP_RAW_CLOSURE (&closure->closure,
- &closure->cif,
- fun,
- (void*) this);
-
- self->ncode = (void *) closure;
- return self->ncode;
-}
-
-
-/* A _Jv_ResolvedMethod is what is put in the constant pool for a
- * MethodRef or InterfacemethodRef. */
-static _Jv_ResolvedMethod*
-_Jv_BuildResolvedMethod (_Jv_Method* method,
- jclass klass,
- jboolean staticp,
- jint vtable_index)
-{
- int arg_count = _Jv_count_arguments (method->signature, staticp);
-
- _Jv_ResolvedMethod* result = (_Jv_ResolvedMethod*)
- _Jv_AllocBytes (sizeof (_Jv_ResolvedMethod)
- + arg_count*sizeof (ffi_type*));
-
- result->stack_item_count
- = init_cif (method->signature,
- arg_count,
- staticp,
- &result->cif,
- &result->arg_types[0],
- NULL);
-
- result->vtable_index = vtable_index;
- result->method = method;
- result->klass = klass;
-
- return result;
-}
-
-
-static void
-throw_class_format_error (jstring msg)
-{
- throw (msg
- ? new java::lang::ClassFormatError (msg)
- : new java::lang::ClassFormatError);
-}
-
-static void
-throw_class_format_error (char *msg)
-{
- throw_class_format_error (JvNewStringLatin1 (msg));
-}
-
-static void
-throw_internal_error (char *msg)
-{
- throw new java::lang::InternalError (JvNewStringLatin1 (msg));
-}
-
-
-#endif /* INTERPRETER */
diff --git a/libjava/testsuite/Makefile.in b/libjava/testsuite/Makefile.in
index 129d25c6471..21c86dd9d01 100644
--- a/libjava/testsuite/Makefile.in
+++ b/libjava/testsuite/Makefile.in
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
-# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
diff --git a/libjava/testsuite/lib/libjava.exp b/libjava/testsuite/lib/libjava.exp
index 31937c3a1e0..ad76f8b0412 100644
--- a/libjava/testsuite/lib/libjava.exp
+++ b/libjava/testsuite/lib/libjava.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation
+# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
load_lib "libgloss.exp"
@@ -495,7 +495,21 @@ proc gcj_invoke {program expectFile ld_library_additions} {
# Invoke a program and check its output. EXECUTABLE is the program;
# ARGS are the arguments to the program. Returns 1 if tests passed
# (or things were left untested), 0 otherwise.
-proc libjava_invoke {errname testName optName executable inpfile resultfile args} {
+proc libjava_invoke {errname testName optName executable inpfile resultfile
+ ld_library_additions args} {
+ global env
+ set lib_path $env(LD_LIBRARY_PATH)
+
+ set newval .
+ if {[llength $ld_library_additions] > 0} {
+ append newval :[join $ld_library_additions :]
+ }
+
+ append newval :$lib_path
+
+ setenv LD_LIBRARY_PATH $newval
+
+ verbose "LD_LIBRARY_PATH=$env(LD_LIBRARY_PATH)"
upvar $optName opts
if {[info exists opts(no-exec)]} {
@@ -512,6 +526,10 @@ proc libjava_invoke {errname testName optName executable inpfile resultfile args
set result [libjava_load $executable $args "$inpfile"]
set status [lindex $result 0]
set output [lindex $result 1]
+
+ # Restore LD_LIBRARY_PATH setting.
+ setenv LD_LIBRARY_PATH $lib_path
+
if {[info exists opts(xfail-exec)]} then {
setup_xfail *-*-*
}
@@ -658,7 +676,7 @@ proc test_libjava_from_source { options srcfile compile_args inpfile resultfile
set opts(xfail-output) x
}
if {[libjava_invoke $errname "source compiled test" opts $executable \
- $inpfile $resultfile]} {
+ $inpfile $resultfile ""]} {
# Everything ok, so clean up.
eval gcj_cleanup $removeList
}
@@ -796,7 +814,7 @@ proc test_libjava_from_javac { options srcfile compile_args inpfile resultfile e
# program; in this case we want to skip the test.
if {$INTERPRETER == "yes" && $gij != "gij"} {
libjava_invoke $errname "gij test" opts $gij \
- $inpfile $resultfile $main_name
+ $inpfile $resultfile "" $main_name
}
# Initial arguments.
@@ -859,7 +877,7 @@ proc test_libjava_from_javac { options srcfile compile_args inpfile resultfile e
set opts(xfail-output) x
}
if {[libjava_invoke $errname "bytecode->native test" opts $executable \
- $inpfile $resultfile]} {
+ $inpfile $resultfile ""]} {
# Everything ok, so clean up.
eval gcj_cleanup $removeList
}
diff --git a/libjava/testsuite/libjava.compile/compile.exp b/libjava/testsuite/libjava.compile/compile.exp
index 9eba0d4ad77..6f1937435d0 100644
--- a/libjava/testsuite/libjava.compile/compile.exp
+++ b/libjava/testsuite/libjava.compile/compile.exp
@@ -11,8 +11,8 @@ foreach x $srcfiles {
}
lappend args no-exec
- test_libjava "" "$x" "" "" "" $args
- test_libjava "" "$x" "-O3" "" "" $args
+ test_libjava "" "$x" "-findirect-dispatch " "" "" $args
+ test_libjava "" "$x" "-findirect-dispatch -O3" "" "" $args
}
# Local Variables:
diff --git a/libjava/testsuite/libjava.jacks/jacks.exp b/libjava/testsuite/libjava.jacks/jacks.exp
index 353859ce803..679c7f58408 100644
--- a/libjava/testsuite/libjava.jacks/jacks.exp
+++ b/libjava/testsuite/libjava.jacks/jacks.exp
@@ -28,7 +28,12 @@ proc gcj_jacks_write {filename} {
puts $fd "set JAVA_CLASSPATH \"$libgcj_jar\""
puts $fd "set JAVAC_FLAGS [list $rest]"
puts $fd "set JAVA [list [libjava_find_gij]]"
- puts $fd "set JAVA_FLAGS \"\""
+
+ # Without an explicit limit on the heap size, tests depending on
+ # an OutOfMemoryError (e.g. "15.9.4-runtime-creation-2") can result
+ # in a lot of unnecessary thrashing.
+ puts $fd "set JAVA_FLAGS \"-mx=64m\""
+
puts $fd "set JAVAC_ENCODING_FLAG --encoding="
puts $fd "set tcltest::testConstraints(encoding) 1"
puts $fd "set tcltest::testConstraints(gcj) 1"
diff --git a/libjava/testsuite/libjava.jacks/jacks.xfail b/libjava/testsuite/libjava.jacks/jacks.xfail
index ed55f1bae5b..2c84bb68790 100644
--- a/libjava/testsuite/libjava.jacks/jacks.xfail
+++ b/libjava/testsuite/libjava.jacks/jacks.xfail
@@ -1,28 +1,34 @@
-14.14-plain-2
-14.14-plain-5
+12.4.1-runtime-1
+12.4.1-runtime-2
+12.4.1-runtime-3
+12.4.1-runtime-4
+13.1-runtime-constant-1
+13.1-runtime-constant-3
+13.1-runtime-field-1
+13.1-runtime-method-5
+13.1-runtime-method-6
+13.4.8-constant-runtime-1
+13.4.8-constant-runtime-2
+14-runtime-jump-1
+14-runtime-jump-2
14.14-label-1
14.14-label-2
14.14-label-5
14.14-label-8
-14.7-shadow-3
-14.3-1
-14.3-scope-2
-14.3-scope-4
-14.3-scope-5
-14.3-scope-9
-14.3-scope-11
-14.4.2-shadow-5
-14.4.2-shadow-6
-14.4.2-shadow-7
-14.4.2-shadow-9
-14.19-shadow-4
-14.19-shadow-5
-14.19-shadow-6
-14.19-shadow-7
+14.14-plain-2
+14.14-plain-5
+14.17-null-1
+14.17-null-3
+14.17-null-4
+14.17-null-5
14.19-shadow-12
14.19-shadow-13
14.19-shadow-14
14.19-shadow-15
+14.19-shadow-4
+14.19-shadow-5
+14.19-shadow-6
+14.19-shadow-7
14.19.exception-13
14.19.exception-14
14.19.exception-15
@@ -31,39 +37,14 @@
14.19.exception-22
14.19.exception-23
14.19.exception-24
+14.20-abrupt-10
+14.20-abrupt-14
+14.20-abrupt-2
+14.20-abrupt-6
14.20-block-4
14.20-block-9
-14.20-local-2
-14.20-label-5
-14.20-label-8
-14.20-label-9
-14.20-label-10
-14.20-label-11
-14.20-label-12
-14.20-label-13
-14.20-label-14
-14.20-label-15
-14.20-switch-8
-14.20-switch-14
-14.20-switch-17
-14.20-switch-18
-14.20-switch-19
-14.20-switch-20
-14.20-switch-21
-14.20-switch-22
-14.20-switch-23
-14.20-switch-24
-14.20-while-4
-14.20-while-12
-14.20-while-13
-14.20-while-14
-14.20-while-15
-14.20-while-16
-14.20-while-17
-14.20-while-18
-14.20-while-19
-14.20-do-6
-14.20-do-9
+14.20-catch-15
+14.20-catch-17
14.20-do-10
14.20-do-11
14.20-do-12
@@ -88,8 +69,8 @@
14.20-do-31
14.20-do-32
14.20-do-33
-14.20-for-4
-14.20-for-8
+14.20-do-6
+14.20-do-9
14.20-for-15
14.20-for-16
14.20-for-17
@@ -98,187 +79,340 @@
14.20-for-20
14.20-for-21
14.20-for-22
-14.20-abrupt-2
-14.20-abrupt-6
-14.20-abrupt-10
-14.20-abrupt-14
+14.20-for-4
+14.20-for-8
+14.20-for-update-1
+14.20-if-6
+14.20-label-10
+14.20-label-11
+14.20-label-12
+14.20-label-13
+14.20-label-14
+14.20-label-15
+14.20-label-5
+14.20-label-8
+14.20-label-9
+14.20-local-2
+14.20-switch-14
+14.20-switch-17
+14.20-switch-18
+14.20-switch-19
+14.20-switch-20
+14.20-switch-21
+14.20-switch-22
+14.20-switch-23
+14.20-switch-24
+14.20-switch-8
14.20-synchronized-3
-14.20-try-3
-14.20-try-9
14.20-try-14
14.20-try-18
14.20-try-22
14.20-try-27
+14.20-try-3
14.20-try-31
-14.20-catch-15
-14.20-catch-17
-14.20-if-6
-14.20-for-update-1
-8.1.1.1-default-abstract-11
-8.1.1.1-default-abstract-13
-8.1.1.1-default-abstract-15
-8.1.1.1-default-abstract-19
-8.1.1.1-default-abstract-21
-8.1.1.1-default-abstract-25
-8.1.2-static-1
-8.1.2-static-11
-8.1.2-static-16
-8.1.2-enclosing-4
-8.1.2-enclosing-5
-8.1.3-object-3
-8.1.3-superclass-5
-8.1.3-superclass-6
-8.8.5.1-example-1
-8.8.5.1-example-3
-8.8.5.1-qualified-1
-8.8.5.1-qualified-2
-8.8.5.1-qualified-3
-8.8.5.1-qualified-4
-8.8.5.1-qualified-10
-8.8.5.1-qualified-11
-8.8.5.1-qualified-12
-8.8.5.1-qualified-13
-8.8.5.1-qualified-15
-8.8.7-inaccessible-default-constructor-toplevel-2
-8.8.7-accessible-default-constructor-inner-18
-8.8.7-accessible-default-constructor-inner-26
-8.3-inheritance-1
-8.3-inheritance-2
-8.3-inheritance-3
-8.3-inheritance-5
-8.3-inheritance-6
-8.3.1.2-final-2
-8.3.1.2-final-17
-8.3.1.2-final-19
-8.3.1.2-final-21
-8.3.1.2-final-24
-8.3.1.2-final-27
-8.3.1.2-final-28
-8.3.1.2-final-29
-8.3.2-abrupt-3
-8.3.2-abrupt-5
-8.3.2-abrupt-6
-8.3.2-abrupt-7
-8.3.2.2-super-2
-8.3.2.3-illegal-forward-instance-1
-8.3.2.3-illegal-forward-instance-2
-8.3.2.3-illegal-forward-instance-3
-8.3.2.3-illegal-forward-instance-4
-8.3.2.3-illegal-forward-instance-5
-8.3.2.3-illegal-forward-instance-6
-8.3.2.3-illegal-forward-instance-7
-8.3.2.3-illegal-forward-instance-8
-8.3.2.3-illegal-forward-instance-9
-8.3.2.3-legal-forward-instance-11
-8.3.2.3-illegal-forward-static-1
-8.3.2.3-illegal-forward-static-2
-8.3.2.3-illegal-forward-static-3
-8.3.2.3-illegal-forward-static-4
-8.3.2.3-illegal-forward-static-5
-8.3.2.3-illegal-forward-static-6
-8.3.2.3-illegal-forward-static-7
-8.3.2.3-illegal-forward-static-8
-8.3.2.3-illegal-forward-static-9
-8.3.2.3-illegal-forward-static-10
-8.6-checked-exception-2
-8.6-checked-exception-4
-8.6-checked-exception-5
-8.6-checked-exception-6
-8.6-checked-exception-8
-8.6-checked-exception-10
-8.6-checked-exception-11
-8.6-checked-exception-12
-8.6-complete-1
-8.6-complete-4
-8.6-complete-5
-8.6-abrupt-1
-8.6-abrupt-4
-8.5-inheritance-1
-8.5-inheritance-2
-8.5-inheritance-3
-8.5-inheritance-6
-8.5.2-non-static-member-usage-2
-8.4.6-inheritance-1
-8.4.6-inheritance-2
-8.4.6.2-hiding-3
-8.4.6.4-multiple-3
-8.4.6.4-multiple-4
-8.4.6.4-multiple-7
-8.4.6.4-multiple-8
-8.4.6.4-abstract-1
-8.4.6.4-abstract-2
-8.4.6.4-abstract-10
-8.4.6.1-override-3
-8.4.6.3-modifier-8
-8.4.6.3-modifier-9
-8.4.6.3-modifier-10
-8.4.6.3-modifier-11
-8.4.6.3-modifier-12
-8.4.6.3-modifier-13
-8.4.6.3-default-4
-8.4.6.3-default-6
-8.4.6.3-default-10
-8.4.6.3-default-12
-8.4.6.3-default-14
-8.4.6.3-signature-4
-8.7-abrupt-1
-8.7-complete-1
-8.7-complete-3
-5.1.2-bts-1
-5.1.2-bts-2
-5.1.2-bts-3
-5.1.2-bts-4
-5.1.2-bts-5
-5.1.2-bti-1
-5.1.2-bti-3
-5.1.2-bti-5
-5.1.2-btl-1
-5.1.2-btl-3
-5.1.2-btl-5
-5.1.2-btf-1
-5.1.2-btf-3
-5.1.2-btf-5
-5.1.2-btd-1
-5.1.2-btd-3
-5.1.2-btd-5
-5.1.2-sti-1
-5.1.2-sti-5
-5.1.2-stl-1
-5.1.2-stl-3
-5.1.2-stl-5
-5.1.2-stf-1
-5.1.2-stf-3
-5.1.2-stf-5
-5.1.2-std-3
-5.1.2-std-5
-16-static-1
-16-static-2
+14.20-try-9
+14.20-while-12
+14.20-while-13
+14.20-while-14
+14.20-while-15
+14.20-while-16
+14.20-while-17
+14.20-while-18
+14.20-while-19
+14.20-while-4
+14.3-1
+14.3-scope-10
+14.3-scope-2
+14.3-scope-4
+14.3-scope-5
+14.3-scope-9
+14.3.1-runtime-3
+14.4.2-shadow-5
+14.4.2-shadow-6
+14.4.2-shadow-7
+14.4.2-shadow-9
+14.7-shadow-3
+15.11.1-ambiguous-2
+15.11.1-ambiguous-3
+15.11.1-explicit-constructor-3
+15.11.1-runtime-static-1
+15.11.1-runtime-static-2
+15.11.1-runtime-static-3
+15.11.1-runtime-static-4
+15.11.2-explicit-constructor-2
+15.11.2-meaning-10
+15.11.2-meaning-11
+15.11.2-meaning-13
+15.11.2-meaning-14
+15.11.2-meaning-17
+15.11.2-meaning-3
+15.11.2-meaning-6
+15.11.2-meaning-8
+15.11.2-meaning-9
+15.11.2-runtime-1
+15.11.2-runtime-2
+15.11.2-syntax-1
+15.12.1-syntax-1
+15.12.1-type-14
+15.12.2.1-accessibility-method-3
+15.12.2.1-accessibility-method-5
+15.12.2.1-accessibility-method-6
+15.12.2.2-ambiguous-10
+15.12.2.2-ambiguous-12
+15.12.2.2-ambiguous-14
+15.12.2.2-ambiguous-17
+15.12.2.2-ambiguous-18
+15.12.2.2-ambiguous-21
+15.12.2.2-ambiguous-25
+15.12.2.2-ambiguous-27
+15.12.2.2-ambiguous-3
+15.12.2.2-ambiguous-6
+15.12.2.2-ambiguous-9
+15.12.3-abstract-1
+15.12.3-abstract-2
+15.12.3-abstract-3
+15.12.3-explicit-constructor-10
+15.12.3-explicit-constructor-3
+15.12.3-explicit-constructor-4
+15.12.3-explicit-constructor-5
+15.12.3-explicit-constructor-7
+15.12.3-runtime-mode-1
+15.12.3-runtime-mode-2
+15.12.3-runtime-mode-3
+15.12.3-runtime-mode-4
+15.12.3-runtime-mode-6
+15.12.4.1-runtime-static-1
+15.12.4.1-runtime-static-2
+15.12.4.1-runtime-super-1
+15.12.4.1-runtime-super-2
+15.13-anon-1
+15.14-runtime-3
+15.14-runtime-4
+15.14.1-final-2
+15.14.1-final-3
+15.14.2-final-2
+15.14.2-final-3
+15.15-precedence-5
+15.15-runtime-3
+15.15-runtime-4
+15.15.1-final-2
+15.15.1-final-3
+15.15.2-final-2
+15.15.2-final-3
+15.16-semantic-5
+15.16-value-1
+15.16-value-2
+15.17-mod-3
+15.17-mod-4
+15.17.3-assoc-2
+15.17.3-double-1
+15.17.3-double-10
+15.17.3-double-11
+15.17.3-double-12
+15.17.3-double-13
+15.17.3-double-14
+15.17.3-double-2
+15.17.3-double-3
+15.17.3-double-4
+15.17.3-double-5
+15.17.3-double-6
+15.17.3-double-7
+15.17.3-double-8
+15.17.3-double-9
+15.17.3-float-1
+15.17.3-float-10
+15.17.3-float-11
+15.17.3-float-12
+15.17.3-float-13
+15.17.3-float-14
+15.17.3-float-2
+15.17.3-float-3
+15.17.3-float-4
+15.17.3-float-5
+15.17.3-float-6
+15.17.3-float-7
+15.17.3-float-8
+15.17.3-float-9
+15.18.1-double-1
+15.18.1-double-10
+15.18.1-double-11
+15.18.1-double-12
+15.18.1-double-13
+15.18.1-double-2
+15.18.1-double-3
+15.18.1-double-4
+15.18.1-double-5
+15.18.1-double-6
+15.18.1-double-7
+15.18.1-double-8
+15.18.1-double-9
+15.18.1-float-1
+15.18.1-float-10
+15.18.1-float-11
+15.18.1-float-12
+15.18.1-float-2
+15.18.1-float-3
+15.18.1-float-4
+15.18.1-float-5
+15.18.1-float-6
+15.18.1-float-7
+15.18.1-float-8
+15.18.1-float-9
+15.18.1-valid-1
+15.18.1.1-runtime-5
+15.20-2-runtime-1
+15.21-assoc-7
+15.21-assoc-8
+15.21-equal-3
+15.21-type-17
+15.21-type-21
+15.21-type-22
+15.21-type-23
+15.21-type-24
+15.21-type-25
+15.21-type-30
+15.21-type-7
+15.25-runtime-1
+15.26.2-add-12
+15.26.2-and-10
+15.26.2-and-12
+15.26.2-div-12
+15.26.2-left-shift-12
+15.26.2-mod-12
+15.26.2-mult-12
+15.26.2-or-10
+15.26.2-or-12
+15.26.2-signed-right-shift-12
+15.26.2-sub-12
+15.26.2-unsigned-right-shift-12
+15.26.2-xor-10
+15.26.2-xor-12
+15.28-cast-simple-name-1
+15.28-cast-simple-name-2
+15.28-cast-simple-name-3
+15.28-instanceof-3
+15.28-notstring-1
+15.28-null-1
+15.28-null-3
+15.28-primitive-15
+15.28-primitive-16
+15.28-primitive-17
+15.28-primitive-9
+15.28-qualified-name-10
+15.28-qualified-name-5
+15.28-qualified-name-6
+15.28-qualified-name-7
+15.28-qualified-name-8
+15.28-qualified-name-9
+15.28-qualified-namestr-7
+15.28-qualified-namestr-8
+15.28-qualified-namestr-9
+15.28-simple-name-6
+15.28-simple-name-8
+15.28-simple-namestr-1
+15.28-simple-namestr-2
+15.28-simple-namestr-3
+15.28-simple-namestr-4
+15.28-string-11
+15.28-string-13
+15.28-string-15
+15.28-string-16
+15.28-string-17
+15.28-string-18
+15.28-string-2
+15.28-string-5
+15.28-string-9
+15.28-uninitialized-simple-name-3
+15.8.2-synthetic-1
+15.8.2-type-11
+15.8.2-type-12
+15.8.2-type-13
+15.8.2-type-14
+15.8.5-field-expression-6
+15.8.5-method-expression-8
+15.8.5-variable-5
+15.8.5-variable-6
+15.8.5-variable-7
+15.8.5-variable-8
+15.9-runtime-numcalls-1
+15.9.1-qualified-anonymous-10
+15.9.1-qualified-anonymous-12
+15.9.1-qualified-anonymous-13
+15.9.1-qualified-anonymous-14
+15.9.1-qualified-anonymous-17
+15.9.1-qualified-anonymous-18
+15.9.1-qualified-anonymous-2
+15.9.1-qualified-anonymous-20
+15.9.1-qualified-anonymous-22
+15.9.1-qualified-anonymous-26
+15.9.1-qualified-anonymous-28
+15.9.1-qualified-anonymous-4
+15.9.1-qualified-anonymous-5
+15.9.1-qualified-concrete-10
+15.9.1-qualified-concrete-12
+15.9.1-qualified-concrete-14
+15.9.1-qualified-concrete-16
+15.9.1-qualified-concrete-20
+15.9.1-qualified-concrete-4
+15.9.1-qualified-concrete-5
+15.9.1-unqualified-anonymous-12
+15.9.1-unqualified-anonymous-14
+15.9.1-unqualified-anonymous-15
+15.9.1-unqualified-anonymous-2
+15.9.1-unqualified-anonymous-23
+15.9.1-unqualified-anonymous-24
+15.9.1-unqualified-anonymous-26
+15.9.1-unqualified-anonymous-27
+15.9.1-unqualified-anonymous-4
+15.9.1-unqualified-anonymous-5
+15.9.1-unqualified-concrete-10
+15.9.1-unqualified-concrete-14
+15.9.1-unqualified-concrete-15
+15.9.1-unqualified-concrete-2
+15.9.1-unqualified-concrete-4
+15.9.1-unqualified-concrete-5
+15.9.3-choosing-4
+15.9.4-runtime-creation-1
+15.9.4-runtime-creation-2
+15.9.4-runtime-creation-5
+15.9.5.1-exception-1
+15.9.5.1-exception-3
+15.9.5.1-exception-4
+15.9.5.1-superconstructor-2
+15.9.5.1-superconstructor-4
+15.9.5.1-superconstructor-7
+15.9.5.1-superconstructor-8
16-instance-5
16-instance-6
16-instance-7
-16.5-anonymous-3
-16.8-constructor-6
-16.8-constructor-7
-16.8-constructor-8
-16.1.7-simple-definite-assignment-fail-8
-16.1.7-simple-definite-assignment-fail-9
+16-static-1
+16-static-2
+16.1.2-definite-unassignment-fail-6
+16.1.3-definite-unassignment-fail-6
+16.1.5-definite-unassignment-pass-4
+16.1.5-definite-unassignment-pass-7
+16.1.5-not-assignable-7
+16.1.5-not-assignable-8
16.1.7-compound-definite-assignment-fail-8
16.1.7-compound-definite-assignment-fail-9
-16.1.7-simple-definite-unassignment-fail-1
16.1.7-compound-definite-unassignment-fail-1
16.1.7-compound-definite-unassignment-fail-6
+16.1.7-compound-definite-unassignment-fail-7
16.1.7-compound-definite-unassignment-pass-6
16.1.7-compound-definite-unassignment-pass-7
-16.1.2-definite-unassignment-fail-6
-16.1.5-definite-unassignment-pass-4
-16.1.5-definite-unassignment-pass-7
-16.1.5-not-assignable-7
-16.1.5-not-assignable-8
-16.1.3-definite-unassignment-fail-6
+16.1.7-simple-definite-assignment-fail-8
+16.1.7-simple-definite-assignment-fail-9
+16.1.7-simple-definite-unassignment-fail-1
16.1.8-definite-unassign-fail-1
16.1.8-definite-unassign-fail-2
16.1.8-definite-unassign-fail-3
16.1.8-definite-unassign-fail-4
+16.2.10-definite-assign-fail-2
+16.2.10-definite-assign-pass-2
+16.2.10-definite-unassign-fail-6
+16.2.10-definite-unassign-fail-7
+16.2.10-definite-unassign-fail-8
+16.2.10-definite-unassign-fail-9
16.2.10-definite-unassign-pass-1
16.2.10-definite-unassign-pass-2
16.2.10-definite-unassign-pass-4
@@ -287,12 +421,11 @@
16.2.10-definite-unassign-pass-7
16.2.10-definite-unassign-pass-8
16.2.10-definite-unassign-pass-9
-16.2.10-definite-unassign-fail-6
-16.2.10-definite-unassign-fail-7
-16.2.10-definite-unassign-fail-8
-16.2.10-definite-unassign-fail-9
-16.2.10-definite-assign-pass-2
-16.2.10-definite-assign-fail-2
+16.2.11-definite-assign-fail-3
+16.2.11-definite-assign-pass-2
+16.2.11-definite-unassign-fail-7
+16.2.11-definite-unassign-fail-8
+16.2.11-definite-unassign-fail-9
16.2.11-definite-unassign-pass-1
16.2.11-definite-unassign-pass-2
16.2.11-definite-unassign-pass-4
@@ -300,28 +433,36 @@
16.2.11-definite-unassign-pass-6
16.2.11-definite-unassign-pass-7
16.2.11-definite-unassign-pass-8
-16.2.11-definite-unassign-fail-7
-16.2.11-definite-unassign-fail-8
-16.2.11-definite-unassign-fail-9
-16.2.11-definite-assign-pass-2
-16.2.11-definite-assign-fail-3
-16.2.7-final-4
-16.2.7-final-6
+16.2.14-definite-unassign-fail-12
+16.2.14-definite-unassign-fail-13
+16.2.14-definite-unassign-fail-5
+16.2.14-definite-unassign-fail-6
+16.2.14-definite-unassign-fail-7
+16.2.14-definite-unassign-fail-8
+16.2.3-local-class-11
+16.2.3-local-class-4
+16.2.3-local-class-5
+16.2.3-switch-1
16.2.5-definite-unassign-pass-1
16.2.5-definite-unassign-pass-2
16.2.5-definite-unassign-pass-3
-16.2.3-switch-1
+16.2.7-final-4
+16.2.7-final-6
16.2.8-final-1
16.2.8-final-2
16.2.8-unassigned-1
+16.2.8-unassigned-20
+16.2.8-unassigned-21
+16.2.8-unassigned-22
+16.2.8-unassigned-23
16.2.8-unassigned-6
16.2.8-unassigned-8
-16.2.14-definite-unassign-fail-5
-16.2.14-definite-unassign-fail-6
-16.2.14-definite-unassign-fail-7
-16.2.14-definite-unassign-fail-8
-16.2.14-definite-unassign-fail-12
-16.2.14-definite-unassign-fail-13
+16.2.8-unassigned-9
+16.2.9-definite-assign-fail-3
+16.2.9-definite-assign-pass-2
+16.2.9-definite-unassign-fail-5
+16.2.9-definite-unassign-fail-6
+16.2.9-definite-unassign-fail-7
16.2.9-definite-unassign-pass-1
16.2.9-definite-unassign-pass-2
16.2.9-definite-unassign-pass-4
@@ -329,361 +470,349 @@
16.2.9-definite-unassign-pass-6
16.2.9-definite-unassign-pass-7
16.2.9-definite-unassign-pass-8
-16.2.9-definite-unassign-fail-5
-16.2.9-definite-unassign-fail-6
-16.2.9-definite-unassign-fail-7
-16.2.9-definite-assign-pass-2
-16.2.9-definite-assign-fail-3
-15.18.1-float-1
-15.18.1-float-2
-15.18.1-float-3
-15.18.1-float-4
-15.18.1-float-5
-15.18.1-float-6
-15.18.1-float-7
-15.18.1-float-8
-15.18.1-float-9
-15.18.1-float-10
-15.18.1-float-11
-15.18.1-float-12
-15.18.1-double-1
-15.18.1-double-2
-15.18.1-double-3
-15.18.1-double-4
-15.18.1-double-5
-15.18.1-double-6
-15.18.1-double-7
-15.18.1-double-8
-15.18.1-double-9
-15.18.1-double-10
-15.18.1-double-11
-15.18.1-double-12
-15.18.1-double-13
-15.18.1-valid-1
-15.13-anon-1
-15.26.2-mult-12
-15.26.2-div-12
-15.26.2-mod-12
-15.26.2-add-12
-15.26.2-sub-12
-15.26.2-left-shift-12
-15.26.2-signed-right-shift-12
-15.26.2-unsigned-right-shift-12
-15.26.2-and-10
-15.26.2-and-12
-15.26.2-xor-10
-15.26.2-xor-12
-15.26.2-or-10
-15.26.2-or-12
-15.16-value-1
-15.16-value-2
-15.16-semantic-5
-15.9.5.1-superconstructor-2
-15.9.5.1-superconstructor-4
-15.9.5.1-superconstructor-7
-15.9.5.1-superconstructor-8
-15.9.5.1-exception-1
-15.9.5.1-exception-3
-15.9.5.1-exception-4
-15.9.3-choosing-4
-15.9.1-unqualified-anonymous-2
-15.9.1-unqualified-anonymous-4
-15.9.1-unqualified-anonymous-5
-15.9.1-unqualified-anonymous-12
-15.9.1-unqualified-anonymous-14
-15.9.1-unqualified-anonymous-15
-15.9.1-unqualified-anonymous-23
-15.9.1-unqualified-anonymous-24
-15.9.1-unqualified-anonymous-26
-15.9.1-unqualified-anonymous-27
-15.9.1-qualified-anonymous-2
-15.9.1-qualified-anonymous-4
-15.9.1-qualified-anonymous-5
-15.9.1-qualified-anonymous-10
-15.9.1-qualified-anonymous-12
-15.9.1-qualified-anonymous-13
-15.9.1-qualified-anonymous-14
-15.9.1-qualified-anonymous-17
-15.9.1-qualified-anonymous-18
-15.9.1-qualified-anonymous-20
-15.9.1-qualified-anonymous-22
-15.9.1-qualified-anonymous-26
-15.9.1-qualified-anonymous-28
-15.9.1-unqualified-concrete-2
-15.9.1-unqualified-concrete-4
-15.9.1-unqualified-concrete-5
-15.9.1-unqualified-concrete-10
-15.9.1-unqualified-concrete-14
-15.9.1-unqualified-concrete-15
-15.9.1-qualified-concrete-4
-15.9.1-qualified-concrete-5
-15.9.1-qualified-concrete-10
-15.9.1-qualified-concrete-12
-15.9.1-qualified-concrete-14
-15.9.1-qualified-concrete-16
-15.9.1-qualified-concrete-20
-15.9.1-qualified-concrete-24
-15.28-primitive-9
-15.28-primitive-15
-15.28-primitive-16
-15.28-primitive-17
-15.28-simple-name-6
-15.28-simple-name-8
-15.28-uninitialized-simple-name-3
-15.28-cast-simple-name-1
-15.28-cast-simple-name-2
-15.28-cast-simple-name-3
-15.28-qualified-name-5
-15.28-qualified-name-6
-15.28-qualified-name-7
-15.28-qualified-name-8
-15.28-qualified-name-9
-15.28-qualified-name-10
-15.28-string-2
-15.28-string-5
-15.28-string-9
-15.28-string-11
-15.28-string-13
-15.28-string-15
-15.28-string-16
-15.28-string-17
-15.28-string-18
-15.28-simple-namestr-1
-15.28-simple-namestr-2
-15.28-simple-namestr-3
-15.28-simple-namestr-4
-15.28-qualified-namestr-7
-15.28-qualified-namestr-8
-15.28-qualified-namestr-9
-15.28-notstring-1
-15.28-null-1
-15.28-null-3
-15.28-instanceof-3
-15.21-assoc-7
-15.21-assoc-8
-15.21-equal-3
-15.21-type-7
-15.21-type-17
-15.21-type-21
-15.21-type-22
-15.21-type-23
-15.21-type-24
-15.21-type-30
-15.11.2-syntax-1
-15.11.2-explicit-constructor-2
-15.11.2-meaning-3
-15.11.2-meaning-6
-15.11.2-meaning-8
-15.11.2-meaning-9
-15.11.2-meaning-10
-15.11.2-meaning-11
-15.11.2-meaning-13
-15.11.2-meaning-14
-15.11.2-meaning-17
-15.11.1-ambiguous-2
-15.11.1-ambiguous-3
-15.11.1-explicit-constructor-3
-15.12.3-explicit-constructor-3
-15.12.3-explicit-constructor-4
-15.12.3-explicit-constructor-5
-15.12.3-explicit-constructor-7
-15.12.3-explicit-constructor-10
-15.12.3-abstract-1
-15.12.3-abstract-2
-15.12.3-abstract-3
-15.12.1-syntax-1
-15.12.1-type-14
-15.12.2.1-accessibility-method-2
-15.12.2.1-accessibility-method-4
-15.12.2.1-accessibility-method-6
-15.12.2.2-ambiguous-1
-15.12.2.2-ambiguous-2
-15.12.2.2-ambiguous-6
-15.12.2.2-ambiguous-9
-15.12.2.2-ambiguous-10
-15.12.2.2-ambiguous-12
-15.12.2.2-ambiguous-14
-15.12.2.2-ambiguous-18
-15.12.2.2-ambiguous-21
-15.17-mod-3
-15.17-mod-4
-15.17.3-assoc-2
-15.17.3-float-1
-15.17.3-float-2
-15.17.3-float-3
-15.17.3-float-4
-15.17.3-float-5
-15.17.3-float-6
-15.17.3-float-7
-15.17.3-float-8
-15.17.3-float-9
-15.17.3-float-10
-15.17.3-float-11
-15.17.3-float-12
-15.17.3-float-13
-15.17.3-float-14
-15.17.3-double-1
-15.17.3-double-2
-15.17.3-double-3
-15.17.3-double-4
-15.17.3-double-5
-15.17.3-double-6
-15.17.3-double-7
-15.17.3-double-8
-15.17.3-double-9
-15.17.3-double-10
-15.17.3-double-11
-15.17.3-double-12
-15.17.3-double-13
-15.17.3-double-14
-15.14.2-final-2
-15.14.2-final-3
-15.14.1-final-2
-15.14.1-final-3
-15.8.2-synthetic-1
-15.8.2-type-11
-15.8.2-type-12
-15.8.2-type-13
-15.8.2-type-14
-15.8.5-field-expression-6
-15.8.5-method-expression-8
-15.8.5-variable-5
-15.8.5-variable-6
-15.8.5-variable-7
-15.8.5-variable-8
-15.15-precedence-5
-15.15.2-final-2
-15.15.2-final-3
-15.15.1-final-2
-15.15.1-final-3
-9.4.1-conflict-2
-9.3.1-init-1
-9.3.1-illegal-forward-1
-9.3.1-illegal-forward-2
-9.1.3-body-5
-9.1.1-in-class-17
-9.1.1-in-class-24
-9.1.1-in-interface-2
-9.1.1-in-interface-3
-9.1.1-in-interface-9
-9.1.1-in-interface-16
-9.1.2-supertype-1
-9.2-implicit-2
-9.2-implicit-3
-9.2-implicit-4
-9.2-implicit-6
-9.2-implicit-7
-9.2-implicit-15
-9.2-implicit-18
-9.2-implicit-19
-3.2-valid-1
-3.10.2-round-6
-3.10.2-round-7
-3.10.2-round-9
+16.5-anonymous-3
+16.5-runtime-1
+16.5-runtime-2
+16.5-runtime-3
+16.5-runtime-4
+16.5-runtime-5
+16.8-constructor-6
+16.8-constructor-7
+16.8-constructor-8
+3.10.1-invalid-3
+3.10.1-invalid-4
+3.10.2-double-13
+3.10.2-double-14
3.10.2-round-10
3.10.2-round-11
3.10.2-round-12
-3.10.2-double-13
-3.10.2-double-14
-3.10.1-invalid-3
-3.10.1-invalid-4
-6.6.2.2-protected-creation-3
-6.6.2.1-protected-instance-field-3
-6.6.2.1-protected-instance-field-4
-6.6.2.1-protected-instance-field-6
-6.6.2.1-protected-instance-field-7
-6.6.2.1-protected-instance-method-3
-6.6.2.1-protected-instance-method-5
-6.6.2.1-protected-instance-method-6
-6.6.2.1-protected-instance-method-7
-6.6.2.1-protected-type-2
-6.6.1-8
+3.10.2-round-6
+3.10.2-round-7
+3.10.2-round-9
+3.2-valid-1
+4.5.4-parameter-2
+4.5.4-parameter-3
+4.5.4-static-1
+4.5.4-static-5
+4.7.10-jvms-class-1
+4.7.10-jvms-class-10
+4.7.10-jvms-class-11
+4.7.10-jvms-class-12
+4.7.10-jvms-class-13
+4.7.10-jvms-class-14
+4.7.10-jvms-class-15
+4.7.10-jvms-class-16
+4.7.10-jvms-class-17
+4.7.10-jvms-class-18
+4.7.10-jvms-class-19
+4.7.10-jvms-class-2
+4.7.10-jvms-class-3
+4.7.10-jvms-class-4
+4.7.10-jvms-class-5
+4.7.10-jvms-class-6
+4.7.10-jvms-class-7
+4.7.10-jvms-class-8
+4.7.10-jvms-class-9
+4.7.10-jvms-constructor-1
+4.7.10-jvms-constructor-10
+4.7.10-jvms-constructor-11
+4.7.10-jvms-constructor-12
+4.7.10-jvms-constructor-13
+4.7.10-jvms-constructor-14
+4.7.10-jvms-constructor-2
+4.7.10-jvms-constructor-3
+4.7.10-jvms-constructor-4
+4.7.10-jvms-constructor-5
+4.7.10-jvms-constructor-6
+4.7.10-jvms-constructor-7
+4.7.10-jvms-constructor-8
+4.7.10-jvms-constructor-9
+4.7.10-jvms-field-1
+4.7.10-jvms-field-10
+4.7.10-jvms-field-11
+4.7.10-jvms-field-12
+4.7.10-jvms-field-13
+4.7.10-jvms-field-2
+4.7.10-jvms-field-3
+4.7.10-jvms-field-4
+4.7.10-jvms-field-5
+4.7.10-jvms-field-6
+4.7.10-jvms-field-7
+4.7.10-jvms-field-8
+4.7.10-jvms-field-9
+4.7.10-jvms-lex-1
+4.7.10-jvms-lex-10
+4.7.10-jvms-lex-2
+4.7.10-jvms-lex-3
+4.7.10-jvms-lex-4
+4.7.10-jvms-lex-5
+4.7.10-jvms-lex-6
+4.7.10-jvms-lex-7
+4.7.10-jvms-lex-8
+4.7.10-jvms-lex-9
+4.7.10-jvms-method-1
+4.7.10-jvms-method-10
+4.7.10-jvms-method-11
+4.7.10-jvms-method-12
+4.7.10-jvms-method-2
+4.7.10-jvms-method-3
+4.7.10-jvms-method-4
+4.7.10-jvms-method-5
+4.7.10-jvms-method-6
+4.7.10-jvms-method-7
+4.7.10-jvms-method-8
+4.7.10-jvms-method-9
+5.1.2-btd-1
+5.1.2-btd-3
+5.1.2-btd-5
+5.1.2-btf-1
+5.1.2-btf-3
+5.1.2-btf-5
+5.1.2-bti-1
+5.1.2-bti-3
+5.1.2-bti-5
+5.1.2-btl-1
+5.1.2-btl-3
+5.1.2-btl-5
+5.1.2-bts-1
+5.1.2-bts-2
+5.1.2-bts-3
+5.1.2-bts-4
+5.1.2-bts-5
+5.1.2-std-3
+5.1.2-std-5
+5.1.2-stf-1
+5.1.2-stf-3
+5.1.2-stf-5
+5.1.2-sti-1
+5.1.2-sti-5
+5.1.2-stl-1
+5.1.2-stl-3
+5.1.2-stl-5
+6.3-1
+6.5.1-type-15
+6.5.1-type-16
+6.5.1-typeorpackage-2
+6.5.4.1-simple-10
+6.5.4.1-simple-11
+6.5.4.1-simple-6
+6.5.5.1-import-2
+6.5.5.1-import-3
+6.5.5.1-nested-14
+6.5.5.1-nested-16
+6.5.5.1-nested-17
+6.5.5.1-nested-19
+6.5.5.1-nested-20
+6.5.5.1-nested-21
+6.5.5.1-nested-23
+6.5.5.1-nested-4
+6.5.5.1-nested-7
+6.5.5.1-nested-8
+6.5.5.1-nested-9
+6.5.5.2-type-4
+6.5.5.2-type-5
+6.5.5.2-type-6
+6.5.5.2-type-7
+6.5.5.2-type-8
+6.5.6.1-explicit-constructor-2
+6.5.6.1-field-6
+6.5.6.1-local-3
+6.5.6.1-local-4
+6.5.6.2-expression-6
+6.5.6.2-type-2
+6.5.6.2-type-6
+6.5.6.2-type-8
+6.5.6.2-type-9
6.6.1-11
-6.6.1-array-2
-6.6.1-array-3
-6.6.1-array-5
-6.6.1-array-8
+6.6.1-8
6.6.1-array-11
6.6.1-array-13
6.6.1-array-14
6.6.1-array-17
+6.6.1-array-2
6.6.1-array-20
6.6.1-array-22
6.6.1-array-23
6.6.1-array-26
6.6.1-array-29
+6.6.1-array-3
6.6.1-array-31
6.6.1-array-32
6.6.1-array-35
-6.5.6.2-type-2
-6.5.6.2-type-6
-6.5.6.2-type-8
-6.5.6.2-type-9
-6.5.6.2-expression-6
-6.5.6.1-local-3
-6.5.6.1-local-4
-6.5.6.1-field-6
-6.5.6.1-explicit-constructor-2
-6.5.4.1-simple-6
-6.5.4.1-simple-10
-6.5.4.1-simple-11
-6.5.1-type-15
-6.5.1-type-16
-6.5.1-typeorpackage-2
-6.5.5.2-type-4
-6.5.5.2-type-5
-6.5.5.2-type-6
-6.5.5.2-type-7
-6.5.5.2-type-8
-6.5.5.1-import-2
-6.5.5.1-import-3
-6.5.5.1-nested-4
-6.5.5.1-nested-7
-6.5.5.1-nested-8
-6.5.5.1-nested-9
-6.5.5.1-nested-14
-6.5.5.1-nested-16
-6.5.5.1-nested-17
-6.5.5.1-nested-19
-6.5.5.1-nested-20
-6.5.5.1-nested-21
-6.5.5.1-nested-23
-6.3-1
+6.6.1-array-5
+6.6.1-array-8
+6.6.1-runtime-privateconstructor-1
+6.6.2.1-protected-instance-field-3
+6.6.2.1-protected-instance-field-4
+6.6.2.1-protected-instance-field-6
+6.6.2.1-protected-instance-field-7
+6.6.2.1-protected-instance-method-3
+6.6.2.1-protected-instance-method-5
+6.6.2.1-protected-instance-method-6
+6.6.2.1-protected-instance-method-7
+6.6.2.1-protected-type-2
+6.6.2.2-protected-creation-3
+7.1-named-5
+7.1-named-6
+7.1-named-7
7.4.2-2
-7.5.1-canonical-3
7.5.1-accessible-4
7.5.1-accessible-5
+7.5.1-canonical-3
7.5.1-duplicate-4
7.5.1-shadow-2
-7.5.2-canonical-2
-7.5.2-canonical-3
7.5.2-accessible-1
7.5.2-accessible-3
7.5.2-accessible-4
+7.5.2-canonical-2
+7.5.2-canonical-3
7.5.2-duplicate-1
7.5.2-duplicate-2
7.5.2-duplicate-3
7.5.2-duplicate-4
-7.1-named-5
-7.1-named-6
-7.1-named-7
7.6-optional-restrictions-1
7.6-unnamed-scope-1
7.6-unnamed-scope-2
-4.5.4-static-1
-4.5.4-static-5
-4.5.4-parameter-2
-4.5.4-parameter-3
-4.7.10-jvms-class-6
-4.7.10-jvms-class-7
-4.7.10-jvms-class-8
-4.7.10-jvms-class-18
-4.7.10-jvms-method-6
-4.7.10-jvms-method-8
-4.7.10-jvms-constructor-6
-4.7.10-jvms-constructor-8
-4.7.10-jvms-field-6
-4.7.10-jvms-field-8
+8.1.1.1-12
+8.1.1.1-default-abstract-11
+8.1.1.1-default-abstract-13
+8.1.1.1-default-abstract-15
+8.1.1.1-default-abstract-19
+8.1.1.1-default-abstract-21
+8.1.1.1-default-abstract-25
+8.1.2-enclosing-10
+8.1.2-enclosing-4
+8.1.2-enclosing-5
+8.1.2-enclosing-7
+8.1.2-runtime-1
+8.1.2-static-1
+8.1.2-static-11
+8.1.2-static-16
+8.1.3-object-3
+8.1.3-superclass-6
+8.3-inheritance-1
+8.3-inheritance-2
+8.3-inheritance-3
+8.3-inheritance-5
+8.3-inheritance-6
+8.3-runtime-1
+8.3.1.2-final-17
+8.3.1.2-final-19
+8.3.1.2-final-2
+8.3.1.2-final-21
+8.3.1.2-final-24
+8.3.1.2-final-27
+8.3.1.2-final-28
+8.3.1.2-final-29
+8.3.2-abrupt-3
+8.3.2-abrupt-5
+8.3.2-abrupt-6
+8.3.2-abrupt-7
+8.3.2.2-super-2
+8.3.2.3-illegal-forward-instance-1
+8.3.2.3-illegal-forward-instance-2
+8.3.2.3-illegal-forward-instance-3
+8.3.2.3-illegal-forward-instance-4
+8.3.2.3-illegal-forward-instance-5
+8.3.2.3-illegal-forward-instance-6
+8.3.2.3-illegal-forward-instance-7
+8.3.2.3-illegal-forward-instance-8
+8.3.2.3-illegal-forward-instance-9
+8.3.2.3-illegal-forward-static-1
+8.3.2.3-illegal-forward-static-10
+8.3.2.3-illegal-forward-static-2
+8.3.2.3-illegal-forward-static-3
+8.3.2.3-illegal-forward-static-4
+8.3.2.3-illegal-forward-static-5
+8.3.2.3-illegal-forward-static-6
+8.3.2.3-illegal-forward-static-7
+8.3.2.3-illegal-forward-static-8
+8.3.2.3-illegal-forward-static-9
+8.3.2.3-legal-forward-instance-11
+8.4.6-inheritance-1
+8.4.6-inheritance-2
+8.4.6.1-override-3
+8.4.6.2-hiding-3
+8.4.6.2-hiding-5
+8.4.6.3-default-10
+8.4.6.3-default-12
+8.4.6.3-default-14
+8.4.6.3-default-4
+8.4.6.3-default-6
+8.4.6.3-modifier-10
+8.4.6.3-modifier-11
+8.4.6.3-modifier-12
+8.4.6.3-modifier-13
+8.4.6.3-modifier-8
+8.4.6.3-modifier-9
+8.4.6.3-signature-4
+8.4.6.4-abstract-1
+8.4.6.4-abstract-10
+8.4.6.4-abstract-2
+8.4.6.4-abstract-9
+8.4.6.4-multiple-3
+8.4.6.4-multiple-4
+8.4.6.4-multiple-7
+8.4.6.4-multiple-8
+8.4.6.4-multiple-runtime-1
+8.5-inheritance-1
+8.5-inheritance-2
+8.5-inheritance-3
+8.5-inheritance-6
+8.5.2-non-static-member-usage-2
+8.5.2-non-static-member-usage-4
+8.5.2-non-static-member-usage-5
+8.6-abrupt-1
+8.6-abrupt-4
+8.6-checked-exception-10
+8.6-checked-exception-11
+8.6-checked-exception-12
+8.6-checked-exception-2
+8.6-checked-exception-4
+8.6-checked-exception-5
+8.6-checked-exception-6
+8.6-checked-exception-8
+8.6-complete-1
+8.6-complete-4
+8.6-complete-5
+8.7-abrupt-1
+8.7-complete-1
+8.7-complete-3
+8.8.3-runtime-inner-4
+8.8.5.1-example-1
+8.8.5.1-example-3
+8.8.5.1-qualified-1
+8.8.5.1-qualified-10
+8.8.5.1-qualified-11
+8.8.5.1-qualified-12
+8.8.5.1-qualified-13
+8.8.5.1-qualified-15
+8.8.5.1-qualified-2
+8.8.5.1-qualified-3
+8.8.5.1-qualified-4
+8.8.7-accessible-default-constructor-inner-18
+8.8.7-accessible-default-constructor-inner-26
+8.8.7-runtime-accessible-default-1
+9.1.1-in-class-17
+9.1.1-in-class-24
+9.1.1-in-interface-16
+9.1.1-in-interface-2
+9.1.1-in-interface-3
+9.1.1-in-interface-9
+9.1.2-supertype-1
+9.1.3-body-5
+9.2-implicit-15
+9.2-implicit-18
+9.2-implicit-19
+9.2-implicit-2
+9.2-implicit-3
+9.2-implicit-4
+9.2-implicit-6
+9.2-implicit-7
+9.3.1-illegal-forward-1
+9.3.1-illegal-forward-2
+9.3.1-init-1
+9.4.1-conflict-2
non-jls-argument-expansion-11
non-jls-argument-expansion-12
non-jls-argument-expansion-13
@@ -692,58 +821,12 @@ non-jls-argument-expansion-tokens-1
non-jls-argument-expansion-tokens-2
non-jls-argument-expansion-tokens-4
non-jls-argument-expansion-tokens-5
-non-jls-zip-2
-13.1-runtime-constant-1
-13.1-runtime-constant-3
-13.1-runtime-field-1
-13.4.8-constant-runtime-1
-14-runtime-jump-1
-14-runtime-jump-2
-14.3.1-runtime-3
-8.1.2-runtime-1
-6.6.1-runtime-privateconstructor-1
-8.8.3-runtime-inner-4
-8.8.7-runtime-accessible-default-1
-8.3-runtime-1
-8.4.6.4-multiple-runtime-1
-16.5-runtime-1
-16.5-runtime-2
-16.5-runtime-3
-16.5-runtime-4
-16.5-runtime-5
-12.4.1-runtime-1
-12.4.1-runtime-2
-12.4.1-runtime-3
-12.4.1-runtime-4
-15.9-runtime-numcalls-1
-15.9.4-runtime-creation-1
-15.9.4-runtime-creation-2
-15.9.4-runtime-creation-5
-15.25-runtime-1
-15.11.2-runtime-1
-15.11.2-runtime-2
-15.11.1-runtime-static-1
-15.11.1-runtime-static-2
-15.11.1-runtime-static-3
-15.11.1-runtime-static-4
-15.12.3-runtime-mode-1
-15.12.3-runtime-mode-2
-15.12.3-runtime-mode-3
-15.12.3-runtime-mode-4
-15.12.3-runtime-mode-6
-15.12.4.1-runtime-static-1
-15.12.4.1-runtime-static-2
-15.12.4.1-runtime-super-1
-15.12.4.1-runtime-super-2
-15.14-runtime-3
-15.14-runtime-4
-15.20-2-runtime-1
-15.15-runtime-3
-15.15-runtime-4
+non-jls-jsr41.2-clash-1
+non-jls-jsr41.3-runtime-2
non-jls-jsr41.4-definite-unassignment-fail-22
+non-jls-jsr41.4-definite-unassignment-pass-10
non-jls-jsr41.4-definite-unassignment-pass-2
non-jls-jsr41.4-definite-unassignment-pass-9
-non-jls-jsr41.4-definite-unassignment-pass-10
non-jls-jsr41.4-definite-unassignment-try-1
non-jls-jsr41.4-definite-unassignment-try-2
non-jls-jsr41.4-definite-unassignment-try-3
@@ -753,15 +836,15 @@ non-jls-jsr41.4-definite-unassignment-try-6
non-jls-jsr41.4-definite-unassignment-try-7
non-jls-jsr41.4-definite-unassignment-try-8
non-jls-jsr41.4-loop-1
-non-jls-jsr41.4-loop-2
-non-jls-jsr41.4-loop-3
-non-jls-jsr41.4-loop-7
-non-jls-jsr41.4-loop-8
-non-jls-jsr41.4-loop-9
non-jls-jsr41.4-loop-10
non-jls-jsr41.4-loop-11
non-jls-jsr41.4-loop-12
non-jls-jsr41.4-loop-13
non-jls-jsr41.4-loop-14
non-jls-jsr41.4-loop-15
-non-jls-jsr41.2-clash-1
+non-jls-jsr41.4-loop-2
+non-jls-jsr41.4-loop-3
+non-jls-jsr41.4-loop-7
+non-jls-jsr41.4-loop-8
+non-jls-jsr41.4-loop-9
+non-jls-zip-2
diff --git a/libjava/testsuite/libjava.jar/jar.exp b/libjava/testsuite/libjava.jar/jar.exp
index bff1fea2c8c..7f4c792c25d 100644
--- a/libjava/testsuite/libjava.jar/jar.exp
+++ b/libjava/testsuite/libjava.jar/jar.exp
@@ -31,7 +31,7 @@ proc gcj_jar_interpret {jarfile} {
set opts(_) {}
set out [file rootname $jarfile].out
libjava_invoke $jarfile "gij test" opts $gij {} $out \
- -jar $jarfile
+ "" -jar $jarfile
}
proc gcj_jar_run {} {
diff --git a/libjava/testsuite/libjava.jni/PR15133.c b/libjava/testsuite/libjava.jni/PR15133.c
new file mode 100644
index 00000000000..be5a48efa3b
--- /dev/null
+++ b/libjava/testsuite/libjava.jni/PR15133.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include <jni.h>
+#include "PR15133.h"
+
+JNIEXPORT void JNICALL
+Java_PR15133_printIt (JNIEnv *env, jobject x, jint y)
+{
+ printf ("%d\n", y);
+}
diff --git a/libjava/testsuite/libjava.jni/PR15133.java b/libjava/testsuite/libjava.jni/PR15133.java
new file mode 100644
index 00000000000..90435765b3d
--- /dev/null
+++ b/libjava/testsuite/libjava.jni/PR15133.java
@@ -0,0 +1,14 @@
+/* Test case for PR java/15133 */
+public class PR15133
+{
+ public void printIt (String dummy) { }
+
+ public native void printIt (int num);
+
+ public static void main (String[] args)
+ {
+ System.loadLibrary ("PR15133");
+
+ new PR15133( ).printIt( 1729);
+ }
+}
diff --git a/libjava/testsuite/libjava.jni/PR15133.out b/libjava/testsuite/libjava.jni/PR15133.out
new file mode 100644
index 00000000000..32bb421c624
--- /dev/null
+++ b/libjava/testsuite/libjava.jni/PR15133.out
@@ -0,0 +1 @@
+1729
diff --git a/libjava/testsuite/libjava.jni/jni.exp b/libjava/testsuite/libjava.jni/jni.exp
index 7dad519d415..b1f6d4e34f4 100644
--- a/libjava/testsuite/libjava.jni/jni.exp
+++ b/libjava/testsuite/libjava.jni/jni.exp
@@ -21,24 +21,36 @@ proc gcj_jni_compile_c_to_so {file {options {}}} {
set so_extension "so"
set so_flag "-shared"
}
- set name [file rootname [file tail $file]]
+ set filename [file tail $file]
+ set name [file rootname $filename]
set soname lib${name}.${so_extension}
lappend options "additional_flags=${so_flag} -fPIC"
# Find the generated header.
lappend options "additional_flags=-I. -I.."
+
+ # Ensure that the generated header has correct prototypes.
+ set cfile [file rootname $file].c
+ if { [file exists $cfile]} {
+ # This option is only valid for C sources.
+ lappend options "additional_flags=-Wmissing-prototypes"
+ }
+
# Find jni.h.
lappend options "additional_flags=-I$srcdir/../include"
+ # Append C++ options
+ lappend options "additional_flags=$options_cxx"
+
set x [libjava_prune_warnings \
[target_compile $file $soname executable $options]]
if {$x != ""} {
verbose "target_compile failed: $x" 2
- fail "$name.c compilation"
+ fail "$filename compilation"
return 0
}
- pass "$name.c compilation"
+ pass "$filename compilation"
return 1
}
@@ -62,6 +74,7 @@ proc gcj_jni_build_header {file} {
proc gcj_jni_test_one {file} {
global runtests
global host_triplet
+ global INTERPRETER
# apple uses a different extension for shared/dynamic libraries
# so we check against powerpc-apple-darwin and set them to
@@ -113,30 +126,46 @@ proc gcj_jni_test_one {file} {
}
}
lappend cxxflaglist $arg
+ # In case the libstdc++ is not installed yet, we pass the build
+ # directory of it to the cxxflaglist.
+ lappend cxxflaglist "-L$cxxldlibflags"
}
lappend cxxflaglist "-lstdc++"
set cxxflags [join $cxxflaglist]
}
- if {! [gcj_jni_compile_c_to_so $cfile]} {
+ if {! [gcj_jni_compile_c_to_so $cfile $cxxflags]} {
# FIXME
return 0
}
- # We use -l$main because the .so is named the same as the main
- # program.
- set args [list "additional_flags=-fjni -L. -l$main $cxxflags"]
+ set args [list "additional_flags=-fjni"]
if {! [gcj_link $main $main $file $args]} {
# FIXME
return 0
}
- if {! [gcj_invoke $main [file rootname $file].out $cxxldlibflags]} {
+ set resultfile [file rootname $file].out
+
+ if {! [gcj_invoke $main $resultfile $cxxldlibflags]} {
# FIXME
return 0
}
+ # We purposely ignore errors here; we still want to run the other
+ # appropriate tests.
+ set errname [file rootname [file tail $file]]
+ set gij [libjava_find_gij]
+ # libjava_find_gij will return `gij' if it couldn't find the
+ # program; in this case we want to skip the test.
+ # If the libraries are not installed yet, we have to pass them via
+ # cxxldlibflags to libjava_invoke.
+ if {$INTERPRETER == "yes" && $gij != "gij"} {
+ libjava_invoke $errname "gij test" opts $gij \
+ "" $resultfile $cxxldlibflags $main
+ }
+
# When we succeed we remove all our clutter.
eval gcj_cleanup [glob -nocomplain -- ${main}.*] [list $main lib${main}.${so_extension}]
diff --git a/libjava/testsuite/libjava.jni/pr11951.java b/libjava/testsuite/libjava.jni/pr11951.java
index 68a9f0126a3..e481503ab59 100644
--- a/libjava/testsuite/libjava.jni/pr11951.java
+++ b/libjava/testsuite/libjava.jni/pr11951.java
@@ -11,4 +11,8 @@ public class pr11951
{
nmethod();
}
+
+ static {
+ System.loadLibrary("pr11951");
+ }
}
diff --git a/libjava/testsuite/libjava.lang/InvokeInterface.java b/libjava/testsuite/libjava.lang/InvokeInterface.java
new file mode 100644
index 00000000000..6f4dc617d39
--- /dev/null
+++ b/libjava/testsuite/libjava.lang/InvokeInterface.java
@@ -0,0 +1,55 @@
+import java.lang.reflect.*;
+
+interface one
+{
+ int n(int N);
+}
+
+interface two
+{
+ int nn(int N);
+}
+
+interface three
+{
+ int nnn(int N);
+}
+
+class arse implements one, two
+{
+ public int n(int N) { return N; }
+ public int nn(int N) { return N*2; }
+}
+
+class arsey implements two, one, three
+{
+ public int n(int N) { return N*4; }
+ public int nn(int N) { return N*8; }
+ public int nnn(int N) { return N*16; }
+}
+
+public class InvokeInterface extends arse
+{
+ int f ()
+ {
+ return flunk.nn(1);
+ }
+ static two flunk = new arse();
+ static three flunkey = new arsey();
+ public static void main(String[] s) throws Throwable
+ {
+ Class[] argtypes = {Integer.TYPE};
+ Method m = two.class.getMethod("nn", argtypes);
+ Object[] args = {new Integer(1)};
+ System.out.println(flunk.nn(1));
+ System.out.println(m.invoke(new arse(), args));
+ m = arse.class.getMethod("nn", argtypes);
+ System.out.println(m.invoke(new arse(), args));
+ m = two.class.getMethod("nn", argtypes);
+ System.out.println(m.invoke(new arsey(), args));
+ m = three.class.getMethod("nnn", argtypes);
+ System.out.println(m.invoke(new arsey(), args));
+ m = arsey.class.getMethod("nnn", argtypes);
+ System.out.println(m.invoke(new arsey(), args));
+ }
+}
diff --git a/libjava/testsuite/libjava.lang/InvokeInterface.out b/libjava/testsuite/libjava.lang/InvokeInterface.out
new file mode 100644
index 00000000000..803d02666a2
--- /dev/null
+++ b/libjava/testsuite/libjava.lang/InvokeInterface.out
@@ -0,0 +1,6 @@
+2
+2
+2
+8
+16
+16
diff --git a/libjava/testsuite/libjava.lang/MathBuiltin.java b/libjava/testsuite/libjava.lang/MathBuiltin.java
index 9a4c367a38e..275a086600a 100644
--- a/libjava/testsuite/libjava.lang/MathBuiltin.java
+++ b/libjava/testsuite/libjava.lang/MathBuiltin.java
@@ -5,6 +5,16 @@ class MathBuiltin
return Math.abs(x);
}
+ static double acos(double x)
+ {
+ return Math.acos(x);
+ }
+
+ static double asin(double x)
+ {
+ return Math.asin(x);
+ }
+
static double atan(double x)
{
return Math.atan(x);
@@ -15,6 +25,11 @@ class MathBuiltin
return Math.atan2(x,y);
}
+ static double ceil(double x)
+ {
+ return Math.ceil(x);
+ }
+
static double cos(double x)
{
return Math.cos(x);
@@ -25,6 +40,11 @@ class MathBuiltin
return Math.exp(x);
}
+ static double floor(double x)
+ {
+ return Math.floor(x);
+ }
+
static double log(double x)
{
return Math.log(x);
@@ -62,8 +82,9 @@ class MathBuiltin
public static void main(String argv[])
{
- double sum = abs (1.0) + atan (1.0) + atan2 (1.0, 1.0) + cos (1.0)
- + exp (1.0) + log(1.0) + max(1.0, 1.0) + min (1.0, 1.0)
+ double sum = abs (1.0) + acos (1.0) + asin (1.0) + atan (1.0)
+ + atan2 (1.0, 1.0) + ceil (1.0) + cos (1.0) + exp (1.0)
+ + floor (1.0) + log(1.0) + max(1.0, 1.0) + min (1.0, 1.0)
+ pow (1.0, 1.0) + sin (1.0) + sqrt(1.0) + tan(1.0);
}
}
diff --git a/libjava/testsuite/libjava.mauve/xfails b/libjava/testsuite/libjava.mauve/xfails
index 64831f6aabc..304a2ce34a0 100644
--- a/libjava/testsuite/libjava.mauve/xfails
+++ b/libjava/testsuite/libjava.mauve/xfails
@@ -32,7 +32,6 @@ FAIL: gnu.testlet.java.lang.String.getBytes13: String.getBytes("UnicodeLittleUnm
FAIL: gnu.testlet.java.lang.String.getBytes14: String.getBytes("ISO8859_15") (number 1)
FAIL: gnu.testlet.java.lang.String.getBytes14: String.getBytes("UTF-16BE") (number 1)
FAIL: gnu.testlet.java.lang.String.getBytes14: String.getBytes("UTF-16LE") (number 1)
-FAIL: gnu.testlet.java.text.AttributedString.Test: Attribute key count (number 1)
FAIL: gnu.testlet.java.text.DateFormatSymbols.Test: patterns (number 2)
FAIL: gnu.testlet.java.text.SimpleDateFormat.getAndSet2DigitYearStart: get2DigitYearStart() initial (number 1)
FAIL: gnu.testlet.java.text.DateFormatSymbols.Test: invalid locale (number 1)
diff --git a/libjava/verify.cc b/libjava/verify.cc
index 7ba2ba4daee..17252d150f7 100644
--- a/libjava/verify.cc
+++ b/libjava/verify.cc
@@ -559,7 +559,7 @@ private:
{
// We use a recursive call because we also need to
// check superinterfaces.
- if (is_assignable_from_slow (target, source->interfaces[i]))
+ if (is_assignable_from_slow (target, source->getInterface (i)))
return true;
}
}
diff --git a/libmudflap/ChangeLog b/libmudflap/ChangeLog
new file mode 100644
index 00000000000..eafa5eb3e57
--- /dev/null
+++ b/libmudflap/ChangeLog
@@ -0,0 +1,957 @@
+2004-03-25 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-impl.h: Added libgcc license header.
+
+2004-03-20 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-hooks[123].c, mf-runtime.c, mf-heuristics.c:
+ Added libgcc license header.
+ * mf-hooks3.c (__mf_0fn_pthread_create): Correct arg constness.
+ (pthread_create): Simplify stack allocation syntax.
+
+2004-03-08 Loren J. Rittle <ljrittle@acm.org>
+
+ * mf-hooks2.c: Support FreeBSD.
+ (WRAP_gets): Avoid gets().
+ * testsuite/libmudflap.c/pass-stratcliff.c: Do not
+ test unimplemented mem/str calls on FreeBSD.
+ * testsuite/libmudflap.c/pass21-frag.c: Do not include
+ <alloca.h> on FreeBSD.
+
+2004-01-30 Frank Ch. Eigler <fche@redhat.com>
+
+ * testsuite/libmudflap.c/pass36-frag.c: Add missing free() call.
+ * testsuite/libmudflap.c/pass46-frag.c: New test for -fmudflapir.
+ * testsuite/libmudflap.cth/cthfrags.exp: Add -DSTATIC to compiler
+ flags for static linking permutation.
+ * testsuite/libmudflap.cth/pass40-frag.c: When -DSTATIC, avoid
+ some pthreads code that croaks on linux glibc tls.
+
+2004-01-27 Frank Ch. Eigler <fche@redhat.com>
+
+ * testsuite/libmudflap.c/fail31-frag.c, pass45-frag.c: New tests.
+
+2004-01-15 Frank Ch. Eigler <fche@redhat.com>
+
+ * testsuite/libmudflap.c/pass44-frag.c: New test.
+
+2004-01-12 Frank Ch. Eigler <fche@redhat.com>
+
+ * testsuite/libmudflap.c/fail{28,29,30}-frag.c: New tests.
+
+2004-01-08 Frank Ch. Eigler <fche@redhat.com>
+
+ * testsuite/libmudflap.c/pass43-frag.c: Added missing program rc.
+
+2003-12-11 Frank Ch. Eigler <fche@redhat.com>
+
+ * testsuite/libmudflap.c/pass42-frag.c, pass43-frag.c: New tests.
+
+2003-12-08 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR libmudflap/12670
+ * configure.in: Add check for see if
+ socklen_t typedef is in sys/socket.h.
+ * mf-hooks1.c: Add define if socklen_t
+ is not typedef.
+ * mf-hooks2.c: Likewise.
+ * mf-hooks3.c: Likewise.
+ * config.h.in: Regen.
+ * configure: Regen.
+
+2003-12-08 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-runtime.c (__mf_watch_or_not): Tweak tracing message.
+ * testsuite/libmudflap.c/fail21-frag.c: Defeat aliasing
+ optimizations.
+ * testsuite/libmudflap.c/pass25-frag.c: Ditto.
+ * testsuite/libmudflap.c/pass26-frag.c: Tolerate non-overlapping
+ (unoptimized) allocation of stack space.
+
+2003-12-07 Richard Henderson <rth@redhat.com>
+
+ * testsuite/libmudflap.c/fail23-frag.c (main): Adjust addend to 11.
+ * testsuite/libmudflap.c/fail27-frag.c (foo): Mark noinline.
+
+2003-12-06 Andrew Pinski <apinski@apple.com>
+
+ partial PR libmudflap/12670
+ * mf-hooks1.c: Respect Darwin checks. Conditionalize POSIX_SOURCE.
+ * mf-hooks2.c: Likewise.
+ * mf-hooks3.c: Likewise.
+
+2003-11-19 Frank Ch. Eigler <fche@redhat.com>
+
+ libstdc++/11696
+ * mf-runtime.h.in: Switch to #pragma redefine_extname for
+ symbols interposed at compile time.
+ * testsuite/libmudflap.c++/pass41-frag.cxx: New test.
+
+ libmudflap/12939
+ * mf-hooks2.c (semctl): Tolerate FreeBSD.
+
+ * configure.in: Reorganize check for <pthread.h>.
+ * configure: Regenerated.
+
+2003-11-04 David Edelsohn <edelsohn@gnu.org>
+
+ * mf-runtime.c (_ALL_SOURCE): Define for AIX.
+ (_LARGE_FILE_API): Define for AIX.
+ * mf-hooks[123]: Same.
+ (_XOPEN_SOURCE_EXTENDED): Define to 1 for AIX.
+
+2003-10-21 David Edelsohn <edelsohn@gnu.org>
+
+ * mf-runtime.c (_XOPEN_SOURCE_EXTENDED): Define to 1 for AIX.
+
+2003-07-29 Frank Ch. Eigler <fche@redhat.com>
+
+ 2003-07-29 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * configure.in: Update check for union semun.
+
+2003-07-29 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ PR other/11673
+ * mf-hooks2.c [WRAP_semctl]: Fix check for HAVE_UNION_SEMUN.
+
+2003-07-29 Frank Ch. Eigler <fche@redhat.com>
+
+ PR other/11673
+ * configure.in: Add checks for 64-bit LFS functions, struct semun
+ definition, for BSD compatibility.
+ * mf-hooks1.c: Respect BSD checks. Conditionalize POSIX_SOURCE.
+ * mf-hooks2.c: Ditto. Include <strings.h> for bcmp* decls.
+ * mf-hooks3.c: Ditto.
+ (pthread_create): Try MAP_ANON on platforms without the MAP_ANONYMOUS
+ mmap flag.
+ * configure, config.h.in: Regenerated.
+
+2003-07-23 Frank Ch. Eigler <fche@redhat.com>
+
+ Multithreading fixes:
+ * mf-runtime.c (__mf_object): Store allocating/deallocating
+ thread id.
+ (options): Support new "-thread-stack" option.
+ Rename "-heur-argv-environ" option to "-heur-stdlib".
+ Disable "-lc-mask" and "-lc-shift" options.
+ (__mf_dynamic): Add function pointers for pthread_join/_exit.
+ (__assert_fail): New self-contained function for glibc.
+ * mf-hooks3.c: Essentially rewritten, particularly related to
+ use of __mf_pthread_info array.
+ (pthread_join, _exit): New hook functions.
+ * mf-impl.h (BEGIN_PROTECT): Handle starting_p case.
+ * testsuite/libmudflap.cth/pass40-frag.c: New test.
+
+ Warning cleanups:
+ * mf-heuristics.c: Add type casts for tracing, sub calls.
+ * mf-impl.h (BEGIN_PROTECT): Redefine to omit result type.
+ Update all callers to declare explicit result holder.
+ (END_PROTECT): Removed.
+ * testsuite/*/*frags.exp: Clean up default MUDFLAP_OPTIONS.
+
+2003-07-15 Diego Novillo <dnovillo@redhat.com>
+
+ * testsuite/libmudflap.c/fail21-frag.c: Add volatile modifiers.
+ * testsuite/libmudflap.c/fail15-frag.c: Likewise.
+ * testsuite/libmudflap.c/fail13-frag.c: Likewise.
+
+2003-07-04 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-hooks1.c, 2.c, 3.c: New file, splits up content from old ...
+ * mf-hooks: Removed.
+ * mf-impl.h (MF_VALIDATE_EXTENT, BEGIN_PROTECT, END_PROTECT):
+ Move these macros from old mf-hooks.c here.
+ * Makefile.am: Adapt to split-up hook sources for faster builds.
+ * Makefile.in: Regenerated.
+
+ * mf-heuristics.c: Remove #if-0 block.
+
+ * mf-impl.h (__mf_state): Reorganize declaration and implementation.
+ (__mf_starting_p): New state only for use while dlsym bootstrapping.
+ (CALL_REAL, __mf_init): Corresponding changes.
+ (TRACE, VERBOSE_TRACE): Include thread id and "mf:" prefix. Update
+ all callers to remove redundant "mf:" prefix.
+ * mf-runtime.h.in: #define a few reentrancy macros for libmudflapth.
+ * mf-hooks3.c: Rewrite chunks to support per-thread __mf_state value.
+ (__mf_pthread_info): Become a hash table.
+
+ * testsuite/lib/mfdg.exp: Support new "dg-timeout" and
+ "dg-repetitions" directives to control test case execution.
+ * testsuite/libmudflap.cth/pass37-frag.c: Add timeout and repeat
+ options.
+ * testsuite/libmudflap.cth/pass39-frag.c: Ditto for this new test.
+
+2003-06-25 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-hooks.c (alloca): Separate into stub.
+ (__mf_wrap_alloca_indirect): New function. Use CALL_REAL
+ malloc/free for alloca blocks.
+ (pthread_create): Tolerate failing pthread_attr_get* calls.
+ * mf-runtime.c (__mf_fini): Call __mf_wrap_alloca_indirect.
+ * mf-impl.h (CALL_WRAP): Remove macro.
+ * testsuite/libmudflap.c/pass21-frag.c: Include <alloca.h>.
+ * testsuite/libmudflap.c/pass23-frag.c: Include more struct
+ padding for ia64 BIT_FIELD_REF constructs.
+
+2003-06-19 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-hooks.c (struct pthread_info): Add "thread_errno" field.
+ (__mf_pthread_spawner, __mf_pthread_cleanup): Use it with GUESS
+ libmudflap object type.
+ * mf-runtime.c (__mfu_unregister): Correct cemetary logic to avoid
+ crashes on unregistering STATIC objects.
+
+2003-06-17 Frank Ch. Eigler <fche@redhat.com>
+
+ Based on patch from Eyal Lebedinsky <eyal@eyal.emu.id.au>:
+ * mf-hooks.c (__mf_pthread_spawner): Register thread errno.
+ (time, strerror, fopen, fopen64, fclose, fread): New hooks.
+ (fwrite, fgetc, fgets, getc, gets, ungetc, fputc): New hooks.
+ (fputs, putc, puts, clearerr, feof, ferror, fileno): New hooks.
+ (printf, fprintf, sprintf, snprintf, vprintf, vfprintf): New hooks.
+ (vsprintf, vsnprintf, access, remove, fflush, fseek): New hooks.
+ (fseeko64, ftell, ftello64, rewind, fgetpos, fsetpos): New hooks.
+ (stat, stat64, fstat, lstat, mkfifo, setvbuf, setbuf): New hooks.
+ (setvbuf, opendir, closedir, readdir, recv, recvfrom): New hooks.
+ (recvmsg, send, sendto, sendmsg, setsockopt, getsockopt): New hooks.
+ (accept, bind, connect, gethostname, sethostname): New hooks.
+ (gethostbyname, wait, waitpid, popen, pclose, execve): New hooks.
+ (execv, execvp, system, dlopen, dlclose, dlerror, dlsym): New hooks.
+ (semop, semctl, shmctl, shmat, shmdt): New hooks.
+ * mf-runtime.h.in: Corresponding changes.
+ * mf-runtime.c (__mf_ini): Register stdio objects. Use STATIC type.
+ (opts) Rename heur_argv_environ to heur_std_data.
+ (__mf_wrap_main): Use STATIC type for argv/environ strings.
+ * Makefile.am: Corresponding changes.
+ * Makefile.in: Regenerated.
+
+2003-06-11 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-heuristics.c (__mf_heuristic_check): Disable stack_bounds
+ heuristic for threaded case, and for non-x86-linux targets.
+ * mf-hooks.c (__mf_0fn_calloc): Provide a working dummy implementation
+ for use during pre-main() program startup.
+ (__mf_0fn_*): Make these functions non-static.
+ * mf-impl.h (DECLARE, CALL_REAL): Support calls to 0fn backup hook
+ functions.
+ * mf-runtime.c (__mf_state): Set initial state to "starting".
+ (__mf_resolve_single_dynamic): Tolerate repeated calls for same symbol.
+ (__wrap_main): New function to register argv[] and environ[] strings.
+ (__mf_ini): Call it.
+ (*): In all trace functions, use "%p" as formatter for uintptr_t.
+
+ * testsuite/libmudflap.c/pass38-frag.c: New test case.
+ * testsuite/libmudflap.cth/pass37-frag.c: Improved test.
+
+ * acinclude.m4: Add comments with aoliva's concerns about x86_64
+ pass_all.
+ * aclocal.m4, configure: Regenerated.
+
+2003-06-04 Frank Ch. Eigler <fche@redhat.com>
+
+ * acinclude.m4: Correct typo in AC_MSG_CHECKING.
+ * aclocal.m4, configure: Regenerated.
+
+2003-06-03 Frank Ch. Eigler <fche@redhat.com>
+
+ * acinclude.m4: Force "pass_all" deplibs_check_method for libtool
+ for x86_64 target. Disable caching for this value.
+ * aclocal.m4, configure: Regenerated.
+
+2003-06-02 Frank Ch. Eigler <fche@redhat.com>
+
+ * testsuite/libmudflap.c/pass38-frag.c: Deleted. -fwritable-strings
+ is about to become deprecated, and its present handling bugs are
+ unworthy of fixing.
+
+2003-05-30 Frank Ch. Eigler <fche@redhat.com>
+
+ * testsuite/libmudflap.c/pass38-frag.c: New test for
+ -fwritable-strings.
+
+2003-05-23 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-runtime.c (__mf_sigusr1_handle): Call unlocked variant of
+ __mf_report, asserting reentrant calling context.
+
+2003-05-23 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-hooks.c (realloc): Correct reentrancy logic.
+ * testsuite/libmudflap.c/hook-allocstuff.c: New test case.
+
+2003-05-20 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-hooks.c (LIBMUDFLAPTH_THREADS_MAX): New macro, replaces
+ PTHREAD_THREADS_MAX. Update users.
+ * mf-runtime.c (__mf_usage): Print [active] instead of [default]
+ for active options.
+ * testsuite/Makefile.am (all-local): Prime dejagnu site.exp file
+ with libmudflapth presence indicator.
+ * testsuite/Makefile.in: Regenerated.
+
+2003-05-16 Frank Ch. Eigler <fche@redhat.com>
+
+ * Makefile.am (AM_CFLAGS): Remove "-ansi".
+ * configure.in: Remove silly no-pthreads => no-shared logic.
+ * Makefile.in, configure: Regenerated.
+ * mf-heuristics.c (__mf_heuristic_check): Remove reentrancy hacks.
+ * mf-hooks.c (BEGIN_PROTECT, END_PROTECT): Reorganize reentrancy
+ code. Count reentrancy events.
+ (all hook functions): Don't directly manipulate __mf_state variable.
+ Add TRACE calls to hook functions without them.
+ * mf-impl.h (LOCKTH): Try to count lock contention events.
+ (VERBOSE_TRACE, TRACE): Remove reentrancy hacks.
+ * mf-runtime.c (BEGIN_RECURSION_PROTECT, END_RECURSION_PROTECT):
+ Reorganize reentrancy code.
+ (external __mf_ entry points): Use RECURSION_PROTECT mechanism to
+ identify reentrancy with mutex holding times.
+ (internal __mfu_ entry points): Remove internal reentrancy code.
+ (__mf_init): Use ordinary locked calls.
+ (__mfu_report): Print the two new counts.
+ * testsuite/lib/libmudflap.exp: Filter out junk ld/pthreads messages.
+ * testsuite/libmudfap.cth/cthfrags.exp: New test driver.
+ * testsuite/libmudflap.cth/pass37-frag.c: New pthreads test.
+ * testsuite/libmudfap.cth/cfrags.exp: Adapt to new libmudflap
+ option defaults.
+
+2003-05-09 Frank Ch. Eigler <fche@redhat.com>
+
+ * configure.in: Add pthread support, plus glibc and porting hacks.
+ * Makefile.am (LIBMUDFLAPTH): New conditional, to build -lmudflapth
+ from objects built into ./pth/.
+ * mf-runtime.c (__mfu_watch,register,...): Fork new unlocked
+ functions for internal entry points. Update callers to pick
+ locked vs. unlocked variants.
+ (__mf_resolve_single_dynamic): Extend to support symbol versioning
+ info coming in from a static data structure.
+ (*): Reorder miscellaneous declarations to group data vs functions.
+ (__mf_set_default_options): Simplify.
+ (__mf_usage): Mention threading status of host executable.
+ * mf-impl.h: Move max/min decls here. Reorganize __mf_dynamic
+ decls to match above.
+ (LOCKTH, UNLOCKTH): New macros for Big Libmudflap Lock management.
+ * mf-heuristics.c: Choose between locked/unlocked calls. Add
+ some lock/unlock markers. Remove some unused code.
+ * mf-hooks: Ditto.
+ (pthread_create): New hook function.
+ (__mf_pthread_cleanup, _spawner): New helper functions.
+ * configure. aclocal.m4, config.h.in, Makefile.in: Regenerated.
+
+2003-05-02 Frank Ch. Eigler <fche@redhat.com>
+
+ * testsuite/libmudflap.c/fail27-frag.c: Add more volatile flags.
+
+2002-04-28 Frank Ch. Eigler <fche@redhat.com>
+
+ * Makefile.am (HOOKOBJS): Add *time related hooks.
+ * configure.in: Look for pthreads.h header.
+ * mf-hooks.c (asctime, ctime, gmtime, localtime): New wrappers.
+ * mf-runtime.c: Begin sketching some pthreads support.
+ (__mf_usage): Check for -lpthread presence.
+ (__mf_unregister): Confirm matching unregistration base.
+ (__mf_find_objects_rec): Reduce unnecessary recursion.
+ * mf-runtime.h.in: Add "nothrow" attribute to functions. Add
+ #defines for new hook functions.
+ * mf-impl.h: Corresponding changes.
+ * config.h.in, configure, Makefile.in: Regenerated.
+
+2002-04-27 Diego Novillo <dnovillo@redhat.com>
+
+ * testsuite/libmudflap.c/fail1-frag.c: Add volatile
+ modifiers to prevent being optimized away.
+ * testsuite/libmudflap.c/fail10-frag.c: Likewise.
+ * testsuite/libmudflap.c/fail13-frag.c: Likewise.
+ * testsuite/libmudflap.c/fail14-frag.c: Likewise.
+ * testsuite/libmudflap.c/fail15-frag.c: Likewise.
+ * testsuite/libmudflap.c/fail2-frag.c: Likewise.
+ * testsuite/libmudflap.c/fail20-frag.c: Likewise.
+ * testsuite/libmudflap.c/fail3-frag.c: Likewise.
+
+2003-04-15 Frank Ch. Eigler <fche@redhat.com>
+
+ * Makefile.am (libmudflap_la_LIBADD): Remove -ldl.
+ * configure.in: Look for uintptr_t and -ldl on target.
+ * mf-runtime.h.in: Adjust uintptr_t declaration logic.
+ * Makefile.in, aclocal.m4, configure, config.h.in: Regenerated.
+ * testsuite/Makefile.in: Regenerated.
+ * mf-runtime.c (__mf_sigusr1_respond): Tweak declaration and calls
+ for better C compliance.
+
+2003-04-15 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-hooks.c (MF_VALIDATE_EXTENT): Remove unnecessary reentrancy
+ prevention code.
+ * mf-runtime.c (__mf_set_default_options): Turn off
+ check-initialization.
+ (__mf_describe_object): Shorten description.
+ * testsuite/libmudflap.c/fail25-frag.c: Turn on check-initialization.
+
+2003-04-07 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-hooks.c (__mf_0fn_mmap): Correct return value, as per <rth>.
+
+2003-04-02 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-hooks.c (BEGIN_PROTECT): Handle startup-time reentrant
+ calls specially.
+ (__mf_0fn_malloc ... _munmap): New dummy backup calls.
+ * mf-impl.h (CALL_BACKUP): New macros.
+ * mf-runtime.c (__mf_init): Tweak __mf_state during startup.
+
+2003-03-31 Frank Ch. Eigler <fche@redhat.com>
+
+ * Makefile.am (AM_CFLAGS): Remove optimization flags.
+ (HOOKOBJS): Remove dlopen hook.
+ (libmudflap_la_LIBADD): Add -ldl.
+ * mf-hooks.c (dlopen): Remove hook.
+ * mf-impl.h (__mf_dynamic): Ditto.
+ * mf-runtime.c (__mf_resolve_dynamics): Ditto.
+ * Makefile.in: Regenerated.
+
+2003-03-28 Frank Ch. Eigler <fche@redhat.com>
+
+ * configure.in: Check for target gettimeofday, signal, some headers.
+ * mf-impl.h (__mf_opts): Add new "sigusr1_report" field. Comment
+ out inop multi_threaded field.
+ * mf-runtime.c (options): Handle new "-sigusr1-report" option.
+ (__mf_set_options): Correct handling of "-help".
+ (__mf_sigusr1_respond): New function to manage SIGUSR1 response.
+ (__mf_check, __mf_register, __mf_unregister): Call it.
+ (__mf_insert_new_object, __mf_unregister): Respect HAVE_GETTIMEOFDAY.
+ (__mf_report_leaks): Make callable
+ (__mf_tree_analyze): Traverse in-order. Accumulate address bit
+ distribution statistics.
+ (__mf_adapt_cache): Rewrite shift guessing logic based on address
+ bit distributions.
+ * config.h.in, configure: Regenerated.
+ * testsuite/libmudflap.c/fail27-frag.c: New test.
+ * testsuite/libmudflap.c/pass36-frag.c: New test.
+
+2003-03-11 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-runtime.h.in: Tweak.
+ * Makefile.am, configure.in: Tweak mf-runtime.h generation some more.
+ Don't use intermediate files nor AC_OUTPUT-time postprocessing.
+ * Makefile.in, testsuite/Makefile.in, configure: Regenerated.
+
+2003-03-10 Frank Ch. Eigler <fche@redhat.com>
+
+ * configure.in: Tweak generation of mf-runtime.h some more. It
+ needs to work from both config.status and configure.
+ * configure: Regenerated.
+
+2003-03-10 Frank Ch. Eigler <fche@redhat.com>
+
+ * Makefile.am: Reorganize hook file building. Add auto dependencies.
+ * configure.in: Tweak generation of mf-runtime.h.
+ * mf-runtime.h.in: Add new __MF_TYPE_HEAP_I.
+ * mf-hooks.c (*): Adapt to initialized-heap object type.
+ * mf-impl.h: Tweak cemetary boundaries.
+ * mf-runtime.c (__mf_check): Adapt to new initialized-heap object
+ type.
+ (__mf_insert_new_object, __mf_register, __mf_unregister): Ditto.
+ (__mf_describe_object, __mf_report_leaks, __mf_violation): Ditto.
+ * testsuite/lib/libmudflap.exp (includes): Include build tree.
+ * testsuite/libmudflap.c/pass{26,5}: Further adapt to initialization
+ checking.
+ * testsuite/.../fail{25,26}-frag.c: New tests.
+ * testsuite/.../pass{32,33,34,35}-frag.c: New tests.
+ * Makefile.in, configure: Regenerated.
+
+2003-03-05 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-runtime.c (__mf_set_default_options): Turn on initialization
+ checking by default.
+ (__mf_insert_new_object): As a temporary hack, assume that new
+ objects registered on the stack start out initialized.
+ * testsuite/libmudflap.c/fail9,pass23,pass[6789]-*: Initialize
+ heap objects by hand.
+
+2003-03-05 Frank Ch. Eigler <fche@redhat.com>
+
+ Switch to macro-style hooks for str*/mem*/b* functions.
+ * mf-runtime.h.in (__MF_TYPE_*): Moved some internal values out.
+ (mem*, str*, b*): Added macro-style hooks for _MUDFLAP case.
+ * mf-runtime.c: #include config.h to enable glibc backtraces again.
+ (__mf_set_default_options): Turn off heur_proc_map.
+ (*): Adapt to to macro-style hook functions.
+ (__mf_object_dead_head, __mf_object_cemetary): Correct bounds.
+ (__mf_check, __mf_register, __mf_unregister): Tweak tracing message.
+ (__mf_violation): Handle __MF_VIOL_WATCH.
+ * mf-impl.h (__MF_TYPE_*): Moved these internal values here.
+ (__mf_dynamic): Removed mem*/str*/b* functions.
+ (TRACE, VERBOSE_TRACE): Add reentrancy locking.
+ (WRAPPER2): New macro for macro-style hooks.
+ * mf-hooks.c: Convert mem*/str*/b* functions to simpler
+ macro-style hooks.
+ (BEGIN_PROTECT): Tweak tracing vs reentrancy-lock ordering.
+ * mf-heuristics.c: Adapt to macro-style hook functions.
+ Correct some comments.
+ * testsuite/lib/mfdg.exp (dg-test): Simplify result string for
+ output pattern tests.
+ * testsuite/libmudflap.c/fail[89]-frag.c: Elaborate output test.
+ * testsuite/libmudflap.c++/c++frags.exp: Enable non-static tests.
+
+2003-02-28 Frank Ch. Eigler <fche@redhat.com>
+
+ * testsuite/libmudflap.c/fail23-frag.c, pass30-frag.c: New tests
+ for global array registration.
+ * testsuite/libmudflap.c++/fail24-frag.cxx, pass31-frag.cxx: Ditto.
+ * testsuite/libmudflap.c++/c++frags.exp: Tweak -static multilib hack.
+
+2003-02-27 Frank Ch. Eigler <fche@redhat.com>
+
+ * Makefile.am: Add gross make bug workarounds. Tweaked
+ SUBDIRS and AM_CFLAGS.
+ * Makefile.in: Regenerated.
+
+2003-02-26 Frank Ch. Eigler <fche@redhat.com>
+
+ Switch to dejagnu.
+ * configure.in (AC_PROG_CXX): Don't look for C++ any more.
+ * Makefile.am (TESTS): Remove simple automake testing.
+ * configure, Makefile.in: Regenerated.
+ (SUBDIRS): Include new testsuite/ directory.
+ * tests/*: Removed all files; moved bulk under:
+ * testsuite/*: New subdirectory tree.
+ * testsuite/libmudflap.c/cfrags.exp: New file, C test driver.
+ * testsuite/libmudflap.c++/c++frags.exp: New file, C++ test driver.
+ * testsuite/lib/libmudflap.exp: New file, derived from libstdc++.
+ * testsuite/lib/mfdg.exp: New file, derived from dejagnu.
+ * testsuite/config/default.exp: New file.
+ * testsuite/Makefile.am, Makefile.in: New files.
+
+2003-01-29 Frank Ch. Eigler <fche@redhat.com>
+
+ * Makefile.am (TESTS_ENVIRONMENT): Remove redundant "-mode-check".
+ (TESTS): Add fail22 and pass29 tests.
+ * mf-runtime.h.in: Change API to take void*/size_t region parameters.
+ Add new access-type parameter for __mf_check. Move __MF_VIOL* out.
+ * mf-impl.h: Corresponding changes. Update CLAMP* macros for void*
+ values. Move __MF_VIOL* here.
+ * mf-runtime.c (*): Adapt to void*/size_t API in mf-runtime.h.
+ (check_initialization): New field in __mf_opts. Default off.
+ (read_count,write_count): New fields in __mf_object.
+ (__mf_check): Implement basic initialization checking.
+ (__mf_insert_new_object): Assume STATIC|GUESS regions are initialized.
+ (__mf_describe_object): Print new fields.
+ (__mf_violation): Identify check/read vs. check/write in messages.
+ * test/pass29-frag.c, test/fail22-frag.c: Basic tests for new
+ "-check-initialized" mudflap option.
+ * test/pass25-frag.c, test/fail21-frag.c: Adapt to API changes.
+ * mf-hooks.c (MF_VALIDATE_EXTENT): Add new access-type parameter.
+ Drop __FILE__/__LINE__ hack. Update callers.
+ (*): Adapt to new mf-runtime.h API.
+ * Makefile.in: regenerated.
+
+2003-01-24 Frank Ch. Eigler <fche@redhat.com>
+
+ * configure.in: Build mf-runtime.h a more proper way.
+ * mf-hooks.c (strdup, strndup): Correct reentrancy logic.
+ * mf-runtime.c (verbose_violations): Turn on by default.
+ * mf-runtime.h.in: Remove some miscellaneous stuff ...
+ * mf-impl.h: ... and move it here.
+ * configure: Regenerated.
+
+2003-01-22 Frank Ch. Eigler <fche@redhat.com>
+
+ * configure.in: Look for C++ compiler.
+ * test/*-frag.c, mf-driver.c: Reformatted with GNU indent and
+ fixed type warnings when built with C++.
+ * test/pass27-frag.cxx, pass28-frag.cxx: New C++ tests.
+ * Makefile.am (TESTS): Run them.
+ (*) Add new rules for building and running C++ tests.
+ (TESTFLAGS): Set new default to avoid libstdc++-v3 shlib issues.
+ * mf-runtime.h.in: Protect with extern "C".
+ * Makefile, configure: Regenerated.
+
+2003-01-06 Frank Ch. Eigler <fche@redhat.com>
+
+ Portability improvements.
+ * configure.in: Look for glibc backtrace headers/functions.
+ * mf-hooks.c: Don't include <execinfo.h> any more.
+ * mf-runtime.c (__mf_set_options): Call more stdlib functions
+ via CALL_REAL.
+ (__mf_backtrace): Provide alternate baby implementation in
+ absence of glibc.
+ * test/mf-driver.c: Portability tweaks.
+ * acinclude.m4: New file, containing top level libtool.m4.
+ * aclocal.m4, configure, Makefile.in, config.h.in: Regenerated.
+
+2002-12-19 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-runtime.h.in (HAVE_UINTPTR_T): Define unconditionally.
+
+2002-11-08 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-runtime.c (options): Add new "wipe-heap", "wipe-stack"
+ options.
+ (__mf_unregister): Implement stack/heap object wiping.
+ (__mf_set_options): Renamed from __mf_process_opts.
+ (__mf_uncache_object): Change arg type, correct callers.
+ * mf-impl.h: Corresponding changes.
+ * mf-hooks.c (realloc): Save/restore heap-wiping flag.
+ * mf-runtime.h.in (__mf_set_options): Extend public API.
+ * test/pass26-frag.c: New test for stack wiping.
+ * Makefile.am (TESTS): Run it.
+ * Makefile.in: Regenerated.
+
+2002-11-07 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-runtime.h.in (__mf_watch, __mf_unwatch): Extend public API.
+ * mf-runtime.c (__mf_object_t): Add watching_p field.
+ (__mf_watch_or_not): New function to implement
+ object watch flagging.
+ (__mf_watch, __mf_unwatch): New wrappers for above.
+ (__mf_check, __mf_describe_object): Handle objects with watching_p.
+ (__mf_count_violation): Enlarge array.
+ (__mf_uncache_object): Renamed from __mf_remove_old_object. Don't
+ unlink object. Clear cache properly.
+ (__mf_unregister): Unlink object explicitly before uncaching.
+ * test/fail21-frag.c, pass25-frag.c: New tests.
+ * Makefile.in, aclocal.m4: Regenerated.
+
+2002-11-05 Frank Ch. Eigler <fche@redhat.com>
+
+ * test/fail20-frag.c: New test for NULL pointer dereferencing.
+ * Makefile.am (TESTS): Add it.
+ * test/pass-stratcliff.c: Add decls of stpcpy.
+ * configure.in: Test for <stdint.h>. Generate mf-runtime.h in
+ build tree from config.h and new file mf-runtime.h.in.
+ * mf-runtime.h.in: Renamed from mf-runtime.h. Tweak uintptr_t decl.
+ * Makefile.in, configure, config.h.in: Regenerated.
+ * mf-hooks.c: Add #undef for wrapped glibc str*/mem* macros.
+ * mf-runtime.c (options, __mf_set_default_options): Support new
+ default "abbreviate" option.
+ (__mf_object.description_epoch): New field.
+ (__mf_describe_object): Conditionally abbreviate objects already
+ displayed in current epoch. Accept NULL input to increment epoch.
+ (__mf_fini, __mf_ini): Reset description epoch.
+ (__mf_register, __mf_unregister, __mf_adapt_cache, __mf_init): Ensure
+ that NULL pointer slot in lookup cache is invalidated. Register a
+ NOACCESS region around NULL.
+ * mf-impl.h: Corresponding changes.
+
+2002-10-16 Frank Ch. Eigler <fche@redhat.com>
+
+ * test/fail19-frag.c, pass24-frag.c, pass-stratcliff.c: New tests.
+ * Makefile.am: Run them. Install mf-runtime.h.
+ * Makefile.in: Regenerated.
+ * mf-hooks.c: Add some markers for more missing functions.
+ * mf-runtime.c (__mf_adapt_cache): Experiment with a utilization-based
+ statistic to tune tune cache size (mask).
+
+2002-10-01 Frank Ch. Eigler <fche@redhat.com>
+
+ * test/pass23-frag.c: New test for bit_field_ref expressions.
+ * Makefile.am, Makefile.in: Add new test.
+ * mf-hooks.c (mmap, munmap): Rewrite to track individual pages.
+ (MF_VALIDATE_EXTENT): Accept zero-size mem/str operations.
+ * mf-runtime.c (__mf_init): Register errno global.
+ (__mf_find_object): Removed function.
+ (__mf_check): Rewrite logic to support accesses across some
+ contiguous but distinctly registered objects.
+ (__mf_remove_old_object): Tolerate cache entries that span
+ contiguous objects.
+
+2002-09-30 Frank Ch. Eigler <fche@redhat.com>
+
+ * test/pass21-frag.c, pass22-frag.c: New tests: alloca, bitfields.
+ * Makefile.am, Makefile.in: Run new tests.
+ * mf-hooks.c (alloca): Correct stack direction logic.
+
+2002-09-26 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-impl.h (adapt_cache): New option.
+ * mf-runtime.c (__mf_set_default_options): Set its default value.
+ Tweak the tree_aging parameter down.
+ (__mf_check): Maintain separate counter for cache-adaptation.
+ (__mf_tree_analyze): New function to collect object tree stats.
+ (__mf_adapt_cache): New function to automate cache parameters.
+
+2002-09-24 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-heuristics.c (__init_misc, __mf_heuristic_check): Add
+ hypothetical #if-0'd argv/envp region registration.
+ * mf-runtime.c (__mf_init): Add kludged form of above.
+ (*) Add "heur_argv_environ" flag, default on, to govern this.
+ * mf-impl.h: Corresponding changes.
+
+2002-09-20 Frank Ch. Eigler <fche@redhat.com>
+
+ * test/fail18-frag.c: New test file for NOACCESS regions.
+ * Makefile.am (TESTS): Add new test.
+ * Makefile.in: Regenerated.
+
+ * mf-heuristics.c (__mf_heuristics_check): Correct deja_vu logic.
+ * mf-impl.h (tree_aging): Add new mudflap_option, default 1000000.
+ (optimize_object_tree): Remove unused mudflap_option.
+ * mf-runtime.h (__MF_TYPE_NOACCESS): New region type. Add printing
+ support throughout. Use .._MAX_CEM for cemetary upper bound.
+ * mf-runtime.c (__mf_init): Register __mf_* globals as NOACCESS
+ regions.
+ (__mf_object): Add new liveness field for use by tree aging.
+ (__mf_check): Trigger tree aging when needed.
+ (__mf_age_tree): New function to decay liveness field.
+ (__mf_find_objects_rec): Use liveness field to rotate tree.
+ (__mf_insert_new_object): Only provide backtrace for HEAP objects.
+ (__mf_unregister): Ditto.
+ (__mf_register): Tweak duplicate-static message.
+ (__mf_violation: Tweak nearby-object counter printing.
+
+2002-09-16 Frank Ch. Eigler <fche@redhat.com>
+
+ * test/pass20-frag.c: New test file.
+ * Makefile.am (TESTS): Reorganize. Add pass20 test.
+ * Makefile.in: Regenerated.
+
+ * mf-impl.h (TRACE_IN, TRACE_OUT): Remove macros. Update callers.
+ * mf-hooks.c (BEGIN_PROTECT): Add hook tracing here.
+ * mf-heuristic.c (__mf_heuristic_check): Track seen /proc/self/map
+ entries to avoid repeat registration.
+ * mf-runtime.c (__mf_object_cemetary): Don't bother bury GUESS regions.
+ (__mf_register, __mf_unregister): Rewrite GUESS handling logic.
+
+2002-09-09 Frank Ch. Eigler <fche@redhat.com>
+
+ * Makefile.am: Create test sources with #include, not cat>>.
+ * Makefile.in: Regenerated.
+ * test/buildtest.sh: Removed.
+ * test/driver.c (abort_handler, main): Be quiet.
+
+2002-09-06 Frank Ch. Eigler <fche@redhat.com>
+
+ * test/pass18-frag.c, pass19-frag.c: New tests.
+ * Makefile.am (check): Run them. Rebuild test programs each time.
+ * Makefile.in: Regenerated.
+
+2002-09-06 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-runtime.c (__mf_register): Correct SEGV-inducing error in
+ overlapping object search.
+ (__mf_violation): Likewise for nearby objects.
+ Improve nearby-object listing.
+
+ cleanup:
+ * mf-runtime.c, mf-hooks.c: Remove "{{{"/"}}}" folding marks.
+ * mf-heuristics.c (__mf_heuristic_check): Tweak message.
+
+2002-09-03 Frank Ch. Eigler <fche@redhat.com>
+
+ alloca support:
+ * Makefile.am (AM_CFLAGS): New definition of needed settings.
+ (HOOKOBJS): Add alloca-hook.o.
+ * mf-hooks.c (alloca): New function to implement alloca in libiberty
+ style.
+ * mf-runtime.c (__mf_report): Call alloca(0) to flush remaining blocks.
+ (__mf_backtrace): Reimplement without using alloca.
+ * Makefile.in: Regenerated.
+
+ cleanup:
+ * mf-hooks.c: Use VERBOSE_TRACE throughout instead of fprintf(stderr).
+ Correct signedness bugs in length-tracking variables.
+ * mf-impl.h: Make options unsigned.
+ (CALL_WRAP): New macro to parallel CALL_REAL().
+ (DECLARE): Remove erroneous ";" at end.
+ * mf-runtime.c, mf-hooks.c, mf-heuristics.c: Replace remaining %p
+ formatting specs with %08lx. Correct several compiler warnings.
+
+2002-08-28 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-runtime.c (__mf_violation): Try harder to locate nearby objects.
+
+2002-08-27 Frank Ch. Eigler <fche@redhat.com>
+
+ libmudflap hook breakup:
+ * Makefile.am (TESTS_ENVIRONMENT): Add ../../gcc to LD_LIBRARY_PATH
+ for libgcc_s.
+ (TESTS): Make dependent on libmudflap.
+ (HOOKOBJS): Break up mf-hooks.o into many little hook objects,
+ compiled from segments of mf-hooks.c.
+ * mf-hooks.c: Corresponding changes: wrap each function in
+ #ifdef/#endif.
+ * Makefile.in: Regenerated.
+
+ Heuristics reorganization:
+ * mf-heuristics.c (__mf_register_ro_sections, __mf_init_heuristics):
+ Remove these functions. Update callers.
+ (__mf_heuristic_check): Incorporate all the various heuristics.
+ Encode cacheability/retry judgement into trinary return value.
+ Separate start-end logic into a separate fallback heuristic. Only
+ register relevant /proc/self/map segments.
+ * mf-impl.h: Corresponding changes.
+ * mf-runtime.c (__mf_check): Reorganize heuristics fallback logic.
+ (__mf_init): Don't call __mf_init_heuristics.
+
+ Tracing cleanup:
+ * mf-heuristics.c, mf-runtime.c: Use new MUDFLAP_OPTION
+ "-verbose-trace" to emit all tracing messages other than those of
+ basic public api. Eliminate some duplicate/excessive messages.
+ * mf-runtime.h: Corresponding changes.
+
+2002-08-27 Graydon Hoare <graydon@redhat.com>
+
+ * mf-impl.h (WRAPPER): Change to create linker aliases for __wrap
+ and __real when compiled with -DPIC.
+ * mf-hooks.c (WRAPPER): Change all uses of WRAPPER macro slightly.
+ * Makefile.am (AUTOMAKE_OPTIONS): Fix LD_LIBRARY_PATH for tests.
+ * Makefile.in: Regenerate.
+
+2002-08-26 Graydon Hoare <graydon@redhat.com>
+
+ * mf-impl.h: New file, private implementation header.
+ * mf-runtime.h: Reorganize a bit.
+ (CLAMPSZ): Fix arithmetic.
+ (__MF_CACHE_MISS_P): Fix arithmetic.
+ * mf-runtime.c: Reorganize a bit.
+ (__mf_dynamic): New structure.
+ (resolve_single_dynamic): New function.
+ (__mf_resolve_dynamics): New function.
+ (__mf_init): Initialize dynamic wrappers.
+ * mf-hooks.c: Macro-ize __real calls.
+ Clamp various bits of arithmetic.
+ Add explicit __mf_check call contexts.
+ * Makefile.am: Add dependencies on mf-impl.h
+ * Makefile.in: Regenerate.
+ * configure.in: Comment out shared override.
+ * configure: Regenerate.
+
+2002-08-22 Graydon Hoare <graydon@redhat.com>
+
+ * mf-runtime.c (__mf_process_opts): Sanity-check free_queue_length.
+ (__mf_check): Re-inialize and check heuristics before violation.
+ (__mf_register): Permit updating pure-guess regions.
+ * mf-hooks.c (__wrap_free): Correct some free queue logic.
+ (__wrap_dlopen): New wrapper function.
+ (__wrap_mmap): New wrapper function.
+ (__wrap_munmap): New wrapper function.
+ * mf-heuristics.c (__mf_register_ro_sections): Register *all* regions
+ which are not stack addresses.
+ (is_stack_address): New function.
+ (__mf_init_heuristics): Save and restore state, always initialize with
+ "starting" state.
+
+2002-08-21 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-hooks.c (MF_VALIDATE_EXTENT): Rewrite to correct off-by-one
+ error. Pass location string.
+ (wrap_strcpy, wrap_strncpy): Remove extra %s in trace strings.
+ * mf-runtime.c (options): Add lc-mask, lc-shift options.
+ (__mf_process_opts): Apply some sanity checking for lc-mask.
+ (__mf_check, __mf_violation): Take new location-string argument.
+ Update callers to pass NULL if necessary.
+ (__mf_backtrace): New smart backtracer function. Calls replace
+ several ad-hoc blocks elsewhere.
+ (__mf_describe_object): Remove bad reentrancy test. Improve
+ tracing message.
+ * mf-runtime.h: Corresponding changes. Public/private markup.
+ (__MF_CACHE_MISS_P): New macro.
+
+2002-08-20 Graydon Hoare <graydon@redhat.com>
+
+ * mf-runtime.h: New option: stack_bound (heuristic).
+ Move some macros out of implementation files.
+ * mf-runtime.c: New option string: -stack-bound.
+ Unify recursion protection with hooks.
+ Add more logging.
+ (__mf_check): Call __mf_heuristic_check.
+ (__mf_process_opts): Fix "no-" processing.
+ * mf-heuristics.c (__mf_heuristic_check): New function.
+ * mf-hooks.c: Much off-by-one fixing, recursion protection.
+
+2002-08-20 Frank Ch. Eigler <fche@redhat.com>
+
+ Option parsing improvements, region splitting bug fixes:
+ * mf-heuristics.c (__mf_register_ro_sections): Add warned casts.
+ * mf-runtime.h (heur_proc_map): New libmudflap option.
+ * mf-runtime.c (__mf_set_default_options): Set it.
+ (__mf_usage): Print default values/status.
+ (__mf_process_opts): Support general "no-" option string prefix.
+ (__mf_init): Print __mf_usage on unknown-option error.
+ (__mf_register): Print trace message up front.
+ Correct region splitting logic for case where a subregion disappears.
+ Correct memory leak.
+ (__mf_violation): Make even basic message conditional on option.
+
+ Build cleanup:
+ * Makefile.am (TESTS_ENVIRONMENT): Add -no-heur-proc-map.
+ (clean-local): New target.
+ (test/*x rules): Add -g CFLAGS.
+ (CFLAGS): Add -freorder-blocks.
+ (MFCONFIG_CFLAGS, INCLUDE): Remove unneeded settings.
+ * Makefile.in: Regenerated.
+ * Makefile, mf-config.h: Removed files.
+
+2002-08-16 Graydon Hoare <graydon@redhat.com>
+
+ * mf-runtime.c (__mf_insert_new_object): Factor out of
+ __mf_register.
+ (__mf_remove_old_object): Factor out of __mf_unregister.
+ (__mf_register): Handle guessed regions, splitting
+ guesses when new registrations arrive.
+ (__mf_unregister): Do not unregister guesses.
+ * mf-runtime.h: Move convenience macros around,
+ declare new option fields. Add __MF_TYPE_GUESS.
+ * mf-hooks.c (__wrap_*alloc): Use crumple zones.
+ (__wrap_free): Call __real_free for deferred frees.
+ * Makefile.am: Add more tests, fix dependency.
+ * Makefile.in: Regenerate.
+ * test/pass[13..17]-frag.c: New testcases.
+ * test/fail[13..17]-frag.c: New testcases.
+
+2002-08-15 Graydon Hoare <graydon@redhat.com>
+
+ * mf-heuristics.c: New file.
+ * mf-runtime.c (options): Add -trace-calls option.
+ (__mf_init): Call __mf_init_heuristics.
+
+2002-08-14 Graydon Hoare <graydon@redhat.com>
+
+ * Makefile.am (TESTS): Add testsuite support.
+ * Makefile.in: Regenerate.
+ * test/mf-driver.c: New file.
+ * test/buildtest.sh: New file.
+ * test/passNN-frag.c: New testcases.
+ * test/failNN-frag.c: New testcases.
+
+2002-08-14 Graydon Hoare <graydon@redhat.com>
+
+ * mf-hooks.c: Change __real_strlen() to __real_strlen()+1 when
+ verifying non-size-limited string extents.
+
+2002-08-14 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-hooks.c: Make __wrap string* functions use __real_str[n]len
+ instead of plain str[n]len for internal checks.
+ * mf-runtime.c (__mf_violation): Print optional stack traceback.
+
+2002-08-14 Frank Ch. Eigler <fche@redhat.com>
+
+ * mf-hooks.c: Remove #if-0 around hooks that are now ld-wrapped.
+
+2002-08-13 Graydon Hoare <graydon@redhat.com>
+
+ * mf-runtime.c: Rework configuration to operate on
+ environment variable options rather than #defines
+ (__mf_violation): Add simple fork-a-gdb violaiton mode.
+ (__mf_init): Set static __mf_active_p flag on startup,
+ to inhibit mudflap wrap-based checking during crt0.s.
+ * mf-runtime.h: Declare options structure.
+ * mf-hooks.c: New wrappings for mem*, b*, str*
+ libc functions (temporarily #if 0-ed out).
+
+2002-08-12 Frank Ch. Eigler <fche@redhat.com>
+
+ * Makefile.am, configure.in: New files.
+ * Makefile.in, Makefile, configure, config.h.in: New generated files.
+ * stamp-h.in, aclocal.m4: Ditto.
+
+2002-08-08 Frank Ch. Eigler <fche@redhat.com>
+
+ * Makefile: New file.
+ * mf-config.h: New file: runtime configuration.
+ * mf-hooks.c: New file: interposed libc functions.
+ * mf-runtime.c: New file: bulk of runtime.
+ * mf-runtime.h: New file: public functions.
+
diff --git a/libmudflap/Makefile.am b/libmudflap/Makefile.am
new file mode 100644
index 00000000000..c5a07490f26
--- /dev/null
+++ b/libmudflap/Makefile.am
@@ -0,0 +1,388 @@
+## Makefile for the toplevel directory of the mudflap library.
+##
+## Copyright (C) 2002, 2003
+## Free Software Foundation, Inc.
+##
+
+AUTOMAKE_OPTIONS = 1.3 foreign
+MAINT_CHARSET = latin1
+SUBDIRS = testsuite
+
+AM_CFLAGS = -Wall
+
+if LIBMUDFLAPTH
+libmudflapth = libmudflapth.la
+else
+libmudflapth =
+endif
+
+lib_LTLIBRARIES = libmudflap.la $(libmudflapth)
+include_HEADERS = mf-runtime.h
+
+libmudflap_la_SOURCES = \
+ mf-runtime.c \
+ mf-heuristics.c
+
+HOOK1OBJS = \
+ malloc-hook.lo \
+ free-hook.lo \
+ calloc-hook.lo \
+ realloc-hook.lo \
+ mmap-hook.lo \
+ munmap-hook.lo \
+ alloca-hook.lo
+
+HOOK2OBJS = \
+ memcpy-hook.lo \
+ memmove-hook.lo \
+ memset-hook.lo \
+ memcmp-hook.lo \
+ memchr-hook.lo \
+ memrchr-hook.lo \
+ strcpy-hook.lo \
+ strncpy-hook.lo \
+ strcat-hook.lo \
+ strncat-hook.lo \
+ strcmp-hook.lo \
+ strcasecmp-hook.lo \
+ strncmp-hook.lo \
+ strncasecmp-hook.lo \
+ strdup-hook.lo \
+ strndup-hook.lo \
+ strchr-hook.lo \
+ strrchr-hook.lo \
+ strstr-hook.lo \
+ memmem-hook.lo \
+ strlen-hook.lo \
+ strnlen-hook.lo \
+ bzero-hook.lo \
+ bcopy-hook.lo \
+ bcmp-hook.lo \
+ index-hook.lo \
+ rindex-hook.lo \
+ asctime-hook.lo \
+ ctime-hook.lo \
+ gmtime-hook.lo \
+ localtime-hook.lo \
+ time-hook.lo \
+ strerror-hook.lo \
+ fopen-hook.lo \
+ fclose-hook.lo \
+ fread-hook.lo \
+ fwrite-hook.lo \
+ fgetc-hook.lo \
+ fgets-hook.lo \
+ getc-hook.lo \
+ gets-hook.lo \
+ ungetc-hook.lo \
+ fputc-hook.lo \
+ fputs-hook.lo \
+ putc-hook.lo \
+ puts-hook.lo \
+ clearerr-hook.lo \
+ feof-hook.lo \
+ ferror-hook.lo \
+ fileno-hook.lo \
+ printf-hook.lo \
+ fprintf-hook.lo \
+ sprintf-hook.lo \
+ snprintf-hook.lo \
+ vprintf-hook.lo \
+ vfprintf-hook.lo \
+ vsprintf-hook.lo \
+ vsnprintf-hook.lo \
+ access-hook.lo \
+ remove-hook.lo \
+ fflush-hook.lo \
+ fseek-hook.lo \
+ ftell-hook.lo \
+ rewind-hook.lo \
+ fgetpos-hook.lo \
+ fsetpos-hook.lo \
+ stat-hook.lo \
+ fstat-hook.lo \
+ lstat-hook.lo \
+ mkfifo-hook.lo \
+ setvbuf-hook.lo \
+ setbuf-hook.lo \
+ opendir-hook.lo \
+ closedir-hook.lo \
+ readdir-hook.lo \
+ recv-hook.lo \
+ recvfrom-hook.lo \
+ recvmsg-hook.lo \
+ send-hook.lo \
+ sendto-hook.lo \
+ sendmsg-hook.lo \
+ setsockopt-hook.lo \
+ getsockopt-hook.lo \
+ accept-hook.lo \
+ bind-hook.lo \
+ connect-hook.lo \
+ gethostname-hook.lo \
+ sethostname-hook.lo \
+ gethostbyname-hook.lo \
+ wait-hook.lo \
+ waitpid-hook.lo \
+ popen-hook.lo \
+ pclose-hook.lo \
+ execve-hook.lo \
+ execv-hook.lo \
+ execvp-hook.lo \
+ system-hook.lo \
+ dlopen-hook.lo \
+ dlerror-hook.lo \
+ dlsym-hook.lo \
+ dlclose-hook.lo \
+ fopen64-hook.lo \
+ stat64-hook.lo \
+ fseeko64-hook.lo \
+ ftello64-hook.lo \
+ semop-hook.lo \
+ semctl-hook.lo \
+ shmctl-hook.lo \
+ shmat-hook.lo \
+ shmdt-hook.lo
+HOOK3OBJS =
+
+$(HOOK1OBJS): mf-hooks1.c mf-runtime.h mf-impl.h
+ hook=`basename $@ -hook.lo`; \
+ $(LTCOMPILE) -DWRAP_$$hook -c $(srcdir)/mf-hooks1.c -o $@
+$(HOOK2OBJS): mf-hooks2.c mf-runtime.h mf-impl.h
+ hook=`basename $@ -hook.lo`; \
+ $(LTCOMPILE) -DWRAP_$$hook -c $(srcdir)/mf-hooks2.c -o $@
+$(HOOK3OBJS): mf-hooks3.c mf-runtime.h mf-impl.h
+ hook=`basename $@ -hook.lo`; \
+ $(LTCOMPILE) -DWRAP_$$hook -c $(srcdir)/mf-hooks3.c -o $@
+
+# Hook objects only for libmudflapth use
+PTHHOOK1OBJS= \
+ pth/malloc-hook.lo \
+ pth/free-hook.lo \
+ pth/calloc-hook.lo \
+ pth/realloc-hook.lo \
+ pth/mmap-hook.lo \
+ pth/munmap-hook.lo \
+ pth/alloca-hook.lo
+
+PTHHOOK2OBJS= \
+ pth/memcpy-hook.lo \
+ pth/memmove-hook.lo \
+ pth/memset-hook.lo \
+ pth/memcmp-hook.lo \
+ pth/memchr-hook.lo \
+ pth/memrchr-hook.lo \
+ pth/strcpy-hook.lo \
+ pth/strncpy-hook.lo \
+ pth/strcat-hook.lo \
+ pth/strncat-hook.lo \
+ pth/strcmp-hook.lo \
+ pth/strcasecmp-hook.lo \
+ pth/strncmp-hook.lo \
+ pth/strncasecmp-hook.lo \
+ pth/strdup-hook.lo \
+ pth/strndup-hook.lo \
+ pth/strchr-hook.lo \
+ pth/strrchr-hook.lo \
+ pth/strstr-hook.lo \
+ pth/memmem-hook.lo \
+ pth/strlen-hook.lo \
+ pth/strnlen-hook.lo \
+ pth/bzero-hook.lo \
+ pth/bcopy-hook.lo \
+ pth/bcmp-hook.lo \
+ pth/index-hook.lo \
+ pth/rindex-hook.lo \
+ pth/asctime-hook.lo \
+ pth/ctime-hook.lo \
+ pth/gmtime-hook.lo \
+ pth/localtime-hook.lo \
+ pth/time-hook.lo \
+ pth/strerror-hook.lo \
+ pth/fopen-hook.lo \
+ pth/fclose-hook.lo \
+ pth/fread-hook.lo \
+ pth/fwrite-hook.lo \
+ pth/fgetc-hook.lo \
+ pth/fgets-hook.lo \
+ pth/getc-hook.lo \
+ pth/gets-hook.lo \
+ pth/ungetc-hook.lo \
+ pth/fputc-hook.lo \
+ pth/fputs-hook.lo \
+ pth/putc-hook.lo \
+ pth/puts-hook.lo \
+ pth/clearerr-hook.lo \
+ pth/feof-hook.lo \
+ pth/ferror-hook.lo \
+ pth/fileno-hook.lo \
+ pth/printf-hook.lo \
+ pth/fprintf-hook.lo \
+ pth/sprintf-hook.lo \
+ pth/snprintf-hook.lo \
+ pth/vprintf-hook.lo \
+ pth/vfprintf-hook.lo \
+ pth/vsprintf-hook.lo \
+ pth/vsnprintf-hook.lo \
+ pth/access-hook.lo \
+ pth/remove-hook.lo \
+ pth/fflush-hook.lo \
+ pth/fseek-hook.lo \
+ pth/ftell-hook.lo \
+ pth/rewind-hook.lo \
+ pth/fgetpos-hook.lo \
+ pth/fsetpos-hook.lo \
+ pth/stat-hook.lo \
+ pth/fstat-hook.lo \
+ pth/lstat-hook.lo \
+ pth/mkfifo-hook.lo \
+ pth/setvbuf-hook.lo \
+ pth/setbuf-hook.lo \
+ pth/opendir-hook.lo \
+ pth/closedir-hook.lo \
+ pth/readdir-hook.lo \
+ pth/recv-hook.lo \
+ pth/recvfrom-hook.lo \
+ pth/recvmsg-hook.lo \
+ pth/send-hook.lo \
+ pth/sendto-hook.lo \
+ pth/sendmsg-hook.lo \
+ pth/setsockopt-hook.lo \
+ pth/getsockopt-hook.lo \
+ pth/accept-hook.lo \
+ pth/bind-hook.lo \
+ pth/connect-hook.lo \
+ pth/gethostname-hook.lo \
+ pth/sethostname-hook.lo \
+ pth/gethostbyname-hook.lo \
+ pth/wait-hook.lo \
+ pth/waitpid-hook.lo \
+ pth/popen-hook.lo \
+ pth/pclose-hook.lo \
+ pth/execve-hook.lo \
+ pth/execv-hook.lo \
+ pth/execvp-hook.lo \
+ pth/system-hook.lo \
+ pth/dlopen-hook.lo \
+ pth/dlerror-hook.lo \
+ pth/dlsym-hook.lo \
+ pth/dlclose-hook.lo \
+ pth/fopen64-hook.lo \
+ pth/stat64-hook.lo \
+ pth/fseeko64-hook.lo \
+ pth/ftello64-hook.lo \
+ pth/semop-hook.lo \
+ pth/semctl-hook.lo \
+ pth/shmctl-hook.lo \
+ pth/shmat-hook.lo \
+ pth/shmdt-hook.lo
+
+PTHHOOK3OBJS= \
+ pth/pthreadstuff-hook.lo
+
+
+clean-local:
+ rm -f pth/*.o pth/*.lo
+
+libmudflapth_la_SOURCES =
+pth/mf-runtime.lo: mf-runtime.c mf-runtime.h mf-impl.h
+ $(LTCOMPILE) -DLIBMUDFLAPTH -c $(srcdir)/mf-runtime.c -o $@
+pth/mf-heuristics.lo: mf-heuristics.c mf-runtime.h mf-impl.h
+ $(LTCOMPILE) -DLIBMUDFLAPTH -c $(srcdir)/mf-heuristics.c -o $@
+$(PTHHOOK1OBJS): mf-hooks1.c mf-runtime.h mf-impl.h
+ hook=`basename $@ -hook.lo`; \
+ $(LTCOMPILE) -DLIBMUDFLAPTH -DWRAP_$$hook -c $(srcdir)/mf-hooks1.c -o $@
+$(PTHHOOK2OBJS): mf-hooks2.c mf-runtime.h mf-impl.h
+ hook=`basename $@ -hook.lo`; \
+ $(LTCOMPILE) -DLIBMUDFLAPTH -DWRAP_$$hook -c $(srcdir)/mf-hooks2.c -o $@
+$(PTHHOOK3OBJS): mf-hooks3.c mf-runtime.h mf-impl.h
+ hook=`basename $@ -hook.lo`; \
+ $(LTCOMPILE) -DLIBMUDFLAPTH -DWRAP_$$hook -c $(srcdir)/mf-hooks3.c -o $@
+
+libmudflap_la_LIBADD = $(HOOK1OBJS) $(HOOK2OBJS) $(HOOK3OBJS)
+libmudflap_la_DEPENDENCIES = $(libmudflap_la_LIBADD)
+
+libmudflapth_la_LIBADD = pth/mf-runtime.lo pth/mf-heuristics.lo \
+ $(PTHHOOK1OBJS) $(PTHHOOK2OBJS) $(PTHHOOK3OBJS)
+libmudflapth_la_DEPENDENCIES = $(libmudflapth_la_LIBADD)
+
+
+
+# XXX hack alert
+# From libffi/Makefile.am
+
+# Work around what appears to be a GNU make bug handling MAKEFLAGS
+# values defined in terms of make variables, as is the case for CC and
+# friends when we are called from the top level Makefile.
+AM_MAKEFLAGS = \
+ "AR_FLAGS=$(AR_FLAGS)" \
+ "CC_FOR_BUILD=$(CC_FOR_BUILD)" \
+ "CFLAGS=$(CFLAGS)" \
+ "CXXFLAGS=$(CXXFLAGS)" \
+ "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
+ "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
+ "INSTALL=$(INSTALL)" \
+ "INSTALL_DATA=$(INSTALL_DATA)" \
+ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+ "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
+ "JC1FLAGS=$(JC1FLAGS)" \
+ "LDFLAGS=$(LDFLAGS)" \
+ "LIBCFLAGS=$(LIBCFLAGS)" \
+ "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
+ "MAKE=$(MAKE)" \
+ "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
+ "PICFLAG=$(PICFLAG)" \
+ "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
+ "SHELL=$(SHELL)" \
+ "exec_prefix=$(exec_prefix)" \
+ "infodir=$(infodir)" \
+ "libdir=$(libdir)" \
+ "prefix=$(prefix)" \
+ "AR=$(AR)" \
+ "AS=$(AS)" \
+ "CC=$(CC)" \
+ "CXX=$(CXX)" \
+ "LD=$(LD)" \
+ "LIBCFLAGS=$(LIBCFLAGS)" \
+ "NM=$(NM)" \
+ "PICFLAG=$(PICFLAG)" \
+ "RANLIB=$(RANLIB)" \
+ "DESTDIR=$(DESTDIR)"
+
+MAKEOVERRIDES=
+
+# Multilib support variables.
+MULTISRCTOP =
+MULTIBUILDTOP =
+MULTIDIRS =
+MULTISUBDIR =
+MULTIDO = true
+MULTICLEAN = true
+
+# Multilib support.
+.PHONY: all-multi mostlyclean-multi clean-multi distclean-multi \
+ maintainer-clean-multi
+
+all-recursive: all-multi
+install-recursive: install-multi
+mostlyclean-recursive: mostlyclean-multi
+clean-recursive: clean-multi
+distclean-recursive: distclean-multi
+maintainer-clean-recursive: maintainer-clean-multi
+
+all-multi:
+ : $(MAKE) ; exec $(MULTIDO) $(AM_MAKEFLAGS) DO=all multi-do
+install-multi:
+ $(MULTIDO) $(AM_MAKEFLAGS) DO=install multi-do
+mostlyclean-multi:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=mostlyclean multi-clean
+clean-multi:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=clean multi-clean
+distclean-multi:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean
+maintainer-clean-multi:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean
+
+
+## ################################################################
+
diff --git a/libmudflap/Makefile.in b/libmudflap/Makefile.in
new file mode 100644
index 00000000000..c21b2dc335f
--- /dev/null
+++ b/libmudflap/Makefile.in
@@ -0,0 +1,918 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AS = @AS@
+CC = @CC@
+CPP = @CPP@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+DLLTOOL = @DLLTOOL@
+EXEEXT = @EXEEXT@
+GCJ = @GCJ@
+GCJFLAGS = @GCJFLAGS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MF_HAVE_STDINT_H = @MF_HAVE_STDINT_H@
+MF_HAVE_UINTPTR_T = @MF_HAVE_UINTPTR_T@
+NM = @NM@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+STRIP = @STRIP@
+VERSION = @VERSION@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
+libtool_VERSION = @libtool_VERSION@
+
+AUTOMAKE_OPTIONS = 1.3 foreign
+MAINT_CHARSET = latin1
+SUBDIRS = testsuite
+
+AM_CFLAGS = -Wall
+@LIBMUDFLAPTH_TRUE@libmudflapth = @LIBMUDFLAPTH_TRUE@libmudflapth.la
+@LIBMUDFLAPTH_FALSE@libmudflapth =
+
+lib_LTLIBRARIES = libmudflap.la $(libmudflapth)
+include_HEADERS = mf-runtime.h
+
+libmudflap_la_SOURCES = \
+ mf-runtime.c \
+ mf-heuristics.c
+
+
+HOOK1OBJS = \
+ malloc-hook.lo \
+ free-hook.lo \
+ calloc-hook.lo \
+ realloc-hook.lo \
+ mmap-hook.lo \
+ munmap-hook.lo \
+ alloca-hook.lo
+
+
+HOOK2OBJS = \
+ memcpy-hook.lo \
+ memmove-hook.lo \
+ memset-hook.lo \
+ memcmp-hook.lo \
+ memchr-hook.lo \
+ memrchr-hook.lo \
+ strcpy-hook.lo \
+ strncpy-hook.lo \
+ strcat-hook.lo \
+ strncat-hook.lo \
+ strcmp-hook.lo \
+ strcasecmp-hook.lo \
+ strncmp-hook.lo \
+ strncasecmp-hook.lo \
+ strdup-hook.lo \
+ strndup-hook.lo \
+ strchr-hook.lo \
+ strrchr-hook.lo \
+ strstr-hook.lo \
+ memmem-hook.lo \
+ strlen-hook.lo \
+ strnlen-hook.lo \
+ bzero-hook.lo \
+ bcopy-hook.lo \
+ bcmp-hook.lo \
+ index-hook.lo \
+ rindex-hook.lo \
+ asctime-hook.lo \
+ ctime-hook.lo \
+ gmtime-hook.lo \
+ localtime-hook.lo \
+ time-hook.lo \
+ strerror-hook.lo \
+ fopen-hook.lo \
+ fclose-hook.lo \
+ fread-hook.lo \
+ fwrite-hook.lo \
+ fgetc-hook.lo \
+ fgets-hook.lo \
+ getc-hook.lo \
+ gets-hook.lo \
+ ungetc-hook.lo \
+ fputc-hook.lo \
+ fputs-hook.lo \
+ putc-hook.lo \
+ puts-hook.lo \
+ clearerr-hook.lo \
+ feof-hook.lo \
+ ferror-hook.lo \
+ fileno-hook.lo \
+ printf-hook.lo \
+ fprintf-hook.lo \
+ sprintf-hook.lo \
+ snprintf-hook.lo \
+ vprintf-hook.lo \
+ vfprintf-hook.lo \
+ vsprintf-hook.lo \
+ vsnprintf-hook.lo \
+ access-hook.lo \
+ remove-hook.lo \
+ fflush-hook.lo \
+ fseek-hook.lo \
+ ftell-hook.lo \
+ rewind-hook.lo \
+ fgetpos-hook.lo \
+ fsetpos-hook.lo \
+ stat-hook.lo \
+ fstat-hook.lo \
+ lstat-hook.lo \
+ mkfifo-hook.lo \
+ setvbuf-hook.lo \
+ setbuf-hook.lo \
+ opendir-hook.lo \
+ closedir-hook.lo \
+ readdir-hook.lo \
+ recv-hook.lo \
+ recvfrom-hook.lo \
+ recvmsg-hook.lo \
+ send-hook.lo \
+ sendto-hook.lo \
+ sendmsg-hook.lo \
+ setsockopt-hook.lo \
+ getsockopt-hook.lo \
+ accept-hook.lo \
+ bind-hook.lo \
+ connect-hook.lo \
+ gethostname-hook.lo \
+ sethostname-hook.lo \
+ gethostbyname-hook.lo \
+ wait-hook.lo \
+ waitpid-hook.lo \
+ popen-hook.lo \
+ pclose-hook.lo \
+ execve-hook.lo \
+ execv-hook.lo \
+ execvp-hook.lo \
+ system-hook.lo \
+ dlopen-hook.lo \
+ dlerror-hook.lo \
+ dlsym-hook.lo \
+ dlclose-hook.lo \
+ fopen64-hook.lo \
+ stat64-hook.lo \
+ fseeko64-hook.lo \
+ ftello64-hook.lo \
+ semop-hook.lo \
+ semctl-hook.lo \
+ shmctl-hook.lo \
+ shmat-hook.lo \
+ shmdt-hook.lo
+
+HOOK3OBJS =
+
+# Hook objects only for libmudflapth use
+PTHHOOK1OBJS = \
+ pth/malloc-hook.lo \
+ pth/free-hook.lo \
+ pth/calloc-hook.lo \
+ pth/realloc-hook.lo \
+ pth/mmap-hook.lo \
+ pth/munmap-hook.lo \
+ pth/alloca-hook.lo
+
+
+PTHHOOK2OBJS = \
+ pth/memcpy-hook.lo \
+ pth/memmove-hook.lo \
+ pth/memset-hook.lo \
+ pth/memcmp-hook.lo \
+ pth/memchr-hook.lo \
+ pth/memrchr-hook.lo \
+ pth/strcpy-hook.lo \
+ pth/strncpy-hook.lo \
+ pth/strcat-hook.lo \
+ pth/strncat-hook.lo \
+ pth/strcmp-hook.lo \
+ pth/strcasecmp-hook.lo \
+ pth/strncmp-hook.lo \
+ pth/strncasecmp-hook.lo \
+ pth/strdup-hook.lo \
+ pth/strndup-hook.lo \
+ pth/strchr-hook.lo \
+ pth/strrchr-hook.lo \
+ pth/strstr-hook.lo \
+ pth/memmem-hook.lo \
+ pth/strlen-hook.lo \
+ pth/strnlen-hook.lo \
+ pth/bzero-hook.lo \
+ pth/bcopy-hook.lo \
+ pth/bcmp-hook.lo \
+ pth/index-hook.lo \
+ pth/rindex-hook.lo \
+ pth/asctime-hook.lo \
+ pth/ctime-hook.lo \
+ pth/gmtime-hook.lo \
+ pth/localtime-hook.lo \
+ pth/time-hook.lo \
+ pth/strerror-hook.lo \
+ pth/fopen-hook.lo \
+ pth/fclose-hook.lo \
+ pth/fread-hook.lo \
+ pth/fwrite-hook.lo \
+ pth/fgetc-hook.lo \
+ pth/fgets-hook.lo \
+ pth/getc-hook.lo \
+ pth/gets-hook.lo \
+ pth/ungetc-hook.lo \
+ pth/fputc-hook.lo \
+ pth/fputs-hook.lo \
+ pth/putc-hook.lo \
+ pth/puts-hook.lo \
+ pth/clearerr-hook.lo \
+ pth/feof-hook.lo \
+ pth/ferror-hook.lo \
+ pth/fileno-hook.lo \
+ pth/printf-hook.lo \
+ pth/fprintf-hook.lo \
+ pth/sprintf-hook.lo \
+ pth/snprintf-hook.lo \
+ pth/vprintf-hook.lo \
+ pth/vfprintf-hook.lo \
+ pth/vsprintf-hook.lo \
+ pth/vsnprintf-hook.lo \
+ pth/access-hook.lo \
+ pth/remove-hook.lo \
+ pth/fflush-hook.lo \
+ pth/fseek-hook.lo \
+ pth/ftell-hook.lo \
+ pth/rewind-hook.lo \
+ pth/fgetpos-hook.lo \
+ pth/fsetpos-hook.lo \
+ pth/stat-hook.lo \
+ pth/fstat-hook.lo \
+ pth/lstat-hook.lo \
+ pth/mkfifo-hook.lo \
+ pth/setvbuf-hook.lo \
+ pth/setbuf-hook.lo \
+ pth/opendir-hook.lo \
+ pth/closedir-hook.lo \
+ pth/readdir-hook.lo \
+ pth/recv-hook.lo \
+ pth/recvfrom-hook.lo \
+ pth/recvmsg-hook.lo \
+ pth/send-hook.lo \
+ pth/sendto-hook.lo \
+ pth/sendmsg-hook.lo \
+ pth/setsockopt-hook.lo \
+ pth/getsockopt-hook.lo \
+ pth/accept-hook.lo \
+ pth/bind-hook.lo \
+ pth/connect-hook.lo \
+ pth/gethostname-hook.lo \
+ pth/sethostname-hook.lo \
+ pth/gethostbyname-hook.lo \
+ pth/wait-hook.lo \
+ pth/waitpid-hook.lo \
+ pth/popen-hook.lo \
+ pth/pclose-hook.lo \
+ pth/execve-hook.lo \
+ pth/execv-hook.lo \
+ pth/execvp-hook.lo \
+ pth/system-hook.lo \
+ pth/dlopen-hook.lo \
+ pth/dlerror-hook.lo \
+ pth/dlsym-hook.lo \
+ pth/dlclose-hook.lo \
+ pth/fopen64-hook.lo \
+ pth/stat64-hook.lo \
+ pth/fseeko64-hook.lo \
+ pth/ftello64-hook.lo \
+ pth/semop-hook.lo \
+ pth/semctl-hook.lo \
+ pth/shmctl-hook.lo \
+ pth/shmat-hook.lo \
+ pth/shmdt-hook.lo
+
+
+PTHHOOK3OBJS = \
+ pth/pthreadstuff-hook.lo
+
+
+libmudflapth_la_SOURCES =
+
+libmudflap_la_LIBADD = $(HOOK1OBJS) $(HOOK2OBJS) $(HOOK3OBJS)
+libmudflap_la_DEPENDENCIES = $(libmudflap_la_LIBADD)
+
+libmudflapth_la_LIBADD = pth/mf-runtime.lo pth/mf-heuristics.lo \
+ $(PTHHOOK1OBJS) $(PTHHOOK2OBJS) $(PTHHOOK3OBJS)
+
+libmudflapth_la_DEPENDENCIES = $(libmudflapth_la_LIBADD)
+
+# XXX hack alert
+# From libffi/Makefile.am
+
+# Work around what appears to be a GNU make bug handling MAKEFLAGS
+# values defined in terms of make variables, as is the case for CC and
+# friends when we are called from the top level Makefile.
+AM_MAKEFLAGS = \
+ "AR_FLAGS=$(AR_FLAGS)" \
+ "CC_FOR_BUILD=$(CC_FOR_BUILD)" \
+ "CFLAGS=$(CFLAGS)" \
+ "CXXFLAGS=$(CXXFLAGS)" \
+ "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
+ "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
+ "INSTALL=$(INSTALL)" \
+ "INSTALL_DATA=$(INSTALL_DATA)" \
+ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+ "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
+ "JC1FLAGS=$(JC1FLAGS)" \
+ "LDFLAGS=$(LDFLAGS)" \
+ "LIBCFLAGS=$(LIBCFLAGS)" \
+ "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
+ "MAKE=$(MAKE)" \
+ "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
+ "PICFLAG=$(PICFLAG)" \
+ "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
+ "SHELL=$(SHELL)" \
+ "exec_prefix=$(exec_prefix)" \
+ "infodir=$(infodir)" \
+ "libdir=$(libdir)" \
+ "prefix=$(prefix)" \
+ "AR=$(AR)" \
+ "AS=$(AS)" \
+ "CC=$(CC)" \
+ "CXX=$(CXX)" \
+ "LD=$(LD)" \
+ "LIBCFLAGS=$(LIBCFLAGS)" \
+ "NM=$(NM)" \
+ "PICFLAG=$(PICFLAG)" \
+ "RANLIB=$(RANLIB)" \
+ "DESTDIR=$(DESTDIR)"
+
+
+MAKEOVERRIDES =
+
+# Multilib support variables.
+MULTISRCTOP =
+MULTIBUILDTOP =
+MULTIDIRS =
+MULTISUBDIR =
+MULTIDO = true
+MULTICLEAN = true
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = mf-runtime.h
+LTLIBRARIES = $(lib_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I.
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+libmudflap_la_LDFLAGS =
+libmudflap_la_OBJECTS = mf-runtime.lo mf-heuristics.lo
+libmudflapth_la_LDFLAGS =
+libmudflapth_la_OBJECTS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+HEADERS = $(include_HEADERS)
+
+DIST_COMMON = ./stamp-h.in ChangeLog Makefile.am Makefile.in \
+acinclude.m4 aclocal.m4 config.h.in configure configure.in \
+mf-runtime.h.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = gtar
+GZIP_ENV = --best
+DEP_FILES = .deps/mf-heuristics.P .deps/mf-runtime.P
+SOURCES = $(libmudflap_la_SOURCES) $(libmudflapth_la_SOURCES)
+OBJECTS = $(libmudflap_la_OBJECTS) $(libmudflapth_la_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .obj .s
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
+ cd $(top_builddir) \
+ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in acinclude.m4
+ cd $(srcdir) && $(ACLOCAL)
+
+config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+config.h: stamp-h
+ @if test ! -f $@; then \
+ rm -f stamp-h; \
+ $(MAKE) stamp-h; \
+ else :; fi
+stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES= CONFIG_HEADERS=config.h \
+ $(SHELL) ./config.status
+ @echo timestamp > stamp-h 2> /dev/null
+$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@$(srcdir)/stamp-h.in
+ @if test ! -f $@; then \
+ rm -f $(srcdir)/stamp-h.in; \
+ $(MAKE) $(srcdir)/stamp-h.in; \
+ else :; fi
+$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOHEADER)
+ @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+ -rm -f config.h
+
+maintainer-clean-hdr:
+mf-runtime.h: $(top_builddir)/config.status mf-runtime.h.in
+ cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+mostlyclean-libLTLIBRARIES:
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+
+distclean-libLTLIBRARIES:
+
+maintainer-clean-libLTLIBRARIES:
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
+ $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+ done
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libmudflap.la: $(libmudflap_la_OBJECTS) $(libmudflap_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libmudflap_la_LDFLAGS) $(libmudflap_la_OBJECTS) $(libmudflap_la_LIBADD) $(LIBS)
+
+libmudflapth.la: $(libmudflapth_la_OBJECTS) $(libmudflapth_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libmudflapth_la_LDFLAGS) $(libmudflapth_la_OBJECTS) $(libmudflapth_la_LIBADD) $(LIBS)
+
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(includedir)
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ list='$(include_HEADERS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(includedir)/$$p; \
+ done
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ test "$$subdir" = "." && dot_seen=yes; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ -rm -rf $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+ mkdir $(distdir)/=build
+ mkdir $(distdir)/=inst
+ dc_install_base=`cd $(distdir)/=inst && pwd`; \
+ cd $(distdir)/=build \
+ && ../configure --srcdir=.. --prefix=$$dc_install_base \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) dist
+ -rm -rf $(distdir)
+ @banner="$(distdir).tar.gz is ready for distribution"; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"
+dist: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+dist-all: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+distdir: $(DISTFILES)
+ -rm -rf $(distdir)
+ mkdir $(distdir)
+ -chmod 777 $(distdir)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign Makefile
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$d/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ for subdir in $(SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am: all-am
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+all-recursive-am: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+install-exec-am: install-libLTLIBRARIES
+install-exec: install-exec-recursive
+
+install-data-am: install-includeHEADERS
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am: uninstall-libLTLIBRARIES uninstall-includeHEADERS
+uninstall: uninstall-recursive
+all-am: Makefile $(LTLIBRARIES) $(HEADERS) config.h
+all-redirect: all-recursive-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+ $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-hdr mostlyclean-libLTLIBRARIES \
+ mostlyclean-compile mostlyclean-libtool \
+ mostlyclean-tags mostlyclean-depend mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-hdr clean-libLTLIBRARIES clean-compile clean-libtool \
+ clean-tags clean-depend clean-generic mostlyclean-am \
+ clean-local
+
+clean: clean-recursive
+
+distclean-am: distclean-hdr distclean-libLTLIBRARIES distclean-compile \
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-recursive
+ -rm -f config.status
+
+maintainer-clean-am: maintainer-clean-hdr \
+ maintainer-clean-libLTLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f config.status
+
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
+mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \
+clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \
+uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool uninstall-includeHEADERS \
+install-includeHEADERS install-data-recursive uninstall-data-recursive \
+install-exec-recursive uninstall-exec-recursive installdirs-recursive \
+uninstalldirs-recursive all-recursive check-recursive \
+installcheck-recursive info-recursive dvi-recursive \
+mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck all-recursive-am install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs-am \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+$(HOOK1OBJS): mf-hooks1.c mf-runtime.h mf-impl.h
+ hook=`basename $@ -hook.lo`; \
+ $(LTCOMPILE) -DWRAP_$$hook -c $(srcdir)/mf-hooks1.c -o $@
+$(HOOK2OBJS): mf-hooks2.c mf-runtime.h mf-impl.h
+ hook=`basename $@ -hook.lo`; \
+ $(LTCOMPILE) -DWRAP_$$hook -c $(srcdir)/mf-hooks2.c -o $@
+$(HOOK3OBJS): mf-hooks3.c mf-runtime.h mf-impl.h
+ hook=`basename $@ -hook.lo`; \
+ $(LTCOMPILE) -DWRAP_$$hook -c $(srcdir)/mf-hooks3.c -o $@
+
+clean-local:
+ rm -f pth/*.o pth/*.lo
+pth/mf-runtime.lo: mf-runtime.c mf-runtime.h mf-impl.h
+ $(LTCOMPILE) -DLIBMUDFLAPTH -c $(srcdir)/mf-runtime.c -o $@
+pth/mf-heuristics.lo: mf-heuristics.c mf-runtime.h mf-impl.h
+ $(LTCOMPILE) -DLIBMUDFLAPTH -c $(srcdir)/mf-heuristics.c -o $@
+$(PTHHOOK1OBJS): mf-hooks1.c mf-runtime.h mf-impl.h
+ hook=`basename $@ -hook.lo`; \
+ $(LTCOMPILE) -DLIBMUDFLAPTH -DWRAP_$$hook -c $(srcdir)/mf-hooks1.c -o $@
+$(PTHHOOK2OBJS): mf-hooks2.c mf-runtime.h mf-impl.h
+ hook=`basename $@ -hook.lo`; \
+ $(LTCOMPILE) -DLIBMUDFLAPTH -DWRAP_$$hook -c $(srcdir)/mf-hooks2.c -o $@
+$(PTHHOOK3OBJS): mf-hooks3.c mf-runtime.h mf-impl.h
+ hook=`basename $@ -hook.lo`; \
+ $(LTCOMPILE) -DLIBMUDFLAPTH -DWRAP_$$hook -c $(srcdir)/mf-hooks3.c -o $@
+
+# Multilib support.
+.PHONY: all-multi mostlyclean-multi clean-multi distclean-multi \
+ maintainer-clean-multi
+
+all-recursive: all-multi
+install-recursive: install-multi
+mostlyclean-recursive: mostlyclean-multi
+clean-recursive: clean-multi
+distclean-recursive: distclean-multi
+maintainer-clean-recursive: maintainer-clean-multi
+
+all-multi:
+ : $(MAKE) ; exec $(MULTIDO) $(AM_MAKEFLAGS) DO=all multi-do
+install-multi:
+ $(MULTIDO) $(AM_MAKEFLAGS) DO=install multi-do
+mostlyclean-multi:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=mostlyclean multi-clean
+clean-multi:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=clean multi-clean
+distclean-multi:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean
+maintainer-clean-multi:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libmudflap/acinclude.m4 b/libmudflap/acinclude.m4
new file mode 100644
index 00000000000..421197d6124
--- /dev/null
+++ b/libmudflap/acinclude.m4
@@ -0,0 +1,928 @@
+## libtool.m4 - Configure libtool for the host system. -*-Shell-script-*-
+## Copyright 1996, 1997, 1998, 1999, 2000, 2001
+## Free Software Foundation, Inc.
+## Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+##
+## This program 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 2 of the License, or
+## (at your option) any later version.
+##
+## This program 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 program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+##
+## As a special exception to the GNU General Public License, if you
+## distribute this file as part of a program that contains a
+## configuration script generated by Autoconf, you may include it under
+## the same distribution terms that you use for the rest of that program.
+
+# serial 46 AC_PROG_LIBTOOL
+AC_DEFUN([AC_PROG_LIBTOOL],
+[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl
+dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX
+dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX.
+ AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [AC_LIBTOOL_CXX],
+ [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX
+])])
+
+dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly.
+dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run
+dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both.
+ AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+ [AC_LIBTOOL_GCJ],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+ [AC_LIBTOOL_GCJ],
+ [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],
+ [AC_LIBTOOL_GCJ],
+ [ifdef([AC_PROG_GCJ],
+ [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ
+])])
+ ifdef([A][M_PROG_GCJ],
+ [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ
+])])
+ ifdef([LT_AC_PROG_GCJ],
+ [define([LT_AC_PROG_GCJ], defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ
+])])])])])])
+
+AC_DEFUN([_AC_PROG_LIBTOOL],
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl
+
+# Save cache, so that ltconfig can load it
+AC_CACHE_SAVE
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+AR="$AR" LTCC="$CC" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \
+AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \
+objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \
+deplibs_check_method="$deplibs_check_method" file_magic_cmd="$file_magic_cmd" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \
+|| AC_MSG_ERROR([libtool configure failed])
+
+# Reload cache, that may have been modified by ltconfig
+AC_CACHE_LOAD
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh $ac_aux_dir/ltcf-c.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+AC_DEFUN([AC_LIBTOOL_SETUP],
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl
+# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
+AC_REQUIRE([AC_OBJEXT])dnl
+AC_REQUIRE([AC_EXEEXT])dnl
+dnl
+
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ AC_PATH_MAGIC
+ fi
+ ;;
+esac
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+AC_CHECK_TOOL(STRIP, strip, :)
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$GCC" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$lt_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN],
+[libtool_flags="$libtool_flags --enable-dlopen"])
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[libtool_flags="$libtool_flags --enable-win32-dll"])
+AC_ARG_ENABLE(libtool-lock,
+ [ --disable-libtool-lock avoid locking (might break parallel builds)])
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+AC_ARG_WITH(pic,
+ [ --with-pic try to use only PIC/non-PIC objects [default=use both]],
+ pic_mode="$withval", pic_mode=default)
+test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic"
+test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case "`/usr/bin/file conftest.o`" in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ case $host in
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ ppc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_LANG_SAVE
+ AC_LANG_C
+ AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+ AC_LANG_RESTORE])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw* | *-*-pw32*)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+
+ # recent cygwin and mingw systems supply a stub DllMain which the user
+ # can override, but on older systems we have to supply one
+ AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain,
+ [AC_TRY_LINK([],
+ [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*);
+ DllMain (0, 0, 0);],
+ [lt_cv_need_dllmain=no],[lt_cv_need_dllmain=yes])])
+
+ case $host/$CC in
+ *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*)
+ # old mingw systems require "-dll" to link a DLL, while more recent ones
+ # require "-mdll"
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -mdll"
+ AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch,
+ [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])])
+ CFLAGS="$SAVE_CFLAGS" ;;
+ *-*-cygwin* | *-*-pw32*)
+ # cygwin systems need to pass --dll to the linker, and not link
+ # crt.o which will require a WinMain@16 definition.
+ lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;;
+ esac
+ ;;
+ ])
+esac
+])
+
+# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
+AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])])
+
+# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
+AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN([AC_ENABLE_SHARED],
+[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case $enableval in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN([AC_DISABLE_SHARED], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN([AC_ENABLE_STATIC],
+[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case $enableval in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN([AC_DISABLE_STATIC],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN([AC_ENABLE_FAST_INSTALL],
+[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case $enableval in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_DISABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN([AC_DISABLE_FAST_INSTALL],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)])
+
+# AC_LIBTOOL_PICMODE - implement the --with-pic flag
+# Usage: AC_LIBTOOL_PICMODE[(MODE)]
+# Where MODE is either `yes' or `no'. If omitted, it defaults to
+# `both'.
+AC_DEFUN([AC_LIBTOOL_PICMODE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+pic_mode=ifelse($#,1,$1,default)])
+
+
+# AC_PATH_TOOL_PREFIX - find a file program which can recognise shared library
+AC_DEFUN([AC_PATH_TOOL_PREFIX],
+[AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+ /*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+ ;;
+ *)
+ ac_save_MAGIC_CMD="$MAGIC_CMD"
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="ifelse([$2], , $PATH, [$2])"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$1; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ egrep "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ MAGIC_CMD="$ac_save_MAGIC_CMD"
+ ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ AC_MSG_RESULT($MAGIC_CMD)
+else
+ AC_MSG_RESULT(no)
+fi
+])
+
+
+# AC_PATH_MAGIC - find a file program which can recognise a shared library
+AC_DEFUN([AC_PATH_MAGIC],
+[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])dnl
+AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin:$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ AC_PATH_TOOL_PREFIX(file, /usr/bin:$PATH)
+ else
+ MAGIC_CMD=:
+ fi
+fi
+])
+
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN([AC_PROG_LD],
+[AC_ARG_WITH(gnu-ld,
+[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by GCC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]* | [A-Za-z]:[\\/]*)]
+ re_direlt=['/[^/][^/]*/\.\./']
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_PROG_LD_GNU
+])
+
+AC_DEFUN([AC_PROG_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ lt_cv_prog_gnu_ld=yes
+else
+ lt_cv_prog_gnu_ld=no
+fi])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])
+
+# AC_PROG_LD_RELOAD_FLAG - find reload flag for linker
+# -- PORTME Some linkers may need a different reload flag.
+AC_DEFUN([AC_PROG_LD_RELOAD_FLAG],
+[AC_CACHE_CHECK([for $LD option to reload object files], lt_cv_ld_reload_flag,
+[lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+])
+
+# AC_DEPLIBS_CHECK_METHOD - how to check for library dependencies
+# -- PORTME fill in with the dynamic library characteristics
+# Don't cache this sucker.
+AC_DEFUN([AC_DEPLIBS_CHECK_METHOD],
+[AC_MSG_CHECKING([how to recognise dependant libraries])
+lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [regex]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi4*)
+ lt_cv_deplibs_check_method=['file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)']
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin* | mingw* |pw32*)
+ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ case "$host_os" in
+ rhapsody* | darwin1.[012])
+ lt_cv_file_magic_test_file='/System/Library/Frameworks/System.framework/System'
+ ;;
+ *) # Darwin 1.3 on
+ lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib'
+ ;;
+ esac
+ ;;
+
+freebsd* )
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method=['file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library']
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20*|hpux11*)
+ case $host_cpu in
+ hppa*)
+ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library']
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ ia64*)
+ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64']
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ esac
+ ;;
+
+irix5* | irix6*)
+ case $host_os in
+ irix5*)
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+ ;;
+ *)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method=["file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"]
+ ;;
+ esac
+ lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+ case $host_cpu in
+ alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* | x86_64*)
+ lt_cv_deplibs_check_method=pass_all ;;
+ # NB 2003-06-03: According to Alexandre Oliva, x86_64 should not be
+ # in this list. However, it works around a libtool problem that
+ # wrongly excludes -ldl/-lpthread from the libmudflap(th) dependencies.
+ *)
+ # glibc up to 2.1.1 does not perform some relocations on ARM
+ lt_cv_deplibs_check_method=['file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'] ;;
+ esac
+ lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ [lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$']
+ else
+ [lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$']
+ fi
+ ;;
+
+newsos6)
+ [lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)']
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+osf3* | osf4* | osf5*)
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method='file_magic COFF format alpha shared library'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sco3.2v5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+
+[sysv5uw[78]* | sysv4*uw2*)]
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ case $host_vendor in
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ motorola)
+ lt_cv_deplibs_check_method=['file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]']
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ esac
+ ;;
+esac
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+# NB: See above NB ... this is to make sure that the overriden
+# local libtool variant doesn't pollute the upstream cache
+unset lt_cv_file_magic_cmd
+unset lt_cv_deplibs_check_method
+AC_MSG_RESULT($deplibs_check_method)
+])
+
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN([AC_PROG_NM],
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(lt_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/${ac_tool_prefix}nm
+ if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ else
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi])
+NM="$lt_cv_path_NM"
+AC_MSG_RESULT([$NM])
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN([AC_CHECK_LIBM],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cygwin* | *-*-pw32*)
+ # These system don't have libm
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+ AC_CHECK_LIB(m, main, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, main, LIBM="-lm")
+ ;;
+esac
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library and INCLTDL to the include flags for
+# the libltdl header and adds --enable-ltdl-convenience to the
+# configure arguments. Note that LIBLTDL and INCLTDL are not
+# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not
+# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed
+# with '${top_builddir}/' and INCLTDL will be prefixed with
+# '${top_srcdir}/' (note the single quotes!). If your package is not
+# flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
+AC_DEFUN([AC_LIBLTDL_CONVENIENCE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ case $enable_ltdl_convenience in
+ no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+ "") enable_ltdl_convenience=yes
+ ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+ esac
+ LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
+ INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library and INCLTDL to the include flags for
+# the libltdl header and adds --enable-ltdl-install to the configure
+# arguments. Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is
+# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed
+# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will
+# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed
+# with '${top_srcdir}/' (note the single quotes!). If your package is
+# not flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN([AC_LIBLTDL_INSTALLABLE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ AC_CHECK_LIB(ltdl, main,
+ [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+ [if test x"$enable_ltdl_install" = xno; then
+ AC_MSG_WARN([libltdl not installed, but installation disabled])
+ else
+ enable_ltdl_install=yes
+ fi
+ ])
+ if test x"$enable_ltdl_install" = x"yes"; then
+ ac_configure_args="$ac_configure_args --enable-ltdl-install"
+ LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
+ INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+ else
+ ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+ LIBLTDL="-lltdl"
+ INCLTDL=
+ fi
+])
+
+# If this macro is not defined by Autoconf, define it here.
+ifdef([AC_PROVIDE_IFELSE],
+ [],
+ [define([AC_PROVIDE_IFELSE],
+ [ifdef([AC_PROVIDE_$1],
+ [$2], [$3])])])
+
+# AC_LIBTOOL_CXX - enable support for C++ libraries
+AC_DEFUN([AC_LIBTOOL_CXX], [AC_REQUIRE([_AC_LIBTOOL_CXX])])
+
+AC_DEFUN([_AC_LIBTOOL_CXX],
+[AC_REQUIRE([AC_PROG_CXX])
+AC_REQUIRE([AC_PROG_CXXCPP])
+LIBTOOL_DEPS=$LIBTOOL_DEPS" $ac_aux_dir/ltcf-cxx.sh"
+lt_save_CC="$CC"
+lt_save_CFLAGS="$CFLAGS"
+dnl Make sure LTCC is set to the C compiler, i.e. set LTCC before CC
+dnl is set to the C++ compiler.
+AR="$AR" LTCC="$CC" CC="$CXX" CXX="$CXX" CFLAGS="$CXXFLAGS" CPPFLAGS="$CPPFLAGS" \
+MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \
+AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \
+objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \
+deplibs_check_method="$deplibs_check_method" \
+file_magic_cmd="$file_magic_cmd" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig -o libtool $libtool_flags \
+--build="$build" --add-tag=CXX $ac_aux_dir/ltcf-cxx.sh $host \
+|| AC_MSG_ERROR([libtool tag configuration failed])
+CC="$lt_save_CC"
+CFLAGS="$lt_save_CFLAGS"
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+# AC_LIBTOOL_GCJ - enable support for GCJ libraries
+AC_DEFUN([AC_LIBTOOL_GCJ],[AC_REQUIRE([_AC_LIBTOOL_GCJ])])
+
+AC_DEFUN([_AC_LIBTOOL_GCJ],
+[AC_REQUIRE([AC_PROG_LIBTOOL])
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],[],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[],
+ [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[],
+ [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])],
+ [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])],
+ [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])])
+LIBTOOL_DEPS=$LIBTOOL_DEPS" $ac_aux_dir/ltcf-gcj.sh"
+lt_save_CC="$CC"
+lt_save_CFLAGS="$CFLAGS"
+dnl Make sure LTCC is set to the C compiler, i.e. set LTCC before CC
+dnl is set to the C++ compiler.
+AR="$AR" LTCC="$CC" CC="$GCJ" CFLAGS="$GCJFLAGS" CPPFLAGS="$CPPFLAGS" \
+MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \
+AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \
+objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \
+deplibs_check_method="$deplibs_check_method" \
+file_magic_cmd="$file_magic_cmd" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig -o libtool $libtool_flags \
+--build="$build" --add-tag=GCJ $ac_aux_dir/ltcf-gcj.sh $host \
+|| AC_MSG_ERROR([libtool tag configuration failed])
+CC="$lt_save_CC"
+CFLAGS="$lt_save_CFLAGS"
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+dnl old names
+AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL])
+AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+AC_DEFUN([AM_PROG_LD], [AC_PROG_LD])
+AC_DEFUN([AM_PROG_NM], [AC_PROG_NM])
+
+dnl This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])dnl
+
+AC_DEFUN([LT_AC_PROG_GCJ],
+[AC_CHECK_TOOL(GCJ, gcj, no)
+ test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+ AC_SUBST(GCJFLAGS)
+])
diff --git a/libmudflap/aclocal.m4 b/libmudflap/aclocal.m4
new file mode 100644
index 00000000000..f33f60bba61
--- /dev/null
+++ b/libmudflap/aclocal.m4
@@ -0,0 +1,1066 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+
+# serial 46 AC_PROG_LIBTOOL
+AC_DEFUN([AC_PROG_LIBTOOL],
+[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl
+dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX
+dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX.
+ AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [AC_LIBTOOL_CXX],
+ [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX
+])])
+
+dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly.
+dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run
+dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both.
+ AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+ [AC_LIBTOOL_GCJ],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+ [AC_LIBTOOL_GCJ],
+ [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],
+ [AC_LIBTOOL_GCJ],
+ [ifdef([AC_PROG_GCJ],
+ [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ
+])])
+ ifdef([A][M_PROG_GCJ],
+ [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ
+])])
+ ifdef([LT_AC_PROG_GCJ],
+ [define([LT_AC_PROG_GCJ], defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ
+])])])])])])
+
+AC_DEFUN([_AC_PROG_LIBTOOL],
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl
+
+# Save cache, so that ltconfig can load it
+AC_CACHE_SAVE
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+AR="$AR" LTCC="$CC" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \
+AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \
+objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \
+deplibs_check_method="$deplibs_check_method" file_magic_cmd="$file_magic_cmd" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \
+|| AC_MSG_ERROR([libtool configure failed])
+
+# Reload cache, that may have been modified by ltconfig
+AC_CACHE_LOAD
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh $ac_aux_dir/ltcf-c.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+AC_DEFUN([AC_LIBTOOL_SETUP],
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl
+# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
+AC_REQUIRE([AC_OBJEXT])dnl
+AC_REQUIRE([AC_EXEEXT])dnl
+dnl
+
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ AC_PATH_MAGIC
+ fi
+ ;;
+esac
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+AC_CHECK_TOOL(STRIP, strip, :)
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$GCC" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$lt_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN],
+[libtool_flags="$libtool_flags --enable-dlopen"])
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[libtool_flags="$libtool_flags --enable-win32-dll"])
+AC_ARG_ENABLE(libtool-lock,
+ [ --disable-libtool-lock avoid locking (might break parallel builds)])
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+AC_ARG_WITH(pic,
+ [ --with-pic try to use only PIC/non-PIC objects [default=use both]],
+ pic_mode="$withval", pic_mode=default)
+test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic"
+test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case "`/usr/bin/file conftest.o`" in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ case $host in
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ ppc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_LANG_SAVE
+ AC_LANG_C
+ AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+ AC_LANG_RESTORE])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw* | *-*-pw32*)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+
+ # recent cygwin and mingw systems supply a stub DllMain which the user
+ # can override, but on older systems we have to supply one
+ AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain,
+ [AC_TRY_LINK([],
+ [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*);
+ DllMain (0, 0, 0);],
+ [lt_cv_need_dllmain=no],[lt_cv_need_dllmain=yes])])
+
+ case $host/$CC in
+ *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*)
+ # old mingw systems require "-dll" to link a DLL, while more recent ones
+ # require "-mdll"
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -mdll"
+ AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch,
+ [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])])
+ CFLAGS="$SAVE_CFLAGS" ;;
+ *-*-cygwin* | *-*-pw32*)
+ # cygwin systems need to pass --dll to the linker, and not link
+ # crt.o which will require a WinMain@16 definition.
+ lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;;
+ esac
+ ;;
+ ])
+esac
+])
+
+# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
+AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])])
+
+# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
+AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN([AC_ENABLE_SHARED],
+[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case $enableval in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN([AC_DISABLE_SHARED], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN([AC_ENABLE_STATIC],
+[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case $enableval in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN([AC_DISABLE_STATIC],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN([AC_ENABLE_FAST_INSTALL],
+[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case $enableval in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_DISABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN([AC_DISABLE_FAST_INSTALL],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)])
+
+# AC_LIBTOOL_PICMODE - implement the --with-pic flag
+# Usage: AC_LIBTOOL_PICMODE[(MODE)]
+# Where MODE is either `yes' or `no'. If omitted, it defaults to
+# `both'.
+AC_DEFUN([AC_LIBTOOL_PICMODE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+pic_mode=ifelse($#,1,$1,default)])
+
+
+# AC_PATH_TOOL_PREFIX - find a file program which can recognise shared library
+AC_DEFUN([AC_PATH_TOOL_PREFIX],
+[AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+ /*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+ ;;
+ *)
+ ac_save_MAGIC_CMD="$MAGIC_CMD"
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="ifelse([$2], , $PATH, [$2])"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$1; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ egrep "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ MAGIC_CMD="$ac_save_MAGIC_CMD"
+ ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ AC_MSG_RESULT($MAGIC_CMD)
+else
+ AC_MSG_RESULT(no)
+fi
+])
+
+
+# AC_PATH_MAGIC - find a file program which can recognise a shared library
+AC_DEFUN([AC_PATH_MAGIC],
+[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])dnl
+AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin:$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ AC_PATH_TOOL_PREFIX(file, /usr/bin:$PATH)
+ else
+ MAGIC_CMD=:
+ fi
+fi
+])
+
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN([AC_PROG_LD],
+[AC_ARG_WITH(gnu-ld,
+[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by GCC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]* | [A-Za-z]:[\\/]*)]
+ re_direlt=['/[^/][^/]*/\.\./']
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_PROG_LD_GNU
+])
+
+AC_DEFUN([AC_PROG_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ lt_cv_prog_gnu_ld=yes
+else
+ lt_cv_prog_gnu_ld=no
+fi])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])
+
+# AC_PROG_LD_RELOAD_FLAG - find reload flag for linker
+# -- PORTME Some linkers may need a different reload flag.
+AC_DEFUN([AC_PROG_LD_RELOAD_FLAG],
+[AC_CACHE_CHECK([for $LD option to reload object files], lt_cv_ld_reload_flag,
+[lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+])
+
+# AC_DEPLIBS_CHECK_METHOD - how to check for library dependencies
+# -- PORTME fill in with the dynamic library characteristics
+# Don't cache this sucker.
+AC_DEFUN([AC_DEPLIBS_CHECK_METHOD],
+[AC_MSG_CHECKING([how to recognise dependant libraries])
+lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [regex]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi4*)
+ lt_cv_deplibs_check_method=['file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)']
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin* | mingw* |pw32*)
+ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ case "$host_os" in
+ rhapsody* | darwin1.[012])
+ lt_cv_file_magic_test_file='/System/Library/Frameworks/System.framework/System'
+ ;;
+ *) # Darwin 1.3 on
+ lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib'
+ ;;
+ esac
+ ;;
+
+freebsd* )
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method=['file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library']
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20*|hpux11*)
+ case $host_cpu in
+ hppa*)
+ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library']
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ ia64*)
+ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64']
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ esac
+ ;;
+
+irix5* | irix6*)
+ case $host_os in
+ irix5*)
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+ ;;
+ *)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method=["file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"]
+ ;;
+ esac
+ lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+ case $host_cpu in
+ alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* | x86_64*)
+ lt_cv_deplibs_check_method=pass_all ;;
+ # NB 2003-06-03: According to Alexandre Oliva, x86_64 should not be
+ # in this list. However, it works around a libtool problem that
+ # wrongly excludes -ldl/-lpthread from the libmudflap(th) dependencies.
+ *)
+ # glibc up to 2.1.1 does not perform some relocations on ARM
+ lt_cv_deplibs_check_method=['file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'] ;;
+ esac
+ lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ [lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$']
+ else
+ [lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$']
+ fi
+ ;;
+
+newsos6)
+ [lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)']
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+osf3* | osf4* | osf5*)
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method='file_magic COFF format alpha shared library'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sco3.2v5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+
+[sysv5uw[78]* | sysv4*uw2*)]
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ case $host_vendor in
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ motorola)
+ lt_cv_deplibs_check_method=['file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]']
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ esac
+ ;;
+esac
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+# NB: See above NB ... this is to make sure that the overriden
+# local libtool variant doesn't pollute the upstream cache
+unset lt_cv_file_magic_cmd
+unset lt_cv_deplibs_check_method
+AC_MSG_RESULT($deplibs_check_method)
+])
+
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN([AC_PROG_NM],
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(lt_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/${ac_tool_prefix}nm
+ if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ else
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi])
+NM="$lt_cv_path_NM"
+AC_MSG_RESULT([$NM])
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN([AC_CHECK_LIBM],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cygwin* | *-*-pw32*)
+ # These system don't have libm
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+ AC_CHECK_LIB(m, main, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, main, LIBM="-lm")
+ ;;
+esac
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library and INCLTDL to the include flags for
+# the libltdl header and adds --enable-ltdl-convenience to the
+# configure arguments. Note that LIBLTDL and INCLTDL are not
+# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not
+# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed
+# with '${top_builddir}/' and INCLTDL will be prefixed with
+# '${top_srcdir}/' (note the single quotes!). If your package is not
+# flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
+AC_DEFUN([AC_LIBLTDL_CONVENIENCE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ case $enable_ltdl_convenience in
+ no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+ "") enable_ltdl_convenience=yes
+ ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+ esac
+ LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
+ INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library and INCLTDL to the include flags for
+# the libltdl header and adds --enable-ltdl-install to the configure
+# arguments. Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is
+# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed
+# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will
+# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed
+# with '${top_srcdir}/' (note the single quotes!). If your package is
+# not flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN([AC_LIBLTDL_INSTALLABLE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ AC_CHECK_LIB(ltdl, main,
+ [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+ [if test x"$enable_ltdl_install" = xno; then
+ AC_MSG_WARN([libltdl not installed, but installation disabled])
+ else
+ enable_ltdl_install=yes
+ fi
+ ])
+ if test x"$enable_ltdl_install" = x"yes"; then
+ ac_configure_args="$ac_configure_args --enable-ltdl-install"
+ LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
+ INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+ else
+ ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+ LIBLTDL="-lltdl"
+ INCLTDL=
+ fi
+])
+
+# If this macro is not defined by Autoconf, define it here.
+ifdef([AC_PROVIDE_IFELSE],
+ [],
+ [define([AC_PROVIDE_IFELSE],
+ [ifdef([AC_PROVIDE_$1],
+ [$2], [$3])])])
+
+# AC_LIBTOOL_CXX - enable support for C++ libraries
+AC_DEFUN([AC_LIBTOOL_CXX], [AC_REQUIRE([_AC_LIBTOOL_CXX])])
+
+AC_DEFUN([_AC_LIBTOOL_CXX],
+[AC_REQUIRE([AC_PROG_CXX])
+AC_REQUIRE([AC_PROG_CXXCPP])
+LIBTOOL_DEPS=$LIBTOOL_DEPS" $ac_aux_dir/ltcf-cxx.sh"
+lt_save_CC="$CC"
+lt_save_CFLAGS="$CFLAGS"
+dnl Make sure LTCC is set to the C compiler, i.e. set LTCC before CC
+dnl is set to the C++ compiler.
+AR="$AR" LTCC="$CC" CC="$CXX" CXX="$CXX" CFLAGS="$CXXFLAGS" CPPFLAGS="$CPPFLAGS" \
+MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \
+AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \
+objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \
+deplibs_check_method="$deplibs_check_method" \
+file_magic_cmd="$file_magic_cmd" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig -o libtool $libtool_flags \
+--build="$build" --add-tag=CXX $ac_aux_dir/ltcf-cxx.sh $host \
+|| AC_MSG_ERROR([libtool tag configuration failed])
+CC="$lt_save_CC"
+CFLAGS="$lt_save_CFLAGS"
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+# AC_LIBTOOL_GCJ - enable support for GCJ libraries
+AC_DEFUN([AC_LIBTOOL_GCJ],[AC_REQUIRE([_AC_LIBTOOL_GCJ])])
+
+AC_DEFUN([_AC_LIBTOOL_GCJ],
+[AC_REQUIRE([AC_PROG_LIBTOOL])
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],[],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[],
+ [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[],
+ [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])],
+ [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])],
+ [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])])
+LIBTOOL_DEPS=$LIBTOOL_DEPS" $ac_aux_dir/ltcf-gcj.sh"
+lt_save_CC="$CC"
+lt_save_CFLAGS="$CFLAGS"
+dnl Make sure LTCC is set to the C compiler, i.e. set LTCC before CC
+dnl is set to the C++ compiler.
+AR="$AR" LTCC="$CC" CC="$GCJ" CFLAGS="$GCJFLAGS" CPPFLAGS="$CPPFLAGS" \
+MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \
+AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \
+objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \
+deplibs_check_method="$deplibs_check_method" \
+file_magic_cmd="$file_magic_cmd" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig -o libtool $libtool_flags \
+--build="$build" --add-tag=GCJ $ac_aux_dir/ltcf-gcj.sh $host \
+|| AC_MSG_ERROR([libtool tag configuration failed])
+CC="$lt_save_CC"
+CFLAGS="$lt_save_CFLAGS"
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+dnl old names
+AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL])
+AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+AC_DEFUN([AM_PROG_LD], [AC_PROG_LD])
+AC_DEFUN([AM_PROG_NM], [AC_PROG_NM])
+
+dnl This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])dnl
+
+AC_DEFUN([LT_AC_PROG_GCJ],
+[AC_CHECK_TOOL(GCJ, gcj, no)
+ test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+ AC_SUBST(GCJFLAGS)
+])
+
+# Do all the work for Automake. This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AC_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_REQUIRE([AM_SANITY_CHECK])
+AC_REQUIRE([AC_ARG_PROGRAM])
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "[$]*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "[$]*" != "X $srcdir/configure conftestfile" \
+ && test "[$]*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "[$]2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+ $1=$2
+ AC_MSG_RESULT(found)
+else
+ $1="$3/missing $2"
+ AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+# Add --enable-maintainer-mode option to configure.
+# From Jim Meyering
+
+# serial 1
+
+AC_DEFUN(AM_MAINTAINER_MODE,
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode is disabled by default
+ AC_ARG_ENABLE(maintainer-mode,
+[ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ USE_MAINTAINER_MODE=$enableval,
+ USE_MAINTAINER_MODE=no)
+ AC_MSG_RESULT($USE_MAINTAINER_MODE)
+ AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes)
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST(MAINT)dnl
+]
+)
+
+# Define a conditional.
+
+AC_DEFUN(AM_CONDITIONAL,
+[AC_SUBST($1_TRUE)
+AC_SUBST($1_FALSE)
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi])
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+AC_DEFUN(AM_CONFIG_HEADER,
+[AC_PREREQ([2.12])
+AC_CONFIG_HEADER([$1])
+dnl When config.status generates a header, we must update the stamp-h file.
+dnl This file resides in the same directory as the config header
+dnl that is generated. We must strip everything past the first ":",
+dnl and everything past the last "/".
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
+ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
+<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
+<<am_indx=1
+for am_file in <<$1>>; do
+ case " <<$>>CONFIG_HEADERS " in
+ *" <<$>>am_file "*<<)>>
+ echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
+ ;;
+ esac
+ am_indx=`expr "<<$>>am_indx" + 1`
+done<<>>dnl>>)
+changequote([,]))])
+
diff --git a/libmudflap/config.h.in b/libmudflap/config.h.in
new file mode 100644
index 00000000000..ebb7360df60
--- /dev/null
+++ b/libmudflap/config.h.in
@@ -0,0 +1,62 @@
+/* config.h.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if you have the backtrace function. */
+#undef HAVE_BACKTRACE
+
+/* Define if you have the backtrace_symbols function. */
+#undef HAVE_BACKTRACE_SYMBOLS
+
+/* Define if you have the dlvsym function. */
+#undef HAVE_DLVSYM
+
+/* Define if you have the fopen64 function. */
+#undef HAVE_FOPEN64
+
+/* Define if you have the fseeko64 function. */
+#undef HAVE_FSEEKO64
+
+/* Define if you have the ftello64 function. */
+#undef HAVE_FTELLO64
+
+/* Define if you have the gettimeofday function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define if you have the signal function. */
+#undef HAVE_SIGNAL
+
+/* Define if you have the stat64 function. */
+#undef HAVE_STAT64
+
+/* Define if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define if you have the <execinfo.h> header file. */
+#undef HAVE_EXECINFO_H
+
+/* Define if you have the <signal.h> header file. */
+#undef HAVE_SIGNAL_H
+
+/* Define if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define if you have the dl library (-ldl). */
+#undef HAVE_LIBDL
+
+/* Name of package */
+#undef PACKAGE
+
+/* Version number of package */
+#undef VERSION
+
+/* union semun defined in sys/ipc.h or sys/sem.h */
+#undef HAVE_UNION_SEMUN
+
+/* Define it socklen_t typedef is in sys/socket.h. */
+#undef HAVE_SOCKLEN_T
+
+/* define if you have <pthread.h> */
+#undef HAVE_PTHREAD_H
+
+/* pthread_create symbol version */
+#undef PTHREAD_CREATE_VERSION
+
diff --git a/libmudflap/configure b/libmudflap/configure
new file mode 100755
index 00000000000..71259c4ce75
--- /dev/null
+++ b/libmudflap/configure
@@ -0,0 +1,3218 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer"
+ac_help="$ac_help
+ --enable-shared[=PKGS] build shared libraries [default=yes]"
+ac_help="$ac_help
+ --enable-static[=PKGS] build static libraries [default=yes]"
+ac_help="$ac_help
+ --enable-fast-install[=PKGS] optimize for fast installation [default=yes]"
+ac_help="$ac_help
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]"
+ac_help="$ac_help
+ --disable-libtool-lock avoid locking (might break parallel builds)"
+ac_help="$ac_help
+ --with-pic try to use only PIC/non-PIC objects [default=use both]"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=mf-runtime.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+ac_aux_dir=
+for ac_dir in ${GNUSYSTEM_AUX_DIR} $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:587: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:608: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:626: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:660: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:713: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "$*" != "X $srcdir/configure conftestfile" \
+ && test "$*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { echo "configure: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+ fi
+
+ test "$2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:770: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+PACKAGE=libmudflap
+
+VERSION=1.0
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:816: checking for working aclocal" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then
+ ACLOCAL=aclocal
+ echo "$ac_t""found" 1>&6
+else
+ ACLOCAL="$missing_dir/missing aclocal"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:829: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+ AUTOCONF=autoconf
+ echo "$ac_t""found" 1>&6
+else
+ AUTOCONF="$missing_dir/missing autoconf"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:842: checking for working automake" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (automake --version) < /dev/null > /dev/null 2>&1; then
+ AUTOMAKE=automake
+ echo "$ac_t""found" 1>&6
+else
+ AUTOMAKE="$missing_dir/missing automake"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:855: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+ AUTOHEADER=autoheader
+ echo "$ac_t""found" 1>&6
+else
+ AUTOHEADER="$missing_dir/missing autoheader"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:868: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+ MAKEINFO=makeinfo
+ echo "$ac_t""found" 1>&6
+else
+ MAKEINFO="$missing_dir/missing makeinfo"
+ echo "$ac_t""missing" 1>&6
+fi
+
+
+
+
+# For libtool versioning info, format is CURRENT:REVISION:AGE
+libtool_VERSION=1:0:0
+
+
+echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
+echo "configure:888: checking whether to enable maintainer-specific portions of Makefiles" >&5
+ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+ enableval="$enable_maintainer_mode"
+ USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6
+
+
+if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:911: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 916 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:927: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_cygwin=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:944: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 949 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:956: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_mingw32=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:975: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+ ac_cv_exeext=.exe
+else
+ rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.$ac_ext
+ ac_cv_exeext=
+ if { (eval echo configure:985: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ for file in conftest.*; do
+ case $file in
+ *.c | *.o | *.obj) ;;
+ *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ else
+ { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+ fi
+ rm -f conftest*
+ test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+
+target_alias=${target_alias-$target}
+
+
+
+
+
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1023: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1053: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1104: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1136: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1147 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1152: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1178: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:1183: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1192: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1211: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+if test "x$GCC" != "xyes"; then
+ { echo "configure: error: libmudflap must be built with GCC" 1>&2; exit 1; }
+fi
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1246: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 1261 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1267: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1278 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1284: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 1295 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1301: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+
+# Some hosts don't have dlsym(RTLD_NEXT, "symbol") for use in
+# symbol interposition. We disable shared libraries for these.
+echo $ac_n "checking whether dlsym(RTLD_NEXT,...) is available""... $ac_c" 1>&6
+echo "configure:1329: checking whether dlsym(RTLD_NEXT,...) is available" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1331 "configure"
+#include "confdefs.h"
+
+#define _GNU_SOURCE
+#include <dlfcn.h>
+
+int main() {
+void *foo = dlsym (RTLD_NEXT, "exit");
+; return 0; }
+EOF
+if { (eval echo configure:1341: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ echo "$ac_t""yes" 1>&6
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ echo "$ac_t""no" 1>&6
+enable_shared=no
+fi
+rm -f conftest*
+
+for ac_hdr in stdint.h execinfo.h signal.h dlfcn.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1357: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1362 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1367: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in backtrace backtrace_symbols gettimeofday signal
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1396: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1401 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1424: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+for ac_func in fopen64 fseeko64 ftello64 stat64
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1452: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1457 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1480: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+cat > conftest.$ac_ext <<EOF
+#line 1506 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+int main() {
+union semun foo;
+; return 0; }
+EOF
+if { (eval echo configure:1515: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ mf_have_semun=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ mf_have_semun=0
+fi
+rm -f conftest*
+if test $mf_have_semun = 1
+then
+ cat >> confdefs.h <<\EOF
+#define HAVE_UNION_SEMUN 1
+EOF
+
+fi
+
+
+echo $ac_n "checking for socklen_t in sys/socket.h""... $ac_c" 1>&6
+echo "configure:1535: checking for socklen_t in sys/socket.h" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1537 "configure"
+#include "confdefs.h"
+#define _POSIX_PII_SOCKET
+#include <sys/types.h>
+#include <sys/socket.h>
+int main() {
+socklen_t x = 5;
+; return 0; }
+EOF
+if { (eval echo configure:1546: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ cat >> confdefs.h <<\EOF
+#define HAVE_SOCKLEN_T 1
+EOF
+
+ echo "$ac_t""yes" 1>&6
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ echo "$ac_t""no" 1>&6
+fi
+rm -f conftest*
+
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ p=${PACKAGE-default}
+case $enableval in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_shared=yes
+fi
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+ enableval="$enable_static"
+ p=${PACKAGE-default}
+case $enableval in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_static=yes
+fi
+
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+ enableval="$enable_fast_install"
+ p=${PACKAGE-default}
+case $enableval in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_fast_install=yes
+fi
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval="$with_gnu_ld"
+ test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+echo "configure:1643: checking for ld used by GCC" >&5
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+echo "configure:1673: checking for GNU ld" >&5
+else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+echo "configure:1676: checking for non-GNU ld" >&5
+fi
+if eval "test \"`echo '$''{'lt_cv_path_LD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ echo "$ac_t""$LD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+echo "configure:1711: checking if the linker ($LD) is GNU ld" >&5
+if eval "test \"`echo '$''{'lt_cv_prog_gnu_ld'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ lt_cv_prog_gnu_ld=yes
+else
+ lt_cv_prog_gnu_ld=no
+fi
+fi
+
+echo "$ac_t""$lt_cv_prog_gnu_ld" 1>&6
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+echo $ac_n "checking for $LD option to reload object files""... $ac_c" 1>&6
+echo "configure:1728: checking for $LD option to reload object files" >&5
+if eval "test \"`echo '$''{'lt_cv_ld_reload_flag'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+
+echo "$ac_t""$lt_cv_ld_reload_flag" 1>&6
+reload_flag=$lt_cv_ld_reload_flag
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+echo "configure:1740: checking for BSD-compatible nm" >&5
+if eval "test \"`echo '$''{'lt_cv_path_NM'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/${ac_tool_prefix}nm
+ if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ else
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi
+fi
+
+NM="$lt_cv_path_NM"
+echo "$ac_t""$NM" 1>&6
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1778: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking how to recognise dependant libraries""... $ac_c" 1>&6
+echo "configure:1799: checking how to recognise dependant libraries" >&5
+lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [regex]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi4*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin* | mingw* |pw32*)
+ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ case "$host_os" in
+ rhapsody* | darwin1.012)
+ lt_cv_file_magic_test_file='/System/Library/Frameworks/System.framework/System'
+ ;;
+ *) # Darwin 1.3 on
+ lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib'
+ ;;
+ esac
+ ;;
+
+freebsd* )
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20*|hpux11*)
+ case $host_cpu in
+ hppa*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ esac
+ ;;
+
+irix5* | irix6*)
+ case $host_os in
+ irix5*)
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+ ;;
+ *)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"
+ ;;
+ esac
+ lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+ case $host_cpu in
+ alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* | x86_64*)
+ lt_cv_deplibs_check_method=pass_all ;;
+ # NB 2003-06-03: According to Alexandre Oliva, x86_64 should not be
+ # in this list. However, it works around a libtool problem that
+ # wrongly excludes -ldl/-lpthread from the libmudflap(th) dependencies.
+ *)
+ # glibc up to 2.1.1 does not perform some relocations on ARM
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;;
+ esac
+ lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$'
+ fi
+ ;;
+
+newsos6)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+osf3* | osf4* | osf5*)
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method='file_magic COFF format alpha shared library'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sco3.2v5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+
+sysv5uw[78]* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ case $host_vendor in
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ esac
+ ;;
+esac
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+# NB: See above NB ... this is to make sure that the overriden
+# local libtool variant doesn't pollute the upstream cache
+unset lt_cv_file_magic_cmd
+unset lt_cv_deplibs_check_method
+echo "$ac_t""$deplibs_check_method" 1>&6
+
+echo $ac_n "checking for object suffix""... $ac_c" 1>&6
+echo "configure:1973: checking for object suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftest*
+echo 'int i = 1;' > conftest.$ac_ext
+if { (eval echo configure:1979: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ for ac_file in conftest.*; do
+ case $ac_file in
+ *.c) ;;
+ *) ac_cv_objext=`echo $ac_file | sed -e s/conftest.//` ;;
+ esac
+ done
+else
+ { echo "configure: error: installation or configuration problem; compiler does not work" 1>&2; exit 1; }
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_objext" 1>&6
+OBJEXT=$ac_cv_objext
+ac_objext=$ac_cv_objext
+
+if test $host != $build; then
+ ac_tool_prefix=${host_alias}-
+else
+ ac_tool_prefix=
+fi
+
+# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
+
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ echo $ac_n "checking for ${ac_tool_prefix}file""... $ac_c" 1>&6
+echo "configure:2009: checking for ${ac_tool_prefix}file" >&5
+if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case $MAGIC_CMD in
+ /*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+ ;;
+ *)
+ ac_save_MAGIC_CMD="$MAGIC_CMD"
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="/usr/bin:$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/${ac_tool_prefix}file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ egrep "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ MAGIC_CMD="$ac_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ echo "$ac_t""$MAGIC_CMD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ echo $ac_n "checking for file""... $ac_c" 1>&6
+echo "configure:2071: checking for file" >&5
+if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case $MAGIC_CMD in
+ /*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+ ;;
+ *)
+ ac_save_MAGIC_CMD="$MAGIC_CMD"
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="/usr/bin:$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ egrep "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ MAGIC_CMD="$ac_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ echo "$ac_t""$MAGIC_CMD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2142: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_RANLIB"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2174: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ RANLIB=":"
+fi
+fi
+
+# Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2209: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+STRIP="$ac_cv_prog_STRIP"
+if test -n "$STRIP"; then
+ echo "$ac_t""$STRIP" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_STRIP"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2241: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_STRIP="strip"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_STRIP" && ac_cv_prog_STRIP=":"
+fi
+fi
+STRIP="$ac_cv_prog_STRIP"
+if test -n "$STRIP"; then
+ echo "$ac_t""$STRIP" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ STRIP=":"
+fi
+fi
+
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$GCC" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$lt_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+libtool_flags="$libtool_flags --enable-dlopen"
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+ enableval="$enable_libtool_lock"
+ :
+fi
+
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Check whether --with-pic or --without-pic was given.
+if test "${with_pic+set}" = set; then
+ withval="$with_pic"
+ pic_mode="$withval"
+else
+ pic_mode=default
+fi
+
+test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic"
+test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line 2308 "configure"' > conftest.$ac_ext
+ if { (eval echo configure:2309: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { (eval echo configure:2328: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ case "`/usr/bin/file conftest.o`" in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { (eval echo configure:2344: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ case $host in
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ ppc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
+echo "configure:2388: checking whether the C compiler needs -belf" >&5
+if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+ ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ cat > conftest.$ac_ext <<EOF
+#line 2401 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:2408: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=no
+fi
+rm -f conftest*
+ ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+fi
+
+echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+
+esac
+
+
+# Save cache, so that ltconfig can load it
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+AR="$AR" LTCC="$CC" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \
+AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \
+objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \
+deplibs_check_method="$deplibs_check_method" file_magic_cmd="$file_magic_cmd" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \
+|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
+
+# Reload cache, that may have been modified by ltconfig
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh $ac_aux_dir/ltcf-c.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+
+
+
+
+
+
+
+
+ac_safe=`echo "stdint.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for stdint.h""... $ac_c" 1>&6
+echo "configure:2528: checking for stdint.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2533 "configure"
+#include "confdefs.h"
+#include <stdint.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2538: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ MF_HAVE_STDINT_H=1
+else
+ echo "$ac_t""no" 1>&6
+MF_HAVE_STDINT_H=0
+fi
+
+
+if test $MF_HAVE_STDINT_H = 1
+then
+ MF_HAVE_UINTPTR_T=1
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2566 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+int main() {
+uintptr_t k = 0;
+; return 0; }
+EOF
+if { (eval echo configure:2573: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ MF_HAVE_UINTPTR_T=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ MF_HAVE_UINTPTR_T=0
+fi
+rm -f conftest*
+fi
+
+
+if test ! -d pth
+then
+ # libmudflapth objects are built in this subdirectory
+ mkdir pth
+fi
+
+pthread_create_version='""'
+ac_safe=`echo "pthread.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for pthread.h""... $ac_c" 1>&6
+echo "configure:2595: checking for pthread.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2600 "configure"
+#include "confdefs.h"
+#include <pthread.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2605: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+cat >> confdefs.h <<EOF
+#define HAVE_PTHREAD_H 1
+EOF
+
+ac_have_pthread_h=yes
+
+else
+ echo "$ac_t""no" 1>&6
+
+ac_have_pthread_h=
+
+fi
+
+
+
+if test "x$ac_have_pthread_h" != ""; then
+ LIBMUDFLAPTH_TRUE=
+ LIBMUDFLAPTH_FALSE='#'
+else
+ LIBMUDFLAPTH_TRUE='#'
+ LIBMUDFLAPTH_FALSE=
+fi
+
+echo $ac_n "checking for dlsym in -ldl""... $ac_c" 1>&6
+echo "configure:2646: checking for dlsym in -ldl" >&5
+ac_lib_var=`echo dl'_'dlsym | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2654 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlsym();
+
+int main() {
+dlsym()
+; return 0; }
+EOF
+if { (eval echo configure:2665: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo dl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-ldl $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test "x$enable_shared" = "xyes" && test "x$ac_have_pthread_h" != ""; then
+ # NB: don't check for -lpthread here, because then it would be
+ # added to LIBS. For the thread-unaware libmudflap.la, we don't
+ # want it there.
+
+ # glibc-related hacks. dlsym() may pick the wrong version of
+ # interposed functions like pthread_create on modern glibc.
+ # We need to find the proper symbol version string, and use
+ # the nonstandard dlvsym().
+ for ac_func in dlvsym
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2705: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2710 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2733: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ # Extract the first word of "${ac_tool_prefix}nm", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nm; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2760: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_NM'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$NM"; then
+ ac_cv_prog_NM="$NM" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_NM="${ac_tool_prefix}nm"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_NM" && ac_cv_prog_NM="nm"
+fi
+fi
+NM="$ac_cv_prog_NM"
+if test -n "$NM"; then
+ echo "$ac_t""$NM" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+ if test "x$ac_cv_have_dlvsym" != ""; then
+ # Try compiling a simple pthreads program. Find the shared libraries it
+ # ends up with. Then use "nm" on those libraries to extract the
+ # default symbol versioning suffix ("@@"), if any. But that's tricky.
+ # Rather, run nm on the resulting executable. Unfortunately, autoconf
+ # doesn't appear to have a macro that builds a test executable for
+ # subsequent analysis ... so we do it by hand here.
+ cat >> conftest.c << EOF
+#include <pthread.h>
+int main () { void *p = (void *) & pthread_create; return (int) p; }
+EOF
+ oldLIBS="$LIBS"
+ LIBS="$LIBS -lpthread"
+ pthread_create_version="\"\""
+ echo $ac_n "checking pthread_create symbol version""... $ac_c" 1>&6
+echo "configure:2804: checking pthread_create symbol version" >&5
+ if eval $ac_link 2>&5 && test -s conftest${ac_exeext}; then
+ version=`$NM conftest${ac_exeect} | grep 'pthread_create@@' | sed -e 's/^.*@@//'`
+ if test "x$version" != "x"; then
+ pthread_create_version="\"$version\""
+ fi
+ fi
+ echo "$ac_t""$pthread_create_version" 1>&6
+ LIBS="$oldLIBS"
+ fi
+fi
+cat >> confdefs.h <<EOF
+#define PTHREAD_CREATE_VERSION $pthread_create_version
+EOF
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile testsuite/Makefile mf-runtime.h config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@libtool_VERSION@%$libtool_VERSION%g
+s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g
+s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g
+s%@MAINT@%$MAINT%g
+s%@EXEEXT@%$EXEEXT%g
+s%@CC@%$CC%g
+s%@CPP@%$CPP%g
+s%@LN_S@%$LN_S%g
+s%@OBJEXT@%$OBJEXT%g
+s%@RANLIB@%$RANLIB%g
+s%@STRIP@%$STRIP%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@enable_shared@%$enable_shared%g
+s%@enable_static@%$enable_static%g
+s%@MF_HAVE_STDINT_H@%$MF_HAVE_STDINT_H%g
+s%@MF_HAVE_UINTPTR_T@%$MF_HAVE_UINTPTR_T%g
+s%@LIBMUDFLAPTH_TRUE@%$LIBMUDFLAPTH_TRUE%g
+s%@LIBMUDFLAPTH_FALSE@%$LIBMUDFLAPTH_FALSE%g
+s%@NM@%$NM%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile testsuite/Makefile mf-runtime.h"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/libmudflap/configure.in b/libmudflap/configure.in
new file mode 100644
index 00000000000..afdde6c52a8
--- /dev/null
+++ b/libmudflap/configure.in
@@ -0,0 +1,137 @@
+# Process this file with autoconf to produce a configure script, like so:
+# aclocal && autoconf && autoheader && automake
+
+AC_PREREQ(2.13)
+AC_INIT(mf-runtime.c)
+AC_CANONICAL_SYSTEM
+AM_INIT_AUTOMAKE(libmudflap, 1.0)
+
+AC_SUBST(PACKAGE)
+# For libtool versioning info, format is CURRENT:REVISION:AGE
+libtool_VERSION=1:0:0
+AC_SUBST(libtool_VERSION)
+
+dnl AM_ENABLE_MULTILIB
+AM_MAINTAINER_MODE
+AC_EXEEXT
+
+target_alias=${target_alias-$target}
+AC_SUBST(target_alias)
+
+AM_CONFIG_HEADER(config.h)
+
+AC_LANG_C
+AC_PROG_CC
+if test "x$GCC" != "xyes"; then
+ AC_MSG_ERROR([libmudflap must be built with GCC])
+fi
+AC_PROG_CPP
+
+# Some hosts don't have dlsym(RTLD_NEXT, "symbol") for use in
+# symbol interposition. We disable shared libraries for these.
+AC_MSG_CHECKING([whether dlsym(RTLD_NEXT,...) is available])
+AC_TRY_COMPILE([
+#define _GNU_SOURCE
+#include <dlfcn.h>
+],
+[void *foo = dlsym (RTLD_NEXT, "exit");],
+[AC_MSG_RESULT(yes)],
+[AC_MSG_RESULT(no)
+enable_shared=no])
+
+AC_CHECK_HEADERS(stdint.h execinfo.h signal.h dlfcn.h)
+AC_CHECK_FUNCS(backtrace backtrace_symbols gettimeofday signal)
+
+dnl Check for 64-bit stdio calls related to Large File Support
+AC_CHECK_FUNCS(fopen64 fseeko64 ftello64 stat64)
+
+AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>],[union semun foo;], [mf_have_semun=1], [mf_have_semun=0])
+if test $mf_have_semun = 1
+then
+ AC_DEFINE(HAVE_UNION_SEMUN, 1, [union semun defined in sys/ipc.h or sys/sem.h])
+fi
+
+
+AC_MSG_CHECKING([for socklen_t in sys/socket.h])
+AC_TRY_COMPILE([#define _POSIX_PII_SOCKET
+#include <sys/types.h>
+#include <sys/socket.h>], [socklen_t x = 5;],
+ [AC_DEFINE(HAVE_SOCKLEN_T, 1, [Define it socklen_t typedef is in sys/socket.h.])
+ AC_MSG_RESULT(yes)],
+ [AC_MSG_RESULT(no)])
+
+AC_LIBTOOL_DLOPEN
+AM_PROG_LIBTOOL
+AC_SUBST(enable_shared)
+AC_SUBST(enable_static)
+
+AC_CHECK_HEADER(stdint.h, [MF_HAVE_STDINT_H=1], [MF_HAVE_STDINT_H=0])
+AC_SUBST(MF_HAVE_STDINT_H)
+if test $MF_HAVE_STDINT_H = 1
+then
+ MF_HAVE_UINTPTR_T=1
+else
+ AC_TRY_COMPILE([#include <sys/types.h>], [uintptr_t k = 0;],
+ [MF_HAVE_UINTPTR_T=1], [MF_HAVE_UINTPTR_T=0])
+fi
+AC_SUBST(MF_HAVE_UINTPTR_T)
+
+if test ! -d pth
+then
+ # libmudflapth objects are built in this subdirectory
+ mkdir pth
+fi
+
+pthread_create_version='""'
+AC_CHECK_HEADER(pthread.h,[
+AC_DEFINE_UNQUOTED(HAVE_PTHREAD_H, 1, [define if you have <pthread.h>])
+ac_have_pthread_h=yes
+],[
+ac_have_pthread_h=
+])
+AM_CONDITIONAL(LIBMUDFLAPTH, [test "x$ac_have_pthread_h" != ""])
+
+AC_CHECK_LIB(dl, dlsym)
+
+if test "x$enable_shared" = "xyes" && test "x$ac_have_pthread_h" != ""; then
+ # NB: don't check for -lpthread here, because then it would be
+ # added to LIBS. For the thread-unaware libmudflap.la, we don't
+ # want it there.
+
+ # glibc-related hacks. dlsym() may pick the wrong version of
+ # interposed functions like pthread_create on modern glibc.
+ # We need to find the proper symbol version string, and use
+ # the nonstandard dlvsym().
+ AC_CHECK_FUNCS(dlvsym)
+ AC_CHECK_TOOL(NM, nm)
+ if test "x$ac_cv_have_dlvsym" != ""; then
+ # Try compiling a simple pthreads program. Find the shared libraries it
+ # ends up with. Then use "nm" on those libraries to extract the
+ # default symbol versioning suffix ("@@"), if any. But that's tricky.
+ # Rather, run nm on the resulting executable. Unfortunately, autoconf
+ # doesn't appear to have a macro that builds a test executable for
+ # subsequent analysis ... so we do it by hand here.
+ cat >> conftest.c << EOF
+#include <pthread.h>
+int main () { void *p = (void *) & pthread_create; return (int) p; }
+EOF
+ oldLIBS="$LIBS"
+ LIBS="$LIBS -lpthread"
+ pthread_create_version="\"\""
+ AC_MSG_CHECKING(pthread_create symbol version)
+ if eval $ac_link 2>&5 && test -s conftest${ac_exeext}; then
+ version=`$NM conftest${ac_exeect} | grep 'pthread_create@@' | sed -e 's/^.*@@//'`
+ if test "x$version" != "x"; then
+ pthread_create_version="\"$version\""
+ fi
+ fi
+ AC_MSG_RESULT($pthread_create_version)
+ LIBS="$oldLIBS"
+ fi
+fi
+AC_DEFINE_UNQUOTED(PTHREAD_CREATE_VERSION, $pthread_create_version, [pthread_create symbol version])
+
+
+AC_OUTPUT([Makefile testsuite/Makefile mf-runtime.h])
diff --git a/libmudflap/mf-heuristics.c b/libmudflap/mf-heuristics.c
new file mode 100644
index 00000000000..5231a08253a
--- /dev/null
+++ b/libmudflap/mf-heuristics.c
@@ -0,0 +1,174 @@
+/* Mudflap: narrow-pointer bounds-checking by tree rewriting.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Frank Ch. Eigler <fche@redhat.com>
+ and Graydon Hoare <graydon@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#include "config.h"
+
+#include <stdio.h>
+
+#include "mf-runtime.h"
+#include "mf-impl.h"
+
+#ifdef _MUDFLAP
+#error "Do not compile this file with -fmudflap!"
+#endif
+
+
+extern char _end;
+extern char _start;
+
+
+/* Run some quick validation of the given region.
+ Return -1 / 0 / 1 if the access known-invalid, possibly-valid, or known-valid.
+*/
+int
+__mf_heuristic_check (uintptr_t ptr, uintptr_t ptr_high)
+{
+ VERBOSE_TRACE ("mf: heuristic check\n");
+
+ /* XXX: Disable the stack bounding check for libmudflapth. We do
+ actually have enough information to track stack bounds (see
+ __mf_pthread_info in mf-hooks.c), so with a bit of future work,
+ this heuristic can be turned on. */
+#ifndef LIBMUDFLAPTH
+
+ /* The first heuristic is to check stack bounds. This is a
+ transient condition and quick to check. */
+ if (__mf_opts.heur_stack_bound)
+ {
+ uintptr_t stack_top_guess = (uintptr_t)__builtin_frame_address(0);
+#if defined(__i386__) && defined (__linux__)
+ uintptr_t stack_segment_base = 0xC0000000; /* XXX: Bad assumption. */
+#else
+ /* Cause tests to fail. */
+ uintptr_t stack_segment_base = 0;
+#endif
+
+ VERBOSE_TRACE ("mf: stack estimated as %p-%p\n",
+ (void *) stack_top_guess, (void *) stack_segment_base);
+
+ if (ptr_high <= stack_segment_base &&
+ ptr >= stack_top_guess &&
+ ptr_high >= ptr)
+ {
+ return 1;
+ }
+ }
+#endif
+
+
+ /* The second heuristic is to scan the range of memory regions
+ listed in /proc/self/maps, a special file provided by the Linux
+ kernel. Its results may be cached, and in fact, a GUESS object
+ may as well be recorded for interesting matching sections. */
+ if (__mf_opts.heur_proc_map)
+ {
+ /* Keep a record of seen records from /proc/self/map. */
+ enum { max_entries = 500 };
+ struct proc_self_map_entry
+ {
+ uintptr_t low;
+ uintptr_t high;
+ };
+ static struct proc_self_map_entry entry [max_entries];
+ static unsigned entry_used [max_entries];
+
+ /* Look for a known proc_self_map entry that may cover this
+ region. If one exists, then this heuristic has already run,
+ and should not be run again. The check should be allowed to
+ fail. */
+ unsigned i;
+ unsigned deja_vu = 0;
+ for (i=0; i<max_entries; i++)
+ {
+ if (entry_used[i] &&
+ (entry[i].low <= ptr) &&
+ (entry[i].high >= ptr_high))
+ deja_vu = 1;
+ }
+
+ if (! deja_vu)
+ {
+ /* Time to run the heuristic. Rescan /proc/self/maps; update the
+ entry[] array; XXX: remove expired entries, add new ones.
+ XXX: Consider entries that have grown (e.g., stack). */
+ char buf[512];
+ char flags[4];
+ void *low, *high;
+ FILE *fp;
+
+ fp = fopen ("/proc/self/maps", "r");
+ if (fp)
+ {
+ while (fgets (buf, sizeof(buf), fp))
+ {
+ if (sscanf (buf, "%p-%p %4c", &low, &high, flags) == 3)
+ {
+ if ((uintptr_t) low <= ptr &&
+ (uintptr_t) high >= ptr_high)
+ {
+ for (i=0; i<max_entries; i++)
+ {
+ if (! entry_used[i])
+ {
+ entry[i].low = (uintptr_t) low;
+ entry[i].high = (uintptr_t) high;
+ entry_used[i] = 1;
+ break;
+ }
+ }
+
+ VERBOSE_TRACE ("mf: registering region #%d "
+ "%p-%p given %s",
+ i, (void *) low, (void *) high, buf);
+
+ __mfu_register ((void *) low, (size_t) (high-low),
+ __MF_TYPE_GUESS,
+ "/proc/self/maps segment");
+
+ return 0; /* undecided (tending to cachable) */
+ }
+ }
+ }
+ fclose (fp);
+ }
+ }
+ }
+
+
+ /* The third heuristic is to approve all accesses between _start and _end,
+ which should include all text and initialized data. */
+ if (__mf_opts.heur_start_end)
+ if (ptr >= (uintptr_t) & _start && ptr_high <= (uintptr_t) & _end)
+ return 1; /* uncacheable */
+
+ return 0; /* unknown */
+}
diff --git a/libmudflap/mf-hooks1.c b/libmudflap/mf-hooks1.c
new file mode 100644
index 00000000000..7199472ebe1
--- /dev/null
+++ b/libmudflap/mf-hooks1.c
@@ -0,0 +1,478 @@
+/* Mudflap: narrow-pointer bounds-checking by tree rewriting.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Frank Ch. Eigler <fche@redhat.com>
+ and Graydon Hoare <graydon@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#include "config.h"
+
+#ifndef HAVE_SOCKLEN_T
+#define socklen_t int
+#endif
+
+
+/* These attempt to coax various unix flavours to declare all our
+ needed tidbits in the system headers. */
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
+#define _POSIX_SOURCE
+#endif /* Some BSDs break <sys/socket.h> if this is defined. */
+#define _GNU_SOURCE
+#define _XOPEN_SOURCE
+#define _BSD_TYPES
+#define __EXTENSIONS__
+#define _ALL_SOURCE
+#define _LARGE_FILE_API
+#define _XOPEN_SOURCE_EXTENDED 1
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <time.h>
+
+#include "mf-runtime.h"
+#include "mf-impl.h"
+
+#ifdef _MUDFLAP
+#error "Do not compile this file with -fmudflap!"
+#endif
+
+
+/* Memory allocation related hook functions. Some of these are
+ intercepted via linker wrapping or symbol interposition. Others
+ use plain macros in mf-runtime.h. */
+
+
+#ifdef WRAP_malloc
+
+#if PIC
+/* A special bootstrap variant. */
+void *
+__mf_0fn_malloc (size_t c)
+{
+ /* fprintf (stderr, "0fn malloc c=%lu\n", c); */
+ return NULL;
+}
+#endif
+
+#undef malloc
+WRAPPER(void *, malloc, size_t c)
+{
+ size_t size_with_crumple_zones;
+ DECLARE(void *, malloc, size_t c);
+ void *result;
+ BEGIN_PROTECT (malloc, c);
+
+ size_with_crumple_zones =
+ CLAMPADD(c,CLAMPADD(__mf_opts.crumple_zone,
+ __mf_opts.crumple_zone));
+ result = (char *) CALL_REAL (malloc, size_with_crumple_zones);
+
+ if (LIKELY(result))
+ {
+ result += __mf_opts.crumple_zone;
+ __mf_register (result, c, __MF_TYPE_HEAP, "malloc region");
+ /* XXX: register __MF_TYPE_NOACCESS for crumple zones. */
+ }
+
+ return result;
+}
+#endif
+
+
+#ifdef WRAP_calloc
+
+#ifdef PIC
+/* A special bootstrap variant. */
+void *
+__mf_0fn_calloc (size_t c, size_t n)
+{
+ enum foo { BS = 4096, NB=10 };
+ static char bufs[NB][BS];
+ static unsigned bufs_used[NB];
+ unsigned i;
+
+ /* fprintf (stderr, "0fn calloc c=%lu n=%lu\n", c, n); */
+ for (i=0; i<NB; i++)
+ {
+ if (! bufs_used[i] && (c*n) < BS)
+ {
+ bufs_used[i] = 1;
+ return & bufs[i][0];
+ }
+ }
+ return NULL;
+}
+#endif
+
+#undef calloc
+WRAPPER(void *, calloc, size_t c, size_t n)
+{
+ size_t size_with_crumple_zones;
+ DECLARE(void *, calloc, size_t, size_t);
+ DECLARE(void *, malloc, size_t);
+ DECLARE(void *, memset, void *, int, size_t);
+ char *result;
+ BEGIN_PROTECT (calloc, c, n);
+
+ size_with_crumple_zones =
+ CLAMPADD((c * n), /* XXX: CLAMPMUL */
+ CLAMPADD(__mf_opts.crumple_zone,
+ __mf_opts.crumple_zone));
+ result = (char *) CALL_REAL (malloc, size_with_crumple_zones);
+
+ if (LIKELY(result))
+ memset (result, 0, size_with_crumple_zones);
+
+ if (LIKELY(result))
+ {
+ result += __mf_opts.crumple_zone;
+ __mf_register (result, c*n /* XXX: clamp */, __MF_TYPE_HEAP_I, "calloc region");
+ /* XXX: register __MF_TYPE_NOACCESS for crumple zones. */
+ }
+
+ return result;
+}
+#endif
+
+#ifdef WRAP_realloc
+
+#if PIC
+/* A special bootstrap variant. */
+void *
+__mf_0fn_realloc (void *buf, size_t c)
+{
+ return NULL;
+}
+#endif
+
+#undef realloc
+WRAPPER(void *, realloc, void *buf, size_t c)
+{
+ DECLARE(void * , realloc, void *, size_t);
+ size_t size_with_crumple_zones;
+ char *base = buf;
+ unsigned saved_wipe_heap;
+ char *result;
+ BEGIN_PROTECT (realloc, buf, c);
+
+ if (LIKELY(buf))
+ base -= __mf_opts.crumple_zone;
+
+ size_with_crumple_zones =
+ CLAMPADD(c, CLAMPADD(__mf_opts.crumple_zone,
+ __mf_opts.crumple_zone));
+ result = (char *) CALL_REAL (realloc, base, size_with_crumple_zones);
+
+ /* Ensure heap wiping doesn't occur during this peculiar
+ unregister/reregister pair. */
+ LOCKTH ();
+ __mf_state = reentrant;
+ saved_wipe_heap = __mf_opts.wipe_heap;
+ __mf_opts.wipe_heap = 0;
+
+ if (LIKELY(buf))
+ __mfu_unregister (buf, 0);
+
+ if (LIKELY(result))
+ {
+ result += __mf_opts.crumple_zone;
+ __mfu_register (result, c, __MF_TYPE_HEAP_I, "realloc region");
+ /* XXX: register __MF_TYPE_NOACCESS for crumple zones. */
+ }
+
+ /* Restore previous setting. */
+ __mf_opts.wipe_heap = saved_wipe_heap;
+
+ __mf_state = active;
+ UNLOCKTH ();
+
+ return result;
+}
+#endif
+
+
+#ifdef WRAP_free
+
+#if PIC
+/* A special bootstrap variant. */
+void
+__mf_0fn_free (void *buf)
+{
+ return;
+}
+#endif
+
+#undef free
+WRAPPER(void, free, void *buf)
+{
+ /* Use a circular queue to delay some number (__mf_opts.free_queue_length) of free()s. */
+ static void *free_queue [__MF_FREEQ_MAX];
+ static unsigned free_ptr = 0;
+ static int freeq_initialized = 0;
+ DECLARE(void, free, void *);
+
+ BEGIN_PROTECT (free, buf);
+
+ if (UNLIKELY(buf == NULL))
+ return;
+
+ LOCKTH ();
+ if (UNLIKELY(!freeq_initialized))
+ {
+ memset (free_queue, 0,
+ __MF_FREEQ_MAX * sizeof (void *));
+ freeq_initialized = 1;
+ }
+ UNLOCKTH ();
+
+ __mf_unregister (buf, 0);
+
+ if (UNLIKELY(__mf_opts.free_queue_length > 0))
+ {
+ char *freeme = NULL;
+ LOCKTH ();
+ if (free_queue [free_ptr] != NULL)
+ {
+ freeme = free_queue [free_ptr];
+ freeme -= __mf_opts.crumple_zone;
+ }
+ free_queue [free_ptr] = buf;
+ free_ptr = (free_ptr == (__mf_opts.free_queue_length-1) ? 0 : free_ptr + 1);
+ UNLOCKTH ();
+ if (freeme)
+ {
+ if (__mf_opts.trace_mf_calls)
+ {
+ VERBOSE_TRACE ("freeing deferred pointer %p (crumple %u)\n",
+ (void *) freeme,
+ __mf_opts.crumple_zone);
+ }
+ CALL_REAL (free, freeme);
+ }
+ }
+ else
+ {
+ /* back pointer up a bit to the beginning of crumple zone */
+ char *base = (char *)buf;
+ base -= __mf_opts.crumple_zone;
+ if (__mf_opts.trace_mf_calls)
+ {
+ VERBOSE_TRACE ("freeing pointer %p = %p - %u\n",
+ (void *) base,
+ (void *) buf,
+ __mf_opts.crumple_zone);
+ }
+ CALL_REAL (free, base);
+ }
+}
+#endif
+
+
+#ifdef WRAP_mmap
+
+#if PIC
+/* A special bootstrap variant. */
+void *
+__mf_0fn_mmap (void *start, size_t l, int prot, int f, int fd, off_t off)
+{
+ return (void *) -1;
+}
+#endif
+
+
+#undef mmap
+WRAPPER(void *, mmap,
+ void *start, size_t length, int prot,
+ int flags, int fd, off_t offset)
+{
+ DECLARE(void *, mmap, void *, size_t, int,
+ int, int, off_t);
+ void *result;
+ BEGIN_PROTECT (mmap, start, length, prot, flags, fd, offset);
+
+ result = CALL_REAL (mmap, start, length, prot,
+ flags, fd, offset);
+
+ /*
+ VERBOSE_TRACE ("mmap (%08lx, %08lx, ...) => %08lx\n",
+ (uintptr_t) start, (uintptr_t) length,
+ (uintptr_t) result);
+ */
+
+ if (result != (void *)-1)
+ {
+ /* Register each page as a heap object. Why not register it all
+ as a single segment? That's so that a later munmap() call
+ can unmap individual pages. XXX: would __MF_TYPE_GUESS make
+ this more automatic? */
+ size_t ps = getpagesize ();
+ uintptr_t base = (uintptr_t) result;
+ uintptr_t offset;
+
+ for (offset=0; offset<length; offset+=ps)
+ {
+ /* XXX: We could map PROT_NONE to __MF_TYPE_NOACCESS. */
+ /* XXX: Unaccessed HEAP pages are reported as leaks. Is this
+ appropriate for unaccessed mmap pages? */
+ __mf_register ((void *) CLAMPADD (base, offset), ps,
+ __MF_TYPE_HEAP_I, "mmap page");
+ }
+ }
+
+ return result;
+}
+#endif
+
+
+#ifdef WRAP_munmap
+
+#if PIC
+/* A special bootstrap variant. */
+int
+__mf_0fn_munmap (void *start, size_t length)
+{
+ return -1;
+}
+#endif
+
+
+#undef munmap
+WRAPPER(int , munmap, void *start, size_t length)
+{
+ DECLARE(int, munmap, void *, size_t);
+ int result;
+ BEGIN_PROTECT (munmap, start, length);
+
+ result = CALL_REAL (munmap, start, length);
+
+ /*
+ VERBOSE_TRACE ("munmap (%08lx, %08lx, ...) => %08lx\n",
+ (uintptr_t) start, (uintptr_t) length,
+ (uintptr_t) result);
+ */
+
+ if (result == 0)
+ {
+ /* Unregister each page as a heap object. */
+ size_t ps = getpagesize ();
+ uintptr_t base = (uintptr_t) start & (~ (ps - 1)); /* page align */
+ uintptr_t offset;
+
+ for (offset=0; offset<length; offset+=ps)
+ __mf_unregister ((void *) CLAMPADD (base, offset), ps);
+ }
+ return result;
+}
+#endif
+
+
+#ifdef WRAP_alloca
+
+/* This wrapper is a little different, as it's called indirectly from
+ __mf_fini also to clean up pending allocations. */
+void *
+__mf_wrap_alloca_indirect (size_t c)
+{
+ DECLARE (void *, malloc, size_t);
+ DECLARE (void, free, void *);
+
+ /* This struct, a linked list, tracks alloca'd objects. The newest
+ object is at the head of the list. If we detect that we've
+ popped a few levels of stack, then the listed objects are freed
+ as needed. NB: The tracking struct is allocated with
+ real_malloc; the user data with wrap_malloc.
+ */
+ struct alloca_tracking { void *ptr; void *stack; struct alloca_tracking* next; };
+ static struct alloca_tracking *alloca_history = NULL;
+
+ void *stack = __builtin_frame_address (0);
+ void *result;
+ struct alloca_tracking *track;
+
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ VERBOSE_TRACE ("alloca stack level %p\n", (void *) stack);
+
+ /* XXX: thread locking! */
+
+ /* Free any previously alloca'd blocks that belong to deeper-nested functions,
+ which must therefore have exited by now. */
+#define DEEPER_THAN < /* for x86 */
+ while (alloca_history &&
+ ((uintptr_t) alloca_history->stack DEEPER_THAN (uintptr_t) stack))
+ {
+ struct alloca_tracking *next = alloca_history->next;
+ __mf_unregister (alloca_history->ptr, 0);
+ CALL_REAL (free, alloca_history->ptr);
+ CALL_REAL (free, alloca_history);
+ alloca_history = next;
+ }
+
+ /* Allocate new block. */
+ result = NULL;
+ if (LIKELY (c > 0)) /* alloca(0) causes no allocation. */
+ {
+ track = (struct alloca_tracking *) CALL_REAL (malloc,
+ sizeof (struct alloca_tracking));
+ if (LIKELY (track != NULL))
+ {
+ result = CALL_REAL (malloc, c);
+ if (UNLIKELY (result == NULL))
+ {
+ CALL_REAL (free, track);
+ /* Too bad. XXX: What about errno? */
+ }
+ else
+ {
+ __mf_register (result, c, __MF_TYPE_HEAP, "alloca region");
+ track->ptr = result;
+ track->stack = stack;
+ track->next = alloca_history;
+ alloca_history = track;
+ }
+ }
+ }
+
+ return result;
+}
+
+
+#undef alloca
+WRAPPER(void *, alloca, size_t c)
+{
+ return __mf_wrap_alloca_indirect (c);
+}
+
+#endif
+
diff --git a/libmudflap/mf-hooks2.c b/libmudflap/mf-hooks2.c
new file mode 100644
index 00000000000..b0867729979
--- /dev/null
+++ b/libmudflap/mf-hooks2.c
@@ -0,0 +1,1767 @@
+/* Mudflap: narrow-pointer bounds-checking by tree rewriting.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Frank Ch. Eigler <fche@redhat.com>
+ and Graydon Hoare <graydon@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#include "config.h"
+
+#ifndef HAVE_SOCKLEN_T
+#define socklen_t int
+#endif
+
+/* These attempt to coax various unix flavours to declare all our
+ needed tidbits in the system headers. */
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
+#define _POSIX_SOURCE
+#endif /* Some BSDs break <sys/socket.h> if this is defined. */
+#define _GNU_SOURCE
+#define _XOPEN_SOURCE
+#define _BSD_TYPES
+#define __EXTENSIONS__
+#define _ALL_SOURCE
+#define _LARGE_FILE_API
+#define _XOPEN_SOURCE_EXTENDED 1
+
+#include <string.h>
+#include <strings.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <time.h>
+
+#include "mf-runtime.h"
+#include "mf-impl.h"
+
+#ifdef _MUDFLAP
+#error "Do not compile this file with -fmudflap!"
+#endif
+
+
+/* A bunch of independent stdlib/unistd hook functions, all
+ intercepted by mf-runtime.h macros. */
+
+#ifdef __FreeBSD__
+#undef WRAP_memrchr
+#undef WRAP_memmem
+#include <dlfcn.h>
+static inline size_t (strnlen) (const char* str, size_t n)
+{
+ const char *s;
+
+ for (s = str; n && *s; ++s, --n)
+ ;
+ return (s - str);
+}
+#endif
+
+/* str*,mem*,b* */
+
+#ifdef WRAP_memcpy
+WRAPPER2(void *, memcpy, void *dest, const void *src, size_t n)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "memcpy source");
+ MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "memcpy dest");
+ return memcpy (dest, src, n);
+}
+#endif
+
+
+#ifdef WRAP_memmove
+WRAPPER2(void *, memmove, void *dest, const void *src, size_t n)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "memmove src");
+ MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "memmove dest");
+ return memmove (dest, src, n);
+}
+#endif
+
+#ifdef WRAP_memset
+WRAPPER2(void *, memset, void *s, int c, size_t n)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "memset dest");
+ return memset (s, c, n);
+}
+#endif
+
+#ifdef WRAP_memcmp
+WRAPPER2(int, memcmp, const void *s1, const void *s2, size_t n)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "memcmp 1st arg");
+ MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "memcmp 2nd arg");
+ return memcmp (s1, s2, n);
+}
+#endif
+
+#ifdef WRAP_memchr
+WRAPPER2(void *, memchr, const void *s, int c, size_t n)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s, n, __MF_CHECK_READ, "memchr region");
+ return memchr (s, c, n);
+}
+#endif
+
+#ifdef WRAP_memrchr
+WRAPPER2(void *, memrchr, const void *s, int c, size_t n)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s, n, __MF_CHECK_READ, "memrchr region");
+ return memrchr (s, c, n);
+}
+#endif
+
+#ifdef WRAP_strcpy
+WRAPPER2(char *, strcpy, char *dest, const char *src)
+{
+ /* nb: just because strlen(src) == n doesn't mean (src + n) or (src + n +
+ 1) are valid pointers. the allocated object might have size < n.
+ check anyways. */
+
+ size_t n = strlen (src);
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(src, CLAMPADD(n, 1), __MF_CHECK_READ, "strcpy src");
+ MF_VALIDATE_EXTENT(dest, CLAMPADD(n, 1), __MF_CHECK_WRITE, "strcpy dest");
+ return strcpy (dest, src);
+}
+#endif
+
+#ifdef WRAP_strncpy
+WRAPPER2(char *, strncpy, char *dest, const char *src, size_t n)
+{
+ size_t len = strnlen (src, n);
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(src, len, __MF_CHECK_READ, "strncpy src");
+ MF_VALIDATE_EXTENT(dest, len, __MF_CHECK_WRITE, "strncpy dest"); /* nb: strNcpy */
+ return strncpy (dest, src, n);
+}
+#endif
+
+#ifdef WRAP_strcat
+WRAPPER2(char *, strcat, char *dest, const char *src)
+{
+ size_t dest_sz;
+ size_t src_sz;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ dest_sz = strlen (dest);
+ src_sz = strlen (src);
+ MF_VALIDATE_EXTENT(src, CLAMPADD(src_sz, 1), __MF_CHECK_READ, "strcat src");
+ MF_VALIDATE_EXTENT(dest, CLAMPADD(dest_sz, CLAMPADD(src_sz, 1)),
+ __MF_CHECK_WRITE, "strcat dest");
+ return strcat (dest, src);
+}
+#endif
+
+#ifdef WRAP_strncat
+WRAPPER2(char *, strncat, char *dest, const char *src, size_t n)
+{
+
+ /* nb: validating the extents (s,n) might be a mistake for two reasons.
+
+ (1) the string s might be shorter than n chars, and n is just a
+ poor choice by the programmer. this is not a "true" error in the
+ sense that the call to strncat would still be ok.
+
+ (2) we could try to compensate for case (1) by calling strlen(s) and
+ using that as a bound for the extent to verify, but strlen might fall off
+ the end of a non-terminated string, leading to a false positive.
+
+ so we will call strnlen(s,n) and use that as a bound.
+
+ if strnlen returns a length beyond the end of the registered extent
+ associated with s, there is an error: the programmer's estimate for n is
+ too large _AND_ the string s is unterminated, in which case they'd be
+ about to touch memory they don't own while calling strncat.
+
+ this same logic applies to further uses of strnlen later down in this
+ file. */
+
+ size_t src_sz;
+ size_t dest_sz;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ src_sz = strnlen (src, n);
+ dest_sz = strnlen (dest, n);
+ MF_VALIDATE_EXTENT(src, src_sz, __MF_CHECK_READ, "strncat src");
+ MF_VALIDATE_EXTENT(dest, (CLAMPADD(dest_sz, CLAMPADD(src_sz, 1))),
+ __MF_CHECK_WRITE, "strncat dest");
+ return strncat (dest, src, n);
+}
+#endif
+
+#ifdef WRAP_strcmp
+WRAPPER2(int, strcmp, const char *s1, const char *s2)
+{
+ size_t s1_sz;
+ size_t s2_sz;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ s1_sz = strlen (s1);
+ s2_sz = strlen (s2);
+ MF_VALIDATE_EXTENT(s1, CLAMPADD(s1_sz, 1), __MF_CHECK_READ, "strcmp 1st arg");
+ MF_VALIDATE_EXTENT(s2, CLAMPADD(s2_sz, 1), __MF_CHECK_WRITE, "strcmp 2nd arg");
+ return strcmp (s1, s2);
+}
+#endif
+
+#ifdef WRAP_strcasecmp
+WRAPPER2(int, strcasecmp, const char *s1, const char *s2)
+{
+ size_t s1_sz;
+ size_t s2_sz;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ s1_sz = strlen (s1);
+ s2_sz = strlen (s2);
+ MF_VALIDATE_EXTENT(s1, CLAMPADD(s1_sz, 1), __MF_CHECK_READ, "strcasecmp 1st arg");
+ MF_VALIDATE_EXTENT(s2, CLAMPADD(s2_sz, 1), __MF_CHECK_READ, "strcasecmp 2nd arg");
+ return strcasecmp (s1, s2);
+}
+#endif
+
+#ifdef WRAP_strncmp
+WRAPPER2(int, strncmp, const char *s1, const char *s2, size_t n)
+{
+ size_t s1_sz;
+ size_t s2_sz;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ s1_sz = strnlen (s1, n);
+ s2_sz = strnlen (s2, n);
+ MF_VALIDATE_EXTENT(s1, s1_sz, __MF_CHECK_READ, "strncmp 1st arg");
+ MF_VALIDATE_EXTENT(s2, s2_sz, __MF_CHECK_READ, "strncmp 2nd arg");
+ return strncmp (s1, s2, n);
+}
+#endif
+
+#ifdef WRAP_strncasecmp
+WRAPPER2(int, strncasecmp, const char *s1, const char *s2, size_t n)
+{
+ size_t s1_sz;
+ size_t s2_sz;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ s1_sz = strnlen (s1, n);
+ s2_sz = strnlen (s2, n);
+ MF_VALIDATE_EXTENT(s1, s1_sz, __MF_CHECK_READ, "strncasecmp 1st arg");
+ MF_VALIDATE_EXTENT(s2, s2_sz, __MF_CHECK_READ, "strncasecmp 2nd arg");
+ return strncasecmp (s1, s2, n);
+}
+#endif
+
+#ifdef WRAP_strdup
+WRAPPER2(char *, strdup, const char *s)
+{
+ DECLARE(void *, malloc, size_t sz);
+ char *result;
+ size_t n = strlen (s);
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strdup region");
+ result = (char *)CALL_REAL(malloc,
+ CLAMPADD(CLAMPADD(n,1),
+ CLAMPADD(__mf_opts.crumple_zone,
+ __mf_opts.crumple_zone)));
+
+ if (UNLIKELY(! result)) return result;
+
+ result += __mf_opts.crumple_zone;
+ memcpy (result, s, n);
+ result[n] = '\0';
+
+ __mf_register (result, CLAMPADD(n,1), __MF_TYPE_HEAP_I, "strdup region");
+ return result;
+}
+#endif
+
+#ifdef WRAP_strndup
+WRAPPER2(char *, strndup, const char *s, size_t n)
+{
+ DECLARE(void *, malloc, size_t sz);
+ char *result;
+ size_t sz = strnlen (s, n);
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s, sz, __MF_CHECK_READ, "strndup region"); /* nb: strNdup */
+
+ /* note: strndup still adds a \0, even with the N limit! */
+ result = (char *)CALL_REAL(malloc,
+ CLAMPADD(CLAMPADD(n,1),
+ CLAMPADD(__mf_opts.crumple_zone,
+ __mf_opts.crumple_zone)));
+
+ if (UNLIKELY(! result)) return result;
+
+ result += __mf_opts.crumple_zone;
+ memcpy (result, s, n);
+ result[n] = '\0';
+
+ __mf_register (result, CLAMPADD(n,1), __MF_TYPE_HEAP_I, "strndup region");
+ return result;
+}
+#endif
+
+#ifdef WRAP_strchr
+WRAPPER2(char *, strchr, const char *s, int c)
+{
+ size_t n;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ n = strlen (s);
+ MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strchr region");
+ return strchr (s, c);
+}
+#endif
+
+#ifdef WRAP_strrchr
+WRAPPER2(char *, strrchr, const char *s, int c)
+{
+ size_t n;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ n = strlen (s);
+ MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), __MF_CHECK_READ, "strrchr region");
+ return strrchr (s, c);
+}
+#endif
+
+#ifdef WRAP_strstr
+WRAPPER2(char *, strstr, const char *haystack, const char *needle)
+{
+ size_t haystack_sz;
+ size_t needle_sz;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ haystack_sz = strlen (haystack);
+ needle_sz = strlen (needle);
+ MF_VALIDATE_EXTENT(haystack, CLAMPADD(haystack_sz, 1), __MF_CHECK_READ, "strstr haystack");
+ MF_VALIDATE_EXTENT(needle, CLAMPADD(needle_sz, 1), __MF_CHECK_READ, "strstr needle");
+ return strstr (haystack, needle);
+}
+#endif
+
+#ifdef WRAP_memmem
+WRAPPER2(void *, memmem,
+ const void *haystack, size_t haystacklen,
+ const void *needle, size_t needlelen)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(haystack, haystacklen, __MF_CHECK_READ, "memmem haystack");
+ MF_VALIDATE_EXTENT(needle, needlelen, __MF_CHECK_READ, "memmem needle");
+ return memmem (haystack, haystacklen, needle, needlelen);
+}
+#endif
+
+#ifdef WRAP_strlen
+WRAPPER2(size_t, strlen, const char *s)
+{
+ size_t result = strlen (s);
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s, CLAMPADD(result, 1), __MF_CHECK_READ, "strlen region");
+ return result;
+}
+#endif
+
+#ifdef WRAP_strnlen
+WRAPPER2(size_t, strnlen, const char *s, size_t n)
+{
+ size_t result = strnlen (s, n);
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s, result, __MF_CHECK_READ, "strnlen region");
+ return result;
+}
+#endif
+
+#ifdef WRAP_bzero
+WRAPPER2(void, bzero, void *s, size_t n)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "bzero region");
+ bzero (s, n);
+}
+#endif
+
+#ifdef WRAP_bcopy
+#undef bcopy
+WRAPPER2(void, bcopy, const void *src, void *dest, size_t n)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "bcopy src");
+ MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "bcopy dest");
+ bcopy (src, dest, n);
+}
+#endif
+
+#ifdef WRAP_bcmp
+#undef bcmp
+WRAPPER2(int, bcmp, const void *s1, const void *s2, size_t n)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "bcmp 1st arg");
+ MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "bcmp 2nd arg");
+ return bcmp (s1, s2, n);
+}
+#endif
+
+#ifdef WRAP_index
+WRAPPER2(char *, index, const char *s, int c)
+{
+ size_t n = strlen (s);
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "index region");
+ return index (s, c);
+}
+#endif
+
+#ifdef WRAP_rindex
+WRAPPER2(char *, rindex, const char *s, int c)
+{
+ size_t n = strlen (s);
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "rindex region");
+ return rindex (s, c);
+}
+#endif
+
+/* XXX: stpcpy, memccpy */
+
+
+/* XXX: *printf,*scanf */
+
+
+/* XXX: setjmp, longjmp */
+
+#ifdef WRAP_asctime
+WRAPPER2(char *, asctime, struct tm *tm)
+{
+ static char *reg_result = NULL;
+ char *result;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(tm, sizeof (struct tm), __MF_CHECK_READ, "asctime tm");
+ result = asctime (tm);
+ if (reg_result == NULL)
+ {
+ __mf_register (result, strlen (result)+1, __MF_TYPE_STATIC, "asctime string");
+ reg_result = result;
+ }
+ return result;
+}
+#endif
+
+#ifdef WRAP_ctime
+WRAPPER2(char *, ctime, const time_t *timep)
+{
+ static char *reg_result = NULL;
+ char *result;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "ctime time");
+ result = ctime (timep);
+ if (reg_result == NULL)
+ {
+ /* XXX: what if asctime and ctime return the same static ptr? */
+ __mf_register (result, strlen (result)+1, __MF_TYPE_STATIC, "ctime string");
+ reg_result = result;
+ }
+ return result;
+}
+#endif
+
+
+#ifdef WRAP_localtime
+WRAPPER2(struct tm*, localtime, const time_t *timep)
+{
+ static struct tm *reg_result = NULL;
+ struct tm *result;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "localtime time");
+ result = localtime (timep);
+ if (reg_result == NULL)
+ {
+ __mf_register (result, sizeof (struct tm), __MF_TYPE_STATIC, "localtime tm");
+ reg_result = result;
+ }
+ return result;
+}
+#endif
+
+#ifdef WRAP_gmtime
+WRAPPER2(struct tm*, gmtime, const time_t *timep)
+{
+ static struct tm *reg_result = NULL;
+ struct tm *result;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT(timep, sizeof (time_t), __MF_CHECK_READ, "gmtime time");
+ result = gmtime (timep);
+ if (reg_result == NULL)
+ {
+ __mf_register (result, sizeof (struct tm), __MF_TYPE_STATIC, "gmtime tm");
+ reg_result = result;
+ }
+ return result;
+}
+#endif
+
+
+
+/* EL start */
+
+/* The following indicate if the result of the corresponding function
+ * should be explicitly un/registered by the wrapper
+*/
+#define MF_REGISTER_strerror __MF_TYPE_STATIC
+#undef MF_REGISTER_fopen
+#define MF_RESULT_SIZE_fopen (sizeof (FILE))
+#undef MF_REGISTER_opendir
+#define MF_RESULT_SIZE_opendir 0 /* (sizeof (DIR)) */
+#undef MF_REGISTER_readdir
+#define MF_REGISTER_gethostbyname __MF_TYPE_STATIC
+#undef MF_REGISTER_gethostbyname_items
+#undef MF_REGISTER_dlopen
+#undef MF_REGISTER_dlerror
+#undef MF_REGISTER_dlsym
+#define MF_REGISTER_shmat __MF_TYPE_GUESS
+
+
+#ifdef WRAP_time
+#include <time.h>
+WRAPPER2(time_t, time, time_t *timep)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ if (NULL != timep)
+ MF_VALIDATE_EXTENT (timep, sizeof (*timep), __MF_CHECK_WRITE,
+ "time timep");
+ return time (timep);
+}
+#endif
+
+#ifdef WRAP_strerror
+WRAPPER2(char *, strerror, int errnum)
+{
+ char *p;
+ size_t n;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ p = strerror (errnum);
+ if (NULL != p) {
+ n = strlen (p);
+ n = CLAMPADD(n, 1);
+#ifdef MF_REGISTER_strerror
+ __mf_register (p, n, MF_REGISTER_strerror, "strerror result");
+#endif
+ MF_VALIDATE_EXTENT (p, n, __MF_CHECK_WRITE, "strerror result");
+ }
+ return p;
+}
+#endif
+
+#ifdef WRAP_fopen
+WRAPPER2(FILE *, fopen, const char *path, const char *mode)
+{
+ size_t n;
+ FILE *p;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+
+ n = strlen (path);
+ MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen path");
+
+ n = strlen (mode);
+ MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen mode");
+
+ p = fopen (path, mode);
+ if (NULL != p) {
+#ifdef MF_REGISTER_fopen
+ __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fopen result");
+#endif
+ MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fopen result");
+ }
+
+ return p;
+}
+#endif
+
+#ifdef HAVE_FOPEN64
+#ifdef WRAP_fopen64
+WRAPPER2(FILE *, fopen64, const char *path, const char *mode)
+{
+ size_t n;
+ FILE *p;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+
+ n = strlen (path);
+ MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen64 path");
+
+ n = strlen (mode);
+ MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "fopen64 mode");
+
+ p = fopen64 (path, mode);
+ if (NULL != p) {
+#ifdef MF_REGISTER_fopen
+ __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fopen64 result");
+#endif
+ MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fopen64 result");
+ }
+
+ return p;
+}
+#endif
+#endif
+
+#ifdef WRAP_fclose
+WRAPPER2(int, fclose, FILE *stream)
+{
+ int resp;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "fclose stream");
+ resp = fclose (stream);
+#ifdef MF_REGISTER_fopen
+ __mf_unregister (stream, sizeof (*stream));
+#endif
+
+ return resp;
+}
+#endif
+
+#ifdef WRAP_fread
+WRAPPER2(size_t, fread, void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "fread stream");
+ MF_VALIDATE_EXTENT (ptr, size * nmemb, __MF_CHECK_WRITE, "fread buffer");
+ return fread (ptr, size, nmemb, stream);
+}
+#endif
+
+#ifdef WRAP_fwrite
+WRAPPER2(size_t, fwrite, const void *ptr, size_t size, size_t nmemb,
+ FILE *stream)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "fwrite stream");
+ MF_VALIDATE_EXTENT (ptr, size * nmemb, __MF_CHECK_READ, "fwrite buffer");
+ return fwrite (ptr, size, nmemb, stream);
+}
+#endif
+
+#ifdef WRAP_fgetc
+WRAPPER2(int, fgetc, FILE *stream)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "fgetc stream");
+ return fgetc (stream);
+}
+#endif
+
+#ifdef WRAP_fgets
+WRAPPER2(char *, fgets, char *s, int size, FILE *stream)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "fgets stream");
+ MF_VALIDATE_EXTENT (s, size, __MF_CHECK_WRITE, "fgets buffer");
+ return fgets (s, size, stream);
+}
+#endif
+
+#ifdef WRAP_getc
+WRAPPER2(int, getc, FILE *stream)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "getc stream");
+ return getc (stream);
+}
+#endif
+
+#ifdef WRAP_gets
+WRAPPER2(char *, gets, char *s)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (s, 1, __MF_CHECK_WRITE, "gets buffer");
+ /* Avoid link-time warning... */
+ s = fgets (s, INT_MAX, stdin);
+ if (NULL != s) { /* better late than never */
+ size_t n = strlen (s);
+ MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_WRITE, "gets buffer");
+ }
+ return s;
+}
+#endif
+
+#ifdef WRAP_ungetc
+WRAPPER2(int, ungetc, int c, FILE *stream)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "ungetc stream");
+ return ungetc (c, stream);
+}
+#endif
+
+#ifdef WRAP_fputc
+WRAPPER2(int, fputc, int c, FILE *stream)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "fputc stream");
+ return fputc (c, stream);
+}
+#endif
+
+#ifdef WRAP_fputs
+WRAPPER2(int, fputs, const char *s, FILE *stream)
+{
+ size_t n;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ n = strlen (s);
+ MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "fputs buffer");
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "fputs stream");
+ return fputs (s, stream);
+}
+#endif
+
+#ifdef WRAP_putc
+WRAPPER2(int, putc, int c, FILE *stream)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "putc stream");
+ return putc (c, stream);
+}
+#endif
+
+#ifdef WRAP_puts
+WRAPPER2(int, puts, const char *s)
+{
+ size_t n;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ n = strlen (s);
+ MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "puts buffer");
+ return puts (s);
+}
+#endif
+
+#ifdef WRAP_clearerr
+WRAPPER2(void, clearerr, FILE *stream)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "clearerr stream");
+ clearerr (stream);
+}
+#endif
+
+#ifdef WRAP_feof
+WRAPPER2(int, feof, FILE *stream)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "feof stream");
+ return feof (stream);
+}
+#endif
+
+#ifdef WRAP_ferror
+WRAPPER2(int, ferror, FILE *stream)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "ferror stream");
+ return ferror (stream);
+}
+#endif
+
+#ifdef WRAP_fileno
+#include <stdio.h>
+WRAPPER2(int, fileno, FILE *stream)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "fileno stream");
+ return fileno (stream);
+}
+#endif
+
+#ifdef WRAP_printf
+#include <stdio.h>
+#include <stdarg.h>
+WRAPPER2(int, printf, const char *format, ...)
+{
+ size_t n;
+ va_list ap;
+ int result;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ n = strlen (format);
+ MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
+ "printf format");
+ va_start (ap, format);
+ result = vprintf (format, ap);
+ va_end (ap);
+ return result;
+}
+#endif
+
+#ifdef WRAP_fprintf
+#include <stdio.h>
+#include <stdarg.h>
+WRAPPER2(int, fprintf, FILE *stream, const char *format, ...)
+{
+ size_t n;
+ va_list ap;
+ int result;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "fprintf stream");
+ n = strlen (format);
+ MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
+ "fprintf format");
+ va_start (ap, format);
+ result = vfprintf (stream, format, ap);
+ va_end (ap);
+ return result;
+}
+#endif
+
+#ifdef WRAP_sprintf
+#include <stdio.h>
+#include <stdarg.h>
+WRAPPER2(int, sprintf, char *str, const char *format, ...)
+{
+ size_t n;
+ va_list ap;
+ int result;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (str, 1, __MF_CHECK_WRITE, "sprintf str");
+ n = strlen (format);
+ MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
+ "sprintf format");
+ va_start (ap, format);
+ result = vsprintf (str, format, ap);
+ va_end (ap);
+ n = strlen (str);
+ MF_VALIDATE_EXTENT (str, CLAMPADD(n, 1), __MF_CHECK_WRITE, "sprintf str");
+ return result;
+}
+#endif
+
+#ifdef WRAP_snprintf
+#include <stdio.h>
+#include <stdarg.h>
+WRAPPER2(int, snprintf, char *str, size_t size, const char *format, ...)
+{
+ size_t n;
+ va_list ap;
+ int result;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (str, size, __MF_CHECK_WRITE, "snprintf str");
+ n = strlen (format);
+ MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
+ "snprintf format");
+ va_start (ap, format);
+ result = vsnprintf (str, size, format, ap);
+ va_end (ap);
+ return result;
+}
+#endif
+
+#ifdef WRAP_vprintf
+#include <stdio.h>
+#include <stdarg.h>
+WRAPPER2(int, vprintf, const char *format, va_list ap)
+{
+ size_t n;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ n = strlen (format);
+ MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
+ "vprintf format");
+ return vprintf (format, ap);
+}
+#endif
+
+#ifdef WRAP_vfprintf
+#include <stdio.h>
+#include <stdarg.h>
+WRAPPER2(int, vfprintf, FILE *stream, const char *format, va_list ap)
+{
+ size_t n;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "vfprintf stream");
+ n = strlen (format);
+ MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
+ "vfprintf format");
+ return vfprintf (stream, format, ap);
+}
+#endif
+
+#ifdef WRAP_vsprintf
+#include <stdio.h>
+#include <stdarg.h>
+WRAPPER2(int, vsprintf, char *str, const char *format, va_list ap)
+{
+ size_t n;
+ int result;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (str, 1, __MF_CHECK_WRITE, "vsprintf str");
+ n = strlen (format);
+ MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
+ "vsprintf format");
+ result = vsprintf (str, format, ap);
+ n = strlen (str);
+ MF_VALIDATE_EXTENT (str, CLAMPADD(n, 1), __MF_CHECK_WRITE, "vsprintf str");
+ return result;
+}
+#endif
+
+#ifdef WRAP_vsnprintf
+#include <stdio.h>
+#include <stdarg.h>
+WRAPPER2(int, vsnprintf, char *str, size_t size, const char *format,
+ va_list ap)
+{
+ size_t n;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (str, size, __MF_CHECK_WRITE, "vsnprintf str");
+ n = strlen (format);
+ MF_VALIDATE_EXTENT (format, CLAMPADD(n, 1), __MF_CHECK_READ,
+ "vsnprintf format");
+ return vsnprintf (str, size, format, ap);
+}
+#endif
+
+#ifdef WRAP_access
+WRAPPER2(int , access, const char *path, int mode)
+{
+ size_t n;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ n = strlen (path);
+ MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "access path");
+ return access (path, mode);
+}
+#endif
+
+#ifdef WRAP_remove
+WRAPPER2(int , remove, const char *path)
+{
+ size_t n;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ n = strlen (path);
+ MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "remove path");
+ return remove (path);
+}
+#endif
+
+#ifdef WRAP_fflush
+WRAPPER2(int, fflush, FILE *stream)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "fflush stream");
+ return fflush (stream);
+}
+#endif
+
+#ifdef WRAP_fseek
+WRAPPER2(int, fseek, FILE *stream, long offset, int whence)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "fseek stream");
+ return fseek (stream, offset, whence);
+}
+#endif
+
+#ifdef HAVE_FSEEKO64
+#ifdef WRAP_fseeko64
+WRAPPER2(int, fseeko64, FILE *stream, off64_t offset, int whence)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "fseeko64 stream");
+ return fseeko64 (stream, offset, whence);
+}
+#endif
+#endif
+
+#ifdef WRAP_ftell
+WRAPPER2(long, ftell, FILE *stream)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "ftell stream");
+ return ftell (stream);
+}
+#endif
+
+#ifdef HAVE_FTELLO64
+#ifdef WRAP_ftello64
+WRAPPER2(off64_t, ftello64, FILE *stream)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "ftello64 stream");
+ return ftello64 (stream);
+}
+#endif
+#endif
+
+#ifdef WRAP_rewind
+WRAPPER2(void, rewind, FILE *stream)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "rewind stream");
+ rewind (stream);
+}
+#endif
+
+#ifdef WRAP_fgetpos
+WRAPPER2(int, fgetpos, FILE *stream, fpos_t *pos)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "fgetpos stream");
+ MF_VALIDATE_EXTENT (pos, sizeof (*pos), __MF_CHECK_WRITE, "fgetpos pos");
+ return fgetpos (stream, pos);
+}
+#endif
+
+#ifdef WRAP_fsetpos
+WRAPPER2(int, fsetpos, FILE *stream, fpos_t *pos)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "fsetpos stream");
+ MF_VALIDATE_EXTENT (pos, sizeof (*pos), __MF_CHECK_READ, "fsetpos pos");
+ return fsetpos (stream, pos);
+}
+#endif
+
+#ifdef WRAP_stat
+#include <sys/stat.h>
+WRAPPER2(int , stat, const char *path, struct stat *buf)
+{
+ size_t n;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ n = strlen (path);
+ MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "stat path");
+ MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "stat buf");
+ return stat (path, buf);
+}
+#endif
+
+#ifdef HAVE_STAT64
+#ifdef WRAP_stat64
+#include <sys/stat.h>
+WRAPPER2(int , stat64, const char *path, struct stat64 *buf)
+{
+ size_t n;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ n = strlen (path);
+ MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "stat64 path");
+ MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "stat64 buf");
+ return stat64 (path, buf);
+}
+#endif
+#endif
+
+#ifdef WRAP_fstat
+#include <sys/stat.h>
+WRAPPER2(int , fstat, int filedes, struct stat *buf)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "fstat buf");
+ return fstat (filedes, buf);
+}
+#endif
+
+#ifdef WRAP_lstat
+#include <sys/stat.h>
+WRAPPER2(int , lstat, const char *path, struct stat *buf)
+{
+ size_t n;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ n = strlen (path);
+ MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "lstat path");
+ MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ, "lstat buf");
+ return lstat (path, buf);
+}
+#endif
+
+#ifdef WRAP_mkfifo
+#include <sys/stat.h>
+WRAPPER2(int , mkfifo, const char *path, mode_t mode)
+{
+ size_t n;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ n = strlen (path);
+ MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "mkfifo path");
+ return mkfifo (path, mode);
+}
+#endif
+
+#ifdef WRAP_setvbuf
+WRAPPER2(int, setvbuf, FILE *stream, char *buf, int mode , size_t size)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "setvbuf stream");
+ if (NULL != buf)
+ MF_VALIDATE_EXTENT (buf, size, __MF_CHECK_READ, "setvbuf buf");
+ return setvbuf (stream, buf, mode, size);
+}
+#endif
+
+#ifdef WRAP_setbuf
+WRAPPER2(void, setbuf, FILE *stream, char *buf)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "setbuf stream");
+ if (NULL != buf)
+ MF_VALIDATE_EXTENT (buf, BUFSIZ, __MF_CHECK_READ, "setbuf buf");
+ setbuf (stream, buf);
+}
+#endif
+
+#ifdef WRAP_opendir
+#include <dirent.h>
+WRAPPER2(DIR *, opendir, const char *path)
+{
+ DIR *p;
+ size_t n;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ n = strlen (path);
+ MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "opendir path");
+
+ p = opendir (path);
+ if (NULL != p) {
+#ifdef MF_REGISTER_opendir
+ __mf_register (p, MF_RESULT_SIZE_opendir, MF_REGISTER_opendir,
+ "opendir result");
+#endif
+ MF_VALIDATE_EXTENT (p, MF_RESULT_SIZE_opendir, __MF_CHECK_WRITE,
+ "opendir result");
+ }
+ return p;
+}
+#endif
+
+#ifdef WRAP_closedir
+#include <dirent.h>
+WRAPPER2(int, closedir, DIR *dir)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (dir, 0, __MF_CHECK_WRITE, "closedir dir");
+#ifdef MF_REGISTER_opendir
+ __mf_unregister (dir, MF_RESULT_SIZE_opendir);
+#endif
+ return closedir (dir);
+}
+#endif
+
+#ifdef WRAP_readdir
+#include <dirent.h>
+WRAPPER2(struct dirent *, readdir, DIR *dir)
+{
+ struct dirent *p;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (dir, 0, __MF_CHECK_READ, "readdir dir");
+ p = readdir (dir);
+ if (NULL != p) {
+#ifdef MF_REGISTER_readdir
+ __mf_register (p, sizeof (*p), MF_REGISTER_readdir, "readdir result");
+#endif
+ MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "readdir result");
+ }
+ return p;
+}
+#endif
+
+#ifdef WRAP_recv
+#include <sys/socket.h>
+WRAPPER2(int, recv, int s, void *buf, size_t len, int flags)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (buf, len, __MF_CHECK_WRITE, "recv buf");
+ return recv (s, buf, len, flags);
+}
+#endif
+
+#ifdef WRAP_recvfrom
+#include <sys/socket.h>
+WRAPPER2(int, recvfrom, int s, void *buf, size_t len, int flags,
+ struct sockaddr *from, socklen_t *fromlen)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (buf, len, __MF_CHECK_WRITE, "recvfrom buf");
+ MF_VALIDATE_EXTENT (from, (size_t)*fromlen, __MF_CHECK_WRITE,
+ "recvfrom from");
+ return recvfrom (s, buf, len, flags, from, fromlen);
+}
+#endif
+
+#ifdef WRAP_recvmsg
+#include <sys/socket.h>
+WRAPPER2(int, recvmsg, int s, struct msghdr *msg, int flags)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (msg, sizeof (*msg), __MF_CHECK_WRITE, "recvmsg msg");
+ return recvmsg (s, msg, flags);
+}
+#endif
+
+#ifdef WRAP_send
+#include <sys/socket.h>
+WRAPPER2(int, send, int s, const void *msg, size_t len, int flags)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (msg, len, __MF_CHECK_READ, "send msg");
+ return send (s, msg, len, flags);
+}
+#endif
+
+#ifdef WRAP_sendto
+#include <sys/socket.h>
+WRAPPER2(int, sendto, int s, const void *msg, size_t len, int flags,
+ const struct sockaddr *to, socklen_t tolen)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (msg, len, __MF_CHECK_READ, "sendto msg");
+ MF_VALIDATE_EXTENT (to, (size_t)tolen, __MF_CHECK_WRITE, "sendto to");
+ return sendto (s, msg, len, flags, to, tolen);
+}
+#endif
+
+#ifdef WRAP_sendmsg
+#include <sys/socket.h>
+WRAPPER2(int, sendmsg, int s, const void *msg, int flags)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (msg, sizeof (*msg), __MF_CHECK_READ, "sendmsg msg");
+ return sendmsg (s, msg, flags);
+}
+#endif
+
+#ifdef WRAP_setsockopt
+#include <sys/socket.h>
+WRAPPER2(int, setsockopt, int s, int level, int optname, const void *optval,
+ socklen_t optlen)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (optval, (size_t)optlen, __MF_CHECK_READ,
+ "setsockopt optval");
+ return setsockopt (s, level, optname, optval, optlen);
+}
+#endif
+
+#ifdef WRAP_getsockopt
+#include <sys/socket.h>
+WRAPPER2(int, getsockopt, int s, int level, int optname, void *optval,
+ socklen_t *optlen)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (optval, (size_t)*optlen, __MF_CHECK_WRITE,
+ "getsockopt optval");
+ return getsockopt (s, level, optname, optval, optlen);
+}
+#endif
+
+#ifdef WRAP_accept
+#include <sys/socket.h>
+WRAPPER2(int, accept, int s, struct sockaddr *addr, socklen_t *addrlen)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (addr, (size_t)*addrlen, __MF_CHECK_WRITE, "accept addr");
+ return accept (s, addr, addrlen);
+}
+#endif
+
+#ifdef WRAP_bind
+#include <sys/socket.h>
+WRAPPER2(int, bind, int sockfd, struct sockaddr *addr, socklen_t addrlen)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (addr, (size_t)addrlen, __MF_CHECK_WRITE, "bind addr");
+ return bind (sockfd, addr, addrlen);
+}
+#endif
+
+#ifdef WRAP_connect
+#include <sys/socket.h>
+WRAPPER2(int, connect, int sockfd, const struct sockaddr *addr,
+ socklen_t addrlen)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (addr, (size_t)addrlen, __MF_CHECK_READ,
+ "connect addr");
+ return connect (sockfd, addr, addrlen);
+}
+#endif
+
+#ifdef WRAP_gethostname
+WRAPPER2(int, gethostname, char *name, size_t len)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (name, len, __MF_CHECK_WRITE, "gethostname name");
+ return gethostname (name, len);
+}
+#endif
+
+#ifdef WRAP_sethostname
+WRAPPER2(int, sethostname, const char *name, size_t len)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (name, len, __MF_CHECK_READ, "sethostname name");
+ return sethostname (name, len);
+}
+#endif
+
+#ifdef WRAP_gethostbyname
+#include <netdb.h>
+WRAPPER2(struct hostent *, gethostbyname, const char *name)
+{
+ struct hostent *p;
+ char **ss;
+ char *s;
+ size_t n;
+ int nreg;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ n = strlen (name);
+ MF_VALIDATE_EXTENT (name, CLAMPADD(n, 1), __MF_CHECK_READ,
+ "gethostbyname name");
+ p = gethostbyname (name);
+ if (NULL != p) {
+#ifdef MF_REGISTER_gethostbyname
+ __mf_register (p, sizeof (*p), MF_REGISTER_gethostbyname,
+ "gethostbyname result");
+#endif
+ MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE,
+ "gethostbyname result");
+ if (NULL != (s = p->h_name)) {
+ n = strlen (s);
+ n = CLAMPADD(n, 1);
+#ifdef MF_REGISTER_gethostbyname_items
+ __mf_register (s, n, MF_REGISTER_gethostbyname_items,
+ "gethostbyname result->h_name");
+#endif
+ MF_VALIDATE_EXTENT (s, n, __MF_CHECK_WRITE,
+ "gethostbyname result->h_name");
+ }
+
+ if (NULL != (ss = p->h_aliases)) {
+ for (nreg = 1;; ++nreg) {
+ s = *ss++;
+ if (NULL == s)
+ break;
+ n = strlen (s);
+ n = CLAMPADD(n, 1);
+#ifdef MF_REGISTER_gethostbyname_items
+ __mf_register (s, n, MF_REGISTER_gethostbyname_items,
+ "gethostbyname result->h_aliases[]");
+#endif
+ MF_VALIDATE_EXTENT (s, n, __MF_CHECK_WRITE,
+ "gethostbyname result->h_aliases[]");
+ }
+ nreg *= sizeof (*p->h_aliases);
+#ifdef MF_REGISTER_gethostbyname_items
+ __mf_register (p->h_aliases, nreg, MF_REGISTER_gethostbyname_items,
+ "gethostbyname result->h_aliases");
+#endif
+ MF_VALIDATE_EXTENT (p->h_aliases, nreg, __MF_CHECK_WRITE,
+ "gethostbyname result->h_aliases");
+ }
+
+ if (NULL != (ss = p->h_addr_list)) {
+ for (nreg = 1;; ++nreg) {
+ s = *ss++;
+ if (NULL == s)
+ break;
+#ifdef MF_REGISTER_gethostbyname_items
+ __mf_register (s, p->h_length, MF_REGISTER_gethostbyname_items,
+ "gethostbyname result->h_addr_list[]");
+#endif
+ MF_VALIDATE_EXTENT (s, p->h_length, __MF_CHECK_WRITE,
+ "gethostbyname result->h_addr_list[]");
+ }
+ nreg *= sizeof (*p->h_addr_list);
+#ifdef MF_REGISTER_gethostbyname_items
+ __mf_register (p->h_addr_list, nreg, MF_REGISTER_gethostbyname_items,
+ "gethostbyname result->h_addr_list");
+#endif
+ MF_VALIDATE_EXTENT (p->h_addr_list, nreg, __MF_CHECK_WRITE,
+ "gethostbyname result->h_addr_list");
+ }
+ }
+ return p;
+}
+#endif
+
+#ifdef WRAP_wait
+#include <sys/wait.h>
+WRAPPER2(pid_t, wait, int *status)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ if (NULL != status)
+ MF_VALIDATE_EXTENT (status, sizeof (*status), __MF_CHECK_WRITE,
+ "wait status");
+ return wait (status);
+}
+#endif
+
+#ifdef WRAP_waitpid
+#include <sys/wait.h>
+WRAPPER2(pid_t, waitpid, pid_t pid, int *status, int options)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ if (NULL != status)
+ MF_VALIDATE_EXTENT (status, sizeof (*status), __MF_CHECK_WRITE,
+ "waitpid status");
+ return waitpid (pid, status, options);
+}
+#endif
+
+#ifdef WRAP_popen
+WRAPPER2(FILE *, popen, const char *command, const char *mode)
+{
+ size_t n;
+ FILE *p;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+
+ n = strlen (command);
+ MF_VALIDATE_EXTENT (command, CLAMPADD(n, 1), __MF_CHECK_READ, "popen path");
+
+ n = strlen (mode);
+ MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "popen mode");
+
+ p = popen (command, mode);
+ if (NULL != p) {
+#ifdef MF_REGISTER_fopen
+ __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "popen result");
+#endif
+ MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "popen result");
+ }
+ return p;
+}
+#endif
+
+#ifdef WRAP_pclose
+WRAPPER2(int, pclose, FILE *stream)
+{
+ int resp;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE,
+ "pclose stream");
+ resp = pclose (stream);
+#ifdef MF_REGISTER_fopen
+ __mf_unregister (stream, sizeof (*stream));
+#endif
+ return resp;
+}
+#endif
+
+#ifdef WRAP_execve
+WRAPPER2(int, execve, const char *path, char *const argv [],
+ char *const envp[])
+{
+ size_t n;
+ char *const *p;
+ const char *s;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+
+ n = strlen (path);
+ MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execve path");
+
+ for (p = argv;;) {
+ MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execve *argv");
+ s = *p++;
+ if (NULL == s)
+ break;
+ n = strlen (s);
+ MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execve **argv");
+ }
+
+ for (p = envp;;) {
+ MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execve *envp");
+ s = *p++;
+ if (NULL == s)
+ break;
+ n = strlen (s);
+ MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execve **envp");
+ }
+ return execve (path, argv, envp);
+}
+#endif
+
+#ifdef WRAP_execv
+WRAPPER2(int, execv, const char *path, char *const argv [])
+{
+ size_t n;
+ char *const *p;
+ const char *s;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+
+ n = strlen (path);
+ MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execv path");
+
+ for (p = argv;;) {
+ MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execv *argv");
+ s = *p++;
+ if (NULL == s)
+ break;
+ n = strlen (s);
+ MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execv **argv");
+ }
+ return execv (path, argv);
+}
+#endif
+
+#ifdef WRAP_execvp
+WRAPPER2(int, execvp, const char *path, char *const argv [])
+{
+ size_t n;
+ char *const *p;
+ const char *s;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+
+ n = strlen (path);
+ MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "execvp path");
+
+ for (p = argv;;) {
+ MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_READ, "execvp *argv");
+ s = *p++;
+ if (NULL == s)
+ break;
+ n = strlen (s);
+ MF_VALIDATE_EXTENT (s, CLAMPADD(n, 1), __MF_CHECK_READ, "execvp **argv");
+ }
+ return execvp (path, argv);
+}
+#endif
+
+#ifdef WRAP_system
+WRAPPER2(int, system, const char *string)
+{
+ size_t n;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ n = strlen (string);
+ MF_VALIDATE_EXTENT (string, CLAMPADD(n, 1), __MF_CHECK_READ,
+ "system string");
+ return system (string);
+}
+#endif
+
+#ifdef WRAP_dlopen
+WRAPPER2(void *, dlopen, const char *path, int flags)
+{
+ void *p;
+ size_t n;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ n = strlen (path);
+ MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "dlopen path");
+ p = dlopen (path, flags);
+ if (NULL != p) {
+#ifdef MF_REGISTER_dlopen
+ __mf_register (p, 0, MF_REGISTER_dlopen, "dlopen result");
+#endif
+ MF_VALIDATE_EXTENT (p, 0, __MF_CHECK_WRITE, "dlopen result");
+ }
+ return p;
+}
+#endif
+
+#ifdef WRAP_dlclose
+WRAPPER2(int, dlclose, void *handle)
+{
+ int resp;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (handle, 0, __MF_CHECK_READ, "dlclose handle");
+ resp = dlclose (handle);
+#ifdef MF_REGISTER_dlopen
+ __mf_unregister (handle, 0);
+#endif
+ return resp;
+}
+#endif
+
+#ifdef WRAP_dlerror
+WRAPPER2(char *, dlerror)
+{
+ char *p;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ p = dlerror ();
+ if (NULL != p) {
+ size_t n;
+ n = strlen (p);
+ n = CLAMPADD(n, 1);
+#ifdef MF_REGISTER_dlerror
+ __mf_register (p, n, MF_REGISTER_dlerror, "dlerror result");
+#endif
+ MF_VALIDATE_EXTENT (p, n, __MF_CHECK_WRITE, "dlerror result");
+ }
+ return p;
+}
+#endif
+
+#ifdef WRAP_dlsym
+WRAPPER2(void *, dlsym, void *handle, char *symbol)
+{
+ size_t n;
+ void *p;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (handle, 0, __MF_CHECK_READ, "dlsym handle");
+ n = strlen (symbol);
+ MF_VALIDATE_EXTENT (symbol, CLAMPADD(n, 1), __MF_CHECK_READ, "dlsym symbol");
+ p = dlsym (handle, symbol);
+ if (NULL != p) {
+#ifdef MF_REGISTER_dlsym
+ __mf_register (p, 0, MF_REGISTER_dlsym, "dlsym result");
+#endif
+ MF_VALIDATE_EXTENT (p, 0, __MF_CHECK_WRITE, "dlsym result");
+ }
+ return p;
+}
+#endif
+
+#ifdef WRAP_semop
+#include <sys/ipc.h>
+#include <sys/sem.h>
+WRAPPER2(int, semop, int semid, struct sembuf *sops, unsigned nsops)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ MF_VALIDATE_EXTENT (sops, sizeof (*sops) * nsops, __MF_CHECK_READ,
+ "semop sops");
+ return semop (semid, sops, nsops);
+}
+#endif
+
+#ifdef WRAP_semctl
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#ifndef HAVE_UNION_SEMUN
+union semun {
+ int val; /* value for SETVAL */
+ struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
+ unsigned short int *array; /* array for GETALL, SETALL */
+ struct seminfo *__buf; /* buffer for IPC_INFO */
+};
+#endif
+WRAPPER2(int, semctl, int semid, int semnum, int cmd, union semun arg)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ switch (cmd) {
+ case IPC_STAT:
+ MF_VALIDATE_EXTENT (arg.buf, sizeof (*arg.buf), __MF_CHECK_WRITE,
+ "semctl buf");
+ break;
+ case IPC_SET:
+ MF_VALIDATE_EXTENT (arg.buf, sizeof (*arg.buf), __MF_CHECK_READ,
+ "semctl buf");
+ break;
+ case GETALL:
+ MF_VALIDATE_EXTENT (arg.array, sizeof (*arg.array), __MF_CHECK_WRITE,
+ "semctl array");
+ case SETALL:
+ MF_VALIDATE_EXTENT (arg.array, sizeof (*arg.array), __MF_CHECK_READ,
+ "semctl array");
+ break;
+#ifdef IPC_INFO
+ /* FreeBSD 5.1 headers include IPC_INFO but not the __buf field. */
+#if !defined(__FreeBSD__)
+ case IPC_INFO:
+ MF_VALIDATE_EXTENT (arg.__buf, sizeof (*arg.__buf), __MF_CHECK_WRITE,
+ "semctl __buf");
+ break;
+#endif
+#endif
+ default:
+ break;
+ }
+ return semctl (semid, semnum, cmd, arg);
+}
+#endif
+
+#ifdef WRAP_shmctl
+#include <sys/ipc.h>
+#include <sys/shm.h>
+WRAPPER2(int, shmctl, int shmid, int cmd, struct shmid_ds *buf)
+{
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ switch (cmd) {
+ case IPC_STAT:
+ MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_WRITE,
+ "shmctl buf");
+ break;
+ case IPC_SET:
+ MF_VALIDATE_EXTENT (buf, sizeof (*buf), __MF_CHECK_READ,
+ "shmctl buf");
+ break;
+ default:
+ break;
+ }
+ return shmctl (shmid, cmd, buf);
+}
+#endif
+
+#ifdef WRAP_shmat
+#include <sys/ipc.h>
+#include <sys/shm.h>
+WRAPPER2(void *, shmat, int shmid, const void *shmaddr, int shmflg)
+{
+ void *p;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ p = shmat (shmid, shmaddr, shmflg);
+#ifdef MF_REGISTER_shmat
+ if (NULL != p) {
+ struct shmid_ds buf;
+ __mf_register (p, shmctl (shmid, IPC_STAT, &buf) ? 0 : buf.shm_segsz,
+ MF_REGISTER_shmat, "shmat result");
+ }
+#endif
+ return p;
+}
+#endif
+
+#ifdef WRAP_shmdt
+#include <sys/ipc.h>
+#include <sys/shm.h>
+WRAPPER2(int, shmdt, const void *shmaddr)
+{
+ int resp;
+ TRACE ("%s\n", __PRETTY_FUNCTION__);
+ resp = shmdt (shmaddr);
+#ifdef MF_REGISTER_shmat
+ __mf_unregister ((void *)shmaddr, 0);
+#endif
+ return resp;
+}
+#endif
+
diff --git a/libmudflap/mf-hooks3.c b/libmudflap/mf-hooks3.c
new file mode 100644
index 00000000000..838f3810db5
--- /dev/null
+++ b/libmudflap/mf-hooks3.c
@@ -0,0 +1,573 @@
+/* Mudflap: narrow-pointer bounds-checking by tree rewriting.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Frank Ch. Eigler <fche@redhat.com>
+ and Graydon Hoare <graydon@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#include "config.h"
+
+#ifndef HAVE_SOCKLEN_T
+#define socklen_t int
+#endif
+
+/* These attempt to coax various unix flavours to declare all our
+ needed tidbits in the system headers. */
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
+#define _POSIX_SOURCE
+#endif /* Some BSDs break <sys/socket.h> if this is defined. */
+#define _GNU_SOURCE
+#define _XOPEN_SOURCE
+#define _BSD_TYPES
+#define __EXTENSIONS__
+#define _ALL_SOURCE
+#define _LARGE_FILE_API
+#define _XOPEN_SOURCE_EXTENDED 1
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <sched.h>
+
+#include "mf-runtime.h"
+#include "mf-impl.h"
+
+#ifdef _MUDFLAP
+#error "Do not compile this file with -fmudflap!"
+#endif
+
+
+/* Multithreading support hooks. */
+
+
+#ifdef WRAP_pthreadstuff
+
+
+#ifndef LIBMUDFLAPTH
+#error "pthreadstuff is to be included only in libmudflapth"
+#endif
+
+
+
+/* Describe a thread (dead or alive). */
+struct pthread_info
+{
+ short used_p; /* Is this slot in use? */
+ short dead_p; /* Is this thread dead? */
+ pthread_t self; /* The thread id. */
+
+ /* If libmudflapth allocated the stack, store its base/size. */
+ void *stack;
+ size_t stack_size;
+
+ int *thread_errno;
+ enum __mf_state_enum state;
+};
+
+
+/* Describe the startup information for a new user thread. */
+struct pthread_start_info
+{
+ /* The user's thread entry point and argument. */
+ void * (*user_fn)(void *);
+ void *user_arg;
+
+ /* Set by user thread when this startup struct may be disposed of. */
+ struct pthread_info *thread_info;
+};
+
+
+
+
+/* To avoid dynamic memory allocation, use static array to store these
+ thread description structs. The second (_idx) array is used as a
+ simple caching hash table, mapping PTHREAD_HASH(thread) to its
+ index in __mf_pthread_info[]. */
+
+#define LIBMUDFLAPTH_THREADS_MAX 1024
+static struct pthread_info __mf_pthread_info[LIBMUDFLAPTH_THREADS_MAX];
+static unsigned __mf_pthread_info_idx[LIBMUDFLAPTH_THREADS_MAX];
+#define PTHREAD_HASH(p) ((unsigned) (p) % LIBMUDFLAPTH_THREADS_MAX)
+
+
+/* Find any old empty entry in __mf_pthread_info; mark it used and
+ return it. Return NULL if there are no more available slots. */
+struct pthread_info*
+__mf_allocate_blank_threadinfo (unsigned* idx)
+{
+ static unsigned probe = LIBMUDFLAPTH_THREADS_MAX-1;
+ unsigned probe_at_start = probe;
+ static pthread_mutex_t mutex =
+#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
+ PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
+#else
+ PTHREAD_MUTEX_INITIALIZER;
+#endif
+ int rc;
+
+ rc = pthread_mutex_lock (& mutex);
+ assert (rc == 0);
+
+ /* Look for a blank spot starting one past the last one we found. */
+ do
+ {
+ probe = (probe + 1) % LIBMUDFLAPTH_THREADS_MAX;
+ struct pthread_info* pi = & __mf_pthread_info [probe];
+ if (! pi->used_p)
+ {
+ /* memset (pi, 0, sizeof (*pi)); */
+ pi->used_p = 1;
+ if (idx != NULL) *idx = probe;
+ /* VERBOSE_TRACE ("allocated threadinfo slot %u\n", probe); */
+ rc = pthread_mutex_unlock (& mutex);
+ assert (rc == 0);
+ return pi;
+ }
+ }
+ while (probe != probe_at_start);
+
+ rc = pthread_mutex_unlock (& mutex);
+ assert (rc == 0);
+ return NULL;
+}
+
+
+/* Find and return the pthread_info struct for the current thread.
+ There might already be one in __mf_pthread_info for this thread, in
+ which case return it. There may not be one (if this is a main
+ thread, an auxiliary -lpthread manager, or an actual user thread
+ making an early call into libmudflap. In these cases, create a new
+ entry. If not it's not the main thread, put it into reentrant
+ initial state.
+*/
+static struct pthread_info*
+__mf_find_threadinfo ()
+{
+ pthread_t it = pthread_self ();
+ unsigned *hash = & __mf_pthread_info_idx [PTHREAD_HASH (it)];
+ struct pthread_info *result = NULL;
+ static pthread_t last;
+ static int main_thread_seen_p;
+
+ /* Check out the lookup cache; failing that, do a linear search
+ around the table. */
+ {
+ struct pthread_info* pi = & __mf_pthread_info [*hash];
+ unsigned i;
+
+ if (pi->used_p && pi->self == it)
+ result = pi;
+ else for (i = 0; i < LIBMUDFLAPTH_THREADS_MAX; i++)
+ {
+ struct pthread_info* pi2 = & __mf_pthread_info [i];
+ if (pi2->used_p && pi2->self == it)
+ {
+ *hash = i;
+ result = pi2;
+ break;
+ }
+ }
+ }
+
+ if (result == NULL)
+ {
+ /* Create a __mf_pthread_info record for the main thread. It's
+ different from the auto-recognized worker bees because for
+ example we can assume that it's a fully stack/errno-equipped
+ thread. */
+
+ /* This must be the main thread, until now unseen in libmudflap. */
+ unsigned *hash = & __mf_pthread_info_idx [PTHREAD_HASH (it)];
+ struct pthread_info* pi = __mf_allocate_blank_threadinfo (hash);
+ assert (pi != NULL);
+ assert (pi->used_p);
+ result = pi;
+ result->self = it;
+
+ if (! main_thread_seen_p)
+ {
+ result->state = active;
+ /* NB: leave result->thread_errno unset, as main thread's errno
+ has already been registered in __mf_init. */
+ /* NB: leave stack-related fields unset, to avoid
+ deallocation. */
+ main_thread_seen_p = 1;
+ VERBOSE_TRACE ("identified self as main thread\n");
+ }
+ else
+ {
+ result->state = reentrant;
+ /* NB: leave result->thread_errno unset, as worker thread's
+ errno is unlikely to be used, and user threads fill them
+ in during __mf_pthread_spawn(). */
+ /* NB: leave stack-related fields unset, leaving pthread_create
+ to fill them in for user threads, leaving them empty for
+ other threads. */
+ VERBOSE_TRACE ("identified self as new aux or user thread\n");
+ }
+ }
+
+ if (last != it)
+ {
+ VERBOSE_TRACE ("found threadinfo for %u, slot %u\n",
+ (unsigned) it,
+ (unsigned) *hash);
+ last = it;
+ }
+
+ assert (result != NULL);
+ assert (result->self == it);
+
+ return result;
+}
+
+
+
+/* Return a pointer to the per-thread __mf_state variable. */
+enum __mf_state_enum *
+__mf_state_perthread ()
+{
+ assert (! __mf_starting_p);
+ return & (__mf_find_threadinfo()->state);
+}
+
+
+static void
+__mf_pthread_cleanup (void *arg)
+{
+ struct pthread_info *pi = arg;
+
+ /* XXX: This unregistration is not safe on platforms where distinct
+ threads share errno (or at least its virtual address). */
+ if (pi->thread_errno != NULL)
+ __mf_unregister (pi->thread_errno, sizeof (int));
+
+ /* XXX: Only detached threads should designate themselves as dead
+ here. Non-detached threads are marked dead after their
+ personalized pthread_join() call. */
+ pi->state = reentrant;
+ pi->dead_p = 1;
+
+ VERBOSE_TRACE ("thread pi %p exiting\n", pi);
+}
+
+
+static void *
+__mf_pthread_spawner (void *arg)
+{
+ struct pthread_info *pi = __mf_find_threadinfo ();
+ void *result = NULL;
+
+ /* Turn off reentrancy indications. */
+ assert (pi->state == reentrant);
+ pi->state = active;
+
+ VERBOSE_TRACE ("new user thread\n");
+
+ if (__mf_opts.heur_std_data)
+ {
+ pi->thread_errno = & errno;
+ __mf_register (pi->thread_errno, sizeof (int),
+ __MF_TYPE_GUESS, "errno area (thread)");
+ /* NB: we could use __MF_TYPE_STATIC above, but we guess that
+ the thread errno is coming out of some dynamically allocated
+ pool that we already know of as __MF_TYPE_HEAP. */
+ }
+
+ /* We considered using pthread_key_t objects instead of these
+ cleanup stacks, but they were less cooperative with the
+ interposed malloc hooks in libmudflap. */
+ pthread_cleanup_push (& __mf_pthread_cleanup, pi);
+
+ /* Call user thread */
+ {
+ /* Extract given entry point and argument. */
+ struct pthread_start_info *psi = arg;
+ void * (*user_fn)(void *) = psi->user_fn;
+ void *user_arg = psi->user_arg;
+
+ /* Signal the main thread to resume. */
+ psi->thread_info = pi;
+
+ result = (*user_fn)(user_arg);
+ }
+
+ pthread_cleanup_pop (1 /* execute */);
+
+ /* NB: there is a slight race here. The pthread_info field will now
+ say this thread is dead, but it may still be running .. right
+ here. We try to check for this possibility using the
+ pthread_kill test below. */
+
+ return result;
+}
+
+
+#if PIC
+/* A special bootstrap variant. */
+int
+__mf_0fn_pthread_create (pthread_t *thr, const pthread_attr_t *attr,
+ void * (*start) (void *), void *arg)
+{
+ return -1;
+}
+#endif
+
+
+#undef pthread_create
+WRAPPER(int, pthread_create, pthread_t *thr, const pthread_attr_t *attr,
+ void * (*start) (void *), void *arg)
+{
+ DECLARE(int, munmap, void *p, size_t l);
+ DECLARE(void *, mmap, void *p, size_t l, int prot, int flags, int fd, off_t of);
+ DECLARE(int, pthread_create, pthread_t *thr, const pthread_attr_t *attr,
+ void * (*start) (void *), void *arg);
+ int result;
+ pthread_attr_t override_attr;
+ void *override_stack;
+ size_t override_stacksize;
+ unsigned i;
+
+ TRACE ("pthread_create\n");
+
+ /* Garbage-collect dead threads' stacks. */
+ LOCKTH ();
+ for (i = 0; i < LIBMUDFLAPTH_THREADS_MAX; i++)
+ {
+ struct pthread_info *pi = & __mf_pthread_info [i];
+ if (! pi->used_p)
+ continue;
+ if (! pi->dead_p)
+ continue;
+
+ /* VERBOSE_TRACE ("thread %u pi %p stack cleanup deferred (%u)\n",
+ (unsigned) pi->self, pi, pi->dead_p); */
+
+ /* Delay actual deallocation by a few cycles, try to discourage the
+ race mentioned at the end of __mf_pthread_spawner(). */
+ if (pi->dead_p)
+ pi->dead_p ++;
+ if (pi->dead_p >= 10 /* XXX */)
+ {
+ if (pi->stack)
+ CALL_REAL (munmap, pi->stack, pi->stack_size);
+
+ VERBOSE_TRACE ("slot %u freed, stack %p\n", i, pi->stack);
+ memset (pi, 0, sizeof (*pi));
+
+ /* One round of garbage collection is enough. */
+ break;
+ }
+ }
+ UNLOCKTH ();
+
+ /* Let's allocate a stack for this thread, if one is not already
+ supplied by the caller. We don't want to let e.g. the
+ linuxthreads manager thread do this allocation. */
+ if (attr != NULL)
+ override_attr = *attr;
+ else
+ pthread_attr_init (& override_attr);
+
+ /* Get supplied attributes, if any. */
+ /* XXX: consider using POSIX2K attr_getstack() */
+ if (pthread_attr_getstackaddr (& override_attr, & override_stack) != 0 ||
+ pthread_attr_getstacksize (& override_attr, & override_stacksize) != 0)
+ {
+ override_stack = NULL;
+ override_stacksize = 0;
+ }
+
+ /* Do we need to allocate the new thread's stack? */
+ if (__mf_opts.thread_stack && override_stack == NULL)
+ {
+ uintptr_t alignment = 256; /* power of two */
+
+ /* Perturb the initial stack addresses slightly, to encourage
+ threads to have nonconflicting entries in the lookup cache
+ for their tracked stack objects. */
+ static unsigned perturb = 0;
+ const unsigned perturb_delta = 32;
+ const unsigned perturb_count = 16;
+ perturb += perturb_delta;
+ if (perturb > perturb_delta*perturb_count) perturb = 0;
+
+ /* Use glibc x86 defaults */
+/* Should have been defined in <limits.h> */
+#ifndef PTHREAD_STACK_MIN
+#define PTHREAD_STACK_MIN 65536
+#endif
+ override_stacksize = max (PTHREAD_STACK_MIN, __mf_opts.thread_stack * 1024);
+
+
+#if defined(MAP_ANONYMOUS)
+#define MF_MAP_ANON MAP_ANONYMOUS
+#elif defined(MAP_ANON)
+#define MF_MAP_ANON MAP_ANON
+#else
+#error "Cannot mmap anonymous memory."
+#endif
+
+ override_stack = CALL_REAL (mmap, NULL, override_stacksize,
+ PROT_READ|PROT_WRITE,
+ MAP_PRIVATE|MF_MAP_ANON,
+ 0, 0);
+ if (override_stack == 0 || override_stack == MAP_FAILED)
+ {
+ errno = EAGAIN;
+ return -1;
+ }
+
+ VERBOSE_TRACE ("thread stack alloc %p size %lu\n",
+ override_stack, (unsigned long) override_stacksize);
+
+ /* The stackaddr pthreads attribute is a candidate stack pointer.
+ It must point near the top or the bottom of this buffer, depending
+ on whether stack grows downward or upward, and suitably aligned.
+ On the x86, it grows down, so we set stackaddr near the top. */
+ override_stack = (void *)
+ (((uintptr_t) override_stack + override_stacksize - alignment - perturb)
+ & (~(uintptr_t)(alignment-1)));
+
+ /* XXX: consider using POSIX2K attr_setstack() */
+ if (pthread_attr_setstackaddr (& override_attr, override_stack) != 0 ||
+ pthread_attr_setstacksize (& override_attr,
+ override_stacksize - alignment - perturb) != 0)
+ {
+ /* This should not happen. */
+ CALL_REAL (munmap, override_stack, override_stacksize);
+ errno = EAGAIN;
+ return -1;
+ }
+ }
+
+ /* Actually start the child thread. */
+ {
+ struct pthread_start_info psi;
+ struct pthread_info *pi = NULL;
+
+ /* Fill in startup-control fields. */
+ psi.user_fn = start;
+ psi.user_arg = arg;
+ psi.thread_info = NULL;
+
+ /* Actually create the thread. */
+ __mf_state = reentrant;
+ result = CALL_REAL (pthread_create, thr, & override_attr,
+ & __mf_pthread_spawner, (void *) & psi);
+ __mf_state = active;
+ /* We also hook pthread_join/pthread_exit to get into reentrant
+ mode during thread shutdown/cleanup. */
+
+ /* Wait until child thread has progressed far enough into its
+ __mf_pthread_spawner() call. */
+ while (1) /* XXX: timeout? */
+ {
+ volatile struct pthread_start_info *psip = & psi;
+ pi = psip->thread_info;
+ if (pi != NULL)
+ break;
+ sched_yield ();
+ }
+
+ /* Fill in remaining fields in pthread_info. */
+ pi->stack = override_stack;
+ pi->stack_size = override_stacksize;
+ /* XXX: this might be too late for future heuristics that attempt
+ to use thread stack bounds. We may need to put the new thread
+ to sleep. */
+ }
+
+
+ /* May need to clean up if we created a pthread_attr_t of our own. */
+ if (attr == NULL)
+ pthread_attr_destroy (& override_attr); /* NB: this shouldn't deallocate stack */
+
+ return result;
+}
+
+
+
+#if PIC
+/* A special bootstrap variant. */
+int
+__mf_0fn_pthread_join (pthread_t thr, void **rc)
+{
+ return -1;
+}
+#endif
+
+
+#undef pthread_join
+WRAPPER(int, pthread_join, pthread_t thr, void **rc)
+{
+ DECLARE(int, pthread_join, pthread_t thr, void **rc);
+ int result;
+
+ TRACE ("pthread_join\n");
+ __mf_state = reentrant;
+ result = CALL_REAL (pthread_join, thr, rc);
+ __mf_state = active;
+
+ return result;
+}
+
+
+#if PIC
+/* A special bootstrap variant. */
+void
+__mf_0fn_pthread_exit (void *rc)
+{
+}
+#endif
+
+
+#undef pthread_exit
+WRAPPER(void, pthread_exit, void *rc)
+{
+ DECLARE(void, pthread_exit, void *rc);
+
+ TRACE ("pthread_exit\n");
+ /* __mf_state = reentrant; */
+ CALL_REAL (pthread_exit, rc);
+ /* NOTREACHED */
+}
+
+
+
+
+
+
+
+#endif /* pthreadstuff */
diff --git a/libmudflap/mf-impl.h b/libmudflap/mf-impl.h
new file mode 100644
index 00000000000..05120bfe4b6
--- /dev/null
+++ b/libmudflap/mf-impl.h
@@ -0,0 +1,389 @@
+/* Implementation header for mudflap runtime library.
+ Mudflap: narrow-pointer bounds-checking by tree rewriting.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Frank Ch. Eigler <fche@redhat.com>
+ and Graydon Hoare <graydon@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#ifndef __MF_IMPL_H
+#define __MF_IMPL_H
+
+#ifdef _MUDFLAP
+#error "Do not compile this file with -fmudflap!"
+#endif
+
+#if HAVE_PTHREAD_H
+#include <pthread.h>
+#elif LIBMUDFLAPTH
+#error "Cannot build libmudflapth without pthread.h."
+#endif
+
+
+/* Private definitions related to mf-runtime.h */
+
+#define __MF_TYPE_MAX_CEM __MF_TYPE_STACK /* largest type# for the cemetary */
+#define __MF_TYPE_MAX __MF_TYPE_GUESS
+
+
+#ifndef max
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+#ifndef min
+#define min(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+/* Address calculation macros. */
+
+#define MINPTR ((uintptr_t) 0)
+#define MAXPTR (~ (uintptr_t) 0)
+
+/* Clamp the addition/subtraction of uintptr_t's to [MINPTR,MAXPTR] */
+#define CLAMPSUB(ptr,offset) (((uintptr_t) ptr) >= (offset) ? ((uintptr_t) ptr)-((uintptr_t) offset) : MINPTR)
+#define CLAMPADD(ptr,offset) (((uintptr_t) ptr) <= MAXPTR-(offset) ? ((uintptr_t) ptr)+((uintptr_t) offset) : MAXPTR)
+#define CLAMPSZ(ptr,size) ((size) ? (((uintptr_t) ptr) <= MAXPTR-(size)+1 ? ((uintptr_t) ptr)+((uintptr_t) size) - 1 : MAXPTR) : ((uintptr_t) ptr))
+
+#define __MF_CACHE_INDEX(ptr) ((((uintptr_t) (ptr)) >> __mf_lc_shift) & __mf_lc_mask)
+#define __MF_CACHE_MISS_P(ptr,sz) ({ \
+ struct __mf_cache *elem = & __mf_lookup_cache[__MF_CACHE_INDEX((ptr))]; \
+ ((elem->low > (uintptr_t) (ptr)) || \
+ (elem->high < (CLAMPADD((uintptr_t) (ptr), (uintptr_t) CLAMPSUB(sz,1) )))); })
+/* XXX: the above should use CLAMPSZ () */
+
+
+
+/* Private functions. */
+
+extern void __mf_violation (void *ptr, size_t sz,
+ uintptr_t pc, const char *location,
+ int type);
+extern size_t __mf_backtrace (char ***, void *, unsigned);
+extern int __mf_heuristic_check (uintptr_t, uintptr_t);
+
+/* ------------------------------------------------------------------------ */
+/* Type definitions. */
+/* ------------------------------------------------------------------------ */
+
+/* The mf_state type codes describe recursion and initialization order. */
+
+enum __mf_state_enum { active, reentrant };
+
+/* The __mf_options structure records optional or tunable aspects of the
+ mudflap library's behavior. There is a single global instance of this
+ structure which is populated from user input (in an environment variable)
+ when the library initializes. */
+
+struct __mf_options
+{
+ /* Emit a trace message for each call. */
+ unsigned trace_mf_calls;
+
+ /* Collect and emit statistics. */
+ unsigned collect_stats;
+
+ /* Set up a SIGUSR1 -> __mf_report handler. */
+ unsigned sigusr1_report;
+
+ /* Execute internal checking code. */
+ unsigned internal_checking;
+
+ /* Age object liveness periodically. */
+ unsigned tree_aging;
+
+ /* Adapt the lookup cache to working set. */
+ unsigned adapt_cache;
+
+ /* Print list of leaked heap objects on shutdown. */
+ unsigned print_leaks;
+
+ /* Detect reads of uninitialized objects. */
+ unsigned check_initialization;
+
+ /* Print verbose description of violations. */
+ unsigned verbose_violations;
+
+ /* Abbreviate duplicate object descriptions. */
+ unsigned abbreviate;
+
+ /* Emit internal tracing message. */
+ unsigned verbose_trace;
+
+ /* Support multiple threads. XXX: not yet implemented. */
+ /* unsigned multi_threaded; */
+
+ /* Wipe stack/heap objects upon unwind. */
+ unsigned wipe_stack;
+ unsigned wipe_heap;
+
+ /* Maintain a queue of this many deferred free()s,
+ to trap use of freed memory. */
+ unsigned free_queue_length;
+
+ /* Maintain a history of this many past unregistered objects. */
+ unsigned persistent_count;
+
+ /* Pad allocated extents by this many bytes on either side. */
+ unsigned crumple_zone;
+
+ /* Maintain this many stack frames for contexts. */
+ unsigned backtrace;
+
+#ifdef LIBMUDFLAPTH
+ /* Thread stack size. */
+ unsigned thread_stack;
+#endif
+
+ /* Major operation mode */
+ enum
+ {
+ mode_nop, /* mudflaps do nothing */
+ mode_populate, /* mudflaps populate tree but do not check for violations */
+ mode_check, /* mudflaps populate and check for violations (normal) */
+ mode_violate /* mudflaps trigger a violation on every call (diagnostic) */
+ }
+ mudflap_mode;
+
+
+ /* How to handle a violation. */
+
+ enum
+ {
+ viol_nop, /* Return control to application. */
+ viol_segv, /* Signal self with segv. */
+ viol_abort, /* Call abort (). */
+ viol_gdb /* Fork a debugger on self */
+ }
+ violation_mode;
+
+ /* Violation heuristics selection. */
+ unsigned heur_stack_bound; /* allow current stack region */
+ unsigned heur_proc_map; /* allow & cache /proc/self/map regions. */
+ unsigned heur_start_end; /* allow _start .. _end */
+ unsigned heur_std_data; /* allow & cache stdlib data */
+};
+
+
+#ifdef PIC
+
+/* This is a table of dynamically resolved function pointers. */
+
+struct __mf_dynamic_entry
+{
+ void *pointer;
+ char *name;
+ char *version;
+};
+
+/* The definition of the array (mf-runtime.c) must match the enums! */
+extern struct __mf_dynamic_entry __mf_dynamic[];
+enum __mf_dynamic_index
+{
+ dyn_calloc, dyn_free, dyn_malloc, dyn_mmap,
+ dyn_munmap, dyn_realloc,
+ dyn_INITRESOLVE, /* Marker for last init-time resolution. */
+#ifdef LIBMUDFLAPTH
+ dyn_pthread_create,
+ dyn_pthread_join,
+ dyn_pthread_exit
+#endif
+};
+
+#endif /* PIC */
+
+/* ------------------------------------------------------------------------ */
+/* Private global variables. */
+/* ------------------------------------------------------------------------ */
+
+#ifdef LIBMUDFLAPTH
+extern pthread_mutex_t __mf_biglock;
+#define LOCKTH() do { extern unsigned long __mf_lock_contention; \
+ int rc = pthread_mutex_trylock (& __mf_biglock); \
+ if (rc) { __mf_lock_contention ++; \
+ rc = pthread_mutex_lock (& __mf_biglock); } \
+ assert (rc==0); } while (0)
+#define UNLOCKTH() do { int rc = pthread_mutex_unlock (& __mf_biglock); \
+ assert (rc==0); } while (0)
+#else
+#define LOCKTH() do {} while (0)
+#define UNLOCKTH() do {} while (0)
+#endif
+
+#ifdef LIBMUDFLAPTH
+extern enum __mf_state_enum *__mf_state_perthread ();
+#define __mf_state (* __mf_state_perthread ())
+#else
+extern enum __mf_state_enum __mf_state;
+#endif
+extern int __mf_starting_p;
+
+extern struct __mf_options __mf_opts;
+
+/* ------------------------------------------------------------------------ */
+/* Utility macros. */
+/* ------------------------------------------------------------------------ */
+
+#define UNLIKELY(e) (__builtin_expect (!!(e), 0))
+#define LIKELY(e) (__builtin_expect (!!(e), 1))
+#define STRINGIFY2(e) #e
+#define STRINGIFY(e) STRINGIFY2(e)
+
+#ifdef LIBMUDFLAPTH
+#define VERBOSE_TRACE(...) \
+ do { if (UNLIKELY (__mf_opts.verbose_trace)) { \
+ fprintf (stderr, "mf(%u): ", (unsigned) pthread_self ()); \
+ fprintf (stderr, __VA_ARGS__); \
+ } } while (0)
+#define TRACE(...) \
+ do { if (UNLIKELY (__mf_opts.trace_mf_calls)) { \
+ fprintf (stderr, "mf(%u): ", (unsigned) pthread_self ()); \
+ fprintf (stderr, __VA_ARGS__); \
+ } } while (0)
+#else
+#define VERBOSE_TRACE(...) \
+ do { if (UNLIKELY (__mf_opts.verbose_trace)) { \
+ fprintf (stderr, "mf: "); \
+ fprintf (stderr, __VA_ARGS__); \
+ } } while (0)
+#define TRACE(...) \
+ do { if (UNLIKELY (__mf_opts.trace_mf_calls)) { \
+ fprintf (stderr, "mf: "); \
+ fprintf (stderr, __VA_ARGS__); \
+ } } while (0)
+#endif
+
+
+#define __MF_PERSIST_MAX 256
+#define __MF_FREEQ_MAX 256
+
+/*
+ Wrapping and redirection:
+
+ Mudflap redirects a number of libc functions into itself, for "cheap"
+ verification (eg. strcpy, bzero, memcpy) and also to register /
+ unregister regions of memory as they are manipulated by the program
+ (eg. malloc/free, mmap/munmap).
+
+ There are two methods of wrapping.
+
+ (1) The static method involves a list of -wrap=foo flags being passed to
+ the linker, which then links references to "foo" to the symbol
+ "__wrap_foo", and links references to "__real_foo" to the symbol "foo".
+ When compiled without -DPIC, libmudflap.a contains such __wrap_foo
+ functions which delegate to __real_foo functions in libc to get their
+ work done.
+
+ (2) The dynamic method involves providing a definition of symbol foo in
+ libmudflap.so and linking it earlier in the compiler command line,
+ before libc.so. The function "foo" in libmudflap must then call
+ dlsym(RTLD_NEXT, "foo") to acquire a pointer to the "real" libc foo, or
+ at least the "next" foo in the dynamic link resolution order.
+
+ We switch between these two techniques by the presence of the -DPIC
+ #define passed in by libtool when building libmudflap.
+*/
+
+
+#ifdef PIC
+
+extern void __mf_resolve_single_dynamic (struct __mf_dynamic_entry *);
+
+#define _GNU_SOURCE
+#include <dlfcn.h>
+
+#define WRAPPER(ret, fname, ...) \
+ret __wrap_ ## fname (__VA_ARGS__) \
+ __attribute__ (( alias (#fname) )); \
+ret __real_ ## fname (__VA_ARGS__) \
+ __attribute__ (( alias (#fname) )); \
+ret fname (__VA_ARGS__)
+#define DECLARE(ty, fname, ...) \
+ typedef ty (*__mf_fn_ ## fname) (__VA_ARGS__); \
+ extern ty __mf_0fn_ ## fname (__VA_ARGS__);
+#define CALL_REAL(fname, ...) \
+ ({__mf_starting_p \
+ ? __mf_0fn_ ## fname (__VA_ARGS__) \
+ : (__mf_resolve_single_dynamic (& __mf_dynamic[dyn_ ## fname]), \
+ (((__mf_fn_ ## fname)(__mf_dynamic[dyn_ ## fname].pointer)) (__VA_ARGS__)));})
+#define CALL_BACKUP(fname, ...) \
+ __mf_0fn_ ## fname(__VA_ARGS__)
+
+#else /* not PIC --> static library */
+
+#define WRAPPER(ret, fname, ...) \
+ret __wrap_ ## fname (__VA_ARGS__)
+#define DECLARE(ty, fname, ...) \
+ extern ty __real_ ## fname (__VA_ARGS__)
+#define CALL_REAL(fname, ...) \
+ __real_ ## fname (__VA_ARGS__)
+#define CALL_BACKUP(fname, ...) \
+ __real_ ## fname(__VA_ARGS__)
+
+#endif /* PIC */
+
+/* WRAPPER2 is for functions intercepted via macros at compile time. */
+#define WRAPPER2(ret, fname, ...) \
+ret __mfwrap_ ## fname (__VA_ARGS__)
+
+
+/* Utility macros for mf-hooks*.c */
+
+#define MF_VALIDATE_EXTENT(value,size,acc,context) \
+ do { \
+ if (UNLIKELY (size > 0 && __MF_CACHE_MISS_P (value, size))) \
+ __mf_check ((void *) (value), (size), acc, "(" context ")"); \
+ } while (0)
+#define BEGIN_PROTECT(fname, ...) \
+ if (UNLIKELY (__mf_starting_p)) \
+ { \
+ return CALL_BACKUP(fname, __VA_ARGS__); \
+ } \
+ else if (UNLIKELY (__mf_state == reentrant)) \
+ { \
+ extern unsigned long __mf_reentrancy; \
+ if (UNLIKELY (__mf_opts.verbose_trace)) { \
+ write (2, "mf: reentrancy detected in `", 28); \
+ write (2, __PRETTY_FUNCTION__, strlen(__PRETTY_FUNCTION__)); \
+ write (2, "'\n", 2); } \
+ __mf_reentrancy ++; \
+ return CALL_REAL(fname, __VA_ARGS__); \
+ } \
+ else \
+ { \
+ TRACE ("%s\n", __PRETTY_FUNCTION__); \
+ }
+
+
+/* Unlocked variants of main entry points from mf-runtime.h. */
+extern void __mfu_check (void *ptr, size_t sz, int type, const char *location);
+extern void __mfu_register (void *ptr, size_t sz, int type, const char *name);
+extern void __mfu_unregister (void *ptr, size_t sz);
+extern void __mfu_report ();
+extern int __mfu_set_options (const char *opts);
+
+
+#endif /* __MF_IMPL_H */
diff --git a/libmudflap/mf-runtime.c b/libmudflap/mf-runtime.c
new file mode 100644
index 00000000000..88a3682081c
--- /dev/null
+++ b/libmudflap/mf-runtime.c
@@ -0,0 +1,2431 @@
+/* Mudflap: narrow-pointer bounds-checking by tree rewriting.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Frank Ch. Eigler <fche@redhat.com>
+ and Graydon Hoare <graydon@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+
+/* These attempt to coax various unix flavours to declare all our
+ needed tidbits in the system headers. */
+#if !defined(__FreeBSD__)
+#define _POSIX_SOURCE
+#endif /* Some BSDs break <sys/socket.h> if this is defined. */
+#define _GNU_SOURCE
+#define _XOPEN_SOURCE
+#define _BSD_TYPES
+#define __EXTENSIONS__
+#define _ALL_SOURCE
+#define _LARGE_FILE_API
+#define _XOPEN_SOURCE_EXTENDED 1
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+#ifdef HAVE_EXECINFO_H
+#include <execinfo.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#include <assert.h>
+
+#include <string.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <errno.h>
+
+#include "mf-runtime.h"
+#include "mf-impl.h"
+
+
+/* ------------------------------------------------------------------------ */
+/* Utility macros */
+
+#define CTOR __attribute__ ((constructor))
+#define DTOR __attribute__ ((destructor))
+
+
+/* Codes to describe the context in which a violation occurs. */
+#define __MF_VIOL_UNKNOWN 0
+#define __MF_VIOL_READ 1
+#define __MF_VIOL_WRITE 2
+#define __MF_VIOL_REGISTER 3
+#define __MF_VIOL_UNREGISTER 4
+#define __MF_VIOL_WATCH 5
+
+/* Protect against recursive calls. */
+#define BEGIN_RECURSION_PROTECT() do { \
+ if (UNLIKELY (__mf_state == reentrant)) { \
+ write (2, "mf: erroneous reentrancy detected in `", 38); \
+ write (2, __PRETTY_FUNCTION__, strlen(__PRETTY_FUNCTION__)); \
+ write (2, "'\n", 2); \
+ abort (); } \
+ __mf_state = reentrant; \
+ } while (0)
+
+#define END_RECURSION_PROTECT() do { \
+ __mf_state = active; \
+ } while (0)
+
+
+
+/* ------------------------------------------------------------------------ */
+/* Required globals. */
+
+#define LOOKUP_CACHE_MASK_DFL 1023
+#define LOOKUP_CACHE_SIZE_MAX 4096 /* Allows max CACHE_MASK 0x0FFF */
+#define LOOKUP_CACHE_SHIFT_DFL 2
+
+struct __mf_cache __mf_lookup_cache [LOOKUP_CACHE_SIZE_MAX];
+uintptr_t __mf_lc_mask = LOOKUP_CACHE_MASK_DFL;
+unsigned char __mf_lc_shift = LOOKUP_CACHE_SHIFT_DFL;
+#define LOOKUP_CACHE_SIZE (__mf_lc_mask + 1)
+
+struct __mf_options __mf_opts;
+
+int __mf_starting_p = 1;
+#ifndef LIBMUDFLAPTH
+enum __mf_state_enum __mf_state = active;
+#else
+/* See __mf_state_perthread() in mf-hooks.c. */
+#endif
+
+
+#ifdef LIBMUDFLAPTH
+pthread_mutex_t __mf_biglock =
+#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
+ PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
+#else
+ PTHREAD_MUTEX_INITIALIZER;
+#endif
+#endif
+
+/* Use HAVE_PTHREAD_H here instead of LIBMUDFLAPTH, so that even
+ the libmudflap.la (no threading support) can diagnose whether
+ the application is linked with -lpthread. See __mf_usage() below. */
+#if HAVE_PTHREAD_H
+#pragma weak pthread_join
+const void *threads_active_p = (void *) pthread_join;
+#endif
+
+
+/* ------------------------------------------------------------------------ */
+/* stats-related globals. */
+
+static unsigned long __mf_count_check;
+static unsigned long __mf_lookup_cache_reusecount [LOOKUP_CACHE_SIZE_MAX];
+static unsigned long __mf_treerot_left, __mf_treerot_right;
+static unsigned long __mf_count_register;
+static unsigned long __mf_total_register_size [__MF_TYPE_MAX+1];
+static unsigned long __mf_count_unregister;
+static unsigned long __mf_total_unregister_size;
+static unsigned long __mf_count_violation [__MF_VIOL_WATCH+1];
+static unsigned long __mf_sigusr1_received;
+static unsigned long __mf_sigusr1_handled;
+/* not static */ unsigned long __mf_reentrancy;
+#ifdef LIBMUDFLAPTH
+/* not static */ unsigned long __mf_lock_contention;
+#endif
+
+
+/* ------------------------------------------------------------------------ */
+/* mode-check-related globals. */
+
+typedef struct __mf_object
+{
+ uintptr_t low, high; /* __mf_register parameters */
+ const char *name;
+ char type; /* __MF_TYPE_something */
+ char watching_p; /* Trigger a VIOL_WATCH on access? */
+ unsigned read_count; /* Number of times __mf_check/read was called on this object. */
+ unsigned write_count; /* Likewise for __mf_check/write. */
+ unsigned liveness; /* A measure of recent checking activity. */
+ unsigned description_epoch; /* Last epoch __mf_describe_object printed this. */
+
+ uintptr_t alloc_pc;
+ struct timeval alloc_time;
+ char **alloc_backtrace;
+ size_t alloc_backtrace_size;
+#ifdef LIBMUDFLAPTH
+ pthread_t alloc_thread;
+#endif
+
+ int deallocated_p;
+ uintptr_t dealloc_pc;
+ struct timeval dealloc_time;
+ char **dealloc_backtrace;
+ size_t dealloc_backtrace_size;
+#ifdef LIBMUDFLAPTH
+ pthread_t dealloc_thread;
+#endif
+} __mf_object_t;
+
+
+typedef struct __mf_object_tree
+{
+ __mf_object_t data;
+ struct __mf_object_tree *left;
+ struct __mf_object_tree *right;
+} __mf_object_tree_t;
+
+/* Live objects: binary tree on __mf_object_t.low */
+static __mf_object_tree_t *__mf_object_root;
+
+/* Dead objects: circular arrays; _MIN_CEM .. _MAX_CEM only */
+static unsigned __mf_object_dead_head[__MF_TYPE_MAX_CEM+1]; /* next empty spot */
+static __mf_object_tree_t *__mf_object_cemetary[__MF_TYPE_MAX_CEM+1][__MF_PERSIST_MAX];
+
+
+/* ------------------------------------------------------------------------ */
+/* Forward function declarations */
+
+static void __mf_init () CTOR;
+static void __mf_sigusr1_respond ();
+static unsigned __mf_find_objects (uintptr_t ptr_low, uintptr_t ptr_high,
+ __mf_object_tree_t **objs, unsigned max_objs);
+static unsigned __mf_find_dead_objects (uintptr_t ptr_low, uintptr_t ptr_high,
+ __mf_object_tree_t **objs, unsigned max_objs);
+static void __mf_link_object (__mf_object_tree_t *obj);
+static void __mf_age_tree (__mf_object_tree_t *obj);
+static void __mf_adapt_cache ();
+static void __mf_unlink_object (__mf_object_tree_t *obj);
+static void __mf_describe_object (__mf_object_t *obj);
+static unsigned __mf_watch_or_not (void *ptr, size_t sz, char flag);
+
+
+
+/* ------------------------------------------------------------------------ */
+/* Configuration engine */
+
+static void
+__mf_set_default_options ()
+{
+ memset (& __mf_opts, 0, sizeof (__mf_opts));
+
+ __mf_opts.tree_aging = 13037;
+ __mf_opts.adapt_cache = 1000003;
+ __mf_opts.abbreviate = 1;
+ __mf_opts.verbose_violations = 1;
+ __mf_opts.free_queue_length = 4;
+ __mf_opts.persistent_count = 100;
+ __mf_opts.crumple_zone = 32;
+ __mf_opts.backtrace = 4;
+ __mf_opts.mudflap_mode = mode_check;
+ __mf_opts.violation_mode = viol_nop;
+ __mf_opts.heur_std_data = 1;
+#ifdef LIBMUDFLAPTH
+ __mf_opts.thread_stack = 0;
+#endif
+}
+
+static struct option
+{
+ char *name;
+ char *description;
+ enum
+ {
+ set_option,
+ read_integer_option,
+ } type;
+ int value;
+ int *target;
+}
+options [] =
+ {
+ {"mode-nop",
+ "mudflaps do nothing",
+ set_option, (int)mode_nop, (int *)&__mf_opts.mudflap_mode},
+ {"mode-populate",
+ "mudflaps populate object tree",
+ set_option, (int)mode_populate, (int *)&__mf_opts.mudflap_mode},
+ {"mode-check",
+ "mudflaps check for memory violations",
+ set_option, (int)mode_check, (int *)&__mf_opts.mudflap_mode},
+ {"mode-violate",
+ "mudflaps always cause violations (diagnostic)",
+ set_option, (int)mode_violate, (int *)&__mf_opts.mudflap_mode},
+
+ {"viol-nop",
+ "violations do not change program execution",
+ set_option, (int)viol_nop, (int *)&__mf_opts.violation_mode},
+ {"viol-abort",
+ "violations cause a call to abort()",
+ set_option, (int)viol_abort, (int *)&__mf_opts.violation_mode},
+ {"viol-segv",
+ "violations are promoted to SIGSEGV signals",
+ set_option, (int)viol_segv, (int *)&__mf_opts.violation_mode},
+ {"viol-gdb",
+ "violations fork a gdb process attached to current program",
+ set_option, (int)viol_gdb, (int *)&__mf_opts.violation_mode},
+ {"trace-calls",
+ "trace calls to mudflap runtime library",
+ set_option, 1, &__mf_opts.trace_mf_calls},
+ {"verbose-trace",
+ "trace internal events within mudflap runtime library",
+ set_option, 1, &__mf_opts.verbose_trace},
+ {"collect-stats",
+ "collect statistics on mudflap's operation",
+ set_option, 1, &__mf_opts.collect_stats},
+#if HAVE_SIGNAL
+ {"sigusr1-report",
+ "print report upon SIGUSR1",
+ set_option, 1, &__mf_opts.sigusr1_report},
+#endif
+ {"internal-checking",
+ "perform more expensive internal checking",
+ set_option, 1, &__mf_opts.internal_checking},
+ {"age-tree",
+ "age the object tree after N accesses for working set",
+ read_integer_option, 1000000, &__mf_opts.tree_aging},
+ {"print-leaks",
+ "print any memory leaks at program shutdown",
+ set_option, 1, &__mf_opts.print_leaks},
+ {"check-initialization",
+ "detect uninitialized object reads",
+ set_option, 1, &__mf_opts.check_initialization},
+ {"verbose-violations",
+ "print verbose messages when memory violations occur",
+ set_option, 1, &__mf_opts.verbose_violations},
+ {"abbreviate",
+ "abbreviate repetitive listings",
+ set_option, 1, &__mf_opts.abbreviate},
+ {"wipe-stack",
+ "wipe stack objects at unwind",
+ set_option, 1, &__mf_opts.wipe_stack},
+ {"wipe-heap",
+ "wipe heap objects at free",
+ set_option, 1, &__mf_opts.wipe_heap},
+ {"heur-proc-map",
+ "support /proc/self/map heuristics",
+ set_option, 1, &__mf_opts.heur_proc_map},
+ {"heur-stack-bound",
+ "enable a simple upper stack bound heuristic",
+ set_option, 1, &__mf_opts.heur_stack_bound},
+ {"heur-start-end",
+ "support _start.._end heuristics",
+ set_option, 1, &__mf_opts.heur_start_end},
+ {"heur-stdlib",
+ "register standard library data (argv, errno, stdin, ...)",
+ set_option, 1, &__mf_opts.heur_std_data},
+ {"free-queue-length",
+ "queue N deferred free() calls before performing them",
+ read_integer_option, 0, &__mf_opts.free_queue_length},
+ {"persistent-count",
+ "keep a history of N unregistered regions",
+ read_integer_option, 0, &__mf_opts.persistent_count},
+ {"crumple-zone",
+ "surround allocations with crumple zones of N bytes",
+ read_integer_option, 0, &__mf_opts.crumple_zone},
+ /* XXX: not type-safe.
+ {"lc-mask",
+ "set lookup cache size mask to N (2**M - 1)",
+ read_integer_option, 0, (int *)(&__mf_lc_mask)},
+ {"lc-shift",
+ "set lookup cache pointer shift",
+ read_integer_option, 0, (int *)(&__mf_lc_shift)},
+ */
+ {"lc-adapt",
+ "adapt mask/shift parameters after N cache misses",
+ read_integer_option, 1, &__mf_opts.adapt_cache},
+ {"backtrace",
+ "keep an N-level stack trace of each call context",
+ read_integer_option, 0, &__mf_opts.backtrace},
+#ifdef LIBMUDFLAPTH
+ {"thread-stack",
+ "override thread stacks allocation: N kB",
+ read_integer_option, 0, &__mf_opts.thread_stack},
+#endif
+ {0, 0, set_option, 0, NULL}
+ };
+
+static void
+__mf_usage ()
+{
+ struct option *opt;
+
+ fprintf (stderr,
+ "This is a %s%sGCC \"mudflap\" memory-checked binary.\n"
+ "Mudflap is Copyright (C) 2002-2003 Free Software Foundation, Inc.\n"
+ "\n"
+ "The mudflap code can be controlled by an environment variable:\n"
+ "\n"
+ "$ export MUDFLAP_OPTIONS='<options>'\n"
+ "$ <mudflapped_program>\n"
+ "\n"
+ "where <options> is a space-separated list of \n"
+ "any of the following options. Use `-no-OPTION' to disable options.\n"
+ "\n",
+#if HAVE_PTHREAD_H
+ (threads_active_p ? "multi-threaded " : "single-threaded "),
+#else
+ "",
+#endif
+#if LIBMUDFLAPTH
+ "thread-aware "
+#else
+ "thread-unaware "
+#endif
+ );
+ /* XXX: The multi-threaded thread-unaware combination is bad. */
+
+ for (opt = options; opt->name; opt++)
+ {
+ int default_p = (opt->value == * opt->target);
+
+ switch (opt->type)
+ {
+ char buf[128];
+ case set_option:
+ fprintf (stderr, "-%-23.23s %s", opt->name, opt->description);
+ if (default_p)
+ fprintf (stderr, " [active]\n");
+ else
+ fprintf (stderr, "\n");
+ break;
+ case read_integer_option:
+ strncpy (buf, opt->name, 128);
+ strncpy (buf + strlen (opt->name), "=N", 2);
+ fprintf (stderr, "-%-23.23s %s", buf, opt->description);
+ fprintf (stderr, " [%d]\n", * opt->target);
+ break;
+ default: abort();
+ }
+ }
+
+ fprintf (stderr, "\n");
+}
+
+
+int
+__mf_set_options (const char *optstr)
+{
+ int rc;
+ LOCKTH ();
+ BEGIN_RECURSION_PROTECT ();
+ rc = __mfu_set_options (optstr);
+ /* XXX: It's not really that easy. A change to a bunch of parameters
+ can require updating auxiliary state or risk crashing:
+ free_queue_length, crumple_zone ... */
+ END_RECURSION_PROTECT ();
+ UNLOCKTH ();
+ return rc;
+}
+
+
+int
+__mfu_set_options (const char *optstr)
+{
+ struct option *opts = 0;
+ char *nxt = 0;
+ long tmp = 0;
+ int rc = 0;
+ const char *saved_optstr = optstr;
+
+ /* XXX: bounds-check for optstr! */
+
+ while (*optstr)
+ {
+ switch (*optstr) {
+ case ' ':
+ case '\t':
+ case '\n':
+ optstr++;
+ break;
+
+ case '-':
+ if (*optstr+1)
+ {
+ int negate = 0;
+ optstr++;
+
+ if (*optstr == '?' ||
+ strncmp (optstr, "help", 4) == 0)
+ {
+ /* Caller will print help and exit. */
+ return -1;
+ }
+
+ if (strncmp (optstr, "no-", 3) == 0)
+ {
+ negate = 1;
+ optstr = & optstr[3];
+ }
+
+ for (opts = options; opts->name; opts++)
+ {
+ if (strncmp (optstr, opts->name, strlen (opts->name)) == 0)
+ {
+ optstr += strlen (opts->name);
+ assert (opts->target);
+ switch (opts->type)
+ {
+ case set_option:
+ if (negate)
+ *(opts->target) = 0;
+ else
+ *(opts->target) = opts->value;
+ break;
+ case read_integer_option:
+ if (! negate && (*optstr == '=' && *(optstr+1)))
+ {
+ optstr++;
+ tmp = strtol (optstr, &nxt, 10);
+ if ((optstr != nxt) && (tmp != LONG_MAX))
+ {
+ optstr = nxt;
+ *(opts->target) = (int)tmp;
+ }
+ }
+ else if (negate)
+ * opts->target = 0;
+ break;
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ fprintf (stderr,
+ "warning: unrecognized string '%s' in mudflap options\n",
+ optstr);
+ optstr += strlen (optstr);
+ rc = -1;
+ break;
+ }
+ }
+
+ /* Special post-processing: bound __mf_lc_mask and free_queue_length for security. */
+ __mf_lc_mask &= (LOOKUP_CACHE_SIZE_MAX - 1);
+ __mf_opts.free_queue_length &= (__MF_FREEQ_MAX - 1);
+
+ /* Clear the lookup cache, in case the parameters got changed. */
+ /* XXX: race */
+ memset (__mf_lookup_cache, 0, sizeof(__mf_lookup_cache));
+ /* void slot 0 */
+ __mf_lookup_cache[0].low = MAXPTR;
+
+ TRACE ("set options from `%s'\n", saved_optstr);
+
+ /* Call this unconditionally, in case -sigusr1-report was toggled. */
+ __mf_sigusr1_respond ();
+
+ return rc;
+}
+
+
+#ifdef PIC
+
+void
+__mf_resolve_single_dynamic (struct __mf_dynamic_entry *e)
+{
+ char *err;
+
+ assert (e);
+ if (e->pointer) return;
+
+#if HAVE_DLVSYM
+ if (e->version != NULL && e->version[0] != '\0') /* non-null/empty */
+ e->pointer = dlvsym (RTLD_NEXT, e->name, e->version);
+ else
+#endif
+ e->pointer = dlsym (RTLD_NEXT, e->name);
+
+ err = dlerror ();
+
+ if (err)
+ {
+ fprintf (stderr, "mf: error in dlsym(\"%s\"): %s\n",
+ e->name, err);
+ abort ();
+ }
+ if (! e->pointer)
+ {
+ fprintf (stderr, "mf: dlsym(\"%s\") = NULL\n", e->name);
+ abort ();
+ }
+}
+
+
+static void
+__mf_resolve_dynamics ()
+{
+ int i;
+ for (i = 0; i < dyn_INITRESOLVE; i++)
+ __mf_resolve_single_dynamic (& __mf_dynamic[i]);
+}
+
+
+/* NB: order must match enums in mf-impl.h */
+struct __mf_dynamic_entry __mf_dynamic [] =
+{
+ {NULL, "calloc", NULL},
+ {NULL, "free", NULL},
+ {NULL, "malloc", NULL},
+ {NULL, "mmap", NULL},
+ {NULL, "munmap", NULL},
+ {NULL, "realloc", NULL},
+ {NULL, "DUMMY", NULL}, /* dyn_INITRESOLVE */
+#ifdef LIBMUDFLAPTH
+ {NULL, "pthread_create", PTHREAD_CREATE_VERSION},
+ {NULL, "pthread_join", NULL},
+ {NULL, "pthread_exit", NULL}
+#endif
+};
+
+#endif /* PIC */
+
+
+
+/* ------------------------------------------------------------------------ */
+
+
+void __mf_init ()
+{
+ char *ov = 0;
+
+ /* This initial bootstrap phase requires that __mf_starting_p = 1. */
+#ifdef PIC
+ __mf_resolve_dynamics ();
+#endif
+ __mf_starting_p = 0;
+
+ __mf_set_default_options ();
+
+ ov = getenv ("MUDFLAP_OPTIONS");
+ if (ov)
+ {
+ int rc = __mfu_set_options (ov);
+ if (rc < 0)
+ {
+ __mf_usage ();
+ exit (1);
+ }
+ }
+
+ /* Initialize to a non-zero description epoch. */
+ __mf_describe_object (NULL);
+
+#define REG_RESERVED(obj) \
+ __mf_register (& obj, sizeof(obj), __MF_TYPE_NOACCESS, # obj)
+
+ REG_RESERVED (__mf_lookup_cache);
+ REG_RESERVED (__mf_lc_mask);
+ REG_RESERVED (__mf_lc_shift);
+ /* XXX: others of our statics? */
+
+ /* Prevent access to *NULL. */
+ __mf_register (MINPTR, 1, __MF_TYPE_NOACCESS, "NULL");
+ __mf_lookup_cache[0].low = (uintptr_t) -1;
+}
+
+
+
+int
+__wrap_main (int argc, char* argv[])
+{
+ extern char **environ;
+ extern int main ();
+ static int been_here = 0;
+
+ if (__mf_opts.heur_std_data && ! been_here)
+ {
+ unsigned i;
+
+ been_here = 1;
+ __mf_register (argv, sizeof(char *)*(argc+1), __MF_TYPE_STATIC, "argv[]");
+ for (i=0; i<argc; i++)
+ {
+ unsigned j = strlen (argv[i]);
+ __mf_register (argv[i], j+1, __MF_TYPE_STATIC, "argv element");
+ }
+
+ for (i=0; ; i++)
+ {
+ char *e = environ[i];
+ unsigned j;
+ if (e == NULL) break;
+ j = strlen (environ[i]);
+ __mf_register (environ[i], j+1, __MF_TYPE_STATIC, "environ element");
+ }
+ __mf_register (environ, sizeof(char *)*(i+1), __MF_TYPE_STATIC, "environ[]");
+
+ __mf_register (& errno, sizeof (errno), __MF_TYPE_STATIC, "errno area");
+
+ __mf_register (stdin, sizeof (*stdin), __MF_TYPE_STATIC, "stdin");
+ __mf_register (stdout, sizeof (*stdout), __MF_TYPE_STATIC, "stdout");
+ __mf_register (stderr, sizeof (*stderr), __MF_TYPE_STATIC, "stderr");
+ }
+
+#ifdef PIC
+ return main (argc, argv, environ);
+#else
+ return __real_main (argc, argv, environ);
+#endif
+}
+
+
+
+extern void __mf_fini () DTOR;
+void __mf_fini ()
+{
+ TRACE ("__mf_fini\n");
+ __mfu_report ();
+}
+
+
+
+/* ------------------------------------------------------------------------ */
+/* __mf_check */
+
+void __mf_check (void *ptr, size_t sz, int type, const char *location)
+{
+ LOCKTH ();
+ BEGIN_RECURSION_PROTECT ();
+ __mfu_check (ptr, sz, type, location);
+ END_RECURSION_PROTECT ();
+ UNLOCKTH ();
+}
+
+
+void __mfu_check (void *ptr, size_t sz, int type, const char *location)
+{
+ unsigned entry_idx = __MF_CACHE_INDEX (ptr);
+ struct __mf_cache *entry = & __mf_lookup_cache [entry_idx];
+ int judgement = 0; /* 0=undecided; <0=violation; >0=okay */
+ uintptr_t ptr_low = (uintptr_t) ptr;
+ uintptr_t ptr_high = CLAMPSZ (ptr, sz);
+ struct __mf_cache old_entry = *entry;
+
+ if (UNLIKELY (__mf_opts.sigusr1_report))
+ __mf_sigusr1_respond ();
+
+ TRACE ("check ptr=%p b=%u size=%lu %s location=`%s'\n",
+ ptr, entry_idx, (unsigned long)sz,
+ (type == 0 ? "read" : "write"), location);
+
+ switch (__mf_opts.mudflap_mode)
+ {
+ case mode_nop:
+ judgement = 1;
+ break;
+
+ case mode_populate:
+ entry->low = ptr_low;
+ entry->high = ptr_high;
+ judgement = 1;
+ break;
+
+ case mode_check:
+ {
+ unsigned heuristics = 0;
+
+ /* Advance aging/adaptation counters. */
+ if (__mf_object_root)
+ {
+ static unsigned aging_count;
+ static unsigned adapt_count;
+ aging_count ++;
+ adapt_count ++;
+ if (UNLIKELY (__mf_opts.tree_aging > 0 &&
+ aging_count > __mf_opts.tree_aging))
+ {
+ aging_count = 0;
+ __mf_age_tree (__mf_object_root);
+ }
+ if (UNLIKELY (__mf_opts.adapt_cache > 0 &&
+ adapt_count > __mf_opts.adapt_cache))
+ {
+ adapt_count = 0;
+ __mf_adapt_cache ();
+ }
+ }
+
+ /* Looping only occurs if heuristics were triggered. */
+ while (judgement == 0)
+ {
+ __mf_object_tree_t* ovr_obj[1];
+ unsigned obj_count;
+
+ obj_count = __mf_find_objects (ptr_low, ptr_high, ovr_obj, 1);
+
+ if (LIKELY (obj_count == 1)) /* A single hit! */
+ {
+ __mf_object_t *obj = & ovr_obj[0]->data;
+ assert (obj != NULL);
+ if (LIKELY (ptr_low >= obj->low && ptr_high <= obj->high))
+ {
+ /* XXX: hope for no overflow! */
+ if (type == __MF_CHECK_READ)
+ obj->read_count ++;
+ else
+ obj->write_count ++;
+
+ obj->liveness ++;
+
+ if (UNLIKELY (obj->type == __MF_TYPE_NOACCESS))
+ judgement = -1;
+ else if (UNLIKELY (obj->watching_p))
+ judgement = -2; /* trigger VIOL_WATCH */
+ else if (UNLIKELY (__mf_opts.check_initialization
+ /* reading */
+ && type == __MF_CHECK_READ
+ /* not written */
+ && obj->write_count == 0
+ /* uninitialized (heap) */
+ && obj->type == __MF_TYPE_HEAP))
+ judgement = -1;
+ else
+ {
+ /* Valid access. */
+ entry->low = obj->low;
+ entry->high = obj->high;
+ judgement = 1;
+ }
+ }
+ /* The object did not cover the entire accessed region. */
+ }
+ else if (LIKELY (obj_count > 1))
+ {
+ __mf_object_tree_t **all_ovr_objs;
+ unsigned n;
+ DECLARE (void *, malloc, size_t c);
+ DECLARE (void, free, void *p);
+
+ all_ovr_objs = CALL_REAL (malloc, (sizeof (__mf_object_tree_t *) *
+ obj_count));
+ if (all_ovr_objs == NULL) abort ();
+ n = __mf_find_objects (ptr_low, ptr_high, all_ovr_objs, obj_count);
+ assert (n == obj_count);
+
+ /* Confirm that accessed range is covered by first/last object. */
+ if (LIKELY ((ptr_low >= all_ovr_objs[0]->data.low) &&
+ (ptr_high <= all_ovr_objs[obj_count-1]->data.high)))
+ {
+ /* Presume valid access. */
+ judgement = 1;
+
+ /* Confirm that intermediate objects are
+ contiguous and share a single name. Thus they
+ are likely split up GUESS regions, or mmap
+ pages. The idea of the name check is to
+ prevent an oversize access to a
+ stack-registered object (followed by some GUESS
+ type) from being accepted as a hit. */
+ for (n=0; n<obj_count-1; n++)
+ {
+ __mf_object_t *obj = & (all_ovr_objs[n]->data);
+ __mf_object_t *nextobj = & (all_ovr_objs[n+1]->data);
+
+ if (UNLIKELY (obj->type == __MF_TYPE_NOACCESS))
+ judgement = -1; /* Force error. */
+
+ if (UNLIKELY (judgement == 1 &&
+ (obj->high + 1 != nextobj->low)))
+ judgement = 0; /* Cancel presumption. */
+
+ if (UNLIKELY (judgement == 1 &&
+ (obj->name != nextobj->name)))
+ judgement = 0; /* Cancel presumption. */
+ /* NB: strcmp above is not necessary since the
+ same literal string pointer is normally
+ used when creating regions. */
+
+ /* XXX: hope for no overflow! */
+ if (type == __MF_CHECK_READ)
+ obj->read_count ++;
+ else
+ obj->write_count ++;
+ obj->liveness ++;
+ }
+
+ /* If the access is otherwise successful, check whether
+ any of the covered objects are being watched. */
+ if (judgement > 0)
+ {
+ unsigned i;
+ for (i=0; i<obj_count; i++)
+ if (all_ovr_objs[i]->data.watching_p)
+ judgement = -2; /* trigger VIOL_WATCH */
+ }
+
+ /* Check for uninitialized reads. */
+ if (judgement > 0 &&
+ __mf_opts.check_initialization &&
+ type == __MF_CHECK_READ)
+ {
+ unsigned i;
+ unsigned written_count = 0;
+
+ for (i=0; i<obj_count; i++)
+ {
+ __mf_object_t *obj = & all_ovr_objs[i]->data;
+
+ if (obj->write_count
+ || obj->type == __MF_TYPE_HEAP_I
+ || obj->type == __MF_TYPE_GUESS)
+ written_count ++;
+ }
+
+ /* Check for ALL pieces having been written-to.
+ XXX: should this be ANY instead? */
+ if (written_count != obj_count)
+ judgement = -1;
+ }
+
+ /* Fill out the cache with the bounds of the first
+ object and the last object that covers this
+ cache line (== includes the same __MF_CACHE_INDEX).
+ This could let this cache line span *two* distinct
+ registered objects: a peculiar but reasonable
+ situation. The cache line may not include the
+ entire object though. */
+ if (judgement > 0)
+ {
+ unsigned i;
+ entry->low = all_ovr_objs[0]->data.low;
+ for (i=0; i<obj_count; i++)
+ {
+ uintptr_t high = all_ovr_objs[i]->data.high;
+ if (__MF_CACHE_INDEX (high) == entry_idx)
+ entry->high = high;
+ }
+ }
+ }
+
+ CALL_REAL (free, all_ovr_objs);
+ }
+
+ if (judgement == 0)
+ {
+ if (heuristics++ < 2) /* XXX parametrize this number? */
+ judgement = __mf_heuristic_check (ptr_low, ptr_high);
+ else
+ judgement = -1;
+ }
+ }
+
+ }
+ break;
+
+ case mode_violate:
+ judgement = -1;
+ break;
+ }
+
+ if (__mf_opts.collect_stats)
+ {
+ __mf_count_check ++;
+
+ if (LIKELY (old_entry.low != entry->low || old_entry.high != entry->high))
+ /* && (old_entry.low != 0) && (old_entry.high != 0)) */
+ __mf_lookup_cache_reusecount [entry_idx] ++;
+ }
+
+ if (UNLIKELY (judgement < 0))
+ __mf_violation (ptr, sz,
+ (uintptr_t) __builtin_return_address (0), location,
+ ((judgement == -1) ?
+ (type == __MF_CHECK_READ ? __MF_VIOL_READ : __MF_VIOL_WRITE) :
+ __MF_VIOL_WATCH));
+}
+
+
+static __mf_object_tree_t *
+__mf_insert_new_object (uintptr_t low, uintptr_t high, int type,
+ const char *name, uintptr_t pc)
+{
+ DECLARE (void *, calloc, size_t c, size_t n);
+
+ __mf_object_tree_t *new_obj;
+ new_obj = CALL_REAL (calloc, 1, sizeof(__mf_object_tree_t));
+ new_obj->data.low = low;
+ new_obj->data.high = high;
+ new_obj->data.type = type;
+ new_obj->data.name = name;
+ new_obj->data.alloc_pc = pc;
+#if HAVE_GETTIMEOFDAY
+ gettimeofday (& new_obj->data.alloc_time, NULL);
+#endif
+#if LIBMUDFLAPTH
+ new_obj->data.alloc_thread = pthread_self ();
+#endif
+
+ if (__mf_opts.backtrace > 0 && (type == __MF_TYPE_HEAP || type == __MF_TYPE_HEAP_I))
+ new_obj->data.alloc_backtrace_size =
+ __mf_backtrace (& new_obj->data.alloc_backtrace,
+ (void *) pc, 2);
+
+ __mf_link_object (new_obj);
+ return new_obj;
+}
+
+
+static void
+__mf_uncache_object (__mf_object_t *old_obj)
+{
+ /* Remove any low/high pointers for this object from the lookup cache. */
+
+ /* Can it possibly exist in the cache? */
+ if (LIKELY (old_obj->read_count + old_obj->write_count))
+ {
+ uintptr_t low = old_obj->low;
+ uintptr_t high = old_obj->high;
+ unsigned idx_low = __MF_CACHE_INDEX (low);
+ unsigned idx_high = __MF_CACHE_INDEX (high);
+ unsigned i;
+ for (i = idx_low; i <= idx_high; i++)
+ {
+ struct __mf_cache *entry = & __mf_lookup_cache [i];
+ /* NB: the "||" in the following test permits this code to
+ tolerate the situation introduced by __mf_check over
+ contiguous objects, where a cache entry spans several
+ objects. */
+ if (entry->low == low || entry->high == high)
+ {
+ entry->low = MAXPTR;
+ entry->high = MINPTR;
+ }
+ }
+ }
+}
+
+
+void
+__mf_register (void *ptr, size_t sz, int type, const char *name)
+{
+ LOCKTH ();
+ BEGIN_RECURSION_PROTECT ();
+ __mfu_register (ptr, sz, type, name);
+ END_RECURSION_PROTECT ();
+ UNLOCKTH ();
+}
+
+
+void
+__mfu_register (void *ptr, size_t sz, int type, const char *name)
+{
+ TRACE ("register ptr=%p size=%lu type=%x name='%s'\n",
+ ptr, (unsigned long) sz, type, name ? name : "");
+
+ if (__mf_opts.collect_stats)
+ {
+ __mf_count_register ++;
+ __mf_total_register_size [(type < 0) ? 0 :
+ (type > __MF_TYPE_MAX) ? 0 :
+ type] += sz;
+ }
+
+ if (UNLIKELY (__mf_opts.sigusr1_report))
+ __mf_sigusr1_respond ();
+
+ switch (__mf_opts.mudflap_mode)
+ {
+ case mode_nop:
+ break;
+
+ case mode_violate:
+ __mf_violation (ptr, sz, (uintptr_t) __builtin_return_address (0), NULL,
+ __MF_VIOL_REGISTER);
+ break;
+
+ case mode_populate:
+ /* Clear the cache. */
+ /* XXX: why the entire cache? */
+ /* XXX: race */
+ memset (__mf_lookup_cache, 0, sizeof(__mf_lookup_cache));
+ /* void slot 0 */
+ __mf_lookup_cache[0].low = MAXPTR;
+ break;
+
+ case mode_check:
+ {
+ __mf_object_tree_t *ovr_objs [1];
+ unsigned num_overlapping_objs;
+ uintptr_t low = (uintptr_t) ptr;
+ uintptr_t high = CLAMPSZ (ptr, sz);
+ uintptr_t pc = (uintptr_t) __builtin_return_address (0);
+
+ /* Treat unknown size indication as 1. */
+ if (UNLIKELY (sz == 0)) sz = 1;
+
+ num_overlapping_objs = __mf_find_objects (low, high, ovr_objs, 1);
+
+ /* Handle overlaps. */
+ if (UNLIKELY (num_overlapping_objs > 0))
+ {
+ __mf_object_tree_t *ovr_obj = ovr_objs[0];
+
+ /* Quietly accept a single duplicate registration for
+ static objects, since these may come from distinct
+ compilation units. */
+ if (type == __MF_TYPE_STATIC
+ && ovr_obj->data.type == __MF_TYPE_STATIC
+ && ovr_obj->data.low == low
+ && ovr_obj->data.high == high)
+ {
+ /* do nothing */
+ VERBOSE_TRACE ("duplicate static reg %p-%p `%s'\n",
+ (void *) low, (void *) high,
+ (ovr_obj->data.name ? ovr_obj->data.name : ""));
+ break;
+ }
+
+ /* Quietly accept a single duplicate registration for
+ guess objects too. */
+ if (type == __MF_TYPE_GUESS &&
+ ovr_obj->data.type == __MF_TYPE_GUESS &&
+ ovr_obj->data.low == low &&
+ ovr_obj->data.high == high)
+ {
+ /* do nothing */
+ VERBOSE_TRACE ("duplicate guess reg %p-%p\n",
+ (void *) low, (void *) high);
+ break;
+ }
+
+ /* Quietly accept new a guess registration that overlaps
+ at least one existing object. Trim it down to size. */
+ else if (type == __MF_TYPE_GUESS)
+ {
+ /* We need to split this new GUESS region into some
+ smaller ones. Or we may not need to insert it at
+ all if it is covered by the overlapping region. */
+
+ /* First, identify all the overlapping objects. */
+ __mf_object_tree_t **all_ovr_objs;
+ unsigned num_ovr_objs, n;
+ uintptr_t next_low;
+ DECLARE (void *, malloc, size_t c);
+ DECLARE (void, free, void *p);
+
+ all_ovr_objs = CALL_REAL (malloc, (sizeof (__mf_object_tree_t *) *
+ num_overlapping_objs));
+ if (all_ovr_objs == NULL) abort ();
+ num_ovr_objs = __mf_find_objects (low, high, all_ovr_objs,
+ num_overlapping_objs);
+ assert (num_ovr_objs == num_overlapping_objs);
+
+ VERBOSE_TRACE ("splitting guess %p-%p, # overlaps: %u\n",
+ (void *) low, (void *) high, num_ovr_objs);
+
+ /* Add GUESS regions between the holes: before each
+ overlapping region. */
+
+ next_low = low;
+ /* This makes use of the assumption that __mf_find_objects() returns
+ overlapping objects in an increasing sequence. */
+ for (n=0; n < min (num_ovr_objs, num_overlapping_objs); n++)
+ {
+ if (all_ovr_objs[n]->data.low > next_low) /* Gap? */
+ {
+ uintptr_t next_high = CLAMPSUB (all_ovr_objs[n]->data.low, 1);
+ __mfu_register ((void *) next_low, next_high-next_low+1,
+ __MF_TYPE_GUESS, name);
+ }
+ next_low = CLAMPADD (all_ovr_objs[n]->data.high, 1);
+ }
+ /* Add in any leftover room at the top. */
+ if (next_low <= high)
+ __mfu_register ((void *) next_low, high-next_low+1,
+ __MF_TYPE_GUESS, name);
+
+ /* XXX: future optimization: allow consecutive GUESS regions to
+ be glued together. */
+ CALL_REAL (free, all_ovr_objs);
+ return;
+ }
+
+ /* Quietly accept a non-GUESS region overlaying a GUESS
+ region. Handle it by removing the GUESS region
+ temporarily, then recursively adding this new object,
+ and then the GUESS back. The latter will be split up
+ by the recursive process above. */
+ else if (ovr_obj->data.type == __MF_TYPE_GUESS)
+ {
+ uintptr_t old_low = ovr_obj->data.low;
+ uintptr_t old_high = ovr_obj->data.high;
+ const char* old_name = ovr_obj->data.name;
+
+ /* Now to recursively remove the guess piece, and
+ reinsert them in the opposite order. Recursion
+ should bottom out if another non-GUESS overlapping
+ region is found for this new object (resulting in a
+ violation), or if no further overlap occurs. The
+ located GUESS region should end up being split up
+ in any case. */
+ __mfu_unregister ((void *) old_low, old_high-old_low+1);
+ __mfu_register ((void *) low, sz, type, name);
+ __mfu_register ((void *) old_low, old_high-old_low+1,
+ __MF_TYPE_GUESS, old_name);
+ return;
+ }
+
+ /* Alas, a genuine violation. */
+ else
+ {
+ /* Two or more *real* mappings here. */
+ __mf_violation ((void *) ptr, sz,
+ (uintptr_t) __builtin_return_address (0), NULL,
+ __MF_VIOL_REGISTER);
+ }
+ }
+
+ /* No overlapping objects: AOK. */
+ else
+ {
+ __mf_insert_new_object (low, high, type, name, pc);
+ }
+
+ /* We could conceivably call __mf_check() here to prime the cache,
+ but then the read_count/write_count field is not reliable. */
+
+ break;
+ }
+ } /* end switch (__mf_opts.mudflap_mode) */
+}
+
+
+void
+__mf_unregister (void *ptr, size_t sz)
+{
+ LOCKTH ();
+ BEGIN_RECURSION_PROTECT ();
+ __mfu_unregister (ptr, sz);
+ END_RECURSION_PROTECT ();
+ UNLOCKTH ();
+}
+
+
+void
+__mfu_unregister (void *ptr, size_t sz)
+{
+ DECLARE (void, free, void *ptr);
+
+ if (UNLIKELY (__mf_opts.sigusr1_report))
+ __mf_sigusr1_respond ();
+
+ TRACE ("unregister ptr=%p size=%lu\n", ptr, (unsigned long) sz);
+
+ switch (__mf_opts.mudflap_mode)
+ {
+ case mode_nop:
+ break;
+
+ case mode_violate:
+ __mf_violation (ptr, sz,
+ (uintptr_t) __builtin_return_address (0), NULL,
+ __MF_VIOL_UNREGISTER);
+ break;
+
+ case mode_populate:
+ /* Clear the cache. */
+ /* XXX: race */
+ memset (__mf_lookup_cache, 0, sizeof(__mf_lookup_cache));
+ /* void slot 0 */
+ __mf_lookup_cache[0].low = MAXPTR;
+ break;
+
+ case mode_check:
+ {
+ __mf_object_tree_t *old_obj = NULL;
+ __mf_object_tree_t *del_obj = NULL; /* Object to actually delete. */
+ __mf_object_tree_t *objs[1] = {NULL};
+ unsigned num_overlapping_objs;
+
+ /* Treat unknown size indication as 1. */
+ if (sz == 0) sz = 1;
+
+ num_overlapping_objs = __mf_find_objects ((uintptr_t) ptr,
+ CLAMPSZ (ptr, sz), objs, 1);
+
+ /* XXX: handle unregistration of big old GUESS region, that has since
+ been splintered. */
+ old_obj = objs[0];
+
+ if (UNLIKELY (num_overlapping_objs != 1 ||
+ (uintptr_t)ptr != old_obj->data.low)) /* XXX: what about sz? */
+ {
+ __mf_violation (ptr, sz,
+ (uintptr_t) __builtin_return_address (0), NULL,
+ __MF_VIOL_UNREGISTER);
+ break;
+ }
+
+ __mf_unlink_object (old_obj);
+ __mf_uncache_object (& old_obj->data);
+
+ /* Wipe buffer contents if desired. */
+ if ((__mf_opts.wipe_stack && old_obj->data.type == __MF_TYPE_STACK)
+ || (__mf_opts.wipe_heap && (old_obj->data.type == __MF_TYPE_HEAP
+ || old_obj->data.type == __MF_TYPE_HEAP_I)))
+ {
+ memset ((void *) old_obj->data.low,
+ 0,
+ (size_t) (old_obj->data.high - old_obj->data.low + 1));
+ }
+
+ /* Manage the object cemetary. */
+ if (__mf_opts.persistent_count > 0 &&
+ old_obj->data.type >= 0 &&
+ old_obj->data.type <= __MF_TYPE_MAX_CEM)
+ {
+ old_obj->data.deallocated_p = 1;
+ old_obj->left = old_obj->right = NULL;
+ old_obj->data.dealloc_pc = (uintptr_t) __builtin_return_address (0);
+#if HAVE_GETTIMEOFDAY
+ gettimeofday (& old_obj->data.dealloc_time, NULL);
+#endif
+#ifdef LIBMUDFLAPTH
+ old_obj->data.dealloc_thread = pthread_self ();
+#endif
+
+ if (__mf_opts.backtrace > 0 && old_obj->data.type == __MF_TYPE_HEAP)
+ old_obj->data.dealloc_backtrace_size =
+ __mf_backtrace (& old_obj->data.dealloc_backtrace,
+ NULL, 2);
+
+ /* Encourage this object to be displayed again in current epoch. */
+ old_obj->data.description_epoch --;
+
+ /* Put this object into the cemetary. This may require this plot to
+ be recycled, and the previous resident to be designated del_obj. */
+ {
+ unsigned row = old_obj->data.type;
+ unsigned plot = __mf_object_dead_head [row];
+
+ del_obj = __mf_object_cemetary [row][plot];
+ __mf_object_cemetary [row][plot] = old_obj;
+ plot ++;
+ if (plot == __mf_opts.persistent_count) plot = 0;
+ __mf_object_dead_head [row] = plot;
+ }
+ }
+ else
+ del_obj = old_obj;
+
+ if (__mf_opts.print_leaks)
+ {
+ if ((old_obj->data.read_count + old_obj->data.write_count) == 0 &&
+ (old_obj->data.type == __MF_TYPE_HEAP
+ || old_obj->data.type == __MF_TYPE_HEAP_I))
+ {
+ fprintf (stderr,
+ "*******\n"
+ "mudflap warning: unaccessed registered object:\n");
+ __mf_describe_object (& old_obj->data);
+ }
+ }
+
+ if (del_obj != NULL) /* May or may not equal old_obj. */
+ {
+ if (__mf_opts.backtrace > 0)
+ {
+ CALL_REAL(free, del_obj->data.alloc_backtrace);
+ if (__mf_opts.persistent_count > 0)
+ {
+ CALL_REAL(free, del_obj->data.dealloc_backtrace);
+ }
+ }
+ CALL_REAL(free, del_obj);
+ }
+
+ break;
+ }
+ } /* end switch (__mf_opts.mudflap_mode) */
+
+
+ if (__mf_opts.collect_stats)
+ {
+ __mf_count_unregister ++;
+ __mf_total_unregister_size += sz;
+ }
+}
+
+/* ------------------------------------------------------------------------ */
+/* __mf_validate_live_object_tree, _object_cemetary */
+
+static void
+__mf_validate_live_object_tree (__mf_object_tree_t *obj)
+{
+ assert (obj != NULL);
+
+ if (__mf_opts.persistent_count > 0)
+ assert (! obj->data.deallocated_p);
+
+ if (obj->left)
+ {
+ assert (obj->left->data.high < obj->data.low);
+ __mf_validate_live_object_tree (obj->left);
+ }
+ if (obj->right)
+ {
+ assert (obj->right->data.low > obj->data.high);
+ __mf_validate_live_object_tree (obj->right);
+ }
+}
+
+static void
+__mf_validate_object_cemetary ()
+{
+ unsigned cls;
+ unsigned i;
+
+ for (cls = 0; cls <= __MF_TYPE_MAX_CEM; cls++)
+ {
+ assert (__mf_object_dead_head [cls] >= 0 &&
+ __mf_object_dead_head [cls] < __mf_opts.persistent_count);
+ for (i = 0; i < __mf_opts.persistent_count; i++)
+ {
+ __mf_object_tree_t *obj = __mf_object_cemetary [cls][i];
+ if (obj != NULL)
+ {
+ assert (obj->data.deallocated_p);
+ assert (obj->left == NULL);
+ assert (obj->right == NULL);
+ }
+ }
+ }
+}
+
+static void
+__mf_validate_objects ()
+{
+ if (__mf_object_root)
+ __mf_validate_live_object_tree (__mf_object_root);
+
+ if (__mf_opts.persistent_count > 0)
+ __mf_validate_object_cemetary ();
+}
+
+
+static void
+__mf_age_tree (__mf_object_tree_t *obj)
+{
+ assert (obj != NULL);
+ obj->data.liveness = obj->data.liveness >> 1;
+
+ if (obj->left)
+ __mf_age_tree (obj->left);
+ if (obj->right)
+ __mf_age_tree (obj->right);
+}
+
+
+
+struct tree_stats
+{
+ unsigned obj_count;
+ unsigned long total_size;
+ unsigned live_obj_count;
+ double total_weight;
+ double weighted_size;
+ unsigned long weighted_address_bits [sizeof (uintptr_t) * 8][2];
+};
+
+
+static void
+__mf_tree_analyze (__mf_object_tree_t *obj, struct tree_stats* s)
+{
+ assert (obj != NULL);
+
+ if (obj->left)
+ __mf_tree_analyze (obj->left, s);
+
+ /* Exclude never-accessed objects. */
+ if (obj->data.read_count + obj->data.write_count)
+ {
+ s->obj_count ++;
+ s->total_size += (obj->data.high - obj->data.low + 1);
+
+ if (obj->data.liveness)
+ {
+ unsigned i;
+ uintptr_t addr;
+
+ VERBOSE_TRACE ("analyze low=%p live=%u name=`%s'\n",
+ (void *) obj->data.low, obj->data.liveness, obj->data.name);
+
+ s->live_obj_count ++;
+ s->total_weight += (double) obj->data.liveness;
+ s->weighted_size +=
+ (double) (obj->data.high - obj->data.low + 1) *
+ (double) obj->data.liveness;
+
+ addr = obj->data.low;
+ for (i=0; i<sizeof(uintptr_t) * 8; i++)
+ {
+ unsigned bit = addr & 1;
+ s->weighted_address_bits[i][bit] += obj->data.liveness;
+ addr = addr >> 1;
+ }
+ }
+ }
+
+ if (obj->right)
+ __mf_tree_analyze (obj->right, s);
+}
+
+
+static void
+__mf_adapt_cache ()
+{
+ struct tree_stats s;
+ uintptr_t new_mask = 0;
+ unsigned char new_shift;
+ float cache_utilization;
+ float max_value;
+ static float smoothed_new_shift = -1.0;
+ unsigned i;
+
+ memset (&s, 0, sizeof (s));
+ if (__mf_object_root)
+ __mf_tree_analyze (__mf_object_root, & s);
+
+ /* Maybe we're dealing with funny aging/adaptation parameters, or an
+ empty tree. Just leave the cache alone in such cases, rather
+ than risk dying by division-by-zero. */
+ if (! (s.obj_count > 0) && (s.live_obj_count > 0) && (s.total_weight > 0.0))
+ return;
+
+ /* Guess a good value for the shift parameter by finding an address bit that is a
+ good discriminant of lively objects. */
+ max_value = 0.0;
+ for (i=0; i<sizeof (uintptr_t)*8; i++)
+ {
+ float value = (float) s.weighted_address_bits[i][0] * (float) s.weighted_address_bits[i][1];
+ if (max_value < value) max_value = value;
+ }
+ for (i=0; i<sizeof (uintptr_t)*8; i++)
+ {
+ float shoulder_factor = 0.7; /* Include slightly less popular bits too. */
+ float value = (float) s.weighted_address_bits[i][0] * (float) s.weighted_address_bits[i][1];
+ if (value >= max_value * shoulder_factor)
+ break;
+ }
+ if (smoothed_new_shift < 0) smoothed_new_shift = __mf_lc_shift;
+ /* Converge toward this slowly to reduce flapping. */
+ smoothed_new_shift = 0.9*smoothed_new_shift + 0.1*i;
+ new_shift = (unsigned) (smoothed_new_shift + 0.5);
+ assert (new_shift < sizeof (uintptr_t)*8);
+
+ /* Count number of used buckets. */
+ cache_utilization = 0.0;
+ for (i = 0; i < (1 + __mf_lc_mask); i++)
+ if (__mf_lookup_cache[i].low != 0 || __mf_lookup_cache[i].high != 0)
+ cache_utilization += 1.0;
+ cache_utilization /= (1 + __mf_lc_mask);
+
+ new_mask |= 0x3ff; /* XXX: force a large cache. */
+ new_mask &= (LOOKUP_CACHE_SIZE_MAX - 1);
+
+ VERBOSE_TRACE ("adapt cache obj=%u/%u sizes=%lu/%.0f/%.0f => "
+ "util=%u%% m=%p s=%u\n",
+ s.obj_count, s.live_obj_count, s.total_size, s.total_weight, s.weighted_size,
+ (unsigned)(cache_utilization*100.0), (void *) new_mask, new_shift);
+
+ /* We should reinitialize cache if its parameters have changed. */
+ if (new_mask != __mf_lc_mask ||
+ new_shift != __mf_lc_shift)
+ {
+ __mf_lc_mask = new_mask;
+ __mf_lc_shift = new_shift;
+ /* XXX: race */
+ memset (__mf_lookup_cache, 0, sizeof(__mf_lookup_cache));
+ /* void slot 0 */
+ __mf_lookup_cache[0].low = MAXPTR;
+ }
+}
+
+
+
+
+/* __mf_find_object[s] */
+
+/* Find overlapping live objecs between [low,high]. Return up to
+ max_objs of their pointers in objs[]. Return total count of
+ overlaps (may exceed max_objs). */
+
+/* XXX: track traversal statistics, like average depth, balance. */
+
+static unsigned
+__mf_find_objects_rec (uintptr_t low, uintptr_t high, __mf_object_tree_t **nodep,
+ __mf_object_tree_t **objs, unsigned max_objs)
+{
+ unsigned count;
+ __mf_object_tree_t *node = *nodep;
+
+ assert (low <= high);
+ assert (max_objs == 0 || objs != NULL);
+
+ if (UNLIKELY (node == NULL)) return 0;
+
+ /* Traverse down left subtree. */
+ count = 0;
+ if (low < node->data.low)
+ count += __mf_find_objects_rec (low, min(high, node->data.low),
+ & node->left, objs, max_objs);
+
+ /* Track the used slots of objs[]. */
+ if (count < max_objs)
+ {
+ objs += count;
+ max_objs -= count;
+ }
+ else
+ {
+ max_objs = 0;
+ }
+
+ /* Check for overlap with this node. */
+ if (high >= node->data.low && low <= node->data.high)
+ {
+ count ++;
+ if (max_objs > 0) /* Any room left? */
+ {
+ objs[0] = node;
+ objs ++;
+ max_objs --;
+ }
+ }
+
+ /* Traverse down right subtree. */
+ if (high > node->data.high)
+ count += __mf_find_objects_rec (max (low, node->data.high), high,
+ & node->right, objs, max_objs);
+ /* There is no need to manipulate objs/max_objs any further. */
+
+
+ /* Rotate a child node up if its access count is higher. */
+ if (UNLIKELY ((node->left && node->left->data.liveness > node->data.liveness) &&
+ ((!node->right || (node->right &&
+ node->left->data.liveness >
+ node->right->data.liveness)))))
+ {
+ __mf_object_tree_t *l = node->left;
+ __mf_object_tree_t *l_r = l->right;
+
+ *nodep = l;
+ l->right = node;
+ node->left = l_r;
+ __mf_treerot_left ++;
+ }
+ else if (UNLIKELY ((node->right && node->right->data.liveness > node->data.liveness) &&
+ ((!node->left || (node->left &&
+ node->right->data.liveness >
+ node->left->data.liveness)))))
+ {
+ __mf_object_tree_t *r = node->right;
+ __mf_object_tree_t *r_l = r->left;
+
+ *nodep = r;
+ r->left = node;
+ node->right = r_l;
+ __mf_treerot_right ++;
+ }
+
+ return count;
+}
+
+
+unsigned
+__mf_find_objects (uintptr_t ptr_low, uintptr_t ptr_high,
+ __mf_object_tree_t **objs, unsigned max_objs)
+{
+ if (UNLIKELY(__mf_opts.internal_checking))
+ __mf_validate_objects ();
+
+ return __mf_find_objects_rec (ptr_low, ptr_high, & __mf_object_root, objs, max_objs);
+}
+
+/* __mf_link_object */
+
+static void
+__mf_link_object2 (__mf_object_tree_t *ptr, __mf_object_tree_t **link)
+{
+ __mf_object_tree_t *node = *link;
+
+ assert (ptr != NULL);
+ if (UNLIKELY(node == NULL))
+ {
+ *link = ptr;
+ return;
+ }
+
+ if (ptr->data.high < node->data.low)
+ return __mf_link_object2 (ptr, & node->left);
+ else if (ptr->data.low > node->data.high)
+ return __mf_link_object2 (ptr, & node->right);
+ else
+ abort (); /* XXX: duplicate object */
+}
+
+
+void
+__mf_link_object (__mf_object_tree_t *ptr)
+{
+ if (UNLIKELY(__mf_opts.internal_checking))
+ __mf_validate_objects ();
+
+ return __mf_link_object2 (ptr, & __mf_object_root);
+}
+
+/* __mf_unlink_object */
+
+static void
+__mf_unlink_object2 (__mf_object_tree_t *ptr, __mf_object_tree_t **link)
+{
+ __mf_object_tree_t *node = *link;
+
+ assert (ptr != NULL);
+ if (UNLIKELY(node == ptr))
+ {
+ static unsigned promote_left_p = 0;
+ promote_left_p = 1 - promote_left_p;
+
+ /* Alternate promoting the left & right subtrees. */
+ if (promote_left_p)
+ {
+ *link = ptr->left;
+ if (ptr->right != NULL)
+ __mf_link_object2 (ptr->right, link);
+ }
+ else
+ {
+ *link = ptr->right;
+ if (ptr->left != NULL)
+ __mf_link_object2 (ptr->left, link);
+ }
+
+ return;
+ }
+
+ if (ptr->data.high < node->data.low)
+ return __mf_unlink_object2 (ptr, & node->left);
+ else if (ptr->data.low > node->data.high)
+ return __mf_unlink_object2 (ptr, & node->right);
+ else
+ abort (); /* XXX: missing object; should fail more gracefully. */
+}
+
+static void
+__mf_unlink_object (__mf_object_tree_t *node)
+{
+ __mf_unlink_object2 (node, & __mf_object_root);
+}
+
+/* __mf_find_dead_objects */
+
+/* Find overlapping dead objecs between [low,high]. Return up to
+ max_objs of their pointers in objs[]. Return total count of
+ overlaps (may exceed max_objs). */
+
+static unsigned
+__mf_find_dead_objects (uintptr_t low, uintptr_t high,
+ __mf_object_tree_t **objs, unsigned max_objs)
+{
+ if (__mf_opts.persistent_count > 0)
+ {
+ unsigned count = 0;
+ unsigned recollection = 0;
+ unsigned row = 0;
+
+ assert (low <= high);
+ assert (max_objs == 0 || objs != NULL);
+
+ /* Widen the search from the most recent plots in each row, looking
+ backward in time. */
+ recollection = 0;
+ while (recollection < __mf_opts.persistent_count)
+ {
+ count = 0;
+
+ for (row = 0; row <= __MF_TYPE_MAX_CEM; row ++)
+ {
+ unsigned plot;
+ unsigned i;
+
+ plot = __mf_object_dead_head [row];
+ for (i = 0; i <= recollection; i ++)
+ {
+ __mf_object_tree_t *obj;
+
+ /* Look backward through row: it's a circular buffer. */
+ if (plot > 0) plot --;
+ else plot = __mf_opts.persistent_count - 1;
+
+ obj = __mf_object_cemetary [row][plot];
+ if (obj && obj->data.low <= high && obj->data.high >= low)
+ {
+ /* Found an overlapping dead object! */
+ if (count < max_objs)
+ objs [count] = obj;
+ count ++;
+ }
+ }
+ }
+
+ if (count)
+ break;
+
+ /* Look farther back in time. */
+ recollection = (recollection * 2) + 1;
+ }
+
+ return count;
+ } else {
+ return 0;
+ }
+}
+
+/* __mf_describe_object */
+
+static void
+__mf_describe_object (__mf_object_t *obj)
+{
+ static unsigned epoch = 0;
+ if (obj == NULL)
+ {
+ epoch ++;
+ return;
+ }
+
+ if (__mf_opts.abbreviate && obj->description_epoch == epoch)
+ {
+ fprintf (stderr,
+ "mudflap object %p: name=`%s'\n",
+ (void *) obj, (obj->name ? obj->name : ""));
+ return;
+ }
+ else
+ obj->description_epoch = epoch;
+
+ fprintf (stderr,
+ "mudflap object %p: name=`%s'\n"
+ "bounds=[%p,%p] size=%lu area=%s check=%ur/%uw liveness=%u%s\n"
+ "alloc time=%lu.%06lu pc=%p"
+#ifdef LIBMUDFLAPTH
+ " thread=%u"
+#endif
+ "\n",
+ (void *) obj, (obj->name ? obj->name : ""),
+ (void *) obj->low, (void *) obj->high,
+ (unsigned long) (obj->high - obj->low + 1),
+ (obj->type == __MF_TYPE_NOACCESS ? "no-access" :
+ obj->type == __MF_TYPE_HEAP ? "heap" :
+ obj->type == __MF_TYPE_HEAP_I ? "heap-init" :
+ obj->type == __MF_TYPE_STACK ? "stack" :
+ obj->type == __MF_TYPE_STATIC ? "static" :
+ obj->type == __MF_TYPE_GUESS ? "guess" :
+ "unknown"),
+ obj->read_count, obj->write_count, obj->liveness,
+ obj->watching_p ? " watching" : "",
+ obj->alloc_time.tv_sec, obj->alloc_time.tv_usec,
+ (void *) obj->alloc_pc
+#ifdef LIBMUDFLAPTH
+ , (unsigned) obj->alloc_thread
+#endif
+ );
+
+ if (__mf_opts.backtrace > 0)
+ {
+ unsigned i;
+ for (i=0; i<obj->alloc_backtrace_size; i++)
+ fprintf (stderr, " %s\n", obj->alloc_backtrace[i]);
+ }
+
+ if (__mf_opts.persistent_count > 0)
+ {
+ if (obj->deallocated_p)
+ {
+ fprintf (stderr, "dealloc time=%lu.%06lu pc=%p"
+#ifdef LIBMUDFLAPTH
+ " thread=%u"
+#endif
+ "\n",
+ obj->dealloc_time.tv_sec, obj->dealloc_time.tv_usec,
+ (void *) obj->dealloc_pc
+#ifdef LIBMUDFLAPTH
+ , (unsigned) obj->dealloc_thread
+#endif
+ );
+
+
+ if (__mf_opts.backtrace > 0)
+ {
+ unsigned i;
+ for (i=0; i<obj->dealloc_backtrace_size; i++)
+ fprintf (stderr, " %s\n", obj->dealloc_backtrace[i]);
+ }
+ }
+ }
+}
+
+static unsigned
+__mf_report_leaks (__mf_object_tree_t *node)
+{
+ /* The counter is amongst recursive calls, so
+ that cumulative numbers are printed below. */
+ static unsigned count = 0;
+
+ if (node == NULL) /* Reset */
+ {
+ count = 0;
+ return 0;
+ }
+
+ /* Inorder traversal. */
+ if (node->left)
+ __mf_report_leaks (node->left);
+ if (node->data.type == __MF_TYPE_HEAP
+ || node->data.type == __MF_TYPE_HEAP_I)
+ {
+ count ++;
+ fprintf (stderr, "Leaked object %u:\n", count);
+ __mf_describe_object (& node->data);
+ }
+ if (node->right)
+ __mf_report_leaks (node->right);
+
+ return count;
+}
+
+/* ------------------------------------------------------------------------ */
+/* __mf_report */
+
+void
+__mf_report ()
+{
+ LOCKTH ();
+ BEGIN_RECURSION_PROTECT ();
+ __mfu_report ();
+ END_RECURSION_PROTECT ();
+ UNLOCKTH ();
+}
+
+void
+__mfu_report ()
+{
+ if (__mf_opts.collect_stats)
+ {
+ fprintf (stderr,
+ "*******\n"
+ "mudflap stats:\n"
+ "calls to __mf_check: %lu rot: %lu/%lu\n"
+ " __mf_register: %lu [%luB, %luB, %luB, %luB, %luB]\n"
+ " __mf_unregister: %lu [%luB]\n"
+ " __mf_violation: [%lu, %lu, %lu, %lu, %lu]\n",
+ __mf_count_check, __mf_treerot_left, __mf_treerot_right,
+ __mf_count_register,
+ __mf_total_register_size[0], __mf_total_register_size[1],
+ __mf_total_register_size[2], __mf_total_register_size[3],
+ __mf_total_register_size[4], /* XXX */
+ __mf_count_unregister, __mf_total_unregister_size,
+ __mf_count_violation[0], __mf_count_violation[1],
+ __mf_count_violation[2], __mf_count_violation[3],
+ __mf_count_violation[4]);
+
+ fprintf (stderr,
+ "calls with reentrancy: %lu\n", __mf_reentrancy);
+#ifdef LIBMUDFLAPTH
+ fprintf (stderr,
+ " lock contention: %lu\n", __mf_lock_contention);
+#endif
+
+ /* Lookup cache stats. */
+ {
+ unsigned i;
+ unsigned max_reuse = 0;
+ unsigned num_used = 0;
+ unsigned num_unused = 0;
+
+ for (i = 0; i < LOOKUP_CACHE_SIZE; i++)
+ {
+ if (__mf_lookup_cache_reusecount[i])
+ num_used ++;
+ else
+ num_unused ++;
+ if (max_reuse < __mf_lookup_cache_reusecount[i])
+ max_reuse = __mf_lookup_cache_reusecount[i];
+ }
+ fprintf (stderr, "lookup cache slots used: %u unused: %u peak-reuse: %u\n",
+ num_used, num_unused, max_reuse);
+ }
+
+ {
+ unsigned live_count;
+ live_count = __mf_find_objects (MINPTR, MAXPTR, NULL, 0);
+ fprintf (stderr, "number of live objects: %u\n", live_count);
+ }
+
+ if (__mf_opts.persistent_count > 0)
+ {
+ unsigned dead_count = 0;
+ unsigned row, plot;
+ for (row = 0; row <= __MF_TYPE_MAX_CEM; row ++)
+ for (plot = 0 ; plot < __mf_opts.persistent_count; plot ++)
+ if (__mf_object_cemetary [row][plot] != 0)
+ dead_count ++;
+ fprintf (stderr, " zombie objects: %u\n", dead_count);
+ }
+ }
+ if (__mf_opts.print_leaks && (__mf_opts.mudflap_mode == mode_check))
+ {
+ unsigned l;
+ extern void * __mf_wrap_alloca_indirect (size_t c);
+
+ /* Free up any remaining alloca()'d blocks. */
+ __mf_wrap_alloca_indirect (0);
+ __mf_describe_object (NULL); /* Reset description epoch. */
+ __mf_report_leaks (NULL); /* Reset cumulative count. */
+ l = __mf_report_leaks (__mf_object_root);
+ fprintf (stderr, "number of leaked objects: %u\n", l);
+ }
+}
+
+/* __mf_backtrace */
+
+size_t
+__mf_backtrace (char ***symbols, void *guess_pc, unsigned guess_omit_levels)
+{
+ void ** pc_array;
+ unsigned pc_array_size = __mf_opts.backtrace + guess_omit_levels;
+ unsigned remaining_size;
+ unsigned omitted_size = 0;
+ unsigned i;
+ DECLARE (void, free, void *ptr);
+ DECLARE (void *, calloc, size_t c, size_t n);
+ DECLARE (void *, malloc, size_t n);
+
+ pc_array = CALL_REAL (calloc, pc_array_size, sizeof (void *) );
+#ifdef HAVE_BACKTRACE
+ pc_array_size = backtrace (pc_array, pc_array_size);
+#else
+#define FETCH(n) do { if (pc_array_size >= n) { \
+ pc_array[n] = __builtin_return_address(n); \
+ if (pc_array[n] == 0) pc_array_size = n; } } while (0)
+
+ /* Unroll some calls __builtin_return_address because this function
+ only takes a literal integer parameter. */
+ FETCH (0);
+#if 0
+ /* XXX: __builtin_return_address sometimes crashes (!) on >0 arguments,
+ rather than simply returning 0. :-( */
+ FETCH (1);
+ FETCH (2);
+ FETCH (3);
+ FETCH (4);
+ FETCH (5);
+ FETCH (6);
+ FETCH (7);
+ FETCH (8);
+ if (pc_array_size > 8) pc_array_size = 9;
+#else
+ if (pc_array_size > 0) pc_array_size = 1;
+#endif
+
+#undef FETCH
+#endif
+
+ /* We want to trim the first few levels of the stack traceback,
+ since they contain libmudflap wrappers and junk. If pc_array[]
+ ends up containing a non-NULL guess_pc, then trim everything
+ before that. Otherwise, omit the first guess_omit_levels
+ entries. */
+
+ if (guess_pc != NULL)
+ for (i=0; i<pc_array_size; i++)
+ if (pc_array [i] == guess_pc)
+ omitted_size = i;
+
+ if (omitted_size == 0) /* No match? */
+ if (pc_array_size > guess_omit_levels)
+ omitted_size = guess_omit_levels;
+
+ remaining_size = pc_array_size - omitted_size;
+
+#ifdef HAVE_BACKTRACE_SYMBOLS
+ *symbols = backtrace_symbols (pc_array + omitted_size, remaining_size);
+#else
+ {
+ /* Let's construct a buffer by hand. It will have <remaining_size>
+ char*'s at the front, pointing at individual strings immediately
+ afterwards. */
+ void *buffer;
+ char *chars;
+ char **pointers;
+ enum { perline = 30 };
+ buffer = CALL_REAL (malloc, remaining_size * (perline + sizeof(char *)));
+ pointers = (char **) buffer;
+ chars = (char *)buffer + (remaining_size * sizeof (char *));
+ for (i = 0; i < remaining_size; i++)
+ {
+ pointers[i] = chars;
+ sprintf (chars, "[0x%p]", pc_array [omitted_size + i]);
+ chars = chars + perline;
+ }
+ *symbols = pointers;
+ }
+#endif
+ CALL_REAL (free, pc_array);
+
+ return remaining_size;
+}
+
+/* ------------------------------------------------------------------------ */
+/* __mf_violation */
+
+void
+__mf_violation (void *ptr, size_t sz, uintptr_t pc,
+ const char *location, int type)
+{
+ char buf [128];
+ static unsigned violation_number;
+ DECLARE(void, free, void *ptr);
+
+ TRACE ("violation pc=%p location=%s type=%d ptr=%p size=%lu\n",
+ (void *) pc,
+ (location != NULL ? location : ""), type, ptr, (unsigned long) sz);
+
+ if (__mf_opts.collect_stats)
+ __mf_count_violation [(type < 0) ? 0 :
+ (type > __MF_VIOL_WATCH) ? 0 :
+ type] ++;
+
+ /* Print out a basic warning message. */
+ if (__mf_opts.verbose_violations)
+ {
+ unsigned dead_p;
+ unsigned num_helpful = 0;
+ struct timeval now;
+#if HAVE_GETTIMEOFDAY
+ gettimeofday (& now, NULL);
+#endif
+
+ violation_number ++;
+ fprintf (stderr,
+ "*******\n"
+ "mudflap violation %u (%s): time=%lu.%06lu "
+ "ptr=%p size=%lu\npc=%p%s%s%s\n",
+ violation_number,
+ ((type == __MF_VIOL_READ) ? "check/read" :
+ (type == __MF_VIOL_WRITE) ? "check/write" :
+ (type == __MF_VIOL_REGISTER) ? "register" :
+ (type == __MF_VIOL_UNREGISTER) ? "unregister" :
+ (type == __MF_VIOL_WATCH) ? "watch" : "unknown"),
+ now.tv_sec, now.tv_usec,
+ (void *) ptr, (unsigned long)sz, (void *) pc,
+ (location != NULL ? " location=`" : ""),
+ (location != NULL ? location : ""),
+ (location != NULL ? "'" : ""));
+
+ if (__mf_opts.backtrace > 0)
+ {
+ char ** symbols;
+ unsigned i, num;
+
+ num = __mf_backtrace (& symbols, (void *) pc, 2);
+ /* Note: backtrace_symbols calls malloc(). But since we're in
+ __mf_violation and presumably __mf_check, it'll detect
+ recursion, and not put the new string into the database. */
+
+ for (i=0; i<num; i++)
+ fprintf (stderr, " %s\n", symbols[i]);
+
+ /* Calling free() here would trigger a violation. */
+ CALL_REAL(free, symbols);
+ }
+
+
+ /* Look for nearby objects. For this, we start with s_low/s_high
+ pointing to the given area, looking for overlapping objects.
+ If none show up, widen the search area and keep looking. */
+
+ if (sz == 0) sz = 1;
+
+ for (dead_p = 0; dead_p <= 1; dead_p ++) /* for dead_p in 0 1 */
+ {
+ enum {max_objs = 3}; /* magic */
+ __mf_object_tree_t *objs[max_objs];
+ unsigned num_objs = 0;
+ uintptr_t s_low, s_high;
+ unsigned tries = 0;
+ unsigned i;
+
+ s_low = (uintptr_t) ptr;
+ s_high = CLAMPSZ (ptr, sz);
+
+ while (tries < 16) /* magic */
+ {
+ if (dead_p)
+ num_objs = __mf_find_dead_objects (s_low, s_high, objs, max_objs);
+ else
+ num_objs = __mf_find_objects (s_low, s_high, objs, max_objs);
+
+ if (num_objs) /* good enough */
+ break;
+
+ tries ++;
+
+ /* XXX: tune this search strategy. It's too dependent on
+ sz, which can vary from 1 to very big (when array index
+ checking) numbers. */
+ s_low = CLAMPSUB (s_low, (sz * tries * tries));
+ s_high = CLAMPADD (s_high, (sz * tries * tries));
+ }
+
+ for (i = 0; i < min (num_objs, max_objs); i++)
+ {
+ __mf_object_t *obj = & objs[i]->data;
+ uintptr_t low = (uintptr_t) ptr;
+ uintptr_t high = CLAMPSZ (ptr, sz);
+ unsigned before1 = (low < obj->low) ? obj->low - low : 0;
+ unsigned after1 = (low > obj->high) ? low - obj->high : 0;
+ unsigned into1 = (high >= obj->low && low <= obj->high) ? low - obj->low : 0;
+ unsigned before2 = (high < obj->low) ? obj->low - high : 0;
+ unsigned after2 = (high > obj->high) ? high - obj->high : 0;
+ unsigned into2 = (high >= obj->low && low <= obj->high) ? high - obj->low : 0;
+
+ fprintf (stderr, "Nearby object %u: checked region begins %uB %s and ends %uB %s\n",
+ num_helpful + i + 1,
+ (before1 ? before1 : after1 ? after1 : into1),
+ (before1 ? "before" : after1 ? "after" : "into"),
+ (before2 ? before2 : after2 ? after2 : into2),
+ (before2 ? "before" : after2 ? "after" : "into"));
+ __mf_describe_object (obj);
+ }
+ num_helpful += num_objs;
+ }
+
+ fprintf (stderr, "number of nearby objects: %u\n", num_helpful);
+ }
+
+ /* How to finally handle this violation? */
+ switch (__mf_opts.violation_mode)
+ {
+ case viol_nop:
+ break;
+ case viol_segv:
+ kill (getpid(), SIGSEGV);
+ break;
+ case viol_abort:
+ abort ();
+ break;
+ case viol_gdb:
+ snprintf (buf, 128, "gdb --pid=%d", getpid ());
+ system (buf);
+ /* XXX: should probably fork() && sleep(GDB_WAIT_PARAMETER)
+ instead, and let the forked child execlp() gdb. That way, this
+ subject process can be resumed under the supervision of gdb.
+ This can't happen now, since system() only returns when gdb
+ dies. In that case, we need to beware of starting a second
+ concurrent gdb child upon the next violation. (But if the first
+ gdb dies, then starting a new one is appropriate.) */
+ break;
+ }
+}
+
+/* ------------------------------------------------------------------------ */
+
+
+unsigned __mf_watch (void *ptr, size_t sz)
+{
+ unsigned rc;
+ LOCKTH ();
+ BEGIN_RECURSION_PROTECT ();
+ rc = __mf_watch_or_not (ptr, sz, 1);
+ END_RECURSION_PROTECT ();
+ UNLOCKTH ();
+ return rc;
+}
+
+unsigned __mf_unwatch (void *ptr, size_t sz)
+{
+ unsigned rc;
+ LOCKTH ();
+ rc = __mf_watch_or_not (ptr, sz, 0);
+ UNLOCKTH ();
+ return rc;
+}
+
+
+static unsigned
+__mf_watch_or_not (void *ptr, size_t sz, char flag)
+{
+ uintptr_t ptr_high = CLAMPSZ (ptr, sz);
+ uintptr_t ptr_low = (uintptr_t) ptr;
+ unsigned count = 0;
+
+ TRACE ("%s ptr=%p size=%lu\n",
+ (flag ? "watch" : "unwatch"), ptr, (unsigned long) sz);
+
+ switch (__mf_opts.mudflap_mode)
+ {
+ case mode_nop:
+ case mode_populate:
+ case mode_violate:
+ count = 0;
+ break;
+
+ case mode_check:
+ {
+ __mf_object_tree_t **all_ovr_objs;
+ unsigned obj_count;
+ unsigned n;
+ DECLARE (void *, malloc, size_t c);
+ DECLARE (void, free, void *p);
+
+ obj_count = __mf_find_objects (ptr_low, ptr_high, NULL, 0);
+ VERBOSE_TRACE (" %u:", obj_count);
+
+ all_ovr_objs = CALL_REAL (malloc, (sizeof (__mf_object_tree_t *) *
+ obj_count));
+ if (all_ovr_objs == NULL) abort ();
+ n = __mf_find_objects (ptr_low, ptr_high, all_ovr_objs, obj_count);
+ assert (n == obj_count);
+
+ for (n = 0; n < obj_count; n ++)
+ {
+ __mf_object_t *obj = & (all_ovr_objs[n]->data);
+
+ VERBOSE_TRACE (" [%p]", (void *) obj);
+ if (obj->watching_p != flag)
+ {
+ obj->watching_p = flag;
+ count ++;
+
+ /* Remove object from cache, to ensure next access
+ goes through __mf_check(). */
+ if (flag)
+ __mf_uncache_object (obj);
+ }
+ }
+ CALL_REAL (free, all_ovr_objs);
+ }
+ break;
+ }
+
+ return count;
+}
+
+
+void
+__mf_sigusr1_handler (int num)
+{
+ __mf_sigusr1_received ++;
+}
+
+/* Install or remove SIGUSR1 handler as necessary.
+ Also, respond to a received pending SIGUSR1. */
+void
+__mf_sigusr1_respond ()
+{
+ static int handler_installed;
+
+#if HAVE_SIGNAL
+ /* Manage handler */
+ if (__mf_opts.sigusr1_report && ! handler_installed)
+ {
+ signal (SIGUSR1, __mf_sigusr1_handler);
+ handler_installed = 1;
+ }
+ else if(! __mf_opts.sigusr1_report && handler_installed)
+ {
+ signal (SIGUSR1, SIG_DFL);
+ handler_installed = 0;
+ }
+#endif
+
+ /* Manage enqueued signals */
+ if (__mf_sigusr1_received > __mf_sigusr1_handled)
+ {
+ __mf_sigusr1_handled ++;
+ assert (__mf_state == reentrant);
+ __mfu_report ();
+ handler_installed = 0; /* We may need to re-enable signal; this might be a SysV library. */
+ }
+}
+
+
+/* XXX: provide an alternative __assert_fail function that cannot
+ fail due to libmudflap infinite recursion. */
+#ifndef NDEBUG
+
+static void
+write_itoa (int fd, unsigned n)
+{
+ enum x { bufsize = sizeof(n)*4 };
+ char buf [bufsize];
+ unsigned i;
+
+ for (i=0; i<bufsize-1; i++)
+ {
+ unsigned digit = n % 10;
+ buf[bufsize-2-i] = digit + '0';
+ n /= 10;
+ if (n == 0)
+ {
+ char *m = & buf [bufsize-2-i];
+ buf[bufsize-1] = '\0';
+ write (fd, m, strlen(m));
+ break;
+ }
+ }
+}
+
+
+void
+__assert_fail (const char *msg, const char *file, unsigned line, const char *func)
+{
+#define write2(string) write (2, (string), strlen ((string)));
+ write2("mf");
+#ifdef LIBMUDFLAPTH
+ write2("(");
+ write_itoa (2, (unsigned) pthread_self ());
+ write2(")");
+#endif
+ write2(": assertion failure: `");
+ write (2, msg, strlen (msg));
+ write2("' in ");
+ write (2, func, strlen (func));
+ write2(" at ");
+ write (2, file, strlen (file));
+ write2(":");
+ write_itoa (2, line);
+ write2("\n");
+#undef write2
+ abort ();
+}
+
+
+#endif
diff --git a/libmudflap/mf-runtime.h.in b/libmudflap/mf-runtime.h.in
new file mode 100644
index 00000000000..11f1f8de5fe
--- /dev/null
+++ b/libmudflap/mf-runtime.h.in
@@ -0,0 +1,191 @@
+/* Public libmudflap declarations -*- C -*- */
+
+#ifndef MF_RUNTIME_H
+#define MF_RUNTIME_H
+
+#if @MF_HAVE_STDINT_H@ /* autoconf HAVE_STDINT_H */
+#include <stdint.h>
+#endif
+#include <sys/types.h>
+#if ! @MF_HAVE_UINTPTR_T@
+typedef unsigned long uintptr_t;
+#define HAVE_UINTPTR_T 1
+/* Define this here, in case an autoconf application was run
+ without CFLAGS=-fmudflap but is being compiled with -fmudflap. */
+#endif
+
+
+/* Global declarations used by instrumentation. */
+
+struct __mf_cache { uintptr_t low; uintptr_t high; };
+extern struct __mf_cache __mf_lookup_cache [];
+extern uintptr_t __mf_lc_mask;
+extern unsigned char __mf_lc_shift;
+
+/* Multithreading support. */
+#ifdef _MUDFLAPTH
+/* extern pthread_mutex_t __mf_biglock; */
+#define _REENTRANT
+#define _THREAD_SAFE
+#endif
+
+/* Codes to describe the type of access to check: __mf_check arg 3 */
+
+#define __MF_CHECK_READ 0
+#define __MF_CHECK_WRITE 1
+
+
+/* Codes to describe a region of memory being registered: __mf_*register arg 3 */
+
+#define __MF_TYPE_NOACCESS 0
+#define __MF_TYPE_HEAP 1
+#define __MF_TYPE_HEAP_I 2
+#define __MF_TYPE_STACK 3
+#define __MF_TYPE_STATIC 4
+#define __MF_TYPE_GUESS 5
+
+
+/* The public mudflap API */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void __mf_check (void *ptr, size_t sz, int type, const char *location)
+ __attribute((nothrow));
+extern void __mf_register (void *ptr, size_t sz, int type, const char *name)
+ __attribute((nothrow));
+extern void __mf_unregister (void *ptr, size_t sz) __attribute((nothrow));
+extern unsigned __mf_watch (void *ptr, size_t sz);
+extern unsigned __mf_unwatch (void *ptr, size_t sz);
+extern void __mf_report ();
+extern int __mf_set_options (const char *opts);
+
+
+/* Redirect some standard library functions to libmudflap. These are
+ done by simple #define rather than linker wrapping, since only
+ instrumented modules are meant to be affected. */
+
+#ifdef _MUDFLAP
+#pragma redefine_extname memcpy __mfwrap_memcpy
+#pragma redefine_extname memmove __mfwrap_memmove
+#pragma redefine_extname memset __mfwrap_memset
+#pragma redefine_extname memcmp __mfwrap_memcmp
+#pragma redefine_extname memchr __mfwrap_memchr
+#pragma redefine_extname memrchr __mfwrap_memrchr
+#pragma redefine_extname strcpy __mfwrap_strcpy
+#pragma redefine_extname strncpy __mfwrap_strncpy
+#pragma redefine_extname strcat __mfwrap_strcat
+#pragma redefine_extname strncat __mfwrap_strncat
+#pragma redefine_extname strcmp __mfwrap_strcmp
+#pragma redefine_extname strcasecmp __mfwrap_strcasecmp
+#pragma redefine_extname strncmp __mfwrap_strncmp
+#pragma redefine_extname strncasecmp __mfwrap_strncasecmp
+#pragma redefine_extname strdup __mfwrap_strdup
+#pragma redefine_extname strndup __mfwrap_strndup
+#pragma redefine_extname strchr __mfwrap_strchr
+#pragma redefine_extname strrchr __mfwrap_strrchr
+#pragma redefine_extname strstr __mfwrap_strstr
+#pragma redefine_extname memmem __mfwrap_memmem
+#pragma redefine_extname strlen __mfwrap_strlen
+#pragma redefine_extname strnlen __mfwrap_strnlen
+#pragma redefine_extname bzero __mfwrap_bzero
+#pragma redefine_extname bcopy __mfwrap_bcopy
+#pragma redefine_extname bcmp __mfwrap_bcmp
+#pragma redefine_extname index __mfwrap_index
+#pragma redefine_extname rindex __mfwrap_rindex
+#pragma redefine_extname asctime __mfwrap_asctime
+#pragma redefine_extname ctime __mfwrap_ctime
+#pragma redefine_extname gmtime __mfwrap_gmtime
+#pragma redefine_extname localtime __mfwrap_localtime
+#pragma redefine_extname time __mfwrap_time
+#pragma redefine_extname strerror __mfwrap_strerror
+#pragma redefine_extname fopen __mfwrap_fopen
+#pragma redefine_extname fclose __mfwrap_fclose
+#pragma redefine_extname fread __mfwrap_fread
+#pragma redefine_extname fwrite __mfwrap_fwrite
+#pragma redefine_extname fgetc __mfwrap_fgetc
+#pragma redefine_extname fgets __mfwrap_fgets
+#pragma redefine_extname getc __mfwrap_getc
+#pragma redefine_extname gets __mfwrap_gets
+#pragma redefine_extname ungetc __mfwrap_ungetc
+#pragma redefine_extname fputc __mfwrap_fputc
+#pragma redefine_extname fputs __mfwrap_fputs
+#pragma redefine_extname putc __mfwrap_putc
+#pragma redefine_extname puts __mfwrap_puts
+#pragma redefine_extname clearerr __mfwrap_clearerr
+#pragma redefine_extname feof __mfwrap_feof
+#pragma redefine_extname ferror __mfwrap_ferror
+#pragma redefine_extname fileno __mfwrap_fileno
+#pragma redefine_extname printf __mfwrap_printf
+#pragma redefine_extname fprintf __mfwrap_fprintf
+#pragma redefine_extname sprintf __mfwrap_sprintf
+#pragma redefine_extname snprintf __mfwrap_snprintf
+#pragma redefine_extname vprintf __mfwrap_vprintf
+#pragma redefine_extname vfprintf __mfwrap_vfprintf
+#pragma redefine_extname vsprintf __mfwrap_vsprintf
+#pragma redefine_extname vsnprintf __mfwrap_vsnprintf
+#pragma redefine_extname access __mfwrap_access
+#pragma redefine_extname remove __mfwrap_remove
+#pragma redefine_extname fflush __mfwrap_fflush
+#pragma redefine_extname fseek __mfwrap_fseek
+#pragma redefine_extname ftell __mfwrap_ftell
+#pragma redefine_extname rewind __mfwrap_rewind
+#pragma redefine_extname fgetpos __mfwrap_fgetpos
+#pragma redefine_extname fsetpos __mfwrap_fsetpos
+#pragma redefine_extname stat __mfwrap_stat
+#pragma redefine_extname fstat __mfwrap_fstat
+#pragma redefine_extname lstat __mfwrap_lstat
+#pragma redefine_extname mkfifo __mfwrap_mkfifo
+#pragma redefine_extname setvbuf __mfwrap_setvbuf
+#pragma redefine_extname setbuf __mfwrap_setbuf
+#pragma redefine_extname opendir __mfwrap_opendir
+#pragma redefine_extname closedir __mfwrap_closedir
+#pragma redefine_extname readdir __mfwrap_readdir
+#pragma redefine_extname recv __mfwrap_recv
+#pragma redefine_extname recvfrom __mfwrap_recvfrom
+#pragma redefine_extname recvmsg __mfwrap_recvmsg
+#pragma redefine_extname send __mfwrap_send
+#pragma redefine_extname sendto __mfwrap_sendto
+#pragma redefine_extname sendmsg __mfwrap_sendmsg
+#pragma redefine_extname setsockopt __mfwrap_setsockopt
+#pragma redefine_extname getsockopt __mfwrap_getsockopt
+#pragma redefine_extname accept __mfwrap_accept
+#pragma redefine_extname bind __mfwrap_bind
+#pragma redefine_extname connect __mfwrap_connect
+#pragma redefine_extname gethostname __mfwrap_gethostname
+#pragma redefine_extname sethostname __mfwrap_sethostname
+#pragma redefine_extname gethostbyname __mfwrap_gethostbyname
+#pragma redefine_extname wait __mfwrap_wait
+#pragma redefine_extname waitpid __mfwrap_waitpid
+#pragma redefine_extname popen __mfwrap_popen
+#pragma redefine_extname pclose __mfwrap_pclose
+#pragma redefine_extname execve __mfwrap_execve
+#pragma redefine_extname execv __mfwrap_execv
+#pragma redefine_extname execvp __mfwrap_execvp
+#pragma redefine_extname system __mfwrap_system
+#pragma redefine_extname dlopen __mfwrap_dlopen
+#pragma redefine_extname dlerror __mfwrap_dlerror
+#pragma redefine_extname dlsym __mfwrap_dlsym
+#pragma redefine_extname dlclose __mfwrap_dlclose
+#pragma redefine_extname fopen64 __mfwrap_fopen64
+#pragma redefine_extname stat64 __mfwrap_stat64
+#pragma redefine_extname fseeko64 __mfwrap_fseeko64
+#pragma redefine_extname ftello64 __mfwrap_ftello64
+#pragma redefine_extname semop __mfwrap_semop
+#pragma redefine_extname semctl __mfwrap_semctl
+#pragma redefine_extname shmctl __mfwrap_shmctl
+#pragma redefine_extname shmat __mfwrap_shmat
+#pragma redefine_extname shmdt __mfwrap_shmdt
+
+/* Disable glibc macros. */
+#define __NO_STRING_INLINES
+
+#endif /* _MUDFLAP */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MF_RUNTIME_H */
diff --git a/libmudflap/stamp-h.in b/libmudflap/stamp-h.in
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/libmudflap/stamp-h.in
diff --git a/libmudflap/testsuite/Makefile.am b/libmudflap/testsuite/Makefile.am
new file mode 100644
index 00000000000..11938e6cf65
--- /dev/null
+++ b/libmudflap/testsuite/Makefile.am
@@ -0,0 +1,18 @@
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS = foreign dejagnu
+
+EXPECT = `if [ -f ../../expect/expect ] ; then \
+ echo ../../expect/expect ; \
+ else echo expect ; fi`
+
+RUNTEST = `if [ -f ${srcdir}/../../dejagnu/runtest ] ; then \
+ echo ${srcdir}/../../dejagnu/runtest ; \
+ else echo runtest ; fi`
+
+all-local: site.exp
+if LIBMUDFLAPTH
+ echo 'set libmudflapth 1' >> site.exp
+else
+ echo 'set libmudflapth 0' >> site.exp
+endif
diff --git a/libmudflap/testsuite/Makefile.in b/libmudflap/testsuite/Makefile.in
new file mode 100644
index 00000000000..30e1763ccdd
--- /dev/null
+++ b/libmudflap/testsuite/Makefile.in
@@ -0,0 +1,249 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AS = @AS@
+CC = @CC@
+CPP = @CPP@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+DLLTOOL = @DLLTOOL@
+EXEEXT = @EXEEXT@
+GCJ = @GCJ@
+GCJFLAGS = @GCJFLAGS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MF_HAVE_STDINT_H = @MF_HAVE_STDINT_H@
+MF_HAVE_UINTPTR_T = @MF_HAVE_UINTPTR_T@
+NM = @NM@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+STRIP = @STRIP@
+VERSION = @VERSION@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
+libtool_VERSION = @libtool_VERSION@
+
+AUTOMAKE_OPTIONS = foreign dejagnu
+
+EXPECT = `if [ -f ../../expect/expect ] ; then \
+ echo ../../expect/expect ; \
+ else echo expect ; fi`
+
+
+RUNTEST = `if [ -f ${srcdir}/../../dejagnu/runtest ] ; then \
+ echo ${srcdir}/../../dejagnu/runtest ; \
+ else echo runtest ; fi`
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = gtar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign testsuite/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+tags: TAGS
+TAGS:
+
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = testsuite
+
+distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign testsuite/Makefile
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$d/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+
+RUNTESTFLAGS =
+
+DEJATOOL = $(PACKAGE)
+
+RUNTESTDEFAULTFLAGS = --tool $(DEJATOOL) --srcdir $$srcdir
+
+check-DEJAGNU: site.exp
+ srcdir=`cd $(srcdir) && pwd`; export srcdir; \
+ EXPECT=$(EXPECT); export EXPECT; \
+ runtest=$(RUNTEST); \
+ if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
+ $$runtest $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \
+ else echo "WARNING: could not find \`runtest'" 1>&2; :;\
+ fi
+site.exp: Makefile
+ @echo 'Making a new site.exp file...'
+ @test ! -f site.bak || rm -f site.bak
+ @echo '## these variables are automatically generated by make ##' > $@-t
+ @echo '# Do not edit here. If you wish to override these values' >> $@-t
+ @echo '# edit the last section' >> $@-t
+ @echo 'set tool $(DEJATOOL)' >> $@-t
+ @echo 'set srcdir $(srcdir)' >> $@-t
+ @echo 'set objdir' `pwd` >> $@-t
+ @echo 'set host_alias $(host_alias)' >> $@-t
+ @echo 'set host_triplet $(host_triplet)' >> $@-t
+ @echo 'set target_alias $(target_alias)' >> $@-t
+ @echo 'set target_triplet $(target_triplet)' >> $@-t
+ @echo 'set build_alias $(build_alias)' >> $@-t
+ @echo 'set build_triplet $(build_triplet)' >> $@-t
+ @echo '## All variables above are generated by configure. Do Not Edit ##' >> $@-t
+ @test ! -f site.exp || sed '1,/^## All variables above are.*##/ d' site.exp >> $@-t
+ @test ! -f site.exp || mv site.exp site.bak
+ @mv $@-t site.exp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: tags distdir check-DEJAGNU info-am info dvi-am dvi check \
+check-am installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-local all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+all-local: site.exp
+@LIBMUDFLAPTH_TRUE@ echo 'set libmudflapth 1' >> site.exp
+@LIBMUDFLAPTH_FALSE@ echo 'set libmudflapth 0' >> site.exp
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libmudflap/testsuite/config/default.exp b/libmudflap/testsuite/config/default.exp
new file mode 100644
index 00000000000..b19491c547c
--- /dev/null
+++ b/libmudflap/testsuite/config/default.exp
@@ -0,0 +1,2 @@
+load_lib standard.exp
+load_lib libmudflap.exp
diff --git a/libmudflap/testsuite/lib/libmudflap.exp b/libmudflap/testsuite/lib/libmudflap.exp
new file mode 100644
index 00000000000..1d1e22ffb28
--- /dev/null
+++ b/libmudflap/testsuite/lib/libmudflap.exp
@@ -0,0 +1,237 @@
+# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+
+# This program 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 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Define libmudflap callbacks for dg.exp.
+# This file is a copy of libstdc++-v3's dejagnu driver, with minor changes.
+
+
+load_lib mfdg.exp
+load_lib libgloss.exp
+
+proc libmudflap-init { compiler } {
+ global srcdir
+ global outdir
+ global blddir
+ global cxx
+ global includes
+ global libs
+ global cxxflags
+ global objdir
+ global gluefile wrap_flags
+ global ld_library_path
+ global tool_root_dir
+
+ verbose "libmudflap-init $compiler"
+
+ set blddir [lookfor_file [get_multilibs] libmudflap]
+
+ # By default, we assume we want to run program images.
+ global dg-do-what-default
+ set dg-do-what-default run
+
+ # set LD_LIBRARY_PATH so that libgcc_s, libstdc++ binaries can be found.
+ # locate libgcc.a so we don't need to account for different values of
+ # SHLIB_EXT on different platforms
+ set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a]
+ if {$gccdir != ""} {
+ set gccdir [file dirname $gccdir]
+ }
+
+ set ld_library_path "."
+ append ld_library_path ":${gccdir}"
+ append ld_library_path ":../../libstdc++-v3/src/.libs"
+ if {[is_remote host] == 0} {
+ foreach i "[exec ${gccdir}/xgcc --print-multi-lib]" {
+ set mldir ""
+ regexp -- "\[a-z0-9=/\.-\]*;" $i mldir
+ set mldir [string trimright $mldir "\;@"]
+ if { "$mldir" == "." } {
+ continue
+ }
+ if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.so.*]] == 1 } {
+ append ld_library_path ":${gccdir}/${mldir}"
+ append ld_library_path ":../../libstdc++-v3/${mldir}/src/.libs"
+ }
+ }
+ }
+ append ld_library_path ":${blddir}/.libs"
+ set cxx $compiler
+ set libs "-L../.libs -L../../libstdc++-v3/src/.libs -L../../../gcc"
+ set cxxflags "-ggdb3 -DDEBUG_ASSERT"
+ set includes "-I${srcdir} -I.."
+
+ verbose "ld_library_path=$ld_library_path"
+ setenv LD_LIBRARY_PATH $ld_library_path
+ setenv SHLIB_PATH $ld_library_path
+ setenv LD_LIBRARYN32_PATH $ld_library_path
+ setenv LD_LIBRARY64_PATH $ld_library_path
+
+ if { [target_info needs_status_wrapper]!=""} {
+ file delete ${objdir}/testglue.o;
+ set gluefile ${objdir}/testglue.o;
+ set result [build_wrapper $gluefile];
+ if { $result != "" } {
+ set gluefile [lindex $result 0];
+ set wrap_flags [lindex $result 1];
+ } else {
+ unset gluefile
+ }
+ }
+}
+
+proc libmudflap-dg-test { prog do_what extra_tool_flags } {
+ # Set up the compiler flags, based on what we're going to do.
+
+ switch $do_what {
+ "preprocess" {
+ set compile_type "preprocess"
+ set output_file "[file rootname [file tail $prog]].i"
+ }
+ "compile" {
+ set compile_type "assembly"
+ set output_file "[file rootname [file tail $prog]].s"
+ }
+ "assemble" {
+ set compile_type "object"
+ set output_file "[file rootname [file tail $prog]].o"
+ }
+ "link" {
+ set compile_type "executable"
+ set output_file "./[file rootname [file tail $prog]].exe"
+ }
+ "run" {
+ set compile_type "executable"
+ # FIXME: "./" is to cope with "." not being in $PATH.
+ # Should this be handled elsewhere?
+ # YES.
+ set output_file "./[file rootname [file tail $prog]].exe"
+ # This is the only place where we care if an executable was
+ # created or not. If it was, dg.exp will try to run it.
+ remote_file build delete $output_file;
+ }
+ default {
+ perror "$do_what: not a valid dg-do keyword"
+ return ""
+ }
+ }
+ set options ""
+ if { $extra_tool_flags != "" } {
+ lappend options "additional_flags=$extra_tool_flags"
+ }
+
+ set comp_output [libmudflap_target_compile "$prog" "$output_file" "$compile_type" $options];
+ set comp_output [prune_gcc_output $comp_output ];
+
+ return [list $comp_output $output_file]
+}
+
+
+proc libmudflap_target_compile { source dest type options } {
+ global gluefile
+ global wrap_flags
+ global cxx
+ global cxxflags
+ global includes
+ global libs
+ global blddir
+
+ if { [target_info needs_status_wrapper] != "" && [info exists gluefile] } {
+ lappend options "libs=${gluefile}"
+ lappend options "ldflags=${wrap_flags}"
+ }
+
+ set cxx_final $cxx
+ set cxxlibglossflags [libgloss_link_flags]
+ set cxx_final [concat $cxx_final $cxxlibglossflags]
+ set cxx_final [concat $cxx_final $cxxflags]
+ set cxx_final [concat $cxx_final $includes]
+ set cxx_final [concat $cxx_final $libs]
+
+ lappend options "compiler=$cxx_final"
+
+ # Picks up the freshly-built testsuite library corresponding to the
+ # multilib under test.
+ lappend options "ldflags=-L${blddir}/testsuite"
+
+ return [target_compile $source $dest $type $options]
+}
+
+
+# A bit sloppy... Returns a list of source files (full pathnames) to
+# compile. We mimic the mkcheck script in that the first time this is run,
+# all existing files are listed in "testsuite_files" in the output
+# directory. Subsequent runs pull the list from that file, allowing users
+# to trim the list down to problematic tests.
+### This is supposed to be done via RUNTESTFLAGS, but that doesn't work.
+proc libmudflap-list-sourcefiles { } {
+ global srcdir
+ global outdir
+
+ set files_file "${outdir}/testsuite_files"
+ set sfiles ""
+ if { [file exists $files_file] } {
+ set f [open $files_file]
+ while { ! [eof $f] } {
+ set t [gets $f]
+ if { [string length "$t"] != 0 } {
+ lappend sfiles ${srcdir}/${t}
+ }
+ }
+ } else {
+ set f [open $files_file "w"]
+ set where_we_were [pwd]
+ cd $srcdir
+ foreach s [lsort [glob -nocomplain "*/*.cc" "*/*/*.cc" "{,*/}*/*/*/*.cc" ]] {
+ lappend sfiles ${srcdir}/${s}
+ puts $f $s
+ }
+ cd $where_we_were
+ }
+ close $f
+
+ # Disable wchar_t tests if library not configured to support
+ # wchar_t testing.
+ set wchar_file "${outdir}/testsuite_wchar_t"
+ if { [file exists $wchar_file] } {
+ return $sfiles
+ } else {
+ # Remove wchar_t tests files from list.
+ set res {}
+ foreach w $sfiles {
+ if [regexp "wchar_t" $w] {
+ verbose "element out list is $w"
+ } else {
+ verbose "element in list is $w"
+ lappend res $w
+ }
+ }
+ return $res
+ }
+}
+
+
+proc prune_gcc_output { text } {
+
+ regsub -all {(^|\n)[^\n]*ld: warning: libgcc_s[^\n]*not found[^\n]*try using[^\n]*} $text "" text
+
+ regsub -all {(^|\n)[^\n]*In function.*pthread_create[^\n]*} $text "" text
+
+ regsub -all {(^|\n)[^\n]*the use of .pthread.*is deprecated[^\n]*} $text "" text
+
+ regsub -all {(^|\n)[^\n]*Dwarf Error:.*FORM value: 14[^\n]*} $text "" text
+
+ return $text
+}
diff --git a/libmudflap/testsuite/lib/mfdg.exp b/libmudflap/testsuite/lib/mfdg.exp
new file mode 100644
index 00000000000..25473d61269
--- /dev/null
+++ b/libmudflap/testsuite/lib/mfdg.exp
@@ -0,0 +1,377 @@
+# `mfdg' - overrides parts of general purpose testcase driver.
+# Copyright (C) 1994 - 2001, 2003 Free Software Foundation, Inc.
+
+# This program 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 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 program; if not, write to the Free Software
+# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+# This is a modified excerpt of dejagnu/lib/dg.exp.
+
+load_lib dg.exp
+
+
+# dg-test -- runs a new style DejaGnu test
+#
+# Syntax: dg-test [-keep-output] prog tool_flags default_extra_tool_flags
+#
+# PROG is the full path name of the file to pass to the tool (eg: compiler).
+# TOOL_FLAGS is a set of options to always pass.
+# DEFAULT_EXTRA_TOOL_FLAGS are additional options if the testcase has none.
+
+#proc dg-test { prog tool_flags default_extra_tool_flags } {
+proc dg-test { args } {
+ global dg-do-what-default dg-interpreter-batch-mode dg-linenum-format
+ global errorCode errorInfo
+ global tool
+ global srcdir ;# eg: /calvin/dje/build/gcc/./testsuite/
+ global host_triplet target_triplet
+
+ set keep 0
+ set i 0
+ set dg-repetitions 1 ;# may be overridden by { dg-repetitions N }
+ global dg-timeout
+ set dg-timeout 0 ;# likewise by { dg-timeout N }
+
+ if { [string index [lindex $args 0] 0] == "-" } {
+ for { set i 0 } { $i < [llength $args] } { incr i } {
+ if { [lindex $args $i] == "--" } {
+ incr i
+ break
+ } elseif { [lindex $args $i] == "-keep-output" } {
+ set keep 1
+ } elseif { [string index [lindex $args $i] 0] == "-" } {
+ clone_output "ERROR: dg-test: illegal argument: [lindex $args $i]"
+ return
+ } else {
+ break
+ }
+ }
+ }
+
+ if { $i + 3 != [llength $args] } {
+ clone_output "ERROR: dg-test: missing arguments in call"
+ return
+ }
+ set prog [lindex $args $i]
+ set tool_flags [lindex $args [expr $i + 1]]
+ set default_extra_tool_flags [lindex $args [expr $i + 2]]
+
+ set text "\[- A-Za-z0-9\.\;\"\_\:\'\`\(\)\!\#\=\+\?\&\*]*"
+
+ set name [dg-trim-dirname $srcdir $prog]
+ # If we couldn't rip $srcdir out of `prog' then just do the best we can.
+ # The point is to reduce the unnecessary noise in the logs. Don't strip
+ # out too much because different testcases with the same name can confuse
+ # `test-tool'.
+ if [string match "/*" $name] {
+ set name "[file tail [file dirname $prog]]/[file tail $prog]"
+ }
+
+ if {$tool_flags != ""} {
+ append name " ($tool_flags)"
+ }
+
+ # Process any embedded dg options in the testcase.
+
+ # Use "" for the second element of dg-do-what so we can tell if it's been
+ # explicitly set to "S".
+ set dg-do-what [list ${dg-do-what-default} "" P]
+ set dg-excess-errors-flag 0
+ set dg-messages ""
+ set dg-extra-tool-flags $default_extra_tool_flags
+ set dg-final-code ""
+
+ # `dg-output-text' is a list of two elements: pass/fail and text.
+ # Leave second element off for now (indicates "don't perform test")
+ set dg-output-text "P"
+
+ # Define our own "special function" `unknown' so we catch spelling errors.
+ # But first rename the existing one so we can restore it afterwards.
+ catch {rename dg-save-unknown ""}
+ rename unknown dg-save-unknown
+ proc unknown { args } {
+ return -code error "unknown dg option: $args"
+ }
+
+ set tmp [dg-get-options $prog]
+ foreach op $tmp {
+ verbose "Processing option: $op" 3
+ set status [catch "$op" errmsg]
+ if { $status != 0 } {
+ if { 0 && [info exists errorInfo] } {
+ # This also prints a backtrace which will just confuse
+ # testcase writers, so it's disabled.
+ perror "$name: $errorInfo\n"
+ } else {
+ perror "$name: $errmsg for \"$op\"\n"
+ }
+ # ??? The call to unresolved here is necessary to clear `errcnt'.
+ # What we really need is a proc like perror that doesn't set errcnt.
+ # It should also set exit_status to 1.
+ unresolved "$name: $errmsg for \"$op\""
+ return
+ }
+ }
+
+ # Restore normal error handling.
+ rename unknown ""
+ rename dg-save-unknown unknown
+
+ # If we're not supposed to try this test on this target, we're done.
+ if { [lindex ${dg-do-what} 1] == "N" } {
+ unsupported "$name"
+ verbose "$name not supported on this target, skipping it" 3
+ return
+ }
+
+ # Run the tool and analyze the results.
+ # The result of ${tool}-dg-test is in a bit of flux.
+ # Currently it is the name of the output file (or "" if none).
+ # If we need more than this it will grow into a list of things.
+ # No intention is made (at this point) to preserve upward compatibility
+ # (though at some point we'll have to).
+
+ set results [${tool}-dg-test $prog [lindex ${dg-do-what} 0] "$tool_flags ${dg-extra-tool-flags}"];
+
+ set comp_output [lindex $results 0];
+ set output_file [lindex $results 1];
+
+ #send_user "\nold_dejagnu.exp: comp_output1 = :$comp_output:\n\n"
+ #send_user "\nold_dejagnu.exp: message = :$message:\n\n"
+ #send_user "\nold_dejagnu.exp: message length = [llength $message]\n\n"
+
+ foreach i ${dg-messages} {
+ verbose "Scanning for message: $i" 4
+
+ # Remove all error messages for the line [lindex $i 0]
+ # in the source file. If we find any, success!
+ set line [lindex $i 0]
+ set pattern [lindex $i 2]
+ set comment [lindex $i 3]
+ #send_user "Before:\n$comp_output\n"
+ if [regsub -all "(^|\n)(\[^\n\]+$line\[^\n\]*($pattern)\[^\n\]*\n?)+" $comp_output "\n" comp_output] {
+ set comp_output [string trimleft $comp_output]
+ set ok pass
+ set uhoh fail
+ } else {
+ set ok fail
+ set uhoh pass
+ }
+ #send_user "After:\n$comp_output\n"
+
+ # $line will either be a formatted line number or a number all by
+ # itself. Delete the formatting.
+ scan $line ${dg-linenum-format} line
+ switch [lindex $i 1] {
+ "ERROR" {
+ $ok "$name $comment (test for errors, line $line)"
+ }
+ "XERROR" {
+ x$ok "$name $comment (test for errors, line $line)"
+ }
+ "WARNING" {
+ $ok "$name $comment (test for warnings, line $line)"
+ }
+ "XWARNING" {
+ x$ok "$name $comment (test for warnings, line $line)"
+ }
+ "BOGUS" {
+ $uhoh "$name $comment (test for bogus messages, line $line)"
+ }
+ "XBOGUS" {
+ x$uhoh "$name $comment (test for bogus messages, line $line)"
+ }
+ "BUILD" {
+ $uhoh "$name $comment (test for build failure, line $line)"
+ }
+ "XBUILD" {
+ x$uhoh "$name $comment (test for build failure, line $line)"
+ }
+ "EXEC" { }
+ "XEXEC" { }
+ }
+ #send_user "\nold_dejagnu.exp: comp_output2= :$comp_output:\n\n"
+ }
+ #send_user "\nold_dejagnu.exp: comp_output3 = :$comp_output:\n\n"
+
+ # Remove messages from the tool that we can ignore.
+ #send_user "comp_output: $comp_output\n"
+ set comp_output [prune_warnings $comp_output]
+
+ if { [info proc ${tool}-dg-prune] != "" } {
+ set comp_output [${tool}-dg-prune $target_triplet $comp_output]
+ switch -glob $comp_output {
+ "::untested::*" {
+ regsub "::untested::" $comp_output "" message
+ untested "$name: $message"
+ return
+ }
+ "::unresolved::*" {
+ regsub "::unresolved::" $comp_output "" message
+ unresolved "$name: $message"
+ return
+ }
+ "::unsupported::*" {
+ regsub "::unsupported::" $comp_output "" message
+ unsupported "$name: $message"
+ return
+ }
+ }
+ }
+
+ # See if someone forgot to delete the extra lines.
+ regsub -all "\n+" $comp_output "\n" comp_output
+ regsub "^\n+" $comp_output "" comp_output
+ #send_user "comp_output: $comp_output\n"
+
+ # Don't do this if we're testing an interpreter.
+ # FIXME: why?
+ if { ${dg-interpreter-batch-mode} == 0 } {
+ # Catch excess errors (new bugs or incomplete testcases).
+ if ${dg-excess-errors-flag} {
+ setup_xfail "*-*-*"
+ }
+ if ![string match "" $comp_output] {
+ fail "$name (test for excess errors)"
+ send_log "Excess errors:\n$comp_output\n"
+ } else {
+ pass "$name (test for excess errors)"
+ }
+ }
+
+ # Run the executable image if asked to do so.
+ # FIXME: This is the only place where we assume a standard meaning to
+ # the `keyword' argument of dg-do. This could be cleaned up.
+ if { [lindex ${dg-do-what} 0] == "run" } {
+ if ![file exists $output_file] {
+ warning "$name compilation failed to produce executable"
+ } else {
+ set testname $name
+ for {set rep 0} {$rep < ${dg-repetitions}} {incr rep} {
+ # include repetition number in test name
+ if {$rep > 0} { set name "$testname (rerun $rep)" }
+
+ set status -1
+ set result [${tool}_load $output_file]
+ set status [lindex $result 0];
+ set output [lindex $result 1];
+ #send_user "After exec, status: $status\n"
+
+ if { "$status" == "pass" } {
+ verbose "Exec succeeded." 3
+ } elseif { "$status" == "fail" } {
+ # It would be nice to get some info out of errorCode.
+ if [info exists errorCode] {
+ verbose "Exec failed, errorCode: $errorCode" 3
+ } else {
+ verbose "Exec failed, errorCode not defined!" 3
+ }
+ }
+
+ if { [lindex ${dg-do-what} 2] == "F" } {
+ # Instead of modelling this as an xfail (via setup_xfail),
+ # treat an expected crash as a success.
+ if { $status == "pass" } then { set status fail } else { set status pass }
+ set testtype "crash"
+ } else { set testtype "execution" }
+
+ $status "$name $testtype test"
+
+ if { [llength ${dg-output-text}] > 1 } {
+ #send_user "${dg-output-text}\n"
+ if { [lindex ${dg-output-text} 0] == "F" } {
+ setup_xfail "*-*-*"
+ }
+ set texttmp [lindex ${dg-output-text} 1]
+ if { ![regexp $texttmp ${output}] } {
+ fail "$name output pattern test"
+ } else {
+ pass "$name output pattern test"
+ }
+ verbose -log "Output pattern $texttmp"
+ unset texttmp
+ }
+ }
+ }
+ }
+
+ # Are there any further tests to perform?
+ # Note that if the program has special run-time requirements, running
+ # of the program can be delayed until here. Ditto for other situations.
+ # It would be a bit cumbersome though.
+
+ if ![string match ${dg-final-code} ""] {
+ regsub -all "\\\\(\[{}\])" ${dg-final-code} "\\1" dg-final-code
+ # Note that the use of `args' here makes this a varargs proc.
+ proc dg-final-proc { args } ${dg-final-code}
+ verbose "Running dg-final tests." 3
+ verbose "dg-final-proc:\n[info body dg-final-proc]" 4
+ if [catch "dg-final-proc $prog" errmsg] {
+ perror "$name: error executing dg-final: $errmsg"
+ # ??? The call to unresolved here is necessary to clear `errcnt'.
+ # What we really need is a proc like perror that doesn't set errcnt.
+ # It should also set exit_status to 1.
+ unresolved "$name: error executing dg-final: $errmsg"
+ }
+ }
+
+ # Do some final clean up.
+ # When testing an interpreter, we don't compile something and leave an
+ # output file.
+ if { ! ${keep} && ${dg-interpreter-batch-mode} == 0 } {
+ catch "exec rm -f $output_file"
+ }
+}
+
+
+
+#
+# Indicate that this test case is to be rerun several times. This
+# is useful if it is nondeterministic. This applies to rerunning the
+# test program only, not rebuilding it.
+# The embedded format is "{ dg-repetitions N }", where N is the number
+# of repetitions. It better be greater than zero.
+#
+proc dg-repetitions { line value } {
+ upvar dg-repetitions repetitions
+ set repetitions $value
+}
+
+
+#
+# Indicate that this test case is to be run with a short timeout.
+# The embedded format is "{ dg-timeout N }", where N is in seconds.
+#
+proc dg-timeout { line value } {
+ global dg-timeout
+ set dg-timeout $value
+}
+
+
+# dejagnu's config/unix.exp hard-codes 300 seconds as the timeout
+# for any natively run executable. That's too long for tests run
+# multiple times and that may possibly hang. So we override it here
+# to provide some degree of control.
+rename standard_wait hooked_standard_wait
+proc standard_wait { dest timeout } {
+ global dg-timeout
+ if {[info exists dg-timeout]} {
+ if {${dg-timeout} > 0} {
+ verbose -log "Overriding timeout = ${dg-timeout}"
+ set timeout ${dg-timeout}
+ }
+ }
+
+ hooked_standard_wait $dest $timeout
+}
diff --git a/libmudflap/testsuite/libmudflap.c++/c++frags.exp b/libmudflap/testsuite/libmudflap.c++/c++frags.exp
new file mode 100644
index 00000000000..5d8be05245c
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c++/c++frags.exp
@@ -0,0 +1,16 @@
+
+libmudflap-init [find_g++]
+
+dg-init
+
+global srcdir
+
+foreach flags [list {} {-static} {-O2} {-O3}] {
+ foreach srcfile [lsort [glob -nocomplain ${srcdir}/libmudflap.c++/*.cxx]] {
+ set bsrc [file tail $srcfile]
+ setenv MUDFLAP_OPTIONS "-no-heur-proc-map -viol-segv"
+ dg-runtest $srcfile $flags "-fmudflap"
+ }
+}
+
+dg-finish
diff --git a/libmudflap/testsuite/libmudflap.c++/fail24-frag.cxx b/libmudflap/testsuite/libmudflap.c++/fail24-frag.cxx
new file mode 100644
index 00000000000..e3467ddaf1a
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c++/fail24-frag.cxx
@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+char zoo [10];
+
+int main ()
+{
+int i = strlen ("twelve") + strlen ("zero") + strlen ("seventeen");
+zoo[i] = 'a';
+return 0;
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object.*" } */
+/* { dg-output "mudflap object.*zoo.*static.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c++/pass27-frag.cxx b/libmudflap/testsuite/libmudflap.c++/pass27-frag.cxx
new file mode 100644
index 00000000000..aca2ea3a3b6
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c++/pass27-frag.cxx
@@ -0,0 +1,12 @@
+class foo {
+ char z [10];
+public:
+ char *get_z () { return & this->z[0]; }
+};
+
+int main ()
+{
+foo x;
+x.get_z()[9] = 'a';
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c++/pass28-frag.cxx b/libmudflap/testsuite/libmudflap.c++/pass28-frag.cxx
new file mode 100644
index 00000000000..75e14ba1460
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c++/pass28-frag.cxx
@@ -0,0 +1,20 @@
+class foo {
+ char z [10];
+public:
+ virtual char *get_z () { return & this->z[0]; }
+};
+
+class bar: public foo {
+ char q [20];
+public:
+ char *get_z () { return & this->q[0]; }
+};
+
+int main () {
+foo *x = new bar ();
+
+x->get_z()[9] = 'a';
+
+delete x;
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c++/pass31-frag.cxx b/libmudflap/testsuite/libmudflap.c++/pass31-frag.cxx
new file mode 100644
index 00000000000..6c4b9f9a7f8
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c++/pass31-frag.cxx
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+char zoo [10];
+
+int main ()
+{
+int i = strlen ("eight") + strlen ("one");
+zoo[i] = 'a';
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c++/pass41-frag.cxx b/libmudflap/testsuite/libmudflap.c++/pass41-frag.cxx
new file mode 100644
index 00000000000..d15b98f1cdd
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c++/pass41-frag.cxx
@@ -0,0 +1,10 @@
+#include <string>
+#include <iostream>
+
+int
+main (int argc, char *argv[])
+{
+ std::string myStr = "Hello, World!";
+ std::cout << myStr << std::endl;
+ return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/cfrags.exp b/libmudflap/testsuite/libmudflap.c/cfrags.exp
new file mode 100644
index 00000000000..bef2f91c312
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/cfrags.exp
@@ -0,0 +1,15 @@
+
+libmudflap-init [find_gcc]
+
+dg-init
+
+global srcdir
+foreach flags [list {} {-static} {-O2} {-O3}] {
+ foreach srcfile [lsort [glob -nocomplain ${srcdir}/libmudflap.c/*.c]] {
+ set bsrc [file tail $srcfile]
+ setenv MUDFLAP_OPTIONS "-viol-segv"
+ dg-runtest $srcfile $flags "-fmudflap"
+ }
+}
+
+dg-finish
diff --git a/libmudflap/testsuite/libmudflap.c/fail1-frag.c b/libmudflap/testsuite/libmudflap.c/fail1-frag.c
new file mode 100644
index 00000000000..1e48fff8771
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail1-frag.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+volatile int foo [10];
+foo[10] = 0;
+return 0;
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*.main. foo.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail10-frag.c b/libmudflap/testsuite/libmudflap.c/fail10-frag.c
new file mode 100644
index 00000000000..db135d5c451
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail10-frag.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+volatile int foo[10];
+int sz = sizeof (int);
+
+volatile char *bar = (char *)foo;
+bar [sz * 10] = 0;
+return 0;
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*.main. foo.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail11-frag.c b/libmudflap/testsuite/libmudflap.c/fail11-frag.c
new file mode 100644
index 00000000000..72038fdba30
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail11-frag.c
@@ -0,0 +1,19 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+int i = 10;
+char *x = (char *) malloc (i * sizeof (char));
+
+while (i--)
+{
+ ++x;
+ *x = 0;
+}
+return 0;
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*malloc region.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail12-frag.c b/libmudflap/testsuite/libmudflap.c/fail12-frag.c
new file mode 100644
index 00000000000..da8bfb7c046
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail12-frag.c
@@ -0,0 +1,19 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+int i = 10;
+int *x = (int *) malloc (i * sizeof (int));
+
+while (i--)
+{
+ ++x;
+ *x = 0;
+}
+return 0;
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*malloc region.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail13-frag.c b/libmudflap/testsuite/libmudflap.c/fail13-frag.c
new file mode 100644
index 00000000000..9fd3e255712
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail13-frag.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+struct a {
+ int x;
+ int y;
+ char z;
+};
+
+struct b {
+ int x;
+ int y;
+};
+
+struct b k;
+
+(*((volatile struct a *) &k)).z = 'q';
+
+return 0;
+}
+/* { dg-output "mudflap violation 1..check/write.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*.main. k.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail14-frag.c b/libmudflap/testsuite/libmudflap.c/fail14-frag.c
new file mode 100644
index 00000000000..e66cc94c49b
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail14-frag.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+struct a {
+ int x;
+ int y;
+ char z;
+};
+
+struct b {
+ int x;
+ int y;
+};
+
+volatile struct b k;
+volatile struct a *p;
+
+p = (struct a*) &k;
+
+p->z = 'q';
+
+return 0;
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*.main. k.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail15-frag.c b/libmudflap/testsuite/libmudflap.c/fail15-frag.c
new file mode 100644
index 00000000000..5d7ae744973
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail15-frag.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+struct base {
+ int basic;
+};
+
+struct derived {
+ struct base common;
+ char extra;
+};
+
+volatile struct base b;
+volatile struct base *bp;
+
+bp = (struct base *)&b;
+
+bp->basic = 10;
+((struct derived volatile *)bp)->extra = 'x';
+return 0;
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*.main. b.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail16-frag.c b/libmudflap/testsuite/libmudflap.c/fail16-frag.c
new file mode 100644
index 00000000000..317e2744731
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail16-frag.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+struct base {
+ int basic;
+};
+
+struct derived {
+ struct base common;
+ char extra;
+};
+
+struct base *bp;
+
+bp = (struct base *) malloc (sizeof (struct base));;
+
+bp->basic = 10;
+((struct derived *)bp)->extra = 'x';
+return 0;
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*.malloc region.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail17-frag.c b/libmudflap/testsuite/libmudflap.c/fail17-frag.c
new file mode 100644
index 00000000000..5af67f13858
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail17-frag.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+
+char * x;
+int foo;
+x = (char *) malloc (10);
+strcpy (x, "123456789");
+foo = strlen (x+10);
+x [foo] = 1; /* we just just use foo to force execution of strlen */
+return 0;
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*.malloc region.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail18-frag.c b/libmudflap/testsuite/libmudflap.c/fail18-frag.c
new file mode 100644
index 00000000000..dde150a8457
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail18-frag.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+/* One cannot redeclare __mf_lc_mask in proper C from instrumented
+ code, because of the way the instrumentation code emits its decls. */
+extern unsigned foo __asm__ ("__mf_lc_mask");
+unsigned *bar = &foo;
+*bar = 4;
+return 0;
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*.__mf_lc_mask.*no-access.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail19-frag.c b/libmudflap/testsuite/libmudflap.c/fail19-frag.c
new file mode 100644
index 00000000000..7e446b40503
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail19-frag.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+struct foo {
+ int bar [10];
+};
+
+struct foo *k = (struct foo *) malloc (2 * sizeof(int));
+k->bar[5] = 9;
+free (k);
+return 0;
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*.malloc region.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail2-frag.c b/libmudflap/testsuite/libmudflap.c/fail2-frag.c
new file mode 100644
index 00000000000..7672e60c602
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail2-frag.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+volatile int foo [10][10];
+foo[10][0] = 0;
+return 0;
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*.main. foo.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail20-frag.c b/libmudflap/testsuite/libmudflap.c/fail20-frag.c
new file mode 100644
index 00000000000..0dd8bb7f983
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail20-frag.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+volatile char *p = (char *) 0;
+*p = 5;
+return 0;
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*.NULL.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail21-frag.c b/libmudflap/testsuite/libmudflap.c/fail21-frag.c
new file mode 100644
index 00000000000..4ab4a09f3b0
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail21-frag.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+ int *bar = (int *) malloc (sizeof (int));
+/* Make an access here to get &foo into the lookup cache. */
+*bar = 5;
+__mf_watch (bar, sizeof(int));
+/* This access should trigger the watch violation. */
+*bar = 10;
+/* NOTREACHED */
+return 0;
+}
+/* { dg-output "mudflap violation 1.*watch.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*malloc region.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail22-frag.c b/libmudflap/testsuite/libmudflap.c/fail22-frag.c
new file mode 100644
index 00000000000..7dd7103d359
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail22-frag.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+struct boo { int a; };
+int c;
+struct boo *b = malloc (sizeof (struct boo));
+__mf_set_options ("-check-initialization");
+c = b->a;
+(void) malloc (c); /* some dummy use of c */
+return 0;
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*.malloc region.*1r/0w.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail23-frag.c b/libmudflap/testsuite/libmudflap.c/fail23-frag.c
new file mode 100644
index 00000000000..bb1b52ec7e0
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail23-frag.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+char zoo [10];
+
+int main ()
+{
+int i = strlen ("012345") + strlen ("6789") + strlen ("01"); /* 11 */
+zoo[i] = 'a';
+return 0;
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object.*" } */
+/* { dg-output "mudflap object.*zoo.*static.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail25-frag.c b/libmudflap/testsuite/libmudflap.c/fail25-frag.c
new file mode 100644
index 00000000000..acac5236b42
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail25-frag.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+char *foo;
+char *bar;
+__mf_set_options ("-check-initialization");
+foo = (char *)malloc (10);
+bar = (char *)malloc (10);
+/* bar[2] = 'z'; */ /* don't touch memcpy source */
+memcpy(foo+1, bar+1, 9);
+return 0;
+}
+/* { dg-output "mudflap violation 1.*check.read.*memcpy source.*" } */
+/* { dg-output "Nearby object.*" } */
+/* { dg-output "mudflap object.*malloc region.*alloc time.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail26-frag.c b/libmudflap/testsuite/libmudflap.c/fail26-frag.c
new file mode 100644
index 00000000000..88484d6adc4
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail26-frag.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+char *foo;
+
+__mf_set_options ("-check-initialization");
+foo = (char *)malloc (1);
+
+/* These two operations each expand to a read-modify-write.
+ * Even though the end result is that every bit of foo[0] is
+ * eventually written to deterministically, the first read
+ * triggers an uninit error. Ideally, it shouldn't, so this
+ * should be treated more like a regular XFAIL. */
+foo[0] &= 0xfe;
+foo[0] |= 0x01;
+
+return foo[0];
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object.*" } */
+/* { dg-output "mudflap object.*malloc region.*1r/0w.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail27-frag.c b/libmudflap/testsuite/libmudflap.c/fail27-frag.c
new file mode 100644
index 00000000000..7168dfc61b2
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail27-frag.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+char volatile *
+__attribute__((noinline))
+foo (unsigned i)
+{
+ char volatile buffer[10];
+ char volatile *k = i ? & buffer[i] : NULL; /* defeat addr-of-local-returned warning */
+ return k;
+}
+
+int main ()
+{
+char volatile *f = foo (5);
+f[0] = 'b';
+
+return 0;
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object.*" } */
+/* { dg-output "mudflap object.*buffer.*alloc.*dealloc" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail28-frag.c b/libmudflap/testsuite/libmudflap.c/fail28-frag.c
new file mode 100644
index 00000000000..7d61c57f34b
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail28-frag.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int foo (int *u, int i)
+{
+ return u[i]; /* this dereference should be instrumented */
+}
+
+int main ()
+{
+int *k = malloc (6);
+return foo (k, 8);
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object.*" } */
+/* { dg-output "mudflap object.*malloc region.*alloc" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail29-frag.c b/libmudflap/testsuite/libmudflap.c/fail29-frag.c
new file mode 100644
index 00000000000..2024064dc73
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail29-frag.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int foo (int u[10])
+{
+ return u[8]; /* this dereference should be instrumented */
+}
+
+int main ()
+{
+int *k = malloc (6);
+return foo (k);
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object.*" } */
+/* { dg-output "mudflap object.*malloc region.*alloc" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail3-frag.c b/libmudflap/testsuite/libmudflap.c/fail3-frag.c
new file mode 100644
index 00000000000..98c1dbae165
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail3-frag.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+volatile int foo [10][10][10];
+foo[9][10][0] = 0;
+return 0;
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*.main. foo.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail30-frag.c b/libmudflap/testsuite/libmudflap.c/fail30-frag.c
new file mode 100644
index 00000000000..8bfea61cbb2
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail30-frag.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int foo (int u)
+{
+ return u*u;
+}
+
+int main ()
+{
+int *k = malloc(5);
+int j = foo (k[8]); /* this call argument should be instrumented */
+return j;
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object.*" } */
+/* { dg-output "mudflap object.*malloc region.*alloc" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail31-frag.c b/libmudflap/testsuite/libmudflap.c/fail31-frag.c
new file mode 100644
index 00000000000..b15056c970c
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail31-frag.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+extern int h (int i, int j);
+
+int main ()
+{
+ int z = h (4, 10);
+ return 0;
+}
+
+int h (int i, int j)
+{
+ int k[i];
+ k[j] = i;
+ return j;
+}
+
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object.*" } */
+/* { dg-output "mudflap object.*\(h\).*k" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail4-frag.c b/libmudflap/testsuite/libmudflap.c/fail4-frag.c
new file mode 100644
index 00000000000..a3423e6c36b
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail4-frag.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+char foo [10];
+strcpy(foo, "1234567890");
+return 0;
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*.main. foo.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail5-frag.c b/libmudflap/testsuite/libmudflap.c/fail5-frag.c
new file mode 100644
index 00000000000..a08569fe773
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail5-frag.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+char foo [15];
+char bar [10];
+memcpy(foo, bar, 11);
+return 0;
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*.main. bar.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail6-frag.c b/libmudflap/testsuite/libmudflap.c/fail6-frag.c
new file mode 100644
index 00000000000..1904a88711a
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail6-frag.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+char *foo;
+char *bar;
+foo = (char *)malloc (10);
+bar = (char *)malloc (15);
+
+memcpy(foo, bar, 11);
+return 0;
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*malloc region.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail7-frag.c b/libmudflap/testsuite/libmudflap.c/fail7-frag.c
new file mode 100644
index 00000000000..580d045386d
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail7-frag.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+char *foo;
+char *bar;
+foo = (char *)malloc (12);
+bar = (char *)malloc (10);
+
+memcpy(foo+1, bar+1, 10);
+return 0;
+}
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*malloc region.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail8-frag.c b/libmudflap/testsuite/libmudflap.c/fail8-frag.c
new file mode 100644
index 00000000000..cc2fbdaac4c
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail8-frag.c
@@ -0,0 +1,19 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+char *foo;
+char *bar;
+foo = (char *)malloc (10);
+bar = (char *)malloc (10);
+
+free(bar);
+
+memcpy(foo, bar, 10);
+return 0;
+}
+/* { dg-output "mudflap violation 1.*memcpy source.*" } */
+/* { dg-output "Nearby object.*" } */
+/* { dg-output "mudflap object.*malloc region.*alloc time.*dealloc time.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/fail9-frag.c b/libmudflap/testsuite/libmudflap.c/fail9-frag.c
new file mode 100644
index 00000000000..029fda5d4d0
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/fail9-frag.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+char *foo;
+char *bar;
+foo = (char *)malloc (10);
+bar = (char *)malloc (10);
+
+free(foo);
+
+bar[4] = 'a'; /* touch source buffer */
+memcpy(foo, bar, 10);
+return 0;
+}
+
+/* { dg-output "mudflap violation 1.*memcpy dest.*" } */
+/* { dg-output "Nearby object.*" } */
+/* { dg-output "mudflap object.*malloc region.*alloc time.*dealloc time.*" } */
+/* { dg-do run { xfail *-*-* } } */
diff --git a/libmudflap/testsuite/libmudflap.c/hook-allocstuff.c b/libmudflap/testsuite/libmudflap.c/hook-allocstuff.c
new file mode 100644
index 00000000000..dc25375488d
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/hook-allocstuff.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int main ()
+{
+ char *foo = (char *) malloc (10);
+ strcpy (foo, "hello");
+ foo = (char *) realloc (foo, 20);
+ printf ("%s", foo);
+ if (strcmp (foo, "hello"))
+ abort ();
+ free (foo);
+ printf (" world\n");
+ return 0;
+}
+/* { dg-output "hello world" } */
diff --git a/libmudflap/testsuite/libmudflap.c/pass-stratcliff.c b/libmudflap/testsuite/libmudflap.c/pass-stratcliff.c
new file mode 100644
index 00000000000..894f10ffa96
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass-stratcliff.c
@@ -0,0 +1,319 @@
+/* Test for string function add boundaries of usable memory.
+ Copyright (C) 1996,1997,1999,2000,2001,2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define _GNU_SOURCE 1
+#define __USE_GNU
+
+/* Make sure we don't test the optimized inline functions if we want to
+ test the real implementation. */
+#undef __USE_STRING_INLINES
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/param.h>
+
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
+int
+main (int argc, char *argv[])
+{
+ int size = sysconf (_SC_PAGESIZE);
+ char *adr, *dest;
+ int result = 0;
+
+ adr = (char *) mmap (NULL, 3 * size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANON, -1, 0);
+ dest = (char *) mmap (NULL, 3 * size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANON, -1, 0);
+ if (adr == MAP_FAILED || dest == MAP_FAILED)
+ {
+ if (errno == ENOSYS)
+ puts ("No test, mmap not available.");
+ else
+ {
+ printf ("mmap failed: %m");
+ result = 1;
+ }
+ }
+ else
+ {
+ int inner, middle, outer;
+
+ mprotect(adr, size, PROT_NONE);
+ mprotect(adr + 2 * size, size, PROT_NONE);
+ adr += size;
+
+ mprotect(dest, size, PROT_NONE);
+ mprotect(dest + 2 * size, size, PROT_NONE);
+ dest += size;
+
+ memset (adr, 'T', size);
+
+ /* strlen test */
+ for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
+ {
+ for (inner = MAX (outer, size - 64); inner < size; ++inner)
+ {
+ adr[inner] = '\0';
+
+ if (strlen (&adr[outer]) != (size_t) (inner - outer))
+ {
+ printf ("strlen flunked for outer = %d, inner = %d\n",
+ outer, inner);
+ result = 1;
+ }
+
+ adr[inner] = 'T';
+ }
+ }
+
+ /* strchr test */
+ for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
+ {
+ for (middle = MAX (outer, size - 64); middle < size; ++middle)
+ {
+ for (inner = middle; inner < size; ++inner)
+ {
+ char *cp;
+ adr[middle] = 'V';
+ adr[inner] = '\0';
+
+ cp = strchr (&adr[outer], 'V');
+
+ if ((inner == middle && cp != NULL)
+ || (inner != middle
+ && (cp - &adr[outer]) != middle - outer))
+ {
+ printf ("strchr flunked for outer = %d, middle = %d, "
+ "inner = %d\n", outer, middle, inner);
+ result = 1;
+ }
+
+ adr[inner] = 'T';
+ adr[middle] = 'T';
+ }
+ }
+ }
+
+ /* Special test. */
+ adr[size - 1] = '\0';
+ if (strchr (&adr[size - 1], '\n') != NULL)
+ {
+ puts ("strchr flunked for test of empty string at end of page");
+ result = 1;
+ }
+
+ /* strrchr test */
+ for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
+ {
+ for (middle = MAX (outer, size - 64); middle < size; ++middle)
+ {
+ for (inner = middle; inner < size; ++inner)
+ {
+ char *cp;
+ adr[middle] = 'V';
+ adr[inner] = '\0';
+
+ cp = strrchr (&adr[outer], 'V');
+
+ if ((inner == middle && cp != NULL)
+ || (inner != middle
+ && (cp - &adr[outer]) != middle - outer))
+ {
+ printf ("strrchr flunked for outer = %d, middle = %d, "
+ "inner = %d\n", outer, middle, inner);
+ result = 1;
+ }
+
+ adr[inner] = 'T';
+ adr[middle] = 'T';
+ }
+ }
+ }
+
+#ifndef __FreeBSD__
+ /* rawmemchr test */
+ for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
+ {
+ for (middle = MAX (outer, size - 64); middle < size; ++middle)
+ {
+ char *cp;
+ adr[middle] = 'V';
+
+ cp = (char *) rawmemchr (&adr[outer], 'V');
+
+ if (cp - &adr[outer] != middle - outer)
+ {
+ printf ("rawmemchr flunked for outer = %d, middle = %d\n",
+ outer, middle);
+ result = 1;
+ }
+
+ adr[middle] = 'T';
+ }
+ }
+#endif
+
+ /* strcpy test */
+ for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
+ {
+ for (inner = MAX (outer, size - 64); inner < size; ++inner)
+ {
+ adr[inner] = '\0';
+
+ if (strcpy (dest, &adr[outer]) != dest
+ || strlen (dest) != (size_t) (inner - outer))
+ {
+ printf ("strcpy flunked for outer = %d, inner = %d\n",
+ outer, inner);
+ result = 1;
+ }
+
+ adr[inner] = 'T';
+ }
+ }
+
+ /* strncpy tests */
+ adr[size-1] = 'T';
+ for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
+ {
+ size_t len;
+
+ for (len = 0; len < size - outer; ++len)
+ {
+ if (strncpy (dest, &adr[outer], len) != dest
+ || memcmp (dest, &adr[outer], len) != 0)
+ {
+ printf ("outer strncpy flunked for outer = %d, len = %Zd\n",
+ outer, len);
+ result = 1;
+ }
+ }
+ }
+ adr[size-1] = '\0';
+
+ for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
+ {
+ for (inner = MAX (outer, size - 64); inner < size; ++inner)
+ {
+ size_t len;
+
+ adr[inner] = '\0';
+
+ for (len = 0; len < size - outer + 64; ++len)
+ {
+ if (strncpy (dest, &adr[outer], len) != dest
+ || memcmp (dest, &adr[outer],
+ MIN (inner - outer, len)) != 0
+ || (inner - outer < len
+ && strlen (dest) != (inner - outer)))
+ {
+ printf ("strncpy flunked for outer = %d, inner = %d, len = %Zd\n",
+ outer, inner, len);
+ result = 1;
+ }
+ if (strncpy (dest + 1, &adr[outer], len) != dest + 1
+ || memcmp (dest + 1, &adr[outer],
+ MIN (inner - outer, len)) != 0
+ || (inner - outer < len
+ && strlen (dest + 1) != (inner - outer)))
+ {
+ printf ("strncpy+1 flunked for outer = %d, inner = %d, len = %Zd\n",
+ outer, inner, len);
+ result = 1;
+ }
+ }
+
+ adr[inner] = 'T';
+ }
+ }
+
+#ifndef __FreeBSD__
+ /* stpcpy test */
+ for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
+ {
+ for (inner = MAX (outer, size - 64); inner < size; ++inner)
+ {
+ adr[inner] = '\0';
+
+ if ((stpcpy (dest, &adr[outer]) - dest) != inner - outer)
+ {
+ printf ("stpcpy flunked for outer = %d, inner = %d\n",
+ outer, inner);
+ result = 1;
+ }
+
+ adr[inner] = 'T';
+ }
+ }
+
+ /* stpncpy test */
+ for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
+ {
+ for (middle = MAX (outer, size - 64); middle < size; ++middle)
+ {
+ adr[middle] = '\0';
+
+ for (inner = 0; inner < size - outer; ++ inner)
+ {
+ if ((stpncpy (dest, &adr[outer], inner) - dest)
+ != MIN (inner, middle - outer))
+ {
+ printf ("stpncpy flunked for outer = %d, middle = %d, "
+ "inner = %d\n", outer, middle, inner);
+ result = 1;
+ }
+ }
+
+ adr[middle] = 'T';
+ }
+ }
+#endif
+
+ /* memcpy test */
+ for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
+ for (inner = 0; inner < size - outer; ++inner)
+ if (memcpy (dest, &adr[outer], inner) != dest)
+ {
+ printf ("memcpy flunked for outer = %d, inner = %d\n",
+ outer, inner);
+ result = 1;
+ }
+
+#ifndef __FreeBSD__
+ /* mempcpy test */
+ for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
+ for (inner = 0; inner < size - outer; ++inner)
+ if (mempcpy (dest, &adr[outer], inner) != dest + inner)
+ {
+ printf ("mempcpy flunked for outer = %d, inner = %d\n",
+ outer, inner);
+ result = 1;
+ }
+#endif
+ }
+
+ return result;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass1-frag.c b/libmudflap/testsuite/libmudflap.c/pass1-frag.c
new file mode 100644
index 00000000000..40f629b56da
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass1-frag.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+int foo [10];
+foo[9] = 0;
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass10-frag.c b/libmudflap/testsuite/libmudflap.c/pass10-frag.c
new file mode 100644
index 00000000000..f05650da515
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass10-frag.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+int foo[10];
+int sz = sizeof (int);
+
+char *bar = (char *)foo;
+bar [sz * 9] = 0;
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass11-frag.c b/libmudflap/testsuite/libmudflap.c/pass11-frag.c
new file mode 100644
index 00000000000..ab7ee38c4f8
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass11-frag.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+int i = 10;
+char *x = (char *) malloc (i * sizeof (char));
+
+while (--i)
+{
+ ++x;
+ *x = 0;
+}
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass12-frag.c b/libmudflap/testsuite/libmudflap.c/pass12-frag.c
new file mode 100644
index 00000000000..53630d9971d
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass12-frag.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+int i = 10;
+int *x = (int *) malloc (i * sizeof (int));
+
+while (--i)
+{
+ ++x;
+ *x = 0;
+}
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass13-frag.c b/libmudflap/testsuite/libmudflap.c/pass13-frag.c
new file mode 100644
index 00000000000..c2b820d0f43
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass13-frag.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+struct a {
+ int x;
+ int y;
+ char z;
+};
+
+struct a k;
+
+k.z = 'q';
+
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass14-frag.c b/libmudflap/testsuite/libmudflap.c/pass14-frag.c
new file mode 100644
index 00000000000..26456432979
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass14-frag.c
@@ -0,0 +1,20 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+struct a {
+ int x;
+ int y;
+ char z;
+};
+
+struct a k;
+struct a *p;
+
+p = &k;
+
+p->z = 'q';
+
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass15-frag.c b/libmudflap/testsuite/libmudflap.c/pass15-frag.c
new file mode 100644
index 00000000000..5e1fee8eb9c
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass15-frag.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+struct base {
+ int basic;
+};
+
+struct derived {
+ struct base common;
+ char extra;
+};
+
+struct derived d;
+struct base *bp;
+
+bp = (struct base *)&d;
+
+bp->basic = 10;
+((struct derived *)bp)->extra = 'x';
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass16-frag.c b/libmudflap/testsuite/libmudflap.c/pass16-frag.c
new file mode 100644
index 00000000000..99ede3f2138
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass16-frag.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+struct base {
+ int basic;
+};
+
+struct derived {
+ struct base common;
+ char extra;
+};
+
+struct base *bp;
+
+bp = (struct base *) malloc (sizeof (struct derived));
+
+bp->basic = 10;
+((struct derived *)bp)->extra = 'x';
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass17-frag.c b/libmudflap/testsuite/libmudflap.c/pass17-frag.c
new file mode 100644
index 00000000000..b840dc98746
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass17-frag.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+
+strlen("123456789");
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass18-frag.c b/libmudflap/testsuite/libmudflap.c/pass18-frag.c
new file mode 100644
index 00000000000..c5d5af0fe12
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass18-frag.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+int t;
+char foo[3] = { 'b', 'c', 'd' };
+int bar[3] = {1, 2, 0};
+t = 1;
+
+/* These tests check expression evaluation rules, such as
+ ensuring that side-effect expression (++) get executed the
+ right number of times; that array lookup checks nest correctly. */
+foo[t++] = 'a';
+if (foo[0] != 'b' || foo[1] != 'a' || foo[2] != 'd' || t != 2) abort ();
+if (bar[0] != 1 || bar[1] != 2 || bar[2] != 0) abort();
+
+foo[bar[t--]] = 'e';
+if (foo[0] != 'e' || foo[1] != 'a' || foo[2] != 'd' || t != 1) abort ();
+if (bar[0] != 1 || bar[1] != 2 || bar[2] != 0) abort();
+
+foo[bar[++t]--] = 'g';
+if (foo[0] != 'g' || foo[1] != 'a' || foo[2] != 'd' || t != 2) abort ();
+if (bar[0] != 1 || bar[1] != 2 || bar[2] != -1) abort();
+
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass19-frag.c b/libmudflap/testsuite/libmudflap.c/pass19-frag.c
new file mode 100644
index 00000000000..0b00845d412
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass19-frag.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+struct foo {int base; char variable[1]; }; /* a common idiom for variable-size structs */
+
+struct foo * b = (struct foo *) malloc (sizeof (int)); /* enough for base */
+b->base = 4;
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass2-frag.c b/libmudflap/testsuite/libmudflap.c/pass2-frag.c
new file mode 100644
index 00000000000..7e71e0cd7b5
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass2-frag.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+int foo [10][10];
+foo[9][0] = 0;
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass20-frag.c b/libmudflap/testsuite/libmudflap.c/pass20-frag.c
new file mode 100644
index 00000000000..98431168548
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass20-frag.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+struct bar {int stuff; int array[10]; };
+
+struct bar *foo = (struct bar *) malloc (sizeof (struct bar));
+foo->array[5] = 4;
+free (foo);
+
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass21-frag.c b/libmudflap/testsuite/libmudflap.c/pass21-frag.c
new file mode 100644
index 00000000000..231055a236f
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass21-frag.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifndef __FreeBSD__
+#include <alloca.h>
+#endif
+int main ()
+{
+char *boo, *foo;
+boo = (char *) alloca (100);
+boo[99] = 'a';
+foo = (char *) __builtin_alloca (200);
+foo[44] = 'b';
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass22-frag.c b/libmudflap/testsuite/libmudflap.c/pass22-frag.c
new file mode 100644
index 00000000000..b092ea0b277
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass22-frag.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+struct foo {
+ unsigned base:8;
+ unsigned flag1:1;
+ unsigned flag2:3;
+ unsigned flag3:4;
+ char nothing[0];
+};
+
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) 0)->MEMBER)
+
+struct foo* f = (struct foo *) malloc (offsetof (struct foo, nothing));
+f->base = 1;
+f->flag1 = 1;
+free (f);
+
+
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass23-frag.c b/libmudflap/testsuite/libmudflap.c/pass23-frag.c
new file mode 100644
index 00000000000..f27c223614b
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass23-frag.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+struct foo {
+ int part1: 8;
+ int nothing : 1;
+ int part2 : 5;
+ int lots_more_nothing : 3;
+ int some_padding; /* for 64-bit hosts */
+ float some_more_nothing;
+ double yet_more_nothing;
+};
+
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) 0)->MEMBER)
+
+struct foo* q = (struct foo *) malloc (offsetof (struct foo, some_more_nothing));
+q->nothing = 1; /* touch q */
+/* The RHS of the following expression is meant to trigger a
+ fold-const.c mapping the expression to a BIT_FIELD_REF. It glues
+ together the accesses to the two non-neighbouring bitfields into a
+ single bigger boolean test. */
+q->lots_more_nothing = (q->part1 == 13 && q->part2 == 7);
+free (q);
+
+
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass24-frag.c b/libmudflap/testsuite/libmudflap.c/pass24-frag.c
new file mode 100644
index 00000000000..00385822130
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass24-frag.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+struct foo {
+ int zoo;
+ int bar [10];
+ float baz;
+};
+
+#define offsetof(S,F) ((size_t) & (((S *) 0)->F))
+
+struct foo *k = (struct foo *) malloc (offsetof (struct foo, bar[4]));
+k->bar[1] = 9;
+free (k);
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass25-frag.c b/libmudflap/testsuite/libmudflap.c/pass25-frag.c
new file mode 100644
index 00000000000..c5a75e3338e
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass25-frag.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+int *foo = malloc (10 * sizeof(int));
+int *bar = & foo[3];
+/* Watching occurs at the object granularity, which is in this case
+ the entire array. */
+__mf_watch (& foo[1], sizeof(foo[1]));
+__mf_unwatch (& foo[6], sizeof(foo[6]));
+*bar = 10;
+free (foo);
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass26-frag.c b/libmudflap/testsuite/libmudflap.c/pass26-frag.c
new file mode 100644
index 00000000000..5a72f5b790c
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass26-frag.c
@@ -0,0 +1,52 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+volatile int *p;
+
+__mf_set_options ("-wipe-stack -no-check-initialization");
+
+{
+ volatile int array [10];
+ p = & array[0];
+
+ array[0] = 2;
+ array[9] = 5;
+
+ /* Array[] should be wiped clean at this point. */
+}
+
+__mf_set_options ("-no-wipe-stack");
+
+{
+ volatile int array2[10];
+
+ /* hope that this is allocated on top of old array[] */
+ if (p != & array2[0])
+ exit (0); /* Test is not applicable. */
+
+ array2[5] = 6;
+
+ /* Old values shouldn't still be around; the new one should. */
+ if (p[0] == 2 || p[9] == 5 || p[5] != 6)
+ abort() ;
+
+ /* array2[] should not be wiped at this point! */
+}
+
+{
+ volatile int array3[10];
+
+ /* hope that this is allocated on top of old array[] and array2[]*/
+ if (p != & array3[0])
+ exit (0); /* Test is not applicable. */
+
+ array3[1] = 2;
+
+ /* Check that old assignment is still around. */
+ if (p[5] != 6 || p[1] != 2)
+ abort() ;
+}
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass29-frag.c b/libmudflap/testsuite/libmudflap.c/pass29-frag.c
new file mode 100644
index 00000000000..97bed6eb373
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass29-frag.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+struct boo { int a; };
+int c;
+struct boo *b = malloc (sizeof (struct boo));
+__mf_set_options ("-check-initialization");
+b->a = 0;
+/* That __mf_set_options call could be here instead. */
+c = b->a;
+(void) malloc (c); /* some dummy use of c */
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass3-frag.c b/libmudflap/testsuite/libmudflap.c/pass3-frag.c
new file mode 100644
index 00000000000..4e950a2c5d8
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass3-frag.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+int foo [10][10][10];
+foo[9][9][0] = 0;
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass30-frag.c b/libmudflap/testsuite/libmudflap.c/pass30-frag.c
new file mode 100644
index 00000000000..6c4b9f9a7f8
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass30-frag.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+char zoo [10];
+
+int main ()
+{
+int i = strlen ("eight") + strlen ("one");
+zoo[i] = 'a';
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass32-frag.c b/libmudflap/testsuite/libmudflap.c/pass32-frag.c
new file mode 100644
index 00000000000..83f121d4fa2
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass32-frag.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct foo { char z[10]; };
+
+char * get_z (struct foo *this)
+{
+ return & this->z[0] /* the `this' pointer is not dereferenced! */;
+}
+
+int main ()
+{
+struct foo k;
+char *n = get_z (& k);
+srand ((int)(uintptr_t) n); /* use the pointer value */
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass33-frag.c b/libmudflap/testsuite/libmudflap.c/pass33-frag.c
new file mode 100644
index 00000000000..95d762cc1aa
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass33-frag.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+void test (int *k)
+{
+ if (*k > 5) { *k --; }
+}
+
+int main ()
+{
+int z;
+/* z is initialized, but not via a pointer, so not instrumented */
+z = rand ();
+test (& z);
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass34-frag.c b/libmudflap/testsuite/libmudflap.c/pass34-frag.c
new file mode 100644
index 00000000000..2dfd0ca2113
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass34-frag.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+void test (int *k)
+{
+ if (*k > 5) { *k --; }
+}
+
+int z;
+
+int main ()
+{
+/* z is initialized, but not via a pointer, so not instrumented */
+z = rand ();
+test (& z);
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass35-frag.c b/libmudflap/testsuite/libmudflap.c/pass35-frag.c
new file mode 100644
index 00000000000..4744ecdbe99
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass35-frag.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern char end []; /* Any old symbol we're sure will be defined. */
+/* { dg-warning "cannot track lifetime of `end'" "cannot track lifetime" { target *-*-* } 0 } */
+
+int main ()
+{
+/* dummy register */
+__mf_register ((void *) end, 1, __MF_TYPE_GUESS, "end");
+char z = end[0];
+return z & 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass36-frag.c b/libmudflap/testsuite/libmudflap.c/pass36-frag.c
new file mode 100644
index 00000000000..68d1a7f8080
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass36-frag.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+
+int main ()
+{
+char *k;
+__mf_set_options ("-sigusr1-report -print-leaks");
+k = (char *) malloc (100);
+raise (SIGUSR1);
+free (k);
+return 0;
+}
+/* { dg-output "Leaked object.*name=.malloc region.*objects: 1" } */
diff --git a/libmudflap/testsuite/libmudflap.c/pass38-frag.c b/libmudflap/testsuite/libmudflap.c/pass38-frag.c
new file mode 100644
index 00000000000..a250234da8a
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass38-frag.c
@@ -0,0 +1,9 @@
+/* Test an odd construct for compilability. */
+static void *fwd;
+void *bwd = &fwd;
+static void *fwd = &bwd;
+
+int main ()
+{
+ return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass4-frag.c b/libmudflap/testsuite/libmudflap.c/pass4-frag.c
new file mode 100644
index 00000000000..0a40d1c425a
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass4-frag.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+char foo[10];
+strcpy (foo, "123456789");
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass42-frag.c b/libmudflap/testsuite/libmudflap.c/pass42-frag.c
new file mode 100644
index 00000000000..1045c47c37a
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass42-frag.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+void
+foo ()
+{
+ putc ('h', stdout);
+ putc ('i', stdout);
+ putc ('\n', stdout);
+}
+
+int
+main (int argc, char *argv[])
+{
+ foo ();
+ return 0;
+}
+/* { dg-output "hi" } */
diff --git a/libmudflap/testsuite/libmudflap.c/pass43-frag.c b/libmudflap/testsuite/libmudflap.c/pass43-frag.c
new file mode 100644
index 00000000000..4fec3306eb1
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass43-frag.c
@@ -0,0 +1,11 @@
+void
+foo ()
+{
+}
+
+int
+main (int argc, char *argv[])
+{
+ foo ();
+ return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass44-frag.c b/libmudflap/testsuite/libmudflap.c/pass44-frag.c
new file mode 100644
index 00000000000..338d6da63bf
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass44-frag.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+void
+foo ()
+{
+ return; /* accept value-less return statement */
+}
+
+int
+main (int argc, char *argv[])
+{
+ foo ();
+ return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass45-frag.c b/libmudflap/testsuite/libmudflap.c/pass45-frag.c
new file mode 100644
index 00000000000..c6bfeb5048c
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass45-frag.c
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern void h (const char *p, const char *f);
+int
+main (void)
+{
+ h (0, "foo");
+ return 0;
+}
+
+void
+h (const char *p, const char *f)
+{
+ size_t pl = p == NULL ? 0 : strlen (p);
+ size_t fl = strlen (f) + 1;
+ char a[pl + 1 + fl];
+ char *cp = a;
+ char b[pl + 5 + fl * 2];
+ char *cccp = b;
+ if (p != NULL)
+ {
+ cp = memcpy (cp, p, pl);
+ *cp++ = ':';
+ }
+ memcpy (cp, f, fl);
+ strcpy (b, a);
+ puts (a);
+}
+/* { dg-output "foo" } */
diff --git a/libmudflap/testsuite/libmudflap.c/pass46-frag.c b/libmudflap/testsuite/libmudflap.c/pass46-frag.c
new file mode 100644
index 00000000000..a1f24be1dc0
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass46-frag.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int foo (int *u, int i)
+{
+ return u[i]; /* this dereference should not be instrumented */
+}
+
+int main ()
+{
+ int *k = malloc (6);
+ int l = foo (k, 8);
+ int boo [8];
+ int m = boo [l % 2 + 12]; /* should not be instrumented */
+ return m & strlen (""); /* a fancy way of saying "0" */
+}
+/* { dg-options "-fmudflap -fmudflapir -Wall" } */
diff --git a/libmudflap/testsuite/libmudflap.c/pass5-frag.c b/libmudflap/testsuite/libmudflap.c/pass5-frag.c
new file mode 100644
index 00000000000..6d3408a4e52
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass5-frag.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+char foo [10];
+char bar [10];
+bar[4] = 'k'; /* touch memcpy source */
+memcpy(foo, bar, 10);
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass6-frag.c b/libmudflap/testsuite/libmudflap.c/pass6-frag.c
new file mode 100644
index 00000000000..9b07fe2de22
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass6-frag.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+char *foo;
+char *bar;
+
+foo = (char *)malloc (10);
+bar = (char *)malloc (10);
+bar[2] = 'z'; /* touch memcpy source */
+memcpy(foo, bar, 10);
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass7-frag.c b/libmudflap/testsuite/libmudflap.c/pass7-frag.c
new file mode 100644
index 00000000000..36197339e88
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass7-frag.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+char *foo;
+char *bar;
+foo = (char *)malloc (10);
+bar = (char *)malloc (10);
+bar[2] = 'z'; /* touch memcpy source */
+memcpy(foo+1, bar+1, 9);
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass8-frag.c b/libmudflap/testsuite/libmudflap.c/pass8-frag.c
new file mode 100644
index 00000000000..6be4e93f000
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass8-frag.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+char *foo;
+char *bar;
+foo = (char *)malloc (10);
+bar = (char *)malloc (10);
+
+free(bar);
+bar = (char *)malloc (10);
+bar[6] = 'k'; /* touch memcpy source */
+memcpy(foo, bar, 10);
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.c/pass9-frag.c b/libmudflap/testsuite/libmudflap.c/pass9-frag.c
new file mode 100644
index 00000000000..9186e062ff8
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.c/pass9-frag.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+int main ()
+{
+char *foo;
+char *bar;
+foo = (char *)malloc (10);
+bar = (char *)malloc (10);
+
+free(foo);
+foo = (char *)malloc (10);
+bar[3] = 'w'; /* touch memcpy source */
+memcpy(foo, bar, 10);
+return 0;
+}
diff --git a/libmudflap/testsuite/libmudflap.cth/cthfrags.exp b/libmudflap/testsuite/libmudflap.cth/cthfrags.exp
new file mode 100644
index 00000000000..508d8eced10
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.cth/cthfrags.exp
@@ -0,0 +1,23 @@
+
+libmudflap-init [find_gcc]
+
+dg-init
+
+global srcdir
+foreach flags [list {} {-static -DSTATIC} {-O2} {-O3}] {
+ foreach srcfile [lsort [glob -nocomplain ${srcdir}/libmudflap.cth/*.c]] {
+ set bsrc [file tail $srcfile]
+ setenv MUDFLAP_OPTIONS "-viol-segv"
+ if {$libmudflapth} then {
+ # --noinhibit-exec works around a ld problem that causes
+ # "Dwarf Error: Invalid or unhandled FORM value: 14"
+ # to fail builds unnecessarily.
+ dg-runtest $srcfile $flags "-fmudflapth -Wl,--noinhibit-exec"
+ } else {
+ if {$flags != ""} {set f " ($flags)"} {set f ""}
+ untested "libmudflap.cth/$bsrc$f"
+ }
+ }
+}
+
+dg-finish
diff --git a/libmudflap/testsuite/libmudflap.cth/pass37-frag.c b/libmudflap/testsuite/libmudflap.cth/pass37-frag.c
new file mode 100644
index 00000000000..bfa2c7c02ab
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.cth/pass37-frag.c
@@ -0,0 +1,58 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <sched.h>
+
+static void *
+func (void *p)
+{
+ int *counter = (int *) p;
+ unsigned i;
+
+ for (i=0; i<100; i++)
+ {
+ (*counter) ++;
+ {
+ int array[17];
+ unsigned x = i % (sizeof(array)/sizeof(array[0]));
+ /* VRP could prove that x is within [0,16], but until then, the
+ following access will ensure that array[] is registered to
+ libmudflap. */
+ array[x] = i;
+ }
+ sched_yield (); /* sleep (1); */
+ }
+
+ return (NULL);
+}
+
+
+int main ()
+{
+ int rc;
+ unsigned i;
+ enum foo { NT=10 };
+ pthread_t threads[NT];
+ int counts[NT];
+
+
+ for (i=0; i<NT; i++)
+ {
+ counts[i] = 0;
+ rc = pthread_create (& threads[i], NULL, func, (void *) & counts[i]);
+ if (rc) abort();
+ }
+
+ for (i=0; i<NT; i++)
+ {
+ rc = pthread_join (threads[i], NULL);
+ if (rc) abort();
+ printf ("%d%s", counts[i], (i==NT-1) ? "\n" : " ");
+ }
+
+ return 0;
+}
+
+/* { dg-output "100 100 100 100 100 100 100 100 100 100" } */
+/* { dg-repetitions 20 } */
+/* { dg-timeout 3 } */
diff --git a/libmudflap/testsuite/libmudflap.cth/pass39-frag.c b/libmudflap/testsuite/libmudflap.cth/pass39-frag.c
new file mode 100644
index 00000000000..eb3449e9d8b
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.cth/pass39-frag.c
@@ -0,0 +1,57 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <sched.h>
+#include <assert.h>
+
+static void *
+func (void *p)
+{
+ int *counter = (int *) p;
+ unsigned i;
+ enum { numarrays = 100, numels = 17 };
+ char *arrays [numarrays];
+
+ for (i=0; i<numarrays; i++)
+ {
+ (*counter) ++;
+ unsigned x = i % numels;
+ arrays[i] = calloc (numels, sizeof(arrays[i][0]));
+ assert (arrays[i] != NULL);
+ arrays[i][x] = i;
+ free (arrays[i]);
+ sched_yield (); /* sleep (1); */
+ }
+
+ return (NULL);
+}
+
+
+int main ()
+{
+ int rc;
+ unsigned i;
+ enum foo { NT=10 };
+ pthread_t threads[NT];
+ int counts[NT];
+
+
+ for (i=0; i<NT; i++)
+ {
+ counts[i] = 0;
+ rc = pthread_create (& threads[i], NULL, func, (void *) & counts[i]);
+ if (rc) abort();
+ }
+
+ for (i=0; i<NT; i++)
+ {
+ rc = pthread_join (threads[i], NULL);
+ if (rc) abort();
+ printf ("%d%s", counts[i], (i==NT-1) ? "\n" : " ");
+ }
+
+ return 0;
+}
+/* { dg-output "100 100 100 100 100 100 100 100 100 100" } */
+/* { dg-repetitions 20 } */
+/* { dg-timeout 3 } */
diff --git a/libmudflap/testsuite/libmudflap.cth/pass40-frag.c b/libmudflap/testsuite/libmudflap.cth/pass40-frag.c
new file mode 100644
index 00000000000..4bba4d350ae
--- /dev/null
+++ b/libmudflap/testsuite/libmudflap.cth/pass40-frag.c
@@ -0,0 +1,59 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+
+static void *
+func (void *p)
+{
+ return (NULL);
+}
+
+static void
+test (void)
+{
+ int rc;
+ pthread_attr_t my_pthread_attr;
+ pthread_t h;
+ long i;
+
+ rc = pthread_attr_init (&my_pthread_attr);
+
+ for (i = 1; i <= 10000; ++i) {
+ if (i%100 == 0) fprintf (stderr, "%i ", i);
+ if (i%1000 == 0) fprintf (stderr, "\n");
+#ifndef STATIC
+ /* Some glibc versions don't like static multithreaded programs doing this. */
+ if (i==5000) __mf_set_options ("-thread-stack=192");
+#endif
+ rc = pthread_create (&h, &my_pthread_attr,
+ func, NULL);
+ if (rc)
+ break;
+
+ rc = pthread_join (h, NULL);
+ if (rc)
+ break;
+ }
+
+ rc = pthread_attr_destroy (&my_pthread_attr);
+}
+
+int main ()
+{
+ test ();
+
+ return (0);
+}
+
+/* { dg-timeout 20 } */
+/* { dg-output "100 200 300 400 500 600 700 800 900 1000 \n" } */
+/* { dg-output "1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 \n" } */
+/* { dg-output "2100 2200 2300 2400 2500 2600 2700 2800 2900 3000 \n" } */
+/* { dg-output "3100 3200 3300 3400 3500 3600 3700 3800 3900 4000 \n" } */
+/* { dg-output "4100 4200 4300 4400 4500 4600 4700 4800 4900 5000 \n" } */
+/* { dg-output "5100 5200 5300 5400 5500 5600 5700 5800 5900 6000 \n" } */
+/* { dg-output "6100 6200 6300 6400 6500 6600 6700 6800 6900 7000 \n" } */
+/* { dg-output "7100 7200 7300 7400 7500 7600 7700 7800 7900 8000 \n" } */
+/* { dg-output "8100 8200 8300 8400 8500 8600 8700 8800 8900 9000 \n" } */
+/* { dg-output "9100 9200 9300 9400 9500 9600 9700 9800 9900 10000 \n" } */
+
diff --git a/libobjc/ChangeLog b/libobjc/ChangeLog
index 4dc49ccdb3b..89855331180 100644
--- a/libobjc/ChangeLog
+++ b/libobjc/ChangeLog
@@ -1,3 +1,24 @@
+2004-05-13 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * archive.c (objc_read_class): Initialize class_name.
+ (objc_read_selector): Initialize selector_name.
+
+2004-05-09 Richard Sandiford <rsandifo@redhat.com>
+
+ * Makefile.in (toolexecdir): Remove trailing space.
+
+2004-04-15 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ PR libobjc/14948
+ * configure.ac: De-precious CC so multilibs work.
+ * configure: Regenerate.
+
+2004-04-14 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.ac: Restore toolexecdir.
+ * Makefile.in: Restore toolexecdir.
+ * configure: Regenerate.
+
2004-04-09 Nathanael Nerode <neroden@gcc.gnu.org>
* configure.ac: Remove (unused) glibcpp_prefixdir.
diff --git a/libobjc/Makefile.in b/libobjc/Makefile.in
index 16e882ccb28..c014a2dcfc8 100644
--- a/libobjc/Makefile.in
+++ b/libobjc/Makefile.in
@@ -36,6 +36,8 @@ target_noncanonical = @target_noncanonical@
gcc_version = @gcc_version@
top_srcdir = @top_srcdir@
toplevel_srcdir = @toplevel_srcdir@
+toolexecdir = @toolexecdir@
+# Toolexecdir is used only by toolexeclibdir
toolexeclibdir = @toolexeclibdir@
top_builddir = .
diff --git a/libobjc/archive.c b/libobjc/archive.c
index aca648ec669..f4245041fc5 100644
--- a/libobjc/archive.c
+++ b/libobjc/archive.c
@@ -887,7 +887,7 @@ objc_read_class (struct objc_typed_stream *stream, Class *class)
if (buf[0] == (_B_EXT | _BX_CLASS))
{
- char *class_name;
+ char *class_name = "";
unsigned long version;
/* get class */
@@ -938,7 +938,7 @@ objc_read_selector (struct objc_typed_stream *stream, SEL* selector)
if (buf[0] == (_B_EXT|_BX_SEL)) /* selector! */
{
- char *selector_name;
+ char *selector_name = "";
/* get selector */
len = objc_read_string (stream, &selector_name);
diff --git a/libobjc/configure b/libobjc/configure
index b5920110a4b..36f7c94fd18 100755
--- a/libobjc/configure
+++ b/libobjc/configure
@@ -309,7 +309,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS VERSION OBJC_BOEHM_GC toplevel_srcdir build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os target_noncanonical glibcpp_srcdir gcc_version toolexeclibdir CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT AS ac_ct_AS AR ac_ct_AR RANLIB ac_ct_RANLIB INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S STRIP ac_ct_STRIP LIBTOOL SET_MAKE CPP EGREP GTHREAD_FLAGS LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS VERSION OBJC_BOEHM_GC toplevel_srcdir build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os target_noncanonical glibcpp_srcdir gcc_version toolexecdir toolexeclibdir CC ac_ct_CC EXEEXT OBJEXT CFLAGS AS ac_ct_AS AR ac_ct_AR RANLIB ac_ct_RANLIB INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S STRIP ac_ct_STRIP LIBTOOL SET_MAKE CPP CPPFLAGS EGREP GTHREAD_FLAGS LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@@ -750,26 +750,14 @@ ac_env_target_alias_set=${target_alias+set}
ac_env_target_alias_value=$target_alias
ac_cv_env_target_alias_set=${target_alias+set}
ac_cv_env_target_alias_value=$target_alias
-ac_env_CC_set=${CC+set}
-ac_env_CC_value=$CC
-ac_cv_env_CC_set=${CC+set}
-ac_cv_env_CC_value=$CC
-ac_env_CFLAGS_set=${CFLAGS+set}
-ac_env_CFLAGS_value=$CFLAGS
-ac_cv_env_CFLAGS_set=${CFLAGS+set}
-ac_cv_env_CFLAGS_value=$CFLAGS
-ac_env_LDFLAGS_set=${LDFLAGS+set}
-ac_env_LDFLAGS_value=$LDFLAGS
-ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
-ac_cv_env_LDFLAGS_value=$LDFLAGS
-ac_env_CPPFLAGS_set=${CPPFLAGS+set}
-ac_env_CPPFLAGS_value=$CPPFLAGS
-ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
-ac_cv_env_CPPFLAGS_value=$CPPFLAGS
ac_env_CPP_set=${CPP+set}
ac_env_CPP_value=$CPP
ac_cv_env_CPP_set=${CPP+set}
ac_cv_env_CPP_value=$CPP
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
#
# Report the --help message.
@@ -963,7 +951,7 @@ esac
else
echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
fi
- cd "$ac_popdir"
+ cd $ac_popdir
done
fi
@@ -1553,19 +1541,23 @@ gcc_version=`echo ${gcc_version_full} | sed -e 's/\(^ *\) .*/\1/'`
# Calculate toolexeclibdir
+# Also toolexecdir, though it's only used in toolexeclibdir
case ${version_specific_libs} in
yes)
# Need the gcc compiler version to know where to install libraries
# and header files if --enable-version-specific-runtime-libs option
# is selected.
+ toolexecdir='$(libdir)/gcc/$(target_noncanonical)'
toolexeclibdir='$(toolexecdir)/'${gcc_version}'$(MULTISUBDIR)'
;;
no)
if test -n "$with_cross_host" &&
test x"$with_cross_host" != x"no"; then
# Install a library built with a cross compiler in tooldir, not libdir.
+ toolexecdir='$(exec_prefix)/$(target_noncanonical)'
toolexeclibdir='$(toolexecdir)/lib'
else
+ toolexecdir='$(libdir)/gcc-lib/$(target_noncanonical)'
toolexeclibdir='$(libdir)'
fi
multi_os_directory=`$CC -print-multi-os-directory`
@@ -1577,11 +1569,18 @@ case ${version_specific_libs} in
esac
+
# --------
# Programs
# --------
+
+# We must force CC to /not/ be a precious variable; otherwise
+# the wrong, non-multilib-adjusted value will be used in multilibs.
+# As a side effect, we have to subst CFLAGS ourselves.
+
+
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -2184,7 +2183,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2242,7 +2242,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2358,7 +2359,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2412,7 +2414,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2457,7 +2460,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2501,7 +2505,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2541,6 +2546,9 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
set dummy ${ac_tool_prefix}as; ac_word=$2
@@ -3145,7 +3153,7 @@ darwin* | rhapsody*)
lt_cv_deplibs_check_method=pass_all
;;
-freebsd* )
+freebsd* | kfreebsd*-gnu)
if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
case $host_cpu in
i*86 )
@@ -3213,7 +3221,7 @@ linux-gnu*)
lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
;;
-netbsd*)
+netbsd* | knetbsd*-gnu)
if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'
else
@@ -3605,7 +3613,7 @@ test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic"
case $host in
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 3608 "configure"' > conftest.$ac_ext
+ echo '#line 3616 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -3752,7 +3760,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -4214,7 +4223,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -4384,7 +4394,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -4447,7 +4458,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -4604,7 +4616,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -4771,7 +4784,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5597,14 +5611,13 @@ s,@target_os@,$target_os,;t t
s,@target_noncanonical@,$target_noncanonical,;t t
s,@glibcpp_srcdir@,$glibcpp_srcdir,;t t
s,@gcc_version@,$gcc_version,;t t
+s,@toolexecdir@,$toolexecdir,;t t
s,@toolexeclibdir@,$toolexeclibdir,;t t
s,@CC@,$CC,;t t
-s,@CFLAGS@,$CFLAGS,;t t
-s,@LDFLAGS@,$LDFLAGS,;t t
-s,@CPPFLAGS@,$CPPFLAGS,;t t
s,@ac_ct_CC@,$ac_ct_CC,;t t
s,@EXEEXT@,$EXEEXT,;t t
s,@OBJEXT@,$OBJEXT,;t t
+s,@CFLAGS@,$CFLAGS,;t t
s,@AS@,$AS,;t t
s,@ac_ct_AS@,$ac_ct_AS,;t t
s,@AR@,$AR,;t t
@@ -5620,6 +5633,7 @@ s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t
s,@LIBTOOL@,$LIBTOOL,;t t
s,@SET_MAKE@,$SET_MAKE,;t t
s,@CPP@,$CPP,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
s,@EGREP@,$EGREP,;t t
s,@GTHREAD_FLAGS@,$GTHREAD_FLAGS,;t t
s,@LIBOBJS@,$LIBOBJS,;t t
@@ -5790,6 +5804,11 @@ esac
*) ac_INSTALL=$ac_top_builddir$INSTALL ;;
esac
+ if test x"$ac_file" != x-; then
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ rm -f "$ac_file"
+ fi
# Let's still pretend it is `configure' which instantiates (i.e., don't
# use $as_me), people would be surprised to read:
# /* config.h. Generated by config.status. */
@@ -5828,12 +5847,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
fi;;
esac
done` || { (exit 1); exit 1; }
-
- if test x"$ac_file" != x-; then
- { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
- rm -f "$ac_file"
- fi
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
sed "$ac_vpsub
diff --git a/libobjc/configure.ac b/libobjc/configure.ac
index f58dafe2614..e6d65fa5e83 100644
--- a/libobjc/configure.ac
+++ b/libobjc/configure.ac
@@ -125,19 +125,23 @@ gcc_version=`echo ${gcc_version_full} | sed -e 's/\([^ ]*\) .*/\1/'`
AC_SUBST(gcc_version)
# Calculate toolexeclibdir
+# Also toolexecdir, though it's only used in toolexeclibdir
case ${version_specific_libs} in
yes)
# Need the gcc compiler version to know where to install libraries
# and header files if --enable-version-specific-runtime-libs option
# is selected.
+ toolexecdir='$(libdir)/gcc/$(target_noncanonical)'
toolexeclibdir='$(toolexecdir)/'${gcc_version}'$(MULTISUBDIR)'
;;
no)
if test -n "$with_cross_host" &&
test x"$with_cross_host" != x"no"; then
# Install a library built with a cross compiler in tooldir, not libdir.
+ toolexecdir='$(exec_prefix)/$(target_noncanonical)'
toolexeclibdir='$(toolexecdir)/lib'
else
+ toolexecdir='$(libdir)/gcc-lib/$(target_noncanonical)'
toolexeclibdir='$(libdir)'
fi
multi_os_directory=`$CC -print-multi-os-directory`
@@ -147,6 +151,7 @@ case ${version_specific_libs} in
esac
;;
esac
+AC_SUBST(toolexecdir)
AC_SUBST(toolexeclibdir)
# --------
@@ -154,7 +159,16 @@ AC_SUBST(toolexeclibdir)
# --------
GCC_NO_EXECUTABLES
+
+# We must force CC to /not/ be a precious variable; otherwise
+# the wrong, non-multilib-adjusted value will be used in multilibs.
+# As a side effect, we have to subst CFLAGS ourselves.
+m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
+m4_define([_AC_ARG_VAR_PRECIOUS],[])
AC_PROG_CC
+m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
+
+AC_SUBST(CFLAGS)
AC_CHECK_TOOL(AS, as)
AC_CHECK_TOOL(AR, ar)
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 67bff0fb323..6b447610520 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,329 @@
+2004-05-14 Paolo Carlini <pcarlini@suse.de>
+ Ivan Godard <igodard@pacbell.net>
+
+ PR libstdc++/15361
+ * include/std/std_bitset.h (_Base_bitset<_Nw>::_M_do_find_next): Fix.
+ * testsuite/23_containers/bitset/ext/15361.cc: New.
+
+2004-05-13 Benjamin Kosnik <bkoz@redhat.com>
+
+ PR libstdc++/15046
+ * crossconfig.m4: Add C99 math bits for linux crosses.
+ * configure: Regenerate.
+
+2004-05-13 Simon Marshall <simon.marshall@misys.com>
+ Benjamin Kosnik <bkoz@redhat.com>
+
+ PR libstdc++/15090
+ * include/bits/locale_facets.h: Fix for -fno-for-scope.
+ * include/debug/safe_sequence.h: Same.
+ * include/debug/safe_iterator.tcc: Same.
+ * src/debug.cc: Same.
+ * src/locale.cc: Same.
+ * src/locale_init.cc: Same.
+ * src/localename.cc: Same.
+ * config/locale/gnu/ctype_members.cc: Same.
+ * config/locale/gnu/numeric_members.cc: Same.
+ * testsuite/testsuite_abi.cc: Same.
+ * testsuite/testsuite_hooks.cc: Same.
+
+2004-05-13 Jonathan Wakely <redi@gcc.gnu.org>
+
+ * docs/html/abi.html: Document effect of -fabi-version on value
+ of __GXX_ABI_VERSION, and that it's defined in c-cppbuiltin.c.
+ Fix markup.
+
+2004-05-13 Benjamin Kosnik <bkoz@redhat.com>
+
+ PR libstdc++/15074
+ * docs/html/faq/index.html: Update docs for libsupc++ usage.
+
+2004-05-13 Benjamin Kosnik <bkoz@redhat.com>
+
+ PR libstdc++/15412
+ * include/bits/stl_threads.h (_GLIBCXX_mutex): Move to namespace
+ __gnu_internal.
+ (_GLIBCXX_mutex_address): Same.
+ (_GLIBCXX_once): Same.
+ (_GLIBCXX_mutex_init): Same.
+ (_GLIBCXX_mutex_address_init): Same.
+
+2004-05-13 Benjamin Kosnik <bkoz@redhat.com>
+
+ * docs/html/abi.html: New.
+ * docs/html/abi.txt: Remove.
+ * docs/html/documentation.html: Add link.
+ * testsuite/Makefile.am: Add files.
+ * testsuite/Makefile.in: Regenerated.
+ * testsuite/abi_check.cc: Move and modify code into...
+ * testsuite/testsuite_abi.cc: Add.
+ * testsuite/testsuite_abi.h: Add.
+
+ * docs/html/17_intro/TODO: Update.
+ * include/bits/stl_pair.h: Format.
+
+2004-05-06 Matthias Klose <doko@debian.org>
+
+ * include/backward/iterator.h: Add GPL copyright info,
+ with exception clause.
+ * include/bits/boost_concept_check.h: Likewise.
+ * include
+ * libsupc++/tinfo.h: Likewise.
+ * po/string_literals.cc: Likewise.
+
+2004-05-03 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * acinclude.m4: Replace -W with more speaking -Wextra.
+ * configure: Rebuilt.
+
+2004-05-03 Paolo Carlini <pcarlini@suse.de>
+
+ Optimize locale::_M_impl->_M_names for the most common cases:
+ !_M_names[0] means unnamed; !_M_names[1] means all the categories
+ the same name (_M_names[0] && _M_names[1] means that the full set
+ of _M_names must be processed, the general case).
+ * include/bits/locale_classes.h (locale::_Impl::_M_check_same_name):
+ Tweak, saving work when !_M_names[1].
+ (locale::locale(const locale&, _Facet*): Simplify: now just setting
+ _M_names[0] = 0 means unnamed.
+ * src/locale.cc (locale::operator==): Deal first with the common,
+ easy cases, otherwise fall back to locale::name().
+ (locale::name()): Tweak, if !_M_names[0] just return "*".
+ (locale::_Impl::_Impl(const _Impl&, size_t): Tweak, early stop
+ copying __imp._M_names if !__imp._M_names[0] or !__imp._M_names[1].
+ * src/locale_init.cc (locale::_Impl::_Impl(size_t)): Tweak.
+ * src/localename.cc (locale::_Impl::_Impl(const char*, size_t):
+ Simplify when !std::strchr, just updating _M_names[0]; clean up.
+ (locale::_Impl::_M_replace_categories): When !_M_names[1] prepare
+ for the general case (full set of names), then do the usual work;
+ clean up.
+
+ * src/locale.cc (locale::name()): Reserve space in __ret.
+ * src/locale_init.cc (locale::global(const locale&)): Save
+ the name in a temporary.
+ * src/localename.cc (locale::locale(const char*)): Reserve space
+ in __str.
+
+2004-04-29 Paolo Carlini <pcarlini@suse.de>
+
+ * src/locale.cc (locale::operator==): Always avoid constructing
+ locale::name(), directly compare pairs of _M_names.
+
+2004-04-26 Paolo Carlini <pcarlini@suse.de>
+
+ * include/bits/istream.tcc: Fix comment.
+
+2004-04-26 Paolo Carlini <pcarlini@suse.de>
+
+ * include/bits/stl_vector.h: Trivial formatting fixes.
+ * include/bits/vector.tcc: Likewise.
+
+2004-04-25 Paolo Carlini <pcarlini@suse.de>
+
+ PR libstdc++/15002 (continued again)
+ * include/bits/istream.tcc (getline(basic_istream<>&,
+ basic_string<>&, _CharT)): Use a temporary buffer, thus
+ avoiding reallocation for common case.
+
+ * include/bits/basic_string.tcc (_S_construct(_InIterator,
+ _InIterator, const _Alloc&, input_iterator_tag)): Tweak size
+ of temporary buffer to a power of two.
+
+ * testsuite/27_io/basic_istream/getline/char/4.cc: Add comment.
+
+2004-04-25 Paolo Carlini <pcarlini@suse.de>
+
+ * testsuite/21_strings/basic_string/inserters_extractors/char/10.cc:
+ New.
+ * testsuite/21_strings/basic_string/inserters_extractors/wchar_t/10.cc:
+ Likewise.
+ * testsuite/27_io/basic_istream/getline/char/5.cc: Likewise.
+
+2004-04-24 Paolo Carlini <pcarlini@suse.de>
+ Petur Runolfsson <peturr02@ru.is>
+
+ PR libstdc++/15002 (continued)
+ * include/bits/istream.tcc (basic_istream<>::getline(char_type*,
+ streamsize, char_type)): Use traits::find/copy in a loop to speed
+ up greatly the function in the common case (I/O buffer size >> 1).
+
+2004-04-24 Paolo Carlini <pcarlini@suse.de>
+
+ * testsuite/27_io/basic_istream/getline/char/4.cc: New.
+
+ * include/bits/istream.tcc (getline(basic_istream<>&,
+ basic_string<>&, _CharT)): Change to use sgetc()/snextc() instead
+ of sbumpc(), consistently with the other functions, thus also
+ dealing correctly with the case of exceeded string::max_size().
+
+2004-04-24 Matthias Klose <doko@debian.org>
+
+ Jonathan Wakely <cow@compsoc.man.ac.uk>
+ * docs/html/configopts.html: Fix reference to allocator config option.
+
+2004-04-23 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * linkage.m4 (GLIBCXX_CHECK_MATH_SUPPORT): Check for libmx also.
+ * configure: Regenerate.
+
+2004-04-23 Daniel Jacobowitz <drow@mvista.com>
+
+ PR libstdc++/15047, libstdc++/11610
+ * testsuite/lib/libstdc++.exp (v3-copy-files): Use remote_download.
+ (libstdc++_init): Don't pass outdir to v3-copy-files.
+
+2004-04-21 Paolo Carlini <pcarlini@suse.de>
+
+ * include/bits/deque.tcc: Trivial formatting fixes.
+ * include/bits/stl_deque.h: Likewise.
+ * include/bits/stl_list.h: Likewise.
+ * include/bits/stl_tree.h: Likewise.
+
+2004-04-21 Paolo Carlini <pcarlini@suse.de>
+ Andrew Pinski <pinskia@physics.uc.edu>
+
+ * include/bits/basic_string.tcc (_M_mutate): Don't compute
+ __src unnecessarily.
+
+2004-04-19 Benjamin Kosnik <bkoz@redhat.com>
+
+ * testsuite/27_io/basic_istream/extractors_character/char/9555-ic.cc:
+ Clarify assertion, set test variable to false before assert.
+ * testsuite/27_io/basic_istringstream/str/char/1.cc: Same.
+ * testsuite/27_io/basic_stringstream/str/char/1.cc: Same.
+ * testsuite/27_io/ios_base/storage/2.cc: Same.
+
+ * testsuite/27_io/basic_filebuf/imbue/char/13171-4.cc: Fix
+ function returns.
+ * testsuite/27_io/basic_filebuf/imbue/wchar_t/13582-3.cc: Same.
+ * testsuite/27_io/fpos/14320-3.cc: Same.
+
+ * testsuite/27_io/basic_filebuf/2.cc: Instantiate in namespace std.
+ * testsuite/27_io/fpos/1.cc: Same.
+ * testsuite/27_io/basic_stringstream/2.cc: Same.
+ * testsuite/27_io/basic_stringbuf/4.cc: Same.
+ * testsuite/27_io/basic_stringbuf/1.cc: Same.
+ * testsuite/27_io/basic_stringbuf/2.cc: Same.
+ * testsuite/27_io/basic_streambuf/2.cc: Same.
+ * testsuite/27_io/basic_ostringstream/2.cc: Same.
+ * testsuite/27_io/basic_ostream/2.cc: Same.
+ * testsuite/27_io/basic_ofstream/2.cc: Same.
+ * testsuite/27_io/basic_istringstream/2.cc: Same.
+ * testsuite/27_io/basic_istream/2.cc: Same.
+ * testsuite/27_io/basic_iostream/2.cc: Same.
+ * testsuite/27_io/basic_ios/2.cc: Same.
+ * testsuite/27_io/basic_ifstream/2.cc: Same.
+ * testsuite/27_io/basic_fstream/2.cc: Same.
+ * testsuite/ext/stdio_filebuf/char/1.cc: Same, in namespace __gnu_cxx.
+
+ * testsuite/21_strings/basic_string/capacity/1.cc: Don't compare
+ unsigned against zero.
+ * testsuite/21_strings/basic_string/capacity/wchar_t/1.cc: Same.
+ * testsuite/21_strings/basic_string/capacity/char/1.cc: Same.
+
+ * testsuite/18_support/new_delete_placement.cc: Initialize
+ variables before first use.
+ * testsuite/21_strings/char_traits/requirements/wchar_t/1.cc: Same.
+ * testsuite/21_strings/char_traits/requirements/char/1.cc: Same.
+ * testsuite/21_strings/char_traits/requirements/short/1.cc: Same.
+ * testsuite/27_io/basic_istream/seekg/char/exceptions_badbit_throw.cc:
+ Same.
+ * testsuite/27_io/basic_ostream/inserters_arithmetic/char/exceptions_badbit_throw.cc: Same.
+ * testsuite/27_io/basic_ostream/seekp/char/exceptions_badbit_throw.cc:
+ Same.
+ * testsuite/27_io/basic_ostream/inserters_arithmetic/char/exceptions_failbit_throw.cc: Same.
+ * testsuite/27_io/types/2.cc: Same.
+
+ * testsuite/ext/stdio_sync_filebuf/wchar_t/12077.cc: Fix temporary
+ file name.
+ * testsuite/27_io/fpos/14775.cc: Same.
+
+2004-04-19 Paolo Carlini <pcarlini@suse.de>
+
+ PR libstdc++/15002 (partial)
+ * include/bits/basic_string.h (_M_replace_aux, _M_replace_safe):
+ Special case __n2 == 1, not calling traits_type::assign/copy.
+
+2004-04-17 Benjamin Kosnik <bkoz@redhat.com>
+
+ * include/bits/stl_bvector.h: Use _M_impl._M_start.
+
+2004-04-16 Benjamin Kosnik <bkoz@redhat.com>
+
+ * include/bits/c++config (_GLIBCXX_STD): New.
+ * src/list.cc: Use it.
+ * include/std/std_bitset.h: Same.
+ * include/bits/vector.tcc: Same.
+ * include/bits/stl_set.h: Same.
+ * include/bits/stl_multiset.h: Same.
+ * include/bits/stl_multimap.h: Same.
+ * include/bits/stl_map.h: Same.
+ * include/bits/stl_list.h: Same.
+ * include/bits/stl_vector.h: Same.
+ * include/bits/stl_bvector.h: Same.
+ * include/bits/stl_deque.h: Same.
+ * include/bits/deque.tcc: Same.
+ * include/bits/list.tcc: Same.
+ * include/debug/vector: Same.
+ * include/debug/set.h: Same.
+ * include/debug/multiset.h: Same.
+ * include/debug/multimap.h: Same.
+ * include/debug/map.h: Same.
+ * include/debug/list: Same.
+ * include/debug/deque: Same.
+ * include/debug/bitset: Same.
+ * include/debug/formatter.h (__gnu_debug): Remove using directive.
+ Add using declaration for std::type_info.
+ * include/debug/safe_iterator.h: Add using declaration for
+ std::iterator_traits and std::pair.
+ * src/debug_list.cc: New.
+ * src/Makefile.am: Add debug_list.cc.
+ * src/Makefile.in: Regenerate.
+ * config/linker-map.gnu: Add _List_node_base exports for std and
+ __gnu_norm.
+
+ * include/bits/stl_bvector.h (_Bvector_base): Use _Bvector_impl
+ idiom that other containers use.
+ * testsuite/23_containers/vector/bool/clear_allocator.cc: New.
+
+2004-04-16 Paolo Carlini <pcarlini@suse.de>
+
+ PR libstdc++/14975
+ * include/bits/fstream.tcc (basic_filebuf::imbue): Zero _M_codecvt
+ in case of error.
+ * testsuite/27_io/basic_filebuf/imbue/char/14975-1.cc: New.
+ * testsuite/27_io/basic_filebuf/imbue/wchar_t/14975-2.cc: New.
+
+2004-04-16 Paolo Carlini <pcarlini@suse.de>
+
+ * acconfig.h: Remove _GLIBCXX_USE_LONG_DOUBLE entry, not
+ used anymore.
+ * config.h.in: Regenerate.
+
+2004-04-16 Paolo Carlini <pcarlini@suse.de>
+
+ * config/locale/generic/monetary_members.cc
+ (moneypunct<wchar_t>::_M_initialize_moneypunct): Avoid calling
+ btowc unnecessarily, just cast to wchar_t (the concerned chars
+ all belong to the basic character set).
+ * config/locale/generic/numeric_members.cc
+ (numpunct<wchar_t>::_M_initialize_numpunct): Likewise.
+ * config/locale/gnu/monetary_members.cc
+ (moneypunct<wchar_t>::_M_initialize_moneypunct): Likewise.
+ * config/locale/gnu/numeric_members.cc
+ (numpunct<wchar_t>::_M_initialize_numpunct): Likewise.
+
+2004-04-15 Paolo Carlini <pcarlini@suse.de>
+
+ * src/locale.cc (locale::operator==): When _M_impl == __rhs._M_impl
+ avoid constructing unnecessarily this->name().
+
+2004-04-14 Zack Weinberg <zack@codesourcery.com>
+
+ * testsuite/Makefile.am: Add definition of AM_CXXFLAGS.
+ Change definition of CXX to use $(shell) instead of backticks.
+ * testsuite/Makefile.in: Regenerate.
+
2004-04-12 Dhruv Matani <dhruvbird@gmx.net>
* testsuite/performance/20_util/allocator/list_sort_search.cc:
@@ -103,7 +429,7 @@
enumerations from _Rope_RopeRep here.
* include/ext/ropeimpl.h: Same.
* src/ext-inst.cc (_S_min_len): Fix up definition.
-
+
* config/locale/gnu/ctype_members.cc: Qualify base class members
with this.
* config/locale/generic/ctype_members.cc: Same.
@@ -111,11 +437,11 @@
* config/locale/generic/messages_members.h: Same.
* src/ctype.cc: Same.
* include/bits/codecvt.h: Same.
-
+
* include/bits/boost_concept_check.h: Declare.
(__error_type_must_be_an_unsigned_integer_type): Remove this.
(__error_type_must_be_an_integer_type): Remove this.
- (__error_type_must_be_a_signed_integer_type): Remove this.
+ (__error_type_must_be_a_signed_integer_type): Remove this.
* config/io/basic_file_stdio.cc (__basic_file::sys_open): Remove cast.
@@ -124,8 +450,8 @@
(__cxa_allocate_exception): Same.
* libsupc++/eh_catch.cc (__cxa_begin_catch): Same.
* libsupc++/eh_globals.cc (__cxa_get_globals_fast): Same.
- (__cxa_get_globals): Same.
-
+ (__cxa_get_globals): Same.
+
* libsupc++/del_op.cc: Add comment about freestanding.
2004-04-05 Paolo Carlini <pcarlini@suse.de>
@@ -244,9 +570,9 @@
* include/bits/stl_tree.h (_Rb_tree_impl): Add _Node_allocator
default argument in constructors.
(_Rb_tree::_M_empty_initialize): Remove.
-
+
2004-03-25 Benjamin Kosnik <bkoz@redhat.com>
-
+
* testsuite/23_containers/map/operators/1_neg.cc: Adjust line numbers.
* testsuite/23_containers/set/operators/1_neg.cc: Same.
@@ -322,7 +648,7 @@
* testsuite/23_containers/deque/cons/clear_allocator.cc: New.
* testsuite/23_containers/list/cons/clear_allocator.cc: New.
* testsuite/23_containers/vector/cons/clear_allocator.cc: New.
-
+
2004-03-24 Dhruv Matani <dhruvbird@gmx.net>
* include/ext/malloc_allocator.h: Fixed the construct function to
@@ -332,7 +658,7 @@
* include/ext/debug_allocator.h: Added a check in the deallocate
function to check whether the user has passed a NULL pointer or
not.
-
+
2004-03-24 Benjamin Kosnik <bkoz@redhat.com>
* docs/html/20_util/allocator.html: Add bitmap_allocator links.
@@ -343,7 +669,7 @@
warning from IA64 assembler.
2004-03-24 Dhruv Matani <dhruvbird@gmx.net>
-
+
* include/ext/bitmap_allocator.h: (_Bit_scan_forward) -> Made this
function call __builtin_ctz instead of the while loop.
(allocate) -> If condition has __builtin_expect.
@@ -357,7 +683,7 @@
* testsuite/performance/20_util/allocator/producer_consumer.cc:
Use linear algorithm for producer.
-
+
2004-03-24 Paolo Carlini <pcarlini@suse.de>
* include/ext/mt_allocator.h (__mt_alloc<>::allocate,
@@ -425,7 +751,7 @@
* testsuite/27_io/basic_istream/extractors_arithmetic/char/12.cc:
Likewise.
* testsuite/27_io/basic_istream/extractors_arithmetic/char/13.cc:
- Likewise.
+ Likewise.
2004-03-20 Paolo Carlini <pcarlini@suse.de>
@@ -489,18 +815,18 @@
* acinclude.m4 (GLIBCXX_ENABLE_ALLOCATOR): Default setting is
new_allocator for all hosts.
* configure: Regenerate.
-
+
2004-03-16 Paolo Carlini <pcarlini@suse.de>
* testsuite/22_locale/num_put/put/char/4.cc: Fix for 64-bit pointers.
* testsuite/22_locale/num_put/put/wchar_t/4.cc: Likewise.
-
+
2004-03-15 Paolo Carlini <pcarlini@suse.de>
* include/bits/locale_facets.tcc (money_get<>::_M_extract):
Adjust the logic underlying the parsing of symbol to deal
correctly with an optional sign component (i.e., when either
- negative_sign or positive_sign is empty)
+ negative_sign or positive_sign is empty)
* testsuite/22_locale/money_get/get/char/19.cc: New.
* testsuite/22_locale/money_get/get/wchar_t/19.cc: New.
@@ -521,7 +847,7 @@
* include/bits/allocator.h: Include c++allocator.h.
* acinclude.m4 (GLIBCXX_ENABLE_ALLOCATOR): New.
* aclocal.m4: Regenerate.
- * configure.ac: Use GLIBCXX_ENABLE_ALLOCATOR.
+ * configure.ac: Use GLIBCXX_ENABLE_ALLOCATOR.
* configure: Regenerate.
* include/Makefile.am (host_headers_extra): Add c++allocator.h.
* include/Makefile.in: Regenerate.
@@ -543,7 +869,7 @@
* testsuite/20_util/allocator/14176.cc: New.
* include/ext/mt_allocator.h: Formatting fixes.
-
+
2004-03-11 Dhruv Matani <dhruvbird@HotPOP.com>
* include/Makefile.am (ext_headers): Add
@@ -551,7 +877,7 @@
* include/Makefile.in: Regenerate.
* docs/html/ext/ballocator_doc.txt: New file.
* include/ext/bitmap_allocator.h: New file.
- * testsuite/performance/20_util/allocator/list_sort_search.cc: Add
+ * testsuite/performance/20_util/allocator/list_sort_search.cc: Add
test.
* testsuite/performance/20_util/allocator/map_mt_find.cc: Likewise.
* testsuite/performance/20_util/allocator/producer_consumer.cc: Add
@@ -617,7 +943,7 @@
* testsuite/22_locale/locale/cons/12658_thread.cc: Catch exceptions.
2004-03-08 Benjamin Kosnik <bkoz@redhat.com>
-
+
PR c++/13658
* testsuite/23_containers/deque/modifiers/swap.cc: New.
* testsuite/23_containers/list/modifiers/swap.cc: New.
@@ -626,7 +952,7 @@
* testsuite/23_containers/multiset/modifiers/swap.cc: New.
* testsuite/23_containers/set/modifiers/swap.cc: New.
* testsuite/23_containers/vector/modifiers/swap.cc: New.
-
+
2004-03-08 Petur Runolfsson <peturr02@ru.is>
PR libstdc++/12658
@@ -651,7 +977,7 @@
* include/bits/locale_facets.tcc (money_get<>::do_get(long_double&)):
Remove redundant conditional on __str.size().
-
+
2004-03-08 Benjamin Kosnik <bkoz@redhat.com>
* include/bits/allocator.h: Switch defaults to mt_alloc.
@@ -666,8 +992,8 @@
PR libstdc++/12658
* src/locale_init.cc (locale::locale): Lock critical regions with
external mutexes.
- (locale::global): Same.
- * include/bits/concurrence.h (__glibcxx_mutex_define_initialized):
+ (locale::global): Same.
+ * include/bits/concurrence.h (__glibcxx_mutex_define_initialized):
Add in once bits for cases without __GTHREAD_MUTEX_INIT.
(__glibcxx_mutex_lock): Same.
@@ -681,7 +1007,7 @@
* config/linker-map.gnu: Remove types in the signature of atomic
exports, as they may vary.
-
+
2004-03-06 Paolo Carlini <pcarlini@suse.de>
* include/bits/locale_facets.tcc: Tweak the comment preceding
@@ -717,7 +1043,7 @@
* testsuite/23_containers/multiset/insert/1.cc: Test result string.
* testsuite/23_containers/bitset/invalidation/1.cc: Main always
- returns 0.
+ returns 0.
* testsuite/23_containers/deque/invalidation/4.cc: Same.
* testsuite/23_containers/list/invalidation/1.cc: Same.
* testsuite/23_containers/list/invalidation/2.cc: Same.
@@ -740,7 +1066,7 @@
* scripts/testsuite_flags.in: Add "-D_GLIBCXX_ASSERT" to
CXXFLAGS_save.
* testsuite/lib/libstdc++.exp: Don't add it conditionally to
- DEFAULT_CXXFLAGS.
+ DEFAULT_CXXFLAGS.
* testsuite/18_support/numeric_limits.cc: Remove "-D_GLIBCXX_ASSERT"
from the dg-options.
* testsuite/23_containers/vector/invalidation/1.cc: Likewise.
@@ -773,20 +1099,20 @@
* testsuite/22_locale/ctype/is/wchar_t/2.cc: Same.
* testsuite/22_locale/ctype/is/char/2.cc: Same.
* testsuite/thread/pthread7-rope.cc: Same.
- * testsuite/thread/pthread6.cc: Same.
- * testsuite/thread/pthread5.cc: Same.
- * testsuite/thread/pthread4.cc: Same.
+ * testsuite/thread/pthread6.cc: Same.
+ * testsuite/thread/pthread5.cc: Same.
+ * testsuite/thread/pthread4.cc: Same.
* testsuite/thread/pthread1.cc: Same.
* testsuite/ext/rope.cc: Same.
* testsuite/ext/hash_set.cc: Same.
- * testsuite/ext/hash_map.cc: Same.
+ * testsuite/ext/hash_map.cc: Same.
* testsuite/ext/concept_checks.cc: Same.
* testsuite/27_io/basic_filebuf/seekpos/wchar_t/9874.cc: Same.
* testsuite/25_algorithms/unique/2.cc: Same.
* testsuite/25_algorithms/unique/1.cc: Same.
* testsuite/25_algorithms/rotate.cc: Same.
* testsuite/25_algorithms/min_max.cc: Same.
- * testsuite/25_algorithms/equal.cc: Same.
+ * testsuite/25_algorithms/equal.cc: Same.
* testsuite/24_iterators/rel_ops.cc: Same.
* testsuite/24_iterators/iterator.cc: Same.
* testsuite/24_iterators/insert_iterator.cc: Same.
@@ -797,7 +1123,7 @@
* testsuite/23_containers/vector/modifiers/1.cc: Same.
* testsuite/23_containers/vector/invalidation/4.cc: Same.
* testsuite/23_containers/vector/invalidation/3.cc: Same.
- * testsuite/23_containers/vector/invalidation/2.cc: Same.
+ * testsuite/23_containers/vector/invalidation/2.cc: Same.
* testsuite/23_containers/vector/invalidation/1.cc: Same.
* testsuite/23_containers/vector/element_access/1.cc: Same.
* testsuite/23_containers/vector/cons/6513.cc: Same.
@@ -813,7 +1139,7 @@
* testsuite/23_containers/queue/members/7157.cc: Same.
* testsuite/23_containers/priority_queue/members/7161.cc: Same.
* testsuite/23_containers/multiset/invalidation/2.cc: Same.
- * testsuite/23_containers/multiset/invalidation/2.cc: Same.
+ * testsuite/23_containers/multiset/invalidation/2.cc: Same.
* testsuite/23_containers/multiset/insert/1.cc: Same.
* testsuite/23_containers/multimap/invalidation/2.cc: Same.
* testsuite/23_containers/multimap/invalidation/2.cc: Same.
@@ -831,7 +1157,7 @@
* testsuite/23_containers/list/invalidation/4.cc: Same.
* testsuite/23_containers/list/invalidation/3.cc: Same.
* testsuite/23_containers/list/invalidation/2.cc: Same.
- * testsuite/23_containers/list/invalidation/1.cc: Same.
+ * testsuite/23_containers/list/invalidation/1.cc: Same.
* testsuite/23_containers/list/cons/9.cc: Same.
* testsuite/23_containers/list/cons/8.cc: Same.
* testsuite/23_containers/list/cons/7.cc: Same.
@@ -913,7 +1239,7 @@
* acconfig.h: Remove _GLIBCXX_SUPPORTS_WEAK.
* config.h.in: Regenerate.
* configure: Same.
-
+
2004-03-01 Benjamin Kosnik <bkoz@redhat.com>
Support autoconf 2.59
@@ -927,7 +1253,7 @@
* docs/html/18_support/howto.html: Add bit about writing to
stderr, mostly by Zack.
-
+
2004-03-01 Paolo Carlini <pcarlini@suse.de>
* include/bits/locale_facets.tcc (money_get<>::_M_extract,
@@ -946,7 +1272,7 @@
and decimal_point; tweak a bit.
* testsuite/22_locale/num_get/get/char/15.cc: New.
* testsuite/22_locale/num_get/get/wchar_t/15.cc: New.
-
+
* include/bits/locale_facets.tcc (num_get<>::_M_extract_float,
num_get<>::_M_extract_int): Reorder some conditionals.
@@ -957,10 +1283,10 @@
22.2.6.3, p3 for the thousands separators; tweak a bit.
* testsuite/22_locale/money_get/get/char/15.cc: New.
* testsuite/22_locale/money_get/get/wchar_t/15.cc: New.
-
+
2004-03-01 David Billinghurst <David.Billinghurst@riotinto.com>
- * testsuite/lib/libstdc++.exp (v3-list-tests): Use
+ * testsuite/lib/libstdc++.exp (v3-list-tests): Use
testsuite_files from correct multilib blddir when running
testsuite.
@@ -987,7 +1313,7 @@
* testsuite/22_locale/num_get/get/wchar_t/14.cc: New.
2004-02-27 Eric Christopher <echristo@redhat.com>
- Phil Edwards <phil@codesourcery.com>
+ Phil Edwards <phil@codesourcery.com>
* testsuite/22_locale/collate/compare/wchar_t/2.cc,
testsuite/22_locale/collate/compare/wchar_t/wrapped_env.cc,
@@ -1002,7 +1328,7 @@
* testsuite/lib/libstdc++.exp: Load target-supports.exp.
2004-02-27 Phil Edwards <phil@codesourcery.com>
- Eric Christopher <echristo@redhat.com>
+ Eric Christopher <echristo@redhat.com>
* testsuite/config/default.exp: Update with comments.
(${tool}_target_compile): New wrapper routine.
@@ -1069,23 +1395,23 @@
2004-02-26 Benjamin Kosnik <bkoz@redhat.com>
PR libstdc++/10246
- * libsupc++/Makefile.am: Use libiberty demangler.
- (c_sources): Add cp-demangle.c.
- * libsupc++/Makefile.in: Regenerate.
- * src/Makefile.am (sources): Remove demangle.cc.
- * src/Makefile.in: Regenerate.
- * include/Makefile.am (bits_headers): Move demangle.h.
+ * libsupc++/Makefile.am: Use libiberty demangler.
+ (c_sources): Add cp-demangle.c.
+ * libsupc++/Makefile.in: Regenerate.
+ * src/Makefile.am (sources): Remove demangle.cc.
+ * src/Makefile.in: Regenerate.
+ * include/Makefile.am (bits_headers): Move demangle.h.
(ext_headers): ...here.
- * include/Makefile.in: Regenerate.
- * include/bits/demangle.h: Move...
+ * include/Makefile.in: Regenerate.
+ * include/bits/demangle.h: Move...
* include/ext/demangle.h: ...here.
- * src/demangle.cc: Remove.
+ * src/demangle.cc: Remove.
2004-02-26 Benjamin Kosnik <bkoz@redhat.com>
-
- * include/bits/demangle.h: Add type template parameter to all
- templates with just an Allocator template parameter.
-
+
+ * include/bits/demangle.h: Add type template parameter to all
+ templates with just an Allocator template parameter.
+
2004-02-25 Benjamin Kosnik <bkoz@redhat.com>
* include/bits/atomicity.h: New, forward declarations for __atomic_add
@@ -1119,7 +1445,7 @@
* config/cpu/powerpc/atomicity.h: Same.
* config/cpu/s390/atomicity.h: Same.
* config/cpu/sparc/atomicity.h: Same.
-
+
* src/Makefile.am (host_sources): Add atomicity.cc.
(atomicity.cc): New rule.
* src/Makefile.in: Regenerate.
@@ -1135,8 +1461,8 @@
* config/linker-map.gnu: Export __exchange_and_add, and __atomic_add.
* testsuite/27_io/ios_base/cons/assign_neg.cc: Adjust line numbers.
- * testsuite/27_io/ios_base/cons/copy_neg.cc: Same.
-
+ * testsuite/27_io/ios_base/cons/copy_neg.cc: Same.
+
2004-02-25 Jonathan Wakely <redi@gcc.gnu.org>
* docs/html/20_util/howto.html, docs/html/20_util/allocator.html,
@@ -1173,20 +1499,20 @@
* libsupc++/vterminate.cc (__gnu_cxx::__verbose_terminate_handler):
Only use fputs, not write.
-
+
2004-02-23 Benjamin Kosnik <bkoz@redhat.com>
* include/ext/malloc_allocator.h: Add operators ==, !=.
* include/ext/new_allocator.h: Add operators ==, !=.
* include/ext/mt_allocator.h (__mt_alloc::tune): New.
(__mt_alloc::_S_get_options): New.
- (__mt_alloc::_S_set_options): New.
+ (__mt_alloc::_S_set_options): New.
(__mt_alloc::_S_thread_key_destr): To _S_destroy_thread_key.
(__mt_alloc::_S_no_of_bins): To _S_bin_size.
Move functions out of line, simplify, format.
* src/allocator.cc: Simplify explicit instantiations.
* include/bits/allocator.h: Tweak.
-
+
2004-02-22 Paolo Carlini <pcarlini@suse.de>
* include/bits/locale_facets.tcc (money_put<>::_M_insert):
@@ -1203,12 +1529,12 @@
avoid multiple reallocations; fix parsing of sign component
according to 22.2.6.1.2, p3.
(money_get<>::do_get(long double&),
- money_get<>::do_get(string_type&)): Update calls of _M_extract.
+ money_get<>::do_get(string_type&)): Update calls of _M_extract.
* src/locale-inst.cc: Add instantiations of
money_get::_M_extract<false> and money_get::_M_extract<true>.
* testsuite/22_locale/money_get/get/char/14.cc: New.
* testsuite/22_locale/money_get/get/wchar_t/14.cc: Ditto.
-
+
2004-02-21 Mark Mitchell <mark@codesourcery.com>
* libsupc++/vterminate.cc
@@ -1396,7 +1722,7 @@
(__basic_file<char>::xwrite): Move to __gnu_internal and make
static.
(__basic_file<char>::xsputn): Update call.
- (__basic_file<char>::xsputn_2): Likewise.
+ (__basic_file<char>::xsputn_2): Likewise.
* config/io/basic_file_stdio.h (__basic_file<char>::xwrite):
Don't declare, now static.
@@ -1492,7 +1818,7 @@
2004-02-08 Richard Henderson <rth@redhat.com>
PR libstdc++/14026
- * libsupc++/eh_catch.cc (__cxa_begin_catch): Don't adjust
+ * libsupc++/eh_catch.cc (__cxa_begin_catch): Don't adjust
uncaughtExceptions during nested catch rethrow.
* testsuite/18_support/14026.cc: New.
diff --git a/libstdc++-v3/Makefile.in b/libstdc++-v3/Makefile.in
index 051ace1e586..cf4d198bdc1 100644
--- a/libstdc++-v3/Makefile.in
+++ b/libstdc++-v3/Makefile.in
@@ -44,7 +44,7 @@ DIST_COMMON = README $(am__configure_deps) $(srcdir)/../config.guess \
$(top_srcdir)/configure $(top_srcdir)/fragment.am \
$(top_srcdir)/scripts/check_survey.in \
$(top_srcdir)/scripts/testsuite_flags.in ../ABOUT-NLS \
- ../COPYING ../COPYING.LIB ../ChangeLog ../README \
+ ../COPYING ../COPYING.LIB ../ChangeLog ../README ../compile \
../config.guess ../config.rpath ../config.sub ../install-sh \
../ltcf-c.sh ../ltcf-cxx.sh ../ltcf-gcj.sh ../ltconfig \
../ltmain.sh ../missing ../mkinstalldirs ../ylwrap ChangeLog \
diff --git a/libstdc++-v3/acconfig.h b/libstdc++-v3/acconfig.h
index cad2748bbdb..c2a96c2248b 100644
--- a/libstdc++-v3/acconfig.h
+++ b/libstdc++-v3/acconfig.h
@@ -13,9 +13,6 @@
// Include I/O support for 'long long' and 'unsigned long long'.
#undef _GLIBCXX_USE_LONG_LONG
-// Include support for 'long double'.
-#undef _GLIBCXX_USE_LONG_DOUBLE
-
// Define if C99 math functions (like fpclassify) should be exposed.
#undef _GLIBCXX_USE_C99_MATH
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index ab4538c5e1c..7529af32586 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -711,7 +711,7 @@ AC_DEFUN([GLIBCXX_EXPORT_FLAGS], [
OPTIMIZE_CXXFLAGS=
AC_SUBST(OPTIMIZE_CXXFLAGS)
- WARN_FLAGS='-Wall -W -Wwrite-strings -Wcast-qual'
+ WARN_FLAGS='-Wall -Wextra -Wwrite-strings -Wcast-qual'
AC_SUBST(WARN_FLAGS)
])
diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in
index bef3e8c8248..ecb29eb35db 100644
--- a/libstdc++-v3/config.h.in
+++ b/libstdc++-v3/config.h.in
@@ -14,9 +14,6 @@
// Include I/O support for 'long long' and 'unsigned long long'.
#undef _GLIBCXX_USE_LONG_LONG
-// Include support for 'long double'.
-#undef _GLIBCXX_USE_LONG_DOUBLE
-
// Define if C99 math functions (like fpclassify) should be exposed.
#undef _GLIBCXX_USE_C99_MATH
diff --git a/libstdc++-v3/config/linker-map.gnu b/libstdc++-v3/config/linker-map.gnu
index 7dd9a2a12f7..b9205db85a0 100644
--- a/libstdc++-v3/config/linker-map.gnu
+++ b/libstdc++-v3/config/linker-map.gnu
@@ -55,6 +55,11 @@ GLIBCXX_3.4 {
std::locale::_S_normalize_category*;
std::locale::_[T-Za-z]*;
std::[A-Zm-z]*;
+ std::_List_node_base::hook*;
+ std::_List_node_base::swap*;
+ std::_List_node_base::unhook*;
+ std::_List_node_base::reverse*;
+ std::_List_node_base::transfer*;
std::__throw_*;
std::__basic_file*;
std::__timepunct*;
@@ -66,10 +71,14 @@ GLIBCXX_3.4 {
std::__moneypunct_cache*;
std::__numpunct_cache*;
std::__timepunct_cache*;
- __gnu_norm::*;
__gnu_debug::_Safe_iterator_base*;
__gnu_debug::_Safe_sequence_base*;
- __gnu_debug::_Error_formatter*
+ __gnu_debug::_Error_formatter*;
+ __gnu_norm::_List_node_base::hook*;
+ __gnu_norm::_List_node_base::swap*;
+ __gnu_norm::_List_node_base::unhook*;
+ __gnu_norm::_List_node_base::reverse*;
+ __gnu_norm::_List_node_base::transfer*
};
# Names not in an 'extern' block are mangled names.
diff --git a/libstdc++-v3/config/locale/generic/monetary_members.cc b/libstdc++-v3/config/locale/generic/monetary_members.cc
index 957a326dbd4..71ad6d218b1 100644
--- a/libstdc++-v3/config/locale/generic/monetary_members.cc
+++ b/libstdc++-v3/config/locale/generic/monetary_members.cc
@@ -127,12 +127,9 @@ namespace std
_M_data->_M_pos_format = money_base::_S_default_pattern;
_M_data->_M_neg_format = money_base::_S_default_pattern;
- unsigned char uc;
for (size_t __i = 0; __i < money_base::_S_end; ++__i)
- {
- uc = static_cast<unsigned char>(money_base::_S_atoms[__i]);
- _M_data->_M_atoms[__i] = btowc(uc);
- }
+ _M_data->_M_atoms[__i] =
+ static_cast<wchar_t>(money_base::_S_atoms[__i]);
}
template<>
@@ -158,12 +155,9 @@ namespace std
_M_data->_M_pos_format = money_base::_S_default_pattern;
_M_data->_M_neg_format = money_base::_S_default_pattern;
- unsigned char uc;
for (size_t __i = 0; __i < money_base::_S_end; ++__i)
- {
- uc = static_cast<unsigned char>(money_base::_S_atoms[__i]);
- _M_data->_M_atoms[__i] = btowc(uc);
- }
+ _M_data->_M_atoms[__i] =
+ static_cast<wchar_t>(money_base::_S_atoms[__i]);
}
template<>
diff --git a/libstdc++-v3/config/locale/generic/numeric_members.cc b/libstdc++-v3/config/locale/generic/numeric_members.cc
index e2afed9c193..62017e02d17 100644
--- a/libstdc++-v3/config/locale/generic/numeric_members.cc
+++ b/libstdc++-v3/config/locale/generic/numeric_members.cc
@@ -59,9 +59,9 @@ namespace std
_M_data->_M_atoms_in[__i] = __num_base::_S_atoms_in[__i];
_M_data->_M_truename = "true";
- _M_data->_M_truename_size = strlen(_M_data->_M_truename);
+ _M_data->_M_truename_size = 4;
_M_data->_M_falsename = "false";
- _M_data->_M_falsename_size = strlen(_M_data->_M_falsename);
+ _M_data->_M_falsename_size = 5;
}
template<>
@@ -85,23 +85,18 @@ namespace std
_M_data->_M_thousands_sep = L',';
// Use ctype::widen code without the facet...
- unsigned char uc;
for (size_t __i = 0; __i < __num_base::_S_oend; ++__i)
- {
- uc = static_cast<unsigned char>(__num_base::_S_atoms_out[__i]);
- _M_data->_M_atoms_out[__i] = btowc(uc);
- }
+ _M_data->_M_atoms_out[__i] =
+ static_cast<wchar_t>(__num_base::_S_atoms_out[__i]);
for (size_t __i = 0; __i < __num_base::_S_iend; ++__i)
- {
- uc = static_cast<unsigned char>(__num_base::_S_atoms_in[__i]);
- _M_data->_M_atoms_in[__i] = btowc(uc);
- }
+ _M_data->_M_atoms_in[__i] =
+ static_cast<wchar_t>(__num_base::_S_atoms_in[__i]);
_M_data->_M_truename = L"true";
- _M_data->_M_truename_size = wcslen(_M_data->_M_truename);
+ _M_data->_M_truename_size = 4;
_M_data->_M_falsename = L"false";
- _M_data->_M_falsename_size = wcslen(_M_data->_M_falsename);
+ _M_data->_M_falsename_size = 5;
}
template<>
diff --git a/libstdc++-v3/config/locale/gnu/ctype_members.cc b/libstdc++-v3/config/locale/gnu/ctype_members.cc
index 2b31d11c2b2..7c53c15831d 100644
--- a/libstdc++-v3/config/locale/gnu/ctype_members.cc
+++ b/libstdc++-v3/config/locale/gnu/ctype_members.cc
@@ -272,14 +272,14 @@ namespace std
_M_narrow_ok = true;
else
_M_narrow_ok = false;
- for (size_t __i = 0;
- __i < sizeof(_M_widen) / sizeof(wint_t); ++__i)
- _M_widen[__i] = btowc(__i);
+ for (size_t __j = 0;
+ __j < sizeof(_M_widen) / sizeof(wint_t); ++__j)
+ _M_widen[__j] = btowc(__j);
- for (size_t __i = 0; __i <= 11; ++__i)
+ for (size_t __k = 0; __k <= 11; ++__k)
{
- _M_bit[__i] = static_cast<mask>(_ISbit(__i));
- _M_wmask[__i] = _M_convert_to_wmask(_M_bit[__i]);
+ _M_bit[__k] = static_cast<mask>(_ISbit(__k));
+ _M_wmask[__k] = _M_convert_to_wmask(_M_bit[__k]);
}
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
__uselocale(__old);
diff --git a/libstdc++-v3/config/locale/gnu/monetary_members.cc b/libstdc++-v3/config/locale/gnu/monetary_members.cc
index 38d9c39969b..f1cb25fe58b 100644
--- a/libstdc++-v3/config/locale/gnu/monetary_members.cc
+++ b/libstdc++-v3/config/locale/gnu/monetary_members.cc
@@ -372,12 +372,9 @@ namespace std
_M_data->_M_neg_format = money_base::_S_default_pattern;
// Use ctype::widen code without the facet...
- unsigned char uc;
for (size_t __i = 0; __i < money_base::_S_end; ++__i)
- {
- uc = static_cast<unsigned char>(money_base::_S_atoms[__i]);
- _M_data->_M_atoms[__i] = btowc(uc);
- }
+ _M_data->_M_atoms[__i] =
+ static_cast<wchar_t>(money_base::_S_atoms[__i]);
}
else
{
@@ -517,12 +514,9 @@ namespace std
_M_data->_M_neg_format = money_base::_S_default_pattern;
// Use ctype::widen code without the facet...
- unsigned char uc;
for (size_t __i = 0; __i < money_base::_S_end; ++__i)
- {
- uc = static_cast<unsigned char>(money_base::_S_atoms[__i]);
- _M_data->_M_atoms[__i] = btowc(uc);
- }
+ _M_data->_M_atoms[__i] =
+ static_cast<wchar_t>(money_base::_S_atoms[__i]);
}
else
{
diff --git a/libstdc++-v3/config/locale/gnu/numeric_members.cc b/libstdc++-v3/config/locale/gnu/numeric_members.cc
index ef1f5bf5703..34fadf45676 100644
--- a/libstdc++-v3/config/locale/gnu/numeric_members.cc
+++ b/libstdc++-v3/config/locale/gnu/numeric_members.cc
@@ -58,14 +58,16 @@ namespace std
for (size_t __i = 0; __i < __num_base::_S_oend; ++__i)
_M_data->_M_atoms_out[__i] = __num_base::_S_atoms_out[__i];
- for (size_t __i = 0; __i < __num_base::_S_iend; ++__i)
- _M_data->_M_atoms_in[__i] = __num_base::_S_atoms_in[__i];
+ for (size_t __j = 0; __j < __num_base::_S_iend; ++__j)
+ _M_data->_M_atoms_in[__j] = __num_base::_S_atoms_in[__j];
}
else
{
// Named locale.
- _M_data->_M_decimal_point = *(__nl_langinfo_l(DECIMAL_POINT, __cloc));
- _M_data->_M_thousands_sep = *(__nl_langinfo_l(THOUSANDS_SEP, __cloc));
+ _M_data->_M_decimal_point = *(__nl_langinfo_l(DECIMAL_POINT,
+ __cloc));
+ _M_data->_M_thousands_sep = *(__nl_langinfo_l(THOUSANDS_SEP,
+ __cloc));
// Check for NULL, which implies no grouping.
if (_M_data->_M_thousands_sep == '\0')
@@ -78,10 +80,10 @@ namespace std
// NB: There is no way to extact this info from posix locales.
// _M_truename = __nl_langinfo_l(YESSTR, __cloc);
_M_data->_M_truename = "true";
- _M_data->_M_truename_size = strlen(_M_data->_M_truename);
+ _M_data->_M_truename_size = 4;
// _M_falsename = __nl_langinfo_l(NOSTR, __cloc);
_M_data->_M_falsename = "false";
- _M_data->_M_falsename_size = strlen(_M_data->_M_falsename);
+ _M_data->_M_falsename_size = 5;
}
template<>
@@ -107,18 +109,13 @@ namespace std
_M_data->_M_thousands_sep = L',';
// Use ctype::widen code without the facet...
- unsigned char uc;
for (size_t __i = 0; __i < __num_base::_S_oend; ++__i)
- {
- uc = static_cast<unsigned char>(__num_base::_S_atoms_out[__i]);
- _M_data->_M_atoms_out[__i] = btowc(uc);
- }
-
- for (size_t __i = 0; __i < __num_base::_S_iend; ++__i)
- {
- uc = static_cast<unsigned char>(__num_base::_S_atoms_in[__i]);
- _M_data->_M_atoms_in[__i] = btowc(uc);
- }
+ _M_data->_M_atoms_out[__i] =
+ static_cast<wchar_t>(__num_base::_S_atoms_out[__i]);
+
+ for (size_t __j = 0; __j < __num_base::_S_iend; ++__j)
+ _M_data->_M_atoms_in[__j] =
+ static_cast<wchar_t>(__num_base::_S_atoms_in[__j]);
}
else
{
@@ -140,10 +137,10 @@ namespace std
// NB: There is no way to extact this info from posix locales.
// _M_truename = __nl_langinfo_l(YESSTR, __cloc);
_M_data->_M_truename = L"true";
- _M_data->_M_truename_size = wcslen(_M_data->_M_truename);
+ _M_data->_M_truename_size = 4;
// _M_falsename = __nl_langinfo_l(NOSTR, __cloc);
_M_data->_M_falsename = L"false";
- _M_data->_M_falsename_size = wcslen(_M_data->_M_falsename);
+ _M_data->_M_falsename_size = 5;
}
template<>
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index c19c57a0ac8..160d2b8c6c7 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -3965,7 +3965,7 @@ darwin* | rhapsody*)
lt_cv_deplibs_check_method=pass_all
;;
-freebsd* )
+freebsd* | kfreebsd*-gnu)
if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
case $host_cpu in
i*86 )
@@ -4033,7 +4033,7 @@ linux-gnu*)
lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
;;
-netbsd*)
+netbsd* | knetbsd*-gnu)
if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'
else
@@ -8447,6 +8447,81 @@ fi
ac_save_LIBS="$LIBS"
LIBS="$LIBS $libm"
+ echo "$as_me:$LINENO: checking for sqrtf in -lmx" >&5
+echo $ECHO_N "checking for sqrtf in -lmx... $ECHO_C" >&6
+if test "${ac_cv_lib_mx_sqrtf+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lmx $LIBS"
+if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char sqrtf ();
+int
+main ()
+{
+sqrtf ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_mx_sqrtf=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_mx_sqrtf=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_mx_sqrtf" >&5
+echo "${ECHO_T}$ac_cv_lib_mx_sqrtf" >&6
+if test $ac_cv_lib_mx_sqrtf = yes; then
+ libmx="-lmx"
+fi
+
+ LIBS="$LIBS $libmx"
+
echo "$as_me:$LINENO: checking for isinf declaration" >&5
@@ -31598,6 +31673,81 @@ fi
ac_save_LIBS="$LIBS"
LIBS="$LIBS $libm"
+ echo "$as_me:$LINENO: checking for sqrtf in -lmx" >&5
+echo $ECHO_N "checking for sqrtf in -lmx... $ECHO_C" >&6
+if test "${ac_cv_lib_mx_sqrtf+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lmx $LIBS"
+if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char sqrtf ();
+int
+main ()
+{
+sqrtf ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_mx_sqrtf=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_mx_sqrtf=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_mx_sqrtf" >&5
+echo "${ECHO_T}$ac_cv_lib_mx_sqrtf" >&6
+if test $ac_cv_lib_mx_sqrtf = yes; then
+ libmx="-lmx"
+fi
+
+ LIBS="$LIBS $libmx"
+
echo "$as_me:$LINENO: checking for isinf declaration" >&5
@@ -58074,9 +58224,12 @@ _ACEOF
+
+
+
for ac_header in nan.h ieeefp.h endian.h sys/isa_defs.h \
machine/endian.h machine/param.h sys/machine.h sys/types.h \
- fp.h locale.h float.h inttypes.h
+ fp.h float.h endian.h inttypes.h locale.h float.h stdint.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if eval "test \"\${$as_ac_Header+set}\" = set"; then
@@ -60848,6 +61001,26 @@ _ACEOF
cat >>confdefs.h <<\_ACEOF
+#define HAVE_ACOSF 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_ASINF 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_ATANF 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_ATAN2F 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_CEILF 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
#define HAVE_COPYSIGN 1
_ACEOF
@@ -60856,6 +61029,22 @@ _ACEOF
_ACEOF
cat >>confdefs.h <<\_ACEOF
+#define HAVE_COSF 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_COSHF 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_EXPF 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_FABSF 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
#define HAVE_FINITE 1
_ACEOF
@@ -60864,10 +61053,22 @@ _ACEOF
_ACEOF
cat >>confdefs.h <<\_ACEOF
+#define HAVE_FLOORF 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_FMODF 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
#define HAVE_FREXPF 1
_ACEOF
cat >>confdefs.h <<\_ACEOF
+#define HAVE_HYPOT 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
#define HAVE_HYPOTF 1
_ACEOF
@@ -60888,6 +61089,34 @@ _ACEOF
_ACEOF
cat >>confdefs.h <<\_ACEOF
+#define HAVE_LOGF 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_LOG10F 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_MODFF 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_SIGNBIT 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_SIGNBITF 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_SINF 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_SINHF 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
#define HAVE_SINCOS 1
_ACEOF
@@ -60895,12 +61124,76 @@ _ACEOF
#define HAVE_SINCOSF 1
_ACEOF
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_SQRTF 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_TANF 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_TANHF 1
+_ACEOF
+
if test x"long_double_math_on_this_cpu" = x"yes"; then
cat >>confdefs.h <<\_ACEOF
+#define HAVE_ACOSL 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_ASINL 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_ATANL 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_ATAN2L 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_CEILL 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_COPYSIGNL 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_COSL 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_COSHL 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_EXPL 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_FABSL 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
#define HAVE_FINITEL 1
_ACEOF
cat >>confdefs.h <<\_ACEOF
+#define HAVE_FLOORL 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_FMODL 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_FREXPL 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
#define HAVE_HYPOTL 1
_ACEOF
@@ -60912,6 +61205,50 @@ _ACEOF
#define HAVE_ISNANL 1
_ACEOF
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_LOGL 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_LOG10L 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_MODFL 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_POWL 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_SIGNBITL 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_SINL 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_SINHL 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_SINCOSL 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_SQRTL 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_TANL 1
+_ACEOF
+
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_TANHL 1
+_ACEOF
+
fi
;;
*-mingw32*)
@@ -73062,7 +73399,7 @@ echo "${ECHO_T}$gxx_include_dir" >&6
OPTIMIZE_CXXFLAGS=
- WARN_FLAGS='-Wall -W -Wwrite-strings -Wcast-qual'
+ WARN_FLAGS='-Wall -Wextra -Wwrite-strings -Wcast-qual'
diff --git a/libstdc++-v3/crossconfig.m4 b/libstdc++-v3/crossconfig.m4
index 2c395e2c355..faa19d92e72 100644
--- a/libstdc++-v3/crossconfig.m4
+++ b/libstdc++-v3/crossconfig.m4
@@ -125,7 +125,7 @@ case "${host}" in
*-linux* | *-uclinux* | *-gnu* | *-kfreebsd*-gnu | *-knetbsd*-gnu)
AC_CHECK_HEADERS([nan.h ieeefp.h endian.h sys/isa_defs.h \
machine/endian.h machine/param.h sys/machine.h sys/types.h \
- fp.h locale.h float.h inttypes.h])
+ fp.h float.h endian.h inttypes.h locale.h float.h stdint.h])
SECTION_FLAGS='-ffunction-sections -fdata-sections'
AC_SUBST(SECTION_FLAGS)
GLIBCXX_CHECK_LINKER_FEATURES
@@ -151,23 +151,69 @@ case "${host}" in
AC_CHECK_HEADERS(sys/uio.h)
GLIBCXX_CHECK_WRITEV
+ AC_DEFINE(HAVE_ACOSF)
+ AC_DEFINE(HAVE_ASINF)
+ AC_DEFINE(HAVE_ATANF)
+ AC_DEFINE(HAVE_ATAN2F)
+ AC_DEFINE(HAVE_CEILF)
AC_DEFINE(HAVE_COPYSIGN)
AC_DEFINE(HAVE_COPYSIGNF)
+ AC_DEFINE(HAVE_COSF)
+ AC_DEFINE(HAVE_COSHF)
+ AC_DEFINE(HAVE_EXPF)
+ AC_DEFINE(HAVE_FABSF)
AC_DEFINE(HAVE_FINITE)
AC_DEFINE(HAVE_FINITEF)
+ AC_DEFINE(HAVE_FLOORF)
+ AC_DEFINE(HAVE_FMODF)
AC_DEFINE(HAVE_FREXPF)
+ AC_DEFINE(HAVE_HYPOT)
AC_DEFINE(HAVE_HYPOTF)
AC_DEFINE(HAVE_ISINF)
AC_DEFINE(HAVE_ISINFF)
AC_DEFINE(HAVE_ISNAN)
AC_DEFINE(HAVE_ISNANF)
+ AC_DEFINE(HAVE_LOGF)
+ AC_DEFINE(HAVE_LOG10F)
+ AC_DEFINE(HAVE_MODFF)
+ AC_DEFINE(HAVE_SIGNBIT)
+ AC_DEFINE(HAVE_SIGNBITF)
+ AC_DEFINE(HAVE_SINF)
+ AC_DEFINE(HAVE_SINHF)
AC_DEFINE(HAVE_SINCOS)
AC_DEFINE(HAVE_SINCOSF)
+ AC_DEFINE(HAVE_SQRTF)
+ AC_DEFINE(HAVE_TANF)
+ AC_DEFINE(HAVE_TANHF)
if test x"long_double_math_on_this_cpu" = x"yes"; then
+ AC_DEFINE(HAVE_ACOSL)
+ AC_DEFINE(HAVE_ASINL)
+ AC_DEFINE(HAVE_ATANL)
+ AC_DEFINE(HAVE_ATAN2L)
+ AC_DEFINE(HAVE_CEILL)
+ AC_DEFINE(HAVE_COPYSIGNL)
+ AC_DEFINE(HAVE_COSL)
+ AC_DEFINE(HAVE_COSHL)
+ AC_DEFINE(HAVE_EXPL)
+ AC_DEFINE(HAVE_FABSL)
AC_DEFINE(HAVE_FINITEL)
+ AC_DEFINE(HAVE_FLOORL)
+ AC_DEFINE(HAVE_FMODL)
+ AC_DEFINE(HAVE_FREXPL)
AC_DEFINE(HAVE_HYPOTL)
AC_DEFINE(HAVE_ISINFL)
AC_DEFINE(HAVE_ISNANL)
+ AC_DEFINE(HAVE_LOGL)
+ AC_DEFINE(HAVE_LOG10L)
+ AC_DEFINE(HAVE_MODFL)
+ AC_DEFINE(HAVE_POWL)
+ AC_DEFINE(HAVE_SIGNBITL)
+ AC_DEFINE(HAVE_SINL)
+ AC_DEFINE(HAVE_SINHL)
+ AC_DEFINE(HAVE_SINCOSL)
+ AC_DEFINE(HAVE_SQRTL)
+ AC_DEFINE(HAVE_TANL)
+ AC_DEFINE(HAVE_TANHL)
fi
;;
*-mingw32*)
diff --git a/libstdc++-v3/docs/html/17_intro/TODO b/libstdc++-v3/docs/html/17_intro/TODO
index 1670f042e28..93685fa3c9e 100644
--- a/libstdc++-v3/docs/html/17_intro/TODO
+++ b/libstdc++-v3/docs/html/17_intro/TODO
@@ -2,16 +2,13 @@ std::allocator
- switch to mt_allocator with --enable-threads=posix.
- - Try to figure out a way to switch allocators in a more elegant
- manner, and make the default allocator configurable.
-
- persistent allocator
- global/extern allocator
std::string
- - re-design for multi-paradigm, meta string class solution incorporating COW
+ - Policy-based design incorporating COW
vs. deep copy issues, MT scalability
See Andrei Alexandrescu, June 2001, C/C++ Users Journal
"Generic<Programming>: A Policy-Based basic_string Implementation"
@@ -53,8 +50,6 @@ std::locale
- minimize ctype convertion in data facets, see numpunct/num_put/num_get
- - finish caching data facets and using the caches
-
std::basic_filebuf, 27_io
- wfilebuf, get variable-encoding working and tested, including
@@ -86,11 +81,11 @@ testsuite
- diffing generated output files
+ - provide testsuites for numerics.
+
- make check-abi needs to have full symbol checking. Scope the LSB
testsuite, see what's going on with the typeinfo etc. bits.
- - provide testsuites for numerics.
-
- try to do a better job of ABI testing, with instantiations of all
standard-specified types checked, not just exported symbols.
@@ -140,9 +135,6 @@ Nathan's commentary on cantrip, http://www.cantrip.org/cheaders.html
- auto_ptr: seems to be some disagreement on what is
standards-conformant behavior, specially on conversion operators.
-- looks like deque::get_allocator not standards conformant or deque
-allocator non-standard.
-
- list::assignment operator needs const_cast
- a cleaner division between pointers-to-value_type and true iterators
diff --git a/libstdc++-v3/docs/html/abi.html b/libstdc++-v3/docs/html/abi.html
new file mode 100644
index 00000000000..421c1706cea
--- /dev/null
+++ b/libstdc++-v3/docs/html/abi.html
@@ -0,0 +1,880 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta name="AUTHOR" content="bkoz@gcc.gnu.org (Benjamin Kosnik)" />
+ <meta name="KEYWORDS" content="C++, libstdc++, dynamic, shared, library, ABI, version" />
+ <meta name="DESCRIPTION" content="C++ Standard Library ABI" />
+ <meta name="GENERATOR" content="emacs and ten fingers" />
+ <title>Standard C++ Library ABI</title>
+<link rel="StyleSheet" href="lib3styles.css" type="text/css" />
+<link rel="Start" href="documentation.html" type="text/html"
+ title="GNU C++ Standard Library" />
+<link rel="Copyright" href="17_intro/license.html" type="text/html" />
+</head>
+<body>
+
+<h1 class="centered"><a name="top">C++ Standard Library ABI</a></h1>
+
+<p class="fineprint"><em>
+ The latest version of this document is always available at
+ <a href="http://gcc.gnu.org/onlinedocs/libstdc++/abi.html">
+ http://gcc.gnu.org/onlinedocs/libstdc++/abi.html</a>.
+</em></p>
+
+<p><em>
+ To the <a href="http://gcc.gnu.org/libstdc++/">libstdc++-v3 homepage</a>.
+</em></p>
+
+<!-- ####################################################### -->
+<hr />
+<h3 class="left">
+ <a name="CXXinterface">The C++ interface</a>
+</h3>
+
+<p> C++ applications often dependent on specific language support
+routines, say for throwing exceptions, or catching exceptions, and
+perhaps also dependent on features in the C++ Standard Library.
+</p>
+
+<p> The C++ Standard Library has many include files, types defined in
+those include files, specific named functions, and other behavior. The
+text of these behaviors, as written in source include files, is called
+the Application Programing Interface, or API.
+</p>
+
+<p> Furthermore, C++ source that is compiled into object files is
+ transformed by the compiler: it arranges objects with specific
+ alignment and in a particular layout, mangling names according to a
+ well-defined algorithm, has specific arrangements for the support of
+ virtual functions, etc. These details are defined as the compiler
+ Application Binary Interface, or ABI. The GNU C++ compiler uses an
+ industry-standard C++ ABI starting with version 3. Details can be
+ found in the <a href="http://www.codesourcery.com/cxx-abi/abi.html">
+ ABI specification</a>.
+</p>
+
+<p>
+ The GNU C++ compiler, g++, has a compiler command line option to
+ switch between various different C++ ABIs. This explicit version
+ switch is the flag <code> -fabi-version</code>. In addition, some
+ g++ command line options may change the ABI as a side-effect of
+ use. Such flags include <code>-fpack-struct</code> and
+ <code>-fno-exceptions</code>, but include others: see the complete
+ list in the GCC manual under the heading <a
+ href="http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code%20Gen%20Options">Options
+ for Code Generation Conventions</a>.
+</p>
+
+<p> The configure options used when building a specific libstdc++
+version may also impact the resulting library ABI. The available
+configure options, and their impact on the library ABI, are documented
+<a href="http://gcc.gnu.org/onlinedocs/libstdc++/configopts.html">
+here</a>.
+</p>
+
+<p> Putting all of these ideas together results in the C++ Standard
+library ABI, which is the compilation of a given library API by a
+given compiler ABI. In a nutshell:
+</p>
+
+<code> library API + compiler ABI = library ABI</code>
+
+<p>
+ The library ABI is mostly of interest for end-users who have
+ unresolved symbols and are linking dynamically to the C++ Standard
+ library, and who thus must be careful to compile their application
+ with a compiler that is compatible with the available C++ Standard
+ library binary. In this case, compatible is defined with the equation
+ above: given an application compiled with a given compiler ABI and
+ library API, it will work correctly with a Standard C++ Library
+ created with the same constraints.
+</p>
+
+<p>
+ To use a specific version of the C++ ABI, one must use a
+ corresponding GNU C++ toolchain (Ie, g++ and libstdc++) that
+ implements the C++ ABI in question.
+</p>
+
+<h3 class="left">
+ <a name="ABI_versioning">Versioning</a>
+</h3>
+
+<p> The C++ interface has evolved throughout the history of the GNU
+C++ toolchain. With each release, various details have been changed so
+as to give distinct versions to the C++ interface.
+</p>
+
+<h5 class="left">
+ <a name="goals">Goals of versioning</a>
+</h5>
+
+<p>Extending existing, stable ABIs. Versioning gives subsequent stable
+releases series libraries the ability to add new symbols and add
+functionality, all the while retaining backwards compatibility with
+the previous releases in the series. Note: the reverse is not true. It
+is not possible to take binaries linked with the latest version of a
+release series (if symbols have been added) and expect the initial
+release of the series to remain link compatible.
+</p>
+
+<p>Allows multiple, incompatible ABIs to coexist at the same time.
+</p>
+
+<p>
+</p>
+
+<h5 class="left">
+ <a name="details"> Version History </a>
+</h5>
+<p>
+ How can this complexity be managed? What does C++ versioning mean?
+ Because library and compiler changes often make binaries compiled
+ with one version of the GNU tools incompatible with binaries
+ compiled with other (either newer or older) versions of the same GNU
+ tools, specific techniques are used to make managing this complexity
+ easier.
+</p>
+
+<p>
+ The following techniques are used:
+</p>
+
+ <ul>
+
+ <li> <p>Release versioning on the libgcc_s.so binary. This is
+implemented via file names and the ELF DT_SONAME mechanism (at least
+on ELF systems).</p>
+
+ <p>It is versioned as follows:
+ </p>
+ <ul>
+ <li>gcc-3.0.0: libgcc_s.so.1</li>
+ <li>gcc-3.0.1: libgcc_s.so.1</li>
+ <li>gcc-3.0.2: libgcc_s.so.1</li>
+ <li>gcc-3.0.3: libgcc_s.so.1</li>
+ <li>gcc-3.0.4: libgcc_s.so.1</li>
+ <li>gcc-3.1.0: libgcc_s.so.1</li>
+ <li>gcc-3.1.1: libgcc_s.so.1</li>
+ <li>gcc-3.2.0: libgcc_s.so.1</li>
+ <li>gcc-3.2.1: libgcc_s.so.1</li>
+ <li>gcc-3.2.2: libgcc_s.so.1</li>
+ <li>gcc-3.2.3: libgcc_s.so.1</li>
+ <li>gcc-3.3.0: libgcc_s.so.1</li>
+ <li>gcc-3.3.1: libgcc_s.so.1</li>
+ <li>gcc-3.3.2: libgcc_s.so.1</li>
+ <li>gcc-3.3.3: libgcc_s.so.1</li>
+ <li>gcc-3.4.0: libgcc_s.so.1</li>
+ </ul>
+ <p></p>
+ </li>
+
+ <li>Release versioning on the libstdc++.so binary, implemented in the same was as the libgcc_s.so binary, above.
+
+ <p>It is versioned as follows:
+ </p>
+ <ul>
+ <li>gcc-3.0.0: libstdc++.so.3.0.0</li>
+ <li>gcc-3.0.1: libstdc++.so.3.0.1</li>
+ <li>gcc-3.0.2: libstdc++.so.3.0.2</li>
+ <li>gcc-3.0.3: libstdc++.so.3.0.2 (Error should be libstdc++.so.3.0.3)</li>
+ <li>gcc-3.0.4: libstdc++.so.3.0.4</li>
+ <li>gcc-3.1.0: libstdc++.so.4.0.0</li>
+ <li>gcc-3.1.1: libstdc++.so.4.0.1</li>
+ <li>gcc-3.2.0: libstdc++.so.5.0.0</li>
+ <li>gcc-3.2.1: libstdc++.so.5.0.1</li>
+ <li>gcc-3.2.2: libstdc++.so.5.0.2</li>
+ <li>gcc-3.2.3: libstdc++.so.5.0.3 (Not strictly required)</li>
+ <li>gcc-3.3.0: libstdc++.so.5.0.4</li>
+ <li>gcc-3.3.1: libstdc++.so.5.0.5</li>
+ <li>gcc-3.3.2: libstdc++.so.5.0.5</li>
+ <li>gcc-3.3.3: libstdc++.so.5.0.5</li>
+ <li>gcc-3.4.0: libstdc++.so.6.0.0</li>
+ </ul>
+ <p></p>
+ </li>
+
+ <li>Symbol versioning on the libgcc_s.so binary.
+ <p>mapfile: gcc/libgcc-std.ver</p>
+
+ <p>It is versioned with the following labels and version definitions:</p>
+ <ul>
+ <li>gcc-3.0.0: GCC_3.0</li>
+ <li>gcc-3.0.1: GCC_3.0</li>
+ <li>gcc-3.0.2: GCC_3.0</li>
+ <li>gcc-3.0.3: GCC_3.0</li>
+ <li>gcc-3.0.4: GCC_3.0</li>
+ <li>gcc-3.1.0: GCC_3.0</li>
+ <li>gcc-3.1.1: GCC_3.0</li>
+ <li>gcc-3.2.0: GCC_3.0</li>
+ <li>gcc-3.2.1: GCC_3.0</li>
+ <li>gcc-3.2.2: GCC_3.0</li>
+ <li>gcc-3.2.3: GCC_3.0</li>
+ <li>gcc-3.3.0: GCC_3.0</li>
+ <li>gcc-3.3.1: GCC_3.0</li>
+ <li>gcc-3.3.2: GCC_3.0</li>
+ <li>gcc-3.3.3: GCC_3.0</li>
+ <li>gcc-3.4.0: GCC_3.0</li>
+ </ul>
+ <p></p>
+ </li>
+
+ <li>Symbol versioning on the libstdc++.so binary.
+
+ <p>mapfile: libstdc++-v3/config/linker-map.gnu</p>
+ <p>It is versioned with the following labels and version
+ definitions, where the version definition is the maximum for a
+ particular release. Note, only symbol which are newly introduced
+ will use the maximum version definition. Thus, for release series
+ with the same label, but incremented version definitions, the later
+ release has both versions. (An example of this would be the
+ gcc-3.2.1 release, which has GLIBCPP_3.2.1 for new symbols and
+ GLIBCPP_3.2 for symbols that were introduced in the gcc-3.2.0
+ release.)
+ </p>
+ <ul>
+ <li>gcc-3.0.0: (Error, not versioned)</li>
+ <li>gcc-3.0.1: (Error, not versioned)</li>
+ <li>gcc-3.0.2: (Error, not versioned)</li>
+ <li>gcc-3.0.3: (Error, not versioned)</li>
+ <li>gcc-3.0.4: (Error, not versioned)</li>
+ <li>gcc-3.1.0: GLIBCPP_3.1, CXXABI_1</li>
+ <li>gcc-3.1.1: GLIBCPP_3.1, CXXABI_1</li>
+ <li>gcc-3.2.0: GLIBCPP_3.2, CXXABI_1.2</li>
+ <li>gcc-3.2.1: GLIBCPP_3.2.1, CXXABI_1.2</li>
+ <li>gcc-3.2.2: GLIBCPP_3.2.2, CXXABI_1.2</li>
+ <li>gcc-3.2.3: GLIBCPP_3.2.2, CXXABI_1.2</li>
+ <li>gcc-3.3.0: GLIBCPP_3.2.2, CXXABI_1.2.1</li>
+ <li>gcc-3.3.1: GLIBCPP_3.2.3, CXXABI_1.2.1</li>
+ <li>gcc-3.3.2: GLIBCPP_3.2.3, CXXABI_1.2.1</li>
+ <li>gcc-3.3.3: GLIBCPP_3.2.3, CXXABI_1.2.1</li>
+ <li>gcc-3.4.0: GLIBCXX_3.4, CXXABI_1.3</li>
+ </ul>
+ <p></p>
+ </li>
+
+ <li>
+ <p>Incremental bumping of a compiler pre-defined macro,
+ __GXX_ABI_VERSION. This macro is defined as the version of the
+ compiler v3 ABI, with g++ 3.0.x being version 100. This macro will
+ be automatically defined whenever g++ is used (the curious can
+ test this by invoking g++ with the '-v' flag.)
+ </p>
+
+ <p>
+ This macro was defined in the file "lang-specs.h" in the gcc/cp directory.
+ Later versions defined it in "c-common.c" in the gcc directory, and from
+ G++ 3.4 it is defined in c-cppbuiltin.c and its value determined by the
+ '-fabi-version' command line option.
+ </p>
+
+ <p>
+ It is versioned as follows, where 'n' is given by '-fabi-version=n':
+ </p>
+ <ul>
+ <li>gcc-3.0.x: 100</li>
+ <li>gcc-3.1.x: 100 (Error, should be 101)</li>
+ <li>gcc-3.2.x: 102</li>
+ <li>gcc-3.3.x: 102</li>
+ <li>gcc-3.4.x: 102 (when n=1)</li>
+ <li>gcc-3.4.x: 1000+n (when n&gt;1)</li>
+ <li>gcc-3.4.x: 999999 (when n=0)</li>
+ </ul>
+ <p></p>
+ </li>
+
+ <li>
+ <p>Changes to the default compiler option for
+ <code>-fabi-version</code>.
+ </p>
+ <p>
+ It is versioned as follows:
+ </p>
+ <ul>
+ <li>gcc-3.0.x: (Error, not versioned) </li>
+ <li>gcc-3.1.x: (Error, not versioned) </li>
+ <li>gcc-3.2.x: <code>-fabi-version=1</code></li>
+ <li>gcc-3.3.x: <code>-fabi-version=1</code></li>
+ <li>gcc-3.4.x: <code>-fabi-version=2</code></li>
+ </ul>
+ <p></p>
+ </li>
+
+ <li>
+ <p>Incremental bumping of a library pre-defined macro. For releases
+ before 3.4.0, the macro is __GLIBCPP__. For later releases, it's
+ __GLIBCXX__. (The libstdc++ project generously changed from CPP to
+ CXX throughout its source to allow the "C" pre-processor the CPP
+ macro namespace.) These macros are defined as the date the library
+ was released, in compressed ISO date format, as an unsigned long.
+ </p>
+
+ <p>
+ In addition, the pre-defined macro is defined in the file
+ "c++config" in the "libstdc++-v3/include/bits" directory and is
+ changed every night by an automated script.
+ </p>
+ <p>
+ It is versioned as follows:
+ </p>
+ <ul>
+ <li>gcc-3.0.0: 20010615</li>
+ <li>gcc-3.0.1: 20010819</li>
+ <li>gcc-3.0.2: 20011023</li>
+ <li>gcc-3.0.3: 20011220</li>
+ <li>gcc-3.0.4: 20020220</li>
+ <li>gcc-3.1.0: 20020514</li>
+ <li>gcc-3.1.1: 20020725</li>
+ <li>gcc-3.2.0: 20020814</li>
+ <li>gcc-3.2.1: 20021119</li>
+ <li>gcc-3.2.2: 20030205</li>
+ <li>gcc-3.2.3: 20030422</li>
+ <li>gcc-3.3.0: 20030513</li>
+ <li>gcc-3.3.1: 20030804</li>
+ <li>gcc-3.3.2: 20031016</li>
+ <li>gcc-3.3.3: 20040214</li>
+ <li>gcc-3.4.0: 20040419</li>
+ </ul>
+ <p></p>
+ </li>
+
+
+ <li>
+ <p>
+ Incremental bumping of a library pre-defined macro,
+ _GLIBCPP_VERSION. This macro is defined as the released version of
+ the library, as a string literal. This is only implemented in
+ gcc-3.1.0 releases and higher, and is deprecated in 3.4 (where it
+ is called _GLIBCXX_VERSION).
+ </p>
+
+ <p>
+ This macro is defined in the file "c++config" in the
+ "libstdc++-v3/include/bits" directory and is generated
+ automatically by autoconf as part of the configure-time generation
+ of config.h.
+ </p>
+
+ <p>
+ It is versioned as follows:
+ </p>
+ <ul>
+ <li>gcc-3.0.0: "3.0.0"</li>
+ <li>gcc-3.0.1: "3.0.0" (Error, should be "3.0.1")</li>
+ <li>gcc-3.0.2: "3.0.0" (Error, should be "3.0.2")</li>
+ <li>gcc-3.0.3: "3.0.0" (Error, should be "3.0.3")</li>
+ <li>gcc-3.0.4: "3.0.0" (Error, should be "3.0.4")</li>
+ <li>gcc-3.1.0: "3.1.0"</li>
+ <li>gcc-3.1.1: "3.1.1"</li>
+ <li>gcc-3.2.0: "3.2"</li>
+ <li>gcc-3.2.1: "3.2.1"</li>
+ <li>gcc-3.2.2: "3.2.2"</li>
+ <li>gcc-3.2.3: "3.2.3"</li>
+ <li>gcc-3.3.0: "3.3"</li>
+ <li>gcc-3.3.1: "3.3.1"</li>
+ <li>gcc-3.3.2: "3.3.2"</li>
+ <li>gcc-3.3.3: "3.3.3"</li>
+ <li>gcc-3.4.0: "version-unused"</li>
+ </ul>
+ <p></p>
+ </li>
+
+ <li>
+ <p>
+ Matching each specific C++ compiler release to a specific set of
+ C++ include files. This is only implemented in gcc-3.1.1 releases
+ and higher.
+ </p>
+ <p>
+ All C++ includes are installed in include/c++, then nest in a
+ directory hierarchy corresponding to the C++ compiler's released
+ version. This version corresponds to the variable "gcc_version" in
+ "libstdc++-v3/acinclude.m4," and more details can be found in that
+ file's macro GLIBCXX_CONFIGURE (GLIBCPP_CONFIGURE before gcc-3.4.0).
+ </p>
+ <p>
+ C++ includes are versioned as follows:
+ </p>
+ <ul>
+ <li>gcc-3.0.0: include/g++-v3</li>
+ <li>gcc-3.0.1: include/g++-v3</li>
+ <li>gcc-3.0.2: include/g++-v3</li>
+ <li>gcc-3.0.3: include/g++-v3</li>
+ <li>gcc-3.0.4: include/g++-v3</li>
+ <li>gcc-3.1.0: include/g++-v3</li>
+ <li>gcc-3.1.1: include/c++/3.1.1</li>
+ <li>gcc-3.2.0: include/c++/3.2</li>
+ <li>gcc-3.2.1: include/c++/3.2.1</li>
+ <li>gcc-3.2.2: include/c++/3.2.2</li>
+ <li>gcc-3.2.3: include/c++/3.2.3</li>
+ <li>gcc-3.3.0: include/c++/3.3</li>
+ <li>gcc-3.3.1: include/c++/3.3.1</li>
+ <li>gcc-3.3.2: include/c++/3.3.2</li>
+ <li>gcc-3.3.3: include/c++/3.3.3</li>
+ <li>gcc-3.4.0: include/c++/3.4.0</li>
+ </ul>
+ <p></p>
+ </li>
+ </ul>
+<p>
+ Taken together, these techniques can accurately specify interface
+ and implementation changes in the GNU C++ tools themselves. Used
+ properly, they allow both the GNU C++ tools implementation, and
+ programs using them, an evolving yet controlled development that
+ maintains backward compatibility.
+</p>
+
+
+
+<h5 class="left">
+ <a name="requirements"> Minimum requirements for a versioned ABI </a>
+</h5>
+<p>
+ Minimum environment that supports a versioned ABI: A supported
+ dynamic linker, a GNU linker of sufficient vintage to understand
+ demangled C++ name globbing (ld), a shared executable compiled with
+ g++, and shared libraries (libgcc_s, libstdc++-v3) compiled by a
+ compiler (g++) with a compatible ABI. Phew.
+</p>
+
+<p>
+ On top of all that, an additional constraint: libstdc++ did not
+ attempt to version symbols (or age gracefully, really) until version
+ 3.1.0.
+</p>
+
+<p>
+ Most modern Linux and BSD versions, particularly ones using
+ gcc-3.1.x tools and more recent vintages, will meet the requirements above.
+</p>
+
+
+<h5 class="left">
+ <a name="config"> What configure options impact symbol versioning? </a>
+</h5>
+<p>
+ It turns out that most of the configure options that change default
+ behavior will impact the mangled names of exported symbols, and thus
+ impact versioning and compatibility.
+</p>
+
+<p>
+ For more information on configure options, including ABI impacts, see:
+ http://gcc.gnu.org/onlinedocs/libstdc++/configopts.html
+</p>
+
+<p>
+ There is one flag that explicitly deals with symbol versioning:
+ --enable-symvers.
+</p>
+
+<p>
+ In particular, libstdc++-v3/acinclude.m4 has a macro called
+ GLIBCXX_ENABLE_SYMVERS that defaults to yes (or the argument passed
+ in via --enable-symvers=foo). At that point, the macro attempts to
+ make sure that all the requirement for symbol versioning are in
+ place. For more information, please consult acinclude.m4.
+</p>
+
+
+<h5 class="left">
+ <a name="active"> How to tell if symbol versioning is, indeed, active? </a>
+</h5>
+<p>
+ When the GNU C++ library is being built with symbol versioning on,
+ you should see the following at configure time for libstdc++-v3:
+</p>
+
+
+<code> checking versioning on shared library symbols... gnu</code>
+
+<p>
+ If you don't see this line in the configure output, or if this line
+ appears but the last word is 'no', then you are out of luck.
+</p>
+
+<p>
+ If the compiler is pre-installed, a quick way to test is to compile
+ the following (or any) simple C++ file and link it to the shared
+ libstdc++ library:
+</p>
+
+<pre>
+#include &lt;iostream&gt;
+
+int main()
+{ std::cout &lt;&lt; "hello" &lt;&lt; std::endl; return 0; }
+
+%g++ hello.cc -o hello.out
+
+%ldd hello.out
+ libstdc++.so.5 =&gt; /usr/lib/libstdc++.so.5 (0x00764000)
+ libm.so.6 =&gt; /lib/tls/libm.so.6 (0x004a8000)
+ libgcc_s.so.1 =&gt; /mnt/hd/bld/gcc/gcc/libgcc_s.so.1 (0x40016000)
+ libc.so.6 =&gt; /lib/tls/libc.so.6 (0x0036d000)
+ /lib/ld-linux.so.2 =&gt; /lib/ld-linux.so.2 (0x00355000)
+
+%nm hello.out
+</pre>
+
+<p>
+If you see symbols in the resulting output with "GLIBCXX_3" as part
+of the name, then the executable is versioned. Here's an example:
+</p>
+
+ <code> U _ZNSt8ios_base4InitC1Ev@@GLIBCXX_3.4 </code>
+
+<h3 class="left">
+ <a name="ABI_allowed">Library allowed ABI changes</a>
+</h3>
+<p>
+The following will cause the library minor version number to
+increase, say from "libstdc++.so.3.0.4" to "libstdc++.so.3.0.5".
+</p>
+<ul>
+ <li>adding an exported global or static data member</li>
+ <li>adding an exported function, static or non-virtual member function</li>
+ <li>adding an exported symbol or symbols by additional instantiations</li>
+</ul>
+<p>
+</p>
+<p>
+Other allowed changes are possible.
+</p>
+
+
+<h3 class="left">
+ <a name="ABI_disallowed">Library disallowed ABI changes</a>
+</h3>
+
+<p>
+The following non-exhaustive list will cause the library major version
+number to increase, say from "libstdc++.so.3.0.4" to
+"libstdc++.so.4.0.0".
+</p>
+<ul>
+ <li>changes in the gcc/g++ compiler ABI</li>
+<li>changing size of an exported symbol</li>
+<li>changing alignment of an exported symbol</li>
+<li>changing the layout of an exported symbol</li>
+<li>changing mangling on an exported symbol</li>
+<li>deleting an exported symbol</li>
+<li>changing the inheritance properties of a type by adding or removing
+ base classes</li>
+<li>
+ changing the size, alignment, or layout of types
+ specified in the C++ standard. These may not necessarily be
+ instantiated or otherwise exported in the library binary, and
+ include all the required locale facets, as well as things like
+ std::basic_streambuf, et al.
+</li>
+</ul>
+
+<h3 class="left">
+ <a name="implementation">Library implementation strategy</a>
+</h3>
+
+<ul>
+ <li>Separation of interface and implementation
+<p>This is accomplished by two techniques that separate the API from
+the ABI: forcing undefined references to link against a library binary
+for definitions.
+</p>
+
+ <dl>
+ <dt>Include files have declarations, source files have defines</dt>
+
+ <dd> For non-templatized types, such as much of <code>class
+ locale</code>, the appropriate standard C++ include, say
+ <code>locale</code>, can contain full declarations, while various
+ source files (say <code> locale.cc, locale_init.cc,
+ localename.cc</code>) contain definitions.</dd>
+
+ <dt>Extern template on required types</dt>
+
+ <dd>For parts of the standard that have an explicit list of required
+ instantiations, the GNU extension syntax <code> extern template
+ </code> can be used to control where template definitions
+ reside. By marking required instantiations as <code> extern
+ template </code> in include files, and providing explicit
+ instantiations in the appropriate instantiation files, non-inlined
+ template functions can be versioned. This technique is mostly used
+ on parts of the standard that require <code> char</code> and <code>
+ wchar_t</code> instantiations, and includes <code>
+ basic_string</code>, the locale facets, and the types in <code>
+ iostreams</code>.</dd>
+
+ </dl>
+ <p> In addition, these techniques have the additional benefit that
+ they reduce binary size, which can increase runtime performance.
+ </p>
+ </li>
+
+ <li>Namespaces linking symbol definitions to export mapfiles
+
+<p>All symbols in the shared library binary are processed by a linker
+script at build time that either allows or disallows external
+linkage. Because of this, some symbols, regardless of normal C/C++
+linkage, are not visible. Symbols that are internal have several
+appealing characteristics: by not exporting the symbols, there are no
+relocations when the shared library is started and thus this makes for
+faster runtime loading performance by the underlying dynamic loading
+mechanism. In addition, they have the possibility of changing without
+impacting ABI compatibility.
+</p>
+
+<p>The following namespaces are transformed by the mapfile:</p>
+
+<dl>
+<dt><code>namespace std</code></dt>
+<dd> Defaults to exporting all symbols in label
+<code>GLIBCXX</code> that do not begin with an underscore, ie
+<code>__test_func</code> would not be exported by default. Select
+exceptional symbols are allowed to be visible.</dd>
+
+<dt><code>namespace __gnu_cxx</code></dt>
+<dd> Defaults to not exporting any symbols in label
+<code>GLIBCXX</code>, select items are allowed to be visible.</dd>
+
+<dt><code>namespace __gnu_internal</code></dt>
+<dd> Defaults to not exported, no items are allowed to be visible.</dd>
+
+<dt><code>namespace __cxxabiv1</code>, aliased to <code> namespace abi</code></dt>
+<dd> Defaults to not exporting any symbols in label
+<code>CXXABI</code>, select items are allowed to be visible.</dd>
+</dl>
+<p>
+</p>
+</li>
+
+ <li>Freezing the API
+ <p>Disallowed changes, as above, are not made on a stable release
+branch. Enforcement tends to be less strict with GNU extensions that
+standard includes.</p>
+</li>
+</ul>
+
+<h3 class="left">
+ <a name="ABI_testing">Testing ABI changes</a>
+</h3>
+
+<p>
+Testing for GNU C++ ABI changes is composed of two distinct areas:
+testing the C++ compiler (g++) for compiler changes, and testing the
+C++ library (libstdc++) for library changes.
+</p>
+
+<p>
+Testing the C++ compiler ABI can be done various ways.
+</p>
+
+<p>
+One.
+Intel ABI checker. More information can be obtained
+<a href="http://developer.intel.com/software/products/opensource/">here.</a>
+</p>
+
+<p>
+Two.
+The second is yet unreleased, but has been announced on the gcc
+mailing list. It is yet unspecified if these tools will be freely
+available, and able to be included in a GNU project. Please contact
+Mark Mitchell (mark@codesourcery.com) for more details, and current
+status.
+</p>
+
+<p>
+Three.
+Involves using the vlad.consistency test framework. This has also been
+discussed on the gcc mailing lists.
+</p>
+
+<p>
+Testing the C++ library ABI can also be done various ways.
+</p>
+
+<p>
+One.
+(Brendan Kehoe, Jeff Law suggestion to run 'make check-c++' two ways,
+one with a new compiler and an old library, and the other with an old
+compiler and a new library, and look for testsuite regressions)
+</p>
+
+<p>
+Details on how to set this kind of test up can be found here:
+http://gcc.gnu.org/ml/gcc/2002-08/msg00142.html
+</p>
+
+<p>
+Two.
+Use the 'make check-abi' rule in the libstdc++-v3 Makefile.
+</p>
+
+<p>
+This is a proactive check the library ABI. Currently, exported symbol
+names that are either weak or defined are checked against a last known
+good baseline. Currently, this baseline is keyed off of 3.2.0
+binaries, as this was the last time the .so number was incremented. In
+addition, all exported names are demangled, and the exported objects
+are checked to make sure they are the same size as the same object in
+the baseline.
+</p>
+
+<p>
+This dataset is insufficient, yet a start. Also needed is a
+comprehensive check for all user-visible types part of the standard
+library for sizeof() and alignof() changes.
+</p>
+
+<p>
+Verifying compatible layouts of objects is not even attempted. It
+should be possible to use sizeof, alignof, and offsetof to compute
+offsets for each structure and type in the standard library, saving to
+another datafile. Then, compute this in a similar way for new
+binaries, and look for differences.
+</p>
+
+<p>
+Another approach might be to use the -fdump-class-hierarchy flag to
+get information. However, currently this approach gives insufficient
+data for use in library testing, as class data members, their offsets,
+and other detailed data is not displayed with this flag.
+(See g++/7470 on how this was used to find bugs.)
+</p>
+
+<p>
+Perhaps there are other C++ ABI checkers. If so, please notify
+us. We'd like to know about them!
+</p>
+
+<h3 class="left">
+ <a name="ABI_multi_testing">Testing Multi-ABI binaries</a>
+</h3>
+
+<p>
+A "C" application, dynamically linked to two shared libraries, liba,
+libb. The dependent library liba is C++ shared library compiled with
+gcc-3.3.x, and uses io, exceptions, locale, etc. The dependent library
+libb is a C++ shared library compiled with gcc-3.4.x, and also uses io,
+exceptions, locale, etc.
+</p>
+
+<p> As above, libone is constructed as follows: </p>
+<pre>
+%$bld/H-x86-gcc-3.4.0/bin/g++ -fPIC -DPIC -c a.cc
+
+%$bld/H-x86-gcc-3.4.0/bin/g++ -shared -Wl,-soname -Wl,libone.so.1 -Wl,-O1 -Wl,-z,defs a.o -o libone.so.1.0.0
+
+%ln -s libone.so.1.0.0 libone.so
+
+%$bld/H-x86-gcc-3.4.0/bin/g++ -c a.cc
+
+%ar cru libone.a a.o
+</pre>
+
+<p> And, libtwo is constructed as follows: </p>
+
+<pre>
+%$bld/H-x86-gcc-3.3.3/bin/g++ -fPIC -DPIC -c b.cc
+
+%$bld/H-x86-gcc-3.3.3/bin/g++ -shared -Wl,-soname -Wl,libtwo.so.1 -Wl,-O1 -Wl,-z,defs b.o -o libtwo.so.1.0.0
+
+%ln -s libtwo.so.1.0.0 libtwo.so
+
+%$bld/H-x86-gcc-3.3.3/bin/g++ -c b.cc
+
+%ar cru libtwo.a b.o
+</pre>
+
+<p> ...with the resulting libraries looking like </p>
+<pre>
+%ldd libone.so.1.0.0
+ libstdc++.so.6 =&gt; /usr/lib/libstdc++.so.6 (0x40016000)
+ libm.so.6 =&gt; /lib/tls/libm.so.6 (0x400fa000)
+ libgcc_s.so.1 =&gt; /mnt/hd/bld/gcc/gcc/libgcc_s.so.1 (0x4011c000)
+ libc.so.6 =&gt; /lib/tls/libc.so.6 (0x40125000)
+ /lib/ld-linux.so.2 =&gt; /lib/ld-linux.so.2 (0x00355000)
+
+%ldd libtwo.so.1.0.0
+ libstdc++.so.5 =&gt; /usr/lib/libstdc++.so.5 (0x40027000)
+ libm.so.6 =&gt; /lib/tls/libm.so.6 (0x400e1000)
+ libgcc_s.so.1 =&gt; /mnt/hd/bld/gcc/gcc/libgcc_s.so.1 (0x40103000)
+ libc.so.6 =&gt; /lib/tls/libc.so.6 (0x4010c000)
+ /lib/ld-linux.so.2 =&gt; /lib/ld-linux.so.2 (0x00355000)
+
+</pre>
+
+<p> Then, the "C" compiler is used to compile a source file that uses
+functions from each library.</p>
+<pre>
+gcc test.c -g -O2 -L. -lone -ltwo /usr/lib/libstdc++.so.5 /usr/lib/libstdc++.so.6
+</pre>
+
+<p>
+Which gives the expected:
+</p>
+<pre>
+%ldd a.out
+ libstdc++.so.5 =&gt; /usr/lib/libstdc++.so.5 (0x00764000)
+ libstdc++.so.6 =&gt; /usr/lib/libstdc++.so.6 (0x40015000)
+ libc.so.6 =&gt; /lib/tls/libc.so.6 (0x0036d000)
+ libm.so.6 =&gt; /lib/tls/libm.so.6 (0x004a8000)
+ libgcc_s.so.1 =&gt; /mnt/hd/bld/gcc/gcc/libgcc_s.so.1 (0x400e5000)
+ /lib/ld-linux.so.2 =&gt; /lib/ld-linux.so.2 (0x00355000)
+</pre>
+
+<p>
+This resulting binary, when executed, will be able to safely use code
+from both liba, and the dependent libstdc++.so.6, and libb, with the
+dependent libstdc++.so.5.
+</p>
+
+<h3 class="left">
+ <a name="references">Bibliography / Further Reading</a>
+</h3>
+
+<p>
+ABIcheck, a vague idea of checking ABI compatibility
+<br />
+<a href="http://abicheck.sourceforge.net/">http://abicheck.sourceforge.net/</a>
+</p>
+
+<p>
+C++ ABI reference
+<br />
+<a href="http://www.codesourcery.com/cxx-abi/">http://www.codesourcery.com/cxx-abi/</a>
+</p>
+
+<p>
+Intel ABI documentation
+<br />
+"Intel® Compilers for Linux* -Compatibility with the GNU Compilers"
+<br />
+(included in icc 6.0)
+</p>
+
+<p>
+Sun Solaris 2.9 docs
+<br />
+Linker and Libraries Guide (document 816-1386)
+<br />
+C++ Migration Guide (document 816-2459)
+<br />
+<a href="http://docs.sun.com/db/prod/solaris.9">http://docs.sun.com/db/prod/solaris.9</a>
+<br />
+<a href="http://docs.sun.com/?p=/doc/816-1386&amp;a=load">http://docs.sun.com/?p=/doc/816-1386&amp;a=load</a>
+</p>
+
+<p>
+Ulrich Drepper, "ELF Symbol Versioning"
+<br />
+<a href="http://people.redhat.com/drepper/symbol-versioning">http://people.redhat.com/drepper/symbol-versioning</a>
+</p>
+
+</body>
+</html>
+
diff --git a/libstdc++-v3/docs/html/configopts.html b/libstdc++-v3/docs/html/configopts.html
index 6a2e214b39e..7e27ee0c5b7 100644
--- a/libstdc++-v3/docs/html/configopts.html
+++ b/libstdc++-v3/docs/html/configopts.html
@@ -135,7 +135,7 @@ options</a></h1>
<dd><p>Select a target-specific underlying std::allocator. The
choices are 'new' to specify a wrapper for new, 'malloc' to
specify a wrapper for malloc, 'mt' for a fixed power of two allocator
- (More <a href="http://sources.redhat.com/glibc/">info</a>) or
+ (<a href="ext/mt_allocator.html">documented</a> under extensions) or
'bitmap' for a bitmap allocator. This option can change the
library ABI.
</p>
diff --git a/libstdc++-v3/docs/html/documentation.html b/libstdc++-v3/docs/html/documentation.html
index 7819955b66b..d1aea5a926e 100644
--- a/libstdc++-v3/docs/html/documentation.html
+++ b/libstdc++-v3/docs/html/documentation.html
@@ -30,7 +30,7 @@
<ul>
<li><a href="17_intro/COPYING">License</a>
- GPL v2 license terms</li>
- <li><a href="abi.txt">ABI Policy and Guidelines</a></li>
+ <li><a href="abi.html">ABI Policy and Guidelines</a></li>
<li><a href="17_intro/BUGS">BUGS</a></li>
<li><a href="17_intro/PROBLEMS">PROBLEMS</a>
- target-specific known issues</li>
diff --git a/libstdc++-v3/docs/html/faq/index.html b/libstdc++-v3/docs/html/faq/index.html
index 4bfc6d456ed..9a8bbafbb36 100644
--- a/libstdc++-v3/docs/html/faq/index.html
+++ b/libstdc++-v3/docs/html/faq/index.html
@@ -395,16 +395,17 @@ which is no longer available, thanks deja...-->
<p>It's not a bug, and it's not really a problem. Nevertheless, some
people don't like it, so here are two pseudo-solutions:
</p>
- <p>If the only functions from libstdc++.a which you need are language
- support functions (those listed in
- <a href="../18_support/howto.html">clause 18</a> of the standard,
- e.g., <code>new</code> and <code>delete</code>), then try linking
- against <code>libsupc++.a</code> (usually specifying
- <code>-lsupc++</code> when calling g++ for the final link step will
- do it). This library contains only those support routines, one per
- object file. But if you are using anything from the rest of the
- library, such as IOStreams or vectors, then you'll still need
- pieces from <code>libstdc++.a</code>.
+ <p>If the only functions from libstdc++.a which you need are
+ language support functions (those listed in <a
+ href="../18_support/howto.html">clause 18</a> of the
+ standard, e.g., <code>new</code> and <code>delete</code>),
+ then try linking against <code>libsupc++.a</code> (Using
+ <code>gcc</code> instead of <code>g++</code> and explicitly
+ linking in <code>-lsupc++</code> for the final link step will
+ do it). This library contains only those support routines,
+ one per object file. But if you are using anything from the
+ rest of the library, such as IOStreams or vectors, then
+ you'll still need pieces from <code>libstdc++.a</code>.
</p>
<p>The second method is one we hope to incorporate into the library
build process. Some platforms can place each function and variable
diff --git a/libstdc++-v3/include/backward/iterator.h b/libstdc++-v3/include/backward/iterator.h
index 659176a73c5..8316a83d698 100644
--- a/libstdc++-v3/include/backward/iterator.h
+++ b/libstdc++-v3/include/backward/iterator.h
@@ -1,3 +1,32 @@
+// Backward-compat support -*- C++ -*-
+
+// Copyright (C) 2001, 2004 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file 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 General Public License.
+
/*
*
* Copyright (c) 1994
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index a33cdefdb53..6837e013fbb 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -1342,7 +1342,9 @@ namespace std
if (this->max_size() - (this->size() - __n1) < __n2)
__throw_length_error(__N("basic_string::_M_replace_aux"));
_M_mutate(__pos1, __n1, __n2);
- if (__n2)
+ if (__n2 == 1)
+ _M_data()[__pos1] = __c;
+ else if (__n2)
traits_type::assign(_M_data() + __pos1, __n2, __c);
return *this;
}
@@ -1352,7 +1354,9 @@ namespace std
size_type __n2)
{
_M_mutate(__pos1, __n1, __n2);
- if (__n2)
+ if (__n2 == 1)
+ _M_data()[__pos1] = *__s;
+ else if (__n2)
traits_type::copy(_M_data() + __pos1, __s, __n2);
return *this;
}
@@ -1960,7 +1964,7 @@ namespace std
* @param rhs Last string.
* @return New string with value of @a lhs followed by @a rhs.
*/
- template<typename _CharT, typename _Traits, typename _Alloc>
+ template<typename _CharT, typename _Traits, typename _Alloc>
basic_string<_CharT, _Traits, _Alloc>
operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc
index 4fa5e87fe22..7034778e9df 100644
--- a/libstdc++-v3/include/bits/basic_string.tcc
+++ b/libstdc++-v3/include/bits/basic_string.tcc
@@ -91,7 +91,7 @@ namespace std
if (__beg == __end && __a == _Alloc())
return _S_empty_rep()._M_refdata();
// Avoid reallocation for common case.
- _CharT __buf[100];
+ _CharT __buf[128];
size_type __len = 0;
while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT))
{
@@ -383,7 +383,6 @@ namespace std
{
const size_type __old_size = this->size();
const size_type __new_size = __old_size + __len2 - __len1;
- const _CharT* __src = _M_data() + __pos + __len1;
const size_type __how_much = __old_size - __pos - __len1;
if (_M_rep() == &_S_empty_rep()
@@ -397,7 +396,7 @@ namespace std
traits_type::copy(__r->_M_refdata(), _M_data(), __pos);
if (__how_much)
traits_type::copy(__r->_M_refdata() + __pos + __len2,
- __src, __how_much);
+ _M_data() + __pos + __len1, __how_much);
_M_rep()->_M_dispose(__a);
_M_data(__r->_M_refdata());
@@ -405,7 +404,8 @@ namespace std
else if (__how_much && __len1 != __len2)
{
// Work in-place
- traits_type::move(_M_data() + __pos + __len2, __src, __how_much);
+ traits_type::move(_M_data() + __pos + __len2,
+ _M_data() + __pos + __len1, __how_much);
}
_M_rep()->_M_set_sharable();
_M_rep()->_M_length = __new_size;
diff --git a/libstdc++-v3/include/bits/boost_concept_check.h b/libstdc++-v3/include/bits/boost_concept_check.h
index aef83af9474..7f255a72eeb 100644
--- a/libstdc++-v3/include/bits/boost_concept_check.h
+++ b/libstdc++-v3/include/bits/boost_concept_check.h
@@ -1,4 +1,30 @@
+// Copyright (C) 2004 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file 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 General Public License.
+
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 5dc04876523..ddaa8435d2d 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -1,6 +1,6 @@
// Predefined symbols and macros -*- C++ -*-
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -35,7 +35,7 @@
#include <bits/os_defines.h>
// The current version of the C++ library in compressed ISO date format.
-#define __GLIBCXX__ 20040413
+#define __GLIBCXX__ 20040514
// Allow use of "export template." This is currently not a feature
// that g++ supports.
@@ -51,27 +51,30 @@
# define _GLIBCXX_EXTERN_TEMPLATE 1
#endif
-// To enable debug mode.
-namespace __gnu_norm
-{
- using namespace std;
-}
-
+// Debug mode support. Debug mode basic_string is not allowed to be
+// associated with std, because of locale and exception link
+// dependence.
namespace __gnu_debug_def { }
namespace __gnu_debug
{
- using namespace __gnu_debug_def __attribute__ ((strong));
+ using namespace __gnu_debug_def;
}
+#ifdef _GLIBCXX_DEBUG
+# define _GLIBCXX_STD __gnu_norm
+namespace __gnu_norm
+{
+ using namespace std;
+}
namespace std
{
-#ifdef _GLIBCXX_DEBUG
using namespace __gnu_debug_def __attribute__ ((strong));
+}
#else
- using namespace __gnu_norm __attribute__ ((strong));
+# define _GLIBCXX_STD std
#endif
-}
+
// The remainder of the prewritten config is automatic; all the
// user hooks are listed above.
diff --git a/libstdc++-v3/include/bits/deque.tcc b/libstdc++-v3/include/bits/deque.tcc
index 22fc573d9c0..84191f5d91a 100644
--- a/libstdc++-v3/include/bits/deque.tcc
+++ b/libstdc++-v3/include/bits/deque.tcc
@@ -61,7 +61,7 @@
#ifndef _DEQUE_TCC
#define _DEQUE_TCC 1
-namespace __gnu_norm
+namespace _GLIBCXX_STD
{
template <typename _Tp, typename _Alloc>
deque<_Tp,_Alloc>&
@@ -131,7 +131,8 @@ namespace __gnu_norm
deque<_Tp,_Alloc>::
erase(iterator __first, iterator __last)
{
- if (__first == this->_M_impl._M_start && __last == this->_M_impl._M_finish)
+ if (__first == this->_M_impl._M_start
+ && __last == this->_M_impl._M_finish)
{
clear();
return this->_M_impl._M_finish;
@@ -139,13 +140,15 @@ namespace __gnu_norm
else
{
const difference_type __n = __last - __first;
- const difference_type __elems_before = __first - this->_M_impl._M_start;
+ const difference_type __elems_before = (__first
+ - this->_M_impl._M_start);
if (static_cast<size_type>(__elems_before) < (size() - __n) / 2)
{
std::copy_backward(this->_M_impl._M_start, __first, __last);
iterator __new_start = this->_M_impl._M_start + __n;
std::_Destroy(this->_M_impl._M_start, __new_start);
- _M_destroy_nodes(this->_M_impl._M_start._M_node, __new_start._M_node);
+ _M_destroy_nodes(this->_M_impl._M_start._M_node,
+ __new_start._M_node);
this->_M_impl._M_start = __new_start;
}
else
@@ -176,12 +179,15 @@ namespace __gnu_norm
if (this->_M_impl._M_start._M_node != this->_M_impl._M_finish._M_node)
{
- std::_Destroy(this->_M_impl._M_start._M_cur, this->_M_impl._M_start._M_last);
- std::_Destroy(this->_M_impl._M_finish._M_first, this->_M_impl._M_finish._M_cur);
+ std::_Destroy(this->_M_impl._M_start._M_cur,
+ this->_M_impl._M_start._M_last);
+ std::_Destroy(this->_M_impl._M_finish._M_first,
+ this->_M_impl._M_finish._M_cur);
_M_deallocate_node(this->_M_impl._M_finish._M_first);
}
else
- std::_Destroy(this->_M_impl._M_start._M_cur, this->_M_impl._M_finish._M_cur);
+ std::_Destroy(this->_M_impl._M_start._M_cur,
+ this->_M_impl._M_finish._M_cur);
this->_M_impl._M_finish = this->_M_impl._M_start;
}
@@ -217,7 +223,8 @@ namespace __gnu_norm
}
catch(...)
{
- _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node);
+ _M_destroy_nodes(__new_start._M_node,
+ this->_M_impl._M_start._M_node);
__throw_exception_again;
}
}
@@ -226,7 +233,8 @@ namespace __gnu_norm
iterator __new_finish = _M_reserve_elements_at_back(__n);
try
{
- std::uninitialized_fill(this->_M_impl._M_finish, __new_finish, __x);
+ std::uninitialized_fill(this->_M_impl._M_finish,
+ __new_finish, __x);
this->_M_impl._M_finish = __new_finish;
}
catch(...)
@@ -305,11 +313,13 @@ namespace __gnu_norm
std::uninitialized_copy(__first, __mid, *__cur_node);
__first = __mid;
}
- std::uninitialized_copy(__first, __last, this->_M_impl._M_finish._M_first);
+ std::uninitialized_copy(__first, __last,
+ this->_M_impl._M_finish._M_first);
}
catch(...)
{
- std::_Destroy(this->_M_impl._M_start, iterator(*__cur_node, __cur_node));
+ std::_Destroy(this->_M_impl._M_start,
+ iterator(*__cur_node, __cur_node));
__throw_exception_again;
}
}
@@ -326,7 +336,8 @@ namespace __gnu_norm
try
{
std::_Construct(this->_M_impl._M_finish._M_cur, __t_copy);
- this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node + 1);
+ this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node
+ + 1);
this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first;
}
catch(...)
@@ -347,7 +358,8 @@ namespace __gnu_norm
*(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node();
try
{
- this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node - 1);
+ this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node
+ - 1);
this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1;
std::_Construct(this->_M_impl._M_start._M_cur, __t_copy);
}
@@ -370,10 +382,11 @@ namespace __gnu_norm
std::_Destroy(this->_M_impl._M_finish._M_cur);
}
- // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_last - 1. Note that
- // if the deque has at least one element (a precondition for this member
- // function), and if _M_impl._M_start._M_cur == _M_impl._M_start._M_last, then the deque
- // must have at least two nodes.
+ // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_last - 1.
+ // Note that if the deque has at least one element (a precondition for this
+ // member function), and if
+ // _M_impl._M_start._M_cur == _M_impl._M_start._M_last,
+ // then the deque must have at least two nodes.
template <typename _Tp, typename _Alloc>
void deque<_Tp,_Alloc>::
_M_pop_front_aux()
@@ -412,7 +425,8 @@ namespace __gnu_norm
}
catch(...)
{
- _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node);
+ _M_destroy_nodes(__new_start._M_node,
+ this->_M_impl._M_start._M_node);
__throw_exception_again;
}
}
@@ -421,7 +435,8 @@ namespace __gnu_norm
iterator __new_finish = _M_reserve_elements_at_back(__n);
try
{
- std::uninitialized_copy(__first, __last, this->_M_impl._M_finish);
+ std::uninitialized_copy(__first, __last,
+ this->_M_impl._M_finish);
this->_M_impl._M_finish = __new_finish;
}
catch(...)
@@ -485,7 +500,8 @@ namespace __gnu_norm
{
if (__elems_before >= difference_type(__n))
{
- iterator __start_n = this->_M_impl._M_start + difference_type(__n);
+ iterator __start_n = (this->_M_impl._M_start
+ + difference_type(__n));
std::uninitialized_copy(this->_M_impl._M_start, __start_n,
__new_start);
this->_M_impl._M_start = __new_start;
@@ -494,16 +510,18 @@ namespace __gnu_norm
}
else
{
- std::__uninitialized_copy_fill(this->_M_impl._M_start, __pos,
- __new_start,
- this->_M_impl._M_start, __x_copy);
+ std::__uninitialized_copy_fill(this->_M_impl._M_start,
+ __pos, __new_start,
+ this->_M_impl._M_start,
+ __x_copy);
this->_M_impl._M_start = __new_start;
std::fill(__old_start, __pos, __x_copy);
}
}
catch(...)
{
- _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node);
+ _M_destroy_nodes(__new_start._M_node,
+ this->_M_impl._M_start._M_node);
__throw_exception_again;
}
}
@@ -518,7 +536,8 @@ namespace __gnu_norm
{
if (__elems_after > difference_type(__n))
{
- iterator __finish_n = this->_M_impl._M_finish - difference_type(__n);
+ iterator __finish_n = (this->_M_impl._M_finish
+ - difference_type(__n));
std::uninitialized_copy(__finish_n, this->_M_impl._M_finish,
this->_M_impl._M_finish);
this->_M_impl._M_finish = __new_finish;
@@ -563,7 +582,8 @@ namespace __gnu_norm
{
if (__elemsbefore >= difference_type(__n))
{
- iterator __start_n = this->_M_impl._M_start + difference_type(__n);
+ iterator __start_n = (this->_M_impl._M_start
+ + difference_type(__n));
std::uninitialized_copy(this->_M_impl._M_start, __start_n,
__new_start);
this->_M_impl._M_start = __new_start;
@@ -574,15 +594,17 @@ namespace __gnu_norm
{
_ForwardIterator __mid = __first;
std::advance(__mid, difference_type(__n) - __elemsbefore);
- std::__uninitialized_copy_copy(this->_M_impl._M_start, __pos,
- __first, __mid, __new_start);
+ std::__uninitialized_copy_copy(this->_M_impl._M_start,
+ __pos, __first, __mid,
+ __new_start);
this->_M_impl._M_start = __new_start;
std::copy(__mid, __last, __old_start);
}
}
catch(...)
{
- _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node);
+ _M_destroy_nodes(__new_start._M_node,
+ this->_M_impl._M_start._M_node);
__throw_exception_again;
}
}
@@ -597,7 +619,8 @@ namespace __gnu_norm
{
if (__elemsafter > difference_type(__n))
{
- iterator __finish_n = this->_M_impl._M_finish - difference_type(__n);
+ iterator __finish_n = (this->_M_impl._M_finish
+ - difference_type(__n));
std::uninitialized_copy(__finish_n,
this->_M_impl._M_finish,
this->_M_impl._M_finish);
@@ -714,6 +737,6 @@ namespace __gnu_norm
this->_M_impl._M_start._M_set_node(__new_nstart);
this->_M_impl._M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
}
-} // namespace __gnu_norm
+} // namespace std
#endif
diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc
index 19530e75c49..9f46279bea5 100644
--- a/libstdc++-v3/include/bits/fstream.tcc
+++ b/libstdc++-v3/include/bits/fstream.tcc
@@ -786,6 +786,8 @@ namespace std
if (__testvalid)
_M_codecvt = _M_codecvt_tmp;
+ else
+ _M_codecvt = 0;
}
// Inhibit implicit instantiations for required instantiations,
diff --git a/libstdc++-v3/include/bits/istream.tcc b/libstdc++-v3/include/bits/istream.tcc
index 3edb8cdeea1..21f809d7897 100644
--- a/libstdc++-v3/include/bits/istream.tcc
+++ b/libstdc++-v3/include/bits/istream.tcc
@@ -1,6 +1,6 @@
// istream classes -*- C++ -*-
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -29,7 +29,7 @@
// the GNU General Public License.
//
-// ISO C++ 14882: 27.6.2 Output streams
+// ISO C++ 14882: 27.6.1 Input streams
//
#ifndef _ISTREAM_TCC
@@ -592,27 +592,45 @@ namespace std
const int_type __eof = traits_type::eof();
__streambuf_type* __sb = this->rdbuf();
int_type __c = __sb->sgetc();
-
- while (_M_gcount + 1 < __n
+ --__n;
+
+ while (_M_gcount < __n
&& !traits_type::eq_int_type(__c, __eof)
&& !traits_type::eq_int_type(__c, __idelim))
{
- *__s++ = traits_type::to_char_type(__c);
- __c = __sb->snextc();
- ++_M_gcount;
+ streamsize __size = std::min(streamsize(__sb->egptr()
+ - __sb->gptr()),
+ __n - _M_gcount);
+ if (__size > 1)
+ {
+ const char_type* __p = traits_type::find(__sb->gptr(),
+ __size,
+ __delim);
+ if (__p)
+ __size = __p - __sb->gptr();
+ traits_type::copy(__s, __sb->gptr(), __size);
+ __s += __size;
+ __sb->gbump(__size);
+ _M_gcount += __size;
+ __c = __sb->sgetc();
+ }
+ else
+ {
+ *__s++ = traits_type::to_char_type(__c);
+ __c = __sb->snextc();
+ ++_M_gcount;
+ }
}
+
if (traits_type::eq_int_type(__c, __eof))
__err |= ios_base::eofbit;
- else
+ else if (traits_type::eq_int_type(__c, __idelim))
{
- if (traits_type::eq_int_type(__c, __idelim))
- {
- __sb->sbumpc();
- ++_M_gcount;
- }
- else
- __err |= ios_base::failbit;
+ __sb->sbumpc();
+ ++_M_gcount;
}
+ else
+ __err |= ios_base::failbit;
}
catch(...)
{ this->_M_setstate(ios_base::badbit); }
@@ -1084,23 +1102,39 @@ namespace std
{
try
{
+ // Avoid reallocation for common case.
__str.erase();
- __int_type __idelim = _Traits::to_int_type(__delim);
- __streambuf_type* __sb = __in.rdbuf();
- __int_type __c = __sb->sbumpc();
+ _CharT __buf[128];
+ __size_type __len = 0;
+ const __int_type __idelim = _Traits::to_int_type(__delim);
const __int_type __eof = _Traits::eof();
- __testdelim = _Traits::eq_int_type(__c, __idelim);
+ __streambuf_type* __sb = __in.rdbuf();
+ __int_type __c = __sb->sgetc();
- while (!_Traits::eq_int_type(__c, __eof) && !__testdelim
- && __extracted < __n)
+ while (__extracted < __n
+ && !_Traits::eq_int_type(__c, __eof)
+ && !_Traits::eq_int_type(__c, __idelim))
{
- __str += _Traits::to_char_type(__c);
+ if (__len == sizeof(__buf) / sizeof(_CharT))
+ {
+ __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
+ __len = 0;
+ }
+ __buf[__len++] = _Traits::to_char_type(__c);
++__extracted;
- __c = __sb->sbumpc();
- __testdelim = _Traits::eq_int_type(__c, __idelim);
+ __c = __sb->snextc();
}
+ __str.append(__buf, __len);
+
if (_Traits::eq_int_type(__c, __eof))
__err |= ios_base::eofbit;
+ else if (_Traits::eq_int_type(__c, __idelim))
+ {
+ __sb->sbumpc();
+ ++__extracted;
+ }
+ else
+ __err |= ios_base::failbit;
}
catch(...)
{
@@ -1110,7 +1144,7 @@ namespace std
__in._M_setstate(ios_base::badbit);
}
}
- if ((!__extracted && !__testdelim) || __extracted == __n)
+ if (!__extracted)
__err |= ios_base::failbit;
if (__err)
__in.setstate(__err);
diff --git a/libstdc++-v3/include/bits/list.tcc b/libstdc++-v3/include/bits/list.tcc
index f712be2ab0b..aaaa8c364bd 100644
--- a/libstdc++-v3/include/bits/list.tcc
+++ b/libstdc++-v3/include/bits/list.tcc
@@ -61,7 +61,7 @@
#ifndef _LIST_TCC
#define _LIST_TCC 1
-namespace __gnu_norm
+namespace _GLIBCXX_STD
{
template<typename _Tp, typename _Alloc>
void
@@ -371,7 +371,7 @@ namespace __gnu_norm
swap( *(__fill-1) );
}
}
-} // namespace __gnu_norm
+} // namespace std
#endif /* _LIST_TCC */
diff --git a/libstdc++-v3/include/bits/locale_classes.h b/libstdc++-v3/include/bits/locale_classes.h
index 926ce209b24..5366d652433 100644
--- a/libstdc++-v3/include/bits/locale_classes.h
+++ b/libstdc++-v3/include/bits/locale_classes.h
@@ -534,8 +534,10 @@ namespace std
_M_check_same_name()
{
bool __ret = true;
- for (size_t __i = 0; __ret && __i < _S_categories_size - 1; ++__i)
- __ret = std::strcmp(_M_names[__i], _M_names[__i + 1]) == 0;
+ if (_M_names[1])
+ // We must actually compare all the _M_names: can be all equal!
+ for (size_t __i = 0; __ret && __i < _S_categories_size - 1; ++__i)
+ __ret = std::strcmp(_M_names[__i], _M_names[__i + 1]) == 0;
return __ret;
}
@@ -569,30 +571,15 @@ namespace std
{
_M_impl = new _Impl(*__other._M_impl, 1);
- char* _M_tmp_names[_S_categories_size];
- size_t __i = 0;
try
- {
- for (; __i < _S_categories_size; ++__i)
- {
- _M_tmp_names[__i] = new char[2];
- std::strcpy(_M_tmp_names[__i], "*");
- }
- _M_impl->_M_install_facet(&_Facet::id, __f);
- }
+ { _M_impl->_M_install_facet(&_Facet::id, __f); }
catch(...)
{
_M_impl->_M_remove_reference();
- for (size_t __j = 0; __j < __i; ++__j)
- delete [] _M_tmp_names[__j];
__throw_exception_again;
}
-
- for (size_t __k = 0; __k < _S_categories_size; ++__k)
- {
- delete [] _M_impl->_M_names[__k];
- _M_impl->_M_names[__k] = _M_tmp_names[__k];
- }
+ delete [] _M_impl->_M_names[0];
+ _M_impl->_M_names[0] = 0; // Unnamed.
}
} // namespace std
diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h
index 453ba78f20a..c1d430db984 100644
--- a/libstdc++-v3/include/bits/locale_facets.h
+++ b/libstdc++-v3/include/bits/locale_facets.h
@@ -1161,8 +1161,8 @@ namespace std
_M_widen_ok = 1;
// Set _M_widen_ok to 2 if memcpy can't be used.
- for (size_t __i = 0; __i < sizeof(_M_widen); ++__i)
- if (__tmp[__i] != _M_widen[__i])
+ for (size_t __j = 0; __j < sizeof(_M_widen); ++__j)
+ if (__tmp[__j] != _M_widen[__j])
{
_M_widen_ok = 2;
break;
@@ -1182,11 +1182,11 @@ namespace std
// Check if any default values were created. Do this by
// renarrowing with a different default value and comparing.
bool __consecutive = true;
- for (size_t __i = 0; __i < sizeof(_M_narrow); ++__i)
- if (!_M_narrow[__i])
+ for (size_t __j = 0; __j < sizeof(_M_narrow); ++__j)
+ if (!_M_narrow[__j])
{
char __c;
- do_narrow(__tmp + __i, __tmp + __i + 1, 1, &__c);
+ do_narrow(__tmp + __j, __tmp + __j + 1, 1, &__c);
if (__c == 1)
{
__consecutive = false;
diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h
index 3ed04e5031b..afae738418d 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -1,4 +1,4 @@
-// bit_vector and vector<bool> specialization -*- C++ -*-
+// vector<bool> specialization -*- C++ -*-
// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
//
@@ -61,7 +61,7 @@
#ifndef _BVECTOR_H
#define _BVECTOR_H 1
-namespace __gnu_norm
+namespace _GLIBCXX_STD
{
typedef unsigned long _Bit_type;
enum { _S_word_bit = int(CHAR_BIT * sizeof(_Bit_type)) };
@@ -322,7 +322,8 @@ namespace __gnu_norm
return *this;
}
- const_iterator operator+(difference_type __i) const {
+ const_iterator
+ operator+(difference_type __i) const {
const_iterator __tmp = *this;
return __tmp += __i;
}
@@ -345,47 +346,52 @@ namespace __gnu_norm
template<class _Alloc>
class _Bvector_base
- : public _Alloc::template rebind<_Bit_type>::other
{
typedef typename _Alloc::template rebind<_Bit_type>::other
_Bit_alloc_type;
+
+ struct _Bvector_impl : public _Bit_alloc_type
+ {
+ _Bit_iterator _M_start;
+ _Bit_iterator _M_finish;
+ _Bit_type* _M_end_of_storage;
+ _Bvector_impl(const _Bit_alloc_type& __a)
+ : _Bit_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage(0)
+ { }
+ };
public:
typedef _Alloc allocator_type;
allocator_type
get_allocator() const
- { return *static_cast<const _Bit_alloc_type*>(this); }
+ { return *static_cast<const _Bit_alloc_type*>(&this->_M_impl); }
- _Bvector_base(const allocator_type& __a)
- : _Bit_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage(0) { }
+ _Bvector_base(const allocator_type& __a) : _M_impl(__a) { }
~_Bvector_base() { this->_M_deallocate(); }
protected:
+ _Bvector_impl _M_impl;
+
_Bit_type*
- _M_bit_alloc(size_t __n)
- { return _Bit_alloc_type::allocate((__n + _S_word_bit - 1)
- / _S_word_bit); }
+ _M_allocate(size_t __n)
+ { return _M_impl.allocate((__n + _S_word_bit - 1) / _S_word_bit); }
void
_M_deallocate()
{
- if (_M_start._M_p)
- _Bit_alloc_type::deallocate(_M_start._M_p,
- _M_end_of_storage - _M_start._M_p);
+ if (_M_impl._M_start._M_p)
+ _M_impl.deallocate(_M_impl._M_start._M_p,
+ _M_impl._M_end_of_storage - _M_impl._M_start._M_p);
}
-
- _Bit_iterator _M_start;
- _Bit_iterator _M_finish;
- _Bit_type* _M_end_of_storage;
};
-} // namespace __gnu_norm
+} // namespace std
// Declare a partial specialization of vector<T, Alloc>.
#include <bits/stl_vector.h>
-namespace __gnu_norm
+namespace _GLIBCXX_STD
{
/**
* @brief A specialization of vector for booleans which offers fixed time
@@ -429,41 +435,40 @@ template<typename _Alloc>
{ return _Bvector_base<_Alloc>::get_allocator(); }
protected:
- using _Bvector_base<_Alloc>::_M_bit_alloc;
+ using _Bvector_base<_Alloc>::_M_allocate;
using _Bvector_base<_Alloc>::_M_deallocate;
- using _Bvector_base<_Alloc>::_M_start;
- using _Bvector_base<_Alloc>::_M_finish;
- using _Bvector_base<_Alloc>::_M_end_of_storage;
protected:
void _M_initialize(size_type __n)
{
- _Bit_type* __q = this->_M_bit_alloc(__n);
- this->_M_end_of_storage = __q + (__n + _S_word_bit - 1) / _S_word_bit;
- this->_M_start = iterator(__q, 0);
- this->_M_finish = this->_M_start + difference_type(__n);
+ _Bit_type* __q = this->_M_allocate(__n);
+ this->_M_impl._M_end_of_storage = __q
+ + (__n + _S_word_bit - 1) / _S_word_bit;
+ this->_M_impl._M_start = iterator(__q, 0);
+ this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n);
}
void _M_insert_aux(iterator __position, bool __x)
{
- if (this->_M_finish._M_p != this->_M_end_of_storage)
+ if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage)
{
- std::copy_backward(__position, this->_M_finish, this->_M_finish + 1);
+ std::copy_backward(__position, this->_M_impl._M_finish,
+ this->_M_impl._M_finish + 1);
*__position = __x;
- ++this->_M_finish;
+ ++this->_M_impl._M_finish;
}
else
{
const size_type __len = size() ? 2 * size()
: static_cast<size_type>(_S_word_bit);
- _Bit_type * __q = this->_M_bit_alloc(__len);
+ _Bit_type * __q = this->_M_allocate(__len);
iterator __i = std::copy(begin(), __position, iterator(__q, 0));
*__i++ = __x;
- this->_M_finish = std::copy(__position, end(), __i);
+ this->_M_impl._M_finish = std::copy(__position, end(), __i);
this->_M_deallocate();
- this->_M_end_of_storage = __q + (__len + _S_word_bit - 1)
+ this->_M_impl._M_end_of_storage = __q + (__len + _S_word_bit - 1)
/ _S_word_bit;
- this->_M_start = iterator(__q, 0);
+ this->_M_impl._M_start = iterator(__q, 0);
}
}
@@ -471,9 +476,9 @@ template<typename _Alloc>
void _M_initialize_range(_InputIterator __first, _InputIterator __last,
input_iterator_tag)
{
- this->_M_start = iterator();
- this->_M_finish = iterator();
- this->_M_end_of_storage = 0;
+ this->_M_impl._M_start = iterator();
+ this->_M_impl._M_finish = iterator();
+ this->_M_impl._M_end_of_storage = 0;
for ( ; __first != __last; ++__first)
push_back(*__first);
}
@@ -484,13 +489,12 @@ template<typename _Alloc>
{
const size_type __n = std::distance(__first, __last);
_M_initialize(__n);
- std::copy(__first, __last, this->_M_start);
+ std::copy(__first, __last, this->_M_impl._M_start);
}
template<class _InputIterator>
- void _M_insert_range(iterator __pos,
- _InputIterator __first, _InputIterator __last,
- input_iterator_tag)
+ void _M_insert_range(iterator __pos, _InputIterator __first,
+ _InputIterator __last, input_iterator_tag)
{
for ( ; __first != __last; ++__first)
{
@@ -500,9 +504,8 @@ template<typename _Alloc>
}
template<class _ForwardIterator>
- void _M_insert_range(iterator __position,
- _ForwardIterator __first, _ForwardIterator __last,
- forward_iterator_tag)
+ void _M_insert_range(iterator __position, _ForwardIterator __first,
+ _ForwardIterator __last, forward_iterator_tag)
{
if (__first != __last)
{
@@ -510,37 +513,37 @@ template<typename _Alloc>
if (capacity() - size() >= __n)
{
std::copy_backward(__position, end(),
- this->_M_finish + difference_type(__n));
+ this->_M_impl._M_finish + difference_type(__n));
std::copy(__first, __last, __position);
- this->_M_finish += difference_type(__n);
+ this->_M_impl._M_finish += difference_type(__n);
}
else
{
const size_type __len = size() + std::max(size(), __n);
- _Bit_type * __q = this->_M_bit_alloc(__len);
+ _Bit_type * __q = this->_M_allocate(__len);
iterator __i = std::copy(begin(), __position, iterator(__q, 0));
__i = std::copy(__first, __last, __i);
- this->_M_finish = std::copy(__position, end(), __i);
+ this->_M_impl._M_finish = std::copy(__position, end(), __i);
this->_M_deallocate();
- this->_M_end_of_storage = __q + (__len + _S_word_bit - 1)
- / _S_word_bit;
- this->_M_start = iterator(__q, 0);
+ this->_M_impl._M_end_of_storage = __q + (__len + _S_word_bit - 1)
+ / _S_word_bit;
+ this->_M_impl._M_start = iterator(__q, 0);
}
}
}
public:
iterator begin()
- { return this->_M_start; }
+ { return this->_M_impl._M_start; }
const_iterator begin() const
- { return this->_M_start; }
+ { return this->_M_impl._M_start; }
iterator end()
- { return this->_M_finish; }
+ { return this->_M_impl._M_finish; }
const_iterator end() const
- { return this->_M_finish; }
+ { return this->_M_impl._M_finish; }
reverse_iterator rbegin()
{ return reverse_iterator(end()); }
@@ -561,7 +564,7 @@ template<typename _Alloc>
{ return size_type(-1); }
size_type capacity() const
- { return size_type(const_iterator(this->_M_end_of_storage, 0)
+ { return size_type(const_iterator(this->_M_impl._M_end_of_storage, 0)
- begin()); }
bool empty() const
{ return begin() == end(); }
@@ -587,45 +590,49 @@ template<typename _Alloc>
explicit vector(const allocator_type& __a = allocator_type())
: _Bvector_base<_Alloc>(__a) { }
- vector(size_type __n, bool __value,
+ vector(size_type __n, bool __value,
const allocator_type& __a = allocator_type())
- : _Bvector_base<_Alloc>(__a)
+ : _Bvector_base<_Alloc>(__a)
{
_M_initialize(__n);
- std::fill(this->_M_start._M_p, this->_M_end_of_storage, __value ? ~0 : 0);
+ std::fill(this->_M_impl._M_start._M_p, this->_M_impl._M_end_of_storage,
+ __value ? ~0 : 0);
}
explicit vector(size_type __n)
- : _Bvector_base<_Alloc>(allocator_type())
+ : _Bvector_base<_Alloc>(allocator_type())
{
_M_initialize(__n);
- std::fill(this->_M_start._M_p, this->_M_end_of_storage, 0);
+ std::fill(this->_M_impl._M_start._M_p,
+ this->_M_impl._M_end_of_storage, 0);
}
vector(const vector& __x) : _Bvector_base<_Alloc>(__x.get_allocator())
{
_M_initialize(__x.size());
- std::copy(__x.begin(), __x.end(), this->_M_start);
+ std::copy(__x.begin(), __x.end(), this->_M_impl._M_start);
}
// Check whether it's an integral type. If so, it's not an iterator.
-
template<class _Integer>
void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
{
_M_initialize(__n);
- std::fill(this->_M_start._M_p, this->_M_end_of_storage, __x ? ~0 : 0);
+ std::fill(this->_M_impl._M_start._M_p,
+ this->_M_impl._M_end_of_storage, __x ? ~0 : 0);
}
template<class _InputIterator>
- void _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
- __false_type)
- { _M_initialize_range(__first, __last, std::__iterator_category(__first)); }
+ void
+ _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
+ __false_type)
+ { _M_initialize_range(__first, __last,
+ std::__iterator_category(__first)); }
template<class _InputIterator>
- vector(_InputIterator __first, _InputIterator __last,
- const allocator_type& __a = allocator_type())
- : _Bvector_base<_Alloc>(__a)
+ vector(_InputIterator __first, _InputIterator __last,
+ const allocator_type& __a = allocator_type())
+ : _Bvector_base<_Alloc>(__a)
{
typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
_M_initialize_dispatch(__first, __last, _Integral());
@@ -643,7 +650,7 @@ template<typename _Alloc>
_M_initialize(__x.size());
}
std::copy(__x.begin(), __x.end(), begin());
- this->_M_finish = begin() + difference_type(__x.size());
+ this->_M_impl._M_finish = begin() + difference_type(__x.size());
return *this;
}
@@ -656,13 +663,15 @@ template<typename _Alloc>
{
if (__n > size())
{
- std::fill(this->_M_start._M_p, this->_M_end_of_storage, __x ? ~0 : 0);
+ std::fill(this->_M_impl._M_start._M_p,
+ this->_M_impl._M_end_of_storage, __x ? ~0 : 0);
insert(end(), __n - size(), __x);
}
else
{
erase(begin() + __n, end());
- std::fill(this->_M_start._M_p, this->_M_end_of_storage, __x ? ~0 : 0);
+ std::fill(this->_M_impl._M_start._M_p,
+ this->_M_impl._M_end_of_storage, __x ? ~0 : 0);
}
}
@@ -720,11 +729,12 @@ template<typename _Alloc>
__throw_length_error(__N("vector::reserve"));
if (this->capacity() < __n)
{
- _Bit_type* __q = this->_M_bit_alloc(__n);
- this->_M_finish = std::copy(begin(), end(), iterator(__q, 0));
+ _Bit_type* __q = this->_M_allocate(__n);
+ this->_M_impl._M_finish = std::copy(begin(), end(),
+ iterator(__q, 0));
this->_M_deallocate();
- this->_M_start = iterator(__q, 0);
- this->_M_end_of_storage = __q + (__n + _S_word_bit - 1) / _S_word_bit;
+ this->_M_impl._M_start = iterator(__q, 0);
+ this->_M_impl._M_end_of_storage = __q + (__n + _S_word_bit - 1) / _S_word_bit;
}
}
@@ -742,17 +752,18 @@ template<typename _Alloc>
void push_back(bool __x)
{
- if (this->_M_finish._M_p != this->_M_end_of_storage)
- *this->_M_finish++ = __x;
+ if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage)
+ *this->_M_impl._M_finish++ = __x;
else
_M_insert_aux(end(), __x);
}
void swap(vector<bool, _Alloc>& __x)
{
- std::swap(this->_M_start, __x._M_start);
- std::swap(this->_M_finish, __x._M_finish);
- std::swap(this->_M_end_of_storage, __x._M_end_of_storage);
+ std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
+ std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
+ std::swap(this->_M_impl._M_end_of_storage,
+ __x._M_impl._M_end_of_storage);
}
// [23.2.5]/1, third-to-last entry in synopsis listing
@@ -766,9 +777,9 @@ template<typename _Alloc>
iterator insert(iterator __position, bool __x = bool())
{
const difference_type __n = __position - begin();
- if (this->_M_finish._M_p != this->_M_end_of_storage
+ if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage
&& __position == end())
- *this->_M_finish++ = __x;
+ *this->_M_impl._M_finish++ = __x;
else
_M_insert_aux(__position, __x);
return begin() + __n;
@@ -803,22 +814,22 @@ template<typename _Alloc>
if (capacity() - size() >= __n)
{
std::copy_backward(__position, end(),
- this->_M_finish + difference_type(__n));
+ this->_M_impl._M_finish + difference_type(__n));
std::fill(__position, __position + difference_type(__n), __x);
- this->_M_finish += difference_type(__n);
+ this->_M_impl._M_finish += difference_type(__n);
}
else
{
const size_type __len = size() + std::max(size(), __n);
- _Bit_type * __q = this->_M_bit_alloc(__len);
+ _Bit_type * __q = this->_M_allocate(__len);
iterator __i = std::copy(begin(), __position, iterator(__q, 0));
std::fill_n(__i, __n, __x);
- this->_M_finish = std::copy(__position, end(),
- __i + difference_type(__n));
+ this->_M_impl._M_finish = std::copy(__position, end(),
+ __i + difference_type(__n));
this->_M_deallocate();
- this->_M_end_of_storage = __q + (__len + _S_word_bit - 1)
- / _S_word_bit;
- this->_M_start = iterator(__q, 0);
+ this->_M_impl._M_end_of_storage = __q + (__len + _S_word_bit - 1)
+ / _S_word_bit;
+ this->_M_impl._M_start = iterator(__q, 0);
}
}
@@ -826,19 +837,19 @@ template<typename _Alloc>
{ _M_fill_insert(__position, __n, __x); }
void pop_back()
- { --this->_M_finish; }
+ { --this->_M_impl._M_finish; }
iterator erase(iterator __position)
{
if (__position + 1 != end())
std::copy(__position + 1, end(), __position);
- --this->_M_finish;
+ --this->_M_impl._M_finish;
return __position;
}
iterator erase(iterator __first, iterator __last)
{
- this->_M_finish = std::copy(__last, end(), __first);
+ this->_M_impl._M_finish = std::copy(__last, end(), __first);
return __first;
}
@@ -852,14 +863,14 @@ template<typename _Alloc>
void flip()
{
- for (_Bit_type * __p = this->_M_start._M_p;
- __p != this->_M_end_of_storage; ++__p)
+ for (_Bit_type * __p = this->_M_impl._M_start._M_p;
+ __p != this->_M_impl._M_end_of_storage; ++__p)
*__p = ~*__p;
}
void clear()
{ erase(begin(), end()); }
};
-} // namespace __gnu_norm
+} // namespace std
#endif
diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h
index 5d237d5f3c1..a3d9f51ea39 100644
--- a/libstdc++-v3/include/bits/stl_deque.h
+++ b/libstdc++-v3/include/bits/stl_deque.h
@@ -65,7 +65,7 @@
#include <bits/stl_iterator_base_types.h>
#include <bits/stl_iterator_base_funcs.h>
-namespace __gnu_norm
+namespace _GLIBCXX_STD
{
/**
* @if maint
@@ -359,15 +359,15 @@ namespace __gnu_norm
get_allocator() const
{ return *static_cast<const _Alloc*>(&this->_M_impl); }
- typedef _Deque_iterator<_Tp,_Tp&,_Tp*> iterator;
- typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
+ typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator;
+ typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
_Deque_base(const allocator_type& __a, size_t __num_elements)
- : _M_impl(__a)
+ : _M_impl(__a)
{ _M_initialize_map(__num_elements); }
_Deque_base(const allocator_type& __a)
- : _M_impl(__a)
+ : _M_impl(__a)
{ }
~_Deque_base();
@@ -377,14 +377,15 @@ namespace __gnu_norm
//standard container and at the same time makes use of the EBO
//for empty allocators.
struct _Deque_impl
- : public _Alloc {
+ : public _Alloc
+ {
_Tp** _M_map;
size_t _M_map_size;
iterator _M_start;
iterator _M_finish;
_Deque_impl(const _Alloc& __a)
- : _Alloc(__a), _M_map(0), _M_map_size(0), _M_start(), _M_finish()
+ : _Alloc(__a), _M_map(0), _M_map_size(0), _M_start(), _M_finish()
{ }
};
@@ -422,7 +423,8 @@ namespace __gnu_norm
{
if (this->_M_impl._M_map)
{
- _M_destroy_nodes(this->_M_impl._M_start._M_node, this->_M_impl._M_finish._M_node + 1);
+ _M_destroy_nodes(this->_M_impl._M_start._M_node,
+ this->_M_impl._M_finish._M_node + 1);
_M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size);
}
}
@@ -452,7 +454,8 @@ namespace __gnu_norm
// the beginning of _M_map, but for small maps it may be as far in as
// _M_map+3.
- _Tp** __nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size - __num_nodes) / 2;
+ _Tp** __nstart = (this->_M_impl._M_map
+ + (this->_M_impl._M_map_size - __num_nodes) / 2);
_Tp** __nfinish = __nstart + __num_nodes;
try
@@ -468,8 +471,9 @@ namespace __gnu_norm
this->_M_impl._M_start._M_set_node(__nstart);
this->_M_impl._M_finish._M_set_node(__nfinish - 1);
this->_M_impl._M_start._M_cur = _M_impl._M_start._M_first;
- this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first + __num_elements
- % __deque_buf_size(sizeof(_Tp));
+ this->_M_impl._M_finish._M_cur = (this->_M_impl._M_finish._M_first
+ + __num_elements
+ % __deque_buf_size(sizeof(_Tp)));
}
template<typename _Tp, typename _Alloc>
@@ -668,7 +672,8 @@ namespace __gnu_norm
*/
deque(const deque& __x)
: _Base(__x.get_allocator(), __x.size())
- { std::uninitialized_copy(__x.begin(), __x.end(), this->_M_impl._M_start); }
+ { std::uninitialized_copy(__x.begin(), __x.end(),
+ this->_M_impl._M_start); }
/**
* @brief Builds a %deque from a range.
@@ -1009,7 +1014,8 @@ namespace __gnu_norm
void
push_back(const value_type& __x)
{
- if (this->_M_impl._M_finish._M_cur != this->_M_impl._M_finish._M_last - 1)
+ if (this->_M_impl._M_finish._M_cur
+ != this->_M_impl._M_finish._M_last - 1)
{
std::_Construct(this->_M_impl._M_finish._M_cur, __x);
++this->_M_impl._M_finish._M_cur;
@@ -1029,7 +1035,8 @@ namespace __gnu_norm
void
pop_front()
{
- if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_last - 1)
+ if (this->_M_impl._M_start._M_cur
+ != this->_M_impl._M_start._M_last - 1)
{
std::_Destroy(this->_M_impl._M_start._M_cur);
++this->_M_impl._M_start._M_cur;
@@ -1049,7 +1056,8 @@ namespace __gnu_norm
void
pop_back()
{
- if (this->_M_impl._M_finish._M_cur != this->_M_impl._M_finish._M_first)
+ if (this->_M_impl._M_finish._M_cur
+ != this->_M_impl._M_finish._M_first)
{
--this->_M_impl._M_finish._M_cur;
std::_Destroy(this->_M_impl._M_finish._M_cur);
@@ -1418,7 +1426,8 @@ namespace __gnu_norm
void
_M_reserve_map_at_front (size_type __nodes_to_add = 1)
{
- if (__nodes_to_add > size_type(this->_M_impl._M_start._M_node - this->_M_impl._M_map))
+ if (__nodes_to_add > size_type(this->_M_impl._M_start._M_node
+ - this->_M_impl._M_map))
_M_reallocate_map(__nodes_to_add, true);
}
@@ -1496,6 +1505,6 @@ namespace __gnu_norm
inline void
swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y)
{ __x.swap(__y); }
-} // namespace __gnu_norm
+} // namespace std
#endif /* _DEQUE_H */
diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h
index c0d821116c7..f55915b1e2c 100644
--- a/libstdc++-v3/include/bits/stl_list.h
+++ b/libstdc++-v3/include/bits/stl_list.h
@@ -63,7 +63,7 @@
#include <bits/concept_check.h>
-namespace __gnu_norm
+namespace _GLIBCXX_STD
{
// Supporting structures are split into common and templated types; the
// latter publicly inherits from the former in an effort to reduce code
@@ -295,10 +295,11 @@ namespace __gnu_norm
_Node_Alloc_type;
struct _List_impl
- : public _Node_Alloc_type {
+ : public _Node_Alloc_type
+ {
_List_node_base _M_node;
_List_impl (const _Node_Alloc_type& __a)
- : _Node_Alloc_type(__a)
+ : _Node_Alloc_type(__a)
{ }
};
@@ -317,10 +318,11 @@ namespace __gnu_norm
allocator_type
get_allocator() const
- { return allocator_type(*static_cast<const _Node_Alloc_type*>(&this->_M_impl)); }
+ { return allocator_type(*static_cast<
+ const _Node_Alloc_type*>(&this->_M_impl)); }
_List_base(const allocator_type& __a)
- : _M_impl(__a)
+ : _M_impl(__a)
{ _M_init(); }
// This is what actually destroys the list.
@@ -1247,7 +1249,7 @@ namespace __gnu_norm
inline void
swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
{ __x.swap(__y); }
-} // namespace __gnu_norm
+} // namespace std
#endif /* _LIST_H */
diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h
index 3a563f174be..bd78f57cdf9 100644
--- a/libstdc++-v3/include/bits/stl_map.h
+++ b/libstdc++-v3/include/bits/stl_map.h
@@ -63,7 +63,7 @@
#include <bits/concept_check.h>
-namespace __gnu_norm
+namespace _GLIBCXX_STD
{
/**
* @brief A standard container made up of (key,value) pairs, which can be
@@ -689,6 +689,6 @@ namespace __gnu_norm
inline void
swap(map<_Key,_Tp,_Compare,_Alloc>& __x, map<_Key,_Tp,_Compare,_Alloc>& __y)
{ __x.swap(__y); }
-} // namespace __gnu_norm
+} // namespace std
#endif /* _MAP_H */
diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h
index cbc7b07a804..c44aa74a692 100644
--- a/libstdc++-v3/include/bits/stl_multimap.h
+++ b/libstdc++-v3/include/bits/stl_multimap.h
@@ -63,7 +63,7 @@
#include <bits/concept_check.h>
-namespace __gnu_norm
+namespace _GLIBCXX_STD
{
// Forward declaration of operators < and ==, needed for friend declaration.
@@ -673,6 +673,6 @@ namespace __gnu_norm
swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x,
multimap<_Key,_Tp,_Compare,_Alloc>& __y)
{ __x.swap(__y); }
-} // namespace __gnu_norm
+} // namespace std
#endif /* _MULTIMAP_H */
diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h
index 887899670b7..c82dee68e4e 100644
--- a/libstdc++-v3/include/bits/stl_multiset.h
+++ b/libstdc++-v3/include/bits/stl_multiset.h
@@ -63,7 +63,7 @@
#include <bits/concept_check.h>
-namespace __gnu_norm
+namespace _GLIBCXX_STD
{
// Forward declaration of operators < and ==, needed for friend declaration.
@@ -580,6 +580,6 @@ namespace __gnu_norm
multiset<_Key,_Compare,_Alloc>& __y)
{ __x.swap(__y); }
-} // namespace __gnu_norm
+} // namespace std
#endif /* _MULTISET_H */
diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h
index 0bbaa24ad6e..d5146bb5943 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -63,9 +63,8 @@
namespace std
{
-
/// pair holds two objects of arbitrary type.
- template <class _T1, class _T2>
+ template<class _T1, class _T2>
struct pair
{
typedef _T1 first_type; ///< @c first_type is the first bound type
@@ -79,51 +78,51 @@ namespace std
/** The default constructor creates @c first and @c second using their
* respective default constructors. */
pair()
- : first(), second() {}
+ : first(), second() { }
/** Two objects may be passed to a @c pair constructor to be copied. */
pair(const _T1& __a, const _T2& __b)
- : first(__a), second(__b) {}
+ : first(__a), second(__b) { }
/** There is also a templated copy ctor for the @c pair class itself. */
- template <class _U1, class _U2>
+ template<class _U1, class _U2>
pair(const pair<_U1, _U2>& __p)
- : first(__p.first), second(__p.second) {}
+ : first(__p.first), second(__p.second) { }
};
/// Two pairs of the same type are equal iff their members are equal.
- template <class _T1, class _T2>
+ template<class _T1, class _T2>
inline bool
operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
{ return __x.first == __y.first && __x.second == __y.second; }
/// <http://gcc.gnu.org/onlinedocs/libstdc++/20_util/howto.html#pairlt>
- template <class _T1, class _T2>
+ template<class _T1, class _T2>
inline bool
operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
{ return __x.first < __y.first
|| (!(__y.first < __x.first) && __x.second < __y.second); }
/// Uses @c operator== to find the result.
- template <class _T1, class _T2>
+ template<class _T1, class _T2>
inline bool
operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
{ return !(__x == __y); }
/// Uses @c operator< to find the result.
- template <class _T1, class _T2>
+ template<class _T1, class _T2>
inline bool
operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
{ return __y < __x; }
/// Uses @c operator< to find the result.
- template <class _T1, class _T2>
+ template<class _T1, class _T2>
inline bool
operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
{ return !(__y < __x); }
/// Uses @c operator< to find the result.
- template <class _T1, class _T2>
+ template<class _T1, class _T2>
inline bool
operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
{ return !(__x < __y); }
@@ -138,18 +137,11 @@ namespace std
* but LWG issue #181 says they should be passed by const value. We follow
* the LWG by default.
*/
- template <class _T1, class _T2>
-
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 181. make_pair() unintended behavior
- inline pair<_T1, _T2>
- make_pair(_T1 __x, _T2 __y)
- { return pair<_T1, _T2>(__x, __y); }
-
+ template<class _T1, class _T2>
+ inline pair<_T1, _T2>
+ make_pair(_T1 __x, _T2 __y) { return pair<_T1, _T2>(__x, __y); }
} // namespace std
#endif /* _PAIR_H */
-
-// Local Variables:
-// mode:C++
-// End:
diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h
index 28e1a3ceb30..bb28bddc7af 100644
--- a/libstdc++-v3/include/bits/stl_set.h
+++ b/libstdc++-v3/include/bits/stl_set.h
@@ -63,7 +63,7 @@
#include <bits/concept_check.h>
-namespace __gnu_norm
+namespace _GLIBCXX_STD
{
// Forward declarations of operators < and ==, needed for friend declaration.
template<class _Key, class _Compare = less<_Key>,
@@ -588,6 +588,6 @@ namespace __gnu_norm
swap(set<_Key,_Compare,_Alloc>& __x, set<_Key,_Compare,_Alloc>& __y)
{ __x.swap(__y); }
-} // namespace __gnu_norm
+} // namespace std
#endif /* _SET_H */
diff --git a/libstdc++-v3/include/bits/stl_threads.h b/libstdc++-v3/include/bits/stl_threads.h
index 93fb9e99ee6..04baf0a08f9 100644
--- a/libstdc++-v3/include/bits/stl_threads.h
+++ b/libstdc++-v3/include/bits/stl_threads.h
@@ -1,6 +1,6 @@
// Threading support -*- C++ -*-
-// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002, 2003, 2004 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
@@ -54,7 +54,7 @@
// layer.
#include "bits/gthr.h"
-namespace __gnu_cxx
+namespace __gnu_internal
{
#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION)
extern __gthread_mutex_t _GLIBCXX_mutex;
@@ -63,7 +63,10 @@ namespace __gnu_cxx
extern void _GLIBCXX_mutex_init(void);
extern void _GLIBCXX_mutex_address_init(void);
#endif
+} // namespace __gnu_internal
+namespace __gnu_cxx
+{
// Locking class. Note that this class *does not have a
// constructor*. It must be initialized either statically, with
// __STL_MUTEX_INITIALIZER, or dynamically, by explicitly calling
@@ -92,24 +95,24 @@ namespace __gnu_cxx
// There should be no code in this path given the usage rules above.
#elif defined(__GTHREAD_MUTEX_INIT_FUNCTION)
if (_M_init_flag) return;
- if (__gthread_once(&__gnu_cxx::_GLIBCXX_once,
- __gnu_cxx::_GLIBCXX_mutex_init) != 0
+ if (__gthread_once(&__gnu_internal::_GLIBCXX_once,
+ __gnu_internal::_GLIBCXX_mutex_init) != 0
&& __gthread_active_p())
abort ();
- __gthread_mutex_lock(&__gnu_cxx::_GLIBCXX_mutex);
+ __gthread_mutex_lock(&__gnu_internal::_GLIBCXX_mutex);
if (!_M_init_flag)
{
// Even though we have a global lock, we use __gthread_once to be
// absolutely certain the _M_lock mutex is only initialized once on
// multiprocessor systems.
- __gnu_cxx::_GLIBCXX_mutex_address = &_M_lock;
+ __gnu_internal::_GLIBCXX_mutex_address = &_M_lock;
if (__gthread_once(&_M_once,
- __gnu_cxx::_GLIBCXX_mutex_address_init) != 0
+ __gnu_internal::_GLIBCXX_mutex_address_init) != 0
&& __gthread_active_p())
abort();
_M_init_flag = 1;
}
- __gthread_mutex_unlock(&__gnu_cxx::_GLIBCXX_mutex);
+ __gthread_mutex_unlock(&__gnu_internal::_GLIBCXX_mutex);
#endif
}
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index ac9add899b9..fdc2ea60772 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -461,7 +461,8 @@ namespace std
_Const_Link_type
_M_begin() const
- { return static_cast<_Const_Link_type>(this->_M_impl._M_header._M_parent); }
+ { return static_cast<
+ _Const_Link_type>(this->_M_impl._M_header._M_parent); }
_Link_type
_M_end()
@@ -999,9 +1000,9 @@ namespace std
inline void
_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::erase(iterator __position)
{
- _Link_type __y =
- static_cast<_Link_type>(_Rb_tree_rebalance_for_erase(__position._M_node,
- this->_M_impl._M_header));
+ _Link_type __y = static_cast<
+ _Link_type>(_Rb_tree_rebalance_for_erase(__position._M_node,
+ this->_M_impl._M_header));
destroy_node(__y);
--_M_impl._M_node_count;
}
@@ -1278,4 +1279,3 @@ namespace std
} // namespace std
#endif
-
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index 10adb6368be..8a741b4d9dc 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -1,6 +1,6 @@
// Vector implementation -*- C++ -*-
-// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002, 2003, 2004 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
@@ -65,7 +65,7 @@
#include <bits/functexcept.h>
#include <bits/concept_check.h>
-namespace __gnu_norm
+namespace _GLIBCXX_STD
{
/**
* @if maint
@@ -76,12 +76,13 @@ namespace __gnu_norm
struct _Vector_base
{
struct _Vector_impl
- : public _Alloc {
+ : public _Alloc
+ {
_Tp* _M_start;
_Tp* _M_finish;
_Tp* _M_end_of_storage;
_Vector_impl (_Alloc const& __a)
- : _Alloc(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
+ : _Alloc(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
{ }
};
@@ -89,13 +90,15 @@ namespace __gnu_norm
typedef _Alloc allocator_type;
allocator_type
- get_allocator() const { return *static_cast<const _Alloc*>(&this->_M_impl); }
+ get_allocator() const
+ { return *static_cast<const _Alloc*>(&this->_M_impl); }
- _Vector_base(const allocator_type& __a) : _M_impl(__a)
+ _Vector_base(const allocator_type& __a)
+ : _M_impl(__a)
{ }
_Vector_base(size_t __n, const allocator_type& __a)
- : _M_impl(__a)
+ : _M_impl(__a)
{
this->_M_impl._M_start = this->_M_allocate(__n);
this->_M_impl._M_finish = this->_M_impl._M_start;
@@ -103,18 +106,21 @@ namespace __gnu_norm
}
~_Vector_base()
- { _M_deallocate(this->_M_impl._M_start,
- this->_M_impl._M_end_of_storage - this->_M_impl._M_start); }
+ { _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage
+ - this->_M_impl._M_start); }
public:
_Vector_impl _M_impl;
_Tp*
- _M_allocate(size_t __n) { return _M_impl.allocate(__n); }
+ _M_allocate(size_t __n)
+ { return _M_impl.allocate(__n); }
void
_M_deallocate(_Tp* __p, size_t __n)
- { if (__p) _M_impl.deallocate(__p, __n); }
+ { if (__p)
+ _M_impl.deallocate(__p, __n);
+ }
};
@@ -179,7 +185,8 @@ namespace __gnu_norm
*/
explicit
vector(const allocator_type& __a = allocator_type())
- : _Base(__a) { }
+ : _Base(__a)
+ { }
/**
* @brief Create a %vector with copies of an exemplar element.
@@ -191,8 +198,9 @@ namespace __gnu_norm
vector(size_type __n, const value_type& __value,
const allocator_type& __a = allocator_type())
: _Base(__n, __a)
- { this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start,
- __n, __value); }
+ { this->_M_impl._M_finish = std::uninitialized_fill_n(this->
+ _M_impl._M_start,
+ __n, __value); }
/**
* @brief Create a %vector with default elements.
@@ -204,8 +212,10 @@ namespace __gnu_norm
explicit
vector(size_type __n)
: _Base(__n, allocator_type())
- { this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start,
- __n, value_type()); }
+ { this->_M_impl._M_finish = std::uninitialized_fill_n(this->
+ _M_impl._M_start,
+ __n,
+ value_type()); }
/**
* @brief %Vector copy constructor.
@@ -218,8 +228,10 @@ namespace __gnu_norm
*/
vector(const vector& __x)
: _Base(__x.size(), __x.get_allocator())
- { this->_M_impl._M_finish = std::uninitialized_copy(__x.begin(), __x.end(),
- this->_M_impl._M_start);
+ { this->_M_impl._M_finish = std::uninitialized_copy(__x.begin(),
+ __x.end(),
+ this->
+ _M_impl._M_start);
}
/**
@@ -253,7 +265,8 @@ namespace __gnu_norm
* not touched in any way. Managing the pointer is the user's
* responsibilty.
*/
- ~vector() { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); }
+ ~vector()
+ { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); }
/**
* @brief %Vector assignment operator.
@@ -311,7 +324,8 @@ namespace __gnu_norm
* element order.
*/
iterator
- begin() { return iterator (this->_M_impl._M_start); }
+ begin()
+ { return iterator (this->_M_impl._M_start); }
/**
* Returns a read-only (constant) iterator that points to the
@@ -319,7 +333,8 @@ namespace __gnu_norm
* element order.
*/
const_iterator
- begin() const { return const_iterator (this->_M_impl._M_start); }
+ begin() const
+ { return const_iterator (this->_M_impl._M_start); }
/**
* Returns a read/write iterator that points one past the last
@@ -327,7 +342,8 @@ namespace __gnu_norm
* element order.
*/
iterator
- end() { return iterator (this->_M_impl._M_finish); }
+ end()
+ { return iterator (this->_M_impl._M_finish); }
/**
* Returns a read-only (constant) iterator that points one past
@@ -335,7 +351,8 @@ namespace __gnu_norm
* ordinary element order.
*/
const_iterator
- end() const { return const_iterator (this->_M_impl._M_finish); }
+ end() const
+ { return const_iterator (this->_M_impl._M_finish); }
/**
* Returns a read/write reverse iterator that points to the
@@ -343,7 +360,8 @@ namespace __gnu_norm
* element order.
*/
reverse_iterator
- rbegin() { return reverse_iterator(end()); }
+ rbegin()
+ { return reverse_iterator(end()); }
/**
* Returns a read-only (constant) reverse iterator that points
@@ -351,7 +369,8 @@ namespace __gnu_norm
* reverse element order.
*/
const_reverse_iterator
- rbegin() const { return const_reverse_iterator(end()); }
+ rbegin() const
+ { return const_reverse_iterator(end()); }
/**
* Returns a read/write reverse iterator that points to one
@@ -359,7 +378,8 @@ namespace __gnu_norm
* in reverse element order.
*/
reverse_iterator
- rend() { return reverse_iterator(begin()); }
+ rend()
+ { return reverse_iterator(begin()); }
/**
* Returns a read-only (constant) reverse iterator that points
@@ -367,16 +387,19 @@ namespace __gnu_norm
* is done in reverse element order.
*/
const_reverse_iterator
- rend() const { return const_reverse_iterator(begin()); }
+ rend() const
+ { return const_reverse_iterator(begin()); }
// [23.2.4.2] capacity
/** Returns the number of elements in the %vector. */
size_type
- size() const { return size_type(end() - begin()); }
+ size() const
+ { return size_type(end() - begin()); }
/** Returns the size() of the largest possible %vector. */
size_type
- max_size() const { return size_type(-1) / sizeof(value_type); }
+ max_size() const
+ { return size_type(-1) / sizeof(value_type); }
/**
* @brief Resizes the %vector to the specified number of elements.
@@ -409,7 +432,8 @@ namespace __gnu_norm
* default-constructed.
*/
void
- resize(size_type __new_size) { resize(__new_size, value_type()); }
+ resize(size_type __new_size)
+ { resize(__new_size, value_type()); }
/**
* Returns the total number of elements that the %vector can
@@ -417,14 +441,16 @@ namespace __gnu_norm
*/
size_type
capacity() const
- { return size_type(const_iterator(this->_M_impl._M_end_of_storage) - begin()); }
+ { return size_type(const_iterator(this->_M_impl._M_end_of_storage)
+ - begin()); }
/**
* Returns true if the %vector is empty. (Thus begin() would
* equal end().)
*/
bool
- empty() const { return begin() == end(); }
+ empty() const
+ { return begin() == end(); }
/**
* @brief Attempt to preallocate enough memory for specified number of
@@ -459,7 +485,8 @@ namespace __gnu_norm
* see at().)
*/
reference
- operator[](size_type __n) { return *(begin() + __n); }
+ operator[](size_type __n)
+ { return *(begin() + __n); }
/**
* @brief Subscript access to the data contained in the %vector.
@@ -473,7 +500,8 @@ namespace __gnu_norm
* see at().)
*/
const_reference
- operator[](size_type __n) const { return *(begin() + __n); }
+ operator[](size_type __n) const
+ { return *(begin() + __n); }
protected:
/// @if maint Safety check used only from at(). @endif
@@ -497,7 +525,11 @@ namespace __gnu_norm
* function throws out_of_range if the check fails.
*/
reference
- at(size_type __n) { _M_range_check(__n); return (*this)[__n]; }
+ at(size_type __n)
+ {
+ _M_range_check(__n);
+ return (*this)[__n];
+ }
/**
* @brief Provides access to the data contained in the %vector.
@@ -511,35 +543,43 @@ namespace __gnu_norm
* function throws out_of_range if the check fails.
*/
const_reference
- at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; }
+ at(size_type __n) const
+ {
+ _M_range_check(__n);
+ return (*this)[__n];
+ }
/**
* Returns a read/write reference to the data at the first
* element of the %vector.
*/
reference
- front() { return *begin(); }
+ front()
+ { return *begin(); }
/**
* Returns a read-only (constant) reference to the data at the first
* element of the %vector.
*/
const_reference
- front() const { return *begin(); }
+ front() const
+ { return *begin(); }
/**
* Returns a read/write reference to the data at the last
* element of the %vector.
*/
reference
- back() { return *(end() - 1); }
-
+ back()
+ { return *(end() - 1); }
+
/**
* Returns a read-only (constant) reference to the data at the
* last element of the %vector.
*/
const_reference
- back() const { return *(end() - 1); }
+ back() const
+ { return *(end() - 1); }
// [23.2.4.3] modifiers
/**
@@ -688,7 +728,8 @@ namespace __gnu_norm
{
std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
- std::swap(this->_M_impl._M_end_of_storage, __x._M_impl._M_end_of_storage);
+ std::swap(this->_M_impl._M_end_of_storage,
+ __x._M_impl._M_end_of_storage);
}
/**
@@ -698,7 +739,8 @@ namespace __gnu_norm
* the user's responsibilty.
*/
void
- clear() { erase(begin(), end()); }
+ clear()
+ { erase(begin(), end()); }
protected:
/**
@@ -735,8 +777,9 @@ namespace __gnu_norm
{
this->_M_impl._M_start = _M_allocate(__n);
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
- this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start,
- __n, __value);
+ this->_M_impl._M_finish = std::uninitialized_fill_n(this->
+ _M_impl._M_start,
+ __n, __value);
}
// Called by the range constructor to implement [23.1.1]/9
@@ -770,7 +813,8 @@ namespace __gnu_norm
this->_M_impl._M_start = this->_M_allocate(__n);
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
this->_M_impl._M_finish = std::uninitialized_copy(__first, __last,
- this->_M_impl._M_start);
+ this->
+ _M_impl._M_start);
}
@@ -873,11 +917,9 @@ namespace __gnu_norm
*/
template<typename _Tp, typename _Alloc>
inline bool
- operator==(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
- {
- return __x.size() == __y.size() &&
- std::equal(__x.begin(), __x.end(), __y.begin());
- }
+ operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
+ { return (__x.size() == __y.size()
+ && std::equal(__x.begin(), __x.end(), __y.begin())); }
/**
* @brief Vector ordering relation.
@@ -892,41 +934,39 @@ namespace __gnu_norm
*/
template<typename _Tp, typename _Alloc>
inline bool
- operator<(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
- {
- return std::lexicographical_compare(__x.begin(), __x.end(),
- __y.begin(), __y.end());
- }
+ operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
+ { return std::lexicographical_compare(__x.begin(), __x.end(),
+ __y.begin(), __y.end()); }
/// Based on operator==
template<typename _Tp, typename _Alloc>
inline bool
- operator!=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
+ operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
{ return !(__x == __y); }
/// Based on operator<
template<typename _Tp, typename _Alloc>
inline bool
- operator>(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
+ operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
{ return __y < __x; }
/// Based on operator<
template<typename _Tp, typename _Alloc>
inline bool
- operator<=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
+ operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
{ return !(__y < __x); }
/// Based on operator<
template<typename _Tp, typename _Alloc>
inline bool
- operator>=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
+ operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
{ return !(__x < __y); }
/// See std::vector::swap().
template<typename _Tp, typename _Alloc>
inline void
- swap(vector<_Tp,_Alloc>& __x, vector<_Tp,_Alloc>& __y)
+ swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y)
{ __x.swap(__y); }
-} // namespace __gnu_norm
+} // namespace std
#endif /* _VECTOR_H */
diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc
index dd459a53431..5e8b9a7108d 100644
--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -1,6 +1,6 @@
// Vector implementation (out of line) -*- C++ -*-
-// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002, 2003, 2004 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
@@ -61,11 +61,11 @@
#ifndef _VECTOR_TCC
#define _VECTOR_TCC 1
-namespace __gnu_norm
+namespace _GLIBCXX_STD
{
template<typename _Tp, typename _Alloc>
void
- vector<_Tp,_Alloc>::
+ vector<_Tp, _Alloc>::
reserve(size_type __n)
{
if (__n > this->max_size())
@@ -78,7 +78,8 @@ namespace __gnu_norm
this->_M_impl._M_finish);
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish);
_M_deallocate(this->_M_impl._M_start,
- this->_M_impl._M_end_of_storage - this->_M_impl._M_start);
+ this->_M_impl._M_end_of_storage
+ - this->_M_impl._M_start);
this->_M_impl._M_start = __tmp;
this->_M_impl._M_finish = __tmp + __old_size;
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
@@ -86,24 +87,25 @@ namespace __gnu_norm
}
template<typename _Tp, typename _Alloc>
- typename vector<_Tp,_Alloc>::iterator
- vector<_Tp,_Alloc>::
+ typename vector<_Tp, _Alloc>::iterator
+ vector<_Tp, _Alloc>::
insert(iterator __position, const value_type& __x)
{
size_type __n = __position - begin();
- if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage && __position == end())
- {
- std::_Construct(this->_M_impl._M_finish, __x);
- ++this->_M_impl._M_finish;
- }
+ if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
+ && __position == end())
+ {
+ std::_Construct(this->_M_impl._M_finish, __x);
+ ++this->_M_impl._M_finish;
+ }
else
_M_insert_aux(__position, __x);
return begin() + __n;
}
template<typename _Tp, typename _Alloc>
- typename vector<_Tp,_Alloc>::iterator
- vector<_Tp,_Alloc>::
+ typename vector<_Tp, _Alloc>::iterator
+ vector<_Tp, _Alloc>::
erase(iterator __position)
{
if (__position + 1 != end())
@@ -114,8 +116,8 @@ namespace __gnu_norm
}
template<typename _Tp, typename _Alloc>
- typename vector<_Tp,_Alloc>::iterator
- vector<_Tp,_Alloc>::
+ typename vector<_Tp, _Alloc>::iterator
+ vector<_Tp, _Alloc>::
erase(iterator __first, iterator __last)
{
iterator __i(copy(__last, end(), __first));
@@ -125,102 +127,118 @@ namespace __gnu_norm
}
template<typename _Tp, typename _Alloc>
- vector<_Tp,_Alloc>&
- vector<_Tp,_Alloc>::
- operator=(const vector<_Tp,_Alloc>& __x)
+ vector<_Tp, _Alloc>&
+ vector<_Tp, _Alloc>::
+ operator=(const vector<_Tp, _Alloc>& __x)
{
if (&__x != this)
- {
- const size_type __xlen = __x.size();
- if (__xlen > capacity())
- {
- pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end());
- std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish);
- _M_deallocate(this->_M_impl._M_start,
- this->_M_impl._M_end_of_storage - this->_M_impl._M_start);
- this->_M_impl._M_start = __tmp;
- this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __xlen;
- }
- else if (size() >= __xlen)
- {
- iterator __i(copy(__x.begin(), __x.end(), begin()));
- std::_Destroy(__i, end());
- }
- else
- {
- std::copy(__x.begin(), __x.begin() + size(), this->_M_impl._M_start);
- std::uninitialized_copy(__x.begin() + size(), __x.end(), this->_M_impl._M_finish);
- }
- this->_M_impl._M_finish = this->_M_impl._M_start + __xlen;
- }
+ {
+ const size_type __xlen = __x.size();
+ if (__xlen > capacity())
+ {
+ pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(),
+ __x.end());
+ std::_Destroy(this->_M_impl._M_start,
+ this->_M_impl._M_finish);
+ _M_deallocate(this->_M_impl._M_start,
+ this->_M_impl._M_end_of_storage
+ - this->_M_impl._M_start);
+ this->_M_impl._M_start = __tmp;
+ this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __xlen;
+ }
+ else if (size() >= __xlen)
+ {
+ iterator __i(copy(__x.begin(), __x.end(), begin()));
+ std::_Destroy(__i, end());
+ }
+ else
+ {
+ std::copy(__x.begin(), __x.begin() + size(),
+ this->_M_impl._M_start);
+ std::uninitialized_copy(__x.begin() + size(),
+ __x.end(), this->_M_impl._M_finish);
+ }
+ this->_M_impl._M_finish = this->_M_impl._M_start + __xlen;
+ }
return *this;
}
template<typename _Tp, typename _Alloc>
void
- vector<_Tp,_Alloc>::
+ vector<_Tp, _Alloc>::
_M_fill_assign(size_t __n, const value_type& __val)
{
if (__n > capacity())
- {
- vector __tmp(__n, __val, get_allocator());
- __tmp.swap(*this);
- }
+ {
+ vector __tmp(__n, __val, get_allocator());
+ __tmp.swap(*this);
+ }
else if (__n > size())
- {
- std::fill(begin(), end(), __val);
- this->_M_impl._M_finish
- = std::uninitialized_fill_n(this->_M_impl._M_finish, __n - size(), __val);
- }
+ {
+ std::fill(begin(), end(), __val);
+ this->_M_impl._M_finish = std::uninitialized_fill_n(this->
+ _M_impl._M_finish,
+ __n - size(),
+ __val);
+ }
else
erase(fill_n(begin(), __n, __val), end());
}
- template<typename _Tp, typename _Alloc> template<typename _InputIterator>
- void
- vector<_Tp,_Alloc>::
- _M_assign_aux(_InputIterator __first, _InputIterator __last, input_iterator_tag)
- {
- iterator __cur(begin());
- for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
- *__cur = *__first;
- if (__first == __last)
- erase(__cur, end());
- else
- insert(end(), __first, __last);
- }
-
- template<typename _Tp, typename _Alloc> template<typename _ForwardIterator>
- void
- vector<_Tp,_Alloc>::
- _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
- forward_iterator_tag)
- {
- size_type __len = std::distance(__first, __last);
-
- if (__len > capacity())
- {
- pointer __tmp(_M_allocate_and_copy(__len, __first, __last));
- std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish);
- _M_deallocate(this->_M_impl._M_start,
- this->_M_impl._M_end_of_storage - this->_M_impl._M_start);
- this->_M_impl._M_start = __tmp;
- this->_M_impl._M_end_of_storage = this->_M_impl._M_finish = this->_M_impl._M_start + __len;
- }
- else if (size() >= __len)
+ template<typename _Tp, typename _Alloc>
+ template<typename _InputIterator>
+ void
+ vector<_Tp, _Alloc>::
+ _M_assign_aux(_InputIterator __first, _InputIterator __last,
+ input_iterator_tag)
{
- iterator __new_finish(copy(__first, __last, this->_M_impl._M_start));
- std::_Destroy(__new_finish, end());
- this->_M_impl._M_finish = __new_finish.base();
+ iterator __cur(begin());
+ for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
+ *__cur = *__first;
+ if (__first == __last)
+ erase(__cur, end());
+ else
+ insert(end(), __first, __last);
}
- else
+
+ template<typename _Tp, typename _Alloc>
+ template<typename _ForwardIterator>
+ void
+ vector<_Tp,_Alloc>::
+ _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
+ forward_iterator_tag)
{
- _ForwardIterator __mid = __first;
- std::advance(__mid, size());
- std::copy(__first, __mid, this->_M_impl._M_start);
- this->_M_impl._M_finish = std::uninitialized_copy(__mid, __last, this->_M_impl._M_finish);
+ size_type __len = std::distance(__first, __last);
+
+ if (__len > capacity())
+ {
+ pointer __tmp(_M_allocate_and_copy(__len, __first, __last));
+ std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish);
+ _M_deallocate(this->_M_impl._M_start,
+ this->_M_impl._M_end_of_storage
+ - this->_M_impl._M_start);
+ this->_M_impl._M_start = __tmp;
+ this->_M_impl._M_finish = this->_M_impl._M_start + __len;
+ this->_M_impl._M_end_of_storage = this->_M_impl._M_finish;
+ }
+ else if (size() >= __len)
+ {
+ iterator __new_finish(copy(__first, __last,
+ this->_M_impl._M_start));
+ std::_Destroy(__new_finish, end());
+ this->_M_impl._M_finish = __new_finish.base();
+ }
+ else
+ {
+ _ForwardIterator __mid = __first;
+ std::advance(__mid, size());
+ std::copy(__first, __mid, this->_M_impl._M_start);
+ this->_M_impl._M_finish = std::uninitialized_copy(__mid,
+ __last,
+ this->_M_impl.
+ _M_finish);
+ }
}
- }
template<typename _Tp, typename _Alloc>
void
@@ -228,45 +246,49 @@ namespace __gnu_norm
_M_insert_aux(iterator __position, const _Tp& __x)
{
if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
- {
- std::_Construct(this->_M_impl._M_finish, *(this->_M_impl._M_finish - 1));
- ++this->_M_impl._M_finish;
- _Tp __x_copy = __x;
- std::copy_backward(__position,
- iterator(this->_M_impl._M_finish-2),
- iterator(this->_M_impl._M_finish-1));
- *__position = __x_copy;
- }
+ {
+ std::_Construct(this->_M_impl._M_finish,
+ *(this->_M_impl._M_finish - 1));
+ ++this->_M_impl._M_finish;
+ _Tp __x_copy = __x;
+ std::copy_backward(__position,
+ iterator(this->_M_impl._M_finish-2),
+ iterator(this->_M_impl._M_finish-1));
+ *__position = __x_copy;
+ }
else
- {
- const size_type __old_size = size();
- const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
- iterator __new_start(this->_M_allocate(__len));
- iterator __new_finish(__new_start);
- try
- {
- __new_finish = std::uninitialized_copy(iterator(this->_M_impl._M_start),
- __position,
- __new_start);
- std::_Construct(__new_finish.base(), __x);
- ++__new_finish;
- __new_finish = std::uninitialized_copy(__position,
- iterator(this->_M_impl._M_finish),
- __new_finish);
- }
- catch(...)
- {
- std::_Destroy(__new_start,__new_finish);
- _M_deallocate(__new_start.base(),__len);
- __throw_exception_again;
+ {
+ const size_type __old_size = size();
+ const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
+ iterator __new_start(this->_M_allocate(__len));
+ iterator __new_finish(__new_start);
+ try
+ {
+ __new_finish = std::uninitialized_copy(iterator(this->
+ _M_impl._M_start),
+ __position,
+ __new_start);
+ std::_Construct(__new_finish.base(), __x);
+ ++__new_finish;
+ __new_finish = std::uninitialized_copy(__position,
+ iterator(this->_M_impl.
+ _M_finish),
+ __new_finish);
}
- std::_Destroy(begin(), end());
- _M_deallocate(this->_M_impl._M_start,
- this->_M_impl._M_end_of_storage - this->_M_impl._M_start);
- this->_M_impl._M_start = __new_start.base();
- this->_M_impl._M_finish = __new_finish.base();
- this->_M_impl._M_end_of_storage = __new_start.base() + __len;
- }
+ catch(...)
+ {
+ std::_Destroy(__new_start,__new_finish);
+ _M_deallocate(__new_start.base(),__len);
+ __throw_exception_again;
+ }
+ std::_Destroy(begin(), end());
+ _M_deallocate(this->_M_impl._M_start,
+ this->_M_impl._M_end_of_storage
+ - this->_M_impl._M_start);
+ this->_M_impl._M_start = __new_start.base();
+ this->_M_impl._M_finish = __new_finish.base();
+ this->_M_impl._M_end_of_storage = __new_start.base() + __len;
+ }
}
template<typename _Tp, typename _Alloc>
@@ -275,140 +297,155 @@ namespace __gnu_norm
_M_fill_insert(iterator __position, size_type __n, const value_type& __x)
{
if (__n != 0)
- {
- if (size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_finish) >= __n)
- {
- value_type __x_copy = __x;
- const size_type __elems_after = end() - __position;
- iterator __old_finish(this->_M_impl._M_finish);
- if (__elems_after > __n)
- {
- std::uninitialized_copy(this->_M_impl._M_finish - __n,
- this->_M_impl._M_finish,
- this->_M_impl._M_finish);
- this->_M_impl._M_finish += __n;
- std::copy_backward(__position, __old_finish - __n, __old_finish);
- std::fill(__position, __position + __n, __x_copy);
- }
- else
- {
- std::uninitialized_fill_n(this->_M_impl._M_finish,
- __n - __elems_after,
- __x_copy);
- this->_M_impl._M_finish += __n - __elems_after;
- std::uninitialized_copy(__position, __old_finish, this->_M_impl._M_finish);
- this->_M_impl._M_finish += __elems_after;
- std::fill(__position, __old_finish, __x_copy);
- }
- }
- else
- {
- const size_type __old_size = size();
- const size_type __len = __old_size + std::max(__old_size, __n);
- iterator __new_start(this->_M_allocate(__len));
- iterator __new_finish(__new_start);
- try
- {
- __new_finish = std::uninitialized_copy(begin(), __position,
- __new_start);
- __new_finish = std::uninitialized_fill_n(__new_finish, __n, __x);
- __new_finish = std::uninitialized_copy(__position, end(),
- __new_finish);
- }
- catch(...)
- {
- std::_Destroy(__new_start,__new_finish);
- _M_deallocate(__new_start.base(),__len);
- __throw_exception_again;
- }
- std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish);
- _M_deallocate(this->_M_impl._M_start,
- this->_M_impl._M_end_of_storage - this->_M_impl._M_start);
- this->_M_impl._M_start = __new_start.base();
- this->_M_impl._M_finish = __new_finish.base();
- this->_M_impl._M_end_of_storage = __new_start.base() + __len;
- }
- }
+ {
+ if (size_type(this->_M_impl._M_end_of_storage
+ - this->_M_impl._M_finish) >= __n)
+ {
+ value_type __x_copy = __x;
+ const size_type __elems_after = end() - __position;
+ iterator __old_finish(this->_M_impl._M_finish);
+ if (__elems_after > __n)
+ {
+ std::uninitialized_copy(this->_M_impl._M_finish - __n,
+ this->_M_impl._M_finish,
+ this->_M_impl._M_finish);
+ this->_M_impl._M_finish += __n;
+ std::copy_backward(__position, __old_finish - __n,
+ __old_finish);
+ std::fill(__position, __position + __n, __x_copy);
+ }
+ else
+ {
+ std::uninitialized_fill_n(this->_M_impl._M_finish,
+ __n - __elems_after,
+ __x_copy);
+ this->_M_impl._M_finish += __n - __elems_after;
+ std::uninitialized_copy(__position, __old_finish,
+ this->_M_impl._M_finish);
+ this->_M_impl._M_finish += __elems_after;
+ std::fill(__position, __old_finish, __x_copy);
+ }
+ }
+ else
+ {
+ const size_type __old_size = size();
+ const size_type __len = __old_size + std::max(__old_size, __n);
+ iterator __new_start(this->_M_allocate(__len));
+ iterator __new_finish(__new_start);
+ try
+ {
+ __new_finish = std::uninitialized_copy(begin(), __position,
+ __new_start);
+ __new_finish = std::uninitialized_fill_n(__new_finish, __n,
+ __x);
+ __new_finish = std::uninitialized_copy(__position, end(),
+ __new_finish);
+ }
+ catch(...)
+ {
+ std::_Destroy(__new_start,__new_finish);
+ _M_deallocate(__new_start.base(),__len);
+ __throw_exception_again;
+ }
+ std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish);
+ _M_deallocate(this->_M_impl._M_start,
+ this->_M_impl._M_end_of_storage
+ - this->_M_impl._M_start);
+ this->_M_impl._M_start = __new_start.base();
+ this->_M_impl._M_finish = __new_finish.base();
+ this->_M_impl._M_end_of_storage = __new_start.base() + __len;
+ }
+ }
}
template<typename _Tp, typename _Alloc> template<typename _InputIterator>
void
vector<_Tp,_Alloc>::
- _M_range_insert(iterator __pos,
- _InputIterator __first, _InputIterator __last,
- input_iterator_tag)
+ _M_range_insert(iterator __pos, _InputIterator __first,
+ _InputIterator __last, input_iterator_tag)
{
for ( ; __first != __last; ++__first)
- {
- __pos = insert(__pos, *__first);
- ++__pos;
- }
+ {
+ __pos = insert(__pos, *__first);
+ ++__pos;
+ }
}
- template<typename _Tp, typename _Alloc> template<typename _ForwardIterator>
- void
- vector<_Tp,_Alloc>::
- _M_range_insert(iterator __position,_ForwardIterator __first,
- _ForwardIterator __last, forward_iterator_tag)
- {
- if (__first != __last)
+ template<typename _Tp, typename _Alloc>
+ template<typename _ForwardIterator>
+ void
+ vector<_Tp,_Alloc>::
+ _M_range_insert(iterator __position,_ForwardIterator __first,
+ _ForwardIterator __last, forward_iterator_tag)
{
- size_type __n = std::distance(__first, __last);
- if (size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_finish) >= __n)
- {
- const size_type __elems_after = end() - __position;
- iterator __old_finish(this->_M_impl._M_finish);
- if (__elems_after > __n)
- {
- std::uninitialized_copy(this->_M_impl._M_finish - __n,
- this->_M_impl._M_finish,
- this->_M_impl._M_finish);
- this->_M_impl._M_finish += __n;
- std::copy_backward(__position, __old_finish - __n, __old_finish);
- std::copy(__first, __last, __position);
- }
- else
- {
- _ForwardIterator __mid = __first;
- std::advance(__mid, __elems_after);
- std::uninitialized_copy(__mid, __last, this->_M_impl._M_finish);
- this->_M_impl._M_finish += __n - __elems_after;
- std::uninitialized_copy(__position, __old_finish, this->_M_impl._M_finish);
- this->_M_impl._M_finish += __elems_after;
- std::copy(__first, __mid, __position);
- }
- }
- else
- {
- const size_type __old_size = size();
- const size_type __len = __old_size + std::max(__old_size, __n);
- iterator __new_start(this->_M_allocate(__len));
- iterator __new_finish(__new_start);
- try
- {
- __new_finish = std::uninitialized_copy(iterator(this->_M_impl._M_start),
- __position, __new_start);
- __new_finish = std::uninitialized_copy(__first, __last,
- __new_finish);
- __new_finish = std::uninitialized_copy(__position,
- iterator(this->_M_impl._M_finish),
- __new_finish);
- }
- catch(...)
- {
- std::_Destroy(__new_start,__new_finish);
- _M_deallocate(__new_start.base(), __len);
- __throw_exception_again;
- }
- std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish);
- _M_deallocate(this->_M_impl._M_start,
- this->_M_impl._M_end_of_storage - this->_M_impl._M_start);
- this->_M_impl._M_start = __new_start.base();
- this->_M_impl._M_finish = __new_finish.base();
- this->_M_impl._M_end_of_storage = __new_start.base() + __len;
- }
+ if (__first != __last)
+ {
+ size_type __n = std::distance(__first, __last);
+ if (size_type(this->_M_impl._M_end_of_storage
+ - this->_M_impl._M_finish) >= __n)
+ {
+ const size_type __elems_after = end() - __position;
+ iterator __old_finish(this->_M_impl._M_finish);
+ if (__elems_after > __n)
+ {
+ std::uninitialized_copy(this->_M_impl._M_finish - __n,
+ this->_M_impl._M_finish,
+ this->_M_impl._M_finish);
+ this->_M_impl._M_finish += __n;
+ std::copy_backward(__position, __old_finish - __n,
+ __old_finish);
+ std::copy(__first, __last, __position);
+ }
+ else
+ {
+ _ForwardIterator __mid = __first;
+ std::advance(__mid, __elems_after);
+ std::uninitialized_copy(__mid, __last,
+ this->_M_impl._M_finish);
+ this->_M_impl._M_finish += __n - __elems_after;
+ std::uninitialized_copy(__position, __old_finish,
+ this->_M_impl._M_finish);
+ this->_M_impl._M_finish += __elems_after;
+ std::copy(__first, __mid, __position);
+ }
+ }
+ else
+ {
+ const size_type __old_size = size();
+ const size_type __len = __old_size + std::max(__old_size, __n);
+ iterator __new_start(this->_M_allocate(__len));
+ iterator __new_finish(__new_start);
+ try
+ {
+ __new_finish = std::uninitialized_copy(iterator(this->
+ _M_impl.
+ _M_start),
+ __position,
+ __new_start);
+ __new_finish = std::uninitialized_copy(__first, __last,
+ __new_finish);
+ __new_finish = std::uninitialized_copy(__position,
+ iterator(this->
+ _M_impl.
+ _M_finish),
+ __new_finish);
+ }
+ catch(...)
+ {
+ std::_Destroy(__new_start,__new_finish);
+ _M_deallocate(__new_start.base(), __len);
+ __throw_exception_again;
+ }
+ std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish);
+ _M_deallocate(this->_M_impl._M_start,
+ this->_M_impl._M_end_of_storage
+ - this->_M_impl._M_start);
+ this->_M_impl._M_start = __new_start.base();
+ this->_M_impl._M_finish = __new_finish.base();
+ this->_M_impl._M_end_of_storage = __new_start.base() + __len;
+ }
+ }
}
- }
-} // namespace __gnu_norm
+} // namespace std
#endif /* _VECTOR_TCC */
diff --git a/libstdc++-v3/include/debug/bitset b/libstdc++-v3/include/debug/bitset
index 1d8875aaa8a..2e2364ff930 100644
--- a/libstdc++-v3/include/debug/bitset
+++ b/libstdc++-v3/include/debug/bitset
@@ -1,6 +1,6 @@
// Debugging bitset implementation -*- C++ -*-
-// Copyright (C) 2003
+// Copyright (C) 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -39,9 +39,10 @@ namespace __gnu_debug_def
{
template<size_t _Nb>
class bitset
- : public __gnu_norm::bitset<_Nb>, public __gnu_debug::_Safe_sequence_base
+ : public _GLIBCXX_STD::bitset<_Nb>,
+ public __gnu_debug::_Safe_sequence_base
{
- typedef __gnu_norm::bitset<_Nb> _Base;
+ typedef _GLIBCXX_STD::bitset<_Nb> _Base;
typedef __gnu_debug::_Safe_sequence_base _Safe_base;
public:
diff --git a/libstdc++-v3/include/debug/deque b/libstdc++-v3/include/debug/deque
index ed68b37a798..c39a49c0461 100644
--- a/libstdc++-v3/include/debug/deque
+++ b/libstdc++-v3/include/debug/deque
@@ -1,6 +1,6 @@
// Debugging deque implementation -*- C++ -*-
-// Copyright (C) 2003
+// Copyright (C) 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -39,10 +39,10 @@ namespace __gnu_debug_def
{
template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
class deque
- : public __gnu_norm::deque<_Tp, _Allocator>,
- public __gnu_debug::_Safe_sequence<deque<_Tp, _Allocator> >
+ : public _GLIBCXX_STD::deque<_Tp, _Allocator>,
+ public __gnu_debug::_Safe_sequence<deque<_Tp, _Allocator> >
{
- typedef __gnu_norm::deque<_Tp, _Allocator> _Base;
+ typedef _GLIBCXX_STD::deque<_Tp, _Allocator> _Base;
typedef __gnu_debug::_Safe_sequence<deque> _Safe_base;
public:
diff --git a/libstdc++-v3/include/debug/formatter.h b/libstdc++-v3/include/debug/formatter.h
index 6ed00bd868e..7022fa70077 100644
--- a/libstdc++-v3/include/debug/formatter.h
+++ b/libstdc++-v3/include/debug/formatter.h
@@ -1,6 +1,6 @@
// Debug-mode error formatting implementation -*- C++ -*-
-// Copyright (C) 2003
+// Copyright (C) 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -36,7 +36,7 @@
namespace __gnu_debug
{
- using namespace std;
+ using std::type_info;
/** Determine if the two types are the same. */
template<typename _Type1, typename _Type2>
diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list
index f9bb9f9435c..556c9d9acff 100644
--- a/libstdc++-v3/include/debug/list
+++ b/libstdc++-v3/include/debug/list
@@ -1,6 +1,6 @@
// Debugging list implementation -*- C++ -*-
-// Copyright (C) 2003
+// Copyright (C) 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -40,10 +40,10 @@ namespace __gnu_debug_def
{
template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
class list
- : public __gnu_norm::list<_Tp, _Allocator>,
+ : public _GLIBCXX_STD::list<_Tp, _Allocator>,
public __gnu_debug::_Safe_sequence<list<_Tp, _Allocator> >
{
- typedef __gnu_norm::list<_Tp, _Allocator> _Base;
+ typedef _GLIBCXX_STD::list<_Tp, _Allocator> _Base;
typedef __gnu_debug::_Safe_sequence<list> _Safe_base;
public:
@@ -76,7 +76,7 @@ namespace __gnu_debug_def
template<class _InputIterator>
list(_InputIterator __first, _InputIterator __last,
const _Allocator& __a = _Allocator())
- : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a)
+ : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a)
{ }
diff --git a/libstdc++-v3/include/debug/map.h b/libstdc++-v3/include/debug/map.h
index 9470e667434..2a6794b31e0 100644
--- a/libstdc++-v3/include/debug/map.h
+++ b/libstdc++-v3/include/debug/map.h
@@ -1,6 +1,6 @@
// Debugging map implementation -*- C++ -*-
-// Copyright (C) 2003
+// Copyright (C) 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -40,10 +40,10 @@ namespace __gnu_debug_def
template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
class map
- : public __gnu_norm::map<_Key, _Tp, _Compare, _Allocator>,
+ : public _GLIBCXX_STD::map<_Key, _Tp, _Compare, _Allocator>,
public __gnu_debug::_Safe_sequence<map<_Key, _Tp, _Compare, _Allocator> >
{
- typedef __gnu_norm::map<_Key, _Tp, _Compare, _Allocator> _Base;
+ typedef _GLIBCXX_STD::map<_Key, _Tp, _Compare, _Allocator> _Base;
typedef __gnu_debug::_Safe_sequence<map> _Safe_base;
public:
diff --git a/libstdc++-v3/include/debug/multimap.h b/libstdc++-v3/include/debug/multimap.h
index 3772c31dc69..4de1e3b58f4 100644
--- a/libstdc++-v3/include/debug/multimap.h
+++ b/libstdc++-v3/include/debug/multimap.h
@@ -1,6 +1,6 @@
// Debugging multimap implementation -*- C++ -*-
-// Copyright (C) 2003
+// Copyright (C) 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -40,10 +40,10 @@ namespace __gnu_debug_def
template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
class multimap
- : public __gnu_norm::multimap<_Key, _Tp, _Compare, _Allocator>,
+ : public _GLIBCXX_STD::multimap<_Key, _Tp, _Compare, _Allocator>,
public __gnu_debug::_Safe_sequence<multimap<_Key,_Tp,_Compare,_Allocator> >
{
- typedef __gnu_norm::multimap<_Key, _Tp, _Compare, _Allocator> _Base;
+ typedef _GLIBCXX_STD::multimap<_Key, _Tp, _Compare, _Allocator> _Base;
typedef __gnu_debug::_Safe_sequence<multimap> _Safe_base;
public:
diff --git a/libstdc++-v3/include/debug/multiset.h b/libstdc++-v3/include/debug/multiset.h
index 19bc29a960a..92042fef68c 100644
--- a/libstdc++-v3/include/debug/multiset.h
+++ b/libstdc++-v3/include/debug/multiset.h
@@ -1,6 +1,6 @@
// Debugging multiset implementation -*- C++ -*-
-// Copyright (C) 2003
+// Copyright (C) 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -40,10 +40,10 @@ namespace __gnu_debug_def
template<typename _Key, typename _Compare = std::less<_Key>,
typename _Allocator = std::allocator<_Key> >
class multiset
- : public __gnu_norm::multiset<_Key, _Compare, _Allocator>,
+ : public _GLIBCXX_STD::multiset<_Key, _Compare, _Allocator>,
public __gnu_debug::_Safe_sequence<multiset<_Key, _Compare, _Allocator> >
{
- typedef __gnu_norm::multiset<_Key, _Compare, _Allocator> _Base;
+ typedef _GLIBCXX_STD::multiset<_Key, _Compare, _Allocator> _Base;
typedef __gnu_debug::_Safe_sequence<multiset> _Safe_base;
public:
diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h
index 72ba3b52f10..7482d6caa65 100644
--- a/libstdc++-v3/include/debug/safe_iterator.h
+++ b/libstdc++-v3/include/debug/safe_iterator.h
@@ -1,6 +1,6 @@
// Safe iterator implementation -*- C++ -*-
-// Copyright (C) 2003
+// Copyright (C) 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -38,6 +38,9 @@
namespace __gnu_debug
{
+ using std::iterator_traits;
+ using std::pair;
+
/** Iterators that derive from _Safe_iterator_base but that aren't
* _Safe_iterators can be determined singular or non-singular via
* _Safe_iterator_base.
diff --git a/libstdc++-v3/include/debug/safe_iterator.tcc b/libstdc++-v3/include/debug/safe_iterator.tcc
index 29813f4e8e2..cede969d168 100644
--- a/libstdc++-v3/include/debug/safe_iterator.tcc
+++ b/libstdc++-v3/include/debug/safe_iterator.tcc
@@ -1,6 +1,6 @@
// Debugging iterator implementation (out of line) -*- C++ -*-
-// Copyright (C) 2003
+// Copyright (C) 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -123,11 +123,11 @@ namespace __gnu_debug
if (this->base() == __victim->base())
__victim->_M_version = 0;
}
- for (_Safe_iterator_base* iter = _M_sequence->_M_const_iterators;
- iter; /* increment in loop */)
+ for (_Safe_iterator_base* iter2 = _M_sequence->_M_const_iterators;
+ iter2; /* increment in loop */)
{
- const_iterator* __victim = static_cast<const_iterator*>(iter);
- iter = iter->_M_next;
+ const_iterator* __victim = static_cast<const_iterator*>(iter2);
+ iter2 = iter2->_M_next;
if (this->base() == __victim->base())
__victim->_M_version = 0;
}
diff --git a/libstdc++-v3/include/debug/safe_sequence.h b/libstdc++-v3/include/debug/safe_sequence.h
index 0bae9430313..f050530a997 100644
--- a/libstdc++-v3/include/debug/safe_sequence.h
+++ b/libstdc++-v3/include/debug/safe_sequence.h
@@ -1,6 +1,6 @@
// Safe sequence implementation -*- C++ -*-
-// Copyright (C) 2003
+// Copyright (C) 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -133,10 +133,10 @@ namespace __gnu_debug
}
}
- for (_Safe_iterator_base* __iter = _M_const_iterators; __iter; )
+ for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2; )
{
- const_iterator* __victim = static_cast<const_iterator*>(__iter);
- __iter = __iter->_M_next;
+ const_iterator* __victim = static_cast<const_iterator*>(__iter2);
+ __iter2 = __iter2->_M_next;
if (!__victim->_M_singular())
{
if (__pred(__victim->base()))
@@ -166,10 +166,11 @@ namespace __gnu_debug
__victim->_M_attach(static_cast<_Sequence*>(this));
}
- for (_Safe_iterator_base* __iter = __from->_M_const_iterators; __iter;)
+ for (_Safe_iterator_base* __iter2 = __from->_M_const_iterators;
+ __iter2;)
{
- const_iterator* __victim = static_cast<const_iterator*>(__iter);
- __iter = __iter->_M_next;
+ const_iterator* __victim = static_cast<const_iterator*>(__iter2);
+ __iter2 = __iter2->_M_next;
if (!__victim->_M_singular() && __victim->base() == __x.base())
__victim->_M_attach(static_cast<_Sequence*>(this));
}
diff --git a/libstdc++-v3/include/debug/set.h b/libstdc++-v3/include/debug/set.h
index b9200adf233..8656cb0aff6 100644
--- a/libstdc++-v3/include/debug/set.h
+++ b/libstdc++-v3/include/debug/set.h
@@ -1,6 +1,6 @@
// Debugging set implementation -*- C++ -*-
-// Copyright (C) 2003
+// Copyright (C) 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -40,10 +40,10 @@ namespace __gnu_debug_def
template<typename _Key, typename _Compare = std::less<_Key>,
typename _Allocator = std::allocator<_Key> >
class set
- : public __gnu_norm::set<_Key,_Compare,_Allocator>,
+ : public _GLIBCXX_STD::set<_Key,_Compare,_Allocator>,
public __gnu_debug::_Safe_sequence<set<_Key, _Compare, _Allocator> >
{
- typedef __gnu_norm::set<_Key,_Compare,_Allocator> _Base;
+ typedef _GLIBCXX_STD::set<_Key,_Compare,_Allocator> _Base;
typedef __gnu_debug::_Safe_sequence<set> _Safe_base;
public:
diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector
index f7fa3e8f092..0cc2997b975 100644
--- a/libstdc++-v3/include/debug/vector
+++ b/libstdc++-v3/include/debug/vector
@@ -1,6 +1,6 @@
// Debugging vector implementation -*- C++ -*-
-// Copyright (C) 2003
+// Copyright (C) 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -41,10 +41,10 @@ namespace __gnu_debug_def
template<typename _Tp,
typename _Allocator = std::allocator<_Tp> >
class vector
- : public __gnu_norm::vector<_Tp, _Allocator>,
+ : public _GLIBCXX_STD::vector<_Tp, _Allocator>,
public __gnu_debug::_Safe_sequence<vector<_Tp, _Allocator> >
{
- typedef __gnu_norm::vector<_Tp, _Allocator> _Base;
+ typedef _GLIBCXX_STD::vector<_Tp, _Allocator> _Base;
typedef __gnu_debug::_Safe_sequence<vector> _Safe_base;
typedef typename _Base::const_iterator _Base_const_iterator;
diff --git a/libstdc++-v3/include/std/std_bitset.h b/libstdc++-v3/include/std/std_bitset.h
index 04249eca4f8..01e3f904e47 100644
--- a/libstdc++-v3/include/std/std_bitset.h
+++ b/libstdc++-v3/include/std/std_bitset.h
@@ -1,6 +1,6 @@
// <bitset> -*- C++ -*-
-// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002, 2003, 2004 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
@@ -59,12 +59,11 @@
#include <ostream> // For ostream (operator<<)
#include <istream> // For istream (operator>>)
-
#define _GLIBCXX_BITSET_BITS_PER_WORD numeric_limits<unsigned long>::digits
#define _GLIBCXX_BITSET_WORDS(__n) \
((__n) < 1 ? 0 : ((__n) + _GLIBCXX_BITSET_BITS_PER_WORD - 1)/_GLIBCXX_BITSET_BITS_PER_WORD)
-namespace __gnu_norm
+namespace _GLIBCXX_STD
{
/**
* @if maint
@@ -291,7 +290,7 @@ namespace __gnu_norm
++__prev;
// check out of bounds
- if ( __prev >= _Nw * _GLIBCXX_BITSET_BITS_PER_WORD )
+ if (__prev >= _Nw * _GLIBCXX_BITSET_BITS_PER_WORD)
return __not_found;
// search first word
@@ -299,7 +298,7 @@ namespace __gnu_norm
_WordT __thisword = _M_w[__i];
// mask off bits below bound
- __thisword >>= __prev + 1;
+ __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev);
if (__thisword != static_cast<_WordT>(0))
return __i * _GLIBCXX_BITSET_BITS_PER_WORD
@@ -1218,7 +1217,7 @@ namespace __gnu_norm
return __os << __tmp;
}
//@}
-} // namespace __gnu_norm
+} // namespace std
#undef _GLIBCXX_BITSET_WORDS
#undef _GLIBCXX_BITSET_BITS_PER_WORD
diff --git a/libstdc++-v3/libsupc++/tinfo.h b/libstdc++-v3/libsupc++/tinfo.h
index b7191900d00..2c55e03a6d9 100644
--- a/libstdc++-v3/libsupc++/tinfo.h
+++ b/libstdc++-v3/libsupc++/tinfo.h
@@ -1,7 +1,33 @@
// RTTI support internals for -*- C++ -*-
-// Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000, 2001
+// Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2004
// Free Software Foundation
+// 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 2, or (at your option)
+// any later version.
+
+// GCC is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file 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 General Public License.
+
#include "typeinfo"
#include <cstddef>
diff --git a/libstdc++-v3/linkage.m4 b/libstdc++-v3/linkage.m4
index eec02800ddb..87c64cb9b57 100644
--- a/libstdc++-v3/linkage.m4
+++ b/libstdc++-v3/linkage.m4
@@ -404,6 +404,11 @@ AC_DEFUN([GLIBCXX_CHECK_MATH_SUPPORT], [
ac_save_LIBS="$LIBS"
LIBS="$LIBS $libm"
+ dnl Check libmx
+ AC_CHECK_LIB(mx, sqrtf, libmx="-lmx")
+ dnl ac_save_LIBS="$LIBS"
+ LIBS="$LIBS $libmx"
+
dnl Check to see if certain C math functions exist.
GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_1(isinf)
GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_1(isnan)
diff --git a/libstdc++-v3/po/string_literals.cc b/libstdc++-v3/po/string_literals.cc
index 776cf39068a..262e708a4dc 100644
--- a/libstdc++-v3/po/string_literals.cc
+++ b/libstdc++-v3/po/string_literals.cc
@@ -16,6 +16,15 @@
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file 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 General Public License.
+
#include <libintl.h>
#define gettext_noop(Str) Str
diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index d70d1af3ad1..ed4c7107901 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -101,6 +101,7 @@ sources = \
complex_io.cc \
ctype.cc \
debug.cc \
+ debug_list.cc \
functexcept.cc \
globals_locale.cc \
globals_io.cc \
diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
index 9c4f48330ca..aa192c2b1e2 100644
--- a/libstdc++-v3/src/Makefile.in
+++ b/libstdc++-v3/src/Makefile.in
@@ -59,12 +59,12 @@ am__objects_1 = atomicity.lo codecvt_members.lo collate_members.lo \
numeric_members.lo time_members.lo
am__objects_2 = basic_file.lo c++locale.lo
am__objects_3 = allocator.lo codecvt.lo complex_io.lo ctype.lo \
- debug.lo functexcept.lo globals_locale.lo globals_io.lo ios.lo \
- ios_failure.lo ios_init.lo ios_locale.lo limits.lo list.lo \
- locale.lo locale_init.lo locale_facets.lo localename.lo \
- stdexcept.lo strstream.lo tree.lo allocator-inst.lo \
- concept-inst.lo fstream-inst.lo ext-inst.lo io-inst.lo \
- istream-inst.lo locale-inst.lo locale-misc-inst.lo \
+ debug.lo debug_list.lo functexcept.lo globals_locale.lo \
+ globals_io.lo ios.lo ios_failure.lo ios_init.lo ios_locale.lo \
+ limits.lo list.lo locale.lo locale_init.lo locale_facets.lo \
+ localename.lo stdexcept.lo strstream.lo tree.lo \
+ allocator-inst.lo concept-inst.lo fstream-inst.lo ext-inst.lo \
+ io-inst.lo istream-inst.lo locale-inst.lo locale-misc-inst.lo \
misc-inst.lo ostream-inst.lo sstream-inst.lo streambuf-inst.lo \
string-inst.lo valarray-inst.lo wlocale-inst.lo \
wstring-inst.lo $(am__objects_1) $(am__objects_2)
@@ -299,6 +299,7 @@ sources = \
complex_io.cc \
ctype.cc \
debug.cc \
+ debug_list.cc \
functexcept.cc \
globals_locale.cc \
globals_io.cc \
diff --git a/libstdc++-v3/src/debug.cc b/libstdc++-v3/src/debug.cc
index 1d1aee46627..05ebc2ffa7b 100644
--- a/libstdc++-v3/src/debug.cc
+++ b/libstdc++-v3/src/debug.cc
@@ -114,10 +114,10 @@ namespace __gnu_debug
__old->_M_attach(0, false);
}
- for (_Safe_iterator_base* __iter = _M_const_iterators; __iter; )
+ for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2; )
{
- _Safe_iterator_base* __old = __iter;
- __iter = __iter->_M_next;
+ _Safe_iterator_base* __old = __iter2;
+ __iter2 = __iter2->_M_next;
__old->_M_attach(0, true);
}
}
@@ -134,10 +134,10 @@ namespace __gnu_debug
__old->_M_attach(0, false);
}
- for (_Safe_iterator_base* __iter = _M_const_iterators; __iter; )
+ for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2; )
{
- _Safe_iterator_base* __old = __iter;
- __iter = __iter->_M_next;
+ _Safe_iterator_base* __old = __iter2;
+ __iter2 = __iter2->_M_next;
if (__old->_M_singular())
__old->_M_attach(0, true);
}
diff --git a/libstdc++-v3/src/debug_list.cc b/libstdc++-v3/src/debug_list.cc
new file mode 100644
index 00000000000..3d14b28f4b9
--- /dev/null
+++ b/libstdc++-v3/src/debug_list.cc
@@ -0,0 +1,34 @@
+// Debugging mode support code for list -*- C++ -*-
+
+// Copyright (C) 2004 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file 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 General Public License.
+
+#define _GLIBCXX_DEBUG
+
+#include <bits/c++config.h>
+
+#include "list.cc"
diff --git a/libstdc++-v3/src/list.cc b/libstdc++-v3/src/list.cc
index 2be2d713193..ec94053b411 100644
--- a/libstdc++-v3/src/list.cc
+++ b/libstdc++-v3/src/list.cc
@@ -55,7 +55,7 @@
#include <list>
-namespace __gnu_norm
+namespace _GLIBCXX_STD
{
void
_List_node_base::swap(_List_node_base& __x, _List_node_base& __y)
@@ -121,7 +121,7 @@ namespace __gnu_norm
}
void
- _List_node_base::hook(_List_node_base * const __position)
+ _List_node_base::hook(_List_node_base* const __position)
{
this->_M_next = __position;
this->_M_prev = __position->_M_prev;
@@ -137,5 +137,5 @@ namespace __gnu_norm
__prev_node->_M_next = __next_node;
__next_node->_M_prev = __prev_node;
}
-} // namespace __gnu_norm
+} // namespace std
diff --git a/libstdc++-v3/src/locale.cc b/libstdc++-v3/src/locale.cc
index 7021b65ec58..d28d39aed76 100644
--- a/libstdc++-v3/src/locale.cc
+++ b/libstdc++-v3/src/locale.cc
@@ -70,9 +70,22 @@ namespace std
bool
locale::operator==(const locale& __rhs) const throw()
{
- string __name = this->name();
- return (_M_impl == __rhs._M_impl
- || (__name != "*" && __name == __rhs.name()));
+ // Deal first with the common cases, fast to process: refcopies,
+ // unnamed (i.e., !_M_names[0]), "simple" (!_M_names[1] => all the
+ // categories same name, i.e., _M_names[0]). Otherwise fall back
+ // to the general locale::name().
+ bool __ret;
+ if (_M_impl == __rhs._M_impl)
+ __ret = true;
+ else if (!_M_impl->_M_names[0] || !__rhs._M_impl->_M_names[0]
+ || std::strcmp(_M_impl->_M_names[0],
+ __rhs._M_impl->_M_names[0]) != 0)
+ __ret = false;
+ else if (!_M_impl->_M_names[1] && !__rhs._M_impl->_M_names[1])
+ __ret = true;
+ else
+ __ret = this->name() == __rhs.name();
+ return __ret;
}
const locale&
@@ -88,10 +101,13 @@ namespace std
locale::name() const
{
string __ret;
- if (_M_impl->_M_check_same_name())
+ if (!_M_impl->_M_names[0])
+ __ret = '*';
+ else if (_M_impl->_M_check_same_name())
__ret = _M_impl->_M_names[0];
else
{
+ __ret.reserve(128);
__ret += _S_categories[0];
__ret += '=';
__ret += _M_impl->_M_names[0];
@@ -225,22 +241,23 @@ namespace std
_M_facets[__i]->_M_add_reference();
}
_M_caches = new const facet*[_M_facets_size];
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
+ for (size_t __j = 0; __j < _M_facets_size; ++__j)
{
- _M_caches[__i] = __imp._M_caches[__i];
- if (_M_caches[__i])
- _M_caches[__i]->_M_add_reference();
+ _M_caches[__j] = __imp._M_caches[__j];
+ if (_M_caches[__j])
+ _M_caches[__j]->_M_add_reference();
}
_M_names = new char*[_S_categories_size];
- for (size_t __i = 0; __i < _S_categories_size; ++__i)
- _M_names[__i] = 0;
+ for (size_t __k = 0; __k < _S_categories_size; ++__k)
+ _M_names[__k] = 0;
- // Name all the categories.
- for (size_t __i = 0; __i < _S_categories_size; ++__i)
+ // Name the categories.
+ for (size_t __l = 0; (__l < _S_categories_size
+ && __imp._M_names[__l]); ++__l)
{
- char* __new = new char[std::strlen(__imp._M_names[__i]) + 1];
- std::strcpy(__new, __imp._M_names[__i]);
- _M_names[__i] = __new;
+ const size_t __len = std::strlen(__imp._M_names[__l]) + 1;
+ _M_names[__l] = new char[__len];
+ std::memcpy(_M_names[__l], __imp._M_names[__l], __len);
}
}
catch(...)
@@ -252,7 +269,8 @@ namespace std
void
locale::_Impl::
- _M_replace_category(const _Impl* __imp, const locale::id* const* __idpp)
+ _M_replace_category(const _Impl* __imp,
+ const locale::id* const* __idpp)
{
for (; *__idpp; ++__idpp)
_M_replace_facet(__imp, *__idpp);
@@ -263,7 +281,8 @@ namespace std
_M_replace_facet(const _Impl* __imp, const locale::id* __idp)
{
size_t __index = __idp->_M_id();
- if ((__index > (__imp->_M_facets_size - 1)) || !__imp->_M_facets[__index])
+ if ((__index > (__imp->_M_facets_size - 1))
+ || !__imp->_M_facets[__index])
__throw_runtime_error(__N("locale::_Impl::_M_replace_facet"));
_M_install_facet(__idp, __imp->_M_facets[__index]);
}
@@ -287,8 +306,8 @@ namespace std
__newf = new const facet*[__new_size];
for (size_t __i = 0; __i < _M_facets_size; ++__i)
__newf[__i] = _M_facets[__i];
- for (size_t __i2 = _M_facets_size; __i2 < __new_size; ++__i2)
- __newf[__i2] = 0;
+ for (size_t __l = _M_facets_size; __l < __new_size; ++__l)
+ __newf[__l] = 0;
// New cache array.
const facet** __oldc = _M_caches;
@@ -302,10 +321,10 @@ namespace std
delete [] __newf;
__throw_exception_again;
}
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
- __newc[__i] = _M_caches[__i];
- for (size_t __i2 = _M_facets_size; __i2 < __new_size; ++__i2)
- __newc[__i2] = 0;
+ for (size_t __j = 0; __j < _M_facets_size; ++__j)
+ __newc[__j] = _M_caches[__j];
+ for (size_t __k = _M_facets_size; __k < __new_size; ++__k)
+ __newc[__k] = 0;
_M_facets_size = __new_size;
_M_facets = __newf;
@@ -347,7 +366,6 @@ namespace std
}
}
-
// locale::id
// Definitions for static const data members of locale::id
_Atomic_word locale::id::_S_refcount; // init'd to 0 by linker
diff --git a/libstdc++-v3/src/locale_init.cc b/libstdc++-v3/src/locale_init.cc
index c1dac9f7a7c..175ece6500d 100644
--- a/libstdc++-v3/src/locale_init.cc
+++ b/libstdc++-v3/src/locale_init.cc
@@ -114,9 +114,10 @@ namespace std
__glibcxx_mutex_lock(__gnu_internal::locale_global_mutex);
_Impl* __old = _S_global;
__other._M_impl->_M_add_reference();
- _S_global = __other._M_impl;
- if (__other.name() != "*")
- setlocale(LC_ALL, __other.name().c_str());
+ _S_global = __other._M_impl;
+ const string __other_name = __other.name();
+ if (__other_name != "*")
+ setlocale(LC_ALL, __other_name.c_str());
__glibcxx_mutex_unlock(__gnu_internal::locale_global_mutex);
// Reference count sanity check: one reference removed for the
@@ -255,13 +256,12 @@ namespace std
for (size_t __i = 0; __i < _M_facets_size; ++__i)
_M_facets[__i] = _M_caches[__i] = 0;
- // Name all the categories.
+ // Name the categories.
_M_names = new (&name_vec) char*[_S_categories_size];
- for (size_t __i = 0; __i < _S_categories_size; ++__i)
- {
- _M_names[__i] = new (&name_c[__i]) char[2];
- std::strcpy(_M_names[__i], locale::facet::_S_get_c_name());
- }
+ _M_names[0] = new (&name_c[0]) char[2];
+ std::memcpy(_M_names[0], locale::facet::_S_get_c_name(), 2);
+ for (size_t __j = 1; __j < _S_categories_size; ++__j)
+ _M_names[__j] = 0;
// This is needed as presently the C++ version of "C" locales
// != data in the underlying locale model for __timepunct,
diff --git a/libstdc++-v3/src/localename.cc b/libstdc++-v3/src/localename.cc
index 4cd1af189fa..1600b2cc55b 100644
--- a/libstdc++-v3/src/localename.cc
+++ b/libstdc++-v3/src/localename.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -34,7 +34,6 @@ namespace std
{
using namespace __gnu_cxx;
-
locale::locale(const char* __s)
{
if (__s)
@@ -95,6 +94,7 @@ namespace std
if (__i < _S_categories_size)
{
string __str;
+ __str.reserve(128);
for (size_t __j = 0; __j < __i; ++__j)
{
__str += _S_categories[__j];
@@ -193,21 +193,18 @@ namespace std
for (size_t __i = 0; __i < _M_facets_size; ++__i)
_M_facets[__i] = 0;
_M_caches = new const facet*[_M_facets_size];
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
- _M_caches[__i] = 0;
+ for (size_t __j = 0; __j < _M_facets_size; ++__j)
+ _M_caches[__j] = 0;
_M_names = new char*[_S_categories_size];
- for (size_t __i = 0; __i < _S_categories_size; ++__i)
- _M_names[__i] = 0;
+ for (size_t __k = 0; __k < _S_categories_size; ++__k)
+ _M_names[__k] = 0;
- // Name all the categories.
+ // Name the categories.
const size_t __len = std::strlen(__s);
if (!std::strchr(__s, ';'))
{
- for (size_t __i = 0; __i < _S_categories_size; ++__i)
- {
- _M_names[__i] = new char[__len + 1];
- std::strcpy(_M_names[__i], __s);
- }
+ _M_names[0] = new char[__len + 1];
+ std::memcpy(_M_names[0], __s, __len + 1);
}
else
{
@@ -218,10 +215,9 @@ namespace std
const char* __end = std::strchr(__beg, ';');
if (!__end)
__end = __s + __len;
- char* __new = new char[__end - __beg + 1];
- std::memcpy(__new, __beg, __end - __beg);
- __new[__end - __beg] = '\0';
- _M_names[__i] = __new;
+ _M_names[__i] = new char[__end - __beg + 1];
+ std::memcpy(_M_names[__i], __beg, __end - __beg);
+ _M_names[__i][__end - __beg] = '\0';
}
}
@@ -271,19 +267,35 @@ namespace std
locale::_Impl::
_M_replace_categories(const _Impl* __imp, category __cat)
{
- for (size_t __ix = 0; __ix < _S_categories_size; ++__ix)
+ category __mask = 1;
+ const bool __have_names = _M_names[0] && __imp->_M_names[0];
+ for (size_t __ix = 0; __ix < _S_categories_size; ++__ix, __mask <<= 1)
{
- const category __mask = 1 << __ix;
if (__mask & __cat)
{
// Need to replace entry in _M_facets with other locale's info.
_M_replace_category(__imp, _S_facet_categories[__ix]);
// If both have names, go ahead and mangle.
- if (std::strcmp(_M_names[__ix], "*") != 0
- && std::strcmp(__imp->_M_names[__ix], "*") != 0)
+ if (__have_names)
{
- char* __new = new char[std::strlen(__imp->_M_names[__ix]) + 1];
- std::strcpy(__new, __imp->_M_names[__ix]);
+ if (!_M_names[1])
+ {
+ // A full set of _M_names must be prepared, all identical
+ // to _M_names[0] to begin with. Then, below, a few will
+ // be replaced by the corresponding __imp->_M_names. I.e.,
+ // not a "simple" locale anymore (see locale::operator==).
+ const size_t __len = std::strlen(_M_names[0]) + 1;
+ for (size_t __i = 1; __i < _S_categories_size; ++__i)
+ {
+ _M_names[__i] = new char[__len];
+ std::memcpy(_M_names[__i], _M_names[0], __len);
+ }
+ }
+ char* __src = __imp->_M_names[__ix] ? __imp->_M_names[__ix]
+ : __imp->_M_names[0];
+ const size_t __len = std::strlen(__src) + 1;
+ char* __new = new char[__len];
+ std::memcpy(__new, __src, __len);
delete [] _M_names[__ix];
_M_names[__ix] = __new;
}
diff --git a/libstdc++-v3/testsuite/18_support/new_delete_placement.cc b/libstdc++-v3/testsuite/18_support/new_delete_placement.cc
index e65f19ca57f..bf28440bd3b 100644
--- a/libstdc++-v3/testsuite/18_support/new_delete_placement.cc
+++ b/libstdc++-v3/testsuite/18_support/new_delete_placement.cc
@@ -1,6 +1,6 @@
// 2002-07-24 Benjamin Kosnik
-// Copyright (C) 2002 Free Software Foundation
+// Copyright (C) 2002, 2004 Free Software Foundation
//
// 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
@@ -28,7 +28,7 @@ void test01()
{
void* pc = new char;
void* pa = new char[10];
- void* tmp;
+ void* tmp = NULL;
operator delete(pc, tmp);
operator delete[](pa, tmp);
}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/1.cc
index 2599d4298ff..f74f143516f 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/1.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/1.cc
@@ -1,6 +1,6 @@
// 1999-05-11 bkoz
-// Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
+// Copyright (C) 1999, 2002, 2003, 2004 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
@@ -140,7 +140,7 @@ void test01()
VERIFY( sz04 >= 100 );
str02.reserve();
sz03 = str02.capacity();
- VERIFY( sz03 >= 0 );
+ VERIFY( sz03 == 0 );
sz03 = str02.size() + 5;
str02.resize(sz03);
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/1.cc
index 9cdc4f0457c..e55899dbbe5 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/1.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/1.cc
@@ -1,6 +1,6 @@
// 1999-05-11 bkoz
-// Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
+// Copyright (C) 1999, 2002, 2003, 2004 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
@@ -37,7 +37,7 @@ void test01()
VERIFY( sz02 >= 100 );
str01.reserve();
sz01 = str01.capacity();
- VERIFY( sz01 >= 0 );
+ VERIFY( sz01 == 0 );
sz01 = str01.size() + 5;
str01.resize(sz01);
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/1.cc
index 925d812c748..55c13463818 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/1.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/1.cc
@@ -1,6 +1,6 @@
// 1999-05-11 bkoz
-// Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
+// Copyright (C) 1999, 2002, 2003, 2004 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
@@ -37,7 +37,7 @@ void test01()
VERIFY( sz02 >= 100 );
str01.reserve();
sz01 = str01.capacity();
- VERIFY( sz01 >= 0 );
+ VERIFY( sz01 == 0 );
sz01 = str01.size() + 5;
str01.resize(sz01);
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char/10.cc b/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char/10.cc
new file mode 100644
index 00000000000..75b7e89d2a5
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/char/10.cc
@@ -0,0 +1,80 @@
+// Copyright (C) 2004 Free Software Foundation
+//
+// 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 21.3.7.9 inserters and extractors
+
+#include <istream>
+#include <string>
+#include <fstream>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+string prepare(string::size_type len, unsigned nchunks, char delim)
+{
+ string ret;
+ for (unsigned i = 0; i < nchunks; ++i)
+ {
+ for (string::size_type j = 0; j < len; ++j)
+ ret.push_back('a' + rand() % 26);
+ len *= 2;
+ ret.push_back(delim);
+ }
+ return ret;
+}
+
+void check(istream& stream, const string& str, char delim)
+{
+ bool test __attribute__((unused)) = true;
+
+ string chunk;
+ string::size_type index = 0, index_new = 0;
+
+ while (getline(stream, chunk, delim))
+ {
+ index_new = str.find(delim, index);
+ VERIFY( !str.compare(index, index_new - index, chunk) );
+ index = index_new + 1;
+ }
+ VERIFY( stream.eof() );
+}
+
+// istream& getline(istream&, string&, char)
+void test01()
+{
+ const char filename[] = "inserters_extractors-2.txt";
+
+ const char delim = '|';
+ const string data = prepare(777, 10, delim);
+
+ ofstream ofstrm;
+ ofstrm.open(filename);
+ ofstrm.write(data.data(), data.size());
+ ofstrm.close();
+
+ ifstream ifstrm;
+ ifstrm.open(filename);
+ check(ifstrm, data, delim);
+ ifstrm.close();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/10.cc b/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/10.cc
new file mode 100644
index 00000000000..5f1e1d77d9e
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/wchar_t/10.cc
@@ -0,0 +1,80 @@
+// Copyright (C) 2004 Free Software Foundation
+//
+// 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 21.3.7.9 inserters and extractors
+
+#include <istream>
+#include <string>
+#include <fstream>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+wstring prepare(wstring::size_type len, unsigned nchunks, wchar_t delim)
+{
+ wstring ret;
+ for (unsigned i = 0; i < nchunks; ++i)
+ {
+ for (wstring::size_type j = 0; j < len; ++j)
+ ret.push_back(L'a' + rand() % 26);
+ len *= 2;
+ ret.push_back(delim);
+ }
+ return ret;
+}
+
+void check(wistream& stream, const wstring& str, wchar_t delim)
+{
+ bool test __attribute__((unused)) = true;
+
+ wstring chunk;
+ wstring::size_type index = 0, index_new = 0;
+
+ while (getline(stream, chunk, delim))
+ {
+ index_new = str.find(delim, index);
+ VERIFY( !str.compare(index, index_new - index, chunk) );
+ index = index_new + 1;
+ }
+ VERIFY( stream.eof() );
+}
+
+// istream& getline(istream&, string&, char)
+void test01()
+{
+ const char filename[] = "inserters_extractors-2.txt";
+
+ const wchar_t delim = L'|';
+ const wstring data = prepare(777, 10, delim);
+
+ wofstream ofstrm;
+ ofstrm.open(filename);
+ ofstrm.write(data.data(), data.size());
+ ofstrm.close();
+
+ wifstream ifstrm;
+ ifstrm.open(filename);
+ check(ifstrm, data, delim);
+ ifstrm.close();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/21_strings/char_traits/requirements/char/1.cc b/libstdc++-v3/testsuite/21_strings/char_traits/requirements/char/1.cc
index 4ef29f20d35..15500b0dce2 100644
--- a/libstdc++-v3/testsuite/21_strings/char_traits/requirements/char/1.cc
+++ b/libstdc++-v3/testsuite/21_strings/char_traits/requirements/char/1.cc
@@ -1,6 +1,6 @@
// 1999-06-03 bkoz
-// Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+// Copyright (C) 1999, 2000, 2001, 2003, 2004 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
@@ -56,6 +56,7 @@ void test01(void)
const char str_lit1[] = "montara and ocean beach";
int len = sizeof(str_lit1) + sizeof(array1) - 1; // two terminating chars
char array2[len];
+ std::char_traits<char>::copy(array2, "boracay, philippines", len);
VERIFY( str_lit1[0] == 'm' );
c1 = array2[0];
diff --git a/libstdc++-v3/testsuite/21_strings/char_traits/requirements/short/1.cc b/libstdc++-v3/testsuite/21_strings/char_traits/requirements/short/1.cc
index b38b3cff177..4dbcae0db91 100644
--- a/libstdc++-v3/testsuite/21_strings/char_traits/requirements/short/1.cc
+++ b/libstdc++-v3/testsuite/21_strings/char_traits/requirements/short/1.cc
@@ -1,7 +1,7 @@
// 1999-06-03 bkoz
// 2003-07-22 Matt Austern
-// Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+// Copyright (C) 1999, 2000, 2001, 2003, 2004 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
@@ -76,7 +76,9 @@ void test02(void)
int len = sizeof(str_lit1)/sizeof(short) + sizeof(array1)/sizeof(short) - 1;
// two terminating chars
+ short array3[] = {'b', 'o', 'r', 'a', 'c', 'a', 'y', ',', ' ', 'p', 'h', 'i', 'l', 'i', 'p', 'p', 'i', 'n', 'e', 's', 0};
short array2[len];
+ std::char_traits<short>::copy(array2, array3, len);
VERIFY( str_lit1[0] == 'm' );
c1 = array2[0];
diff --git a/libstdc++-v3/testsuite/21_strings/char_traits/requirements/wchar_t/1.cc b/libstdc++-v3/testsuite/21_strings/char_traits/requirements/wchar_t/1.cc
index d4a64ae4a10..d7582ca4cc1 100644
--- a/libstdc++-v3/testsuite/21_strings/char_traits/requirements/wchar_t/1.cc
+++ b/libstdc++-v3/testsuite/21_strings/char_traits/requirements/wchar_t/1.cc
@@ -1,6 +1,6 @@
// 1999-06-03 bkoz
-// Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+// Copyright (C) 1999, 2000, 2001, 2003, 2004 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
@@ -56,6 +56,7 @@ void test02(void)
const wchar_t str_lit1[] = L"montara and ocean beach";
int len = sizeof(str_lit1) + sizeof(array1) - 1; // two terminating chars
wchar_t array2[len];
+ std::char_traits<wchar_t>::copy(array2, L"boracay, philippines", len);
VERIFY( str_lit1[0] == 'm' );
c1 = array2[0];
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/ext/15361.cc b/libstdc++-v3/testsuite/23_containers/bitset/ext/15361.cc
new file mode 100644
index 00000000000..e42d6498e4e
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/bitset/ext/15361.cc
@@ -0,0 +1,40 @@
+// Copyright (C) 2004 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+#include <bitset>
+#include <testsuite_hooks.h>
+
+// libstdc++/15361
+void test01()
+{
+ using namespace std;
+ bool test __attribute__((unused)) = true;
+
+ bitset<256> b;
+ b.set(225);
+ b.set(226);
+
+ VERIFY( b._Find_first() == 225 );
+ VERIFY( b._Find_next(225) == 226 );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/clear_allocator.cc b/libstdc++-v3/testsuite/23_containers/vector/bool/clear_allocator.cc
new file mode 100644
index 00000000000..ff177162674
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/bool/clear_allocator.cc
@@ -0,0 +1,88 @@
+// Copyright (C) 2004 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+#include <vector>
+#include <ext/new_allocator.h>
+
+using namespace std;
+using __gnu_cxx::new_allocator;
+
+template<typename T>
+ class clear_alloc : public new_allocator<T>
+ {
+ public:
+
+ template <typename T1>
+ struct rebind
+ { typedef clear_alloc<T1> other; };
+
+ virtual void clear() throw()
+ { }
+
+ clear_alloc() throw()
+ { }
+
+ clear_alloc(clear_alloc const& _wa) throw()
+ { }
+
+ template<typename T1>
+ clear_alloc(clear_alloc<T1> const& _wa) throw()
+ { }
+
+ virtual ~clear_alloc() throw()
+ { this->clear(); }
+
+ T* allocate(typename new_allocator<T>::size_type n, const void *hint = 0)
+ {
+ this->clear();
+ return new_allocator<T>::allocate(n, hint);
+ }
+
+ void deallocate(T *ptr, typename new_allocator<T>::size_type n)
+ {
+ this->clear();
+ new_allocator<T>::deallocate(ptr, n);
+ }
+ };
+
+template<typename Container>
+ void Check_Container()
+ {
+ Container* pic = new Container;
+ int x = 230;
+
+ while (x--)
+ {
+ pic->push_back(x);
+ }
+
+ pic->get_allocator();
+
+ // The following has led to infinite recursions or cores.
+ pic->clear();
+
+ delete pic;
+ }
+
+
+int main()
+{
+ Check_Container<std::vector<bool, clear_alloc<bool> > >();
+ return 0;
+}
+
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/2.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/2.cc
index 5005c17f4b4..60f00ba41d4 100644
--- a/libstdc++-v3/testsuite/27_io/basic_filebuf/2.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/2.cc
@@ -1,6 +1,6 @@
// 1999-01-17 bkoz test functionality of basic_filebuf for char_type == char
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -30,9 +30,8 @@
// test05
// libstdc++/1886
// should be able to instantiate basic_filebuf for non-standard types.
-namespace test
+namespace std
{
- using namespace std;
using __gnu_test::pod_char;
typedef short type_t;
template class basic_filebuf<type_t, char_traits<type_t> >;
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-4.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-4.cc
index 497a35fea72..a6cb7b12a1d 100644
--- a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-4.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-4.cc
@@ -33,7 +33,7 @@ protected:
};
// libstdc++/13171
-int test01()
+void test01()
{
bool test __attribute__((unused)) = true;
using namespace std;
@@ -51,4 +51,5 @@ int test01()
int main()
{
test01();
+ return 0;
}
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/14975-1.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/14975-1.cc
new file mode 100644
index 00000000000..0b7369e12b1
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/14975-1.cc
@@ -0,0 +1,67 @@
+// 2004-04-16 Petur Runolfsson <peturr02@ru.is>
+
+// Copyright (C) 2004 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 27.8.1.4 Overridden virtual functions
+
+#include <fstream>
+#include <locale>
+#include <testsuite_hooks.h>
+
+class Buf : public std::filebuf
+{
+protected:
+ virtual int_type
+ overflow(int_type c = traits_type::eof())
+ {
+ return traits_type::eq_int_type(c, traits_type::eof()) ?
+ traits_type::eof() : std::filebuf::overflow(c);
+ }
+};
+
+// libstdc++/14975
+void test01()
+{
+ using namespace std;
+ bool test __attribute__((unused)) = true;
+
+ Buf fb;
+ locale loc_us = __gnu_test::try_named_locale("en_US");
+ fb.pubimbue(loc_us);
+ fb.open("tmp_14975-1", ios_base::out);
+
+ try
+ {
+ fb.sputc('a');
+ fb.sputc('b');
+ fb.pubimbue(locale::classic());
+ fb.sputc('c');
+ fb.pubsync();
+ fb.close();
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/13582-3.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/13582-3.cc
index afda81412cb..3d15b24e203 100644
--- a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/13582-3.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/13582-3.cc
@@ -25,7 +25,7 @@
#include <testsuite_hooks.h>
// libstdc++/13582
-int test01()
+void test01()
{
bool test __attribute__((unused)) = true;
using namespace std;
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/14975-2.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/14975-2.cc
new file mode 100644
index 00000000000..8789b9aa4d8
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/14975-2.cc
@@ -0,0 +1,83 @@
+// 2004-04-16 Petur Runolfsson <peturr02@ru.is>
+
+// Copyright (C) 2004 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+#include <fstream>
+#include <locale>
+#include <unistd.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <testsuite_hooks.h>
+
+// libstdc++/14975
+void test01()
+{
+ using namespace std;
+ using namespace __gnu_test;
+ bool test __attribute__((unused)) = true;
+
+ locale loc_us = try_named_locale("en_US");
+
+ const char* name = "tmp_14975-2";
+
+ signal(SIGPIPE, SIG_IGN);
+
+ unlink(name);
+ try_mkfifo(name, S_IRWXU);
+
+ int child = fork();
+ VERIFY( child != -1 );
+
+ if (child == 0)
+ {
+ filebuf fbin;
+ fbin.open(name, ios_base::in);
+ sleep(2);
+ exit(0);
+ }
+
+ wfilebuf fb;
+ fb.pubimbue(loc_us);
+ sleep(1);
+ wfilebuf* ret = fb.open(name, ios_base::out);
+ VERIFY( ret != NULL );
+ VERIFY( fb.is_open() );
+
+ sleep(3);
+
+ try
+ {
+ fb.sputc(L'a');
+ fb.sputc(L'b');
+ fb.pubimbue(locale::classic());
+ fb.sputc(L'c');
+ fb.close();
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_fstream/2.cc b/libstdc++-v3/testsuite/27_io/basic_fstream/2.cc
index 861a6044f9e..ebe19417366 100644
--- a/libstdc++-v3/testsuite/27_io/basic_fstream/2.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_fstream/2.cc
@@ -1,6 +1,6 @@
// 2002-07-25 Benjamin Kosnik <bkoz@redhat.com>
-// Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+// Copyright (C) 2002, 2003, 2004 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
@@ -35,9 +35,8 @@
// { dg-do compile }
-namespace test
+namespace std
{
- using namespace std;
using __gnu_test::pod_char;
typedef short type_t;
template class basic_fstream<type_t, char_traits<type_t> >;
diff --git a/libstdc++-v3/testsuite/27_io/basic_ifstream/2.cc b/libstdc++-v3/testsuite/27_io/basic_ifstream/2.cc
index 6fb71a575ad..224abcf6608 100644
--- a/libstdc++-v3/testsuite/27_io/basic_ifstream/2.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_ifstream/2.cc
@@ -1,6 +1,6 @@
// 2002-07-25 Benjamin Kosnik <bkoz@redhat.com>
-// Copyright (C) 2002 Free Software Foundation, Inc.
+// Copyright (C) 2002, 2004 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
@@ -34,9 +34,8 @@
// { dg-do compile }
-namespace test
+namespace std
{
- using namespace std;
typedef short type_t;
template class basic_ifstream<type_t, char_traits<type_t> >;
} // test
diff --git a/libstdc++-v3/testsuite/27_io/basic_ios/2.cc b/libstdc++-v3/testsuite/27_io/basic_ios/2.cc
index 56e2bd8ed69..88b94438642 100644
--- a/libstdc++-v3/testsuite/27_io/basic_ios/2.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_ios/2.cc
@@ -1,6 +1,6 @@
// 2002-07-25 Benjamin Kosnik <bkoz@redhat.com>
-// Copyright (C) 2002 Free Software Foundation, Inc.
+// Copyright (C) 2002, 2004 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
@@ -34,9 +34,8 @@
// { dg-do compile }
-namespace test
+namespace std
{
- using namespace std;
typedef short type_t;
template class basic_ios<type_t, char_traits<type_t> >;
} // test
diff --git a/libstdc++-v3/testsuite/27_io/basic_iostream/2.cc b/libstdc++-v3/testsuite/27_io/basic_iostream/2.cc
index b77ec4f79f2..eff57709285 100644
--- a/libstdc++-v3/testsuite/27_io/basic_iostream/2.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_iostream/2.cc
@@ -1,6 +1,6 @@
// 2002-01-08 bkoz
-// Copyright (C) 2002 Free Software Foundation, Inc.
+// Copyright (C) 2002, 2004 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
@@ -34,9 +34,8 @@
#include <istream>
-namespace test
+namespace std
{
- using namespace std;
typedef short type_t;
template class basic_iostream<type_t, char_traits<type_t> >;
} // test
diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/2.cc b/libstdc++-v3/testsuite/27_io/basic_istream/2.cc
index 7676f6a094e..b58b77ce5bf 100644
--- a/libstdc++-v3/testsuite/27_io/basic_istream/2.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/2.cc
@@ -1,6 +1,7 @@
// 1999-09-20 bkoz
-// Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+// 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
@@ -35,9 +36,8 @@
// { dg-do compile }
-namespace test
+namespace std
{
- using namespace std;
using __gnu_test::pod_char;
typedef short type_t;
template class basic_istream<type_t, char_traits<type_t> >;
diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_character/char/9555-ic.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_character/char/9555-ic.cc
index 435e7f428af..0e27199fd2b 100644
--- a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_character/char/9555-ic.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_character/char/9555-ic.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2003 Free Software Foundation, Inc.
+// Copyright (C) 2003, 2004 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
@@ -54,7 +54,8 @@ void testthrow(T arg)
}
catch(...)
{
- VERIFY( test = false );
+ test = false;
+ VERIFY( test );
}
}
diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/getline/char/4.cc b/libstdc++-v3/testsuite/27_io/basic_istream/getline/char/4.cc
new file mode 100644
index 00000000000..2734c60fd2e
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/getline/char/4.cc
@@ -0,0 +1,108 @@
+// Copyright (C) 2004 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file 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 General Public License.
+
+// 27.6.1.3 unformatted input functions
+
+#include <cstring> // for strlen
+#include <istream>
+#include <testsuite_hooks.h>
+
+class Inbuf : public std::streambuf
+{
+ static const char buf[];
+ const char* current;
+ int size;
+
+public:
+ Inbuf()
+ {
+ current = buf;
+ size = std::strlen(buf);
+ }
+
+ int_type underflow()
+ {
+ if (current < buf + size)
+ return traits_type::to_int_type(*current);
+ return traits_type::eof();
+ }
+
+ int_type uflow()
+ {
+ if (current < buf + size)
+ return traits_type::to_int_type(*current++);
+ return traits_type::eof();
+ }
+};
+
+const char Inbuf::buf[] = "1234567890abcdefghij";
+
+void test01()
+{
+ using namespace std;
+ bool test __attribute__((unused)) = true;
+
+ typedef char_traits<char> traits_type;
+
+ Inbuf inbuf1;
+ istream is(&inbuf1);
+
+ char buffer[10];
+ traits_type::assign(buffer, sizeof(buffer), 'X');
+
+ is.getline(buffer, sizeof(buffer), '0');
+ VERIFY( is.rdstate() == ios_base::goodbit );
+ VERIFY( !traits_type::compare(buffer, "123456789\0", sizeof(buffer)) );
+ VERIFY( is.gcount() == 10 );
+
+ is.clear();
+ traits_type::assign(buffer, sizeof(buffer), 'X');
+ is.getline(buffer, sizeof(buffer));
+ VERIFY( is.rdstate() == ios_base::failbit );
+ VERIFY( !traits_type::compare(buffer, "abcdefghi\0", sizeof(buffer)) );
+ VERIFY( is.gcount() == 9 );
+
+ is.clear();
+ traits_type::assign(buffer, sizeof(buffer), 'X');
+ is.getline(buffer, sizeof(buffer));
+ VERIFY( is.rdstate() == ios_base::eofbit );
+ VERIFY( !traits_type::compare(buffer, "j\0XXXXXXXX", sizeof(buffer)) );
+ VERIFY( is.gcount() == 1 );
+
+ is.clear();
+ traits_type::assign(buffer, sizeof(buffer), 'X');
+ is.getline(buffer, sizeof(buffer));
+ VERIFY( is.rdstate() == (ios_base::eofbit | ios_base::failbit) );
+ VERIFY( !traits_type::compare(buffer, "\0XXXXXXXXX", sizeof(buffer)) );
+ VERIFY( is.gcount() == 0 );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/getline/char/5.cc b/libstdc++-v3/testsuite/27_io/basic_istream/getline/char/5.cc
new file mode 100644
index 00000000000..b2f07725c64
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/getline/char/5.cc
@@ -0,0 +1,81 @@
+// Copyright (C) 2004 Free Software Foundation
+//
+// 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 27.6.1.3 unformatted input functions
+
+#include <istream>
+#include <string>
+#include <fstream>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+string prepare(string::size_type len, unsigned nchunks, char delim)
+{
+ string ret;
+ for (unsigned i = 0; i < nchunks; ++i)
+ {
+ for (string::size_type j = 0; j < len; ++j)
+ ret.push_back('a' + rand() % 26);
+ len *= 2;
+ ret.push_back(delim);
+ }
+ return ret;
+}
+
+void check(istream& stream, const string& str, char delim)
+{
+ bool test __attribute__((unused)) = true;
+
+ char buf[1000000];
+ string::size_type index = 0, index_new = 0;
+
+ while (stream.getline(buf, sizeof(buf), delim))
+ {
+ index_new = str.find(delim, index);
+ VERIFY( stream.gcount() == index_new - index + 1 );
+ VERIFY( !str.compare(index, index_new - index, buf) );
+ index = index_new + 1;
+ }
+ VERIFY( stream.gcount() == 0 );
+ VERIFY( stream.eof() );
+}
+
+void test01()
+{
+ const char filename[] = "istream_getline.txt";
+
+ const char delim = '|';
+ const string data = prepare(777, 10, delim);
+
+ ofstream ofstrm;
+ ofstrm.open(filename);
+ ofstrm.write(data.data(), data.size());
+ ofstrm.close();
+
+ ifstream ifstrm;
+ ifstrm.open(filename);
+ check(ifstrm, data, delim);
+ ifstrm.close();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/seekg/char/exceptions_badbit_throw.cc b/libstdc++-v3/testsuite/27_io/basic_istream/seekg/char/exceptions_badbit_throw.cc
index bf893408064..2d65f2c81a1 100644
--- a/libstdc++-v3/testsuite/27_io/basic_istream/seekg/char/exceptions_badbit_throw.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/seekg/char/exceptions_badbit_throw.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2003 Free Software Foundation, Inc.
+// Copyright (C) 2003, 2004 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
@@ -67,7 +67,7 @@ void test02()
istream stream(&bib);
stream.exceptions(ios_base::badbit);
- istream::off_type off;
+ istream::off_type off(5);
try
{
diff --git a/libstdc++-v3/testsuite/27_io/basic_istringstream/2.cc b/libstdc++-v3/testsuite/27_io/basic_istringstream/2.cc
index becb4c8a81f..27e6f565916 100644
--- a/libstdc++-v3/testsuite/27_io/basic_istringstream/2.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_istringstream/2.cc
@@ -1,6 +1,6 @@
// 2002-07-25 Benjamin Kosnik <bkoz@redhat.com>
-// Copyright (C) 2002 Free Software Foundation, Inc.
+// Copyright (C) 2002, 2004 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
@@ -34,9 +34,8 @@
// { dg-do compile }
-namespace test
+namespace std
{
- using namespace std;
typedef short type_t;
template class basic_istringstream<type_t, char_traits<type_t> >;
} // test
diff --git a/libstdc++-v3/testsuite/27_io/basic_istringstream/str/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_istringstream/str/char/1.cc
index 509386e2a11..d9cd676704b 100644
--- a/libstdc++-v3/testsuite/27_io/basic_istringstream/str/char/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_istringstream/str/char/1.cc
@@ -1,6 +1,6 @@
// 2000-01-10 bkoz
-// Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+// Copyright (C) 2000, 2001, 2003, 2004 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
@@ -48,7 +48,7 @@ void test01()
state1 = is01.rdstate();
is01 >> a;
state2 = is01.rdstate();
- VERIFY( a = i01 );
+ VERIFY( a == i01 );
// 22.2.2.1.2 num_get virtual functions
// p 13
// in any case, if stage 2 processing was terminated by the test for
diff --git a/libstdc++-v3/testsuite/27_io/basic_ofstream/2.cc b/libstdc++-v3/testsuite/27_io/basic_ofstream/2.cc
index b13948945a6..24f2ed4822e 100644
--- a/libstdc++-v3/testsuite/27_io/basic_ofstream/2.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_ofstream/2.cc
@@ -1,6 +1,6 @@
// 2002-07-25 Benjamin Kosnik <bkoz@redhat.com>
-// Copyright (C) 2002 Free Software Foundation, Inc.
+// Copyright (C) 2002, 2004 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
@@ -34,9 +34,8 @@
// { dg-do compile }
-namespace test
+namespace std
{
- using namespace std;
typedef short type_t;
template class basic_ifstream<type_t, char_traits<type_t> >;
} // test
diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/2.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/2.cc
index 3910aa7bd34..84305c8bdc0 100644
--- a/libstdc++-v3/testsuite/27_io/basic_ostream/2.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_ostream/2.cc
@@ -1,6 +1,7 @@
// 1999-09-20 bkoz
-// Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+// 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
@@ -35,9 +36,8 @@
// { dg-do compile }
-namespace test
+namespace std
{
- using namespace std;
using __gnu_test::pod_char;
typedef short type_t;
template class basic_ostream<type_t, char_traits<type_t> >;
diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/char/exceptions_badbit_throw.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/char/exceptions_badbit_throw.cc
index a084dbdb7d4..32ff029b6a0 100644
--- a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/char/exceptions_badbit_throw.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/char/exceptions_badbit_throw.cc
@@ -1,6 +1,6 @@
// 2003-03-08 Jerry Quinn <jlquinn@optonline.net>
-// Copyright (C) 2003 Free Software Foundation, Inc.
+// Copyright (C) 2003, 2004 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
@@ -39,7 +39,7 @@ void test_badbit()
try
{
- T i;
+ T i = T();
stream << i;
VERIFY( false );
}
diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/char/exceptions_failbit_throw.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/char/exceptions_failbit_throw.cc
index a1fbe21178f..6b3b77df68c 100644
--- a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/char/exceptions_failbit_throw.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/char/exceptions_failbit_throw.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2003
+// Copyright (C) 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -45,7 +45,7 @@ void test_failbit()
try
{
- T i;
+ T i = T();
stream << i;
}
catch (const ios_base::failure&)
diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/seekp/char/exceptions_badbit_throw.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/seekp/char/exceptions_badbit_throw.cc
index b0b30518eb0..eba317456c7 100644
--- a/libstdc++-v3/testsuite/27_io/basic_ostream/seekp/char/exceptions_badbit_throw.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_ostream/seekp/char/exceptions_badbit_throw.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2003 Free Software Foundation, Inc.
+// Copyright (C) 2003, 2004 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
@@ -40,7 +40,7 @@ void test01()
ostream stream(&bib);
stream.exceptions(ios_base::badbit);
- ostream::pos_type pos;
+ ostream::pos_type pos = ostream::pos_type();
try
{
@@ -67,7 +67,7 @@ void test02()
ostream stream(&bib);
stream.exceptions(ios_base::badbit);
- ostream::off_type off;
+ ostream::off_type off(5);
try
{
diff --git a/libstdc++-v3/testsuite/27_io/basic_ostringstream/2.cc b/libstdc++-v3/testsuite/27_io/basic_ostringstream/2.cc
index a1ca0bf27ed..dd0d4c40206 100644
--- a/libstdc++-v3/testsuite/27_io/basic_ostringstream/2.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_ostringstream/2.cc
@@ -1,6 +1,6 @@
// 2002-07-25 Benjamin Kosnik <bkoz@redhat.com>
-// Copyright (C) 2002 Free Software Foundation, Inc.
+// Copyright (C) 2002, 2004 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
@@ -34,9 +34,8 @@
// { dg-do compile }
-namespace test
+namespace std
{
- using namespace std;
typedef short type_t;
template class basic_ostringstream<type_t, char_traits<type_t> >;
} // test
diff --git a/libstdc++-v3/testsuite/27_io/basic_streambuf/2.cc b/libstdc++-v3/testsuite/27_io/basic_streambuf/2.cc
index 71da9a59349..83d510d85f7 100644
--- a/libstdc++-v3/testsuite/27_io/basic_streambuf/2.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_streambuf/2.cc
@@ -1,6 +1,6 @@
// 2002-07-25 Benjamin Kosnik <bkoz@redhat.com>
-// Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+// Copyright (C) 2002, 2003, 2004 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
@@ -35,9 +35,8 @@
// { dg-do compile }
-namespace test
+namespace std
{
- using namespace std;
using __gnu_test::pod_char;
typedef short type_t;
template class basic_streambuf<type_t, char_traits<type_t> >;
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/1.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/1.cc
index 7841f3275c5..b80f50a939f 100644
--- a/libstdc++-v3/testsuite/27_io/basic_stringbuf/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/1.cc
@@ -47,15 +47,6 @@ void test01()
typedef test_type::off_type off_type;
}
-namespace test
-{
- using namespace std;
- using __gnu_test::pod_char;
- typedef short type_t;
- template class basic_stringbuf<type_t, char_traits<type_t> >;
- template class basic_stringbuf<pod_char, char_traits<pod_char> >;
-} // test
-
int main()
{
test01();
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/2.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/2.cc
index 940aa7a852a..b4532bf9e18 100644
--- a/libstdc++-v3/testsuite/27_io/basic_stringbuf/2.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/2.cc
@@ -1,6 +1,6 @@
// 1999-01-17 bkoz test functionality of basic_filebuf for char_type == char
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -30,14 +30,13 @@
// test05
// libstdc++/1886
// should be able to instantiate basic_stringbuf for non-standard types.
-namespace test
+namespace std
{
- using namespace std;
using __gnu_test::pod_char;
typedef short type_t;
template class basic_stringbuf<type_t, char_traits<type_t> >;
template class basic_stringbuf<pod_char, char_traits<pod_char> >;
-} // test
+} // std
// more surf!!!
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/4.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/4.cc
index fd2ddbd6acc..eebc9968bb2 100644
--- a/libstdc++-v3/testsuite/27_io/basic_stringbuf/4.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/4.cc
@@ -1,6 +1,6 @@
// 2003-04-07 bkoz
-// Copyright (C) 2003 Free Software Foundation, Inc.
+// Copyright (C) 2003, 2004 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
@@ -27,9 +27,8 @@
// { dg-do compile }
-namespace test
+namespace std
{
- using namespace std;
using __gnu_test::pod_char;
typedef __gnu_test::tracker_alloc<char> alloc_type;
template class basic_stringbuf<char, char_traits<char>, alloc_type>;
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringstream/2.cc b/libstdc++-v3/testsuite/27_io/basic_stringstream/2.cc
index 5cd55f1d30b..fcec7f75238 100644
--- a/libstdc++-v3/testsuite/27_io/basic_stringstream/2.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_stringstream/2.cc
@@ -1,6 +1,6 @@
// 2002-07-25 Benjamin Kosnik <bkoz@redhat.com>
-// Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+// Copyright (C) 2002, 2003, 2004 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
@@ -35,11 +35,10 @@
// { dg-do compile }
-namespace test
+namespace std
{
- using namespace std;
using __gnu_test::pod_char;
typedef short type_t;
template class basic_stringstream<type_t, char_traits<type_t> >;
template class basic_stringstream<pod_char, char_traits<pod_char> >;
-} // test
+} // std
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringstream/str/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_stringstream/str/char/1.cc
index 45c78cdafac..00bfb89c85f 100644
--- a/libstdc++-v3/testsuite/27_io/basic_stringstream/str/char/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_stringstream/str/char/1.cc
@@ -1,6 +1,6 @@
// 2001-05-24 Benjamin Kosnik <bkoz@redhat.com>
-// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002, 2003, 2004 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
@@ -48,7 +48,7 @@ void test01()
state1 = is01.rdstate();
is01 >> a;
state2 = is01.rdstate();
- VERIFY( a = i01 );
+ VERIFY( a == i01 );
// 22.2.2.1.2 num_get virtual functions
// p 13
// in any case, if stage 2 processing was terminated by the test for
diff --git a/libstdc++-v3/testsuite/27_io/fpos/1.cc b/libstdc++-v3/testsuite/27_io/fpos/1.cc
index 8d927dc51e1..4d9fe8629f3 100644
--- a/libstdc++-v3/testsuite/27_io/fpos/1.cc
+++ b/libstdc++-v3/testsuite/27_io/fpos/1.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2003
+// Copyright (C) 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -25,14 +25,13 @@
// { dg-do compile }
-namespace test
+namespace std
{
- using namespace std;
using __gnu_test::pod_char;
typedef short type_t;
template class fpos<type_t>;
template class fpos<pod_char>;
-} // test
+} // std
// more surf!!!
diff --git a/libstdc++-v3/testsuite/27_io/fpos/14320-3.cc b/libstdc++-v3/testsuite/27_io/fpos/14320-3.cc
index 19c839e2f74..0e83c05b9ca 100644
--- a/libstdc++-v3/testsuite/27_io/fpos/14320-3.cc
+++ b/libstdc++-v3/testsuite/27_io/fpos/14320-3.cc
@@ -24,7 +24,7 @@
#include <testsuite_hooks.h>
// libstdc++/14320
-int test01()
+void test01()
{
using namespace std;
bool test __attribute__((unused)) = true;
diff --git a/libstdc++-v3/testsuite/27_io/fpos/14775.cc b/libstdc++-v3/testsuite/27_io/fpos/14775.cc
index aff56b6fefb..c8d5b9d6e74 100644
--- a/libstdc++-v3/testsuite/27_io/fpos/14775.cc
+++ b/libstdc++-v3/testsuite/27_io/fpos/14775.cc
@@ -38,7 +38,7 @@ void test01()
__gnu_test::set_file_limit(TWO_GB + 200);
basic_filebuf<char> fb;
- fb.open("14775_tmp", ios_base::out | ios_base::in | ios_base::trunc);
+ fb.open("tmp_14775", ios_base::out | ios_base::in | ios_base::trunc);
pos_type ret = fb.pubseekoff(TWO_GB + 100, ios_base::beg);
VERIFY( ret != pos_type(off_type(-1)) );
diff --git a/libstdc++-v3/testsuite/27_io/ios_base/storage/2.cc b/libstdc++-v3/testsuite/27_io/ios_base/storage/2.cc
index 0da1382edd5..a5570903ed9 100644
--- a/libstdc++-v3/testsuite/27_io/ios_base/storage/2.cc
+++ b/libstdc++-v3/testsuite/27_io/ios_base/storage/2.cc
@@ -58,7 +58,8 @@ void test02()
}
catch(...)
{
- VERIFY( test = false );
+ test = false;
+ VERIFY( test );
}
VERIFY( v == 0 );
@@ -77,7 +78,8 @@ void test02()
}
catch(...)
{
- VERIFY( test = false );
+ test = false;
+ VERIFY( test );
}
VERIFY( v == &test );
@@ -96,7 +98,8 @@ void test02()
}
catch(...)
{
- VERIFY( test = false );
+ test = false;
+ VERIFY( test );
}
VERIFY( l == 0 );
@@ -115,7 +118,8 @@ void test02()
}
catch(...)
{
- VERIFY( test = false );
+ test = false;
+ VERIFY( test );
}
VERIFY( l == 1 );
diff --git a/libstdc++-v3/testsuite/27_io/types/2.cc b/libstdc++-v3/testsuite/27_io/types/2.cc
index 6e0cb502220..106c8f1e9d0 100644
--- a/libstdc++-v3/testsuite/27_io/types/2.cc
+++ b/libstdc++-v3/testsuite/27_io/types/2.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2003 Free Software Foundation
+// Copyright (C) 2003, 2004 Free Software Foundation
//
// 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
@@ -23,7 +23,7 @@
void test01()
{
- std::streamsize ssize;
+ std::streamsize ssize = 0;
std::streamoff soff;
// No signed/unsigned warnings.
diff --git a/libstdc++-v3/testsuite/Makefile.am b/libstdc++-v3/testsuite/Makefile.am
index 0dffb3e8286..9e11ac30ae9 100644
--- a/libstdc++-v3/testsuite/Makefile.am
+++ b/libstdc++-v3/testsuite/Makefile.am
@@ -30,7 +30,8 @@ AM_RUNTESTFLAGS =
## CXX is actually a "C" compiler. These are real C++ programs.
testsuite_flags_script=${glibcxx_builddir}/scripts/testsuite_flags
-CXX=`${testsuite_flags_script} --build-cxx`
+CXX = $(shell ${testsuite_flags_script} --build-cxx)
+AM_CXXFLAGS = $(shell ${testsuite_flags_script} --cxxflags)
GLIBGCC_DIR=`$(CC) -print-libgcc-file-name | sed 's,/[^/]*$$,,'`
GLIBCXX_DIR=${glibcxx_builddir}/src/.libs
@@ -38,18 +39,14 @@ GLIBCXX_DIR=${glibcxx_builddir}/src/.libs
CXXLINK = \
$(LIBTOOL) --tag=CXX --mode=link $(CXX) \
-R $(GLIBGCC_DIR) -R $(GLIBCXX_DIR) \
- $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
-
-# Generated lists of files to run. All of these names are valid make
-# targets, if you wish to generate a list manually.
-lists_of_files = \
- testsuite_files \
- testsuite_files_interactive \
- testsuite_files_performance
+ $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -lv3test -L. -o $@
## Build support library.
noinst_LIBRARIES = libv3test.a
-libv3test_a_SOURCES = testsuite_hooks.cc testsuite_allocator.cc
+libv3test_a_SOURCES = \
+ testsuite_abi.cc \
+ testsuite_allocator.cc \
+ testsuite_hooks.cc
## Build support utilities.
if GLIBCXX_TEST_ABI
@@ -58,6 +55,7 @@ else
noinst_PROGRAMS =
endif
abi_check_SOURCES = abi_check.cc
+abi_check_DEPENDENCIES = libv3test.a
all-local: stamp_wchar testsuite_files
@@ -69,6 +67,14 @@ else
stamp_wchar:
endif
+# Generated lists of files to run. All of these names are valid make
+# targets, if you wish to generate a list manually.
+lists_of_files = \
+ testsuite_files \
+ testsuite_files_interactive \
+ testsuite_files_performance
+
+
# We need more things in site.exp, but automake completely controls the
# creation of that file; there's no way to append to it without messing up
# the dependancy chains. So we overrule automake. This rule is exactly
diff --git a/libstdc++-v3/testsuite/Makefile.in b/libstdc++-v3/testsuite/Makefile.in
index adc811611b2..b74f2b36cdb 100644
--- a/libstdc++-v3/testsuite/Makefile.in
+++ b/libstdc++-v3/testsuite/Makefile.in
@@ -58,8 +58,8 @@ ARFLAGS = cru
LIBRARIES = $(noinst_LIBRARIES)
libv3test_a_AR = $(AR) $(ARFLAGS)
libv3test_a_LIBADD =
-am_libv3test_a_OBJECTS = testsuite_hooks.$(OBJEXT) \
- testsuite_allocator.$(OBJEXT)
+am_libv3test_a_OBJECTS = testsuite_abi.$(OBJEXT) \
+ testsuite_allocator.$(OBJEXT) testsuite_hooks.$(OBJEXT)
libv3test_a_OBJECTS = $(am_libv3test_a_OBJECTS)
PROGRAMS = $(noinst_PROGRAMS)
am_abi_check_OBJECTS = abi_check.$(OBJEXT)
@@ -115,7 +115,7 @@ CPPFLAGS = @CPPFLAGS@
CSTDIO_H = @CSTDIO_H@
CTIME_CC = @CTIME_CC@
CTIME_H = @CTIME_H@
-CXX = `${testsuite_flags_script} --build-cxx`
+CXX = $(shell ${testsuite_flags_script} --build-cxx)
CXXCPP = @CXXCPP@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -266,13 +266,22 @@ AM_CPPFLAGS = $(GLIBCXX_INCLUDES)
AM_MAKEFLAGS = -j1
AM_RUNTESTFLAGS =
testsuite_flags_script = ${glibcxx_builddir}/scripts/testsuite_flags
+AM_CXXFLAGS = $(shell ${testsuite_flags_script} --cxxflags)
GLIBGCC_DIR = `$(CC) -print-libgcc-file-name | sed 's,/[^/]*$$,,'`
GLIBCXX_DIR = ${glibcxx_builddir}/src/.libs
CXXLINK = \
$(LIBTOOL) --tag=CXX --mode=link $(CXX) \
-R $(GLIBGCC_DIR) -R $(GLIBCXX_DIR) \
- $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
+ $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -lv3test -L. -o $@
+noinst_LIBRARIES = libv3test.a
+libv3test_a_SOURCES = \
+ testsuite_abi.cc \
+ testsuite_allocator.cc \
+ testsuite_hooks.cc
+
+abi_check_SOURCES = abi_check.cc
+abi_check_DEPENDENCIES = libv3test.a
# Generated lists of files to run. All of these names are valid make
# targets, if you wish to generate a list manually.
@@ -281,9 +290,6 @@ lists_of_files = \
testsuite_files_interactive \
testsuite_files_performance
-noinst_LIBRARIES = libv3test.a
-libv3test_a_SOURCES = testsuite_hooks.cc testsuite_allocator.cc
-abi_check_SOURCES = abi_check.cc
baseline_file = ${baseline_dir}/baseline_symbols.txt
extract_symvers = $(glibcxx_srcdir)/scripts/extract_symvers
diff --git a/libstdc++-v3/testsuite/abi_check.cc b/libstdc++-v3/testsuite/abi_check.cc
index 2116f7a6b30..18c8b7be9b6 100644
--- a/libstdc++-v3/testsuite/abi_check.cc
+++ b/libstdc++-v3/testsuite/abi_check.cc
@@ -1,311 +1,38 @@
-// Utility for libstdc++ ABI analysis -*- C++ -*-
-
-// Copyright (C) 2002, 2003 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 2, 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 COPYING. If not, write to the Free
-// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-// USA.
-
-// As a special exception, you may use this file as part of a free software
-// library without restriction. Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file 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 General Public License.
+// -*- C++ -*-
+
+// Copyright (C) 2004 Free Software Foundation, Inc.
+
+// 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 2, 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 COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file 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 General
+// Public License.
// Benjamin Kosnik <bkoz@redhat.com>
// Blame subsequent hacks on Loren J. Rittle <ljrittle@acm.org>, Phil
// Edwards <pme@gcc.gnu.org>, and a cast of dozens at libstdc++@gcc.gnu.org.
-
-#include <string>
-#include <ext/hash_map>
-#include <deque>
-#include <sstream>
-#include <fstream>
+
+#include "testsuite_abi.h"
#include <iostream>
-#include <cxxabi.h>
-#include <stdlib.h> // for system(3)
-#include <unistd.h> // for access(2)
-
-struct symbol_info
-{
- enum category { none, function, object, error };
- category type;
- std::string name;
- std::string demangled_name;
- int size;
- std::string version_name;
-
- symbol_info() : type(none), size(0) { }
-
- symbol_info(const symbol_info& other)
- : type(other.type), name(other.name), demangled_name(other.demangled_name),
- size(other.size), version_name(other.version_name) { }
-};
-
-namespace __gnu_cxx
-{
- using namespace std;
-
- template<>
- struct hash<string>
- {
- size_t operator()(const string& s) const
- {
- const collate<char>& c = use_facet<collate<char> >(locale::classic());
- return c.hash(s.c_str(), s.c_str() + s.size());
- }
- };
-}
-
-typedef std::deque<std::string> symbol_names;
-typedef __gnu_cxx::hash_map<std::string, symbol_info> symbol_infos;
-
-
-bool
-check_version(const symbol_info& test, bool added = false)
-{
- typedef std::vector<std::string> compat_list;
- static compat_list known_versions;
- if (known_versions.empty())
- {
- known_versions.push_back("GLIBCPP_3.2"); // base version
- known_versions.push_back("GLIBCPP_3.2.1");
- known_versions.push_back("GLIBCPP_3.2.2");
- known_versions.push_back("GLIBCPP_3.2.3"); // gcc-3.3.0
- known_versions.push_back("GLIBCXX_3.4");
- known_versions.push_back("CXXABI_1.2");
- known_versions.push_back("CXXABI_1.2.1");
- known_versions.push_back("CXXABI_1.3");
- }
- compat_list::iterator begin = known_versions.begin();
- compat_list::iterator end = known_versions.end();
-
- // Check version names for compatibility...
- compat_list::iterator it1 = find(begin, end, test.version_name);
-
- // Check for weak label.
- compat_list::iterator it2 = find(begin, end, test.name);
-
- // Check that added symbols aren't added in the base version.
- bool compat = true;
- if (added && test.version_name == known_versions[0])
- compat = false;
-
- if (it1 == end && it2 == end)
- compat = false;
-
- return compat;
-}
-
-bool
-check_compatible(const symbol_info& lhs, const symbol_info& rhs,
- bool verbose = false)
-{
- using namespace std;
- bool ret = true;
- const char tab = '\t';
-
- // Check to see if symbol_infos are compatible.
- if (lhs.type != rhs.type)
- {
- ret = false;
- if (verbose)
- {
- cout << tab << "incompatible types" << endl;
- }
- }
-
- if (lhs.name != rhs.name)
- {
- ret = false;
- if (verbose)
- {
- cout << tab << "incompatible names" << endl;
- }
- }
-
- if (lhs.size != rhs.size)
- {
- ret = false;
- if (verbose)
- {
- cout << tab << "incompatible sizes" << endl;
- cout << tab << lhs.size << endl;
- cout << tab << rhs.size << endl;
- }
- }
-
- if (lhs.version_name != rhs.version_name
- && !check_version(lhs) && !check_version(rhs))
- {
- ret = false;
- if (verbose)
- {
- cout << tab << "incompatible versions" << endl;
- cout << tab << lhs.version_name << endl;
- cout << tab << rhs.version_name << endl;
- }
- }
-
- if (verbose)
- cout << endl;
-
- return ret;
-}
-
-const char*
-demangle(const std::string& mangled)
-{
- const char* name;
- if (mangled[0] != '_' || mangled[1] != 'Z')
- {
- // This is not a mangled symbol, thus has "C" linkage.
- name = mangled.c_str();
- }
- else
- {
- // Use __cxa_demangle to demangle.
- int status = 0;
- name = abi::__cxa_demangle(mangled.c_str(), 0, 0, &status);
- if (!name)
- {
- switch (status)
- {
- case 0:
- name = "error code = 0: success";
- break;
- case -1:
- name = "error code = -1: memory allocation failure";
- break;
- case -2:
- name = "error code = -2: invalid mangled name";
- break;
- case -3:
- name = "error code = -3: invalid arguments";
- break;
- default:
- name = "error code unknown - who knows what happened";
- }
- }
- }
- return name;
-}
-
-void
-line_to_symbol_info(std::string& input, symbol_info& output)
-{
- using namespace std;
- const char delim = ':';
- const char version_delim = '@';
- const string::size_type npos = string::npos;
- string::size_type n = 0;
-
- // Set the type.
- if (input.find("FUNC") == 0)
- output.type = symbol_info::function;
- else if (input.find("OBJECT") == 0)
- output.type = symbol_info::object;
- else
- output.type = symbol_info::error;
- n = input.find_first_of(delim);
- if (n != npos)
- input.erase(input.begin(), input.begin() + n + 1);
-
- // Iff object, get size info.
- if (output.type == symbol_info::object)
- {
- n = input.find_first_of(delim);
- if (n != npos)
- {
- string size(input.begin(), input.begin() + n);
- istringstream iss(size);
- int x;
- iss >> x;
- if (!iss.fail())
- output.size = x;
- input.erase(input.begin(), input.begin() + n + 1);
- }
- }
-
- // Set the name.
- n = input.find_first_of(version_delim);
- if (n != npos)
- {
- // Found version string.
- output.name = string(input.begin(), input.begin() + n);
- n = input.find_last_of(version_delim);
- input.erase(input.begin(), input.begin() + n + 1);
-
- // Set version name.
- output.version_name = input;
- }
- else
- {
- // No versioning info.
- output.name = string(input.begin(), input.end());
- input.erase(input.begin(), input.end());
- }
-
- // Set the demangled name.
- output.demangled_name = demangle(output.name);
-}
-
-void
-create_symbol_data(const char* file, symbol_infos& symbols,
- symbol_names& names)
-{
- // Parse list of symbols in file into vectors of symbol_info.
- // For 3.2.0 on x86/linux, this usually is
- // 947 non-weak symbols
- // 2084 weak symbols
- using namespace std;
- ifstream ifs(file);
- if (ifs.is_open())
- {
- // Organize input into container of symbol_info objects.
- const string empty;
- string line = empty;
- while (getline(ifs, line).good())
- {
- symbol_info symbol;
- line_to_symbol_info(line, symbol);
- symbols[symbol.name] = symbol;
- names.push_back(symbol.name);
- line = empty;
- }
- }
-}
-
-void
-report_symbol_info(const symbol_info& symbol, std::size_t n, bool ret = true)
-{
- using namespace std;
- const char tab = '\t';
-
- // Add any other information to display here.
- cout << tab << symbol.demangled_name << endl;
- cout << tab << symbol.name << endl;
- cout << tab << symbol.version_name << endl;
-
- if (ret)
- cout << endl;
-}
-
int
main(int argc, char** argv)
@@ -313,144 +40,54 @@ main(int argc, char** argv)
using namespace std;
// Get arguments. (Heading towards getopt_long, I can feel it.)
- bool verbose = false;
string argv1 = argc > 1 ? argv[1] : "";
if (argv1 == "--help" || argc < 4)
{
cerr << "usage: abi_check --check current baseline\n"
" --check-verbose current baseline\n"
- " --help\n\n"
- "Where CURRENT is a file containing the current results from\n"
- "extract_symvers, and BASELINE is one from config/abi.\n"
+ " --examine symbol current\n"
+ " --help\n"
+ "\n"
+ "All arguments are string literals.\n"
+ "CURRENT is a file generated byextract_symvers.\n"
+ "BASELINE is a file from config/abi.\n"
+ "SYMBOL is a mangled name.\n"
<< endl;
exit(1);
}
- else if (argv1 == "--check-verbose")
- verbose = true;
-
- // Quick sanity/setup check for arguments.
- const char* test_file = argv[2];
- const char* baseline_file = argv[3];
- if (access(test_file, R_OK) != 0)
- {
- cerr << "Cannot read symbols file " << test_file
- << ", did you forget to build first?" << endl;
- exit(1);
- }
- if (access(baseline_file, R_OK) != 0)
- {
- cerr << "Cannot read baseline file " << baseline_file << endl;
- exit(1);
- }
-
- // Input both lists of symbols into container.
- symbol_infos baseline_symbols;
- symbol_names baseline_names;
- symbol_infos test_symbols;
- symbol_names test_names;
- create_symbol_data(baseline_file, baseline_symbols, baseline_names);
- create_symbol_data(test_file, test_symbols, test_names);
-
- // Sanity check results.
- const symbol_names::size_type baseline_size = baseline_names.size();
- const symbol_names::size_type test_size = test_names.size();
- if (!baseline_size || !test_size)
- {
- cerr << "Problems parsing the list of exported symbols." << endl;
- exit(2);
- }
-
- // Sort out names.
- // Assuming baseline_names, test_names are both unique w/ no duplicates.
- //
- // The names added to missing_names are baseline_names not found in
- // test_names
- // -> symbols that have been deleted.
- //
- // The names added to added_names are test_names are names not in
- // baseline_names
- // -> symbols that have been added.
- symbol_names shared_names;
- symbol_names missing_names;
- symbol_names added_names = test_names;
- for (size_t i = 0; i < baseline_size; ++i)
- {
- string what(baseline_names[i]);
- symbol_names::iterator end = added_names.end();
- symbol_names::iterator it = find(added_names.begin(), end, what);
- if (it != end)
+
+ if (argv1.find("--check") != string::npos)
+ {
+ bool verbose = false;
+ if (argv1 == "--check-verbose")
+ verbose = true;
+
+ // Quick sanity/setup check for arguments.
+ const char* test_file = argv[2];
+ const char* baseline_file = argv[3];
+ if (access(test_file, R_OK) != 0)
{
- // Found.
- shared_names.push_back(what);
- added_names.erase(it);
+ cerr << "Cannot read symbols file " << test_file
+ << ", did you forget to build first?" << endl;
+ exit(1);
}
- else
- missing_names.push_back(what);
- }
-
- // Check missing names for compatibility.
- typedef pair<symbol_info, symbol_info> symbol_pair;
- vector<symbol_pair> incompatible;
- for (size_t i = 0; i < missing_names.size(); ++i)
- {
- symbol_info base = baseline_symbols[missing_names[i]];
- incompatible.push_back(symbol_pair(base, base));
- }
-
- // Check shared names for compatibility.
- for (size_t i = 0; i < shared_names.size(); ++i)
- {
- symbol_info base = baseline_symbols[shared_names[i]];
- symbol_info test = test_symbols[shared_names[i]];
- if (!check_compatible(base, test))
- incompatible.push_back(symbol_pair(base, test));
- }
-
- // Check added names for compatibility.
- for (size_t i = 0; i < added_names.size(); ++i)
- {
- symbol_info test = test_symbols[added_names[i]];
- if (!check_version(test, true))
- incompatible.push_back(symbol_pair(test, test));
- }
-
- // Report results.
- if (verbose && added_names.size())
- {
- cout << added_names.size() << " added symbols " << endl;
- for (size_t j = 0; j < added_names.size() ; ++j)
- report_symbol_info(test_symbols[added_names[j]], j + 1);
- }
-
- if (verbose && missing_names.size())
- {
- cout << missing_names.size() << " missing symbols " << endl;
- for (size_t j = 0; j < missing_names.size() ; ++j)
- report_symbol_info(baseline_symbols[missing_names[j]], j + 1);
+ if (access(baseline_file, R_OK) != 0)
+ {
+ cerr << "Cannot read baseline file " << baseline_file << endl;
+ exit(1);
+ }
+ compare_symbols(baseline_file, test_file, verbose);
}
- if (verbose && incompatible.size())
+ if (argv1 == "--examine")
{
- cout << incompatible.size() << " incompatible symbols " << endl;
- for (size_t j = 0; j < incompatible.size() ; ++j)
+ const char* file = argv[3];
+ if (access(file, R_OK) != 0)
{
- // First, report name.
- const symbol_info& base = incompatible[j].first;
- const symbol_info& test = incompatible[j].second;
- report_symbol_info(test, j + 1, false);
-
- // Second, report reason or reasons incompatible.
- check_compatible(base, test, true);
+ cerr << "Cannot read symbol file " << file << endl;
+ exit(1);
}
+ examine_symbol(argv[2], file);
}
-
- cout << "\n\t\t=== libstdc++-v3 check-abi Summary ===" << endl;
- cout << endl;
- cout << "# of added symbols:\t\t " << added_names.size() << endl;
- cout << "# of missing symbols:\t\t " << missing_names.size() << endl;
- cout << "# of incompatible symbols:\t " << incompatible.size() << endl;
- cout << endl;
- cout << "using: " << baseline_file << endl;
-
return 0;
}
diff --git a/libstdc++-v3/testsuite/ext/stdio_filebuf/char/1.cc b/libstdc++-v3/testsuite/ext/stdio_filebuf/char/1.cc
index 8b313b3f31f..ab28f369edd 100644
--- a/libstdc++-v3/testsuite/ext/stdio_filebuf/char/1.cc
+++ b/libstdc++-v3/testsuite/ext/stdio_filebuf/char/1.cc
@@ -1,6 +1,6 @@
// 2003-02-11 Paolo Carlini <pcarlini@unitus.it>
-// Copyright (C) 2003 Free Software Foundation, Inc.
+// Copyright (C) 2003, 2004 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
@@ -26,11 +26,9 @@
// { dg-do compile }
// libstdc++/9320
-namespace test
+namespace __gnu_cxx
{
- using namespace std;
- using __gnu_test::pod_char;
typedef short type_t;
- template class __gnu_cxx::stdio_filebuf<type_t, char_traits<type_t> >;
- template class __gnu_cxx::stdio_filebuf<pod_char, char_traits<pod_char> >;
-} // test
+ template class stdio_filebuf<type_t, std::char_traits<type_t> >;
+ template class stdio_filebuf<__gnu_test::pod_char, std::char_traits<__gnu_test::pod_char> >;
+} // __gnu_cxx
diff --git a/libstdc++-v3/testsuite/ext/stdio_sync_filebuf/wchar_t/12077.cc b/libstdc++-v3/testsuite/ext/stdio_sync_filebuf/wchar_t/12077.cc
index 9ba9eb5043e..158287faaa8 100644
--- a/libstdc++-v3/testsuite/ext/stdio_sync_filebuf/wchar_t/12077.cc
+++ b/libstdc++-v3/testsuite/ext/stdio_sync_filebuf/wchar_t/12077.cc
@@ -26,7 +26,7 @@ void test01()
using namespace std;
bool test __attribute__((unused)) = true;
- const char* name = "12077_tmp";
+ const char* name = "tmp_12077";
locale loc = __gnu_test::try_named_locale("is_IS.UTF-8");
locale::global(loc);
diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp
index 8bba2827b24..4e0d86df74a 100644
--- a/libstdc++-v3/testsuite/lib/libstdc++.exp
+++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
@@ -59,16 +59,16 @@ proc v3track { var n } {
}
# Called by v3-init below. "Static" to this file.
-proc v3-copy-files {srcfiles dstdir} {
+proc v3-copy-files {srcfiles} {
foreach f $srcfiles {
if { [catch { set symlink [file readlink $f] } x] } then {
- file copy -force $f $dstdir
+ remote_download target $f
} else {
if { [regexp "^/" "$symlink"] } then {
- file copy -force $symlink $dstdir
+ remote_download target $symlink
} else {
set dirname [file dirname $f]
- file copy -force $dirname/$symlink $dstdir
+ remote_download target $dirname/$symlink
}
}
}
@@ -77,7 +77,7 @@ proc v3-copy-files {srcfiles dstdir} {
# Called once, during runtest.exp setup.
proc libstdc++_init { testfile } {
global env
- global srcdir outdir blddir objdir tool_root_dir
+ global srcdir blddir objdir tool_root_dir
global cxx cxxflags
global includes
global gluefile wrap_flags
@@ -116,8 +116,8 @@ proc libstdc++_init { testfile } {
set dg-do-what-default run
# Copy any required data files.
- v3-copy-files [glob -nocomplain "$srcdir/data/*.tst"] $outdir
- v3-copy-files [glob -nocomplain "$srcdir/data/*.txt"] $outdir
+ v3-copy-files [glob -nocomplain "$srcdir/data/*.tst"]
+ v3-copy-files [glob -nocomplain "$srcdir/data/*.txt"]
# Setup LD_LIBRARY_PATH so that libgcc_s, libstdc++ binaries can be found.
# Find the existing LD_LIBRARY_PATH.
diff --git a/libstdc++-v3/testsuite/testsuite_abi.cc b/libstdc++-v3/testsuite/testsuite_abi.cc
new file mode 100644
index 00000000000..45d47777dda
--- /dev/null
+++ b/libstdc++-v3/testsuite/testsuite_abi.cc
@@ -0,0 +1,462 @@
+// -*- C++ -*-
+
+// Copyright (C) 2004 Free Software Foundation, Inc.
+
+// 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 2, 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 COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file 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 General
+// Public License.
+
+// Benjamin Kosnik <bkoz@redhat.com>
+
+#include "testsuite_abi.h"
+#include <sstream>
+#include <fstream>
+#include <iostream>
+
+using namespace std;
+
+void
+symbol::init(string& data)
+{
+ const char delim = ':';
+ const char version_delim = '@';
+ const string::size_type npos = string::npos;
+ string::size_type n = 0;
+
+ // Set the type.
+ if (data.find("FUNC") == 0)
+ type = symbol::function;
+ else if (data.find("OBJECT") == 0)
+ type = symbol::object;
+ else
+ type = symbol::error;
+ n = data.find_first_of(delim);
+ if (n != npos)
+ data.erase(data.begin(), data.begin() + n + 1);
+
+ // Iff object, get size info.
+ if (type == symbol::object)
+ {
+ n = data.find_first_of(delim);
+ if (n != npos)
+ {
+ string size(data.begin(), data.begin() + n);
+ istringstream iss(size);
+ int x;
+ iss >> x;
+ if (!iss.fail())
+ size = x;
+ data.erase(data.begin(), data.begin() + n + 1);
+ }
+ }
+
+ // Set the name.
+ n = data.find_first_of(version_delim);
+ if (n != npos)
+ {
+ // Found version string.
+ name = string(data.begin(), data.begin() + n);
+ n = data.find_last_of(version_delim);
+ data.erase(data.begin(), data.begin() + n + 1);
+
+ // Set version name.
+ version_name = data;
+ }
+ else
+ {
+ // No versioning info.
+ name = string(data.begin(), data.end());
+ data.erase(data.begin(), data.end());
+ }
+
+ // Set the demangled name.
+ demangled_name = demangle(name);
+}
+
+void
+symbol::print() const
+{
+ const char tab = '\t';
+ cout << tab << name << endl;
+ cout << tab << demangled_name << endl;
+ cout << tab << version_name << endl;
+
+ string type_string;
+ switch (type)
+ {
+ case none:
+ type_string = "none";
+ break;
+ case function:
+ type_string = "function";
+ break;
+ case object:
+ type_string = "object";
+ break;
+ case error:
+ type_string = "error";
+ break;
+ default:
+ type_string = "<default>";
+ }
+ cout << tab << type_string << endl;
+
+ if (type == object)
+ cout << tab << size << endl;
+
+ string status_string;
+ switch (status)
+ {
+ case unknown:
+ status_string = "unknown";
+ break;
+ case added:
+ status_string = "added";
+ break;
+ case subtracted:
+ status_string = "subtracted";
+ break;
+ case compatible:
+ status_string = "compatible";
+ break;
+ case incompatible:
+ status_string = "incompatible";
+ break;
+ default:
+ status_string = "<default>";
+ }
+ cout << tab << status_string << endl;
+}
+
+
+bool
+check_version(const symbol& test, bool added)
+{
+ typedef std::vector<std::string> compat_list;
+ static compat_list known_versions;
+ if (known_versions.empty())
+ {
+ known_versions.push_back("GLIBCPP_3.2"); // base version
+ known_versions.push_back("GLIBCPP_3.2.1");
+ known_versions.push_back("GLIBCPP_3.2.2");
+ known_versions.push_back("GLIBCPP_3.2.3"); // gcc-3.3.0
+ known_versions.push_back("GLIBCXX_3.4");
+ known_versions.push_back("CXXABI_1.2");
+ known_versions.push_back("CXXABI_1.2.1");
+ known_versions.push_back("CXXABI_1.3");
+ }
+ compat_list::iterator begin = known_versions.begin();
+ compat_list::iterator end = known_versions.end();
+
+ // Check version names for compatibility...
+ compat_list::iterator it1 = find(begin, end, test.version_name);
+
+ // Check for weak label.
+ compat_list::iterator it2 = find(begin, end, test.name);
+
+ // Check that added symbols aren't added in the base version.
+ bool compat = true;
+ if (added && test.version_name == known_versions[0])
+ compat = false;
+
+ if (it1 == end && it2 == end)
+ compat = false;
+
+ return compat;
+}
+
+bool
+check_compatible(const symbol& lhs, const symbol& rhs, bool verbose)
+{
+ bool ret = true;
+ const char tab = '\t';
+
+ // Check to see if symbol_objects are compatible.
+ if (lhs.type != rhs.type)
+ {
+ ret = false;
+ if (verbose)
+ cout << tab << "incompatible types" << endl;
+ }
+
+ if (lhs.name != rhs.name)
+ {
+ ret = false;
+ if (verbose)
+ cout << tab << "incompatible names" << endl;
+ }
+
+ if (lhs.size != rhs.size)
+ {
+ ret = false;
+ if (verbose)
+ {
+ cout << tab << "incompatible sizes" << endl;
+ cout << tab << lhs.size << endl;
+ cout << tab << rhs.size << endl;
+ }
+ }
+
+ if (lhs.version_name != rhs.version_name
+ && !check_version(lhs) && !check_version(rhs))
+ {
+ ret = false;
+ if (verbose)
+ {
+ cout << tab << "incompatible versions" << endl;
+ cout << tab << lhs.version_name << endl;
+ cout << tab << rhs.version_name << endl;
+ }
+ }
+
+ if (verbose)
+ cout << endl;
+
+ return ret;
+}
+
+
+bool
+has_symbol(const string& mangled, const symbols& s) throw()
+{
+ const symbol_names& names = s.first;
+ symbol_names::const_iterator i = find(names.begin(), names.end(), mangled);
+ return i != names.end();
+}
+
+symbol&
+get_symbol(const string& mangled, const symbols& s)
+{
+ const symbol_names& names = s.first;
+ symbol_names::const_iterator i = find(names.begin(), names.end(), mangled);
+ if (i != names.end())
+ {
+ symbol_objects objects = s.second;
+ return objects[mangled];
+ }
+ else
+ {
+ ostringstream os;
+ os << "get_symbol failed for symbol " << mangled;
+ throw symbol_error(os.str());
+ }
+}
+
+void
+examine_symbol(const char* name, const char* file)
+{
+ try
+ {
+ symbols s = create_symbols(file);
+ symbol& sym = get_symbol(name, s);
+ sym.print();
+ }
+ catch(...)
+ { throw; }
+}
+
+void
+compare_symbols(const char* baseline_file, const char* test_file,
+ bool verbose)
+{
+ // Input both lists of symbols into container.
+ symbols baseline = create_symbols(baseline_file);
+ symbols test = create_symbols(test_file);
+ symbol_names& baseline_names = baseline.first;
+ symbol_objects& baseline_objects = baseline.second;
+ symbol_names& test_names = test.first;
+ symbol_objects& test_objects = test.second;
+
+ // Sanity check results.
+ const symbol_names::size_type baseline_size = baseline_names.size();
+ const symbol_names::size_type test_size = test_names.size();
+ if (!baseline_size || !test_size)
+ {
+ cerr << "Problems parsing the list of exported symbols." << endl;
+ exit(2);
+ }
+
+ // Sort out names.
+ // Assuming baseline_names, test_names are both unique w/ no duplicates.
+ //
+ // The names added to missing_names are baseline_names not found in
+ // test_names
+ // -> symbols that have been deleted.
+ //
+ // The names added to added_names are test_names are names not in
+ // baseline_names
+ // -> symbols that have been added.
+ symbol_names shared_names;
+ symbol_names missing_names;
+ symbol_names added_names = test_names;
+ for (size_t i = 0; i < baseline_size; ++i)
+ {
+ string what(baseline_names[i]);
+ symbol_names::iterator end = added_names.end();
+ symbol_names::iterator it = find(added_names.begin(), end, what);
+ if (it != end)
+ {
+ // Found.
+ shared_names.push_back(what);
+ added_names.erase(it);
+ }
+ else
+ missing_names.push_back(what);
+ }
+
+ // Check missing names for compatibility.
+ typedef pair<symbol, symbol> symbol_pair;
+ vector<symbol_pair> incompatible;
+ for (size_t j = 0; j < missing_names.size(); ++j)
+ {
+ symbol base = baseline_objects[missing_names[j]];
+ incompatible.push_back(symbol_pair(base, base));
+ }
+
+ // Check shared names for compatibility.
+ for (size_t k = 0; k < shared_names.size(); ++k)
+ {
+ symbol base = baseline_objects[shared_names[k]];
+ symbol test = test_objects[shared_names[k]];
+ if (!check_compatible(base, test))
+ incompatible.push_back(symbol_pair(base, test));
+ }
+
+ // Check added names for compatibility.
+ for (size_t l = 0; l < added_names.size(); ++l)
+ {
+ symbol test = test_objects[added_names[l]];
+ if (!check_version(test, true))
+ incompatible.push_back(symbol_pair(test, test));
+ }
+
+ // Report results.
+ if (verbose && added_names.size())
+ {
+ cout << added_names.size() << " added symbols " << endl;
+ for (size_t j = 0; j < added_names.size() ; ++j)
+ test_objects[added_names[j]].print();
+ }
+
+ if (verbose && missing_names.size())
+ {
+ cout << missing_names.size() << " missing symbols " << endl;
+ for (size_t j = 0; j < missing_names.size() ; ++j)
+ baseline_objects[missing_names[j]].print();
+ }
+
+ if (verbose && incompatible.size())
+ {
+ cout << incompatible.size() << " incompatible symbols " << endl;
+ for (size_t j = 0; j < incompatible.size() ; ++j)
+ {
+ // First, report name.
+ const symbol& base = incompatible[j].first;
+ const symbol& test = incompatible[j].second;
+ test.print();
+
+ // Second, report reason or reasons incompatible.
+ check_compatible(base, test, true);
+ }
+ }
+
+ cout << "\n\t\t=== libstdc++-v3 check-abi Summary ===" << endl;
+ cout << endl;
+ cout << "# of added symbols:\t\t " << added_names.size() << endl;
+ cout << "# of missing symbols:\t\t " << missing_names.size() << endl;
+ cout << "# of incompatible symbols:\t " << incompatible.size() << endl;
+ cout << endl;
+ cout << "using: " << baseline_file << endl;
+}
+
+
+symbols
+create_symbols(const char* file)
+{
+ symbols s;
+ ifstream ifs(file);
+ if (ifs.is_open())
+ {
+ // Organize file data into container of symbol objects.
+ symbol_names& names = s.first;
+ symbol_objects& objects = s.second;
+ const string empty;
+ string line = empty;
+ while (getline(ifs, line).good())
+ {
+ symbol tmp;
+ tmp.init(line);
+ objects[tmp.name] = tmp;
+ names.push_back(tmp.name);
+ line = empty;
+ }
+ }
+ else
+ {
+ ostringstream os;
+ os << "create_symbols failed for file " << file;
+ throw runtime_error(os.str());
+ }
+ return s;
+}
+
+
+const char*
+demangle(const std::string& mangled)
+{
+ const char* name;
+ if (mangled[0] != '_' || mangled[1] != 'Z')
+ {
+ // This is not a mangled symbol, thus has "C" linkage.
+ name = mangled.c_str();
+ }
+ else
+ {
+ // Use __cxa_demangle to demangle.
+ int status = 0;
+ name = abi::__cxa_demangle(mangled.c_str(), 0, 0, &status);
+ if (!name)
+ {
+ switch (status)
+ {
+ case 0:
+ name = "error code = 0: success";
+ break;
+ case -1:
+ name = "error code = -1: memory allocation failure";
+ break;
+ case -2:
+ name = "error code = -2: invalid mangled name";
+ break;
+ case -3:
+ name = "error code = -3: invalid arguments";
+ break;
+ default:
+ name = "error code unknown - who knows what happened";
+ }
+ }
+ }
+ return name;
+}
+
diff --git a/libstdc++-v3/testsuite/testsuite_abi.h b/libstdc++-v3/testsuite/testsuite_abi.h
new file mode 100644
index 00000000000..ebacb6a46e8
--- /dev/null
+++ b/libstdc++-v3/testsuite/testsuite_abi.h
@@ -0,0 +1,129 @@
+// -*- C++ -*-
+
+// Copyright (C) 2004 Free Software Foundation, Inc.
+
+// 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 2, 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 COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file 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 General
+// Public License.
+
+// Benjamin Kosnik <bkoz@redhat.com>
+
+#include <string>
+#include <stdexcept>
+#include <deque>
+#include <ext/hash_map>
+#include <cxxabi.h>
+
+// Encapsulates symbol characteristics.
+struct symbol
+{
+ enum category { none, function, object, error };
+ enum designation { unknown, added, subtracted, compatible, incompatible };
+ enum compatibility
+ {
+ compat_type = 1,
+ compat_name = 2,
+ compat_size = 4,
+ compat_version = 8
+ };
+
+ category type;
+ std::string name;
+ std::string demangled_name;
+ int size;
+ std::string version_name;
+ designation status;
+
+ symbol() : type(none), size(0), status(unknown) { }
+
+ symbol(const symbol& other)
+ : type(other.type), name(other.name), demangled_name(other.demangled_name),
+ size(other.size), version_name(other.version_name),
+ status(other.status) { }
+
+ void
+ print() const;
+
+ void
+ init(std::string& data);
+};
+
+struct symbol_error : public std::logic_error
+{
+ explicit symbol_error(const std::string& s) : std::logic_error(s) { }
+};
+
+
+typedef __gnu_cxx::hash_map<std::string, symbol> symbol_objects;
+
+typedef std::deque<std::string> symbol_names;
+
+typedef std::pair<symbol_names, symbol_objects> symbols;
+
+
+// Check.
+bool
+check_version(const symbol& test, bool added = false);
+
+bool
+check_compatible(const symbol& lhs, const symbol& rhs, bool verbose = false);
+
+
+// Examine.
+bool
+has_symbol(const std::string& mangled, const symbols& list) throw();
+
+symbol&
+get_symbol(const std::string& mangled, const symbols& list);
+
+extern "C" void
+examine_symbol(const char* name, const char* file);
+
+extern "C" void
+compare_symbols(const char* baseline_file, const char* test_file, bool verb);
+
+
+// Util.
+symbols
+create_symbols(const char* file);
+
+const char*
+demangle(const std::string& mangled);
+
+
+// Specialization.
+namespace __gnu_cxx
+{
+ using namespace std;
+
+ template<>
+ struct hash<string>
+ {
+ size_t operator()(const string& s) const
+ {
+ const collate<char>& c = use_facet<collate<char> >(locale::classic());
+ return c.hash(s.c_str(), s.c_str() + s.size());
+ }
+ };
+}
diff --git a/libstdc++-v3/testsuite/testsuite_hooks.cc b/libstdc++-v3/testsuite/testsuite_hooks.cc
index 689a02b57e8..e12a9b41f59 100644
--- a/libstdc++-v3/testsuite/testsuite_hooks.cc
+++ b/libstdc++-v3/testsuite/testsuite_hooks.cc
@@ -1,7 +1,7 @@
// -*- C++ -*-
// Utility subroutines for the C++ library testsuite.
//
-// Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+// Copyright (C) 2002, 2003, 2004 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
@@ -373,8 +373,8 @@ namespace std
}
_M_data->_M_atoms_out[__num_base::_S_oend] = pod_type();
- for (size_t i = 0; i < __num_base::_S_iend; ++i)
- _M_data->_M_atoms_in[i].value = value_type(__num_base::_S_atoms_in[i]);
+ for (size_t j = 0; j < __num_base::_S_iend; ++j)
+ _M_data->_M_atoms_in[j].value = value_type(__num_base::_S_atoms_in[j]);
_M_data->_M_atoms_in[__num_base::_S_iend] = pod_type();
// "true"
diff --git a/libtool.m4 b/libtool.m4
index 0312861d47f..91ceb2db5fa 100644
--- a/libtool.m4
+++ b/libtool.m4
@@ -621,7 +621,7 @@ darwin* | rhapsody*)
lt_cv_deplibs_check_method=pass_all
;;
-freebsd* )
+freebsd* | kfreebsd*-gnu)
if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
case $host_cpu in
i*86 )
@@ -689,7 +689,7 @@ linux-gnu*)
lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
;;
-netbsd*)
+netbsd* | knetbsd*-gnu)
if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
[lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$']
else
diff --git a/ltcf-c.sh b/ltcf-c.sh
index 2c51fd3d55c..7cc273d36ff 100644
--- a/ltcf-c.sh
+++ b/ltcf-c.sh
@@ -175,7 +175,7 @@ EOF
$CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags'
;;
- netbsd*)
+ netbsd* | knetbsd*-gnu)
if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
wlarc=
@@ -442,7 +442,7 @@ else
;;
# FreeBSD 3 and greater uses gcc -shared to do shared libraries.
- freebsd*)
+ freebsd* | kfreebsd*-gnu)
archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
@@ -489,7 +489,7 @@ else
link_all_deplibs=yes
;;
- netbsd*)
+ netbsd* | knetbsd*-gnu)
if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
else
diff --git a/ltcf-cxx.sh b/ltcf-cxx.sh
index 2ecd53e5758..ce28177ee11 100644
--- a/ltcf-cxx.sh
+++ b/ltcf-cxx.sh
@@ -289,7 +289,7 @@ case $host_os in
# C++ shared libraries reported to be fairly broken before switch to ELF
ld_shlibs=no
;;
- freebsd*)
+ freebsd* | kfreebsd*-gnu)
# FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
# conventions
ld_shlibs=yes
@@ -449,7 +449,7 @@ case $host_os in
;;
esac
;;
- netbsd*)
+ netbsd* | knetbsd*-gnu)
# NetBSD uses g++ - do we need to do anything?
;;
osf3*)
@@ -804,7 +804,7 @@ else
;;
esac
;;
- freebsd*)
+ freebsd* | kfreebsd*-gnu)
# FreeBSD uses GNU C++
;;
gnu*)
diff --git a/ltcf-gcj.sh b/ltcf-gcj.sh
index ac4fbbca3d4..950dd003177 100644
--- a/ltcf-gcj.sh
+++ b/ltcf-gcj.sh
@@ -178,7 +178,7 @@ EOF
$CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags'
;;
- netbsd*)
+ netbsd* | knetbsd*-gnu)
if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
wlarc=
@@ -445,7 +445,7 @@ else
;;
# FreeBSD 3 and greater uses gcc -shared to do shared libraries.
- freebsd*)
+ freebsd* | kfreebsd*-gnu)
archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
@@ -476,7 +476,7 @@ else
link_all_deplibs=yes
;;
- netbsd*)
+ netbsd* | knetbsd*-gnu)
if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
else
diff --git a/ltconfig b/ltconfig
index 0d97409d799..03204787a3d 100755
--- a/ltconfig
+++ b/ltconfig
@@ -1168,6 +1168,17 @@ gnu*)
hardcode_into_libs=yes
;;
+kfreebsd*-gnu | knetbsd*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
hpux9* | hpux10* | hpux11*)
# Give a soname corresponding to the major version so that dld.sl refuses to
# link against other versions.
diff --git a/maintainer-scripts/ChangeLog b/maintainer-scripts/ChangeLog
index 7b4f157029c..ca970b84eec 100644
--- a/maintainer-scripts/ChangeLog
+++ b/maintainer-scripts/ChangeLog
@@ -1,3 +1,43 @@
+2004-05-13 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * update_web_docs: Also remove old .gz files from subdirectories
+ on the 15th of the month.
+
+2004-05-13 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * update_web_docs (MANUALS): Add gfortran.
+
+2004-05-13 Arnaud Charlet <charlet@act-europe.fr>
+
+ * update_web_docs: Fix generation of Ada docs.
+
+2004-05-13 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * update_version (ADD_BRANCHES): Remove tree-ssa-20020619-branch.
+
+ * gcc_release (DIFF): Remove -3 option.
+
+2003-07-26 Paul Brook <paul@nowt.org>
+
+ * gcc_release: Add gcc-fortran.
+ * snapshot-README: Ditto.
+ * snapshot-index.html: Ditto.
+
+2004-05-02 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * crontab: Move GCC 3.4 snapshots from Wednesday afternoon to
+ Friday night, where gcc.gnu.org has less load.
+
+2004-05-02 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * crontab: Adjust temporary directory used for snapshot generation.
+ Move GCC 3.3 snapshots to Wednesday 22:32, where gcc.gnu.org has
+ less load.
+
+2004-04-19 Mark Mitchell <mark@codesourcery.com>
+
+ * gcc_release (build_sources): Do not use "-F" to tag sources.
+
2004-04-07 Mark Mitchell <mark@codesourcery.com>
* gcc_release (build_sources): Do not use "-r" and "-D" at the
diff --git a/maintainer-scripts/crontab b/maintainer-scripts/crontab
index 809dc9c96fc..c69c75d02d1 100644
--- a/maintainer-scripts/crontab
+++ b/maintainer-scripts/crontab
@@ -1,5 +1,5 @@
-16 0 * * * sh /home/gccadmin/scripts/update_version
-50 0 * * * sh /home/gccadmin/scripts/update_web_docs
-55 0 * * * sh /home/gccadmin/scripts/update_web_docs_libstdcxx
-40 16 * * 1 sh /home/gccadmin/scripts/gcc_release -s 3.3:gcc-3_3-branch -l -d /sourceware/snapshot-tmp all
-42 16 * * 3 sh /home/gccadmin/scripts/gcc_release -s 3.4:gcc-3_4-branch -l -d /sourceware/snapshot-tmp all
+16 0 * * * sh /home/gccadmin/scripts/update_version
+50 0 * * * sh /home/gccadmin/scripts/update_web_docs
+55 0 * * * sh /home/gccadmin/scripts/update_web_docs_libstdcxx
+32 22 * * 3 sh /home/gccadmin/scripts/gcc_release -s 3.3:gcc-3_3-branch -l -d /sourceware/snapshot-tmp/gcc all
+32 22 * * 5 sh /home/gccadmin/scripts/gcc_release -s 3.4:gcc-3_4-branch -l -d /sourceware/snapshot-tmp/gcc all
diff --git a/maintainer-scripts/gcc_release b/maintainer-scripts/gcc_release
index 3ac73da469f..eda1adc077a 100755
--- a/maintainer-scripts/gcc_release
+++ b/maintainer-scripts/gcc_release
@@ -160,7 +160,10 @@ EOF
EXPORTDATE=""
if [ -n "${TAG}" ]; then
inform "Tagging sources as ${TAG}"
- ${CVS} rtag -r ${CVSBRANCH} -F ${TAG} gcc || \
+ # The -F option to CVS is intentionally not used below. If you
+ # need to retry a release, you will have to manually remove any
+ # existing tag.
+ ${CVS} rtag -r ${CVSBRANCH} ${TAG} gcc || \
error "Could not tag sources"
EXPORTTAG="-r${TAG}"
else
@@ -292,13 +295,14 @@ build_tarfiles() {
build_tarfile gcc-ada-${RELEASE} ${ADA_DIRS}
build_tarfile gcc-g++-${RELEASE} ${CPLUSPLUS_DIRS}
build_tarfile gcc-g77-${RELEASE} ${FORTRAN_DIRS}
+ build_tarfile gcc-fortran-${RELEASE} ${FORTRAN95_DIRS}
build_tarfile gcc-java-${RELEASE} ${JAVA_DIRS}
build_tarfile gcc-objc-${RELEASE} ${OBJECTIVEC_DIRS}
build_tarfile gcc-testsuite-${RELEASE} ${TESTSUITE_DIRS}
# The core is everything else.
EXCLUDES=""
- for x in ${ADA_DIRS} ${CPLUSPLUS_DIRS} ${FORTRAN_DIRS} \
+ for x in ${ADA_DIRS} ${CPLUSPLUS_DIRS} ${FORTRAN_DIRS} ${FORTRAN95_DIRS}\
${JAVA_DIRS} ${OBJECTIVEC_DIRS} ${TESTSUITE_DIRS}; do
EXCLUDES="${EXCLUDES} --exclude $x"
done
@@ -321,7 +325,7 @@ build_diffs() {
old_vers=${old_file%.tar.bz2}
old_vers=${old_vers#gcc-}
inform "Building diffs against version $old_vers"
- for f in gcc gcc-ada gcc-g++ gcc-g77 gcc-java gcc-objc gcc-testsuite gcc-core; do
+ for f in gcc gcc-ada gcc-g++ gcc-g77 gcc-fortran gcc-java gcc-objc gcc-testsuite gcc-core; do
old_tar=${old_dir}/${f}-${old_vers}.tar.bz2
new_tar=${WORKING_DIRECTORY}/${f}-${RELEASE}.tar.bz2
if [ ! -e $old_tar ]; then
@@ -486,6 +490,7 @@ SOURCE_DIRECTORY=""
ADA_DIRS="gcc/ada libada"
CPLUSPLUS_DIRS="gcc/cp libstdc++-v3"
FORTRAN_DIRS="gcc/f libf2c"
+FORTRAN95_DIRS="gcc/fortran libgfortran"
JAVA_DIRS="gcc/java libjava libffi fastjar zlib boehm-gc"
OBJECTIVEC_DIRS="gcc/objc libobjc"
TESTSUITE_DIRS="gcc/testsuite"
@@ -515,7 +520,7 @@ FILE_LIST=""
BZIP2="${BZIP2:-bzip2}"
CVS="${CVS:-cvs -f -Q -z9}"
-DIFF="${DIFF:-diff -Nrc3pad}"
+DIFF="${DIFF:-diff -Nrcpad}"
ENV="${ENV:-env}"
GZIP="${GZIP:-gzip --best}"
SCP="${SCP:-scp -p}"
@@ -635,6 +640,7 @@ SOURCE_DIRECTORY="${WORKING_DIRECTORY}/gcc-${RELEASE}"
ADA_DIRS=`adjust_dirs ${ADA_DIRS}`
CPLUSPLUS_DIRS=`adjust_dirs ${CPLUSPLUS_DIRS}`
FORTRAN_DIRS=`adjust_dirs ${FORTRAN_DIRS}`
+FORTRAN95_DIRS=`adjust_dirs ${FORTRAN95_DIRS}`
JAVA_DIRS=`adjust_dirs ${JAVA_DIRS}`
OBJECTIVEC_DIRS=`adjust_dirs ${OBJECTIVEC_DIRS}`
TESTSUITE_DIRS=`adjust_dirs ${TESTSUITE_DIRS}`
diff --git a/maintainer-scripts/snapshot-README b/maintainer-scripts/snapshot-README
index b32cdd706b8..77b49ac7ea7 100644
--- a/maintainer-scripts/snapshot-README
+++ b/maintainer-scripts/snapshot-README
@@ -20,6 +20,8 @@ You'll find:
gcc-g77-@RELEASE@.tar.bz2 The F77 front end and runtime.
+ gcc-fortran-@RELEASE@.tar.gz The Fortran front end and runtime.
+
gcc-objc-@RELEASE@.tar.bz2 The Objective-C front end and runtime.
gcc-java-@RELEASE@.tar.bz2 The Java front end and runtime.
diff --git a/maintainer-scripts/snapshot-index.html b/maintainer-scripts/snapshot-index.html
index 67a786b50eb..de3859b7ac5 100644
--- a/maintainer-scripts/snapshot-index.html
+++ b/maintainer-scripts/snapshot-index.html
@@ -34,6 +34,10 @@ with the following options: @EXPORT@</p>
gcc-g77</a> @TEXT_DATE@ snapshot, includes just the F77 front
end and runtime.
+ <p> <a href="gcc-fortran-@RELEASE@.tar.bz2">
+ gcc-fortran</a> @TEXT_DATE@ snapshot, includes just the Fortran front
+ end and runtime.
+
<p> <a href="gcc-java-@RELEASE@.tar.bz2">
gcc-java</a> @TEXT_DATE@ snapshot, includes just the Java
front end and runtime.
diff --git a/maintainer-scripts/update_version b/maintainer-scripts/update_version
index 7d3d2f07dcd..8898dc02dd7 100755
--- a/maintainer-scripts/update_version
+++ b/maintainer-scripts/update_version
@@ -7,7 +7,7 @@
CVSROOT=${CVSROOT:-/cvs/gcc}
IGNORE_BRANCHES='gcc-(2_95|3_0|3_1|3_2)-branch'
-ADD_BRANCHES='HEAD tree-ssa-20020619-branch lno-branch'
+ADD_BRANCHES='HEAD lno-branch'
# Run this from /tmp.
export CVSROOT
diff --git a/maintainer-scripts/update_web_docs b/maintainer-scripts/update_web_docs
index 998885c6935..e22779c7bcc 100755
--- a/maintainer-scripts/update_web_docs
+++ b/maintainer-scripts/update_web_docs
@@ -88,7 +88,7 @@ find $CVSROOT/gcc -name \*.texi,v -print | fgrep -v -f/home/gccadmin/scripts/doc
# Checkout all the texi files.
-cvs -Q export -r$RELEASE `cat FILES` gcc/gcc/doc/install.texi2html gcc/gcc/doc/include/texinfo.tex
+cvs -Q export -r$RELEASE `cat FILES` gcc/gcc/doc/install.texi2html gcc/gcc/doc/include/texinfo.tex gcc/gcc/ada/xgnatugn.adb gcc/gcc/ada/ug_words
# Build a tarball of the sources.
tar cf docs-sources.tar gcc
@@ -97,7 +97,15 @@ tar cf docs-sources.tar gcc
# and fdl.texi.
includedir=gcc/gcc/doc/include
-MANUALS="cpp cppinternals fastjar gcc gccint gcj g77 gnat_ug_unx gnat_ug_vms gnat_ug_vxw gnat_ug_wnt gnat-style gnat_rm libiberty porting"
+MANUALS="cpp cppinternals fastjar gcc gccint gcj g77 gfortran gnat_ug_unx gnat_ug_vms gnat_ug_vxw gnat_ug_wnt gnat_ugn_unw gnat-style gnat_rm libiberty porting"
+
+# Generate gnat_ugn_unw
+
+if [ -f gcc/gcc/ada/xgnatugn.adb ]; then
+ gnatmake -q gcc/gcc/ada/xgnatugn
+ ./xgnatugn unw gcc/gcc/ada/gnat_ugn.texi \
+ gcc/gcc/ada/ug_words gnat_ugn_unw.texi
+fi
# Now convert the relevant files from texi to HTML and PostScript.
for file in $MANUALS; do
@@ -121,7 +129,7 @@ today=`date +%d`
if test $today = 15; then
find $DOCSDIR -type f -maxdepth 1 -print | grep -v index.html | xargs rm
for m in $MANUALS; do
- rm $DOCSDIR/$m/*.html
+ rm $DOCSDIR/$m/*.html $DOCSDIR/$m/*.html.gz
done
fi